diff --git a/.eslintrc.json b/.eslintrc.json index fde84ce4b..84e8898fc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,4 +31,4 @@ "ecmaVersion": 13, "sourceType": "module" } -} \ No newline at end of file +} diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3941a586b..feaeaf832 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -31,4 +31,5 @@ - [ ] 如果此次PR涉及到新功能的添加,我已在`PR描述`中写入详细文档 - [ ] 如果此次PR需要扩展跟进,我已在`扩展适配`中写入详细文档 - [ ] 如果这个PR解决了一个issue,我在`诱因和背景`中明确链接到该issue -- [ ] 我保证该PR中没有随意修改换行符等内容,没有制造出大量的Diff \ No newline at end of file +- [ ] 我保证该PR中没有随意修改换行符等内容,没有制造出大量的Diff +- [ ] 我保证该PR遵循项目中`.editorconfig`、`eslint.config.mjs`和`prettier.config.mjs`所规定的代码样式,并且已经通过`prettier`格式化过代码 diff --git a/.gitignore b/.gitignore index cf3bd6cc2..c8875aef3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ noname.ico package-lock.json package.json Thumbs.db +bun.lockb diff --git a/audio/card/female/fudichouxin.mp3 b/audio/card/female/fudichouxin.mp3 new file mode 100644 index 000000000..cfc1ebb57 Binary files /dev/null and b/audio/card/female/fudichouxin.mp3 differ diff --git a/audio/card/female/toulianghuanzhu.mp3 b/audio/card/female/toulianghuanzhu.mp3 new file mode 100644 index 000000000..7e8e7156c Binary files /dev/null and b/audio/card/female/toulianghuanzhu.mp3 differ diff --git a/audio/card/male/fudichouxin.mp3 b/audio/card/male/fudichouxin.mp3 new file mode 100644 index 000000000..18b5b42d0 Binary files /dev/null and b/audio/card/male/fudichouxin.mp3 differ diff --git a/audio/card/male/toulianghuanzhu.mp3 b/audio/card/male/toulianghuanzhu.mp3 new file mode 100644 index 000000000..067624528 Binary files /dev/null and b/audio/card/male/toulianghuanzhu.mp3 differ diff --git a/audio/die/chengji.mp3 b/audio/die/chengji.mp3 new file mode 100644 index 000000000..2f85bf38b Binary files /dev/null and b/audio/die/chengji.mp3 differ diff --git a/audio/die/dc_jiangji.mp3 b/audio/die/dc_jiangji.mp3 new file mode 100644 index 000000000..1e67b57a1 Binary files /dev/null and b/audio/die/dc_jiangji.mp3 differ diff --git a/audio/die/gz_yuji.mp3 b/audio/die/gz_yuji.mp3 new file mode 100644 index 000000000..6ed476113 Binary files /dev/null and b/audio/die/gz_yuji.mp3 differ diff --git a/audio/die/lizhaojiaobo.mp3 b/audio/die/lizhaojiaobo.mp3 new file mode 100644 index 000000000..123f2963b Binary files /dev/null and b/audio/die/lizhaojiaobo.mp3 differ diff --git a/audio/die/mb_caomao.mp3 b/audio/die/mb_caomao.mp3 new file mode 100644 index 000000000..bc917aea3 Binary files /dev/null and b/audio/die/mb_caomao.mp3 differ diff --git a/audio/die/mb_sp_guanqiujian.mp3 b/audio/die/mb_sp_guanqiujian.mp3 new file mode 100644 index 000000000..c37327afb Binary files /dev/null and b/audio/die/mb_sp_guanqiujian.mp3 differ diff --git a/audio/die/sp_sunce.mp3 b/audio/die/sp_sunce.mp3 new file mode 100644 index 000000000..b155b238a Binary files /dev/null and b/audio/die/sp_sunce.mp3 differ diff --git a/audio/skill/dcshiju1.mp3 b/audio/skill/dcshiju1.mp3 new file mode 100644 index 000000000..1f47d0902 Binary files /dev/null and b/audio/skill/dcshiju1.mp3 differ diff --git a/audio/skill/dcshiju2.mp3 b/audio/skill/dcshiju2.mp3 new file mode 100644 index 000000000..acf66632f Binary files /dev/null and b/audio/skill/dcshiju2.mp3 differ diff --git a/audio/skill/dcyingshi1.mp3 b/audio/skill/dcyingshi1.mp3 new file mode 100644 index 000000000..ea32c9502 Binary files /dev/null and b/audio/skill/dcyingshi1.mp3 differ diff --git a/audio/skill/dcyingshi2.mp3 b/audio/skill/dcyingshi2.mp3 new file mode 100644 index 000000000..47dbd6a0f Binary files /dev/null and b/audio/skill/dcyingshi2.mp3 differ diff --git a/audio/skill/mbcuizhen1.mp3 b/audio/skill/mbcuizhen1.mp3 new file mode 100644 index 000000000..7698c7298 Binary files /dev/null and b/audio/skill/mbcuizhen1.mp3 differ diff --git a/audio/skill/mbcuizhen2.mp3 b/audio/skill/mbcuizhen2.mp3 new file mode 100644 index 000000000..60e22c201 Binary files /dev/null and b/audio/skill/mbcuizhen2.mp3 differ diff --git a/audio/skill/mbjuejin1.mp3 b/audio/skill/mbjuejin1.mp3 new file mode 100644 index 000000000..89a6155bc Binary files /dev/null and b/audio/skill/mbjuejin1.mp3 differ diff --git a/audio/skill/mbjuejin2.mp3 b/audio/skill/mbjuejin2.mp3 new file mode 100644 index 000000000..a48370ee8 Binary files /dev/null and b/audio/skill/mbjuejin2.mp3 differ diff --git a/audio/skill/mbkuangli1.mp3 b/audio/skill/mbkuangli1.mp3 new file mode 100644 index 000000000..7ca0cc1ca Binary files /dev/null and b/audio/skill/mbkuangli1.mp3 differ diff --git a/audio/skill/mbkuangli2.mp3 b/audio/skill/mbkuangli2.mp3 new file mode 100644 index 000000000..aa519a215 Binary files /dev/null and b/audio/skill/mbkuangli2.mp3 differ diff --git a/audio/skill/mbkuili1.mp3 b/audio/skill/mbkuili1.mp3 new file mode 100644 index 000000000..5ddb33cff Binary files /dev/null and b/audio/skill/mbkuili1.mp3 differ diff --git a/audio/skill/mbkuili2.mp3 b/audio/skill/mbkuili2.mp3 new file mode 100644 index 000000000..94eb9c725 Binary files /dev/null and b/audio/skill/mbkuili2.mp3 differ diff --git a/audio/skill/mbqianlong1.mp3 b/audio/skill/mbqianlong1.mp3 new file mode 100644 index 000000000..e848f335c Binary files /dev/null and b/audio/skill/mbqianlong1.mp3 differ diff --git a/audio/skill/mbqianlong2.mp3 b/audio/skill/mbqianlong2.mp3 new file mode 100644 index 000000000..bb51536db Binary files /dev/null and b/audio/skill/mbqianlong2.mp3 differ diff --git a/audio/skill/mbqianlong3.mp3 b/audio/skill/mbqianlong3.mp3 new file mode 100644 index 000000000..14b845c89 Binary files /dev/null and b/audio/skill/mbqianlong3.mp3 differ diff --git a/audio/skill/mbqianlong4.mp3 b/audio/skill/mbqianlong4.mp3 new file mode 100644 index 000000000..c103071c3 Binary files /dev/null and b/audio/skill/mbqianlong4.mp3 differ diff --git a/audio/skill/mbqianlong5.mp3 b/audio/skill/mbqianlong5.mp3 new file mode 100644 index 000000000..663f323e8 Binary files /dev/null and b/audio/skill/mbqianlong5.mp3 differ diff --git a/audio/skill/mbqianlong6.mp3 b/audio/skill/mbqianlong6.mp3 new file mode 100644 index 000000000..7d50bb760 Binary files /dev/null and b/audio/skill/mbqianlong6.mp3 differ diff --git a/audio/skill/mbshishou1.mp3 b/audio/skill/mbshishou1.mp3 new file mode 100644 index 000000000..c78a1aaf9 Binary files /dev/null and b/audio/skill/mbshishou1.mp3 differ diff --git a/audio/skill/mbshishou2.mp3 b/audio/skill/mbshishou2.mp3 new file mode 100644 index 000000000..fe60f784f Binary files /dev/null and b/audio/skill/mbshishou2.mp3 differ diff --git a/audio/skill/mbweitong1.mp3 b/audio/skill/mbweitong1.mp3 new file mode 100644 index 000000000..2de7ec6bd Binary files /dev/null and b/audio/skill/mbweitong1.mp3 differ diff --git a/audio/skill/mbxiongsi1.mp3 b/audio/skill/mbxiongsi1.mp3 new file mode 100644 index 000000000..0f9a6d65f Binary files /dev/null and b/audio/skill/mbxiongsi1.mp3 differ diff --git a/audio/skill/mbxiongsi2.mp3 b/audio/skill/mbxiongsi2.mp3 new file mode 100644 index 000000000..ec2a86dcb Binary files /dev/null and b/audio/skill/mbxiongsi2.mp3 differ diff --git a/audio/skill/mbzuoyou1.mp3 b/audio/skill/mbzuoyou1.mp3 new file mode 100644 index 000000000..8b40ce73f Binary files /dev/null and b/audio/skill/mbzuoyou1.mp3 differ diff --git a/audio/skill/mbzuoyou2.mp3 b/audio/skill/mbzuoyou2.mp3 new file mode 100644 index 000000000..2cbb78fb1 Binary files /dev/null and b/audio/skill/mbzuoyou2.mp3 differ diff --git a/audio/skill/olliantao1.mp3 b/audio/skill/olliantao1.mp3 new file mode 100644 index 000000000..c4d469313 Binary files /dev/null and b/audio/skill/olliantao1.mp3 differ diff --git a/audio/skill/olliantao2.mp3 b/audio/skill/olliantao2.mp3 new file mode 100644 index 000000000..d7a485824 Binary files /dev/null and b/audio/skill/olliantao2.mp3 differ diff --git a/audio/skill/rejiushi_mb_caomao1.mp3 b/audio/skill/rejiushi_mb_caomao1.mp3 new file mode 100644 index 000000000..fe05d0725 Binary files /dev/null and b/audio/skill/rejiushi_mb_caomao1.mp3 differ diff --git a/audio/skill/rejiushi_mb_caomao2.mp3 b/audio/skill/rejiushi_mb_caomao2.mp3 new file mode 100644 index 000000000..21db5b72a Binary files /dev/null and b/audio/skill/rejiushi_mb_caomao2.mp3 differ diff --git a/audio/skill/sbfangzhu_mb_caomao1.mp3 b/audio/skill/sbfangzhu_mb_caomao1.mp3 new file mode 100644 index 000000000..232a31d95 Binary files /dev/null and b/audio/skill/sbfangzhu_mb_caomao1.mp3 differ diff --git a/audio/skill/sbfangzhu_mb_caomao2.mp3 b/audio/skill/sbfangzhu_mb_caomao2.mp3 new file mode 100644 index 000000000..879631b55 Binary files /dev/null and b/audio/skill/sbfangzhu_mb_caomao2.mp3 differ diff --git a/audio/skill/sbqingzheng_mb_caomao1.mp3 b/audio/skill/sbqingzheng_mb_caomao1.mp3 new file mode 100644 index 000000000..69d8ca64c Binary files /dev/null and b/audio/skill/sbqingzheng_mb_caomao1.mp3 differ diff --git a/audio/skill/sbqingzheng_mb_caomao2.mp3 b/audio/skill/sbqingzheng_mb_caomao2.mp3 new file mode 100644 index 000000000..100657944 Binary files /dev/null and b/audio/skill/sbqingzheng_mb_caomao2.mp3 differ diff --git a/card/extra.js b/card/extra.js index 519ada0a6..175aa4119 100644 --- a/card/extra.js +++ b/card/extra.js @@ -1,726 +1,834 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'extra', - connect:true, - card:{ - muniu:{ - fullskin:true, - type:'equip', - subtype:'equip5', - nomod:true, - onEquip:function(){ - if(card&&card.cards&&card.cards.length){ - player.directgains(card.cards,null,'muniu'); + name: "extra", + connect: true, + card: { + muniu: { + fullskin: true, + type: "equip", + subtype: "equip5", + nomod: true, + onEquip: function () { + if (card && card.cards && card.cards.length) { + player.directgains(card.cards, null, "muniu"); } - player.markSkill('muniu_skill'); + player.markSkill("muniu_skill"); }, - forceDie:true, - onLose:function(){ - delete player.getStat('skill').muniu_skill; - player.unmarkSkill('muniu_skill'); - if(!card||!card.cards||!card.cards.length) return; - if((!event.getParent(2)||event.getParent(2).name!='swapEquip')&&(event.getParent().type!='equip'||event.getParent().swapEquip)){ - player.lose(card.cards,ui.discardPile); - player.$throw(card.cards,1000); - player.popup('muniu'); - game.log(card,'掉落了',card.cards); - card.cards.length=0; - } - else{ - player.lose(card.cards,ui.special); + forceDie: true, + onLose: function () { + delete player.getStat("skill").muniu_skill; + player.unmarkSkill("muniu_skill"); + if (!card || !card.cards || !card.cards.length) return; + if ( + (!event.getParent(2) || event.getParent(2).name != "swapEquip") && + (event.getParent().type != "equip" || event.getParent().swapEquip) + ) { + player.lose(card.cards, ui.discardPile); + player.$throw(card.cards, 1000); + player.popup("muniu"); + game.log(card, "掉落了", card.cards); + card.cards.length = 0; + } else { + player.lose(card.cards, ui.special); } }, - clearLose:true, - equipDelay:false, - loseDelay:false, - skills:['muniu_skill','muniu_skill7'], - ai:{ - equipValue:function(card){ - if(card.card) return 7+card.card.length; + clearLose: true, + equipDelay: false, + loseDelay: false, + skills: ["muniu_skill", "muniu_skill7"], + ai: { + equipValue: function (card) { + if (card.card) return 7 + card.card.length; return 7; }, - basic:{ - equipValue:7 - } - } + basic: { + equipValue: 7, + }, + }, }, - jiu:{ - audio:true, - fullskin:true, - type:"basic", - toself:true, - enable:function(event,player){ + jiu: { + audio: true, + fullskin: true, + type: "basic", + toself: true, + enable: function (event, player) { //return !player.hasSkill('jiu'); return true; }, - lianheng:true, - logv:false, - savable:function(card,player,dying){ - return dying==player||player.hasSkillTag('jiuOther',null,dying,true); + lianheng: true, + logv: false, + savable: function (card, player, dying) { + return dying == player || player.hasSkillTag("jiuOther", null, dying, true); }, - usable:1, - selectTarget:-1, - modTarget:true, - filterTarget:function(card,player,target){ - return target==player; + usable: 1, + selectTarget: -1, + modTarget: true, + filterTarget: function (card, player, target) { + return target == player; }, - content:function(){ - if(typeof event.baseDamage!='number') event.baseDamage=1; - if(target.isDying()||event.getParent(2).type=='dying'){ + content: function () { + if (typeof event.baseDamage != "number") event.baseDamage = 1; + if (target.isDying() || event.getParent(2).type == "dying") { target.recover(); - if(_status.currentPhase==target){ + if (_status.currentPhase == target) { target.getStat().card.jiu--; } - } - else{ - game.addVideo('jiuNode',target,true); - if(cards&&cards.length){ - card=cards[0]; + } else { + game.addVideo("jiuNode", target, true); + if (cards && cards.length) { + card = cards[0]; } - if(!target.storage.jiu) target.storage.jiu=0; - target.storage.jiu+=event.baseDamage; - game.broadcastAll(function(target,card,gain2){ - target.addSkill('jiu'); - if(!target.node.jiu&&lib.config.jiu_effect){ - target.node.jiu=ui.create.div('.playerjiu',target.node.avatar); - target.node.jiu2=ui.create.div('.playerjiu',target.node.avatar2); - } - if(gain2&&card.clone&&(card.clone.parentNode==target.parentNode||card.clone.parentNode==ui.arena)){ - card.clone.moveDelete(target); - } - },target,card,target==targets[0]&&cards.length==1); - if(target==targets[0]&&cards.length==1){ - if(card.clone&&(card.clone.parentNode==target.parentNode||card.clone.parentNode==ui.arena)){ - game.addVideo('gain2',target,get.cardsInfo([card])); + if (!target.storage.jiu) target.storage.jiu = 0; + target.storage.jiu += event.baseDamage; + game.broadcastAll( + function (target, card, gain2) { + target.addSkill("jiu"); + if (!target.node.jiu && lib.config.jiu_effect) { + target.node.jiu = ui.create.div(".playerjiu", target.node.avatar); + target.node.jiu2 = ui.create.div(".playerjiu", target.node.avatar2); + } + if ( + gain2 && + card.clone && + (card.clone.parentNode == target.parentNode || + card.clone.parentNode == ui.arena) + ) { + card.clone.moveDelete(target); + } + }, + target, + card, + target == targets[0] && cards.length == 1 + ); + if (target == targets[0] && cards.length == 1) { + if ( + card.clone && + (card.clone.parentNode == target.parentNode || + card.clone.parentNode == ui.arena) + ) { + game.addVideo("gain2", target, get.cardsInfo([card])); } } } }, - ai:{ - basic:{ - useful:(card,i)=>{ - if(_status.event.player.hp>1){ - if(i===0) return 4; + ai: { + basic: { + useful: (card, i) => { + if (_status.event.player.hp > 1) { + if (i === 0) return 4; return 1; } - if(i===0) return 7.3; + if (i === 0) return 7.3; return 3; }, - value:(card,player,i)=>{ - if(player.hp>1){ - if(i===0) return 5; + value: (card, player, i) => { + if (player.hp > 1) { + if (i === 0) return 5; return 1; } - if(i===0) return 7.3; + if (i === 0) return 7.3; return 3; - } + }, }, - order:()=>{ - if(_status.event.dying) return 9; - let sha=get.order({name:'sha'}); - if(sha>0) return sha+0.2; + order: () => { + if (_status.event.dying) return 9; + let sha = get.order({ name: "sha" }); + if (sha > 0) return sha + 0.2; return 0; }, - result:{ - target:(player,target,card)=>{ - if(target&&target.isDying()) return 2; - if(!target || target._jiu_temp || !target.isPhaseUsing()) return 0; - let usable=target.getCardUsable('sha'); - if(!usable || lib.config.mode==='stone'&&!player.isMin()&&player.getActCount()+1>=player.actcount || !target.mayHaveSha(player,'use',card)) return 0; - let effs={order:0},temp; - target.getCards('hs',i=>{ - if(get.name(i)!=='sha' || ui.selected.cards.includes(i)) return false; - temp=get.order(i,target); - if(tempeffs.order) effs={order:temp}; - effs[i.cardid]={ - card:i, - target:null, - eff:0 + result: { + target: (player, target, card) => { + if (target && target.isDying()) return 2; + if (!target || target._jiu_temp || !target.isPhaseUsing()) return 0; + let usable = target.getCardUsable("sha"); + if ( + !usable || + (lib.config.mode === "stone" && + !player.isMin() && + player.getActCount() + 1 >= player.actcount) || + !target.mayHaveSha(player, "use", card) + ) + return 0; + let effs = { order: 0 }, + temp; + target.getCards("hs", (i) => { + if (get.name(i) !== "sha" || ui.selected.cards.includes(i)) return false; + temp = get.order(i, target); + if (temp < effs.order) return false; + if (temp > effs.order) effs = { order: temp }; + effs[i.cardid] = { + card: i, + target: null, + eff: 0, }; }); delete effs.order; - for(let i in effs){ - if(!lib.filter.filterCard(effs[i].card,target)) continue; - game.filterPlayer(current=>{ - if(get.attitude(target,current)>=0 || !target.canUse(effs[i].card,current,null,true) || current.hasSkillTag('filterDamage',null,{ - player:target, - card:effs[i].card, - jiu:true - })) return false; - temp=get.effect(current,effs[i].card,target,player); - if(temp<=effs[i].eff) return false; - effs[i].target=current; - effs[i].eff=temp; + for (let i in effs) { + if (!lib.filter.filterCard(effs[i].card, target)) continue; + game.filterPlayer((current) => { + if ( + get.attitude(target, current) >= 0 || + !target.canUse(effs[i].card, current, null, true) || + current.hasSkillTag("filterDamage", null, { + player: target, + card: effs[i].card, + jiu: true, + }) + ) + return false; + temp = get.effect(current, effs[i].card, target, player); + if (temp <= effs[i].eff) return false; + effs[i].target = current; + effs[i].eff = temp; return false; }); - if(!effs[i].target) continue; - if(target.hasSkillTag('directHit_ai',true,{ - target:effs[i].target, - card:i - },true) || usable===1&&(target.needsToDiscard()>Math.max(0,3-target.hp) || !effs[i].target.mayHaveShan(player,'use',effs[i].target.getCards(i=>{ - return i.hasGaintag('sha_notshan'); - })))){ + if (!effs[i].target) continue; + if ( + target.hasSkillTag( + "directHit_ai", + true, + { + target: effs[i].target, + card: i, + }, + true + ) || + (usable === 1 && + (target.needsToDiscard() > Math.max(0, 3 - target.hp) || + !effs[i].target.mayHaveShan( + player, + "use", + effs[i].target.getCards((i) => { + return i.hasGaintag("sha_notshan"); + }) + ))) + ) { delete target._jiu_temp; return 1; } } delete target._jiu_temp; return 0; - } + }, + }, + tag: { + save: 1, + recover: 0.1, }, - tag:{ - save:1, - recover:0.1, - } - } - }, - huogong:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - //cardnature:'fire', - filterTarget:function(card,player,target){ - //if(player!=game.me&&player.countCards('h')<2) return false; - return target.countCards('h')>0; }, - content:function(){ - "step 0" - if(target.countCards('h')==0){ + }, + huogong: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + //cardnature:'fire', + filterTarget: function (card, player, target) { + //if(player!=game.me&&player.countCards('h')<2) return false; + return target.countCards("h") > 0; + }, + content: function () { + "step 0"; + if (target.countCards("h") == 0) { event.finish(); return; - } - else if(target.countCards('h')==1) event._result={cards:target.getCards('h')}; - else target.chooseCard(true).ai=function(card){ - if(_status.event.getRand()<0.5) return Math.random(); - return get.value(card); - }; - "step 1" - target.showCards(result.cards).setContent(function(){}); - event.dialog=ui.create.dialog(get.translation(target)+'展示的手牌',result.cards); - event.videoId=lib.status.videoId++; + } else if (target.countCards("h") == 1) event._result = { cards: target.getCards("h") }; + else + target.chooseCard(true).ai = function (card) { + if (_status.event.getRand() < 0.5) return Math.random(); + return get.value(card); + }; + "step 1"; + target.showCards(result.cards).setContent(function () {}); + event.dialog = ui.create.dialog(get.translation(target) + "展示的手牌", result.cards); + event.videoId = lib.status.videoId++; - game.broadcast('createDialog',event.videoId,get.translation(target)+'展示的手牌',result.cards); - game.addVideo('cardDialog',null,[get.translation(target)+'展示的手牌',get.cardsInfo(result.cards),event.videoId]); - event.card2=result.cards[0]; - game.log(target,'展示了',event.card2); - game.addCardKnower(result.cards, 'everyone'); - event._result={}; - 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 6.2+Math.min(4,evt.player.hp)-get.value(card,evt.player); - } - return -1; - }).set('prompt',false); + game.broadcast( + "createDialog", + event.videoId, + get.translation(target) + "展示的手牌", + result.cards + ); + game.addVideo("cardDialog", null, [ + get.translation(target) + "展示的手牌", + get.cardsInfo(result.cards), + event.videoId, + ]); + event.card2 = result.cards[0]; + game.log(target, "展示了", event.card2); + game.addCardKnower(result.cards, "everyone"); + event._result = {}; + 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 6.2 + Math.min(4, evt.player.hp) - get.value(card, evt.player); + } + return -1; + }) + .set("prompt", false); game.delay(2); - "step 2" - if(result.bool){ - target.damage('fire'); - } - else{ - target.addTempSkill('huogong2'); + "step 2"; + if (result.bool) { + target.damage("fire"); + } else { + target.addTempSkill("huogong2"); } event.dialog.close(); - game.addVideo('cardDialog',null,event.videoId); - game.broadcast('closeDialog',event.videoId); + game.addVideo("cardDialog", null, event.videoId); + game.broadcast("closeDialog", event.videoId); }, - ai:{ - basic:{ - order:9.2, - value:[3,1], - useful:0.6, + ai: { + basic: { + order: 9.2, + value: [3, 1], + useful: 0.6, }, - wuxie:function(target,card,player,viewer,status){ - if(get.attitude(viewer,player._trueMe||player)>0) return 0; - if(status*get.attitude(viewer,target)*get.effect(target,card,player,target)>=0) return 0; - if(_status.event.getRand('huogong_wuxie')*4>player.countCards('h')) return 0; + wuxie: function (target, card, player, viewer, status) { + if (get.attitude(viewer, player._trueMe || player) > 0) return 0; + if ( + status * + get.attitude(viewer, target) * + get.effect(target, card, player, target) >= + 0 + ) + return 0; + if (_status.event.getRand("huogong_wuxie") * 4 > player.countCards("h")) return 0; }, - result:{ - player:function(player){ - var nh=player.countCards('h'); - if(nh<=player.hp&&nh<=4&&_status.event.name=='chooseToUse'){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard(new lib.element.VCard({name:'huogong'}),player,_status.event)){ + result: { + player: function (player) { + var nh = player.countCards("h"); + if (nh <= player.hp && nh <= 4 && _status.event.name == "chooseToUse") { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard( + new lib.element.VCard({ name: "huogong" }), + player, + _status.event + ) + ) { return -10; } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='huogong') return -10; - if(viewAs&&viewAs.name=='huogong') return -10; + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "huogong") return -10; + if (viewAs && viewAs.name == "huogong") return -10; } } return 0; }, - target:function(player,target){ - if(target.hasSkill('huogong2')||target.countCards('h')==0) return 0; - if(player.countCards('h')<=1) return 0; - if(_status.event.player == player){ - if(target.isAllCardsKnown(player)){ - if(!target.countCards('h',card=>{ - return player.countCards('h',card2=>{ - return get.suit(card2) == get.suit(card); - }); - })){ + target: function (player, target) { + if (target.hasSkill("huogong2") || target.countCards("h") == 0) return 0; + if (player.countCards("h") <= 1) return 0; + if (_status.event.player == player) { + if (target.isAllCardsKnown(player)) { + if ( + !target.countCards("h", (card) => { + return player.countCards("h", (card2) => { + return get.suit(card2) == get.suit(card); + }); + }) + ) { return 0; } } } - if(target==player){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard(new lib.element.VCard({name:'huogong'}),player,_status.event)){ + if (target == player) { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard( + new lib.element.VCard({ name: "huogong" }), + player, + _status.event + ) + ) { return -1.15; } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='huogong') return -1.15; - if(viewAs&&viewAs.name=='huogong') return -1.15; + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "huogong") return -1.15; + if (viewAs && viewAs.name == "huogong") return -1.15; } return 0; } return -1.15; - } + }, }, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - norepeat:1 - } - } + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + norepeat: 1, + }, + }, }, - tiesuo:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - selectTarget:[1,2], - complexTarget:true, - content:function(){ + tiesuo: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + selectTarget: [1, 2], + complexTarget: true, + content: function () { target.link(); }, - recastable:true, - ai:{ - wuxie:(target,card,player,viewer, status)=>{ - if(status*get.attitude(viewer,player._trueMe||player)>0 || target.hasSkillTag('nodamage') || target.hasSkillTag('nofire') || target.hasSkillTag('nothunder') || get.attitude(viewer,player)>0 || (1+target.countCards('hs'))*_status.event.getRand()>1.57) return 0; + recastable: true, + ai: { + wuxie: (target, card, player, viewer, status) => { + if ( + status * get.attitude(viewer, player._trueMe || player) > 0 || + target.hasSkillTag("nodamage") || + target.hasSkillTag("nofire") || + target.hasSkillTag("nothunder") || + get.attitude(viewer, player) > 0 || + (1 + target.countCards("hs")) * _status.event.getRand() > 1.57 + ) + return 0; }, - basic:{ - order:7.3, - useful:1.2, - value:4 + basic: { + order: 7.3, + useful: 1.2, + value: 4, }, - result:{ - target:(player,target)=>{ - if(target.hasSkillTag('link')) return 0; - let curs = game.filterPlayer(current=>{ - if(current.hasSkillTag('nodamage')) return false; - return !current.hasSkillTag('nofire') || !current.hasSkillTag('nothunder'); + result: { + target: (player, target) => { + if (target.hasSkillTag("link")) return 0; + let curs = game.filterPlayer((current) => { + if (current.hasSkillTag("nodamage")) return false; + return !current.hasSkillTag("nofire") || !current.hasSkillTag("nothunder"); }); - if(curs.length<2) return 0; - let f = target.hasSkillTag('nofire'), - t = target.hasSkillTag('nothunder'), + if (curs.length < 2) return 0; + let f = target.hasSkillTag("nofire"), + t = target.hasSkillTag("nothunder"), res = 0.9; - if(f&&t || target.hasSkillTag('nodamage')) return 0; - if(f || t) res = 0.45; - if(!f&&target.getEquip('tengjia')) res *= 2; - if(!target.isLinked()) res = -res; - if(ui.selected.targets.length) return res; + if ((f && t) || target.hasSkillTag("nodamage")) return 0; + if (f || t) res = 0.45; + if (!f && target.getEquip("tengjia")) res *= 2; + if (!target.isLinked()) res = -res; + if (ui.selected.targets.length) return res; let fs = 0, es = 0, - att = get.attitude(player,target), + att = get.attitude(player, target), linkf = false, alink = true; - curs.forEach(i=>{ - let atti = get.attitude(player,i); - if(atti>0){ + curs.forEach((i) => { + let atti = get.attitude(player, i); + if (atti > 0) { fs++; - if(i.isLinked()) linkf = true; - } - else if(atti<0){ + if (i.isLinked()) linkf = true; + } else if (atti < 0) { es++; - if(!i.isLinked()) alink = false; + if (!i.isLinked()) alink = false; } }); - if(es<2&&!alink) { - if(att<=0 || att>0 && linkf && fs<2) return 0; + if (es < 2 && !alink) { + if (att <= 0 || (att > 0 && linkf && fs < 2)) return 0; } return res; - } + }, + }, + tag: { + multitarget: 1, + multineg: 1, + norepeat: 1, }, - tag:{ - multitarget:1, - multineg:1, - norepeat:1 - } - } - }, - bingliang:{ - audio:true, - fullskin:true, - type:'delay', - range:{global:1}, - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player!=target); }, - judge:function(card){ - if(get.suit(card)=='club') return 1; + }, + bingliang: { + audio: true, + fullskin: true, + type: "delay", + range: { global: 1 }, + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player != target; + }, + judge: function (card) { + if (get.suit(card) == "club") return 1; return -2; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - effect:function(){ - if(result.bool==false){ - if(get.is.changban()) player.addTempSkill('bingliang_changban'); - else player.skip('phaseDraw'); + effect: function () { + if (result.bool == false) { + if (get.is.changban()) player.addTempSkill("bingliang_changban"); + else player.skip("phaseDraw"); } }, - ai:{ - basic:{ - order:1, - useful:1, - value:4, + ai: { + basic: { + order: 1, + useful: 1, + value: 4, }, - result:{ - target:function(player,target){ - if(target.hasJudge('caomu')) return 0; - return -2.7/Math.sqrt(target.countCards('h')+1); - } + result: { + target: function (player, target) { + if (target.hasJudge("caomu")) return 0; + return -2.7 / Math.sqrt(target.countCards("h") + 1); + }, + }, + tag: { + skip: "phaseDraw", }, - tag:{ - skip:'phaseDraw' - } - } - }, - hualiu:{ - fullskin:true, - type:'equip', - subtype:'equip3', - distance:{globalTo:1}, - }, - zhuque:{ - fullskin:true, - type:'equip', - subtype:'equip1', - //cardnature:'fire', - distance:{attackFrom:-3}, - ai:{ - basic:{ - equipValue:2 - } }, - skills:['zhuque_skill'] }, - guding:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['guding_skill'] + hualiu: { + fullskin: true, + type: "equip", + subtype: "equip3", + distance: { globalTo: 1 }, }, - tengjia:{ - fullskin:true, - type:'equip', - subtype:'equip2', + zhuque: { + fullskin: true, + type: "equip", + subtype: "equip1", //cardnature:'fire', - ai:{ - value:function(card,player,index,method){ - if(player.isDisabled(2)) return 0.01; - if(player.getEquips('tengjia').includes(card)){ - if(player.hasSkillTag('noDirectDamage')) return 10; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(current,player)<0&¤t.hasSkillTag('fireAttack',null,null,true); - })) return 0; + distance: { attackFrom: -3 }, + ai: { + basic: { + equipValue: 2, + }, + }, + skills: ["zhuque_skill"], + }, + guding: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + ai: { + basic: { + equipValue: 2, + }, + }, + skills: ["guding_skill"], + }, + tengjia: { + fullskin: true, + type: "equip", + subtype: "equip2", + //cardnature:'fire', + ai: { + value: function (card, player, index, method) { + if (player.isDisabled(2)) return 0.01; + if (player.getEquips("tengjia").includes(card)) { + if (player.hasSkillTag("noDirectDamage")) return 10; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(current, player) < 0 && + current.hasSkillTag("fireAttack", null, null, true) + ); + }) + ) + return 0; return 6; } - var value=0; - var info=get.info(card); - var current=player.getEquip(info.subtype); - if(current&&card!=current){ - value=get.value(current,player); + var value = 0; + var info = get.info(card); + var current = player.getEquip(info.subtype); + if (current && card != current) { + value = get.value(current, player); } - var equipValue=info.ai.equipValue; - if(equipValue==undefined){ - equipValue=info.ai.basic.equipValue; + var equipValue = info.ai.equipValue; + if (equipValue == undefined) { + equipValue = info.ai.basic.equipValue; } - if(typeof equipValue=='function'){ - if(method=='raw') return equipValue(card,player); - if(method=='raw2') return equipValue(card,player)-value; - return Math.max(0.1,equipValue(card,player)-value); + if (typeof equipValue == "function") { + if (method == "raw") return equipValue(card, player); + if (method == "raw2") return equipValue(card, player) - value; + return Math.max(0.1, equipValue(card, player) - value); } - if(typeof equipValue!='number') equipValue=0; - if(method=='raw') return equipValue; - if(method=='raw2') return equipValue-value; - return Math.max(0.1,equipValue-value); + if (typeof equipValue != "number") equipValue = 0; + if (method == "raw") return equipValue; + if (method == "raw2") return equipValue - value; + return Math.max(0.1, equipValue - value); }, - equipValue:function(card,player){ - if(player._tengjiaEv_temp) return Math.max(1,6-player.hp); - if(player.hasSkillTag('maixie')&&player.hp>1) return 0; - if(player.hasSkillTag('noDirectDamage')) return 10; - player._tengjiaEv_temp=true; - let eff=get.damageEffect(player,player,player,'fire'); + equipValue: function (card, player) { + if (player._tengjiaEv_temp) return Math.max(1, 6 - player.hp); + if (player.hasSkillTag("maixie") && player.hp > 1) return 0; + if (player.hasSkillTag("noDirectDamage")) return 10; + player._tengjiaEv_temp = true; + let eff = get.damageEffect(player, player, player, "fire"); delete player._tengjiaEv_temp; - if(eff>=0) return 10; - let num=4-game.countPlayer(function(current){ - if(get.attitude(current,player)<0){ - if(current.hasSkillTag('fireAttack',null,null,true)) return 3; - return 1; - } - return false; - }); - if(player.hp==1) num+=3; - if(player.hp==2) num+=1; + if (eff >= 0) return 10; + let num = + 4 - + game.countPlayer(function (current) { + if (get.attitude(current, player) < 0) { + if (current.hasSkillTag("fireAttack", null, null, true)) return 3; + return 1; + } + return false; + }); + if (player.hp == 1) num += 3; + if (player.hp == 2) num += 1; return num; }, - basic:{ - equipValue:3 + basic: { + equipValue: 3, }, }, - skills:['tengjia1','tengjia2','tengjia3'] + skills: ["tengjia1", "tengjia2", "tengjia3"], }, - baiyin:{ - fullskin:true, - type:'equip', - subtype:'equip2', - loseDelay:false, - onLose:function(){ - player.addTempSkill('baiyin_skill_lose') + baiyin: { + fullskin: true, + type: "equip", + subtype: "equip2", + loseDelay: false, + onLose: function () { + player.addTempSkill("baiyin_skill_lose"); }, - skills:['baiyin_skill'], - tag:{ - recover:1, + skills: ["baiyin_skill"], + tag: { + recover: 1, }, - ai:{ - order:9.5, - equipValue:function(card,player){ - if(player.hp==player.maxHp) return 5; - if(player.countCards('h','baiyin')) return 6; + ai: { + order: 9.5, + equipValue: function (card, player) { + if (player.hp == player.maxHp) return 5; + if (player.countCards("h", "baiyin")) return 6; return 0; }, - basic:{ - equipValue:5 - } - } + basic: { + equipValue: 5, + }, + }, }, }, - skill:{ - bingliang_changban:{ - cardSkill:true, - unique:true, - trigger:{player:'phaseDrawBegin'}, - silent:true, - content:function(){ + skill: { + bingliang_changban: { + cardSkill: true, + unique: true, + trigger: { player: "phaseDrawBegin" }, + silent: true, + content: function () { trigger.num--; }, - group:'bingliang_changban2' + group: "bingliang_changban2", }, - bingliang_changban2:{ - cardSkill:true, - trigger:{player:'phaseDrawAfter'}, - silent:true, - content:function(){ - if(player.enemy) player.enemy.draw(); - } - }, - muniu_skill:{ - equipSkill:true, - enable:'phaseUse', - usable:1, - filterCard:true, - check:function(card){ - if(card.name=='du') return 20; - var player=_status.event.player; - var nh=player.countCards('h'); - if(!player.needsToDiscard()){ - if(nh<3) return 0; - if(nh==3) return 5-get.value(card); - return 7-get.value(card); - } - return 10-get.useful(card); + bingliang_changban2: { + cardSkill: true, + trigger: { player: "phaseDrawAfter" }, + silent: true, + content: function () { + if (player.enemy) player.enemy.draw(); }, - discard:false, - lose:false, - delay:false, - sync:function(muniu){ - if(game.online){ + }, + muniu_skill: { + equipSkill: true, + enable: "phaseUse", + usable: 1, + filterCard: true, + check: function (card) { + if (card.name == "du") return 20; + var player = _status.event.player; + var nh = player.countCards("h"); + if (!player.needsToDiscard()) { + if (nh < 3) return 0; + if (nh == 3) return 5 - get.value(card); + return 7 - get.value(card); + } + return 10 - get.useful(card); + }, + discard: false, + lose: false, + delay: false, + sync: function (muniu) { + if (game.online) { return; } - if(!muniu.cards){ - muniu.cards=[]; + if (!muniu.cards) { + muniu.cards = []; } - for(var i=0;i0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - prepare:function(cards,player){ - player.$give(1,player,false); + prepare: function (cards, player) { + player.$give(1, player, false); }, - content:function(){ - "step 0" - player.loseToSpecial(cards,'muniu'); - "step 1" - for(var i=0;i=3&&get.attitude(current,player)>=3){ + "step 2"; + var muniu = player.getEquip("muniu"); + var players = game.filterPlayer(function (current) { + if ( + current.canEquip(muniu) && + current != player && + !current.isTurnedOver() && + get.attitude(player, current) >= 3 && + get.attitude(current, player) >= 3 + ) { return true; } }); players.sort(lib.sort.seat); - var choice=players[0]; - var next=player.chooseTarget('是否移动木牛流马?',function(card,player,target){ - return !target.isMin()&&player!=target&&target.canEquip(_status.event.muniu); - }).set('muniu',muniu) - next.set('ai',function(target){ - return target==_status.event.choice?1:-1; + var choice = players[0]; + var next = player + .chooseTarget("是否移动木牛流马?", function (card, player, target) { + return ( + !target.isMin() && player != target && target.canEquip(_status.event.muniu) + ); + }) + .set("muniu", muniu); + next.set("ai", function (target) { + return target == _status.event.choice ? 1 : -1; }); - next.set('choice',choice); - "step 3" - if(result.bool){ - var card=player.getEquip('muniu'); + next.set("choice", choice); + "step 3"; + if (result.bool) { + var card = player.getEquip("muniu"); result.targets[0].equip(card); - player.$give(card,result.targets[0]); - player.line(result.targets,'green'); + player.$give(card, result.targets[0]); + player.line(result.targets, "green"); game.delay(); - } - else{ + } else { player.updateMarks(); } }, - ai:{ - order:1, - expose:0.1, - result:{ - player:1 - } + ai: { + order: 1, + expose: 0.1, + result: { + player: 1, + }, }, - mod:{ - cardEnabled2:function(card,player){ - if(!ui.selected.cards.length) return; - var muniu=player.getEquip('muniu'); - if(!muniu||!muniu.cards||!muniu.cards.length) return; - for(var i of ui.selected.cards){ - if(i==muniu&&muniu.cards.includes(card)) return false; - if(muniu.cards.includes(i)&&card==muniu) return false; + mod: { + cardEnabled2: function (card, player) { + if (!ui.selected.cards.length) return; + var muniu = player.getEquip("muniu"); + if (!muniu || !muniu.cards || !muniu.cards.length) return; + for (var i of ui.selected.cards) { + if (i == muniu && muniu.cards.includes(card)) return false; + if (muniu.cards.includes(i) && card == muniu) return false; } }, }, - mark:true, - markimage2:'image/card/muniu_small.png', - intro:{ - content:function(storage,player){ - var muniu=player.getEquip('muniu'); - if(!muniu||!muniu.cards||!muniu.cards.length) return '共有零张牌'; - if(player.isUnderControl(true)){ + mark: true, + markimage2: "image/card/muniu_small.png", + intro: { + content: function (storage, player) { + var muniu = player.getEquip("muniu"); + if (!muniu || !muniu.cards || !muniu.cards.length) return "共有零张牌"; + if (player.isUnderControl(true)) { return get.translation(muniu.cards); - } - else{ - return '共有'+get.cnNumber(muniu.cards.length)+'张牌'; + } else { + return "共有" + get.cnNumber(muniu.cards.length) + "张牌"; } }, - mark:function(dialog,storage,player){ - var muniu=player.getEquip('muniu'); - if(!muniu||!muniu.cards||!muniu.cards.length) return '共有零张牌'; - if(player.isUnderControl(true)){ + mark: function (dialog, storage, player) { + var muniu = player.getEquip("muniu"); + if (!muniu || !muniu.cards || !muniu.cards.length) return "共有零张牌"; + if (player.isUnderControl(true)) { dialog.addAuto(muniu.cards); - } - else{ - return '共有'+get.cnNumber(muniu.cards.length)+'张牌'; + } else { + return "共有" + get.cnNumber(muniu.cards.length) + "张牌"; } }, - markcount:function(storage,player){ - var muniu=player.getEquip('muniu'); - if(muniu&&muniu.cards) return muniu.cards.length; + markcount: function (storage, player) { + var muniu = player.getEquip("muniu"); + if (muniu && muniu.cards) return muniu.cards.length; return 0; - } - } - }, - muniu_skill7:{ - trigger:{player:'loseEnd'}, - firstDo:true, - forced:true, - //silent:true, - filter:function(event,player){ - if(!event.ss||!event.ss.length||event.parent.name=='lose_muniu') return false; - var muniu=player.getEquip('muniu'); - if(!muniu||!muniu.cards) return false; - return event.ss.filter(function(card){ - return muniu.cards.includes(card); - }).length>0; + }, }, - content:function(){ - var muniu=player.getEquip('muniu'); - if(muniu&&muniu.cards){ + }, + muniu_skill7: { + trigger: { player: "loseEnd" }, + firstDo: true, + forced: true, + //silent:true, + filter: function (event, player) { + if (!event.ss || !event.ss.length || event.parent.name == "lose_muniu") return false; + var muniu = player.getEquip("muniu"); + if (!muniu || !muniu.cards) return false; + return ( + event.ss.filter(function (card) { + return muniu.cards.includes(card); + }).length > 0 + ); + }, + content: function () { + var muniu = player.getEquip("muniu"); + if (muniu && muniu.cards) { muniu.cards.removeArray(trigger.ss); lib.skill.muniu_skill.sync(muniu); } player.updateMarks(); }, }, - huogong2:{charlotte:true}, - jiu:{ - trigger:{player:'useCard1'}, - filter:function(event){ - return event.card&&event.card.name=='sha'; + huogong2: { charlotte: true }, + jiu: { + trigger: { player: "useCard1" }, + filter: function (event) { + return event.card && event.card.name == "sha"; }, - forced:true, - charlotte:true, - firstDo:true, - content:function(){ - if(!trigger.baseDamage) trigger.baseDamage=1; - trigger.baseDamage+=player.storage.jiu; - trigger.jiu=true; - trigger.jiu_add=player.storage.jiu; - game.addVideo('jiuNode',player,false); - game.broadcastAll(function(player){ - player.removeSkill('jiu'); - },player); + forced: true, + charlotte: true, + firstDo: true, + content: function () { + if (!trigger.baseDamage) trigger.baseDamage = 1; + trigger.baseDamage += player.storage.jiu; + trigger.jiu = true; + trigger.jiu_add = player.storage.jiu; + game.addVideo("jiuNode", player, false); + game.broadcastAll(function (player) { + player.removeSkill("jiu"); + }, player); }, - temp:true, - vanish:true, - silent:true, - popup:false, - nopop:true, - onremove:function(player){ - if(player.node.jiu){ + temp: true, + vanish: true, + silent: true, + popup: false, + nopop: true, + onremove: function (player) { + if (player.node.jiu) { player.node.jiu.delete(); player.node.jiu2.delete(); delete player.node.jiu; @@ -728,361 +836,404 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } delete player.storage.jiu; }, - ai:{ - damageBonus:true, - skillTagFilter:function(player,tag,arg){ - if(tag==='damageBonus') return arg&&arg.card&&arg.card.name==='sha'; - } + ai: { + damageBonus: true, + skillTagFilter: function (player, tag, arg) { + if (tag === "damageBonus") return arg && arg.card && arg.card.name === "sha"; + }, }, - group:'jiu2' + group: "jiu2", }, - jiu2:{ - trigger:{player:'useCardAfter',global:'phaseAfter'}, - priority:2, - firstDo:true, - charlotte:true, - filter:function(event,player){ - if(player.hasSkillTag('jiuSustain',null,event.name)) return false; - if(event.name=='useCard') return (event.card&&(event.card.name=='sha')); + jiu2: { + trigger: { player: "useCardAfter", global: "phaseAfter" }, + priority: 2, + firstDo: true, + charlotte: true, + filter: function (event, player) { + if (player.hasSkillTag("jiuSustain", null, event.name)) return false; + if (event.name == "useCard") return event.card && event.card.name == "sha"; return true; }, - forced:true, - popup:false, - audio:false, - content:function(){ - game.broadcastAll(function(player){ - player.removeSkill('jiu'); - },player); - game.addVideo('jiuNode',player,false); + forced: true, + popup: false, + audio: false, + content: function () { + game.broadcastAll(function (player) { + player.removeSkill("jiu"); + }, player); + game.addVideo("jiuNode", player, false); }, }, - guding_skill:{ - equipSkill:true, - audio:true, - trigger:{source:'damageBegin1'}, - filter:function(event){ - if(event.parent.name=='_lianhuan'||event.parent.name=='_lianhuan2') return false; - if(event.card&&event.card.name=='sha'){ - if(event.player.countCards('h')==0) return true; + guding_skill: { + equipSkill: true, + audio: true, + trigger: { source: "damageBegin1" }, + filter: function (event) { + if (event.parent.name == "_lianhuan" || event.parent.name == "_lianhuan2") return false; + if (event.card && event.card.name == "sha") { + if (event.player.countCards("h") == 0) return true; } return false; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num++; }, - ai:{ - effect:{ - player:function(card,player,target,current,isLink){ - if(card.name=='sha'&&!isLink&&target.countCards('h')==0&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - })) return [1,0,1,-3]; - } - } - } + ai: { + effect: { + player: function (card, player, target, current, isLink) { + if ( + card.name == "sha" && + !isLink && + target.countCards("h") == 0 && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + return [1, 0, 1, -3]; + }, + }, + }, }, - tengjia1:{ - equipSkill:true, - trigger:{target:['useCardToBefore']}, - forced:true, - priority:6, - audio:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - if(event.card.name=='nanman') return true; - if(event.card.name=='wanjian') return true; + tengjia1: { + equipSkill: true, + trigger: { target: ["useCardToBefore"] }, + forced: true, + priority: 6, + audio: true, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + if (event.card.name == "nanman") return true; + if (event.card.name == "wanjian") return true; //if(event.card.name=='chuqibuyi') return true; return false; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:target, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:target, - card:card - })) return; + ai: { + effect: { + target: function (card, player, target, current) { + if (target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) + return; //if(card.name=='nanman'||card.name=='wanjian'||card.name=='chuqibuyi') return 'zerotarget'; - if(card.name=='nanman'||card.name=='wanjian') return 'zerotarget'; - if(card.name=='sha'){ - var equip1=player.getEquip('zhuque'); - if(equip1&&equip1.name=='zhuque') return 1.9; - if(!game.hasNature(card)) return 'zerotarget'; + if (card.name == "nanman" || card.name == "wanjian") return "zerotarget"; + if (card.name == "sha") { + var equip1 = player.getEquip("zhuque"); + if (equip1 && equip1.name == "zhuque") return 1.9; + if (!game.hasNature(card)) return "zerotarget"; } - } - } - } + }, + }, + }, }, - tengjia2:{ - equipSkill:true, - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - if(!event.hasNature('fire')) return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; + tengjia2: { + equipSkill: true, + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + if (!event.hasNature("fire")) return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; return true; }, - audio:true, - forced:true, - content:function(){ + audio: true, + forced: true, + content: function () { trigger.num++; }, - ai:{ - fireAttack:true, - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'){ - if(game.hasNature(card,'fire')) return 2; - if(player.hasSkill('zhuque_skill')) return 1.9; + ai: { + fireAttack: true, + effect: { + target: function (card, player, target, current) { + if (card.name == "sha") { + if (game.hasNature(card, "fire")) return 2; + if (player.hasSkill("zhuque_skill")) return 1.9; } - if(get.tag(card,'fireDamage')&¤t<0) return 2; - } - } - } + if (get.tag(card, "fireDamage") && current < 0) return 2; + }, + }, + }, }, - tengjia3:{ - equipSkill:true, - audio:'tengjia1', - trigger:{target:'shaBefore'}, - forced:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + tengjia3: { + equipSkill: true, + audio: "tengjia1", + trigger: { target: "shaBefore" }, + forced: true, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; return false; }, - content:function(){ + content: function () { trigger.cancel(); }, }, - baiyin_skill:{ - equipSkill:true, - trigger:{player:'damageBegin4'}, - forced:true, - audio:true, - filter:function(event,player){ - if(event.num<=1) return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; + baiyin_skill: { + equipSkill: true, + trigger: { player: "damageBegin4" }, + forced: true, + audio: true, + filter: function (event, player) { + if (event.num <= 1) return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; return true; }, //priority:-10, - content:function(){ - trigger.num=1; + content: function () { + trigger.num = 1; }, - subSkill:{ - lose:{ - audio:'baiyin_skill', - forced:true, - charlotte:true, - equipSkill:true, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + lose: { + audio: "baiyin_skill", + forced: true, + charlotte: true, + equipSkill: true, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:(event,player)=>{ - if(player.isHealthy()||player.hasSkillTag('unequip2')) return false; - var evt=event.getl(player); - return evt&&evt.es.some(card=>card.name=='baiyin') + filter: (event, player) => { + if (player.isHealthy() || player.hasSkillTag("unequip2")) return false; + var evt = event.getl(player); + return evt && evt.es.some((card) => card.name == "baiyin"); }, - content:function(){ - var evt=trigger.getl(player); - evt.es.forEach(card=>{ - if(card.name=='baiyin'){ + content: function () { + var evt = trigger.getl(player); + evt.es.forEach((card) => { + if (card.name == "baiyin") { player.recover(); } - }) + }); }, }, }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(player.hasSkillTag('unequip2')) return false; - if(arg&&arg.player){ - if(arg.player.hasSkillTag('unequip',false,{ - name:arg.card?arg.card.name:null, - target:player, - card:arg.card, - })) return false; - if(arg.player.hasSkillTag('unequip_ai',false,{ - name:arg.card?arg.card.name:null, - target:player, - card:arg.card, - })) return false; - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (player.hasSkillTag("unequip2")) return false; + if (arg && arg.player) { + if ( + arg.player.hasSkillTag("unequip", false, { + name: arg.card ? arg.card.name : null, + target: player, + card: arg.card, + }) + ) + return false; + if ( + arg.player.hasSkillTag("unequip_ai", false, { + name: arg.card ? arg.card.name : null, + target: player, + card: arg.card, + }) + ) + return false; + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, - zhuque_skill:{ - equipSkill:true, - trigger:{player:'useCard1'}, + zhuque_skill: { + equipSkill: true, + trigger: { player: "useCard1" }, //priority:7, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; }, - audio:true, - check:function(event,player){ - var eff=0; - for(var i=0;i=0; + return eff >= 0; }, - prompt2:function(event,player){ - return '将'+get.translation(event.card)+'改为火属性'; + prompt2: function (event, player) { + return "将" + get.translation(event.card) + "改为火属性"; }, - content:function(){ - game.setNature(trigger.card,'fire'); - if(get.itemtype(trigger.card)=='card'){ - var next=game.createEvent('zhuque_clear'); - next.card=trigger.card; + content: function () { + game.setNature(trigger.card, "fire"); + if (get.itemtype(trigger.card) == "card") { + var next = game.createEvent("zhuque_clear"); + next.card = trigger.card; event.next.remove(next); trigger.after.push(next); - next.setContent(function(){ - game.setNature(trigger.card,[]); + next.setContent(function () { + game.setNature(trigger.card, []); }); } - } + }, }, - zhuque_skill2:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - content:function(){ + zhuque_skill2: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + content: function () { delete player.storage.zhuque_skill.nature; - } + }, }, - huogon2:{}, + huogon2: {}, }, - translate:{ - jiu:'酒', - jiu_info:'①每回合限一次。出牌阶段,对你自己使用。本回合目标角色使用的下一张【杀】的伤害值基数+1。②当你处于濒死状态时,对你自己使用。目标角色回复1点体力。', - huogong:'火攻', - tiesuo:'铁索连环', - tiesuo_info:'此牌可被重铸。出牌阶段,对至多两名角色使用。目标角色横置。', - huogong_bg:'攻', - huogong_info:'出牌阶段,对一名有手牌的角色使用。目标角色展示一张手牌A,然后你可以弃置一张与A花色相同的手牌,对目标造成1点火属性伤害。', - tiesuo_bg:'索', - bingliang:'兵粮寸断', - hualiu:'骅骝', - zhuque:'朱雀羽扇', - bingliang_bg:'粮', - bingliang_info:'出牌阶段,对一名距离为1的其他角色使用。目标角色于其判定阶段进行判定:若判定结果不为梅花,则其跳过下一个摸牌阶段。', - hualiu_bg:'+马', - hualiu_info:'锁定技,其他角色计算与你的距离+1。', - zhuque_bg:'扇', - zhuque_skill:'朱雀羽扇', - zhuque_info:'当你声明使用普【杀】后,你可以为此【杀】赋予火属性。', - guding:'古锭刀', - guding_info:'锁定技,当你因执行【杀】的效果而对目标角色造成伤害时,若其没有手牌,则此伤害+1。', - guding_skill:'古锭刀', - tengjia:'藤甲', + translate: { + jiu: "酒", + jiu_info: + "①每回合限一次。出牌阶段,对你自己使用。本回合目标角色使用的下一张【杀】的伤害值基数+1。②当你处于濒死状态时,对你自己使用。目标角色回复1点体力。", + huogong: "火攻", + tiesuo: "铁索连环", + tiesuo_info: "此牌可被重铸。出牌阶段,对至多两名角色使用。目标角色横置。", + huogong_bg: "攻", + huogong_info: + "出牌阶段,对一名有手牌的角色使用。目标角色展示一张手牌A,然后你可以弃置一张与A花色相同的手牌,对目标造成1点火属性伤害。", + tiesuo_bg: "索", + bingliang: "兵粮寸断", + hualiu: "骅骝", + zhuque: "朱雀羽扇", + bingliang_bg: "粮", + bingliang_info: + "出牌阶段,对一名距离为1的其他角色使用。目标角色于其判定阶段进行判定:若判定结果不为梅花,则其跳过下一个摸牌阶段。", + hualiu_bg: "+马", + hualiu_info: "锁定技,其他角色计算与你的距离+1。", + zhuque_bg: "扇", + zhuque_skill: "朱雀羽扇", + zhuque_info: "当你声明使用普【杀】后,你可以为此【杀】赋予火属性。", + guding: "古锭刀", + guding_info: "锁定技,当你因执行【杀】的效果而对目标角色造成伤害时,若其没有手牌,则此伤害+1。", + guding_skill: "古锭刀", + tengjia: "藤甲", //tengjia_info:'锁定技,【南蛮入侵】、【万箭齐发】、【出其不意】和普通【杀】对你无效。当你受到火焰伤害时,该伤害+1。', - tengjia_info:'锁定技。①【南蛮入侵】、【万箭齐发】和普【杀】对你无效。②当你受到火属性伤害时,此伤害+1。', - tengjia1:'藤甲', - tengjia2:'藤甲', - tengjia3:'藤甲', - baiyin:'白银狮子', - baiyin_info:'锁定技。①当你受到伤害时,若此伤害大于1,则你将伤害值扣减至1点。②当你失去装备区内的【白银狮子】后,你回复1点体力。', - baiyin_skill:'白银狮子', + tengjia_info: + "锁定技。①【南蛮入侵】、【万箭齐发】和普【杀】对你无效。②当你受到火属性伤害时,此伤害+1。", + tengjia1: "藤甲", + tengjia2: "藤甲", + tengjia3: "藤甲", + baiyin: "白银狮子", + baiyin_info: + "锁定技。①当你受到伤害时,若此伤害大于1,则你将伤害值扣减至1点。②当你失去装备区内的【白银狮子】后,你回复1点体力。", + baiyin_skill: "白银狮子", - muniu:'木牛流马', - muniu_bg:'牛', - muniu_skill:'木牛', - muniu_skill7:'木牛流马', - muniu_skill_bg:'辎', - muniu_info:'①出牌阶段限一次,你可以将一张手牌扣置于你装备区里的【木牛流马】下,然后你可以将【木牛流马】移动到一名其他角色的装备区里。②你可以将【木牛流马】下的牌如手牌般使用或打出。③当你失去装备区的【木牛流马】后,你刷新〖木牛流马①〗的使用次数限制。若此牌不是因置入其他角色的装备区而失去的,则你将【木牛流马】下的所有牌置入弃牌堆。', - muniu_skill_info:'将一张手牌扣置于你装备区里的【木牛流马】下,然后可以将此装备移动到一名其他角色的装备区里。', + muniu: "木牛流马", + muniu_bg: "牛", + muniu_skill: "木牛", + muniu_skill7: "木牛流马", + muniu_skill_bg: "辎", + muniu_info: + "①出牌阶段限一次,你可以将一张手牌扣置于你装备区里的【木牛流马】下,然后你可以将【木牛流马】移动到一名其他角色的装备区里。②你可以将【木牛流马】下的牌如手牌般使用或打出。③当你失去装备区的【木牛流马】后,你刷新〖木牛流马①〗的使用次数限制。若此牌不是因置入其他角色的装备区而失去的,则你将【木牛流马】下的所有牌置入弃牌堆。", + muniu_skill_info: + "将一张手牌扣置于你装备区里的【木牛流马】下,然后可以将此装备移动到一名其他角色的装备区里。", }, - list:[ - ["heart",4,"sha","fire"], - ["heart",7,"sha","fire"], - ["heart",10,"sha","fire"], - ["diamond",4,"sha","fire"], - ["diamond",5,"sha","fire"], - ["spade",4,"sha","thunder"], - ["spade",5,"sha","thunder"], - ["spade",6,"sha","thunder"], - ["spade",7,"sha","thunder"], - ["spade",8,"sha","thunder"], - ["club",5,"sha","thunder"], - ["club",6,"sha","thunder"], - ["club",7,"sha","thunder"], - ["club",8,"sha","thunder"], - ["heart",8,"shan"], - ["heart",9,"shan"], - ["heart",11,"shan"], - ["heart",12,"shan"], - ["diamond",6,"shan"], - ["diamond",7,"shan"], - ["diamond",8,"shan"], - ["diamond",10,"shan"], - ["diamond",11,"shan"], - ["heart",5,"tao"], - ["heart",6,"tao"], - ["diamond",2,"tao"], - ["diamond",3,"tao"], - ["diamond",9,"jiu"], - ["spade",3,"jiu"], - ["spade",9,"jiu"], - ["club",3,"jiu"], - ["club",9,"jiu"], + list: [ + ["heart", 4, "sha", "fire"], + ["heart", 7, "sha", "fire"], + ["heart", 10, "sha", "fire"], + ["diamond", 4, "sha", "fire"], + ["diamond", 5, "sha", "fire"], + ["spade", 4, "sha", "thunder"], + ["spade", 5, "sha", "thunder"], + ["spade", 6, "sha", "thunder"], + ["spade", 7, "sha", "thunder"], + ["spade", 8, "sha", "thunder"], + ["club", 5, "sha", "thunder"], + ["club", 6, "sha", "thunder"], + ["club", 7, "sha", "thunder"], + ["club", 8, "sha", "thunder"], + ["heart", 8, "shan"], + ["heart", 9, "shan"], + ["heart", 11, "shan"], + ["heart", 12, "shan"], + ["diamond", 6, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 10, "shan"], + ["diamond", 11, "shan"], + ["heart", 5, "tao"], + ["heart", 6, "tao"], + ["diamond", 2, "tao"], + ["diamond", 3, "tao"], + ["diamond", 9, "jiu"], + ["spade", 3, "jiu"], + ["spade", 9, "jiu"], + ["club", 3, "jiu"], + ["club", 9, "jiu"], - ["diamond",13,"hualiu"], - ["club",1,"baiyin"], - ["spade",2,"tengjia"], - ["club",2,"tengjia"], - ["spade",1,"guding"], - ["diamond",1,"zhuque"], + ["diamond", 13, "hualiu"], + ["club", 1, "baiyin"], + ["spade", 2, "tengjia"], + ["club", 2, "tengjia"], + ["spade", 1, "guding"], + ["diamond", 1, "zhuque"], - ["heart",2,"huogong"], - ["heart",3,"huogong"], - ["diamond",12,"huogong"], - ["spade",11,"tiesuo"], - ["spade",12,"tiesuo"], - ["club",10,"tiesuo"], - ["club",11,"tiesuo"], - ["club",12,"tiesuo"], - ["club",13,"tiesuo"], - ["heart",1,"wuxie"], - ["heart",13,"wuxie"], - ["spade",13,"wuxie"], - ["spade",10,"bingliang"], - ["club",4,"bingliang"], + ["heart", 2, "huogong"], + ["heart", 3, "huogong"], + ["diamond", 12, "huogong"], + ["spade", 11, "tiesuo"], + ["spade", 12, "tiesuo"], + ["club", 10, "tiesuo"], + ["club", 11, "tiesuo"], + ["club", 12, "tiesuo"], + ["club", 13, "tiesuo"], + ["heart", 1, "wuxie"], + ["heart", 13, "wuxie"], + ["spade", 13, "wuxie"], + ["spade", 10, "bingliang"], + ["club", 4, "bingliang"], - ['diamond',5,'muniu'], + ["diamond", 5, "muniu"], ], - } + }; }); diff --git a/card/gujian.js b/card/gujian.js index 9b27de9f1..234f7738a 100644 --- a/card/gujian.js +++ b/card/gujian.js @@ -1,947 +1,972 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'gujian', - card:{ - luyugeng:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('luyugeng'); + name: "gujian", + card: { + luyugeng: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("luyugeng"); }, //range:{global:1}, - content:function(){ + content: function () { target.$gain2(cards); - target.storage.luyugeng=card; - target.storage.luyugeng_markcount=3; - target.addSkill('luyugeng'); + target.storage.luyugeng = card; + target.storage.luyugeng_markcount = 3; + target.addSkill("luyugeng"); + }, + ai: { + order: 2, + value: 4, + result: { + target: 1, + }, }, - ai:{ - order:2, - value:4, - result:{ - target:1 - } - } }, - jinlianzhu:{ - type:'trick', - fullskin:true, - filterTarget:true, - global:'g_jinlianzhu', - content:function(){ - var evt=event.getParent(3)._trigger; - evt.cancel() - if(evt.source){ + jinlianzhu: { + type: "trick", + fullskin: true, + filterTarget: true, + global: "g_jinlianzhu", + content: function () { + var evt = event.getParent(3)._trigger; + evt.cancel(); + if (evt.source) { evt.source.draw(); } }, - ai:{ - order:1, - value:[5,1], - useful:[6,1], - result:{ - target:function(player,target){ - var evt=_status.event.getTrigger(); - var eff=get.damageEffect(target,evt.source,target,evt.nature); - if(eff>0) return -1; - if(eff<0) return 2; + ai: { + order: 1, + value: [5, 1], + useful: [6, 1], + result: { + target: function (player, target) { + var evt = _status.event.getTrigger(); + var eff = get.damageEffect(target, evt.source, target, evt.nature); + if (eff > 0) return -1; + if (eff < 0) return 2; return 0; - } - } - } + }, + }, + }, }, - chunbing:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('chunbing'); + chunbing: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("chunbing"); }, //range:{global:1}, - content:function(){ + content: function () { target.$gain2(cards); - target.storage.chunbing=card; - target.storage.chunbing_markcount=5; - target.addSkill('chunbing'); + target.storage.chunbing = card; + target.storage.chunbing_markcount = 5; + target.addSkill("chunbing"); }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - var num=target.needsToDiscard(); - if(num){ - if(target==player&&num>1){ + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + var num = target.needsToDiscard(); + if (num) { + if (target == player && num > 1) { return num; } return Math.sqrt(num); } return 0; - } - } - } + }, + }, + }, }, - gudonggeng:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gudonggeng'); + gudonggeng: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gudonggeng"); }, //range:{global:1}, - content:function(){ + content: function () { target.$gain2(cards); - target.storage.gudonggeng=card; - target.storage.gudonggeng_markcount=3; - target.addSkill('gudonggeng'); + target.storage.gudonggeng = card; + target.storage.gudonggeng_markcount = 3; + target.addSkill("gudonggeng"); + }, + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + if (player == target && !player.hasShan()) return 2; + return 1 / Math.max(1, target.hp); + }, + }, }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - if(player==target&&!player.hasShan()) return 2; - return 1/Math.max(1,target.hp); - } - } - } }, - liyutang:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('liyutang'); + liyutang: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("liyutang"); }, //range:{global:1}, - content:function(){ + content: function () { target.$gain2(cards); - target.storage.liyutang=card; - target.storage.liyutang_markcount=2; - target.addSkill('liyutang'); + target.storage.liyutang = card; + target.storage.liyutang_markcount = 2; + target.addSkill("liyutang"); + }, + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + if (player == target && target.isMinHp()) return 2; + if (target.isMinHp()) return 1.5; + return 1 / Math.max(1, target.hp); + }, + }, }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - if(player==target&&target.isMinHp()) return 2; - if(target.isMinHp()) return 1.5; - return 1/Math.max(1,target.hp); - } - } - } }, - mizhilianou:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('mizhilianou'); + mizhilianou: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("mizhilianou"); }, //range:{global:1}, - content:function(){ + content: function () { target.$gain2(cards); - target.storage.mizhilianou=card; - target.storage.mizhilianou_markcount=4; - target.addSkill('mizhilianou'); + target.storage.mizhilianou = card; + target.storage.mizhilianou_markcount = 4; + target.addSkill("mizhilianou"); }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - if(target==player){ - if(target.countCards('he',{suit:'heart'})){ - if(target.isDamaged()) return 1.5; - } - else{ + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + if (target == player) { + if (target.countCards("he", { suit: "heart" })) { + if (target.isDamaged()) return 1.5; + } else { return 0.2; } - } - else if(target.isDamaged()){ + } else if (target.isDamaged()) { return 1; } return 0.5; - } - } - } - }, - xiajiao:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('xiajiao'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.xiajiao=card; - target.storage.xiajiao_markcount=3; - target.addSkill('xiajiao'); - target.addTempSkill('xiajiao3'); - }, - ai:{ - order:2, - value:5, - result:{ - target:1 - } - } - }, - tanhuadong:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('tanhuadong'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.tanhuadong=card; - target.storage.tanhuadong_markcount=3; - target.addSkill('tanhuadong'); - }, - ai:{ - order:2, - value:5, - result:{ - target:1 - } - } - }, - mapodoufu:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('mapodoufu'); - }, - //range:{global:1}, - content:function(){ - if(target==targets[0]&&cards.length) target.$gain2(cards); - target.storage.mapodoufu=card; - target.storage.mapodoufu_markcount=2; - target.addSkill('mapodoufu'); - }, - ai:{ - order:1, - value:5, - result:{ - target:function(player,target){ - return player==target?2:1; - } - } - } - }, - qingtuan:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('qingtuan'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.qingtuan=card; - target.storage.qingtuan_markcount=2; - target.addSkill('qingtuan'); - }, - ai:{ - order:4, - value:4, - result:{ - target:function(player,target){ - if(target==player){ - if(target.hasSha()) return 2; - } - else{ - var nh=target.countCards('h'); - if(nh>=3) return 1; - if(target.hasSha()) return 1; - if(nh&&Math.random()<0.5) return 1; - } - return player.needsToDiscard()?0.2:0; - } - } - } - }, - yougeng:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('yougeng'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.yougeng=card; - target.storage.yougeng_markcount=2; - target.addSkill('yougeng'); - }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - if(target.isHealthy()) return player.needsToDiscard()?0.1:0; - if(target.isMinHp()) return 1.5; - return 1/Math.max(1,target.hp); - } - } - } - }, - molicha:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('molicha'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.molicha=card; - target.storage.molicha_markcount=4; - target.addSkill('molicha'); - }, - ai:{ - order:2, - value:4, - result:{ - target:1 - } - } - }, - yuanbaorou:{ - fullskin:true, - type:'food', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('yuanbaorou'); - }, - //range:{global:1}, - content:function(){ - target.$gain2(cards); - target.storage.yuanbaorou=card; - target.storage.yuanbaorou_markcount=4; - target.addSkill('yuanbaorou'); - }, - ai:{ - order:2, - value:4, - result:{ - target:function(player,target){ - if(target==player){ - if(target.hasSha()) return 2; - } - else{ - var nh=target.countCards('h'); - if(nh>=3) return 1; - if(target.hasSha()) return 1; - if(nh&&Math.random()<0.5) return 1; - } - return player.needsToDiscard()?0.2:0; - } - } - } - }, - heilonglinpian:{ - fullskin:true, - type:'trick', - enable:true, - toself:true, - filterTarget:function(card,player,target){ - return target==player; - }, - selectTarget:-1, - modTarget:true, - content:function(){ - target.changeHujia(); - target.addTempSkill('heilonglinpian',{player:'phaseBegin'}); - }, - ai:{ - value:[6,1], - useful:1, - order:2, - result:{ - target:1 - } - } - }, - mutoumianju:{ - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['mutoumianju_skill'], - ai:{ - equipValue:4 - } - }, - yuheng:{fullskin:true}, - gjyuheng:{ - fullskin:true, - cardimage:'yuheng', - type:'equip', - subtype:'equip5', - nopower:true, - nomod:true, - unique:true, - skills:['gjyuheng_skill'], - ai:{ - equipValue:6 - } - }, - gjyuheng_plus:{ - fullskin:true, - type:'equip', - subtype:'equip5', - nopower:true, - unique:true, - nomod:true, - epic:true, - cardimage:'yuheng', - skills:['gjyuheng_plus_skill'], - ai:{ - equipValue:7 - } - }, - gjyuheng_pro:{ - fullskin:true, - type:'equip', - subtype:'equip5', - nopower:true, - unique:true, - nomod:true, - legend:true, - cardimage:'yuheng', - skills:['gjyuheng_pro_skill'], - ai:{ - equipValue:8 - } - }, - shatang:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - cardcolor:'red', - cardnature:'fire', - content:function(){ - 'step 0' - target.damage('fire'); - 'step 1' - target.changeHujia(); - }, - ai:{ - value:[4,1], - useful:2, - order:2, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nofire')) return 1.5; - if(target.hasSkillTag('maixie_hp')) return 0; - if(target.hp==1) return -1; - return -1/Math.sqrt(target.hp+1); - } - }, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1 - } - } - }, - shujinsan:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('he')>0; - }, - content:function(){ - 'step 0' - target.chooseToDiscard('he',[1,target.countCards('he')],'弃置任意张牌并摸等量的牌').ai=function(card){ - return 6-get.value(card); - } - 'step 1' - if(result.bool){ - target.draw(result.cards.length); - } - }, - ai:{ - order:1.5, - value:[4,1], - tag:{ - norepeat:1 - }, - result:{ - target:function(player,target){ - if(target==player){ - var cards=player.getCards('he'); - var num=-1; - for(var i=0;i2){ - if(player.needsToDiscard()) return 1/target.hp; - return 0; - } - if(target.hp>0){ - return 2/target.hp; - } - return 0; - } - } - } - }, - yunvyuanshen:{ - fullskin:true, - type:'basic', - enable:true, - logv:false, - filterTarget:function(card,player,target){ - return !target.hasSkill('yunvyuanshen_skill'); - }, - content:function(){ - target.storage.yunvyuanshen_skill=game.createCard('yunvyuanshen'); - target.addSkill('yunvyuanshen_skill'); - if(cards&&cards.length){ - card=cards[0]; - } - if(target==targets[0]&&card.clone&&(card.clone.parentNode==player.parentNode||card.clone.parentNode==ui.arena)){ - card.clone.moveDelete(target); - game.addVideo('gain2',target,get.cardsInfo([card])); - } - }, - ai:{ - basic:{ - value:9, - useful:4, - value:7 - }, - order:2, - result:{ - target:function(player,target){ - return 1/Math.sqrt(1+target.hp); }, }, - } - }, - bingpotong:{ - fullskin:true, - type:'jiguan', - enable:true, - wuxieable:true, - filterTarget:function(card,player,target){ - return target.countCards('h')>0; }, - selectTarget:[1,3], - content:function(){ - "step 0" - if(target.countCards('h')==0||player.countCards('h')==0){ + }, + xiajiao: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("xiajiao"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.xiajiao = card; + target.storage.xiajiao_markcount = 3; + target.addSkill("xiajiao"); + target.addTempSkill("xiajiao3"); + }, + ai: { + order: 2, + value: 5, + result: { + target: 1, + }, + }, + }, + tanhuadong: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("tanhuadong"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.tanhuadong = card; + target.storage.tanhuadong_markcount = 3; + target.addSkill("tanhuadong"); + }, + ai: { + order: 2, + value: 5, + result: { + target: 1, + }, + }, + }, + mapodoufu: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("mapodoufu"); + }, + //range:{global:1}, + content: function () { + if (target == targets[0] && cards.length) target.$gain2(cards); + target.storage.mapodoufu = card; + target.storage.mapodoufu_markcount = 2; + target.addSkill("mapodoufu"); + }, + ai: { + order: 1, + value: 5, + result: { + target: function (player, target) { + return player == target ? 2 : 1; + }, + }, + }, + }, + qingtuan: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("qingtuan"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.qingtuan = card; + target.storage.qingtuan_markcount = 2; + target.addSkill("qingtuan"); + }, + ai: { + order: 4, + value: 4, + result: { + target: function (player, target) { + if (target == player) { + if (target.hasSha()) return 2; + } else { + var nh = target.countCards("h"); + if (nh >= 3) return 1; + if (target.hasSha()) return 1; + if (nh && Math.random() < 0.5) return 1; + } + return player.needsToDiscard() ? 0.2 : 0; + }, + }, + }, + }, + yougeng: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("yougeng"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.yougeng = card; + target.storage.yougeng_markcount = 2; + target.addSkill("yougeng"); + }, + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + if (target.isHealthy()) return player.needsToDiscard() ? 0.1 : 0; + if (target.isMinHp()) return 1.5; + return 1 / Math.max(1, target.hp); + }, + }, + }, + }, + molicha: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("molicha"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.molicha = card; + target.storage.molicha_markcount = 4; + target.addSkill("molicha"); + }, + ai: { + order: 2, + value: 4, + result: { + target: 1, + }, + }, + }, + yuanbaorou: { + fullskin: true, + type: "food", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("yuanbaorou"); + }, + //range:{global:1}, + content: function () { + target.$gain2(cards); + target.storage.yuanbaorou = card; + target.storage.yuanbaorou_markcount = 4; + target.addSkill("yuanbaorou"); + }, + ai: { + order: 2, + value: 4, + result: { + target: function (player, target) { + if (target == player) { + if (target.hasSha()) return 2; + } else { + var nh = target.countCards("h"); + if (nh >= 3) return 1; + if (target.hasSha()) return 1; + if (nh && Math.random() < 0.5) return 1; + } + return player.needsToDiscard() ? 0.2 : 0; + }, + }, + }, + }, + heilonglinpian: { + fullskin: true, + type: "trick", + enable: true, + toself: true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + modTarget: true, + content: function () { + target.changeHujia(); + target.addTempSkill("heilonglinpian", { player: "phaseBegin" }); + }, + ai: { + value: [6, 1], + useful: 1, + order: 2, + result: { + target: 1, + }, + }, + }, + mutoumianju: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["mutoumianju_skill"], + ai: { + equipValue: 4, + }, + }, + yuheng: { fullskin: true }, + gjyuheng: { + fullskin: true, + cardimage: "yuheng", + type: "equip", + subtype: "equip5", + nopower: true, + nomod: true, + unique: true, + skills: ["gjyuheng_skill"], + ai: { + equipValue: 6, + }, + }, + gjyuheng_plus: { + fullskin: true, + type: "equip", + subtype: "equip5", + nopower: true, + unique: true, + nomod: true, + epic: true, + cardimage: "yuheng", + skills: ["gjyuheng_plus_skill"], + ai: { + equipValue: 7, + }, + }, + gjyuheng_pro: { + fullskin: true, + type: "equip", + subtype: "equip5", + nopower: true, + unique: true, + nomod: true, + legend: true, + cardimage: "yuheng", + skills: ["gjyuheng_pro_skill"], + ai: { + equipValue: 8, + }, + }, + shatang: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + cardcolor: "red", + cardnature: "fire", + content: function () { + "step 0"; + target.damage("fire"); + "step 1"; + target.changeHujia(); + }, + ai: { + value: [4, 1], + useful: 2, + order: 2, + result: { + target: function (player, target) { + if (target.hasSkillTag("nofire")) return 1.5; + if (target.hasSkillTag("maixie_hp")) return 0; + if (target.hp == 1) return -1; + return -1 / Math.sqrt(target.hp + 1); + }, + }, + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + }, + }, + }, + shujinsan: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("he") > 0; + }, + content: function () { + "step 0"; + target.chooseToDiscard( + "he", + [1, target.countCards("he")], + "弃置任意张牌并摸等量的牌" + ).ai = function (card) { + return 6 - get.value(card); + }; + "step 1"; + if (result.bool) { + target.draw(result.cards.length); + } + }, + ai: { + order: 1.5, + value: [4, 1], + tag: { + norepeat: 1, + }, + result: { + target: function (player, target) { + if (target == player) { + var cards = player.getCards("he"); + var num = -1; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) < 6) num++; + } + if (player.needsToDiscard() && num < 1) { + num = 1; + } + return Math.max(0, num); + } else { + if (!player.needsToDiscard() && target.countCards("he") <= 3) { + return 0; + } + return target.countCards("he") / 2; + } + }, + }, + }, + }, + dinvxuanshuang: { + fullskin: true, + type: "basic", + savable: true, + selectTarget: -1, + content: function () { + "step 0"; + target.recover(); + "step 1"; + if (target.isIn()) { + target.chooseToDiscard([1, Infinity], "he", "弃置任意张牌并摸等量的牌"); + } else { + event.finish(); + } + "step 2"; + if (result.bool) { + target.draw(result.cards.length); + } + }, + ai: { + basic: { + order: 6, + useful: 10, + value: [8, 6.5, 5, 4], + }, + result: { + target: 2, + }, + tag: { + recover: 1, + save: 1, + }, + }, + }, + dinvxuanshuang_old: { + fullskin: true, + type: "basic", + enable: true, + // range:{global:1}, + filterTarget: function (card, player, target) { + return !target.hujia; + }, + content: function () { + target.storage.dinvxuanshuang_skill = game.createCard("dinvxuanshuang"); + target.addSkill("dinvxuanshuang_skill"); + if (cards && cards.length) { + card = cards[0]; + } + if ( + target == targets[0] && + card.clone && + (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena) + ) { + card.clone.moveDelete(target); + game.addVideo("gain2", target, get.cardsInfo([card])); + } + }, + ai: { + basic: { + order: 7, + useful: 5, + value: [8, 6.5, 5, 4], + }, + result: { + target: function (player, target) { + var num = + 1 / Math.sqrt(1 + target.hp) + 0.1 / Math.sqrt(target.countCards("h") + 1); + if (player == target) num *= 1.2; + return num; + }, + }, + }, + }, + ziyangdan: { + fullskin: true, + type: "basic", + enable: true, + filterTarget: true, + content: function () { + target.changeHujia(3); + if (target.hasSkill("ziyangdan")) { + target.storage.ziyangdan += 3; + } else { + target.addSkill("ziyangdan"); + } + }, + ai: { + order: 1.6, + value: [7, 1], + useful: 3, + tag: { + norepeat: 1, + }, + result: { + target: function (player, target) { + if (target.hp > 2) { + if (player.needsToDiscard()) return 1 / target.hp; + return 0; + } + if (target.hp > 0) { + return 2 / target.hp; + } + return 0; + }, + }, + }, + }, + yunvyuanshen: { + fullskin: true, + type: "basic", + enable: true, + logv: false, + filterTarget: function (card, player, target) { + return !target.hasSkill("yunvyuanshen_skill"); + }, + content: function () { + target.storage.yunvyuanshen_skill = game.createCard("yunvyuanshen"); + target.addSkill("yunvyuanshen_skill"); + if (cards && cards.length) { + card = cards[0]; + } + if ( + target == targets[0] && + card.clone && + (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena) + ) { + card.clone.moveDelete(target); + game.addVideo("gain2", target, get.cardsInfo([card])); + } + }, + ai: { + basic: { + value: 9, + useful: 4, + value: 7, + }, + order: 2, + result: { + target: function (player, target) { + return 1 / Math.sqrt(1 + target.hp); + }, + }, + }, + }, + bingpotong: { + fullskin: true, + type: "jiguan", + enable: true, + wuxieable: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0; + }, + selectTarget: [1, 3], + content: function () { + "step 0"; + if (target.countCards("h") == 0 || player.countCards("h") == 0) { event.finish(); return; } - player.chooseCard('请展示一张手牌',true).set('ai',function(){ - var num=0; - var rand=_status.event.rand; - if(get.color(card)=='red'){ - if(rand) num-=6; - } - else{ - if(!rand) num-=6; - } - var value=get.value(card); - if(value>=8) return -100; - return num-value; - }).set('rand', Math.random()<0.5).prompt2='若与'+get.translation(target)+'展示的牌相同,你弃置展示的牌,'+get.translation(target)+'失去1点体力'; - "step 1" - event.card1=result.cards[0]; - target.chooseCard('请展示一张手牌',true).set('ai',function(card){ - var num=0; - var rand=_status.event.rand; - if(get.color(card)=='red'){ - if(rand) num-=6; - } - else{ - if(!rand) num-=6; - } - var value=get.value(card); - if(value>=8) return -100; - return num-value; - }).set('rand', Math.random()<0.5).prompt2='若与'+get.translation(player)+'展示的牌相同,'+get.translation(player)+'弃置展示的牌,你失去1点体力'; - "step 2" - event.card2=result.cards[0]; - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1,target,event.card2); + player + .chooseCard("请展示一张手牌", true) + .set("ai", function () { + var num = 0; + var rand = _status.event.rand; + if (get.color(card) == "red") { + if (rand) num -= 6; + } else { + if (!rand) num -= 6; + } + var value = get.value(card); + if (value >= 8) return -100; + return num - value; + }) + .set("rand", Math.random() < 0.5).prompt2 = + "若与" + + get.translation(target) + + "展示的牌相同,你弃置展示的牌," + + get.translation(target) + + "失去1点体力"; + "step 1"; + event.card1 = result.cards[0]; + target + .chooseCard("请展示一张手牌", true) + .set("ai", function (card) { + var num = 0; + var rand = _status.event.rand; + if (get.color(card) == "red") { + if (rand) num -= 6; + } else { + if (!rand) num -= 6; + } + var value = get.value(card); + if (value >= 8) return -100; + return num - value; + }) + .set("rand", Math.random() < 0.5).prompt2 = + "若与" + + get.translation(player) + + "展示的牌相同," + + get.translation(player) + + "弃置展示的牌,你失去1点体力"; + "step 2"; + event.card2 = result.cards[0]; + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + player.$compare(event.card1, target, event.card2); game.delay(4); - "step 3" - game.log(player,'展示了',event.card1); - game.log(target,'展示了',event.card2); - if(get.color(event.card2)==get.color(event.card1)){ - player.discard(event.card1).animate=false; + "step 3"; + game.log(player, "展示了", event.card1); + game.log(target, "展示了", event.card2); + if (get.color(event.card2) == get.color(event.card1)) { + player.discard(event.card1).animate = false; target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } target.loseHp(); event.finish(); - event.parent.cancelled=true; - } - else{ + event.parent.cancelled = true; + } else { player.$gain2(event.card1); target.$gain2(event.card2); game.delay(); } - ui.arena.classList.remove('thrownhighlight'); - game.addVideo('thrownhighlight2'); - "step 4" + ui.arena.classList.remove("thrownhighlight"); + game.addVideo("thrownhighlight2"); + "step 4"; // if(cards&&cards.length){ // player.gain(cards,'gain2'); // target.addTempSkill('bingpotong'); // } }, - ai:{ - basic:{ - order:2, - value:[5,1], - useful:1, + ai: { + basic: { + order: 2, + value: [5, 1], + useful: 1, }, - result:{ - player:function(player,target){ - if(player.countCards('h')<=Math.min(5,Math.max(2,player.hp))&&_status.event.name=='chooseToUse'){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard(new lib.element.VCard({name:'bingpotong'}))){ + result: { + player: function (player, target) { + if ( + player.countCards("h") <= Math.min(5, Math.max(2, player.hp)) && + _status.event.name == "chooseToUse" + ) { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard(new lib.element.VCard({ name: "bingpotong" })) + ) { return -10; } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='bingpotong') return -10; - if(viewAs&&viewAs.name=='bingpotong') return -10; + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "bingpotong") return -10; + if (viewAs && viewAs.name == "bingpotong") return -10; } } return 0; }, - target:function(player,target){ - if(player.countCards('h')<=1) return 0; + target: function (player, target) { + if (player.countCards("h") <= 1) return 0; return -1.5; - } + }, + }, + tag: { + loseHp: 1, }, - tag:{ - loseHp:1 - } - } - }, - feibiao:{ - type:'jiguan', - enable:true, - fullskin:true, - wuxieable:true, - outrange:{globalFrom:2}, - filterTarget:function(card,player,target){ - return target!=player; }, - content:function(){ - "step 0" - if(!target.countCards('h',{color:'black'})){ + }, + feibiao: { + type: "jiguan", + enable: true, + fullskin: true, + wuxieable: true, + outrange: { globalFrom: 2 }, + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + if (!target.countCards("h", { color: "black" })) { target.loseHp(); event.finish(); + } else { + target.chooseToDiscard({ color: "black" }, "弃置一张黑色手牌或受失去1点体力").ai = + function (card) { + return 8 - get.value(card); + }; } - else{ - target.chooseToDiscard({color:'black'},'弃置一张黑色手牌或受失去1点体力').ai=function(card){ - return 8-get.value(card); - }; - } - "step 1" - if(!result.bool){ + "step 1"; + if (!result.bool) { target.loseHp(); } }, - ai:{ - basic:{ - order:9, - value:3, - useful:1, + ai: { + basic: { + order: 9, + value: 3, + useful: 1, }, - result:{ - target:-2 + result: { + target: -2, + }, + tag: { + discard: 1, + loseHp: 1, }, - tag:{ - discard:1, - loseHp:1 - } - } - }, - longxugou:{ - type:'jiguan', - enable:true, - fullskin:true, - wuxieable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'e'); }, - content:function(){ - 'step 0' - var es=target.getGainableCards(player,'e') - if(es.length){ - player.choosePlayerCard('e',target,true).set('es',es).set('filterButton',function(button){ - return _status.event.es.includes(button.link); - }); - } - else{ + }, + longxugou: { + type: "jiguan", + enable: true, + fullskin: true, + wuxieable: true, + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "e"); + }, + content: function () { + "step 0"; + var es = target.getGainableCards(player, "e"); + if (es.length) { + player + .choosePlayerCard("e", target, true) + .set("es", es) + .set("filterButton", function (button) { + return _status.event.es.includes(button.link); + }); + } else { event.finish(); } - 'step 1' - if(result.bool){ - target.$give(result.links[0],player); - target.lose(result.links[0],ui.special); - event.card=result.links[0]; + "step 1"; + if (result.bool) { + target.$give(result.links[0], player); + target.lose(result.links[0], ui.special); + event.card = result.links[0]; game.delay(); - } - else{ + } else { event.finish(); } - 'step 2' - if(event.card&&get.position(event.card)=='s'){ + "step 2"; + if (event.card && get.position(event.card) == "s") { player.equip(event.card); } }, - ai:{ - basic:{ - order:9, - value:6, - useful:4, + ai: { + basic: { + order: 9, + value: 6, + useful: 4, }, - result:{ - target:-1 + result: { + target: -1, }, - tag:{ - loseCard:1, - gain:1, - } - } + tag: { + loseCard: 1, + gain: 1, + }, + }, }, - qiankunbiao:{ - type:'jiguan', - enable:true, - fullskin:true, - wuxieable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + qiankunbiao: { + type: "jiguan", + enable: true, + fullskin: true, + wuxieable: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - changeTarget:function(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1&¤t.countCards('he'); - },targets); + changeTarget: function (player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1 && current.countCards("he"); + }, targets); }, - content:function(){ - var he=target.getCards('he'); - if(he.length){ - target.discard(he.randomGet()).delay=false; + content: function () { + var he = target.getCards("he"); + if (he.length) { + target.discard(he.randomGet()).delay = false; } }, - contentAfter:function(){ + contentAfter: function () { game.delay(0.5); }, - ai:{ - order:7, - tag:{ - loseCard:1, - discard:1, + ai: { + order: 7, + tag: { + loseCard: 1, + discard: 1, }, - wuxie:function(){ + wuxie: function () { return 0; }, - result:{ - target:-1, - } - } + result: { + target: -1, + }, + }, }, - shenhuofeiya:{ - type:'jiguan', - enable:true, - fullskin:true, - wuxieable:true, - filterTarget:function(card,player,target){ - return target!=player; + shenhuofeiya: { + type: "jiguan", + enable: true, + fullskin: true, + wuxieable: true, + filterTarget: function (card, player, target) { + return target != player; }, - changeTarget:function(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1; - },targets); + changeTarget: function (player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1; + }, targets); }, - cardcolor:'red', - cardnature:'fire', - content:function(){ - "step 0" - var next=target.chooseToRespond({name:'shan'}); - next.ai=function(card){ - if(get.damageEffect(target,player,target,'fire')>=0) return 0; - if(player.hasSkillTag('notricksource')) return 0; - if(target.hasSkillTag('notrick')) return 0; - if(target.hasSkillTag('noShan')){ + cardcolor: "red", + cardnature: "fire", + content: function () { + "step 0"; + var next = target.chooseToRespond({ name: "shan" }); + next.ai = function (card) { + if (get.damageEffect(target, player, target, "fire") >= 0) return 0; + if (player.hasSkillTag("notricksource")) return 0; + if (target.hasSkillTag("notrick")) return 0; + if (target.hasSkillTag("noShan")) { return -1; } - return 11-get.value(card); + return 11 - get.value(card); }; - next.autochoose=lib.filter.autoRespondShan; - "step 1" - if(result.bool==false){ - target.damage('fire'); + next.autochoose = lib.filter.autoRespondShan; + "step 1"; + if (result.bool == false) { + target.damage("fire"); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0&&target.countCards('h','shan')){ - if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.attitude(viewer, target) > 0 && target.countCards("h", "shan")) { + if (!target.countCards("h") || target.hp == 1 || Math.random() < 0.7) return 0; } - if(get.attitude(viewer,target)<=0){ + if (get.attitude(viewer, target) <= 0) { return 0; } }, - order:7, - tag:{ - respond:1, - respondShan:1, - damage:1, - natureDamage:1, - fireDamage:1, - multitarget:1, - multineg:1, + order: 7, + tag: { + respond: 1, + respondShan: 1, + damage: 1, + natureDamage: 1, + fireDamage: 1, + multitarget: 1, + multineg: 1, }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nofire')) return 0; - if(player.hasUnknown(2)) return 0; - var nh=target.countCards('h'); - if(lib.config.mode=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + result: { + target: function (player, target) { + if (target.hasSkillTag("nofire")) return 0; + if (player.hasUnknown(2)) return 0; + var nh = target.countCards("h"); + if (lib.config.mode == "identity") { + if (target.isZhu && nh <= 2 && target.hp <= 1) return -100; } - if(nh==0) return -2; - if(nh==1) return -1.7 + if (nh == 0) return -2; + if (nh == 1) return -1.7; return -1.5; }, - } - } + }, + }, }, // wenhuangsan:{ // type:'jiguan', @@ -958,978 +983,1035 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // enable:true, // fullskin:true, // }, - mianlijinzhen:{ - type:'jiguan', - enable:true, - fullskin:true, - filterTarget:function(card,player,target){ - return target.hp>=player.hp; + mianlijinzhen: { + type: "jiguan", + enable: true, + fullskin: true, + filterTarget: function (card, player, target) { + return target.hp >= player.hp; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.draw(); - 'step 1' + "step 1"; target.loseHp(); }, - ai:{ - order:2, - value:[5,1], - useful:[4,1], - result:{ - target:-1.5 + ai: { + order: 2, + value: [5, 1], + useful: [4, 1], + result: { + target: -1.5, }, - tag:{ + tag: { // damage:1 - } - } + }, + }, }, // longxugou:{ // type:'jiguan', // enable:true, // fullskin:true, // }, - liutouge:{ - type:'jiguan', - enable:true, - fullskin:true, - filterTarget:true, - wuxieable:true, - content:function(){ - if(player.getEnemies().includes(target)){ + liutouge: { + type: "jiguan", + enable: true, + fullskin: true, + filterTarget: true, + wuxieable: true, + content: function () { + if (player.getEnemies().includes(target)) { target.getDebuff(); - } - else{ + } else { target.getBuff(); } }, - ai:{ - order:4, - value:5, - result:{ - player:function(player,target){ - if(get.attitude(player,target)==0) return 0; + ai: { + order: 4, + value: 5, + result: { + player: function (player, target) { + if (get.attitude(player, target) == 0) return 0; return 1; - } - } - } - }, - liufengsan:{ - type:'trick', - enable:true, - fullskin:true, - filterTarget:true, - content:function(){ - var list=[]; - for(var i=0;i<2;i++){ - list.push(game.createCard('shan')); - } - target.gain(list,'gain2'); - }, - ai:{ - order:4.5, - value:[5,1], - tag:{ - gain:1, - norepeat:1 + }, }, - result:{ - target:function(player,target){ - if(target==player){ - if(!target.hasShan()) return 2; - var num=target.needsToDiscard(2); - if(num==0) return 1.5; - if(num==1) return 1; + }, + }, + liufengsan: { + type: "trick", + enable: true, + fullskin: true, + filterTarget: true, + content: function () { + var list = []; + for (var i = 0; i < 2; i++) { + list.push(game.createCard("shan")); + } + target.gain(list, "gain2"); + }, + ai: { + order: 4.5, + value: [5, 1], + tag: { + gain: 1, + norepeat: 1, + }, + result: { + target: function (player, target) { + if (target == player) { + if (!target.hasShan()) return 2; + var num = target.needsToDiscard(2); + if (num == 0) return 1.5; + if (num == 1) return 1; return 0.5; - } - else{ - switch(target.countCards('h')){ - case 0:return 2; - case 1:return 1.5; - case 2:return 1; - default:return 0.5; + } else { + switch (target.countCards("h")) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return 1; + default: + return 0.5; } } - } - } - } + }, + }, + }, }, - shihuifen:{ - type:'trick', - fullskin:true, - filterTarget:true, - global:'g_shihuifen', - content:function(){ - 'step 0' - var next=_status.currentPhase.chooseToRespond({name:'shan'}); - next.set('prompt2','否则本回合无法对其他角色使用卡牌'); - 'step 1' - if(!result.bool){ - _status.currentPhase.addTempSkill('shihuifen','phaseUseAfter'); + shihuifen: { + type: "trick", + fullskin: true, + filterTarget: true, + global: "g_shihuifen", + content: function () { + "step 0"; + var next = _status.currentPhase.chooseToRespond({ name: "shan" }); + next.set("prompt2", "否则本回合无法对其他角色使用卡牌"); + "step 1"; + if (!result.bool) { + _status.currentPhase.addTempSkill("shihuifen", "phaseUseAfter"); } }, - ai:{ - order:1, - value:[5,1], - useful:[5,1], - tag:{ - respond:1, - respondShan:1, + ai: { + order: 1, + value: [5, 1], + useful: [5, 1], + tag: { + respond: 1, + respondShan: 1, }, - result:{ - target:function(player,target){ - if(target.countCards('h')>=3||target.needsToDiscard()) return -1.5; + result: { + target: function (player, target) { + if (target.countCards("h") >= 3 || target.needsToDiscard()) return -1.5; return 0; - } - } - } + }, + }, + }, }, }, - skill:{ - ziyangdan:{ - trigger:{player:'phaseBegin'}, - silent:true, - init:function(player){ - player.storage.ziyangdan=3; + skill: { + ziyangdan: { + trigger: { player: "phaseBegin" }, + silent: true, + init: function (player) { + player.storage.ziyangdan = 3; }, - onremove:true, - content:function(){ - if(player.hujia>0){ + onremove: true, + content: function () { + if (player.hujia > 0) { player.changeHujia(-1); } player.storage.ziyangdan--; - if(player.hujia==0||player.storage.ziyangdan==0){ - player.removeSkill('ziyangdan'); + if (player.hujia == 0 || player.storage.ziyangdan == 0) { + player.removeSkill("ziyangdan"); } }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, - luyugeng:{ - mark:'card', - enable:'phaseUse', - usable:1, - nopop:true, - filterCard:{type:'basic'}, - filter:function(event,player){ - return player.countCards('h',{type:'basic'}); + luyugeng: { + mark: "card", + enable: "phaseUse", + usable: 1, + nopop: true, + filterCard: { type: "basic" }, + filter: function (event, player) { + return player.countCards("h", { type: "basic" }); }, - intro:{ - content:function(storage,player){ - return '出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续两回合(剩余'+player.storage.luyugeng_markcount+'回合)' - } + intro: { + content: function (storage, player) { + return ( + "出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续两回合(剩余" + + player.storage.luyugeng_markcount + + "回合)" + ); + }, }, - content:function(){ + content: function () { player.discoverCard(); }, - group:'luyugeng_count', - subSkill:{ - count:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - content:function(){ + group: "luyugeng_count", + subSkill: { + count: { + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + content: function () { player.storage.luyugeng_markcount--; - if(player.storage.luyugeng_markcount==0){ + if (player.storage.luyugeng_markcount == 0) { delete player.storage.luyugeng; delete player.storage.luyugeng_markcount; - player.removeSkill('luyugeng'); - } - else{ + player.removeSkill("luyugeng"); + } else { player.updateMarks(); } }, - } - } + }, + }, }, - xiajiao:{ - mark:'card', - trigger:{player:['phaseUseBefore','phaseEnd']}, - forced:true, - popup:false, - nopop:true, - filter:function(event,player){ - return !player.hasSkill('xiajiao3'); + xiajiao: { + mark: "card", + trigger: { player: ["phaseUseBefore", "phaseEnd"] }, + forced: true, + popup: false, + nopop: true, + filter: function (event, player) { + return !player.hasSkill("xiajiao3"); }, - intro:{ - content:function(storage,player){ - return '你在摸牌阶段额外摸一张牌,然后弃置一张牌(剩余'+player.storage.xiajiao_markcount+'回合)' - } + intro: { + content: function (storage, player) { + return ( + "你在摸牌阶段额外摸一张牌,然后弃置一张牌(剩余" + + player.storage.xiajiao_markcount + + "回合)" + ); + }, }, - content:function(){ + content: function () { player.storage.xiajiao_markcount--; - if(player.storage.xiajiao_markcount==0){ + if (player.storage.xiajiao_markcount == 0) { delete player.storage.xiajiao; delete player.storage.xiajiao_markcount; - player.removeSkill('xiajiao'); - } - else{ + player.removeSkill("xiajiao"); + } else { player.updateMarks(); } - player.addTempSkill('xiajiao3'); + player.addTempSkill("xiajiao3"); }, - group:'xiajiao_draw', - subSkill:{ - draw:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ + group: "xiajiao_draw", + subSkill: { + draw: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + content: function () { trigger.num++; - player.addTempSkill('xiajiao2'); - } - } - } - }, - xiajiao2:{ - trigger:{player:'phaseDrawAfter'}, - silent:true, - content:function(){ - player.chooseToDiscard('he',true); - } - }, - xiajiao3:{}, - mizhilianou:{ - mark:'card', - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '你可以将一张红桃牌当作桃使用(剩余'+player.storage.mizhilianou_markcount+'回合)' - } + player.addTempSkill("xiajiao2"); + }, + }, }, - content:function(){ + }, + xiajiao2: { + trigger: { player: "phaseDrawAfter" }, + silent: true, + content: function () { + player.chooseToDiscard("he", true); + }, + }, + xiajiao3: {}, + mizhilianou: { + mark: "card", + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "你可以将一张红桃牌当作桃使用(剩余" + + player.storage.mizhilianou_markcount + + "回合)" + ); + }, + }, + content: function () { player.storage.mizhilianou_markcount--; - if(player.storage.mizhilianou_markcount==0){ + if (player.storage.mizhilianou_markcount == 0) { delete player.storage.mizhilianou; delete player.storage.mizhilianou_markcount; - player.removeSkill('mizhilianou'); - } - else{ + player.removeSkill("mizhilianou"); + } else { player.updateMarks(); } }, - group:'mizhilianou_use', - subSkill:{ - use:{ - enable:'chooseToUse', - filterCard:{suit:'heart'}, - position:'he', - viewAs:{name:'tao'}, - viewAsFilter:function(player){ - return player.countCards('he',{suit:'heart'})>0; + group: "mizhilianou_use", + subSkill: { + use: { + enable: "chooseToUse", + filterCard: { suit: "heart" }, + position: "he", + viewAs: { name: "tao" }, + viewAsFilter: function (player) { + return player.countCards("he", { suit: "heart" }) > 0; }, - prompt:'将一张红桃牌当桃使用', - check:function(card){return 10-get.value(card)}, - ai:{ - skillTagFilter:function(player){ - return player.countCards('he',{suit:'heart'})>0; + prompt: "将一张红桃牌当桃使用", + check: function (card) { + return 10 - get.value(card); + }, + ai: { + skillTagFilter: function (player) { + return player.countCards("he", { suit: "heart" }) > 0; }, - save:true, - respondTao:true, - } - } - } + save: true, + respondTao: true, + }, + }, + }, }, - chunbing:{ - mark:'card', - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '你的手牌上限+1(剩余'+player.storage.chunbing_markcount+'回合)' - } + chunbing: { + mark: "card", + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return "你的手牌上限+1(剩余" + player.storage.chunbing_markcount + "回合)"; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num+1; - } + mod: { + maxHandcard: function (player, num) { + return num + 1; + }, }, - content:function(){ + content: function () { player.storage.chunbing_markcount--; - if(player.storage.chunbing_markcount==0){ + if (player.storage.chunbing_markcount == 0) { delete player.storage.chunbing; delete player.storage.chunbing_markcount; - player.removeSkill('chunbing'); - } - else{ + player.removeSkill("chunbing"); + } else { player.updateMarks(); } }, }, - gudonggeng:{ - mark:'card', - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '当你下一次受到杀造成的伤害时,令伤害-1(剩余'+player.storage.gudonggeng_markcount+'回合)' - } + gudonggeng: { + mark: "card", + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "当你下一次受到杀造成的伤害时,令伤害-1(剩余" + + player.storage.gudonggeng_markcount + + "回合)" + ); + }, }, - content:function(){ + content: function () { player.storage.gudonggeng_markcount--; - if(player.storage.gudonggeng_markcount==0){ + if (player.storage.gudonggeng_markcount == 0) { delete player.storage.gudonggeng; delete player.storage.gudonggeng_markcount; - player.removeSkill('gudonggeng'); - } - else{ + player.removeSkill("gudonggeng"); + } else { player.updateMarks(); } }, - group:'gudonggeng_damage', - subSkill:{ - damage:{ - trigger:{player:'damageBegin'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.num>0; + group: "gudonggeng_damage", + subSkill: { + damage: { + trigger: { player: "damageBegin" }, + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.num > 0; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num--; delete player.storage.gudonggeng; delete player.storage.gudonggeng_markcount; - player.removeSkill('gudonggeng'); - } - } + player.removeSkill("gudonggeng"); + }, + }, + }, + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "sha" && get.attitude(player, target) < 0) return 0.5; + }, + }, }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='sha'&&get.attitude(player,target)<0) return 0.5; - } - } - } }, - qingtuan:{ - mark:'card', - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '你在回合内使用首张杀时摸一张牌(剩余'+player.storage.qingtuan_markcount+'回合)' - } + qingtuan: { + mark: "card", + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "你在回合内使用首张杀时摸一张牌(剩余" + + player.storage.qingtuan_markcount + + "回合)" + ); + }, }, - content:function(){ + content: function () { player.storage.qingtuan_markcount--; - if(player.storage.qingtuan_markcount==0){ + if (player.storage.qingtuan_markcount == 0) { delete player.storage.qingtuan; delete player.storage.qingtuan_markcount; - player.removeSkill('qingtuan'); - } - else{ + player.removeSkill("qingtuan"); + } else { player.updateMarks(); } }, - group:'qingtuan_draw', - subSkill:{ - draw:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='sha'&&_status.currentPhase==player; + group: "qingtuan_draw", + subSkill: { + draw: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "sha" && _status.currentPhase == player; }, - usable:1, - forced:true, - content:function(){ + usable: 1, + forced: true, + content: function () { player.draw(); - } - } - } - }, - liyutang:{ - mark:'card', - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '结束阶段,若你的体力值为全场最少或之一,你获得1点护甲(剩余'+player.storage.liyutang_markcount+'回合)' - } + }, + }, }, - content:function(){ - if(player.isMinHp()){ - player.logSkill('liyutang'); + }, + liyutang: { + mark: "card", + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "结束阶段,若你的体力值为全场最少或之一,你获得1点护甲(剩余" + + player.storage.liyutang_markcount + + "回合)" + ); + }, + }, + content: function () { + if (player.isMinHp()) { + player.logSkill("liyutang"); player.changeHujia(); } player.storage.liyutang_markcount--; - if(player.storage.liyutang_markcount==0){ + if (player.storage.liyutang_markcount == 0) { delete player.storage.liyutang; delete player.storage.liyutang_markcount; - player.removeSkill('liyutang'); - } - else{ + player.removeSkill("liyutang"); + } else { player.updateMarks(); } }, }, - yougeng:{ - mark:'card', - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '准备阶段,若你的体力值为全场最少或之一,你回复1点体力(剩余'+player.storage.yougeng_markcount+'回合)' - } + yougeng: { + mark: "card", + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "准备阶段,若你的体力值为全场最少或之一,你回复1点体力(剩余" + + player.storage.yougeng_markcount + + "回合)" + ); + }, }, - content:function(){ - if(player.isDamaged()&&player.isMinHp()){ - player.logSkill('yougeng'); + content: function () { + if (player.isDamaged() && player.isMinHp()) { + player.logSkill("yougeng"); player.recover(); } player.storage.yougeng_markcount--; - if(player.storage.yougeng_markcount==0){ + if (player.storage.yougeng_markcount == 0) { delete player.storage.yougeng; delete player.storage.yougeng_markcount; - player.removeSkill('yougeng'); - } - else{ + player.removeSkill("yougeng"); + } else { player.updateMarks(); } }, }, - molicha:{ - mark:'card', - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '你不能成为其他角色的黑色牌的目标(剩余'+player.storage.molicha_markcount+'回合)' - } + molicha: { + mark: "card", + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "你不能成为其他角色的黑色牌的目标(剩余" + + player.storage.molicha_markcount + + "回合)" + ); + }, }, - mod:{ - targetEnabled:function(card,player,target){ - if(player!=target&&get.color(card)=='black'){ + mod: { + targetEnabled: function (card, player, target) { + if (player != target && get.color(card) == "black") { return false; } - } + }, }, - content:function(){ + content: function () { player.storage.molicha_markcount--; - if(player.storage.molicha_markcount==0){ + if (player.storage.molicha_markcount == 0) { delete player.storage.molicha; delete player.storage.molicha_markcount; - player.removeSkill('molicha'); - player.logSkill('molicha'); - } - else{ + player.removeSkill("molicha"); + player.logSkill("molicha"); + } else { player.updateMarks(); } - } + }, }, - yuanbaorou:{ - mark:'card', - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '你在出牌阶段可以额外使用一张杀(剩余'+player.storage.yuanbaorou_markcount+'回合)' - } + yuanbaorou: { + mark: "card", + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "你在出牌阶段可以额外使用一张杀(剩余" + + player.storage.yuanbaorou_markcount + + "回合)" + ); + }, }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, }, - content:function(){ + content: function () { player.storage.yuanbaorou_markcount--; - if(player.storage.yuanbaorou_markcount==0){ + if (player.storage.yuanbaorou_markcount == 0) { delete player.storage.yuanbaorou; delete player.storage.yuanbaorou_markcount; - player.removeSkill('yuanbaorou'); - } - else{ + player.removeSkill("yuanbaorou"); + } else { player.updateMarks(); } }, }, - tanhuadong:{ - mark:'card', - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - nopop:true, - intro:{ - content:function(storage,player){ - return '出牌阶段结束时,你摸一张牌(剩余'+player.storage.tanhuadong_markcount+'回合)' - } + tanhuadong: { + mark: "card", + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + nopop: true, + intro: { + content: function (storage, player) { + return ( + "出牌阶段结束时,你摸一张牌(剩余" + + player.storage.tanhuadong_markcount + + "回合)" + ); + }, }, - content:function(){ + content: function () { player.storage.tanhuadong_markcount--; - if(player.storage.tanhuadong_markcount==0){ + if (player.storage.tanhuadong_markcount == 0) { delete player.storage.tanhuadong; delete player.storage.tanhuadong_markcount; - player.removeSkill('tanhuadong'); - } - else{ + player.removeSkill("tanhuadong"); + } else { player.updateMarks(); } }, - group:'tanhuadong_draw', - subSkill:{ - draw:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - content:function(){ + group: "tanhuadong_draw", + subSkill: { + draw: { + trigger: { player: "phaseUseEnd" }, + forced: true, + content: function () { player.draw(); - } - } - } - }, - mapodoufu:{ - mark:'card', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - popup:false, - nopop:true, - forceLoad:true, - intro:{ - content:function(storage,player){ - return '结束阶段,你随机弃置一名随机敌人的一张随机牌(剩余'+player.storage.mapodoufu_markcount+'回合)' - } + }, + }, }, - content:function(){ - var list=player.getEnemies(); - for(var i=0;i=3){ - card.init([card.suit,card.number,'gjyuheng_plus',card.nature]); - player.addTempSkill('gjyuheng_plus_temp'); + if (card.storage.gjyuheng >= 3) { + card.init([card.suit, card.number, "gjyuheng_plus", card.nature]); + player.addTempSkill("gjyuheng_plus_temp"); } } }, - ai:{ - order:9, - result:{ - player:1 - } - } - }, - gjyuheng_plus_temp:{}, - gjyuheng_plus_skill:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'black'}, - check:function(card){ - return 8-get.value(card); + ai: { + order: 9, + result: { + player: 1, + }, }, - filter:function(event,player){ + }, + gjyuheng_plus_temp: {}, + gjyuheng_plus_skill: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "black" }, + check: function (card) { + return 8 - get.value(card); + }, + filter: function (event, player) { // if(player.hasSkill('gjyuheng_plus_temp')) return false; - if(!player.countCards('h',{color:'black'})) return false; - var enemies=player.getEnemies(); - for(var i=0;i=7){ - card.init([card.suit,card.number,'gjyuheng_pro',card.nature]); + if (card.storage.gjyuheng >= 7) { + card.init([card.suit, card.number, "gjyuheng_pro", card.nature]); } } }, - ai:{ - order:9, - result:{ - player:1 - } - } - }, - gjyuheng_pro_skill:{ - enable:'phaseUse', - filterCard:{color:'black'}, - check:function(card){ - return 8-get.value(card); + ai: { + order: 9, + result: { + player: 1, + }, }, - filter:function(event,player){ - if(!player.countCards('h',{color:'black'})) return false; - var enemies=player.getEnemies(); - for(var i=0;i=3){ - card.init([card.suit,card.number,'gjyuheng_plus',card.nature]); - player.addTempSkill('gjyuheng_plus_temp'); + if (card.storage.gjyuheng >= 3) { + card.init([card.suit, card.number, "gjyuheng_plus", card.nature]); + player.addTempSkill("gjyuheng_plus_temp"); } } }, - ai:{ - order:9, - result:{ - player:1 - } - } - }, - shihuifen:{ - mark:true, - intro:{ - content:'使用卡牌无法指定其他角色为目标' + ai: { + order: 9, + result: { + player: 1, + }, }, - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; - } - } }, - g_shihuifen:{ - trigger:{global:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - if(event.player.hasSkill('shihuifen')) return false; - if(event.player==player) return false; - if(!lib.filter.targetEnabled({name:'shihuifen'},player,event.player)) return false; - return player.hasCard('shihuifen')||player.hasSkillTag('shihuifen'); + shihuifen: { + mark: true, + intro: { + content: "使用卡牌无法指定其他角色为目标", + }, + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; + }, }, - content:function(){ - player.chooseToUse(get.prompt('shihuifen',trigger.player).replace(/发动/,'使用'),function(card,player){ - if(card.name!='shihuifen') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - },trigger.player,-1).targetRequired=true; - } }, - g_jinlianzhu:{ - trigger:{global:'damageBefore'}, - direct:true, - filter:function(event,player){ - if(!lib.filter.targetEnabled({name:'jinlianzhu'},player,event.player)) return false; - return player.hasCard('jinlianzhu'); + g_shihuifen: { + trigger: { global: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + if (event.player.hasSkill("shihuifen")) return false; + if (event.player == player) return false; + if (!lib.filter.targetEnabled({ name: "shihuifen" }, player, event.player)) return false; + return player.hasCard("shihuifen") || player.hasSkillTag("shihuifen"); + }, + content: function () { + player.chooseToUse( + get.prompt("shihuifen", trigger.player).replace(/发动/, "使用"), + function (card, player) { + if (card.name != "shihuifen") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }, + trigger.player, + -1 + ).targetRequired = true; + }, + }, + g_jinlianzhu: { + trigger: { global: "damageBefore" }, + direct: true, + filter: function (event, player) { + if (!lib.filter.targetEnabled({ name: "jinlianzhu" }, player, event.player)) return false; + return player.hasCard("jinlianzhu"); + }, + content: function () { + player.chooseToUse( + get.prompt("jinlianzhu", trigger.player).replace(/发动/, "使用"), + function (card, player) { + if (card.name != "jinlianzhu") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }, + trigger.player, + -1 + ).targetRequired = true; }, - content:function(){ - player.chooseToUse(get.prompt('jinlianzhu',trigger.player).replace(/发动/,'使用'),function(card,player){ - if(card.name!='jinlianzhu') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - },trigger.player,-1).targetRequired=true; - } }, }, - cardType:{ - food:0.3 + cardType: { + food: 0.3, }, - translate:{ - jinlianzhu:'金莲珠', - jinlianzhu_info:'对一名即将受到伤害的角色使用,防止此伤害,并令伤害来源摸一张牌。', - shihuifen:'石灰粉', - shihuifen_info:'在一名其他角色的出牌阶段开始时对其使用,目标需打出一张闪,否则此阶段使用卡牌无法指定其他角色为目标。', - liufengsan:'流风散', - liufengsan_info:'出牌阶段对一名角色使用,目标获得两张闪。', - liutouge:'六骰格', - liutouge_info:'出牌阶段对一名角色使用,若目标是敌人,对目标施加一个随机的负面效果;否则对目标施加一个随机的正面效果。', - longxugou:'龙须钩', - longxugou_info:'出牌阶段对一名装备区内有牌的其他角色使用,获得其装备区内的一张牌并装备之。', - mianlijinzhen:'棉里针', - mianlijinzhen_info:'出牌阶段对一名体力值不小于你的角色使用,目标摸一张牌然后失去1点体力。', - shenhuofeiya:'神火飞鸦', - shenhuofeiya_info:'出牌阶段对一名其他角色和其相邻角色使用,目标需打出一张闪,否则受到1点火属性伤害。', + translate: { + jinlianzhu: "金莲珠", + jinlianzhu_info: "对一名即将受到伤害的角色使用,防止此伤害,并令伤害来源摸一张牌。", + shihuifen: "石灰粉", + shihuifen_info: + "在一名其他角色的出牌阶段开始时对其使用,目标需打出一张闪,否则此阶段使用卡牌无法指定其他角色为目标。", + liufengsan: "流风散", + liufengsan_info: "出牌阶段对一名角色使用,目标获得两张闪。", + liutouge: "六骰格", + liutouge_info: + "出牌阶段对一名角色使用,若目标是敌人,对目标施加一个随机的负面效果;否则对目标施加一个随机的正面效果。", + longxugou: "龙须钩", + longxugou_info: "出牌阶段对一名装备区内有牌的其他角色使用,获得其装备区内的一张牌并装备之。", + mianlijinzhen: "棉里针", + mianlijinzhen_info: "出牌阶段对一名体力值不小于你的角色使用,目标摸一张牌然后失去1点体力。", + shenhuofeiya: "神火飞鸦", + shenhuofeiya_info: + "出牌阶段对一名其他角色和其相邻角色使用,目标需打出一张闪,否则受到1点火属性伤害。", // tuhunsha:'土魂砂', // tuhunsha_info:'土魂砂', // wenhuangsan:'瘟癀伞', // wenhuangsan_info:'瘟癀伞', - qiankunbiao:'乾坤镖', - qiankunbiao_info:'随机弃置一名其他角色和其相邻角色的一张牌。', + qiankunbiao: "乾坤镖", + qiankunbiao_info: "随机弃置一名其他角色和其相邻角色的一张牌。", - bingpotong:'天女散花', - bingpotong_ab:'散花', - bingpotong_info:'出牌阶段对至多3名角色使用,你与每个目标依次同时展示一张手牌,若颜色相同,你弃置展示的手牌,目标失去1点体力并终止结算。', - feibiao:'飞镖', - feibiao_info:'出牌阶段,对一名距离1以外的角色使用,令其弃置一张黑色手牌或失去1点体力。', + bingpotong: "天女散花", + bingpotong_ab: "散花", + bingpotong_info: + "出牌阶段对至多3名角色使用,你与每个目标依次同时展示一张手牌,若颜色相同,你弃置展示的手牌,目标失去1点体力并终止结算。", + feibiao: "飞镖", + feibiao_info: "出牌阶段,对一名距离1以外的角色使用,令其弃置一张黑色手牌或失去1点体力。", - dinvxuanshuang:'帝女玄霜', - dinvxuanshuang_skill:'帝女玄霜', - dinvxuanshuang_info:'对一名濒死状态的角色使用,目标回复1点体力,然后可以弃置任意张牌并摸等量的牌。', - yunvyuanshen:'玉女元参', - yunvyuanshen_skill:'玉女元参', - yunvyuanshen_info:'出牌阶段对一名角色使用,目标在下一次进入濒死状态时回复1点体力。', - ziyangdan:'紫阳丹', - ziyangdan_info:'出牌阶段对一名角色使用,目标获得3点护甲,此后每个准备阶段失去1点护甲,直到首次失去所有护甲或累计以此法失去3点护甲。', - gjyuheng:'玉衡', - gjyuheng_plus:'玉衡', - gjyuheng_pro:'玉衡', - gjyuheng_skill:'玉衡', - gjyuheng_plus_skill:'玉衡', - gjyuheng_pro_skill:'玉衡', - gjyuheng_info:'出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌(此牌在本局游戏中第三次和第七次发动效果后,分别自动获得一次强化)。', - gjyuheng_plus_info:'由普通玉衡强化得到,将玉衡技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”。', - gjyuheng_pro_info:'由普通玉衡二次强化得到,将玉横技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”,并去掉使用次数限制。', - gjyuheng_skill_info:'出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。', - gjyuheng_plus_skill_info:'出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。', - gjyuheng_pro_skill_info:'出牌阶段限,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。', - shujinsan:'舒筋散', - shujinsan_info:'出牌阶段对任意角色使用,目标可弃置任意张牌,并摸等量的牌。', - mutoumianju:'木头面具', - mutoumianju_info:'出牌阶段限一次,你可以将一张手牌当作杀使用。', - mutoumianju_skill:'木杀', - mutoumianju_skill_info:'出牌阶段限一次,你可以将一张手牌当作杀使用。', - heilonglinpian:'黑龙鳞片', - heilonglinpian_info:'出牌阶段对自己使用,获得1点护甲,直到下一回合开始,你的防御距离+1。', - shatang:'沙棠', - shatang_info:'出牌阶段对一名角色使用,对目标造成1点火焰伤害,然后目标获得1点护甲。', + dinvxuanshuang: "帝女玄霜", + dinvxuanshuang_skill: "帝女玄霜", + dinvxuanshuang_info: + "对一名濒死状态的角色使用,目标回复1点体力,然后可以弃置任意张牌并摸等量的牌。", + yunvyuanshen: "玉女元参", + yunvyuanshen_skill: "玉女元参", + yunvyuanshen_info: "出牌阶段对一名角色使用,目标在下一次进入濒死状态时回复1点体力。", + ziyangdan: "紫阳丹", + ziyangdan_info: + "出牌阶段对一名角色使用,目标获得3点护甲,此后每个准备阶段失去1点护甲,直到首次失去所有护甲或累计以此法失去3点护甲。", + gjyuheng: "玉衡", + gjyuheng_plus: "玉衡", + gjyuheng_pro: "玉衡", + gjyuheng_skill: "玉衡", + gjyuheng_plus_skill: "玉衡", + gjyuheng_pro_skill: "玉衡", + gjyuheng_info: + "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌(此牌在本局游戏中第三次和第七次发动效果后,分别自动获得一次强化)。", + gjyuheng_plus_info: + "由普通玉衡强化得到,将玉衡技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”。", + gjyuheng_pro_info: + "由普通玉衡二次强化得到,将玉横技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”,并去掉使用次数限制。", + gjyuheng_skill_info: + "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", + gjyuheng_plus_skill_info: + "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", + gjyuheng_pro_skill_info: + "出牌阶段限,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", + shujinsan: "舒筋散", + shujinsan_info: "出牌阶段对任意角色使用,目标可弃置任意张牌,并摸等量的牌。", + mutoumianju: "木头面具", + mutoumianju_info: "出牌阶段限一次,你可以将一张手牌当作杀使用。", + mutoumianju_skill: "木杀", + mutoumianju_skill_info: "出牌阶段限一次,你可以将一张手牌当作杀使用。", + heilonglinpian: "黑龙鳞片", + heilonglinpian_info: "出牌阶段对自己使用,获得1点护甲,直到下一回合开始,你的防御距离+1。", + shatang: "沙棠", + shatang_info: "出牌阶段对一名角色使用,对目标造成1点火焰伤害,然后目标获得1点护甲。", - food:'食物', - chunbing:'春饼', - chunbing_info:'你的手牌上限+1,持续五回合。', - gudonggeng:'骨董羹', - gudonggeng_info:'当你下一次受到杀造成的伤害时,令伤害-1,持续三回合。', - yougeng:'酉羹', - yougeng_info:'准备阶段,若你的体力值为全场最少或之一,你回复1点体力,持续两回合。', - liyutang:'鲤鱼汤', - liyutang_info:'结束阶段,若你的体力值为全场最少或之一,你获得1点护甲,持续两回合。', - mizhilianou:'蜜汁藕', - mizhilianou_info:'你可以将一张红桃牌当作桃使用,持续四回合。', - xiajiao:'虾饺', - xiajiao_info:'你在摸牌阶段额外摸一张牌,然后弃置一张牌,持续三回合。', - tanhuadong:'昙花冻', - tanhuadong_info:'出牌阶段结束时,你摸一张牌,持续三回合。', - qingtuan:'青团', - qingtuan_info:'你在回合内使用首张杀时摸一张牌,持续两回合。', - luyugeng:'鲈鱼羹', - luyugeng_info:'出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续三回合。', - yuanbaorou:'元宝肉', - yuanbaorou_info:'你在出牌阶段可以额外使用一张杀,持续四回合。', - molicha:'茉莉茶', - molicha_info:'你不能成为其他角色的黑色牌的目标,持续四回合。', - mapodoufu:'麻婆豆腐', - mapodoufu_info:'结束阶段,你弃置一名随机敌人的一张随机牌,持续两回合。', + food: "食物", + chunbing: "春饼", + chunbing_info: "你的手牌上限+1,持续五回合。", + gudonggeng: "骨董羹", + gudonggeng_info: "当你下一次受到杀造成的伤害时,令伤害-1,持续三回合。", + yougeng: "酉羹", + yougeng_info: "准备阶段,若你的体力值为全场最少或之一,你回复1点体力,持续两回合。", + liyutang: "鲤鱼汤", + liyutang_info: "结束阶段,若你的体力值为全场最少或之一,你获得1点护甲,持续两回合。", + mizhilianou: "蜜汁藕", + mizhilianou_info: "你可以将一张红桃牌当作桃使用,持续四回合。", + xiajiao: "虾饺", + xiajiao_info: "你在摸牌阶段额外摸一张牌,然后弃置一张牌,持续三回合。", + tanhuadong: "昙花冻", + tanhuadong_info: "出牌阶段结束时,你摸一张牌,持续三回合。", + qingtuan: "青团", + qingtuan_info: "你在回合内使用首张杀时摸一张牌,持续两回合。", + luyugeng: "鲈鱼羹", + luyugeng_info: "出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续三回合。", + yuanbaorou: "元宝肉", + yuanbaorou_info: "你在出牌阶段可以额外使用一张杀,持续四回合。", + molicha: "茉莉茶", + molicha_info: "你不能成为其他角色的黑色牌的目标,持续四回合。", + mapodoufu: "麻婆豆腐", + mapodoufu_info: "结束阶段,你弃置一名随机敌人的一张随机牌,持续两回合。", }, - list:[ - ['spade',2,'tanhuadong'], - ['club',1,'molicha'], - ['club',3,'chunbing'], - ['heart',12,'yougeng'], - ['heart',8,'gudonggeng'], - ['heart',1,'liyutang'], - ['diamond',4,'mizhilianou'], - ['diamond',6,'xiajiao'], - ['spade',3,'qingtuan'], - ['club',11,'luyugeng'], - ['heart',4,'mapodoufu'], - ['spade',8,'yuanbaorou'], + list: [ + ["spade", 2, "tanhuadong"], + ["club", 1, "molicha"], + ["club", 3, "chunbing"], + ["heart", 12, "yougeng"], + ["heart", 8, "gudonggeng"], + ["heart", 1, "liyutang"], + ["diamond", 4, "mizhilianou"], + ["diamond", 6, "xiajiao"], + ["spade", 3, "qingtuan"], + ["club", 11, "luyugeng"], + ["heart", 4, "mapodoufu"], + ["spade", 8, "yuanbaorou"], - ['spade',7,'gjyuheng'], - ['club',4,'mutoumianju'], - ['spade',2,'heilonglinpian'], - ['spade',1,'mianlijinzhen'], - ['heart',13,'yunvyuanshen'], + ["spade", 7, "gjyuheng"], + ["club", 4, "mutoumianju"], + ["spade", 2, "heilonglinpian"], + ["spade", 1, "mianlijinzhen"], + ["heart", 13, "yunvyuanshen"], - ['club',8,'feibiao','poison'], - ['diamond',9,'feibiao','poison'], + ["club", 8, "feibiao", "poison"], + ["diamond", 9, "feibiao", "poison"], - ['spade',3,'bingpotong','poison'], - ['club',12,'bingpotong','poison'], + ["spade", 3, "bingpotong", "poison"], + ["club", 12, "bingpotong", "poison"], - ['club',5,'shihuifen'], - ['club',1,'shihuifen'], - ['spade',13,'shihuifen'], + ["club", 5, "shihuifen"], + ["club", 1, "shihuifen"], + ["spade", 13, "shihuifen"], - ['diamond',6,'shujinsan'], - ['spade',2,'shujinsan'], + ["diamond", 6, "shujinsan"], + ["spade", 2, "shujinsan"], - ['diamond',6,'ziyangdan'], - ['heart',1,'ziyangdan'], + ["diamond", 6, "ziyangdan"], + ["heart", 1, "ziyangdan"], // ['diamond',7,'dinvxuanshuang'], - ['heart',9,'dinvxuanshuang'], + ["heart", 9, "dinvxuanshuang"], - ['spade',9,'qiankunbiao'], - ['club',13,'qiankunbiao'], + ["spade", 9, "qiankunbiao"], + ["club", 13, "qiankunbiao"], - ['diamond',9,'shenhuofeiya'], - ['spade',7,'longxugou'], + ["diamond", 9, "shenhuofeiya"], + ["spade", 7, "longxugou"], - ['heart',9,'jinlianzhu'], - ['spade',7,'jinlianzhu'], + ["heart", 9, "jinlianzhu"], + ["spade", 7, "jinlianzhu"], - ['heart',6,'liutouge'], - ['club',6,'liutouge'], + ["heart", 6, "liutouge"], + ["club", 6, "liutouge"], - ['club',6,'liufengsan'], - ['club',3,'liufengsan'], + ["club", 6, "liufengsan"], + ["club", 3, "liufengsan"], - ['heart',13,'shatang','fire'] - ] + ["heart", 13, "shatang", "fire"], + ], }; }); diff --git a/card/guozhan.js b/card/guozhan.js index 7af2dbe16..f23f18c56 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -1,665 +1,822 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'guozhan', - connect:true, - card:{ - zhaoshu:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['zhaoshu_skill'], - content:function(){ - cards=cards.filterInD(); - if(cards.length&&target.isAlive()){ - target.addToExpansion(cards,'gain2').gaintag.add('zhaoshu_skill'); - target.addSkill('zhaoshu_skill'); - game.addGlobalSkill('zhaoshu_global'); + name: "guozhan", + connect: true, + card: { + zhaoshu: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["zhaoshu_skill"], + content: function () { + cards = cards.filterInD(); + if (cards.length && target.isAlive()) { + target.addToExpansion(cards, "gain2").gaintag.add("zhaoshu_skill"); + target.addSkill("zhaoshu_skill"); + game.addGlobalSkill("zhaoshu_global"); } }, - onEquip:function(){ - if(player.isAlive()){ - player.addToExpansion(card,'giveAuto').gaintag.add('zhaoshu_skill'); - player.markAuto('zhaoshu_skill',[card]); - player.addSkill('zhaoshu_skill'); - game.addGlobalSkill('zhaoshu_global'); + onEquip: function () { + if (player.isAlive()) { + player.addToExpansion(card, "giveAuto").gaintag.add("zhaoshu_skill"); + player.markAuto("zhaoshu_skill", [card]); + player.addSkill("zhaoshu_skill"); + game.addGlobalSkill("zhaoshu_global"); } }, - ai:{ - order:12, - value:3, - useful:1, - result:{ - keepAI:true, - target:1, + ai: { + order: 12, + value: 3, + useful: 1, + result: { + keepAI: true, + target: 1, }, - } - }, - gz_haolingtianxia:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'trick', - enable:true, - filterTarget(card,player,target){ - return target!=player&&!target.isMinHp(); }, - async content(event,trigger,player){ - const target=event.target; - if(!target.isIn()) return; - const str=get.translation(target); - const card=new lib.element.VCard({name:'sha'}); - const targets=game.filterPlayer(current=>{ - return current!=target; - }).sortBySeat(); - for(const current of targets){ - if(!target.isIn()) return; - if(!current||!current.isIn()||current.hasSkill('diaohulishan')) continue; - let choiceList=[ - '弃置一张牌,视为对'+str+'使用一张【杀】', - '弃置'+str+'一张牌', - ],choices=['出杀','弃牌','cancel2']; - if(current.identity=='wei'){ - choiceList[0]=choiceList[0].slice(6); - choiceList[1]='获得'+choiceList[1].slice(2); - choices[1]='得牌'; + }, + gz_haolingtianxia: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "trick", + enable: true, + filterTarget(card, player, target) { + return target != player && !target.isMinHp(); + }, + async content(event, trigger, player) { + const target = event.target; + if (!target.isIn()) return; + const str = get.translation(target); + const card = new lib.element.VCard({ name: "sha" }); + const targets = game + .filterPlayer((current) => { + return current != target; + }) + .sortBySeat(); + for (const current of targets) { + if (!target.isIn()) return; + if (!current || !current.isIn() || current.hasSkill("diaohulishan")) continue; + let choiceList = [ + "弃置一张牌,视为对" + str + "使用一张【杀】", + "弃置" + str + "一张牌", + ], + choices = ["出杀", "弃牌", "cancel2"]; + if (current.identity == "wei") { + choiceList[0] = choiceList[0].slice(6); + choiceList[1] = "获得" + choiceList[1].slice(2); + choices[1] = "得牌"; } - if(!current.canUse(card,target,false)||(current.identity!='wei'&&!current.countDiscardableCards(current,'he'))){ - choiceList[0]=''+choiceList[0]+''; - choices.remove('出杀'); + if ( + !current.canUse(card, target, false) || + (current.identity != "wei" && !current.countDiscardableCards(current, "he")) + ) { + choiceList[0] = '' + choiceList[0] + ""; + choices.remove("出杀"); } - if(!target.countCards('he')){ - choiceList[1]=''+choiceList[1]+''; - choices.remove(current.identity=='wei'?'得牌':'弃牌'); + if (!target.countCards("he")) { + choiceList[1] = '' + choiceList[1] + ""; + choices.remove(current.identity == "wei" ? "得牌" : "弃牌"); } - if(choices.length>1){ - const {result:{control}}=await current.chooseControl(choices) - .set('prompt','号令天下:请选择其中一项').set('target',target) - .set('ai',()=>{ - const player=get.event('player'),target=get.event('target'),choices=get.event('controls'); - const guohe=new lib.element.VCard({name:'guohe_copy2'}),shunshou=new lib.element.VCard({name:'shunshou_copy2'}),sha=new lib.element.VCard({name:'sha'}); - const num=Math.max(0,choices.includes('弃牌')?get.effect(target,guohe,player):0,choices.includes('得牌')?get.effect(target,shunshou,player):0); - if(choices.includes('出杀')&&get.effect(player,guohe,player)+get.effect(target,sha,player)>num) return '出杀'; - if(choices.includes('得牌')&&num>0) return '得牌'; - if(choices.includes('弃牌')&&num>0) return '弃牌'; - return 'cancel2'; - }); - if(control!='cancel2'){ - if(control=='出杀'){ - if(current.identity!='wei') await current.chooseToDiscard('he',true); - await current.useCard(card,target,false); - } - else await current[current.identity=='wei'?'gainPlayerCard':'discardPlayerCard'](target,true,'he').set('boolline',true); + if (choices.length > 1) { + const { + result: { control }, + } = await current + .chooseControl(choices) + .set("prompt", "号令天下:请选择其中一项") + .set("target", target) + .set("ai", () => { + const player = get.event("player"), + target = get.event("target"), + choices = get.event("controls"); + const guohe = new lib.element.VCard({ name: "guohe_copy2" }), + shunshou = new lib.element.VCard({ name: "shunshou_copy2" }), + sha = new lib.element.VCard({ name: "sha" }); + const num = Math.max( + 0, + choices.includes("弃牌") ? get.effect(target, guohe, player) : 0, + choices.includes("得牌") ? get.effect(target, shunshou, player) : 0 + ); + if ( + choices.includes("出杀") && + get.effect(player, guohe, player) + get.effect(target, sha, player) > + num + ) + return "出杀"; + if (choices.includes("得牌") && num > 0) return "得牌"; + if (choices.includes("弃牌") && num > 0) return "弃牌"; + return "cancel2"; + }); + if (control != "cancel2") { + if (control == "出杀") { + if (current.identity != "wei") await current.chooseToDiscard("he", true); + await current.useCard(card, target, false); + } else + await current[ + current.identity == "wei" ? "gainPlayerCard" : "discardPlayerCard" + ](target, true, "he").set("boolline", true); } } } }, - ai:{ - order:6, - value:9, - useful:6, - tag:{ - damage:1, - discard:1, - loseCard:1, + ai: { + order: 6, + value: 9, + useful: 6, + tag: { + damage: 1, + discard: 1, + loseCard: 1, }, - result:{ - target(player,target){ - return -1.5*(game.countPlayer()-1); + result: { + target(player, target) { + return -1.5 * (game.countPlayer() - 1); }, }, }, }, - gz_kefuzhongyuan:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - selectTarget:[1,Infinity], - content:function(){ - 'step 0' - var p1='请选择【杀】的目标',p2='或点击「取消」摸一张牌'; - if(target.identity=='shu'){ - p1+='(伤害+1)'; - p2='或点击「取消」摸两张牌'; + gz_kefuzhongyuan: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + selectTarget: [1, Infinity], + content: function () { + "step 0"; + var p1 = "请选择【杀】的目标", + p2 = "或点击「取消」摸一张牌"; + if (target.identity == "shu") { + p1 += "(伤害+1)"; + p2 = "或点击「取消」摸两张牌"; } - var next=target.chooseUseTarget('sha',p1,p2,false); - if(target.identity=='shu') next.set('oncard',function(){ - _status.event.baseDamage++; - }); - 'step 1' - if(!result.bool){ - target.draw(target.identity=='shu'?2:1); + var next = target.chooseUseTarget("sha", p1, p2, false); + if (target.identity == "shu") + next.set("oncard", function () { + _status.event.baseDamage++; + }); + "step 1"; + if (!result.bool) { + target.draw(target.identity == "shu" ? 2 : 1); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.mode()=='guozhan'){ - if(!_status._aozhan){ - if(!player.isMajor()){ - if(!viewer.isMajor()) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.mode() == "guozhan") { + if (!_status._aozhan) { + if (!player.isMajor()) { + if (!viewer.isMajor()) return 0; } } } }, - order:4, - value:9, - useful:6, - tag:{ - gain:1, + order: 4, + value: 9, + useful: 6, + tag: { + gain: 1, }, - result:{target:1.5}, + result: { target: 1.5 }, }, }, - gz_guguoanbang:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - toself:true, - filterTarget:function(card,player,target){ - return target==player; + gz_guguoanbang: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + toself: true, + filterTarget: function (card, player, target) { + return target == player; }, - modTarget:true, - content:function(){ - 'step 0' + modTarget: true, + content: function () { + "step 0"; target.draw(8); - 'step 1' - target.chooseToDiscard('请弃置至少六张手牌',[6,target.countCards('h')],true,'h'); - if(target.identity!='wu') event.finish(); - 'step 2' - if(!result.cards||!result.cards.length) event.finish(); - event.give_cards=result.cards; - event.given_list=[]; - 'step 3' - event.give_cards=event.give_cards.filterInD('d'); - if(!event.give_cards.length||!game.hasPlayer(function(current){ - return current!=target&¤t.identity=='wu'&&!event.given_list.includes(current); - })) event.finish(); - else{ - target.chooseButton(['是否将弃置的牌交给其他吴势力角色?',event.give_cards],[1,2]); + "step 1"; + target.chooseToDiscard("请弃置至少六张手牌", [6, target.countCards("h")], true, "h"); + if (target.identity != "wu") event.finish(); + "step 2"; + if (!result.cards || !result.cards.length) event.finish(); + event.give_cards = result.cards; + event.given_list = []; + "step 3"; + event.give_cards = event.give_cards.filterInD("d"); + if ( + !event.give_cards.length || + !game.hasPlayer(function (current) { + return ( + current != target && + current.identity == "wu" && + !event.given_list.includes(current) + ); + }) + ) + event.finish(); + else { + target.chooseButton(["是否将弃置的牌交给其他吴势力角色?", event.give_cards], [1, 2]); } - 'step 4' - if(result.bool){ - event.cards2=result.links; - target.chooseTarget(true,'选择获得'+get.translation(event.cards2)+'的角色',function(card,player,target){ - return target!=player&&target.identity=='wu'&&!_status.event.targets.includes(target); - }).set('targets',event.given_list); - } - else event.finish(); - 'step 5' - if(result.bool&&result.targets&&result.targets.length){ - var current=result.targets[0]; - target.line(current,'green'); - current.gain(event.cards2,'gain2').giver=player; + "step 4"; + if (result.bool) { + event.cards2 = result.links; + target + .chooseTarget( + true, + "选择获得" + get.translation(event.cards2) + "的角色", + function (card, player, target) { + return ( + target != player && + target.identity == "wu" && + !_status.event.targets.includes(target) + ); + } + ) + .set("targets", event.given_list); + } else event.finish(); + "step 5"; + if (result.bool && result.targets && result.targets.length) { + var current = result.targets[0]; + target.line(current, "green"); + current.gain(event.cards2, "gain2").giver = player; event.given_list.push(current); event.goto(3); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.mode()=='guozhan'){ - if(!_status._aozhan){ - if(!player.isMajor()){ - if(!viewer.isMajor()) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.mode() == "guozhan") { + if (!_status._aozhan) { + if (!player.isMajor()) { + if (!viewer.isMajor()) return 0; } } } }, - order:6, - value:9, - useful:6, - tag:{ - draw:8, - loseCard:6, - discard:6, + order: 6, + value: 9, + useful: 6, + tag: { + draw: 8, + loseCard: 6, + discard: 6, }, - result:{ - target:function(player,target){ - if(target.identity!='wu') return 3; - return Math.max(3,Math.min(8,2*game.countPlayer(function(current){ - return current.identity=='wu'; - }))); + result: { + target: function (player, target) { + if (target.identity != "wu") return 3; + return Math.max( + 3, + Math.min( + 8, + 2 * + game.countPlayer(function (current) { + return current.identity == "wu"; + }) + ) + ); }, }, }, }, - gz_wenheluanwu:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - selectTarget:-1, - ignoreTarget:function(card,player,target){ - return target.countCards('h')==0; + gz_wenheluanwu: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + selectTarget: -1, + ignoreTarget: function (card, player, target) { + return target.countCards("h") == 0; }, - content:function(){ - 'step 0' - if(!target.countCards('h')||!player.isIn()) event.finish(); + content: function () { + "step 0"; + if (!target.countCards("h") || !player.isIn()) event.finish(); else target.showHandcards(); - 'step 1' - var str=get.translation(target); - player.chooseControl().set('prompt','文和乱武:请选择一项').set('choiceList',[ - '令'+str+'弃置两张类型不同的手牌', - '弃置'+str+'的一张手牌', - ]).set('ai',()=>{ - let target=_status.event.getParent().target,hs=target.getCards('h'),type=[],att=get.attitude(_status.event.player,target); - if(hs.length<2) return att>0?1:0; - hs.forEach(i=>{ - type.add(get.type2(i,target)); + "step 1"; + var str = get.translation(target); + player + .chooseControl() + .set("prompt", "文和乱武:请选择一项") + .set("choiceList", [ + "令" + str + "弃置两张类型不同的手牌", + "弃置" + str + "的一张手牌", + ]) + .set("ai", () => { + let target = _status.event.getParent().target, + hs = target.getCards("h"), + type = [], + att = get.attitude(_status.event.player, target); + if (hs.length < 2) return att > 0 ? 1 : 0; + hs.forEach((i) => { + type.add(get.type2(i, target)); + }); + if (target.identity !== "qun") { + if (Boolean(att > 0) === Boolean(type.length > 1)) return 1; + return 0; + } + if (type.length < 2 || target.hp < 3) return att > 0 ? 1 : 0; + if (hs.length === 2) return att > 0 ? 0 : 1; + return att > 0 ? 1 : 0; }); - if(target.identity!=='qun'){ - if(Boolean(att>0)===Boolean(type.length>1)) return 1; - return 0; + "step 2"; + if (result.index == 0) { + var list = [], + hs = target.getCards("h"); + for (var i of hs) { + if (lib.filter.cardDiscardable(i, target, "gz_wenheluanwu")) + list.add(get.type2(i, target)); + if (list.length > 1) break; } - if(type.length<2||target.hp<3) return att>0?1:0; - if(hs.length===2) return att>0?0:1; - return att>0?1:0; - }); - 'step 2' - if(result.index==0){ - var list=[],hs=target.getCards('h'); - for(var i of hs){ - if(lib.filter.cardDiscardable(i,target,'gz_wenheluanwu')) list.add(get.type2(i,target)); - if(list.length>1) break; - } - if(list.length>1) target.chooseToDiscard('h',true,'请弃置两张类型不同的手牌',2,function(card,player){ - if(!ui.selected.cards.length) return true; - return get.type2(card,target)!=get.type2(ui.selected.cards[0],target); - }).set('complexCard',true); - else if(list.length==1) target.chooseToDiscard('h',true); + if (list.length > 1) + target + .chooseToDiscard( + "h", + true, + "请弃置两张类型不同的手牌", + 2, + function (card, player) { + if (!ui.selected.cards.length) return true; + return ( + get.type2(card, target) != get.type2(ui.selected.cards[0], target) + ); + } + ) + .set("complexCard", true); + else if (list.length == 1) target.chooseToDiscard("h", true); else event.finish(); + } else { + player.discardPlayerCard(target, "h", true, "visible"); } - else{ - player.discardPlayerCard(target,'h',true,'visible'); - } - 'step 3' - if(target.identity!='qun'||!result.bool||!result.cards||!result.cards.length||target.countCards('h')>0||target.hp<1) event.finish(); - else target.draw(Math.min(5,target.hp)); + "step 3"; + if ( + target.identity != "qun" || + !result.bool || + !result.cards || + !result.cards.length || + target.countCards("h") > 0 || + target.hp < 1 + ) + event.finish(); + else target.draw(Math.min(5, target.hp)); }, - ai:{ - order:6, - value:10, - useful:6, - tag:{ - discard:1.5, - loseCard:1.5, + ai: { + order: 6, + value: 10, + useful: 6, + tag: { + discard: 1.5, + loseCard: 1.5, }, - result:{target:-1.5}, + result: { target: -1.5 }, }, }, - liulongcanjia:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip6', - subtypes:['equip3','equip4'], - nomod:true, - nopower:true, + liulongcanjia: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip6", + subtypes: ["equip3", "equip4"], + nomod: true, + nopower: true, //unique:true, - distance:{ - globalFrom:-1, - globalTo:+1, + distance: { + globalFrom: -1, + globalTo: +1, }, - skills:['liulongcanjia'], - ai:{ - equipValue:function(card,player){ - if(player.countCards('e',{subtype:['equip3','equip4']})>1) return 1; - if(player.hasSkill('gzzongyu')) return 9; - if(game.hasPlayer(function(current){ - return current.hasSkill('gzzongyu')&&get.attitude(player,current)<=0; - })) return 1; + skills: ["liulongcanjia"], + ai: { + equipValue: function (card, player) { + if (player.countCards("e", { subtype: ["equip3", "equip4"] }) > 1) return 1; + if (player.hasSkill("gzzongyu")) return 9; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("gzzongyu") && get.attitude(player, current) <= 0; + }) + ) + return 1; return 7.2; }, - basic:{ - equipValue:7.2 - } + basic: { + equipValue: 7.2, + }, }, }, - minguangkai:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['minguangkai_cancel','minguangkai_link'], - ai:{ - basic:{ - equipValue:6 - } - } + minguangkai: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["minguangkai_cancel", "minguangkai_link"], + ai: { + basic: { + equipValue: 6, + }, + }, }, - dinglanyemingzhu:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip5', - nomod:true, - nopower:true, - unique:true, - global:'g_dinglanyemingzhu_ai', - skills:['dinglanyemingzhu_skill'], - ai:{ - equipValue:function(card,player){ - if(player.hasSkill('jubao')) return 8; - if(player.hasSkill('gzzhiheng')) return 6; - if(game.hasPlayer(function(current){ - return current.hasSkill('jubao')&&get.attitude(player,current)<=0; - })){ + dinglanyemingzhu: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip5", + nomod: true, + nopower: true, + unique: true, + global: "g_dinglanyemingzhu_ai", + skills: ["dinglanyemingzhu_skill"], + ai: { + equipValue: function (card, player) { + if (player.hasSkill("jubao")) return 8; + if (player.hasSkill("gzzhiheng")) return 6; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("jubao") && get.attitude(player, current) <= 0; + }) + ) { return 0; } return 7; }, - basic:{ - equipValue:6.5 - } - } + basic: { + equipValue: 6.5, + }, + }, }, - feilongduofeng:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip1', - nomod:true, - nopower:true, - unique:true, - global:'g_feilongduofeng_ai', - distance:{attackFrom:-1}, - skills:['feilongduofeng','feilongduofeng3'], - ai:{ - equipValue:function(card,player){ - if(player.hasSkill('zhangwu')) return 9; - if(game.hasPlayer(function(current){ - return current.hasSkill('zhangwu')&&get.attitude(player,current)<=0; - })){ + feilongduofeng: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip1", + nomod: true, + nopower: true, + unique: true, + global: "g_feilongduofeng_ai", + distance: { attackFrom: -1 }, + skills: ["feilongduofeng", "feilongduofeng3"], + ai: { + equipValue: function (card, player) { + if (player.hasSkill("zhangwu")) return 9; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("zhangwu") && get.attitude(player, current) <= 0; + }) + ) { return 1; } return 8; }, - basic:{ - equipValue:7 - } - } + basic: { + equipValue: 7, + }, + }, }, - taipingyaoshu:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip2', - nomod:true, - nopower:true, - unique:true, - global:['g_taipingyaoshu_ai'], - skills:['taipingyaoshu'], - ai:{ - equipValue:function(card,player){ - if(player.hasSkill('wendao')) return 9; - if(game.hasPlayer(function(current){ - return current.hasSkill('wendao')&&get.attitude(player,current)<=0; - })){ + taipingyaoshu: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip2", + nomod: true, + nopower: true, + unique: true, + global: ["g_taipingyaoshu_ai"], + skills: ["taipingyaoshu"], + ai: { + equipValue: function (card, player) { + if (player.hasSkill("wendao")) return 9; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("wendao") && get.attitude(player, current) <= 0; + }) + ) { return 1; } return 6; }, - basic:{ - equipValue:6 - } + basic: { + equipValue: 6, + }, }, - filterLose:function(card,player){ - if(player.hasSkillTag('unequip2')) return false; + filterLose: function (card, player) { + if (player.hasSkillTag("unequip2")) return false; return true; }, - loseDelay:false, - onLose:function(){ - var next=game.createEvent('taipingyaoshu'); + loseDelay: false, + onLose: function () { + var next = game.createEvent("taipingyaoshu"); event.next.remove(next); - var evt=event.getParent(); - if(evt.getlx===false) evt=evt.getParent(); + var evt = event.getParent(); + if (evt.getlx === false) evt = evt.getParent(); evt.after.push(next); - next.player=player; + next.player = player; next.setContent(lib.card.taipingyaoshu.onLosex); }, - onLosex:function(){ - 'step 0' - player.logSkill('taipingyaoshu'); + onLosex: function () { + "step 0"; + player.logSkill("taipingyaoshu"); player.draw(2); - 'step 1' - if(player.hp>1) player.loseHp(); - } - }, - yuxi:{ - audio:true, - mode:['guozhan'], - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['yuxi_skill'], - ai:{ - equipValue:9 - } - }, - xietianzi:{ - audio:true, - fullskin:true, - type:'trick', - enable:function(card,player,event){ - if(get.mode()=='guozhan'&&!player.isMajor()) return false; - if(player.hasSkill('xietianzi')) return false; - if(_status.currentPhase!=player) return false; - var evt=event||_status.event; - if(evt.name!='chooseToUse') evt=evt.getParent('chooseToUse'); - return evt.type=='phase'; + "step 1"; + if (player.hp > 1) player.loseHp(); }, - filterTarget:function(card,player,target){ - return player==target; + }, + yuxi: { + audio: true, + mode: ["guozhan"], + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["yuxi_skill"], + ai: { + equipValue: 9, }, - selectTarget:-1, - content:function(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + }, + xietianzi: { + audio: true, + fullskin: true, + type: "trick", + enable: function (card, player, event) { + if (get.mode() == "guozhan" && !player.isMajor()) return false; + if (player.hasSkill("xietianzi")) return false; + if (_status.currentPhase != player) return false; + var evt = event || _status.event; + if (evt.name != "chooseToUse") evt = evt.getParent("chooseToUse"); + return evt.type == "phase"; + }, + filterTarget: function (card, player, target) { + return player == target; + }, + selectTarget: -1, + content: function () { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } - target.addTempSkill('xietianzi'); + target.addTempSkill("xietianzi"); }, - ai:{ - order:0.5, - value:4, - useful:2, - result:{ - target:function(player,target){ - if(target.countCards('h')>=2) return 1; + ai: { + order: 0.5, + value: 4, + useful: 2, + result: { + target: function (player, target) { + if (target.countCards("h") >= 2) return 1; return 0; - } - } - } - }, - shuiyanqijunx:{ - audio:'shuiyanqijun', - fullskin:true, - type:'trick', - filterTarget:function(card,player,target){ - return target!=player&&(get.mode()!='guozhan'||_status.mode=='yingbian'||_status.mode=='free'||target.countCards('e')>0); + }, + }, }, - enable:true, - defaultYingbianEffect:'add', - content:function(){ - 'step 0' - if(event.card.yingbian_all){ - target.discard(target.getCards('e',function(card){ - return lib.filter.cardDiscardable(card,target,'shuiyanqijunx'); - })); - target.damage('thunder'); + }, + shuiyanqijunx: { + audio: "shuiyanqijun", + fullskin: true, + type: "trick", + filterTarget: function (card, player, target) { + return ( + target != player && + (get.mode() != "guozhan" || + _status.mode == "yingbian" || + _status.mode == "free" || + target.countCards("e") > 0) + ); + }, + enable: true, + defaultYingbianEffect: "add", + content: function () { + "step 0"; + if (event.card.yingbian_all) { + target.discard( + target.getCards("e", function (card) { + return lib.filter.cardDiscardable(card, target, "shuiyanqijunx"); + }) + ); + target.damage("thunder"); event.finish(); - } - else if(!target.countCards('e',function(card){ - return lib.filter.cardDiscardable(card,target,'shuiyanqijunx'); - })){ - var next=target.damage(); - if(!get.is.single()) game.setNature(next,'thunder',true); + } else if ( + !target.countCards("e", function (card) { + return lib.filter.cardDiscardable(card, target, "shuiyanqijunx"); + }) + ) { + var next = target.damage(); + if (!get.is.single()) game.setNature(next, "thunder", true); event.finish(); return; - } - else target.chooseControl('discard_card','take_damage',function(event,player){ - let eff=get.damageEffect(player,event.player,player,'thunder'); - if(eff>0) return 'take_damage'; - if(player.hasSkillTag('noe')) return 'discard_card'; - if(!eff) return 'take_damage'; - if(player.isDamaged()&&player.hasCard((card)=>get.name(card)=='baiyin'&&get.recoverEffect(player,player,_status.event.player)>0,'e')) return 'discard_card'; - if(player.hasCard((card)=>get.value(card,player)<=0,'e')&&!player.hasCard((card)=>get.value(card,player)>Math.max(7,12-player.hp),'e')) return 'discard_card'; - if(player.hp>2&&player.countCards('e')>2||player.hp>1&&player.countCards('e')>3) return 'take_damage'; - return 'discard_card'; - }).set('prompt','水淹七军').set('prompt2','请选择一项:⒈弃置装备区里的所有牌;⒉受到'+get.translation(player)+'造成的1点雷电伤害。'); - 'step 1' - if(result.control=='discard_card'){ - target.discard(target.getCards('e',function(card){ - return lib.filter.cardDiscardable(card,target,'shuiyanqijunx'); - })); - } - else{ - var next=target.damage(); - if(!get.is.single()) game.setNature(next,'thunder',true); + } else + target + .chooseControl("discard_card", "take_damage", function (event, player) { + let eff = get.damageEffect(player, event.player, player, "thunder"); + if (eff > 0) return "take_damage"; + if (player.hasSkillTag("noe")) return "discard_card"; + if (!eff) return "take_damage"; + if ( + player.isDamaged() && + player.hasCard( + (card) => + get.name(card) == "baiyin" && + get.recoverEffect(player, player, _status.event.player) > 0, + "e" + ) + ) + return "discard_card"; + if ( + player.hasCard((card) => get.value(card, player) <= 0, "e") && + !player.hasCard( + (card) => get.value(card, player) > Math.max(7, 12 - player.hp), + "e" + ) + ) + return "discard_card"; + if ( + (player.hp > 2 && player.countCards("e") > 2) || + (player.hp > 1 && player.countCards("e") > 3) + ) + return "take_damage"; + return "discard_card"; + }) + .set("prompt", "水淹七军") + .set( + "prompt2", + "请选择一项:⒈弃置装备区里的所有牌;⒉受到" + + get.translation(player) + + "造成的1点雷电伤害。" + ); + "step 1"; + if (result.control == "discard_card") { + target.discard( + target.getCards("e", function (card) { + return lib.filter.cardDiscardable(card, target, "shuiyanqijunx"); + }) + ); + } else { + var next = target.damage(); + if (!get.is.single()) game.setNature(next, "thunder", true); } event.finish(); }, - ai:{ - canLink:function(player,target,card){ - if(!target.isLinked()||player.hasSkill('jueqing')||target.hasSkill('gangzhi')||player.hasSkill('gangzhi')) return false; - let es=target.getCards('e'),val=0; - if(!es.length) return true; - for(let i of es){ - if(i.name=='baiyin'&&target.isDamaged()&&get.recoverEffect(target)) val+=get.value({name:'tao'},target); - else val-=get.value(i,target); + ai: { + canLink: function (player, target, card) { + if ( + !target.isLinked() || + player.hasSkill("jueqing") || + target.hasSkill("gangzhi") || + player.hasSkill("gangzhi") + ) + return false; + let es = target.getCards("e"), + val = 0; + if (!es.length) return true; + for (let i of es) { + if (i.name == "baiyin" && target.isDamaged() && get.recoverEffect(target)) + val += get.value({ name: "tao" }, target); + else val -= get.value(i, target); } - if(0.15*val>2*get.sgn(get.damageEffect(target,player,target,'thunder'))) return false; + if (0.15 * val > 2 * get.sgn(get.damageEffect(target, player, target, "thunder"))) + return false; return true; }, - order:6, - value:4, - useful:2, - tag:{ - damage:1, - thunderDamage:1, - natureDamage:1, - loseCard:1, + order: 6, + value: 4, + useful: 2, + tag: { + damage: 1, + thunderDamage: 1, + natureDamage: 1, + loseCard: 1, }, - yingbian:function(card,player,targets,viewer){ - if(get.attitude(viewer,player)<=0) return 0; - var base=0; - if(get.cardtag(card,'yingbian_all')){ - if(targets.filter(function(current){ - return get.damageEffect(current,player,player,'thunder')>0&¤t.countCards('e',function(card){ - return get.value(card,current)<=0; - })<2&¤t.countCards('e',function(card){ - return get.value(card,current)>0; - })>0; - }).length) base+=6; + yingbian: function (card, player, targets, viewer) { + if (get.attitude(viewer, player) <= 0) return 0; + var base = 0; + if (get.cardtag(card, "yingbian_all")) { + if ( + targets.filter(function (current) { + return ( + get.damageEffect(current, player, player, "thunder") > 0 && + current.countCards("e", function (card) { + return get.value(card, current) <= 0; + }) < 2 && + current.countCards("e", function (card) { + return get.value(card, current) > 0; + }) > 0 + ); + }).length + ) + base += 6; } - if(get.cardtag(card,'yingbian_add')){ - if(game.hasPlayer(function(current){ - return !targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })) base+=6; + if (get.cardtag(card, "yingbian_add")) { + if ( + game.hasPlayer(function (current) { + return ( + !targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + base += 6; } return 0; }, - result:{ - target:function(player,target,card,isLink){ - let es=target.getCards('e'), eff=2*get.sgn(get.damageEffect(target,player,target,'thunder')); - if(isLink || !es.length) return eff; - let val=0; - for(let i of es){ - if(i.name=='baiyin'&&target.isDamaged()&&get.recoverEffect(target)) val+=6; - else val-=get.value(i,target); + result: { + target: function (player, target, card, isLink) { + let es = target.getCards("e"), + eff = 2 * get.sgn(get.damageEffect(target, player, target, "thunder")); + if (isLink || !es.length) return eff; + let val = 0; + for (let i of es) { + if (i.name == "baiyin" && target.isDamaged() && get.recoverEffect(target)) + val += 6; + else val -= get.value(i, target); } - return Math.max(eff,0.15*val); - } - } - } + return Math.max(eff, 0.15 * val); + }, + }, + }, }, - lulitongxin:{ - fullskin:true, - audio:true, - type:'trick', - enable:function(card,player){ - if(get.mode()=='versus') return true; - return game.hasPlayer(function(current){ + lulitongxin: { + fullskin: true, + audio: true, + type: "trick", + enable: function (card, player) { + if (get.mode() == "versus") return true; + return game.hasPlayer(function (current) { return current.isMajor(); }); }, - mode:['guozhan','versus'], - filterTarget:true, - recastable:true, - changeTarget:function(player,targets){ - var target=targets[0]; - game.filterPlayer(function(current){ - if(get.mode()=='versus') return current.isFriendOf(target); - return current.isMajor()==target.isMajor()&¤t!=target&&!current.hasSkill('diaohulishan'); - },targets); + mode: ["guozhan", "versus"], + filterTarget: true, + recastable: true, + changeTarget: function (player, targets) { + var target = targets[0]; + game.filterPlayer(function (current) { + if (get.mode() == "versus") return current.isFriendOf(target); + return ( + current.isMajor() == target.isMajor() && + current != target && + !current.hasSkill("diaohulishan") + ); + }, targets); }, - content:function(){ - if(get.mode()=='versus'){ - if(target.isEnemyOf(player)) target.link(true); - else if(target.isLinked()) target.draw(); - } - else if(target.isLinked()){ + content: function () { + if (get.mode() == "versus") { + if (target.isEnemyOf(player)) target.link(true); + else if (target.isLinked()) target.draw(); + } else if (target.isLinked()) { target.draw(); - } - else{ + } else { target.link(); } }, - ai:{ - order:7.5, - value:4, - useful:2, - result:{ - target:function(player,target){ - if(get.mode()=='versus'){ - if(target.isFriendOf(player)) return target.isLinked()?1:0; - return target.isLinked()?0:-1; + ai: { + order: 7.5, + value: 4, + useful: 2, + result: { + target: function (player, target) { + if (get.mode() == "versus") { + if (target.isFriendOf(player)) return target.isLinked() ? 1 : 0; + return target.isLinked() ? 0 : -1; } - return target.isLinked()?1:-1; - } - } - } + return target.isLinked() ? 1 : -1; + }, + }, + }, }, - lianjunshengyan:{ - fullskin:true, - audio:true, - type:'trick', - enable:function(card,player){ - if(get.mode()=='guozhan') return !player.isUnseen(); + lianjunshengyan: { + fullskin: true, + audio: true, + type: "trick", + enable: function (card, player) { + if (get.mode() == "guozhan") return !player.isUnseen(); return true; }, - mode:['guozhan','boss'], - filterTarget:function(card,player,target){ - if(get.mode()=='guozhan') return target!=player&&target.identity!='unknown'&&!target.isFriendOf(player); + mode: ["guozhan", "boss"], + filterTarget: function (card, player, target) { + if (get.mode() == "guozhan") + return target != player && target.identity != "unknown" && !target.isFriendOf(player); return true; }, - selectTarget:function(){ - return get.mode()=='guozhan'?1:-1; + selectTarget: function () { + return get.mode() == "guozhan" ? 1 : -1; }, - changeTarget:function(player,targets){ - if(get.mode()=='guozhan'){ - var target=targets[0]; + changeTarget: function (player, targets) { + if (get.mode() == "guozhan") { + var target = targets[0]; targets.push(player); - if(target.identity!='ye'){ - game.filterPlayer(function(current){ - return target!=current&&target.isFriendOf(current)&&!current.hasSkill('diaohulishan'); - },targets); + if (target.identity != "ye") { + game.filterPlayer(function (current) { + return ( + target != current && + target.isFriendOf(current) && + !current.hasSkill("diaohulishan") + ); + }, targets); } } - },/* + } /* contentBefore:function(){ if(get.mode()=='guozhan'){ var evt=event.getParent(); @@ -670,438 +827,457 @@ game.import('card',function(lib,game,ui,get,ai,_status){ evt.targets.push(player); } } - },*/ - content:function(){ - 'step 0' - if(get.mode()!='guozhan'){ - if(player==target) target.draw(game.filterPlayer().length); + },*/, + content: function () { + "step 0"; + if (get.mode() != "guozhan") { + if (player == target) target.draw(game.filterPlayer().length); else target.chooseDrawRecover(true); event.finish(); - } - else{ - if(target==player){ - var num=targets.length-1; - event.num=num; - var damaged=target.maxHp-target.hp; - if(damaged==0){ + } else { + if (target == player) { + var num = targets.length - 1; + event.num = num; + var damaged = target.maxHp - target.hp; + if (damaged == 0) { target.draw(num); event.finish(); - } - else{ - var list=[]; - for(var i=Math.min(num,damaged);i>=0;i--){ - list.push('摸'+(num-i)+'回'+i); + } else { + var list = []; + for (var i = Math.min(num, damaged); i >= 0; i--) { + list.push("摸" + (num - i) + "回" + i); } - target.chooseControl(list).set('prompt','请分配自己的摸牌数和回复量').ai=function(){ - return 0; - }; + target.chooseControl(list).set("prompt", "请分配自己的摸牌数和回复量").ai = + function () { + return 0; + }; } - } - else{ + } else { target.draw(); } } - 'step 1' - if(target!=player) target.link(false); - else if(typeof result.control=='string'){ - var index=result.control.indexOf('回'); - var draw=parseInt(result.control.slice(1,index)); - var recover=parseInt(result.control.slice(index+1)); - if(draw) target.draw(draw); - if(recover) target.recover(recover); + "step 1"; + if (target != player) target.link(false); + else if (typeof result.control == "string") { + var index = result.control.indexOf("回"); + var draw = parseInt(result.control.slice(1, index)); + var recover = parseInt(result.control.slice(index + 1)); + if (draw) target.draw(draw); + if (recover) target.recover(recover); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.mode()=='guozhan'){ - if(!_status._aozhan){ - if(!player.isMajor()){ - if(!viewer.isMajor()) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.mode() == "guozhan") { + if (!_status._aozhan) { + if (!player.isMajor()) { + if (!viewer.isMajor()) return 0; } } } }, - order:6, - value:4, - useful:2, - result:{ - target:function(player,target){ - if(player==target) return 2; + order: 6, + value: 4, + useful: 2, + result: { + target: function (player, target) { + if (player == target) return 2; return 1; }, }, }, }, - chiling:{ - fullskin:true, - audio:true, - type:'trick', - enable:function(){ - return game.hasPlayer(function(current){ + chiling: { + fullskin: true, + audio: true, + type: "trick", + enable: function () { + return game.hasPlayer(function (current) { return current.isUnseen(); }); }, - mode:['guozhan'], + mode: ["guozhan"], //global:['g_chiling1','g_chiling2','g_chiling3'], - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return target.isUnseen(); }, - selectTarget:-1, - chooseai:function(event,player){ - if(player.hasSkillTag('mingzhi_yes')) return '选项一'; - if(_status.event.controls.includes('选项三')){ - if(player.hasSkillTag('mingzhi_no')) return '选项三'; - return Math.random()<0.5?'选项一':'选项三'; - } - else{ - if(_status.event.getParent().nomingzhi){ - if(_status.event.controls.includes('选项二')) return '选项二'; - return '选项一'; + selectTarget: -1, + chooseai: function (event, player) { + if (player.hasSkillTag("mingzhi_yes")) return "选项一"; + if (_status.event.controls.includes("选项三")) { + if (player.hasSkillTag("mingzhi_no")) return "选项三"; + return Math.random() < 0.5 ? "选项一" : "选项三"; + } else { + if (_status.event.getParent().nomingzhi) { + if (_status.event.controls.includes("选项二")) return "选项二"; + return "选项一"; } - if(player.hasSkillTag('maixie_hp')||player.hp<=2) return '选项一'; - return Math.random()<0.5?'选项一':'选项二'; + if (player.hasSkillTag("maixie_hp") || player.hp <= 2) return "选项一"; + return Math.random() < 0.5 ? "选项一" : "选项二"; } }, - content:function(){ - 'step 0' - var choiceList=['明置一张武将牌,然后摸一张牌','失去1点体力']; - event.nomingzhi=target.hasSkillTag('nomingzhi',false,null,true); - if(event.nomingzhi){ + content: function () { + "step 0"; + var choiceList = ["明置一张武将牌,然后摸一张牌", "失去1点体力"]; + event.nomingzhi = target.hasSkillTag("nomingzhi", false, null, true); + if (event.nomingzhi) { choiceList.shift(); } - if(target.countCards('he',{type:'equip'})){ - choiceList.push('弃置一张装备牌'); + if (target.countCards("he", { type: "equip" })) { + choiceList.push("弃置一张装备牌"); } - target.chooseControl(lib.card.chiling.chooseai).set('prompt','敕令').set('choiceList',choiceList); - 'step 1' - var index=result.index; - if(event.nomingzhi){ + target + .chooseControl(lib.card.chiling.chooseai) + .set("prompt", "敕令") + .set("choiceList", choiceList); + "step 1"; + var index = result.index; + if (event.nomingzhi) { index++; } - if(index==0){ - target.chooseControl('主将','副将',function(){ - return Math.floor(Math.random()*2); - }).set('prompt','选择要明置的武将牌'); - } - else if(index==1){ + if (index == 0) { + target + .chooseControl("主将", "副将", function () { + return Math.floor(Math.random() * 2); + }) + .set("prompt", "选择要明置的武将牌"); + } else if (index == 1) { target.loseHp(); event.finish(); - } - else{ - target.chooseToDiscard('he',{type:'equip'},true); + } else { + target.chooseToDiscard("he", { type: "equip" }, true); event.finish(); } - 'step 2' - if(result.index==0){ + "step 2"; + if (result.index == 0) { target.showCharacter(0); - } - else{ + } else { target.showCharacter(1); } target.draw(); }, - destroy:function(card,targetPosition,player,event){ - if((event.name!='lose'&&event.name!='cardsDiscard')||targetPosition!='discardPile') return false; - var evt=event.getParent().relatedEvent; - if(evt&&evt.name=='useCard') return false; + destroy: function (card, targetPosition, player, event) { + if ( + (event.name != "lose" && event.name != "cardsDiscard") || + targetPosition != "discardPile" + ) + return false; + var evt = event.getParent().relatedEvent; + if (evt && evt.name == "useCard") return false; return true; }, - onDestroy:function(){ - var currentPhase=_status.currentPhase; - if(currentPhase){ - _status.chiling=true; - currentPhase.addTempSkill('g_chiling3'); + onDestroy: function () { + var currentPhase = _status.currentPhase; + if (currentPhase) { + _status.chiling = true; + currentPhase.addTempSkill("g_chiling3"); } - if(!lib.inpile.includes('zhaoshu')){ - lib.inpile.push('zhaoshu'); - var card=game.createCard2('zhaoshu','club',3); - game.log(card,'被置于了牌堆底'); + if (!lib.inpile.includes("zhaoshu")) { + lib.inpile.push("zhaoshu"); + var card = game.createCard2("zhaoshu", "club", 3); + game.log(card, "被置于了牌堆底"); ui.cardPile.appendChild(card); game.updateRoundNumber(); } }, - ai:{ - order:6, - result:{ - target:-1 + ai: { + order: 6, + result: { + target: -1, }, - tag:{ - multitarget:1, - multineg:1, - } - } + tag: { + multitarget: 1, + multineg: 1, + }, + }, }, - diaohulishan:{ - fullskin:true, - audio:true, - type:'trick', - enable:true, - global:'g_diaohulishan', - filterTarget:function(card,player,target){ - return target!=player; + diaohulishan: { + fullskin: true, + audio: true, + type: "trick", + enable: true, + global: "g_diaohulishan", + filterTarget: function (card, player, target) { + return target != player; }, - selectTarget:[1,2], - content:function(){ - target.addTempSkill('diaohulishan'); + selectTarget: [1, 2], + content: function () { + target.addTempSkill("diaohulishan"); }, - ai:{ - order:function(item, player){ - if(!player) player=get.player(); - if(player.hasCard(function(card){ - return ['gz_haolingtianxia','gz_guguoanbang','gz_kefuzhongyuan','wuzhong','yuanjiao','lianjunshengyan','lulitongxin','yiyi'].includes(get.name(card)); - },'hs')) return 3.5; - if(player.hasCard(function(card){ - return get.name(card)=='taoyuan'; - },'hs')) return get.order({name:'taoyuan'},player)-1; + ai: { + order: function (item, player) { + if (!player) player = get.player(); + if ( + player.hasCard(function (card) { + return [ + "gz_haolingtianxia", + "gz_guguoanbang", + "gz_kefuzhongyuan", + "wuzhong", + "yuanjiao", + "lianjunshengyan", + "lulitongxin", + "yiyi", + ].includes(get.name(card)); + }, "hs") + ) + return 3.5; + if ( + player.hasCard(function (card) { + return get.name(card) == "taoyuan"; + }, "hs") + ) + return get.order({ name: "taoyuan" }, player) - 1; return 9.5; }, - value:4, - useful:[2,1], - wuxie:function(){ + value: 4, + useful: [2, 1], + wuxie: function () { return 0; }, - result:{ - player:function(player,target){ - var att=get.attitude(player,target); - if(target.hp==1&&att<0) return 0; - if(game.hasPlayer(function(current){ - return get.attitude(player,current)1){ - player.chooseControl(controls).set('ai',function(){return 1}); + var controls = []; + if (target.countCards("h")) controls.push("手牌"); + if (target.isUnseen(0)) controls.push("主将"); + if (target.isUnseen(1)) controls.push("副将"); + if (controls.length > 1) { + player.chooseControl(controls).set("ai", function () { + return 1; + }); } - if(controls.length==0) event.finish(); - "step 1" + if (controls.length == 0) event.finish(); + "step 1"; var content; - var str=get.translation(target)+'的'; - if(result.control){ - if(result.control=='手牌'){ - content=[str+'手牌',target.getCards('h')]; - game.log(player,'观看了',target,'的手牌'); - } - else if(result.control=='主将'){ - content=[str+'主将',[[target.name1],'character']]; - game.log(player,'观看了',target,'的主将'); - } - else{ - content=[str+'副将',[[target.name2],'character']]; - game.log(player,'观看了',target,'的副将'); + var str = get.translation(target) + "的"; + if (result.control) { + if (result.control == "手牌") { + content = [str + "手牌", target.getCards("h")]; + game.log(player, "观看了", target, "的手牌"); + } else if (result.control == "主将") { + content = [str + "主将", [[target.name1], "character"]]; + game.log(player, "观看了", target, "的主将"); + } else { + content = [str + "副将", [[target.name2], "character"]]; + game.log(player, "观看了", target, "的副将"); } + } else if (target.countCards("h")) { + content = [str + "手牌", target.getCards("h")]; + game.log(player, "观看了", target, "的手牌"); + } else if (target.isUnseen(0)) { + content = [str + "主将", [[target.name1], "character"]]; + game.log(player, "观看了", target, "的主将"); + } else { + content = [str + "副将", [[target.name2], "character"]]; + game.log(player, "观看了", target, "的副将"); } - else if(target.countCards('h')){ - content=[str+'手牌',target.getCards('h')]; - game.log(player,'观看了',target,'的手牌'); - } - else if(target.isUnseen(0)){ - content=[str+'主将',[[target.name1],'character']]; - game.log(player,'观看了',target,'的主将'); - } - else{ - content=[str+'副将',[[target.name2],'character']]; - game.log(player,'观看了',target,'的副将'); - } - player.chooseControl('ok').set('dialog',content); + player.chooseControl("ok").set("dialog", content); }, - mode:['guozhan'], - ai:{ - order:9.5, - wuxie:function(){ + mode: ["guozhan"], + ai: { + order: 9.5, + wuxie: function () { return 0; }, - result:{ - player:function(player,target){ - if(player.countCards('h')<=player.hp) return 0; - if(player.storage.zhibi&&player.storage.zhibi.includes(target)) return 0; - return target.isUnseen()?1:0; - } - } - } + result: { + player: function (player, target) { + if (player.countCards("h") <= player.hp) return 0; + if (player.storage.zhibi && player.storage.zhibi.includes(target)) return 0; + return target.isUnseen() ? 1 : 0; + }, + }, + }, }, - yiyi:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - if(get.mode()=='guozhan'){ + yiyi: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + if (get.mode() == "guozhan") { return target.isFriendOf(player); - } - else if(get.is.versus()){ - return player.side==target.side; - } - else{ + } else if (get.is.versus()) { + return player.side == target.side; + } else { return true; } }, - selectTarget:function(){ - if(get.mode()=='guozhan') return -1; - return [1,3]; + selectTarget: function () { + if (get.mode() == "guozhan") return -1; + return [1, 3]; }, - content:function(){ + content: function () { target.draw(2); - target.chooseToDiscard(2,'he',true).ai=get.disvalue; + target.chooseToDiscard(2, "he", true).ai = get.disvalue; }, - ai:{ + ai: { wuxie: function () { return 0; }, basic: { order: 9, useful: 1.5, - value: 3 + value: 3, }, result: { target(player, target) { @@ -1112,839 +1288,964 @@ game.import('card',function(lib,game,ui,get,ai,_status){ if (!ui.selected.cards) y = 0; if (ui.selected.targets) tars = 0.01 * ui.selected.targets.length; else tars = 0; - if (target == player) i = player.countCards('h', function (card) { - if (y > 0 && ui.selected.cards.includes(card)) return false; - if (!y && get.name(card) === 'yiyi') { - y = -1; - return false; - } - return true; - }); - else i = target.countCards('he'); - if (target.hasSkillTag('noh')) add++; + if (target == player) + i = player.countCards("h", function (card) { + if (y > 0 && ui.selected.cards.includes(card)) return false; + if (!y && get.name(card) === "yiyi") { + y = -1; + return false; + } + return true; + }); + else i = target.countCards("he"); + if (target.hasSkillTag("noh")) add++; return add + Math.sqrt(i / 3.6 + tars) / 2; - } + }, }, tag: { draw: 2, loseCard: 2, discard: 2, multitarget: true, - norepeat: 1 - } - }, - }, - wuliu:{ - fullskin:true, - type:'equip', - subtype:'equip1', - global:'g_wuliu_skill', - distance:{attackFrom:-1}, - ai:{ - equipValue:function(card,player){ - if(player.identity=='unknown'||player.identity=='ye') return 2; - return 2+game.countPlayer(function(current){ - return current.isFriendOf(player); - })/2; + norepeat: 1, }, - basic:{ - equipValue:3 - } }, - skills:['wuliu_skill'], - mode:['guozhan'], }, - sanjian:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - basic:{ - equipValue:4 - } + wuliu: { + fullskin: true, + type: "equip", + subtype: "equip1", + global: "g_wuliu_skill", + distance: { attackFrom: -1 }, + ai: { + equipValue: function (card, player) { + if (player.identity == "unknown" || player.identity == "ye") return 2; + return ( + 2 + + game.countPlayer(function (current) { + return current.isFriendOf(player); + }) / + 2 + ); + }, + basic: { + equipValue: 3, + }, }, - skills:['sanjian_skill'] + skills: ["wuliu_skill"], + mode: ["guozhan"], }, - jingfanma:{ - fullskin:true, - type:'equip', - subtype:'equip4', - distance:{globalFrom:-1}, + sanjian: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + basic: { + equipValue: 4, + }, + }, + skills: ["sanjian_skill"], + }, + jingfanma: { + fullskin: true, + type: "equip", + subtype: "equip4", + distance: { globalFrom: -1 }, }, }, - skill:{ - zhaoshu_skill:{ - equipSkill:true, - charlotte:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var cards=player.getExpansions('zhaoshu_cards'); - if(cards.length<4) return false; - var list=[]; - for(var i of cards){ - list.add(get.suit(i,false)); - if(list.length>=4) return true; + skill: { + zhaoshu_skill: { + equipSkill: true, + charlotte: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var cards = player.getExpansions("zhaoshu_cards"); + if (cards.length < 4) return false; + var list = []; + for (var i of cards) { + list.add(get.suit(i, false)); + if (list.length >= 4) return true; } return false; }, - delay:false, - content:function(){ - 'step 0' - var cards=player.getExpansions('zhaoshu_cards'); + delay: false, + content: function () { + "step 0"; + var cards = player.getExpansions("zhaoshu_cards"); player.loseToDiscardpile(cards); game.delayx(); - 'step 1' - var list=[ - ['spade',12,'gz_haolingtianxia'], - ['diamond',1,'gz_kefuzhongyuan'], - ['heart',1,'gz_guguoanbang'], - ['club',12,'gz_wenheluanwu'], + "step 1"; + var list = [ + ["spade", 12, "gz_haolingtianxia"], + ["diamond", 1, "gz_kefuzhongyuan"], + ["heart", 1, "gz_guguoanbang"], + ["club", 12, "gz_wenheluanwu"], ]; - for(var i=0;i
  • 与你势力相同的角色的出牌阶段限一次,其可以将一张手牌(小势力角色改为至多两张)置于【诏书】上,称为“应”。
  • 出牌阶段限一次,若你的“应”中包含至少四种花色,则你可以发动“锦囊召唤”,将所有“应”置入弃牌堆,然后随机获得一张未加入游戏的势力锦囊牌。',false); - var cards=player.getExpansions('zhaoshu_cards'); - if(cards.length){ - dialog.addAuto(cards) + dialog.addText( + "
  • 与你势力相同的角色的出牌阶段限一次,其可以将一张手牌(小势力角色改为至多两张)置于【诏书】上,称为“应”。
  • 出牌阶段限一次,若你的“应”中包含至少四种花色,则你可以发动“锦囊召唤”,将所有“应”置入弃牌堆,然后随机获得一张未加入游戏的势力锦囊牌。", + false + ); + var cards = player.getExpansions("zhaoshu_cards"); + if (cards.length) { + dialog.addAuto(cards); } }, - content:'expansion', - markcount:function(content,player){ - return player.getExpansions('zhaoshu_cards').length; + content: "expansion", + markcount: function (content, player) { + return player.getExpansions("zhaoshu_cards").length; }, }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill).concat(player.getExpansions('zhaoshu_cards')); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill).concat(player.getExpansions("zhaoshu_cards")); + if (cards.length) player.loseToDiscardpile(cards); }, }, - zhaoshu_global:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(!player.countCards('h')) return false; - return game.hasPlayer(function(current){ - return current.hasSkill('zhaoshu_skill')&¤t.isFriendOf(player); + zhaoshu_global: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (!player.countCards("h")) return false; + return game.hasPlayer(function (current) { + return current.hasSkill("zhaoshu_skill") && current.isFriendOf(player); }); }, - filterCard:true, - selectCard:function(){ - if(_status.event.player.isNotMajor()) return [1,2]; - return [1,1]; + filterCard: true, + selectCard: function () { + if (_status.event.player.isNotMajor()) return [1, 2]; + return [1, 1]; }, - position:'h', - discard:false, - lose:false, - delay:false, - check:function(card){ - var player=_status.event.player,cards=ui.selected.cards.concat(game.findPlayer(function(current){ - return current.hasSkill('zhaoshu_skill')&¤t.isFriendOf(player); - }).getExpansions('zhaoshu_cards')),suit=get.suit(card,false); - for(var i of cards){ - if(get.suit(i)==suit) return 0; + position: "h", + discard: false, + lose: false, + delay: false, + check: function (card) { + var player = _status.event.player, + cards = ui.selected.cards.concat( + game + .findPlayer(function (current) { + return current.hasSkill("zhaoshu_skill") && current.isFriendOf(player); + }) + .getExpansions("zhaoshu_cards") + ), + suit = get.suit(card, false); + for (var i of cards) { + if (get.suit(i) == suit) return 0; } - return 5+player.needsToDiscard()*1.5-get.value(card); + return 5 + player.needsToDiscard() * 1.5 - get.value(card); }, - filterTarget:function(card,player,target){ - return target.hasSkill('zhaoshu_skill')&&target.isFriendOf(player); + filterTarget: function (card, player, target) { + return target.hasSkill("zhaoshu_skill") && target.isFriendOf(player); }, - selectTarget:function(){ - if(game.countPlayer(function(current){ - return current.hasSkill('zhaoshu_skill')&¤t.isFriendOf(_status.event.player); - })==1) return -1; + selectTarget: function () { + if ( + game.countPlayer(function (current) { + return ( + current.hasSkill("zhaoshu_skill") && current.isFriendOf(_status.event.player) + ); + }) == 1 + ) + return -1; return 1; }, - prompt:function(){ - var player=_status.event.player; - return '将'+(player.isNotMajor()?'至多两':'一')+'张手牌置于'+get.translation(game.filterPlayer(function(current){ - return current.hasSkill('zhaoshu_skill')&¤t.isFriendOf(player); - }))+'的【诏书】上'; + prompt: function () { + var player = _status.event.player; + return ( + "将" + + (player.isNotMajor() ? "至多两" : "一") + + "张手牌置于" + + get.translation( + game.filterPlayer(function (current) { + return current.hasSkill("zhaoshu_skill") && current.isFriendOf(player); + }) + ) + + "的【诏书】上" + ); }, - content:function(){ - 'step 0' - target.addToExpansion(cards,player,'give').gaintag.add('zhaoshu_cards'); - 'step 1' - target.markSkill('zhaoshu_skill'); + content: function () { + "step 0"; + target.addToExpansion(cards, player, "give").gaintag.add("zhaoshu_cards"); + "step 1"; + target.markSkill("zhaoshu_skill"); }, - ai:{ - order:1, - result:{ - player:1, + ai: { + order: 1, + result: { + player: 1, }, }, }, - liulongcanjia:{ - equipSkill:true, - mod:{ - canBeReplaced:function(card,player){ - if(player.getEquips('liulongcanjia').includes(card)) return false; + liulongcanjia: { + equipSkill: true, + mod: { + canBeReplaced: function (card, player) { + if (player.getEquips("liulongcanjia").includes(card)) return false; }, }, }, - minguangkai_cancel:{ - equipSkill:true, - trigger:{target:'useCardToTarget'}, - forced:true, - check:function(event,player){ - return get.effect(event.target,event.card,event.player,player)<0; + minguangkai_cancel: { + equipSkill: true, + trigger: { target: "useCardToTarget" }, + forced: true, + check: function (event, player) { + return get.effect(event.target, event.card, event.player, player) < 0; }, - filter:function(event,player){ - if(['huoshaolianying','huogong'].includes(event.card.name)) return true; - if(event.card.name=='sha') return game.hasNature(event.card,'fire'); + filter: function (event, player) { + if (["huoshaolianying", "huogong"].includes(event.card.name)) return true; + if (event.card.name == "sha") return game.hasNature(event.card, "fire"); return false; }, - content:function(){ + content: function () { trigger.getParent().targets.remove(player); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(['huoshaolianying','huogong'].includes(card.name)||(card.name=='sha'&&game.hasNature(card,'fire'))){ - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if ( + ["huoshaolianying", "huogong"].includes(card.name) || + (card.name == "sha" && game.hasNature(card, "fire")) + ) { + return "zeroplayertarget"; } }, - } - } - }, - minguangkai_link:{ - equipSkill:true, - trigger:{player:'linkBefore'}, - forced:true, - filter:function(event,player){ - return player.isNotMajor()&&!player.isLinked(); + }, }, - content:function(){ + }, + minguangkai_link: { + equipSkill: true, + trigger: { player: "linkBefore" }, + forced: true, + filter: function (event, player) { + return player.isNotMajor() && !player.isLinked(); + }, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target.isMinor()&&['tiesuo','lulitongxin'].includes(card.name)){ - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (target.isMinor() && ["tiesuo", "lulitongxin"].includes(card.name)) { + return "zeroplayertarget"; } }, - } - } + }, + }, }, - dinglanyemingzhu_skill:{ - equipSkill:true, - inherit:'zhiheng', - filter:function(event,player){ - return !player.hasSkill('gzzhiheng',true); + dinglanyemingzhu_skill: { + equipSkill: true, + inherit: "zhiheng", + filter: function (event, player) { + return !player.hasSkill("gzzhiheng", true); }, - selectCard:function(){ - var player=_status.event.player; - return [1,player.maxHp]; + selectCard: function () { + var player = _status.event.player; + return [1, player.maxHp]; }, - filterCard:function(card,player){ - var cards=player.getEquips('dinglanyemingzhu'); - if(cards.length) return cards.some(card2=>card2!=card&&!ui.selected.cards.includes(card2)) + filterCard: function (card, player) { + var cards = player.getEquips("dinglanyemingzhu"); + if (cards.length) + return cards.some((card2) => card2 != card && !ui.selected.cards.includes(card2)); return true; }, - prompt:'出牌阶段限一次,你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌' + prompt: "出牌阶段限一次,你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌", }, - g_dinglanyemingzhu_ai:{ - ai:{ - effect:{ - player:function(card,player){ - if(player.hasSkill('jubao')) return; - if(card.name=='dinglanyemingzhu'&&game.hasPlayer(function(current){ - return current.hasSkill('jubao')&&get.attitude(player,current)<=0; - })){ - return [0,0,0,0]; - } - } - } - } - }, - g_feilongduofeng_ai:{ - ai:{ - effect:{ - player:function(card,player){ - if(player.hasSkill('zhangwu')) return; - if(card.name=='feilongduofeng'&&game.hasPlayer(function(current){ - return current.hasSkill('zhangwu')&&get.attitude(player,current)<=0; - })){ - return [0,0,0,0]; - } - } - } - } - }, - g_taipingyaoshu_ai:{ - ai:{ - effect:{ - player:function(card,player){ - if(player.hasSkill('wendao')) return; - if(card.name=='taipingyaoshu'&&game.hasPlayer(function(current){ - return current.hasSkill('wendao')&&get.attitude(player,current)<=0; - })){ - return [0,0,0,0]; + g_dinglanyemingzhu_ai: { + ai: { + effect: { + player: function (card, player) { + if (player.hasSkill("jubao")) return; + if ( + card.name == "dinglanyemingzhu" && + game.hasPlayer(function (current) { + return current.hasSkill("jubao") && get.attitude(player, current) <= 0; + }) + ) { + return [0, 0, 0, 0]; } }, - target:(card,player,target)=>{ - if(target._g_taipingyaoshu_temp) return; - if(get.subtype(card)==='equip2'&&target.getEquip('taipingyaoshu')&&!target.countEmptySlot(2)){ - target._g_taipingyaoshu_temp=true; - let lose=get.effect(target,{name:'losehp'},target,target), - draw=2*get.effect(target,{name:'draw'},target,target); - delete target._g_taipingyaoshu_temp; - if(lose<0&&target.hp<=1&&!target.hasCard(i=>{ - return get.name(i)==='tao'&&lib.filter.cardEnabled(i,target,'forceEnable'); - })) draw=0; - return [1,(lose+draw)/get.attitude(target,target)]; + }, + }, + }, + g_feilongduofeng_ai: { + ai: { + effect: { + player: function (card, player) { + if (player.hasSkill("zhangwu")) return; + if ( + card.name == "feilongduofeng" && + game.hasPlayer(function (current) { + return current.hasSkill("zhangwu") && get.attitude(player, current) <= 0; + }) + ) { + return [0, 0, 0, 0]; } - } - } - } - }, - feilongduofeng:{ - equipSkill:true, - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - check:function(event,player){ - return get.attitude(player,event.target)<=0; - }, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('he'); - }, - content:function(){ - trigger.target.chooseToDiscard('he',true); + }, + }, }, }, - feilongduofeng2:{ - equipSkill:true, - trigger:{source:'dieAfter'}, - filter:function(event,player){ - if(event.reason&&event.reason.card&&event.reason.card.name=='sha'){ - return event.player.isDead()&&lib.group.includes(player.identity)&&player.isMinor(); + g_taipingyaoshu_ai: { + ai: { + effect: { + player: function (card, player) { + if (player.hasSkill("wendao")) return; + if ( + card.name == "taipingyaoshu" && + game.hasPlayer(function (current) { + return current.hasSkill("wendao") && get.attitude(player, current) <= 0; + }) + ) { + return [0, 0, 0, 0]; + } + }, + target: (card, player, target) => { + if (target._g_taipingyaoshu_temp) return; + if ( + get.subtype(card) === "equip2" && + target.getEquip("taipingyaoshu") && + !target.countEmptySlot(2) + ) { + target._g_taipingyaoshu_temp = true; + let lose = get.effect(target, { name: "losehp" }, target, target), + draw = 2 * get.effect(target, { name: "draw" }, target, target); + delete target._g_taipingyaoshu_temp; + if ( + lose < 0 && + target.hp <= 1 && + !target.hasCard((i) => { + return ( + get.name(i) === "tao" && + lib.filter.cardEnabled(i, target, "forceEnable") + ); + }) + ) + draw = 0; + return [1, (lose + draw) / get.attitude(target, target)]; + } + }, + }, + }, + }, + feilongduofeng: { + equipSkill: true, + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + check: function (event, player) { + return get.attitude(player, event.target) <= 0; + }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countCards("he"); + }, + content: function () { + trigger.target.chooseToDiscard("he", true); + }, + }, + feilongduofeng2: { + equipSkill: true, + trigger: { source: "dieAfter" }, + filter: function (event, player) { + if (event.reason && event.reason.card && event.reason.card.name == "sha") { + return ( + event.player.isDead() && lib.group.includes(player.identity) && player.isMinor() + ); } return false; }, - logTarget:'player', - content:function(){ - 'step 0' - var list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - var info=lib.character[_status.characterlist[i]]; - if(info[4]&&info[4].includes('jun')) continue; - if(info[1]==player.identity){ + logTarget: "player", + content: function () { + "step 0"; + var list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + var info = lib.character[_status.characterlist[i]]; + if (info[4] && info[4].includes("jun")) continue; + if (info[1] == player.identity) { list.push(_status.characterlist[i]); } } - event.identity=event.player.identity; - if(trigger.player==game.me&&!_status.auto){ - event.dialog=ui.create.dialog('是否选择一名角色重新加入游戏?',[list,'character']); - event.filterButton=function(){return true}; - event.player=game.me; - event.custom.replace.confirm=function(){ - if(!ui.selected.buttons.length){ - event.directresult='refuse'; - } - else{ - event.directresult=ui.selected.buttons[0].link; + event.identity = event.player.identity; + if (trigger.player == game.me && !_status.auto) { + event.dialog = ui.create.dialog("是否选择一名角色重新加入游戏?", [ + list, + "character", + ]); + event.filterButton = function () { + return true; + }; + event.player = game.me; + event.custom.replace.confirm = function () { + if (!ui.selected.buttons.length) { + event.directresult = "refuse"; + } else { + event.directresult = ui.selected.buttons[0].link; } event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; game.resume(); - } - event.switchToAuto=function(){ - event.directresult=list.randomGet(); + }; + event.switchToAuto = function () { + event.directresult = list.randomGet(); event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; }; game.check(); game.pause(); - } - else if(trigger.player.isOnline()){ - trigger.player.send(function(player,list){ - if(_status.auto){ - _status.event._result=list.randomGet(); - } - else{ - var next=game.createEvent('replacePlayer'); - next.source=player; - next.list=list; - next.setContent(function(){ - event.dialog=ui.create.dialog('是否选择一名角色重新加入游戏?',[event.list,'character']); - event.filterButton=function(){return true}; - event.player=event.source; - event.custom.replace.confirm=function(){ - if(!ui.selected.buttons.length){ - event.result='refuse'; - } - else{ - event.result=ui.selected.buttons[0].link; - } - event.dialog.close(); - if(ui.confirm) ui.confirm.close(); - delete event.player; - game.resume(); - game.uncheck(); - } - event.switchToAuto=function(){ - event.result=list.randomGet(); - event.dialog.close(); - if(ui.confirm) ui.confirm.close(); - delete event.player; - game.uncheck(); - }; - game.check(); - game.pause(); - }); - } - game.resume(); - },trigger.player,list); + } else if (trigger.player.isOnline()) { + trigger.player.send( + function (player, list) { + if (_status.auto) { + _status.event._result = list.randomGet(); + } else { + var next = game.createEvent("replacePlayer"); + next.source = player; + next.list = list; + next.setContent(function () { + event.dialog = ui.create.dialog("是否选择一名角色重新加入游戏?", [ + event.list, + "character", + ]); + event.filterButton = function () { + return true; + }; + event.player = event.source; + event.custom.replace.confirm = function () { + if (!ui.selected.buttons.length) { + event.result = "refuse"; + } else { + event.result = ui.selected.buttons[0].link; + } + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + delete event.player; + game.resume(); + game.uncheck(); + }; + event.switchToAuto = function () { + event.result = list.randomGet(); + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + delete event.player; + game.uncheck(); + }; + game.check(); + game.pause(); + }); + } + game.resume(); + }, + trigger.player, + list + ); trigger.player.wait(); game.pause(); + } else { + event.directresult = list.randomGet(); } - else{ - event.directresult=list.randomGet(); - } - event.list=list; - 'step 1' + event.list = list; + "step 1"; game.uncheck(); - if(!event.directresult){ - if(event.resultOL){ - event.directresult=event.resultOL[trigger.player.playerid]; + if (!event.directresult) { + if (event.resultOL) { + event.directresult = event.resultOL[trigger.player.playerid]; } - if(!event.directresult||event.directresult=='ai'){ - event.directresult=event.list.randomGet(); + if (!event.directresult || event.directresult == "ai") { + event.directresult = event.list.randomGet(); } } - if(event.directresult=='refuse'){ - game.log(trigger.player,'拒绝重新加入游戏'); + if (event.directresult == "refuse") { + game.log(trigger.player, "拒绝重新加入游戏"); return; } - game.log(trigger.player,'重新加入游戏'); - var name=event.directresult; - game.log(trigger.player,'将主将替换为','#b'+name); + game.log(trigger.player, "重新加入游戏"); + var name = event.directresult; + game.log(trigger.player, "将主将替换为", "#b" + name); _status.characterlist.remove(name); - game.broadcastAll(function(source,name,identity){ - source.revive(2,false); - source.identity=identity; - source._group=identity; - source.setIdentity(); - if(source==game.me){ - ui.arena.classList.remove('selecting'); - } - },trigger.player,name,event.identity); + game.broadcastAll( + function (source, name, identity) { + source.revive(2, false); + source.identity = identity; + source._group = identity; + source.setIdentity(); + if (source == game.me) { + ui.arena.classList.remove("selecting"); + } + }, + trigger.player, + name, + event.identity + ); trigger.player.draw(); - trigger.player.reinit(trigger.player.name1,name,false); + trigger.player.reinit(trigger.player.name1, name, false); trigger.player.removeCharacter(1); - trigger.getParent('damage').untrigger(false,trigger.player); - game.addVideo('setIdentity',trigger.player,event.identity); - } + trigger.getParent("damage").untrigger(false, trigger.player); + game.addVideo("setIdentity", trigger.player, event.identity); + }, }, - feilongduofeng3:{ - equipSkill:true, - trigger:{source:'dying'}, - filter:function(event,player){ - var evt=event.getParent('damage'); - return evt&&evt.card&&evt.card.name=='sha'&&event.player.countGainableCards(player,'h')>0; + feilongduofeng3: { + equipSkill: true, + trigger: { source: "dying" }, + filter: function (event, player) { + var evt = event.getParent("damage"); + return ( + evt && + evt.card && + evt.card.name == "sha" && + event.player.countGainableCards(player, "h") > 0 + ); }, //priority:7, - logTarget:'player', - prompt2:'获得该角色的一张手牌', - check:function(event,player){ - return get.attitude(player,event.player)<0; + logTarget: "player", + prompt2: "获得该角色的一张手牌", + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - content:function(){ - player.gainPlayerCard(trigger.player,'h',true); + content: function () { + player.gainPlayerCard(trigger.player, "h", true); }, }, - taipingyaoshu:{ - equipSkill:true, - mod:{ - maxHandcard:function(player,num){ - if(get.mode()=='guozhan'){ - if(player.hasSkill('huangjintianbingfu')){ - num+=player.getExpansions('huangjintianbingfu').length; + taipingyaoshu: { + equipSkill: true, + mod: { + maxHandcard: function (player, num) { + if (get.mode() == "guozhan") { + if (player.hasSkill("huangjintianbingfu")) { + num += player.getExpansions("huangjintianbingfu").length; } - return num+game.countPlayer(function(current){ - return current.isFriendOf(player); - }); + return ( + num + + game.countPlayer(function (current) { + return current.isFriendOf(player); + }) + ); } - return num+game.countGroup()-1; - } + return num + game.countGroup() - 1; + }, }, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - if(event.nature) return true; + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + if (event.nature) return true; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); }, - ai:{ - nofire:true, - nothunder:true, - effect:{ - target:function(card,player,target,current){ - if(target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:target, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:target, - card:card - })) return; - if(get.tag(card,'natureDamage')) return 'zeroplayertarget'; - if(card.name=='tiesuo'){ - return [0,0]; + ai: { + nofire: true, + nothunder: true, + effect: { + target: function (card, player, target, current) { + if (target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) + return; + if (get.tag(card, "natureDamage")) return "zeroplayertarget"; + if (card.name == "tiesuo") { + return [0, 0]; } - } - } - } - }, - g_taipingyaoshu:{}, - yuxi_skill:{ - equipSkill:true, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ - return !player.isUnseen()&&!event.numFixed; + }, + }, }, - content:function(){ + }, + g_taipingyaoshu: {}, + yuxi_skill: { + equipSkill: true, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { + return !player.isUnseen() && !event.numFixed; + }, + content: function () { trigger.num++; }, - ai:{ - threaten:1.3, - forceMajor:true, + ai: { + threaten: 1.3, + forceMajor: true, }, - group:'yuxi_skill2' + group: "yuxi_skill2", }, - yuxi_skill2:{ - equipSkill:true, - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - if(player.isUnseen()) return false; - return game.hasPlayer(function(current){ - return player.canUse('zhibi',current); + yuxi_skill2: { + equipSkill: true, + trigger: { player: "phaseUseBegin" }, + forced: true, + filter: function (event, player) { + if (player.isUnseen()) return false; + return game.hasPlayer(function (current) { + return player.canUse("zhibi", current); }); }, - content:function(){ - player.chooseUseTarget('玉玺:选择知己知彼的目标',{name:'zhibi'}); - } + content: function () { + player.chooseUseTarget("玉玺:选择知己知彼的目标", { name: "zhibi" }); + }, }, - xietianzi:{ - forced:true, - popup:false, - filter:function(event,player){ - return player.countCards('h')>0; + xietianzi: { + forced: true, + popup: false, + filter: function (event, player) { + return player.countCards("h") > 0; }, - trigger:{ - player:'phaseDiscardAfter', + trigger: { + player: "phaseDiscardAfter", }, - content:function(){ - "step 0" - player.removeSkill('xietianzi'); - player.chooseToDiscard('h','是否弃置一张手牌并获得一个额外回合?').set('ai',function(card){ - return 10-get.value(card); - }); - "step 1" - if(result.bool){ + content: function () { + "step 0"; + player.removeSkill("xietianzi"); + player + .chooseToDiscard("h", "是否弃置一张手牌并获得一个额外回合?") + .set("ai", function (card) { + return 10 - get.value(card); + }); + "step 1"; + if (result.bool) { player.insertPhase(); } }, }, - g_chiling3:{ - mode:['guozhan'], - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - filter:function(){ - return _status.chiling==true; + g_chiling3: { + mode: ["guozhan"], + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + filter: function () { + return _status.chiling == true; }, - content:function(){ - 'step 0' - _status.chiling=false; - var targets=game.filterPlayer(function(target){ + content: function () { + "step 0"; + _status.chiling = false; + var targets = game.filterPlayer(function (target) { return target.isUnseen(); }); targets.sort(lib.sort.seat); - event.targets=targets; - 'step 1' - if(event.targets.length){ - var target=event.targets.shift(); - event.current=target; - var choiceList=['明置一张武将牌,然后摸一张牌','失去1点体力']; - if(target.countCards('he',{type:'equip'})){ - choiceList.push('弃置一张装备牌'); + event.targets = targets; + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + event.current = target; + var choiceList = ["明置一张武将牌,然后摸一张牌", "失去1点体力"]; + if (target.countCards("he", { type: "equip" })) { + choiceList.push("弃置一张装备牌"); } - target.chooseControl(lib.card.chiling.chooseai).set('prompt','敕令').set('choiceList',choiceList); - } - else{ + target + .chooseControl(lib.card.chiling.chooseai) + .set("prompt", "敕令") + .set("choiceList", choiceList); + } else { event.finish(); } - 'step 2' - var target=event.current; - if(result.control=='选项一'){ - target.chooseControl('主将','副将',function(){ - return Math.floor(Math.random()*2); - }).set('prompt','选择要明置的武将牌'); - } - else if(result.control=='选项二'){ + "step 2"; + var target = event.current; + if (result.control == "选项一") { + target + .chooseControl("主将", "副将", function () { + return Math.floor(Math.random() * 2); + }) + .set("prompt", "选择要明置的武将牌"); + } else if (result.control == "选项二") { target.loseHp(); event.goto(1); - } - else{ - target.chooseToDiscard('he',{type:'equip'},true); + } else { + target.chooseToDiscard("he", { type: "equip" }, true); event.goto(1); } - 'step 3' - var target=event.current; - if(result.index==0){ + "step 3"; + var target = event.current; + if (result.index == 0) { target.showCharacter(0); - } - else{ + } else { target.showCharacter(1); } target.draw(); event.goto(1); - } + }, }, - g_diaohulishan:{}, - diaohulishan:{ - charlotte:true, - group:'undist', - init:function(player){ - if(player.isIn()){ - game.broadcastAll(function(player){ - player.classList.add('out'); - },player); - game.log(player,'移出了游戏'); + g_diaohulishan: {}, + diaohulishan: { + charlotte: true, + group: "undist", + init: function (player) { + if (player.isIn()) { + game.broadcastAll(function (player) { + player.classList.add("out"); + }, player); + game.log(player, "移出了游戏"); } }, - onremove:function(player){ - if(player.isOut()){ - game.broadcastAll(function(player){ - player.classList.remove('out'); - },player); - game.log(player,'移回了游戏'); + onremove: function (player) { + if (player.isOut()) { + game.broadcastAll(function (player) { + player.classList.remove("out"); + }, player); + game.log(player, "移回了游戏"); } }, }, - huxinjing:{ - equipSkill:true, - trigger:{player:'damageBegin4'}, + huxinjing: { + equipSkill: true, + trigger: { player: "damageBegin4" }, // forced:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - var cards=player.getEquips('huxinjing'); - if(!cards.length) return false; - if(get.mode()!='guozhan'&&event.num>1) return true; - return event.num>=player.hp; + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + var cards = player.getEquips("huxinjing"); + if (!cards.length) return false; + if (get.mode() != "guozhan" && event.num > 1) return true; + return event.num >= player.hp; }, - content:function(){ + content: function () { trigger.cancel(); - var e2=player.getEquips('huxinjing'); - if(e2.length){ + var e2 = player.getEquips("huxinjing"); + if (e2.length) { player.discard(e2); } - player.removeSkill('huxinjing'); - } + player.removeSkill("huxinjing"); + }, }, - wuliu_skill:{ - equipSkill:true, + wuliu_skill: { + equipSkill: true, }, - g_wuliu_skill:{ - equipSkill:true, - mod:{ - attackRange:function(player,distance){ - return distance+game.countPlayer(function(current){ - if(current==player||!current.isFriendOf(player)) return false; - if(current.hasSkill('wuliu_skill')) return true; - }); - } - } + g_wuliu_skill: { + equipSkill: true, + mod: { + attackRange: function (player, distance) { + return ( + distance + + game.countPlayer(function (current) { + if (current == player || !current.isFriendOf(player)) return false; + if (current.hasSkill("wuliu_skill")) return true; + }) + ); + }, + }, }, - sanjian_skill:{ - equipSkill:true, - audio:true, - trigger:{source:'damageSource'}, - direct:true, - filter:function(event,player){ - if(event.player.isDead()) return false; - if(player.countCards('h')==0) return false; - if(!event.card) return false; - if(event.card.name!='sha') return false; - if(!event.notLink()) return false; - return game.hasPlayer(function(current){ - return current!=event.player&&get.distance(event.player,current)<=1; + sanjian_skill: { + equipSkill: true, + audio: true, + trigger: { source: "damageSource" }, + direct: true, + filter: function (event, player) { + if (event.player.isDead()) return false; + if (player.countCards("h") == 0) return false; + if (!event.card) return false; + if (event.card.name != "sha") return false; + if (!event.notLink()) return false; + return game.hasPlayer(function (current) { + return current != event.player && get.distance(event.player, current) <= 1; }); }, - content:function(){ - "step 0" - var damaged=trigger.player; - player.chooseCardTarget({ - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - var damaged=_status.event.damaged; - return get.distance(damaged,target)<=1&&target!=damaged; - }, - ai1:function(card){ - return 9-get.value(card); - }, - ai2:function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }, - prompt:get.prompt('sanjian') - }).set('damaged',damaged); - "step 1" - if(result.bool){ - player.logSkill('sanjian_skill',result.targets); + content: function () { + "step 0"; + var damaged = trigger.player; + player + .chooseCardTarget({ + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + var damaged = _status.event.damaged; + return get.distance(damaged, target) <= 1 && target != damaged; + }, + ai1: function (card) { + return 9 - get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }, + prompt: get.prompt("sanjian"), + }) + .set("damaged", damaged); + "step 1"; + if (result.bool) { + player.logSkill("sanjian_skill", result.targets); player.discard(result.cards); result.targets[0].damage(); } - } + }, }, }, - translate:{ - liulongcanjia:'六龙骖驾', - liulongcanjia_info:'锁定技。此牌占用1个进攻坐骑和1个防御坐骑槽位,且不可被替换。你计算与其他角色的距离-1,其他角色计算与你的距离+1。', - minguangkai:'明光铠', - minguangkai_cancel:'明光铠', - minguangkai_link:'明光铠', - minguangkai_info:'锁定技。①当你成为【火烧连营】、【火攻】或火【杀】的目标时,取消之。②当你即将横置前,若你是小势力角色,取消之。', - dinglanyemingzhu:'定澜夜明珠', - dinglanyemingzhu_bg:'珠', - dinglanyemingzhu_info:'锁定技。若你拥有〖制衡〗,则你取消〖制衡〗的弃置牌数限制,否则你视为拥有〖制衡〗。', - dinglanyemingzhu_skill:'制衡', - dinglanyemingzhu_skill_info:'出牌阶段限一次。你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌。', - feilongduofeng:'飞龙夺凤', - feilongduofeng2:'飞龙夺凤', - feilongduofeng3:'飞龙夺凤', - feilongduofeng_info:'①当你使用【杀】指定目标后,你可令目标角色弃置一张牌。②当你因使用【杀】而令其他角色进入濒死状态时,你可以获得其一张手牌。', - taipingyaoshu:'太平要术', - taipingyaoshu_info:'锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为场上势力数-1)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。', - taipingyaoshu_info_guozhan:'锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为与你势力相同的角色数)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。', - yuxi_skill:'玉玺', - yuxi_skill2:'玉玺', - yuxi:'玉玺', - yuxi_info:'锁定技。若你有明置的武将牌,则:①你的势力视为唯一的大势力。②摸牌阶段开始时,你令额定摸牌数+1。③出牌阶段开始时,你视为使用【知己知彼】。', - xietianzi:'挟令', - xietianzi_info:'出牌阶段,对自己使用。你结束出牌阶段。本回合的弃牌阶段结束时,你可以弃置一张手牌,获得一个额外的回合。', - xietianzi_info_guozhan:'出牌阶段,对身为大势力角色的自己使用。你结束出牌阶段。本回合的弃牌阶段结束时,你可以弃置一张手牌,获得一个额外的回合。', - shuiyanqijunx:'水淹七军', - shuiyanqijunx_info:'出牌阶段,对一名其他角色使用。目标角色选择一项:⒈弃置装备区里的所有牌(至少一张)。⒉受到你造成的1点雷电伤害。', - shuiyanqijunx_info_guozhan:'出牌阶段,对一名装备区里有牌的其他角色使用。目标角色选择一项:⒈弃置装备区里的所有牌。⒉受到你造成的1点雷电伤害。', - lulitongxin:'勠力同心', - lulitongxin_info:'出牌阶段,对所有大势力角色或所有小势力角色使用。若目标角色:未横置,则其横置;已横置,则其摸一张牌。', - lulitongxin_info_versus:'出牌阶段,对所有己方角色或所有敌方角色使用。若目标角色:未横置,则其横置;已横置,则其摸一张牌。', - lianjunshengyan:'联军盛宴', - lianjunshengyan_info:'出牌阶段,对你和你选择的除你的势力外的一个势力的所有角色使用。若目标角色:为你,你选择摸Y张牌并回复X-Y点体力(X为该势力的角色数,Y∈[0,X]);不为你,其摸一张牌,然后重置。', - lianjunshengyan_info_boss:'出牌阶段,对场上所有角色使用。你摸X张牌(X为存活角色数),其他角色依次选择回复1点体力或摸一张牌。', - chiling:'敕令', - chiling_info:'①出牌阶段,对所有没有势力的角色使用。目标角色选择一项:1、明置一张武将牌,然后摸一张牌;2、弃置一张装备牌;3、失去1点体力。②当【敕令】因判定或弃置而置入弃牌堆时,系统将之移出游戏并将【诏书】置于牌堆底,然后系统于当前回合结束后视为对所有没有势力的角色使用【敕令】。', - diaohulishan:'调虎离山', - diaohulishan_info:'出牌阶段,对至多两名其他角色使用。目标角色于此回合视为移出游戏。', - huoshaolianying:'火烧连营', - huoshaolianying_bg:'烧', - huoshaolianying_info_guozhan:'出牌阶段,对你的下家及其队列中的所有角色使用。你对目标角色造成1点火属性伤害。', - huoshaolianying_info:'出牌阶段,对距离最小的一名横置角色使用(若无横置角色,则改为对距离最小的所有角色使用),你对目标造成1点火属性伤害。', - yuanjiao:'远交近攻', - yuanjiao_info:'出牌阶段,对一名与你势力不同的其他角色使用。其摸一张牌,然后你摸三张牌。', - yuanjiao_info_guozhan:'出牌阶段,对一名与你势力不同且已确定势力的其他角色使用。其摸一张牌,然后你摸三张牌。', - yuanjiao_bg:'交', - zhibi:'知己知彼', - zhibi_info:'出牌阶段,对一名有手牌或有暗置武将牌的其他角色使用。你选择一项:⒈观看其手牌。⒉观看其的一张暗置武将牌。', - yiyi:'以逸待劳', - yiyi_info_guozhan:'出牌阶段,对所有己方角色使用。目标角色摸两张牌,然后弃置两张牌。', - yiyi_info_combat:'出牌阶段,对所有己方角色使用。目标角色摸两张牌,然后弃置两张牌。', - yiyi_info:'出牌阶段,对至多三名角色使用。目标角色摸两张牌,然后弃置两张牌。', - yiyi_bg:'逸', - wuliu:'吴六剑', - wuliu_info:'锁定技。与你势力相同的所有其他角色的攻击范围+1。', - sanjian:'三尖两刃刀', - sanjian_info:'当你因执行【杀】而对A造成伤害后,你可以弃置一张牌并选择一名其他角色B(A至B的距离需为1)。你对B造成1点伤害。', - wuliu_skill:'吴六剑', - sanjian_skill:'三尖两刃刀', - jingfanma_bg:'-马', - jingfanma:'惊帆', - jingfanma_info:'锁定技,你计算与其他角色的距离-1。', - huxinjing_bg:'镜', - huxinjing:'护心镜', - huxinjing_info:'此牌可对其他角色使用。当你受到伤害时,若伤害值大于1或大于等于你的体力值,则你可以将所有【护心镜】置入弃牌堆,然后防止此伤害。', - huxinjing_info_guozhan:'当你受到伤害时,若伤害值大于等于你的体力值,则你可以将所有【护心镜】置入弃牌堆,然后防止此伤害。', - gz_haolingtianxia:'号令天下', - gz_haolingtianxia_info:'出牌阶段,对一名体力值不为全场最少的角色使用。所有其他角色依次可以选择一项:①弃置一张牌(魏势力角色无需弃牌),视为对目标角色使用一张【杀】;②弃置目标角色的一张牌(魏势力角色改为获得其一张牌)。', - gz_kefuzhongyuan:'克复中原', - gz_kefuzhongyuan_info:'出牌阶段,对任意名角色使用。目标角色选择一项:①视为使用一张【杀】(蜀势力角色以此法使用【杀】的伤害值基数+1);②摸一张牌(蜀势力角色改为摸两张牌)。', - gz_guguoanbang:'固国安邦', - gz_guguoanbang_info:'出牌阶段,对你自己使用。你摸八张牌,然后弃置至少六张手牌。然后若你的势力为吴,则你可以将你以此法弃置的牌交给其他吴势力角色(每名角色至多获得两张牌)。', - gz_wenheluanwu:'文和乱武', - gz_wenheluanwu_info:'出牌阶段,对所有角色使用。目标角色展示所有手牌,然后你选择一项:①令其弃置两张类型不同的手牌;②你弃置其一张手牌。然后若其为群势力角色且其没有手牌,则其将手牌摸至当前体力值(至多为5)。', - zhaoshu:'诏书', - zhaoshu_skill:'锦囊召唤', - zhaoshu_global:'诏书', - zhaoshu_info:'
  • 出牌阶段,对你自己使用。你将此牌置于目标的武将牌上。
  • 与你势力相同的角色的出牌阶段限一次,其可以将一张手牌(小势力角色改为至多两张)置于【诏书】上,称为“应”。
  • 出牌阶段限一次,若你的“应”中包含至少四种花色,则你可以发动“锦囊召唤”:将所有“应”置入弃牌堆,然后随机获得一张未加入游戏的势力锦囊牌。', + translate: { + liulongcanjia: "六龙骖驾", + liulongcanjia_info: + "锁定技。此牌占用1个进攻坐骑和1个防御坐骑槽位,且不可被替换。你计算与其他角色的距离-1,其他角色计算与你的距离+1。", + minguangkai: "明光铠", + minguangkai_cancel: "明光铠", + minguangkai_link: "明光铠", + minguangkai_info: + "锁定技。①当你成为【火烧连营】、【火攻】或火【杀】的目标时,取消之。②当你即将横置前,若你是小势力角色,取消之。", + dinglanyemingzhu: "定澜夜明珠", + dinglanyemingzhu_bg: "珠", + dinglanyemingzhu_info: + "锁定技。若你拥有〖制衡〗,则你取消〖制衡〗的弃置牌数限制,否则你视为拥有〖制衡〗。", + dinglanyemingzhu_skill: "制衡", + dinglanyemingzhu_skill_info: + "出牌阶段限一次。你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌。", + feilongduofeng: "飞龙夺凤", + feilongduofeng2: "飞龙夺凤", + feilongduofeng3: "飞龙夺凤", + feilongduofeng_info: + "①当你使用【杀】指定目标后,你可令目标角色弃置一张牌。②当你因使用【杀】而令其他角色进入濒死状态时,你可以获得其一张手牌。", + taipingyaoshu: "太平要术", + taipingyaoshu_info: + "锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为场上势力数-1)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。", + taipingyaoshu_info_guozhan: + "锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为与你势力相同的角色数)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。", + yuxi_skill: "玉玺", + yuxi_skill2: "玉玺", + yuxi: "玉玺", + yuxi_info: + "锁定技。若你有明置的武将牌,则:①你的势力视为唯一的大势力。②摸牌阶段开始时,你令额定摸牌数+1。③出牌阶段开始时,你视为使用【知己知彼】。", + xietianzi: "挟令", + xietianzi_info: + "出牌阶段,对自己使用。你结束出牌阶段。本回合的弃牌阶段结束时,你可以弃置一张手牌,获得一个额外的回合。", + xietianzi_info_guozhan: + "出牌阶段,对身为大势力角色的自己使用。你结束出牌阶段。本回合的弃牌阶段结束时,你可以弃置一张手牌,获得一个额外的回合。", + shuiyanqijunx: "水淹七军", + shuiyanqijunx_info: + "出牌阶段,对一名其他角色使用。目标角色选择一项:⒈弃置装备区里的所有牌(至少一张)。⒉受到你造成的1点雷电伤害。", + shuiyanqijunx_info_guozhan: + "出牌阶段,对一名装备区里有牌的其他角色使用。目标角色选择一项:⒈弃置装备区里的所有牌。⒉受到你造成的1点雷电伤害。", + lulitongxin: "勠力同心", + lulitongxin_info: + "出牌阶段,对所有大势力角色或所有小势力角色使用。若目标角色:未横置,则其横置;已横置,则其摸一张牌。", + lulitongxin_info_versus: + "出牌阶段,对所有己方角色或所有敌方角色使用。若目标角色:未横置,则其横置;已横置,则其摸一张牌。", + lianjunshengyan: "联军盛宴", + lianjunshengyan_info: + "出牌阶段,对你和你选择的除你的势力外的一个势力的所有角色使用。若目标角色:为你,你选择摸Y张牌并回复X-Y点体力(X为该势力的角色数,Y∈[0,X]);不为你,其摸一张牌,然后重置。", + lianjunshengyan_info_boss: + "出牌阶段,对场上所有角色使用。你摸X张牌(X为存活角色数),其他角色依次选择回复1点体力或摸一张牌。", + chiling: "敕令", + chiling_info: + "①出牌阶段,对所有没有势力的角色使用。目标角色选择一项:1、明置一张武将牌,然后摸一张牌;2、弃置一张装备牌;3、失去1点体力。②当【敕令】因判定或弃置而置入弃牌堆时,系统将之移出游戏并将【诏书】置于牌堆底,然后系统于当前回合结束后视为对所有没有势力的角色使用【敕令】。", + diaohulishan: "调虎离山", + diaohulishan_info: "出牌阶段,对至多两名其他角色使用。目标角色于此回合视为移出游戏。", + huoshaolianying: "火烧连营", + huoshaolianying_bg: "烧", + huoshaolianying_info_guozhan: + "出牌阶段,对你的下家及其队列中的所有角色使用。你对目标角色造成1点火属性伤害。", + huoshaolianying_info: + "出牌阶段,对距离最小的一名横置角色使用(若无横置角色,则改为对距离最小的所有角色使用),你对目标造成1点火属性伤害。", + yuanjiao: "远交近攻", + yuanjiao_info: "出牌阶段,对一名与你势力不同的其他角色使用。其摸一张牌,然后你摸三张牌。", + yuanjiao_info_guozhan: + "出牌阶段,对一名与你势力不同且已确定势力的其他角色使用。其摸一张牌,然后你摸三张牌。", + yuanjiao_bg: "交", + zhibi: "知己知彼", + zhibi_info: + "出牌阶段,对一名有手牌或有暗置武将牌的其他角色使用。你选择一项:⒈观看其手牌。⒉观看其的一张暗置武将牌。", + yiyi: "以逸待劳", + yiyi_info_guozhan: "出牌阶段,对所有己方角色使用。目标角色摸两张牌,然后弃置两张牌。", + yiyi_info_combat: "出牌阶段,对所有己方角色使用。目标角色摸两张牌,然后弃置两张牌。", + yiyi_info: "出牌阶段,对至多三名角色使用。目标角色摸两张牌,然后弃置两张牌。", + yiyi_bg: "逸", + wuliu: "吴六剑", + wuliu_info: "锁定技。与你势力相同的所有其他角色的攻击范围+1。", + sanjian: "三尖两刃刀", + sanjian_info: + "当你因执行【杀】而对A造成伤害后,你可以弃置一张牌并选择一名其他角色B(A至B的距离需为1)。你对B造成1点伤害。", + wuliu_skill: "吴六剑", + sanjian_skill: "三尖两刃刀", + jingfanma_bg: "-马", + jingfanma: "惊帆", + jingfanma_info: "锁定技,你计算与其他角色的距离-1。", + huxinjing_bg: "镜", + huxinjing: "护心镜", + huxinjing_info: + "此牌可对其他角色使用。当你受到伤害时,若伤害值大于1或大于等于你的体力值,则你可以将所有【护心镜】置入弃牌堆,然后防止此伤害。", + huxinjing_info_guozhan: + "当你受到伤害时,若伤害值大于等于你的体力值,则你可以将所有【护心镜】置入弃牌堆,然后防止此伤害。", + gz_haolingtianxia: "号令天下", + gz_haolingtianxia_info: + "出牌阶段,对一名体力值不为全场最少的角色使用。所有其他角色依次可以选择一项:①弃置一张牌(魏势力角色无需弃牌),视为对目标角色使用一张【杀】;②弃置目标角色的一张牌(魏势力角色改为获得其一张牌)。", + gz_kefuzhongyuan: "克复中原", + gz_kefuzhongyuan_info: + "出牌阶段,对任意名角色使用。目标角色选择一项:①视为使用一张【杀】(蜀势力角色以此法使用【杀】的伤害值基数+1);②摸一张牌(蜀势力角色改为摸两张牌)。", + gz_guguoanbang: "固国安邦", + gz_guguoanbang_info: + "出牌阶段,对你自己使用。你摸八张牌,然后弃置至少六张手牌。然后若你的势力为吴,则你可以将你以此法弃置的牌交给其他吴势力角色(每名角色至多获得两张牌)。", + gz_wenheluanwu: "文和乱武", + gz_wenheluanwu_info: + "出牌阶段,对所有角色使用。目标角色展示所有手牌,然后你选择一项:①令其弃置两张类型不同的手牌;②你弃置其一张手牌。然后若其为群势力角色且其没有手牌,则其将手牌摸至当前体力值(至多为5)。", + zhaoshu: "诏书", + zhaoshu_skill: "锦囊召唤", + zhaoshu_global: "诏书", + zhaoshu_info: + "
  • 出牌阶段,对你自己使用。你将此牌置于目标的武将牌上。
  • 与你势力相同的角色的出牌阶段限一次,其可以将一张手牌(小势力角色改为至多两张)置于【诏书】上,称为“应”。
  • 出牌阶段限一次,若你的“应”中包含至少四种花色,则你可以发动“锦囊召唤”:将所有“应”置入弃牌堆,然后随机获得一张未加入游戏的势力锦囊牌。", }, - list:[ - ['heart',9,'yuanjiao'], - ['club',3,'zhibi'], - ['club',4,'zhibi'], - ['diamond',4,'yiyi'], - ['heart',11,'yiyi'], - ['diamond',6,'wuliu'], - ['diamond',12,'sanjian'], - ['heart',3,'jingfanma'], - ["spade",4,'shunshou'], - ["spade",12,'guohe'], - ["spade",11,'wuxie'], - ['spade',3,'huoshaolianying','fire'], - ['club',11,'huoshaolianying','fire'], - ['heart',12,'huoshaolianying','fire'], - ['club',2,'huxinjing'], - ['heart',2,'diaohulishan'], - ['diamond',10,'diaohulishan'], - ['heart',1,'lianjunshengyan'], - ['club',3,'chiling'], - ['spade',12,'lulitongxin'], - ['club',10,'lulitongxin'], - ['club',12,'shuiyanqijunx'], - ['heart',13,'shuiyanqijunx'], - ['spade',1,'xietianzi'], - ['diamond',1,'xietianzi'], - ['diamond',4,'xietianzi'], - ['club',1,'yuxi'], + list: [ + ["heart", 9, "yuanjiao"], + ["club", 3, "zhibi"], + ["club", 4, "zhibi"], + ["diamond", 4, "yiyi"], + ["heart", 11, "yiyi"], + ["diamond", 6, "wuliu"], + ["diamond", 12, "sanjian"], + ["heart", 3, "jingfanma"], + ["spade", 4, "shunshou"], + ["spade", 12, "guohe"], + ["spade", 11, "wuxie"], + ["spade", 3, "huoshaolianying", "fire"], + ["club", 11, "huoshaolianying", "fire"], + ["heart", 12, "huoshaolianying", "fire"], + ["club", 2, "huxinjing"], + ["heart", 2, "diaohulishan"], + ["diamond", 10, "diaohulishan"], + ["heart", 1, "lianjunshengyan"], + ["club", 3, "chiling"], + ["spade", 12, "lulitongxin"], + ["club", 10, "lulitongxin"], + ["club", 12, "shuiyanqijunx"], + ["heart", 13, "shuiyanqijunx"], + ["spade", 1, "xietianzi"], + ["diamond", 1, "xietianzi"], + ["diamond", 4, "xietianzi"], + ["club", 1, "yuxi"], ], - } + }; }); diff --git a/card/gwent.js b/card/gwent.js index 560b18cb5..92d7ac812 100644 --- a/card/gwent.js +++ b/card/gwent.js @@ -1,787 +1,825 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'gwent', - card:{ - gw_dieyi:{ - fullskin:true + name: "gwent", + card: { + gw_dieyi: { + fullskin: true, }, - gw_dieyi_equip1:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - type:'equip', - subtype:'equip1', - onLose:function(){ + gw_dieyi_equip1: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + type: "equip", + subtype: "equip1", + onLose: function () { lib.skill.gw_dieyi.process(player); }, - loseDelay:false, - skills:[], - ai:{ - equipValue:0 - } + loseDelay: false, + skills: [], + ai: { + equipValue: 0, + }, }, - gw_dieyi_equip2:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - type:'equip', - subtype:'equip2', - onLose:function(){ + gw_dieyi_equip2: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + type: "equip", + subtype: "equip2", + onLose: function () { lib.skill.gw_dieyi.process(player); }, - loseDelay:false, - skills:[], - ai:{ - equipValue:0 - } + loseDelay: false, + skills: [], + ai: { + equipValue: 0, + }, }, - gw_dieyi_equip3:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - type:'equip', - subtype:'equip3', - onLose:function(){ + gw_dieyi_equip3: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + type: "equip", + subtype: "equip3", + onLose: function () { lib.skill.gw_dieyi.process(player); }, - loseDelay:false, - skills:[], - ai:{ - equipValue:0 - } + loseDelay: false, + skills: [], + ai: { + equipValue: 0, + }, }, - gw_dieyi_equip4:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - type:'equip', - subtype:'equip4', - onLose:function(){ + gw_dieyi_equip4: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + type: "equip", + subtype: "equip4", + onLose: function () { lib.skill.gw_dieyi.process(player); }, - loseDelay:false, - skills:[], - ai:{ - equipValue:0 - } + loseDelay: false, + skills: [], + ai: { + equipValue: 0, + }, }, - gw_dieyi_equip5:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - type:'equip', - subtype:'equip5', - onLose:function(){ + gw_dieyi_equip5: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + type: "equip", + subtype: "equip5", + onLose: function () { lib.skill.gw_dieyi.process(player); }, - loseDelay:false, - skills:[], - ai:{ - equipValue:0 - } + loseDelay: false, + skills: [], + ai: { + equipValue: 0, + }, }, - gw_dieyi_judge:{ - fullskin:true, - vanish:true, - hidden:true, - cardimage:'gw_dieyi', - enable:true, - type:'delay', - filterTarget:true, - effect:function(){ + gw_dieyi_judge: { + fullskin: true, + vanish: true, + hidden: true, + cardimage: "gw_dieyi", + enable: true, + type: "delay", + filterTarget: true, + effect: function () { lib.skill.gw_dieyi.process(player); }, }, - gw_hudiewu:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:function(card,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('ej'); + gw_hudiewu: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: function (card, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("ej"); }); }, - notarget:true, - contentBefore:function(){ - player.$skill('蝴蝶舞','legend','metal'); + notarget: true, + contentBefore: function () { + player.$skill("蝴蝶舞", "legend", "metal"); game.delay(2); }, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current.countCards('ej'); - }).sortBySeat(); + content: function () { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return current.countCards("ej"); + }) + .sortBySeat(); event.targets.remove(player); - 'step 1' - if(event.targets.length){ - var target=event.targets.shift(); - var ej=target.getCards('ej'); + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + var ej = target.getCards("ej"); player.line(target); target.removeEquipTrigger(); - for(var i=0;imax2){ - return get.damageEffect(get.max(enemies,func,'item'),player,player,'fire'); - } - else{ + var max2 = get.max(players, func); + if (max1 - 1 > max2) { + return get.damageEffect( + get.max(enemies, func, "item"), + player, + player, + "fire" + ); + } else { var num; - if(max1>max2){ - num=get.sgn(get.damageEffect(get.max(enemies,func,'item'),player,player,'fire')); + if (max1 > max2) { + num = get.sgn( + get.damageEffect( + get.max(enemies, func, "item"), + player, + player, + "fire" + ) + ); + } else if (max1 == max2) { + num = 0; + } else { + num = 1; } - else if(max1==max2){ - num=0; - } - else{ - num=1; - } - return num+game.countPlayer(function(current){ - if(current.hp>=max2){ - return get.sgn(get.damageEffect(current,player,player,'fire')); - } - }); + return ( + num + + game.countPlayer(function (current) { + if (current.hp >= max2) { + return get.sgn(get.damageEffect(current, player, player, "fire")); + } + }) + ); } - } + }, }, - order:0.7, - } + order: 0.7, + }, }, - gw_leizhoushu:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:true, - notarget:true, - contentBefore:function(){ - player.$skill('雷咒术','legend','metal'); + gw_leizhoushu: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: true, + notarget: true, + contentBefore: function () { + player.$skill("雷咒术", "legend", "metal"); game.delay(2); }, - content:function(){ - if(player.hasSkill('gw_leizhoushu')){ - if(typeof player.storage.gw_leizhoushu!='number'){ - player.storage.gw_leizhoushu=2; - } - else{ + content: function () { + if (player.hasSkill("gw_leizhoushu")) { + if (typeof player.storage.gw_leizhoushu != "number") { + player.storage.gw_leizhoushu = 2; + } else { player.storage.gw_leizhoushu++; } - player.syncStorage('gw_leizhoushu'); + player.syncStorage("gw_leizhoushu"); player.updateMarks(); - } - else{ - player.addSkill('gw_leizhoushu'); + } else { + player.addSkill("gw_leizhoushu"); } }, - contentAfter:function(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter: function () { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:8, - useful:[6,1], - result:{ - player:function(player){ - return 1+game.countPlayer(function(current){ - if(current!=player&¤t.isMaxHandcard()){ - return -get.sgn(get.attitude(player,current)); - } - }); - } + ai: { + value: 8, + useful: [6, 1], + result: { + player: function (player) { + return ( + 1 + + game.countPlayer(function (current) { + if (current != player && current.isMaxHandcard()) { + return -get.sgn(get.attitude(player, current)); + } + }) + ); + }, }, - order:0.5, - } - }, - gw_aerdeyin:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:function(card,player){ - var enemies=player.getEnemies(); - return enemies.length>0; + order: 0.5, }, - notarget:true, - contentBefore:function(){ - player.$skill('阿尔德印','legend','metal'); + }, + gw_aerdeyin: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: function (card, player) { + var enemies = player.getEnemies(); + return enemies.length > 0; + }, + notarget: true, + contentBefore: function () { + player.$skill("阿尔德印", "legend", "metal"); game.delay(2); }, - content:function(){ - 'step 0' - var enemies=player.getEnemies(); - event.list=[enemies.randomGet()]; - 'step 1' - if(event.list.length){ - var target=event.list.shift(); - event.target=target; - player.line(target,'green'); + content: function () { + "step 0"; + var enemies = player.getEnemies(); + event.list = [enemies.randomGet()]; + "step 1"; + if (event.list.length) { + var target = event.list.shift(); + event.target = target; + player.line(target, "green"); target.damage(); - } - else{ + } else { delete event.target; } - 'step 2' - if(event.target){ - if(!event.target.isTurnedOver()){ + "step 2"; + if (event.target) { + if (!event.target.isTurnedOver()) { event.target.turnOver(); - event.target.addSkill('gw_aerdeyin'); + event.target.addSkill("gw_aerdeyin"); } event.goto(1); } - 'step 3' + "step 3"; game.delay(); }, - contentAfter:function(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter: function () { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:8, - useful:[6,1], - result:{ - player:function(player){ - return game.countPlayer(function(current){ - if(get.distance(player,current,'pure')==1){ - var att=get.sgn(get.attitude(player,current)); - if(current==player.next){ - return -att*1.5; + ai: { + value: 8, + useful: [6, 1], + result: { + player: function (player) { + return game.countPlayer(function (current) { + if (get.distance(player, current, "pure") == 1) { + var att = get.sgn(get.attitude(player, current)); + if (current == player.next) { + return -att * 1.5; } return -att; } }); - } + }, }, - order:0.5, - } + order: 0.5, + }, }, - gw_ansha:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:function(card,player){ - var enemies=player.getEnemies(); - return game.hasPlayer(function(current){ - return current.hp==1&&enemies.includes(current); + gw_ansha: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: function (card, player) { + var enemies = player.getEnemies(); + return game.hasPlayer(function (current) { + return current.hp == 1 && enemies.includes(current); }); }, - notarget:true, - contentBefore:function(){ - player.$skill('暗杀','legend','metal'); + notarget: true, + contentBefore: function () { + player.$skill("暗杀", "legend", "metal"); game.delay(2); }, - content:function(){ - var enemies=player.getEnemies(); - var list=game.filterPlayer(function(current){ - return current.hp==1&&enemies.includes(current); + content: function () { + var enemies = player.getEnemies(); + var list = game.filterPlayer(function (current) { + return current.hp == 1 && enemies.includes(current); }); - if(list.length){ - var target=list.randomGet(); + if (list.length) { + var target = list.randomGet(); player.line(target); target.die(); } }, - contentAfter:function(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter: function () { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:8, - useful:[6,1], - result:{ - player:1 + ai: { + value: 8, + useful: [6, 1], + result: { + player: 1, }, - order:0.6, - } + order: 0.6, + }, }, - gw_xinsheng:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:function(card,player){ - return game.hasPlayer(function(current){ + gw_xinsheng: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: function (card, player) { + return game.hasPlayer(function (current) { return !current.isUnseen(); }); }, - notarget:true, - contentBefore:function(){ - player.$skill('新生','legend','metal'); + notarget: true, + contentBefore: function () { + player.$skill("新生", "legend", "metal"); game.delay(2); }, - content:function(){ - 'step 0' - var target=get.max(game.filterPlayer(function(current){ - return !current.isUnseen(); - },'list').randomSort(),function(current){ - var att=get.attitude(player,current); - if(att<0&¤t.isDamaged()&¤t.hp<=3){ - return -10; - } - var rank=get.rank(current,true); - if(current.maxHp>=3){ - if(current.hp<=1){ - if(att>0) return att*3+2; - return att*3; + content: function () { + "step 0"; + var target = get.max( + game + .filterPlayer(function (current) { + return !current.isUnseen(); + }, "list") + .randomSort(), + function (current) { + var att = get.attitude(player, current); + if (att < 0 && current.isDamaged() && current.hp <= 3) { + return -10; } - else if(current.hp==2){ - if(att>0){ - att*=1.5; - } - else{ - att/=1.5; + var rank = get.rank(current, true); + if (current.maxHp >= 3) { + if (current.hp <= 1) { + if (att > 0) return att * 3 + 2; + return att * 3; + } else if (current.hp == 2) { + if (att > 0) { + att *= 1.5; + } else { + att /= 1.5; + } } } - } - if(rank>=7){ - if(att>0){ - return att/10; + if (rank >= 7) { + if (att > 0) { + return att / 10; + } + return -att / 5; + } else if (rank <= 4) { + if (att < 0) { + return -att / 10; + } + return att; } - return -att/5; - } - else if(rank<=4){ - if(att<0){ - return -att/10; - } - return att; - } - return Math.abs(att/2); - },'item'); - event.aitarget=target; - var list=[]; - for(var i in lib.character){ - if(!lib.filter.characterDisabled(i)&&!lib.filter.characterDisabled2(i)){ + return Math.abs(att / 2); + }, + "item" + ); + event.aitarget = target; + var list = []; + for (var i in lib.character) { + if (!lib.filter.characterDisabled(i) && !lib.filter.characterDisabled2(i)) { list.push(i); } } - var players=game.players.concat(game.dead); - for(var i=0;i0){ - return get.rank(button.link,true); - } - else{ - return -get.rank(button.link,true); + var dialog = ui.create.dialog("选择一张武将牌", "hidden"); + dialog.add([list.randomGets(12), "character"]); + player.chooseButton(dialog, true).ai = function (button) { + if (get.attitude(player, event.aitarget) > 0) { + return get.rank(button.link, true); + } else { + return -get.rank(button.link, true); } }; - 'step 1' - event.nametarget=result.links[0]; - player.chooseTarget(true,'使用'+get.translation(event.nametarget)+'替换一名角色的武将牌',function(card,player,target){ - return !target.isUnseen()&&!target.isMin(); - }).ai=function(target){ - if(target==event.aitarget){ - return 1; + "step 1"; + event.nametarget = result.links[0]; + player.chooseTarget( + true, + "使用" + get.translation(event.nametarget) + "替换一名角色的武将牌", + function (card, player, target) { + return !target.isUnseen() && !target.isMin(); } - else{ + ).ai = function (target) { + if (target == event.aitarget) { + return 1; + } else { return 0; } - } - 'step 2' - var target=result.targets[0]; - var hp=target.hp; - target.reinit(target.name,event.nametarget); - target.hp=Math.min(hp+1,target.maxHp); + }; + "step 2"; + var target = result.targets[0]; + var hp = target.hp; + target.reinit(target.name, event.nametarget); + target.hp = Math.min(hp + 1, target.maxHp); target.update(); - player.line(target,'green'); - 'step 3' + player.line(target, "green"); + "step 3"; game.triggerEnter(target); }, - contentAfter:function(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter: function () { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:8, - useful:[6,1], - result:{ - player:1 + ai: { + value: 8, + useful: [6, 1], + result: { + player: 1, }, - order:0.5, - } + order: 0.5, + }, }, - gw_niuquzhijing:{ - fullborder:'gold', - type:'spell', - subtype:'spell_gold', - vanish:true, - enable:function(card,player){ - return game.hasPlayer(function(current){ - return current.hp!=player.hp; + gw_niuquzhijing: { + fullborder: "gold", + type: "spell", + subtype: "spell_gold", + vanish: true, + enable: function (card, player) { + return game.hasPlayer(function (current) { + return current.hp != player.hp; }); }, - notarget:true, - contentBefore:function(){ - var list1=game.filterPlayer(function(current){ + notarget: true, + contentBefore: function () { + var list1 = game.filterPlayer(function (current) { return current.isMaxHp(); }); - var list2=game.filterPlayer(function(current){ + var list2 = game.filterPlayer(function (current) { return current.isMinHp(); }); player.line(list1); - for(var i=0;ilist11.length){ + setTimeout(function () { + var list11 = list1.slice(0); + var list22 = list2.slice(0); + while (list22.length > list11.length) { list11.push(list1.randomGet()); } - while(list22.length0; + order: 0.2, }, - content:function(){ - 'step 0' - var cards=target.getCards('h'); - target.lose(cards,ui.special); - target.storage.gw_youer=cards; - target.addSkill('gw_youer'); - 'step 1' + }, + gw_youer: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + enable: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; + }, + content: function () { + "step 0"; + var cards = target.getCards("h"); + target.lose(cards, ui.special); + target.storage.gw_youer = cards; + target.addSkill("gw_youer"); + "step 1"; player.draw(); }, - ai:{ - basic:{ - order:10, - value:7, - useful:[3,1], + ai: { + basic: { + order: 10, + value: 7, + useful: [3, 1], }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noh')) return 3; - var num=-Math.sqrt(target.countCards('h')); - if(player.hasSha()&&player.canUse('sha',target)){ - num-=2; + result: { + target: function (player, target) { + if (target.hasSkillTag("noh")) return 3; + var num = -Math.sqrt(target.countCards("h")); + if (player.hasSha() && player.canUse("sha", target)) { + num -= 2; } return num; }, }, - } - }, - gw_tongdi:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - vanish:true, - enable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'h',true,'visible').set('ai',function(button){ + }, + gw_tongdi: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + enable: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); + }, + content: function () { + "step 0"; + player.gainPlayerCard(target, "h", true, "visible").set("ai", function (button) { return get.value(button.link); }); - 'step 1' - target.gain(game.createCard('sha'),'gain2'); + "step 1"; + target.gain(game.createCard("sha"), "gain2"); }, - ai:{ - basic:{ - order:8, - value:9.5, - useful:[5,1], + ai: { + basic: { + order: 8, + value: 9.5, + useful: [5, 1], }, - result:{ - target:function(player,target){ - if(target.getEquip(4)) return -2; + result: { + target: function (player, target) { + if (target.getEquip(4)) return -2; return -1; - } + }, }, - } + }, }, - gw_fuyuan:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - vanish:true, - savable:true, - selectTarget:-1, - content:function(){ + gw_fuyuan: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + savable: true, + selectTarget: -1, + content: function () { target.recover(); target.draw(); }, - ai:{ - basic:{ - order:6, - useful:10, - value:[8,6.5,5,4], + ai: { + basic: { + order: 6, + useful: 10, + value: [8, 6.5, 5, 4], }, - result:{ - target:2 + result: { + target: 2, }, - tag:{ - recover:1, - save:1, - } - } + tag: { + recover: 1, + save: 1, + }, + }, }, - gw_zhuoshao:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - vanish:true, - enable:true, - filterTarget:function(card,player,target){ + gw_zhuoshao: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + enable: true, + filterTarget: function (card, player, target) { return target.isMaxHp(); }, - cardnature:'fire', - selectTarget:[1,Infinity], - content:function(){ - target.damage('fire'); + cardnature: "fire", + selectTarget: [1, Infinity], + content: function () { + target.damage("fire"); }, - ai:{ - basic:{ - order:8.5, - value:7.5, - useful:[4,1], + ai: { + basic: { + order: 8.5, + value: 7.5, + useful: [4, 1], }, - result:{ - target:-1 + result: { + target: -1, }, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - } - } + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + }, + }, }, - gw_butianshu:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - vanish:true, - enable:true, - filterTarget:true, + gw_butianshu: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + enable: true, + filterTarget: true, // contentBefore:function(){ // player.$skill('卜天术','legend','water'); // game.delay(2); // }, - content:function(){ - 'step 0' - var list=[]; - for(var i in lib.card){ - if(lib.card[i].mode&&lib.card[i].mode.includes(lib.config.mode)==false) continue; - if(lib.card[i].vanish) continue; - if(lib.card[i].type=='delay') list.push([cards[0].suit,cards[0].number,i]); + content: function () { + "step 0"; + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; + if (lib.card[i].vanish) continue; + if (lib.card[i].type == "delay") list.push([cards[0].suit, cards[0].number, i]); } - var dialog=ui.create.dialog('卜天术',[list,'vcard']); - var bing=target.countCards('h')<=1; - player.chooseButton(dialog,true,function(button){ - if(get.effect(target,{name:button.link[2]},player,player)>0){ - if(button.link[2]=='bingliang'){ - if(bing) return 2; + var dialog = ui.create.dialog("卜天术", [list, "vcard"]); + var bing = target.countCards("h") <= 1; + player.chooseButton(dialog, true, function (button) { + if (get.effect(target, { name: button.link[2] }, player, player) > 0) { + if (button.link[2] == "bingliang") { + if (bing) return 2; return 0.7; } - if(button.link[2]=='lebu'){ + if (button.link[2] == "lebu") { return 1; } - if(button.link[2]=='guiyoujie'){ + if (button.link[2] == "guiyoujie") { return 0.5; } - if(button.link[2]=='caomu'){ + if (button.link[2] == "caomu") { return 0.3; } return 0.2; } return 0; - }).filterButton=function(button){ + }).filterButton = function (button) { return !target.hasJudge(button.link[2]); }; - 'step 1' - var card=game.createCard(result.links[0][2]); - event.judgecard=card; + "step 1"; + var card = game.createCard(result.links[0][2]); + event.judgecard = card; target.$draw(card); game.delay(0.7); - 'step 2' + "step 2"; target.addJudge(event.judgecard); }, - ai:{ - value:8, - useful:[5,1], - result:{ - player:function(player,target){ - var eff=0; - for(var i in lib.card){ - if(lib.card[i].type=='delay'){ - var current=get.effect(target,{name:i},player,player); - if(current>eff){ - eff=current; + ai: { + value: 8, + useful: [5, 1], + result: { + player: function (player, target) { + var eff = 0; + for (var i in lib.card) { + if (lib.card[i].type == "delay") { + var current = get.effect(target, { name: i }, player, player); + if (current > eff) { + eff = current; } } } return eff; - } + }, }, - order:6, - } - }, - gw_shizizhaohuan:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - vanish:true, - enable:true, - filterTarget:function(card,player,target){ - return target==player; + order: 6, }, - selectTarget:-1, + }, + gw_shizizhaohuan: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + vanish: true, + enable: true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, // contentBefore:function(){ // player.$skill('十字召唤','legend','water'); // game.delay(2); // }, - content:function(){ - var list=[]; - list.push(get.cardPile2('juedou')); - list.push(get.cardPile2('huogong')); - list.push(get.cardPile2('nanman')); - list.push(get.cardPile2('huoshaolianying')); - for(var i=0;i0; + var dialog = ui.create.dialog("自然馈赠", [list, "vcard"]); + var rand = get.rand(); + var aozu = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + current.hp <= 3 && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var aozu2=game.hasPlayer(function(current){ - return player.canUse('gw_aozuzhilei',current)&¤t.hp<=2&&get.effect(current,{name:'gw_aozuzhilei'},player,player)>0; + var aozu2 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + current.hp <= 2 && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var aozu3=game.hasPlayer(function(current){ - return player.canUse('gw_aozuzhilei',current)&&get.effect(current,{name:'gw_aozuzhilei'},player,player)>0; + var aozu3 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var baoxue=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&&[2,3].includes(current.countCards('h'))&&!current.hasSkillTag('noh'); + var baoxue = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + [2, 3].includes(current.countCards("h")) && + !current.hasSkillTag("noh") + ); }); - var baoxue2=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&&[2].includes(current.countCards('h'))&&!current.hasSkillTag('noh'); + var baoxue2 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + [2].includes(current.countCards("h")) && + !current.hasSkillTag("noh") + ); }); - var baoxue3=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&¤t.countCards('h')>=2&&!current.hasSkillTag('noh'); + var baoxue3 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + current.countCards("h") >= 2 && + !current.hasSkillTag("noh") + ); }); - var nongwu=game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&(get.attitude(player,current.getNext())<0||get.attitude(player,current.getPrevious())<0); + var nongwu = game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + (get.attitude(player, current.getNext()) < 0 || + get.attitude(player, current.getPrevious()) < 0) + ); }); - var nongwu2=game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&get.attitude(player,current.getNext())<0&&get.attitude(player,current.getPrevious())<0; + var nongwu2 = game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + get.attitude(player, current.getNext()) < 0 && + get.attitude(player, current.getPrevious()) < 0 + ); }); - var yanzi=game.hasPlayer(function(current){ - return get.attitude(player,current)>0&¤t.isMinHandcard(); + var yanzi = game.hasPlayer(function (current) { + return get.attitude(player, current) > 0 && current.isMinHandcard(); }); - player.chooseButton(dialog,true,function(button){ - var name=button.link[2]; - switch(name){ - case 'gw_ciguhanshuang': - if(nongwu2) return 3; - if(nongwu) return 1; + player.chooseButton(dialog, true, function (button) { + var name = button.link[2]; + switch (name) { + case "gw_ciguhanshuang": + if (nongwu2) return 3; + if (nongwu) return 1; return 0; - case 'gw_baoxueyaoshui': - if(baoxue2) return 2; - if(baoxue) return 1.5; - if(baoxue3) return 0.5; + case "gw_baoxueyaoshui": + if (baoxue2) return 2; + if (baoxue) return 1.5; + if (baoxue3) return 0.5; return 0; - case 'gw_aozuzhilei': - if(aozu2) return 2.5; - if(aozu) return 1.2; - if(aozu3) return 0.2; + case "gw_aozuzhilei": + if (aozu2) return 2.5; + if (aozu) return 1.2; + if (aozu3) return 0.2; return 0; - case 'gw_yanziyaoshui': - if(yanzi) return 2; + case "gw_yanziyaoshui": + if (yanzi) return 2; return 0.6; } - if(game.hasPlayer(function(current){ - return player.canUse(name,current)&&get.effect(current,{name:name},player,player)>0; - })){ + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(name, current) && + get.effect(current, { name: name }, player, player) > 0 + ); + }) + ) { return Math.random(); } return 0; - }).filterButton=function(button){ - var name=button.link[2]; - if(!lib.card[name].notarget){ - return game.hasPlayer(function(current){ - return player.canUse(name,current); - }) + }).filterButton = function (button) { + var name = button.link[2]; + if (!lib.card[name].notarget) { + return game.hasPlayer(function (current) { + return player.canUse(name, current); + }); } return true; }; - 'step 1' - player.chooseUseTarget(true,game.createCard(result.links[0][2],get.suit(card),get.number(card))); + "step 1"; + player.chooseUseTarget( + true, + game.createCard(result.links[0][2], get.suit(card), get.number(card)) + ); }, - ai:{ - value:7, - useful:[4,1], - result:{ - player:function(player){ + ai: { + value: 7, + useful: [4, 1], + result: { + player: function (player) { return 1; - } + }, }, - order:7, - } + order: 7, + }, }, - gw_nuhaifengbao:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_nuhaifengbao'); + gw_nuhaifengbao: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_nuhaifengbao"); }, - content:function(){ - target.addSkill('gw_nuhaifengbao'); + content: function () { + target.addSkill("gw_nuhaifengbao"); }, - ai:{ - value:[7,1], - useful:[4,1], - result:{ - target:function(player,target){ - return -2/Math.sqrt(1+target.hp); - } + ai: { + value: [7, 1], + useful: [4, 1], + result: { + target: function (player, target) { + return -2 / Math.sqrt(1 + target.hp); + }, }, - order:1.2, - } + order: 1.2, + }, }, - gw_baishuang:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_ciguhanshuang'); + gw_baishuang: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_ciguhanshuang"); }, - selectTarget:[1,3], - content:function(){ - target.addSkill('gw_ciguhanshuang'); + selectTarget: [1, 3], + content: function () { + target.addSkill("gw_ciguhanshuang"); }, - ai:{ - value:[7.5,1], - useful:[5,1], - result:{ - target:-1 + ai: { + value: [7.5, 1], + useful: [5, 1], + result: { + target: -1, }, - order:1.2, - } + order: 1.2, + }, }, - gw_baobaoshu:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_baobaoshu'); + gw_baobaoshu: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_baobaoshu"); }, - selectTarget:[1,2], - content:function(){ - target.addTempSkill('gw_baobaoshu',{player:'phaseAfter'}); + selectTarget: [1, 2], + content: function () { + target.addTempSkill("gw_baobaoshu", { player: "phaseAfter" }); }, - ai:{ - value:[7.5,1], - useful:[5,1], - result:{ - target:function(player,target){ - return -Math.sqrt(target.countCards('h'))-0.5; - } + ai: { + value: [7.5, 1], + useful: [5, 1], + result: { + target: function (player, target) { + return -Math.sqrt(target.countCards("h")) - 0.5; + }, }, - order:1.2, - } - }, - gw_guaiwuchaoxue:{ - fullborder:'silver', - type:'spell', - subtype:'spell_silver', - enable:true, - usable:1, - updateUsable:'phaseUse', - forceUsable:true, - filterTarget:function(card,player,target){ - return target==player; + order: 1.2, }, - selectTarget:-1, - content:function(){ - var list=get.gainableSkills(function(info,skill){ - return !info.notemp&&info.ai&&info.ai.maixie_hp&&!player.hasSkill(skill); + }, + gw_guaiwuchaoxue: { + fullborder: "silver", + type: "spell", + subtype: "spell_silver", + enable: true, + usable: 1, + updateUsable: "phaseUse", + forceUsable: true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + content: function () { + var list = get.gainableSkills(function (info, skill) { + return !info.notemp && info.ai && info.ai.maixie_hp && !player.hasSkill(skill); }); - list.remove('guixin'); - if(list.length){ - var skill=list.randomGet(); + list.remove("guixin"); + if (list.length) { + var skill = list.randomGet(); player.popup(skill); - player.addTempSkill(skill,{player:'phaseBegin'}); - var enemies=player.getEnemies(); - if(enemies.length){ - var source=enemies.randomGet(); + player.addTempSkill(skill, { player: "phaseBegin" }); + var enemies = player.getEnemies(); + if (enemies.length) { + var source = enemies.randomGet(); source.line(player); source.addExpose(0.1); player.damage(source); @@ -1363,966 +1443,1004 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } } }, - ai:{ - value:[8,1], - useful:[3,1], - result:{ - target:function(player,target){ - if(target.hp<=1||target.hujia) return 0; + ai: { + value: [8, 1], + useful: [3, 1], + result: { + target: function (player, target) { + if (target.hp <= 1 || target.hujia) return 0; return 1; - } + }, }, - order:1, - } + order: 1, + }, }, - gw_qinpendayu:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_qinpendayu'); + gw_qinpendayu: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_qinpendayu"); }, - changeTarget:function(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1; - },targets); + changeTarget: function (player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1; + }, targets); }, - content:function(){ - target.addSkill('gw_qinpendayu'); + content: function () { + target.addSkill("gw_qinpendayu"); }, - ai:{ - value:[5,1], - useful:[3,1], - result:{ - target:function(player,current){ - if(current.hasSkill('gw_qinpendayu')) return 0; - return Math.max(-1,-0.1-0.3*current.needsToDiscard(2)); - } + ai: { + value: [5, 1], + useful: [3, 1], + result: { + target: function (player, current) { + if (current.hasSkill("gw_qinpendayu")) return 0; + return Math.max(-1, -0.1 - 0.3 * current.needsToDiscard(2)); + }, }, - order:1.2, - } + order: 1.2, + }, }, - gw_birinongwu:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_birinongwu'); + gw_birinongwu: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_birinongwu"); }, - changeTarget:function(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1; - },targets); + changeTarget: function (player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1; + }, targets); }, - content:function(){ - target.addSkill('gw_birinongwu'); + content: function () { + target.addSkill("gw_birinongwu"); }, - ai:{ - value:[5,1], - useful:[3,1], - result:{ - player:function(player,current){ - if(current.hasSkill('gw_birinongwu')) return 0; + ai: { + value: [5, 1], + useful: [3, 1], + result: { + player: function (player, current) { + if (current.hasSkill("gw_birinongwu")) return 0; return -1; - } + }, }, - order:1.2, - } + order: 1.2, + }, }, - gw_ciguhanshuang:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - filterTarget:function(card,player,target){ - return !target.hasSkill('gw_ciguhanshuang'); + gw_ciguhanshuang: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + filterTarget: function (card, player, target) { + return !target.hasSkill("gw_ciguhanshuang"); }, - changeTarget:function(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1; - },targets); + changeTarget: function (player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1; + }, targets); }, - content:function(){ - target.addSkill('gw_ciguhanshuang'); + content: function () { + target.addSkill("gw_ciguhanshuang"); }, - ai:{ - value:[5,1], - useful:[3,1], - result:{ - target:function(player,target){ - if(target.hasSkill('gw_ciguhanshuang')) return 0; + ai: { + value: [5, 1], + useful: [3, 1], + result: { + target: function (player, target) { + if (target.hasSkill("gw_ciguhanshuang")) return 0; return -1; - } + }, }, - order:1.2, - } + order: 1.2, + }, }, - gw_baoxueyaoshui:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - filterTarget:true, - content:function(){ - 'step 0' - target.chooseToDiscard('h',2,true).delay=false; - 'step 1' + gw_baoxueyaoshui: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + filterTarget: true, + content: function () { + "step 0"; + target.chooseToDiscard("h", 2, true).delay = false; + "step 1"; target.draw(); }, - ai:{ - value:6, - useful:[3,1], - result:{ - target:function(player,target){ - if(target.hasSkillTag('noh')) return 0.1; - switch(target.countCards('h')){ - case 0:return 0.5; - case 1:return 0; - case 2:return -1.5; - default:return -1; + ai: { + value: 6, + useful: [3, 1], + result: { + target: function (player, target) { + if (target.hasSkillTag("noh")) return 0.1; + switch (target.countCards("h")) { + case 0: + return 0.5; + case 1: + return 0; + case 2: + return -1.5; + default: + return -1; } - } + }, }, - order:8, - tag:{ - loseCard:1, - discard:1, - } - } + order: 8, + tag: { + loseCard: 1, + discard: 1, + }, + }, }, - gw_zhihuanjun:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - filterTarget:function(card,player,target){ + gw_zhihuanjun: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + filterTarget: function (card, player, target) { return target.isDamaged(); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.loseMaxHp(true); - 'step 1' - if(target.isDamaged()&&target.countCards('h')=player.hp; + order: 9.5, }, - content:function(){ - 'step 0' - target.damage('thunder'); - 'step 1' - if(target.isIn()){ + }, + gw_aozuzhilei: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + cardnature: "thunder", + filterTarget: function (card, player, target) { + return target.hp >= player.hp; + }, + content: function () { + "step 0"; + target.damage("thunder"); + "step 1"; + if (target.isIn()) { target.draw(); } }, - ai:{ - basic:{ - order:1.8, - value:[5,1], - useful:[4,1], + ai: { + basic: { + order: 1.8, + value: [5, 1], + useful: [4, 1], }, - result:{ - target:-1 + result: { + target: -1, }, - tag:{ - damage:1, - thunderDamage:1, - natureDamage:1, - } - } + tag: { + damage: 1, + thunderDamage: 1, + natureDamage: 1, + }, + }, }, - gw_poxiao:{ - fullborder:'bronze', - type:'spell', - subtype:'spell_bronze', - enable:true, - notarget:true, - content:function(){ - 'step 0' - var choice=1; - if(game.countPlayer(function(current){ - if(current.countCards('j')||current.hasSkillTag('weather')){ - if(get.attitude(player,current)>0){ - choice=0; + gw_poxiao: { + fullborder: "bronze", + type: "spell", + subtype: "spell_bronze", + enable: true, + notarget: true, + content: function () { + "step 0"; + var choice = 1; + if ( + game.countPlayer(function (current) { + if (current.countCards("j") || current.hasSkillTag("weather")) { + if (get.attitude(player, current) > 0) { + choice = 0; + } + return true; } - return true; - } - })){ - player.chooseControl(function(){ - return choice; - }).set('choiceList',[ - '解除任意名角色的天气效果并移除其判定区内的牌', - '随机获得一张铜卡法术(破晓除外)并展示之' - ]); + }) + ) { + player + .chooseControl(function () { + return choice; + }) + .set("choiceList", [ + "解除任意名角色的天气效果并移除其判定区内的牌", + "随机获得一张铜卡法术(破晓除外)并展示之", + ]); + } else { + event.directfalse = true; } - else{ - event.directfalse=true; - } - 'step 1' - if(!event.directfalse&&result.index==0){ - player.chooseTarget(true,[1,Infinity],'解除任意名角色的天气效果并移除其判定区内的牌',function(card,player,target){ - return target.countCards('j')||target.hasSkillTag('weather'); - }).ai=function(target){ - return get.attitude(player,target); + "step 1"; + if (!event.directfalse && result.index == 0) { + player.chooseTarget( + true, + [1, Infinity], + "解除任意名角色的天气效果并移除其判定区内的牌", + function (card, player, target) { + return target.countCards("j") || target.hasSkillTag("weather"); + } + ).ai = function (target) { + return get.attitude(player, target); }; - } - else{ - var list=get.libCard(function(info,name){ - return name!='gw_poxiao'&&info.subtype=='spell_bronze'; + } else { + var list = get.libCard(function (info, name) { + return name != "gw_poxiao" && info.subtype == "spell_bronze"; }); - if(list.length){ - player.gain(game.createCard(list.randomGet()),'gain2'); - } - else{ + if (list.length) { + player.gain(game.createCard(list.randomGet()), "gain2"); + } else { player.draw(); } event.finish(); } - 'step 2' - event.list=result.targets.slice(0).sortBySeat(); - 'step 3' - if(event.list.length){ - var target=event.list.shift(); - player.line(target,'green'); - var cards=target.getCards('j'); - if(cards.length){ + "step 2"; + event.list = result.targets.slice(0).sortBySeat(); + "step 3"; + if (event.list.length) { + var target = event.list.shift(); + player.line(target, "green"); + var cards = target.getCards("j"); + if (cards.length) { target.discard(cards); } - if(target.hasSkillTag('weather')){ - var skills=target.getSkills(); - for(var i=0;i0){ + if (player.storage.gw_kunenfayin > 0) { player.updateMarks(); - } - else{ - player.removeSkill('gw_kunenfayin'); + } else { + player.removeSkill("gw_kunenfayin"); } }, - } + }, }, - group:'gw_kunenfayin_count', - onremove:true + group: "gw_kunenfayin_count", + onremove: true, }, - gw_baobaoshu:{ - mark:true, - nopop:true, - intro:{ - content:'每使用一张基本牌或锦囊牌,需弃置一张牌' + gw_baobaoshu: { + mark: true, + nopop: true, + intro: { + content: "每使用一张基本牌或锦囊牌,需弃置一张牌", }, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - var type=get.type(event.card,'trick'); - return type=='basic'||type=='trick'; + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + var type = get.type(event.card, "trick"); + return type == "basic" || type == "trick"; }, - content:function(){ - if(!event.isMine()) game.delay(0.5); - player.chooseToDiscard(true,'he'); + content: function () { + if (!event.isMine()) game.delay(0.5); + player.chooseToDiscard(true, "he"); + }, + ai: { + weather: true, + effect: { + player: function (card, player) { + if (!player.needsToDiscard()) return "zeroplayertarget"; + }, + }, }, - ai:{ - weather:true, - effect:{ - player:function(card,player){ - if(!player.needsToDiscard()) return 'zeroplayertarget'; - } - } - } }, - gw_nuhaifengbao:{ - mark:true, - intro:{ - content:'结束阶段随机弃置一张牌(剩余#回合)' + gw_nuhaifengbao: { + mark: true, + intro: { + content: "结束阶段随机弃置一张牌(剩余#回合)", }, - init:function(player){ - player.storage.gw_nuhaifengbao=2; + init: function (player) { + player.storage.gw_nuhaifengbao = 2; }, - trigger:{player:'phaseEnd'}, - forced:true, - nopop:true, - content:function(){ + trigger: { player: "phaseEnd" }, + forced: true, + nopop: true, + content: function () { player.randomDiscard(); player.storage.gw_nuhaifengbao--; - if(player.storage.gw_nuhaifengbao>0){ + if (player.storage.gw_nuhaifengbao > 0) { player.updateMarks(); - } - else{ - player.removeSkill('gw_nuhaifengbao'); + } else { + player.removeSkill("gw_nuhaifengbao"); } }, - onremove:true, - ai:{ - neg:true, - weather:true - } + onremove: true, + ai: { + neg: true, + weather: true, + }, }, - gw_youer:{ - trigger:{global:'phaseEnd',player:'dieBegin'}, - forced:true, - audio:false, - mark:true, - intro:{ - content:'cards' + gw_youer: { + trigger: { global: "phaseEnd", player: "dieBegin" }, + forced: true, + audio: false, + mark: true, + intro: { + content: "cards", }, - content:function(){ - if(player.storage.gw_youer){ - if(trigger.name=='phase'){ + content: function () { + if (player.storage.gw_youer) { + if (trigger.name == "phase") { player.gain(player.storage.gw_youer); - } - else{ - player.$throw(player.storage.gw_youer,1000); - for(var i=0;i0; + filter: function (event) { + return event.num > 0; }, - content:function(){ + content: function () { trigger.num--; - player.removeSkill('gw_ciguhanshuang'); + player.removeSkill("gw_ciguhanshuang"); + }, + ai: { + weather: true, }, - ai:{ - weather:true - } }, - gw_dieyi:{ - init:function(player){ - player.storage.gw_dieyi=1; + gw_dieyi: { + init: function (player) { + player.storage.gw_dieyi = 1; }, - onremove:true, - trigger:{global:'phaseEnd'}, - forced:true, - mark:true, - nopop:true, - process:function(player){ - if(player.hasSkill('gw_dieyi')){ + onremove: true, + trigger: { global: "phaseEnd" }, + forced: true, + mark: true, + nopop: true, + process: function (player) { + if (player.hasSkill("gw_dieyi")) { player.storage.gw_dieyi++; + } else { + player.addSkill("gw_dieyi"); } - else{ - player.addSkill('gw_dieyi'); - } - player.syncStorage('gw_dieyi'); + player.syncStorage("gw_dieyi"); player.updateMarks(); }, - intro:{ - content:'在当前回合的结束阶段,你随机弃置#张牌' + intro: { + content: "在当前回合的结束阶段,你随机弃置#张牌", }, - content:function(){ + content: function () { player.randomDiscard(player.storage.gw_dieyi); - player.removeSkill('gw_dieyi'); - } - }, - gw_leizhoushu:{ - mark:true, - intro:{ - content:function(storage,player){ - if(storage>=2){ - return '锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标(重复'+storage+'次)'; - } - else{ - return '锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标'; - } - } + player.removeSkill("gw_dieyi"); }, - nopop:true, - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event,player){ - var list=game.filterPlayer(); - for(var i=0;i= 2) { + return ( + "锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标(重复" + + storage + + "次)" + ); + } else { + return "锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标"; + } + }, + }, + nopop: true, + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + var list = game.filterPlayer(); + for (var i = 0; i < list.length; i++) { + if (list[i] != player && list[i].isMaxHandcard()) return true; } return false; }, - content:function(){ - 'step 0' - if(typeof player.storage.gw_leizhoushu=='number'){ - event.num=player.storage.gw_leizhoushu; + content: function () { + "step 0"; + if (typeof player.storage.gw_leizhoushu == "number") { + event.num = player.storage.gw_leizhoushu; + } else { + event.num = 1; } - else{ - event.num=1; - } - 'step 1' - if(event.num){ - var max=0; - var maxp=null; - var list=game.filterPlayer(function(current){ - return current.isMaxHandcard(); - }).sortBySeat(); - var enemies=player.getEnemies(); - for(var i=0;i0&&event.parent.name=='phaseDraw'; }, - content:function(){ - if(!player.storage.spell_gain||Math.max.apply(null,player.storage.spell_gain)<0){ - var tmp=player.storage.spell_gain2; - player.storage.spell_gain=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].randomGets(3); - player.storage.spell_gain2=Math.floor((15-Math.max.apply(null,player.storage.spell_gain))/2); - if(tmp){ - for(var i=0;i<3;i++){ - player.storage.spell_gain[i]+=tmp; + }, + _gainspell: { + trigger: { player: "drawBegin" }, + silent: true, + priority: -11, + filter: function (event, player) { + if (_status.connectMode) return false; + if (!lib.config.cards.includes("gwent")) return false; + if (player.isMin()) return false; + if (game.fixedPile) return false; + return event.num > 0 && event.parent.name == "phaseDraw"; + }, + content: function () { + if (!player.storage.spell_gain || Math.max.apply(null, player.storage.spell_gain) < 0) { + var tmp = player.storage.spell_gain2; + player.storage.spell_gain = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + ].randomGets(3); + player.storage.spell_gain2 = Math.floor( + (15 - Math.max.apply(null, player.storage.spell_gain)) / 2 + ); + if (tmp) { + for (var i = 0; i < 3; i++) { + player.storage.spell_gain[i] += tmp; } } } - for(var i=0;i<3;i++){ - if(player.storage.spell_gain[i]==0){ + for (var i = 0; i < 3; i++) { + if (player.storage.spell_gain[i] == 0) { var list; - if(i==0){ - list=get.libCard(function(info){ - return info.subtype=='spell_gold'; + if (i == 0) { + list = get.libCard(function (info) { + return info.subtype == "spell_gold"; }); - if(get.mode()=='stone'){ - list.remove('gw_aerdeyin'); - list.remove('gw_niuquzhijing'); + if (get.mode() == "stone") { + list.remove("gw_aerdeyin"); + list.remove("gw_niuquzhijing"); + } + } else { + list = get.libCard(function (info) { + return info.subtype == "spell_silver"; + }); + if (get.mode() == "stone") { + list.remove("gw_butianshu"); } } - else{ - list=get.libCard(function(info){ - return info.subtype=='spell_silver'; - }); - if(get.mode()=='stone'){ - list.remove('gw_butianshu'); - } - } - if(list&&list.length){ - ui.cardPile.insertBefore(game.createCard(list.randomGet()),ui.cardPile.firstChild); + if (list && list.length) { + ui.cardPile.insertBefore( + game.createCard(list.randomGet()), + ui.cardPile.firstChild + ); } } player.storage.spell_gain[i]--; } - } - } + }, + }, }, - help:{ - '昆特牌':'
    • 法术为分金、银、铜三类,金卡和银卡不出现在牌堆中
    • '+ - '摸牌阶段有一定概率摸到银卡,在16个摸牌阶段中至少会摸到2张银卡
    • '+ - '摸牌阶段有一定概率摸到金卡,在16个摸牌阶段中至少会摸到1张金卡
    • '+ - '金卡无视调虎离山、潜行等免疫目标的效果
    • '+ - '进行洗牌时金卡、银卡将从弃牌堆中消失,不进入牌堆' + help: { + 昆特牌: + "
      • 法术为分金、银、铜三类,金卡和银卡不出现在牌堆中
      • " + + "摸牌阶段有一定概率摸到银卡,在16个摸牌阶段中至少会摸到2张银卡
      • " + + "摸牌阶段有一定概率摸到金卡,在16个摸牌阶段中至少会摸到1张金卡
      • " + + "金卡无视调虎离山、潜行等免疫目标的效果
      • " + + "进行洗牌时金卡、银卡将从弃牌堆中消失,不进入牌堆", }, - translate:{ - spell:'法术', - spell_gold:'金卡法术', - spell_silver:'银卡法术', - spell_bronze:'铜卡法术', + translate: { + spell: "法术", + spell_gold: "金卡法术", + spell_silver: "银卡法术", + spell_bronze: "铜卡法术", - gw_youlanzhimeng:'幽蓝之梦', - gw_guaiwuchaoxue:'怪物巢穴', - gw_guaiwuchaoxue_info:'出牌阶段限用一次,随机获得一个卖血技能直到下一回合开始;令一名随机敌方角色对你造成1点伤害,然后你回复1点体力。', - gw_baobaoshu:'雹暴术', - gw_baobaoshu_info:'天气牌,出牌阶段对至多两名角色使用,目标每使用一张基本牌或锦囊牌,需弃置一张牌,直到下一回合结束。', - gw_baishuang:'白霜', - gw_baishuang_info:'天气牌,出牌阶段对至多三名角色使用,目标下个摸牌阶段摸牌数-1。', - gw_nuhaifengbao:'怒海风暴', - gw_nuhaifengbao_bg:'海', - gw_nuhaifengbao_info:'天气牌,出牌阶段对一名角色使用,目标在结束阶段随机弃置一张牌,持续2回合。', - gw_ganhan:'干旱', - gw_ganhan_info:'所有角色减少1点体力上限(不触发技能),然后结束出牌阶段。', - gw_huangjiashenpan:'皇家审判', - gw_huangjiashenpan_info:'获得任意一张金卡法术(皇家审判除外),然后结束出牌阶段。', - gw_chongci:'冲刺', - gw_chongci_info:'弃置所有牌并随机获得一张非金法术牌,每弃置一张手牌,便随机获得一张类别相同的牌;每弃置一张装备区内的牌,随机装备一件类别相同的装备;获得潜行直到下一回合开始,然后结束出牌阶段。', - gw_tunshi:'吞噬', - gw_tunshi_info:'随机移除一名敌方角色的一个随机技能,你获得此技能并减少1点体力和体力上限,被移除技能的角色增加1点体力和体力上限,然后结束出牌阶段。', - gw_dieyi:'蝶翼', - gw_dieyi_equip1:'蝶翼·器', - gw_dieyi_equip2:'蝶翼·衣', - gw_dieyi_equip3:'蝶翼·攻', - gw_dieyi_equip4:'蝶翼·防', - gw_dieyi_equip5:'蝶翼·宝', - gw_dieyi_judge:'蝶翼·判', - gw_dieyi_equip1_info:'在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_dieyi_equip2_info:'在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_dieyi_equip3_info:'在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_dieyi_equip4_info:'在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_dieyi_equip5_info:'在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_dieyi_judge_info:'你在判定阶段移去此牌,并获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。', - gw_hudiewu:'蝴蝶舞', - gw_hudiewu_info:'将其他角色在场上的所有牌替换为蝶翼(每当你失去一张蝶翼,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌),然后结束出牌阶段。', - gw_yigeniyin:'伊格尼印', - gw_yigeniyin_info:'对敌方角色中体力值最高的一名随机角色造成1点火焰伤害,然后对场上体力值最高的所有角色各造成1点火焰伤害,然后结束出牌阶段。', - gw_leizhoushu:'雷咒术', - gw_leizhoushu_info:'获得技能雷咒术(在每个准备阶段令全场牌数最多的所有其他角色各随机弃置一张牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标,结算X次,X为本局获得此技能的次数),然后结束出牌阶段。', - gw_aerdeyin:'阿尔德印', - gw_aerdeyin_bg:'印', - gw_aerdeyin_info:'对一名随机敌方角色造成1点伤害,若目标武将牌正面朝上,则将其翻面;新的一轮开始时,若目标武将牌正面朝上,则在当前回合结束后进行一个额外回合,否则将武将牌翻回正面。', - gw_xinsheng:'新生', - gw_xinsheng_info:'选择一名角色,随机观看12张武将牌,选择一张替代其武将牌,并令其增加1点体力,然后结束出牌阶段。', - gw_zhongmozhizhan:'终末之战', - gw_zhongmozhizhan_info:'将所有角色区域内的所有牌置入弃牌堆(不触发技能),然后结束出牌阶段。', - gw_butianshu:'卜天术', - gw_butianshu_info:'出牌阶段对任意角色使用,将任意一张延时锦囊牌置入其判定区。', - gw_zhihuanjun:'致幻菌', - gw_zhihuanjun_info:'出牌阶段对一名已受伤角色使用,令其减少1点体力上限;若该角色仍处于受伤状态且手牌数小于体力上限,则重复此结算。', - gw_niuquzhijing:'纽曲之镜', - gw_niuquzhijing_info:'令全场体力最多的角色减少1点体力和体力上限,体力最少的角色增加1点体力和体力上限(不触发技能),然后结束出牌阶段。', - gw_ansha:'暗杀', - gw_ansha_info:'令一名体力为1的随机敌方角立即死亡,然后结束出牌阶段。', - gw_shizizhaohuan:'十字召唤', - gw_shizizhaohuan_info:'从牌堆中获得一张杀以及决斗、火攻、火烧连营、南蛮入侵四张牌中的随机一张。', - gw_zuihouyuanwang:'最后愿望', - gw_zuihouyuanwang_info:'摸X张牌并弃置X张牌,X为存活角色数。', - gw_zirankuizeng:'自然馈赠', - gw_zirankuizeng_info:'选择任意一张铜卡法术使用。', - gw_poxiao:'破晓', - gw_poxiao_info:'选择一项:解除任意名角色的天气效果并移除其判定区内的牌,或随机获得一张铜卡法术(破晓除外)并展示之。', - gw_zumoshoukao:'阻魔手铐', - gw_zumoshoukao_info:'令一名角色非锁定技失效直到下一回合结束。', - gw_aozuzhilei:'奥祖之雷', - gw_aozuzhilei_info:'对一名体力值不小于你的角色造成1点雷属性伤害,然后该角色摸一张牌。', - gw_zhuoshao:'灼烧', - gw_zhuoshao_info:'对任意名体力值为全场最高的角色使用,造成1点火属性伤害。', - gw_fuyuan:'复原', - gw_fuyuan_info:'对一名濒死状态角色使用,目标回复1点体力并摸一张牌。', - gw_youer:'诱饵', - gw_youer_bg:'饵', - gw_youer_info:'将一名其他角色的所有手牌移出游戏,然后摸一张牌,当前回合结束后该角色将以此法失去的牌收回手牌。', - gw_tongdi:'通敌', - gw_tongdi_info:'观看一名其他角色的手牌并获得其中一张,然后令目标获得一张杀。', - gw_baoxueyaoshui:'暴雪药水', - gw_baoxueyaoshui_info:'令一名角色弃置两张手牌并摸一张牌。', - gw_birinongwu:'蔽日浓雾', - gw_birinongwu_bg:'雾', - gw_birinongwu_info:'天气牌,出牌阶段对一名角色及其相邻角色使用,目标不能使用杀直到下一个出牌阶段结束。', - gw_qinpendayu:'倾盆大雨', - gw_qinpendayu_bg:'雨', - gw_qinpendayu_info:'天气牌,出牌阶段对一名角色及其相邻角色使用,目标手牌上限-1直到下一个弃牌阶段结束。', - gw_ciguhanshuang:'刺骨寒霜', - gw_ciguhanshuang_bg:'霜', - gw_ciguhanshuang_info:'天气牌,出牌阶段对一名角色及其相邻角色使用,目标下个摸牌阶段摸牌数-1。', - gw_wenyi:'瘟疫', - gw_wenyi_info:'令所有体力值为全场最少的角色随机弃置一张手牌;若没有手牌,改为失去1点体力。', - gw_yanziyaoshui:'燕子药水', - gw_yanziyaoshui_info:'令一名角色摸一张牌,若其手牌数为全场最少或之一,改为摸两张。', - gw_shanbengshu:'山崩术', - gw_shanbengshu_info:'出牌阶段对自己使用,随机弃置两件敌方角色场上的装备。', - gw_kunenfayin:'昆恩法印', - gw_kunenfayin_info:'出牌阶段对一名角色使用,目标防止所有非属性伤害,持续X个角色的回合(X为存活角色数且最多为5)。', + gw_youlanzhimeng: "幽蓝之梦", + gw_guaiwuchaoxue: "怪物巢穴", + gw_guaiwuchaoxue_info: + "出牌阶段限用一次,随机获得一个卖血技能直到下一回合开始;令一名随机敌方角色对你造成1点伤害,然后你回复1点体力。", + gw_baobaoshu: "雹暴术", + gw_baobaoshu_info: + "天气牌,出牌阶段对至多两名角色使用,目标每使用一张基本牌或锦囊牌,需弃置一张牌,直到下一回合结束。", + gw_baishuang: "白霜", + gw_baishuang_info: "天气牌,出牌阶段对至多三名角色使用,目标下个摸牌阶段摸牌数-1。", + gw_nuhaifengbao: "怒海风暴", + gw_nuhaifengbao_bg: "海", + gw_nuhaifengbao_info: "天气牌,出牌阶段对一名角色使用,目标在结束阶段随机弃置一张牌,持续2回合。", + gw_ganhan: "干旱", + gw_ganhan_info: "所有角色减少1点体力上限(不触发技能),然后结束出牌阶段。", + gw_huangjiashenpan: "皇家审判", + gw_huangjiashenpan_info: "获得任意一张金卡法术(皇家审判除外),然后结束出牌阶段。", + gw_chongci: "冲刺", + gw_chongci_info: + "弃置所有牌并随机获得一张非金法术牌,每弃置一张手牌,便随机获得一张类别相同的牌;每弃置一张装备区内的牌,随机装备一件类别相同的装备;获得潜行直到下一回合开始,然后结束出牌阶段。", + gw_tunshi: "吞噬", + gw_tunshi_info: + "随机移除一名敌方角色的一个随机技能,你获得此技能并减少1点体力和体力上限,被移除技能的角色增加1点体力和体力上限,然后结束出牌阶段。", + gw_dieyi: "蝶翼", + gw_dieyi_equip1: "蝶翼·器", + gw_dieyi_equip2: "蝶翼·衣", + gw_dieyi_equip3: "蝶翼·攻", + gw_dieyi_equip4: "蝶翼·防", + gw_dieyi_equip5: "蝶翼·宝", + gw_dieyi_judge: "蝶翼·判", + gw_dieyi_equip1_info: + "在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_dieyi_equip2_info: + "在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_dieyi_equip3_info: + "在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_dieyi_equip4_info: + "在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_dieyi_equip5_info: + "在你从装备区中失去此牌后,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_dieyi_judge_info: + "你在判定阶段移去此牌,并获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌。", + gw_hudiewu: "蝴蝶舞", + gw_hudiewu_info: + "将其他角色在场上的所有牌替换为蝶翼(每当你失去一张蝶翼,你获得一枚“蝶翼”标记;在任意角色的结束阶段,你移去所有“蝶翼”标记,并随机弃置等量的牌),然后结束出牌阶段。", + gw_yigeniyin: "伊格尼印", + gw_yigeniyin_info: + "对敌方角色中体力值最高的一名随机角色造成1点火焰伤害,然后对场上体力值最高的所有角色各造成1点火焰伤害,然后结束出牌阶段。", + gw_leizhoushu: "雷咒术", + gw_leizhoushu_info: + "获得技能雷咒术(在每个准备阶段令全场牌数最多的所有其他角色各随机弃置一张牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标,结算X次,X为本局获得此技能的次数),然后结束出牌阶段。", + gw_aerdeyin: "阿尔德印", + gw_aerdeyin_bg: "印", + gw_aerdeyin_info: + "对一名随机敌方角色造成1点伤害,若目标武将牌正面朝上,则将其翻面;新的一轮开始时,若目标武将牌正面朝上,则在当前回合结束后进行一个额外回合,否则将武将牌翻回正面。", + gw_xinsheng: "新生", + gw_xinsheng_info: + "选择一名角色,随机观看12张武将牌,选择一张替代其武将牌,并令其增加1点体力,然后结束出牌阶段。", + gw_zhongmozhizhan: "终末之战", + gw_zhongmozhizhan_info: "将所有角色区域内的所有牌置入弃牌堆(不触发技能),然后结束出牌阶段。", + gw_butianshu: "卜天术", + gw_butianshu_info: "出牌阶段对任意角色使用,将任意一张延时锦囊牌置入其判定区。", + gw_zhihuanjun: "致幻菌", + gw_zhihuanjun_info: + "出牌阶段对一名已受伤角色使用,令其减少1点体力上限;若该角色仍处于受伤状态且手牌数小于体力上限,则重复此结算。", + gw_niuquzhijing: "纽曲之镜", + gw_niuquzhijing_info: + "令全场体力最多的角色减少1点体力和体力上限,体力最少的角色增加1点体力和体力上限(不触发技能),然后结束出牌阶段。", + gw_ansha: "暗杀", + gw_ansha_info: "令一名体力为1的随机敌方角立即死亡,然后结束出牌阶段。", + gw_shizizhaohuan: "十字召唤", + gw_shizizhaohuan_info: "从牌堆中获得一张杀以及决斗、火攻、火烧连营、南蛮入侵四张牌中的随机一张。", + gw_zuihouyuanwang: "最后愿望", + gw_zuihouyuanwang_info: "摸X张牌并弃置X张牌,X为存活角色数。", + gw_zirankuizeng: "自然馈赠", + gw_zirankuizeng_info: "选择任意一张铜卡法术使用。", + gw_poxiao: "破晓", + gw_poxiao_info: + "选择一项:解除任意名角色的天气效果并移除其判定区内的牌,或随机获得一张铜卡法术(破晓除外)并展示之。", + gw_zumoshoukao: "阻魔手铐", + gw_zumoshoukao_info: "令一名角色非锁定技失效直到下一回合结束。", + gw_aozuzhilei: "奥祖之雷", + gw_aozuzhilei_info: "对一名体力值不小于你的角色造成1点雷属性伤害,然后该角色摸一张牌。", + gw_zhuoshao: "灼烧", + gw_zhuoshao_info: "对任意名体力值为全场最高的角色使用,造成1点火属性伤害。", + gw_fuyuan: "复原", + gw_fuyuan_info: "对一名濒死状态角色使用,目标回复1点体力并摸一张牌。", + gw_youer: "诱饵", + gw_youer_bg: "饵", + gw_youer_info: + "将一名其他角色的所有手牌移出游戏,然后摸一张牌,当前回合结束后该角色将以此法失去的牌收回手牌。", + gw_tongdi: "通敌", + gw_tongdi_info: "观看一名其他角色的手牌并获得其中一张,然后令目标获得一张杀。", + gw_baoxueyaoshui: "暴雪药水", + gw_baoxueyaoshui_info: "令一名角色弃置两张手牌并摸一张牌。", + gw_birinongwu: "蔽日浓雾", + gw_birinongwu_bg: "雾", + gw_birinongwu_info: + "天气牌,出牌阶段对一名角色及其相邻角色使用,目标不能使用杀直到下一个出牌阶段结束。", + gw_qinpendayu: "倾盆大雨", + gw_qinpendayu_bg: "雨", + gw_qinpendayu_info: + "天气牌,出牌阶段对一名角色及其相邻角色使用,目标手牌上限-1直到下一个弃牌阶段结束。", + gw_ciguhanshuang: "刺骨寒霜", + gw_ciguhanshuang_bg: "霜", + gw_ciguhanshuang_info: "天气牌,出牌阶段对一名角色及其相邻角色使用,目标下个摸牌阶段摸牌数-1。", + gw_wenyi: "瘟疫", + gw_wenyi_info: "令所有体力值为全场最少的角色随机弃置一张手牌;若没有手牌,改为失去1点体力。", + gw_yanziyaoshui: "燕子药水", + gw_yanziyaoshui_info: "令一名角色摸一张牌,若其手牌数为全场最少或之一,改为摸两张。", + gw_shanbengshu: "山崩术", + gw_shanbengshu_info: "出牌阶段对自己使用,随机弃置两件敌方角色场上的装备。", + gw_kunenfayin: "昆恩法印", + gw_kunenfayin_info: + "出牌阶段对一名角色使用,目标防止所有非属性伤害,持续X个角色的回合(X为存活角色数且最多为5)。", }, - cardType:{ - spell:0.5, - spell_bronze:0.2, - spell_silver:0.3, - spell_gold:0.4 + cardType: { + spell: 0.5, + spell_bronze: 0.2, + spell_silver: 0.3, + spell_gold: 0.4, }, - list:[ - ['club',3,'gw_zhihuanjun'], - ['spade',2,'gw_zhihuanjun'], + list: [ + ["club", 3, "gw_zhihuanjun"], + ["spade", 2, "gw_zhihuanjun"], - ['heart',7,'gw_poxiao'], - ['diamond',4,'gw_poxiao'], + ["heart", 7, "gw_poxiao"], + ["diamond", 4, "gw_poxiao"], - ['spade',9,'gw_aozuzhilei','thunder'], - ['club',7,'gw_aozuzhilei','thunder'], + ["spade", 9, "gw_aozuzhilei", "thunder"], + ["club", 7, "gw_aozuzhilei", "thunder"], - ['club',1,'gw_zumoshoukao'], - ['spade',1,'gw_zumoshoukao'], + ["club", 1, "gw_zumoshoukao"], + ["spade", 1, "gw_zumoshoukao"], - ['diamond',5,'gw_qinpendayu'], - ['club',7,'gw_qinpendayu'], + ["diamond", 5, "gw_qinpendayu"], + ["club", 7, "gw_qinpendayu"], - ['spade',9,'gw_birinongwu'], - ['heart',13,'gw_birinongwu'], + ["spade", 9, "gw_birinongwu"], + ["heart", 13, "gw_birinongwu"], - ['diamond',11,'gw_ciguhanshuang'], - ['club',7,'gw_ciguhanshuang'], + ["diamond", 11, "gw_ciguhanshuang"], + ["club", 7, "gw_ciguhanshuang"], - ['heart',4,'gw_baoxueyaoshui'], - ['spade',8,'gw_baoxueyaoshui'], + ["heart", 4, "gw_baoxueyaoshui"], + ["spade", 8, "gw_baoxueyaoshui"], - ['spade',8,'gw_shanbengshu'], - ['spade',2,'gw_kunenfayin'], - ['club',3,'gw_wenyi'], - ['heart',8,'gw_yanziyaoshui'], + ["spade", 8, "gw_shanbengshu"], + ["spade", 2, "gw_kunenfayin"], + ["club", 3, "gw_wenyi"], + ["heart", 8, "gw_yanziyaoshui"], ], }; }); diff --git a/card/hearth.js b/card/hearth.js index 1482e6e43..37533bf55 100644 --- a/card/hearth.js +++ b/card/hearth.js @@ -1,741 +1,756 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ - return { - name:'hearth', - card:{ - linghunzhihuo:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - content:function(){ - 'step 0' - target.damage('fire'); - 'step 1' - var hs=player.getCards('h'); - if(hs.length){ - player.discard(hs.randomGet()); - } - }, - ai:{ - basic:{ - order:1.8, - value:[6,1], - useful:[4,1], - }, - result:{ - player:function(player,target){ - if(player==target) return -1; - if(player.countCards('h')>=player.hp) return -0.1; - if(player.countCards('h')>1) return -0.5; - return 0; - }, - target:-1 - }, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - } - } - }, - jihuocard:{ - fullskin:true, - type:'trick', - enable:true, - toself:true, - filterTarget:function(card,player,target){ - return player==target; - }, - selectTarget:-1, - modTarget:true, - content:function(){ - if(_status.currentPhase==target){ - target.addTempSkill('jihuocard2'); - } - target.draw(); - }, - ai:{ - order:10, - result:{ - target:1 - } - } - }, - zhaomingdan:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('hej')>0; - }, - content:function(){ - 'step 0' - if(target.countCards('hej')){ - var next=player.discardPlayerCard('hej',target,true); - next.visible=true; - next.delay=false; - } - else{ - event.goto(2); - } - 'step 1' - if(result.bool){ - game.delay(0.5); - } - 'step 2' - target.draw(false); - target.$draw(); - game.delay(0.5); - 'step 3' - player.draw(); - }, - ai:{ - order:9.5, - value:6, - useful:3, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0){ - var js=target.getCards('j'); - if(js.length){ - var jj=js[0].viewAs?{name:js[0].viewAs}:js[0]; - if(jj.name=='zhaomingdan') return 3; - if(js.length==1&&get.effect(target,jj,target,player)>=0){ - return 0; - } - return 3; - } - } - var es=target.getCards('e'); - var nh=target.countCards('h'); - var noe=(es.length==0||target.hasSkillTag('noe')); - var noe2=(es.length==1&&es[0].name=='baiyin'&&target.hp0; - }, - content:function(){ - "step 0" - if(target.countCards('h')==0){ - event.finish(); - return; - } - var rand=Math.random()<0.5; - target.chooseCard(true).ai=function(card){ - if(rand) return Math.random(); - return get.value(card); - }; - "step 1" - event.dialog=ui.create.dialog(get.translation(target.name)+'展示的手牌',result.cards); - event.card2=result.cards[0]; - event.videoId=lib.status.videoId++; - game.addVideo('cardDialog',null,[get.translation(target.name)+'展示的手牌',get.cardsInfo(result.cards),event.videoId]); - game.log(target,'展示了',event.card2); - player.chooseToDiscard(function(card){ - return get.suit(card)==get.suit(_status.event.parent.card2); - },function(card){ - if(get.damageEffect(target,player,player,'thunder')>0){ - return 6-get.value(card,_status.event.player); - } - return -1; - }).prompt=false; - game.delay(2); - "step 2" - if(result.bool){ - target.damage('thunder'); - } - else{ - target.addTempSkill('huogong2'); - } - game.addVideo('cardDialog',null,event.videoId); - event.dialog.close(); - }, - ai:{ - basic:{ - order:4, - value:[3,1], - useful:1, - }, - wuxie:function(target,card,player,current,state){ - if(get.attitude(current,player)>=0&&state>0) return false; - }, - result:{ - player:function(player){ - var nh=player.countCards('h'); - if(nh<=player.hp&&nh<=4&&_status.event.name=='chooseToUse'){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard(new lib.element.VCard({name:'shandianjian'}))){ - return -10; - } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='shandianjian') return -10; - if(viewAs&&viewAs.name=='shandianjian') return -10; - } - } - return 0; - }, - target:function(player,target){ - if(target.hasSkill('huogong2')||target.countCards('h')==0) return 0; - if(player.countCards('h')<=1) return 0; - if(target==player){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard(new lib.element.VCard({name:'shandianjian'}))){ - return -1.5; - } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='shandianjian') return -1.5; - if(viewAs&&viewAs.name=='shandianjian') return -1.5; - } - return 0; - } - return -1.5; - } - }, - tag:{ - damage:1, - thunderDamage:1, - natureDamage:1, - norepeat:1 - } - } - }, - shihuawuqi:{ - fullskin:true, - type:'basic', - enable:true, - usable:1, - filterTarget:function(card,player,target){ - return player==target; - }, - selectTarget:-1, - content:function(){ - player.addTempSkill('shihuawuqi'); - if(!player.countCards('h','sha')){ - var card=get.cardPile('sha'); - if(card){ - player.gain(card,'gain2'); - } - } - }, - ai:{ - value:4, - useful:2, - order:8, - result:{ - target:function(player,target){ - return target.countCards('h','sha')?0:1; - } - } - } - }, - siwangchanrao:{ - enable:true, - type:'trick', - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h')>0; - }, - selectTarget:1, - content:function(){ - 'step 0' - var hs=target.getCards('h'); - if(hs.length){ - target.discard(hs.randomGet()); - } - 'step 1' - if(!target.countCards('h')){ - player.draw(); - } - }, - ai:{ - order:9, - value:4, - useful:1, - result:{ - target:-1, - player:function(player,target){ - if(target.countCards('h')==1) return 1; - } - } - } - }, - dunpaigedang:{ - fullskin:true, - enable:true, - type:'trick', - toself:true, - filterTarget:function(card,player,target){ - return player==target; - }, - selectTarget:-1, - modTarget:true, - content:function(){ - 'step 0' - target.changeHujia(); - target.draw(); - 'step 1' - if(target.countCards('he')){ - target.chooseToDiscard('he',true); - } - }, - ai:{ - order:8.5, - value:7, - useful:3, - result:{ - target:1 - } - } - }, - chuansongmen:{ - fullskin:true, - type:'trick', - enable:true, - discard:false, - toself:true, - selectTarget:-1, - filterTarget:function(card,player,target){ - return target==player; - }, - modTarget:true, - // usable:3, - // forceUsable:true, - content:function(){ - 'step 0' - var gained=get.cards()[0]; - target.gain(gained,'gain2'); - if(event.getParent(3).name=='phaseUse'&&_status.currentPhase==target&& - lib.filter.filterCard(gained,target,event.getParent(2))){ - var next=target.chooseToUse(); - next.filterCard=function(card){ - return card==gained; - }; - next.prompt='是否使用'+get.translation(gained)+'?'; - if(cards[0]){ - ui.special.appendChild(cards[0]); - } - else{ - event.finish(); - } - } - else{ - // if(cards[0]){ - // cards[0].discard(); - // } - event.finish(); - } - 'step 1' - if(result.bool&&!target.hasSkill('chuansongmen3')){ - if(target.hasSkill('chuansongmen2')){ - target.addTempSkill('chuansongmen3'); - } - else{ - target.addTempSkill('chuansongmen2'); - } - cards[0].fix(); - target.gain(cards,'gain2'); - } - else{ - cards[0].discard(); - } - }, - ai:{ - order:9.5, - value:7, - useful:3, - result:{ - target:1 - }, - tag:{ - norepeat:1 - } - } - }, - tanshezhiren:{ - fullskin:true, - type:'trick', - enable:true, - // recastable:true, - filterTarget:function(card,player,target){ - return target==player; - }, - selectTarget:-1, - modTarget:true, - content:function(){ - 'step 0' - event.current=target; - event.num=game.countPlayer(); - if(event.num%2==0){ - event.num--; - } - 'step 1' - if(event.num){ - var enemies=event.current.getEnemies(); - enemies.remove(player); - for(var i=0;i2) return 1; - return 0; - }, - }, - tag:{ - recover:1 - } - } - }, - shenenshu:{ - fullskin:true, - enable:true, - type:'trick', - selectTarget:-1, - filterTarget:function(card,player,target){ - return target==player; - }, - modTarget:true, - content:function(){ - 'step 0' - var cards=target.getCards('h'); - if(cards.length){ - target.lose(cards)._triggered=null; - } - event.num=1+cards.length; - 'step 1' - var cards=[]; - var list=get.typeCard('basic'); - list.remove('du'); - if(list.length){ - for(var i=0;i=6){ - return 0; - } - } - return 1; - } - } - } - }, - zhiliaobo:{ - fullskin:true, - enable:true, - filterTarget:function(card,player,target){ - return target.hp=0){ - if(target.hasSkillTag('maixie')){ - if(ui.selected.cards.length) return 0; - } - else{ - return 0; - } - } - if(player.hasSkillTag('notricksource')) return 0; - if(target.hasSkillTag('notrick')) return 0; - if(card.name=='tao') return 0; - if(target.hp==1&&card.name=='jiu') return 0; - if(get.type(card)!='basic'){ - return 10-get.value(card); - } - return 8-get.value(card); - }; - "step 1" - if(!result.bool||result.cards.length<2){ - if(result.bool) target.damage(2-result.cards.length,'thunder'); - else target.damage(2,'thunder'); - } - }, - ai:{ - basic:{ - order:7, - useful:[5,1] - }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nothunder')) return 0; - if(player.hasUnknown(2)) return 0; - var nh=target.countCards('he'); - if(target==player) nh--; - if(nh==2) return -2.5; - if(nh==1) return -3; - if(nh==0) return -4; - return -2; - }, - }, - tag:{ - damage:1, - natureDamage:1, - thunderDamage:1, - multitarget:1, - multineg:1, - discard:2, - loseCard:2, - } - } - } - }, - skill:{ - chuansongmen2:{}, - chuansongmen3:{}, - shihuawuqi:{ - mod:{ - attackFrom:function(from,to,distance){ - return distance-1; - } - } - }, - jihuocard2:{ - mod:{ - maxHandcard:function(player,num){ - return num+2; - } - } - } - }, - translate:{ - linghunzhihuo:'灵魂之火', - linghunzhihuo_info:'对一名角色造成1点火焰伤害,然后随机弃置一张手牌。', - shenenshu:'神恩术', - shenenshu_info:'出牌阶段对自己使用,将所有手牌(含此张)替换为基本牌。', - zhiliaobo:'治疗波', - zhiliaobo_info:'出牌阶段对一名受伤角色使用,目标进行一次判定,若结果为红色,则回复1点体力,否则获得1点护甲。', - yuansuhuimie:'元素毁灭', - yuansuhuimie_info:'对所有角色使用,令目标弃置0~2张牌,并受到2-X点雷电伤害,X为其弃置的手牌数。', - xingjiegoutong:'星界沟通', - xingjiegoutong_info:'增加1点体力上限并回复1点体力,弃置你的所有手牌。', - tanshezhiren:'弹射之刃', - tanshezhiren_info:'出牌阶段对自己使用,依次按敌方-友方-敌方-的顺序随机弃置阵营内一名随机角色的一张牌(目标不包含你),共结算X次,X为存活角色数,若X为偶数,改为X-1。', - chuansongmen:'传送门', - chuansongmen_info:'摸一张牌并展示,若发生在出牌阶段,你可以立即使用摸到的牌,若如此做,你将传送门收回手牌(每阶段最多收回2张传送门)。', - dunpaigedang:'盾牌格挡', - dunpaigedang_info:'获得1点护甲值,摸一张牌,然后弃置一张牌。', - siwangchanrao:'死亡缠绕', - siwangchanrao_infox:'弃置一名其他角色的一张手牌,若其此时没有手牌,则你摸一张牌。', - shihuawuqi:'石化武器', - shihuawuqi_infox:'本回合内攻击范围+1;若你手牌中没有杀,则从牌堆中获得一张杀。', - shandianjian:'闪电箭', - shandianjian_info:'目标角色展示一张手牌,然后若你能弃掉一张与所展示牌相同花色的手牌,则对该角色造成1点雷电伤害。', - shijieshu:'视界术', - shijieshu_info:'目标从牌堆或弃牌堆中随机装备两张类别不同的装备牌,然后弃置一张牌。', - zhaomingdan:'照明弹', - zhaomingdan_info:'观看一名其他角色的手牌,并弃置其区域内的一张牌,然后其与你各摸一张牌。', - jihuocard:'激活', - jihuocard_info:'摸一张牌,本回合手牌上限+2。', - }, - list:[ - ['heart',2,'shenenshu'], - ['diamond',12,'shenenshu'], - ['club',7,'zhiliaobo'], - ['spade',1,'zhiliaobo'], - ['spade',13,'yuansuhuimie'], - ['spade',13,'xingjiegoutong'], - ['diamond',2,'tanshezhiren'], - ['diamond',2,'chuansongmen'], - ['heart',2,'chuansongmen'], - ['club',3,'dunpaigedang'], - ['club',3,'shandianjian','thunder'], - ['spade',1,'shandianjian','thunder'], - ['spade',7,'shijieshu'], - ['diamond',5,'zhaomingdan'], - ['heart',10,'zhaomingdan'], - ['diamond',2,'jihuocard'], - ['diamond',1,'linghunzhihuo'], - ], - }; -}); +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { + return { + name: "hearth", + card: { + linghunzhihuo: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + content: function () { + "step 0"; + target.damage("fire"); + "step 1"; + var hs = player.getCards("h"); + if (hs.length) { + player.discard(hs.randomGet()); + } + }, + ai: { + basic: { + order: 1.8, + value: [6, 1], + useful: [4, 1], + }, + result: { + player: function (player, target) { + if (player == target) return -1; + if (player.countCards("h") >= player.hp) return -0.1; + if (player.countCards("h") > 1) return -0.5; + return 0; + }, + target: -1, + }, + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + }, + }, + }, + jihuocard: { + fullskin: true, + type: "trick", + enable: true, + toself: true, + filterTarget: function (card, player, target) { + return player == target; + }, + selectTarget: -1, + modTarget: true, + content: function () { + if (_status.currentPhase == target) { + target.addTempSkill("jihuocard2"); + } + target.draw(); + }, + ai: { + order: 10, + result: { + target: 1, + }, + }, + }, + zhaomingdan: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return player != target && target.countCards("hej") > 0; + }, + content: function () { + "step 0"; + if (target.countCards("hej")) { + var next = player.discardPlayerCard("hej", target, true); + next.visible = true; + next.delay = false; + } else { + event.goto(2); + } + "step 1"; + if (result.bool) { + game.delay(0.5); + } + "step 2"; + target.draw(false); + target.$draw(); + game.delay(0.5); + "step 3"; + player.draw(); + }, + ai: { + order: 9.5, + value: 6, + useful: 3, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) { + var js = target.getCards("j"); + if (js.length) { + var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0]; + if (jj.name == "zhaomingdan") return 3; + if (js.length == 1 && get.effect(target, jj, target, player) >= 0) { + return 0; + } + return 3; + } + } + var es = target.getCards("e"); + var nh = target.countCards("h"); + var noe = es.length == 0 || target.hasSkillTag("noe"); + var noe2 = es.length == 1 && es[0].name == "baiyin" && target.hp < target.maxHp; + var noh = nh == 0 || target.hasSkillTag("noh"); + if (noh && noe) return 0; + if (noh && noe2) return 0.01; + if (get.attitude(player, target) <= 0) + return target.countCards("he") ? -1.5 : 1.5; + return 0.1; + }, + }, + }, + }, + shijieshu: { + fullskin: true, + enable: true, + type: "trick", + filterTarget: function (card, player, target) { + return !target.isMin(); + }, + content: function () { + "step 0"; + var cards = []; + var subtype = null; + for (var i = 0; i < 2; i++) { + var card = get.cardPile(function (card) { + if (get.type(card) == "equip") { + if (subtype) { + if (get.subtype(card) == subtype) { + return false; + } + } else { + subtype = get.subtype(card); + } + return true; + } + return false; + }); + if (card) { + ui.special.appendChild(card); + cards.push(card); + } + } + switch (cards.length) { + case 1: { + target.$gain(cards[0]); + game.delay(); + break; + } + case 2: { + target.$gain(cards[0]); + setTimeout(function () { + target.$gain(cards[1]); + }, 250); + game.delay(); + break; + } + } + event.cards = cards; + "step 1"; + if (event.cards.length) { + target.equip(event.cards.shift()); + game.delay(0.5); + if (event.cards.length) { + event.redo(); + } + } + "step 2"; + game.delay(0.5); + "step 3"; + if (target.countCards("he")) { + target.chooseToDiscard("he", true); + } + }, + ai: { + order: 9, + value: 6, + useful: 2, + result: { + target: function (player, target) { + return Math.max(0, 2 - target.countCards("e")); + }, + }, + tag: { + norepeat: 1, + }, + }, + }, + shandianjian: { + fullskin: true, + type: "trick", + enable: true, + cardnature: "thunder", + filterTarget: function (card, player, target) { + if (player != game.me && player.countCards("h") < 2) return false; + return target.countCards("h") > 0; + }, + content: function () { + "step 0"; + if (target.countCards("h") == 0) { + event.finish(); + return; + } + var rand = Math.random() < 0.5; + target.chooseCard(true).ai = function (card) { + if (rand) return Math.random(); + return get.value(card); + }; + "step 1"; + event.dialog = ui.create.dialog( + get.translation(target.name) + "展示的手牌", + result.cards + ); + event.card2 = result.cards[0]; + event.videoId = lib.status.videoId++; + game.addVideo("cardDialog", null, [ + get.translation(target.name) + "展示的手牌", + get.cardsInfo(result.cards), + event.videoId, + ]); + game.log(target, "展示了", event.card2); + player.chooseToDiscard( + function (card) { + return get.suit(card) == get.suit(_status.event.parent.card2); + }, + function (card) { + if (get.damageEffect(target, player, player, "thunder") > 0) { + return 6 - get.value(card, _status.event.player); + } + return -1; + } + ).prompt = false; + game.delay(2); + "step 2"; + if (result.bool) { + target.damage("thunder"); + } else { + target.addTempSkill("huogong2"); + } + game.addVideo("cardDialog", null, event.videoId); + event.dialog.close(); + }, + ai: { + basic: { + order: 4, + value: [3, 1], + useful: 1, + }, + wuxie: function (target, card, player, current, state) { + if (get.attitude(current, player) >= 0 && state > 0) return false; + }, + result: { + player: function (player) { + var nh = player.countCards("h"); + if (nh <= player.hp && nh <= 4 && _status.event.name == "chooseToUse") { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard(new lib.element.VCard({ name: "shandianjian" })) + ) { + return -10; + } + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "shandianjian") return -10; + if (viewAs && viewAs.name == "shandianjian") return -10; + } + } + return 0; + }, + target: function (player, target) { + if (target.hasSkill("huogong2") || target.countCards("h") == 0) return 0; + if (player.countCards("h") <= 1) return 0; + if (target == player) { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard(new lib.element.VCard({ name: "shandianjian" })) + ) { + return -1.5; + } + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "shandianjian") return -1.5; + if (viewAs && viewAs.name == "shandianjian") return -1.5; + } + return 0; + } + return -1.5; + }, + }, + tag: { + damage: 1, + thunderDamage: 1, + natureDamage: 1, + norepeat: 1, + }, + }, + }, + shihuawuqi: { + fullskin: true, + type: "basic", + enable: true, + usable: 1, + filterTarget: function (card, player, target) { + return player == target; + }, + selectTarget: -1, + content: function () { + player.addTempSkill("shihuawuqi"); + if (!player.countCards("h", "sha")) { + var card = get.cardPile("sha"); + if (card) { + player.gain(card, "gain2"); + } + } + }, + ai: { + value: 4, + useful: 2, + order: 8, + result: { + target: function (player, target) { + return target.countCards("h", "sha") ? 0 : 1; + }, + }, + }, + }, + siwangchanrao: { + enable: true, + type: "trick", + filterTarget: function (card, player, target) { + return player != target && target.countCards("h") > 0; + }, + selectTarget: 1, + content: function () { + "step 0"; + var hs = target.getCards("h"); + if (hs.length) { + target.discard(hs.randomGet()); + } + "step 1"; + if (!target.countCards("h")) { + player.draw(); + } + }, + ai: { + order: 9, + value: 4, + useful: 1, + result: { + target: -1, + player: function (player, target) { + if (target.countCards("h") == 1) return 1; + }, + }, + }, + }, + dunpaigedang: { + fullskin: true, + enable: true, + type: "trick", + toself: true, + filterTarget: function (card, player, target) { + return player == target; + }, + selectTarget: -1, + modTarget: true, + content: function () { + "step 0"; + target.changeHujia(); + target.draw(); + "step 1"; + if (target.countCards("he")) { + target.chooseToDiscard("he", true); + } + }, + ai: { + order: 8.5, + value: 7, + useful: 3, + result: { + target: 1, + }, + }, + }, + chuansongmen: { + fullskin: true, + type: "trick", + enable: true, + discard: false, + toself: true, + selectTarget: -1, + filterTarget: function (card, player, target) { + return target == player; + }, + modTarget: true, + // usable:3, + // forceUsable:true, + content: function () { + "step 0"; + var gained = get.cards()[0]; + target.gain(gained, "gain2"); + if ( + event.getParent(3).name == "phaseUse" && + _status.currentPhase == target && + lib.filter.filterCard(gained, target, event.getParent(2)) + ) { + var next = target.chooseToUse(); + next.filterCard = function (card) { + return card == gained; + }; + next.prompt = "是否使用" + get.translation(gained) + "?"; + if (cards[0]) { + ui.special.appendChild(cards[0]); + } else { + event.finish(); + } + } else { + // if(cards[0]){ + // cards[0].discard(); + // } + event.finish(); + } + "step 1"; + if (result.bool && !target.hasSkill("chuansongmen3")) { + if (target.hasSkill("chuansongmen2")) { + target.addTempSkill("chuansongmen3"); + } else { + target.addTempSkill("chuansongmen2"); + } + cards[0].fix(); + target.gain(cards, "gain2"); + } else { + cards[0].discard(); + } + }, + ai: { + order: 9.5, + value: 7, + useful: 3, + result: { + target: 1, + }, + tag: { + norepeat: 1, + }, + }, + }, + tanshezhiren: { + fullskin: true, + type: "trick", + enable: true, + // recastable:true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + modTarget: true, + content: function () { + "step 0"; + event.current = target; + event.num = game.countPlayer(); + if (event.num % 2 == 0) { + event.num--; + } + "step 1"; + if (event.num) { + var enemies = event.current.getEnemies(); + enemies.remove(player); + for (var i = 0; i < enemies.length; i++) { + if (!enemies[i].countCards("h")) { + enemies.splice(i--, 1); + } + } + if (enemies.length) { + var enemy = enemies.randomGet(); + event.current.line(enemy); + enemy.discard(enemy.getCards("h").randomGet()); + event.current = enemy; + event.num--; + event.redo(); + } + } + }, + ai: { + order: 8.5, + wuxie: function () { + return 0; + }, + result: { + player: 1, + }, + tag: { + multineg: 1, + multitarget: 1, + }, + }, + }, + xingjiegoutong: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + modTarget: true, + toself: true, + filterTarget: function (card, player, target) { + return player == target; + }, + content: function () { + target.gainMaxHp(); + target.recover(); + target.discard(target.getCards("h")); + }, + ai: { + basic: { + useful: [1, 1], + value: [1, 1], + }, + order: 1, + result: { + target: function (player, target) { + if (target.countCards("h", "tao")) return 0; + var nh = target.countCards("h"); + if (nh <= 2) return 1; + if (target.hp == 1 && target.maxHp > 2) return 1; + return 0; + }, + }, + tag: { + recover: 1, + }, + }, + }, + shenenshu: { + fullskin: true, + enable: true, + type: "trick", + selectTarget: -1, + filterTarget: function (card, player, target) { + return target == player; + }, + modTarget: true, + content: function () { + "step 0"; + var cards = target.getCards("h"); + if (cards.length) { + target.lose(cards)._triggered = null; + } + event.num = 1 + cards.length; + "step 1"; + var cards = []; + var list = get.typeCard("basic"); + list.remove("du"); + if (list.length) { + for (var i = 0; i < event.num; i++) { + cards.push(game.createCard(list.randomGet())); + } + target.directgain(cards); + } + }, + ai: { + order: 1, + result: { + target: function (player, target) { + var hs = target.getCards("h"); + for (var i = 0; i < hs.length; i++) { + if (get.type(hs[i]) != "basic" && get.useful(hs[i]) >= 6) { + return 0; + } + } + return 1; + }, + }, + }, + }, + zhiliaobo: { + fullskin: true, + enable: true, + filterTarget: function (card, player, target) { + return target.hp < target.maxHp; + }, + type: "trick", + content: function () { + "step 0"; + target.judge(function (card) { + return get.color(card) == "red" ? 1 : 0; + }); + "step 1"; + if (result.bool) { + target.recover(); + } else { + target.changeHujia(); + } + }, + ai: { + order: 4, + value: [7, 3], + useful: [6, 3], + result: { + target: function (player, target) { + var eff = get.recoverEffect(target, player, target); + if (eff <= 0) return 0; + var num = target.maxHp - target.hp; + if (num < 1) return 0; + if (num == 1) return 1; + if (target.hp == 1) return 2.5; + return 2; + }, + }, + tag: { + recover: 1, + }, + }, + }, + yuansuhuimie: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + filterTarget: true, + reverseOrder: true, + content: function () { + "step 0"; + target.chooseToDiscard([1, 2], "he").ai = function (card) { + if (get.damageEffect(target, player, target, "thunder") >= 0) { + if (target.hasSkillTag("maixie")) { + if (ui.selected.cards.length) return 0; + } else { + return 0; + } + } + if (player.hasSkillTag("notricksource")) return 0; + if (target.hasSkillTag("notrick")) return 0; + if (card.name == "tao") return 0; + if (target.hp == 1 && card.name == "jiu") return 0; + if (get.type(card) != "basic") { + return 10 - get.value(card); + } + return 8 - get.value(card); + }; + "step 1"; + if (!result.bool || result.cards.length < 2) { + if (result.bool) target.damage(2 - result.cards.length, "thunder"); + else target.damage(2, "thunder"); + } + }, + ai: { + basic: { + order: 7, + useful: [5, 1], + }, + result: { + target: function (player, target) { + if (target.hasSkillTag("nothunder")) return 0; + if (player.hasUnknown(2)) return 0; + var nh = target.countCards("he"); + if (target == player) nh--; + if (nh == 2) return -2.5; + if (nh == 1) return -3; + if (nh == 0) return -4; + return -2; + }, + }, + tag: { + damage: 1, + natureDamage: 1, + thunderDamage: 1, + multitarget: 1, + multineg: 1, + discard: 2, + loseCard: 2, + }, + }, + }, + }, + skill: { + chuansongmen2: {}, + chuansongmen3: {}, + shihuawuqi: { + mod: { + attackFrom: function (from, to, distance) { + return distance - 1; + }, + }, + }, + jihuocard2: { + mod: { + maxHandcard: function (player, num) { + return num + 2; + }, + }, + }, + }, + translate: { + linghunzhihuo: "灵魂之火", + linghunzhihuo_info: "对一名角色造成1点火焰伤害,然后随机弃置一张手牌。", + shenenshu: "神恩术", + shenenshu_info: "出牌阶段对自己使用,将所有手牌(含此张)替换为基本牌。", + zhiliaobo: "治疗波", + zhiliaobo_info: + "出牌阶段对一名受伤角色使用,目标进行一次判定,若结果为红色,则回复1点体力,否则获得1点护甲。", + yuansuhuimie: "元素毁灭", + yuansuhuimie_info: "对所有角色使用,令目标弃置0~2张牌,并受到2-X点雷电伤害,X为其弃置的手牌数。", + xingjiegoutong: "星界沟通", + xingjiegoutong_info: "增加1点体力上限并回复1点体力,弃置你的所有手牌。", + tanshezhiren: "弹射之刃", + tanshezhiren_info: + "出牌阶段对自己使用,依次按敌方-友方-敌方-的顺序随机弃置阵营内一名随机角色的一张牌(目标不包含你),共结算X次,X为存活角色数,若X为偶数,改为X-1。", + chuansongmen: "传送门", + chuansongmen_info: + "摸一张牌并展示,若发生在出牌阶段,你可以立即使用摸到的牌,若如此做,你将传送门收回手牌(每阶段最多收回2张传送门)。", + dunpaigedang: "盾牌格挡", + dunpaigedang_info: "获得1点护甲值,摸一张牌,然后弃置一张牌。", + siwangchanrao: "死亡缠绕", + siwangchanrao_infox: "弃置一名其他角色的一张手牌,若其此时没有手牌,则你摸一张牌。", + shihuawuqi: "石化武器", + shihuawuqi_infox: "本回合内攻击范围+1;若你手牌中没有杀,则从牌堆中获得一张杀。", + shandianjian: "闪电箭", + shandianjian_info: + "目标角色展示一张手牌,然后若你能弃掉一张与所展示牌相同花色的手牌,则对该角色造成1点雷电伤害。", + shijieshu: "视界术", + shijieshu_info: "目标从牌堆或弃牌堆中随机装备两张类别不同的装备牌,然后弃置一张牌。", + zhaomingdan: "照明弹", + zhaomingdan_info: "观看一名其他角色的手牌,并弃置其区域内的一张牌,然后其与你各摸一张牌。", + jihuocard: "激活", + jihuocard_info: "摸一张牌,本回合手牌上限+2。", + }, + list: [ + ["heart", 2, "shenenshu"], + ["diamond", 12, "shenenshu"], + ["club", 7, "zhiliaobo"], + ["spade", 1, "zhiliaobo"], + ["spade", 13, "yuansuhuimie"], + ["spade", 13, "xingjiegoutong"], + ["diamond", 2, "tanshezhiren"], + ["diamond", 2, "chuansongmen"], + ["heart", 2, "chuansongmen"], + ["club", 3, "dunpaigedang"], + ["club", 3, "shandianjian", "thunder"], + ["spade", 1, "shandianjian", "thunder"], + ["spade", 7, "shijieshu"], + ["diamond", 5, "zhaomingdan"], + ["heart", 10, "zhaomingdan"], + ["diamond", 2, "jihuocard"], + ["diamond", 1, "linghunzhihuo"], + ], + }; +}); diff --git a/card/huanlekapai.js b/card/huanlekapai.js index 5ace59494..94360748e 100644 --- a/card/huanlekapai.js +++ b/card/huanlekapai.js @@ -1,290 +1,316 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ - return { - name:'huanlekapai', - connect:true, - card:{ - "monkey":{ - audio:true, - fullskin:true, - type:"equip", - subtype:"equip5", - skills:["monkey"], - ai:{ - basic:{ - equipValue:8, +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { + return { + name: "huanlekapai", + connect: true, + card: { + monkey: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["monkey"], + ai: { + basic: { + equipValue: 8, }, }, }, - "mianju":{ - audio:true, - fullskin:true, - type:"equip", - subtype:"equip2", - skills:["mianju"], - ai:{ - order:9.5, - basic:{ - equipValue:function (card,player){ - if(!player.isTurnedOver()) return 6; - if(player.isTurnedOver()) return -10; + mianju: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["mianju"], + ai: { + order: 9.5, + basic: { + equipValue: function (card, player) { + if (!player.isTurnedOver()) return 6; + if (player.isTurnedOver()) return -10; return 0; }, }, }, }, - "shoulijian":{ - audio:true, - type:"basic", - enable:true, - fullskin:true, - outrange:{ - global:2, + shoulijian: { + audio: true, + type: "basic", + enable: true, + fullskin: true, + outrange: { + global: 2, }, - filterTarget:lib.filter.notMe, - content:function (){ - "step 0" - if(!target.countCards('he',{type:'equip'})){ + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + if (!target.countCards("he", { type: "equip" })) { target.damage(); event.finish(); + } else { + target.chooseToDiscard("he", { type: "equip" }, "弃置一张装备牌或受到1点伤害").ai = + function (card) { + var player = _status.event.player; + var source = _status.event.getParent().player; + if (get.damageEffect(player, source, player) > 0) return -1; + return 7 - get.value(card); + }; } - else{ - target.chooseToDiscard('he',{type:'equip'},'弃置一张装备牌或受到1点伤害').ai=function(card){ - var player=_status.event.player; - var source=_status.event.getParent().player; - if(get.damageEffect(player,source,player)>0) return -1; - return 7-get.value(card); - }; - } - "step 1" - if(!result.bool){ + "step 1"; + if (!result.bool) { target.damage(); } }, - ai:{ - basic:{ - order:9, - value:6, - useful:2, + ai: { + basic: { + order: 9, + value: 6, + useful: 2, }, - result:{ - target:-2, + result: { + target: -2, }, - tag:{ - discard:1, - damage:1, + tag: { + discard: 1, + damage: 1, }, }, - selectTarget:1, + selectTarget: 1, }, - "kuwu":{ - audio:true, - fullskin:true, - type:"equip", - subtype:"equip1", - skills:["kuwu"], - nomod:true, - nopower:true, - unique:true, - distance:{ - attackFrom:-1, + kuwu: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + skills: ["kuwu"], + nomod: true, + nopower: true, + unique: true, + distance: { + attackFrom: -1, }, - ai:{ - equipValue:6, + ai: { + equipValue: 6, }, }, - "xuelunyang":{ - audio:true, - fullskin:true, - type:"equip", - subtype:"equip5", - skills:["xuelunyang"], - ai:{ - basic:{ - equipValue:8, + xuelunyang: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["xuelunyang"], + ai: { + basic: { + equipValue: 8, }, }, }, - "jiuwei":{ - audio:true, - fullskin:true, - type:"equip", - subtype:"equip5", - skills:["jiuwei"], - ai:{ - basic:{ - equipValue:8, + jiuwei: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["jiuwei"], + ai: { + basic: { + equipValue: 8, }, }, }, }, - skill:{ - "monkey":{ - trigger:{ - global:"useCardToBegin", + skill: { + monkey: { + trigger: { + global: "useCardToBegin", }, - audio:true, - filter:function (event,player){ - var card=player.getEquip(5); - if(card){ - var name=card.name; - if(name&&name.indexOf('monkey')!=-1&&event.name=='tao'&&event.player!=player&&event.cards.filterInD().length>0) return true; + audio: true, + filter: function (event, player) { + var card = player.getEquip(5); + if (card) { + var name = card.name; + if ( + name && + name.indexOf("monkey") != -1 && + event.name == "tao" && + event.player != player && + event.cards.filterInD().length > 0 + ) + return true; } return false; }, - check:function (event,player){ - return get.attitude(player,event.player)<=0; + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function (){ - "step 0" - player.$fullscreenpop('猴子偷桃','fire'); + content: function () { + "step 0"; + player.$fullscreenpop("猴子偷桃", "fire"); trigger.untrigger(); trigger.finish(); - "step 1" + "step 1"; player.discard(player.getEquip(5)); - "step 2" - player.gain(trigger.cards.filterInD(),'gain2','log'); + "step 2"; + player.gain(trigger.cards.filterInD(), "gain2", "log"); }, }, - "mianju":{ - audio:true, - trigger:{ - player:"turnOverBefore", + mianju: { + audio: true, + trigger: { + player: "turnOverBefore", }, - forced:true, - equipSkill:true, - content:function (){ + forced: true, + equipSkill: true, + content: function () { trigger.cancel(); }, - ai:{ - noturnOver:true, - effect:{ - target:function (card,player,target,current){ - if(get.tag(card,'turnOver')) return [0,0]; + ai: { + noturnOver: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "turnOver")) return [0, 0]; }, }, }, }, - "kuwu":{ - audio:true, - trigger:{ - source:"damageSource", + kuwu: { + audio: true, + trigger: { + source: "damageSource", }, - forced:true, - equipSkill:true, - filter:function (event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.notLink()&&event.player.countCards('he')>0; + forced: true, + equipSkill: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.notLink() && + event.player.countCards("he") > 0 + ); }, - content:function (){ - trigger.player.chooseToDiscard(true,'he'); + content: function () { + trigger.player.chooseToDiscard(true, "he"); }, }, - "xuelunyang":{ - audio:true, - trigger:{ - player:"phaseBegin", + xuelunyang: { + audio: true, + trigger: { + player: "phaseBegin", }, - 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;i锁定技 你的武将牌不能被翻面。", - "shoulijian":"手里剑", - "shoulijian_info":"出牌阶段,对一名距离1以外的角色使用,令其弃置一张装备牌或受到1点伤害。", - "kuwu":"苦无", - "kuwu_info":"锁定技 每当你使用【杀】造成一次伤害,受伤角色须弃置一张牌。", - "xuelunyang":"写轮眼", - "xuelunyang_info":"回合开始阶段,你可以选择一名角色,然后获得其一项技能,直到回合结束。", - "jiuwei":"九尾", - "jiuwei_info":"(收集查克拉)回合结束时,若你已受伤,你可回复1点体力,否则摸一张牌。", + translate: { + monkey: "猴子", + monkey_info: + "猴子偷桃:当场上有其他角色使用【桃】时,你可以弃掉【猴子】,阻止【桃】的结算并将其收为手牌。", + mianju: "漩涡面具", + mianju_info: "锁定技 你的武将牌不能被翻面。", + shoulijian: "手里剑", + shoulijian_info: "出牌阶段,对一名距离1以外的角色使用,令其弃置一张装备牌或受到1点伤害。", + kuwu: "苦无", + kuwu_info: "锁定技 每当你使用【杀】造成一次伤害,受伤角色须弃置一张牌。", + xuelunyang: "写轮眼", + xuelunyang_info: "回合开始阶段,你可以选择一名角色,然后获得其一项技能,直到回合结束。", + jiuwei: "九尾", + jiuwei_info: "(收集查克拉)回合结束时,若你已受伤,你可回复1点体力,否则摸一张牌。", }, - list:[ - ["diamond","5","monkey"], - ["heart","9","jiuwei"], - ["heart","2","xuelunyang"], - ["spade","6","kuwu"], - ["diamond","4","shoulijian"], - ["spade","4","shoulijian"], - ["club","3","mianju"], + list: [ + ["diamond", "5", "monkey"], + ["heart", "9", "jiuwei"], + ["heart", "2", "xuelunyang"], + ["spade", "6", "kuwu"], + ["diamond", "4", "shoulijian"], + ["spade", "4", "shoulijian"], + ["club", "3", "mianju"], ], - } + }; }); diff --git a/card/mtg.js b/card/mtg.js index a3965aab6..05e2921b8 100644 --- a/card/mtg.js +++ b/card/mtg.js @@ -1,726 +1,768 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ - return { - name:'mtg', - card:{ - mtg_lindixiliu:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_lindixiliu',player); - var card=get.cardPile2(function(card){ - return get.suit(card)=='heart'; - }); - if(card){ - player.gain(card,'draw'); - } - 'step 1' - player.chooseToDiscard('he',[1,Infinity],{suit:'heart'},'林地溪流').set('ai',function(card){ - return 8-get.value(card); - }).set('prompt2','弃置任意张红桃牌,每弃置一张牌,将一张延时锦囊牌置入一名随机敌方角色的判定区'); - 'step 2' - if(result.bool){ - event.num=result.cards.length; - event.targets=player.getEnemies(); - } - 'step 3' - if(event.num&&event.targets&&event.targets.length){ - var target=event.targets.randomGet(); - var list=get.inpile('delay'); - for(var i=0;i0){ - player.useCard({name:name},target); - return; - } - } - } - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:1 - } - } - }, - mtg_haidao:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_haidao',player); - if(player.isHealthy()){ - player.changeHujia(); - event.finish(); - } - else{ - player._temp_mtg_haidao=true; - player.chooseToDiscard('he','海岛').set('ai',function(card){ - return 5-get.value(card); - }).set('prompt2','弃置一张牌并回复1点体力,或取消并获得1点护甲'); - } - 'step 1' - if(result.bool){ - player.recover(); - } - else{ - player.changeHujia(); - } - 'step 2' - delete player._temp_mtg_haidao; - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:1 - } - } - }, - mtg_yixialan:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_yixialan',player); - player.chooseControl('基本牌','锦囊牌').set('prompt','选择一个类型获得该类型的一张牌').set('ai',function(){ - var player=_status.event.player; - if(!player.hasSha()||!player.hasShan()||player.hp==1) return 0; - return 1; - }); - 'step 1' - if(result.control=='基本牌'){ - player.gain(game.createCard(get.inpile('basic').randomGet()),'gain2'); - } - else{ - player.gain(game.createCard(get.inpile('trick','trick').randomGet()),'gain2'); - } - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:1 - } - } - }, - mtg_shuimomuxue:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_shuimomuxue',player); - if(player.countDiscardableCards('he')){ - player.chooseToDiscard('是否弃置一张牌并摸两张牌?','he').set('ai',function(card){ - return 8-get.value(card); - }); - } - else{ - event.finish(); - } - 'step 1' - if(result.bool){ - player.draw(2); - } - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:function(player){ - if(!player.countCards('h',function(card){ - return card.name!='mtg_shuimomuxue'&&get.value(card)<8; - })){ - return 0; - } - return 1; - } - } - } - }, - mtg_feixu:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - game.changeLand('mtg_feixu',player); - player.discoverCard(ui.discardPile.childNodes); - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:1 - } - } - }, - mtg_shamolvzhou:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - game.changeLand('mtg_shamolvzhou',player); - player.discoverCard(get.inpile('basic')); - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:1 - } - } - }, - mtg_duzhao:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_duzhao',player); - player.chooseTarget('选择一名角色令其获得一张毒',true).set('ai',function(target){ - if(target.hasSkillTag('nodu')) return 0; - return -get.attitude(_status.event.player,target)/Math.sqrt(target.hp+1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(game.createCard('du'),'gain2'); - } - }, - ai:{ - value:5, - useful:3, - order:4, - result:{ - player:function(player){ - if(game.countPlayer(function(current){ - if(current.hasSkillTag('nodu')) return false; - return get.attitude(player,current)<0; - })>game.countPlayer(function(current){ - if(current.hasSkillTag('nodu')) return false; - return get.attitude(player,current)>0; - })){ - return 1; - } - return 0; - } - } - } - }, - mtg_bingheyaosai:{ - type:'land', - fullborder:'wood', - enable:function(card,player){ - return !player.hasSkill('land_used'); - }, - notarget:true, - content:function(){ - 'step 0' - game.changeLand('mtg_bingheyaosai',player); - player.draw(2); - 'step 1' - player.chooseToDiscard('he',2,true); - }, - ai:{ - value:5, - useful:3, - order:2, - result:{ - player:1 - } - } - } - }, - skill:{ - mtg_bingheyaosai_skill:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - return event.card.name=='sha'; - }, - autodelay:true, - content:function(){ - player.chooseToDiscard(true,'he'); - }, - ai:{ - mapValue:-4 - } - }, - mtg_duzhao_skill:{ - trigger:{player:'phaseEnd'}, - forced:true, - content:function(){ - player.gain(game.createCard('du'),'gain2'); - }, - ai:{ - mapValue:-5 - } - }, - mtg_shamolvzhou_skill:{ - mod:{ - ignoredHandcard:function(card){ - if(get.type(card)=='basic'){ - return true; - } - } - }, - ai:{ - mapValue:3 - } - }, - mtg_haidao_skill:{ - trigger:{player:'changeHujiaBefore'}, - forced:true, - filter:function(event,player){ - return player.isDamaged()&&!player._temp_mtg_haidao&&event.num>0; - }, - content:function(){ - player.recover(trigger.num); - trigger.cancel(); - }, - ai:{ - mapValue:1 - } - }, - mtg_yixialan_skill:{ - enable:'phaseUse', - filter:(event,player)=>player.hasCard(card=>lib.skill.mtg_yixialan_skill.filterCard(card,player),'h'), - filterCard:(card,player)=>get.type(card)=='basic'&&player.canRecast(card), - discard:false, - lose:false, - check:function(card){ - return 7-get.value(card); - }, - usable:1, - content:function(){ - player.recast(cards,null,(player,cards)=>{ - var cardsToGain=[]; - for(var repetition=0;repetitionget.type(card,'trick')=='trick'); - if(card) cardsToGain.push(card); - } - if(cardsToGain.length) player.gain(cardsToGain,'draw'); - if(cards.length-cardsToGain.length) player.draw(cards.length-cardsToGain.length).log=false; - }); - }, - ai:{ - mapValue:2, - order:1, - result:{ - player:1 - } - } - }, - mtg_shuimomuxue_skill:{ - mod:{ - maxHandcard:function(player,num){ - return num-1; - } - }, - trigger:{player:'phaseDiscardEnd'}, - forced:true, - filter:function(event){ - return event.cards&&event.cards.length>0; - }, - content:function(){ - player.draw(); - }, - ai:{ - mapValue:2 - } - }, - mtg_feixu_skill:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - var num=ui.discardPile.childNodes.length; - if(num){ - var card=ui.discardPile.childNodes[get.rand(num)]; - if(card){ - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); - } - } - }, - ai:{ - mapValue:0 - } - }, - mtg_youlin_skill:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay']}); - }, - filterCard:function(card){ - return get.type(card,'trick')=='trick'; - }, - check:function(card){ - return 7-get.value(card); - }, - content:function(){ - player.discoverCard(); - }, - ai:{ - mapValue:1, - order:7, - result:{ - player:2 - } - } - }, - mtg_linzhongjianta_skill:{ - enable:'chooseToUse', - filterCard:function(card){ - return get.type(card)=='basic'; - }, - usable:1, - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(!player.getEquip(1)) return false; - if(!player.countCards('h',{type:'basic'})) return false; - }, - prompt:'将一张基本牌当杀使用', - check:function(card){return 6-get.value(card)}, - ai:{ - mapValue:2, - respondSha:true, - order:function(){ - return get.order({name:'sha'})-0.1; - }, - skillTagFilter:function(player,tag,arg){ - if(arg!='use') return false; - if(!player.getEquip(1)) return false; - if(!player.countCards('h',{type:'basic'})) return false; - }, - } - }, - mtg_cangbaohaiwan_skill:{ - trigger:{player:'drawBegin'}, - silent:true, - content:function(){ - if(Math.random()<1/3){ - var list=[]; - for(var i=0;i
      • 地图牌可于出牌阶段使用,每阶段最多使用一张地图牌
      • '+ - '地图牌分为两部分:即时效果以及地图效果,即时效果由使用者在使用时选择;地图效果对所有角色有效
      • '+ - '当使用者死亡或下个回合开始时,当前地图效果消失
      • '+ - '新地图被使用时会覆盖当前地图效果' - }, - list:[ - ['club',12,'mtg_yixialan'], - ['spade',11,'mtg_shuimomuxue'], - ['diamond',5,'mtg_haidao'], - ['club',10,'mtg_youlin'], - ['club',8,'mtg_feixu'], - ['heart',6,'mtg_shamolvzhou'], - - ['club',12,'mtg_cangbaohaiwan'], - ['spade',11,'mtg_lindixiliu'], - ['diamond',5,'mtg_bingheyaosai'], - ['club',10,'mtg_longlushanfeng'], - ['club',8,'mtg_duzhao'], - ['heart',6,'mtg_linzhongjianta'], - ], - }; -}); +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { + return { + name: "mtg", + card: { + mtg_lindixiliu: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_lindixiliu", player); + var card = get.cardPile2(function (card) { + return get.suit(card) == "heart"; + }); + if (card) { + player.gain(card, "draw"); + } + "step 1"; + player + .chooseToDiscard("he", [1, Infinity], { suit: "heart" }, "林地溪流") + .set("ai", function (card) { + return 8 - get.value(card); + }) + .set( + "prompt2", + "弃置任意张红桃牌,每弃置一张牌,将一张延时锦囊牌置入一名随机敌方角色的判定区" + ); + "step 2"; + if (result.bool) { + event.num = result.cards.length; + event.targets = player.getEnemies(); + } + "step 3"; + if (event.num && event.targets && event.targets.length) { + var target = event.targets.randomGet(); + var list = get.inpile("delay"); + for (var i = 0; i < list.length; i++) { + if (target.hasJudge(list[i])) { + list.splice(i--, 1); + } + } + if (list.length) { + player.line(target); + var card = game.createCard(list.randomGet()); + target.addJudge(card); + target.$draw(card); + game.delay(); + event.num--; + } else { + event.targets.remove(target); + } + event.redo(); + } + }, + ai: { + value: 6, + useful: 3, + order: 7, + result: { + player: 1, + }, + }, + }, + mtg_longlushanfeng: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_longlushanfeng", player); + player + .chooseControl("获得杀", "获得闪") + .set("prompt", "选择一项") + .set("ai", function () { + var player = _status.event.player; + if (player.hasShan()) return 0; + return 1; + }); + "step 1"; + if (result.control == "获得杀") { + player.gain(game.createCard("sha"), "gain2"); + } else { + player.gain(game.createCard("shan"), "gain2"); + } + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_cangbaohaiwan: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + if (!lib.cardPack.mode_derivation || !lib.cardPack.mode_derivation.length) return false; + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_cangbaohaiwan", player); + event.map = {}; + var pack1 = []; + var pack2 = []; + for (var i = 0; i < lib.cardPack.mode_derivation.length; i++) { + var name = lib.cardPack.mode_derivation[i]; + var info = lib.card[name]; + if (info.gainable == false || info.destroy) continue; + if (info.derivationpack) { + var trans = lib.translate[info.derivationpack + "_card_config"] + "(卡牌包)"; + if (!event.map[trans]) { + event.map[trans] = []; + pack2.push(trans); + } + event.map[trans].push(name); + } else if (typeof info.derivation == "string") { + for (var j in lib.characterPack) { + if (lib.characterPack[j][info.derivation]) { + var trans = lib.translate[j + "_character_config"] + "(武将包)"; + if (!event.map[trans]) { + event.map[trans] = []; + pack1.push(trans); + } + event.map[trans].push(name); + break; + } + } + } + } + if (!pack1.length && !pack2.length) { + event.finish(); + return; + } + player + .chooseControl(pack1.concat(pack2), "dialogcontrol", function () { + return _status.event.controls.randomGet("轩辕剑(卡牌包)"); + }) + .set("prompt", "选择一个扩展包获得其中一张衍生牌"); + "step 1"; + if (result.control && event.map[result.control]) { + player.gain(game.createCard(event.map[result.control].randomGet()), "draw"); + } + }, + ai: { + value: 7, + useful: 3, + order: 9, + result: { + player: 1, + }, + }, + }, + mtg_linzhongjianta: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_linzhongjianta", player); + player.discoverCard( + function (card) { + return get.subtype(card) == "equip1"; + }, + "nogain", + "选择一个武器装备之" + ); + "step 1"; + if (result.choice) { + player.equip(game.createCard(result.choice), true); + } + }, + ai: { + value: 5, + useful: 3, + order: 9, + result: { + player: function (player) { + if (player.getEquip(1)) return 0; + return 1; + }, + }, + }, + }, + mtg_youlin: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + game.changeLand("mtg_youlin", player); + var list = get.inpile("trick"); + while (list.length) { + var name = list.randomRemove(); + if (lib.card[name].multitarget) continue; + var targets = game.filterPlayer(); + while (targets.length) { + var target = targets.randomRemove(); + if ( + player.canUse(name, target, false) && + get.effect(target, { name: name }, player, player) > 0 + ) { + player.useCard({ name: name }, target); + return; + } + } + } + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_haidao: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_haidao", player); + if (player.isHealthy()) { + player.changeHujia(); + event.finish(); + } else { + player._temp_mtg_haidao = true; + player + .chooseToDiscard("he", "海岛") + .set("ai", function (card) { + return 5 - get.value(card); + }) + .set("prompt2", "弃置一张牌并回复1点体力,或取消并获得1点护甲"); + } + "step 1"; + if (result.bool) { + player.recover(); + } else { + player.changeHujia(); + } + "step 2"; + delete player._temp_mtg_haidao; + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_yixialan: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_yixialan", player); + player + .chooseControl("基本牌", "锦囊牌") + .set("prompt", "选择一个类型获得该类型的一张牌") + .set("ai", function () { + var player = _status.event.player; + if (!player.hasSha() || !player.hasShan() || player.hp == 1) return 0; + return 1; + }); + "step 1"; + if (result.control == "基本牌") { + player.gain(game.createCard(get.inpile("basic").randomGet()), "gain2"); + } else { + player.gain(game.createCard(get.inpile("trick", "trick").randomGet()), "gain2"); + } + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_shuimomuxue: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_shuimomuxue", player); + if (player.countDiscardableCards("he")) { + player.chooseToDiscard("是否弃置一张牌并摸两张牌?", "he").set("ai", function (card) { + return 8 - get.value(card); + }); + } else { + event.finish(); + } + "step 1"; + if (result.bool) { + player.draw(2); + } + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: function (player) { + if ( + !player.countCards("h", function (card) { + return card.name != "mtg_shuimomuxue" && get.value(card) < 8; + }) + ) { + return 0; + } + return 1; + }, + }, + }, + }, + mtg_feixu: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + game.changeLand("mtg_feixu", player); + player.discoverCard(ui.discardPile.childNodes); + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_shamolvzhou: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + game.changeLand("mtg_shamolvzhou", player); + player.discoverCard(get.inpile("basic")); + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: 1, + }, + }, + }, + mtg_duzhao: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_duzhao", player); + player.chooseTarget("选择一名角色令其获得一张毒", true).set("ai", function (target) { + if (target.hasSkillTag("nodu")) return 0; + return -get.attitude(_status.event.player, target) / Math.sqrt(target.hp + 1); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(game.createCard("du"), "gain2"); + } + }, + ai: { + value: 5, + useful: 3, + order: 4, + result: { + player: function (player) { + if ( + game.countPlayer(function (current) { + if (current.hasSkillTag("nodu")) return false; + return get.attitude(player, current) < 0; + }) > + game.countPlayer(function (current) { + if (current.hasSkillTag("nodu")) return false; + return get.attitude(player, current) > 0; + }) + ) { + return 1; + } + return 0; + }, + }, + }, + }, + mtg_bingheyaosai: { + type: "land", + fullborder: "wood", + enable: function (card, player) { + return !player.hasSkill("land_used"); + }, + notarget: true, + content: function () { + "step 0"; + game.changeLand("mtg_bingheyaosai", player); + player.draw(2); + "step 1"; + player.chooseToDiscard("he", 2, true); + }, + ai: { + value: 5, + useful: 3, + order: 2, + result: { + player: 1, + }, + }, + }, + }, + skill: { + mtg_bingheyaosai_skill: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + return event.card.name == "sha"; + }, + autodelay: true, + content: function () { + player.chooseToDiscard(true, "he"); + }, + ai: { + mapValue: -4, + }, + }, + mtg_duzhao_skill: { + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { + player.gain(game.createCard("du"), "gain2"); + }, + ai: { + mapValue: -5, + }, + }, + mtg_shamolvzhou_skill: { + mod: { + ignoredHandcard: function (card) { + if (get.type(card) == "basic") { + return true; + } + }, + }, + ai: { + mapValue: 3, + }, + }, + mtg_haidao_skill: { + trigger: { player: "changeHujiaBefore" }, + forced: true, + filter: function (event, player) { + return player.isDamaged() && !player._temp_mtg_haidao && event.num > 0; + }, + content: function () { + player.recover(trigger.num); + trigger.cancel(); + }, + ai: { + mapValue: 1, + }, + }, + mtg_yixialan_skill: { + enable: "phaseUse", + filter: (event, player) => + player.hasCard((card) => lib.skill.mtg_yixialan_skill.filterCard(card, player), "h"), + filterCard: (card, player) => get.type(card) == "basic" && player.canRecast(card), + discard: false, + lose: false, + check: function (card) { + return 7 - get.value(card); + }, + usable: 1, + content: function () { + player.recast(cards, null, (player, cards) => { + var cardsToGain = []; + for (var repetition = 0; repetition < cards.length; repetition++) { + var card = get.cardPile((card) => get.type(card, "trick") == "trick"); + if (card) cardsToGain.push(card); + } + if (cardsToGain.length) player.gain(cardsToGain, "draw"); + if (cards.length - cardsToGain.length) + player.draw(cards.length - cardsToGain.length).log = false; + }); + }, + ai: { + mapValue: 2, + order: 1, + result: { + player: 1, + }, + }, + }, + mtg_shuimomuxue_skill: { + mod: { + maxHandcard: function (player, num) { + return num - 1; + }, + }, + trigger: { player: "phaseDiscardEnd" }, + forced: true, + filter: function (event) { + return event.cards && event.cards.length > 0; + }, + content: function () { + player.draw(); + }, + ai: { + mapValue: 2, + }, + }, + mtg_feixu_skill: { + trigger: { player: "phaseBegin" }, + silent: true, + content: function () { + var num = ui.discardPile.childNodes.length; + if (num) { + var card = ui.discardPile.childNodes[get.rand(num)]; + if (card) { + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); + } + } + }, + ai: { + mapValue: 0, + }, + }, + mtg_youlin_skill: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", { type: ["trick", "delay"] }); + }, + filterCard: function (card) { + return get.type(card, "trick") == "trick"; + }, + check: function (card) { + return 7 - get.value(card); + }, + content: function () { + player.discoverCard(); + }, + ai: { + mapValue: 1, + order: 7, + result: { + player: 2, + }, + }, + }, + mtg_linzhongjianta_skill: { + enable: "chooseToUse", + filterCard: function (card) { + return get.type(card) == "basic"; + }, + usable: 1, + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (!player.getEquip(1)) return false; + if (!player.countCards("h", { type: "basic" })) return false; + }, + prompt: "将一张基本牌当杀使用", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + mapValue: 2, + respondSha: true, + order: function () { + return get.order({ name: "sha" }) - 0.1; + }, + skillTagFilter: function (player, tag, arg) { + if (arg != "use") return false; + if (!player.getEquip(1)) return false; + if (!player.countCards("h", { type: "basic" })) return false; + }, + }, + }, + mtg_cangbaohaiwan_skill: { + trigger: { player: "drawBegin" }, + silent: true, + content: function () { + if (Math.random() < 1 / 3) { + var list = []; + for (var i = 0; i < lib.cardPack.mode_derivation.length; i++) { + var name = lib.cardPack.mode_derivation[i]; + var info = lib.card[name]; + if (info.gainable == false || info.destroy) continue; + list.push(name); + } + if (list.length) { + ui.cardPile.insertBefore( + game.createCard(list.randomGet()), + ui.cardPile.firstChild + ); + } + } + }, + ai: { + mapValue: 5, + }, + }, + mtg_longlushanfeng_skill: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + ai: { + mapValue: 2, + }, + }, + mtg_lindixiliu_skill: { + trigger: { player: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { suit: "heart" }) && player.countCards("j"); + }, + content: function () { + "step 0"; + player + .chooseToDiscard("he", { suit: "heart" }, get.prompt2("mtg_lindixiliu_skill")) + .set("ai", function (card) { + return 8 - get.value(card); + }) + .set("logSkill", "mtg_lindixiliu_skill"); + "step 1"; + if (result.bool) { + player.discardPlayerCard(player, "j", true); + } + }, + ai: { + mapValue: 1.5, + }, + }, + }, + cardType: { + land: 0.6, + }, + translate: { + land: "地图", + mtg_yixialan: "依夏兰", + mtg_yixialan_skill: "依夏兰", + mtg_yixialan_info: + "选项一:随机获得一张基本牌;选项二:随机获得一张锦囊牌。地图效果:出牌阶段限一次,你可以将一张基本牌重铸为锦囊牌。", + mtg_yixialan_skill_info: "出牌阶段限一次,你可以将一张基本牌重铸为锦囊牌。", + mtg_shuimomuxue: "水没墓穴", + mtg_shuimomuxue_skill: "水没墓穴", + mtg_shuimomuxue_info: + "你可以弃置一张牌并摸两张牌。地图效果:锁定技,你的手牌上限-1;若弃牌阶段弃置了至少一张牌,则在此阶段结束时摸一张牌。", + mtg_shuimomuxue_skill_info: + "锁定技,你的手牌上限-1;若弃牌阶段弃置了至少一张牌,则在此阶段结束时摸一张牌。", + mtg_feixu: "废墟", + mtg_feixu_skill: "废墟", + mtg_feixu_info: "从弃牌堆中发现一张牌。地图效果:准备阶段,随机将弃牌堆的一张牌置于牌堆顶。", + mtg_feixu_skill_info: "准备阶段,随机将弃牌堆的一张牌置于牌堆顶。", + mtg_haidao: "海岛", + mtg_haidao_skill: "海岛", + mtg_haidao_info: + "选项一:获得1点护甲(无视地图效果);选项二:弃置一张牌并回复1点体力。地图效果:锁定技,当你获得护甲时,若你已受伤,改为回复等量体力。", + mtg_haidao_skill_info: "锁定技,当你获得护甲时,若你已受伤,改为回复等量体力。", + mtg_youlin: "幽林", + mtg_youlin_skill: "幽林", + mtg_youlin_info: + "随机使用一张普通锦囊牌,随机指定一个具有正收益的目标。地图效果:出牌阶段限一次,你可以弃置一张锦囊牌并发现一张牌。", + mtg_youlin_skill_info: "出牌阶段限一次,你可以弃置一张锦囊牌并发现一张牌。", + mtg_shamolvzhou: "沙漠绿洲", + mtg_shamolvzhou_skill: "沙漠绿洲", + mtg_shamolvzhou_info: "发现一张基本牌。地图效果:你的基本牌不计入手牌上限。", + mtg_shamolvzhou_skill_info: "你的基本牌不计入手牌上限。", + + mtg_duzhao: "毒沼", + mtg_duzhao_skill: "毒沼", + mtg_duzhao_info: "选择一名角色令其获得一张毒。地图效果:结束阶段,你获得一张毒。", + mtg_duzhao_skill_info: "结束阶段,你获得一张毒。", + mtg_linzhongjianta: "林中尖塔", + mtg_linzhongjianta_skill: "林中尖塔", + mtg_linzhongjianta_info: + "发现一张武器牌并装备之。地图效果:若你装备区内有武器牌,你可以将一张基本牌当作杀使用。", + mtg_linzhongjianta_skill_info: "若你装备区内有武器牌,你可以将一张基本牌当作杀使用。", + mtg_cangbaohaiwan: "藏宝海湾", + mtg_cangbaohaiwan_skill: "藏宝海湾", + mtg_cangbaohaiwan_info: + "选择一个扩展包,随机获得来自该扩展包的一张衍生牌。地图效果:你在摸牌时有可能摸到衍生牌。", + mtg_cangbaohaiwan_skill_info: "你在摸牌时有可能摸到衍生牌。", + mtg_longlushanfeng: "龙颅山峰", + mtg_longlushanfeng_skill: "龙颅山峰", + mtg_longlushanfeng_info: "选项一:获得一张杀;选项二:获得一张闪。地图效果:你出杀的次数上限+1。", + mtg_longlushanfeng_skill_info: "你出杀的次数上限+1。", + mtg_bingheyaosai: "冰河要塞", + mtg_bingheyaosai_skill: "冰河要塞", + mtg_bingheyaosai_info: + "摸两张牌,然后弃置两张牌。地图效果:锁定技,每当你使用一张杀,若你有牌,则需弃置一张牌。", + mtg_bingheyaosai_skill_info: "锁定技,每当你使用一张杀,若你有牌,则需弃置一张牌。", + mtg_lindixiliu: "林地溪流", + mtg_lindixiliu_skill: "林地溪流", + mtg_lindixiliu_info: + "从牌堆中摸一张红桃牌,然后弃置任意张红桃牌,每弃置一张牌,将一张延时锦囊牌置入一名随机敌方角色的判定区。地图效果:准备阶段,你可以弃置一张红桃牌,然后弃置判定区内的一张牌。", + mtg_lindixiliu_skill_info: "准备阶段,你可以弃置一张红桃牌,然后弃置判定区内的一张牌。", + }, + help: { + 万智牌: + "
        • 地图牌可于出牌阶段使用,每阶段最多使用一张地图牌
        • " + + "地图牌分为两部分:即时效果以及地图效果,即时效果由使用者在使用时选择;地图效果对所有角色有效
        • " + + "当使用者死亡或下个回合开始时,当前地图效果消失
        • " + + "新地图被使用时会覆盖当前地图效果", + }, + list: [ + ["club", 12, "mtg_yixialan"], + ["spade", 11, "mtg_shuimomuxue"], + ["diamond", 5, "mtg_haidao"], + ["club", 10, "mtg_youlin"], + ["club", 8, "mtg_feixu"], + ["heart", 6, "mtg_shamolvzhou"], + + ["club", 12, "mtg_cangbaohaiwan"], + ["spade", 11, "mtg_lindixiliu"], + ["diamond", 5, "mtg_bingheyaosai"], + ["club", 10, "mtg_longlushanfeng"], + ["club", 8, "mtg_duzhao"], + ["heart", 6, "mtg_linzhongjianta"], + ], + }; +}); diff --git a/card/sp.js b/card/sp.js index ea1dbd73b..252fb9022 100644 --- a/card/sp.js +++ b/card/sp.js @@ -1,679 +1,718 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'sp', - connect:true, - card:{ - jinchan:{ - audio:true, - fullskin:true, - wuxieable:true, - type:'trick', - notarget:true, - global:['g_jinchan','g_jinchan2'], - content:function(){ - var evt=event.getParent(3)._trigger; - if(evt.jinchan){ - var type=get.type(evt.card,'trick'); - if(type=='basic'||type=='trick'){ + name: "sp", + connect: true, + card: { + jinchan: { + audio: true, + fullskin: true, + wuxieable: true, + type: "trick", + notarget: true, + global: ["g_jinchan", "g_jinchan2"], + content: function () { + var evt = event.getParent(3)._trigger; + if (evt.jinchan) { + var type = get.type(evt.card, "trick"); + if (type == "basic" || type == "trick") { evt.neutralize(); } } player.draw(2); }, - ai:{ - useful:function(){ - var player=_status.event.player; - var nj=player.countCards('h','jinchan'); - var num=player.getHandcardLimit(); - if(nj>=num){ + ai: { + useful: function () { + var player = _status.event.player; + var nj = player.countCards("h", "jinchan"); + var num = player.getHandcardLimit(); + if (nj >= num) { return 10; } - if(nj==num-1){ + if (nj == num - 1) { return 6; } return 1; }, - result:{ - player:1 + result: { + player: 1, }, - value:5 - } + value: 5, + }, }, - qijia:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(target.getEquips(5).length){ - return target.countCards('e')>1; - } - else{ - return target.countCards('e')>0; + qijia: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + if (target == player) return false; + if (target.getEquips(5).length) { + return target.countCards("e") > 1; + } else { + return target.countCards("e") > 0; } }, - content:function(){ - 'step 0' - var e1=[],e2=[]; - var he=target.getCards('he'); - for(var i=0;ie2.length||(target.hp>=3&&Math.random()<0.3)){ - choice=1; + if (e1.length && e2.length) { + var choice = 0; + if (e1.length > e2.length || (target.hp >= 3 && Math.random() < 0.3)) { + choice = 1; } - event.e1=e1; - event.e2=e2; - target.chooseControl(choice).set('choiceList',['弃置'+get.translation(e1),'弃置'+get.translation(e2)]); - } - else{ - if(e1.length){ + event.e1 = e1; + event.e2 = e2; + target + .chooseControl(choice) + .set("choiceList", ["弃置" + get.translation(e1), "弃置" + get.translation(e2)]); + } else { + if (e1.length) { target.discard(e1); - } - else if(e2.length){ + } else if (e2.length) { target.discard(e2); } event.finish(); } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { target.discard(event.e1); - } - else{ + } else { target.discard(event.e2); } }, - ai:{ - order:9.01, - useful:1, - value:5, - result:{ - target:function(player,target){ - var num1=0,num2=0; - for(var i=1;i<=4;i++){ - var card=target.getEquip(i); - if(card){ - if(i==1||i==4){ - num1+=get.equipValue(card); - } - else{ - num2+=get.equipValue(card); + ai: { + order: 9.01, + useful: 1, + value: 5, + result: { + target: function (player, target) { + var num1 = 0, + num2 = 0; + for (var i = 1; i <= 4; i++) { + var card = target.getEquip(i); + if (card) { + if (i == 1 || i == 4) { + num1 += get.equipValue(card); + } else { + num2 += get.equipValue(card); } } } var num; - if(num1==0){ - num=num2; + if (num1 == 0) { + num = num2; + } else if (num2 == 0) { + num = num1; + } else { + num = Math.min(num1, num2); } - else if(num2==0){ - num=num1; - } - else{ - num=Math.min(num1,num2); - } - if(num>0){ - return -0.8-num/10; - } - else{ + if (num > 0) { + return -0.8 - num / 10; + } else { return 0; } - } + }, + }, + tag: { + loseCard: 1, + discard: 1, }, - tag:{ - loseCard:1, - discard:1 - } - } - }, - fulei:{ - audio:true, - fullskin:true, - type:'delay', - cardnature:'thunder', - modTarget:function(card,player,target){ - return lib.filter.judge(card,player,target); }, - enable:function(card,player){ + }, + fulei: { + audio: true, + fullskin: true, + type: "delay", + cardnature: "thunder", + modTarget: function (card, player, target) { + return lib.filter.judge(card, player, target); + }, + enable: function (card, player) { return player.canAddJudge(card); }, - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player==target); + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player == target; }, - selectTarget:[-1,-1], - toself:true, - judge:function(card){ - if(get.suit(card)=='spade') return -6; + selectTarget: [-1, -1], + toself: true, + judge: function (card) { + if (get.suit(card) == "spade") return -6; return 6; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - cardPrompt:function(card){ - var str='出牌阶段,对你使用。你将【浮雷】置入判定区。若判定结果为♠,则目标角色受到X点雷电伤害(X为此牌判定结果为♠的次数)。判定完成后,将此牌移动到下家的判定区里。'; - if(card.storage&&card.storage.fulei) str+=('
          此牌已判定命中过:'+card.storage.fulei+'次'); + cardPrompt: function (card) { + var str = + "出牌阶段,对你使用。你将【浮雷】置入判定区。若判定结果为♠,则目标角色受到X点雷电伤害(X为此牌判定结果为♠的次数)。判定完成后,将此牌移动到下家的判定区里。"; + if (card.storage && card.storage.fulei) + str += + '
          此牌已判定命中过:' + + card.storage.fulei + + "次"; return str; }, - effect:function(){ - 'step 0' - if(result.bool==false){ - var card=cards[0]; - if(card){ - if(!card.storage.fulei){ - card.storage.fulei=1; - } - else{ + effect: function () { + "step 0"; + if (result.bool == false) { + var card = cards[0]; + if (card) { + if (!card.storage.fulei) { + card.storage.fulei = 1; + } else { card.storage.fulei++; } - player.damage(card.storage.fulei,'thunder','nosource'); + player.damage(card.storage.fulei, "thunder", "nosource"); } } - 'step 1' + "step 1"; player.addJudgeNext(card); }, - cancel:function(){ + cancel: function () { player.addJudgeNext(card); }, - ai:{ - basic:{ - order:1, - useful:0, - value:0, + ai: { + basic: { + order: 1, + useful: 0, + value: 0, }, - result:{ - target:function(player,target){ - return lib.card.shandian.ai.result.target(player,target); - } + result: { + target: function (player, target) { + return lib.card.shandian.ai.result.target(player, target); + }, }, - tag:{ - damage:0.25, - natureDamage:0.25, - thunderDamage:0.25, - } - } + tag: { + damage: 0.25, + natureDamage: 0.25, + thunderDamage: 0.25, + }, + }, }, - qibaodao:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip1', - skills:['qibaodao','qibaodao2'], - distance:{attackFrom:-1}, - ai:{ - equipValue:function(card,player){ - if(game.hasPlayer(function(current){ - return player.canUse('sha',current)&¤t.isHealthy()&&get.attitude(player,current)<0; - })){ + qibaodao: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + skills: ["qibaodao", "qibaodao2"], + distance: { attackFrom: -1 }, + ai: { + equipValue: function (card, player) { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + current.isHealthy() && + get.attitude(player, current) < 0 + ); + }) + ) { return 5; } return 3; }, - basic:{ - equipValue:5 - } + basic: { + equipValue: 5, + }, }, }, - zhungangshuo:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip1', - skills:['zhungangshuo'], - distance:{attackFrom:-2}, - ai:{ - equipValue:4 + zhungangshuo: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + skills: ["zhungangshuo"], + distance: { attackFrom: -2 }, + ai: { + equipValue: 4, }, }, - lanyinjia:{ - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['lanyinjia','lanyinjia2'], - ai:{ - equipValue:6 - } + lanyinjia: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["lanyinjia", "lanyinjia2"], + ai: { + equipValue: 6, + }, }, - yinyueqiang:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - basic:{ - equipValue:4 - } + yinyueqiang: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + basic: { + equipValue: 4, + }, }, - skills:['yinyueqiang'] + skills: ["yinyueqiang"], }, - shengdong:{ - audio:true, - fullskin:true, - enable:function(){ - return game.countPlayer()>2; + shengdong: { + audio: true, + fullskin: true, + enable: function () { + return game.countPlayer() > 2; }, - recastable:function(){ - return game.countPlayer()<=2; + recastable: function () { + return game.countPlayer() <= 2; }, - singleCard:true, - type:'trick', - complexTarget:true, - multitarget:true, - targetprompt:['给一张牌','得两张牌'], - filterTarget:function(card,player,target){ - return target!==player; + singleCard: true, + type: "trick", + complexTarget: true, + multitarget: true, + targetprompt: ["给一张牌", "得两张牌"], + filterTarget: function (card, player, target) { + return target !== player; }, - filterAddedTarget:function(card,player,target,preTarget){ - return target!==preTarget&&target!==player; + filterAddedTarget: function (card, player, target, preTarget) { + return target !== preTarget && target !== player; }, - content:function(){ - 'step 0' - if(!player.countCards('h')){ + content: function () { + "step 0"; + if (!player.countCards("h")) { event.finish(); + } else { + event.target1 = target; + event.target2 = event.addedTarget; + player.chooseCard("h", "将一张手牌交给" + get.translation(event.target1), true); } - else{ - event.target1=target; - event.target2=event.addedTarget; - player.chooseCard('h','将一张手牌交给'+get.translation(event.target1),true); - } - 'step 1' - player.give(result.cards,event.target1); - 'step 2' - if(!event.target1.countCards('h')){ + "step 1"; + player.give(result.cards, event.target1); + "step 2"; + if (!event.target1.countCards("h")) { event.finish(); - } - else{ - var he=event.target1.getCards('he'); - if(he.length<=2){ - event.directresult=he; - } - else{ - event.target1.chooseCard('he','将两张牌交给'+get.translation(event.target2),2,true); + } else { + var he = event.target1.getCards("he"); + if (he.length <= 2) { + event.directresult = he; + } else { + event.target1.chooseCard( + "he", + "将两张牌交给" + get.translation(event.target2), + 2, + true + ); } } - 'step 3' - if(!event.directresult){ - event.directresult=result.cards; + "step 3"; + if (!event.directresult) { + event.directresult = result.cards; } - event.target1.give(event.directresult,event.target2); + event.target1.give(event.directresult, event.target2); }, - ai:{ - order:2.5, - value:[4,1], - useful:1, - wuxie:function(){ + ai: { + order: 2.5, + value: [4, 1], + useful: 1, + wuxie: function () { return 0; }, - result:{ - target:function(player,target){ - let hs=player.getCards('h'); - if(hs.length<=1||!hs.some(i=>{ - return get.value(i)<5.5; - })) return 0; - let targets=get.copy(ui.selected.targets); - if(_status.event.preTarget) targets.add(_status.event.preTarget); - if(targets.length){ - if(target.hasSkillTag('nogain')) return 0.01; + result: { + target: function (player, target) { + let hs = player.getCards("h"); + if ( + hs.length <= 1 || + !hs.some((i) => { + return get.value(i) < 5.5; + }) + ) + return 0; + let targets = get.copy(ui.selected.targets); + if (_status.event.preTarget) targets.add(_status.event.preTarget); + if (targets.length) { + if (target.hasSkillTag("nogain")) return 0.01; return 2; } - if(!target.countCards('he')) return 0; - if(player.hasFriend()) return -1; + if (!target.countCards("he")) return 0; + if (player.hasFriend()) return -1; return 0; - } - } - } - }, - zengbin:{ - audio:true, - fullskin:true, - enable:true, - type:'trick', - filterTarget:true, - content:function(){ - 'step 0' - target.draw(3); - 'step 1' - if(target.countCards('he',{type:'basic'})1).set('prompt2','弃置一张非基本牌,或取消并弃置两张牌'); - event.more=true; - } - else{ - target.chooseToDiscard('he',2,true).set('ai',get.disvalue2); - } - 'step 2' - if(event.more&&!result.bool){ - target.chooseToDiscard('he',2,true).set('ai',get.disvalue2); - } - }, - ai:{ - order:7, - useful:4, - value:10, - tag:{ - draw:3, - discard:1 + }, }, - result:{ - target:function(player,target){ - if(target.hasJudge('lebu')) return 0; - return Math.max(1,2-target.countCards('h')/10); - } - } - } - }, - caomu:{ - audio:true, - fullskin:true, - enable:true, - type:'delay', - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player!=target); }, - judge:function(card){ - if(get.suit(card)=='club') return 1; + }, + zengbin: { + audio: true, + fullskin: true, + enable: true, + type: "trick", + filterTarget: true, + content: function () { + "step 0"; + target.draw(3); + "step 1"; + if (target.countCards("he", { type: "basic" }) < target.countCards("he")) { + target + .chooseToDiscard("增兵减灶", "he", function (card) { + return get.type(card) != "basic"; + }) + .set("ai", function (card) { + if (_status.event.goon) return 8 - get.value(card); + return 11 - get.value(card); + }) + .set( + "goon", + target.countCards("h", function (card) { + return get.value(card, target, "raw") < 8; + }) > 1 + ) + .set("prompt2", "弃置一张非基本牌,或取消并弃置两张牌"); + event.more = true; + } else { + target.chooseToDiscard("he", 2, true).set("ai", get.disvalue2); + } + "step 2"; + if (event.more && !result.bool) { + target.chooseToDiscard("he", 2, true).set("ai", get.disvalue2); + } + }, + ai: { + order: 7, + useful: 4, + value: 10, + tag: { + draw: 3, + discard: 1, + }, + result: { + target: function (player, target) { + if (target.hasJudge("lebu")) return 0; + return Math.max(1, 2 - target.countCards("h") / 10); + }, + }, + }, + }, + caomu: { + audio: true, + fullskin: true, + enable: true, + type: "delay", + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player != target; + }, + judge: function (card) { + if (get.suit(card) == "club") return 1; return -3; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - effect:function(){ - if(result.bool==false){ - player.addTempSkill('caomu_skill'); + effect: function () { + if (result.bool == false) { + player.addTempSkill("caomu_skill"); } }, - ai:{ - basic:{ - order:1, - useful:1, - value:4.5, + ai: { + basic: { + order: 1, + useful: 1, + value: 4.5, }, - result:{ - player:function(player,target){ - return game.countPlayer(function(current){ - if(get.distance(target,current)<=1&¤t!=target){ - var att=get.attitude(player,current); - if(att>3){ + result: { + player: function (player, target) { + return game.countPlayer(function (current) { + if (get.distance(target, current) <= 1 && current != target) { + var att = get.attitude(player, current); + if (att > 3) { return 1.1; - } - else if(att>0){ + } else if (att > 0) { return 1; - } - else if(att<-3){ + } else if (att < -3) { return -1.1; - } - else if(att<0){ + } else if (att < 0) { return -1; } } }); }, - target:function(player,target){ - if(target.hasJudge('bingliang')) return 0; - return -1.5/Math.sqrt(target.countCards('h')+1); - } + target: function (player, target) { + if (target.hasJudge("bingliang")) return 0; + return -1.5 / Math.sqrt(target.countCards("h") + 1); + }, }, - } - } - }, - skill:{ - lanyinjia:{ - equipSkill:true, - enable:['chooseToUse','chooseToRespond'], - filterCard:true, - viewAs:{name:'shan'}, - viewAsFilter:function(player){ - if(!player.countCards('hs')) return false; }, - position:'hs', - prompt:'将一张手牌当闪使用或打出', - check:function(card){ - return 6-get.value(card); - }, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hs')) return false; - }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0&&target.countCards('hs')) return 0.59 - } - }, - order:4, - useful:-0.5, - value:-0.5 - } }, - lanyinjia2:{ - equipSkill:true, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.getEquips('lanyinjia').length>0; + }, + skill: { + lanyinjia: { + equipSkill: true, + enable: ["chooseToUse", "chooseToRespond"], + filterCard: true, + viewAs: { name: "shan" }, + viewAsFilter: function (player) { + if (!player.countCards("hs")) return false; }, - content:function(){ - var card=player.getEquips('lanyinjia'); - if(card.length){ + position: "hs", + prompt: "将一张手牌当闪使用或打出", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hs")) return false; + }, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0 && target.countCards("hs")) + return 0.59; + }, + }, + order: 4, + useful: -0.5, + value: -0.5, + }, + }, + lanyinjia2: { + equipSkill: true, + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.getEquips("lanyinjia").length > 0; + }, + content: function () { + var card = player.getEquips("lanyinjia"); + if (card.length) { player.discard(card); } }, }, - zhungangshuo:{ - equipSkill:true, - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - filter:function(event,player){ - return event.card.name=='sha'&&(event.player.countCards('h')||player.countCards('h')); + zhungangshuo: { + equipSkill: true, + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + filter: function (event, player) { + return ( + event.card.name == "sha" && (event.player.countCards("h") || player.countCards("h")) + ); }, - check:function(event,player){ - var target=event.target; - if(get.attitude(player,target)>=0) return false; - if(player.hasCard(function(card){ - return get.value(card)>=8; - })){ + check: function (event, player) { + var target = event.target; + if (get.attitude(player, target) >= 0) return false; + if ( + player.hasCard(function (card) { + return get.value(card) >= 8; + }) + ) { return false; } - var n1=event.target.countCards('h'); - return n1>0&&n1<=player.countCards('h'); + var n1 = event.target.countCards("h"); + return n1 > 0 && n1 <= player.countCards("h"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; game.delayx(); - 'step 1' - trigger.target.discardPlayerCard('h',player,true); - 'step 2' - player.discardPlayerCard('h',trigger.target,true); - } - }, - qibaodao:{ - equipSkill:true, - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.player.isHealthy(); + "step 1"; + trigger.target.discardPlayerCard("h", player, true); + "step 2"; + player.discardPlayerCard("h", trigger.target, true); }, - content:function(){ + }, + qibaodao: { + equipSkill: true, + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event) { + return event.card && event.card.name == "sha" && event.player.isHealthy(); + }, + content: function () { trigger.num++; }, - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name=='sha'&&target.isHealthy()&&get.attitude(player,target)>0){ - return [1,-2]; + ai: { + effect: { + player: function (card, player, target) { + if ( + card.name == "sha" && + target.isHealthy() && + get.attitude(player, target) > 0 + ) { + return [1, -2]; } - } - } - } - }, - qibaodao2:{ - inherit:'qinggang_skill', - audio:true, - }, - g_jinchan:{ - cardSkill:true, - trigger:{target:'useCardToBefore'}, - forced:true, - popup:false, - filter:function(event,player){ - if(event.player==player) return false; - if(event.getParent().directHit.includes(player)) return false; - var num=player.countCards('h','jinchan'); - return num&&num==player.countCards('h'); + }, + }, }, - content:function(){ - 'step 0' - player.chooseToUse('是否对'+get.translation(trigger.card)+'使用【金蝉脱壳】?').set('ai1',function(card){ - return _status.event.bool; - }).set('bool',-get.effect(player,trigger.card,trigger.player,player)).set('respondTo',[trigger.player,trigger.card]).set('filterCard',function(card,player){ - if(get.name(card)!='jinchan') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - }); - trigger.jinchan=true; - 'step 1' + }, + qibaodao2: { + inherit: "qinggang_skill", + audio: true, + }, + g_jinchan: { + cardSkill: true, + trigger: { target: "useCardToBefore" }, + forced: true, + popup: false, + filter: function (event, player) { + if (event.player == player) return false; + if (event.getParent().directHit.includes(player)) return false; + var num = player.countCards("h", "jinchan"); + return num && num == player.countCards("h"); + }, + content: function () { + "step 0"; + player + .chooseToUse("是否对" + get.translation(trigger.card) + "使用【金蝉脱壳】?") + .set("ai1", function (card) { + return _status.event.bool; + }) + .set("bool", -get.effect(player, trigger.card, trigger.player, player)) + .set("respondTo", [trigger.player, trigger.card]) + .set("filterCard", function (card, player) { + if (get.name(card) != "jinchan") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }); + trigger.jinchan = true; + "step 1"; delete trigger.jinchan; - } - }, - g_jinchan2:{ - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', }, - forced:true, - cardSkill:true, - filter:function(event,player){ - if(event.type!='discard') return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - for(var i of evt.cards2){ - if(i.name=='jinchan') return true; + }, + g_jinchan2: { + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", + }, + forced: true, + cardSkill: true, + filter: function (event, player) { + if (event.type != "discard") return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + for (var i of evt.cards2) { + if (i.name == "jinchan") return true; } return false; }, - content:function(){ - var num=0,cards=trigger.getl(player).cards2; - for(var i=0;inatures.includes(n)); - if(linked.length) str+=get.translation(get.nature(linked))+'属性'; - str+='伤害。'; + str += "否则你对其造成1点"; + var linked = lib.linked.filter((n) => natures.includes(n)); + if (linked.length) str += get.translation(get.nature(linked)) + "属性"; + str += "伤害。"; return str; }, - defaultYingbianEffect:'add', - filterTarget:function(card,player,target){return player!=target}, - content:function(){ - "step 0" - if(typeof event.shanRequired!='number'||!event.shanRequired||event.shanRequired<0){ - event.shanRequired=1; + defaultYingbianEffect: "add", + filterTarget: function (card, player, target) { + return player != target; + }, + content: function () { + "step 0"; + if ( + typeof event.shanRequired != "number" || + !event.shanRequired || + event.shanRequired < 0 + ) { + event.shanRequired = 1; } - if(typeof event.baseDamage!='number') event.baseDamage=1; - if(typeof event.extraDamage!='number') event.extraDamage=0; - "step 1" - if(event.directHit||event.directHit2||(!_status.connectMode&&lib.config.skip_shan&&!target.hasShan())){ - event._result={bool:false}; - } - else if(event.skipShan){ - event._result={bool:true,result:'shaned'}; - } - else{ - var next=target.chooseToUse('请使用一张闪响应杀'); - next.set('type','respondShan'); - next.set('filterCard',function(card,player){ - if(get.name(card)!='shan') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); + if (typeof event.baseDamage != "number") event.baseDamage = 1; + if (typeof event.extraDamage != "number") event.extraDamage = 0; + "step 1"; + if ( + event.directHit || + event.directHit2 || + (!_status.connectMode && lib.config.skip_shan && !target.hasShan()) + ) { + event._result = { bool: false }; + } else if (event.skipShan) { + event._result = { bool: true, result: "shaned" }; + } else { + var next = target.chooseToUse("请使用一张闪响应杀"); + next.set("type", "respondShan"); + next.set("filterCard", function (card, player) { + if (get.name(card) != "shan") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); }); - if(event.shanRequired>1){ - next.set('prompt2','(共需使用'+event.shanRequired+'张闪)'); + if (event.shanRequired > 1) { + next.set("prompt2", "(共需使用" + event.shanRequired + "张闪)"); + } else if (game.hasNature(event.card, "stab")) { + next.set("prompt2", "(在此之后仍需弃置一张手牌)"); } - else if(game.hasNature(event.card,'stab')){ - next.set('prompt2','(在此之后仍需弃置一张手牌)'); - } - next.set('ai1',function(card){ - if(_status.event.useShan) return get.order(card); + next.set("ai1", function (card) { + if (_status.event.useShan) return get.order(card); return 0; - }).set('shanRequired',event.shanRequired); - next.set('respondTo',[player,card]); - next.set('useShan',(()=>{ - if(target.hasSkillTag('noShan',null,event)) return false; - if(target.hasSkillTag('useShan',null,event)) return true; - if(target.isLinked()&&game.hasNature(event.card)&&get.attitude(target,player._trueMe||player)>0) return false; - if(event.baseDamage+event.extraDamage<=0&&!game.hasNature(event.card,'ice')) return false; - if(event.baseDamage+event.extraDamage>=target.hp+ - ((player.hasSkillTag('jueqing',false,target)||target.hasSkill('gangzhi'))?target.hujia:0)) return true; - if(!game.hasNature(event.card,'ice')&&get.damageEffect(target,player,target,get.nature(event.card))>=0) return false; - if(event.shanRequired>1&&target.mayHaveShan(target,'use',null,'count') { + if (target.hasSkillTag("noShan", null, event)) return false; + if (target.hasSkillTag("useShan", null, event)) return true; + if ( + target.isLinked() && + game.hasNature(event.card) && + get.attitude(target, player._trueMe || player) > 0 + ) + return false; + if ( + event.baseDamage + event.extraDamage <= 0 && + !game.hasNature(event.card, "ice") + ) + return false; + if ( + event.baseDamage + event.extraDamage >= + target.hp + + (player.hasSkillTag("jueqing", false, target) || + target.hasSkill("gangzhi") + ? target.hujia + : 0) + ) + return true; + if ( + !game.hasNature(event.card, "ice") && + get.damageEffect(target, player, target, get.nature(event.card)) >= 0 + ) + return false; + if ( + event.shanRequired > 1 && + target.mayHaveShan(target, "use", null, "count") < + event.shanRequired - (event.shanIgnored || 0) + ) + return false; + return true; + })() + ); //next.autochoose=lib.filter.autoRespondShan; } - "step 2" - if(!result||!result.bool||!result.result||result.result!='shaned'){ - event.trigger('shaHit'); - } - else{ + "step 2"; + if (!result || !result.bool || !result.result || result.result != "shaned") { + event.trigger("shaHit"); + } else { event.shanRequired--; - if(event.shanRequired>0){ + if (event.shanRequired > 0) { event.goto(1); - } - else if(game.hasNature(event.card,'stab')&&target.countCards('h')>0){ - event.responded=result; + } else if (game.hasNature(event.card, "stab") && target.countCards("h") > 0) { + event.responded = result; event.goto(4); - } - else{ - event.trigger('shaMiss'); - event.responded=result; + } else { + event.trigger("shaMiss"); + event.responded = result; } } - "step 3" - if((!result||!result.bool||!result.result||result.result!='shaned')&&!event.unhurt){ - if (!event.directHit&&!event.directHit2&&lib.filter.cardEnabled(new lib.element.VCard({name:'shan'}), target, 'forceEnable')&& - target.countCards('hs')>0&&get.damageEffect(target,player,target)<0) target.addGaintag(target.getCards('hs'),'sha_notshan'); + "step 3"; + if ( + (!result || !result.bool || !result.result || result.result != "shaned") && + !event.unhurt + ) { + if ( + !event.directHit && + !event.directHit2 && + lib.filter.cardEnabled( + new lib.element.VCard({ name: "shan" }), + target, + "forceEnable" + ) && + target.countCards("hs") > 0 && + get.damageEffect(target, player, target) < 0 + ) + target.addGaintag(target.getCards("hs"), "sha_notshan"); target.damage(get.nature(event.card)); - event.result={bool:true} - event.trigger('shaDamage'); - } - else{ - event.result={bool:false} - event.trigger('shaUnhirt'); + event.result = { bool: true }; + event.trigger("shaDamage"); + } else { + event.result = { bool: false }; + event.trigger("shaUnhirt"); } event.finish(); - "step 4" - target.chooseToDiscard('刺杀:请弃置一张牌,否则此【杀】依然造成伤害').set('ai',function(card){ - var target=_status.event.player; - var evt=_status.event.getParent(); - var bool=true; - if(get.damageEffect(target,evt.player,target,evt.card.nature)>=0) bool=false; - if(bool){ - return 8-get.useful(card); - } - return 0; - }); - "step 5" - if((!result||!result.bool)&&!event.unhurt){ + "step 4"; + target + .chooseToDiscard("刺杀:请弃置一张牌,否则此【杀】依然造成伤害") + .set("ai", function (card) { + var target = _status.event.player; + var evt = _status.event.getParent(); + var bool = true; + if (get.damageEffect(target, evt.player, target, evt.card.nature) >= 0) + bool = false; + if (bool) { + return 8 - get.useful(card); + } + return 0; + }); + "step 5"; + if ((!result || !result.bool) && !event.unhurt) { target.damage(get.nature(event.card)); - event.result={bool:true} - event.trigger('shaDamage'); + event.result = { bool: true }; + event.trigger("shaDamage"); event.finish(); + } else { + event.trigger("shaMiss"); } - else{ - event.trigger('shaMiss'); - } - "step 6" - if((!result||!result.bool)&&!event.unhurt){ + "step 6"; + if ((!result || !result.bool) && !event.unhurt) { target.damage(get.nature(event.card)); - event.result={bool:true} - event.trigger('shaDamage'); + event.result = { bool: true }; + event.trigger("shaDamage"); event.finish(); - } - else{ - event.result={bool:false} - event.trigger('shaUnhirt'); + } else { + event.result = { bool: false }; + event.trigger("shaUnhirt"); } }, - ai:{ - yingbian:function(card,player,targets,viewer){ - if(get.attitude(viewer,player)<=0) return 0; - var base=0,hit=false; - if(get.cardtag(card,'yingbian_hit')){ - hit=true; - if(targets.some(target=>{ - return target.mayHaveShan(viewer,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&get.attitude(viewer,target)<0&&get.damageEffect(target,player,viewer,get.natureList(card))>0; - })) base+=5; - } - if(get.cardtag(card,'yingbian_add')){ - if(game.hasPlayer(function(current){ - return !targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })) base+=5; - } - if(get.cardtag(card,'yingbian_damage')){ - if(targets.some(target=>{ - return get.attitude(player,target)<0&&(hit||!target.mayHaveShan(viewer,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true))&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - jiu:true, + ai: { + yingbian: function (card, player, targets, viewer) { + if (get.attitude(viewer, player) <= 0) return 0; + var base = 0, + hit = false; + if (get.cardtag(card, "yingbian_hit")) { + hit = true; + if ( + targets.some((target) => { + return ( + target.mayHaveShan( + viewer, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + get.attitude(viewer, target) < 0 && + get.damageEffect(target, player, viewer, get.natureList(card)) > 0 + ); }) - })) base+=5; + ) + base += 5; + } + if (get.cardtag(card, "yingbian_add")) { + if ( + game.hasPlayer(function (current) { + return ( + !targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + base += 5; + } + if (get.cardtag(card, "yingbian_damage")) { + if ( + targets.some((target) => { + return ( + get.attitude(player, target) < 0 && + (hit || + !target.mayHaveShan( + viewer, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + )) && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + jiu: true, + }) + ); + }) + ) + base += 5; } return base; }, - canLink:function(player,target,card){ - if(!target.isLinked()&&!player.hasSkill('wutiesuolian_skill')) return false; - if(player.hasSkill('jueqing')||player.hasSkill('gangzhi')||target.hasSkill('gangzhi')) return false; + canLink: function (player, target, card) { + if (!target.isLinked() && !player.hasSkill("wutiesuolian_skill")) return false; + if ( + player.hasSkill("jueqing") || + player.hasSkill("gangzhi") || + target.hasSkill("gangzhi") + ) + return false; return true; }, - basic:{ - useful:[5,3,1], - value:[5,3,1], + basic: { + useful: [5, 3, 1], + value: [5, 3, 1], }, order(item, player) { let res = 3.2; - if (player.hasSkillTag('presha', true, null, true)) res = 10; - if (typeof item !== 'object' || !game.hasNature(item, 'linked') || game.countPlayer(cur => cur.isLinked()) < 2) return res; + if (player.hasSkillTag("presha", true, null, true)) res = 10; + if ( + typeof item !== "object" || + !game.hasNature(item, "linked") || + game.countPlayer((cur) => cur.isLinked()) < 2 + ) + return res; //let used = player.getCardUsable('sha') - 1.5, natures = ['thunder', 'fire', 'ice', 'kami']; let uv = player.getUseValue(item, true); if (uv <= 0) return res; - let temp = player.getUseValue('sha', true) - uv; + let temp = player.getUseValue("sha", true) - uv; if (temp < 0) return res + 0.15; if (temp > 0) return res - 0.15; return res; }, - result:{ - target:function(player,target,card,isLink){ - let eff=-1.5,odds=1.35,num=1; - if(isLink){ - let cache=_status.event.getTempCache('sha_result','eff'); - if(typeof cache!=='object'||cache.card!==get.translation(card)) return eff; - if(cache.odds<1.35&&cache.bool) return 1.35*cache.eff; - return cache.odds*cache.eff; + result: { + target: function (player, target, card, isLink) { + let eff = -1.5, + odds = 1.35, + num = 1; + if (isLink) { + let cache = _status.event.getTempCache("sha_result", "eff"); + if (typeof cache !== "object" || cache.card !== get.translation(card)) + return eff; + if (cache.odds < 1.35 && cache.bool) return 1.35 * cache.eff; + return cache.odds * cache.eff; } - if(player.hasSkill('jiu')||player.hasSkillTag('damageBonus',true,{ - target:target, - card:card - })){ - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - jiu:true, - })) eff=-0.5; - else{ - num=2; - if(get.attitude(player,target)>0) eff=-7; - else eff=-4; + if ( + player.hasSkill("jiu") || + player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }) + ) { + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + jiu: true, + }) + ) + eff = -0.5; + else { + num = 2; + if (get.attitude(player, target) > 0) eff = -7; + else eff = -4; } } - if(!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)) odds-=0.7*target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }),'odds'); - _status.event.putTempCache('sha_result','eff',{ - bool:target.hp>num&&get.attitude(player,target)>0, - card:get.translation(card), - eff:eff, - odds:odds + if ( + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) + odds -= + 0.7 * + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }), + "odds" + ); + _status.event.putTempCache("sha_result", "eff", { + bool: target.hp > num && get.attitude(player, target) > 0, + card: get.translation(card), + eff: eff, + odds: odds, }); - return odds*eff; + return odds * eff; }, }, - tag:{ - respond:1, - respondShan:1, - damage:function(card){ - if(game.hasNature(card,'poison')) return; + tag: { + respond: 1, + respondShan: 1, + damage: function (card) { + if (game.hasNature(card, "poison")) return; return 1; }, - natureDamage:function(card){ - if(game.hasNature(card,'linked')) return 1; + natureDamage: function (card) { + if (game.hasNature(card, "linked")) return 1; }, - fireDamage:function(card,nature){ - if(game.hasNature(card,'fire')) return 1; + fireDamage: function (card, nature) { + if (game.hasNature(card, "fire")) return 1; }, - thunderDamage:function(card,nature){ - if(game.hasNature(card,'thunder')) return 1; + thunderDamage: function (card, nature) { + if (game.hasNature(card, "thunder")) return 1; }, - poisonDamage:function(card,nature){ - if(game.hasNature(card,'poison')) return 1; - } - } - } + poisonDamage: function (card, nature) { + if (game.hasNature(card, "poison")) return 1; + }, + }, + }, }, - shacopy:{ - ai:{ - basic:{ - useful:[5,3,1], - value:[5,3,1], + shacopy: { + ai: { + basic: { + useful: [5, 3, 1], + value: [5, 3, 1], }, - order:3, - result:{ - target:-1.5, + order: 3, + result: { + target: -1.5, }, - tag:{ - respond:1, - respondShan:1, - damage:function(card){ - if(game.hasNature(card,'poison')) return; + tag: { + respond: 1, + respondShan: 1, + damage: function (card) { + if (game.hasNature(card, "poison")) return; return 1; }, - natureDamage:function(card){ - if(game.hasNature(card)) return 1; + natureDamage: function (card) { + if (game.hasNature(card)) return 1; }, - fireDamage:function(card,nature){ - if(game.hasNature(card,'fire')) return 1; + fireDamage: function (card, nature) { + if (game.hasNature(card, "fire")) return 1; }, - thunderDamage:function(card,nature){ - if(game.hasNature(card,'thunder')) return 1; + thunderDamage: function (card, nature) { + if (game.hasNature(card, "thunder")) return 1; }, - poisonDamage:function(card,nature){ - if(game.hasNature(card,'poison')) return 1; - } - } - } + poisonDamage: function (card, nature) { + if (game.hasNature(card, "poison")) return 1; + }, + }, + }, }, - shan:{ - audio:true, - fullskin:true, - type:'basic', - cardcolor:'red', - notarget:true, - nodelay:true, - defaultYingbianEffect:'draw', - content:function(){ - event.result='shaned'; - event.getParent().delayx=false; + shan: { + audio: true, + fullskin: true, + type: "basic", + cardcolor: "red", + notarget: true, + nodelay: true, + defaultYingbianEffect: "draw", + content: function () { + event.result = "shaned"; + event.getParent().delayx = false; game.delay(0.5); }, - ai:{ - order:3, - basic:{ - useful:(card,i)=>{ - let player = _status.event.player, basic = [7, 5.1, 2], num = basic[Math.min(2, i)]; - if(player.hp>2&&player.hasSkillTag('maixie')) num *= 0.57; - if(player.hasSkillTag('freeShan',false,null,true) || player.getEquip('rewrite_renwang')) num *= 0.8; + ai: { + order: 3, + basic: { + useful: (card, i) => { + let player = _status.event.player, + basic = [7, 5.1, 2], + num = basic[Math.min(2, i)]; + if (player.hp > 2 && player.hasSkillTag("maixie")) num *= 0.57; + if ( + player.hasSkillTag("freeShan", false, null, true) || + player.getEquip("rewrite_renwang") + ) + num *= 0.8; return num; }, - value:[7,5.1,2], + value: [7, 5.1, 2], }, - result:{player:1}, + result: { player: 1 }, //expose:0.2 - } + }, }, - tao:{ - fullskin:true, - type:'basic', - cardcolor:'red', - toself:true, - enable:function(card,player){ - return player.hp{ - if(player.hasSkillTag('pretao')) return 9; + ai: { + basic: { + order: (card, player) => { + if (player.hasSkillTag("pretao")) return 9; return 2; }, - useful:(card,i)=>{ + useful: (card, i) => { let player = _status.event.player; - if(!game.checkMod(card,player,'unchanged','cardEnabled2',player)) return 2/(1+i); - let fs = game.filterPlayer(current=>{ - return get.attitude(player,current)>0&¤t.hp<=2; - }), damaged = 0, needs = 0; - fs.forEach(f=>{ - if(f.hp>3 || !lib.filter.cardSavable(card,player,f)) return; - if(f.hp>1) damaged++; + if (!game.checkMod(card, player, "unchanged", "cardEnabled2", player)) + return 2 / (1 + i); + let fs = game.filterPlayer((current) => { + return get.attitude(player, current) > 0 && current.hp <= 2; + }), + damaged = 0, + needs = 0; + fs.forEach((f) => { + if (f.hp > 3 || !lib.filter.cardSavable(card, player, f)) return; + if (f.hp > 1) damaged++; else needs++; }); - if(needs&&damaged) return 5*needs+3*damaged; - if(needs+damaged>1 || player.hasSkillTag('maixie')) return 8; - if(player.hp/player.maxHp<0.7) return 7+Math.abs(player.hp/player.maxHp-0.5); - if(needs) return 7; - if(damaged) return Math.max(3,7.8-i); - return Math.max(1,7.2-i); + if (needs && damaged) return 5 * needs + 3 * damaged; + if (needs + damaged > 1 || player.hasSkillTag("maixie")) return 8; + if (player.hp / player.maxHp < 0.7) + return 7 + Math.abs(player.hp / player.maxHp - 0.5); + if (needs) return 7; + if (damaged) return Math.max(3, 7.8 - i); + return Math.max(1, 7.2 - i); }, - value:(card,player)=>{ - let fs = game.filterPlayer(current=>{ - return get.attitude(_status.event.player,current)>0; - }), damaged = 0, needs = 0; - fs.forEach(f=>{ - if(!player.canUse('tao',f)) return; - if(f.hp<=1) needs++; - else if(f.hp==2) damaged++; + value: (card, player) => { + let fs = game.filterPlayer((current) => { + return get.attitude(_status.event.player, current) > 0; + }), + damaged = 0, + needs = 0; + fs.forEach((f) => { + if (!player.canUse("tao", f)) return; + if (f.hp <= 1) needs++; + else if (f.hp == 2) damaged++; }); - if(needs&&damaged || player.hasSkillTag('maixie')) return Math.max(9,5*needs+3*damaged); - if(needs || damaged>1) return 8; - if(damaged) return 7.5; - return Math.max(5,9.2-player.hp); - } + if ((needs && damaged) || player.hasSkillTag("maixie")) + return Math.max(9, 5 * needs + 3 * damaged); + if (needs || damaged > 1) return 8; + if (damaged) return 7.5; + return Math.max(5, 9.2 - player.hp); + }, }, - result:{ - target:(player,target)=>{ - if(target.hasSkillTag('maixie')) return 3; + result: { + target: (player, target) => { + if (target.hasSkillTag("maixie")) return 3; return 2; }, - target_use:(player,target,card)=>{ + target_use: (player, target, card) => { let mode = get.mode(), - taos = player.getCards('hs',i=>get.name(i)==='tao'&&lib.filter.cardEnabled(i,target,'forceEnable')); - if(target!==_status.event.dying){ - if(!player.isPhaseUsing() || player.hasSkillTag('nokeep',true,{ - card:card, - target:target - },true)) return 2; - let min = 7.2-4*player.hp/player.maxHp, - nd = player.needsToDiscard(0,(i,player)=>{ - return !player.canIgnoreHandcard(i)&&(taos.includes(i)||get.value(i)>=min); + taos = player.getCards( + "hs", + (i) => + get.name(i) === "tao" && + lib.filter.cardEnabled(i, target, "forceEnable") + ); + if (target !== _status.event.dying) { + if ( + !player.isPhaseUsing() || + player.hasSkillTag( + "nokeep", + true, + { + card: card, + target: target, + }, + true + ) + ) + return 2; + let min = 7.2 - (4 * player.hp) / player.maxHp, + nd = player.needsToDiscard(0, (i, player) => { + return ( + !player.canIgnoreHandcard(i) && + (taos.includes(i) || get.value(i) >= min) + ); }), - keep = nd?0:2; - if(nd>2 || taos.length>1&&(nd>1||nd&&player.hp<1+taos.length) || target.identity==='zhu'&&(nd||target.hp<3)&&(mode==='identity'||mode==='versus'||mode==='chess') || !player.hasFriend()) return 2; - if(game.hasPlayer(current=>{ - return player!==current&¤t.identity==='zhu'&¤t.hp<3&&(mode==='identity'||mode==='versus'||mode==='chess')&&get.attitude(player,current)>0; - })) keep = 3; - else if(nd===2||player.hp<2) return 2; - if(nd===2&&player.hp<=1) return 2; - if(keep===3) return 0; - if(taos.length<=player.hp/2) keep = 1; - if(keep&&game.countPlayer(current=>{ - if(player!==current&¤t.hp<3&&player.hp>current.hp&&get.attitude(player,current)>2){ - keep += player.hp-current.hp; - return true; - } - return false; - })){ - if(keep>2) return 0; + keep = nd ? 0 : 2; + if ( + nd > 2 || + (taos.length > 1 && (nd > 1 || (nd && player.hp < 1 + taos.length))) || + (target.identity === "zhu" && + (nd || target.hp < 3) && + (mode === "identity" || mode === "versus" || mode === "chess")) || + !player.hasFriend() + ) + return 2; + if ( + game.hasPlayer((current) => { + return ( + player !== current && + current.identity === "zhu" && + current.hp < 3 && + (mode === "identity" || mode === "versus" || mode === "chess") && + get.attitude(player, current) > 0 + ); + }) + ) + keep = 3; + else if (nd === 2 || player.hp < 2) return 2; + if (nd === 2 && player.hp <= 1) return 2; + if (keep === 3) return 0; + if (taos.length <= player.hp / 2) keep = 1; + if ( + keep && + game.countPlayer((current) => { + if ( + player !== current && + current.hp < 3 && + player.hp > current.hp && + get.attitude(player, current) > 2 + ) { + keep += player.hp - current.hp; + return true; + } + return false; + }) + ) { + if (keep > 2) return 0; } return 2; } - if(target.isZhu2() || target===game.boss) return 2; - if(player!==target){ - if(target.hp<0&&taos.length+target.hp<=0) return 0; - if(Math.abs(get.attitude(player,target))<1) return 0; + if (target.isZhu2() || target === game.boss) return 2; + if (player !== target) { + if (target.hp < 0 && taos.length + target.hp <= 0) return 0; + if (Math.abs(get.attitude(player, target)) < 1) return 0; } - if(!player.getFriends().length) return 2; + if (!player.getFriends().length) return 2; let tri = _status.event.getTrigger(), - num = game.countPlayer(current=>{ - if(get.attitude(current,target)>0) return current.countCards('hs',i=>get.name(i)==='tao'&&lib.filter.cardEnabled(i,target,'forceEnable')); + num = game.countPlayer((current) => { + if (get.attitude(current, target) > 0) + return current.countCards( + "hs", + (i) => + get.name(i) === "tao" && + lib.filter.cardEnabled(i, target, "forceEnable") + ); }), dis = 1, - t = _status.currentPhase||game.me; - while(t!==target){ - let att = get.attitude(player,t); - if(att<-2) dis++; - else if(att<1) dis += 0.45; + t = _status.currentPhase || game.me; + while (t !== target) { + let att = get.attitude(player, t); + if (att < -2) dis++; + else if (att < 1) dis += 0.45; t = t.next; } - if(mode==='identity'){ - if(tri&&tri.name==='dying'){ - if(target.identity==='fan') { - if(!tri.source&&player!==target || tri.source&&tri.source!==target&&player.getFriends().includes(tri.source.identity)){ - if(num>dis || player===target&&player.countCards('hs',{type:'basic'})>1.6*dis) return 2; + if (mode === "identity") { + if (tri && tri.name === "dying") { + if (target.identity === "fan") { + if ( + (!tri.source && player !== target) || + (tri.source && + tri.source !== target && + player.getFriends().includes(tri.source.identity)) + ) { + if ( + num > dis || + (player === target && + player.countCards("hs", { type: "basic" }) > 1.6 * dis) + ) + return 2; return 0; } - } - else if(tri.source&&tri.source.isZhu&&(target.identity==='zhong'||target.identity==='mingzhong')&& - (tri.source.countCards('he')>2||player===tri.source&&player.hasCard((i)=>i.name!=='tao','he'))) return 2; + } else if ( + tri.source && + tri.source.isZhu && + (target.identity === "zhong" || target.identity === "mingzhong") && + (tri.source.countCards("he") > 2 || + (player === tri.source && + player.hasCard((i) => i.name !== "tao", "he"))) + ) + return 2; //if(player!==target&&!target.isZhu&&target.countCards('hs'){ - return current.identity==='fan'; - }))) return 0; + if (player.identity === "zhu") { + if ( + player.hp <= 1 && + player !== target && + taos + player.countCards("hs", "jiu") <= + Math.min( + dis, + game.countPlayer((current) => { + return current.identity === "fan"; + }) + ) + ) + return 0; } - } - else if(mode==='stone'&&target.isMin()&&player!==target&&tri&&tri.name==='dying'&&player.side===target.side&&tri.source!==target.getEnemy()) return 0; + } else if ( + mode === "stone" && + target.isMin() && + player !== target && + tri && + tri.name === "dying" && + player.side === target.side && + tri.source !== target.getEnemy() + ) + return 0; return 2; - } + }, + }, + tag: { + recover: 1, + save: 1, }, - tag:{ - recover:1, - save:1, - } - } - }, - bagua:{ - fullskin:true, - type:'equip', - subtype:'equip2', - ai:{ - basic:{ - equipValue:7.5 - } }, - skills:['bagua_skill'] }, - jueying:{ - fullskin:true, - type:'equip', - subtype:'equip3', - distance:{globalTo:1}, - }, - dilu:{ - fullskin:true, - type:'equip', - subtype:'equip3', - distance:{globalTo:1}, - }, - zhuahuang:{ - fullskin:true, - type:'equip', - subtype:'equip3', - distance:{globalTo:1}, - }, - chitu:{ - fullskin:true, - type:'equip', - subtype:'equip4', - distance:{globalFrom:-1}, - }, - dawan:{ - fullskin:true, - type:'equip', - subtype:'equip4', - distance:{globalFrom:-1}, - }, - zixin:{ - fullskin:true, - type:'equip', - subtype:'equip4', - distance:{globalFrom:-1}, - }, - zhuge:{ - fullskin:true, - type:'equip', - subtype:'equip1', - ai:{ - order:function(){ - return get.order({name:'sha'})-0.1; + bagua: { + fullskin: true, + type: "equip", + subtype: "equip2", + ai: { + basic: { + equipValue: 7.5, }, - equipValue:function(card,player){ - if(player._zhuge_temp) return 1; - player._zhuge_temp=true; - var result=function(){ - if(!game.hasPlayer(function(current){ - return get.distance(player,current)<=1&&player.canUse('sha',current)&&get.effect(current,{name:'sha'},player,player)>0; - })){ + }, + skills: ["bagua_skill"], + }, + jueying: { + fullskin: true, + type: "equip", + subtype: "equip3", + distance: { globalTo: 1 }, + }, + dilu: { + fullskin: true, + type: "equip", + subtype: "equip3", + distance: { globalTo: 1 }, + }, + zhuahuang: { + fullskin: true, + type: "equip", + subtype: "equip3", + distance: { globalTo: 1 }, + }, + chitu: { + fullskin: true, + type: "equip", + subtype: "equip4", + distance: { globalFrom: -1 }, + }, + dawan: { + fullskin: true, + type: "equip", + subtype: "equip4", + distance: { globalFrom: -1 }, + }, + zixin: { + fullskin: true, + type: "equip", + subtype: "equip4", + distance: { globalFrom: -1 }, + }, + zhuge: { + fullskin: true, + type: "equip", + subtype: "equip1", + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.1; + }, + equipValue: function (card, player) { + if (player._zhuge_temp) return 1; + player._zhuge_temp = true; + var result = (function () { + if ( + !game.hasPlayer(function (current) { + return ( + get.distance(player, current) <= 1 && + player.canUse("sha", current) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 1; } - if(player.hasSha()&&_status.currentPhase==player){ - if(player.getEquip('zhuge')&&player.countUsed('sha')||player.getCardUsable('sha')==0){ + if (player.hasSha() && _status.currentPhase == player) { + if ( + (player.getEquip("zhuge") && player.countUsed("sha")) || + player.getCardUsable("sha") == 0 + ) { return 10; } } - var num=player.countCards('h','sha'); - if(num>1) return 6+num; - return 3+num; - }(); + var num = player.countCards("h", "sha"); + if (num > 1) return 6 + num; + return 3 + num; + })(); delete player._zhuge_temp; return result; }, - basic:{ - equipValue:5 + basic: { + equipValue: 5, }, - tag:{ - valueswap:1 - } - }, - skills:['zhuge_skill'] - }, - cixiong:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['cixiong_skill'] - }, - qinggang:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['qinggang_skill'] - }, - qinglong:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - equipValue:function(card,player){ - return Math.min(2.5+player.countCards('h','sha'),4); + tag: { + valueswap: 1, }, - basic:{ - equipValue:3.5 - } }, - skills:['qinglong_skill','qinglong_guozhan'] + skills: ["zhuge_skill"], }, - zhangba:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - equipValue:function(card,player){ - var num=2.5+player.countCards('h')/3; - return Math.min(num,4); + cixiong: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + ai: { + basic: { + equipValue: 2, }, - basic:{ - equipValue:3.5 - } }, - skills:['zhangba_skill'] + skills: ["cixiong_skill"], }, - guanshi:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - equipValue:function(card,player){ - var num=2.5+(player.countCards('h')+player.countCards('e'))/2.5; - return Math.min(num,5); + qinggang: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + ai: { + basic: { + equipValue: 2, }, - basic:{ - equipValue:4.5, - } }, - skills:['guanshi_skill'] + skills: ["qinggang_skill"], }, - fangtian:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-3}, - ai:{ - basic:{ - equipValue:2.5 - } + qinglong: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + equipValue: function (card, player) { + return Math.min(2.5 + player.countCards("h", "sha"), 4); + }, + basic: { + equipValue: 3.5, + }, }, - skills:['fangtian_skill','fangtian_guozhan'] + skills: ["qinglong_skill", "qinglong_guozhan"], }, - qilin:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-4}, - ai:{ - basic:{ - equipValue:3 - } + zhangba: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + equipValue: function (card, player) { + var num = 2.5 + player.countCards("h") / 3; + return Math.min(num, 4); + }, + basic: { + equipValue: 3.5, + }, }, - skills:['qilin_skill'] + skills: ["zhangba_skill"], }, - wugu:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - cardcolor:'red', - selectTarget:-1, - filterTarget:true, - contentBefore:function(){ - "step 0" - if(!targets.length){ + guanshi: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + equipValue: function (card, player) { + var num = 2.5 + (player.countCards("h") + player.countCards("e")) / 2.5; + return Math.min(num, 5); + }, + basic: { + equipValue: 4.5, + }, + }, + skills: ["guanshi_skill"], + }, + fangtian: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -3 }, + ai: { + basic: { + equipValue: 2.5, + }, + }, + skills: ["fangtian_skill", "fangtian_guozhan"], + }, + qilin: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -4 }, + ai: { + basic: { + equipValue: 3, + }, + }, + skills: ["qilin_skill"], + }, + wugu: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + cardcolor: "red", + selectTarget: -1, + filterTarget: true, + contentBefore: function () { + "step 0"; + if (!targets.length) { event.finish(); return; } - if(card.storage&&card.storage.chooseDirection||get.is.versus()){ - player.chooseControl('顺时针','逆时针',function(event,player){ - if(get.event('isVersus')&&player.next.side==player.side||get.attitude(player,player.next)>get.attitude(player,player.previous)) return '逆时针'; - return '顺时针'; - }).set('prompt','选择'+get.translation(card)+'的结算方向').set('isVersus',get.is.versus()); - } - else{ + if ((card.storage && card.storage.chooseDirection) || get.is.versus()) { + player + .chooseControl("顺时针", "逆时针", function (event, player) { + if ( + (get.event("isVersus") && player.next.side == player.side) || + get.attitude(player, player.next) > get.attitude(player, player.previous) + ) + return "逆时针"; + return "顺时针"; + }) + .set("prompt", "选择" + get.translation(card) + "的结算方向") + .set("isVersus", get.is.versus()); + } else { event.goto(2); } - "step 1" - if(result&&result.control=='顺时针'){ - var evt=event.getParent(),sorter=(_status.currentPhase||player); - evt.fixedSeat=true; + "step 1"; + if (result && result.control == "顺时针") { + var evt = event.getParent(), + sorter = _status.currentPhase || player; + evt.fixedSeat = true; evt.targets.sortBySeat(sorter); evt.targets.reverse(); - if(evt.targets[evt.targets.length-1]==sorter){ + if (evt.targets[evt.targets.length - 1] == sorter) { evt.targets.unshift(evt.targets.pop()); } } - "step 2" + "step 2"; ui.clear(); - var num; - if(event.targets){ - num=event.targets.length; + var cards; + if (card.storage && Array.isArray(card.storage.fixedShownCards)) { + cards = card.storage.fixedShownCards.slice(); + var lose_list = [], + cards2 = []; + cards.forEach((card) => { + var owner = get.owner(card); + if (owner) { + var arr = lose_list.find((i) => i[0] == owner); + if (arr) arr[1].push(card); + else lose_list.push([owner, [card]]); + } else cards2.add(card); + }); + if (lose_list.length) { + lose_list.forEach((list) => { + list[0].$throw(list[1]); + game.log(list[0], "将", list[1], "置于了处理区"); + }); + game.loseAsync({ + lose_list: lose_list, + }).setContent("chooseToCompareLose"); + } + if (cards2.length) game.cardsGotoOrdering(cards2); + game.delayex(); + } else { + var num; + if (event.targets) { + num = event.targets.length; + } else { + num = game.countPlayer(); + } + if (card.storage && typeof card.storage.extraCardsNum == "number") + num += card.storage.extraCardsNum; + cards = get.cards(num); + game.cardsGotoOrdering(cards).relatedEvent = event.getParent(); } - else{ - num=game.countPlayer(); - } - if(card.storage&&typeof card.storage.extraCardsNum=='number') num+=card.storage.extraCardsNum; - var cards=get.cards(num); - game.cardsGotoOrdering(cards).relatedEvent=event.getParent(); - var dialog=ui.create.dialog('五谷丰登',cards,true); + var dialog = ui.create.dialog("五谷丰登", cards, true); _status.dieClose.push(dialog); - dialog.videoId=lib.status.videoId++; - game.addVideo('cardDialog',null,['五谷丰登',get.cardsInfo(cards),dialog.videoId]); - event.getParent().preResult=dialog.videoId; - game.broadcast(function(cards,id){ - var dialog=ui.create.dialog('五谷丰登',cards,true); - _status.dieClose.push(dialog); - dialog.videoId=id; - },cards,dialog.videoId); - game.log(event.card,'亮出了',cards); + dialog.videoId = lib.status.videoId++; + game.addVideo("cardDialog", null, ["五谷丰登", get.cardsInfo(cards), dialog.videoId]); + event.getParent().preResult = dialog.videoId; + game.broadcast( + function (cards, id) { + var dialog = ui.create.dialog("五谷丰登", cards, true); + _status.dieClose.push(dialog); + dialog.videoId = id; + }, + cards, + dialog.videoId + ); + game.log(event.card, "亮出了", cards); }, - content:function(){ - "step 0" - for(var i=0;i1){ - var next=target.chooseButton(true,function(button){ - return get.value(button.link,_status.event.player); + if (event.dialog.buttons.length > 1) { + var next = target.chooseButton(true, function (button) { + return get.value(button.link, _status.event.player); }); - next.set('dialog',event.preResult); - next.set('closeDialog',false); - next.set('dialogdisplay',true); + next.set("dialog", event.preResult); + next.set("closeDialog", false); + next.set("dialogdisplay", true); + } else { + event.directButton = event.dialog.buttons[0]; } - else{ - event.directButton=event.dialog.buttons[0]; - } - "step 1" - var dialog=event.dialog; + "step 1"; + var dialog = event.dialog; var card; - if(event.directButton){ - card=event.directButton.link; - } - else{ - for(var i of dialog.buttons){ - if(i.link==result.links[0]){ - card=i.link; + if (event.directButton) { + card = event.directButton.link; + } else { + for (var i of dialog.buttons) { + if (i.link == result.links[0]) { + card = i.link; break; } } - if(!card) card=event.dialog.buttons[0].link; + if (!card) card = event.dialog.buttons[0].link; } var button; - for(var i=0;i0?0.5:0.7; - } + return (1 - get.distance(sorter, target, "absolute") / game.countPlayer()) * + get.attitude(player, target) > + 0 + ? 0.5 + : 0.7; + }, }, - tag:{ - draw:1, - multitarget:1 - } - } + tag: { + draw: 1, + multitarget: 1, + }, + }, }, - taoyuan:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - cardcolor:'red', - reverseOrder:true, - defaultYingbianEffect:'remove', - filterTarget:function(card,player,target){ + taoyuan: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + cardcolor: "red", + reverseOrder: true, + defaultYingbianEffect: "remove", + filterTarget: function (card, player, target) { //return target.hp{ - if(game.hasPlayer(current=>current.hp<=1&&get.recoverEffect(current,player,_status.event.player)<0)) return 1; + ai: { + basic: { + order: (item, player) => { + if ( + game.hasPlayer( + (current) => + current.hp <= 1 && + get.recoverEffect(current, player, _status.event.player) < 0 + ) + ) + return 1; return 10; }, - useful:[3,1], - value:0, + useful: [3, 1], + value: 0, }, - result:{ - target:function(player,target){ - return (target.hp1){ - next.set('prompt2','共需打出'+event.shaRequired+'张杀'); + }, + nanman: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + defaultYingbianEffect: "remove", + filterTarget: function (card, player, target) { + return target != player; + }, + reverseOrder: true, + content: function () { + "step 0"; + if (typeof event.shaRequired != "number" || !event.shaRequired || event.shaRequired < 0) + event.shaRequired = 1; + if (typeof event.baseDamage != "number") event.baseDamage = 1; + "step 1"; + if (event.directHit) event._result = { bool: false }; + else { + var next = target.chooseToRespond({ name: "sha" }); + if (event.shaRequired > 1) { + next.set("prompt2", "共需打出" + event.shaRequired + "张杀"); } - next.set('ai',function(card){ - var evt=_status.event.getParent(); - if(get.damageEffect(evt.target,evt.player,evt.target)>=0) return 0; - if(evt.player.hasSkillTag('notricksource')) return 0; - if(evt.target.hasSkillTag('notrick')) return 0; + next.set("ai", function (card) { + var evt = _status.event.getParent(); + if (get.damageEffect(evt.target, evt.player, evt.target) >= 0) return 0; + if (evt.player.hasSkillTag("notricksource")) return 0; + if (evt.target.hasSkillTag("notrick")) return 0; return get.order(card); }); - next.autochoose=lib.filter.autoRespondSha; + next.autochoose = lib.filter.autoRespondSha; } - "step 2" - if(result.bool==false){ + "step 2"; + if (result.bool == false) { target.damage(); - } - else{ + } else { event.shaRequired--; - if(event.shaRequired>0) event.goto(1); + if (event.shaRequired > 0) event.goto(1); } }, - ai:{ + ai: { wuxie(target, card, player, viewer, status) { - let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target); + let att = get.attitude(viewer, target), + eff = get.effect(target, card, player, target); if (Math.abs(att) < 1 || status * eff * att >= 0) return 0; - let evt = _status.event.getParent('useCard'), pri = 1, bonus = player.hasSkillTag('damageBonus', true, { - target: target, - card: card - }), damage = 1, isZhu = function (tar) { - return tar.isZhu || tar === game.boss || tar === game.trueZhu || tar === game.falseZhu; - }, canSha = function (tar, blur) { - let known = tar.getKnownCards(viewer); - if (!blur) return known.some(card => { - let name = get.name(card, tar); - return (name === 'sha' || name === 'hufu' || name === 'yuchanqian') && lib.filter.cardRespondable(card, tar); - }); - if (tar.countCards('hs', i => !known.includes(i)) > 4.67 - 2 * tar.hp / tar.maxHp) return true; - if (!tar.hasSkillTag('respondSha', true, 'respond', true)) return false; - if (tar.hp <= damage) return false; - if (tar.hp <= damage + 1) return isZhu(tar); - return true; - }, self = false; + let evt = _status.event.getParent("useCard"), + pri = 1, + bonus = player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }), + damage = 1, + isZhu = function (tar) { + return ( + tar.isZhu || + tar === game.boss || + tar === game.trueZhu || + tar === game.falseZhu + ); + }, + canSha = function (tar, blur) { + let known = tar.getKnownCards(viewer); + if (!blur) + return known.some((card) => { + let name = get.name(card, tar); + return ( + (name === "sha" || name === "hufu" || name === "yuchanqian") && + lib.filter.cardRespondable(card, tar) + ); + }); + if ( + tar.countCards("hs", (i) => !known.includes(i)) > + 4.67 - (2 * tar.hp) / tar.maxHp + ) + return true; + if (!tar.hasSkillTag("respondSha", true, "respond", true)) return false; + if (tar.hp <= damage) return false; + if (tar.hp <= damage + 1) return isZhu(tar); + return true; + }, + self = false; if (canSha(target)) return 0; - if (bonus && !viewer.hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; - if ((viewer.hp <= damage || viewer.hp <= damage + 1 && isZhu(viewer)) && !canSha(viewer)) { + if ( + bonus && + !viewer.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; + if ( + (viewer.hp <= damage || (viewer.hp <= damage + 1 && isZhu(viewer))) && + !canSha(viewer) + ) { if (viewer === target) return status; let fv = true; - if (evt && evt.targets) for (let i of evt.targets) { - if (fv) { - if (target === i) fv = false; - continue; + if (evt && evt.targets) + for (let i of evt.targets) { + if (fv) { + if (target === i) fv = false; + continue; + } + if (viewer == i) { + if (isZhu(viewer)) return 0; + self = true; + break; + } } - if (viewer == i) { - if (isZhu(viewer)) return 0; - self = true; - break; - } - } } let maySha = canSha(target, true); - if (bonus && !target.hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; + if ( + bonus && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; else damage = 1; if (isZhu(target)) { if (eff < 0) { - if (target.hp <= damage + 1 || !maySha && target.hp <= damage + 2) return 1; + if (target.hp <= damage + 1 || (!maySha && target.hp <= damage + 2)) return 1; if (maySha && target.hp > damage + 2) return 0; else if (maySha || target.hp > damage + 2) pri = 3; else pri = 4; - } - else if (target.hp > damage + 1) pri = 2; + } else if (target.hp > damage + 1) pri = 2; else return 0; - } - else if (self) return 0; + } else if (self) return 0; else if (eff < 0) { if (!maySha && target.hp <= damage) pri = 5; else if (maySha) return 0; else if (target.hp > damage + 1) pri = 2; else if (target.hp === damage + 1) pri = 3; else pri = 4; - } - else if (target.hp <= damage) return 0; + } else if (target.hp <= damage) return 0; let find = false; - if (evt && evt.targets) for (let i = 0; i < evt.targets.length; i++) { - if (!find) { - if (evt.targets[i] === target) find = true; - continue; - } - let att1 = get.attitude(viewer, evt.targets[i]), eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), temp = 1; - if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canSha(evt.targets[i])) continue; - maySha = canSha(evt.targets[i], true); - if (bonus && !evt.targets[i].hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; - else damage = 1; - if (isZhu(evt.targets[i])) { - if (eff1 < 0) { - if (evt.targets[i].hp <= damage + 1 || !maySha && evt.targets[i].hp <= damage + 2) return 0; - if (maySha && evt.targets[i].hp > damage + 2) continue; - if (maySha || evt.targets[i].hp > damage + 2) temp = 3; - else temp = 4; + if (evt && evt.targets) + for (let i = 0; i < evt.targets.length; i++) { + if (!find) { + if (evt.targets[i] === target) find = true; + continue; } - else if (evt.targets[i].hp > damage + 1) temp = 2; - else continue; + let att1 = get.attitude(viewer, evt.targets[i]), + eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), + temp = 1; + if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canSha(evt.targets[i])) + continue; + maySha = canSha(evt.targets[i], true); + if ( + bonus && + !evt.targets[i].hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; + else damage = 1; + if (isZhu(evt.targets[i])) { + if (eff1 < 0) { + if ( + evt.targets[i].hp <= damage + 1 || + (!maySha && evt.targets[i].hp <= damage + 2) + ) + return 0; + if (maySha && evt.targets[i].hp > damage + 2) continue; + if (maySha || evt.targets[i].hp > damage + 2) temp = 3; + else temp = 4; + } else if (evt.targets[i].hp > damage + 1) temp = 2; + else continue; + } else if (eff1 < 0) { + if (!maySha && evt.targets[i].hp <= damage) temp = 5; + else if (maySha) continue; + else if (evt.targets[i].hp > damage + 1) temp = 2; + else if (evt.targets[i].hp === damage + 1) temp = 3; + else temp = 4; + } else if (evt.targets[i].hp > damage + 1) temp = 2; + if (temp > pri) return 0; } - else if (eff1 < 0) { - if (!maySha && evt.targets[i].hp <= damage) temp = 5; - else if (maySha) continue; - else if (evt.targets[i].hp > damage + 1) temp = 2; - else if (evt.targets[i].hp === damage + 1) temp = 3; - else temp = 4; - } - else if (evt.targets[i].hp > damage + 1) temp = 2; - if (temp > pri) return 0; - } return 1; }, basic: { order: 9, useful: [5, 1], - value: 5 + value: 5, }, result: { player(player, target) { - if (player._nanman_temp || player.hasSkillTag('jueqing', false, target)) return 0; + if (player._nanman_temp || player.hasSkillTag("jueqing", false, target)) return 0; player._nanman_temp = true; - let eff = get.effect(target, new lib.element.VCard({ name: 'nanman' }), player, target); + let eff = get.effect( + target, + new lib.element.VCard({ name: "nanman" }), + player, + target + ); delete player._nanman_temp; if (eff >= 0) return 0; - if (target.hp > 2 || target.hp > 1 && !target.isZhu && target != game.boss && target != game.trueZhu && target != game.falseZhu) return 0; - if (target.hp > 1 && target.hasSkillTag('respondSha', true, 'respond', true)) return 0; + if ( + target.hp > 2 || + (target.hp > 1 && + !target.isZhu && + target != game.boss && + target != game.trueZhu && + target != game.falseZhu) + ) + return 0; + if (target.hp > 1 && target.hasSkillTag("respondSha", true, "respond", true)) + return 0; let known = target.getKnownCards(player); - if (known.some(card => { - let name = get.name(card, target); - if (name === 'sha' || name === 'hufu' || name === 'yuchanqian') return lib.filter.cardRespondable(card, target); - if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); - })) return 0; - if (target.hp > 1 || target.countCards('hs', i => !known.includes(i)) > 4.67 - 2 * target.hp / target.maxHp) return 0; - let res = 0, att = get.sgnAttitude(player, target); - res -= att * (0.8 * target.countCards('hs') + 0.6 * target.countCards('e') + 3.6); - if (get.mode() === 'identity' && target.identity === 'fan') res += 2.4; - if (get.mode() === 'guozhan' && player.identity !== 'ye' && player.identity === target.identity || - get.mode() === 'identity' && player.identity === 'zhu' && (target.identity === 'zhong' || target.identity === 'mingzhong')) res -= 0.8 * player.countCards('he'); + if ( + known.some((card) => { + let name = get.name(card, target); + if (name === "sha" || name === "hufu" || name === "yuchanqian") + return lib.filter.cardRespondable(card, target); + if (name === "wuxie") + return lib.filter.cardEnabled(card, target, "forceEnable"); + }) + ) + return 0; + if ( + target.hp > 1 || + target.countCards("hs", (i) => !known.includes(i)) > + 4.67 - (2 * target.hp) / target.maxHp + ) + return 0; + let res = 0, + att = get.sgnAttitude(player, target); + res -= att * (0.8 * target.countCards("hs") + 0.6 * target.countCards("e") + 3.6); + if (get.mode() === "identity" && target.identity === "fan") res += 2.4; + if ( + (get.mode() === "guozhan" && + player.identity !== "ye" && + player.identity === target.identity) || + (get.mode() === "identity" && + player.identity === "zhu" && + (target.identity === "zhong" || target.identity === "mingzhong")) + ) + res -= 0.8 * player.countCards("he"); return res; }, target(player, target) { - let zhu = (get.mode() === 'identity' && target.isZhu) || target.identity === 'zhu'; - if (!lib.filter.cardRespondable({ name: 'sha' }, target)) { + let zhu = + (get.mode() === "identity" && target.isZhu) || target.identity === "zhu"; + if (!lib.filter.cardRespondable({ name: "sha" }, target)) { if (zhu) { if (target.hp < 2) return -99; if (target.hp === 2) return -3.6; @@ -1132,12 +1476,17 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return -2; } let known = target.getKnownCards(player); - if (known.some(card => { - let name = get.name(card, target); - if (name === 'sha' || name === 'hufu' || name === 'yuchanqian') return lib.filter.cardRespondable(card, target); - if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); - })) return -1.2; - let nh = target.countCards('hs', i => !known.includes(i)); + if ( + known.some((card) => { + let name = get.name(card, target); + if (name === "sha" || name === "hufu" || name === "yuchanqian") + return lib.filter.cardRespondable(card, target); + if (name === "wuxie") + return lib.filter.cardEnabled(card, target, "forceEnable"); + }) + ) + return -1.2; + let nh = target.countCards("hs", (i) => !known.includes(i)); if (zhu && target.hp <= 1) { if (nh === 0) return -99; if (nh === 1) return -60; @@ -1146,197 +1495,274 @@ game.import('card',function(lib,game,ui,get,ai,_status){ if (nh === 4) return -8; return -5; } - if (target.hasSkillTag('respondSha', true, 'respond', true)) return -1.35; + if (target.hasSkillTag("respondSha", true, "respond", true)) return -1.35; if (!nh) return -2; if (nh === 1) return -1.8; return -1.5; - } + }, }, tag: { respond: 1, respondSha: 1, damage: 1, multitarget: 1, - multineg: 1 - } - } - }, - wanjian:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - reverseOrder:true, - defaultYingbianEffect:'remove', - filterTarget:function(card,player,target){ - return target!=player; + multineg: 1, + }, }, - content:function(){ - "step 0" - if(typeof event.shanRequired!='number'||!event.shanRequired||event.shanRequired<0) event.shanRequired=1; - if(typeof event.baseDamage!='number') event.baseDamage=1; - "step 1" - if(event.directHit) event._result={bool:false}; - else{ - var next=target.chooseToRespond({name:'shan'}); - if(event.shanRequired>1){ - next.set('prompt2','共需打出'+event.shanRequired+'张闪'); + }, + wanjian: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + reverseOrder: true, + defaultYingbianEffect: "remove", + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + if ( + typeof event.shanRequired != "number" || + !event.shanRequired || + event.shanRequired < 0 + ) + event.shanRequired = 1; + if (typeof event.baseDamage != "number") event.baseDamage = 1; + "step 1"; + if (event.directHit) event._result = { bool: false }; + else { + var next = target.chooseToRespond({ name: "shan" }); + if (event.shanRequired > 1) { + next.set("prompt2", "共需打出" + event.shanRequired + "张闪"); } - next.set('ai',function(card){ - var evt=_status.event.getParent(); - if(get.damageEffect(evt.target,evt.player,evt.target)>=0) return 0; - if(evt.player.hasSkillTag('notricksource')) return 0; - if(evt.target.hasSkillTag('notrick')) return 0; - if(evt.target.hasSkillTag('noShan')){ + next.set("ai", function (card) { + var evt = _status.event.getParent(); + if (get.damageEffect(evt.target, evt.player, evt.target) >= 0) return 0; + if (evt.player.hasSkillTag("notricksource")) return 0; + if (evt.target.hasSkillTag("notrick")) return 0; + if (evt.target.hasSkillTag("noShan")) { return -1; } - return get.order(card); + return get.order(card); }); - next.autochoose=lib.filter.autoRespondShan; + next.autochoose = lib.filter.autoRespondShan; } - "step 2" - if(result.bool==false){ + "step 2"; + if (result.bool == false) { target.damage(); - } - else{ + } else { event.shanRequired--; - if(event.shanRequired>0) event.goto(1); + if (event.shanRequired > 0) event.goto(1); } }, - ai:{ + ai: { wuxie(target, card, player, viewer, status) { - let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target); + let att = get.attitude(viewer, target), + eff = get.effect(target, card, player, target); if (Math.abs(att) < 1 || status * eff * att >= 0) return 0; - let evt = _status.event.getParent('useCard'), pri = 1, bonus = player.hasSkillTag('damageBonus', true, { - target: target, - card: card - }), damage = 1, isZhu = function (tar) { - return tar.isZhu || tar === game.boss || tar === game.trueZhu || tar === game.falseZhu; - }, canShan = function (tar, blur) { - let known = tar.getKnownCards(viewer); - if (!blur) return known.some(card => { - let name = get.name(card, tar); - return (name === 'shan' || name === 'hufu') && lib.filter.cardRespondable(card, tar); - }); - if (tar.countCards('hs', i => !known.includes(i)) > 3.67 - 2 * tar.hp / tar.maxHp) return true; - if (!tar.hasSkillTag('respondShan', true, 'respond', true)) return false; - if (tar.hp <= damage) return false; - if (tar.hp <= damage + 1) return isZhu(tar); - return true; - }, self = false; + let evt = _status.event.getParent("useCard"), + pri = 1, + bonus = player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }), + damage = 1, + isZhu = function (tar) { + return ( + tar.isZhu || + tar === game.boss || + tar === game.trueZhu || + tar === game.falseZhu + ); + }, + canShan = function (tar, blur) { + let known = tar.getKnownCards(viewer); + if (!blur) + return known.some((card) => { + let name = get.name(card, tar); + return ( + (name === "shan" || name === "hufu") && + lib.filter.cardRespondable(card, tar) + ); + }); + if ( + tar.countCards("hs", (i) => !known.includes(i)) > + 3.67 - (2 * tar.hp) / tar.maxHp + ) + return true; + if (!tar.hasSkillTag("respondShan", true, "respond", true)) return false; + if (tar.hp <= damage) return false; + if (tar.hp <= damage + 1) return isZhu(tar); + return true; + }, + self = false; if (canShan(target)) return 0; - if (bonus && !viewer.hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; - if ((viewer.hp <= damage || viewer.hp <= damage + 1 && isZhu(viewer)) && !canShan(viewer)) { + if ( + bonus && + !viewer.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; + if ( + (viewer.hp <= damage || (viewer.hp <= damage + 1 && isZhu(viewer))) && + !canShan(viewer) + ) { if (viewer === target) return status; let fv = true; - if (evt && evt.targets) for (let i of evt.targets) { - if (fv) { - if (target === i) fv = false; - continue; + if (evt && evt.targets) + for (let i of evt.targets) { + if (fv) { + if (target === i) fv = false; + continue; + } + if (viewer == i) { + if (isZhu(viewer)) return 0; + self = true; + break; + } } - if (viewer == i) { - if (isZhu(viewer)) return 0; - self = true; - break; - } - } } let mayShan = canShan(target, true); - if (bonus && !target.hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; + if ( + bonus && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; else damage = 1; if (isZhu(target)) { if (eff < 0) { - if (target.hp <= damage + 1 || !mayShan && target.hp <= damage + 2) return 1; + if (target.hp <= damage + 1 || (!mayShan && target.hp <= damage + 2)) + return 1; if (mayShan && target.hp > damage + 2) return 0; else if (mayShan || target.hp > damage + 2) pri = 3; else pri = 4; - } - else if (target.hp > damage + 1) pri = 2; + } else if (target.hp > damage + 1) pri = 2; else return 0; - } - else if (self) return 0; + } else if (self) return 0; else if (eff < 0) { if (!mayShan && target.hp <= damage) pri = 5; else if (mayShan) return 0; else if (target.hp > damage + 1) pri = 2; else if (target.hp === damage + 1) pri = 3; else pri = 4; - } - else if (target.hp <= damage) return 0; + } else if (target.hp <= damage) return 0; let find = false; - if (evt && evt.targets) for (let i = 0; i < evt.targets.length; i++) { - if (!find) { - if (evt.targets[i] === target) find = true; - continue; - } - let att1 = get.attitude(viewer, evt.targets[i]), eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), temp = 1; - if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canShan(evt.targets[i])) continue; - mayShan = canShan(evt.targets[i], true); - if (bonus && !evt.targets[i].hasSkillTag('filterDamage', null, { - player: player, - card: card - })) damage = 2; - else damage = 1; - if (isZhu(evt.targets[i])) { - if (eff1 < 0) { - if (evt.targets[i].hp <= damage + 1 || !mayShan && evt.targets[i].hp <= damage + 2) return 0; - if (mayShan && evt.targets[i].hp > damage + 2) continue; - if (mayShan || evt.targets[i].hp > damage + 2) temp = 3; - else temp = 4; + if (evt && evt.targets) + for (let i = 0; i < evt.targets.length; i++) { + if (!find) { + if (evt.targets[i] === target) find = true; + continue; } - else if (evt.targets[i].hp > damage + 1) temp = 2; - else continue; + let att1 = get.attitude(viewer, evt.targets[i]), + eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), + temp = 1; + if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canShan(evt.targets[i])) + continue; + mayShan = canShan(evt.targets[i], true); + if ( + bonus && + !evt.targets[i].hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + damage = 2; + else damage = 1; + if (isZhu(evt.targets[i])) { + if (eff1 < 0) { + if ( + evt.targets[i].hp <= damage + 1 || + (!mayShan && evt.targets[i].hp <= damage + 2) + ) + return 0; + if (mayShan && evt.targets[i].hp > damage + 2) continue; + if (mayShan || evt.targets[i].hp > damage + 2) temp = 3; + else temp = 4; + } else if (evt.targets[i].hp > damage + 1) temp = 2; + else continue; + } else if (eff1 < 0) { + if (!mayShan && evt.targets[i].hp <= damage) temp = 5; + else if (mayShan) continue; + else if (evt.targets[i].hp > damage + 1) temp = 2; + else if (evt.targets[i].hp === damage + 1) temp = 3; + else temp = 4; + } else if (evt.targets[i].hp > damage + 1) temp = 2; + if (temp > pri) return 0; } - else if (eff1 < 0) { - if (!mayShan && evt.targets[i].hp <= damage) temp = 5; - else if (mayShan) continue; - else if (evt.targets[i].hp > damage + 1) temp = 2; - else if (evt.targets[i].hp === damage + 1) temp = 3; - else temp = 4; - } - else if (evt.targets[i].hp > damage + 1) temp = 2; - if (temp > pri) return 0; - } return 1; }, basic: { order: 9, useful: 1, - value: 5 + value: 5, }, result: { player(player, target) { - if (player._wanjian_temp || player.hasSkillTag('jueqing', false, target)) return 0; + if (player._wanjian_temp || player.hasSkillTag("jueqing", false, target)) + return 0; player._wanjian_temp = true; - let eff = get.effect(target, new lib.element.VCard({ name: 'wanjian' }), player, target); + let eff = get.effect( + target, + new lib.element.VCard({ name: "wanjian" }), + player, + target + ); delete player._wanjian_temp; if (eff >= 0) return 0; - if (target.hp > 2 || target.hp > 1 && !target.isZhu && target != game.boss && target != game.trueZhu && target != game.falseZhu) return 0; - if (target.hp > 1 && target.hasSkillTag('respondShan', true, 'respond', true)) return 0; + if ( + target.hp > 2 || + (target.hp > 1 && + !target.isZhu && + target != game.boss && + target != game.trueZhu && + target != game.falseZhu) + ) + return 0; + if (target.hp > 1 && target.hasSkillTag("respondShan", true, "respond", true)) + return 0; let known = target.getKnownCards(player); - if (known.some(card => { - let name = get.name(card, target); - if (name === 'shan' || name === 'hufu') return lib.filter.cardRespondable(card, target); - if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); - })) return 0; - if (target.hp > 1 || target.countCards('hs', i => !known.includes(i)) > 3.67 - 2 * target.hp / target.maxHp) return 0; - let res = 0, att = get.sgnAttitude(player, target); - res -= att * (0.8 * target.countCards('hs') + 0.6 * target.countCards('e') + 3.6); - if (get.mode() === 'identity' && target.identity === 'fan') res += 2.4; - if (get.mode() === 'guozhan' && player.identity !== 'ye' && player.identity === target.identity || - get.mode() === 'identity' && player.identity === 'zhu' && (target.identity === 'zhong' || target.identity === 'mingzhong')) res -= 0.8 * player.countCards('he'); + if ( + known.some((card) => { + let name = get.name(card, target); + if (name === "shan" || name === "hufu") + return lib.filter.cardRespondable(card, target); + if (name === "wuxie") + return lib.filter.cardEnabled(card, target, "forceEnable"); + }) + ) + return 0; + if ( + target.hp > 1 || + target.countCards("hs", (i) => !known.includes(i)) > + 3.67 - (2 * target.hp) / target.maxHp + ) + return 0; + let res = 0, + att = get.sgnAttitude(player, target); + res -= att * (0.8 * target.countCards("hs") + 0.6 * target.countCards("e") + 3.6); + if (get.mode() === "identity" && target.identity === "fan") res += 2.4; + if ( + (get.mode() === "guozhan" && + player.identity !== "ye" && + player.identity === target.identity) || + (get.mode() === "identity" && + player.identity === "zhu" && + (target.identity === "zhong" || target.identity === "mingzhong")) + ) + res -= 0.8 * player.countCards("he"); return res; }, target(player, target) { - let zhu = (get.mode() === 'identity' && target.isZhu) || target.identity === 'zhu'; - if (!lib.filter.cardRespondable({ name: 'shan' }, target)) { + let zhu = + (get.mode() === "identity" && target.isZhu) || target.identity === "zhu"; + if (!lib.filter.cardRespondable({ name: "shan" }, target)) { if (zhu) { if (target.hp < 2) return -99; if (target.hp === 2) return -3.6; @@ -1344,12 +1770,17 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return -2; } let known = target.getKnownCards(player); - if (known.some(card => { - let name = get.name(card, target); - if (name === 'shan' || name === 'hufu') return lib.filter.cardRespondable(card, target); - if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); - })) return -1.2; - let nh = target.countCards('hs', i => !known.includes(i)); + if ( + known.some((card) => { + let name = get.name(card, target); + if (name === "shan" || name === "hufu") + return lib.filter.cardRespondable(card, target); + if (name === "wuxie") + return lib.filter.cardEnabled(card, target, "forceEnable"); + }) + ) + return -1.2; + let nh = target.countCards("hs", (i) => !known.includes(i)); if (zhu && target.hp <= 1) { if (nh === 0) return -99; if (nh === 1) return -60; @@ -1357,186 +1788,218 @@ game.import('card',function(lib,game,ui,get,ai,_status){ if (nh === 3) return -8; return -5; } - if (target.hasSkillTag('respondShan', true, 'respond', true)) return -1.35; + if (target.hasSkillTag("respondShan", true, "respond", true)) return -1.35; if (!nh) return -2; if (nh === 1) return -1.65; return -1.5; - } + }, }, tag: { respond: 1, respondShan: 1, damage: 1, multitarget: 1, - multineg: 1 - } - } - }, - wuzhong:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - cardcolor:'red', - toself:true, - filterTarget:function(card,player,target){ - return target==player; + multineg: 1, + }, }, - modTarget:true, - content:function(){ - if(get.is.versus()){ - if(game.friend.includes(target)){ - if(game.friend.lengthgame.enemy.length){ - target.draw(3);return; + } else { + if (game.friend.length > game.enemy.length) { + target.draw(3); + return; } } } target.draw(2); }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.mode()=='guozhan'){ - if(!_status._aozhan){ - if(!player.isMajor()){ - if(!viewer.isMajor()) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.mode() == "guozhan") { + if (!_status._aozhan) { + if (!player.isMajor()) { + if (!viewer.isMajor()) return 0; } } } }, - basic:{ - order:7.2, - useful:4.5, - value:9.2 + basic: { + order: 7.2, + useful: 4.5, + value: 9.2, }, - result:{ - target:2, + result: { + target: 2, + }, + tag: { + draw: 2, }, - tag:{ - draw:2 - } - } - }, - juedou:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - defaultYingbianEffect:'hit', - filterTarget:function(card,player,target){ - return target!=player; }, - content:function(){ - "step 0" - if(event.turn==undefined) event.turn=target; - if(typeof event.baseDamage!='number') event.baseDamage=1; - if(typeof event.extraDamage!='number'){ - event.extraDamage=0; + }, + juedou: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + defaultYingbianEffect: "hit", + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + if (event.turn == undefined) event.turn = target; + if (typeof event.baseDamage != "number") event.baseDamage = 1; + if (typeof event.extraDamage != "number") { + event.extraDamage = 0; } - if(!event.shaReq) event.shaReq={}; - if(typeof event.shaReq[player.playerid]!='number') event.shaReq[player.playerid]=1; - if(typeof event.shaReq[target.playerid]!='number') event.shaReq[target.playerid]=1; - event.playerCards=[]; - event.targetCards=[]; - "step 1" - event.trigger('juedou'); - event.shaRequired=event.shaReq[event.turn.playerid]; - "step 2" - if(event.directHit){ - event._result={bool:false}; - } - else{ - var next=event.turn.chooseToRespond({name:'sha'}); - if(event.shaRequired>1) next.set('prompt2','共需打出'+event.shaRequired+'张杀'); - next.set('ai',function(card){ - let event=_status.event,player=event.splayer,target=event.starget; - if(player.hasSkillTag('notricksource')||target.hasSkillTag('notrick')) return 0; - if(event.shaRequired>1&&player.countCards('h','sha')=0||player.hasSkill('naman')) return -1; - if(get.attitude(target,player)<=0||event.player.hp<=1&&_status.event.tdamage<_status.event.pdamage){ + if (!event.shaReq) event.shaReq = {}; + if (typeof event.shaReq[player.playerid] != "number") event.shaReq[player.playerid] = 1; + if (typeof event.shaReq[target.playerid] != "number") event.shaReq[target.playerid] = 1; + event.playerCards = []; + event.targetCards = []; + "step 1"; + event.trigger("juedou"); + event.shaRequired = event.shaReq[event.turn.playerid]; + "step 2"; + if (event.directHit) { + event._result = { bool: false }; + } else { + var next = event.turn.chooseToRespond({ name: "sha" }); + if (event.shaRequired > 1) + next.set("prompt2", "共需打出" + event.shaRequired + "张杀"); + next.set("ai", function (card) { + let event = _status.event, + player = event.splayer, + target = event.starget; + if (player.hasSkillTag("notricksource") || target.hasSkillTag("notrick")) + return 0; + if (event.shaRequired > 1 && player.countCards("h", "sha") < event.shaRequired) + return 0; + if (event.player === target) { + if (_status.event.tdamage >= 0 || player.hasSkill("naman")) return -1; + if ( + get.attitude(target, player) <= 0 || + (event.player.hp <= 1 && _status.event.tdamage < _status.event.pdamage) + ) { return get.order(card); } return -1; - } - else{ - if(_status.event.pdamage>=0||target.hasSkill('naman')) return -1; - if(get.attitude(player,target)<=0||event.player.hp<=1&&_status.event.tdamage>_status.event.pdamage){ + } else { + if (_status.event.pdamage >= 0 || target.hasSkill("naman")) return -1; + if ( + get.attitude(player, target) <= 0 || + (event.player.hp <= 1 && _status.event.tdamage > _status.event.pdamage) + ) { return get.order(card); } return -1; } }); - next.set('splayer',player); - next.set('starget',target); - next.set('pdamage',get.damageEffect(player,target,event.turn)); - next.set('tdamage',get.damageEffect(target,player,event.turn)); - next.set('shaRequired',event.shaRequired); - next.autochoose=lib.filter.autoRespondSha; - if(event.turn==target){ - next.source=player; - } - else{ - next.source=target; + next.set("splayer", player); + next.set("starget", target); + next.set("pdamage", get.damageEffect(player, target, event.turn)); + next.set("tdamage", get.damageEffect(target, player, event.turn)); + next.set("shaRequired", event.shaRequired); + next.autochoose = lib.filter.autoRespondSha; + if (event.turn == target) { + next.source = player; + } else { + next.source = target; } } - "step 3" - if(result.bool){ + "step 3"; + if (result.bool) { event.shaRequired--; - if(event.turn==target){ - if(result.cards) event.targetCards.addArray(result.cards); - if(event.shaRequired>0) event.goto(2); - else{ - event.turn=player; + if (event.turn == target) { + if (result.cards) event.targetCards.addArray(result.cards); + if (event.shaRequired > 0) event.goto(2); + else { + event.turn = player; + event.goto(1); + } + } else { + if (result.cards) event.playerCards.addArray(result.cards); + if (event.shaRequired > 0) event.goto(2); + else { + event.turn = target; event.goto(1); } } - else{ - if(result.cards) event.playerCards.addArray(result.cards); - if(event.shaRequired>0) event.goto(2); - else{ - event.turn=target; - event.goto(1); - } - } - } - else{ - if(event.turn==target){ + } else { + if (event.turn == target) { target.damage(); - } - else{ + } else { player.damage(target); } } - event._result={}; + event._result = {}; }, - ai:{ - wuxie:function(target,card,player,viewer,status){ - if(player===game.me&&get.attitude(viewer,player._trueMe||player)>0) return 0; - if(status*get.attitude(viewer,target)*get.effect(target,card,player,target)>=0) return 0; + ai: { + wuxie: function (target, card, player, viewer, status) { + if (player === game.me && get.attitude(viewer, player._trueMe || player) > 0) + return 0; + if ( + status * + get.attitude(viewer, target) * + get.effect(target, card, player, target) >= + 0 + ) + return 0; }, - basic:{ - order:5, - useful:1, - value:5.5 + basic: { + order: 5, + useful: 1, + value: 5.5, }, - result:{ + result: { player(player, target, card) { - if (player.hasSkillTag('directHit_ai', true, { - target: target, - card: card - }, true)) return 0; + if ( + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) + return 0; if (get.damageEffect(target, player, target) >= 0) return 0; - let pd = get.damageEffect(player, target, player), att = get.attitude(player, target); + let pd = get.damageEffect(player, target, player), + att = get.attitude(player, target); if (att > 0 && get.damageEffect(target, player, player) > pd) return 0; - let ts = target.mayHaveSha(player, 'respond', null, 'count'), ps = player.mayHaveSha(player, 'respond', player.getCards('h', i => { - return card === i || card.cards && card.cards.includes(i) || ui.selected.cards.includes(i); - }), 'count'); + let ts = target.mayHaveSha(player, "respond", null, "count"), + ps = player.mayHaveSha( + player, + "respond", + player.getCards("h", (i) => { + return ( + card === i || + (card.cards && card.cards.includes(i)) || + ui.selected.cards.includes(i) + ); + }), + "count" + ); if (ts < 1 && ts << 3 < Math.pow(player.hp, 2)) return 0; if (att > 0) { if (ts < 1) return 0; @@ -1547,672 +2010,781 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return -2 - ts; }, target(player, target, card) { - if (player.hasSkillTag('directHit_ai', true, { - target: target, - card: card - }, true)) return -2; + if ( + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) + return -2; let td = get.damageEffect(target, player, target); if (td >= 0) return td / get.attitude(target, target); - let pd = get.damageEffect(player, target, player), att = get.attitude(player, target); + let pd = get.damageEffect(player, target, player), + att = get.attitude(player, target); if (att > 0 && get.damageEffect(target, player, player) > pd) return -2; - let ts = target.mayHaveSha(player, 'respond', null, 'count'), ps = player.mayHaveSha(player, 'respond', player.getCards('h', i => { - return card === i || card.cards && card.cards.includes(i) || ui.selected.cards.includes(i); - }), 'count'); + let ts = target.mayHaveSha(player, "respond", null, "count"), + ps = player.mayHaveSha( + player, + "respond", + player.getCards("h", (i) => { + return ( + card === i || + (card.cards && card.cards.includes(i)) || + ui.selected.cards.includes(i) + ); + }), + "count" + ); if (ts < 1) return -1.5; if (att > 0) return -2; if (ts - ps < 1) return -2 - ts; if (pd >= 0) return -1; return -ts; - } + }, }, - tag:{ - respond:2, - respondSha:2, - damage:1, - } - } + tag: { + respond: 2, + respondSha: 2, + damage: 1, + }, + }, }, - shunshou:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - range:{global:1}, - selectTarget:1, - postAi:function(targets){ - return targets.length==1&&targets[0].countCards('j'); + shunshou: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + range: { global: 1 }, + selectTarget: 1, + postAi: function (targets) { + return targets.length == 1 && targets[0].countCards("j"); }, - filterTarget:function(card,player,target){ - if(player==target) return false; - return target.hasCard(card=>lib.filter.canBeGained(card,player,target),get.is.single()?'he':'hej'); + filterTarget: function (card, player, target) { + if (player == target) return false; + return target.hasCard( + (card) => lib.filter.canBeGained(card, player, target), + get.is.single() ? "he" : "hej" + ); }, - content:function(){ - let pos=get.is.single()?'he':'hej'; - if(target.countGainableCards(player,pos)) player.gainPlayerCard(pos, target, true).set('target',target).set('ai',lib.card.shunshou.ai.button); + content: function () { + let pos = get.is.single() ? "he" : "hej"; + if (target.countGainableCards(player, pos)) + player + .gainPlayerCard(pos, target, true) + .set("target", target) + .set("complexSelect", false) + .set("ai", lib.card.shunshou.ai.button); }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,player._trueMe||player)>0) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.attitude(viewer, player._trueMe || player) > 0) return 0; }, - basic:{ - order:7.5, - useful:(card,i)=>8/(3+i), - value:(card,player)=>{ - let max=0; - game.countPlayer(cur=>{ - max=Math.max(max,lib.card.shunshou.ai.result.target(player,cur)*get.attitude(player,cur)); + basic: { + order: 7.5, + useful: (card, i) => 8 / (3 + i), + value: (card, player) => { + let max = 0; + game.countPlayer((cur) => { + max = Math.max( + max, + lib.card.shunshou.ai.result.target(player, cur) * + get.attitude(player, cur) + ); }); - if(max<=0) return 2; - return 0.53*max; - } + if (max <= 0) return 2; + return 0.53 * max; + }, }, - button:(button)=>{ - let player = _status.event.player, target = _status.event.target; - if(!lib.filter.canBeGained(button.link,player,target)) return 0; + button: (button) => { + let player = _status.event.player, + target = _status.event.target; + if (!lib.filter.canBeGained(button.link, player, target)) return 0; let att = get.attitude(player, target), - val = get.value(button.link,player)/60, + val = get.value(button.link, player) / 60, btv = get.buttonValue(button), pos = get.position(button.link), name = get.name(button.link); - if(pos=='j'){ - if(name=='lebu'){ - let needs=target.needsToDiscard(2); - btv*=1.08+0.2*needs; - } - else if(name=='shandian'||name=='fulei'||name=='plague') btv/=2; + if (pos == "j") { + if (name == "lebu") { + let needs = target.needsToDiscard(2); + btv *= 1.08 + 0.2 * needs; + } else if (name == "shandian" || name == "fulei" || name == "plague") btv /= 2; } - if(get.attitude(player,get.owner(button.link))>0) btv=-btv; - if(pos!='e'){ - if(pos=='h'&&!player.hasSkillTag('viewHandcard',null,target,true)) return btv+0.1; - return btv+val; + if (get.attitude(player, get.owner(button.link)) > 0) btv = -btv; + if (pos != "e") { + if (pos == "h" && !player.hasSkillTag("viewHandcard", null, target, true)) + return btv + 0.1; + return btv + val; } let sub = get.subtype(button.link); - if(sub=='equip1') return btv*Math.min(3.6,target.hp)/3; - if(sub=='equip2'){ - if(name=='baiyin'&&pos=='e'&&target.isDamaged()){ - let by=3-0.6*Math.min(5,target.hp); - return get.sgn(get.recoverEffect(target,player,player))*by; + if (sub == "equip1") return (btv * Math.min(3.6, target.hp)) / 3; + if (sub == "equip2") { + if (name == "baiyin" && pos == "e" && target.isDamaged()) { + let by = 3 - 0.6 * Math.min(5, target.hp); + return get.sgn(get.recoverEffect(target, player, player)) * by; } - return 1.57*btv+val; + return 1.57 * btv + val; } - if(att<=0&&(sub=='equip3'||sub=='equip4')&&(player.hasSkill('shouli')||player.hasSkill('psshouli'))) return 0; - if(sub=='equip3'&&!game.hasPlayer((cur)=>!cur.inRange(target)&&get.attitude(cur,target)<0)) return 0.4*btv+val; - if(sub=='equip4') return btv/2+val; - return btv+val; + if ( + att <= 0 && + (sub == "equip3" || sub == "equip4") && + (player.hasSkill("shouli") || player.hasSkill("psshouli")) + ) + return 0; + if ( + sub == "equip3" && + !game.hasPlayer((cur) => !cur.inRange(target) && get.attitude(cur, target) < 0) + ) + return 0.4 * btv + val; + if (sub == "equip4") return btv / 2 + val; + return btv + val; }, - result:{ - player:function(player,target){ - let att=get.attitude(player,target), - hs=target.hasCard((card)=>lib.filter.canBeGained(card,player,target),'h'), - lose=hs, - gain=att>0?0.52:1.28; - if(Math.abs(att)<5.03){ - let temp=0.015*att*att; - if(att<0) gain=0.9+temp; - else gain=0.9-temp; - } - target.countCards('e',function(card){ - if(card.name!='jinhe'&&lib.filter.canBeGained(card,player,target)&&att*get.value(card,target)<0){ - lose=true; - let val=get.value(card,player); - if(val>0) gain=Math.max(gain,val/7); - } - }); - target.countCards('j',function(card){ - let cardj=card.viewAs?new lib.element.VCard({name:card.viewAs}):card; - if(lib.filter.canBeGained(card,player,target)&&att*get.effect(target,cardj,target,target)<0){ - lose=true; - if(cardj.name=='lebu'){ - let needs=target.needsToDiscard(2); - if(att>0) gain=Math.max(gain,1.6+needs/10); - } - else if(cardj.name=='shandian'||cardj.name=='fulei'||cardj.name=='plague') gain=Math.max(gain,1.5/Math.max(1,target.hp)); - else if(att>0) gain=Math.max(gain,1.7); - } - }); - if(!lose) return 0; - return gain; - }, - target:function(player,target){ - let att=get.attitude(player,target), - hs=target.countCards('h',(card)=>lib.filter.canBeGained(card,player,target)), - es=target.countCards('e',(card)=>lib.filter.canBeGained(card,player,target)), - js=target.countCards('j',(card)=>lib.filter.canBeGained(card,player,target)), - noh=!hs||target.hasSkillTag('noh'), - noe=!es||target.hasSkillTag('noe'), - check=[-1,att>0?-1.3:1.3,att>0?-2.5:2.5], - idx=-1; - if(hs){ - idx=0; - if(noh) check[0]=0.7; - } - if(es){ - if(idx<0) idx=1; - if(target.getEquip('baiyin')&&target.isDamaged()&&lib.filter.canBeGained(target.getEquip('baiyin'),player,target)){ - let rec=get.recoverEffect(target,player,target); - if(es==1||att*rec>0){ - let val=3-0.6*Math.min(5,target.hp); - if(rec>0) check[1]=val; - else if(rec<0) check[1]=-val; - } - } - target.countCards('e',function(card){ - let val=get.value(card,target); - if(card.name=='jinhe'||att*val>=0||!lib.filter.canBeGained(card,player,target)) return false; - if(att>0){ - check[1]=Math.max(1.3,check[1]); - return true; - } - let sub=get.subtype(card); - if(sub=='equip2'||sub=='equip5') val+=4; - else if(sub=='equip1') val*=0.4*Math.min(3.6,target.hp); - else val*=0.6; - if(target.hp<3&&sub!='equip2'&&sub!='equip5') val*=0.4; - check[1]=Math.min(-0.16*val,check[1]); - }); - if(noe) check[1]+=0.9; - } - if(js){ - let func=function(num){ - if(att>0) check[2]=Math.max(check[2],num); - else check[2]=Math.min(check[2],0.6-num); - }; - if(idx<0) idx=2; - target.countCards('j',function(card){ - let cardj=card.viewAs?new lib.element.VCard({name:card.viewAs}):card; - if(!lib.filter.canBeGained(card,player,target)||att*get.effect(target,cardj,target,target)>=0) return false; - if(cardj.name=='lebu') func(2.1+0.4*target.needsToDiscard(2)); - else if(cardj.name=='bingliang') func(2.4); - else if(cardj.name=='shandian'||cardj.name=='fulei'||cardj.name=='plague') func(Math.abs(check[2])/(1+target.hp)); - else func(2.1); - }); - } - if(idx<0) return 0; - for(let i=idx+1;i<3;i++){ - if(i==1&&!es||i==2&&!js) continue; - if(att>0&&check[i]>check[idx]||att<=0&&check[i]0) return -1.5; - return (es.some(card=>{ - return get.value(card,target)>0&&card!=target.getEquip('jinhe'); - })||js.some(card=>{ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; - }))?-1.5:1.5; - } - return (es.some(card=>{ - return get.value(card,target)<=0; - })||js.some(card=>{ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; - }))?1.5:-1.5; - }, - player:function(player,target,card){ - let position='hej'; - if(card&&card.position) position=card.position; - const hs=position.includes('h')?target.getGainableCards(player,'h'):[]; - const es=position.includes('e')?target.getGainableCards(player,'e'):[]; - const js=position.includes('j')?target.getGainableCards(player,'j'):[]; - const att=get.attitude(player,target); - if(att<0){ - if(!hs.length&&!es.some(card=>{ - return get.value(card,target)>0&&card!=target.getEquip('jinhe'); - })&&!js.some(card=>{ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; + result: { + player: function (player, target) { + const hs = target.getGainableCards(player, 'h'); + const es = target.getGainableCards(player, 'e'); + const js = target.getGainableCards(player, 'j'); + const att = get.attitude(player, target); + if (att < 0) { + if (!hs.length && !es.some(card => { + return get.value(card, target) > 0 && card != target.getEquip('jinhe'); + }) && !js.some(card => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; })) return 0; } - else if(att>1){ - return (es.some(card=>{ - return get.value(card,target)<=0; - })||js.some(card=>{ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; - }))?1.5:0; + else if (att > 1) { + return (es.some(card => { + return get.value(card, target) <= 0; + }) || js.some(card => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + })) ? 1.5 : 0; } return 1; - } - }, - tag:{ - loseCard:1, - gain:1, - } - } - }, - shunshou_copy2:{ - ai:{ - basic:{ - order:7.5, - useful:4, - value:9 - }, - result:{ - target:function(player,target,card,isLink){ - return lib.card.shunshou_copy.ai.result.target(player,target,{ - name:'shunshou_copy', - position:'he', - },isLink) }, - player:function(player,target,card,isLink){ - return lib.card.shunshou_copy.ai.result.player(player,target,{ - name:'shunshou_copy', - position:'he', - },isLink) - } + target: function (player, target) { + const hs = target.getGainableCards(player, 'h'); + const es = target.getGainableCards(player, 'e'); + const js = target.getGainableCards(player, 'j'); + + if (get.attitude(player, target) <= 0) { + if (hs.length > 0) return -1.5; + return (es.some(card => { + return get.value(card, target) > 0 && card != target.getEquip('jinhe'); + }) || js.some(card => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + })) ? -1.5 : 1.5; + } + return (es.some(card => { + return get.value(card, target) <= 0; + }) || js.some(card => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + })) ? 1.5 : -1.5; + }, }, - tag:{ - loseCard:1, - gain:1, - } - } + tag: { + loseCard: 1, + gain: 1, + }, + }, }, - guohe:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:1, - postAi:function(targets){ - return targets.length==1&&targets[0].countCards('j'); - }, - filterTarget:function(card,player,target){ - if(player==target) return false; - return target.hasCard(card=>lib.filter.canBeDiscarded(card,player,target),get.is.single()?'he':'hej'); - }, - defaultYingbianEffect:'add', - content:function(){ - 'step 0' - if(get.is.single()){ - let bool1 = target.countDiscardableCards(player, 'h'), - bool2 = target.countDiscardableCards(player, 'e'); - if(bool1&&bool2) player.chooseControl('手牌区','装备区').set('ai',function(){ - return Math.random() < 0.5 ? 1 : 0; - }).set('prompt', '弃置'+get.translation(target)+'装备区的一张牌,或观看其手牌并弃置其中的一张牌。'); - else event._result={control:bool1?'手牌区':'装备区'}; - } - else event._result={control:'所有区域'}; - 'step 1' - let pos, vis='visible'; - if(result.control=='手牌区') pos='h'; - else if(result.control=='装备区') pos='e'; - else{ - pos='hej'; - vis=undefined; - } - if(target.countDiscardableCards(player,pos)) player.discardPlayerCard(pos, target, true, vis).set('target',target).set('ai',lib.card.guohe.ai.button); - }, - ai:{ - wuxie:(target,card,player,viewer,status)=>{ - if(status*get.attitude(viewer,player._trueMe||player)>0 || target.hp>2&&!target.hasCard(i=>{ - let val=get.value(i,target),subtypes=get.subtypes(i); - if(val<8&&target.hp<2&&!subtypes.includes('equip2')&&!subtypes.includes('equip5')) return false; - return val>3+Math.min(5,target.hp); - },'e')&&target.countCards('h')*_status.event.getRand('guohe_wuxie')>1.57) return 0; + shunshou_copy: { + ai: { + basic: { + order: 7.5, + useful: 4, + value: 9, }, - basic:{ - order:9, - useful:(card,i)=>10/(3+i), - value:(card,player)=>{ - let max=0; - game.countPlayer(cur=>{ - max=Math.max(max,lib.card.guohe.ai.result.target(player,cur)*get.attitude(player,cur)); + result: { + target: function (player, target, card) { + let position = "hej"; + if (card && card.position) position = card.position; + const hs = position.includes("h") ? target.getGainableCards(player, "h") : []; + const es = position.includes("e") ? target.getGainableCards(player, "e") : []; + const js = position.includes("j") ? target.getGainableCards(player, "j") : []; + if (get.attitude(player, target) <= 0) { + if (hs.length > 0) return -1.5; + return es.some((card) => { + return get.value(card, target) > 0 && card != target.getEquip("jinhe"); + }) || + js.some((card) => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) + ? -1.5 + : 1.5; + } + return es.some((card) => { + return get.value(card, target) <= 0; + }) || + js.some((card) => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) + ? 1.5 + : -1.5; + }, + player: function (player, target, card) { + let position = "hej"; + if (card && card.position) position = card.position; + const hs = position.includes("h") ? target.getGainableCards(player, "h") : []; + const es = position.includes("e") ? target.getGainableCards(player, "e") : []; + const js = position.includes("j") ? target.getGainableCards(player, "j") : []; + const att = get.attitude(player, target); + if (att < 0) { + if ( + !hs.length && + !es.some((card) => { + return ( + get.value(card, target) > 0 && card != target.getEquip("jinhe") + ); + }) && + !js.some((card) => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) + ) + return 0; + } else if (att > 1) { + return es.some((card) => { + return get.value(card, target) <= 0; + }) || + js.some((card) => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) + ? 1.5 + : 0; + } + return 1; + }, + }, + tag: { + loseCard: 1, + gain: 1, + }, + }, + }, + shunshou_copy2: { + ai: { + basic: { + order: 7.5, + useful: 4, + value: 9, + }, + result: { + target: function (player, target, card, isLink) { + return lib.card.shunshou_copy.ai.result.target( + player, + target, + { + name: "shunshou_copy", + position: "he", + }, + isLink + ); + }, + player: function (player, target, card, isLink) { + return lib.card.shunshou_copy.ai.result.player( + player, + target, + { + name: "shunshou_copy", + position: "he", + }, + isLink + ); + }, + }, + tag: { + loseCard: 1, + gain: 1, + }, + }, + }, + guohe: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: 1, + postAi: function (targets) { + return targets.length == 1 && targets[0].countCards("j"); + }, + filterTarget: function (card, player, target) { + if (player == target) return false; + return target.hasCard( + (card) => lib.filter.canBeDiscarded(card, player, target), + get.is.single() ? "he" : "hej" + ); + }, + defaultYingbianEffect: "add", + content: function () { + "step 0"; + if (get.is.single()) { + let bool1 = target.countDiscardableCards(player, "h"), + bool2 = target.countDiscardableCards(player, "e"); + if (bool1 && bool2) + player + .chooseControl("手牌区", "装备区") + .set("ai", function () { + return Math.random() < 0.5 ? 1 : 0; + }) + .set( + "prompt", + "弃置" + + get.translation(target) + + "装备区的一张牌,或观看其手牌并弃置其中的一张牌。" + ); + else event._result = { control: bool1 ? "手牌区" : "装备区" }; + } else event._result = { control: "所有区域" }; + "step 1"; + let pos, + vis = "visible"; + if (result.control == "手牌区") pos = "h"; + else if (result.control == "装备区") pos = "e"; + else { + pos = "hej"; + vis = undefined; + } + if (target.countDiscardableCards(player, pos)) + player + .discardPlayerCard(pos, target, true, vis) + .set("target", target) + .set("complexSelect", false) + .set("ai", lib.card.guohe.ai.button); + }, + ai: { + wuxie: (target, card, player, viewer, status) => { + if ( + status * get.attitude(viewer, player._trueMe || player) > 0 || + (target.hp > 2 && + !target.hasCard((i) => { + let val = get.value(i, target), + subtypes = get.subtypes(i); + if ( + val < 8 && + target.hp < 2 && + !subtypes.includes("equip2") && + !subtypes.includes("equip5") + ) + return false; + return val > 3 + Math.min(5, target.hp); + }, "e") && + target.countCards("h") * _status.event.getRand("guohe_wuxie") > 1.57) + ) + return 0; + }, + basic: { + order: 9, + useful: (card, i) => 10 / (3 + i), + value: (card, player) => { + let max = 0; + game.countPlayer((cur) => { + max = Math.max( + max, + lib.card.guohe.ai.result.target(player, cur) * get.attitude(player, cur) + ); }); - if(max<=0) return 5; - return 0.42*max; - } + if (max <= 0) return 5; + return 0.42 * max; + }, }, - yingbian:function(card,player,targets,viewer){ - if(get.attitude(viewer,player)<=0) return 0; - if(game.hasPlayer(function(current){ - return !targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })) return 6; + yingbian: function (card, player, targets, viewer) { + if (get.attitude(viewer, player) <= 0) return 0; + if ( + game.hasPlayer(function (current) { + return ( + !targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return 6; return 0; }, - button:(button)=>{ - let player = _status.event.player, target = _status.event.target; - if(!lib.filter.canBeDiscarded(button.link,player,target)) return 0; + button: (button) => { + let player = _status.event.player, + target = _status.event.target; + if (!lib.filter.canBeDiscarded(button.link, player, target)) return 0; let att = get.attitude(player, target), val = get.buttonValue(button), pos = get.position(button.link), name = get.name(button.link); - if(pos==='j'){ - if(name==='lebu'){ - let needs=target.needsToDiscard(2); - val *= 1.08+0.2*needs; - } - else if(name=='shandian'||name=='fulei'||name=='plague') val /= 2; + if (pos === "j") { + if (name === "lebu") { + let needs = target.needsToDiscard(2); + val *= 1.08 + 0.2 * needs; + } else if (name == "shandian" || name == "fulei" || name == "plague") val /= 2; } - if(get.attitude(player,get.owner(button.link))>0) val = -val; - if(pos!=='e') return val; + if (get.attitude(player, get.owner(button.link)) > 0) val = -val; + if (pos !== "e") return val; let sub = get.subtypes(button.link); - if(sub.includes('equip1')) return val*Math.min(3.6,target.hp)/3; - if(sub.includes('equip2')){ - if(name==='baiyin'&&pos==='e'&&target.isDamaged()){ - let by=3-0.6*Math.min(5,target.hp); - return get.sgn(get.recoverEffect(target,player,player))*by; + if (sub.includes("equip1")) return (val * Math.min(3.6, target.hp)) / 3; + if (sub.includes("equip2")) { + if (name === "baiyin" && pos === "e" && target.isDamaged()) { + let by = 3 - 0.6 * Math.min(5, target.hp); + return get.sgn(get.recoverEffect(target, player, player)) * by; } - return 1.57*val; + return 1.57 * val; } - if(att<=0&&(sub.includes('equip3')||sub.includes('equip4'))&&(player.hasSkill('shouli')||player.hasSkill('psshouli'))) return 0; - if(sub.includes('equip6')) return val; - if(sub.includes('equip4')) return val/2; - if(sub.includes('equip3')&&!game.hasPlayer((cur)=>{ - return !cur.inRange(target)&&get.attitude(cur,target)<0; - })) return 0.4*val; + if ( + att <= 0 && + (sub.includes("equip3") || sub.includes("equip4")) && + (player.hasSkill("shouli") || player.hasSkill("psshouli")) + ) + return 0; + if (sub.includes("equip6")) return val; + if (sub.includes("equip4")) return val / 2; + if ( + sub.includes("equip3") && + !game.hasPlayer((cur) => { + return !cur.inRange(target) && get.attitude(cur, target) < 0; + }) + ) + return 0.4 * val; return val; }, - result:{ - target:function(player,target){ - let att=get.attitude(player, target), - hs=target.countCards('h',(card)=>lib.filter.canBeDiscarded(card,player,target)), - es=target.countCards('e',(card)=>lib.filter.canBeDiscarded(card,player,target)), - js=target.countCards('j',(card)=>lib.filter.canBeDiscarded(card,player,target)), - noh=!hs||target.hasSkillTag('noh'), - noe=!es||target.hasSkillTag('noe'), - check=[-1,att>0?-1.3:1.3,att>0?-2.5:2.5], - idx=-1; - if(hs){ - idx=0; - if(noh) check[0]=0.7; - } - if(es){ - if(idx<0) idx=1; - if(target.getEquip('baiyin')&&target.isDamaged()&&lib.filter.canBeDiscarded(target.getEquip('baiyin'),player,target)){ - let rec=get.recoverEffect(target,player,target); - if(es==1||att*rec>0){ - let val=3-0.6*Math.min(5,target.hp); - if(rec>0) check[1]=val; - else if(rec<0) check[1]=-val; - } - } - target.countCards('e',function(card){ - let val=get.value(card,target); - if(card.name=='jinhe'||att*val>=0||!lib.filter.canBeDiscarded(card,player,target)) return false; - if(att>0){ - check[1]=Math.max(1.3,check[1]); - return true; - } - let sub=get.subtype(card); - if(sub=='equip2'||sub=='equip5') val+=4; - else if(sub=='equip1') val*=0.4*Math.min(3.6,target.hp); - else val*=0.6; - if(target.hp<3&&sub!='equip2'&&sub!='equip5') val*=0.4; - check[1]=Math.min(-0.16*val,check[1]); - }); - if(noe) check[1]+=0.9; - } - if(js){ - let func=function(num){ - if(att>0) check[2]=Math.max(check[2],num); - else check[2]=Math.min(check[2],0.6-num); - }; - if(idx<0) idx=2; - target.countCards('j',function(card){ - let cardj=card.viewAs?new lib.element.VCard({name:card.viewAs}):card; - if(!lib.filter.canBeDiscarded(card,player,target)||att*get.effect(target,cardj,target,target)>=0) return false; - if(cardj.name=='lebu') func(2.1+0.4*target.needsToDiscard(2)); - else if(cardj.name=='bingliang') func(2.4); - else if(cardj.name=='shandian'||cardj.name=='fulei'||cardj.name=='plague') func(Math.abs(check[2])/(1+target.hp)); - else func(2.1); - }); - } - if(idx<0) return 0; - for(let i=idx+1;i<3;i++){ - if(i==1&&!es||i==2&&!js) continue; - if(att>0&&check[i]>check[idx]||att<=0&&check[i]0){ - if(js.some(card=>{ - const cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; + result: { + target: function (player, target) { + const att = get.attitude(player, target); + const hs = target.getDiscardableCards(player, 'h'); + const es = target.getDiscardableCards(player, 'e'); + const js = target.getDiscardableCards(player, 'j'); + if (!hs.length && !es.length && !js.length) return 0; + if (att > 0) { + if (js.some(card => { + const cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; })) return 3; - if(target.isDamaged()&&es.some(card=>card.name=='baiyin')&& - get.recoverEffect(target,player,player)>0){ - if(target.hp==1&&!target.hujia) return 1.6; + if (target.isDamaged() && es.some(card => card.name == 'baiyin') && + get.recoverEffect(target, player, player) > 0) { + if (target.hp == 1 && !target.hujia) return 1.6; } - if(es.some(card=>{ - return get.value(card,target)<0; + if (es.some(card => { + return get.value(card, target) < 0; })) return 1; return -1.5; } - else{ - const noh=(hs.length==0||target.hasSkillTag('noh')); - const noe=(es.length==0||target.hasSkillTag('noe')); - const noe2=(noe||!es.some(card=>{ - return get.value(card,target)>0; + else { + const noh = (hs.length == 0 || target.hasSkillTag('noh')); + const noe = (es.length == 0 || target.hasSkillTag('noe')); + const noe2 = (noe || !es.some(card => { + return get.value(card, target) > 0; })); - const noj=(js.length==0||!js.some(card=>{ - const cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; + const noj = (js.length == 0 || !js.some(card => { + const cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; })) - if(noh&&noe2&&noj) return 1.5; + if (noh && noe2 && noj) return 1.5; return -1.5; } }, }, - tag:{ - loseCard:1, - discard:1 - } - } + tag: { + loseCard: 1, + discard: 1, + }, + }, }, - guohe_copy2:{ - ai:{ - basic:{ - order:9, - useful:5, - value:5, + guohe_copy: { + ai: { + basic: { + order: 9, + useful: 5, + value: 5, }, - result:{ - target:function(player,target,card,isLink){ - return lib.card.guohe_copy.ai.result.target(player,target,{ - name:'guohe_copy', - position:'he', - },isLink) - }, - }, - tag:{ - loseCard:1, - discard:1 - } - } - }, - jiedao:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - singleCard:true, - targetprompt:['被借刀','出杀目标'], - complexSelect:true, - complexTarget:true, - multicheck:function(){ - var card={name:'sha',isCard:true}; - return game.hasPlayer(function(current){ - if(current.getEquips(1).length>0){ - return game.hasPlayer(function(current2){ - return current.inRange(current2)&&lib.filter.targetEnabled(card,current,current2); - }) - } - }); - }, - filterTarget:function(card,player,target){ - var card={name:'sha',isCard:true}; - return player!=target&&target.getEquips(1).length>0&&game.hasPlayer(function(current){ - return target!=current&&target.inRange(current)&&lib.filter.targetEnabled(card,target,current); - }); - }, - filterAddedTarget:function(card,player,target,preTarget){ - var card={name:'sha',isCard:true}; - return target!=preTarget&&preTarget.inRange(target)&&lib.filter.targetEnabled(card,preTarget,target); - }, - content:function(){ - "step 0" - if(event.directHit||!event.addedTarget||(!_status.connectMode&&lib.config.skip_shan&&!target.hasSha())){ - event.directfalse=true; - } - else{ - target.chooseToUse('对'+get.translation(event.addedTarget)+'使用一张杀,或令'+get.translation(player)+'获得你的武器牌',function(card,player){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - }).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',event.addedTarget).set('addCount',false).set('respondTo',[player,card]); - } - "step 1" - if(event.directfalse||result.bool==false){ - var cards=target.getEquips(1); - if(cards.length) player.gain(cards,target,'give','bySelf'); - } - }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(player==game.me&&get.attitude(viewer,player._trueMe||player)>0) return 0; - }, - basic:{ - order:8, - value:2, - useful:1, - }, - result:{ - player:(player,target)=>{ - if(!target.hasSkillTag('noe')&&get.attitude(player,target)>0) return 0; - return (player.hasSkillTag('noe')?0.32:0.15)*target.getEquips(1).reduce((num,i)=>{ - return num+get.value(i,player); - },0); - }, - target:(player,target,card)=>{ - let targets=[].concat(ui.selected.targets); - if(_status.event.preTarget) targets.add(_status.event.preTarget); - if(targets.length){ - let preTarget=targets.lastItem,pre=_status.event.getTempCache('jiedao_result',preTarget.playerid); - if(pre&&pre.card===card&&pre.target.isIn()) return target===pre.target?pre.eff:0; - return get.effect(target,{name:'sha'},preTarget,player)/get.attitude(player,target); + result: { + target: function (player, target, card) { + let position = "hej"; + if (card && card.position) position = card.position; + const att = get.attitude(player, target); + const hs = position.includes("h") ? target.getDiscardableCards(player, "h") : []; + const es = position.includes("e") ? target.getDiscardableCards(player, "e") : []; + const js = position.includes("j") ? target.getDiscardableCards(player, "j") : []; + if (!hs.length && !es.length && !js.length) return 0; + if (att > 0) { + if ( + js.some((card) => { + const cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) + ) + return 3; + if ( + target.isDamaged() && + es.some((card) => card.name == "baiyin") && + get.recoverEffect(target, player, player) > 0 + ) { + if (target.hp == 1 && !target.hujia) return 1.6; + } + if ( + es.some((card) => { + return get.value(card, target) < 0; + }) + ) + return 1; + return -1.5; + } else { + const noh = hs.length == 0 || target.hasSkillTag("noh"); + const noe = es.length == 0 || target.hasSkillTag("noe"); + const noe2 = + noe || + !es.some((card) => { + return get.value(card, target) > 0; + }); + const noj = + js.length == 0 || + !js.some((card) => { + const cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }); + if (noh && noe2 && noj) return 1.5; + return -1.5; } - let arms=(target.hasSkillTag('noe')?0.32:-0.15)*target.getEquips(1).reduce((num,i)=>{ - return num+get.value(i,target); - },0); - if(!target.mayHaveSha(player,'use')) return arms; - let sha=game.filterPlayer(get.info({name:'jiedao'}).filterAddedTarget),addTar=null; - sha=sha.reduce((num,current)=>{ - let eff=get.effect(current,{name:'sha'},target,player); - if(eff<=num) return num; - addTar=current; - return eff; - },-100); - if(!addTar) return arms; - sha/=get.attitude(player,target); - _status.event.putTempCache('jiedao_result',target.playerid,{ - card:card, - target:addTar, - eff:sha - }); - return Math.max(arms,sha); - } + }, }, - tag:{ - gain:1, - use:1, - useSha:1, - loseCard:1, - } - } + tag: { + loseCard: 1, + discard: 1, + }, + }, }, - wuxie:{ - audio:true, - fullskin:true, - type:'trick', - ai:{ - basic:{ - useful:[6,4,3], - value:[6,4,3], + guohe_copy2: { + ai: { + basic: { + order: 9, + useful: 5, + value: 5, + }, + result: { + target: function (player, target, card, isLink) { + return lib.card.guohe_copy.ai.result.target( + player, + target, + { + name: "guohe_copy", + position: "he", + }, + isLink + ); + }, + }, + tag: { + loseCard: 1, + discard: 1, }, - result:{player:1}, - expose:0.2 }, - notarget:true, - finalDelay:false, - defaultYingbianEffect:'draw', - contentBefore:function(){ - 'step 0' - if(get.mode()=='guozhan'&&get.cardtag(card,'guo')){ - var trigger=event.getParent(2)._trigger; - if(trigger.name!='phaseJudge'&&trigger.card.name!='wuxie'&&trigger.targets.length>1){ - player.chooseControl('对单体使用','对势力使用').set('prompt','请选择'+get.translation(card)+'的使用方式').set('ai',function(){ - return '对势力使用' + }, + jiedao: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + singleCard: true, + targetprompt: ["被借刀", "出杀目标"], + complexSelect: true, + complexTarget: true, + multicheck: function () { + var card = { name: "sha", isCard: true }; + return game.hasPlayer(function (current) { + if (current.getEquips(1).length > 0) { + return game.hasPlayer(function (current2) { + return ( + current.inRange(current2) && + lib.filter.targetEnabled(card, current, current2) + ); }); } - else event.finish(); + }); + }, + filterTarget: function (card, player, target) { + var card = { name: "sha", isCard: true }; + return ( + player != target && + target.getEquips(1).length > 0 && + game.hasPlayer(function (current) { + return ( + target != current && + target.inRange(current) && + lib.filter.targetEnabled(card, target, current) + ); + }) + ); + }, + filterAddedTarget: function (card, player, target, preTarget) { + var card = { name: "sha", isCard: true }; + return ( + target != preTarget && + preTarget.inRange(target) && + lib.filter.targetEnabled(card, preTarget, target) + ); + }, + content: function () { + "step 0"; + if ( + event.directHit || + !event.addedTarget || + (!_status.connectMode && lib.config.skip_shan && !target.hasSha()) + ) { + event.directfalse = true; + } else { + target + .chooseToUse( + "对" + + get.translation(event.addedTarget) + + "使用一张杀,或令" + + get.translation(player) + + "获得你的武器牌", + function (card, player) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + } + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", event.addedTarget) + .set("addCount", false) + .set("respondTo", [player, card]); } - else event.finish(); - 'step 1' - if(result.control=='对势力使用'){ - player.chat('对势力使用'); - event.getParent().guowuxie=true; + "step 1"; + if (event.directfalse || result.bool == false) { + var cards = target.getEquips(1); + if (cards.length) player.gain(cards, target, "give", "bySelf"); } }, - content:function(){ - var trigger=event.getParent(2)._trigger; - if(trigger.name=='phaseJudge'){ - trigger.untrigger('currentOnly'); - trigger.cancelled=true; + ai: { + wuxie: function (target, card, player, viewer) { + if (player == game.me && get.attitude(viewer, player._trueMe || player) > 0) return 0; + }, + basic: { + order: 8, + value: 2, + useful: 1, + }, + result: { + player: (player, target) => { + if (!target.hasSkillTag("noe") && get.attitude(player, target) > 0) return 0; + return ( + (player.hasSkillTag("noe") ? 0.32 : 0.15) * + target.getEquips(1).reduce((num, i) => { + return num + get.value(i, player); + }, 0) + ); + }, + target: (player, target, card) => { + let targets = [].concat(ui.selected.targets); + if (_status.event.preTarget) targets.add(_status.event.preTarget); + if (targets.length) { + let preTarget = targets.lastItem, + pre = _status.event.getTempCache("jiedao_result", preTarget.playerid); + if (pre && pre.card === card && pre.target.isIn()) + return target === pre.target ? pre.eff : 0; + return ( + get.effect(target, { name: "sha" }, preTarget, player) / + get.attitude(player, target) + ); + } + let arms = + (target.hasSkillTag("noe") ? 0.32 : -0.15) * + target.getEquips(1).reduce((num, i) => { + return num + get.value(i, target); + }, 0); + if (!target.mayHaveSha(player, "use")) return arms; + let sha = game.filterPlayer(get.info({ name: "jiedao" }).filterAddedTarget), + addTar = null; + sha = sha.reduce((num, current) => { + let eff = get.effect(current, { name: "sha" }, target, player); + if (eff <= num) return num; + addTar = current; + return eff; + }, -100); + if (!addTar) return arms; + sha /= get.attitude(player, target); + _status.event.putTempCache("jiedao_result", target.playerid, { + card: card, + target: addTar, + eff: sha, + }); + return Math.max(arms, sha); + }, + }, + tag: { + gain: 1, + use: 1, + useSha: 1, + loseCard: 1, + }, + }, + }, + wuxie: { + audio: true, + fullskin: true, + type: "trick", + ai: { + basic: { + useful: [6, 4, 3], + value: [6, 4, 3], + }, + result: { player: 1 }, + expose: 0.2, + }, + notarget: true, + finalDelay: false, + defaultYingbianEffect: "draw", + contentBefore: function () { + "step 0"; + if (get.mode() == "guozhan" && get.cardtag(card, "guo")) { + var trigger = event.getParent(2)._trigger; + if ( + trigger.name != "phaseJudge" && + trigger.card.name != "wuxie" && + trigger.targets.length > 1 + ) { + player + .chooseControl("对单体使用", "对势力使用") + .set("prompt", "请选择" + get.translation(card) + "的使用方式") + .set("ai", function () { + return "对势力使用"; + }); + } else event.finish(); + } else event.finish(); + "step 1"; + if (result.control == "对势力使用") { + player.chat("对势力使用"); + event.getParent().guowuxie = true; } - else{ + }, + content: function () { + var trigger = event.getParent(2)._trigger; + if (trigger.name == "phaseJudge") { + trigger.untrigger("currentOnly"); + trigger.cancelled = true; + } else { trigger.neutralize(); - if(event.getParent().guowuxie==true){ - trigger.getParent().excluded.addArray(game.filterPlayer(function(current){ - return current.isFriendOf(trigger.target); - })); + if (event.getParent().guowuxie == true) { + trigger.getParent().excluded.addArray( + game.filterPlayer(function (current) { + return current.isFriendOf(trigger.target); + }) + ); } } /* @@ -2221,1073 +2793,1306 @@ game.import('card',function(lib,game,ui,get,ai,_status){ directHit:evt.directHit||[], nowuxie:evt.nowuxie, };*/ - if(player.isOnline()){ - player.send(function(player){ - if(ui.tempnowuxie&&!player.hasWuxie()){ + if (player.isOnline()) { + player.send(function (player) { + if (ui.tempnowuxie && !player.hasWuxie()) { ui.tempnowuxie.close(); delete ui.tempnowuxie; } - },player); - } - else if(player==game.me){ - if(ui.tempnowuxie&&!player.hasWuxie()){ + }, player); + } else if (player == game.me) { + if (ui.tempnowuxie && !player.hasWuxie()) { ui.tempnowuxie.close(); delete ui.tempnowuxie; } } - } - }, - lebu:{ - audio:true, - fullskin:true, - type:'delay', - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player!=target); }, - judge:function(card){ - if(get.suit(card)=='heart') return 1; + }, + lebu: { + audio: true, + fullskin: true, + type: "delay", + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player != target; + }, + judge: function (card) { + if (get.suit(card) == "heart") return 1; return -2; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - effect:function(){ - if(result.bool==false){ - player.skip('phaseUse'); + effect: function () { + if (result.bool == false) { + player.skip("phaseUse"); } }, - ai:{ - basic:{ - order:1, - useful:1, - value:8, + ai: { + basic: { + order: 1, + useful: 1, + value: 8, }, - result:{ - ignoreStatus:true, - target:(player,target)=>{ - if(target===_status.currentPhase&&target.skipList.includes('phaseUse')){ - let evt=_status.event.getParent('phase'); - if(evt&&evt.phaseList.indexOf('phaseJudge')<=evt.num) return 0; + result: { + ignoreStatus: true, + target: (player, target) => { + if (target === _status.currentPhase && target.skipList.includes("phaseUse")) { + let evt = _status.event.getParent("phase"); + if (evt && evt.phaseList.indexOf("phaseJudge") <= evt.num) return 0; } - let num=target.needsToDiscard(3),cf=Math.pow(get.threaten(target,player),2); - if(!num) return -0.01*cf; - if(target.hp>2) num--; - let dist=Math.sqrt(get.distance(player,target,'absolute')); - if(dist<1) dist=1; - if(target.isTurnedOver()) dist++; - return Math.min(-0.1,-num)*cf/dist; - } + let num = target.needsToDiscard(3), + cf = Math.pow(get.threaten(target, player), 2); + if (!num) return -0.01 * cf; + if (target.hp > 2) num--; + let dist = Math.sqrt(1 + get.distance(player, target, "absolute")); + if (dist < 1) dist = 1; + if (target.isTurnedOver()) dist++; + return (Math.min(-0.1, -num) * cf) / dist; + }, + }, + tag: { + skip: "phaseUse", }, - tag:{ - skip:'phaseUse' - } - } - }, - shandian:{ - audio:true, - fullskin:true, - type:'delay', - cardnature:'thunder', - modTarget:function(card,player,target){ - return lib.filter.judge(card,player,target); }, - enable:function(card,player){ + }, + shandian: { + audio: true, + fullskin: true, + type: "delay", + cardnature: "thunder", + modTarget: function (card, player, target) { + return lib.filter.judge(card, player, target); + }, + enable: function (card, player) { return player.canAddJudge(card); }, - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player==target); + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player == target; }, - selectTarget:[-1,-1], - toself:true, - judge:function(card){ - if(get.suit(card)=='spade'&&get.number(card)>1&&get.number(card)<10) return -5; + selectTarget: [-1, -1], + toself: true, + judge: function (card) { + if (get.suit(card) == "spade" && get.number(card) > 1 && get.number(card) < 10) return -5; return 1; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - effect:function(){ - if(result.bool==false){ - player.damage(3,'thunder','nosource'); - } - else{ + effect: function () { + if (result.bool == false) { + player.damage(3, "thunder", "nosource"); + } else { player.addJudgeNext(card); } }, - cancel:function(){ + cancel: function () { player.addJudgeNext(card); }, - ai:{ - basic:{ - order:1, - useful:0, - value:0, + ai: { + basic: { + order: 1, + useful: 0, + value: 0, }, - result:{ - target:function(player,target){ - var num=game.countPlayer(function(current){ + result: { + target: function (player, target) { + var num = game.countPlayer(function (current) { //var skills=current.getSkills(); - for(var j=0;j0&& - get.attitude(current,target)>0){ + for (var j = 0; j < current.skills.length; j++) { + var rejudge = get.tag(current.skills[j], "rejudge", current); + if (rejudge != undefined) { + if ( + get.attitude(target, current) > 0 && + get.attitude(current, target) > 0 + ) { return rejudge; - } - else{ + } else { return -rejudge; } } } }); - if(num>0) return num; - if(num==0){ - var mode=get.mode(); - if(mode=='identity'){ - if(target.identity=='nei') return 1; - var situ=get.situation(); - if(target.identity=='fan'){ - if(situ>1) return 1; + if (num > 0) return num; + if (num == 0) { + var mode = get.mode(); + if (mode == "identity") { + if (target.identity == "nei") return 1; + var situ = get.situation(); + if (target.identity == "fan") { + if (situ > 1) return 1; + } else { + if (situ < -1) return 1; } - else{ - if(situ<-1) return 1; - } - } - else if(mode=='guozhan'){ - if(target.identity=='ye') return 1; - if(game.hasPlayer(function(current){ - return current.identity=='unknown'; - })){ + } else if (mode == "guozhan") { + if (target.identity == "ye") return 1; + if ( + game.hasPlayer(function (current) { + return current.identity == "unknown"; + }) + ) { return -1; } - if(get.population(target.identity)==1){ - if(target.maxHp>2&&target.hp<2) return 1; - if(game.countPlayer()<3) return -1; - if(target.hp<=2&&target.countCards('he')<=3) return 1; + if (get.population(target.identity) == 1) { + if (target.maxHp > 2 && target.hp < 2) return 1; + if (game.countPlayer() < 3) return -1; + if (target.hp <= 2 && target.countCards("he") <= 3) return 1; } } } return -1; - } + }, + }, + tag: { + damage: 0.16, + natureDamage: 0.16, + thunderDamage: 0.16, }, - tag:{ - damage:0.16, - natureDamage:0.16, - thunderDamage:0.16, - } - } - }, - hanbing:{ - fullskin:true, - type:"equip", - subtype:"equip1", - distance:{attackFrom:-1}, - skills:['hanbing_skill'], - ai:{ - basic:{ - equipValue:2 - } }, }, - renwang:{ - fullskin:true, - type:"equip", - subtype:"equip2", - skills:['renwang_skill'], - ai:{ - basic:{ - equipValue:7.5 + hanbing: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["hanbing_skill"], + ai: { + basic: { + equipValue: 2, + }, + }, + }, + renwang: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["renwang_skill"], + ai: { + basic: { + equipValue: 7.5, }, }, }, }, - skill:{ - qinglong_guozhan:{ - equipSkill:true, - trigger:{player:'useCard'}, - forced:true, - audio:'qinglong_skill', - filter:function(event,player){ - return get.mode()=='guozhan'&&event.card.name=='sha'; + skill: { + qinglong_guozhan: { + equipSkill: true, + trigger: { player: "useCard" }, + forced: true, + audio: "qinglong_skill", + filter: function (event, player) { + return get.mode() == "guozhan" && event.card.name == "sha"; }, - content:function(){ - if(!_status.qinglong_guozhan) _status.qinglong_guozhan=[]; + content: function () { + if (!_status.qinglong_guozhan) _status.qinglong_guozhan = []; _status.qinglong_guozhan.add(trigger); - game.countPlayer2(function(current){ - current.addTempSkill('qinglong_guozhan_mingzhi'); + game.countPlayer2(function (current) { + current.addTempSkill("qinglong_guozhan_mingzhi"); }); - game.broadcast(function(list){ - _status.qinglong_guozhan=list; - },_status.qinglong_guozhan.map(function(i){ - return {targets:i.targets}; - })) - var next=game.createEvent('qinglong_guozhan'); + game.broadcast( + function (list) { + _status.qinglong_guozhan = list; + }, + _status.qinglong_guozhan.map(function (i) { + return { targets: i.targets }; + }) + ); + var next = game.createEvent("qinglong_guozhan"); event.next.remove(next); trigger.after.add(next); - next.setContent(function(){ + next.setContent(function () { _status.qinglong_guozhan.remove(event.parent); - game.broadcast(function(list){ - _status.qinglong_guozhan=list; - },_status.qinglong_guozhan.map(function(i){ - return {targets:i.targets}; - })); + game.broadcast( + function (list) { + _status.qinglong_guozhan = list; + }, + _status.qinglong_guozhan.map(function (i) { + return { targets: i.targets }; + }) + ); }); - } + }, }, - qinglong_guozhan_mingzhi:{ - ai:{ - nomingzhi:true, - skillTagFilter:function(player){ - if(_status.qinglong_guozhan){ - for(var i=0;i<_status.qinglong_guozhan.length;i++){ - if(_status.qinglong_guozhan[i].targets.includes(player)) return true; + qinglong_guozhan_mingzhi: { + ai: { + nomingzhi: true, + skillTagFilter: function (player) { + if (_status.qinglong_guozhan) { + for (var i = 0; i < _status.qinglong_guozhan.length; i++) { + if (_status.qinglong_guozhan[i].targets.includes(player)) return true; } } return false; }, - } + }, }, - hanbing_skill:{ - equipSkill:true, - trigger:{source:'damageBegin2'}, + hanbing_skill: { + equipSkill: true, + trigger: { source: "damageBegin2" }, //direct:true, - audio:true, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.notLink()&&event.player.getCards('he').length>0; + audio: true, + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + event.notLink() && + event.player.getCards("he").length > 0 + ); }, //priority:1, - check:function(event,player){ - var target=event.player; - var eff=get.damageEffect(target,player,player,event.nature); - if(get.attitude(player,target)>0){ - if(eff>=0) return false; + check: function (event, player) { + var target = event.player; + var eff = get.damageEffect(target, player, player, event.nature); + if (get.attitude(player, target) > 0) { + if (eff >= 0) return false; return true; } - if(eff<=0) return true; - if(target.hp==1) return false; - if(event.num>1||player.hasSkill('tianxianjiu')|| - player.hasSkill('luoyi2')||player.hasSkill('reluoyi2')) return false; - if(target.countCards('he')<2) return false; - var num=0; - var cards=target.getCards('he'); - for(var i=0;i6) num++; + if (eff <= 0) return true; + if (target.hp == 1) return false; + if ( + event.num > 1 || + player.hasSkill("tianxianjiu") || + player.hasSkill("luoyi2") || + player.hasSkill("reluoyi2") + ) + return false; + if (target.countCards("he") < 2) return false; + var num = 0; + var cards = target.getCards("he"); + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) > 6) num++; } - if(num>=2) return true; + if (num >= 2) return true; return false; }, - logTarget:"player", - content:function(){ - "step 0" + logTarget: "player", + content: function () { + "step 0"; trigger.cancel(); - "step 1" - if(trigger.player.countDiscardableCards(player,'he')){ + "step 1"; + if (trigger.player.countDiscardableCards(player, "he")) { player.line(trigger.player); - player.discardPlayerCard('he',trigger.player,true); + player.discardPlayerCard("he", trigger.player, true); } - "step 2" - if(trigger.player.countDiscardableCards(player,'he')){ + "step 2"; + if (trigger.player.countDiscardableCards(player, "he")) { player.line(trigger.player); - player.discardPlayerCard('he',trigger.player,true); + player.discardPlayerCard("he", trigger.player, true); } - } - }, - icesha_skill:{ - inherit:'hanbing_skill', - trigger:{source:'damageBegin3'}, - equipSkill:false, - ruleSkill:true, - filter:function(event){ - return event.hasNature('ice')&&event.notLink()&&event.player.getCards('he').length>0; }, }, - renwang_skill:{ - equipSkill:true, - trigger:{target:'shaBegin'}, - forced:true, - priority:6, - audio:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return (event.card.name=='sha'&&get.color(event.card)=='black') + icesha_skill: { + inherit: "hanbing_skill", + trigger: { source: "damageBegin3" }, + equipSkill: false, + ruleSkill: true, + filter: function (event) { + return ( + event.hasNature("ice") && event.notLink() && event.player.getCards("he").length > 0 + ); }, - content:function(){ + }, + renwang_skill: { + equipSkill: true, + trigger: { target: "shaBegin" }, + forced: true, + priority: 6, + audio: true, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + return event.card.name == "sha" && get.color(event.card) == "black"; + }, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(typeof card!=='object'||target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:target, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:target, - card:card - })) return; - if(card.name=='sha'&&get.color(card)=='black') return 'zeroplayertarget'; - } - } - } + ai: { + effect: { + target: function (card, player, target) { + if (typeof card !== "object" || target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) + return; + if (card.name == "sha" && get.color(card) == "black") return "zeroplayertarget"; + }, + }, + }, }, - zhuge_skill:{ - equipSkill:true, - audio:true, - firstDo:true, - trigger:{player:'useCard1'}, - forced:true, - filter:function(event,player){ - return !event.audioed&&event.card.name=='sha'&&player.countUsed('sha',true)>1&&event.getParent().type=='phase'; + zhuge_skill: { + equipSkill: true, + audio: true, + firstDo: true, + trigger: { player: "useCard1" }, + forced: true, + filter: function (event, player) { + return ( + !event.audioed && + event.card.name == "sha" && + player.countUsed("sha", true) > 1 && + event.getParent().type == "phase" + ); }, - content:function(){ - trigger.audioed=true; + content: function () { + trigger.audioed = true; }, - mod:{ - cardUsable:function(card,player,num){ - var cards=player.getEquips('zhuge') - if(card.name=='sha'){ - if(!cards.length||player.hasSkill('zhuge_skill',null,false)||cards.some(card=>(card!=_status.zhuge_temp&&!ui.selected.cards.includes(card)))){ - if(get.is.versus()||get.is.changban()){ - return num+3; + mod: { + cardUsable: function (card, player, num) { + var cards = player.getEquips("zhuge"); + if (card.name == "sha") { + if ( + !cards.length || + player.hasSkill("zhuge_skill", null, false) || + cards.some( + (card) => card != _status.zhuge_temp && !ui.selected.cards.includes(card) + ) + ) { + if (get.is.versus() || get.is.changban()) { + return num + 3; } return Infinity; } } }, - cardEnabled2:function(card,player){ - if(!_status.event.addCount_extra||player.hasSkill('zhuge_skill',null,false)) return; - var cards=player.getEquips('zhuge'); - if(card&&cards.includes(card)){ - try{ - var cardz=get.card(); - } - catch(e){ + cardEnabled2: function (card, player) { + if (!_status.event.addCount_extra || player.hasSkill("zhuge_skill", null, false)) + return; + var cards = player.getEquips("zhuge"); + if (card && cards.includes(card)) { + try { + var cardz = get.card(); + } catch (e) { return; } - if(!cardz||cardz.name!='sha') return; - _status.zhuge_temp=card; - var bool=lib.filter.cardUsable(get.autoViewAs({name:'sha'},ui.selected.cards.concat([card])),player); + if (!cardz || cardz.name != "sha") return; + _status.zhuge_temp = card; + var bool = lib.filter.cardUsable( + get.autoViewAs({ name: "sha" }, ui.selected.cards.concat([card])), + player + ); delete _status.zhuge_temp; - if(!bool) return false; + if (!bool) return false; } }, }, }, - cixiong_skill:{ - equipSkill:true, - trigger:{player:'useCardToPlayered'}, - audio:true, - logTarget:'target', - check:function(event,player){ - if(get.attitude(player,event.target)>0) return true; - var target=event.target; - return target.countCards('h')==0||!target.hasSkillTag('noh'); + cixiong_skill: { + equipSkill: true, + trigger: { player: "useCardToPlayered" }, + audio: true, + logTarget: "target", + check: function (event, player) { + if (get.attitude(player, event.target) > 0) return true; + var target = event.target; + return target.countCards("h") == 0 || !target.hasSkillTag("noh"); }, - filter:function(event,player){ - if(event.card.name!='sha') return false; + filter: function (event, player) { + if (event.card.name != "sha") return false; return player.differentSexFrom(event.target); }, - content:function(){ - "step 0" - if(!trigger.target.countCards('h')) event._result={bool:false}; - else trigger.target.chooseToDiscard('弃置一张手牌,或令'+get.translation(player)+'摸一张牌').set('ai',function(card){ - var trigger=_status.event.getTrigger(); - return -get.attitude(trigger.target,trigger.player)-get.value(card)-Math.max(0,4-trigger.target.hp)*2; - }); - "step 1" - if(result.bool==false) player.draw(); - } + content: function () { + "step 0"; + if (!trigger.target.countCards("h")) event._result = { bool: false }; + else + trigger.target + .chooseToDiscard("弃置一张手牌,或令" + get.translation(player) + "摸一张牌") + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + return ( + -get.attitude(trigger.target, trigger.player) - + get.value(card) - + Math.max(0, 4 - trigger.target.hp) * 2 + ); + }); + "step 1"; + if (result.bool == false) player.draw(); + }, }, - qinggang_skill:{ - equipSkill:true, - audio:true, - trigger:{ - player:'useCardToPlayered', + qinggang_skill: { + equipSkill: true, + audio: true, + trigger: { + player: "useCardToPlayered", }, - filter:function(event){ - return event.card.name=='sha'; + filter: function (event) { + return event.card.name == "sha"; }, - forced:true, - logTarget:'target', - content:function(){ - trigger.target.addTempSkill('qinggang2'); + forced: true, + logTarget: "target", + content: function () { + trigger.target.addTempSkill("qinggang2"); trigger.target.storage.qinggang2.add(trigger.card); - trigger.target.markSkill('qinggang2'); + trigger.target.markSkill("qinggang2"); }, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.name=='sha') return true; + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.name == "sha") return true; return false; - } - } - }, - qinggang2:{ - firstDo:true, - ai:{unequip2:true}, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; - }, - onremove:true, - trigger:{ - player:['damage','damageCancelled','damageZero'], - source:['damage','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded','useCardToEnd','eventNeutralized'], - global:['useCardEnd'], - }, - charlotte:true, - filter:function(event,player){ - return player.storage.qinggang2&&event.card&&player.storage.qinggang2.includes(event.card)&&(event.name!='damage'||event.notLink()); - }, - silent:true, - forced:true, - popup:false, - priority:12, - content:function(){ - player.storage.qinggang2.remove(trigger.card); - if(!player.storage.qinggang2.length) player.removeSkill('qinggang2'); - }, - marktext:'※', - intro:{content:'当前防具技能已失效'}, - }, - qinglong_skill:{ - equipSkill:true, - trigger:{player:['shaMiss','eventNeutralized']}, - direct:true, - filter:function(event,player){ - if(get.mode()=='guozhan'||!event.card||event.card.name!='sha') return false; - return event.target.isIn()&&player.canUse('sha',event.target,false)&&(player.hasSha()||_status.connectMode&&player.countCards('hs')); - }, - content:function(){ - "step 0" - player.chooseToUse(get.prompt('qinglong',trigger.target),function(card,player,event){ - if(get.name(card)!='sha') return false; - if(!player.hasSkill('qinglong_skill',null,false)){ - var cards=player.getEquips('qinglong'); - if(!cards.some(card2=>card2!=card&&!ui.selected.cards.includes(card2))) return false; - } - return lib.filter.filterCard.apply(this,arguments); - },trigger.target,-1).set('addCount',false).logSkill='qinglong_skill'; - } - }, - zhangba_skill:{ - equipSkill:true, - enable:['chooseToUse','chooseToRespond'], - filterCard:true, - selectCard:2, - position:'hs', - viewAs:{name:'sha'}, - complexCard:true, - filter:function(event,player){ - return player.countCards('hs')>=2; - }, - audio:true, - prompt:'将两张手牌当杀使用或打出', - check:function(card){ - let player=_status.event.player; - if(player.hasCard(function(card){ - return get.name(card)=='sha'; - })) return 0; - if(_status.event&&_status.event.name=='chooseToRespond'&&player.hp<3&&!player.countCards('hs',function(card){ - return get.name(card)!='tao'&&get.name(card)!='jiu'; - })) return (player.hp>1?10:8)-get.value(card); - return Math.max(5,8-0.7*player.hp)-get.value(card); - }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - return player.countCards('hs')>=2; }, - } + }, }, - guanshi_skill:{ - equipSkill:true, - trigger:{ - player:['shaMiss','eventNeutralized'], + qinggang2: { + firstDo: true, + ai: { unequip2: true }, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - direct:true, - audio:true, - filter:function(event,player){ - if(event.type!='card'||event.card.name!='sha'||!event.target.isIn()) return false; - var min=2; - if(!player.hasSkill('guanshi_skill',null,false)) min+=get.sgn(player.getEquips('guanshi').length) - return player.countCards('he')>=min; + onremove: true, + trigger: { + player: ["damage", "damageCancelled", "damageZero"], + source: ["damage", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded", "useCardToEnd", "eventNeutralized"], + global: ["useCardEnd"], }, - content:function(){ - "step 0" + charlotte: true, + filter: function (event, player) { + return ( + player.storage.qinggang2 && + event.card && + player.storage.qinggang2.includes(event.card) && + (event.name != "damage" || event.notLink()) + ); + }, + silent: true, + forced: true, + popup: false, + priority: 12, + content: function () { + player.storage.qinggang2.remove(trigger.card); + if (!player.storage.qinggang2.length) player.removeSkill("qinggang2"); + }, + marktext: "※", + intro: { content: "当前防具技能已失效" }, + }, + qinglong_skill: { + equipSkill: true, + trigger: { player: ["shaMiss", "eventNeutralized"] }, + direct: true, + filter: function (event, player) { + if (get.mode() == "guozhan" || !event.card || event.card.name != "sha") return false; + return ( + event.target.isIn() && + player.canUse("sha", event.target, false) && + (player.hasSha() || (_status.connectMode && player.countCards("hs"))) + ); + }, + content: function () { + "step 0"; + player + .chooseToUse( + get.prompt("qinglong", trigger.target), + function (card, player, event) { + if (get.name(card) != "sha") return false; + if (!player.hasSkill("qinglong_skill", null, false)) { + var cards = player.getEquips("qinglong"); + if ( + !cards.some( + (card2) => card2 != card && !ui.selected.cards.includes(card2) + ) + ) + return false; + } + return lib.filter.filterCard.apply(this, arguments); + }, + trigger.target, + -1 + ) + .set("addCount", false).logSkill = "qinglong_skill"; + }, + }, + zhangba_skill: { + equipSkill: true, + enable: ["chooseToUse", "chooseToRespond"], + filterCard: true, + selectCard: 2, + position: "hs", + viewAs: { name: "sha" }, + complexCard: true, + filter: function (event, player) { + return player.countCards("hs") >= 2; + }, + audio: true, + prompt: "将两张手牌当杀使用或打出", + check: function (card) { + let player = _status.event.player; + if ( + player.hasCard(function (card) { + return get.name(card) == "sha"; + }) + ) + return 0; + if ( + _status.event && + _status.event.name == "chooseToRespond" && + player.hp < 3 && + !player.countCards("hs", function (card) { + return get.name(card) != "tao" && get.name(card) != "jiu"; + }) + ) + return (player.hp > 1 ? 10 : 8) - get.value(card); + return Math.max(5, 8 - 0.7 * player.hp) - get.value(card); + }, + ai: { + respondSha: true, + skillTagFilter: function (player) { + return player.countCards("hs") >= 2; + }, + }, + }, + guanshi_skill: { + equipSkill: true, + trigger: { + player: ["shaMiss", "eventNeutralized"], + }, + direct: true, + audio: true, + filter: function (event, player) { + if (event.type != "card" || event.card.name != "sha" || !event.target.isIn()) + return false; + var min = 2; + if (!player.hasSkill("guanshi_skill", null, false)) + min += get.sgn(player.getEquips("guanshi").length); + return player.countCards("he") >= min; + }, + content: function () { + "step 0"; //装备区内可能有多个贯石斧 或者玩家可能通过其他渠道获得贯石斧技能 只要留一张贯石斧不扔掉即可 - var next=player.chooseToDiscard(get.prompt('guanshi'),2,'he',function(card,player){ - if(_status.event.ignoreCard) return true; - var cards=player.getEquips('guanshi'); - if(!cards.includes(card)) return true; - return cards.some(cardx=>(cardx!=card&&!ui.selected.cards.includes(cardx))); - }).set('ignoreCard',player.hasSkill('guanshi_skill',null,false)).set('complexCard',true) - next.logSkill='guanshi_skill'; - next.set('ai',function(card){ - var evt=_status.event.getTrigger(); - if(get.attitude(evt.player,evt.target)<0){ - if(player.needsToDiscard()) return 15-get.value(card); - if(evt.baseDamage+evt.extraDamage>=Math.min(2,evt.target.hp)) return 8-get.value(card); - return 5-get.value(card); + var next = player + .chooseToDiscard(get.prompt("guanshi"), 2, "he", function (card, player) { + if (_status.event.ignoreCard) return true; + var cards = player.getEquips("guanshi"); + if (!cards.includes(card)) return true; + return cards.some((cardx) => cardx != card && !ui.selected.cards.includes(cardx)); + }) + .set("ignoreCard", player.hasSkill("guanshi_skill", null, false)) + .set("complexCard", true); + next.logSkill = "guanshi_skill"; + next.set("ai", function (card) { + var evt = _status.event.getTrigger(); + if (get.attitude(evt.player, evt.target) < 0) { + if (evt.player.needsToDiscard()) return 15 - get.value(card); + if (evt.baseDamage + evt.extraDamage >= Math.min(2, evt.target.hp)) + return 8 - get.value(card); + return 5 - get.value(card); } return -1; }); - "step 1" - if(result.bool){ - if(event.triggername=='shaMiss'){ + "step 1"; + if (result.bool) { + if (event.triggername == "shaMiss") { trigger.untrigger(); - trigger.trigger('shaHit'); - trigger._result.bool=false; - trigger._result.result=null; - } - else{ + trigger.trigger("shaHit"); + trigger._result.bool = false; + trigger._result.result = null; + } else { trigger.unneutralize(); } } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(player._guanshi_temp) return; - player._guanshi_temp=true; - var bool=(get.attitude(player,arg.target)<0&&arg.card&&arg.card.name=='sha'&&player.countCards('he',function(card){ - return card!=player.getEquip('guanshi')&&card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card))&&get.value(card)<5; - })>1); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (player._guanshi_temp) return; + player._guanshi_temp = true; + var bool = + get.attitude(player, arg.target) < 0 && + arg.card && + arg.card.name == "sha" && + player.countCards("he", function (card) { + return ( + card != player.getEquip("guanshi") && + card != arg.card && + (!arg.card.cards || !arg.card.cards.includes(card)) && + get.value(card) < 5 + ); + }) > 1; delete player._guanshi_temp; return bool; }, }, }, - fangtian_skill:{ - equipSkill:true, - audio:true, - trigger:{player:'useCard1'}, - forced:true, - firstDo:true, - filter:function(event,player){ - if(event.card.name!='sha'||get.mode()=='guozhan') return false; - var card=event.card; + fangtian_skill: { + equipSkill: true, + audio: true, + trigger: { player: "useCard1" }, + forced: true, + firstDo: true, + filter: function (event, player) { + if (event.card.name != "sha" || get.mode() == "guozhan") return false; + var card = event.card; var range; - var select=get.copy(get.info(card).selectTarget); - if(select==undefined){ - if(get.info(card).filterTarget==undefined) return false; - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); - return range[1]!=-1&&event.targets.length>range[1]; + var select = get.copy(get.info(card).selectTarget); + if (select == undefined) { + if (get.info(card).filterTarget == undefined) return false; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); + return range[1] != -1 && event.targets.length > range[1]; }, - content:function(){}, - mod:{ - selectTarget:function(card,player,range){ - if(card.name!='sha') return; - if(get.mode()=='guozhan') return; - if(range[1]==-1) return; - var cards=player.getCards('h'); - if(!cards.length) return; - for(var i=0;i0 }, - direct:true, - audio:true, - content:function(){ - "step 0" - var att=(get.attitude(player,trigger.player)<=0); - var next=player.chooseButton(); - next.set('att',att); - next.set('createDialog',['是否发动【麒麟弓】,弃置'+get.translation(trigger.player)+'的一张坐骑牌?',trigger.player.getCards('e',{subtype:['equip3','equip4','equip6']})]); - next.set('ai',function(button){ - if(_status.event.att) return get.buttonValue(button); + }, + qilin_skill: { + equipSkill: true, + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.notLink() && + event.player.getCards("e", { subtype: ["equip3", "equip4", "equip6"] }).length > 0 + ); + }, + direct: true, + audio: true, + content: function () { + "step 0"; + var att = get.attitude(player, trigger.player) <= 0; + var next = player.chooseButton(); + next.set("att", att); + next.set("createDialog", [ + "是否发动【麒麟弓】,弃置" + get.translation(trigger.player) + "的一张坐骑牌?", + trigger.player.getCards("e", { subtype: ["equip3", "equip4", "equip6"] }), + ]); + next.set("ai", function (button) { + if (_status.event.att) return get.buttonValue(button); return 0; }); - "step 1" - if(result.bool){ - player.logSkill('qilin_skill',trigger.player); + "step 1"; + if (result.bool) { + player.logSkill("qilin_skill", trigger.player); trigger.player.discard(result.links[0]); } - } + }, }, - bagua_skill:{ - equipSkill:true, - trigger:{player:['chooseToRespondBegin','chooseToUseBegin']}, - filter:function(event,player){ - if(event.responded) return false; - if(event.bagua_skill) return false; - if(!event.filterCard||!event.filterCard({name:'shan'},player,event)) return false; - if(event.name=='chooseToRespond'&&!lib.filter.cardRespondable({name:'shan'},player,event)) return false; - if(player.hasSkillTag('unequip2')) return false; - var evt=event.getParent(); - if(evt.player&&evt.player.hasSkillTag('unequip',false,{ - name:evt.card?evt.card.name:null, - target:player, - card:evt.card - })) return false; + bagua_skill: { + equipSkill: true, + trigger: { player: ["chooseToRespondBegin", "chooseToUseBegin"] }, + filter: function (event, player) { + if (event.responded) return false; + if (event.bagua_skill) return false; + if (!event.filterCard || !event.filterCard({ name: "shan" }, player, event)) return false; + if ( + event.name == "chooseToRespond" && + !lib.filter.cardRespondable({ name: "shan" }, player, event) + ) + return false; + if (player.hasSkillTag("unequip2")) return false; + var evt = event.getParent(); + if ( + evt.player && + evt.player.hasSkillTag("unequip", false, { + name: evt.card ? evt.card.name : null, + target: player, + card: evt.card, + }) + ) + return false; return true; }, - audio:true, - check:function(event,player){ - if(!event) return true; - if(event.ai){ - var ai=event.ai; - var tmp=_status.event; - _status.event=event; - var result=ai({name:'shan'},_status.event.player,event); - _status.event=tmp; - return result>0; + audio: true, + check: function (event, player) { + if (!event) return true; + if (event.ai) { + var ai = event.ai; + var tmp = _status.event; + _status.event = event; + var result = ai({ name: "shan" }, _status.event.player, event); + _status.event = tmp; + return result > 0; } - let evt=event.getParent(); - if(player.hasSkillTag('noShan',null,evt)) return false; - if(!evt||!evt.card||!evt.player||player.hasSkillTag('useShan',null,evt)) return true; - if(evt.card&&evt.player&&player.isLinked()&&game.hasNature(evt.card)&&get.attitude(player,evt.player._trueMe||evt.player)>0) return false; + let evt = event.getParent(); + if (player.hasSkillTag("noShan", null, evt)) return false; + if (!evt || !evt.card || !evt.player || player.hasSkillTag("useShan", null, evt)) + return true; + if ( + evt.card && + evt.player && + player.isLinked() && + game.hasNature(evt.card) && + get.attitude(player, evt.player._trueMe || evt.player) > 0 + ) + return false; return true; }, - content:function(){ - "step 0" - trigger.bagua_skill=true; - player.judge('bagua',function(card){return (get.color(card)=='red')?1.5:-0.5}).judge2=function(result){ + content: function () { + "step 0"; + trigger.bagua_skill = true; + player.judge("bagua", function (card) { + return get.color(card) == "red" ? 1.5 : -0.5; + }).judge2 = function (result) { return result.bool; }; - "step 1" - if(result.judge>0){ + "step 1"; + if (result.judge > 0) { trigger.untrigger(); - trigger.set('responded',true); - trigger.result={bool:true,card:{name:'shan',isCard:true}} + trigger.set("responded", true); + trigger.result = { bool: true, card: { name: "shan", isCard: true } }; } }, - ai:{ - respondShan:true, - freeShan:true, - skillTagFilter(player,tag,arg){ - if(tag!=='respondShan'&&tag!=='freeShan') return; - if(player.hasSkillTag('unequip2')) return false; - if(!arg||!arg.player) return true; - if(arg.player.hasSkillTag('unequip',false,{ - target:player - })) return false; + ai: { + respondShan: true, + freeShan: true, + skillTagFilter(player, tag, arg) { + if (tag !== "respondShan" && tag !== "freeShan") return; + if (player.hasSkillTag("unequip2")) return false; + if (!arg || !arg.player) return true; + if ( + arg.player.hasSkillTag("unequip", false, { + target: player, + }) + ) + return false; return true; }, - effect:{ - target:function(card,player,target,effect){ - if(target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:target, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:target, - card:card - })) return; - if(get.tag(card,'respondShan')) return 0.5; - } - } - } + effect: { + target: function (card, player, target, effect) { + if (target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) + return; + if (get.tag(card, "respondShan")) return 0.5; + }, + }, + }, }, - _wuxie:{ - trigger:{player:['useCardToBegin','phaseJudge']}, - priority:5, - popup:false, - forced:true, - silent:true, - filter:function(event,player){ - if(event.card.storage&&event.card.storage.nowuxie) return false; - var card=event.card; - if(event.name=='phaseJudge'&&card.viewAs) card={name:card.viewAs}; - var info=get.info(card); - if(info.wuxieable===false) return false; - if(event.name!='phaseJudge'){ - if(event.getParent().nowuxie) return false; - if(event.player.hasSkillTag('playernowuxie',false,event.card)) return false; - if(get.type(event.card)!='trick'&&!info.wuxieable) return false; + _wuxie: { + trigger: { player: ["useCardToBegin", "phaseJudge"] }, + priority: 5, + popup: false, + forced: true, + silent: true, + filter: function (event, player) { + if (event.card.storage && event.card.storage.nowuxie) return false; + var card = event.card; + if (event.name == "phaseJudge" && card.viewAs) card = { name: card.viewAs }; + var info = get.info(card); + if (info.wuxieable === false) return false; + if (event.name != "phaseJudge") { + if (event.getParent().nowuxie) return false; + if (event.player.hasSkillTag("playernowuxie", false, event.card)) return false; + if (get.type(event.card) != "trick" && !info.wuxieable) return false; } return true; }, - forceLoad:true, - forceDie:true, - content:function(){ - 'step 0' + forceLoad: true, + forceDie: true, + content: function () { + "step 0"; delete event.wuxieresult; delete event.wuxieresult2; //创建map存储各种信息,用于hasHiddenWuxie判断 - var map={}; - event._info_map=map; - var card=trigger.card; - var state=true; - if(trigger.name=='phaseJudge'){ - if(get.itemtype(card)=='card'&&card.viewAs) card=get.autoViewAs({name:card.viewAs},[card]); - map.target=trigger.player; - map.isJudge=true; - } - else{ - map.player=trigger.player; - if(trigger.multitarget) map.multitargets=true; - map.target=trigger.target; - map.targets=trigger.targets; - map.tempnowuxie=(trigger.targets&&trigger.targets.length>1&&!trigger.multitarget); - map.noai=Boolean(trigger.getParent().noai); + var map = {}; + event._info_map = map; + var card = trigger.card; + var state = true; + if (trigger.name == "phaseJudge") { + if (get.itemtype(card) == "card" && card.viewAs) + card = get.autoViewAs({ name: card.viewAs }, [card]); + map.target = trigger.player; + map.isJudge = true; + } else { + map.player = trigger.player; + if (trigger.multitarget) map.multitargets = true; + map.target = trigger.target; + map.targets = trigger.targets; + map.tempnowuxie = + trigger.targets && trigger.targets.length > 1 && !trigger.multitarget; + map.noai = Boolean(trigger.getParent().noai); //如果对拼无懈,获取历史数据 - if(card.name=='wuxie'){ - var evt=event; - while(true){ - evt=evt.getParent(5); - if(evt&&evt.name=='_wuxie'){ - state=!state; - var evtmap=evt._info_map; - if(evtmap.card.name!='wuxie'){ - map._source=evtmap; + if (card.name == "wuxie") { + var evt = event; + while (true) { + evt = evt.getParent(5); + if (evt && evt.name == "_wuxie") { + state = !state; + var evtmap = evt._info_map; + if (evtmap.card.name != "wuxie") { + map._source = evtmap; } - } - else break; + } else break; } } } - map.card=card; - map.state=state?1:-1; - map.id2=trigger.getParent().id; - event._global_waiting=true; + map.card = card; + map.state = state ? 1 : -1; + map.id2 = trigger.getParent().id; + event._global_waiting = true; //发送函数 - event.send=function(player,map,skillState){ + event.send = function (player, map, skillState) { //获取技能数据 - if(skillState){ + if (skillState) { player.applySkills(skillState); } //生成描述提示 - var prompt='',evtmap=map,state=map.state; - if(map._source) evtmap=map._source; - if(evtmap.isJudge){ - prompt+=(get.translation(evtmap.target)+'的'+get.translation(evtmap.card)+'即将'+(state>0?'生':'失')+'效。'); - } - else{ - prompt+=get.translation(evtmap.player); - if(evtmap.multitarget){ - if(evtmap.targets.length){ - prompt+='对'; - prompt+=get.translation(evtmap.targets); + var prompt = "", + evtmap = map, + state = map.state; + if (map._source) evtmap = map._source; + if (evtmap.isJudge) { + prompt += + get.translation(evtmap.target) + + "的" + + get.translation(evtmap.card) + + "即将" + + (state > 0 ? "生" : "失") + + "效。"; + } else { + prompt += get.translation(evtmap.player); + if (evtmap.multitarget) { + if (evtmap.targets.length) { + prompt += "对"; + prompt += get.translation(evtmap.targets); } + } else if (evtmap.target) { + prompt += "对"; + prompt += + evtmap.target == evtmap.player ? "自己" : get.translation(evtmap.target); } - else if(evtmap.target){ - prompt+='对'; - prompt+=(evtmap.target==evtmap.player?'自己':get.translation(evtmap.target)); - } - prompt+=('使用的'+get.translation(evtmap.card)); - prompt+=('即将'+(state>0?'生':'失')+'效。'); + prompt += "使用的" + get.translation(evtmap.card); + prompt += "即将" + (state > 0 ? "生" : "失") + "效。"; } - prompt+='是否使用【无懈可击】?'; - if(player.isUnderControl(true)&&!_status.auto&&!ui.tempnowuxie&&map.tempnowuxie){ - var translation=get.translation(map.card.name); - if(translation.length>=4){ - translation=lib.translate[map.card.name+'_ab']||translation.slice(0,2); + prompt += "是否使用【无懈可击】?"; + if ( + player.isUnderControl(true) && + !_status.auto && + !ui.tempnowuxie && + map.tempnowuxie + ) { + var translation = get.translation(map.card.name); + if (translation.length >= 4) { + translation = lib.translate[map.card.name + "_ab"] || translation.slice(0, 2); } - ui.tempnowuxie=ui.create.control('不无懈'+translation,ui.click.tempnowuxie,'stayleft'); - ui.tempnowuxie._origin=map.id2; + ui.tempnowuxie = ui.create.control( + "不无懈" + translation, + ui.click.tempnowuxie, + "stayleft" + ); + ui.tempnowuxie._origin = map.id2; } - var next=player.chooseToUse({ - filterCard:function(card,player){ - if(get.name(card)!='wuxie') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); + var next = player.chooseToUse({ + filterCard: function (card, player) { + if (get.name(card) != "wuxie") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); }, - prompt:prompt, - type:'wuxie', - _global_waiting:true, - ai1:function(){ - if(map.isJudge){ - var card=evtmap.card,source=evtmap.target; - var name=card.viewAs||card.name; - var info=lib.card[name]; - if(info&&info.ai&&info.ai.wuxie){ - var aiii=info.ai.wuxie(source,card,source,_status.event.player,state); - if(typeof aiii=='number') return aiii; + prompt: prompt, + type: "wuxie", + _global_waiting: true, + ai1: function () { + if (map.isJudge) { + var card = evtmap.card, + source = evtmap.target; + var name = card.viewAs || card.name; + var info = lib.card[name]; + if (info && info.ai && info.ai.wuxie) { + var aiii = info.ai.wuxie( + source, + card, + source, + _status.event.player, + state + ); + if (typeof aiii == "number") return aiii; } - if(Math.abs(get.attitude(_status.event.player,source))<3) return 0; - if(source.hasSkillTag('nowuxie_judge')||source.hasSkillTag('guanxing')&&(source!=player||!source.hasSkill('guanxing_fail'))) return 0; - if(name!='lebu'&&name!='bingliang'){ - if(source!=_status.event.player){ + if (Math.abs(get.attitude(_status.event.player, source)) < 3) return 0; + if ( + source.hasSkillTag("nowuxie_judge") || + (source.hasSkillTag("guanxing") && + (source != player || !source.hasSkill("guanxing_fail"))) + ) + return 0; + if (name != "lebu" && name != "bingliang") { + if (source != _status.event.player) { return 0; } } - if(name=='bingliang'&&source.countCards('j')>0&&source.countCards('h')>=source.hp-1){ + if ( + name == "bingliang" && + source.countCards("j") > 0 && + source.countCards("h") >= source.hp - 1 + ) { return 0; } var card2; - if(name!=card.name){ - card2={name:name}; + if (name != card.name) { + card2 = { name: name }; + } else { + card2 = card; } - else{ - card2=card; - } - var eff=get.effect(source,card2,source,source); - if(eff>=0) return 0; - return state*get.attitude(_status.event.player,source); - } - else if(evtmap.target){ - var triggerevent=_status.event.getTrigger(); - if(triggerevent&&triggerevent.parent&& - triggerevent.parent.postAi&& - triggerevent.player.isUnknown(_status.event.player)){ + var eff = get.effect(source, card2, source, source); + if (eff >= 0) return 0; + return state * get.attitude(_status.event.player, source); + } else if (evtmap.target) { + var triggerevent = _status.event.getTrigger(); + if ( + triggerevent && + triggerevent.parent && + triggerevent.parent.postAi && + triggerevent.player.isUnknown(_status.event.player) + ) { return 0; } - var card=evtmap.card,target=evtmap.target,source=evtmap.player; - var info=get.info(card); - if(info.ai&&info.ai.wuxie){ - var aiii=info.ai.wuxie(target,card,source,_status.event.player,state); - if(typeof aiii=='number') return aiii; + var card = evtmap.card, + target = evtmap.target, + source = evtmap.player; + var info = get.info(card); + if (info.ai && info.ai.wuxie) { + var aiii = info.ai.wuxie( + target, + card, + source, + _status.event.player, + state + ); + if (typeof aiii == "number") return aiii; } - if(info.multitarget&&targets){ - var eff=0; - for(var i=0;i这是一种十分含蓄的计谋。', - wuxie_info:'一张锦囊牌生效前,对此牌使用。抵消此牌对一名角色产生的效果,或抵消另一张【无懈可击】产生的效果。', - lebu_info:'出牌阶段,对一名其他角色使用。若判定结果不为红桃,跳过其出牌阶段。', - shandian_info:'出牌阶段,对自己使用。若判定结果为黑桃2~9,则目标角色受到3点雷电伤害。若判定不为黑桃2~9,将之移动到下家的判定区里。', - icesha_skill:'冰冻', - icesha_skill_info:'防止即将造成的伤害,改为依次弃置其两张牌。', - sha_notshan:'invisible', - qinggang2:'破防', + translate: { + sha: "杀", + huosha: "火杀", + leisha: "雷杀", + icesha: "冰杀", + kamisha: "神杀", + cisha: "刺杀", + shan: "闪", + tao: "桃", + bagua: "八卦阵", + bagua_bg: "卦", + bagua_skill: "八卦阵", + jueying: "绝影", + dilu: "的卢", + zhuahuang: "爪黄飞电", + jueying_bg: "+马", + dilu_bg: "+马", + zhuahuang_bg: "+马", + chitu: "赤兔", + chitu_bg: "-马", + dawan: "大宛", + dawan_bg: "-马", + zixin: "紫骍", + zixin_bg: "-马", + zhuge: "诸葛连弩", + cixiong: "雌雄双股剑", + zhuge_bg: "弩", + cixiong_bg: "双", + qinggang: "青釭剑", + qinglong: "青龙偃月刀", + zhangba: "丈八蛇矛", + qinglong_bg: "偃", + zhangba_bg: "蛇", + guanshi: "贯石斧", + fangtian: "方天画戟", + qilin: "麒麟弓", + qilin_bg: "弓", + zhuge_skill: "诸葛连弩", + cixiong_skill: "雌雄双股剑", + qinggang_skill: "青釭剑", + qinglong_skill: "青龙偃月刀", + qinglong_guozhan: "青龙偃月刀", + zhangba_skill: "丈八蛇矛", + guanshi_skill: "贯石斧", + fangtian_skill: "方天画戟", + qilin_skill: "麒麟弓", + wugu: "五谷丰登", + taoyuan: "桃园结义", + nanman: "南蛮入侵", + wanjian: "万箭齐发", + wuzhong: "无中生有", + juedou: "决斗", + wugu_bg: "谷", + taoyuan_bg: "园", + nanman_bg: "蛮", + wanjian_bg: "箭", + wuzhong_bg: "生", + juedou_bg: "斗", + shunshou: "顺手牵羊", + guohe: "过河拆桥", + guohe_bg: "拆", + jiedao: "借刀杀人", + wuxie: "无懈可击", + wuxie_bg: "懈", + lebu: "乐不思蜀", + shandian: "闪电", + shandian_bg: "电", + hanbing: "寒冰剑", + renwang: "仁王盾", + hanbing_bg: "冰", + renwang_bg: "盾", + hanbing_skill: "寒冰剑", + renwang_skill: "仁王盾", + hanbing_info: + "当你因执行【杀】的效果而造成伤害时,若目标角色有能被弃置的牌,则你可以防止此伤害,然后依次弃置目标角色的两张牌。", + hanbing_skill_info: + "当你因执行【杀】的效果而造成伤害时,若目标角色有能被弃置的牌,则你可以防止此伤害,然后依次弃置目标角色的两张牌。", + renwang_info: "锁定技,黑色【杀】对你无效。", + renwang_skill_info: "锁定技,黑色【杀】对你无效。", + sha_info: "出牌阶段,对你攻击范围内的一名角色使用。其须使用一张【闪】,否则你对其造成1点伤害。", + shan_info: "抵消一张【杀】。", + tao_info: + "①出牌阶段,对自己使用,目标角色回复1点体力。②当有角色处于濒死状态时,对该角色使用。目标角色回复1点体力。", + bagua_info: + "当你需要使用或打出一张【闪】时,你可以进行判定。若结果为红色,则你视为使用或打出一张【闪】。", + bagua_skill_info: + "当你需要使用或打出一张【闪】时,你可以进行判定。若结果为红色,则你视为使用或打出一张【闪】。", + jueying_info: "锁定技,其他角色计算与你的距离+1。", + dilu_info: "锁定技,其他角色计算与你的距离+1。", + zhuahuang_info: "锁定技,其他角色计算与你的距离+1。", + chitu_info: "锁定技,你计算与其他角色的距离-1。", + dawan_info: "锁定技,你计算与其他角色的距离-1。", + zixin_info: "锁定技,你计算与其他角色的距离-1。", + zhuge_skill_info: "锁定技,你于出牌阶段内使用【杀】无次数限制。", + zhuge_info: "锁定技,你于出牌阶段内使用【杀】无次数限制。", + cixiong_skill_info: + "当你使用【杀】指定一名异性的目标角色后,你可以令其选择一项:1.弃置一张手牌;2.令你摸一张牌。", + cixiong_info: + "当你使用【杀】指定一名异性的目标角色后,你可以令其选择一项:1.弃置一张手牌;2.令你摸一张牌。", + qinggang_skill_info: + "锁定技,当你使用【杀】指定一名目标角色后,你令其防具技能无效直到此【杀】被抵消或造成伤害。", + qinggang_info: + "锁定技,当你使用【杀】指定一名目标角色后,你令其防具技能无效直到此【杀】被抵消或造成伤害。", + qinglong_skill_info: + "当你使用的【杀】被目标角色使用的【闪】抵消时,你可以对其使用一张【杀】(无距离限制)。", + qinglong_guozhan_info: + "锁定技,当你使用【杀】指定目标后,所有目标角色不能明置武将牌直到此【杀】结算完毕为止。", + qinglong_info: + "当你使用的【杀】被目标角色使用的【闪】抵消时,你可以对其使用一张【杀】(无距离限制)。", + qinglong_info_guozhan: + "锁定技,当你使用【杀】指定目标后,所有目标角色不能明置武将牌直到此【杀】结算完毕为止。", + zhangba_skill_info: "你可以将两张手牌当【杀】使用或打出。", + zhangba_info: "你可以将两张手牌当【杀】使用或打出。", + guanshi_skill_info: + "当你使用的【杀】被目标角色使用的【闪】抵消时,你可以弃置两张牌,令此【杀】依然对其造成伤害。", + guanshi_info: + "当你使用的【杀】被目标角色使用的【闪】抵消时,你可以弃置两张牌,令此【杀】依然对其造成伤害。", + fangtian_skill_info: "你使用的【杀】若是你最后的手牌,你可以额外选择至多两个目标。", + fangtian_info: "你使用的【杀】若是你最后的手牌,你可以额外选择至多两个目标。", + fangtian_info_guozhan: + "你使用【杀】可以指定任意名角色为目标(不能包含势力相同的角色),若任意一名目标角色使用【闪】抵消了此【杀】,则此【杀】对剩余的目标角色无效。", + qilin_skill_info: "当你使用【杀】对目标角色造成伤害时,你可以弃置其装备区里的一张坐骑牌。", + qilin_info: "当你使用【杀】对目标角色造成伤害时,你可以弃置其装备区里的一张坐骑牌。", + wugu_info: + "出牌阶段,对所有角色使用。(选择目标后)你从牌堆顶亮出等同于目标数量的牌,每名目标角色获得这些牌中(剩余的)的任意一张。", + taoyuan_info: "出牌阶段,对所有角色使用。每名目标角色回复1点体力。", + nanman_info: "出牌阶段,对所有其他角色使用。每名目标角色需打出一张【杀】,否则受到1点伤害。", + wanjian_info: "出牌阶段,对所有其他角色使用。每名目标角色需打出一张【闪】,否则受到1点伤害。", + wuzhong_info: "出牌阶段,对你使用。你摸两张牌。", + juedou_info: + "出牌阶段,对一名其他角色使用。由其开始,其与你轮流打出一张【杀】,直到其中一方未打出【杀】为止。未打出【杀】的一方受到另一方对其造成的1点伤害。", + shunshou_info: "出牌阶段,对距离为1且区域里有牌的一名其他角色使用。你获得其区域里的一张牌。", + guohe_info: "出牌阶段,对区域里有牌的一名其他角色使用。你弃置其区域里的一张牌。", + jiedao_info: + "出牌阶段,对装备区里有武器牌且有使用【杀】的目标的一名其他角色使用。令其对你指定的一名角色使用一张【杀】,否则将其装备区里的武器牌交给你。", + jiedao_append: '这是一种十分含蓄的计谋。', + wuxie_info: + "一张锦囊牌生效前,对此牌使用。抵消此牌对一名角色产生的效果,或抵消另一张【无懈可击】产生的效果。", + lebu_info: "出牌阶段,对一名其他角色使用。若判定结果不为红桃,跳过其出牌阶段。", + shandian_info: + "出牌阶段,对自己使用。若判定结果为黑桃2~9,则目标角色受到3点雷电伤害。若判定不为黑桃2~9,将之移动到下家的判定区里。", + icesha_skill: "冰冻", + icesha_skill_info: "防止即将造成的伤害,改为依次弃置其两张牌。", + sha_notshan: "invisible", + qinggang2: "破防", }, - list:[ - ["spade",7,"sha"], - ["spade",8,"sha"], - ["spade",8,"sha"], - ["spade",9,"sha"], - ["spade",9,"sha"], - ["spade",10,"sha"], - ["spade",10,"sha"], - ["club",2,"sha"], - ["club",3,"sha"], - ["club",4,"sha"], - ["club",5,"sha"], - ["club",6,"sha"], - ["club",7,"sha"], - ["club",8,"sha"], - ["club",8,"sha"], - ["club",9,"sha"], - ["club",9,"sha"], - ["club",10,"sha"], - ["club",10,"sha"], - ["club",11,"sha"], - ["club",11,"sha"], - ["heart",10,"sha"], - ["heart",10,"sha"], - ["heart",11,"sha"], - ["diamond",6,"sha"], - ["diamond",7,"sha"], - ["diamond",8,"sha"], - ["diamond",9,"sha"], - ["diamond",10,"sha"], - ["diamond",13,"sha"], - ["heart",2,"shan"], - ["heart",2,"shan"], - ["heart",13,"shan"], - ["diamond",2,"shan"], - ["diamond",2,"shan"], - ["diamond",3,"shan"], - ["diamond",4,"shan"], - ["diamond",5,"shan"], - ["diamond",6,"shan"], - ["diamond",7,"shan"], - ["diamond",8,"shan"], - ["diamond",9,"shan"], - ["diamond",10,"shan"], - ["diamond",11,"shan"], - ["diamond",11,"shan"], - ["heart",3,"tao"], - ["heart",4,"tao"], - ["heart",6,"tao"], - ["heart",7,"tao"], - ["heart",8,"tao"], - ["heart",9,"tao"], - ["heart",12,"tao"], - ["diamond",12,"tao"], + list: [ + ["spade", 7, "sha"], + ["spade", 8, "sha"], + ["spade", 8, "sha"], + ["spade", 9, "sha"], + ["spade", 9, "sha"], + ["spade", 10, "sha"], + ["spade", 10, "sha"], + ["club", 2, "sha"], + ["club", 3, "sha"], + ["club", 4, "sha"], + ["club", 5, "sha"], + ["club", 6, "sha"], + ["club", 7, "sha"], + ["club", 8, "sha"], + ["club", 8, "sha"], + ["club", 9, "sha"], + ["club", 9, "sha"], + ["club", 10, "sha"], + ["club", 10, "sha"], + ["club", 11, "sha"], + ["club", 11, "sha"], + ["heart", 10, "sha"], + ["heart", 10, "sha"], + ["heart", 11, "sha"], + ["diamond", 6, "sha"], + ["diamond", 7, "sha"], + ["diamond", 8, "sha"], + ["diamond", 9, "sha"], + ["diamond", 10, "sha"], + ["diamond", 13, "sha"], + ["heart", 2, "shan"], + ["heart", 2, "shan"], + ["heart", 13, "shan"], + ["diamond", 2, "shan"], + ["diamond", 2, "shan"], + ["diamond", 3, "shan"], + ["diamond", 4, "shan"], + ["diamond", 5, "shan"], + ["diamond", 6, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "shan"], + ["diamond", 10, "shan"], + ["diamond", 11, "shan"], + ["diamond", 11, "shan"], + ["heart", 3, "tao"], + ["heart", 4, "tao"], + ["heart", 6, "tao"], + ["heart", 7, "tao"], + ["heart", 8, "tao"], + ["heart", 9, "tao"], + ["heart", 12, "tao"], + ["diamond", 12, "tao"], - ["spade",2,"bagua"], - ["club",2,"bagua"], - ["spade",5,"jueying"], - ["club",5,"dilu"], - ["heart",13,"zhuahuang"], - ["heart",5,"chitu"], - ["spade",13,"dawan"], - ["diamond",13,"zixin"], - ["club",1,"zhuge"], - ["diamond",1,"zhuge"], - ["spade",2,"cixiong"], - ["spade",6,"qinggang"], - ["spade",5,"qinglong"], - ["spade",12,"zhangba"], - ["diamond",5,"guanshi"], - ["diamond",12,"fangtian"], - ["heart",5,"qilin"], + ["spade", 2, "bagua"], + ["club", 2, "bagua"], + ["spade", 5, "jueying"], + ["club", 5, "dilu"], + ["heart", 13, "zhuahuang"], + ["heart", 5, "chitu"], + ["spade", 13, "dawan"], + ["diamond", 13, "zixin"], + ["club", 1, "zhuge"], + ["diamond", 1, "zhuge"], + ["spade", 2, "cixiong"], + ["spade", 6, "qinggang"], + ["spade", 5, "qinglong"], + ["spade", 12, "zhangba"], + ["diamond", 5, "guanshi"], + ["diamond", 12, "fangtian"], + ["heart", 5, "qilin"], - ["heart",3,"wugu"], - ["heart",4,"wugu"], - ["heart",1,"taoyuan"], - ["spade",7,"nanman"], - ["spade",13,"nanman"], - ["club",7,"nanman"], - ["heart",1,"wanjian"], - ["spade",1,"juedou"], - ["club",1,"juedou"], - ["diamond",1,"juedou"], - ["heart",7,"wuzhong"], - ["heart",8,"wuzhong"], - ["heart",9,"wuzhong"], - ["heart",11,"wuzhong"], - ["spade",3,'shunshou'], - ["spade",4,'shunshou'], - ["spade",11,'shunshou'], - ["diamond",3,'shunshou'], - ["diamond",4,'shunshou'], - ["spade",3,'guohe'], - ["spade",4,'guohe'], - ["spade",12,'guohe'], - ["club",3,'guohe'], - ["club",4,'guohe'], - ["heart",12,'guohe'], - ["club",12,'jiedao'], - ["club",13,'jiedao'], - ["spade",11,'wuxie'], - ["club",12,'wuxie'], - ["club",13,'wuxie'], - ["spade",6,'lebu'], - ["club",6,'lebu'], - ["heart",6,'lebu'], - ["spade",1,'shandian'], - ["spade",2,'hanbing'], - ["club",2,'renwang'], - ["heart",12,'shandian'], - ["diamond",12,'wuxie'], + ["heart", 3, "wugu"], + ["heart", 4, "wugu"], + ["heart", 1, "taoyuan"], + ["spade", 7, "nanman"], + ["spade", 13, "nanman"], + ["club", 7, "nanman"], + ["heart", 1, "wanjian"], + ["spade", 1, "juedou"], + ["club", 1, "juedou"], + ["diamond", 1, "juedou"], + ["heart", 7, "wuzhong"], + ["heart", 8, "wuzhong"], + ["heart", 9, "wuzhong"], + ["heart", 11, "wuzhong"], + ["spade", 3, "shunshou"], + ["spade", 4, "shunshou"], + ["spade", 11, "shunshou"], + ["diamond", 3, "shunshou"], + ["diamond", 4, "shunshou"], + ["spade", 3, "guohe"], + ["spade", 4, "guohe"], + ["spade", 12, "guohe"], + ["club", 3, "guohe"], + ["club", 4, "guohe"], + ["heart", 12, "guohe"], + ["club", 12, "jiedao"], + ["club", 13, "jiedao"], + ["spade", 11, "wuxie"], + ["club", 12, "wuxie"], + ["club", 13, "wuxie"], + ["spade", 6, "lebu"], + ["club", 6, "lebu"], + ["heart", 6, "lebu"], + ["spade", 1, "shandian"], + ["spade", 2, "hanbing"], + ["club", 2, "renwang"], + ["heart", 12, "shandian"], + ["diamond", 12, "wuxie"], ], }; }); diff --git a/card/swd.js b/card/swd.js index bb5764f0b..37f12d477 100644 --- a/card/swd.js +++ b/card/swd.js @@ -1,19 +1,19 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'swd', - card:{ - hufu:{ - fullskin:true, - type:'basic', - global:['g_hufu_sha','g_hufu_shan','g_hufu_jiu'], - savable:function(card,player,dying){ - return dying==player; + name: "swd", + card: { + hufu: { + fullskin: true, + type: "basic", + global: ["g_hufu_sha", "g_hufu_shan", "g_hufu_jiu"], + savable: function (card, player, dying) { + return dying == player; + }, + ai: { + value: [7.5, 5, 2], + useful: [7.5, 5, 2], }, - ai:{ - value:[7.5,5,2], - useful:[7.5,5,2], - } }, // yihuajiemu:{ // fullskin:true, @@ -64,1143 +64,1175 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // } // } // }, - liuxinghuoyu:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - cardcolor:'red', - cardnature:'fire', - content:function(){ - "step 0" - if(target.countCards('he')<2){ - event.directfalse=true; - } - else{ - target.chooseToDiscard('he',2).ai=function(card){ - if(target.hasSkillTag('nofire')) return 0; - if(get.damageEffect(target,player,target,'fire')>=0) return 0; - if(player.hasSkillTag('notricksource')) return 0; - if(target.hasSkillTag('notrick')) return 0; - if(card.name=='tao') return 0; - if(target.hp==1&&card.name=='jiu') return 0; - if(target.hp==1&&get.type(card)!='basic'){ - return 10-get.value(card); + liuxinghuoyu: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + cardcolor: "red", + cardnature: "fire", + content: function () { + "step 0"; + if (target.countCards("he") < 2) { + event.directfalse = true; + } else { + target.chooseToDiscard("he", 2).ai = function (card) { + if (target.hasSkillTag("nofire")) return 0; + if (get.damageEffect(target, player, target, "fire") >= 0) return 0; + if (player.hasSkillTag("notricksource")) return 0; + if (target.hasSkillTag("notrick")) return 0; + if (card.name == "tao") return 0; + if (target.hp == 1 && card.name == "jiu") return 0; + if (target.hp == 1 && get.type(card) != "basic") { + return 10 - get.value(card); } - return 8-get.value(card); + return 8 - get.value(card); }; } - "step 1" - if(event.directfalse||!result.bool){ - target.damage('fire'); + "step 1"; + if (event.directfalse || !result.bool) { + target.damage("fire"); } }, - ai:{ - basic:{ - order:4, - value:7, - useful:2, + ai: { + basic: { + order: 4, + value: 7, + useful: 2, }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nofire')) return 0; - if(get.damageEffect(target,player,player)<0&&get.attitude(player,target)>0){ + result: { + target: function (player, target) { + if (target.hasSkillTag("nofire")) return 0; + if ( + get.damageEffect(target, player, player) < 0 && + get.attitude(player, target) > 0 + ) { return -2; } - var nh=target.countCards('he'); - if(target==player) nh--; - switch(nh){ - case 0:case 1:return -2; - case 2:return -1.5; - case 3:return -1; - default:return -0.7; + var nh = target.countCards("he"); + if (target == player) nh--; + switch (nh) { + case 0: + case 1: + return -2; + case 2: + return -1.5; + case 3: + return -1; + default: + return -0.7; } - } + }, + }, + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + discard: 1, + loseCard: 1, + position: "he", }, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - discard:1, - loseCard:1, - position:'he', - } - } - }, - dujian:{ - fullskin:true, - type:'basic', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('h')>0; }, - content:function(){ - "step 0" - if(target.countCards('h')==0||player.countCards('h')==0){ + }, + dujian: { + fullskin: true, + type: "basic", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0; + }, + content: function () { + "step 0"; + if (target.countCards("h") == 0 || player.countCards("h") == 0) { event.finish(); return; } player.chooseCard(true); - "step 1" - event.card1=result.cards[0]; - var rand=Math.random()<0.5; - target.chooseCard(true).ai=function(card){ - if(rand) return Math.random(); + "step 1"; + event.card1 = result.cards[0]; + var rand = Math.random() < 0.5; + target.chooseCard(true).ai = function (card) { + if (rand) return Math.random(); return get.value(card); }; - "step 2" - event.card2=result.cards[0]; - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1,target,event.card2); + "step 2"; + event.card2 = result.cards[0]; + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + player.$compare(event.card1, target, event.card2); game.delay(4); - "step 3" - game.log(player,'展示了',event.card1); - game.log(target,'展示了',event.card2); - if(get.color(event.card2)==get.color(event.card1)){ - player.discard(event.card1).animate=false; + "step 3"; + game.log(player, "展示了", event.card1); + game.log(target, "展示了", event.card2); + if (get.color(event.card2) == get.color(event.card1)) { + player.discard(event.card1).animate = false; target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } target.loseHp(); - } - else{ + } else { player.$gain2(event.card1); target.$gain2(event.card2); - target.addTempSkill('dujian2'); + target.addTempSkill("dujian2"); } - ui.arena.classList.remove('thrownhighlight'); - game.addVideo('thrownhighlight2'); + ui.arena.classList.remove("thrownhighlight"); + game.addVideo("thrownhighlight2"); }, - ai:{ - basic:{ - order:2, - value:3, - useful:1, + ai: { + basic: { + order: 2, + value: 3, + useful: 1, }, - result:{ - player:function(player,target){ - if(player.countCards('h')<=Math.min(5,Math.max(2,player.hp))&&_status.event.name=='chooseToUse'){ - if(typeof _status.event.filterCard=='function'&& - _status.event.filterCard({name:'dujian'})){ + result: { + player: function (player, target) { + if ( + player.countCards("h") <= Math.min(5, Math.max(2, player.hp)) && + _status.event.name == "chooseToUse" + ) { + if ( + typeof _status.event.filterCard == "function" && + _status.event.filterCard({ name: "dujian" }) + ) { return -10; } - if(_status.event.skill){ - var viewAs=get.info(_status.event.skill).viewAs; - if(viewAs=='dujian') return -10; - if(viewAs&&viewAs.name=='dujian') return -10; + if (_status.event.skill) { + var viewAs = get.info(_status.event.skill).viewAs; + if (viewAs == "dujian") return -10; + if (viewAs && viewAs.name == "dujian") return -10; } } return 0; }, - target:function(player,target){ - if(target.hasSkill('dujian2')||target.countCards('h')==0) return 0; - if(player.countCards('h')<=1) return 0; + target: function (player, target) { + if (target.hasSkill("dujian2") || target.countCards("h") == 0) return 0; + if (player.countCards("h") <= 1) return 0; return -1.5; - } + }, + }, + tag: { + loseHp: 1, }, - tag:{ - loseHp:1 - } - } - }, - yangpijuan:{ - fullskin:true, - type:'trick', - enable:true, - toself:true, - filterTarget:function(card,player,target){ - return target==player; }, - modTarget:true, - content:function(){ - 'step 0' + }, + yangpijuan: { + fullskin: true, + type: "trick", + enable: true, + toself: true, + filterTarget: function (card, player, target) { + return target == player; + }, + modTarget: true, + content: function () { + "step 0"; var choice; - if(target.countCards('h','shan')==0||target.countCards('h','sha')==0||target.hp<=1){ - choice='basic'; - } - else{ - var e2=target.getEquip(2); - var e3=target.getEquip(3); - if((e2&&e3)||((e2||e3)&&target.needsToDiscard()<=1)||Math.random()<0.5){ - choice='trick'; - } - else{ - choice='equip'; + if ( + target.countCards("h", "shan") == 0 || + target.countCards("h", "sha") == 0 || + target.hp <= 1 + ) { + choice = "basic"; + } else { + var e2 = target.getEquip(2); + var e3 = target.getEquip(3); + if ( + (e2 && e3) || + ((e2 || e3) && target.needsToDiscard() <= 1) || + Math.random() < 0.5 + ) { + choice = "trick"; + } else { + choice = "equip"; } } - target.chooseControl('basic','trick','equip',function(){ - return choice; - }).set('prompt','选择一种卡牌类型'); - 'step 1' - var list=get.inpile(result.control,'trick'); - list=list.randomGets(3); - for(var i=0;i=0) return 0; + ai: { + order: 1, + useful: 5, + value: 6, + result: { + target: function (player, target) { + if (target == player) { + if (get.damageEffect(target, player, target) >= 0) return 0; return 1; - } - else{ - if(get.attitude(player,target)>0) return 0; - if(get.damageEffect(target,player,target)>=0) return 0; + } else { + if (get.attitude(player, target) > 0) return 0; + if (get.damageEffect(target, player, target) >= 0) return 0; return -1; } - } + }, }, - } - }, - yuruyi:{ - type:'equip', - subtype:'equip5', - skills:['yuruyi'], - fullskin:true, - ai:{ - basic:{ - equipValue:6 - } }, }, - fengyinzhidan:{ - type:'basic', - enable:true, - fullskin:true, - filterTarget:function(card,player,target){ - return target==player; + yuruyi: { + type: "equip", + subtype: "equip5", + skills: ["yuruyi"], + fullskin: true, + ai: { + basic: { + equipValue: 6, + }, }, - selectTarget:-1, - modTarget:true, + }, + fengyinzhidan: { + type: "basic", + enable: true, + fullskin: true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + modTarget: true, // usable:1, - content:function(){ - 'step 0' - event.num=2; - var list=[]; - event.list=list; - for(var i=0;i0&&info.selectTarget[1]>=info.selectTarget[0]){ + content: function () { + "step 0"; + event.num = 2; + var list = []; + event.list = list; + for (var i = 0; i < lib.inpile.length; i++) { + if (lib.filter.filterCard({ name: lib.inpile[i] }, target)) { + var info = lib.card[lib.inpile[i]]; + if (info.type == "trick" && !info.multitarget && !info.notarget) { + if (Array.isArray(info.selectTarget)) { + if ( + info.selectTarget[0] > 0 && + info.selectTarget[1] >= info.selectTarget[0] + ) { list.push(lib.inpile[i]); } - } - else if(typeof info.selectTarget=='number'){ + } else if (typeof info.selectTarget == "number") { list.push(lib.inpile[i]); } } } } - 'step 1' - var list=event.list; - while(list.length){ - var card={name:list.randomRemove()}; - var info=get.info(card); - var targets=game.filterPlayer(function(current){ - return lib.filter.filterTarget(card,target,current); + "step 1"; + var list = event.list; + while (list.length) { + var card = { name: list.randomRemove() }; + var info = get.info(card); + var targets = game.filterPlayer(function (current) { + return lib.filter.filterTarget(card, target, current); }); - if(targets.length){ + if (targets.length) { targets.sort(lib.sort.seat); - if(info.selectTarget==-1){ - target.useCard(card,targets,'noai'); - } - else{ - var num=info.selectTarget; - if(Array.isArray(num)){ - if(targets.length0){ + if (--event.num > 0) { event.redo(); } break; } } }, - ai:{ - order:9, - value:8, - useful:3, - result:{ - target:1 - } - } - }, - yuchanqian:{ - fullskin:true, - type:'jiqi', - addinfo:'杀', - autoViewAs:'sha', - global:['g_yuchan_swap','g_yuchan_equip'], - ai:{ - value:6, - useful:[5,1] - } - }, - yuchankun:{ - fullskin:true, - type:'jiqi', - addinfo:'药', - autoViewAs:'caoyao', - global:['g_yuchan_swap','g_yuchan_equip'], - ai:{ - value:6, - useful:[7,2] - } - }, - yuchanzhen:{ - fullskin:true, - type:'jiqi', - autoViewAs:'jiu', - addinfo:'酒', - global:['g_yuchan_swap','g_yuchan_equip'], - savable:function(card,player,dying){ - return dying==player; - }, - ai:{ - value:6, - useful:[4,1] - } - }, - yuchanxun:{ - fullskin:true, - type:'jiqi', - autoViewAs:'tao', - addinfo:'桃', - global:['g_yuchan_swap','g_yuchan_equip'], - savable:true, - ai:{ - value:6, - useful:[8,6.5] - } - }, - yuchankan:{ - fullskin:true, - type:'jiqi', - autoViewAs:'shenmiguo', - global:['g_yuchan_swap','g_yuchan_equip'], - addinfo:'果', - ai:{ - order:1, - useful:4, - value:6, - result:{ - player:function(){ - var cardname=_status.event.cardname; - if(cardname=='tiesuo') return 0; - if(cardname=='jiu') return 0; - if(cardname=='tianxianjiu') return 0; - if(cardname=='toulianghuanzhu') return 0; - if(cardname=='shijieshu') return 0; - if(cardname=='xietianzi') return 0; - if(cardname=='huogong') return 0; - if(cardname=='shandianjian') return 0; - return 1; - } + ai: { + order: 9, + value: 8, + useful: 3, + result: { + target: 1, }, - } - }, - yuchanli:{ - fullskin:true, - type:'jiqi', - autoViewAs:'tianxianjiu', - global:['g_yuchan_swap','g_yuchan_equip'], - addinfo:'仙', - savable:function(card,player,dying){ - return dying==player; }, - ai:{ - value:6, - useful:1 - } }, - yuchangen:{ - fullskin:true, - type:'jiqi', - addinfo:'蛋', - autoViewAs:'fengyinzhidan', - global:['g_yuchan_swap','g_yuchan_equip'], - ai:{ - value:6, - useful:1 - } - }, - yuchandui:{ - fullskin:true, - type:'jiqi', - addinfo:'雪', - autoViewAs:'xuejibingbao', - global:['g_yuchan_swap','g_yuchan_equip'], - ai:{ - value:6, - useful:4 - } - }, - mujiaren:{ - fullskin:true, - enable:true, - type:'jiguan', - usable:1, - updateUsable:'phaseUse', - forceUsable:true, - wuxieable:true, - selectTarget:-1, - filterTarget:function(card,player,target){ - return target==player; + yuchanqian: { + fullskin: true, + type: "jiqi", + addinfo: "杀", + autoViewAs: "sha", + global: ["g_yuchan_swap", "g_yuchan_equip"], + ai: { + value: 6, + useful: [5, 1], }, - content:function(){ - 'step 0' - var cards=target.getCards('h',function(card){ - return get.type(card)!='basic'; + }, + yuchankun: { + fullskin: true, + type: "jiqi", + addinfo: "药", + autoViewAs: "caoyao", + global: ["g_yuchan_swap", "g_yuchan_equip"], + ai: { + value: 6, + useful: [7, 2], + }, + }, + yuchanzhen: { + fullskin: true, + type: "jiqi", + autoViewAs: "jiu", + addinfo: "酒", + global: ["g_yuchan_swap", "g_yuchan_equip"], + savable: function (card, player, dying) { + return dying == player; + }, + ai: { + value: 6, + useful: [4, 1], + }, + }, + yuchanxun: { + fullskin: true, + type: "jiqi", + autoViewAs: "tao", + addinfo: "桃", + global: ["g_yuchan_swap", "g_yuchan_equip"], + savable: true, + ai: { + value: 6, + useful: [8, 6.5], + }, + }, + yuchankan: { + fullskin: true, + type: "jiqi", + autoViewAs: "shenmiguo", + global: ["g_yuchan_swap", "g_yuchan_equip"], + addinfo: "果", + ai: { + order: 1, + useful: 4, + value: 6, + result: { + player: function () { + var cardname = _status.event.cardname; + if (cardname == "tiesuo") return 0; + if (cardname == "jiu") return 0; + if (cardname == "tianxianjiu") return 0; + if (cardname == "toulianghuanzhu") return 0; + if (cardname == "shijieshu") return 0; + if (cardname == "xietianzi") return 0; + if (cardname == "huogong") return 0; + if (cardname == "shandianjian") return 0; + return 1; + }, + }, + }, + }, + yuchanli: { + fullskin: true, + type: "jiqi", + autoViewAs: "tianxianjiu", + global: ["g_yuchan_swap", "g_yuchan_equip"], + addinfo: "仙", + savable: function (card, player, dying) { + return dying == player; + }, + ai: { + value: 6, + useful: 1, + }, + }, + yuchangen: { + fullskin: true, + type: "jiqi", + addinfo: "蛋", + autoViewAs: "fengyinzhidan", + global: ["g_yuchan_swap", "g_yuchan_equip"], + ai: { + value: 6, + useful: 1, + }, + }, + yuchandui: { + fullskin: true, + type: "jiqi", + addinfo: "雪", + autoViewAs: "xuejibingbao", + global: ["g_yuchan_swap", "g_yuchan_equip"], + ai: { + value: 6, + useful: 4, + }, + }, + mujiaren: { + fullskin: true, + enable: true, + type: "jiguan", + usable: 1, + updateUsable: "phaseUse", + forceUsable: true, + wuxieable: true, + selectTarget: -1, + filterTarget: function (card, player, target) { + return target == player; + }, + content: function () { + "step 0"; + var cards = target.getCards("h", function (card) { + return get.type(card) != "basic"; }); - if(cards.length){ - target.lose(cards)._triggered=null; + if (cards.length) { + target.lose(cards)._triggered = null; } - event.num=1+cards.length; - 'step 1' - var cards=[]; - var list=get.typeCard('jiguan'); - for(var i=0;i=0) return 0; - return 8-get.useful(card); + content: function () { + target.storage.gouhunluo = 3; + target.storage.gouhunluo2 = player; + target.addSkill("gouhunluo"); + }, + ai: { + order: 2, + value: 5, + result: { + target: function (player, target) { + return -1 / Math.max(1, target.hp); + }, + }, + }, + }, + zhuquezhizhang: { + type: "jiqi", + fullskin: true, + global: "g_zhuquezhizhang", + ai: { + value: 8, + useful: 6.5, + }, + }, + xuanwuzhihuang: { + type: "jiqi", + fullskin: true, + global: "g_xuanwuzhihuang", + ai: { + value: 8, + useful: 6.5, + }, + }, + huanglinzhicong: { + type: "jiqi", + fullskin: true, + global: "g_huanglinzhicong", + ai: { + value: 8, + useful: 6.5, + }, + }, + cangchizhibi: { + type: "jiqi", + fullskin: true, + global: "g_cangchizhibi", + ai: { + value: 8, + useful: 6.5, + }, + }, + qinglongzhigui: { + type: "jiqi", + fullskin: true, + global: "g_qinglongzhigui", + ai: { + value: 8, + useful: 6.5, + }, + }, + baishouzhihu: { + type: "jiqi", + fullskin: true, + global: "g_baishouzhihu", + ai: { + value: 8, + useful: 6.5, + }, + }, + jiguantong: { + fullskin: true, + type: "jiguan", + enable: true, + wuxieable: true, + selectTarget: -1, + reverseOrder: true, + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + if (target.countCards("h")) { + var next = target.chooseToDiscard("机关火筒:弃置一张手牌或受到1点火焰伤害"); + next.set("ai", function (card) { + var evt = _status.event.getParent(); + if (get.damageEffect(evt.target, evt.player, evt.target, "fire") >= 0) return 0; + return 8 - get.useful(card); }); - } - else{ - target.damage('fire'); - event.parent.preResult=true; + } else { + target.damage("fire"); + event.parent.preResult = true; event.finish(); } - "step 1" - if(result.bool==false){ - target.damage('fire'); - event.parent.preResult=true; + "step 1"; + if (result.bool == false) { + target.damage("fire"); + event.parent.preResult = true; } }, - contentAfter:function(){ - if(!event.preResult) player.draw(); + contentAfter: function () { + if (!event.preResult) player.draw(); }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0){ - if(target.countCards('h')>0||target.hp>1) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.attitude(viewer, target) > 0) { + if (target.countCards("h") > 0 || target.hp > 1) return 0; } }, - basic:{ - order:9, - useful:1 + basic: { + order: 9, + useful: 1, }, - result:{ - target:function(player,target){ - if(player.hasUnknown(2)) return 0; - var nh=target.countCards('h'); - if(get.mode()=='identity'){ - if(target.isZhu&&nh<=1&&target.hp<=1) return -100; + result: { + target: function (player, target) { + if (player.hasUnknown(2)) return 0; + var nh = target.countCards("h"); + if (get.mode() == "identity") { + if (target.isZhu && nh <= 1 && target.hp <= 1) return -100; } - if(nh==0) return -1; - if(nh==1) return -0.7 + if (nh == 0) return -1; + if (nh == 1) return -0.7; return -0.5; }, }, - tag:{ - discard:1, - loseCard:1, - damage:1, - natureDamage:1, - fireDamage:1, - multitarget:1, - multineg:1, - } - } - }, - donghuangzhong:{ - fullskin:true, - type:'equip', - subtype:'equip5', - nomod:true, - nopower:true, - unique:true, - skills:['donghuangzhong'], - ai:{ - equipValue:7 - } - }, - xuanyuanjian:{ - fullskin:true, - type:'equip', - subtype:'equip1', - nomod:true, - nopower:true, - unique:true, - skills:['xuanyuanjian','xuanyuanjian2','xuanyuanjian3'], - enable:function(card,player){ - return player.hasSkill('xuanyuan')||player.hp>2; + tag: { + discard: 1, + loseCard: 1, + damage: 1, + natureDamage: 1, + fireDamage: 1, + multitarget: 1, + multineg: 1, + }, }, - distance:{attackFrom:-2}, - onEquip:function(){ - if(!player.hasSkill('xuanyuan')&&player.hp<=2){ + }, + donghuangzhong: { + fullskin: true, + type: "equip", + subtype: "equip5", + nomod: true, + nopower: true, + unique: true, + skills: ["donghuangzhong"], + ai: { + equipValue: 7, + }, + }, + xuanyuanjian: { + fullskin: true, + type: "equip", + subtype: "equip1", + nomod: true, + nopower: true, + unique: true, + skills: ["xuanyuanjian", "xuanyuanjian2", "xuanyuanjian3"], + enable: function (card, player) { + return player.hasSkill("xuanyuan") || player.hp > 2; + }, + distance: { attackFrom: -2 }, + onEquip: function () { + if (!player.hasSkill("xuanyuan") && player.hp <= 2) { player.discard(card); - } - else{ + } else { player.changeHujia(); } }, - ai:{ - equipValue:9 - } - }, - pangufu:{ - fullskin:true, - type:'equip', - subtype:'equip1', - skills:['pangufu'], - nomod:true, - nopower:true, - unique:true, - distance:{attackFrom:-3}, - ai:{ - equipValue:8 - } - }, - lianyaohu:{ - fullskin:true, - type:'equip', - subtype:'equip5', - equipDelay:false, - loseDelay:false, - nomod:true, - nopower:true, - unique:true, - onEquip:function(){ - player.markSkill('lianyaohu_skill'); + ai: { + equipValue: 9, }, - onLose:function(){ - player.unmarkSkill('lianyaohu_skill'); + }, + pangufu: { + fullskin: true, + type: "equip", + subtype: "equip1", + skills: ["pangufu"], + nomod: true, + nopower: true, + unique: true, + distance: { attackFrom: -3 }, + ai: { + equipValue: 8, }, - clearLose:true, - ai:{ - equipValue:6 + }, + lianyaohu: { + fullskin: true, + type: "equip", + subtype: "equip5", + equipDelay: false, + loseDelay: false, + nomod: true, + nopower: true, + unique: true, + onEquip: function () { + player.markSkill("lianyaohu_skill"); }, - skills:['lianhua','shouna','lianyaohu_skill'] + onLose: function () { + player.unmarkSkill("lianyaohu_skill"); + }, + clearLose: true, + ai: { + equipValue: 6, + }, + skills: ["lianhua", "shouna", "lianyaohu_skill"], }, - haotianta:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['haotianta'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:7 - } + haotianta: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["haotianta"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 7, + }, }, - fuxiqin:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['kongxin'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:6 - } + fuxiqin: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["kongxin"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 6, + }, }, - shennongding:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['shennongding'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:6 - } + shennongding: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["shennongding"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 6, + }, }, - kongdongyin:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['kongdongyin'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:function(card,player){ - if(player.hp==2) return 7; - if(player.hp==1) return 10; + kongdongyin: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["kongdongyin"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: function (card, player) { + if (player.hp == 2) return 7; + if (player.hp == 1) return 10; return 5; }, - basic:{ - equipValue:7 - } - } + basic: { + equipValue: 7, + }, + }, }, - kunlunjingc:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['kunlunjingc'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:6 - } + kunlunjingc: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["kunlunjingc"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 6, + }, }, - nvwashi:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['nvwashi'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:5 - } + nvwashi: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["nvwashi"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 5, + }, }, - guisheqi:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - content:function(){ + guisheqi: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + content: function () { target.changeHujia(); }, - ai:{ - basic:{ - order:5, - useful:3, - value:[6,2,1] + ai: { + basic: { + order: 5, + useful: 3, + value: [6, 2, 1], }, - result:{ - target:function(player,target){ - return 2/Math.max(1,Math.sqrt(target.hp)); + result: { + target: function (player, target) { + return 2 / Math.max(1, Math.sqrt(target.hp)); }, }, - } - }, - jiguanfeng:{ - fullskin:true, - type:'jiguan', - enable:true, - wuxieable:true, - filterTarget:function(card,player,target){ - return target!=player; }, - content:function(){ - "step 0" - var next=target.chooseToRespond({name:'shan'}); - next.autochoose=lib.filter.autoRespondShan; - "step 1" - if(result.bool==false){ - if(!target.hasSkill('fengyin')){ - target.addTempSkill('fengyin',{player:'phaseBegin'}); + }, + jiguanfeng: { + fullskin: true, + type: "jiguan", + enable: true, + wuxieable: true, + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + var next = target.chooseToRespond({ name: "shan" }); + next.autochoose = lib.filter.autoRespondShan; + "step 1"; + if (result.bool == false) { + if (!target.hasSkill("fengyin")) { + target.addTempSkill("fengyin", { player: "phaseBegin" }); } target.damage(); - } - else{ + } else { event.finish(); } }, - ai:{ - basic:{ - order:9, - useful:3, - value:6.5, + ai: { + basic: { + order: 9, + useful: 3, + value: 6.5, }, - result:{ - target:-2, + result: { + target: -2, }, - tag:{ - respond:1, - respondShan:1, + tag: { + respond: 1, + respondShan: 1, // damage:1, - } - } + }, + }, }, - jiguanyuan:{ - fullskin:true, - type:'jiguan', - wuxieable:true, - enable:function(card,player){ - var hs=player.getCards('he'); - return hs.length>1||(hs.length==1&&hs[0]!=card); + jiguanyuan: { + fullskin: true, + type: "jiguan", + wuxieable: true, + enable: function (card, player) { + var hs = player.getCards("he"); + return hs.length > 1 || (hs.length == 1 && hs[0] != card); }, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('jiguanyuan'); + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("jiguanyuan"); }, - content:function(){ - 'step 0' - if(player.countCards('he')){ - player.chooseCard(true,'he').set('prompt2','你将'+ - get.translation(cards)+'和选择牌置于'+get.translation(target)+ - '的武将牌上,然后摸一张牌;'+get.translation(target)+ - '于下一结束阶段获得武将牌上的牌'); - } - else{ + content: function () { + "step 0"; + if (player.countCards("he")) { + player + .chooseCard(true, "he") + .set( + "prompt2", + "你将" + + get.translation(cards) + + "和选择牌置于" + + get.translation(target) + + "的武将牌上,然后摸一张牌;" + + get.translation(target) + + "于下一结束阶段获得武将牌上的牌" + ); + } else { event.finish(); } - 'step 1' + "step 1"; player.$throw(result.cards); - player.lose(result.cards,ui.special); + player.lose(result.cards, ui.special); ui.special.appendChild(cards[0]); - event.togive=[cards[0],result.cards[0]]; + event.togive = [cards[0], result.cards[0]]; game.delay(); - 'step 2' + "step 2"; // target.gain(event.togive).delay=false; target.$gain2(event.togive); - target.storage.jiguanyuan=event.togive; - target.addSkill('jiguanyuan'); - game.log(target,'从',player,'获得了',event.togive); + target.storage.jiguanyuan = event.togive; + target.addSkill("jiguanyuan"); + game.log(target, "从", player, "获得了", event.togive); player.draw(); }, - ai:{ - basic:{ - order:2, - useful:2, - value:7 + ai: { + basic: { + order: 2, + useful: 2, + value: 7, }, - result:{ - target:function(player,target){ - var players=game.filterPlayer(function(current){ - return (current!=player&&!current.isTurnedOver()&& - get.attitude(player,current)>=3&&get.attitude(current,player)>=3) + result: { + target: function (player, target) { + var players = game.filterPlayer(function (current) { + return ( + current != player && + !current.isTurnedOver() && + get.attitude(player, current) >= 3 && + get.attitude(current, player) >= 3 + ); }); players.sort(lib.sort.seat); - if(target==players[0]) return 2; + if (target == players[0]) return 2; return 0.5; }, }, - } - }, - shenmiguo_old:{ - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - filterTarget:function(card,player,target){ - return target==player; }, - modTarget:true, - content:function(){ - var list=[]; - for(var i in lib.card){ - if(lib.card[i].derivation){ + }, + shenmiguo_old: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + filterTarget: function (card, player, target) { + return target == player; + }, + modTarget: true, + content: function () { + var list = []; + for (var i in lib.card) { + if (lib.card[i].derivation) { list.push(i); } } - if(get.mode()=='stone'){ - list.remove('hslingjian_jinjilengdong'); + if (get.mode() == "stone") { + list.remove("hslingjian_jinjilengdong"); } - if(list.length){ - target.gain(game.createCard(list.randomGet()),'draw'); + if (list.length) { + target.gain(game.createCard(list.randomGet()), "draw"); } }, - ai:{ - basic:{ - order:7.3, - useful:2, - value:6 + ai: { + basic: { + order: 7.3, + useful: 2, + value: 6, }, - result:{ - target:2, + result: { + target: 2, }, - } + }, }, - shenmiguo:{ - fullskin:true, - type:'basic', - global:'g_shenmiguo', - content:function(){ - if(Array.isArray(player.storage.shenmiguo)){ - player.useCard(player.storage.shenmiguo[0],player.storage.shenmiguo[1]); + shenmiguo: { + fullskin: true, + type: "basic", + global: "g_shenmiguo", + content: function () { + if (Array.isArray(player.storage.shenmiguo)) { + player.useCard(player.storage.shenmiguo[0], player.storage.shenmiguo[1]); } }, - ai:{ - order:1, - useful:6, - value:6, - result:{ - player:function(){ - var cardname=_status.event.cardname; - if(get.tag({name:cardname},'norepeat')) return 0; + ai: { + order: 1, + useful: 6, + value: 6, + result: { + player: function () { + var cardname = _status.event.cardname; + if (get.tag({ name: cardname }, "norepeat")) return 0; return 1; - } + }, }, - } - }, - qinglianxindeng:{ - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['qinglianxindeng'], - ai:{ - basic:{ - equipValue:8 - } }, }, - lingjiandai:{ - fullskin:true, - enable:true, - type:'jiguan', - wuxieable:true, - filterTarget:function(card,player,target){ - return target==player; + qinglianxindeng: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["qinglianxindeng"], + ai: { + basic: { + equipValue: 8, + }, }, - selectTarget:-1, - modTarget:true, - content:function(){ - var list=get.typeCard('hslingjian'); - if(list.length){ - list=list.randomGets(3); - for(var i=0;i0; - }, - content:function(){ - target.discard(target.getCards('he').randomGet()); - }, - ai:{ - order:9, - result:{ - target:-1, + order: 10.1, + value: [5, 1], + result: { + target: function (player, target) { + return 1 / (1 + target.countCards("e")); + }, }, - useful:[2,0.5], - value:[2,0.5], - } + }, }, - hslingjian_zhongxinghujia:{ - type:'hslingjian', - fullimage:true, - vanish:true, - enable:true, - derivation:true, - derivationpack:'swd', - filterTarget:function(card,player,target){ + hslingjian_xuanfengzhiren: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { + return target.countCards("he") > 0; + }, + content: function () { + target.discard(target.getCards("he").randomGet()); + }, + ai: { + order: 9, + result: { + target: -1, + }, + useful: [2, 0.5], + value: [2, 0.5], + }, + }, + hslingjian_zhongxinghujia: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { return !target.isMin(); }, - content:function(){ - 'step 0' - var list=[]; - for(var i=0;i6) return num; + if (player == target) { + if (hs.length == 2) return num; + if (hs.length == 1) return num + 1; + if (hs.length <= 4) { + for (var i = 0; i < hs.length; i++) { + if (get.value(hs[i]) > 6) return num; } } - if(hs.length>4) return num+0.5; - } - else{ - if(hs.length){ - if(hs.length<=3) return num; - return num+0.5; + if (hs.length > 4) return num + 0.5; + } else { + if (hs.length) { + if (hs.length <= 3) return num; + return num + 0.5; } } - return num+1; + return num + 1; } - } + }, }, - useful:[2,0.5], - value:[2,0.5], - } - }, - hslingjian_xingtigaizao:{ - type:'hslingjian', - fullimage:true, - vanish:true, - enable:true, - derivation:true, - derivationpack:'swd', - filterTarget:function(card,player,target){ - return target==player; + useful: [2, 0.5], + value: [2, 0.5], }, - selectTarget:-1, - content:function(){ + }, + hslingjian_xingtigaizao: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + content: function () { target.draw(); - target.addSkill('hslingjian_xingtigaizao'); - if(typeof target.storage.hslingjian_xingtigaizao=='number'){ + target.addSkill("hslingjian_xingtigaizao"); + if (typeof target.storage.hslingjian_xingtigaizao == "number") { target.storage.hslingjian_xingtigaizao++; - } - else{ - target.storage.hslingjian_xingtigaizao=1; + } else { + target.storage.hslingjian_xingtigaizao = 1; } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(!player.needsToDiscard()) return 1; + ai: { + order: 9, + result: { + target: function (player, target) { + if (!player.needsToDiscard()) return 1; return 0; - } + }, }, - useful:[2,0.5], - value:[2,0.5], - } - }, - hslingjian_shijianhuisu:{ - type:'hslingjian', - fullimage:true, - vanish:true, - enable:true, - derivation:true, - derivationpack:'swd', - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('e')>0; + useful: [2, 0.5], + value: [2, 0.5], }, - content:function(){ - var es=target.getCards('e'); + }, + hslingjian_shijianhuisu: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { + return target != player && target.countCards("e") > 0; + }, + content: function () { + var es = target.getCards("e"); target.gain(es); target.$gain2(es); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noe')||target.hasSkillTag('reverseEquip')) return target.countCards('e')*2; - if(target.getEquip('baiyin')&&target.isDamaged()) return 2; - if(target.getEquip('xuanyuanjian')||target.getEquip('qiankundai')) return 1; - if(target.hasSkill('jiguanyaoshu_skill')) return 0.5; - var num=0; - var es=target.getCards('e'); - for(var i=0;i4) return -1.2*num; - else if(target.hp==4) return -1*num; - else if(target.hp==3) return -0.9*num; - else if(target.hp==2) return -0.5*num; - else{ - if(target.maxHp>2){ - if(target.hujia) return 0.5*num; + ai: { + order: 2, + result: { + target: function (player, target) { + var num = get.threaten(target, player); + if (target.hasSkillTag("noturn")) return 2 * num; + if (target.hp > 4) return -1.2 * num; + else if (target.hp == 4) return -1 * num; + else if (target.hp == 3) return -0.9 * num; + else if (target.hp == 2) return -0.5 * num; + else { + if (target.maxHp > 2) { + if (target.hujia) return 0.5 * num; return num; } return 0; } }, }, - useful:[2,0.5], - value:[2,0.5], - } + useful: [2, 0.5], + value: [2, 0.5], + }, }, - hslingjian_shengxiuhaojiao:{ - type:'hslingjian', - fullimage:true, - vanish:true, - enable:true, - derivation:true, - derivationpack:'swd', - filterTarget:function(card,player,target){ - return !target.hasSkill('hslingjian_chaofeng'); + hslingjian_shengxiuhaojiao: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { + return !target.hasSkill("hslingjian_chaofeng"); }, - content:function(){ - target.addTempSkill('hslingjian_chaofeng',{player:'phaseBegin'}); + content: function () { + target.addTempSkill("hslingjian_chaofeng", { player: "phaseBegin" }); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(get.distance(player,target,'absolute')<=1) return 0; - if(target.countCards('h')<=target.hp) return -0.1; + ai: { + order: 2, + result: { + target: function (player, target) { + if (get.distance(player, target, "absolute") <= 1) return 0; + if (target.countCards("h") <= target.hp) return -0.1; return -1; - } + }, }, - useful:[2,0.5], - value:[2,0.5], - } - }, - hslingjian_yinmilichang:{ - type:'hslingjian', - fullimage:true, - vanish:true, - enable:true, - derivation:true, - derivationpack:'swd', - filterTarget:function(card,player,target){ - return player!=target&&!target.hasSkill('qianxing'); + useful: [2, 0.5], + value: [2, 0.5], }, - content:function(){ + }, + hslingjian_yinmilichang: { + type: "hslingjian", + fullimage: true, + vanish: true, + enable: true, + derivation: true, + derivationpack: "swd", + filterTarget: function (card, player, target) { + return player != target && !target.hasSkill("qianxing"); + }, + content: function () { target.tempHide(); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(get.distance(player,target,'absolute')<=1) return 0; - if(target.hp==1) return 2; - if(target.hp==2&&target.countCards('h')<=2) return 1.2; - return 1; - } - }, - useful:[2,0.5], - value:[2,0.5], - } - }, - xingjunyan:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['xingjunyan'], - ai:{ - basic:{ - equipValue:4 - }, - }, - }, - qinglonglingzhu:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['qinglonglingzhu'], - ai:{ - basic:{ - equipValue:5 - }, - }, - }, - baihupifeng:{ - fullskin:true, - type:"equip", - subtype:"equip2", - skills:['baihupifeng'], - ai:{ - equipValue:function(card,player){ - if(player.hp<=2) return 8; - return 6; - }, - basic:{ - equipValue:7 - }, - }, - }, - fengxueren:{ - fullskin:true, - type:"equip", - subtype:"equip1", - distance:{attackFrom:-1}, - skills:['fengxueren'], - ai:{ - basic:{ - equipValue:5 - }, - }, - }, - chilongya:{ - fullskin:true, - type:"equip", - subtype:"equip1", - distance:{attackFrom:-1}, - skills:['chilongya'], - ai:{ - basic:{ - equipValue:4 - }, - }, - }, - daihuofenglun:{ - type:'equip', - subtype:'equip4', - fullskin:true, - cardnature:'fire', - distance:{globalFrom:-2,globalTo:-1}, - ai:{ - basic:{ - equipValue:4 - }, - }, - }, - xiayuncailing:{ - type:'equip', - subtype:'equip3', - fullskin:true, - distance:{globalFrom:1,globalTo:2}, - }, - shentoumianju:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['shentou'], - ai:{ - basic:{ - equipValue:7, - } - } - }, - xianluhui:{ - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - reverseOrder:true, - filterTarget:function(card,player,target){ - return target.isDamaged(); - }, - content:function(){ - target.changeHujia(); - }, - ai:{ - tag:{ - multitarget:1, - }, - basic:{ - order:7, - useful:3, - value:3, - }, - result:{ - target:function(player,target){ - if(target.hp<=1) return 1.5; - if(target.hp==2) return 1.2; + ai: { + order: 2, + result: { + target: function (player, target) { + if (get.distance(player, target, "absolute") <= 1) return 0; + if (target.hp == 1) return 2; + if (target.hp == 2 && target.countCards("h") <= 2) return 1.2; return 1; }, }, - } - }, - xiangyuye:{ - type:'basic', - enable:true, - fullskin:true, - filterTarget:function(card,player,target){ - return get.distance(player,target,'attack')>1; + useful: [2, 0.5], + value: [2, 0.5], }, - content:function(){ - "step 0" - if(!target.countCards('h',{color:'black'})){ + }, + xingjunyan: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["xingjunyan"], + ai: { + basic: { + equipValue: 4, + }, + }, + }, + qinglonglingzhu: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["qinglonglingzhu"], + ai: { + basic: { + equipValue: 5, + }, + }, + }, + baihupifeng: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["baihupifeng"], + ai: { + equipValue: function (card, player) { + if (player.hp <= 2) return 8; + return 6; + }, + basic: { + equipValue: 7, + }, + }, + }, + fengxueren: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["fengxueren"], + ai: { + basic: { + equipValue: 5, + }, + }, + }, + chilongya: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["chilongya"], + ai: { + basic: { + equipValue: 4, + }, + }, + }, + daihuofenglun: { + type: "equip", + subtype: "equip4", + fullskin: true, + cardnature: "fire", + distance: { globalFrom: -2, globalTo: -1 }, + ai: { + basic: { + equipValue: 4, + }, + }, + }, + xiayuncailing: { + type: "equip", + subtype: "equip3", + fullskin: true, + distance: { globalFrom: 1, globalTo: 2 }, + }, + shentoumianju: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["shentou"], + ai: { + basic: { + equipValue: 7, + }, + }, + }, + xianluhui: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + reverseOrder: true, + filterTarget: function (card, player, target) { + return target.isDamaged(); + }, + content: function () { + target.changeHujia(); + }, + ai: { + tag: { + multitarget: 1, + }, + basic: { + order: 7, + useful: 3, + value: 3, + }, + result: { + target: function (player, target) { + if (target.hp <= 1) return 1.5; + if (target.hp == 2) return 1.2; + return 1; + }, + }, + }, + }, + xiangyuye: { + type: "basic", + enable: true, + fullskin: true, + filterTarget: function (card, player, target) { + return get.distance(player, target, "attack") > 1; + }, + content: function () { + "step 0"; + if (!target.countCards("h", { color: "black" })) { target.loseHp(); event.finish(); + } else { + target.chooseToDiscard({ color: "black" }, "弃置一张黑色手牌或受失去1点体力").ai = + function (card) { + return 8 - get.value(card); + }; } - else{ - target.chooseToDiscard({color:'black'},'弃置一张黑色手牌或受失去1点体力').ai=function(card){ - return 8-get.value(card); - }; - } - "step 1" - if(!result.bool){ + "step 1"; + if (!result.bool) { target.loseHp(); } }, - ai:{ - basic:{ - order:9, - value:3, - useful:1, + ai: { + basic: { + order: 9, + value: 3, + useful: 1, }, - result:{ - target:-2 + result: { + target: -2, + }, + tag: { + discard: 1, + loseHp: 1, }, - tag:{ - discard:1, - loseHp:1 - } - } - }, - caoyao:{ - fullskin:true, - type:'basic', - range:{global:1}, - enable:true, - filterTarget:function(card,player,target){ - return target.hp0}, - notarget:true, - mode:['identity','guozhan'], - fullskin:true, - content:function(){ - "step 0" - var list=[]; - for(var i=0;i 0; + }, + notarget: true, + mode: ["identity", "guozhan"], + fullskin: true, + content: function () { + "step 0"; + var list = []; + for (var i = 0; i < game.dead.length; i++) { list.push(game.dead[i].name); } - player.chooseButton(ui.create.dialog('选择要复活的角色',[list,'character']),function(button){ - for(var i=0;i3) return 7; + order: function (card, player) { + for (var i = 0; i < game.dead.length; i++) { + if (get.attitude(player, game.dead[i]) > 3) return 7; } return -10; }, - result:{ - player:function(player){ - for(var i=0;i3) return 2; + result: { + player: function (player) { + for (var i = 0; i < game.dead.length; i++) { + if (get.attitude(player, game.dead[i]) > 3) return 2; } return -10; - } + }, }, - } + }, }, - tianxianjiu:{ - fullskin:true, - type:'basic', - toself:true, - enable:function(event,player){ - return !player.hasSkill('tianxianjiu'); + tianxianjiu: { + fullskin: true, + type: "basic", + toself: true, + enable: function (event, player) { + return !player.hasSkill("tianxianjiu"); }, - savable:function(card,player,dying){ - return dying==player; + savable: function (card, player, dying) { + return dying == player; }, - usable:1, - selectTarget:-1, - logv:false, - modTarget:true, - filterTarget:function(card,player,target){ - return target==player; + usable: 1, + selectTarget: -1, + logv: false, + modTarget: true, + filterTarget: function (card, player, target) { + return target == player; }, - content:function(){ - "step 0" - if(target.isDying()) target.recover(); - else{ - target.addTempSkill('tianxianjiu',['phaseAfter','shaAfter']); - if(cards&&cards.length){ - card=cards[0]; + content: function () { + "step 0"; + if (target.isDying()) target.recover(); + else { + target.addTempSkill("tianxianjiu", ["phaseAfter", "shaAfter"]); + if (cards && cards.length) { + card = cards[0]; } - if(target==targets[0]&&card.clone&&(card.clone.parentNode==player.parentNode||card.clone.parentNode==ui.arena)){ + if ( + target == targets[0] && + card.clone && + (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena) + ) { card.clone.moveDelete(target); - game.addVideo('gain2',target,get.cardsInfo([card])); + game.addVideo("gain2", target, get.cardsInfo([card])); } - if(!target.node.jiu&&lib.config.jiu_effect){ - target.node.jiu=ui.create.div('.playerjiu',target.node.avatar); - target.node.jiu2=ui.create.div('.playerjiu',target.node.avatar2); + if (!target.node.jiu && lib.config.jiu_effect) { + target.node.jiu = ui.create.div(".playerjiu", target.node.avatar); + target.node.jiu2 = ui.create.div(".playerjiu", target.node.avatar2); } } }, - ai:{ - basic:{ - useful:function(card,i){ - if(_status.event.player.hp>1){ - if(i==0) return 5; + ai: { + basic: { + useful: function (card, i) { + if (_status.event.player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 3; }, - value:function(card,player,i){ - if(player.hp>1){ - if(i==0) return 5; + value: function (card, player, i) { + if (player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 3; }, }, - order:function(){ - return get.order({name:'sha'})+0.2; + order: function () { + return get.order({ name: "sha" }) + 0.2; }, - result:{ - target:function(player,target){ - if(target&&target.isDying()) return 2; - if(lib.config.mode=='stone'&&!player.isMin()){ - if(player.getActCount()+1>=player.actcount) return false; + result: { + target: function (player, target) { + if (target && target.isDying()) return 2; + if (lib.config.mode == "stone" && !player.isMin()) { + if (player.getActCount() + 1 >= player.actcount) return false; } - var shas=player.getCards('h','sha'); - if(shas.length>1&&player.getCardUsable('sha')>1){ + var shas = player.getCards("h", "sha"); + if (shas.length > 1 && player.getCardUsable("sha") > 1) { return 0; } var card; - if(shas.length){ - for(var i=0;i0); - })){ + if (card) { + if ( + game.hasPlayer(function (current) { + return ( + !current.hujia && + get.attitude(target, current) < 0 && + target.canUse(card, current, true, true) && + get.effect(current, card, target) > 0 + ); + }) + ) { return 1; } } return 0; }, }, - } + }, }, - huanpodan:{ - fullskin:true, - type:'basic', - enable:true, - logv:false, - filterTarget:function(card,player,target){ - return !target.hasSkill('huanpodan_skill'); + huanpodan: { + fullskin: true, + type: "basic", + enable: true, + logv: false, + filterTarget: function (card, player, target) { + return !target.hasSkill("huanpodan_skill"); }, - content:function(){ - target.addSkill('huanpodan_skill'); - if(cards&&cards.length){ - card=cards[0]; + content: function () { + target.addSkill("huanpodan_skill"); + if (cards && cards.length) { + card = cards[0]; } - if(target==targets[0]&&card.clone&&(card.clone.parentNode==player.parentNode||card.clone.parentNode==ui.arena)){ + if ( + target == targets[0] && + card.clone && + (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena) + ) { card.clone.moveDelete(target); - game.addVideo('gain2',target,get.cardsInfo([card])); + game.addVideo("gain2", target, get.cardsInfo([card])); } }, - ai:{ - basic:{ - value:8, - useful:4, + ai: { + basic: { + value: 8, + useful: 4, }, - order:2, - result:{ - target:function(player,target){ - return 1/Math.sqrt(1+target.hp); + order: 2, + result: { + target: function (player, target) { + return 1 / Math.sqrt(1 + target.hp); }, }, - } - }, - langeguaiyi:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['longfan'], - ai:{ - basic:{ - equipValue:7, - } - } - }, - guiyoujie:{ - fullskin:true, - type:'delay', - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player!=target); }, - judge:function(card){ - if(get.color(card)=='black') return -3; + }, + langeguaiyi: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["longfan"], + ai: { + basic: { + equipValue: 7, + }, + }, + }, + guiyoujie: { + fullskin: true, + type: "delay", + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player != target; + }, + judge: function (card) { + if (get.color(card) == "black") return -3; return 0; }, - effect:function(){ - if(result.bool==false){ + effect: function () { + if (result.bool == false) { player.loseHp(); player.randomDiscard(); } }, - ai:{ - basic:{ - order:1, - useful:1, - value:6, + ai: { + basic: { + order: 1, + useful: 1, + value: 6, }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noturn')) return 0; + result: { + target: function (player, target) { + if (target.hasSkillTag("noturn")) return 0; return -3; - } + }, }, - } - }, - yufulu:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['touzhi'], - ai:{ - basic:{ - equipValue:5 - } - } - }, - xixueguizhihuan:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['xixue'], - ai:{ - basic:{ - equipValue:5 - } - } - }, - zhufangshenshi:{ - fullskin:true, - type:'trick', - enable:true, - global:'g_zhufangshenshi', - filterTarget:function(card,player,target){ - return target!=player; }, - content:function(){ - player.storage.zhufangshenshi=target; - player.addTempSkill('zhufangshenshi'); - }, - ai:{ - tag:{ - norepeat:1 + }, + yufulu: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["touzhi"], + ai: { + basic: { + equipValue: 5, }, - value:4, - wuxie:function(){ + }, + }, + xixueguizhihuan: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["xixue"], + ai: { + basic: { + equipValue: 5, + }, + }, + }, + zhufangshenshi: { + fullskin: true, + type: "trick", + enable: true, + global: "g_zhufangshenshi", + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + player.storage.zhufangshenshi = target; + player.addTempSkill("zhufangshenshi"); + }, + ai: { + tag: { + norepeat: 1, + }, + value: 4, + wuxie: function () { return 0; }, - useful:[2,1], - basic:{ - order:7, + useful: [2, 1], + basic: { + order: 7, }, - result:{ - player:function(player,target){ - if(get.attitude(player,target)<0){ - if(get.distance(player,target)>1) return 1; + result: { + player: function (player, target) { + if (get.attitude(player, target) < 0) { + if (get.distance(player, target) > 1) return 1; return 0.6; } return 0.3; - } - } + }, + }, }, }, - jingleishan:{ - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - reverseOrder:true, - cardcolor:'black', - cardnature:'thunder', - filterTarget:function(card,player,target){ - return target!=player; + jingleishan: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + reverseOrder: true, + cardcolor: "black", + cardnature: "thunder", + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - "step 0" - var next=target.chooseToRespond({name:'sha'}); - next.ai=function(card){ - if(get.damageEffect(target,player,target,'thunder')>=0) return 0; - if(player.hasSkillTag('notricksource')) return 0; - if(target.hasSkillTag('notrick')) return 0; - return 11-get.value(card); + content: function () { + "step 0"; + var next = target.chooseToRespond({ name: "sha" }); + next.ai = function (card) { + if (get.damageEffect(target, player, target, "thunder") >= 0) return 0; + if (player.hasSkillTag("notricksource")) return 0; + if (target.hasSkillTag("notrick")) return 0; + return 11 - get.value(card); }; - next.autochoose=lib.filter.autoRespondSha; - "step 1" - if(result.bool==false){ - target.damage('thunder'); + next.autochoose = lib.filter.autoRespondSha; + "step 1"; + if (result.bool == false) { + target.damage("thunder"); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0&&target.countCards('h','sha')){ - if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.attitude(viewer, target) > 0 && target.countCards("h", "sha")) { + if (!target.countCards("h") || target.hp == 1 || Math.random() < 0.7) return 0; } }, - basic:{ - order:9, - useful:[5,1], - value:5 + basic: { + order: 9, + useful: [5, 1], + value: 5, }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nothunder')) return 0; - if(target.hasUnknown(2)) return 0; - var nh=target.countCards('h'); - if(lib.config.mode=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + result: { + target: function (player, target) { + if (target.hasSkillTag("nothunder")) return 0; + if (target.hasUnknown(2)) return 0; + var nh = target.countCards("h"); + if (lib.config.mode == "identity") { + if (target.isZhu && nh <= 2 && target.hp <= 1) return -100; } - if(nh==0) return -2; - if(nh==1) return -1.7 + if (nh == 0) return -2; + if (nh == 1) return -1.7; return -1.5; }, }, - tag:{ - respond:1, - respondSha:1, - damage:1, - natureDamage:1, - thunderDamage:1, - multitarget:1, - multineg:1, - } - } - }, - chiyuxi:{ - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - reverseOrder:true, - cardcolor:'red', - cardnature:'fire', - filterTarget:function(card,player,target){ - return target!=player; + tag: { + respond: 1, + respondSha: 1, + damage: 1, + natureDamage: 1, + thunderDamage: 1, + multitarget: 1, + multineg: 1, + }, }, - content:function(){ - "step 0" - var next=target.chooseToRespond({name:'shan'}); - next.ai=function(card){ - if(get.damageEffect(target,player,target,'fire')>=0) return 0; - if(player.hasSkillTag('notricksource')) return 0; - if(target.hasSkillTag('notrick')) return 0; - if(target.hasSkillTag('noShan')){ + }, + chiyuxi: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + reverseOrder: true, + cardcolor: "red", + cardnature: "fire", + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + "step 0"; + var next = target.chooseToRespond({ name: "shan" }); + next.ai = function (card) { + if (get.damageEffect(target, player, target, "fire") >= 0) return 0; + if (player.hasSkillTag("notricksource")) return 0; + if (target.hasSkillTag("notrick")) return 0; + if (target.hasSkillTag("noShan")) { return -1; } - return 11-get.value(card); + return 11 - get.value(card); }; - next.autochoose=lib.filter.autoRespondShan; - "step 1" - if(result.bool==false){ - target.damage('fire'); + next.autochoose = lib.filter.autoRespondShan; + "step 1"; + if (result.bool == false) { + target.damage("fire"); } }, - ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0&&target.countCards('h','shan')){ - if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; + ai: { + wuxie: function (target, card, player, viewer) { + if (get.attitude(viewer, target) > 0 && target.countCards("h", "shan")) { + if (!target.countCards("h") || target.hp == 1 || Math.random() < 0.7) return 0; } }, - basic:{ - order:9, - useful:1, - value:5 + basic: { + order: 9, + useful: 1, + value: 5, }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nofire')) return 0; - if(player.hasUnknown(2)) return 0; - var nh=target.countCards('h'); - if(lib.config.mode=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; + result: { + target: function (player, target) { + if (target.hasSkillTag("nofire")) return 0; + if (player.hasUnknown(2)) return 0; + var nh = target.countCards("h"); + if (lib.config.mode == "identity") { + if (target.isZhu && nh <= 2 && target.hp <= 1) return -100; } - if(nh==0) return -2; - if(nh==1) return -1.7 + if (nh == 0) return -2; + if (nh == 1) return -1.7; return -1.5; }, }, - tag:{ - respond:1, - respondShan:1, - damage:1, - natureDamage:1, - fireDamage:1, - multitarget:1, - multineg:1, - } - } - }, - guangshatianyi:{ - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['guangshatianyi'], - ai:{ - basic:{ - equipValue:6 - } - } - }, - guilingzhitao:{ - type:'equip', - fullskin:true, - subtype:'equip5', - skills:['nigong'], - ai:{ - equipValue:function(card,player){ - if(!player.storage.nigong) return 5; - return 5+player.storage.nigong; + tag: { + respond: 1, + respondShan: 1, + damage: 1, + natureDamage: 1, + fireDamage: 1, + multitarget: 1, + multineg: 1, }, - basic:{ - equipValue:5 - } - }, - equipDelay:false, - loseDelay:false, - clearLose:true, - onLose:function(){ - player.storage.nigong=0; - player.unmarkSkill('nigong'); - }, - onEquip:function(){ - player.storage.nigong=0; - player.markSkill('nigong'); - } - }, - qipoguyu:{ - type:'equip', - subtype:'equip5', - skills:['xujin'], - equipDelay:false, - loseDelay:false, - clearLose:true, - onLose:function(){ - player.storage.xujin=0; - }, - onEquip:function(){ - player.storage.xujin=0; - } - }, - sadengjinhuan:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['sadengjinhuan'], - ai:{ - basic:{ - equipValue:5.5 - } }, }, - sifeizhenmian:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['yiluan'], - ai:{ - basic:{ - equipValue:6 - } + guangshatianyi: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["guangshatianyi"], + ai: { + basic: { + equipValue: 6, + }, }, }, - shuchui:{ - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['shuchui'], - ai:{ - basic:{ - equipValue:5.5 - } + guilingzhitao: { + type: "equip", + fullskin: true, + subtype: "equip5", + skills: ["nigong"], + ai: { + equipValue: function (card, player) { + if (!player.storage.nigong) return 5; + return 5 + player.storage.nigong; + }, + basic: { + equipValue: 5, + }, + }, + equipDelay: false, + loseDelay: false, + clearLose: true, + onLose: function () { + player.storage.nigong = 0; + player.unmarkSkill("nigong"); + }, + onEquip: function () { + player.storage.nigong = 0; + player.markSkill("nigong"); }, }, - ximohu:{ - type:'equip', - subtype:'equip5', - skills:['ximohu'], - ai:{ - basic:{ - equipValue:6 - } + qipoguyu: { + type: "equip", + subtype: "equip5", + skills: ["xujin"], + equipDelay: false, + loseDelay: false, + clearLose: true, + onLose: function () { + player.storage.xujin = 0; + }, + onEquip: function () { + player.storage.xujin = 0; }, }, - guiyanfadao:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - ai:{ - basic:{ - equipValue:3 - } + sadengjinhuan: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["sadengjinhuan"], + ai: { + basic: { + equipValue: 5.5, + }, }, - skills:['guiyanfadao'] }, - qiankundai:{ - fullskin:true, - type:'equip', - subtype:'equip5', - onLose:function(){ + sifeizhenmian: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["yiluan"], + ai: { + basic: { + equipValue: 6, + }, + }, + }, + shuchui: { + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["shuchui"], + ai: { + basic: { + equipValue: 5.5, + }, + }, + }, + ximohu: { + type: "equip", + subtype: "equip5", + skills: ["ximohu"], + ai: { + basic: { + equipValue: 6, + }, + }, + }, + guiyanfadao: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + ai: { + basic: { + equipValue: 3, + }, + }, + skills: ["guiyanfadao"], + }, + qiankundai: { + fullskin: true, + type: "equip", + subtype: "equip5", + onLose: function () { player.draw(); }, - skills:['qiankundai'], - ai:{ - order:9.5, - equipValue:function(card,player){ - if(player.countCards('h','qiankundai')) return 6; + skills: ["qiankundai"], + ai: { + order: 9.5, + equipValue: function (card, player) { + if (player.countCards("h", "qiankundai")) return 6; return 1; }, - basic:{ - equipValue:5, - } - } + basic: { + equipValue: 5, + }, + }, }, }, - skill:{ - qiankundai:{ - mod:{ - maxHandcard:function(player,num){ - return num+1; - } - }, - }, - g_hufu_sha:{ - enable:['chooseToRespond','chooseToUse'], - filter:function(event,player){ - return player.countCards('h','hufu')>0; - }, - filterCard:{name:'hufu'}, - viewAs:{name:'sha'}, - prompt:'将一张玉符当杀使用或打出', - check:function(card){return 1}, - ai:{ - order:1, - useful:7.5, - value:7.5 - } - }, - g_hufu_shan:{ - enable:['chooseToRespond','chooseToUse'], - filter:function(event,player){ - return player.countCards('h','hufu')>0; - }, - filterCard:{name:'hufu'}, - viewAs:{name:'shan'}, - prompt:'将一张玉符当闪使用或打出', - check:function(){return 1}, - ai:{ - order:1, - useful:7.5, - value:7.5 - } - }, - g_hufu_jiu:{ - enable:['chooseToRespond','chooseToUse'], - filter:function(event,player){ - return player.countCards('h','hufu')>0; - }, - filterCard:{name:'hufu'}, - viewAs:{name:'jiu'}, - prompt:'将一张玉符当酒使用', - check:function(){return 1}, - }, - zhiluxiaohu:{ - trigger:{source:'damageAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent(3).name=='zhiluxiaohu'; - }, - content:function(){ - player.draw(); - } - }, - zhufangshenshi:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(player.storage.zhufangshenshi==target) return true; + skill: { + qiankundai: { + mod: { + maxHandcard: function (player, num) { + return num + 1; }, }, - mark:true, - intro:{ - content:'player' - }, - onremove:true, }, - g_zhufangshenshi:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.name=='zhufangshenshi'; + g_hufu_sha: { + enable: ["chooseToRespond", "chooseToUse"], + filter: function (event, player) { + return player.countCards("h", "hufu") > 0; }, - content:function(){ + filterCard: { name: "hufu" }, + viewAs: { name: "sha" }, + prompt: "将一张玉符当杀使用或打出", + check: function (card) { + return 1; + }, + ai: { + order: 1, + useful: 7.5, + value: 7.5, + }, + }, + g_hufu_shan: { + enable: ["chooseToRespond", "chooseToUse"], + filter: function (event, player) { + return player.countCards("h", "hufu") > 0; + }, + filterCard: { name: "hufu" }, + viewAs: { name: "shan" }, + prompt: "将一张玉符当闪使用或打出", + check: function () { + return 1; + }, + ai: { + order: 1, + useful: 7.5, + value: 7.5, + }, + }, + g_hufu_jiu: { + enable: ["chooseToRespond", "chooseToUse"], + filter: function (event, player) { + return player.countCards("h", "hufu") > 0; + }, + filterCard: { name: "hufu" }, + viewAs: { name: "jiu" }, + prompt: "将一张玉符当酒使用", + check: function () { + return 1; + }, + }, + zhiluxiaohu: { + trigger: { source: "damageAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.getParent(3).name == "zhiluxiaohu"; + }, + content: function () { player.draw(); - } - }, - huanpodan_skill:{ - mark:true, - intro:{ - content:'防止一次死亡,改为弃置所有牌,将体力值变为1并摸一张牌' }, - trigger:{player:'dieBefore'}, - forced:true, - content:function(){ - 'step 0' + }, + zhufangshenshi: { + mod: { + targetInRange: function (card, player, target, now) { + if (player.storage.zhufangshenshi == target) return true; + }, + }, + mark: true, + intro: { + content: "player", + }, + onremove: true, + }, + g_zhufangshenshi: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card.name == "zhufangshenshi"; + }, + content: function () { + player.draw(); + }, + }, + huanpodan_skill: { + mark: true, + intro: { + content: "防止一次死亡,改为弃置所有牌,将体力值变为1并摸一张牌", + }, + trigger: { player: "dieBefore" }, + forced: true, + content: function () { + "step 0"; trigger.cancel(); - player.discard(player.getCards('he')); - player.removeSkill('huanpodan_skill'); - 'step 1' - player.changeHp(1-player.hp); - 'step 2' + player.discard(player.getCards("he")); + player.removeSkill("huanpodan_skill"); + "step 1"; + player.changeHp(1 - player.hp); + "step 2"; player.draw(); - } + }, }, - dujian2:{}, - g_yuchan_swap:{ - trigger:{player:'useCardAfter'}, - silent:true, - priority:-1, - content:function(){ - var hs=player.getCards('h'); - var list=['yuchanqian','yuchankun','yuchanzhen','yuchanxun','yuchangen','yuchanli','yuchankan','yuchandui']; - for(var i=0;i0; + g_yuchan_equip: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var skills = player.getSkills(); + for (var i = 0; i < skills.length; i++) { + if (skills[i].indexOf("yuchan") == 0 && skills[i].indexOf("_equip") != -1) { + return player.countCards("h", { type: "basic" }) > 0; } } return false; }, - filterCard:{type:'basic'}, - selectCard:[1,Infinity], - prompt:'弃置任意张基本牌并摸等量的牌', - check:function(card){ - return 6-get.value(card) + filterCard: { type: "basic" }, + selectCard: [1, Infinity], + prompt: "弃置任意张基本牌并摸等量的牌", + check: function (card) { + return 6 - get.value(card); }, - content:function(){ + content: function () { player.draw(cards.length); }, - ai:{ - order:1, - result:{ - player:1 + ai: { + order: 1, + result: { + player: 1, }, }, }, - yuchanqian_equip1:{}, - yuchanqian_equip2:{}, - yuchanqian_equip3:{}, - yuchanqian_equip4:{}, - yuchanqian_equip5:{}, - yuchankun_equip1:{}, - yuchankun_equip2:{}, - yuchankun_equip3:{}, - yuchankun_equip4:{}, - yuchankun_equip5:{}, - yuchanzhen_equip1:{}, - yuchanzhen_equip2:{}, - yuchanzhen_equip3:{}, - yuchanzhen_equip4:{}, - yuchanzhen_equip5:{}, - yuchanxun_equip1:{}, - yuchanxun_equip2:{}, - yuchanxun_equip3:{}, - yuchanxun_equip4:{}, - yuchanxun_equip5:{}, - yuchankan_equip1:{}, - yuchankan_equip2:{}, - yuchankan_equip3:{}, - yuchankan_equip4:{}, - yuchankan_equip5:{}, - yuchanli_equip1:{}, - yuchanli_equip2:{}, - yuchanli_equip3:{}, - yuchanli_equip4:{}, - yuchanli_equip5:{}, - yuchangen_equip1:{}, - yuchangen_equip2:{}, - yuchangen_equip3:{}, - yuchangen_equip4:{}, - yuchangen_equip5:{}, - yuchandui_equip1:{}, - yuchandui_equip2:{}, - yuchandui_equip3:{}, - yuchandui_equip4:{}, - yuchandui_equip5:{}, - lianyaohu_skill:{ - mark:true, - intro:{ - content:function(storage,player){ - var card=player.getEquip('lianyaohu'); - if(card&&card.storage.shouna&&card.storage.shouna.length){ - return '共有'+get.cnNumber(card.storage.shouna.length)+'张牌'; + yuchanqian_equip1: {}, + yuchanqian_equip2: {}, + yuchanqian_equip3: {}, + yuchanqian_equip4: {}, + yuchanqian_equip5: {}, + yuchankun_equip1: {}, + yuchankun_equip2: {}, + yuchankun_equip3: {}, + yuchankun_equip4: {}, + yuchankun_equip5: {}, + yuchanzhen_equip1: {}, + yuchanzhen_equip2: {}, + yuchanzhen_equip3: {}, + yuchanzhen_equip4: {}, + yuchanzhen_equip5: {}, + yuchanxun_equip1: {}, + yuchanxun_equip2: {}, + yuchanxun_equip3: {}, + yuchanxun_equip4: {}, + yuchanxun_equip5: {}, + yuchankan_equip1: {}, + yuchankan_equip2: {}, + yuchankan_equip3: {}, + yuchankan_equip4: {}, + yuchankan_equip5: {}, + yuchanli_equip1: {}, + yuchanli_equip2: {}, + yuchanli_equip3: {}, + yuchanli_equip4: {}, + yuchanli_equip5: {}, + yuchangen_equip1: {}, + yuchangen_equip2: {}, + yuchangen_equip3: {}, + yuchangen_equip4: {}, + yuchangen_equip5: {}, + yuchandui_equip1: {}, + yuchandui_equip2: {}, + yuchandui_equip3: {}, + yuchandui_equip4: {}, + yuchandui_equip5: {}, + lianyaohu_skill: { + mark: true, + intro: { + content: function (storage, player) { + var card = player.getEquip("lianyaohu"); + if (card && card.storage.shouna && card.storage.shouna.length) { + return "共有" + get.cnNumber(card.storage.shouna.length) + "张牌"; } - return '共有零张牌'; + return "共有零张牌"; }, - mark:function(dialog,storage,player){ - var card=player.getEquip('lianyaohu'); - if(card&&card.storage.shouna&&card.storage.shouna.length){ + mark: function (dialog, storage, player) { + var card = player.getEquip("lianyaohu"); + if (card && card.storage.shouna && card.storage.shouna.length) { dialog.addAuto(card.storage.shouna); - } - else{ - return '共有零张牌'; + } else { + return "共有零张牌"; } }, - markcount:function(storage,player){ - var card=player.getEquip('lianyaohu'); - if(card&&card.storage.shouna) return card.storage.shouna.length; + markcount: function (storage, player) { + var card = player.getEquip("lianyaohu"); + if (card && card.storage.shouna) return card.storage.shouna.length; return 0; - } - } + }, + }, }, - g_shencaojie:{ - trigger:{source:'damageBegin',player:'damageBegin'}, - direct:true, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(player.hasCard('shencaojie')) return true; + g_shencaojie: { + trigger: { source: "damageBegin", player: "damageBegin" }, + direct: true, + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + if (player.hasCard("shencaojie")) return true; return false; }, - content:function(){ - player.chooseToUse(get.prompt('shencaojie',trigger.player).replace(/发动/,'使用'),function(card,player){ - if(card.name!='shencaojie') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - },trigger.player,-1).targetRequired=true; - } + content: function () { + player.chooseToUse( + get.prompt("shencaojie", trigger.player).replace(/发动/, "使用"), + function (card, player) { + if (card.name != "shencaojie") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }, + trigger.player, + -1 + ).targetRequired = true; + }, }, - g_shenmiguo:{ - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - if(event.parent.name=='g_shenmiguo') return false; - if(_status.currentPhase!=player) return false; - if(event.parent.parent.name!='phaseUse') return false; - if(!event.targets||!event.card) return false; - if(event.card.name=='shenmiguo') return false; - if(event.card.name=='yuchankan') return false; - if(player.hasSkill('shenmiguo2')) return false; - if(get.info(event.card).complexTarget) return false; - if(!lib.filter.cardEnabled(event.card,player,event.parent)) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - var card=game.createCard(event.card.name,event.card.suit,event.card.number,event.card.nature); - var targets=event._targets||event.targets; - for(var i=0;i1; }, - content:function(){ - var value=get.value(ui.cardPile.firstChild); - var num=Math.min(20,ui.cardPile.childElementCount); - var list=[],list2=[],list3=[]; - for(var i=1;ivalue){ + }, + shenmiguo2: {}, + yuruyi: { + trigger: { player: "drawBegin" }, + silent: true, + filter: function () { + return ui.cardPile.childElementCount > 1; + }, + content: function () { + var value = get.value(ui.cardPile.firstChild); + var num = Math.min(20, ui.cardPile.childElementCount); + var list = [], + list2 = [], + list3 = []; + for (var i = 1; i < num; i++) { + var val = get.value(ui.cardPile.childNodes[i]); + if (val > value) { list.push(ui.cardPile.childNodes[i]); - if(val>value+1&&val>=7){ + if (val > value + 1 && val >= 7) { list2.push(ui.cardPile.childNodes[i]); } - if(val>value+1&&val>=8){ + if (val > value + 1 && val >= 8) { list3.push(ui.cardPile.childNodes[i]); } } } var card; - if(list3.length){ - card=list3.randomGet(); + if (list3.length) { + card = list3.randomGet(); + } else if (list2.length) { + card = list2.randomGet(); + } else if (list.length) { + card = list.randomGet(); } - else if(list2.length){ - card=list2.randomGet(); + if (card) { + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); } - else if(list.length){ - card=list.randomGet(); - } - if(card){ - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); - } - } + }, }, - shuchui:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player.canUse('sha',target); + shuchui: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player.canUse("sha", target); }, - filter:function(event,player){ - return player.countCards('h','sha')>0&&lib.filter.cardUsable({name:'sha'},player); + filter: function (event, player) { + return ( + player.countCards("h", "sha") > 0 && lib.filter.cardUsable({ name: "sha" }, player) + ); }, - content:function(){ - 'step 0' - player.addSkill('shuchui2'); - player.storage.shuchui2=false; - event.num=0; - 'step 1' - var card=player.getCards('h','sha')[0]; - if(card){ - player.useCard(card,target); - } - else{ - if(player.storage.shuchui2){ + content: function () { + "step 0"; + player.addSkill("shuchui2"); + player.storage.shuchui2 = false; + event.num = 0; + "step 1"; + var card = player.getCards("h", "sha")[0]; + if (card) { + player.useCard(card, target); + } else { + if (player.storage.shuchui2) { player.draw(); } - player.removeSkill('shuchui2'); + player.removeSkill("shuchui2"); event.finish(); } - 'step 2' - if(event.num++<2&&target.isAlive()){ + "step 2"; + if (event.num++ < 2 && target.isAlive()) { event.goto(1); - } - else{ - if(player.storage.shuchui2){ + } else { + if (player.storage.shuchui2) { player.draw(); } - player.removeSkill('shuchui2'); + player.removeSkill("shuchui2"); } }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.11; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.11; + }, + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, }, - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,target); - } - } - } - }, - shuchui2:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - onremove:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&!player.storage.shuchui2; }, - content:function(){ - player.storage.shuchui2=true; - } }, - xuejibingbao:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - mark:true, - temp:true, - intro:{ - content:'摸牌阶段摸牌数+1' + shuchui2: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + onremove: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && !player.storage.shuchui2; }, - nopop:true, - content:function(){ + content: function () { + player.storage.shuchui2 = true; + }, + }, + xuejibingbao: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + mark: true, + temp: true, + intro: { + content: "摸牌阶段摸牌数+1", + }, + nopop: true, + content: function () { trigger.num++; player.storage.xuejibingbao--; - if(player.storage.xuejibingbao<=0){ - player.removeSkill('xuejibingbao'); + if (player.storage.xuejibingbao <= 0) { + player.removeSkill("xuejibingbao"); delete player.storage.xuejibingbao; - } - else{ + } else { player.updateMarks(); } - } + }, }, - gouhunluo:{ - mark:true, - intro:{ - content:function(storage,player){ - if(storage==1){ - '在'+get.translation(player.storage.gouhunluo2)+'的下个准备阶段失去1点体力并弃置所有手牌' + gouhunluo: { + mark: true, + intro: { + content: function (storage, player) { + if (storage == 1) { + "在" + + get.translation(player.storage.gouhunluo2) + + "的下个准备阶段失去1点体力并弃置所有手牌"; } - return '在'+storage+'轮后'+get.translation(player.storage.gouhunluo2)+'的准备阶段失去1点体力并弃置所有手牌' - } + return ( + "在" + + storage + + "轮后" + + get.translation(player.storage.gouhunluo2) + + "的准备阶段失去1点体力并弃置所有手牌" + ); + }, }, - nopop:true, - temp:true, - trigger:{global:'phaseBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.gouhunluo2==event.player; + nopop: true, + temp: true, + trigger: { global: "phaseBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.gouhunluo2 == event.player; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.storage.gouhunluo--; - if(player.storage.gouhunluo<=0){ - player.logSkill('gouhunluo'); + if (player.storage.gouhunluo <= 0) { + player.logSkill("gouhunluo"); player.loseHp(); - player.removeSkill('gouhunluo'); + player.removeSkill("gouhunluo"); delete player.storage.gouhunluo; delete player.storage.gouhunluo2; - } - else{ + } else { player.updateMarks(); event.finish(); } - 'step 1' - var es=player.getCards('h'); - if(es.length){ + "step 1"; + var es = player.getCards("h"); + if (es.length) { player.discard(es); } }, - group:'gouhunluo2' + group: "gouhunluo2", }, - gouhunluo2:{ - trigger:{global:'dieBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.gouhunluo2==event.player; + gouhunluo2: { + trigger: { global: "dieBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.gouhunluo2 == event.player; }, - content:function(){ - player.removeSkill('gouhunluo'); + content: function () { + player.removeSkill("gouhunluo"); delete player.storage.gouhunluo; delete player.storage.gouhunluo2; - } - }, - jiguanyuan:{ - mark:'card', - intro:{ - content:'cards' }, - trigger:{player:'phaseEnd'}, - forced:true, - temp:true, - popup:false, - content:function(){ - player.gain(player.storage.jiguanyuan,'gain2'); - player.removeSkill('jiguanyuan'); + }, + jiguanyuan: { + mark: "card", + intro: { + content: "cards", + }, + trigger: { player: "phaseEnd" }, + forced: true, + temp: true, + popup: false, + content: function () { + player.gain(player.storage.jiguanyuan, "gain2"); + player.removeSkill("jiguanyuan"); delete player.storage.jiguanyuan; - } - }, - g_qinglongzhigui:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event,player){ - return player.countCards('h','qinglongzhigui')>0; }, - content:function(){ - 'step 0' - player.showCards(get.translation(player)+'发动了【青龙之圭】',player.getCards('h','qinglongzhigui')); + }, + g_qinglongzhigui: { + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + return player.countCards("h", "qinglongzhigui") > 0; + }, + content: function () { + "step 0"; + player.showCards( + get.translation(player) + "发动了【青龙之圭】", + player.getCards("h", "qinglongzhigui") + ); player.draw(2); - 'step 1' - player.chooseToDiscard('he',true); - } - }, - g_baishouzhihu:{ - trigger:{player:'discardEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('h','baishouzhihu')>0; + "step 1"; + player.chooseToDiscard("he", true); }, - content:function(){ - "step 0" - player.chooseTarget([1,1],get.prompt('baishouzhihu'),function(card,player,target){ - if(player==target) return false; - return target.countCards('he')>0; - }).ai=function(target){ - return -get.attitude(player,target); + }, + g_baishouzhihu: { + trigger: { player: "discardEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", "baishouzhihu") > 0; + }, + content: function () { + "step 0"; + player.chooseTarget([1, 1], get.prompt("baishouzhihu"), function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + }).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.showCards(get.translation(player)+'发动了【白兽之琥】',player.getCards('h','baishouzhihu')); - player.logSkill('_baishouzhihu',result.targets); + "step 1"; + if (result.bool) { + player.showCards( + get.translation(player) + "发动了【白兽之琥】", + player.getCards("h", "baishouzhihu") + ); + player.logSkill("_baishouzhihu", result.targets); result.targets[0].randomDiscard(); // player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + } else { event.finish(); } }, }, - g_zhuquezhizhang:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.isAlive()&&player.countCards('h','zhuquezhizhang')>0; + g_zhuquezhizhang: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.source && + event.source != player && + event.source.isAlive() && + player.countCards("h", "zhuquezhizhang") > 0 + ); }, - logTarget:'source', - check:function(event,player){ - return get.damageEffect(event.source,player,player,'fire')>0; + logTarget: "source", + check: function (event, player) { + return get.damageEffect(event.source, player, player, "fire") > 0; }, - content:function(){ - 'step 0' - player.showCards(get.translation(player)+'发动了【朱雀之璋】',player.getCards('h','zhuquezhizhang')); - trigger.source.damage('fire'); - 'step 1' + content: function () { + "step 0"; + player.showCards( + get.translation(player) + "发动了【朱雀之璋】", + player.getCards("h", "zhuquezhizhang") + ); + trigger.source.damage("fire"); + "step 1"; game.delay(); - } - }, - g_xuanwuzhihuang:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player.countCards('h','xuanwuzhihuang')>0&&event.num>0&&player.hp 0 && + event.num > 0 && + player.hp < player.maxHp + ); + }, + content: function () { + player.showCards( + get.translation(player) + "发动了【玄武之璜】", + player.getCards("h", "xuanwuzhihuang") + ); player.recover(trigger.num); - } - }, - g_huanglinzhicong:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event,player){ - return !player.hujia&&player.countCards('h','huanglinzhicong')>0; }, - content:function(){ - player.showCards(get.translation(player)+'发动了【黄麟之琮】',player.getCards('h','huanglinzhicong')); + }, + g_huanglinzhicong: { + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + return !player.hujia && player.countCards("h", "huanglinzhicong") > 0; + }, + content: function () { + player.showCards( + get.translation(player) + "发动了【黄麟之琮】", + player.getCards("h", "huanglinzhicong") + ); player.changeHujia(); player.update(); }, }, - g_cangchizhibi:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h','cangchizhibi')>0; + g_cangchizhibi: { + trigger: { player: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", "cangchizhibi") > 0; }, - content:function(){ - 'step 0' - player.chooseTarget([1,3],get.prompt('cangchizhibi')).ai=function(target){ - var att=get.attitude(player,target); - if(target.isLinked()){ + content: function () { + "step 0"; + player.chooseTarget([1, 3], get.prompt("cangchizhibi")).ai = function (target) { + var att = get.attitude(player, target); + if (target.isLinked()) { return att; } return -att; }; - 'step 1' - if(result.bool){ - player.showCards(get.translation(player)+'发动了【苍螭之璧】',player.getCards('h','cangchizhibi')); - player.logSkill('_cangchizhibi',result.targets); - for(var i=0;i0&&player.hujia==0 }, - content:function(){ - 'step 0' - var next=player.chooseToDiscard('he',{color:'black'},get.prompt('huanglinzhicong_duanzao')); - next.ai=function(card){ - return 8-get.value(card); + }, + cangchizhibi_equip2: { + inherit: "cangchizhibi_equip1", + }, + cangchizhibi_equip3: { + inherit: "cangchizhibi_equip1", + }, + cangchizhibi_equip4: { + inherit: "cangchizhibi_equip1", + }, + cangchizhibi_equip5: { + inherit: "cangchizhibi_equip1", + }, + huanglinzhicong_equip1: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { color: "black" }) > 0 && player.hujia == 0; + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + { color: "black" }, + get.prompt("huanglinzhicong_duanzao") + ); + next.ai = function (card) { + return 8 - get.value(card); }; - next.logSkill='huanglinzhicong_equip1' - 'step 1' - if(result.bool){ + next.logSkill = "huanglinzhicong_equip1"; + "step 1"; + if (result.bool) { player.changeHujia(); } - } - }, - huanglinzhicong_equip2:{ - inherit:'huanglinzhicong_equip1' - }, - huanglinzhicong_equip3:{ - inherit:'huanglinzhicong_equip1' - }, - huanglinzhicong_equip4:{ - inherit:'huanglinzhicong_equip1' - }, - huanglinzhicong_equip5:{ - inherit:'huanglinzhicong_equip1' - }, - xuanwuzhihuang_equip1:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{color:'red'})>0&&player.hp 0 && player.hp < player.maxHp; + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + { color: "red" }, + get.prompt("xuanwuzhihuang_duanzao") + ); + next.ai = function (card) { + if (get.recoverEffect(player, player, player) <= 0) return 0; + return 8 - get.value(card); }; - next.logSkill='xuanwuzhihuang_equip1' - 'step 1' - if(result.bool){ + next.logSkill = "xuanwuzhihuang_equip1"; + "step 1"; + if (result.bool) { player.recover(); } - } - }, - xuanwuzhihuang_equip2:{ - inherit:'xuanwuzhihuang_equip1' - }, - xuanwuzhihuang_equip3:{ - inherit:'xuanwuzhihuang_equip1' - }, - xuanwuzhihuang_equip4:{ - inherit:'xuanwuzhihuang_equip1' - }, - xuanwuzhihuang_equip5:{ - inherit:'xuanwuzhihuang_equip1' - }, - zhuquezhizhang_equip1:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{color:'red'})>0; }, - content:function(){ - "step 0" + }, + xuanwuzhihuang_equip2: { + inherit: "xuanwuzhihuang_equip1", + }, + xuanwuzhihuang_equip3: { + inherit: "xuanwuzhihuang_equip1", + }, + xuanwuzhihuang_equip4: { + inherit: "xuanwuzhihuang_equip1", + }, + xuanwuzhihuang_equip5: { + inherit: "xuanwuzhihuang_equip1", + }, + zhuquezhizhang_equip1: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { color: "red" }) > 0; + }, + content: function () { + "step 0"; player.chooseCardTarget({ - position:'he', - filterTarget:function(card,player,target){ - return player!=target&&target.hp>=player.hp; + position: "he", + filterTarget: function (card, player, target) { + return player != target && target.hp >= player.hp; }, - filterCard:function(card,player){ - return get.color(card)=='red'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.color(card) == "red" && lib.filter.cardDiscardable(card, player); }, - ai1:function(card){ - return 9-get.value(card); + ai1: function (card) { + return 9 - get.value(card); }, - ai2:function(target){ - return get.damageEffect(target,player,player,'fire'); + ai2: function (target) { + return get.damageEffect(target, player, player, "fire"); }, - prompt:get.prompt('zhuquezhizhang_duanzao') + prompt: get.prompt("zhuquezhizhang_duanzao"), }); - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('zhuquezhizhang_equip1',event.target,'fire'); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("zhuquezhizhang_equip1", event.target, "fire"); player.discard(result.cards); - } - else{ + } else { event.finish(); } - "step 2" - if(event.target){ - event.target.damage('fire'); + "step 2"; + if (event.target) { + event.target.damage("fire"); } }, }, - zhuquezhizhang_equip2:{ - inherit:'zhuquezhizhang_equip1' + zhuquezhizhang_equip2: { + inherit: "zhuquezhizhang_equip1", }, - zhuquezhizhang_equip3:{ - inherit:'zhuquezhizhang_equip1' + zhuquezhizhang_equip3: { + inherit: "zhuquezhizhang_equip1", }, - zhuquezhizhang_equip4:{ - inherit:'zhuquezhizhang_equip1' + zhuquezhizhang_equip4: { + inherit: "zhuquezhizhang_equip1", }, - zhuquezhizhang_equip5:{ - inherit:'zhuquezhizhang_equip1' + zhuquezhizhang_equip5: { + inherit: "zhuquezhizhang_equip1", }, - baishouzhihu_equip1:{ - trigger:{player:'phaseEnd'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget([1,1],get.prompt('baishouzhihu_duanzao'),function(card,player,target){ - if(player==target) return false; - return target.countCards('he')>0; - }).ai=function(target){ - return -get.attitude(player,target); + baishouzhihu_equip1: { + trigger: { player: "phaseEnd" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + [1, 1], + get.prompt("baishouzhihu_duanzao"), + function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + } + ).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('baishouzhihu_equip1',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("baishouzhihu_equip1", result.targets); result.targets[0].randomDiscard(); // player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + } else { event.finish(); } }, }, - baishouzhihu_equip2:{ - inherit:'baishouzhihu_equip1' + baishouzhihu_equip2: { + inherit: "baishouzhihu_equip1", }, - baishouzhihu_equip3:{ - inherit:'baishouzhihu_equip1' + baishouzhihu_equip3: { + inherit: "baishouzhihu_equip1", }, - baishouzhihu_equip4:{ - inherit:'baishouzhihu_equip1' + baishouzhihu_equip4: { + inherit: "baishouzhihu_equip1", }, - baishouzhihu_equip5:{ - inherit:'baishouzhihu_equip1' + baishouzhihu_equip5: { + inherit: "baishouzhihu_equip1", }, - qinglongzhigui_equip1:{ - trigger:{player:'phaseEnd'}, - forced:true, - content:function(){ + qinglongzhigui_equip1: { + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { player.draw(); - } - }, - qinglongzhigui_equip2:{ - inherit:'qinglongzhigui_equip1' - }, - qinglongzhigui_equip3:{ - inherit:'qinglongzhigui_equip1' - }, - qinglongzhigui_equip4:{ - inherit:'qinglongzhigui_equip1' - }, - qinglongzhigui_equip5:{ - inherit:'qinglongzhigui_equip1' - }, - kunlunjingc:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; }, - delay:false, - content:function(){ - 'step 0' - var cards=get.cards(3); - event.cards=cards; - player.chooseCardButton('选择一张牌',cards,true); - 'step 1' - event.card=result.links[0]; - player.chooseCard('h',true,'用一张手牌替换'+get.translation(event.card)); - 'step 2' - if(result.bool){ - event.cards[event.cards.indexOf(event.card)]=result.cards[0]; - player.lose(result.cards,ui.special); - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - } - else{ + }, + qinglongzhigui_equip2: { + inherit: "qinglongzhigui_equip1", + }, + qinglongzhigui_equip3: { + inherit: "qinglongzhigui_equip1", + }, + qinglongzhigui_equip4: { + inherit: "qinglongzhigui_equip1", + }, + qinglongzhigui_equip5: { + inherit: "qinglongzhigui_equip1", + }, + kunlunjingc: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + delay: false, + content: function () { + "step 0"; + var cards = get.cards(3); + event.cards = cards; + player.chooseCardButton("选择一张牌", cards, true); + "step 1"; + event.card = result.links[0]; + player.chooseCard("h", true, "用一张手牌替换" + get.translation(event.card)); + "step 2"; + if (result.bool) { + event.cards[event.cards.indexOf(event.card)] = result.cards[0]; + player.lose(result.cards, ui.special); + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + } else { event.finish(); } - 'step 3' + "step 3"; player.gain(event.card); player.$draw(); - for(var i=event.cards.length-1;i>=0;i--){ + for (var i = event.cards.length - 1; i >= 0; i--) { event.cards[i].fix(); - ui.cardPile.insertBefore(event.cards[i],ui.cardPile.firstChild); + ui.cardPile.insertBefore(event.cards[i], ui.cardPile.firstChild); } game.delay(); }, - ai:{ - order:10, - result:{ - player:1 - } - } + ai: { + order: 10, + result: { + player: 1, + }, + }, }, - lianhua:{ - enable:'phaseUse', - filter:function(event,player){ - var hu=player.getEquip('lianyaohu'); - if(hu&&hu.storage.shouna&&hu.storage.shouna.length>1){ + lianhua: { + enable: "phaseUse", + filter: function (event, player) { + var hu = player.getEquip("lianyaohu"); + if (hu && hu.storage.shouna && hu.storage.shouna.length > 1) { return true; } return false; }, - usable:1, - delay:false, - content:function(){ - "step 0" - event.hu=player.getEquip('lianyaohu'); - player.chooseCardButton('弃置两张壶中的牌,然后从牌堆中获得一张类别不同的牌',2,event.hu.storage.shouna).ai=function(){ + usable: 1, + delay: false, + content: function () { + "step 0"; + event.hu = player.getEquip("lianyaohu"); + player.chooseCardButton( + "弃置两张壶中的牌,然后从牌堆中获得一张类别不同的牌", + 2, + event.hu.storage.shouna + ).ai = function () { return 1; - } - "step 1" - if(result.bool){ - var type=[]; + }; + "step 1"; + if (result.bool) { + var type = []; player.$throw(result.links); - game.log(player,'弃置了',result.links); - for(var i=0;i0; + shouna: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h") > 0; }, - usable:1, - filterCard:true, - check:function(card){ - return 6-get.value(card); + usable: 1, + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - var card=target.getCards('h').randomGet(); - var hu=player.getEquip('lianyaohu'); - if(card&&hu){ - if(!hu.storage.shouna){ - hu.storage.shouna=[]; + content: function () { + "step 0"; + var card = target.getCards("h").randomGet(); + var hu = player.getEquip("lianyaohu"); + if (card && hu) { + if (!hu.storage.shouna) { + hu.storage.shouna = []; } - target.$give(card,player); - target.lose(card,ui.special); - event.card=card; - event.hu=hu; + target.$give(card, player); + target.lose(card, ui.special); + event.card = card; + event.hu = hu; } - 'step 1' - if(!event.card._selfDestroyed){ + "step 1"; + if (!event.card._selfDestroyed) { event.hu.storage.shouna.push(event.card); player.updateMarks(); } }, - ai:{ - order:5, - result:{ - target:function(player,target){ - return -1/Math.sqrt(1+target.countCards('h')); - } - } - } + ai: { + order: 5, + result: { + target: function (player, target) { + return -1 / Math.sqrt(1 + target.countCards("h")); + }, + }, + }, }, - shouna_old:{ - trigger:{global:'discardAfter'}, - filter:function(event,player){ - if(player.hasSkill('shouna2')) return false; - if(_status.currentPhase==event.player) return false; - if(event.player==player) return false; - for(var i=0;i0; + shouna2: {}, + donghuangzhong: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", { color: "red" }) > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterTarget:true, - filterCard:function(card,player,event){ - if(get.color(card)!='red') return false; - return lib.filter.cardDiscardable(card,player,event); + filterTarget: true, + filterCard: function (card, player, event) { + if (get.color(card) != "red") return false; + return lib.filter.cardDiscardable(card, player, event); }, - ai1:function(card){ - return 8-get.useful(card); + ai1: function (card) { + return 8 - get.useful(card); }, - ai2:function(target){ - return -get.attitude(player,target); + ai2: function (target) { + return -get.attitude(player, target); }, - prompt:get.prompt('donghuangzhong') + prompt: get.prompt("donghuangzhong"), }); - 'step 1' - if(result.bool){ - player.logSkill('donghuangzhong',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("donghuangzhong", result.targets); player.discard(result.cards); - event.target=result.targets[0]; - } - else{ + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - var target=event.target; - var list=[]; - for(var i=0;i0; + pangufu: { + trigger: { source: "damageEnd" }, + forced: true, + priority: 55, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.player.countCards("he") > 0; + }, + content: function () { + trigger.player.chooseToDiscard(true, "he"); }, - content:function(){ - trigger.player.chooseToDiscard(true,'he'); - } }, - shouhua:{ - mode:['identity','infinity'], - enable:'phaseUse', - filter:function(event,player){ - return player==game.me; + shouhua: { + mode: ["identity", "infinity"], + enable: "phaseUse", + filter: function (event, player) { + return player == game.me; }, - usable:1, - filterTarget:function(card,player,target){ - return target!=game.zhu&&target!=game.me&&target.hp0){ - return 1+trigger.judge(button.link); + haotianta: { + trigger: { global: "judgeBefore" }, + direct: true, + content: function () { + "step 0"; + event.cards = get.cards(2); + player.chooseCardButton( + true, + event.cards, + "昊天塔:选择一张牌作为" + + get.translation(trigger.player) + + "的" + + trigger.judgestr + + "判定结果" + ).ai = function (button) { + if (get.attitude(player, trigger.player) > 0) { + return 1 + trigger.judge(button.link); } - if(get.attitude(player,trigger.player)<0){ - return 1-trigger.judge(button.link); + if (get.attitude(player, trigger.player) < 0) { + return 1 - trigger.judge(button.link); } return 0; }; - "step 1" - if(!result.bool){ + "step 1"; + if (!result.bool) { event.finish(); return; } - player.logSkill('haotianta',trigger.player); - var card=result.links[0]; + player.logSkill("haotianta", trigger.player); + var card = result.links[0]; event.cards.remove(card); - var judgestr=get.translation(trigger.player)+'的'+trigger.judgestr+'判定'; - event.videoId=lib.status.videoId++; - event.dialog=ui.create.dialog(judgestr); - event.dialog.classList.add('center'); - event.dialog.videoId=event.videoId; + var judgestr = get.translation(trigger.player) + "的" + trigger.judgestr + "判定"; + event.videoId = lib.status.videoId++; + event.dialog = ui.create.dialog(judgestr); + event.dialog.classList.add("center"); + event.dialog.videoId = event.videoId; - game.addVideo('judge1',player,[get.cardInfo(card),judgestr,event.videoId]); - for(var i=0;i0){ - trigger.result.bool=true; - trigger.player.popup('判定生效'); + if (trigger.result.judge > 0) { + trigger.result.bool = true; + trigger.player.popup("判定生效"); } - if(trigger.result.judge<0){ - trigger.result.bool=false; - trigger.player.popup('判定失效'); + if (trigger.result.judge < 0) { + trigger.result.bool = false; + trigger.player.popup("判定失效"); } - game.log(trigger.player,'的判定结果为',card); - trigger.direct=true; + game.log(trigger.player, "的判定结果为", card); + trigger.direct = true; trigger.position.appendChild(card); game.delay(2); - } - else{ + } else { event.finish(); } - "step 2" - ui.arena.classList.remove('thrownhighlight'); + "step 2"; + ui.arena.classList.remove("thrownhighlight"); event.dialog.close(); - game.addVideo('judge2',null,event.videoId); + game.addVideo("judge2", null, event.videoId); ui.clear(); - var card=trigger.result.card; + var card = trigger.result.card; trigger.position.appendChild(card); trigger.result.node.delete(); game.delay(); }, - ai:{ - tag:{ - rejudge:1 - } - } + ai: { + tag: { + rejudge: 1, + }, + }, }, - shennongding:{ - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:2, - check:function(card){ - if(get.tag(card,'recover')>=1) return 0; - return 7-get.value(card); + shennongding: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 2, + check: function (card) { + if (get.tag(card, "recover") >= 1) return 0; + return 7 - get.value(card); }, - filter:function(event,player){ - return player.hp=2; + filter: function (event, player) { + return player.hp < player.maxHp && player.countCards("h") >= 2; }, - content:function(){ + content: function () { player.recover(); }, - ai:{ - result:{ - player:function(player){ + ai: { + result: { + player: function (player) { return get.recoverEffect(player); - } + }, }, - order:2.5 - } - }, - kongdongyin:{ - trigger:{player:'dieBefore'}, - forced:true, - filter:function(event,player){ - return player.maxHp>0; + order: 2.5, }, - content:function(){ + }, + kongdongyin: { + trigger: { player: "dieBefore" }, + forced: true, + filter: function (event, player) { + return player.maxHp > 0; + }, + content: function () { trigger.cancel(); - player.hp=1; + player.hp = 1; player.draw(); - player.discard(player.getCards('e',{subtype:'equip5'})); + player.discard(player.getCards("e", { subtype: "equip5" })); game.delay(); - } + }, }, - nvwashi:{ - trigger:{global:'dying'}, - priority:6, - filter:function(event,player){ - return event.player.hp<=0&&player.hp>1; + nvwashi: { + trigger: { global: "dying" }, + priority: 6, + filter: function (event, player) { + return event.player.hp <= 0 && player.hp > 1; }, - check:function(event,player){ - return get.attitude(player,event.player)>=3&&!event.player.hasSkillTag('nosave'); + check: function (event, player) { + return get.attitude(player, event.player) >= 3 && !event.player.hasSkillTag("nosave"); }, - logTarget:'player', - content:function(){ - "step 0" + logTarget: "player", + content: function () { + "step 0"; trigger.player.recover(); - "step 1" + "step 1"; player.loseHp(); }, - ai:{ - threaten:1.2, - expose:0.2 - } + ai: { + threaten: 1.2, + expose: 0.2, + }, }, - kongxin:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + kongxin: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')&&game.hasPlayer(function(current){ - return player.canCompare(current); - }); + filter: function (event, player) { + return ( + player.countCards("h") && + game.hasPlayer(function (current) { + return player.canCompare(current); + }) + ); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.bool){ - event.bool=true; - player.chooseTarget('选择一个目标视为'+get.translation(target)+'对其使用一张杀',function(card,player,target2){ - return player!=target2&&target.canUse('sha',target2); - }).ai=function(target2){ - return get.effect(target2,{name:'sha'},target,player); - } - } - else{ + "step 1"; + if (result.bool) { + event.bool = true; + player.chooseTarget( + "选择一个目标视为" + get.translation(target) + "对其使用一张杀", + function (card, player, target2) { + return player != target2 && target.canUse("sha", target2); + } + ).ai = function (target2) { + return get.effect(target2, { name: "sha" }, target, player); + }; + } else { target.discardPlayerCard(player); } - "step 2" - if(event.bool&&result.bool){ - target.useCard({name:'sha'},result.targets); + "step 2"; + if (event.bool && result.bool) { + target.useCard({ name: "sha" }, result.targets); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(player.countCards('h')<=1) return 0; - if(get.attitude(player,target)>=0) return 0; - if(game.hasPlayer(function(current){ - return (player!=current&&target.canUse('sha',current)&& - get.effect(current,{name:'sha'},target,player)>0) - })){ + ai: { + order: 7, + result: { + target: function (player, target) { + if (player.countCards("h") <= 1) return 0; + if (get.attitude(player, target) >= 0) return 0; + if ( + game.hasPlayer(function (current) { + return ( + player != current && + target.canUse("sha", current) && + get.effect(current, { name: "sha" }, target, player) > 0 + ); + }) + ) { return -1; } return 0; - } - } - } - }, - kongxin2:{ - trigger:{player:'dying'}, - priority:10, - forced:true, - popup:false, - filter:function(event,player){ - return player==game.me; + }, + }, }, - content:function(){ - player.removeSkill('kongxin2'); + }, + kongxin2: { + trigger: { player: "dying" }, + priority: 10, + forced: true, + popup: false, + filter: function (event, player) { + return player == game.me; + }, + content: function () { + player.removeSkill("kongxin2"); game.swapPlayer(player); - player.storage.kongxin.lockOut=false; + player.storage.kongxin.lockOut = false; player.storage.kongxin.out(); - if(player==game.me) game.swapPlayer(player.storage.kongxin); - if(lib.config.mode=='identity') player.storage.kongxin.setIdentity(); + if (player == game.me) game.swapPlayer(player.storage.kongxin); + if (lib.config.mode == "identity") player.storage.kongxin.setIdentity(); delete player.storage.kongxin; }, }, - qinglianxindeng:{ - trigger:{player:'damageBefore'}, - forced:true, - priority:15, - filter:function(event,player){ - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return get.type(event.card,'trick')=='trick'; + qinglianxindeng: { + trigger: { player: "damageBefore" }, + forced: true, + priority: 15, + filter: function (event, player) { + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + return get.type(event.card, "trick") == "trick"; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - notrick:true, - effect:{ - target:function(card,player,target,current){ - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })) return; - if(get.type(card)=='trick'&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + ai: { + notrick: true, + effect: { + target: function (card, player, target, current) { + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return; + if (get.type(card) == "trick" && get.tag(card, "damage")) { + return "zeroplayertarget"; } }, - } - } - }, - yiluan:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); + }, }, - content:function(){ - 'step 0' + }, + yiluan: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); + }, + content: function () { + "step 0"; target.judge(); - 'step 1' - if(result.suit!='heart'){ - var hs=target.getCards('h'); - while(hs.length){ - var chosen=hs.randomRemove(); - if(target.hasUseTarget(chosen)&&!get.info(chosen).multitarget){ - var list=game.filterPlayer(function(current){ - return lib.filter.targetEnabled2(chosen,target,current); + "step 1"; + if (result.suit != "heart") { + var hs = target.getCards("h"); + while (hs.length) { + var chosen = hs.randomRemove(); + if (target.hasUseTarget(chosen) && !get.info(chosen).multitarget) { + var list = game.filterPlayer(function (current) { + return lib.filter.targetEnabled2(chosen, target, current); }); - if(list.length){ - target.useCard(chosen,list.randomGet()); + if (list.length) { + target.useCard(chosen, list.randomGet()); event.finish(); break; } @@ -3626,1073 +3795,1152 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } } }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(!target.countCards('h')) return 0; + ai: { + order: 10, + result: { + target: function (player, target) { + if (!target.countCards("h")) return 0; return -1; - } - } - } + }, + }, + }, }, - hslingjian_xuanfengzhiren_equip1:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.countCards('he'); + hslingjian_xuanfengzhiren_equip1: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.card && event.card.name == "sha" && event.player.countCards("he"); + }, + content: function () { + trigger.player.discard(trigger.player.getCards("he").randomGet()); }, - content:function(){ - trigger.player.discard(trigger.player.getCards('he').randomGet()); - } }, - hslingjian_xuanfengzhiren_equip2:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.source&&event.source.countCards('he'); + hslingjian_xuanfengzhiren_equip2: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + event.source && + event.source.countCards("he") + ); + }, + content: function () { + trigger.source.discard(trigger.source.getCards("he").randomGet()); }, - content:function(){ - trigger.source.discard(trigger.source.getCards('he').randomGet()); - } }, - hslingjian_xuanfengzhiren_equip3:{ - trigger:{player:'loseAfter'}, - forced:true, - filter:function(event,player){ - return _status.currentPhase!=player&&!player.hasSkill('hslingjian_xuanfengzhiren_equip3_dist'); + hslingjian_xuanfengzhiren_equip3: { + trigger: { player: "loseAfter" }, + forced: true, + filter: function (event, player) { + return ( + _status.currentPhase != player && + !player.hasSkill("hslingjian_xuanfengzhiren_equip3_dist") + ); + }, + content: function () { + player.addTempSkill("hslingjian_xuanfengzhiren_equip3_dist"); }, - content:function(){ - player.addTempSkill('hslingjian_xuanfengzhiren_equip3_dist'); - } }, - hslingjian_xuanfengzhiren_equip3_dist:{ - mod:{ - globalTo:function(from,to,distance){ - return distance+1; - } - } + hslingjian_xuanfengzhiren_equip3_dist: { + mod: { + globalTo: function (from, to, distance) { + return distance + 1; + }, + }, }, - hslingjian_xuanfengzhiren_equip4:{ - trigger:{player:'loseAfter'}, - forced:true, - filter:function(event,player){ - return _status.currentPhase==player&&!player.hasSkill('hslingjian_xuanfengzhiren_equip4_dist'); + hslingjian_xuanfengzhiren_equip4: { + trigger: { player: "loseAfter" }, + forced: true, + filter: function (event, player) { + return ( + _status.currentPhase == player && + !player.hasSkill("hslingjian_xuanfengzhiren_equip4_dist") + ); + }, + content: function () { + player.addTempSkill("hslingjian_xuanfengzhiren_equip4_dist"); }, - content:function(){ - player.addTempSkill('hslingjian_xuanfengzhiren_equip4_dist'); - } }, - hslingjian_xuanfengzhiren_equip4_dist:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance-1; - } - } + hslingjian_xuanfengzhiren_equip4_dist: { + mod: { + globalFrom: function (from, to, distance) { + return distance - 1; + }, + }, }, - hslingjian_xuanfengzhiren_equip5:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filter:function(event,player){ - return player.countCards('he')>0; + hslingjian_xuanfengzhiren_equip5: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterTarget:function(card,player,target){ - return target.countCards('he')>0; + filterTarget: function (card, player, target) { + return target.countCards("he") > 0; }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - target.discard(target.getCards('he').randomGet()); + content: function () { + target.discard(target.getCards("he").randomGet()); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - var dh=player.countCards('he')-target.countCards('he'); - if(dh>0){ + ai: { + order: 5, + result: { + target: function (player, target) { + var dh = player.countCards("he") - target.countCards("he"); + if (dh > 0) { return -Math.sqrt(dh); } return 0; - } - } - } + }, + }, + }, }, - hslingjian_zhongxinghujia_equip1:{ - trigger:{source:'damageEnd'}, - check:function(event,player){ + hslingjian_zhongxinghujia_equip1: { + trigger: { source: "damageEnd" }, + check: function (event, player) { return !player.getEquip(2); }, - filter:function(event){ - return event.card&&event.card.name=='sha'; + filter: function (event) { + return event.card && event.card.name == "sha"; }, - content:function(){ - var card=game.createCard(get.inpile('equip2').randomGet()); + content: function () { + var card = game.createCard(get.inpile("equip2").randomGet()); player.equip(card); player.$draw(card); game.delay(); - } + }, }, - hslingjian_zhongxinghujia_equip2:{ - trigger:{player:'damageEnd'}, - check:function(event,player){ - return get.attitude(player,event.source)<0; + hslingjian_zhongxinghujia_equip2: { + trigger: { player: "damageEnd" }, + check: function (event, player) { + return get.attitude(player, event.source) < 0; }, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.source&&event.source.getEquip(2); + filter: function (event) { + return event.card && event.card.name == "sha" && event.source && event.source.getEquip(2); }, - content:function(){ - player.line(trigger.source,'green'); + content: function () { + player.line(trigger.source, "green"); trigger.source.discard(trigger.source.getEquip(2)); - } - }, - hslingjian_zhongxinghujia_equip3:{ - mod:{ - globalTo:function(from,to,distance){ - if(to.getEquip(2)) return distance+1; - } - } - }, - hslingjian_zhongxinghujia_equip4:{ - mod:{ - globalFrom:function(from,to,distance){ - if(from.getEquip(2)) return distance-1; - } - } - }, - hslingjian_zhongxinghujia_equip5:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filterTarget:true, - selectCard:2, - filter:function(event,player){ - return player.countCards('he')>=2; }, - check:function(card){ - return 5-get.value(card); + }, + hslingjian_zhongxinghujia_equip3: { + mod: { + globalTo: function (from, to, distance) { + if (to.getEquip(2)) return distance + 1; + }, }, - content:function(){ - var card=game.createCard(get.inpile('equip2').randomGet()); + }, + hslingjian_zhongxinghujia_equip4: { + mod: { + globalFrom: function (from, to, distance) { + if (from.getEquip(2)) return distance - 1; + }, + }, + }, + hslingjian_zhongxinghujia_equip5: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filterTarget: true, + selectCard: 2, + filter: function (event, player) { + return player.countCards("he") >= 2; + }, + check: function (card) { + return 5 - get.value(card); + }, + content: function () { + var card = game.createCard(get.inpile("equip2").randomGet()); target.equip(card); target.$draw(card); game.delay(); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.getEquip(2)) return 0; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.getEquip(2)) return 0; return 1; - } - } - } + }, + }, + }, }, - hslingjian_jinjilengdong_equip1:{ - trigger:{source:'damageEnd'}, - check:function(event,player){ - if(event.player.hasSkillTag('noturn')) return 0; - if(event.player.isTurnedOver()){ - return get.attitude(player,event.player)>0; + hslingjian_jinjilengdong_equip1: { + trigger: { source: "damageEnd" }, + check: function (event, player) { + if (event.player.hasSkillTag("noturn")) return 0; + if (event.player.isTurnedOver()) { + return get.attitude(player, event.player) > 0; } - return get.attitude(player,event.player)<=0; + return get.attitude(player, event.player) <= 0; }, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player&&event.player.isAlive(); + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.card && event.card.name == "sha" && event.player && event.player.isAlive(); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.draw(2); trigger.player.turnOver(); - } + }, }, - hslingjian_jinjilengdong_equip2:{ - trigger:{player:'damageEnd'}, - check:function(event,player){ - if(event.player.hasSkillTag('noturn')) return 0; - if(event.player.isTurnedOver()){ - return get.attitude(player,event.source)>0; + hslingjian_jinjilengdong_equip2: { + trigger: { player: "damageEnd" }, + check: function (event, player) { + if (event.player.hasSkillTag("noturn")) return 0; + if (event.player.isTurnedOver()) { + return get.attitude(player, event.source) > 0; } - return get.attitude(player,event.source)<=0; + return get.attitude(player, event.source) <= 0; }, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.source&&event.source.isAlive(); + filter: function (event) { + return event.card && event.card.name == "sha" && event.source && event.source.isAlive(); }, - logTarget:'source', - content:function(){ - player.line(trigger.source,'green'); + logTarget: "source", + content: function () { + player.line(trigger.source, "green"); trigger.source.draw(2); trigger.source.turnOver(); - } + }, }, - hslingjian_jinjilengdong_equip3:{ - mod:{ - globalTo:function(from,to,distance){ - if(to.isTurnedOver()) return distance+2; - } - } + hslingjian_jinjilengdong_equip3: { + mod: { + globalTo: function (from, to, distance) { + if (to.isTurnedOver()) return distance + 2; + }, + }, }, - hslingjian_jinjilengdong_equip4:{ - mod:{ - globalFrom:function(from,to,distance){ - if(from.isTurnedOver()) return distance-2; - } - } + hslingjian_jinjilengdong_equip4: { + mod: { + globalFrom: function (from, to, distance) { + if (from.isTurnedOver()) return distance - 2; + }, + }, }, - hslingjian_jinjilengdong_equip5:{ - trigger:{player:'phaseAfter'}, - direct:true, - filter:function(event,player){ + hslingjian_jinjilengdong_equip5: { + trigger: { player: "phaseAfter" }, + direct: true, + filter: function (event, player) { return !player.isTurnedOver(); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('hslingjian_jinjilengdong_duanzao'),function(card,player,target){ - return player!=target&&!target.isTurnedOver(); - }).ai=function(target){ - if(target.hasSkillTag('noturn')) return 0; - return Math.max(0,-get.attitude(player,target)-2); + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("hslingjian_jinjilengdong_duanzao"), + function (card, player, target) { + return player != target && !target.isTurnedOver(); + } + ).ai = function (target) { + if (target.hasSkillTag("noturn")) return 0; + return Math.max(0, -get.attitude(player, target) - 2); }; - "step 1" - if(result.bool){ - player.logSkill('hslingjian_jinjilengdong_equip5',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("hslingjian_jinjilengdong_equip5", result.targets); player.turnOver(); result.targets[0].turnOver(); - game.asyncDraw([player,result.targets[0]],2); + game.asyncDraw([player, result.targets[0]], 2); } }, }, - hslingjian_yinmilichang_equip1:{ - trigger:{source:'damageEnd'}, - direct:true, - filter:function(event){ - return event.card&&event.card.name=='sha'; + hslingjian_yinmilichang_equip1: { + trigger: { source: "damageEnd" }, + direct: true, + filter: function (event) { + return event.card && event.card.name == "sha"; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('hslingjian_yinmilichang_duanzao'),function(card,player,target){ - return target!=player&&!target.hasSkill('qianxing'); - }).ai=function(target){ - var att=get.attitude(player,target); - if(get.distance(player,target,'absolute')<=1) return 0; - if(target.hp==1) return 2*att; - if(target.hp==2&&target.countCards('h')<=2) return 1.2*att; + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("hslingjian_yinmilichang_duanzao"), + function (card, player, target) { + return target != player && !target.hasSkill("qianxing"); + } + ).ai = function (target) { + var att = get.attitude(player, target); + if (get.distance(player, target, "absolute") <= 1) return 0; + if (target.hp == 1) return 2 * att; + if (target.hp == 2 && target.countCards("h") <= 2) return 1.2 * att; return att; - } - 'step 1' - if(result.bool){ - player.logSkill('hslingjian_yinmilichang_equip1',result.targets); + }; + "step 1"; + if (result.bool) { + player.logSkill("hslingjian_yinmilichang_equip1", result.targets); result.targets[0].tempHide(); } - } - }, - hslingjian_yinmilichang_equip2:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return !player.hasSkill('qianxing'); }, - content:function(){ - player.addTempSkill('qianxing'); - } }, - hslingjian_yinmilichang_equip3:{ - mod:{ - globalTo:function(from,to,distance){ - if(to.hp==1) return distance+1; - } - } - }, - hslingjian_yinmilichang_equip4:{ - mod:{ - globalFrom:function(from,to,distance){ - if(from.hp==1) return distance-1; - } - } - }, - hslingjian_yinmilichang_equip5:{ - mod:{ - targetEnabled:function(card,player,target,now){ - if(target.countCards('h')==0){ - if(card.name=='sha'||card.name=='juedou') return false; - } - } + hslingjian_yinmilichang_equip2: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return !player.hasSkill("qianxing"); }, - ai:{ - noh:true, - skillTagFilter:function(player,tag){ - if(tag=='noh'){ - if(player.countCards('h')!=1) return false; - } - } - } - }, - hslingjian_xingtigaizao_equip1:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event){ - return event.card&&event.card.name=='sha'; + content: function () { + player.addTempSkill("qianxing"); }, - content:function(){ - player.draw(); - } }, - hslingjian_xingtigaizao_equip2:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event){ - return event.card&&event.card.name=='sha'; - }, - content:function(){ - player.draw(); - } - }, - hslingjian_xingtigaizao_equip3:{ - mod:{ - globalTo:function(from,to,distance){ - return distance+1; + hslingjian_yinmilichang_equip3: { + mod: { + globalTo: function (from, to, distance) { + if (to.hp == 1) return distance + 1; }, - globalFrom:function(from,to,distance){ - return distance+1; - } - } - }, - hslingjian_xingtigaizao_equip4:{ - mod:{ - globalTo:function(from,to,distance){ - return distance-1; - }, - globalFrom:function(from,to,distance){ - return distance-1; - } - } - }, - hslingjian_xingtigaizao_equip5:{ - mod:{ - maxHandcard:function(player,num){ - return num-1; - } }, - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ + }, + hslingjian_yinmilichang_equip4: { + mod: { + globalFrom: function (from, to, distance) { + if (from.hp == 1) return distance - 1; + }, + }, + }, + hslingjian_yinmilichang_equip5: { + mod: { + targetEnabled: function (card, player, target, now) { + if (target.countCards("h") == 0) { + if (card.name == "sha" || card.name == "juedou") return false; + } + }, + }, + ai: { + noh: true, + skillTagFilter: function (player, tag) { + if (tag == "noh") { + if (player.countCards("h") != 1) return false; + } + }, + }, + }, + hslingjian_xingtigaizao_equip1: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event) { + return event.card && event.card.name == "sha"; + }, + content: function () { + player.draw(); + }, + }, + hslingjian_xingtigaizao_equip2: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event) { + return event.card && event.card.name == "sha"; + }, + content: function () { + player.draw(); + }, + }, + hslingjian_xingtigaizao_equip3: { + mod: { + globalTo: function (from, to, distance) { + return distance + 1; + }, + globalFrom: function (from, to, distance) { + return distance + 1; + }, + }, + }, + hslingjian_xingtigaizao_equip4: { + mod: { + globalTo: function (from, to, distance) { + return distance - 1; + }, + globalFrom: function (from, to, distance) { + return distance - 1; + }, + }, + }, + hslingjian_xingtigaizao_equip5: { + mod: { + maxHandcard: function (player, num) { + return num - 1; + }, + }, + trigger: { player: "phaseDrawBegin" }, + forced: true, + content: function () { trigger.num++; - } - }, - hslingjian_shengxiuhaojiao_equip1:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return event.target.hasSkill('hslingjian_chaofeng'); }, - content:function(){ - trigger.directHit=true; - } }, - hslingjian_shengxiuhaojiao_equip2:{ - mod:{ - targetEnabled:function(card,player,target){ - if(player.hasSkill('hslingjian_chaofeng')) return false; - } - } - }, - hslingjian_shengxiuhaojiao_equip3:{ - mod:{ - globalTo:function(from,to,distance){ - if(to.hp0; + hslingjian_shijianhuisu_equip3: { + mod: { + globalTo: function (from, to, distance) { + if (to.countCards("e") == 1) return distance + 1; + }, }, - position:'he', - content:function(){ - var es=target.getCards('e'); + }, + hslingjian_shijianhuisu_equip4: { + mod: { + globalFrom: function (from, to, distance) { + if (from.countCards("e") == 1) return distance - 1; + }, + }, + }, + hslingjian_shijianhuisu_equip5: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; + }, + position: "he", + content: function () { + var es = target.getCards("e"); target.gain(es); target.$gain2(es); }, - check:function(card){ - return 4-get.value(card); + check: function (card) { + return 4 - get.value(card); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noe')) return target.countCards('e')*2; - return -target.countCards('e'); - } + ai: { + order: 5, + result: { + target: function (player, target) { + if (target.hasSkillTag("noe")) return target.countCards("e") * 2; + return -target.countCards("e"); + }, }, - } - }, - jiguanyaoshu_skill_old:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay']})>0; }, - filterCard:{type:['trick','delay']}, - check:function(card){ - return 5-get.value(card); - }, - viewAs:{name:'jiguanshu'} }, - jiguanyaoshu_skill:{ - trigger:{player:'loseEnd'}, - forced:true, - filter:function(event,player){ - if(_status.currentPhase==player) return false; - for(var i=0;i 0; + }, + filterCard: { type: ["trick", "delay"] }, + check: function (card) { + return 5 - get.value(card); + }, + viewAs: { name: "jiguanshu" }, + }, + jiguanyaoshu_skill: { + trigger: { player: "loseEnd" }, + forced: true, + filter: function (event, player) { + if (_status.currentPhase == player) return false; + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].original == "e") return true; } return false; }, - content:function(){ - var num=0; - for(var i=0;i10) return 10+(value-10)/10; - if(value<9) return 8+value/10; + var dvalue = type == "jiqi" ? 3 : 1; + var getValue = function (value, dvalue) { + if (dvalue == 1) return Math.min(10, value + dvalue); + value += dvalue; + if (value > 10) return 10 + (value - 10) / 10; + if (value < 9) return 8 + value / 10; return value; }; - if(typeof lib.card[name].ai.equipValue=='number'){ - lib.card[name].ai.equipValue=getValue(lib.card[name].ai.equipValue,dvalue); - } - else if(typeof lib.card[name].ai.equipValue=='function'){ - lib.card[name].ai.equipValue=function(){ - return getValue(lib.card[equipname].ai.equipValue.apply(this,arguments),dvalue); + if (typeof lib.card[name].ai.equipValue == "number") { + lib.card[name].ai.equipValue = getValue(lib.card[name].ai.equipValue, dvalue); + } else if (typeof lib.card[name].ai.equipValue == "function") { + lib.card[name].ai.equipValue = function () { + return getValue(lib.card[equipname].ai.equipValue.apply(this, arguments), dvalue); + }; + } else if ( + lib.card[name].ai.basic && + typeof lib.card[name].ai.basic.equipValue == "number" + ) { + lib.card[name].ai.basic.equipValue = getValue( + lib.card[name].ai.basic.equipValue, + dvalue + ); + } else if ( + lib.card[name].ai.basic && + typeof lib.card[name].ai.basic.equipValue == "function" + ) { + lib.card[name].ai.basic.equipValue = function () { + return getValue( + lib.card[equipname].ai.basic.equipValue.apply(this, arguments), + dvalue + ); + }; + } else { + if (dvalue == 3) { + lib.card[name].ai.equipValue = 7; + } else { + lib.card[name].ai.equipValue = dvalue; } } - else if(lib.card[name].ai.basic&&typeof lib.card[name].ai.basic.equipValue=='number'){ - lib.card[name].ai.basic.equipValue=getValue(lib.card[name].ai.basic.equipValue,dvalue); - } - else if(lib.card[name].ai.basic&&typeof lib.card[name].ai.basic.equipValue=='function'){ - lib.card[name].ai.basic.equipValue=function(){ - return getValue(lib.card[equipname].ai.basic.equipValue.apply(this,arguments),dvalue); - } - } - else{ - if(dvalue==3){ - lib.card[name].ai.equipValue=7; - } - else{ - lib.card[name].ai.equipValue=dvalue; - } - } - if(Array.isArray(lib.card[name].skills)){ - lib.card[name].skills=lib.card[name].skills.slice(0); - } - else{ - lib.card[name].skills=[]; + if (Array.isArray(lib.card[name].skills)) { + lib.card[name].skills = lib.card[name].skills.slice(0); + } else { + lib.card[name].skills = []; } // lib.card[name].filterTarget=function(card,player,target){ // return !target.isMin(); // }; // lib.card[name].selectTarget=1; // lib.card[name].range={global:1}; - var str=lib.translate[cards[0].name+'_duanzao']; - var str2=get.translation(equip.name,'skill'); - lib.translate[name]=str+str2; - str2=lib.translate[equip.name+'_info']||''; - if(str2[str2.length-1]=='.'||str2[str2.length-1]=='。'){ - str2=str2.slice(0,str2.length-1); + var str = lib.translate[cards[0].name + "_duanzao"]; + var str2 = get.translation(equip.name, "skill"); + lib.translate[name] = str + str2; + str2 = lib.translate[equip.name + "_info"] || ""; + if (str2[str2.length - 1] == "." || str2[str2.length - 1] == "。") { + str2 = str2.slice(0, str2.length - 1); } - for(var i=0;i'; + str += + '
          ' + + lib.translate[lingjians[i]] + + "
          "; + for (var j = 0; j < types.length; j++) { + str += + '
          ' + + (type != "jiqi" ? lib.translate[types[j]] + ":" : "") + + lib.translate[lingjians[i] + "_" + types[j] + "_info"] + + "
          "; + if (type == "jiqi") break; } - str+='
          '; - str+='
          '+lib.translate[lingjians[i]]+'
          '; - for(var j=0;j'; - if(type=='jiqi') break; - } - str+='
          '; + str += ""; } return str; }, - check:function(card){ - if(get.type(card)=='jiqi'){ - if(_status.event.player.needsToDiscard()){ + check: function (card) { + if (get.type(card) == "jiqi") { + if (_status.event.player.needsToDiscard()) { return 0.5; } return 0; } - var num=1+get.value(card); - if(get.position(card)=='e'){ - num+=0.1; + var num = 1 + get.value(card); + if (get.position(card) == "e") { + num += 0.1; } return num; }, - filterCard:function(card){ - var type=get.type(card); - if(type=='equip'){ - if(!lib.inpile.includes(card.name)) return false; - if(lib.card[card.name].nopower) return false; - if(lib.card[card.name].unique) return false; - if(card.nopower) return false; + filterCard: function (card) { + var type = get.type(card); + if (type == "equip") { + if (!lib.inpile.includes(card.name)) return false; + if (lib.card[card.name].nopower) return false; + if (lib.card[card.name].unique) return false; + if (card.nopower) return false; } - if(ui.selected.cards.length){ - var type2=get.type(ui.selected.cards[0]); - if(type2=='equip'){ - return type=='hslingjian'||type=='jiqi'; + if (ui.selected.cards.length) { + var type2 = get.type(ui.selected.cards[0]); + if (type2 == "equip") { + return type == "hslingjian" || type == "jiqi"; + } else { + return type == "equip"; } - else{ - return type=='equip'; - } - } - else{ - return type=='equip'||type=='hslingjian'||type=='jiqi'; + } else { + return type == "equip" || type == "hslingjian" || type == "jiqi"; } }, - selectCard:2, - complexCard:true, - filter:function(event,player){ - if(!player.countCards('h',{type:['hslingjian','jiqi']})) return false; - var es=player.getCards('he',{type:'equip'}); - for(var i=0;i0; - if(event.target.hp==1) return att>0; - if(event.target.hasSkillTag('maixie')){ - return att<=0; + fengxueren: { + trigger: { player: "shaHit" }, + check: function (event, player) { + var att = get.attitude(player, event.target); + if (player.hasSkill("jiu")) return att > 0; + if (event.target.hp == 1) return att > 0; + if (event.target.hasSkillTag("maixie")) { + return att <= 0; } - if(player.hasSkill('tianxianjiu')) return false; - return att<=0; + if (player.hasSkill("tianxianjiu")) return false; + return att <= 0; }, - filter:function(event,player){ + filter: function (event, player) { return !event.target.isTurnedOver(); }, - logTarget:'target', - content:function(){ - trigger.unhurt=true; + logTarget: "target", + content: function () { + trigger.unhurt = true; trigger.target.turnOver(); trigger.target.draw(); - } - }, - chilongya:{ - trigger:{source:'damageBegin'}, - forced:true, - filter:function(event){ - return event.hasNature('fire')&&event.notLink(); }, - content:function(){ + }, + chilongya: { + trigger: { source: "damageBegin" }, + forced: true, + filter: function (event) { + return event.hasNature("fire") && event.notLink(); + }, + content: function () { trigger.num++; - } - }, - chilongya2:{ - trigger:{source:'damageBegin'}, - filter:function(event,player){ - return (event.card&&event.card.name=='sha'); }, - popup:false, - forced:true, - content:function(){ - if(Math.random()<0.5){ + }, + chilongya2: { + trigger: { source: "damageBegin" }, + filter: function (event, player) { + return event.card && event.card.name == "sha"; + }, + popup: false, + forced: true, + content: function () { + if (Math.random() < 0.5) { trigger.num++; - trigger.player.addSkill('chilongfengxue'); + trigger.player.addSkill("chilongfengxue"); } - } + }, }, - chilongfengxue:{ - trigger:{global:'shaAfter'}, - forced:true, - popup:false, - content:function(){ + chilongfengxue: { + trigger: { global: "shaAfter" }, + forced: true, + popup: false, + content: function () { player.draw(); - player.removeSkill('chilongfengxue'); - } + player.removeSkill("chilongfengxue"); + }, }, - shentou:{ - enable:'phaseUse', - usable:1, - filterCard:true, - filter:function(event,player){ - var nh=player.countCards('h'); - if(nh==0) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>nh; + shentou: { + enable: "phaseUse", + usable: 1, + filterCard: true, + filter: function (event, player) { + var nh = player.countCards("h"); + if (nh == 0) return false; + return game.hasPlayer(function (current) { + return current != player && current.countCards("h") > nh; }); }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - filterTarget:function(card,player,target){ - if(target.countCards('h')==0) return false; - if(target==player) return false; - if(target.countCards('h')<=player.countCards('h')) return false; + filterTarget: function (card, player, target) { + if (target.countCards("h") == 0) return false; + if (target == player) return false; + if (target.countCards("h") <= player.countCards("h")) return false; return true; }, - content:function(){ - "step 0" - player.judge(function(card){ - if(get.suit(card)=='club') return -1; + content: function () { + "step 0"; + player.judge(function (card) { + if (get.suit(card) == "club") return -1; return 1; }); - "step 1" - if(result.bool){ - var card=target.getCards('h').randomGet(); - if(card){ - player.gain(card,target); - target.$giveAuto(card,player); + "step 1"; + if (result.bool) { + var card = target.getCards("h").randomGet(); + if (card) { + player.gain(card, target); + target.$giveAuto(card, player); } } }, - ai:{ - basic:{ - order:5 + ai: { + basic: { + order: 5, }, - result:{ - player:0.3, - target:-1, - } - } + result: { + player: 0.3, + target: -1, + }, + }, }, - old_longfan:{ - enable:'phaseUse', - usable:1, - prompt:'?', - filterTarget:true, - content:function(){ - "step 0" - if(event.isMine()){ - event.longfan=ui.create.control('零','零','零','零',function(){ + old_longfan: { + enable: "phaseUse", + usable: 1, + prompt: "?", + filterTarget: true, + content: function () { + "step 0"; + if (event.isMine()) { + event.longfan = ui.create.control("零", "零", "零", "零", function () { event.longfan.status--; }); - event.longfan.status=4; - for(var i=0;i1) event.count(1); - if(event.longfan.status>2) event.count(2); - if(event.longfan.status>3) event.count(3); - },200); - event.count=function(num){ - event.longfan.childNodes[num].num=(event.longfan.childNodes[num].num+1)%10; - if(event.longfan.childNodes[num].num==2) event.longfan.childNodes[num].innerHTML='二'; - else event.longfan.childNodes[num].innerHTML=get.cnNumber(event.longfan.childNodes[num].num); - } + if (event.longfan.status > 1) event.count(1); + if (event.longfan.status > 2) event.count(2); + if (event.longfan.status > 3) event.count(3); + }, 200); + event.count = function (num) { + event.longfan.childNodes[num].num = (event.longfan.childNodes[num].num + 1) % 10; + if (event.longfan.childNodes[num].num == 2) + event.longfan.childNodes[num].innerHTML = "二"; + else + event.longfan.childNodes[num].innerHTML = get.cnNumber( + event.longfan.childNodes[num].num + ); + }; game.pause(); - } - else{ + } else { event.finish(); - var x=Math.random(); - if(x<0.1) target.draw(); - else if(x<0.2) target.chooseToDiscard(true); - else if(x<0.3) target.loseHp(); - else if(x<0.4) target.recover(); - else if(x<0.6){ - if(get.attitude(player,target)>0) target.draw(); + var x = Math.random(); + if (x < 0.1) target.draw(); + else if (x < 0.2) target.chooseToDiscard(true); + else if (x < 0.3) target.loseHp(); + else if (x < 0.4) target.recover(); + else if (x < 0.6) { + if (get.attitude(player, target) > 0) target.draw(); else target.chooseToDiscard(true); - } - else if(x<0.8){ - if(get.attitude(player,target)>0) target.recover(); + } else if (x < 0.8) { + if (get.attitude(player, target) > 0) target.recover(); else target.loseHp(); } } - "step 1" - var str=''; - for(var i=0;iplayer.hp?2:0; - case 'diamond':return 1; - case 'club':return 1; - case 'spade':return 0; + longfan: { + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + player.judge(function (card) { + switch (get.suit(card)) { + case "heart": + return player.maxHp > player.hp ? 2 : 0; + case "diamond": + return 1; + case "club": + return 1; + case "spade": + return 0; } }); - "step 1" - switch(result.suit){ - case 'heart':player.recover();break; - case 'diamond':player.draw();break; - case 'club':{ - var targets=player.getEnemies(); - for(var i=0;i0; + filter: function (event, player) { + return player.countCards("he", { subtype: "equip1" }) > 0; }, - discard:false, - prepare:'give', - filterTarget:function(card,player,target){ - if(player==target) return false; + discard: false, + prepare: "give", + filterTarget: function (card, player, target) { + if (player == target) return false; return true; }, - content:function(){ + content: function () { target.damage(); - target.gain(cards,player); + target.gain(cards, player); // game.delay(); }, - check:function(card){ - return 10-get.value(card); + check: function (card) { + return 10 - get.value(card); }, - position:'he', - ai:{ - basic:{ - order:8 + position: "he", + ai: { + basic: { + order: 8, + }, + result: { + target: -1, }, - result:{ - target:-1 - } - } - }, - xixue:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.hp1/3) return false; + xixue: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.hp < player.maxHp; + }, + content: function () { + player.recover(trigger.num); + }, + }, + guangshatianyi: { + trigger: { player: "damageBegin" }, + forced: true, + filter: function (event, player) { + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + if (Math.random() > 1 / 3) return false; return true; }, - content:function(){ + content: function () { trigger.num--; - } + }, }, - nigong:{ - trigger:{player:'damageAfter'}, - group:['nigong2','nigong3'], - forced:true, - content:function(){ - player.storage.nigong+=trigger.num; - if(player.storage.nigong>4){ - player.storage.nigong=4; + nigong: { + trigger: { player: "damageAfter" }, + group: ["nigong2", "nigong3"], + forced: true, + content: function () { + player.storage.nigong += trigger.num; + if (player.storage.nigong > 4) { + player.storage.nigong = 4; } player.updateMarks(); }, - ai:{ - effect:function(card,player,target){ - if(get.tag(card,'damage')&&!target.hujia) return [1,0.5]; - } + ai: { + effect: function (card, player, target) { + if (get.tag(card, "damage") && !target.hujia) return [1, 0.5]; + }, + }, + intro: { + content: "已积攒#点伤害", }, - intro:{ - content:'已积攒#点伤害' - } }, - nigong2:{ - enable:'phaseUse', - filter:function(event,player){ - return player.storage.nigong>1; + nigong2: { + enable: "phaseUse", + filter: function (event, player) { + return player.storage.nigong > 1; }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - prompt:function(event){ - var str='弃置所有逆攻标记,'; - if(event.player.storage.nigong%2!=0){ - str+='摸一张牌,'; + prompt: function (event) { + var str = "弃置所有逆攻标记,"; + if (event.player.storage.nigong % 2 != 0) { + str += "摸一张牌,"; } - str+='并对一名其他角色造成'+get.cnNumber(Math.floor(event.player.storage.nigong/2))+'点伤害'; + str += + "并对一名其他角色造成" + + get.cnNumber(Math.floor(event.player.storage.nigong / 2)) + + "点伤害"; return str; }, - content:function(){ - if(player.storage.nigong%2!=0){ + content: function () { + if (player.storage.nigong % 2 != 0) { player.draw(); } - target.damage(Math.floor(player.storage.nigong/2)); - player.storage.nigong=0; + target.damage(Math.floor(player.storage.nigong / 2)); + player.storage.nigong = 0; player.updateMarks(); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - var num=get.damageEffect(target,player,target); - if(player.storage.nigong>=4&&num>0){ - num=0; + ai: { + order: 10, + result: { + target: function (player, target) { + var num = get.damageEffect(target, player, target); + if (player.storage.nigong >= 4 && num > 0) { + num = 0; } return num; - } - } - } - }, - nigong3:{ - enable:'phaseUse', - filter:function(event,player){ - return player.storage.nigong==1; + }, + }, }, - content:function(){ + }, + nigong3: { + enable: "phaseUse", + filter: function (event, player) { + return player.storage.nigong == 1; + }, + content: function () { player.draw(); - player.storage.nigong=0; + player.storage.nigong = 0; player.updateMarks(); }, - ai:{ - order:10, - result:{ - player:1 - } - } - }, - sadengjinhuan:{ - trigger:{player:'shaMiss'}, - check:function(event,player){ - return get.attitude(player,event.target)<0; + ai: { + order: 10, + result: { + player: 1, + }, }, - content:function(){ - "step 0" - player.judge(function(card){ - return get.color(card)=='red'?1:0; - }) - "step 1" - if(result.bool){ - trigger.target.chooseToRespond({name:'shan'},'萨登荆环:请额外打出一张闪响应杀').autochoose=lib.filter.autoRespondShan; - } - else{ + }, + sadengjinhuan: { + trigger: { player: "shaMiss" }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + content: function () { + "step 0"; + player.judge(function (card) { + return get.color(card) == "red" ? 1 : 0; + }); + "step 1"; + if (result.bool) { + trigger.target.chooseToRespond( + { name: "shan" }, + "萨登荆环:请额外打出一张闪响应杀" + ).autochoose = lib.filter.autoRespondShan; + } else { event.finish(); } - "step 2" - if(!result.bool){ + "step 2"; + if (!result.bool) { trigger.untrigger(); - trigger.trigger('shaHit'); - trigger._result.bool=false; + trigger.trigger("shaHit"); + trigger._result.bool = false; } - } - }, - ximohu:{ - trigger:{player:'damageBefore'}, - forced:true, - filter:function(event){ - return event.hasNature('thunder'); }, - content:function(){ + }, + ximohu: { + trigger: { player: "damageBefore" }, + forced: true, + filter: function (event) { + return event.hasNature("thunder"); + }, + content: function () { trigger.cancel(); player.recover(trigger.num); }, - ai:{ - effect:function(card){ - if(get.tag(card,'thunderDamage')) return [0,2]; - } - } + ai: { + effect: function (card) { + if (get.tag(card, "thunderDamage")) return [0, 2]; + }, + }, }, - guiyanfadao:{ - trigger:{player:'shaHit'}, - check:function(event,player){ - var att=get.attitude(player,event.target); - if(player.hasSkill('jiu')) return att>0; - if(event.target.hasSkillTag('maixie_hp')||event.target.hasSkillTag('maixie_defend')){ - return att<=0; + guiyanfadao: { + trigger: { player: "shaHit" }, + check: function (event, player) { + var att = get.attitude(player, event.target); + if (player.hasSkill("jiu")) return att > 0; + if (event.target.hasSkillTag("maixie_hp") || event.target.hasSkillTag("maixie_defend")) { + return att <= 0; } - if(player.hasSkill('tianxianjiu')) return false; - if(event.target.hujia>0) return att<0; - if(event.target.hp==1) return att>0; + if (player.hasSkill("tianxianjiu")) return false; + if (event.target.hujia > 0) return att < 0; + if (event.target.hp == 1) return att > 0; return false; }, - content:function(){ - trigger.unhurt=true; + content: function () { + trigger.unhurt = true; trigger.target.loseHp(); - } - }, - guiyanfadao2:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - content:function(){ - delete player.storage.zhuque_skill.nature; - } - }, - tianxianjiu:{ - trigger:{source:'damageEnd'}, - filter:function(event){ - return (event.card&&(event.card.name=='sha')); }, - forced:true, - temp:true, - vanish:true, - onremove:function(player){ - if(player.node.jiu){ + }, + guiyanfadao2: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + content: function () { + delete player.storage.zhuque_skill.nature; + }, + }, + tianxianjiu: { + trigger: { source: "damageEnd" }, + filter: function (event) { + return event.card && event.card.name == "sha"; + }, + forced: true, + temp: true, + vanish: true, + onremove: function (player) { + if (player.node.jiu) { player.node.jiu.delete(); player.node.jiu2.delete(); delete player.node.jiu; delete player.node.jiu2; } }, - content:function(){ + content: function () { player.draw(2); - player.removeSkill('tianxianjiu'); + player.removeSkill("tianxianjiu"); + }, + ai: { + damageBonus: true, }, - ai:{ - damageBonus:true - } }, }, - cardType:{ - hslingjian:0.5, - jiqi:0.4, - jiguan:0.45 + cardType: { + hslingjian: 0.5, + jiqi: 0.4, + jiguan: 0.45, }, - help:{ - '轩辕剑':'
          • 零件、祭器牌可用于煅造装备,煅造得到强化装备,并装备给距离1以内的角色
          • '+ - '煅造装备时失去牌以及装备牌的过程不触发任何技能(如枭姬、祈禳)
          • '+ - '进行洗牌时强化装备将从弃牌堆中消失,不进入牌堆
          • '+ - '专属、特殊装备无法被强化' + help: { + 轩辕剑: + "
            • 零件、祭器牌可用于煅造装备,煅造得到强化装备,并装备给距离1以内的角色
            • " + + "煅造装备时失去牌以及装备牌的过程不触发任何技能(如枭姬、祈禳)
            • " + + "进行洗牌时强化装备将从弃牌堆中消失,不进入牌堆
            • " + + "专属、特殊装备无法被强化", }, - translate:{ - qiankundai:'乾坤袋', - qiankundai_info:'你的手牌上限+1。当你失去该装备时,你摸一张牌。', - hufu:'玉符', - hufu_bg:'符', - g_hufu_sha:'符杀', - g_hufu_shan:'符闪', - g_hufu_jiu:'符酒', - hufu_info:'你可以将一张玉符当作杀、闪或酒使用或打出。', + translate: { + qiankundai: "乾坤袋", + qiankundai_info: "你的手牌上限+1。当你失去该装备时,你摸一张牌。", + hufu: "玉符", + hufu_bg: "符", + g_hufu_sha: "符杀", + g_hufu_shan: "符闪", + g_hufu_jiu: "符酒", + hufu_info: "你可以将一张玉符当作杀、闪或酒使用或打出。", // yihuajiemu:'移花接木', // yihuajiemu_info:'对一名装备区内有宝物的角色使用,将其宝物牌转移至另一名角色。', - liuxinghuoyu:'流星火羽', - liuxinghuoyu_info:'出牌阶段,对一名角色使用,令目标弃置两张牌,或受到1点火焰伤害。', - g_yuchan_equip:'玉蝉', - yuchanqian_duanzao:'玉蝉', - yuchanqian_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanqian_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanqian_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanqian_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanqian_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankun_duanzao:'玉蝉', - yuchankun_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankun_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankun_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankun_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankun_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanzhen_duanzao:'玉蝉', - yuchanzhen_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanzhen_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanzhen_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanzhen_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanzhen_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanxun_duanzao:'玉蝉', - yuchanxun_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanxun_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanxun_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanxun_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanxun_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankan_duanzao:'玉蝉', - yuchankan_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankan_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankan_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankan_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchankan_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanli_duanzao:'玉蝉', - yuchanli_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanli_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanli_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanli_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanli_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchangen_duanzao:'玉蝉', - yuchangen_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchangen_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchangen_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchangen_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchangen_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchandui_duanzao:'玉蝉', - yuchandui_equip1_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchandui_equip2_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchandui_equip3_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchandui_equip4_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchandui_equip5_info:'出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。', - yuchanqian:'乾玉蝉', - yuchanqian_info:'在你行动时可当作杀使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchankun:'坤玉蝉', - yuchankun_info:'在你行动时可当作草药使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchanzhen:'震玉蝉', - yuchanzhen_info:'在你行动时可当作酒使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchanxun:'巽玉蝉', - yuchanxun_info:'在你行动时可当作桃使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchankan:'坎玉蝉', - yuchankan_info:'在你行动时可当作神秘果使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchanli:'离玉蝉', - yuchanli_info:'在你行动时可当作天仙酒使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchangen:'艮玉蝉', - yuchangen_info:'在你行动时可当作封印之蛋使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yuchandui:'兑玉蝉', - yuchandui_info:'在你行动时可当作雪肌冰鲍使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。', - yangpijuan:'羊皮卷', - yangpijuan_info:'出牌阶段对自己使用,选择一种卡牌类别,发现一张该类别的卡牌。', + liuxinghuoyu: "流星火羽", + liuxinghuoyu_info: "出牌阶段,对一名角色使用,令目标弃置两张牌,或受到1点火焰伤害。", + g_yuchan_equip: "玉蝉", + yuchanqian_duanzao: "玉蝉", + yuchanqian_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanqian_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanqian_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanqian_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanqian_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankun_duanzao: "玉蝉", + yuchankun_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankun_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankun_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankun_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankun_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanzhen_duanzao: "玉蝉", + yuchanzhen_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanzhen_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanzhen_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanzhen_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanzhen_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanxun_duanzao: "玉蝉", + yuchanxun_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanxun_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanxun_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanxun_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanxun_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankan_duanzao: "玉蝉", + yuchankan_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankan_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankan_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankan_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchankan_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanli_duanzao: "玉蝉", + yuchanli_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanli_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanli_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanli_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanli_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchangen_duanzao: "玉蝉", + yuchangen_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchangen_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchangen_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchangen_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchangen_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchandui_duanzao: "玉蝉", + yuchandui_equip1_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchandui_equip2_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchandui_equip3_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchandui_equip4_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchandui_equip5_info: "出牌阶段限一次,你可以弃置任意张基本牌并摸等量的牌。", + yuchanqian: "乾玉蝉", + yuchanqian_info: "在你行动时可当作杀使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchankun: "坤玉蝉", + yuchankun_info: + "在你行动时可当作草药使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchanzhen: "震玉蝉", + yuchanzhen_info: "在你行动时可当作酒使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchanxun: "巽玉蝉", + yuchanxun_info: "在你行动时可当作桃使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchankan: "坎玉蝉", + yuchankan_info: + "在你行动时可当作神秘果使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchanli: "离玉蝉", + yuchanli_info: + "在你行动时可当作天仙酒使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchangen: "艮玉蝉", + yuchangen_info: + "在你行动时可当作封印之蛋使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yuchandui: "兑玉蝉", + yuchandui_info: + "在你行动时可当作雪肌冰鲍使用;可用于煅造装备;在你使用一张牌后,此牌会随机切换形态。", + yangpijuan: "羊皮卷", + yangpijuan_info: "出牌阶段对自己使用,选择一种卡牌类别,发现一张该类别的卡牌。", // pantao:'蟠桃', // pantao_info:'出牌阶段对自己使用,或对濒死角色使用,目标回复2点体力并获得1点护甲。', - shencaojie:'神草结', - shencaojie_info:'你的锦囊牌即将造成伤害时对目标使用,令此伤害+1;你即将受到锦囊牌伤害时对自己使用,令此伤害-1。', - yuruyi:'玉如意', - yuruyi_ab:'如意', - yuruyi_info:'你有更高的机率摸到好牌。', - fengyinzhidan:'封印之蛋', - fengyinzhidan_info:'随机使用两张普通锦囊牌(随机指定目标)。', - shuchui:'鼠槌', - shuchui_info:'出牌阶段限一次,你可以指定一名攻击范围内的角色,依次将手牌中的至多3张杀对该角色使用,若杀造成了伤害,你摸一张牌。', - zhiluxiaohu:'指路小狐', - zhiluxiaohu_info:'出牌阶段对自己使用,视为对一名随机敌方角色使用一张杀,若此杀造成伤害,你摸一张牌。', - xuejibingbao:'雪肌冰鲍', - xuejibingbao_info:'出牌阶段对一名角色使用,该角色摸牌阶段摸牌数+1,持续2个回合。', - gouhunluo:'勾魂锣', - gouhunluo_info:'出牌阶段对一名角色使用,在3轮后你的准备阶段令该角色失去1点体力并弃置所有手牌。', - jiguan:'机关', - jiqi:'祭器', - qinglongzhigui:'青龙之圭', - g_qinglongzhigui:'青龙之圭', - qinglongzhigui_info:'可用于煅造装备;此牌在你手牌中时,准备阶段,你摸两张牌然后弃置一张牌。', - qinglongzhigui_duanzao:'云屏', - qinglongzhigui_equip1_info:'结束阶段,你摸一张牌。', - qinglongzhigui_equip2_info:'结束阶段,你摸一张牌。', - qinglongzhigui_equip3_info:'结束阶段,你摸一张牌。', - qinglongzhigui_equip4_info:'结束阶段,你摸一张牌。', - qinglongzhigui_equip5_info:'结束阶段,你摸一张牌。', - baishouzhihu:'白兽之琥', - g_baishouzhihu:'白兽之琥', - baishouzhihu_info:'可用于煅造装备;此牌在你手牌中时,每当你弃置卡牌,你可以弃置一名其他角色的一张随机牌。', - baishouzhihu_duanzao:'风牙', - baishouzhihu_equip1_info:'结束阶段,你可以弃置一名其他角色的一张随机牌。', - baishouzhihu_equip2_info:'结束阶段,你可以弃置一名其他角色的一张随机牌。', - baishouzhihu_equip3_info:'结束阶段,你可以弃置一名其他角色的一张随机牌。', - baishouzhihu_equip4_info:'结束阶段,你可以弃置一名其他角色的一张随机牌。', - baishouzhihu_equip5_info:'结束阶段,你可以弃置一名其他角色的一张随机牌。', - zhuquezhizhang:'朱雀之璋', - g_zhuquezhizhang:'朱雀之璋', - zhuquezhizhang_info:'可用于煅造装备;此牌在你手牌中时,每当你受到其他角色造成的伤害,你对伤害来源造成1点火属性伤害。', - zhuquezhizhang_duanzao:'炽翎', - zhuquezhizhang_equip1_info:'结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。', - zhuquezhizhang_equip2_info:'结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。', - zhuquezhizhang_equip3_info:'结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。', - zhuquezhizhang_equip4_info:'结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。', - zhuquezhizhang_equip5_info:'结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。', - xuanwuzhihuang:'玄武之璜', - g_xuanwuzhihuang:'玄武之璜', - xuanwuzhihuang_duanzao:'寒晶', - xuanwuzhihuang_info:'可用于煅造装备;此牌在你手牌中时,每当你造成伤害,你回复等量的体力。', - xuanwuzhihuang_equip1_info:'结束阶段,你可以弃置一张红色牌并回复1点体力。', - xuanwuzhihuang_equip2_info:'结束阶段,你可以弃置一张红色牌并回复1点体力。', - xuanwuzhihuang_equip3_info:'结束阶段,你可以弃置一张红色牌并回复1点体力。', - xuanwuzhihuang_equip4_info:'结束阶段,你可以弃置一张红色牌并回复1点体力。', - xuanwuzhihuang_equip5_info:'结束阶段,你可以弃置一张红色牌并回复1点体力。', - huanglinzhicong:'黄麟之琮', - g_huanglinzhicong:'黄麟之琮', - huanglinzhicong_duanzao:'玄甲', - huanglinzhicong_info:'可用于煅造装备;此牌在你手牌中时,准备阶段,若你没有护甲,你获得1点护甲。', - huanglinzhicong_equip1_info:'结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。', - huanglinzhicong_equip2_info:'结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。', - huanglinzhicong_equip3_info:'结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。', - huanglinzhicong_equip4_info:'结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。', - huanglinzhicong_equip5_info:'结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。', - cangchizhibi:'苍螭之璧', - g_cangchizhibi:'苍螭之璧', - cangchizhibi_duanzao:'灵枢', - cangchizhibi_info:'可用于煅造装备;此牌在你手牌中时,准备阶段,你可以选择至多3名角色横置或重置之。', - cangchizhibi_equip1_info:'结束阶段,你可以横置或重置一名角色。', - cangchizhibi_equip2_info:'结束阶段,你可以横置或重置一名角色。', - cangchizhibi_equip3_info:'结束阶段,你可以横置或重置一名角色。', - cangchizhibi_equip4_info:'结束阶段,你可以横置或重置一名角色。', - cangchizhibi_equip5_info:'结束阶段,你可以横置或重置一名角色。', + shencaojie: "神草结", + shencaojie_info: + "你的锦囊牌即将造成伤害时对目标使用,令此伤害+1;你即将受到锦囊牌伤害时对自己使用,令此伤害-1。", + yuruyi: "玉如意", + yuruyi_ab: "如意", + yuruyi_info: "你有更高的机率摸到好牌。", + fengyinzhidan: "封印之蛋", + fengyinzhidan_info: "随机使用两张普通锦囊牌(随机指定目标)。", + shuchui: "鼠槌", + shuchui_info: + "出牌阶段限一次,你可以指定一名攻击范围内的角色,依次将手牌中的至多3张杀对该角色使用,若杀造成了伤害,你摸一张牌。", + zhiluxiaohu: "指路小狐", + zhiluxiaohu_info: + "出牌阶段对自己使用,视为对一名随机敌方角色使用一张杀,若此杀造成伤害,你摸一张牌。", + xuejibingbao: "雪肌冰鲍", + xuejibingbao_info: "出牌阶段对一名角色使用,该角色摸牌阶段摸牌数+1,持续2个回合。", + gouhunluo: "勾魂锣", + gouhunluo_info: "出牌阶段对一名角色使用,在3轮后你的准备阶段令该角色失去1点体力并弃置所有手牌。", + jiguan: "机关", + jiqi: "祭器", + qinglongzhigui: "青龙之圭", + g_qinglongzhigui: "青龙之圭", + qinglongzhigui_info: "可用于煅造装备;此牌在你手牌中时,准备阶段,你摸两张牌然后弃置一张牌。", + qinglongzhigui_duanzao: "云屏", + qinglongzhigui_equip1_info: "结束阶段,你摸一张牌。", + qinglongzhigui_equip2_info: "结束阶段,你摸一张牌。", + qinglongzhigui_equip3_info: "结束阶段,你摸一张牌。", + qinglongzhigui_equip4_info: "结束阶段,你摸一张牌。", + qinglongzhigui_equip5_info: "结束阶段,你摸一张牌。", + baishouzhihu: "白兽之琥", + g_baishouzhihu: "白兽之琥", + baishouzhihu_info: + "可用于煅造装备;此牌在你手牌中时,每当你弃置卡牌,你可以弃置一名其他角色的一张随机牌。", + baishouzhihu_duanzao: "风牙", + baishouzhihu_equip1_info: "结束阶段,你可以弃置一名其他角色的一张随机牌。", + baishouzhihu_equip2_info: "结束阶段,你可以弃置一名其他角色的一张随机牌。", + baishouzhihu_equip3_info: "结束阶段,你可以弃置一名其他角色的一张随机牌。", + baishouzhihu_equip4_info: "结束阶段,你可以弃置一名其他角色的一张随机牌。", + baishouzhihu_equip5_info: "结束阶段,你可以弃置一名其他角色的一张随机牌。", + zhuquezhizhang: "朱雀之璋", + g_zhuquezhizhang: "朱雀之璋", + zhuquezhizhang_info: + "可用于煅造装备;此牌在你手牌中时,每当你受到其他角色造成的伤害,你对伤害来源造成1点火属性伤害。", + zhuquezhizhang_duanzao: "炽翎", + zhuquezhizhang_equip1_info: + "结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。", + zhuquezhizhang_equip2_info: + "结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。", + zhuquezhizhang_equip3_info: + "结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。", + zhuquezhizhang_equip4_info: + "结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。", + zhuquezhizhang_equip5_info: + "结束阶段,你可以弃置一张红色牌并对一名体力值不小于你的角色造成1点火属性伤害。", + xuanwuzhihuang: "玄武之璜", + g_xuanwuzhihuang: "玄武之璜", + xuanwuzhihuang_duanzao: "寒晶", + xuanwuzhihuang_info: "可用于煅造装备;此牌在你手牌中时,每当你造成伤害,你回复等量的体力。", + xuanwuzhihuang_equip1_info: "结束阶段,你可以弃置一张红色牌并回复1点体力。", + xuanwuzhihuang_equip2_info: "结束阶段,你可以弃置一张红色牌并回复1点体力。", + xuanwuzhihuang_equip3_info: "结束阶段,你可以弃置一张红色牌并回复1点体力。", + xuanwuzhihuang_equip4_info: "结束阶段,你可以弃置一张红色牌并回复1点体力。", + xuanwuzhihuang_equip5_info: "结束阶段,你可以弃置一张红色牌并回复1点体力。", + huanglinzhicong: "黄麟之琮", + g_huanglinzhicong: "黄麟之琮", + huanglinzhicong_duanzao: "玄甲", + huanglinzhicong_info: "可用于煅造装备;此牌在你手牌中时,准备阶段,若你没有护甲,你获得1点护甲。", + huanglinzhicong_equip1_info: "结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。", + huanglinzhicong_equip2_info: "结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。", + huanglinzhicong_equip3_info: "结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。", + huanglinzhicong_equip4_info: "结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。", + huanglinzhicong_equip5_info: "结束阶段,若你没有护甲,你可以弃置一张黑色牌并获得1点护甲。", + cangchizhibi: "苍螭之璧", + g_cangchizhibi: "苍螭之璧", + cangchizhibi_duanzao: "灵枢", + cangchizhibi_info: + "可用于煅造装备;此牌在你手牌中时,准备阶段,你可以选择至多3名角色横置或重置之。", + cangchizhibi_equip1_info: "结束阶段,你可以横置或重置一名角色。", + cangchizhibi_equip2_info: "结束阶段,你可以横置或重置一名角色。", + cangchizhibi_equip3_info: "结束阶段,你可以横置或重置一名角色。", + cangchizhibi_equip4_info: "结束阶段,你可以横置或重置一名角色。", + cangchizhibi_equip5_info: "结束阶段,你可以横置或重置一名角色。", - guisheqi:'龟蛇旗', - guisheqi_info:'出牌阶段对一名角色使用,目标获得1点护甲。', - jiguanfeng:'机关蜂', - jiguanfeng_info:'出牌阶段对一名其他角色使用,目标需打出一张闪,否则非锁定技失效直到下一回合开始,并受到1点伤害。', - jiguanyuan:'机关鸢', - jiguanyuan_info:'出牌阶段对一名其他角色使用,你将此牌和一张其它牌置于一名其他角色的武将牌上,然后摸一张牌;该角色于下一结束阶段获得武将牌上的牌。', - jiguantong:'机关火筒', - jiguantong_ab:'火筒', - jiguantong_info:'出牌阶段对所有其他角色使用,目标弃置一张手牌,或受到1点火焰伤害;若没有人选择受到伤害,使用者摸一张牌。', - jiutiansuanchi:'九天算尺', - jiutiansuanchi_info:'每当你使用杀造成伤害,你可以弃置一张牌并展示受伤害角色的一张手牌,若此牌与你弃置的牌花色或点数相同,此杀的伤害+2。', - shenmiguo:'神秘果', - shenmiguo_info:'出牌阶段内,当你使用一张基本牌或普通锦囊牌后使用,令此牌再结算一次。每阶段限用一次。', - qinglianxindeng:'青莲心灯', - qinglianxindeng_info:'你防止锦囊牌造成的伤害。', - hslingjian_xuanfengzhiren_duanzao:'风刃', - hslingjian_xuanfengzhiren_duanzao2:'风', - hslingjian_xuanfengzhiren_equip1_info:'每当你用杀造成一次伤害,受伤害角色随机弃置一张牌。', - hslingjian_xuanfengzhiren_equip2_info:'每当你受到杀造成的伤害,伤害来源随机弃置一张牌。', - hslingjian_xuanfengzhiren_equip3_info:'当你于回合外失去牌后,你本回合的防御距离+1。', - hslingjian_xuanfengzhiren_equip4_info:'当你于回合内失去牌后,你本回合的进攻距离+1。', - hslingjian_xuanfengzhiren_equip5_info:'出牌阶段限一次,你可以弃置一张牌,然后随机弃置一名其他角色的一张牌。', - hslingjian_zhongxinghujia_duanzao:'重甲', - hslingjian_zhongxinghujia_duanzao2:'护', - hslingjian_zhongxinghujia_equip1_info:'每当你用杀造成一次伤害,你可以随机装备一件防具牌。', - hslingjian_zhongxinghujia_equip2_info:'每当你受到杀造成的伤害,你可以弃置伤害来源的防具牌。', - hslingjian_zhongxinghujia_equip3_info:'当你的装备区内有防具牌时,你的防御距离+1。', - hslingjian_zhongxinghujia_equip4_info:'当你的装备区内有防具牌时,你的进攻距离+1。', - hslingjian_zhongxinghujia_equip5_info:'出牌阶段限一次,你可以弃置两张牌,然后令一名角色随机装备一件防具。', - hslingjian_jinjilengdong_duanzao:'冰冻', - hslingjian_jinjilengdong_duanzao2:'冰', - hslingjian_jinjilengdong_equip1_info:'每当你用杀造成一次伤害,你可以令目标摸两张牌并翻面。', - hslingjian_jinjilengdong_equip2_info:'每当你受到杀造成的伤害,你可以令伤害来源摸两张牌并翻面。', - hslingjian_jinjilengdong_equip3_info:'你的武将牌背面朝上时防御距离+2。', - hslingjian_jinjilengdong_equip4_info:'你的武将牌背面朝上时进攻距离+2。', - hslingjian_jinjilengdong_equip5_info:'回合结束后,若你的武将牌正面朝上,你可以与一名武将牌正面朝上的其他角色同时翻面,然后各摸两张牌。', - hslingjian_yinmilichang_duanzao:'隐力', - hslingjian_yinmilichang_duanzao2:'隐', - hslingjian_yinmilichang_equip1_info:'每当你用杀造成一次伤害,你可以令一名其他角色获得潜行直到其下一回合开始。', - hslingjian_yinmilichang_equip2_info:'每当你受到一次伤害,你本回合内获得潜行。', - hslingjian_yinmilichang_equip3_info:'当你的体力值为1时,你的防御距离+1。', - hslingjian_yinmilichang_equip4_info:'当你的体力值为1时,你的进攻距离+1。', - hslingjian_yinmilichang_equip5_info:'当你没有手牌时,你不能成为杀或决斗的目标。', - hslingjian_xingtigaizao_duanzao:'移形', - hslingjian_xingtigaizao_duanzao2:'形', - hslingjian_xingtigaizao_equip1_info:'每当你用杀造成一次伤害,你摸一张牌。', - hslingjian_xingtigaizao_equip2_info:'每当你受到杀造成的伤害,你摸一张牌。', - hslingjian_xingtigaizao_equip3_info:'你的防御距离+1,进攻距离-1。', - hslingjian_xingtigaizao_equip4_info:'你的防御距离-1,进攻距离+1。', - hslingjian_xingtigaizao_equip5_info:'你于摸牌阶段额外摸一张牌;你的手牌上限-1。', - hslingjian_shengxiuhaojiao_duanzao:'号角', - hslingjian_shengxiuhaojiao_duanzao2:'角', - hslingjian_shengxiuhaojiao_equip1_info:'有嘲讽的角色不能闪避你的杀。', - hslingjian_shengxiuhaojiao_equip2_info:'有嘲讽的角色不能对你使用杀。', - hslingjian_shengxiuhaojiao_equip3_info:'若你的手牌数大于你的体力值,你的防御距离+1。', - hslingjian_shengxiuhaojiao_equip4_info:'若你的手牌数大于你的体力值,你的进攻距离+1。', - hslingjian_shengxiuhaojiao_equip5_info:'出牌阶段限一次,你可以弃置两张牌,然后令一名角色获得或解除嘲讽。', - hslingjian_shijianhuisu_duanzao:'回溯', - hslingjian_shijianhuisu_duanzao2:'溯', - hslingjian_shijianhuisu_equip1_info:'当你装备一张防具牌时,你摸一张牌。', - hslingjian_shijianhuisu_equip2_info:'当你装备一张武器牌时,你摸一张牌。', - hslingjian_shijianhuisu_equip3_info:'当你的装备区内没有其他牌时,你的防御距离+1。', - hslingjian_shijianhuisu_equip4_info:'当你的装备区内没有其他牌时,你的进攻距离+1。', - hslingjian_shijianhuisu_equip5_info:'出牌阶段限一次,你可以弃置一张牌,然后令一名其他角色将其装备区内的牌收回手牌。', - _lingjianduanzao:'煅造', - _lingjianduanzao_info:'出牌阶段,你可以将一张装备牌和一张可煅造的牌合成为一件强化装备,并装备给距离1以内的一名角色。', - jiguanshu:'机关鼠', - jiguanshu_info:'出牌阶段对自己使用,用随机祭器强化装备区内的一张随机装备,然后用随机零件强化其余的装备。', - lingjiandai:'零件袋', - lingjiandai_info:'出牌阶段对自己使用,获得3张随机零件。', - mujiaren:'木甲人', - mujiaren_info:'出牌阶段限用一次,将你手牌中的非基本牌(含此张)替换为随机的机关牌。', - jiguanyaoshu:'机关要术', - jiguanyaoshu_skill:'巧匠', - jiguanyaoshu_skill_info:'每当你于回合外失去装备区内的牌,你获得一个随机零件。', - jiguanyaoshu_info:'出牌阶段对距离1以内的一名角色使用,目标随机装备一件装备牌并获得技能巧匠(每当你于回合外失去装备区内的牌,你获得一个随机零件)。', - hslingjian:'零件', - hslingjian_xuanfengzhiren:'旋风之刃', - hslingjian_xuanfengzhiren_info:'可用于煅造装备;随机弃置一名角色的一张牌。', - hslingjian_zhongxinghujia:'重型护甲', - hslingjian_zhongxinghujia_info:'可用于煅造装备;令一名角色装备一件随机防具,然后随机弃置其一张手牌。', - hslingjian_jinjilengdong:'紧急冷冻', - hslingjian_jinjilengdong_bg:'冻', - hslingjian_jinjilengdong_info:'可用于煅造装备;令一名武将牌正面朝上的其他角色获得2点护甲并翻面,该角色不能使用卡牌,也不能成为卡牌的目标直到武将牌翻回正面。', - hslingjian_yinmilichang:'隐秘力场', - hslingjian_yinmilichang_info:'可用于煅造装备;令一名其他角色获得技能潜行,直到其下一回合开始。', - hslingjian_xingtigaizao:'型体改造', - hslingjian_xingtigaizao_info:'可用于煅造装备;摸一张牌,本回合手牌上限-1。', - hslingjian_shengxiuhaojiao:'生锈号角', - hslingjian_shengxiuhaojiao_info:'可用于煅造装备;令一名角色获得技能嘲讽,直到其下一回合开始。', - hslingjian_shijianhuisu:'时间回溯', - hslingjian_shijianhuisu_info:'可用于煅造装备;令一名其他角色将其装备牌收回手牌。', - hslingjian_chaofeng:'嘲讽', - hslingjian_chaofeng_info:'锁定技,与你相邻的角色只能选择你为出杀目标。', - qinglonglingzhu:'青龙灵珠', - qinglonglingzhu_ab:'灵珠', - qinglonglingzhu_info:'每当你造成一次属性伤害,你可以获得对方的一张牌。', - xingjunyan:'星君眼', - xingjunyan_info:'你的杀造成的伤害+1;杀对你造成的伤害+1。', - guiyanfadao:'鬼眼法刀', - guiyanfadao_bg:'眼', - guiyanfadao_info:'每当你使用杀命中目标,你可以防止伤害,改为令目标失去1点体力。', - tianxianjiu:'天仙酒', - tianxianjiu_bg:'仙', - tianxianjiu_info:'出牌阶段对自己使用,你使用的下一张杀造成伤害后可以摸两张牌;濒死阶段,对自己使用,回复1点体力。', + guisheqi: "龟蛇旗", + guisheqi_info: "出牌阶段对一名角色使用,目标获得1点护甲。", + jiguanfeng: "机关蜂", + jiguanfeng_info: + "出牌阶段对一名其他角色使用,目标需打出一张闪,否则非锁定技失效直到下一回合开始,并受到1点伤害。", + jiguanyuan: "机关鸢", + jiguanyuan_info: + "出牌阶段对一名其他角色使用,你将此牌和一张其它牌置于一名其他角色的武将牌上,然后摸一张牌;该角色于下一结束阶段获得武将牌上的牌。", + jiguantong: "机关火筒", + jiguantong_ab: "火筒", + jiguantong_info: + "出牌阶段对所有其他角色使用,目标弃置一张手牌,或受到1点火焰伤害;若没有人选择受到伤害,使用者摸一张牌。", + jiutiansuanchi: "九天算尺", + jiutiansuanchi_info: + "每当你使用杀造成伤害,你可以弃置一张牌并展示受伤害角色的一张手牌,若此牌与你弃置的牌花色或点数相同,此杀的伤害+2。", + shenmiguo: "神秘果", + shenmiguo_info: + "出牌阶段内,当你使用一张基本牌或普通锦囊牌后使用,令此牌再结算一次。每阶段限用一次。", + qinglianxindeng: "青莲心灯", + qinglianxindeng_info: "你防止锦囊牌造成的伤害。", + hslingjian_xuanfengzhiren_duanzao: "风刃", + hslingjian_xuanfengzhiren_duanzao2: "风", + hslingjian_xuanfengzhiren_equip1_info: "每当你用杀造成一次伤害,受伤害角色随机弃置一张牌。", + hslingjian_xuanfengzhiren_equip2_info: "每当你受到杀造成的伤害,伤害来源随机弃置一张牌。", + hslingjian_xuanfengzhiren_equip3_info: "当你于回合外失去牌后,你本回合的防御距离+1。", + hslingjian_xuanfengzhiren_equip4_info: "当你于回合内失去牌后,你本回合的进攻距离+1。", + hslingjian_xuanfengzhiren_equip5_info: + "出牌阶段限一次,你可以弃置一张牌,然后随机弃置一名其他角色的一张牌。", + hslingjian_zhongxinghujia_duanzao: "重甲", + hslingjian_zhongxinghujia_duanzao2: "护", + hslingjian_zhongxinghujia_equip1_info: "每当你用杀造成一次伤害,你可以随机装备一件防具牌。", + hslingjian_zhongxinghujia_equip2_info: "每当你受到杀造成的伤害,你可以弃置伤害来源的防具牌。", + hslingjian_zhongxinghujia_equip3_info: "当你的装备区内有防具牌时,你的防御距离+1。", + hslingjian_zhongxinghujia_equip4_info: "当你的装备区内有防具牌时,你的进攻距离+1。", + hslingjian_zhongxinghujia_equip5_info: + "出牌阶段限一次,你可以弃置两张牌,然后令一名角色随机装备一件防具。", + hslingjian_jinjilengdong_duanzao: "冰冻", + hslingjian_jinjilengdong_duanzao2: "冰", + hslingjian_jinjilengdong_equip1_info: "每当你用杀造成一次伤害,你可以令目标摸两张牌并翻面。", + hslingjian_jinjilengdong_equip2_info: "每当你受到杀造成的伤害,你可以令伤害来源摸两张牌并翻面。", + hslingjian_jinjilengdong_equip3_info: "你的武将牌背面朝上时防御距离+2。", + hslingjian_jinjilengdong_equip4_info: "你的武将牌背面朝上时进攻距离+2。", + hslingjian_jinjilengdong_equip5_info: + "回合结束后,若你的武将牌正面朝上,你可以与一名武将牌正面朝上的其他角色同时翻面,然后各摸两张牌。", + hslingjian_yinmilichang_duanzao: "隐力", + hslingjian_yinmilichang_duanzao2: "隐", + hslingjian_yinmilichang_equip1_info: + "每当你用杀造成一次伤害,你可以令一名其他角色获得潜行直到其下一回合开始。", + hslingjian_yinmilichang_equip2_info: "每当你受到一次伤害,你本回合内获得潜行。", + hslingjian_yinmilichang_equip3_info: "当你的体力值为1时,你的防御距离+1。", + hslingjian_yinmilichang_equip4_info: "当你的体力值为1时,你的进攻距离+1。", + hslingjian_yinmilichang_equip5_info: "当你没有手牌时,你不能成为杀或决斗的目标。", + hslingjian_xingtigaizao_duanzao: "移形", + hslingjian_xingtigaizao_duanzao2: "形", + hslingjian_xingtigaizao_equip1_info: "每当你用杀造成一次伤害,你摸一张牌。", + hslingjian_xingtigaizao_equip2_info: "每当你受到杀造成的伤害,你摸一张牌。", + hslingjian_xingtigaizao_equip3_info: "你的防御距离+1,进攻距离-1。", + hslingjian_xingtigaizao_equip4_info: "你的防御距离-1,进攻距离+1。", + hslingjian_xingtigaizao_equip5_info: "你于摸牌阶段额外摸一张牌;你的手牌上限-1。", + hslingjian_shengxiuhaojiao_duanzao: "号角", + hslingjian_shengxiuhaojiao_duanzao2: "角", + hslingjian_shengxiuhaojiao_equip1_info: "有嘲讽的角色不能闪避你的杀。", + hslingjian_shengxiuhaojiao_equip2_info: "有嘲讽的角色不能对你使用杀。", + hslingjian_shengxiuhaojiao_equip3_info: "若你的手牌数大于你的体力值,你的防御距离+1。", + hslingjian_shengxiuhaojiao_equip4_info: "若你的手牌数大于你的体力值,你的进攻距离+1。", + hslingjian_shengxiuhaojiao_equip5_info: + "出牌阶段限一次,你可以弃置两张牌,然后令一名角色获得或解除嘲讽。", + hslingjian_shijianhuisu_duanzao: "回溯", + hslingjian_shijianhuisu_duanzao2: "溯", + hslingjian_shijianhuisu_equip1_info: "当你装备一张防具牌时,你摸一张牌。", + hslingjian_shijianhuisu_equip2_info: "当你装备一张武器牌时,你摸一张牌。", + hslingjian_shijianhuisu_equip3_info: "当你的装备区内没有其他牌时,你的防御距离+1。", + hslingjian_shijianhuisu_equip4_info: "当你的装备区内没有其他牌时,你的进攻距离+1。", + hslingjian_shijianhuisu_equip5_info: + "出牌阶段限一次,你可以弃置一张牌,然后令一名其他角色将其装备区内的牌收回手牌。", + _lingjianduanzao: "煅造", + _lingjianduanzao_info: + "出牌阶段,你可以将一张装备牌和一张可煅造的牌合成为一件强化装备,并装备给距离1以内的一名角色。", + jiguanshu: "机关鼠", + jiguanshu_info: + "出牌阶段对自己使用,用随机祭器强化装备区内的一张随机装备,然后用随机零件强化其余的装备。", + lingjiandai: "零件袋", + lingjiandai_info: "出牌阶段对自己使用,获得3张随机零件。", + mujiaren: "木甲人", + mujiaren_info: "出牌阶段限用一次,将你手牌中的非基本牌(含此张)替换为随机的机关牌。", + jiguanyaoshu: "机关要术", + jiguanyaoshu_skill: "巧匠", + jiguanyaoshu_skill_info: "每当你于回合外失去装备区内的牌,你获得一个随机零件。", + jiguanyaoshu_info: + "出牌阶段对距离1以内的一名角色使用,目标随机装备一件装备牌并获得技能巧匠(每当你于回合外失去装备区内的牌,你获得一个随机零件)。", + hslingjian: "零件", + hslingjian_xuanfengzhiren: "旋风之刃", + hslingjian_xuanfengzhiren_info: "可用于煅造装备;随机弃置一名角色的一张牌。", + hslingjian_zhongxinghujia: "重型护甲", + hslingjian_zhongxinghujia_info: + "可用于煅造装备;令一名角色装备一件随机防具,然后随机弃置其一张手牌。", + hslingjian_jinjilengdong: "紧急冷冻", + hslingjian_jinjilengdong_bg: "冻", + hslingjian_jinjilengdong_info: + "可用于煅造装备;令一名武将牌正面朝上的其他角色获得2点护甲并翻面,该角色不能使用卡牌,也不能成为卡牌的目标直到武将牌翻回正面。", + hslingjian_yinmilichang: "隐秘力场", + hslingjian_yinmilichang_info: "可用于煅造装备;令一名其他角色获得技能潜行,直到其下一回合开始。", + hslingjian_xingtigaizao: "型体改造", + hslingjian_xingtigaizao_info: "可用于煅造装备;摸一张牌,本回合手牌上限-1。", + hslingjian_shengxiuhaojiao: "生锈号角", + hslingjian_shengxiuhaojiao_info: "可用于煅造装备;令一名角色获得技能嘲讽,直到其下一回合开始。", + hslingjian_shijianhuisu: "时间回溯", + hslingjian_shijianhuisu_info: "可用于煅造装备;令一名其他角色将其装备牌收回手牌。", + hslingjian_chaofeng: "嘲讽", + hslingjian_chaofeng_info: "锁定技,与你相邻的角色只能选择你为出杀目标。", + qinglonglingzhu: "青龙灵珠", + qinglonglingzhu_ab: "灵珠", + qinglonglingzhu_info: "每当你造成一次属性伤害,你可以获得对方的一张牌。", + xingjunyan: "星君眼", + xingjunyan_info: "你的杀造成的伤害+1;杀对你造成的伤害+1。", + guiyanfadao: "鬼眼法刀", + guiyanfadao_bg: "眼", + guiyanfadao_info: "每当你使用杀命中目标,你可以防止伤害,改为令目标失去1点体力。", + tianxianjiu: "天仙酒", + tianxianjiu_bg: "仙", + tianxianjiu_info: + "出牌阶段对自己使用,你使用的下一张杀造成伤害后可以摸两张牌;濒死阶段,对自己使用,回复1点体力。", // xiangyuye:'翔羽叶', // xiangyuye_info:'出牌阶段,对一名攻击范围外的角色使用,令其弃置一张黑色手牌或失去1点体力。', // huanpodan:'还魄丹', @@ -5210,268 +5501,286 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // huanpodan_skill:'还魄丹', // huanpodan_skill_bg:'丹', // huanpodan_skill_info:'防止一次死亡,改为弃置所有牌,将体力值变为1并摸一张牌。', - ximohu:'吸魔壶', - ximohu_bg:'魔', + ximohu: "吸魔壶", + ximohu_bg: "魔", // ximohu_info:'锁定技,你将即将受到的雷属性伤害转化为你的体力值。', - sadengjinhuan:'萨登荆环', - sadengjinhuan_ab:'荆环', - sadengjinhuan_info:'当你的杀被闪避后,可以进行一次判定,若结果为红色目标需再打出一张闪。', - sadengjinhuan_bg:'荆', - qipoguyu:'奇魄古玉', - xujin:'蓄劲', - xujin2:'蓄劲', + sadengjinhuan: "萨登荆环", + sadengjinhuan_ab: "荆环", + sadengjinhuan_info: "当你的杀被闪避后,可以进行一次判定,若结果为红色目标需再打出一张闪。", + sadengjinhuan_bg: "荆", + qipoguyu: "奇魄古玉", + xujin: "蓄劲", + xujin2: "蓄劲", // qipoguyu_info:'装备后获得蓄劲技能。', - xujin_info:'回合开始前,若你的蓄劲标记数小于当前的体力值,你可以跳过此回合,并获得一枚蓄劲标记。锁定技,每当你即将造成伤害,你令此伤害+X,然后弃置一枚蓄劲标记,X为你拥有的蓄劲标记数。', - guilingzhitao:'归灵指套', - nigong:'逆攻', - nigong2:'逆攻', - nigong3:'逆攻', - nigong4:'逆攻', - guilingzhitao_info:'每当你受到1点伤害,你获得一个逆攻标记,标记数不能超过4。出牌阶段,你可以弃置所有逆攻标记并令对一名其他角色造成标记数一半的伤害(若非整数则向下取整并摸一张牌)。', - nigong_info:'每当你受到1点伤害,你获得一个逆攻标记,标记数不能超过4。出牌阶段,你可以弃置所有逆攻标记并令对一名其他角色造成标记数一半的伤害(若非整数则向下取整并摸一张牌)。', - baihupifeng:'白狐披风', - baihupifeng_bg:'狐', - baihupifeng_info:'结束阶段,若你的体力值是全场最小的之一,你可以回复1点体力。', - fengxueren:'封雪刃', - fengxueren_bg:'雪', - fengxueren_info:'你使用杀击中目标后,若目标武将牌正面朝上,你可以防止伤害,然后令目标摸一张牌并翻面。', - chilongya:'赤龙牙', - chilongya_info:'锁定技,你的火属性伤害+1。', - daihuofenglun:'带火风轮', - daihuofenglun_ab:'风轮', - daihuofenglun_bg:'轮', - daihuofenglun_info:'你的进攻距离+2,你的防御距离-1。', - xiayuncailing:'霞云彩绫', - xiayuncailing_ab:'彩绫', - xiayuncailing_bg:'云', - xiayuncailing_info:'你的进攻距离-1,你的防御距离+2。', - shentoumianju:'神偷面具', - shentoumianju_bg:'偷', - shentoumianju_info:'出牌阶段,你可以指定一名手牌比你多的角色,弃置一张手牌并进行一次判定,若结果不为梅花,你获得其一张手牌。', - shentou:'神偷', - shentou_info:'出牌阶段,你可以进行一次判定,若结果不为梅花,你获得任意一名角色的一张手牌。', - xianluhui:'仙炉灰', - xianluhui_info:'令所有已受伤角色获得1点护甲。', - caoyao:'草药', - caoyao_info:'出牌阶段,对距离为1以内的角色使用,回复1点体力。', - langeguaiyi:'蓝格怪衣', - langeguaiyi_bg:'格', - langeguaiyi_info:'出牌阶段限一次,你可以进行一次判定,然后按花色执行以下效果。红桃:你回复1点体力;方片:你摸一张牌;梅花:你令一名随机敌方角色随机弃置一张牌;黑桃:无事发生。', - longfan:'龙帆', - longfan_info:'出牌阶段限一次,你可以进行一次判定,然后按花色执行以下效果。红桃:你回复1点体力;方片:你摸一张牌;梅花:你令一名随机敌方角色随机弃置一张牌;黑桃:无事发生。', + xujin_info: + "回合开始前,若你的蓄劲标记数小于当前的体力值,你可以跳过此回合,并获得一枚蓄劲标记。锁定技,每当你即将造成伤害,你令此伤害+X,然后弃置一枚蓄劲标记,X为你拥有的蓄劲标记数。", + guilingzhitao: "归灵指套", + nigong: "逆攻", + nigong2: "逆攻", + nigong3: "逆攻", + nigong4: "逆攻", + guilingzhitao_info: + "每当你受到1点伤害,你获得一个逆攻标记,标记数不能超过4。出牌阶段,你可以弃置所有逆攻标记并令对一名其他角色造成标记数一半的伤害(若非整数则向下取整并摸一张牌)。", + nigong_info: + "每当你受到1点伤害,你获得一个逆攻标记,标记数不能超过4。出牌阶段,你可以弃置所有逆攻标记并令对一名其他角色造成标记数一半的伤害(若非整数则向下取整并摸一张牌)。", + baihupifeng: "白狐披风", + baihupifeng_bg: "狐", + baihupifeng_info: "结束阶段,若你的体力值是全场最小的之一,你可以回复1点体力。", + fengxueren: "封雪刃", + fengxueren_bg: "雪", + fengxueren_info: + "你使用杀击中目标后,若目标武将牌正面朝上,你可以防止伤害,然后令目标摸一张牌并翻面。", + chilongya: "赤龙牙", + chilongya_info: "锁定技,你的火属性伤害+1。", + daihuofenglun: "带火风轮", + daihuofenglun_ab: "风轮", + daihuofenglun_bg: "轮", + daihuofenglun_info: "你的进攻距离+2,你的防御距离-1。", + xiayuncailing: "霞云彩绫", + xiayuncailing_ab: "彩绫", + xiayuncailing_bg: "云", + xiayuncailing_info: "你的进攻距离-1,你的防御距离+2。", + shentoumianju: "神偷面具", + shentoumianju_bg: "偷", + shentoumianju_info: + "出牌阶段,你可以指定一名手牌比你多的角色,弃置一张手牌并进行一次判定,若结果不为梅花,你获得其一张手牌。", + shentou: "神偷", + shentou_info: "出牌阶段,你可以进行一次判定,若结果不为梅花,你获得任意一名角色的一张手牌。", + xianluhui: "仙炉灰", + xianluhui_info: "令所有已受伤角色获得1点护甲。", + caoyao: "草药", + caoyao_info: "出牌阶段,对距离为1以内的角色使用,回复1点体力。", + langeguaiyi: "蓝格怪衣", + langeguaiyi_bg: "格", + langeguaiyi_info: + "出牌阶段限一次,你可以进行一次判定,然后按花色执行以下效果。红桃:你回复1点体力;方片:你摸一张牌;梅花:你令一名随机敌方角色随机弃置一张牌;黑桃:无事发生。", + longfan: "龙帆", + longfan_info: + "出牌阶段限一次,你可以进行一次判定,然后按花色执行以下效果。红桃:你回复1点体力;方片:你摸一张牌;梅花:你令一名随机敌方角色随机弃置一张牌;黑桃:无事发生。", // longfan_info:'0000:翻面;1111:弃手牌;2222:弃装备牌;3333:受伤害;4444:失去体力;5555:连环;6666:摸牌;7777:回复体力;8888:弃置判定牌;9999:置衡。', - guiyoujie:'鬼幽结', - guiyoujie_bg:'结', - guiyoujie_info:'出牌阶段,对一名其他角色使用。若判定结果为黑色,其失去1点体力并随机弃置一张牌。', - yufulu:'御夫录', - yufulu_info:'出牌阶段,可弃置一张武器牌令一名角色受到1点伤害,然后该角色获得此武器牌。', - touzhi:'投掷', - touzhi_info:'出牌阶段,可弃置一张武器牌令一名角色受到1点伤害,然后该角色获得此武器牌。', - xixueguizhihuan:'吸血鬼指环', - xixueguizhihuan_ab:'血环', - xixueguizhihuan_info:'锁定技,每当你使用杀造成1点伤害,你回复1点体力。', - xixue:'吸血', - xixue_info:'锁定技,每当你使用杀造成1点伤害,你回复1点体力。', - zhufangshenshi:'祠符', - zhufangshenshi_info:'出牌阶段,对一名其他角色使用,本回合内对其使用卡牌无视距离,结算后摸一张牌。', - jingleishan:'惊雷闪', - jingleishan_info:'出牌阶段,对所有其他角色使用。每名目标角色需打出一张【杀】,否则受到1点雷电伤害。', - chiyuxi:'炽羽袭', - chiyuxi_info:'出牌阶段,对所有其他角色使用。每名目标角色需打出一张【闪】,否则受到1点火焰伤害。', - guangshatianyi:'光纱天衣', - guangshatianyi_bg:'纱', - guangshatianyi_info:'锁定技,每当你即将受到伤害,有三分之一的概率令伤害减一。', - sifeizhenmian:'四非真面', - sifeizhenmian_info:'出牌阶段限一次,你可以令一名有手牌的其他角色进行一次判定,若结果为不为红桃且目标有可用的手牌,目标随机使用一张手牌(随机指定目标)。', - yiluan:'意乱', - yiluan_info:'出牌阶段限一次,你可以令一名有手牌的其他角色进行一次判定,若结果为不为红桃且目标有可用的手牌,目标随机使用一张手牌(随机指定目标)。', - donghuangzhong:'东皇钟', - xuanyuanjian:'轩辕剑', - xuanyuanjian2:'轩辕剑', - pangufu:'盘古斧', - lianyaohu:'炼妖壶', - lianyaohu_skill:'炼妖壶', - lianyaohu_skill_bg:'壶', - haotianta:'昊天塔', - fuxiqin:'伏羲琴', - shennongding:'神农鼎', - kongdongyin:'崆峒印', - kunlunjingc:'昆仑镜', - nvwashi:'女娲石', - donghuangzhong_bg:'钟', - lianyaohu_bg:'壶', - haotianta_bg:'塔', - fuxiqin_bg:'琴', - shennongding_bg:'鼎', - kongdongyin_bg:'印', - kunlunjingc_bg:'镜', - nvwashi_bg:'石', - kongxin:'控心', - lianhua:'炼化', + guiyoujie: "鬼幽结", + guiyoujie_bg: "结", + guiyoujie_info: "出牌阶段,对一名其他角色使用。若判定结果为黑色,其失去1点体力并随机弃置一张牌。", + yufulu: "御夫录", + yufulu_info: "出牌阶段,可弃置一张武器牌令一名角色受到1点伤害,然后该角色获得此武器牌。", + touzhi: "投掷", + touzhi_info: "出牌阶段,可弃置一张武器牌令一名角色受到1点伤害,然后该角色获得此武器牌。", + xixueguizhihuan: "吸血鬼指环", + xixueguizhihuan_ab: "血环", + xixueguizhihuan_info: "锁定技,每当你使用杀造成1点伤害,你回复1点体力。", + xixue: "吸血", + xixue_info: "锁定技,每当你使用杀造成1点伤害,你回复1点体力。", + zhufangshenshi: "祠符", + zhufangshenshi_info: + "出牌阶段,对一名其他角色使用,本回合内对其使用卡牌无视距离,结算后摸一张牌。", + jingleishan: "惊雷闪", + jingleishan_info: + "出牌阶段,对所有其他角色使用。每名目标角色需打出一张【杀】,否则受到1点雷电伤害。", + chiyuxi: "炽羽袭", + chiyuxi_info: "出牌阶段,对所有其他角色使用。每名目标角色需打出一张【闪】,否则受到1点火焰伤害。", + guangshatianyi: "光纱天衣", + guangshatianyi_bg: "纱", + guangshatianyi_info: "锁定技,每当你即将受到伤害,有三分之一的概率令伤害减一。", + sifeizhenmian: "四非真面", + sifeizhenmian_info: + "出牌阶段限一次,你可以令一名有手牌的其他角色进行一次判定,若结果为不为红桃且目标有可用的手牌,目标随机使用一张手牌(随机指定目标)。", + yiluan: "意乱", + yiluan_info: + "出牌阶段限一次,你可以令一名有手牌的其他角色进行一次判定,若结果为不为红桃且目标有可用的手牌,目标随机使用一张手牌(随机指定目标)。", + donghuangzhong: "东皇钟", + xuanyuanjian: "轩辕剑", + xuanyuanjian2: "轩辕剑", + pangufu: "盘古斧", + lianyaohu: "炼妖壶", + lianyaohu_skill: "炼妖壶", + lianyaohu_skill_bg: "壶", + haotianta: "昊天塔", + fuxiqin: "伏羲琴", + shennongding: "神农鼎", + kongdongyin: "崆峒印", + kunlunjingc: "昆仑镜", + nvwashi: "女娲石", + donghuangzhong_bg: "钟", + lianyaohu_bg: "壶", + haotianta_bg: "塔", + fuxiqin_bg: "琴", + shennongding_bg: "鼎", + kongdongyin_bg: "印", + kunlunjingc_bg: "镜", + nvwashi_bg: "石", + kongxin: "控心", + lianhua: "炼化", // dujian:'毒箭', // dujian_info:'出牌阶段,对一名有手牌或装备牌的角色使用,令其展示一张手牌,若与你选择的手牌颜色相同,其失去1点体力。', - lianhua_info:'出牌阶段限一次,你可以弃置两张炼妖壶中的牌,从牌堆中获得一张与弃置的牌类别均不相同的牌。', - shouna:'收纳', - shouna_info:'出牌阶段限一次,你可以弃置一张手牌,并将一名其他角色的一张手牌置入炼妖壶。', - donghuangzhong_info:'结束阶段,你可以弃置一张红色手牌,并选择一名角色将一张随机单体延时锦囊置入其判定区。', - xuanyuanjian_info:'装备时获得1点护甲;每当你即将造成一次伤害,你令此伤害加一并变为雷属性,并在伤害结算后失去1点体力。任何时候,若你体力值不超过2,则立即失去轩辕剑。', - pangufu_info:'锁定技,每当你造成一次伤害,受伤角色须弃置一张牌。', - haotianta_info:'锁定技,任意一名角色进行判定前,你观看牌堆顶的2张牌,并选择一张作为判定结果,此结果不可被更改,也不能触发技能。', - shennongding_info:'出牌阶段,你可以弃置两张手牌,然后回复1点体力。每阶段限一次。', - kongdongyin_info:'令你抵挡一次死亡,将体力回复至1,并摸一张牌,发动后进入弃牌堆。', - kunlunjingc_info:'出牌阶段限一次,你可以观看牌堆顶的三张牌,然后用一张手牌替换其中的一张。', - nvwashi_info:'当一名角色濒死时,若你的体力值大于1,你可以失去1点体力并令其回复1点体力。', - kongxin_info:'出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你可以指定另一名角色视为对方对该角色使用一张杀,否则对方可弃置你一张牌。', - fuxiqin_info:'出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你可以指定另一名角色视为对方对该角色使用一张杀,否则对方可弃置你一张牌。', - lianyaohu_info:'出牌阶段各限一次,你可以选择一项:1.弃置一张手牌,并将一名其他角色的一张手牌置入炼妖壶;2.弃置两张炼妖壶中的牌,从牌堆中获得一张与弃置的牌类别均不相同的牌。', + lianhua_info: + "出牌阶段限一次,你可以弃置两张炼妖壶中的牌,从牌堆中获得一张与弃置的牌类别均不相同的牌。", + shouna: "收纳", + shouna_info: "出牌阶段限一次,你可以弃置一张手牌,并将一名其他角色的一张手牌置入炼妖壶。", + donghuangzhong_info: + "结束阶段,你可以弃置一张红色手牌,并选择一名角色将一张随机单体延时锦囊置入其判定区。", + xuanyuanjian_info: + "装备时获得1点护甲;每当你即将造成一次伤害,你令此伤害加一并变为雷属性,并在伤害结算后失去1点体力。任何时候,若你体力值不超过2,则立即失去轩辕剑。", + pangufu_info: "锁定技,每当你造成一次伤害,受伤角色须弃置一张牌。", + haotianta_info: + "锁定技,任意一名角色进行判定前,你观看牌堆顶的2张牌,并选择一张作为判定结果,此结果不可被更改,也不能触发技能。", + shennongding_info: "出牌阶段,你可以弃置两张手牌,然后回复1点体力。每阶段限一次。", + kongdongyin_info: "令你抵挡一次死亡,将体力回复至1,并摸一张牌,发动后进入弃牌堆。", + kunlunjingc_info: "出牌阶段限一次,你可以观看牌堆顶的三张牌,然后用一张手牌替换其中的一张。", + nvwashi_info: "当一名角色濒死时,若你的体力值大于1,你可以失去1点体力并令其回复1点体力。", + kongxin_info: + "出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你可以指定另一名角色视为对方对该角色使用一张杀,否则对方可弃置你一张牌。", + fuxiqin_info: + "出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你可以指定另一名角色视为对方对该角色使用一张杀,否则对方可弃置你一张牌。", + lianyaohu_info: + "出牌阶段各限一次,你可以选择一项:1.弃置一张手牌,并将一名其他角色的一张手牌置入炼妖壶;2.弃置两张炼妖壶中的牌,从牌堆中获得一张与弃置的牌类别均不相同的牌。", }, - list:[ - ['heart',1,'hufu'], - ['spade',1,'hufu'], - ['club',1,'qiankundai'], + list: [ + ["heart", 1, "hufu"], + ["spade", 1, "hufu"], + ["club", 1, "qiankundai"], // ['heart',3,'yihuajiemu'], // ['diamond',1,'yihuajiemu'], // ['diamond',7,'yihuajiemu'], - ['diamond',3,'liuxinghuoyu','fire'], - ['heart',6,'liuxinghuoyu','fire'], - ['heart',9,'liuxinghuoyu','fire'], + ["diamond", 3, "liuxinghuoyu", "fire"], + ["heart", 6, "liuxinghuoyu", "fire"], + ["heart", 9, "liuxinghuoyu", "fire"], - ['spade',1,'baihupifeng'], - ['club',1,'fengxueren'], - ['diamond',1,'langeguaiyi'], - ['heart',1,'daihuofenglun','fire'], + ["spade", 1, "baihupifeng"], + ["club", 1, "fengxueren"], + ["diamond", 1, "langeguaiyi"], + ["heart", 1, "daihuofenglun", "fire"], - ['diamond',2,'xiayuncailing'], + ["diamond", 2, "xiayuncailing"], // ['heart',2,'pantao'], // ['heart',2,'huanpodan'], - ['club',3,'caoyao'], - ['diamond',3,'chilongya','fire'], - ['spade',3,'guiyoujie'], + ["club", 3, "caoyao"], + ["diamond", 3, "chilongya", "fire"], + ["spade", 3, "guiyoujie"], - ['club',4,'caoyao'], - ['spade',4,'zhufangshenshi'], + ["club", 4, "caoyao"], + ["spade", 4, "zhufangshenshi"], // ['spade',4,'huanpodan'], - ['club',5,'caoyao'], - ['spade',5,'xixueguizhihuan'], + ["club", 5, "caoyao"], + ["spade", 5, "xixueguizhihuan"], // ['diamond',5,'huanpodan'], - ['club',6,'shentoumianju'], - ['spade',6,'yufulu'], + ["club", 6, "shentoumianju"], + ["spade", 6, "yufulu"], - ['diamond',7,'chiyuxi','fire'], - ['club',7,'jingleishan','thunder'], - ['spade',7,'guilingzhitao'], + ["diamond", 7, "chiyuxi", "fire"], + ["club", 7, "jingleishan", "thunder"], + ["spade", 7, "guilingzhitao"], - ['spade',8,'zhufangshenshi'], + ["spade", 8, "zhufangshenshi"], // ['club',8,'xiangyuye','poison'], - ['spade',9,'yangpijuan'], - ['club',9,'guiyoujie'], + ["spade", 9, "yangpijuan"], + ["club", 9, "guiyoujie"], // ['diamond',9,'xiangyuye','poison'], // ['diamond',9,'tianxianjiu'], - ['heart',9,'tianxianjiu'], - ['diamond',2,'tianxianjiu'], + ["heart", 9, "tianxianjiu"], + ["diamond", 2, "tianxianjiu"], - ['spade',2,'qinglonglingzhu'], - ['spade',7,'xingjunyan'], + ["spade", 2, "qinglonglingzhu"], + ["spade", 7, "xingjunyan"], //['spade',10,'qipoguyu'], //['diamond',10,'xiangyuye','poison'], - ['club',7,'yangpijuan'], + ["club", 7, "yangpijuan"], // ['spade',11,'xiangyuye','poison'], - ['spade',12,'guiyanfadao','poison'], + ["spade", 12, "guiyanfadao", "poison"], - ['spade',13,'xianluhui'], - ['diamond',3,'guangshatianyi'], - ['club',13,'sadengjinhuan'], + ["spade", 13, "xianluhui"], + ["diamond", 3, "guangshatianyi"], + ["club", 13, "sadengjinhuan"], - ['club',2,'lingjiandai'], + ["club", 2, "lingjiandai"], // ['spade',3,'lingjiandai'], // ['heart',5,'lingjiandai'], - ['diamond',8,'lingjiandai'], + ["diamond", 8, "lingjiandai"], - ['club',2,'jiguanshu'], + ["club", 2, "jiguanshu"], // ['spade',2,'jiguanshu'], // ['heart',2,'jiguanshu'], - ['diamond',2,'jiguanshu'], + ["diamond", 2, "jiguanshu"], - ['club',3,'jiguanyaoshu'], - ['spade',3,'jiguanyaoshu'], + ["club", 3, "jiguanyaoshu"], + ["spade", 3, "jiguanyaoshu"], // ['heart',3,'jiguanyaoshu'], // ['diamond',3,'jiguanyaoshu'], - ['spade',4,'sifeizhenmian'], - ['heart',13,'qinglianxindeng'], - ['club',3,'jiguanyuan'], - ['diamond',2,'jiguanyuan'], - ['diamond',4,'jiguantong'], - ['club',7,'jiguantong'], + ["spade", 4, "sifeizhenmian"], + ["heart", 13, "qinglianxindeng"], + ["club", 3, "jiguanyuan"], + ["diamond", 2, "jiguanyuan"], + ["diamond", 4, "jiguantong"], + ["club", 7, "jiguantong"], // ['spade',1,'shenmiguo'], - ['spade',2,'shenmiguo'], - ['heart',1,'shenmiguo'], - ['club',3,'jiguanfeng'], - ['spade',4,'jiguanfeng'], - ['spade',9,'guisheqi'], - ['club',7,'guisheqi'], + ["spade", 2, "shenmiguo"], + ["heart", 1, "shenmiguo"], + ["club", 3, "jiguanfeng"], + ["spade", 4, "jiguanfeng"], + ["spade", 9, "guisheqi"], + ["club", 7, "guisheqi"], - ['diamond',13,'donghuangzhong'], - ['diamond',13,'fuxiqin'], - ['spade',13,'kunlunjingc'], - ['spade',13,'xuanyuanjian'], - ['spade',13,'pangufu'], - ['club',13,'lianyaohu'], - ['diamond',13,'haotianta'], - ['club',13,'shennongding'], - ['heart',13,'nvwashi'], - ['heart',13,'kongdongyin'], + ["diamond", 13, "donghuangzhong"], + ["diamond", 13, "fuxiqin"], + ["spade", 13, "kunlunjingc"], + ["spade", 13, "xuanyuanjian"], + ["spade", 13, "pangufu"], + ["club", 13, "lianyaohu"], + ["diamond", 13, "haotianta"], + ["club", 13, "shennongding"], + ["heart", 13, "nvwashi"], + ["heart", 13, "kongdongyin"], - ['heart',6,'qinglongzhigui'], - ['diamond',6,'zhuquezhizhang'], - ['spade',6,'baishouzhihu'], - ['club',6,'xuanwuzhihuang'], - ['spade',7,'cangchizhibi'], - ['heart',5,'huanglinzhicong'], + ["heart", 6, "qinglongzhigui"], + ["diamond", 6, "zhuquezhizhang"], + ["spade", 6, "baishouzhihu"], + ["club", 6, "xuanwuzhihuang"], + ["spade", 7, "cangchizhibi"], + ["heart", 5, "huanglinzhicong"], - ['spade',9,'gouhunluo'], - ['club',7,'gouhunluo'], + ["spade", 9, "gouhunluo"], + ["club", 7, "gouhunluo"], - ['spade',1,'xuejibingbao'], - ['club',1,'xuejibingbao'], + ["spade", 1, "xuejibingbao"], + ["club", 1, "xuejibingbao"], - ['heart',3,'zhiluxiaohu'], - ['diamond',4,'zhiluxiaohu'], + ["heart", 3, "zhiluxiaohu"], + ["diamond", 4, "zhiluxiaohu"], - ['club',7,'mujiaren'], - ['heart',6,'mujiaren'], - ['diamond',11,'mujiaren'], + ["club", 7, "mujiaren"], + ["heart", 6, "mujiaren"], + ["diamond", 11, "mujiaren"], - ['club',6,'shuchui'], + ["club", 6, "shuchui"], // ['club',1,'fengyinzhidan'], // ['diamond',1,'fengyinzhidan'], // ['heart',1,'fengyinzhidan'], - ['spade',1,'fengyinzhidan'], + ["spade", 1, "fengyinzhidan"], - ['heart',9,'yuruyi'], + ["heart", 9, "yuruyi"], - ['club',4,'shencaojie'], - ['diamond',4,'shencaojie'], - ['spade',4,'shencaojie'], + ["club", 4, "shencaojie"], + ["diamond", 4, "shencaojie"], + ["spade", 4, "shencaojie"], - ['spade',1,'yuchanqian'], - ['club',2,'yuchankun'], - ['diamond',3,'yuchanzhen'], - ['heart',4,'yuchanxun'], - ['spade',5,'yuchankan'], - ['club',6,'yuchanli'], - ['diamond',7,'yuchangen'], - ['heart',8,'yuchandui'], + ["spade", 1, "yuchanqian"], + ["club", 2, "yuchankun"], + ["diamond", 3, "yuchanzhen"], + ["heart", 4, "yuchanxun"], + ["spade", 5, "yuchankan"], + ["club", 6, "yuchanli"], + ["diamond", 7, "yuchangen"], + ["heart", 8, "yuchandui"], // ['spade',3,'dujian','poison'], // ['club',11,'dujian','poison'], diff --git a/card/yingbian.js b/card/yingbian.js index f17f12c54..1f83bb44d 100644 --- a/card/yingbian.js +++ b/card/yingbian.js @@ -1,109 +1,167 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'yingbian', - connect:true, - card:{ - suijiyingbian:{ - global:'suijiyingbian_skill', - fullskin:true, - type:'trick', + name: "yingbian", + connect: true, + card: { + suijiyingbian: { + global: "suijiyingbian_skill", + fullskin: true, + type: "trick", }, - zhujinqiyuan:{ - type:'trick', - enable:true, - audio:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('hej')>0; + zhujinqiyuan: { + type: "trick", + enable: true, + audio: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("hej") > 0; }, - defaultYingbianEffect:'add', - content:function(){ - var dist=get.distance(player,target); - if(dist>1||card.yingbian_all) player.discardPlayerCard(target,'hej',true).set('target',target).set('ai',lib.card.guohe.ai.button); - if(dist<=1||card.yingbian_all) player.gainPlayerCard(target,'hej',true).set('target',target).set('ai',lib.card.shunshou.ai.button); + defaultYingbianEffect: "add", + content: function () { + var dist = get.distance(player, target); + if (dist > 1 || card.yingbian_all) + player + .discardPlayerCard(target, "hej", true) + .set("target", target) + .set("ai", lib.card.guohe.ai.button); + if (dist <= 1 || card.yingbian_all) + player + .gainPlayerCard(target, "hej", true) + .set("target", target) + .set("ai", lib.card.shunshou.ai.button); }, - fullskin:true, - postAi:function(targets){ - return targets.length==1&&targets[0].countCards('j'); + fullskin: true, + postAi: function (targets) { + return targets.length == 1 && targets[0].countCards("j"); }, - ai:{ - wuxie:function(target,card,player,viewer,status){ - if(get.attitude(viewer,player._trueMe||player)>0) return 0; - if(!card.yingbian_all&&get.distance(player,target)>1&&!target.hasCard(i=>{ - let val=get.value(i,target),subtypes=get.subtypes(i); - if(val<8&&target.hp<2&&!subtypes.includes('equip2')&&!subtypes.includes('equip5')) return false; - return val>3+Math.min(5,target.hp); - },'e')&&target.countCards('h')*_status.event.getRand('guohe_wuxie')>1.57) return 0; + ai: { + wuxie: function (target, card, player, viewer, status) { + if (get.attitude(viewer, player._trueMe || player) > 0) return 0; + if ( + !card.yingbian_all && + get.distance(player, target) > 1 && + !target.hasCard((i) => { + let val = get.value(i, target), + subtypes = get.subtypes(i); + if ( + val < 8 && + target.hp < 2 && + !subtypes.includes("equip2") && + !subtypes.includes("equip5") + ) + return false; + return val > 3 + Math.min(5, target.hp); + }, "e") && + target.countCards("h") * _status.event.getRand("guohe_wuxie") > 1.57 + ) + return 0; }, - yingbian:function(card,player,targets,viewer){ - if(get.attitude(viewer,player)<=0) return 0; - var base=0; - if(get.cardtag(card,'yingbian_all')){ - if(targets.filter(function(current){ - var att=get.attitude(player,current); - if(att<=0) return current.countCards('he',function(card){ - return get.value(card,current)>0; - })>1; - return current.countCards('ej',function(card){ - return get.position(card)=='j'||get.value(card,current)<=0; - })>1; - }).length) base+=6; + yingbian: function (card, player, targets, viewer) { + if (get.attitude(viewer, player) <= 0) return 0; + var base = 0; + if (get.cardtag(card, "yingbian_all")) { + if ( + targets.filter(function (current) { + var att = get.attitude(player, current); + if (att <= 0) + return ( + current.countCards("he", function (card) { + return get.value(card, current) > 0; + }) > 1 + ); + return ( + current.countCards("ej", function (card) { + return get.position(card) == "j" || get.value(card, current) <= 0; + }) > 1 + ); + }).length + ) + base += 6; } - if(get.cardtag(card,'yingbian_add')){ - if(game.hasPlayer(function(current){ - return !targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })) base+=5; + if (get.cardtag(card, "yingbian_add")) { + if ( + game.hasPlayer(function (current) { + return ( + !targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + base += 5; } - if(get.cardtag(card,'yingbian_hit')){ - if(game.hasPlayer(function(current){ - return get.attitude(current,player)<0&¤t.hasWuxie(); - })) base+=3*targets.length; + if (get.cardtag(card, "yingbian_hit")) { + if ( + game.hasPlayer(function (current) { + return get.attitude(current, player) < 0 && current.hasWuxie(); + }) + ) + base += 3 * targets.length; } return base; }, - basic:{ - order:7.5, - useful:(card,i)=>9.6/(2+i), - value:(card,player)=>{ - let max=0; - game.countPlayer(cur=>{ - let dist=get.distance(player,cur); - if(dist>1||card.yingbian_all) max=Math.max(max,lib.card.shunshou.ai.result.target(player,cur)*get.attitude(player,cur)); - else max=Math.max(max,lib.card.guohe.ai.result.target(player,cur)*get.attitude(player,cur)); + basic: { + order: 7.5, + useful: (card, i) => 9.6 / (2 + i), + value: (card, player) => { + let max = 0; + game.countPlayer((cur) => { + let dist = get.distance(player, cur); + if (dist > 1 || card.yingbian_all) + max = Math.max( + max, + lib.card.shunshou.ai.result.target(player, cur) * + get.attitude(player, cur) + ); + else + max = Math.max( + max, + lib.card.guohe.ai.result.target(player, cur) * + get.attitude(player, cur) + ); }); - if(max<=0) return 7; - if(card.yingbian_all) return 0.75*max; - return 0.6*max; - } + if (max <= 0) return 7; + if (card.yingbian_all) return 0.75 * max; + return 0.6 * max; + }, }, - result:{ - target:function(player,target){ - var discard=get.distance(player,target)>1; - if(get.attitude(player,target)<=0) return (target.countCards('he',function(card){ - return get.value(card,target)>0&&(discard||card!=target.getEquip('jinhe')); - })>0)?-1.5:1.5; - var js=target.getCards('j'); - if(js.length){ - var jj=js[0].viewAs?{name:js[0].viewAs}:js[0]; - if(js.length==1&&get.effect(target,jj,target,player)>=0){ + result: { + target: function (player, target) { + var discard = get.distance(player, target) > 1; + if (get.attitude(player, target) <= 0) + return target.countCards("he", function (card) { + return ( + get.value(card, target) > 0 && + (discard || card != target.getEquip("jinhe")) + ); + }) > 0 + ? -1.5 + : 1.5; + var js = target.getCards("j"); + if (js.length) { + var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0]; + if (js.length == 1 && get.effect(target, jj, target, player) >= 0) { return -1.5; } return 3; } return -1.5; }, - player:function(player,target){ - if(get.distance(player,target)>1) return 0; - if(get.attitude(player,target)<0&&!target.countCards('he',function(card){ - return get.value(card,target)>0&&card!=target.getEquip('jinhe'); - })){ + player: function (player, target) { + if (get.distance(player, target) > 1) return 0; + if ( + get.attitude(player, target) < 0 && + !target.countCards("he", function (card) { + return get.value(card, target) > 0 && card != target.getEquip("jinhe"); + }) + ) { return 0; } - if(get.attitude(player,target)>1){ - var js=target.getCards('j'); - if(js.length){ - var jj=js[0].viewAs?{name:js[0].viewAs}:js[0]; - if(js.length==1&&get.effect(target,jj,target,player)>=0){ + if (get.attitude(player, target) > 1) { + var js = target.getCards("j"); + if (js.length) { + var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0]; + if (js.length == 1 && get.effect(target, jj, target, player) >= 0) { return 0; } return 1; @@ -111,762 +169,869 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return 0; } return 1; - } + }, + }, + tag: { + loseCard: 1, + gain: 1, }, - tag:{ - loseCard:1, - gain:1, - } }, }, - dongzhuxianji:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - toself:true, - filterTarget:function(card,player,target){ - return target==player; + dongzhuxianji: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + toself: true, + filterTarget: function (card, player, target) { + return target == player; }, - modTarget:true, - content:function(){ + modTarget: true, + content: function () { target.chooseToGuanxing(2); target.draw(2); }, - ai:{ - basic:{ - order:7.2, - useful:4.5, - value:9.2 + ai: { + basic: { + order: 7.2, + useful: 4.5, + value: 9.2, }, - result:{ - target:2.5, + result: { + target: 2.5, + }, + tag: { + draw: 2, }, - tag:{ - draw:2 - } - } - }, - chuqibuyi:{ - audio:true, - enable:true, - type:'trick', - fullskin:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; }, - defaultYingbianEffect:'add', - content:function(){ - 'step 0' - if(player.isDead()||!target.countCards('h')){ + }, + chuqibuyi: { + audio: true, + enable: true, + type: "trick", + fullskin: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; + }, + defaultYingbianEffect: "add", + content: function () { + "step 0"; + if (player.isDead() || !target.countCards("h")) { event.finish(); return; } - player.choosePlayerCard(target,'h',true); - 'step 1' - if(result.bool){ + player.choosePlayerCard(target, "h", true); + "step 1"; + if (result.bool) { target.showCards(result.cards); - if(get.suit(card)!=get.suit(result.cards[0])) target.damage(); + if (get.suit(card) != get.suit(result.cards[0])) target.damage(); } }, - ai:{ - basic:{ - order:5, - useful:2, - value:6 + ai: { + basic: { + order: 5, + useful: 2, + value: 6, }, - yingbian:function(card,player,targets,viewer){ - if(get.attitude(viewer,player)<=0) return 0; - if(game.hasPlayer(function(current){ - return !targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })) return 6; + yingbian: function (card, player, targets, viewer) { + if (get.attitude(viewer, player) <= 0) return 0; + if ( + game.hasPlayer(function (current) { + return ( + !targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return 6; return 0; }, - result:{ - target:(player,target,card)=>{ + result: { + target: (player, target, card) => { //if(typeof card!=='object') return -2; - let suit=get.suit(card), - view=player.hasSkillTag('viewHandcard',null,target,true), - fz=0, - fm=0; - target.getCards('h',i=>{ - if(i.isKnownBy(player)){ - if(suit!==get.suit(i)){ - if(view||get.is.shownCard(i)) return -2; + let suit = get.suit(card), + view = player.hasSkillTag("viewHandcard", null, target, true), + fz = 0, + fm = 0; + target.getCards("h", (i) => { + if (i.isKnownBy(player)) { + if (suit !== get.suit(i)) { + if (view || get.is.shownCard(i)) return -2; fz++; fm++; - } - else if(!view&&!get.is.shownCard(i)) fm++; - } - else{ - fz+=0.75; + } else if (!view && !get.is.shownCard(i)) fm++; + } else { + fz += 0.75; fm++; } }); - if(!fm) return 0; - return -2*fz/fm; - } + if (!fm) return 0; + return (-2 * fz) / fm; + }, }, - tag:{ - damage:1, - } - } - }, - wuxinghelingshan:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-3}, - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['wuxinghelingshan_skill'] - }, - wutiesuolian:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['wutiesuolian_skill'] - }, - heiguangkai:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip2', - ai:{ - basic:{ - equipValue:2 - } - }, - skills:['heiguangkai_skill'], - }, - tongque:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip5', - ai:{ - basic:{ - equipValue:6.5 - } - }, - skills:['tongque_skill'] - }, - tianjitu:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip5', - skills:['tianjitu_skill'], - onLose:function(){ - player.addTempSkill('tianjitu_skill_lose') - }, - loseDelay:false, - ai:{ - value:function(card,player){ - if(player.countCards('h')>3||get.position(card)!='e') return 0.5; - return (player.countCards('h')-4)*5; + tag: { + damage: 1, }, - equipValue:function(card,player){ - if(player.countCards('h')>3||get.position(card)!='e') return 0.5; - return (player.countCards('h')-4)*5; - }, - basic:{ - equipValue:0.5 - } }, }, - taigongyinfu:{ - audio:true, - fullskin:true, - type:'equip', - subtype:'equip5', - ai:{ - basic:{ - equipValue:3 - } + wuxinghelingshan: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -3 }, + ai: { + basic: { + equipValue: 2, + }, }, - skills:['taigongyinfu_skill','taigongyinfu_link'], + skills: ["wuxinghelingshan_skill"], + }, + wutiesuolian: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + ai: { + basic: { + equipValue: 2, + }, + }, + skills: ["wutiesuolian_skill"], + }, + heiguangkai: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip2", + ai: { + basic: { + equipValue: 2, + }, + }, + skills: ["heiguangkai_skill"], + }, + tongque: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + ai: { + basic: { + equipValue: 6.5, + }, + }, + skills: ["tongque_skill"], + }, + tianjitu: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + skills: ["tianjitu_skill"], + onLose: function () { + player.addTempSkill("tianjitu_skill_lose"); + }, + loseDelay: false, + ai: { + value: function (card, player) { + if (player.countCards("h") > 3 || get.position(card) != "e") return 0.5; + return (player.countCards("h") - 4) * 5; + }, + equipValue: function (card, player) { + if (player.countCards("h") > 3 || get.position(card) != "e") return 0.5; + return (player.countCards("h") - 4) * 5; + }, + basic: { + equipValue: 0.5, + }, + }, + }, + taigongyinfu: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip5", + ai: { + basic: { + equipValue: 3, + }, + }, + skills: ["taigongyinfu_skill", "taigongyinfu_link"], }, }, - skill:{ - suijiyingbian_skill:{ - mod:{ - cardname:function(card,player){ - if(card.name=='suijiyingbian'&&player.storage.suijiyingbian) return player.storage.suijiyingbian; + skill: { + suijiyingbian_skill: { + mod: { + cardname: function (card, player) { + if (card.name == "suijiyingbian" && player.storage.suijiyingbian) + return player.storage.suijiyingbian; }, - cardnature:function(card,player){ - if(card.name=='suijiyingbian'&&player.storage.suijiyingbian_nature) return player.storage.suijiyingbian_nature; + cardnature: function (card, player) { + if (card.name == "suijiyingbian" && player.storage.suijiyingbian_nature) + return player.storage.suijiyingbian_nature; }, }, - trigger:{ - player:['useCard1','respond'], - global:'phaseBeginStart', + trigger: { + player: ["useCard1", "respond"], + global: "phaseBeginStart", }, - silent:true, - firstDo:true, - filter:function(event,player,name){ - if(name=='phaseBeginStart') return true; - var type=get.type(event.card); - return type=='basic'||type=='trick'; + silent: true, + firstDo: true, + filter: function (event, player, name) { + if (name == "phaseBeginStart") return true; + var type = get.type(event.card); + return type == "basic" || type == "trick"; }, - content:function(){ - if(event.triggername=='phaseBeginStart'){ + content: function () { + if (event.triggername == "phaseBeginStart") { delete player.storage.suijiyingbian; delete player.storage.suijiyingbian_nature; - } - else{ - player.storage.suijiyingbian=trigger.card.name; - player.storage.suijiyingbian_nature=trigger.card.nature; + } else { + player.storage.suijiyingbian = trigger.card.name; + player.storage.suijiyingbian_nature = trigger.card.nature; } }, }, - wuxinghelingshan_skill:{ - equipSkill:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return (event.card.name=='sha'&&lib.linked.some(n=>n!='kami'&&game.hasNature(event.card,n))); + wuxinghelingshan_skill: { + equipSkill: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + lib.linked.some((n) => n != "kami" && game.hasNature(event.card, n)) + ); }, - audio:true, - direct:true, - content:function(){ - 'step 0' - var list=lib.linked.slice(0); - list.remove('kami'); + audio: true, + direct: true, + content: function () { + "step 0"; + var list = lib.linked.slice(0); + list.remove("kami"); list.removeArray(get.natureList(trigger.card)); - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('wuxinghelingshan_skill')).set('prompt2','将'+get.translation(trigger.card)+'转换为以下属性之一'); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('wuxinghelingshan_skill'); - player.popup(get.translation(result.control)+'杀',result.control); - game.log(trigger.card,'被转为了','#y'+get.translation(result.control),'属性'); - game.setNature(trigger.card,result.control); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("wuxinghelingshan_skill")) + .set("prompt2", "将" + get.translation(trigger.card) + "转换为以下属性之一"); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("wuxinghelingshan_skill"); + player.popup(get.translation(result.control) + "杀", result.control); + game.log(trigger.card, "被转为了", "#y" + get.translation(result.control), "属性"); + game.setNature(trigger.card, result.control); } - } - }, - wutiesuolian_skill:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - equipSkill:true, - audio:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.target.isLinked();//||event.target.countCards('h')); }, - logTarget:'target', - content:function(){ - var target=trigger.target; - if(!target.isLinked()) target.link(); + }, + wutiesuolian_skill: { + trigger: { player: "useCardToPlayered" }, + forced: true, + equipSkill: true, + audio: true, + filter: function (event, player) { + return event.card.name == "sha" && !event.target.isLinked(); //||event.target.countCards('h')); + }, + logTarget: "target", + content: function () { + var target = trigger.target; + if (!target.isLinked()) target.link(); //else player.viewHandcards(target); }, }, - heiguangkai_skill:{ - equipSkill:true, - trigger:{target:'useCardToTargeted'}, - forced:true, - audio:true, - filter:function(event,player){ - if(event.targets.length<2) return false; - if(event.card.name!='sha'){ - var type=get.type(event.card); - if(type!='trick') return false; - if(get.color(event.card)!='black'&&!get.tag(event.card,'damage')) return false; + heiguangkai_skill: { + equipSkill: true, + trigger: { target: "useCardToTargeted" }, + forced: true, + audio: true, + filter: function (event, player) { + if (event.targets.length < 2) return false; + if (event.card.name != "sha") { + var type = get.type(event.card); + if (type != "trick") return false; + if (get.color(event.card) != "black" && !get.tag(event.card, "damage")) return false; } - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; return true; }, - content:function(){ + content: function () { trigger.excluded.add(player); }, - global:'heiguangkai_ai', + global: "heiguangkai_ai", }, - tongque_skill:{ - trigger:{player:'yingbian'}, - equipSkill:true, - forced:true, - filter:(event,player)=>get.is.yingbianConditional(event.card)&&player.getHistory('useCard',evt=>get.is.yingbianConditional(evt.card)).length<2, - content:()=>{ - trigger.forceYingbian=true; - } - }, - tianjitu_skill:{ - audio:true, - trigger:{player:'equipAfter'}, - forced:true, - equipSkill:true, - filter:(event,player)=>event.card.name=='tianjitu'&&player.hasCard(card=>card!=event.card,'he'), - content:()=>{ - player.chooseToDiscard(true,card=>card!=_status.event.getTrigger().card,'he'); + tongque_skill: { + trigger: { player: "yingbian" }, + equipSkill: true, + forced: true, + filter: (event, player) => + get.is.yingbianConditional(event.card) && + player.getHistory("useCard", (evt) => get.is.yingbianConditional(evt.card)).length < 2, + content: () => { + trigger.forceYingbian = true; }, - subSkill:{ - lose:{ - audio:'tianjitu_skill', - forced:true, - charlotte:true, - equipSkill:true, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + }, + tianjitu_skill: { + audio: true, + trigger: { player: "equipAfter" }, + forced: true, + equipSkill: true, + filter: (event, player) => + event.card.name == "tianjitu" && player.hasCard((card) => card != event.card, "he"), + content: () => { + player.chooseToDiscard(true, (card) => card != _status.event.getTrigger().card, "he"); + }, + subSkill: { + lose: { + audio: "tianjitu_skill", + forced: true, + charlotte: true, + equipSkill: true, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:(event,player)=>{ - if(player.countCards('h')>=5) return false; - var evt=event.getl(player); - return evt&&evt.es.some(card=>card.name=='tianjitu') + filter: (event, player) => { + if (player.countCards("h") >= 5) return false; + var evt = event.getl(player); + return evt && evt.es.some((card) => card.name == "tianjitu"); }, - content:function(){ + content: function () { player.drawTo(5); }, }, }, }, - taigongyinfu_skill:{ - equipSkill:true, - audio:true, - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + taigongyinfu_skill: { + equipSkill: true, + audio: true, + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('h','是否发动【太公阴符】重铸一张手牌?',lib.filter.cardRecastable).set('ai',function(card){ - return 5-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('taigongyinfu_skill'); + content: function () { + "step 0"; + player + .chooseCard("h", "是否发动【太公阴符】重铸一张手牌?", lib.filter.cardRecastable) + .set("ai", function (card) { + return 5 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("taigongyinfu_skill"); player.recast(result.cards); } }, }, - taigongyinfu_link:{ - audio:'taigongyinfu_skill', - trigger:{player:'phaseUseBegin'}, - equipSkill:true, + taigongyinfu_link: { + audio: "taigongyinfu_skill", + trigger: { player: "phaseUseBegin" }, + equipSkill: true, //filter:function(event,player){ // return game.hasPlayer(function(current){ // return !current.isLinked(); // }); //}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget( - //function(card,player,target){ - // return !target.isLinked(); - //}, - '是否发动【太公阴符】横置或重置一名角色?').set('ai',function(target){ - return get.effect(target,{name:'tiesuo'},_status.event.player,_status.event.player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('taigongyinfu_link',target); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + //function(card,player,target){ + // return !target.isLinked(); + //}, + "是否发动【太公阴符】横置或重置一名角色?" + ) + .set("ai", function (target) { + return get.effect( + target, + { name: "tiesuo" }, + _status.event.player, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("taigongyinfu_link", target); target.link(); } }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, }, - _yingbian:{ - trigger:{player:'yingbian'}, - forced:true, - popup:false, - ruleSkill:true, - forceLoad:true, - filter:(event,player)=>{ - if(event.card.yingbian) return false; - const temporaryYingbian=event.temporaryYingbian||[],card=event.card; - if(temporaryYingbian.includes('force')||get.cardtag(card,'yingbian_force')) return true; - const forceYingbian=event.forceYingbian||player.hasSkillTag('forceYingbian'); - for(const entry of lib.yingbian.condition.simple){ - const key=entry[0]; - if((temporaryYingbian.includes(key)||get.cardtag(card,`yingbian_${key}`))&&(forceYingbian||entry[1](event))) return true; + _yingbian: { + trigger: { player: "yingbian" }, + forced: true, + popup: false, + ruleSkill: true, + forceLoad: true, + filter: (event, player) => { + if (event.card.yingbian) return false; + const temporaryYingbian = event.temporaryYingbian || [], + card = event.card; + if (temporaryYingbian.includes("force") || get.cardtag(card, "yingbian_force")) + return true; + const forceYingbian = event.forceYingbian || player.hasSkillTag("forceYingbian"); + for (const entry of lib.yingbian.condition.simple) { + const key = entry[0]; + if ( + (temporaryYingbian.includes(key) || get.cardtag(card, `yingbian_${key}`)) && + (forceYingbian || entry[1](event)) + ) + return true; } - const complexYingbianConditions=get.complexYingbianConditions(); - return temporaryYingbian.some(value=>complexYingbianConditions.includes(value))||get.is.complexlyYingbianConditional(card); + const complexYingbianConditions = get.complexYingbianConditions(); + return ( + temporaryYingbian.some((value) => complexYingbianConditions.includes(value)) || + get.is.complexlyYingbianConditional(card) + ); }, - content:()=>{ - 'step 0' - event.card=trigger.card; - event.temporaryYingbian=trigger.temporaryYingbian||[]; - var yingbianConditionSatisfied=false; - lib.yingbian.condition.simple.forEach((value,key)=>{ - if(!event.temporaryYingbian.includes(key)&&!get.cardtag(event.card,`yingbian_${key}`)||!value(trigger)) return; - player.popup(`yingbian_${key}_tag`,lib.yingbian.condition.color.get(key)); - if(!yingbianConditionSatisfied) yingbianConditionSatisfied=true; + content: () => { + "step 0"; + event.card = trigger.card; + event.temporaryYingbian = trigger.temporaryYingbian || []; + var yingbianConditionSatisfied = false; + lib.yingbian.condition.simple.forEach((value, key) => { + if ( + (!event.temporaryYingbian.includes(key) && + !get.cardtag(event.card, `yingbian_${key}`)) || + !value(trigger) + ) + return; + player.popup(`yingbian_${key}_tag`, lib.yingbian.condition.color.get(key)); + if (!yingbianConditionSatisfied) yingbianConditionSatisfied = true; }); - if(event.temporaryYingbian.includes('force')||get.cardtag(event.card,'yingbian_force')||trigger.forceYingbian||player.hasSkillTag('forceYingbian')){ - player.popup('yingbian_force_tag',lib.yingbian.condition.color.get('force')); - if(!yingbianConditionSatisfied) yingbianConditionSatisfied=true; + if ( + event.temporaryYingbian.includes("force") || + get.cardtag(event.card, "yingbian_force") || + trigger.forceYingbian || + player.hasSkillTag("forceYingbian") + ) { + player.popup("yingbian_force_tag", lib.yingbian.condition.color.get("force")); + if (!yingbianConditionSatisfied) yingbianConditionSatisfied = true; } - if(yingbianConditionSatisfied){ - game.log(player,'触发了',event.card,'的应变条件'); + if (yingbianConditionSatisfied) { + game.log(player, "触发了", event.card, "的应变条件"); event.goto(4); - } - else if((event.num=0)>=(event.yingbianConditions=get.complexYingbianConditions()).length) event.finish(); - 'step 1' - var yingbianCondition=event.yingbianConditions[num]; - if(event.temporaryYingbian.includes(yingbianCondition)||get.cardtag(card,`yingbian_${yingbianCondition}`)) lib.yingbian.condition.complex.get(yingbianCondition)(trigger); + } else if ( + (event.num = 0) >= (event.yingbianConditions = get.complexYingbianConditions()).length + ) + event.finish(); + "step 1"; + var yingbianCondition = event.yingbianConditions[num]; + if ( + event.temporaryYingbian.includes(yingbianCondition) || + get.cardtag(card, `yingbian_${yingbianCondition}`) + ) + lib.yingbian.condition.complex.get(yingbianCondition)(trigger); else event.goto(3); - 'step 2' - if(result.bool) event.goto(4); - 'step 3' + "step 2"; + if (result.bool) event.goto(4); + "step 3"; event.num++; - if(event.num{ - if(!event.temporaryYingbian.includes(key)&&!get.cardtag(card,`yingbian_${key}`)) return; - game.yingbianEffect(trigger,value); - if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + "step 4"; + trigger.card.yingbian = true; + var yingbianEffectExecuted = false; + lib.yingbian.effect.forEach((value, key) => { + if (!event.temporaryYingbian.includes(key) && !get.cardtag(card, `yingbian_${key}`)) + return; + game.yingbianEffect(trigger, value); + if (!yingbianEffectExecuted) yingbianEffectExecuted = true; }); - if(!yingbianEffectExecuted){ - var defaultYingbianEffect=get.defaultYingbianEffect(card); - if(lib.yingbian.effect.has(defaultYingbianEffect)){ - game.yingbianEffect(trigger,lib.yingbian.effect.get(defaultYingbianEffect)); - if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + if (!yingbianEffectExecuted) { + var defaultYingbianEffect = get.defaultYingbianEffect(card); + if (lib.yingbian.effect.has(defaultYingbianEffect)) { + game.yingbianEffect(trigger, lib.yingbian.effect.get(defaultYingbianEffect)); + if (!yingbianEffectExecuted) yingbianEffectExecuted = true; } } - if(yingbianEffectExecuted) player.addTempSkill('yingbian_changeTarget'); - } + if (yingbianEffectExecuted) player.addTempSkill("yingbian_changeTarget"); + }, }, - yingbian_changeTarget:{ - trigger:{player:'useCard2'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - if(event.yingbian_removeTarget&&event.targets&&event.targets.length>1) return true; - if(!event.yingbian_addTarget) return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + yingbian_changeTarget: { + trigger: { player: "useCard2" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + if (event.yingbian_removeTarget && event.targets && event.targets.length > 1) return true; + if (!event.yingbian_addTarget) return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - if(trigger.yingbian_addTarget) player.chooseTarget('应变:是否为'+get.translation(trigger.card)+'增加一个目标?',function(card,player,target){ - var trigger=_status.event.getTrigger(); - var card=trigger.card; - return !trigger.targets.includes(target)&&lib.filter.targetEnabled2(card,player,target)&&lib.filter.targetInRange(card,player,target); - }).set('ai',function(target){ - var player=_status.event.player; - var card=_status.event.getTrigger().card; - return get.effect(target,card,player,player); - }); + content: function () { + "step 0"; + if (trigger.yingbian_addTarget) + player + .chooseTarget( + "应变:是否为" + get.translation(trigger.card) + "增加一个目标?", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + var card = trigger.card; + return ( + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var card = _status.event.getTrigger().card; + return get.effect(target, card, player, player); + }); else event.goto(2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'发动应变效果,令',target,'也成为了',trigger.card,'的目标'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "发动应变效果,令", target, "也成为了", trigger.card, "的目标"); trigger.targets.add(target); } - 'step 2' - if(trigger.yingbian_removeTarget&&trigger.targets.length>1) player.chooseTarget('应变:是否为'+get.translation(trigger.card)+'减少一个目标?',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return trigger.targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - var card=_status.event.getTrigger().card; - return -get.effect(target,card,player,player); - }); + "step 2"; + if (trigger.yingbian_removeTarget && trigger.targets.length > 1) + player + .chooseTarget( + "应变:是否为" + get.translation(trigger.card) + "减少一个目标?", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return trigger.targets.includes(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var card = _status.event.getTrigger().card; + return -get.effect(target, card, player, player); + }); else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'发动应变效果,将',target,'从',trigger.card,'的目标中移除了'); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "发动应变效果,将", target, "从", trigger.card, "的目标中移除了"); trigger.targets.remove(target); } }, }, - heiguangkai_ai:{ - ai:{ - effect:{ - player:function(card,player,target){ - if(typeof card!=='object'||!target||get.name(card)!=='sha'&&(get.type(card)!=='trick'||get.color(card)!=='black'&&!get.tag(card,'damage'))) return; - if(!target.hasSkill('heiguangkai_skill')||target.hasSkillTag('unequip2')||player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:target, - card:card, - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:target, - card:card, - })) return; - let targets=[],evt=_status.event.getParent('useCard'); + heiguangkai_ai: { + ai: { + effect: { + player: function (card, player, target) { + if ( + typeof card !== "object" || + !target || + (get.name(card) !== "sha" && + (get.type(card) !== "trick" || + (get.color(card) !== "black" && !get.tag(card, "damage")))) + ) + return; + if ( + !target.hasSkill("heiguangkai_skill") || + target.hasSkillTag("unequip2") || + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) + return; + let targets = [], + evt = _status.event.getParent("useCard"); targets.addArray(ui.selected.targets); - if(evt&&evt.card==card) targets.addArray(evt.targets); - if(targets.length){ - if(targets.length>1||!targets.includes(target)) return 'zeroplayertarget'; + if (evt && evt.card == card) targets.addArray(evt.targets); + if (targets.length) { + if (targets.length > 1 || !targets.includes(target)) + return "zeroplayertarget"; return; } - let info=get.info(card); - if(!info||info.notarget||!info.filterTarget) return; - let range,select=get.copy(info.selectTarget),filter; - if(select===undefined) range=[1,1]; - else if(typeof select==='number') range=[select,select]; - else if(get.itemtype(select)==='select') range=select; - else if(typeof select==='function') range=select(card,player); - if(info.singleCard) range=[1,1]; - game.checkMod(card,player,range,'selectTarget',player); - if(range[1]<-1) range=[1, 1]; - else if(range[0]<0){ - if(info.filterTarget===true) filter=game.players.length; - else filter=game.countPlayer(current=>{ - return info.filterTarget(card,player,current); - }); - range=[filter,filter]; + let info = get.info(card); + if (!info || info.notarget || !info.filterTarget) return; + let range, + select = get.copy(info.selectTarget), + filter; + if (select === undefined) range = [1, 1]; + else if (typeof select === "number") range = [select, select]; + else if (get.itemtype(select) === "select") range = select; + else if (typeof select === "function") range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); + if (range[1] < -1) range = [1, 1]; + else if (range[0] < 0) { + if (info.filterTarget === true) filter = game.players.length; + else + filter = game.countPlayer((current) => { + return info.filterTarget(card, player, current); + }); + range = [filter, filter]; } - if(!range) return; - if(range[0]>1&&range[1]>1) return 'zeroplayertarget'; - return [1,0,0.7,0]; + if (!range) return; + if (range[0] > 1 && range[1] > 1) return "zeroplayertarget"; + return [1, 0, 0.7, 0]; }, }, }, }, }, - translate:{ - suijiyingbian:'随机应变', - suijiyingbian_info:'此牌的牌名视为你本回合内使用或打出的上一张基本牌或普通锦囊牌的牌名。', - zhujinqiyuan:'逐近弃远', - zhujinqiyuan_info:'出牌阶段,对一名有牌的其他角色使用。若你至其距离的大于1,你弃置其区域内的一张牌。若你至其的距离等于1,你获得其区域内的一张牌。', - dongzhuxianji:'洞烛先机', - dongzhuxianji_info:'出牌阶段,对包含你在内的一名角色使用。目标角色卜算2,然后摸两张牌。', - chuqibuyi:'出其不意', - chuqibuyi_info:'出牌阶段,对一名有手牌的其他角色使用。你展示其一张手牌,若此牌与【出其不意】的花色不同,则你对其造成1点伤害。', - wuxinghelingshan:'五行鹤翎扇', - wuxinghelingshan_skill:'五行鹤翎扇', - wuxinghelingshan_info:'当你声明使用不为神属性的属性【杀】后,你可将此【杀】的属性改为不为神属性的其他属性。', - wutiesuolian:'乌铁锁链', - wutiesuolian_skill:'乌铁锁链', - wutiesuolian_info:'锁定技,当你使用【杀】指定目标后,若其未横置,则其横置。', - heiguangkai:'黑光铠', - heiguangkai_skill:'黑光铠', - heiguangkai_info:'锁定技,当你成为【杀】或伤害类锦囊牌或黑色普通锦囊牌的目标后,若此牌的目标数大于1,则你令此牌对你无效。', - tongque:'铜雀', - tongque_skill:'铜雀', - tongque_info:'锁定技,你于一回合内使用的第一张带有“应变”效果的牌无视条件直接生效。', - tianjitu:'天机图', - tianjitu_skill:'天机图', - tianjitu_info:'锁定技,当此牌进入你的装备区时,你弃置一张不为此【天机图】的牌。当此牌离开你的装备区时,你将手牌摸至五张。', - taigongyinfu:'太公阴符', - taigongyinfu_info:'出牌阶段开始时,你可以横置或重置一名角色。出牌阶段结束时,你可以重铸一张手牌。', - taigongyinfu_skill:'太公阴符', - taigongyinfu_link:'太公阴符', - yingbian_zhuzhan_tag:'助战', - yingbian_kongchao_tag:'空巢', - yingbian_fujia_tag:'富甲', - yingbian_canqu_tag:'残躯', - yingbian_force_tag:'应变', - _yingbian:'应变', - yingbian_changeTarget:'应变', - yingbian_add_tag:'(目标+)', - yingbian_remove_tag:'(目标-)', - yingbian_damage_tag:'(伤害+)', - yingbian_draw_tag:'(摸牌)', - yingbian_gain_tag:'(反甲)', - yingbian_hit_tag:'(强命)', - yingbian_all_tag:'(双项)' + translate: { + suijiyingbian: "随机应变", + suijiyingbian_info: "此牌的牌名视为你本回合内使用或打出的上一张基本牌或普通锦囊牌的牌名。", + zhujinqiyuan: "逐近弃远", + zhujinqiyuan_info: + "出牌阶段,对一名有牌的其他角色使用。若你至其距离的大于1,你弃置其区域内的一张牌。若你至其的距离等于1,你获得其区域内的一张牌。", + dongzhuxianji: "洞烛先机", + dongzhuxianji_info: "出牌阶段,对包含你在内的一名角色使用。目标角色卜算2,然后摸两张牌。", + chuqibuyi: "出其不意", + chuqibuyi_info: + "出牌阶段,对一名有手牌的其他角色使用。你展示其一张手牌,若此牌与【出其不意】的花色不同,则你对其造成1点伤害。", + wuxinghelingshan: "五行鹤翎扇", + wuxinghelingshan_skill: "五行鹤翎扇", + wuxinghelingshan_info: + "当你声明使用不为神属性的属性【杀】后,你可将此【杀】的属性改为不为神属性的其他属性。", + wutiesuolian: "乌铁锁链", + wutiesuolian_skill: "乌铁锁链", + wutiesuolian_info: "锁定技,当你使用【杀】指定目标后,若其未横置,则其横置。", + heiguangkai: "黑光铠", + heiguangkai_skill: "黑光铠", + heiguangkai_info: + "锁定技,当你成为【杀】或伤害类锦囊牌或黑色普通锦囊牌的目标后,若此牌的目标数大于1,则你令此牌对你无效。", + tongque: "铜雀", + tongque_skill: "铜雀", + tongque_info: "锁定技,你于一回合内使用的第一张带有“应变”效果的牌无视条件直接生效。", + tianjitu: "天机图", + tianjitu_skill: "天机图", + tianjitu_info: + "锁定技,当此牌进入你的装备区时,你弃置一张不为此【天机图】的牌。当此牌离开你的装备区时,你将手牌摸至五张。", + taigongyinfu: "太公阴符", + taigongyinfu_info: + "出牌阶段开始时,你可以横置或重置一名角色。出牌阶段结束时,你可以重铸一张手牌。", + taigongyinfu_skill: "太公阴符", + taigongyinfu_link: "太公阴符", + yingbian_zhuzhan_tag: "助战", + yingbian_kongchao_tag: "空巢", + yingbian_fujia_tag: "富甲", + yingbian_canqu_tag: "残躯", + yingbian_force_tag: "应变", + _yingbian: "应变", + yingbian_changeTarget: "应变", + yingbian_add_tag: "(目标+)", + yingbian_remove_tag: "(目标-)", + yingbian_damage_tag: "(伤害+)", + yingbian_draw_tag: "(摸牌)", + yingbian_gain_tag: "(反甲)", + yingbian_hit_tag: "(强命)", + yingbian_all_tag: "(双项)", }, - list:[ - ['spade',1,'juedou'], - ['spade',1,'taigongyinfu'], - ['spade',1,'guding'], - ['spade',2,'cixiong'], - ['spade',2,'bagua'], - ['spade',2,'tengjia'], - ['spade',2,'suijiyingbian'], - ['spade',3,'jiu'], - ['spade',3,'zhujinqiyuan'], - ['spade',3,'shuiyanqijunx',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',4,'sha','thunder'], - ['spade',4,'guohe'], - ['spade',4,'shuiyanqijunx',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',5,'sha','thunder'], - ['spade',5,'qinglong'], - ['spade',5,'jueying'], - ['spade',6,'sha','thunder'], - ['spade',6,'lebu'], - ['spade',6,'qinggang'], - ['spade',7,'sha','ice'], - ['spade',7,'sha','ice'], - ['spade',7,'nanman',null,['yingbian_fujia','yingbian_remove']], - ['spade',8,'sha','ice'], - ['spade',8,'sha','ice'], - ['spade',8,'sha','ice'], - ['spade',9,'sha',null,['yingbian_canqu','yingbian_add']], - ['spade',9,'sha',null,['yingbian_canqu','yingbian_add']], - ['spade',9,'jiu'], - ['spade',10,'sha'], - ['spade',10,'sha',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',10,'bingliang'], - ['spade',11,'wuxie'], - ['spade',11,'shunshou'], - ['spade',11,'tiesuo'], - ['spade',12,'zhujinqiyuan',null,['yingbian_fujia','yingbian_hit']], - ['spade',12,'tiesuo'], - ['spade',12,'zhangba'], - ['spade',13,'wuxie',null,['yingbian_kongchao','yingbian_draw']], - ['spade',13,'nanman',null,['yingbian_fujia','yingbian_remove']], - ['spade',13,'dawan'], + list: [ + ["spade", 1, "juedou"], + ["spade", 1, "taigongyinfu"], + ["spade", 1, "guding"], + ["spade", 2, "cixiong"], + ["spade", 2, "bagua"], + ["spade", 2, "tengjia"], + ["spade", 2, "suijiyingbian"], + ["spade", 3, "jiu"], + ["spade", 3, "zhujinqiyuan"], + ["spade", 3, "shuiyanqijunx", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 4, "sha", "thunder"], + ["spade", 4, "guohe"], + ["spade", 4, "shuiyanqijunx", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 5, "sha", "thunder"], + ["spade", 5, "qinglong"], + ["spade", 5, "jueying"], + ["spade", 6, "sha", "thunder"], + ["spade", 6, "lebu"], + ["spade", 6, "qinggang"], + ["spade", 7, "sha", "ice"], + ["spade", 7, "sha", "ice"], + ["spade", 7, "nanman", null, ["yingbian_fujia", "yingbian_remove"]], + ["spade", 8, "sha", "ice"], + ["spade", 8, "sha", "ice"], + ["spade", 8, "sha", "ice"], + ["spade", 9, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["spade", 9, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["spade", 9, "jiu"], + ["spade", 10, "sha"], + ["spade", 10, "sha", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 10, "bingliang"], + ["spade", 11, "wuxie"], + ["spade", 11, "shunshou"], + ["spade", 11, "tiesuo"], + ["spade", 12, "zhujinqiyuan", null, ["yingbian_fujia", "yingbian_hit"]], + ["spade", 12, "tiesuo"], + ["spade", 12, "zhangba"], + ["spade", 13, "wuxie", null, ["yingbian_kongchao", "yingbian_draw"]], + ["spade", 13, "nanman", null, ["yingbian_fujia", "yingbian_remove"]], + ["spade", 13, "dawan"], - ['heart',1,'taoyuan',null,['yingbian_fujia','yingbian_remove']], - ['heart',1,'wanjian',null,['yingbian_fujia','yingbian_remove']], - ['heart',1,'wuxie'], - ['heart',2,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['heart',2,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['heart',2,'guohe',null,['yingbian_zhuzhan','yingbian_add']], - ['heart',3,'wugu'], - ['heart',3,'tao'], - ['heart',3,'chuqibuyi'], - ['heart',4,'sha','fire'], - ['heart',4,'tao'], - ['heart',4,'wugu'], - ['heart',5,'chitu'], - ['heart',5,'tao'], - ['heart',5,'qilin'], - ['heart',6,'tao'], - ['heart',6,'tao'], - ['heart',6,'lebu'], - ['heart',7,'sha','fire'], - ['heart',7,'tao'], - ['heart',7,'dongzhuxianji'], - ['heart',8,'tao'], - ['heart',8,'shan'], - ['heart',8,'dongzhuxianji'], - ['heart',9,'tao'], - ['heart',9,'shan'], - ['heart',9,'dongzhuxianji'], - ['heart',10,'sha','fire',['yingbian_kongchao','yingbian_damage']], - ['heart',10,'sha'], - ['heart',10,'sha'], - ['heart',11,'sha'], - ['heart',11,'shan'], - ['heart',11,'dongzhuxianji'], - ['heart',12,'tao'], - ['heart',12,'shan'], - ['heart',12,'guohe'], - ['heart',12,'shandian'], - ['heart',13,'wuxie',null,['yingbian_kongchao','yingbian_gain']], - ['heart',13,'shan'], - ['heart',13,'zhuahuang'], + ["heart", 1, "taoyuan", null, ["yingbian_fujia", "yingbian_remove"]], + ["heart", 1, "wanjian", null, ["yingbian_fujia", "yingbian_remove"]], + ["heart", 1, "wuxie"], + ["heart", 2, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["heart", 2, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["heart", 2, "guohe", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["heart", 3, "wugu"], + ["heart", 3, "tao"], + ["heart", 3, "chuqibuyi"], + ["heart", 4, "sha", "fire"], + ["heart", 4, "tao"], + ["heart", 4, "wugu"], + ["heart", 5, "chitu"], + ["heart", 5, "tao"], + ["heart", 5, "qilin"], + ["heart", 6, "tao"], + ["heart", 6, "tao"], + ["heart", 6, "lebu"], + ["heart", 7, "sha", "fire"], + ["heart", 7, "tao"], + ["heart", 7, "dongzhuxianji"], + ["heart", 8, "tao"], + ["heart", 8, "shan"], + ["heart", 8, "dongzhuxianji"], + ["heart", 9, "tao"], + ["heart", 9, "shan"], + ["heart", 9, "dongzhuxianji"], + ["heart", 10, "sha", "fire", ["yingbian_kongchao", "yingbian_damage"]], + ["heart", 10, "sha"], + ["heart", 10, "sha"], + ["heart", 11, "sha"], + ["heart", 11, "shan"], + ["heart", 11, "dongzhuxianji"], + ["heart", 12, "tao"], + ["heart", 12, "shan"], + ["heart", 12, "guohe"], + ["heart", 12, "shandian"], + ["heart", 13, "wuxie", null, ["yingbian_kongchao", "yingbian_gain"]], + ["heart", 13, "shan"], + ["heart", 13, "zhuahuang"], - ['club',1,'juedou'], - ['club',1,'zhuge'], - ['club',1,'huxinjing'], - ['club',2,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',2,'heiguangkai'], - ['club',2,'tengjia'], - ['club',2,'renwang'], - ['club',3,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',3,'jiu'], - ['club',3,'zhujinqiyuan',null,['yingbian_zhuzhan','yingbian_add']], - ['club',4,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',4,'bingliang'], - ['club',4,'zhujinqiyuan',null,['yingbian_zhuzhan','yingbian_add']], - ['club',5,'sha'], - ['club',5,'sha','thunder'], - ['club',5,'dilu'], - ['club',6,'sha'], - ['club',6,'sha','thunder'], - ['club',6,'lebu'], - ['club',7,'sha'], - ['club',7,'sha','thunder'], - ['club',7,'nanman',null,['yingbian_fujia','yingbian_remove']], - ['club',8,'sha'], - ['club',8,'sha','thunder'], - ['club',8,'sha'], - ['club',9,'sha','thunder'], - ['club',9,'sha','thunder'], - ['club',9,'jiu'], - ['club',10,'sha','thunder'], - ['club',10,'sha','thunder'], - ['club',10,'tiesuo'], - ['club',11,'sha'], - ['club',11,'sha',null,['yingbian_canqu','yingbian_add']], - ['club',11,'tiesuo'], - ['club',12,'wuxie'], - ['club',12,'tianjitu'], - ['club',12,'tiesuo'], - ['club',13,'wuxie',null,['yingbian_canqu','yingbian_draw']], - ['club',13,'tongque'], - ['club',13,'tiesuo'], + ["club", 1, "juedou"], + ["club", 1, "zhuge"], + ["club", 1, "huxinjing"], + ["club", 2, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 2, "heiguangkai"], + ["club", 2, "tengjia"], + ["club", 2, "renwang"], + ["club", 3, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 3, "jiu"], + ["club", 3, "zhujinqiyuan", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["club", 4, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 4, "bingliang"], + ["club", 4, "zhujinqiyuan", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["club", 5, "sha"], + ["club", 5, "sha", "thunder"], + ["club", 5, "dilu"], + ["club", 6, "sha"], + ["club", 6, "sha", "thunder"], + ["club", 6, "lebu"], + ["club", 7, "sha"], + ["club", 7, "sha", "thunder"], + ["club", 7, "nanman", null, ["yingbian_fujia", "yingbian_remove"]], + ["club", 8, "sha"], + ["club", 8, "sha", "thunder"], + ["club", 8, "sha"], + ["club", 9, "sha", "thunder"], + ["club", 9, "sha", "thunder"], + ["club", 9, "jiu"], + ["club", 10, "sha", "thunder"], + ["club", 10, "sha", "thunder"], + ["club", 10, "tiesuo"], + ["club", 11, "sha"], + ["club", 11, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["club", 11, "tiesuo"], + ["club", 12, "wuxie"], + ["club", 12, "tianjitu"], + ["club", 12, "tiesuo"], + ["club", 13, "wuxie", null, ["yingbian_canqu", "yingbian_draw"]], + ["club", 13, "tongque"], + ["club", 13, "tiesuo"], - ['diamond',1,'juedou'], - ['diamond',1,'zhuge'], - ['diamond',1,'wuxinghelingshan'], - ['diamond',2,'tao'], - ['diamond',2,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',2,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',3,'tao'], - ['diamond',3,'shan'], - ['diamond',3,'shunshou'], - ['diamond',4,'sha','fire',['yingbian_kongchao','yingbian_damage']], - ['diamond',4,'shan',null,['yingbian_canqu','yingbian_gain']], - ['diamond',4,'shunshou'], - ['diamond',5,'sha','fire'], - ['diamond',5,'shan'], - ['diamond',5,'guanshi'], - ['diamond',6,'sha'], - ['diamond',6,'shan'], - ['diamond',6,'shan'], - ['diamond',7,'sha'], - ['diamond',7,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'sha',null,['yingbian_canqu','yingbian_hit']], - ['diamond',8,'shan'], - ['diamond',8,'shan'], - ['diamond',9,'sha'], - ['diamond',9,'shan'], - ['diamond',9,'jiu'], - ['diamond',10,'sha','fire'], - ['diamond',10,'shan'], - ['diamond',10,'shan'], - ['diamond',11,'shan'], - ['diamond',11,'shan'], - ['diamond',11,'shan'], - ['diamond',12,'tao'], - ['diamond',12,'chuqibuyi'], - ['diamond',12,'wutiesuolian'], - ['diamond',12,'wuxie'], - ['diamond',13,'sha'], - ['diamond',13,'zixin'], - ['diamond',13,'hualiu'], + ["diamond", 1, "juedou"], + ["diamond", 1, "zhuge"], + ["diamond", 1, "wuxinghelingshan"], + ["diamond", 2, "tao"], + ["diamond", 2, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 2, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 3, "tao"], + ["diamond", 3, "shan"], + ["diamond", 3, "shunshou"], + ["diamond", 4, "sha", "fire", ["yingbian_kongchao", "yingbian_damage"]], + ["diamond", 4, "shan", null, ["yingbian_canqu", "yingbian_gain"]], + ["diamond", 4, "shunshou"], + ["diamond", 5, "sha", "fire"], + ["diamond", 5, "shan"], + ["diamond", 5, "guanshi"], + ["diamond", 6, "sha"], + ["diamond", 6, "shan"], + ["diamond", 6, "shan"], + ["diamond", 7, "sha"], + ["diamond", 7, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "sha", null, ["yingbian_canqu", "yingbian_hit"]], + ["diamond", 8, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "sha"], + ["diamond", 9, "shan"], + ["diamond", 9, "jiu"], + ["diamond", 10, "sha", "fire"], + ["diamond", 10, "shan"], + ["diamond", 10, "shan"], + ["diamond", 11, "shan"], + ["diamond", 11, "shan"], + ["diamond", 11, "shan"], + ["diamond", 12, "tao"], + ["diamond", 12, "chuqibuyi"], + ["diamond", 12, "wutiesuolian"], + ["diamond", 12, "wuxie"], + ["diamond", 13, "sha"], + ["diamond", 13, "zixin"], + ["diamond", 13, "hualiu"], - ['diamond',5,'muniu'], + ["diamond", 5, "muniu"], ], - help:{ - '应变篇':('
              应变机制
                '+ - '
              • 当一名角色声明使用右下角标注了应变条件的卡牌后,若其满足应变条件,则其触发此牌的“应变”效果。
              • 长按或鼠标右键点击卡牌,即可查看此牌所拥有的应变效果。'+ - '
              • 应变条件
                • 空巢:该角色声明使用此牌后,其手牌数为0。
                • 富甲:该角色声明使用此牌后,其手牌数为全场最多或之一。
                • 残躯:该角色声明使用此牌后,其体力值为1。
                • 助战:该角色声明使用此牌后,其发起“助战”。其他角色可弃置一张与此牌类型相同的卡牌,响应此“助战”。若有角色响应,则视为其应变成功。
              '), + help: { + 应变篇: + '
              应变机制
                ' + + "
              • 当一名角色声明使用右下角标注了应变条件的卡牌后,若其满足应变条件,则其触发此牌的“应变”效果。
              • 长按或鼠标右键点击卡牌,即可查看此牌所拥有的应变效果。" + + '
              • 应变条件
                • 空巢:该角色声明使用此牌后,其手牌数为0。
                • 富甲:该角色声明使用此牌后,其手牌数为全场最多或之一。
                • 残躯:该角色声明使用此牌后,其体力值为1。
                • 助战:该角色声明使用此牌后,其发起“助战”。其他角色可弃置一张与此牌类型相同的卡牌,响应此“助战”。若有角色响应,则视为其应变成功。
              ', }, - } + }; }); diff --git a/card/yongjian.js b/card/yongjian.js index c9c5dc9dd..bdda92dc4 100644 --- a/card/yongjian.js +++ b/card/yongjian.js @@ -1,798 +1,925 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'yongjian', - connect:true, - card:{ - du:{ - type:'basic', - fullskin:true, - global:['g_du','g_du_give'], - content:function(){}, - ai:{ - value:-5, - useful:6, - result:{ - player:function(player,target){ - if(player.hasSkillTag('usedu')) return 5; + name: "yongjian", + connect: true, + card: { + du: { + type: "basic", + fullskin: true, + global: ["g_du", "g_du_give"], + content: function () {}, + ai: { + value: -5, + useful: 6, + result: { + player: function (player, target) { + if (player.hasSkillTag("usedu")) return 5; return -1; - } + }, }, - order:7.5 + order: 7.5, }, }, - guaguliaodu:{ - type:'trick', - fullskin:true, - enable:true, - filterTarget:function(card,player,target){ + guaguliaodu: { + type: "trick", + fullskin: true, + enable: true, + filterTarget: function (card, player, target) { return target.isDamaged(); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.recover(); - 'step 1' - if(target.hasCard(function(card){ - return _status.connectMode||get.name(card,target)=='du'; - },'h')) target.chooseToDiscard('h',{name:'du'},'是否弃置一张【毒】?(不失去体力)').set('ai',()=>1); + "step 1"; + if ( + target.hasCard(function (card) { + return _status.connectMode || get.name(card, target) == "du"; + }, "h") + ) + target + .chooseToDiscard("h", { name: "du" }, "是否弃置一张【毒】?(不失去体力)") + .set("ai", () => 1); }, - ai:{ - order:2, - tag:{ - recover:1, + ai: { + order: 2, + tag: { + recover: 1, + }, + result: { + target: 1.5, }, - result:{ - target:1.5, - } }, }, - chenghuodajie:{ - type:'trick', - fullskin:true, - enable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + chenghuodajie: { + type: "trick", + fullskin: true, + enable: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - if(typeof event.baseDamage!='number') event.baseDamage=1; - if(typeof event.extraDamage!='number') event.extraDamage=0; - if(!target.countCards('h')||!player.isIn()) event.finish(); - else player.choosePlayerCard(target,'h',true); - 'step 1' - if(result.bool){ - event.show_card=result.cards[0]; - var str=get.translation(player); + content: function () { + "step 0"; + if (typeof event.baseDamage != "number") event.baseDamage = 1; + if (typeof event.extraDamage != "number") event.extraDamage = 0; + if (!target.countCards("h") || !player.isIn()) event.finish(); + else player.choosePlayerCard(target, "h", true); + "step 1"; + if (result.bool) { + event.show_card = result.cards[0]; + var str = get.translation(player); player.showCards(event.show_card); - target.chooseControl().set('choiceList',[ - `令${str}获得${get.translation(event.show_card)}`, - `受到${str}造成的${event.baseDamage+event.extraDamage}点伤害`, - ]).set('ai',function(){ - var evt=_status.event.getParent(),player=evt.target,source=evt.player,card=evt.show_card; - if(get.damageEffect(player,source,player)>0) return 1; - if(get.attitude(player,source)*get.value(card,source)>=0) return 0; - if(card.name=='tao') return 1; - return get.value(card,player)>(6+(Math.max(player.maxHp,3)-player.hp)*1.5)?1:0; - }); - } - else event.finish(); - 'step 2' - if(result.index==0) target.give(event.show_card,player); + target + .chooseControl() + .set("choiceList", [ + `令${str}获得${get.translation(event.show_card)}`, + `受到${str}造成的${event.baseDamage + event.extraDamage}点伤害`, + ]) + .set("ai", function () { + var evt = _status.event.getParent(), + player = evt.target, + source = evt.player, + card = evt.show_card; + if (get.damageEffect(player, source, player) > 0) return 1; + if (get.attitude(player, source) * get.value(card, source) >= 0) return 0; + if (card.name == "tao") return 1; + return get.value(card, player) > + 6 + (Math.max(player.maxHp, 3) - player.hp) * 1.5 + ? 1 + : 0; + }); + } else event.finish(); + "step 2"; + if (result.index == 0) target.give(event.show_card, player); else target.damage(); }, - ai:{ - order:6, - tag:{ - damage:1, - loseCard:1, - gain:1, + ai: { + order: 6, + tag: { + damage: 1, + loseCard: 1, + gain: 1, }, - result:{ - player:0.1, - target:-1.2, + result: { + player: 0.1, + target: -1.2, }, }, }, - tuixinzhifu:{ - type:'trick', - fullskin:true, - enable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'hej')>0; + tuixinzhifu: { + type: "trick", + fullskin: true, + enable: true, + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "hej") > 0; }, - range:{global:1}, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'hej',true,[1,2]); - 'step 1' - if(result.bool&&target.isIn()){ - var num=result.cards.length,hs=player.getCards('h'); - if(!hs.length) event.finish(); - else if(hs.length0&&get.attitude(viewer,player)>0){ + wuxie: function (target, card, player, viewer) { + if (get.attitude(player, target) > 0 && get.attitude(viewer, player) > 0) { return 0; } }, - result:{ - target:function(player,target){ - if(get.attitude(player,target)<=0) return ((target.countCards('he',function(card){ - return get.value(card,target)>0&&card!=target.getEquip('jinhe'); - })>0)?-0.3:0.3)*Math.sqrt(player.countCards('h')); - return ((target.countCards('ej',function(card){ - if(get.position(card)=='e') return get.value(card,target)<=0; - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; - })>0)?1.5:-0.3)*Math.sqrt(player.countCards('h')); + result: { + target: function (player, target) { + if (get.attitude(player, target) <= 0) + return ( + (target.countCards("he", function (card) { + return ( + get.value(card, target) > 0 && card != target.getEquip("jinhe") + ); + }) > 0 + ? -0.3 + : 0.3) * Math.sqrt(player.countCards("h")) + ); + return ( + (target.countCards("ej", function (card) { + if (get.position(card) == "e") return get.value(card, target) <= 0; + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) > 0 + ? 1.5 + : -0.3) * Math.sqrt(player.countCards("h")) + ); }, }, }, }, - yitianjian:{ - type:'equip', - subtype:'equip1', - fullskin:true, - distance:{attackFrom:-1}, - skills:['yitianjian'], - ai:{ - equipValue:1.5, - basic:{ - equipValue:1.5, + yitianjian: { + type: "equip", + subtype: "equip1", + fullskin: true, + distance: { attackFrom: -1 }, + skills: ["yitianjian"], + ai: { + equipValue: 1.5, + basic: { + equipValue: 1.5, }, - } + }, }, - qixingbaodao:{ - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - fullskin:true, - global:'qixingbaodao', - ai:{ - order:9, - value:function(card,player){ - if(player.getEquips(1).includes(card)) return 0.4; + qixingbaodao: { + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + fullskin: true, + global: "qixingbaodao", + ai: { + order: 9, + value: function (card, player) { + if (player.getEquips(1).includes(card)) return 0.4; return 4; }, - equipValue:function(card,player){ - if(player.getCards('e').includes(card)) return 0.4; - return -get.value(player.getCards('e')); + equipValue: function (card, player) { + if (player.getCards("e").includes(card)) return 0.4; + return -get.value(player.getCards("e")); }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target){ - var cards=target.getCards('e'),js=target.getCards('j'); - var val=get.value(cards,target); - for(var card of js) val-=get.effect(target,card.viewAs?{name:card.viewAs}:card,target,player); + result: { + keepAI: true, + target: function (player, target) { + var cards = target.getCards("e"), + js = target.getCards("j"); + var val = get.value(cards, target); + for (var card of js) + val -= get.effect( + target, + card.viewAs ? { name: card.viewAs } : card, + target, + player + ); return -val; }, }, }, }, - duanjian:{ - type:'equip', - subtype:'equip1', - fullskin:true, - distance:{attackFrom:1}, - selectTarget:[-1,-2], - ai:{ - order:9, - equipValue:function(card,player){ - if(get.position(card)=='e') return -2; + duanjian: { + type: "equip", + subtype: "equip1", + fullskin: true, + distance: { attackFrom: 1 }, + selectTarget: [-1, -2], + ai: { + order: 9, + equipValue: function (card, player) { + if (get.position(card) == "e") return -2; return 2; }, - value:function(card,player){ - if(player.getEquips(1).includes(card)) return -3; + value: function (card, player) { + if (player.getEquips(1).includes(card)) return -3; return 3; }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target){ - var val=2.5; - var val2=0; - var card=target.getEquip(1); - if(card){ - val2=get.value(card,target); - if(val2<0) return 0; + result: { + keepAI: true, + target: function (player, target) { + var val = 2.5; + var val2 = 0; + var card = target.getEquip(1); + if (card) { + val2 = get.value(card, target); + if (val2 < 0) return 0; } - return -val-val2; + return -val - val2; }, }, }, }, - serafuku:{ - type:'equip', - subtype:'equip2', - fullskin:true, - skills:['serafuku'], - selectTarget:[-1,-2], - ai:{ - order:9, - equipValue:function(card,player){ - if(get.position(card)=='e'){ - if(player.hasSex('male')) return -7; + serafuku: { + type: "equip", + subtype: "equip2", + fullskin: true, + skills: ["serafuku"], + selectTarget: [-1, -2], + ai: { + order: 9, + equipValue: function (card, player) { + if (get.position(card) == "e") { + if (player.hasSex("male")) return -7; return 0; } return 2; }, - value:function(card,player){ - if(player.getEquips(2).includes(card)){ - if(player.hasSex('male')) return -8; + value: function (card, player) { + if (player.getEquips(2).includes(card)) { + if (player.hasSex("male")) return -8; return 0; } return 3; }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target){ - var val=(target.hasSex('male')?2.5:0); - var val2=0; - var card=target.getEquip(1); - if(card){ - val2=get.value(card,target); - if(val2<0) return 0; + result: { + keepAI: true, + target: function (player, target) { + var val = target.hasSex("male") ? 2.5 : 0; + var val2 = 0; + var card = target.getEquip(1); + if (card) { + val2 = get.value(card, target); + if (val2 < 0) return 0; } - return -val-val2; + return -val - val2; }, }, }, }, - yinfengyi:{ - type:'equip', - subtype:'equip2', - fullskin:true, - skills:['yinfengyi'], - selectTarget:[-1,-2], - ai:{ - order:9, - equipValue:function(card,player){ - if(get.position(card)=='e') return -8; + yinfengyi: { + type: "equip", + subtype: "equip2", + fullskin: true, + skills: ["yinfengyi"], + selectTarget: [-1, -2], + ai: { + order: 9, + equipValue: function (card, player) { + if (get.position(card) == "e") return -8; return 1; }, - value:function(card,player){ - if(player.getEquips(2).includes(card)) return -10; + value: function (card, player) { + if (player.getEquips(2).includes(card)) return -10; return 2.5; }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target){ - var val=2; - var val2=0; - var card=target.getEquip(2); - if(card){ - val2=get.value(card,target); - if(val2<0) return 0; + result: { + keepAI: true, + target: function (player, target) { + var val = 2; + var val2 = 0; + var card = target.getEquip(2); + if (card) { + val2 = get.value(card, target); + if (val2 < 0) return 0; } - return -val-val2; + return -val - val2; }, }, }, }, - yonglv:{ - type:'equip', - subtype:'equip4', - fullskin:true, - selectTarget:[-1,-2], - distance:{ - globalFrom:-1, - globalTo:-Infinity, + yonglv: { + type: "equip", + subtype: "equip4", + fullskin: true, + selectTarget: [-1, -2], + distance: { + globalFrom: -1, + globalTo: -Infinity, }, - ai:{ - order:9, - equipValue:0, - value:function(card,player){ - if(player.getEquips(2).includes(card)) return 0; + ai: { + order: 9, + equipValue: 0, + value: function (card, player) { + if (player.getEquips(2).includes(card)) return 0; return 0.5; }, - basic:{ - equipValue:0, + basic: { + equipValue: 0, }, }, }, - zhanxiang:{ - type:'equip', - subtype:'equip3', - fullskin:true, - distance:{globalTo:1}, - skills:['zhanxiang'], - ai:{ - equipValue:3.5, - basic:{ - equipValue:3.5, + zhanxiang: { + type: "equip", + subtype: "equip3", + fullskin: true, + distance: { globalTo: 1 }, + skills: ["zhanxiang"], + ai: { + equipValue: 3.5, + basic: { + equipValue: 3.5, }, - } + }, }, - xinge:{ - type:'equip', - subtype:'equip5', - fullskin:true, - skills:['xinge'], - ai:{ - equipValue:2, - basic:{ - equipValue:2, + xinge: { + type: "equip", + subtype: "equip5", + fullskin: true, + skills: ["xinge"], + ai: { + equipValue: 2, + basic: { + equipValue: 2, }, - } + }, }, }, - skill:{ - yitianjian:{ - audio:true, - trigger:{source:'damageSource'}, - direct:true, - equipSkill:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent().name=='sha'&&player.isDamaged()&&player.countCards('h')>0; + skill: { + yitianjian: { + audio: true, + trigger: { source: "damageSource" }, + direct: true, + equipSkill: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.getParent().name == "sha" && + player.isDamaged() && + player.countCards("h") > 0 + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('h',get.prompt('yitianjian'),'弃置一张手牌并回复1点体力').set('ai',(card)=>7-get.value(card)).logSkill='yitianjian'; - 'step 1' - if(result.bool) player.recover(); + content: function () { + "step 0"; + player + .chooseToDiscard("h", get.prompt("yitianjian"), "弃置一张手牌并回复1点体力") + .set("ai", (card) => 7 - get.value(card)).logSkill = "yitianjian"; + "step 1"; + if (result.bool) player.recover(); }, }, - serafuku:{ - audio:true, - trigger:{target:'useCardToTargeted'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return event.card.name=='sha'&&player.hasSex('male'); + serafuku: { + audio: true, + trigger: { target: "useCardToTargeted" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + return event.card.name == "sha" && player.hasSex("male"); }, - content:function(){ - 'step 0' - player.judge(function(card){ - return get.color(card)=='black'?-2:0; - }).judge2=function(result){ - return result.bool==false?true:false; + content: function () { + "step 0"; + player.judge(function (card) { + return get.color(card) == "black" ? -2 : 0; + }).judge2 = function (result) { + return result.bool == false ? true : false; }; - 'step 1' - if(result.bool===false){ - var map=trigger.customArgs,id=player.playerid; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + "step 1"; + if (result.bool === false) { + var map = trigger.customArgs, + id = player.playerid; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; - game.log(trigger.card,'对',player,'的伤害+1'); + game.log(trigger.card, "对", player, "的伤害+1"); } }, }, - yinfengyi:{ - audio:true, - equipSkill:true, - forced:true, - trigger:{player:['damageBegin3','loseHpBegin']}, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.name=='damage'){ - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return event.card&&get.type2(event.card)=='trick'; + yinfengyi: { + audio: true, + equipSkill: true, + forced: true, + trigger: { player: ["damageBegin3", "loseHpBegin"] }, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if (event.name == "damage") { + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + return event.card && get.type2(event.card) == "trick"; } - return event.type=='du'; + return event.type == "du"; }, - content:function(){ + content: function () { trigger.num++; }, }, - zhanxiang:{ - audio:true, - equipSkill:true, - forced:true, - trigger:{target:'gift'}, - filter:(event,player)=>event.player!=player, - logTarget:'player', - content:()=>{ + zhanxiang: { + audio: true, + equipSkill: true, + forced: true, + trigger: { target: "gift" }, + filter: (event, player) => event.player != player, + logTarget: "player", + content: () => { trigger.deniedGifts.add(trigger.card); }, - ai:{ - refuseGifts:true - } + ai: { + refuseGifts: true, + }, }, - xinge:{ - audio:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + xinge: { + audio: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - position:'h', - filterTarget:lib.filter.notMe, - check:function(card){ - var player=_status.event.player; - var val=5; - if(player.needsToDiscard()) val=15; - return val-get.value(card); + filterCard: true, + position: "h", + filterTarget: lib.filter.notMe, + check: function (card) { + var player = _status.event.player; + var val = 5; + if (player.needsToDiscard()) val = 15; + return val - get.value(card); }, - discard:false, - lose:false, - delay:false, - equipSkill:true, - content:function(){ - player.give(cards,target); + discard: false, + lose: false, + delay: false, + equipSkill: true, + content: function () { + player.give(cards, target); }, - ai:{ - expose:0.1, - order:1, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - if(get.value(ui.selected.cards[0],false,'raw')<0) return -1; + ai: { + expose: 0.1, + order: 1, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + if (get.value(ui.selected.cards[0], false, "raw") < 0) return -1; return 1; - } - } - } - }, - qixingbaodao:{ - trigger:{player:'equipBegin'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - return event.card.name=='qixingbaodao'&&player.hasCard(function(card){ - return card!=event.card; - },'ej'); + }, + }, }, - content:function(){ - var cards=player.getCards('ej',function(card){ - return card!=trigger.card&&lib.filter.cardDiscardable(card,player,'qixingbaodao'); + }, + qixingbaodao: { + trigger: { player: "equipBegin" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + return ( + event.card.name == "qixingbaodao" && + player.hasCard(function (card) { + return card != event.card; + }, "ej") + ); + }, + content: function () { + var cards = player.getCards("ej", function (card) { + return ( + card != trigger.card && lib.filter.cardDiscardable(card, player, "qixingbaodao") + ); }); - if(cards.length) player.discard(cards); + if (cards.length) player.discard(cards); }, }, - g_du:{ - trigger:{ - player:['loseAfter','compare'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], - target:'compare', + g_du: { + trigger: { + player: ["loseAfter", "compare"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + target: "compare", }, - cardSkill:true, - filter:function(event,player,name){ - if(name=='compare'){ - if(player==event.player){ - if(event.iwhile>0) return false; - return event.card1.name=='du'; + cardSkill: true, + filter: function (event, player, name) { + if (name == "compare") { + if (player == event.player) { + if (event.iwhile > 0) return false; + return event.card1.name == "du"; } - return event.card2.name=='du'; + return event.card2.name == "du"; } - if(event.name!='equip'&&!event.visible) return false; - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.filter(function(i){ - return get.name(i,player)=='du'; - }).length) return false; - for(var i of lib.skill.g_du.whiteListFilter){ - if(i(event,player)) return false; + if (event.name != "equip" && !event.visible) return false; + var evt = event.getl(player); + if ( + !evt || + !evt.hs || + !evt.hs.filter(function (i) { + return get.name(i, player) == "du"; + }).length + ) + return false; + for (var i of lib.skill.g_du.whiteListFilter) { + if (i(event, player)) return false; } return true; }, - whiteListFilter:[ - (event)=>event.getParent().name=='g_du_give', - (event)=>event.getParent(3).name=='guaguliaodu', + whiteListFilter: [ + (event) => event.getParent().name == "g_du_give", + (event) => event.getParent(3).name == "guaguliaodu", ], - forced:true, - popup:false, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - 'step 1' - game.log(player,'触发了','#g【毒】','的效果'); - var num=1; - if(typeof trigger.getl=='function'){ - num=trigger.getl(player).hs.filter(function(i){ - return get.name(i,player)=='du'; + forced: true, + popup: false, + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + "step 1"; + game.log(player, "触发了", "#g【毒】", "的效果"); + var num = 1; + if (typeof trigger.getl == "function") { + num = trigger.getl(player).hs.filter(function (i) { + return get.name(i, player) == "du"; }).length; } - player.loseHp(num).type='du'; + player.loseHp(num).type = "du"; }, }, - g_du_give:{ - trigger:{ - player:'gainAfter', - global:'phaseBefore', + g_du_give: { + trigger: { + player: "gainAfter", + global: "phaseBefore", }, - cardSkill:true, - direct:true, - filter:function(event,player){ - if(event.name=='phase'){ - if(game.phaseNumber!=0) return false; - if(!player._start_cards) return false; - let hs=player.getCards('h'); - for(let card of player._start_cards){ - if(get.name(card,player)=='du'&&hs.includes(card)) return true; + cardSkill: true, + direct: true, + filter: function (event, player) { + if (event.name == "phase") { + if (game.phaseNumber != 0) return false; + if (!player._start_cards) return false; + let hs = player.getCards("h"); + for (let card of player._start_cards) { + if (get.name(card, player) == "du" && hs.includes(card)) return true; } - } - else{ - if(event.getParent().name!='draw') return false; - let hs=player.getCards('h'); - for(let card of event.getg(player)){ - if(get.name(card,player)=='du'&&hs.includes(card)) return true; + } else { + if (event.getParent().name != "draw") return false; + let hs = player.getCards("h"); + for (let card of event.getg(player)) { + if (get.name(card, player) == "du" && hs.includes(card)) return true; } } return false; }, - content:function(){ - 'step 0' - var hs=player.getCards('h'); - if(trigger.name=='phase'){ - event.cards=player._start_cards.filter(function(card){ - return (get.name(card,player)=='du'&&hs.includes(card)); + content: function () { + "step 0"; + var hs = player.getCards("h"); + if (trigger.name == "phase") { + event.cards = player._start_cards.filter(function (card) { + return get.name(card, player) == "du" && hs.includes(card); + }); + } else { + event.cards = trigger.cards.filter(function (card) { + return get.name(card, player) == "du" && hs.includes(card); }); } - else{ - event.cards=trigger.cards.filter(function(card){ - return (get.name(card,player)=='du'&&hs.includes(card)); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 1' + event.given_map = {}; + "step 1"; player.chooseCardTarget({ - filterCard:function(card){ + filterCard: function (card) { return _status.event.cards.includes(card); }, - filterTarget:lib.filter.notMe, - selectCard:[1,cards.length], - cards:event.cards, - prompt:'是否发动【赠毒】?', - prompt2:'将本次获得的【毒】交给其他角色', - ai1:function(card){ - var player=get.player(); - if(['usedu','keepdu'].some(tag=>player.hasSkillTag(tag))||get.effect(player,{name:"losehp"},player,player)>0) return 0; - if(!ui.selected.cards.length) return 1; + filterTarget: lib.filter.notMe, + selectCard: [1, cards.length], + cards: event.cards, + prompt: "是否发动【赠毒】?", + prompt2: "将本次获得的【毒】交给其他角色", + ai1: function (card) { + var player = get.player(); + if ( + ["usedu", "keepdu"].some((tag) => player.hasSkillTag(tag)) || + get.effect(player, { name: "losehp" }, player, player) > 0 + ) + return 0; + if (!ui.selected.cards.length) return 1; return 0; }, - ai2:function(target){ - if(['usedu','keepdu'].some(tag=>target.hasSkillTag(tag))) return get.attitude(_status.event.player,target)-0.01; - return -get.attitude(_status.event.player,target)+0.01; + ai2: function (target) { + if (["usedu", "keepdu"].some((tag) => target.hasSkillTag(tag))) + return get.attitude(_status.event.player, target) - 0.01; + return -get.attitude(_status.event.player, target) + 0.01; }, }); - 'step 2' - if(result.bool){ - event.given=true; - var res=result.cards,target=result.targets[0].playerid; - player.addGaintag(res,'du_given'); + "step 2"; + if (result.bool) { + event.given = true; + var res = result.cards, + target = result.targets[0].playerid; + player.addGaintag(res, "du_given"); cards.removeArray(res); - if(!event.given_map[target]) event.given_map[target]=[]; + if (!event.given_map[target]) event.given_map[target] = []; event.given_map[target].addArray(res); - if(cards.length) event.goto(1); - } - else if(!event.given){ - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length) event.goto(1); + } else if (!event.given) { + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } event.finish(); } - 'step 3' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + "step 3"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var logs=[]; - var map=[],cards=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; + var logs = []; + var map = [], + cards = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; logs.push(source); - map.push([source,event.given_map[i]]); + map.push([source, event.given_map[i]]); cards.addArray(event.given_map[i]); } - player.showCards(cards,`${get.translation(player)}对${(targets=>{ - if(get.itemtype(targets)=='player') targets=[targets]; - if(targets[0]!=player) return get.translation(targets); - var selfTargets=targets.slice(); - selfTargets[0]='自己'; - return get.translation(selfTargets); - })(logs)}发动了【${get.skillTranslation(event.name,player)}】`); + player.showCards( + cards, + `${get.translation(player)}对${((targets) => { + if (get.itemtype(targets) == "player") targets = [targets]; + if (targets[0] != player) return get.translation(targets); + var selfTargets = targets.slice(); + selfTargets[0] = "自己"; + return get.translation(selfTargets); + })(logs)}发动了【${get.skillTranslation(event.name, player)}】` + ); game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); - player.logSkill('g_du_give',logs); + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); + player.logSkill("g_du_give", logs); }, - ai:{expose:0.1}, + ai: { expose: 0.1 }, }, - _gifting:{ - enable:'phaseUse', - forceLoad:true, - filter:(event,player)=>player.hasCard(card=>lib.skill._gifting.filterCard(card,player),lib.skill._gifting.position), - filterCard:(card,player)=>game.hasPlayer(current=>player.canGift(card,current,true)), - filterTarget:(card,player,target)=>ui.selected.cards.every(value=>player.canGift(value,target,true)), - position:'he', - discard:false, - lose:false, - delay:false, - check:card=>{ - const player=_status.event.player; - if(game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0)) return 2; - if(!player.needsToDiscard()&&get.position(card)=='h') return 0; - return 1+Math.random(); + _gifting: { + enable: "phaseUse", + forceLoad: true, + filter: (event, player) => + player.hasCard( + (card) => lib.skill._gifting.filterCard(card, player), + lib.skill._gifting.position + ), + filterCard: (card, player) => + game.hasPlayer((current) => player.canGift(card, current, true)), + filterTarget: (card, player, target) => + ui.selected.cards.every((value) => player.canGift(value, target, true)), + position: "he", + discard: false, + lose: false, + delay: false, + check: (card) => { + const player = _status.event.player; + if ( + game.hasPlayer( + (current) => + player.canGift(card, current, true) && + !current.refuseGifts(card, player) && + get.effect(current, card, player, player) > 0 + ) + ) + return 2; + if (!player.needsToDiscard() && get.position(card) == "h") return 0; + return 1 + Math.random(); }, - content:()=>{ - player.gift(cards,target); + content: () => { + player.gift(cards, target); + }, + ai: { + order: (item, player) => + player.hasCard( + (card) => + game.hasPlayer( + (current) => + player.canGift(card, current, true) && + !current.refuseGifts(card, player) && + get.effect(current, card, player, player) > 0 + ), + "h" + ) + ? 7 + : 0.51, + result: { + target: (player, target) => { + const result = ui.selected.cards.map((value) => + player.getGiftAIResultTarget(value, target) + ); + return ( + result.reduce( + (previousValue, currentValue) => previousValue + currentValue, + 0 + ) / result.length + ); + }, + }, }, - ai:{ - order:(item,player)=>player.hasCard(card=>game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0),'h')?7:0.51, - result:{ - target:(player,target)=>{ - const result=ui.selected.cards.map(value=>player.getGiftAIResultTarget(value,target)); - return result.reduce((previousValue,currentValue)=>previousValue+currentValue,0)/result.length; - } - } - } }, /** * @deprecated */ - _yongjian_zengyu:{ - get forceLoad(){ + _yongjian_zengyu: { + get forceLoad() { return lib.skill._gifting.forceLoad; }, - set forceLoad(forceLoad){ - lib.skill._gifting.forceLoad=forceLoad; + set forceLoad(forceLoad) { + lib.skill._gifting.forceLoad = forceLoad; }, - get filter(){ + get filter() { return lib.skill._gifting.filter; }, - set filter(filter){ - lib.skill._gifting.filter=filter; + set filter(filter) { + lib.skill._gifting.filter = filter; }, - get filterCard(){ + get filterCard() { return lib.skill._gifting.filterCard; }, - set filterCard(filterCard){ - lib.skill._gifting.filterCard=filterCard; + set filterCard(filterCard) { + lib.skill._gifting.filterCard = filterCard; }, - get filterTarget(){ + get filterTarget() { return lib.skill._gifting.filterTarget; }, - set filterTarget(filterTarget){ - lib.skill._gifting.filterTarget=filterTarget; + set filterTarget(filterTarget) { + lib.skill._gifting.filterTarget = filterTarget; }, - get check(){ + get check() { return lib.skill._gifting.check; }, - set check(check){ - lib.skill._gifting.check=check; + set check(check) { + lib.skill._gifting.check = check; }, - get content(){ + get content() { return lib.skill._gifting.content; }, - set content(content){ - lib.skill._gifting.content=content; + set content(content) { + lib.skill._gifting.content = content; }, - get ai(){ + get ai() { return lib.skill._gifting.ai; }, - set ai(ai){ - lib.skill._gifting.ai=ai; - } - } + set ai(ai) { + lib.skill._gifting.ai = ai; + }, + }, }, - translate:{ - gifts_tag:'赠', - du:'毒', - du_info:'①当此牌正面向上离开你的手牌区,或作为你的拼点牌而亮出时,你失去1点体力。②当你因摸牌或分发起始手牌而获得【毒】后,你可展示之并交给其他角色(不触发〖毒①〗)。', - g_du:'毒', - g_du_give:'赠毒', - du_given:'已分配', - guaguliaodu:'刮骨疗毒', - guaguliaodu_info:'出牌阶段,对一名已受伤的角色使用。目标角色回复1点体力,然后其可以弃置一张【毒】(不触发〖毒①〗失去体力的效果)。', - chenghuodajie:'趁火打劫', - chenghuodajie_info:'出牌阶段,对一名有手牌的其他角色使用。你展示其一张手牌,然后令其选择一项:①将此牌交给你。②你对其造成1点伤害。', - tuixinzhifu:'推心置腹', - tuixinzhifu_info:'出牌阶段,对一名距离为1的其他角色使用。你获得其区域内的至多两张牌,然后交给其等量的牌。', - yitianjian:'倚天剑', - yitianjian_info:'当你因执行【杀】的效果而造成伤害后,若你已受伤,则你可弃置一张手牌,然后回复1点体力。', - qixingbaodao:'七星宝刀', - qixingbaodao_info:'锁定技。当此牌进入你的装备区时,你弃置装备区和判定区内的所有其他牌。', - duanjian:'断剑', - duanjian_info:'这是一把坏掉的武器…', - duanjian_append:'不要因为手快而装给自己。', - serafuku:'水手服', - serafuku_info:'锁定技。当你成为【杀】的目标后,若你的性别包含男性,则你进行判定:若结果为黑色,则此牌对你的伤害值基数+1。', - serafuku_append:'セーラー服だからです、
              結論!
              ', - yinfengyi:'引蜂衣', - yinfengyi_info:'锁定技。当你受到渠道为锦囊牌的伤害时,此伤害+1。当你因〖毒①〗而失去体力时,失去体力的量值+1。', - yonglv:'庸驴', - yonglv_info:'锁定技。①你至其他角色的距离-1。②其他角色至你的距离视为1。', - yonglv_append:'它旁边的就是王仲宣。', - zhanxiang:'战象', - zhanxiang_info:'锁定技。①其他角色至你的距离+1。②其他角色对你赠予的牌视为赠予失败。', - xinge:'信鸽', - xinge_info:'出牌阶段限一次。你可以将一张手牌交给一名其他角色。', - xinge_append:'咕咕咕。', + translate: { + gifts_tag: "赠", + du: "毒", + du_info: + "①当此牌正面向上离开你的手牌区,或作为你的拼点牌而亮出时,你失去1点体力。②当你因摸牌或分发起始手牌而获得【毒】后,你可展示之并交给其他角色(不触发〖毒①〗)。", + g_du: "毒", + g_du_give: "赠毒", + du_given: "已分配", + guaguliaodu: "刮骨疗毒", + guaguliaodu_info: + "出牌阶段,对一名已受伤的角色使用。目标角色回复1点体力,然后其可以弃置一张【毒】(不触发〖毒①〗失去体力的效果)。", + chenghuodajie: "趁火打劫", + chenghuodajie_info: + "出牌阶段,对一名有手牌的其他角色使用。你展示其一张手牌,然后令其选择一项:①将此牌交给你。②你对其造成1点伤害。", + tuixinzhifu: "推心置腹", + tuixinzhifu_info: + "出牌阶段,对一名距离为1的其他角色使用。你获得其区域内的至多两张牌,然后交给其等量的牌。", + yitianjian: "倚天剑", + yitianjian_info: + "当你因执行【杀】的效果而造成伤害后,若你已受伤,则你可弃置一张手牌,然后回复1点体力。", + qixingbaodao: "七星宝刀", + qixingbaodao_info: "锁定技。当此牌进入你的装备区时,你弃置装备区和判定区内的所有其他牌。", + duanjian: "断剑", + duanjian_info: "这是一把坏掉的武器…", + duanjian_append: '不要因为手快而装给自己。', + serafuku: "水手服", + serafuku_info: + "锁定技。当你成为【杀】的目标后,若你的性别包含男性,则你进行判定:若结果为黑色,则此牌对你的伤害值基数+1。", + serafuku_append: + 'セーラー服だからです、
              結論!
              ', + yinfengyi: "引蜂衣", + yinfengyi_info: + "锁定技。当你受到渠道为锦囊牌的伤害时,此伤害+1。当你因〖毒①〗而失去体力时,失去体力的量值+1。", + yonglv: "庸驴", + yonglv_info: "锁定技。①你至其他角色的距离-1。②其他角色至你的距离视为1。", + yonglv_append: '它旁边的就是王仲宣。', + zhanxiang: "战象", + zhanxiang_info: "锁定技。①其他角色至你的距离+1。②其他角色对你赠予的牌视为赠予失败。", + xinge: "信鸽", + xinge_info: "出牌阶段限一次。你可以将一张手牌交给一名其他角色。", + xinge_append: '咕咕咕。', - _gifting:'赠予', - _gifting_info:'出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。', + _gifting: "赠予", + _gifting_info: + "出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。", }, - list:[ - ['spade',1,'guaguliaodu'], - ['spade',2,'qixingbaodao',null,['gifts']], - ['spade',3,'shunshou',null,['gifts']], - ['spade',4,'du',null,['gifts']], - ['spade',5,'du',null,['gifts']], - ['spade',6,'sha','stab'], - ['spade',7,'sha','stab'], - ['spade',8,'sha','stab'], - ['spade',9,'du',null,['gifts']], - ['spade',10,'du',null,['gifts']], - ['spade',11,'wuxie'], - ['spade',12,'chenghuodajie'], - ['spade',13,'chenghuodajie'], + list: [ + ["spade", 1, "guaguliaodu"], + ["spade", 2, "qixingbaodao", null, ["gifts"]], + ["spade", 3, "shunshou", null, ["gifts"]], + ["spade", 4, "du", null, ["gifts"]], + ["spade", 5, "du", null, ["gifts"]], + ["spade", 6, "sha", "stab"], + ["spade", 7, "sha", "stab"], + ["spade", 8, "sha", "stab"], + ["spade", 9, "du", null, ["gifts"]], + ["spade", 10, "du", null, ["gifts"]], + ["spade", 11, "wuxie"], + ["spade", 12, "chenghuodajie"], + ["spade", 13, "chenghuodajie"], - ['heart',1,'guaguliaodu'], - ['heart',2,'shan',null,['gifts']], - ['heart',3,'wugu',null,['gifts']], - ['heart',4,'xinge',null,['gifts']], - ['heart',5,'sha',null,['gifts']], - ['heart',6,'chenghuodajie'], - ['heart',7,'tao'], - ['heart',8,'tao'], - ['heart',9,'serafuku',null,['gifts']], - ['heart',10,'sha',null,['gifts']], - ['heart',11,'sha',null,['gifts']], - ['heart',12,'sha',null,['gifts']], - ['heart',13,'zhanxiang',null,['gifts']], + ["heart", 1, "guaguliaodu"], + ["heart", 2, "shan", null, ["gifts"]], + ["heart", 3, "wugu", null, ["gifts"]], + ["heart", 4, "xinge", null, ["gifts"]], + ["heart", 5, "sha", null, ["gifts"]], + ["heart", 6, "chenghuodajie"], + ["heart", 7, "tao"], + ["heart", 8, "tao"], + ["heart", 9, "serafuku", null, ["gifts"]], + ["heart", 10, "sha", null, ["gifts"]], + ["heart", 11, "sha", null, ["gifts"]], + ["heart", 12, "sha", null, ["gifts"]], + ["heart", 13, "zhanxiang", null, ["gifts"]], - ['club',1,'duanjian',null,['gifts']], - ['club',2,'sha','stab'], - ['club',3,'yinfengyi',null,['gifts']], - ['club',4,'du'], - ['club',5,'yitianjian'], - ['club',6,'sha','stab'], - ['club',7,'sha','stab'], - ['club',8,'sha','stab'], - ['club',9,'sha','stab'], - ['club',10,'sha','stab'], - ['club',11,'wuxie'], - ['club',12,'wuxie'], - ['club',13,'yonglv',null,['gifts']], + ["club", 1, "duanjian", null, ["gifts"]], + ["club", 2, "sha", "stab"], + ["club", 3, "yinfengyi", null, ["gifts"]], + ["club", 4, "du"], + ["club", 5, "yitianjian"], + ["club", 6, "sha", "stab"], + ["club", 7, "sha", "stab"], + ["club", 8, "sha", "stab"], + ["club", 9, "sha", "stab"], + ["club", 10, "sha", "stab"], + ["club", 11, "wuxie"], + ["club", 12, "wuxie"], + ["club", 13, "yonglv", null, ["gifts"]], - ['diamond',1,'juedou',null,['gifts']], - ['diamond',2,'shan'], - ['diamond',3,'kaihua',null,['gifts']], - ['diamond',4,'kaihua',null,['gifts']], - ['diamond',5,'shan'], - ['diamond',6,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'shan'], - ['diamond',9,'tuixinzhifu'], - ['diamond',10,'tuixinzhifu'], - ['diamond',11,'tao',null,['gifts']], - ['diamond',12,'shan'], - ['diamond',13,'sha','stab'], + ["diamond", 1, "juedou", null, ["gifts"]], + ["diamond", 2, "shan"], + ["diamond", 3, "kaihua", null, ["gifts"]], + ["diamond", 4, "kaihua", null, ["gifts"]], + ["diamond", 5, "shan"], + ["diamond", 6, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "tuixinzhifu"], + ["diamond", 10, "tuixinzhifu"], + ["diamond", 11, "tao", null, ["gifts"]], + ["diamond", 12, "shan"], + ["diamond", 13, "sha", "stab"], ], - } + }; }); diff --git a/card/yunchou.js b/card/yunchou.js index 72027ab01..4c9799cfc 100644 --- a/card/yunchou.js +++ b/card/yunchou.js @@ -1,218 +1,230 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'yunchou', - card:{ - diaobingqianjiang:{ - fullskin:true, - type:'trick', - enable:true, - selectTarget:-1, - filterTarget:function(card,player,target){ - return player==target||target.countCards('h'); + name: "yunchou", + card: { + diaobingqianjiang: { + fullskin: true, + type: "trick", + enable: true, + selectTarget: -1, + filterTarget: function (card, player, target) { + return player == target || target.countCards("h"); }, - contentBefore:function(){ - "step 0" + contentBefore: function () { + "step 0"; game.delay(); player.draw(); - "step 1" - if(get.is.versus()){ - player.chooseControl('顺时针','逆时针',function(event,player){ - if(player.next.side==player.side) return '逆时针'; - return '顺时针'; - }).set('prompt','选择'+get.translation(card)+'的结算方向'); - } - else{ + "step 1"; + if (get.is.versus()) { + player + .chooseControl("顺时针", "逆时针", function (event, player) { + if (player.next.side == player.side) return "逆时针"; + return "顺时针"; + }) + .set("prompt", "选择" + get.translation(card) + "的结算方向"); + } else { event.goto(3); } - "step 2" - if(result&&result.control=='顺时针'){ - var evt=event.getParent(); - evt.fixedSeat=true; + "step 2"; + if (result && result.control == "顺时针") { + var evt = event.getParent(); + evt.fixedSeat = true; evt.targets.sortBySeat(); evt.targets.reverse(); - if(evt.targets[evt.targets.length-1]==player){ + if (evt.targets[evt.targets.length - 1] == player) { evt.targets.unshift(evt.targets.pop()); } } - "step 3" + "step 3"; ui.clear(); - var cards=get.cards(Math.ceil(game.countPlayer()/2)); - var dialog=ui.create.dialog('调兵遣将',cards,true); + var cards = get.cards(Math.ceil(game.countPlayer() / 2)); + var dialog = ui.create.dialog("调兵遣将", cards, true); _status.dieClose.push(dialog); - dialog.videoId=lib.status.videoId++; - game.addVideo('cardDialog',null,['调兵遣将',get.cardsInfo(cards),dialog.videoId]); - event.getParent().preResult=dialog.videoId; + dialog.videoId = lib.status.videoId++; + game.addVideo("cardDialog", null, ["调兵遣将", get.cardsInfo(cards), dialog.videoId]); + event.getParent().preResult = dialog.videoId; }, - content:function(){ - "step 0" - for(var i=0;i0){ - return get.value(button.link,nextSeat)-5; + var next = player.chooseButton([1, event.dialog.buttons.length], event.dialog); + next.ai = function (button) { + if (att > 0) { + return get.value(button.link, nextSeat) - 5; + } else { + return 5 - get.value(button.link, nextSeat); } - else{ - return 5-get.value(button.link,nextSeat); - } - } - next.set('closeDialog',false); - next.set('dialogdisplay',true); - 'step 1' - if(result&&result.bool&&result.links&&result.links.length){ - for(var i=0;i0&&target!=player; }, - content:function(){ - 'step 0' - if(target.countCards('h','sha')){ - var name=get.translation(player.name); - target.chooseControl().set('prompt',get.translation('caochuanjiejian')).set('choiceList',[ - '将手牌中的所有杀交给'+name+',并视为对'+name+'使用一张杀','展示手牌并令'+name+'弃置任意一张' - ],function(){ - if(get.effect(player,{name:'sha'},target,target)<0) return 1; - if(target.countCards('h','sha')>=3) return 1; - return 0; - }); + }, + caochuanjiejian: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0 && target != player; + }, + content: function () { + "step 0"; + if (target.countCards("h", "sha")) { + var name = get.translation(player.name); + target + .chooseControl() + .set("prompt", get.translation("caochuanjiejian")) + .set( + "choiceList", + [ + "将手牌中的所有杀交给" + name + ",并视为对" + name + "使用一张杀", + "展示手牌并令" + name + "弃置任意一张", + ], + function () { + if (get.effect(player, { name: "sha" }, target, target) < 0) return 1; + if (target.countCards("h", "sha") >= 3) return 1; + return 0; + } + ); + } else { + event.directfalse = true; } - else{ - event.directfalse=true; - } - 'step 1' - if(event.directfalse||result.control=='选项二'){ - if(target.countCards('h')){ - if(!player.isUnderControl(true)){ + "step 1"; + if (event.directfalse || result.control == "选项二") { + if (target.countCards("h")) { + if (!player.isUnderControl(true)) { target.showHandcards(); + } else { + game.log(target, "展示了", target.getCards("h")); } - else{ - game.log(target,'展示了',target.getCards('h')); - } - player.discardPlayerCard(target,'h',true,'visible'); + player.discardPlayerCard(target, "h", true, "visible"); } event.finish(); + } else { + var hs = target.getCards("h", "sha"); + player.gain(hs, target); + target.$give(hs, player); } - else{ - var hs=target.getCards('h','sha'); - player.gain(hs,target); - target.$give(hs,player); - } - 'step 2' - target.useCard({name:'sha'},player); + "step 2"; + target.useCard({ name: "sha" }, player); }, - ai:{ - order:4, - value:[5,1], - result:{ - target:function(player,target){ - if(player.hasShan()) return -1; + ai: { + order: 4, + value: [5, 1], + result: { + target: function (player, target) { + if (player.hasShan()) return -1; return 0; - } - } - } + }, + }, + }, }, // xiaolicangdao:{ // fullskin:true, @@ -259,767 +271,803 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // } // } // }, - geanguanhuo:{ - fullskin:true, - type:'trick', - filterTarget:function(card,player,target){ - if(target==player) return false; - return target.countCards('h')>0&&game.hasPlayer(function(current){ - return target.canCompare(current); - }); + geanguanhuo: { + fullskin: true, + type: "trick", + filterTarget: function (card, player, target) { + if (target == player) return false; + return ( + target.countCards("h") > 0 && + game.hasPlayer(function (current) { + return target.canCompare(current); + }) + ); //return ui.selected.targets[0].canCompare(target); }, - filterAddedTarget:function(card,player,target,preTarget){ - return target!=player&&preTarget.canCompare(target); + filterAddedTarget: function (card, player, target, preTarget) { + return target != player && preTarget.canCompare(target); }, - enable:function(){ - return game.countPlayer()>2; + enable: function () { + return game.countPlayer() > 2; }, - recastable:function(){ - return game.countPlayer()<=2; + recastable: function () { + return game.countPlayer() <= 2; }, - multicheck:function(card,player){ - return game.countPlayer(function(current){ - return current!=player&¤t.countCards('h'); - })>1; + multicheck: function (card, player) { + return ( + game.countPlayer(function (current) { + return current != player && current.countCards("h"); + }) > 1 + ); }, - multitarget:true, - multiline:true, - singleCard:true, - complexSelect:true, - content:function(){ - 'step 0' - if(!event.addedTarget||!target.canCompare(event.addedTarget)){ + multitarget: true, + multiline: true, + singleCard: true, + complexSelect: true, + content: function () { + "step 0"; + if (!event.addedTarget || !target.canCompare(event.addedTarget)) { event.finish(); return; } target.chooseToCompare(event.addedTarget); - 'step 1' - if(!result.tie){ - if(result.bool){ - if(event.addedTarget.countCards('he')){ + "step 1"; + if (!result.tie) { + if (result.bool) { + if (event.addedTarget.countCards("he")) { target.line(event.addedTarget); - target.gainPlayerCard(event.addedTarget,true); + target.gainPlayerCard(event.addedTarget, true); } - } - else{ - if(target.countCards('he')){ + } else { + if (target.countCards("he")) { event.addedTarget.line(target); - event.addedTarget.gainPlayerCard(target,true); + event.addedTarget.gainPlayerCard(target, true); } } event.finish(); } - 'step 2' + "step 2"; target.discardPlayerCard(player); target.line(player); }, - ai:{ - order:5, - value:[7,1], - useful:[4,1], - result:{ - target:-1, - } - } - }, - shezhanqunru:{ - fullskin:true, - type:'trick', - enable:true, - toself:true, - filterTarget:function(card,player,target){ - return target==player; + ai: { + order: 5, + value: [7, 1], + useful: [4, 1], + result: { + target: -1, + }, }, - selectTarget:-1, - modTarget:true, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current!=target&&target.canCompare(current); + }, + shezhanqunru: { + fullskin: true, + type: "trick", + enable: true, + toself: true, + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + modTarget: true, + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current != target && target.canCompare(current); }); - if(!list.length){ + if (!list.length) { target.draw(3); event.finish(); - } - else{ + } else { list.sortBySeat(target); - event.list=list; - event.torespond=[]; + event.list = list; + event.torespond = []; } - 'step 1' - if(event.list.length){ - event.current=event.list.shift(); - event.current.chooseBool('是否响应'+get.translation(target)+'的舌战群儒?',function(event,player){ - if(get.attitude(player,_status.event.source)>=0) return false; - var hs=player.getCards('h'); - var dutag=player.hasSkillTag('nodu'); - for(var i=0;i=8&&value<=7) return true; - if(value<=3) return true; + "step 1"; + if (event.list.length) { + event.current = event.list.shift(); + event.current + .chooseBool( + "是否响应" + get.translation(target) + "的舌战群儒?", + function (event, player) { + if (get.attitude(player, _status.event.source) >= 0) return false; + var hs = player.getCards("h"); + var dutag = player.hasSkillTag("nodu"); + for (var i = 0; i < hs.length; i++) { + var value = get.value(hs[i], player); + if (hs[i].name == "du" && dutag) continue; + if (value < 0) return true; + if (!_status.event.hasTarget) { + if (hs[i].number >= 8 && value <= 7) return true; + if (value <= 3) return true; + } else if (_status.event.hasTarget % 2 == 1) { + if (hs[i].number >= 11 && value <= 6) return true; + } + } + return false; } - else if(_status.event.hasTarget%2==1){ - if(hs[i].number>=11&&value<=6) return true; - } - } - return false; - }).set('source',target).set('hasTarget',event.torespond.length); - } - else{ + ) + .set("source", target) + .set("hasTarget", event.torespond.length); + } else { event.goto(3); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.torespond.push(event.current); - event.current.line(target,'green'); - event.current.popup('响应'); - game.log(event.current,'响应了舌战群儒'); + event.current.line(target, "green"); + event.current.popup("响应"); + game.log(event.current, "响应了舌战群儒"); game.delayx(0.5); } event.goto(1); - 'step 3' - if(event.torespond.length==0){ - event.num=1; + "step 3"; + if (event.torespond.length == 0) { + event.num = 1; + } else { + event.num = 0; + target.chooseToCompare(event.torespond).callback = lib.card.shezhanqunru.callback; } - else{ - event.num=0; - target.chooseToCompare(event.torespond).callback=lib.card.shezhanqunru.callback; - } - 'step 4' - if(event.num>0){ + "step 4"; + if (event.num > 0) { target.draw(3); } }, - callback:function(){ - if(event.card1.number>event.card2.number){ + callback: function () { + if (event.card1.number > event.card2.number) { event.parent.parent.num++; - } - else{ + } else { event.parent.parent.num--; } }, - ai:{ - order:8.5, - value:[6,1], - useful:[3,1], - tag:{ - draw:3 + ai: { + order: 8.5, + value: [6, 1], + useful: [3, 1], + tag: { + draw: 3, }, - result:{ - target:function(player,target){ - var hs=target.getCards('h'); - for(var i=0;i=7&&value<=6) return 1; - if(value<=3) return 1; + result: { + target: function (player, target) { + var hs = target.getCards("h"); + for (var i = 0; i < hs.length; i++) { + var value = get.value(hs[i]); + if (hs[i].number >= 7 && value <= 6) return 1; + if (value <= 3) return 1; } return 0; - } - } - } + }, + }, + }, }, - youdishenru:{ - fullskin:true, - type:'trick', - notarget:true, - wuxieable:true, - global:'g_youdishenru', - content:function(){ - 'step 0' - var info=event.getParent(2).youdiinfo||event.getParent(3).youdiinfo; - if(!info){ + youdishenru: { + fullskin: true, + type: "trick", + notarget: true, + wuxieable: true, + global: "g_youdishenru", + content: function () { + "step 0"; + var info = event.getParent(2).youdiinfo || event.getParent(3).youdiinfo; + if (!info) { event.finish(); return; } info.evt.cancel(); - event.source=info.source; - event.source.storage.youdishenru=player; - event.source.addSkill('youdishenru'); - 'step 1' - var next=event.source.chooseToUse({name:'sha'},player,-1,'对'+get.translation(player)+'使用一张杀,或受到1点伤害').set('addCount',false); - next.ai2=function(){ + event.source = info.source; + event.source.storage.youdishenru = player; + event.source.addSkill("youdishenru"); + "step 1"; + var next = event.source + .chooseToUse( + { name: "sha" }, + player, + -1, + "对" + get.translation(player) + "使用一张杀,或受到1点伤害" + ) + .set("addCount", false); + next.ai2 = function () { return 1; }; - 'step 2' - if(result.bool){ - if(event.source.storage.youdishenru){ + "step 2"; + if (result.bool) { + if (event.source.storage.youdishenru) { event.goto(1); + } else { + event.source.removeSkill("youdishenru"); } - else{ - event.source.removeSkill('youdishenru'); - } - } - else{ + } else { event.source.damage(player); - event.source.removeSkill('youdishenru'); + event.source.removeSkill("youdishenru"); } }, - ai:{ - value:[5,1], - useful:[5,1], - order:1, - wuxie:function(target,card,player,current,state){ - return -state*get.attitude(player,current); + ai: { + value: [5, 1], + useful: [5, 1], + order: 1, + wuxie: function (target, card, player, current, state) { + return -state * get.attitude(player, current); }, - result:{ - player:function(player){ - if(_status.event.parent.youdiinfo&& - get.attitude(player,_status.event.parent.youdiinfo.source)<=0){ + result: { + player: function (player) { + if ( + _status.event.parent.youdiinfo && + get.attitude(player, _status.event.parent.youdiinfo.source) <= 0 + ) { return 1; } return 0; - } - } - } - }, - wangmeizhike:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - content(){ - 'step 0' - if(target.isMinHp()&&target.isDamaged()){ - target.recover(); - event.rec=true; - } - 'step 1' - if(target.isMinHandcard()) target.draw(event.rec?1:2); + }, + }, }, - ai:{ - order(){ - let player=_status.event.player, - nan=player.hasCard(card=>{ - return get.name(card)==='nanman'; - },'hs'), - wan=player.hasCard(card=>{ - return get.name(card)==='wanjian'; - },'hs'), - aoe=0, - max=0; - game.countPlayer(current=>{ - if(get.attitude(player,current)<=0) return false; - let hp=current.isMinHp(), - hc=current.isMinHandcard(); - if((nan || wan)&&(hp || hc)) aoe=1; - if(hp&&hc&&max!==1) max=current===player?1:-1; + }, + wangmeizhike: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + content() { + "step 0"; + if (target.isMinHp() && target.isDamaged()) { + target.recover(); + event.rec = true; + } + "step 1"; + if (target.isMinHandcard()) target.draw(event.rec ? 1 : 2); + }, + ai: { + order() { + let player = _status.event.player, + nan = player.hasCard((card) => { + return get.name(card) === "nanman"; + }, "hs"), + wan = player.hasCard((card) => { + return get.name(card) === "wanjian"; + }, "hs"), + aoe = 0, + max = 0; + game.countPlayer((current) => { + if (get.attitude(player, current) <= 0) return false; + let hp = current.isMinHp(), + hc = current.isMinHandcard(); + if ((nan || wan) && (hp || hc)) aoe = 1; + if (hp && hc && max !== 1) max = current === player ? 1 : -1; }); - if(aoe){ - if(nan) aoe=Math.max(aoe,get.order('nanman')); - if(wan) aoe=Math.max(aoe,get.order('wanjian')); - return aoe+0.2; + if (aoe) { + if (nan) aoe = Math.max(aoe, get.order("nanman")); + if (wan) aoe = Math.max(aoe, get.order("wanjian")); + return aoe + 0.2; } - if(max) return 5.8; - if(player.isDamaged()&&player.isMinHp()&&player.countCards('hs','tao')) return get.order('tao')+0.2; + if (max) return 5.8; + if (player.isDamaged() && player.isMinHp() && player.countCards("hs", "tao")) + return get.order("tao") + 0.2; return 0.5; }, - value:7, - result:{ - target(player,target){ - let num=0, - current=player.next, - mei=1, - draw=target.hasSkillTag('nogain')?0.1:1; - if(!ui.selected.cards) mei=0; - let mine=player.countCards('h',card=>{ - if(mei>0&& ui.selected.cards.includes(card)) return false; - if(!mei&&get.name(card)==='phd_wmzk'){ - mei=-1; + value: 7, + result: { + target(player, target) { + let num = 0, + current = player.next, + mei = 1, + draw = target.hasSkillTag("nogain") ? 0.1 : 1; + if (!ui.selected.cards) mei = 0; + let mine = player.countCards("h", (card) => { + if (mei > 0 && ui.selected.cards.includes(card)) return false; + if (!mei && get.name(card) === "phd_wmzk") { + mei = -1; return false; } return true; }); - if(player.hasSkillTag('noh')&&player.countCards('h')) mine++; - let min=mine; - while(current!==player){ - if(current.countCards('h')0){ - if(target.hp===1) num+=3; - else num+=2; + if (target.isMinHp() && target.isDamaged() && get.recoverEffect(target) > 0) { + if (target.hp === 1) num += 3; + else num += 2; } - if(player===target){ - if(mine<=min) num+=(num?2:1)*draw; - } - else if(target.countCards('h')<=min) num+=(num?2:1)*draw; + if (player === target) { + if (mine <= min) num += (num ? 2 : 1) * draw; + } else if (target.countCards("h") <= min) num += (num ? 2 : 1) * draw; return num; - } + }, }, - tag:{ - draw:1.2, - recover:0.5 - } - } - }, - suolianjia:{ - fullskin:true, - type:"equip", - subtype:"equip2", - skills:['suolianjia'], - onEquip:function(){ - if(player.isLinked()==false) player.link(); - }, - onLose:function(){ - if(player.isLinked()) player.link(); - }, - ai:{ - basic:{ - equipValue:5 + tag: { + draw: 1.2, + recover: 0.5, }, }, }, - chenhuodajie:{ - fullskin:true, - type:'trick', - filterTarget:true, - global:'g_chenhuodajie', - content:function(){ - if(target.countCards('he')){ - player.gainPlayerCard('he',target,true); + suolianjia: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["suolianjia"], + onEquip: function () { + if (player.isLinked() == false) player.link(); + }, + onLose: function () { + if (player.isLinked()) player.link(); + }, + ai: { + basic: { + equipValue: 5, + }, + }, + }, + chenhuodajie: { + fullskin: true, + type: "trick", + filterTarget: true, + global: "g_chenhuodajie", + content: function () { + if (target.countCards("he")) { + player.gainPlayerCard("he", target, true); } }, - ai:{ - order:1, - useful:6, - value:6, - result:{ - target:-1 + ai: { + order: 1, + useful: 6, + value: 6, + result: { + target: -1, }, - tag:{ - loseCard:1 - } - } + tag: { + loseCard: 1, + }, + }, }, - fudichouxin:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ + fudichouxin: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - content:function(){ - "step 0" - player.chooseToCompare(target).set('preserve','win').clear=false; - "step 1" - if(result.bool){ - player.gain([result.player,result.target]); + content: function () { + "step 0"; + player.chooseToCompare(target).set("preserve", "win").clear = false; + "step 1"; + if (result.bool) { + player.gain([result.player, result.target]); result.player.clone.moveDelete(player); result.target.clone.moveDelete(player); - game.addVideo('gain2',player,get.cardsInfo([result.player,result.target])); - } - else if(!result.cancelled){ + game.addVideo("gain2", player, get.cardsInfo([result.player, result.target])); + } else if (!result.cancelled) { result.player.clone.delete(); result.target.clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([result.player,result.target])); + game.addVideo("deletenode", player, get.cardsInfo([result.player, result.target])); } }, - ai:{ - order:4, - value:[4,1], - result:{ - target:function(player){ - if(player.countCards('h')<=1) return 0; + ai: { + order: 4, + value: [4, 1], + result: { + target: function (player) { + if (player.countCards("h") <= 1) return 0; return -1; }, - player:function(player){ - if(player.countCards('h')<=1) return 0; + player: function (player) { + if (player.countCards("h") <= 1) return 0; return 0.5; - } + }, }, - tag:{ - loseCard:1 - } - } + tag: { + loseCard: 1, + }, + }, }, - shuiyanqijun:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('e'); + shuiyanqijun: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("e"); }, - selectTarget:-1, - content:function(){ - if(target.countCards('e')) target.chooseToDiscard('e',true); + selectTarget: -1, + content: function () { + if (target.countCards("e")) target.chooseToDiscard("e", true); }, - reverseOrder:true, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(target.countCards('e')) return -1; + reverseOrder: true, + ai: { + order: 9, + result: { + target: function (player, target) { + if (target.countCards("e")) return -1; return 0; - } + }, + }, + tag: { + multitarget: 1, + multineg: 1, }, - tag:{ - multitarget:1, - multineg:1 - } - } - }, - toulianghuanzhu:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('h')>0; }, - content:function(){ - 'step 0' - if(!target.countCards('h')){ + }, + toulianghuanzhu: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0; + }, + content: function () { + "step 0"; + if (!target.countCards("h")) { event.finish(); return; } - var hs=player.getCards('h'); - if(hs.length){ - var minval=get.value(hs[0]); - var colors=[get.color(hs[0])]; - for(var i=1;i=0){ - if(colors.includes(get.color(button.link))){ - val+=3; + player.chooseCardButton("偷梁换柱", target.getCards("h")).ai = function (button) { + var val = get.value(button.link, player, "raw") - minval; + if (val >= 0) { + if (colors.includes(get.color(button.link))) { + val += 3; } } return val; - } - } - else{ + }; + } else { player.viewHandcards(target); event.finish(); } - 'step 1' - if(result.bool){ - event.card=result.links[[0]]; - player.chooseCard('h',true,'用一张手牌替换'+get.translation(event.card)).ai=function(card){ - return -get.value(card); - }; - } - else{ + "step 1"; + if (result.bool) { + event.card = result.links[[0]]; + player.chooseCard("h", true, "用一张手牌替换" + get.translation(event.card)).ai = + function (card) { + return -get.value(card); + }; + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.gain(event.card,target); - target.gain(result.cards,player); - player.$giveAuto(result.cards,target); - target.$giveAuto(event.card,player); - game.log(player,'与',target,'交换了一张手牌'); - if(get.color(event.card)==get.color(result.cards[0])){ + "step 2"; + if (result.bool) { + player.gain(event.card, target); + target.gain(result.cards, player); + player.$giveAuto(result.cards, target); + target.$giveAuto(event.card, player); + game.log(player, "与", target, "交换了一张手牌"); + if (get.color(event.card) == get.color(result.cards[0])) { player.draw(); } - target.addTempSkill('toulianghuanzhu_ai1'); - } - else{ - target.addTempSkill('toulianghuanzhu_ai2'); + target.addTempSkill("toulianghuanzhu_ai1"); + } else { + target.addTempSkill("toulianghuanzhu_ai2"); } }, - ai:{ - order:8, - tag:{ - loseCard:1, - norepeat:1, + ai: { + order: 8, + tag: { + loseCard: 1, + norepeat: 1, }, - result:{ - target:function(player,target){ - if(player.countCards('h')<=1) return 0; - if(target.hasSkill('toulianghuanzhu_ai2')) return 0; - if(target.hasSkill('toulianghuanzhu_ai1')) return 0.5; + result: { + target: function (player, target) { + if (player.countCards("h") <= 1) return 0; + if (target.hasSkill("toulianghuanzhu_ai2")) return 0; + if (target.hasSkill("toulianghuanzhu_ai1")) return 0.5; return -1; - } + }, }, - useful:[4,1], - value:[6,1] - } - }, - huoshan:{ - fullskin:true, - type:'delay', - cardcolor:'red', - cardnature:'fire', - toself:true, - modTarget:function(card,player,target){ - return lib.filter.judge(card,player,target); + useful: [4, 1], + value: [6, 1], }, - enable:function(card,player){ + }, + huoshan: { + fullskin: true, + type: "delay", + cardcolor: "red", + cardnature: "fire", + toself: true, + modTarget: function (card, player, target) { + return lib.filter.judge(card, player, target); + }, + enable: function (card, player) { return player.canAddJudge(card); }, - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player==target); + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player == target; }, - selectTarget:[-1,-1], - judge:function(card){ - if(get.suit(card)=='heart'&&get.number(card)>1&&get.number(card)<10) return -6; + selectTarget: [-1, -1], + judge: function (card) { + if (get.suit(card) == "heart" && get.number(card) > 1 && get.number(card) < 10) return -6; return 1; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - effect:function(){ - if(result.bool==false){ - player.damage(2,'fire','nosource'); - var players=game.filterPlayer(function(current){ - return get.distance(player,current)<=1&&player!=current; + effect: function () { + if (result.bool == false) { + player.damage(2, "fire", "nosource"); + var players = game.filterPlayer(function (current) { + return get.distance(player, current) <= 1 && player != current; }); players.sort(lib.sort.seat); - for(var i=0;i1&&get.number(card)<10) return -3; + selectTarget: [-1, -1], + judge: function (card) { + if (get.suit(card) == "club" && get.number(card) > 1 && get.number(card) < 10) return -3; return 1; }, - judge2:function(result){ - if(result.bool==false) return true; + judge2: function (result) { + if (result.bool == false) return true; return false; }, - fullskin:true, - effect:function(){ - if(result.bool==false){ - if(player.countCards('he')==0) player.loseHp(); - else{ - player.discard(player.getCards('he').randomGets(3)); + fullskin: true, + effect: function () { + if (result.bool == false) { + if (player.countCards("he") == 0) player.loseHp(); + else { + player.discard(player.getCards("he").randomGets(3)); } - var players=get.players(); - for(var i=0;i0; + filterTarget: function (card, player, target) { + return target.isMajor() && target.countCards("he") > 0; }, - selectTarget:-1, - content:function(){ - target.chooseToDiscard('he',true).delay=false; + selectTarget: -1, + content: function () { + target.chooseToDiscard("he", true).delay = false; }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:-1, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: -1, }, - tag:{ - discard:1 - } - } + tag: { + discard: 1, + }, + }, }, - dizaizhen:{ - type:'zhenfa', - recastable:true, - enable:function(){ - return game.hasPlayer(function(current){ + dizaizhen: { + type: "zhenfa", + recastable: true, + enable: function () { + return game.hasPlayer(function (current) { return current.isNotMajor(); }); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return target.isNotMajor(); }, - selectTarget:-1, - content:function(){ + selectTarget: -1, + content: function () { target.draw(false); target.$draw(); }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:1, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: 1, }, - tag:{ - draw:1 - } - } + tag: { + draw: 1, + }, + }, }, - fengyangzhen:{ - type:'zhenfa', - recastable:true, - enable:true, - filterTarget:function(card,player,target){ + fengyangzhen: { + type: "zhenfa", + recastable: true, + enable: true, + filterTarget: function (card, player, target) { return target.sieged(); }, - selectTarget:-1, - content:function(){ - target.addTempSkill('feiying',{player:'damageAfter'}); - target.popup('feiying'); - game.log(target,'获得了技能','【飞影】'); + selectTarget: -1, + content: function () { + target.addTempSkill("feiying", { player: "damageAfter" }); + target.popup("feiying"); + game.log(target, "获得了技能", "【飞影】"); }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:2, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: 2, }, - } + }, }, - yunchuizhen:{ - type:'zhenfa', - recastable:true, - enable:true, - filterTarget:function(card,player,target){ + yunchuizhen: { + type: "zhenfa", + recastable: true, + enable: true, + filterTarget: function (card, player, target) { return target.siege(); }, - selectTarget:-1, - content:function(){ - target.addTempSkill('wushuang',{source:'damageAfter'}); - target.popup('wushuang'); - game.log(target,'获得了技能','【无双】'); + selectTarget: -1, + content: function () { + target.addTempSkill("wushuang", { source: "damageAfter" }); + target.popup("wushuang"); + game.log(target, "获得了技能", "【无双】"); }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:2, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: 2, }, - } + }, }, - qixingzhen:{ - type:'zhenfa', - recastable:true, - enable:function(card,player){ - return player.siege()||player.sieged(); + qixingzhen: { + type: "zhenfa", + recastable: true, + enable: function (card, player) { + return player.siege() || player.sieged(); }, - filterTarget:function(card,player,target){ - return target==player; + filterTarget: function (card, player, target) { + return target == player; }, - selectTarget:-1, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ + selectTarget: -1, + content: function () { + "step 0"; + event.targets = game.filterPlayer(function (current) { return current.siege(player); }); - 'step 1' - if(event.targets.length){ - var current=event.targets.shift(); - player.line(current,'green'); - player.discardPlayerCard(current,true); + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); + player.line(current, "green"); + player.discardPlayerCard(current, true); event.redo(); } - 'step 2' - var card={name:'sha',isCard:true}; - var list=game.filterPlayer(function(current){ - return current.siege(player)&&player.canUse(card,current); + "step 2"; + var card = { name: "sha", isCard: true }; + var list = game.filterPlayer(function (current) { + return current.siege(player) && player.canUse(card, current); }); - if(list.length){ - player.useCard(card,list,false); + if (list.length) { + player.useCard(card, list, false); } }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:1, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: 1, }, - } + }, }, - shepanzhen:{ - type:'zhenfa', - recastable:true, - enable:function(card,player){ - if(player.identity=='unknown'||player.identity=='ye') return false; - if(get.population(player.identity)<=1) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.identity==player.identity&&!player.inline(current); + shepanzhen: { + type: "zhenfa", + recastable: true, + enable: function (card, player) { + if (player.identity == "unknown" || player.identity == "ye") return false; + if (get.population(player.identity) <= 1) return false; + return game.hasPlayer(function (current) { + return ( + current != player && + current.identity == player.identity && + !player.inline(current) + ); }); }, - notarget:true, - content:function(){ - var targets=game.filterPlayer(function(current){ - return current.identity==player.identity; + notarget: true, + content: function () { + var targets = game.filterPlayer(function (current) { + return current.identity == player.identity; }); targets.sortBySeat(); - for(var i=1;i0){ - return 6-get.value(card); + selectTarget: -1, + content: function () { + "step 0"; + player.chooseCard( + "将一张非基本牌当作杀对" + get.translation(target) + "使用", + "he", + function (card) { + return get.type(card) != "basic"; + } + ).ai = function (card) { + if (get.effect(target, { name: "sha" }, player, player) > 0) { + return 6 - get.value(card); } return 0; }; - "step 1" - if(result.bool){ - player.useCard({name:'sha'},result.cards,target,false); + "step 1"; + if (result.bool) { + player.useCard({ name: "sha" }, result.cards, target, false); } - "step 2" - if(target==player.next) event.player2=player.next.next; - else event.player2=player.previous.previous; - event.player2.chooseCard('将一张非基本牌当作杀对'+get.translation(target)+'使用','he',function(card){ - return get.type(card)!='basic'; - }).ai=function(card){ - if(get.effect(target,{name:'sha'},event.player2,event.player2)>0){ - return 6-get.value(card); + "step 2"; + if (target == player.next) event.player2 = player.next.next; + else event.player2 = player.previous.previous; + event.player2.chooseCard( + "将一张非基本牌当作杀对" + get.translation(target) + "使用", + "he", + function (card) { + return get.type(card) != "basic"; + } + ).ai = function (card) { + if (get.effect(target, { name: "sha" }, event.player2, event.player2) > 0) { + return 6 - get.value(card); } return 0; }; - "step 3" - if(result.bool){ - event.player2.useCard({name:'sha'},result.cards,target,false); + "step 3"; + if (result.bool) { + event.player2.useCard({ name: "sha" }, result.cards, target, false); } }, - mode:['guozhan'], - ai:{ - order:7, - result:{ - target:-2, + mode: ["guozhan"], + ai: { + order: 7, + result: { + target: -2, }, - } - }, - niaoxiangzhen:{ - type:'zhenfa', - recastable:true, - enable:true, - filterTarget:function(card,player,target){ - if(player.identity==target.identity) return false; - if(target.identity=='unknown'||target.identity=='ye') return false; - return target.identity==target.next.identity||target.identity==target.previous.identity }, - selectTarget:-1, - content:function(){ - "step 0" - var next=target.chooseToRespond({name:'shan'}); - next.ai=function(card){ - if(get.damageEffect(target,player,target)>=0) return 0; + }, + niaoxiangzhen: { + type: "zhenfa", + recastable: true, + enable: true, + filterTarget: function (card, player, target) { + if (player.identity == target.identity) return false; + if (target.identity == "unknown" || target.identity == "ye") return false; + return ( + target.identity == target.next.identity || target.identity == target.previous.identity + ); + }, + selectTarget: -1, + content: function () { + "step 0"; + var next = target.chooseToRespond({ name: "shan" }); + next.ai = function (card) { + if (get.damageEffect(target, player, target) >= 0) return 0; return 1; }; - next.autochoose=lib.filter.autoRespondShan; - "step 1" - if(result.bool==false){ + next.autochoose = lib.filter.autoRespondShan; + "step 1"; + if (result.bool == false) { target.damage(); } }, - ai:{ - basic:{ - order:9, - useful:1 + ai: { + basic: { + order: 9, + useful: 1, }, - result:{ - target:-1.5, + result: { + target: -1.5, + }, + tag: { + respond: 1, + respondShan: 1, + damage: 1, }, - tag:{ - respond:1, - respondShan:1, - damage:1, - } }, - mode:['guozhan'], + mode: ["guozhan"], }, }, - skill:{ - }, - translate:{ - zhenfa:'阵法', - changshezhen:'长蛇阵', - pozhenjue:'破阵决', - tianfuzhen:'天覆阵', - dizaizhen:'地载阵', - fengyangzhen:'风扬阵', - yunchuizhen:'云垂阵', - qixingzhen:'七星阵', - shepanzhen:'蛇蟠阵', - shepanzhen_bg:'列', - yunchuizhen_bg:'垂', - longfeizhen:'龙飞阵', - huyizhen:'虎翼阵', - niaoxiangzhen:'鸟翔阵', - niaoxiangzhen_info:'令所有非你阵营的队列的角色今次打出一张闪,或者受到1点伤害。', - qixingzhen_info:'弃置所有围攻你的角色各一张牌,然后视为对所有你围攻的角色使用一张不计入出杀次数的杀。', + skill: {}, + translate: { + zhenfa: "阵法", + changshezhen: "长蛇阵", + pozhenjue: "破阵决", + tianfuzhen: "天覆阵", + dizaizhen: "地载阵", + fengyangzhen: "风扬阵", + yunchuizhen: "云垂阵", + qixingzhen: "七星阵", + shepanzhen: "蛇蟠阵", + shepanzhen_bg: "列", + yunchuizhen_bg: "垂", + longfeizhen: "龙飞阵", + huyizhen: "虎翼阵", + niaoxiangzhen: "鸟翔阵", + niaoxiangzhen_info: "令所有非你阵营的队列的角色今次打出一张闪,或者受到1点伤害。", + qixingzhen_info: + "弃置所有围攻你的角色各一张牌,然后视为对所有你围攻的角色使用一张不计入出杀次数的杀。", // longfeizhen_info:'弃置围攻你的角色各一张牌,然后摸一张牌。', // qixingzhen_info:'令我方所有角色进入围攻状态。', // shepanzhen_info:'令我方所有角色进入队列状态。', // yunchuizhen_info:'令所有围攻角色获得技能〖无双〗,直到其首次造成伤害。', // fengyangzhen_info:'令所有被围攻角色获得技能〖飞影〗,直到其首次受到伤害。', - dizaizhen_info:'所有小势力角色摸一张牌。', - changshezhen_info:'若你处于队列中,与你同一队列的所有角色摸一张牌,否则将与你逆时针距离最近的同势力角色移至你下家。', + dizaizhen_info: "所有小势力角色摸一张牌。", + changshezhen_info: + "若你处于队列中,与你同一队列的所有角色摸一张牌,否则将与你逆时针距离最近的同势力角色移至你下家。", // pozhenjue_info:'将所有角色的顺序随机重排。', - tianfuzhen_info:'所有大势力角色弃置一张牌。' + tianfuzhen_info: "所有大势力角色弃置一张牌。", }, - list:[ - ["diamond",1,'changshezhen'], - ["club",1,'changshezhen'], + list: [ + ["diamond", 1, "changshezhen"], + ["club", 1, "changshezhen"], // ["spade",1,'changshezhen'], // ["heart",1,'changshezhen'], - ["diamond",2,'tianfuzhen'], + ["diamond", 2, "tianfuzhen"], // ["club",2,'tianfuzhen'], - ["spade",2,'tianfuzhen'], - ["heart",2,'tianfuzhen'], + ["spade", 2, "tianfuzhen"], + ["heart", 2, "tianfuzhen"], - ["diamond",3,'dizaizhen'], + ["diamond", 3, "dizaizhen"], // ["club",3,'dizaizhen'], - ["spade",3,'dizaizhen'], - ["heart",3,'dizaizhen'], + ["spade", 3, "dizaizhen"], + ["heart", 3, "dizaizhen"], // ["diamond",4,'fengyangzhen'], // ["club",4,'fengyangzhen'], @@ -407,9 +423,9 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // ["spade",6,'huyizhen'], // ["heart",6,'huyizhen'], - ["diamond",7,'qixingzhen'], - ["club",7,'qixingzhen'], - ["spade",7,'qixingzhen'], + ["diamond", 7, "qixingzhen"], + ["club", 7, "qixingzhen"], + ["spade", 7, "qixingzhen"], // ["heart",7,'qixingzhen'], // ["diamond",8,'shepanzhen'], @@ -422,10 +438,10 @@ game.import('card',function(lib,game,ui,get,ai,_status){ // ["spade",9,'longfeizhen'], // ["heart",9,'longfeizhen'], - ["diamond",11,'niaoxiangzhen'], + ["diamond", 11, "niaoxiangzhen"], // ["club",11,'niaoxiangzhen'], - ["spade",11,'niaoxiangzhen'], - ["heart",11,'niaoxiangzhen'], + ["spade", 11, "niaoxiangzhen"], + ["heart", 11, "niaoxiangzhen"], // ["diamond",12,'yunchuizhen'], // ["club",12,'yunchuizhen'], diff --git a/card/zhulu.js b/card/zhulu.js index 9aa9a9231..ecbce8ed8 100644 --- a/card/zhulu.js +++ b/card/zhulu.js @@ -1,936 +1,1050 @@ -'use strict'; -game.import('card',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("card", function () { return { - name:'zhulu', - connect:true, - card:{ - zhulu_card:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - cardcolor:'red', - selectTarget:-1, - filterTarget:true, - contentBefore:function(){ - "step 0" - if(get.is.versus()){ - player.chooseControl('顺时针','逆时针',function(event,player){ - if(player.next.side==player.side) return '逆时针'; - return '顺时针'; - }).set('prompt','选择'+get.translation(card)+'的结算方向'); - } - else{ + name: "zhulu", + connect: true, + card: { + zhulu_card: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + cardcolor: "red", + selectTarget: -1, + filterTarget: true, + contentBefore: function () { + "step 0"; + if (get.is.versus()) { + player + .chooseControl("顺时针", "逆时针", function (event, player) { + if (player.next.side == player.side) return "逆时针"; + return "顺时针"; + }) + .set("prompt", "选择" + get.translation(card) + "的结算方向"); + } else { event.goto(2); } - "step 1" - if(result&&result.control=='顺时针'){ - var evt=event.getParent(); - evt.fixedSeat=true; + "step 1"; + if (result && result.control == "顺时针") { + var evt = event.getParent(); + evt.fixedSeat = true; evt.targets.sortBySeat(); evt.targets.reverse(); - if(evt.targets[evt.targets.length-1]==player){ + if (evt.targets[evt.targets.length - 1] == player) { evt.targets.unshift(evt.targets.pop()); } } - "step 2" + "step 2"; ui.clear(); var num; - if(event.targets){ - num=event.targets.length; + if (event.targets) { + num = event.targets.length; + } else { + num = game.countPlayer(); } - else{ - num=game.countPlayer(); - } - var cards=[]; - for(var i=0;i1){ - var next=target.chooseButton(true,function(button){ - var player=_status.event.player; - return get.effect(player,button.link,player,player); + if (equips.length > 1) { + var next = target.chooseButton(true, function (button) { + var player = _status.event.player; + return get.effect(player, button.link, player, player); }); - next.set('equips',equips); - next.set('filterButton',function(button){ + next.set("equips", equips); + next.set("filterButton", function (button) { return _status.event.equips.includes(button.link); }); - next.set('dialog',event.preResult); - next.set('closeDialog',false); - next.set('dialogdisplay',true); - } - else if(equips.length){ - event.directButton=equips[0]; - } - else event.finish(); - "step 1" - var dialog=event.dialog; + next.set("dialog", event.preResult); + next.set("closeDialog", false); + next.set("dialogdisplay", true); + } else if (equips.length) { + event.directButton = equips[0]; + } else event.finish(); + "step 1"; + var dialog = event.dialog; var card; - if(event.directButton){ - card=event.directButton; - } - else{ - card=result.links[0]; + if (event.directButton) { + card = event.directButton; + } else { + card = result.links[0]; } var button; - for(var i=0;i0?0.4:0.7; - } + return (1 - get.distance(player, target, "absolute") / game.countPlayer()) * + get.attitude(player, target) > + 0 + ? 0.4 + : 0.7; + }, }, - tag:{ - draw:1, - multitarget:1 - } - } + tag: { + draw: 1, + multitarget: 1, + }, + }, }, - kaihua:{ - enable:true, - fullskin:true, - type:'trick', - selectTarget:-1, - toself:true, - filterTarget:function(card,player,target){ - return target==player; + kaihua: { + enable: true, + fullskin: true, + type: "trick", + selectTarget: -1, + toself: true, + filterTarget: function (card, player, target) { + return target == player; }, - modTarget:true, - content:function(){ - 'step 0' - if(!target.countCards('he')){ - event.finish();return; + modTarget: true, + content: function () { + "step 0"; + if (!target.countCards("he")) { + event.finish(); + return; } - target.chooseToDiscard(true,'he',[1,2]).set('ai',function(card){ - if(!ui.selected.cards.length&&get.type(card)=='equip') return 8-get.value(card); - return 6-get.value(card); + target.chooseToDiscard(true, "he", [1, 2]).set("ai", function (card) { + if (!ui.selected.cards.length && get.type(card) == "equip") + return 8 - get.value(card); + return 6 - get.value(card); }); - 'step 1' - if(result.bool&&result.cards){ - var bool=0; - for(var i=0;iget.value(card); - return 6>get.value(card); + result: { + target: function (player, target, card) { + var cards = ui.selected.cards.concat(card.cards || []); + var num = player.countCards("he", function (card) { + if (cards.includes(card)) return false; + if (get.type(card) == "equip") return 8 > get.value(card); + return 6 > get.value(card); }); - if(!num) return 0; - if(player.countCards('he',function(card){ - if(cards.includes(card)) return false; - if(get.type(card)=='equip') return 4>get.value(card); - return false; - })) return 1.6; - if(num<2) return 0.5; + if (!num) return 0; + if ( + player.countCards("he", function (card) { + if (cards.includes(card)) return false; + if (get.type(card) == "equip") return 4 > get.value(card); + return false; + }) + ) + return 1.6; + if (num < 2) return 0.5; return 1.2; }, }, - tag:{ - loseCard:1, - discard:1, - norepeat:1 - } + tag: { + loseCard: 1, + discard: 1, + norepeat: 1, + }, }, }, - jiejia:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('e')>0; + jiejia: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("e") > 0; }, - content:function(){ - var es=target.getCards('e'); - if(es.length) target.gain(es,'gain2','log'); + content: function () { + var es = target.getCards("e"); + if (es.length) target.gain(es, "gain2", "log"); }, - ai:{ - order:10, - tag:{ - gain:1, + ai: { + order: 10, + tag: { + gain: 1, //loseCard:1, }, - basic:{ - useful:0.5, - value:0.5, + basic: { + useful: 0.5, + value: 0.5, }, - result:{ - target:function(player,target){ - var e5=target.getEquip('muniu'); - if(e5&&e5.name=='muniu'&&e5.cards&&e5.cards.length>1) return -1; - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })||target.hasSkillTag('noe')) return 1; + result: { + target: function (player, target) { + var e5 = target.getEquip("muniu"); + if (e5 && e5.name == "muniu" && e5.cards && e5.cards.length > 1) return -1; + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) || + target.hasSkillTag("noe") + ) + return 1; return 0; }, }, }, }, - caochuan:{ - fullskin:true, - type:'trick', - wuxieable:true, - global:['caochuan_skill'], - notarget:true, - content:function(){ - var evt2=event.getParent(3)._trigger; + caochuan: { + fullskin: true, + type: "trick", + wuxieable: true, + global: ["caochuan_skill"], + notarget: true, + content: function () { + var evt2 = event.getParent(3)._trigger; evt2.neutralize(); - var evt=evt2.getParent(); - var next=game.createEvent('caochuan_gain'); + var evt = evt2.getParent(); + var next = game.createEvent("caochuan_gain"); _status.event.next.remove(next); evt.after.unshift(next); - next.player=player; - next.setContent(function(){ - var cards=event.getParent().cards.filterInD(); - if(cards.length) player.gain(cards,'gain2','log'); + next.player = player; + next.setContent(function () { + var cards = event.getParent().cards.filterInD(); + if (cards.length) player.gain(cards, "gain2", "log"); }); }, - ai:{ - basic:{ - useful:[6,4], - value:[6,4], + ai: { + basic: { + useful: [6, 4], + value: [6, 4], }, - result:{player:1}, + result: { player: 1 }, }, }, - numa:{ - fullskin:true, - type:'equip', - subtype:'equip4', - filterTarget:function(card,player,target){ - if(player==target) return false; - return target.canEquip(card,true) + numa: { + fullskin: true, + type: "equip", + subtype: "equip4", + filterTarget: function (card, player, target) { + if (player == target) return false; + return target.canEquip(card, true); }, - selectTarget:1, - toself:false, - loseThrow:true, - customSwap:function(){ + selectTarget: 1, + toself: false, + loseThrow: true, + customSwap: function () { return true; }, - ai:{ - order:9, - value:function(card,player){ - if(player.getEquips(4).includes(card)) return 0; + ai: { + order: 9, + value: function (card, player) { + if (player.getEquips(4).includes(card)) return 0; return 4; }, - equipValue:function(card,player){ - if(player.getCards('e').includes(card)) return 0; - return -get.value(player.getCards('e')); + equipValue: function (card, player) { + if (player.getCards("e").includes(card)) return 0; + return -get.value(player.getCards("e")); }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target){ - var cards=target.getCards('e'); - if(cards.length==1&&cards[0].name=='nvzhuang') return 0; - var val=get.value(cards,target); - if(val>0) return -val; + result: { + keepAI: true, + target: function (player, target) { + var cards = target.getCards("e"); + if (cards.length == 1 && cards[0].name == "nvzhuang") return 0; + var val = get.value(cards, target); + if (val > 0) return -val; return 0; }, }, }, }, - yajiaoqiang:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - skills:['yajiaoqiang_skill'], - ai:{ - equipValue:function(card,player){ - var skills=['longdan','kanpo','rekanpo','qingguo','reqingguo','ollongdan','refanghun']; - for(var i=0;i0) val+=4/num; + if (num > 0) val += 4 / num; return -val; } - if(card){ - var val2=get.value(card,target); - if(val2>0) return -val2/4; + if (card) { + var val2 = get.value(card, target); + if (val2 > 0) return -val2 / 4; } return 0; }, }, - } - }, - yexingyi:{ - fullskin:true, - type:'equip', - subtype:'equip2', - skills:['yexingyi_skill'], - ai:{ - equipValue:4, - basic:{ - equipValue:4, - }, - } - }, - jinhe:{ - fullskin:true, - type:'equip', - subtype:'equip5', - filterTarget:function(card,player,target){ - if(player==target) return false; - return target.canEquip(card,true) }, - selectTarget:1, - toself:false, - skills:['jinhe_skill'], - global:['jinhe_lose'], - loseDelay:false, - onEquip:function(){ - "step 0" - player.markSkill('jinhe_skill'); - if(event.getParent(2).name!='jinhe') event.finish(); - else{ - event.target=player; - event.player=event.getParent(2).player; + }, + yexingyi: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["yexingyi_skill"], + ai: { + equipValue: 4, + basic: { + equipValue: 4, + }, + }, + }, + jinhe: { + fullskin: true, + type: "equip", + subtype: "equip5", + filterTarget: function (card, player, target) { + if (player == target) return false; + return target.canEquip(card, true); + }, + selectTarget: 1, + toself: false, + skills: ["jinhe_skill"], + global: ["jinhe_lose"], + loseDelay: false, + onEquip: function () { + "step 0"; + player.markSkill("jinhe_skill"); + if (event.getParent(2).name != "jinhe") event.finish(); + else { + event.target = player; + event.player = event.getParent(2).player; } - "step 1" - var id=card.cardid; - event.cardid=id; - if(!_status.jinhe) _status.jinhe={}; - if(_status.jinhe[id]){ + "step 1"; + var id = card.cardid; + event.cardid = id; + if (!_status.jinhe) _status.jinhe = {}; + if (_status.jinhe[id]) { game.cardsDiscard(_status.jinhe[id].card); delete _status.jinhe[id]; } - var cards2=get.cards(2); - event.cards2=cards2; - player.chooseButton(['选择一张牌作为「礼」',cards2],true); - "step 2" - var id=event.cardid; - _status.jinhe[id]={ - player:player, - card:result.links[0], + var cards2 = get.cards(2); + event.cards2 = cards2; + player.chooseButton(["选择一张牌作为「礼」", cards2], true); + "step 2"; + var id = event.cardid; + _status.jinhe[id] = { + player: player, + card: result.links[0], }; - game.broadcast(function(jinhe){ - _status.jinhe=jinhe; - },_status.jinhe); + game.broadcast(function (jinhe) { + _status.jinhe = jinhe; + }, _status.jinhe); game.cardsGotoSpecial(result.links[0]); event.cards2.remove(result.links[0]); event.cards2[0].fix(); - ui.cardPile.insertBefore(event.cards2[0],ui.cardPile.firstChild); + ui.cardPile.insertBefore(event.cards2[0], ui.cardPile.firstChild); game.updateRoundNumber(); - target.markSkill('jinhe_skill'); + target.markSkill("jinhe_skill"); }, - onLose:function(){ - player.unmarkSkill('jinhe_skill'); - var id=card.cardid; - if((event.getParent(2)&&event.getParent(2).name!='swapEquip')&&get.position(card)!='d'&&event.parent.type!='equip'&&_status.jinhe&&_status.jinhe[id]){ - var card2=_status.jinhe[id].card; - player.$throw(card2,1000); - game.log(card,'掉落了',card2); + onLose: function () { + player.unmarkSkill("jinhe_skill"); + var id = card.cardid; + if ( + event.getParent(2) && + event.getParent(2).name != "swapEquip" && + get.position(card) != "d" && + event.parent.type != "equip" && + _status.jinhe && + _status.jinhe[id] + ) { + var card2 = _status.jinhe[id].card; + player.$throw(card2, 1000); + game.log(card, "掉落了", card2); game.cardsDiscard(card2); delete _status.jinhe[id]; } }, - ai:{ - order:9.5, - equipValue:function(card,player){ - if(!player.getEquips(5).includes(card)) return 5; - if(_status.jinhe&&_status.jinhe[card.cardid]&&_status.event.name!='gainPlayerCard') return 3*player.countCards('h'); + ai: { + order: 9.5, + equipValue: function (card, player) { + if (!player.getEquips(5).includes(card)) return 5; + if ( + _status.jinhe && + _status.jinhe[card.cardid] && + _status.event.name != "gainPlayerCard" + ) + return 3 * player.countCards("h"); return 0; }, - value:function(){ - return lib.card.jinhe.ai.equipValue.apply(this,arguments); + value: function () { + return lib.card.jinhe.ai.equipValue.apply(this, arguments); }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - result:{ - keepAI:true, - target:function(player,target,cardx){ - if(_status.jinhe&&_status.jinhe[cardx.cardid]) return -0.5-2*target.countCards('h'); - var card=target.getEquip(5); - if(!card) return 0; - return -get.value(card,target); + result: { + keepAI: true, + target: function (player, target, cardx) { + if (_status.jinhe && _status.jinhe[cardx.cardid]) + return -0.5 - 2 * target.countCards("h"); + var card = target.getEquip(5); + if (!card) return 0; + return -get.value(card, target); }, - target_use:function(player,target){ - return -0.5-2*target.countCards('h'); + target_use: function (player, target) { + return -0.5 - 2 * target.countCards("h"); }, }, - } + }, }, }, - skill:{ - jinhe_lose:{ - trigger:{ - player:['loseAfter','equipAfter'], - global:'loseAsyncAfter', + skill: { + jinhe_lose: { + trigger: { + player: ["loseAfter", "equipAfter"], + global: "loseAsyncAfter", }, - equipSkill:true, - forced:true, - filter:function(event,player){ - if(event.getl===false) return false; - if(!event.getd(player).length||!_status.jinhe||event.getParent(2).name=='jinhe_skill'&&event.getParent(2).player==player) return false; - var evt=event.getl(player); - if(!evt) return false; - for(var i=0;icard.cards.includes(cardx)||ui.selected.cards.includes(cardx))) return false; + yexingyi_skill: { + equipSkill: true, + mod: { + targetEnabled: function (card, player, target) { + if ( + get.color(card) == "black" && + get.type(card, "trick") == "trick" && + !target.hasSkillTag("unequip2") && + !player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: target, + card: card, + }) + ) { + const cards = player.getEquips("yexingyi"); + if ( + player.hasSkill("yexingyi_skill", null, false) || + !card.cards || + !cards.some( + (cardx) => card.cards.includes(cardx) || ui.selected.cards.includes(cardx) + ) + ) + return false; } }, }, }, - yinfengjia_skill:{ - trigger:{player:'damageBegin3'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - if(get.type(event.card,'trick')!='trick') return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; + yinfengjia_skill: { + trigger: { player: "damageBegin3" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + if (get.type(event.card, "trick") != "trick") return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; return true; }, - content:function(){trigger.num++}, + content: function () { + trigger.num++; + }, }, - wufengjian_skill:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - var cards=player.getEquips('wufengjian'); - return player.hasCard(function(card){ + wufengjian_skill: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + var cards = player.getEquips("wufengjian"); + return player.hasCard(function (card) { return !cards.includes(card); - },'he'); + }, "he"); }, - content:function(){ - if(player!=game.me&&!player.isUnderControl()&&!player.isOnline()) game.delayx(); - player.chooseToDiscard(true,'he',function(card){ - return !_status.event.cards.includes(card); - }).set('cards',player.getEquips('wufengjian')); + content: function () { + if (player != game.me && !player.isUnderControl() && !player.isOnline()) game.delayx(); + player + .chooseToDiscard(true, "he", function (card) { + return !_status.event.cards.includes(card); + }) + .set("cards", player.getEquips("wufengjian")); }, }, - yajiaoqiang_skill:{ - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(_status.currentPhase==player||get.color(event.card)!='black'||event.cards.filterInD().length==0) return false; - return player.getHistory('useCard',function(evt){ - return get.color(evt.card)=='black'; - }).indexOf(event)==0; + yajiaoqiang_skill: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if ( + _status.currentPhase == player || + get.color(event.card) != "black" || + event.cards.filterInD().length == 0 + ) + return false; + return ( + player + .getHistory("useCard", function (evt) { + return get.color(evt.card) == "black"; + }) + .indexOf(event) == 0 + ); }, - prompt2:function(event,player){ - return '获得'+get.translation(event.cards.filterInD()); + prompt2: function (event, player) { + return "获得" + get.translation(event.cards.filterInD()); }, - content:function(){ - player.gain(trigger.cards.filterInD(),'gain2','log'); + content: function () { + player.gain(trigger.cards.filterInD(), "gain2", "log"); }, }, - caochuan_skill:{ - trigger:{target:'useCardToBegin'}, - forced:true, - priority:6, - filter:function(event,player){ - if(event.directHit||!get.tag(event.card,'damage')||!['basic','trick'].includes(get.type(event.card))) return false; - return player.hasUsableCard('caochuan'); + caochuan_skill: { + trigger: { target: "useCardToBegin" }, + forced: true, + priority: 6, + filter: function (event, player) { + if ( + event.directHit || + !get.tag(event.card, "damage") || + !["basic", "trick"].includes(get.type(event.card)) + ) + return false; + return player.hasUsableCard("caochuan"); }, - content:function(){ - var next=player.chooseToUse(); - next.set('prompt','是否使用【草船借箭】响应'+get.translation(trigger.player)+'使用的'+get.translation(trigger.card)+'?'); - next.set('filterCard',function(card,player){ - if(get.name(card)!='caochuan') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); + content: function () { + var next = player.chooseToUse(); + next.set( + "prompt", + "是否使用【草船借箭】响应" + + get.translation(trigger.player) + + "使用的" + + get.translation(trigger.card) + + "?" + ); + next.set("filterCard", function (card, player) { + if (get.name(card) != "caochuan") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); }); - next.set('respondTo',[trigger.player,trigger.card]); - next.set('goon',-get.effect(player,trigger.card,trigger.player,player)); - next.set('ai1',function(card){ + next.set("respondTo", [trigger.player, trigger.card]); + next.set("goon", -get.effect(player, trigger.card, trigger.player, player)); + next.set("ai1", function (card) { return _status.event.goon; - }) + }); }, }, }, - translate:{ - jinhe:'锦盒', - jinhe_info:'此牌的使用目标为其他角色。当你使用【锦盒】时,你将原有的与此牌对应的「礼」置入弃牌堆(若有),然后观看牌堆顶的两张牌并将其中一张置于游戏外与此牌对应,称之为「礼」。
              出牌阶段,你可以将与此牌对应的「礼」置入弃牌堆,然后弃置【锦盒】以及所有与「礼」花色相同的手牌。当此牌因其他原因进入弃牌堆后,你将与此牌对应的「礼」置入弃牌堆并弃置所有手牌。', - jinhe_skill:'锦盒', - jinhe_lose:'锦盒', - yexingyi:'夜行衣', - yexingyi_info:'锁定技,你不是黑色锦囊牌的合法目标。', - nvzhuang:'女装', - nvzhuang_info:'此牌的使用目标为其他角色。锁定技,当此牌进入或离开你的装备区时,若你的性别为男性,你弃置一张不为此牌的牌。', - yinfengjia:'引蜂甲', - yinfengjia_info:'此牌的使用目标为其他角色。锁定技,当你受到锦囊牌造成的伤害时,此伤害+1。', - yinfengjia_skill:'引蜂甲', - zheji:'折戟', - zheji_info:'此牌的使用目标为其他角色。这是一把坏掉的武器...', - wufengjian:'无锋剑', - wufengjian_info:'此牌的使用目标为其他角色。锁定技,当你使用【杀】时,你弃置一张不为装备区内【无锋剑】的牌。', - wufengjian_skill:'无锋剑', - yajiaoqiang_skill:'涯角枪', - yajiaoqiang:'涯角枪', - yajiaoqiang_info:'当你于一名其他角色的回合内第一次使用的黑色牌结算完成后,你可以获得此牌对应的所有实体牌。', - numa:'驽马', - numa_info:'此牌的使用目标为其他角色。锁定技,当此牌进入你的装备区时,你弃置装备区内的所有其他牌。', - caochuan:'草船借箭', - caochuan_info:'当带有「伤害」标签的基本牌或普通锦囊牌对你生效前,对此牌使用。抵消此牌对你产生的效果。当此牌结算完成后,你获得此牌对应的所有实体牌。', - jiejia:'解甲归田', - jiejia_info:'出牌阶段,对一名装备区内有牌的角色使用。该角色获得其装备区内的所有牌。', - kaihua:'树上开花', - kaihua_info:'出牌阶段,对包含你自己在内的一名角色使用。目标角色弃置一至两张牌,然后摸等量的牌。若其以此法弃置了装备牌,则多摸一张牌。', - zhulu_card:'逐鹿天下', - zhulu_card_info:'出牌阶段,对所有角色使用。你从牌堆和弃牌堆亮出等同于目标角色数的装备牌,每名目标角色将其中一张牌置于自己的装备区。', + translate: { + jinhe: "锦盒", + jinhe_info: + "此牌的使用目标为其他角色。当你使用【锦盒】时,你将原有的与此牌对应的「礼」置入弃牌堆(若有),然后观看牌堆顶的两张牌并将其中一张置于游戏外与此牌对应,称之为「礼」。
              出牌阶段,你可以将与此牌对应的「礼」置入弃牌堆,然后弃置【锦盒】以及所有与「礼」花色相同的手牌。当此牌因其他原因进入弃牌堆后,你将与此牌对应的「礼」置入弃牌堆并弃置所有手牌。", + jinhe_skill: "锦盒", + jinhe_lose: "锦盒", + yexingyi: "夜行衣", + yexingyi_info: "锁定技,你不是黑色锦囊牌的合法目标。", + nvzhuang: "女装", + nvzhuang_info: + "此牌的使用目标为其他角色。锁定技,当此牌进入或离开你的装备区时,若你的性别为男性,你弃置一张不为此牌的牌。", + yinfengjia: "引蜂甲", + yinfengjia_info: "此牌的使用目标为其他角色。锁定技,当你受到锦囊牌造成的伤害时,此伤害+1。", + yinfengjia_skill: "引蜂甲", + zheji: "折戟", + zheji_info: "此牌的使用目标为其他角色。这是一把坏掉的武器...", + wufengjian: "无锋剑", + wufengjian_info: + "此牌的使用目标为其他角色。锁定技,当你使用【杀】时,你弃置一张不为装备区内【无锋剑】的牌。", + wufengjian_skill: "无锋剑", + yajiaoqiang_skill: "涯角枪", + yajiaoqiang: "涯角枪", + yajiaoqiang_info: + "当你于一名其他角色的回合内第一次使用的黑色牌结算完成后,你可以获得此牌对应的所有实体牌。", + numa: "驽马", + numa_info: + "此牌的使用目标为其他角色。锁定技,当此牌进入你的装备区时,你弃置装备区内的所有其他牌。", + caochuan: "草船借箭", + caochuan_info: + "当带有「伤害」标签的基本牌或普通锦囊牌对你生效前,对此牌使用。抵消此牌对你产生的效果。当此牌结算完成后,你获得此牌对应的所有实体牌。", + jiejia: "解甲归田", + jiejia_info: "出牌阶段,对一名装备区内有牌的角色使用。该角色获得其装备区内的所有牌。", + kaihua: "树上开花", + kaihua_info: + "出牌阶段,对包含你自己在内的一名角色使用。目标角色弃置一至两张牌,然后摸等量的牌。若其以此法弃置了装备牌,则多摸一张牌。", + zhulu_card: "逐鹿天下", + zhulu_card_info: + "出牌阶段,对所有角色使用。你从牌堆和弃牌堆亮出等同于目标角色数的装备牌,每名目标角色将其中一张牌置于自己的装备区。", }, - list:[ - ['diamond',3,'jiejia'], - ['diamond',4,'shan'], - ['diamond',5,'yajiaoqiang'], - ['diamond',6,'sha'], - ['diamond',8,'shan'], - ['diamond',9,'kaihua'], - ['diamond',10,'yinfengjia'], - ['diamond',11,'sha'], + list: [ + ["diamond", 3, "jiejia"], + ["diamond", 4, "shan"], + ["diamond", 5, "yajiaoqiang"], + ["diamond", 6, "sha"], + ["diamond", 8, "shan"], + ["diamond", 9, "kaihua"], + ["diamond", 10, "yinfengjia"], + ["diamond", 11, "sha"], - ['club',3,'jiejia'], - ['club',4,'sha','thunder'], - ['club',5,'zheji'], - ['club',6,'jiu'], - ['club',8,'jiu'], - ['club',9,'zhulu_card'], - ['club',10,'jinhe'], - ['club',11,'sha'], + ["club", 3, "jiejia"], + ["club", 4, "sha", "thunder"], + ["club", 5, "zheji"], + ["club", 6, "jiu"], + ["club", 8, "jiu"], + ["club", 9, "zhulu_card"], + ["club", 10, "jinhe"], + ["club", 11, "sha"], - ['heart',3,'sha','fire'], - ['heart',4,'shan'], - ['heart',5,'numa'], - ['heart',6,'tao'], - ['heart',8,'shan'], - ['heart',9,'kaihua'], - ['heart',10,'nvzhuang'], - ['heart',11,'kaihua'], + ["heart", 3, "sha", "fire"], + ["heart", 4, "shan"], + ["heart", 5, "numa"], + ["heart", 6, "tao"], + ["heart", 8, "shan"], + ["heart", 9, "kaihua"], + ["heart", 10, "nvzhuang"], + ["heart", 11, "kaihua"], - ['spade',3,'caochuan'], - ['spade',4,'sha','thunder'], - ['spade',5,'wufengjian'], - ['spade',6,'caochuan'], - ['spade',8,'sha'], - ['spade',9,'sha'], - ['spade',10,'yexingyi'], - ['spade',11,'sha'], + ["spade", 3, "caochuan"], + ["spade", 4, "sha", "thunder"], + ["spade", 5, "wufengjian"], + ["spade", 6, "caochuan"], + ["spade", 8, "sha"], + ["spade", 9, "sha"], + ["spade", 10, "yexingyi"], + ["spade", 11, "sha"], ], - } + }; }); diff --git a/character/clan.js b/character/clan.js index dc5bf8992..c99823343 100644 --- a/character/clan.js +++ b/character/clan.js @@ -1,2812 +1,3895 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { //clan n.宗派;(尤指苏格兰的)宗族,氏族,家族;庞大的家族;帮派;小集团 - name:'clan', - connect:true, - character:{ - clan_wuxian:['female','shu',3,['clanyirong','clanguixiang','clanmuyin'],['clan:陈留吴氏']], - clan_wuban:['male','shu',4,['clanzhanding','clanmuyin'],['clan:陈留吴氏']], - clan_xunshu:['male','qun',3,['clanshenjun','clanbalong','clandaojie'],['clan:颍川荀氏']], - clan_xunchen:['male','qun',3,['clansankuang','clanbeishi','clandaojie'],['clan:颍川荀氏']], - clan_xuncai:['female','qun',3,['clanlieshi','clandianzhan','clanhuanyin','clandaojie'],['clan:颍川荀氏']], - clan_xuncan:['male','wei',3,['clanyunshen','clanshangshen','clanfenchai','clandaojie'],['clan:颍川荀氏']], - clan_hanshao:['male','qun',3,['clanfangzhen','clanliuju','clanxumin'],['clan:颍川韩氏']], - clan_hanrong:['male','qun',3,['clanlianhe','clanhuanjia','clanxumin'],['clan:颍川韩氏']], - clan_wukuang:['male','qun',4,['clanlianzhu','clanmuyin'],['clan:陈留吴氏']], - clan_wangling:['male','wei',4,['clanbolong','clanzhongliu'],['clan:太原王氏']], - clan_zhongyan:['female','jin',3,['clanguangu','clanxiaoyong','clanbaozu'],['clan:颍川钟氏']], - clan_wangyun:['male','qun',3,['clanjiexuan','clanmingjie','clanzhongliu'],['clan:太原王氏']], - clan_wanghun:['male','jin',3,['clanfuxun','clanchenya','clanzhongliu'],['clan:太原王氏']], - clan_zhonghui:['male','wei','3/4',['clanyuzhi','clanxieshu','clanbaozu'],['clan:颍川钟氏']], - clan_zhongyu:['male','wei',3,['clanjiejian','clanhuanghan','clanbaozu'],['clan:颍川钟氏']], - clan_wanglun:['male','jin',3,['clanqiuxin','clanjianyuan','clanzhongliu'],['clan:太原王氏']], - clan_xunyou:['male','wei',3,['clanbaichu','clandaojie'],['clan:颍川荀氏']], - clan_wuqiao:['male','jin',4,['clanqiajue','clanmuyin'],['clan:陈留吴氏']], - clan_wangguang:['male','wei',3,['clanlilun','clanjianji','clanzhongliu'],['clan:太原王氏']], - clan_wangmingshan:['male','wei',3,['clantanque','clanshengmo','clanzhongliu'],['clan:太原王氏']], + name: "clan", + connect: true, + character: { + clan_wuxian: ["female", "shu", 3, ["clanyirong", "clanguixiang", "clanmuyin"], ["clan:陈留吴氏"]], + clan_wuban: ["male", "shu", 4, ["clanzhanding", "clanmuyin"], ["clan:陈留吴氏"]], + clan_xunshu: ["male", "qun", 3, ["clanshenjun", "clanbalong", "clandaojie"], ["clan:颍川荀氏"]], + clan_xunchen: ["male", "qun", 3, ["clansankuang", "clanbeishi", "clandaojie"], ["clan:颍川荀氏"]], + clan_xuncai: [ + "female", + "qun", + 3, + ["clanlieshi", "clandianzhan", "clanhuanyin", "clandaojie"], + ["clan:颍川荀氏"], + ], + clan_xuncan: [ + "male", + "wei", + 3, + ["clanyunshen", "clanshangshen", "clanfenchai", "clandaojie"], + ["clan:颍川荀氏"], + ], + clan_hanshao: ["male", "qun", 3, ["clanfangzhen", "clanliuju", "clanxumin"], ["clan:颍川韩氏"]], + clan_hanrong: ["male", "qun", 3, ["clanlianhe", "clanhuanjia", "clanxumin"], ["clan:颍川韩氏"]], + clan_wukuang: ["male", "qun", 4, ["clanlianzhu", "clanmuyin"], ["clan:陈留吴氏"]], + clan_wangling: ["male", "wei", 4, ["clanbolong", "clanzhongliu"], ["clan:太原王氏"]], + clan_zhongyan: [ + "female", + "jin", + 3, + ["clanguangu", "clanxiaoyong", "clanbaozu"], + ["clan:颍川钟氏"], + ], + clan_wangyun: [ + "male", + "qun", + 3, + ["clanjiexuan", "clanmingjie", "clanzhongliu"], + ["clan:太原王氏"], + ], + clan_wanghun: ["male", "jin", 3, ["clanfuxun", "clanchenya", "clanzhongliu"], ["clan:太原王氏"]], + clan_zhonghui: [ + "male", + "wei", + "3/4", + ["clanyuzhi", "clanxieshu", "clanbaozu"], + ["clan:颍川钟氏"], + ], + clan_zhongyu: ["male", "wei", 3, ["clanjiejian", "clanhuanghan", "clanbaozu"], ["clan:颍川钟氏"]], + clan_wanglun: [ + "male", + "jin", + 3, + ["clanqiuxin", "clanjianyuan", "clanzhongliu"], + ["clan:太原王氏"], + ], + clan_xunyou: ["male", "wei", 3, ["clanbaichu", "clandaojie"], ["clan:颍川荀氏"]], + clan_wuqiao: ["male", "jin", 4, ["clanqiajue", "clanmuyin"], ["clan:陈留吴氏"]], + clan_wangguang: [ + "male", + "wei", + 3, + ["clanlilun", "clanjianji", "clanzhongliu"], + ["clan:太原王氏"], + ], + clan_wangmingshan: [ + "male", + "wei", + 3, + ["clantanque", "clanshengmo", "clanzhongliu"], + ["clan:太原王氏"], + ], }, - characterSort:{ - clan:{ - clan_wu:['clan_wuxian','clan_wuban','clan_wukuang','clan_wuqiao'], - clan_xun:['clan_xunshu','clan_xunchen','clan_xuncai','clan_xuncan','clan_xunyou'], - clan_han:['clan_hanshao','clan_hanrong'], - clan_wang:['clan_wangling','clan_wangyun','clan_wanghun','clan_wanglun','clan_wangguang','clan_wangmingshan'], - clan_zhong:['clan_zhongyan','clan_zhonghui','clan_zhongyu'], + characterSort: { + clan: { + clan_wu: ["clan_wuxian", "clan_wuban", "clan_wukuang", "clan_wuqiao"], + clan_xun: ["clan_xunshu", "clan_xunchen", "clan_xuncai", "clan_xuncan", "clan_xunyou"], + clan_han: ["clan_hanshao", "clan_hanrong"], + clan_wang: [ + "clan_wangling", + "clan_wangyun", + "clan_wanghun", + "clan_wanglun", + "clan_wangguang", + "clan_wangmingshan", + ], + clan_zhong: ["clan_zhongyan", "clan_zhonghui", "clan_zhongyu"], }, }, /** @type { importCharacterConfig['skill'] } */ - skill:{ + skill: { //族王明山 - clantanque:{ - audio:2, - trigger:{player:'useCardAfter'}, - usable:1, - filter(event,player){ - const evt=lib.skill.dcjianying.getLastUsed(player,event); - if(!evt||!evt.card) return false; - const curCard=event.card,prevCard=evt.card; - const curNum=get.number(curCard),prevNum=get.number(prevCard); - if(typeof curNum!='number'||typeof prevNum!='number') return false; - const delNum=Math.abs(curNum-prevNum); - if(delNum===0) return false; - return game.hasPlayer(current=>{ - return current.getHp()===delNum; + clantanque: { + audio: 2, + trigger: { player: "useCardAfter" }, + usable: 1, + filter(event, player) { + const evt = lib.skill.dcjianying.getLastUsed(player, event); + if (!evt || !evt.card) return false; + const curCard = event.card, + prevCard = evt.card; + const curNum = get.number(curCard), + prevNum = get.number(prevCard); + if (typeof curNum != "number" || typeof prevNum != "number") return false; + const delNum = Math.abs(curNum - prevNum); + if (delNum === 0) return false; + return game.hasPlayer((current) => { + return current.getHp() === delNum; }); }, - locked:false, - async cost(event,trigger,player){ - const evt=lib.skill.dcjianying.getLastUsed(player,trigger); - const curCard=trigger.card,prevCard=evt.card; - const curNum=get.number(curCard),prevNum=get.number(prevCard); - const delNum=Math.abs(curNum-prevNum); - event.result=await player.chooseTarget(get.prompt('clantanque'),`对一名体力值为${delNum}的角色造成1点伤害`,(card,player,target)=>{ - return target.getHp()===get.event('delNum'); - }).set('delNum',delNum).set('ai',target=>{ - return get.damageEffect(target,get.player(),get.player()); - }).forResult(); + locked: false, + async cost(event, trigger, player) { + const evt = lib.skill.dcjianying.getLastUsed(player, trigger); + const curCard = trigger.card, + prevCard = evt.card; + const curNum = get.number(curCard), + prevNum = get.number(prevCard); + const delNum = Math.abs(curNum - prevNum); + event.result = await player + .chooseTarget( + get.prompt("clantanque"), + `对一名体力值为${delNum}的角色造成1点伤害`, + (card, player, target) => { + return target.getHp() === get.event("delNum"); + } + ) + .set("delNum", delNum) + .set("ai", (target) => { + return get.damageEffect(target, get.player(), get.player()); + }) + .forResult(); }, - async content(event,trigger,player){ - const target=event.targets[0]; + async content(event, trigger, player) { + const target = event.targets[0]; await target.damage(); await game.asyncDelayx(); }, - mod:{ - aiOrder(player,card,num){ - if(typeof card!='object') return; - const evt=lib.skill.dcjianying.getLastUsed(player); - if(!evt||!evt.card) return; - const curNum=get.number(card),prevNum=get.number(evt.card); - if(typeof curNum!='number'||typeof prevNum!='number') return; - const pairs=game.filterPlayer().map(current=>{ - return [current.getHp(),get.damageEffect(current,player,player)]; - }).filter(pair=>pair[1]>0); - if(!pairs.length) return; - const delNum=Math.abs(curNum-prevNum); - for(const [hp,eff] of pairs){ - if(hp!=delNum) continue; - return num+10+(pairs.filter(pair=>pair[0]===hp).sort((a,b)=>b[1]-a[1])[0][1])/20; + mod: { + aiOrder(player, card, num) { + if (typeof card != "object") return; + const evt = lib.skill.dcjianying.getLastUsed(player); + if (!evt || !evt.card) return; + const curNum = get.number(card), + prevNum = get.number(evt.card); + if (typeof curNum != "number" || typeof prevNum != "number") return; + const pairs = game + .filterPlayer() + .map((current) => { + return [current.getHp(), get.damageEffect(current, player, player)]; + }) + .filter((pair) => pair[1] > 0); + if (!pairs.length) return; + const delNum = Math.abs(curNum - prevNum); + for (const [hp, eff] of pairs) { + if (hp != delNum) continue; + return ( + num + + 10 + + pairs.filter((pair) => pair[0] === hp).sort((a, b) => b[1] - a[1])[0][1] / 20 + ); } }, - } + }, }, - clanshengmo:{ - audio:2, - enable:'chooseToUse', - hiddenCard(player,name){ - if(get.type(name)!='basic') return false; - if(!player.getStorage('clanshengmo').includes(name)&&(get.event('clanshengmo_cards')||[]).length>0) return true; + clanshengmo: { + audio: 2, + enable: "chooseToUse", + hiddenCard(player, name) { + if (get.type(name) != "basic") return false; + if ( + !player.getStorage("clanshengmo").includes(name) && + (get.event("clanshengmo_cards") || []).length > 0 + ) + return true; }, - filter(event,player){ - if(event.responded) return false; - const names=lib.inpile.filter(name=>get.type(name)=='basic'&&!player.getStorage('clanshengmo').includes(name)),cards=get.event('clanshengmo_cards')||[]; - return cards.length>0&&names.some(name=>{ - return event.filterCard({name,isCard:true},player,event); - }); + filter(event, player) { + if (event.responded) return false; + const names = lib.inpile.filter( + (name) => + get.type(name) == "basic" && !player.getStorage("clanshengmo").includes(name) + ), + cards = get.event("clanshengmo_cards") || []; + return ( + cards.length > 0 && + names.some((name) => { + return event.filterCard({ name, isCard: true }, player, event); + }) + ); }, - onChooseToUse(event){ - if(game.online) return; - if(!event.clanshengmo_cards){ - let cards=[]; - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name!='cardsDiscard'&&(evt.name!='lose'||evt.position!=ui.discardPile)) return; - cards.addArray(evt.cards.filter(card=>get.position(card,true)=='d')); + onChooseToUse(event) { + if (game.online) return; + if (!event.clanshengmo_cards) { + let cards = []; + game.checkGlobalHistory("cardMove", (evt) => { + if ( + evt.name != "cardsDiscard" && + (evt.name != "lose" || evt.position != ui.discardPile) + ) + return; + cards.addArray(evt.cards.filter((card) => get.position(card, true) == "d")); }); - const numbers=cards.map(card=>get.number(card,false)).unique(); - const [min,max]=[Math.min(...numbers),Math.max(...numbers)]; - event.set('clanshengmo_cards',cards.filter(card=>{ - const num=get.number(card,false); - return num>min&&num get.number(card, false)).unique(); + const [min, max] = [Math.min(...numbers), Math.max(...numbers)]; + event.set( + "clanshengmo_cards", + cards.filter((card) => { + const num = get.number(card, false); + return num > min && num < max; + }) + ); } }, - async content(event,trigger,player){ + async content(event, trigger, player) { const evt = event.getParent(2); - const names = lib.inpile.filter(name => get.type(name) == 'basic' && !player.getStorage('clanshengmo').includes(name)), cards = evt.clanshengmo_cards; - const links = await player.chooseButton(['剩墨:获得其中一张牌', cards], true).set('ai', button => { - return get.value(button.link); - }).forResultLinks(); + const names = lib.inpile.filter( + (name) => + get.type(name) == "basic" && !player.getStorage("clanshengmo").includes(name) + ), + cards = evt.clanshengmo_cards; + const links = await player + .chooseButton(["剩墨:获得其中一张牌", cards], true) + .set("ai", (button) => { + return get.value(button.link); + }) + .forResultLinks(); if (!links || !links.length) return; const list = []; for (const name of names) { const card = { name, isCard: true }; if (evt.filterCard(card, player, evt)) { - list.push(['基本', '', name]); + list.push(["基本", "", name]); } - if (name == 'sha') { + if (name == "sha") { for (const nature of lib.inpile_nature) { card.nature = nature; if (evt.filterCard(card, player, evt)) { - list.push(['基本', '', name, nature]); + list.push(["基本", "", name, nature]); } } } } if (!list.length) return; - const links2 = await player.chooseButton(['视为使用一张未以此法使用过的基本牌', [list, 'vcard']], true).set('ai', button => { - return get.player().getUseValue(button.link) + 1; - }).forResultLinks(); - const name = links2[0][2], nature = links2[0][3]; - game.broadcastAll((name, nature, toGain) => { - lib.skill.clanshengmo_backup.viewAs = { - name, - nature, - isCard: true, - }; - lib.skill.clanshengmo_backup.prompt = `选择${get.translation(nature)}【${get.translation(name)}】的目标`; - lib.skill.clanshengmo_backup.cardToGain = toGain; - }, name, nature, links[0]); - evt.set('_backupevent', 'clanshengmo_backup'); - evt.backup('clanshengmo_backup'); - evt.set('openskilldialog', `选择${get.translation(nature)}【${get.translation(name)}】的目标`); - evt.set('norestore', true); - evt.set('custom', { + const links2 = await player + .chooseButton(["视为使用一张未以此法使用过的基本牌", [list, "vcard"]], true) + .set("ai", (button) => { + return get.player().getUseValue(button.link) + 1; + }) + .forResultLinks(); + const name = links2[0][2], + nature = links2[0][3]; + game.broadcastAll( + (name, nature, toGain) => { + lib.skill.clanshengmo_backup.viewAs = { + name, + nature, + isCard: true, + }; + lib.skill.clanshengmo_backup.prompt = `选择${get.translation( + nature + )}【${get.translation(name)}】的目标`; + lib.skill.clanshengmo_backup.cardToGain = toGain; + }, + name, + nature, + links[0] + ); + evt.set("_backupevent", "clanshengmo_backup"); + evt.backup("clanshengmo_backup"); + evt.set( + "openskilldialog", + `选择${get.translation(nature)}【${get.translation(name)}】的目标` + ); + evt.set("norestore", true); + evt.set("custom", { add: {}, - replace: { window() { } } + replace: { window() {} }, }); evt.goto(0); }, - marktext:'墨', - intro:{ - content:'已以此法使用过$' + marktext: "墨", + intro: { + content: "已以此法使用过$", }, - subSkill:{ - backup:{ - precontent(){ + subSkill: { + backup: { + precontent() { delete event.result.skill; event.result.card.storage.clanshengmo = true; - player.markAuto('clanshengmo',event.result.card.name); - player.gain(lib.skill.clanshengmo_backup.cardToGain, 'gain2'); + player.markAuto("clanshengmo", event.result.card.name); + player.gain(lib.skill.clanshengmo_backup.cardToGain, "gain2"); + }, + filterCard: () => false, + selectCard: -1, + }, + }, + ai: { + order: 3, + result: { + player(player) { + if (get.event().dying) return get.attitude(player, get.event().dying); + if (get.event().type != "phase") return 1; + const names = lib.inpile.filter( + (name) => + get.type(name) == "basic" && + !player.getStorage("clanshengmo").includes(name) + ); + if (Array.isArray(names)) { + return names.some((name) => { + return player.getUseValue({ name }) > 0; + }); + } + return 0; }, - filterCard:()=>false, - selectCard:-1, }, }, - ai:{ - order:3, - result:{ - player(player){ - if(get.event().dying) return get.attitude(player, get.event().dying); - if(get.event().type!='phase') return 1; - const names=get.event(`clanshengmo_${player.playerid}_enabled_names`); - return names.some(name=>{ - return player.getUseValue({name})>0; - }); - } - } - } }, //族贝斯塔[doge] - clanlilun:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.hasCard(card=>get.info('clanlilun').filterCard(card,player),'h'); + clanlilun: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return player.hasCard((card) => get.info("clanlilun").filterCard(card, player), "h"); }, - filterCard(card,player){ - if(player.getStorage('clanlilun').includes(card.name)) return false; - if(ui.selected.cards.length&&ui.selected.cards[0].name!=card.name) return false; - const cards=player.getCards('h',cardx=>player.canRecast(cardx)); - return cards.includes(card)&&cards.filter(i=>i.name==card.name).length>1; + filterCard(card, player) { + if (player.getStorage("clanlilun").includes(card.name)) return false; + if (ui.selected.cards.length && ui.selected.cards[0].name != card.name) return false; + const cards = player.getCards("h", (cardx) => player.canRecast(cardx)); + return cards.includes(card) && cards.filter((i) => i.name == card.name).length > 1; }, - selectCard:2, - position:'h', - check(card){ - const player=get.event('player'); - const value=function(card,player){ - const num=player.getUseValue(card); - return num>0?(num+(1/(get.value(card)||0.5))+7):7-get.value(card); + selectCard: 2, + position: "h", + check(card) { + const player = get.event("player"); + const value = function (card, player) { + const num = player.getUseValue(card); + return num > 0 ? num + 1 / (get.value(card) || 0.5) + 7 : 7 - get.value(card); }; - if(ui.selected.cards.length&&value(card,player){ - player.unmarkSkill('clanlilun'); + if (!player.storage.clanlilun) { + player.when({ global: "phaseAfter" }).then(() => { + player.unmarkSkill("clanlilun"); delete player.storage.clanlilun; }); } - player.markAuto('clanlilun',event.cards.slice().map(card=>card.name)); - const cards=event.cards.filterInD('d'); - if(cards.some(card=>player.hasUseTarget(card))){ - const {result:{bool,links}}=await player.chooseButton(['离论:是否使用其中的一张牌?',cards]).set('filterButton',button=>{ - return get.event('player').hasUseTarget(button.link); - }).set('ai',button=>{ - return get.event('player').getUseValue(button.link); - }); - if(bool){ - const card=links[0]; - player.$gain2(card,false); + player.markAuto( + "clanlilun", + event.cards.slice().map((card) => card.name) + ); + const cards = event.cards.filterInD("d"); + if (cards.some((card) => player.hasUseTarget(card))) { + const { + result: { bool, links }, + } = await player + .chooseButton(["离论:是否使用其中的一张牌?", cards]) + .set("filterButton", (button) => { + return get.event("player").hasUseTarget(button.link); + }) + .set("ai", (button) => { + return get.event("player").getUseValue(button.link); + }); + if (bool) { + const card = links[0]; + player.$gain2(card, false); await game.asyncDelayx(); - await player.chooseUseTarget(true,card,false); + await player.chooseUseTarget(true, card, false); } } }, - onremove:true, - intro:{content:'本回合已重铸过$'}, - ai:{ - order(item,player){ - let cards=player.getCards('h',card=>get.info('clanlilun').filterCard(card,player)&&player.getUseValue(card)>0); - cards=cards.filter(card=>cards.filter(i=>i.name==card.name).length>1); - if(!cards.length) return 1; - cards.sort((a,b)=>get.order(b)-get.order(a)); - return get.order(cards[0])-0.001; + onremove: true, + intro: { content: "本回合已重铸过$" }, + ai: { + order(item, player) { + let cards = player.getCards( + "h", + (card) => + get.info("clanlilun").filterCard(card, player) && player.getUseValue(card) > 0 + ); + cards = cards.filter((card) => cards.filter((i) => i.name == card.name).length > 1); + if (!cards.length) return 1; + cards.sort((a, b) => get.order(b) - get.order(a)); + return get.order(cards[0]) - 0.001; }, - result:{player:1}, + result: { player: 1 }, }, }, - clanjianji:{ - unique:true, - limited:true, - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - if(!event.player.isIn()) return false; - const targets=game.filterPlayer(target=>{ - return event.player.getPrevious()==target||event.player.getNext()==target; + clanjianji: { + unique: true, + limited: true, + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + if (!event.player.isIn()) return false; + const targets = game.filterPlayer((target) => { + return event.player.getPrevious() == target || event.player.getNext() == target; }); - if(!targets.length) return false; - const card=new lib.element.VCard({name:'sha'}); - return !targets.some(target=>{ - return target.getHistory('useCard').length; - })||(player.hasUseTarget(card)&&!targets.some(target=>{ - return game.hasPlayer2(current=>{ - return current.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.includes(target); - }).length; - }); - })); + if (!targets.length) return false; + const card = new lib.element.VCard({ name: "sha" }); + return ( + !targets.some((target) => { + return target.getHistory("useCard").length; + }) || + (player.hasUseTarget(card) && + !targets.some((target) => { + return game.hasPlayer2((current) => { + return current.getHistory("useCard", (evt) => { + return evt.targets && evt.targets.includes(target); + }).length; + }); + })) + ); }, - skillAnimation:true, - animationColor:'watar', - prompt2(event,player){ - let str=''; - const card=new lib.element.VCard({name:'sha'}); - const targets=game.filterPlayer(target=>{ - return event.player.getPrevious()==target||event.player.getNext()==target; - }),bool=(!targets.some(target=>{ - return target.getHistory('useCard').length; - })),goon=(player.hasUseTarget(card)&&!targets.some(target=>{ - return game.hasPlayer2(current=>{ - return current.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.includes(target); - }).length; - }); - })); - if(bool){ - if(goon) str+='你可以'; - str+='与'+get.translation(get.translation(event.player))+'各摸一张牌'; + skillAnimation: true, + animationColor: "watar", + prompt2(event, player) { + let str = ""; + const card = new lib.element.VCard({ name: "sha" }); + const targets = game.filterPlayer((target) => { + return event.player.getPrevious() == target || event.player.getNext() == target; + }), + bool = !targets.some((target) => { + return target.getHistory("useCard").length; + }), + goon = + player.hasUseTarget(card) && + !targets.some((target) => { + return game.hasPlayer2((current) => { + return current.getHistory("useCard", (evt) => { + return evt.targets && evt.targets.includes(target); + }).length; + }); + }); + if (bool) { + if (goon) str += "你可以"; + str += "与" + get.translation(get.translation(event.player)) + "各摸一张牌"; } - if(goon){ - if(bool) str+=',然后你可以'; - str+='视为使用一张【杀】'; + if (goon) { + if (bool) str += ",然后你可以"; + str += "视为使用一张【杀】"; } return str; }, - check(event,player){ - const card=new lib.element.VCard({name:'sha'}); - const targets=game.filterPlayer(target=>{ - return event.player.getPrevious()==target||event.player.getNext()==target; - }),bool=(!targets.some(target=>{ - return target.getHistory('useCard').length; - })),goon=(player.hasUseTarget(card)&&!targets.some(target=>{ - return game.hasPlayer2(current=>{ - return current.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.includes(target); - }).length; - }); - })); - return (bool&&(get.attitude(player,event.player)>0||event.player.countCards('h')>player.countCards('h')))||(goon&&player.hasValueTarget(card)); + check(event, player) { + const card = new lib.element.VCard({ name: "sha" }); + const targets = game.filterPlayer((target) => { + return event.player.getPrevious() == target || event.player.getNext() == target; + }), + bool = !targets.some((target) => { + return target.getHistory("useCard").length; + }), + goon = + player.hasUseTarget(card) && + !targets.some((target) => { + return game.hasPlayer2((current) => { + return current.getHistory("useCard", (evt) => { + return evt.targets && evt.targets.includes(target); + }).length; + }); + }); + return ( + (bool && + (get.attitude(player, event.player) > 0 || + event.player.countCards("h") > player.countCards("h"))) || + (goon && player.hasValueTarget(card)) + ); }, - logTarget:'player', - async content(event,trigger,player){ - player.awakenSkill('clanjianji'); - const card=new lib.element.VCard({name:'sha'}); - const targets=game.filterPlayer(target=>{ - return trigger.player.getPrevious()==target||trigger.player.getNext()==target; - }),boolx=(!targets.some(target=>{ - return target.getHistory('useCard').length; - })),goon=(player.hasUseTarget(card)&&!targets.some(target=>{ - return game.hasPlayer2(current=>{ - return current.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.includes(target); - }).length; - }); - })); - if(boolx){ - let draw=false; - if(goon){ - const {result:{bool}}=await player.chooseBool('是否与'+get.translation(trigger.player)+'各摸一张牌?').set('choice',get.attitude(player,trigger.player)>0||trigger.player.countCards('h')>player.countCards('h')); - if(bool) draw=true; - } - else draw=true; - if(draw){ - await player.draw('nodelay'); + logTarget: "player", + async content(event, trigger, player) { + player.awakenSkill("clanjianji"); + const card = new lib.element.VCard({ name: "sha" }); + const targets = game.filterPlayer((target) => { + return ( + trigger.player.getPrevious() == target || trigger.player.getNext() == target + ); + }), + boolx = !targets.some((target) => { + return target.getHistory("useCard").length; + }), + goon = + player.hasUseTarget(card) && + !targets.some((target) => { + return game.hasPlayer2((current) => { + return current.getHistory("useCard", (evt) => { + return evt.targets && evt.targets.includes(target); + }).length; + }); + }); + if (boolx) { + let draw = false; + if (goon) { + const { + result: { bool }, + } = await player + .chooseBool("是否与" + get.translation(trigger.player) + "各摸一张牌?") + .set( + "choice", + get.attitude(player, trigger.player) > 0 || + trigger.player.countCards("h") > player.countCards("h") + ); + if (bool) draw = true; + } else draw = true; + if (draw) { + await player.draw("nodelay"); await trigger.player.draw(); } } - if(goon) await player.chooseUseTarget(card,false,!boolx); + if (goon) await player.chooseUseTarget(card, false, !boolx); }, }, //族吴乔 - clanqiajue:{ - audio:2, - trigger:{player:'phaseDrawBegin'}, - filter(event,player){ - return player.countCards('he',card=>{ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.color(card,player)=='black'&&lib.filter.cardDiscardable(card,player); - })>0; + clanqiajue: { + audio: 2, + trigger: { player: "phaseDrawBegin" }, + filter(event, player) { + return ( + player.countCards("he", (card) => { + if (_status.connectMode && get.position(card) == "h") return true; + return ( + get.color(card, player) == "black" && lib.filter.cardDiscardable(card, player) + ); + }) > 0 + ); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool}}=await player.chooseToDiscard((card,player)=>{ - return get.color(card,player)=='black'&&lib.filter.cardDiscardable(card,player); - },'he') - .set('prompt','当前手牌点数和为'+player.getCards('h').reduce((sum,card)=>sum+get.number(card),0)+','+get.prompt('clanqiajue')) - .set('prompt2',lib.translate.clanqiajue_info.slice(lib.translate.clanqiajue_info.indexOf('弃置')).slice(0,-1)) - .set('ai',card=>{ - const player=get.event('player'),goon=get.position(card)=='h'; - let num=player.getCards('h').reduce((sum,card)=>sum+get.number(card),0); - if(num-(goon?get.number(card):0)>30) return 0; - return goon?get.number(card):1/(get.value(card)||0.5); - }).set('logSkill','clanqiajue'); - if(bool){ - player.when({player:['phaseDrawEnd','phaseDrawCancelled','phaseUseSkipped']}) - .filter(evt=>evt==trigger) - .then(()=>{ - const cards=player.getCards('h'),num=cards.reduce((sum,card)=>sum+get.number(card),0); - if(cards.length) player.showCards(cards,get.translation(player)+'【跒倔】展示'); - if(num>30){ - player.popup('杯具'); - lib.skill.chenliuwushi.change(player,-2); - } - else{ - player.popup('洗具'); - const next=player.phaseDraw(); - event.next.remove(next); - trigger.getParent('phase').next.push(next); - } + direct: true, + async content(event, trigger, player) { + const { + result: { bool }, + } = await player + .chooseToDiscard((card, player) => { + return ( + get.color(card, player) == "black" && lib.filter.cardDiscardable(card, player) + ); + }, "he") + .set( + "prompt", + "当前手牌点数和为" + + player.getCards("h").reduce((sum, card) => sum + get.number(card), 0) + + "," + + get.prompt("clanqiajue") + ) + .set( + "prompt2", + lib.translate.clanqiajue_info + .slice(lib.translate.clanqiajue_info.indexOf("弃置")) + .slice(0, -1) + ) + .set("ai", (card) => { + const player = get.event("player"), + goon = get.position(card) == "h"; + let num = player.getCards("h").reduce((sum, card) => sum + get.number(card), 0); + if (num - (goon ? get.number(card) : 0) > 30) return 0; + return goon ? get.number(card) : 1 / (get.value(card) || 0.5); }) + .set("logSkill", "clanqiajue"); + if (bool) { + player + .when({ + player: ["phaseDrawEnd", "phaseDrawCancelled", "phaseUseSkipped"], + }) + .filter((evt) => evt == trigger) + .then(() => { + const cards = player.getCards("h"), + num = cards.reduce((sum, card) => sum + get.number(card), 0); + if (cards.length) + player.showCards(cards, get.translation(player) + "【跒倔】展示"); + if (num > 30) { + player.popup("杯具"); + lib.skill.chenliuwushi.change(player, -2); + } else { + player.popup("洗具"); + const next = player.phaseDraw(); + event.next.remove(next); + trigger.getParent("phase").next.push(next); + } + }); } }, }, //族荀攸 - clanbaichu:{ - derivation:'qice', - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - const storage=player.storage.clanbaichu||{}; - if(Object.values(storage).includes(event.card.name)) return true; - const suit=get.suit(event.card); - if(suit=='none') return false; - if(!player.hasSkill('qice')) return true; - const key=`${suit}+${get.type2(event.card)}`; - return !(key in storage) + clanbaichu: { + derivation: "qice", + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + const storage = player.storage.clanbaichu || {}; + if (Object.values(storage).includes(event.card.name)) return true; + const suit = get.suit(event.card); + if (suit == "none") return false; + if (!player.hasSkill("qice")) return true; + const key = `${suit}+${get.type2(event.card)}`; + return !(key in storage); }, - forced:true, - content(){ - 'step 0' - var storage=player.storage.clanbaichu||{},suit=get.suit(trigger.card); - if(suit!='none'){ - var key=`${suit}+${get.type2(trigger.card)}`; - if(key in storage){ - if(!player.hasSkill('qice')){ - player.addTempSkills('qice','roundStart'); - player.popup('奇策'); + forced: true, + content() { + "step 0"; + var storage = player.storage.clanbaichu || {}, + suit = get.suit(trigger.card); + if (suit != "none") { + var key = `${suit}+${get.type2(trigger.card)}`; + if (key in storage) { + if (!player.hasSkill("qice")) { + player.addTempSkills("qice", "roundStart"); + player.popup("奇策"); // game.log(player,'获得了技能','#g【奇策】'); } event.goto(2); - } - else{ - var list=lib.inpile.filter(name=>get.type(name)=='trick'); + } else { + var list = lib.inpile.filter((name) => get.type(name) == "trick"); list.removeArray(Object.values(storage)); - if(list.length>0){ - var dialog=['百出:选择记录一种普通锦囊牌',[list,'vcard']]; - player.chooseButton(dialog,true).set('ai',function(button){ - var player=_status.event.player,name=button.link[2]; - if(name==_status.event.getTrigger().card.name) return 1919810; - if(name=='wuxie') return 114514; - return get.effect(player,{name:name},player,player)*(1+player.countCards('hs',name)); + if (list.length > 0) { + var dialog = ["百出:选择记录一种普通锦囊牌", [list, "vcard"]]; + player.chooseButton(dialog, true).set("ai", function (button) { + var player = _status.event.player, + name = button.link[2]; + if (name == _status.event.getTrigger().card.name) return 1919810; + if (name == "wuxie") return 114514; + return ( + get.effect(player, { name: name }, player, player) * + (1 + player.countCards("hs", name)) + ); }); - } - else event.goto(2); + } else event.goto(2); } - } - else event.goto(2); - 'step 1' - if(result.bool){ - var key=`${get.suit(trigger.card)}+${get.type2(trigger.card)}`,name=result.links[0][2]; - if(!player.storage.clanbaichu) player.storage.clanbaichu={}; - player.storage.clanbaichu[key]=name; - player.markSkill('clanbaichu'); - game.log(player,'记录了','#y'+get.translation(name)); + } else event.goto(2); + "step 1"; + if (result.bool) { + var key = `${get.suit(trigger.card)}+${get.type2(trigger.card)}`, + name = result.links[0][2]; + if (!player.storage.clanbaichu) player.storage.clanbaichu = {}; + player.storage.clanbaichu[key] = name; + player.markSkill("clanbaichu"); + game.log(player, "记录了", "#y" + get.translation(name)); game.delayx(); } - 'step 2' - if(Object.values(player.getStorage('clanbaichu')).includes(trigger.card.name)){ + "step 2"; + if (Object.values(player.getStorage("clanbaichu")).includes(trigger.card.name)) { player.chooseDrawRecover(true); } }, - intro:{ - markcount(storage){ + intro: { + markcount(storage) { return Object.keys(storage).length; }, - content(storage){ - if(!storage) return '当前暂无记录'; - const keys=Object.keys(storage).map(i=>i.split('+')); - keys.sort((a,b)=>{ - if(a[0]!=b[0]) return lib.suit.indexOf(b[0])-lib.suit.indexOf(a[0]); - return lib.sort.name(a[1],b[1]); + content(storage) { + if (!storage) return "当前暂无记录"; + const keys = Object.keys(storage).map((i) => i.split("+")); + keys.sort((a, b) => { + if (a[0] != b[0]) return lib.suit.indexOf(b[0]) - lib.suit.indexOf(a[0]); + return lib.sort.name(a[1], b[1]); }); - return keys.map(item=>{ - return `
            • ${get.translation(item[0])}+${get.translation(item[1])}:【${get.translation(storage[item.join('+')])}】`; - }).join('
              '); + return keys + .map((item) => { + return `
            • ${get.translation(item[0])}+${get.translation( + item[1] + )}:【${get.translation(storage[item.join("+")])}】`; + }) + .join("
              "); }, }, }, //族王沦 - clanqiuxin:{ - audio:2, - enable:'phaseUse', - filterTarget:lib.filter.notMe, - usable:1, - content(){ - 'step 0' - var str=get.translation(player); - target.chooseControl().set('choiceList',[ - str+'下次对你使用【杀】后,其视为对你使用任意普通锦囊牌', - str+'下次对你使用任意普通锦囊牌后,其视为对你使用【杀】', - ]).set('ai',function(){ - var target=_status.event.player; - var player=_status.event.target; - var num1=get.effect(target,get.autoViewAs({name:'sha'},[]),player,player); - if(!player.canUse(get.autoViewAs({name:'sha'},[]),target)) num1=0; - var num2=0; - for(var name of lib.inpile){ - if(get.type(name)!='trick') continue; - if(!player.canUse(get.autoViewAs({name:name},[]),target)) continue; - if(num2=num2?1:0; - }).set('target',player); - 'step 1' - player.addSkill('clanqiuxin_effect'); - player.markAuto('clanqiuxin_effect',[[target,result.index]]); + clanqiuxin: { + audio: 2, + enable: "phaseUse", + filterTarget: lib.filter.notMe, + usable: 1, + content() { + "step 0"; + var str = get.translation(player); + target + .chooseControl() + .set("choiceList", [ + str + "下次对你使用【杀】后,其视为对你使用任意普通锦囊牌", + str + "下次对你使用任意普通锦囊牌后,其视为对你使用【杀】", + ]) + .set("ai", function () { + var target = _status.event.player; + var player = _status.event.target; + var num1 = get.effect( + target, + get.autoViewAs({ name: "sha" }, []), + player, + player + ); + if (!player.canUse(get.autoViewAs({ name: "sha" }, []), target)) num1 = 0; + var num2 = 0; + for (var name of lib.inpile) { + if (get.type(name) != "trick") continue; + if (!player.canUse(get.autoViewAs({ name: name }, []), target)) continue; + if ( + num2 < + get.effect(target, get.autoViewAs({ name: name }, []), player, player) + ) + num2 = get.effect( + target, + get.autoViewAs({ name: name }, []), + player, + player + ); + } + return num1 >= num2 ? 1 : 0; + }) + .set("target", player); + "step 1"; + player.addSkill("clanqiuxin_effect"); + player.markAuto("clanqiuxin_effect", [[target, result.index]]); }, - ai:{ - order:9, - result:{ - target(player,target){ - var cards=player.getCards('hs',card=>{ - if(get.name(card,player)!='sha'&&get.type(card,player)!='trick') return false; + ai: { + order: 9, + result: { + target(player, target) { + var cards = player.getCards("hs", (card) => { + if (get.name(card, player) != "sha" && get.type(card, player) != "trick") + return false; return player.hasValueTarget(card); }); - if(cards.some(card=>player.canUse(card,target)&&get.effect(target,card,player,player)>0)){ - var att=get.attitude(player,target); - if(att>0) return 9; - if(att<0) return -6; + if ( + cards.some( + (card) => + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ) + ) { + var att = get.attitude(player, target); + if (att > 0) return 9; + if (att < 0) return -6; return 0; - } - else{ - var att=get.attitude(player,target); - if(att<0) return -3; - if(att>0) return 1; + } else { + var att = get.attitude(player, target); + if (att < 0) return -3; + if (att > 0) return 1; return 2; } }, }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - intro:{ - content(storage,player){ - var str=''; - for(var i=0;i{ - return player.getStorage('clanqiuxin_effect').some(list=>list[0]==target&&list[1]==0); - }); - if(get.type(event.card)=='trick') return event.targets.some(target=>{ - return player.getStorage('clanqiuxin_effect').some(list=>list[0]==target&&list[1]==1); - }); + trigger: { player: "useCardAfter" }, + filter(event, player) { + if (!event.targets || !event.targets.length) return false; + if (event.card.name == "sha") + return event.targets.some((target) => { + return player + .getStorage("clanqiuxin_effect") + .some((list) => list[0] == target && list[1] == 0); + }); + if (get.type(event.card) == "trick") + return event.targets.some((target) => { + return player + .getStorage("clanqiuxin_effect") + .some((list) => list[0] == target && list[1] == 1); + }); return false; }, - forced:true, - popup:false, - content(){ - 'step 0' + forced: true, + popup: false, + content() { + "step 0"; var list; - if(trigger.card.name=='sha') list=player.getStorage('clanqiuxin_effect').filter(listx=>trigger.targets.includes(listx[0])&&listx[1]==0); - if(get.type(trigger.card)=='trick') list=player.getStorage('clanqiuxin_effect').filter(listx=>trigger.targets.includes(listx[0])&&listx[1]==1); - player.unmarkAuto('clanqiuxin_effect',list); - var targets=list.map(listx=>listx[0]); - event.targets=targets; - 'step 1' - var target=event.targets.shift(); - event.target=target; - var list=[]; - for(var name of lib.inpile){ - if(name!='sha'&&get.type(name)!='trick') continue; - if(trigger.card.name=='sha'&&get.type(name)!='trick') continue; - if(name=='sha'&&get.type(trigger.card)!='trick') continue; - if(!player.canUse(get.autoViewAs({name:name},[]),target)) continue; - list.push([get.translation(get.type(name)),'',name]); + if (trigger.card.name == "sha") + list = player + .getStorage("clanqiuxin_effect") + .filter((listx) => trigger.targets.includes(listx[0]) && listx[1] == 0); + if (get.type(trigger.card) == "trick") + list = player + .getStorage("clanqiuxin_effect") + .filter((listx) => trigger.targets.includes(listx[0]) && listx[1] == 1); + player.unmarkAuto("clanqiuxin_effect", list); + var targets = list.map((listx) => listx[0]); + event.targets = targets; + "step 1"; + var target = event.targets.shift(); + event.target = target; + var list = []; + for (var name of lib.inpile) { + if (name != "sha" && get.type(name) != "trick") continue; + if (trigger.card.name == "sha" && get.type(name) != "trick") continue; + if (name == "sha" && get.type(trigger.card) != "trick") continue; + if (!player.canUse(get.autoViewAs({ name: name }, []), target)) continue; + list.push([get.translation(get.type(name)), "", name]); } - if(!list.length) event.goto(3); - else{ - player.chooseButton(['求心:视为对'+get.translation(target)+'使用一张牌',[list,'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - var target=_status.event.target; - return get.effect(target,{name:button.link[2],nature:button.link[3]},player,player); - }).set('target',target); + if (!list.length) event.goto(3); + else { + player + .chooseButton( + [ + "求心:视为对" + get.translation(target) + "使用一张牌", + [list, "vcard"], + ], + true + ) + .set("ai", function (button) { + var player = _status.event.player; + var target = _status.event.target; + return get.effect( + target, + { + name: button.link[2], + nature: button.link[3], + }, + player, + player + ); + }) + .set("target", target); } - 'step 2' - if(result.bool){ - var card={ - name:result.links[0][2], - nature:result.links[0][3], + "step 2"; + if (result.bool) { + var card = { + name: result.links[0][2], + nature: result.links[0][3], }; - player.useCard(card,target,false); + player.useCard(card, target, false); } - 'step 3' - if(event.targets.length) event.goto(1); - else if(!player.getStorage('clanqiuxin_effect').length) player.removeSkill('clanqiuxin_effect'); + "step 3"; + if (event.targets.length) event.goto(1); + else if (!player.getStorage("clanqiuxin_effect").length) + player.removeSkill("clanqiuxin_effect"); }, }, }, }, - clanjianyuan:{ - inherit:'clanchenya', - filter(event,player){ - for(var phase of lib.phaseName){ - var evt=event.getParent(phase); - if(evt&&evt.name==phase){ - if(event.player.getHistory('useCard',evtx=>evtx.getParent(phase)==evt).length) return lib.skill.clanchenya.filter(event,player); + clanjianyuan: { + inherit: "clanchenya", + filter(event, player) { + for (var phase of lib.phaseName) { + var evt = event.getParent(phase); + if (evt && evt.name == phase) { + if ( + event.player.getHistory("useCard", (evtx) => evtx.getParent(phase) == evt) + .length + ) + return lib.skill.clanchenya.filter(event, player); } } return false; }, - content(){ - 'step 0' - var num=0; - for(var phase of lib.phaseName){ - var evt=trigger.getParent(phase); - if(evt&&evt.name==phase){ - num+=trigger.player.getHistory('useCard',evtx=>evtx.getParent(phase)==evt).length; + content() { + "step 0"; + var num = 0; + for (var phase of lib.phaseName) { + var evt = trigger.getParent(phase); + if (evt && evt.name == phase) { + num += trigger.player.getHistory( + "useCard", + (evtx) => evtx.getParent(phase) == evt + ).length; } } - trigger.player.chooseCard('是否重铸任意张牌名字数为'+num+'的牌?',[1,Infinity],'he',(card,player)=>_status.event.cards.includes(card)&&player.canRecast(card)).set('ai',card=>{ - var val=get.value(card); - return 6-val; - }).set('cards',trigger.player.getCards('he',card=>{ - return get.cardNameLength(card)==num; - })); - 'step 1' - if(result.bool) trigger.player.recast(result.cards); + trigger.player + .chooseCard( + "是否重铸任意张牌名字数为" + num + "的牌?", + [1, Infinity], + "he", + (card, player) => _status.event.cards.includes(card) && player.canRecast(card) + ) + .set("ai", (card) => { + var val = get.value(card); + return 6 - val; + }) + .set( + "cards", + trigger.player.getCards("he", (card) => { + return get.cardNameLength(card) == num; + }) + ); + "step 1"; + if (result.bool) trigger.player.recast(result.cards); }, }, //族钟毓 - clanjiejian:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget||get.type(event.card)=='equip') return false; - return get.cardNameLength(event.card)==player.getHistory('useCard').indexOf(event.getParent())+1; + clanjiejian: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget || get.type(event.card) == "equip") return false; + return ( + get.cardNameLength(event.card) == + player.getHistory("useCard").indexOf(event.getParent()) + 1 + ); }, - direct:true, - locked:false, - content(){ - 'step 0' - var num=get.cardNameLength(trigger.card); - event.num=num; - player.chooseTarget(get.prompt('clanjiejian'),'令一名目标角色摸'+get.cnNumber(num)+'张牌',function(card,player,target){ - return _status.event.getTrigger().targets.includes(target); - }).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('clanjiejian',target); + direct: true, + locked: false, + content() { + "step 0"; + var num = get.cardNameLength(trigger.card); + event.num = num; + player + .chooseTarget( + get.prompt("clanjiejian"), + "令一名目标角色摸" + get.cnNumber(num) + "张牌", + function (card, player, target) { + return _status.event.getTrigger().targets.includes(target); + } + ) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("clanjiejian", target); target.draw(num); } }, - ai:{ - threaten:3, - effect:{ - player(card,player,target){ - if(!target||typeof card!=='object'||player._clanjiejian_mod_temp||get.type(card)==='equip'|| - get.attitude(player,target)<=0||get.cardNameLength(card)!==player.getHistory('useCard').length+1) return; - let targets=[target],evt=_status.event.getParent('useCard'); + ai: { + threaten: 3, + effect: { + player(card, player, target) { + if ( + !target || + typeof card !== "object" || + player._clanjiejian_mod_temp || + get.type(card) === "equip" || + get.attitude(player, target) <= 0 || + get.cardNameLength(card) !== player.getHistory("useCard").length + 1 + ) + return; + let targets = [target], + evt = _status.event.getParent("useCard"); targets.addArray(ui.selected.targets); - if(evt&&evt.card==card) targets.addArray(evt.targets); - return [1,0.8*get.cardNameLength(card)/targets.length]; - } - } + if (evt && evt.card == card) targets.addArray(evt.targets); + return [1, (0.8 * get.cardNameLength(card)) / targets.length]; + }, + }, }, - mod:{ - aiOrder(player,card,num){ - if(typeof card=='object'&&get.type(card)!=='equip'){ - let cs=get.cardNameLength(card)-player.getHistory('useCard').length-1; - if(cs<0) return num; - if(cs>0) return num/3; - player._clanjiejian_mod_temp=true; - let bool=game.hasPlayer(target=>{ - if(get.attitude(player,target)<=0||!player.canUse(card,target,null,true)) return false; - return get.effect(target,card,player,player)+get.effect(target,{name:'draw'},player,player)>0; + mod: { + aiOrder(player, card, num) { + if (typeof card == "object" && get.type(card) !== "equip") { + let cs = get.cardNameLength(card) - player.getHistory("useCard").length - 1; + if (cs < 0) return num; + if (cs > 0) return num / 3; + player._clanjiejian_mod_temp = true; + let bool = game.hasPlayer((target) => { + if ( + get.attitude(player, target) <= 0 || + !player.canUse(card, target, null, true) + ) + return false; + return ( + get.effect(target, card, player, player) + + get.effect(target, { name: "draw" }, player, player) > + 0 + ); }); delete player._clanjiejian_mod_temp; - if(bool) return num+15; + if (bool) return num + 15; } }, }, }, - clanhuanghan:{ - audio:2, - trigger:{player:'damageEnd'}, - filter(event,player){ - if(!event.card) return false; - var num=get.cardNameLength(event.card); - return typeof num=='number'&&num>0; + clanhuanghan: { + audio: 2, + trigger: { player: "damageEnd" }, + filter(event, player) { + if (!event.card) return false; + var num = get.cardNameLength(event.card); + return typeof num == "number" && num > 0; }, - check(event,player){ - let num=get.cardNameLength(event.card)-player.getDamagedHp(); - if(num>=0) return true; - if(num<-1) return false; - if(player.hasSkill('clanbaozu',null,false,false)&&player.awakenedSkills.includes('clanbaozu')&&player.getHistory('useSkill',evt=>{ - return evt.skill=='clanhuanghan'; - }).length) return true; + check(event, player) { + let num = get.cardNameLength(event.card) - player.getDamagedHp(); + if (num >= 0) return true; + if (num < -1) return false; + if ( + player.hasSkill("clanbaozu", null, false, false) && + player.awakenedSkills.includes("clanbaozu") && + player.getHistory("useSkill", (evt) => { + return evt.skill == "clanhuanghan"; + }).length + ) + return true; return false; }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(get.cardNameLength(trigger.card)); - if(player.isDamaged()) player.chooseToDiscard(player.getDamagedHp(),'he',true); - 'step 1' - if(player.getHistory('useSkill',evt=>evt.skill=='clanhuanghan').length>1&&player.hasSkill('clanbaozu',null,false,false)&&player.awakenedSkills.includes('clanbaozu')){ - player.restoreSkill('clanbaozu'); - player.popup('保族'); - game.log(player,'恢复了技能','#【保族】'); + if (player.isDamaged()) player.chooseToDiscard(player.getDamagedHp(), "he", true); + "step 1"; + if ( + player.getHistory("useSkill", (evt) => evt.skill == "clanhuanghan").length > 1 && + player.hasSkill("clanbaozu", null, false, false) && + player.awakenedSkills.includes("clanbaozu") + ) { + player.restoreSkill("clanbaozu"); + player.popup("保族"); + game.log(player, "恢复了技能", "#【保族】"); } }, - ai:{ - threaten:3, - effect:{ - target(card,player,target){ - if(!get.tag(card,'damage')||player.hasSkillTag('jueqing',false,target)) return; - let num=get.cardNameLength(card)-target.getDamagedHp(); - if(num>0) return [1,num+0.1]; - } - } + ai: { + threaten: 3, + effect: { + target(card, player, target) { + if (!get.tag(card, "damage") || player.hasSkillTag("jueqing", false, target)) + return; + let num = get.cardNameLength(card) - target.getDamagedHp(); + if (num > 0) return [1, num + 0.1]; + }, + }, }, }, //族钟会 - clanyuzhi:{ - mod:{ - aiOrder(player,card,num){ - if(card.name=='tao') return num/114514; + clanyuzhi: { + mod: { + aiOrder(player, card, num) { + if (card.name == "tao") return num / 114514; }, }, - audio:2, - trigger:{global:'roundStart'}, - direct:true, - locked:true, - content(){ - 'step 0' - player.unmarkSkill('clanyuzhi'); - var num1=player.getRoundHistory('gain',evt=>{ - return evt.getParent().name=='draw'&&evt.getParent(2).name=='clanyuzhi'; - },1).reduce((sum,evt)=>sum+evt.cards.length,0); - var num2=player.getRoundHistory('gain',evt=>{ - return evt.getParent().name=='draw'&&evt.getParent(2).name=='clanyuzhi'; - },2).reduce((sum,evt)=>sum+evt.cards.length,0); - var num3=player.getRoundHistory('useCard',evt=>{ - return evt.cards&&evt.cards.length; - },1).reduce((sum,evt)=>sum+evt.cards.length,0); - event.num1=num1; - if(num1>0&&(num2>0&&num1>num2)||num1>num3){ - player.logSkill('clanyuzhi'); - if(num2>0&&num1>num2) game.log(player,'的野心已开始膨胀','#y('+num1+'张>'+num2+'张)'); - if(num1>num3) game.log(player,'的行动未达到野心','#y('+num3+'张<'+num1+'张)'); - if(player.hasSkill('clanbaozu',null,false,false)) player.chooseBool('迂志:是否失去〖保族〗?','若选择“否”,则你失去1点体力').set('choice',player.awakenedSkills.includes('clanbaozu')); - else event._result={bool:false}; + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + locked: true, + content() { + "step 0"; + player.unmarkSkill("clanyuzhi"); + if ( + player.countCards("h", (card) => { + return card.hasGaintag("clanyuzhi") && lib.filter.cardDiscardable(card, player); + }) + ) { + event.logged = true; + player.chooseToDiscard( + player.countCards("h"), + "h", + (card, player) => { + return card.hasGaintag("clanyuzhi"); + }, + true + ).logSkill = "clanyuzhi"; } - else event.goto(2); - 'step 1' - if(result.bool){ - player.removeSkills('clanbaozu'); - } - else player.loseHp(); - 'step 2' - if(!player.countCards('h')) event.finish(); - 'step 3' - player.chooseCard('迂志:请展示一张手牌','摸此牌牌名字数的牌。下一轮开始时,若本轮你使用的牌数或上一轮你以此法摸的牌数小于此牌牌名字数,则你失去1点体力。',function(card,player){ - var num=get.cardNameLength(card); - return typeof num=='number'&&num>0; - },true).set('logSkill','clanyuzhi').set('ai',function(card){ - if(_status.event.dying&&_status.event.num>0&&get.cardNameLength(card)>_status.event.num) return 1/get.cardNameLength(card);//怂 - return get.cardNameLength(card);//勇 - }).set('dying',player.hp+player.countCards('hs',{name:['tao','jiu']})<1).set('num',event.num1); - 'step 4' - if(result.bool){ - player.logSkill('clanyuzhi'); - player.showCards(result.cards,get.translation(player)+'发动了【迂志】'); + "step 1"; + player.removeGaintag("clanyuzhi"); + var num1 = player + .getRoundHistory( + "gain", + (evt) => { + return evt.getParent().name == "draw" && evt.getParent(2).name == "clanyuzhi"; + }, + 1 + ) + .reduce((sum, evt) => sum + evt.cards.length, 0); + var num2 = player + .getRoundHistory( + "gain", + (evt) => { + return evt.getParent().name == "draw" && evt.getParent(2).name == "clanyuzhi"; + }, + 2 + ) + .reduce((sum, evt) => sum + evt.cards.length, 0); + var num3 = player + .getRoundHistory( + "useCard", + (evt) => { + return evt.cards && evt.cards.length; + }, + 1 + ) + .reduce((sum, evt) => sum + evt.cards.length, 0); + event.num1 = num1; + if ((num1 > 0 && num2 > 0 && num1 > num2) || num1 > num3) { + if (!event.logged) player.logSkill("clanyuzhi"); + if (num2 > 0 && num1 > num2) + game.log(player, "的野心已开始膨胀", "#y(" + num1 + "张>" + num2 + "张)"); + if (num1 > num3) + game.log(player, "的行动未达到野心", "#y(" + num3 + "张<" + num1 + "张)"); + if (player.hasSkill("clanbaozu", null, false, false)) + player + .chooseBool("迂志:是否失去〖保族〗?", "若选择“否”,则你受到1点雷属性伤害") + .set("choice", player.awakenedSkills.includes("clanbaozu")); + else event._result = { bool: false }; + } else event.goto(3); + "step 2"; + if (result.bool) { + player.removeSkills("clanbaozu"); + } else player.damage(1, "thunder"); + "step 3"; + if (player.countCards("h")) { + player + .chooseCard( + "迂志:请展示一张手牌", + "摸此牌牌名字数的牌。下一轮开始时弃置此牌,若本轮你使用的牌数或上一轮你以此法摸的牌数小于此牌牌名字数,则你受到1点雷属性伤害或失去〖保族〗。", + function (card, player) { + var num = get.cardNameLength(card); + return typeof num == "number" && num > 0; + }, + true + ) + .set("ai", function (card) { + if ( + _status.event.dying && + _status.event.num > 0 && + get.cardNameLength(card) > _status.event.num + ) + return 1 / get.cardNameLength(card); //怂 + return get.cardNameLength(card); //勇 + }) + .set( + "dying", + player.hp + + player.countCards("hs", { + name: ["tao", "jiu"], + }) < + 1 + ) + .set("num", event.num1); + } else event.finish(); + "step 4"; + if (result.bool) { + player.logSkill("clanyuzhi"); + player.showCards(result.cards, get.translation(player) + "发动了【迂志】"); + player.addGaintag(result.cards, "clanyuzhi"); player.draw(get.cardNameLength(result.cards[0])); - player.storage.clanyuzhi=get.cardNameLength(result.cards[0]); - player.markSkill('clanyuzhi'); + player.storage.clanyuzhi = get.cardNameLength(result.cards[0]); + player.markSkill("clanyuzhi"); } }, - ai:{ - threaten:3, - nokeep:true, + ai: { + threaten: 3, + nokeep: true, }, - onremove:true, - intro:{content:'本轮野心:#张'}, + onremove: true, + intro: { content: "本轮野心:#张" }, }, - clanxieshu:{ - audio:2, - trigger:{player:'damageEnd',source:'damageSource'}, - filter(event,player){ - if(!event.card/*||player.isLinked()*/) return false; - if(game.getGlobalHistory('everything',evt=>{ - if(evt.name!='damage'||!evt.card) return false; - return evt.player==player||(evt.source&&evt.source==player); - }).indexOf(event)!=0) return false; - var num=get.cardNameLength(event.card); - return typeof num=='number'&&num>0&&player.countCards('he')>0; + clanxieshu: { + audio: 2, + trigger: { player: "damageEnd", source: "damageSource" }, + filter(event, player) { + if (!event.card || player.isLinked()) return false; + var num = get.cardNameLength(event.card); + return typeof num == "number" && num > 0 && player.countCards("he") > 0; }, - direct:true, - content(){ - 'step 0' - var num=get.cardNameLength(trigger.card),str=''; - if(player.getDamagedHp()>0) str+=('并摸'+get.cnNumber(player.getDamagedHp())+'张牌'); - player.chooseToDiscard(get.prompt('clanxieshu'),/*'横置武将牌,'+*/'弃置'+get.cnNumber(num)+'张牌'+str,'he',num).set('ai',function(card){ - var player=_status.event.player; - var num=_status.event.num; - var num2=player.getDamagedHp(); - if(num=(2+num-num2)) return lib.skill.zhiheng.check(card); - return 0; - }).set('num',num).logSkill='clanxieshu'; - 'step 1' - if(result.bool){ - //player.link(true); - if(player.getDamagedHp()>0) player.draw(player.getDamagedHp()); - } + async cost(event, trigger, player) { + var num = get.cardNameLength(trigger.card), + str = ""; + if (player.getDamagedHp() > 0) + str += ",然后摸" + get.cnNumber(player.getDamagedHp()) + "张牌"; + player + .chooseToDiscard( + get.prompt("clanxieshu"), + "横置武将牌并弃置" + get.cnNumber(num) + "张牌" + str, + "he", + num + ) + .set("ai", function (card) { + var player = _status.event.player; + var num = _status.event.num; + var num2 = player.getDamagedHp(); + if (!num2) return 0; + if (num < num2) return 8 - get.value(card); + if (num == num2 || num2 >= 2 + num - num2) return lib.skill.zhiheng.check(card); + return 0; + }) + .set("num", num) + .set("logSkill", "clanxieshu") + .forResult(); + }, + popup: false, + content() { + player.link(true); + if (player.getDamagedHp() > 0) player.draw(player.getDamagedHp()); + }, + ai: { threaten: 3 }, + group: "clanxieshu_ban", + subSkill: { + ban: { + audio: "clanxieshu", + trigger: { global: "dyingAfter" }, + filter(event, player) { + return !player.isTempBanned("clanxieshu"); + }, + forced: true, + locked: false, + content() { + player.tempBanSkill("clanxieshu"); + }, + }, }, - ai:{threaten:3}, }, //族王浑 - clanfuxun:{ - mod:{ - aiOrder(player,card,num){ - if(player.isPhaseUsing()&&get.type(card)=='equip'&&get.equipValue(card,player)>0) return num+3; + clanfuxun: { + mod: { + aiOrder(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, - filterCard:true, - position:'h', - discard:false, - lose:false, - delay:false, - selectCard(){ - var player=_status.event.player; - if(ui.selected.targets.length&&!ui.selected.targets[0].countGainableCards(player,'h')) return 1; - return [0,1]; + locked: false, + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "h", + discard: false, + lose: false, + delay: false, + selectCard() { + var player = _status.event.player; + if (ui.selected.targets.length && !ui.selected.targets[0].countGainableCards(player, "h")) + return 1; + return [0, 1]; }, - filterTarget(card,player,target){ - if(player==target) return false; - if(!ui.selected.cards.length) return target.countGainableCards(player,'h')>0; + filterTarget(card, player, target) { + if (player == target) return false; + if (!ui.selected.cards.length) return target.countGainableCards(player, "h") > 0; return true; }, - check(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); + check(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; + if (card.name == "du") return 20; return -1; } - if(card.name=='du') return 20; + if (card.name == "du") return 20; return -1; }, - content(){ - 'step 0' - if(cards.length){ - player.give(cards,target); + content() { + "step 0"; + if (cards.length) { + player.give(cards, target); + } else { + player.gainPlayerCard(target, "h", true); } - else{ - player.gainPlayerCard(target,'h',true); - } - 'step 1' - var evtx=event.getParent('phaseUse'); - if(player.countCards('h')==target.countCards('h')&&evtx&&!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; - })&&player.countCards('he')){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(player.hasUseTarget({name:name})) list.push(['基本','',name]); - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(player.hasUseTarget({name:name,nature:nature})) list.push(['基本','',name,nature]); + "step 1"; + var evtx = event.getParent("phaseUse"); + if ( + player.countCards("h") == target.countCards("h") && + evtx && + !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 + ); + }) && + player.countCards("he") + ) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (player.hasUseTarget({ name: name })) list.push(["基本", "", name]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + player.hasUseTarget({ + name: name, + nature: nature, + }) + ) + list.push(["基本", "", name, nature]); } } } - if(list.length){ - player.chooseButton(['是否将一张牌当做一种基本牌使用?',[list,'vcard']]).set('ai',button=>{ - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); - }); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card={ - name:result.links[0][2], - nature:result.links[0][3] + if (list.length) { + player + .chooseButton(["是否将一张牌当做一种基本牌使用?", [list, "vcard"]]) + .set("ai", (button) => { + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = { + name: result.links[0][2], + nature: result.links[0][3], }; - game.broadcastAll(function(card){ - lib.skill.clanfuxun_backup.viewAs=card; - },card); - var next=player.chooseToUse(); - next.set('openskilldialog','将一张牌当做'+get.translation(card)+'使用'); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','clanfuxun_backup'); - next.set('custom',{ - add:{}, - replace:{window(){}} + game.broadcastAll(function (card) { + lib.skill.clanfuxun_backup.viewAs = card; + }, card); + var next = player.chooseToUse(); + next.set("openskilldialog", "将一张牌当做" + get.translation(card) + "使用"); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "clanfuxun_backup"); + next.set("custom", { + add: {}, + replace: { window() {} }, }); - next.backup('clanfuxun_backup'); + next.backup("clanfuxun_backup"); } }, - ai:{ - order(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; + ai: { + order(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(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; + result: { + target(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.includes(target)){ - if(player.countCards('h')value!='出牌阶段限一次')) return false; - return event.player.countCards('h')>0; + filter(event, player) { + if (event.type != "player") return false; + var skill = event.sourceSkill || event.skill; + var info = get.info(skill); + if (info.charlotte) return false; + var translation = get.skillInfoTranslation(skill, event.player); + if (!translation) return false; + var match = translation.match(/“?出牌阶段限一次/g); + if (!match || match.every((value) => value != "出牌阶段限一次")) return false; + return event.player.countCards("h") > 0; }, - check(event,player){ - return get.attitude(player,event.player)>0; + check(event, player) { + return get.attitude(player, event.player) > 0; + }, + logTarget: "player", + content() { + "step 0"; + var num = trigger.player.countCards("h"); + trigger.player + .chooseCard( + "是否重铸任意张牌名字数为" + num + "的牌?", + [1, Infinity], + "he", + (card, player) => _status.event.cards.includes(card) && player.canRecast(card) + ) + .set("ai", (card) => { + var val = get.value(card); + return 6 - val; + }) + .set( + "cards", + trigger.player.getCards("he", (card) => { + return get.cardNameLength(card) == num; + }) + ); + "step 1"; + if (result.bool) trigger.player.recast(result.cards); }, - logTarget:'player', - content(){ - 'step 0' - var num=trigger.player.countCards('h'); - trigger.player.chooseCard('是否重铸任意张牌名字数为'+num+'的牌?',[1,Infinity],'he',(card,player)=>_status.event.cards.includes(card)&&player.canRecast(card)).set('ai',card=>{ - var val=get.value(card); - return 6-val; - }).set('cards',trigger.player.getCards('he',card=>{ - return get.cardNameLength(card)==num; - })); - 'step 1' - if(result.bool) trigger.player.recast(result.cards); - } }, //族王允 - clanjiexuan:{ - audio:2, - enable:'phaseUse', - limited:true, - zhuanhuanji:'number', - mark:true, - marktext:'☯', - intro:{ - markcount:()=>0, - content(storage){ - return '限定技,转换技。你可以将一张'+((storage||0)%2?'黑色牌当【过河拆桥】':'红色牌当【顺手牵羊】')+'使用。'; + clanjiexuan: { + audio: 2, + enable: "phaseUse", + limited: true, + zhuanhuanji: "number", + mark: true, + marktext: "☯", + intro: { + markcount: () => 0, + content(storage) { + return ( + "限定技,转换技。你可以将一张" + + ((storage || 0) % 2 ? "黑色牌当【过河拆桥】" : "红色牌当【顺手牵羊】") + + "使用。" + ); }, }, - viewAs(cards,player){ - var storage=player.storage.clanjiexuan; - var name=(storage||0)%2?'guohe':'shunshou'; - return {name:name}; + viewAs(cards, player) { + var storage = player.storage.clanjiexuan; + var name = (storage || 0) % 2 ? "guohe" : "shunshou"; + return { name: name }; }, - check(card){ - var player=_status.event.player; - var storage=player.storage.clanjiexuan; - var name=(storage||0)%2?'guohe':'shunshou'; - var fix=player.hasSkill('clanzhongliu')&&get.position(card)!='h'?2:1; - return (get.value({name:name},player)-get.value(card))*fix; + check(card) { + var player = _status.event.player; + var storage = player.storage.clanjiexuan; + var name = (storage || 0) % 2 ? "guohe" : "shunshou"; + var fix = player.hasSkill("clanzhongliu") && get.position(card) != "h" ? 2 : 1; + return (get.value({ name: name }, player) - get.value(card)) * fix; }, - position:'hes', - filterCard(card,player){ - var storage=player.storage.clanjiexuan; - return get.color(card)==((storage||0)%2?'black':'red'); + position: "hes", + filterCard(card, player) { + var storage = player.storage.clanjiexuan; + return get.color(card) == ((storage || 0) % 2 ? "black" : "red"); }, - prompt(){ - var storage=_status.event.player.storage.clanjiexuan; - if((storage||0)%2) return '将一张黑色牌当【过河拆桥】使用'; - return '将一张红色牌当【顺手牵羊】使用'; + prompt() { + var storage = _status.event.player.storage.clanjiexuan; + if ((storage || 0) % 2) return "将一张黑色牌当【过河拆桥】使用"; + return "将一张红色牌当【顺手牵羊】使用"; }, - skillAnimation:true, - animationColor:'thunder', - precontent(){ - 'step 0' - var skill='clanjiexuan'; + skillAnimation: true, + animationColor: "thunder", + precontent() { + "step 0"; + var skill = "clanjiexuan"; player.logSkill(skill); player.changeZhuanhuanji(skill); - player.awakenSkill(skill,true); + player.awakenSkill(skill, true); delete event.result.skill; }, - ai:{ - order(item,player){ - player=player||_status.event.player; - var storage=_status.event.player.storage.clanjiexuan; - var name=(storage||0)%2?'guohe':'shunshou'; - return get.order({name:name})+0.1; + ai: { + order(item, player) { + player = player || _status.event.player; + var storage = _status.event.player.storage.clanjiexuan; + var name = (storage || 0) % 2 ? "guohe" : "shunshou"; + return get.order({ name: name }) + 0.1; }, }, }, - clanmingjie:{ - init(player){ - player.addSkill('clanmingjie_record'); + clanmingjie: { + init(player) { + player.addSkill("clanmingjie_record"); }, - initSkill(skill){ - if(!lib.skill[skill]){ - lib.skill[skill]={ - charlotte:true, - mark:true, - marktext:'戒', - intro:{content:'已被$指定为【铭戒】目标'}, + initSkill(skill) { + if (!lib.skill[skill]) { + lib.skill[skill] = { + charlotte: true, + mark: true, + marktext: "戒", + intro: { content: "已被$指定为【铭戒】目标" }, }; - lib.translate[skill]='铭戒'; - lib.translate[skill+'_bg']='戒'; + lib.translate[skill] = "铭戒"; + lib.translate[skill + "_bg"] = "戒"; } }, - onremove(player){ - player.removeSkill('clanmingjie_record'); + onremove(player) { + player.removeSkill("clanmingjie_record"); }, - audio:2, - enable:'phaseUse', - limited:true, - filterTarget(card,player,target){ - return !target.hasSkill('clanmingjie_'+player.playerid); + audio: 2, + enable: "phaseUse", + limited: true, + filterTarget(card, player, target) { + return !target.hasSkill("clanmingjie_" + player.playerid); }, - skillAnimation:true, - animationColor:'thunder', - content(){ - player.awakenSkill('clanmingjie'); - player.addSkill('clanmingjie_effect'); - var skill='clanmingjie_'+player.playerid; - game.broadcastAll(lib.skill.clanmingjie.initSkill,skill); - target.addTempSkill(skill,{player:'phaseAfter'}); - target.storage[skill]=player; + skillAnimation: true, + animationColor: "thunder", + content() { + player.awakenSkill("clanmingjie"); + player.addSkill("clanmingjie_effect"); + var skill = "clanmingjie_" + player.playerid; + game.broadcastAll(lib.skill.clanmingjie.initSkill, skill); + target.addTempSkill(skill, { player: "phaseAfter" }); + target.storage[skill] = player; }, - ai:{ - order:10, - result:{ - target(player,target){ - if(player.hasSkill('clanzhongliu')||player.hp==1){ - if(!player.hasCard(card=>{ - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(!lib.filter.targetEnabled2(card,player,target)) return false; - return game.hasPlayer(current=>{ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0&¤t!=target&&get.effect(target,card,player,player)>0; - }); - },'hs')) return 0; + ai: { + order: 10, + result: { + target(player, target) { + if (player.hasSkill("clanzhongliu") || player.hp == 1) { + if ( + !player.hasCard((card) => { + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (!lib.filter.targetEnabled2(card, player, target)) return false; + return game.hasPlayer((current) => { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 && + current != target && + get.effect(target, card, player, player) > 0 + ); + }); + }, "hs") + ) + return 0; + } else { + if ( + player.countCards("hs", (card) => { + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (!lib.filter.targetEnabled2(card, player, target)) return false; + return game.hasPlayer((current) => { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 && + current != target && + get.effect(target, card, player, player) > 0 + ); + }); + }) < 3 + ) + return 0; } - else{ - if(player.countCards('hs',card=>{ - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(!lib.filter.targetEnabled2(card,player,target)) return false; - return game.hasPlayer(current=>{ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0&¤t!=target&&get.effect(target,card,player,player)>0; - }); - })<3) return 0; - } - return get.sgnAttitude(player,target); + return get.sgnAttitude(player, target); }, }, }, - subSkill:{ - effect:{ - charlotte:true, - audio:'clanmingjie', - trigger:{player:'useCard2'}, - filter(event,player){ - var card=event.card; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - return game.filterPlayer().some(current=>{ - if(!current.hasSkill('clanmingjie_'+player.playerid)) return false; - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&lib.filter.targetInRange(card,player,current); + subSkill: { + effect: { + charlotte: true, + audio: "clanmingjie", + trigger: { player: "useCard2" }, + filter(event, player) { + var card = event.card; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + return game.filterPlayer().some((current) => { + if (!current.hasSkill("clanmingjie_" + player.playerid)) return false; + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + lib.filter.targetInRange(card, player, current) + ); }); } return false; }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('clanmingjie_effect'),'令任意【铭戒】目标角色成为'+get.translation(trigger.card)+'的目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - if(trigger.targets.includes(target)||!target.isIn()||!target.hasSkill('clanmingjie_'+player.playerid)) return false; - return lib.filter.targetEnabled2(trigger.card,player,target)&&lib.filter.targetInRange(trigger.card,player,target); - },[1,Infinity]).set('ai',function(target){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,player,player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('clanmingjie_effect',targets); + direct: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("clanmingjie_effect"), + "令任意【铭戒】目标角色成为" + get.translation(trigger.card) + "的目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + if ( + trigger.targets.includes(target) || + !target.isIn() || + !target.hasSkill("clanmingjie_" + player.playerid) + ) + return false; + return ( + lib.filter.targetEnabled2(trigger.card, player, target) && + lib.filter.targetInRange(trigger.card, player, target) + ); + }, + [1, Infinity] + ) + .set("ai", function (target) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, player, player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("clanmingjie_effect", targets); trigger.targets.addArray(targets); - game.log(targets,'成为了',trigger.card,'的额外目标'); + game.log(targets, "成为了", trigger.card, "的额外目标"); } }, - group:'clanmingjie_targeted', + group: "clanmingjie_targeted", }, - targeted:{ - charlotte:true, - trigger:{global:'phaseEnd'}, - filter(event,player){ - var cards=player.getStorage('clanmingjie_record').slice(); - cards=cards.filterInD('d'); - if(!cards.length) return false; - var history=player.getHistory('useSkill',evt=>evt.skill=='clanmingjie'); - if(history.length){ - var targets=history.reduce((list,evt)=>list.addArray(evt.targets),[]); - if(event.player!=player&&targets.includes(event.player)) return true; + targeted: { + charlotte: true, + trigger: { global: "phaseEnd" }, + filter(event, player) { + var cards = player.getStorage("clanmingjie_record").slice(); + cards = cards.filterInD("d"); + if (!cards.length) return false; + var history = player.getHistory("useSkill", (evt) => evt.skill == "clanmingjie"); + if (history.length) { + var targets = history.reduce((list, evt) => list.addArray(evt.targets), []); + if (event.player != player && targets.includes(event.player)) return true; } - if(player.actionHistory.length>=2){ - for(var i=player.actionHistory.length-2;i>=0;i--){ - if(!player.actionHistory[i].isMe) continue; - var history2=player.actionHistory[i].useSkill.filter(evt=>evt.skill=='clanmingjie'); - if(history2.length){ - var targets2=history2.reduce((list,evt)=>list.addArray(evt.targets),[]); - if(targets2.includes(event.player)) return true; + if (player.actionHistory.length >= 2) { + for (var i = player.actionHistory.length - 2; i >= 0; i--) { + if (!player.actionHistory[i].isMe) continue; + var history2 = player.actionHistory[i].useSkill.filter( + (evt) => evt.skill == "clanmingjie" + ); + if (history2.length) { + var targets2 = history2.reduce( + (list, evt) => list.addArray(evt.targets), + [] + ); + if (targets2.includes(event.player)) return true; } break; } } return false; }, - forced:true, - popup:false, - content(){ - 'step 0' - var cards=player.getStorage('clanmingjie_record').slice(); - cards=cards.filterInD('d'); - event.cards=cards; - 'step 1' - player.chooseButton(['铭戒:是否使用这些牌?',cards]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link); - }).set('ai',button=>{ - return _status.event.player.getUseValue(button.link); - }); - 'step 2' - if(result.bool){ - var card=result.links[0]; + forced: true, + popup: false, + content() { + "step 0"; + var cards = player.getStorage("clanmingjie_record").slice(); + cards = cards.filterInD("d"); + event.cards = cards; + "step 1"; + player + .chooseButton(["铭戒:是否使用这些牌?", cards]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link); + }) + .set("ai", (button) => { + return _status.event.player.getUseValue(button.link); + }); + "step 2"; + if (result.bool) { + var card = result.links[0]; event.cards.remove(card); - player.$gain2(card,false); + player.$gain2(card, false); game.delayx(); - player.chooseUseTarget(card,true); - } - else event.finish(); - 'step 3' - if(event.cards.filter(card=>{ - return get.position(card,true)=='d'&&player.hasUseTarget(card); - }).length) event.goto(1); + player.chooseUseTarget(card, true); + } else event.finish(); + "step 3"; + if ( + event.cards.filter((card) => { + return get.position(card, true) == "d" && player.hasUseTarget(card); + }).length + ) + event.goto(1); }, }, - record:{ - charlotte:true, - trigger:{ - global:['shaMiss','eventNeutralized','useCard1','phaseAfter'], + record: { + charlotte: true, + trigger: { + global: ["shaMiss", "eventNeutralized", "useCard1", "phaseAfter"], }, - filter(event,player){ - if(event.name=='useCard'){ - return get.suit(event.card)=='spade'; + filter(event, player) { + if (event.name == "useCard") { + return get.suit(event.card) == "spade"; } - if(event.name=='phase') return true; - if(event.type!='card') return false; + if (event.name == "phase") return true; + if (event.type != "card") return false; return true; }, - silent:true, - forced:true, - content(){ - 'step 0' - if(trigger.name=='phase'){ + silent: true, + forced: true, + content() { + "step 0"; + if (trigger.name == "phase") { delete player.storage.clanmingjie_record; return; } - player.markAuto('clanmingjie_record',trigger.cards); - } + player.markAuto("clanmingjie_record", trigger.cards); + }, }, - } + }, }, //族钟琰 - clanguangu:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content(storage){ - return '转换技。出牌阶段限一次,你可以观看'+(storage?'一名角色的至多四张手':'牌堆顶的至多四张')+'牌,然后可以使用其中的一张牌。'; + clanguangu: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content(storage) { + return ( + "转换技。出牌阶段限一次,你可以观看" + + (storage ? "一名角色的至多四张手" : "牌堆顶的至多四张") + + "牌,然后可以使用其中的一张牌。" + ); }, }, - filter(event,player){ - if(player.storage.clanguangu) return game.hasPlayer(current=>{ - return current.countCards('h'); - }); + filter(event, player) { + if (player.storage.clanguangu) + return game.hasPlayer((current) => { + return current.countCards("h"); + }); return true; }, - chooseButton:{ - dialog(event,player){ - var dialog=ui.create.dialog('观骨:选择观看牌堆的牌数','hidden'); - if(player.storage.clanguangu) dialog.forceDirect=true; + chooseButton: { + dialog(event, player) { + var dialog = ui.create.dialog("观骨:选择观看牌堆的牌数", "hidden"); + if (player.storage.clanguangu) dialog.forceDirect = true; return dialog; }, - chooseControl(event,player){ - var list=[1,2,3,4].map(i=>{ - return get.cnNumber(i,true); + chooseControl(event, player) { + var list = [1, 2, 3, 4].map((i) => { + return get.cnNumber(i, true); }); - list.push('cancel2'); + list.push("cancel2"); return list; }, - check(button,player){ + check(button, player) { var ret; - if(!player.hasSkill('clanxiaoyong')) ret=4; - else{ - var list=[4,3,2,1]; - player.getHistory('useCard',evt=>{ - var len=get.cardNameLength(evt.card); + if (!player.hasSkill("clanxiaoyong")) ret = 4; + else { + var list = [4, 3, 2, 1]; + player.getHistory("useCard", (evt) => { + var len = get.cardNameLength(evt.card); list.remove(len); }); - if(list.length) ret=list[0]; - else ret=4; + if (list.length) ret = list[0]; + else ret = 4; } - return get.cnNumber(ret,true); + return get.cnNumber(ret, true); }, - backup(result,player){ + backup(result, player) { return { - audio:'clanguangu', - filterCard:()=>false, - selectCard:-1, - filterTarget(card,player,target){ - if(player.storage.clanguangu) return true; + audio: "clanguangu", + filterCard: () => false, + selectCard: -1, + filterTarget(card, player, target) { + if (player.storage.clanguangu) return true; return false; }, - selectTarget(){ - var player=_status.event.player; - if(player.storage.clanguangu) return 1; + selectTarget() { + var player = _status.event.player; + if (player.storage.clanguangu) return 1; return -1; }, - num:result.index+1, - content(){ - 'step 0' - player.changeZhuanhuanji('clanguangu'); - if(!targets.length){ - var num=lib.skill.clanguangu_backup.num; - var cards=get.cards(num); - event.cards=cards.slice(0); - while(cards.length) ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); + num: result.index + 1, + content() { + "step 0"; + player.changeZhuanhuanji("clanguangu"); + if (!targets.length) { + var num = lib.skill.clanguangu_backup.num; + var cards = get.cards(num); + event.cards = cards.slice(0); + while (cards.length) + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); game.updateRoundNumber(); event.goto(2); - } - else{ + } else { var ret; - if(!player.hasSkill('clanxiaoyong')) ret=4; - else{ - var list=[4,3,2,1]; - player.getHistory('useCard',evt=>{ - var len=get.cardNameLength(evt.card); + if (!player.hasSkill("clanxiaoyong")) ret = 4; + else { + var list = [4, 3, 2, 1]; + player.getHistory("useCard", (evt) => { + var len = get.cardNameLength(evt.card); list.remove(len); }); - if(list.length) ret=list[0]; - else ret=4; + if (list.length) ret = list[0]; + else ret = 4; } - player.choosePlayerCard(target,'h',true,[1,4]).set('prompt','观骨:观看'+get.translation(target)+'的至多四张牌').set('ai',button=>{ - if(ui.selected.buttons.length>=_status.event.num) return 0; - return Math.random(); - }).set('num',ret); + player + .choosePlayerCard(target, "h", true, [1, 4]) + .set( + "prompt", + "观骨:观看" + get.translation(target) + "的至多四张牌" + ) + .set("ai", (button) => { + if (ui.selected.buttons.length >= _status.event.num) return 0; + return Math.random(); + }) + .set("num", ret); } - 'step 1' - if(result.bool){ - event.cards=result.links; - } - else{ + "step 1"; + if (result.bool) { + event.cards = result.links; + } else { event.finish(); } - 'step 2' - var count=cards.length; - event.getParent().viewedCount=count; - player.chooseButton(['观骨:是否使用其中一张牌?',cards]).set('filterButton',button=>{ - var player=_status.event.player; - var card=button.link; - var cardx={ - name:get.name(card,get.owner(card)), - nature:get.nature(card,get.owner(card)), - cards:[card], - } - return player.hasUseTarget(cardx,null,false); - }).set('ai',button=>{ - var len=_status.event.len; - var card=button.link; - var fix=1; - if(get.cardNameLength(card)==len) fix=2; - return fix*_status.event.player.getUseValue(card); - }).set('len',function(){ - if(!player.hasSkill('clanxiaoyong')) return 0; - var list=[]; - player.getHistory('useCard',evt=>{ - var len=get.cardNameLength(evt.card); - list.add(len); - }); - if(!list.includes(count)) return count; - if(list.length) return list.randomGet(); - return 4; - }()); - 'step 3' - if(result.bool){ - var card=result.links[0]; + "step 2"; + var count = cards.length; + event.getParent().viewedCount = count; + player + .chooseButton(["观骨:是否使用其中一张牌?", cards]) + .set("filterButton", (button) => { + var player = _status.event.player; + var card = button.link; + var cardx = { + name: get.name(card, get.owner(card)), + nature: get.nature(card, get.owner(card)), + cards: [card], + }; + return player.hasUseTarget(cardx, null, false); + }) + .set("ai", (button) => { + var len = _status.event.len; + var card = button.link; + var fix = 1; + if (get.cardNameLength(card) == len) fix = 2; + return fix * _status.event.player.getUseValue(card); + }) + .set( + "len", + (function () { + if (!player.hasSkill("clanxiaoyong")) return 0; + var list = []; + player.getHistory("useCard", (evt) => { + var len = get.cardNameLength(evt.card); + list.add(len); + }); + if (!list.includes(count)) return count; + if (list.length) return list.randomGet(); + return 4; + })() + ); + "step 3"; + if (result.bool) { + var card = result.links[0]; cards.remove(card); - var cardx={ - name:get.name(card,get.owner(card)), - nature:get.nature(card,get.owner(card)), - cards:[card], - } - var next=player.chooseUseTarget(cardx,[card],true,false).set('oncard',(card)=>{ - var owner=_status.event.getParent().owner; - if(owner) owner.$throw(card.cards); - }); - if(card.name===cardx.name&&get.is.sameNature(card,cardx,true)) next.viewAs=false; - var owner=get.owner(card); - if(owner!=player&&get.position(card)=='h'){ - next.throw=false; - next.set('owner',owner); + var cardx = { + name: get.name(card, get.owner(card)), + nature: get.nature(card, get.owner(card)), + cards: [card], + }; + var next = player + .chooseUseTarget(cardx, [card], true, false) + .set("oncard", (card) => { + var owner = _status.event.getParent().owner; + if (owner) owner.$throw(card.cards); + }); + if (card.name === cardx.name && get.is.sameNature(card, cardx, true)) + next.viewAs = false; + var owner = get.owner(card); + if (owner != player && get.position(card) == "h") { + next.throw = false; + next.set("owner", owner); } } }, - ai:{ - order:10, - result:{ - target(player,target){ - return -Math.min(target.countCards('h'),4)/2; + ai: { + order: 10, + result: { + target(player, target) { + return -Math.min(target.countCards("h"), 4) / 2; }, }, - } - } + }, + }; }, - prompt(result,player){ - if(!player.storage.clanguangu) return '点击“确定”以观看牌堆顶牌'; - return '观骨:选择观看牌的目标'; + prompt(result, player) { + if (!player.storage.clanguangu) return "点击“确定”以观看牌堆顶牌"; + return "观骨:选择观看牌的目标"; }, }, - subSkill:{ - backup:{}, + subSkill: { + backup: {}, }, - ai:{ - order:10, - result:{ - player:1, - } + ai: { + order: 10, + result: { + player: 1, + }, }, }, - clanxiaoyong:{ - audio:2, - trigger:{ - player:'useCard', + clanxiaoyong: { + audio: 2, + trigger: { + player: "useCard", }, - filter(event,player){ - var len=get.cardNameLength(event.card); - if(player.hasHistory('useCard',function(evt){ - return evt!=event&&get.cardNameLength(evt.card)==len; - },event)) return false; - if(!player.getStat().skill.clanguangu) return false; - var history=player.getAllHistory('useSkill',evt=>{ - return evt.skill=='clanguangu_backup'; - }).map(evt=>evt.event); - if(!history.length) return false; - var num=0; - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - if(evt.viewedCount){ - num=evt.viewedCount; + filter(event, player) { + var len = get.cardNameLength(event.card); + if ( + player.hasHistory( + "useCard", + function (evt) { + return evt != event && get.cardNameLength(evt.card) == len; + }, + event + ) + ) + return false; + if (!player.getStat().skill.clanguangu) return false; + var history = player + .getAllHistory("useSkill", (evt) => { + return evt.skill == "clanguangu_backup"; + }) + .map((evt) => evt.event); + if (!history.length) return false; + var num = 0; + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + if (evt.viewedCount) { + num = evt.viewedCount; break; } } - if(num&&len==num) return true; + if (num && len == num) return true; return false; }, - forced:true, - content(){ - 'step 0' + forced: true, + content() { + "step 0"; delete player.getStat().skill.clanguangu; - game.log(player,'重置了','#g【观骨】'); + game.log(player, "重置了", "#g【观骨】"); }, - mod:{ - aiOrder(player,card,num){ - if(!player.hasSkill('clanguangu')||!player.getStat().skill.clanguangu) return; - var history=player.getAllHistory('useSkill',evt=>{ - return evt.skill=='clanguangu_backup'; - }).map(evt=>evt.event); - if(!history.length) return; - var numx=0; - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - if(evt.viewedCount){ - numx=evt.viewedCount; + ai: { + combo: "clanguangu", + }, + mod: { + aiOrder(player, card, num) { + if (!player.hasSkill("clanguangu") || !player.getStat().skill.clanguangu) return; + var history = player + .getAllHistory("useSkill", (evt) => { + return evt.skill == "clanguangu_backup"; + }) + .map((evt) => evt.event); + if (!history.length) return; + var numx = 0; + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + if (evt.viewedCount) { + numx = evt.viewedCount; break; } } - if(numx==get.cardNameLength(card)){ - if(!player.hasHistory('useCard',evt=>{ - return numx==get.cardNameLength(evt.card); - })){ - return num+9; + if (numx == get.cardNameLength(card)) { + if ( + !player.hasHistory("useCard", (evt) => { + return numx == get.cardNameLength(evt.card); + }) + ) { + return num + 9; } } }, - } + }, }, - clanbaozu:{ - audio:2, - audioname:['clan_zhongyan','clan_zhonghui','clan_zhongyu'], - trigger:{global:'dying'}, - clanSkill:true, - limited:true, - skillAnimation:true, - animationColor:'water', - filter(event,player){ - return (event.player==player||event.player.hasClan('颍川钟氏'))&&event.player.hp<=0&&!event.player.isLinked(); + clanbaozu: { + audio: 2, + audioname: ["clan_zhongyan", "clan_zhonghui", "clan_zhongyu"], + trigger: { global: "dying" }, + clanSkill: true, + limited: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return ( + (event.player == player || event.player.hasClan("颍川钟氏")) && + event.player.hp <= 0 && + !event.player.isLinked() + ); }, - logTarget:'player', - check(event,player){ - return lib.skill.wanlan.check(event,player); + logTarget: "player", + check(event, player) { + return lib.skill.wanlan.check(event, player); }, - content(){ - 'step 0' - player.awakenSkill('clanbaozu'); - 'step 1' + content() { + "step 0"; + player.awakenSkill("clanbaozu"); + "step 1"; trigger.player.link(true); trigger.player.recover(); }, }, //族王淩 - clanbolong:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('he')>0; + clanbolong: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("he") > 0; }, - filterTarget:lib.filter.notMe, - content(){ - 'step 0' - var num=player.countCards('h'); - var str='是否交给其'+get.cnNumber(num)+'张牌,然后视为你对其使用一张【酒】?或者点击“取消”,令其交给你一张牌,然后其视为对你使用一张雷【杀】。'; - if(!num||target.countCards('he'){ - if(_status.event.canGive) return 5+Math.max(0,3-_status.event.player.hp)/1.5-get.value(card); - return 0; - }).set('canGive',function(){ - if(get.attitude(target,player)>1) return true; - if(!player.hasSha()&&player.countCards('h')<=4) return true; - var sha={name:'sha',nature:'thunder',isCard:true}; - if(game.hasPlayer(current=>{ - return player.canUse(sha,current,true,true)&&get.effect(current,sha,player,target)<0&&!current.countCards('hs',['shan','caochuan']); - })) return false; - return true; - }()); - 'step 1' - if(result.bool){ - var cards=result.cards; - target.give(cards,player); - if(lib.filter.targetEnabled2({name:'jiu',isCard:true},target,player)) target.useCard({name:'jiu',isCard:true},player,false); + filterTarget: lib.filter.notMe, + content() { + "step 0"; + var num = player.countCards("h"); + var str = + "是否交给其" + + get.cnNumber(num) + + "张牌,然后视为你对其使用一张【酒】?或者点击“取消”,令其交给你一张牌,然后其视为对你使用一张雷【杀】。"; + if (!num || target.countCards("he") < num) event._result = { bool: false }; + else + target + .chooseCard(get.translation(player) + "对你发动了【驳龙】", str, num, "he") + .set("ai", (card) => { + if (_status.event.canGive) + return ( + 5 + Math.max(0, 3 - _status.event.player.hp) / 1.5 - get.value(card) + ); + return 0; + }) + .set( + "canGive", + (function () { + if (get.attitude(target, player) > 1) return true; + if (!player.hasSha() && player.countCards("h") <= 4) return true; + var sha = { + name: "sha", + nature: "thunder", + isCard: true, + }; + if ( + game.hasPlayer((current) => { + return ( + player.canUse(sha, current, true, true) && + get.effect(current, sha, player, target) < 0 && + !current.countCards("hs", ["shan", "caochuan"]) + ); + }) + ) + return false; + return true; + })() + ); + "step 1"; + if (result.bool) { + var cards = result.cards; + target.give(cards, player); + if (lib.filter.targetEnabled2({ name: "jiu", isCard: true }, target, player)) + target.useCard({ name: "jiu", isCard: true }, player, false); event.finish(); + } else { + player.chooseCard( + "驳龙:交给" + get.translation(target) + "一张牌", + get.translation(target) + "拒绝给牌,请交给其一张牌然后视为对其使用一张雷【杀】", + true, + "he" + ); } - else{ - player.chooseCard('驳龙:交给'+get.translation(target)+'一张牌',get.translation(target)+'拒绝给牌,请交给其一张牌然后视为对其使用一张雷【杀】',true,'he'); - } - 'step 2' - if(result.bool){ - var cards=result.cards; - player.give(cards,target); - var sha={name:'sha',nature:'thunder',isCard:true}; - if(player.canUse(sha,target,false,false)) player.useCard(sha,target,false); + "step 2"; + if (result.bool) { + var cards = result.cards; + player.give(cards, target); + var sha = { + name: "sha", + nature: "thunder", + isCard: true, + }; + if (player.canUse(sha, target, false, false)) player.useCard(sha, target, false); } }, - ai:{ - order(item,player){ - return get.order({name:'jiu'})+0.01; + ai: { + order(item, player) { + return get.order({ name: "jiu" }) + 0.01; }, - threaten:2, - result:{ - target(player,target){ - if(player.hasCard(card=>{ - return get.value(card)<5&&!['shan','tao','jiu','wuxie','caochuan'].includes(get.name(card)); - },'he')) return -1; + threaten: 2, + result: { + target(player, target) { + if ( + player.hasCard((card) => { + return ( + get.value(card) < 5 && + !["shan", "tao", "jiu", "wuxie", "caochuan"].includes(get.name(card)) + ); + }, "he") + ) + return -1; return 0; }, - } - } + }, + }, }, - clanzhongliu:{ - audio:2, - audioname:['clan_wangling','clan_wangyun','clan_wanghun','clan_wanglun','clan_wangguang','clan_wangmingshan'], - trigger:{player:'useCard'}, - forced:true, - clanSkill:true, - filter(event,player){ - if(!event.cards.length) return true; - return !game.hasPlayer2(current=>{ - if(!current.hasClan('太原王氏')&¤t!=player) return false; - return current.hasHistory('lose',evt=>{ - return evt.getParent()==event&&evt.hs.length>0; + clanzhongliu: { + audio: 2, + audioname: [ + "clan_wangling", + "clan_wangyun", + "clan_wanghun", + "clan_wanglun", + "clan_wangguang", + "clan_wangmingshan", + ], + trigger: { player: "useCard" }, + forced: true, + clanSkill: true, + filter(event, player) { + if (!event.cards.length) return true; + return !game.hasPlayer2((current) => { + if (!current.hasClan("太原王氏") && current != player) return false; + return current.hasHistory("lose", (evt) => { + return evt.getParent() == event && evt.hs.length > 0; }); }); }, - content(){ - 'step 0' - var skills=player.getStockSkills(true,true); + content() { + "step 0"; + var skills = player.getStockSkills(true, true); game.expandSkills(skills); - var resetSkills=[]; - var suffixs=['used','round','block','blocker']; - for(var skill of skills){ - var info=get.info(skill); - if(typeof info.usable=='number'){ - if(player.hasSkill('counttrigger')&&player.storage.counttrigger[skill]&&player.storage.counttrigger[skill]>=1){ + var resetSkills = []; + var suffixs = ["used", "round", "block", "blocker"]; + for (var skill of skills) { + var info = get.info(skill); + if (typeof info.usable == "number") { + if ( + player.hasSkill("counttrigger") && + player.storage.counttrigger[skill] && + player.storage.counttrigger[skill] >= 1 + ) { delete player.storage.counttrigger[skill]; resetSkills.add(skill); } - if(typeof get.skillCount(skill)=='number'&&get.skillCount(skill)>=1){ - delete player.getStat('skill')[skill]; + if (typeof get.skillCount(skill) == "number" && get.skillCount(skill) >= 1) { + delete player.getStat("skill")[skill]; resetSkills.add(skill); } } - if(info.round&&player.storage[skill+'_roundcount']){ - delete player.storage[skill+'_roundcount']; + if (info.round && player.storage[skill + "_roundcount"]) { + delete player.storage[skill + "_roundcount"]; resetSkills.add(skill); } - if(player.storage[`temp_ban_${skill}`]){ + if (player.storage[`temp_ban_${skill}`]) { delete player.storage[`temp_ban_${skill}`]; } - if(player.awakenedSkills.includes(skill)){ + if (player.awakenedSkills.includes(skill)) { player.restoreSkill(skill); resetSkills.add(skill); } - for(var suffix of suffixs){ - if(player.hasSkill(skill+'_'+suffix)){ - player.removeSkill(skill+'_'+suffix); + for (var suffix of suffixs) { + if (player.hasSkill(skill + "_" + suffix)) { + player.removeSkill(skill + "_" + suffix); resetSkills.add(skill); } } } - if(resetSkills.length){ - var str=''; - for(var i of resetSkills){ - str+='【'+get.translation(i)+'】、'; + if (resetSkills.length) { + var str = ""; + for (var i of resetSkills) { + str += "【" + get.translation(i) + "】、"; } - game.log(player,'重置了技能','#g'+str.slice(0,-1)); + game.log(player, "重置了技能", "#g" + str.slice(0, -1)); } - } + }, }, //族吴匡 - clanlianzhu:{ - audio:2, - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content(storage){ - var str='转换技。每名角色A的出牌阶段限一次。'; - if(!storage) str+='A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1。'; - else str+='A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1'; + clanlianzhu: { + audio: 2, + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content(storage) { + var str = "转换技。每名角色A的出牌阶段限一次。"; + if (!storage) + str += + "A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1。"; + else + str += + "A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1"; return str; }, }, - global:'clanlianzhu_global', - subSkill:{ - global:{ - forceaudio:true, - audio:'clanlianzhu', - enable:'phaseUse', - filter:(event,player)=>game.hasPlayer(current=>lib.skill.clanlianzhu_global.filterTarget(null,player,current)), - filterCard:(card,player)=>game.hasPlayer(current=>current.hasSkill('clanlianzhu')&&!current.hasSkill('clanlianzhu_targeted')&&!current.storage.clanlianzhu)&&player.canRecast(card), - selectCard:[0,1], - check(card){ - return 5-get.value(card); + global: "clanlianzhu_global", + subSkill: { + global: { + forceaudio: true, + audio: "clanlianzhu", + enable: "phaseUse", + filter: (event, player) => + game.hasPlayer((current) => + lib.skill.clanlianzhu_global.filterTarget(null, player, current) + ), + filterCard: (card, player) => + game.hasPlayer( + (current) => + current.hasSkill("clanlianzhu") && + !current.hasSkill("clanlianzhu_targeted") && + !current.storage.clanlianzhu + ) && player.canRecast(card), + selectCard: [0, 1], + check(card) { + return 5 - get.value(card); }, - filterTarget(card,player,target){ - return target.hasSkill('clanlianzhu')&&!target.hasSkill('clanlianzhu_targeted')&&(!target.storage.clanlianzhu||target.storage.clanlianzhu&&game.hasPlayer(current=>{ - if(current==player||current==target) return false; - return current.inRangeOf(player)||current.inRangeOf(target); - })); + filterTarget(card, player, target) { + return ( + target.hasSkill("clanlianzhu") && + !target.hasSkill("clanlianzhu_targeted") && + (!target.storage.clanlianzhu || + (target.storage.clanlianzhu && + game.hasPlayer((current) => { + if (current == player || current == target) return false; + return current.inRangeOf(player) || current.inRangeOf(target); + }))) + ); }, - selectTarget(){ - var player=_status.event.player; - var count=game.countPlayer(current=>lib.skill.clanlianzhu_global.filterTarget(null,player,current)); - return count==1?-1:1; + selectTarget() { + var player = _status.event.player; + var count = game.countPlayer((current) => + lib.skill.clanlianzhu_global.filterTarget(null, player, current) + ); + return count == 1 ? -1 : 1; }, - filterOk(){ - var target=ui.selected.targets[0]; - if(!target) return false; - if(!target.storage.clanlianzhu){ - return ui.selected.cards.length==1; + filterOk() { + var target = ui.selected.targets[0]; + if (!target) return false; + if (!target.storage.clanlianzhu) { + return ui.selected.cards.length == 1; } - return ui.selected.cards.length==0; + return ui.selected.cards.length == 0; }, - position:'he', - discard:false, - lose:false, - delay:false, - prompt(){ - var player=_status.event.player; - var bocchi=[],kita=[]; - game.countPlayer(function(target){ - if(target.hasSkill('clanlianzhu')&&!target.hasSkill('clanlianzhu_targeted')){ - if(target.storage.clanlianzhu){ - if(game.hasPlayer(current=>{ - if(current==player||current==target) return false; - return current.inRangeOf(player)||current.inRangeOf(target); - })) kita.add(target); - } - else{ - if(player.countCards('he')>0) bocchi.add(target); + position: "he", + discard: false, + lose: false, + delay: false, + prompt() { + var player = _status.event.player; + var bocchi = [], + kita = []; + game.countPlayer(function (target) { + if ( + target.hasSkill("clanlianzhu") && + !target.hasSkill("clanlianzhu_targeted") + ) { + if (target.storage.clanlianzhu) { + if ( + game.hasPlayer((current) => { + if (current == player || current == target) return false; + return current.inRangeOf(player) || current.inRangeOf(target); + }) + ) + kita.add(target); + } else { + if (player.countCards("he") > 0) bocchi.add(target); } } }); bocchi.sortBySeat(); kita.sortBySeat(); - var str=''; - if(bocchi.length){ - str+='重铸一张牌,然后令'; - bocchi.forEach((current,i)=>{ - str+=get.translation(current); - if(i { + str += get.translation(current); + if (i < bocchi.length - 1) str += "或"; }); - str+='选择是否重铸一张牌'; - if(kita.length) str+='。
              或者'; + str += "选择是否重铸一张牌"; + if (kita.length) str += "。
              或者"; } - if(kita.length){ - str+='令'; - kita.forEach((current,i)=>{ - str+=get.translation(current); - if(i { + str += get.translation(current); + if (i < kita.length - 1) str += "或"; }); - str+='选择一名目标,然后对其进行集火'; + str += "选择一名目标,然后对其进行集火"; } - str+='。'; + str += "。"; return str; }, - content(){ - 'step 0' - target.addTempSkill('clanlianzhu_targeted','phaseUseAfter'); - if(target.storage.clanlianzhu) event.goto(4); - target.changeZhuanhuanji('clanlianzhu'); - 'step 1' + content() { + "step 0"; + target.addTempSkill("clanlianzhu_targeted", "phaseUseAfter"); + if (target.storage.clanlianzhu) event.goto(4); + target.changeZhuanhuanji("clanlianzhu"); + "step 1"; player.recast(cards); - 'step 2' - if(!target.countCards('he')&&!_status.connectMode) event._result={bool:false}; - else target.chooseCard('he','联诛:是否重铸一张牌?',lib.filter.cardRecastable); - 'step 3' - if(result.bool){ + "step 2"; + if (!target.countCards("he") && !_status.connectMode) + event._result = { bool: false }; + else target.chooseCard("he", "联诛:是否重铸一张牌?", lib.filter.cardRecastable); + "step 3"; + if (result.bool) { target.recast(result.cards); - if(get.color(cards[0])!=get.color(result.cards[0])) lib.skill.chenliuwushi.change(target,-1); + if (get.color(cards[0]) === get.color(result.cards[0])) + lib.skill.chenliuwushi.change(target, 1); } event.finish(); - 'step 4' - target.chooseTarget('联诛:选择其与你使用【杀】的目标',true,(card,player,target)=>{ - if(target==player||target==_status.event.sourcex) return false; - return target.inRangeOf(player)||target.inRangeOf(_status.event.sourcex); - }).set('ai',target=>{ - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player); - }).set('sourcex',player); - 'step 5' - if(result.bool){ - var targetx=result.targets[0]; - event.targetx=targetx; + "step 4"; + target + .chooseTarget( + "联诛:选择其与你使用【杀】的目标", + true, + (card, player, target) => { + if (target == player || target == _status.event.sourcex) return false; + return ( + target.inRangeOf(player) || + target.inRangeOf(_status.event.sourcex) + ); + } + ) + .set("ai", (target) => { + return get.effect( + target, + { name: "sha" }, + _status.event.player, + _status.event.player + ); + }) + .set("sourcex", player); + "step 5"; + if (result.bool) { + var targetx = result.targets[0]; + event.targetx = targetx; target.line(targetx); - event.targets=[player,target]; - event.cards=[]; - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 6' - var current=targets.shift(); - current.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'联诛:是否对'+get.translation(event.targetx)+'使用一张杀?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',event.targetx).set('addCount',false); - 'step 7' - if(result.bool) cards.push(result.card); - if(targets.length>0) event.goto(6); - 'step 8' - if(cards.length>1&&get.color(cards)!='none') lib.skill.chenliuwushi.change(target,1); - }, - ai:{ - order:4.1, - result:{ - player(player,target){ - if(!target.storage.clanlianzhu&&player.hasCard(card=>get.value(card)<5,'he')) return 1; - return 0; - }, - target(player,target){ - if(target.storage.clanlianzhu&&player.hasSha()) return 1; - return 0; + event.targets = [player, target]; + event.cards = []; + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 6"; + var current = targets.shift(); + current + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "联诛:是否对" + get.translation(event.targetx) + "使用一张杀?") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", event.targetx) + .set("addCount", false); + "step 7"; + if (result.bool) cards.push(result.card); + if (targets.length > 0) event.goto(6); + "step 8"; + if (cards.length > 1) { + const color = get.color(cards[0], false); + if (color != "none") { + for (let i = 1; i < cards.length; i++) { + const color2 = get.color(cards[i], false); + if (color !== color2 && color2 !== "none") { + lib.skill.chenliuwushi.change(target, -1); + break; + } + } } } - } + }, + ai: { + order: 4.1, + result: { + player(player, target) { + if ( + !target.storage.clanlianzhu && + player.hasCard((card) => get.value(card) < 5, "he") + ) + return 1; + return 0; + }, + target(player, target) { + if (target.storage.clanlianzhu && player.hasSha()) return 1; + return 0; + }, + }, + }, }, - targeted:{charlotte:true} - } + targeted: { charlotte: true }, + }, }, //族韩韶 - clanfangzhen:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(current=>!current.isLinked()); + clanfangzhen: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((current) => !current.isLinked()); }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('clanfangzhen'),(card,player,target)=>{ - return !target.isLinked(); - }).set('ai',target=>{ - var player=_status.event.player; - if(_status.event.goon&&target!=player){ - target.classList.add('linked'); - target.classList.add('linked2'); - try{ - var cards=player.getCards('hs',cardx=>{ - if(get.name(cardx)!='sha') return false; - return game.hasNature(cardx,'linked'); - }); - cards.map(i=>[i,get.effect(target,i,player,player)]); - cards.sort((a,b)=>b[1]-a[1]); + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("clanfangzhen"), (card, player, target) => { + return !target.isLinked(); + }) + .set("ai", (target) => { + var player = _status.event.player; + if (_status.event.goon && target != player) { + target.classList.add("linked"); + target.classList.add("linked2"); + try { + var cards = player.getCards("hs", (cardx) => { + if (get.name(cardx) != "sha") return false; + return game.hasNature(cardx, "linked"); + }); + cards.map((i) => [i, get.effect(target, i, player, player)]); + cards.sort((a, b) => b[1] - a[1]); + } catch (e) { + target.classList.remove("linked"); + target.classList.remove("linked2"); + } + target.classList.remove("linked"); + target.classList.remove("linked2"); + var eff = cards[0][1]; + if (eff > 0) return eff; + return Math.max( + 2 * get.effect(target, { name: "draw" }, player, player) + + 0.6 * get.effect(player, { name: "draw" }, player, player), + get.recoverEffect(target, player, player) + ); } - catch(e){ - target.classList.remove('linked'); - target.classList.remove('linked2'); - } - target.classList.remove('linked'); - target.classList.remove('linked2'); - var eff=cards[0][1]; - if(eff>0) return eff; - return Math.max((2*get.effect(target,{name:'draw'},player,player)+0.6*get.effect(player,{name:'draw'},player,player)),get.recoverEffect(target,player,player)); - } - return Math.max((2*get.effect(target,{name:'draw'},player,player)+0.6*get.effect(player,{name:'draw'},player,player)),get.recoverEffect(target,player,player)); - }).set('goon',player.countCards('hs',card=>{ - return get.name(card)=='jiu'&&player.hasUseTarget(card); - })&&player.countCards('hs',card=>{ - if(get.name(card)!='sha') return false; - return game.hasNature(card,'linked'); - })); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('clanfangzhen',target); - player.addSkill('clanfangzhen_remove'); - player.markAuto('clanfangzhen_remove',[target.getSeatNum()]); + return Math.max( + 2 * get.effect(target, { name: "draw" }, player, player) + + 0.6 * get.effect(player, { name: "draw" }, player, player), + get.recoverEffect(target, player, player) + ); + }) + .set( + "goon", + player.countCards("hs", (card) => { + return get.name(card) == "jiu" && player.hasUseTarget(card); + }) && + player.countCards("hs", (card) => { + if (get.name(card) != "sha") return false; + return game.hasNature(card, "linked"); + }) + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("clanfangzhen", target); + player.addSkill("clanfangzhen_remove"); + player.markAuto("clanfangzhen_remove", [target.getSeatNum()]); target.link(true); - var choices=['选项一'],choiceList=[ - '摸两张牌,然后交给'+get.translation(target)+'两张牌', - '令'+get.translation(target)+'回复1点体力' - ]; - if(target.isDamaged()) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - player.chooseControl(choices).set('prompt','放赈:请选择一项').set('choiceList',choiceList).set('ai',()=>{ - var player=_status.event.player,target=_status.event.getParent().target; - if(!target.isDamaged()) return 0; - if(get.attitude(player,target)<=0&&player.countCards('he',card=>get.value(card)<0)>=2) return 0; - return (2*get.effect(target,{name:'draw'},player,player)+0.6*get.effect(player,{name:'draw'},player,player))>get.recoverEffect(target,player,player)?0:1; - }); - } - else event.finish(); - 'step 2' - if(result.control=='选项一'){ + var choices = ["选项一"], + choiceList = [ + "摸两张牌,然后交给" + get.translation(target) + "两张牌", + "令" + get.translation(target) + "回复1点体力", + ]; + if (target.isDamaged()) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + player + .chooseControl(choices) + .set("prompt", "放赈:请选择一项") + .set("choiceList", choiceList) + .set("ai", () => { + var player = _status.event.player, + target = _status.event.getParent().target; + if (!target.isDamaged()) return 0; + if ( + get.attitude(player, target) <= 0 && + player.countCards("he", (card) => get.value(card) < 0) >= 2 + ) + return 0; + return 2 * get.effect(target, { name: "draw" }, player, player) + + 0.6 * get.effect(player, { name: "draw" }, player, player) > + get.recoverEffect(target, player, player) + ? 0 + : 1; + }); + } else event.finish(); + "step 2"; + if (result.control == "选项一") { player.draw(2); - if(player==target) event.finish(); - } - else{ + if (player == target) event.finish(); + } else { target.recover(); event.finish(); } - 'step 3' - if(!player.countCards('he')) event.finish(); - else if(player.countCards('he')<=2) event._result={bool:true,cards:player.getCards('he')}; - else{ - player.chooseCard('放赈:交给'+get.translation(target)+'两张牌','he',2,true); + "step 3"; + if (!player.countCards("he")) event.finish(); + else if (player.countCards("he") <= 2) + event._result = { + bool: true, + cards: player.getCards("he"), + }; + else { + player.chooseCard("放赈:交给" + get.translation(target) + "两张牌", "he", 2, true); } - 'step 4' - if(result.bool){ - player.give(result.cards,target); + "step 4"; + if (result.bool) { + player.give(result.cards, target); } }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, - subSkill:{ - remove:{ - trigger:{global:'roundStart'}, - onremove:true, - forced:true, - locked:false, - charlotte:true, - filter(event,player){ - return player.getStorage('clanfangzhen_remove').includes(game.roundNumber); + subSkill: { + remove: { + trigger: { global: "roundStart" }, + onremove: true, + forced: true, + locked: false, + charlotte: true, + filter(event, player) { + return player.getStorage("clanfangzhen_remove").includes(game.roundNumber); }, - content(){ - player.removeSkills('clanfangzhen'); - } - } - } - }, - clanliuju:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - return game.hasPlayer(current=>player.canCompare(current)); + content() { + player.removeSkills("clanfangzhen"); + }, + }, }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('clanliuju'),'与一名其他角色拼点,输的角色可以使用任意张拼点牌中的非基本牌',(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',target=>{ - var player=_status.event.player; - var ts=target.getCards('h').sort((a,b)=>get.number(a)-get.number(b)); - if(get.attitude(player,target)<0){ - var hs=player.getCards('h').sort((a,b)=>get.number(a)-get.number(b)); - if(!hs.length||!ts.length) return 0; - if(get.type(hs[0],null,false)=='basic'&&get.value(hs[0])>6) return 0; - if(get.number(hs[0]){ - if(evt.getParent(2)==event) cards.addArray(evt.cards.filter(i=>{ - return get.position(i,true)=='d'&&get.type(i,null,false)!='basic'; - })); + }, + clanliuju: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + return game.hasPlayer((current) => player.canCompare(current)); + }, + direct: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("clanliuju"), + "与一名其他角色拼点,输的角色可以使用任意张拼点牌中的非基本牌", + (card, player, target) => { + return player.canCompare(target); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + var ts = target.getCards("h").sort((a, b) => get.number(a) - get.number(b)); + if (get.attitude(player, target) < 0) { + var hs = player.getCards("h").sort((a, b) => get.number(a) - get.number(b)); + if (!hs.length || !ts.length) return 0; + if (get.type(hs[0], null, false) == "basic" && get.value(hs[0]) > 6) return 0; + if ( + get.number(hs[0]) < get.number(ts[0]) || + get.type(hs[0], null, false) == "basic" + ) + return 1; + return Math.random() - 0.7; + } + return get.type(ts[0]) != "basic"; }); - event.loser=loser; - event.distance=[get.distance(player,target),get.distance(target,player)]; - if(cards.length) event.cards=cards; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("clanliuju", target); + player.chooseToCompare(target).set("small", true); + } else event.finish(); + "step 2"; + if (!result.tie) { + var loser = result.bool ? target : player; + var cards = []; + game.getGlobalHistory("cardMove", (evt) => { + if (evt.getParent(2) == event) + cards.addArray( + evt.cards.filter((i) => { + return ( + get.position(i, true) == "d" && + get.type(i, null, false) != "basic" + ); + }) + ); + }); + event.loser = loser; + event.distance = [get.distance(player, target), get.distance(target, player)]; + if (cards.length) event.cards = cards; else event.finish(); - } - else event.finish(); - 'step 3' - var cardsx=cards.filter(i=>get.position(i,true)=='d'&&event.loser.hasUseTarget(i)); - if(!cardsx.length) event.goto(6); - else event.loser.chooseButton(['留驹:是否使用其中的一张牌?',cardsx]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link); - }).set('ai',button=>{ - return _status.event.player.getUseValue(button.link)+0.1; - }); - 'step 4' - if(result.bool){ - var card=result.links[0]; + } else event.finish(); + "step 3"; + var cardsx = cards.filter( + (i) => get.position(i, true) == "d" && event.loser.hasUseTarget(i) + ); + if (!cardsx.length) event.goto(6); + else + event.loser + .chooseButton(["留驹:是否使用其中的一张牌?", cardsx]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link); + }) + .set("ai", (button) => { + return _status.event.player.getUseValue(button.link) + 0.1; + }); + "step 4"; + if (result.bool) { + var card = result.links[0]; event.cards.remove(card); - event.loser.$gain2(card,false); + event.loser.$gain2(card, false); game.delayx(); - event.loser.chooseUseTarget(true,card,false); + event.loser.chooseUseTarget(true, card, false); + } else event.goto(6); + "step 5"; + if ( + cards.filter((i) => get.position(i, true) == "d" && event.loser.hasUseTarget(i)) + .length + ) + event.goto(3); + "step 6"; + if ( + get.distance(player, target) != event.distance[0] || + get.distance(target, player) != event.distance[1] + ) { + player.restoreSkill("clanxumin"); + game.log(player, "重置了", "#g【恤民】"); } - else event.goto(6); - 'step 5' - if(cards.filter(i=>get.position(i,true)=='d'&&event.loser.hasUseTarget(i)).length) event.goto(3); - 'step 6' - if(get.distance(player,target)!=event.distance[0]||get.distance(target,player)!=event.distance[1]){ - player.restoreSkill('clanxumin'); - game.log(player,'重置了','#g【恤民】'); - } - } + }, }, - clanxumin:{ - audio:2, - audioname:['clan_hanshao','clan_hanrong'], - enable:'phaseUse', - viewAs:{name:'wugu'}, - filterCard:true, - filterTarget(card,player,target){ - if(player==target) return false; - return player.canUse(card,target); + clanxumin: { + audio: 2, + audioname: ["clan_hanshao", "clan_hanrong"], + enable: "phaseUse", + viewAs: { name: "wugu" }, + filterCard: true, + filterTarget(card, player, target) { + if (player == target) return false; + return player.canUse(card, target); }, - selectTarget:[1,Infinity], - check(card){ - return 6-get.value(card); + selectTarget: [1, Infinity], + check(card) { + return 6 - get.value(card); }, - position:'he', - limited:true, - clanSkill:true, - skillAnimation:true, - animationColor:'soil', - precontent(){ - player.logSkill('clanxumin'); - player.awakenSkill('clanxumin'); + position: "he", + limited: true, + clanSkill: true, + skillAnimation: true, + animationColor: "soil", + precontent() { + player.logSkill("clanxumin"); + player.awakenSkill("clanxumin"); delete event.result.skill; }, - ai:{ - order:7, - result:{target:1} + ai: { + order: 7, + result: { target: 1 }, }, }, //族韩融 //我们连和!(?) - clanlianhe:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(current=>!current.isLinked()); + clanlianhe: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((current) => !current.isLinked()); }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('clanlianhe'),2,(card,player,target)=>{ - return !target.isLinked(); - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(att>0) att/=1.2; - return Math.abs(att); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - targets.forEach(i=>i.link(true)); - player.logSkill('clanlianhe',targets); - player.addSkill('clanlianhe_effect'); - player.markAuto('clanlianhe_effect',targets); + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("clanlianhe"), 2, (card, player, target) => { + return !target.isLinked(); + }) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (att > 0) att /= 1.2; + return Math.abs(att); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + targets.forEach((i) => i.link(true)); + player.logSkill("clanlianhe", targets); + player.addSkill("clanlianhe_effect"); + player.markAuto("clanlianhe_effect", targets); } }, - subSkill:{ - effect:{ - trigger:{global:['phaseUseEnd','die']}, - charlotte:true, - forced:true, - locked:false, - popup:false, - onremove:true, - filter(event,player){ - return player.getStorage('clanlianhe_effect').includes(event.player); + subSkill: { + effect: { + trigger: { global: ["phaseUseEnd", "die"] }, + charlotte: true, + forced: true, + locked: false, + popup: false, + onremove: true, + filter(event, player) { + return player.getStorage("clanlianhe_effect").includes(event.player); }, - marktext:'连', - intro:{content:'已选择目标:$'}, - content(){ - 'step 0' - player.unmarkAuto('clanlianhe_effect',[trigger.player]); - if(trigger.name=='die') event.finish(); - 'step 1' - if(trigger.player.hasHistory('gain',evt=>{ - return evt.getParent().name=='draw'&&evt.getParent('phaseUse')==trigger; - })) event.finish(); - else{ - player.logSkill('clanlianhe_effect',trigger.player); - var num=0; - trigger.player.getHistory('gain',evt=>{ - if(evt.getParent('phaseUse')!=trigger) return false; - num+=evt.cards.length; + marktext: "连", + intro: { content: "已选择目标:$" }, + content() { + "step 0"; + player.unmarkAuto("clanlianhe_effect", [trigger.player]); + if (trigger.name == "die") event.finish(); + "step 1"; + if ( + trigger.player.hasHistory("gain", (evt) => { + return ( + evt.getParent().name == "draw" && evt.getParent("phaseUse") == trigger + ); + }) + ) + event.finish(); + else { + player.logSkill("clanlianhe_effect", trigger.player); + var num = 0; + trigger.player.getHistory("gain", (evt) => { + if (evt.getParent("phaseUse") != trigger) return false; + num += evt.cards.length; }); - num=Math.min(num,3); - event.num=num; - if(num<=1) event._result={bool:false}; - else{ - var pos=player==trigger.player?'e':'he'; - trigger.player.chooseCard('连和:交给'+get.translation(player)+get.cnNumber(num-1)+'张牌,或点“取消”令其摸'+get.cnNumber(num+1)+'张牌',num-1,pos).set('ai',card=>{ - if(_status.event.draw) return 0; - return 5-get.value(card); - }).set('draw',get.attitude(trigger.player,player)>=0); + num = Math.min(num, 3); + event.num = num; + if (num <= 1) event._result = { bool: false }; + else { + var pos = player == trigger.player ? "e" : "he"; + trigger.player + .chooseCard( + "连和:交给" + + get.translation(player) + + get.cnNumber(num - 1) + + "张牌,或点“取消”令其摸" + + get.cnNumber(num + 1) + + "张牌", + num - 1, + pos + ) + .set("ai", (card) => { + if (_status.event.draw) return 0; + return 5 - get.value(card); + }) + .set("draw", get.attitude(trigger.player, player) >= 0); } } - 'step 2' - if(result.bool){ - trigger.player.give(result.cards,player); - } - else player.draw(num+1); - } - } - } - }, - clanhuanjia:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - return game.hasPlayer(current=>player.canCompare(current)); - }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('clanhuanjia'),'与一名其他角色拼点,赢的角色可以使用一张拼点牌。若此牌未造成过伤害,你获得另一张拼点牌,否则你失去一个技能',(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',target=>{ - var player=_status.event.player; - if(get.attitude(player,target)<=0){ - var hs=player.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - var ts=target.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - if(!hs.length||!ts.length) return 0; - if(get.number(hs[0])>get.number(ts[0])&&(!get.tag(hs[0],'damage')&&player.hasValueTarget(hs[0]))) return 1; - return Math.random()-0.4; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('clanhuanjia',target); - player.chooseToCompare(target); - } - else event.finish(); - 'step 2' - if(!result.tie){ - var winner=result.bool?player:target; - var cards=[]; - game.getGlobalHistory('cardMove',evt=>{ - if(evt.getParent(3)==event) cards.addArray(evt.cards.filterInD('d')); - }); - event.winner=winner; - if(cards.length) event.cards=cards; - else event.finish(); - } - else event.finish(); - 'step 3' - var cardsx=cards.filter(i=>get.position(i,true)=='d'&&event.winner.hasUseTarget(i)); - if(!cardsx.length) event.goto(6); - else event.winner.chooseButton(['缓颊:是否使用其中的一张牌?',cardsx]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link); - }).set('ai',button=>{ - var damage=1; - if(_status.event.att>2&&get.tag(button.link,'damage')) damage*=2; - return _status.event.player.getUseValue(button.link)*damage+0.1; - }).set('att',get.attitude(event.winner,player)); - 'step 4' - if(result.bool){ - var card=result.links[0]; - event.card=card; - event.cards.remove(card); - event.winner.$gain2(card,false); - game.delayx(); - event.winner.chooseUseTarget(true,card,false); - } - 'step 5' - if(game.hasPlayer2(current=>{ - return current.hasHistory('sourceDamage',evt=>evt.cards&&evt.cards[0]==card); - })){ - var skills=player.getSkills(null,false,false).filter(skill=>{ - var info=get.info(skill); - if(!info||get.is.empty(info)||info.charlotte) return false; - return true; - }); - player.chooseControl(skills).set('choiceList',skills.map(i=>{ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','恤民:失去一个技能').set('ai',()=>{ - var choices=_status.event.controls.slice(); - var value=(skill)=>get.skillRank(skill,'in')+get.skillRank(skill,'out'); - choices=choices.map(skill=>[skill,value(skill)]); - var list=choices.sort((a,b)=>a[1]-b[1])[0]; - if(list[1]<2) return list[0]; - else{ - if(_status.event.controls.includes('clanxumin')) return 'clanxumin'; - return list[0]; - } - }); - } - else{ - player.gain(cards,'gain2'); - event.finish(); - } - 'step 6' - player.removeSkills(result.control); - }, - ai:{ - expose:0.1, - } - }, - //族荀谌 - clansankuang:{ - audio:2, - trigger:{player:'useCardAfter'}, - direct:true, - forced:true, - filter(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; - const type=get.type2(event.card); - return player.getRoundHistory('useCard',evt=>get.type2(evt.card)==type).indexOf(event)==0; - }, - getNum(player){ - return (player.countCards('ej')>0)+(player.isDamaged())+(Math.max(0,player.hp){ - var att=get.attitude(player,target),num=lib.skill.clansankuang.getNum(target); - if(num==0) return att; - if(_status.event.goon) return -att; - return -Math.sqrt(Math.abs(att))-lib.skill.clansankuang.getNum(target); - }).set('goon',Math.max.apply(Math,trigger.cards.map(i=>get.value(i)))<=5||trigger.cards.filterInD('oe').length==0) - 'step 1' - if(result.bool){ - var target=result.targets[0],num=lib.skill.clansankuang.getNum(target),num2=target.countCards('he'); - event.target=target; - player.logSkill('clansankuang',target); - if(num2==0) event._result={bool:false}; - else if(num2<=num) event._result={bool:true,cards:target.getCards('he')}; - else{ - var cards=trigger.cards.filterInD('oe'); - target.chooseCard('he',num>0,[num,Infinity]).set('ai',get.unuseful).set('prompt',num>0? - '是否交给'+get.translation(player)+'任意张牌'+(cards.length?'并获得'+get.translation(cards):'')+'?': - '交给'+get.translation(player)+'至少'+get.cnNumber(num)+'张牌'); - } - }else event.finish(); - 'step 2' - if(result.bool){ - var cards=result.cards; - target.give(cards,player); - game.delayx(); - } - else event.finish(); - 'step 3' - if(trigger.cards.filterInD().length) target.gain(trigger.cards.filterInD(),'gain2','bySelf'); - else if(trigger.cards.filterInD('e').length) target.gain(trigger.cards.filterInD('e'),get.owner(trigger.cards.filterInD('e')[0]),'give'); - }, - ai:{ - reverseOrder:true, - skillTagFilter(player){ - if(player.getHistory('useCard',evt=>get.type(evt.card)=='equip').length>0) return false; - }, - effect:{ - target(card,player,target){ - if(player==target&&get.type(card)=='equip'&&!player.getHistory('useCard',evt=>get.type(evt.card)=='equip').length==0) return [1,3]; + "step 2"; + if (result.bool) { + trigger.player.give(result.cards, player); + } else player.draw(num + 1); }, }, - threaten:1.6, }, }, - clanbeishi:{ - audio:2, - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + clanhuanjia: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + return game.hasPlayer((current) => player.canCompare(current)); }, - forced:true, - filter(event,player){ - var history=player.getAllHistory('useSkill',evt=>evt.skill=='clansankuang'); - if(!history.length) return false; - var target=history[0].targets[0]; - if(target.countCards('h')) return false; - var evt=event.getl(target); - return evt&&evt.hs&&evt.hs.length; + direct: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("clanhuanjia"), + "与一名其他角色拼点,赢的角色可以使用一张拼点牌。若此牌未造成过伤害,你获得另一张拼点牌,否则你失去一个技能", + (card, player, target) => { + return player.canCompare(target); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + if (get.attitude(player, target) <= 0) { + var hs = player.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + var ts = target.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + if (!hs.length || !ts.length) return 0; + if ( + get.number(hs[0]) > get.number(ts[0]) && + !get.tag(hs[0], "damage") && + player.hasValueTarget(hs[0]) + ) + return 1; + return Math.random() - 0.4; + } + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("clanhuanjia", target); + player.chooseToCompare(target); + } else event.finish(); + "step 2"; + if (!result.tie) { + var winner = result.bool ? player : target; + var cards = []; + game.getGlobalHistory("cardMove", (evt) => { + if (evt.getParent(3) == event) cards.addArray(evt.cards.filterInD("d")); + }); + event.winner = winner; + if (cards.length) event.cards = cards; + else event.finish(); + } else event.finish(); + "step 3"; + var cardsx = cards.filter( + (i) => get.position(i, true) == "d" && event.winner.hasUseTarget(i) + ); + if (!cardsx.length) event.goto(6); + else + event.winner + .chooseButton(["缓颊:是否使用其中的一张牌?", cardsx]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link); + }) + .set("ai", (button) => { + var damage = 1; + if (_status.event.att > 2 && get.tag(button.link, "damage")) damage *= 2; + return _status.event.player.getUseValue(button.link) * damage + 0.1; + }) + .set("att", get.attitude(event.winner, player)); + "step 4"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + event.cards.remove(card); + event.winner.$gain2(card, false); + game.delayx(); + event.winner.chooseUseTarget(true, card, false); + } + "step 5"; + if ( + game.hasPlayer2((current) => { + return current.hasHistory( + "sourceDamage", + (evt) => evt.cards && evt.cards[0] == card + ); + }) + ) { + var skills = player.getSkills(null, false, false).filter((skill) => { + var info = get.info(skill); + if (!info || get.is.empty(info) || info.charlotte) return false; + return true; + }); + player + .chooseControl(skills) + .set( + "choiceList", + skills.map((i) => { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "恤民:失去一个技能") + .set("ai", () => { + var choices = _status.event.controls.slice(); + var value = (skill) => + get.skillRank(skill, "in") + get.skillRank(skill, "out"); + choices = choices.map((skill) => [skill, value(skill)]); + var list = choices.sort((a, b) => a[1] - b[1])[0]; + if (list[1] < 2) return list[0]; + else { + if (_status.event.controls.includes("clanxumin")) return "clanxumin"; + return list[0]; + } + }); + } else { + player.gain(cards, "gain2"); + event.finish(); + } + "step 6"; + player.removeSkills(result.control); }, - content(){ + ai: { + expose: 0.1, + }, + }, + //族荀谌 + clansankuang: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + forced: true, + filter(event, player) { + if (!game.hasPlayer((current) => current != player)) return false; + const type = get.type2(event.card); + return ( + player + .getRoundHistory("useCard", (evt) => get.type2(evt.card) == type) + .indexOf(event) == 0 + ); + }, + getNum(player) { + return ( + (player.countCards("ej") > 0) + + player.isDamaged() + + (Math.max(0, player.hp) < player.countCards("h")) + ); + }, + content() { + "step 0"; + var cards = trigger.cards.filterInD("oe"); + player + .chooseTarget( + "三恇:选择一名其他角色", + "令其交给你至少X张牌" + + (cards.length ? ",然后其获得" + get.translation(cards) : "") + + "(X为以下条件中其满足的项数:场上有牌、已受伤、体力值小于手牌数)", + true, + lib.filter.notMe + ) + .set("ai", (target) => { + var att = get.attitude(player, target), + num = lib.skill.clansankuang.getNum(target); + if (num == 0) return att; + if (_status.event.goon) return -att; + return -Math.sqrt(Math.abs(att)) - lib.skill.clansankuang.getNum(target); + }) + .set( + "goon", + Math.max.apply( + Math, + trigger.cards.map((i) => get.value(i)) + ) <= 5 || trigger.cards.filterInD("oe").length == 0 + ); + "step 1"; + if (result.bool) { + var target = result.targets[0], + num = lib.skill.clansankuang.getNum(target), + num2 = target.countCards("he"); + event.target = target; + player.logSkill("clansankuang", target); + if (num2 == 0) event._result = { bool: false }; + else if (num2 <= num) + event._result = { + bool: true, + cards: target.getCards("he"), + }; + else { + var cards = trigger.cards.filterInD("oe"); + target + .chooseCard("he", num > 0, [num, Infinity]) + .set("ai", get.unuseful) + .set( + "prompt", + num > 0 + ? "是否交给" + + get.translation(player) + + "任意张牌" + + (cards.length ? "并获得" + get.translation(cards) : "") + + "?" + : "交给" + + get.translation(player) + + "至少" + + get.cnNumber(num) + + "张牌" + ); + } + } else event.finish(); + "step 2"; + if (result.bool) { + var cards = result.cards; + target.give(cards, player); + game.delayx(); + } else event.finish(); + "step 3"; + if (trigger.cards.filterInD().length) + target.gain(trigger.cards.filterInD(), "gain2", "bySelf"); + else if (trigger.cards.filterInD("e").length) + target.gain( + trigger.cards.filterInD("e"), + get.owner(trigger.cards.filterInD("e")[0]), + "give" + ); + }, + ai: { + reverseOrder: true, + skillTagFilter(player) { + if (player.getHistory("useCard", (evt) => get.type(evt.card) == "equip").length > 0) + return false; + }, + effect: { + target(card, player, target) { + if ( + player == target && + get.type(card) == "equip" && + !player.getHistory("useCard", (evt) => get.type(evt.card) == "equip") + .length == 0 + ) + return [1, 3]; + }, + }, + threaten: 1.6, + }, + }, + clanbeishi: { + audio: 2, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + forced: true, + filter(event, player) { + var history = player.getAllHistory("useSkill", (evt) => evt.skill == "clansankuang"); + if (!history.length) return false; + var target = history[0].targets[0]; + if (target.countCards("h")) return false; + var evt = event.getl(target); + return evt && evt.hs && evt.hs.length; + }, + content() { player.recover(); - } + }, + ai: { + combo: "clansankuang", + }, }, //族荀淑 - clanshenjun:{ - audio:2, - trigger:{ - global:'useCard', + clanshenjun: { + audio: 2, + trigger: { + global: "useCard", }, - forced:true, - locked:false, - filter(event,player){ - return (event.card.name=='sha'||get.type(event.card)=='trick')&&player.countCards('h',event.card.name)>0; + forced: true, + locked: false, + filter(event, player) { + return ( + (event.card.name == "sha" || get.type(event.card) == "trick") && + player.countCards("h", event.card.name) > 0 + ); }, - content(){ - var cards=player.getCards('h',trigger.card.name); - player.showCards(cards,get.translation(player)+'发动了【神君】'); - player.markSkill('clanshenjun'); - player.addGaintag(cards,'clanshenjun'); - for(var name of lib.phaseName){ - var evt=_status.event.getParent(name); - if(!evt||evt.name!=name) continue; - player.addTempSkill('clanshenjun_viewAs',name+'After'); + content() { + var cards = player.getCards("h", trigger.card.name); + player.showCards(cards, get.translation(player) + "发动了【神君】"); + player.markSkill("clanshenjun"); + player.addGaintag(cards, "clanshenjun"); + for (var name of lib.phaseName) { + var evt = _status.event.getParent(name); + if (!evt || evt.name != name) continue; + player.addTempSkill("clanshenjun_viewAs", name + "After"); break; } }, - marktext:'君', - intro:{ - markcount(storage,player){ - return player.countCards('h',card=>card.hasGaintag('clanshenjun')); + marktext: "君", + intro: { + markcount(storage, player) { + return player.countCards("h", (card) => card.hasGaintag("clanshenjun")); }, - mark(dialog,content,player){ - var cards=player.getCards('h',card=>card.hasGaintag('clanshenjun')); - if(cards.length){ + mark(dialog, content, player) { + var cards = player.getCards("h", (card) => card.hasGaintag("clanshenjun")); + if (cards.length) { dialog.addAuto(cards); - } - else return '无展示牌'; + } else return "无展示牌"; }, }, - subSkill:{ - viewAs:{ - trigger:{global:['phaseZhunbeiEnd','phaseJudgeEnd','phaseDrawEnd','phaseUseEnd','phaseDiscardEnd','phaseJieshuEnd']}, - filter(event,player){ - return player.countCards('h',card=>card.hasGaintag('clanshenjun'))>0; + subSkill: { + viewAs: { + trigger: { + global: [ + "phaseZhunbeiEnd", + "phaseJudgeEnd", + "phaseDrawEnd", + "phaseUseEnd", + "phaseDiscardEnd", + "phaseJieshuEnd", + ], }, - forced:true, - charlotte:true, - content(){ - 'step 0' - var cards=player.getCards('h',card=>card.hasGaintag('clanshenjun')); - var list=[],names=[]; - for(var card of cards){ - var name=get.name(card),nature=get.nature(card); - var namex=name; - if(nature&&nature.length){ - namex+=nature; - if(names.includes(namex)) continue; - list.push([get.type(card),'',name,nature]); - } - else{ - if(names.includes(namex)) continue; - list.push([get.type(card),'',name]); + filter(event, player) { + return player.countCards("h", (card) => card.hasGaintag("clanshenjun")) > 0; + }, + forced: true, + charlotte: true, + content() { + "step 0"; + var cards = player.getCards("h", (card) => card.hasGaintag("clanshenjun")); + var list = [], + names = []; + for (var card of cards) { + var name = get.name(card), + nature = get.nature(card); + var namex = name; + if (nature && nature.length) { + namex += nature; + if (names.includes(namex)) continue; + list.push([get.type(card), "", name, nature]); + } else { + if (names.includes(namex)) continue; + list.push([get.type(card), "", name]); } names.push(namex); } - list.sort((a,b)=>{ - var del1=lib.inpile.indexOf(a[2])-lib.inpile.indexOf(b[2]); - if(del1!=0) return del1; - var a1=0,b1=0; - if(a.length>3) a1=(lib.nature.get(a)||0); - if(b.length>3) b1=(lib.nature.get(b)||0); - return a1-b1; - }) - player.chooseButton(['是否将'+get.cnNumber(cards.length)+'张牌当下列一张牌使用?',[list,'vcard']]).set('ai',function(button){ - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); + list.sort((a, b) => { + var del1 = lib.inpile.indexOf(a[2]) - lib.inpile.indexOf(b[2]); + if (del1 != 0) return del1; + var a1 = 0, + b1 = 0; + if (a.length > 3) a1 = lib.nature.get(a) || 0; + if (b.length > 3) b1 = lib.nature.get(b) || 0; + return a1 - b1; }); - 'step 1' - if(result.bool){ - var name=result.links[0][2],nature=result.links[0][3]; - var cards=player.getCards('h',card=>card.hasGaintag('clanshenjun')); - game.broadcastAll(function(num,card){ - lib.skill.clanshenjun_backup.selectCard=num; - lib.skill.clanshenjun_backup.viewAs=card; - },cards.length,{name:name,nature:nature}); - var next=player.chooseToUse(); - next.set('openskilldialog','将'+get.cnNumber(cards.length)+'张牌当做'+(get.translation(nature)||'')+'【'+get.translation(name)+'】使用'); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','clanshenjun_backup'); - next.set('custom',{ - add:{}, - replace:{window(){}} + player + .chooseButton([ + "是否将" + get.cnNumber(cards.length) + "张牌当下列一张牌使用?", + [list, "vcard"], + ]) + .set("ai", function (button) { + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); }); - next.backup('clanshenjun_backup'); + "step 1"; + if (result.bool) { + var name = result.links[0][2], + nature = result.links[0][3]; + var cards = player.getCards("h", (card) => card.hasGaintag("clanshenjun")); + game.broadcastAll( + function (num, card) { + lib.skill.clanshenjun_backup.selectCard = num; + lib.skill.clanshenjun_backup.viewAs = card; + }, + cards.length, + { name: name, nature: nature } + ); + var next = player.chooseToUse(); + next.set( + "openskilldialog", + "将" + + get.cnNumber(cards.length) + + "张牌当做" + + (get.translation(nature) || "") + + "【" + + get.translation(name) + + "】使用" + ); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "clanshenjun_backup"); + next.set("custom", { + add: {}, + replace: { window() {} }, + }); + next.backup("clanshenjun_backup"); } - } - }, - backup:{ - filterCard(card){ - return get.itemtype(card)=='card'; }, - position:'hes', - filterTarget:lib.filter.filterTarget, - check:(card)=>6-get.value(card), - log:false, - precontent(){ + }, + backup: { + filterCard(card) { + return get.itemtype(card) == "card"; + }, + position: "hes", + filterTarget: lib.filter.filterTarget, + check: (card) => 6 - get.value(card), + log: false, + precontent() { delete event.result.skill; }, - } - } - }, - clanbalong:{ - audio:2, - trigger:{ - player:['damageEnd','recoverEnd','loseHpEnd'], + }, }, - forced:true, - filter(event,player){ - if(game.getGlobalHistory('changeHp',evt=>evt.player==player).length!=1) return false; - var cards=player.getCards('h'),map={}; - if(!cards.length) return false; - for(var card of cards){ - var type=get.type2(card); - if(typeof map[type]!='number') map[type]=0; + }, + clanbalong: { + audio: 2, + trigger: { + player: ["damageEnd", "recoverEnd", "loseHpEnd"], + }, + forced: true, + filter(event, player) { + if (game.getGlobalHistory("changeHp", (evt) => evt.player == player).length != 1) + return false; + var cards = player.getCards("h"), + map = {}; + if (!cards.length) return false; + for (var card of cards) { + var type = get.type2(card); + if (typeof map[type] != "number") map[type] = 0; map[type]++; } - var list=[]; - for(var i in map){ - if(map[i]>0) list.push([i,map[i]]); + var list = []; + for (var i in map) { + if (map[i] > 0) list.push([i, map[i]]); } - list.sort((a,b)=>b[1]-a[1]); - return list[0][0]=='trick'&&(list.length==1||list[0][1]>list[1][1]); + list.sort((a, b) => b[1] - a[1]); + return list[0][0] == "trick" && (list.length == 1 || list[0][1] > list[1][1]); }, - content(){ - player.showHandcards(get.translation(player)+'发动了【八龙】'); + content() { + player.showHandcards(get.translation(player) + "发动了【八龙】"); player.drawTo(game.countPlayer()); - } + }, }, //族荀粲 - clanyunshen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return player!=target&&target.isDamaged(); + clanyunshen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return player != target && target.isDamaged(); }, - content(){ - 'step 0' + content() { + "step 0"; target.recover(); - 'step 1' - var name=get.translation(target); - player.chooseControl().set('choiceList',[name+'视为对你使用一张冰【杀】','你视为对'+name+'使用一张冰【杀】']).set('prompt','熨身:请选择一项').set('ai',()=>_status.event.choice).set('choice',function(){ - var card={name:'sha',nature:'ice',isCard:true}; - var eff=get.effect(player,card,target,player),eff2=get.effect(target,card,player,player); - if(eff>eff2) return '选项一'; - else return '选项二'; - }()); - 'step 2' - var players=[target,player]; - if(result.control=='选项二') players.reverse(); - var card={name:'sha',nature:'ice',isCard:true}; - if(players[0].canUse(card,players[1],false)) players[0].useCard(card,players[1],false,'noai'); + "step 1"; + var name = get.translation(target); + player + .chooseControl() + .set("choiceList", [ + name + "视为对你使用一张冰【杀】", + "你视为对" + name + "使用一张冰【杀】", + ]) + .set("prompt", "熨身:请选择一项") + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + var card = { + name: "sha", + nature: "ice", + isCard: true, + }; + var eff = get.effect(player, card, target, player), + eff2 = get.effect(target, card, player, player); + if (eff > eff2) return "选项一"; + else return "选项二"; + })() + ); + "step 2"; + var players = [target, player]; + if (result.control == "选项二") players.reverse(); + var card = { name: "sha", nature: "ice", isCard: true }; + if (players[0].canUse(card, players[1], false)) + players[0].useCard(card, players[1], false, "noai"); }, - ai:{ - order:2, - expose:0.2, - result:{ - target(player,target){ - var eff=get.recoverEffect(target,player,player); - if(eff>0) return 1; - else if(get.effect(target,{name:'sha',nature:'ice',isCard:true},player,player)>eff) return -1; + ai: { + order: 2, + expose: 0.2, + result: { + target(player, target) { + var eff = get.recoverEffect(target, player, player); + if (eff > 0) return 1; + else if ( + get.effect( + target, + { + name: "sha", + nature: "ice", + isCard: true, + }, + player, + player + ) > eff + ) + return -1; return 0; - } - } - } - }, - clanshangshen:{ - audio:2, - trigger:{global:'damageEnd'}, - filter(event,player){ - if(!event.hasNature()||!event.player.isIn()) return false; - return game.countPlayer2(current=>{ - return current.hasHistory('damage',evt=>{ - return evt.hasNature()&&evt!=event; - }); - })==0; + }, + }, }, - logTarget:'player', - check(event,player){ - if(get.attitude(player,event.player)<=2) return false; - if(event.player.countCards('h')>=4) return false; + }, + clanshangshen: { + audio: 2, + trigger: { global: "damageEnd" }, + filter(event, player) { + if (!event.hasNature() || !event.player.isIn()) return false; + return ( + game.countPlayer2((current) => { + return current.hasHistory("damage", (evt) => { + return evt.hasNature() && evt != event; + }); + }) == 0 + ); + }, + logTarget: "player", + check(event, player) { + if (get.attitude(player, event.player) <= 2) return false; + if (event.player.countCards("h") >= 4) return false; return true; }, - content(){ - player.executeDelayCardEffect('shandian'); + content() { + player.executeDelayCardEffect("shandian"); trigger.player.drawTo(4); }, - ai:{expose:0.25} + ai: { expose: 0.25 }, }, - clanfenchai:{ - audio:2, - init(player){ - if(player.getStorage('clanfenchai').length>0) return; - var history=player.getHistory('useSkill',evt=>{ - if(evt.type!='player') return false; - var skill=evt.sourceSkill||evt.skill,targets=evt.targets; - var info=get.info(skill); - if(!info||info.charlotte) return false; - if(targets&&targets.length){ - if(targets.filter(i=>player.differentSexFrom(i)).length>0) return true; + clanfenchai: { + audio: 2, + init(player) { + if (player.getStorage("clanfenchai").length > 0) return; + var history = player.getHistory("useSkill", (evt) => { + if (evt.type != "player") return false; + var skill = evt.sourceSkill || evt.skill, + targets = evt.targets; + var info = get.info(skill); + if (!info || info.charlotte) return false; + if (targets && targets.length) { + if (targets.filter((i) => player.differentSexFrom(i)).length > 0) return true; } return false; }); - if(history.length){ - var evt=history[0],targets=evt.targets; - player.markAuto('clanfenchai',targets.filter(i=>player.differentSexFrom(i))); + if (history.length) { + var evt = history[0], + targets = evt.targets; + player.markAuto( + "clanfenchai", + targets.filter((i) => player.differentSexFrom(i)) + ); } }, - trigger:{ - player:['logSkill','useSkillAfter'], + trigger: { + player: ["logSkill", "useSkillAfter"], }, - forced:true, - silent:true, - onremove:true, - marktext:'钗', - intro:{ - content:(storage,player)=>'对象:'+get.translation(storage), + forced: true, + silent: true, + onremove: true, + marktext: "钗", + intro: { + content: (storage, player) => "对象:" + get.translation(storage), }, - group:'clanfenchai_audio', - filter(event,player){ - if(event.type!='player') return false; - var targets=event.targets; - if(!targets||!targets.length) return false; - var info=get.info(event.sourceSkill||event.skill); - if(!info||info.charlotte) return false; - if(player.getStorage('clanfenchai').length!=0) return false; - return targets.filter(i=>player.differentSexFrom(i)).length>0; + group: "clanfenchai_audio", + filter(event, player) { + if (event.type != "player") return false; + var targets = event.targets; + if (!targets || !targets.length) return false; + var info = get.info(event.sourceSkill || event.skill); + if (!info || info.charlotte) return false; + if (player.getStorage("clanfenchai").length != 0) return false; + return targets.filter((i) => player.differentSexFrom(i)).length > 0; }, - content(){ - player.markAuto('clanfenchai',trigger.targets.filter(i=>player.differentSexFrom(i))); + content() { + player.markAuto( + "clanfenchai", + trigger.targets.filter((i) => player.differentSexFrom(i)) + ); }, - subSkill:{ - audio:{ - audio:'clanfenchai', - forced:true, - trigger:{player:'judge'}, - filter(event,player){ - return player.getStorage('clanfenchai').length; + subSkill: { + audio: { + audio: "clanfenchai", + forced: true, + trigger: { player: "judge" }, + filter(event, player) { + return player.getStorage("clanfenchai").length; }, - content(){} - } + content() {}, + }, + }, + mod: { + suit(card, suit) { + var player = get.owner(card) || _status.event.player; + if (!player || !player.judging || player.judging[0] != card) return; + var storage = player.getStorage("clanfenchai"); + if (!storage.length) return; + return storage.filter((i) => i.isIn()).length > 0 ? "heart" : "spade"; + }, }, - mod:{ - suit(card,suit){ - var player=get.owner(card)||_status.event.player; - if(!player||!player.judging||player.judging[0]!=card) return; - var storage=player.getStorage('clanfenchai'); - if(!storage.length) return; - return storage.filter(i=>i.isIn()).length>0?'heart':'spade'; - } - } }, //族荀采 - clanlieshi:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return !player.isDisabledJudge()||player.countCards('h',card=>['sha','shan'].includes(get.name(card)))>0; + clanlieshi: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return ( + !player.isDisabledJudge() || + player.countCards("h", (card) => ["sha", "shan"].includes(get.name(card))) > 0 + ); }, - chooseButton:{ - dialog(event,player){ - var dialog=ui.create.dialog('烈誓:选择一项','hidden'); - dialog.add([lib.skill.clanlieshi.choices.slice(),'textbutton']); + chooseButton: { + dialog(event, player) { + var dialog = ui.create.dialog("烈誓:选择一项", "hidden"); + dialog.add([lib.skill.clanlieshi.choices.slice(), "textbutton"]); return dialog; }, - filter(button,player){ - var link=button.link; - if(link=='damage') return !player.isDisabledJudge(); - var num=player.countCards('h',link); - return num>0&&num==player.getDiscardableCards(player,'h').filter(i=>get.name(i)==link).length; + filter(button, player) { + var link = button.link; + if (link == "damage") return !player.isDisabledJudge(); + var num = player.countCards("h", link); + return ( + num > 0 && + num == + player.getDiscardableCards(player, "h").filter((i) => get.name(i) == link) + .length + ); }, - check(button){ - var player=_status.event.player; - switch (button.link){ - case 'damage': - if(get.damageEffect(player,player,player,'fire')>=0) return 10; - if(player.hp>=Math.max(2,3-player.getFriends().length)&&game.countPlayer(current=>get.attitude(player,current)<0&¤t.countCards('h',card=>['sha','shan'].includes(get.name(card))))) return 0.8+Math.random(); + check(button) { + var player = _status.event.player; + switch (button.link) { + case "damage": + if (get.damageEffect(player, player, player, "fire") >= 0) return 10; + if ( + player.hp >= Math.max(2, 3 - player.getFriends().length) && + game.countPlayer( + (current) => + get.attitude(player, current) < 0 && + current.countCards("h", (card) => + ["sha", "shan"].includes(get.name(card)) + ) + ) + ) + return 0.8 + Math.random(); return 0; - case 'shan': - if(player.countCards('h','shan')==1) return 8+Math.random(); - return 1+Math.random(); - case 'sha': - if(player.countCards('h','sha')==1) return 8+Math.random(); - return 0.9+Math.random(); + case "shan": + if (player.countCards("h", "shan") == 1) return 8 + Math.random(); + return 1 + Math.random(); + case "sha": + if (player.countCards("h", "sha") == 1) return 8 + Math.random(); + return 0.9 + Math.random(); } }, - backup(links){ - var next=get.copy(lib.skill['clanlieshi_backupx']); - next.choice=links[0]; + backup(links) { + var next = get.copy(lib.skill["clanlieshi_backupx"]); + next.choice = links[0]; return next; }, - prompt(links){ - if(links[0]=='damage') return '废除判定区并受到1点火焰伤害'; - return '弃置所有【'+get.translation(links[0])+'】'; + prompt(links) { + if (links[0] == "damage") return "废除判定区并受到1点火焰伤害"; + return "弃置所有【" + get.translation(links[0]) + "】"; }, }, - choices:[ - ['damage','废除判定区并受到1点火焰伤害'], - ['shan','弃置所有【闪】'], - ['sha','弃置所有【杀】'], + choices: [ + ["damage", "废除判定区并受到1点火焰伤害"], + ["shan", "弃置所有【闪】"], + ["sha", "弃置所有【杀】"], ], - ai:{ - order(item,player){ - if(!player) return; - var eff=get.damageEffect(player,player,player,'fire'),disabled=!player.isDisabledJudge(); - if((player.countCards('h','sha')==1||player.countCards('h','shan')==1)&&eff<0&&!disabled) return 8; - else if(eff>=0&&!disabled) return 5.8; - if(!disabled&&!player.countCards('h',card=>['sha','shan'].includes(get.name(card)))){ - if((!player.hasSkill('clanhuanyin')||!player.canSave(player))&&player.hp<=1) return 0; - if(player.canSave(player)&&player.hp==1&&player.countCards('h')<=1) return 2.6; - if(player.hpget.attitude(player,current)<0&¤t.countCards('h',card=>['sha','shan'].includes(get.name(card))))) return 0; + ai: { + order(item, player) { + if (!player) return; + var eff = get.damageEffect(player, player, player, "fire"), + disabled = !player.isDisabledJudge(); + if ( + (player.countCards("h", "sha") == 1 || player.countCards("h", "shan") == 1) && + eff < 0 && + !disabled + ) + return 8; + else if (eff >= 0 && !disabled) return 5.8; + if ( + !disabled && + !player.countCards("h", (card) => ["sha", "shan"].includes(get.name(card))) + ) { + if ( + (!player.hasSkill("clanhuanyin") || !player.canSave(player)) && + player.hp <= 1 + ) + return 0; + if (player.canSave(player) && player.hp == 1 && player.countCards("h") <= 1) + return 2.6; + if ( + player.hp < Math.max(2, 3 - player.getFriends().length) || + !game.countPlayer( + (current) => + get.attitude(player, current) < 0 && + current.countCards("h", (card) => + ["sha", "shan"].includes(get.name(card)) + ) + ) + ) + return 0; } return 2.5; }, - expose:0.2, - result:{player:1}, + expose: 0.2, + result: { player: 1 }, }, - subSkill:{ - backup:{}, - backupx:{ - audio:'clanlieshi', - selectCard:-1, - selectTarget:-1, - filterCard:()=>false, - filterTarget:()=>false, - multitarget:true, - content(){ - 'step 0' - var choice=lib.skill.clanlieshi_backup.choice; - event.choice=choice; - if(choice=='damage'){ - player.damage('fire'); - if(!player.isDisabledJudge()) player.disableJudge(); - }else{ - var cards=player.getCards('h',choice); - if(cards.length) player.discard(cards); + subSkill: { + backup: {}, + backupx: { + audio: "clanlieshi", + selectCard: -1, + selectTarget: -1, + filterCard: () => false, + filterTarget: () => false, + multitarget: true, + content() { + "step 0"; + var choice = lib.skill.clanlieshi_backup.choice; + event.choice = choice; + if (choice == "damage") { + player.damage("fire"); + if (!player.isDisabledJudge()) player.disableJudge(); + } else { + var cards = player.getCards("h", choice); + if (cards.length) player.discard(cards); } - 'step 1' - if(!player.isIn()||!game.hasPlayer(current=>current!=player)) event.finish(); - else player.chooseTarget('烈誓:令一名其他角色选择另一项',lib.filter.notMe,true).set('ai',target=>{ - var player=_status.event.player,chosen=_status.event.getParent().choice,att=get.attitude(player,target); - if(chosen=='damage'){ - if(att>0) return 0; - return -att/2+target.countCards('h',card=>['sha','shan'].includes(get.name(card))); - } - return get.damageEffect(target,player,player,'fire'); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'fire'); - var list=[],choice=event.choice; - var choiceList=lib.skill.clanlieshi.choices.slice(); - choiceList=choiceList.map((link,ind,arr)=>{ - link=link[1]; - var ok=true; - if(arr[ind][0]==choice){ - link+='('+get.translation(player)+'已选)'; - ok=false; + "step 1"; + if (!player.isIn() || !game.hasPlayer((current) => current != player)) + event.finish(); + else + player + .chooseTarget("烈誓:令一名其他角色选择另一项", lib.filter.notMe, true) + .set("ai", (target) => { + var player = _status.event.player, + chosen = _status.event.getParent().choice, + att = get.attitude(player, target); + if (chosen == "damage") { + if (att > 0) return 0; + return ( + -att / 2 + + target.countCards("h", (card) => + ["sha", "shan"].includes(get.name(card)) + ) + ); + } + return get.damageEffect(target, player, player, "fire"); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "fire"); + var list = [], + choice = event.choice; + var choiceList = lib.skill.clanlieshi.choices.slice(); + choiceList = choiceList.map((link, ind, arr) => { + link = link[1]; + var ok = true; + if (arr[ind][0] == choice) { + link += "(" + get.translation(player) + "已选)"; + ok = false; } - if(ind==0){ - if(target.isDisabledJudge()) ok=false; + if (ind == 0) { + if (target.isDisabledJudge()) ok = false; + } else if (ind > 0) { + var name = ind == 1 ? "shan" : "sha"; + if (!target.countCards("h", name)) ok = false; } - else if(ind>0){ - var name=ind==1?'shan':'sha'; - if(!target.countCards('h',name)) ok=false; - } - if(!ok) link=''+link+''; - else list.push('选项'+get.cnNumber(ind+1,true)); + if (!ok) link = '' + link + ""; + else list.push("选项" + get.cnNumber(ind + 1, true)); return link; }); - if(!list.length){ + if (!list.length) { game.log(target, "没有能执行的选项"); event.finish(); return; } - target.chooseControl(list).set('choiceList',choiceList).set('ai',()=>{ - var controls=_status.event.controls.slice(),player=_status.event.player,user=_status.event.getParent().player; - if(controls.length==1) return controls[0]; - if(controls.includes('选项一')&&get.damageEffect(player,user,player,'fire')>=0) return '选项一'; - if(controls.includes('选项一')&&player.hp<=2&&player.countCards('h',card=>['sha','shan'].includes(get.name(card)))<=3) controls.remove('选项一'); - if(controls.length==1) return controls[0]; - if(player.getCards('h','sha').reduce((p,c)=>p+get.value(c,player),0)>player.getCards('h','sha').reduce((p,c)=>p+get.value(c,player),0)){ - if(controls.includes('选项三')) return '选项三'; - } - else if(controls.includes('选项二')) return '选项二'; - return controls.randomGet(); - }); + target + .chooseControl(list) + .set("choiceList", choiceList) + .set("ai", () => { + var controls = _status.event.controls.slice(), + player = _status.event.player, + user = _status.event.getParent().player; + if (controls.length == 1) return controls[0]; + if ( + controls.includes("选项一") && + get.damageEffect(player, user, player, "fire") >= 0 + ) + return "选项一"; + if ( + controls.includes("选项一") && + player.hp <= 2 && + player.countCards("h", (card) => + ["sha", "shan"].includes(get.name(card)) + ) <= 3 + ) + controls.remove("选项一"); + if (controls.length == 1) return controls[0]; + if ( + player + .getCards("h", "sha") + .reduce((p, c) => p + get.value(c, player), 0) > + player + .getCards("h", "sha") + .reduce((p, c) => p + get.value(c, player), 0) + ) { + if (controls.includes("选项三")) return "选项三"; + } else if (controls.includes("选项二")) return "选项二"; + return controls.randomGet(); + }); } else event.finish(); - 'step 3' - if(result.control=='选项一'){ - if(!target.isDisabledJudge()) target.disableJudge(); - target.damage('fire'); + "step 3"; + if (result.control == "选项一") { + if (!target.isDisabledJudge()) target.disableJudge(); + target.damage("fire"); + } else { + var cards = target.getCards("h", result.control == "选项二" ? "shan" : "sha"); + if (cards.length) target.discard(cards); } - else{ - var cards=target.getCards('h',result.control=='选项二'?'shan':'sha'); - if(cards.length) target.discard(cards); - } - } - } - } - }, - clandianzhan:{ - audio:2, - intro:{ - content:'已使用过的花色:$', - onunmark:true, - }, - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - if(!lib.suit.includes(get.suit(event.card))) return false; - const suit=get.suit(event.card); - if(player.getRoundHistory('useCard',evt=>get.suit(evt.card)==suit).indexOf(event)!=0) return false; - return event.targets&&event.targets.length==1&&!event.targets[0].isLinked()||player.hasCard(card=>get.suit(card)==get.suit(event.card)&&player.canRecast(card),'h'); - }, - content(){ - 'step 0' - if(trigger.targets&&trigger.targets.length==1&&!trigger.targets[0].isLinked()){ - trigger.targets[0].link(true); - event.link=true; - } - var cards=player.getCards('h',card=>get.suit(card)==get.suit(trigger.card)&&player.canRecast(card)); - if(cards.length>0){ - player.recast(cards); - event.recast=true; - } - 'step 1' - if(event.link&&event.recast) player.draw(); - }, - group:'clandianzhan_count', - subSkill:{ - count:{ - charlotte:true, - trigger:{player:'useCardAfter'}, - filter(event,player){ - let suit=get.suit(event.card); - return lib.suits.includes(suit)&&!player.getStorage('clandianzhan').includes(suit); - }, - forced:true, - silent:true, - content(){ - let suits=player.getRoundHistory('useCard',evt=>{ - return lib.suits.includes(get.suit(evt.card)); - }).reduce((list,evt)=>{ - return list.add(get.suit(evt.card)); - },[]).sort((a,b)=>lib.suits.indexOf(a)-lib.suits.indexOf(b)); - if(!player.storage.clandianzhan){ - player.when({global:'roundStart'}).then(()=>{ - delete player.storage.clandianzhan; - player.unmarkSkill('clandianzhan'); - }); - } - player.storage.clandianzhan=suits; - player.markSkill('clandianzhan'); }, }, }, - init(player){ - let suits=player.getRoundHistory('useCard',evt=>{ - return lib.suits.includes(get.suit(evt.card)); - }).reduce((list,evt)=>{ - return list.add(get.suit(evt.card)); - },[]).sort((a,b)=>lib.suits.indexOf(a)-lib.suits.indexOf(b)); - if(suits.length){ - if(!player.storage.clandianzhan){ - player.when({global:'roundStart'}).then(()=>{ + }, + clandianzhan: { + audio: 2, + intro: { + content: "已使用过的花色:$", + onunmark: true, + }, + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + if (!lib.suit.includes(get.suit(event.card))) return false; + const suit = get.suit(event.card); + if ( + player + .getRoundHistory("useCard", (evt) => get.suit(evt.card) == suit) + .indexOf(event) != 0 + ) + return false; + return ( + (event.targets && event.targets.length == 1 && !event.targets[0].isLinked()) || + player.hasCard( + (card) => get.suit(card) == get.suit(event.card) && player.canRecast(card), + "h" + ) + ); + }, + content() { + "step 0"; + if (trigger.targets && trigger.targets.length == 1 && !trigger.targets[0].isLinked()) { + trigger.targets[0].link(true); + event.link = true; + } + var cards = player.getCards( + "h", + (card) => get.suit(card) == get.suit(trigger.card) && player.canRecast(card) + ); + if (cards.length > 0) { + player.recast(cards); + event.recast = true; + } + "step 1"; + if (event.link && event.recast) player.draw(); + }, + group: "clandianzhan_count", + subSkill: { + count: { + charlotte: true, + trigger: { player: "useCardAfter" }, + filter(event, player) { + let suit = get.suit(event.card); + return ( + lib.suits.includes(suit) && !player.getStorage("clandianzhan").includes(suit) + ); + }, + forced: true, + silent: true, + content() { + let suits = player + .getRoundHistory("useCard", (evt) => { + return lib.suits.includes(get.suit(evt.card)); + }) + .reduce((list, evt) => { + return list.add(get.suit(evt.card)); + }, []) + .sort((a, b) => lib.suits.indexOf(a) - lib.suits.indexOf(b)); + if (!player.storage.clandianzhan) { + player.when({ global: "roundStart" }).then(() => { + delete player.storage.clandianzhan; + player.unmarkSkill("clandianzhan"); + }); + } + player.storage.clandianzhan = suits; + player.markSkill("clandianzhan"); + }, + }, + }, + init(player) { + let suits = player + .getRoundHistory("useCard", (evt) => { + return lib.suits.includes(get.suit(evt.card)); + }) + .reduce((list, evt) => { + return list.add(get.suit(evt.card)); + }, []) + .sort((a, b) => lib.suits.indexOf(a) - lib.suits.indexOf(b)); + if (suits.length) { + if (!player.storage.clandianzhan) { + player.when({ global: "roundStart" }).then(() => { delete player.storage.clandianzhan; - player.unmarkSkill('clandianzhan'); + player.unmarkSkill("clandianzhan"); }); } - player.storage.clandianzhan=suits; - player.markSkill('clandianzhan'); + player.storage.clandianzhan = suits; + player.markSkill("clandianzhan"); } - } - }, - clanhuanyin:{ - audio:2, - trigger:{player:'dying'}, - forced:true, - check:()=>true, - filter(event){ - return event.player.countCards('h')<4; }, - content(){ + }, + clanhuanyin: { + audio: 2, + trigger: { player: "dying" }, + forced: true, + check: () => true, + filter(event) { + return event.player.countCards("h") < 4; + }, + content() { player.drawTo(4); - } - }, - clandaojie:{ - audio:2, - audioname:['clan_xunshu','clan_xunchen','clan_xuncai','clan_xuncan','clan_xunyou'], - trigger:{player:'useCardAfter'}, - filter(event,player){ - return get.type(event.card,null,false)=='trick'&&!get.tag(event.card,'damage')&&event.cards.filterInD().length>0&&player.getHistory('useCard',evt=>{ - return get.type(evt.card,null,false)=='trick'&&!get.tag(evt.card,'damage'); - }).indexOf(event)==0; }, - forced:true, - clanSkill:true, - content(){ - 'step 0' - var skills=player.getSkills(null,false,false).filter(skill=>{ - var info=get.info(skill); - if(!info||info.charlotte||!get.is.locked(skill)||get.skillInfoTranslation(skill,player).length==0) return false; + }, + clandaojie: { + audio: 2, + audioname: ["clan_xunshu", "clan_xunchen", "clan_xuncai", "clan_xuncan", "clan_xunyou"], + trigger: { player: "useCardAfter" }, + filter(event, player) { + return ( + get.type(event.card, null, false) == "trick" && + !get.tag(event.card, "damage") && + event.cards.filterInD().length > 0 && + player + .getHistory("useCard", (evt) => { + return ( + get.type(evt.card, null, false) == "trick" && !get.tag(evt.card, "damage") + ); + }) + .indexOf(event) == 0 + ); + }, + forced: true, + clanSkill: true, + content() { + "step 0"; + var skills = player.getSkills(null, false, false).filter((skill) => { + var info = get.info(skill); + if ( + !info || + info.charlotte || + !get.is.locked(skill) || + get.skillInfoTranslation(skill, player).length == 0 + ) + return false; return true; }); - player.chooseControl(skills,'cancel2').set('choiceList',skills.map(i=>{ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','蹈节:失去一个锁定技,或点“取消”失去1点体力').set('ai',()=>{ - var player=_status.event.player,choices=_status.event.controls.slice(); - var negs=choices.filter(i=>{ - var info=get.info(i); - if(!info||!info.ai) return false; - return info.ai.neg||info.ai.halfneg; + player + .chooseControl(skills, "cancel2") + .set( + "choiceList", + skills.map((i) => { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "蹈节:失去一个锁定技,或点“取消”失去1点体力") + .set("ai", () => { + var player = _status.event.player, + choices = _status.event.controls.slice(); + var negs = choices.filter((i) => { + var info = get.info(i); + if (!info || !info.ai) return false; + return info.ai.neg || info.ai.halfneg; + }); + if (negs.length) return negs.randomGet(); + if (get.effect(player, { name: "losehp" }, player, player) >= 0) return "cancel2"; + if (player.hp > 3) return "cancel2"; + return Math.random() < 0.75 ? "clandaojie" : choices.randomGet(); }); - if(negs.length) return negs.randomGet(); - if(get.effect(player,{name:'losehp'},player,player)>=0) return 'cancel2'; - if(player.hp>3) return 'cancel2'; - return Math.random()<0.75?'clandaojie':choices.randomGet(); - }); - 'step 1' - if(result.control!='cancel2'){ + "step 1"; + if (result.control != "cancel2") { player.removeSkills(result.control); - } - else{ + } else { player.loseHp(); } - 'step 2' - var targets=game.filterPlayer(current=>current==player||current.hasClan('颍川荀氏')); - if(targets.length==1) event._result={bool:true,targets:targets}; - else player.chooseTarget('蹈节:将'+get.translation(trigger.cards.filterInD())+'交给一名颍川荀氏角色',true,(card,player,target)=>{ - return target==player||target.hasClan('颍川荀氏') - }).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(trigger.cards.filterInD(),player,'gain2'); + "step 2"; + var targets = game.filterPlayer( + (current) => current == player || current.hasClan("颍川荀氏") + ); + if (targets.length == 1) event._result = { bool: true, targets: targets }; + else + player + .chooseTarget( + "蹈节:将" + + get.translation(trigger.cards.filterInD()) + + "交给一名颍川荀氏角色", + true, + (card, player, target) => { + return target == player || target.hasClan("颍川荀氏"); + } + ) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(trigger.cards.filterInD(), player, "gain2"); } }, }, //族吴班 - clanzhanding:{ - audio:2, - enable:'chooseToUse', - viewAsFilter(player){ - return player.countCards('hes')>0; + clanzhanding: { + audio: 2, + enable: "chooseToUse", + viewAsFilter(player) { + return player.countCards("hes") > 0; }, - viewAs:{name:'sha'}, - filterCard:true, - position:'hes', - selectCard:[1,Infinity], - check(card){ - return 6-ui.selected.cards.length-get.value(card); + viewAs: { name: "sha" }, + filterCard: true, + position: "hes", + selectCard: [1, Infinity], + check(card) { + return 6 - ui.selected.cards.length - get.value(card); }, - onuse(links,player){ - lib.skill.chenliuwushi.change(player,-1); - player.addTempSkill('clanzhanding_effect'); + onuse(links, player) { + lib.skill.chenliuwushi.change(player, -1); + player.addTempSkill("clanzhanding_effect"); }, - ai:{ - order:1, - respondSha:true, - skillTagFilter(player){ - return player.countCards('hes')>0; + ai: { + order: 1, + respondSha: true, + skillTagFilter(player) { + return player.countCards("hes") > 0; }, }, - subSkill:{ - effect:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='clanzhanding'; + subSkill: { + effect: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter(event, player) { + return event.skill == "clanzhanding"; }, - content(){ - if(player.hasHistory('sourceDamage',function(evt){ - return evt.card==trigger.card; - })){ - var num1=player.countCards('h'),num2=player.getHandcardLimit(); - if(num1num2) return num1-num2; - return [0,1]; + selectCard() { + var player = _status.event.player; + var num1 = player.countCards("h"), + num2 = player.getHandcardLimit(); + if (num1 > num2) return num1 - num2; + return [0, 1]; }, - filterCard(card,player){ - var num1=player.countCards('h'),num2=player.getHandcardLimit(); - return num1>num2; + filterCard(card, player) { + var num1 = player.countCards("h"), + num2 = player.getHandcardLimit(); + return num1 > num2; }, - check(card){ - var player=_status.event.player; - if(player.countCards('h',function(card){ - return lib.skill.clanyirong.checkx(card)>0; - })+1<(player.countCards('h')-player.getHandcardLimit())) return 0; + check(card) { + var player = _status.event.player; + if ( + player.countCards("h", function (card) { + return lib.skill.clanyirong.checkx(card) > 0; + }) + + 1 < + player.countCards("h") - player.getHandcardLimit() + ) + return 0; return lib.skill.clanyirong.checkx(card); }, - checkx(card){ - var num=1; - if(_status.event.player.getUseValue(card,null,true)<=0) num=1.5; - return (15-get.value(card))*num; + checkx(card) { + var num = 1; + if (_status.event.player.getUseValue(card, null, true) <= 0) num = 1.5; + return (15 - get.value(card)) * num; }, - prompt(){ - var player=_status.event.player; - var num1=player.countCards('h'),num2=player.getHandcardLimit(); - var str=''; - if(num1>num2){ - str+=('弃置'+get.cnNumber(num1-num2)+'张牌,然后手牌上限+1。') + prompt() { + var player = _status.event.player; + var num1 = player.countCards("h"), + num2 = player.getHandcardLimit(); + var str = ''; + if (num1 > num2) { + str += "弃置" + get.cnNumber(num1 - num2) + "张牌,然后手牌上限+1。"; + } else { + str += "摸" + get.cnNumber(Math.min(8, num2 - num1)) + "张牌,然后手牌上限-1。"; } - else{ - str+=('摸'+get.cnNumber(Math.min(8,num2-num1))+'张牌,然后手牌上限-1。'); + str += "
              ※当前手牌上限:" + num2; + var num3 = (_status.event.getParent().phaseIndex || 0) + 1; + if (num3 > 0) { + str += ";阶段数:" + num3; } - str+=('
              ※当前手牌上限:'+num2); - var num3=((_status.event.getParent().phaseIndex||0)+1); - if(num3>0){ - str+=(';阶段数:'+num3) - } - str+='
              '; + str += "
              "; return str; }, - content(){ - 'step 0' - if(cards.length){ - lib.skill.chenliuwushi.change(player,1); + content() { + "step 0"; + if (cards.length) { + lib.skill.chenliuwushi.change(player, 1); event.finish(); + } else { + var num1 = player.countCards("h"), + num2 = player.getHandcardLimit(); + if (num1 < num2) player.draw(Math.min(8, num2 - num1)); } - else{ - var num1=player.countCards('h'),num2=player.getHandcardLimit(); - if(num14&&numx>4)) return 10; + ai: { + order(item, player) { + 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; }, - result:{player:1}, - threaten:5, + result: { player: 1 }, + threaten: 5, }, }, - clanguixiang:{ - audio:2, - trigger:{ - player:'phaseChange', + clanguixiang: { + audio: 2, + trigger: { + player: "phaseChange", }, - forced:true, - filter(event,player){ - if(event.phaseList[event.num].startsWith('phaseUse')) return false; - var num1=player.getHandcardLimit()-1,num2=event.num; - return num1==num2; + forced: true, + filter(event, player) { + if (event.phaseList[event.num].startsWith("phaseUse")) return false; + var num1 = player.getHandcardLimit() - 1, + num2 = event.num; + return num1 == num2; }, - content(){ - trigger.phaseList[trigger.num]='phaseUse|clanguixiang'; + content() { + trigger.phaseList[trigger.num] = "phaseUse|clanguixiang"; game.delayx(); }, }, - clanmuyin:{ - audio:2, - clanSkill:true, - audioname:['clan_wuxian','clan_wuban','clan_wukuang','clan_wuqiao'], - trigger:{player:'phaseBegin'}, - isMax(player){ - var num=player.getHandcardLimit(); - return !game.hasPlayer(function(current){ - return current!=player&¤t.getHandcardLimit()>num; + clanmuyin: { + audio: 2, + clanSkill: true, + audioname: ["clan_wuxian", "clan_wuban", "clan_wukuang", "clan_wuqiao"], + trigger: { player: "phaseBegin" }, + isMax(player) { + var num = player.getHandcardLimit(); + return !game.hasPlayer(function (current) { + return current != player && current.getHandcardLimit() > num; }); }, - filter(event,player){ - return game.hasPlayer(function(current){ - return (current==player||current.hasClan('陈留吴氏'))&&!lib.skill.clanmuyin.isMax(current); + filter(event, player) { + return game.hasPlayer(function (current) { + return ( + (current == player || current.hasClan("陈留吴氏")) && + !lib.skill.clanmuyin.isMax(current) + ); }); }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('clanmuyin'),'令一名陈留吴氏角色的手牌上限+1',function(card,player,current){ - return (current==player||current.hasClan('陈留吴氏'))&&!lib.skill.clanmuyin.isMax(current); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('clanmuyin',target); - lib.skill.chenliuwushi.change(target,1); + direct: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("clanmuyin"), + "令一名陈留吴氏角色的手牌上限+1", + function (card, player, current) { + return ( + (current == player || current.hasClan("陈留吴氏")) && + !lib.skill.clanmuyin.isMax(current) + ); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("clanmuyin", target); + lib.skill.chenliuwushi.change(target, 1); game.delayx(); } }, }, - chenliuwushi:{ - charlotte:true, - change(player,num){ - player.addSkill('chenliuwushi'); - var info=player.storage; - if(typeof info.chenliuwushi!='number') info.chenliuwushi=0; - info.chenliuwushi+=num; - if(info.chenliuwushi==0) player.unmarkSkill('chenliuwushi'); - else player.markSkill('chenliuwushi'); - if(num>=0) game.log(player,'的手牌上限','#y+'+num); - else game.log(player,'的手牌上限','#g'+num); + chenliuwushi: { + charlotte: true, + change(player, num) { + player.addSkill("chenliuwushi"); + var info = player.storage; + if (typeof info.chenliuwushi != "number") info.chenliuwushi = 0; + info.chenliuwushi += num; + if (info.chenliuwushi == 0) player.unmarkSkill("chenliuwushi"); + else player.markSkill("chenliuwushi"); + if (num >= 0) game.log(player, "的手牌上限", "#y+" + num); + else game.log(player, "的手牌上限", "#g" + num); }, - mod:{ - maxHandcard(player,num){ - var add=player.storage.chenliuwushi; - if(typeof add=='number') return num+add; + mod: { + maxHandcard(player, num) { + var add = player.storage.chenliuwushi; + if (typeof add == "number") return num + add; }, }, - markimage:'image/card/handcard.png', - intro:{ - content(num,player){ - var str='
            • 手牌上限'; - if(num>=0) str+='+'; - str+=num; - str+='
            • 当前手牌上限:'; - str+=player.getHandcardLimit(); + markimage: "image/card/handcard.png", + intro: { + content(num, player) { + var str = "
            • 手牌上限"; + if (num >= 0) str += "+"; + str += num; + str += "
            • 当前手牌上限:"; + str += player.getHandcardLimit(); return str; }, }, }, }, - characterReplace:{ - wuban:['clan_wuban','dc_wuban','wuban','xin_wuban'], + characterReplace: { + wuban: ["clan_wuban", "dc_wuban", "wuban", "xin_wuban"], }, - characterIntro:{ - xunshu:'荀淑(83年~149年),字季和,为郎陵侯相,颍川颍阴人(今河南省许昌市)人。汉和帝至汉桓帝时人物,以品行高洁著称。有子八人,号八龙。年轻时有高尚的德行,学问渊博,不喜欢雕章琢句,徒在文字上用功,不注重实际的学识。因此,常常被俗儒看不起。但州里却称他有知人之明。安帝时,征召任为郎中,后来再升当涂长。离职还乡里。他的孙子荀彧是曹操部下著名的谋士。', - xuncai:'荀采(生卒年不详),字女荀,颍川人,东汉名士荀爽之女。荀采聪慧敏捷而有才艺。十七岁时,荀采嫁给阴瑜。两年后阴瑜去世。荀采不愿意改嫁,但荀爽答应把荀采嫁给同郡人郭奕。荀采趁着旁人没有防备,用粉在门上写下:“尸还阴”,而后自缢而死。', - xuncan:'荀粲(210年—238年),字奉倩,颍川郡颍阴县(今河南省许昌市)人。三国时期曹魏大臣、玄学家,太尉荀彧幼子。个性简贵,不轻易交接常人,所交之辈皆一时俊杰。聪颖过人,善谈玄理,名噪一时。娶大将军曹洪之女为妻,生活美满。景初二年,面对妻子去世,悲痛过度而死,时年二十九,成语“荀令伤神”与之有关。', - hanshao:'韩韶(生卒年不详),字仲黄,颍川舞阳(今河南省漯河市)人,东汉桓帝时出仕。任郡吏,有政绩,继而被征入司徒府。他公正廉明,尽心民事,视民苦如在己身,政绩卓著。汉永寿二年(公元156年),泰山贼公孙举率流寇数千骚扰嬴县,守令因不能拒敌安民,多受制裁,朝廷命尚书府从三府(司徒、司马、司空)属员中,选择能治理民事,又能拒寇入侵的官员,前往镇守。韩韶被封为“嬴长”到嬴县上任,他是莱芜历史上唯一的一位“嬴长”。', - hanrong:'韩融(127年~196年),字元长,颍川舞阳(今属河南省漯河市)人。赢长韩韶子,献帝时大臣。中平五年(188年),融与荀爽、陈纪等十四人并博士征,不至。董卓废立,融等复俱公车征。初平元年(190年)六月,融为大鸿胪,奉命与执金吾胡母班等出使关东。献帝东迁,为李傕、郭汜等所败,融为太仆,奉命至弘农与傕、汜连和,使其放遣公卿百官及宫女妇人。', - wukuang:'吴匡(生卒年不详),兖州陈留(今河南开封市)人。东汉末年大臣,大将军何进部将。光熹元年(公元189年),汉灵帝死后,十常侍干预朝政,大将军何进谋诛宦官,但失败被杀,吴匡联合曹操、袁绍等杀尽宦官,攻杀车骑将军何苗。兴平二年(公元195年)十月,李傕、郭汜后悔放汉献帝东归洛阳,于是联合起来追击,曹操遂起兵平乱,但在回朝后,曹操挟天子以令诸侯,实行专权,但遭到吴匡反对。', - wanghun:'王浑(223年~297年),字玄冲,太原郡晋阳县(今山西省太原市)人。魏晋时期名臣,曹魏司空王昶的儿子。王浑早年为大将军曹爽的掾吏,高平陵政变后,循例免官,出任怀县县令、散骑侍郎等职,袭封京陵县侯。西晋王朝建立后,加号扬烈将军,历任征虏将军、东中郎将、豫州刺史等职,积极筹划伐吴方略。咸宁五年(279年),配合镇南将军杜预灭亡吴国,迁征东大将军、左仆射、司徒公,晋爵京陵县公。晋惠帝司马衷即位,加任侍中衔。楚王司马玮发动政变,有意寻求支持,遭到严词拒绝。楚王司马玮死后,复任司徒、录尚书事。元康七年(297年),王浑去世,享年七十五岁,谥号为元。《唐会要》尊为“魏晋八君子”之一。', - zhongyu:'钟毓(?-263年),字稚叔,颍川长社(今河南长葛市)人。三国时期魏国大臣,太傅钟繇之子、司徒钟会之兄。出身颍川钟氏,机灵敏捷,有其父之遗风。十四岁时,起家散骑侍郎。太和初年,迁黄门侍郎,袭封定陵县侯。正始年间,拜散骑常侍,迁魏郡太守,入为侍中、御史中丞、廷尉 [5] 。随平诸葛诞的淮南叛乱,拜青州刺史、后将军,都督徐州、荆州诸军事。景元四年(263年),去世,追赠车骑将军,谥号为惠,著有文集五卷(见《隋书·经籍志》及《两唐书·经籍志》),传于世。', - wanglun:'王沦(233年-257年)字太冲,出身太原晋阳王姓世族(今山西省太原市),王昶三子,王浑、王深之弟,王湛之兄。醇粹简远,崇尚老庄之学,心思平淡。二十多时被举荐为孝廉,没有前往,后任大将军参军。257年,诸葛诞不满司马氏篡权而在寿春起义,王沦跟随司马昭征讨,遭遇疾疫去世,时年二十五,时人惜之,司马昭为他流泪。其兄著诔文《表德论》,表述其德行,说“因为畏惧帝王的典章制度,不能写墓志铭,于是撰写过往的事迹,刻在墓的背面。”', - wuqiao:'吴乔,西晋人物,蜀车骑将军吴懿之孙。李雄建立成汉政权,他沦落益州,长达三十年,始终不向李雄屈服。', - clan_wangguang:'王广,三国时期曹魏太原祁县人,哲学家。东汉司徒王允从孙,魏太尉王凌之子。有志尚学,官至尚书。魏时随父亲在朝作官,屯骑校尉,机智有谋。当得知司马懿篡夺曹魏政权时,王凌与外甥令狐愚合谋立楚王为魏主,王广劝其父不可,王凌没有接受儿子的谏言,结果计谋泄而被害。', - wangmingshan:'王明山,王凌的小儿子,太原祁(今山西省祁县)人,三国魏书法家,最知名善画,多技艺,人得其书,皆以为法。太尉王凌参与谋划废立,事情泄露,被太傅司马懿领兵平定。', + characterIntro: { + xunshu: "荀淑(83年~149年),字季和,为郎陵侯相,颍川颍阴人(今河南省许昌市)人。汉和帝至汉桓帝时人物,以品行高洁著称。有子八人,号八龙。年轻时有高尚的德行,学问渊博,不喜欢雕章琢句,徒在文字上用功,不注重实际的学识。因此,常常被俗儒看不起。但州里却称他有知人之明。安帝时,征召任为郎中,后来再升当涂长。离职还乡里。他的孙子荀彧是曹操部下著名的谋士。", + xuncai: "荀采(生卒年不详),字女荀,颍川人,东汉名士荀爽之女。荀采聪慧敏捷而有才艺。十七岁时,荀采嫁给阴瑜。两年后阴瑜去世。荀采不愿意改嫁,但荀爽答应把荀采嫁给同郡人郭奕。荀采趁着旁人没有防备,用粉在门上写下:“尸还阴”,而后自缢而死。", + xuncan: "荀粲(210年—238年),字奉倩,颍川郡颍阴县(今河南省许昌市)人。三国时期曹魏大臣、玄学家,太尉荀彧幼子。个性简贵,不轻易交接常人,所交之辈皆一时俊杰。聪颖过人,善谈玄理,名噪一时。娶大将军曹洪之女为妻,生活美满。景初二年,面对妻子去世,悲痛过度而死,时年二十九,成语“荀令伤神”与之有关。", + hanshao: + "韩韶(生卒年不详),字仲黄,颍川舞阳(今河南省漯河市)人,东汉桓帝时出仕。任郡吏,有政绩,继而被征入司徒府。他公正廉明,尽心民事,视民苦如在己身,政绩卓著。汉永寿二年(公元156年),泰山贼公孙举率流寇数千骚扰嬴县,守令因不能拒敌安民,多受制裁,朝廷命尚书府从三府(司徒、司马、司空)属员中,选择能治理民事,又能拒寇入侵的官员,前往镇守。韩韶被封为“嬴长”到嬴县上任,他是莱芜历史上唯一的一位“嬴长”。", + hanrong: + "韩融(127年~196年),字元长,颍川舞阳(今属河南省漯河市)人。赢长韩韶子,献帝时大臣。中平五年(188年),融与荀爽、陈纪等十四人并博士征,不至。董卓废立,融等复俱公车征。初平元年(190年)六月,融为大鸿胪,奉命与执金吾胡母班等出使关东。献帝东迁,为李傕、郭汜等所败,融为太仆,奉命至弘农与傕、汜连和,使其放遣公卿百官及宫女妇人。", + wukuang: + "吴匡(生卒年不详),兖州陈留(今河南开封市)人。东汉末年大臣,大将军何进部将。光熹元年(公元189年),汉灵帝死后,十常侍干预朝政,大将军何进谋诛宦官,但失败被杀,吴匡联合曹操、袁绍等杀尽宦官,攻杀车骑将军何苗。兴平二年(公元195年)十月,李傕、郭汜后悔放汉献帝东归洛阳,于是联合起来追击,曹操遂起兵平乱,但在回朝后,曹操挟天子以令诸侯,实行专权,但遭到吴匡反对。", + wanghun: + "王浑(223年~297年),字玄冲,太原郡晋阳县(今山西省太原市)人。魏晋时期名臣,曹魏司空王昶的儿子。王浑早年为大将军曹爽的掾吏,高平陵政变后,循例免官,出任怀县县令、散骑侍郎等职,袭封京陵县侯。西晋王朝建立后,加号扬烈将军,历任征虏将军、东中郎将、豫州刺史等职,积极筹划伐吴方略。咸宁五年(279年),配合镇南将军杜预灭亡吴国,迁征东大将军、左仆射、司徒公,晋爵京陵县公。晋惠帝司马衷即位,加任侍中衔。楚王司马玮发动政变,有意寻求支持,遭到严词拒绝。楚王司马玮死后,复任司徒、录尚书事。元康七年(297年),王浑去世,享年七十五岁,谥号为元。《唐会要》尊为“魏晋八君子”之一。", + zhongyu: + "钟毓(?-263年),字稚叔,颍川长社(今河南长葛市)人。三国时期魏国大臣,太傅钟繇之子、司徒钟会之兄。出身颍川钟氏,机灵敏捷,有其父之遗风。十四岁时,起家散骑侍郎。太和初年,迁黄门侍郎,袭封定陵县侯。正始年间,拜散骑常侍,迁魏郡太守,入为侍中、御史中丞、廷尉 [5] 。随平诸葛诞的淮南叛乱,拜青州刺史、后将军,都督徐州、荆州诸军事。景元四年(263年),去世,追赠车骑将军,谥号为惠,著有文集五卷(见《隋书·经籍志》及《两唐书·经籍志》),传于世。", + wanglun: + "王沦(233年-257年)字太冲,出身太原晋阳王姓世族(今山西省太原市),王昶三子,王浑、王深之弟,王湛之兄。醇粹简远,崇尚老庄之学,心思平淡。二十多时被举荐为孝廉,没有前往,后任大将军参军。257年,诸葛诞不满司马氏篡权而在寿春起义,王沦跟随司马昭征讨,遭遇疾疫去世,时年二十五,时人惜之,司马昭为他流泪。其兄著诔文《表德论》,表述其德行,说“因为畏惧帝王的典章制度,不能写墓志铭,于是撰写过往的事迹,刻在墓的背面。”", + wuqiao: "吴乔,西晋人物,蜀车骑将军吴懿之孙。李雄建立成汉政权,他沦落益州,长达三十年,始终不向李雄屈服。", + clan_wangguang: + "王广,三国时期曹魏太原祁县人,哲学家。东汉司徒王允从孙,魏太尉王凌之子。有志尚学,官至尚书。魏时随父亲在朝作官,屯骑校尉,机智有谋。当得知司马懿篡夺曹魏政权时,王凌与外甥令狐愚合谋立楚王为魏主,王广劝其父不可,王凌没有接受儿子的谏言,结果计谋泄而被害。", + wangmingshan: + "王明山,王凌的小儿子,太原祁(今山西省祁县)人,三国魏书法家,最知名善画,多技艺,人得其书,皆以为法。太尉王凌参与谋划废立,事情泄露,被太傅司马懿领兵平定。", }, - dynamicTranslate:{ - clanlianzhu(player){ - if(player.storage.clanlianzhu) return '转换技。每名角色A的出牌阶段限一次。阴:A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1;阳:A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1。'; + dynamicTranslate: { + clanlianzhu(player) { + if (player.storage.clanlianzhu) + return '转换技。每名角色A的出牌阶段限一次。阴:A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1;阳:A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1。'; return '转换技。每名角色A的出牌阶段限一次。阴:A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1;阳:A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1。'; }, - clanguangu(player){ - if(player.storage.clanguangu) return '转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。'; + clanguangu(player) { + if (player.storage.clanguangu) + return '转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。'; return '转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。'; }, - clanjiexuan(player){ - if(player.storage.clanjiexuan) return '限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。'; + clanjiexuan(player) { + if (player.storage.clanjiexuan) + return '限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。'; return '限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。'; }, }, - translate:{ - clan_wuxian_prefix:'族', - clan_wuban_prefix:'族', - clan_xunshu_prefix:'族', - clan_xunchen_prefix:'族', - clan_xuncai_prefix:'族', - clan_xuncan_prefix:'族', - clan_hanshao_prefix:'族', - clan_hanrong_prefix:'族', - clan_wukuang_prefix:'族', - clan_wangling_prefix:'族', - clan_zhongyan_prefix:'族', - clan_wangyun_prefix:'族', - clan_wanghun_prefix:'族', - clan_zhonghui_prefix:'族', - clan_zhongyu_prefix:'族', - clan_wanglun_prefix:'族', - clan_xunyou_prefix:'族', - clan_wuqiao_prefix:'族', + translate: { + clan_wuxian_prefix: "族", + clan_wuban_prefix: "族", + clan_xunshu_prefix: "族", + clan_xunchen_prefix: "族", + clan_xuncai_prefix: "族", + clan_xuncan_prefix: "族", + clan_hanshao_prefix: "族", + clan_hanrong_prefix: "族", + clan_wukuang_prefix: "族", + clan_wangling_prefix: "族", + clan_zhongyan_prefix: "族", + clan_wangyun_prefix: "族", + clan_wanghun_prefix: "族", + clan_zhonghui_prefix: "族", + clan_zhongyu_prefix: "族", + clan_wanglun_prefix: "族", + clan_xunyou_prefix: "族", + clan_wuqiao_prefix: "族", - clan_wuxian:'族吴苋', - clanyirong:'移荣', - clanyirong_info:'出牌阶段限两次。若你的手牌数:小于X,则你可以将手牌摸至X张(至多摸八张),然后X-1;大于X,则你可以将手牌弃置至X张,然后X+1。(X为你的手牌上限)', - clanguixiang:'贵相', - clanguixiang_info:'锁定技。你的非出牌阶段开始前,若此阶段即将成为你本回合内的第X个阶段(X为你的手牌上限),则你终止此阶段,改为进行一个出牌阶段。', - clanmuyin:'穆荫', - clanmuyin_info:'宗族技。回合开始时,你可以选择一名手牌上限不为全场最多的陈留吴氏角色。该角色的手牌上限+1。', - chenliuwushi:'陈留·吴氏', - clan_wuban:'族吴班', - clanzhanding:'斩钉', - clanzhanding_info:'你可以将任意张牌当做【杀】使用并你令你的手牌上限-1。你以此法使用的【杀】结算结束后,若你因此【杀】造成过伤害,则你将手牌摸至手牌上限(至多摸五张),否则你令此【杀】不计入次数限制。', - clan_xunshu:'族荀淑', - clanshenjun:'神君', - clanshenjun_info:'当一名角色使用【杀】或普通锦囊牌时,若你手牌中有该牌名的牌,你展示之,且这些牌称为“神君”。然后本阶段结束时,你可以将等同于你“神君”数张牌当做一张“神君”牌使用。', - clanbalong:'八龙', - clanbalong_info:'锁定技。当你于一回合内首次{回复体力后或受到伤害后或失去体力后},若你手牌中唯一最多的类别为锦囊牌,你展示所有手牌并摸至角色数张。', - clandaojie:'蹈节', - clandaojie_info:'宗族技,锁定技。当你每回合第一次使用非伤害类普通锦囊牌后,你须失去一个锁定技或失去1点体力,令一名颍川荀氏角色获得此牌对应的所有实体牌。', - clan_xuncai:'族荀采', - clanlieshi:'烈誓', - clanlieshi_info:'出牌阶段,你可以选择一项:1.废除判定区并受到你造成的1点火焰伤害;2.弃置所有【闪】;3.弃置所有【杀】。然后令一名其他角色从你未选择的选项中选择一项。', - clandianzhan:'点盏', - clandianzhan_info:'锁定技。当你每轮第一次使用一种花色的牌后:若此牌的目标数为1且目标未横置,你横置此牌目标;若你有此花色的手牌,你重铸这些牌。均执行后你摸一张牌。', - clanhuanyin:'还阴', - clanhuanyin_info:'锁定技。当你进入濒死状态时,将手牌补至四张。', - clan_xunchen:'族荀谌', - clansankuang:'三恇', - clansankuang_info:'锁定技。当你每轮第一次使用一种类别的牌后,你令一名其他角色交给你至少X张牌,然后于装备区或处理区内获得你使用的牌对应的所有实体牌(X为以下条件中其满足的项数:场上有牌、已受伤、体力值小于手牌数)。', - clanbeishi:'卑势', - clanbeishi_info:'锁定技。当一名角色失去最后的手牌后,若其是你首次发动〖三恇〗的目标角色,你回复1点体力。', - clan_xuncan:'族荀粲', - clanyunshen:'熨身', - clanyunshen_info:'出牌阶段限一次。你可以令一名其他角色回复1点体力,然后选择一项:1.你视为对其使用一张冰【杀】;2.其视为对你使用一张冰【杀】。', - clanshangshen:'伤神', - clanshangshen_info:'当一名角色受到属性伤害后,若本回合此前没有角色或已死亡的角色受到过属性伤害,你可以执行目标角色为你的【闪电】效果,然后其将手牌摸至四张。', - clanfenchai:'分钗', - clanfenchai_info:'锁定技。若你首次发动技能指定的异性目标角色中:存在存活角色,你的判定牌视为♥;不存在存活角色,你的判定牌视为♠。', - clan_hanshao:'族韩韶', - clanfangzhen:'放赈', - clanfangzhen_info:'出牌阶段开始时,你可以横置一名角色并选择一项:1.摸两张牌,然后交给其两张牌;2.令其回复1点体力。然后第X轮游戏开始时,你失去〖放赈〗(X为其座位号)。', - clanliuju:'留驹', - clanliuju_info:'出牌阶段结束时,你可以与一名角色A拼点,输的角色可以使用任意张拼点牌中的非基本牌。然后若你至A的距离或A至你的距离发生了变化,你重置〖恤民〗。', - clanxumin:'恤民', - clanxumin_info:'宗族技,限定技。你可以将一张牌当做【五谷丰登】对任意名其他角色使用。', - clan_hanrong:'族韩融', - clanlianhe:'连和', - clanlianhe_info:'出牌阶段开始时,你可以横置两名角色。这些角色于自己的下个出牌阶段结束时,若其此阶段未摸牌,其令你摸X+1张牌或交给你X-1张牌(X为其此阶段获得的牌数且至多为3)。', - clanhuanjia:'缓颊', - clanhuanjia_info:'出牌阶段结束时,你可以与一名角色拼点。赢的角色可以使用一张拼点牌。然后若此牌:未造成过伤害,你获得另一张拼点牌;造成过伤害,你失去一个技能。', - clan_wukuang:'族吴匡', - clanlianzhu:'联诛', - clanlianzhu_info:'转换技。每名角色A的出牌阶段限一次。阴:A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色不同,则你的手牌上限-1;阳:A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色相同,则你的手牌上限+1。', - clan_wangling:'族王淩', - clanbolong:'驳龙', - clanbolong_info:'出牌阶段限一次。你可以令一名其他角色选择一项:1.你交给其一张牌,然后视为对其使用一张雷【杀】;2.交给你等同于你手牌数的牌,然后视为对你使用一张【酒】。', - clanzhongliu:'中流', - clanzhongliu_info:'宗族技,锁定技。当你使用牌时,若此牌对应的实体牌均不为太原王氏角色的手牌,你重置武将牌上的技能。', - clan_zhongyan:'族钟琰', - clanguangu:'观骨', - clanguangu_info:'转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。', - clanxiaoyong:'啸咏', - clanxiaoyong_info:'锁定技。当你于回合内首次使用字数为X的牌时,你重置〖观骨〗(X为你上次发动〖观骨〗观看的牌数)。', - clanbaozu:'保族', - clanbaozu_info:'宗族技,限定技。当一名颍川钟氏角色进入濒死状态时,你可以令其横置并回复1点体力。', - clan_wangyun:'族王允', - clanjiexuan:'解悬', - clanjiexuan_info:'限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。', - clanmingjie:'铭戒', - clanmingjie_info:'限定技。出牌阶段,你可以选择一名角色,然后你获得此下效果:①你使用牌时你可以指定其为额外目标直到其下个回合结束。②其下个回合结束时(若该角色为你则改为你的下下个回合结束时),你可以使用本回合使用过的黑桃牌和被抵消过的牌。', - clan_wanghun:'族王浑', - clanfuxun:'抚循', - clanfuxun_info:'出牌阶段限一次。你可以获得或交给一名其他角色一张手牌,然后若其手牌数与你相等且于此阶段仅以此法获得或失去过牌,你可以将一张牌当任意基本牌使用。', - clanchenya:'沉雅', - clanchenya_info:'当一名角色发动“出牌阶段限一次”的技能后,你可以令其重铸任意张牌名字数为X的牌(X为其手牌数)。', - clan_zhonghui:'族钟会', - clanyuzhi:'迂志', - clanyuzhi_info:'锁定技。新的一轮开始时,你依次执行以下项:①若你上一轮使用的牌数或你上上轮因〖迂志〗摸的牌数小于你上轮因〖迂志〗摸的牌数,你失去1点体力或失去〖保族〗。②你展示一张手牌,然后摸X张牌(X为此牌牌名字数)。', - clanxieshu:'挟术', - clanxieshu_info:'当你每回合首次因牌造成或受到伤害后,你可以弃置Y张牌并摸你已损失体力值张牌(Y为此牌牌名字数)。', - clan_zhongyu:'族钟毓', - clanjiejian:'捷谏', - clanjiejian_info:'当你于一回合使用第X张牌指定第一个目标后,若此牌不为装备牌,则你可以令一名目标角色摸X张牌。(X为此牌牌名字数)', - clanhuanghan:'惶汗', - clanhuanghan_info:'当你受到牌造成的伤害后,你可以摸X张牌并弃置Y张牌(X为此牌牌名字数,Y为你已损失的体力值),然后若此次技能发动不为你本回合首次发动此技能,你重置技能〖保族〗。', - clan_wanglun:'族王沦', - clanqiuxin:'求心', - clanqiuxin_info:'出牌阶段限一次,你可以令一名其他角色选择一项:①你对其使用【杀】;②你对其使用任意普通锦囊牌。当你执行其选择的选项后,你视为执行另一项。', - clanjianyuan:'简远', - clanjianyuan_info:'当一名角色发动“出牌阶段限一次”的技能后,你可以令其重铸任意张牌名字数为X的牌(X为其本阶段的使用牌数)。', - clan_xunyou:'族荀攸', - clanbaichu:'百出', - clanbaichu_info:'锁定技,当你使用一张牌结算完毕后,若你:未记录过此牌的花色和类型组合,则你记录此组合并记录一个普通锦囊牌名,否则你于本轮获得技能〖奇策〗;已记录此牌牌名,你回复1点体力或摸一张牌。', - clan_wuqiao:'族吴乔', - clanqiajue:'跒倔', - clanqiajue_info:'摸牌阶段开始时,你可以弃置一张黑色牌。若如此做,此阶段结束时,你展示手牌,若这些牌的点数和大于30,你的手牌上限-2,否则你执行一个额外的摸牌阶段。', - clan_wangguang:'族王广', - clan_wangguang_prefix:'族', - clanlilun:'离论', - clanlilun_info:'出牌阶段限一次,你可以重铸两张手牌(不能是你本回合以此法重铸过的牌名的牌),然后使用其中的一张牌。', - clanjianji:'见机', - clanjianji_info:'限定技,一名角色的结束阶段,若其上下家均未于本回合:使用过牌,则你可以与其各摸一张牌;成为过牌的目标,则你可以视为使用一张【杀】。', - clan_wangmingshan:'族王明山', - clan_wangmingshan_prefix:'族', - clantanque:'弹雀', - clantanque_info:'每回合限一次。当你使用牌结算结束后,你可以对一名体力值为X且不为0的角色造成1点伤害(X为此牌点数与你上一张使用的牌的点数之差)。', - clanshengmo:'剩墨', - clanshengmo_info:'当你需要使用一张未以此法使用过的基本牌时,你可以获得一张于本回合进入弃牌堆且点数不为这些牌中最大且不为这些牌中最小的牌,视为你使用需要使用的牌。', + clan_wuxian: "族吴苋", + clanyirong: "移荣", + clanyirong_info: + "出牌阶段限两次。若你的手牌数:小于X,则你可以将手牌摸至X张(至多摸八张),然后X-1;大于X,则你可以将手牌弃置至X张,然后X+1。(X为你的手牌上限)", + clanguixiang: "贵相", + clanguixiang_info: + "锁定技。你的非出牌阶段开始前,若此阶段即将成为你本回合内的第X个阶段(X为你的手牌上限),则你终止此阶段,改为进行一个出牌阶段。", + clanmuyin: "穆荫", + clanmuyin_info: + "宗族技。回合开始时,你可以选择一名手牌上限不为全场最多的陈留吴氏角色。该角色的手牌上限+1。", + chenliuwushi: "陈留·吴氏", + clan_wuban: "族吴班", + clanzhanding: "斩钉", + clanzhanding_info: + "你可以将任意张牌当做【杀】使用并你令你的手牌上限-1。你以此法使用的【杀】结算结束后,若你因此【杀】造成过伤害,则你将手牌摸至手牌上限(至多摸五张),否则你令此【杀】不计入次数限制。", + clan_xunshu: "族荀淑", + clanshenjun: "神君", + clanshenjun_info: + "当一名角色使用【杀】或普通锦囊牌时,若你手牌中有该牌名的牌,你展示之,且这些牌称为“神君”。然后本阶段结束时,你可以将等同于你“神君”数张牌当做一张“神君”牌使用。", + clanbalong: "八龙", + clanbalong_info: + "锁定技。当你于一回合内首次{回复体力后或受到伤害后或失去体力后},若你手牌中唯一最多的类别为锦囊牌,你展示所有手牌并摸至角色数张。", + clandaojie: "蹈节", + clandaojie_info: + "宗族技,锁定技。当你每回合第一次使用非伤害类普通锦囊牌后,你须失去一个锁定技或失去1点体力,令一名颍川荀氏角色获得此牌对应的所有实体牌。", + clan_xuncai: "族荀采", + clanlieshi: "烈誓", + clanlieshi_info: + "出牌阶段,你可以选择一项:1.废除判定区并受到你造成的1点火焰伤害;2.弃置所有【闪】;3.弃置所有【杀】。然后令一名其他角色从你未选择的选项中选择一项。", + clandianzhan: "点盏", + clandianzhan_info: + "锁定技。当你每轮第一次使用一种花色的牌后:若此牌的目标数为1且目标未横置,你横置此牌目标;若你有此花色的手牌,你重铸这些牌。均执行后你摸一张牌。", + clanhuanyin: "还阴", + clanhuanyin_info: "锁定技。当你进入濒死状态时,将手牌补至四张。", + clan_xunchen: "族荀谌", + clansankuang: "三恇", + clansankuang_info: + "锁定技。当你每轮第一次使用一种类别的牌后,你令一名其他角色交给你至少X张牌,然后于装备区或处理区内获得你使用的牌对应的所有实体牌(X为以下条件中其满足的项数:场上有牌、已受伤、体力值小于手牌数)。", + clanbeishi: "卑势", + clanbeishi_info: + "锁定技。当一名角色失去最后的手牌后,若其是你首次发动〖三恇〗的目标角色,你回复1点体力。", + clan_xuncan: "族荀粲", + clanyunshen: "熨身", + clanyunshen_info: + "出牌阶段限一次。你可以令一名其他角色回复1点体力,然后选择一项:1.你视为对其使用一张冰【杀】;2.其视为对你使用一张冰【杀】。", + clanshangshen: "伤神", + clanshangshen_info: + "当一名角色受到属性伤害后,若本回合此前没有角色或已死亡的角色受到过属性伤害,你可以执行目标角色为你的【闪电】效果,然后其将手牌摸至四张。", + clanfenchai: "分钗", + clanfenchai_info: + "锁定技。若你首次发动技能指定的异性目标角色中:存在存活角色,你的判定牌视为♥;不存在存活角色,你的判定牌视为♠。", + clan_hanshao: "族韩韶", + clanfangzhen: "放赈", + clanfangzhen_info: + "出牌阶段开始时,你可以横置一名角色并选择一项:1.摸两张牌,然后交给其两张牌;2.令其回复1点体力。然后第X轮游戏开始时,你失去〖放赈〗(X为其座位号)。", + clanliuju: "留驹", + clanliuju_info: + "出牌阶段结束时,你可以与一名角色A拼点,输的角色可以使用任意张拼点牌中的非基本牌。然后若你至A的距离或A至你的距离发生了变化,你重置〖恤民〗。", + clanxumin: "恤民", + clanxumin_info: "宗族技,限定技。你可以将一张牌当做【五谷丰登】对任意名其他角色使用。", + clan_hanrong: "族韩融", + clanlianhe: "连和", + clanlianhe_info: + "出牌阶段开始时,你可以横置两名角色。这些角色于自己的下个出牌阶段结束时,若其此阶段未摸牌,其令你摸X+1张牌或交给你X-1张牌(X为其此阶段获得的牌数且至多为3)。", + clanhuanjia: "缓颊", + clanhuanjia_info: + "出牌阶段结束时,你可以与一名角色拼点。赢的角色可以使用一张拼点牌。然后若此牌:未造成过伤害,你获得另一张拼点牌;造成过伤害,你失去一个技能。", + clan_wukuang: "族吴匡", + clanlianzhu: "联诛", + clanlianzhu_info: + "转换技。每名角色A的出牌阶段限一次。阴:A可以重铸一张牌,然后你可以重铸一张牌。若这两张牌颜色相同,则你的手牌上限+1;阳:A可以令你选择一名在你或A攻击范围内的另一名其他角色B,然后A和你可依次选择是否对B使用一张【杀】。若这两张【杀】颜色不同,则你的手牌上限-1。", + clan_wangling: "族王淩", + clanbolong: "驳龙", + clanbolong_info: + "出牌阶段限一次。你可以令一名其他角色选择一项:1.你交给其一张牌,然后视为对其使用一张雷【杀】;2.交给你等同于你手牌数的牌,然后视为对你使用一张【酒】。", + clanzhongliu: "中流", + clanzhongliu_info: + "宗族技,锁定技。当你使用牌时,若此牌对应的实体牌均不为太原王氏角色的手牌,你重置武将牌上的技能。", + clan_zhongyan: "族钟琰", + clanguangu: "观骨", + clanguangu_info: + "转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。", + clanxiaoyong: "啸咏", + clanxiaoyong_info: + "锁定技。当你于回合内首次使用字数为X的牌时,你重置〖观骨〗(X为你上次发动〖观骨〗观看的牌数)。", + clanbaozu: "保族", + clanbaozu_info: "宗族技,限定技。当一名颍川钟氏角色进入濒死状态时,你可以令其横置并回复1点体力。", + clan_wangyun: "族王允", + clanjiexuan: "解悬", + clanjiexuan_info: + "限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。", + clanmingjie: "铭戒", + clanmingjie_info: + "限定技。出牌阶段,你可以选择一名角色,然后你获得此下效果:①你使用牌时你可以指定其为额外目标直到其下个回合结束。②其下个回合结束时(若该角色为你则改为你的下下个回合结束时),你可以使用本回合使用过的黑桃牌和被抵消过的牌。", + clan_wanghun: "族王浑", + clanfuxun: "抚循", + clanfuxun_info: + "出牌阶段限一次。你可以获得或交给一名其他角色一张手牌,然后若其手牌数与你相等且于此阶段仅以此法获得或失去过牌,你可以将一张牌当任意基本牌使用。", + clanchenya: "沉雅", + clanchenya_info: + "当一名角色发动“出牌阶段限一次”的技能后,你可以令其重铸任意张牌名字数为X的牌(X为其手牌数)。", + clan_zhonghui: "族钟会", + clanyuzhi: "迂志", + clanyuzhi_info: + "锁定技。新的一轮开始时,你依次执行以下项:①你弃置上一轮因〖迂志〗展示的手牌,然后若你上一轮使用的牌数或你上上轮因〖迂志〗摸的牌数小于你上轮因〖迂志〗摸的牌数,你受到1点雷属性伤害或失去〖保族〗。②你展示一张手牌,然后摸X张牌(X为此牌牌名字数)。", + clanxieshu: "挟术", + clanxieshu_info: + "①当你因牌造成或受到伤害后,你可以横置武将牌并弃置Y张牌,然后摸你已损失体力值张牌(Y为此牌牌名字数)。②一名角色的濒死状态结算完毕后,你令〖挟术〗于本回合失效。", + clan_zhongyu: "族钟毓", + clanjiejian: "捷谏", + clanjiejian_info: + "当你于一回合使用第X张牌指定第一个目标后,若此牌不为装备牌,则你可以令一名目标角色摸X张牌。(X为此牌牌名字数)", + clanhuanghan: "惶汗", + clanhuanghan_info: + "当你受到牌造成的伤害后,你可以摸X张牌并弃置Y张牌(X为此牌牌名字数,Y为你已损失的体力值),然后若此次技能发动不为你本回合首次发动此技能,你重置技能〖保族〗。", + clan_wanglun: "族王沦", + clanqiuxin: "求心", + clanqiuxin_info: + "出牌阶段限一次,你可以令一名其他角色选择一项:①你对其使用【杀】;②你对其使用任意普通锦囊牌。当你执行其选择的选项后,你视为执行另一项。", + clanjianyuan: "简远", + clanjianyuan_info: + "当一名角色发动“出牌阶段限一次”的技能后,你可以令其重铸任意张牌名字数为X的牌(X为其本阶段的使用牌数)。", + clan_xunyou: "族荀攸", + clanbaichu: "百出", + clanbaichu_info: + "锁定技,当你使用一张牌结算完毕后,若你:未记录过此牌的花色和类型组合,则你记录此组合并记录一个普通锦囊牌名,否则你于本轮获得技能〖奇策〗;已记录此牌牌名,你回复1点体力或摸一张牌。", + clan_wuqiao: "族吴乔", + clanqiajue: "跒倔", + clanqiajue_info: + "摸牌阶段开始时,你可以弃置一张黑色牌。若如此做,此阶段结束时,你展示手牌,若这些牌的点数和大于30,你的手牌上限-2,否则你执行一个额外的摸牌阶段。", + clan_wangguang: "族王广", + clan_wangguang_prefix: "族", + clanlilun: "离论", + clanlilun_info: + "出牌阶段限一次,你可以重铸两张手牌(不能是你本回合以此法重铸过的牌名的牌),然后使用其中的一张牌。", + clanjianji: "见机", + clanjianji_info: + "限定技,一名角色的结束阶段,若其上下家均未于本回合:使用过牌,则你可以与其各摸一张牌;成为过牌的目标,则你可以视为使用一张【杀】。", + clan_wangmingshan: "族王明山", + clan_wangmingshan_prefix: "族", + clantanque: "弹雀", + clantanque_info: + "每回合限一次。当你使用牌结算结束后,你可以对一名体力值为X且不为0的角色造成1点伤害(X为此牌点数与你上一张使用的牌的点数之差)。", + clanshengmo: "剩墨", + clanshengmo_info: + "当你需要使用一张未以此法使用过的基本牌时,你可以获得一张于本回合进入弃牌堆且点数不为这些牌中最大且不为这些牌中最小的牌,视为你使用需要使用的牌。", - clan_wu:'陈留·吴氏', - clan_xun:'颍川·荀氏', - clan_han:'颍川·韩氏', - clan_wang:'太原·王氏', - clan_zhong:'颍川·钟氏', + clan_wu: "陈留·吴氏", + clan_xun: "颍川·荀氏", + clan_han: "颍川·韩氏", + clan_wang: "太原·王氏", + clan_zhong: "颍川·钟氏", }, }; }); diff --git a/character/collab.js b/character/collab.js index daca94166..2ab724c6e 100644 --- a/character/collab.js +++ b/character/collab.js @@ -1,788 +1,1043 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'collab', - connect:true, - character:{ - dc_zhaoyun:['male','shen',1,['boss_juejing','dclonghun','dczhanjiang'],['shu','InitFilter:noZhuHp:noZhuSkill']], - dc_sunce:['male','wu',4,['dcshuangbi']], - nezha:['male','qun',3,['dcsantou','dcfaqi'],['InitFilter:noZhuHp']], - dc_caocao:['male','wei',4,['dcjianxiong']], - dc_liubei:['male','shu',4,['dcrende']], - dc_sunquan:['male','wu',4,['dczhiheng']], - zhutiexiong:['male','qun',3,['dcbianzhuang']], - wu_zhutiexiong:['male','qun',3,['dcbianzhuang'],['unseen']], - xiaoyuehankehan:['male','qun',3,['dctongliao','dcwudao']], - libai:['male','qun',3,['dclbjiuxian','dcshixian']], - sunwukong:['male','qun',3,['dcjinjing','dccibei','dcruyi']], - longwang:['male','qun',3,['dclonggong','dcsitian']], - taoshen:['male','qun',3,['dcnutao']], - sunyang:['male','wu',4,['clbshuijian']], - yeshiwen:['female','wu',3,['clbjisu','clbshuiyong']], - sp_jiben:['male','qun',3,['spduanzhi','spduyi']], - sp_fuhuanghou:['female','qun',3,['spcangni','spmixin']], - sp_fuwan:['male','qun',3,['spfengyin','spchizhong']], - old_lingju:['female','qun',3,['jieyuan','fenxin_old']], - sp_mushun:['male','qun',4,['moukui']], + name: "collab", + connect: true, + character: { + dc_zhaoyun: [ + "male", + "shen", + 1, + ["boss_juejing", "dclonghun", "dczhanjiang"], + ["shu", "InitFilter:noZhuHp:noZhuSkill"], + ], + dc_sunce: ["male", "wu", 4, ["dcshuangbi"]], + nezha: ["male", "qun", 3, ["dcsantou", "dcfaqi"], ["InitFilter:noZhuHp"]], + dc_caocao: ["male", "wei", 4, ["dcjianxiong"]], + dc_liubei: ["male", "shu", 4, ["dcrende"]], + dc_sunquan: ["male", "wu", 4, ["dczhiheng"]], + zhutiexiong: ["male", "qun", 3, ["dcbianzhuang"]], + wu_zhutiexiong: ["male", "qun", 3, ["dcbianzhuang"], ["unseen"]], + xiaoyuehankehan: ["male", "qun", 3, ["dctongliao", "dcwudao"]], + libai: ["male", "qun", 3, ["dclbjiuxian", "dcshixian"]], + sunwukong: ["male", "qun", 3, ["dcjinjing", "dccibei", "dcruyi"]], + longwang: ["male", "qun", 3, ["dclonggong", "dcsitian"]], + taoshen: ["male", "qun", 3, ["dcnutao"]], + sunyang: ["male", "wu", 4, ["clbshuijian"]], + yeshiwen: ["female", "wu", 3, ["clbjisu", "clbshuiyong"]], + sp_jiben: ["male", "qun", 3, ["spduanzhi", "spduyi"]], + sp_fuhuanghou: ["female", "qun", 3, ["spcangni", "spmixin"]], + sp_fuwan: ["male", "qun", 3, ["spfengyin", "spchizhong"]], + old_lingju: ["female", "qun", 3, ["jieyuan", "fenxin_old"]], + sp_mushun: ["male", "qun", 4, ["moukui"]], }, - characterFilter:{ - old_lingju(mode){ - return mode=='identity'; - } - }, - characterInitFilter:{ - dc_zhaoyun(tag){ - if(tag=='noZhuSkill'&&(get.mode()!='doudizhu'||_status.mode!='normal')) return false; + characterFilter: { + old_lingju(mode) { + return mode == "identity"; }, }, - characterSort:{ - collab:{ - collab_olympic:['sunyang','yeshiwen'], - collab_tongque:["sp_fuwan","sp_fuhuanghou","sp_jiben","old_lingju",'sp_mushun'], - collab_duanwu:['sunwukong','longwang','taoshen'], - collab_decade:['libai','xiaoyuehankehan','zhutiexiong','wu_zhutiexiong'], - collab_remake:['dc_caocao','dc_liubei','dc_sunquan','nezha','dc_sunce','dc_zhaoyun'], + characterInitFilter: { + dc_zhaoyun(tag) { + if (tag == "noZhuSkill" && (get.mode() != "doudizhu" || _status.mode != "normal")) + return false; + }, + }, + characterSort: { + collab: { + collab_olympic: ["sunyang", "yeshiwen"], + collab_tongque: ["sp_fuwan", "sp_fuhuanghou", "sp_jiben", "old_lingju", "sp_mushun"], + collab_duanwu: ["sunwukong", "longwang", "taoshen"], + collab_decade: ["libai", "xiaoyuehankehan", "zhutiexiong", "wu_zhutiexiong"], + collab_remake: ["dc_caocao", "dc_liubei", "dc_sunquan", "nezha", "dc_sunce", "dc_zhaoyun"], }, }, /** @type { importCharacterConfig['skill'] } */ - skill:{ + skill: { //新InitFilter测试高达一号 //打赢复活赛的牢达[哭] - dclonghun:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - prompt:'将♦牌当做火【杀】,♥牌当做【桃】,♣牌当做【闪】,♠牌当做【无懈可击】使用或打出', - viewAs(cards,player){ + dclonghun: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + prompt: "将♦牌当做火【杀】,♥牌当做【桃】,♣牌当做【闪】,♠牌当做【无懈可击】使用或打出", + viewAs(cards, player) { var name; - var nature=null; - switch(get.suit(cards[0],player)){ - case 'club':name='shan';break; - case 'diamond':name='sha';nature='fire';break; - case 'spade':name='wuxie';break; - case 'heart':name='tao';break; + var nature = null; + switch (get.suit(cards[0], player)) { + case "club": + name = "shan"; + break; + case "diamond": + name = "sha"; + nature = "fire"; + break; + case "spade": + name = "wuxie"; + break; + case "heart": + name = "tao"; + break; } - if(name) return {name:name,nature:nature}; + if (name) return { name: name, nature: nature }; return null; }, - check(card){ - var player=_status.event.player; - if(_status.event.type=='phase'){ - var max=0; + check(card) { + var player = _status.event.player; + if (_status.event.type == "phase") { + var max = 0; var name2; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return (name2=='diamond'?(5-get.value(card)):20-get.value(card)); + if (name2 == get.suit(card, player)) + return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, - position:'hes', - filterCard(card,player,event){ - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.suit(card,player); - if(name=='club'&&filter({name:'shan',cards:[card]},player,event)) return true; - if(name=='diamond'&&filter({name:'sha',cards:[card],nature:'fire'},player,event)) return true; - if(name=='spade'&&filter({name:'wuxie',cards:[card]},player,event)) return true; - if(name=='heart'&&filter({name:'tao',cards:[card]},player,event)) return true; + position: "hes", + filterCard(card, player, event) { + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.suit(card, player); + if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if ( + name == "diamond" && + filter({ name: "sha", cards: [card], nature: "fire" }, player, event) + ) + return true; + if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) + return true; + if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, - filter(event,player){ - var filter=event.filterCard; - if(filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)&&player.countCards('hes',{suit:'diamond'})) return true; - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hes',{suit:'club'})) return true; - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hes',{suit:'heart'})) return true; - if(filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)&&player.countCards('hes',{suit:'spade'})) return true; + filter(event, player) { + var filter = event.filterCard; + if ( + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && + player.countCards("hes", { suit: "diamond" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hes", { suit: "club" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hes", { suit: "heart" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && + player.countCards("hes", { suit: "spade" }) + ) + return true; return false; }, - usable:20, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ - if((player.getStat('skill').dclonghun||0)>=20) return false; + usable: 20, + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { + if ((player.getStat("skill").dclonghun || 0) >= 20) return false; var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hes',{suit:name})) return false; + if (!player.countCards("hes", { suit: name })) return false; }, - order(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order(item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard(player,name){ - if((player.getStat('skill').dclonghun||0)>=20) return false; - if(name=='wuxie'&&_status.connectMode&&player.countCards('hes')>0) return true; - if(name=='wuxie') return player.countCards('hes',{suit:'spade'})>0; - if(name=='tao') return player.countCards('hes',{suit:'heart'})>0; + hiddenCard(player, name) { + if ((player.getStat("skill").dclonghun || 0) >= 20) return false; + if (name == "wuxie" && _status.connectMode && player.countCards("hes") > 0) return true; + if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; + if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, }, - dczhanjiang:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return game.hasPlayer(target=>{ - return target.countCards('ej',card=>get.name(card,false)=='qinggang'||get.name(card,get.owner(card))=='qinggang'); + dczhanjiang: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return game.hasPlayer((target) => { + return target.countCards( + "ej", + (card) => + get.name(card, false) == "qinggang" || + get.name(card, get.owner(card)) == "qinggang" + ); }); }, - content(){ - let cards=[],targets=game.filterPlayer(target=>{ - return target.countCards('ej',card=>get.name(card,false)=='qinggang'||get.name(card,get.owner(card))=='qinggang'); - }); - targets.forEach(target=>cards.addArray(target.getCards('ej',card=>get.name(card,false)=='qinggang'||get.name(card,get.owner(card))=='qinggang'))); - player.gain(cards,'give'); + content() { + let cards = [], + targets = game.filterPlayer((target) => { + return target.countCards( + "ej", + (card) => + get.name(card, false) == "qinggang" || + get.name(card, get.owner(card)) == "qinggang" + ); + }); + targets.forEach((target) => + cards.addArray( + target.getCards( + "ej", + (card) => + get.name(card, false) == "qinggang" || + get.name(card, get.owner(card)) == "qinggang" + ) + ) + ); + player.gain(cards, "give"); }, }, //孙策 //双壁=100%技能周瑜+100%原画孙策 - dcshuangbi:{ - audio:2, - enable:'phaseUse', - usable:1, - *content(event,map){ - var player=map.player,num=game.countPlayer(); - var result=yield player.chooseControl().set('choiceList',[ - '摸'+get.cnNumber(num)+'张牌,本回合手牌上限+'+parseFloat(num), - '弃置至多'+get.cnNumber(num)+'张牌,随机对其他角色造成等量火焰伤害', - '视为使用'+get.cnNumber(num)+'张火【杀】或【火攻】', - ]).set('ai',()=>{ - var player=_status.event.player,card={name:'sha',nature:'fire'}; - if(!game.hasPlayer(target=>player.canUse(card,target)&&get.effect(target,card,player,player)>0)) return 0; - return 2; - }); - player.flashAvatar('dcshuangbi',['re_zhouyu','shen_zhouyu','dc_sb_zhouyu'][result.index]); - switch(result.index){ + dcshuangbi: { + audio: 2, + enable: "phaseUse", + usable: 1, + *content(event, map) { + var player = map.player, + num = game.countPlayer(); + var result = yield player + .chooseControl() + .set("choiceList", [ + "摸" + get.cnNumber(num) + "张牌,本回合手牌上限+" + parseFloat(num), + "弃置至多" + get.cnNumber(num) + "张牌,随机对其他角色造成等量火焰伤害", + "视为使用" + get.cnNumber(num) + "张火【杀】或【火攻】", + ]) + .set("ai", () => { + var player = _status.event.player, + card = { name: "sha", nature: "fire" }; + if ( + !game.hasPlayer( + (target) => + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ) + ) + return 0; + return 2; + }); + player.flashAvatar( + "dcshuangbi", + ["re_zhouyu", "shen_zhouyu", "dc_sb_zhouyu"][result.index] + ); + switch (result.index) { case 0: player.draw(num); - player.addTempSkill('dcshuangbi_effect'); - player.addMark('dcshuangbi_effect',num,false); + player.addTempSkill("dcshuangbi_effect"); + player.addMark("dcshuangbi_effect", num, false); break; case 1: - var result2=yield player.chooseToDiscard('双壁:弃置至多'+get.cnNumber(num)+'张牌,随机对其他角色造成等量火焰伤害',[1,num],'he').set('ai',card=>1/(get.value(card)||0.5)); - if(result2.bool){ - var map={},sum=result2.cards.length; - var targets=game.filterPlayer(target=>target!=player); - if(targets.length){ - while(sum){ + var result2 = yield player + .chooseToDiscard( + "双壁:弃置至多" + + get.cnNumber(num) + + "张牌,随机对其他角色造成等量火焰伤害", + [1, num], + "he" + ) + .set("ai", (card) => 1 / (get.value(card) || 0.5)); + if (result2.bool) { + var map = {}, + sum = result2.cards.length; + var targets = game.filterPlayer((target) => target != player); + if (targets.length) { + while (sum) { sum--; - var target=targets.randomGet(); + var target = targets.randomGet(); player.line(target); - target.damage(1,'fire'); + target.damage(1, "fire"); game.delayx(); } } } break; case 2: - while(num&&game.hasPlayer(target=>player.canUse({name:'sha',nature:'fire'},target)||player.canUse({name:'huogong'},target))){ + while ( + num && + game.hasPlayer( + (target) => + player.canUse({ name: "sha", nature: "fire" }, target) || + player.canUse({ name: "huogong" }, target) + ) + ) { num--; - var list=[]; - if(game.hasPlayer(target=>player.canUse({name:'sha',nature:'fire'},target))) list.push(['基本','','sha','fire']); - if(game.hasPlayer(target=>player.canUse({name:'huogong'},target))) list.push(['锦囊','','huogong']); - var result2=yield player.chooseButton([ - '双壁:请选择你要使用的牌', - [list,'vcard']], - true).set('ai',button=>button.link[2]=='sha'?1:0); - if(result2.bool){ - var card={ - name:result2.links[0][2], - nature:result2.links[0][3], + var list = []; + if ( + game.hasPlayer((target) => + player.canUse({ name: "sha", nature: "fire" }, target) + ) + ) + list.push(["基本", "", "sha", "fire"]); + if (game.hasPlayer((target) => player.canUse({ name: "huogong" }, target))) + list.push(["锦囊", "", "huogong"]); + var result2 = yield player + .chooseButton(["双壁:请选择你要使用的牌", [list, "vcard"]], true) + .set("ai", (button) => (button.link[2] == "sha" ? 1 : 0)); + if (result2.bool) { + var card = { + name: result2.links[0][2], + nature: result2.links[0][3], }; - yield player.chooseUseTarget(true,card,false); - } - else break; + yield player.chooseUseTarget(true, card, false); + } else break; } break; } }, - ai:{ - order:9, - result:{player:1}, + ai: { + order: 9, + result: { player: 1 }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - intro:{content:'手牌上限+#'}, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('dcshuangbi_effect'); + subSkill: { + effect: { + charlotte: true, + onremove: true, + intro: { content: "手牌上限+#" }, + mod: { + maxHandcard(player, num) { + return num + player.countMark("dcshuangbi_effect"); }, }, }, }, }, //哪吒 - dcsantou:{ - audio:2, - trigger:{player:'damageBegin4'}, - forced:true, - *content(event,map){ - var player=map.player,trigger=map.trigger; - var source=trigger.source; + dcsantou: { + audio: 2, + trigger: { player: "damageBegin4" }, + forced: true, + *content(event, map) { + var player = map.player, + trigger = map.trigger; + var source = trigger.source; trigger.cancel(); - var hp=player.getHp(); - var lose=false; - if(hp>=3){ - if(player.hasHistory('useSkill',evt=>{ - var evtx=evt.event; - return evt.skill=='dcsantou'&&evtx.getTrigger().source==source&&evtx.getParent(2)!=trigger; - })) lose=true; + var hp = player.getHp(); + var lose = false; + if (hp >= 3) { + if ( + player.hasHistory("useSkill", (evt) => { + var evtx = evt.event; + return ( + evt.skill == "dcsantou" && + evtx.getTrigger().source == source && + evtx.getParent(2) != trigger + ); + }) + ) + lose = true; + } else if (hp == 2) { + if (trigger.hasNature()) lose = true; + } else if (hp == 1) { + if (trigger.card && get.color(trigger.card) == "red") lose = true; } - else if(hp==2){ - if(trigger.hasNature()) lose=true; - } - else if(hp==1){ - if(trigger.card&&get.color(trigger.card)=='red') lose=true; - } - if(lose) player.loseHp(); + if (lose) player.loseHp(); }, - ai:{ - filterDamage:true, - skillTagFilter(player,tag,arg){ - if(arg&&arg.player&&arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter(player, tag, arg) { + if (arg && arg.player && arg.player.hasSkillTag("jueqing", false, player)) + return false; }, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(player._dcsantou_temp) return; - if(get.tag(card,'damage')){ - const hp=target.getHp(); - player._dcsantou_temp=true; - const losehp=get.effect(target,{name:'losehp'},target,target)/get.attitude(target,target); + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (player._dcsantou_temp) return; + if (get.tag(card, "damage")) { + const hp = target.getHp(); + player._dcsantou_temp = true; + const losehp = + get.effect(target, { name: "losehp" }, target, target) / + get.attitude(target, target); delete player._dcsantou_temp; - if(hp>=3){ - if(target.hasHistory('useSkill',evt=>evt.skill=='dcsantou'&&evt.event.getTrigger().source==player)) return [0,losehp,0,0]; - else if(get.attitude(player,target)<0){ - let hs=player.getCards('hs',i=>{ - return i!==card&&(!card.cards||!card.cards.includes(i)); - }),num=player.getCardUsable('sha'); - if(card.name==='sha') num--; - hs=hs.filter(i=>{ - if(!player.canUse(i,target)) return false; - if(get.tag(card,'damage')&&get.name(i,player)!=='sha') return true; - if(num){ + if (hp >= 3) { + if ( + target.hasHistory( + "useSkill", + (evt) => + evt.skill == "dcsantou" && + evt.event.getTrigger().source == player + ) + ) + return [0, losehp, 0, 0]; + else if (get.attitude(player, target) < 0) { + let hs = player.getCards("hs", (i) => { + return i !== card && (!card.cards || !card.cards.includes(i)); + }), + num = player.getCardUsable("sha"); + if (card.name === "sha") num--; + hs = hs.filter((i) => { + if (!player.canUse(i, target)) return false; + if (get.tag(card, "damage") && get.name(i, player) !== "sha") + return true; + if (num) { num--; return true; } return false; }).length; - if(player.hasSkillTag('damage',null,{target:target})) hs++; - if(!hs) return 'zeroplayertarget'; - num=1-2/3/hs; - return [num,0,num,0]; + if ( + player.hasSkillTag("damage", null, { + target: target, + }) + ) + hs++; + if (!hs) return "zeroplayertarget"; + num = 1 - 2 / 3 / hs; + return [num, 0, num, 0]; } } - if(hp==2&&get.tag(card,'natureDamage')||hp==1&&typeof card=='object'&&get.color(card)=='red') return [0,losehp,0,0]; - return 'zeroplayertarget'; + if ( + (hp == 2 && get.tag(card, "natureDamage")) || + (hp == 1 && typeof card == "object" && get.color(card) == "red") + ) + return [0, losehp, 0, 0]; + return "zeroplayertarget"; } - } - } + }, + }, }, }, - dcfaqi:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(get.type(event.card)!='equip') return false; - if(!player.isPhaseUsing()) return false; - for(const name of lib.inpile){ - if(get.type(name)!='trick') continue; - if(!player.hasStorage('dcfaqi',name)&&player.hasUseTarget({name:name,isCard:true})) return true; + dcfaqi: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + if (get.type(event.card) != "equip") return false; + if (!player.isPhaseUsing()) return false; + for (const name of lib.inpile) { + if (get.type(name) != "trick") continue; + if ( + !player.hasStorage("dcfaqi", name) && + player.hasUseTarget({ name: name, isCard: true }) + ) + return true; } return false; }, - direct:true, - *content(event,map){ - var player=map.player; - var list=get.inpileVCardList(info=>{ - if(info[0]!='trick') return false; - var name=info[2]; - return !player.hasStorage('dcfaqi',name)&&player.hasUseTarget({name:name,isCard:true}); + direct: true, + *content(event, map) { + var player = map.player; + var list = get.inpileVCardList((info) => { + if (info[0] != "trick") return false; + var name = info[2]; + return ( + !player.hasStorage("dcfaqi", name) && + player.hasUseTarget({ name: name, isCard: true }) + ); }); - if(list.length){ - var result=yield player.chooseButton(['法器:视为使用一张普通锦囊牌',[list,'vcard']],true).set('ai',button=>{ - return get.player().getUseValue({name:button.link[2]}); - }); - if(result.bool){ - var name=result.links[0][2]; - if(!player.storage.dcfaqi) player.when({global:'phaseAfter'}).then(()=>delete player.storage.dcfaqi); - player.markAuto('dcfaqi',name); - player.chooseUseTarget({name:name,isCard:true},true,false).logSkill='dcfaqi'; + if (list.length) { + var result = yield player + .chooseButton(["法器:视为使用一张普通锦囊牌", [list, "vcard"]], true) + .set("ai", (button) => { + return get.player().getUseValue({ name: button.link[2] }); + }); + if (result.bool) { + var name = result.links[0][2]; + if (!player.storage.dcfaqi) + player + .when({ global: "phaseAfter" }) + .then(() => delete player.storage.dcfaqi); + player.markAuto("dcfaqi", name); + player.chooseUseTarget({ name: name, isCard: true }, true, false).logSkill = + "dcfaqi"; } - } - else event.finish(); + } else event.finish(); + }, + ai: { + reverseEquip: true, }, - ai:{ - reverseEquip:true - } }, //隅泣曹操 - dcjianxiong:{ - audio:'rejianxiong', - trigger:{ - player:'damageEnd', + dcjianxiong: { + audio: "rejianxiong", + trigger: { + player: "damageEnd", }, - content(){ - 'step 0' - if(get.itemtype(trigger.cards)=='cards'&&get.position(trigger.cards[0],true)=='o'){ - player.gain(trigger.cards,'gain2'); + content() { + "step 0"; + if ( + get.itemtype(trigger.cards) == "cards" && + get.position(trigger.cards[0], true) == "o" + ) { + player.gain(trigger.cards, "gain2"); } - player.draw(player.countMark('dcjianxiong')+1,'nodelay'); - 'step 1' - if(player.countMark('dcjianxiong')<4) player.addMark('dcjianxiong',1,false); + player.draw(player.countMark("dcjianxiong") + 1, "nodelay"); + "step 1"; + if (player.countMark("dcjianxiong") < 4) player.addMark("dcjianxiong", 1, false); }, - marktext:'雄', - intro:{ - markcount(storage,player){ - return player.countMark('dcjianxiong')+1; + marktext: "雄", + intro: { + markcount(storage, player) { + return player.countMark("dcjianxiong") + 1; }, - content(storage,player){ - return '摸牌数为'+(player.countMark('dcjianxiong')+1); + content(storage, player) { + return "摸牌数为" + (player.countMark("dcjianxiong") + 1); }, }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target (card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target){ - var cards=card.cards,evt=_status.event; - if(evt.player==target&&card.name=='damage'&&evt.getParent().type=='card') cards=evt.getParent().cards.filterInD(); - if(target.hp<=1) return; - if(get.itemtype(cards)!='cards') return; - for(var i of cards){ - if(get.name(i,target)=='tao') return [1,5+player.countMark('dcjianxiong')/2]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage") && player != target) { + var cards = card.cards, + evt = _status.event; + if ( + evt.player == target && + card.name == "damage" && + evt.getParent().type == "card" + ) + cards = evt.getParent().cards.filterInD(); + if (target.hp <= 1) return; + if (get.itemtype(cards) != "cards") return; + for (var i of cards) { + if (get.name(i, target) == "tao") + return [1, 5 + player.countMark("dcjianxiong") / 2]; } - if(get.value(cards,target)>=(7-player.countMark('dcjianxiong')/2+target.getDamagedHp())) return [1,3+player.countMark('dcjianxiong')/2]; - return [1,0.6+player.countMark('dcjianxiong')/2]; + if ( + get.value(cards, target) >= + 7 - player.countMark("dcjianxiong") / 2 + target.getDamagedHp() + ) + return [1, 3 + player.countMark("dcjianxiong") / 2]; + return [1, 0.6 + player.countMark("dcjianxiong") / 2]; } }, }, }, }, //缺德刘备 - dcrende:{ - audio:'rerende', - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(current=>{ - return lib.skill.dcrende.filterTarget(null,player,current); + dcrende: { + audio: "rerende", + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((current) => { + return lib.skill.dcrende.filterTarget(null, player, current); }); }, - discard:false, - lose:false, - delay:false, - filterTarget(card,player,target){ - if(player.getStorage('dcrende_targeted').includes(target)) return false; - return player!=target&&target.countGainableCards(player,'h')>1; + discard: false, + lose: false, + delay: false, + filterTarget(card, player, target) { + if (player.getStorage("dcrende_targeted").includes(target)) return false; + return player != target && target.countGainableCards(player, "h") > 1; }, - content(){ - 'step 0' - player.addTempSkill('dcrende_targeted','phaseUseAfter'); - player.markAuto('dcrende_targeted',[target]); - player.gainPlayerCard(target,'h',true,2); - 'step 1' - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - var card={name:name,isCard:true}; - if(lib.filter.cardUsable(card,player,event.getParent('chooseToUse'))&&game.hasPlayer(current=>{ - return player.canUse(card,current); - })){ - list.push(['基本','',name]); + content() { + "step 0"; + player.addTempSkill("dcrende_targeted", "phaseUseAfter"); + player.markAuto("dcrende_targeted", [target]); + player.gainPlayerCard(target, "h", true, 2); + "step 1"; + var list = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + var card = { name: name, isCard: true }; + if ( + lib.filter.cardUsable(card, player, event.getParent("chooseToUse")) && + game.hasPlayer((current) => { + return player.canUse(card, current); + }) + ) { + list.push(["基本", "", name]); } - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(lib.filter.cardUsable(card,player,event.getParent('chooseToUse'))&&game.hasPlayer(current=>{ - return player.canUse(card,current); - })){ - list.push(['基本','',name,nature]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if ( + lib.filter.cardUsable(card, player, event.getParent("chooseToUse")) && + game.hasPlayer((current) => { + return player.canUse(card, current); + }) + ) { + list.push(["基本", "", name, nature]); } } } } - if(list.length){ - player.chooseButton(['是否视为使用一张基本牌?',[list,'vcard']]).set('ai',function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3],isCard:true}; - if(card.name=='tao'){ - if(player.hp==1||(player.hp==2&&!player.hasShan())||player.needsToDiscard()) return 5; - return 1; - } - if(card.name=='sha'){ - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0 - })){ - if(card.nature=='fire') return 2.95; - if(card.nature=='thunder'||card.nature=='ice') return 2.92; - return 2.9; + if (list.length) { + player + .chooseButton(["是否视为使用一张基本牌?", [list, "vcard"]]) + .set("ai", function (button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }; + if (card.name == "tao") { + if ( + player.hp == 1 || + (player.hp == 2 && !player.hasShan()) || + player.needsToDiscard() + ) + return 5; + return 1; + } + if (card.name == "sha") { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + if (card.nature == "fire") return 2.95; + if (card.nature == "thunder" || card.nature == "ice") return 2.92; + return 2.9; + } + return 0; + } + if (card.name == "jiu") { + return 0.5; } return 0; - } - if(card.name=='jiu'){ - return 0.5; - } - return 0; - }); - } - else{ + }); + } else { event.finish(); } - 'step 2' - if(result&&result.bool&&result.links[0]){ - var card={name:result.links[0][2],nature:result.links[0][3],isCard:true}; - player.chooseUseTarget(card,true); + "step 2"; + if (result && result.bool && result.links[0]) { + var card = { + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }; + player.chooseUseTarget(card, true); } }, - subSkill:{ - targeted:{ - onremove:true, - charlotte:true, + subSkill: { + targeted: { + onremove: true, + charlotte: true, }, }, - ai:{ - fireAttack:true, - order(skill,player){ + ai: { + fireAttack: true, + order(skill, player) { return 10; }, - result:{ - target(player,target){ - if(target.hasSkillTag('noh')) return -0.1; + result: { + target(player, target) { + if (target.hasSkillTag("noh")) return -0.1; return -2; - } + }, }, - threaten:3, + threaten: 3, }, }, //会玩孙权 - dczhiheng:{ - audio:'rezhiheng', - init:(player)=>{ - player.storage.dczhiheng_hit=[]; + dczhiheng: { + audio: "rezhiheng", + init: (player) => { + player.storage.dczhiheng_hit = []; }, - enable:'phaseUse', - position:'he', - filterCard:lib.filter.cardDiscardable, - discard:false, - lose:false, - delay:false, - selectCard:[1,Infinity], - filter(event,player){ - var skill=player.getStat().skill; - return !skill.dczhiheng||skill.dczhiheng<1+player.getStorage('dczhiheng_hit').length; + enable: "phaseUse", + position: "he", + filterCard: lib.filter.cardDiscardable, + discard: false, + lose: false, + delay: false, + selectCard: [1, Infinity], + filter(event, player) { + var skill = player.getStat().skill; + return ( + !skill.dczhiheng || skill.dczhiheng < 1 + player.getStorage("dczhiheng_hit").length + ); }, - check(card){ - var player=_status.event.player; - if(get.position(card)=='h'&&!player.countCards('h','du')&&(player.hp>2||!player.countCards('h',function(card){ - return get.value(card)>=8; - }))){ + check(card) { + var player = _status.event.player; + if ( + get.position(card) == "h" && + !player.countCards("h", "du") && + (player.hp > 2 || + !player.countCards("h", function (card) { + return get.value(card) >= 8; + })) + ) { return 1; } - return 6-get.value(card) + return 6 - get.value(card); }, - group:'dczhiheng_add', - content(){ - 'step 0' + group: "dczhiheng_add", + content() { + "step 0"; player.discard(cards); - event.num=1; - var hs=player.getCards('h'); - if(!hs.length) event.num=0; - for(var i=0;i{ - player.storage.dczhiheng_hit=[]; - }, - mark:true, - marktext:'衡', - intro:{ - markcount(storage){ - if(storage) return storage.length; - return 0; - }, - content:'本回合已对$造成过伤害', - }, - } - }, - ai:{ - order(item,player){ - if(player.hasCard((i)=>{ - return get.value(i)>Math.max(6,9-player.hp); - },'he')) return 1; - return 10; - }, - result:{ - player:1 - }, - nokeep:true, - skillTagFilter(player,tag,arg){ - if(tag==='nokeep') return (!arg||arg&&arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&player.countSkill('dczhiheng')<1+player.getStorage('dczhiheng_hit').length&&player.hasCard((card)=>{ - return get.name(card)!=='tao'; - },'h'); - }, - threaten:1.55 - }, - }, - //朱铁雄 - dcbianzhuang:{ - audio:2, - enable:'phaseUse', - usable:1, - content(){ - 'step 0' - var list=[]; - for(var i in lib.skill.dcbianzhuang.characterMap){ - if(Array.isArray(lib.character[i])&&get.is.object(lib.skill[lib.skill.dcbianzhuang.characterMap[i]])) list.push(i); - } - var characters=list.randomGets(player.storage.dcbianzhuang_inited?3:2); - if(!characters.length){ - event.finish(); - return; - } - var skills=characters.map(i=>lib.skill.dcbianzhuang.characterMap[i]); - player.chooseControl(skills).set('dialog',[ - '选择获得一个技能并“变装”', - [characters,'character'] - ]); - 'step 1' - var skill=result.control; - player.addTempSkills(skill,'dcbianzhuangAfter'); - for(var i in lib.skill.dcbianzhuang.characterMap){ - if(lib.skill.dcbianzhuang.characterMap[i]==skill){ - player.flashAvatar('dcbianzhuang',i); - player.popup(skill); - game.log(player,'“变装”为了','#b'+get.translation(i)); + event.num = 1; + var hs = player.getCards("h"); + if (!hs.length) event.num = 0; + for (var i = 0; i < hs.length; i++) { + if (!cards.includes(hs[i])) { + event.num = 0; break; } } - player.chooseUseTarget('sha',true,false,'nodistance'); - 'step 2' - if(result.bool&&!player.storage.dcbianzhuang_inited){ - player.addMark('dcbianzhuang',1,false); - if(player.countMark('dcbianzhuang')>2){ - player.storage.dcbianzhuang_inited=true; - player.reinitCharacter('zhutiexiong','wu_zhutiexiong'); + "step 1"; + player.draw(event.num + cards.length); + }, + subSkill: { + add: { + audio: 2, + trigger: { + source: "damageSource", + }, + forced: true, + locked: false, + filter(event, player) { + return !player.getStorage("dczhiheng_hit").includes(event.player); + }, + content() { + player.addTempSkill("dczhiheng_hit"); + player.markAuto("dczhiheng_hit", [trigger.player]); + }, + }, + hit: { + charlotte: true, + onremove: (player) => { + player.storage.dczhiheng_hit = []; + }, + mark: true, + marktext: "衡", + intro: { + markcount(storage) { + if (storage) return storage.length; + return 0; + }, + content: "本回合已对$造成过伤害", + }, + }, + }, + ai: { + order(item, player) { + if ( + player.hasCard((i) => { + return get.value(i) > Math.max(6, 9 - player.hp); + }, "he") + ) + return 1; + return 10; + }, + result: { + player: 1, + }, + nokeep: true, + skillTagFilter(player, tag, arg) { + if (tag === "nokeep") + return ( + (!arg || (arg && arg.card && get.name(arg.card) === "tao")) && + player.isPhaseUsing() && + player.countSkill("dczhiheng") < + 1 + player.getStorage("dczhiheng_hit").length && + player.hasCard((card) => { + return get.name(card) !== "tao"; + }, "h") + ); + }, + threaten: 1.55, + }, + }, + //朱铁雄 + dcbianzhuang: { + audio: 2, + enable: "phaseUse", + usable: 1, + content() { + "step 0"; + var list = []; + for (var i in lib.skill.dcbianzhuang.characterMap) { + if ( + Array.isArray(lib.character[i]) && + get.is.object(lib.skill[lib.skill.dcbianzhuang.characterMap[i]]) + ) + list.push(i); + } + var characters = list.randomGets(player.storage.dcbianzhuang_inited ? 3 : 2); + if (!characters.length) { + event.finish(); + return; + } + var skills = characters.map((i) => lib.skill.dcbianzhuang.characterMap[i]); + player + .chooseControl(skills) + .set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]]); + "step 1"; + var skill = result.control; + player.addTempSkills(skill, "dcbianzhuangAfter"); + for (var i in lib.skill.dcbianzhuang.characterMap) { + if (lib.skill.dcbianzhuang.characterMap[i] == skill) { + player.flashAvatar("dcbianzhuang", i); + player.popup(skill); + game.log(player, "“变装”为了", "#b" + get.translation(i)); + break; + } + } + player.chooseUseTarget("sha", true, false, "nodistance"); + "step 2"; + if (result.bool && !player.storage.dcbianzhuang_inited) { + player.addMark("dcbianzhuang", 1, false); + if (player.countMark("dcbianzhuang") > 2) { + player.storage.dcbianzhuang_inited = true; + player.reinitCharacter("zhutiexiong", "wu_zhutiexiong"); } } }, - group:'dcbianzhuang_refresh', - ai:{ - order:16, - result:{ - player(player){ - if(player.hasValueTarget('sha',false)) return 1; + group: "dcbianzhuang_refresh", + ai: { + order: 16, + result: { + player(player) { + if (player.hasValueTarget("sha", false)) return 1; return 0; }, }, - effect:{ - target(card,player,target,current){ - if(player==target&&player.isPhaseUsing()&&get.type(card)=='equip'){ - if(player.hasValueTarget('sha',false)&&typeof player.getStat('skill').dcbianzhuang=='number') return [1,3]; + effect: { + target(card, player, target, current) { + if (player == target && player.isPhaseUsing() && get.type(card) == "equip") { + if ( + player.hasValueTarget("sha", false) && + typeof player.getStat("skill").dcbianzhuang == "number" + ) + return [1, 3]; } }, }, }, - subSkill:{ - refresh:{ - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - return get.type2(event.card,false)=='equip'&&typeof player.getStat('skill').dcbianzhuang=='number'; + subSkill: { + refresh: { + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + return ( + get.type2(event.card, false) == "equip" && + typeof player.getStat("skill").dcbianzhuang == "number" + ); }, - content(){ - var stat=player.getStat('skill'); + content() { + var stat = player.getStat("skill"); delete stat.dcbianzhuang; }, }, }, - characterMap:{ - re_zhangchunhua:'rejueqing', - wangshuang:'spzhuilie', - re_machao:'retieji', - ol_weiyan:'xinkuanggu', - re_lvbu:'wushuang', - re_huangzhong:'xinliegong', - ol_pangde:'rejianchu', - ol_zhurong:'lieren', - re_masu:'rezhiman', - re_panzhangmazhong:'reanjian', - mayunlu:'fengpo', - re_quyi:'refuqi', + characterMap: { + re_zhangchunhua: "rejueqing", + wangshuang: "spzhuilie", + re_machao: "retieji", + ol_weiyan: "xinkuanggu", + re_lvbu: "wushuang", + re_huangzhong: "xinliegong", + ol_pangde: "rejianchu", + ol_zhurong: "lieren", + re_masu: "rezhiman", + re_panzhangmazhong: "reanjian", + mayunlu: "fengpo", + re_quyi: "refuqi", }, }, //小约翰可汗 - dctongliao:{ - audio:3, - trigger:{player:'phaseDrawAfter'}, - direct:true, - locked:false, - filter(event,player){ - return player.countCards('h')>0; + dctongliao: { + audio: 3, + trigger: { player: "phaseDrawAfter" }, + direct: true, + locked: false, + filter(event, player) { + return player.countCards("h") > 0; }, - content(){ - 'step 0' - player.chooseCard('h',get.prompt('dctongliao'),'选择一张牌标记为“通辽”',function(card,player){ - if(card.hasGaintag('dctongliao')) return false; - var num=get.number(card,player); - return !player.hasCard(card2=>{ - return card!=card2&&get.number(card2,player) { + return card != card2 && get.number(card2, player) < num; + }); + } + ) + .set("ai", function (card) { + var player = _status.event.player; + return 1 + Math.max(0, player.getUseValue(card, null, true)); + }); + "step 1"; + if (result.bool) { + player.logSkill("dctongliao"); + player.addGaintag(result.cards, "dctongliao"); game.delayx(); } }, - mod:{ - aiOrder(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dctongliao')) return num+0.6; + mod: { + aiOrder(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dctongliao")) return num + 0.6; }, }, - group:'dctongliao_draw', - subSkill:{ - draw:{ - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + group: "dctongliao_draw", + subSkill: { + draw: { + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dctongliao')) return true; + filter(event, player) { + var evt = event.getl(player); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dctongliao")) return true; } return false; } - return player.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dctongliao')) return true; + return player.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dctongliao")) return true; } return false; }); }, - forced:true, - content(){ - var num=0; - var cards=trigger.getl(player).hs,ids=[]; - if(trigger.name=='lose'){ - for(var i in trigger.gaintag_map){ - if(trigger.gaintag_map[i].includes('dctongliao')) ids.push(i); + forced: true, + content() { + var num = 0; + var cards = trigger.getl(player).hs, + ids = []; + if (trigger.name == "lose") { + for (var i in trigger.gaintag_map) { + if (trigger.gaintag_map[i].includes("dctongliao")) ids.push(i); } + } else + player.getHistory("lose", function (evt) { + if (trigger != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dctongliao")) ids.push(i); + } + }); + for (var card of cards) { + if (ids.includes(card.cardid)) num += get.number(card, player); } - else player.getHistory('lose',function(evt){ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dctongliao')) ids.push(i); - } - }); - for(var card of cards){ - if(ids.includes(card.cardid)) num+=get.number(card,player); - } - if(num>0) player.draw(num); - } + if (num > 0) player.draw(num); + }, }, }, }, - dcwudao:{ - audio:3, - trigger:{player:'useCardAfter'}, - frequent:true, - filter(event,player){ - if(player.getStorage('dcwudao_effect').includes(get.type2(event.card,false))) return false; - var history=player.getHistory('useCard'),index=history.indexOf(event); - if(index<1) return false; - var evt=history[index-1]; - return get.type2(event.card,false)==get.type2(evt.card,false); + dcwudao: { + audio: 3, + trigger: { player: "useCardAfter" }, + frequent: true, + filter(event, player) { + if (player.getStorage("dcwudao_effect").includes(get.type2(event.card, false))) + return false; + var history = player.getHistory("useCard"), + index = history.indexOf(event); + if (index < 1) return false; + var evt = history[index - 1]; + return get.type2(event.card, false) == get.type2(evt.card, false); }, - prompt2(event){ - return '令你本回合使用'+get.translation(get.type2(event.card,false))+'牌时不可被响应且伤害+1'; + prompt2(event) { + return ( + "令你本回合使用" + + get.translation(get.type2(event.card, false)) + + "牌时不可被响应且伤害+1" + ); }, - content(){ - player.addTempSkill('dcwudao_effect'); - player.markAuto('dcwudao_effect',[get.type2(trigger.card,false)]) + content() { + player.addTempSkill("dcwudao_effect"); + player.markAuto("dcwudao_effect", [get.type2(trigger.card, false)]); }, - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - onremove:true, - filter(event,player){ - return player.getStorage('dcwudao_effect').includes(get.type2(event.card,false)); + subSkill: { + effect: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + onremove: true, + filter(event, player) { + return player.getStorage("dcwudao_effect").includes(get.type2(event.card, false)); }, - content(){ - if(get.tag(trigger.card,'damage')>0) trigger.baseDamage++; + content() { + if (get.tag(trigger.card, "damage") > 0) trigger.baseDamage++; trigger.directHit.addArray(game.filterPlayer()); }, - intro:{content:'已经悟到了$牌'}, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(arg&&arg.card&&player.getStorage('dcwudao_effect').includes(get.type2(arg.card))) return true; + intro: { content: "已经悟到了$牌" }, + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if ( + arg && + arg.card && + player.getStorage("dcwudao_effect").includes(get.type2(arg.card)) + ) + return true; return false; }, }, @@ -790,441 +1045,488 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //叶诗文 - clbjisu:{ - audio:2, - trigger:{player:'phaseJudgeBefore'}, - direct:true, - content(){ - "step 0" - var check=player.countCards('h')>2; - player.chooseTarget(get.prompt("clbjisu"),"跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',check).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }).setHiddenSkill('clbjisu'); - "step 1" - if(result.bool){ - player.useCard({name:'sha',isCard:true},result.targets[0],false,'clbjisu'); + clbjisu: { + audio: 2, + trigger: { player: "phaseJudgeBefore" }, + direct: true, + content() { + "step 0"; + var check = player.countCards("h") > 2; + player + .chooseTarget( + get.prompt("clbjisu"), + "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", check) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }) + .setHiddenSkill("clbjisu"); + "step 1"; + if (result.bool) { + player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu"); trigger.cancel(); - player.skip('phaseDraw'); + player.skip("phaseDraw"); } - } - }, - clbshuiyong:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter(event){ - return event.hasNature('fire'); }, - forced:true, - content(){ + }, + clbshuiyong: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter(event) { + return event.hasNature("fire"); + }, + forced: true, + content() { trigger.cancel(); }, - ai:{ - nofire:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'fireDamage')) return 'zerotarget'; - } - } - } + ai: { + nofire: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "fireDamage")) return "zerotarget"; + }, + }, + }, }, //孙杨 - clbshuijian:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - filter(event,player){ + clbshuijian: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + filter(event, player) { return !event.numFixed; }, - content(){ - var num=1+Math.floor(player.countCards('e')/2); - trigger.num+=num; + content() { + var num = 1 + Math.floor(player.countCards("e") / 2); + trigger.num += num; }, }, //李白 - dclbjiuxian:{ - audio:2, - enable:'chooseToUse', - locked:false, - viewAs:{name:'jiu'}, - check:card=>6.5-get.value(card), - filterCard(card){ - var info=get.info(card); - if(!info||(info.type!='trick'&&info.type!='delay')) return false; - if(info.notarget) return false; - if(info.selectTarget!=undefined){ - if(Array.isArray(info.selectTarget)){ - if(info.selectTarget[0]<0) return !info.toself; - return info.selectTarget[0]!=1||info.selectTarget[1]!=1; - } - else{ - if(info.selectTarget<0) return !info.toself; - return info.selectTarget!=1; + dclbjiuxian: { + audio: 2, + enable: "chooseToUse", + locked: false, + viewAs: { name: "jiu" }, + check: (card) => 6.5 - get.value(card), + filterCard(card) { + var info = get.info(card); + if (!info || (info.type != "trick" && info.type != "delay")) return false; + if (info.notarget) return false; + if (info.selectTarget != undefined) { + if (Array.isArray(info.selectTarget)) { + if (info.selectTarget[0] < 0) return !info.toself; + return info.selectTarget[0] != 1 || info.selectTarget[1] != 1; + } else { + if (info.selectTarget < 0) return !info.toself; + return info.selectTarget != 1; } } return false; }, - viewAsFilter(player){ - if(_status.connectMode&&player.countCards('hs')>0) return true; - return player.hasCard(lib.skill.dclbjiuxian.filterCard,'hs') + viewAsFilter(player) { + if (_status.connectMode && player.countCards("hs") > 0) return true; + return player.hasCard(lib.skill.dclbjiuxian.filterCard, "hs"); }, - ai:{ - order:(item,player)=>get.order({name:'jiu'},player), + ai: { + order: (item, player) => get.order({ name: "jiu" }, player), }, - mod:{ - cardUsable(card){ - if(card.name=='jiu') return Infinity; + mod: { + cardUsable(card) { + if (card.name == "jiu") return Infinity; }, }, }, - dcshixian:{ - audio:2, - trigger:{player:'useCard'}, + dcshixian: { + audio: 2, + trigger: { player: "useCard" }, //frequent:true, //direct:true, - locked:false, - filter(event,player){ - var history=player.getAllHistory('useCard'),index=history.indexOf(event); - if(index<1) return false; - var evt=history[index-1]; - return get.is.yayun(get.translation(event.card.name),get.translation(evt.card.name)); + locked: false, + filter(event, player) { + var history = player.getAllHistory("useCard"), + index = history.indexOf(event); + if (index < 1) return false; + var evt = history[index - 1]; + return get.is.yayun(get.translation(event.card.name), get.translation(evt.card.name)); }, - filterx(event){ - if(event.targets.length==0) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; + filterx(event) { + if (event.targets.length == 0) return false; + var type = get.type(event.card); + if (type != "basic" && type != "trick") return false; return true; }, - prompt2(event,player){ - if(lib.skill.dcshixian.filterx(event)) return '摸一张牌并令'+get.translation(event.card)+'额外结算一次?'; - return '摸一张牌。'; + prompt2(event, player) { + if (lib.skill.dcshixian.filterx(event)) + return "摸一张牌并令" + get.translation(event.card) + "额外结算一次?"; + return "摸一张牌。"; }, - check(event,player){ - if(lib.skill.dcshixian.filterx(event)) return !get.tag(event.card,'norepeat'); + check(event, player) { + if (lib.skill.dcshixian.filterx(event)) return !get.tag(event.card, "norepeat"); return true; }, - content(){ + content() { player.draw(); - if(lib.skill.dcshixian.filterx(trigger)){ + if (lib.skill.dcshixian.filterx(trigger)) { trigger.effectCount++; - game.log(trigger.card,'额外结算一次'); + game.log(trigger.card, "额外结算一次"); } }, - mod:{ - aiOrder(player,card,num){ - if(typeof card=='object'&&!get.tag(card,'norepeat')){ - var history=player.getAllHistory('useCard'); - if(history.length>0){ - var cardx=history[history.length-1].card; - if(get.is.yayun(get.translation(cardx.name),get.translation(card.name))) return num+20; + mod: { + aiOrder(player, card, num) { + if (typeof card == "object" && !get.tag(card, "norepeat")) { + var history = player.getAllHistory("useCard"); + if (history.length > 0) { + var cardx = history[history.length - 1].card; + if (get.is.yayun(get.translation(cardx.name), get.translation(card.name))) + return num + 20; } } }, }, - init(player){ - player.addSkill('dcshixian_yayun'); - var history=player.getAllHistory('useCard'); - if(history.length){ - player.addGaintag(player.getCards('h',card=>{ - return get.is.yayun(get.translation(card.name),get.translation(history[history.length-1].card.name)); - }),'dcshixian_yayun'); + init(player) { + player.addSkill("dcshixian_yayun"); + var history = player.getAllHistory("useCard"); + if (history.length) { + player.addGaintag( + player.getCards("h", (card) => { + return get.is.yayun( + get.translation(card.name), + get.translation(history[history.length - 1].card.name) + ); + }), + "dcshixian_yayun" + ); } }, - onremove(player){ - player.removeSkill('dcshixian_yayun'); - player.removeGaintag('dcshixian_yayun'); + onremove(player) { + player.removeSkill("dcshixian_yayun"); + player.removeGaintag("dcshixian_yayun"); }, - subSkill:{ - yayun:{ - charlotte:true, - trigger:{player:'useCard1'}, - filter(event,player){ - return player.countCards('h')>0; + subSkill: { + yayun: { + charlotte: true, + trigger: { player: "useCard1" }, + filter(event, player) { + return player.countCards("h") > 0; }, - direct:true, - priority:11+45+14+19+19+810, - content(){ - 'step 0' - player.removeGaintag('dcshixian_yayun'); - 'step 1' - player.addGaintag(player.getCards('h',card=>{ - return get.is.yayun(get.translation(card.name),get.translation(trigger.card.name)); - }),'dcshixian_yayun'); + direct: true, + priority: 11 + 45 + 14 + 19 + 19 + 810, + content() { + "step 0"; + player.removeGaintag("dcshixian_yayun"); + "step 1"; + player.addGaintag( + player.getCards("h", (card) => { + return get.is.yayun( + get.translation(card.name), + get.translation(trigger.card.name) + ); + }), + "dcshixian_yayun" + ); }, }, }, }, //龙王 - dclonggong:{ - audio:2, - trigger:{player:'damageBegin4'}, - usable:1, - filter(event,player){ - return event.source&&event.source.isIn(); + dclonggong: { + audio: 2, + trigger: { player: "damageBegin4" }, + usable: 1, + filter(event, player) { + return event.source && event.source.isIn(); }, - logTarget:'source', - check(event,player){ - return get.attitude(player,event.source)>=0||player.hp<=Math.max(2,event.num); + logTarget: "source", + check(event, player) { + return get.attitude(player, event.source) >= 0 || player.hp <= Math.max(2, event.num); }, - content(){ - 'step 0' + content() { + "step 0"; trigger.cancel(); - 'step 1' - var card=get.cardPile2(function(card){ - return get.type(card,null,false)=='equip'; - }),source=trigger.source; - if(card&&source&&source.isIn()) source.gain(card,'gain2'); + "step 1"; + var card = get.cardPile2(function (card) { + return get.type(card, null, false) == "equip"; + }), + source = trigger.source; + if (card && source && source.isIn()) source.gain(card, "gain2"); }, - ai:{ - filterDamage:true, - skillTagFilter(player){ - return !player.storage.counttrigger||!player.storage.counttrigger.dclonggong; + ai: { + filterDamage: true, + skillTagFilter(player) { + return !player.storage.counttrigger || !player.storage.counttrigger.dclonggong; }, }, }, - dcsitian:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - var colorx=false,hs=player.getCards('he'); - if(hs.length<2) return false; - for(var card of hs){ - if(!lib.filter.cardDiscardable(card,player)) continue; - var color=get.color(card,player); - if(color=='none') continue; - if(!colorx) colorx=color; - else if(colorx!=color) return true; + dcsitian: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + var colorx = false, + hs = player.getCards("he"); + if (hs.length < 2) return false; + for (var card of hs) { + if (!lib.filter.cardDiscardable(card, player)) continue; + var color = get.color(card, player); + if (color == "none") continue; + if (!colorx) colorx = color; + else if (colorx != color) return true; } return false; }, - filterCard(card,player){ - var color=get.color(card,player); - if(color=='none') return false; - return !ui.selected.cards.length||get.color(ui.selected.cards[0])!=color; + filterCard(card, player) { + var color = get.color(card, player); + if (color == "none") return false; + return !ui.selected.cards.length || get.color(ui.selected.cards[0]) != color; }, - selectCard:2, - complexCard:true, - prompt:'弃置两张颜色不同的牌并改变天气', - check:(card)=>4.5-get.value(card), - content(){ - 'step 0' - var list=['烈日','雷电','大浪','暴雨','大雾'].randomGets(2); - player.chooseButton(true,[ - '请选择执行一个天气', - [list.map(i=>[ - i, - '', - ]),'textbutton'], - ]).set('ai',function(button){ - return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player); - }) - 'step 1' - if(result.bool){ - var choice=result.links[0]; - game.log(player,'将当前天气变更为','#g'+choice); - var next=game.createEvent('dcsitian_weather',false); - next.player=player; + selectCard: 2, + complexCard: true, + prompt: "弃置两张颜色不同的牌并改变天气", + check: (card) => 4.5 - get.value(card), + content() { + "step 0"; + var list = ["烈日", "雷电", "大浪", "暴雨", "大雾"].randomGets(2); + player + .chooseButton(true, [ + "请选择执行一个天气", + [ + list.map((i) => [ + i, + '", + ]), + "textbutton", + ], + ]) + .set("ai", function (button) { + return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player); + }); + "step 1"; + if (result.bool) { + var choice = result.links[0]; + game.log(player, "将当前天气变更为", "#g" + choice); + var next = game.createEvent("dcsitian_weather", false); + next.player = player; next.setContent(lib.skill.dcsitian.weathers[choice].content); } }, - ai:{ - order:8, - result:{ - player(player){ - var num1=0,num2=0; - game.countPlayer(function(current){ - if(player==current) return; - var att=get.attitude(player,current); - if(att>0) num1++; + ai: { + order: 8, + result: { + player(player) { + var num1 = 0, + num2 = 0; + game.countPlayer(function (current) { + if (player == current) return; + var att = get.attitude(player, current); + if (att > 0) num1++; else num2++; }); - return num2-num1; + return num2 - num1; }, }, }, - subSkill:{ - dawu:{ - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - filter(event,player){ - return get.type2(event.card,false)=='basic'; + subSkill: { + dawu: { + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + filter(event, player) { + return get.type2(event.card, false) == "basic"; }, - content(){ - trigger.targets.length=0; - trigger.all_excluded=true; - player.removeSkill('dcsitian_dawu'); + content() { + trigger.targets.length = 0; + trigger.all_excluded = true; + player.removeSkill("dcsitian_dawu"); }, - mark:true, - marktext:'雾', - intro:{ - name:'司天 - 大雾', - content:'使用的下一张基本牌无效', + mark: true, + marktext: "雾", + intro: { + name: "司天 - 大雾", + content: "使用的下一张基本牌无效", }, }, }, - weathers:{ - 烈日:{ - description:'你对其他角色造成1点火属性伤害。', - content(){ - var targets=game.filterPlayer(current=>current!=player).sortBySeat(); - player.line(targets,'fire'); - for(var target of targets){ - target.damage('fire'); + weathers: { + 烈日: { + description: "你对其他角色造成1点火属性伤害。", + content() { + var targets = game.filterPlayer((current) => current != player).sortBySeat(); + player.line(targets, "fire"); + for (var target of targets) { + target.damage("fire"); } }, - ai(player){ - var effect=0; - game.countPlayer(function(current){ - if(current==player) return; - effect+=get.damageEffect(current,player,player,'fire'); + ai(player) { + var effect = 0; + game.countPlayer(function (current) { + if (current == player) return; + effect += get.damageEffect(current, player, player, "fire"); }); return effect; }, }, - 雷电:{ - description:'你令其他角色各进行一次判定。若结果为♠2~9,则其受到3点无来源雷属性伤害。', - content(){ - 'step 0' - var targets=game.filterPlayer(current=>current!=player).sortBySeat(); - player.line(targets,'thunder'); - event.targets=targets; - 'step 1' - var target=targets.shift(); - if(!target.isIn()){ - if(targets.length>0) event.redo(); - else{ + 雷电: { + description: + "你令其他角色各进行一次判定。若结果为♠2~9,则其受到3点无来源雷属性伤害。", + content() { + "step 0"; + var targets = game.filterPlayer((current) => current != player).sortBySeat(); + player.line(targets, "thunder"); + event.targets = targets; + "step 1"; + var target = targets.shift(); + if (!target.isIn()) { + if (targets.length > 0) event.redo(); + else { event.finish(); return; } } - event.target=target; - event.judgestr=get.translation('shandian'); - target.judge(lib.card.shandian.judge,event.judgestr).judge2=lib.card.shandian.judge2; + event.target = target; + event.judgestr = get.translation("shandian"); + target.judge(lib.card.shandian.judge, event.judgestr).judge2 = + lib.card.shandian.judge2; //game.delayx(1.5); - 'step 2' - var name='shandian'; - if(event.cancelled&&!event.direct){ - if(lib.card[name].cancel){ - var next=game.createEvent(name+'Cancel'); + "step 2"; + var name = "shandian"; + if (event.cancelled && !event.direct) { + if (lib.card[name].cancel) { + var next = game.createEvent(name + "Cancel"); next.setContent(lib.card[name].cancel); - next.cards=[]; - next.card=get.autoViewAs({name:name}); - next.player=target; + next.cards = []; + next.card = get.autoViewAs({ name: name }); + next.player = target; } - } - else{ - var next=game.createEvent(name); - next.setContent(function(){ - if(result.bool==false){ - player.damage(3,'thunder','nosource'); + } else { + var next = game.createEvent(name); + next.setContent(function () { + if (result.bool == false) { + player.damage(3, "thunder", "nosource"); } }); - next._result=result; - next.cards=[]; - next.card=get.autoViewAs({name:name}); - next.player=target; + next._result = result; + next.cards = []; + next.card = get.autoViewAs({ name: name }); + next.player = target; } - if(targets.length>0) event.goto(1); + if (targets.length > 0) event.goto(1); }, - ai(player){ - var effect=0; - game.countPlayer(function(current){ - if(current==player) return; - effect+=get.damageEffect(current,current,player,'thunder')/5; + ai(player) { + var effect = 0; + game.countPlayer(function (current) { + if (current == player) return; + effect += get.damageEffect(current, current, player, "thunder") / 5; }); return effect; }, }, - 大浪:{ - description:'你弃置其他角色装备区内的所有牌(装备区内没有牌的角色改为失去1点体力)。', - content(){ - 'step 0' - var targets=game.filterPlayer(current=>current!=player).sortBySeat(); - player.line(targets,'green'); - event.targets=targets; - 'step 1' - var target=targets.shift(); - if(target.isIn()){ - var num=target.countCards('e'); - if(num>0){ - player.discardPlayerCard(target,true,'e',num) - } - else{ + 大浪: { + description: + "你弃置其他角色装备区内的所有牌(装备区内没有牌的角色改为失去1点体力)。", + content() { + "step 0"; + var targets = game.filterPlayer((current) => current != player).sortBySeat(); + player.line(targets, "green"); + event.targets = targets; + "step 1"; + var target = targets.shift(); + if (target.isIn()) { + var num = target.countCards("e"); + if (num > 0) { + player.discardPlayerCard(target, true, "e", num); + } else { target.loseHp(); game.delayex(); } } - if(targets.length>0) event.redo(); + if (targets.length > 0) event.redo(); }, - ai(player){ - var effect=0; - game.countPlayer(function(current){ - if(current==player) return; - var es=current.getCards('e'); - if(es.length>0){ - var att=get.attitude(player,current),val=get.value(es,current); - effect-=Math.sqrt(att)*val; - } - else effect+=get.effect(current,{name:'losehp'},player,player); + ai(player) { + var effect = 0; + game.countPlayer(function (current) { + if (current == player) return; + var es = current.getCards("e"); + if (es.length > 0) { + var att = get.attitude(player, current), + val = get.value(es, current); + effect -= Math.sqrt(att) * val; + } else effect += get.effect(current, { name: "losehp" }, player, player); }); return effect; }, }, - 暴雨:{ - description:'你弃置一名角色的所有手牌。若其没有手牌,则改为令其失去1点体力。', - content(){ - 'step 0' - player.chooseTarget('请选择【暴雨】的目标','令目标角色弃置所有手牌。若其没有手牌,则其改为失去1点体力。').set('ai',function(current){ - var es=current.getCards('h'),player=_status.event.player; - if(es.length>0){ - var att=get.attitude(player,current),val=get.value(es,current); - return -Math.sqrt(att)*val; - } - return get.effect(current,{name:'losehp'},player,player); - }) - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - var num=target.countCards('h'); - if(num>0){ - player.discardPlayerCard(target,true,'h',num) - } - else{ + 暴雨: { + description: "你弃置一名角色的所有手牌。若其没有手牌,则改为令其失去1点体力。", + content() { + "step 0"; + player + .chooseTarget( + "请选择【暴雨】的目标", + "令目标角色弃置所有手牌。若其没有手牌,则其改为失去1点体力。" + ) + .set("ai", function (current) { + var es = current.getCards("h"), + player = _status.event.player; + if (es.length > 0) { + var att = get.attitude(player, current), + val = get.value(es, current); + return -Math.sqrt(att) * val; + } + return get.effect(current, { name: "losehp" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + var num = target.countCards("h"); + if (num > 0) { + player.discardPlayerCard(target, true, "h", num); + } else { target.loseHp(); game.delayex(); } } }, - ai(player){ - return Math.max.apply(Math,game.filterPlayer(function(current){ - return current!=player - }).map(function(current){ - var es=current.getCards('h'); - if(es.length>0){ - var att=get.attitude(player,current),val=get.value(es,current); - return -Math.sqrt(att)*val; - } - return get.effect(current,{name:'losehp'},player,player); - })); + ai(player) { + return Math.max.apply( + Math, + game + .filterPlayer(function (current) { + return current != player; + }) + .map(function (current) { + var es = current.getCards("h"); + if (es.length > 0) { + var att = get.attitude(player, current), + val = get.value(es, current); + return -Math.sqrt(att) * val; + } + return get.effect(current, { name: "losehp" }, player, player); + }) + ); }, }, - 大雾:{ - description:'你令所有其他角色获得如下效果:当其使用下一张基本牌时,取消之。', - content(){ - var targets=game.filterPlayer(current=>current!=player).sortBySeat(); + 大雾: { + description: "你令所有其他角色获得如下效果:当其使用下一张基本牌时,取消之。", + content() { + var targets = game.filterPlayer((current) => current != player).sortBySeat(); player.line(targets); - for(var target of targets) target.addSkill('dcsitian_dawu'); + for (var target of targets) target.addSkill("dcsitian_dawu"); }, - ai(player){ - var effect=0; - game.countPlayer(function(current){ - if(current==player||current.hasSkill('dcsitian_dawu')) return; - effect-=0.5*get.attitude(player,current); + ai(player) { + var effect = 0; + game.countPlayer(function (current) { + if (current == player || current.hasSkill("dcsitian_dawu")) return; + effect -= 0.5 * get.attitude(player, current); }); return effect; }, @@ -1232,743 +1534,890 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //美猴王 - dcjinjing:{ - locked:true, - ai:{ - viewHandcard:true, - skillTagFilter(player,tag,arg){ - if(player==arg) return false; + dcjinjing: { + locked: true, + ai: { + viewHandcard: true, + skillTagFilter(player, tag, arg) { + if (player == arg) return false; }, }, }, - dccibei:{ - audio:2, - trigger:{source:'damageBegin2'}, - logTarget:'player', - filter(event,player){ - return player!=event.player&&!player.hasHistory('useSkill',function(evt){ - return evt.skill=='dccibei'&&evt.targets.includes(event.player); - }); + dccibei: { + audio: 2, + trigger: { source: "damageBegin2" }, + logTarget: "player", + filter(event, player) { + return ( + player != event.player && + !player.hasHistory("useSkill", function (evt) { + return evt.skill == "dccibei" && evt.targets.includes(event.player); + }) + ); }, - check(event,player){ - var target=event.player; - if(get.attitude(player,target)>=0) return true; - return (!player.getStat('skill').ruyijingubang_skill||player.storage.ruyijingubang_skill==1); + check(event, player) { + var target = event.player; + if (get.attitude(player, target) >= 0) return true; + return ( + !player.getStat("skill").ruyijingubang_skill || + player.storage.ruyijingubang_skill == 1 + ); }, - content(){ + content() { trigger.cancel(); player.draw(5); }, - ai:{ - threaten:4.5, + ai: { + threaten: 4.5, }, }, - dcruyi:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dcruyi: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.hasEquipableSlot(1)&&!player.getEquips('ruyijingubang').length; + forced: true, + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + player.hasEquipableSlot(1) && + !player.getEquips("ruyijingubang").length + ); }, - content(){ - var card=game.createCard2('ruyijingubang','heart',9); - player.$gain2(card,false); + content() { + var card = game.createCard2("ruyijingubang", "heart", 9); + player.$gain2(card, false); game.delayx(); player.equip(card); }, - mod:{ - canBeGained(card,source,player){ - if(player.getEquips('ruyijingubang').includes(card)) return false; + mod: { + canBeGained(card, source, player) { + if (player.getEquips("ruyijingubang").includes(card)) return false; }, - canBeDiscarded(card,source,player){ - if(player.getEquips('ruyijingubang').includes(card)) return false; + canBeDiscarded(card, source, player) { + if (player.getEquips("ruyijingubang").includes(card)) return false; }, - canBeReplaced(card,player){ - if(player.getEquips('ruyijingubang').includes(card)) return false; + canBeReplaced(card, player) { + if (player.getEquips("ruyijingubang").includes(card)) return false; }, - cardname(card){ - if(get.subtype(card,false)=='equip1') return 'sha'; + cardname(card) { + if (get.subtype(card, false) == "equip1") return "sha"; }, - cardnature(card){ - if(get.subtypes(card,false).includes('equip1')) return false; + cardnature(card) { + if (get.subtypes(card, false).includes("equip1")) return false; }, - cardDiscardable(card,player){ - if(player.getEquips('ruyijingubang').includes(card)) return false; + cardDiscardable(card, player) { + if (player.getEquips("ruyijingubang").includes(card)) return false; }, - cardEnabled2(card,player){ - if(player.getEquips('ruyijingubang').includes(card)) return false; + cardEnabled2(card, player) { + if (player.getEquips("ruyijingubang").includes(card)) return false; }, }, - group:'dcruyi_blocker', - subSkill:{ - blocker:{ - trigger:{player:['loseBefore','disableEquipBefore']}, - forced:true, - filter(event,player){ - if(event.name=='disableEquip') return (event.slots.includes('equip1')); - var cards=player.getEquips('ruyijingubang'); - return event.cards.some(card=>cards.includes(card)); + group: "dcruyi_blocker", + subSkill: { + blocker: { + trigger: { + player: ["loseBefore", "disableEquipBefore"], }, - content(){ - if(trigger.name=='lose'){ - trigger.cards.removeArray(player.getEquips('ruyijingubang')); - } - else{ - while(trigger.slots.includes('equip1')) trigger.slots.remove('equip1'); + forced: true, + filter(event, player) { + if (event.name == "disableEquip") return event.slots.includes("equip1"); + var cards = player.getEquips("ruyijingubang"); + return event.cards.some((card) => cards.includes(card)); + }, + content() { + if (trigger.name == "lose") { + trigger.cards.removeArray(player.getEquips("ruyijingubang")); + } else { + while (trigger.slots.includes("equip1")) trigger.slots.remove("equip1"); } }, }, }, }, - ruyijingubang_skill:{ - equipSkill:true, - enable:'phaseUse', - usable:1, - chooseButton:{ - dialog(){ - var dialog=ui.create.dialog( - '如意金箍棒:选择变化攻击范围', - [[ - [1,'   ⒈【杀】无次数限制   '], - [2,'   ⒉【杀】的伤害值+1   '], - ],'tdnodes'], - [[ - [3,'   ⒊【杀】不可被响应   '], - [4,'   ⒋【杀】的目标数+1   '], - ],'tdnodes'] + ruyijingubang_skill: { + equipSkill: true, + enable: "phaseUse", + usable: 1, + chooseButton: { + dialog() { + var dialog = ui.create.dialog( + "如意金箍棒:选择变化攻击范围", + [ + [ + [1, "   ⒈【杀】无次数限制   "], + [2, "   ⒉【杀】的伤害值+1   "], + ], + "tdnodes", + ], + [ + [ + [3, "   ⒊【杀】不可被响应   "], + [4, "   ⒋【杀】的目标数+1   "], + ], + "tdnodes", + ] ); return dialog; }, - filter(button,player){ - return button.link!=player.storage.ruyijingubang_skill; + filter(button, player) { + return button.link != player.storage.ruyijingubang_skill; }, - check(button){ - if(button.link==1||button.link==3) return 1; + check(button) { + if (button.link == 1 || button.link == 3) return 1; return 0; }, - backup(links,player){ + backup(links, player) { return { - audio:'dcruyi', - num:links[0], - popup:'如意金箍棒', - content(){ - var num=lib.skill.ruyijingubang_skill_backup.num; - player.storage.ruyijingubang_skill=num; - var cards=player.getEquips(1); - for(var card of cards){ - if(card&&card.name=='ruyijingubang'){ - card.storage.ruyijingubang_skill=num; - game.log(player,'将',card,'的攻击范围改为'+num) + audio: "dcruyi", + num: links[0], + popup: "如意金箍棒", + content() { + var num = lib.skill.ruyijingubang_skill_backup.num; + player.storage.ruyijingubang_skill = num; + var cards = player.getEquips(1); + for (var card of cards) { + if (card && card.name == "ruyijingubang") { + card.storage.ruyijingubang_skill = num; + game.log(player, "将", card, "的攻击范围改为" + num); } } - player.markSkill('ruyijingubang_skill'); + player.markSkill("ruyijingubang_skill"); }, - } + }; }, }, - mod:{ - cardUsable(card,player,num){ - if(player.storage.ruyijingubang_skill==1&&card.name=='sha') return Infinity; + mod: { + cardUsable(card, player, num) { + if (player.storage.ruyijingubang_skill == 1 && card.name == "sha") return Infinity; }, }, - ai:{ - order:1, - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return player.storage.ruyijingubang_skill==3; + ai: { + order: 1, + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return player.storage.ruyijingubang_skill == 3; }, - effect:{ - player(card,player,target,current){ - if(get.tag(card,'damage')>0&&player!=target){ - if(player.getStat('skill').ruyijingubang_skill&&player.storage.ruyijingubang_skill!=1) return; - if(player.hasSkill('dccibei')&&!player.hasHistory('useSkill',function(evt){ - return evt.skill=='dccibei'&&evt.targets.includes(target); - })){ - return [1,3]; + effect: { + player(card, player, target, current) { + if (get.tag(card, "damage") > 0 && player != target) { + if ( + player.getStat("skill").ruyijingubang_skill && + player.storage.ruyijingubang_skill != 1 + ) + return; + if ( + player.hasSkill("dccibei") && + !player.hasHistory("useSkill", function (evt) { + return evt.skill == "dccibei" && evt.targets.includes(target); + }) + ) { + return [1, 3]; } } }, }, - result:{ - player(player){ - if(player.storage.ruyijingubang_skill==1){ - if(!player.hasSha()) return 1; + result: { + player(player) { + if (player.storage.ruyijingubang_skill == 1) { + if (!player.hasSha()) return 1; return 0; - } - else{ - if(player.hasSha()&&player.getCardUsable('sha')<=0) return 1; + } else { + if (player.hasSha() && player.getCardUsable("sha") <= 0) return 1; return 0; } }, - } - }, - intro:{ - name:'如意金箍棒', - content(storage){ - if(!storage) storage=3; - return '
            • 攻击范围:'+storage+'
            • '+['你使用【杀】无次数限制。','你使用的【杀】伤害+1。','你使用的【杀】不可被响应。','你使用【杀】选择目标后,可以增加一个额外目标。'][storage-1] }, }, - subSkill:{ - backup:{}, + intro: { + name: "如意金箍棒", + content(storage) { + if (!storage) storage = 3; + return ( + "
            • 攻击范围:" + + storage + + "
            • " + + [ + "你使用【杀】无次数限制。", + "你使用的【杀】伤害+1。", + "你使用的【杀】不可被响应。", + "你使用【杀】选择目标后,可以增加一个额外目标。", + ][storage - 1] + ); + }, + }, + subSkill: { + backup: {}, }, }, - ruyijingubang_effect:{ - equipSkill:true, - trigger:{player:'useCard2'}, - direct:true, - locked:true, - filter(event,player){ - if(event.card.name!='sha') return false; - var num=player.storage.ruyijingubang_skill; - if(!num||num==1) return false; - if(num!=4) return true; - var card=event.card; - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&lib.filter.targetInRange(card,player,current); - })){ + ruyijingubang_effect: { + equipSkill: true, + trigger: { player: "useCard2" }, + direct: true, + locked: true, + filter(event, player) { + if (event.card.name != "sha") return false; + var num = player.storage.ruyijingubang_skill; + if (!num || num == 1) return false; + if (num != 4) return true; + var card = event.card; + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + lib.filter.targetInRange(card, player, current) + ); + }) + ) { return true; } return false; }, - content(){ - 'step 0' - var num=player.storage.ruyijingubang_skill; - if(num==4){ - player.chooseTarget(get.prompt('ruyijingubang_effect'),'为'+get.translation(trigger.card)+'额外指定一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target,false); - }).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); - } - else{ - player.logSkill('ruyijingubang_effect'); - if(num==2){ + content() { + "step 0"; + var num = player.storage.ruyijingubang_skill; + if (num == 4) { + player + .chooseTarget( + get.prompt("ruyijingubang_effect"), + "为" + get.translation(trigger.card) + "额外指定一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target, false) + ); + } + ) + .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); + } else { + player.logSkill("ruyijingubang_effect"); + if (num == 2) { trigger.baseDamage++; - game.log(trigger.card,'的伤害+1'); - } - else if(num==3){ + game.log(trigger.card, "的伤害+1"); + } else if (num == 3) { trigger.directHit.addArray(game.filterPlayer()); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); } event.finish(); } - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - player.logSkill('ruyijingubang_effect',event.targets); + "step 2"; + player.logSkill("ruyijingubang_effect", event.targets); trigger.targets.addArray(event.targets); }, }, //涛神 - dcnutao:{ - audio:4, - trigger:{player:'useCardToPlayer'}, - forced:true, - group:'dcnutao_add', - filter(event,player){ - if(get.type2(event.card)!='trick') return false; - return event.isFirstTarget&&event.targets.some(i=>i!=player); + dcnutao: { + audio: 4, + trigger: { player: "useCardToPlayer" }, + forced: true, + group: "dcnutao_add", + filter(event, player) { + if (get.type2(event.card) != "trick") return false; + return event.isFirstTarget && event.targets.some((i) => i != player); }, - content(){ - var target=trigger.targets.filter(i=>i!=player).randomGet(); - player.line(target,'thunder'); - target.damage('thunder'); + content() { + var target = trigger.targets.filter((i) => i != player).randomGet(); + player.line(target, "thunder"); + target.damage("thunder"); }, - ai:{ - effect:{ - player(card,player,target){ - if(player!==target&&get.type2(card)==='trick'){ - let tars=[target]; - if(ui.selected.targets.length) tars.addArray(ui.selected.targets.filter(i=>i!==player&&i!==target)); - if(tars.length<2) return [1,0,1,-2]; - return [1,0,1,-2/tars.length]; + ai: { + effect: { + player(card, player, target) { + if (player !== target && get.type2(card) === "trick") { + let tars = [target]; + if (ui.selected.targets.length) + tars.addArray( + ui.selected.targets.filter((i) => i !== player && i !== target) + ); + if (tars.length < 2) return [1, 0, 1, -2]; + return [1, 0, 1, -2 / tars.length]; } }, }, }, - subSkill:{ - add:{ - audio:'dcnutao', - trigger:{source:'damageSource'}, - filter(event,player){ - return event.nature=='thunder'&&player.isPhaseUsing(); + subSkill: { + add: { + audio: "dcnutao", + trigger: { source: "damageSource" }, + filter(event, player) { + return event.nature == "thunder" && player.isPhaseUsing(); + }, + forced: true, + content() { + player.addTempSkill("dcnutao_sha", "phaseUseAfter"); + player.addMark("dcnutao_sha", 1, false); }, - forced:true, - content(){ - player.addTempSkill('dcnutao_sha','phaseUseAfter'); - player.addMark('dcnutao_sha',1,false); - } }, - sha:{ - charlotte:true, - onremove:true, - marktext:'涛', - intro:{ - content:'此阶段使用【杀】的次数上限+#', + sha: { + charlotte: true, + onremove: true, + marktext: "涛", + intro: { + content: "此阶段使用【杀】的次数上限+#", }, - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.countMark('dcnutao_sha'); + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("dcnutao_sha"); }, - } - } - } + }, + }, + }, }, //铜雀台 - spduanzhi:{ - trigger:{target:'useCardToTargeted'}, - logTarget:'player', - check(event,player){ - var target=event.player; - if(get.attitude(player,target)>=-2||target.countCards('he',function(card){ - return get.value(card,target)>5; - })<2) return false; - if(player.hp>2) return true; - if(player.hp==1){ - if(get.tag(event.card,'respondSha')){ - if(player.countCards('h',{name:'sha'})==0){ + spduanzhi: { + trigger: { target: "useCardToTargeted" }, + logTarget: "player", + check(event, player) { + var target = event.player; + if ( + get.attitude(player, target) >= -2 || + target.countCards("he", function (card) { + return get.value(card, target) > 5; + }) < 2 + ) + return false; + if (player.hp > 2) return true; + if (player.hp == 1) { + if (get.tag(event.card, "respondSha")) { + if (player.countCards("h", { name: "sha" }) == 0) { return true; } - } - else if(get.tag(event.card,'respondShan')){ - if(player.countCards('h',{name:'shan'})==0){ + } else if (get.tag(event.card, "respondShan")) { + if (player.countCards("h", { name: "shan" }) == 0) { return true; } - } - else if(get.tag(event.card,'damage')){ - if(event.card.name=='shuiyanqijunx') return player.countCards('e')==0; + } else if (get.tag(event.card, "damage")) { + if (event.card.name == "shuiyanqijunx") return player.countCards("e") == 0; return true; } } return false; }, - filter(event,player){ - return player!=event.player&&event.player.countDiscardableCards(player,'he')>0; + filter(event, player) { + return player != event.player && event.player.countDiscardableCards(player, "he") > 0; }, - content(){ - player.discardPlayerCard(trigger.player,true,'he',[1,2]); + content() { + player.discardPlayerCard(trigger.player, true, "he", [1, 2]); player.loseHp(); }, }, - spduyi:{ - enable:'phaseUse', - usable:1, - content(){ - 'step 0' - event.card=get.cards()[0]; + spduyi: { + enable: "phaseUse", + usable: 1, + content() { + "step 0"; + event.card = get.cards()[0]; game.cardsGotoOrdering(event.card); player.showCards(event.card); - 'step 1' - player.chooseTarget('令一名角色获得'+get.translation(card),true).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.du){ - if(target.hasSkillTag('nodu')) return 0; - return -att; - } - if(att>0){ - if(target==player) att*=0.6; - return att+Math.sqrt(Math.max(0,5-target.countCards('h'))); - } - return att; - }).set('du',card.name=='du'); - 'step 2' - if(result&&result.bool){ - var target=result.targets[0]; - target.gain(card,'gain2'); - if(get.color(card,false)=='black') target.addTempSkill('spduyi2'); + "step 1"; + player + .chooseTarget("令一名角色获得" + get.translation(card), true) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0; + return -att; + } + if (att > 0) { + if (target == player) att *= 0.6; + return att + Math.sqrt(Math.max(0, 5 - target.countCards("h"))); + } + return att; + }) + .set("du", card.name == "du"); + "step 2"; + if (result && result.bool) { + var target = result.targets[0]; + target.gain(card, "gain2"); + if (get.color(card, false) == "black") target.addTempSkill("spduyi2"); } }, - ai:{ - order:0.1, - result:{ - player:1, + ai: { + order: 0.1, + result: { + player: 1, }, }, }, - spduyi2:{ - mod:{ - cardEnabled2(card){ - if(get.position(card)=='h') return false; + spduyi2: { + mod: { + cardEnabled2(card) { + if (get.position(card) == "h") return false; }, }, - mark:true, - intro:{ - content:'不能使用或打出手牌', + mark: true, + intro: { + content: "不能使用或打出手牌", }, }, - spcangni:{ - audio:'zhuikong', - trigger:{player:'phaseDiscardBegin'}, - direct:true, - content(){ - 'step 0' - player.chooseDrawRecover('###'+get.prompt('spcangni')+'###摸两张牌或回复1点体力,然后将武将牌翻面',2).logSkill='spcangni'; - 'step 1' - if(result.control!='cancel2') player.turnOver(); + spcangni: { + audio: "zhuikong", + trigger: { player: "phaseDiscardBegin" }, + direct: true, + content() { + "step 0"; + player.chooseDrawRecover( + "###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力,然后将武将牌翻面", + 2 + ).logSkill = "spcangni"; + "step 1"; + if (result.control != "cancel2") player.turnOver(); }, - group:['spcangni_gain','spcangni_lose'], - subSkill:{ - gain:{ - audio:'zhuikong', - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + group: ["spcangni_gain", "spcangni_lose"], + subSkill: { + gain: { + audio: "zhuikong", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - usable:1, - filter(event,player){ - return player.isTurnedOver()&&player!=_status.currentPhase&&event.getg(player).length>0; + usable: 1, + filter(event, player) { + return ( + player.isTurnedOver() && + player != _status.currentPhase && + event.getg(player).length > 0 + ); }, - check(event,player){ - return get.attitude(player,_status.currentPhase)>0; + check(event, player) { + return get.attitude(player, _status.currentPhase) > 0; }, - logTarget(){ + logTarget() { return _status.currentPhase; }, - prompt2:'令该角色摸一张牌', - content(){ + prompt2: "令该角色摸一张牌", + content() { _status.currentPhase.draw(); }, }, - lose:{ - audio:'zhuikong', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + lose: { + audio: "zhuikong", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - if(event.name=='gain'&&player==event.player) return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - return player.isTurnedOver()&&player!=_status.currentPhase&&_status.currentPhase.countCards('he')>0; + filter(event, player) { + if (event.name == "gain" && player == event.player) return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + return ( + player.isTurnedOver() && + player != _status.currentPhase && + _status.currentPhase.countCards("he") > 0 + ); }, - check(event,player){ - var target=_status.currentPhase; - var att=get.attitude(player,target); - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })) return att>0; - return att<0; + check(event, player) { + var target = _status.currentPhase; + var att = get.attitude(player, target); + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) + ) + return att > 0; + return att < 0; }, - logTarget(){ + logTarget() { return _status.currentPhase; }, - prompt2:'令该角色弃置一张牌', - content(){ - _status.currentPhase.chooseToDiscard('he',true); + prompt2: "令该角色弃置一张牌", + content() { + _status.currentPhase.chooseToDiscard("he", true); }, }, }, }, - spmixin:{ - audio:'qiuyuan', - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0&&game.countPlayer()>2; + spmixin: { + audio: "qiuyuan", + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0 && game.countPlayer() > 2; }, - filterCard:true, - filterTarget:lib.filter.notMe, - position:'h', - selectTarget:2, - targetprompt:['拿牌打人','被打'], - multitarget:true, - delay:false, - discard:false, - lose:false, - check(card){ - if(card.name=='sha') return 4; - return 4-get.value(card); + filterCard: true, + filterTarget: lib.filter.notMe, + position: "h", + selectTarget: 2, + targetprompt: ["拿牌打人", "被打"], + multitarget: true, + delay: false, + discard: false, + lose: false, + check(card) { + if (card.name == "sha") return 4; + return 4 - get.value(card); }, - content(){ - 'step 0' - player.give(cards,targets[0]); - 'step 1' - if(!targets[0].isIn()||!targets[1].isIn()){ + content() { + "step 0"; + player.give(cards, targets[0]); + "step 1"; + if (!targets[0].isIn() || !targets[1].isIn()) { event.finish(); return; } - targets[0].chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'密信:对'+get.translation(targets[1])+'使用一张【杀】,或令其观看并获得你的一张手牌').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',targets[1]); - 'step 2' - if(!result.bool&&targets[0].countCards('h')) targets[1].gainPlayerCard(targets[0],'visible','h',true); + targets[0] + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "密信:对" + + get.translation(targets[1]) + + "使用一张【杀】,或令其观看并获得你的一张手牌") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", targets[1]); + "step 2"; + if (!result.bool && targets[0].countCards("h")) + targets[1].gainPlayerCard(targets[0], "visible", "h", true); }, - ai:{ - order:1, - expose:0.1, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(!card) return 0; - if(ui.selected.targets.length==0){ - if(card.name=='sha'||target.hasSha()) return 2; - if(get.value(card,target)<0) return -2; + ai: { + order: 1, + expose: 0.1, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (!card) return 0; + if (ui.selected.targets.length == 0) { + if (card.name == "sha" || target.hasSha()) return 2; + if (get.value(card, target) < 0) return -2; return 0; } - var target1=ui.selected.targets[0]; - if((card.name=='sha'||target1.hasSha())&&get.effect(target,{name:'sha'},target1,target1)>0) return get.effect(target,{name:'sha'},target1,target); + var target1 = ui.selected.targets[0]; + if ( + (card.name == "sha" || target1.hasSha()) && + get.effect(target, { name: "sha" }, target1, target1) > 0 + ) + return get.effect(target, { name: "sha" }, target1, target); return 1.5; }, }, }, }, - spfengyin:{ - audio:'moukui', - trigger:{global:'phaseZhunbeiBegin'}, - direct:true, - filter(event,player){ - return player!=event.player&&event.player.hp>=player.hp&&player.countCards('h',function(card){ - if(_status.connectMode) return true; - return get.name(card,player)=='sha'; - })>0; + spfengyin: { + audio: "moukui", + trigger: { global: "phaseZhunbeiBegin" }, + direct: true, + filter(event, player) { + return ( + player != event.player && + event.player.hp >= player.hp && + player.countCards("h", function (card) { + if (_status.connectMode) return true; + return get.name(card, player) == "sha"; + }) > 0 + ); }, - content(){ - 'step 0' - player.chooseCard('h',get.prompt('spfengyin',trigger.player),'交给该角色一张【杀】并令其跳过出牌阶段和弃牌阶段',function(card,player){ - return get.name(card,player)=='sha'; - }).set('ai',function(card){ - if(_status.event.goon) return 5-get.value(card); - return 0; - }).set('goon',function(){ - if(get.attitude(player,trigger.player)>=0) return false; - if(trigger.player.countCards('hs')= 0) return false; + if (trigger.player.countCards("hs") < trigger.player.hp) return false; + return true; + })() + ); + "step 1"; + if (result.bool) { + var target = trigger.player; + player.logSkill("spfengyin", target); + player.give(result.cards, target, "give"); + target.skip("phaseUse"); + target.skip("phaseDiscard"); } }, }, - spchizhong:{ - mod:{ - maxHandcardBase(player,num){ + spchizhong: { + mod: { + maxHandcardBase(player, num) { return player.maxHp; }, }, - trigger:{global:'dieAfter'}, - forced:true, - content(){ + trigger: { global: "dieAfter" }, + forced: true, + content() { player.gainMaxHp(); }, }, - fenxin_old:{ - mode:['identity'], - trigger:{source:'dieBegin'}, - init(player){ - player.storage.fenxin=false; + fenxin_old: { + mode: ["identity"], + trigger: { source: "dieBegin" }, + init(player) { + player.storage.fenxin = false; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - skillAnimation:'epic', - animationColor:'fire', - unique:true, - limited:true, - audio:2, - mark:true, - filter(event,player){ - if(player.storage.fenxin) return false; - return event.player.identity!='zhu'&&player.identity!='zhu'&& - player.identity!='mingzhong'&&event.player.identity!='mingzhong'; + skillAnimation: "epic", + animationColor: "fire", + unique: true, + limited: true, + audio: 2, + mark: true, + filter(event, player) { + if (player.storage.fenxin) return false; + return ( + event.player.identity != "zhu" && + player.identity != "zhu" && + player.identity != "mingzhong" && + event.player.identity != "mingzhong" + ); }, - check(event,player){ - if(player.identity==event.player.identity) return Math.random()<0.5; - var stat=get.situation(); - switch(player.identity){ - case 'fan': - if(stat<0) return false; - if(stat==0) return Math.random()<0.6; + check(event, player) { + if (player.identity == event.player.identity) return Math.random() < 0.5; + var stat = get.situation(); + switch (player.identity) { + case "fan": + if (stat < 0) return false; + if (stat == 0) return Math.random() < 0.6; return true; - case 'zhong': - if(stat>0) return false; - if(stat==0) return Math.random()<0.6; + case "zhong": + if (stat > 0) return false; + if (stat == 0) return Math.random() < 0.6; return true; - case 'nei': - if(event.player.identity=='fan'&&stat<0) return true; - if(event.player.identity=='zhong'&&stat>0) return true; - if(stat==0) return Math.random()<0.7; + case "nei": + if (event.player.identity == "fan" && stat < 0) return true; + if (event.player.identity == "zhong" && stat > 0) return true; + if (stat == 0) return Math.random() < 0.7; return false; } return false; }, - prompt(event,player){ - return '焚心:是否与'+get.translation(event.player)+'交换身份?'; + prompt(event, player) { + return "焚心:是否与" + get.translation(event.player) + "交换身份?"; }, - content(){ - game.broadcastAll(function(player,target,shown){ - var identity=player.identity; - player.identity=target.identity; - if(shown||player==game.me){ - player.setIdentity(); - } - target.identity=identity; - },player,trigger.player,trigger.player.identityShown); - player.line(trigger.player,'green'); - player.storage.fenxin=true; - player.awakenSkill('fenxin_old'); - } - }, - }, - characterIntro:{ - sunwukong:'孙悟空是中国古典小说《西游记》的主人公,也是中国神话中的民俗神祇之一,明代百回本《西游记》书中最为深入人心的形象之一。《西游记》中的孙悟空本是天地生成的一个石猴,率领群猴在花果山水帘洞过着逍遥自在的日子,后来为学习长生的法术而拜菩提祖师为师,学会了七十二变和筋斗云等绝技。后来他前往东海龙宫夺取如意金箍棒,又大闹地府勾了生死簿,惊动天庭,天庭两次派兵征讨花果山,仍然降他不得,只好请西天如来佛祖前来助阵。如来佛祖以五行山将悟空压在山下五百年。五百年后,悟空在观音菩萨的指点下拜唐僧为师,并跟随唐僧前往西天求取真经。路上唐僧又收了猪八戒、沙和尚两个徒弟,众人在途中斩妖除魔、历经磨难,终于取得真经,修成正果。', - longwang:'东海龙王,名敖广,是中国古代神话传说中的龙族之王,为“四海龙王”之首,亦为所有水族之王。统治东海之洋,主宰着雨水、雷鸣、洪灾、海潮、海啸等。曾下陷东京、水淹陈塘关(影视设定)。在中国以东方为尊位,按周易来说东为阳,故此东海龙王排第一便是理所应当。常记载于《西游记》《封神演义》《三教搜神大全》等文学典籍。东海龙王居于东海的海底水晶宫(花果山瀑布顺流可直抵龙宫)。虽为司雨之神,但其保持着较大的特殊自由性,人间降雨由其它江河湖井龙王完成,很少需要东海龙王亲自降雨。海洋管辖之权为龙王所有,天庭一般任其自治。', - taoshen:'涛神,是司掌钱塘江的神,传说其原型为春秋战国时期的吴国大臣伍子胥。伍子胥从楚国投奔吴国,为吴国立下了汗马功劳;但吴王夫差听信太宰伯嚭的谗言,逐渐疏远了伍子胥,最后还赐死了他。伍子胥含冤身亡,十分悲愤,做出了吴国灭亡的预言后自杀。暴怒的夫差下令用皮革包裹住伍子胥的尸身,在五月五日这天丢进钱塘江。百姓可怜伍子胥忠于吴王却遭受惨死,因此将五月五日这一天定为节日,以此纪念伍子胥,这也是端午节的来历之一。', - libai:'李白(701年2月28日—762年12月),字太白,号青莲居士,祖籍陇西成纪(今甘肃省秦安县),出生于蜀郡绵州昌隆县(一说出生于西域碎叶)。唐朝伟大的浪漫主义诗人,凉武昭王李暠九世孙。
              为人爽朗大方,乐于交友,爱好饮酒作诗,名列“酒中八仙”。曾经得到唐玄宗李隆基赏识,担任翰林学士,赐金放还,游历全国,先后迎娶宰相许圉师、宗楚客的孙女。唐肃宗即位后,卷入永王之乱,流放夜郎,辗转到达当涂县令李阳冰家。上元二年,去世,时年六十二。
              著有《李太白集》,代表作有《望庐山瀑布》《行路难》《蜀道难》《将进酒》《早发白帝城》等。李白所作词赋,就其开创意义及艺术成就而言,享有极为崇高的地位,后世誉为“诗仙”,与诗圣杜甫并称“李杜”。', - sunyang:'孙杨,1991年12月1日生于浙江杭州,男子1500米自由泳世界纪录保持者,男子400米自由泳奥运会纪录保持者。年伦敦奥运会男子400米自由泳、男子1500米自由泳冠军;2016年里约奥运会男子200米自由泳冠军。孙杨是世界泳坛历史上唯一一位男子200米自由泳、男子400米自由泳、男子1500米自由泳的奥运会世锦赛大满贯冠军得主,史上唯一一位男子400米自由泳世锦赛四连冠,唯一一位男子800米自由泳世锦赛三连冠,男子自由泳个人单项金牌数居世界第一。', - yeshiwen:'叶诗文,1996年3月1日生于浙江省杭州市,中国女子游泳队运动员,女子200米混合泳奥运会纪录保持者。叶诗文是中国泳坛首位集奥运会、长池世锦赛、短池世锦赛、游泳世界杯、亚运会、全运会冠军于一身的运动员,成为中国泳坛首个金满贯。2010年广州亚运会女子200米和400米个人混合泳冠军。2011年上海世界游泳锦标赛女子200米混合泳冠军。2012年伦敦奥运会女子200米混合泳、400米混合泳冠军。2012年伊斯坦布尔短池世锦赛女子200米混合泳冠军。2013年辽宁全运会女子200米、400米混合泳冠军。2016年里约奥运会女子200米混合泳第八名。2017年天津全运会女子200米混合泳冠军。2019年光州世界游泳锦标赛女子200米混合泳亚军、女子400米混合泳亚军。2018年1月30日,当选为浙江省出席第十三届全国人民代表大会代表。2019年7月28日,2019年韩国光州游泳世锦赛,叶诗文以4分32秒07获得亚军。2021年9月19日,叶诗文获得第十四届全国运动会游泳女子4×200米混合泳接力金牌。9月22日,叶诗文获得全运会女子200米个人混合泳银牌。', - jiben:'吉本(?—218年),东汉末年太医令。建安二十三年春正月,时金祎自以世为汉臣,睹汉祚将移,谓可季兴,乃喟然发愤,遂与太医令本、少府耿纪、司直韦晃、本子邈、邈弟穆等结谋攻许,杀曹公长史王必,南援刘备。后必营,必与典农中郎将严匡讨斩之。在《三国演义》中,吉本在此为吉平或吉太,因字称平,故又唤作吉平。曾参与董承等人刺杀曹操的计划,并企图在为曹操治病时毒死曹操,但被曹操识破而遭处刑。之后其子吉邈和吉穆都参与了由耿纪和韦晃等人所发动的反叛曹操的行动,但都失败被杀。', - xiaoyuehankehan:'小约翰可汗,知乎答主,bilibili知识区up主,其视频以介绍冷门国家和名人为主,因其视频极具特色的幽默风格而知名。代表作包括《奇葩小国》系列和《硬核狠人》系列。昵称里的“小约翰”来源于《纸牌屋》里的主角弗朗西斯·厄克特的外号Little John。家乡在内蒙古通辽市,在《奇葩小国》系列视频中,介绍小国面积和人口时,常用通辽市的面积和人口作为计量单位,后简化为T。1T=6万平方公里或287万人(如:阿富汗面积约为64万平方公里,超过10T)。此梗成为该系列视频的特色之一,可汗也因此被称为“通辽可汗”。', - zhutiexiong:'朱铁雄,福建莆田人,1994年出生,短视频创作者。中国魔法少年的英雄梦,国风变装的热血与浪漫。抖音年度高光时刻作者,国风变装现象级人物。创玩节期间化身三国杀武将,来一场热血变身!', - nezha:'哪吒是中国神话中的民俗神之一,在古典名著《西游记》《封神演义》等及其衍生作品中也多有登场。传说中,哪吒是托塔天王李靖的第三子。哪吒之母怀胎三年,而哪吒出生之时是一个肉球,李靖惊怒之下,用剑劈开了肉球,而哪吒就在肉球中。哪吒广泛流传于道教以及民间传说中,被称为三坛海会大神、威灵显圣大将军、中坛元帅等,民间俗称“三太子”,又常冠其父姓,称为“李哪吒”。哪吒的原型为佛教护法神“那咤”。在不同作品的设定中,哪吒的师承关系有所不同,比如《封神演义》中,哪吒是太乙真人的弟子、元始天尊的徒孙,而《西游记》之中,哪吒则是释迦牟尼(如来佛祖)的弟子。在传说中,哪吒的形象常被形容为可化作三头六臂(封神之中是三头八臂),使用多种武器战斗。比如,《封神演义》中哪吒使用的武器(法宝)为乾坤圈、混天绫、火尖枪和风火轮等,西游记中是斩妖剑、砍妖刀、缚妖索、降妖杵、绣球儿、火轮儿。而哪吒第一次死后被其师父(太乙真人或如来佛祖)以莲花和莲藕复活。', - }, - card:{ - ruyijingubang:{ - fullskin:true, - derivation:'sunwukong', - type:'equip', - subtype:'equip1', - skills:['ruyijingubang_skill','ruyijingubang_effect'], - equipDelay:false, - distance:{ - attackFrom:-2, - attackRange:(card,player)=>{ - return (player.storage.ruyijingubang_skill||3); - } - }, - onEquip(){ - if(!card.storage.ruyijingubang_skill) card.storage.ruyijingubang_skill=3; - player.storage.ruyijingubang_skill=card.storage.ruyijingubang_skill; - player.markSkill('ruyijingubang_skill'); + content() { + game.broadcastAll( + function (player, target, shown) { + var identity = player.identity; + player.identity = target.identity; + if (shown || player == game.me) { + player.setIdentity(); + } + target.identity = identity; + }, + player, + trigger.player, + trigger.player.identityShown + ); + player.line(trigger.player, "green"); + player.storage.fenxin = true; + player.awakenSkill("fenxin_old"); }, }, }, - dynamicTranslate:{ - dcjianxiong(player){ - return '当你受到伤害后,你可以摸'+get.cnNumber(player.countMark('dcjianxiong')+1)+'张牌并获得对你造成伤害的牌,然后你令此技能摸牌数+1(至多为5)。'; + characterIntro: { + sunwukong: + "孙悟空是中国古典小说《西游记》的主人公,也是中国神话中的民俗神祇之一,明代百回本《西游记》书中最为深入人心的形象之一。《西游记》中的孙悟空本是天地生成的一个石猴,率领群猴在花果山水帘洞过着逍遥自在的日子,后来为学习长生的法术而拜菩提祖师为师,学会了七十二变和筋斗云等绝技。后来他前往东海龙宫夺取如意金箍棒,又大闹地府勾了生死簿,惊动天庭,天庭两次派兵征讨花果山,仍然降他不得,只好请西天如来佛祖前来助阵。如来佛祖以五行山将悟空压在山下五百年。五百年后,悟空在观音菩萨的指点下拜唐僧为师,并跟随唐僧前往西天求取真经。路上唐僧又收了猪八戒、沙和尚两个徒弟,众人在途中斩妖除魔、历经磨难,终于取得真经,修成正果。", + longwang: + "东海龙王,名敖广,是中国古代神话传说中的龙族之王,为“四海龙王”之首,亦为所有水族之王。统治东海之洋,主宰着雨水、雷鸣、洪灾、海潮、海啸等。曾下陷东京、水淹陈塘关(影视设定)。在中国以东方为尊位,按周易来说东为阳,故此东海龙王排第一便是理所应当。常记载于《西游记》《封神演义》《三教搜神大全》等文学典籍。东海龙王居于东海的海底水晶宫(花果山瀑布顺流可直抵龙宫)。虽为司雨之神,但其保持着较大的特殊自由性,人间降雨由其它江河湖井龙王完成,很少需要东海龙王亲自降雨。海洋管辖之权为龙王所有,天庭一般任其自治。", + taoshen: + "涛神,是司掌钱塘江的神,传说其原型为春秋战国时期的吴国大臣伍子胥。伍子胥从楚国投奔吴国,为吴国立下了汗马功劳;但吴王夫差听信太宰伯嚭的谗言,逐渐疏远了伍子胥,最后还赐死了他。伍子胥含冤身亡,十分悲愤,做出了吴国灭亡的预言后自杀。暴怒的夫差下令用皮革包裹住伍子胥的尸身,在五月五日这天丢进钱塘江。百姓可怜伍子胥忠于吴王却遭受惨死,因此将五月五日这一天定为节日,以此纪念伍子胥,这也是端午节的来历之一。", + libai: "李白(701年2月28日—762年12月),字太白,号青莲居士,祖籍陇西成纪(今甘肃省秦安县),出生于蜀郡绵州昌隆县(一说出生于西域碎叶)。唐朝伟大的浪漫主义诗人,凉武昭王李暠九世孙。
              为人爽朗大方,乐于交友,爱好饮酒作诗,名列“酒中八仙”。曾经得到唐玄宗李隆基赏识,担任翰林学士,赐金放还,游历全国,先后迎娶宰相许圉师、宗楚客的孙女。唐肃宗即位后,卷入永王之乱,流放夜郎,辗转到达当涂县令李阳冰家。上元二年,去世,时年六十二。
              著有《李太白集》,代表作有《望庐山瀑布》《行路难》《蜀道难》《将进酒》《早发白帝城》等。李白所作词赋,就其开创意义及艺术成就而言,享有极为崇高的地位,后世誉为“诗仙”,与诗圣杜甫并称“李杜”。", + sunyang: + "孙杨,1991年12月1日生于浙江杭州,男子1500米自由泳世界纪录保持者,男子400米自由泳奥运会纪录保持者。年伦敦奥运会男子400米自由泳、男子1500米自由泳冠军;2016年里约奥运会男子200米自由泳冠军。孙杨是世界泳坛历史上唯一一位男子200米自由泳、男子400米自由泳、男子1500米自由泳的奥运会世锦赛大满贯冠军得主,史上唯一一位男子400米自由泳世锦赛四连冠,唯一一位男子800米自由泳世锦赛三连冠,男子自由泳个人单项金牌数居世界第一。", + yeshiwen: + "叶诗文,1996年3月1日生于浙江省杭州市,中国女子游泳队运动员,女子200米混合泳奥运会纪录保持者。叶诗文是中国泳坛首位集奥运会、长池世锦赛、短池世锦赛、游泳世界杯、亚运会、全运会冠军于一身的运动员,成为中国泳坛首个金满贯。2010年广州亚运会女子200米和400米个人混合泳冠军。2011年上海世界游泳锦标赛女子200米混合泳冠军。2012年伦敦奥运会女子200米混合泳、400米混合泳冠军。2012年伊斯坦布尔短池世锦赛女子200米混合泳冠军。2013年辽宁全运会女子200米、400米混合泳冠军。2016年里约奥运会女子200米混合泳第八名。2017年天津全运会女子200米混合泳冠军。2019年光州世界游泳锦标赛女子200米混合泳亚军、女子400米混合泳亚军。2018年1月30日,当选为浙江省出席第十三届全国人民代表大会代表。2019年7月28日,2019年韩国光州游泳世锦赛,叶诗文以4分32秒07获得亚军。2021年9月19日,叶诗文获得第十四届全国运动会游泳女子4×200米混合泳接力金牌。9月22日,叶诗文获得全运会女子200米个人混合泳银牌。", + jiben: "吉本(?—218年),东汉末年太医令。建安二十三年春正月,时金祎自以世为汉臣,睹汉祚将移,谓可季兴,乃喟然发愤,遂与太医令本、少府耿纪、司直韦晃、本子邈、邈弟穆等结谋攻许,杀曹公长史王必,南援刘备。后必营,必与典农中郎将严匡讨斩之。在《三国演义》中,吉本在此为吉平或吉太,因字称平,故又唤作吉平。曾参与董承等人刺杀曹操的计划,并企图在为曹操治病时毒死曹操,但被曹操识破而遭处刑。之后其子吉邈和吉穆都参与了由耿纪和韦晃等人所发动的反叛曹操的行动,但都失败被杀。", + xiaoyuehankehan: + '小约翰可汗,知乎答主,bilibili知识区up主,其视频以介绍冷门国家和名人为主,因其视频极具特色的幽默风格而知名。代表作包括《奇葩小国》系列和《硬核狠人》系列。昵称里的“小约翰”来源于《纸牌屋》里的主角弗朗西斯·厄克特的外号Little John。家乡在内蒙古通辽市,在《奇葩小国》系列视频中,介绍小国面积和人口时,常用通辽市的面积和人口作为计量单位,后简化为T。1T=6万平方公里或287万人(如:阿富汗面积约为64万平方公里,超过10T)。此梗成为该系列视频的特色之一,可汗也因此被称为“通辽可汗”。', + zhutiexiong: + "朱铁雄,福建莆田人,1994年出生,短视频创作者。中国魔法少年的英雄梦,国风变装的热血与浪漫。抖音年度高光时刻作者,国风变装现象级人物。创玩节期间化身三国杀武将,来一场热血变身!", + nezha: "哪吒是中国神话中的民俗神之一,在古典名著《西游记》《封神演义》等及其衍生作品中也多有登场。传说中,哪吒是托塔天王李靖的第三子。哪吒之母怀胎三年,而哪吒出生之时是一个肉球,李靖惊怒之下,用剑劈开了肉球,而哪吒就在肉球中。哪吒广泛流传于道教以及民间传说中,被称为三坛海会大神、威灵显圣大将军、中坛元帅等,民间俗称“三太子”,又常冠其父姓,称为“李哪吒”。哪吒的原型为佛教护法神“那咤”。在不同作品的设定中,哪吒的师承关系有所不同,比如《封神演义》中,哪吒是太乙真人的弟子、元始天尊的徒孙,而《西游记》之中,哪吒则是释迦牟尼(如来佛祖)的弟子。在传说中,哪吒的形象常被形容为可化作三头六臂(封神之中是三头八臂),使用多种武器战斗。比如,《封神演义》中哪吒使用的武器(法宝)为乾坤圈、混天绫、火尖枪和风火轮等,西游记中是斩妖剑、砍妖刀、缚妖索、降妖杵、绣球儿、火轮儿。而哪吒第一次死后被其师父(太乙真人或如来佛祖)以莲花和莲藕复活。", + }, + card: { + ruyijingubang: { + fullskin: true, + derivation: "sunwukong", + type: "equip", + subtype: "equip1", + skills: ["ruyijingubang_skill", "ruyijingubang_effect"], + equipDelay: false, + distance: { + attackFrom: -2, + attackRange: (card, player) => { + return player.storage.ruyijingubang_skill || 3; + }, + }, + onEquip() { + if (!card.storage.ruyijingubang_skill) card.storage.ruyijingubang_skill = 3; + player.storage.ruyijingubang_skill = card.storage.ruyijingubang_skill; + player.markSkill("ruyijingubang_skill"); + }, }, }, - translate:{ - old_lingju:'SP灵雎', - old_lingju_prefix:'SP', - fenxin_old:'焚心', - fenxin_old_info:'限定技,当你杀死一名非主公角色时,你可以与其交换未翻开的身份牌。(你的身份为主公时不能发动此技能)', - sp_fuwan:'SP伏完', - sp_fuwan_prefix:'SP', - spfengyin:'奉印', - spfengyin_info:'其他角色的回合开始时,若其体力值不少于你,你可以交给其一张【杀】,令其跳过出牌阶段和弃牌阶段。', - spchizhong:'持重', - spchizhong_info:'锁定技,你的手牌上限等于体力上限;其他角色死亡时,你加1点体力上限。', - sp_fuhuanghou:'SP伏寿', - sp_fuhuanghou_prefix:'SP', - spcangni:'藏匿', - spcangni_info:'弃牌阶段开始时,你可以回复1点体力或摸两张牌,然后将你的武将牌翻面;其他角色的回合内,当你获得(每回合限一次)/失去一次牌时,若你的武将牌背面朝上,你可以令该角色摸/弃置一张牌。', - spmixin:'密信', - spmixin_info:'出牌阶段限一次,你可以将一张手牌交给一名其他角色,该角色须对你选择的另一名角色使用一张无距离限制的【杀】,否则你选择的角色观看其手牌并获得其中一张。', - sp_jiben:'SP吉本', - sp_jiben_prefix:'SP', - spduanzhi:'断指', - spduanzhi_info:'当你成为其他角色使用的牌的目标后,你可以弃置其至多两张牌,然后失去1点体力。', - spduyi:'毒医', - spduyi2:'毒医', - spduyi_info:'出牌阶段限一次,你可以亮出牌堆顶的一张牌并交给一名角色,若此牌为黑色,该角色不能使用或打出手牌,直到回到结束。', - sp_mushun:'SP穆顺', - sp_mushun_prefix:'SP', - libai:'李白', - dclbjiuxian:'酒仙', - dclbjiuxian_info:'①你可以将额定目标数大于1的锦囊牌当做【酒】使用。②你使用【酒】无次数限制。', - dcshixian:'诗仙', - dcshixian_yayun:'押韵', - dcshixian_info:'当你使用一张牌时,若此牌的牌名与你于本局游戏使用的上一张牌的牌名押韵,则你可以摸一张牌,并令此牌额外结算一次。', - taoshen:'涛神', - dcnutao:'怒涛', - dcnutao_info:'锁定技。①当你使用锦囊牌指定第一个目标时,若目标角色包含其他角色,你随机对其中一名其他目标角色造成1点雷电伤害。②当你于出牌阶段造成雷电伤害后,你于此阶段使用【杀】的次数上限+1。', - sunwukong:'孙悟空', - dcjinjing:'金睛', - dcjinjing_info:'锁定技。其他角色的手牌对你可见。', - dccibei:'慈悲', - dccibei_info:'每回合每名角色限一次。当你对其他角色造成伤害时,你可以防止此伤害,然后摸五张牌。', - dcruyi:'如意', - dcruyi_info:'锁定技。①游戏开始时,你将【如意金箍棒】置入装备区。②你手牌区内的武器牌均视为【杀】,且你不是武器牌的合法目标。③当你即将失去【如意金箍棒】或即将废除武器栏时,取消之。④你不能将装备区内的【如意金箍棒】当做其他牌使用或打出。', - ruyijingubang:'如意金箍棒', + dynamicTranslate: { + dcjianxiong(player) { + return ( + "当你受到伤害后,你可以摸" + + get.cnNumber(player.countMark("dcjianxiong") + 1) + + "张牌并获得对你造成伤害的牌,然后你令此技能摸牌数+1(至多为5)。" + ); + }, + }, + translate: { + old_lingju: "SP灵雎", + old_lingju_prefix: "SP", + fenxin_old: "焚心", + fenxin_old_info: + "限定技,当你杀死一名非主公角色时,你可以与其交换未翻开的身份牌。(你的身份为主公时不能发动此技能)", + sp_fuwan: "SP伏完", + sp_fuwan_prefix: "SP", + spfengyin: "奉印", + spfengyin_info: + "其他角色的回合开始时,若其体力值不少于你,你可以交给其一张【杀】,令其跳过出牌阶段和弃牌阶段。", + spchizhong: "持重", + spchizhong_info: "锁定技,你的手牌上限等于体力上限;其他角色死亡时,你加1点体力上限。", + sp_fuhuanghou: "SP伏寿", + sp_fuhuanghou_prefix: "SP", + spcangni: "藏匿", + spcangni_info: + "弃牌阶段开始时,你可以回复1点体力或摸两张牌,然后将你的武将牌翻面;其他角色的回合内,当你获得(每回合限一次)/失去一次牌时,若你的武将牌背面朝上,你可以令该角色摸/弃置一张牌。", + spmixin: "密信", + spmixin_info: + "出牌阶段限一次,你可以将一张手牌交给一名其他角色,该角色须对你选择的另一名角色使用一张无距离限制的【杀】,否则你选择的角色观看其手牌并获得其中一张。", + sp_jiben: "SP吉本", + sp_jiben_prefix: "SP", + spduanzhi: "断指", + spduanzhi_info: "当你成为其他角色使用的牌的目标后,你可以弃置其至多两张牌,然后失去1点体力。", + spduyi: "毒医", + spduyi2: "毒医", + spduyi_info: + "出牌阶段限一次,你可以亮出牌堆顶的一张牌并交给一名角色,若此牌为黑色,该角色不能使用或打出手牌,直到回到结束。", + sp_mushun: "SP穆顺", + sp_mushun_prefix: "SP", + libai: "李白", + dclbjiuxian: "酒仙", + dclbjiuxian_info: "①你可以将额定目标数大于1的锦囊牌当做【酒】使用。②你使用【酒】无次数限制。", + dcshixian: "诗仙", + dcshixian_yayun: "押韵", + dcshixian_info: + "当你使用一张牌时,若此牌的牌名与你于本局游戏使用的上一张牌的牌名押韵,则你可以摸一张牌,并令此牌额外结算一次。", + taoshen: "涛神", + dcnutao: "怒涛", + dcnutao_info: + "锁定技。①当你使用锦囊牌指定第一个目标时,若目标角色包含其他角色,你随机对其中一名其他目标角色造成1点雷电伤害。②当你于出牌阶段造成雷电伤害后,你于此阶段使用【杀】的次数上限+1。", + sunwukong: "孙悟空", + dcjinjing: "金睛", + dcjinjing_info: "锁定技。其他角色的手牌对你可见。", + dccibei: "慈悲", + dccibei_info: "每回合每名角色限一次。当你对其他角色造成伤害时,你可以防止此伤害,然后摸五张牌。", + dcruyi: "如意", + dcruyi_info: + "锁定技。①游戏开始时,你将【如意金箍棒】置入装备区。②你手牌区内的武器牌均视为【杀】,且你不是武器牌的合法目标。③当你即将失去【如意金箍棒】或即将废除武器栏时,取消之。④你不能将装备区内的【如意金箍棒】当做其他牌使用或打出。", + ruyijingubang: "如意金箍棒", // ruyijingubang_skill:'如意', - ruyijingubang_skill:'如意金箍棒', - ruyijingubang_effect:'如意金箍棒', - ruyijingubang_info:'出牌阶段限一次。你可以将此牌的实际攻击范围调整为1~4内的任意整数。你根据此牌的实际攻击范围拥有对应的效果:
            • ⑴你使用【杀】无次数限制。
            • ⑵你使用的【杀】伤害+1。
            • ⑶你使用的【杀】不可被响应。
            • ⑷你使用【杀】选择目标后,可以增加一个额外目标。', - longwang:'龙王', - dclonggong:'龙宫', - dclonggong_info:'每回合限一次。当你受到伤害时,你可以防止此伤害,然后令伤害来源从牌堆中获得一张装备牌。', - dcsitian:'司天', - dcsitian_info:'出牌阶段,你可以弃置两张颜色不同的手牌。系统从所有天气中随机选择两个,你观看这些天气并选择一个执行。
            • 烈日:你对其他角色依次造成1点火属性伤害。
            • 雷电:你令其他角色各进行一次判定。若结果为♠2~9,则其受到3点无来源雷属性伤害。
            • 大浪:你弃置其他角色装备区内的所有牌(装备区内没有牌的角色改为失去1点体力)。
            • 暴雨:你弃置一名角色的所有手牌。若其没有手牌,则改为令其失去1点体力。
            • 大雾:你令所有其他角色获得如下效果:当其使用下一张锦囊牌时,取消之。', - sunyang:'孙杨', - clbshuijian:'水箭', - clbshuijian_info:'摸牌阶段开始时,你可以令额定摸牌数+X(X为你装备区内牌数的一半+1,且向下取整)。', - yeshiwen:'叶诗文', - clbjisu:'急速', - clbjisu_info:'判定阶段开始前,你可以跳过本回合的判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】。', - clbshuiyong:'水泳', - clbshuiyong_info:'锁定技。当你受到火属性伤害时,取消之。', - xiaoyuehankehan:'小约翰可汗', - dctongliao:'通辽', - dctongliao_info:'①摸牌阶段结束时,你可以选择一张点数最小的手牌,将此牌标记为“通辽”。②当你失去一张具有“通辽”标签的牌时,你摸X张牌(X为此牌点数)。', - dcwudao:'悟道', - dcwudao_info:'当你使用牌结算结束后,若你使用的上一张牌与此牌类型相同,则你可以于本回合内获得如下效果:当你于回合内使用该类型的牌时,你令此牌不可被响应且伤害值基数+1。', - zhutiexiong:'朱铁雄', - wu_zhutiexiong:'朱铁雄', - dcbianzhuang:'变装', - dcbianzhuang_info:'①出牌阶段限一次,你可以从系统随机选择的两个技能中获得一个,并视为使用一张【杀】(无距离次数限制),然后失去以此法获得的技能。②当你使用装备牌后,你清空此技能的发动次数记录。③当你发动〖变装①〗后,若你发动〖变装①〗的次数大于2,则你将武将牌变更为诸葛亮,并将系统选择的技能数改为三个。', - dc_caocao:'经典曹操', - dc_caocao_prefix:'经典', - dcjianxiong:'奸雄', - dcjianxiong_info:'当你受到伤害后,你可以摸一张牌并获得对你造成伤害的牌,然后你令此技能摸牌数+1(至多为5)。', - dc_liubei:'经典刘备', - dc_liubei_prefix:'经典', - dcrende:'仁德', - dcrende_info:'出牌阶段每名角色限一次。你可以获得一名其他角色两张手牌,然后视为使用一张基本牌。', - dc_sunquan:'经典孙权', - dc_sunquan_prefix:'经典', - dczhiheng:'制衡', - dczhiheng_info:'①出牌阶段限一次。你可以弃置任意张牌并摸等量的牌,若你在发动〖制衡〗时弃置了所有手牌,则你多摸一张牌。②每回合每名角色限一次。当你对其他角色造成伤害后,你令〖制衡①〗于此回合发动次数上限+1。', - nezha:'哪吒', - dcsantou:'三头', - dcsantou_info:'锁定技,当你受到伤害时,防止之,然后若以下有条件成立,你失去1点体力:1.你于本回合此前以此法防止过该伤害来源的伤害,且你的体力值不小于3;2.本次伤害为属性伤害,且你的体力值为2;3.本次伤害的渠道为红色的牌,且你的体力值为1。', - dcfaqi:'法器', - dcfaqi_info:'当你于出牌阶段使用装备牌结算结束后,你视为使用一张本回合未以此法使用过的普通锦囊牌。', - dc_sunce:'经典孙策', - dc_sunce_prefix:'经典', - dcshuangbi:'双壁', - dcshuangbi_info:'出牌阶段限一次,你可以选择一项:①摸X张牌,本回合手牌上限+X;②弃置至多X张牌,随机对其他角色造成等量火焰伤害;③视为使用X张火【杀】或【火攻】。(X为场上存活角色数)', - dc_zhaoyun:'经典神赵云', - dc_zhaoyun_prefix:'经典神', - dclonghun:'龙魂', - dclonghun_info:'每回合限20次,你可以将你的牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当【无懈可击】。', - dczhanjiang:'斩将', - dczhanjiang_info:'准备阶段,若场上有【青釭剑】,则你可以获得之。', + ruyijingubang_skill: "如意金箍棒", + ruyijingubang_effect: "如意金箍棒", + ruyijingubang_info: + "出牌阶段限一次。你可以将此牌的实际攻击范围调整为1~4内的任意整数。你根据此牌的实际攻击范围拥有对应的效果:
            • ⑴你使用【杀】无次数限制。
            • ⑵你使用的【杀】伤害+1。
            • ⑶你使用的【杀】不可被响应。
            • ⑷你使用【杀】选择目标后,可以增加一个额外目标。", + longwang: "龙王", + dclonggong: "龙宫", + dclonggong_info: + "每回合限一次。当你受到伤害时,你可以防止此伤害,然后令伤害来源从牌堆中获得一张装备牌。", + dcsitian: "司天", + dcsitian_info: + "出牌阶段,你可以弃置两张颜色不同的手牌。系统从所有天气中随机选择两个,你观看这些天气并选择一个执行。
            • 烈日:你对其他角色依次造成1点火属性伤害。
            • 雷电:你令其他角色各进行一次判定。若结果为♠2~9,则其受到3点无来源雷属性伤害。
            • 大浪:你弃置其他角色装备区内的所有牌(装备区内没有牌的角色改为失去1点体力)。
            • 暴雨:你弃置一名角色的所有手牌。若其没有手牌,则改为令其失去1点体力。
            • 大雾:你令所有其他角色获得如下效果:当其使用下一张基本牌时,取消之。", + sunyang: "孙杨", + clbshuijian: "水箭", + clbshuijian_info: + "摸牌阶段开始时,你可以令额定摸牌数+X(X为你装备区内牌数的一半+1,且向下取整)。", + yeshiwen: "叶诗文", + clbjisu: "急速", + clbjisu_info: + "判定阶段开始前,你可以跳过本回合的判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】。", + clbshuiyong: "水泳", + clbshuiyong_info: "锁定技。当你受到火属性伤害时,取消之。", + xiaoyuehankehan: "小约翰可汗", + dctongliao: "通辽", + dctongliao_info: + "①摸牌阶段结束时,你可以选择一张点数最小的手牌,将此牌标记为“通辽”。②当你失去一张具有“通辽”标签的牌时,你摸X张牌(X为此牌点数)。", + dcwudao: "悟道", + dcwudao_info: + "当你使用牌结算结束后,若你使用的上一张牌与此牌类型相同,则你可以于本回合内获得如下效果:当你于回合内使用该类型的牌时,你令此牌不可被响应且伤害值基数+1。", + zhutiexiong: "朱铁雄", + wu_zhutiexiong: "朱铁雄", + dcbianzhuang: "变装", + dcbianzhuang_info: + "①出牌阶段限一次,你可以从系统随机选择的两个技能中获得一个,并视为使用一张【杀】(无距离次数限制),然后失去以此法获得的技能。②当你使用装备牌后,你清空此技能的发动次数记录。③当你发动〖变装①〗后,若你发动〖变装①〗的次数大于2,则你将武将牌变更为诸葛亮,并将系统选择的技能数改为三个。", + dc_caocao: "经典曹操", + dc_caocao_prefix: "经典", + dcjianxiong: "奸雄", + dcjianxiong_info: + "当你受到伤害后,你可以摸一张牌并获得对你造成伤害的牌,然后你令此技能摸牌数+1(至多为5)。", + dc_liubei: "经典刘备", + dc_liubei_prefix: "经典", + dcrende: "仁德", + dcrende_info: "出牌阶段每名角色限一次。你可以获得一名其他角色两张手牌,然后视为使用一张基本牌。", + dc_sunquan: "经典孙权", + dc_sunquan_prefix: "经典", + dczhiheng: "制衡", + dczhiheng_info: + "①出牌阶段限一次。你可以弃置任意张牌并摸等量的牌,若你在发动〖制衡〗时弃置了所有手牌,则你多摸一张牌。②每回合每名角色限一次。当你对其他角色造成伤害后,你令〖制衡①〗于此回合发动次数上限+1。", + nezha: "哪吒", + dcsantou: "三头", + dcsantou_info: + "锁定技,当你受到伤害时,防止之,然后若以下有条件成立,你失去1点体力:1.你于本回合此前以此法防止过该伤害来源的伤害,且你的体力值不小于3;2.本次伤害为属性伤害,且你的体力值为2;3.本次伤害的渠道为红色的牌,且你的体力值为1。", + dcfaqi: "法器", + dcfaqi_info: + "当你于出牌阶段使用装备牌结算结束后,你视为使用一张本回合未以此法使用过的普通锦囊牌。", + dc_sunce: "经典孙策", + dc_sunce_prefix: "经典", + dcshuangbi: "双壁", + dcshuangbi_info: + "出牌阶段限一次,你可以选择一项:①摸X张牌,本回合手牌上限+X;②弃置至多X张牌,随机对其他角色造成等量火焰伤害;③视为使用X张火【杀】或【火攻】。(X为场上存活角色数)", + dc_zhaoyun: "经典神赵云", + dc_zhaoyun_prefix: "经典神", + dclonghun: "龙魂", + dclonghun_info: + "每回合限20次,你可以将你的牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当【无懈可击】。", + dczhanjiang: "斩将", + dczhanjiang_info: "准备阶段,若场上有【青釭剑】,则你可以获得之。", - collab_olympic:'OL·伦敦奥运会', - collab_tongque:'OL·铜雀台', - collab_duanwu:'新服·端午畅玩', - collab_decade:'新服·创玩节', - collab_remake:'新服·共创武将', + collab_olympic: "OL·伦敦奥运会", + collab_tongque: "OL·铜雀台", + collab_duanwu: "新服·端午畅玩", + collab_decade: "新服·创玩节", + collab_remake: "新服·共创武将", }, }; }); diff --git a/character/ddd.js b/character/ddd.js index 493032017..adaa7e8ba 100644 --- a/character/ddd.js +++ b/character/ddd.js @@ -1,764 +1,901 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'ddd', - connect:true, - character:{ - ddd_handang:["male","wu",4,["dddxianxi"]], + name: "ddd", + connect: true, + character: { + ddd_handang: ["male", "wu", 4, ["dddxianxi"]], // ddd_wuzhi:["male","wei",3,["dddlingyong","dddxuxiao"]], - ddd_xujing:["male","shu",3,["dddxuyu","dddshijian"]], + ddd_xujing: ["male", "shu", 3, ["dddxuyu", "dddshijian"]], // ddd_caomao:["male","wei",3,["dddtaisi","dddquche","dddqianlong"],["zhu"]], // ddd_xinxianying:["female","wei",3,["ddddongcha","dddzhijie"]], - ddd_xianglang:["male","shu",3,["dddqiahua","dddfusi","dddtuoji"]], - ddd_yujin:['male','wei',4,['dddzhengjun']], - ddd_liuye:['male','wei',3,['dddchashi','dddqice']], - ddd_baosanniang:['female','shu',3,['dddzhilian','dddjijian']], + ddd_xianglang: ["male", "shu", 3, ["dddqiahua", "dddfusi", "dddtuoji"]], + ddd_yujin: ["male", "wei", 4, ["dddzhengjun"]], + ddd_liuye: ["male", "wei", 3, ["dddchashi", "dddqice"]], + ddd_baosanniang: ["female", "shu", 3, ["dddzhilian", "dddjijian"]], // ddd_zhenji:['female','wei',3,['dddmiaoxing','dddfushi']], - ddd_zhaoang:['male','wei',4,['dddfenji']], - ddd_zhouchu:['male','wu',5,['dddxiaheng']], - ddd_liuba:['male','shu',3,['dddfengzheng','dddyulv']], - ddd_jianshuo:['male','qun',4,['dddfenye','dddshichao']], - ddd_guanning:['male','qun',3,['dddyouxue','dddchengjing']], - ddd_dingfeng:['male','wu',4,['dddduanbing']], - ddd_caoshuang:['male','wei',5,['dddzhuanshe','dddweiqiu']], - ddd_xuelingyun:['female','wei',3,['dddlianer','dddanzhi']], - ddd_liuhong:['male','qun',4,['dddshixing','ddddanggu','dddfuzong'],['zhu']], - ddd_xiahouxuan:['male','wei',3,['dddlanghuai','dddxuanlun']], - ddd_zhangkai:['male','qun','3/4',['dddjiexing','dddbailei']], - ddd_liangxi:['male','wei',4,['dddtongyu']], - ddd_wangkanglvkai:['male','shu',4,['dddbingjian']], + ddd_zhaoang: ["male", "wei", 4, ["dddfenji"]], + ddd_zhouchu: ["male", "wu", 5, ["dddxiaheng"]], + ddd_liuba: ["male", "shu", 3, ["dddfengzheng", "dddyulv"]], + ddd_jianshuo: ["male", "qun", 4, ["dddfenye", "dddshichao"]], + ddd_guanning: ["male", "qun", 3, ["dddyouxue", "dddchengjing"]], + ddd_dingfeng: ["male", "wu", 4, ["dddduanbing"]], + ddd_caoshuang: ["male", "wei", 5, ["dddzhuanshe", "dddweiqiu"]], + ddd_xuelingyun: ["female", "wei", 3, ["dddlianer", "dddanzhi"]], + ddd_liuhong: ["male", "qun", 4, ["dddshixing", "ddddanggu", "dddfuzong"], ["zhu"]], + ddd_xiahouxuan: ["male", "wei", 3, ["dddlanghuai", "dddxuanlun"]], + ddd_zhangkai: ["male", "qun", "3/4", ["dddjiexing", "dddbailei"]], + ddd_liangxi: ["male", "wei", 4, ["dddtongyu"]], + ddd_wangkanglvkai: ["male", "shu", 4, ["dddbingjian"]], // ddd_sunliang:['male','wu',3,['ddddiedang','dddanliu','dddguiying'],['zhu']], - ddd_lie:['female','wu',3,['dddyeshen','dddqiaoduan']], - ddd_kebineng:['male','qun',4,['dddxiaoxing','dddlangzhi','dddfuyi'],['zhu']], - ddd_qianzhao:['male','wei',4,['dddyuanzhen','dddzhishu']], - ddd_zhangmiao:['male','qun',4,['dddxiaxing']], - ddd_zhangcheng:['male','wu',3,['dddjuxian','dddjungui']], - ddd_liuchong:['male','qun',4,['dddjinggou','dddmoyan']], - ddd_luoxian:['male','shu',4,['dddshilie']], + ddd_lie: ["female", "wu", 3, ["dddyeshen", "dddqiaoduan"]], + ddd_kebineng: ["male", "qun", 4, ["dddxiaoxing", "dddlangzhi", "dddfuyi"], ["zhu"]], + ddd_qianzhao: ["male", "wei", 4, ["dddyuanzhen", "dddzhishu"]], + ddd_zhangmiao: ["male", "qun", 4, ["dddxiaxing"]], + ddd_zhangcheng: ["male", "wu", 3, ["dddjuxian", "dddjungui"]], + ddd_liuchong: ["male", "qun", 4, ["dddjinggou", "dddmoyan"]], + ddd_luoxian: ["male", "shu", 4, ["dddshilie"]], }, - characterFilter:{}, - characterSort:{}, - characterTitle:{ - ddd_handang:'#g晓ャ绝对', - ddd_wuzhi:'#g沸治·克里夫', - ddd_xujing:'#g沸治·克里夫', - ddd_caomao:'#gRocxu', - ddd_xinxianying:'#g好孩子系我', - ddd_xianglang:'#g会乱武的袁绍', - ddd_liuye:'#g好孩子系我', - ddd_baosanniang:'#g会乱武的袁绍', - ddd_wangkanglvkai:'#g扬林', - ddd_yujin:'#g虎鲸', - ddd_caoshuang:'#g辰木', - ddd_zhenji:'#g巴德', - ddd_zhaoang:'#g君腾天下', - ddd_xuelingyun:'#gGENTOVA07', - ddd_liuhong:'#g拉普拉斯', - ddd_xiahouxuan:'#g好孩子系我', - ddd_zhouchu:'#g志文', - ddd_kebineng:'#g晨星', - ddd_zhangkai:'#g拼音', - ddd_liuba:'#g浅水', - ddd_jianshuo:'#g浅水', - ddd_guanning:'#g虎鲸', - ddd_lie:'#gyyuaN', - ddd_liangxi:'#g先負', + characterFilter: {}, + characterSort: {}, + characterTitle: { + ddd_handang: "#g晓ャ绝对", + ddd_wuzhi: "#g沸治·克里夫", + ddd_xujing: "#g沸治·克里夫", + ddd_caomao: "#gRocxu", + ddd_xinxianying: "#g好孩子系我", + ddd_xianglang: "#g会乱武的袁绍", + ddd_liuye: "#g好孩子系我", + ddd_baosanniang: "#g会乱武的袁绍", + ddd_wangkanglvkai: "#g扬林", + ddd_yujin: "#g虎鲸", + ddd_caoshuang: "#g辰木", + ddd_zhenji: "#g巴德", + ddd_zhaoang: "#g君腾天下", + ddd_xuelingyun: "#gGENTOVA07", + ddd_liuhong: "#g拉普拉斯", + ddd_xiahouxuan: "#g好孩子系我", + ddd_zhouchu: "#g志文", + ddd_kebineng: "#g晨星", + ddd_zhangkai: "#g拼音", + ddd_liuba: "#g浅水", + ddd_jianshuo: "#g浅水", + ddd_guanning: "#g虎鲸", + ddd_lie: "#gyyuaN", + ddd_liangxi: "#g先負", // ddd_liuchong:'#g', - ddd_luoxian:'#g绝代倾国倾城貌', + ddd_luoxian: "#g绝代倾国倾城貌", }, /** @type { importCharacterConfig['skill'] } */ - skill:{ + skill: { //牵招 - dddyuanzhen:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - forced:true, - filter(event,player){ - return event.target!=player&&get.distance(player,event.target)!=1&&event.isFirstTarget&&event.targets.length==1; + dddyuanzhen: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + forced: true, + filter(event, player) { + return ( + event.target != player && + get.distance(player, event.target) != 1 && + event.isFirstTarget && + event.targets.length == 1 + ); }, - logTarget:'target', - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.target; + logTarget: "target", + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.target; let result; game.delayex(); - if(!target.countCards('he')) result={bool:false}; - else result=yield target.chooseToDiscard('he',`${get.translation(player)}对你使用了【远振】`,'请弃置一张牌,或点击“取消”令其摸一张牌').set('ai',card=>{ - if(get.event('goon')) return 4.5-get.value(card); - }).set('goon',get.attitude(target,player)>0); - if(!result.bool){ + if (!target.countCards("he")) result = { bool: false }; + else + result = yield target + .chooseToDiscard( + "he", + `${get.translation(player)}对你使用了【远振】`, + "请弃置一张牌,或点击“取消”令其摸一张牌" + ) + .set("ai", (card) => { + if (get.event("goon")) return 4.5 - get.value(card); + }) + .set("goon", get.attitude(target, player) > 0); + if (!result.bool) { target.line(player); player.draw(); } }, }, - dddzhishu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return player.canMoveCard(null,true); + dddzhishu: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return player.canMoveCard(null, true); }, - check(event,player){ - return player.canMoveCard(true,true); + check(event, player) { + return player.canMoveCard(true, true); + }, + *content(event, map) { + const player = map.player; + let result = yield player.moveCard(); + const targets = result.targets; + const guohe = new lib.element.VCard({ + name: "guohe", + isCard: true, + }); + if (targets[0].canUse(guohe, targets[1])) targets[0].useCard(guohe, targets[1], "noai"); }, - *content(event,map){ - const player=map.player; - let result=yield player.moveCard(); - const targets=result.targets; - const guohe=new lib.element.VCard({name:'guohe',isCard:true}); - if(targets[0].canUse(guohe,targets[1])) targets[0].useCard(guohe,targets[1],'noai'); - } }, //张邈 - dddxiaxing:{ - audio:2, - enable:'chooseToUse', - hiddenCard(player,name){ - if(player.hasSkill('dddxiaxing_used')) return false; - return name=='tao'; + dddxiaxing: { + audio: 2, + enable: "chooseToUse", + hiddenCard(player, name) { + if (player.hasSkill("dddxiaxing_used")) return false; + return name == "tao"; }, - filter(event,player){ - if(event.type!='dying') return false; - if(!player.countCards('he')) return false; - const evt=get.event().getParent('_save'); - if(!evt||!evt.dying||!evt.dying.isIn()) return false; - return !player.hasSkill('dddxiaxing_used'); + filter(event, player) { + if (event.type != "dying") return false; + if (!player.countCards("he")) return false; + const evt = get.event().getParent("_save"); + if (!evt || !evt.dying || !evt.dying.isIn()) return false; + return !player.hasSkill("dddxiaxing_used"); }, - check:card=>{ - return 7-get.value(card); + check: (card) => { + return 7 - get.value(card); }, - filterCard:true, - position:'he', - discard:false, - delay:false, - lose:false, - group:['dddxiaxing_begin','dddxiaxing_viewas'], - prompt(){ - const evt=get.event().getParent('_save'); + filterCard: true, + position: "he", + discard: false, + delay: false, + lose: false, + group: ["dddxiaxing_begin", "dddxiaxing_viewas"], + prompt() { + const evt = get.event().getParent("_save"); return `将一张牌置于牌堆顶,视为${get.translation(evt.dying)}使用一张【桃】`; }, - *content(event,map){ - const player=map.player,cards=event.cards; - player.addTempSkill('dddxiaxing_used','roundStart'); - game.log(player,'将一张牌置于了牌堆顶'); - player.$throw(cards.length,1000); - yield player.lose(cards,ui.cardPile,'insert'); - const evt=event.getParent('_save'); - yield evt.dying.chooseUseTarget('tao',true); - if(!player.hasMark('dddxiaxing')) player.addMark('dddxiaxing'); + *content(event, map) { + const player = map.player, + cards = event.cards; + player.addTempSkill("dddxiaxing_used", "roundStart"); + game.log(player, "将一张牌置于了牌堆顶"); + player.$throw(cards.length, 1000); + yield player.lose(cards, ui.cardPile, "insert"); + const evt = event.getParent("_save"); + yield evt.dying.chooseUseTarget("tao", true); + if (!player.hasMark("dddxiaxing")) player.addMark("dddxiaxing"); }, - marktext:'侠', - intro:{ - markcount:()=>0, - name:'侠行', - name2:'侠', - content:'已拥有“侠”标记', + marktext: "侠", + intro: { + markcount: () => 0, + name: "侠行", + name2: "侠", + content: "已拥有“侠”标记", }, - ai:{ - order:4, - result:{ - player(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + ai: { + order: 4, + result: { + player(player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, - } - }, - subSkill:{ - begin:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - filter(event,player){ - if(!player.countCards('he')) return false; - return !player.hasSkill('dddxiaxing_used'); - }, - direct:true, - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - let result=yield player.chooseCard(get.prompt('dddxiaxing'),`将一张牌置于牌堆顶,视为${get.translation(target)}使用一张【酒】`,'he').set('ai',card=>{ - if(get.event('goon')) return 5-get.value(card); - return 0; - }).set('goon',get.effect(target,{name:'jiu'},player,player)>0); - if(!result.bool) return event.finish(); - const cards=result.cards; - player.logSkill('dddxiaxing_begin',target); - player.addTempSkill('dddxiaxing_used','roundStart'); - game.log(player,'将一张牌置于了牌堆顶'); - player.$throw(cards.length,1000); - yield player.lose(cards,ui.cardPile,'insert'); - yield target.chooseUseTarget('jiu',true); - if(!player.hasMark('dddxiaxing')) player.addMark('dddxiaxing'); - } }, - used:{charlotte:true}, - viewas:{ - audio:'dddxiaxing', - enable:'chooseToUse', - filter(event,player){ - if(event.type=='wuxie'||!player.hasMark('dddxiaxing')) return false; - for(const name of ['sha','shan']){ - if(event.filterCard({name:name,isCard:true},player,event)) return true; + }, + subSkill: { + begin: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + filter(event, player) { + if (!player.countCards("he")) return false; + return !player.hasSkill("dddxiaxing_used"); + }, + direct: true, + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + let result = yield player + .chooseCard( + get.prompt("dddxiaxing"), + `将一张牌置于牌堆顶,视为${get.translation(target)}使用一张【酒】`, + "he" + ) + .set("ai", (card) => { + if (get.event("goon")) return 5 - get.value(card); + return 0; + }) + .set("goon", get.effect(target, { name: "jiu" }, player, player) > 0); + if (!result.bool) return event.finish(); + const cards = result.cards; + player.logSkill("dddxiaxing_begin", target); + player.addTempSkill("dddxiaxing_used", "roundStart"); + game.log(player, "将一张牌置于了牌堆顶"); + player.$throw(cards.length, 1000); + yield player.lose(cards, ui.cardPile, "insert"); + yield target.chooseUseTarget("jiu", true); + if (!player.hasMark("dddxiaxing")) player.addMark("dddxiaxing"); + }, + }, + used: { charlotte: true }, + viewas: { + audio: "dddxiaxing", + enable: "chooseToUse", + filter(event, player) { + if (event.type == "wuxie" || !player.hasMark("dddxiaxing")) return false; + for (const name of ["sha", "shan"]) { + if (event.filterCard({ name: name, isCard: true }, player, event)) + return true; } return false; }, - chooseButton:{ - dialog(event,player){ - const vcards=[]; - for(const name of ['sha','shan']){ - const card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); + chooseButton: { + dialog(event, player) { + const vcards = []; + for (const name of ["sha", "shan"]) { + const card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) + vcards.push(["基本", "", name]); } - const dialog=ui.create.dialog('侠行',[vcards,'vcard'],'hidden'); - dialog.direct=true; + const dialog = ui.create.dialog("侠行", [vcards, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - backup(links,player){ + backup(links, player) { return { - filterCard:()=>false, - selectCard:-1, - viewAs:{ - name:links[0][2], - isCard:true, + filterCard: () => false, + selectCard: -1, + viewAs: { + name: links[0][2], + isCard: true, }, - popname:true, - precontent(){ - player.logSkill('dddxiaxing_viewas'); - player.clearMark('dddxiaxing'); + popname: true, + precontent() { + player.logSkill("dddxiaxing_viewas"); + player.clearMark("dddxiaxing"); }, - } + }; + }, + prompt(links, player) { + return ( + "侠行:移去“侠”标记,视为使用一张【" + get.translation(links[0][2]) + "】" + ); }, - prompt(links,player){ - return '侠行:移去“侠”标记,视为使用一张【'+get.translation(links[0][2])+'】'; - } }, - ai:{ - order(item,player){ - const event=get.event(); - if(event.filterCard({name:'sha'},player,event)){ - if(!player.hasShan()&&!game.hasPlayer(function(current){ - return player.canUse('sha',current)&¤t.hp==1&&get.effect(current,{name:'sha'},player,player)>0; - })){ + ai: { + order(item, player) { + const event = get.event(); + if (event.filterCard({ name: "sha" }, player, event)) { + if ( + !player.hasShan() && + !game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + current.hp == 1 && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 0; } return 2.95; - } - else return 3.15; + } else return 3.15; }, - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(!player.hasMark('dddxiaxing')) return false; - if(arg!='use') return false; + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + if (!player.hasMark("dddxiaxing")) return false; + if (arg != "use") return false; + }, + result: { + player: 1, }, - result:{ - player:1 - } }, }, - } + }, }, //张承 - dddjuxian:{ - enable:'phaseUse', - usable:2, - filter(event,player){ - return !player.hasSkill('dddjuxian_ban'); + dddjuxian: { + enable: "phaseUse", + usable: 2, + filter(event, player) { + return !player.hasSkill("dddjuxian_ban"); }, - chooseButton:{ - dialog(event,player){ - var dialog=ui.create.dialog('聚贤:请选择一项','hidden'); - dialog.add([[ - ['top','展示一张牌,然后将此牌置于牌堆顶'], - ['hand','展示一张牌,然后将此牌交给一名其他角色'] - ],'textbutton']); + chooseButton: { + dialog(event, player) { + var dialog = ui.create.dialog("聚贤:请选择一项", "hidden"); + dialog.add([ + [ + ["top", "展示一张牌,然后将此牌置于牌堆顶"], + ["hand", "展示一张牌,然后将此牌交给一名其他角色"], + ], + "textbutton", + ]); return dialog; }, - filter(button,player){ - return !player.hasSkill('dddjuxian_'+button.link,null,null,false); + filter(button, player) { + return !player.hasSkill("dddjuxian_" + button.link, null, null, false); }, - check(button){ + check(button) { return 1; }, - backup(links){ - return get.copy(lib.skill['dddjuxian_'+links[0]]); + backup(links) { + return get.copy(lib.skill["dddjuxian_" + links[0]]); }, - prompt(links){ - if(links[0]=='top') return '展示一张牌,然后将此牌置于牌堆顶'; - return '展示一张牌,然后将此牌交给一名其他角色'; + prompt(links) { + if (links[0] == "top") return "展示一张牌,然后将此牌置于牌堆顶"; + return "展示一张牌,然后将此牌交给一名其他角色"; }, }, - ai:{ - order:10, - threaten:1.7, - result:{player:1}, + ai: { + order: 10, + threaten: 1.7, + result: { player: 1 }, }, - subSkill:{ - backup:{audio:'dddjuxian'}, - ban:{charlotte:true}, - top:{ - audio:'dddjuxian', - filterCard:true, - selectCard:1, - position:'he', - discard:false, - delay:false, - lose:false, - *content(event,map){ - const player=map.player,cards=event.cards; - player.addTempSkill('dddjuxian_top','phaseUseAfter'); + subSkill: { + backup: { audio: "dddjuxian" }, + ban: { charlotte: true }, + top: { + audio: "dddjuxian", + filterCard: true, + selectCard: 1, + position: "he", + discard: false, + delay: false, + lose: false, + *content(event, map) { + const player = map.player, + cards = event.cards; + player.addTempSkill("dddjuxian_top", "phaseUseAfter"); player.showCards(cards); - const color1=get.color(cards); - player.$throw(cards,1000); - game.log(player,'将',cards,'置于了牌堆顶'); - yield player.lose(cards,ui.cardPile,'insert'); - const targets=game.filterPlayer(target=>target.countGainableCards(player,'he')); + const color1 = get.color(cards); + player.$throw(cards, 1000); + game.log(player, "将", cards, "置于了牌堆顶"); + yield player.lose(cards, ui.cardPile, "insert"); + const targets = game.filterPlayer((target) => + target.countGainableCards(player, "he") + ); let result; - if(!targets.length) return event.finish(); - else if(targets.length==1) result={bool:true,targets:targets}; - else result=yield player.chooseTarget('聚贤:获得一名其他角色的一张牌',(card,player,target)=>{ - if(target==player) return false; - return target.countGainableCards(player,'he'); - },true).set('ai',target=>{ - const player=get.player(); - return get.effect(target,{name:'shunshou'},player,player); - }); - if(!result.bool) return event.finish(); - const target=result.targets[0]; + if (!targets.length) return event.finish(); + else if (targets.length == 1) result = { bool: true, targets: targets }; + else + result = yield player + .chooseTarget( + "聚贤:获得一名其他角色的一张牌", + (card, player, target) => { + if (target == player) return false; + return target.countGainableCards(player, "he"); + }, + true + ) + .set("ai", (target) => { + const player = get.player(); + return get.effect(target, { name: "shunshou" }, player, player); + }); + if (!result.bool) return event.finish(); + const target = result.targets[0]; player.line(target); - result=yield player.gainPlayerCard(target,'he',true); - if(!result.bool) return event.finish(); - const cards2=result.links; - const color2=get.color(cards2); - if(color1&&color2&&color1!=color2) player.addTempSkill('dddjuxian_ban'); + result = yield player.gainPlayerCard(target, "he", true); + if (!result.bool) return event.finish(); + const cards2 = result.links; + const color2 = get.color(cards2); + if (color1 && color2 && color1 != color2) player.addTempSkill("dddjuxian_ban"); }, - ai:{ - result:{ - player:1, + ai: { + result: { + player: 1, }, }, }, - hand:{ - audio:'dddjuxian', - filterTarget:lib.filter.notMe, - filterCard:true, - selectCard:1, - position:'he', - discard:false, - delay:false, - lose:false, - *content(event,map){ - const player=map.player,cards=event.cards,target=event.targets[0]; - player.addTempSkill('dddjuxian_hand','phaseUseAfter'); + hand: { + audio: "dddjuxian", + filterTarget: lib.filter.notMe, + filterCard: true, + selectCard: 1, + position: "he", + discard: false, + delay: false, + lose: false, + *content(event, map) { + const player = map.player, + cards = event.cards, + target = event.targets[0]; + player.addTempSkill("dddjuxian_hand", "phaseUseAfter"); player.showCards(cards); - const color1=get.color(cards); + const color1 = get.color(cards); let result; - yield player.give(cards,target); - result=yield player.draw(); - const cards2=result.filter(i=>get.owner(i)==player&&get.position(i)=='h'); - if(!cards.length) return event.finish(); - const color2=get.color(cards2); + yield player.give(cards, target); + result = yield player.draw(); + const cards2 = result.filter( + (i) => get.owner(i) == player && get.position(i) == "h" + ); + if (!cards.length) return event.finish(); + const color2 = get.color(cards2); player.showCards(cards2); - if(color1&&color2&&color1!=color2) player.addTempSkill('dddjuxian_ban'); + if (color1 && color2 && color1 != color2) player.addTempSkill("dddjuxian_ban"); }, - ai:{ - result:{ - player:1, - target:1, + ai: { + result: { + player: 1, + target: 1, }, }, }, }, }, - dddjungui:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - *content(event,map){ - const player=map.player; - let result=yield player.chooseTarget(get.prompt2('dddjungui')); - if(!result.bool) return event.finish(); - const target=result.targets[0]; - player.logSkill('dddjungui',target); + dddjungui: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + *content(event, map) { + const player = map.player; + let result = yield player.chooseTarget(get.prompt2("dddjungui")); + if (!result.bool) return event.finish(); + const target = result.targets[0]; + player.logSkill("dddjungui", target); target.draw(2); yield target.showHandcards(); - const targetSuitsCount=target.getCards('h').map(card=>{ - return get.suit(card); - }).toUniqued().length; - const usedCount=player.getHistory('useCard').map(evt=>{ - return get.suit(evt.card); - }).toUniqued().length; - let decreasedCount=0; - if(usedCount>0){ - const numbers=Array.from({length:usedCount},(_,i)=>get.cnNumber(i+1,true)); - result=yield player.chooseControl(numbers,'cancel2').set('prompt',`是否令${get.translation(target)}少弃置任意张牌?`).set('ai',()=>{ - return get.event('choice'); - }).set('choice',get.attitude(player,target)>0?numbers.lastItem:'cancel2'); - if(result.control!='cancel'){ - decreasedCount=result.index+1; - game.log(player,'选择令',target,'少弃置',get.cnNumber(decreasedCount),'张牌'); + const targetSuitsCount = target + .getCards("h") + .map((card) => { + return get.suit(card); + }) + .toUniqued().length; + const usedCount = player + .getHistory("useCard") + .map((evt) => { + return get.suit(evt.card); + }) + .toUniqued().length; + let decreasedCount = 0; + if (usedCount > 0) { + const numbers = Array.from({ length: usedCount }, (_, i) => + get.cnNumber(i + 1, true) + ); + result = yield player + .chooseControl(numbers, "cancel2") + .set("prompt", `是否令${get.translation(target)}少弃置任意张牌?`) + .set("ai", () => { + return get.event("choice"); + }) + .set("choice", get.attitude(player, target) > 0 ? numbers.lastItem : "cancel2"); + if (result.control != "cancel") { + decreasedCount = result.index + 1; + game.log( + player, + "选择令", + target, + "少弃置", + get.cnNumber(decreasedCount), + "张牌" + ); } } - const toDiscardNum=targetSuitsCount-decreasedCount; - if(toDiscardNum<=0) return event.finish(); - target.chooseToDiscard(`隽轨:请弃置${get.cnNumber(toDiscardNum)}张花色不同的手牌`,toDiscardNum,true,(card,player)=>{ - const suit=get.suit(card); - for(const cardx of ui.selected.cards){ - if(get.suit(cardx)==suit) return false; - } - return true; - }).set('complexCard',true); - } + const toDiscardNum = targetSuitsCount - decreasedCount; + if (toDiscardNum <= 0) return event.finish(); + target + .chooseToDiscard( + `隽轨:请弃置${get.cnNumber(toDiscardNum)}张花色不同的手牌`, + toDiscardNum, + true, + (card, player) => { + const suit = get.suit(card); + for (const cardx of ui.selected.cards) { + if (get.suit(cardx) == suit) return false; + } + return true; + } + ) + .set("complexCard", true); + }, }, //刘宠 - dddjinggou:{ - audio:2, - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - if(get.type(event.card)!='equip') return false; - if(get.subtype(event.card)!='equip1') return false; - const range=player.getAttackRange(); - return !game.hasPlayer(current=>{ - return current.getAttackRange()>range; + dddjinggou: { + audio: 2, + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + if (get.type(event.card) != "equip") return false; + if (get.subtype(event.card) != "equip1") return false; + const range = player.getAttackRange(); + return !game.hasPlayer((current) => { + return current.getAttackRange() > range; }); }, - direct:true, - *content(event,map){ - const player=map.player; - let result=yield player.chooseTarget('精彀:对一名其他角色造成1点伤害',true,lib.filter.notMe).set('ai',target=>{ - var player=get.player(); - return get.damageEffect(target,player,player); - }); - if(result.bool){ - const target=result.targets[0]; - player.logSkill('dddjinggou',target); + direct: true, + *content(event, map) { + const player = map.player; + let result = yield player + .chooseTarget("精彀:对一名其他角色造成1点伤害", true, lib.filter.notMe) + .set("ai", (target) => { + var player = get.player(); + return get.damageEffect(target, player, player); + }); + if (result.bool) { + const target = result.targets[0]; + player.logSkill("dddjinggou", target); target.damage(); } }, }, - dddmoyan:{ - audio:2, - trigger:{global:'roundStart'}, - *content(event,map){ - const player=map.player; - const cards=game.cardsGotoOrdering(get.cards(3)).cards; - yield player.showCards(cards,`${get.translation(player)}发动了【末焱】`); - let result=yield player.chooseTarget('末焱:选择一名角色获得其中至少一张牌').set('ai',target=>get.attitude(get.player(),target)); - if(!result.bool) return event.finish(); - const target=result.targets[0]; - result=yield target.chooseButton(['末焱:获得至少一张牌',cards],true,[1,cards.length]).set('ai',button=>{ - return get.value(button.link); - }); - if(!result.bool) return event.finish(); - const gains=result.links; - target.gain(gains,'gain2'); - player.setStorage('dddmoyan_target',[target,gains.length]); - player.addTempSkill('dddmoyan_target','roundStart'); + dddmoyan: { + audio: 2, + trigger: { global: "roundStart" }, + *content(event, map) { + const player = map.player; + const cards = game.cardsGotoOrdering(get.cards(3)).cards; + yield player.showCards(cards, `${get.translation(player)}发动了【末焱】`); + let result = yield player + .chooseTarget("末焱:选择一名角色获得其中至少一张牌") + .set("ai", (target) => get.attitude(get.player(), target)); + if (!result.bool) return event.finish(); + const target = result.targets[0]; + result = yield target + .chooseButton(["末焱:获得至少一张牌", cards], true, [1, cards.length]) + .set("ai", (button) => { + return get.value(button.link); + }); + if (!result.bool) return event.finish(); + const gains = result.links; + target.gain(gains, "gain2"); + player.setStorage("dddmoyan_target", [target, gains.length]); + player.addTempSkill("dddmoyan_target", "roundStart"); }, - subSkill:{ - target:{ - onremove:true, - trigger:{player:'damageBegin3'}, - filter(event,player){ - const info=player.getStorage('dddmoyan_target'); - return info[0]&&info[0].isIn()&&info[0].countCards('h')<=info[1]; + subSkill: { + target: { + onremove: true, + trigger: { player: "damageBegin3" }, + filter(event, player) { + const info = player.getStorage("dddmoyan_target"); + return info[0] && info[0].isIn() && info[0].countCards("h") <= info[1]; }, - forced:true, - charlotte:true, - content(){ - trigger.increase('num'); + forced: true, + charlotte: true, + content() { + trigger.increase("num"); }, }, }, }, //罗宪 - dddshilie:{ - audio:2, - enable:'chooseToUse', - hiddenCard(player,name){ - if(!player.countCards('h')) return false; - return name=='sha'||name=='shan'; + dddshilie: { + audio: 2, + enable: "chooseToUse", + hiddenCard(player, name) { + if (!player.countCards("h")) return false; + return name == "sha" || name == "shan"; }, - filter(event,player){ - if(event.type=='wuxie'||!_status.currentPhase) return false; - if(!player.countCards('h')||player.hasSkill('dddshilie_used',null,null,false)) return false; - for(var name of ['sha','shan']){ - if(event.filterCard({name:name,isCard:true},player,event)) return true; + filter(event, player) { + if (event.type == "wuxie" || !_status.currentPhase) return false; + if (!player.countCards("h") || player.hasSkill("dddshilie_used", null, null, false)) + return false; + for (var name of ["sha", "shan"]) { + if (event.filterCard({ name: name, isCard: true }, player, event)) return true; } return false; }, - chooseButton:{ - dialog(event,player){ - var vcards=[]; - for(var name of ['sha','shan']){ - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); + chooseButton: { + dialog(event, player) { + var vcards = []; + for (var name of ["sha", "shan"]) { + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); } - const dialog=ui.create.dialog('示烈',[vcards,'vcard'],'hidden'); - dialog.direct=true; + const dialog = ui.create.dialog("示烈", [vcards, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - check(button){ + check(button) { return 1; }, - backup(links,player){ + backup(links, player) { return { - filterCard(card){ + filterCard(card) { return !get.is.shownCard(card); }, - filterOk:()=>{ - return ui.selected.cards.map(card=>{ - return get.number(card); - }).reduce((p,c)=>{ - return p+c; - },0)>=get.player().getHp()+(_status.currentPhase?_status.currentPhase.getHp():0); + filterOk: () => { + return ( + ui.selected.cards + .map((card) => { + return get.number(card); + }) + .reduce((p, c) => { + return p + c; + }, 0) >= + get.player().getHp() + + (_status.currentPhase ? _status.currentPhase.getHp() : 0) + ); }, - selectCard:[1,Infinity], - viewAs:{ - name:links[0][2], - isCard:true, + selectCard: [1, Infinity], + viewAs: { + name: links[0][2], + isCard: true, }, - popname:true, - ignoreMod:true, - ai1(card){ - const need=get.player().getHp()+(_status.currentPhase?_status.currentPhase.getHp():0); - let num=0; - for(var i=0;i=need){ - if(cards[i]==card||cards[j]==card) return 15-get.value(card); + if (num + get.number(card) == need) return 20 - get.value(card); + if (ui.selected.cards.length == 0) { + var cards = _status.event.player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + for (var j = i + 1; j < cards.length; j++) { + if (cards[i].number + cards[j].number >= need) { + if (cards[i] == card || cards[j] == card) + return 15 - get.value(card); } } } } return 0.1; }, - precontent(){ - 'step 0' - player.logSkill('dddshilie'); - player.addTempSkill('dddshilie_used'); - var cards=event.result.cards.slice(); - player.addShownCards(cards,'visible_dddshilie'); + precontent() { + "step 0"; + player.logSkill("dddshilie"); + player.addTempSkill("dddshilie_used"); + var cards = event.result.cards.slice(); + player.addShownCards(cards, "visible_dddshilie"); delete event.result.skill; - player.showCards(cards,get.translation(player)+'发动了【示烈】'); - if(cards.map(card=>{ - return get.number(card); - }).reduce((p,c)=>{ - return p+c; - },0)==player.getHp()+(_status.currentPhase?_status.currentPhase.getHp():0)){ + player.showCards(cards, get.translation(player) + "发动了【示烈】"); + if ( + cards + .map((card) => { + return get.number(card); + }) + .reduce((p, c) => { + return p + c; + }, 0) == + player.getHp() + (_status.currentPhase ? _status.currentPhase.getHp() : 0) + ) { player.draw(cards.length); } - event.result.card=new lib.element.VCard({name:event.result.card.name,isCard:true}); - event.result.cards=[]; + event.result.card = new lib.element.VCard({ + name: event.result.card.name, + isCard: true, + }); + event.result.cards = []; game.delayx(); }, - } + }; + }, + prompt(links, player) { + return `###示烈###明置任意张点数之和不小于${ + player.getHp() + (_status.currentPhase ? _status.currentPhase.getHp() : 0) + }的牌,视为使用【${get.translation(links[0][2])}】`; }, - prompt(links,player){ - return `###示烈###明置任意张点数之和不小于${player.getHp()+(_status.currentPhase?_status.currentPhase.getHp():0)}的牌,视为使用【${get.translation(links[0][2])}】`; - } }, - subSkill:{used:{charlotte:true}}, - ai:{ - order(item,player){ - const evt=get.event(); - for(var name of ['sha','shan']){ - if(evt.filterCard({name:name},player,evt)) return get.order({name:name})+0.1; + subSkill: { used: { charlotte: true } }, + ai: { + order(item, player) { + const evt = get.event(); + for (var name of ["sha", "shan"]) { + if (evt.filterCard({ name: name }, player, evt)) + return get.order({ name: name }) + 0.1; } return 1; }, - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(!player.countCards('h')) return false; + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + if (!player.countCards("h")) return false; }, - result:{ - player(player){ + result: { + player(player) { return 1; - } - } - } + }, + }, + }, }, //李娥 - dddyeshen:{ - trigger:{global:'phaseJieshuBegin'}, - logTarget:'player', - prompt2(event,player){ - var num=player.countMark('dddyeshen'); - var str='展示牌堆顶的'+get.cnNumber(3-num)+'张牌,然后其将其中的一张牌当作【铁索连环】使用或打出。'; - if(num>=2) str+='然后你受到1点火属性伤害并重置此技能。'; + dddyeshen: { + trigger: { global: "phaseJieshuBegin" }, + logTarget: "player", + prompt2(event, player) { + var num = player.countMark("dddyeshen"); + var str = + "亮出牌堆底的" + + get.cnNumber(3 - num) + + "张牌,然后其将其中的一张牌当作【铁索连环】使用或打出。"; + if (num >= 2) str += "然后你受到1点火属性伤害并重置此技能。"; return str; }, - check(event,player){ - if(player.countMark('dddyeshen')>=2&&get.damageEffect(player,player,player,'fire')<0) return false; - return get.attitude(player,event.player)>0; + check(event, player) { + if ( + player.countMark("dddyeshen") >= 2 && + get.damageEffect(player, player, player, "fire") < 0 + ) + return false; + return get.attitude(player, event.player) > 0; }, - content(){ - 'step 0' - event.target=trigger.player; - var cards=get.bottomCards(3-player.countMark('dddyeshen')); - event.cards=cards; + content() { + "step 0"; + event.target = trigger.player; + var cards = get.bottomCards(3 - player.countMark("dddyeshen")); + event.cards = cards; game.cardsGotoOrdering(cards); - player.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【冶身】'); - if(!cards.some(card=>get.color(card)=='black')) event.goto(4); - 'step 1' - if(target.isIn()){ - var blacks=cards.filter(card=>get.color(card)=='black'); - if(blacks.length>1) target.chooseButton([ - '选择一张牌当作【铁索连环】使用或重铸', - blacks, - ],true).set('ai',button=>get.translation(button.link.name).length); - else event._result={ - bool:true, - links:blacks, - }; + player.showCards( + cards, + get.translation(player) + "对" + get.translation(target) + "发动了【冶身】" + ); + if (!cards.some((card) => get.color(card) == "black")) event.goto(4); + "step 1"; + if (target.isIn()) { + var blacks = cards.filter((card) => get.color(card) == "black"); + if (blacks.length > 1) + target + .chooseButton(["选择一张牌当作【铁索连环】使用或重铸", blacks], true) + .set("ai", (button) => get.translation(button.link.name).length); + else + event._result = { + bool: true, + links: blacks, + }; + } else event.goto(4); + "step 2"; + if (result.bool) { + event.links = result.links.slice(0); + var card = get.autoViewAs({ name: "tiesuo" }, result.links); + var maxNum = get.translation(result.links[0].name).length; + if (!game.hasPlayer((current) => target.canUse(card, current))) { + event._result = { bool: false }; + } else + target + .chooseTarget( + "请选择【铁索连环】的目标,或点“取消”重铸", + function (card, player, target) { + var card = _status.event.card; + return player.canUse(card, target); + }, + [1, Math.min(maxNum, game.countPlayer())] + ) + .set("card", card) + .set("ai", function (target) { + var player = _status.event.player, + card = _status.event.card; + return get.effect_use(target, card, player, player); + }); } - else event.goto(4); - 'step 2' - if(result.bool){ - event.links=result.links.slice(0); - var card=get.autoViewAs({name:'tiesuo'},result.links); - var maxNum=get.translation(result.links[0].name).length; - if(!game.hasPlayer(current=>target.canUse(card,current))){ - event._result={bool:false}; - } - else target.chooseTarget('请选择【铁索连环】的目标,或点“取消”重铸',function(card,player,target){ - var card=_status.event.card; - return player.canUse(card,target); - },[1,Math.min(maxNum,game.countPlayer())]).set('card',card).set('ai',function(target){ - var player=_status.event.player,card=_status.event.card; - return get.effect_use(target,card,player,player) - }); + "step 3"; + if (result.bool && result.targets.length > 0) { + var card = get.autoViewAs({ name: "tiesuo" }, event.links); + target.useCard(result.targets, card, event.links); + } else { + target.recast(event.links, (player, cards) => game.cardsDiscard(cards)); } - 'step 3' - if(result.bool&&result.targets.length>0){ - var card=get.autoViewAs({name:'tiesuo'},event.links); - target.useCard(result.targets,card,event.links); + "step 4"; + for (var card of cards) { + if (get.position(card, true) == "o") + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); } - else{ - target.recast(event.links,(player,cards)=>game.cardsDiscard(cards)); - } - 'step 4' - for(var card of cards){ - if(get.position(card,true)=='o') ui.cardPile.insertBefore(card,ui.cardPile.firstChild); - } - 'step 5' - var num=player.countMark('dddyeshen'); - if(num<2){ - player.addMark('dddyeshen',1,false); - game.log(player,'的','#g【冶身】','的亮出牌数-1'); - } - else{ - player.removeMark('dddyeshen',num,false); - game.log(player,'还原了','#g【冶身】','的亮出牌数'); - player.damage('fire','nocard'); + "step 5"; + var num = player.countMark("dddyeshen"); + if (num < 2) { + player.addMark("dddyeshen", 1, false); + game.log(player, "的", "#g【冶身】", "的亮出牌数-1"); + } else { + player.removeMark("dddyeshen", num, false); + game.log(player, "还原了", "#g【冶身】", "的亮出牌数"); + player.damage("fire", "nocard"); } }, }, - dddqiaoduan:{ - trigger:{global:'linkAfter'}, - direct:true, - usable:1, - filter(event,player){ - var num=game.countPlayer(current=>current.isLinked()); - if(event.player.isLinked()){ - return player.countCards('he')>=num&&game.hasPlayer(current=>current.isDamaged()); - } - else{ - return num>0; + dddqiaoduan: { + trigger: { global: "linkAfter" }, + direct: true, + usable: 1, + filter(event, player) { + var num = game.countPlayer((current) => current.isLinked()); + if (event.player.isLinked()) { + return ( + player.countCards("he") >= num && game.hasPlayer((current) => current.isDamaged()) + ); + } else { + return num > 0; } }, - content(){ - 'step 0' - if(trigger.player.isLinked()){ - var num=game.countPlayer(current=>current.isLinked()); + content() { + "step 0"; + if (trigger.player.isLinked()) { + var num = game.countPlayer((current) => current.isLinked()); player.chooseCardTarget({ - prompt:get.prompt('dddqiaoduan'), - prompt2:'操作提示:选择'+get.cnNumber(num)+'张牌和一名已受伤的角色。将这些牌置于牌堆底(先选择的在上),然后该角色回复1点体力。', - filterCard:true, - selectCard:num, - filterTarget:(card,player,target)=>target.isDamaged(), - ai1:card=>5-get.value(card), - ai2:target=>{ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - } - }) - } - else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('dddqiaoduan',result.targets[0]); - player.loseToDiscardpile(result.cards,ui.cardPile); + prompt: get.prompt("dddqiaoduan"), + prompt2: + "操作提示:选择" + + get.cnNumber(num) + + "张牌和一名已受伤的角色。将这些牌置于牌堆底(先选择的在上),然后该角色回复1点体力。", + filterCard: true, + selectCard: num, + filterTarget: (card, player, target) => target.isDamaged(), + ai1: (card) => 5 - get.value(card), + ai2: (target) => { + var player = _status.event.player; + return get.recoverEffect(target, player, player); + }, + }); + } else event.goto(2); + "step 1"; + if (result.bool) { + player.logSkill("dddqiaoduan", result.targets[0]); + player.loseToDiscardpile(result.cards, ui.cardPile); result.targets[0].recover(); - } - else player.storage.counttrigger.dddqiaoduan--; + } else player.storage.counttrigger.dddqiaoduan--; event.finish(); - 'step 2' - var num=game.countPlayer(current=>current.isLinked()); - player.chooseTarget(get.prompt('dddqiaoduan'),[1,num],'令至多'+get.cnNumber(num)+'名角色各摸一张牌').set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - if(target.hasSkillTag('nogain')) att/=10; - return att; - }); - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('dddqiaoduan',targets); + "step 2"; + var num = game.countPlayer((current) => current.isLinked()); + player + .chooseTarget( + get.prompt("dddqiaoduan"), + [1, num], + "令至多" + get.cnNumber(num) + "名角色各摸一张牌" + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + if (target.hasSkillTag("nogain")) att /= 10; + return att; + }); + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("dddqiaoduan", targets); game.asyncDraw(targets); game.delayex(); - } - else player.storage.counttrigger.dddqiaoduan--; + } else player.storage.counttrigger.dddqiaoduan--; }, }, //孙亮 - ddddiedang:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - if(player.storage.ddddiedang) return player.countCards('he')>=3; + ddddiedang: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + if (player.storage.ddddiedang) return player.countCards("he") >= 3; return true; }, - filterCard:true, - position:'he', - selectCard(){ - var player=_status.event.player; - return player.storage.ddddiedang?3:0; + filterCard: true, + position: "he", + selectCard() { + var player = _status.event.player; + return player.storage.ddddiedang ? 3 : 0; }, - prompt(){ - var player=_status.event.player; - if(player.storage.ddddiedang) return '弃置三张牌,然后摸一张牌'; - return '摸三张牌,然后弃置一张牌'; + prompt() { + var player = _status.event.player; + if (player.storage.ddddiedang) return "弃置三张牌,然后摸一张牌"; + return "摸三张牌,然后弃置一张牌"; }, - check:card=>5-get.value(card), - content(){ - 'step 0' - if(player.storage.ddddiedang){ + check: (card) => 5 - get.value(card), + content() { + "step 0"; + if (player.storage.ddddiedang) { player.draw(); - } - else{ + } else { player.draw(3); - player.chooseToDiscard(true,'he'); + player.chooseToDiscard(true, "he"); } - 'step 1' - if(player.isMaxHandcard()||player.isMinHandcard()) player.storage.ddddiedang=!player.storage.ddddiedang; + "step 1"; + if (player.isMaxHandcard() || player.isMinHandcard()) + player.storage.ddddiedang = !player.storage.ddddiedang; }, - ai:{ - order:1, - result:{ - player(player){ - if(ui.selected.cards.length){ - var num=1+player.countCards('h',card=>!ui.selected.cards.includes(card)); - if(!game.hasPlayer(current=>{ - return current!=player&¤t.countCards('h')>num; - })||!game.hasPlayer(current=>{ - return current!=player&¤t.countCards('h') !ui.selected.cards.includes(card)); + if ( + !game.hasPlayer((current) => { + return current != player && current.countCards("h") > num; + }) || + !game.hasPlayer((current) => { + return current != player && current.countCards("h") < num; + }) + ) + return 1; return -1; } return 1; @@ -766,1951 +903,2589 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - dddanliu:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + dddanliu: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter(event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('dddanliu'),function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).set('ai',function(target){ - return get.attitude(get.player(),target)*Math.sqrt(1+target.countCards('h')); - }) - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddanliu',target); - event.target=target; + content() { + "step 0"; + player + .chooseTarget(get.prompt2("dddanliu"), function (card, player, target) { + return target != player && target.countCards("h") > 0; + }) + .set("ai", function (target) { + return get.attitude(get.player(), target) * Math.sqrt(1 + target.countCards("h")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddanliu", target); + event.target = target; + } else event.finish(); + "step 2"; + player + .choosePlayerCard(target, true, "h", "visible", [0, 1]) + .set("filterOk", () => ui.selected.buttons.length > 0) + .set("ai", (button) => { + var player = get.player(), + target = _status.event.target; + var color = get.color(button.link); + if ( + player.hasCard(function (card) { + return get.color(card) == color; + }, "h") + ) { + if (color == "red") + return ( + get.recoverEffect(player, player, player) + + 2 / Math.max(2, get.value(button.link)) + ); + if (color == "black") + return ( + 2 * get.effect(target, { name: "draw" }, target, player) + + 2 / Math.max(2, get.value(button.link)) + ); + } + return get.value(button.link) / 3; + }); + "step 3"; + if (result.bool) { + event.card1 = result.cards[0]; + target + .choosePlayerCard( + player, + true, + "h", + "visible", + [0, 1], + get.translation(player) + + "选择了你的" + + get.translation(event.card1) + + "。请选择其的一张牌" + ) + .set("ai", function (button) { + var evt = _status.event.getParent(); + var player = evt.target, + card = evt.card1, + source = evt.player; + var color = get.color(card); + if (get.attitude(player, target) > 0) { + if (get.color(button.link) == color) return 20 - get.value(card); + return -get.value(card); + } else { + if (get.color(button.link) == "black") return 20 + get.value(card); + return get.value(card); + } + }) + .set("filterOk", () => ui.selected.buttons.length > 0); } - else event.finish(); - 'step 2' - player.choosePlayerCard(target,true,'h','visible',[0,1]).set('filterOk',()=>ui.selected.buttons.length>0).set('ai',button=>{ - var player=get.player(),target=_status.event.target; - var color=get.color(button.link); - if(player.hasCard(function(card){ - return get.color(card)==color; - },'h')){ - if(color=='red') return get.recoverEffect(player,player,player)+2/Math.max(2,get.value(button.link)); - if(color=='black') return 2*get.effect(target,{name:'draw'},target,player)+2/Math.max(2,get.value(button.link)); - } - return get.value(button.link)/3; - }) - 'step 3' - if(result.bool){ - event.card1=result.cards[0]; - target.choosePlayerCard( - player,true,'h','visible',[0,1], - get.translation(player)+'选择了你的'+get.translation(event.card1)+'。请选择其的一张牌' - ).set('ai',function(button){ - var evt=_status.event.getParent(); - var player=evt.target,card=evt.card1,source=evt.player; - var color=get.color(card); - if(get.attitude(player,target)>0){ - if(get.color(button.link)==color) return 20-get.value(card); - return -get.value(card); + "step 4"; + if (result.bool) { + event.card2 = result.cards[0]; + var color = get.color(event.card1); + if (color != "none" && get.color(event.card2) == color) { + event.color = color; + var next = player.chooseBool("是否与" + get.translation(target) + "交换展示牌"); + var prompt2 = + "用" + + get.translation(event.card1) + + "交换对方的" + + get.translation(event.card2); + if (color == "black") { + prompt2 += ",然后对方摸两张牌"; + next.set( + "goon", + 2 * get.effect(target, { name: "draw" }, target, player) > 0 + ); + } else if (color == "red" && player.isDamaged()) { + prompt2 += ",然后你回复1点体力"; + next.set("goon", get.recoverEffect(player, player, player) > 0); } - else{ - if(get.color(button.link)=='black') return 20+get.value(card); - return get.value(card); - } - }).set('filterOk',()=>ui.selected.buttons.length>0); + next.set("prompt2", prompt2); + next.set("ai", () => Boolean(_status.event.goon)); + } else event.finish(); } - 'step 4' - if(result.bool){ - event.card2=result.cards[0]; - var color=get.color(event.card1); - if(color!='none'&&get.color(event.card2)==color){ - event.color=color; - var next=player.chooseBool('是否与'+get.translation(target)+'交换展示牌'); - var prompt2='用'+get.translation(event.card1)+'交换对方的'+get.translation(event.card2); - if(color=='black'){ - prompt2+=',然后对方摸两张牌'; - next.set('goon',2*get.effect(target,{name:'draw'},target,player)>0); - } - else if(color=='red'&&player.isDamaged()){ - prompt2+=',然后你回复1点体力'; - next.set('goon',get.recoverEffect(player,player,player)>0); - } - next.set('prompt2',prompt2); - next.set('ai',()=>Boolean(_status.event.goon)); - } - else event.finish(); - } - 'step 5' - if(result.bool){ - player.swapHandcards(target,[event.card2],[event.card1]); - if(event.color=='black'){ + "step 5"; + if (result.bool) { + player.swapHandcards(target, [event.card2], [event.card1]); + if (event.color == "black") { target.draw(2); - } - else if(event.color=='red'){ + } else if (event.color == "red") { player.recover(); } } }, }, - dddguiying:{ - zhuSkill:true, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter(event,player){ - return player.hasZhuSkill('dddguiying')&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='wu'&&player.hasZhuSkill('dddguiying',current)&¤t.countCards('h')>0; - }); - }, - gainEffect(player){ - var gainers=game.filterPlayer(current=>current.countCards('ej')); - if(!gainers.length) return 0; - var min=Math.min.apply(Math,gainers.map((current)=>{ - return Math.min.apply(Math,current.getCards('ej').map(function(card){ - return get.number(card,current); - })); - })); - return Math.max.apply(Math,game.filterPlayer(function(target){ - return target.hasCard(function(card){ - return get.number(card,target)==min&&lib.filter.canBeGained(card,player,target); - },'ej'); - }).map(function(target){ - var cards=target.getCards('ej',function(card){ - return get.number(card,target)==min&&lib.filter.canBeGained(card,player,target); - }),att=get.attitude(player,target) - return Math.max.apply(Math,cards.map(card=>{ - if(target.getCards('j').includes(card)){ - var efff=get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },player,player); - if(efff>0) return -0.5*att; - if(efff==0) return 0; - return 1.5*att; - } - if(target.getCards('e').includes(card)){ - var evalue=get.value(card,target); - if(target.hasSkillTag('noe')){ - if(evalue>=7){ - return -evalue/6*att; - } - return -evalue/10*att; - } - return -evalue/3*att; - } - })); - })) - }, - content(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current!=player&¤t.group=='wu'&&player.hasZhuSkill('dddguiying',current); - }).sortBySeat(); - if(!event.targets.length) event.finish(); - 'step 1' - var target=event.targets.shift(); - event.target=target; - if(target.isIn()&&target.group=='wu'&&target.countCards('h')>0){ - target.chooseBool( - '归萤:是否响应'+get.translation(player)+'的主公技?', - '你可以展示所有手牌,将点数最大的牌交给该角色;然后你可以获得场上点数最小的一张牌' - ).set('ai',function(){ - var player=get.player(),source=_status.event.getParent().player; - if(_status.event.gainEffect<=0) return 0; - return get.attitude(player,source)>0; - }).set('gainEffect',lib.skill.dddguiying.gainEffect(target)); - } - else event.goto(7); - 'step 2' - if(result.bool){ - target.logSkill('dddguiying',player); - target.showHandcards(get.translation(target)+'响应了〖归萤〗'); - } - else event.goto(7); - 'step 3' - if(target.isIn()){ - var cards=target.getCards('he') - if(!cards.length) event.goto(7); - var max=Math.max.apply(Math,cards.map(card=>get.number(card,target))); - var gives=cards.filter(card=>get.number(card,target)==max); - if(gives.length<=1) event._result={bool:true,cards:gives}; - else target.chooseCard('he',true,'选择给出一张点数最大的牌',function(card){ - return _status.event.cards.includes(card); - }).set('cards',gives); - } - else event.goto(7); - 'step 4' - if(result.bool){ - target.give(result.cards,player,'visible'); - } - else event.goto(7); - 'step 5' - var gainers=game.filterPlayer(current=>current.countCards('ej')); - if(target.isIn()&&gainers.length>0){ - var min=Math.min.apply(Math,gainers.map((current)=>{ - return Math.min.apply(Math,current.getCards('ej').map(function(card){ - return get.number(card,current); - })); - })); - target.chooseTarget('是否获得场上点数最小的一张牌?',function(card,player,target){ - var num=_status.event.minNum; - return target.hasCard(function(card){ - return get.number(card,target)==num&&lib.filter.canBeGained(card,player,target); - },'ej'); - }).set('minNum',min).set('ai',function(target){ - var player=get.player(),min=_status.event.minNum; - var cards=target.getCards('ej',function(card){ - return get.number(card,target)==min&&lib.filter.canBeGained(card,player,target); - }),att=get.attitude(player,target) - return Math.max.apply(Math,cards.map(card=>{ - if(target.getCards('j').includes(card)){ - var efff=get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },player,player); - if(efff>0) return -0.5*att; - if(efff==0) return 0; - return 1.5*att; - } - if(target.getCards('e').includes(card)){ - var evalue=get.value(card,target); - if(target.hasSkillTag('noe')){ - if(evalue>=7){ - return -evalue/6*att; - } - return -evalue/10*att; - } - return -evalue/3*att; - } - })); + dddguiying: { + zhuSkill: true, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter(event, player) { + return ( + player.hasZhuSkill("dddguiying") && + game.hasPlayer(function (current) { + return ( + current != player && + current.group == "wu" && + player.hasZhuSkill("dddguiying", current) && + current.countCards("h") > 0 + ); }) + ); + }, + gainEffect(player) { + var gainers = game.filterPlayer((current) => current.countCards("ej")); + if (!gainers.length) return 0; + var min = Math.min.apply( + Math, + gainers.map((current) => { + return Math.min.apply( + Math, + current.getCards("ej").map(function (card) { + return get.number(card, current); + }) + ); + }) + ); + return Math.max.apply( + Math, + game + .filterPlayer(function (target) { + return target.hasCard(function (card) { + return ( + get.number(card, target) == min && + lib.filter.canBeGained(card, player, target) + ); + }, "ej"); + }) + .map(function (target) { + var cards = target.getCards("ej", function (card) { + return ( + get.number(card, target) == min && + lib.filter.canBeGained(card, player, target) + ); + }), + att = get.attitude(player, target); + return Math.max.apply( + Math, + cards.map((card) => { + if (target.getCards("j").includes(card)) { + var efff = get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ); + if (efff > 0) return -0.5 * att; + if (efff == 0) return 0; + return 1.5 * att; + } + if (target.getCards("e").includes(card)) { + var evalue = get.value(card, target); + if (target.hasSkillTag("noe")) { + if (evalue >= 7) { + return (-evalue / 6) * att; + } + return (-evalue / 10) * att; + } + return (-evalue / 3) * att; + } + }) + ); + }) + ); + }, + content() { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return ( + current != player && + current.group == "wu" && + player.hasZhuSkill("dddguiying", current) + ); + }) + .sortBySeat(); + if (!event.targets.length) event.finish(); + "step 1"; + var target = event.targets.shift(); + event.target = target; + if (target.isIn() && target.group == "wu" && target.countCards("h") > 0) { + target + .chooseBool( + "归萤:是否响应" + get.translation(player) + "的主公技?", + "你可以展示所有手牌,将点数最大的牌交给该角色;然后你可以获得场上点数最小的一张牌" + ) + .set("ai", function () { + var player = get.player(), + source = _status.event.getParent().player; + if (_status.event.gainEffect <= 0) return 0; + return get.attitude(player, source) > 0; + }) + .set("gainEffect", lib.skill.dddguiying.gainEffect(target)); + } else event.goto(7); + "step 2"; + if (result.bool) { + target.logSkill("dddguiying", player); + target.showHandcards(get.translation(target) + "响应了〖归萤〗"); + } else event.goto(7); + "step 3"; + if (target.isIn()) { + var cards = target.getCards("he"); + if (!cards.length) event.goto(7); + var max = Math.max.apply( + Math, + cards.map((card) => get.number(card, target)) + ); + var gives = cards.filter((card) => get.number(card, target) == max); + if (gives.length <= 1) event._result = { bool: true, cards: gives }; + else + target + .chooseCard("he", true, "选择给出一张点数最大的牌", function (card) { + return _status.event.cards.includes(card); + }) + .set("cards", gives); + } else event.goto(7); + "step 4"; + if (result.bool) { + target.give(result.cards, player, "visible"); + } else event.goto(7); + "step 5"; + var gainers = game.filterPlayer((current) => current.countCards("ej")); + if (target.isIn() && gainers.length > 0) { + var min = Math.min.apply( + Math, + gainers.map((current) => { + return Math.min.apply( + Math, + current.getCards("ej").map(function (card) { + return get.number(card, current); + }) + ); + }) + ); + target + .chooseTarget("是否获得场上点数最小的一张牌?", function (card, player, target) { + var num = _status.event.minNum; + return target.hasCard(function (card) { + return ( + get.number(card, target) == num && + lib.filter.canBeGained(card, player, target) + ); + }, "ej"); + }) + .set("minNum", min) + .set("ai", function (target) { + var player = get.player(), + min = _status.event.minNum; + var cards = target.getCards("ej", function (card) { + return ( + get.number(card, target) == min && + lib.filter.canBeGained(card, player, target) + ); + }), + att = get.attitude(player, target); + return Math.max.apply( + Math, + cards.map((card) => { + if (target.getCards("j").includes(card)) { + var efff = get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ); + if (efff > 0) return -0.5 * att; + if (efff == 0) return 0; + return 1.5 * att; + } + if (target.getCards("e").includes(card)) { + var evalue = get.value(card, target); + if (target.hasSkillTag("noe")) { + if (evalue >= 7) { + return (-evalue / 6) * att; + } + return (-evalue / 10) * att; + } + return (-evalue / 3) * att; + } + }) + ); + }); + } else event.goto(7); + "step 6"; + if (result.bool) { + var target2 = result.targets[0]; + target.line(target2, "green"); + var min = Math.min.apply( + Math, + target2.getCards("ej").map(function (card) { + return get.number(card, target2); + }) + ), + cards = target2.getCards("ej", (card) => get.number(card, target2) == min); + if (cards.length <= 1) target.gain(cards, target2, "give", "bySelf"); + else + target + .gainPlayerCard(target2, "ej", true) + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set("cards", cards); } - else event.goto(7); - 'step 6' - if(result.bool){ - var target2=result.targets[0]; - target.line(target2,'green'); - var min=Math.min.apply(Math,target2.getCards('ej').map(function(card){ - return get.number(card,target2); - })),cards=target2.getCards('ej',card=>get.number(card,target2)==min); - if(cards.length<=1) target.gain(cards,target2,'give','bySelf'); - else target.gainPlayerCard(target2,'ej',true).set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards); - } - 'step 7' - if(targets.length>0) event.goto(1); + "step 7"; + if (targets.length > 0) event.goto(1); }, }, //王伉吕凯 - dddbingjian:{ - enable:['chooseToUse','chooseToRespond'], - filter(event,player){ - if(event.type=='wuxie') return false; - if(player.countMark('dddbingjian_used')>=2) return false; - if(player.countCards('h')==2) return false; - return event.filterCard({ - name:'sha', - isCard:true, - },player,event)||event.filterCard({ - name:'shan', - isCard:true, - },player,event) + dddbingjian: { + enable: ["chooseToUse", "chooseToRespond"], + filter(event, player) { + if (event.type == "wuxie") return false; + if (player.countMark("dddbingjian_used") >= 2) return false; + if (player.countCards("h") == 2) return false; + return ( + event.filterCard( + { + name: "sha", + isCard: true, + }, + player, + event + ) || + event.filterCard( + { + name: "shan", + isCard: true, + }, + player, + event + ) + ); }, - chooseButton:{ - dialog(event,player){ + chooseButton: { + dialog(event, player) { return ui.create.dialog( - '并肩', + "并肩", // [[ // [2,'调整至2张'], // [4,'调整至4张'] // ],'tdnodes'], - [['sha','shan'],'vcard'], - 'hidden' - ) + [["sha", "shan"], "vcard"], + "hidden" + ); }, // select:2, - filter(button,player){ - if(ui.selected.buttons.length){ - if(typeof button.link==typeof ui.selected.buttons[0].link) return false; + filter(button, player) { + if (ui.selected.buttons.length) { + if (typeof button.link == typeof ui.selected.buttons[0].link) return false; } // if(typeof button.link=='number'){ // return button.link!=player.countCards('h'); // } return _status.event.getParent().filterCard({ - name:button.link[2], - isCard:true, + name: button.link[2], + isCard: true, }); }, - check(button){ + check(button) { // if(typeof button.link=='number') return button.link; return 1; }, - backup(links,player){ + backup(links, player) { // if(typeof links[0]=='number') links.reverse(); - var skill={ - viewAs:{ - name:links[0][2], - suit:'none', - number:null, - isCard:true, - } - } - var num=2-player.countCards('h'); - if(num>0){ - skill.draw=num; - skill.filterCard=function(){ + var skill = { + viewAs: { + name: links[0][2], + suit: "none", + number: null, + isCard: true, + }, + }; + var num = 2 - player.countCards("h"); + if (num > 0) { + skill.draw = num; + skill.filterCard = function () { return false; - } - skill.selectCard=-1; - skill.precontent=lib.skill.dddbingjian.content_draw; - } - else{ - skill.selectCard=-num; - skill.ignoreMod=true; - skill.filterCard=lib.filter.cardDiscardable; - skill.precontent=lib.skill.dddbingjian.content_discard; - skill.check=function(card){ - return 5-get.value(card) + }; + skill.selectCard = -1; + skill.precontent = lib.skill.dddbingjian.content_draw; + } else { + skill.selectCard = -num; + skill.ignoreMod = true; + skill.filterCard = lib.filter.cardDiscardable; + skill.precontent = lib.skill.dddbingjian.content_discard; + skill.check = function (card) { + return 5 - get.value(card); }; } return skill; }, - prompt(links,player){ + prompt(links, player) { // if(typeof links[0]=='number') links.reverse(); - var num=2-player.countCards('h'); - if(num>0){ - return '摸'+get.cnNumber(num)+'张牌并视为使用'+get.translation(links[0][2]); + var num = 2 - player.countCards("h"); + if (num > 0) { + return "摸" + get.cnNumber(num) + "张牌并视为使用" + get.translation(links[0][2]); + } else { + return ( + "弃置" + get.cnNumber(-num) + "张牌并视为使用" + get.translation(links[0][2]) + ); } - else{ - return '弃置'+get.cnNumber(-num)+'张牌并视为使用'+get.translation(links[0][2]); - } - } + }, }, - ai:{ - pretao:true, - order(item,player){ - if(player.countCards('h')<4) return get.order({name:'sha'},player)+0.2; + ai: { + pretao: true, + order(item, player) { + if (player.countCards("h") < 4) return get.order({ name: "sha" }, player) + 0.2; return 1; }, - result:{ - player:1, + result: { + player: 1, }, }, - content_draw(){ - 'step 0' + content_draw() { + "step 0"; delete event.result.skill; - player.logSkill('dddbingjian'); + player.logSkill("dddbingjian"); player.draw(lib.skill.dddbingjian_backup.draw); - player.addTempSkill('dddbingjian_used'); - player.addMark('dddbingjian_used',1,false); - 'step 1' - player.chooseTarget('是否令一名其他角色摸等量的牌?',lib.filter.notMe).set('ai',target=>{ - var player=get.player(); - return get.effect(target,{name:'draw'},player,player); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + player.addTempSkill("dddbingjian_used"); + player.addMark("dddbingjian_used", 1, false); + "step 1"; + player + .chooseTarget("是否令一名其他角色摸等量的牌?", lib.filter.notMe) + .set("ai", (target) => { + var player = get.player(); + return get.effect(target, { name: "draw" }, player, player); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(lib.skill.dddbingjian_backup.draw); } }, - content_discard(){ - 'step 0' + content_discard() { + "step 0"; delete event.result.skill; - player.logSkill('dddbingjian'); + player.logSkill("dddbingjian"); player.discard(event.result.cards); - event.num=event.result.cards.length; - player.addTempSkill('dddbingjian_used'); - player.addMark('dddbingjian_used',1,false); - event.result.card={ - name:event.result.card.name, - isCard:true, - } - event.result.cards=[]; - 'step 1' - player.chooseTarget('是否弃置一名其他角色等量的牌?',lib.filter.notMe).set('ai',target=>{ - var player=get.player(),num=target.countCards('he')-get.event('num'); - if(num>=0) num=1; - else num=1-num/5; - var eff=get.effect(target,{name:'guohe_copy2'},player,player); - return eff/num; - }).set('num',event.num); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - player.discardPlayerCard(target,'he',true,event.num); + event.num = event.result.cards.length; + player.addTempSkill("dddbingjian_used"); + player.addMark("dddbingjian_used", 1, false); + event.result.card = { + name: event.result.card.name, + isCard: true, + }; + event.result.cards = []; + "step 1"; + player + .chooseTarget("是否弃置一名其他角色等量的牌?", lib.filter.notMe) + .set("ai", (target) => { + var player = get.player(), + num = target.countCards("he") - get.event("num"); + if (num >= 0) num = 1; + else num = 1 - num / 5; + var eff = get.effect(target, { name: "guohe_copy2" }, player, player); + return eff / num; + }) + .set("num", event.num); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + player.discardPlayerCard(target, "he", true, event.num); } }, - content_draw_old(){ - 'step 0' + content_draw_old() { + "step 0"; delete event.result.skill; - player.logSkill('dddbingjian'); - player.addTempSkill('dddbingjian_round','roundStart'); + player.logSkill("dddbingjian"); + player.addTempSkill("dddbingjian_round", "roundStart"); player.draw(lib.skill.dddbingjian_backup.draw); - 'step 1' - player.chooseTarget('是否令一名角色本轮内不能使用或打出'+get.translation(event.result.card)+'?').set('ai',function(target){ - var player=_status.event.player; - return -get.attitude(player,target)*get.threaten(target,player)*Math.sqrt(1+target.countCards('h')); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - player.chat('你不许使用'+get.translation(event.result.card)); - target.addTempSkill('dddbingjian_blocker','roundStart'); - target.markAuto('dddbingjian_blocker',[event.result.card.name]); + "step 1"; + player + .chooseTarget( + "是否令一名角色本轮内不能使用或打出" + get.translation(event.result.card) + "?" + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + -get.attitude(player, target) * + get.threaten(target, player) * + Math.sqrt(1 + target.countCards("h")) + ); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + player.chat("你不许使用" + get.translation(event.result.card)); + target.addTempSkill("dddbingjian_blocker", "roundStart"); + target.markAuto("dddbingjian_blocker", [event.result.card.name]); game.delayx(); } }, - content_discard_old(){ - 'step 0' + content_discard_old() { + "step 0"; delete event.result.skill; - player.logSkill('dddbingjian'); + player.logSkill("dddbingjian"); player.discard(event.result.cards); - event.result.card={ - name:event.result.card.name, - isCard:true, - } - event.result.cards=[]; - 'step 1' - var hs=player.countCards('h'); - if(!game.hasPlayer(current=>current.countCards('h')!=hs)){ + event.result.card = { + name: event.result.card.name, + isCard: true, + }; + event.result.cards = []; + "step 1"; + var hs = player.countCards("h"); + if (!game.hasPlayer((current) => current.countCards("h") != hs)) { event.finish(); + } else { + player + .chooseTarget( + "是否令一名角色将手牌调整至" + get.cnNumber(player.countCards("h")) + "张?", + function (card, player, target) { + return target.countCards("h") != player.countCards("h"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + num = target.countCards("h") - player.countCards("h"); + if (num > 0) + return get.attitude(player, target) * Math.sqrt(1 + Math.abs(num)); + return -get.attitude(player, target) * Math.sqrt(-num); + }); } - else{ - player.chooseTarget('是否令一名角色将手牌调整至'+get.cnNumber(player.countCards('h'))+'张?',function(card,player,target){ - return target.countCards('h')!=player.countCards('h'); - }).set('ai',function(target){ - var player=_status.event.player,num=target.countCards('h')-player.countCards('h'); - if(num>0) return get.attitude(player,target)*Math.sqrt(1+Math.abs(num)); - return -get.attitude(player,target)*Math.sqrt(-num); - }) - } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - var num=target.countCards('h')-player.countCards('h'); - if(num>0) target.chooseToDiscard('h',true,num); - else target.draw(Math.min(5,-num)); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + var num = target.countCards("h") - player.countCards("h"); + if (num > 0) target.chooseToDiscard("h", true, num); + else target.draw(Math.min(5, -num)); } }, - subSkill:{ - round:{charlotte:true}, - blocker:{ - charlotte:true, - mod:{ - cardEnabled(card,player){ - if(player.getStorage('dddbingjian_blocker').includes(card.name)) return false; + subSkill: { + round: { charlotte: true }, + blocker: { + charlotte: true, + mod: { + cardEnabled(card, player) { + if (player.getStorage("dddbingjian_blocker").includes(card.name)) + return false; }, - cardRespondable(card,player){ - if(player.getStorage('dddbingjian_blocker').includes(card.name)) return false; + cardRespondable(card, player) { + if (player.getStorage("dddbingjian_blocker").includes(card.name)) + return false; }, - cardSavable(card,player){ - if(player.getStorage('dddbingjian_blocker').includes(card.name)) return false; + cardSavable(card, player) { + if (player.getStorage("dddbingjian_blocker").includes(card.name)) + return false; }, }, - mark:true, - intro:{ - content:'本轮内不能使用或打出$', + mark: true, + intro: { + content: "本轮内不能使用或打出$", }, }, - used:{ - charlotte:true, - onremove:true, + used: { + charlotte: true, + onremove: true, }, - } + }, }, //梁习 - dddtongyu:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('hs')>0; + dddtongyu: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("hs") > 0; }, - viewAs:{ - name:'wugu', + viewAs: { + name: "wugu", }, - selectCard:[1,4], - filterCard(card){ - var suit=get.suit(card); - if(suit=='none') return false; - if(!ui.selected.cards.length) return true; - for(var card of ui.selected.cards){ - if(get.suit(card)==suit) return false; + selectCard: [1, 4], + filterCard(card) { + var suit = get.suit(card); + if (suit == "none") return false; + if (!ui.selected.cards.length) return true; + for (var card of ui.selected.cards) { + if (get.suit(card) == suit) return false; } return true; }, - complexCard:true, - position:'hs', - prompt:'将任意张花色不同的牌当做【五谷丰登】使用', - check(card){ - return 5-get.value(card); + complexCard: true, + position: "hs", + prompt: "将任意张花色不同的牌当做【五谷丰登】使用", + check(card) { + return 5 - get.value(card); }, - precontent(){ - if(!event.result.card.storage) event.result.card.storage={}; - event.result.card.storage.chooseDirection=true; - event.result.card.storage.extraCardsNum=event.result.cards.length; - player.addTempSkill('dddtongyu_effect'); + precontent() { + if (!event.result.card.storage) event.result.card.storage = {}; + event.result.card.storage.chooseDirection = true; + event.result.card.storage.extraCardsNum = event.result.cards.length; + player.addTempSkill("dddtongyu_effect"); }, - ai:{ - order:1, + ai: { + order: 1, }, - subSkill:{ - effect:{ - trigger:{global:'useCardToTargeted'}, - forced:true, - charlotte:true, - popup:false, - filter(event,player){ - return event.skill=='dddtongyu'&&event.isFirstTarget; + subSkill: { + effect: { + trigger: { global: "useCardToTargeted" }, + forced: true, + charlotte: true, + popup: false, + filter(event, player) { + return event.skill == "dddtongyu" && event.isFirstTarget; }, - content(){ - 'step 0' - event.targets=trigger.targets.slice().sortBySeat(_status.currentPhase||player); - 'step 1' - var target=targets.shift(); - event.target=target; - if(!target.isUnderControl(true)&&!target.isOnline()) game.delayx(); - target.chooseControl().set('choiceList',[ - '本回合不能使用或打出手牌', - '令'+get.translation(trigger.card)+'对自己无效', - ]).set('ai',function(){ - var player=_status.event.player; - var source=_status.event.getTrigger().player; - return player==source?1:0; - }); - 'step 2' - if(result.index==0){ - target.chat('接受五谷'); - target.addTempSkill('dddtongyu_blocker'); - game.log(target,'本回合不能使用或打出手牌') - } - else{ - target.chat('拒绝五谷'); + content() { + "step 0"; + event.targets = trigger.targets + .slice() + .sortBySeat(_status.currentPhase || player); + "step 1"; + var target = targets.shift(); + event.target = target; + if (!target.isUnderControl(true) && !target.isOnline()) game.delayx(); + target + .chooseControl() + .set("choiceList", [ + "本回合不能使用或打出手牌", + "令" + get.translation(trigger.card) + "对自己无效", + ]) + .set("ai", function () { + var player = _status.event.player; + var source = _status.event.getTrigger().player; + return player == source ? 1 : 0; + }); + "step 2"; + if (result.index == 0) { + target.chat("接受五谷"); + target.addTempSkill("dddtongyu_blocker"); + game.log(target, "本回合不能使用或打出手牌"); + } else { + target.chat("拒绝五谷"); trigger.excluded.add(target); - var evt=trigger.getParent(); - if(!evt.dddtongyu_targets) evt.dddtongyu_targets=[]; + var evt = trigger.getParent(); + if (!evt.dddtongyu_targets) evt.dddtongyu_targets = []; evt.dddtongyu_targets.add(target); - game.log(target,'令',trigger.card,'对其无效'); + game.log(target, "令", trigger.card, "对其无效"); } - if(targets.length) event.goto(1); + if (targets.length) event.goto(1); }, - group:'dddtongyu_give', + group: "dddtongyu_give", }, - give:{ - trigger:{player:'wuguRemained'}, - direct:true, - filter(event,player){ - if(event.skill!='dddtongyu'||event.remained.filterInD().length==0) return false; - var list=event.getParent().dddtongyu_targets; - return list.some(target=>target.isIn()); + give: { + trigger: { player: "wuguRemained" }, + direct: true, + filter(event, player) { + if (event.skill != "dddtongyu" || event.remained.filterInD().length == 0) + return false; + var list = event.getParent().dddtongyu_targets; + return list.some((target) => target.isIn()); }, - content(){ - 'step 0' - event.cards=trigger.remained.filterInD(); - player.chooseTarget('仝御:令一名角色获得'+get.translation(event.cards),function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',trigger.getParent().dddtongyu_targets).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att<3) return 0; - if(target.hasJudge('lebu')) att/=2; - if(target.hasSkillTag('nogain')) att/=10; - return att/(1+get.distance(player,target,'absolute')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddtongyu_give',target); - target.gain(cards,'gain2'); + content() { + "step 0"; + event.cards = trigger.remained.filterInD(); + player + .chooseTarget( + "仝御:令一名角色获得" + get.translation(event.cards), + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", trigger.getParent().dddtongyu_targets) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att < 3) return 0; + if (target.hasJudge("lebu")) att /= 2; + if (target.hasSkillTag("nogain")) att /= 10; + return att / (1 + get.distance(player, target, "absolute")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddtongyu_give", target); + target.gain(cards, "gain2"); } }, }, - blocker:{ - mark:true, - intro:{content:'本回合不能使用或打出手牌'}, - mod:{ - cardEnabled2(card){ + blocker: { + mark: true, + intro: { content: "本回合不能使用或打出手牌" }, + mod: { + cardEnabled2(card) { return false; }, }, }, }, }, - dddzhilian:{ - trigger:{global:'phaseEnd'}, - direct:true, - filter(event,player){ - var targets=game.filterPlayer2(function(current){ - return current.getHistory('useCard').length+current.getHistory('respond').length>0; + dddzhilian: { + trigger: { global: "phaseEnd" }, + direct: true, + filter(event, player) { + var targets = game.filterPlayer2(function (current) { + return ( + current.getHistory("useCard").length + current.getHistory("respond").length > 0 + ); }); - if(!targets.includes(player)||!targets.some(target=>target!=player&&target.hasSex('male'))) return false; - return targets.length==2&&!targets.some(target=>!target.isIn()); + if ( + !targets.includes(player) || + !targets.some((target) => target != player && target.hasSex("male")) + ) + return false; + return targets.length == 2 && !targets.some((target) => !target.isIn()); }, - content(){ - 'step 0' - var targets=game.filterPlayer(function(current){ - return current.getHistory('useCard').length+current.getHistory('respond').length>0; - }).sortBySeat(trigger.player); - event.targets=targets; - var choices=['摸牌']; - var prompt2='令'; - for(var i=0;i<2;i++){ - if(targets[i]==player) prompt2+='你'; - else prompt2+=get.translation(targets[i]); - if(i==0) prompt2+='和' + content() { + "step 0"; + var targets = game + .filterPlayer(function (current) { + return ( + current.getHistory("useCard").length + current.getHistory("respond").length > + 0 + ); + }) + .sortBySeat(trigger.player); + event.targets = targets; + var choices = ["摸牌"]; + var prompt2 = "令"; + for (var i = 0; i < 2; i++) { + if (targets[i] == player) prompt2 += "你"; + else prompt2 += get.translation(targets[i]); + if (i == 0) prompt2 += "和"; } - prompt2+='各摸一张牌'; - if(targets.some(target=>target.countCards('he')>0)){ - prompt2+='或各弃置一张牌'; - choices.push('弃牌'); + prompt2 += "各摸一张牌"; + if (targets.some((target) => target.countCards("he") > 0)) { + prompt2 += "或各弃置一张牌"; + choices.push("弃牌"); } - player.chooseControl(choices,'cancel2').set('prompt',get.prompt('dddzhilian')).set('prompt2',prompt2).set('ai',function(){ - var player=_status.event.player; - var targets=_status.event.getParent().targets.slice(0); - if(targets.includes(player)){ - targets.remove(player); - if(get.attitude(player,targets[0])>0) return 0; - if(targets[0].countCards('he')>0&&!targets[0].hasCard(card=>get.value(card,targets[0])<=0,'e')&&player.countCards('h','sha')>0) return 1; - return 'cancel2'; - } - else{ - var att1=get.attitude(player,targets[0]),att2=get.attitude(player,targets[1]); - if(get.sgn(att1)!=get.sgn(att2)) return 'cancel2'; - return att1>0?0:1; - } - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dddzhilian',targets); - if(result.control=='摸牌'){ + player + .chooseControl(choices, "cancel2") + .set("prompt", get.prompt("dddzhilian")) + .set("prompt2", prompt2) + .set("ai", function () { + var player = _status.event.player; + var targets = _status.event.getParent().targets.slice(0); + if (targets.includes(player)) { + targets.remove(player); + if (get.attitude(player, targets[0]) > 0) return 0; + if ( + targets[0].countCards("he") > 0 && + !targets[0].hasCard((card) => get.value(card, targets[0]) <= 0, "e") && + player.countCards("h", "sha") > 0 + ) + return 1; + return "cancel2"; + } else { + var att1 = get.attitude(player, targets[0]), + att2 = get.attitude(player, targets[1]); + if (get.sgn(att1) != get.sgn(att2)) return "cancel2"; + return att1 > 0 ? 0 : 1; + } + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dddzhilian", targets); + if (result.control == "摸牌") { game.asyncDraw(targets); game.delayex(); + } else { + for (var target of targets) target.chooseToDiscard("he", true); } - else{ - for(var target of targets) target.chooseToDiscard('he',true); - } - if(!targets.includes(player)) event.finish(); - } - else event.finish(); - 'step 2' - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if((evt.name=='lose'&&evt.position==ui.discardPile)||evt.name=='cardsDiscard') cards.addArray(evt.cards); + if (!targets.includes(player)) event.finish(); + } else event.finish(); + "step 2"; + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) + cards.addArray(evt.cards); }); - cards=cards.filter(card=>card.name=='sha'&&get.position(card,true)=='d'); - if(cards.length>0) player.gain(cards,'gain2'); - } + cards = cards.filter((card) => card.name == "sha" && get.position(card, true) == "d"); + if (cards.length > 0) player.gain(cards, "gain2"); + }, }, - dddjijian:{ - enable:'phaseUse', - usable:1, - filterCard:{name:'sha'}, - position:'h', - discard:false, - delay:false, - lose:false, - filter:(event,player)=>game.hasPlayer(current=>lib.skill.dddjijian.filterTarget(null,player,current)), - filterTarget:(card,player,target)=>(target!=player&&target.hasSex('male')), - content(){ - 'step 0' + dddjijian: { + enable: "phaseUse", + usable: 1, + filterCard: { name: "sha" }, + position: "h", + discard: false, + delay: false, + lose: false, + filter: (event, player) => + game.hasPlayer((current) => lib.skill.dddjijian.filterTarget(null, player, current)), + filterTarget: (card, player, target) => target != player && target.hasSex("male"), + content() { + "step 0"; player.showCards(cards); - player.give(cards,target); - 'step 1' - var cards=target.getCards('h'); - if(!cards.length) event.finish(); - else if(cards.length==1) event._result={bool:true,cards:cards}; - else target.chooseCard('h',true,[1,2],'请展示一至两张颜色相同的【杀】或普通锦囊牌',(card,player)=>{ - var color=get.color(card); - for(var cardx of ui.selected.cards){ - if(get.color(cardx)!=color) return false; - } - return get.name(card)=='sha'||get.type(card)=='trick'; - }).set('complexCard',true).set('ai',function(card){ - var player=_status.event.player,source=_status.event.getParent().player; - if(get.attitude(source,player)<=0) return -get.value(card); - var name=get.name(card),color=get.color(card); - if(name=='sha'||player.getUseValue(card)<=0||player.hasCard(card2=>{ - return card2!=card&&!ui.selected.cards.includes(card2)&&get.name(card2)==name; - })){ - if(!ui.selected.cards.length&&color=='black') return 1+Math.random(); - return Math.random(); - } - if(!ui.selected.cards.length||get.color(ui.selected.cards[0]=='red')){ - if(color=='black') return 0.2-player.getUseValue(card)/100+Math.random(); - } - return 0.1-player.getUseValue(card)/100; - }); - 'step 2' - if(result.bool){ - var cards=result.cards; - event.cards=cards; - target.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【赍剑】'); - event.usedName=[]; - event.targets=[player,target].sortBySeat(_status.currentPhase||player); - } - else event.finish(); - 'step 3' - var current=event.targets.shift(); - if(!current.isIn()){ + player.give(cards, target); + "step 1"; + var cards = target.getCards("h"); + if (!cards.length) event.finish(); + else if (cards.length == 1) event._result = { bool: true, cards: cards }; + else + target + .chooseCard( + "h", + true, + [1, 2], + "请展示一至两张颜色相同的【杀】或普通锦囊牌", + (card, player) => { + var color = get.color(card); + for (var cardx of ui.selected.cards) { + if (get.color(cardx) != color) return false; + } + return get.name(card) == "sha" || get.type(card) == "trick"; + } + ) + .set("complexCard", true) + .set("ai", function (card) { + var player = _status.event.player, + source = _status.event.getParent().player; + if (get.attitude(source, player) <= 0) return -get.value(card); + var name = get.name(card), + color = get.color(card); + if ( + name == "sha" || + player.getUseValue(card) <= 0 || + player.hasCard((card2) => { + return ( + card2 != card && + !ui.selected.cards.includes(card2) && + get.name(card2) == name + ); + }) + ) { + if (!ui.selected.cards.length && color == "black") + return 1 + Math.random(); + return Math.random(); + } + if (!ui.selected.cards.length || get.color(ui.selected.cards[0] == "red")) { + if (color == "black") + return 0.2 - player.getUseValue(card) / 100 + Math.random(); + } + return 0.1 - player.getUseValue(card) / 100; + }); + "step 2"; + if (result.bool) { + var cards = result.cards; + event.cards = cards; + target.showCards( + cards, + get.translation(player) + "对" + get.translation(target) + "发动了【赍剑】" + ); + event.usedName = []; + event.targets = [player, target].sortBySeat(_status.currentPhase || player); + } else event.finish(); + "step 3"; + var current = event.targets.shift(); + if (!current.isIn()) { event.goto(5); return; } - event.current=current; - var list=event.cards.filter(card=>{ - return !event.usedName.includes(get.name(card))&¤t.hasUseTarget({ - name:get.name(card), - nature:get.nature(card) + event.current = current; + var list = event.cards + .filter((card) => { + return ( + !event.usedName.includes(get.name(card)) && + current.hasUseTarget({ + name: get.name(card), + nature: get.nature(card), + }) + ); + }) + .map((card) => { + return [get.type(card), "", get.name(card), get.nature(card)]; }); - }).map(card=>{ - return [get.type(card),'',get.name(card),get.nature(card)]; - }); - if(!list.length) event.finish(); - else current.chooseButton(['赍剑:视为使用一张牌',[list,'vcard']],true).set('ai',function(button){ - return get.player().getUseValue({name:button.link[2],nature:button.link[3]}); - }); - 'step 4' - if(result.bool){ - var name=result.links[0][2]; + if (!list.length) event.finish(); + else + current + .chooseButton(["赍剑:视为使用一张牌", [list, "vcard"]], true) + .set("ai", function (button) { + return get.player().getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }); + "step 4"; + if (result.bool) { + var name = result.links[0][2]; event.usedName.add(name); - event.current.chooseUseTarget({name:name,nature:result.links[0][3],isCard:true},true,false); + event.current.chooseUseTarget( + { + name: name, + nature: result.links[0][3], + isCard: true, + }, + true, + false + ); } - 'step 5' - if(event.targets.length) event.goto(3); + "step 5"; + if (event.targets.length) event.goto(3); }, - ai:{ - order:4, - result:{ - player(player,target){ - if(get.attitude(player,target)>0&&player.hasCard(card=>get.name(card)=='sha','h')) return target.countCards('h'); - return 0.1/target.countCards('h'); + ai: { + order: 4, + result: { + player(player, target) { + if ( + get.attitude(player, target) > 0 && + player.hasCard((card) => get.name(card) == "sha", "h") + ) + return target.countCards("h"); + return 0.1 / target.countCards("h"); }, }, }, }, - dddjijian_old:{ - enable:'phaseUse', - usable:1, - filter:(event,player)=>game.hasPlayer(current=>lib.skill.dddjijian_old.filterTarget(null,player,current)), - filterTarget:(card,player,target)=>(target!=player&&target.hasSex('male')&&target.countCards('h')>0), - content(){ - 'step 0' - target.chooseCard('h',true,[1,2],'请展示一至两张手牌').set('ai',function(card){ - var player=_status.event.player,source=_status.event.getParent().player; - if(get.attitude(source,player)<=0) return -get.value(card); - var name=get.name(card),color=get.color(card); - if(name=='sha'||player.getUseValue(card)<=0||player.hasCard(card2=>{ - return card2!=card&&!ui.selected.cards.includes(card2)&&get.name(card2)==name; - })){ - if(!ui.selected.cards.length&&color=='black') return 1+Math.random(); + dddjijian_old: { + enable: "phaseUse", + usable: 1, + filter: (event, player) => + game.hasPlayer((current) => lib.skill.dddjijian_old.filterTarget(null, player, current)), + filterTarget: (card, player, target) => + target != player && target.hasSex("male") && target.countCards("h") > 0, + content() { + "step 0"; + target.chooseCard("h", true, [1, 2], "请展示一至两张手牌").set("ai", function (card) { + var player = _status.event.player, + source = _status.event.getParent().player; + if (get.attitude(source, player) <= 0) return -get.value(card); + var name = get.name(card), + color = get.color(card); + if ( + name == "sha" || + player.getUseValue(card) <= 0 || + player.hasCard((card2) => { + return ( + card2 != card && + !ui.selected.cards.includes(card2) && + get.name(card2) == name + ); + }) + ) { + if (!ui.selected.cards.length && color == "black") return 1 + Math.random(); return Math.random(); } - if(!ui.selected.cards.length||get.color(ui.selected.cards[0]=='red')){ - if(color=='black') return 0.2-player.getUseValue(card)/100+Math.random(); + if (!ui.selected.cards.length || get.color(ui.selected.cards[0] == "red")) { + if (color == "black") return 0.2 - player.getUseValue(card) / 100 + Math.random(); } - return 0.1-player.getUseValue(card)/100; + return 0.1 - player.getUseValue(card) / 100; }); - 'step 1' - if(result.bool){ - var cards=result.cards; - event.cards=cards; - target.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【赍剑】'); - if(!player.hasCard(card=>{ - if(_status.connectMode) return true; - return get.name(card,player)=='sha'; - },'h')) event.finish(); - } - else event.finish(); - 'step 2' - var colors=[]; - for(var card of cards) colors.add(get.color(card,target)); + "step 1"; + if (result.bool) { + var cards = result.cards; + event.cards = cards; + target.showCards( + cards, + get.translation(player) + "对" + get.translation(target) + "发动了【赍剑】" + ); + if ( + !player.hasCard((card) => { + if (_status.connectMode) return true; + return get.name(card, player) == "sha"; + }, "h") + ) + event.finish(); + } else event.finish(); + "step 2"; + var colors = []; + for (var card of cards) colors.add(get.color(card, target)); colors.sort(); - var str='若你给出的【杀】为' - for(var i=0;iget.name(card,player)=='sha', - '是否交给'+get.translation(target)+'一张【杀】?',str - ).set('colors',colors).set('ai',function(card){ - var player=_status.event.player,target=_status.event.getParent().target; - if(get.attitude(player,target)<0) return false; - if(!_status.event.colors.includes(get.color(card,player))) return 0; - if(game.hasNature(card)) return 1.2; - return 1; - }) - 'step 3' - if(result.bool){ - player.give(result.cards,target,'giveAuto'); - var num=0,color=get.color(result.cards[0],player); - for(var card of cards){ - if(get.color(card,target)==color) num++; + str += ",则其获得后续增益效果"; + player + .chooseCard( + "h", + (card, player) => get.name(card, player) == "sha", + "是否交给" + get.translation(target) + "一张【杀】?", + str + ) + .set("colors", colors) + .set("ai", function (card) { + var player = _status.event.player, + target = _status.event.getParent().target; + if (get.attitude(player, target) < 0) return false; + if (!_status.event.colors.includes(get.color(card, player))) return 0; + if (game.hasNature(card)) return 1.2; + return 1; + }); + "step 3"; + if (result.bool) { + player.give(result.cards, target, "giveAuto"); + var num = 0, + color = get.color(result.cards[0], player); + for (var card of cards) { + if (get.color(card, target) == color) num++; } - if(!num) event.finish(); - else event.num=num; - } - else event.finish(); - 'step 4' - var cards=target.getCards('h'); + if (!num) event.finish(); + else event.num = num; + } else event.finish(); + "step 4"; + var cards = target.getCards("h"); cards.removeArray(event.cards); - var names=[]; - for(var card of cards){ - var name=get.name(card,target),type=get.type(card); - if(type!='basic'&&type!='trick') continue; - if(name=='sha'){ - var natures=get.natureList(card,target); - for(var nature of natures){ - if(nature&&lib.nature.has(nature)) name+=('|'+nature); + var names = []; + for (var card of cards) { + var name = get.name(card, target), + type = get.type(card); + if (type != "basic" && type != "trick") continue; + if (name == "sha") { + var natures = get.natureList(card, target); + for (var nature of natures) { + if (nature && lib.nature.has(nature)) name += "|" + nature; } } names.push(name); } - if(!names.length) event.finish(); - else event.names=names; - 'step 5' + if (!names.length) event.finish(); + else event.names = names; + "step 5"; event.num--; - target.chooseButton([ - '是否视为使用一张牌?', - [event.names.map(name=>{ - if(name.indexOf('sha|')==0){ - return ['基本','','sha',name.slice(4).split('|')]; - } - return [get.type(name),'',name]; - }),'vcard'] - ]).set('filterButton',function(button){ - var card={ - name:button.link[2], - nature:button.link[3], - isCard:true, - },player=_status.event.player; - return player.hasUseTarget(card); - }).set('ai',function(button){ - var card={ - name:button.link[2], - nature:button.link[3], - isCard:true, - },player=_status.event.player; - return player.getUseValue(card); - }); - 'step 6' - if(result.bool){ - var card={ - name:result.links[0][2], - nature:result.links[0][3], - isCard:true, - } - target.chooseUseTarget(card,true,false); - if(event.num>0){ - var name=card.name; - if(name=='sha'){ - var natures=get.natureList(card,target); - for(var nature of natures){ - if(nature&&lib.nature.has(nature)) name+=('|'+nature); + target + .chooseButton([ + "是否视为使用一张牌?", + [ + event.names.map((name) => { + if (name.indexOf("sha|") == 0) { + return ["基本", "", "sha", name.slice(4).split("|")]; + } + return [get.type(name), "", name]; + }), + "vcard", + ], + ]) + .set("filterButton", function (button) { + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }, + player = _status.event.player; + return player.hasUseTarget(card); + }) + .set("ai", function (button) { + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }, + player = _status.event.player; + return player.getUseValue(card); + }); + "step 6"; + if (result.bool) { + var card = { + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }; + target.chooseUseTarget(card, true, false); + if (event.num > 0) { + var name = card.name; + if (name == "sha") { + var natures = get.natureList(card, target); + for (var nature of natures) { + if (nature && lib.nature.has(nature)) name += "|" + nature; } } event.names.remove(name); - if(event.names.length>0) event.goto(5); + if (event.names.length > 0) event.goto(5); } - } - else event.finish(); + } else event.finish(); }, - ai:{ - order:4, - result:{ - player(player,target){ - if(get.attitude(player,target)>0&&player.hasCard(card=>get.name(card)=='sha','h')) return target.countCards('h'); - return 0.1/target.countCards('h'); + ai: { + order: 4, + result: { + player(player, target) { + if ( + get.attitude(player, target) > 0 && + player.hasCard((card) => get.name(card) == "sha", "h") + ) + return target.countCards("h"); + return 0.1 / target.countCards("h"); }, }, }, }, - dddzhengjun:{ - trigger:{global:['damageEnd','loseHpEnd','recoverEnd','loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter']}, - filter(event,player){ - if(!player.isPhaseUsing()) return false; - if(event.name=='damage'||event.name=='loseHp'||event.name=='recover'){ - if(player.hasSkill('dddzhengjun_hp')) return false; - return event.player.getHp()==player.getHp(); + dddzhengjun: { + trigger: { + global: [ + "damageEnd", + "loseHpEnd", + "recoverEnd", + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + filter(event, player) { + if (!player.isPhaseUsing()) return false; + if (event.name == "damage" || event.name == "loseHp" || event.name == "recover") { + if (player.hasSkill("dddzhengjun_hp")) return false; + return event.player.getHp() == player.getHp(); } - const info=get.info('dddzhengjun'); - const hs_check=info.hs_check,es_check=info.es_check; - return game.hasPlayer(target=>{ - if(event.getg&&event.getg(target)&&event.getg(target).length&&hs_check(player,target)) return true; - const evt=event.getl(target); - if(evt&&evt.hs&&evt.hs.length&&hs_check(player,target)) return true; - if(event.name=='equip'&&event.player==target&&(!evt||evt.cards.length!=1)&&es_check(player,target)) return true; - return evt&&evt.es&&evt.es.length&&es_check(player,target); + const info = get.info("dddzhengjun"); + const hs_check = info.hs_check, + es_check = info.es_check; + return game.hasPlayer((target) => { + if ( + event.getg && + event.getg(target) && + event.getg(target).length && + hs_check(player, target) + ) + return true; + const evt = event.getl(target); + if (evt && evt.hs && evt.hs.length && hs_check(player, target)) return true; + if ( + event.name == "equip" && + event.player == target && + (!evt || evt.cards.length != 1) && + es_check(player, target) + ) + return true; + return evt && evt.es && evt.es.length && es_check(player, target); }); }, - hs_check(player,target){ - return !player.hasSkill('dddzhengjun_hs')&&target.countCards('h')==player.countCards('h'); + hs_check(player, target) { + return ( + !player.hasSkill("dddzhengjun_hs") && target.countCards("h") == player.countCards("h") + ); }, - es_check(player,target){ - return !player.hasSkill('dddzhengjun_es')&&target.countCards('e')==player.countCards('e'); + es_check(player, target) { + return ( + !player.hasSkill("dddzhengjun_es") && target.countCards("e") == player.countCards("e") + ); }, - async cost(event,trigger,player){ - if(trigger.name=='damage'||trigger.name=='loseHp'||trigger.name=='recover'){ - let list=['失去体力','cancel2']; - if(trigger.player.isDamaged()) list.unshift('回复体力'); - const {result:{control}}=await player.chooseControl(list) - .set('prompt',get.prompt('dddzhengjun',trigger.player)) - .set('prompt2','令'+get.translation(event.player)+'执行其中一项') - .set('ai',()=>{ - const player=get.event('player'),target=get.event().getTrigger().player; - if(get.event('controls').includes('回复体力')&&get.recoverEffect(target,player,player)>0) return '回复体力'; - return get.effect(target,{name:'losehp'},player,player)>0?'失去体力':'cancel2'; - }); - event.result={ - bool:control!='cancel2', - targets:[trigger.player], - cost_data:control, + async cost(event, trigger, player) { + if (trigger.name == "damage" || trigger.name == "loseHp" || trigger.name == "recover") { + let list = ["失去体力", "cancel2"]; + if (trigger.player.isDamaged()) list.unshift("回复体力"); + const { + result: { control }, + } = await player + .chooseControl(list) + .set("prompt", get.prompt("dddzhengjun", trigger.player)) + .set("prompt2", "令" + get.translation(event.player) + "执行其中一项") + .set("ai", () => { + const player = get.event("player"), + target = get.event().getTrigger().player; + if ( + get.event("controls").includes("回复体力") && + get.recoverEffect(target, player, player) > 0 + ) + return "回复体力"; + return get.effect(target, { name: "losehp" }, player, player) > 0 + ? "失去体力" + : "cancel2"; + }); + event.result = { + bool: control != "cancel2", + targets: [trigger.player], + cost_data: control, }; - } - else{ - let map={}; - const hs_targets=game.filterPlayer(target=>{ - if(!get.info('dddzhengjun').hs_check(player,target)) return false; - if(trigger.getg&&trigger.getg(target)&&trigger.getg(target).length) return true; - const evt=trigger.getl(target); - return evt&&evt.hs&&evt.hs.length; + } else { + let map = {}; + const hs_targets = game.filterPlayer((target) => { + if (!get.info("dddzhengjun").hs_check(player, target)) return false; + if (trigger.getg && trigger.getg(target) && trigger.getg(target).length) + return true; + const evt = trigger.getl(target); + return evt && evt.hs && evt.hs.length; }); - const es_targets=game.filterPlayer(target=>{ - if(!get.info('dddzhengjun').es_check(player,target)) return false; - const evt=trigger.getl(target); - if(trigger.name=='equip'&&trigger.player==target&&(!evt||evt.cards.length!=1)) return true; - return evt&&evt.es&&evt.es.length; + const es_targets = game.filterPlayer((target) => { + if (!get.info("dddzhengjun").es_check(player, target)) return false; + const evt = trigger.getl(target); + if ( + trigger.name == "equip" && + trigger.player == target && + (!evt || evt.cards.length != 1) + ) + return true; + return evt && evt.es && evt.es.length; }); - if(hs_targets.length){ + if (hs_targets.length) { let target; - if(hs_targets.length==1) target=hs_targets[0]; - else{ - let targets=await player.chooseTarget(get.prompt('dddzhengjun'),'令其中一名角色摸一张牌或弃置一张牌',(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('ai',target=>{ - const player=get.event('player'); - return Math.max(get.effect(target,{name:'guohe_copy2'},target,player),get.effect(target,{name:'draw'},player,player)); - }).set('targets',hs_targets).forResultTargets(); - if(targets&&targets.length) target=targets[0]; + if (hs_targets.length == 1) target = hs_targets[0]; + else { + let targets = await player + .chooseTarget( + get.prompt("dddzhengjun"), + "令其中一名角色摸一张牌或弃置一张牌", + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return Math.max( + get.effect(target, { name: "guohe_copy2" }, target, player), + get.effect(target, { name: "draw" }, player, player) + ); + }) + .set("targets", hs_targets) + .forResultTargets(); + if (targets && targets.length) target = targets[0]; } - if(target){ - let list=['摸牌']; - if(target.countCards('h')) list.push('弃牌'); - const {result:{control}}=await player.chooseControl(list,'cancel2') - .set('prompt',get.prompt('dddzhengjun',target)) - .set('prompt2','令'+get.translation(target)+'执行其中一项') - .set('ai',()=>{ - const player=get.event('player'),target=get.event().getTrigger().player; - if(get.event('controls').includes('弃牌')&&get.effect(target,{name:'guohe_copy2'},player,player)>0) return '弃牌'; - return get.effect(target,{name:'draw'},player,player)>0?'摸牌':'cancel2'; - }); - if(control!='cancel2'){ - map.hs_target=[target,control]; + if (target) { + let list = ["摸牌"]; + if (target.countCards("h")) list.push("弃牌"); + const { + result: { control }, + } = await player + .chooseControl(list, "cancel2") + .set("prompt", get.prompt("dddzhengjun", target)) + .set("prompt2", "令" + get.translation(target) + "执行其中一项") + .set("ai", () => { + const player = get.event("player"), + target = get.event().getTrigger().player; + if ( + get.event("controls").includes("弃牌") && + get.effect(target, { name: "guohe_copy2" }, player, player) > 0 + ) + return "弃牌"; + return get.effect(target, { name: "draw" }, player, player) > 0 + ? "摸牌" + : "cancel2"; + }); + if (control != "cancel2") { + map.hs_target = [target, control]; } } } - if(es_targets.length){ + if (es_targets.length) { let target; - if(hs_targets.length==1){ - const {result:{bool}}=await player.chooseBool() - .set('prompt',get.prompt('dddzhengjun',hs_targets[0])) - .set('prompt2','移动'+get.translation(hs_targets[0])+'的一张装备牌') - .set('choice',()=>player.canMoveCard(true,true,hs_targets[0])); - if(bool) target=hs_targets[0]; + if (hs_targets.length == 1) { + const { + result: { bool }, + } = await player + .chooseBool() + .set("prompt", get.prompt("dddzhengjun", hs_targets[0])) + .set("prompt2", "移动" + get.translation(hs_targets[0]) + "的一张装备牌") + .set("choice", () => player.canMoveCard(true, true, hs_targets[0])); + if (bool) target = hs_targets[0]; + } else { + let targets = await player + .chooseTarget( + get.prompt("dddzhengjun"), + "移动其中一名角色的一张装备牌", + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return player.canMoveCard(true, true, target) ? 1 + Math.random() : 0; + }) + .set("targets", es_targets) + .forResultTargets(); + if (targets && targets.length) target = targets[0]; } - else{ - let targets=await player.chooseTarget(get.prompt('dddzhengjun'),'移动其中一名角色的一张装备牌',(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('ai',target=>{ - const player=get.event('player'); - return player.canMoveCard(true,true,target)?(1+Math.random()):0; - }).set('targets',es_targets).forResultTargets(); - if(targets&&targets.length) target=targets[0]; - } - if(target){ - map.es_target=target; + if (target) { + map.es_target = target; } } - event.result={ - bool:(map.hs_target||map.es_target), - targets:[(map.hs_target||[])[0]].concat(map.es_target?[map.es_target]:[]), - cost_data:map, + event.result = { + bool: map.hs_target || map.es_target, + targets: [(map.hs_target || [])[0]].concat(map.es_target ? [map.es_target] : []), + cost_data: map, }; } }, - async content(event,trigger,player){ - const data=event.cost_data; - if(trigger.name=='damage'||trigger.name=='loseHp'||trigger.name=='recover'){ - player.addTempSkill('dddzhengjun_hp','phaseUseAfter'); - await trigger.player[data=='回复体力'?'recover':'loseHp'](); - } - else{ - if(data.hs_target){ - player.addTempSkill('dddzhengjun_hs','phaseUseAfter'); - if(data.hs_target[1]=='摸牌') await data.hs_target[0].draw(); - else await data.hs_target[0].chooseToDiscard('he',true); + async content(event, trigger, player) { + const data = event.cost_data; + if (trigger.name == "damage" || trigger.name == "loseHp" || trigger.name == "recover") { + player.addTempSkill("dddzhengjun_hp", "phaseUseAfter"); + await trigger.player[data == "回复体力" ? "recover" : "loseHp"](); + } else { + if (data.hs_target) { + player.addTempSkill("dddzhengjun_hs", "phaseUseAfter"); + if (data.hs_target[1] == "摸牌") await data.hs_target[0].draw(); + else await data.hs_target[0].chooseToDiscard("he", true); } - if(data.es_target){ - player.addTempSkill('dddzhengjun_es','phaseUseAfter'); - await player.moveCard(true,data.es_target); + if (data.es_target) { + player.addTempSkill("dddzhengjun_es", "phaseUseAfter"); + await player.moveCard(true, data.es_target); } } }, - subSkill:{ - hs:{charlotte:true}, - es:{charlotte:true}, - hp:{charlotte:true}, + subSkill: { + hs: { charlotte: true }, + es: { charlotte: true }, + hp: { charlotte: true }, }, }, - dddxianxi:{ - trigger:{ - player:"useCard2", + dddxianxi: { + trigger: { + player: "useCard2", }, - direct:true, - filter(event,player){ - if(event.card.name!='sha'||!player.isPhaseUsing()) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); + direct: true, + filter(event, player) { + if (event.card.name != "sha" || !player.isPhaseUsing()) return false; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) + ); }); }, - content(){ - 'step 0' - player.chooseTarget( - get.prompt('dddxianxi'), - '为'+get.translation(trigger.card)+'增加任意个目标', - function(card,player,target){ - var event=_status.event.getTrigger(); - return !event.targets.includes(target)&&lib.filter.targetEnabled2(event.card,player,target); - }, - [1,Infinity] - ).set('ai',function(target){ - var evt=_status.event.getTrigger(); - if(get.damageEffect(target,evt.player,evt.player)<0) return 0; - return get.effect(target,evt.card,evt.player,evt.player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - event.targets=targets; - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - player.logSkill('dddxianxi',targets); + content() { + "step 0"; + player + .chooseTarget( + get.prompt("dddxianxi"), + "为" + get.translation(trigger.card) + "增加任意个目标", + function (card, player, target) { + var event = _status.event.getTrigger(); + return ( + !event.targets.includes(target) && + lib.filter.targetEnabled2(event.card, player, target) + ); + }, + [1, Infinity] + ) + .set("ai", function (target) { + var evt = _status.event.getTrigger(); + if (get.damageEffect(target, evt.player, evt.player) < 0) return 0; + return get.effect(target, evt.card, evt.player, evt.player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + event.targets = targets; + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + player.logSkill("dddxianxi", targets); trigger.targets.addArray(targets); - if(!trigger._dddxianxi_map) trigger._dddxianxi_map={}; - trigger._dddxianxi_map[player.playerid]=targets.slice(0); - player.addTempSkill('dddxianxi_delay'); + if (!trigger._dddxianxi_map) trigger._dddxianxi_map = {}; + trigger._dddxianxi_map[player.playerid] = targets.slice(0); + player.addTempSkill("dddxianxi_delay"); }, - subSkill:{ - delay:{ - charlotte:true, - trigger:{ - player:"useCardAfter", + subSkill: { + delay: { + charlotte: true, + trigger: { + player: "useCardAfter", }, - forced:true, - filter(event,player){ - if(!event._dddxianxi_map||!event._dddxianxi_map[player.playerid]) return false; - for(var target of event._dddxianxi_map[player.playerid]){ - if(!target.hasHistory('damage',function(evt){ - return evt.card==event.card; - })) return true; + forced: true, + filter(event, player) { + if (!event._dddxianxi_map || !event._dddxianxi_map[player.playerid]) return false; + for (var target of event._dddxianxi_map[player.playerid]) { + if ( + !target.hasHistory("damage", function (evt) { + return evt.card == event.card; + }) + ) + return true; } return false; }, - content(){ - 'step 0' - var targets=trigger._dddxianxi_map[player.playerid].filter(function(target){ - return !target.hasHistory('damage',function(evt){ - return evt.card==trigger.card; + content() { + "step 0"; + var targets = trigger._dddxianxi_map[player.playerid] + .filter(function (target) { + return !target.hasHistory("damage", function (evt) { + return evt.card == trigger.card; + }); + }) + .sortBySeat(); + event.targets = targets; + var num = targets.length; + player + .chooseToDiscard( + "he", + num, + "险袭:选择弃置" + get.cnNumber(num) + "张牌", + "然后对" + + get.translation(targets) + + "各造成1点伤害。或点击「取消」,改为摸" + + get.cnNumber(num) + + "张牌并失去1点体力" + ) + .set("ai", function (card) { + return 7 - get.value(card); }); - }).sortBySeat(); - event.targets=targets; - var num=targets.length; - player.chooseToDiscard('he',num,'险袭:选择弃置'+get.cnNumber(num)+'张牌','然后对'+get.translation(targets)+'各造成1点伤害。或点击「取消」,改为摸'+get.cnNumber(num)+'张牌并失去1点体力').set('ai',function(card){ - return 7-get.value(card); - }) - 'step 1' - if(result.bool){ - for(var i of targets){ + "step 1"; + if (result.bool) { + for (var i of targets) { player.line(i); i.damage(); } - } - else{ + } else { player.draw(targets.length); player.loseHp(); } }, - sub:true, + sub: true, }, }, }, - dddlingyong:{ - trigger:{ - global:["phaseZhunbeiSkipped","phaseZhunbeiCancelled","phaseDrawSkipped","phaseDrawCancelled","phaseJudgeSkipped","phaseJudgeCancelled","phaseUseSkipped","phaseUseCancelled","phaseDiscardSkipped","phaseDiscardCancelled","phaseJieshuSkipped","phaseJieshuCancelled"], + dddlingyong: { + trigger: { + global: [ + "phaseZhunbeiSkipped", + "phaseZhunbeiCancelled", + "phaseDrawSkipped", + "phaseDrawCancelled", + "phaseJudgeSkipped", + "phaseJudgeCancelled", + "phaseUseSkipped", + "phaseUseCancelled", + "phaseDiscardSkipped", + "phaseDiscardCancelled", + "phaseJieshuSkipped", + "phaseJieshuCancelled", + ], }, - frequent:true, - content (){ - 'step 0' - player.judge(function(card){ - var name=get.name(card,false); - if(name=='sha') return -2; - return 2; - }).set('callback',function(){ - if(event.judgeResult.name!='sha'){ - var card=event.judgeResult.card; - if(get.position(card,true)=='o') player.chooseUseTarget(card); - } - }).judge2=function(result){ + frequent: true, + content() { + "step 0"; + player + .judge(function (card) { + var name = get.name(card, false); + if (name == "sha") return -2; + return 2; + }) + .set("callback", function () { + if (event.judgeResult.name != "sha") { + var card = event.judgeResult.card; + if (get.position(card, true) == "o") player.chooseUseTarget(card); + } + }).judge2 = function (result) { return result.bool; }; - 'step 1' - if(result.bool){ - player.chooseBool('是否继续进行【灵涌】判定?').set('frequentSkill','dddlingyong'); - } - else event.finish(); - 'step 2' - if(result.bool) event.goto(0); + "step 1"; + if (result.bool) { + player.chooseBool("是否继续进行【灵涌】判定?").set("frequentSkill", "dddlingyong"); + } else event.finish(); + "step 2"; + if (result.bool) event.goto(0); }, }, - "dddxuxiao":{ - trigger:{ - global:["loseAfter","loseAsyncAfter"], + dddxuxiao: { + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - direct:true, - filter (event,player){ - if(event.type!='discard') return false; - var cards=event.getd(); - for(var i of cards){ - if(get.position(i,true)=='d'&&get.color(i,false)=='black'&&get.type(i,null,true)=='basic'){ - var card=get.autoViewAs({name:'bingliang'},[i]); - if(game.hasPlayer(function(current){ - return current.canAddJudge(card); - })) return true; + direct: true, + filter(event, player) { + if (event.type != "discard") return false; + var cards = event.getd(); + for (var i of cards) { + if ( + get.position(i, true) == "d" && + get.color(i, false) == "black" && + get.type(i, null, true) == "basic" + ) { + var card = get.autoViewAs({ name: "bingliang" }, [i]); + if ( + game.hasPlayer(function (current) { + return current.canAddJudge(card); + }) + ) + return true; } } return false; }, - content (){ - 'step 0' - if(!event.cards) event.cards=[]; - var cards=trigger.getd().filter(function(i){ - if(!event.cards.includes(i)&&get.position(i,true)=='d'&&get.color(i,false)=='black'&&get.type(i,null,true)=='basic'){ - var card=get.autoViewAs({name:'bingliang'},[i]); - if(game.hasPlayer(function(current){ - return current.canAddJudge(card); - })) return true; + content() { + "step 0"; + if (!event.cards) event.cards = []; + var cards = trigger.getd().filter(function (i) { + if ( + !event.cards.includes(i) && + get.position(i, true) == "d" && + get.color(i, false) == "black" && + get.type(i, null, true) == "basic" + ) { + var card = get.autoViewAs({ name: "bingliang" }, [i]); + if ( + game.hasPlayer(function (current) { + return current.canAddJudge(card); + }) + ) + return true; } return false; }); - if(cards.length){ - player.chooseButton([get.prompt('dddxuxiao'),cards]); - } - else event.finish(); - 'step 1' - if(result.bool){ - var card=result.links[0]; + if (cards.length) { + player.chooseButton([get.prompt("dddxuxiao"), cards]); + } else event.finish(); + "step 1"; + if (result.bool) { + var card = result.links[0]; event.cards.push(card); - event.card=card; - player.chooseTarget(true,'请选择【兵粮寸断】的目标','将'+get.translation(card)+'置于一名角色的判定区内,然后其摸两张牌',function(card,player,target){ - var card=get.autoViewAs({name:'bingliang'},[_status.event.card]); - return target.canAddJudge(card); - }).set('card',card).set('ai',function(target){ - var card=get.autoViewAs({name:'bingliang'},[_status.event.card]),player=_status.event.player; - return get.attitude(player,target)+Math.max(0,get.effect(target,card,player,player)) - }) + event.card = card; + player + .chooseTarget( + true, + "请选择【兵粮寸断】的目标", + "将" + get.translation(card) + "置于一名角色的判定区内,然后其摸两张牌", + function (card, player, target) { + var card = get.autoViewAs({ name: "bingliang" }, [_status.event.card]); + return target.canAddJudge(card); + } + ) + .set("card", card) + .set("ai", function (target) { + var card = get.autoViewAs({ name: "bingliang" }, [_status.event.card]), + player = _status.event.player; + return ( + get.attitude(player, target) + + Math.max(0, get.effect(target, card, player, player)) + ); + }); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddxuxiao',target); - target.addJudge({name:'bingliang'},[card]); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddxuxiao", target); + target.addJudge({ name: "bingliang" }, [card]); target.draw(2); event.goto(0); } }, }, - dddxuyu:{ - trigger:{ - player:"useCardAfter", + dddxuyu: { + trigger: { + player: "useCardAfter", }, - content(){ + content() { player.draw(); - player.when({player:'useCardAfter',global:'phaseAfter'}).filter(evt=>evt!=trigger).then(()=>{ - if(trigger.name=='useCard') player.chooseToDiscard('he',true); - }); + player + .when({ player: "useCardAfter", global: "phaseAfter" }) + .filter((evt) => evt != trigger) + .then(() => { + if (trigger.name == "useCard") player.chooseToDiscard("he", true); + }); }, }, - dddshijian:{ - trigger:{ - global:'useCardAfter', + dddshijian: { + trigger: { + global: "useCardAfter", }, - filter(event,player){ - if(player==event.player) return false; - const evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - return event.player.getHistory('useCard',evtx=>{ - return evtx.getParent('phaseUse')==evt; - },event).length==2; + filter(event, player) { + if (player == event.player) return false; + const evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + return ( + event.player.getHistory( + "useCard", + (evtx) => { + return evtx.getParent("phaseUse") == evt; + }, + event + ).length == 2 + ); }, - direct:true, - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - let result=yield player.chooseCard('he',get.prompt('dddshijian',target),`交给${get.translation(target)}一张牌,然后其本回合使用下一张牌指定目标时,你令此牌额外结算一次或摸一张牌。`).set('ai',card=>{ - if(get.event('goon')) return 6-get.value(card); - return 0; - }).set('goon',get.attitude(player,target)>0&&target.hasCard(card=>target.hasValueTarget(card))); - if(!result.bool) return event.finish(); - player.logSkill('dddshijian',target); - player.give(result.cards,target); - player.addTempSkill('dddshijian_extra'); - player.markAuto('dddshijian_extra',target); + direct: true, + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + let result = yield player + .chooseCard( + "he", + get.prompt("dddshijian", target), + `交给${get.translation( + target + )}一张牌,然后其本回合使用下一张牌指定目标时,你令此牌额外结算一次或摸一张牌。` + ) + .set("ai", (card) => { + if (get.event("goon")) return 6 - get.value(card); + return 0; + }) + .set( + "goon", + get.attitude(player, target) > 0 && + target.hasCard((card) => target.hasValueTarget(card)) + ); + if (!result.bool) return event.finish(); + player.logSkill("dddshijian", target); + player.give(result.cards, target); + player.addTempSkill("dddshijian_extra"); + player.markAuto("dddshijian_extra", target); }, - subSkill:{ - extra:{ - trigger:{global:'useCardToPlayer'}, - filter(event,player){ - if(!event.isFirstTarget) return false; - return player.getStorage('dddshijian_extra').includes(event.player); + subSkill: { + extra: { + trigger: { global: "useCardToPlayer" }, + filter(event, player) { + if (!event.isFirstTarget) return false; + return player.getStorage("dddshijian_extra").includes(event.player); }, - charlotte:true, - forced:true, - onremove:true, - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - if(trigger.targets&&trigger.targets.length){ - let result=yield player.chooseControl(['额外结算','摸一张牌']).set('prompt','实荐:请选择一项').set('prompt2',`令${get.translation(trigger.card)}额外结算一次,或摸一张牌`).set('ai',()=>{ - return get.event('choice'); - }).set('choice',function(){ - if(trigger.card.name==='tiesuo'||!['basic','trick'].includes(get.type(trigger.card))) return 1; - if(trigger.targets.reduce((p,c)=>{ - return p+get.effect(c,trigger.card,target,_status.event.player); - },0)>=get.effect(player,{name:'draw'},player,_status.event.player)) return 0; - return 1; - }()); - if(result.index==0){ + charlotte: true, + forced: true, + onremove: true, + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + if (trigger.targets && trigger.targets.length) { + let result = yield player + .chooseControl(["额外结算", "摸一张牌"]) + .set("prompt", "实荐:请选择一项") + .set( + "prompt2", + `令${get.translation(trigger.card)}额外结算一次,或摸一张牌` + ) + .set("ai", () => { + return get.event("choice"); + }) + .set( + "choice", + (function () { + if ( + trigger.card.name === "tiesuo" || + !["basic", "trick"].includes(get.type(trigger.card)) + ) + return 1; + if ( + trigger.targets.reduce((p, c) => { + return ( + p + + get.effect( + c, + trigger.card, + target, + _status.event.player + ) + ); + }, 0) >= + get.effect( + player, + { name: "draw" }, + player, + _status.event.player + ) + ) + return 0; + return 1; + })() + ); + if (result.index == 0) { trigger.getParent().effectCount++; - game.log(player,'令',trigger.card,'额外结算一次'); - } - else player.draw(); - } - else player.draw(); - player.removeSkill('dddshijian_extra'); - } - } - }, - }, - dddxuyu_old:{ - trigger:{ - player:"useCardAfter", - }, - filter (event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - return player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; - },event).length==1; - }, - content (){ - player.draw(2); - player.addTempSkill('dddxuyu_old_discard','phaseUseAfter'); - }, - subSkill:{ - discard:{ - trigger:{ - player:"useCardAfter", + game.log(player, "令", trigger.card, "额外结算一次"); + } else player.draw(); + } else player.draw(); + player.removeSkill("dddshijian_extra"); }, - filter (event,player){ - if(!player.countCards('he')) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - return player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; - },event).length==3; - }, - forced:true, - charlotte:true, - content (){ - player.chooseToDiscard('he',true); - }, - sub:true, }, }, }, - dddshijian_old:{ - trigger:{ - global:"useCardAfter", + dddxuyu_old: { + trigger: { + player: "useCardAfter", }, - filter (event,player){ - if(player==event.player) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - return event.player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; - },event).length==3; + filter(event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + return ( + player.getHistory( + "useCard", + function (evtx) { + return evtx.getParent("phaseUse") == evt; + }, + event + ).length == 1 + ); }, - logTarget:"player", - check(event,player){ - return get.attitude(player,event.player)>0; + content() { + player.draw(2); + player.addTempSkill("dddxuyu_old_discard", "phaseUseAfter"); }, - content (){ + subSkill: { + discard: { + trigger: { + player: "useCardAfter", + }, + filter(event, player) { + if (!player.countCards("he")) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + return ( + player.getHistory( + "useCard", + function (evtx) { + return evtx.getParent("phaseUse") == evt; + }, + event + ).length == 3 + ); + }, + forced: true, + charlotte: true, + content() { + player.chooseToDiscard("he", true); + }, + sub: true, + }, + }, + }, + dddshijian_old: { + trigger: { + global: "useCardAfter", + }, + filter(event, player) { + if (player == event.player) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + return ( + event.player.getHistory( + "useCard", + function (evtx) { + return evtx.getParent("phaseUse") == evt; + }, + event + ).length == 3 + ); + }, + logTarget: "player", + check(event, player) { + return get.attitude(player, event.player) > 0; + }, + content() { trigger.player.draw(); - player.addTempSkill('dddshijian_old_draw','phaseUseAfter'); + player.addTempSkill("dddshijian_old_draw", "phaseUseAfter"); }, - subSkill:{ - draw:{ - trigger:{ - global:"useCardAfter", + subSkill: { + draw: { + trigger: { + global: "useCardAfter", }, - filter (event,player){ - if(!event.player.countCards('he')) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - return event.player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; - },event).length==4; + filter(event, player) { + if (!event.player.countCards("he")) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + return ( + event.player.getHistory( + "useCard", + function (evtx) { + return evtx.getParent("phaseUse") == evt; + }, + event + ).length == 4 + ); }, - forced:true, - charlotte:true, - content (){ + forced: true, + charlotte: true, + content() { player.draw(2); }, - sub:true, + sub: true, }, }, }, - dddtaisi:{ - trigger:{ - global:"phaseEnd", + dddtaisi: { + trigger: { + global: "phaseEnd", }, - direct:true, - filter (event,player){ - if(!game.getGlobalHistory('changeHp').some(evt=>evt.player==player)) return false; - return game.getGlobalHistory('cardMove').some(function(evt){ - if(evt.name!='cardsDiscard'){ - if(evt.name!='lose'||evt.position!=ui.discardPile) return false; + direct: true, + filter(event, player) { + if (!game.getGlobalHistory("changeHp").some((evt) => evt.player == player)) return false; + return game.getGlobalHistory("cardMove").some(function (evt) { + if (evt.name != "cardsDiscard") { + if (evt.name != "lose" || evt.position != ui.discardPile) return false; } - return evt.cards.some(card=>get.position(card,true)=='d'); + return evt.cards.some((card) => get.position(card, true) == "d"); }); }, - content (){ - 'step 0' - player.chooseTarget(get.prompt('dddtaisi'),'你可以令一名角色获得一张于本回合内进入弃牌堆的牌。若该角色于本回合内对你造成过伤害,则你摸两张牌。').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(player.hasHistory('damage',evt=>evt.source==target)) return 10+att; - return att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddtaisi',target); - event.target=target; - } - else event.finish(); - 'step 2' - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='cardsDiscard'){ - if(evt.name!='lose'||evt.position!=ui.discardPile) return false; + content() { + "step 0"; + player + .chooseTarget( + get.prompt("dddtaisi"), + "你可以令一名角色获得一张于本回合内进入弃牌堆的牌。若该角色于本回合内对你造成过伤害,则你摸两张牌。" + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (player.hasHistory("damage", (evt) => evt.source == target)) return 10 + att; + return att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddtaisi", target); + event.target = target; + } else event.finish(); + "step 2"; + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "cardsDiscard") { + if (evt.name != "lose" || evt.position != ui.discardPile) return false; } - cards.addArray(evt.cards.filter(card=>get.position(card,true)=='d')); + cards.addArray(evt.cards.filter((card) => get.position(card, true) == "d")); }); - if(!cards.length) event.finish(); - else if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton(['令'+get.translation(target)+'获得一张牌',cards],true).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().target; - var att=get.attitude(player,target)-0.1; - return get.sgn(att)*get.value(button.link,target); - }); - 'step 3' - if(result.bool){ - target.gain(result.links,'gain2'); - } - else event.finish(); - 'step 4' - if(player.hasHistory('damage',evt=>evt.source==target)) player.draw(2); + if (!cards.length) event.finish(); + else if (cards.length == 1) event._result = { bool: true, links: cards }; + else + player + .chooseButton(["令" + get.translation(target) + "获得一张牌", cards], true) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target; + var att = get.attitude(player, target) - 0.1; + return get.sgn(att) * get.value(button.link, target); + }); + "step 3"; + if (result.bool) { + target.gain(result.links, "gain2"); + } else event.finish(); + "step 4"; + if (player.hasHistory("damage", (evt) => evt.source == target)) player.draw(2); }, }, - dddquche:{ - enable:"phaseUse", - limited:true, - skillAnimation:true, - animationColor:"thunder", - filter (event,player){ - return player.hasCard({color:'red'},'he'); + dddquche: { + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + return player.hasCard({ color: "red" }, "he"); }, - filterCard:{ - color:"red", + filterCard: { + color: "red", }, - filterTarget (card,player,target){ - return player!=target; + filterTarget(card, player, target) { + return player != target; }, - discard:false, - delay:false, - lose:false, - content (){ - 'step 0' - event.count=1; - player.awakenSkill('dddquche'); - player.addTempSkill('dddquche_effect'); - player.addMark('dddquche_effect',1,false); - player.give(cards,target); + discard: false, + delay: false, + lose: false, + content() { + "step 0"; + event.count = 1; + player.awakenSkill("dddquche"); + player.addTempSkill("dddquche_effect"); + player.addMark("dddquche_effect", 1, false); + player.give(cards, target); event.goto(3); - 'step 1' - if(player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.color(card)=='red'; - },'he')){ + "step 1"; + if ( + player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.color(card) == "red"; + }, "he") + ) { player.chooseCardTarget({ - prompt:'是否将一张红色牌交给一名其他角色?', - filterCard:{color:'red'}, - filterTarget:lib.filter.notMe, - position:'he', + prompt: "是否将一张红色牌交给一名其他角色?", + filterCard: { color: "red" }, + filterTarget: lib.filter.notMe, + position: "he", }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.addMark('dddquche_effect',1,false); - player.give(result.cards,result.targets[0]); - } - else event.finish(); - 'step 3' - if(player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.color(card)=='black'; - },'hes')){ + } else event.finish(); + "step 2"; + if (result.bool) { + player.addMark("dddquche_effect", 1, false); + player.give(result.cards, result.targets[0]); + } else event.finish(); + "step 3"; + if ( + player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.color(card) == "black"; + }, "hes") + ) { player.chooseCardTarget({ - prompt:'是否将一张黑色牌当做【杀】使用?', - position:'he', - filterCard(card,player){ - if(get.color(card)!='black') return false; - var card=get.autoViewAs({name:'sha'},[card]); - return lib.filter.cardEnabled(card,player); + prompt: "是否将一张黑色牌当做【杀】使用?", + position: "he", + filterCard(card, player) { + if (get.color(card) != "black") return false; + var card = get.autoViewAs({ name: "sha" }, [card]); + return lib.filter.cardEnabled(card, player); }, - selectTarget(){ - var card=get.autoViewAs({name:'sha'},ui.selected.cards); - return lib.filter.selectTarget(card,_status.event.player); + selectTarget() { + var card = get.autoViewAs({ name: "sha" }, ui.selected.cards); + return lib.filter.selectTarget(card, _status.event.player); }, - filterTarget(card,player,target){ - var card=get.autoViewAs({name:'sha'},ui.selected.cards); - return lib.filter.targetEnabled(card,player,target)&&lib.filter.targetInRange(card,player,target); + filterTarget(card, player, target) { + var card = get.autoViewAs({ name: "sha" }, ui.selected.cards); + return ( + lib.filter.targetEnabled(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); }, }); - } - else event.finish(); - 'step 4' - if(result.bool){ - player.addMark('dddquche_effect',1,false); - player.useCard({name:'sha'},result.cards,result.targets,false); + } else event.finish(); + "step 4"; + if (result.bool) { + player.addMark("dddquche_effect", 1, false); + player.useCard({ name: "sha" }, result.cards, result.targets, false); event.goto(1); - } - else event.finish(); + } else event.finish(); }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - mod:{ - globalFrom (from,to,distance){ - return distance-from.countMark('dddquche_effect'); + subSkill: { + effect: { + charlotte: true, + onremove: true, + mod: { + globalFrom(from, to, distance) { + return distance - from.countMark("dddquche_effect"); }, }, - intro:{ - content:"至其他角色的距离-#", + intro: { + content: "至其他角色的距离-#", }, - sub:true, + sub: true, }, }, - mark:true, - intro:{ - content:"limited", + mark: true, + intro: { + content: "limited", }, - init (player,skill){ - player.storage[skill]=false; + init(player, skill) { + player.storage[skill] = false; }, }, - dddqianlong:{ - zhuSkill:true, - trigger:{ - source:"dieAfter", + dddqianlong: { + zhuSkill: true, + trigger: { + source: "dieAfter", }, - forced:true, - filter:(event,player)=>player.hasZhuSkill('dddqianlong'), - content (){ + forced: true, + filter: (event, player) => player.hasZhuSkill("dddqianlong"), + content() { player.draw(3); }, - group:"dddqianlong_cancel", - subSkill:{ - cancel:{ - trigger:{ - player:["drawBefore","discardBefore"], + group: "dddqianlong_cancel", + subSkill: { + cancel: { + trigger: { + player: ["drawBefore", "discardBefore"], }, - forced:true, - popup:false, - filter (event,player){ - if(!player.hasZhuSkill('dddqianlong')) return false; - var evt=event.getParent(); - return evt&&evt.name=='die'&&evt.source==player; + forced: true, + popup: false, + filter(event, player) { + if (!player.hasZhuSkill("dddqianlong")) return false; + var evt = event.getParent(); + return evt && evt.name == "die" && evt.source == player; }, - content (){ + content() { trigger.cancel(); }, - sub:true, + sub: true, }, }, }, - ddddongcha:{ - trigger:{ - global:"phaseBegin", + ddddongcha: { + trigger: { + global: "phaseBegin", }, - logTarget:"player", - filter (event,player){ - return player!=event.player&&player.countCards('h')>0&&event.player.countCards('h')>0; + logTarget: "player", + filter(event, player) { + return ( + player != event.player && + player.countCards("h") > 0 && + event.player.countCards("h") > 0 + ); }, - check(event,player){ - return get.attitude(player,event.player)<=0; + check(event, player) { + return get.attitude(player, event.player) <= 0; }, - content (){ - 'step 0' - event.target=trigger.player; - player.addTempSkill('ddddongcha_effect'); - if(player.countCards('h')>0) player.chooseCard('h',true,'选择一张牌作为“鉴”'); - 'step 1' - if(result.bool){ - player.addToExpansion(result.cards,player,'give').gaintag.add('ddddongcha_effect'); + content() { + "step 0"; + event.target = trigger.player; + player.addTempSkill("ddddongcha_effect"); + if (player.countCards("h") > 0) player.chooseCard("h", true, "选择一张牌作为“鉴”"); + "step 1"; + if (result.bool) { + player.addToExpansion(result.cards, player, "give").gaintag.add("ddddongcha_effect"); } - 'step 2' - if(target.countCards('h')>0) target.chooseCard('h',true,'选择一张牌作为“鉴”'); - 'step 3' - if(result.bool){ - player.addToExpansion(result.cards,target,'give').gaintag.add('ddddongcha_effect'); + "step 2"; + if (target.countCards("h") > 0) target.chooseCard("h", true, "选择一张牌作为“鉴”"); + "step 3"; + if (result.bool) { + player.addToExpansion(result.cards, target, "give").gaintag.add("ddddongcha_effect"); } }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{ - global:"phaseEnd", + subSkill: { + effect: { + charlotte: true, + trigger: { + global: "phaseEnd", }, - forced:true, - filter (event,player){ - return player.getExpansions('ddddongcha_effect').length>0; + forced: true, + filter(event, player) { + return player.getExpansions("ddddongcha_effect").length > 0; }, - content (){ - 'step 0' - var cards=player.getExpansions('ddddongcha_effect'); - if(cards.length>0){ - if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton(['选择获得一张“鉴”',cards],true); - } - else event.finish(); - 'step 1' - if(result.bool) player.gain(result.links,'gain2'); - 'step 2' - var cards=player.getExpansions('ddddongcha_effect'); - if(cards.length>0&&trigger.player.isIn()){ - if(cards.length==1) event._result={bool:true,links:cards}; - else trigger.player.chooseButton(['选择获得一张“鉴”',cards],true).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }) - } - else event.finish(); - 'step 3' - if(result.bool) trigger.player.gain(result.links,player,'give'); + content() { + "step 0"; + var cards = player.getExpansions("ddddongcha_effect"); + if (cards.length > 0) { + if (cards.length == 1) + event._result = { + bool: true, + links: cards, + }; + else player.chooseButton(["选择获得一张“鉴”", cards], true); + } else event.finish(); + "step 1"; + if (result.bool) player.gain(result.links, "gain2"); + "step 2"; + var cards = player.getExpansions("ddddongcha_effect"); + if (cards.length > 0 && trigger.player.isIn()) { + if (cards.length == 1) + event._result = { + bool: true, + links: cards, + }; + else + trigger.player + .chooseButton(["选择获得一张“鉴”", cards], true) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); + } else event.finish(); + "step 3"; + if (result.bool) trigger.player.gain(result.links, player, "give"); }, - marktext:"鉴", - intro:{ - content:"expansion", - markcount:"expansion", + marktext: "鉴", + intro: { + content: "expansion", + markcount: "expansion", }, - sub:true, + sub: true, }, }, }, - dddzhijie:{ - enable:"chooseToUse", - filter (event,player){ - if(event.type=='phase') return false; - var cards=player.getExpansions('ddddongcha_effect'); - if(cards.length<2) return false; - var shan=false,wuxie=false; - for(var i=0;i1, - backup (links,player){ + check: () => 1, + backup(links, player) { return { - viewAs:{name:(get.color(links[0])==get.color(links[1]))?'shan':'wuxie'}, - cards:links, - selectCard:-1, - position:'x', - filterCard:(card)=>lib.skill['dddzhijie_backup'].cards.includes(card), - popname:true, - precontent(){ - player.addTempSkill('dddzhijie_draw'); + viewAs: { + name: get.color(links[0]) == get.color(links[1]) ? "shan" : "wuxie", }, - } + cards: links, + selectCard: -1, + position: "x", + filterCard: (card) => lib.skill["dddzhijie_backup"].cards.includes(card), + popname: true, + precontent() { + player.addTempSkill("dddzhijie_draw"); + }, + }; }, }, - ai:{ - combo:"ddddongcha", - respondShan:true, - skillTagFilter (player){ - return lib.skill['dddzhijie'].hiddenCard(player,'shan'); + ai: { + combo: "ddddongcha", + respondShan: true, + skillTagFilter(player) { + return lib.skill["dddzhijie"].hiddenCard(player, "shan"); + }, + order: 10, + result: { player: 1 }, + effect: { + target: (card, player, target) => { + if ( + card.name === "sha" && + target.getExpansions("ddddongcha_effect").length < 2 && + lib.skill["dddzhijie"].hiddenCard(target, "shan") + ) + return [1, 1, 1, -get.sgn(get.attitude(player, _status.currentPhase))]; + }, }, - order:10, - result:{player:1}, - effect:{ - target:(card,player,target)=>{ - if(card.name==='sha'&&target.getExpansions('ddddongcha_effect').length<2&&lib.skill['dddzhijie'].hiddenCard(target,'shan')) return [1,1,1,-get.sgn(get.attitude(player,_status.currentPhase))]; - } - } }, - subSkill:{ - draw:{ - trigger:{ - player:"useCardAfter", + subSkill: { + draw: { + trigger: { + player: "useCardAfter", }, - forced:true, - charlotte:true, - popup:false, - filter (event,player){ - return event.skill=='dddzhijie_backup'; + forced: true, + charlotte: true, + popup: false, + filter(event, player) { + return event.skill == "dddzhijie_backup"; }, - content (){ + content() { player.draw(2); }, - sub:true, + sub: true, }, }, }, - dddqiahua:{ - trigger:{ - global:"phaseBegin", + dddqiahua: { + trigger: { + global: "phaseBegin", }, - direct:true, - filter (event,player){ - return player!=event.player&&event.player.hp>0&&player.countCards('h',function(card){ - return !get.is.shownCard(card); - })>=event.player.hp; - }, - content (){ - 'step 0' - var target=trigger.player; - player.chooseCard('h',target.hp,get.prompt('dddqiahua',target),'选择明置'+get.cnNumber(target.hp)+'张手牌,然后'+get.translation(target)+'获得技能〖恂恂〗直到本回合结束。',function(card){ - return !get.is.shownCard(card); - }).set('goon',get.attitude(player,target)>0).set('ai',function(card){ - if(_status.event.goon) return 1+Math.random(); - return 0; - }); - 'step 1' - if(result.bool){ - var target=trigger.player,cards=result.cards; - player.logSkill('dddqiahua',target); - target.addTempSkills('dddxunxun'); - player.addShownCards(cards,'visible_dddxianglang'); - game.log(player,'选择了',cards,'作为“明”'); - player.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【恰化】'); - } - }, - ai:{ - expose:0.15, - }, - derivation:"dddxunxun", - }, - dddxunxun:{ - inherit:"xunxun", - audio:2, - }, - dddfusi:{ - mod:{ - ignoredHandcard (card,player){ - if(get.is.shownCard(card)) return true; - }, - cardDiscardable (card,player,name){ - if(name=='phaseDiscard'&&get.is.shownCard(card)) return false; - }, - }, - global:"dddfusi_global", - subSkill:{ - refused:{ - charlotte:true, - sub:true, - }, - allowed:{ - charlotte:true, - sub:true, - }, - }, - }, - dddfusi_global:{ - mod:{ - cardEnabled2(card,player){ - var source=_status.currentPhase; - if(!source||source==player||!source.hasSkill('dddfusi')||source.countCards('h')==0||source.hasCard(function(card){ + direct: true, + filter(event, player) { + return ( + player != event.player && + event.player.hp > 0 && + player.countCards("h", function (card) { return !get.is.shownCard(card); - },'h')) return; - if(player.getCards('h').includes(card)) return false; + }) >= event.player.hp + ); + }, + content() { + "step 0"; + var target = trigger.player; + player + .chooseCard( + "h", + target.hp, + get.prompt("dddqiahua", target), + "选择明置" + + get.cnNumber(target.hp) + + "张手牌,然后" + + get.translation(target) + + "获得技能〖恂恂〗直到本回合结束。", + function (card) { + return !get.is.shownCard(card); + } + ) + .set("goon", get.attitude(player, target) > 0) + .set("ai", function (card) { + if (_status.event.goon) return 1 + Math.random(); + return 0; + }); + "step 1"; + if (result.bool) { + var target = trigger.player, + cards = result.cards; + player.logSkill("dddqiahua", target); + target.addTempSkills("dddxunxun"); + player.addShownCards(cards, "visible_dddxianglang"); + game.log(player, "选择了", cards, "作为“明”"); + player.showCards( + cards, + get.translation(player) + "对" + get.translation(target) + "发动了【恰化】" + ); + } + }, + ai: { + expose: 0.15, + }, + derivation: "dddxunxun", + }, + dddxunxun: { + inherit: "xunxun", + audio: 2, + }, + dddfusi: { + mod: { + ignoredHandcard(card, player) { + if (get.is.shownCard(card)) return true; + }, + cardDiscardable(card, player, name) { + if (name == "phaseDiscard" && get.is.shownCard(card)) return false; }, }, - enable:"chooseToUse", - filter (event,player){ - if(event._dddfusi_refused||player.hasSkill('dddfusi_refused')) return false; - var players=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('dddfusi'); + global: "dddfusi_global", + subSkill: { + refused: { + charlotte: true, + sub: true, + }, + allowed: { + charlotte: true, + sub: true, + }, + }, + }, + dddfusi_global: { + mod: { + cardEnabled2(card, player) { + var source = _status.currentPhase; + if ( + !source || + source == player || + !source.hasSkill("dddfusi") || + source.countCards("h") == 0 || + source.hasCard(function (card) { + return !get.is.shownCard(card); + }, "h") + ) + return; + if (player.getCards("h").includes(card)) return false; + }, + }, + enable: "chooseToUse", + filter(event, player) { + if (event._dddfusi_refused || player.hasSkill("dddfusi_refused")) return false; + var players = game.filterPlayer(function (current) { + return current != player && current.hasSkill("dddfusi"); }); - for(var source of players){ - var cards=source.getShownCards(); - for(var i of cards){ - var card=get.autoViewAs(i); - if(event.filterCard(card,player,event)) return true; + for (var source of players) { + var cards = source.getShownCards(); + for (var i of cards) { + var card = get.autoViewAs(i); + if (event.filterCard(card, player, event)) return true; } } return false; }, - hiddenCard (player,name){ - if(player.hasSkill('dddfusi_refused')) return false; - var players=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('dddfusi'); + hiddenCard(player, name) { + if (player.hasSkill("dddfusi_refused")) return false; + var players = game.filterPlayer(function (current) { + return current != player && current.hasSkill("dddfusi"); }); - for(var source of players){ - var cards=source.getShownCards(); - for(var i of cards){ - var card=get.autoViewAs(i); - if(name==card.name) return true; + for (var source of players) { + var cards = source.getShownCards(); + for (var i of cards) { + var card = get.autoViewAs(i); + if (name == card.name) return true; } } return false; }, - chooseButton:{ - dialog (event,player){ - var dialog=ui.create.dialog('腹笥','hidden'); - var players=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('dddfusi'); - }).sortBySeat(); - for(var source of players){ - var cards=source.getShownCards(); - if(cards.length){ - var str='
              '; - str+=get.translation(source); - var num=source.getSeatNum(); - if(num>0) str+=('('+get.cnNumber(num,true)+'号位)'); - str+='
              '; + chooseButton: { + dialog(event, player) { + var dialog = ui.create.dialog("腹笥", "hidden"); + var players = game + .filterPlayer(function (current) { + return current != player && current.hasSkill("dddfusi"); + }) + .sortBySeat(); + for (var source of players) { + var cards = source.getShownCards(); + if (cards.length) { + var str = '
              '; + str += get.translation(source); + var num = source.getSeatNum(); + if (num > 0) str += "(" + get.cnNumber(num, true) + "号位)"; + str += "
              "; dialog.add(str); dialog.add(cards); } } return dialog; }, - filter (button,player){ - var card=get.autoViewAs(button.link),evt=_status.event.getParent(); - return evt.filterCard(card,player,evt); + filter(button, player) { + var card = get.autoViewAs(button.link), + evt = _status.event.getParent(); + return evt.filterCard(card, player, evt); }, - check (button){ - if(_status.event.getParent().type!='phase') return 1; - return _status.event.player.getUseValue(get.autoViewAs(button.link),null,true); + check(button) { + if (_status.event.getParent().type != "phase") return 1; + return _status.event.player.getUseValue(get.autoViewAs(button.link), null, true); }, - backup (links,player){ + backup(links, player) { return { - card:links[0], - viewAs:get.autoViewAs(links[0]), - filterCard:()=>false, - selectCard:-1, - precontent(){ - 'step 0' - var card=lib.skill['dddfusi_global_backup'].card; - event.card=card; - event.result.cards=[card]; - event.source=get.owner(card); - if(!event.result.card.storage) event.result.card.storage={}; - event.result.card.storage._dddfusi_owner=event.source; + card: links[0], + viewAs: get.autoViewAs(links[0]), + filterCard: () => false, + selectCard: -1, + precontent() { + "step 0"; + var card = lib.skill["dddfusi_global_backup"].card; + event.card = card; + event.result.cards = [card]; + event.source = get.owner(card); + if (!event.result.card.storage) event.result.card.storage = {}; + event.result.card.storage._dddfusi_owner = event.source; delete event.result.skill; - player.logSkill('dddfusi_global',event.source); - if(player.hasSkill('dddfusi_allowed')) event.finish(); - 'step 1' - if(event.result.targets&&event.result.targets.length) player.line(event.result.targets,event.result.card.nature); - player.showCards([card],get.translation(player)+'向'+get.translation(source)+'发动【腹笥】'); - source.chooseButton([ - '是否同意'+get.translation(player)+'使用'+get.translation(card)+'?', - '
              '+function(){ - if(event.result.targets&&event.result.targets.length) return '(目标角色:'+get.translation(event.result.targets)+')'; - return '(无目标角色)'; - }()+'
              ', - [['   同意   ','  不同意  '],'tdnodes'], - [['   同意且本回合内不再提示   '],'tdnodes'], - [['  不同意且本回合内不再提示  '],'tdnodes'], - 'forcebutton', - ],true).set('forceAuto',true); - 'step 2' - if(result.links[0].indexOf('不同意')==-1){ - source.chat('同意'); - if(result.links[0].indexOf('本回合内不再提示')>0) player.addTempSkill('dddfusi_allowed'); - } - else if(result.links[0].indexOf('不同意')!=-1){ - source.chat('不同意'); - if(result.links[0].indexOf('本回合内不再提示')>0) player.addTempSkill('dddfusi_refused'); - else if(event.result.card.name=='wuxie') player.addTempSkill('dddfusi_refused','_wuxieAfter'); - var evt=event.getParent(); - evt.set('_dddfusi_refused',true); + player.logSkill("dddfusi_global", event.source); + if (player.hasSkill("dddfusi_allowed")) event.finish(); + "step 1"; + if (event.result.targets && event.result.targets.length) + player.line(event.result.targets, event.result.card.nature); + player.showCards( + [card], + get.translation(player) + "向" + get.translation(source) + "发动【腹笥】" + ); + source + .chooseButton( + [ + "是否同意" + + get.translation(player) + + "使用" + + get.translation(card) + + "?", + '
              ' + + (function () { + if (event.result.targets && event.result.targets.length) + return ( + "(目标角色:" + + get.translation(event.result.targets) + + ")" + ); + return "(无目标角色)"; + })() + + "
              ", + [["   同意   ", "  不同意  "], "tdnodes"], + [["   同意且本回合内不再提示   "], "tdnodes"], + [["  不同意且本回合内不再提示  "], "tdnodes"], + "forcebutton", + ], + true + ) + .set("forceAuto", true); + "step 2"; + if (result.links[0].indexOf("不同意") == -1) { + source.chat("同意"); + if (result.links[0].indexOf("本回合内不再提示") > 0) + player.addTempSkill("dddfusi_allowed"); + } else if (result.links[0].indexOf("不同意") != -1) { + source.chat("不同意"); + if (result.links[0].indexOf("本回合内不再提示") > 0) + player.addTempSkill("dddfusi_refused"); + else if (event.result.card.name == "wuxie") + player.addTempSkill("dddfusi_refused", "_wuxieAfter"); + var evt = event.getParent(); + evt.set("_dddfusi_refused", true); evt.goto(0); } }, - } + }; }, - prompt (links,player){ - return '请选择'+get.translation(links[0])+'的目标'; + prompt(links, player) { + return "请选择" + get.translation(links[0]) + "的目标"; }, }, - ai:{ - order:10, - result:{ - player (player,target){ - if(!game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('dddfusi')&&get.attitude(player,current)>=0; - })) return 0; - if(_status.event.dying) return get.attitude(player,_status.event.dying); + ai: { + order: 10, + result: { + player(player, target) { + if ( + !game.hasPlayer(function (current) { + return ( + current != player && + current.hasSkill("dddfusi") && + get.attitude(player, current) >= 0 + ); + }) + ) + return 0; + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, - respondSha:true, - respondShan:true, - skillTagFilter (player,tag,arg){ + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { var name; - switch(tag){ - case 'respondSha':name='sha';break; - case 'respondShan':name='shan';break; + switch (tag) { + case "respondSha": + name = "sha"; + break; + case "respondShan": + name = "shan"; + break; } - return lib.skill['dddfusi_global'].hiddenCard(player,name); + return lib.skill["dddfusi_global"].hiddenCard(player, name); }, }, }, - dddtuoji:{ - trigger:{global:'useCardAfter'}, - frequent:true, - filter(event,player){ - return event.card.storage&&event.card.storage._dddfusi_owner==player&&!player.hasCard(function(card){ - return !get.is.shownCard(card); - },'h'); + dddtuoji: { + trigger: { global: "useCardAfter" }, + frequent: true, + filter(event, player) { + return ( + event.card.storage && + event.card.storage._dddfusi_owner == player && + !player.hasCard(function (card) { + return !get.is.shownCard(card); + }, "h") + ); }, - content(){ + content() { player.draw(3); }, + ai: { + combo: "dddfusi" + }, }, - dddchashi:{ - trigger:{global:'phaseUseBegin'}, - direct:true, - filter(event,player){ - return player!=event.player&&player.countCards('he')>0; + dddchashi: { + trigger: { global: "phaseUseBegin" }, + direct: true, + filter(event, player) { + return player != event.player && player.countCards("he") > 0; }, - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - const valuableCards=target.getCards('hs',card=>target.hasValueTarget(card)); - let result=yield player.chooseToDiscard(get.prompt('dddchashi',target),'弃置一张牌,若其使用的下一张牌的花色或类型与此牌相同,你与其各摸一张牌','he').set('logSkill',['dddchashi',target]).set('ai',card=>{ - if(!get.event('goon')) return 0; - var list=get.event('list'); - return list[0].includes(get.suit(card))||list[1].includes(get.type2(card)); - }).set('list',[ - valuableCards.map(card=>get.suit(card)).toUniqued(), - valuableCards.map(card=>get.type2(card)).toUniqued() - ]).set('goon',get.attitude(player,target)>0); - if(!result.bool) return event.finish(); - player.storage['dddchashi']=[result.cards[0],target]; - player.addTempSkill('dddchashi_effect','phaseUseAfter'); - target.addTempSkill('dddchashi_ai',{player:['phaseUseAfter','useCard1']}); - }, - content_old(){ - 'step 0' - var target=trigger.player,history=target.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==trigger; + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + const valuableCards = target.getCards("hs", (card) => target.hasValueTarget(card)); + let result = yield player + .chooseToDiscard( + get.prompt("dddchashi", target), + "弃置一张牌,若其使用的下一张牌的花色或类型与此牌相同,你与其各摸一张牌", + "he" + ) + .set("logSkill", ["dddchashi", target]) + .set("ai", (card) => { + if (!get.event("goon")) return 0; + var list = get.event("list"); + return list[0].includes(get.suit(card)) || list[1].includes(get.type2(card)); + }) + .set("list", [ + valuableCards.map((card) => get.suit(card)).toUniqued(), + valuableCards.map((card) => get.type2(card)).toUniqued(), + ]) + .set("goon", get.attitude(player, target) > 0); + if (!result.bool) return event.finish(); + player.storage["dddchashi"] = [result.cards[0], target]; + player.addTempSkill("dddchashi_effect", "phaseUseAfter"); + target.addTempSkill("dddchashi_ai", { + player: ["phaseUseAfter", "useCard1"], }); - event.target=target; - if(history.length>0){ - var suit=get.suit(history[0].card); - event.suit=suit; - player.chooseCard('he',get.prompt('dddchashi',target),'你可以展示一张牌。若此牌花色为'+get.translation(suit)+',则'+get.translation(target)+'获得你展示的牌,然后你摸一张牌。').set('goon',get.sgn(get.attitude(player,target))).set('ai',function(card){ - if(_status.event.goon<=0) return _status.event.goon*(get.value(card)+0.01); - return 2/Math.max(0.1,get.value(card)) + }, + content_old() { + "step 0"; + var target = trigger.player, + history = target.getHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == trigger; }); - } - else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('dddchashi',target); - var card=result.cards[0]; - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【察势】'); - if(get.color(card)==event.suit){ - target.gain(card,player,'give'); + event.target = target; + if (history.length > 0) { + var suit = get.suit(history[0].card); + event.suit = suit; + player + .chooseCard( + "he", + get.prompt("dddchashi", target), + "你可以展示一张牌。若此牌花色为" + + get.translation(suit) + + ",则" + + get.translation(target) + + "获得你展示的牌,然后你摸一张牌。" + ) + .set("goon", get.sgn(get.attitude(player, target))) + .set("ai", function (card) { + if (_status.event.goon <= 0) + return _status.event.goon * (get.value(card) + 0.01); + return 2 / Math.max(0.1, get.value(card)); + }); + } else event.goto(2); + "step 1"; + if (result.bool) { + player.logSkill("dddchashi", target); + var card = result.cards[0]; + player.showCards( + card, + get.translation(player) + "对" + get.translation(target) + "发动了【察势】" + ); + if (get.color(card) == event.suit) { + target.gain(card, player, "give"); player.draw(); } } event.finish(); - 'step 2' - player.chooseCard('he',get.prompt('dddchashi',target),'你可以展示一张牌。若其本阶段内使用的第一张牌与此牌花色相同,则'+get.translation(target)+'获得你展示的牌,然后你摸一张牌。').set('goon',get.sgn(get.attitude(player,target))).set('ai',function(card){ - if(_status.event.goon<=0) return _status.event.goon*(get.value(card)+0.01); - return 2/Math.max(0.1,get.value(card)) - }); - 'step 3' - if(result.bool){ - player.logSkill('dddchashi',target); - var card=result.cards[0]; - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【察势】'); - player.addTempSkill('dddchashi_effect','phaseUseAfter'); - player.addGaintag([card],'dddchashi'); - player.storage['dddchashi']=[card,target]; - target.addTempSkill('dddchashi_ai',{player:['phaseUseAfter','useCard1']}); + "step 2"; + player + .chooseCard( + "he", + get.prompt("dddchashi", target), + "你可以展示一张牌。若其本阶段内使用的第一张牌与此牌花色相同,则" + + get.translation(target) + + "获得你展示的牌,然后你摸一张牌。" + ) + .set("goon", get.sgn(get.attitude(player, target))) + .set("ai", function (card) { + if (_status.event.goon <= 0) return _status.event.goon * (get.value(card) + 0.01); + return 2 / Math.max(0.1, get.value(card)); + }); + "step 3"; + if (result.bool) { + player.logSkill("dddchashi", target); + var card = result.cards[0]; + player.showCards( + card, + get.translation(player) + "对" + get.translation(target) + "发动了【察势】" + ); + player.addTempSkill("dddchashi_effect", "phaseUseAfter"); + player.addGaintag([card], "dddchashi"); + player.storage["dddchashi"] = [card, target]; + target.addTempSkill("dddchashi_ai", { + player: ["phaseUseAfter", "useCard1"], + }); } }, - subSkill:{ - effect:{ - trigger:{global:'useCard'}, - forced:true, - charlotte:true, - filter(event,player){ - var storage=player.getStorage('dddchashi'); - if(!storage||!storage.length) return false; - if(event.player!=storage[1]||!event.player.isIn()) return false; + subSkill: { + effect: { + trigger: { global: "useCard" }, + forced: true, + charlotte: true, + filter(event, player) { + var storage = player.getStorage("dddchashi"); + if (!storage || !storage.length) return false; + if (event.player != storage[1] || !event.player.isIn()) return false; // if(!player.getCards('he').includes(storage[0])||!storage[0].hasGaintag('dddchashi')) return false; - if(get.suit(event.card)!=get.suit(storage[0])&&get.type2(event.card)!=get.type2(storage[0])) return false; + if ( + get.suit(event.card) != get.suit(storage[0]) && + get.type2(event.card) != get.type2(storage[0]) + ) + return false; // var evt=event.getParent('phaseUse'); // if(evt.player) // if(event.player.getHistory('useCard',function(evtx){ @@ -2718,69 +3493,80 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // }).indexOf(event)!=0) return false; return true; }, - content(){ - var storage=player.getStorage('dddchashi'); + content() { + var storage = player.getStorage("dddchashi"); // storage[1].gain(storage[0],player,'give'); // player.draw(); - game.asyncDraw([player,storage[1]].sortBySeat(_status.currentPhase)); - player.removeSkill('dddchashi_effect'); + game.asyncDraw([player, storage[1]].sortBySeat(_status.currentPhase)); + player.removeSkill("dddchashi_effect"); }, - onremove(player,storage){ - delete player.storage['dddchashi']; + onremove(player, storage) { + delete player.storage["dddchashi"]; // player.removeGaintag('dddchashi'); }, }, - ai:{ - charlotte:true, + ai: { + charlotte: true, }, }, }, - dddqice:{ - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return !player.storage['dddqice']; + dddqice: { + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return !player.storage["dddqice"]; }, - content(){ + content() { player.draw(2); // player.addTempSkill('dddqice_effect'); - player.setStorage('dddqice',true); - player.when('useCard1').filter(evt=>get.type2(evt.card)=='trick').then(()=>{ - delete player.storage['dddqice']; - }) + player.setStorage("dddqice", true); + player + .when("useCard1") + .filter((evt) => get.type2(evt.card) == "trick") + .then(() => { + delete player.storage["dddqice"]; + }); }, - subSkill:{ - effect:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - charlotte:true, - content(){ - 'step 0' - var list=[]; - player.getHistory('useCard',function(evt){ - if(get.type(evt.card)=='trick') list.add(evt.card.name); + subSkill: { + effect: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + content() { + "step 0"; + var list = []; + player.getHistory("useCard", function (evt) { + if (get.type(evt.card) == "trick") list.add(evt.card.name); }); list.sort(); - if(list.length>0){ - player.chooseButton(['齐策:是否视为使用一张牌?',[list,'vcard']],function(button){ - return _status.event.player.hasUseTarget({name:button.link[2],isCard:true}); - }).set('ai',function(button){ - var card={ - name:button.link[2], - nature:button.link[3], - isCard:true, - },player=_status.event.player; - return player.getUseValue(card); - }); - } - else{ - player.removeSkills('dddqice'); + if (list.length > 0) { + player + .chooseButton( + ["齐策:是否视为使用一张牌?", [list, "vcard"]], + function (button) { + return _status.event.player.hasUseTarget({ + name: button.link[2], + isCard: true, + }); + } + ) + .set("ai", function (button) { + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }, + player = _status.event.player; + return player.getUseValue(card); + }); + } else { + player.removeSkills("dddqice"); event.finish(); } - 'step 1' - if(result.bool){ - player.chooseUseTarget(true,{ - name:result.links[0][2], - isCard:true, + "step 1"; + if (result.bool) { + player.chooseUseTarget(true, { + name: result.links[0][2], + isCard: true, }); } }, @@ -2788,110 +3574,140 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //甄姬 - dddmiaoxing:{ - audio:2, - trigger:{global:'gameDrawBegin'}, - forced:true, - content(){ - var me=player; - var numx=trigger.num; - trigger.num=typeof numx=='function'?function(player){ - if(player==me){ - return 3*numx(player); - } - return numx(player); - }:function(player){ - if(player==me){ - return 3*numx; - } - return numx; - } - player._dddmiaoxing=true; + dddmiaoxing: { + audio: 2, + trigger: { global: "gameDrawBegin" }, + forced: true, + content() { + var me = player; + var numx = trigger.num; + trigger.num = + typeof numx == "function" + ? function (player) { + if (player == me) { + return 3 * numx(player); + } + return numx(player); + } + : function (player) { + if (player == me) { + return 3 * numx; + } + return numx; + }; + player._dddmiaoxing = true; }, - group:['dddmiaoxing_out','dddmiaoxing_balance'], - marktext:'水', - intro:{ - name:'水相', - markcount(storage,player){ - return ''+player.getExpansions('dddmiaoxing_1').length+'/'+player.getExpansions('dddmiaoxing_2').length; + group: ["dddmiaoxing_out", "dddmiaoxing_balance"], + marktext: "水", + intro: { + name: "水相", + markcount(storage, player) { + return ( + "" + + player.getExpansions("dddmiaoxing_1").length + + "/" + + player.getExpansions("dddmiaoxing_2").length + ); }, - mark(dialog,content,player){ - var content1=player.getExpansions('dddmiaoxing_1'); - var content2=player.getExpansions('dddmiaoxing_2'); - if(content1&&content1.length||content2&&content2.length){ - if(player==game.me||player.isUnderControl()){ - dialog.addText('第一组'); + mark(dialog, content, player) { + var content1 = player.getExpansions("dddmiaoxing_1"); + var content2 = player.getExpansions("dddmiaoxing_2"); + if ((content1 && content1.length) || (content2 && content2.length)) { + if (player == game.me || player.isUnderControl()) { + dialog.addText("第一组"); dialog.addAuto(content1); - dialog.addText('第二组'); + dialog.addText("第二组"); dialog.addAuto(content2); + } else { + return ( + "第一组“水相”有" + + get.cnNumber(content1.length) + + "张;" + + "第二组“水相”有" + + get.cnNumber(content2.length) + + "张" + ); } - else{ - return '第一组“水相”有'+get.cnNumber(content1.length)+'张;'+'第二组“水相”有'+get.cnNumber(content2.length)+'张'; - } - } - } - }, - subSkill:{ - out:{ - trigger:{ - global:'phaseBefore', - }, - forced:true, - filter(event,player){ - return game.phaseNumber==0&&player._dddmiaoxing; - }, - content(){ - 'step 0' - delete player._dddmiaoxing; - var cardsx=player.getCards('h'),num=Math.ceil(cardsx.length/3); - var cards=[cardsx.slice(0,num),cardsx.slice(num,2*num),cardsx.slice(2*num)]; - event.cards=cards; - player.chooseControl('第一组','第二组','第三组').set('dialog',[ - '淼形:选择一组作为你的手牌', - '第一组', - cards[0], - '第二组', - cards[1], - '第三组', - cards[2] - ]); - 'step 1' - event.cards.splice(result.index,1); - var cards=event.cards; - player.addToExpansion(cards[0],player,'giveAuto',false).gaintag.add('dddmiaoxing_1'); - player.addToExpansion(cards[1],player,'giveAuto').gaintag.add('dddmiaoxing_2'); - player.markSkill('dddmiaoxing'); } }, - balance:{ - trigger:{player:'phaseDrawAfter'}, - forced:true, - content(){ - 'step 0' - var forced=player.getExpansions('dddmiaoxing_1').length!=player.countCards('h')&& - player.getExpansions('dddmiaoxing_2').length!=player.countCards('h'); - var next=player.chooseButton([1,2],[ - '淼形:将至少一组“水相”调整至与手牌数相等', - [['第一组','第二组'],'tdnodes'], - '第一组', - player.getExpansions('dddmiaoxing_1'), - '第二组', - player.getExpansions('dddmiaoxing_2'), - ],forced); - next.set('filterButton',button=>{ - var type=typeof button.link; - return type!='object'; - }) - next.set('ai',button=>{ - var player=_status.event.player; - var ind=['第一组','第二组'].indexOf(button.link)+1; - if(ind==-1) return -100; - return player.countCards('h')-player.getExpansions('dddmiaoxing_'+ind).length; - }) - 'step 1' - if(result.bool){ - var choices=result.links; - event.choices=choices; + }, + subSkill: { + out: { + trigger: { + global: "phaseBefore", + }, + forced: true, + filter(event, player) { + return game.phaseNumber == 0 && player._dddmiaoxing; + }, + content() { + "step 0"; + delete player._dddmiaoxing; + var cardsx = player.getCards("h"), + num = Math.ceil(cardsx.length / 3); + var cards = [ + cardsx.slice(0, num), + cardsx.slice(num, 2 * num), + cardsx.slice(2 * num), + ]; + event.cards = cards; + player + .chooseControl("第一组", "第二组", "第三组") + .set("dialog", [ + "淼形:选择一组作为你的手牌", + '第一组', + cards[0], + '第二组', + cards[1], + '第三组', + cards[2], + ]); + "step 1"; + event.cards.splice(result.index, 1); + var cards = event.cards; + player + .addToExpansion(cards[0], player, "giveAuto", false) + .gaintag.add("dddmiaoxing_1"); + player.addToExpansion(cards[1], player, "giveAuto").gaintag.add("dddmiaoxing_2"); + player.markSkill("dddmiaoxing"); + }, + }, + balance: { + trigger: { player: "phaseDrawAfter" }, + forced: true, + content() { + "step 0"; + var forced = + player.getExpansions("dddmiaoxing_1").length != player.countCards("h") && + player.getExpansions("dddmiaoxing_2").length != player.countCards("h"); + var next = player.chooseButton( + [1, 2], + [ + "淼形:将至少一组“水相”调整至与手牌数相等", + [["第一组", "第二组"], "tdnodes"], + '第一组', + player.getExpansions("dddmiaoxing_1"), + '第二组', + player.getExpansions("dddmiaoxing_2"), + ], + forced + ); + next.set("filterButton", (button) => { + var type = typeof button.link; + return type != "object"; + }); + next.set("ai", (button) => { + var player = _status.event.player; + var ind = ["第一组", "第二组"].indexOf(button.link) + 1; + if (ind == -1) return -100; + return ( + player.countCards("h") - player.getExpansions("dddmiaoxing_" + ind).length + ); + }); + "step 1"; + if (result.bool) { + var choices = result.links; + event.choices = choices; // var hs=result.moved[0],sx1=result.moved[1],sx2=result.moved[2]; // hs.removeArray(player.getCards('h')); // sx1.removeArray(player.getExpansions('dddmiaoxing_1')); @@ -2900,1724 +3716,2148 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // player.gain(hs,'gain2'); // player.addToExpansion(sx1,player,'giveAuto').gaintag.add('dddmiaoxing_1'); // player.addToExpansion(sx2,player,'giveAuto').gaintag.add('dddmiaoxing_2'); - } - else event.finish(); - 'step 2' - if(event.choices.includes('第一组')){ - var del=player.countCards('h')-player.getExpansions('dddmiaoxing_1').length; - if(del>=0){ - if(del!=0) player.addToExpansion(get.cards(del),player,'draw').gaintag.add('dddmiaoxing_1'); + } else event.finish(); + "step 2"; + if (event.choices.includes("第一组")) { + var del = + player.countCards("h") - player.getExpansions("dddmiaoxing_1").length; + if (del >= 0) { + if (del != 0) + player + .addToExpansion(get.cards(del), player, "draw") + .gaintag.add("dddmiaoxing_1"); event.goto(4); - } - else{ - player.chooseButton(['淼形:移除'+get.cnNumber(-del)+'张第一组的“水相”',player.getExpansions('dddmiaoxing_1')],-del,true).set('ai',button=>{ - return -get.buttonValue(button); - }); + } else { + player + .chooseButton( + [ + "淼形:移除" + get.cnNumber(-del) + "张第一组的“水相”", + player.getExpansions("dddmiaoxing_1"), + ], + -del, + true + ) + .set("ai", (button) => { + return -get.buttonValue(button); + }); } } - 'step 3' - if(result.bool){ + "step 3"; + if (result.bool) { player.loseToDiscardpile(result.links); } - 'step 4' - player.markSkill('dddmiaoxing'); - if(event.choices.includes('第二组')){ - var del=player.countCards('h')-player.getExpansions('dddmiaoxing_2').length; - if(del>=0){ - if(del!=0) player.addToExpansion(get.cards(del),player,'draw').gaintag.add('dddmiaoxing_2'); + "step 4"; + player.markSkill("dddmiaoxing"); + if (event.choices.includes("第二组")) { + var del = + player.countCards("h") - player.getExpansions("dddmiaoxing_2").length; + if (del >= 0) { + if (del != 0) + player + .addToExpansion(get.cards(del), player, "draw") + .gaintag.add("dddmiaoxing_2"); event.goto(6); - } - else{ - player.chooseButton(['淼形:移除'+get.cnNumber(-del)+'张第二组的“水相”',player.getExpansions('dddmiaoxing_2')],-del,true).set('ai',button=>{ - return -get.buttonValue(button); - }); + } else { + player + .chooseButton( + [ + "淼形:移除" + get.cnNumber(-del) + "张第二组的“水相”", + player.getExpansions("dddmiaoxing_2"), + ], + -del, + true + ) + .set("ai", (button) => { + return -get.buttonValue(button); + }); } } - 'step 5' - if(result.bool){ + "step 5"; + if (result.bool) { player.loseToDiscardpile(result.links); } - 'step 6' - player.markSkill('dddmiaoxing'); - } - } - } + "step 6"; + player.markSkill("dddmiaoxing"); + }, + }, + }, }, - dddfushi:{ - audio:2, - trigger:{player:['useCardAfter','respondAfter']}, - filter(event,player){ - return get.type(event.card)=='basic'&&!player.hasSkill('dddfushi_used'); + dddfushi: { + audio: 2, + trigger: { player: ["useCardAfter", "respondAfter"] }, + filter(event, player) { + return get.type(event.card) == "basic" && !player.hasSkill("dddfushi_used"); }, - direct:true, - content(){ - 'step 0' - player.chooseControl('第一组','第二组','cancel2').set('dialog',[ - get.prompt('dddfushi'), - '用所有手牌交换一组“水相”', - '第一组', - player.getExpansions('dddmiaoxing_1'), - '第二组', - player.getExpansions('dddmiaoxing_2'), - ]).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var fn=player==_status.currentPhase?'useful':'value'; - var list=[ - [1,player.getExpansions('dddmiaoxing_1').reduce((p,c)=>p+get[fn](c),0)], - [2,player.getExpansions('dddmiaoxing_2').reduce((p,c)=>p+get[fn](c),0)], - [3,player.getCards('h').reduce((p,c)=>p+get[fn](c),0)], - ].sort((a,b)=>b[1]-a[1]); - return list[0][0]-1; - }()); - 'step 1' - if(result.control=='cancel2') event.finish(); - else{ - player.logSkill('dddfushi'); - player.addTempSkill('dddfushi_used'); - var index=result.index+1; - player.addToExpansion(player.getCards('h'),player,'giveAuto').gaintag.add('dddmiaoxing_'+index); - player.gain(player.getExpansions('dddmiaoxing_'+index),'draw'); - game.log(player,'获得了'+get.cnNumber(player.getExpansions('dddmiaoxing_'+index).length)+'张“水相”'); - } - 'step 2' - player.markSkill('dddmiaoxing'); - player.chooseTarget('是否令一名男性角色选择是否交换“水相”?',(card,player,target)=>{ - return target.hasSex('male'); - }).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target); - target.chooseControl('第一组','第二组','cancel2').set('dialog',[ - '浮世:是否用所有手牌交换一组“水相”?', + direct: true, + content() { + "step 0"; + player + .chooseControl("第一组", "第二组", "cancel2") + .set("dialog", [ + get.prompt("dddfushi"), + '用所有手牌交换一组“水相”', '第一组', - player.getExpansions('dddmiaoxing_1'), + player.getExpansions("dddmiaoxing_1"), '第二组', - player.getExpansions('dddmiaoxing_2'), - ]).set('ai',()=>{ + player.getExpansions("dddmiaoxing_2"), + ]) + .set("ai", () => { return _status.event.choice; - }).set('choice',function(){ - var fn=target==_status.currentPhase?'useful':'value'; - var list=[ - [1,player.getExpansions('dddmiaoxing_1').reduce((p,c)=>p+get[fn](c),0)], - [2,player.getExpansions('dddmiaoxing_2').reduce((p,c)=>p+get[fn](c),0)], - [3,target.getCards('h').reduce((p,c)=>p+get[fn](c),0)], - ].sort((a,b)=>b[1]-a[1]); - return list[0]-1; - }()); + }) + .set( + "choice", + (function () { + var fn = player == _status.currentPhase ? "useful" : "value"; + var list = [ + [ + 1, + player + .getExpansions("dddmiaoxing_1") + .reduce((p, c) => p + get[fn](c), 0), + ], + [ + 2, + player + .getExpansions("dddmiaoxing_2") + .reduce((p, c) => p + get[fn](c), 0), + ], + [3, player.getCards("h").reduce((p, c) => p + get[fn](c), 0)], + ].sort((a, b) => b[1] - a[1]); + return list[0][0] - 1; + })() + ); + "step 1"; + if (result.control == "cancel2") event.finish(); + else { + player.logSkill("dddfushi"); + player.addTempSkill("dddfushi_used"); + var index = result.index + 1; + player + .addToExpansion(player.getCards("h"), player, "giveAuto") + .gaintag.add("dddmiaoxing_" + index); + player.gain(player.getExpansions("dddmiaoxing_" + index), "draw"); + game.log( + player, + "获得了" + + get.cnNumber(player.getExpansions("dddmiaoxing_" + index).length) + + "张“水相”" + ); } - else event.finish(); - 'step 4' - if(result.control=='cancel2') event.finish(); - else{ - var index=result.index+1; - player.addToExpansion(target.getCards('h'),target,'giveAuto').gaintag.add('dddmiaoxing_'+index); - target.gain(player.getExpansions('dddmiaoxing_'+index),player,'giveAuto'); + "step 2"; + player.markSkill("dddmiaoxing"); + player + .chooseTarget("是否令一名男性角色选择是否交换“水相”?", (card, player, target) => { + return target.hasSex("male"); + }) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target); + target + .chooseControl("第一组", "第二组", "cancel2") + .set("dialog", [ + "浮世:是否用所有手牌交换一组“水相”?", + '第一组', + player.getExpansions("dddmiaoxing_1"), + '第二组', + player.getExpansions("dddmiaoxing_2"), + ]) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var fn = target == _status.currentPhase ? "useful" : "value"; + var list = [ + [ + 1, + player + .getExpansions("dddmiaoxing_1") + .reduce((p, c) => p + get[fn](c), 0), + ], + [ + 2, + player + .getExpansions("dddmiaoxing_2") + .reduce((p, c) => p + get[fn](c), 0), + ], + [3, target.getCards("h").reduce((p, c) => p + get[fn](c), 0)], + ].sort((a, b) => b[1] - a[1]); + return list[0] - 1; + })() + ); + } else event.finish(); + "step 4"; + if (result.control == "cancel2") event.finish(); + else { + var index = result.index + 1; + player + .addToExpansion(target.getCards("h"), target, "giveAuto") + .gaintag.add("dddmiaoxing_" + index); + target.gain(player.getExpansions("dddmiaoxing_" + index), player, "giveAuto"); } - 'step 5' - player.markSkill('dddmiaoxing'); + "step 5"; + player.markSkill("dddmiaoxing"); + }, + subSkill: { + used: { charlotte: true }, }, - subSkill:{ - used:{charlotte:true} - } }, //赵昂 - dddfenji:{ - audio:2, - trigger:{player:['phaseDrawBegin1','phaseDiscardBegin']}, - direct:true, - filter(event,player){ - if(event.name=='phaseDraw'&&event.numFixed) return false; - return lib.inpile.filter(i=>get.type(i)=='trick').removeArray(player.getStorage('dddfenji')).length > 0; + dddfenji: { + audio: 2, + trigger: { player: ["phaseDrawBegin1", "phaseDiscardBegin"] }, + direct: true, + filter(event, player) { + if (event.name == "phaseDraw" && event.numFixed) return false; + return ( + lib.inpile + .filter((i) => get.type(i) == "trick") + .removeArray(player.getStorage("dddfenji")).length > 0 + ); }, - content(){ - 'step 0' - var cards=lib.inpile.filter(i=>{ - return get.type(i)=='trick'&&!player.getStorage('dddfenji').includes(i); - }).map(i=>['锦囊','',i]); - player.chooseButton([get.prompt('dddfenji'),[cards,'vcard']]).set('ai',button=>{ - var evt=_status.event.getTrigger(); - if(evt.name=='phaseDraw'){ - if(!get.tag({name:button.link[2]},'damage')) return 0; - } - else{ - if(lib.skill.xunshi.isXunshi({name:button.link[2]})) return 0; - } - return _status.event.player.getUseValue({name:button.link[2]}); - }).set('filterButton',button=>{ - return player.hasUseTarget(button.link[2]); - }); - 'step 1' - if(result.bool){ - player.logSkill('dddfenji'); - player.markAuto('dddfenji',[result.links[0][2]]); - player.chooseUseTarget(result.links[0][2],true); - } - else event.finish(); - 'step 2' - if(trigger.name=='phaseDraw'){ - trigger.changeToZero(); - var num=0; - game.filterPlayer(current=>{ - current.getHistory('sourceDamage',evt=>{ - if(evt.getParent(4)==event) num+=evt.num; + content() { + "step 0"; + var cards = lib.inpile + .filter((i) => { + return get.type(i) == "trick" && !player.getStorage("dddfenji").includes(i); + }) + .map((i) => ["锦囊", "", i]); + player + .chooseButton([get.prompt("dddfenji"), [cards, "vcard"]]) + .set("ai", (button) => { + var evt = _status.event.getTrigger(); + if (evt.name == "phaseDraw") { + if (!get.tag({ name: button.link[2] }, "damage")) return 0; + } else { + if ( + lib.skill.xunshi.isXunshi({ + name: button.link[2], + }) + ) + return 0; + } + return _status.event.player.getUseValue({ + name: button.link[2], }); }) - if(num>0) player.draw(num); - } - else{ - trigger.cancel(); - var num=0; - player.getHistory('useCard',evt=>{ - if(evt.getParent(2)==event) num=evt.targets.length; + .set("filterButton", (button) => { + return player.hasUseTarget(button.link[2]); }); - if(num>0&&player.countCards('he')) player.chooseToDiscard(num,true); + "step 1"; + if (result.bool) { + player.logSkill("dddfenji"); + player.markAuto("dddfenji", [result.links[0][2]]); + player.chooseUseTarget(result.links[0][2], true); + } else event.finish(); + "step 2"; + if (trigger.name == "phaseDraw") { + trigger.changeToZero(); + var num = 0; + game.filterPlayer((current) => { + current.getHistory("sourceDamage", (evt) => { + if (evt.getParent(4) == event) num += evt.num; + }); + }); + if (num > 0) player.draw(num); + } else { + trigger.cancel(); + var num = 0; + player.getHistory("useCard", (evt) => { + if (evt.getParent(2) == event) num = evt.targets.length; + }); + if (num > 0 && player.countCards("he")) player.chooseToDiscard(num, true); } - } + }, }, //周处 - dddxiaheng:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - onremove:['dddxiaheng','dddxiaheng_del'], - intro:{content:'已因此技能对$造成过伤害'}, - content(){ - 'step 0' - event.targets=[]; - player.chooseTarget('侠横:令一名角色弃置两张牌',true).set('ai',target=>{ - var player=_status.event.player,eff=get.effect(target,{name:'guohe_copy2'},player,player),eff2=get.damageEffect(target,player,player); - if(player.storage['dddxiaheng_del']) return eff; - var toself=false; - if(eff2>eff*2){ - toself=!player.isDamaged()&&player.countCards('he',card=>get.value(card,player)<5)>=2; + dddxiaheng: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + onremove: ["dddxiaheng", "dddxiaheng_del"], + intro: { content: "已因此技能对$造成过伤害" }, + content() { + "step 0"; + event.targets = []; + player.chooseTarget("侠横:令一名角色弃置两张牌", true).set("ai", (target) => { + var player = _status.event.player, + eff = get.effect(target, { name: "guohe_copy2" }, player, player), + eff2 = get.damageEffect(target, player, player); + if (player.storage["dddxiaheng_del"]) return eff; + var toself = false; + if (eff2 > eff * 2) { + toself = + !player.isDamaged() && + player.countCards("he", (card) => get.value(card, player) < 5) >= 2; } - if(toself) return target==player?100:0; - return eff*(eff2>eff*2?0.5:1.5); + if (toself) return target == player ? 100 : 0; + return eff * (eff2 > eff * 2 ? 0.5 : 1.5); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; event.targets.add(target); player.line(target); - target.chooseToDiscard(2,true,'he'); + target.chooseToDiscard(2, true, "he"); } - 'step 2' - player.chooseTarget('侠横:对一名角色造成1点伤害',true).set('ai',target=>{ - var player=_status.event.player,eff=get.damageEffect(target,player,player),targetx=_status.event.targetx; - if(player.storage['dddxiaheng_del']) return eff; - var fix=player.getStorage('dddxiaheng').includes(target)?0.75:1; - if(target==player&&targetx!=player&&player.isHealthy()&&!player.getStorage('dddxiaheng').includes(player)&&player.hp>2) return 100; - return eff*(player.hp==1||target==targetx?0.1:1)*fix; - }).set('targetx',targets[0]); - 'step 3' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + player + .chooseTarget("侠横:对一名角色造成1点伤害", true) + .set("ai", (target) => { + var player = _status.event.player, + eff = get.damageEffect(target, player, player), + targetx = _status.event.targetx; + if (player.storage["dddxiaheng_del"]) return eff; + var fix = player.getStorage("dddxiaheng").includes(target) ? 0.75 : 1; + if ( + target == player && + targetx != player && + player.isHealthy() && + !player.getStorage("dddxiaheng").includes(player) && + player.hp > 2 + ) + return 100; + return eff * (player.hp == 1 || target == targetx ? 0.1 : 1) * fix; + }) + .set("targetx", targets[0]); + "step 3"; + if (result.bool) { + var target = result.targets[0]; event.targets.add(target); player.line(target); target.damage(); - player.markAuto('dddxiaheng',[target]); + player.markAuto("dddxiaheng", [target]); } - 'step 4' - if(player.storage['dddxiaheng_del']) event.finish(); - else{ - if(!targets.includes(player)) player.loseMaxHp(); - if(targets.length==1){ - player.removeSkills('dddxiaheng'); + "step 4"; + if (player.storage["dddxiaheng_del"]) event.finish(); + else { + if (!targets.includes(player)) player.loseMaxHp(); + if (targets.length == 1) { + player.removeSkills("dddxiaheng"); } } - 'step 5' - if(player.getStorage('dddxiaheng').length>=3){ - player.storage['dddxiaheng_del']=true; + "step 5"; + if (player.getStorage("dddxiaheng").length >= 3) { + player.storage["dddxiaheng_del"] = true; } - } + }, }, //刘巴 - dddfengzheng:{ - audio:2, - global:'dddfengzheng_global', - trigger:{ - global:'roundStart', + dddfengzheng: { + audio: 2, + global: "dddfengzheng_global", + trigger: { + global: "roundStart", }, - filter(event,player){ - return game.hasPlayer(current=>{ - var history=current.actionHistory; - for(var i=history.length-2;i>=0;i--){ - var evts=history[i].useSkill; - for(var evt of evts){ - if(evt.skill=='dddfengzheng_global') return true; + filter(event, player) { + return game.hasPlayer((current) => { + var history = current.actionHistory; + for (var i = history.length - 2; i >= 0; i--) { + var evts = history[i].useSkill; + for (var evt of evts) { + if (evt.skill == "dddfengzheng_global") return true; } - if(history[i].isRound) break; + if (history[i].isRound) break; } return false; }); }, - prompt2(event,player){ - var num=game.countPlayer(current=>{ - var history=current.actionHistory; - for(var i=history.length-2;i>=0;i--){ - var evts=history[i].useSkill; - for(var evt of evts){ - if(evt.skill=='dddfengzheng_global') return true; + prompt2(event, player) { + var num = game.countPlayer((current) => { + var history = current.actionHistory; + for (var i = history.length - 2; i >= 0; i--) { + var evts = history[i].useSkill; + for (var evt of evts) { + if (evt.skill == "dddfengzheng_global") return true; } - if(history[i].isRound) break; + if (history[i].isRound) break; } return false; }); - return '观看并分配牌堆顶的'+get.cnNumber(num)+'张牌'; + return "观看并分配牌堆顶的" + get.cnNumber(num) + "张牌"; }, - content(){ - 'step 0' - var num=game.countPlayer(current=>{ - var history=current.actionHistory; - for(var i=history.length-2;i>=0;i--){ - var evts=history[i].useSkill; - for(var evt of evts){ - if(evt.skill=='dddfengzheng_global') return true; + content() { + "step 0"; + var num = game.countPlayer((current) => { + var history = current.actionHistory; + for (var i = history.length - 2; i >= 0; i--) { + var evts = history[i].useSkill; + for (var evt of evts) { + if (evt.skill == "dddfengzheng_global") return true; } - if(history[i].isRound) break; + if (history[i].isRound) break; } return false; }); - var cards=game.cardsGotoOrdering(get.cards(num)).cards; - event.cards=cards; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 1' - if(event.cards.length>1){ - player.chooseCardButton('丰政:请选择要分配的牌',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return 1; - return 0; + var cards = game.cardsGotoOrdering(get.cards(num)).cards; + event.cards = cards; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cards.length==1) event._result={links:event.cards.slice(0),bool:true}; + event.given_map = {}; + "step 1"; + if (event.cards.length > 1) { + player + .chooseCardButton("丰政:请选择要分配的牌", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + } else if (event.cards.length == 1) + event._result = { + links: event.cards.slice(0), + bool: true, + }; else event.finish(); - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.cards.removeArray(result.links); - event.togive=result.links.slice(0); - player.chooseTarget('选择一名角色获得'+get.translation(result.links),true).set('ai',function(target){ - var fix=(_status.event.getParent().given_map[target.playerid]||0)+1; - var att=get.attitude(_status.event.player,target)/Math.sqrt(fix); - if(_status.event.enemy) return -att; - else if(att>0) return att/(1+target.countCards('h')); - else return att/100; - }).set('enemy',get.value(event.togive[0],player,'raw')<0); + event.togive = result.links.slice(0); + player + .chooseTarget("选择一名角色获得" + get.translation(result.links), true) + .set("ai", function (target) { + var fix = (_status.event.getParent().given_map[target.playerid] || 0) + 1; + var att = get.attitude(_status.event.player, target) / Math.sqrt(fix); + if (_status.event.enemy) return -att; + else if (att > 0) return att / (1 + target.countCards("h")); + else return att / 100; + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); } - 'step 3' - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + "step 3"; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(cards.length>0) event.goto(1); - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length > 0) event.goto(1); + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var list=[],lose=false; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - list.push([source,event.given_map[i]]); - if(event.given_map[i].length>2) lose=true; + var list = [], + lose = false; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + list.push([source, event.given_map[i]]); + if (event.given_map[i].length > 2) lose = true; } game.loseAsync({ - gain_list:list, - giver:player, - animate:'draw', - }).setContent('gaincardMultiple'); - if(!lose) event.finish(); - 'step 5' - player.removeSkills('dddfengzheng'); + gain_list: list, + giver: player, + animate: "draw", + }).setContent("gaincardMultiple"); + if (!lose) event.finish(); + "step 5"; + player.removeSkills("dddfengzheng"); }, - subSkill:{ - global:{ - audio:'dddfengzheng', - enable:'phaseUse', - usable:1, - filter(event,player){ - return game.hasPlayer(current=>current.hasSkill('dddfengzheng')); + subSkill: { + global: { + audio: "dddfengzheng", + enable: "phaseUse", + usable: 1, + filter(event, player) { + return game.hasPlayer((current) => current.hasSkill("dddfengzheng")); }, - filterCard(card,player){ - var num=0; - for(var i=0;iget.number(i,false)==number); - }, - content(){ - 'step 0' - player.chooseControl('摸牌','弃牌').set('prompt','玉律:令'+get.translation(_status.currentPhase)+'摸一张牌或弃置一张牌').set('ai',()=>{ - return get.attitude(_status.event.player,_status.currentPhase)>0?'摸牌':'弃牌'; - }); - 'step 1' - player.logSkill('dddyulv_enter',_status.currentPhase); - var reset=false; - if(result.index==0) _status.currentPhase.draw(); - else _status.currentPhase.chooseToDiscard(true,'he'); - var reset=player.getHistory('useSkill',evt=>{ - return evt.skill=='dddyulv_enter'; - }).length==2; - if(!reset) event.finish(); - 'step 2' - if(!player.countCards('h')) player.draw(); - 'step 3' - if(!player.countCards('h')) event.finish(); - else player.chooseCard('玉律:选择一张手牌交换“玉律”('+get.translation(player.getExpansions('dddyulv'))+')',true); - 'step 4' - if(result.bool){ - player.gain(player.getExpansions('dddyulv'),player,'give'); - player.addToExpansion(result.cards,player,'log','give').gaintag.add('dddyulv'); - } - } + position: "hs", + viewAs: { name: "wuzhong" }, }, - } + }, }, - dddyulv_old:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dddyulv: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - group:'dddyulv_old_enter', - content(){ - 'step 0' - player.chooseControl(Array.from({length:13},(_,i)=>get.strNumber(i+1))).set('prompt','玉律:声明一个点数').set('ai',()=>_status.event.controls.randomGet()); - 'step 1' - player.popup(result.control); - var number=result.index+1; - player.storage['dddyulv_old']=number; - player.markSkill('dddyulv_old'); + group: "dddyulv_enter", + content() { + "step 0"; + player.draw(); + "step 1"; + if (!player.countCards("he")) event.finish(); + else player.chooseCard("玉律:将一张牌置于武将牌上", true); + "step 2"; + if (result.bool) { + player.addToExpansion(result.cards, player, "give").gaintag.add("dddyulv"); + } }, - intro:{ - content:'声明的点数为#', + marktext: "律", + intro: { + markcount: "expansion", + content: "expansion", }, - subSkill:{ - enter:{ - trigger:{global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter']}, - forced:true, - direct:true, - filter(event,player){ - var cards=event.getd(); - if(!cards.length||!player.storage['dddyulv_old']) return false; - if(!_status.currentPhase||!_status.currentPhase.isIn()) return false; - return cards.some(i=>get.number(i,false)==player.storage['dddyulv_old']); + subSkill: { + enter: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - content(){ - 'step 0' - player.chooseControl('摸牌','弃牌').set('prompt','玉律:令'+get.translation(_status.currentPhase)+'摸一张牌或弃置一张牌').set('ai',()=>{ - return get.attitude(_status.event.player,_status.currentPhase)>0?'摸牌':'弃牌'; - }); - 'step 1' - player.logSkill('dddyulv_old_enter',_status.currentPhase); - var reset=false; - if(result.index==0) _status.currentPhase.draw(); - else _status.currentPhase.chooseToDiscard(true,'he'); - if(_status.currentPhase.hasSkill('dddyulv_old_'+result.index)) reset=true; - _status.currentPhase.removeSkill('dddyulv_old_0'); - _status.currentPhase.removeSkill('dddyulv_old_1'); - _status.currentPhase.addSkill('dddyulv_old_'+result.index); - if(!reset) event.finish(); - 'step 2' - player.chooseControl(Array.from({length:13},(_,i)=>get.strNumber(i+1))).set('prompt','玉律:重新声明一个点数').set('ai',()=>_status.event.controls.randomGet()); - 'step 3' - player.popup(result.control); - var number=result.index+1; - player.storage['dddyulv_old']=number; - player.markSkill('dddyulv_old'); - 'step 4' - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + forced: true, + direct: true, + filter(event, player) { + var cards = event.getd(); + if (!cards.length) return false; + const card = player.getExpansions("dddyulv")[0]; + if (!card) return false; + const number = get.number(card, false); + if (!_status.currentPhase || !_status.currentPhase.isIn()) return false; + return cards.some((i) => get.number(i, false) == number); + }, + content() { + "step 0"; + player + .chooseControl("摸牌", "弃牌") + .set( + "prompt", + "玉律:令" + + get.translation(_status.currentPhase) + + "摸一张牌或弃置一张牌" + ) + .set("ai", () => { + return get.attitude(_status.event.player, _status.currentPhase) > 0 + ? "摸牌" + : "弃牌"; + }); + "step 1"; + player.logSkill("dddyulv_enter", _status.currentPhase); + var reset = false; + if (result.index == 0) _status.currentPhase.draw(); + else _status.currentPhase.chooseToDiscard(true, "he"); + var reset = + player.getHistory("useSkill", (evt) => { + return evt.skill == "dddyulv_enter"; + }).length == 2; + if (!reset) event.finish(); + "step 2"; + if (!player.countCards("h")) player.draw(); + "step 3"; + if (!player.countCards("h")) event.finish(); + else + player.chooseCard( + "玉律:选择一张手牌交换“玉律”(" + + get.translation(player.getExpansions("dddyulv")) + + ")", + true + ); + "step 4"; + if (result.bool) { + player.gain(player.getExpansions("dddyulv"), player, "give"); + player + .addToExpansion(result.cards, player, "log", "give") + .gaintag.add("dddyulv"); } - var evt=trigger.getParent('phase'); - if(evt&&evt.name=='phase'){ - game.log(evt.player,'结束了回合'); + }, + }, + }, + }, + dddyulv_old: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", + }, + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; + }, + group: "dddyulv_old_enter", + content() { + "step 0"; + player + .chooseControl(Array.from({ length: 13 }, (_, i) => get.strNumber(i + 1))) + .set("prompt", "玉律:声明一个点数") + .set("ai", () => _status.event.controls.randomGet()); + "step 1"; + player.popup(result.control); + var number = result.index + 1; + player.storage["dddyulv_old"] = number; + player.markSkill("dddyulv_old"); + }, + intro: { + content: "声明的点数为#", + }, + subSkill: { + enter: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], + }, + forced: true, + direct: true, + filter(event, player) { + var cards = event.getd(); + if (!cards.length || !player.storage["dddyulv_old"]) return false; + if (!_status.currentPhase || !_status.currentPhase.isIn()) return false; + return cards.some((i) => get.number(i, false) == player.storage["dddyulv_old"]); + }, + content() { + "step 0"; + player + .chooseControl("摸牌", "弃牌") + .set( + "prompt", + "玉律:令" + + get.translation(_status.currentPhase) + + "摸一张牌或弃置一张牌" + ) + .set("ai", () => { + return get.attitude(_status.event.player, _status.currentPhase) > 0 + ? "摸牌" + : "弃牌"; + }); + "step 1"; + player.logSkill("dddyulv_old_enter", _status.currentPhase); + var reset = false; + if (result.index == 0) _status.currentPhase.draw(); + else _status.currentPhase.chooseToDiscard(true, "he"); + if (_status.currentPhase.hasSkill("dddyulv_old_" + result.index)) reset = true; + _status.currentPhase.removeSkill("dddyulv_old_0"); + _status.currentPhase.removeSkill("dddyulv_old_1"); + _status.currentPhase.addSkill("dddyulv_old_" + result.index); + if (!reset) event.finish(); + "step 2"; + player + .chooseControl(Array.from({ length: 13 }, (_, i) => get.strNumber(i + 1))) + .set("prompt", "玉律:重新声明一个点数") + .set("ai", () => _status.event.controls.randomGet()); + "step 3"; + player.popup(result.control); + var number = result.index + 1; + player.storage["dddyulv_old"] = number; + player.markSkill("dddyulv_old"); + "step 4"; + var evt = trigger.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; + } + var evt = trigger.getParent("phase"); + if (evt && evt.name == "phase") { + game.log(evt.player, "结束了回合"); evt.finish(); evt.untrigger(true); } - } + }, }, - 0:{charlotte:true}, - 1:{charlotte:true}, - } + 0: { charlotte: true }, + 1: { charlotte: true }, + }, }, //蹇硕 - dddfenye:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ + dddfenye: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { return player.canCompare(target); }, - filter(event,player){ - return player.countCards('h')>0; + filter(event, player) { + return player.countCards("h") > 0; }, - content(){ - 'step 0' - player.chooseToCompare([target]).setContent(lib.skill['dddfenye'].chooseToCompareFenye); - 'step 1' - result.winner.forEach(i=>i.addExpose(0.05)); - result.loser.forEach(i=>i.addExpose(0.05)); - if(result.winner.length&&result.loser.length){ - var players=result.winner; - event.players=players.sortBySeat(); - event.targets=result.loser; - } - else event.finish(); - 'step 2' - var current=event.players.shift(); - event.current=current; - current.chooseTarget('是否视为对一名没赢的角色使用一张【杀】?',(card,player,target)=>{ - return player.canUse('sha',target,false)&&_status.event.targets.includes(target); - }).set('ai',target=>{ - return get.effect(target,{name:'sha'},get.player(),get.player()); - }).set('targets',event.targets); - 'step 3' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - var target=result.targets[0]; - event.current.useCard({name:'sha',isCard:true},target,false); + content() { + "step 0"; + player.chooseToCompare([target]).setContent(lib.skill["dddfenye"].chooseToCompareFenye); + "step 1"; + result.winner.forEach((i) => i.addExpose(0.05)); + result.loser.forEach((i) => i.addExpose(0.05)); + if (result.winner.length && result.loser.length) { + var players = result.winner; + event.players = players.sortBySeat(); + event.targets = result.loser; + } else event.finish(); + "step 2"; + var current = event.players.shift(); + event.current = current; + current + .chooseTarget("是否视为对一名没赢的角色使用一张【杀】?", (card, player, target) => { + return ( + player.canUse("sha", target, false) && _status.event.targets.includes(target) + ); + }) + .set("ai", (target) => { + return get.effect(target, { name: "sha" }, get.player(), get.player()); + }) + .set("targets", event.targets); + "step 3"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + var target = result.targets[0]; + event.current.useCard({ name: "sha", isCard: true }, target, false); event.targets.remove(target); } - if(event.targets.length&&event.players.length) event.goto(2); + if (event.targets.length && event.players.length) event.goto(2); }, - chooseToCompareFenye(){ - "step 0" - var target=event.targets[0]; + chooseToCompareFenye() { + "step 0"; + var target = event.targets[0]; event.targets.unshift(player); - event.targetx=target; - if(player.countCards('h')==0||target.countCards('h')==0){ - event.result={cancelled:true,bool:false} + event.targetx = target; + if (player.countCards("h") == 0 || target.countCards("h") == 0) { + event.result = { cancelled: true, bool: false }; event.finish(); return; } - game.log(player,'对',target,'发起拼点'); - "step 1" - var send=function(targets){ - var next=game.createEvent('dddfenye_choose',false); + game.log(player, "对", target, "发起拼点"); + "step 1"; + var send = function (targets) { + var next = game.createEvent("dddfenye_choose", false); // next.player=game.me; - next.targets=targets; - next.ai=event.ai; - next.fixedResult=event.fixedResult; - next.setContent(lib.skill['dddfenye'].contentx); + next.targets = targets; + next.ai = event.ai; + next.fixedResult = event.fixedResult; + next.setContent(lib.skill["dddfenye"].contentx); game.resume(); }; - var sendback=function(result,player){ - if(!Array.isArray(result)){ - result=[null,null]; + var sendback = function (result, player) { + if (!Array.isArray(result)) { + result = [null, null]; } - event.results.push([player,result]); + event.results.push([player, result]); }; - event.ai_targets=[]; - event.results=[]; - var players=game.filterPlayer().sortBySeat(); - var time=10000; - if(lib.configOL&&lib.configOL.choose_timeout) time=parseInt(lib.configOL.choose_timeout)*1000; - for(var i=0;i{ - return event.ai(b)-event.ai(a); + if (event.ai_targets.length) { + for (var i = 0; i < event.ai_targets.length; i++) { + if (targets.includes(event.ai_targets[i])) { + var target = event.ai_targets[i]; + var cards = target.getCards("h").sort((a, b) => { + return event.ai(b) - event.ai(a); }); - sendback([target,cards[0]],target); - event.ai_targets.splice(i--,1); + sendback([target, cards[0]], target); + event.ai_targets.splice(i--, 1); } } - if(event.ai_targets.length){ + if (event.ai_targets.length) { event.ai_targets.randomSort(); - setTimeout(function(){ - event.interval=setInterval(function(){ - var target=event.ai_targets.shift(); - var cards=target.getCards('h',card=>get.value(card)<4).sort((a,b)=>{ - return event.ai(b)-event.ai(a); - }); - if(!cards.length){ - sendback([null,null],target); - } - else{ - if(Math.abs(get.number(cards[0])-7)<=2){ - sendback([null,null],target); - } - else{ - var sgn=get.number(cards[0])>=7?1:-1; - var targetsx=targets.slice().sort((a,b)=>{ - var attA=get.attitude(target,a),attB=get.attitude(target,b); - return sgn*(attB-attA); + setTimeout(function () { + event.interval = setInterval( + function () { + var target = event.ai_targets.shift(); + var cards = target + .getCards("h", (card) => get.value(card) < 4) + .sort((a, b) => { + return event.ai(b) - event.ai(a); }); - sendback([targetsx[0],cards[0]],target); + if (!cards.length) { + sendback([null, null], target); + } else { + if (Math.abs(get.number(cards[0]) - 7) <= 2) { + sendback([null, null], target); + } else { + var sgn = get.number(cards[0]) >= 7 ? 1 : -1; + var targetsx = targets.slice().sort((a, b) => { + var attA = get.attitude(target, a), + attB = get.attitude(target, b); + return sgn * (attB - attA); + }); + sendback([targetsx[0], cards[0]], target); + } } - } - if(!event.ai_targets.length){ - clearInterval(event.interval); - if(event.withai) game.resume(); - } - },_status.connectMode?750:75); - },500); + if (!event.ai_targets.length) { + clearInterval(event.interval); + if (event.withai) game.resume(); + } + }, + _status.connectMode ? 750 : 75 + ); + }, 500); } } - "step 2" - if(event.withme){ - if(_status.connectMode) game.me.unwait(result,game.me); - else{ - if(!Array.isArray(result)){ - result=[null,null]; + "step 2"; + if (event.withme) { + if (_status.connectMode) game.me.unwait(result, game.me); + else { + if (!Array.isArray(result)) { + result = [null, null]; } - event.results.push([game.me,result]); + event.results.push([game.me, result]); } } - "step 3" - if(event.withol&&!event.resultOL){ + "step 3"; + if (event.withol && !event.resultOL) { game.pause(); } - "step 4" - if(event.ai_targets.length>0){ - event.withai=true; + "step 4"; + if (event.ai_targets.length > 0) { + event.withai = true; game.pause(); } - "step 5" + "step 5"; delete event._global_waiting; - for(var i of game.players) i.hideTimer(); - var cards=[]; - var targets=[]; - var lose_list=[]; - event.results.sort((a,b)=>lib.sort.seat(a[0],b[0])); - for(var res of event.results){ - var target=res[0],card=res[1][1],skill=res[1][2]; - if(!target||!card) continue; - if(skill&&lib.skill[skill]&&lib.skill[skill].onCompare){ + for (var i of game.players) i.hideTimer(); + var cards = []; + var targets = []; + var lose_list = []; + event.results.sort((a, b) => lib.sort.seat(a[0], b[0])); + for (var res of event.results) { + var target = res[0], + card = res[1][1], + skill = res[1][2]; + if (!target || !card) continue; + if (skill && lib.skill[skill] && lib.skill[skill].onCompare) { target.logSkill(skill); - res[1][1]=lib.skill[skill].onCompare(target); - if(target!=player) cards.push(res[1][1]); + res[1][1] = lib.skill[skill].onCompare(target); + if (target != player) cards.push(res[1][1]); + } else { + if (target != player) cards.push(card); + lose_list.push([target, [card]]); } - else{ - if(target!=player) cards.push(card); - lose_list.push([target,[card]]); - } - if(target!=player) targets.push(target); + if (target != player) targets.push(target); } - if(lose_list.length){ + if (lose_list.length) { game.loseAsync({ - lose_list:lose_list, - }).setContent('chooseToCompareLose'); + lose_list: lose_list, + }).setContent("chooseToCompareLose"); } - event.lose_list=lose_list; - event.getNum=function(card){ - for(var i of event.lose_list){ - if(i[1].includes&&i[1].includes(card)) return get.number(card,i[0]); + event.lose_list = lose_list; + event.getNum = function (card) { + for (var i of event.lose_list) { + if (i[1].includes && i[1].includes(card)) return get.number(card, i[0]); } - return get.number(card,false); - } - event.cardlist=cards; - event.cards=cards; - event.card1=event.results[0][1][1]; - event.num1=event.getNum(event.card1); - event.iwhile=0; - event.targets=targets; - event.tempplayer=event.player; - event.players=event.results.filter(i=>i[1][0]==player&&i[1][1]).map(i=>i[0]); - event.targetsx=event.results.filter(i=>i[1][0]==event.targetx&&i[1][1]).map(i=>i[0]); - event.result={ - player:event.card1, - targets:event.cardlist.slice(0), - num1:[event.num1], - num2:[], - winner:[], - loser:[], + return get.number(card, false); }; - game.log(player,'的拼点牌为',event.card1); - "step 6" - event.target=null; - event.trigger('compare'); - lib.skill['dddfenye'].$compareFenye(event.players,event.results.filter(i=>i[1][0]==player).map(i=>i[1][1]),event.targetsx,event.results.filter(i=>i[1][0]==event.targetx).map(i=>i[1][1])); - "step 7" - if(event.iwhile i[1][0] == player && i[1][1]) + .map((i) => i[0]); + event.targetsx = event.results + .filter((i) => i[1][0] == event.targetx && i[1][1]) + .map((i) => i[0]); + event.result = { + player: event.card1, + targets: event.cardlist.slice(0), + num1: [event.num1], + num2: [], + winner: [], + loser: [], + }; + game.log(player, "的拼点牌为", event.card1); + "step 6"; + event.target = null; + event.trigger("compare"); + lib.skill["dddfenye"].$compareFenye( + event.players, + event.results.filter((i) => i[1][0] == player).map((i) => i[1][1]), + event.targetsx, + event.results.filter((i) => i[1][0] == event.targetx).map((i) => i[1][1]) + ); + "step 7"; + if (event.iwhile < targets.length) { + event.target = targets[event.iwhile]; + event.target.addTempClass("target"); + event.card2 = event.cardlist[event.iwhile]; + event.num2 = event.getNum(event.card2); + game.log(event.target, "的拼点牌为", event.card2); delete event.player; - event.trigger('compare'); - } - else{ - game.delay(0,1000); + event.trigger("compare"); + } else { + game.delay(0, 1000); event.goto(9); } - "step 8" - var key=event.players.includes(target)?'num1':'num2'; + "step 8"; + var key = event.players.includes(target) ? "num1" : "num2"; event.result[key].push(event.num2); event.iwhile++; event.goto(7); - "step 9" - event.player=event.tempplayer; + "step 9"; + event.player = event.tempplayer; delete event.tempplayer; var str; - var num1=event.result.num1.reduce((p,c)=>p+c,0)/event.result.num1.length,num2=event.result.num2.reduce((p,c)=>p+c,0)/event.result.num2.length; - game.log(event.player,'方的点数均值为','#y'+Math.floor(num1*100)/100); - game.log(event.targetx,'方的点数均值为','#y'+Math.floor(num2*100)/100); - if(num1>num2){ - str=get.translation(event.players)+'拼点成功'; - event.players.forEach(i=>i.popup('胜')); - event.targetsx.forEach(i=>i.popup('负')); - event.result.winner=event.players; - event.result.loser=event.targetsx; - } - else{ - str=get.translation(event.players)+'拼点失败'; - if(num1==num2){ - event.players.forEach(i=>i.popup('平')); - event.targetsx.forEach(i=>i.popup('平')); - event.result.loser=event.players.addArray(event.targetsx); - } - else{ - event.players.forEach(i=>i.popup('负')); - event.targetsx.forEach(i=>i.popup('胜')); - event.result.winner=event.targetsx; - event.result.loser=event.players; + var num1 = event.result.num1.reduce((p, c) => p + c, 0) / event.result.num1.length, + num2 = event.result.num2.reduce((p, c) => p + c, 0) / event.result.num2.length; + game.log(event.player, "方的点数均值为", "#y" + Math.floor(num1 * 100) / 100); + game.log(event.targetx, "方的点数均值为", "#y" + Math.floor(num2 * 100) / 100); + if (num1 > num2) { + str = get.translation(event.players) + "拼点成功"; + event.players.forEach((i) => i.popup("胜")); + event.targetsx.forEach((i) => i.popup("负")); + event.result.winner = event.players; + event.result.loser = event.targetsx; + } else { + str = get.translation(event.players) + "拼点失败"; + if (num1 == num2) { + event.players.forEach((i) => i.popup("平")); + event.targetsx.forEach((i) => i.popup("平")); + event.result.loser = event.players.addArray(event.targetsx); + } else { + event.players.forEach((i) => i.popup("负")); + event.targetsx.forEach((i) => i.popup("胜")); + event.result.winner = event.targetsx; + event.result.loser = event.players; } } - game.broadcastAll(function(str){ - var dialog=ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function(){ + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { dialog.close(); - },1000); - },str); + }, 1000); + }, str); game.delay(3); - "step 10" + "step 10"; game.broadcastAll(ui.clear); - "step 11" + "step 11"; event.cards.add(event.card1); }, - contentx(){ - 'step 0' - var player=game.me; - event.player=player; - event._global_waiting=true; - event.result=[]; - if(targets.includes(player)){ - if(event.fixedResult&&event.fixedResult[player.playerid]){ - event.result[0]=player; - event.result[1]=event.fixedResult[player.playerid]; + contentx() { + "step 0"; + var player = game.me; + event.player = player; + event._global_waiting = true; + event.result = []; + if (targets.includes(player)) { + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.result[0] = player; + event.result[1] = event.fixedResult[player.playerid]; event.finish(); - } - else player.chooseCard('请选择拼点牌',true).set('type','compare').set('glow_result',true).set('_global_waiting',true).ai=event.ai; - } - else{ + } else + player + .chooseCard("请选择拼点牌", true) + .set("type", "compare") + .set("glow_result", true) + .set("_global_waiting", true).ai = event.ai; + } else { player.chooseCardTarget({ - targets:targets, - filterTarget(card,player,target){ + targets: targets, + filterTarget(card, player, target) { return _status.event.targets.includes(target); }, - selectCard:1, - prompt:'是否于此次拼点加入其中一方?', - position:'h', - _global_waiting:true, - ai1:event.ai, - ai2(target){ - var player=_status.event.player,sgn=-1; - if(player.hasCard(card=>get.number(card)>10&&get.value(card)<5)) sgn=1; - return sgn*get.attitude(player,target); + selectCard: 1, + prompt: "是否于此次拼点加入其中一方?", + position: "h", + _global_waiting: true, + ai1: event.ai, + ai2(target) { + var player = _status.event.player, + sgn = -1; + if (player.hasCard((card) => get.number(card) > 10 && get.value(card) < 5)) + sgn = 1; + return sgn * get.attitude(player, target); }, }); } - 'step 1' - if(targets.includes(player)){ - event.result[0]=player; - event.result[1]=result.cards[0]; - event.result[2]=result.skill; - } - else{ - if(result.bool){ - event.result[0]=result.targets[0]; - event.result[1]=result.cards[0]; - } - else{ - event.result=[null,null]; + "step 1"; + if (targets.includes(player)) { + event.result[0] = player; + event.result[1] = result.cards[0]; + event.result[2] = result.skill; + } else { + if (result.bool) { + event.result[0] = result.targets[0]; + event.result[1] = result.cards[0]; + } else { + event.result = [null, null]; } } }, - $compareFenye(players,cards1,targets,cards2){ - game.broadcast(function(players,cards1,targets,cards2){ - lib.skill['dddfenye'].$compareFenye(players,cards1,targets,cards2); - },players,cards1,targets,cards2); - var left0=-players.length*52-(players.length-1)*8; - for(var i=0;i{ - return _status.event.targets.includes(target); - }).set('ai',target=>{ - var zhu=get.zhu(player)||game.filterPlayer(i=>i.getSeatNum()==1)[0]; - return Math.min(target.countCards('h')-player.countCards('h'),zhu.maxHp-player.countCards('h')); - }).set('targets',function(){ - var list=game.filterPlayer().map(i=>[i,i.countCards('h')]).sort((a,b)=>b[1]-a[1]); - var targets=[]; - var ind=0,tmp=Infinity; - for(var i of list){ - if(i[1] { + return _status.event.targets.includes(target); } - if(ind==N){ - targets.push(i[0]); - } - if(ind>N) break; - } - if(!targets.length) targets=game.filterPlayer(i=>i.countCards('h')==list[list.length-1][1]); - return targets; - }()); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddshichao',target); - var zhu=get.zhu(player)||game.filterPlayer(i=>i.getSeatNum()==1)[0]; - var del=Math.min(target.countCards('h')-player.countCards('h'),zhu.maxHp-player.countCards('h')); - if(del>0) player.draw(del); - if(del<0) player.chooseToDiscard(-del,true); - target.addSkill('dddshichao_up'); - target.markAuto('dddshichao_up',[player]); - player.addTempSkill('dddshichao_clear',{player:'phaseBegin'}); - player.markAuto('dddshichao_clear',[target]); + ) + .set("ai", (target) => { + var zhu = get.zhu(player) || game.filterPlayer((i) => i.getSeatNum() == 1)[0]; + return Math.min( + target.countCards("h") - player.countCards("h"), + zhu.maxHp - player.countCards("h") + ); + }) + .set( + "targets", + (function () { + var list = game + .filterPlayer() + .map((i) => [i, i.countCards("h")]) + .sort((a, b) => b[1] - a[1]); + var targets = []; + var ind = 0, + tmp = Infinity; + for (var i of list) { + if (i[1] < tmp) { + ind++; + tmp = i[1]; + } + if (ind == N) { + targets.push(i[0]); + } + if (ind > N) break; + } + if (!targets.length) + targets = game.filterPlayer( + (i) => i.countCards("h") == list[list.length - 1][1] + ); + return targets; + })() + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddshichao", target); + var zhu = get.zhu(player) || game.filterPlayer((i) => i.getSeatNum() == 1)[0]; + var del = Math.min( + target.countCards("h") - player.countCards("h"), + zhu.maxHp - player.countCards("h") + ); + if (del > 0) player.draw(del); + if (del < 0) player.chooseToDiscard(-del, true); + target.addSkill("dddshichao_up"); + target.markAuto("dddshichao_up", [player]); + player.addTempSkill("dddshichao_clear", { + player: "phaseBegin", + }); + player.markAuto("dddshichao_clear", [target]); } }, - subSkill:{ - up:{ - trigger:{source:'damageBegin2'}, - filter(event,player){ - return player.getStorage('dddshichao_up').includes(event.player); + subSkill: { + up: { + trigger: { source: "damageBegin2" }, + filter(event, player) { + return player.getStorage("dddshichao_up").includes(event.player); }, - charlotte:true, - check(event,player){ - var eff=get.damageEffect(event.player,player,player); - return event.player.hasSkill('dddshichao')&&eff<0||event.num==1&&eff<13; + charlotte: true, + check(event, player) { + var eff = get.damageEffect(event.player, player, player); + return ( + (event.player.hasSkill("dddshichao") && eff < 0) || + (event.num == 1 && eff < 13) + ); }, - logTarget:'player', - content(){ - 'step 0' + logTarget: "player", + content() { + "step 0"; trigger.cancel(); - if(trigger.player.hasSkill('dddshichao')){ - trigger.player.addMark('dddshichao',1,false); + if (trigger.player.hasSkill("dddshichao")) { + trigger.player.addMark("dddshichao", 1, false); } - } + }, }, - clear:{ - charlotte:true, - onremove(player){ - game.filterPlayer(current=>{ - current.unmarkAuto('dddshichao_up',[player]); + clear: { + charlotte: true, + onremove(player) { + game.filterPlayer((current) => { + current.unmarkAuto("dddshichao_up", [player]); }); - } - } - } + }, + }, + }, }, //管宁 - dddyouxue:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - content(){ - 'step 0' - if(!game.hasPlayer(current=>current.hasMark('dddyouxue'))) player.addMark('dddyouxue'); - if(!game.hasPlayer(current=>!current.hasMark('dddyouxue'))) event.finish(); - 'step 1' - player.chooseTarget('游学:将“游学”标记交给另一名角色',true,(card,player,target)=>{ - return !target.hasMark('dddyouxue'); - }).set('ai',target=>{ - return get.distance(game.findPlayer(current=>current.hasMark('dddyouxue')),target); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - var source=game.findPlayer(current=>current.hasMark('dddyouxue')); - if(source==player) player.line(target,'green'); - else player.line2([source,target],'green'); - source.clearMark('dddyouxue'); - target.addMark('dddyouxue'); - player.draw(get.distance(source,target)); + dddyouxue: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + content() { + "step 0"; + if (!game.hasPlayer((current) => current.hasMark("dddyouxue"))) + player.addMark("dddyouxue"); + if (!game.hasPlayer((current) => !current.hasMark("dddyouxue"))) event.finish(); + "step 1"; + player + .chooseTarget("游学:将“游学”标记交给另一名角色", true, (card, player, target) => { + return !target.hasMark("dddyouxue"); + }) + .set("ai", (target) => { + return get.distance( + game.findPlayer((current) => current.hasMark("dddyouxue")), + target + ); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + var source = game.findPlayer((current) => current.hasMark("dddyouxue")); + if (source == player) player.line(target, "green"); + else player.line2([source, target], "green"); + source.clearMark("dddyouxue"); + target.addMark("dddyouxue"); + player.draw(get.distance(source, target)); } }, - marktext:'游', - intro:{ - name:'游学', - content:()=>get.translation(game.filterPlayer(current=>current.hasSkill('dddyouxue')))+'到此一游', + marktext: "游", + intro: { + name: "游学", + content: () => + get.translation(game.filterPlayer((current) => current.hasSkill("dddyouxue"))) + + "到此一游", }, }, - dddchengjing:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter(event,player){ - if(!event.player.hasMark('dddyouxue')) return false; - return event.player.hasHistory('useCard',evt=>{ - if(!['basic','trick'].includes(get.type(evt.card))) return false; - if(!evt.card.isCard||evt.cards.length!=1) return false; - return get.position(evt.cards[0],true)=='d'; + dddchengjing: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter(event, player) { + if (!event.player.hasMark("dddyouxue")) return false; + return event.player.hasHistory("useCard", (evt) => { + if (!["basic", "trick"].includes(get.type(evt.card))) return false; + if (!evt.card.isCard || evt.cards.length != 1) return false; + return get.position(evt.cards[0], true) == "d"; }); }, - forced:true, - locked:false, - group:'dddchengjing_use', - logTarget:'player', - *content(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - let history=target.getHistory('useCard').reverse(); - let cards=[]; - for(var evt of history){ - if(!['basic','trick'].includes(get.type(evt.card))) continue; - if(!evt.card.isCard||evt.cards.length!=1) continue; - if(get.position(evt.cards[0],true)=='d'){ + forced: true, + locked: false, + group: "dddchengjing_use", + logTarget: "player", + *content(event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + let history = target.getHistory("useCard").reverse(); + let cards = []; + for (var evt of history) { + if (!["basic", "trick"].includes(get.type(evt.card))) continue; + if (!evt.card.isCard || evt.cards.length != 1) continue; + if (get.position(evt.cards[0], true) == "d") { cards.addArray(evt.cards); break; } } - const jing=player.getExpansions('dddchengjing'); - if(jing.length) player.loseToDiscardpile(jing); - player.addToExpansion(cards,'log','gain2').gaintag.add('dddchengjing'); + const jing = player.getExpansions("dddchengjing"); + if (jing.length) player.loseToDiscardpile(jing); + player.addToExpansion(cards, "log", "gain2").gaintag.add("dddchengjing"); }, - marktext:'经', - intro:{ - name:'经(承经)', - name2:'经', - markcount:'expansion', - content:'expansion', + marktext: "经", + intro: { + name: "经(承经)", + name2: "经", + markcount: "expansion", + content: "expansion", }, - subSkill:{ - use:{ - audio:'dddchengjing', - enable:'phaseUse', - usable:1, - filterCard:true, - position:'hes', - filter(event,player){ - return player.getExpansions('dddchengjing').length>0; + subSkill: { + use: { + audio: "dddchengjing", + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "hes", + filter(event, player) { + return player.getExpansions("dddchengjing").length > 0; }, - viewAs(cards,player){ - const card=player.getExpansions('dddchengjing')[0]; + viewAs(cards, player) { + const card = player.getExpansions("dddchengjing")[0]; return new lib.element.VCard({ - name:get.name(card,false), - nature:get.nature(card,false), - storage:{dddchengjing:true}, + name: get.name(card, false), + nature: get.nature(card, false), + storage: { dddchengjing: true }, }); }, - popname:true, - prompt(){ - const card=get.player().getExpansions('dddchengjing')[0]; - return '将一张牌当'+get.translation({ - name:get.name(card,false), - nature:get.nature(card,false) - })+'使用'; + popname: true, + prompt() { + const card = get.player().getExpansions("dddchengjing")[0]; + return ( + "将一张牌当" + + get.translation({ + name: get.name(card, false), + nature: get.nature(card, false), + }) + + "使用" + ); }, - precontent(){ - player.when('useCardAfter').filter(evt=>evt.card.storage.dddchengjing).then(()=>{ - var cards=trigger.cards.filterInD('od'); - if(!cards.length){event.finish();return}; - var target=game.findPlayer(current=>current.hasMark('dddyouxue')); - if(!target){event.finish();return}; - target=target.getNext(); - event.target=target; - player.chooseBool(`承经:是否将${get.translation(cards)}交给${get.translation(target)}?`).set('choice',get.attitude(player,target)>0); - }).then(()=>{ - if(result.bool){ - player.line(event.target); - player.addExpose(0.1); - event.target.gain(trigger.cards.filterInD('od'),'gain2'); - } - }); + precontent() { + player + .when("useCardAfter") + .filter((evt) => evt.card.storage.dddchengjing) + .then(() => { + var cards = trigger.cards.filterInD("od"); + if (!cards.length) { + event.finish(); + return; + } + var target = game.findPlayer((current) => current.hasMark("dddyouxue")); + if (!target) { + event.finish(); + return; + } + target = target.getNext(); + event.target = target; + player + .chooseBool( + `承经:是否将${get.translation(cards)}交给${get.translation( + target + )}?` + ) + .set("choice", get.attitude(player, target) > 0); + }) + .then(() => { + if (result.bool) { + player.line(event.target); + player.addExpose(0.1); + event.target.gain(trigger.cards.filterInD("od"), "gain2"); + } + }); }, - } + }, + }, + ai: { + combo: "dddyouxue" }, }, - dddyouxue_old:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - content(){ - 'step 0' - var vpos=player.hasMark('dddyouxue_old')?game.filterPlayer2(i=>i.getSeatNum()==player.countMark('dddyouxue_old'))[0]:player; - event.vpos=vpos; - player.chooseTarget('游学:选择你的行动次序',true).set('ai',target=>{ - return get.distance(_status.event.vpos,target); - }).set('vpos',vpos); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(event.vpos==player) player.line(target,'green'); - else player.line2([event.vpos,target],'green'); - event.num=get.distance(event.vpos,target); - player.storage['dddyouxue_old']=target.getSeatNum(); - player.addSkill('dddyouxue_old_act'); - player.markSkill('dddyouxue_old'); - } - else event.finish(); - 'step 2' - var next=player.phaseDraw(); - next.set('num',num); + dddyouxue_old: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + content() { + "step 0"; + var vpos = player.hasMark("dddyouxue_old") + ? game.filterPlayer2((i) => i.getSeatNum() == player.countMark("dddyouxue_old"))[0] + : player; + event.vpos = vpos; + player + .chooseTarget("游学:选择你的行动次序", true) + .set("ai", (target) => { + return get.distance(_status.event.vpos, target); + }) + .set("vpos", vpos); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (event.vpos == player) player.line(target, "green"); + else player.line2([event.vpos, target], "green"); + event.num = get.distance(event.vpos, target); + player.storage["dddyouxue_old"] = target.getSeatNum(); + player.addSkill("dddyouxue_old_act"); + player.markSkill("dddyouxue_old"); + } else event.finish(); + "step 2"; + var next = player.phaseDraw(); + next.set("num", num); delete next.skill; - 'step 3' - player.skip('phaseDraw'); + "step 3"; + player.skip("phaseDraw"); }, - marktext:'虚', - intro:{ - name:'虚位', - content:'当前虚位为#号', + marktext: "虚", + intro: { + name: "虚位", + content: "当前虚位为#号", }, - subSkill:{ - act:{ - trigger:{ - global:['phaseBefore','phaseAfter','phaseYouxueed'], + subSkill: { + act: { + trigger: { + global: ["phaseBefore", "phaseAfter", "phaseYouxueed"], }, - forced:true, - firstDo:true, - charlotte:true, - filter(event,player,name){ - if(event.skill) return false; - var vseat=player.countMark('dddyouxue_old'); - if(name!='phaseBefore'){ - if(player.hasSkill('dddyouxue_old_acted',null,false,false)) return false; - var seat=event.player.getSeatNum(); - var next=event.player.next; - if(!game.players.includes(next)) next=game.findNext(next); - var seat2=next.getSeatNum(); - if(seat==seat2) return false; - if(seatseat&&vseat<=seat2; - return seat2>=vseat; - } - else{ - return event.player==player; + forced: true, + firstDo: true, + charlotte: true, + filter(event, player, name) { + if (event.skill) return false; + var vseat = player.countMark("dddyouxue_old"); + if (name != "phaseBefore") { + if (player.hasSkill("dddyouxue_old_acted", null, false, false)) return false; + var seat = event.player.getSeatNum(); + var next = event.player.next; + if (!game.players.includes(next)) next = game.findNext(next); + var seat2 = next.getSeatNum(); + if (seat == seat2) return false; + if (seat < seat2) return vseat > seat && vseat <= seat2; + return seat2 >= vseat; + } else { + return event.player == player; } }, - content(){ - if(event.triggername=='phaseBefore'){ + content() { + if (event.triggername == "phaseBefore") { trigger.finish(); trigger.untrigger(true); - trigger._triggered=5; - trigger.trigger('phaseYouxueed'); + trigger._triggered = 5; + trigger.trigger("phaseYouxueed"); + } else { + player.insertPhase("dddyouxue_old_act"); + player.addTempSkill("dddyouxue_old_acted", "roundStart"); } - else{ - player.insertPhase('dddyouxue_old_act'); - player.addTempSkill('dddyouxue_old_acted','roundStart'); - } - } + }, }, - acted:{charlotte:true} - } - }, - dddchengjing_old:{ - audio:2, - usable:1, - enable:'phaseUse', - filter(event,player){ - return player.countCards('hes')>0&&player.countMark('dddyouxue_old')>0&&lib.skill['dddchengjing_old'].getList(player).length>0; + acted: { charlotte: true }, }, - getList(player){ - var vpos=player.hasMark('dddyouxue_old')?game.filterPlayer2(i=>i.getSeatNum()==player.countMark('dddyouxue_old'))[0]:player; - if(!vpos||!vpos.isIn()) return []; - var vcard=[]; - var history=vpos.getPrevious().actionHistory.filter(evt=>!evt.custom.some(i=>i['dddyouxue_old'])); - history=history[history.length-2]; - var evts=history.useCard; - for(var evt of evts){ - var card=evt.card; - var type=get.type(card); - if(type!='basic'&&type!='trick') continue; - if(card.name=='sha'){ - vcard.push(['基本','',card.name,card.nature]); - } - else vcard.push([type,'',card.name]); + }, + dddchengjing_old: { + audio: 2, + usable: 1, + enable: "phaseUse", + filter(event, player) { + return ( + player.countCards("hes") > 0 && + player.countMark("dddyouxue_old") > 0 && + lib.skill["dddchengjing_old"].getList(player).length > 0 + ); + }, + getList(player) { + var vpos = player.hasMark("dddyouxue_old") + ? game.filterPlayer2((i) => i.getSeatNum() == player.countMark("dddyouxue_old"))[0] + : player; + if (!vpos || !vpos.isIn()) return []; + var vcard = []; + var history = vpos + .getPrevious() + .actionHistory.filter((evt) => !evt.custom.some((i) => i["dddyouxue_old"])); + history = history[history.length - 2]; + var evts = history.useCard; + for (var evt of evts) { + var card = evt.card; + var type = get.type(card); + if (type != "basic" && type != "trick") continue; + if (card.name == "sha") { + vcard.push(["基本", "", card.name, card.nature]); + } else vcard.push([type, "", card.name]); } return vcard; }, - chooseButton:{ - dialog(event,player){ - var list=lib.skill['dddchengjing_old'].getList(player); - list.sort((a,b)=>{ - return 100*(lib.inpile.indexOf(a[2])-lib.inpile.indexOf(b[2]))+lib.inpile_nature.indexOf(a[3])-lib.inpile_nature.indexOf(b[3]); + chooseButton: { + dialog(event, player) { + var list = lib.skill["dddchengjing_old"].getList(player); + list.sort((a, b) => { + return ( + 100 * (lib.inpile.indexOf(a[2]) - lib.inpile.indexOf(b[2])) + + lib.inpile_nature.indexOf(a[3]) - + lib.inpile_nature.indexOf(b[3]) + ); }); - list.filter(vcard=>{ - return event.filterCard({name:vcard[2],nature:vcard[3]},player,event); - }) - return ui.create.dialog('承经',[list,'vcard']); + list.filter((vcard) => { + return event.filterCard({ name: vcard[2], nature: vcard[3] }, player, event); + }); + return ui.create.dialog("承经", [list, "vcard"]); }, - filter(button,player){ - return _status.event.getParent().filterCard({name:button.link[2]},player,_status.event.getParent()); + filter(button, player) { + return _status.event + .getParent() + .filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, - check(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; + check(button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; return player.getUseValue({ - name:button.link[2], - nature:button.link[3], + name: button.link[2], + nature: button.link[3], }); }, - backup(links,player){ + backup(links, player) { return { - filterCard:true, - audio:'dddchengjing_old', - popname:true, - check(card){ - return 8-get.value(card); + filterCard: true, + audio: "dddchengjing_old", + popname: true, + check(card) { + return 8 - get.value(card); }, - position:'hes', - viewAs:{ - name:links[0][2], - nature:links[0][3], - storage:{'dddchengjing_old':true} + position: "hes", + viewAs: { + name: links[0][2], + nature: links[0][3], + storage: { dddchengjing_old: true }, }, - precontent(){ - player.addTempSkill('dddchengjing_old_effect'); + precontent() { + player.addTempSkill("dddchengjing_old_effect"); }, - } + }; }, - prompt(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } - }, - ai:{ - combo:'dddyouxue_old', - order:1, - result:{ - player:1, + prompt(links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - subSkill:{ - effect:{ - audio:'dddchengjing_old', - trigger:{global:'useCardAfter'}, - charlotte:true, - direct:true, - filter(event,player){ - return event.card&&event.card.storage&&event.card.storage['dddchengjing_old']; - }, - content(){ - 'step 0' - var damaged=game.hasPlayer2(current=>current.hasHistory('damage',evt=>evt.card==trigger.card)); - event.damaged=damaged; - var vpos=player.hasMark('dddyouxue_old')?game.filterPlayer2(i=>i.getSeatNum()==player.countMark('dddyouxue_old'))[0]:player; - var target=vpos.getNext(); - event.target=target; - player.chooseControl(' +1 ',' -1 ','cancel2').set('prompt','是否令“虚位”下家('+get.translation(target)+')下回合的'+(damaged?'摸牌数':'手牌上限')+'+1或-1?').set('ai',function(){ - var sgn=get.sgn(get.attitude(_status.event.player,_status.event.target)); - if(sgn==0) return 2; - if(sgn==1) return 0; - return 1; - }).set('target',target); - 'step 1' - if(result.index!=2){ - player.logSkill('dddchengjing_old_effect',target); - var name=(event.damaged?'draw':'limit')+result.index; - target.addTempSkill('dddchengjing_old_check',{player:'phaseAfter'}); - target.addMark('dddchengjing_old_'+name,1,false); - game.log(target,'下回合的'+(event.damaged?'摸牌数':'手牌上限'),'#y'+(['+1','-1'][result.index])); - } - } + ai: { + combo: "dddyouxue_old", + order: 1, + result: { + player: 1, }, - check:{ - trigger:{player:'phaseDrawBegin2'}, - charlotte:true, - forced:true, - filter(event,player){ - return player.countMark('dddchengjing_old_draw0')>0||player.countMark('dddchengjing_old_draw1')>0; + }, + subSkill: { + effect: { + audio: "dddchengjing_old", + trigger: { global: "useCardAfter" }, + charlotte: true, + direct: true, + filter(event, player) { + return event.card && event.card.storage && event.card.storage["dddchengjing_old"]; }, - content(){ - trigger.num+=player.countMark('dddchengjing_old_draw0')-player.countMark('dddchengjing_old_draw1'); - }, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('dddchengjing_old_limit0')-player.countMark('dddchengjing_old_limit1'); + content() { + "step 0"; + var damaged = game.hasPlayer2((current) => + current.hasHistory("damage", (evt) => evt.card == trigger.card) + ); + event.damaged = damaged; + var vpos = player.hasMark("dddyouxue_old") + ? game.filterPlayer2( + (i) => i.getSeatNum() == player.countMark("dddyouxue_old") + )[0] + : player; + var target = vpos.getNext(); + event.target = target; + player + .chooseControl(" +1 ", " -1 ", "cancel2") + .set( + "prompt", + "是否令“虚位”下家(" + + get.translation(target) + + ")下回合的" + + (damaged ? "摸牌数" : "手牌上限") + + "+1或-1?" + ) + .set("ai", function () { + var sgn = get.sgn( + get.attitude(_status.event.player, _status.event.target) + ); + if (sgn == 0) return 2; + if (sgn == 1) return 0; + return 1; + }) + .set("target", target); + "step 1"; + if (result.index != 2) { + player.logSkill("dddchengjing_old_effect", target); + var name = (event.damaged ? "draw" : "limit") + result.index; + target.addTempSkill("dddchengjing_old_check", { + player: "phaseAfter", + }); + target.addMark("dddchengjing_old_" + name, 1, false); + game.log( + target, + "下回合的" + (event.damaged ? "摸牌数" : "手牌上限"), + "#y" + ["+1", "-1"][result.index] + ); } }, - onremove(player){ - delete player.storage['dddchengjing_old_draw0']; - delete player.storage['dddchengjing_old_draw1']; - delete player.storage['dddchengjing_old_limit0']; - delete player.storage['dddchengjing_old_limit1']; + }, + check: { + trigger: { player: "phaseDrawBegin2" }, + charlotte: true, + forced: true, + filter(event, player) { + return ( + player.countMark("dddchengjing_old_draw0") > 0 || + player.countMark("dddchengjing_old_draw1") > 0 + ); }, - mark:true, - marktext:'承', - intro:{ - name:'承经', - content(storage,player){ - var str=''; - if(player.countMark('dddchengjing_old_draw0')||player.countMark('dddchengjing_old_draw1')){ - var num=player.countMark('dddchengjing_old_draw0')-player.countMark('dddchengjing_old_draw1'); - str+='
            • 摸牌阶段摸牌数'+(num>=0?'+':'')+num; + content() { + trigger.num += + player.countMark("dddchengjing_old_draw0") - + player.countMark("dddchengjing_old_draw1"); + }, + mod: { + maxHandcard(player, num) { + return ( + num + + player.countMark("dddchengjing_old_limit0") - + player.countMark("dddchengjing_old_limit1") + ); + }, + }, + onremove(player) { + delete player.storage["dddchengjing_old_draw0"]; + delete player.storage["dddchengjing_old_draw1"]; + delete player.storage["dddchengjing_old_limit0"]; + delete player.storage["dddchengjing_old_limit1"]; + }, + mark: true, + marktext: "承", + intro: { + name: "承经", + content(storage, player) { + var str = ""; + if ( + player.countMark("dddchengjing_old_draw0") || + player.countMark("dddchengjing_old_draw1") + ) { + var num = + player.countMark("dddchengjing_old_draw0") - + player.countMark("dddchengjing_old_draw1"); + str += "
            • 摸牌阶段摸牌数" + (num >= 0 ? "+" : "") + num; } - if(player.countMark('dddchengjing_old_limit0')||player.countMark('dddchengjing_old_limit1')){ - var num=player.countMark('dddchengjing_old_limit0')-player.countMark('dddchengjing_old_limit1'); - str+='
            • 手牌上限'+(num>=0?'+':'')+num; + if ( + player.countMark("dddchengjing_old_limit0") || + player.countMark("dddchengjing_old_limit1") + ) { + var num = + player.countMark("dddchengjing_old_limit0") - + player.countMark("dddchengjing_old_limit1"); + str += "
            • 手牌上限" + (num >= 0 ? "+" : "") + num; } return str; - } - } + }, + }, }, - draw0:{charlotte:true}, - draw1:{charlotte:true}, - limit0:{charlotte:true}, - limit1:{charlotte:true}, - } + draw0: { charlotte: true }, + draw1: { charlotte: true }, + limit0: { charlotte: true }, + limit1: { charlotte: true }, + }, }, - dddduanbing:{ - enable:'phaseUse', - filter(event,player){ - return player.canAddJudge('bingliang')&&player.hasCard((card)=>lib.skill['dddduanbing'].filterCard(card,player),'he'); + dddduanbing: { + enable: "phaseUse", + filter(event, player) { + return ( + player.canAddJudge("bingliang") && + player.hasCard((card) => lib.skill["dddduanbing"].filterCard(card, player), "he") + ); }, - filterCard(card,player){ - if(get.color(card)!='black'||get.type2(card)=='trick') return false; - return player.canAddJudge(get.autoViewAs({name:'bingliang'},[card])); + filterCard(card, player) { + if (get.color(card) != "black" || get.type2(card) == "trick") return false; + return player.canAddJudge(get.autoViewAs({ name: "bingliang" }, [card])); }, - check(card){ - return 8.2-get.value(card); + check(card) { + return 8.2 - get.value(card); }, - discard:false, - lose:false, - delay:false, - prepare:'throw', - group:'dddduanbing_effect', - position:'he', - content(){ - 'step 0' - player.addJudge({name:'bingliang'},cards); - 'step 1' + discard: false, + lose: false, + delay: false, + prepare: "throw", + group: "dddduanbing_effect", + position: "he", + content() { + "step 0"; + player.addJudge({ name: "bingliang" }, cards); + "step 1"; game.delayx(); player.draw(2); - 'step 2' - player.chooseUseTarget({ - name:'sha', - isCard:true, - storage:{_dddduanbing:true}, - },false,'nodistance'); + "step 2"; + player.chooseUseTarget( + { + name: "sha", + isCard: true, + storage: { _dddduanbing: true }, + }, + false, + "nodistance" + ); }, - ai:{ - order(item,player){ - return get.order({name:'sha'})-0.1; + ai: { + order(item, player) { + return get.order({ name: "sha" }) - 0.1; }, - result:{ - player(player){ - return player.getUseValue({name:'sha'},false) + result: { + player(player) { + return player.getUseValue({ name: "sha" }, false); }, }, }, - subSkill:{ - effect:{ - trigger:{source:'damageSource'}, - charlotte:true, - filter(event,player){ - if(event.getParent().type!='card'||!event.player.isIn()) return false; - return player.hasCard(card=>{ - return (card.viewAs||card.name)=='bingliang'&&event.player.canAddJudge(card); - },'j'); + subSkill: { + effect: { + trigger: { source: "damageSource" }, + charlotte: true, + filter(event, player) { + if (event.getParent().type != "card" || !event.player.isIn()) return false; + return player.hasCard((card) => { + return ( + (card.viewAs || card.name) == "bingliang" && + event.player.canAddJudge(card) + ); + }, "j"); }, - prompt:(event)=>('是否将【兵粮寸断】转移给'+get.translation(event.player)+'?'), - check(event,player){ - return player.hasCard(card=>{ - return (card.viewAs||card.name)=='bingliang'&&event.player.canAddJudge(card)&&get.effect(event.player,new lib.element.VCard({ - name:'bingliang', - cards:[card] - }),player,_status.event.player)>=0; - },'j'); + prompt: (event) => "是否将【兵粮寸断】转移给" + get.translation(event.player) + "?", + check(event, player) { + return player.hasCard((card) => { + return ( + (card.viewAs || card.name) == "bingliang" && + event.player.canAddJudge(card) && + get.effect( + event.player, + new lib.element.VCard({ + name: "bingliang", + cards: [card], + }), + player, + _status.event.player + ) >= 0 + ); + }, "j"); }, - content(){ - var cards=player.getCards('j',card=>{ - return (card.viewAs||card.name)=='bingliang'&&trigger.player.canAddJudge(card); + content() { + var cards = player.getCards("j", (card) => { + return ( + (card.viewAs || card.name) == "bingliang" && + trigger.player.canAddJudge(card) + ); }); - var target=trigger.player; + var target = trigger.player; player.line(target); - player.$give(cards,target,false); - cards.forEach(card=>{ - target.addJudge({name:'bingliang'},card); + player.$give(cards, target, false); + cards.forEach((card) => { + target.addJudge({ name: "bingliang" }, card); }); }, }, }, }, //轲比能 - dddxiaoxing:{ - audio:2, - trigger:{global:'gameDrawBegin'}, - forced:true, - group:'dddxiaoxing_remove', - init(player,skill){ - if(game.online) return; - var bool=get.event().getParent('phaseLoop',true); - if(!bool) return; - if(player.hasSkill(skill)){ - player.logSkill('dddxiaoxing'); + dddxiaoxing: { + audio: 2, + trigger: { global: "gameDrawBegin" }, + forced: true, + group: "dddxiaoxing_remove", + init(player, skill) { + if (game.online) return; + var bool = get.event().getParent("phaseLoop", true); + if (!bool) return; + if (player.hasSkill(skill)) { + player.logSkill("dddxiaoxing"); player.draw(3); } }, - content(){ - var me=player; - var numx=trigger.num; - trigger.num=typeof numx=='function'?function(player){ - if(player==me){ - return 3+numx(player); - } - return numx(player); - }:function(player){ - if(player==me){ - return 3+numx; - } - return numx; - } + content() { + var me = player; + var numx = trigger.num; + trigger.num = + typeof numx == "function" + ? function (player) { + if (player == me) { + return 3 + numx(player); + } + return numx(player); + } + : function (player) { + if (player == me) { + return 3 + numx; + } + return numx; + }; }, - mod:{ - attackRange:(player,num)=>num+3, - maxHandcard:(player,num)=>num+3, + mod: { + attackRange: (player, num) => num + 3, + maxHandcard: (player, num) => num + 3, }, - subSkill:{ - remove:{ - trigger:{player:'dying'}, - forced:true, + subSkill: { + remove: { + trigger: { player: "dying" }, + forced: true, // direct:true, // filter(event,player){ // return event.source&&event.source.isIn()&&event.source.getEquips(1).length>0; // }, - content(){ - player.removeSkills('dddxiaoxing'); + content() { + player.removeSkills("dddxiaoxing"); }, - content_old(){ - 'step 0' - trigger.source.chooseBool(get.prompt('dddxiaoxing',player),'废除武器栏,令其失去〖枭行〗').set('ai',()=>{ - if(_status.event.maybe) return Math.random()<0.5; - return false; - }).set('maybe',player.countCards('hs',{name:['tao','jiu']})&&player.countCards('h')>=3); - 'step 1' - if(result.bool){ - trigger.source.logSkill('dddxiaoxing',player); + content_old() { + "step 0"; + trigger.source + .chooseBool(get.prompt("dddxiaoxing", player), "废除武器栏,令其失去〖枭行〗") + .set("ai", () => { + if (_status.event.maybe) return Math.random() < 0.5; + return false; + }) + .set( + "maybe", + player.countCards("hs", { + name: ["tao", "jiu"], + }) && player.countCards("h") >= 3 + ); + "step 1"; + if (result.bool) { + trigger.source.logSkill("dddxiaoxing", player); trigger.source.disableEquip(1); - player.removeSkills('dddxiaoxing'); + player.removeSkills("dddxiaoxing"); } - } - } - } + }, + }, + }, }, - dddlangzhi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - logTarget(event,player){ - return game.filterPlayer(current=>player.inRange(current)&¤t.countCards('he')); + dddlangzhi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + logTarget(event, player) { + return game.filterPlayer( + (current) => player.inRange(current) && current.countCards("he") + ); }, - prompt:'是否发动【狼志】?', - prompt2(event,player){ - return `展示${get.translation(game.filterPlayer(current=>player.inRange(current)&¤t.countCards('he')))}的各一张牌,然后选择一项:1.用任意张牌替换其中等量张牌;2.获得所有展示牌,失去〖狼志〗。` + prompt: "是否发动【狼志】?", + prompt2(event, player) { + return `展示${get.translation( + game.filterPlayer((current) => player.inRange(current) && current.countCards("he")) + )}的各一张牌,然后选择一项:1.用任意张牌替换其中等量张牌;2.获得所有展示牌,失去〖狼志〗。`; }, - content(){ - 'step 0' - event.targets=game.filterPlayer(current=>player.inRange(current)&¤t.countCards('he')); - event.cards=[]; - event.num=0; - 'step 1' - var target=targets[num]; + content() { + "step 0"; + event.targets = game.filterPlayer( + (current) => player.inRange(current) && current.countCards("he") + ); + event.cards = []; + event.num = 0; + "step 1"; + var target = targets[num]; event.num++; - event.target=target; - player.choosePlayerCard('狼志:展示'+get.translation(target)+'一张牌','he',target,true); - 'step 2' - if(result.bool){ - var card=result.links[0]; - player.showCards(card,get.translation(target)+'被展示'); + event.target = target; + player.choosePlayerCard( + "狼志:展示" + get.translation(target) + "一张牌", + "he", + target, + true + ); + "step 2"; + if (result.bool) { + var card = result.links[0]; + player.showCards(card, get.translation(target) + "被展示"); event.cards.push(card); } - 'step 3' - if(num或点击“取消”,获得所有展示牌,然后失去〖狼志〗',cards); - event.dialog.videoId=event.videoId; + "step 3"; + if (num < targets.length) event.goto(1); + else { + event.videoId = lib.status.videoId++; + if (event.isMine()) { + event.dialog = ui.create.dialog( + '###是否替换其中的任意张牌?###
              或点击“取消”,获得所有展示牌,然后失去〖狼志〗
              ', + cards + ); + event.dialog.videoId = event.videoId; + } else if (player.isOnline2()) { + player.send( + function (cards, id) { + var dialog = ui.create.dialog( + '###是否替换其中的任意张牌?###
              或点击“取消”,获得所有展示牌,然后失去〖狼志〗
              ', + cards + ); + dialog.videoId = id; + }, + cards, + event.videoId + ); } - else if(player.isOnline2()){ - player.send(function(cards,id){ - var dialog=ui.create.dialog('###是否替换其中的任意张牌?###
              或点击“取消”,获得所有展示牌,然后失去〖狼志〗
              ',cards); - dialog.videoId=id; - },cards,event.videoId); - } - player.chooseCard([1,cards.length],'he').set('ai',card=>{ - if(ui.selected.cards.length>=_status.event.num) return 0; - return 100-get.value(card); - }).set('num',function(){ - if(cards.lengthp+get.value(c),0); - if(valget.value(card,player)),list2=cards.map((card,i)=>get.value(card,targets[i])*get.sgnAttitude(player,targets[i])); - list1.sort((a,b)=>a[1]-b[1]); - list2.sort((a,b)=>b[1]-a[1]); - list2=list2.filter(i=>i>0); - var count=0; - for(var i of list2){ - for(var j=0;jlist1[j]){ - count++; - list1.splice(j,1); - break; + player + .chooseCard([1, cards.length], "he") + .set("ai", (card) => { + if (ui.selected.cards.length >= _status.event.num) return 0; + return 100 - get.value(card); + }) + .set( + "num", + (function () { + if (cards.length < Math.floor(game.countPlayer() / 2 - 0.5)) return 0; + var val = cards.reduce((p, c) => p + get.value(c), 0); + if (val < cards.length * 6) return 0; + var list1 = player.getCards("he").map((card) => get.value(card, player)), + list2 = cards.map( + (card, i) => + get.value(card, targets[i]) * + get.sgnAttitude(player, targets[i]) + ); + list1.sort((a, b) => a[1] - b[1]); + list2.sort((a, b) => b[1] - a[1]); + list2 = list2.filter((i) => i > 0); + var count = 0; + for (var i of list2) { + for (var j = 0; j < list1.length; j++) { + if (i > list1[j]) { + count++; + list1.splice(j, 1); + break; + } + } } - } - } - return count; - }()).set('prompt',false); + return count; + })() + ) + .set("prompt", false); } - 'step 4' - if(result.bool){ - var cards2=result.cards; - event.cards2=cards2; - var func=function(id){ - var dialog=get.idDialog(id); - if(dialog) dialog.content.childNodes[1].innerHTML='
              选择要交换的牌(按选择的顺序一一交换)
              '; + "step 4"; + if (result.bool) { + var cards2 = result.cards; + event.cards2 = cards2; + var func = function (id) { + var dialog = get.idDialog(id); + if (dialog) + dialog.content.childNodes[1].innerHTML = + '
              选择要交换的牌(按选择的顺序一一交换)
              '; }; - if(event.isMine()) func(event.videoId); - else if(player.isOnline2()) player.send(func,event.videoId); - player.chooseButton(cards2.length,true).set('dialog',event.videoId).set('ai',button=>{ - return get.value(button.link); - }); + if (event.isMine()) func(event.videoId); + else if (player.isOnline2()) player.send(func, event.videoId); + player + .chooseButton(cards2.length, true) + .set("dialog", event.videoId) + .set("ai", (button) => { + return get.value(button.link); + }); event.goto(6); - } - else{ - for(var i=0;i{ - return !player.hasSkill(skill,null,false,false); + filter(event, player) { + if (!event.source || !event.source.isIn() || event.source.group != "qun") return false; + if (!event.source.countCards("he") < 2) return false; + if (!player.hasZhuSkill("dddfuyi", event.source)) return false; + const skills = player.getStockSkills(true, true).filter((skill) => { + return !player.hasSkill(skill, null, false, false); }); - return skills.length>0; + return skills.length > 0; }, - filter_old(event,player){ - var evt=event.getParent(); - if(evt.name!='die'||evt.source!=event.player||event.player==player) return false; - if(!player.hasZhuSkill('dddfuyi',event.player)) return false; - var skills=player.getSkills('dddxiaoxing',null,false,false); - return !skills.includes('dddxiaoxing')||!skills.includes('dddlangzhi'); + filter_old(event, player) { + var evt = event.getParent(); + if (evt.name != "die" || evt.source != event.player || event.player == player) + return false; + if (!player.hasZhuSkill("dddfuyi", event.player)) return false; + var skills = player.getSkills("dddxiaoxing", null, false, false); + return !skills.includes("dddxiaoxing") || !skills.includes("dddlangzhi"); }, - direct:true, - global:'dddfuyi_sha', - content(){ - 'step 0' - trigger.source.chooseCard('是否响应'+get.translation(player)+'的【附义】?','弃置两张牌,令其获得其武将牌上的一个技能','he',2,lib.filter.cardDiscardable).set('ai',()=>{ - if(get.attitude(_status.event.player,_status.event.getParent().player)<=2) return 0; - return 6-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('dddfuyi',trigger.source); - trigger.source.discard(result.cards).discarder=trigger.source; - var skills=player.getStockSkills(true,true).filter(skill=>{ - return !player.hasSkill(skill,null,false,false); + direct: true, + global: "dddfuyi_sha", + content() { + "step 0"; + trigger.source + .chooseCard( + "是否响应" + get.translation(player) + "的【附义】?", + "弃置两张牌,令其获得其武将牌上的一个技能", + "he", + 2, + lib.filter.cardDiscardable + ) + .set("ai", () => { + if (get.attitude(_status.event.player, _status.event.getParent().player) <= 2) + return 0; + return 6 - get.value(card); }); - if(skills.length==1) event._result={control:skills[0]}; - else trigger.source.chooseControl(skills).set('choiceList',skills.map(skill=>{ - return '
              【'+get.translation(lib.translate[skill+'_ab']||get.translation(skill).slice(0,2))+'】
              '+get.skillInfoTranslation(skill,player)+'
              '; - })).set('displayIndex',false).set('prompt',`附义:选择令${get.translation(player)}获得一个技能`).set('ai',()=>{ - var controls=get.event('controls'); - if(controls.includes('dddxiaoxing')) return 'dddxiaoxing'; - return controls.sort((a,b)=>{ - return get.skillrank(b,'inout')-get.skillrank(a,'inout'); - })[0]; + "step 1"; + if (result.bool) { + player.logSkill("dddfuyi", trigger.source); + trigger.source.discard(result.cards).discarder = trigger.source; + var skills = player.getStockSkills(true, true).filter((skill) => { + return !player.hasSkill(skill, null, false, false); }); - } - else event.finish(); - 'step 2' - var skill=result.control; + if (skills.length == 1) event._result = { control: skills[0] }; + else + trigger.source + .chooseControl(skills) + .set( + "choiceList", + skills.map((skill) => { + return ( + '
              【' + + get.translation( + lib.translate[skill + "_ab"] || + get.translation(skill).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(skill, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", `附义:选择令${get.translation(player)}获得一个技能`) + .set("ai", () => { + var controls = get.event("controls"); + if (controls.includes("dddxiaoxing")) return "dddxiaoxing"; + return controls.sort((a, b) => { + return get.skillrank(b, "inout") - get.skillrank(a, "inout"); + })[0]; + }); + } else event.finish(); + "step 2"; + var skill = result.control; player.addSkills(skill); }, - content_old(){ - 'step 0' - var str='取消此次奖惩,令其获得'; - var skills=player.getSkills('dddxiaoxing',null,false,false); - var bool1=!skills.includes('dddxiaoxing'),bool2=!skills.includes('dddlangzhi'); - var choices=[]; - if(bool1) { - str+='〖枭行〗'; - choices.push('dddxiaoxing'); + content_old() { + "step 0"; + var str = "取消此次奖惩,令其获得"; + var skills = player.getSkills("dddxiaoxing", null, false, false); + var bool1 = !skills.includes("dddxiaoxing"), + bool2 = !skills.includes("dddlangzhi"); + var choices = []; + if (bool1) { + str += "〖枭行〗"; + choices.push("dddxiaoxing"); } - if(bool1&&bool2) str+='/'; - if(bool2){ - str+='〖狼志〗'; - choices.push('dddlangzhi'); + if (bool1 && bool2) str += "/"; + if (bool2) { + str += "〖狼志〗"; + choices.push("dddlangzhi"); } - if(bool1&&bool2){ - str+='中的一或两个'; - choices.push('dddfuyi_both') + if (bool1 && bool2) { + str += "中的一或两个"; + choices.push("dddfuyi_both"); } - choices.push('cancel2'); - trigger.player.chooseControl(choices).set('prompt','是否对'+get.translation(player)+'发动【附义】?').set('prompt2',str).set('ai',()=>{ - if(get.attitude(_status.event.player,_status.event.getParent().player)<=2) return 'cancel2'; - if(_status.event.choices.includes('dddfuyi_both')) return 'dddfuyi_both'; - if(_status.event.choices.includes('dddlangzhi')) return 'dddlangzhi'; - return Math.random()<0.5?'dddxiaoxing':'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - trigger.player.logSkill('dddfuyi',player); + choices.push("cancel2"); + trigger.player + .chooseControl(choices) + .set("prompt", "是否对" + get.translation(player) + "发动【附义】?") + .set("prompt2", str) + .set("ai", () => { + if (get.attitude(_status.event.player, _status.event.getParent().player) <= 2) + return "cancel2"; + if (_status.event.choices.includes("dddfuyi_both")) return "dddfuyi_both"; + if (_status.event.choices.includes("dddlangzhi")) return "dddlangzhi"; + return Math.random() < 0.5 ? "dddxiaoxing" : "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + trigger.player.logSkill("dddfuyi", player); trigger.cancel(); - var skills=[result.control]; - if(result.control=='dddfuyi_both'){ - skills=['dddxiaoxing','dddlangzhi']; + var skills = [result.control]; + if (result.control == "dddfuyi_both") { + skills = ["dddxiaoxing", "dddlangzhi"]; player.draw(3); - } - else event.finish(); + } else event.finish(); player.addSkills(skills); - } - else event.finish(); - 'step 2' - player.removeSkills('dddfuyi'); + } else event.finish(); + "step 2"; + player.removeSkills("dddfuyi"); }, - subSkill:{ - sha:{ - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha'){ - if(player.group!='qun') return; - return num+game.countPlayer(current=>{ - return current.hasZhuSkill('dddfuyi',player); - }); + subSkill: { + sha: { + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") { + if (player.group != "qun") return; + return ( + num + + game.countPlayer((current) => { + return current.hasZhuSkill("dddfuyi", player); + }) + ); } }, }, @@ -4625,807 +5865,1018 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //曹爽 - dddzhuanshe:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - filter(event,player){ - return player.countCards('h')>0&&event.player!=player; + dddzhuanshe: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + filter(event, player) { + return player.countCards("h") > 0 && event.player != player; }, - direct:true, - content(){ - 'step 0' - player.chooseCard(get.prompt2('dddzhuanshe',trigger.player)).set('ai',card=>{ - var target=_status.event.getTrigger().player; - if(!_status.event.goon){ - if(get.value(card)<4) return -target.getUseValue(card)+0.001; - return 0; - } - return target.getUseValue(card); - }).set('goon',get.attitude(player,trigger.player)); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - player.logSkill('dddzhuanshe',trigger.player); - player.give(card,trigger.player,true); - player.addTempSkill('dddzhuanshe_effect'); - player.markAuto('dddzhuanshe_effect',[card.name]); + direct: true, + content() { + "step 0"; + player + .chooseCard(get.prompt2("dddzhuanshe", trigger.player)) + .set("ai", (card) => { + var target = _status.event.getTrigger().player; + if (!_status.event.goon) { + if (get.value(card) < 4) return -target.getUseValue(card) + 0.001; + return 0; + } + return target.getUseValue(card); + }) + .set("goon", get.attitude(player, trigger.player)); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + player.logSkill("dddzhuanshe", trigger.player); + player.give(card, trigger.player, true); + player.addTempSkill("dddzhuanshe_effect"); + player.markAuto("dddzhuanshe_effect", [card.name]); } }, - subSkill:{ - effect:{ - audio:'dddzhuanshe', - trigger:{global:'useCard2'}, - filter(event,player){ - if(!player.getStorage('dddzhuanshe_effect').includes(event.card.name)) return false; - if(event.player!=_status.currentPhase) return false; - var type=get.type(event.card,null,false); - if(type!='basic'&&type!='trick') return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,event.player,current); - })){ + subSkill: { + effect: { + audio: "dddzhuanshe", + trigger: { global: "useCard2" }, + filter(event, player) { + if (!player.getStorage("dddzhuanshe_effect").includes(event.card.name)) + return false; + if (event.player != _status.currentPhase) return false; + var type = get.type(event.card, null, false); + if (type != "basic" && type != "trick") return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, event.player, current) + ); + }) + ) { return true; } } return false; }, - direct:true, - group:'dddzhuanshe_damage', - charlotte:true, - onremove:true, - content(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('dddzhuanshe_effect'),function(card,player,target){ - var player=_status.event.source; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.source; - return get.effect(target,trigger.card,player,_status.event.player); - }).set('targets',trigger.targets).set('card',trigger.card).set('source',trigger.player); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + direct: true, + group: "dddzhuanshe_damage", + charlotte: true, + onremove: true, + content() { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget( + get.prompt("dddzhuanshe_effect"), + function (card, player, target) { + var player = _status.event.source; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + } + ) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.source; + return get.effect(target, trigger.card, player, _status.event.player); + }) + .set("targets", trigger.targets) + .set("card", trigger.card) + .set("source", trigger.player); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill(event.name,event.targets); + "step 2"; + if (event.targets) { + player.logSkill(event.name, event.targets); trigger.targets.addArray(event.targets); - game.log(event.targets,'也成为了',trigger.card,'的目标'); + game.log(event.targets, "也成为了", trigger.card, "的目标"); + } + }, + }, + damage: { + audio: "dddzhuanshe", + trigger: { global: "phaseEnd" }, + filter(event, player) { + var list = player.getStorage("dddzhuanshe_effect").slice(); + event.player.getHistory("useCard", (evt) => { + list.remove(evt.card.name); + }); + return list.length; + }, + charlotte: true, + logTarget: "player", + prompt2: "对其造成1点伤害", + check(event, player) { + return get.damageEffect(event.player, player, player) >= 0; + }, + content() { + trigger.player.damage(player); + }, + }, + }, + }, + dddweiqiu: { + audio: 2, + trigger: { global: "recoverBefore" }, + filter(event, player) { + return !player.countCards("h"); + }, + forced: true, + direct: true, + content() { + trigger.player.logSkill("dddweiqiu", player); + trigger.cancel(); + player.draw(); + }, + }, + //薛灵芸 + dddlianer: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + return event.cards.filterInD("od").length > 0 && get.color(event.card) == "red"; + }, + content() { + "step 0"; + var cards = trigger.cards.filterInD("od"); + event.cards = cards; + player.gain(cards, "gain2"); + "step 1"; + var number = get.number(cards[0]); + if (cards.length == 1 && typeof number == "number") { + player.addTempSkill("dddlianer_ceiling"); + player.storage["dddlianer_ceiling"] = number; + } + }, + mod: { + aiOrder(player, card, num) { + if (get.itemtype(card) == "card" && get.color(card) == "red") { + if (!player.storage["dddlianer_ceiling"]) return; + var numx = get.number(card); + if (typeof numx == "number") { + return num + 10 / Math.max(1, player.storage["dddlianer_ceiling"] - numx); } } }, - damage:{ - audio:'dddzhuanshe', - trigger:{global:'phaseEnd'}, - filter(event,player){ - var list=player.getStorage('dddzhuanshe_effect').slice(); - event.player.getHistory('useCard',evt=>{ - list.remove(evt.card.name); - }) - return list.length; - }, - charlotte:true, - logTarget:'player', - prompt2:'对其造成1点伤害', - check(event,player){ - return get.damageEffect(event.player,player,player)>=0; - }, - content(){ - trigger.player.damage(player); - } - } - } - }, - dddweiqiu:{ - audio:2, - trigger:{global:'recoverBefore'}, - filter(event,player){ - return !player.countCards('h'); }, - forced:true, - direct:true, - content(){ - trigger.player.logSkill('dddweiqiu',player); - trigger.cancel(); - player.draw(); - } - }, - //薛灵芸 - dddlianer:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - return event.cards.filterInD('od').length>0&&get.color(event.card)=='red'; - }, - content(){ - 'step 0' - var cards=trigger.cards.filterInD('od'); - event.cards=cards; - player.gain(cards,'gain2'); - 'step 1' - var number=get.number(cards[0]); - if(cards.length==1&&typeof number=='number'){ - player.addTempSkill('dddlianer_ceiling'); - player.storage['dddlianer_ceiling']=number; - } - }, - mod:{ - aiOrder(player,card,num){ - if(get.itemtype(card)=='card'&&get.color(card)=='red'){ - if(!player.storage['dddlianer_ceiling']) return; - var numx=get.number(card); - if(typeof numx=='number'){ - return num+10/Math.max(1,player.storage['dddlianer_ceiling']-numx); - } - } - } - }, - subSkill:{ - ceiling:{ - onremove:true, - charlotte:true, - mod:{ - cardEnabled(card,player){ - if(!player.storage['dddlianer_ceiling']) return; - var num=get.number(card); - if(num!='unsure'&&(typeof num!='number'||player.storage['dddlianer_ceiling']<=num)) return false; + subSkill: { + ceiling: { + onremove: true, + charlotte: true, + mod: { + cardEnabled(card, player) { + if (!player.storage["dddlianer_ceiling"]) return; + var num = get.number(card); + if ( + num != "unsure" && + (typeof num != "number" || player.storage["dddlianer_ceiling"] <= num) + ) + return false; }, - cardRespondable(card,player){ - if(!player.storage['dddlianer_ceiling']) return; - var num=get.number(card); - if(num!='unsure'&&(typeof num!='number'||player.storage['dddlianer_ceiling']<=num)) return false; + cardRespondable(card, player) { + if (!player.storage["dddlianer_ceiling"]) return; + var num = get.number(card); + if ( + num != "unsure" && + (typeof num != "number" || player.storage["dddlianer_ceiling"] <= num) + ) + return false; }, - cardSavable(card,player){ - if(!player.storage['dddlianer_ceiling']) return; - var num=get.number(card); - if(num!='unsure'&&(typeof num!='number'||player.storage['dddlianer_ceiling']<=num)) return false; + cardSavable(card, player) { + if (!player.storage["dddlianer_ceiling"]) return; + var num = get.number(card); + if ( + num != "unsure" && + (typeof num != "number" || player.storage["dddlianer_ceiling"] <= num) + ) + return false; }, - } - } - } - }, - dddanzhi:{ - audio:2, - trigger:{global:'phaseBegin'}, - filter(event,player){ - var evts=game.getAllGlobalHistory('everything',evt=>['useCard','respond'].includes(evt.name)); - if(!evts.length) return false; - const color=get.color(evts.lastItem.card,false); - return color=='black' - }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('dddanzhi'),'选择一名角色,此回合其第一次成为黑色牌的目标时,此牌对其无效').set('ai',target=>{ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dddanzhi',target); - target.addTempSkill('dddanzhi_effect'); - } - }, - subSkill:{ - effect:{ - trigger:{target:'useCardToTarget'}, - filter(event,player){ - return get.color(event.card)=='black'; }, - forced:true, - charlotte:true, - content(){ + }, + }, + }, + dddanzhi: { + audio: 2, + trigger: { global: "phaseBegin" }, + filter(event, player) { + var evts = game.getAllGlobalHistory("everything", (evt) => + ["useCard", "respond"].includes(evt.name) + ); + if (!evts.length) return false; + const color = get.color(evts.lastItem.card, false); + return color == "black"; + }, + direct: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("dddanzhi"), + "选择一名角色,此回合其第一次成为黑色牌的目标时,此牌对其无效" + ) + .set("ai", (target) => { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dddanzhi", target); + target.addTempSkill("dddanzhi_effect"); + } + }, + subSkill: { + effect: { + trigger: { target: "useCardToTarget" }, + filter(event, player) { + return get.color(event.card) == "black"; + }, + forced: true, + charlotte: true, + content() { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); - game.log(trigger.card,'对',player,'无效了'); + game.log(trigger.card, "对", player, "无效了"); game.delayx(); - player.removeSkill('dddanzhi_effect'); - } - } - } + player.removeSkill("dddanzhi_effect"); + }, + }, + }, }, //刘宏 - dddshixing:{ - audio:2, - trigger:{ - global:['changeHp','useCard1','phaseBefore'], + dddshixing: { + audio: 2, + trigger: { + global: ["changeHp", "useCard1", "phaseBefore"], }, - forced:true, - onremove:true, - filter(event,player){ - var num=player.countMark('dddshixing'); - if(event.name=='changeHp'){ - if(event.player.hasSex('female')){ - var bool=!event.player.isDamaged(); - if(bool&&((num&1)==0)||!bool&&((num&1)==1)){ + forced: true, + onremove: true, + filter(event, player) { + var num = player.countMark("dddshixing"); + if (event.name == "changeHp") { + if (event.player.hasSex("female")) { + var bool = !event.player.isDamaged(); + if ((bool && (num & 1) == 0) || (!bool && (num & 1) == 1)) { return true; } } return false; } - if(event.name=='useCard'){ - var bool=game.getGlobalHistory('useCard',evt=>get.type2(evt.card)=='trick').length==0; - if((bool&&(num&2)==0)||!bool&&((num&2)==2)){ + if (event.name == "useCard") { + var bool = + game.getGlobalHistory("useCard", (evt) => get.type2(evt.card) == "trick") + .length == 0; + if ((bool && (num & 2) == 0) || (!bool && (num & 2) == 2)) { return true; } return false; } return true; }, - content(){ - lib.skill['dddshixing'].applyChange(player); + content() { + lib.skill["dddshixing"].applyChange(player); }, - applyChange(player){ - player.removeAdditionalSkill('dddshixing'); - var bool1=game.hasPlayer(current=>!current.isDamaged()&¤t.hasSex('female')), - bool2=game.getGlobalHistory('useCard',evt=>get.type2(evt.card)=='trick').length==0; - player.storage['dddshixing']=bool1+2*bool2; - var list=[]; - if(bool1) list.push('xiangle'); - if(bool2) list.push('jiushi'); - if(!bool1&&!bool2) list.push('rezhiheng'); - player.addAdditionalSkill('dddshixing',list); + applyChange(player) { + player.removeAdditionalSkill("dddshixing"); + var bool1 = game.hasPlayer((current) => !current.isDamaged() && current.hasSex("female")), + bool2 = + game.getGlobalHistory("useCard", (evt) => get.type2(evt.card) == "trick") + .length == 0; + player.storage["dddshixing"] = bool1 + 2 * bool2; + var list = []; + if (bool1) list.push("xiangle"); + if (bool2) list.push("jiushi"); + if (!bool1 && !bool2) list.push("rezhiheng"); + player.addAdditionalSkill("dddshixing", list); }, - derivation:['xiangle','jiushi','rezhiheng'], + derivation: ["xiangle", "jiushi", "rezhiheng"], }, - ddddanggu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return game.countPlayer(current=>current.isLinked())current.group=='qun'); + ddddanggu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return ( + game.countPlayer((current) => current.isLinked()) < + game.countPlayer((current) => current.group == "qun") + ); }, - forced:true, - group:'ddddanggu_negative', - content(){ - 'step 0' - if(!event.loop) event.loop=0; - var num=game.countPlayer(current=>current.group=='qun')-game.countPlayer(current=>current.isLinked()); - player.chooseTarget('党锢:横置至少'+get.cnNumber(num)+'名角色',[num,Infinity],true,(card,player,target)=>{ - return !target.isLinked(); - }).set('ai',target=>{ - return get.effect(target,{name:'tiesuo'},_status.event.player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('ddddanggu',targets); - targets.forEach(i=>i.link()); + forced: true, + group: "ddddanggu_negative", + content() { + "step 0"; + if (!event.loop) event.loop = 0; + var num = + game.countPlayer((current) => current.group == "qun") - + game.countPlayer((current) => current.isLinked()); + player + .chooseTarget( + "党锢:横置至少" + get.cnNumber(num) + "名角色", + [num, Infinity], + true, + (card, player, target) => { + return !target.isLinked(); + } + ) + .set("ai", (target) => { + return get.effect(target, { name: "tiesuo" }, _status.event.player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("ddddanggu", targets); + targets.forEach((i) => i.link()); } }, - discard(){ - "step 0" - game.log(player,'进入了弃牌阶段'); - event.num=Math.max(0,player.countCards('he',card=>!player.canIgnoreHandcard(card))-player.getHandcardLimit()); - if(event.num<=0) event.finish(); - else{ - if(lib.config.show_phase_prompt){ - player.popup('弃牌阶段'); + discard() { + "step 0"; + game.log(player, "进入了弃牌阶段"); + event.num = Math.max( + 0, + player.countCards("he", (card) => !player.canIgnoreHandcard(card)) - + player.getHandcardLimit() + ); + if (event.num <= 0) event.finish(); + else { + if (lib.config.show_phase_prompt) { + player.popup("弃牌阶段"); } } - event.trigger('phaseDiscard'); - "step 1" - player.chooseToDiscard(num,true,'he'); - "step 2" - event.cards=result.cards; + event.trigger("phaseDiscard"); + "step 1"; + player.chooseToDiscard(num, true, "he"); + "step 2"; + event.cards = result.cards; }, - subSkill:{ - negative:{ - trigger:{global:'phaseDiscardBegin'}, - filter(event,player){ - return event.player!=player&&event.player.isLinked(); + subSkill: { + negative: { + trigger: { global: "phaseDiscardBegin" }, + filter(event, player) { + return event.player != player && event.player.isLinked(); }, - forced:true, - logTarget:'player', - content(){ - trigger.setContent(lib.skill['ddddanggu'].discard); + forced: true, + logTarget: "player", + content() { + trigger.setContent(lib.skill["ddddanggu"].discard); }, - } - } + }, + }, }, - dddfuzong:{ - audio:2, - zhuSkill:true, - forced:true, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dddfuzong: { + audio: 2, + zhuSkill: true, + forced: true, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - if(!player.hasZhuSkill('dddfuzong')) return false; - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter(event, player) { + if (!player.hasZhuSkill("dddfuzong")) return false; + return event.name != "phase" || game.phaseNumber == 0; }, - group:'dddfuzong_discard', - content(){ - player.draw(game.countPlayer(current=>{ - return current.group=='qun'; - })); + group: "dddfuzong_discard", + content() { + player.draw( + game.countPlayer((current) => { + return current.group == "qun"; + }) + ); }, - subSkill:{ - discard:{ - trigger:{global:'die'}, - filter(event,player){ - if(!player.hasZhuSkill('dddfuzong')) return false; - return event.player.group=='qun'; + subSkill: { + discard: { + trigger: { global: "die" }, + filter(event, player) { + if (!player.hasZhuSkill("dddfuzong")) return false; + return event.player.group == "qun"; }, - zhuSkill:true, - forced:true, - logTarget:'player', - content(){ - trigger.player.discardPlayerCard(player,'he',true).set('forceDie',true); + zhuSkill: true, + forced: true, + logTarget: "player", + content() { + trigger.player.discardPlayerCard(player, "he", true).set("forceDie", true); }, - } - } + }, + }, }, //夏侯玄 - dddlanghuai:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - zhuanhuanji:true, - direct:true, - content(){ - 'step 0' - if(player.hasMark('dddxuanlun_del')) event._result={bool:true}; - else player.chooseBool(get.prompt('dddlanghuai'),'展示手牌(无牌则不展示),并改为摸其中'+(!player.storage['dddlanghuai']?'包含':'缺少')+'花色数的牌').set('ai',()=>_status.event.bool).set('bool',function(){ - var list=[],cards=player.getCards('h'); - for(var i of cards){ - var suit=get.suit(i,player); - if(!lib.suit.includes(suit)) continue; - list.add(suit); - } - if(player.storage['dddlanghuai']){ - list=list.removeArray(lib.suit); - } - return list.length==2&&!player.storage['dddlanghuai']||list.length>2; - }()); - 'step 1' - if(result.bool){ - player.logSkill('dddlanghuai'); - delete player.storage['dddxuanlun_del']; - if(player.countCards('h')) player.showHandcards(); - } - else event.finish(); - 'step 2' - var list=[],cards=player.getCards('h'); - for(var i of cards){ - var suit=get.suit(i,player); - if(!lib.suit.includes(suit)) continue; + dddlanghuai: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + zhuanhuanji: true, + direct: true, + content() { + "step 0"; + if (player.hasMark("dddxuanlun_del")) event._result = { bool: true }; + else + player + .chooseBool( + get.prompt("dddlanghuai"), + "展示手牌(无牌则不展示),并改为摸其中" + + (!player.storage["dddlanghuai"] ? "包含" : "缺少") + + "花色数的牌" + ) + .set("ai", () => _status.event.bool) + .set( + "bool", + (function () { + var list = [], + cards = player.getCards("h"); + for (var i of cards) { + var suit = get.suit(i, player); + if (!lib.suit.includes(suit)) continue; + list.add(suit); + } + if (player.storage["dddlanghuai"]) { + list = list.removeArray(lib.suit); + } + return ( + (list.length == 2 && !player.storage["dddlanghuai"]) || + list.length > 2 + ); + })() + ); + "step 1"; + if (result.bool) { + player.logSkill("dddlanghuai"); + delete player.storage["dddxuanlun_del"]; + if (player.countCards("h")) player.showHandcards(); + } else event.finish(); + "step 2"; + var list = [], + cards = player.getCards("h"); + for (var i of cards) { + var suit = get.suit(i, player); + if (!lib.suit.includes(suit)) continue; list.add(suit); } - if(player.storage['dddlanghuai']){ - list=lib.suit.slice().removeArray(list); + if (player.storage["dddlanghuai"]) { + list = lib.suit.slice().removeArray(list); } - player.changeZhuanhuanji('dddlanghuai'); + player.changeZhuanhuanji("dddlanghuai"); trigger.changeToZero(); - if(list.length) player.draw(list.length); + if (list.length) player.draw(list.length); }, - mark:true, - intro:{ - content(storage,player){ - return '摸牌阶段,你可展示手牌(无牌则不展示),并改为摸其中'+(!storage?'包含':'缺少')+'花色数的牌。'; + mark: true, + intro: { + content(storage, player) { + return ( + "摸牌阶段,你可展示手牌(无牌则不展示),并改为摸其中" + + (!storage ? "包含" : "缺少") + + "花色数的牌。" + ); }, }, - marktext:'☯', + marktext: "☯", }, - dddxuanlun:{ - audio:2, - trigger:{player:'damageEnd'}, - content(){ + dddxuanlun: { + audio: 2, + trigger: { player: "damageEnd" }, + content() { player.draw(4); - player.addTempSkill('dddxuanlun_choose'); + player.addTempSkill("dddxuanlun_choose"); }, - ai:{ - maixie:true, - maixie_hp:true, - result:{ - effect (card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + result: { + effect(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(target.hp>=4) return [1,num*2.5]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2.5]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } }, }, - threaten:0.6, + threaten: 0.6, }, - subSkill:{ - choose:{ - trigger:{global:'phaseEnd'}, - forced:true, - charlotte:true, - filter(event,player){ - if(player.hasMark('dddxuanlun_del')&&!player.countCards('h')) return false; + subSkill: { + choose: { + trigger: { global: "phaseEnd" }, + forced: true, + charlotte: true, + filter(event, player) { + if (player.hasMark("dddxuanlun_del") && !player.countCards("h")) return false; return true; }, - content(){ - 'step 0' - var choices=[]; - var choiceList=['将四张牌以任意顺序置于牌堆顶或底','删去此项和〖朗怀〗中的“可”,直到你发动〖朗怀〗']; - if(player.countCards('he')>=4||player.hasMark('dddxuanlun_del')) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(!player.hasMark('dddxuanlun_del')) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(choices.length==1&&choices[0]=='选项一') event._result={control:'选项一'}; - else player.chooseControl(choices).set('choiceList',choiceList).set('ai',()=>{ - if(!_status.event.controls.includes('选项一')) return 1; - if(!_status.event.controls.includes('选项二')) return 0; - var player=_status.event.player; - var num=0; - for(var card of player.getCards('he')){ - if(get.value(card,player)<=5) num++; - if(num>=4) break; - } - return num>=4?0:1; - }); - 'step 1' - game.log(player,'选择了','#y'+result.control); - if(result.control=='选项一'){ - var cards=player.getCards('he'); - if(cards.length<=4) event._result={bool:true,cards:cards}; - else player.chooseCard('玄论:将四张牌置于牌堆顶或牌堆底','he',true,4); - } - else{ - player.addMark('dddxuanlun_del',1,false); + content() { + "step 0"; + var choices = []; + var choiceList = [ + "将四张牌以任意顺序置于牌堆顶或底", + "删去此项和〖朗怀〗中的“可”,直到你发动〖朗怀〗", + ]; + if (player.countCards("he") >= 4 || player.hasMark("dddxuanlun_del")) + choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (!player.hasMark("dddxuanlun_del")) choices.push("选项二"); + else + choiceList[1] = + '' + + choiceList[1] + + ""; + if (choices.length == 1 && choices[0] == "选项一") + event._result = { control: "选项一" }; + else + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("ai", () => { + if (!_status.event.controls.includes("选项一")) return 1; + if (!_status.event.controls.includes("选项二")) return 0; + var player = _status.event.player; + var num = 0; + for (var card of player.getCards("he")) { + if (get.value(card, player) <= 5) num++; + if (num >= 4) break; + } + return num >= 4 ? 0 : 1; + }); + "step 1"; + game.log(player, "选择了", "#y" + result.control); + if (result.control == "选项一") { + var cards = player.getCards("he"); + if (cards.length <= 4) + event._result = { + bool: true, + cards: cards, + }; + else player.chooseCard("玄论:将四张牌置于牌堆顶或牌堆底", "he", true, 4); + } else { + player.addMark("dddxuanlun_del", 1, false); event.finish(); } - 'step 2' - if(result.bool){ - var cards=result.cards; - event.cards=cards; - player.chooseToMove().set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]).set('prompt','玄论:将这些牌置于牌堆顶或牌堆底').set('processAI',function(list){ - var cards=list[0][1],player=_status.event.player; - var target=_status.currentPhase.next; - var att=get.sgn(get.attitude(player,target)); - var top=[]; - var judges=target.getCards('j'); - var stopped=false; - if(player!=target||!target.hasWuxie()){ - for(var i=0;i 0) break; top.unshift(cards.shift()); } } - } - var bottom; - if(!stopped){ - cards.sort(function(a,b){ - return (get.value(b,player)-get.value(a,player))*att; - }); - while(cards.length){ - if((get.value(cards[0],player)<=5)==(att>0)) break; - top.unshift(cards.shift()); - } - } - bottom=cards; - return [top,bottom]; - }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var top=result.moved[0]; - var bottom=result.moved[1]; + bottom = cards; + return [top, bottom]; + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); - var cards=top.addArray(bottom); - player.$throw(cards.length,1000); - player.lose(cards,ui.cardPile).set('top',top).insert_index=function(event,card){ - if(event.top.includes(card)) return ui.cardPile.firstChild; + player.popup( + get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下" + ); + var cards = top.addArray(bottom); + player.$throw(cards.length, 1000); + player.lose(cards, ui.cardPile).set("top", top).insert_index = function ( + event, + card + ) { + if (event.top.includes(card)) return ui.cardPile.firstChild; return null; }; } - } - } - } + }, + }, + }, }, //张闿 - dddjiexing:{ - audio:2, - trigger:{ - global:['recoverBegin','useCard'], + dddjiexing: { + audio: 2, + trigger: { + global: ["recoverBegin", "useCard"], }, - filter(event,player){ - if(event.player==player) return false; - if(event.name=='recover') return player.isDamaged(); - return get.type(event.card,false)=='equip'&&event.cards.some(i=>get.position(i,true)=='o'&&player.canEquip(i,true)); + filter(event, player) { + if (event.player == player) return false; + if (event.name == "recover") return player.isDamaged(); + return ( + get.type(event.card, false) == "equip" && + event.cards.some((i) => get.position(i, true) == "o" && player.canEquip(i, true)) + ); }, - limited:true, - skillAnimation:true, - animationColor:'legend', - logTarget:'player', - check(event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(event.name=='recover') return get.recoverEffect(event.player,player,player)= 0) return false; + if (event.name == "recover") + return ( + get.recoverEffect(event.player, player, player) < + get.recoverEffect(player, player, player) + ); + return ( + get.effect(event.targets[0], event.card, player, player) < + get.effect(player, event.card, player, player) + ); }, - content(){ - player.awakenSkill('dddjiexing'); - player.addSkill('dddjiexing_reset'); - if(trigger.name=='recover'){ + content() { + player.awakenSkill("dddjiexing"); + player.addSkill("dddjiexing_reset"); + if (trigger.name == "recover") { trigger.cancel(); player.recover(trigger.num); - } - else{ - trigger.all_excluded=true; - trigger.targets.length=0; - var cards=trigger.cards.filterInD(); - for(var i of cards){ - if(player.canEquip(i,true)) player.equip(i); + } else { + trigger.all_excluded = true; + trigger.targets.length = 0; + var cards = trigger.cards.filterInD(); + for (var i of cards) { + if (player.canEquip(i, true)) player.equip(i); } } }, - subSkill:{ - reset:{ - audio:'dddjiexing', - trigger:{player:['recoverAfter','useCardAfter']}, - filter(event,player){ - if(event.getParent().name=='dddjiexing') return false; - if(event.name=='useCard') return get.type(event.card,false)=='equip'; + subSkill: { + reset: { + audio: "dddjiexing", + trigger: { player: ["recoverAfter", "useCardAfter"] }, + filter(event, player) { + if (event.getParent().name == "dddjiexing") return false; + if (event.name == "useCard") return get.type(event.card, false) == "equip"; return true; }, - forced:true, - charlotte:true, - content(){ - player.restoreSkill('dddjiexing'); - player.removeSkill('dddjiexing_reset'); - } - } - } - }, - dddbailei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return game.hasPlayer(current=>current.isMaxEquip(true)&¤t.countGainableCards(player,'he'))||game.hasPlayer(current=>current.getHp()==1); + forced: true, + charlotte: true, + content() { + player.restoreSkill("dddjiexing"); + player.removeSkill("dddjiexing_reset"); + }, + }, }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('dddbailei'),(card,player,target)=>{ - return target.isMaxEquip(true)&&target.countGainableCards(player,'he')||target.getHp()==1; - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(att>=3) return false; - if(target.hp==1) return 100; - return 1; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dddbailei',target); - if(target.isMaxEquip(true)&&target.hp==1){ - if(target.countGainableCards(player,'he')){ - player.gainPlayerCard('拜泪:获得'+get.translation(target)+'一张牌,或点击“取消”对其造成1点伤害','he',target); - } - else event._result={bool:false}; + }, + dddbailei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return ( + game.hasPlayer( + (current) => current.isMaxEquip(true) && current.countGainableCards(player, "he") + ) || game.hasPlayer((current) => current.getHp() == 1) + ); + }, + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("dddbailei"), (card, player, target) => { + return ( + (target.isMaxEquip(true) && target.countGainableCards(player, "he")) || + target.getHp() == 1 + ); + }) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (att >= 3) return false; + if (target.hp == 1) return 100; + return 1; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dddbailei", target); + if (target.isMaxEquip(true) && target.hp == 1) { + if (target.countGainableCards(player, "he")) { + player.gainPlayerCard( + "拜泪:获得" + + get.translation(target) + + "一张牌,或点击“取消”对其造成1点伤害", + "he", + target + ); + } else event._result = { bool: false }; + } else if (target.isMaxEquip(true)) + player.gainPlayerCard( + "拜泪:获得" + get.translation(target) + "一张牌", + "he", + target, + true + ); + else { + event._result = { bool: false }; } - else if(target.isMaxEquip(true)) player.gainPlayerCard('拜泪:获得'+get.translation(target)+'一张牌','he',target,true); - else{ - event._result={bool:false}; - } - } - else event.finish(); - 'step 2' - if(!result.bool){ + } else event.finish(); + "step 2"; + if (!result.bool) { player.line(target); // player.trySkillAnimate('dddbailei_animate','dddbailei_animate',player.checkShow('dddbailei')); target.damage(); game.delayx(); + } else event.finish(); + "step 3"; + if (target.isIn()) { + event.finish(); + return; } - else event.finish(); - 'step 3' - if(target.isIn()){event.finish(); return}; - player.removeSkills('dddbailei'); + player.removeSkills("dddbailei"); + }, + subSkill: { + animate: { + skillAnimation: true, + animationColor: "fire", + }, }, - subSkill:{ - animate:{ - skillAnimation:true, - animationColor:'fire', - } - } }, }, - dynamicTranslate:{ - dddxiaheng(player){ - return '锁定技。出牌阶段开始时,你选择一名角色,其弃置两张牌,然后你对一名角色造成1点伤害。'+(player.storage['dddxiaheng_del']?'':'。“若两名角色:均不为你,你失去一点体力上限;为同一名角色,你失去一点体力;然后若以此法对包括你在内三名不同的角色造成伤害,删除双引号里的描述内容”'); + dynamicTranslate: { + dddxiaheng(player) { + return ( + "锁定技。出牌阶段开始时,你选择一名角色,其弃置两张牌,然后你对一名角色造成1点伤害。" + + (player.storage["dddxiaheng_del"] + ? "" + : "“若两名角色:均不为你,你失去一点体力上限;为同一名角色,你失去一点体力;然后若以此法对包括你在内三名不同的角色造成伤害,删除双引号里的描述内容”") + ); }, - dddshichao(player){ - return '锁定技,准备阶段,你选择一名手牌数为全场第('+(1+player.countMark('dddshichao'))+')大的角色,将手牌数调整至与其相等且至多等于主公的体力上限;其于你的下回合开始前对你造成伤害时,其可防止之,然后令()内的数字+1。'; + dddshichao(player) { + return ( + "锁定技,准备阶段,你选择一名手牌数为全场第(" + + (1 + player.countMark("dddshichao")) + + ")大的角色,将手牌数调整至与其相等且至多等于主公的体力上限;其于你的下回合开始前对你造成伤害时,其可防止之,然后令()内的数字+1。" + ); }, - dddlanghuai(player){ - return '转换技,摸牌阶段,你'+(player.hasMark('dddxuanlun_del')?'':'可')+'展示手牌(无牌则不展示),并改为摸其中'+(!player.storage['dddlanghuai']?'包含':'缺少')+'花色数的牌。'; + dddlanghuai(player) { + return ( + "转换技,摸牌阶段,你" + + (player.hasMark("dddxuanlun_del") ? "" : "可") + + "展示手牌(无牌则不展示),并改为摸其中:" + + (player.storage["dddlanghuai"] ? '阴:包含花色数的牌;阳:缺少花色数的牌。' : '阴:包含花色数的牌;阳:缺少花色数的牌。') + ); }, - dddxuanlun(player){ - var deleted=player.hasMark('dddxuanlun_del'); - return '你受到伤害后,你可摸四张牌;你发动此技能的回合结束时,'+(deleted?'你':'须选择一项:')+'将四张牌以任意顺序置于牌堆顶或底'+(deleted?'。':';或删去此项和“朗怀”中的“可”,直到你发动“朗怀”。'); + dddxuanlun(player) { + var deleted = player.hasMark("dddxuanlun_del"); + return ( + "你受到伤害后,你可摸四张牌;你发动此技能的回合结束时," + + (deleted ? "你" : "须选择一项:") + + "将四张牌以任意顺序置于牌堆顶或底" + + (deleted ? "。" : ";或删去此项和“朗怀”中的“可”,直到你发动“朗怀”。") + ); }, - ddddiedang(player){ - if(player.storage.ddddiedang) return '出牌阶段限一次,你可以弃置三张牌,然后摸一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“弃置”和“摸”。' - return '出牌阶段限一次,你可以摸三张牌,然后弃置一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“摸”和“弃置”。'; + ddddiedang(player) { + if (player.storage.ddddiedang) + return "出牌阶段限一次,你可以弃置三张牌,然后摸一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“弃置”和“摸”。"; + return "出牌阶段限一次,你可以摸三张牌,然后弃置一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“摸”和“弃置”。"; }, - dddyeshen(player){ - return '一名角色的结束阶段,你可以亮出牌堆底'+get.cnNumber(3-player.countMark('dddyeshen'))+'张牌,令其将其中一张黑色牌当做最大目标数为牌名字数的【铁索连环】使用或重铸,其余牌置于牌堆顶,然后此技能亮出牌数-1;若减至零张或其中没有黑色牌,你复原此技能并对自己造成1点火焰伤害。'; + dddyeshen(player) { + return ( + "一名角色的结束阶段,你可以亮出牌堆底" + + get.cnNumber(3 - player.countMark("dddyeshen")) + + "张牌,令其将其中一张黑色牌当做最大目标数为牌名字数的【铁索连环】使用或重铸,其余牌置于牌堆顶,然后此技能亮出牌数-1;若减至零张或其中没有黑色牌,你复原此技能并对自己造成1点火焰伤害。" + ); }, }, - translate:{ - ddd_handang:"韩当", - dddxianxi:"险袭", - dddxianxi_info:"出牌阶段,你使用【杀】时可无视距离额外指定任意名角色为目标;此【杀】结算后,若额外指定的目标中有未受到此【杀】伤害的,你须选择一项:弃置X张牌对其各造成1点伤害;或摸X张牌并失去1点体力(X为未受到此【杀】伤害的目标数)。", - ddd_wuzhi:"吴质", - dddlingyong:"灵涌", - dddlingyong_info:"一名角色跳过其的阶段时,你可进行判定。若结果不为【杀】,则你可以使用判定牌,然后重复此流程。", - dddxuxiao:"虚孝", - dddxuxiao_info:"当有黑色基本牌因弃置而进入弃牌堆后,你可将其当做【兵粮寸断】置于一名角色的判定区,然后其摸两张牌。", - ddd_xujing:"许靖", - dddxuyu:"虚誉", - dddxuyu_info:"当你使用牌结算结束后,你可以摸一张牌。若如此做,当你于本回合使用下一张牌结算结束后,你弃置一张牌。", - dddshijian:"实荐", - dddshijian_info:"其他角色于其出牌阶段使用的第二张牌结算结束后,你可以交给其一张牌。若如此做,其本回合使用的下一张牌指定第一个目标时,你选择一项:1.令此牌额外结算一次;2.你摸一张牌。", - ddd_caomao:"曹髦", - dddtaisi:"太思", - dddtaisi_info:"一名角色的回合结束时,若你的体力值于本回合内发生过变化,则你可以令一名角色获得一张于本回合内进入弃牌堆的牌。然后若该角色于本回合内对你造成过伤害,则你摸两张牌。", - dddquche:"驱车", - dddquche_info:"限定技。出牌阶段,你可依次执行大括号内的流程至多X次(X为你的体力上限):{[⒈将一张牌交给一名其他角色]+[将一张黑色牌当做【杀】使用(不计入次数限制)]}。你每执行一个中括号内的选项,本回合内至其他角色的距离便-1。", - dddqianlong:"潜龙", - dddqianlong_info:"主公技,锁定技。当你因执行奖惩而摸牌或弃置牌时,取消之;当你杀死一名角色后,你摸三张牌。", - ddd_xinxianying:"辛宪英", - ddddongcha:"洞察", - ddddongcha_info:"其他角色的回合开始时,你可以令你和其依次将一张手牌置于你的武将牌上,称为“鉴”。若如此做,本回合结束时,你与其依次选择获得一张“鉴”。", - dddzhijie:"智解", - dddzhijie_info:"你可以将两张颜色相同的“鉴”当做【闪】使用,或将两张颜色不同的“鉴”当做【无懈可击】使用;然后你摸两张牌。", - ddd_xianglang:'向朗', - dddqiahua:"恰化", - dddqiahua_info:"其他角色的回合开始时,你可明置X张手牌(X为其体力值),然后其于本回合内获得〖恂恂〗。", - dddfusi:"腹笥", - dddfusi_info:"锁定技。①你的明置手牌不计入手牌上限。②其他角色需要使用牌时,可以改为使用你的明置手牌(需经过你的确认)。③你的回合内,若你的手牌均为明置手牌,则其他角色不能使用各自的手牌。", - dddfusi_global:"腹笥", - dddtuoji:"拓籍", - dddtuoji_info:"其他角色因〖腹笥〗而使用你的牌后,若你的手牌均为明置手牌,则你可以摸三张牌。", - visible_dddxianglang:"明", - ddd_yujin:'于禁', - dddzhengjun:'整军', - dddzhengjun_info:'出牌阶段内每项各限一次。当有角色的手牌数/体力值/装备区内牌数变化后,若其的对应数值与你相同,则你可以执行对应的选项。体力值:你令其回复或失去1点体力;手牌数:你令其摸或弃置一张牌;装备区内牌数:你移动其的一张装备牌。', - ddd_liuye:'刘晔', - dddchashi:'察势', - dddchashi_info:'其他角色的出牌阶段开始时,你可弃置一张牌A。当其于本阶段内使用下一张牌结算结束后,若此牌与A花色或类型相同,你与其各摸一张牌。', - dddqice:'齐策', - dddqice_info:'准备阶段开始时,你可以摸两张牌,然后你的〖齐策〗失效直到你使用锦囊牌。', - ddd_baosanniang:'鲍三娘', - dddzhilian:'枝连', - dddzhilian_info:'一名角色的回合结束时,若本回合仅有你与另一名男性角色使用或打出过牌,则你可以令你与其各摸一张牌或各弃置一张牌,然后你获得本回合内进入弃牌堆的所有【杀】。', - dddjijian:'赍剑', - dddjijian_info:'出牌阶段限一次。你可以展示一张【杀】并交给一名其他男性角色,然后其展示至多两张颜色相同的【杀】或普通锦囊牌,你与其依次视为使用一张其展示的牌(不能重复使用同一张展示牌)。', - ddd_zhenji:'甄姬', - dddmiaoxing:'淼形', - dddmiaoxing_info:'锁定技。①分发起始手牌时,你额外获得两份起始手牌,然后将其中的两份移出游戏,称为“水相”。②摸牌阶段结束后,你须将至少一份“水相”调整至与你的手牌数相等。', - dddfushi:'浮世', - dddfushi_info:'每回合限一次。当你使用或打出基本牌结算结束后,你可以用所有手牌交换一份“水相”,然后你可令一名男性角色选择是否用其所有手牌交换一份“水相”。', - ddd_zhaoang:'赵昂', - dddfenji:'奋计', - dddfenji_info:'摸牌/弃牌阶段开始时,你可视为使用一张未以此法使用过的普通锦囊牌,然后将此阶段摸牌/弃牌数改为此牌造成的伤害值/此牌的目标数。', - ddd_zhouchu:'周处', - dddxiaheng:'侠横', - dddxiaheng_info:'锁定技。出牌阶段开始时,你选择一名角色,其弃置两张牌,然后你对一名角色造成1点伤害。“若这两名角色:均不为你,你减1点体力上限;为同一名角色,你失去〖侠横〗;然后若你以此法对三名不同的角色造成过伤害,删除该技能双引号里的描述。”', - ddd_liuba:'刘巴', - dddfengzheng:'丰政', - dddfengzheng_info:'①每名角色的出牌阶段限一次。其可将点数之和为13的任意张手牌当一张【无中生有】使用。②一轮游戏开始时,你可观看并分配牌堆顶的X张牌(X为上一轮发动过〖丰政〗的角色数),若有角色以此法得到的牌数多于两张,你失去〖丰政〗。', - dddyulv:'玉律', - dddyulv_info:'锁定技。①游戏开始时,你摸一张牌。将一张手牌置于武将牌上,称为“玉律”。②当有与“玉律”牌点数相同的牌进入弃牌堆后,你令当前回合角色摸一张牌或弃置一张牌。然后若本次为此回合使用的第二次〖玉律②〗,你用一张手牌交换“玉律”牌(若你没有手牌则先摸一张牌)。', - ddd_jianshuo:'蹇硕', - dddfenye:'分野', - dddfenye_info:'出牌阶段限一次。你可与一名其他角色拼点,其余角色于此次拼点中可加入其中一方并扣置一张手牌作为其拼点牌,本次拼点判断胜负的条件改为比较双方点数均值。然后拼点胜方角色依次可视为对一名不同的拼点败方角色使用【杀】。', - dddshichao:'逝潮', - dddshichao_info:'锁定技。准备阶段,你选择一名手牌数为全场第(1)大的角色,将手牌数调整至与其相等且至多等于主公的体力上限。然后当其于你的下回合开始前对你造成伤害时,其可防止之,令你〖逝潮〗的()内的数字+1。', - ddd_guanning:'管宁', - dddyouxue:'游学', - dddyouxue_info:'锁定技。一轮游戏开始时,你将场上的“游学”标记交给一名其他角色(若场上没有“游学”,你获得“游学”),然后摸X张牌(X为本次失去“游学”的角色至获得“游学”的角色的距离)。', - dddchengjing:'承经', - dddchengjing_info:'①一名角色的回合结束时,若其有“游学”,你将其于此回合内使用的最后一张{非转化且对应的实体牌数为1且均位于弃牌堆中}的基本牌或普通锦囊牌对应的所有实体牌置于武将牌上,称为“经”(若你此前有“经”,你先将这些“经”置入弃牌堆)。②出牌阶段限一次,你可以将一张牌当“经”使用,然后可以将该牌交给有“游学”的角色的下家。', - ddd_dingfeng:'丁奉', - dddduanbing:'短兵', - dddduanbing_info:'①出牌阶段,你可将一张黑色非锦囊牌当一张【兵粮寸断】置入自己的判定区,摸两张牌,然后视为使用一张无视距离限制的【杀】。②当你使用【杀】对目标角色造成伤害后,若你判定区里有【兵粮寸断】,你可将【兵粮寸断】移至目标角色的判定区。', - ddd_kebineng:'轲比能', - dddxiaoxing:'枭行', - dddxiaoxing_info:'锁定技。①你的初始手牌,攻击范围和手牌上限+3。②当你进入濒死状态时,你失去〖枭行〗。③当你获得〖枭行〗后,你摸三张牌。', - dddlangzhi:'狼志', - dddlangzhi_info:'结束阶段,你可展示你攻击范围内的所有角色各一张牌,然后选择一项:1.用任意张牌替换其中等量张牌;2.获得所有展示牌,失去〖狼志〗。', - dddfuyi:'附义', - dddfuyi_both:'〖枭行〗和〖狼志〗', - dddfuyi_info:'主公技,锁定技。①群势力角色使用【杀】的次数上限+1。②当一名群势力角色杀死角色后,其可以弃置两张牌,令你获得你武将牌上的一个技能。', - ddd_caoshuang:'曹爽', - ddd_xuelingyun:'薛灵芸', - ddd_liuhong:'刘宏', - ddd_xiahouxuan:'夏侯玄', - ddd_zhangkai:'张闿', - dddzhuanshe:'专摄', - dddzhuanshe_info:'其他角色的出牌阶段开始时,你可将一张手牌正面朝上交给该角色,则当其在此回合内使用与之名称相同的基本牌或普通锦囊牌时,你可无视距离限制为之额外选择一个目标;此回合结束时,若其未使用与之名称相同的牌,你可以对其造成1点伤害。', - dddweiqiu:'危秋', - dddweiqiu_info:'锁定技。一名角色回复体力前,若你没有手牌,改为令你摸一张牌。', - dddlianer:'涟洏', - dddlianer_info:'当你使用红色牌结算后,你可以获得之,然后你只能使用点数小于此牌的牌直到回合结束。', - dddanzhi:'暗织', - dddanzhi_info:'一名角色的回合开始时,若上一张被使用或打出的牌为黑色,你可以指定一名角色,此回合其第一次成为黑色牌的目标时,此牌对其无效。', - dddshixing:'失兴', - dddshixing_info:'锁定技。若有未受伤的女性角色,你视为拥有〖享乐〗;若当前回合没有锦囊牌被使用,你视为拥有〖酒诗〗;若你没有上述技能,你视为拥有〖制衡〗。', - ddddanggu:'党锢', - ddddanggu_info:'锁定技。①结束阶段,你横置任意名角色的武将牌,直到场上已横置的角色数不少于X(X为群势力角色数)。②其他角色的弃牌阶段,若其处于连环状态,其装备区里的牌视为手牌。', - dddfuzong:'覆宗', - dddfuzong_info:'主公技,锁定技。①游戏开始时,你摸等同于场上群势力角色数的牌。②一名群势力角色死亡时,其弃置你的一张牌。', - dddlanghuai:'朗怀', - dddlanghuai_info:'转换技。摸牌阶段,你可展示手牌(无牌则不展示),并改为摸其中:阴,包含花色数的牌;阳,缺少花色数的牌。', - dddxuanlun:'玄论', - dddxuanlun_info:'当你受到伤害后,你可摸四张牌,然后该回合结束时,你选择一项:1.将四张牌以任意顺序置于牌堆顶或底;2.删去此项和〖郎怀〗中的“可”直到你发动〖郎怀〗。', - dddjiexing:'劫行', - dddjiexing_info:'限定技。其他角色回复体力时,你可改为你回复等量体力;其他角色使用装备牌时,你可改为将此牌置入你的装备区。当你不以此法回复体力后或使用装备牌后,重置此技能。', - dddbailei:'拜泪', - dddbailei_info:'准备阶段,你可以选择一项:1.获得装备区牌数唯一最多的角色的一张牌;2.对一名体力值为1的角色造成1点伤害,若其因此死亡,你失去此技能。', - ddd_liangxi:'梁习', - dddtongyu:'仝御', - dddtongyu_info:'出牌阶段限一次,你可以将任意张花色不同的牌当做【五谷丰登】使用,且你为此牌选择结算方向,此牌的亮出牌数+X(X为此牌对应的实体牌数量)。此牌的所有目标角色在被指定目标后选择一项:⒈本回合不能再使用或打出手牌。⒉令此【五谷丰登】对其无效。此【五谷丰登】的多余展示牌置入弃牌堆前,你可以令一名选择了选项二的角色获得这些牌。', - ddd_wangkanglvkai:'王伉吕凯', - dddbingjian:'并肩', - dddbingjian_info:'每回合限两次。你可以将手牌数调整至2(至少调整一张),视为使用或打出一张【杀】或【闪】。若你:因此摸牌,则你可以令一名其他角色摸等量的牌;因此弃牌,则你可以弃置一名其他角色等量的牌。', - ddd_sunliang:'孙亮', - ddddiedang:'迭宕', - ddddiedang_info:'出牌阶段限一次,你可以摸三张牌,然后弃置一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“摸”和“弃”。', - dddanliu:'暗流', - dddanliu_info:'结束阶段,你可以与一名其他角色依次观看并选择对方的一张手牌,然后交换这两张牌。若这两张牌颜色相同,则你可以逾期交换这两张牌,且:若此牌为红色,则你回复1点体力;若此牌为黑色,则其摸两张牌。', - dddguiying:'归萤', - dddguiying_info:'主公技。准备阶段,其他吴势力角色可依次展示其一张手牌,然后将其点数最大的一张牌交给你,然后其可以获得场上点数最小的一张牌。', - ddd_qianzhao:'牵招', - dddyuanzhen:'远振', - dddyuanzhen_info:'锁定技。当你使用牌指定其他角色为唯一目标后,若你至其距离不为1,你令其选择一项:1.弃置一张牌;2.令你摸一张牌。', - dddzhishu:'制戍', - dddzhishu_info:'出牌阶段开始时,你可以移动场上的一张装备牌,然后以此法失去牌的角色视为对以此法装备区被置入牌的角色使用一张【过河拆桥】。', - ddd_zhangmiao:'张邈', - dddxiaxing:'侠行', - dddxiaxing_info:'①每轮限一次。一名角色处于濒死状态时/回合开始时,你可以将一张牌置于牌堆顶,视为其使用一张【桃】/【酒】。若你没有“侠”标记,你获得“侠”。②你可以移去“侠”,视为使用一张【杀】或【闪】。', - ddd_zhangcheng:'张承', - dddjuxian:'聚贤', - dddjuxian_info:'出牌阶段每项各限一次。你可以展示一张牌,然后:1.将其置于牌堆顶,然后获得其他角色的一张牌并展示之;2.将此牌交给一名其他角色,然后摸一张牌并展示之。若你以此法展示的两张牌颜色不同,此技能本回合失效。', - dddjungui:'隽轨', - dddjungui_info:'结束阶段,你可以令一名角色摸两张牌,然后其展示所有手牌,你选择一个不大于X的值。若Y大于0,你令其弃置Y张花色各不同的手牌(X为你于本回合使用过的牌的花色数,Y为其手牌中包含的花色数-X)。', - ddd_liuchong:'刘宠', - dddjinggou:'精彀', - dddjinggou_info:'锁定技。当你使用武器牌结算结束后,若你的攻击范围为全场最大,你对一名其他角色造成1点伤害。', - dddmoyan:'末焱', - dddmoyan_info:'一轮游戏开始时,你可以亮出牌堆顶三张牌,令一名角色选择获得其中至少一张牌,然后当你于本轮受到伤害时,若其手牌数不大于X,此伤害+1(X为其本次获得的牌数)。', - ddd_luoxian:'罗宪', - dddshilie:'示烈', - visible_dddshilie:'明', - dddshilie_info:'每回合限一次。当你需要使用一张【杀】或【闪】时,你可以明置任意点数之和不小于X的手牌,视为你使用之。若本次明置的牌点数等于X,你摸等同于本次明置的牌数的牌(X为你与当前回合角色的体力值之和)。', - ddd_lie:'李娥', - dddyeshen:'冶身', - dddyeshen_info:'一名角色的结束阶段,你可以亮出牌堆底三张牌,令其将其中一张黑色牌当做最大目标数为牌名字数的【铁索连环】使用或重铸,其余牌置于牌堆顶,然后此技能亮出牌数-1;若减至零张或其中没有黑色牌,你复原此技能并对自己造成1点火焰伤害。', - dddqiaoduan:'巧锻', - dddqiaoduan_info:'每回合限一次。当有角色:重置后,你可以令至多X名角色各摸一张牌;横置后,你可以将X张牌置于牌堆底,并令一名角色回复1点体力(X为横置角色数)。', + translate: { + ddd_handang: "韩当", + dddxianxi: "险袭", + dddxianxi_info: + "出牌阶段,你使用【杀】时可无视距离额外指定任意名角色为目标;此【杀】结算后,若额外指定的目标中有未受到此【杀】伤害的,你须选择一项:弃置X张牌对其各造成1点伤害;或摸X张牌并失去1点体力(X为未受到此【杀】伤害的目标数)。", + ddd_wuzhi: "吴质", + dddlingyong: "灵涌", + dddlingyong_info: + "一名角色跳过其的阶段时,你可进行判定。若结果不为【杀】,则你可以使用判定牌,然后重复此流程。", + dddxuxiao: "虚孝", + dddxuxiao_info: + "当有黑色基本牌因弃置而进入弃牌堆后,你可将其当做【兵粮寸断】置于一名角色的判定区,然后其摸两张牌。", + ddd_xujing: "许靖", + dddxuyu: "虚誉", + dddxuyu_info: + "当你使用牌结算结束后,你可以摸一张牌。若如此做,当你于本回合使用下一张牌结算结束后,你弃置一张牌。", + dddshijian: "实荐", + dddshijian_info: + "其他角色于其出牌阶段使用的第二张牌结算结束后,你可以交给其一张牌。若如此做,其本回合使用的下一张牌指定第一个目标时,你选择一项:1.令此牌额外结算一次;2.你摸一张牌。", + ddd_caomao: "曹髦", + dddtaisi: "太思", + dddtaisi_info: + "一名角色的回合结束时,若你的体力值于本回合内发生过变化,则你可以令一名角色获得一张于本回合内进入弃牌堆的牌。然后若该角色于本回合内对你造成过伤害,则你摸两张牌。", + dddquche: "驱车", + dddquche_info: + "限定技。出牌阶段,你可依次执行大括号内的流程至多X次(X为你的体力上限):{[⒈将一张牌交给一名其他角色]+[将一张黑色牌当做【杀】使用(不计入次数限制)]}。你每执行一个中括号内的选项,本回合内至其他角色的距离便-1。", + dddqianlong: "潜龙", + dddqianlong_info: + "主公技,锁定技。当你因执行奖惩而摸牌或弃置牌时,取消之;当你杀死一名角色后,你摸三张牌。", + ddd_xinxianying: "辛宪英", + ddddongcha: "洞察", + ddddongcha_info: + "其他角色的回合开始时,你可以令你和其依次将一张手牌置于你的武将牌上,称为“鉴”。若如此做,本回合结束时,你与其依次选择获得一张“鉴”。", + dddzhijie: "智解", + dddzhijie_info: + "你可以将两张颜色相同的“鉴”当做【闪】使用,或将两张颜色不同的“鉴”当做【无懈可击】使用;然后你摸两张牌。", + ddd_xianglang: "向朗", + dddqiahua: "恰化", + dddqiahua_info: + "其他角色的回合开始时,你可明置X张手牌(X为其体力值),然后其于本回合内获得〖恂恂〗。", + dddfusi: "腹笥", + dddfusi_info: + "锁定技。①你的明置手牌不计入手牌上限。②其他角色需要使用牌时,可以改为使用你的明置手牌(需经过你的确认)。③你的回合内,若你的手牌均为明置手牌,则其他角色不能使用各自的手牌。", + dddfusi_global: "腹笥", + dddtuoji: "拓籍", + dddtuoji_info: "其他角色因〖腹笥〗而使用你的牌后,若你的手牌均为明置手牌,则你可以摸三张牌。", + visible_dddxianglang: "明", + ddd_yujin: "于禁", + dddzhengjun: "整军", + dddzhengjun_info: + "出牌阶段内每项各限一次。当有角色的手牌数/体力值/装备区内牌数变化后,若其的对应数值与你相同,则你可以执行对应的选项。体力值:你令其回复或失去1点体力;手牌数:你令其摸或弃置一张牌;装备区内牌数:你移动其的一张装备牌。", + ddd_liuye: "刘晔", + dddchashi: "察势", + dddchashi_info: + "其他角色的出牌阶段开始时,你可弃置一张牌A。当其于本阶段内使用下一张牌结算结束后,若此牌与A花色或类型相同,你与其各摸一张牌。", + dddqice: "齐策", + dddqice_info: "准备阶段开始时,你可以摸两张牌,然后你的〖齐策〗失效直到你使用锦囊牌。", + ddd_baosanniang: "鲍三娘", + dddzhilian: "枝连", + dddzhilian_info: + "一名角色的回合结束时,若本回合仅有你与另一名男性角色使用或打出过牌,则你可以令你与其各摸一张牌或各弃置一张牌,然后你获得本回合内进入弃牌堆的所有【杀】。", + dddjijian: "赍剑", + dddjijian_info: + "出牌阶段限一次。你可以展示一张【杀】并交给一名其他男性角色,然后其展示至多两张颜色相同的【杀】或普通锦囊牌,你与其依次视为使用一张其展示的牌(不能重复使用同一张展示牌)。", + ddd_zhenji: "甄姬", + dddmiaoxing: "淼形", + dddmiaoxing_info: + "锁定技。①分发起始手牌时,你额外获得两份起始手牌,然后将其中的两份移出游戏,称为“水相”。②摸牌阶段结束后,你须将至少一份“水相”调整至与你的手牌数相等。", + dddfushi: "浮世", + dddfushi_info: + "每回合限一次。当你使用或打出基本牌结算结束后,你可以用所有手牌交换一份“水相”,然后你可令一名男性角色选择是否用其所有手牌交换一份“水相”。", + ddd_zhaoang: "赵昂", + dddfenji: "奋计", + dddfenji_info: + "摸牌/弃牌阶段开始时,你可视为使用一张未以此法使用过的普通锦囊牌,然后将此阶段摸牌/弃牌数改为此牌造成的伤害值/此牌的目标数。", + ddd_zhouchu: "周处", + dddxiaheng: "侠横", + dddxiaheng_info: + "锁定技。出牌阶段开始时,你选择一名角色,其弃置两张牌,然后你对一名角色造成1点伤害。“若这两名角色:均不为你,你减1点体力上限;为同一名角色,你失去〖侠横〗;然后若你以此法对三名不同的角色造成过伤害,删除该技能双引号里的描述。”", + ddd_liuba: "刘巴", + dddfengzheng: "丰政", + dddfengzheng_info: + "①每名角色的出牌阶段限一次。其可将点数之和为13的任意张手牌当一张【无中生有】使用。②一轮游戏开始时,你可观看并分配牌堆顶的X张牌(X为上一轮发动过〖丰政〗的角色数),若有角色以此法得到的牌数多于两张,你失去〖丰政〗。", + dddyulv: "玉律", + dddyulv_info: + "锁定技。①游戏开始时,你摸一张牌。将一张手牌置于武将牌上,称为“玉律”。②当有与“玉律”牌点数相同的牌进入弃牌堆后,你令当前回合角色摸一张牌或弃置一张牌。然后若本次为此回合使用的第二次〖玉律②〗,你用一张手牌交换“玉律”牌(若你没有手牌则先摸一张牌)。", + ddd_jianshuo: "蹇硕", + dddfenye: "分野", + dddfenye_info: + "出牌阶段限一次。你可与一名其他角色拼点,其余角色于此次拼点中可加入其中一方并扣置一张手牌作为其拼点牌,本次拼点判断胜负的条件改为比较双方点数均值。然后拼点胜方角色依次可视为对一名不同的拼点败方角色使用【杀】。", + dddshichao: "逝潮", + dddshichao_info: + "锁定技。准备阶段,你选择一名手牌数为全场第(1)大的角色,将手牌数调整至与其相等且至多等于主公的体力上限。然后当其于你的下回合开始前对你造成伤害时,其可防止之,令你〖逝潮〗的()内的数字+1。", + ddd_guanning: "管宁", + dddyouxue: "游学", + dddyouxue_info: + "锁定技。一轮游戏开始时,你将场上的“游学”标记交给一名其他角色(若场上没有“游学”,你获得“游学”),然后摸X张牌(X为本次失去“游学”的角色至获得“游学”的角色的距离)。", + dddchengjing: "承经", + dddchengjing_info: + "①一名角色的回合结束时,若其有“游学”,你将其于此回合内使用的最后一张{非转化且对应的实体牌数为1且均位于弃牌堆中}的基本牌或普通锦囊牌对应的所有实体牌置于武将牌上,称为“经”(若你此前有“经”,你先将这些“经”置入弃牌堆)。②出牌阶段限一次,你可以将一张牌当“经”使用,然后可以将该牌交给有“游学”的角色的下家。", + ddd_dingfeng: "丁奉", + dddduanbing: "短兵", + dddduanbing_info: + "①出牌阶段,你可将一张黑色非锦囊牌当一张【兵粮寸断】置入自己的判定区,摸两张牌,然后视为使用一张无视距离限制的【杀】。②当你使用【杀】对目标角色造成伤害后,若你判定区里有【兵粮寸断】,你可将【兵粮寸断】移至目标角色的判定区。", + ddd_kebineng: "轲比能", + dddxiaoxing: "枭行", + dddxiaoxing_info: + "锁定技。①你的初始手牌,攻击范围和手牌上限+3。②当你进入濒死状态时,你失去〖枭行〗。③当你获得〖枭行〗后,你摸三张牌。", + dddlangzhi: "狼志", + dddlangzhi_info: + "结束阶段,你可展示你攻击范围内的所有角色各一张牌,然后选择一项:1.用任意张牌替换其中等量张牌;2.获得所有展示牌,失去〖狼志〗。", + dddfuyi: "附义", + dddfuyi_both: "〖枭行〗和〖狼志〗", + dddfuyi_info: + "主公技,锁定技。①群势力角色使用【杀】的次数上限+1。②当一名群势力角色杀死角色后,其可以弃置两张牌,令你获得你武将牌上的一个技能。", + ddd_caoshuang: "曹爽", + ddd_xuelingyun: "薛灵芸", + ddd_liuhong: "刘宏", + ddd_xiahouxuan: "夏侯玄", + ddd_zhangkai: "张闿", + dddzhuanshe: "专摄", + dddzhuanshe_info: + "其他角色的出牌阶段开始时,你可将一张手牌正面朝上交给该角色,则当其在此回合内使用与之名称相同的基本牌或普通锦囊牌时,你可无视距离限制为之额外选择一个目标;此回合结束时,若其未使用与之名称相同的牌,你可以对其造成1点伤害。", + dddweiqiu: "危秋", + dddweiqiu_info: "锁定技。一名角色回复体力前,若你没有手牌,改为令你摸一张牌。", + dddlianer: "涟洏", + dddlianer_info: + "当你使用红色牌结算后,你可以获得之,然后你只能使用点数小于此牌的牌直到回合结束。", + dddanzhi: "暗织", + dddanzhi_info: + "一名角色的回合开始时,若上一张被使用或打出的牌为黑色,你可以指定一名角色,此回合其第一次成为黑色牌的目标时,此牌对其无效。", + dddshixing: "失兴", + dddshixing_info: + "锁定技。若有未受伤的女性角色,你视为拥有〖享乐〗;若当前回合没有锦囊牌被使用,你视为拥有〖酒诗〗;若你没有上述技能,你视为拥有〖制衡〗。", + ddddanggu: "党锢", + ddddanggu_info: + "锁定技。①结束阶段,你横置任意名角色的武将牌,直到场上已横置的角色数不少于X(X为群势力角色数)。②其他角色的弃牌阶段,若其处于连环状态,其装备区里的牌视为手牌。", + dddfuzong: "覆宗", + dddfuzong_info: + "主公技,锁定技。①游戏开始时,你摸等同于场上群势力角色数的牌。②一名群势力角色死亡时,其弃置你的一张牌。", + dddlanghuai: "朗怀", + dddlanghuai_info: + "转换技。摸牌阶段,你可展示手牌(无牌则不展示),并改为摸其中:阴,包含花色数的牌;阳,缺少花色数的牌。", + dddxuanlun: "玄论", + dddxuanlun_info: + "当你受到伤害后,你可摸四张牌,然后该回合结束时,你选择一项:1.将四张牌以任意顺序置于牌堆顶或底;2.删去此项和〖郎怀〗中的“可”直到你发动〖郎怀〗。", + dddjiexing: "劫行", + dddjiexing_info: + "限定技。其他角色回复体力时,你可改为你回复等量体力;其他角色使用装备牌时,你可改为将此牌置入你的装备区。当你不以此法回复体力后或使用装备牌后,重置此技能。", + dddbailei: "拜泪", + dddbailei_info: + "准备阶段,你可以选择一项:1.获得装备区牌数唯一最多的角色的一张牌;2.对一名体力值为1的角色造成1点伤害,若其因此死亡,你失去此技能。", + ddd_liangxi: "梁习", + dddtongyu: "仝御", + dddtongyu_info: + "出牌阶段限一次,你可以将任意张花色不同的牌当做【五谷丰登】使用,且你为此牌选择结算方向,此牌的亮出牌数+X(X为此牌对应的实体牌数量)。此牌的所有目标角色在被指定目标后选择一项:⒈本回合不能再使用或打出手牌。⒉令此【五谷丰登】对其无效。此【五谷丰登】的多余展示牌置入弃牌堆前,你可以令一名选择了选项二的角色获得这些牌。", + ddd_wangkanglvkai: "王伉吕凯", + dddbingjian: "并肩", + dddbingjian_info: + "每回合限两次。你可以将手牌数调整至2(至少调整一张),视为使用或打出一张【杀】或【闪】。若你:因此摸牌,则你可以令一名其他角色摸等量的牌;因此弃牌,则你可以弃置一名其他角色等量的牌。", + ddd_sunliang: "孙亮", + ddddiedang: "迭宕", + ddddiedang_info: + "出牌阶段限一次,你可以摸三张牌,然后弃置一张牌;然后若你的手牌数为全场最多或最少,则你交换上述描述中的“摸”和“弃”。", + dddanliu: "暗流", + dddanliu_info: + "结束阶段,你可以与一名其他角色依次观看并选择对方的一张手牌,然后交换这两张牌。若这两张牌颜色相同,则你可以逾期交换这两张牌,且:若此牌为红色,则你回复1点体力;若此牌为黑色,则其摸两张牌。", + dddguiying: "归萤", + dddguiying_info: + "主公技。准备阶段,其他吴势力角色可依次展示其一张手牌,然后将其点数最大的一张牌交给你,然后其可以获得场上点数最小的一张牌。", + ddd_qianzhao: "牵招", + dddyuanzhen: "远振", + dddyuanzhen_info: + "锁定技。当你使用牌指定其他角色为唯一目标后,若你至其距离不为1,你令其选择一项:1.弃置一张牌;2.令你摸一张牌。", + dddzhishu: "制戍", + dddzhishu_info: + "出牌阶段开始时,你可以移动场上的一张装备牌,然后以此法失去牌的角色视为对以此法装备区被置入牌的角色使用一张【过河拆桥】。", + ddd_zhangmiao: "张邈", + dddxiaxing: "侠行", + dddxiaxing_info: + "①每轮限一次。一名角色处于濒死状态时/回合开始时,你可以将一张牌置于牌堆顶,视为其使用一张【桃】/【酒】。若你没有“侠”标记,你获得“侠”。②你可以移去“侠”,视为使用一张【杀】或【闪】。", + ddd_zhangcheng: "张承", + dddjuxian: "聚贤", + dddjuxian_info: + "出牌阶段每项各限一次。你可以展示一张牌,然后:1.将其置于牌堆顶,然后获得其他角色的一张牌并展示之;2.将此牌交给一名其他角色,然后摸一张牌并展示之。若你以此法展示的两张牌颜色不同,此技能本回合失效。", + dddjungui: "隽轨", + dddjungui_info: + "结束阶段,你可以令一名角色摸两张牌,然后其展示所有手牌,你选择一个不大于X的值。若Y大于0,你令其弃置Y张花色各不同的手牌(X为你于本回合使用过的牌的花色数,Y为其手牌中包含的花色数-X)。", + ddd_liuchong: "刘宠", + dddjinggou: "精彀", + dddjinggou_info: + "锁定技。当你使用武器牌结算结束后,若你的攻击范围为全场最大,你对一名其他角色造成1点伤害。", + dddmoyan: "末焱", + dddmoyan_info: + "一轮游戏开始时,你可以亮出牌堆顶三张牌,令一名角色选择获得其中至少一张牌,然后当你于本轮受到伤害时,若其手牌数不大于X,此伤害+1(X为其本次获得的牌数)。", + ddd_luoxian: "罗宪", + dddshilie: "示烈", + visible_dddshilie: "明", + dddshilie_info: + "每回合限一次。当你需要使用一张【杀】或【闪】时,你可以明置任意点数之和不小于X的手牌,视为你使用之。若本次明置的牌点数等于X,你摸等同于本次明置的牌数的牌(X为你与当前回合角色的体力值之和)。", + ddd_lie: "李娥", + dddyeshen: "冶身", + dddyeshen_info: + "一名角色的结束阶段,你可以亮出牌堆底三张牌,令其将其中一张黑色牌当做最大目标数为牌名字数的【铁索连环】使用或重铸,其余牌置于牌堆顶,然后此技能亮出牌数-1;若减至零张或其中没有黑色牌,你复原此技能并对自己造成1点火焰伤害。", + dddqiaoduan: "巧锻", + dddqiaoduan_info: + "每回合限一次。当有角色:重置后,你可以令至多X名角色各摸一张牌;横置后,你可以将X张牌置于牌堆底,并令一名角色回复1点体力(X为横置角色数)。", }, }; }); diff --git a/character/diy.js b/character/diy.js index c9cd5422f..4d338ba34 100755 --- a/character/diy.js +++ b/character/diy.js @@ -1,2241 +1,2769 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'diy', - connect:true, - connectBanned:['diy_tianyu','diy_yangyi','diy_lukang','ns_huamulan','ns_yuji','ns_duangui','ns_liuzhang','key_yuu'], - character:{ - noname:["female","key",3,["noname_zhuyuan","noname_duocai"]], - sp_key_yuri:['female','qun',4,['mubing','ziqu','diaoling'],['border:key']], - key_lucia:['female','key','2/3',['lucia_duqu','lucia_zhenren']], - key_kyousuke:['male','key',4,['nk_shekong','key_huanjie']], - key_yuri:['female','key',3,['yuri_xingdong','key_huanjie','yuri_wangxi'],['zhu']], - key_haruko:['female','key',4,['haruko_haofang','haruko_zhuishi']], - key_umi:['female','key',3,['umi_chaofan','umi_lunhui','umi_qihuan']], - key_umi2:['female','key',3,[],['unseen']], - key_rei:['male','key',4,['xiandeng','shulv','xisheng']], - key_komari:['female','key',3,['komari_tiankou','komari_xueshang']], - key_yukine:['female','key',3,['yukine_wenzhou']], - key_yusa:['female','key',3,['yusa_yanyi','yusa_misa','dualside'],['dualside:key_misa']], - key_misa:['female','key',3,['misa_yehuo','misa_yusa','dualside'],['unseen']], - key_masato:['male','key','4/8',['masato_baoquan']], - key_iwasawa:['female','key',3,['iwasawa_yinhang','iwasawa_mysong']], - key_kengo:['male','key',4,['kengo_weishang','kengo_guidui']], - key_yoshino:['male','key',4,['yoshino_jueyi']], - key_yui:['female','key',3,['yui_jiang','yui_lieyin','yui_takaramono']], - key_tsumugi:['female','key',3,['tsumugi_mugyu','tsumugi_huilang']], - key_saya:['female','key',3,['saya_shouji','saya_powei']], - key_harukakanata:['female','key',3,['haruka_shuangche']], - key_inari:['female','key',2,['inari_baiwei','inari_huhun']], - key_shiina:['female','key',3,['shiina_qingshen','shiina_feiyan']], - key_sunohara:['double','key','3/3/2',['sunohara_chengshuang','sunohara_tiaoyin','sunohara_jianren']], - key_rin:['female','key',3,['rin_baoqiu']], - key_sasami:['female','key',3,['sasami_miaobian']], - key_akane:['female','key',3,['akane_jugu','akane_quanqing','akane_yifu'],['zhu']], - key_doruji:['female','key',16,['doruji_feiqu']], - key_yuiko:['female','key',3,['yuiko_fenglun','yuiko_dilve']], - key_riki:['double','key',3,['riki_spwenji','riki_nvzhuang','riki_mengzhong']], - key_hisako:['female','key',3,['hisako_yinbao','hisako_zhuanyun']], - key_hinata:['male','key',4,['hinata_qiulve','hinata_ehou']], - key_noda:['male','key',4,['noda_fengcheng','noda_xunxin']], - key_tomoya:['male','key',4,['tomoya_shangxian','tomoya_wangjin']], - key_nagisa:['female','key',3,['nagisa_tiandu','nagisa_fuxin']], - key_ayato:['male','key',3,['ayato_jianshen','ayato_zonghuan']], - key_ao:['female','key',3,['ao_xishi','ao_kuihun','ao_shixin']], - key_yuzuru:['male','key',5,['yuzuru_wuxin','yuzuru_deyi']], - sp_key_kanade:['female','key',3,['kanade_mapo','kanade_benzhan']], - key_mio:['female','key',3,['mio_tuifu','mio_tishen']], - key_midori:['female','key',3,['midori_nonghuan','midori_tishen']], - key_kyoko:['female','key',3,['kyoko_juwu','kyoko_zhengyi']], - key_shizuru:['female','key',3,['shizuru_nianli','shizuru_benzhan']], - key_shiorimiyuki:['female','key',3,['shiorimiyuki_banyin','shiorimiyuki_tingxian']], - key_miki:['female','key',3,['miki_shenqiang','miki_huanmeng','miki_zhiluo']], - key_shiori:['female','key','2/3',['shiori_huijuan']], - key_kaori:['female','key','3/4',['kaori_siyuan']], - key_akiko:['female','key',3,['akiko_dongcha']], - key_abyusa:['female','key',3,['abyusa_jueqing','abyusa_dunying']], - key_godan:['male','key',6,['godan_yuanyi','godan_feiqu','godan_xiaoyuan']], - key_yuu:['male','key',3,['yuu_lveduo']], - key_ryoichi:['male','key',4,['ryoichi_baoyi','ryoichi_tuipi']], - key_kotori:['female','key',3,['kotori_yumo','kotori_huazhan']], - key_jojiro:['male','key',4,['jojiro_shensu','jojiro_shunying']], - key_shiroha:['female','key',3,['shiroha_yuzhao','shiroha_guying','shiroha_jiezhao']], - key_shizuku:['female','key',3,['shizuku_sizhi','shizuku_biyi','shizuku_sanhua']], - key_hiroto:['male','key',3,['hiroto_huyu','hiroto_tuolao']], - key_sakuya:['male','key',3,['youlong','luanfeng','sakuya_junbu']], - key_youta:['male','key',4,[]], - key_rumi:['female','key','3/4',['rumi_shuwu']], - key_chihaya:['female','key',3,['chihaya_liewu','chihaya_youfeng']], - key_yukito:['male','key',4,['yukito_kongwu','yukito_yaxiang']], - key_crow:['male','key',4,[],['unseen']], - key_asara:['female','key',3,['asara_shelu','asara_yingwei']], - key_kotomi:['female','key',3,['kotomi_qinji','kotomi_chuanxiang']], - key_mia:['female','key',3,['mia_shihui','mia_qianmeng']], - key_kano:['female','key',3,['kano_liezhen','kano_poyu']], - db_key_liyingxia:['female','shu',3,['liyingxia_sanli','liyingxia_zhenjun','liyingxia_wumai'],['doublegroup:shu:key']], - key_erika:['female','key','3/3/2',['erika_shisong','erika_yousheng']], - key_satomi:['female','key',3,['satomi_luodao','satomi_daohai']], - key_iriya:['female','key',3,['iriya_yinji','iriya_haozhi']], - key_fuuko:['female','key',3,['fuuko_xingdiao','fuuko_chuanyuan']], + name: "diy", + connect: true, + connectBanned: [ + "diy_tianyu", + "diy_yangyi", + "diy_lukang", + "ns_huamulan", + "ns_yuji", + "ns_duangui", + "ns_liuzhang", + "key_yuu", + ], + character: { + noname: ["female", "key", 3, ["noname_zhuyuan", "noname_duocai"]], + sp_key_yuri: ["female", "qun", 4, ["mubing", "ziqu", "diaoling"], ["border:key"]], + key_lucia: ["female", "key", "2/3", ["lucia_duqu", "lucia_zhenren"]], + key_kyousuke: ["male", "key", 4, ["nk_shekong", "key_huanjie"]], + key_yuri: ["female", "key", 3, ["yuri_xingdong", "key_huanjie", "yuri_wangxi"], ["zhu"]], + key_haruko: ["female", "key", 4, ["haruko_haofang", "haruko_zhuishi"]], + key_umi: ["female", "key", 3, ["umi_chaofan", "umi_lunhui", "umi_qihuan"]], + key_umi2: ["female", "key", 3, [], ["unseen"]], + key_rei: ["male", "key", 4, ["xiandeng", "shulv", "xisheng"]], + key_komari: ["female", "key", 3, ["komari_tiankou", "komari_xueshang"]], + key_yukine: ["female", "key", 3, ["yukine_wenzhou"]], + key_yusa: ["female", "key", 3, ["yusa_yanyi", "yusa_misa", "dualside"], ["dualside:key_misa"]], + key_misa: ["female", "key", 3, ["misa_yehuo", "misa_yusa", "dualside"], ["unseen"]], + key_masato: ["male", "key", "4/8", ["masato_baoquan"]], + key_iwasawa: ["female", "key", 3, ["iwasawa_yinhang", "iwasawa_mysong"]], + key_kengo: ["male", "key", 4, ["kengo_weishang", "kengo_guidui"]], + key_yoshino: ["male", "key", 4, ["yoshino_jueyi"]], + key_yui: ["female", "key", 3, ["yui_jiang", "yui_lieyin", "yui_takaramono"]], + key_tsumugi: ["female", "key", 3, ["tsumugi_mugyu", "tsumugi_huilang"]], + key_saya: ["female", "key", 3, ["saya_shouji", "saya_powei"]], + key_harukakanata: ["female", "key", 3, ["haruka_shuangche"]], + key_inari: ["female", "key", 2, ["inari_baiwei", "inari_huhun"]], + key_shiina: ["female", "key", 3, ["shiina_qingshen", "shiina_feiyan"]], + key_sunohara: [ + "double", + "key", + "3/3/2", + ["sunohara_chengshuang", "sunohara_tiaoyin", "sunohara_jianren"], + ], + key_rin: ["female", "key", 3, ["rin_baoqiu"]], + key_sasami: ["female", "key", 3, ["sasami_miaobian"]], + key_akane: ["female", "key", 3, ["akane_jugu", "akane_quanqing", "akane_yifu"], ["zhu"]], + key_doruji: ["female", "key", 16, ["doruji_feiqu"]], + key_yuiko: ["female", "key", 3, ["yuiko_fenglun", "yuiko_dilve"]], + key_riki: ["double", "key", 3, ["riki_spwenji", "riki_nvzhuang", "riki_mengzhong"]], + key_hisako: ["female", "key", 3, ["hisako_yinbao", "hisako_zhuanyun"]], + key_hinata: ["male", "key", 4, ["hinata_qiulve", "hinata_ehou"]], + key_noda: ["male", "key", 4, ["noda_fengcheng", "noda_xunxin"]], + key_tomoya: ["male", "key", 4, ["tomoya_shangxian", "tomoya_wangjin"]], + key_nagisa: ["female", "key", 3, ["nagisa_tiandu", "nagisa_fuxin"]], + key_ayato: ["male", "key", 3, ["ayato_jianshen", "ayato_zonghuan"]], + key_ao: ["female", "key", 3, ["ao_xishi", "ao_kuihun", "ao_shixin"]], + key_yuzuru: ["male", "key", 5, ["yuzuru_wuxin", "yuzuru_deyi"]], + sp_key_kanade: ["female", "key", 3, ["kanade_mapo", "kanade_benzhan"]], + key_mio: ["female", "key", 3, ["mio_tuifu", "mio_tishen"]], + key_midori: ["female", "key", 3, ["midori_nonghuan", "midori_tishen"]], + key_kyoko: ["female", "key", 3, ["kyoko_juwu", "kyoko_zhengyi"]], + key_shizuru: ["female", "key", 3, ["shizuru_nianli", "shizuru_benzhan"]], + key_shiorimiyuki: ["female", "key", 3, ["shiorimiyuki_banyin", "shiorimiyuki_tingxian"]], + key_miki: ["female", "key", 3, ["miki_shenqiang", "miki_huanmeng", "miki_zhiluo"]], + key_shiori: ["female", "key", "2/3", ["shiori_huijuan"]], + key_kaori: ["female", "key", "3/4", ["kaori_siyuan"]], + key_akiko: ["female", "key", 3, ["akiko_dongcha"]], + key_abyusa: ["female", "key", 3, ["abyusa_jueqing", "abyusa_dunying"]], + key_godan: ["male", "key", 6, ["godan_yuanyi", "godan_feiqu", "godan_xiaoyuan"]], + key_yuu: ["male", "key", 3, ["yuu_lveduo"]], + key_ryoichi: ["male", "key", 4, ["ryoichi_baoyi", "ryoichi_tuipi"]], + key_kotori: ["female", "key", 3, ["kotori_yumo", "kotori_huazhan"]], + key_jojiro: ["male", "key", 4, ["jojiro_shensu", "jojiro_shunying"]], + key_shiroha: ["female", "key", 3, ["shiroha_yuzhao", "shiroha_guying", "shiroha_jiezhao"]], + key_shizuku: ["female", "key", 3, ["shizuku_sizhi", "shizuku_biyi", "shizuku_sanhua"]], + key_hiroto: ["male", "key", 3, ["hiroto_huyu", "hiroto_tuolao"]], + key_sakuya: ["male", "key", 3, ["youlong", "luanfeng", "sakuya_junbu"]], + key_youta: ["male", "key", 4, []], + key_rumi: ["female", "key", "3/4", ["rumi_shuwu"]], + key_chihaya: ["female", "key", 3, ["chihaya_liewu", "chihaya_youfeng"]], + key_yukito: ["male", "key", 4, ["yukito_kongwu", "yukito_yaxiang"]], + key_crow: ["male", "key", 4, [], ["unseen"]], + key_asara: ["female", "key", 3, ["asara_shelu", "asara_yingwei"]], + key_kotomi: ["female", "key", 3, ["kotomi_qinji", "kotomi_chuanxiang"]], + key_mia: ["female", "key", 3, ["mia_shihui", "mia_qianmeng"]], + key_kano: ["female", "key", 3, ["kano_liezhen", "kano_poyu"]], + db_key_liyingxia: [ + "female", + "shu", + 3, + ["liyingxia_sanli", "liyingxia_zhenjun", "liyingxia_wumai"], + ["doublegroup:shu:key"], + ], + key_erika: ["female", "key", "3/3/2", ["erika_shisong", "erika_yousheng"]], + key_satomi: ["female", "key", 3, ["satomi_luodao", "satomi_daohai"]], + key_iriya: ["female", "key", 3, ["iriya_yinji", "iriya_haozhi"]], + key_fuuko: ["female", "key", 3, ["fuuko_xingdiao", "fuuko_chuanyuan"]], - key_kud:['female','key',3,['kud_qiaoshou','kud_buhui']], - key_misuzu:['female','key',3,['misuzu_hengzhou','misuzu_nongyin','misuzu_zhongxing']], - key_kamome:['female','key',3,['kamome_yangfan','kamome_huanmeng','kamome_jieban']], - key_nao:['female','key',3,['nao_duyin','nao_wanxin','nao_shouqing']], - key_yuuki:['female','key',3,['yuuki_yicha']], - key_kotarou:['male','key',3,['kotarou_rewrite','kotarou_aurora']], - key_tenzen:['male','key',4,['tenzen_fenghuan','tenzen_retianquan']], - key_kyouko:['female','key',3,['kyouko_rongzhu','kyouko_gongmian']], - key_kyou:['female','key',3,['kyou_zhidian','kyou_duanfa']], - key_seira:['female','key',3,['seira_xinghui','seira_yuanying']], - key_kiyu:['female','key',3,['kiyu_yuling','kiyu_rexianyu']], - key_tomoyo:['female','key',4,['tomoyo_wuwei','tomoyo_zhengfeng']], - key_minagi:['female','key',3,['minagi_peiquan','minagi_huanliu']], - key_michiru:['female','key',3,['michiru_sheyuan']], + key_kud: ["female", "key", 3, ["kud_qiaoshou", "kud_buhui"]], + key_misuzu: ["female", "key", 3, ["misuzu_hengzhou", "misuzu_nongyin", "misuzu_zhongxing"]], + key_kamome: ["female", "key", 3, ["kamome_yangfan", "kamome_huanmeng", "kamome_jieban"]], + key_nao: ["female", "key", 3, ["nao_duyin", "nao_wanxin", "nao_shouqing"]], + key_yuuki: ["female", "key", 3, ["yuuki_yicha"]], + key_kotarou: ["male", "key", 3, ["kotarou_rewrite", "kotarou_aurora"]], + key_tenzen: ["male", "key", 4, ["tenzen_fenghuan", "tenzen_retianquan"]], + key_kyouko: ["female", "key", 3, ["kyouko_rongzhu", "kyouko_gongmian"]], + key_kyou: ["female", "key", 3, ["kyou_zhidian", "kyou_duanfa"]], + key_seira: ["female", "key", 3, ["seira_xinghui", "seira_yuanying"]], + key_kiyu: ["female", "key", 3, ["kiyu_yuling", "kiyu_rexianyu"]], + key_tomoyo: ["female", "key", 4, ["tomoyo_wuwei", "tomoyo_zhengfeng"]], + key_minagi: ["female", "key", 3, ["minagi_peiquan", "minagi_huanliu"]], + key_michiru: ["female", "key", 3, ["michiru_sheyuan"]], - ns_huangchengyan:['male','shu',3,['nslongyue','nszhenyin']], - ns_sunchensunjun:['male','wu',5,['nsxianhai','nsxingchu']], - ns_yuanxi:['male','qun',4,['nsshengyan','nsdaizhan']], - ns_caoshuang:['male','wei',4,['nsjiquan','nsfuwei']], - ns_sunyi:['male','wu',4,['nsguolie']], - ns_huangwudie:['female','shu',4,['nsdiewu','nslingying','nspojian']], - ns_chentai:['male','wei',4,['nsweiyuan','nsjuxian']], - ns_zhangning:['female','qun',3,['nsfuzhou','nsguidao','nstaiping']], - ns_yanghu:['male','jin',3,['nsbizhao','nsqingde','nsyidi'],['hiddenSkill']], - ns_zanghong:['male','qun',4,['nsshimeng']], - ns_ruanji:['male','wei',3,['nsshizui','nsxiaoye']], - ns_limi:['male','jin',3,['nstuilun']], - ns_zhonglimu:['male','wu',4,['nskuanhuai','nsdingbian']], - prp_zhugeliang:['male','shu',3,['nsxingyun','nshanlang']], + ns_huangchengyan: ["male", "shu", 3, ["nslongyue", "nszhenyin"]], + ns_sunchensunjun: ["male", "wu", 5, ["nsxianhai", "nsxingchu"]], + ns_yuanxi: ["male", "qun", 4, ["nsshengyan", "nsdaizhan"]], + ns_caoshuang: ["male", "wei", 4, ["nsjiquan", "nsfuwei"]], + ns_sunyi: ["male", "wu", 4, ["nsguolie"]], + ns_huangwudie: ["female", "shu", 4, ["nsdiewu", "nslingying", "nspojian"]], + ns_chentai: ["male", "wei", 4, ["nsweiyuan", "nsjuxian"]], + ns_zhangning: ["female", "qun", 3, ["nsfuzhou", "nsguidao", "nstaiping"]], + ns_yanghu: ["male", "jin", 3, ["nsbizhao", "nsqingde", "nsyidi"], ["hiddenSkill"]], + ns_zanghong: ["male", "qun", 4, ["nsshimeng"]], + ns_ruanji: ["male", "wei", 3, ["nsshizui", "nsxiaoye"]], + ns_limi: ["male", "jin", 3, ["nstuilun"]], + ns_zhonglimu: ["male", "wu", 4, ["nskuanhuai", "nsdingbian"]], + prp_zhugeliang: ["male", "shu", 3, ["nsxingyun", "nshanlang"]], - ns_zhangwei:['female','shu',3,['nsqiyue','nsxuezhu']], - diy_wenyang:['male','wei','4/6',['lvli','choujue']], + ns_zhangwei: ["female", "shu", 3, ["nsqiyue", "nsxuezhu"]], + diy_wenyang: ["male", "wei", "4/6", ["lvli", "choujue"]], // diy_caocao:['male','wei',4,['xicai','diyjianxiong','hujia']], - diy_hanlong:['male','wei',4,['siji','ciqiu']], - diy_feishi:['male','shu',3,['nsshuaiyan','moshou']], - diy_liuyan:['male','qun',3,['juedao','geju']], + diy_hanlong: ["male", "wei", 4, ["siji", "ciqiu"]], + diy_feishi: ["male", "shu", 3, ["nsshuaiyan", "moshou"]], + diy_liuyan: ["male", "qun", 3, ["juedao", "geju"]], // diy_luxun:['male','wu',3,['shaoying','zonghuo']], - diy_yuji:['male','qun',3,['diyguhuo','diychanyuan']], + diy_yuji: ["male", "qun", 3, ["diyguhuo", "diychanyuan"]], // diy_zhouyu:['male','wu',3,['jieyan','honglian']], // diy_zhouyu:['male','wu',3,['xiongzi','yaliang']], - diy_caiwenji:['female','qun',3,['beige','guihan']], - diy_lukang:['male','wu',4,['luweiyan','qianxun']], + diy_caiwenji: ["female", "qun", 3, ["beige", "guihan"]], + diy_lukang: ["male", "wu", 4, ["luweiyan", "qianxun"]], // diy_xuhuang:['male','wei',4,['diyduanliang']], // diy_dianwei:['male','wei',4,['diyqiangxi']], // diy_huangzhong:['male','shu',4,['liegong','fuli']], // diy_weiyan:['male','shu',4,['diykuanggu']], - diy_zhenji:['female','wei',3,['diy_jiaoxia','yiesheng']], + diy_zhenji: ["female", "wei", 3, ["diy_jiaoxia", "yiesheng"]], // diy_menghuo:['male','shu',4,['huoshou','zaiqix']], //re_huangyueying:['female','shu',3,['rejizhi','qicai']], - diy_liufu:['male','wei',3,['zhucheng','duoqi']], - diy_xizhenxihong:['male','shu',4,['fuchou','jinyan']], - diy_liuzan:['male','wu',4,['kangyin']], - diy_zaozhirenjun:['male','wei',3,['liangce','jianbi','diyjuntun']], - diy_yangyi:['male','shu',3,['choudu','liduan']], - diy_tianyu:['male','wei',4,['chezhen','youzhan']], + diy_liufu: ["male", "wei", 3, ["zhucheng", "duoqi"]], + diy_xizhenxihong: ["male", "shu", 4, ["fuchou", "jinyan"]], + diy_liuzan: ["male", "wu", 4, ["kangyin"]], + diy_zaozhirenjun: ["male", "wei", 3, ["liangce", "jianbi", "diyjuntun"]], + diy_yangyi: ["male", "shu", 3, ["choudu", "liduan"]], + diy_tianyu: ["male", "wei", 4, ["chezhen", "youzhan"]], - ns_zuoci:['male','qun',3,['nsxinsheng','nsdunxing']], - ns_lvzhi:['female','qun',3,['nsnongquan','nsdufu']], - ns_wangyun:["male","qun",4,["liangji","jugong","chengmou"]], - ns_nanhua:["male","qun",3,["nshuanxian","nstaiping_nh","nsshoudao"]], - ns_nanhua_left:["male","qun",2,[],['unseen']], - ns_nanhua_right:["female","qun",2,[],['unseen']], - ns_huamulan:['female','qun',3,['nscongjun','xiaoji','gongji']], - ns_huangzu:['male','qun',4,['nsjihui','nsmouyun']], - ns_jinke:['male','qun',4,['nspinmin','nsshishou']], - ns_yanliang:['male','qun',4,['nsduijue','nsshuangxiong','dualside'],['dualside:ns_wenchou']], - ns_wenchou:['male','qun',2,['nsguanyong','dualside'],['unseen']], + ns_zuoci: ["male", "qun", 3, ["nsxinsheng", "nsdunxing"]], + ns_lvzhi: ["female", "qun", 3, ["nsnongquan", "nsdufu"]], + ns_wangyun: ["male", "qun", 4, ["liangji", "jugong", "chengmou"]], + ns_nanhua: ["male", "qun", 3, ["nshuanxian", "nstaiping_nh", "nsshoudao"]], + ns_nanhua_left: ["male", "qun", 2, [], ["unseen"]], + ns_nanhua_right: ["female", "qun", 2, [], ["unseen"]], + ns_huamulan: ["female", "qun", 3, ["nscongjun", "xiaoji", "gongji"]], + ns_huangzu: ["male", "qun", 4, ["nsjihui", "nsmouyun"]], + ns_jinke: ["male", "qun", 4, ["nspinmin", "nsshishou"]], + ns_yanliang: [ + "male", + "qun", + 4, + ["nsduijue", "nsshuangxiong", "dualside"], + ["dualside:ns_wenchou"], + ], + ns_wenchou: ["male", "qun", 2, ["nsguanyong", "dualside"], ["unseen"]], - ns_caocao:['male','wei',4,['nscaiyi','nsgefa','nshaoling']], - ns_caocaosp:['male','qun',3,['nsjianxiong','nsxionglue']], - ns_zhugeliang:['male','shu',3,['nsguanxing','kongcheng','nsyunxing']], - ns_wangyue:['male','qun',4,['nsjianshu','nscangjian']], - ns_yuji:['male','qun',3,['nsyaowang','nshuanhuo']], - ns_xinxianying:['female','wei',3,['nsdongcha','nscaijian','nsgongjian']], - ns_guanlu:['male','wei',3,['nsbugua','nstuiyan','nstianji']], - ns_simazhao:['male','wei',3,['nszhaoxin','nsxiuxin','nsshijun']], - ns_sunjian:['male','wu',4,['nswulie','nshunyou','nscangxi']], + ns_caocao: ["male", "wei", 4, ["nscaiyi", "nsgefa", "nshaoling"]], + ns_caocaosp: ["male", "qun", 3, ["nsjianxiong", "nsxionglue"]], + ns_zhugeliang: ["male", "shu", 3, ["nsguanxing", "kongcheng", "nsyunxing"]], + ns_wangyue: ["male", "qun", 4, ["nsjianshu", "nscangjian"]], + ns_yuji: ["male", "qun", 3, ["nsyaowang", "nshuanhuo"]], + ns_xinxianying: ["female", "wei", 3, ["nsdongcha", "nscaijian", "nsgongjian"]], + ns_guanlu: ["male", "wei", 3, ["nsbugua", "nstuiyan", "nstianji"]], + ns_simazhao: ["male", "wei", 3, ["nszhaoxin", "nsxiuxin", "nsshijun"]], + ns_sunjian: ["male", "wu", 4, ["nswulie", "nshunyou", "nscangxi"]], - ns_duangui:['male','qun',3,['nscuanquan','nsjianning','nschangshi','nsbaquan']], - ns_zhangbao:['male','qun',3,['nsfuhuo','nswangfeng']], - ns_masu:['male','shu',3,['nstanbing','nsxinzhan']], - ns_zhangxiu:['male','qun',4,['nsbaiming','nsfuge']], - ns_lvmeng:['male','wu',3,['nsqinxue','nsbaiyi']], - ns_shenpei:['male','qun',3,['nshunji','shibei']], + ns_duangui: ["male", "qun", 3, ["nscuanquan", "nsjianning", "nschangshi", "nsbaquan"]], + ns_zhangbao: ["male", "qun", 3, ["nsfuhuo", "nswangfeng"]], + ns_masu: ["male", "shu", 3, ["nstanbing", "nsxinzhan"]], + ns_zhangxiu: ["male", "qun", 4, ["nsbaiming", "nsfuge"]], + ns_lvmeng: ["male", "wu", 3, ["nsqinxue", "nsbaiyi"]], + ns_shenpei: ["male", "qun", 3, ["nshunji", "shibei"]], - ns_yujisp:['male','qun',3,['nsguhuo']], - ns_yangyi:['male','shu',3,['nsjuanli','nsyuanchou']], - ns_liuzhang:['male','qun',3,['nsanruo','nsxunshan','nskaicheng']], + ns_yujisp: ["male", "qun", 3, ["nsguhuo"]], + ns_yangyi: ["male", "shu", 3, ["nsjuanli", "nsyuanchou"]], + ns_liuzhang: ["male", "qun", 3, ["nsanruo", "nsxunshan", "nskaicheng"]], // ns_zhaoyun:['male','qun',3,[]], // ns_lvmeng:['male','qun',3,[]], // ns_zhaoyunshen:['male','qun',3,[]], // ns_lisu:['male','qun',3,[]], // ns_sunhao:['male','qun',3,[]], - ns_xinnanhua:['male','qun',3,['ns_xiandao','ns_xiuzheng','ns_chuanshu']], - ns_caimao:['male','qun',4,['nsdingzhou']], - ns_luyusheng:['female','wu',3,['nshuaishuang','nsfengli']], - 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"]], - ns_mengyou:['male','qun',4,['nsmanzhi']], + ns_xinnanhua: ["male", "qun", 3, ["ns_xiandao", "ns_xiuzheng", "ns_chuanshu"]], + ns_caimao: ["male", "qun", 4, ["nsdingzhou"]], + ns_luyusheng: ["female", "wu", 3, ["nshuaishuang", "nsfengli"]], + 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"]], + ns_mengyou: ["male", "qun", 4, ["nsmanzhi"]], - old_jiakui:['male','wei',4,['tongqu','xinwanlan']], - ol_guohuai:['male','wei',3,['rejingce']], - junk_zhangrang:['male','qun',3,['junktaoluan'],['sex:male_castrated']], - old_bulianshi:['female','wu',3,['anxu','zhuiyi']], - ol_maliang:['male','shu',3,['zishu','xinyingyuan']], - junk_liubei:['male','shu',4,['junkrende','jijiang'],['zhu']], - junk_huangyueying:['female','shu',3,['junkjizhi','junkqicai']], - junk_lidian:['male','wei',3,['xunxun','junkwangxi']], - junk_duanwei:['male','qun',4,['junklangmie']], - junk_xuyou:["male","qun",3,["nzry_chenglve","junkshicai","nzry_cunmu"]], - junk_zhangjiao:['male','shen',3,['yizhao','junksijun','tianjie'],['qun','die_audio:shen_zhangjiao']], - junk_guanyu:['male','shu',4,['olsbfumeng','olsbguidao']], + old_jiakui: ["male", "wei", 4, ["tongqu", "xinwanlan"]], + ol_guohuai: ["male", "wei", 3, ["rejingce"]], + junk_zhangrang: ["male", "qun", 3, ["junktaoluan"], ["sex:male_castrated"]], + old_bulianshi: ["female", "wu", 3, ["anxu", "zhuiyi"]], + ol_maliang: ["male", "shu", 3, ["zishu", "xinyingyuan"]], + junk_liubei: ["male", "shu", 4, ["junkrende", "jijiang"], ["zhu"]], + junk_huangyueying: ["female", "shu", 3, ["junkjizhi", "junkqicai"]], + junk_lidian: ["male", "wei", 3, ["xunxun", "junkwangxi"]], + junk_duanwei: ["male", "qun", 4, ["junklangmie"]], + junk_xuyou: ["male", "qun", 3, ["nzry_chenglve", "junkshicai", "nzry_cunmu"]], + junk_zhangjiao: [ + "male", + "shen", + 3, + ["yizhao", "junksijun", "tianjie"], + ["qun", "die_audio:shen_zhangjiao"], + ], + junk_guanyu: ["male", "shu", 4, ["olsbfumeng", "olsbguidao"]], }, - characterFilter:{ - key_jojiro(mode){ - return mode=='chess'||mode=='tafang'; + characterFilter: { + key_jojiro(mode) { + return mode == "chess" || mode == "tafang"; }, - key_yuu(mode){ - return mode=='identity'||mode=='doudizhu'||mode=='single'||(mode=='versus'&&_status.mode!='standard'&&_status.mode!='three'); + key_yuu(mode) { + return ( + mode == "identity" || + mode == "doudizhu" || + mode == "single" || + (mode == "versus" && _status.mode != "standard" && _status.mode != "three") + ); }, - key_tomoya(mode){ - return mode!='chess'&&mode!='tafang'&&mode!='stone'; + key_tomoya(mode) { + return mode != "chess" && mode != "tafang" && mode != "stone"; }, - key_sunohara(mode){ - return mode!='guozhan'; + key_sunohara(mode) { + return mode != "guozhan"; }, - ns_duangui(mode){ - return mode=='identity'&&_status.mode=='normal'; + ns_duangui(mode) { + return mode == "identity" && _status.mode == "normal"; }, - diy_liuyan(mode){ - return mode!='chess'&&mode!='tafang'; - } - }, - characterSort:{ - diy:{ - diy_yijiang:["key_kud","key_misuzu","key_kamome","key_nao", - "ns_huangchengyan","ns_sunchensunjun","ns_yuanxi","ns_caoshuang"], - diy_yijiang2:["key_yuuki","key_tenzen","key_kyouko","key_kotarou","key_kyou", - "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','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'], - diy_key:["key_lucia","key_kyousuke","key_yuri","key_haruko","key_umi","key_rei","key_komari","key_yukine","key_yusa","key_misa","key_masato","key_iwasawa","key_kengo","key_yoshino","key_yui","key_tsumugi","key_saya","key_harukakanata","key_inari","key_shiina","key_sunohara","key_rin","key_sasami","key_akane","key_doruji","key_yuiko","key_riki","key_hisako","key_hinata","key_noda","key_tomoya","key_nagisa","key_ayato","key_ao","key_yuzuru","sp_key_kanade","key_mio","key_midori","key_kyoko","key_shizuru","key_shiorimiyuki","key_miki","key_shiori","key_kaori","sp_key_yuri","key_akiko","key_abyusa","key_godan","key_yuu","key_ryoichi","key_kotori","key_jojiro","key_shiroha","key_shizuku","key_hiroto","key_sakuya","key_youta","key_rumi","key_chihaya","key_yukito","key_asara","key_kotomi","key_mia","key_kano","db_key_liyingxia","key_erika","key_satomi","key_iriya","key_fuuko"], - diy_trashbin:['junk_guanyu','junk_zhangjiao','old_jiakui','ol_guohuai','junk_zhangrang','old_bulianshi','ol_maliang','junk_liubei','junk_huangyueying','junk_lidian','junk_duanwei','junk_xuyou'], + diy_liuyan(mode) { + return mode != "chess" && mode != "tafang"; }, }, - characterIntro:{ - noname:'无名杀的吉祥物。
              画师:空城
              技能设计:李木子', - diy_hanlong:'韩龙,魏国刺客。他孤身一人深入到了长城外的敌人领地,成功刺杀了敌方首领轲比能,瓦解了鲜卑民族,曹魏边境因此获得了几十年的安稳。', - ns_zhangwei:'血骑教习·张葳,三国杀集换式卡牌游戏《阵面对决》中的帝畿系列卡牌。游卡桌游官方原创的三国时期女性角色。', - diy_feishi:'字公举,生卒年不详,益州犍为郡南安县(今四川省乐山市)人。刘璋占据益州时,以费诗为绵竹县县令。刘备进攻刘璋夺取益州,费诗举城而降,后受拜督军从事,转任牂牁郡太守,再为州前部司马。', - diy_lukang:'字幼节,吴郡吴县(今江苏苏州)人。三国时期吴国名将,丞相陆逊次子。', - diy_liufu:'字元颖,沛国相县(今安徽濉溪县西北)人。东汉末年名守。在汉末避难于淮南,说服袁术将戚寄和秦翊率部投奔曹操,曹操大悦,使司徒辟其为掾属。', - diy_xizhenxihong:'习珍,襄阳人。三国时蜀汉将领。先主刘备时曾任零陵北部都尉,加裨将军。建安二十四年,关羽率荆州大军攻打樊城,唯有习珍据城不降。被困月余,直到箭尽粮绝,拔剑自刎而死。习宏,生卒年不详,习珍之弟。曾在东吴入侵蜀汉时建议哥哥习珍伪降,约樊胄举兵。习珍死后,弟弟习宏落在东吴,有问必不答,终身不为孙权发一言。', - diy_zaozhirenjun:'枣祗,生卒年月不详,东汉末年颍川阳翟(今河南省禹州市)人。曾任东阿令、羽林监、屯田都尉、陈留太守等职。任峻(?—204年),字伯达,河南郡中牟县人。曹操每次出征,任峻通常在后方补给军队。后来发生饥荒,枣祗建议实施屯田,任峻被任命为典农中郎将,招募百姓在许下屯田,结果连年丰收,积谷足以装满全部粮仓。', - diy_yangyi:'字威公,襄阳(今湖北襄阳)人,三国时期蜀汉政治家。最初,为荆州刺史傅群的主簿,后投奔关羽,任为功曹。羽遣其至成都,大受刘备赞赏,擢为尚书。建兴三年(225年)任丞相参军,此后一直跟随诸葛亮战斗。亮卒,他部署安全退军。亮生前定蒋琬继己任,仪仅拜中军师。建兴十三年(235年),因多出怨言,被削职流放至汉嘉郡。但杨仪仍不自省,又上书诽谤,言辞激烈,最后下狱,自杀身亡。', - diy_tianyu:'字国让,渔阳雍奴(今天津市武清区东北)人。三国时期曹魏将领。初从刘备,因母亲年老回乡,后跟随公孙瓒,公孙瓒败亡,劝说鲜于辅加入曹操。曹操攻略河北时,田豫正式得到曹操任用,历任颖阴、郎陵令、弋阳太守等。', - chentai:'陈泰(200年~260年),字玄伯,颍川许昌(今河南省许昌市)人。三国时期魏国名将,司空陈群之子。陈泰早年起家员外散骑侍郎,其父陈群死后袭封颍阴侯,历任游击将军、并州、雍州刺史、尚书等职,高平陵政变发生时,陈泰力劝大将军曹爽投降,因此得到掌权的司马氏信任,此后为了回避朝廷的争斗,陈泰主动请求外调雍州任职,任内成功防御蜀将姜维的多次进攻。甘露元年(256年),陈泰被调回朝中任尚书右仆射,曾随司马昭两度抵抗东吴的进攻,后改任左仆射。甘露五年(260年),魏帝曹髦被弑杀,陈泰闻讯后悲痛过度,呕血而死,享年六十一岁。追赠司空,赐谥为穆。', - huangwudie:'黄舞蝶是在现代三国作品中出场的虚拟人物,设定为蜀汉大将黄忠之女,跟随父亲一同投效刘备,在游戏中是一名不错的女将。', - sunyi:'孙翊(184年~204年),又名孙俨,字叔弼,是孙坚的第三子,孙策、孙权的弟弟。曾被大臣推荐为继承者。孙权继位后,孙翊任丹杨太守,后被身边的人边鸿刺杀。', - zhangning:'《三国杀·阵面对决》中登场的角色。张角之女,能呼雷掣电。', - yanghu:'羊祜(221年-278年12月27日),字叔子,泰山郡南城县人。西晋时期杰出的战略家、政治家、文学家,曹魏上党太守羊衜的儿子,名儒蔡邕的女儿蔡文姬的外甥。出身“泰山羊氏”,博学能文,清廉正直。曹魏时期,接受公车征辟,出任中书郎,迁给事黄门侍郎。姐姐嫁给大将军司马师,投靠司马氏家族,仕途平步青云。魏元帝曹奂即位,出任秘书监、相国从事中郎、中领军,统领御林军,兼管内外政事,册封钜平县子,迁。西晋建立后,迁中军将军、散骑常侍、郎中令,册封钜平侯。泰始五年(269年),出任车骑将军、荆州都督,加任开府仪同三司坐镇襄阳,屯田兴学,以德怀柔,深得军民之心;扩充军备,训练士兵,全力准备灭亡孙吴,累迁征南大将军,册封南城侯。咸宁四年,去世,临终前举荐杜预接任职务,获赠侍中、太傅,谥号为“成”。唐宋时期,配享武庙。', - ns_wangyue:'王越,东汉末年游侠(生卒年不详),乃辽东燕山人士,擅使剑术, 三国时期史阿的师父,曹丕的师公,官职虎贲将军。在史书《典论》中略有记载。', + characterSort: { + diy: { + diy_yijiang: [ + "key_kud", + "key_misuzu", + "key_kamome", + "key_nao", + "ns_huangchengyan", + "ns_sunchensunjun", + "ns_yuanxi", + "ns_caoshuang", + ], + diy_yijiang2: [ + "key_yuuki", + "key_tenzen", + "key_kyouko", + "key_kotarou", + "key_kyou", + "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", + "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"], + diy_key: [ + "key_lucia", + "key_kyousuke", + "key_yuri", + "key_haruko", + "key_umi", + "key_rei", + "key_komari", + "key_yukine", + "key_yusa", + "key_misa", + "key_masato", + "key_iwasawa", + "key_kengo", + "key_yoshino", + "key_yui", + "key_tsumugi", + "key_saya", + "key_harukakanata", + "key_inari", + "key_shiina", + "key_sunohara", + "key_rin", + "key_sasami", + "key_akane", + "key_doruji", + "key_yuiko", + "key_riki", + "key_hisako", + "key_hinata", + "key_noda", + "key_tomoya", + "key_nagisa", + "key_ayato", + "key_ao", + "key_yuzuru", + "sp_key_kanade", + "key_mio", + "key_midori", + "key_kyoko", + "key_shizuru", + "key_shiorimiyuki", + "key_miki", + "key_shiori", + "key_kaori", + "sp_key_yuri", + "key_akiko", + "key_abyusa", + "key_godan", + "key_yuu", + "key_ryoichi", + "key_kotori", + "key_jojiro", + "key_shiroha", + "key_shizuku", + "key_hiroto", + "key_sakuya", + "key_youta", + "key_rumi", + "key_chihaya", + "key_yukito", + "key_asara", + "key_kotomi", + "key_mia", + "key_kano", + "db_key_liyingxia", + "key_erika", + "key_satomi", + "key_iriya", + "key_fuuko", + ], + diy_trashbin: [ + "junk_guanyu", + "junk_zhangjiao", + "old_jiakui", + "ol_guohuai", + "junk_zhangrang", + "old_bulianshi", + "ol_maliang", + "junk_liubei", + "junk_huangyueying", + "junk_lidian", + "junk_duanwei", + "junk_xuyou", + ], + }, }, - characterTitle:{ - key_satomi:'#rHeaven Burns Red', - key_erika:'#rHeaven Burns Red', - db_key_liyingxia:'#rHeaven Burns Red', - key_kano:'#bAIR', - key_mia:'#bLoopers', - key_kotomi:'#gClannad', - key_asara:'#bRewrite', - key_yukito:'#bAIR', - key_chihaya:'#bRewrite', - key_rumi:'#rONE ~輝く季節へ~', - key_youta:'#b神様になった日', - key_sakuya:'#bRewrite', - key_hiroto:'#b神様になった日', - key_shizuku:'#bSummer Pockets', - key_shiroha:'#bSummer Pockets', - key_jojiro:'#bCharlotte
              战棋专属角色', - key_kotori:'#bRewrite', - key_ryoichi:'#bSummer Pockets', - key_yuu:'#bCharlotte', - key_godan:'#rAngel Beats!', - key_abyusa:'#rAngel Beats!', - key_akiko:'#bKanon', - key_kaori:'#bKanon', - key_shiori:'#bKanon', - key_miki:'#bSummer Pockets', - key_shiorimiyuki:'#rAngel Beats!', - key_shizuru:'#bRewrite', - key_kyoko:'#bSummer Pockets', - sp_key_kanade:'#rAngel Beats!', - key_yuzuru:'#rAngel Beats!', - key_tsumugi:'#bSummer Pockets', - key_ayato:'#rAngel Beats!', - key_nagisa:'#gClannad', - key_tomoya:'#gClannad', - key_noda:'#rAngel Beats!', - key_hinata:'#rAngel Beats!', - key_hisako:'#rAngel Beats!', - key_doruji:'#bLittle Busters!', - key_riki:'#bLittle Busters!', - key_yuiko:'#bLittle Busters!', - key_akane:'#bRewrite', - key_sasami:'#bLittle Busters!', - key_rin:'#bLittle Busters!', - key_shiina:'#rAngel Beats!', - key_inari:'#bSummer Pockets', - key_saya:'#bLittle Busters!', - key_harukakanata:'#bLittle Busters!', - key_yui:'#rAngel Beats!', - key_yoshino:'#bRewrite', - key_kengo:'#bLittle Busters!', - key_iwasawa:'#rAngel Beats!', - key_masato:'#bLittle Busters!', - key_yusa:'#bCharlotte', - key_misa:'#rCharlotte', - key_yukine:'#gClannad', - key_komari:'#bLittle Busters!', - key_umi:'#bSummer Pockets', - key_rei:'#gHarmonia', - key_lucia:'#bRewrite', - key_kyousuke:'#bLittle Busters!', - key_yuri:'#rAngel Beats!', - key_haruko:'#bAIR', - sp_key_yuri:'#bAngel Beats!', - key_fuuko:'#gClannad', + characterIntro: { + noname: "无名杀的吉祥物。
              画师:空城
              技能设计:李木子", + diy_hanlong: + "韩龙,魏国刺客。他孤身一人深入到了长城外的敌人领地,成功刺杀了敌方首领轲比能,瓦解了鲜卑民族,曹魏边境因此获得了几十年的安稳。", + ns_zhangwei: + "血骑教习·张葳,三国杀集换式卡牌游戏《阵面对决》中的帝畿系列卡牌。游卡桌游官方原创的三国时期女性角色。", + diy_feishi: + "字公举,生卒年不详,益州犍为郡南安县(今四川省乐山市)人。刘璋占据益州时,以费诗为绵竹县县令。刘备进攻刘璋夺取益州,费诗举城而降,后受拜督军从事,转任牂牁郡太守,再为州前部司马。", + diy_lukang: "字幼节,吴郡吴县(今江苏苏州)人。三国时期吴国名将,丞相陆逊次子。", + diy_liufu: + "字元颖,沛国相县(今安徽濉溪县西北)人。东汉末年名守。在汉末避难于淮南,说服袁术将戚寄和秦翊率部投奔曹操,曹操大悦,使司徒辟其为掾属。", + diy_xizhenxihong: + "习珍,襄阳人。三国时蜀汉将领。先主刘备时曾任零陵北部都尉,加裨将军。建安二十四年,关羽率荆州大军攻打樊城,唯有习珍据城不降。被困月余,直到箭尽粮绝,拔剑自刎而死。习宏,生卒年不详,习珍之弟。曾在东吴入侵蜀汉时建议哥哥习珍伪降,约樊胄举兵。习珍死后,弟弟习宏落在东吴,有问必不答,终身不为孙权发一言。", + diy_zaozhirenjun: + "枣祗,生卒年月不详,东汉末年颍川阳翟(今河南省禹州市)人。曾任东阿令、羽林监、屯田都尉、陈留太守等职。任峻(?—204年),字伯达,河南郡中牟县人。曹操每次出征,任峻通常在后方补给军队。后来发生饥荒,枣祗建议实施屯田,任峻被任命为典农中郎将,招募百姓在许下屯田,结果连年丰收,积谷足以装满全部粮仓。", + diy_yangyi: + "字威公,襄阳(今湖北襄阳)人,三国时期蜀汉政治家。最初,为荆州刺史傅群的主簿,后投奔关羽,任为功曹。羽遣其至成都,大受刘备赞赏,擢为尚书。建兴三年(225年)任丞相参军,此后一直跟随诸葛亮战斗。亮卒,他部署安全退军。亮生前定蒋琬继己任,仪仅拜中军师。建兴十三年(235年),因多出怨言,被削职流放至汉嘉郡。但杨仪仍不自省,又上书诽谤,言辞激烈,最后下狱,自杀身亡。", + diy_tianyu: + "字国让,渔阳雍奴(今天津市武清区东北)人。三国时期曹魏将领。初从刘备,因母亲年老回乡,后跟随公孙瓒,公孙瓒败亡,劝说鲜于辅加入曹操。曹操攻略河北时,田豫正式得到曹操任用,历任颖阴、郎陵令、弋阳太守等。", + chentai: + "陈泰(200年~260年),字玄伯,颍川许昌(今河南省许昌市)人。三国时期魏国名将,司空陈群之子。陈泰早年起家员外散骑侍郎,其父陈群死后袭封颍阴侯,历任游击将军、并州、雍州刺史、尚书等职,高平陵政变发生时,陈泰力劝大将军曹爽投降,因此得到掌权的司马氏信任,此后为了回避朝廷的争斗,陈泰主动请求外调雍州任职,任内成功防御蜀将姜维的多次进攻。甘露元年(256年),陈泰被调回朝中任尚书右仆射,曾随司马昭两度抵抗东吴的进攻,后改任左仆射。甘露五年(260年),魏帝曹髦被弑杀,陈泰闻讯后悲痛过度,呕血而死,享年六十一岁。追赠司空,赐谥为穆。", + huangwudie: + "黄舞蝶是在现代三国作品中出场的虚拟人物,设定为蜀汉大将黄忠之女,跟随父亲一同投效刘备,在游戏中是一名不错的女将。", + sunyi: "孙翊(184年~204年),又名孙俨,字叔弼,是孙坚的第三子,孙策、孙权的弟弟。曾被大臣推荐为继承者。孙权继位后,孙翊任丹杨太守,后被身边的人边鸿刺杀。", + zhangning: "《三国杀·阵面对决》中登场的角色。张角之女,能呼雷掣电。", + yanghu: "羊祜(221年-278年12月27日),字叔子,泰山郡南城县人。西晋时期杰出的战略家、政治家、文学家,曹魏上党太守羊衜的儿子,名儒蔡邕的女儿蔡文姬的外甥。出身“泰山羊氏”,博学能文,清廉正直。曹魏时期,接受公车征辟,出任中书郎,迁给事黄门侍郎。姐姐嫁给大将军司马师,投靠司马氏家族,仕途平步青云。魏元帝曹奂即位,出任秘书监、相国从事中郎、中领军,统领御林军,兼管内外政事,册封钜平县子,迁。西晋建立后,迁中军将军、散骑常侍、郎中令,册封钜平侯。泰始五年(269年),出任车骑将军、荆州都督,加任开府仪同三司坐镇襄阳,屯田兴学,以德怀柔,深得军民之心;扩充军备,训练士兵,全力准备灭亡孙吴,累迁征南大将军,册封南城侯。咸宁四年,去世,临终前举荐杜预接任职务,获赠侍中、太傅,谥号为“成”。唐宋时期,配享武庙。", + ns_wangyue: + "王越,东汉末年游侠(生卒年不详),乃辽东燕山人士,擅使剑术, 三国时期史阿的师父,曹丕的师公,官职虎贲将军。在史书《典论》中略有记载。", + }, + characterTitle: { + key_satomi: "#rHeaven Burns Red", + key_erika: "#rHeaven Burns Red", + db_key_liyingxia: "#rHeaven Burns Red", + key_kano: "#bAIR", + key_mia: "#bLoopers", + key_kotomi: "#gClannad", + key_asara: "#bRewrite", + key_yukito: "#bAIR", + key_chihaya: "#bRewrite", + key_rumi: "#rONE ~輝く季節へ~", + key_youta: "#b神様になった日", + key_sakuya: "#bRewrite", + key_hiroto: "#b神様になった日", + key_shizuku: "#bSummer Pockets", + key_shiroha: "#bSummer Pockets", + key_jojiro: "#bCharlotte
              战棋专属角色", + key_kotori: "#bRewrite", + key_ryoichi: "#bSummer Pockets", + key_yuu: "#bCharlotte", + key_godan: "#rAngel Beats!", + key_abyusa: "#rAngel Beats!", + key_akiko: "#bKanon", + key_kaori: "#bKanon", + key_shiori: "#bKanon", + key_miki: "#bSummer Pockets", + key_shiorimiyuki: "#rAngel Beats!", + key_shizuru: "#bRewrite", + key_kyoko: "#bSummer Pockets", + sp_key_kanade: "#rAngel Beats!", + key_yuzuru: "#rAngel Beats!", + key_tsumugi: "#bSummer Pockets", + key_ayato: "#rAngel Beats!", + key_nagisa: "#gClannad", + key_tomoya: "#gClannad", + key_noda: "#rAngel Beats!", + key_hinata: "#rAngel Beats!", + key_hisako: "#rAngel Beats!", + key_doruji: "#bLittle Busters!", + key_riki: "#bLittle Busters!", + key_yuiko: "#bLittle Busters!", + key_akane: "#bRewrite", + key_sasami: "#bLittle Busters!", + key_rin: "#bLittle Busters!", + key_shiina: "#rAngel Beats!", + key_inari: "#bSummer Pockets", + key_saya: "#bLittle Busters!", + key_harukakanata: "#bLittle Busters!", + key_yui: "#rAngel Beats!", + key_yoshino: "#bRewrite", + key_kengo: "#bLittle Busters!", + key_iwasawa: "#rAngel Beats!", + key_masato: "#bLittle Busters!", + key_yusa: "#bCharlotte", + key_misa: "#rCharlotte", + key_yukine: "#gClannad", + key_komari: "#bLittle Busters!", + key_umi: "#bSummer Pockets", + key_rei: "#gHarmonia", + key_lucia: "#bRewrite", + key_kyousuke: "#bLittle Busters!", + key_yuri: "#rAngel Beats!", + key_haruko: "#bAIR", + sp_key_yuri: "#bAngel Beats!", + key_fuuko: "#gClannad", - key_kud:'#b千夜', - key_misuzu:'#b长发及腰黑长直', - key_kamome:'#b仿生纱', - key_nao:'#b潮鸣', - key_kyou:'#b长发及腰黑长直', - key_yuuki:'#b4399司命', - key_kyouko:'#b阿阿阿687', - key_tenzen:'#b皋耳击', - key_kotarou:'#bb1154486224', - key_seira:'#b阿开木木W🍀', - key_kiyu:'#b无面◎隐者', - key_tomoyo:'#b长发及腰黑长直', - key_minagi:'#b无面◎隐者', + key_kud: "#b千夜", + key_misuzu: "#b长发及腰黑长直", + key_kamome: "#b仿生纱", + key_nao: "#b潮鸣", + key_kyou: "#b长发及腰黑长直", + key_yuuki: "#b4399司命", + key_kyouko: "#b阿阿阿687", + key_tenzen: "#b皋耳击", + key_kotarou: "#bb1154486224", + key_seira: "#b阿开木木W🍀", + key_kiyu: "#b无面◎隐者", + key_tomoyo: "#b长发及腰黑长直", + key_minagi: "#b无面◎隐者", - ns_huangchengyan:'#g竹邀月', - ns_sunchensunjun:'#gVenusjeu', - ns_yuanxi:'#g食茸二十四', - ns_caoshuang:'#g荬庀芬兰', - ns_chentai:'#g荀彧III荀文若', - ns_huangwudie:'#g你爸爸来了164', - ns_sunyi:'#g无民氏4251', - ns_zhangning:'#g如颍隋行1314', - ns_yanghu:'#ginCenv', - ns_ruanji:'#g伯约的崛起', - ns_zanghong:'#g阿七', - ns_limi:'#g-心若困兽-', - ns_zhonglimu:'#gJG赛文♠7', - prp_zhugeliang:'#g阿开木木W🍀', + ns_huangchengyan: "#g竹邀月", + ns_sunchensunjun: "#gVenusjeu", + ns_yuanxi: "#g食茸二十四", + ns_caoshuang: "#g荬庀芬兰", + ns_chentai: "#g荀彧III荀文若", + ns_huangwudie: "#g你爸爸来了164", + ns_sunyi: "#g无民氏4251", + ns_zhangning: "#g如颍隋行1314", + ns_yanghu: "#ginCenv", + ns_ruanji: "#g伯约的崛起", + ns_zanghong: "#g阿七", + ns_limi: "#g-心若困兽-", + ns_zhonglimu: "#gJG赛文♠7", + prp_zhugeliang: "#g阿开木木W🍀", - ns_luyusheng:'#g猫咪大院 - 魚と水', - ns_caimao:'#gP尔号玩家◆', - diy_wenyang:'#g最粗的梦想XD', - ns_zuoci:'#bskystarwuwei', - ns_lvzhi:'#bskystarwuwei', - ns_wangyun:'#rSukincen', - ns_guanlu:'#rSukincen', - ns_xinnanhua:'#rSukincen', - ns_nanhua:'#g戒除联盟', - ns_shenpei:'#g戒除联盟', - ns_huamulan:'#p哎别管我是谁', - ns_jinke:'#p哎别管我是谁', - ns_huangzu:'#r小芯儿童鞋', - ns_lisu:'#r小芯儿童鞋', - ns_yanliang:'#r丶橙续缘', - ns_wenchou:'#r丶橙续缘', - ns_caocao:'#r一瞬间丶遗忘', - ns_caocaosp:'#g希望教主', - ns_zhugeliang:'#p死不死什么的', - ns_xinxianying:'#b扶苏公子', - ns_zhangbao:'#b扶苏公子', - ns_wangyue:'#p废城君', - ns_sunjian:'#b兔子两只2', - ns_lvmeng:'#b兔子两只2', - ns_yujisp:'#b兔子两只2', - ns_yuji:'#g蔚屿凉音', - ns_simazhao:'#r一纸载春秋', - ns_duangui:'#b宝宝酱紫萌萌哒', - ns_masu:'#g修女', - ns_zhangxiu:'#p本因坊神策', - ns_yangyi:'#p本因坊神策', - ns_liuzhang:'#r矮子剑薄荷糖', - ns_mengyou:'#g残昼厄夜', + ns_luyusheng: "#g猫咪大院 - 魚と水", + ns_caimao: "#gP尔号玩家◆", + diy_wenyang: "#g最粗的梦想XD", + ns_zuoci: "#bskystarwuwei", + ns_lvzhi: "#bskystarwuwei", + ns_wangyun: "#rSukincen", + ns_guanlu: "#rSukincen", + ns_xinnanhua: "#rSukincen", + ns_nanhua: "#g戒除联盟", + ns_shenpei: "#g戒除联盟", + ns_huamulan: "#p哎别管我是谁", + ns_jinke: "#p哎别管我是谁", + ns_huangzu: "#r小芯儿童鞋", + ns_lisu: "#r小芯儿童鞋", + ns_yanliang: "#r丶橙续缘", + ns_wenchou: "#r丶橙续缘", + ns_caocao: "#r一瞬间丶遗忘", + ns_caocaosp: "#g希望教主", + ns_zhugeliang: "#p死不死什么的", + ns_xinxianying: "#b扶苏公子", + ns_zhangbao: "#b扶苏公子", + ns_wangyue: "#p废城君", + ns_sunjian: "#b兔子两只2", + ns_lvmeng: "#b兔子两只2", + ns_yujisp: "#b兔子两只2", + ns_yuji: "#g蔚屿凉音", + ns_simazhao: "#r一纸载春秋", + ns_duangui: "#b宝宝酱紫萌萌哒", + ns_masu: "#g修女", + ns_zhangxiu: "#p本因坊神策", + ns_yangyi: "#p本因坊神策", + ns_liuzhang: "#r矮子剑薄荷糖", + ns_mengyou: "#g残昼厄夜", }, - card:{ - kano_paibingbuzhen:{ - fullskin:true, - type:'trick', - enable:true, - filterTarget:true, - selectTarget:[1,3], - derivation:'key_kano', - content(){ - 'step 0' + card: { + kano_paibingbuzhen: { + fullskin: true, + type: "trick", + enable: true, + filterTarget: true, + selectTarget: [1, 3], + derivation: "key_kano", + content() { + "step 0"; target.draw(); - 'step 1' - var hs=target.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length==1) event._result={bool:true,cards:hs}; - else target.chooseCard('he',true,'选择一张牌置入仁库'); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - target.$throw(card,1000); - target.lose(card,'toRenku'); + "step 1"; + var hs = target.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length == 1) event._result = { bool: true, cards: hs }; + else target.chooseCard("he", true, "选择一张牌置入仁库"); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + target.$throw(card, 1000); + target.lose(card, "toRenku"); } }, - contentAfter(){ - if(player.isIn()&&_status.renku.length&&function(){ - var cards=_status.renku; - if(cards.length==1) return true; - var color=get.color(cards[0],false),type=get.type(cards[0],false); - for(var i=1;i{ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: (event) => { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - 'step 0' + content() { + "step 0"; player.drawTo(8); - 'step 1' - var hs=player.getCards('h'); - if(hs.length>0) player.addShownCards(hs,'visible_fuuko_xingdiao'); + "step 1"; + var hs = player.getCards("h"); + if (hs.length > 0) player.addShownCards(hs, "visible_fuuko_xingdiao"); }, - mod:{ - ignoredHandcard(card){ - if(card.hasGaintag('visible_fuuko_xingdiao')){ + mod: { + ignoredHandcard(card) { + if (card.hasGaintag("visible_fuuko_xingdiao")) { return true; } }, - cardDiscardable(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('visible_fuuko_xingdiao')){ + cardDiscardable(card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("visible_fuuko_xingdiao")) { return false; } }, }, - onremove:true, - global:'fuuko_xingdiao_gain', - subSkill:{ - gain:{ - enable:'phaseUse', - filter:(event,player)=>{ - return game.hasPlayer(current=>lib.skill.fuuko_xingdiao_gain.filterTarget(null,player,current)); + onremove: true, + global: "fuuko_xingdiao_gain", + subSkill: { + gain: { + enable: "phaseUse", + filter: (event, player) => { + return game.hasPlayer((current) => + lib.skill.fuuko_xingdiao_gain.filterTarget(null, player, current) + ); }, - filterTarget:(card,player,target)=>{ - return target!=player&&target.hasCard(card=>card.hasGaintag('visible_fuuko_xingdiao'),'h') - &&!target.getStorage('fuuko_xingdiao').includes(player)&&target.hasSkill('fuuko_xingdiao'); + filterTarget: (card, player, target) => { + return ( + target != player && + target.hasCard((card) => card.hasGaintag("visible_fuuko_xingdiao"), "h") && + !target.getStorage("fuuko_xingdiao").includes(player) && + target.hasSkill("fuuko_xingdiao") + ); }, - selectTarget:()=>{ - const num=game.countPlayer(current=>lib.skill.fuuko_xingdiao_gain.filterTarget(null,_status.event.player,current)); - return num>1?1:-1; + selectTarget: () => { + const num = game.countPlayer((current) => + lib.skill.fuuko_xingdiao_gain.filterTarget( + null, + _status.event.player, + current + ) + ); + return num > 1 ? 1 : -1; }, - content(){ - 'step 0' - target.markAuto('fuuko_xingdiao',[player]); - var cards=target.getCards('h',card=>card.hasGaintag('visible_fuuko_xingdiao')); - if(!cards.length) event.finish(); - else if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton(true,['选择获得'+get.translation(target)+'的一张“星”',cards]); - 'step 1' - if(result.bool){ - player.gain(result.links,target,'give'); + content() { + "step 0"; + target.markAuto("fuuko_xingdiao", [player]); + var cards = target.getCards("h", (card) => + card.hasGaintag("visible_fuuko_xingdiao") + ); + if (!cards.length) event.finish(); + else if (cards.length == 1) event._result = { bool: true, links: cards }; + else + player.chooseButton(true, [ + "选择获得" + get.translation(target) + "的一张“星”", + cards, + ]); + "step 1"; + if (result.bool) { + player.gain(result.links, target, "give"); target.draw(); } }, - ai:{ - order:6, - result:{ - target:1, + ai: { + order: 6, + result: { + target: 1, }, }, }, }, }, - fuuko_chuanyuan:{ - trigger:{ - player:'loseAfter', - global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'], + fuuko_chuanyuan: { + trigger: { + player: "loseAfter", + global: [ + "gainAfter", + "equipAfter", + "addJudgeAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter(event,player){ - const evt=event.getl(player); - if(!evt.hs.length) return false; - for(let i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('visible_fuuko_xingdiao')) return true; + forced: true, + filter(event, player) { + const evt = event.getl(player); + if (!evt.hs.length) return false; + for (let i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("visible_fuuko_xingdiao")) return true; } return false; }, - content(){ - var evt=trigger.getl(player),gains=[],draws=0; - var map=evt.gaintag_map; - var cards=evt.hs.filter(card=>{ - return map[card.cardid]&&map[card.cardid].includes('visible_fuuko_xingdiao'); + content() { + var evt = trigger.getl(player), + gains = [], + draws = 0; + var map = evt.gaintag_map; + var cards = evt.hs.filter((card) => { + return map[card.cardid] && map[card.cardid].includes("visible_fuuko_xingdiao"); }); - cards.forEach(card=>{ - var suit=get.suit(card,player),num=get.number(card,player); - var card2=get.cardPile2(function(card){ - if(gains.includes(card)) return false; - return get.suit(card,player)==suit&&get.number(card,player)==num; + cards.forEach((card) => { + var suit = get.suit(card, player), + num = get.number(card, player); + var card2 = get.cardPile2(function (card) { + if (gains.includes(card)) return false; + return get.suit(card, player) == suit && get.number(card, player) == num; }); - if(card2) gains.push(card2); + if (card2) gains.push(card2); else draws++; }); - if(gains.length) player.gain(gains,'gain2').gaintag.add('fuuko_chuanyuan'); - if(draws) player.draw(draws).gaintag=['fuuko_chuanyuan']; - player.addSkill('fuuko_chuanyuan_effect'); + if (gains.length) player.gain(gains, "gain2").gaintag.add("fuuko_chuanyuan"); + if (draws) player.draw(draws).gaintag = ["fuuko_chuanyuan"]; + player.addSkill("fuuko_chuanyuan_effect"); }, - subSkill:{ - effect:{ - mod:{ - targetInRange(card){ - if(!card.cards||!card.cards.length) return; - for(var i of card.cards){ - if(!i.hasGaintag('fuuko_chuanyuan')) return; + subSkill: { + effect: { + mod: { + targetInRange(card) { + if (!card.cards || !card.cards.length) return; + for (var i of card.cards) { + if (!i.hasGaintag("fuuko_chuanyuan")) return; } return true; }, - cardUsable(card){ - if(!card.cards||!card.cards.length) return; - for(var i of card.cards){ - if(!i.hasGaintag('fuuko_chuanyuan')) return; + cardUsable(card) { + if (!card.cards || !card.cards.length) return; + for (var i of card.cards) { + if (!i.hasGaintag("fuuko_chuanyuan")) return; } return Infinity; }, }, - charlotte:true, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter(event,player){ - if(event.addCount===false) return false; - return player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - for(let i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('fuuko_chuanyuan')) return true; + charlotte: true, + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter(event, player) { + if (event.addCount === false) return false; + return player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (let i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("fuuko_chuanyuan")) return true; } }); //return false; }, - content(){ - trigger.addCount=false; - player.getStat('card')[trigger.card.name]--; + content() { + trigger.addCount = false; + player.getStat("card")[trigger.card.name]--; }, }, }, }, //伊莉雅 - iriya_yinji:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - filter(event,player){ - return player.countCards('h')<17; + iriya_yinji: { + trigger: { player: "phaseUseBegin" }, + forced: true, + filter(event, player) { + return player.countCards("h") < 17; }, - content(){ - player.drawTo(17).gaintag=['iriya_yinji_tag']; - player.addSkill('iriya_yinji_tag'); + content() { + player.drawTo(17).gaintag = ["iriya_yinji_tag"]; + player.addSkill("iriya_yinji_tag"); }, - subSkill:{ - tag:{ - charlotte:true, - mod:{ - cardEnabled(card){ - if(get.itemtype(card)=='card'){ - if(card.hasGaintag('iriya_yinji_tag')) return false; - } - else if(card.isCard&&card.cards){ - if(card.cards.some(card=>card.hasGaintag('iriya_yinji_tag'))) return false; + subSkill: { + tag: { + charlotte: true, + mod: { + cardEnabled(card) { + if (get.itemtype(card) == "card") { + if (card.hasGaintag("iriya_yinji_tag")) return false; + } else if (card.isCard && card.cards) { + if (card.cards.some((card) => card.hasGaintag("iriya_yinji_tag"))) + return false; } }, - aiValue(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('iriya_yinji_tag')) return num/10000; + aiValue(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("iriya_yinji_tag")) + return num / 10000; }, - aiUseful(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('iriya_yinji_tag')) return num/10000; + aiUseful(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("iriya_yinji_tag")) + return num / 10000; }, }, }, }, }, - iriya_haozhi:{ - enable:'phaseUse', - filterCard:true, - selectCard:[2,Infinity], - promptfunc:()=>'出牌阶段,你可以按照斗地主牌型弃置至少两张牌,且其他角色可以依次对其进行一轮响应。最后一名进行响应的角色可以根据对应牌型执行对应效果。', - position:'he', - getType(cards,player){ - var nums=cards.map(card=>{ - var num=get.number(card,player); - if(num<=2) return num+13; - return num; - }).sort((a,b)=>(a-b)),len=nums.length; - if(len==1) return ['单张',nums[0],1]; - if(len==2) return nums[1]==nums[0]?['对子',nums[0],1]:null; - var map={}; - for(var i=0;i + "出牌阶段,你可以按照斗地主牌型弃置至少两张牌,且其他角色可以依次对其进行一轮响应。最后一名进行响应的角色可以根据对应牌型执行对应效果。", + position: "he", + getType(cards, player) { + var nums = cards + .map((card) => { + var num = get.number(card, player); + if (num <= 2) return num + 13; + return num; + }) + .sort((a, b) => a - b), + len = nums.length; + if (len == 1) return ["单张", nums[0], 1]; + if (len == 2) return nums[1] == nums[0] ? ["对子", nums[0], 1] : null; + var map = {}; + for (var i = 0; i < len; i++) { + var count = get.numOf(nums, nums[i]); + if (!map[count]) map[count] = []; map[count].push(nums[i]); - i+=(count-1); + i += count - 1; } - if(len==3){ - if(map[3]) return ['三张',nums[0],1]; + if (len == 3) { + if (map[3]) return ["三张", nums[0], 1]; return null; } - if(map[len]){ - return ['炸弹',nums[0],length]; + if (map[len]) { + return ["炸弹", nums[0], length]; } - if(map[1]){ - if(map[1].length==len&&len>4){ - for(var i=0;i 4) { + for (var i = 0; i < map[1].length - 1; i++) { + if (map[1][i + 1] - map[1][i] != 1) return null; + if (map[1][i + 1] == 15) return null; } - return ['单顺',nums[0],len]; - } - else if(map[1].length==2&&map[4]&&len==6){ - return ['四带二',map[4][0],1] - } - else if(map[3]&&map[1].length==map[3].length&&len==map[1].length*4){ - if(map[3].length==1) return ['三带一',map[3][0],1]; - for(var i=0;i5){ - for(var i=0;i 5) { + for (var i = 0; i < map[2].length - 1; i++) { + if (map[2][i + 1] - map[2][i] != 1) return null; + if (map[2][i + 1] == 15) return null; } - return ['双顺',nums[0],len]; - } - else if(map[4]&&len==6){ - return ['四带二',map[4][0],1] - } - else if(map[3]&&map[2].length==map[3].length&&len==map[2].length*5){ - if(map[3].length==1) return ['三带二',map[3][0],1]; - for(var i=0;i5){ - for(var i=0;i 5) { + for (var i = 0; i < map[3].length - 1; i++) { + if (map[3][i + 1] - map[3][i] != 1) return null; + if (map[3][i + 1] == 15) return null; } - return ['三顺',nums[0],len]; + return ["三顺", nums[0], len]; } return null; } return null; }, - filterOk(){ - return Array.isArray(lib.skill.iriya_haozhi.getType(ui.selected.cards,_status.event.player)); + filterOk() { + return Array.isArray( + lib.skill.iriya_haozhi.getType(ui.selected.cards, _status.event.player) + ); }, - check(card){ - var player=_status.event.player; + check(card) { + var player = _status.event.player; //收益都一样 多一牌不如少一牌 - var types=['炸弹','三顺','单顺','双顺','三张','对子']; - var getNum=function(card,player){ - var num=get.number(card,player); - if(num<=2) return num+13; - return num; - },hasEnemy=game.hasPlayer(current=>get.attitude(player,current)<0); + var types = ["炸弹", "三顺", "单顺", "双顺", "三张", "对子"]; + var getNum = function (card, player) { + var num = get.number(card, player); + if (num <= 2) return num + 13; + return num; + }, + hasEnemy = game.hasPlayer((current) => get.attitude(player, current) < 0); //所有手牌 - var nums=player.getCards('he',function(card){ - return lib.filter.cardDiscardable(card,player); - }).map(card=>getNum(card,player)); - var numu=ui.selected.cards.map(card=>getNum(card,player)); - var num=getNum(card,player); - if(!_status.event._iriya_haozhi_type){ - for(var type of types){ - switch(type){ - case '炸弹': - if(!hasEnemy) break; - for(var i of nums){ - if(get.numOf(nums,i)>=4){ - _status.event._iriya_haozhi_type='炸弹'; + var nums = player + .getCards("he", function (card) { + return lib.filter.cardDiscardable(card, player); + }) + .map((card) => getNum(card, player)); + var numu = ui.selected.cards.map((card) => getNum(card, player)); + var num = getNum(card, player); + if (!_status.event._iriya_haozhi_type) { + for (var type of types) { + switch (type) { + case "炸弹": + if (!hasEnemy) break; + for (var i of nums) { + if (get.numOf(nums, i) >= 4) { + _status.event._iriya_haozhi_type = "炸弹"; break; } } break; - case '三顺': - if(!hasEnemy) break; - for(var i of nums){ - if(i<14&&get.numOf(nums,i)>=3&&get.numOf(nums,i+1)>=3){ - _status.event._iriya_haozhi_type='三顺'; + case "三顺": + if (!hasEnemy) break; + for (var i of nums) { + if ( + i < 14 && + get.numOf(nums, i) >= 3 && + get.numOf(nums, i + 1) >= 3 + ) { + _status.event._iriya_haozhi_type = "三顺"; break; } } break; - case '双顺': - if(!hasEnemy) break; - for(var i of nums){ - if(i<13&&get.numOf(nums,i)>=2){ - for(var j=1;j<3;j++){ - if(get.numOf(nums,i+j)<2) break; - if(j==2) _status.event._iriya_haozhi_type='双顺'; + case "双顺": + if (!hasEnemy) break; + for (var i of nums) { + if (i < 13 && get.numOf(nums, i) >= 2) { + for (var j = 1; j < 3; j++) { + if (get.numOf(nums, i + j) < 2) break; + if (j == 2) _status.event._iriya_haozhi_type = "双顺"; } } } break; - case '单顺': - if(!hasEnemy) break; - for(var i of nums){ - if(i<11){ - for(var j=1;j<5;j++){ - if(!nums.includes(i+j)) break; - if(j==4) _status.event._iriya_haozhi_type='单顺'; + case "单顺": + if (!hasEnemy) break; + for (var i of nums) { + if (i < 11) { + for (var j = 1; j < 5; j++) { + if (!nums.includes(i + j)) break; + if (j == 4) _status.event._iriya_haozhi_type = "单顺"; } } } break; - case '三张': - if(!hasEnemy) break; - for(var i of nums){ - if(get.numOf(nums,i)>=3){ - _status.event._iriya_haozhi_type='三张'; + case "三张": + if (!hasEnemy) break; + for (var i of nums) { + if (get.numOf(nums, i) >= 3) { + _status.event._iriya_haozhi_type = "三张"; break; } } break; - case '对子': - for(var i of nums){ - if(get.numOf(nums,i)>=2){ - _status.event._iriya_haozhi_type='对子'; + case "对子": + for (var i of nums) { + if (get.numOf(nums, i) >= 2) { + _status.event._iriya_haozhi_type = "对子"; break; } } break; } - if(_status.event._iriya_haozhi_type) break; + if (_status.event._iriya_haozhi_type) break; } - if(!_status.event._iriya_haozhi_type) _status.event._iriya_haozhi_type='要不起'; + if (!_status.event._iriya_haozhi_type) _status.event._iriya_haozhi_type = "要不起"; } - if(_status.event._iriya_haozhi_type=='要不起') return 0; + if (_status.event._iriya_haozhi_type == "要不起") return 0; //复用响应AI - if(!ui.selected.cards.length){ - var count=get.numOf(nums,num); - switch(_status.event._iriya_haozhi_type){ - case '炸弹': - if(count>=4) return 15; + if (!ui.selected.cards.length) { + var count = get.numOf(nums, num); + switch (_status.event._iriya_haozhi_type) { + case "炸弹": + if (count >= 4) return 15; break; - case '对子': - if(count>1&&player.hasCard(function(cardx){ - return cardx!=card&&getNum(cardx,player)==num&&cardx.hasGaintag('iriya_yinji_tag'); - },'he')) return 4-get.value(card); + case "对子": + if ( + count > 1 && + player.hasCard(function (cardx) { + return ( + cardx != card && + getNum(cardx, player) == num && + cardx.hasGaintag("iriya_yinji_tag") + ); + }, "he") + ) + return 4 - get.value(card); break; - case '三张': - if(count>2) return 8-get.value(card); + case "三张": + if (count > 2) return 8 - get.value(card); break; - case '单顺': - if(num>10) return 0; - for(var i=1;i<5;i++){ - if(get.numOf(nums,num+i)<1) return 0; + case "单顺": + if (num > 10) return 0; + for (var i = 1; i < 5; i++) { + if (get.numOf(nums, num + i) < 1) return 0; } - return 9-get.value(card); - case '双顺': - if(count<2||num>12) return 0; - for(var i=1;i<3;i++){ - if(get.numOf(nums,num+i)<2) return 0; + return 9 - get.value(card); + case "双顺": + if (count < 2 || num > 12) return 0; + for (var i = 1; i < 3; i++) { + if (get.numOf(nums, num + i) < 2) return 0; } - return 9-get.value(card); - case '三顺': - if(count<3||num>13) return 0; - for(var i=1;i<2;i++){ - if(get.numOf(nums,num+i)<2) return 0; + return 9 - get.value(card); + case "三顺": + if (count < 3 || num > 13) return 0; + for (var i = 1; i < 2; i++) { + if (get.numOf(nums, num + i) < 2) return 0; } - return 12-get.value(card); + return 12 - get.value(card); } return 0; - } - else{ - switch(_status.event._iriya_haozhi_type){ - case '炸弹': - if(numu.length>=4) return 0; - if(num==numu[0]) return 15; + } else { + switch (_status.event._iriya_haozhi_type) { + case "炸弹": + if (numu.length >= 4) return 0; + if (num == numu[0]) return 15; return 0; - case '对子': - if(numu.length>=2) return 0; - if(num==numu[0]) return 3-get.value(card); + case "对子": + if (numu.length >= 2) return 0; + if (num == numu[0]) return 3 - get.value(card); return 0; - case '三张': - if(numu.length>=3) return 0; - if(num==numu[0]) return 9-get.value(card); + case "三张": + if (numu.length >= 3) return 0; + if (num == numu[0]) return 9 - get.value(card); return 0; - case '单顺': case '双顺': case '三顺': - var map={ - 单顺:[5,0], - 双顺:[3,1], - 三顺:[2,2], - },len=map[_status.event._iriya_haozhi_type][0],addNum=map[_status.event._iriya_haozhi_type][1]; - if(numu.length>=len) return 0; - var numt=numu[numu.length-1]+(numu.length%(1+addNum)==0?1:0); - if(num==numt) return 10+addNum-get.value(card); + case "单顺": + case "双顺": + case "三顺": + var map = { + 单顺: [5, 0], + 双顺: [3, 1], + 三顺: [2, 2], + }, + len = map[_status.event._iriya_haozhi_type][0], + addNum = map[_status.event._iriya_haozhi_type][1]; + if (numu.length >= len) return 0; + var numt = numu[numu.length - 1] + (numu.length % (1 + addNum) == 0 ? 1 : 0); + if (num == numt) return 10 + addNum - get.value(card); return 0; } } }, //响应AI - respondAI(card){ - if(!_status.event.goon) return 0; - var type=_status.event.type,player=_status.event.player; - var getNum=function(card,player){ - var num=get.number(card,player); - if(num<=2) return num+13; - return num; - },nums=player.getCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'iriya_haozhi'); - }).map(card=>getNum(card,player)); - var num=getNum(card,player); - if(!ui.selected.cards.length){ - var count=get.numOf(nums,num); - if(count>=4&&(type[0]!='炸弹'||num>type[1]||count>type[2])) return 15; - switch(type[0]){ - case '对子': - if(count>1&&num>type[1]) return 8-get.value(card); + respondAI(card) { + if (!_status.event.goon) return 0; + var type = _status.event.type, + player = _status.event.player; + var getNum = function (card, player) { + var num = get.number(card, player); + if (num <= 2) return num + 13; + return num; + }, + nums = player + .getCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "iriya_haozhi"); + }) + .map((card) => getNum(card, player)); + var num = getNum(card, player); + if (!ui.selected.cards.length) { + var count = get.numOf(nums, num); + if (count >= 4 && (type[0] != "炸弹" || num > type[1] || count > type[2])) return 15; + switch (type[0]) { + case "对子": + if (count > 1 && num > type[1]) return 8 - get.value(card); break; - case '三张': case '三带一': case '三带二': - if(count>2&&num>type[1]) return 9-get.value(card); + case "三张": + case "三带一": + case "三带二": + if (count > 2 && num > type[1]) return 9 - get.value(card); break; - case '单顺': - if(num<=type[1]||num>(15-type[2])) return 0; - for(var i=1;i 15 - type[2]) return 0; + for (var i = 1; i < type[2]; i++) { + if (get.numOf(nums, num + i) < 1) return 0; } - return 10-get.value(card); - case '双顺': - if(num<=type[1]||count<2||num>(15-type[2]/2)) return 0; - for(var i=1;i 15 - type[2] / 2) return 0; + for (var i = 1; i < type[2] / 2; i++) { + if (get.numOf(nums, num + i) < 2) return 0; } - return 11-get.value(card); - case '三顺': case '单带飞机': case '双带飞机': - var size=3+['三顺','单带飞机','双带飞机'].indexOf(type[0]); - if(num<=type[1]||count<3||num>(15-type[2]/size)) return 0; - for(var i=1;i 15 - type[2] / size) return 0; + for (var i = 1; i < type[2] / size; i++) { + if (get.numOf(nums, num + i) < 2) return 0; } - return 12-get.value(card); + return 12 - get.value(card); } return 0; - } - else{ - var numu=ui.selected.cards.map(card=>getNum(card,player)) - var numx=numu[0]; - if(num==numx){ - var count=get.numOf(nums,numx); - if(count>=4&&(type[0]!='炸弹'||num>type[1]||count>type[2])&&(numu.length<(type[0]=='炸弹'?type2:4))) return 15; + } else { + var numu = ui.selected.cards.map((card) => getNum(card, player)); + var numx = numu[0]; + if (num == numx) { + var count = get.numOf(nums, numx); + if ( + count >= 4 && + (type[0] != "炸弹" || num > type[1] || count > type[2]) && + numu.length < (type[0] == "炸弹" ? type2 : 4) + ) + return 15; } - switch(type[0]){ - case '对子': - if(numu.length>=2) return 0; - if(num==numu[0]) return 8-get.value(card); + switch (type[0]) { + case "对子": + if (numu.length >= 2) return 0; + if (num == numu[0]) return 8 - get.value(card); return 0; - case '三张': - if(numu.length>=3) return 0; - if(num==numu[0]) return 9-get.value(card); + case "三张": + if (numu.length >= 3) return 0; + if (num == numu[0]) return 9 - get.value(card); return 0; - case '三带一': - if(numu.length==3||num==numu[0]) return 9-get.value(card); + case "三带一": + if (numu.length == 3 || num == numu[0]) return 9 - get.value(card); return 0; - case '三带二': - if(numu.length>=5) return false; - if(numu.length==3){ - if(num==numu[0]||get.numOf(nums,num)<2) return 0; + case "三带二": + if (numu.length >= 5) return false; + if (numu.length == 3) { + if (num == numu[0] || get.numOf(nums, num) < 2) return 0; + } else if (numu.length == 4) { + return num == numu[3] ? 9 - get.value(card) : 0; } - else if(numu.length==4){ - return num==numu[3]?9-get.value(card):0; - } - if(num==numu[0]) return 9-get.value(card); + if (num == numu[0]) return 9 - get.value(card); return 0; - case '单顺': case '双顺': case '三顺': - if(numu.length>=type[2]) return 0; - var addNum=['单顺','双顺','三顺'].indexOf(type[0]); - var numt=numu[numu.length-1]+(numu.length%(1+addNum)==0?1:0); - if(num==numt) return 10+addNum-get.value(card); + case "单顺": + case "双顺": + case "三顺": + if (numu.length >= type[2]) return 0; + var addNum = ["单顺", "双顺", "三顺"].indexOf(type[0]); + var numt = numu[numu.length - 1] + (numu.length % (1 + addNum) == 0 ? 1 : 0); + if (num == numt) return 10 + addNum - get.value(card); return 0; - case '单带飞机': - if(numu.length>=type[2]) return 0; - var len=type[2]/4*3; - if(numu.length=numu[0]||num<=numu[len-1]) return 0; - return 12-get.value(card); + case "单带飞机": + if (numu.length >= type[2]) return 0; + var len = (type[2] / 4) * 3; + if (numu.length < len) { + var numt = numu[numu.length - 1] + (numu.length % 3 == 0 ? 1 : 0); + if (num == numt) return 12 - get.value(card); + } else { + if (num >= numu[0] || num <= numu[len - 1]) return 0; + return 12 - get.value(card); } return 0; - case '双带飞机': - if(numu.length>=type[2]) return 0; - var len=type[2]/5*3; - if(numu.length= type[2]) return 0; + var len = (type[2] / 5) * 3; + if (numu.length < len) { + var numt = numu[numu.length - 1] + (numu.length % 3 == 0 ? 1 : 0); + if (num == numt) return 12 - get.value(card); + } else { + if ((numu.length - len) % 2 == 0) { + if (numu.includes(num) || get.numOf(nums, num) < 2) return 0; + return 12 - get.value(card); + } else { + return num == numu[numu.length - 1] ? 12 - get.value(card) : 0; } } return 0; } } }, - content(){ - 'step 0' - var players=game.filterPlayer().sortBySeat(player.getNext()); - event.players=players; - event.current=player; - event.current_type=lib.skill.iriya_haozhi.getType(cards,player); - event.current_cards=cards.slice(0); - if(!event.current_type) event.finish(); - 'step 1' - var target=event.players.shift(); - if((target!=player||event.current!=player)&&target.isIn()&&target.countCards('h')>=Math.min(cards.length,4)){ - event.target=target; - target.addTempSkill('iriya_haozhi_temp',{global:['discardBefore','chooseToDiscardEnd','phaseAfter']}); - var trans=get.translation(event.current); - var cardsn=function(cards,player){ - var getn=(card,player)=>{ - var num=get.number(card,player); - if(num<=2) return num+13; + content() { + "step 0"; + var players = game.filterPlayer().sortBySeat(player.getNext()); + event.players = players; + event.current = player; + event.current_type = lib.skill.iriya_haozhi.getType(cards, player); + event.current_cards = cards.slice(0); + if (!event.current_type) event.finish(); + "step 1"; + var target = event.players.shift(); + if ( + (target != player || event.current != player) && + target.isIn() && + target.countCards("h") >= Math.min(cards.length, 4) + ) { + event.target = target; + target.addTempSkill("iriya_haozhi_temp", { + global: ["discardBefore", "chooseToDiscardEnd", "phaseAfter"], + }); + var trans = get.translation(event.current); + var cardsn = (function (cards, player) { + var getn = (card, player) => { + var num = get.number(card, player); + if (num <= 2) return num + 13; return num; }; - cards.sort(function(a,b){ - var numa=getn(a,player),numb=getn(b,player); - if(numa!=numb) return numa-numb; - return lib.suit.indexOf(get.suit(a,player)-get.suit(b,player)); + cards.sort(function (a, b) { + var numa = getn(a, player), + numb = getn(b, player); + if (numa != numb) return numa - numb; + return lib.suit.indexOf(get.suit(a, player) - get.suit(b, player)); }); - var str=''; - for(var i of cards){ - str+=','; - str+=get.strNumber(get.number(i,player)); - str+=get.translation(get.suit(i,player)); + var str = ""; + for (var i of cards) { + str += ","; + str += get.strNumber(get.number(i, player)); + str += get.translation(get.suit(i, player)); } return str.slice(1); - }(event.current_cards,event.current); - var next=target.chooseToDiscard( - '是否响应'+trans+'的'+get.translation(event.current_type[0])+'?', - trans+'的牌组为'+cardsn+'。您此时可以点击“整理手牌”,将手牌按点数排序。',[2,Infinity],'he'); - next.set('type',event.current_type); - next.set('filterOk',function(){ - var type=lib.skill.iriya_haozhi.getType(ui.selected.cards,_status.event.player); - if(!type) return false; - var ptype=_status.event.type; - if(type[0]=='炸弹'){ - if(ptype[0]=='炸弹'){ - if(type[2]>ptype[2]) return true; - return type[1]>ptype[1]&&type[2]==ptype[2]; + })(event.current_cards, event.current); + var next = target.chooseToDiscard( + "是否响应" + trans + "的" + get.translation(event.current_type[0]) + "?", + trans + "的牌组为" + cardsn + "。您此时可以点击“整理手牌”,将手牌按点数排序。", + [2, Infinity], + "he" + ); + next.set("type", event.current_type); + next.set("filterOk", function () { + var type = lib.skill.iriya_haozhi.getType( + ui.selected.cards, + _status.event.player + ); + if (!type) return false; + var ptype = _status.event.type; + if (type[0] == "炸弹") { + if (ptype[0] == "炸弹") { + if (type[2] > ptype[2]) return true; + return type[1] > ptype[1] && type[2] == ptype[2]; } return true; } - return type[0]==ptype[0]&&type[2]==ptype[2]&&type[1]>ptype[1]; + return type[0] == ptype[0] && type[2] == ptype[2] && type[1] > ptype[1]; }); - next.set('goon',get.attitude(target,event.current)<0); - next.set('ai',lib.skill.iriya_haozhi.respondAI); - } - else if(event.players.length>0) event.redo(); + next.set("goon", get.attitude(target, event.current) < 0); + next.set("ai", lib.skill.iriya_haozhi.respondAI); + } else if (event.players.length > 0) event.redo(); else event.goto(3); - 'step 2' - if(result.bool){ - event.current=target; - event.current_type=lib.skill.iriya_haozhi.getType(result.cards.slice(0),target); - event.current_cards=result.cards.slice(0); - if(!event.current_type) event.finish(); + "step 2"; + if (result.bool) { + event.current = target; + event.current_type = lib.skill.iriya_haozhi.getType(result.cards.slice(0), target); + event.current_cards = result.cards.slice(0); + if (!event.current_type) event.finish(); event.current.addExpose(0.5); } - if(event.players.length>0) event.goto(1); - 'step 3' - var current=event.current,type=0; - if(!current.isIn()) return; - switch(event.current_type[0]){ - case '对子': - type=1;break; - case '三张': case '三带一': case '三带二': - type=2;break; - case '单顺': - type=3;break; - case '双顺': - type=4;break; - case '三顺': case '单带飞机': case '双带飞机': - type=5;break; - case '炸弹': case'四带二': - type=6;break; + if (event.players.length > 0) event.goto(1); + "step 3"; + var current = event.current, + type = 0; + if (!current.isIn()) return; + switch (event.current_type[0]) { + case "对子": + type = 1; + break; + case "三张": + case "三带一": + case "三带二": + type = 2; + break; + case "单顺": + type = 3; + break; + case "双顺": + type = 4; + break; + case "三顺": + case "单带飞机": + case "双带飞机": + type = 5; + break; + case "炸弹": + case "四带二": + type = 6; + break; } /*if(type==2){ current.addSkill('iriya_haozhi_extra'); current.addMark('iriya_haozhi_extra',1,false); } else */ - if(type>0){ - var next=game.createEvent('iriya_haozhi_effect',false); - next.player=current; - next.setContent(lib.skill.iriya_haozhi['content'+type]); + if (type > 0) { + var next = game.createEvent("iriya_haozhi_effect", false); + next.player = current; + next.setContent(lib.skill.iriya_haozhi["content" + type]); } }, - content1(){ - 'step 0' - player.chooseTarget([1,2],'是否令至多两名角色各摸一张牌?').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) att/=10; - return att; - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); + content1() { + "step 0"; + player + .chooseTarget([1, 2], "是否令至多两名角色各摸一张牌?") + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) att /= 10; + return att; + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); player.line(targets); game.asyncDraw(targets); game.delayex(); } }, - content2(){ - 'step 0' - player.chooseTarget([1,3],'是否弃置至多三名角色的各一张牌?',function(card,player,target){ - return target!=player&&target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he') - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); - for(var target of targets){ - player.discardPlayerCard(target,true,'he'); + content2() { + "step 0"; + player + .chooseTarget( + [1, 3], + "是否弃置至多三名角色的各一张牌?", + function (card, player, target) { + return ( + target != player && + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); + for (var target of targets) { + player.discardPlayerCard(target, true, "he"); } } - 'step 2' + "step 2"; //player.recover(); player.draw(); }, - content3(){ - 'step 0' - event.count=0; - 'step 1' - var next=player.chooseTarget('是否弃置一名其他角色的一张牌?',function(card,player,target){ - return target!=player&&target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - if(event.color) next.set('prompt2','若你弃置的牌为'+get.translation(event.color)+',则你可以重复此流程'); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - player.discardPlayerCard(target,true,'he'); - } - else event.goto(4); - 'step 3' - if(result.bool){ + content3() { + "step 0"; + event.count = 0; + "step 1"; + var next = player + .chooseTarget("是否弃置一名其他角色的一张牌?", function (card, player, target) { + return ( + target != player && + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + if (event.color) + next.set( + "prompt2", + "若你弃置的牌为" + get.translation(event.color) + ",则你可以重复此流程" + ); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + player.discardPlayerCard(target, true, "he"); + } else event.goto(4); + "step 3"; + if (result.bool) { event.count++; - var card=result.cards[0],color=get.color(card,false); - if(!event.color){ - event.color=color; + var card = result.cards[0], + color = get.color(card, false); + if (!event.color) { + event.color = color; event.goto(1); - } - else if(color==event.color) event.goto(1); + } else if (color == event.color) event.goto(1); } - 'step 4' - if(event.count>0) player.draw(event.count); + "step 4"; + if (event.count > 0) player.draw(event.count); }, - content4(){ - 'step 0' - event.count=0; - 'step 1' - var next=player.chooseTarget('是否获得一名其他角色的一张牌?',function(card,player,target){ - return target!=player&&target.hasCard(function(card){ - return lib.filter.canBeGained(card,player,target); - },'he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'shunshou_copy2'},player,player); - }); - if(event.color) next.set('prompt2','若你得到的牌为'+get.translation(event.color)+',则你可以重复此流程'); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - player.gainPlayerCard(target,true,'he'); - } - else event.goto(4); - 'step 3' - if(result.bool){ + content4() { + "step 0"; + event.count = 0; + "step 1"; + var next = player + .chooseTarget("是否获得一名其他角色的一张牌?", function (card, player, target) { + return ( + target != player && + target.hasCard(function (card) { + return lib.filter.canBeGained(card, player, target); + }, "he") + ); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "shunshou_copy2" }, player, player); + }); + if (event.color) + next.set( + "prompt2", + "若你得到的牌为" + get.translation(event.color) + ",则你可以重复此流程" + ); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + player.gainPlayerCard(target, true, "he"); + } else event.goto(4); + "step 3"; + if (result.bool) { event.count++; - var card=result.cards[0],color=get.color(card,false); - if(!event.color){ - event.color=color; + var card = result.cards[0], + color = get.color(card, false); + if (!event.color) { + event.color = color; event.goto(1); - } - else if(color==event.color) event.goto(1); + } else if (color == event.color) event.goto(1); //player.draw(); } - 'step 4' - if(event.count>0) player.recover(event.count); + "step 4"; + if (event.count > 0) player.recover(event.count); }, - content5(){ - 'step 0' - player.chooseTarget([1,3],'是否令至多三名其他角色翻面?',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.isTurnedOver()) return 10*att; - return -6*att; - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'thunder'); - event.targets=targets; - for(var target of targets) target.turnOver(); + content5() { + "step 0"; + player + .chooseTarget([1, 3], "是否令至多三名其他角色翻面?", lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.isTurnedOver()) return 10 * att; + return -6 * att; + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "thunder"); + event.targets = targets; + for (var target of targets) target.turnOver(); } - 'step 2' - player.chooseTarget('是否对一名目标角色造成1点火属性伤害?',function(card,player,target){ - return _status.event.getParent().targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player,'fire'); - }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - target.damage('fire'); + "step 2"; + player + .chooseTarget( + "是否对一名目标角色造成1点火属性伤害?", + function (card, player, target) { + return _status.event.getParent().targets.includes(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player, "fire"); + }); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + target.damage("fire"); } }, - content6(){ - 'step 0' - player.chooseTarget('是否对一名其他角色进行核打击?','你对该角色造成2点雷属性伤害,然后该角色翻面,弃置装备区内的所有牌和四张手牌。',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.isTurnedOver()) return -6*att*Math.sqrt(2+target.countCards('he')); - return -att*Math.sqrt(2+target.countCards('he')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'thunder'); - target.damage('thunder',2); + content6() { + "step 0"; + player + .chooseTarget( + "是否对一名其他角色进行核打击?", + "你对该角色造成2点雷属性伤害,然后该角色翻面,弃置装备区内的所有牌和四张手牌。", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.isTurnedOver()) + return -6 * att * Math.sqrt(2 + target.countCards("he")); + return -att * Math.sqrt(2 + target.countCards("he")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "thunder"); + target.damage("thunder", 2); target.turnOver(); - } - else event.finish(); - 'step 2' - var num=target.countCards('e'); - if(num>0) target.chooseToDiscard('e',true,num); - 'step 3' - var num=target.countCards('h'); - if(num>0) target.chooseToDiscard('h',true,Math.min(4,num)); + } else event.finish(); + "step 2"; + var num = target.countCards("e"); + if (num > 0) target.chooseToDiscard("e", true, num); + "step 3"; + var num = target.countCards("h"); + if (num > 0) target.chooseToDiscard("h", true, Math.min(4, num)); }, - ai:{ - sortCardByNum:true, - order:13, - result:{ - player:1, + ai: { + sortCardByNum: true, + order: 13, + result: { + player: 1, }, }, - subSkill:{ - extra:{ - charlotte:true, - mod:{ - targetInRange:()=>true, - cardUsable:()=>Infinity, + subSkill: { + extra: { + charlotte: true, + mod: { + targetInRange: () => true, + cardUsable: () => Infinity, }, - trigger:{player:'useCard2'}, - forced:true, - onremove:true, - content(){ - 'step 0' - var num=player.countMark('iriya_haozhi_extra'); - player.removeSkill('iriya_haozhi_extra'); - var card=trigger.card; - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card; - if(stat[card.name]&&stat[card.name]>0) stat[card.name]--; + trigger: { player: "useCard2" }, + forced: true, + onremove: true, + content() { + "step 0"; + var num = player.countMark("iriya_haozhi_extra"); + player.removeSkill("iriya_haozhi_extra"); + var card = trigger.card; + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card; + if (stat[card.name] && stat[card.name] > 0) stat[card.name]--; } - var info=get.info(card); - if(info.allowMultiple==false) event.finish(); - if(trigger.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ - var prompt2='为'+get.translation(card)+'增加'+(num>1?'至多':'')+get.cnNumber(num)+'个目标' - player.chooseTarget(get.prompt('iriya_haozhi_extra'),[1,num],function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); + var info = get.info(card); + if (info.allowMultiple == false) event.finish(); + if (trigger.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { + var prompt2 = + "为" + + get.translation(card) + + "增加" + + (num > 1 ? "至多" : "") + + get.cnNumber(num) + + "个目标"; + player + .chooseTarget( + get.prompt("iriya_haozhi_extra"), + [1, num], + function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2( + _status.event.card, + player, + target + ) + ); + } + ) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); } } - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('iriya_haozhi_extra',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("iriya_haozhi_extra", event.targets); trigger.targets.addArray(event.targets); } }, - intro:{content:'使用下一张牌无距离和次数限制,且可以增加#个目标'}, + intro: { + content: "使用下一张牌无距离和次数限制,且可以增加#个目标", + }, + }, + temp: { + ai: { sortCardByNum: true }, + charlotte: true, }, - temp:{ - ai:{sortCardByNum:true}, - charlotte:true, - } }, }, //远野美凪&远野小满 - minagi_peiquan:{ - enable:'phaseUse', - filter(event,player){ - return player.hasCard((card)=>card.hasGaintag('minagi_tag'),'h'); + minagi_peiquan: { + enable: "phaseUse", + filter(event, player) { + return player.hasCard((card) => card.hasGaintag("minagi_tag"), "h"); }, - filterCard(card){ - return card.hasGaintag('minagi_tag'); + filterCard(card) { + return card.hasGaintag("minagi_tag"); }, - position:'h', - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - promptfunc:()=>'出牌阶段,你可以赠予一张“米券”,然后执行一项本回合内未被选择过的效果:⒈对其造成1点伤害;⒉摸两张牌;⒊弃置其的两张牌;⒋亮出牌堆顶的一张牌,然后你可以使用之。', - check:card=>{ - const player=_status.event.player; - return get.type(card,false)=='equip'&&game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0)?2:1+Math.random(); + position: "h", + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + promptfunc: () => + "出牌阶段,你可以赠予一张“米券”,然后执行一项本回合内未被选择过的效果:⒈对其造成1点伤害;⒉摸两张牌;⒊弃置其的两张牌;⒋亮出牌堆顶的一张牌,然后你可以使用之。", + check: (card) => { + const player = _status.event.player; + return get.type(card, false) == "equip" && + game.hasPlayer( + (current) => + player.canGift(card, current, true) && + !current.refuseGifts(card, player) && + get.effect(current, card, player, player) > 0 + ) + ? 2 + : 1 + Math.random(); }, - content(){ - 'step 0' - player.gift(cards,target); - 'step 1' - var list=player.getStorage('minagi_peiquan_yukito'); - if(list.length>=4) event.finish(); - else{ - var yukito=get.translation(target); - player.chooseButton([ - '配券:请选择一项执行', - [[ - ['damage','选项一:对'+yukito+'造成1点伤害'], - ['draw','选项二:摸两张牌'], - ['discard','选项三:弃置'+yukito+'的两张牌'], - ['use','选项四:亮出牌堆顶的一张牌,然后可以使用之'], - ],'textbutton'] - ],true).set('list',list).set('filterButton',function(button){ - return !_status.event.list.includes(button.link); - }).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().target; - switch(button.link){ - case 'damage':return get.damageEffect(target,player,player); - case 'draw':return 2*get.effect(player,{name:'draw'},player,player) - case 'discard':return get.effect(target,{name:'guohe_copy2'},player,player)*Math.min(1.6,target.countCards('he')); - case 'use':return _status.event.getRand('minagi_peiquan')*4; - } - }); + content() { + "step 0"; + player.gift(cards, target); + "step 1"; + var list = player.getStorage("minagi_peiquan_yukito"); + if (list.length >= 4) event.finish(); + else { + var yukito = get.translation(target); + player + .chooseButton( + [ + "配券:请选择一项执行", + [ + [ + ["damage", "选项一:对" + yukito + "造成1点伤害"], + ["draw", "选项二:摸两张牌"], + ["discard", "选项三:弃置" + yukito + "的两张牌"], + ["use", "选项四:亮出牌堆顶的一张牌,然后可以使用之"], + ], + "textbutton", + ], + ], + true + ) + .set("list", list) + .set("filterButton", function (button) { + return !_status.event.list.includes(button.link); + }) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target; + switch (button.link) { + case "damage": + return get.damageEffect(target, player, player); + case "draw": + return 2 * get.effect(player, { name: "draw" }, player, player); + case "discard": + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) * + Math.min(1.6, target.countCards("he")) + ); + case "use": + return _status.event.getRand("minagi_peiquan") * 4; + } + }); } - 'step 2' - player.markAuto('minagi_peiquan_yukito',result.links); - player.addTempSkill('minagi_peiquan_yukito'); - switch(result.links[0]){ - case 'damage':target.damage('nocard');break; - case 'draw':player.draw(2);break; - case 'discard':player.discardPlayerCard(target,2,'he',true);break; + "step 2"; + player.markAuto("minagi_peiquan_yukito", result.links); + player.addTempSkill("minagi_peiquan_yukito"); + switch (result.links[0]) { + case "damage": + target.damage("nocard"); + break; + case "draw": + player.draw(2); + break; + case "discard": + player.discardPlayerCard(target, 2, "he", true); + break; } - if(result.links[0]!='use') event.finish(); - 'step 3' - var card=get.cards()[0]; + if (result.links[0] != "use") event.finish(); + "step 3"; + var card = get.cards()[0]; game.cardsGotoOrdering(card); player.showCards(card); - player.chooseUseTarget(card,'是否使用'+get.translation(card)+'?'); + player.chooseUseTarget(card, "是否使用" + get.translation(card) + "?"); }, - ai:{ - order:4, - result:{ - player:(player,target)=>{ - const giftEffects=ui.selected.cards.map(value=>player.getGiftEffect(value,target)); - const baseEffect=Math.min(3,giftEffects.reduce((previousValue,currentValue)=>previousValue+currentValue,0)/giftEffects.length); - const choices=['damage','draw','discard','use']; - choices.removeArray(player.getStorage('minagi_peiquan_yukito')); - if(choices.length<=0) return baseEffect; - return baseEffect+Math.max(...choices.map(choice=>{ - switch(choice){ - case 'damage':return get.damageEffect(target,player,player); - case 'draw':return 2*get.effect(player,{name:'draw'},player,player); - case 'discard':return get.effect(target,{name:'guohe_copy2'},player,player)*Math.min(1.6,target.countCards('he')); - case 'use':return _status.event.getRand('minagi_peiquan')*4; - } - })); - } - } + ai: { + order: 4, + result: { + player: (player, target) => { + const giftEffects = ui.selected.cards.map((value) => + player.getGiftEffect(value, target) + ); + const baseEffect = Math.min( + 3, + giftEffects.reduce( + (previousValue, currentValue) => previousValue + currentValue, + 0 + ) / giftEffects.length + ); + const choices = ["damage", "draw", "discard", "use"]; + choices.removeArray(player.getStorage("minagi_peiquan_yukito")); + if (choices.length <= 0) return baseEffect; + return ( + baseEffect + + Math.max( + ...choices.map((choice) => { + switch (choice) { + case "damage": + return get.damageEffect(target, player, player); + case "draw": + return ( + 2 * get.effect(player, { name: "draw" }, player, player) + ); + case "discard": + return ( + get.effect( + target, + { name: "guohe_copy2" }, + player, + player + ) * Math.min(1.6, target.countCards("he")) + ); + case "use": + return _status.event.getRand("minagi_peiquan") * 4; + } + }) + ) + ); + }, + }, }, - group:'minagi_peiquan_umareta', - subSkill:{ - yukito:{charlotte:true,onremove:true}, - umareta:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + group: "minagi_peiquan_umareta", + subSkill: { + yukito: { charlotte: true, onremove: true }, + umareta: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.countCards('h')>0; + forced: true, + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && player.countCards("h") > 0 + ); }, - content(){ - var hs=player.getCards('h'); - player.addGaintag(hs,'minagi_tag'); + content() { + var hs = player.getCards("h"); + player.addGaintag(hs, "minagi_tag"); }, }, }, }, - minagi_huanliu:{ - trigger:{player:'phaseZhunbeiBegin'}, - async cost(event,trigger,player){ - event.result = await player.chooseTarget(lib.filter.notMe,get.prompt('minagi_huanliu'),'和一名其他角色进行“协力”,并获得“远野小满”的所有对应技能').set('ai',function(target){ - return get.threaten(target)*Math.sqrt(1+target.countCards('h'))*((target.isTurnedOver()||target.hasJudge('lebu'))?0.1:1); - }).forResult(); + minagi_huanliu: { + trigger: { player: "phaseZhunbeiBegin" }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + lib.filter.notMe, + get.prompt("minagi_huanliu"), + "和一名其他角色进行“协力”,并获得“远野小满”的所有对应技能" + ) + .set("ai", function (target) { + return ( + get.threaten(target) * + Math.sqrt(1 + target.countCards("h")) * + (target.isTurnedOver() || target.hasJudge("lebu") ? 0.1 : 1) + ); + }) + .forResult(); }, - content(){ - 'step 0' - var target=targets[0]; - player.chooseCooperationFor(target,'minagi_huanliu').set('ai',function(button){ - var base=0; - switch(button.link){ - case 'cooperation_damage':base=0.1;break; - case 'cooperation_draw':base=0.6;break; - case 'cooperation_discard':base=0.1;break; - case 'cooperation_use':base=0.3;break; + content() { + "step 0"; + var target = targets[0]; + player.chooseCooperationFor(target, "minagi_huanliu").set("ai", function (button) { + var base = 0; + switch (button.link) { + case "cooperation_damage": + base = 0.1; + break; + case "cooperation_draw": + base = 0.6; + break; + case "cooperation_discard": + base = 0.1; + break; + case "cooperation_use": + base = 0.3; + break; } - return base+Math.random(); + return base + Math.random(); }); - player.addAdditionalSkill('cooperation',['minagi_huanliu_effect','michiru_sheyuan']); - 'step 1' + player.addAdditionalSkill("cooperation", ["minagi_huanliu_effect", "michiru_sheyuan"]); + "step 1"; game.delayx(); }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - logTarget:'player', - filter(event,player){ - return player.checkCooperationStatus(event.player,'minagi_huanliu')&&player.countCards('h')>0; + subSkill: { + effect: { + charlotte: true, + trigger: { global: "phaseJieshuBegin" }, + forced: true, + logTarget: "player", + filter(event, player) { + return ( + player.checkCooperationStatus(event.player, "minagi_huanliu") && + player.countCards("h") > 0 + ); }, - content(){ - game.log(player,'和',trigger.player,'的协力成功'); - var hs=player.getCards('h'); - player.addGaintag(hs,'minagi_tag'); + content() { + game.log(player, "和", trigger.player, "的协力成功"); + var hs = player.getCards("h"); + player.addGaintag(hs, "minagi_tag"); game.delayx(); }, }, }, - derivation:'michiru_sheyuan', + derivation: "michiru_sheyuan", }, - michiru_sheyuan:{ - charlotte:true, - enable:'chooseToUse', - filter(event,player){ - if(player.hasSkill('michiru_sheyuan_round')) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of hs){ - if(i.hasGaintag('minagi_tag')) return false; - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) return false; + michiru_sheyuan: { + charlotte: true, + enable: "chooseToUse", + filter(event, player) { + if (player.hasSkill("michiru_sheyuan_round")) return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of hs) { + if (i.hasGaintag("minagi_tag")) return false; + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false; } - for(var name of lib.inpile){ - var type=get.type(name); - if(type!='basic'&&type!='trick') return false; - var card=get.autoViewAs({name:name},hs) - if(event.filterCard(card,player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) return true; + for (var name of lib.inpile) { + var type = get.type(name); + if (type != "basic" && type != "trick") return false; + var card = get.autoViewAs({ name: name }, hs); + if (event.filterCard(card, player, event)) return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return true; } } } return false; }, - hiddenCard(player,name){ - var type=get.type(name); - if(type!='basic'&&type!='trick') return false; - if(player.hasSkill('michiru_sheyuan_round')) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - if(_status.connectMode) return true; - for(var i of hs){ - if(i.hasGaintag('minagi_tag')) return false; - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) return false; + hiddenCard(player, name) { + var type = get.type(name); + if (type != "basic" && type != "trick") return false; + if (player.hasSkill("michiru_sheyuan_round")) return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + if (_status.connectMode) return true; + for (var i of hs) { + if (i.hasGaintag("minagi_tag")) return false; + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false; } return true; }, - chooseButton:{ - dialog(event,player){ - var list=[],hs=player.getCards('h'); - for(var name of lib.inpile){ - var type=get.type(name); - if(type!='basic'&&type!='trick') continue; - var card=get.autoViewAs({name:name},hs); - if(event.filterCard(card,player,event)) list.push([type,'',name]); - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) list.push([type,'',name,nature]); + chooseButton: { + dialog(event, player) { + var list = [], + hs = player.getCards("h"); + for (var name of lib.inpile) { + var type = get.type(name); + if (type != "basic" && type != "trick") continue; + var card = get.autoViewAs({ name: name }, hs); + if (event.filterCard(card, player, event)) list.push([type, "", name]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) + list.push([type, "", name, nature]); } } } - return ui.create.dialog('舍愿',[list,'vcard'],'hidden'); + return ui.create.dialog("舍愿", [list, "vcard"], "hidden"); }, - check(button){ - var player=_status.event.player; - var card={ - name:button.link[2], - nature:button.link[3], + check(button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], }; - if(_status.event.getParent().type=='phase') return player.getUseValue(card,null,true); + if (_status.event.getParent().type == "phase") + return player.getUseValue(card, null, true); return 1; }, - backup(links,player){ + backup(links, player) { return { - viewAs:{ - name:links[0][2], - nature:links[0][3], + viewAs: { + name: links[0][2], + nature: links[0][3], }, - filterCard:true, - position:'h', - selectCard:-1, - onuse(result,player){ - player.addTempSkill('michiru_sheyuan_round','roundStart'); + filterCard: true, + position: "h", + selectCard: -1, + onuse(result, player) { + player.addTempSkill("michiru_sheyuan_round", "roundStart"); }, - } + }; }, - prompt(links,player){ - return '将所有手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用,然后摸等量的牌'; + prompt(links, player) { + return ( + "将所有手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用,然后摸等量的牌" + ); }, }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - return lib.skill.michiru_sheyuan.hiddenCard(player,'s'+tag.slice(8)); + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + return lib.skill.michiru_sheyuan.hiddenCard(player, "s" + tag.slice(8)); }, - order:1, - result:{ - player(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + order: 1, + result: { + player(player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - round:{ - charlotte:true, - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='michiru_sheyuan_backup'; + subSkill: { + round: { + charlotte: true, + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter(event, player) { + return event.skill == "michiru_sheyuan_backup"; }, - content(){ + content() { player.draw(trigger.cards.length); }, }, - backup:{}, + backup: {}, }, }, //坂上智代 - tomoyo_wuwei:{ - enable:['chooseToUse','chooseToRespond'], - viewAs:{name:'sha'}, - viewAsFilter(player){ - var storage=player.getStorage('tomoyo_wuwei_mark'); - return player.hasCard(function(card){ + tomoyo_wuwei: { + enable: ["chooseToUse", "chooseToRespond"], + viewAs: { name: "sha" }, + viewAsFilter(player) { + var storage = player.getStorage("tomoyo_wuwei_mark"); + return player.hasCard(function (card) { return !storage.includes(get.suit(card)); - },'hs'); + }, "hs"); }, - position:'hs', - filterCard(card,player){ - var storage=player.getStorage('tomoyo_wuwei_mark'); + position: "hs", + filterCard(card, player) { + var storage = player.getStorage("tomoyo_wuwei_mark"); return !storage.includes(get.suit(card)); }, - check(card){ - return 5-get.value(card); + check(card) { + return 5 - get.value(card); }, - onuse(result,player){ - player.markAuto('tomoyo_wuwei_mark',[get.suit(result.card,false)]); - player.addTempSkill('tomoyo_wuwei_mark'); + onuse(result, player) { + player.markAuto("tomoyo_wuwei_mark", [get.suit(result.card, false)]); + player.addTempSkill("tomoyo_wuwei_mark"); }, - onrespond(event,player){ - player.markAuto('tomoyo_wuwei_mark',[get.suit(event.card,false)]); - player.addTempSkill('tomoyo_wuwei_mark'); + onrespond(event, player) { + player.markAuto("tomoyo_wuwei_mark", [get.suit(event.card, false)]); + player.addTempSkill("tomoyo_wuwei_mark"); }, - group:'tomoyo_wuwei_combo', - subSkill:{ - mark:{ - charlotte:true, - onremove:true, + group: "tomoyo_wuwei_combo", + subSkill: { + mark: { + charlotte: true, + onremove: true, }, - combo:{ - trigger:{global:'useCardAfter'}, - direct:true, + combo: { + trigger: { global: "useCardAfter" }, + direct: true, //chooseToUse类技能暂时没办法改 - filter(event,player){ - return event.card.name=='shan'&&player.inRangeOf(event.player)&&player.canUse('sha',event.player,false); + filter(event, player) { + return ( + event.card.name == "shan" && + player.inRangeOf(event.player) && + player.canUse("sha", event.player, false) + ); }, - content(){ - player.chooseToUse('武威:是否对'+get.translation(trigger.player)+'使用一张【杀】?',function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },trigger.player,-1).set('addCount',false).logSkill='tomoyo_wuwei_combo'; + content() { + player + .chooseToUse( + "武威:是否对" + get.translation(trigger.player) + "使用一张【杀】?", + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + trigger.player, + -1 + ) + .set("addCount", false).logSkill = "tomoyo_wuwei_combo"; }, }, }, }, - tomoyo_zhengfeng:{ - dutySkill:true, - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return game.hasPlayer((current)=>player.inRange(current)); + tomoyo_zhengfeng: { + dutySkill: true, + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return game.hasPlayer((current) => player.inRange(current)); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt('tomoyo_zhengfeng'),'令一名攻击范围内的角色进行判定。其于你的下回合开始前使用与判定结果颜色相同的牌时,你摸一张牌。',function(card,player,target){ - return player.inRange(target); - }).set('ai',function(target){ - var player=_status.event.player; - if(player.hp<=1&&!player.countCards('h')) return 0; - var hs=target.countCards('h'),thr=get.threaten(target); - if(target.hasJudge('lebu')) return 0; - return Math.sqrt(1+hs)*Math.sqrt(Math.max(1,1+thr)); - }).forResult() + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("tomoyo_zhengfeng"), + "令一名攻击范围内的角色进行判定。其于你的下回合开始前使用与判定结果颜色相同的牌时,你摸一张牌。", + function (card, player, target) { + return player.inRange(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (player.hp <= 1 && !player.countCards("h")) return 0; + var hs = target.countCards("h"), + thr = get.threaten(target); + if (target.hasJudge("lebu")) return 0; + return Math.sqrt(1 + hs) * Math.sqrt(Math.max(1, 1 + thr)); + }) + .forResult(); }, - content(){ - 'step 0' + content() { + "step 0"; var target = targets[0]; event.target = target; target.judge(); - 'step 1' - player.addTempSkill('tomoyo_zhengfeng_tomoyo',{player:'phaseBeginStart'}); - player.markAuto('tomoyo_zhengfeng_tomoyo',[{ - target:target, - color:result.color, - }]); + "step 1"; + player.addTempSkill("tomoyo_zhengfeng_tomoyo", { + player: "phaseBeginStart", + }); + player.markAuto("tomoyo_zhengfeng_tomoyo", [ + { + target: target, + color: result.color, + }, + ]); }, - group:'tomoyo_zhengfeng_after', - subSkill:{ - tomoyo:{ - charlotte:true, - onremove:true, - mod:{ - inRangeOf(source,player){ - var list=player.getStorage('tomoyo_zhengfeng_tomoyo'); - for(var obj of list){ - if(obj.target==source) return true; + group: "tomoyo_zhengfeng_after", + subSkill: { + tomoyo: { + charlotte: true, + onremove: true, + mod: { + inRangeOf(source, player) { + var list = player.getStorage("tomoyo_zhengfeng_tomoyo"); + for (var obj of list) { + if (obj.target == source) return true; } }, }, - trigger:{global:'useCard'}, - forced:true, - filter(event,player){ - var color=get.color(event.card); - if(color=='none') return false; - var list=player.getStorage('tomoyo_zhengfeng_tomoyo'); - for(var obj of list){ - if(obj.target==event.player&&color==obj.color) return true; + trigger: { global: "useCard" }, + forced: true, + filter(event, player) { + var color = get.color(event.card); + if (color == "none") return false; + var list = player.getStorage("tomoyo_zhengfeng_tomoyo"); + for (var obj of list) { + if (obj.target == event.player && color == obj.color) return true; } return false; }, - content(){ + content() { player.draw(); }, - intro:{ - mark(dialog,students,player){ - if(!students||!students.length) return '全校风纪良好!'; - var str=''; - for(var i of students){ - if(str.length>0) str+='
              '; - str+=get.translation(i.target); - str+=':'; - str+=get.translation(i.color); + intro: { + mark(dialog, students, player) { + if (!students || !students.length) return "全校风纪良好!"; + var str = ""; + for (var i of students) { + if (str.length > 0) str += "
              "; + str += get.translation(i.target); + str += ":"; + str += get.translation(i.color); } dialog.addText(str); }, }, }, - after:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return !player.hasHistory('useSkill',function(evt){ - return evt.skill=='tomoyo_zhengfeng'; + after: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return !player.hasHistory("useSkill", function (evt) { + return evt.skill == "tomoyo_zhengfeng"; }); }, - prompt:'整风:是否放弃使命?', - prompt2:'你可以减1点体力上限并失去〖武威〗,摸两张牌并回复1点体力,然后获得技能〖长誓〗。', - skillAnimation:true, - animationColor:'gray', - check(event,player){ - return (player.hp*1.1+player.countCards('h'))<3; + prompt: "整风:是否放弃使命?", + prompt2: + "你可以减1点体力上限并失去〖武威〗,摸两张牌并回复1点体力,然后获得技能〖长誓〗。", + skillAnimation: true, + animationColor: "gray", + check(event, player) { + return player.hp * 1.1 + player.countCards("h") < 3; }, - content(){ - 'step 0' - game.log(player,'放弃了身为学生会长的使命'); - player.awakenSkill('tomoyo_zhengfeng'); + content() { + "step 0"; + game.log(player, "放弃了身为学生会长的使命"); + player.awakenSkill("tomoyo_zhengfeng"); player.loseMaxHp(); - 'step 1' - player.removeSkills('tomoyo_wuwei'); - 'step 2' + "step 1"; + player.removeSkills("tomoyo_wuwei"); + "step 2"; player.draw(2); player.recover(); - 'step 3' - player.addSkills('tomoyo_changshi'); + "step 3"; + player.addSkills("tomoyo_changshi"); }, }, }, }, - tomoyo_changshi:{ - trigger:{ - global:['gainAfter','loseAsyncAfter'], + tomoyo_changshi: { + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - forced:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&event.getg(current).length>1&&player.inRangeOf(current); + forced: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && event.getg(current).length > 1 && player.inRangeOf(current) + ); }); }, - content(){ + content() { player.draw(); }, - group:'tomoyo_changshi_recover', - subSkill:{ - recover:{ - trigger:{global:'recoverAfter'}, - forced:true, - filter(event,player){ - return event.player.isAlive()&&player.inRangeOf(event.player); + group: "tomoyo_changshi_recover", + subSkill: { + recover: { + trigger: { global: "recoverAfter" }, + forced: true, + filter(event, player) { + return event.player.isAlive() && player.inRangeOf(event.player); }, - content(){ + content() { player.changeHujia(1); }, }, }, }, //天宫希优 - kiyu_yuling:{ - mod:{ - targetEnabled(card){ - var info=get.info(card); - if(!info||(info.type!='trick'&&info.type!='delay')) return; - if(info.range) return false; + kiyu_yuling: { + mod: { + targetEnabled(card) { + var info = get.info(card); + if (!info || (info.type != "trick" && info.type != "delay")) return; + if (info.range) return false; }, }, - trigger:{target:'useCardToTargeted'}, - forced:true, - charlotte:true, - filter(event,player){ - return event.card.name=='sha'&&event.player.countCards('he')>0; + trigger: { target: "useCardToTargeted" }, + forced: true, + charlotte: true, + filter(event, player) { + return event.card.name == "sha" && event.player.countCards("he") > 0; }, - logTarget:'player', - content(){ - trigger.player.chooseToDiscard('he',true,get.distance(trigger.player,player)); + logTarget: "player", + content() { + trigger.player.chooseToDiscard("he", true, get.distance(trigger.player, player)); }, - ai:{ - threaten:0.7, - effect:{ - target(card,player,target,current){ - if(card.name=='sha') return 0.7; + ai: { + threaten: 0.7, + effect: { + target(card, player, target, current) { + if (card.name == "sha") return 0.7; }, }, }, }, - kiyu_rexianyu:{ - trigger:{player:'phaseUseEnd'}, - charlotte:true, - unique:true, - filter(event,player){ - return !player.hasSkill('kiyu_rexianyu_round',null,null,false)&&player.hasHistory('useCard',function(evt){ - var type=get.type(evt.card); - if(type!='basic'&&type!='trick') return false; - return evt.getParent('phaseUse')==event; - }); + kiyu_rexianyu: { + trigger: { player: "phaseUseEnd" }, + charlotte: true, + unique: true, + filter(event, player) { + return ( + !player.hasSkill("kiyu_rexianyu_round", null, null, false) && + player.hasHistory("useCard", function (evt) { + var type = get.type(evt.card); + if (type != "basic" && type != "trick") return false; + return evt.getParent("phaseUse") == event; + }) + ); }, - async cost(event, trigger, player){ - const history=player.getHistory('useCard',function(evt){ - var type=get.type(evt.card); - if(type!='basic'&&type!='trick') return false; - return evt.getParent('phaseUse')==trigger; + async cost(event, trigger, player) { + const history = player.getHistory("useCard", function (evt) { + var type = get.type(evt.card); + if (type != "basic" && type != "trick") return false; + return evt.getParent("phaseUse") == trigger; }); - const list=[]; - for(var i=0;i0; + kiyu_xianyu: { + trigger: { global: "phaseUseBegin" }, + charlotte: true, + round: 1, + filter(event, player) { + return event.player.countCards("h") > 0; }, - logTarget:'player', - check(event,player){ - var target=event.player; - var next=target.next; - if(target.getSeatNum()>next.getSeatNum()) return true; - if(target.countCards('h')<4&&target.countCards('h',function(card){ - return target.hasUseTarget(card,null,true); - })<2) return false; + logTarget: "player", + check(event, player) { + var target = event.player; + var next = target.next; + if (target.getSeatNum() > next.getSeatNum()) return true; + if ( + target.countCards("h") < 4 && + target.countCards("h", function (card) { + return target.hasUseTarget(card, null, true); + }) < 2 + ) + return false; return true; }, - content(){ - 'step 0' - var target=trigger.player,cards=target.getCards('h'); - var next=player.chooseToMove('先预:预测'+get.translation(target)+'使用牌的顺序',true); - next.set('list',[ - [get.translation(target)+'的手牌',cards] - ]); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0); - var target=_status.event.getTrigger().player; - cards.sort(function(a,b){ - return get.order(b,target)-get.order(a,target); + content() { + "step 0"; + var target = trigger.player, + cards = target.getCards("h"); + var next = player.chooseToMove( + "先预:预测" + get.translation(target) + "使用牌的顺序", + true + ); + next.set("list", [[get.translation(target) + "的手牌", cards]]); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0); + var target = _status.event.getTrigger().player; + cards.sort(function (a, b) { + return get.order(b, target) - get.order(a, target); }); return [cards]; }); - 'step 1' - if(result.bool){ - var list=result.moved[0]; - player.storage.kiyu_xianyu_lastrun=list; - player.addTempSkill('kiyu_xianyu_lastrun',list); + "step 1"; + if (result.bool) { + var list = result.moved[0]; + player.storage.kiyu_xianyu_lastrun = list; + player.addTempSkill("kiyu_xianyu_lastrun", list); } }, - subSkill:{ - lastrun:{ - trigger:{global:'phaseUseAfter'}, - forced:true, - charlotte:true, - onremove:true, - content(){ - var num=0,index=-1,target=trigger.player; - var cards=player.getStorage('kiyu_xianyu_lastrun'); - var history=target.getHistory('useCard',function(event){ - return event.getParent('phaseUse')==trigger; + subSkill: { + lastrun: { + trigger: { global: "phaseUseAfter" }, + forced: true, + charlotte: true, + onremove: true, + content() { + var num = 0, + index = -1, + target = trigger.player; + var cards = player.getStorage("kiyu_xianyu_lastrun"); + var history = target.getHistory("useCard", function (event) { + return event.getParent("phaseUse") == trigger; }); - for(var evt of history){ - var goon=false; - for(var card of evt.cards){ - var index2=cards.indexOf(card); - if(index2>index){ - goon=true; - index=index2; + for (var evt of history) { + var goon = false; + for (var card of evt.cards) { + var index2 = cards.indexOf(card); + if (index2 > index) { + goon = true; + index = index2; } } - if(goon) num++; + if (goon) num++; } - if(num>0){ - num=Math.min(3,num); + if (num > 0) { + num = Math.min(3, num); player.draw(num); - if(target.isIn()){ - target.addTempSkill('kiyu_xianyu_effect'); - target.addMark('kiyu_xianyu_effect',num,false); + if (target.isIn()) { + target.addTempSkill("kiyu_xianyu_effect"); + target.addMark("kiyu_xianyu_effect", num, false); } } }, }, - effect:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('kiyu_xianyu_effect'); + effect: { + charlotte: true, + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("kiyu_xianyu_effect"); }, }, }, }, }, //樱庭星罗 - seira_xinghui:{ - trigger:{player:'phaseZhunbeiBegin'}, - check(event,player){ - return !player.getExpansions('seira_xinghui').length; + seira_xinghui: { + trigger: { player: "phaseZhunbeiBegin" }, + check(event, player) { + return !player.getExpansions("seira_xinghui").length; }, - content(){ - 'step 0' + content() { + "step 0"; game.delayx(); - 'step 1' - if(get.isLuckyStar(player)){ - event.num=6; + "step 1"; + if (get.isLuckyStar(player)) { + event.num = 6; player.throwDice(6); - } - else player.throwDice(); - 'step 2' - var cards=get.cards(num); - event.cards=cards; + } else player.throwDice(); + "step 2"; + var cards = get.cards(num); + event.cards = cards; game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('prompt','星辉:选择要作为“星屑”的牌(先选择的在上)'); - next.set('list',[ - ['置于武将牌上',cards], - ['置入弃牌堆'], - ]); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var top=[]; - var judges=player.getCards('j'); - var stopped=false; - if(!player.hasWuxie()){ - for(var i=0;i0; + subSkill: { + hoshikuzu: { + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + filter(event, player) { + return player.getExpansions("seira_xinghui").length > 0; }, - content(){ + content() { trigger.num++; - game.log(player,'造成了','#y暴击伤害'); + game.log(player, "造成了", "#y暴击伤害"); }, - group:['seira_xinghui_draw','seira_xinghui_judge'], + group: ["seira_xinghui_draw", "seira_xinghui_judge"], }, - draw:{ - trigger:{player:'drawBefore'}, - forced:true, - filter(event,player){ - return player.getExpansions('seira_xinghui').length>0; + draw: { + trigger: { player: "drawBefore" }, + forced: true, + filter(event, player) { + return player.getExpansions("seira_xinghui").length > 0; }, - content(){ - var cards=player.getExpansions('seira_xinghui'); - var num=Math.min(cards.length,trigger.num); - trigger.num-=num; - player.gain(cards.slice(0,num),'draw'); - if(trigger.num==0) trigger.cancel(); + content() { + var cards = player.getExpansions("seira_xinghui"); + var num = Math.min(cards.length, trigger.num); + trigger.num -= num; + player.gain(cards.slice(0, num), "draw"); + if (trigger.num == 0) trigger.cancel(); }, }, - judge:{ - trigger:{player:'judgeBegin'}, - forced:true, - filter(event,player){ - return player.getExpansions('seira_xinghui').length>0; + judge: { + trigger: { player: "judgeBegin" }, + forced: true, + filter(event, player) { + return player.getExpansions("seira_xinghui").length > 0; }, - content(){ - trigger.directresult=player.getExpansions('seira_xinghui')[0]; + content() { + trigger.directresult = player.getExpansions("seira_xinghui")[0]; }, }, }, }, - seira_yuanying:{ - enable:'phaseUse', - usable:1, - filterTarget:true, - selectTarget:2, - multitarget:true, - multiline:true, - line:{color:[253, 153, 182]}, - content(){ - game.filterPlayer().sortBySeat().forEach(function(current){ - if(!targets.includes(current)){ - current.removeSkills('seira_yinyuan'); - } - else{ - current.addSkills('seira_yinyuan'); - } - }); + seira_yuanying: { + enable: "phaseUse", + usable: 1, + filterTarget: true, + selectTarget: 2, + multitarget: true, + multiline: true, + line: { color: [253, 153, 182] }, + content() { + game.filterPlayer() + .sortBySeat() + .forEach(function (current) { + if (!targets.includes(current)) { + current.removeSkills("seira_yinyuan"); + } else { + current.addSkills("seira_yinyuan"); + } + }); game.delayx(); }, - ai:{ - order:1, - result:{target:1}, - expose:0.1, + ai: { + order: 1, + result: { target: 1 }, + expose: 0.1, }, - derivation:'seira_yinyuan', + derivation: "seira_yinyuan", }, - seira_yinyuan:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.hasSkill('seira_yinyuan',null,null,false)&&target.countCards('hej')>0; + seira_yinyuan: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return ( + target != player && + target.hasSkill("seira_yinyuan", null, null, false) && + target.countCards("hej") > 0 + ); }, - content(){ - player.gainPlayerCard(target,true,'hej'); + content() { + player.gainPlayerCard(target, true, "hej"); target.recover(); }, - mark:true, - intro:{content:'你的手牌对其他“姻缘者”可见。出牌阶段限一次,你可以获得一名其他“姻缘者”区域内的一张牌,然后其回复1点体力。'}, - ai:{ - order:9, - viewHandcard:true, - skillTagFilter(player,tag,arg){ - if(player==arg) return false; - return player.hasSkill('seira_yinyuan')&&arg.hasSkill('seira_yinyuan'); + mark: true, + intro: { + content: + "你的手牌对其他“姻缘者”可见。出牌阶段限一次,你可以获得一名其他“姻缘者”区域内的一张牌,然后其回复1点体力。", + }, + ai: { + order: 9, + viewHandcard: true, + skillTagFilter(player, tag, arg) { + if (player == arg) return false; + return player.hasSkill("seira_yinyuan") && arg.hasSkill("seira_yinyuan"); }, - result:{ - player(player,target){ - var effect=get.effect(target,{name:'shunshou_copy'},player,player); - if(target.isDamaged()){ - if(effect<0) effect/=2; - effect+=get.recoverEffect(target,player,player); + result: { + player(player, target) { + var effect = get.effect(target, { name: "shunshou_copy" }, player, player); + if (target.isDamaged()) { + if (effect < 0) effect /= 2; + effect += get.recoverEffect(target, player, player); } return effect; }, @@ -2243,7922 +2771,9598 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //派对浪客 - nsxingyun:{ - audio:2, - enable:'chooseToUse', - getSixiang(card){ - if(typeof card=='string') card={name:card}; - if(card.name=='shan') return '玄武'; - var type=get.type(card,null,false); - if(type=='delay') return '朱雀'; - if(get.tag(card,'damage')) return '白虎'; - if(get.tag(card,'recover')) return '玄武'; - if(type=='trick') return '青龙'; + nsxingyun: { + audio: 2, + enable: "chooseToUse", + getSixiang(card) { + if (typeof card == "string") card = { name: card }; + if (card.name == "shan") return "玄武"; + var type = get.type(card, null, false); + if (type == "delay") return "朱雀"; + if (get.tag(card, "damage")) return "白虎"; + if (get.tag(card, "recover")) return "玄武"; + if (type == "trick") return "青龙"; return false; }, - filter(event,player){ - if(player.hasSkill('nsxingyun_round')) return false; - var list=player.getStorage('nsxingyun'); - if(list.length>=4) return false; - for(var i of lib.inpile){ - var type=lib.skill.nsxingyun.getSixiang(i); - if(!type||list.includes(type)) continue; - if(event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) return true; + filter(event, player) { + if (player.hasSkill("nsxingyun_round")) return false; + var list = player.getStorage("nsxingyun"); + if (list.length >= 4) return false; + for (var i of lib.inpile) { + var type = lib.skill.nsxingyun.getSixiang(i); + if (!type || list.includes(type)) continue; + if (event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event)) + return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + return true; } } } return false; }, - chooseButton:{ - dialog(event,player){ - var map={青龙:[],朱雀:[],白虎:[],玄武:[]}; - var list=player.getStorage('nsxingyun'); - for(var i of lib.inpile){ - var type=lib.skill.nsxingyun.getSixiang(i); - if(!type||list.includes(type)) continue; - if(event.filterCard({name:i},player,event)) map[type].push([get.type2(i,false),'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard({name:i,nature:j},player,event)) map[type].push([get.type2(i,false),'',i,j]); + chooseButton: { + dialog(event, player) { + var map = { 青龙: [], 朱雀: [], 白虎: [], 玄武: [] }; + var list = player.getStorage("nsxingyun"); + for (var i of lib.inpile) { + var type = lib.skill.nsxingyun.getSixiang(i); + if (!type || list.includes(type)) continue; + if (event.filterCard({ name: i }, player, event)) + map[type].push([get.type2(i, false), "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: i, nature: j }, player, event)) + map[type].push([get.type2(i, false), "", i, j]); } } } - var dialog=['星陨','hidden']; - for(var i in map){ - if(map[i].length>0){ - dialog.push('
              '+i+'
              '); - dialog.push([map[i],'vcard']); + var dialog = ["星陨", "hidden"]; + for (var i in map) { + if (map[i].length > 0) { + dialog.push('
              ' + i + "
              "); + dialog.push([map[i], "vcard"]); } } - return ui.create.dialog.apply(ui.create,dialog); + return ui.create.dialog.apply(ui.create, dialog); }, - filter(button,player){ - return _status.event.getParent().filterCard({ - name:button.link[2], - nature:button.link[3], - },player,_status.event.getParent()); + filter(button, player) { + return _status.event.getParent().filterCard( + { + name: button.link[2], + nature: button.link[3], + }, + player, + _status.event.getParent() + ); }, - check(button){ - if(_status.event.getParent().type!='phase') return 1; - return _status.event.player.getUseValue({ - name:button.link[2], - nature:button.link[3], - },false); + check(button) { + if (_status.event.getParent().type != "phase") return 1; + return _status.event.player.getUseValue( + { + name: button.link[2], + nature: button.link[3], + }, + false + ); }, - backup(links,player){ + backup(links, player) { return { - selectCard:1, - filterCard:true, - popname:true, - position:'hs', - check(card){ - return 7-get.value(card); + selectCard: 1, + filterCard: true, + popname: true, + position: "hs", + check(card) { + return 7 - get.value(card); }, - viewAs:{name:links[0][2],nature:links[0][3]}, - precontent(){ - player.addTempSkill('nsxingyun_round'); + viewAs: { name: links[0][2], nature: links[0][3] }, + precontent() { + player.addTempSkill("nsxingyun_round"); }, - } + }; + }, + prompt(links, player) { + return ( + "将一张手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt(links,player){ - return '将一张手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - threaten:2.6, - order:1, - result:{player:1}, + ai: { + threaten: 2.6, + order: 1, + result: { player: 1 }, }, - group:'nsxingyun_clear', - derivation:['nsxingyun_faq','bazhen'], - subSkill:{ - backup:{}, - clear:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='nsxingyun_backup'&&event.cards.length==1 - &&lib.skill.nsxingyun.getSixiang(event.card)!=lib.skill.nsxingyun.getSixiang(event.cards[0])&&!player.getStorage('nsxingyun').includes(lib.skill.nsxingyun.getSixiang(event.card)); + group: "nsxingyun_clear", + derivation: ["nsxingyun_faq", "bazhen"], + subSkill: { + backup: {}, + clear: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter(event, player) { + return ( + event.skill == "nsxingyun_backup" && + event.cards.length == 1 && + lib.skill.nsxingyun.getSixiang(event.card) != + lib.skill.nsxingyun.getSixiang(event.cards[0]) && + !player + .getStorage("nsxingyun") + .includes(lib.skill.nsxingyun.getSixiang(event.card)) + ); }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(2); - player.markAuto('nsxingyun',[lib.skill.nsxingyun.getSixiang(trigger.card)]); - 'step 1' - if(player.getStorage('nsxingyun').length>=4) player.addSkills('bazhen'); + player.markAuto("nsxingyun", [lib.skill.nsxingyun.getSixiang(trigger.card)]); + "step 1"; + if (player.getStorage("nsxingyun").length >= 4) player.addSkills("bazhen"); }, }, - round:{ - charlotte:true, - onremove:true, + round: { + charlotte: true, + onremove: true, }, }, }, - nshanlang:{ - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return player.countCards('h')>0&&game.hasPlayer( - (current)=>player!=current&&player.canCompare(current) + nshanlang: { + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer((current) => player != current && player.canCompare(current)) ); }, - async cost(event, trigger, player){ - const goon=player.hasCard(function(card){ - return get.value(card)<=7; - },'h'); - event.result = await player.chooseTarget([1,3],get.prompt('nshanlang'),'和至多三名角色进行拼点',function(card,player,target){ - return target!=player&&player.canCompare(target); - }).set('ai',function(target){ - if(!_status.event.goon) return false; - var att=get.attitude(_status.event.player,target); - if(att>=0) return 0; - if(target.hasSkillTag('noh')) att/=3; - return -att/Math.sqrt(target.countCards('h')); - }).set('goon',goon).forResult(); + async cost(event, trigger, player) { + const goon = player.hasCard(function (card) { + return get.value(card) <= 7; + }, "h"); + event.result = await player + .chooseTarget( + [1, 3], + get.prompt("nshanlang"), + "和至多三名角色进行拼点", + function (card, player, target) { + return target != player && player.canCompare(target); + } + ) + .set("ai", function (target) { + if (!_status.event.goon) return false; + var att = get.attitude(_status.event.player, target); + if (att >= 0) return 0; + if (target.hasSkillTag("noh")) att /= 3; + return -att / Math.sqrt(target.countCards("h")); + }) + .set("goon", goon) + .forResult(); }, - content(){ - 'step 0' - event.max_num=0; + content() { + "step 0"; + event.max_num = 0; targets.sortBySeat(); - player.chooseToCompare(targets).callback=lib.skill.nshanlang.callback; - 'step 1' - if(event.target){ - player.chooseBool('是否令'+get.translation(target)+'获得一张牌?').set('goon',get.attitude(player,target)>0).set('ai',()=>_status.event.goon); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=get.cardPile2(function(card){ + player.chooseToCompare(targets).callback = lib.skill.nshanlang.callback; + "step 1"; + if (event.target) { + player + .chooseBool("是否令" + get.translation(target) + "获得一张牌?") + .set("goon", get.attitude(player, target) > 0) + .set("ai", () => _status.event.goon); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = get.cardPile2(function (card) { return !lib.skill.nsxingyun.getSixiang(card); }); - if(card) target.gain(card,'gain2'); + if (card) target.gain(card, "gain2"); } }, - callback(){ - var list=[[player,event.num1],[target,event.num2]],evt=event.getParent(2); - for(var i of list){ - if(i[1]>evt.max_num){ - evt.max_num=i[1]; - evt.target=i[0]; - } - else if(evt.target&&i[1]==evt.max_num&&i[0]!=evt.target){ + callback() { + var list = [ + [player, event.num1], + [target, event.num2], + ], + evt = event.getParent(2); + for (var i of list) { + if (i[1] > evt.max_num) { + evt.max_num = i[1]; + evt.target = i[0]; + } else if (evt.target && i[1] == evt.max_num && i[0] != evt.target) { delete evt.target; } } }, }, //钟离牧 - nskuanhuai:{ - trigger:{player:'phaseUseBegin'}, - content(){ - 'step 0' - var card=get.discardPile(function(card){ - return get.type(card)!='basic'; + nskuanhuai: { + trigger: { player: "phaseUseBegin" }, + content() { + "step 0"; + var card = get.discardPile(function (card) { + return get.type(card) != "basic"; }); - if(card) player.gain(card,'gain2'); - 'step 1' - player.addTempSkill('nskuanhuai_blocker','phaseUseAfter'); - player.addTempSkill('nskuanhuai_effect'); + if (card) player.gain(card, "gain2"); + "step 1"; + player.addTempSkill("nskuanhuai_blocker", "phaseUseAfter"); + player.addTempSkill("nskuanhuai_effect"); }, - subSkill:{ - blocker:{ - charlotte:true, - mod:{ - cardEnabled(card){ - if(get.type(card)=='basic') return false; + subSkill: { + blocker: { + charlotte: true, + mod: { + cardEnabled(card) { + if (get.type(card) == "basic") return false; }, - cardSavable(card){ - if(get.type(card)=='basic') return false; + cardSavable(card) { + if (get.type(card) == "basic") return false; }, }, }, - effect:{ - trigger:{player:'phaseDiscardEnd'}, - charlotte:true, - popup:false, - filter(event,player){ - return player.hasHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent('phaseDiscard')!=event) return false; - for(var i of evt.cards2){ - if(get.type(i,false)=='basic'&&get.position(i,true)=='d'&&player.hasUseTarget(i)) return true; + effect: { + trigger: { player: "phaseDiscardEnd" }, + charlotte: true, + popup: false, + filter(event, player) { + return player.hasHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent("phaseDiscard") != event) + return false; + for (var i of evt.cards2) { + if ( + get.type(i, false) == "basic" && + get.position(i, true) == "d" && + player.hasUseTarget(i) + ) + return true; } return false; }); }, - content(){ - 'step 0' - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent('phaseDiscard')!=trigger) return false; - for(var i of evt.cards2){ - if(get.type(i,false)=='basic'&&get.position(i,true)=='d') cards.push(i); + content() { + "step 0"; + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent("phaseDiscard") != trigger) + return false; + for (var i of evt.cards2) { + if (get.type(i, false) == "basic" && get.position(i, true) == "d") + cards.push(i); } return false; }); - event.cards=cards; - 'step 1' - var cards2=event.cards.filter(function(i){ - return get.position(i,true)=='d'&&player.hasUseTarget(i); + event.cards = cards; + "step 1"; + var cards2 = event.cards.filter(function (i) { + return get.position(i, true) == "d" && player.hasUseTarget(i); }); - if(cards2.length){ - player.chooseButton(['宽怀:是否使用其中一张牌?',cards2]); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.links[0]; + if (cards2.length) { + player.chooseButton(["宽怀:是否使用其中一张牌?", cards2]); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.links[0]; cards.remove(card); - player.chooseUseTarget(card,true); - if(cards.length>0) event.goto(1); + player.chooseUseTarget(card, true); + if (cards.length > 0) event.goto(1); } }, }, }, }, - nsdingbian:{ - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - if(player!=_status.currentPhase) return false; - return get.type(event.card)!='basic'; + nsdingbian: { + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + if (player != _status.currentPhase) return false; + return get.type(event.card) != "basic"; }, - content(){ - 'step 0' - player.addTempSkill('nsdingbian_mark'); - player.addMark('nsdingbian_mark',1,false); - var storage=player.getStorage('nsdingbian_ignore'); - var goon=false; - for(var i of lib.inpile){ - if(get.type(i)=='basic'&&!storage.includes(i)){ - goon=true; + content() { + "step 0"; + player.addTempSkill("nsdingbian_mark"); + player.addMark("nsdingbian_mark", 1, false); + var storage = player.getStorage("nsdingbian_ignore"); + var goon = false; + for (var i of lib.inpile) { + if (get.type(i) == "basic" && !storage.includes(i)) { + goon = true; break; } } - if(goon) player.chooseControl().set('choiceList',[ - '从牌堆中获得一张基本牌', - '令一种基本牌于本回合内不计入手牌上限', - ]).set('prompt','定边:请选择一项').set('ai',function(){ - var player=_status.event.player; - var list=['tao','shan'],list2=player.getStorage('nsdingbian_ignore'); - list.removeArray(list2); - if(!list.length) return 0; - var num1=player.countCards('hs',function(card){ - return get.type(card)!='basic'&&player.hasValueTarget(card,null,true); - }),num2=player.getHandcardLimit(); - if(player.countCards('h',list)<=num2-num1) return 0; - return 1; - }); - else event._result={index:0}; - 'step 1' - if(result.index==0){ - var card=get.cardPile2(function(card){ - return get.type(card,false)=='basic'; + if (goon) + player + .chooseControl() + .set("choiceList", [ + "从牌堆中获得一张基本牌", + "令一种基本牌于本回合内不计入手牌上限", + ]) + .set("prompt", "定边:请选择一项") + .set("ai", function () { + var player = _status.event.player; + var list = ["tao", "shan"], + list2 = player.getStorage("nsdingbian_ignore"); + list.removeArray(list2); + if (!list.length) return 0; + var num1 = player.countCards("hs", function (card) { + return ( + get.type(card) != "basic" && + player.hasValueTarget(card, null, true) + ); + }), + num2 = player.getHandcardLimit(); + if (player.countCards("h", list) <= num2 - num1) return 0; + return 1; + }); + else event._result = { index: 0 }; + "step 1"; + if (result.index == 0) { + var card = get.cardPile2(function (card) { + return get.type(card, false) == "basic"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); event.finish(); - } - else{ - var list=[],storage=player.getStorage('nsdingbian_ignore'); - for(var i of lib.inpile){ - if(get.type(i)=='basic'&&!storage.includes(i)){ + } else { + var list = [], + storage = player.getStorage("nsdingbian_ignore"); + for (var i of lib.inpile) { + if (get.type(i) == "basic" && !storage.includes(i)) { list.push(i); } } - player.chooseButton(['令一种基本牌于本回合内不计入手牌上限',[list,'vcard']],true).set('ai',function(button){ - var name=button.link[2],player=_status.event.player; - if(name=='sha') return 0; - var cards=player.getCards('h',name); - if(!cards.length) return 0; - return get.value(cards,player); - }); + player + .chooseButton(["令一种基本牌于本回合内不计入手牌上限", [list, "vcard"]], true) + .set("ai", function (button) { + var name = button.link[2], + player = _status.event.player; + if (name == "sha") return 0; + var cards = player.getCards("h", name); + if (!cards.length) return 0; + return get.value(cards, player); + }); } - 'step 2' - player.markAuto('nsdingbian_ignore',[result.links[0][2]]); + "step 2"; + player.markAuto("nsdingbian_ignore", [result.links[0][2]]); }, - subSkill:{ - mark:{ - onremove(player){ + subSkill: { + mark: { + onremove(player) { delete player.storage.nsdingbian_mark; delete player.storage.nsdingbian_ignore; }, - mod:{ - maxHandcard:(player,num)=>num-player.countMark('nsdingbian_mark'), - ignoredHandcard(card,player){ - if(player.getStorage('nsdingbian_ignore').includes(get.name(card,player))){ + mod: { + maxHandcard: (player, num) => num - player.countMark("nsdingbian_mark"), + ignoredHandcard(card, player) { + if (player.getStorage("nsdingbian_ignore").includes(get.name(card, player))) { return true; } }, - cardDiscardable(card,player,name){ - if(name=='phaseDiscard'&&player.getStorage('nsdingbian_ignore').includes(get.name(card,player))){ + cardDiscardable(card, player, name) { + if ( + name == "phaseDiscard" && + player.getStorage("nsdingbian_ignore").includes(get.name(card, player)) + ) { return false; } }, }, - intro:{content:'手牌上限-#'}, + intro: { content: "手牌上限-#" }, }, }, }, //李密 - nstuilun:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.hp>1&&player.countCards('h')>1&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'nstuilun'); - },'h'); + nstuilun: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player.hp > 1 && + player.countCards("h") > 1 && + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "nstuilun"); + }, "h") + ); }, - prompt2:'失去任意点体力(至多失去至1点)并弃置任意张手牌(至多弃置至一张)。', - check(event,player){ - if(game.hasPlayer(function(current){ - return current!=player&¤t.hp>=player.hp; - })) return true; + prompt2: "失去任意点体力(至多失去至1点)并弃置任意张手牌(至多弃置至一张)。", + check(event, player) { + if ( + game.hasPlayer(function (current) { + return current != player && current.hp >= player.hp; + }) + ) + return true; return false; }, - content(){ - 'step 0' - if(player.hp==2) event._result={index:0}; - else{ - var list=[]; - for(var i=1;i1&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'nstuilun'); - },'h')){ - player.chooseToDiscard('h',true,[1,player.countCards('h')-1]); - } - else game.delayx(); - 'step 3' - player.addTempSkill('nstuilun_effect',{player:'phaseBeginStart'}); + "step 1"; + player.loseHp(1 + result.index); + "step 2"; + if ( + player.countCards("h") > 1 && + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "nstuilun"); + }, "h") + ) { + player.chooseToDiscard("h", true, [1, player.countCards("h") - 1]); + } else game.delayx(); + "step 3"; + player.addTempSkill("nstuilun_effect", { + player: "phaseBeginStart", + }); }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{global:'phaseBegin'}, - forced:true, - popup:false, - filter(event,player){ - return player.hp0&&player.countCards('h') 0 && player.countCards("h") < event.player.countCards("h")) + ); }, - content(){ - 'step 0' - if(player.hp=get.effect(target,{name:'losehp'},player,player)) return 0; - return 1; - }); - } - else event.goto(3); - 'step 2' - if(result.index==0) target.recover(); + content() { + "step 0"; + if (player.hp < trigger.player.hp) { + player + .chooseTarget("退论:是否令一名角色回复或失去1点体力?") + .set("ai", function (target) { + var eff = get.effect(target, { name: "losehp" }, player, player); + if (target.isDamaged()) + eff = Math.max(eff, get.recoverEffect(target, player, player)); + return eff; + }); + } else event.goto(3); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("nstuilun_effect", target); + if (target.isHealthy()) event._result = { index: 1 }; + else + player + .chooseControl("回复1点体力", "失去1点体力") + .set("prompt", "令" + get.translation(target) + "…") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + if ( + get.recoverEffect(target, player, player) >= + get.effect(target, { name: "losehp" }, player, player) + ) + return 0; + return 1; + }); + } else event.goto(3); + "step 2"; + if (result.index == 0) target.recover(); else target.loseHp(); - 'step 3' - if(trigger.player.countCards('h')>player.countCards('h')){ - var str=get.cnNumber(player.hp); - player.chooseTarget('退论:是否令一名角色摸一张牌或弃置一张牌?').set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0||target.countCards('he')==0) return get.effect(target,{name:'draw'},player,player); - return get.effect(target,{name:'guohe_copy2'},target,player); - }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('nstuilun_effect',target); - if(!target.countCards('he')) event._result={index:0}; - else player.chooseControl('摸一张牌','弃置一张牌').set('prompt','令'+get.translation(target)+'…').set('ai',function(player){ - var evt=_status.event; - return get.attitude(evt.player,evt.getParent().target)>0?0:1; - }); - } - else event.finish(); - 'step 5' - if(result.index==0) target.draw(); - else target.chooseToDiscard('he',true); + "step 3"; + if (trigger.player.countCards("h") > player.countCards("h")) { + var str = get.cnNumber(player.hp); + player + .chooseTarget("退论:是否令一名角色摸一张牌或弃置一张牌?") + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0 || target.countCards("he") == 0) + return get.effect(target, { name: "draw" }, player, player); + return get.effect(target, { name: "guohe_copy2" }, target, player); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("nstuilun_effect", target); + if (!target.countCards("he")) event._result = { index: 0 }; + else + player + .chooseControl("摸一张牌", "弃置一张牌") + .set("prompt", "令" + get.translation(target) + "…") + .set("ai", function (player) { + var evt = _status.event; + return get.attitude(evt.player, evt.getParent().target) > 0 + ? 0 + : 1; + }); + } else event.finish(); + "step 5"; + if (result.index == 0) target.draw(); + else target.chooseToDiscard("he", true); }, }, }, }, //阮籍 - nsshizui:{ - trigger:{target:'useCardToTargeted'}, - usable:1, - filter(event,player){ - var type=get.type(event.card,null,false); - return (type=='basic'||type=='trick')&&player.countCards('he')>0&&player.hasUseTarget({name:'jiu'},null,true); + nsshizui: { + trigger: { target: "useCardToTargeted" }, + usable: 1, + filter(event, player) { + var type = get.type(event.card, null, false); + return ( + (type == "basic" || type == "trick") && + player.countCards("he") > 0 && + player.hasUseTarget({ name: "jiu" }, null, true) + ); }, - async cost(event,trigger,player){ - var suit=get.suit(trigger.card),cards=trigger.cards.filterInD(); - var str='弃置一张牌并视为使用一张【酒】'; - if(lib.suit.includes(suit)) str+=(';若弃置'+get.translation(suit)+'牌,则'+get.translation(trigger.card)+'对你无效'); - if(cards.length) str+=(';若弃置♣牌则获得'+get.translation(cards)); - str+='。'; - var next=player.chooseToDiscard('he', get.prompt('nsshizui'), str, 'chooseonly'); - next.set('val1',cards.length?get.value(cards,player):0); - next.set('val2',-get.effect(player,trigger.card,trigger.player,player)); - next.set('suit',suit); - next.set('ai',function(card){ - var base=2,suit=get.suit(card); - if(suit=='club') base+=_status.event.val1; - if(suit==_status.event.suit) base+=_status.event.val2; - return base-get.value(card); + async cost(event, trigger, player) { + var suit = get.suit(trigger.card), + cards = trigger.cards.filterInD(); + var str = "弃置一张牌并视为使用一张【酒】"; + if (lib.suit.includes(suit)) + str += + ";若弃置" + + get.translation(suit) + + "牌,则" + + get.translation(trigger.card) + + "对你无效"; + if (cards.length) str += ";若弃置♣牌则获得" + get.translation(cards); + str += "。"; + var next = player.chooseToDiscard("he", get.prompt("nsshizui"), str, "chooseonly"); + next.set("val1", cards.length ? get.value(cards, player) : 0); + next.set("val2", -get.effect(player, trigger.card, trigger.player, player)); + next.set("suit", suit); + next.set("ai", function (card) { + var base = 2, + suit = get.suit(card); + if (suit == "club") base += _status.event.val1; + if (suit == _status.event.suit) base += _status.event.val2; + return base - get.value(card); }); event.result = await next.forResult(); }, - content(){ - 'step 0' - event.suit1=get.suit(cards[0],player); + content() { + "step 0"; + event.suit1 = get.suit(cards[0], player); player.discard(cards); - player.chooseUseTarget('jiu',true); - 'step 1' - var suit1=event.suit1,suit2=get.suit(trigger.card,false); - if(suit1==suit2&&lib.suit.includes(suit1)) trigger.excluded.add(player); - if(suit1=='club'){ - var cards=trigger.cards.filterInD(); - if(cards.length>0) player.gain(cards,'gain2'); + player.chooseUseTarget("jiu", true); + "step 1"; + var suit1 = event.suit1, + suit2 = get.suit(trigger.card, false); + if (suit1 == suit2 && lib.suit.includes(suit1)) trigger.excluded.add(player); + if (suit1 == "club") { + var cards = trigger.cards.filterInD(); + if (cards.length > 0) player.gain(cards, "gain2"); } }, }, - nsxiaoye:{ - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - return player.hasHistory('useCard',function(evt){ - return evt.card.name=='jiu'; - })&&event.player.hasHistory('useCard',function(evt){ - return (evt.card.name=='sha'||get.type(evt.card)=='trick')&&player.hasUseTarget({ - name:evt.card.name, - nature:evt.card.nature, - isCard:true, - }); - }) + nsxiaoye: { + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player.hasHistory("useCard", function (evt) { + return evt.card.name == "jiu"; + }) && + event.player.hasHistory("useCard", function (evt) { + return ( + (evt.card.name == "sha" || get.type(evt.card) == "trick") && + player.hasUseTarget({ + name: evt.card.name, + nature: evt.card.nature, + isCard: true, + }) + ); + }) + ); }, - async cost(event,trigger,player){ - const list=[]; - trigger.player.getHistory('useCard',function(evt){ - if(evt.card.name!='sha'&&get.type(evt.card)!='trick') return; - if(evt.card.name=='sha'&&evt.card.nature) list.add('sha:'+evt.card.nature); + async cost(event, trigger, player) { + const list = []; + trigger.player.getHistory("useCard", function (evt) { + if (evt.card.name != "sha" && get.type(evt.card) != "trick") return; + if (evt.card.name == "sha" && evt.card.nature) list.add("sha:" + evt.card.nature); else list.add(evt.card.name); }); - for(let i=0;i1||player.countCards('hs',['tao','jiu'])) return 1; - if(!ui.selected.targets.length){ - if(target!=player) return 0; - if(player.hasSha()) return 1; + ai: { + order: 3.05, + result: { + player(player, target) { + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (player.hp > 1 || player.countCards("hs", ["tao", "jiu"])) return 1; + if (!ui.selected.targets.length) { + if (target != player) return 0; + if (player.hasSha()) return 1; return 0; } - if(ui.selected.targets.length>1&&!target.hasSha()) return 0; + if (ui.selected.targets.length > 1 && !target.hasSha()) return 0; return 1; }, }, }, }, - tenzen_fenghuan:{ - trigger:{global:'useCardAfter'}, - filter(event,player){ - if(player==event.player||event.targets.length!=1||event.targets[0]!=player||!event.player.isIn()|| - (event.card.name!='sha'&&(get.type(event.card,null,false)!='trick'||!get.tag(event.card,'damage')))) return false; - if(!player.canUse({ - name:event.card.name, - nature:event.card.nature, - isCard:true, - },event.player,false)) return false; - var num=get.number(event.card); - if(typeof num!='number') return false; - num*=2; - var hs=player.getCards('he'); - for(var i of hs){ - num-=get.number(i); - if(num<=0) return true; + tenzen_fenghuan: { + trigger: { global: "useCardAfter" }, + filter(event, player) { + if ( + player == event.player || + event.targets.length != 1 || + event.targets[0] != player || + !event.player.isIn() || + (event.card.name != "sha" && + (get.type(event.card, null, false) != "trick" || !get.tag(event.card, "damage"))) + ) + return false; + if ( + !player.canUse( + { + name: event.card.name, + nature: event.card.nature, + isCard: true, + }, + event.player, + false + ) + ) + return false; + var num = get.number(event.card); + if (typeof num != "number") return false; + num *= 2; + var hs = player.getCards("he"); + for (var i of hs) { + num -= get.number(i); + if (num <= 0) return true; } return false; }, - async cost(event, trigger, player){ - const num=get.number(trigger.card)*2, card = { - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - }; - event.result = await player.chooseToDiscard('he',get.prompt('tenzen_fenghuan',trigger.player),'弃置任意张点数之和不小于'+num+'的牌,然后视为对其使用一张'+get.translation(card),'chooseonly').set('selectCard',function(){ - var cards=ui.selected.cards,num=_status.event.cardNumber; - for(var i of cards){ - num-=get.number(i); - if(num<=0) return [cards.length,cards.length+1]; - } - return [cards.length+1,cards.length+1]; - }).set('cardNumber',num).set('effect',get.effect(trigger.player,card,player,player)).set('ai',function(card){ - var eff=_status.event.effect; - if(eff<=0) return 0; - for(var i of ui.selected.cards) eff-=get.value(i)/Math.sqrt(get.number(i)/3); - return eff-get.value(card)/Math.sqrt(get.number(card)/3); - }).forResult(); + async cost(event, trigger, player) { + const num = get.number(trigger.card) * 2, + card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + }; + event.result = await player + .chooseToDiscard( + "he", + get.prompt("tenzen_fenghuan", trigger.player), + "弃置任意张点数之和不小于" + + num + + "的牌,然后视为对其使用一张" + + get.translation(card), + "chooseonly" + ) + .set("selectCard", function () { + var cards = ui.selected.cards, + num = _status.event.cardNumber; + for (var i of cards) { + num -= get.number(i); + if (num <= 0) return [cards.length, cards.length + 1]; + } + return [cards.length + 1, cards.length + 1]; + }) + .set("cardNumber", num) + .set("effect", get.effect(trigger.player, card, player, player)) + .set("ai", function (card) { + var eff = _status.event.effect; + if (eff <= 0) return 0; + for (var i of ui.selected.cards) + eff -= get.value(i) / Math.sqrt(get.number(i) / 3); + return eff - get.value(card) / Math.sqrt(get.number(card) / 3); + }) + .forResult(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await player.discard(event.cards); - var card={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - },target=trigger.player; - if(target.isIn()&&player.canUse(card,target,false)) await player.useCard(card,target,false); + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + }, + target = trigger.player; + if (target.isIn() && player.canUse(card, target, false)) + await player.useCard(card, target, false); }, }, - tenzen_retianquan:{ - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return event.card.name=='sha'&&(player.hp>0||player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'tenzen_retianquan'); - },'he')); + tenzen_retianquan: { + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return ( + event.card.name == "sha" && + (player.hp > 0 || + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "tenzen_retianquan"); + }, "he")) + ); }, - logTarget:'target', - usable:1, - check(event,player){ - if(get.attitude(player,event.target)>=0) return false; - if(player.hp>player.maxHp/2) return true; - if(player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'tenzen_retianquan')&&get.value(card)<6; - },'he')) return true; + logTarget: "target", + usable: 1, + check(event, player) { + if (get.attitude(player, event.target) >= 0) return false; + if (player.hp > player.maxHp / 2) return true; + if ( + player.hasCard(function (card) { + return ( + lib.filter.cardDiscardable(card, player, "tenzen_retianquan") && + get.value(card) < 6 + ); + }, "he") + ) + return true; return true; }, - prompt2:'你可失去1点体力或弃置一张牌,展示牌堆顶的三张牌(若你的体力值小于体力上限的50%,则改为展示五张牌)。每有一张基本牌,其所需使用的【闪】的数量便+1。然后若此牌造成过伤害,则你获得展示牌中的所有非基本牌。', - content(){ - 'step 0' - player.chooseToDiscard('弃置一张牌,或点「取消」失去1点体力','he').set('goon',(player.hp>player.maxHp/2)).set('ai',function(card){ - var val=get.value(card); - if(_status.event.goon) return 0.1-val; - return 6-val; - }); - 'step 1' - if(!result.bool) player.loseHp(); - 'step 2' - var cards=get.cards(player.hp<=player.maxHp/2?5:3); - player.showCards(cards,get.translation(player)+'发动了【天全】'); - game.cardsGotoOrdering(cards).relatedEvent=trigger.getParent(); - var num=cards.filter(function(card){ - return get.type(card,false)=='basic'; + prompt2: + "你可失去1点体力或弃置一张牌,亮出牌堆顶的三张牌(若你的体力值小于体力上限的50%,则改为展示五张牌)。每有一张基本牌,其所需使用的【闪】的数量便+1。然后若此牌造成过伤害,则你获得展示牌中的所有非基本牌。", + content() { + "step 0"; + player + .chooseToDiscard("弃置一张牌,或点「取消」失去1点体力", "he") + .set("goon", player.hp > player.maxHp / 2) + .set("ai", function (card) { + var val = get.value(card); + if (_status.event.goon) return 0.1 - val; + return 6 - val; + }); + "step 1"; + if (!result.bool) player.loseHp(); + "step 2"; + var cards = get.cards(player.hp <= player.maxHp / 2 ? 5 : 3); + player.showCards(cards, get.translation(player) + "发动了【天全】"); + game.cardsGotoOrdering(cards).relatedEvent = trigger.getParent(); + var num = cards.filter(function (card) { + return get.type(card, false) == "basic"; }).length; - if(num){ - if(trigger.card.name=='sha'){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ - map[id].shanRequired+=num; - } - else{ - map[id].shanRequired=1+num; + if (num) { + if (trigger.card.name == "sha") { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { + map[id].shanRequired += num; + } else { + map[id].shanRequired = 1 + num; } } } - if(num<5){ - var next=game.createEvent('tenzen_retianqua_gain'); - next.cards=cards; - next.player=player; + if (num < 5) { + var next = game.createEvent("tenzen_retianqua_gain"); + next.cards = cards; + next.player = player; event.next.remove(next); trigger.getParent().after.push(next); - next.setContent(function(){ - if(player.getHistory('sourceDamage',function(evt){ - return evt.card==event.parent.card; - }).length>0) player.gain(cards.filter(function(card){ - return get.type(card,false)!='basic'; - }),'gain2'); + next.setContent(function () { + if ( + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.parent.card; + }).length > 0 + ) + player.gain( + cards.filter(function (card) { + return get.type(card, false) != "basic"; + }), + "gain2" + ); }); } }, }, - satomi_luodao:{ - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - filter(event,player){ - return event.card.name=='sha'&&event.target.countCards('h')>0; + satomi_luodao: { + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + filter(event, player) { + return event.card.name == "sha" && event.target.countCards("h") > 0; }, - content(){ - 'step 0' - var target=trigger.target; - event.target=target; - target.showHandcards(get.translation(player)+'对'+get.translation(target)+'发动了【落刀】'); - 'step 1' - if(target.hasCard(function(card){ - return get.name(card,target)=='shan'; - },'h')){ - player.discardPlayerCard(target,true,'h','visible').set('filterButton',function(button){ - return get.name(button.link)=='shan'; - }); - } - else if(player.countCards('he')>0) player.chooseToDiscard('he',true); + content() { + "step 0"; + var target = trigger.target; + event.target = target; + target.showHandcards( + get.translation(player) + "对" + get.translation(target) + "发动了【落刀】" + ); + "step 1"; + if ( + target.hasCard(function (card) { + return get.name(card, target) == "shan"; + }, "h") + ) { + player + .discardPlayerCard(target, true, "h", "visible") + .set("filterButton", function (button) { + return get.name(button.link) == "shan"; + }); + } else if (player.countCards("he") > 0) player.chooseToDiscard("he", true); }, }, - satomi_daohai:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.hasHistory('lose',function(evt){ - return evt.type=='discard'&&evt.cards2.length>0; - })&&player.hasUseTarget({name:'wugu'}); + satomi_daohai: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player.hasHistory("lose", function (evt) { + return evt.type == "discard" && evt.cards2.length > 0; + }) && player.hasUseTarget({ name: "wugu" }) + ); }, - check(event,player){ - return player.getUseValue({name:'wugu'})+player.getUseValue({name:'lebu'})>0; + check(event, player) { + return player.getUseValue({ name: "wugu" }) + player.getUseValue({ name: "lebu" }) > 0; }, - content(){ - 'step 0' - player.chooseUseTarget('wugu',true); - 'step 1' - if(result.bool){ - var cards=[]; - player.getHistory('gain',function(evt){ - if(evt.getParent().name=='wugu'&&evt.getParent(4)==event){ + content() { + "step 0"; + player.chooseUseTarget("wugu", true); + "step 1"; + if (result.bool) { + var cards = []; + player.getHistory("gain", function (evt) { + if (evt.getParent().name == "wugu" && evt.getParent(4) == event) { cards.addArray(evt.cards); } }); - cards=cards.filter(function(card){ - return player.getCards('h').includes(card)&&game.checkMod(card,player,'unchanged','cardEnabled2',player); + cards = cards.filter(function (card) { + return ( + player.getCards("h").includes(card) && + game.checkMod(card, player, "unchanged", "cardEnabled2", player) + ); }); - if(cards.length){ + if (cards.length) { player.chooseCardTarget({ - prompt:'是否将得到的牌当做【乐不思蜀】使用?', - filterCard(card){ + prompt: "是否将得到的牌当做【乐不思蜀】使用?", + filterCard(card) { return _status.event.cards.includes(card); }, - cards:cards, - filterTarget(card,player,target){ - var card=get.autoViewAs({name:'lebu'},ui.selected.cards); - return player.canUse(card,target); + cards: cards, + filterTarget(card, player, target) { + var card = get.autoViewAs({ name: "lebu" }, ui.selected.cards); + return player.canUse(card, target); }, - ai1:()=>1, - ai2(target){ - var player=_status.event.player,card=get.autoViewAs({name:'lebu'},ui.selected.cards); - return get.effect(target,{name:'lebu'},player,player); + ai1: () => 1, + ai2(target) { + var player = _status.event.player, + card = get.autoViewAs({ name: "lebu" }, ui.selected.cards); + return get.effect(target, { name: "lebu" }, player, player); }, - }) - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.useCard({name:'lebu'},result.cards,result.targets[0]); + }); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { + player.useCard({ name: "lebu" }, result.cards, result.targets[0]); } }, }, - erika_shisong:{ - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - filter(event,player){ - if(player!=_status.currentPhase) return false; - var index=player.getHistory('useCard').indexOf(event),history=player.actionHistory; - for(var i=history.length-2;i>=0;i--){ - if(history[i].isMe){ - var evt=history[i].useCard[index]; - return evt&&get.type2(evt.card)==get.type(event.card); + erika_shisong: { + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + filter(event, player) { + if (player != _status.currentPhase) return false; + var index = player.getHistory("useCard").indexOf(event), + history = player.actionHistory; + for (var i = history.length - 2; i >= 0; i--) { + if (history[i].isMe) { + var evt = history[i].useCard[index]; + return evt && get.type2(evt.card) == get.type(event.card); } } return false; }, - content(){ + content() { player.draw(); }, - mod:{ - maxHandcard(player,num){ - return num+player.hujia; + mod: { + maxHandcard(player, num) { + return num + player.hujia; }, }, }, - erika_yousheng:{ - init:(player)=>{ - player.addSkill('erika_yousheng_mamori'); + erika_yousheng: { + init: (player) => { + player.addSkill("erika_yousheng_mamori"); }, - dutySkill:true, - group:['erika_yousheng_achieve','erika_yousheng_fail'], - trigger:{global:'useCardToTarget'}, - filter(event,player){ - return player.getStorage('erika_yousheng').includes(event.target)&& - (event.card.name=='sha'||(get.type2(event.card,false)=='trick'&&get.tag(event.card,'damage')>0))&& - (player.countMark('erika_yousheng_ruka')+1)<=player.countCards('he'); + dutySkill: true, + group: ["erika_yousheng_achieve", "erika_yousheng_fail"], + trigger: { global: "useCardToTarget" }, + filter(event, player) { + return ( + player.getStorage("erika_yousheng").includes(event.target) && + (event.card.name == "sha" || + (get.type2(event.card, false) == "trick" && get.tag(event.card, "damage") > 0)) && + player.countMark("erika_yousheng_ruka") + 1 <= player.countCards("he") + ); }, - intro:{ - content:'已保护$', + intro: { + content: "已保护$", }, - async cost(event, trigger, player){ - const num=(player.countMark('erika_yousheng_ruka')+1); - event.result = await player.chooseToDiscard('he',num,get.prompt('erika_yousheng',trigger.target),'弃置'+(num)+'张牌,并转移'+get.translation(trigger.card)).forResult(); + async cost(event, trigger, player) { + const num = player.countMark("erika_yousheng_ruka") + 1; + event.result = await player + .chooseToDiscard( + "he", + num, + get.prompt("erika_yousheng", trigger.target), + "弃置" + num + "张牌,并转移" + get.translation(trigger.card) + ) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { player.discard(event.cards); - var ruka=trigger.target,evt=trigger.getParent(); + var ruka = trigger.target, + evt = trigger.getParent(); evt.targets.remove(ruka); evt.triggeredTargets2.remove(ruka); evt.targets.push(player); evt.triggeredTargets2.push(player); - player.addTempSkill('erika_yousheng_ruka'); - var str='erika_yousheng_'+player.playerid; - if(!evt[str]) evt[str]=[]; + player.addTempSkill("erika_yousheng_ruka"); + var str = "erika_yousheng_" + player.playerid; + if (!evt[str]) evt[str] = []; evt[str].add(ruka); }, - subSkill:{ - achieve:{ - trigger:{player:'changeHujiaAfter'}, - forced:true, - skillAnimation:'legend', - animationColor:'water', - filter(event,player){ - return player.storage.erika_yousheng&&event.num<0&&!player.hujia; + subSkill: { + achieve: { + trigger: { player: "changeHujiaAfter" }, + forced: true, + skillAnimation: "legend", + animationColor: "water", + filter(event, player) { + return player.storage.erika_yousheng && event.num < 0 && !player.hujia; }, - content(){ - 'step 0' - player.awakenSkill('erika_yousheng'); - game.log(player,'成功完成使命'); - var list=[player]; + content() { + "step 0"; + player.awakenSkill("erika_yousheng"); + game.log(player, "成功完成使命"); + var list = [player]; list.addArray(player.storage.erika_yousheng); list.sortBySeat(); - list=list.filter(function(current){ + list = list.filter(function (current) { return current.isAlive(); }); - player.line(list,'green'); - game.asyncDraw(list,3); - 'step 1' + player.line(list, "green"); + game.asyncDraw(list, 3); + "step 1"; game.delayx(); }, }, - fail:{ - trigger:{global:'damageEnd'}, - forced:true, - filter(event,player){ - return player.getStorage('erika_yousheng').includes(event.player)&&event.card&&(event.card.name=='sha'||(get.type2(event.card,false)=='trick'&&get.tag(event.card,'damage')>0)); + fail: { + trigger: { global: "damageEnd" }, + forced: true, + filter(event, player) { + return ( + player.getStorage("erika_yousheng").includes(event.player) && + event.card && + (event.card.name == "sha" || + (get.type2(event.card, false) == "trick" && + get.tag(event.card, "damage") > 0)) + ); }, - content(){ - player.awakenSkill('erika_yousheng'); - game.log(player,'使命失败'); - var num=player.hujia; - if(num>0){ + content() { + player.awakenSkill("erika_yousheng"); + game.log(player, "使命失败"); + var num = player.hujia; + if (num > 0) { player.changeHujia(-num); - player.chooseToDiscard(num,true,'he'); + player.chooseToDiscard(num, true, "he"); } }, }, - mamori:{ - trigger:{global:'roundStart'}, - skillAnimation:true, - animationColor:'wood', - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt('erika_yousheng'),[1,2],lib.filter.notMe,'选择至多两名其他角色。你减2点体力上限并获得3点护甲。').set('ai',function(ruka){ - return -1; - }).forResult(); + mamori: { + trigger: { global: "roundStart" }, + skillAnimation: true, + animationColor: "wood", + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("erika_yousheng"), + [1, 2], + lib.filter.notMe, + "选择至多两名其他角色。你减2点体力上限并获得3点护甲。" + ) + .set("ai", function (ruka) { + return -1; + }) + .forResult(); }, - async content(event, trigger, player){ - player.awakenSkill('erika_yousheng_mamori'); - player.markAuto('erika_yousheng', event.targets); + async content(event, trigger, player) { + player.awakenSkill("erika_yousheng_mamori"); + player.markAuto("erika_yousheng", event.targets); await player.loseMaxHp(2); await player.changeHujia(3); }, }, - ruka:{ - trigger:{global:'useCardAfter'}, - charlotte:true, - filter(event,player){ - return event['erika_yousheng_'+player.playerid]&&event.cards.filterInD().length>0; + ruka: { + trigger: { global: "useCardAfter" }, + charlotte: true, + filter(event, player) { + return ( + event["erika_yousheng_" + player.playerid] && + event.cards.filterInD().length > 0 + ); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget('是否令一名原目标角色获得'+get.translation(trigger.cards.filterInD())+'?',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',trigger['erika_yousheng_'+player.playerid]).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + "是否令一名原目标角色获得" + + get.translation(trigger.cards.filterInD()) + + "?", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", trigger["erika_yousheng_" + player.playerid]) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const ruka = event.targets[0]; - player.line(ruka,'green'); - ruka.gain(trigger.cards.filterInD(),'gain2'); + player.line(ruka, "green"); + ruka.gain(trigger.cards.filterInD(), "gain2"); }, }, }, }, - liyingxia_sanli:{ - trigger:{target:'useCardToTargeted'}, - forced:true, - filter(event,player){ - if(event.player==player||event.player!=_status.currentPhase) return false; - var index=event.player.getHistory('useCard',function(evt){ - return evt.targets.includes(player); - }).indexOf(event.getParent()); - if(index==2) return event.player.isIn()&&player.countCards('he')>0; - return index<2&&index>-1; + liyingxia_sanli: { + trigger: { target: "useCardToTargeted" }, + forced: true, + filter(event, player) { + if (event.player == player || event.player != _status.currentPhase) return false; + var index = event.player + .getHistory("useCard", function (evt) { + return evt.targets.includes(player); + }) + .indexOf(event.getParent()); + if (index == 2) return event.player.isIn() && player.countCards("he") > 0; + return index < 2 && index > -1; }, - logTarget:'player', - content(){ - 'step 0' - var index=trigger.player.getHistory('useCard',function(evt){ - return evt.targets.includes(player); - }).indexOf(trigger.getParent()); - if(index==2){ - player.chooseCard('he',true,'三礼:交给'+get.translation(trigger.player)+'一张牌'); - } - else{ + logTarget: "player", + content() { + "step 0"; + var index = trigger.player + .getHistory("useCard", function (evt) { + return evt.targets.includes(player); + }) + .indexOf(trigger.getParent()); + if (index == 2) { + player.chooseCard( + "he", + true, + "三礼:交给" + get.translation(trigger.player) + "一张牌" + ); + } else { player.draw(); event.finish(); } - 'step 1' - if(result.bool){ - player.give(result.cards,trigger.player); + "step 1"; + if (result.bool) { + player.give(result.cards, trigger.player); } }, }, - liyingxia_zhenjun:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.group=='key'; + liyingxia_zhenjun: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return player.group == "key"; }, - async cost(event, trigger, player){ - const num=player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'||(get.type(evt.card)=='trick'&&get.tag(evt.card,'damage')>0); - }).length+1; - event.result = await player.chooseTarget(get.prompt('liyingxia_zhenjun'),[1,num],'令至多'+get.cnNumber(num)+'名角色各摸一张牌').set('ai',(serafu)=>get.attitude(_status.event.player,serafu)).forResult(); + async cost(event, trigger, player) { + const num = + player.getHistory("useCard", function (evt) { + return ( + evt.card.name == "sha" || + (get.type(evt.card) == "trick" && get.tag(evt.card, "damage") > 0) + ); + }).length + 1; + event.result = await player + .chooseTarget( + get.prompt("liyingxia_zhenjun"), + [1, num], + "令至多" + get.cnNumber(num) + "名角色各摸一张牌" + ) + .set("ai", (serafu) => get.attitude(_status.event.player, serafu)) + .forResult(); }, - content(){ + content() { targets.sortBySeat(); game.asyncDraw(targets); - for(var i of targets) i.addTempSkill('liyingxia_zhenjun_enhance',{player:player==i?'phaseJieshuBegin':'phaseAfter'}); + for (var i of targets) + i.addTempSkill("liyingxia_zhenjun_enhance", { + player: player == i ? "phaseJieshuBegin" : "phaseAfter", + }); game.delayx(); }, - subSkill:{ - enhance:{ - trigger:{source:'damageBegin1'}, - forced:true, - charlotte:true, - mark:true, - filter:(event,player)=>(player==_status.currentPhase), - intro:{content:'下回合首次造成的伤害+1'}, - content(){ + subSkill: { + enhance: { + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + mark: true, + filter: (event, player) => player == _status.currentPhase, + intro: { content: "下回合首次造成的伤害+1" }, + content() { trigger.num++; player.removeSkill(event.name); }, }, }, }, - liyingxia_wumai:{ - trigger:{global:'roundStart'}, - filter(event,player){ - return player.group=='shu'&&(player.getStorage('liyingxia_wumai').length<4||game.hasPlayer((current)=>current.isDamaged())); + liyingxia_wumai: { + trigger: { global: "roundStart" }, + filter(event, player) { + return ( + player.group == "shu" && + (player.getStorage("liyingxia_wumai").length < 4 || + game.hasPlayer((current) => current.isDamaged())) + ); }, - async cost(event, trigger, player){ - var list=lib.skill.liyingxia_wumai.derivation.slice(0); - list.removeArray(player.getStorage('liyingxia_wumai')); - if(list.length){ - const {result} = await player.chooseControl(list,'cancel2').set('prompt',get.prompt('liyingxia_wumai')).set('prompt2','获得一个技能直到本轮结束'); - if (result.control !== 'cancel2') { + async cost(event, trigger, player) { + var list = lib.skill.liyingxia_wumai.derivation.slice(0); + list.removeArray(player.getStorage("liyingxia_wumai")); + if (list.length) { + const { result } = await player + .chooseControl(list, "cancel2") + .set("prompt", get.prompt("liyingxia_wumai")) + .set("prompt2", "获得一个技能直到本轮结束"); + if (result.control !== "cancel2") { event.result = { bool: true, cost_data: { - type: 'addSkill', + type: "addSkill", skill: result.control, }, - } + }; } - } - else{ - const num=Math.min(3,game.countPlayer((current)=>current.isDamaged())); - const {result} = await player.chooseBool(get.prompt('liyingxia_wumai')+'(可摸'+get.cnNumber(num)+'张牌)'); + } else { + const num = Math.min( + 3, + game.countPlayer((current) => current.isDamaged()) + ); + const { result } = await player.chooseBool( + get.prompt("liyingxia_wumai") + "(可摸" + get.cnNumber(num) + "张牌)" + ); if (result.bool) { event.result = { bool: true, cost_data: { - type: 'drawCards', + type: "drawCards", num, }, - } + }; } } }, - async content(event, trigger, player){ + async content(event, trigger, player) { const result = event.cost_data; - if(result.type === 'addSkill'){ - player.markAuto('liyingxia_wumai',[result.skill]); - player.addTempSkills(result.skill, 'roundStart'); - } - else if(result.type === 'drawCards'){ + if (result.type === "addSkill") { + player.markAuto("liyingxia_wumai", [result.skill]); + player.addTempSkills(result.skill, "roundStart"); + } else if (result.type === "drawCards") { player.draw(result.num); } }, - derivation:['bazhen','rejizhi','reguanxing','youlong'], + derivation: ["bazhen", "rejizhi", "reguanxing", "youlong"], }, - kano_liezhen:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.getHistory('useCard').length>0; + kano_liezhen: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return player.getHistory("useCard").length > 0; }, - frequent:true, - async cost(event,trigger,player){ - var history=player.getHistory('useCard'); - if(history.length>1){ - var type=get.type2(history[0].card,false); - for(var i=1;i 1) { + var type = get.type2(history[0].card, false); + for (var i = 1; i < history.length; i++) { + if (get.type2(history[i].card, false) != type) { + const result = await player + .chooseButton([ + "列阵:是否视为使用其中一种牌?", + [["kano_paibingbuzhen"].concat(get.zhinangs()), "vcard"], + ]) + .set("filterButton", function (button) { + return _status.event.player.hasUseTarget({ + name: button.link[2], + isCard: true, + }); + }) + .set("ai", function (button) { + return _status.event.player.getUseValue({ + name: button.link[2], + isCard: true, + }); + }) + .forResult(); + if (result.bool) + event.result = { + bool: true, + cost_data: { + links: result.links, + }, + }; return; } } } - var str=_status.renku.length?'获得仁库中的所有牌':'摸两张牌'; - event.result = await player.chooseBool(get.prompt('kano_liezhen'),str).set('frequentSkill','kano_liezhen').forResult(); + var str = _status.renku.length ? "获得仁库中的所有牌" : "摸两张牌"; + event.result = await player + .chooseBool(get.prompt("kano_liezhen"), str) + .set("frequentSkill", "kano_liezhen") + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const result = event.cost_data; if (!result || !result.links.length) { if (_status.renku.length) { const cards = _status.renku.slice(0); - _status.renku.length=0; + _status.renku.length = 0; game.updateRenku(); - await player.gain(cards, 'gain2', 'fromRenku'); - } - else player.draw(2); - } - else { + await player.gain(cards, "gain2", "fromRenku"); + } else player.draw(2); + } else { player.chooseUseTarget(result.links[0][2], true); } }, - init(player){ - player.storage.renku=true; + init(player) { + player.storage.renku = true; }, }, - kano_poyu:{ - trigger:{target:'useCardToTargeted'}, - charlotte:true, - filter(event,player){ - return _status.renku.length>0&&(event.card.name=='sha'||get.type(event.card)=='trick'&&get.tag(event.card,'damage')>0); + kano_poyu: { + trigger: { target: "useCardToTargeted" }, + charlotte: true, + filter(event, player) { + return ( + _status.renku.length > 0 && + (event.card.name == "sha" || + (get.type(event.card) == "trick" && get.tag(event.card, "damage") > 0)) + ); }, - check(trigger,player){ - return get.effect(player,trigger.card,trigger.player,player)<0; + check(trigger, player) { + return get.effect(player, trigger.card, trigger.player, player) < 0; }, - content(){ - 'step 0' + content() { + "step 0"; player.judge(); - 'step 1' - var bool=false,type=get.type2(result.card.name); - for(var i of _status.renku){ - if(get.suit(i)==result.suit||get.type2(i)==type){ - bool=true;break; + "step 1"; + var bool = false, + type = get.type2(result.card.name); + for (var i of _status.renku) { + if (get.suit(i) == result.suit || get.type2(i) == type) { + bool = true; + break; } } - if(bool){ - player.chooseButton(['是否移去一张牌,令'+get.translation(trigger.card)+'对你无效?',_status.renku]).set('types',[result.suit,type]).set('filterButton',function(button){ - var types=_status.event.types; - return get.suit(button.link,false)==types[0]||get.type2(button.link,false)==types[1]; - }).set('ai',()=>1); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.links[0]; - player.$throw(card,1000); + if (bool) { + player + .chooseButton([ + "是否移去一张牌,令" + get.translation(trigger.card) + "对你无效?", + _status.renku, + ]) + .set("types", [result.suit, type]) + .set("filterButton", function (button) { + var types = _status.event.types; + return ( + get.suit(button.link, false) == types[0] || + get.type2(button.link, false) == types[1] + ); + }) + .set("ai", () => 1); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.links[0]; + player.$throw(card, 1000); _status.renku.remove(card); - game.cardsDiscard(card).fromRenku=true; - game.log(player,'将',card,'置入了弃牌堆'); + game.cardsDiscard(card).fromRenku = true; + game.log(player, "将", card, "置入了弃牌堆"); trigger.excluded.add(player); game.updateRenku(); } }, - init(player){ - player.storage.renku=true; + init(player) { + player.storage.renku = true; }, }, - mia_shihui:{ - trigger:{player:'phaseDrawBegin1'}, - forced:true, - filter(event,player){ + mia_shihui: { + trigger: { player: "phaseDrawBegin1" }, + forced: true, + filter(event, player) { return !event.numFixed; }, - content(){ + content() { trigger.changeToZero(); - var num=0;all=player.getAllHistory(); - if(all.length>1){ - for(var i=all.length-2;i>=0;i--){ - if(all[i].isMe){ - for(var evt of all[i].lose){ - if(evt.type=='discard') num+=evt.cards2.length; + var num = 0; + all = player.getAllHistory(); + if (all.length > 1) { + for (var i = all.length - 2; i >= 0; i--) { + if (all[i].isMe) { + for (var evt of all[i].lose) { + if (evt.type == "discard") num += evt.cards2.length; } break; } } } - player.draw(1+num); + player.draw(1 + num); }, - group:'mia_shihui_recover', - subSkill:{ - recover:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter(event,player){ - return player.isDamaged()||player.countCards('he')>0; + group: "mia_shihui_recover", + subSkill: { + recover: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter(event, player) { + return player.isDamaged() || player.countCards("he") > 0; }, - content(){ - player.chooseToDiscard('he',true); + content() { + player.chooseToDiscard("he", true); player.recover(); }, }, }, }, - mia_qianmeng:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + mia_qianmeng: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - dutySkill:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + dutySkill: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(); - 'step 1' - if(player.countCards('he')>0){ - player.chooseCard('he',true,'潜梦:选择一张牌置于牌堆中'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - player.storage.mia_qianmeng=card; - player.$throw(card,1000); - player.lose(card,ui.cardPile).insert_index=function(){ - return ui.cardPile.childNodes[Math.ceil(ui.cardPile.childNodes.length/2)]; + "step 1"; + if (player.countCards("he") > 0) { + player.chooseCard("he", true, "潜梦:选择一张牌置于牌堆中"); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + player.storage.mia_qianmeng = card; + player.$throw(card, 1000); + player.lose(card, ui.cardPile).insert_index = function () { + return ui.cardPile.childNodes[Math.ceil(ui.cardPile.childNodes.length / 2)]; }; - } - else event.finish(); - 'step 3' + } else event.finish(); + "step 3"; game.delayx(); }, - onremove:true, - group:['mia_qianmeng_achieve','mia_qianmeng_fail'], - subSkill:{ - achieve:{ - trigger:{ - global:['gainAfter','loseAsyncAfter'], + onremove: true, + group: ["mia_qianmeng_achieve", "mia_qianmeng_fail"], + subSkill: { + achieve: { + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - forced:true, - filter(event,player){ - var card=player.storage.mia_qianmeng; - if(event.name=='gain'){ - var source=event.player,cards=event.getg(source); - return cards.includes(card)&&source.getCards('hejsx').includes(card); - } - else{ - if(event.type!='gain') return false; - var owner=get.owner(card); - return owner&&event.getg(owner).includes(card); + forced: true, + filter(event, player) { + var card = player.storage.mia_qianmeng; + if (event.name == "gain") { + var source = event.player, + cards = event.getg(source); + return cards.includes(card) && source.getCards("hejsx").includes(card); + } else { + if (event.type != "gain") return false; + var owner = get.owner(card); + return owner && event.getg(owner).includes(card); } }, - skillAnimation:true, - animationColor:'key', - content(){ - 'step 0' - game.log(player,'成功完成使命'); - player.awakenSkill('mia_qianmeng'); - var card=player.storage.mia_qianmeng,owner=get.owner(card); - if(owner&&owner!=player) owner.give(card,player); - 'step 1' - if(player.hp1){ - for(var i=all.length-2;i>=0;i--){ - if(all[i].isMe){ - num+=all[i].useCard.length; + content() { + var num = 0; + all = player.getAllHistory(); + if (all.length > 1) { + for (var i = all.length - 2; i >= 0; i--) { + if (all[i].isMe) { + num += all[i].useCard.length; break; } } } - trigger.num+=num; + trigger.num += num; }, }, - kyou_zhidian:{ - locked:false, - mod:{ - targetInRange(card){ - if(card.kyou_zhidian) return true; + kyou_zhidian: { + locked: false, + mod: { + targetInRange(card) { + if (card.kyou_zhidian) return true; }, - aiOrder(player,card,numx){ - var num=_status.event._kyou_zhidian_baseValue; - if(num>0&&get.type2(card)=='trick'&&player.getUseValue(card) 0 && get.type2(card) == "trick" && player.getUseValue(card) < num) + return numx / 10; }, }, - enable:'chooseToUse', - filter(event,player){ - return player.countCards('hs',(card)=>get.type2(card)=='trick')>0; + enable: "chooseToUse", + filter(event, player) { + return player.countCards("hs", (card) => get.type2(card) == "trick") > 0; }, - filterCard(card){ - return get.type2(card)=='trick'; + filterCard(card) { + return get.type2(card) == "trick"; }, - onChooseToUse(event){ - event._kyou_zhidian_baseValue=event.player.getUseValue({name:'sha'}); + onChooseToUse(event) { + event._kyou_zhidian_baseValue = event.player.getUseValue({ + name: "sha", + }); }, - check(card){ - var num=_status.event._kyou_zhidian_baseValue,player=_status.event.player; - return num-player.getUseValue(card); + check(card) { + var num = _status.event._kyou_zhidian_baseValue, + player = _status.event.player; + return num - player.getUseValue(card); }, - prompt:'将一张锦囊牌当做【杀】使用', - viewAs:{ - name:'sha', - kyou_zhidian:true, + prompt: "将一张锦囊牌当做【杀】使用", + viewAs: { + name: "sha", + kyou_zhidian: true, }, - group:'kyou_zhidian_aim', - ai:{ - respondSha:true, - skillTagFilter:(player)=>player.countCards('hs',(card)=>get.type2(card)=='trick')>0, + group: "kyou_zhidian_aim", + ai: { + respondSha: true, + skillTagFilter: (player) => + player.countCards("hs", (card) => get.type2(card) == "trick") > 0, }, - subSkill:{ - aim:{ - trigger:{ - player:'useCardToPlayered', + subSkill: { + aim: { + trigger: { + player: "useCardToPlayered", }, - forced:true, - locked:false, - filter(event,player){ - return event.isFirstTarget&&event.card.name=='sha'; + forced: true, + locked: false, + filter(event, player) { + return event.isFirstTarget && event.card.name == "sha"; }, - logTarget:'target', - content(){ - 'step 0' - var list=['不可被响应','无视防具','伤害+1','不计入次数']; + logTarget: "target", + content() { + "step 0"; + var list = ["不可被响应", "无视防具", "伤害+1", "不计入次数"]; list.remove(player.storage.kyou_zhidian); - player.chooseControl(list).set('prompt','掷典:请为'+get.translation(trigger.card)+'选择一种效果').set('choice',function(){ - if(list.includes('不计入次数')&&player.hasSha()) return '不计入次数'; - if(list.includes('不可被响应')&&trigger.target.mayHaveShan(player,'use',trigger.target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return '不可被响应'; - if(list.includes('伤害+1')) return '伤害+1'; - return list.randomGet(); - }()).set('ai',()=>_status.event.choice); - 'step 1' - var target=trigger.target; - player.storage.kyou_zhidian=result.control; - game.log(player,'对',target,'的',trigger.card,'#g'+result.control); - switch(result.control){ - case '不可被响应': + player + .chooseControl(list) + .set("prompt", "掷典:请为" + get.translation(trigger.card) + "选择一种效果") + .set( + "choice", + (function () { + if (list.includes("不计入次数") && player.hasSha()) + return "不计入次数"; + if ( + list.includes("不可被响应") && + trigger.target.mayHaveShan( + player, + "use", + trigger.target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return "不可被响应"; + if (list.includes("伤害+1")) return "伤害+1"; + return list.randomGet(); + })() + ) + .set("ai", () => _status.event.choice); + "step 1"; + var target = trigger.target; + player.storage.kyou_zhidian = result.control; + game.log(player, "对", target, "的", trigger.card, "#g" + result.control); + switch (result.control) { + case "不可被响应": trigger.directHit.add(target); break; - case '无视防具': - target.addTempSkill('qinggang2'); + case "无视防具": + target.addTempSkill("qinggang2"); target.storage.qinggang2.add(trigger.card); break; - case '伤害+1': - var map=trigger.customArgs; - var id=target.playerid; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + case "伤害+1": + var map = trigger.customArgs; + var id = target.playerid; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; break; - case '不计入次数': - var evt=trigger.getParent(); - if(evt.addCount!==false){ - evt.addCount=false; + case "不计入次数": + var evt = trigger.getParent(); + if (evt.addCount !== false) { + evt.addCount = false; player.getStat().card.sha--; } break; } }, - } + }, }, }, - kyou_duanfa:{ - trigger:{player:'damageBegin2'}, - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter(event,player){ - return player.hp<=event.num; + kyou_duanfa: { + trigger: { player: "damageBegin2" }, + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + return player.hp <= event.num; }, - content(){ - player.awakenSkill('kyou_duanfa'); - if(player.countCards('h')>0) player.chooseToDiscard('h',true,player.countCards('h')); + content() { + player.awakenSkill("kyou_duanfa"); + if (player.countCards("h") > 0) player.chooseToDiscard("h", true, player.countCards("h")); player.recover(); trigger.cancel(); - player.addTempSkill('kyou_duanfa_draw',{player:'phaseBeginStart'}); + player.addTempSkill("kyou_duanfa_draw", { + player: "phaseBeginStart", + }); }, - subSkill:{ - draw:{ - trigger:{target:'useCardToTargeted'}, - forced:true, - charlotte:true, - filter(event,player){ - if(event.card.name=='sha') return true; - return get.type(event.card,false)=='trick'&&get.tag(event.card,'damage')>0; + subSkill: { + draw: { + trigger: { target: "useCardToTargeted" }, + forced: true, + charlotte: true, + filter(event, player) { + if (event.card.name == "sha") return true; + return ( + get.type(event.card, false) == "trick" && get.tag(event.card, "damage") > 0 + ); }, - content(){ + content() { player.draw(); }, }, }, }, - kotarou_aurora:{ - trigger:{ - player:['damageEnd','loseHpEnd','gainMaxHpEnd'] + kotarou_aurora: { + trigger: { + player: ["damageEnd", "loseHpEnd", "gainMaxHpEnd"], }, - forced:true, - charlotte:true, - filter(event,player){ + forced: true, + charlotte: true, + filter(event, player) { return player.hasEnabledSlot(1); }, - content(){ - if(player.hasEmptySlot(1)){ - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'&&!get.cardtag(card,'gifts')&&player.canUse(card,player); + content() { + if (player.hasEmptySlot(1)) { + var card = get.cardPile2(function (card) { + return ( + get.subtype(card) == "equip1" && + !get.cardtag(card, "gifts") && + player.canUse(card, player) + ); }); - if(card) player.chooseUseTarget(card,true); - } - else player.chooseUseTarget('sha',true,false); + if (card) player.chooseUseTarget(card, true); + } else player.chooseUseTarget("sha", true, false); }, }, - kotarou_rewrite:{ - enable:'phaseUse', - charlotte:true, - filter(event,player){ - return !player.hasSkill('kotarou_rewrite_block'); + kotarou_rewrite: { + enable: "phaseUse", + charlotte: true, + filter(event, player) { + return !player.hasSkill("kotarou_rewrite_block"); }, - content(){ - 'step 0' - player.getHistory('custom').push({kotarou_rewrite:true}); - player.chooseControl().set('choiceList',[ - '视为使用一张本局游戏没有以此法使用过的基本牌或普通锦囊牌', - '移动场上的一张牌', - '增加1点体力上限并失去1点体力', - '本回合内下一次造成的伤害+1', - '本回合内下一次回复体力时,额外回复1点体力', - '本回合内手牌上限和【杀】的使用次数+1                         ', - ]).set('ai',function(){ - var player=_status.event.player; - if(player.hp>2&&player.getUseValue({name:'sha'})>0) return 2; - return 0; - }); - 'step 1' - lib.skill.kotarou_rewrite.rewrites[result.index](player,event); - if(result.index!=0) event.goto(3); - 'step 2' - if(result.bool){ + content() { + "step 0"; + player.getHistory("custom").push({ kotarou_rewrite: true }); + player + .chooseControl() + .set("choiceList", [ + "视为使用一张本局游戏没有以此法使用过的基本牌或普通锦囊牌", + "移动场上的一张牌", + "增加1点体力上限并失去1点体力", + "本回合内下一次造成的伤害+1", + "本回合内下一次回复体力时,额外回复1点体力", + "本回合内手牌上限和【杀】的使用次数+1                         ", + ]) + .set("ai", function () { + var player = _status.event.player; + if (player.hp > 2 && player.getUseValue({ name: "sha" }) > 0) return 2; + return 0; + }); + "step 1"; + lib.skill.kotarou_rewrite.rewrites[result.index](player, event); + if (result.index != 0) event.goto(3); + "step 2"; + if (result.bool) { player.storage.kotarou_rewrite.push(result.links[0][2]); - player.chooseUseTarget(true,{name:result.links[0][2],nature:result.links[0][3],isCard:true}); + player.chooseUseTarget(true, { + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }); } - 'step 3' - if(player.getHistory('custom',function(evt){ - return evt&&evt.kotarou_rewrite==true; - }).length>=3) player.addTempSkill('kotarou_rewrite_block'); + "step 3"; + if ( + player.getHistory("custom", function (evt) { + return evt && evt.kotarou_rewrite == true; + }).length >= 3 + ) + player.addTempSkill("kotarou_rewrite_block"); }, - onremove:true, - rewrites:[ - function(player,event){ - var list=[]; - if(!player.storage.kotarou_rewrite) player.storage.kotarou_rewrite=[]; - for(var i of lib.inpile){ - if(player.storage.kotarou_rewrite.includes(i)) continue; - var type=get.type(i); - if((type=='basic'||type=='trick')) list.push([type,'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature) list.push([type,'',i,j]); + onremove: true, + rewrites: [ + function (player, event) { + var list = []; + if (!player.storage.kotarou_rewrite) player.storage.kotarou_rewrite = []; + for (var i of lib.inpile) { + if (player.storage.kotarou_rewrite.includes(i)) continue; + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) list.push([type, "", i, j]); } } - if(list.length){ - player.chooseButton(['改写:视为使用一张基本牌或普通锦囊牌',[list,'vcard']],true).set('filterButton',function(button){ - return player.hasUseTarget({name:button.link[2],nature:button.link[3],isCard:true},null,true); - }).set('ai',function(button){ - return player.getUseValue({name:button.link[2],nature:button.link[3],isCard:true}); - }); - } - else event._result={bool:false}; + if (list.length) { + player + .chooseButton(["改写:视为使用一张基本牌或普通锦囊牌", [list, "vcard"]], true) + .set("filterButton", function (button) { + return player.hasUseTarget( + { + name: button.link[2], + nature: button.link[3], + isCard: true, + }, + null, + true + ); + }) + .set("ai", function (button) { + return player.getUseValue({ + name: button.link[2], + nature: button.link[3], + isCard: true, + }); + }); + } else event._result = { bool: false }; }, - function(player,event){ + function (player, event) { player.moveCard(true); }, - function(player,event){ - if(player.maxHp<5) player.gainMaxHp(); + function (player, event) { + if (player.maxHp < 5) player.gainMaxHp(); player.loseHp(); }, - function(player,event){ - player.addSkill('kotarou_rewrite_damage'); - player.addMark('kotarou_rewrite_damage',1,false); - game.log(player,'本回合下次造成的伤害','#y+1'); + function (player, event) { + player.addSkill("kotarou_rewrite_damage"); + player.addMark("kotarou_rewrite_damage", 1, false); + game.log(player, "本回合下次造成的伤害", "#y+1"); }, - function(player,event){ - player.addSkill('kotarou_rewrite_recover'); - player.addMark('kotarou_rewrite_recover',1,false); - game.log(player,'本回合下次回复的体力','#y+1'); + function (player, event) { + player.addSkill("kotarou_rewrite_recover"); + player.addMark("kotarou_rewrite_recover", 1, false); + game.log(player, "本回合下次回复的体力", "#y+1"); }, - function(player,event){ - player.addSkill('kotarou_rewrite_sha'); - player.addMark('kotarou_rewrite_sha',1,false); - game.log(player,'本回合的手牌上限和使用【杀】的次数上限','#y+1'); + function (player, event) { + player.addSkill("kotarou_rewrite_sha"); + player.addMark("kotarou_rewrite_sha", 1, false); + game.log(player, "本回合的手牌上限和使用【杀】的次数上限", "#y+1"); }, ], - ai:{ - order:4, - result:{ - player(player){ - if(player.getHistory('custom',function(evt){ - return evt&&evt.kotarou_rewrite==true; - }).length>=2) return 0; + ai: { + order: 4, + result: { + player(player) { + if ( + player.getHistory("custom", function (evt) { + return evt && evt.kotarou_rewrite == true; + }).length >= 2 + ) + return 0; return 1; }, - } - }, - }, - kotarou_rewrite_damage:{ - onremove:true, - trigger:{source:'damageBegin1'}, - forced:true, - content(){ - trigger.num+=player.countMark('kotarou_rewrite_damage'); - player.removeSkill('kotarou_rewrite_damage'); - }, - charlotte:true, - intro:{content:'下一次造成的伤害+#'}, - }, - kotarou_rewrite_recover:{ - onremove:true, - trigger:{player:'recoverBegin'}, - forced:true, - content(){ - trigger.num+=player.countMark('kotarou_rewrite_recover'); - player.removeSkill('kotarou_rewrite_recover'); - }, - charlotte:true, - intro:{content:'下一次回复的体力+#'}, - }, - kotarou_rewrite_sha:{ - onremove:true, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('kotarou_rewrite_sha'); }, - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.countMark('kotarou_rewrite_sha'); - } - }, - charlotte:true, - intro:{content:'手牌上限和出杀次数+#'}, - }, - kotarou_rewrite_block:{ - trigger:{player:'phaseEnd'}, - forced:true, - charlotte:true, - content(){ - player.removeSkill('kotarou_rewrite'); - player.removeSkill('kotarou_aurora'); - if(player.maxHp>3) player.loseMaxHp(player.maxHp-3) }, }, - tenzen_yixing:{ - trigger:{ - global:'damageEnd', + kotarou_rewrite_damage: { + onremove: true, + trigger: { source: "damageBegin1" }, + forced: true, + content() { + trigger.num += player.countMark("kotarou_rewrite_damage"); + player.removeSkill("kotarou_rewrite_damage"); }, - filter(event,player){ - if(!event.card||(event.card.name!='sha'&&event.card.name!='juedou')) return false; - var hairi=event.source; - if(hairi&&(hairi==player||player.inRangeOf(hairi))&&hairi.isIn()&&(hairi.name1!='key_shizuku'&&hairi.name2!='key_shizuku')) return true; - hairi=event.player; - return (hairi&&(hairi==player||player.inRange(hairi))&&hairi.isIn()&&(hairi.name1!='key_shizuku'&&hairi.name2!='key_shizuku')); + charlotte: true, + intro: { content: "下一次造成的伤害+#" }, + }, + kotarou_rewrite_recover: { + onremove: true, + trigger: { player: "recoverBegin" }, + forced: true, + content() { + trigger.num += player.countMark("kotarou_rewrite_recover"); + player.removeSkill("kotarou_rewrite_recover"); }, - frequent:true, - content(){ - 'step 0' + charlotte: true, + intro: { content: "下一次回复的体力+#" }, + }, + kotarou_rewrite_sha: { + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("kotarou_rewrite_sha"); + }, + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("kotarou_rewrite_sha"); + }, + }, + charlotte: true, + intro: { content: "手牌上限和出杀次数+#" }, + }, + kotarou_rewrite_block: { + trigger: { player: "phaseEnd" }, + forced: true, + charlotte: true, + content() { + player.removeSkill("kotarou_rewrite"); + player.removeSkill("kotarou_aurora"); + if (player.maxHp > 3) player.loseMaxHp(player.maxHp - 3); + }, + }, + tenzen_yixing: { + trigger: { + global: "damageEnd", + }, + filter(event, player) { + if (!event.card || (event.card.name != "sha" && event.card.name != "juedou")) + return false; + var hairi = event.source; + if ( + hairi && + (hairi == player || player.inRangeOf(hairi)) && + hairi.isIn() && + hairi.name1 != "key_shizuku" && + hairi.name2 != "key_shizuku" + ) + return true; + hairi = event.player; + return ( + hairi && + (hairi == player || player.inRange(hairi)) && + hairi.isIn() && + hairi.name1 != "key_shizuku" && + hairi.name2 != "key_shizuku" + ); + }, + frequent: true, + content() { + "step 0"; player.draw(); - 'step 1' - if(player.countCards('he')>0){ - player.chooseCard('he',true,'将一张牌作为“兴”置于武将牌上'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('tenzen_yixing'); + "step 1"; + if (player.countCards("he") > 0) { + player.chooseCard("he", true, "将一张牌作为“兴”置于武将牌上"); + } else event.finish(); + "step 2"; + if (result.bool) { + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("tenzen_yixing"); } }, - intro:{ - content:'expansion', - onunmark:'expansion', + intro: { + content: "expansion", + onunmark: "expansion", }, - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'tenzen_yixing_counter', - subSkill:{ - counter:{ - trigger:{target:'useCardToTargeted'}, - filter(event,player){ - if(player==event.player||!player.getExpansions('tenzen_yixing').length) return false; - return event.targets.length==1&&(event.card.name=='sha'||get.type(event.card)=='trick'); + group: "tenzen_yixing_counter", + subSkill: { + counter: { + trigger: { target: "useCardToTargeted" }, + filter(event, player) { + if (player == event.player || !player.getExpansions("tenzen_yixing").length) + return false; + return ( + event.targets.length == 1 && + (event.card.name == "sha" || get.type(event.card) == "trick") + ); }, - prompt2(event){ - return '获得一张“兴”,且'+get.translation(event.card)+'结算完成后可以弃置两张牌,视为对'+get.translation(event.player)+'使用一张同名牌'; + prompt2(event) { + return ( + "获得一张“兴”,且" + + get.translation(event.card) + + "结算完成后可以弃置两张牌,视为对" + + get.translation(event.player) + + "使用一张同名牌" + ); }, - check(event,player){ - if(!player.storage.tenzen_lingyu&&player.getExpansions('tenzen_yixing').length<3) return false; - var card={ - name:event.card.name, - nature:event.card.nature, - isCard:true, + check(event, player) { + if ( + !player.storage.tenzen_lingyu && + player.getExpansions("tenzen_yixing").length < 3 + ) + return false; + var card = { + name: event.card.name, + nature: event.card.nature, + isCard: true, + }; + return ( + player.canUse(card, event.player, false) && + get.effect(event.player, card, player, player) > 0 + ); + }, + content() { + "step 0"; + player.chooseButton( + ["选择获得一张“兴”", player.getExpansions("tenzen_yixing")], + true + ); + "step 1"; + if (result.bool) { + player.gain(result.links, "gain2"); } - return player.canUse(card,event.player,false)&&get.effect(event.player,card,player,player)>0; - }, - content(){ - 'step 0' - player.chooseButton(['选择获得一张“兴”',player.getExpansions('tenzen_yixing')],true); - 'step 1' - if(result.bool){ - player.gain(result.links,'gain2'); - } - var next=game.createEvent('tenzen_yixing_insert'); + var next = game.createEvent("tenzen_yixing_insert"); event.next.remove(next); trigger.getParent().after.push(next); - next.player=player; - next.target=trigger.player; + next.player = player; + next.target = trigger.player; next.setContent(lib.skill.tenzen_yixing.content_extra); }, }, }, - content_extra(){ - 'step 0' - var card=event.getParent().card; - event.card={ - name:card.name, - nature:card.nature, - isCard:true, + content_extra() { + "step 0"; + var card = event.getParent().card; + event.card = { + name: card.name, + nature: card.nature, + isCard: true, }; - if(player.countCards('he')>1&&target&&target.isIn()&&player.canUse(event.card,target,false)){ - player.chooseToDiscard('he',2,'是否弃置两张牌,视为对'+get.translation(target)+'使用'+get.translation(event.card)+'?').set('ai',function(card){ - return 5-get.value(card); - }); - } - else event.finish(); - 'step 1' - if(result.bool) player.useCard(card,target,false,'tenzen_yixing'); + if ( + player.countCards("he") > 1 && + target && + target.isIn() && + player.canUse(event.card, target, false) + ) { + player + .chooseToDiscard( + "he", + 2, + "是否弃置两张牌,视为对" + + get.translation(target) + + "使用" + + get.translation(event.card) + + "?" + ) + .set("ai", function (card) { + return 5 - get.value(card); + }); + } else event.finish(); + "step 1"; + if (result.bool) player.useCard(card, target, false, "tenzen_yixing"); }, }, - tenzen_lingyu:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'water', - filter(event,player){ - return player.getExpansions('tenzen_yixing').length>=player.hp; + tenzen_lingyu: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return player.getExpansions("tenzen_yixing").length >= player.hp; }, - content(){ - player.awakenSkill('tenzen_lingyu'); - player.storage.tenzen_lingyu=true; + content() { + player.awakenSkill("tenzen_lingyu"); + player.storage.tenzen_lingyu = true; player.loseMaxHp(); - if(player.isHealthy()) player.draw(2); - player.addSkills('tenzen_tianquan'); + if (player.isHealthy()) player.draw(2); + player.addSkills("tenzen_tianquan"); + }, + ai: { + combo: "tenzen_yixing" }, }, - tenzen_tianquan:{ - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return (event.card.name=='sha'||event.card.name=='juedou')&&event.targets.length==1&&player.getExpansions('tenzen_yixing').length>1; + tenzen_tianquan: { + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return ( + (event.card.name == "sha" || event.card.name == "juedou") && + event.targets.length == 1 && + player.getExpansions("tenzen_yixing").length > 1 + ); }, - logTarget:'target', - usable:1, - check(event,player){ - return get.attitude(player,event.target)<0; + logTarget: "target", + usable: 1, + check(event, player) { + return get.attitude(player, event.target) < 0; }, - content(){ - 'step 0' + content() { + "step 0"; //player.viewHandcards(trigger.target); - player.chooseButton(['选择移去两张“兴”',player.getExpansions('tenzen_yixing')],true,2); - 'step 1' - if(result.bool){ + player.chooseButton(["选择移去两张“兴”", player.getExpansions("tenzen_yixing")], true, 2); + "step 1"; + if (result.bool) { player.loseToDiscardpile(result.links); - var cards=get.cards(5); - player.showCards(cards,get.translation(player)+'发动了【天全】'); - game.cardsGotoOrdering(cards).relatedEvent=trigger.getParent(); - var num=cards.filter(function(card){ - return get.type(card,false)=='basic'; + var cards = get.cards(5); + player.showCards(cards, get.translation(player) + "发动了【天全】"); + game.cardsGotoOrdering(cards).relatedEvent = trigger.getParent(); + var num = cards.filter(function (card) { + return get.type(card, false) == "basic"; }).length; - if(num){ - if(trigger.card.name=='sha'){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ - map[id].shanRequired+=num; + if (num) { + if (trigger.card.name == "sha") { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { + map[id].shanRequired += num; + } else { + map[id].shanRequired = 1 + num; } - else{ - map[id].shanRequired=1+num; - } - } - else{ - var idt=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[idt]) map[idt]={}; - if(!map[idt].shaReq) map[idt].shaReq={}; - if(!map[idt].shaReq[idt]) map[idt].shaReq[idt]=1; + } else { + var idt = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[idt]) map[idt] = {}; + if (!map[idt].shaReq) map[idt].shaReq = {}; + if (!map[idt].shaReq[idt]) map[idt].shaReq[idt] = 1; map[idt].shaReq[idt]++; } } - if(num<5){ - var next=game.createEvent('tenzen_lingyu_gain'); - next.cards=cards; - next.player=player; + if (num < 5) { + var next = game.createEvent("tenzen_lingyu_gain"); + next.cards = cards; + next.player = player; event.next.remove(next); trigger.getParent().after.push(next); - next.setContent(function(){ - if(player.getHistory('sourceDamage',function(evt){ - return evt.card==event.parent.card; - }).length>0) player.gain(cards.filter(function(card){ - return get.type(card,false)!='basic'; - }),'gain2'); + next.setContent(function () { + if ( + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.parent.card; + }).length > 0 + ) + player.gain( + cards.filter(function (card) { + return get.type(card, false) != "basic"; + }), + "gain2" + ); }); } } }, }, - kyouko_rongzhu:{ - trigger:{global:'gainEnd'}, - filter(event,player){ - if(player==event.player||event.getParent().name=='kyouko_rongzhu') return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + kyouko_rongzhu: { + trigger: { global: "gainEnd" }, + filter(event, player) { + if (player == event.player || event.getParent().name == "kyouko_rongzhu") return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - logTarget:'player', - check(event,player){ - return get.attitude(player,event.player)>0; + logTarget: "player", + check(event, player) { + return get.attitude(player, event.player) > 0; }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(); - 'step 1' - var target=trigger.player; - if(player.countCards('he')>0&&target.isIn()){ - player.chooseCard('he',true,'将一张牌交给'+get.translation(target)); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.give(result.cards,trigger.player); - var target=_status.currentPhase; + "step 1"; + var target = trigger.player; + if (player.countCards("he") > 0 && target.isIn()) { + player.chooseCard("he", true, "将一张牌交给" + get.translation(target)); + } else event.finish(); + "step 2"; + if (result.bool) { + player.give(result.cards, trigger.player); + var target = _status.currentPhase; var name; - if(target==player){ - name='kyouko_rongzhu_me'; + if (target == player) { + name = "kyouko_rongzhu_me"; player.addTempSkill(name); - player.addMark(name,1,false); - } - else if(target==trigger.player){ - name='kyouko_rongzhu_notme'; - player.addTempSkill(name); - player.addMark(name,1,false); + player.addMark(name, 1, false); + } else if (target == trigger.player) { + name = "kyouko_rongzhu_notme"; + target.addTempSkill(name); + target.addMark(name, 1, false); } } }, - subSkill:{ - me:{ - mod:{ - maxHandcard(player,num){ - return num+player.countMark('kyouko_rongzhu_me'); + subSkill: { + me: { + mod: { + maxHandcard(player, num) { + return num + player.countMark("kyouko_rongzhu_me"); }, }, - intro:{content:'手牌上限+#'}, - onremove:true, + intro: { content: "手牌上限+#" }, + onremove: true, }, - notme:{ - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.countMark('kyouko_rongzhu_notme'); + notme: { + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("kyouko_rongzhu_notme"); }, }, - intro:{content:'使用杀的次数上限+#'}, - onremove:true, + intro: { content: "使用杀的次数上限+#" }, + onremove: true, }, }, }, - kyouko_gongmian:{ - enable:'phaseUse', - prompt:'出牌阶段,你可以选择一名未以此法选择过的角色,若其手牌:大于你,你获得其一张牌,然后交给其一张牌;小于你,其交给你一张牌,然后你交给其一张牌;等于你,你与其各摸一张牌。', - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&lib.skill.kyouko_gongmian.filterTarget(null,player,current); + kyouko_gongmian: { + enable: "phaseUse", + prompt: "出牌阶段,你可以选择一名未以此法选择过的角色,若其手牌:大于你,你获得其一张牌,然后交给其一张牌;小于你,其交给你一张牌,然后你交给其一张牌;等于你,你与其各摸一张牌。", + filter(event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && lib.skill.kyouko_gongmian.filterTarget(null, player, current) + ); }); }, - filterTarget(card,kyouko,hina){ - if(kyouko==hina||kyouko.getStorage('kyouko_gongmian').includes(hina)) return false; - var hs=hina.countCards('he'); - if(hs==0) return kyouko.countCards('h')==0; + filterTarget(card, kyouko, hina) { + if (kyouko == hina || kyouko.getStorage("kyouko_gongmian").includes(hina)) return false; + var hs = hina.countCards("he"); + if (hs == 0) return kyouko.countCards("h") == 0; return true; }, - content(){ - 'step 0' - player.markAuto('kyouko_gongmian',targets); - var hs=player.countCards('h'),ts=target.countCards('h'); - player.getHistory('custom').push({kyouko_gongmian:true}); - if(hs>ts){ - event.utype=1; - target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); + content() { + "step 0"; + player.markAuto("kyouko_gongmian", targets); + var hs = player.countCards("h"), + ts = target.countCards("h"); + player.getHistory("custom").push({ kyouko_gongmian: true }); + if (hs > ts) { + event.utype = 1; + target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); + } else if (hs == ts) { + game.asyncDraw([player, target]); + event.utype = 2; + } else { + event.utype = 3; + player.gainPlayerCard(target, true, "he"); } - else if(hs==ts){ - game.asyncDraw([player,target]); - event.utype=2; - } - else{ - event.utype=3; - player.gainPlayerCard(target,true,'he'); - } - 'step 1' - if(event.utype==2){ + "step 1"; + if (event.utype == 2) { game.delayx(); event.finish(); - } - else if(!result.bool) event.finish(); - else if(event.utype==1) target.give(result.cards,player); - 'step 2' - if(player.countCards('he')>0){ - player.chooseCard('he',true,'交给'+get.translation(target)+'一张牌'); - } - else event.finish(); - 'step 3' - if(result.bool) player.give(result.cards,target); + } else if (!result.bool) event.finish(); + else if (event.utype == 1) target.give(result.cards, player); + "step 2"; + if (player.countCards("he") > 0) { + player.chooseCard("he", true, "交给" + get.translation(target) + "一张牌"); + } else event.finish(); + "step 3"; + if (result.bool) player.give(result.cards, target); }, - intro:{ - content:'已与$共勉', + intro: { + content: "已与$共勉", }, - group:['kyouko_gongmian_use','kyouko_gongmian_discard'], - ai:{ - order:6, - result:{ - target(player,target){ - if(player.getHistory('custom',function(evt){ - return evt.kyouko_gongmian==true; - }).length) return 0; + group: ["kyouko_gongmian_use", "kyouko_gongmian_discard"], + ai: { + order: 6, + result: { + target(player, target) { + if ( + player.getHistory("custom", function (evt) { + return evt.kyouko_gongmian == true; + }).length + ) + return 0; return 1; }, }, }, }, - kyouko_gongmian_use:{ - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - return player.getHistory('custom',function(evt){ - return evt.kyouko_gongmian==true; - }).length>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countGainableCards(player,'hej')>0; - }); + kyouko_gongmian_use: { + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + return ( + player.getHistory("custom", function (evt) { + return evt.kyouko_gongmian == true; + }).length > 0 && + game.hasPlayer(function (current) { + return current != player && current.countGainableCards(player, "hej") > 0; + }) + ); }, - async cost(event, trigger, player){ - const num = player.getHistory('custom',function(evt){ - return evt.kyouko_gongmian==true; + async cost(event, trigger, player) { + const num = player.getHistory("custom", function (evt) { + return evt.kyouko_gongmian == true; }).length; - event.result = await player.chooseTarget(get.prompt('kyouko_gongmian'),'获得一名其他角色的至多'+get.cnNumber(num)+'张牌,然后交给其等量的牌',function(card,player,target){ - return target!=player&&target.countGainableCards(player,'hej')>0; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att>0) return att; - var he=player.getCards('he'); - if(target.countCards('he',function(card){ - return get.value(card,target)>7; - })&&he.length>0) return -att+5-Math.min.apply(Math,he.map(function(card){ - return get.value(card,player); - })); - return 0; - }).forResult(); + event.result = await player + .chooseTarget( + get.prompt("kyouko_gongmian"), + "获得一名其他角色的至多" + get.cnNumber(num) + "张牌,然后交给其等量的牌", + function (card, player, target) { + return target != player && target.countGainableCards(player, "hej") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att > 0) return att; + var he = player.getCards("he"); + if ( + target.countCards("he", function (card) { + return get.value(card, target) > 7; + }) && + he.length > 0 + ) + return ( + -att + + 5 - + Math.min.apply( + Math, + he.map(function (card) { + return get.value(card, player); + }) + ) + ); + return 0; + }) + .forResult(); }, - async content(event, trigger, player){ - const num = player.getHistory('custom',function(evt){ - return evt.kyouko_gongmian==true; - }).length, target = event.targets[0]; - let result = await player.gainPlayerCard(target,'hej',true,[1,num]).forResult(); - if(target.isIn()&&result.bool&&result.cards&&result.cards.length&&player.countCards('he')>0){ - const num = result.cards.length, hs = player.getCards('he'); - if(hs.length<=num) result = {bool:true,cards:hs}; - else{ - result = await player.chooseCard('he',true,num,'交给'+get.translation(target)+get.cnNumber(num)+'张牌').forResult(); + async content(event, trigger, player) { + const num = player.getHistory("custom", function (evt) { + return evt.kyouko_gongmian == true; + }).length, + target = event.targets[0]; + let result = await player.gainPlayerCard(target, "hej", true, [1, num]).forResult(); + if ( + target.isIn() && + result.bool && + result.cards && + result.cards.length && + player.countCards("he") > 0 + ) { + const num = result.cards.length, + hs = player.getCards("he"); + if (hs.length <= num) result = { bool: true, cards: hs }; + else { + result = await player + .chooseCard( + "he", + true, + num, + "交给" + get.translation(target) + get.cnNumber(num) + "张牌" + ) + .forResult(); } - if(result.bool&&result.cards&&result.cards.length){ - player.give(result.cards,target); + if (result.bool && result.cards && result.cards.length) { + player.give(result.cards, target); } } }, }, - kyouko_gongmian_discard:{ - trigger:{player:'phaseDiscardBegin'}, - filter(event,player){ - var hs=player.countCards('h'); - return hs>0&&player.getHistory('custom',function(evt){ - return evt.kyouko_gongmian==true; - }).length>=player.hp&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h') 0 && + player.getHistory("custom", function (evt) { + return evt.kyouko_gongmian == true; + }).length >= player.hp && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") < hs; + }) + ); }, - async cost(event,trigger,player){ - event.result = await player.chooseTarget(get.prompt('kyouko_gongmian'),'获得一名其他角色的所有手牌,然后将一半的牌交给该角色(向上取整)',function(card,player,target){ - return target!=player&&target.countCards('h')0) player.gain(hs,target,'giveAuto','bySelf'); - 'step 1' - if(target.isIn()&&player.countCards('h')>0){ - var hs=player.getCards('h'),num=Math.ceil(hs.length/2); - if(hs.length<=num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,num,'交给'+get.translation(target)+get.cnNumber(num)+'张牌'); - } - else event.finish(); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - player.give(result.cards,target); + content() { + "step 0"; + var target = event.targets[0]; + event.target = target; + var hs = target.getCards("h"); + if (hs.length > 0) player.gain(hs, target, "giveAuto", "bySelf"); + "step 1"; + if (target.isIn() && player.countCards("h") > 0) { + var hs = player.getCards("h"), + num = Math.ceil(hs.length / 2); + if (hs.length <= num) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "he", + true, + num, + "交给" + get.translation(target) + get.cnNumber(num) + "张牌" + ); + } else event.finish(); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + player.give(result.cards, target); } }, }, - yuuki_yicha:{ - trigger:{player:'phaseUseBegin'}, - frequent:true, - createDialog(id){ - var dialog=ui.create.dialog('hidden'); - (dialog.textPrompt=dialog.add('异插')).style.textAlign='center'; - dialog.cards=[]; - dialog.rawButtons=[]; - dialog.videoId=id; - var cards=[]; - for(var i=0;i<3;i++){ - var card=ui.create.card(null,null,true); - card.pos=i; - card.pos_x=i; - card.pos_y=0; + yuuki_yicha: { + trigger: { player: "phaseUseBegin" }, + frequent: true, + createDialog(id) { + var dialog = ui.create.dialog("hidden"); + (dialog.textPrompt = dialog.add("异插")).style.textAlign = "center"; + dialog.cards = []; + dialog.rawButtons = []; + dialog.videoId = id; + var cards = []; + for (var i = 0; i < 3; i++) { + var card = ui.create.card(null, null, true); + card.pos = i; + card.pos_x = i; + card.pos_y = 0; cards.push(card); dialog.rawButtons.push(card); } dialog.add(cards); - cards=[]; - for(var i=0;i<3;i++){ - var card=ui.create.card(null,null,true); - card.pos=i+3; - card.pos_x=i; - card.pos_y=1; + cards = []; + for (var i = 0; i < 3; i++) { + var card = ui.create.card(null, null, true); + card.pos = i + 3; + card.pos_x = i; + card.pos_y = 1; cards.push(card); dialog.rawButtons.push(card); } dialog.add(cards); - for(var i of dialog.buttons){ - i.pos_x=i.link.pos_x; - i.pos_y=i.link.pos_y; - i.link=i.link.pos; + for (var i of dialog.buttons) { + i.pos_x = i.link.pos_x; + i.pos_y = i.link.pos_y; + i.link = i.link.pos; } dialog.open(); }, - addCard(card,id,pos){ - var dialog=get.idDialog(id); - if(!dialog) return; - for(var i=0;i0){ - var color=get.color(list[0],false); - if(list.length>1){ - for(var i=1;i 0) { + var color = get.color(list[0], false); + if (list.length > 1) { + for (var i = 1; i < list.length; i++) { + if (get.color(list[i]) != color) return false; + } + } + return get.color(_status.event.card, false) != color; + } + return false; + }) + .set("card", card); + "step 5"; + if (result.bool) { cards.push(card); event.positions.remove(result.links[0]); - game.broadcastAll(function(card,id,pos,player){ - lib.skill.yuuki_yicha.addCard(card,id,pos); - lib.skill.yuuki_yicha.changePrompt(get.translation(player)+'放置了'+get.translation(card),id); - },card,event.videoId,result.links[0],player); + game.broadcastAll( + function (card, id, pos, player) { + lib.skill.yuuki_yicha.addCard(card, id, pos); + lib.skill.yuuki_yicha.changePrompt( + get.translation(player) + "放置了" + get.translation(card), + id + ); + }, + card, + event.videoId, + result.links[0], + player + ); game.delay(2); } - if(event.count>0) event.goto(3); - 'step 6' - game.broadcastAll('closeDialog',event.videoId); - player.chooseTarget('令一名角色获得'+get.translation(cards),true).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 7' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(cards,'gain2'); + if (event.count > 0) event.goto(3); + "step 6"; + game.broadcastAll("closeDialog", event.videoId); + player + .chooseTarget("令一名角色获得" + get.translation(cards), true) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 7"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(cards, "gain2"); } }, }, - kotomi_qinji:{ - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return player.hasUseTarget('wanjian'); + kotomi_qinji: { + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return player.hasUseTarget("wanjian"); }, //chooseUseTarget也不好改 先放着 - direct:true, - content(){ - player.addTempSkill('kotomi_qinji2'); - player.chooseUseTarget({name:'wanjian',isCard:true},get.prompt('kotomi_qinji'),'视为使用一张【万箭齐发】').logSkill='kotomi_qinji'; + direct: true, + content() { + player.addTempSkill("kotomi_qinji2"); + player.chooseUseTarget( + { name: "wanjian", isCard: true }, + get.prompt("kotomi_qinji"), + "视为使用一张【万箭齐发】" + ).logSkill = "kotomi_qinji"; }, }, - kotomi_qinji2:{ - trigger:{source:'damageBefore'}, - forced:true, - popup:false, - filter(event,player){ - return event.getParent().skill=='kotomi_qinji'; + kotomi_qinji2: { + trigger: { source: "damageBefore" }, + forced: true, + popup: false, + filter(event, player) { + return event.getParent().skill == "kotomi_qinji"; }, - content(){ + content() { trigger.cancel(); trigger.player.loseHp(trigger.num); }, }, - kotomi_chuanxiang:{ - global:'kotomi_chuanxiang2', + kotomi_chuanxiang: { + global: "kotomi_chuanxiang2", }, - kotomi_chuanxiang2:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return !player.hasSkill('kotomi_chuanxiang')&&player.countCards('e',lib.skill.kotomi_chuanxiang2.filterCard)>0; + kotomi_chuanxiang2: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return ( + !player.hasSkill("kotomi_chuanxiang") && + player.countCards("e", lib.skill.kotomi_chuanxiang2.filterCard) > 0 + ); }, - filterCard(card,player){ - if(!player) player=_status.event.player; - return game.hasPlayer(function(current){ - return current!=player&¤t.canEquip(card); + filterCard(card, player) { + if (!player) player = _status.event.player; + return game.hasPlayer(function (current) { + return current != player && current.canEquip(card); }); }, - position:'e', - filterTarget(card,player,target){ - return target!=player&&target.canEquip(ui.selected.cards[0]); + position: "e", + filterTarget(card, player, target) { + return target != player && target.canEquip(ui.selected.cards[0]); }, - check(card){ - if(get.value(card)<=0) return 10; - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current.hasSkill('kotomi_chuanxiang')&&get.attitude(player,current)>0; - })){ - var subtype=get.subtype(card,false); - if(player.countCards('hs',function(cardx){ - return get.type(cardx)=='equip'&&get.subtype(cardx,false)==subtype&&player.canUse(cardx,player)&&get.effect(player,cardx,player,player)>0; - })) return 8; - return 7/Math.max(1,get.value(card)); + check(card) { + if (get.value(card) <= 0) return 10; + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("kotomi_chuanxiang") && get.attitude(player, current) > 0; + }) + ) { + var subtype = get.subtype(card, false); + if ( + player.countCards("hs", function (cardx) { + return ( + get.type(cardx) == "equip" && + get.subtype(cardx, false) == subtype && + player.canUse(cardx, player) && + get.effect(player, cardx, player, player) > 0 + ); + }) + ) + return 8; + return 7 / Math.max(1, get.value(card)); } return 0; }, - promptfunc(){ - var players=game.filterPlayer(function(current){ - return current.hasSkill('kotomi_chuanxiang'); + promptfunc() { + var players = game.filterPlayer(function (current) { + return current.hasSkill("kotomi_chuanxiang"); }); - return '将一张装备牌传给其他角色,然后令'+get.translation(players)+'摸一张牌。若传给该角色,则其改为摸两张牌。' + return ( + "将一张装备牌传给其他角色,然后令" + + get.translation(players) + + "摸一张牌。若传给该角色,则其改为摸两张牌。" + ); }, - prepare:'give', - discard:false, - lose:false, - content(){ - 'step 0' + prepare: "give", + discard: false, + lose: false, + content() { + "step 0"; target.equip(cards[0]); - var list=game.filterPlayer(function(current){ - return current.hasSkill('kotomi_chuanxiang'); + var list = game.filterPlayer(function (current) { + return current.hasSkill("kotomi_chuanxiang"); }); - game.asyncDraw(list,function(targetx){ - return targetx==target?2:1; + game.asyncDraw(list, function (targetx) { + return targetx == target ? 2 : 1; }); - 'step 1' + "step 1"; game.delayx(); }, - ai:{ - order:8, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(!card) return 0; - var eff=get.effect(target,card,player,target); - if(target.hasSkill('kotomi_chuanxiang')) eff++; + ai: { + order: 8, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (!card) return 0; + var eff = get.effect(target, card, player, target); + if (target.hasSkill("kotomi_chuanxiang")) eff++; return eff; }, }, }, }, - asara_shelu:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + asara_shelu: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - filterCard:true, - position:'he', - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterCard: true, + position: "he", + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; }, - check(card){ - return 6-get.value(card); + check(card) { + return 6 - get.value(card); }, - content(){ - 'step 0' - if(!target.countCards('h')) event.finish(); - else player.choosePlayerCard(target,'h',true); - 'step 1' + content() { + "step 0"; + if (!target.countCards("h")) event.finish(); + else player.choosePlayerCard(target, "h", true); + "step 1"; player.showCards(result.cards); - event.cards2=result.cards; - 'step 2' - target.$give(event.cards2,player,false); - target.loseToSpecial(event.cards2,'asara_yingwei',player).visible=true; - var card1=cards[0],card2=event.cards2[0]; - if(card1.suit==card2.suit) player.draw(2); - if(card1.number==card2.number) player.recover(); + event.cards2 = result.cards; + "step 2"; + target.$give(event.cards2, player, false); + target.loseToSpecial(event.cards2, "asara_yingwei", player).visible = true; + var card1 = cards[0], + card2 = event.cards2[0]; + if (card1.suit == card2.suit) player.draw(2); + if (card1.number == card2.number) player.recover(); }, - ai:{ - order:6, - result:{ - target:-1, + ai: { + order: 6, + result: { + target: -1, }, }, }, - asara_yingwei:{ - trigger:{player:'yingbian'}, - forced:true, - filter:(event,player)=>event.card.isCard&&player.hasHistory('lose',evt=>evt.getParent()==event&&Object.values(evt.gaintag_map).some(value=>value.includes('asara_yingwei'))), - content:()=>{ - trigger.forceYingbian=true; - } + asara_yingwei: { + trigger: { player: "yingbian" }, + forced: true, + filter: (event, player) => + event.card.isCard && + player.hasHistory( + "lose", + (evt) => + evt.getParent() == event && + Object.values(evt.gaintag_map).some((value) => value.includes("asara_yingwei")) + ), + content: () => { + trigger.forceYingbian = true; + }, + ai: { + combo: "asara_shelu" + }, }, - yukito_kongwu:{ - enable:'phaseUse', - usable:1, - content(){ - "step 0" - if(_status.connectMode) event.time=lib.configOL.choose_timeout; - event.videoId=lib.status.videoId++; - if(player.isUnderControl()){ + yukito_kongwu: { + enable: "phaseUse", + usable: 1, + content() { + "step 0"; + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + event.videoId = lib.status.videoId++; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ + var switchToAuto = function () { game.pause(); game.countChoose(); - setTimeout(function(){ - _status.imchoosing=false; - event._result={ - bool:true, - score:get.rand(1,5), + setTimeout(function () { + _status.imchoosing = false; + event._result = { + bool: true, + score: get.rand(1, 5), }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); game.resume(); - },5000); + }, 5000); }; - var createDialog=function(player,id){ - if(_status.connectMode) lib.configOL.choose_timeout='30'; - if(player==game.me) return; - var str=get.translation(player)+'正在表演《小空飞天》...
              '; - ui.create.dialog(str).videoId=id; + var createDialog = function (player, id) { + if (_status.connectMode) lib.configOL.choose_timeout = "30"; + if (player == game.me) return; + var str = get.translation(player) + "正在表演《小空飞天》...
              "; + ui.create.dialog(str).videoId = id; + }; + var chooseButton = function () { + lib.skill.yufeng.$playFlappyBird(5, "小空飞天"); }; - var chooseButton=function(){lib.skill.yufeng.$playFlappyBird(5,'小空飞天')}; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId); - if(event.isMine()){ + game.broadcastAll(createDialog, player, event.videoId); + if (event.isMine()) { chooseButton(); - } - else if(event.isOnline()){ + } else if (event.isOnline()) { event.player.send(chooseButton); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - game.broadcastAll(function(id,time){ - if(_status.connectMode) lib.configOL.choose_timeout=time; - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - },event.videoId,event.time); - var result=event.result||result; - game.log(player,'获得了','#g'+result.score+'分'); - if(!result.score){ - player.chooseToDiscard(2,true,'he'); + "step 1"; + game.broadcastAll( + function (id, time) { + if (_status.connectMode) lib.configOL.choose_timeout = time; + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + }, + event.videoId, + event.time + ); + var result = event.result || result; + game.log(player, "获得了", "#g" + result.score + "分"); + if (!result.score) { + player.chooseToDiscard(2, true, "he"); event.finish(); return; } - var list=[]; - var list2=[]; - for(var i=0;i<5;i++){ - if(lib.skill.yukito_kongwu.moves[i].filter(player,true)) list.push(i); + var list = []; + var list2 = []; + for (var i = 0; i < 5; i++) { + if (lib.skill.yukito_kongwu.moves[i].filter(player, true)) list.push(i); else list2.push(i); } - if(list.length>=result.score) list=list.randomGets(result.score); - else list.addArray(list2.randomGets(result.score-list.length)); + if (list.length >= result.score) list = list.randomGets(result.score); + else list.addArray(list2.randomGets(result.score - list.length)); list.sort(); - var next=player.chooseButton([ - '控物:请选择一项', - [list.map(i=>{ - return [i,lib.skill.yukito_kongwu.moves[i].prompt]; - }),'textbutton'], + var next = player.chooseButton([ + "控物:请选择一项", + [ + list.map((i) => { + return [i, lib.skill.yukito_kongwu.moves[i].prompt]; + }), + "textbutton", + ], ]); - next.set('forced',true); - next.set('filterButton',function(button){ + next.set("forced", true); + next.set("filterButton", function (button) { return lib.skill.yukito_kongwu.moves[button.link].filter(_status.event.player); }); - next.set('ai',function(button){ - if(lib.skill.yukito_kongwu.moves[button.link].filter(_status.event.player,true)) return 1+Math.random(); + next.set("ai", function (button) { + if (lib.skill.yukito_kongwu.moves[button.link].filter(_status.event.player, true)) + return 1 + Math.random(); return Math.random(); }); - "step 2" - var num=result.links[0]; - switch(num){ - case 0:event.goto(3);break; - case 1:event.goto(5);break; - case 2:event.goto(7);break; - case 3:event.goto(9);break; - case 4:player.moveCard(true);event.finish();break; + "step 2"; + var num = result.links[0]; + switch (num) { + case 0: + event.goto(3); + break; + case 1: + event.goto(5); + break; + case 2: + event.goto(7); + break; + case 3: + event.goto(9); + break; + case 4: + player.moveCard(true); + event.finish(); + break; } - "step 3" - player.chooseTarget(true,'令一名角色摸两张牌').set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - if(target.hasSkillTag('nogain')) att/=10; + "step 3"; + player.chooseTarget(true, "令一名角色摸两张牌").set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + if (target.hasSkillTag("nogain")) att /= 10; return att; }); - "step 4" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(2); } event.finish(); - "step 5" - player.chooseTarget(true,'对一名角色造成1点伤害').set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); + "step 5"; + player.chooseTarget(true, "对一名角色造成1点伤害").set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); }); - "step 6" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 6"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.damage(); } event.finish(); - "step 7" - player.chooseTarget(true,'令一名已受伤的角色回复1点体力',function(card,player,target){ - return target.isDamaged(); - }).set('ai',function(target){ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - }); - "step 8" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 7"; + player + .chooseTarget(true, "令一名已受伤的角色回复1点体力", function (card, player, target) { + return target.isDamaged(); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.recoverEffect(target, player, player); + }); + "step 8"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.recover(); } event.finish(); - "step 9" - player.chooseTarget(true,'弃置一名角色区域内的两张牌',function(card,player,target){ - return target.countDiscardableCards(player,'hej')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 10" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,'hej',true,2); + "step 9"; + player + .chooseTarget(true, "弃置一名角色区域内的两张牌", function (card, player, target) { + return target.countDiscardableCards(player, "hej") > 0; + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 10"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, "hej", true, 2); } event.finish(); }, - moves:[ + moves: [ { - prompt:'令一名角色摸两张牌', - filter:()=>true, + prompt: "令一名角色摸两张牌", + filter: () => true, }, { - prompt:'对一名角色造成1点伤害', - filter(player,ai){ - if(!ai) return true; - return game.hasPlayer(function(current){ - return get.damageEffect(current,player,player)>0; + prompt: "对一名角色造成1点伤害", + filter(player, ai) { + if (!ai) return true; + return game.hasPlayer(function (current) { + return get.damageEffect(current, player, player) > 0; }); }, }, { - prompt:'令一名已受伤的角色回复1点体力', - filter(player,ai){ - return game.hasPlayer(function(current){ - if(current.isDamaged()) return !ai||get.recoverEffect(current,player,player)>0; - }); - } - }, - { - prompt:'弃置一名角色区域内的两张牌', - filter(player,ai){ - return game.hasPlayer(function(current){ - return current.countDiscardableCards(player,'hej',function(card){ - if(!ai) return true; - return get.buttonValue({link:card})*get.attitude(player,current)>0; - })>=(ai?1:Math.min(2,current.countDiscardableCards(player,'hej'))); + prompt: "令一名已受伤的角色回复1点体力", + filter(player, ai) { + return game.hasPlayer(function (current) { + if (current.isDamaged()) + return !ai || get.recoverEffect(current, player, player) > 0; }); }, }, { - prompt:'移动场上的一张牌', - filter(player,ai){ + prompt: "弃置一名角色区域内的两张牌", + filter(player, ai) { + return game.hasPlayer(function (current) { + return ( + current.countDiscardableCards(player, "hej", function (card) { + if (!ai) return true; + return ( + get.buttonValue({ + link: card, + }) * + get.attitude(player, current) > + 0 + ); + }) >= (ai ? 1 : Math.min(2, current.countDiscardableCards(player, "hej"))) + ); + }); + }, + }, + { + prompt: "移动场上的一张牌", + filter(player, ai) { return player.canMoveCard(ai); }, }, ], - ai:{ - order:10, - result:{player:1}, - threaten:3.2, - } + ai: { + order: 10, + result: { player: 1 }, + threaten: 3.2, + }, }, - yukito_yaxiang:{ - enable:'chooseToUse', - limited:true, - filter(event,player){ - return event.type=='dying'&&(player.name1=='key_yukito'||player.name2=='key_yukito'); + yukito_yaxiang: { + enable: "chooseToUse", + limited: true, + filter(event, player) { + return ( + event.type == "dying" && + (player.name1 == "key_yukito" || player.name2 == "key_yukito") + ); }, - filterTarget(card,player,target){ - return target==_status.event.dying; + filterTarget(card, player, target) { + return target == _status.event.dying; }, - selectTarget:-1, - skillAnimation:true, - animationColor:'key', - content(){ - 'step 0' - player.awakenSkill('yukito_yaxiang'); - player.reinitCharacter('key_yukito', 'key_crow', false); - 'step 1' - if(target.hp<3) target.recover(3-target.hp); - 'step 2' - var cards=target.getCards('j'); - if(cards.length) target.discard(cards); - 'step 3' - target.addSkills('misuzu_zhongyuan'); + selectTarget: -1, + skillAnimation: true, + animationColor: "key", + content() { + "step 0"; + player.awakenSkill("yukito_yaxiang"); + player.reinitCharacter("key_yukito", "key_crow", false); + "step 1"; + if (target.hp < 3) target.recover(3 - target.hp); + "step 2"; + var cards = target.getCards("j"); + if (cards.length) target.discard(cards); + "step 3"; + target.addSkills("misuzu_zhongyuan"); }, - derivation:'misuzu_zhongyuan', - ai:{ - save:true, - order:4, - result:{ - target(player,target){ - if(get.attitude(player,target)<4) return false; - if(player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,target,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,target); - return savable; - })>=1-target.hp) return false; - if(target==player||target==get.zhu(player)) return true; + derivation: "misuzu_zhongyuan", + ai: { + save: true, + order: 4, + result: { + target(player, target) { + if (get.attitude(player, target) < 4) return false; + if ( + player.countCards("h", function (card) { + var mod2 = game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + target, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") savable = savable(card, player, target); + return savable; + }) >= + 1 - target.hp + ) + return false; + if (target == player || target == get.zhu(player)) return true; return !player.hasUnknown(); }, }, }, }, - misuzu_zhongyuan:{ - trigger:{player:'judge'}, - skillAnimation:true, - animationColor:'key', - logTarget:'player', - cost(){ - 'step 0' - var str='你的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+',是否发动【终愿】修改判定结果?'; - if(player.isUnderControl()){ + misuzu_zhongyuan: { + trigger: { player: "judge" }, + skillAnimation: true, + animationColor: "key", + logTarget: "player", + cost() { + "step 0"; + var str = + "你的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + ",是否发动【终愿】修改判定结果?"; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ - _status.imchoosing=false; - event._result={ - bool:false, + var switchToAuto = function () { + _status.imchoosing = false; + event._result = { + bool: false, }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); }; - var chooseButton=function(player,str){ - var event=_status.event; - player=player||event.player; - if(!event._result) event._result={}; - var dialog=ui.create.dialog(str,'forcebutton','hidden'); - event.dialog=dialog; - dialog.addText('花色'); - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var listi=['spade','heart','club','diamond']; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + td.innerHTML = "" + get.translation(listi[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.suit=link; + this.classList.add("bluebg"); + event._result.suit = link; }); } dialog.content.appendChild(table); - dialog.addText('点数'); - var table2=document.createElement('div'); - table2.classList.add('add-setting'); - table2.style.margin='0'; - table2.style.width='100%'; - table2.style.position='relative'; - for(var i=1;i<14;i++){ - var td=ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode'); - td.link=i; + dialog.addText("点数"); + var table2 = document.createElement("div"); + table2.classList.add("add-setting"); + table2.style.margin = "0"; + table2.style.width = "100%"; + table2.style.position = "relative"; + for (var i = 1; i < 14; i++) { + var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); + td.link = i; table2.appendChild(td); - var num=i; - td.innerHTML=''+get.strNumber(num)+''; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + var num = i; + td.innerHTML = "" + get.strNumber(num) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.number=link; + this.classList.add("bluebg"); + event._result.number = link; }); } dialog.content.appendChild(table2); - dialog.add('  '); + dialog.add("  "); event.dialog.open(); - event.switchToAuto=function(){ - event._result={ - bool:false, + event.switchToAuto = function () { + event._result = { + bool: false, }; event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok','cancel2',function(link){ - var result=event._result; - if(link=='cancel2') result.bool=false; - else{ - if(!result.number||!result.suit) return; - result.bool=true; + event.control = ui.create.control("ok", "cancel2", function (link) { + var result = event._result; + if (link == "cancel2") result.bool = false; + else { + if (!result.number || !result.suit) return; + result.bool = true; } event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;iplayer.hasCard(card=>lib.skill.chihaya_huairou.filterCard(card,player),lib.skill.chihaya_huairou.position), - filterCard:(card,player)=>get.type(card)=='equip'&&player.canRecast(card), - check(card){ - if(!_status.event.player.hasEquipableSlot(get.subtype(card))) return 5; - return 3-get.value(card); + chihaya_huairou: { + audio: 2, + enable: "phaseUse", + position: "he", + filter: (event, player) => + player.hasCard( + (card) => lib.skill.chihaya_huairou.filterCard(card, player), + lib.skill.chihaya_huairou.position + ), + filterCard: (card, player) => get.type(card) == "equip" && player.canRecast(card), + check(card) { + if (!_status.event.player.hasEquipableSlot(get.subtype(card))) return 5; + return 3 - get.value(card); }, - content(){ + content() { player.recast(cards); }, - discard:false, - lose:false, - delay:false, - prompt:"将一张装备牌置入弃牌堆并摸一张牌", - ai:{ - order:10, - result:{ - player:1 - } - } - }, - chihaya_youfeng:{ - enable:'chooseToUse', - zhuanhuanji:true, - mark:true, - intro:{ - content(storage,player){ - return storage?'每轮限一次,你可以废除你的一个装备栏,视为使用一张基本牌。':'每轮限一次,你可以加1点体力上限,视为使用一张普通锦囊牌。'; + discard: false, + lose: false, + delay: false, + prompt: "将一张装备牌置入弃牌堆并摸一张牌", + ai: { + order: 10, + result: { + player: 1, }, }, - marktext:'☯', - init(player){ - player.storage.chihaya_youfeng=false; + }, + chihaya_youfeng: { + enable: "chooseToUse", + zhuanhuanji: true, + mark: true, + intro: { + content(storage, player) { + return storage + ? "每轮限一次,你可以废除你的一个装备栏,视为使用一张基本牌。" + : "每轮限一次,你可以加1点体力上限,视为使用一张普通锦囊牌。"; + }, }, - hiddenCard(player,name){ - if(player.storage.chihaya_youfeng&&!player.hasEnabledSlot()) return false; - if(player.hasSkill('chihaya_youfeng_'+(player.storage.chihaya_youfeng||false))) return false; - var type=get.type(name); - if(player.storage.chihaya_youfeng) return type=='basic'; - return type=='trick'; + marktext: "☯", + init(player) { + player.storage.chihaya_youfeng = false; }, - filter(event,player){ - if(player.storage.chihaya_youfeng&&!player.hasEnabledSlot()) return false; - if(player.hasSkill('chihaya_youfeng_'+(player.storage.chihaya_youfeng||false))) return false; - var type=player.storage.chihaya_youfeng?'basic':'trick'; - for(var name of lib.inpile){ - if(get.type(name)!=type) continue; - if(event.filterCard({name:name,isCard:true},player,event)) return true; + hiddenCard(player, name) { + if (player.storage.chihaya_youfeng && !player.hasEnabledSlot()) return false; + if (player.hasSkill("chihaya_youfeng_" + (player.storage.chihaya_youfeng || false))) + return false; + var type = get.type(name); + if (player.storage.chihaya_youfeng) return type == "basic"; + return type == "trick"; + }, + filter(event, player) { + if (player.storage.chihaya_youfeng && !player.hasEnabledSlot()) return false; + if (player.hasSkill("chihaya_youfeng_" + (player.storage.chihaya_youfeng || false))) + return false; + var type = player.storage.chihaya_youfeng ? "basic" : "trick"; + for (var name of lib.inpile) { + if (get.type(name) != type) continue; + if (event.filterCard({ name: name, isCard: true }, player, event)) return true; } return false; }, - chooseButton:{ - dialog(event,player){ - const dialog=ui.create.dialog('游凤','hidden'); - const equips=[]; - if(player.storage.chihaya_youfeng){ - for(let i=1;i<6;i++){ - if(!player.hasEnabledSlot(i)) continue; - equips.push([i,get.translation('equip'+i)]); + chooseButton: { + dialog(event, player) { + const dialog = ui.create.dialog("游凤", "hidden"); + const equips = []; + if (player.storage.chihaya_youfeng) { + for (let i = 1; i < 6; i++) { + if (!player.hasEnabledSlot(i)) continue; + equips.push([i, get.translation("equip" + i)]); } - if(equips.length>0) dialog.add([equips,'tdnodes']) + if (equips.length > 0) dialog.add([equips, "tdnodes"]); } - const type=player.storage.chihaya_youfeng?'basic':'trick'; - const list=[]; - for(const name of lib.inpile){ - if(get.type(name)!=type) continue; - if(event.filterCard({name:name,isCard:true},player,event)){ - list.push([type,'',name]); - if(name=='sha'){ - for(let j of lib.inpile_nature) list.push([type,'',name,j]); + const type = player.storage.chihaya_youfeng ? "basic" : "trick"; + const list = []; + for (const name of lib.inpile) { + if (get.type(name) != type) continue; + if (event.filterCard({ name: name, isCard: true }, player, event)) { + list.push([type, "", name]); + if (name == "sha") { + for (let j of lib.inpile_nature) list.push([type, "", name, j]); } } } - dialog.add([list,'vcard']); + dialog.add([list, "vcard"]); return dialog; }, - filter(button){ - if(ui.selected.buttons.length&&typeof button.link==typeof ui.selected.buttons[0].link) return false; + filter(button) { + if ( + ui.selected.buttons.length && + typeof button.link == typeof ui.selected.buttons[0].link + ) + return false; return true; }, - select(){ - if(_status.event.player.storage.chihaya_youfeng) return 2; + select() { + if (_status.event.player.storage.chihaya_youfeng) return 2; return 1; }, - check(button){ - var player=_status.event.player; - if(typeof button.link=='number'){ - if(!player.hasEmptySlot(button.link)){ - var card=player.getEquip(button.link); - if(card){ - var val=get.value(card); - if(val>0) return 0; - return 5-val; + check(button) { + var player = _status.event.player; + if (typeof button.link == "number") { + if (!player.hasEmptySlot(button.link)) { + var card = player.getEquip(button.link); + if (card) { + var val = get.value(card); + if (val > 0) return 0; + return 5 - val; } } - switch(button.link){ - case 3:return 4.5; - case 4:return 4.4; - case 5:return 4.3; - case 2:return (3-player.hp)*1.5; - case 1:{ - if(game.hasPlayer(function(current){ - return (get.realAttitude||get.attitude)(player,current)<0&&get.distance(player,current)>1; - })) return 0; + switch (button.link) { + case 3: + return 4.5; + case 4: + return 4.4; + case 5: + return 4.3; + case 2: + return (3 - player.hp) * 1.5; + case 1: { + if ( + game.hasPlayer(function (current) { + return ( + (get.realAttitude || get.attitude)(player, current) < 0 && + get.distance(player, current) > 1 + ); + }) + ) + return 0; return 3.2; } } } - var name=button.link[2]; - var evt=_status.event.getParent(); - if(get.type(name)=='basic'){ - if(name=='shan') return 2; - if(evt.type=='dying'){ - if(get.attitude(player,evt.dying)<2) return false; - if(name=='jiu') return 2.1; + var name = button.link[2]; + var evt = _status.event.getParent(); + if (get.type(name) == "basic") { + if (name == "shan") return 2; + if (evt.type == "dying") { + if (get.attitude(player, evt.dying) < 2) return false; + if (name == "jiu") return 2.1; return 1.9; } - if(evt.type=='phase') return player.getUseValue({name:name,nature:button.link[3],isCard:true}); + if (evt.type == "phase") + return player.getUseValue({ + name: name, + nature: button.link[3], + isCard: true, + }); return 1; } - if(!['chuqibuyi','shuiyanqijunx','juedou','nanman','wanjian','shunshou','zhujinqiyuan'].includes(name)) return 0; - var card={name:name,isCard:true}; - if(['shunshou','zhujinqiyuan'].includes(card.name)){ - if(!game.hasPlayer(function(current){ - return get.attitude(player,current)!=0&&get.distance(player,current)<=1&&player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })) return 0; - return player.getUseValue(card)-7; + if ( + ![ + "chuqibuyi", + "shuiyanqijunx", + "juedou", + "nanman", + "wanjian", + "shunshou", + "zhujinqiyuan", + ].includes(name) + ) + return 0; + var card = { name: name, isCard: true }; + if (["shunshou", "zhujinqiyuan"].includes(card.name)) { + if ( + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) != 0 && + get.distance(player, current) <= 1 && + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return 0; + return player.getUseValue(card) - 7; } - return player.getUseValue(card)-4; + return player.getUseValue(card) - 4; }, - backup(links,player){ - if(links.length==1) return { - filterCard(){return false}, - selectCard:-1, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, - }, - popname:true, - precontent(){ - player.logSkill('chihaya_youfeng'); - player.gainMaxHp(); - delete event.result.skill; - player.addTempSkill('chihaya_youfeng_'+(player.storage.chihaya_youfeng||false),'roundStart'); - player.changeZhuanhuanji('chihaya_youfeng'); - }, - } - if(typeof links[1]=='number') links.reverse(); - var equip=links[0]; - var name=links[1][2]; - var nature=links[1][3]; + backup(links, player) { + if (links.length == 1) + return { + filterCard() { + return false; + }, + selectCard: -1, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, + }, + popname: true, + precontent() { + player.logSkill("chihaya_youfeng"); + player.gainMaxHp(); + delete event.result.skill; + player.addTempSkill( + "chihaya_youfeng_" + (player.storage.chihaya_youfeng || false), + "roundStart" + ); + player.changeZhuanhuanji("chihaya_youfeng"); + }, + }; + if (typeof links[1] == "number") links.reverse(); + var equip = links[0]; + var name = links[1][2]; + var nature = links[1][3]; return { - filterCard(){return false}, - selectCard:-1, - equip:equip, - viewAs:{ - name:name, - nature:nature, - isCard:true, + filterCard() { + return false; }, - popname:true, - precontent(){ - player.logSkill('chihaya_youfeng'); + selectCard: -1, + equip: equip, + viewAs: { + name: name, + nature: nature, + isCard: true, + }, + popname: true, + precontent() { + player.logSkill("chihaya_youfeng"); player.disableEquip(lib.skill.chihaya_youfeng_backup.equip); delete event.result.skill; - player.addTempSkill('chihaya_youfeng_'+(player.storage.chihaya_youfeng||false),'roundStart'); - player.changeZhuanhuanji('chihaya_youfeng'); + player.addTempSkill( + "chihaya_youfeng_" + (player.storage.chihaya_youfeng || false), + "roundStart" + ); + player.changeZhuanhuanji("chihaya_youfeng"); }, - } + }; }, - prompt(links,player){ - if(links.length==1) return '增加1点体力上限,视为使用'+(get.translation(links[0][3])||'')+get.translation(links[0][2]); - if(typeof links[1]=='number') links.reverse(); - var equip='equip'+links[0]; - var name=links[1][2]; - var nature=links[1][3]; - return '废除自己的'+get.translation(equip)+'栏,视为使用'+(get.translation(nature)||'')+get.translation(name); + prompt(links, player) { + if (links.length == 1) + return ( + "增加1点体力上限,视为使用" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + ); + if (typeof links[1] == "number") links.reverse(); + var equip = "equip" + links[0]; + var name = links[1][2]; + var nature = links[1][3]; + return ( + "废除自己的" + + get.translation(equip) + + "栏,视为使用" + + (get.translation(nature) || "") + + get.translation(name) + ); }, }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(arg=='respond') return false; - if(!player.storage.chihaya_youfeng||player.hasSkill('chihaya_youfeng_true')) return false; + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + if (arg == "respond") return false; + if (!player.storage.chihaya_youfeng || player.hasSkill("chihaya_youfeng_true")) + return false; }, - order:1, - result:{ - player:1, + order: 1, + result: { + player: 1, }, }, }, - chihaya_youfeng_true:{charlotte:true}, - chihaya_youfeng_false:{charlotte:true}, - rumi_shuwu:{ - mod:{ - cardUsable(card){ - if(card.name=='sha') return Infinity; + chihaya_youfeng_true: { charlotte: true }, + chihaya_youfeng_false: { charlotte: true }, + rumi_shuwu: { + mod: { + cardUsable(card) { + if (card.name == "sha") return Infinity; }, - targetInRange(card){ - if(card.name=='sha') return true; + targetInRange(card) { + if (card.name == "sha") return true; }, }, - trigger:{player:'useCard2'}, - filter(event,player){ - var card=event.card; - var info=get.info(card); - if(info.type!='trick'||info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ + trigger: { player: "useCard2" }, + filter(event, player) { + var card = event.card; + var info = get.info(card); + if (info.type != "trick" || info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { return true; } } return false; }, - autodelay:true, - async cost(event, trigger, player){ - var prompt2='为'+get.translation(trigger.card)+'增加一个目标'; - const {result} = await player.chooseTarget(get.prompt('rumi_shuwu'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); + autodelay: true, + async cost(event, trigger, player) { + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + const { result } = await player + .chooseTarget(get.prompt("rumi_shuwu"), function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); event.result = result; }, - content(){ + content() { trigger.targets.addArray(event.targets); - game.log(event.targets, '也成为了', trigger.card, '的目标'); + game.log(event.targets, "也成为了", trigger.card, "的目标"); }, - group:'rumi_shuwu2', + group: "rumi_shuwu2", }, - rumi_shuwu2:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - filter(event,player){ - if(player.hp<=3) return true; - if(player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'&&evt.addCount!==false&&evt.getParent('phaseUse')==event; - }).length<=1) return true; - if(player.getHistory('sourceDamage',function(evt){ - return get.type(evt.card,false)=='trick'&&evt.getParent('phaseUse')==event; - }).length==0) return true; + rumi_shuwu2: { + trigger: { player: "phaseUseEnd" }, + forced: true, + filter(event, player) { + if (player.hp <= 3) return true; + if ( + player.getHistory("useCard", function (evt) { + return ( + evt.card.name == "sha" && + evt.addCount !== false && + evt.getParent("phaseUse") == event + ); + }).length <= 1 + ) + return true; + if ( + player.getHistory("sourceDamage", function (evt) { + return get.type(evt.card, false) == "trick" && evt.getParent("phaseUse") == event; + }).length == 0 + ) + return true; return false; }, - content(){ - var num=0; - if(player.hp<=3) num++; - if(player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'&&evt.addCount!==false&&evt.getParent('phaseUse')==trigger; - }).length<=1) num++; - if(player.getHistory('sourceDamage',function(evt){ - return get.type(evt.card,false)=='trick'&&evt.getParent('phaseUse')==trigger; - }).length==0) num++; + content() { + var num = 0; + if (player.hp <= 3) num++; + if ( + player.getHistory("useCard", function (evt) { + return ( + evt.card.name == "sha" && + evt.addCount !== false && + evt.getParent("phaseUse") == trigger + ); + }).length <= 1 + ) + num++; + if ( + player.getHistory("sourceDamage", function (evt) { + return ( + get.type(evt.card, false) == "trick" && evt.getParent("phaseUse") == trigger + ); + }).length == 0 + ) + num++; player.draw(num); - player.addTempSkill('rumi_shuwu3'); - player.addMark('rumi_shuwu3',num,false); + player.addTempSkill("rumi_shuwu3"); + player.addMark("rumi_shuwu3", num, false); }, }, - rumi_shuwu3:{ - mod:{ - maxHandcard(player,num){ - return num+player.countMark('rumi_shuwu3'); + rumi_shuwu3: { + mod: { + maxHandcard(player, num) { + return num + player.countMark("rumi_shuwu3"); }, }, - onremove:true, + onremove: true, }, - sakuya_junbu:{ - mod:{ - targetInRange(card,player){ - if(player.countDisabledSlot()>=1) return true; + sakuya_junbu: { + mod: { + targetInRange(card, player) { + if (player.countDisabledSlot() >= 1) return true; }, - cardUsable(card,player){ - if(player.countDisabledSlot()>=2) return Infinity; + cardUsable(card, player) { + if (player.countDisabledSlot() >= 2) return Infinity; }, }, - trigger:{player:'useCard2'}, - filter(event,player){ - if(player.countDisabledSlot()>=4) return true; - return lib.skill.sakuya_junbu.filter2.apply(this,arguments); + trigger: { player: "useCard2" }, + filter(event, player) { + if (player.countDisabledSlot() >= 4) return true; + return lib.skill.sakuya_junbu.filter2.apply(this, arguments); }, - filter2(event,player){ - if(player.countDisabledSlot()<3) return false; - var card=event.card; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ + filter2(event, player) { + if (player.countDisabledSlot() < 3) return false; + var card = event.card; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { return true; } } return false; }, - async cost(event, trigger, player){ - const result = {bool:false}; + async cost(event, trigger, player) { + const result = { bool: false }; event.result = result; - if(player.countDisabledSlot()>=4){ + if (player.countDisabledSlot() >= 4) { result.bool = true; - if(!lib.skill.sakuya_junbu.filter2(trigger,player)){ + if (!lib.skill.sakuya_junbu.filter2(trigger, player)) { return; } } - var prompt2='为'+get.translation(trigger.card)+'增加一个目标'; - const {result:result2} = await player.chooseTarget(get.prompt('sakuya_junbu'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - if(result2.bool){ + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + const { result: result2 } = await player + .chooseTarget(get.prompt("sakuya_junbu"), function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + if (result2.bool) { result.bool = true; result.targets = result2.targets; } }, - async content(event, trigger, player){ - if(player.countDisabledSlot()>=4){ + async content(event, trigger, player) { + if (player.countDisabledSlot() >= 4) { trigger.directHit.addArray(game.players); - game.log(trigger.card, '不可被响应'); + game.log(trigger.card, "不可被响应"); } - if(event.targets && event.targets.length>0){ + if (event.targets && event.targets.length > 0) { trigger.targets.addArray(event.targets); - game.log(event.targets, '也成为了', trigger.card, '的目标'); + game.log(event.targets, "也成为了", trigger.card, "的目标"); } }, - group:'sakuya_junbu_damage', - subSkill:{ - damage:{ - trigger:{source:'damageBegin1'}, - forced:true, - sub:true, - filter(event,player){ - return !player.hasEnabledSlot()&&event.getParent().type=='card'; + group: "sakuya_junbu_damage", + subSkill: { + damage: { + trigger: { source: "damageBegin1" }, + forced: true, + sub: true, + filter(event, player) { + return !player.hasEnabledSlot() && event.getParent().type == "card"; }, - logTarget:'player', - content(){ + logTarget: "player", + content() { player.loseHp(); trigger.num++; }, }, }, }, - hiroto_huyu:{ - trigger:{global:'phaseUseEnd'}, - noHidden:true, - filter(event,player){ - return player!=event.player&&player.hasSkill('hiroto_huyu')&&!player.hasSkill('hiroto_zonglve')&&event.player.countCards('h')>0; + hiroto_huyu: { + trigger: { global: "phaseUseEnd" }, + noHidden: true, + filter(event, player) { + return ( + player != event.player && + player.hasSkill("hiroto_huyu") && + !player.hasSkill("hiroto_zonglve") && + event.player.countCards("h") > 0 + ); }, - async cost(event, trigger, player){ - event.result = await trigger.player.chooseCard(2,'h','是否对'+get.translation(player)+'发动【虎驭】?','将两张手牌交给该角色,然后令其获得〖纵略〗并于下回合获得该角色得到的所有牌').set('goon',function(){ - var source=trigger.player; - if(get.attitude(source,player)>0) return 7; - if(source.hp>2) return 4; - return 0; - }()).set('ai',function(card){ - return _status.event.goon-get.value(card); - }).forResult(); + async cost(event, trigger, player) { + event.result = await trigger.player + .chooseCard( + 2, + "h", + "是否对" + get.translation(player) + "发动【虎驭】?", + "将两张手牌交给该角色,然后令其获得〖纵略〗并于下回合获得该角色得到的所有牌" + ) + .set( + "goon", + (function () { + var source = trigger.player; + if (get.attitude(source, player) > 0) return 7; + if (source.hp > 2) return 4; + return 0; + })() + ) + .set("ai", function (card) { + return _status.event.goon - get.value(card); + }) + .forResult(); }, - content(){ - var target=trigger.player; - target.give(cards,player); - player.storage.hiroto_huyu2=target; - player.addSkills('hiroto_zonglve'); - player.addSkill('hiroto_huyu2'); + content() { + var target = trigger.player; + target.give(cards, player); + player.storage.hiroto_huyu2 = target; + player.addSkills("hiroto_zonglve"); + player.addSkill("hiroto_huyu2"); }, - derivation:'hiroto_zonglve', + derivation: "hiroto_zonglve", }, - hiroto_huyu2:{ - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - async content(event,trigger,player){ - player.removeSkill('hiroto_huyu2'); - await player.removeSkills('hiroto_zonglve'); - player.removeGaintag('hiroto_huyu2'); - var target=player.storage.hiroto_huyu2; - if(target&&target.isIn()){ - var cards=[]; - player.getHistory('gain',function(evt){ + hiroto_huyu2: { + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + async content(event, trigger, player) { + player.removeSkill("hiroto_huyu2"); + await player.removeSkills("hiroto_zonglve"); + player.removeGaintag("hiroto_huyu2"); + var target = player.storage.hiroto_huyu2; + if (target && target.isIn()) { + var cards = []; + player.getHistory("gain", function (evt) { cards.addArray(evt.cards); }); - var he=player.getCards('he'); - cards=cards.filter(function(card){ + var he = player.getCards("he"); + cards = cards.filter(function (card) { return he.includes(card); }); - if(cards.length) target.gain(cards,player,'giveAuto','bySelf'); + if (cards.length) target.gain(cards, player, "giveAuto", "bySelf"); } }, - mark:'character', - intro:{content:'已成为$的工具人'}, - group:'hiroto_huyu_gain', + mark: "character", + intro: { content: "已成为$的工具人" }, + group: "hiroto_huyu_gain", }, - hiroto_huyu_gain:{ - trigger:{player:'gainBegin'}, - silent:true, - filter(event,player){ - if(player==_status.currentPhase) event.gaintag.add('hiroto_huyu2'); + hiroto_huyu_gain: { + trigger: { player: "gainBegin" }, + silent: true, + filter(event, player) { + if (player == _status.currentPhase) event.gaintag.add("hiroto_huyu2"); return false; }, }, - hiroto_zonglve:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + hiroto_zonglve: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; }, - filterCard:true, - delay:false, - charlotte:true, - position:'h', - discard:false, - lose:false, - content(){ - 'step 0' - player.choosePlayerCard(true,target,'h'); - 'step 1' - event.card=result.cards[0]; - player.$compare(cards[0],target,event.card); - game.log(player,'展示了',cards[0]); - game.log(target,'展示了',event.card) + filterCard: true, + delay: false, + charlotte: true, + position: "h", + discard: false, + lose: false, + content() { + "step 0"; + player.choosePlayerCard(true, target, "h"); + "step 1"; + event.card = result.cards[0]; + player.$compare(cards[0], target, event.card); + game.log(player, "展示了", cards[0]); + game.log(target, "展示了", event.card); game.delay(3.5); - 'step 2' + "step 2"; game.broadcastAll(ui.clear); - if(get.color(cards[0],player)==get.color(card,target)){ - target.damage('nocard'); - target.discard(card).animate=false; - } - else player.gainPlayerCard(target,true,2,'hej'); + if (get.color(cards[0], player) == get.color(card, target)) { + target.damage("nocard"); + target.discard(card).animate = false; + } else player.gainPlayerCard(target, true, 2, "hej"); }, - mod:{ - maxHandcard(player,num){ - return num+3; + mod: { + maxHandcard(player, num) { + return num + 3; }, }, - ai:{ - order:7, - result:{ - target:-1, + ai: { + order: 7, + result: { + target: -1, }, }, }, - hiroto_tuolao:{ - trigger:{player:'phaseAfter'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'water', - filter(event,player){ - return player.phaseNumber>1&&!player.getHistory('lose',function(evt){ - return evt.getParent(2).name=='hiroto_huyu2'; - }).length; + hiroto_tuolao: { + trigger: { player: "phaseAfter" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return ( + player.phaseNumber > 1 && + !player.getHistory("lose", function (evt) { + return evt.getParent(2).name == "hiroto_huyu2"; + }).length + ); }, - content(){ - player.awakenSkill('hiroto_tuolao'); + content() { + player.awakenSkill("hiroto_tuolao"); player.draw(3); - player.changeSkills(['hiroto_zonglve'],['hiroto_huyu']); + player.changeSkills(["hiroto_zonglve"], ["hiroto_huyu"]); }, }, - shizuku_sizhi:{ - audio:2, - enable:'phaseUse', - getResult(cards){ - var l=cards.length; - var all=Math.pow(l,2); - var list=[]; - for(var i=1;i0) array.push(cards[j]) + shizuku_sizhi: { + audio: 2, + enable: "phaseUse", + getResult(cards) { + var l = cards.length; + var all = Math.pow(l, 2); + var list = []; + for (var i = 1; i < all; i++) { + var array = []; + for (var j = 0; j < l; j++) { + if (Math.floor((i % Math.pow(2, j + 1)) / Math.pow(2, j)) > 0) + array.push(cards[j]); } - var num=0; - for(var k of array){ - num+=get.number(k); + var num = 0; + for (var k of array) { + num += get.number(k); } - if(num==13) list.push(array); + if (num == 13) list.push(array); } - if(list.length){ - list.sort(function(a,b){ - if(a.length!=b.length) return b.length-a.length; - return get.value(a)-get.value(b); + if (list.length) { + list.sort(function (a, b) { + if (a.length != b.length) return b.length - a.length; + return get.value(a) - get.value(b); }); return list[0]; } return list; }, - usable:1, - filterCard(card){ - var num=0; - for(var i=0;i0) array.push(cards[j]) + "step 1"; + var num = result.number; + var next = player.chooseToDiscard( + "是否弃置任意张点数之和为" + get.cnNumber(num) + "的牌并回复1点体力?", + function (card) { + var num = 0; + for (var i = 0; i < ui.selected.cards.length; i++) { + num += get.number(ui.selected.cards[i]); } - var numx=0; - for(var k of array){ - numx+=get.number(k); - } - if(numx==num) list.push(array); + return get.number(card) + num <= _status.event.num; + }, + "he" + ); + next.set("num", num); + next.set("complexCard", true); + next.set("selectCard", function () { + var num = 0; + for (var i = 0; i < ui.selected.cards.length; i++) { + num += get.number(ui.selected.cards[i]); } - if(list.length){ - list.sort(function(a,b){ - return get.value(a)-get.value(b); - }); - return list[0]; - } - return list; - }()); - next.set('ai',function(card){ - if(!_status.event.cardResult.includes(card)) return 0; - return 6-get.value(card); + if (num == _status.event.num) return ui.selected.cards.length; + return ui.selected.cards.length + 2; }); - 'step 2' - if(result.bool) player.recover(); + next.set( + "cardResult", + (function () { + var cards = player.getCards("he"); + var l = cards.length; + var all = Math.pow(l, 2); + var list = []; + for (var i = 1; i < all; i++) { + var array = []; + for (var j = 0; j < l; j++) { + if (Math.floor((i % Math.pow(2, j + 1)) / Math.pow(2, j)) > 0) + array.push(cards[j]); + } + var numx = 0; + for (var k of array) { + numx += get.number(k); + } + if (numx == num) list.push(array); + } + if (list.length) { + list.sort(function (a, b) { + return get.value(a) - get.value(b); + }); + return list[0]; + } + return list; + })() + ); + next.set("ai", function (card) { + if (!_status.event.cardResult.includes(card)) return 0; + return 6 - get.value(card); + }); + "step 2"; + if (result.bool) player.recover(); }, }, - shizuku_sanhua:{ - trigger:{player:'die'}, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('shizuku_sanhua'),lib.filter.notMe).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).forResult(); + shizuku_sanhua: { + trigger: { player: "die" }, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("shizuku_sanhua"), lib.filter.notMe) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { var target = event.targets[0]; var names = []; var cards = []; while (cards.length < 4) { - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&!names.includes(card.name)&&get.type(card)=='basic'; + var card = get.cardPile2(function (card) { + return ( + !cards.includes(card) && + !names.includes(card.name) && + get.type(card) == "basic" + ); }); - if(card){ + if (card) { cards.push(card); names.push(card.name); - } - else break; + } else break; } - if(cards.length) await target.gain(cards,'gain2'); + if (cards.length) await target.gain(cards, "gain2"); }, }, - shiroha_yuzhao:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + shiroha_yuzhao: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - charlotte:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + charlotte: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - player.addToExpansion(get.cards(game.countGroup()),'draw').gaintag.add('shiroha_yuzhao'); + content() { + player.addToExpansion(get.cards(game.countGroup()), "draw").gaintag.add("shiroha_yuzhao"); }, - marktext:'兆', - intro:{ - markcount:'expansion', - mark(dialog,content,player){ - var content=player.getExpansions('shiroha_yuzhao'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + marktext: "兆", + intro: { + markcount: "expansion", + mark(dialog, content, player) { + var content = player.getExpansions("shiroha_yuzhao"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { dialog.addAuto(content); - } - else{ - return '共有'+get.cnNumber(content.length)+'张牌'; + } else { + return "共有" + get.cnNumber(content.length) + "张牌"; } } }, - content(content,player){ - var content=player.getExpansions('shiroha_yuzhao'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + content(content, player) { + var content = player.getExpansions("shiroha_yuzhao"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { return get.translation(content); } - return '共有'+get.cnNumber(content.length)+'张牌'; + return "共有" + get.cnNumber(content.length) + "张牌"; } - } + }, }, - group:'shiroha_yuzhao_umi', + group: "shiroha_yuzhao_umi", }, - shiroha_yuzhao_umi:{ - trigger:{global:'phaseBegin'}, - forced:true, - filter(event,player){ - return player.getExpansions('shiroha_yuzhao').length>0&&get.distance(event.player,player)<=1; + shiroha_yuzhao_umi: { + trigger: { global: "phaseBegin" }, + forced: true, + filter(event, player) { + return ( + player.getExpansions("shiroha_yuzhao").length > 0 && + get.distance(event.player, player) <= 1 + ); }, - content(){ - 'step 0' - event.num=game.countGroup(); - player.addToExpansion(get.cards(event.num)).gaintag.add('shiroha_yuzhao'); - 'step 1' - var next=player.chooseToMove(),num=game.countGroup(); - next.set('prompt','预兆:将'+get.cnNumber(num)+'张牌置于牌堆顶'); - next.set('num',num); - next.set('forced',true); - next.set('filterOk',function(moved){ - return moved[1].length==_status.event.num; + content() { + "step 0"; + event.num = game.countGroup(); + player.addToExpansion(get.cards(event.num)).gaintag.add("shiroha_yuzhao"); + "step 1"; + var next = player.chooseToMove(), + num = game.countGroup(); + next.set("prompt", "预兆:将" + get.cnNumber(num) + "张牌置于牌堆顶"); + next.set("num", num); + next.set("forced", true); + next.set("filterOk", function (moved) { + return moved[1].length == _status.event.num; }); - next.set('filterMove',function(from,to,moved){ - if(to!=1) return true; - return moved[1].length<_status.event.num; + next.set("filterMove", function (from, to, moved) { + if (to != 1) return true; + return moved[1].length < _status.event.num; }); - next.set('list',[ - [get.translation(player)+'(你)的“兆”',player.getExpansions('shiroha_yuzhao')], - ['牌堆顶'], + next.set("list", [ + [get.translation(player) + "(你)的“兆”", player.getExpansions("shiroha_yuzhao")], + ["牌堆顶"], ]); - next.set('processAI',function(list){ - var cards=list[0][1],cards2=cards.randomRemove(_status.event.num); - return [cards,cards2]; + next.set("processAI", function (list) { + var cards = list[0][1], + cards2 = cards.randomRemove(_status.event.num); + return [cards, cards2]; }); - 'step 2' - if(result&&result.bool){ - var cards=result.moved[1]; - player.lose(cards,ui.cardPile,'insert'); + "step 2"; + if (result && result.bool) { + var cards = result.moved[1]; + player.lose(cards, ui.cardPile, "insert"); } game.updateRoundNumber(); }, }, - shiroha_guying:{ - derivation:'shiroha_guying_rewrite', - trigger:{ - player:'damageBegin3', - source:'damageBegin1', + shiroha_guying: { + derivation: "shiroha_guying_rewrite", + trigger: { + player: "damageBegin3", + source: "damageBegin1", }, - filter(event,player,name){ - if(!player.storage.shiroha_jiezhao&&player.hasSkill('shiroha_guying_temp')) return false; - if(name=='damageBegin3') return true; - return player!=event.player; + filter(event, player, name) { + if (!player.storage.shiroha_jiezhao && player.hasSkill("shiroha_guying_temp")) + return false; + if (name == "damageBegin3") return true; + return player != event.player; }, - locked(skill,player){ - if(!player||!player.storage.shiroha_jiezhao) return true; + locked(skill, player) { + if (!player || !player.storage.shiroha_jiezhao) return true; return false; }, - cost(){ - 'step 0' - var num=event.triggername=='damageBegin3'?-1:1; - if(player.storage.shiroha_jiezhao||!player.hasSkill('shiroha_guying')){ - if(num>0) player.chooseBool(get.prompt('shiroha_guying',trigger.player),'进行判定。若判定结果为黑色,则即将对其造成的伤害+1'); - else player.chooseBool(get.prompt('shiroha_guying'),'进行判定。若判定结果为红色,则即将受到的伤害-1'); - } - else event._result={bool:true}; - 'step 1' + cost() { + "step 0"; + var num = event.triggername == "damageBegin3" ? -1 : 1; + if (player.storage.shiroha_jiezhao || !player.hasSkill("shiroha_guying")) { + if (num > 0) + player.chooseBool( + get.prompt("shiroha_guying", trigger.player), + "进行判定。若判定结果为黑色,则即将对其造成的伤害+1" + ); + else + player.chooseBool( + get.prompt("shiroha_guying"), + "进行判定。若判定结果为红色,则即将受到的伤害-1" + ); + } else event._result = { bool: true }; + "step 1"; event.result = result; }, - content(){ - 'step 0' - var num=event.triggername=='damageBegin3'?-1:1; - event.num=num; - player.addTempSkill('shiroha_guying_temp'); - player.judge(function(card){ - return (get.color(card)==(_status.event.getParent('shiroha_guying').num>0?'black':'red'))?2:0; - }).judge2=function(result){ - return result.bool?true:false; + content() { + "step 0"; + var num = event.triggername == "damageBegin3" ? -1 : 1; + event.num = num; + player.addTempSkill("shiroha_guying_temp"); + player.judge(function (card) { + return get.color(card) == + (_status.event.getParent("shiroha_guying").num > 0 ? "black" : "red") + ? 2 + : 0; + }).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 1' - if(result.bool) trigger.num+=num; + "step 1"; + if (result.bool) trigger.num += num; }, }, - shiroha_guying_temp:{charlotte:true}, - shiroha_jiezhao:{ - trigger:{global:'judge'}, - filter(event,player){ - return player.getExpansions('shiroha_yuzhao').length&&event.player.isIn(); + shiroha_guying_temp: { charlotte: true }, + shiroha_jiezhao: { + trigger: { global: "judge" }, + filter(event, player) { + return player.getExpansions("shiroha_yuzhao").length && event.player.isIn(); }, - async cost(event, trigger, player){ - const list = player.getExpansions('shiroha_yuzhao'); - const {result} = await player.chooseButton([get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+get.translation(trigger.player.judging[0])+ - ','+get.prompt('shiroha_jiezhao'),list,'hidden'],function(button){ - var card=button.link; - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - return result*attitude; - }).set('judging',trigger.player.judging[0]).set('filterButton',function(button){ - var player=_status.event.player; - var card=button.link; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }); - if(result.bool){ - event.result = {bool:true, cards:result.links}; + async cost(event, trigger, player) { + const list = player.getExpansions("shiroha_yuzhao"); + const { result } = await player + .chooseButton( + [ + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("shiroha_jiezhao"), + list, + "hidden", + ], + function (button) { + var card = button.link; + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + return result * attitude; + } + ) + .set("judging", trigger.player.judging[0]) + .set("filterButton", function (button) { + var player = _status.event.player; + var card = button.link; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + }); + if (result.bool) { + event.result = { bool: true, cards: result.links }; } }, //logSkill留给respond - popup:false, - async content(event, trigger, player){ + popup: false, + async content(event, trigger, player) { const cards = event.cards; - await player.respond(cards, 'shiroha_jiezhao','highlight','noOrdering'); - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + await player.respond(cards, "shiroha_jiezhao", "highlight", "noOrdering"); + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo("deletenode", player, get.cardsInfo([trigger.player.judging[0].clone])); } const oldJudgeCard = trigger.player.judging[0]; trigger.player.judging[0] = cards[0]; trigger.orderingCards.addArray(cards); - game.log(trigger.player,'的判定牌改为',cards[0]); + game.log(trigger.player, "的判定牌改为", cards[0]); await game.cardsDiscard(oldJudgeCard); await game.asyncDelay(2); - if(!player.getExpansions('shiroha_yuzhao').length){ - player.storage.shiroha_jiezhao=true; + if (!player.getExpansions("shiroha_yuzhao").length) { + player.storage.shiroha_jiezhao = true; player.gainMaxHp(); player.recover(); - var list=['umi_chaofan','ao_xishi','tsumugi_mugyu','kamome_jieban']; - var skill=list.randomGet(); - player.flashAvatar('shiroha_jiezhao','key_'+skill.split('_')[0]); + var list = ["umi_chaofan", "ao_xishi", "tsumugi_mugyu", "kamome_jieban"]; + var skill = list.randomGet(); + player.flashAvatar("shiroha_jiezhao", "key_" + skill.split("_")[0]); await player.addSkills(skill); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:0.6 - } + ai: { + rejudge: true, + tag: { + rejudge: 0.6, + }, + combo: "shiroha_yuzhao" }, - derivation:['umi_chaofan','ao_xishi','tsumugi_mugyu','kamome_jieban'], + derivation: ["umi_chaofan", "ao_xishi", "tsumugi_mugyu", "kamome_jieban"], }, - jojiro_shensu:{ - group:['jojiro_shensu1','jojiro_shensu2','jojiro_shensu4'], - charlotte:true, + jojiro_shensu: { + group: ["jojiro_shensu1", "jojiro_shensu2", "jojiro_shensu4"], + charlotte: true, }, - jojiro_shensu1:{ - trigger:{player:'phaseJudgeBefore'}, - async cost(event,trigger,player){ - const check = player.countCards('h')>2; - event.result = await player.chooseTarget(get.prompt("jojiro_shensu"),"跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',check).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }).forResult(); + jojiro_shensu1: { + trigger: { player: "phaseJudgeBefore" }, + async cost(event, trigger, player) { + const check = player.countCards("h") > 2; + event.result = await player + .chooseTarget( + get.prompt("jojiro_shensu"), + "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", check) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }) + .forResult(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await trigger.cancel(); - player.skip('phaseDraw'); - await player.useCard({name:'sha',isCard:true},event.targets[0],false); - } + player.skip("phaseDraw"); + await player.useCard({ name: "sha", isCard: true }, event.targets[0], false); + }, }, - jojiro_shensu2:{ - trigger:{player:'phaseUseBefore'}, - filter(event,player){ - return player.countCards('he',{type:'equip'})>0; + jojiro_shensu2: { + trigger: { player: "phaseUseBefore" }, + filter(event, player) { + return player.countCards("he", { type: "equip" }) > 0; }, - async cost(event,trigger,player){ + async cost(event, trigger, player) { const check = player.needsToDiscard(); - event.result = await player.chooseCardTarget({ - prompt:get.prompt('jojiro_shensu'), - prompt2:"弃置一张装备牌并跳过出牌阶段,视为对一名其他角色使用一张【杀】", - filterCard(card,player){ - return get.type(card)=='equip'&&lib.filter.cardDiscardable(card,player) - }, - position:'he', - filterTarget(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }, - ai1(card){ - if(_status.event.check) return 0; - return 6-get.value(card); - }, - ai2(target){ - if(_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }, - check:check - }).forResult(); + event.result = await player + .chooseCardTarget({ + prompt: get.prompt("jojiro_shensu"), + prompt2: "弃置一张装备牌并跳过出牌阶段,视为对一名其他角色使用一张【杀】", + filterCard(card, player) { + return get.type(card) == "equip" && lib.filter.cardDiscardable(card, player); + }, + position: "he", + filterTarget(card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + }, + ai1(card) { + if (_status.event.check) return 0; + return 6 - get.value(card); + }, + ai2(target) { + if (_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }, + check: check, + }) + .forResult(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await trigger.cancel(); await player.discard(event.cards[0]); - await player.useCard({name:'sha',isCard:true}, event.targets[0]); - } - }, - jojiro_shensu4:{ - trigger:{player:'phaseDiscardBefore'}, - async cost(event, trigger, player){ - var check=player.needsToDiscard()||player.isTurnedOver()||(player.hasSkill('shebian')&&player.canMoveCard(true,true)); - event.result = await player.chooseTarget(get.prompt('jojiro_shensu'),"跳过弃牌阶段并将武将牌翻面,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',check).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player); - }).forResult(); + await player.useCard({ name: "sha", isCard: true }, event.targets[0]); }, - async content(event, trigger, player){ + }, + jojiro_shensu4: { + trigger: { player: "phaseDiscardBefore" }, + async cost(event, trigger, player) { + var check = + player.needsToDiscard() || + player.isTurnedOver() || + (player.hasSkill("shebian") && player.canMoveCard(true, true)); + event.result = await player + .chooseTarget( + get.prompt("jojiro_shensu"), + "跳过弃牌阶段并将武将牌翻面,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", check) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect( + target, + { name: "sha" }, + _status.event.player, + _status.event.player + ); + }) + .forResult(); + }, + async content(event, trigger, player) { await trigger.cancel(); await player.turnOver(); - await player.useCard({name:'sha',isCard:true}, event.targets[0], false); - } - }, - jojiro_shunying:{ - trigger:{player:'phaseEnd'}, - forced:true, - charlotte:true, - filter(event,player){ - return player.getHistory('skipped').length>0; + await player.useCard({ name: "sha", isCard: true }, event.targets[0], false); }, - content(){ - 'step 0' - var num=player.getHistory('skipped').length; - event.num=num; - player.chooseToMoveChess(num,'瞬影:移动至多'+get.cnNumber(num)+'格或失去1点体力'); - 'step 1' - if(!result.bool) player.loseHp(); + }, + jojiro_shunying: { + trigger: { player: "phaseEnd" }, + forced: true, + charlotte: true, + filter(event, player) { + return player.getHistory("skipped").length > 0; + }, + content() { + "step 0"; + var num = player.getHistory("skipped").length; + event.num = num; + player.chooseToMoveChess(num, "瞬影:移动至多" + get.cnNumber(num) + "格或失去1点体力"); + "step 1"; + if (!result.bool) player.loseHp(); else player.draw(num); }, }, - kotori_yumo:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + kotori_yumo: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - charlotte:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + charlotte: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - var list=['wei','shu','wu','qun','jin']; - for(var i of list){ - if(!player.hasMark('kotori_yumo_'+i)){ - player.addMark('kotori_yumo_'+i,1,false); - game.log(player,'获得了一个',lib.translate['kotori_yumo_'+i].replace(/魔物/g,'【魔物】')); + content() { + var list = ["wei", "shu", "wu", "qun", "jin"]; + for (var i of list) { + if (!player.hasMark("kotori_yumo_" + i)) { + player.addMark("kotori_yumo_" + i, 1, false); + game.log( + player, + "获得了一个", + lib.translate["kotori_yumo_" + i].replace(/魔物/g, "【魔物】") + ); } } }, - group:['kotori_yumo_damage','kotori_yumo_gain'], + group: ["kotori_yumo_damage", "kotori_yumo_gain"], }, - kotori_yumo_damage:{ - trigger:{global:'damageEnd'}, - forced:true, - filter(event,player){ - var name='kotori_yumo_'+event.player.group; - return lib.skill[name]&&!player.hasMark(name); + kotori_yumo_damage: { + trigger: { global: "damageEnd" }, + forced: true, + filter(event, player) { + var name = "kotori_yumo_" + event.player.group; + return lib.skill[name] && !player.hasMark(name); }, - popup:false, - content(){ - game.log(player,'对',trigger.player,'发动了','#g【驭魔】'); - var group=trigger.player.group; - player.popup('驭魔',get.groupnature(group)); - player.addMark('kotori_yumo_'+group,1,false); - game.log(player,'获得了一个',lib.translate['kotori_yumo_'+group].replace(/魔物/g,'【魔物】')); + popup: false, + content() { + game.log(player, "对", trigger.player, "发动了", "#g【驭魔】"); + var group = trigger.player.group; + player.popup("驭魔", get.groupnature(group)); + player.addMark("kotori_yumo_" + group, 1, false); + game.log( + player, + "获得了一个", + lib.translate["kotori_yumo_" + group].replace(/魔物/g, "【魔物】") + ); }, }, - kotori_yumo_gain:{ - trigger:{player:'phaseBegin'}, - filter(event,player){ - var list=['wei','shu','wu','qun','key','jin']; - for(var i in list){ - if(player.hasMark('kotori_yumo_'+list[i])) return true; + kotori_yumo_gain: { + trigger: { player: "phaseBegin" }, + filter(event, player) { + var list = ["wei", "shu", "wu", "qun", "key", "jin"]; + for (var i in list) { + if (player.hasMark("kotori_yumo_" + list[i])) return true; } return false; }, - async cost(event, trigger, player){ - const list=['wei','shu','wu','qun','key','jin']; - const list2=[]; - for(const i of list){ - if(player.hasMark('kotori_yumo_'+i)) list2.push('kotori_skill_'+i); + async cost(event, trigger, player) { + const list = ["wei", "shu", "wu", "qun", "key", "jin"]; + const list2 = []; + for (const i of list) { + if (player.hasMark("kotori_yumo_" + i)) list2.push("kotori_skill_" + i); } - list2.push('cancel2'); - const {control} = await player.chooseControl(list2).set('prompt','###是否发动【驭魔】?###弃置对应的标记并获得下列技能中的一个,或点取消,不获得技能').set('choice',function(){ - if(list2.includes('kotori_skill_shu')&&player.countCards('h',function(card){ - return get.name(card,player)=='sha'&&player.getUseValue(card)>0; - })>1) return 'kotori_skill_shu'; - if(list2.includes('kotori_skill_key')&&player.hp>1) return 'kotori_skill_key'; - if(list2.includes('kotori_skill_qun')&&player.isDamaged()&&player.needsToDiscard()>1) return 'kotori_skill_qun'; - return 'cancel2'; - }()).set('ai',function(){ - return _status.event.choice; - }).forResult(); + list2.push("cancel2"); + const { control } = await player + .chooseControl(list2) + .set( + "prompt", + "###是否发动【驭魔】?###弃置对应的标记并获得下列技能中的一个,或点取消,不获得技能" + ) + .set( + "choice", + (function () { + if ( + list2.includes("kotori_skill_shu") && + player.countCards("h", function (card) { + return ( + get.name(card, player) == "sha" && player.getUseValue(card) > 0 + ); + }) > 1 + ) + return "kotori_skill_shu"; + if (list2.includes("kotori_skill_key") && player.hp > 1) + return "kotori_skill_key"; + if ( + list2.includes("kotori_skill_qun") && + player.isDamaged() && + player.needsToDiscard() > 1 + ) + return "kotori_skill_qun"; + return "cancel2"; + })() + ) + .set("ai", function () { + return _status.event.choice; + }) + .forResult(); event.result = { - bool: control !== 'cancel2', - cost_data: {control}, - } + bool: control !== "cancel2", + cost_data: { control }, + }; }, - content(){ + content() { const result = event.cost_data; - if(result.control!='cancel2'){ - var name='kotori_yumo_'+result.control.slice(13); - player.removeMark(name,1,false);game.log(player,'移去了一个',lib.translate[name].replace(/魔物/g,'【魔物】')); + if (result.control != "cancel2") { + var name = "kotori_yumo_" + result.control.slice(13); + player.removeMark(name, 1, false); + game.log(player, "移去了一个", lib.translate[name].replace(/魔物/g, "【魔物】")); player.addTempSkills(result.control); - game.log(player,'获得了技能',lib.translate[name].replace(/魔物/g,'【'+get.translation(result.control)+'】')); + game.log( + player, + "获得了技能", + lib.translate[name].replace( + /魔物/g, + "【" + get.translation(result.control) + "】" + ) + ); } }, }, - kotori_skill_wei:{ - trigger:{player:'phaseBegin'}, - filter(event,player){ - return player.countCards('he')>0; + kotori_skill_wei: { + trigger: { player: "phaseBegin" }, + filter(event, player) { + return player.countCards("he") > 0; }, - async cost(event, trigger, player){ - event.result = await player.chooseCardTarget({ - prompt:get.prompt2(event.skill), - filterCard:lib.filter.cardDiscardable, - filterTarget(card,player,target){ - return player!=target; - }, - position:'he', - ai1(card){ - return 6-get.value(card); - }, - ai2(target){ - return 1/(1+target.countCards('he'))*-get.attitude(_status.event.player,target); - }, - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseCardTarget({ + prompt: get.prompt2(event.skill), + filterCard: lib.filter.cardDiscardable, + filterTarget(card, player, target) { + return player != target; + }, + position: "he", + ai1(card) { + return 6 - get.value(card); + }, + ai2(target) { + return ( + (1 / (1 + target.countCards("he"))) * + -get.attitude(_status.event.player, target) + ); + }, + }) + .forResult(); }, - content(){ - 'step 0' + content() { + "step 0"; player.discard(cards); - targets[0].chooseToDiscard('弃置一张牌,或令'+get.translation(player)+'摸一张牌','he').ai=lib.skill.zhiheng.check; - 'step 1' - if(!result.bool) player.draw(); + targets[0].chooseToDiscard( + "弃置一张牌,或令" + get.translation(player) + "摸一张牌", + "he" + ).ai = lib.skill.zhiheng.check; + "step 1"; + if (!result.bool) player.draw(); }, }, - kotori_skill_shu:{ - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+1; + kotori_skill_shu: { + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + 1; }, }, - trigger:{player:'phaseUseEnd'}, - forced:true, - filter(event,player){ - return player.getHistory('useCard',function(evt){ - return evt.card&&evt.card.name=='sha'&&evt.getParent('phaseUse')==event; - }).length>1; + trigger: { player: "phaseUseEnd" }, + forced: true, + filter(event, player) { + return ( + player.getHistory("useCard", function (evt) { + return evt.card && evt.card.name == "sha" && evt.getParent("phaseUse") == event; + }).length > 1 + ); }, - content(){player.draw()}, - }, - kotori_skill_wu:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.countCards('h')!=player.hp; - }, - content(){player.draw()}, - }, - kotori_skill_qun:{ - trigger:{player:'phaseDiscardBegin'}, - forced:true, - filter(event,player){ - return (player.getDamagedHp()>1||player.countCards('h')-player.getHp()>1); - }, - content(){ - var num=0; - if(player.getDamagedHp()>1) num++; - if(player.countCards('h')-player.getHp()>1) num++; - player.addMark('kotori_qunxin_temp',num,false); - player.addTempSkill('kotori_qunxin_temp','phaseDiscardEnd'); - }, - }, - kotori_skill_key:{ - enable:'phaseUse', - usable:1, - content(){ - "step 0" + content() { player.draw(); - "step 1" + }, + }, + kotori_skill_wu: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.countCards("h") != player.hp; + }, + content() { + player.draw(); + }, + }, + kotori_skill_qun: { + trigger: { player: "phaseDiscardBegin" }, + forced: true, + filter(event, player) { + return player.getDamagedHp() > 1 || player.countCards("h") - player.getHp() > 1; + }, + content() { + var num = 0; + if (player.getDamagedHp() > 1) num++; + if (player.countCards("h") - player.getHp() > 1) num++; + player.addMark("kotori_qunxin_temp", num, false); + player.addTempSkill("kotori_qunxin_temp", "phaseDiscardEnd"); + }, + }, + kotori_skill_key: { + enable: "phaseUse", + usable: 1, + content() { + "step 0"; + player.draw(); + "step 1"; player.changeHujia(1); - "step 2" - var evt=event.getParent('phase'); - if(evt&&evt.after){ - var next=player.loseHp(); + "step 2"; + var evt = event.getParent("phase"); + if (evt && evt.after) { + var next = player.loseHp(); event.next.remove(next); evt.after.push(next); } }, - ai:{ - order:10, - result:{ - player(player){ - return player.hp-1; + ai: { + order: 10, + result: { + player(player) { + return player.hp - 1; }, }, }, }, - kotori_skill_jin:{ - trigger:{player:'phaseDrawEnd'}, - filter(event,player){ - var hs=player.getCards('h'); - return hs.length>0&&player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=event) return false; - for(var i of evt.cards){ - if(hs.includes(i)) return true; - } - return false; - }).length>0; + kotori_skill_jin: { + trigger: { player: "phaseDrawEnd" }, + filter(event, player) { + var hs = player.getCards("h"); + return ( + hs.length > 0 && + player.getHistory("gain", function (evt) { + if (evt.getParent().name != "draw" || evt.getParent("phaseDraw") != event) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) return true; + } + return false; + }).length > 0 + ); }, - check(event,player){ - var hs=player.getCards('h'),cards=[],suits=[]; - player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=event) return false; - for(var i of evt.cards){ - if(hs.includes(i)){ + check(event, player) { + var hs = player.getCards("h"), + cards = [], + suits = []; + player.getHistory("gain", function (evt) { + if (evt.getParent().name != "draw" || evt.getParent("phaseDraw") != event) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) { cards.add(i); - suits.add(get.suit(i,player)); + suits.add(get.suit(i, player)); } } }); - return cards.length==suits.length; + return cards.length == suits.length; }, - content(){ - var hs=player.getCards('h'),cards=[],suits=[]; - player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=trigger) return false; - for(var i of evt.cards){ - if(hs.includes(i)){ + content() { + var hs = player.getCards("h"), + cards = [], + suits = []; + player.getHistory("gain", function (evt) { + if (evt.getParent().name != "draw" || evt.getParent("phaseDraw") != trigger) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) { cards.add(i); - suits.add(get.suit(i,player)); + suits.add(get.suit(i, player)); } } }); - player.showCards(cards,get.translation(player)+'发动了【晋势】'); - if(cards.length==suits.length) player.draw(); + player.showCards(cards, get.translation(player) + "发动了【晋势】"); + if (cards.length == suits.length) player.draw(); }, }, - kotori_qunxin_temp:{ - onremove:true, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('kotori_qunxin_temp'); + kotori_qunxin_temp: { + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("kotori_qunxin_temp"); }, }, }, - kotori_yumo_wei:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_wei: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_yumo_shu:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_shu: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_yumo_wu:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_wu: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_yumo_qun:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_qun: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_yumo_key:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_key: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_yumo_jin:{ - marktext:'', - intro:{name:'魔物',content:'mark'}, + kotori_yumo_jin: { + marktext: '', + intro: { + name: '魔物', + content: "mark", + }, }, - kotori_huazhan:{ - charlotte:true, - enable:'chooseToUse', - filter(event,player){ - var bool=false; - var list=['wei','shu','wu','qun','key','jin']; - for(var i of list){ - if(player.hasMark('kotori_yumo_'+i)&&!player.getStorage('kotori_huazhan2').includes('kotori_yumo_'+i)){ - bool=true;break; + kotori_huazhan: { + charlotte: true, + enable: "chooseToUse", + filter(event, player) { + var bool = false; + var list = ["wei", "shu", "wu", "qun", "key", "jin"]; + for (var i of list) { + if ( + player.hasMark("kotori_yumo_" + i) && + !player.getStorage("kotori_huazhan2").includes("kotori_yumo_" + i) + ) { + bool = true; + break; } } - return bool&&event.filterCard({name:'kaihua',isCard:true},player,event); + return bool && event.filterCard({ name: "kaihua", isCard: true }, player, event); }, - chooseButton:{ - dialog(event,player){ - return ui.create.dialog('###花绽###'+lib.translate.kotori_huazhan_info); + chooseButton: { + dialog(event, player) { + return ui.create.dialog("###花绽###" + lib.translate.kotori_huazhan_info); }, - chooseControl(event,player){ - var list=['wei','shu','wu','qun','key','jin']; - var list2=[]; - for(var i of list){ - if(player.hasMark('kotori_yumo_'+i)&&!player.getStorage('kotori_huazhan2').includes('kotori_yumo_'+i)) list2.push('kotori_yumo_'+i); + chooseControl(event, player) { + var list = ["wei", "shu", "wu", "qun", "key", "jin"]; + var list2 = []; + for (var i of list) { + if ( + player.hasMark("kotori_yumo_" + i) && + !player.getStorage("kotori_huazhan2").includes("kotori_yumo_" + i) + ) + list2.push("kotori_yumo_" + i); } - list2.push('cancel2'); + list2.push("cancel2"); return list2; }, - check(){ - var player=_status.event.player; - var list=['wei','shu','wu','qun','key','jin']; - var list2=[]; - for(var i of list){ - if(player.hasMark('kotori_yumo_'+i)&&!player.getStorage('kotori_huazhan2').includes('kotori_yumo_'+i)) list2.push('kotori_yumo_'+i); + check() { + var player = _status.event.player; + var list = ["wei", "shu", "wu", "qun", "key", "jin"]; + var list2 = []; + for (var i of list) { + if ( + player.hasMark("kotori_yumo_" + i) && + !player.getStorage("kotori_huazhan2").includes("kotori_yumo_" + i) + ) + list2.push("kotori_yumo_" + i); } - if(list2.includes('kotori_yumo_wei')) return 'kotori_yumo_wei'; - if(list2.includes('kotori_yumo_wu')) return 'kotori_yumo_wu'; - if(list2.includes('kotori_yumo_qun')) return 'kotori_yumo_qun'; - if(list2.includes('kotori_yumo_key')) return 'kotori_yumo_key'; - if(list2.includes('kotori_yumo_shu')&&game.hasPlayer(function(current){ - return current.group=='shu'; - })) return 'kotori_yumo_shu'; - return 'cancel2'; + if (list2.includes("kotori_yumo_wei")) return "kotori_yumo_wei"; + if (list2.includes("kotori_yumo_wu")) return "kotori_yumo_wu"; + if (list2.includes("kotori_yumo_qun")) return "kotori_yumo_qun"; + if (list2.includes("kotori_yumo_key")) return "kotori_yumo_key"; + if ( + list2.includes("kotori_yumo_shu") && + game.hasPlayer(function (current) { + return current.group == "shu"; + }) + ) + return "kotori_yumo_shu"; + return "cancel2"; }, - backup(result,player){ + backup(result, player) { return { - markname:result.control, - viewAs:{name:'kaihua',isCard:true}, - filterCard(){return false}, - selectCard:-1, - precontent(){ - delete event.result.skill; - var name=lib.skill.kotori_huazhan_backup.markname; - if(!player.storage.kotori_huazhan2) player.storage.kotori_huazhan2=[]; - player.storage.kotori_huazhan2.push(name); - player.addTempSkill('kotori_huazhan2'); - player.popup('花绽',get.groupnature(name.slice(12))); - game.log(player,'发动了技能',lib.translate[name].replace(/魔物/g,'【花绽】')); - player.removeMark(name,1,false); - game.log(player,'移去了一个',lib.translate[name].replace(/魔物/g,'【魔物】')); + markname: result.control, + viewAs: { name: "kaihua", isCard: true }, + filterCard() { + return false; }, - } - } + selectCard: -1, + precontent() { + delete event.result.skill; + var name = lib.skill.kotori_huazhan_backup.markname; + if (!player.storage.kotori_huazhan2) player.storage.kotori_huazhan2 = []; + player.storage.kotori_huazhan2.push(name); + player.addTempSkill("kotori_huazhan2"); + player.popup("花绽", get.groupnature(name.slice(12))); + game.log( + player, + "发动了技能", + lib.translate[name].replace(/魔物/g, "【花绽】") + ); + player.removeMark(name, 1, false); + game.log( + player, + "移去了一个", + lib.translate[name].replace(/魔物/g, "【魔物】") + ); + }, + }; + }, }, - ai:{ - order:1, - result:{ - player(player){ - if(player.countCards('he',function(card){ - if(get.type(card,player)=='equip') return get.value(card)<6; - return get.value(card)<5; - })<2) return 0; - return player.getUseValue({name:'kaihua'}); + ai: { + order: 1, + result: { + player(player) { + if ( + player.countCards("he", function (card) { + if (get.type(card, player) == "equip") return get.value(card) < 6; + return get.value(card) < 5; + }) < 2 + ) + return 0; + return player.getUseValue({ name: "kaihua" }); }, }, }, }, - kotori_huazhan2:{onremove:true}, - ryoichi_baoyi:{ - trigger:{ - player:'loseAfter', - global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'], + kotori_huazhan2: { onremove: true }, + ryoichi_baoyi: { + trigger: { + player: "loseAfter", + global: [ + "gainAfter", + "equipAfter", + "addJudgeAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filterTarget(card,player,target){ - return target!=player&&(target.hasSex('female')||target.countCards('hej')>0); + filterTarget(card, player, target) { + return target != player && (target.hasSex("female") || target.countCards("hej") > 0); }, - filter(event,player){ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0&&game.hasPlayer(function(target){ - return lib.skill.ryoichi_baoyi.filterTarget; - }); + filter(event, player) { + var evt = event.getl(player); + return ( + evt && + evt.es && + evt.es.length > 0 && + game.hasPlayer(function (target) { + return lib.skill.ryoichi_baoyi.filterTarget; + }) + ); }, - forced:true, - content(){ - 'step 0' - event.count=trigger.getl(player).es.length; + forced: true, + content() { + "step 0"; + event.count = trigger.getl(player).es.length; player.draw(event.count); - 'step 1' + "step 1"; event.count--; - if(game.hasPlayer(function(target){ - return lib.skill.ryoichi_baoyi.filterTarget(null,player,target); - })){ - player.chooseTarget(true,lib.skill.ryoichi_baoyi.filterTarget,'请选择【爆衣】的目标').set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - } - else event.finish(); - 'step 2' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - if(target.hasSex('female')) target.loseHp(); - else player.discardPlayerCard(target,2,'hej',true); - } - else event.finish(); - 'step 3' - if(event.count&&game.hasPlayer(function(target){ - return lib.skill.ryoichi_baoyi.filterTarget(null,player,target); - })) event.goto(1); + if ( + game.hasPlayer(function (target) { + return lib.skill.ryoichi_baoyi.filterTarget(null, player, target); + }) + ) { + player + .chooseTarget(true, lib.skill.ryoichi_baoyi.filterTarget, "请选择【爆衣】的目标") + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + } else event.finish(); + "step 2"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + if (target.hasSex("female")) target.loseHp(); + else player.discardPlayerCard(target, 2, "hej", true); + } else event.finish(); + "step 3"; + if ( + event.count && + game.hasPlayer(function (target) { + return lib.skill.ryoichi_baoyi.filterTarget(null, player, target); + }) + ) + event.goto(1); }, }, - ryoichi_tuipi:{ - mod:{ - targetEnabled(card){ - if(card.name=='shunshou'||card.name=='guohe') return false; + ryoichi_tuipi: { + mod: { + targetEnabled(card) { + if (card.name == "shunshou" || card.name == "guohe") return false; }, }, - trigger:{player:'phaseDiscardBegin'}, - forced:true, - content(){ + trigger: { player: "phaseDiscardBegin" }, + forced: true, + content() { trigger.setContent(lib.skill.ryoichi_tuipi.phaseDiscardContent); }, - phaseDiscardContent(){ - "step 0" - event.num=Math.max(0,player.countCards('he',card=>!player.canIgnoreHandcard(card))-player.getHandcardLimit()); - if(event.num<=0) event.finish(); - else{ - if(lib.config.show_phase_prompt){ - player.popup('弃牌阶段'); + phaseDiscardContent() { + "step 0"; + event.num = Math.max( + 0, + player.countCards("he", (card) => !player.canIgnoreHandcard(card)) - + player.getHandcardLimit() + ); + if (event.num <= 0) event.finish(); + else { + if (lib.config.show_phase_prompt) { + player.popup("弃牌阶段"); } } - event.trigger('phaseDiscard'); - "step 1" - player.chooseToDiscard(num,true,'he'); - "step 2" - event.cards=result.cards; + event.trigger("phaseDiscard"); + "step 1"; + player.chooseToDiscard(num, true, "he"); + "step 2"; + event.cards = result.cards; }, }, - yuu_lveduo:{ - mod:{ - cardEnabled(card,player){ - if(player.isTurnedOver()) return false; + yuu_lveduo: { + mod: { + cardEnabled(card, player) { + if (player.isTurnedOver()) return false; }, - cardRespondable(card,player){ - if(player.isTurnedOver()) return false; + cardRespondable(card, player) { + if (player.isTurnedOver()) return false; }, - cardSavable(card,player){ - if(player.isTurnedOver()) return false; + cardSavable(card, player) { + if (player.isTurnedOver()) return false; }, }, - trigger:{global:'phaseBeginStart'}, - filter(event,player){ - return player!=event.player&&!event.player._trueMe&&!player.getStorage('yuu_lveduo').includes(event.player)&&!player.isTurnedOver()&&!player.hasSkill('yuu_lveduo4'); + trigger: { global: "phaseBeginStart" }, + filter(event, player) { + return ( + player != event.player && + !event.player._trueMe && + !player.getStorage("yuu_lveduo").includes(event.player) && + !player.isTurnedOver() && + !player.hasSkill("yuu_lveduo4") + ); }, - charlotte:true, - check(event,player){ - if(get.attitude(player,event.player)>0) return false; - if(event.player.hasJudge('lebu')||!event.player.needsToDiscard()) return false; + charlotte: true, + check(event, player) { + if (get.attitude(player, event.player) > 0) return false; + if (event.player.hasJudge("lebu") || !event.player.needsToDiscard()) return false; return true; }, - logTarget:'player', - content(){ - 'step 0' + logTarget: "player", + content() { + "step 0"; player.turnOver(); - 'step 1' - if(player.isTurnedOver()){ - player.addTempSkill('yuu_lveduo4','roundStart') - if(!player.storage.yuu_lveduo) player.storage.yuu_lveduo=[]; + "step 1"; + if (player.isTurnedOver()) { + player.addTempSkill("yuu_lveduo4", "roundStart"); + if (!player.storage.yuu_lveduo) player.storage.yuu_lveduo = []; player.storage.yuu_lveduo.push(trigger.player); - trigger.player._trueMe=player; - game.addGlobalSkill('autoswap'); - if(trigger.player==game.me){ - game.notMe=true; - if(!_status.auto) ui.click.auto(); + trigger.player._trueMe = player; + game.addGlobalSkill("autoswap"); + if (trigger.player == game.me) { + game.notMe = true; + if (!_status.auto) ui.click.auto(); } - player.addSkill('yuu_lveduo2'); - trigger.player.addSkill('yuu_lveduo3'); + player.addSkill("yuu_lveduo2"); + trigger.player.addSkill("yuu_lveduo3"); } }, }, - yuu_lveduo2:{ - trigger:{ - player:'turnOverEnd', + yuu_lveduo2: { + trigger: { + player: "turnOverEnd", }, - lastDo:true, - charlotte:true, - forceDie:true, - forced:true, - silent:true, - filter(event,player){ + lastDo: true, + charlotte: true, + forceDie: true, + forced: true, + silent: true, + filter(event, player) { return !player.isTurnedOver(); }, - content(){ - var target=game.findPlayer(function(current){ - return current._trueMe==player; + content() { + var target = game.findPlayer(function (current) { + return current._trueMe == player; }); - if(target){ - if(target==game.me){ - if(!game.notMe) game.swapPlayerAuto(target._trueMe) + if (target) { + if (target == game.me) { + if (!game.notMe) game.swapPlayerAuto(target._trueMe); else delete game.notMe; - if(_status.auto) ui.click.auto(); + if (_status.auto) ui.click.auto(); } delete target._trueMe; - target.removeSkill('yuu_lveduo3'); - var skills=target.getStockSkills(true,true).filter(function(skill){ - var info=get.info(skill); - return info&&info.charlotte==true; + target.removeSkill("yuu_lveduo3"); + var skills = target.getStockSkills(true, true).filter(function (skill) { + var info = get.info(skill); + return info && info.charlotte == true; }); - if(skills.length){ + if (skills.length) { target.removeSkills(skills); player.addSkills(skills); - lib.translate.yuu_lveduo_info=lib.translate.yuu_lveduo_full_info; + lib.translate.yuu_lveduo_info = lib.translate.yuu_lveduo_full_info; } - if(target.name=='key_yusa'){ + if (target.name == "key_yusa") { delete target.storage.dualside; - target.storage.dualside_over=true; - target.unmarkSkill('dualside'); - target.removeSkill('dualside'); - } - else if(target.name=='key_misa'){ + target.storage.dualside_over = true; + target.unmarkSkill("dualside"); + target.removeSkill("dualside"); + } else if (target.name == "key_misa") { delete target.storage.dualside; - target.storage.dualside_over=true; - target.unmarkSkill('dualside'); - target.reinit('key_misa','key_yusa'); - target.removeSkill('yusa_misa'); - target.removeSkill('dualside'); + target.storage.dualside_over = true; + target.unmarkSkill("dualside"); + target.reinit("key_misa", "key_yusa"); + target.removeSkill("yusa_misa"); + target.removeSkill("dualside"); target.turnOver(false); } } - player.removeSkill('yuu_lveduo2'); + player.removeSkill("yuu_lveduo2"); }, }, - yuu_lveduo3:{ - trigger:{ - player:['phaseAfter','dieAfter'], - global:'phaseBefore', + yuu_lveduo3: { + trigger: { + player: ["phaseAfter", "dieAfter"], + global: "phaseBefore", }, - lastDo:true, - charlotte:true, - forceDie:true, - forced:true, - silent:true, - content(){ - player.removeSkill('yuu_lveduo3'); + lastDo: true, + charlotte: true, + forceDie: true, + forced: true, + silent: true, + content() { + player.removeSkill("yuu_lveduo3"); }, - onremove(player){ - if(player._trueMe&&player._trueMe.isTurnedOver()) player._trueMe.turnOver(); + onremove(player) { + if (player._trueMe && player._trueMe.isTurnedOver()) player._trueMe.turnOver(); }, }, - yuu_lveduo4:{charlotte:true}, - godan_yuanyi:{ - trigger:{player:'phaseBegin'}, - forced:true, - content(){ - 'step 0' - var num=game.roundNumber; - if(num&&typeof num=='number') player.draw(Math.min(3,num)); - 'step 1' - trigger.phaseList.splice(trigger.num,0,'phaseUse|godan_yuanyi'); + yuu_lveduo4: { charlotte: true }, + godan_yuanyi: { + trigger: { player: "phaseBegin" }, + forced: true, + content() { + "step 0"; + var num = game.roundNumber; + if (num && typeof num == "number") player.draw(Math.min(3, num)); + "step 1"; + trigger.phaseList.splice(trigger.num, 0, "phaseUse|godan_yuanyi"); }, }, - godan_feiqu:{ - inherit:'doruji_feiqu', + godan_feiqu: { + inherit: "doruji_feiqu", }, - godan_xiaoyuan:{ - trigger:{player:'changeHp'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'soil', - filter(event,player){ - return event.num<0&&player.hp<4; + godan_xiaoyuan: { + trigger: { player: "changeHp" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "soil", + filter(event, player) { + return event.num < 0 && player.hp < 4; }, - content(){ - player.awakenSkill('godan_xiaoyuan'); + content() { + player.awakenSkill("godan_xiaoyuan"); player.loseMaxHp(3); player.draw(3); - player.removeSkills('godan_feiqu'); + player.removeSkills("godan_feiqu"); }, }, - abyusa_jueqing:{ - audio:2, - trigger:{source:'damageBegin2'}, - skillAnimation:true, - animationColor:'water', - filter(event,player){ - return player!=event.player&&!player.storage.abyusa_jueqing_rewrite; + abyusa_jueqing: { + audio: 2, + trigger: { source: "damageBegin2" }, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return player != event.player && !player.storage.abyusa_jueqing_rewrite; }, - prompt2(event,player){ - var num=get.cnNumber(2*event.num,true); - return '令即将对其造成的伤害翻倍至'+num+'点,并令自己失去'+get.cnNumber(event.num)+'点体力'; + prompt2(event, player) { + var num = get.cnNumber(2 * event.num, true); + return ( + "令即将对其造成的伤害翻倍至" + + num + + "点,并令自己失去" + + get.cnNumber(event.num) + + "点体力" + ); }, - check(event,player){ - return player.hp>event.num&&event.player.hp>event.num&&!event.player.hasSkillTag('filterDamage',null,{ - player:player, - card:event.card, - })&&get.attitude(player,event.player)<0; + check(event, player) { + return ( + player.hp > event.num && + event.player.hp > event.num && + !event.player.hasSkillTag("filterDamage", null, { + player: player, + card: event.card, + }) && + get.attitude(player, event.player) < 0 + ); }, - locked(skill,player){ - return player&&player.storage.abyusa_jueqing_rewrite; + locked(skill, player) { + return player && player.storage.abyusa_jueqing_rewrite; }, - logTarget:'player', - content(){ + logTarget: "player", + content() { player.loseHp(trigger.num); - trigger.num*=2; - player.storage.abyusa_jueqing_rewrite=true; + trigger.num *= 2; + player.storage.abyusa_jueqing_rewrite = true; }, - derivation:'abyusa_jueqing_rewrite', - group:'abyusa_jueqing_rewrite', - subSkill:{ - rewrite:{ - audio:'abyusa_jueqing', - trigger:{source:'damageBefore'}, - forced:true, - charlotte:true, - filter(event,player){ - return player.storage.abyusa_jueqing_rewrite==true; + derivation: "abyusa_jueqing_rewrite", + group: "abyusa_jueqing_rewrite", + subSkill: { + rewrite: { + audio: "abyusa_jueqing", + trigger: { source: "damageBefore" }, + forced: true, + charlotte: true, + filter(event, player) { + return player.storage.abyusa_jueqing_rewrite == true; }, - check(){return false;}, - content(){ + check() { + return false; + }, + content() { trigger.cancel(); trigger.player.loseHp(trigger.num); }, - ai:{ - jueqing:true, - skillTagFilter(player){ - return player.storage.abyusa_jueqing_rewrite==true; + ai: { + jueqing: true, + skillTagFilter(player) { + return player.storage.abyusa_jueqing_rewrite == true; }, - } - } + }, + }, }, }, - akiko_dongcha:{ - trigger:{global:'phaseBefore'}, - forced:true, - filter(event,player){ - return get.mode()=='identity'&&game.phaseNumber==0; + akiko_dongcha: { + trigger: { global: "phaseBefore" }, + forced: true, + filter(event, player) { + return get.mode() == "identity" && game.phaseNumber == 0; }, - content(){ - var func=function(){ - game.countPlayer(function(current){ + content() { + var func = function () { + game.countPlayer(function (current) { current.setIdentity(); }); }; - if(player==game.me) func(); - else if(player.isOnline()) player.send(func); - if(!player.storage.zhibi) player.storage.zhibi=[]; + if (player == game.me) func(); + else if (player.isOnline()) player.send(func); + if (!player.storage.zhibi) player.storage.zhibi = []; player.storage.zhibi.addArray(game.players); }, - ai:{ - viewHandcard:true, - skillTagFilter(player,tag,arg){ - if(player==arg) return false; + ai: { + viewHandcard: true, + skillTagFilter(player, tag, arg) { + if (player == arg) return false; }, }, }, - abyusa_dunying:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - forced:true, - filter(event,player){ + abyusa_dunying: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + forced: true, + filter(event, player) { return player.isDamaged(); }, - content(){ + content() { player.draw(player.getDamagedHp()); }, - mod:{ - globalTo(from,to,num){ - return num+to.getDamagedHp(); + mod: { + globalTo(from, to, num) { + return num + to.getDamagedHp(); }, }, }, - kaori_siyuan:{ - enable:'phaseUse', - filter(event,player){ - return player.countCards('he',lib.skill.kaori_siyuan.filterCard); + kaori_siyuan: { + enable: "phaseUse", + filter(event, player) { + return player.countCards("he", lib.skill.kaori_siyuan.filterCard); }, - filterCard(card){ - return ['equip','delay'].includes(get.type(card,false)); + filterCard(card) { + return ["equip", "delay"].includes(get.type(card, false)); }, - filterTarget(card,player,target){ - if(player==target) return false; - var card=ui.selected.cards[0]; - if(get.type(card,false)=='delay') return target.canAddJudge({name:card.name}); + filterTarget(card, player, target) { + if (player == target) return false; + var card = ui.selected.cards[0]; + if (get.type(card, false) == "delay") return target.canAddJudge({ name: card.name }); return target.canEquip(card); }, - discard:false, - lose:false, - prepare:'give', - content(){ - 'step 0' - var card=cards[0]; - if(get.type(card,false)=='equip') target.equip(card); + discard: false, + lose: false, + prepare: "give", + content() { + "step 0"; + var card = cards[0]; + if (get.type(card, false) == "equip") target.equip(card); else target.addJudge(card); - 'step 1' - var list=[]; - for(var i of lib.inpile){ - var type=get.type(i); - if(type=='basic'||type=='trick') list.push([type,'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature) list.push([type,'',i,j]); + "step 1"; + var list = []; + for (var i of lib.inpile) { + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) list.push([type, "", i, j]); } } - player.chooseButton(['是否视为使用一张基本牌或普通锦囊牌?',[list,'vcard']]).set('filterButton',function(button){ - return player.hasUseTarget({name:button.link[2],nature:button.link[3],isCard:true}); - }).set('ai',function(button){ - return player.getUseValue({name:button.link[2],nature:button.link[3],isCard:true}); - }); - 'step 2' - if(result.bool){ - player.chooseUseTarget(true,{name:result.links[0][2],nature:result.links[0][3],isCard:true}); + player + .chooseButton(["是否视为使用一张基本牌或普通锦囊牌?", [list, "vcard"]]) + .set("filterButton", function (button) { + return player.hasUseTarget({ + name: button.link[2], + nature: button.link[3], + isCard: true, + }); + }) + .set("ai", function (button) { + return player.getUseValue({ + name: button.link[2], + nature: button.link[3], + isCard: true, + }); + }); + "step 2"; + if (result.bool) { + player.chooseUseTarget(true, { + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }); } }, - ai:{ - basic:{ - order:10 + ai: { + basic: { + order: 10, }, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(card) return get.effect(target,card,target,target); + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (card) return get.effect(target, card, target, target); return 0; }, }, - } - }, - shiori_huijuan:{ - trigger:{global:'phaseJieshuBegin'}, - locked:true, - filter(event,player){ - return event.player!=player&&event.player.getHistory('useCard',function(evt){ - return evt.isPhaseUsing()&&['basic','trick'].includes(get.type(evt.card))&&player.hasUseTarget({ - name:evt.card.name, - nature:evt.card.nature, - isCard:true, - }); - }).length>0; }, - async cost(event, trigger, player){ - const list=[]; - trigger.player.getHistory('useCard',function(evt){ - if(!evt.isPhaseUsing()||!['basic','trick'].includes(get.type(evt.card))) return; - if(evt.card.name=='sha'&&evt.card.nature) list.add('sha:'+evt.card.nature); + }, + shiori_huijuan: { + trigger: { global: "phaseJieshuBegin" }, + locked: true, + filter(event, player) { + return ( + event.player != player && + event.player.getHistory("useCard", function (evt) { + return ( + evt.isPhaseUsing() && + ["basic", "trick"].includes(get.type(evt.card)) && + player.hasUseTarget({ + name: evt.card.name, + nature: evt.card.nature, + isCard: true, + }) + ); + }).length > 0 + ); + }, + async cost(event, trigger, player) { + const list = []; + trigger.player.getHistory("useCard", function (evt) { + if (!evt.isPhaseUsing() || !["basic", "trick"].includes(get.type(evt.card))) return; + if (evt.card.name == "sha" && evt.card.nature) list.add("sha:" + evt.card.nature); else list.add(evt.card.name); }); - for(var i=0;i=0){ - if(stat[i].isMe) break; - if(stat[i].skill&&stat[i].skill.shiori_huijuan) num++; + shiori_huijuan_discard: { + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + var num = 0; + var stat = player.stat; + for (var i = stat.length - 2; i--; i >= 0) { + if (stat[i].isMe) break; + if (stat[i].skill && stat[i].skill.shiori_huijuan) num++; } - return num>=Math.max(2,game.countPlayer()/2); + return num >= Math.max(2, game.countPlayer() / 2); }, - forced:true, - content(){ - 'step 0' - if(!player.countDiscardableCards(player,'ej')) event._result={bool:false}; - else player.discardPlayerCard(player,'ej').set('ai',function(button){ - var card=button.link; - var player=_status.event.player; - if(get.position(card)=='j') return 7+Math.random(); - return 4+player.needsToDiscard()-get.value(card); - }); - 'step 1' - if(!result.bool) player.skip('phaseUse'); + forced: true, + content() { + "step 0"; + if (!player.countDiscardableCards(player, "ej")) event._result = { bool: false }; + else + player.discardPlayerCard(player, "ej").set("ai", function (button) { + var card = button.link; + var player = _status.event.player; + if (get.position(card) == "j") return 7 + Math.random(); + return 4 + player.needsToDiscard() - get.value(card); + }); + "step 1"; + if (!result.bool) player.skip("phaseUse"); }, }, - miki_shenqiang:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + miki_shenqiang: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - player.equip(game.createCard2('miki_hydrogladiator','club',6)); - player.equip(game.createCard2('miki_binoculars','diamond',6)); + content() { + player.equip(game.createCard2("miki_hydrogladiator", "club", 6)); + player.equip(game.createCard2("miki_binoculars", "diamond", 6)); }, - mod:{ - canBeDiscarded(card){ - if(get.position(card)=='e'&&['equip1','equip5'].includes(get.subtype(card))) return false; + mod: { + canBeDiscarded(card) { + if (get.position(card) == "e" && ["equip1", "equip5"].includes(get.subtype(card))) + return false; }, }, }, - miki_huanmeng:{ - inherit:'kamome_huanmeng', + miki_huanmeng: { + inherit: "kamome_huanmeng", }, - miki_zhiluo:{ - trigger:{global:'phaseEnd'}, - filter(event,player){ - return !event.player.countCards('e')&&player.inRange(event.player); + miki_zhiluo: { + trigger: { global: "phaseEnd" }, + filter(event, player) { + return !event.player.countCards("e") && player.inRange(event.player); }, - locked:true, - async cost(event, trigger, player){ - event.result = {bool: true, cost_data: {index:0}}; - if (player.canUse('sha', trigger.player, false)){ - const {index} = await player.chooseControl().set('prompt','制裸:请选择一项').set('choiceList',[ - '摸一张牌', - '视为对'+get.translation(trigger.player)+'使用一张【杀】', - ]).set('ai',function(){ - if(get.effect(_status.event.getTrigger().player,{name:'sha'},_status.event.player)>0) return 1; - return 0; - }).forResult(); + locked: true, + async cost(event, trigger, player) { + event.result = { bool: true, cost_data: { index: 0 } }; + if (player.canUse("sha", trigger.player, false)) { + const { index } = await player + .chooseControl() + .set("prompt", "制裸:请选择一项") + .set("choiceList", [ + "摸一张牌", + "视为对" + get.translation(trigger.player) + "使用一张【杀】", + ]) + .set("ai", function () { + if ( + get.effect( + _status.event.getTrigger().player, + { name: "sha" }, + _status.event.player + ) > 0 + ) + return 1; + return 0; + }) + .forResult(); event.result.cost_data.index = index; } }, - async content(event, trigger, player){ + async content(event, trigger, player) { const result = event.cost_data; - if(result.index==0){ - player.logSkill('miki_zhiluo'); + if (result.index == 0) { + player.logSkill("miki_zhiluo"); player.draw(); - } - else player.useCard({name:'sha',isCard:true},trigger.player,'miki_zhiluo'); + } else player.useCard({ name: "sha", isCard: true }, trigger.player, "miki_zhiluo"); }, }, - miki_hydrogladiator_skill:{ - trigger:{ - source:'damageSource', + miki_hydrogladiator_skill: { + trigger: { + source: "damageSource", }, - locked:true, - popup:'海德洛', - filter(event,player){ - return event.getParent().name=='sha'&&game.hasPlayer(function(current){ - return (current==event.player||current!=player&&get.distance(current,event.player)<=1)&¤t.countDiscardableCards(player,'he')>0; - }); + locked: true, + popup: "海德洛", + filter(event, player) { + return ( + event.getParent().name == "sha" && + game.hasPlayer(function (current) { + return ( + (current == event.player || + (current != player && get.distance(current, event.player) <= 1)) && + current.countDiscardableCards(player, "he") > 0 + ); + }) + ); }, - cost(){ - 'step 0' - var list=[]; - var choiceList=[]; - if(trigger.player.countDiscardableCards(player,'he')>0){ + cost() { + "step 0"; + var list = []; + var choiceList = []; + if (trigger.player.countDiscardableCards(player, "he") > 0) { list.push(true); - choiceList.push('弃置'+get.translation(trigger.player)+'的两张牌'); + choiceList.push("弃置" + get.translation(trigger.player) + "的两张牌"); } - if(game.hasPlayer(function(current){ - return current!=player&&get.distance(current,trigger.player)<=1; - })){ + if ( + game.hasPlayer(function (current) { + return current != player && get.distance(current, trigger.player) <= 1; + }) + ) { list.push(false); - choiceList.push('弃置所有至'+get.translation(trigger.player)+'距离为1的角色的各一张牌'); + choiceList.push( + "弃置所有至" + get.translation(trigger.player) + "距离为1的角色的各一张牌" + ); } - event.list=list; - if(list.length==1) event._result={index:0}; - else{ - player.chooseControl().set('choiceList',choiceList).set('prompt','海德洛格拉迪尔特·改').set('ai',function(){ - var player=_status.event.player; - var source=_status.event.getTrigger().player; - var num=game.countPlayer(function(current){ - if(current!=player&&get.distance(current,source)<=1&¤t.countDiscardableCards(player,'he')>0) return -get.sgn(get.attitude(player,current)); + event.list = list; + if (list.length == 1) event._result = { index: 0 }; + else { + player + .chooseControl() + .set("choiceList", choiceList) + .set("prompt", "海德洛格拉迪尔特·改") + .set("ai", function () { + var player = _status.event.player; + var source = _status.event.getTrigger().player; + var num = game.countPlayer(function (current) { + if ( + current != player && + get.distance(current, source) <= 1 && + current.countDiscardableCards(player, "he") > 0 + ) + return -get.sgn(get.attitude(player, current)); + }); + if (num > Math.min(2, source.countDiscardableCards(player, "he"))) return 1; + return 0; }); - if(num>Math.min(2,source.countDiscardableCards(player,'he'))) return 1; - return 0; - }); } - 'step 1' - if(event.list[result.index]){ + "step 1"; + if (event.list[result.index]) { event.result = { bool: true, - cost_data:{type: 'single'}, + cost_data: { type: "single" }, targets: [trigger.player], - } - } - else{ + }; + } else { event.result = { bool: true, - cost_data:{type: 'multiple'}, - targets: game.filterPlayer(function(current){ - return current!=player&&get.distance(current,trigger.player)<=1; - }).sortBySeat(), - } + cost_data: { type: "multiple" }, + targets: game + .filterPlayer(function (current) { + return current != player && get.distance(current, trigger.player) <= 1; + }) + .sortBySeat(), + }; } }, - content(){ - 'step 0' - if(event.cost_data.type == 'single'){ - player.discardPlayerCard(targets[0],'he',2,true); + content() { + "step 0"; + if (event.cost_data.type == "single") { + player.discardPlayerCard(targets[0], "he", 2, true); event.finish(); } - 'step 1' - var target=targets.shift(); - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true); - if(targets.length) event.redo(); + "step 1"; + var target = targets.shift(); + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true); + if (targets.length) event.redo(); }, }, - miki_binoculars:{ - locked:true, - ai:{ - viewHandcard:true, - skillTagFilter(player,tag,arg){ - if(player==arg) return false; + miki_binoculars: { + locked: true, + ai: { + viewHandcard: true, + skillTagFilter(player, tag, arg) { + if (player == arg) return false; }, }, }, - kud_qiaoshou:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return !player.getExpansions('kud_qiaoshou_equip').length&&player.countCards('h')>0; + kud_qiaoshou: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return !player.getExpansions("kud_qiaoshou_equip").length && player.countCards("h") > 0; }, - chooseButton:{ - dialog(){ - var list=[]; - var list2=['pyzhuren_heart','pyzhuren_diamond','pyzhuren_club','pyzhuren_spade','pyzhuren_shandian','rewrite_zhuge']; + chooseButton: { + dialog() { + var list = []; + var list2 = [ + "pyzhuren_heart", + "pyzhuren_diamond", + "pyzhuren_club", + "pyzhuren_spade", + "pyzhuren_shandian", + "rewrite_zhuge", + ]; list2.addArray(lib.inpile); - for(var i of list2){ - var sub=get.subtype(i); - if(['equip1','equip4'].includes(sub)) list.push([sub,'',i]); + for (var i of list2) { + var sub = get.subtype(i); + if (["equip1", "equip4"].includes(sub)) list.push([sub, "", i]); } - return ui.create.dialog('巧手:选择一种装备牌',[list,'vcard'],'hidden'); + return ui.create.dialog("巧手:选择一种装备牌", [list, "vcard"], "hidden"); }, - check(button){ - var player=_status.event.player; - var name=button.link[2]; - if(get.subtype(name)=='equip4'||player.getEquip(name)) return 0; - var sha=player.countCards('h','sha'); - switch(name){ - case 'rewrite_zhuge': - return sha-player.getCardUsable('sha'); - case 'guding': - if(sha>0&&game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&!current.countCards('h')&&player.canUse('sha',current)&&get.effect(current,{name:'sha'},player)>0; - })) return 1.4+Math.random(); + check(button) { + var player = _status.event.player; + var name = button.link[2]; + if (get.subtype(name) == "equip4" || player.getEquip(name)) return 0; + var sha = player.countCards("h", "sha"); + switch (name) { + case "rewrite_zhuge": + return sha - player.getCardUsable("sha"); + case "guding": + if ( + sha > 0 && + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + !current.countCards("h") && + player.canUse("sha", current) && + get.effect(current, { name: "sha" }, player) > 0 + ); + }) + ) + return 1.4 + Math.random(); return 0; - case 'guanshi': - if(sha>0) return 0.7+Math.random(); + case "guanshi": + if (sha > 0) return 0.7 + Math.random(); return 0; - case 'qinggang': - if(sha>0) return 0.4+Math.random(); + case "qinggang": + if (sha > 0) return 0.4 + Math.random(); return 0; - case 'zhuque': - if(game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.getEquip('tengjia')&&get.effect(current,{name:'sha',nature:'fire'},player)>0; - })) return 1.2+Math.random(); + case "zhuque": + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.getEquip("tengjia") && + get.effect(current, { name: "sha", nature: "fire" }, player) > 0 + ); + }) + ) + return 1.2 + Math.random(); + return 0; + default: return 0; - default: return 0; } }, - backup(links){ - var next=get.copy(lib.skill.kud_qiaoshou_backupx); - next.cardname=links[0][2]; + backup(links) { + var next = get.copy(lib.skill.kud_qiaoshou_backupx); + next.cardname = links[0][2]; return next; }, - prompt(links){ - return '将一张手牌置于武将牌上,然后视为装备'+get.translation(links[0][2]); + prompt(links) { + return "将一张手牌置于武将牌上,然后视为装备" + get.translation(links[0][2]); }, }, - group:'kud_qiaoshou_end', - ai:{ - notemp:true, - order:5, - result:{ - player:1, + group: "kud_qiaoshou_end", + ai: { + notemp: true, + order: 5, + result: { + player: 1, }, }, }, - kud_qiaoshou_backupx:{ - filterCard:true, - discard:false, - lose:false, - delay:false, - check(event,player){ - return 6-get.value(card); + kud_qiaoshou_backupx: { + filterCard: true, + discard: false, + lose: false, + delay: false, + check(event, player) { + return 6 - get.value(card); }, - content(){ - 'step 0' - player.addToExpansion(cards,player,'give').gaintag.add('kud_qiaoshou_equip'); - 'step 1' - if(!player.getExpansions('kud_qiaoshou_equip').length) return; - player.addTempSkill('kud_qiaoshou_equip',{player:['phaseUseEnd','phaseZhunbeiBegin']}); - var name=lib.skill.kud_qiaoshou_backup.cardname; - player.storage.kud_qiaoshou_equip2=name; - var info=lib.card[name].skills; - if(info&&info.length) player.addAdditionalSkill('kud_qiaoshou_equip',info); + content() { + "step 0"; + player.addToExpansion(cards, player, "give").gaintag.add("kud_qiaoshou_equip"); + "step 1"; + if (!player.getExpansions("kud_qiaoshou_equip").length) return; + player.addTempSkill("kud_qiaoshou_equip", { + player: ["phaseUseEnd", "phaseZhunbeiBegin"], + }); + var name = lib.skill.kud_qiaoshou_backup.cardname; + player.storage.kud_qiaoshou_equip2 = name; + var info = lib.card[name].skills; + if (info && info.length) player.addAdditionalSkill("kud_qiaoshou_equip", info); player.draw(); - game.log(player,'声明了','#y'+get.translation(name)); + game.log(player, "声明了", "#y" + get.translation(name)); }, - ai:{ - result:{ - player:1, + ai: { + result: { + player: 1, }, }, }, - kud_qiaoshou_equip:{ - charlotte:true, - mod:{ - globalFrom(from,to,distance){ - var info=lib.card[from.storage.kud_qiaoshou_equip2]; - if(info&&info.distance&&info.distance.globalFrom) return distance+info.distance.globalFrom; + kud_qiaoshou_equip: { + charlotte: true, + mod: { + globalFrom(from, to, distance) { + var info = lib.card[from.storage.kud_qiaoshou_equip2]; + if (info && info.distance && info.distance.globalFrom) + return distance + info.distance.globalFrom; }, - globalTo(from,to,distance){ - var info=lib.card[to.storage.kud_qiaoshou_equip2]; - if(info&&info.distance&&info.distance.globalTo) return distance+info.distance.globalTo; + globalTo(from, to, distance) { + var info = lib.card[to.storage.kud_qiaoshou_equip2]; + if (info && info.distance && info.distance.globalTo) + return distance + info.distance.globalTo; }, - attackRange(from,distance){ - var info=lib.card[from.storage.kud_qiaoshou_equip2]; - if(info&&info.distance&&info.distance.attackFrom) return distance-info.distance.attackFrom; + attackRange(from, distance) { + var info = lib.card[from.storage.kud_qiaoshou_equip2]; + if (info && info.distance && info.distance.attackFrom) + return distance - info.distance.attackFrom; }, - attackTo(from,to,distance){ - var info=lib.card[to.storage.kud_qiaoshou_equip2]; - if(info&&info.distance&&info.distance.attackTo) return distance+info.distance.attackTo; + attackTo(from, to, distance) { + var info = lib.card[to.storage.kud_qiaoshou_equip2]; + if (info && info.distance && info.distance.attackTo) + return distance + info.distance.attackTo; }, }, - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - markcount:'expansion', - mark(dialog,storage,player){ - dialog.add(player.getExpansions('kud_qiaoshou_equip')); - dialog.addText('当前装备:'+get.translation(player.storage.kud_qiaoshou_equip2)); - var str2=lib.translate[player.storage.kud_qiaoshou_equip2+'_info']; - if(str2){ - if(str2.length>=12) dialog.addText(str2,false); + intro: { + markcount: "expansion", + mark(dialog, storage, player) { + dialog.add(player.getExpansions("kud_qiaoshou_equip")); + dialog.addText("当前装备:" + get.translation(player.storage.kud_qiaoshou_equip2)); + var str2 = lib.translate[player.storage.kud_qiaoshou_equip2 + "_info"]; + if (str2) { + if (str2.length >= 12) dialog.addText(str2, false); else dialog.addText(str2); } }, - onunmark(storage,player){ - player.removeAdditionalSkill('kud_qiaoshou_equip'); + onunmark(storage, player) { + player.removeAdditionalSkill("kud_qiaoshou_equip"); delete player.storage.kud_qiaoshou_equip2; player.addEquipTrigger(); }, }, }, - kud_qiaoshou_end:{ - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.countCards('h')>0&&!player.getExpansions('kud_qiaoshou_equip').length; + kud_qiaoshou_end: { + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return player.countCards("h") > 0 && !player.getExpansions("kud_qiaoshou_equip").length; }, - cost(){ - 'step 0' - var list=[]; - var list2=['rewrite_bagua','rewrite_renwang','rewrite_tengjia','rewrite_baiyin']; + cost() { + "step 0"; + var list = []; + var list2 = ["rewrite_bagua", "rewrite_renwang", "rewrite_tengjia", "rewrite_baiyin"]; list2.addArray(lib.inpile); - for(var i of list2){ - var sub=get.subtype(i); - if(['equip2','equip3'].includes(sub)) list.push([sub,'',i]); + for (var i of list2) { + var sub = get.subtype(i); + if (["equip2", "equip3"].includes(sub)) list.push([sub, "", i]); } - player.chooseButton([get.prompt('kud_qiaoshou'),[list,'vcard']]).set('ai',function(button){ - var player=_status.event.player; - var name=button.link[2]; - if(get.subtype(name)=='equip3'||player.getEquip(name)) return false; - switch(name){ - case 'yexingyi': - if(player.hp>2||player.getEquip('bagua')||player.getEquip('tengjia')) return 1.5+Math.random(); - return 0.5+Math.random(); - case 'rewrite_bagua':case 'rewrite_renwang': - if(player.getEquip('bagua')||player.getEquip('tengjia')||player.getEquip('renwang')) return Math.random(); - return 1.2+Math.random(); - case 'rewrite_tengjia': - if(player.getEquip('baiyin')) return 1.3+Math.random(); - return Math.random(); - case 'rewrite_baiyin': - return 0.4+Math.random(); - default: return 0; - } - }); - 'step 1' - if(result.bool){ - event.cardname=result.links[0][2]; - player.chooseCard('h',true,'将一张手牌置于武将牌上,然后视为装备'+get.translation(event.cardname)); - } - else event.finish(); - 'step 2' - if(result.bool){ + player + .chooseButton([get.prompt("kud_qiaoshou"), [list, "vcard"]]) + .set("ai", function (button) { + var player = _status.event.player; + var name = button.link[2]; + if (get.subtype(name) == "equip3" || player.getEquip(name)) return false; + switch (name) { + case "yexingyi": + if ( + player.hp > 2 || + player.getEquip("bagua") || + player.getEquip("tengjia") + ) + return 1.5 + Math.random(); + return 0.5 + Math.random(); + case "rewrite_bagua": + case "rewrite_renwang": + if ( + player.getEquip("bagua") || + player.getEquip("tengjia") || + player.getEquip("renwang") + ) + return Math.random(); + return 1.2 + Math.random(); + case "rewrite_tengjia": + if (player.getEquip("baiyin")) return 1.3 + Math.random(); + return Math.random(); + case "rewrite_baiyin": + return 0.4 + Math.random(); + default: + return 0; + } + }); + "step 1"; + if (result.bool) { + event.cardname = result.links[0][2]; + player.chooseCard( + "h", + true, + "将一张手牌置于武将牌上,然后视为装备" + get.translation(event.cardname) + ); + } else event.finish(); + "step 2"; + if (result.bool) { event.result = { - bool:true, + bool: true, cards: result.cards, - cost_data:{ + cost_data: { cardname: event.cardname, }, - } + }; } }, - async content(event, trigger, player){ - await player.addToExpansion(event.cards,player,'give').gaintag.add('kud_qiaoshou_equip'); - if(!player.getExpansions('kud_qiaoshou_equip').length) return; - player.addTempSkill('kud_qiaoshou_equip',{player:['phaseUseEnd','phaseZhunbeiBegin']}); - var name=event.cost_data.cardname; - player.storage.kud_qiaoshou_equip2=name; - player.markAuto('kud_qiaoshou_equip',cards); - var info=lib.card[name].skills; - if(info&&info.length) player.addAdditionalSkill('kud_qiaoshou_equip',info); - game.log(player,'声明了','#y'+get.translation(name)); + async content(event, trigger, player) { + await player + .addToExpansion(event.cards, player, "give") + .gaintag.add("kud_qiaoshou_equip"); + if (!player.getExpansions("kud_qiaoshou_equip").length) return; + player.addTempSkill("kud_qiaoshou_equip", { + player: ["phaseUseEnd", "phaseZhunbeiBegin"], + }); + var name = event.cost_data.cardname; + player.storage.kud_qiaoshou_equip2 = name; + player.markAuto("kud_qiaoshou_equip", cards); + var info = lib.card[name].skills; + if (info && info.length) player.addAdditionalSkill("kud_qiaoshou_equip", info); + game.log(player, "声明了", "#y" + get.translation(name)); await player.draw(); }, }, - kud_buhui:{ - enable:'chooseToUse', - filter(event,player){ - return event.type=='dying'&&player==event.dying&&(player.getExpansions('kud_qiaoshou_equip').length+player.countCards('e'))>0; + kud_buhui: { + enable: "chooseToUse", + filter(event, player) { + return ( + event.type == "dying" && + player == event.dying && + player.getExpansions("kud_qiaoshou_equip").length + player.countCards("e") > 0 + ); }, - skillAnimation:true, - limited:true, - animationColor:'gray', - content(){ - 'step 0' - player.awakenSkill('kud_buhui'); - var cards=player.getCards('e').concat(player.getExpansions('kud_qiaoshou_equip')); - if(cards.length) player.discard(cards); - player.removeSkill('kud_qiaoshou_equip'); + skillAnimation: true, + limited: true, + animationColor: "gray", + content() { + "step 0"; + player.awakenSkill("kud_buhui"); + var cards = player.getCards("e").concat(player.getExpansions("kud_qiaoshou_equip")); + if (cards.length) player.discard(cards); + player.removeSkill("kud_qiaoshou_equip"); player.draw(cards.length); - player.addSkills('kud_chongzhen'); - 'step 1' - var num=2-player.hp; - if(num) player.recover(num); + player.addSkills("kud_chongzhen"); + "step 1"; + var num = 2 - player.hp; + if (num) player.recover(num); }, - derivation:'riki_chongzhen', - ai:{ - order:0.5, - result:{ - player:1, + derivation: "riki_chongzhen", + ai: { + order: 0.5, + result: { + player: 1, }, - save:true, - skillTagFilter(player,tag,target){ - return player==target; + save: true, + skillTagFilter(player, tag, target) { + return player == target; }, }, }, - kud_chongzhen:{ - inherit:'riki_chongzhen', + kud_chongzhen: { + inherit: "riki_chongzhen", }, - misuzu_hengzhou:{ - trigger:{player:['phaseJieshuBegin','recoverEnd','damageEnd','phaseDrawBegin2','phaseZhunbeiBegin']}, - forced:true, - character:true, - filter(event,player){ - if(event.name=='phaseZhunbei') return true; - if(['damage','recover'].includes(event.name)) return event.num>0; - var num=player.countMark('misuzu_hengzhou'); - if(event.name=='phaseDraw') return num>0&&!event.numFixed; - return num>3; + misuzu_hengzhou: { + trigger: { + player: [ + "phaseJieshuBegin", + "recoverEnd", + "damageEnd", + "phaseDrawBegin2", + "phaseZhunbeiBegin", + ], }, - content(){ - var num=player.countMark('misuzu_hengzhou'); - if(trigger.name=='phaseDraw') trigger.num+=num; - else if(trigger.name=='phaseJieshu'){ - player.removeMark('misuzu_hengzhou',num); + forced: true, + character: true, + filter(event, player) { + if (event.name == "phaseZhunbei") return true; + if (["damage", "recover"].includes(event.name)) return event.num > 0; + var num = player.countMark("misuzu_hengzhou"); + if (event.name == "phaseDraw") return num > 0 && !event.numFixed; + return num > 3; + }, + content() { + var num = player.countMark("misuzu_hengzhou"); + if (trigger.name == "phaseDraw") trigger.num += num; + else if (trigger.name == "phaseJieshu") { + player.removeMark("misuzu_hengzhou", num); player.loseHp(); - } - else player.addMark('misuzu_hengzhou',trigger.num||1); + } else player.addMark("misuzu_hengzhou", trigger.num || 1); }, - intro:{ - name:'诅咒', - name2:'诅咒', - content:'mark', + intro: { + name: "诅咒", + name2: "诅咒", + content: "mark", }, - marktext:'诅', - mod:{ - maxHandcard(player,num){ - return num+player.countMark('misuzu_hengzhou'); + marktext: "诅", + mod: { + maxHandcard(player, num) { + return num + player.countMark("misuzu_hengzhou"); }, }, - ai:{ - notemp:true, + ai: { + notemp: true, }, }, - misuzu_nongyin:{ - enable:'chooseToUse', - viewAs:{ - name:'tao', - isCard:true, + misuzu_nongyin: { + enable: "chooseToUse", + viewAs: { + name: "tao", + isCard: true, }, - viewAsFilter(player){ - return !player.hasJudge('lebu')&&player.countCards('hes',function(card){ - return get.color(card)=='red'&&get.type(card,'trick')!='trick'; - }); + viewAsFilter(player) { + return ( + !player.hasJudge("lebu") && + player.countCards("hes", function (card) { + return get.color(card) == "red" && get.type(card, "trick") != "trick"; + }) + ); }, - filterCard(card){ - return get.color(card)=='red'&&get.type(card,'trick')!='trick'; + filterCard(card) { + return get.color(card) == "red" && get.type(card, "trick") != "trick"; }, - check(card){ - return 7+(_status.event.dying||_status.event.player).getDamagedHp()-get.value(card); + check(card) { + return 7 + (_status.event.dying || _status.event.player).getDamagedHp() - get.value(card); }, - ignoreMod:true, - position:'hes', - precontent(){ - player.logSkill('misuzu_nongyin'); + ignoreMod: true, + position: "hes", + precontent() { + player.logSkill("misuzu_nongyin"); player.$throw(event.result.cards); - player.addJudge({name:'lebu'},event.result.cards); - event.result.card.cards=[]; - event.result.cards=[]; + player.addJudge({ name: "lebu" }, event.result.cards); + event.result.card.cards = []; + event.result.cards = []; delete event.result.skill; delete event.result.card.suit; delete event.result.card.number; }, - ai:{ - result:0.5, + ai: { + result: 0.5, }, }, - misuzu_zhongxing:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + misuzu_zhongxing: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - var evt=event.getl(player); - return evt&&evt.js&&evt.js.length>0&&!player.hasSkill('misuzu_zhongxing_haruko'); + filter(event, player) { + var evt = event.getl(player); + return evt && evt.js && evt.js.length > 0 && !player.hasSkill("misuzu_zhongxing_haruko"); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt('misuzu_zhongxing'),'令一名角色选择摸两张牌或回复1点体力').set('ai',function(card){ - return get.attitude(_status.event.player,card); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt("misuzu_zhongxing"), "令一名角色选择摸两张牌或回复1点体力") + .set("ai", function (card) { + return get.attitude(_status.event.player, card); + }) + .forResult(); }, - async content(event, trigger, player){ - var target=event.targets[0]; - player.logSkill('misuzu_zhongxing',target); - player.addTempSkill('misuzu_zhongxing_haruko'); - target.chooseDrawRecover(2,true); + async content(event, trigger, player) { + var target = event.targets[0]; + player.logSkill("misuzu_zhongxing", target); + player.addTempSkill("misuzu_zhongxing_haruko"); + target.chooseDrawRecover(2, true); }, }, - misuzu_zhongxing_haruko:{charlotte:true}, - kamome_suitcase:{ - trigger:{player:['phaseJudgeBefore','phaseDiscardBefore','turnOverBefore']}, - forced:true, - popup:false, - equipSkill:true, - content(){ + misuzu_zhongxing_haruko: { charlotte: true }, + kamome_suitcase: { + trigger: { + player: ["phaseJudgeBefore", "phaseDiscardBefore", "turnOverBefore"], + }, + forced: true, + popup: false, + equipSkill: true, + content() { trigger.cancel(); }, }, - kamome_yangfan:{ - trigger:{ - player:['loseAfter','enterGame'], - global:['equipAfter','addJudgeAfter','phaseBefore','gainAfter','loseAsyncAfter','addToExpansionAfter'], + kamome_yangfan: { + trigger: { + player: ["loseAfter", "enterGame"], + global: [ + "equipAfter", + "addJudgeAfter", + "phaseBefore", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter(event,player){ - if(typeof event.getl!='function') return (event.name!='phase'||game.phaseNumber==0); - var evt=event.getl(player); - return evt&&evt.player==player&&evt.es&&evt.es.length; + forced: true, + filter(event, player) { + if (typeof event.getl != "function") + return event.name != "phase" || game.phaseNumber == 0; + var evt = event.getl(player); + return evt && evt.player == player && evt.es && evt.es.length; }, - content(){ - if(trigger.getl) player.draw(2*trigger.getl(player).es.length); - else player.equip(game.createCard2('kamome_suitcase','spade',1)); + content() { + if (trigger.getl) player.draw(2 * trigger.getl(player).es.length); + else player.equip(game.createCard2("kamome_suitcase", "spade", 1)); + }, + ai: { + noe: true, + reverseEquip: true, + effect: { + target(card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; + }, + }, }, - ai:{ - noe:true, - reverseEquip:true, - effect:{ - target(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } - } - } }, - kamome_huanmeng:{ - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - content(){ - "step 0" - var num=1+player.countCards('e'); - var cards=get.cards(num); + kamome_huanmeng: { + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + content() { + "step 0"; + var num = 1 + player.countCards("e"); + var cards = get.cards(num); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','幻梦:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var top=[]; - var judges=player.getCards('j'); - var stopped=false; - if(!player.hasWuxie()){ - for(var i=0;i=num&&!player.hasSkill('kamome_jieban_phase'); + filter(event, player) { + var num = player.storage.kamome_jieban ? 1 : 2; + return player.countCards("he") >= num && !player.hasSkill("kamome_jieban_phase"); }, - async cost(event, trigger, player){ - event.num=player.storage.kamome_jieban?1:2; - event.result = await player.chooseCardTarget({ - position:'he', - filterCard:true, - filterTarget:lib.filter.notMe, - selectCard:event.num, - prompt:get.prompt('kamome_jieban'), - prompt2:event.num==2?'将两张牌交给一名其他角色,然后其交给你一张牌。':'将一张牌交给一名其他角色,然后其交给你两张牌。', - ai1(card){ - if(card.name=='du') return 20; - var val=get.value(card); - var player=_status.event.player; - if(get.position(card)=='e'){ - if(val<=0) return 10; - return 10/val; - } - return 6-val; - }, - ai2(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(ui.selected.cards[0].name=='du') return -2*att; - if(att>0) return 1.5*att; - var num=get.select(_status.event.selectCard)[1]; - if(att<0&&num==1) return -0.7*att; - return att; - }, - }).forResult(); - }, - content(){ - 'step 0' - event.num=player.storage.kamome_jieban?1:2; - var target=targets[0]; - event.target=target; - player.addTempSkill('kamome_jieban_phase'); - player.give(cards,target); - player.changeZhuanhuanji('kamome_jieban'); - 'step 1' - var num=3-event.num; - var hs=target.getCards('he'); - if(hs.length){ - if(hs.length<=num) event._result={bool:true,cards:hs}; - else{ - target.chooseCard('he',true,'交给'+get.translation(player)+get.cnNumber(num)+'张牌',num).set('ai',function(card){ - var player=_status.event.player; - var target=_status.event.getParent().player; - if(get.attitude(player,target)>0){ - if(!target.hasShan()&&card.name=='shan') return 10; - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')&&target.hasUseTarget(card)) return 10-get.value(card); - return 6-get.value(card); + async cost(event, trigger, player) { + event.num = player.storage.kamome_jieban ? 1 : 2; + event.result = await player + .chooseCardTarget({ + position: "he", + filterCard: true, + filterTarget: lib.filter.notMe, + selectCard: event.num, + prompt: get.prompt("kamome_jieban"), + prompt2: + event.num == 2 + ? "将两张牌交给一名其他角色,然后其交给你一张牌。" + : "将一张牌交给一名其他角色,然后其交给你两张牌。", + ai1(card) { + if (card.name == "du") return 20; + var val = get.value(card); + var player = _status.event.player; + if (get.position(card) == "e") { + if (val <= 0) return 10; + return 10 / val; } - return -get.value(card); - }); + return 6 - val; + }, + ai2(target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (ui.selected.cards[0].name == "du") return -2 * att; + if (att > 0) return 1.5 * att; + var num = get.select(_status.event.selectCard)[1]; + if (att < 0 && num == 1) return -0.7 * att; + return att; + }, + }) + .forResult(); + }, + content() { + "step 0"; + event.num = player.storage.kamome_jieban ? 1 : 2; + var target = targets[0]; + event.target = target; + player.addTempSkill("kamome_jieban_phase"); + player.give(cards, target); + player.changeZhuanhuanji("kamome_jieban"); + "step 1"; + var num = 3 - event.num; + var hs = target.getCards("he"); + if (hs.length) { + if (hs.length <= num) event._result = { bool: true, cards: hs }; + else { + target + .chooseCard( + "he", + true, + "交给" + get.translation(player) + get.cnNumber(num) + "张牌", + num + ) + .set("ai", function (card) { + var player = _status.event.player; + var target = _status.event.getParent().player; + if (get.attitude(player, target) > 0) { + if (!target.hasShan() && card.name == "shan") return 10; + if ( + get.type(card) == "equip" && + !get.cardtag(card, "gifts") && + target.hasUseTarget(card) + ) + return 10 - get.value(card); + return 6 - get.value(card); + } + return -get.value(card); + }); } - } - else event.finish(); - 'step 2' - target.give(result.cards,player); + } else event.finish(); + "step 2"; + target.give(result.cards, player); }, }, - kamome_jieban_phase:{charlotte:true}, - nao_duyin:{ - trigger:{global:'phaseBegin'}, - filter(event,player){ - return event.player!=player&&(!player.storage.nao_duyin||!player.storage.nao_duyin.includes(event.player)); + kamome_jieban_phase: { charlotte: true }, + nao_duyin: { + trigger: { global: "phaseBegin" }, + filter(event, player) { + return ( + event.player != player && + (!player.storage.nao_duyin || !player.storage.nao_duyin.includes(event.player)) + ); }, - logTarget:'player', - charlotte:true, - check(){ + logTarget: "player", + charlotte: true, + check() { return false; }, - content(){ - 'step 0' - player.chooseToDiscard('he','弃置一张牌,或将武将牌翻面').set('ai',function(card){ - if(_status.event.player.isTurnedOver()) return 0; - return 6-get.value(card); + content() { + "step 0"; + player.chooseToDiscard("he", "弃置一张牌,或将武将牌翻面").set("ai", function (card) { + if (_status.event.player.isTurnedOver()) return 0; + return 6 - get.value(card); }); - 'step 1' - if(!result.bool) player.turnOver(); - player.addTempSkill('nao_duyin2',{player:'phaseAfter'}); - if(!player.storage.nao_duyin) player.storage.nao_duyin=[]; + "step 1"; + if (!result.bool) player.turnOver(); + player.addTempSkill("nao_duyin2", { player: "phaseAfter" }); + if (!player.storage.nao_duyin) player.storage.nao_duyin = []; player.storage.nao_duyin.push(trigger.player); - if(!player.storage.nao_duyin2) player.storage.nao_duyin2=[]; + if (!player.storage.nao_duyin2) player.storage.nao_duyin2 = []; player.storage.nao_duyin2.push(trigger.player); - player.markSkill('nao_duyin2'); + player.markSkill("nao_duyin2"); }, }, - nao_duyin2:{ - intro:{ - content:'$不能使用牌指定你为目标,对$使用牌没有距离和次数限制', + nao_duyin2: { + intro: { + content: "$不能使用牌指定你为目标,对$使用牌没有距离和次数限制", }, - mod:{ - targetEnabled(card,player,target){ - if(target.storage.nao_duyin2&&target.storage.nao_duyin2.includes(player)) return false; + mod: { + targetEnabled(card, player, target) { + if (target.storage.nao_duyin2 && target.storage.nao_duyin2.includes(player)) + return false; }, - targetInRange(card,player,target){ - if(player.storage.nao_duyin2&&player.storage.nao_duyin2.includes(target)) return true; + targetInRange(card, player, target) { + if (player.storage.nao_duyin2 && player.storage.nao_duyin2.includes(target)) + return true; }, }, - trigger:{player:'useCardEnd'}, - firstDo:true, - silent:true, - onremove:true, - filter(event,player){ - if(player.storage.nao_duyin2){ - for(var i of player.storage.nao_duyin2){ - if(event.targets.includes(i)) return true; + trigger: { player: "useCardEnd" }, + firstDo: true, + silent: true, + onremove: true, + filter(event, player) { + if (player.storage.nao_duyin2) { + for (var i of player.storage.nao_duyin2) { + if (event.targets.includes(i)) return true; } } return false; }, - content(){ - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat(); - if(stat&&stat.card&&stat.card[trigger.card.name]) stat.card[trigger.card.name]--; + content() { + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat(); + if (stat && stat.card && stat.card[trigger.card.name]) stat.card[trigger.card.name]--; } }, }, - nao_wanxin:{ - trigger:{global:'phaseEnd'}, - hasHistory(player){ - return player.getHistory('damage').length>0; + nao_wanxin: { + trigger: { global: "phaseEnd" }, + hasHistory(player) { + return player.getHistory("damage").length > 0; }, - filter(event,player){ - return game.hasPlayer(function(current){ + filter(event, player) { + return game.hasPlayer(function (current) { return lib.skill.nao_wanxin.hasHistory(current); }); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('nao_wanxin'),function(card,player,target){ - return _status.event.yuus.includes(target); - }).set('yuus',game.filterPlayer(function(current){ - return lib.skill.nao_wanxin.hasHistory(current); - })).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("nao_wanxin"), function (card, player, target) { + return _status.event.yuus.includes(target); + }) + .set( + "yuus", + game.filterPlayer(function (current) { + return lib.skill.nao_wanxin.hasHistory(current); + }) + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .forResult(); }, - async content(event, trigger, player){ - const target=event.targets[0]; + async content(event, trigger, player) { + const target = event.targets[0]; await target.draw(2); await player.turnOver(false); await player.link(false); - if(target==player) return; + if (target == player) return; await target.turnOver(false); await target.link(false); }, }, - nao_shouqing:{ - global:'nao_shouqing2', + nao_shouqing: { + global: "nao_shouqing2", }, - nao_shouqing2:{ - enable:'phaseUse', - viewAs(){ - return {name:'tao'} + nao_shouqing2: { + enable: "phaseUse", + viewAs() { + return { name: "tao" }; }, - filterCard:{name:'tao'}, - ignoreMod:true, - filterTarget(card,player,target){ - return target!=player&&target.isDamaged()&&target.hasSkill('nao_shouqing'); + filterCard: { name: "tao" }, + ignoreMod: true, + filterTarget(card, player, target) { + return target != player && target.isDamaged() && target.hasSkill("nao_shouqing"); }, - selectTarget(){ - return game.countPlayer(function(current){ - return lib.skill.nao_shouqing2.filterTarget(null,_status.event.player,current); - })>1?1:-1; + selectTarget() { + return game.countPlayer(function (current) { + return lib.skill.nao_shouqing2.filterTarget(null, _status.event.player, current); + }) > 1 + ? 1 + : -1; }, - filter(event,player){ - return player.countCards('hs','tao')&&game.hasPlayer(function(current){ - return lib.skill.nao_shouqing2.filterTarget(null,player,current) + filter(event, player) { + return ( + player.countCards("hs", "tao") && + game.hasPlayer(function (current) { + return lib.skill.nao_shouqing2.filterTarget(null, player, current); + }) + ); + }, + position: "hs", + onuse(links, player) { + player.addSkill("nao_shouqing3"); + player.addMark("nao_shouqing3", 1, false); + }, + prompt() { + var list = game.filterPlayer(function (current) { + return lib.skill.nao_shouqing2.filterTarget(null, _status.event.player, current); }); - }, - position:'hs', - onuse(links,player){ - player.addSkill('nao_shouqing3'); - player.addMark('nao_shouqing3',1,false); - }, - prompt(){ - var list=game.filterPlayer(function(current){ - return lib.skill.nao_shouqing2.filterTarget(null,_status.event.player,current); - }); - var str='对'+get.translation(list); - if(list.length>1) str+='中的一名角色'; - str+='使用一张【桃】'; + var str = "对" + get.translation(list); + if (list.length > 1) str += "中的一名角色"; + str += "使用一张【桃】"; return str; }, }, - nao_shouqing3:{ - intro:{ - content:'手牌上限+#', + nao_shouqing3: { + intro: { + content: "手牌上限+#", }, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('nao_shouqing3'); + mod: { + maxHandcard(player, num) { + return num + player.countMark("nao_shouqing3"); }, }, - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='nao_shouqing2'; + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter(event, player) { + return event.skill == "nao_shouqing2"; }, - content(){ + content() { player.draw(); }, }, - shiorimiyuki_banyin:{ - audio:2, - trigger:{player:['damageEnd','recoverEnd']}, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged(); - }) + shiorimiyuki_banyin: { + audio: 2, + trigger: { player: ["damageEnd", "recoverEnd"] }, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isDamaged(); + }); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt('shiorimiyuki_banyin'),'令一名其他角色回复1点体力',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("shiorimiyuki_banyin"), + "令一名其他角色回复1点体力", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.recoverEffect(target, player, player); + }) + .forResult(); }, - async content(event, trigger, player){ - const target=event.targets[0]; + async content(event, trigger, player) { + const target = event.targets[0]; target.recover(); }, }, - shiorimiyuki_tingxian:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - async cost(event, trigger, player){ - const {control, index} = await player.chooseControl('一张','两张','三张','cancel2').set('prompt',get.prompt2('shiorimiyuki_tingxian')).set('ai',function(){ - var player=_status.event.player; - var max=Math.min(player.hp+1,player.maxHp) - var min=Math.min(Math.max(max-2,max-player.hp),3); - if(min) return min-1; - return 3; - }).forResult(); - if (control != 'cancel2') event.result = {bool:true, cost_data:index}; + shiorimiyuki_tingxian: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + async cost(event, trigger, player) { + const { control, index } = await player + .chooseControl("一张", "两张", "三张", "cancel2") + .set("prompt", get.prompt2("shiorimiyuki_tingxian")) + .set("ai", function () { + var player = _status.event.player; + var max = Math.min(player.hp + 1, player.maxHp); + var min = Math.min(Math.max(max - 2, max - player.hp), 3); + if (min) return min - 1; + return 3; + }) + .forResult(); + if (control != "cancel2") event.result = { bool: true, cost_data: index }; }, - async content(event, trigger, player){ + async content(event, trigger, player) { let num = 1 + event.cost_data; - await player.draw(num).set('gaintag', ['shiorimiyuki_tingxian']); + await player.draw(num).set("gaintag", ["shiorimiyuki_tingxian"]); await player.recover(); - player.addTempSkill('shiorimiyuki_tingxian2'); + player.addTempSkill("shiorimiyuki_tingxian2"); }, - group:'shiorimiyuki_tingxian1', + group: "shiorimiyuki_tingxian1", }, - shiorimiyuki_tingxian1:{audio:true}, - shiorimiyuki_tingxian2:{ - audio:true, - trigger:{player:'phaseUseEnd'}, - forced:true, - charlotte:true, - mod:{ - aiOrder(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('shiorimiyuki_tingxian')) return num+2; + shiorimiyuki_tingxian1: { audio: true }, + shiorimiyuki_tingxian2: { + audio: true, + trigger: { player: "phaseUseEnd" }, + forced: true, + charlotte: true, + mod: { + aiOrder(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("shiorimiyuki_tingxian")) + return num + 2; }, - aiValue(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('shiorimiyuki_tingxian')) return 0; + aiValue(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("shiorimiyuki_tingxian")) + return 0; }, }, - filter(event,player){ - return player.countCards('h',function(card){ - return card.hasGaintag('shiorimiyuki_tingxian'); - })>0; + filter(event, player) { + return ( + player.countCards("h", function (card) { + return card.hasGaintag("shiorimiyuki_tingxian"); + }) > 0 + ); }, - content(){ - player.loseHp(player.countCards('h',function(card){ - return card.hasGaintag('shiorimiyuki_tingxian'); - })); - player.removeGaintag('shiorimiyuki_tingxian'); + content() { + player.loseHp( + player.countCards("h", function (card) { + return card.hasGaintag("shiorimiyuki_tingxian"); + }) + ); + player.removeGaintag("shiorimiyuki_tingxian"); }, }, - shizuru_nianli:{ - enable:'chooseToUse', - charlotte:true, - prompt:'展示一张♦/♣/♥/♠手牌,然后视为使用一张雷杀/闪/桃/无懈可击', - viewAs(cards,player){ - var name=false; - var nature=null; - switch(get.suit(cards[0],player)){ - case 'club':name='shan';break; - case 'diamond':name='sha';nature='thunder';break; - case 'spade':name='wuxie';break; - case 'heart':name='tao';break; + shizuru_nianli: { + enable: "chooseToUse", + charlotte: true, + prompt: "展示一张♦/♣/♥/♠手牌,然后视为使用一张雷杀/闪/桃/无懈可击", + viewAs(cards, player) { + var name = false; + var nature = null; + switch (get.suit(cards[0], player)) { + case "club": + name = "shan"; + break; + case "diamond": + name = "sha"; + nature = "thunder"; + break; + case "spade": + name = "wuxie"; + break; + case "heart": + name = "tao"; + break; } - if(name) return {name:name,nature:nature,isCard:true}; + if (name) return { name: name, nature: nature, isCard: true }; return null; }, - check(card){ - var player=_status.event.player; - if(_status.event.type=='phase'){ - var max=0; + check(card) { + var player = _status.event.player; + if (_status.event.type == "phase") { + var max = 0; var name2; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("h", function (card) { + return get.suit(card, player) == map[name]; + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return 1; + if (name2 == get.suit(card, player)) return 1; return 0; } return 1; }, - ignoreMod:true, - filterCard(card,player,event){ - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.suit(card,player); - if(name=='club'&&filter({name:'shan'},player,event)) return true; - if(name=='diamond'&&filter({name:'sha',nature:'thunder'},player,event)) return true; - if(name=='spade'&&filter({name:'wuxie'},player,event)) return true; - if(name=='heart'&&filter({name:'tao'},player,event)) return true; + ignoreMod: true, + filterCard(card, player, event) { + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.suit(card, player); + if (name == "club" && filter({ name: "shan" }, player, event)) return true; + if (name == "diamond" && filter({ name: "sha", nature: "thunder" }, player, event)) + return true; + if (name == "spade" && filter({ name: "wuxie" }, player, event)) return true; + if (name == "heart" && filter({ name: "tao" }, player, event)) return true; return false; }, - filter(event,player){ - if(player.hasSkill('shizuru_nianli_round')) return false; - var filter=event.filterCard; - if(filter({name:'sha',nature:'thunder'},player,event)&&player.countCards('h',{suit:'diamond'})) return true; - if(filter({name:'shan'},player,event)&&player.countCards('h',{suit:'club'})) return true; - if(filter({name:'tao'},player,event)&&player.countCards('h',{suit:'heart'})) return true; - if(filter({name:'wuxie'},player,event)&&player.countCards('h',{suit:'spade'})) return true; + filter(event, player) { + if (player.hasSkill("shizuru_nianli_round")) return false; + var filter = event.filterCard; + if ( + filter({ name: "sha", nature: "thunder" }, player, event) && + player.countCards("h", { suit: "diamond" }) + ) + return true; + if (filter({ name: "shan" }, player, event) && player.countCards("h", { suit: "club" })) + return true; + if (filter({ name: "tao" }, player, event) && player.countCards("h", { suit: "heart" })) + return true; + if (filter({ name: "wuxie" }, player, event) && player.countCards("h", { suit: "spade" })) + return true; return false; }, - precontent(){ - player.logSkill('shizuru_nianli'); - player.addTempSkill('shizuru_nianli_round','roundStart'); - player.showCards(get.translation(player)+'发动了【念力】',event.result.cards.slice(0)); - event.result.card.cards=[]; - event.result.cards=[]; + precontent() { + player.logSkill("shizuru_nianli"); + player.addTempSkill("shizuru_nianli_round", "roundStart"); + player.showCards(get.translation(player) + "发动了【念力】", event.result.cards.slice(0)); + event.result.card.cards = []; + event.result.cards = []; delete event.result.skill; delete event.result.card.suit; delete event.result.card.number; - event.getParent().addCount=false; - event.getParent().shizuru_nianli=true; + event.getParent().addCount = false; + event.getParent().shizuru_nianli = true; }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ - if(player.hasSkill('shizuru_nianli_round')) return false; + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { + if (player.hasSkill("shizuru_nianli_round")) return false; var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('h',{suit:name})) return false; + if (!player.countCards("h", { suit: name })) return false; }, - order(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'thunder':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'thunder':null}); - if(temp>max) max=temp; + order(item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("h", function (card) { + return get.suit(card, player) == map[name]; + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "thunder" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "thunder" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard(player,name){ - if(name=='wuxie') return player.countCards('h',function(card){ - return _status.connectMode||get.suit(card)=='spade'; - })>0&&!player.hasSkill('shizuru_nianli_round'); - if(name=='tao') return player.countCards('h',{suit:'heart'})>0&&!player.hasSkill('shizuru_nianli_round'); + hiddenCard(player, name) { + if (name == "wuxie") + return ( + player.countCards("h", function (card) { + return _status.connectMode || get.suit(card) == "spade"; + }) > 0 && !player.hasSkill("shizuru_nianli_round") + ); + if (name == "tao") + return ( + player.countCards("h", { suit: "heart" }) > 0 && + !player.hasSkill("shizuru_nianli_round") + ); return false; }, - group:'shizuru_nianli_clear', - subSkill:{ - round:{ - mark:true, - intro:{content:'本轮已发动'}, + group: "shizuru_nianli_clear", + subSkill: { + round: { + mark: true, + intro: { content: "本轮已发动" }, }, - clear:{ - trigger:{player:'useCardAfter'}, - lastDo:true, - silent:true, - filter(event,player){ - return event.getParent().shizuru_nianli==true; + clear: { + trigger: { player: "useCardAfter" }, + lastDo: true, + silent: true, + filter(event, player) { + return event.getParent().shizuru_nianli == true; }, - content(){ - player.getHistory('useCard').remove(trigger); + content() { + player.getHistory("useCard").remove(trigger); }, }, }, }, - shizuru_benzhan:{ - trigger:{global:['useCard','respond']}, - usable:1, - filter(event,player){ - return Array.isArray(event.respondTo)&&event.respondTo[0]!=event.player&&[event.respondTo[0],event.player].includes(player); + shizuru_benzhan: { + trigger: { global: ["useCard", "respond"] }, + usable: 1, + filter(event, player) { + return ( + Array.isArray(event.respondTo) && + event.respondTo[0] != event.player && + [event.respondTo[0], event.player].includes(player) + ); }, - async cost(event, trigger, player){ - event.type=get.type(trigger.card)=='basic'; - var prompt=event.type?'令一名角色摸两张牌或弃置两张牌':'令一名角色回复1点体力或对其造成1点伤害'; - event.result = await player.chooseTarget(get.prompt('shizuru_benzhan'),prompt).set('ai',function(target){ - var player=_status.event.player; - if(_status.event.getParent().type){ - var att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) return -att; - if(target.countCards('he')==1&&att<0) att/=2; - return Math.abs(att)*(1+0.1*(Math.min(0,5-target.countCards('h')))) - } - return Math.max(get.recoverEffect(target,player,player),get.damageEffect(target,player,player)) - }).forResult(); + async cost(event, trigger, player) { + event.type = get.type(trigger.card) == "basic"; + var prompt = event.type + ? "令一名角色摸两张牌或弃置两张牌" + : "令一名角色回复1点体力或对其造成1点伤害"; + event.result = await player + .chooseTarget(get.prompt("shizuru_benzhan"), prompt) + .set("ai", function (target) { + var player = _status.event.player; + if (_status.event.getParent().type) { + var att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) return -att; + if (target.countCards("he") == 1 && att < 0) att /= 2; + return Math.abs(att) * (1 + 0.1 * Math.min(0, 5 - target.countCards("h"))); + } + return Math.max( + get.recoverEffect(target, player, player), + get.damageEffect(target, player, player) + ); + }) + .forResult(); }, - content(){ - 'step 0' - event.type=get.type(trigger.card)=='basic'; - var target=event.targets[0]; - event.target=target; - var trans=get.translation(target); + content() { + "step 0"; + event.type = get.type(trigger.card) == "basic"; + var target = event.targets[0]; + event.target = target; + var trans = get.translation(target); var list; - if(event.type){ - if(!target.countCards('he')) event._result={index:0}; - else list=['令'+trans+'摸两张牌','令'+trans+'弃置两张牌']; + if (event.type) { + if (!target.countCards("he")) event._result = { index: 0 }; + else list = ["令" + trans + "摸两张牌", "令" + trans + "弃置两张牌"]; + } else { + if (target.isHealthy()) event._result = { index: 1 }; + else list = ["令" + trans + "回复1点体力", "对" + trans + "造成1点伤害"]; } - else{ - if(target.isHealthy()) event._result={index:1}; - else list=['令'+trans+'回复1点体力','对'+trans+'造成1点伤害']; - } - player.chooseControl().set('choiceList',list).set('choice',function(){ - if(event.type) return (get.attitude(player,target)>0)?0:1; - return (get.recoverEffect(target,player,player)>get.damageEffect(target,player,player))?0:1; - }()).set('ai',function(){ - return _status.event.choice; - }); - 'step 1' + player + .chooseControl() + .set("choiceList", list) + .set( + "choice", + (function () { + if (event.type) return get.attitude(player, target) > 0 ? 0 : 1; + return get.recoverEffect(target, player, player) > + get.damageEffect(target, player, player) + ? 0 + : 1; + })() + ) + .set("ai", function () { + return _status.event.choice; + }); + "step 1"; player.addExpose(0.2); - if(event.type){ - if(result.index==0) target.draw(2); - else target.chooseToDiscard(2,'he',true); - } - else{ - if(result.index==0) target.recover(); + if (event.type) { + if (result.index == 0) target.draw(2); + else target.chooseToDiscard(2, "he", true); + } else { + if (result.index == 0) target.recover(); else target.damage(); } }, }, - kyoko_juwu:{ - trigger:{global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter']}, - filter(event,player){ - if(player==_status.currentPhase) return false; - var cards=event.getd(); - if(!cards.length) return false; + kyoko_juwu: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], + }, + filter(event, player) { + if (player == _status.currentPhase) return false; + var cards = event.getd(); + if (!cards.length) return false; cards.removeArray(event.getd(player)); - for(var card of cards){ - if(get.position(card,true)=='d'&&get.type(card,null,false)=='equip') return true; + for (var card of cards) { + if (get.position(card, true) == "d" && get.type(card, null, false) == "equip") + return true; } return false; }, - autodelay(event,player){ + autodelay(event, player) { return event.delay === false; }, - async cost(event, trigger, player){ - var cards=trigger.getd(); + async cost(event, trigger, player) { + var cards = trigger.getd(); cards.removeArray(trigger.getd(player)); - cards=cards.filter(function(card){ - if(get.position(card,true)=='d'&&get.type(card,null,false)=='equip') return true; + cards = cards.filter(function (card) { + if (get.position(card, true) == "d" && get.type(card, null, false) == "equip") + return true; }); - const {result} = await player.chooseButton([get.prompt('kyoko_juwu'),cards],[1,cards.length]).set('ai',function(){return 1}); - if(result.bool) event.result = { - bool: true, - cards: result.links - } + const { result } = await player + .chooseButton([get.prompt("kyoko_juwu"), cards], [1, cards.length]) + .set("ai", function () { + return 1; + }); + if (result.bool) + event.result = { + bool: true, + cards: result.links, + }; }, - async content(event, trigger, player){ - await player.gain(event.cards, 'gain2', 'log'); + async content(event, trigger, player) { + await player.gain(event.cards, "gain2", "log"); }, }, - kyoko_zhengyi:{ - group:['kyoko_jingce','kyoko_shelie','kyoko_zhiheng'], - count(player){ - var list=[]; - player.countCards('e',function(card){ - list.add(get.suit(card,player)); + kyoko_zhengyi: { + group: ["kyoko_jingce", "kyoko_shelie", "kyoko_zhiheng"], + count(player) { + var list = []; + player.countCards("e", function (card) { + list.add(get.suit(card, player)); }); return list.length; }, }, - kyoko_jingce:{ - trigger:{player:['phaseUseEnd','phaseJieshuBegin']}, - filter(event,player){ - var num=lib.skill.kyoko_zhengyi.count(player); - if(!num||(event.name=='phaseUse')==(num>3)) return false; - return player.getHistory('useCard',function(evt){ - return event.name!='phaseUse'||evt.getParent('phaseUse')==event; - }).length>=player.hp; + kyoko_jingce: { + trigger: { player: ["phaseUseEnd", "phaseJieshuBegin"] }, + filter(event, player) { + var num = lib.skill.kyoko_zhengyi.count(player); + if (!num || (event.name == "phaseUse") == num > 3) return false; + return ( + player.getHistory("useCard", function (evt) { + return event.name != "phaseUse" || evt.getParent("phaseUse") == event; + }).length >= player.hp + ); }, - frequent:true, - content(){ - 'step 0' - if(trigger.name=='phaseUse'){ + frequent: true, + content() { + "step 0"; + if (trigger.name == "phaseUse") { player.draw(2); event.finish(); return; } - var list=[],history=player.getHistory('useCard'); - for(var i of history){ + var list = [], + history = player.getHistory("useCard"); + for (var i of history) { list.add(get.suit(i.card)); - if(list.length>=player.hp) break; + if (list.length >= player.hp) break; } - if(list.length>=player.hp) event.goon=true; - else player.chooseControl('摸牌阶段','出牌阶段').set('prompt','精策:选择要执行的额外阶段'); - 'step 1' - if(event.goon||result.index==0){ - var next=player.phaseDraw(); + if (list.length >= player.hp) event.goon = true; + else + player + .chooseControl("摸牌阶段", "出牌阶段") + .set("prompt", "精策:选择要执行的额外阶段"); + "step 1"; + if (event.goon || result.index == 0) { + var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); } - if(event.goon||result.index==1){ - var next=player.phaseUse(); + if (event.goon || result.index == 1) { + var next = player.phaseUse(); event.next.remove(next); trigger.getParent().next.push(next); } }, }, - kyoko_shelie:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter(event,player){ - return !event.numFixed&&lib.skill.kyoko_zhengyi.count(player)>1; + kyoko_shelie: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter(event, player) { + return !event.numFixed && lib.skill.kyoko_zhengyi.count(player) > 1; }, - content(){ - "step 0" + content() { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(5); + event.cards = get.cards(5); game.cardsGotoOrdering(event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str; - if(player==game.me&&!_status.auto){ - str='涉猎:获取花色各不相同的牌'; - } - else{ - str='涉猎'; - } - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - event.time=get.utc(); - game.addVideo('showCards',player,['涉猎',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - "step 1" - var next=player.chooseButton([0,5],true); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - for(var i=0;i0){ - game.delay(0,time); + var time = 1000 - (get.utc() - event.time); + if (time > 0) { + game.delay(0, time); } - "step 3" - game.broadcastAll('closeDialog',event.videoId); - var cards2=event.cards2; - player.gain(cards2,'log','gain2'); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var cards2 = event.cards2; + player.gain(cards2, "log", "gain2"); }, }, - kyoko_zhiheng:{ - enable:'phaseUse', - usable:1, - position:'he', - filter(event,player){ - return lib.skill.kyoko_zhengyi.count(player)>2; + kyoko_zhiheng: { + enable: "phaseUse", + usable: 1, + position: "he", + filter(event, player) { + return lib.skill.kyoko_zhengyi.count(player) > 2; }, - prompt(){ - var str='弃置任意张牌并摸等量的牌'; - if(lib.skill.kyoko_zhengyi.count(_status.event.player)>3) str+=',若弃置了所有手牌则多摸一张牌。'; + prompt() { + var str = "弃置任意张牌并摸等量的牌"; + if (lib.skill.kyoko_zhengyi.count(_status.event.player) > 3) + str += ",若弃置了所有手牌则多摸一张牌。"; return str; }, - filterCard:lib.filter.cardDiscardable, - discard:false, - lose:false, - delay:false, - selectCard:[1,Infinity], - check(card){ - var player=_status.event.player; - if(get.position(card)=='h'){ - return 8-get.value(card); + filterCard: lib.filter.cardDiscardable, + discard: false, + lose: false, + delay: false, + selectCard: [1, Infinity], + check(card) { + var player = _status.event.player; + if (get.position(card) == "h") { + return 8 - get.value(card); } - return 6-get.value(card) + return 6 - get.value(card); }, - content(){ - 'step 0' + content() { + "step 0"; player.discard(cards); - event.num=1; - var hs=player.getCards('h'); - if(!hs.length||lib.skill.kyoko_zhengyi.count(player)<4) event.num=0; - else for(var i=0;i1; + check(event, player) { + return player.hp <= 1 || player.getDamagedHp() > 1; }, - content(){ + content() { player.awakenSkill(event.name); - var num=player.maxHp-player.hp; + var num = player.maxHp - player.hp; player.recover(num); player.draw(num); - if(_status.characterlist&&_status.characterlist.includes('key_midori')){ - player.reinitCharacter('key_mio','key_midori', false); + if (_status.characterlist && _status.characterlist.includes("key_midori")) { + player.reinitCharacter("key_mio", "key_midori", false); } }, }, - midori_nonghuan:{ - enable:'phaseUse', - charlotte:true, - filter(event,player){ - return (player.getStat('skill').midori_nonghuan||0)0; + filterTarget(card, player, target) { + var stat = player.getStat("midori_nonghuan"); + return ( + target != player && + (!stat || !stat.includes(target)) && + target.countGainableCards(player, "hej") > 0 + ); }, - content(){ - 'step 0' - var stat=player.getStat(); - if(!stat.midori_nonghuan) stat.midori_nonghuan=[]; + content() { + "step 0"; + var stat = player.getStat(); + if (!stat.midori_nonghuan) stat.midori_nonghuan = []; stat.midori_nonghuan.push(target); - player.gainPlayerCard(target,'hej',true); + player.gainPlayerCard(target, "hej", true); player.draw(); - 'step 1' - if(player.countCards('he')>0) player.chooseCard('he',true,'交给'+get.translation(target)+'一张牌'); + "step 1"; + if (player.countCards("he") > 0) + player.chooseCard("he", true, "交给" + get.translation(target) + "一张牌"); else event.goto(3); - 'step 2' - player.give(result.cards,target); - 'step 3' - var history=game.getGlobalHistory('cardMove'); - for(var i=0;i1; + check(event, player) { + return player.hp <= 1 || player.getDamagedHp() > 1; }, - content(){ + content() { player.awakenSkill(event.name); - var num=player.maxHp-player.hp; + var num = player.maxHp - player.hp; player.recover(num); player.draw(num); - if(_status.characterlist&&_status.characterlist.includes('key_mio')){ - player.reinitCharacter('key_midori', 'key_mio', false); + if (_status.characterlist && _status.characterlist.includes("key_mio")) { + player.reinitCharacter("key_midori", "key_mio", false); } }, }, - kanade_mapo:{ - audio:2, - derivation:'mapodoufu', - enable:'chooseToUse', - viewAs:{name:'mapodoufu'}, - filterCard:{suit:'heart'}, - viewAsFilter(player){ - return player.countCards('hes',{suit:'heart'})>0; + kanade_mapo: { + audio: 2, + derivation: "mapodoufu", + enable: "chooseToUse", + viewAs: { name: "mapodoufu" }, + filterCard: { suit: "heart" }, + viewAsFilter(player) { + return player.countCards("hes", { suit: "heart" }) > 0; }, - position:'hes', - mod:{ - selectTarget(card,player,range){ - if(card.name=='mapodoufu'&&range[1]!=-1) range[1]++; + position: "hes", + mod: { + selectTarget(card, player, range) { + if (card.name == "mapodoufu" && range[1] != -1) range[1]++; }, }, - check(card){ - var player=_status.event.player; - if(game.countPlayer(function(current){ - return player.canUse('mapodoufu',current)&&get.effect(current,{name:'mapodoufu'},player,player)>0; - })>1) return 6-get.value(card); - return 4-get.value(card); + check(card) { + var player = _status.event.player; + if ( + game.countPlayer(function (current) { + return ( + player.canUse("mapodoufu", current) && + get.effect(current, { name: "mapodoufu" }, player, player) > 0 + ); + }) > 1 + ) + return 6 - get.value(card); + return 4 - get.value(card); }, }, - kanade_benzhan:{ - audio:3, - trigger:{global:['useCard','respond']}, - usable:1, - filter(event,player){ - return Array.isArray(event.respondTo)&&event.respondTo[0]!=event.player&&[event.respondTo[0],event.player].includes(player); + kanade_benzhan: { + audio: 3, + trigger: { global: ["useCard", "respond"] }, + usable: 1, + filter(event, player) { + return ( + Array.isArray(event.respondTo) && + event.respondTo[0] != event.player && + [event.respondTo[0], event.player].includes(player) + ); }, - async cost(event, trigger, player){ - event.type=get.type(trigger.card)=='basic'; - var prompt=event.type?'令一名角色摸两张牌或弃置两张牌':'令一名角色回复1点体力或对其造成1点伤害'; - event.result = await player.chooseTarget(get.prompt('kanade_benzhan'),prompt).set('ai',function(target){ - var player=_status.event.player; - if(_status.event.getParent().type){ - var att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) return -att; - if(target.countCards('he')==1&&att<0) att/=2; - return Math.abs(att)*(1+0.1*(Math.min(0,5-target.countCards('h')))) - } - return Math.max(get.recoverEffect(target,player,player),get.damageEffect(target,player,player)) - }).forResult(); + async cost(event, trigger, player) { + event.type = get.type(trigger.card) == "basic"; + var prompt = event.type + ? "令一名角色摸两张牌或弃置两张牌" + : "令一名角色回复1点体力或对其造成1点伤害"; + event.result = await player + .chooseTarget(get.prompt("kanade_benzhan"), prompt) + .set("ai", function (target) { + var player = _status.event.player; + if (_status.event.getParent().type) { + var att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) return -att; + if (target.countCards("he") == 1 && att < 0) att /= 2; + return Math.abs(att) * (1 + 0.1 * Math.min(0, 5 - target.countCards("h"))); + } + return Math.max( + get.recoverEffect(target, player, player), + get.damageEffect(target, player, player) + ); + }) + .forResult(); }, - content(){ - 'step 0' - event.type=get.type(trigger.card)=='basic'; - var target=event.targets[0]; - event.target=target; - var trans=get.translation(target); + content() { + "step 0"; + event.type = get.type(trigger.card) == "basic"; + var target = event.targets[0]; + event.target = target; + var trans = get.translation(target); var list; - if(event.type){ - if(!target.countCards('he')) event._result={index:0}; - else list=['令'+trans+'摸两张牌','令'+trans+'弃置两张牌']; + if (event.type) { + if (!target.countCards("he")) event._result = { index: 0 }; + else list = ["令" + trans + "摸两张牌", "令" + trans + "弃置两张牌"]; + } else { + if (target.isHealthy()) event._result = { index: 1 }; + else list = ["令" + trans + "回复1点体力", "对" + trans + "造成1点伤害"]; } - else{ - if(target.isHealthy()) event._result={index:1}; - else list=['令'+trans+'回复1点体力','对'+trans+'造成1点伤害']; - } - player.chooseControl().set('choiceList',list).set('choice',function(){ - if(event.type) return (get.attitude(player,target)>0)?0:1; - return (get.recoverEffect(target,player,player)>get.damageEffect(target,player,player))?0:1; - }()).set('ai',function(){ - return _status.event.choice; - }); - 'step 1' + player + .chooseControl() + .set("choiceList", list) + .set( + "choice", + (function () { + if (event.type) return get.attitude(player, target) > 0 ? 0 : 1; + return get.recoverEffect(target, player, player) > + get.damageEffect(target, player, player) + ? 0 + : 1; + })() + ) + .set("ai", function () { + return _status.event.choice; + }); + "step 1"; player.addExpose(0.2); - if(event.type){ - if(result.index==0) target.draw(2); - else target.chooseToDiscard(2,'he',true); - } - else{ - if(result.index==0) target.recover(); + if (event.type) { + if (result.index == 0) target.draw(2); + else target.chooseToDiscard(2, "he", true); + } else { + if (result.index == 0) target.recover(); else target.damage(); } }, }, - yuzuru_wuxin:{ - trigger:{player:'phaseJieshuBegin'}, - async cost(event, trigger, player){ - event.result = await player.chooseCardTarget({ - filterTarget(){ - if(ui.selected.cards.length) return false; - return true; - }, - filterCard(){ - if(ui.selected.targets.length) return false; - return lib.filter.cardDiscardable.apply(this,arguments); - }, - selectTarget(){ - if(!ui.selected.cards.length) return [1,1]; - return [0,0]; - }, - selectCard(){ - if(ui.selected.targets.length) return [0,0]; - if(!ui.selected.cards.length) return [0,2]; - return [2,2]; - }, - prompt:get.prompt2('yuzuru_wuxin'), - complexCard:true, - complexTarget:true, - ai1(card){ - var player=_status.event.player; - if(player.hp>3) return 0; - return (player.getDamagedHp()*2)-get.value(card); - }, - ai2(target){ - if(player.hp<4||target.hasSkillTag('nogain')) return 0; - return get.attitude(_status.event.player,target); - }, - }).forResult(); + yuzuru_wuxin: { + trigger: { player: "phaseJieshuBegin" }, + async cost(event, trigger, player) { + event.result = await player + .chooseCardTarget({ + filterTarget() { + if (ui.selected.cards.length) return false; + return true; + }, + filterCard() { + if (ui.selected.targets.length) return false; + return lib.filter.cardDiscardable.apply(this, arguments); + }, + selectTarget() { + if (!ui.selected.cards.length) return [1, 1]; + return [0, 0]; + }, + selectCard() { + if (ui.selected.targets.length) return [0, 0]; + if (!ui.selected.cards.length) return [0, 2]; + return [2, 2]; + }, + prompt: get.prompt2("yuzuru_wuxin"), + complexCard: true, + complexTarget: true, + ai1(card) { + var player = _status.event.player; + if (player.hp > 3) return 0; + return player.getDamagedHp() * 2 - get.value(card); + }, + ai2(target) { + if (player.hp < 4 || target.hasSkillTag("nogain")) return 0; + return get.attitude(_status.event.player, target); + }, + }) + .forResult(); }, - async content(event, trigger, player){ - if (event.cards&&event.cards.length) { + async content(event, trigger, player) { + if (event.cards && event.cards.length) { player.discard(event.cards); player.recover(); - } - else { + } else { const target = event.targets[0]; player.loseHp(); target.draw(2); } }, }, - yuzuru_deyi:{ - derivation:['yuzuru_kunfen','yuzuru_quji','yuzuru_wangsheng','yuzuru_kunfen_rewrite','yuzuru_quji_rewrite'], - trigger:{global:'dieAfter'}, - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'orange', - content(){ - player.awakenSkill('yuzuru_deyi'); - player.changeSkills(['yuzuru_kunfen','yuzuru_quji','yuzuru_wangsheng'],['yuzuru_wuxin']); + yuzuru_deyi: { + derivation: [ + "yuzuru_kunfen", + "yuzuru_quji", + "yuzuru_wangsheng", + "yuzuru_kunfen_rewrite", + "yuzuru_quji_rewrite", + ], + trigger: { global: "dieAfter" }, + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "orange", + content() { + player.awakenSkill("yuzuru_deyi"); + player.changeSkills( + ["yuzuru_kunfen", "yuzuru_quji", "yuzuru_wangsheng"], + ["yuzuru_wuxin"] + ); player.loseMaxHp(); player.recover(); }, }, - yuzuru_kunfen:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content(){ - 'step 0' - if(!player.storage._yuzuru_sss) player.loseHp(); + yuzuru_kunfen: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content() { + "step 0"; + if (!player.storage._yuzuru_sss) player.loseHp(); player.draw(2); - 'step 1' - if(player.countCards('he')<2) event.finish(); - else{ + "step 1"; + if (player.countCards("he") < 2) event.finish(); + else { player.chooseCardTarget({ - selectCard:2, - filterTarget:lib.filter.notMe, - prompt:'是否交给一名其他角色两张牌?', - position:'he', - ai1(card){ - var player=_status.event.player; - if(player.maxHp-player.hp==1&&card.name=='du') return 30; - var check=player.countCards('h')-2; - if(check<1) return 0; - if(player.hp>1&&check<2) return 0; - return get.unuseful(card)+9; + selectCard: 2, + filterTarget: lib.filter.notMe, + prompt: "是否交给一名其他角色两张牌?", + position: "he", + ai1(card) { + var player = _status.event.player; + if (player.maxHp - player.hp == 1 && card.name == "du") return 30; + var check = player.countCards("h") - 2; + if (check < 1) return 0; + if (player.hp > 1 && check < 2) return 0; + return get.unuseful(card) + 9; }, - ai2(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length==1&&ui.selected.cards[0].name=='du') return 1-att; - return att-2; + ai2(target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length == 1 && ui.selected.cards[0].name == "du") + return 1 - att; + return att - 2; }, }); } - 'step 2' - if(result.bool) player.give(result.cards,result.targets[0]); + "step 2"; + if (result.bool) player.give(result.cards, result.targets[0]); }, }, - yuzuru_quji:{ - audio:2, - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - selectCard(){ - var player=_status.event.player; + yuzuru_quji: { + audio: 2, + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + selectCard() { + var player = _status.event.player; return player.getDamagedHp(); }, - filterTarget(card,player,target){ - return target!=player&&target.hp0){ + player.awakenSkill("yuzuru_wangsheng"); + player.storage._yuzuru_sss = true; + if (player.countCards("he") > 0) { player.chooseCardTarget({ - selectCard:[1,Infinity], - filterTarget:lib.filter.notMe, - prompt:'将任意张牌交给一名其他角色,或点【取消】。', - position:'he', - ai1(card){ - var player=_status.event.player; - if(get.suit(card,false)=='heart'&&game.hasPlayer(function(current){ - return current.hasSkill('kanade_mapo')&&get.attitude(player,current)>0; - })) return 1; + selectCard: [1, Infinity], + filterTarget: lib.filter.notMe, + prompt: "将任意张牌交给一名其他角色,或点【取消】。", + position: "he", + ai1(card) { + var player = _status.event.player; + if ( + get.suit(card, false) == "heart" && + game.hasPlayer(function (current) { + return ( + current.hasSkill("kanade_mapo") && + get.attitude(player, current) > 0 + ); + }) + ) + return 1; return 0; }, - ai2(kanade){ - if(kanade.hasSkill('kanade_mapo')&&get.attitude(_status.event.player,kanade)>0) return 2; + ai2(kanade) { + if ( + kanade.hasSkill("kanade_mapo") && + get.attitude(_status.event.player, kanade) > 0 + ) + return 2; return 0; }, }); - } - else event.goto(2); - 'step 1' - if(result.bool) player.give(result.cards,result.targets[0]); - 'step 2' + } else event.goto(2); + "step 1"; + if (result.bool) player.give(result.cards, result.targets[0]); + "step 2"; player.loseMaxHp(); - 'step 3' - if(player.hp<2) player.recover(2-player.hp); + "step 3"; + if (player.hp < 2) player.recover(2 - player.hp); }, }, - ao_xishi:{ - trigger:{ - player:['useCard','respond'], - target:'useCardToTargeted', + ao_xishi: { + trigger: { + player: ["useCard", "respond"], + target: "useCardToTargeted", }, - forced:true, - filter(event,player,name){ - return (name=='useCard'||name=='respond'||event.player!=player)&&get.suit(event.card)=='diamond'; + forced: true, + filter(event, player, name) { + return ( + (name == "useCard" || name == "respond" || event.player != player) && + get.suit(event.card) == "diamond" + ); }, - content(){player.draw()}, - }, - ao_kuihun:{ - trigger:{global:'dying'}, - logTarget:'player', - line:'thunder', - filter(event,player){ - return player!=event.player; - }, - content(){ - 'step 0' + content() { player.draw(); - 'step 1' - if(!trigger.player.countCards('h')) event.finish(); - else player.chooseButton(['选择一张牌作为「蝶」',trigger.player.getCards('h')]).set('ai',function(button){ - var val=get.buttonValue(button); - if(get.attitude(_status.event.player,get.owner(button.link))<=0) return 10+val; - if(val<=0) return 20; - if(button.link.name=='tao'||button.link.name=='jiu') return 0; - return 1/val; - }); - 'step 2' - if(result.bool){ - player.addToExpansion(result.links,trigger.player,'give').set('log',false).gaintag.add('ao_diegui'); - game.log(result.links,'飞向了',player); + }, + }, + ao_kuihun: { + trigger: { global: "dying" }, + logTarget: "player", + line: "thunder", + filter(event, player) { + return player != event.player; + }, + content() { + "step 0"; + player.draw(); + "step 1"; + if (!trigger.player.countCards("h")) event.finish(); + else + player + .chooseButton(["选择一张牌作为「蝶」", trigger.player.getCards("h")]) + .set("ai", function (button) { + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, get.owner(button.link)) <= 0) + return 10 + val; + if (val <= 0) return 20; + if (button.link.name == "tao" || button.link.name == "jiu") return 0; + return 1 / val; + }); + "step 2"; + if (result.bool) { + player + .addToExpansion(result.links, trigger.player, "give") + .set("log", false) + .gaintag.add("ao_diegui"); + game.log(result.links, "飞向了", player); } }, - locked:false, - mod:{ - targetInRange(card,player){ - const cardSuit = get.suit(card,false); - const list = player.getExpansions('ao_diegui'); - for(let i = 0; i < list.length; i++){ - if(cardSuit==='unsure'||get.suit(list[i],false)===cardSuit) return true; + locked: false, + mod: { + targetInRange(card, player) { + const cardSuit = get.suit(card, false); + const list = player.getExpansions("ao_diegui"); + for (let i = 0; i < list.length; i++) { + if (cardSuit === "unsure" || get.suit(list[i], false) === cardSuit) return true; } }, - cardUsable(card,player){ - const cardSuit = get.suit(card,false); - const list = player.getExpansions('ao_diegui'); - for(let i = 0; i < list.length; i++){ - if(cardSuit==='unsure'||get.suit(list[i],false)===cardSuit) return Infinity; + cardUsable(card, player) { + const cardSuit = get.suit(card, false); + const list = player.getExpansions("ao_diegui"); + for (let i = 0; i < list.length; i++) { + if (cardSuit === "unsure" || get.suit(list[i], false) === cardSuit) + return Infinity; } }, - maxHandcard(player,num){ - return num+player.getExpansions('ao_diegui').length; + maxHandcard(player, num) { + return num + player.getExpansions("ao_diegui").length; }, }, }, - ao_shixin:{ - derivation:'ao_diegui', - trigger:{player:'phaseZhunbeiBegin'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'key', - unique:true, - filter(event,player){ - var list=player.getExpansions('ao_diegui'); - var list2=[]; - for(var i=0;i2; + return list2.length > 2; }, - content(){ - player.awakenSkill('ao_shixin'); - player.changeSkills(['ao_diegui'],['ao_kuihun']); + content() { + player.awakenSkill("ao_shixin"); + player.changeSkills(["ao_diegui"], ["ao_kuihun"]); player.gainMaxHp(); player.recover(); }, - }, - ao_diegui:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.getExpansions('ao_diegui').length>0; + ai: { + combo: "ao_kuihun" }, - chooseButton:{ - dialog(event,player){ - return ui.create.dialog('蝶归',player.getExpansions('ao_diegui'),'hidden'); + }, + ao_diegui: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.getExpansions("ao_diegui").length > 0; + }, + chooseButton: { + dialog(event, player) { + return ui.create.dialog("蝶归", player.getExpansions("ao_diegui"), "hidden"); }, - backup(links,player){ + backup(links, player) { return { - card:links, - filterCard(){return false}, - selectCard:-1, - filterTarget:true, - delay:false, - content:lib.skill.ao_diegui.contentx, - line:'thunder', - ai:{ - result:{ - target(player,target){ - if(target!=player&&target.hasSkillTag('nogain')) return 0; - var num=1; - if(target.isTurnedOver()) num+=2; - if(target.isLinked()) num+=0.5; + card: links, + filterCard() { + return false; + }, + selectCard: -1, + filterTarget: true, + delay: false, + content: lib.skill.ao_diegui.contentx, + line: "thunder", + ai: { + result: { + target(player, target) { + if (target != player && target.hasSkillTag("nogain")) return 0; + var num = 1; + if (target.isTurnedOver()) num += 2; + if (target.isLinked()) num += 0.5; return num; }, - } + }, }, - } + }; }, - prompt(links,player){ - return '选择一名角色,令其获得'+get.translation(links[0])+',摸两张牌并将武将牌复原。' + prompt(links, player) { + return ( + "选择一名角色,令其获得" + + get.translation(links[0]) + + ",摸两张牌并将武将牌复原。" + ); }, }, - contentx(){ - 'step 0' - player.give(lib.skill.ao_diegui_backup.card,target,'visible'); + contentx() { + "step 0"; + player.give(lib.skill.ao_diegui_backup.card, target, "visible"); target.draw(2); - 'step 1' + "step 1"; target.link(false); - 'step 2' + "step 2"; target.turnOver(false); }, - intro:{ - name:'七影蝶', - content:'expansion', - markcount:'expansion', + intro: { + name: "七影蝶", + content: "expansion", + markcount: "expansion", }, - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{order:1,result:{player:1}}, + ai: { order: 1, result: { player: 1 } }, }, - ayato_jianshen:{ - mod:{ - cardnature(card,player){ - if(get.name(card)=='sha') return 'kami'; + ayato_jianshen: { + mod: { + cardnature(card, player) { + if (get.name(card) == "sha") return "kami"; }, }, - ai:{threaten:3}, + ai: { threaten: 3 }, }, - ayato_zonghuan:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + ayato_zonghuan: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; }, - content(){ - 'step 0' - player.chooseButton(['请选择'+get.translation(target)+'的一张手牌',target.getCards('h')],true).set('ai',get.buttonValue); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - if(!lib.filter.cardEnabled(card,target)) event._result={bool:false}; - else{ - var targets=game.players.slice(0); - var info=get.info(card); + content() { + "step 0"; + player + .chooseButton( + ["请选择" + get.translation(target) + "的一张手牌", target.getCards("h")], + true + ) + .set("ai", get.buttonValue); + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + if (!lib.filter.cardEnabled(card, target)) event._result = { bool: false }; + else { + var targets = game.players.slice(0); + var info = get.info(card); var range; - if(!info.notarget){ - var select=get.copy(info.selectTarget); - if(select==undefined){ - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,target,range,'selectTarget',target); + if (!info.notarget) { + var select = get.copy(info.selectTarget); + if (select == undefined) { + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, target, range, "selectTarget", target); } - if(info.notarget||range[1]==-1){ - if(range[1]==-1){ - for(var i=0;i0; + return eff > 0; }; - } - else{ - var next=player.chooseTarget(); - next.set('_get_card',card); - next.set('source',target); - next.set('filterTarget',function(card,player,target){ - return lib.filter.filterTarget(_status.event._get_card,_status.event.source,target); + } else { + var next = player.chooseTarget(); + next.set("_get_card", card); + next.set("source", target); + next.set("filterTarget", function (card, player, target) { + return lib.filter.filterTarget( + _status.event._get_card, + _status.event.source, + target + ); }); - next.set('ai',function(target){ - var evt=_status.event; - return get.effect(target,evt._get_card,evt.source,evt.player) + next.set("ai", function (target) { + var evt = _status.event; + return get.effect(target, evt._get_card, evt.source, evt.player); }); - next.set('selectTarget',function(){ - var card=get.card(),player=_status.event.source; - if(card==undefined) return; + next.set("selectTarget", function () { + var card = get.card(), + player = _status.event.source; + if (card == undefined) return; var range; - var select=get.copy(get.info(card).selectTarget); - if(select==undefined){ - if(get.info(card).filterTarget==undefined) return[0,0]; - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); + var select = get.copy(get.info(card).selectTarget); + if (select == undefined) { + if (get.info(card).filterTarget == undefined) return [0, 0]; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); return range; }); - next.set('prompt',event.prompt||('选择'+get.translation(target)+'使用'+get.translation(card)+'的目标')); - next.set('prompt2','或点「取消」令其将此牌置入弃牌堆'); + next.set( + "prompt", + event.prompt || + "选择" + + get.translation(target) + + "使用" + + get.translation(card) + + "的目标" + ); + next.set("prompt2", "或点「取消」令其将此牌置入弃牌堆"); } } - } - else event.finish(); - 'step 2' - if(result.bool){ - target.useCard(card,event.targets2||result.targets,false,'noai'); + } else event.finish(); + "step 2"; + if (result.bool) { + target.useCard(card, event.targets2 || result.targets, false, "noai"); player.draw(); - } - else{ - target.lose(card,ui.discardPile); + } else { + target.lose(card, ui.discardPile); target.$throw(card); - game.log(target,'将',card,'置入了弃牌堆'); + game.log(target, "将", card, "置入了弃牌堆"); } }, - ai:{order:10,result:{target:-1}}, + ai: { order: 10, result: { target: -1 } }, }, - nagisa_tiandu:{ - trigger:{player:'judgeEnd'}, - charlotte:true, - frequent(event){ - if(event.result.card.name=='du') return false; + nagisa_tiandu: { + trigger: { player: "judgeEnd" }, + charlotte: true, + frequent(event) { + if (event.result.card.name == "du") return false; return true; }, - check(event){ - if(event.result.card.name=='du') return false; + check(event) { + if (event.result.card.name == "du") return false; return true; }, - filter(event,player){ - return get.position(event.result.card,true)=='o'; + filter(event, player) { + return get.position(event.result.card, true) == "o"; + }, + content() { + player.gain(trigger.result.card, "gain2"); }, - content(){ - player.gain(trigger.result.card,'gain2'); - } }, - nagisa_fuxin:{ - trigger:{ - global:['gainAfter','loseAfter','loseAsyncAfter','damageEnd'], + nagisa_fuxin: { + trigger: { + global: ["gainAfter", "loseAfter", "loseAsyncAfter", "damageEnd"], }, - filterx(event,player){ - var source=_status.currentPhase; - if(event.name=='damage'){ - return event.player.isAlive()&&event.player!=source; - } - else if(event.name=='lose'){ - if(event.type!='discard'||event.player==source||event.player.isDead()) return false; - if((event.discarder||event.getParent(2).player)==event.player) return false; - if(!event.getl(event.player).hs.length) return false; + filterx(event, player) { + var source = _status.currentPhase; + if (event.name == "damage") { + return event.player.isAlive() && event.player != source; + } else if (event.name == "lose") { + if (event.type != "discard" || event.player == source || event.player.isDead()) + return false; + if ((event.discarder || event.getParent(2).player) == event.player) return false; + if (!event.getl(event.player).hs.length) return false; return true; - } - else if(event.name=='gain'){ - if(event.giver||event.getParent().name=='gift') return false; - var cards=event.getg(event.player); - if(!cards.length) return false; - return game.hasPlayer(function(current){ - if(current==event.player||current==source) return false; - var hs=event.getl(current).hs; - for(var i of hs){ - if(cards.includes(i)) return true; + } else if (event.name == "gain") { + if (event.giver || event.getParent().name == "gift") return false; + var cards = event.getg(event.player); + if (!cards.length) return false; + return game.hasPlayer(function (current) { + if (current == event.player || current == source) return false; + var hs = event.getl(current).hs; + for (var i of hs) { + if (cards.includes(i)) return true; } return false; }); - } - else if(event.type=='gain'){ - if(event.giver||!event.player||event.player==source||event.player.isDead()) return false; - var hs=event.getl(event.player); - return game.hasPlayer(function(current){ - if(current==event.player) return false; - var cards=event.getg(current); - for(var i of cards){ - if(hs.includes(i)) return true; + } else if (event.type == "gain") { + if (event.giver || !event.player || event.player == source || event.player.isDead()) + return false; + var hs = event.getl(event.player); + return game.hasPlayer(function (current) { + if (current == event.player) return false; + var cards = event.getg(current); + for (var i of cards) { + if (hs.includes(i)) return true; } }); - } - else if(event.type=='discard'){ - if(!event.discarder) return false; - return game.hasPlayer(function(current){ - return current!=source&¤t!=event.discarder&&event.getl(current).hs.length>0; + } else if (event.type == "discard") { + if (!event.discarder) return false; + return game.hasPlayer(function (current) { + return ( + current != source && + current != event.discarder && + event.getl(current).hs.length > 0 + ); }); } return false; }, - filter(event, player, triggername, target){ + filter(event, player, triggername, target) { return target.isIn(); }, - getIndex(trigger, player, triggername){ + getIndex(trigger, player, triggername) { if (!lib.skill.nagisa_fuxin.filterx(trigger, player)) return false; - const targets = [], source = _status.currentPhase; - if (trigger.name=='gain') { + const targets = [], + source = _status.currentPhase; + if (trigger.name == "gain") { const cards = trigger.getg(trigger.player); - targets.addArray(game.filterPlayer(function(current){ - if (current === trigger.player || current === source) return false; - const hs = trigger.getl(current).hs; - for (const i of hs) { - if (cards.includes(i)) return true; - } - return false; - })); - } - else if (trigger.name == 'loseAsync' && trigger.type == 'discard') { - targets.addArray(game.filterPlayer(function(current){ - return current != trigger.discarder && current != source && trigger.getl(current).hs.length>0; - })); - } - else targets.push(trigger.player); + targets.addArray( + game.filterPlayer(function (current) { + if (current === trigger.player || current === source) return false; + const hs = trigger.getl(current).hs; + for (const i of hs) { + if (cards.includes(i)) return true; + } + return false; + }) + ); + } else if (trigger.name == "loseAsync" && trigger.type == "discard") { + targets.addArray( + game.filterPlayer(function (current) { + return ( + current != trigger.discarder && + current != source && + trigger.getl(current).hs.length > 0 + ); + }) + ); + } else targets.push(trigger.player); targets.sortBySeat(); return targets; }, - logTarget:(event, player, triggername, target)=>target, - check(event, player, triggername, target){ + logTarget: (event, player, triggername, target) => target, + check(event, player, triggername, target) { const source = _status.currentPhase; - if (source && source.isIn() && get.attitude(player,source) > 0) return false; - return get.attitude(player,target) > 0; + if (source && source.isIn() && get.attitude(player, source) > 0) return false; + return get.attitude(player, target) > 0; }, - async content(event, trigger, player){ + async content(event, trigger, player) { const target = event.indexedData; - const {result} = await target.judge(); - if (result.color === 'red' && target.isIn()) { + const { result } = await target.judge(); + if (result.color === "red" && target.isIn()) { await target.draw(); - } - else { + } else { const source = _status.currentPhase; - if (source && source.isIn() && source.countCards('h') > 0) { - source.chooseToDiscard('he',true); + if (source && source.isIn() && source.countCards("h") > 0) { + source.chooseToDiscard("he", true); } } }, - ai:{expose:0.2}, + ai: { expose: 0.2 }, }, - tomoya_shangxian:{ - trigger:{player:'phaseUseBegin'}, - mark:true, - locked:true, - intro:{ - content(s){ - return '计算与其他角色的距离时始终从'+(s?'逆':'顺')+'时针计算' + tomoya_shangxian: { + trigger: { player: "phaseUseBegin" }, + mark: true, + locked: true, + intro: { + content(s) { + return "计算与其他角色的距离时始终从" + (s ? "逆" : "顺") + "时针计算"; }, }, - content(){ + content() { player.draw(); - player.storage.tomoya_shangxian=!player.storage.tomoya_shangxian; + player.storage.tomoya_shangxian = !player.storage.tomoya_shangxian; }, - ai:{ - left_hand:true, - right_hand:true, - skillTagFilter(player,tag){ - return (player.storage.tomoya_shangxian==true)==(tag=='left_hand'); + ai: { + left_hand: true, + right_hand: true, + skillTagFilter(player, tag) { + return (player.storage.tomoya_shangxian == true) == (tag == "left_hand"); }, }, }, - tomoya_wangjin:{ - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - return player!=event.player&&!player.hasSkill('tomoya_wangjin_'+player.inRange(event.player)); + tomoya_wangjin: { + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player != event.player && + !player.hasSkill("tomoya_wangjin_" + player.inRange(event.player)) + ); }, - logTarget:'player', - check(event,player){ - var target=event.player; - var bool=player.inRange(target); - if(!bool){ - if(target.hp>player.hp) return get.effect(target,{name:'sha',isCard:true},player,player)>0; - var temp=target; - while(true){ - temp=temp.getNext(); - if(temp==target||temp==_status.roundStart) return true; - if(temp==player) continue; - if(temp.hp>player.hp&&!player.inRange(temp)&&get.effect(temp,{name:'sha',isCard:true},player,player)>0) return false; + logTarget: "player", + check(event, player) { + var target = event.player; + var bool = player.inRange(target); + if (!bool) { + if (target.hp > player.hp) + return get.effect(target, { name: "sha", isCard: true }, player, player) > 0; + var temp = target; + while (true) { + temp = temp.getNext(); + if (temp == target || temp == _status.roundStart) return true; + if (temp == player) continue; + if ( + temp.hp > player.hp && + !player.inRange(temp) && + get.effect(temp, { name: "sha", isCard: true }, player, player) > 0 + ) + return false; } } - if(get.attitude(player,target)<2) return false; - if(target.hp=2&&!temp.hasSkillTag('nogain')) return false; + if (get.attitude(player, target) < 2) return false; + if (target.hp < player.hp && !target.hasSkillTag("nogain")) return true; + var temp = target; + while (true) { + temp = temp.getNext(); + if (temp == target || temp == _status.roundStart) return true; + if (temp == player) continue; + if ( + temp.hp < player.hp && + player.inRange(temp) && + get.attitude(player, target) >= 2 && + !temp.hasSkillTag("nogain") + ) + return false; } }, - content(){ - 'step 0' - event.bool=player.inRange(trigger.player); - player.addTempSkill('tomoya_wangjin_'+event.bool,'roundStart'); - if(event.bool){ + content() { + "step 0"; + event.bool = player.inRange(trigger.player); + player.addTempSkill("tomoya_wangjin_" + event.bool, "roundStart"); + if (event.bool) { trigger.player.draw(); - } - else player.draw(2); - 'step 1' - if(event.bool){ - if(trigger.player.hp 0) + trigger.player.discardPlayerCard(player, "h", true); else event.finish(); } - else{ - if(player.countDiscardableCards(trigger.player,'h')>0) trigger.player.discardPlayerCard(player,'h',true); - else event.finish(); - } - 'step 2' - if(event.bool){ - player.chooseCard('h','是否交给'+get.translation(trigger.player)+'一张牌?'); - } - else{ + "step 2"; + if (event.bool) { + player.chooseCard("h", "是否交给" + get.translation(trigger.player) + "一张牌?"); + } else { event.finish(); - if(player.hp>=trigger.player.hp) return; - var card={name:'sha',isCard:true}; - if(player.canUse(card,trigger.player,false)) player.useCard(card,trigger.player,false); + if (player.hp >= trigger.player.hp) return; + var card = { name: "sha", isCard: true }; + if (player.canUse(card, trigger.player, false)) + player.useCard(card, trigger.player, false); } - 'step 3' - if(result.bool) player.give(result.cards,target); + "step 3"; + if (result.bool) player.give(result.cards, target); }, - subSkill:{true:{charlotte:true},false:{charlotte:true}}, - ai:{expose:0.2}, + subSkill: { + true: { charlotte: true }, + false: { charlotte: true }, + }, + ai: { expose: 0.2 }, }, - noda_fengcheng:{ - audio:2, - trigger:{ - player:"gainAfter", + noda_fengcheng: { + audio: 2, + trigger: { + player: "gainAfter", }, - forced:true, - filter(event,player){ - return get.itemtype(event.source)=='player'&&event.bySelf!=true; + forced: true, + filter(event, player) { + return get.itemtype(event.source) == "player" && event.bySelf != true; }, - check(event,player){ - return get.attitude(player,event.source)>0; + check(event, player) { + return get.attitude(player, event.source) > 0; }, - logTarget:"source", - content(){ + logTarget: "source", + content() { trigger.source.draw(); }, }, - noda_xunxin:{ - audio:2, - enable:'phaseUse', - viewAs:{name:'juedou'}, - filter(event,player){ - return (player.getStat('skill').noda_xunxin||0)0; + noda_xunxin2: { + trigger: { player: "juedouAfter" }, + popup: false, + forced: true, + filter(event, player) { + if (event.target.isDead()) return false; + return event.turn && event.turn.countCards("he") > 0; }, - content(){ - 'step 0' - event.giver=trigger.turn; - event.gainner=event.giver==player?trigger.target:player; - event.giver.chooseCard('he',true,'交给'+get.translation(event.gainner)+'一张牌'); - 'step 1' - event.giver.give(result.cards,event.gainner); + content() { + "step 0"; + event.giver = trigger.turn; + event.gainner = event.giver == player ? trigger.target : player; + event.giver.chooseCard("he", true, "交给" + get.translation(event.gainner) + "一张牌"); + "step 1"; + event.giver.give(result.cards, event.gainner); }, }, - hinata_qiulve:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - viewAsFilter(player){ - return player.countCards('hes',function(card){ - return get.type(card)!='basic'; - })>0; + hinata_qiulve: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + viewAsFilter(player) { + return ( + player.countCards("hes", function (card) { + return get.type(card) != "basic"; + }) > 0 + ); }, - viewAs:{name:'sha'}, - filterCard(card,player){ - return get.type(card)!='basic'; + viewAs: { name: "sha" }, + filterCard(card, player) { + return get.type(card) != "basic"; }, - locked:false, - position:'hes', - check(card){ - var val=get.value(card); - if(val>=6) return 0; - if(get.color(card)=='black') return 12-val; - return 6-val; + locked: false, + position: "hes", + check(card) { + var val = get.value(card); + if (val >= 6) return 0; + if (get.color(card) == "black") return 12 - val; + return 6 - val; }, - mod:{ - targetInRange(card,player,target){ - if(_status.event.skill=='hinata_qiulve') return true; + mod: { + targetInRange(card, player, target) { + if (_status.event.skill == "hinata_qiulve") return true; }, }, - group:'hinata_qiulve_clear', - ai:{ - respondSha:true, - skillTagFilter(player){ - return player.countCards('hes',function(card){ - return get.type(card)!='basic'; - })>0; + group: "hinata_qiulve_clear", + ai: { + respondSha: true, + skillTagFilter(player) { + return ( + player.countCards("hes", function (card) { + return get.type(card) != "basic"; + }) > 0 + ); }, }, }, - hinata_qiulve_clear:{ - trigger:{player:'useCard1'}, - firstDo:true, - silent:true, - filter(event,player){ - return event.skill=='hinata_qiulve'; + hinata_qiulve_clear: { + trigger: { player: "useCard1" }, + firstDo: true, + silent: true, + filter(event, player) { + return event.skill == "hinata_qiulve"; }, - content(){ - if(get.color(trigger.card)=='red') trigger.directHit.addArray(game.players); - else if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card; - if(stat.sha) stat.sha--; + content() { + if (get.color(trigger.card) == "red") trigger.directHit.addArray(game.players); + else if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card; + if (stat.sha) stat.sha--; } }, }, - hinata_ehou:{ - audio:2, - trigger:{global:'useCardAfter'}, + hinata_ehou: { + audio: 2, + trigger: { global: "useCardAfter" }, //这个也是chooseToUse 改不了 - direct:true, - filter(event,player){ - return player!=event.player&&event.targets&&event.targets.includes(player)&&(_status.connectMode||player.hasSha()); + direct: true, + filter(event, player) { + return ( + player != event.player && + event.targets && + event.targets.includes(player) && + (_status.connectMode || player.hasSha()) + ); }, - content(){ - 'step 0' + content() { + "step 0"; player.chooseToUse({ - logSkill:'hinata_ehou', - preTarget:trigger.player, - prompt:'是否发动【扼喉】,对'+get.translation(trigger.player)+'使用一张【杀】?', - filterCard(card,player){ - return get.name(card)=='sha'&&lib.filter.filterCard.apply(this,arguments); + logSkill: "hinata_ehou", + preTarget: trigger.player, + prompt: "是否发动【扼喉】,对" + get.translation(trigger.player) + "使用一张【杀】?", + filterCard(card, player) { + return get.name(card) == "sha" && lib.filter.filterCard.apply(this, arguments); }, - filterTarget(card,player,target){ - return target==_status.event.preTarget&&lib.filter.filterTarget.apply(this,arguments); + filterTarget(card, player, target) { + return ( + target == _status.event.preTarget && + lib.filter.filterTarget.apply(this, arguments) + ); }, - addCount:false, + addCount: false, }); - 'step 1' - if(result.bool&&player.getHistory('sourceDamage',function(evt){ - return evt.getParent(4)==event; - }).length) player.draw(); + "step 1"; + if ( + result.bool && + player.getHistory("sourceDamage", function (evt) { + return evt.getParent(4) == event; + }).length + ) + player.draw(); }, }, - hisako_yinbao:{ - audio:2, - trigger:{player:['damageEnd','recoverAfter']}, - content(){ - 'step 0' - player.judge(function(card){ - return get.suit(card)=='spade'?2:-2; - }).judge2=function(result){ + hisako_yinbao: { + audio: 2, + trigger: { player: ["damageEnd", "recoverAfter"] }, + content() { + "step 0"; + player.judge(function (card) { + return get.suit(card) == "spade" ? 2 : -2; + }).judge2 = function (result) { return result.bool; }; - 'step 1' - if(result.bool&&game.hasPlayer(current=>current!=player)){ - player.chooseTarget(lib.filter.notMe,true,'选择一名其他角色,对其造成1点雷属性伤害').set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player,'thunder'); - }); - } - else event.finish(); - 'step 2' - var target=result.targets[0]; + "step 1"; + if (result.bool && game.hasPlayer((current) => current != player)) { + player + .chooseTarget(lib.filter.notMe, true, "选择一名其他角色,对其造成1点雷属性伤害") + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player, "thunder"); + }); + } else event.finish(); + "step 2"; + var target = result.targets[0]; player.addExpose(0.2); - player.line(target,'thunder'); - target.damage('thunder'); + player.line(target, "thunder"); + target.damage("thunder"); }, }, - hisako_zhuanyun:{ - trigger:{player:'judgeBegin'}, - forced:true, - charlotte:true, - silent:true, - filter(event,player){ + hisako_zhuanyun: { + trigger: { player: "judgeBegin" }, + forced: true, + charlotte: true, + silent: true, + filter(event, player) { return !event.directresult; }, - content(){ - var tempcard=false,temp=-Infinity; - for(var i=0;itemp){ - tempcard=card; - temp=temp2; + content() { + var tempcard = false, + temp = -Infinity; + for (var i = 0; i < ui.cardPile.childElementCount; i++) { + var card = ui.cardPile.childNodes[i]; + var temp2 = trigger.judge(card); + if (temp2 > temp) { + tempcard = card; + temp = temp2; } } - if(tempcard) trigger.directresult=tempcard; + if (tempcard) trigger.directresult = tempcard; }, - ai:{luckyStar:true}, + ai: { luckyStar: true }, }, - riki_spwenji:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); + riki_spwenji: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he"); }); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('riki_spwenji'),function(card,player,target){ - return target!=player&&target.countCards('he'); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return Math.sqrt(att)/10; - return 5-att; - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("riki_spwenji"), function (card, player, target) { + return target != player && target.countCards("he"); + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return Math.sqrt(att) / 10; + return 5 - att; + }) + .forResult(); }, - content(){ - 'step 0' + content() { + "step 0"; target = targets[0]; event.target = target; - target.chooseCard('he', true, '问计:将一张牌交给'+get.translation(player)); - 'step 1' - if(result.bool){ - player.addTempSkill('riki_spwenji_respond'); - player.storage.riki_spwenji_respond=get.type2(result.cards[0],target); - event.target.give(result.cards,player,true); + target.chooseCard("he", true, "问计:将一张牌交给" + get.translation(player)); + "step 1"; + if (result.bool) { + player.addTempSkill("riki_spwenji_respond"); + player.storage.riki_spwenji_respond = get.type2(result.cards[0], target); + event.target.give(result.cards, player, true); } }, - ai:{expose:0.2}, - subSkill:{ - respond:{ - onremove:true, - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - audio:'riki_spwenji', - filter(event,player){ - return get.type2(event.card)==player.storage.riki_spwenji_respond; + ai: { expose: 0.2 }, + subSkill: { + respond: { + onremove: true, + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + audio: "riki_spwenji", + filter(event, player) { + return get.type2(event.card) == player.storage.riki_spwenji_respond; }, - content(){ + content() { trigger.directHit.addArray(game.players); }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return get.type2(arg.card)==player.storage.riki_spwenji_respond; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return get.type2(arg.card) == player.storage.riki_spwenji_respond; }, }, - } - } - }, - riki_nvzhuang:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content(){ - player.draw(player.countCards('h')==0?2:1); + }, }, }, - riki_mengzhong:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - derivation:'riki_chongzhen', - juexingji:true, - unique:true, - skillAnimation:true, - animationColor:'key', - filter(event,player){ - var num=0; - player.getAllHistory('gain',function(evt){ - if(evt.getParent().name=='riki_spwenji') num+=evt.cards.length; + riki_nvzhuang: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content() { + player.draw(player.countCards("h") == 0 ? 2 : 1); + }, + }, + riki_mengzhong: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + derivation: "riki_chongzhen", + juexingji: true, + unique: true, + skillAnimation: true, + animationColor: "key", + filter(event, player) { + var num = 0; + player.getAllHistory("gain", function (evt) { + if (evt.getParent().name == "riki_spwenji") num += evt.cards.length; }); - return num>=3; + return num >= 3; }, - content(){ - player.awakenSkill('riki_mengzhong'); - player.removeSkills('riki_spwenji'); + content() { + player.awakenSkill("riki_mengzhong"); + player.removeSkills("riki_spwenji"); player.gainMaxHp(); player.recover(); - player.addSkills('riki_chongzhen'); + player.addSkills("riki_chongzhen"); + }, + ai: { + combo: "riki_spwenji" }, }, - riki_chongzhen:{ - trigger:{ - player:"phaseUseBegin", + riki_chongzhen: { + trigger: { + player: "phaseUseBegin", }, - filter(event, player){ - return game.hasPlayer(current => player.canCompare(current)); + filter(event, player) { + return game.hasPlayer((current) => player.canCompare(current)); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('riki_chongzhen'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - return -get.attitude(player,target)*(1+target.countCards('e'))/(1+target.countCards('j')); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("riki_chongzhen"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + return ( + (-get.attitude(player, target) * (1 + target.countCards("e"))) / + (1 + target.countCards("j")) + ); + }) + .forResult(); }, - content(){ - 'step 0' + content() { + "step 0"; var target = targets[0]; event.target = target; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - var num=0; - if(target.countCards('h')) num++; - if(target.countCards('e')) num++; - if(target.countCards('j')) num++; - if(num){ - player.gainPlayerCard(target,num,'hej',true).set('filterButton',function(button){ - for(var i=0;i0&&game.hasPlayer(function(current){ - return player.canCompare(current); - }); + yuiko_fenglun: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return player.canCompare(current); + }) + ); }, - filterTarget(card,player,target){ + filterTarget(card, player, target) { return player.canCompare(target); }, - content(){ - 'step 0' + content() { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool) player.addTempSkill('yuiko_fenglun2','phaseUseEnd'); + "step 1"; + if (result.bool) player.addTempSkill("yuiko_fenglun2", "phaseUseEnd"); }, - ai:{ - order:10, - result:{target:-1}, + ai: { + order: 10, + result: { target: -1 }, }, }, - yuiko_fenglun2:{ - mod:{ - cardUsable(){return Infinity}, - targetInRange(){return true}, + yuiko_fenglun2: { + mod: { + cardUsable() { + return Infinity; + }, + targetInRange() { + return true; + }, }, }, - yuiko_dilve:{ - enable:"chooseCard", - check(){ + yuiko_dilve: { + enable: "chooseCard", + check() { return 20; }, - filter(event){ - return event.type=='compare'&&!event.directresult; + filter(event) { + return event.type == "compare" && !event.directresult; }, - onCompare(player){ + onCompare(player) { return game.cardsGotoOrdering(get.bottomCards()).cards; }, - group:'yuiko_dilve_gain', - subSkill:{ - gain:{ - trigger:{ - player:['chooseToCompareAfter','compareMultipleAfter'], - target:['chooseToCompareAfter','compareMultipleAfter'] + group: "yuiko_dilve_gain", + subSkill: { + gain: { + trigger: { + player: ["chooseToCompareAfter", "compareMultipleAfter"], + target: ["chooseToCompareAfter", "compareMultipleAfter"], }, - filter(event,player){ - if(event.preserve) return false; - return [event.card1,event.card2].filterInD('od').length>0; + filter(event, player) { + if (event.preserve) return false; + return [event.card1, event.card2].filterInD("od").length > 0; }, - prompt2(event,player){ - return '获得'+get.translation([event.card1,event.card2].filterInD('od')); + prompt2(event, player) { + return "获得" + get.translation([event.card1, event.card2].filterInD("od")); + }, + content() { + player.gain([trigger.card1, trigger.card2].filterInD("od"), "gain2", "log"); }, - content(){ - player.gain([trigger.card1,trigger.card2].filterInD('od'),'gain2','log'); - } }, }, }, - doruji_feiqu:{ - trigger:{ - player:'useCard', - target:'useCardToTargeted', + doruji_feiqu: { + trigger: { + player: "useCard", + target: "useCardToTargeted", }, - forced:true, - filter(event,player){ - return event.card.name=='sha'; + forced: true, + filter(event, player) { + return event.card.name == "sha"; }, - content(){ - if(trigger.name=='useCard') trigger.directHit.addArray(game.players); + content() { + if (trigger.name == "useCard") trigger.directHit.addArray(game.players); else trigger.directHit.add(player); }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return arg.card.name=='sha'; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return arg.card.name == "sha"; }, }, - global:'doruji_feiqu_ai', + global: "doruji_feiqu_ai", }, - doruji_feiqu_ai:{ - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return arg.card.name=='sha'&&(arg.target.hasSkill('doruji_feiqu')||arg.target.hasSkill('godan_feiqu')); + doruji_feiqu_ai: { + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return ( + arg.card.name == "sha" && + (arg.target.hasSkill("doruji_feiqu") || arg.target.hasSkill("godan_feiqu")) + ); }, }, }, - akane_jugu:{ - audio:2, - mod:{ - maxHandcard(player,num){ - return num+player.maxHp; - } + akane_jugu: { + audio: 2, + mod: { + maxHandcard(player, num) { + return num + player.maxHp; + }, }, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ + content() { player.draw(player.maxHp); - } + }, }, - akane_quanqing:{ - enable:'phaseUse', - filterCard:true, - filterTarget(card,player,target){ - return target!=player&&player.inRange(target); + akane_quanqing: { + enable: "phaseUse", + filterCard: true, + filterTarget(card, player, target) { + return target != player && player.inRange(target); }, - position:'he', - check(card){ - var val=get.value(card); - var num=card.number; - if(num>10) return 8-val; - var player=_status.event.player; - if(player.getUseValue(card,null,true)>player.getUseValue({name:'guohe'})) return 0; - if(num>6) return 6-val; - return 3-val; + position: "he", + check(card) { + var val = get.value(card); + var num = card.number; + if (num > 10) return 8 - val; + var player = _status.event.player; + if (player.getUseValue(card, null, true) > player.getUseValue({ name: "guohe" })) + return 0; + if (num > 6) return 6 - val; + return 3 - val; }, - content(){ - 'step 0' - var num=cards[0].number; - var trans=get.translation(target); - var list=['令'+trans+'摸一张牌']; - event.addIndex=0; - if(num>6){ - if(target.countDiscardableCards(player,'hej')>0) list.push('弃置'+trans+'区域内的一张牌'); + content() { + "step 0"; + var num = cards[0].number; + var trans = get.translation(target); + var list = ["令" + trans + "摸一张牌"]; + event.addIndex = 0; + if (num > 6) { + if (target.countDiscardableCards(player, "hej") > 0) + list.push("弃置" + trans + "区域内的一张牌"); else event.addIndex++; } - if(num>10) list.push('对'+trans+'造成1点伤害'); - if(list.length==1) event._result={index:0}; - else player.chooseControl().set('choiceList',list).set('index',list.length-1).set('ai',function(){return _status.event.index}); - 'step 1' - if(result.index>0) result.index+=event.addIndex; - switch(result.index){ - case 0:target.draw();break; - case 1:player.discardPlayerCard(target,'hej',true);break; - case 2:target.damage('nocard');break; + if (num > 10) list.push("对" + trans + "造成1点伤害"); + if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl() + .set("choiceList", list) + .set("index", list.length - 1) + .set("ai", function () { + return _status.event.index; + }); + "step 1"; + if (result.index > 0) result.index += event.addIndex; + switch (result.index) { + case 0: + target.draw(); + break; + case 1: + player.discardPlayerCard(target, "hej", true); + break; + case 2: + target.damage("nocard"); + break; } }, - ai:{ - order:4, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(card){ - if(card.number>10) return get.damageEffect(target,player,target); - if(card.number>6) return lib.card.guohe.ai.result.target.apply(this,arguments); + ai: { + order: 4, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (card) { + if (card.number > 10) return get.damageEffect(target, player, target); + if (card.number > 6) + return lib.card.guohe.ai.result.target.apply(this, arguments); return 1; } }, }, }, }, - akane_yifu:{ - unique:true, - global:'akane_yifu2', - zhuSkill:true, + akane_yifu: { + unique: true, + global: "akane_yifu2", + zhuSkill: true, }, - akane_yifu2:{ - audio:2, - enable:'phaseUse', - discard:false, - line:true, - log:false, - delay:false, - lose:false, - prepare(cards,player,targets){ - targets[0].logSkill('akane_yifu'); + akane_yifu2: { + audio: 2, + enable: "phaseUse", + discard: false, + line: true, + log: false, + delay: false, + lose: false, + prepare(cards, player, targets) { + targets[0].logSkill("akane_yifu"); }, - prompt(){ - var player=_status.event.player; - var list=game.filterPlayer(function(target){ - return target!=player&&target.hasZhuSkill('akane_yifu',player); + prompt() { + var player = _status.event.player; + var list = game.filterPlayer(function (target) { + return target != player && target.hasZhuSkill("akane_yifu", player); }); - var str='将一张手牌交给'+get.translation(list); - if(list.length>1) str+='中的一人'; + var str = "将一张手牌交给" + get.translation(list); + if (list.length > 1) str += "中的一人"; return str; }, - filter(event,player){ - if(player.group!='key') return false; - if(player.countCards('h')==0) return 0; - return game.hasPlayer(function(target){ - return target!=player&&target.hasZhuSkill('akane_yifu',player)&&!target.hasSkill('akane_yifu3'); + filter(event, player) { + if (player.group != "key") return false; + if (player.countCards("h") == 0) return 0; + return game.hasPlayer(function (target) { + return ( + target != player && + target.hasZhuSkill("akane_yifu", player) && + !target.hasSkill("akane_yifu3") + ); }); }, - filterCard:true, - filterTarget(card,player,target){ - return target!=player&&target.hasZhuSkill('akane_yifu',player)&&!target.hasSkill('akane_yifu3'); + filterCard: true, + filterTarget(card, player, target) { + return ( + target != player && + target.hasZhuSkill("akane_yifu", player) && + !target.hasSkill("akane_yifu3") + ); }, - content(){ - 'step 0' - player.give(cards,target); - target.addTempSkill('akane_yifu3','phaseUseEnd'); + content() { + "step 0"; + player.give(cards, target); + target.addTempSkill("akane_yifu3", "phaseUseEnd"); target.draw(); - 'step 1' - if(target.countCards('h')>0) target.chooseCard('h',true,'交给'+get.translation(player)+'一张牌').set('ai',function(card){ - return 14-get.value(card); - }); + "step 1"; + if (target.countCards("h") > 0) + target + .chooseCard("h", true, "交给" + get.translation(player) + "一张牌") + .set("ai", function (card) { + return 14 - get.value(card); + }); else event.finish(); - 'step 2' - target.give(result.cards,player); + "step 2"; + target.give(result.cards, player); + }, + ai: { + expose: 0.3, + order: 10, + result: { + target: 5, + }, }, - ai:{ - expose:0.3, - order:10, - result:{ - target:5 - } - } }, - akane_yifu3:{charlotte:true}, - sasami_miaobian:{ - derivation:['sasami_gongqing','sasami_funan','sasami_baoqiu'], - init2(player){ - if(player.hp<=3) player.addSkill('sasami_gongqing'); - if(player.hp<=2) player.addSkill('sasami_funan'); - if(player.hp<=1) player.addSkill('sasami_baoqiu'); + akane_yifu3: { charlotte: true }, + sasami_miaobian: { + derivation: ["sasami_gongqing", "sasami_funan", "sasami_baoqiu"], + init2(player) { + if (player.hp <= 3) player.addSkill("sasami_gongqing"); + if (player.hp <= 2) player.addSkill("sasami_funan"); + if (player.hp <= 1) player.addSkill("sasami_baoqiu"); }, - trigger:{player:'changeHp'}, - firstDo:true, - silent:true, - content(){ + trigger: { player: "changeHp" }, + firstDo: true, + silent: true, + content() { lib.skill.sasami_miaobian.init2(player); }, }, - sasami_baoqiu:{ - line:{color:[173,149,206]}, - inherit:'rin_baoqiu' + sasami_baoqiu: { + line: { color: [173, 149, 206] }, + inherit: "rin_baoqiu", }, - "sasami_gongqing":{ - audio:true, - trigger:{ - player:["damageBegin3","damageBegin4"], + sasami_gongqing: { + audio: true, + trigger: { + player: ["damageBegin3", "damageBegin4"], }, - forced:true, - filter (event,player,name){ - if(!event.source) return false; - var range=event.source.getAttackRange(); - if(name=='damageBegin3') return range>3; - return event.num>1&&range<3; + forced: true, + filter(event, player, name) { + if (!event.source) return false; + var range = event.source.getAttackRange(); + if (name == "damageBegin3") return range > 3; + return event.num > 1 && range < 3; }, - content (){ - trigger.num=event.triggername=='damageBegin4'?1:trigger.num+1; + content() { + trigger.num = event.triggername == "damageBegin4" ? 1 : trigger.num + 1; }, - ai:{ - filterDamage:true, - skillTagFilter(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; - if(arg.player.getAttackRange()<3) return true; + ai: { + filterDamage: true, + skillTagFilter(player, tag, arg) { + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; + if (arg.player.getAttackRange() < 3) return true; } return false; - } - }, - }, - sasami_funan:{ - audio:2, - trigger:{global:['respond','useCard']}, - line:{color:[173,149,206]}, - filter(event,player){ - if(!event.respondTo) return false; - if(event.player==player) return false; - if(player!=event.respondTo[0]) return false; - if(!player.hasSkill('sasami_funan_jiexun')){ - var cards=[] - if(get.itemtype(event.respondTo[1])=='card') cards.push(event.respondTo[1]); - else if(event.respondTo[1].cards) cards.addArray(event.respondTo[1].cards); - return cards.filterInD('od').length>0; - } - else return event.cards.filterInD('od').length>0; - }, - logTarget:'player', - content(){ - 'step 0' - if(!player.hasSkill('sasami_funan_jiexun')){ - var cards=[] - if(get.itemtype(trigger.respondTo[1])=='card') cards.push(trigger.respondTo[1]); - else if(trigger.respondTo[1].cards) cards.addArray(trigger.respondTo[1].cards); - cards=cards.filterInD('od'); - trigger.player.gain(cards,'gain2','log').gaintag.add('sasami_funan'); - trigger.player.addTempSkill('sasami_funan_use'); - } - 'step 1' - var cards=trigger.cards.filterInD('od'); - player.gain(cards,'log','gain2'); - }, - subSkill:{ - use:{ - onremove(player){ - player.removeGaintag('sasami_funan'); - }, - charlotte:true, - mod:{ - cardEnabled2(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('sasami_funan')){ - return false; - } - } - } - } - } - }, - rin_baoqiu:{ - mod:{ - attackRange(rin,ball){ - return ball+2; }, }, - trigger:{player:'useCardToPlayered'}, - forced:true, - logTarget:'target', - filter(event,player){ - return event.card.name=='sha'; + }, + sasami_funan: { + audio: 2, + trigger: { global: ["respond", "useCard"] }, + line: { color: [173, 149, 206] }, + filter(event, player) { + if (!event.respondTo) return false; + if (event.player == player) return false; + if (player != event.respondTo[0]) return false; + if (!player.hasSkill("sasami_funan_jiexun")) { + var cards = []; + if (get.itemtype(event.respondTo[1]) == "card") cards.push(event.respondTo[1]); + else if (event.respondTo[1].cards) cards.addArray(event.respondTo[1].cards); + return cards.filterInD("od").length > 0; + } else return event.cards.filterInD("od").length > 0; }, - line:{color:[194,117,92]}, - content(){ - 'step 0' - player.judge(function(){return 0}); - 'step 1' - var target=trigger.target; - var map=trigger.customArgs; - var id=target.playerid; - if(!map[id]) map[id]={}; - if(result.color=='red'){ - if(!map[id].extraDamage) map[id].extraDamage=0; + logTarget: "player", + content() { + "step 0"; + if (!player.hasSkill("sasami_funan_jiexun")) { + var cards = []; + if (get.itemtype(trigger.respondTo[1]) == "card") cards.push(trigger.respondTo[1]); + else if (trigger.respondTo[1].cards) cards.addArray(trigger.respondTo[1].cards); + cards = cards.filterInD("od"); + trigger.player.gain(cards, "gain2", "log").gaintag.add("sasami_funan"); + trigger.player.addTempSkill("sasami_funan_use"); + } + "step 1"; + var cards = trigger.cards.filterInD("od"); + player.gain(cards, "log", "gain2"); + }, + subSkill: { + use: { + onremove(player) { + player.removeGaintag("sasami_funan"); + }, + charlotte: true, + mod: { + cardEnabled2(card, player) { + if (get.itemtype(card) == "card" && card.hasGaintag("sasami_funan")) { + return false; + } + }, + }, + }, + }, + }, + rin_baoqiu: { + mod: { + attackRange(rin, ball) { + return ball + 2; + }, + }, + trigger: { player: "useCardToPlayered" }, + forced: true, + logTarget: "target", + filter(event, player) { + return event.card.name == "sha"; + }, + line: { color: [194, 117, 92] }, + content() { + "step 0"; + player.judge(function () { + return 0; + }); + "step 1"; + var target = trigger.target; + var map = trigger.customArgs; + var id = target.playerid; + if (!map[id]) map[id] = {}; + if (result.color == "red") { + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; } - if(result.color=='black'){ + if (result.color == "black") { trigger.directHit.add(target); } - if(result.suit=='spade'||result.suit=='heart'){ - var evt=trigger.getParent(); - if(evt.addCount!==false){ - evt.addCount=false; + if (result.suit == "spade" || result.suit == "heart") { + var evt = trigger.getParent(); + if (evt.addCount !== false) { + evt.addCount = false; player.getStat().card.sha--; } player.draw(); } - if(result.suit=='diamond'||result.suit=='club'){ - target.addTempSkill('fengyin'); - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true); + if (result.suit == "diamond" || result.suit == "club") { + target.addTempSkill("fengyin"); + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true); } }, }, - sunohara_chengshuang:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + sunohara_chengshuang: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - group:'sunohara_chengshuang_phase', - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + group: "sunohara_chengshuang_phase", + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - 'step 0' - var evt=event.getParent('phase'); - if(evt&&evt.player==player) evt.sunohara_chengshuang=true; - player.chooseControl('male','female').set('prompt','成双:请选择自己的性别'); - 'step 1' - var sex=result.control; - game.broadcastAll(function(player,sex){ - player.sex=sex; - if(player.marks&&player.marks.sunohara_chengshuang) player.marks.sunohara_chengshuang.firstChild.innerHTML=sex=='male'?'♂':'♀'; - },player,sex); - game.log(player,'将性别变更为','#g'+get.translation(sex)+'性'); + content() { + "step 0"; + var evt = event.getParent("phase"); + if (evt && evt.player == player) evt.sunohara_chengshuang = true; + player.chooseControl("male", "female").set("prompt", "成双:请选择自己的性别"); + "step 1"; + var sex = result.control; + game.broadcastAll( + function (player, sex) { + player.sex = sex; + if (player.marks && player.marks.sunohara_chengshuang) + player.marks.sunohara_chengshuang.firstChild.innerHTML = + sex == "male" ? "♂" : "♀"; + }, + player, + sex + ); + game.log(player, "将性别变更为", "#g" + get.translation(sex) + "性"); }, - mark:true, - intro:{ - content(storage,player){ - if(player.sex=='unknown'||player.sex=='double') return '当前性别未确定'; - return '当前性别:'+get.translation(player.sex); + mark: true, + intro: { + content(storage, player) { + if (player.sex == "unknown" || player.sex == "double") return "当前性别未确定"; + return "当前性别:" + get.translation(player.sex); }, }, }, - sunohara_chengshuang_phase:{ - trigger:{ - player:'phaseBegin', + sunohara_chengshuang_phase: { + trigger: { + player: "phaseBegin", }, - filter(event,player){ - if(event.sunohara_chengshuang) return false; - return game.phaseNumber>1; + filter(event, player) { + if (event.sunohara_chengshuang) return false; + return game.phaseNumber > 1; }, - prompt2(event,player){ - if(player.sex=='unknown'||player.sex=='double') return '选择自己的性别'; - return '将自己的性别变更为'+(player.sex=='male'?'女性':'男性'); + prompt2(event, player) { + if (player.sex == "unknown" || player.sex == "double") return "选择自己的性别"; + return "将自己的性别变更为" + (player.sex == "male" ? "女性" : "男性"); }, - content(){ - 'step 0' - if(player.sex=='unknown'||player.sex=='double') player.chooseControl('male','female').set('prompt','成双:请选择自己的性别'); - else event._result={control:player.sex=='male'?'female':'male'}; - 'step 1' - var sex=result.control; - game.broadcastAll(function(player,sex){ - player.sex=sex; - if(player.marks&&player.marks.sunohara_chengshuang) player.marks.sunohara_chengshuang.firstChild.innerHTML=sex=='male'?'♂':'♀'; - },player,sex); - game.log(player,'将性别变更为','#g'+get.translation(sex)+'性'); + content() { + "step 0"; + if (player.sex == "unknown" || player.sex == "double") + player.chooseControl("male", "female").set("prompt", "成双:请选择自己的性别"); + else + event._result = { + control: player.sex == "male" ? "female" : "male", + }; + "step 1"; + var sex = result.control; + game.broadcastAll( + function (player, sex) { + player.sex = sex; + if (player.marks && player.marks.sunohara_chengshuang) + player.marks.sunohara_chengshuang.firstChild.innerHTML = + sex == "male" ? "♂" : "♀"; + }, + player, + sex + ); + game.log(player, "将性别变更为", "#g" + get.translation(sex) + "性"); }, }, - sunohara_tiaoyin:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countGainableCards(player,'hej')>0; + sunohara_tiaoyin: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countGainableCards(player, "hej") > 0; }, - selectCard:[1,4], - filterCard(card){ - for(var i=0;i0) player.gainPlayerCard(target,'hej','visible'); + line: { color: [239, 204, 96] }, + content() { + if (target.countGainableCards(player, "hej") > 0) + player.gainPlayerCard(target, "hej", "visible"); }, - contentAfter(){ - var bool=false; - for(var i=0;i0)?1:-2; + return get.attitude(player, target) < 0 && target.countCards("h", "tao") > 0 + ? 1 + : -2; }, - } + }, }, }, - sunohara_jianren:{ - trigger:{player:'damageEnd'}, - line: {color:[145,149,179]}, - async cost(event, trigger, player){ - const num=(!trigger.source||trigger.source.isDead()||trigger.source.differentSexFrom(player))?3:1; - event.result = await player.chooseTarget(get.prompt('sunohara_jianren'),'令一名角色摸'+get.cnNumber(num)+'张牌。').set('ai',function(target){ - var att=get.attitude(player,target); - if(att<=0) return 0; - if(target.hasSkillTag('nogain')&&target!=_status.currentPhase) return 0.1; - return att/(1+0.1*target.countCards('h')); - }).forResult(); + sunohara_jianren: { + trigger: { player: "damageEnd" }, + line: { color: [145, 149, 179] }, + async cost(event, trigger, player) { + const num = + !trigger.source || trigger.source.isDead() || trigger.source.differentSexFrom(player) + ? 3 + : 1; + event.result = await player + .chooseTarget( + get.prompt("sunohara_jianren"), + "令一名角色摸" + get.cnNumber(num) + "张牌。" + ) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (target.hasSkillTag("nogain") && target != _status.currentPhase) return 0.1; + return att / (1 + 0.1 * target.countCards("h")); + }) + .forResult(); }, - async content(event, trigger, player){ - const target =event.targets[0]; - const num = (!trigger.source || trigger.source.isDead() || trigger.source.differentSexFrom(player)) ? 3 : 1; + async content(event, trigger, player) { + const target = event.targets[0]; + const num = + !trigger.source || trigger.source.isDead() || trigger.source.differentSexFrom(player) + ? 3 + : 1; target.draw(num); }, }, - shiina_qingshen:{ - audio:1, - trigger:{ - player:'damageEnd', - source:'damageSource', + shiina_qingshen: { + audio: 1, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter(event,player){ - return event.cards&&event.cards.filterInD().length>0; + filter(event, player) { + return event.cards && event.cards.filterInD().length > 0; }, - frequent:true, - content(){ - 'step 0' - var cards=trigger.cards.filterInD('od'); - player.gain(cards,'gain2','log'); - event.count=cards.length; - 'step 1' - var cards=player.getCards('he'); - if(cards.length==0){ + frequent: true, + content() { + "step 0"; + var cards = trigger.cards.filterInD("od"); + player.gain(cards, "gain2", "log"); + event.count = cards.length; + "step 1"; + var cards = player.getCards("he"); + if (cards.length == 0) { event.finish(); return; - } - else if(cards.length<=event.count){ - event._result={bool:true,cards:cards}; - } - else player.chooseCard(true,'he',event.count,'请选择要置于武将牌上的牌'); - 'step 2' - if(result.bool&&result.cards.length){ - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('shiina_qingshen'); + } else if (cards.length <= event.count) { + event._result = { bool: true, cards: cards }; + } else player.chooseCard(true, "he", event.count, "请选择要置于武将牌上的牌"); + "step 2"; + if (result.bool && result.cards.length) { + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("shiina_qingshen"); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - mod:{ - attackRange(from,num){ - return num+from.getExpansions('shiina_qingshen').length; + mod: { + attackRange(from, num) { + return num + from.getExpansions("shiina_qingshen").length; }, - maxHandcard(from,num){ - return num+from.getExpansions('shiina_qingshen').length; + maxHandcard(from, num) { + return num + from.getExpansions("shiina_qingshen").length; }, }, - ai:{ - notemp:true, + ai: { + notemp: true, }, }, - shiina_feiyan:{ - audio:1, - animalList:['key_inari','key_doruji'], - trigger:{global:'phaseBegin'}, - filter(event,player){ - if(lib.skill.shiina_feiyan.animalList.includes(event.player.name)) return false; - return player.getExpansions('shiina_qingshen').length>0&&player.inRange(event.player); + shiina_feiyan: { + audio: 1, + animalList: ["key_inari", "key_doruji"], + trigger: { global: "phaseBegin" }, + filter(event, player) { + if (lib.skill.shiina_feiyan.animalList.includes(event.player.name)) return false; + return player.getExpansions("shiina_qingshen").length > 0 && player.inRange(event.player); }, - async cost(event, trigger, player){ - const {result} = await player.chooseButton([get.prompt('shiina_feiyan',trigger.player),player.getExpansions('shiina_qingshen')]).set('goon',get.attitude(player,trigger.player)<0?1:-1).set('ai',function(){return _status.event.goon}); - if (result.bool) event.result = { - bool: true, - cards: result.links, - } + async cost(event, trigger, player) { + const { result } = await player + .chooseButton([ + get.prompt("shiina_feiyan", trigger.player), + player.getExpansions("shiina_qingshen"), + ]) + .set("goon", get.attitude(player, trigger.player) < 0 ? 1 : -1) + .set("ai", function () { + return _status.event.goon; + }); + if (result.bool) + event.result = { + bool: true, + cards: result.links, + }; }, - logTarget: 'player', - async content(event, trigger, player){ + logTarget: "player", + async content(event, trigger, player) { await player.loseToDiscardpile(event.cards); - const cardToUse = {name:'sha', isCard:true}; - if(lib.filter.targetEnabled(cardToUse, player, trigger.player)){ - const {card} = await player.useCard(cardToUse, trigger.player); + const cardToUse = { name: "sha", isCard: true }; + if (lib.filter.targetEnabled(cardToUse, player, trigger.player)) { + const { card } = await player.useCard(cardToUse, trigger.player); console.log(card); - if(!player.hasHistory('sourceDamage', function(evt){ - return evt.card === card; - })) await player.draw(); + if ( + !player.hasHistory("sourceDamage", function (evt) { + return evt.card === card; + }) + ) + await player.draw(); } }, - group:'shiina_retieji', - ai:{ - notemp:true, - combo:'shiina_feiyan' + group: "shiina_retieji", + ai: { + notemp: true, + combo: "shiina_feiyan", }, }, - shiina_retieji:{ - audio:1, - shaRelated:true, - trigger:{player:'useCardToPlayered'}, - check(event,player){ - return get.attitude(player,event.target)<0; + shiina_retieji: { + audio: 1, + shaRelated: true, + trigger: { player: "useCardToPlayered" }, + check(event, player) { + return get.attitude(player, event.target) < 0; }, - filter(event,player){ - return event.card.name=='sha' && event.getParent(2).name == 'shiina_feiyan'; + filter(event, player) { + return event.card.name == "sha" && event.getParent(2).name == "shiina_feiyan"; }, - logTarget:'target', - content(){ - "step 0" - player.judge(function(){return 0}); - if(!trigger.target.hasSkill('fengyin')){ - trigger.target.addTempSkill('fengyin'); + logTarget: "target", + content() { + "step 0"; + player.judge(function () { + return 0; + }); + if (!trigger.target.hasSkill("fengyin")) { + trigger.target.addTempSkill("fengyin"); } - "step 1" - var suit=get.suit(result.card); - var target=trigger.target; - var num=target.countCards('h','shan'); - target.chooseToDiscard('请弃置一张'+get.translation(suit)+'牌,否则不能使用闪抵消此杀','he',function(card){ - return get.suit(card)==_status.event.suit; - }).set('ai',function(card){ - var num=_status.event.num; - if(num==0) return 0; - if(card.name=='shan') return num>1?2:0; - return 8-get.value(card); - }).set('num',num).set('suit',suit); - "step 2" - if(!result.bool){ + "step 1"; + var suit = get.suit(result.card); + var target = trigger.target; + var num = target.countCards("h", "shan"); + target + .chooseToDiscard( + "请弃置一张" + get.translation(suit) + "牌,否则不能使用闪抵消此杀", + "he", + function (card) { + return get.suit(card) == _status.event.suit; + } + ) + .set("ai", function (card) { + var num = _status.event.num; + if (num == 0) return 0; + if (card.name == "shan") return num > 1 ? 2 : 0; + return 8 - get.value(card); + }) + .set("num", num) + .set("suit", suit); + "step 2"; + if (!result.bool) { trigger.getParent().directHit.add(trigger.target); } - } - }, - inari_baiwei:{ - enable:['chooseToUse','chooseToRespond'], - hiddenCard(player,name){ - return name!='du'&&get.type(name)=='basic'&&player.countCards('hes',{suit:'diamond'})>0; }, - filter(event,player){ - if(event.type=='wuxie'||!player.countCards('hse',{suit:'diamond'})) return false; - for(var i=0;i 0 + ); + }, + filter(event, player) { + if (event.type == "wuxie" || !player.countCards("hse", { suit: "diamond" })) return false; + for (var i = 0; i < lib.inpile.length; i++) { + var name = lib.inpile[i]; + if ( + name != "du" && + get.type(name) == "basic" && + event.filterCard(get.autoViewAs({ name: name }, "unsure"), player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog(event,player){ - var list=[]; - for(var i=0;i0) return get.order(fakecard); + check(button) { + if (_status.event.getParent().type == "phase") { + var player = _status.event.player; + var fakecard = { + name: button.link[2], + nature: button.link[3], + }; + if (player.getUseValue(fakecard) > 0) return get.order(fakecard); return 0; } return 1; }, - backup(links,player){ + backup(links, player) { return { - selectCard:1, - filterCard:{suit:'diamond'}, - popname:true, - check(card){ - if(get.type(card)=='basic') return 6; - return 1/Math.max(0.1,get.value(card)); + selectCard: 1, + filterCard: { suit: "diamond" }, + popname: true, + check(card) { + if (get.type(card) == "basic") return 6; + return 1 / Math.max(0.1, get.value(card)); }, - position:'hse', - viewAs:{name:links[0][2],nature:links[0][3]}, - } + position: "hse", + viewAs: { name: links[0][2], nature: links[0][3] }, + }; + }, + prompt(links, player) { + return ( + "将一张♦牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用或打出" + ); }, - prompt(links,player){ - return '将一张♦牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用或打出'; - } }, - ai:{ - order(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0 - for(var i=0;i0){ - var temp=get.order({name:name}); - if(temp>max) max=temp; + ai: { + order(item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + for (var i = 0; i < lib.inpile.length; i++) { + var name = lib.inpile[i]; + if (get.type(name) == "basic" && player.getUseValue({ name: name }) > 0) { + var temp = get.order({ name: name }); + if (temp > max) max = temp; } } - if(max>0) max+=0.5; + if (max > 0) max += 0.5; return max; } return 4; }, - result:{ - player:1, + result: { + player: 1, }, - respondSha:true, - fireAttack:true, - skillTagFilter(player,tag){ - return tag=='fireAttack'||player.countCards('he',{suit:'diamond'})>0; + respondSha: true, + fireAttack: true, + skillTagFilter(player, tag) { + return tag == "fireAttack" || player.countCards("he", { suit: "diamond" }) > 0; }, }, - group:['inari_baiwei_draw'], + group: ["inari_baiwei_draw"], }, - inari_baiwei_draw:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - popup:false, - filter(event,player){ - return event.skill&&event.skill.indexOf('inari_baiwei')==0; + inari_baiwei_draw: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + popup: false, + filter(event, player) { + return event.skill && event.skill.indexOf("inari_baiwei") == 0; + }, + content() { + player.draw(); }, - content(){player.draw()}, }, - inari_huhun:{ - mod:{ - suit(card,suit){ - if(suit=='club') return 'diamond'; + inari_huhun: { + mod: { + suit(card, suit) { + if (suit == "club") return "diamond"; }, - maxHandcard(player,num){ - return num+1; + maxHandcard(player, num) { + return num + 1; }, - } + }, }, - saya_powei:{ - audio:2, - trigger:{player:'phaseAfter'}, - locked:true, - limited:true, - unique:true, - skillAnimation:true, - animationColor:'metal', - filter(event,player){ - return event.type!='saya_powei'&&game.hasPlayer(function(current){ - return current.hp>player.hp; - }); + saya_powei: { + audio: 2, + trigger: { player: "phaseAfter" }, + locked: true, + limited: true, + unique: true, + skillAnimation: true, + animationColor: "metal", + filter(event, player) { + return ( + event.type != "saya_powei" && + game.hasPlayer(function (current) { + return current.hp > player.hp; + }) + ); }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('saya_powei'),function(card,saya,kyousuke){ - return kyousuke.hp>saya.hp; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>=-2) return 0; - if(target!=get.zhu(target)&&player.hasUnknown()) return 0; - if(target.getEquip(3)&&!player.getEquip(4)) att/=2; - if(player.hp<=1) att*=1.5; - return -att; - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("saya_powei"), function (card, saya, kyousuke) { + return kyousuke.hp > saya.hp; + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att >= -2) return 0; + if (target != get.zhu(target) && player.hasUnknown()) return 0; + if (target.getEquip(3) && !player.getEquip(4)) att /= 2; + if (player.hp <= 1) att *= 1.5; + return -att; + }) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const target = event.targets[0]; - player.awakenSkill('saya_powei'); + player.awakenSkill("saya_powei"); game.asyncDelay(3); - var next = game.createEvent('saya_powei_loop',false,trigger); + var next = game.createEvent("saya_powei_loop", false, trigger); next.playertrue = player; next.playerfalse = target; next.setContent(lib.skill.saya_powei.content2); }, - content2(){ - 'step 0' - event.count=0; - event.stat=true; - event.current=event['player'+event.stat]; - game.countPlayer2(function(current){ - if(current!=event.playertrue&¤t!=event.playerfalse) current.addSkill('saya_nodis'); + content2() { + "step 0"; + event.count = 0; + event.stat = true; + event.current = event["player" + event.stat]; + game.countPlayer2(function (current) { + if (current != event.playertrue && current != event.playerfalse) + current.addSkill("saya_nodis"); }); - event.playertrue.addSkill('saya_judge'); - 'step 1' + event.playertrue.addSkill("saya_judge"); + "step 1"; event.count++; - event.current.phase().set('type','saya_powei'); - 'step 2' - if(event.count==9||event.playertrue.isDead()||event.playerfalse.isDead()){ - game.countPlayer2(function(current){ - current.removeSkill('saya_nodis'); - current.removeSkill('saya_judge'); + event.current.phase().set("type", "saya_powei"); + "step 2"; + if (event.count == 9 || event.playertrue.isDead() || event.playerfalse.isDead()) { + game.countPlayer2(function (current) { + current.removeSkill("saya_nodis"); + current.removeSkill("saya_judge"); }); - } - else{ - event.stat=!event.stat; - event.current=event['player'+event.stat]; + } else { + event.stat = !event.stat; + event.current = event["player" + event.stat]; event.goto(1); } - } - }, - saya_nodis:{ - group:'undist', - mark:true, - intro:{content:'不计入距离和座次的计算'}, - }, - saya_judge:{ - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - filter(event,player){ - return event.type=='saya_powei'&&player==event.getParent().playertrue; }, - content(){ - 'step 0' - player.judge(function(card){ - return get.color(card)=='red'?5:0; - }).judge2=function(result){ - return result.bool?true:false; + }, + saya_nodis: { + group: "undist", + mark: true, + intro: { content: "不计入距离和座次的计算" }, + }, + saya_judge: { + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + filter(event, player) { + return event.type == "saya_powei" && player == event.getParent().playertrue; + }, + content() { + "step 0"; + player.judge(function (card) { + return get.color(card) == "red" ? 5 : 0; + }).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { player.line(trigger.getParent().playerfalse); trigger.getParent().playerfalse.damage(); } }, }, - saya_shouji:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - return event.cards.filterInD().length>0; + saya_shouji: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + return event.cards.filterInD().length > 0; }, - usable:1, - async cost(event, trigger, player){ - const goon = function(){ - var num=0; - var cards=trigger.cards.filterInD(); - for(var i=0;inum; - })==0; - }(); - event.result = await player.chooseTarget(get.prompt2('saya_shouji'),lib.filter.notMe).set('ai',function(target){ - if(!_status.event.goon) return 0; - var player=_status.event.player; - var cards=_status.event.getTrigger().cards.filterInD(); - var att=get.attitude(player,target); - var num=0; - for(var i=0;i num; + }) == 0 + ); + })(); + event.result = await player + .chooseTarget(get.prompt2("saya_shouji"), lib.filter.notMe) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + var player = _status.event.player; + var cards = _status.event.getTrigger().cards.filterInD(); + var att = get.attitude(player, target); + var num = 0; + for (var i = 0; i < cards.length; i++) { + num += target.getUseValue(cards[i]); + } + return Math.max(num, 0.1) * att; + }) + .set("goon", goon) + .forResult(); }, - content(){ - 'step 0' - event.cards=trigger.cards.filterInD(); - var target=targets[0]; - event.target=target; - target.gain(event.cards,'gain2','log'); - 'step 2' + content() { + "step 0"; + event.cards = trigger.cards.filterInD(); + var target = targets[0]; + event.target = target; + target.gain(event.cards, "gain2", "log"); + "step 2"; target.chooseToUse({ - cards:cards, - filterCard(card){ - if(get.itemtype(card)!='card'||!_status.event.cards||!_status.event.cards.includes(card)) return false; - return lib.filter.filterCard.apply(this,arguments); + cards: cards, + filterCard(card) { + if ( + get.itemtype(card) != "card" || + !_status.event.cards || + !_status.event.cards.includes(card) + ) + return false; + return lib.filter.filterCard.apply(this, arguments); }, - prompt:'是否使用得到的牌中的一张?', + prompt: "是否使用得到的牌中的一张?", }); - 'step 3' - if(result.bool) player.draw(); + "step 3"; + if (result.bool) player.draw(); }, }, - haruka_shuangche:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return !player.hasSkill('haruka_kanata'); + haruka_shuangche: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return !player.hasSkill("haruka_kanata"); }, - chooseButton:{ - dialog(event,player){ - var list=[]; - for(var i=0;i0) return 0; - if(['wugu','zhulu_card'].includes(button.link[2])) return 0; - var effect=player.getUseValue(button.link[2]); - if(effect>0) return effect; + check(button) { + var player = _status.event.player; + if (player.countCards("h", button.link[2]) > 0) return 0; + if (["wugu", "zhulu_card"].includes(button.link[2])) return 0; + var effect = player.getUseValue(button.link[2]); + if (effect > 0) return effect; return 0; }, - backup(links,player){ + backup(links, player) { return { - audio:'haruka_shuangche', - filterCard(){return false}, - selectCard:-1, - popname:true, - check(card){ - return 6-get.value(card); + audio: "haruka_shuangche", + filterCard() { + return false; }, - position:'he', - viewAs:{name:links[0][2],nature:links[0][3],isCard:true}, - } + selectCard: -1, + popname: true, + check(card) { + return 6 - get.value(card); + }, + position: "he", + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, + }, + }; + }, + prompt(links, player) { + return ( + "请选择" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "的目标" + ); }, - prompt(links,player){ - return '请选择'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'的目标'; - } }, - ai:{ - order:1, - result:{ - player(player){ - var cards=player.getCards('he').sort(function(a,b){ - return get.value(a)-get.value(b); + ai: { + order: 1, + result: { + player(player) { + var cards = player.getCards("he").sort(function (a, b) { + return get.value(a) - get.value(b); }); - var num=(player.getStat('skill').haruka_shuangche||0)+1; - if(player.needsToDiscard()>=num) return 1; - if(player.hp>2) return 1; - if(cards.length>=num){ - var val=0; - for(var i=0;i= num) return 1; + if (player.hp > 2) return 1; + if (cards.length >= num) { + var val = 0; + for (var i = 0; i < cards.length; i++) { + val += get.value(cards[i]); } - return 12-val; + return 12 - val; } return 0; - } + }, }, - fireAttack:true, + fireAttack: true, }, - group:'kanata_shuangche', + group: "kanata_shuangche", }, - kanata_shuangche:{ - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - return event.skill=='haruka_shuangche_backup'; + kanata_shuangche: { + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + return event.skill == "haruka_shuangche_backup"; }, - content(){ - 'step 0' - var num=player.getStat('skill').haruka_shuangche||1; - player.chooseToDiscard('###双掣:请选择一项###选择弃置'+get.cnNumber(num)+'张牌,或失去1点体力且令〖双掣〗失效至回合结束',num,'he').set('ai',function(card){ - var total=12; - for(var i=0;i0; + tsumugi_huilang: { + trigger: { player: "phaseEnd" }, + charlotte: true, + line: { color: [253, 198, 116] }, + filter(event, player) { + return player.countCards("he") > 0; }, - async cost(event, trigger, player){ - event.result = await player.chooseCard('he',[1,player.countCards('he')],get.prompt2('tsumugi_huilang')).set('ai',function(card){ - if(get.position(card)!='h') return -1; - if(!['shan','wuxie','caochuan'].includes(get.name(card))) return 9; - return 5-get.value(card); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseCard("he", [1, player.countCards("he")], get.prompt2("tsumugi_huilang")) + .set("ai", function (card) { + if (get.position(card) != "h") return -1; + if (!["shan", "wuxie", "caochuan"].includes(get.name(card))) return 9; + return 5 - get.value(card); + }) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const cards = event.cards; - player.addSkill('tsumugi_huilang2'); - player.addToExpansion('giveAuto', cards, player).gaintag.add('tsumugi_huilang2'); + player.addSkill("tsumugi_huilang2"); + player.addToExpansion("giveAuto", cards, player).gaintag.add("tsumugi_huilang2"); }, }, - tsumugi_huilang2:{ - charlotte:true, - marktext:'隐', - intro:{content:'隐藏于回廊之牌',markcount:'expansion'}, - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + tsumugi_huilang2: { + charlotte: true, + marktext: "隐", + intro: { content: "隐藏于回廊之牌", markcount: "expansion" }, + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return player.getExpansions('tsumugi_huilang2').length>0; + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return player.getExpansions("tsumugi_huilang2").length > 0; }, - content(){ - 'step 0' - var cards=player.getExpansions('tsumugi_huilang2'); - event.num=cards.length; - player.gain(cards,'draw'); - 'step 1' - player.chooseTarget([1,num],'是否令至多'+get.cnNumber(num)+'名角色各摸一张牌?').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 2' - if(result.bool){ - var targets=result.targets; - player.line(targets,lib.skill.tsumugi_huilang.line); + content() { + "step 0"; + var cards = player.getExpansions("tsumugi_huilang2"); + event.num = cards.length; + player.gain(cards, "draw"); + "step 1"; + player + .chooseTarget([1, num], "是否令至多" + get.cnNumber(num) + "名角色各摸一张牌?") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 2"; + if (result.bool) { + var targets = result.targets; + player.line(targets, lib.skill.tsumugi_huilang.line); targets.sortBySeat(); game.asyncDraw(targets); - } - else event.finish(); - 'step 3' + } else event.finish(); + "step 3"; game.delay(); }, }, - yui_jiang:{ - shaRelated:true, - audio:2, - audioname:['sp_lvmeng','re_sunben','re_sunce'], - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + yui_jiang: { + shaRelated: true, + audio: 2, + audioname: ["sp_lvmeng", "re_sunben", "re_sunce"], + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter(event,player){ - 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; + filter(event, player) { + 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; }, - frequent:true, - content(){ + frequent: true, + content() { player.draw(); }, - ai:{ - effect:{ - target(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,0.6]; + ai: { + effect: { + target(card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 0.6]; }, - player(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,1]; - } - } - } + player(card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 1]; + }, + }, + }, }, - yui_lieyin:{ - trigger:{player:'phaseUseBegin'}, - locked:true, - async cost(event, trigger, player){ - const list=[]; - if(player.storage._ichiban_no_takaramono) list.push('cancel2'); - const {control, index} = await player.chooseControl(...list).set('choiceList',[ - '令此阶段内的所有红色牌视为【杀】', - '令此阶段内的所有【杀】视为【决斗】' - ]).set('prompt',player.storage._ichiban_no_takaramono?get.prompt('yui_lieyin'):'烈音:请选择一项').set('ai',function(){ - var player=_status.event.player; - var shas=player.countCards('h','sha') - if(shas>0){ - if(game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&player.canUse('juedou',current)&&!current.hasSha()&&get.effect(current,{name:'juedou'},player,player)>0; - })) return 1; - if(player.storage._ichiban_no_takaramono) return 'cancel2'; - } - if(player.countCards('h',function(card){ - return get.color(card)=='red'&&card.name!='sha'&&player.hasValueTarget(card); - })==0) return 0; - if(player.storage._ichiban_no_takaramono) return 'cancel2'; - return 1; - }).forResult(); - if (control !== 'cancel2'){ + yui_lieyin: { + trigger: { player: "phaseUseBegin" }, + locked: true, + async cost(event, trigger, player) { + const list = []; + if (player.storage._ichiban_no_takaramono) list.push("cancel2"); + const { control, index } = await player + .chooseControl(...list) + .set("choiceList", [ + "令此阶段内的所有红色牌视为【杀】", + "令此阶段内的所有【杀】视为【决斗】", + ]) + .set( + "prompt", + player.storage._ichiban_no_takaramono + ? get.prompt("yui_lieyin") + : "烈音:请选择一项" + ) + .set("ai", function () { + var player = _status.event.player; + var shas = player.countCards("h", "sha"); + if (shas > 0) { + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + player.canUse("juedou", current) && + !current.hasSha() && + get.effect(current, { name: "juedou" }, player, player) > 0 + ); + }) + ) + return 1; + if (player.storage._ichiban_no_takaramono) return "cancel2"; + } + if ( + player.countCards("h", function (card) { + return ( + get.color(card) == "red" && + card.name != "sha" && + player.hasValueTarget(card) + ); + }) == 0 + ) + return 0; + if (player.storage._ichiban_no_takaramono) return "cancel2"; + return 1; + }) + .forResult(); + if (control !== "cancel2") { event.result = { bool: true, - cost_data: {index} - } + cost_data: { index }, + }; } }, - async content(event, trigger, player){ - player.addTempSkill(`yui_lieyin${event.cost_data.index}`,'phaseUseEnd') + async content(event, trigger, player) { + player.addTempSkill(`yui_lieyin${event.cost_data.index}`, "phaseUseEnd"); }, }, - yui_lieyin0:{ - mod:{ - cardname(card){ - if(get.color(card)=='red') return 'sha'; + yui_lieyin0: { + mod: { + cardname(card) { + if (get.color(card) == "red") return "sha"; }, }, }, - yui_lieyin1:{ - mod:{ - cardname(card){ - if(card.name=='sha') return 'juedou'; + yui_lieyin1: { + mod: { + cardname(card) { + if (card.name == "sha") return "juedou"; }, }, }, - yui_takaramono:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'key', - filter(event,player){ - var num=0; - if(player.hp<=1) num++; - if(game.dead.length>0) num++; - if(num!=1) return num>1; - var draw=0; - player.getAllHistory('gain',function(evt){ - if(evt.getParent(2).name=='yui_jiang') draw+=evt.cards.length; + yui_takaramono: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "key", + filter(event, player) { + var num = 0; + if (player.hp <= 1) num++; + if (game.dead.length > 0) num++; + if (num != 1) return num > 1; + var draw = 0; + player.getAllHistory("gain", function (evt) { + if (evt.getParent(2).name == "yui_jiang") draw += evt.cards.length; }); - return draw>=3; + return draw >= 3; }, - content(){ - player.awakenSkill('yui_takaramono'); - player.addSkills('yui_yinhang'); - player.storage._ichiban_no_takaramono=true; + content() { + player.awakenSkill("yui_takaramono"); + player.addSkills("yui_yinhang"); + player.storage._ichiban_no_takaramono = true; player.gainMaxHp(); player.recover(); }, - derivation:'yui_yinhang', + derivation: "yui_yinhang", }, - yui_yinhang:{ - trigger:{player:'changeHp'}, - locked:true, - getIndex:(event)=>Math.abs(event.num), - line:{color:[253, 153, 182]}, - async cost(event, trigger, player){ - event.result = await player.chooseTarget([1,2],get.prompt('yui_yinhang'),'令至多两名角色各摸一张牌').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).forResult(); + yui_yinhang: { + trigger: { player: "changeHp" }, + locked: true, + getIndex: (event) => Math.abs(event.num), + line: { color: [253, 153, 182] }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget([1, 2], get.prompt("yui_yinhang"), "令至多两名角色各摸一张牌") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const targets = event.targets; targets.sortBySeat(); game.asyncDraw(targets); }, }, - yoshino_jueyi:{ - trigger:{player:'phaseUseBegin'}, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(lib.filter.notMe,get.prompt2('yoshino_jueyi')).set('ai',function(target){ - var player=_status.event.player; - if(get.damageEffect(target,player,player)<0) return 0; - var att=get.attitude(player,target); - if(att>0) return 0; - if(att==0) return 0.1; - var eff=0; - var hs=player.getCards('h'); - for(var i=0;i0) eff+=eff2; + yoshino_jueyi: { + trigger: { player: "phaseUseBegin" }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(lib.filter.notMe, get.prompt2("yoshino_jueyi")) + .set("ai", function (target) { + var player = _status.event.player; + if (get.damageEffect(target, player, player) < 0) return 0; + var att = get.attitude(player, target); + if (att > 0) return 0; + if (att == 0) return 0.1; + var eff = 0; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { + if (player.canUse(hs[i], target)) { + var eff2 = get.effect(target, hs[i], player, player); + if (eff2 > 0) eff += eff2; + } } - } - return -att/(1+eff); - }).forResult(); + return -att / (1 + eff); + }) + .forResult(); }, - content(){ - 'step 0' - var target=targets[0]; - event.target=target; + content() { + "step 0"; + var target = targets[0]; + event.target = target; player.draw(); - 'step 1' + "step 1"; player.chooseToPSS(target); - 'step 2' - if(result.tie) event.goto(1); - else if(result.bool) target.damage(); - else target.addTempSkill('yoshino_fail','phaseUseEnd'); + "step 2"; + if (result.tie) event.goto(1); + else if (result.bool) target.damage(); + else target.addTempSkill("yoshino_fail", "phaseUseEnd"); }, }, - yoshino_fail:{ - mod:{ - targetEnabled(card,player,target){ - if(player==_status.currentPhase) return false; + yoshino_fail: { + mod: { + targetEnabled(card, player, target) { + if (player == _status.currentPhase) return false; }, }, }, - kengo_weishang:{ - locked:false, - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha'&&player.hasDisabledSlot(1)) return num+1; + kengo_weishang: { + locked: false, + mod: { + cardUsable(card, player, num) { + if (card.name == "sha" && player.hasDisabledSlot(1)) return num + 1; }, - globalFrom(from,to,distance){ - if(from.hasDisabledSlot(4)) return distance-1; + globalFrom(from, to, distance) { + if (from.hasDisabledSlot(4)) return distance - 1; }, - globalTo(from,to,distance){ - if(to.hasDisabledSlot(3)) return distance+1; + globalTo(from, to, distance) { + if (to.hasDisabledSlot(3)) return distance + 1; }, }, - enable:'phaseUse', - usable:1, - filter(event,player){ - var list=['equip1','equip2','equip3','equip4','equip5']; - for(var i=0;i0 - })) return 'equip1'; - if(list.includes('equip3')&&player.hasEmptySlot('equip3')) return 'equip3'; - if(list.includes('equip4')&&player.hasEmptySlot('equip4')) return 'equip4'; - if(list.includes('equip5')&&player.hasEmptySlot('equip5')) return 'equip5'; - if(list.includes('equip2')&&player.hasEmptySlot('equip2')) return 'equip2'; + player.chooseControl(list).set("prompt", "请选择废除一个装备栏").ai = function () { + if ( + list.includes("equip1") && + player.hasEmptySlot("equip1") && + player.countCards("h", function (card) { + return card.name == "sha" && player.getUseValue(card) > 0; + }) + ) + return "equip1"; + if (list.includes("equip3") && player.hasEmptySlot("equip3")) return "equip3"; + if (list.includes("equip4") && player.hasEmptySlot("equip4")) return "equip4"; + if (list.includes("equip5") && player.hasEmptySlot("equip5")) return "equip5"; + if (list.includes("equip2") && player.hasEmptySlot("equip2")) return "equip2"; return list.randomGet(); }; - 'step 1' + "step 1"; player.disableEquip(result.control); player.draw(2); }, - group:['kengo_weishang_sha','kengo_weishang_shan'], - ai:{ - order:10, - result:{player:1}, + group: ["kengo_weishang_sha", "kengo_weishang_shan"], + ai: { + order: 10, + result: { player: 1 }, }, }, - kengo_weishang_sha:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'&&player.hasDisabledSlot(1)&&event.target.countCards('he')>0; + kengo_weishang_sha: { + trigger: { player: "useCardToPlayered" }, + forced: true, + filter(event, player) { + return ( + event.card.name == "sha" && + player.hasDisabledSlot(1) && + event.target.countCards("he") > 0 + ); }, - logTarget:'target', - content(){ - trigger.target.chooseToDiscard('he',true); + logTarget: "target", + content() { + trigger.target.chooseToDiscard("he", true); }, }, - kengo_weishang_shan:{ - enable:['chooseToUse','chooseToRespond'], - viewAs:{name:'shan'}, - filterCard:true, - position:'hes', - prompt:'将一张牌当做闪使用或打出', - viewAsFilter(player){ - return player.hasDisabledSlot(2)&&player.countCards('hes')>0; + kengo_weishang_shan: { + enable: ["chooseToUse", "chooseToRespond"], + viewAs: { name: "shan" }, + filterCard: true, + position: "hes", + prompt: "将一张牌当做闪使用或打出", + viewAsFilter(player) { + return player.hasDisabledSlot(2) && player.countCards("hes") > 0; }, - check(card){ - return 1/Math.max(0.1,get.value(card)); + check(card) { + return 1 / Math.max(0.1, get.value(card)); }, - ai:{ - respondShan:true, - skillTagFilter(player){ - return player.hasDisabledSlot(2)&&player.countCards('he')>0; + ai: { + respondShan: true, + skillTagFilter(player) { + return player.hasDisabledSlot(2) && player.countCards("he") > 0; }, }, }, - kengo_guidui:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter(event,player){ - return player.countDisabledSlot()>0; + kengo_guidui: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter(event, player) { + return player.countDisabledSlot() > 0; }, - content(){ - var list=[]; - for(var i=1;i<=5;i++){ - for(var j=0;jMath.abs(event.num), - async cost(event, trigger, player){ - event.result = await player.chooseTarget([1,2],get.prompt('iwasawa_yinhang'),'令至多两名角色各摸一张牌').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).forResult(); + kengo_guidui2: { onremove: true }, + iwasawa_yinhang: { + trigger: { player: "changeHp" }, + locked: true, + line: { color: [235, 96, 138] }, + getIndex: (event) => Math.abs(event.num), + async cost(event, trigger, player) { + event.result = await player + .chooseTarget([1, 2], get.prompt("iwasawa_yinhang"), "令至多两名角色各摸一张牌") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .forResult(); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const targets = event.targets; targets.sortBySeat(); game.asyncDraw(targets); }, }, - iwasawa_mysong:{ - trigger:{player:['phaseBeginStart','phaseAfter','dyingBefore']}, - forced:true, - filter(event,player){ - return event.name=='dying'||player.hp<1; + iwasawa_mysong: { + trigger: { + player: ["phaseBeginStart", "phaseAfter", "dyingBefore"], }, - content(){ - if(trigger.name=='dying') trigger.cancel(); - else if(event.triggername=='phaseBeginStart') player.addTempSkill('iwasawa_fenyin'); + forced: true, + filter(event, player) { + return event.name == "dying" || player.hp < 1; + }, + content() { + if (trigger.name == "dying") trigger.cancel(); + else if (event.triggername == "phaseBeginStart") player.addTempSkill("iwasawa_fenyin"); else player.die(); }, - nobracket:true, - derivation:'iwasawa_fenyin', + nobracket: true, + derivation: "iwasawa_fenyin", }, - iwasawa_refenyin:{ - audio:2, - audioname2:{ - wufan:'refenyin_wufan', + iwasawa_refenyin: { + audio: 2, + audioname2: { + wufan: "refenyin_wufan", }, - trigger:{global:['loseAfter','cardsDiscardAfter','equipAfter']}, - forced:true, - filter(event,player){ - if(player!=_status.currentPhase) return false; - var cards=event.getd(); - var list=[]; - for(var i=0;i0; + return list.length > 0; }, - content(){ - var list=[]; - var list2=[]; - var cards=trigger.getd(); - for(var i=0;i=0?0:1).set('ai',function(){return _status.event.choice}); - 'step 1' - if(result.control=='增加伤害'){ + masato_baoquan: { + trigger: { source: "damageBefore" }, + forced: true, + content() { + "step 0"; + player + .chooseControl("防止伤害", "增加伤害") + .set( + "prompt", + "暴拳:防止即将对" + + get.translation(trigger.player) + + "造成的伤害,或失去1点体力上限并令此伤害+2" + ) + .set("choice", get.attitude(player, trigger.player) >= 0 ? 0 : 1) + .set("ai", function () { + return _status.event.choice; + }); + "step 1"; + if (result.control == "增加伤害") { player.loseMaxHp(); - trigger.num+=2; - } - else trigger.cancel(); + trigger.num += 2; + } else trigger.cancel(); }, - ai:{ - effect:{ - player(card,player,target){ - if(target&&get.attitude(player,target)>0&&get.tag(card,'damage')) return 'zeroplayertarget'; + ai: { + effect: { + player(card, player, target) { + if (target && get.attitude(player, target) > 0 && get.tag(card, "damage")) + return "zeroplayertarget"; }, }, }, }, - yusa_yanyi:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return get.distance(player,target)<=player.hp; + yusa_yanyi: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return get.distance(player, target) <= player.hp; }, - selectTarget(){ - return [1,Math.max(_status.event.player.getAttackRange())]; + selectTarget() { + return [1, Math.max(_status.event.player.getAttackRange())]; }, - line:'thunder', - content(){ - 'step 0' - if(target.isHealthy()){ + line: "thunder", + content() { + "step 0"; + if (target.isHealthy()) { player.draw(); event.finish(); + } else { + var name = get.translation(player); + target + .chooseControl() + .set("choiceList", [ + "令" + name + "摸一张牌", + "回复1点体力,然后交给" + name + "一张牌", + ]) + .set("ai", function () { + return 1; + }); } - else{ - var name=get.translation(player); - target.chooseControl().set('choiceList',[ - '令'+name+'摸一张牌', - '回复1点体力,然后交给'+name+'一张牌', - ]).set('ai',function(){ - return 1; - }); - } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { player.draw(); event.finish(); - } - else{ + } else { target.recover(); } - 'step 2' - if(target!=player&&target.countCards('he')>0){ - target.chooseCard('交给'+get.translation(player)+'一张牌','he',true); - } - else event.finish(); - 'step 3' - target.give(result.cards,player,'giveAuto'); + "step 2"; + if (target != player && target.countCards("he") > 0) { + target.chooseCard("交给" + get.translation(player) + "一张牌", "he", true); + } else event.finish(); + "step 3"; + target.give(result.cards, player, "giveAuto"); }, - ai:{ - order:10, - result:{ - player(player,target){ - return target.isHealthy()?1:0; + ai: { + order: 10, + result: { + player(player, target) { + return target.isHealthy() ? 1 : 0; }, - target(player,target){ - if(target.isHealthy()) return 0; - return get.recoverEffect(target,player,target); + target(player, target) { + if (target.isHealthy()) return 0; + return get.recoverEffect(target, player, target); }, }, }, }, - yusa_misa:{ - charlotte:true, - trigger:{player:'useSkillAfter'}, - filter(event,player){ - return event.skill=='yusa_yanyi'&&!player.storage.dualside_over&&Array.isArray(player.storage.dualside); + yusa_misa: { + charlotte: true, + trigger: { player: "useSkillAfter" }, + filter(event, player) { + return ( + event.skill == "yusa_yanyi" && + !player.storage.dualside_over && + Array.isArray(player.storage.dualside) + ); }, - content(){ + content() { player.turnOver(); }, }, - misa_yusa:{ - charlotte:true, - trigger:{player:'misa_yehuoAfter'}, - filter(event,player){ - return event.bool===true&&!player.storage.dualside_over&&Array.isArray(player.storage.dualside); + misa_yusa: { + charlotte: true, + trigger: { player: "misa_yehuoAfter" }, + filter(event, player) { + return ( + event.bool === true && + !player.storage.dualside_over && + Array.isArray(player.storage.dualside) + ); }, - content(){ + content() { player.turnOver(); }, }, - misa_yehuo:{ - charlotte:true, - trigger:{global:'phaseDrawBegin1'}, - locked:true, - line:{color:[236,137,52]}, - filter(event,player){ - var target=event.player; - return player.inRange(target)&&player.countCards('he')>=get.distance(player,target); + misa_yehuo: { + charlotte: true, + trigger: { global: "phaseDrawBegin1" }, + locked: true, + line: { color: [236, 137, 52] }, + filter(event, player) { + var target = event.player; + return player.inRange(target) && player.countCards("he") >= get.distance(player, target); }, - async cost(event, trigger, player){ - var next=player.chooseToDiscard('he',get.distance(player,trigger.player)||1,get.prompt2('misa_yehuo',trigger.player),'chooseonly'); - next.set('ai',function(card){ - var val=_status.event.val; - for(var i=0;i0; + check(event, player) { + return !event.player.isTurnedOver() || get.attitude(player, event.player) > 0; }, }, - yukine_wenzhou:{ - trigger:{global:'phaseUseBegin'}, - filter(event,player){ - return event.player.countCards('he')>0; + yukine_wenzhou: { + trigger: { global: "phaseUseBegin" }, + filter(event, player) { + return event.player.countCards("he") > 0; }, - async cost(event, trigger, player){ + async cost(event, trigger, player) { event.forceDie = true; - var ask = trigger.player.chooseCard('he', get.prompt('yukine_wenzhou')); - if(player === trigger.player){ - ask.set('prompt2','选择一张牌,然后从牌堆中获得一张与此牌类型相同的牌。本回合内使用与此牌类型相同的牌时不可被其他角色响应。'); - } - else ask.set('prompt2','将一张牌交给'+get.translation(player)+'然后其可以选择:交给你一张牌;或令你从牌堆中获得一张与此牌类型相同的牌,且你本回合内使用与此牌类型相同的牌时不可被响应。'); - ask.set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0) return 10-get.value(card); + var ask = trigger.player.chooseCard("he", get.prompt("yukine_wenzhou")); + if (player === trigger.player) { + ask.set( + "prompt2", + "选择一张牌,然后从牌堆中获得一张与此牌类型相同的牌。本回合内使用与此牌类型相同的牌时不可被其他角色响应。" + ); + } else + ask.set( + "prompt2", + "将一张牌交给" + + get.translation(player) + + "然后其可以选择:交给你一张牌;或令你从牌堆中获得一张与此牌类型相同的牌,且你本回合内使用与此牌类型相同的牌时不可被响应。" + ); + ask.set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) + return 10 - get.value(card); return -1; }); event.result = await ask.forResult(); }, - content(){ - "step 0" - event.forceDie=true; - event.type=get.type(cards[0],'trick'); - if(trigger.player!=player) trigger.player.give(cards,player,'giveAuto'); - "step 1" - if(player==trigger.player||player.countCards('he')==0){ - event._result={index:1}; + content() { + "step 0"; + event.forceDie = true; + event.type = get.type(cards[0], "trick"); + if (trigger.player != player) trigger.player.give(cards, player, "giveAuto"); + "step 1"; + if (player == trigger.player || player.countCards("he") == 0) { + event._result = { index: 1 }; + } else { + player + .chooseControl() + .set("choiceList", [ + "将一张牌交给" + get.translation(trigger.player), + "令" + + get.translation(trigger.player) + + "从牌堆中获得一张" + + get.translation(event.type) + + "牌,且其本回合内使用与此牌名称相同的牌时不可被响应", + ]) + .set("forceDie", true) + .set("ai", function () { + if (get.attitude(_status.event.player, _status.event.getTrigger().player) > 0) + return 1; + return 0; + }); } - else{ - player.chooseControl().set('choiceList',[ - '将一张牌交给'+get.translation(trigger.player), - '令'+get.translation(trigger.player)+'从牌堆中获得一张'+get.translation(event.type)+'牌,且其本回合内使用与此牌名称相同的牌时不可被响应', - ]).set('forceDie',true).set('ai',function(){ - if(get.attitude(_status.event.player,_status.event.getTrigger().player)>0) return 1; - return 0; + "step 2"; + event.index = result.index; + if (result.index == 1) { + var magic = get.cardPile2(function (card) { + return get.type(card, "trick") == event.type; }); - } - "step 2" - event.index=result.index; - if(result.index==1){ - var magic=get.cardPile2(function(card){ - return get.type(card,'trick')==event.type; - }); - if(magic){ - trigger.player.addTempSkill('yukine_magic','phaseUseEnd'); + if (magic) { + trigger.player.addTempSkill("yukine_magic", "phaseUseEnd"); trigger.player.storage.yukine_magic.add(magic.name); - trigger.player.gain(magic,'draw'); - } - else event.finish(); - } - else player.chooseCard('he',true,'选择要交给'+get.translation(trigger.player)+'的牌').set('ai',function(card){ - return -get.value(card,_status.event.getTrigger().player); - }); - "step 3" - if(event.index==1) game.updateRoundNumber(); - else if(result.bool) player.give(result.cards,trigger.player,'giveAuto'); + trigger.player.gain(magic, "draw"); + } else event.finish(); + } else + player + .chooseCard("he", true, "选择要交给" + get.translation(trigger.player) + "的牌") + .set("ai", function (card) { + return -get.value(card, _status.event.getTrigger().player); + }); + "step 3"; + if (event.index == 1) game.updateRoundNumber(); + else if (result.bool) player.give(result.cards, trigger.player, "giveAuto"); }, }, - yukine_magic:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - charlotte:true, - filter(event,player){ - return player.storage.yukine_magic&&player.storage.yukine_magic.includes(event.card.name); + yukine_magic: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + charlotte: true, + filter(event, player) { + return ( + player.storage.yukine_magic && player.storage.yukine_magic.includes(event.card.name) + ); }, - content(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - if(player!=current) return true; - return !player.hasSkill('yukine_wenzhou'); - })); + content() { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + if (player != current) return true; + return !player.hasSkill("yukine_wenzhou"); + }) + ); }, - onremove:true, - init(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + onremove: true, + init(player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return player.storage.yukine_magic&&player.storage.yukine_magic.includes(arg.card.name); + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return ( + player.storage.yukine_magic && player.storage.yukine_magic.includes(arg.card.name) + ); }, }, }, - komari_tiankou:{ - trigger:{ - player:'useCard2', - target:'useCardToTarget', + komari_tiankou: { + trigger: { + player: "useCard2", + target: "useCardToTarget", }, - forced:true, - filter(event,player,name){ - if(name=='useCardToTarget'&&player==event.player) return false; - if(get.color(event.card)!='red') return false; - if(get.tag(event.card,'damage')) return false; - return ['basic','trick'].includes(get.type(event.card)); + forced: true, + filter(event, player, name) { + if (name == "useCardToTarget" && player == event.player) return false; + if (get.color(event.card) != "red") return false; + if (get.tag(event.card, "damage")) return false; + return ["basic", "trick"].includes(get.type(event.card)); }, - content(){ - 'step 0' - var info=get.info(trigger.card); - var bool=true; - if(info.multitarget||info.allowMultiple===false) bool=false; - else{ - var list=game.filterPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,trigger.player,current); - }) - if(!list.length) bool=false; + content() { + "step 0"; + var info = get.info(trigger.card); + var bool = true; + if (info.multitarget || info.allowMultiple === false) bool = false; + else { + var list = game.filterPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ); + }); + if (!list.length) bool = false; } - if(bool) player.chooseTarget('甜口:为'+get.translation(trigger.card)+'增加一个额外目标,或点【取消】摸一张牌。',function(candy,komari,rin){ - return _status.event.rin_chan.includes(rin); - }).set('rin_chan',list).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,evt.candy,evt.source,evt.player); - }).set('candy',trigger.card).set('',trigger.player); - else event._result={bool:false}; - 'step 1' - if(result.bool){ - var rin=result.targets[0]; + if (bool) + player + .chooseTarget( + "甜口:为" + + get.translation(trigger.card) + + "增加一个额外目标,或点【取消】摸一张牌。", + function (candy, komari, rin) { + return _status.event.rin_chan.includes(rin); + } + ) + .set("rin_chan", list) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, evt.candy, evt.source, evt.player); + }) + .set("candy", trigger.card) + .set("", trigger.player); + else event._result = { bool: false }; + "step 1"; + if (result.bool) { + var rin = result.targets[0]; trigger.targets.push(rin); - player.line(rin,{color:[255, 224,172]}); - } - else player.draw(); + player.line(rin, { color: [255, 224, 172] }); + } else player.draw(); }, }, - komari_xueshang:{ - trigger:{global:'die'}, - forced:true, - skillAnimation:true, - chargingSkill:true, - filter(event,player){ - return player.hp>0; + komari_xueshang: { + trigger: { global: "die" }, + forced: true, + skillAnimation: true, + chargingSkill: true, + filter(event, player) { + return player.hp > 0; }, - animationColor:'metal', - content(){ - 'step 0' - player.addSkill('riki_xueshang'); - var map={}; - var list=[]; - for(var i=1;i<=player.hp;i++){ - var cn=get.cnNumber(i,true); - map[cn]=i; + animationColor: "metal", + content() { + "step 0"; + player.addSkill("riki_xueshang"); + var map = {}; + var list = []; + for (var i = 1; i <= player.hp; i++) { + var cn = get.cnNumber(i, true); + map[cn] = i; list.push(cn); } - event.map=map; - player.chooseControl(list,function(){ - return '一'; - }).set('prompt','血殇:请选择自己受到的伤害的点数'); - 'step 1' - var num=event.map[result.control]||1; - event.num=num>1?2:1; - event.list=game.filterPlayer(function(current){ - return current!=player; - }).sortBySeat(); + event.map = map; + player + .chooseControl(list, function () { + return "一"; + }) + .set("prompt", "血殇:请选择自己受到的伤害的点数"); + "step 1"; + var num = event.map[result.control] || 1; + event.num = num > 1 ? 2 : 1; + event.list = game + .filterPlayer(function (current) { + return current != player; + }) + .sortBySeat(); player.damage(num); - player.line(event.list,{color:[255, 224,172]}); - 'step 2' - if(!player.hasSkill(event.name)) return; - else{ + player.line(event.list, { color: [255, 224, 172] }); + "step 2"; + if (!player.hasSkill(event.name)) return; + else { event.list.shift().damage(num); - if(event.list.length) event.redo(); + if (event.list.length) event.redo(); } }, }, - riki_xueshang:{ - trigger:{global:'dying'}, - forced:true, - popup:false, - charlotte:true, - filter(event,player){ - return event.getParent(2).name=='komari_xueshang'&&event.getParent(2).player==player; + riki_xueshang: { + trigger: { global: "dying" }, + forced: true, + popup: false, + charlotte: true, + filter(event, player) { + return ( + event.getParent(2).name == "komari_xueshang" && event.getParent(2).player == player + ); }, - content(){ - player.removeSkills('komari_xueshang'); + content() { + player.removeSkills("komari_xueshang"); player.gainMaxHp(true); player.recover(); }, }, - umi_chaofan:{ - enable:'phaseUse', - usable:1, - selectCard:2, - complexCard:true, - filter(summer,umi){ - return umi.countCards('h')>1; + umi_chaofan: { + enable: "phaseUse", + usable: 1, + selectCard: 2, + complexCard: true, + filter(summer, umi) { + return umi.countCards("h") > 1; }, - check(ingredient){ - return 7-get.value(ingredient); + check(ingredient) { + return 7 - get.value(ingredient); }, - filterCard(ingredient){ - if(ui.selected.cards.length) return get.suit(ingredient)!=get.suit(ui.selected.cards[0]); + filterCard(ingredient) { + if (ui.selected.cards.length) + return get.suit(ingredient) != get.suit(ui.selected.cards[0]); return true; }, - line:{color:[251, 193, 217]}, - filterTarget:lib.filter.notMe, - content(){ - 'step 0' + line: { color: [251, 193, 217] }, + filterTarget: lib.filter.notMe, + content() { + "step 0"; player.draw(); - 'step 1' - if(player.hp>2) target.recover(); - else if(player.hp==2) target.draw(2); - else target.damage('fire','nosource'); + "step 1"; + if (player.hp > 2) target.recover(); + else if (player.hp == 2) target.draw(2); + else target.damage("fire", "nosource"); }, - ai:{ - order:2, - result:{ - target(umi,takahara){ - if(umi.hp>2&&takahara.isDamaged()) return 2.2; - if(umi.hp==2&&!takahara.hasSkillTag('nogain')) return 2; - if(umi.hp<2) return get.damageEffect(takahara,umi,umi,'fire'); + ai: { + order: 2, + result: { + target(umi, takahara) { + if (umi.hp > 2 && takahara.isDamaged()) return 2.2; + if (umi.hp == 2 && !takahara.hasSkillTag("nogain")) return 2; + if (umi.hp < 2) return get.damageEffect(takahara, umi, umi, "fire"); }, }, }, }, - umi_lunhui:{ - trigger:{global:'phaseAfter'}, - filter(summer,umi){ - return summer.player!=umi&&umi.countCards('h')0; - }, - check(event,player){ - return get.attitude(player,event.player)>1; - }, - logTarget:'player', - content(){ - 'step 0' - player.gain(trigger.player.getCards('j'),trigger.player,'give','bySelf'); - 'step 1' - if(player.hp>1) player.loseHp(); + content() { + trigger.num += 2; }, }, - yuri_xingdong:{ - audio:3, - group:'yuri_xingdong_gain', - subSkill:{ - mark:{ - mark:true, - marktext:'令', - intro:{ - content:'跳过下个回合的判定阶段和摸牌阶段', + haruko_zhuishi: { + trigger: { global: "phaseJudgeBegin" }, + filter(misuzu) { + return misuzu.player.countCards("j") > 0; + }, + check(event, player) { + return get.attitude(player, event.player) > 1; + }, + logTarget: "player", + content() { + "step 0"; + player.gain(trigger.player.getCards("j"), trigger.player, "give", "bySelf"); + "step 1"; + if (player.hp > 1) player.loseHp(); + }, + }, + yuri_xingdong: { + audio: 3, + group: "yuri_xingdong_gain", + subSkill: { + mark: { + mark: true, + marktext: "令", + intro: { + content: "跳过下个回合的判定阶段和摸牌阶段", }, }, - gain:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - content(){ - 'step 0' - var card=get.cardPile(function(card){ - return card.name=='sha'||get.type(card)=='trick'; + gain: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + content() { + "step 0"; + var card = get.cardPile(function (card) { + return card.name == "sha" || get.type(card) == "trick"; }); - if(card) player.gain(card,'gain2','log'); - 'step 1' + if (card) player.gain(card, "gain2", "log"); + "step 1"; game.updateRoundNumber(); }, }, }, - enable:'phaseUse', - usable:1, - locked:true, - filter(event,player){ - return player.countCards('h',lib.skill.yuri_xingdong.filterCard); + enable: "phaseUse", + usable: 1, + locked: true, + filter(event, player) { + return player.countCards("h", lib.skill.yuri_xingdong.filterCard); }, - filterCard(card){ - return card.name=='sha'||get.type(card)=='trick'; + filterCard(card) { + return card.name == "sha" || get.type(card) == "trick"; }, - check(card){return 1}, - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:0, - content(){ - 'step 0' - player.give(cards,target); - 'step 1' - if(!target.getCards('h').includes(cards[0])) event._result={bool:false}; - else target.chooseUseTarget(cards[0],game.filterPlayer(function(current){ - return current!=player; - }),'请使用得到的牌,或者跳过下回合的判定阶段和摸牌阶段'); - 'step 2' - if(result.bool) game.asyncDraw([player,target]); - else{ - target.addTempSkill('yuri_xingdong_mark','phaseJudgeSkipped'); - target.skip('phaseJudge'); - target.skip('phaseDraw'); - target.addTempSkill('zhengjing3',{player:'phaseAfter'}); + check(card) { + return 1; + }, + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: 0, + content() { + "step 0"; + player.give(cards, target); + "step 1"; + if (!target.getCards("h").includes(cards[0])) event._result = { bool: false }; + else + target.chooseUseTarget( + cards[0], + game.filterPlayer(function (current) { + return current != player; + }), + "请使用得到的牌,或者跳过下回合的判定阶段和摸牌阶段" + ); + "step 2"; + if (result.bool) game.asyncDraw([player, target]); + else { + target.addTempSkill("yuri_xingdong_mark", "phaseJudgeSkipped"); + target.skip("phaseJudge"); + target.skip("phaseDraw"); + target.addTempSkill("zhengjing3", { + player: "phaseAfter", + }); event.finish(); } - 'step 3' + "step 3"; game.delay(); }, - ai:{ - order:12, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(target.hasSkill('pingkou')) return 1; - if(!card) return 0; - var info=get.info(card); - if(info.selectTarget==-1){ - var eff=0; - game.countPlayer(function(current){ - if(current!=player&&target.canUse(card,current)) eff+=get.effect(current,card,target,target); + ai: { + order: 12, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (target.hasSkill("pingkou")) return 1; + if (!card) return 0; + var info = get.info(card); + if (info.selectTarget == -1) { + var eff = 0; + game.countPlayer(function (current) { + if (current != player && target.canUse(card, current)) + eff += get.effect(current, card, target, target); }); - if(eff>0||get.value(card)<3) return eff; + if (eff > 0 || get.value(card) < 3) return eff; return 0; - } - else if(game.hasPlayer(function(current){ - return current!=player&&target.canUse(card,current)&&get.effect(current,card,target,target)>0 - })) return 1.5; - else if(get.value(card)<3) return -1; + } else if ( + game.hasPlayer(function (current) { + return ( + current != player && + target.canUse(card, current) && + get.effect(current, card, target, target) > 0 + ); + }) + ) + return 1.5; + else if (get.value(card) < 3) return -1; return 0; }, }, }, }, - yuri_wangxi:{ - audio:2, - trigger:{global:'dieAfter'}, - limited:true, - mark:false, - init(player){ - if(player.hasZhuSkill('yuri_wangxi')){ - player.markSkill('yuri_wangxi'); - player.storage.yuri_wangxi=false; + yuri_wangxi: { + audio: 2, + trigger: { global: "dieAfter" }, + limited: true, + mark: false, + init(player) { + if (player.hasZhuSkill("yuri_wangxi")) { + player.markSkill("yuri_wangxi"); + player.storage.yuri_wangxi = false; } }, - zhuSkill:true, - unique:true, - skillAnimation:true, - animationColor:'thunder', - filter(event,player){ - if(get.mode()!='identity') return false; - if(!player.hasZhuSkill('yuri_wangxi')) return false; - if(event.player.isIn()) return false; - if(event.player.identity=='mingzhong') return false; - var evt=event.getParent('yuri_xingdong'); - return evt&&evt.name=='yuri_xingdong'&&evt.player==player; + zhuSkill: true, + unique: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + if (get.mode() != "identity") return false; + if (!player.hasZhuSkill("yuri_wangxi")) return false; + if (event.player.isIn()) return false; + if (event.player.identity == "mingzhong") return false; + var evt = event.getParent("yuri_xingdong"); + return evt && evt.name == "yuri_xingdong" && evt.player == player; }, - async cost(event, trigger, player){ - event.result = await trigger.player.chooseBool('是否发动'+get.translation(player)+'的【忘隙】?').set('forceDie', true).forResult(); + async cost(event, trigger, player) { + event.result = await trigger.player + .chooseBool("是否发动" + get.translation(player) + "的【忘隙】?") + .set("forceDie", true) + .forResult(); }, - logTarget:'player', - async content(event, trigger, player){ - player.awakenSkill('yuri_wangxi'); - var identity='zhong'; - if(_status.mode=='purple'){ - if(['rNei','bNei'].includes(player.identity)) identity = player.identity; - else if(['rZhu','rZhong','bNei'].includes(player.identity)) identity='rZhong'; - else identity='bZhong'; + logTarget: "player", + async content(event, trigger, player) { + player.awakenSkill("yuri_wangxi"); + var identity = "zhong"; + if (_status.mode == "purple") { + if (["rNei", "bNei"].includes(player.identity)) identity = player.identity; + else if (["rZhu", "rZhong", "bNei"].includes(player.identity)) identity = "rZhong"; + else identity = "bZhong"; } - game.broadcastAll(function(source,identity){ - if(source.node.dieidentity){ - source.node.dieidentity.innerHTML=get.translation(identity+2); - } - source.revive(2,false); - source.identity=identity; - source.setIdentity(); - },trigger.player,identity); - var evt=trigger.getParent('damage'); - if(evt.untrigger) evt.untrigger(false,trigger.player); - game.addVideo('setIdentity',trigger.player,'zhong'); + game.broadcastAll( + function (source, identity) { + if (source.node.dieidentity) { + source.node.dieidentity.innerHTML = get.translation(identity + 2); + } + source.revive(2, false); + source.identity = identity; + source.setIdentity(); + }, + trigger.player, + identity + ); + var evt = trigger.getParent("damage"); + if (evt.untrigger) evt.untrigger(false, trigger.player); + game.addVideo("setIdentity", trigger.player, "zhong"); await trigger.player.changeGroup(player.group); await trigger.player.draw(); }, }, - nk_shekong:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0; + nk_shekong: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - selectCard(){ - if(ui.selected.targets.length) return [1,ui.selected.targets[0].countCards('he')]; - return [1,Infinity]; + filterCard: true, + selectCard() { + if (ui.selected.targets.length) return [1, ui.selected.targets[0].countCards("he")]; + return [1, Infinity]; }, - filterTarget(event,player,target){ - return target!=player&&target.countCards('he')>=Math.max(1,ui.selected.cards.length); + filterTarget(event, player, target) { + return ( + target != player && target.countCards("he") >= Math.max(1, ui.selected.cards.length) + ); }, - check(card){ - if(!game.hasPlayer(function(current){ - return current!=_status.event.player&&get.attitude(_status.event.player,current)<0&¤t.countCards('he')>ui.selected.cards.length; - })) return 0; - return 6-get.value(card); + check(card) { + if ( + !game.hasPlayer(function (current) { + return ( + current != _status.event.player && + get.attitude(_status.event.player, current) < 0 && + current.countCards("he") > ui.selected.cards.length + ); + }) + ) + return 0; + return 6 - get.value(card); }, - content(){ - 'step 0' - event.cardsx=cards.slice(0); - var num=get.cnNumber(cards.length); - var trans=get.translation(player); - var prompt=('弃置'+num+'张牌,然后'+trans+'摸一张牌'); - if(cards.length>1) prompt+=(';或弃置一张牌,然后'+trans+'摸'+num+'张牌'); - var next=target.chooseToDiscard(prompt,'he',true); - next.numx=cards.length; - next.selectCard=function(){ - if(ui.selected.cards.length>1) return _status.event.numx; - return [1,_status.event.numx]; + content() { + "step 0"; + event.cardsx = cards.slice(0); + var num = get.cnNumber(cards.length); + var trans = get.translation(player); + var prompt = "弃置" + num + "张牌,然后" + trans + "摸一张牌"; + if (cards.length > 1) prompt += ";或弃置一张牌,然后" + trans + "摸" + num + "张牌"; + var next = target.chooseToDiscard(prompt, "he", true); + next.numx = cards.length; + next.selectCard = function () { + if (ui.selected.cards.length > 1) return _status.event.numx; + return [1, _status.event.numx]; }; - next.complexCard=true; - next.ai=function(card){ - if(ui.selected.cards.length==0||(_status.event.player.countCards('he',function(cardxq){ - return get.value(cardxq)<7; - })>=_status.event.numx)) return 7-get.value(card); + next.complexCard = true; + next.ai = function (card) { + if ( + ui.selected.cards.length == 0 || + _status.event.player.countCards("he", function (cardxq) { + return get.value(cardxq) < 7; + }) >= _status.event.numx + ) + return 7 - get.value(card); return -1; }; - 'step 1' - if(result.bool){ - if(result.cards.length==cards.length) player.draw(); + "step 1"; + if (result.bool) { + if (result.cards.length == cards.length) player.draw(); else player.draw(cards.length); event.cardsx.addArray(result.cards); - for(var i=0;i0; + lucia_zhenren: { + trigger: { global: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + filter(event, player) { + return player.countCards("e") > 0; }, - content(){ - 'step 0' - var es=player.getCards('e'); - event.count=es.length; + content() { + "step 0"; + var es = player.getCards("e"); + event.count = es.length; player.discard(es); - 'step 1' + "step 1"; event.count--; - if(game.hasPlayer(function(current){ - return current.countDiscardableCards(player,'ej')>0; - })){ - player.chooseTarget('请选择一名角色,弃置其装备区或判定区内的一张牌。',true,function(card,player,target){ - return target.countDiscardableCards(player,'ej')>0; - }).ai=function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countCards('j')&&att>0) return att*1.5; + if ( + game.hasPlayer(function (current) { + return current.countDiscardableCards(player, "ej") > 0; + }) + ) { + player.chooseTarget( + "请选择一名角色,弃置其装备区或判定区内的一张牌。", + true, + function (card, player, target) { + return target.countDiscardableCards(player, "ej") > 0; + } + ).ai = function (target) { + var att = get.attitude(_status.event.player, target); + if (target.countCards("j") && att > 0) return att * 1.5; return -att; }; - } - else event.finish(); - 'step 2' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,{color:[220, 90, 139]}); - player.discardPlayerCard(target,'ej',true); - if(event.count) event.goto(1); + } else event.finish(); + "step 2"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, { color: [220, 90, 139] }); + player.discardPlayerCard(target, "ej", true); + if (event.count) event.goto(1); } }, }, - noname_zhuyuan:{ - enable:"phaseUse", - position:"he", - selectCard:4, - complexCard:true, - charlotte:true, - prompt:"将4张花色各不同的牌交一名角色并令你与其获得【铁骑】和【激昂】直到各自回合结束", - check(card){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(ui.selected.cards.length>=Math.max(2,player.countCards('h')-player.hp)) return 0; - if(player.hp==player.maxHp||player.countCards('h')<=1){ - var players=game.filterPlayer(); - for(var i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + noname_zhuyuan: { + enable: "phaseUse", + position: "he", + selectCard: 4, + complexCard: true, + charlotte: true, + prompt: "将4张花色各不同的牌交一名角色并令你与其获得【铁骑】和【激昂】直到各自回合结束", + check(card) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + var player = get.owner(card); + if (ui.selected.cards.length >= Math.max(2, player.countCards("h") - player.hp)) return 0; + if (player.hp == player.maxHp || player.countCards("h") <= 1) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - filterCard(card,player){ - var suit=get.suit(card,player); - for(var i=0;i", - intro:{ - name:"小无·铁骑", - content:"你使用【杀】指定一名角色为目标后,可以进行一次判定并令该角色的非锁定技失效直到回合结束,除非该角色弃置一张与判定结果花色相同的牌,否则不能使用【闪】抵消此【杀】。", + noname_retieji: { + inherit: "retieji", + mark: true, + marktext: "", + intro: { + name: "小无·铁骑", + content: + "你使用【杀】指定一名角色为目标后,可以进行一次判定并令该角色的非锁定技失效直到回合结束,除非该角色弃置一张与判定结果花色相同的牌,否则不能使用【闪】抵消此【杀】。", }, }, - noname_jiang:{ - inherit:"jiang", - mark:true, - marktext:"", - intro:{ - name:"小无·激昂", - content:"每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。", + noname_jiang: { + inherit: "jiang", + mark: true, + marktext: "", + intro: { + name: "小无·激昂", + content: + "每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。", }, }, - noname_duocai:{ - trigger:{ - global:["loseAfter","loseAsyncAfter"], + noname_duocai: { + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - filter(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - var evt=event.getl(player); - var cards=event.cards.slice(0); - if(evt&&evt.cards) cards.removeArray(evt.cards); - return cards.filterInD('d').length>0&&!player.hasSkill('noname_duocai2'); + filter(event, player) { + if (event.type != "discard" || event.getlx === false) return false; + var evt = event.getl(player); + var cards = event.cards.slice(0); + if (evt && evt.cards) cards.removeArray(evt.cards); + return cards.filterInD("d").length > 0 && !player.hasSkill("noname_duocai2"); }, - direct:true, - charlotte:true, - content(){ - "step 0" - if(trigger.delay==false&&player!=game.me&&!player.isOnline()) game.delay(); - var evt=trigger.getl(player); - var cards=trigger.cards.slice(0); + direct: true, + charlotte: true, + content() { + "step 0"; + if (trigger.delay == false && player != game.me && !player.isOnline()) game.delay(); + var evt = trigger.getl(player); + var cards = trigger.cards.slice(0); cards.removeArray(evt.cards); - player.chooseButton([get.prompt('noname_duocai'),cards],[1,cards.length]); - "step 1" - if(result.bool){ - player.logSkill('noname_duocai'); - player.addTempSkill('noname_duocai2'); - player.gain(result.links,'gain2'); - if(result.links.length>2){ - var filterTarget=function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'hej')>0; + player.chooseButton([get.prompt("noname_duocai"), cards], [1, cards.length]); + "step 1"; + if (result.bool) { + player.logSkill("noname_duocai"); + player.addTempSkill("noname_duocai2"); + player.gain(result.links, "gain2"); + if (result.links.length > 2) { + var filterTarget = function (card, player, target) { + return target != player && target.countDiscardableCards(player, "hej") > 0; }; - if(game.hasPlayer(function(current){ - return filterTarget(null,player,current); - })){ - player.chooseTarget('弃置一名其他角色区域内的一张牌',true,filterTarget).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe'},player,player); - }); - } - else event.finish(); - } - else{ - if(result.links.length==2) player.draw(); + if ( + game.hasPlayer(function (current) { + return filterTarget(null, player, current); + }) + ) { + player + .chooseTarget("弃置一名其他角色区域内的一张牌", true, filterTarget) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe" }, player, player); + }); + } else event.finish(); + } else { + if (result.links.length == 2) player.draw(); else player.recover(); event.finish(); } - } - else event.finish(); - "step 2" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,'hej',true); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, "hej", true); } }, }, - noname_duocai2:{charlotte:true}, - nsbizhao:{ - trigger:{player:'showCharacterAfter'}, - forced:true, - hiddenSkill:true, - filter(event,player){ - return event.toShow&&event.toShow.includes('ns_yanghu')&&player!=_status.currentPhase; + noname_duocai2: { charlotte: true }, + nsbizhao: { + trigger: { player: "showCharacterAfter" }, + forced: true, + hiddenSkill: true, + filter(event, player) { + return ( + event.toShow && event.toShow.includes("ns_yanghu") && player != _status.currentPhase + ); }, - content(){ - player.addTempSkill('nsbizhao2',{player:'phaseBeginStart'}); + content() { + player.addTempSkill("nsbizhao2", { + player: "phaseBeginStart", + }); }, }, - nsbizhao2:{ - charlotte:true, - mark:true, - intro:{content:'其他角色至自己的距离+1'}, - mod:{ - globalTo(source,player,distance){ - return distance+1; + nsbizhao2: { + charlotte: true, + mark: true, + intro: { content: "其他角色至自己的距离+1" }, + mod: { + globalTo(source, player, distance) { + return distance + 1; }, }, }, - nsqingde:{ - trigger:{ - player:'damageEnd', - source:'damageSource', + nsqingde: { + trigger: { + player: "damageEnd", + source: "damageSource", }, - usable:1, - filter(event,player){ - if(!event.card||!event.cards||event.player==event.source||(event.card.name!='sha'&& - get.type(event.card)!='trick')||event.cards.filterInD().length!=1) return false; - var target=lib.skill.nsqingde.logTarget(event,player); - if(player.hasSkillTag('noCompareSource')||target.hasSkillTag('noCompareTarget')) return false; - return target.countCards('h')>0; + usable: 1, + filter(event, player) { + if ( + !event.card || + !event.cards || + event.player == event.source || + (event.card.name != "sha" && get.type(event.card) != "trick") || + event.cards.filterInD().length != 1 + ) + return false; + var target = lib.skill.nsqingde.logTarget(event, player); + if (player.hasSkillTag("noCompareSource") || target.hasSkillTag("noCompareTarget")) + return false; + return target.countCards("h") > 0; }, - logTarget(event,player){ - if(player==event.source) return event.player; + logTarget(event, player) { + if (player == event.source) return event.player; return event.source; }, - check(event,player){ - var target=lib.skill.nsqingde.logTarget(event,player); - return get.attitude(player,target)<=0; + check(event, player) { + var target = lib.skill.nsqingde.logTarget(event, player); + return get.attitude(player, target) <= 0; }, - content(){ - 'step 0' - var target=lib.skill.nsqingde.logTarget(trigger,player); - event.target=target - var next=player.chooseToCompare(target); - if(event.triggername=='damageSource') next.set('small',true); - if(!next.fixedResult) next.fixedResult={}; - next.fixedResult[player.playerid]=trigger.cards.filterInD()[0]; - 'step 1' - if(result.tie){ + content() { + "step 0"; + var target = lib.skill.nsqingde.logTarget(trigger, player); + event.target = target; + var next = player.chooseToCompare(target); + if (event.triggername == "damageSource") next.set("small", true); + if (!next.fixedResult) next.fixedResult = {}; + next.fixedResult[player.playerid] = trigger.cards.filterInD()[0]; + "step 1"; + if (result.tie) { event.finish(); return; } - var i=result.bool; - if(event.triggername=='damageSource') i=!i; - event.target2=i?player:target; - if(event.triggername=='damageSource') event.goto(3); - else if(event.target2.isDamaged()) player.chooseBool('是否令'+get.translation(event.target2)+'回复1点体力?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target2)>0; - }); + var i = result.bool; + if (event.triggername == "damageSource") i = !i; + event.target2 = i ? player : target; + if (event.triggername == "damageSource") event.goto(3); + else if (event.target2.isDamaged()) + player + .chooseBool("是否令" + get.translation(event.target2) + "回复1点体力?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target2) > 0; + }); else event.finish(); - 'step 2' - if(result.bool) event.target2.recover(); + "step 2"; + if (result.bool) event.target2.recover(); event.finish(); - 'step 3' - player.chooseBool('是否令'+get.translation(event.target2)+'摸两张牌?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target2)>0; - }); - 'step 4' - if(result.bool) event.target2.draw(2); + "step 3"; + player + .chooseBool("是否令" + get.translation(event.target2) + "摸两张牌?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target2) > 0; + }); + "step 4"; + if (result.bool) event.target2.draw(2); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(target.storage.counttrigger&&target.storage.counttrigger.nsqingde) return; - var num=get.number(card); - if(typeof num=='number'){ - if(target.hasSkillTag('noCompareSource')||player.hasSkillTag('noCompareTarget')) return; - var hs=player.getCards('h'); - if(card.cards) hs.removeArray(card.cards); - if(ui.selected.cards) hs.removeArray(ui.selected.cards); - if(!hs.length) return; - for(var i of hs){ - if(get.number(i)>=num) return; - if(player.hasSkill('tianbian')&&get.suit(card)=='heart') return; + ai: { + effect: { + target(card, player, target, current) { + if (target.storage.counttrigger && target.storage.counttrigger.nsqingde) return; + var num = get.number(card); + if (typeof num == "number") { + if ( + target.hasSkillTag("noCompareSource") || + player.hasSkillTag("noCompareTarget") + ) + return; + var hs = player.getCards("h"); + if (card.cards) hs.removeArray(card.cards); + if (ui.selected.cards) hs.removeArray(ui.selected.cards); + if (!hs.length) return; + for (var i of hs) { + if (get.number(i) >= num) return; + if (player.hasSkill("tianbian") && get.suit(card) == "heart") return; } - return 'zerotarget'; + return "zerotarget"; } }, }, }, }, - nsyidi:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0; + nsyidi: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - check(card){ - var player=_status.event.player; - if(get.type(card,player)=='basic'){ - if(game.hasPlayer(function(current){ - return get.attitude(current,player)>0&¤t.getUseValue(card)>player.getUseValue(card,null,true); - })) return 5+Math.random(); + filterCard: true, + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + check(card) { + var player = _status.event.player; + if (get.type(card, player) == "basic") { + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(current, player) > 0 && + current.getUseValue(card) > player.getUseValue(card, null, true) + ); + }) + ) + return 5 + Math.random(); return 0; } - if(game.hasPlayer(function(current){ - return get.attitude(current,player)>0&&!current.hasJudge('lebu')&¤t.getUseValue(card)>player.getUseValue(card); - })) return 4.7+Math.random(); - if(card.name=='wuxie'&&game.hasPlayer(function(current){ - return get.attitude(current,player)>0; - })) return 5+Math.random(); - return 4-get.value(card); + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(current, player) > 0 && + !current.hasJudge("lebu") && + current.getUseValue(card) > player.getUseValue(card) + ); + }) + ) + return 4.7 + Math.random(); + if ( + card.name == "wuxie" && + game.hasPlayer(function (current) { + return get.attitude(current, player) > 0; + }) + ) + return 5 + Math.random(); + return 4 - get.value(card); }, - content(){ - 'step 0' - player.give(cards,target,'visible'); - if(get.type(cards[0],player)!='basic'){ + content() { + "step 0"; + player.give(cards, target, "visible"); + if (get.type(cards[0], player) != "basic") { player.draw(); event.finish(); } - 'step 1' - if(target.getCards('h').includes(cards[0])&&target.hasUseTarget(cards[0])) target.chooseUseTarget(cards[0]); + "step 1"; + if (target.getCards("h").includes(cards[0]) && target.hasUseTarget(cards[0])) + target.chooseUseTarget(cards[0]); }, - ai:{ - order:7, - result:{ - player(player,target){ - if(!ui.selected.cards.length||get.type(ui.selected.cards[0],player)=='basic') return 0; - if(get.value(ui.selected.cards[0])<4) return 2; + ai: { + order: 7, + result: { + player(player, target) { + if ( + !ui.selected.cards.length || + get.type(ui.selected.cards[0], player) == "basic" + ) + return 0; + if (get.value(ui.selected.cards[0]) < 4) return 2; return 0.5; }, - target:1, + target: 1, }, }, }, - nsfuzhou:{ - enable:'phaseUse', - usable:2, - filter(event,player){ - if(!player.storage.nstaiping&&player.getStat('skill').nsfuzhou) return false; - return player.countCards('he',{color:'black'})>0; + nsfuzhou: { + enable: "phaseUse", + usable: 2, + filter(event, player) { + if (!player.storage.nstaiping && player.getStat("skill").nsfuzhou) return false; + return player.countCards("he", { color: "black" }) > 0; }, - filterCard:{color:'black'}, - filterTarget(card,player,target){ - return !target.hasJudge('nsfuzhou_card'); + filterCard: { color: "black" }, + filterTarget(card, player, target) { + return !target.hasJudge("nsfuzhou_card"); }, - check(card){ - return 8-get.value(card); + check(card) { + return 8 - get.value(card); }, - prepare:'give', - position:'he', - discard:false, - lose:false, - delay:false, - content(){ - 'step 0' - target.addJudge({name:'nsfuzhou_card'},cards[0]); - cards[0].storage.nsfuzhou_source=player; - 'step 1' + prepare: "give", + position: "he", + discard: false, + lose: false, + delay: false, + content() { + "step 0"; + target.addJudge({ name: "nsfuzhou_card" }, cards[0]); + cards[0].storage.nsfuzhou_source = player; + "step 1"; game.delayx(); }, - ai:{ - order:5, - result:{ - target(player,target){ - if(player.storage.nsfuzhou_draw){ - if(get.attitude(player,target)>0&&player.countCards('he',function(card){ - return get.color(card)=='red'; - })){ + ai: { + order: 5, + result: { + target(player, target) { + if (player.storage.nsfuzhou_draw) { + if ( + get.attitude(player, target) > 0 && + player.countCards("he", function (card) { + return get.color(card) == "red"; + }) + ) { return 1; } return 0; } - if(player.storage.nsfuzhou_damage) return -2; + if (player.storage.nsfuzhou_damage) return -2; return -1.5; }, }, }, }, - nsfuzhou_num:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard(player,num){ - return num+player.storage.nsfuzhou_num; + nsfuzhou_num: { + charlotte: true, + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.storage.nsfuzhou_num; }, }, - intro:{ - content(num){ - return '手牌上限'+(num<0?'':'+')+num; + intro: { + content(num) { + return "手牌上限" + (num < 0 ? "" : "+") + num; }, - } + }, }, - nsguidao:{ - trigger:{global:'judge'}, - filter(event,player){ - return player.countCards('hes',function(card){ - if(player.storage.nstaiping||(_status.connectMode&&get.position(card)!='e')) return true; - return get.color(card)=='black'; - })>0; + nsguidao: { + trigger: { global: "judge" }, + filter(event, player) { + return ( + player.countCards("hes", function (card) { + if ( + player.storage.nstaiping || + (_status.connectMode && get.position(card) != "e") + ) + return true; + return get.color(card) == "black"; + }) > 0 + ); }, - direct:true, - content(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('nsguidao'),'hes',function(card,player){ - if(!player.storage.nstaiping&&get.color(card)!='black') return false; - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result; - } - else{ - return -result; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','nsguidao','noOrdering'); - } - else{ + direct: true, + content() { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("nsguidao"), + "hes", + function (card, player) { + if (!player.storage.nstaiping && get.color(card) != "black") return false; + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result; + } else { + return -result; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "nsguidao", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); } - "step 3" + "step 3"; game.delay(2); }, - ai:{ - rejudge:true, - tag:{ - rejudge:1 - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, - nstaiping:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter(event,player){ - return player.getAllHistory('sourceDamage',function(evt){ - return evt.getParent().name=='nsfuzhou_card'; - }).length>1||player.getAllHistory('gain',function(evt){ - return evt.getParent(2).name=='nsfuzhou_card'; - }).length>1; + nstaiping: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + return ( + player.getAllHistory("sourceDamage", function (evt) { + return evt.getParent().name == "nsfuzhou_card"; + }).length > 1 || + player.getAllHistory("gain", function (evt) { + return evt.getParent(2).name == "nsfuzhou_card"; + }).length > 1 + ); }, - content(){ - player.awakenSkill('nstaiping'); - player.storage.nstaiping=true; - if(player.getAllHistory('sourceDamage',function(evt){ - return evt.getParent().name=='nsfuzhou_card'; - }).length>1) player.storage.nsfuzhou_damage=true; - if(player.getAllHistory('gain',function(evt){ - return evt.getParent(2).name=='nsfuzhou_card'; - }).length>1) player.storage.nsfuzhou_draw=true; + content() { + player.awakenSkill("nstaiping"); + player.storage.nstaiping = true; + if ( + player.getAllHistory("sourceDamage", function (evt) { + return evt.getParent().name == "nsfuzhou_card"; + }).length > 1 + ) + player.storage.nsfuzhou_damage = true; + if ( + player.getAllHistory("gain", function (evt) { + return evt.getParent(2).name == "nsfuzhou_card"; + }).length > 1 + ) + player.storage.nsfuzhou_draw = true; }, - derivation:['nsfuzhou_damage','nsfuzhou_draw'], + derivation: ["nsfuzhou_damage", "nsfuzhou_draw"], }, - nsweiyuan:{ - trigger:{player:'useCardToTargeted'}, - direct:true, - filter(event,player){ - return player!=event.target&&event.targets&&event.targets.length==1&&event.target.isIn() - &&player.isPhaseUsing()&&!player.hasSkill('nsweiyuan2')&&game.hasPlayer(function(current){ - return current!=player&¤t!=event.target; - }); + nsweiyuan: { + trigger: { player: "useCardToTargeted" }, + direct: true, + filter(event, player) { + return ( + player != event.target && + event.targets && + event.targets.length == 1 && + event.target.isIn() && + player.isPhaseUsing() && + !player.hasSkill("nsweiyuan2") && + game.hasPlayer(function (current) { + return current != player && current != event.target; + }) + ); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('nsweiyuan'),function(card,player,target){ - return target!=player&&target!=_status.event.getTrigger().target; - }).set('ai',function(target){ - return Math.max(Math.random(),get.attitude(player,target)); - }); - 'step 1' - if(result.bool){ - player.addTempSkill('nsweiyuan2','phaseUseAfter'); - var target=result.targets[0]; - event.target=target; - player.logSkill('nsweiyuan',target); - target.chooseCard('he','交给'+get.translation(trigger.target)+'一张牌并受到1点伤害,或令'+get.translation(player)+'摸一张牌且可以重复使用牌').set('ai',function(card){ - if(_status.event.goon) return Math.random(); - return 0; - }).set('goon',function(){ - if(get.attitude(target,player)>0) return false; - return Math.random()>0.5; - }()); - } - else event.finish(); - 'step 2' - if(result.bool){ - target.gain(result.cards,trigger.target); + content() { + "step 0"; + player + .chooseTarget(get.prompt2("nsweiyuan"), function (card, player, target) { + return target != player && target != _status.event.getTrigger().target; + }) + .set("ai", function (target) { + return Math.max(Math.random(), get.attitude(player, target)); + }); + "step 1"; + if (result.bool) { + player.addTempSkill("nsweiyuan2", "phaseUseAfter"); + var target = result.targets[0]; + event.target = target; + player.logSkill("nsweiyuan", target); + target + .chooseCard( + "he", + "交给" + + get.translation(trigger.target) + + "一张牌并受到1点伤害,或令" + + get.translation(player) + + "摸一张牌且可以重复使用牌" + ) + .set("ai", function (card) { + if (_status.event.goon) return Math.random(); + return 0; + }) + .set( + "goon", + (function () { + if (get.attitude(target, player) > 0) return false; + return Math.random() > 0.5; + })() + ); + } else event.finish(); + "step 2"; + if (result.bool) { + target.gain(result.cards, trigger.target); target.damage(); - } - else{ - player.addTempSkill('nsweiyuan_use'); + } else { + player.addTempSkill("nsweiyuan_use"); player.draw(); } }, }, - nsweiyuan2:{charlotte:true}, - nsweiyuan_use_backup:{}, - nsweiyuan_use:{ - enable:'phaseUse', - charlotte:true, - mod:{ - cardUsable(){ - if(_status.event.skill=='nsweiyuan_use_backup') return Infinity; + nsweiyuan2: { charlotte: true }, + nsweiyuan_use_backup: {}, + nsweiyuan_use: { + enable: "phaseUse", + charlotte: true, + mod: { + cardUsable() { + if (_status.event.skill == "nsweiyuan_use_backup") return Infinity; }, - targetInRange(){ - if(_status.event.skill=='nsweiyuan_use_backup') return true; + targetInRange() { + if (_status.event.skill == "nsweiyuan_use_backup") return true; }, }, - onChooseToUse(event){ - if(game.online||event.type!='phase') return; - var list=[]; - event.player.getHistory('useCard',function(evt){ - var name=evt.card.name; - var type=get.type(name); - if(type!='basic'&&type!='trick') return; - if(name=='sha'){ - var nature=evt.card.nature; - switch(nature){ - case 'fire':name='huosha';break; - case 'thunder':name='leisha';break; - case 'kami':name='kamisha';break; - case 'ice':name='icesha';break; + onChooseToUse(event) { + if (game.online || event.type != "phase") return; + var list = []; + event.player.getHistory("useCard", function (evt) { + var name = evt.card.name; + var type = get.type(name); + if (type != "basic" && type != "trick") return; + if (name == "sha") { + var nature = evt.card.nature; + switch (nature) { + case "fire": + name = "huosha"; + break; + case "thunder": + name = "leisha"; + break; + case "kami": + name = "kamisha"; + break; + case "ice": + name = "icesha"; + break; } } - list.add(type+'咕咕'+name); + list.add(type + "咕咕" + name); }); - event.set('nsweiyuan_list',list); + event.set("nsweiyuan_list", list); }, - filter(event,player){ - return player.countCards('h')>0&&event.nsweiyuan_list&&event.nsweiyuan_list.length>0; + filter(event, player) { + return ( + player.countCards("h") > 0 && event.nsweiyuan_list && event.nsweiyuan_list.length > 0 + ); }, - chooseButton:{ - dialog(event,player){ - return ui.create.dialog('围援',[event.nsweiyuan_list.map(function(i){ - return i.split('咕'); - }),'vcard']); + chooseButton: { + dialog(event, player) { + return ui.create.dialog("围援", [ + event.nsweiyuan_list.map(function (i) { + return i.split("咕"); + }), + "vcard", + ]); }, - filter(button,player){ - return lib.filter.cardEnabled({ - name:button.link[2], - nature:button.link[3], - },player); + filter(button, player) { + return lib.filter.cardEnabled( + { + name: button.link[2], + nature: button.link[3], + }, + player + ); }, - check(button){ - return _status.event.player.getUseValue({ - name:button.link[2], - nature:button.link[3], - },false); + check(button) { + return _status.event.player.getUseValue( + { + name: button.link[2], + nature: button.link[3], + }, + false + ); }, - backup(links,player){ + backup(links, player) { return { - popname:true, - position:'h', - filterCard:true, - ai1(card){ - return 7-get.value(card); + popname: true, + position: "h", + filterCard: true, + ai1(card) { + return 7 - get.value(card); }, - viewAs:{ - name:links[0][2], - nature:links[0][3], + viewAs: { + name: links[0][2], + nature: links[0][3], }, - onuse(links,player){ - player.removeSkill('nsweiyuan_use'); + onuse(links, player) { + player.removeSkill("nsweiyuan_use"); }, - } + }; }, - prompt(links,player){ - return '将一张手牌当做'+get.translation(links[0][3]||'')+get.translation(links[0][2])+'使用'; + prompt(links, player) { + return ( + "将一张手牌当做" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - order:1, - result:{ - player:1, + ai: { + order: 1, + result: { + player: 1, }, }, }, - nsjuxian:{ - trigger:{player:'damageBegin2'}, - filter(event,player){ - return !player.hasSkill('nsjuxian2'); + nsjuxian: { + trigger: { player: "damageBegin2" }, + filter(event, player) { + return !player.hasSkill("nsjuxian2"); }, - check(event,player){ - if(player.countCards('h')+2>=player.maxHp) return !event.source||!event.source.countCards('he')||get.attitude(player,event.source)>0; + check(event, player) { + if (player.countCards("h") + 2 >= player.maxHp) + return ( + !event.source || + !event.source.countCards("he") || + get.attitude(player, event.source) > 0 + ); return true; }, - content(){ - 'step 0' - player.addSkill('nsjuxian2'); + content() { + "step 0"; + player.addSkill("nsjuxian2"); player.draw(2); - 'step 1' - var target=trigger.source; - if(player.countCards('h')>=player.maxHp&&target&&target.countCards('he')){ - player.line(target,'green'); - target.chooseToDiscard('he',true); + "step 1"; + var target = trigger.source; + if (player.countCards("h") >= player.maxHp && target && target.countCards("he")) { + player.line(target, "green"); + target.chooseToDiscard("he", true); } }, }, - nsjuxian2:{ - trigger:{player:'phaseDrawBefore'}, - forced:true, - charlotte:true, - content(){ - player.removeSkill('nsjuxian2'); + nsjuxian2: { + trigger: { player: "phaseDrawBefore" }, + forced: true, + charlotte: true, + content() { + player.removeSkill("nsjuxian2"); trigger.cancel(); - game.log(player,'跳过了','#y摸牌阶段'); + game.log(player, "跳过了", "#y摸牌阶段"); }, }, - nsdiewu:{ - trigger:{ - player:['damageEnd','gainAfter'], - global:'loseAsyncAfter', + nsdiewu: { + trigger: { + player: ["damageEnd", "gainAfter"], + global: "loseAsyncAfter", }, - forced:true, - locked:false, - filter(event,player){ - if(event.name!='damage') return event.getg(player).length>1; + forced: true, + locked: false, + filter(event, player) { + if (event.name != "damage") return event.getg(player).length > 1; return true; }, - content(){ - player.addMark('nsdiewu',1); + content() { + player.addMark("nsdiewu", 1); }, - intro:{ - content:'mark', + intro: { + content: "mark", }, - group:['nsdiewu_sha','nsdiewu_shan','nsdiewu_draw'], - subSkill:{ - sha:{ - enable:'chooseToUse', - viewAs:{name:'sha',isCard:true}, - prompt:'视为使用一张【杀】', - viewAsFilter(player){ - return player.countMark('nsdiewu')>0; + group: ["nsdiewu_sha", "nsdiewu_shan", "nsdiewu_draw"], + subSkill: { + sha: { + enable: "chooseToUse", + viewAs: { name: "sha", isCard: true }, + prompt: "视为使用一张【杀】", + viewAsFilter(player) { + return player.countMark("nsdiewu") > 0; }, - filterCard:()=>false, - selectCard:-1, - onuse(links,player){ - player.removeMark('nsdiewu',1); + filterCard: () => false, + selectCard: -1, + onuse(links, player) { + player.removeMark("nsdiewu", 1); }, - ai:{ - order(){ - var player=_status.event.player; - if(!player.storage.nspojian&&player.countMark('nsdiewu')<=player.hp) return 0; - return get.order({name:'sha'})+0.1; + ai: { + order() { + var player = _status.event.player; + if (!player.storage.nspojian && player.countMark("nsdiewu") <= player.hp) + return 0; + return get.order({ name: "sha" }) + 0.1; }, }, }, - shan:{ - enable:'chooseToUse', - viewAs:{name:'shan',isCard:true}, - viewAsFilter(player){ - return player.countMark('nsdiewu')>0&&!player.storage.nspojian; + shan: { + enable: "chooseToUse", + viewAs: { name: "shan", isCard: true }, + viewAsFilter(player) { + return player.countMark("nsdiewu") > 0 && !player.storage.nspojian; }, - filterCard:()=>false, - selectCard:-1, - onuse(links,player){ - player.removeMark('nsdiewu',1); + filterCard: () => false, + selectCard: -1, + onuse(links, player) { + player.removeMark("nsdiewu", 1); }, - ai:{ - order(){ - var player=_status.event.player; - if(player.hp>1&&player.countMark('nsdiewu')<=player.hp) return 0; - return get.order({name:'shan'})-0.2; + ai: { + order() { + var player = _status.event.player; + if (player.hp > 1 && player.countMark("nsdiewu") <= player.hp) return 0; + return get.order({ name: "shan" }) - 0.2; }, }, }, - draw:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - filter(event,player){ - var evt=event.getParent(); - return evt&&evt.type=='card'&&evt.skill=='nsdiewu_sha'; + draw: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + filter(event, player) { + var evt = event.getParent(); + return evt && evt.type == "card" && evt.skill == "nsdiewu_sha"; }, - content(){ + content() { player.draw(); }, }, }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ - if(tag=='respondShan'&&player.storage.nspojian) return false; - return player.countMark('nsdiewu')>0; + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { + if (tag == "respondShan" && player.storage.nspojian) return false; + return player.countMark("nsdiewu") > 0; }, }, }, - nslingying:{ - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+1; + nslingying: { + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + 1; }, - targetInRange(card){ - if(card.name=='sha') return true; + targetInRange(card) { + if (card.name == "sha") return true; }, }, }, - nspojian:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'fire', - filter(event,player){ - return player.countMark('nsdiewu')>=player.hp; + nspojian: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "fire", + filter(event, player) { + return player.countMark("nsdiewu") >= player.hp; }, - content(){ - player.awakenSkill('nspojian'); - player.storage.nspojian=true; + content() { + player.awakenSkill("nspojian"); + player.storage.nspojian = true; player.loseMaxHp(); player.draw(2); - player.addSkill('nsliegong'); + player.addSkill("nsliegong"); }, - derivation:'nsliegong', - }, - nsliegong:{ - inherit:'xinliegong', - }, - nsguolie:{ - trigger:{player:'phaseDrawBefore'}, - check(event,player){ - var h1=player.getUseValue({name:'sha'},false); - var h2=player.getUseValue({name:'guohe'}); - return player.countCards('h',function(card){ - if(get.color(card)=='red') return h1>0; - return h2>0; - })>2; + derivation: "nsliegong", + ai: { + combo: "nsdiewu" }, - content(){ + }, + nsliegong: { + inherit: "xinliegong", + }, + nsguolie: { + trigger: { player: "phaseDrawBefore" }, + check(event, player) { + var h1 = player.getUseValue({ name: "sha" }, false); + var h2 = player.getUseValue({ name: "guohe" }); + return ( + player.countCards("h", function (card) { + if (get.color(card) == "red") return h1 > 0; + return h2 > 0; + }) > 2 + ); + }, + content() { trigger.cancel(); - player.addTempSkill('nsguolie2'); + player.addTempSkill("nsguolie2"); }, }, - nsguolie2:{ - mod:{ - cardname(card,player){ - var color=get.color(card,player); - if(color=='red') return 'sha'; - if(color=='black') return 'guohe'; + nsguolie2: { + mod: { + cardname(card, player) { + var color = get.color(card, player); + if (color == "red") return "sha"; + if (color == "black") return "guohe"; }, - cardnature(){ + cardnature() { return false; }, - cardUsable(){ + cardUsable() { return Infinity; }, - targetInRange(){ + targetInRange() { return true; }, }, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter(event,player){ - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.player==player) return; - for(var i of evt.cards){ - if(get.position(i,true)=='d') cards.push(i); + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter(event, player) { + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.player == player) return; + for (var i of evt.cards) { + if (get.position(i, true) == "d") cards.push(i); } }); - return cards.length>0; + return cards.length > 0; }, - content(){ - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.player==player) return; - if(evt.name=='cardsDiscard'&&evt.parent.name=='orderingDiscard') return; - for(var i of evt.cards){ - if(get.position(i,true)=='d') cards.push(i); + content() { + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.player == player) return; + if (evt.name == "cardsDiscard" && evt.parent.name == "orderingDiscard") return; + for (var i of evt.cards) { + if (get.position(i, true) == "d") cards.push(i); } }); - player.gain(cards,'gain2'); + player.gain(cards, "gain2"); }, }, - nslongyue:{ - init:()=>{ - game.addGlobalSkill('nslongyue_ai'); + nslongyue: { + init: () => { + game.addGlobalSkill("nslongyue_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('nslongyue'),true)) game.removeGlobalSkill('nslongyue_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("nslongyue"), true)) + game.removeGlobalSkill("nslongyue_ai"); }, - trigger:{global:'useCard'}, - filter(event,player){ - return get.type(event.card,'trick')=='trick'&&event.player.getHistory('useCard').indexOf(event)==0; + trigger: { global: "useCard" }, + filter(event, player) { + return ( + get.type(event.card, "trick") == "trick" && + event.player.getHistory("useCard").indexOf(event) == 0 + ); }, - logTarget:'player', - check(event,player){ - return get.attitude(player,event.player)>0; + logTarget: "player", + check(event, player) { + return get.attitude(player, event.player) > 0; }, - content(){ + content() { trigger.player.draw(); }, - ai:{ - expose:0.2, - } + ai: { + expose: 0.2, + }, }, - nslongyue_ai:{ - mod:{ - aiOrder(player,card,num){ - if(!player.getHistory('useCard').length&&get.type(card)=='trick'&&game.hasPlayer(function(current){ - return current.hasSkill('nslongyue')&&get.attitude(player,current)>=0; - })) return num+6; + nslongyue_ai: { + mod: { + aiOrder(player, card, num) { + if ( + !player.getHistory("useCard").length && + get.type(card) == "trick" && + game.hasPlayer(function (current) { + return current.hasSkill("nslongyue") && get.attitude(player, current) >= 0; + }) + ) + return num + 6; }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('nslongyue'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("nslongyue"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("nslongyue_ai"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('nslongyue_ai'); - } }, - nszhenyin:{ - trigger:{global:'judge'}, - usable:1, - filter(event,player){ - return _status.currentPhase&&_status.currentPhase.countCards('h')>0; + nszhenyin: { + trigger: { global: "judge" }, + usable: 1, + filter(event, player) { + return _status.currentPhase && _status.currentPhase.countCards("h") > 0; }, - logTarget(){ + logTarget() { return _status.currentPhase; }, - check(event,player){ - var target=_status.currentPhase; - var judge=event.judge(event.player.judging[0]); - var max=0; - var hs=target.getCards('h',function(card){ - var mod2=game.checkMod(card,target,'unchanged','cardEnabled2',target); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,target,'unchanged','cardRespondable',target); - if(mod!='unchanged') return mod; + check(event, player) { + var target = _status.currentPhase; + var judge = event.judge(event.player.judging[0]); + var max = 0; + var hs = target.getCards("h", function (card) { + var mod2 = game.checkMod(card, target, "unchanged", "cardEnabled2", target); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, target, "unchanged", "cardRespondable", target); + if (mod != "unchanged") return mod; return true; }); - for(var i of hs){ - var num=event.judge(i)-judge; - if(num>max) max=num; + for (var i of hs) { + var num = event.judge(i) - judge; + if (num > max) max = num; } - var att=get.attitude(player,target); - if(att>0) return max>0; - if(att<0) return max<=0; + var att = get.attitude(player, target); + if (att > 0) return max > 0; + if (att < 0) return max <= 0; return false; }, - content(){ - "step 0" - if(!_status.currentPhase.countCards('h',function(card){ - var player=_status.currentPhase; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - })){ + content() { + "step 0"; + if ( + !_status.currentPhase.countCards("h", function (card) { + var player = _status.currentPhase; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + }) + ) { event.finish(); return; } - _status.currentPhase.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+',请打出一张手牌进行改判','h',true,function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result/Math.max(0.1,get.value(card)); - } - else{ - return -result/Math.max(0.1,get.value(card)); - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - _status.currentPhase.respond(result.cards,'highlight').nopopup=true; - } - else{ + _status.currentPhase + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + ",请打出一张手牌进行改判", + "h", + true, + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result / Math.max(0.1, get.value(card)); + } else { + return -result / Math.max(0.1, get.value(card)); + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + _status.currentPhase.respond(result.cards, "highlight").nopopup = true; + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, - nsxianhai:{ - trigger:{global:'damageSource'}, - filter(event,player){ - return event.source&&event.source!=player&&event.source.isIn()&&event.source==_status.currentPhase&& - (event.source.getStat('damage')||0)>(player.getLastStat('damage')||0)&& - !player.hasSkill('nsxianhai_round'); + nsxianhai: { + trigger: { global: "damageSource" }, + filter(event, player) { + return ( + event.source && + event.source != player && + event.source.isIn() && + event.source == _status.currentPhase && + (event.source.getStat("damage") || 0) > (player.getLastStat("damage") || 0) && + !player.hasSkill("nsxianhai_round") + ); }, - check(event,player){ - return player.maxHp>1&&get.attitude(player,event.source)<-4; + check(event, player) { + return player.maxHp > 1 && get.attitude(player, event.source) < -4; }, - logTarget:'source', - content(){ - 'step 0' - player.addTempSkill('nsxianhai_round','roundStart'); + logTarget: "source", + content() { + "step 0"; + player.addTempSkill("nsxianhai_round", "roundStart"); player.loseMaxHp(); - var list=[]; - for(var i=1;i<6;i++){ - if(trigger.source.hasEnabledSlot(i)) list.add('equip'+((i==3||i==4)?'3_4':i)); + var list = []; + for (var i = 1; i < 6; i++) { + if (trigger.source.hasEnabledSlot(i)) + list.add("equip" + (i == 3 || i == 4 ? "3_4" : i)); } - if(list.length){ - player.chooseControl(list).set('prompt','选择废除'+get.translation(trigger.source)+'的一种装备栏').set('ai',function(){ - var target=_status.event.getTrigger().source; - if(list.includes('equip6')&&target.getEquip('equip3')&&target.getEquip('equip4')) return 'equip6'; - if(list.includes('equip2')&&target.getEquip(2)&&get.value(target.getEquip(2),target)>0) return 'equip2'; - if(list.includes('equip5')&&target.getEquip(5)&&get.value(target.getEquip(5),target)>0) return 'equip5'; - return 0; - }); + if (list.length) { + player + .chooseControl(list) + .set("prompt", "选择废除" + get.translation(trigger.source) + "的一种装备栏") + .set("ai", function () { + var target = _status.event.getTrigger().source; + if ( + list.includes("equip6") && + target.getEquip("equip3") && + target.getEquip("equip4") + ) + return "equip6"; + if ( + list.includes("equip2") && + target.getEquip(2) && + get.value(target.getEquip(2), target) > 0 + ) + return "equip2"; + if ( + list.includes("equip5") && + target.getEquip(5) && + get.value(target.getEquip(5), target) > 0 + ) + return "equip5"; + return 0; + }); + } else event.goto(2); + "step 1"; + if (result.control != "equip3_4") trigger.source.disableEquip(result.control); + else { + trigger.source.disableEquip(3, 4); } - else event.goto(2); - 'step 1' - if(result.control!='equip3_4') trigger.source.disableEquip(result.control); - else{ - trigger.source.disableEquip(3,4); - } - 'step 2' - if(player.awakenedSkills.includes('nsxingchu')){ - var next=game.createEvent('nsxianhai_clear'); + "step 2"; + if (player.awakenedSkills.includes("nsxingchu")) { + var next = game.createEvent("nsxianhai_clear"); event.next.remove(next); - event.getParent('phase').after.push(next); - next.player=player; - next.setContent(function(){ - player.restoreSkill('nsxingchu'); + event.getParent("phase").after.push(next); + next.player = player; + next.setContent(function () { + player.restoreSkill("nsxingchu"); }); } - 'step 3' - if(trigger.source){ - var hs=trigger.source.getCards('h','shan'); - if(hs.length) trigger.source.discard(hs); + "step 3"; + if (trigger.source) { + var hs = trigger.source.getCards("h", "shan"); + if (hs.length) trigger.source.discard(hs); } }, }, - nsxianhai_round:{charlotte:true}, - nsxingchu:{ - trigger:{global:'die'}, - forceDie:true, - filter(event,player){ - return player==event.player||player==event.source; + nsxianhai_round: { charlotte: true }, + nsxingchu: { + trigger: { global: "die" }, + forceDie: true, + filter(event, player) { + return player == event.player || player == event.source; }, - limited:true, - skillAnimation:true, - animationColor:'wood', - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('nsxingchu')).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('forceDie',true); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('nsxingchu',target); - player.awakenSkill('nsxingchu'); - var he=trigger.player.getCards('he'); - if(he.length) target.gain(he,trigger.player,'giveAuto','bySelf'); + limited: true, + skillAnimation: true, + animationColor: "wood", + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("nsxingchu")) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("forceDie", true); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("nsxingchu", target); + player.awakenSkill("nsxingchu"); + var he = trigger.player.getCards("he"); + if (he.length) target.gain(he, trigger.player, "giveAuto", "bySelf"); target.gainMaxHp(); } }, }, - nsshengyan:{ - trigger:{player:'judgeEnd'}, - forced:true, - filter(event,player){ - return _status.currentPhase&&_status.currentPhase.isIn()&&(!player.storage.nsshengyan2||!player.storage.nsshengyan2.includes(event.result.suit)); + nsshengyan: { + trigger: { player: "judgeEnd" }, + forced: true, + filter(event, player) { + return ( + _status.currentPhase && + _status.currentPhase.isIn() && + (!player.storage.nsshengyan2 || + !player.storage.nsshengyan2.includes(event.result.suit)) + ); }, - logTarget(){ + logTarget() { return _status.currentPhase; }, - content(){ - player.addTempSkill('nsshengyan2'); - if(!player.storage.nsshengyan2) player.storage.nsshengyan2=[]; - _status.currentPhase.addTempSkill('nsshengyan3'); + content() { + player.addTempSkill("nsshengyan2"); + if (!player.storage.nsshengyan2) player.storage.nsshengyan2 = []; + _status.currentPhase.addTempSkill("nsshengyan3"); player.storage.nsshengyan2.add(trigger.result.suit); - _status.currentPhase.addMark('nsshengyan3',2,false); + _status.currentPhase.addMark("nsshengyan3", 2, false); }, }, - nsshengyan2:{onremove:true}, - nsshengyan3:{ - mod:{ - maxHandcard(player,num){ - return num+player.countMark('nsshengyan3'); + nsshengyan2: { onremove: true }, + nsshengyan3: { + mod: { + maxHandcard(player, num) { + return num + player.countMark("nsshengyan3"); }, }, - onremove:true, - intro:{ - content:'本回合手牌上限+#', + onremove: true, + intro: { + content: "本回合手牌上限+#", }, - marktext:'筵', + marktext: "筵", }, - nsdaizhan:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter(event,player){ - return (!player.hasJudge('lebu')||!player.hasJudge('bingliang'))&&player.countCards('he',function(card){ - if(_status.connectMode) return true; - return get.type(card,'trick')!='trick'; - }); + nsdaizhan: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter(event, player) { + return ( + (!player.hasJudge("lebu") || !player.hasJudge("bingliang")) && + player.countCards("he", function (card) { + if (_status.connectMode) return true; + return get.type(card, "trick") != "trick"; + }) + ); }, - content(){ - var next=player.chooseToUse(); - next.set('norestore',true); - next.set('_backupevent','nsdaizhanx'); - next.set('custom',{ - add:{}, - replace:{window(){}} + content() { + var next = player.chooseToUse(); + next.set("norestore", true); + next.set("_backupevent", "nsdaizhanx"); + next.set("custom", { + add: {}, + replace: { window() {} }, }); - next.backup('nsdaizhanx'); + next.backup("nsdaizhanx"); }, }, - nsdaizhanx:{ - chooseButton:{ - dialog(){ - var list=['lebu','bingliang']; - var list2=[]; - for(var i of list){ - list2.push(['延时锦囊','',i]); + nsdaizhanx: { + chooseButton: { + dialog() { + var list = ["lebu", "bingliang"]; + var list2 = []; + for (var i of list) { + list2.push(["延时锦囊", "", i]); } - return ui.create.dialog(get.prompt('nsdaizhan'),[list2,'vcard'],'hidden'); + return ui.create.dialog(get.prompt("nsdaizhan"), [list2, "vcard"], "hidden"); }, - filter(button,player){ - return !player.hasJudge(button.link[2]) + filter(button, player) { + return !player.hasJudge(button.link[2]); }, - check(button){ - if(button.link[2]=='lebu') return 0; - var player=_status.event.player; - var delta=player.getHandcardLimit()+player.countCards('j')*2+2-player.hp; - if(delta>=2) return 1+Math.random(); - if(delta>=0&&!player.countCards('h',function(card){ - return player.hasValueTarget(card); - })) return Math.random(); + check(button) { + if (button.link[2] == "lebu") return 0; + var player = _status.event.player; + var delta = player.getHandcardLimit() + player.countCards("j") * 2 + 2 - player.hp; + if (delta >= 2) return 1 + Math.random(); + if ( + delta >= 0 && + !player.countCards("h", function (card) { + return player.hasValueTarget(card); + }) + ) + return Math.random(); return 0; }, - backup(links,player){ + backup(links, player) { return { - filterCard(card,player){ - return get.itemtype(card)=='card'&&get.type(card,'trick')!='trick'&&player.canAddJudge({name:links[0][2],cards:[card]}); + filterCard(card, player) { + return ( + get.itemtype(card) == "card" && + get.type(card, "trick") != "trick" && + player.canAddJudge({ + name: links[0][2], + cards: [card], + }) + ); }, - filterTarget(card,player,target){ - return player==target; + filterTarget(card, player, target) { + return player == target; }, - check(card){ - return 8-get.value(card); + check(card) { + return 8 - get.value(card); }, - viewAs:{name:links[0][2]}, - position:'he', - precontent(){ - player.addTempSkill('nsdaizhany'); - event.result.skill='nsdaizhan'; + viewAs: { name: links[0][2] }, + position: "he", + precontent() { + player.addTempSkill("nsdaizhany"); + event.result.skill = "nsdaizhan"; }, - ai:{ - result:{ - target:1, + ai: { + result: { + target: 1, }, }, }; }, - prompt(links){ - return '将一张牌当做'+get.translation(links[0][2])+'对自己使用'; + prompt(links) { + return "将一张牌当做" + get.translation(links[0][2]) + "对自己使用"; }, }, }, - nsdaizhany:{ - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - filter(event,player){ - return player.countCards('h')0; + direct: true, + filter(event, player, name) { + var target = name == "damageSource" ? event.source : event.player; + return ( + target && + target != player && + get.distance(player, target) <= 1 && + target.countCards("hej") > 0 + ); }, - locked(skill,player){ - return player&&player.storage.nsfuwei; + locked(skill, player) { + return player && player.storage.nsfuwei; }, - content(){ - 'step 0' - var target=(event.triggername=='damageSource'?trigger.source:trigger.player); - event.target=target; - player.choosePlayerCard(target,'hej',player.storage.nsfuwei?true:1).set('ai',function(button){ - var val=get.buttonValue(button); - if(get.attitude(_status.event.player,get.owner(button.link))>0) return -val; - return val; - }); - 'step 1' - if(result.bool){ - player.logSkill('nsjiquan',target); - player.addToExpansion(result.cards,target,'give').gaintag.add('nsjiquan_mark'); - } - else event.finish(); - 'step 2' + content() { + "step 0"; + var target = event.triggername == "damageSource" ? trigger.source : trigger.player; + event.target = target; + player + .choosePlayerCard(target, "hej", player.storage.nsfuwei ? true : 1) + .set("ai", function (button) { + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, get.owner(button.link)) > 0) return -val; + return val; + }); + "step 1"; + if (result.bool) { + player.logSkill("nsjiquan", target); + player.addToExpansion(result.cards, target, "give").gaintag.add("nsjiquan_mark"); + } else event.finish(); + "step 2"; game.delayx(); }, - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.getExpansions('nsjiquan_mark').length; + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.getExpansions("nsjiquan_mark").length; }, }, }, - nsjiquan_mark:{ - intro:{ - content:'expansion', - markcount:'expansion', + nsjiquan_mark: { + intro: { + content: "expansion", + markcount: "expansion", }, - marktext:'威', + marktext: "威", }, - nsfuwei:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter(event,player){ - return player.getExpansions('nsjiquan_mark').length>4; + nsfuwei: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + return player.getExpansions("nsjiquan_mark").length > 4; }, - content(){ - player.awakenSkill('nsfuwei'); - player.storage.nsfuwei=true; - player.addSkill('nsdiemou'); - player.addSkill('nszhihuang'); + content() { + player.awakenSkill("nsfuwei"); + player.storage.nsfuwei = true; + player.addSkill("nsdiemou"); + player.addSkill("nszhihuang"); player.gainMaxHp(2); }, - derivation:['nsdiemou','nszhihuang'], - }, - nsdiemou:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - filter(event,player){ - return player.getExpansions('nsjiquan_mark').length>game.players.length; + derivation: ["nsdiemou", "nszhihuang"], + ai: { + combo: "nsjiquan" }, - content(){ - var cards=player.getExpansions('nsjiquan_mark'); + }, + nsdiemou: { + trigger: { player: "phaseUseBegin" }, + forced: true, + filter(event, player) { + return player.getExpansions("nsjiquan_mark").length > game.players.length; + }, + content() { + var cards = player.getExpansions("nsjiquan_mark"); player.draw(cards.length); player.loseMaxHp(); player.loseToDiscardpile(cards); - if(cards.length>4) player.turnOver(); + if (cards.length > 4) player.turnOver(); + }, + ai: { + combo: "nsjiquan" }, }, - nszhihuang:{ - group:'nszhihuang_damage', - trigger:{global:'useCard'}, - usable:1, - filter(event,player){ - return event.player==get.zhu(player)&&player.getExpansions('nsjiquan_mark').length>0&&event.cards&&event.cards.filterInD().length>0; + nszhihuang: { + group: "nszhihuang_damage", + trigger: { global: "useCard" }, + usable: 1, + filter(event, player) { + return ( + event.player == get.zhu(player) && + player.getExpansions("nsjiquan_mark").length > 0 && + event.cards && + event.cards.filterInD().length > 0 + ); }, - prompt2(event){ - return '移去一张“威”并获得'+get.translation(event.cards.filterInD()); + prompt2(event) { + return "移去一张“威”并获得" + get.translation(event.cards.filterInD()); }, - check(event,player){ - if(['equip','delay'].includes(get.type(event.card))) return get.attitude(player,event.player)<0; - return get.value(event.cards.filterInD())>0; + check(event, player) { + if (["equip", "delay"].includes(get.type(event.card))) + return get.attitude(player, event.player) < 0; + return get.value(event.cards.filterInD()) > 0; }, - logTarget:'player', - content(){ - 'step 0' - var cards=player.getExpansions('nsjiquan_mark'); - if(cards.length==1) event._result={ - bool:true, - links:cards.slice(0), - } - else player.chooseButton(['选择移去一张“威”',cards],true); - 'step 1' + logTarget: "player", + content() { + "step 0"; + var cards = player.getExpansions("nsjiquan_mark"); + if (cards.length == 1) + event._result = { + bool: true, + links: cards.slice(0), + }; + else player.chooseButton(["选择移去一张“威”", cards], true); + "step 1"; player.loseToDiscardpile(result.links); - player.gain(trigger.cards.filterInD(),'gain2','log'); + player.gain(trigger.cards.filterInD(), "gain2", "log"); + }, + ai: { + combo: "nsjiquan" }, }, - nszhihuang_damage:{ - trigger:{source:'damageBegin1'}, - forced:true, - filter(event,player){ - var zhu=get.zhu(player); - return zhu&&player.countCards('h')>zhu.countCards('h')&&event.getParent().type=='card'; + nszhihuang_damage: { + trigger: { source: "damageBegin1" }, + forced: true, + filter(event, player) { + var zhu = get.zhu(player); + return ( + zhu && + player.countCards("h") > zhu.countCards("h") && + event.getParent().type == "card" + ); }, - content(){ + content() { trigger.num++; }, }, //OL神张角 - junksijun:{ - audio:'sijun', - inherit:'sijun', - check(event,player){ + junksijun: { + audio: "sijun", + inherit: "sijun", + check(event, player) { return ui.cardPile.childNodes.length; }, - async content(event,trigger,player){ - player.removeMark('yizhao',player.countMark('yizhao')); - const pile=Array.from(ui.cardPile.childNodes); - if(pile.length){ - const max=Math.pow(2,Math.min(100,pile.length)); - let bool=false,index,cards=[]; - for(let i=0;i36) break; + for (var k = 0; k < index.length; k++) { + if (index[k] == "1") num += get.number(pile[k]); + if (num > 36) break; } - if(num==36){ - bool=true; + if (num == 36) { + bool = true; break; } } - if(bool){ - for(let k=0;k=36) break; + if (total >= 36) break; } } - if(cards.length) await player.gain(cards,'gain2'); + if (cards.length) await player.gain(cards, "gain2"); } }, }, //手杀削弱版许攸 - junkshicai:{ - audio:'nzry_shicai_2', - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(!event.cards.filterInD('oe').length) return false; - return player.getHistory('useCard',evt=>get.type2(evt.card)==get.type2(event.card)).indexOf(event)==0; + junkshicai: { + audio: "nzry_shicai_2", + trigger: { player: "useCardAfter" }, + filter(event, player) { + if (!event.cards.filterInD("oe").length) return false; + return ( + player + .getHistory("useCard", (evt) => get.type2(evt.card) == get.type2(event.card)) + .indexOf(event) == 0 + ); }, - prompt2(event,player){ - const cards=event.cards.filterInD('oe'); - return '你可以将'+get.translation(cards)+(cards.length>1?'以任意顺序':'')+'置于牌堆顶,然后摸一张牌'; + prompt2(event, player) { + const cards = event.cards.filterInD("oe"); + return ( + "你可以将" + + get.translation(cards) + + (cards.length > 1 ? "以任意顺序" : "") + + "置于牌堆顶,然后摸一张牌" + ); }, - content(){ - 'step 0' - event.cards=trigger.cards.filterInD('oe'); - var lose_list=[]; - event.cards.forEach(card=>{ - var owner=get.owner(card); - if(owner){ - var arr=lose_list.find(i=>i[0]==owner); - if(arr) arr[1].push(card); - else lose_list.push([owner,[card]]); + content() { + "step 0"; + event.cards = trigger.cards.filterInD("oe"); + var lose_list = []; + event.cards.forEach((card) => { + var owner = get.owner(card); + if (owner) { + var arr = lose_list.find((i) => i[0] == owner); + if (arr) arr[1].push(card); + else lose_list.push([owner, [card]]); } }); - if(lose_list.length){ + if (lose_list.length) { game.loseAsync({ - lose_list:lose_list, - }).setContent('chooseToCompareLose'); + lose_list: lose_list, + }).setContent("chooseToCompareLose"); } - 'step 1' - if(cards.length>1){ - var next=player.chooseToMove('恃才:将牌按顺序置于牌堆顶'); - next.set('list',[['牌堆顶',cards]]); - next.set('reverse',((_status.currentPhase&&_status.currentPhase.next)?get.attitude(player,_status.currentPhase.next)>0:false)); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0); - cards.sort(function(a,b){ - return (_status.event.reverse?1:-1)*(get.value(b)-get.value(a)); + "step 1"; + if (cards.length > 1) { + var next = player.chooseToMove("恃才:将牌按顺序置于牌堆顶"); + next.set("list", [["牌堆顶", cards]]); + next.set( + "reverse", + _status.currentPhase && _status.currentPhase.next + ? get.attitude(player, _status.currentPhase.next) > 0 + : false + ); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0); + cards.sort(function (a, b) { + return (_status.event.reverse ? 1 : -1) * (get.value(b) - get.value(a)); }); return [cards]; }); } - 'step 2' - if(result.bool&&result.moved&&result.moved[0].length) cards=result.moved[0].slice(0); + "step 2"; + if (result.bool && result.moved && result.moved[0].length) + cards = result.moved[0].slice(0); cards.reverse(); - game.cardsGotoPile(cards,'insert'); - game.log(player,'将',cards,'置于了牌堆顶'); + game.cardsGotoPile(cards, "insert"); + game.log(player, "将", cards, "置于了牌堆顶"); player.draw(); }, - ai:{ - reverseOrder:true, - skillTagFilter(player){ - if(player.getHistory('useCard',function(evt){ - return get.type(evt.card)=='equip'; - }).length>0) return false; + ai: { + reverseOrder: true, + skillTagFilter(player) { + if ( + player.getHistory("useCard", function (evt) { + return get.type(evt.card) == "equip"; + }).length > 0 + ) + return false; }, }, }, //削弱版段煨 - junklangmie:{ - audio:'langmie', - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter(event,player){ - if(player==event.player||player.countCards('he')==0) return false; - var num=0; - if(event.player.hasHistory('sourceDamage',function(evt){ - num+=evt.num; - return num>=2; - })) return true; - var map={}; - return event.player.hasHistory('useCard',function(i){ - var name=get.type2(i.card,false); - if(!map[name]){ - map[name]=true; + junklangmie: { + audio: "langmie", + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter(event, player) { + if (player == event.player || player.countCards("he") == 0) return false; + var num = 0; + if ( + event.player.hasHistory("sourceDamage", function (evt) { + num += evt.num; + return num >= 2; + }) + ) + return true; + var map = {}; + return event.player.hasHistory("useCard", function (i) { + var name = get.type2(i.card, false); + if (!map[name]) { + map[name] = true; return false; } return true; }); }, - content(){ - 'step 0' - var list=[],num=0,target=trigger.player; - event.target=target; - event.choices=[]; - var map={}; - if(target.hasHistory('useCard',function(i){ - var name=get.type2(i.card,false); - if(!map[name]){ - map[name]=true; - return false; - } - return true; - })){ - list.push('弃置一张牌,然后摸两张牌'); - event.choices.push('draw'); - } - if(target.hasHistory('sourceDamage',function(evt){ - num+=evt.num; - return num>=2; - })){ - list.push('弃置一张牌,对'+get.translation(target)+'造成1点伤害'); - event.choices.push('damage'); - } - player.chooseControl('cancel2').set('choiceList',list).set('ai',function(){ - var player=_status.event.player; - var choices=_status.event.getParent().choices.slice(0); - choices.push('cancel'); - choicex=choices.slice(0); - var getx=function(a){ - switch(a){ - case 'draw':return 2*get.effect(player,{name:'draw'},player,player); - case 'damage':return get.damageEffect(_status.event.getParent().target,player,player); - default:return 0; + content() { + "step 0"; + var list = [], + num = 0, + target = trigger.player; + event.target = target; + event.choices = []; + var map = {}; + if ( + target.hasHistory("useCard", function (i) { + var name = get.type2(i.card, false); + if (!map[name]) { + map[name] = true; + return false; } - } - choices.sort(function(a,b){ - return getx(b)-getx(a); - }); - return choicex.indexOf(choices[0]); - }).set('prompt',get.prompt('junklangmie',target)); - 'step 1' - if(result.control=='cancel2') event.finish(); - else{ - event.choice=event.choices[result.index]; - player.chooseToDiscard('he').set('ai',card=>(7-get.value(card))).logSkill=(event.choice=='draw'?'junklangmie':['junklangmie',target]); + return true; + }) + ) { + list.push("弃置一张牌,然后摸两张牌"); + event.choices.push("draw"); } - 'step 2' - if(result.bool){ - if(event.choice=='draw') player.draw(2); + if ( + target.hasHistory("sourceDamage", function (evt) { + num += evt.num; + return num >= 2; + }) + ) { + list.push("弃置一张牌,对" + get.translation(target) + "造成1点伤害"); + event.choices.push("damage"); + } + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("ai", function () { + var player = _status.event.player; + var choices = _status.event.getParent().choices.slice(0); + choices.push("cancel"); + choicex = choices.slice(0); + var getx = function (a) { + switch (a) { + case "draw": + return 2 * get.effect(player, { name: "draw" }, player, player); + case "damage": + return get.damageEffect( + _status.event.getParent().target, + player, + player + ); + default: + return 0; + } + }; + choices.sort(function (a, b) { + return getx(b) - getx(a); + }); + return choicex.indexOf(choices[0]); + }) + .set("prompt", get.prompt("junklangmie", target)); + "step 1"; + if (result.control == "cancel2") event.finish(); + else { + event.choice = event.choices[result.index]; + player.chooseToDiscard("he").set("ai", (card) => 7 - get.value(card)).logSkill = + event.choice == "draw" ? "junklangmie" : ["junklangmie", target]; + } + "step 2"; + if (result.bool) { + if (event.choice == "draw") player.draw(2); else target.damage(); } }, }, //李典光速通渠传说 - junkwangxi:{ - audio:'wangxi', - trigger:{player:'damageEnd',source:'damageSource'}, - filter(event){ - if(event._notrigger.includes(event.player)) return false; - return event.num&&event.source&&event.player&& - event.player.isIn()&&event.source.isIn()&&event.source!=event.player; + junkwangxi: { + audio: "wangxi", + trigger: { player: "damageEnd", source: "damageSource" }, + filter(event) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.num && + event.source && + event.player && + event.player.isIn() && + event.source.isIn() && + event.source != event.player + ); }, - check(event,player){ - if(player.isPhaseUsing()) return true; - if(event.player==player) return get.attitude(player,event.source)>-5; - return get.attitude(player,event.player)>-5; + check(event, player) { + if (player.isPhaseUsing()) return true; + if (event.player == player) return get.attitude(player, event.source) > -5; + return get.attitude(player, event.player) > -5; }, - logTarget(event,player){ - if(event.player==player) return event.source; + logTarget(event, player) { + if (event.player == player) return event.source; return event.player; }, - preHidden:true, - content(){ - 'step 0' - event.count=trigger.num; - event.target=lib.skill.junkwangxi.logTarget(trigger,player); - 'step 1' - player.draw(2).gaintag=['junkwangxi_tag']; + preHidden: true, + content() { + "step 0"; + event.count = trigger.num; + event.target = lib.skill.junkwangxi.logTarget(trigger, player); + "step 1"; + player.draw(2).gaintag = ["junkwangxi_tag"]; event.count--; - 'step 2' - var cards=player.getCards('he',(card)=>card.hasGaintag('junkwangxi_tag')); - if(cards.length>0&&target.isIn()){ - if(cards.length==1) event._result={bool:true,cards:cards}; - else player.chooseCard('he','忘隙:交给'+get.translation(target)+'一张牌',true,function(card){ - return card.hasGaintag('junkwangxi_tag'); - }); + "step 2"; + var cards = player.getCards("he", (card) => card.hasGaintag("junkwangxi_tag")); + if (cards.length > 0 && target.isIn()) { + if (cards.length == 1) event._result = { bool: true, cards: cards }; + else + player.chooseCard( + "he", + "忘隙:交给" + get.translation(target) + "一张牌", + true, + function (card) { + return card.hasGaintag("junkwangxi_tag"); + } + ); + } else event.goto(4); + "step 3"; + if (result.bool) { + player.give(result.cards, target); } - else event.goto(4); - 'step 3' - if(result.bool){ - player.give(result.cards,target); - } - 'step 4' - player.removeGaintag('junkwangxi_tag'); - if(event.count&&target.isIn()&&player.hasSkill('junkwangxi')){ - player.chooseBool(get.prompt2('junkwangxi',target)); - } - else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('junkwangxi',target); + "step 4"; + player.removeGaintag("junkwangxi_tag"); + if (event.count && target.isIn() && player.hasSkill("junkwangxi")) { + player.chooseBool(get.prompt2("junkwangxi", target)); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("junkwangxi", target); event.goto(1); } }, - ai:{ - maixie:true, - maixie_hp:true - } + ai: { + maixie: true, + maixie_hp: true, + }, }, //2013标准包双蜀黑 - junkjizhi:{ - audio:'jizhi', - trigger:{player:'useCard'}, - frequent:true, - filter(event,player){ - return get.type(event.card)=='trick'&&event.card.isCard; + junkjizhi: { + audio: "jizhi", + trigger: { player: "useCard" }, + frequent: true, + filter(event, player) { + return get.type(event.card) == "trick" && event.card.isCard; }, - content(){ - 'step 0' - var card=get.cards()[0]; - event.card=card; + content() { + "step 0"; + var card = get.cards()[0]; + event.card = card; game.cardsGotoOrdering(card); - player.showCards(card,get.translation(player)+'发动了【集智】'); - if(get.type(card)!='basic'){ - player.gain(card,'gain2'); + player.showCards(card, get.translation(player) + "发动了【集智】"); + if (get.type(card) != "basic") { + player.gain(card, "gain2"); event.finish(); - } - else if(!player.countCards('h')) event.finish(); - 'step 1' - player.chooseCard('h','是否用一张手牌交换'+get.translation(card)+'?','若选择「取消」,则'+get.translation(card)+'将被置入弃牌堆。'); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - player.$throw(card,1000); - game.log(player,'将',card,'置于牌堆顶'); - player.lose(card,ui.cardPile,'visible','insert'); - player.gain(event.card,'gain2'); + } else if (!player.countCards("h")) event.finish(); + "step 1"; + player.chooseCard( + "h", + "是否用一张手牌交换" + get.translation(card) + "?", + "若选择「取消」,则" + get.translation(card) + "将被置入弃牌堆。" + ); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + player.$throw(card, 1000); + game.log(player, "将", card, "置于牌堆顶"); + player.lose(card, ui.cardPile, "visible", "insert"); + player.gain(event.card, "gain2"); } }, }, - junkqicai:{ - mod:{ - targetInRange(card,player,target,now){ - var type=get.type(card); - if(type=='trick'||type=='delay') return true; + junkqicai: { + mod: { + targetInRange(card, player, target, now) { + var type = get.type(card); + if (type == "trick" || type == "delay") return true; }, - canBeDiscarded(card){ - if(get.position(card)=='e'&&!['equip3','equip4','equip6'].includes(get.subtype(card))) return false; + canBeDiscarded(card) { + if ( + get.position(card) == "e" && + !["equip3", "equip4", "equip6"].includes(get.subtype(card)) + ) + return false; }, }, }, - junkrende:{ - audio:'rende', - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0; + junkrende: { + audio: "rende", + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0; }, - filterTarget:lib.filter.notMe, - filterCard:true, - selectCard:[1,Infinity], - position:'h', - discard:false, - lose:false, - delay:false, - content(){ - 'step 0' - event.num=cards.length; - event.targets=targets.slice(0); - player.give(cards,target); - if(event.num>1) player.recover(); - 'step 1' - if(player.countCards('h')>0&&game.hasPlayer(current=>(current!=player&&!targets.includes(current)))){ + filterTarget: lib.filter.notMe, + filterCard: true, + selectCard: [1, Infinity], + position: "h", + discard: false, + lose: false, + delay: false, + content() { + "step 0"; + event.num = cards.length; + event.targets = targets.slice(0); + player.give(cards, target); + if (event.num > 1) player.recover(); + "step 1"; + if ( + player.countCards("h") > 0 && + game.hasPlayer((current) => current != player && !targets.includes(current)) + ) { player.chooseCardTarget({ - prompt:'是否继续分配剩余的手牌', - prompt2:'操作提示:请先选择要分配的手牌,然后再选择一名角色,该角色将获得你选择的所有手牌。', - filterCard:true, - selectCard:[1,Infinity], - filterTarget(card,player,target){ - return target!=player&&!_status.event.getParent().targets.includes(target); + prompt: "是否继续分配剩余的手牌", + prompt2: + "操作提示:请先选择要分配的手牌,然后再选择一名角色,该角色将获得你选择的所有手牌。", + filterCard: true, + selectCard: [1, Infinity], + filterTarget(card, player, target) { + return ( + target != player && !_status.event.getParent().targets.includes(target) + ); }, }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.line(target,'green'); - player.give(cards,target); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.line(target, "green"); + player.give(cards, target); targets.add(target); - event.num+=cards.length; - if(num<2&&event.num>1) player.recover(); + event.num += cards.length; + if (num < 2 && event.num > 1) player.recover(); event.goto(1); } }, }, //十周年削弱版张让 - junktaoluan:{ - hiddenCard(player,name){ - return !player.getStorage('junktaoluan').includes(name)&&player.countCards('hes',card=>!player.getStorage('junktaoluan2').includes(get.suit(card)))>0&&!player.hasSkill('junktaoluan3')&&lib.inpile.includes(name); + junktaoluan: { + hiddenCard(player, name) { + return ( + !player.getStorage("junktaoluan").includes(name) && + player.countCards( + "hes", + (card) => !player.getStorage("junktaoluan2").includes(get.suit(card)) + ) > 0 && + !player.hasSkill("junktaoluan3") && + lib.inpile.includes(name) + ); }, - audio:'taoluan', - enable:'chooseToUse', - filter(event,player){ - return !player.hasSkill('junktaoluan3')&&player.countCards('hes',card=>{ - return lib.inpile.some(name=>{ - if(player.getStorage('junktaoluan2').includes(get.suit(card))) return false; - if(player.getStorage('junktaoluan').includes(name)) return false; - if(get.type(name)!='basic'&&get.type(name)!='trick') return false; - if(event.filterCard({name:name,isCard:true,cards:[card]},player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard({name:name,nature:nature,isCard:true,cards:[card]},player,event)) return true; + audio: "taoluan", + enable: "chooseToUse", + filter(event, player) { + return ( + !player.hasSkill("junktaoluan3") && + player.countCards("hes", (card) => { + return lib.inpile.some((name) => { + if (player.getStorage("junktaoluan2").includes(get.suit(card))) return false; + if (player.getStorage("junktaoluan").includes(name)) return false; + if (get.type(name) != "basic" && get.type(name) != "trick") return false; + if ( + event.filterCard( + { + name: name, + isCard: true, + cards: [card], + }, + player, + event + ) + ) + return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + { + name: name, + nature: nature, + isCard: true, + cards: [card], + }, + player, + event + ) + ) + return true; + } } - } - return false; - }); - })>0; + return false; + }); + }) > 0 + ); }, - chooseButton:{ - dialog(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)=='basic'||get.type(name)=='trick'){ - if(player.getStorage('junktaoluan').includes(name)) continue; - list.push([get.translation(get.type(name)),'',name]); - if(name=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog(event, player) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) == "basic" || get.type(name) == "trick") { + if (player.getStorage("junktaoluan").includes(name)) continue; + list.push([get.translation(get.type(name)), "", name]); + if (name == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } } - return ui.create.dialog('滔乱',[list,'vcard']); + return ui.create.dialog("滔乱", [list, "vcard"]); }, - filter(button,player){ - return _status.event.getParent().filterCard({name:button.link[2]},player,_status.event.getParent()); + filter(button, player) { + return _status.event + .getParent() + .filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, - check(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(player.countCards('hes',cardx=>cardx.name==card.name)) return 0; - return _status.event.getParent().type=='phase'?player.getUseValue(card):1; + check(button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], + }; + if (player.countCards("hes", (cardx) => cardx.name == card.name)) return 0; + return _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; }, - backup(links,player){ + backup(links, player) { return { - filterCard(card,player){ - return !player.getStorage('junktaoluan2').includes(get.suit(card)); + filterCard(card, player) { + return !player.getStorage("junktaoluan2").includes(get.suit(card)); }, - audio:'taoluan', - popname:true, - check(card){ - return 7-get.value(card); + audio: "taoluan", + popname: true, + check(card) { + return 7 - get.value(card); }, - position:'hse', - viewAs:{name:links[0][2],nature:links[0][3]}, - onuse(result,player){ - player.markAuto('junktaoluan2',[get.suit(result.cards[0],player)]); - var evt=_status.event.getParent('phase'); - if(evt&&evt.name=='phase'&&!evt.junktaoluan){ - evt.junktaoluan=true; - var next=game.createEvent('taoluan_clear'); + position: "hse", + viewAs: { name: links[0][2], nature: links[0][3] }, + onuse(result, player) { + player.markAuto("junktaoluan2", [get.suit(result.cards[0], player)]); + var evt = _status.event.getParent("phase"); + if (evt && evt.name == "phase" && !evt.junktaoluan) { + evt.junktaoluan = true; + var next = game.createEvent("taoluan_clear"); _status.event.next.remove(next); evt.after.push(next); - next.player=player; - next.setContent(function(){ + next.player = player; + next.setContent(function () { delete player.storage.junktaoluan2; }); } - player.markAuto('junktaoluan',[result.card.name]); + player.markAuto("junktaoluan", [result.card.name]); }, - } + }; + }, + prompt(links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order:4, - save:true, - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(!player.countCards('hes',card=>!player.getStorage('junktaoluan2').includes(get.suit(card)))||player.hasSkill('taoluan3')) return false; - if(tag=='respondSha'||tag=='respondShan'){ - if(arg=='respond') return false; - return !player.getStorage('taoluan').includes(tag=='respondSha'?'sha':'shan'); + ai: { + order: 4, + save: true, + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + if ( + !player.countCards( + "hes", + (card) => !player.getStorage("junktaoluan2").includes(get.suit(card)) + ) || + player.hasSkill("taoluan3") + ) + return false; + if (tag == "respondSha" || tag == "respondShan") { + if (arg == "respond") return false; + return !player + .getStorage("taoluan") + .includes(tag == "respondSha" ? "sha" : "shan"); } - return !player.getStorage('taoluan').includes('tao')||(!player.getStorage('taoluan').includes('jiu')&&arg==player); + return ( + !player.getStorage("taoluan").includes("tao") || + (!player.getStorage("taoluan").includes("jiu") && arg == player) + ); }, - result:{ - player(player){ - var players=game.filterPlayer(); - for(var i=0;i0){ + result: { + player(player) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + players[i].countCards("he") && + get.attitude(player, players[i]) > 0 + ) { return 1; } } return 0; - } + }, }, - threaten:1.9, + threaten: 1.9, }, - group:'junktaoluan2', + group: "junktaoluan2", }, - junktaoluan2:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - popup:false, - charlotte:true, - filter(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; - return event.skill=='junktaoluan_backup'; + junktaoluan2: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + popup: false, + charlotte: true, + filter(event, player) { + if (!game.hasPlayer((current) => current != player)) return false; + return event.skill == "junktaoluan_backup"; }, - content(){ - 'step 0' - player.chooseTarget(true,function(card,player,target){ - return target!=player; - },'###滔乱###令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力').set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0){ - if(get.attitude(target,player)>0){ - return target.countCards('h'); + content() { + "step 0"; + player + .chooseTarget( + true, + function (card, player, target) { + return target != player; + }, + "###滔乱###令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力" + ) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) { + if (get.attitude(target, player) > 0) { + return target.countCards("h"); + } + return target.countCards("h") / 2; } - return target.countCards('h')/2; - } - return 0; - }); - 'step 1' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var type=get.type(trigger.card,'trick'); - target.chooseCard('###滔乱###交给'+get.translation(player)+'一张不为'+get.translation(type)+'牌的牌,或令其失去1点体力且滔乱无效直到回合结束','he',num,function(card,player,target){ - return get.type(card,'trick')!=_status.event.cardType; - }).set('cardType',type).set('ai',function(card){ - if(_status.event.att){ - return 11-get.value(card); - } - return 0; - }).set('att',get.attitude(target,player)>0); - 'step 2' - if(result.bool){ - target.give(result.cards,player,'visible'); + return 0; + }); + "step 1"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var type = get.type(trigger.card, "trick"); + target + .chooseCard( + "###滔乱###交给" + + get.translation(player) + + "一张不为" + + get.translation(type) + + "牌的牌,或令其失去1点体力且滔乱无效直到回合结束", + "he", + num, + function (card, player, target) { + return get.type(card, "trick") != _status.event.cardType; + } + ) + .set("cardType", type) + .set("ai", function (card) { + if (_status.event.att) { + return 11 - get.value(card); + } + return 0; + }) + .set("att", get.attitude(target, player) > 0); + "step 2"; + if (result.bool) { + target.give(result.cards, player, "visible"); + } else { + player.addTempSkill("junktaoluan3"); } - else{ - player.addTempSkill('junktaoluan3'); - } - } + }, }, - junktaoluan3:{ - charlotte:true, - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - content(){ + junktaoluan3: { + charlotte: true, + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + content() { player.loseHp(); }, }, - junktaoluan_backup:{charlotte:true}, + junktaoluan_backup: { charlotte: true }, - nshuaishuang:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content(){ - 'step 0' - var card=get.cardPile(function(card){ - return card.name=='tao'; + nshuaishuang: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content() { + "step 0"; + var card = get.cardPile(function (card) { + return card.name == "tao"; }); - if(card){ - player.gain(card,'gain2'); - } - else event.finish(); - 'step 1' + if (card) { + player.gain(card, "gain2"); + } else event.finish(); + "step 1"; game.updateRoundNumber(); player.loseHp(); }, }, - nsfengli:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&&!current.hasSkill('nsfengli_use'); - }); + nsfengli: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && !current.hasSkill("nsfengli_use"); + }) + ); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('nsfengli'),function(card,player,target){ - return target!=player&&!target.hasSkill('nsfengli_use'); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)/(5+target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('nsfengli',target); - var cards=player.getCards('h'); - player.addShownCards(cards,'visible_nsfengli'); - player.addSkill('nsfengli2'); - target.addSkill('nsfengli_use'); - target.storage.nsfengli_use=player; + content() { + "step 0"; + player + .chooseTarget(get.prompt2("nsfengli"), function (card, player, target) { + return target != player && !target.hasSkill("nsfengli_use"); + }) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) / (5 + target.countCards("h")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("nsfengli", target); + var cards = player.getCards("h"); + player.addShownCards(cards, "visible_nsfengli"); + player.addSkill("nsfengli2"); + target.addSkill("nsfengli_use"); + target.storage.nsfengli_use = player; } }, - group:['nsfengli_draw','nsfengli_clear'], - onremove(player){ - player.removeSkill('nsfengli2'); + group: ["nsfengli_draw", "nsfengli_clear"], + onremove(player) { + player.removeSkill("nsfengli2"); }, }, - nsfengli_draw:{ - trigger:{ - player:['loseAfter','hideShownCardsAfter'], - global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'], + nsfengli_draw: { + trigger: { + player: ["loseAfter", "hideShownCardsAfter"], + global: [ + "gainAfter", + "equipAfter", + "addJudgeAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - charlotte:true, - filter(event,player,name){ - if(event.name=='hideShownCards'){ - const hs=player.countCards('h'); - return game.hasPlayer(current=>current.countCards('h') current.countCards("h") < hs); } - var num=0; - var evt=event.getl(player); - if(!evt||!evt.gaintag_map) return false; - var bool=false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].some(tag=>tag.indexOf('visible_')==0)) num++; + var num = 0; + var evt = event.getl(player); + if (!evt || !evt.gaintag_map) return false; + var bool = false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].some((tag) => tag.indexOf("visible_") == 0)) num++; } - if(event.getg){ - if(event.name=='gain'){ - if(event.getlx===false&&event.gaintag.some(tag=>tag.indexOf('visible_')==0)) num-=event.cards.length; - } - else{ - player.checkHistory('gain',function(evt){ - if(evt.parent==event&&evt.gaintag.some(tag=>tag.indexOf('visible_')==0)){ - num-=evt.cards.length; + if (event.getg) { + if (event.name == "gain") { + if ( + event.getlx === false && + event.gaintag.some((tag) => tag.indexOf("visible_") == 0) + ) + num -= event.cards.length; + } else { + player.checkHistory("gain", function (evt) { + if ( + evt.parent == event && + evt.gaintag.some((tag) => tag.indexOf("visible_") == 0) + ) { + num -= evt.cards.length; } }); } } - if(num>0){ - const hs=player.countCards('h'); - return game.hasPlayer(current=>current.countCards('h') 0) { + const hs = player.countCards("h"); + return game.hasPlayer((current) => current.countCards("h") < hs); } }, - content(){ - 'step 0' - player.chooseTarget('奉礼:是否令一名手牌数小于你的其他角色摸一张牌?',function(card,player,target){ - return target!=player&&target.countCards('h')0) player.hideShownCards(cards); - player.removeSkill('nsfengli2'); + content() { + var cards = player.getShownCards(); + if (cards.length > 0) player.hideShownCards(cards); + player.removeSkill("nsfengli2"); }, }, - nsfengli2:{ - onremove(player){ - player.removeGaintag('nsfengli2'); - game.countPlayer(function(current){ - if(current.storage.nsfengli_use==player) current.removeSkill('nsfengli_use'); - }) + nsfengli2: { + onremove(player) { + player.removeGaintag("nsfengli2"); + game.countPlayer(function (current) { + if (current.storage.nsfengli_use == player) current.removeSkill("nsfengli_use"); + }); }, }, - nsfengli_use:{ - hiddenCard(player,name){ - if(player==_status.currentPhase) return false; - var target=player.storage.nsfengli_use; - var cards=target.getShownCards(); - for(var i of cards){ - if(get.name(i,target)==name) return true; + nsfengli_use: { + hiddenCard(player, name) { + if (player == _status.currentPhase) return false; + var target = player.storage.nsfengli_use; + var cards = target.getShownCards(); + for (var i of cards) { + if (get.name(i, target) == name) return true; } return false; }, - enable:['chooseToUse','chooseToRespond'], - charlotte:true, - onremove:true, - filter(event,player){ - if(player==_status.currentPhase) return false; - var target=player.storage.nsfengli_use; - var cards=target.getShownCards(); - for(var i of cards){ - if(event.filterCard({ - name:get.name(i,target), - nature:get.nature(i,target), - isCard:true, - },player,event)) return true; + enable: ["chooseToUse", "chooseToRespond"], + charlotte: true, + onremove: true, + filter(event, player) { + if (player == _status.currentPhase) return false; + var target = player.storage.nsfengli_use; + var cards = target.getShownCards(); + for (var i of cards) { + if ( + event.filterCard( + { + name: get.name(i, target), + nature: get.nature(i, target), + isCard: true, + }, + player, + event + ) + ) + return true; } return false; }, - chooseButton:{ - dialog(event,player){ - var target=player.storage.nsfengli_use; - var cards=target.getShownCards(); - return ui.create.dialog('奉礼',cards); + chooseButton: { + dialog(event, player) { + var target = player.storage.nsfengli_use; + var cards = target.getShownCards(); + return ui.create.dialog("奉礼", cards); }, - filter(button,player){ - var evt=_status.event.getParent(); - var target=player.storage.nsfengli_use; - return evt.filterCard({ - name:get.name(button.link,target), - nature:get.nature(button.link,target), - isCard:true, - },player,evt); + filter(button, player) { + var evt = _status.event.getParent(); + var target = player.storage.nsfengli_use; + return evt.filterCard( + { + name: get.name(button.link, target), + nature: get.nature(button.link, target), + isCard: true, + }, + player, + evt + ); }, - check(button){ - var player=_status.event.player; - var evt=_status.event.getParent(); - if(evt.dying) return get.attitude(player,evt.dying); + check(button) { + var player = _status.event.player; + var evt = _status.event.getParent(); + if (evt.dying) return get.attitude(player, evt.dying); return 1; }, - backup(links,player){ - var target=player.storage.nsfengli_use; + backup(links, player) { + var target = player.storage.nsfengli_use; return { - viewAs:{ - name:get.name(links[0],target), - nature:get.nature(links[0],target), - isCard:true, + viewAs: { + name: get.name(links[0], target), + nature: get.nature(links[0], target), + isCard: true, }, - card:links[0], - filterCard:()=>false, - selectCard:-1, - precontent(){ - var card=lib.skill.nsfengli_use_backup.card; - var target=player.storage.nsfengli_use; - event.target=target; - player.logSkill('nsfengli',target); + card: links[0], + filterCard: () => false, + selectCard: -1, + precontent() { + var card = lib.skill.nsfengli_use_backup.card; + var target = player.storage.nsfengli_use; + event.target = target; + player.logSkill("nsfengli", target); delete event.result.skill; - player.showCards(card,get.translation(player)+'发动了【奉礼】'); + player.showCards(card, get.translation(player) + "发动了【奉礼】"); target.hideShownCards(card); }, }; }, - ai:{ - hasSha:true, - hasShan:true, - skillTagFilter(player,tag){ - var name='s'+tag.slice(4); - return lib.skill.nsfengli_use.hiddenCard(player,name); + ai: { + hasSha: true, + hasShan: true, + skillTagFilter(player, tag) { + var name = "s" + tag.slice(4); + return lib.skill.nsfengli_use.hiddenCard(player, name); }, }, }, - ai:{ - order:8, - result:{ - player:1, + ai: { + order: 8, + result: { + player: 1, }, }, }, - ns_chuanshu:{ - audio:["xingshuai",2], - trigger:{ - global:"dying", + ns_chuanshu: { + audio: ["xingshuai", 2], + trigger: { + global: "dying", }, - priority:8, - unique:true, - skillAnimation:true, - animationColor:"water", - filter (event,player){ - return event.player.hp<=0&&event.player!=player; + priority: 8, + unique: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return event.player.hp <= 0 && event.player != player; }, - check (event,player){ - return get.attitude(player,event.player)>0; + check(event, player) { + return get.attitude(player, event.player) > 0; }, - logTarget:"player", - content (){ - 'step 0' - trigger.player.chooseControl('releiji','guidao').set('prompt',''+get.translation(trigger.player)+'获得一项技能'); - goon=true; - if(!goon){ + logTarget: "player", + content() { + "step 0"; + trigger.player + .chooseControl("releiji", "guidao") + .set("prompt", "" + get.translation(trigger.player) + "获得一项技能"); + goon = true; + if (!goon) { event.finish(); } - 'step 1' + "step 1"; trigger.player.addSkillLog(result.control); - trigger.player.recover(1-trigger.player.hp); + trigger.player.recover(1 - trigger.player.hp); trigger.player.draw(2); - trigger.player.storage.ns_chuanshu2=player; - trigger.player.addSkill('ns_chuanshu2'); - player.awakenSkill('ns_chuanshu'); + trigger.player.storage.ns_chuanshu2 = player; + trigger.player.addSkill("ns_chuanshu2"); + player.awakenSkill("ns_chuanshu"); }, }, - ns_xiandao1:{ - audio:["huashen",2], - forced:true, + ns_xiandao1: { + audio: ["huashen", 2], + forced: true, //noLose:true, //locked:true, //noRemove:true, //noDisable:true, - priority:10, - trigger:{ - global:"gameStart", - player:["phaseEnd","enterGame"], + priority: 10, + trigger: { + global: "gameStart", + player: ["phaseEnd", "enterGame"], }, //filter (event,player){ // return player.isAlive(); //}, - content (){ - var n=[1,2].randomGet(); - if(n==1){ - player.addTempSkill("releiji",{player:"phaseUseBegin"}); - player.markSkill("releiji",{player:"phaseUseBegin"}); + content() { + var n = [1, 2].randomGet(); + if (n == 1) { + player.addTempSkill("releiji", { + player: "phaseUseBegin", + }); + player.markSkill("releiji", { + player: "phaseUseBegin", + }); } - if(n==2){ - player.addTempSkill("guidao",{player:"phaseUseBegin"}); - player.markSkill("guidao",{player:"phaseUseBegin"}); + if (n == 2) { + player.addTempSkill("guidao", { + player: "phaseUseBegin", + }); + player.markSkill("guidao", { player: "phaseUseBegin" }); } }, }, - ns_xiandao2:{ - audio:["huashen",2], - forced:true, + ns_xiandao2: { + audio: ["huashen", 2], + forced: true, //noLose:true, //locked:true, //noRemove:true, //noDisable:true, - trigger:{ - player:"damageBefore", + trigger: { + player: "damageBefore", }, - filter (event,player){ - if(!event.nature) return false; + filter(event, player) { + if (!event.nature) return false; return true; }, - content (){ + content() { trigger.cancel(); //event.finish(); }, }, - ns_xiandao:{ - forced:true, + ns_xiandao: { + forced: true, //noLose:true, //locked:true, - noRemove:true, + noRemove: true, //noDisable:true, - group:["ns_xiandao1","ns_xiandao2"], + group: ["ns_xiandao1", "ns_xiandao2"], }, - ns_chuanshu2:{ - audio:["songwei",2], - mark:"character", - intro:{ - content:"当你造成或受到一次伤害后,$摸一张牌", + ns_chuanshu2: { + audio: ["songwei", 2], + mark: "character", + intro: { + content: "当你造成或受到一次伤害后,$摸一张牌", }, - nopop:true, - trigger:{ - source:"damageEnd", - player:"damageEnd", + nopop: true, + trigger: { + source: "damageEnd", + player: "damageEnd", }, - forced:true, - popup:false, - filter (event,player){ - return player.storage.ns_chuanshu2&&player.storage.ns_chuanshu2.isIn()&&event.num>0; + forced: true, + popup: false, + filter(event, player) { + return player.storage.ns_chuanshu2 && player.storage.ns_chuanshu2.isIn() && event.num > 0; }, - content (){ - 'step 0' + content() { + "step 0"; game.delayx(); - 'step 1' - var target=player.storage.ns_chuanshu2; - player.line(target,'green'); + "step 1"; + var target = player.storage.ns_chuanshu2; + player.line(target, "green"); target.draw(); game.delay(); }, - onremove:true, - group:"ns_chuanshu3", + onremove: true, + group: "ns_chuanshu3", }, - ns_chuanshu3:{ - audio:1, - trigger:{ - player:"dieBegin", + ns_chuanshu3: { + audio: 1, + trigger: { + player: "dieBegin", }, - silent:true, - onremove:true, - filter (event,player){ - return player.storage.ns_chuanshu2&&player.storage.ns_chuanshu2.isIn(); + silent: true, + onremove: true, + filter(event, player) { + return player.storage.ns_chuanshu2 && player.storage.ns_chuanshu2.isIn(); }, - content (){ - 'step 0' + content() { + "step 0"; game.delayx(); - 'step 1' - var target=player.storage.ns_chuanshu2; - player.line(target,'green'); + "step 1"; + var target = player.storage.ns_chuanshu2; + player.line(target, "green"); //target.addSkill('ns_chuanshu'); - target.restoreSkill('ns_chuanshu'); + target.restoreSkill("ns_chuanshu"); target.update(); }, - forced:true, - popup:false, + forced: true, + popup: false, }, - ns_xiuzheng:{ - audio:["xinsheng",2], - enable:"phaseUse", - usable:1, - priority:10, - filter (event,player){ - return (ui.cardPile.childElementCount+ui.discardPile.childElementCount)>=2; + ns_xiuzheng: { + audio: ["xinsheng", 2], + enable: "phaseUse", + usable: 1, + priority: 10, + filter(event, player) { + return ui.cardPile.childElementCount + ui.discardPile.childElementCount >= 2; }, - filterTarget (card,player,target){ - return player!=target; + filterTarget(card, player, target) { + return player != target; }, - content (){ - "step 0" - event.cards=get.cards(2); + content() { + "step 0"; + event.cards = get.cards(2); player.showCards(event.cards); - "step 1" - if(get.color(event.cards[0])=='red'&&get.color(event.cards[1])=='red'){ - target.damage('fire'); + "step 1"; + if (get.color(event.cards[0]) == "red" && get.color(event.cards[1]) == "red") { + target.damage("fire"); } - if(get.color(event.cards[0])!=get.color(event.cards[1])){ - player.discardPlayerCard(target,"he",true); + if (get.color(event.cards[0]) != get.color(event.cards[1])) { + player.discardPlayerCard(target, "he", true); } - if(get.color(event.cards[0])=='black'&&get.color(event.cards[1])=='black'){ - target.damage('thunder'); + if (get.color(event.cards[0]) == "black" && get.color(event.cards[1]) == "black") { + target.damage("thunder"); } - "step 2" - if(event.cards.length){ - player.gain(event.cards,'gain2'); + "step 2"; + if (event.cards.length) { + player.gain(event.cards, "gain2"); game.delay(); } - "step 3" - player.chooseToDiscard(2,'he','请弃置两张牌',true); + "step 3"; + player.chooseToDiscard(2, "he", "请弃置两张牌", true); }, - ai:{ - threaten:0.5, - order:13, - result:{ - target (player,target){ - return get.damageEffect(target,player); + ai: { + threaten: 0.5, + order: 13, + result: { + target(player, target) { + return get.damageEffect(target, player); }, }, }, }, - nsanruo:{ - unique:true, - init(player){ - if(!player.node.handcards1.cardMod){ - player.node.handcards1.cardMod={}; + nsanruo: { + unique: true, + init(player) { + if (!player.node.handcards1.cardMod) { + player.node.handcards1.cardMod = {}; } - if(!player.node.handcards2.cardMod){ - player.node.handcards2.cardMod={}; + if (!player.node.handcards2.cardMod) { + player.node.handcards2.cardMod = {}; } - var cardMod=function(card){ - if(get.info(card).multitarget) return; - if(card.name=='sha'||get.type(card)=='trick') return ['暗弱','杀或普通锦囊牌对你不可见']; + var cardMod = function (card) { + if (get.info(card).multitarget) return; + if (card.name == "sha" || get.type(card) == "trick") + return ["暗弱", "杀或普通锦囊牌对你不可见"]; }; - player.node.handcards1.cardMod.nsanruo=cardMod; - player.node.handcards2.cardMod.nsanruo=cardMod; - player.node.handcards1.classList.add('nsanruo'); - player.node.handcards2.classList.add('nsanruo'); - if(!ui.css.nsanruo){ - ui.css.nsanruo=lib.init.sheet( - '.handcards.nsanruo>.card[data-card-type="trick"]:not(*[data-card-multitarget="1"])>*,'+ - '.handcards.nsanruo>.card[data-card-name="sha"]>*{visibility:hidden !important}' + player.node.handcards1.cardMod.nsanruo = cardMod; + player.node.handcards2.cardMod.nsanruo = cardMod; + player.node.handcards1.classList.add("nsanruo"); + player.node.handcards2.classList.add("nsanruo"); + if (!ui.css.nsanruo) { + ui.css.nsanruo = lib.init.sheet( + '.handcards.nsanruo>.card[data-card-type="trick"]:not(*[data-card-multitarget="1"])>*,' + + '.handcards.nsanruo>.card[data-card-name="sha"]>*{visibility:hidden !important}' ); } }, - onremove(player){ - player.node.handcards1.classList.remove('nsanruo'); - player.node.handcards2.classList.remove('nsanruo'); + onremove(player) { + player.node.handcards1.classList.remove("nsanruo"); + player.node.handcards2.classList.remove("nsanruo"); delete player.node.handcards1.cardMod.nsanruo; delete player.node.handcards2.cardMod.nsanruo; }, - ai:{ - neg:true - } + ai: { + neg: true, + }, }, - nsxunshan:{ - mod:{ - selectTarget(card,player,range){ - if(!player.hasSkill('nsanruo')) return; - if(_status.auto) return; - if(get.position(card)!='h'||get.owner(card)!=player) return; - if(get.info(card).multitarget) return; - if(card.name=='sha'||get.type(card)=='trick') range[1]=game.countPlayer(); + nsxunshan: { + mod: { + selectTarget(card, player, range) { + if (!player.hasSkill("nsanruo")) return; + if (_status.auto) return; + if (get.position(card) != "h" || get.owner(card) != player) return; + if (get.info(card).multitarget) return; + if (card.name == "sha" || get.type(card) == "trick") range[1] = game.countPlayer(); }, // playerEnabled(card,player,target,current){ // if(current==false) return; @@ -13141,2630 +15893,2846 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // if(card.name=='sha'||get.type(card)=='trick') return true; // } }, - ai:{ - combo:'nsanruo' - } + ai: { + combo: "nsanruo", + }, }, - nskaicheng:{ - enable:'phaseUse', - usable:1, - zhuSkill:true, - unique:true, - filter(event,player){ - if(!player.hasZhuSkill('nskaicheng')) return false; - if(!player.hasCard(function(card){ - if(get.info(card).multitarget) return false; - return card.name=='sha'||get.type(card)=='trick'; - })){ + nskaicheng: { + enable: "phaseUse", + usable: 1, + zhuSkill: true, + unique: true, + filter(event, player) { + if (!player.hasZhuSkill("nskaicheng")) return false; + if ( + !player.hasCard(function (card) { + if (get.info(card).multitarget) return false; + return card.name == "sha" || get.type(card) == "trick"; + }) + ) { return false; } - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='qun'; + return game.hasPlayer(function (current) { + return current != player && current.group == "qun"; }); }, - filterCard(card){ - if(get.info(card).multitarget) return false; - return card.name=='sha'||get.type(card)=='trick'; + filterCard(card) { + if (get.info(card).multitarget) return false; + return card.name == "sha" || get.type(card) == "trick"; }, - filterTarget(card,player,target){ - return player!=target&&target.group=='qun'; + filterTarget(card, player, target) { + return player != target && target.group == "qun"; }, - lose:false, - content(){ - 'step 0' - target.chooseBool(function(){ - return get.attitude(target,player)>0; - },'是否将'+get.translation(cards)+'告知'+get.translation(player)); - 'step 1' - if(!player.hasUseTarget(cards[0])){ - if(result.bool){ - player.chooseControl('确定').set('prompt','你展示的手牌为'+get.translation(cards)); + lose: false, + content() { + "step 0"; + target.chooseBool(function () { + return get.attitude(target, player) > 0; + }, "是否将" + get.translation(cards) + "告知" + get.translation(player)); + "step 1"; + if (!player.hasUseTarget(cards[0])) { + if (result.bool) { + player + .chooseControl("确定") + .set("prompt", "你展示的手牌为" + get.translation(cards)); + } else { + event.hidden = true; + player + .chooseControl("确定") + .set("prompt", get.translation(target) + "拒绝告知你卡牌信息"); } - else{ - event.hidden=true; - player.chooseControl('确定').set('prompt',get.translation(target)+'拒绝告知你卡牌信息'); + } else { + if (result.bool) { + player.chooseBool( + "是否使用展示的牌?", + "你展示的手牌为" + + get.translation(cards) + + "。如果你使用此牌,则在结算后摸一张牌;如果你不使用此牌,则结束出牌阶段" + ); + } else { + event.hidden = true; + player.chooseBool( + "是否使用展示的牌?", + get.translation(target) + + "拒绝告知你卡牌信息。如果你使用此牌,则在结算后摸一张牌;如果你不使用此牌,则结束出牌阶段" + ); } } - else{ - if(result.bool){ - player.chooseBool('是否使用展示的牌?','你展示的手牌为'+get.translation(cards)+'。如果你使用此牌,则在结算后摸一张牌;如果你不使用此牌,则结束出牌阶段'); - } - else{ - event.hidden=true; - player.chooseBool('是否使用展示的牌?',get.translation(target)+'拒绝告知你卡牌信息。如果你使用此牌,则在结算后摸一张牌;如果你不使用此牌,则结束出牌阶段'); - } - } - 'step 2' - if(result.bool){ - player.chooseUseTarget(true,cards[0],event.hidden?'选择此牌的目标':null); - } - else{ - var evt=_status.event.getParent('phaseUse'); - if(evt){ - evt.skipped=true; + "step 2"; + if (result.bool) { + player.chooseUseTarget(true, cards[0], event.hidden ? "选择此牌的目标" : null); + } else { + var evt = _status.event.getParent("phaseUse"); + if (evt) { + evt.skipped = true; } event.finish(); } - 'step 3' + "step 3"; player.draw(); }, - ai:{ - combo:'nsanruo' - } + ai: { + combo: "nsanruo", + }, }, - nsjuanli:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h'); + nsjuanli: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("h"); }, - filter(event,player){ - return player.countCards('h'); + filter(event, player) { + return player.countCards("h"); }, - init(player){ - player.storage.nsjuanli_win=[]; - player.storage.nsjuanli_lose=[]; + init(player) { + player.storage.nsjuanli_win = []; + player.storage.nsjuanli_lose = []; }, - intro:{ - content(storage,player){ - var str=''; - if(player.storage.nsjuanli_win.length){ - str+=get.translation(player.storage.nsjuanli_win)+'与你距离-1直到与你下次赌牌'; + intro: { + content(storage, player) { + var str = ""; + if (player.storage.nsjuanli_win.length) { + str += + get.translation(player.storage.nsjuanli_win) + "与你距离-1直到与你下次赌牌"; } - if(player.storage.nsjuanli_lose.length){ - if(str.length){ - str+=';'; + if (player.storage.nsjuanli_lose.length) { + if (str.length) { + str += ";"; } - str+=get.translation(player.storage.nsjuanli_lose)+'与你距离+1直到与你下次赌牌'; + str += + get.translation(player.storage.nsjuanli_lose) + "与你距离+1直到与你下次赌牌"; } return str; - } + }, }, - onremove:['nsjuanli_win','nsjuanli_lose'], - content(){ - 'step 0' + onremove: ["nsjuanli_win", "nsjuanli_lose"], + content() { + "step 0"; player.storage.nsjuanli_win.remove(target); player.storage.nsjuanli_lose.remove(target); - event.prompt2='赌牌的两名角色分别亮开一张手牌,若花色相同则赌牌平局,若花色不同,则依次展示牌堆顶的牌直到翻开的牌与其中一人亮出牌的花色相同,则该角色获得赌牌的胜利'; - player.chooseCard('h',true).set('prompt2',event.prompt2); - 'step 1' - if(result.bool){ - event.card1=result.cards[0]; - target.chooseCard('h',true).set('prompt2',event.prompt2); - } - else{ + event.prompt2 = + "赌牌的两名角色分别亮开一张手牌,若花色相同则赌牌平局,若花色不同,则依次亮出牌堆顶的牌直到翻开的牌与其中一人亮出牌的花色相同,则该角色获得赌牌的胜利"; + player.chooseCard("h", true).set("prompt2", event.prompt2); + "step 1"; + if (result.bool) { + event.card1 = result.cards[0]; + target.chooseCard("h", true).set("prompt2", event.prompt2); + } else { event.finish(); } - 'step 2' - if(result.bool){ - event.card2=result.cards[0]; - } - else{ + "step 2"; + if (result.bool) { + event.card2 = result.cards[0]; + } else { event.finish(); } - 'step 3' - player.$compare(event.card1,event.target,event.card2); - game.delay(0,1500); - game.log(player,'亮出的牌为',event.card1); - game.log(target,'亮出的牌为',event.card2); - 'step 4' - var suit1=get.suit(event.card1); - var suit2=get.suit(event.card2); - if(suit1==suit2){ - game.broadcastAll(function(str){ - var dialog=ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function(){ + "step 3"; + player.$compare(event.card1, event.target, event.card2); + game.delay(0, 1500); + game.log(player, "亮出的牌为", event.card1); + game.log(target, "亮出的牌为", event.card2); + "step 4"; + var suit1 = get.suit(event.card1); + var suit2 = get.suit(event.card2); + if (suit1 == suit2) { + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { dialog.close(); - },1000); - },'平局'); + }, 1000); + }, "平局"); game.delay(2); - if(!player.storage.nsjuanli_win.length&&!player.storage.nsjuanli_lose.length){ - player.unmarkSkill('nsjuanli'); + if (!player.storage.nsjuanli_win.length && !player.storage.nsjuanli_lose.length) { + player.unmarkSkill("nsjuanli"); } - } - else{ - var cards=[]; - for(var i=0;i<1000;i++){ - var current=get.cards(); - if(current&¤t.length){ - current=current[0]; + } else { + var cards = []; + for (var i = 0; i < 1000; i++) { + var current = get.cards(); + if (current && current.length) { + current = current[0]; current.discard(); cards.push(current); - var suit=get.suit(current); - if(suit==suit1){ - player.showCards(cards,get.translation(player)+'赌牌获胜'); + var suit = get.suit(current); + if (suit == suit1) { + player.showCards(cards, get.translation(player) + "赌牌获胜"); player.storage.nsjuanli_win.add(target); target.loseHp(); - player.markSkill('nsjuanli'); + player.markSkill("nsjuanli"); break; - } - else if(suit==suit2){ - player.showCards(cards,get.translation(target)+'赌牌获胜'); + } else if (suit == suit2) { + player.showCards(cards, get.translation(target) + "赌牌获胜"); player.storage.nsjuanli_lose.add(target); target.recover(); - player.markSkill('nsjuanli'); + player.markSkill("nsjuanli"); break; } - } - else{ + } else { break; } } } }, - mod:{ - globalTo(from,to,distance){ - if(to.storage.nsjuanli_win&&to.storage.nsjuanli_win.includes(from)){ - return distance-1; + mod: { + globalTo(from, to, distance) { + if (to.storage.nsjuanli_win && to.storage.nsjuanli_win.includes(from)) { + return distance - 1; } - if(to.storage.nsjuanli_lose&&to.storage.nsjuanli_lose.includes(from)){ - return distance+1; + if (to.storage.nsjuanli_lose && to.storage.nsjuanli_lose.includes(from)) { + return distance + 1; } - } + }, }, - ai:{ - order:4, - result:{ - target(player,target){ - if(target.isHealthy()){ - return -1/(1+target.hp); + ai: { + order: 4, + result: { + target(player, target) { + if (target.isHealthy()) { + return -1 / (1 + target.hp); + } else { + return -0.3 / (1 + target.hp); } - else{ - return -0.3/(1+target.hp); - } - } - } - } + }, + }, + }, }, - nsyuanchou:{ - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - check(event,player){ - return get.effect(event.target,event.card,event.player,player)<0; + nsyuanchou: { + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + check(event, player) { + return get.effect(event.target, event.card, event.player, player) < 0; }, - filter(event,player){ - return get.type(event.card,'trick')=='trick'&&get.distance(event.player,player)>1; + filter(event, player) { + return get.type(event.card, "trick") == "trick" && get.distance(event.player, player) > 1; }, - content(){ + content() { trigger.cancel(); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.type(card,'trick')=='trick'&&get.distance(player,target)>1) return 'zeroplayertarget'; + ai: { + effect: { + target(card, player, target, current) { + if (get.type(card, "trick") == "trick" && get.distance(player, target) > 1) + return "zeroplayertarget"; }, - } - } + }, + }, }, - nsguhuo:{ - trigger:{player:'useCardAfter'}, - forced:true, - usable:2, - filter(event,player){ - if(event.parent.name=='nsguhuo') return false; - if(event.card==event.cards[0]){ - var type=get.type(event.card,'trick'); - var names=[]; - if(get.cardPile(function(card){ - if(get.type(card,'trick')!=type) return false; - if(get.info(card).multitarget) return false; - if(names.includes(card.name)) return false; - if(player.hasUseTarget(card)){ - return true; - } - else{ - names.add(card.name); - return false; - } - })){ + nsguhuo: { + trigger: { player: "useCardAfter" }, + forced: true, + usable: 2, + filter(event, player) { + if (event.parent.name == "nsguhuo") return false; + if (event.card == event.cards[0]) { + var type = get.type(event.card, "trick"); + var names = []; + if ( + get.cardPile(function (card) { + if (get.type(card, "trick") != type) return false; + if (get.info(card).multitarget) return false; + if (names.includes(card.name)) return false; + if (player.hasUseTarget(card)) { + return true; + } else { + names.add(card.name); + return false; + } + }) + ) { return true; } } return true; }, - content(){ - var type=get.type(trigger.card,'trick'); - var names=[]; - var card=get.cardPile(function(card){ - if(get.type(card,'trick')!=type) return false; - if(get.info(card).multitarget) return false; - if(names.includes(card.name)) return false; - if(player.hasUseTarget(card)){ + content() { + var type = get.type(trigger.card, "trick"); + var names = []; + var card = get.cardPile(function (card) { + if (get.type(card, "trick") != type) return false; + if (get.info(card).multitarget) return false; + if (names.includes(card.name)) return false; + if (player.hasUseTarget(card)) { return true; - } - else{ + } else { names.add(card.name); return false; } }); - if(card){ - var info=get.info(card); - var targets=game.filterPlayer(function(current){ - return lib.filter.filterTarget(card,player,current); + if (card) { + var info = get.info(card); + var targets = game.filterPlayer(function (current) { + return lib.filter.filterTarget(card, player, current); }); - if(targets.length){ + if (targets.length) { targets.sort(lib.sort.seat); - var select=get.select(info.selectTarget); - if(select[0]==-1||select[1]==-1){ - player.useCard(card,targets,'noai'); - } - else if(targets.length>=select[0]){ - var num=select[0]+Math.floor(Math.random()*(select[1]-select[0]+1)); - player.useCard(card,targets.randomGets(num),'noai'); + var select = get.select(info.selectTarget); + if (select[0] == -1 || select[1] == -1) { + player.useCard(card, targets, "noai"); + } else if (targets.length >= select[0]) { + var num = select[0] + Math.floor(Math.random() * (select[1] - select[0] + 1)); + player.useCard(card, targets.randomGets(num), "noai"); } } } - } - }, - nsbaiyi:{ - trigger:{player:'phaseDiscardBefore'}, - forced:true, - filter(event,player){ - return player.storage.nsqinxue&&player.storage.nsqinxue.length; }, - content(){ - 'step 0' + }, + nsbaiyi: { + trigger: { player: "phaseDiscardBefore" }, + forced: true, + filter(event, player) { + return player.storage.nsqinxue && player.storage.nsqinxue.length; + }, + content() { + "step 0"; trigger.cancel(); - var num=player.storage.nsqinxue.length; - player.chooseToDiscard('白衣:请弃置'+get.cnNumber(num)+'张牌','he',true,num); - 'step 1' - if(result.bool&&result.cards.length){ - event.goon=true; - if(result.cards.length==3){ - var type=[]; - for(var i=0;i=2; + skillAnimation: true, + check(event, player) { + return player.hp == 1 || player.maxHp - player.hp >= 2; }, - content(){ - player.storage.nsfuge=true; + content() { + player.storage.nsfuge = true; player.insertPhase(); }, - group:'nsfuge_draw', - subSkill:{ - draw:{ - trigger:{player:'phaseDrawBegin'}, - silent:true, - filter(event,player){ - var evt=event.getParent('phase'); - return evt&&evt.skill=='nsfuge'; + group: "nsfuge_draw", + subSkill: { + draw: { + trigger: { player: "phaseDrawBegin" }, + silent: true, + filter(event, player) { + var evt = event.getParent("phase"); + return evt && evt.skill == "nsfuge"; }, - content(){ - trigger.num+=player.maxHp-player.hp; - } - } - } - }, - nsbaiming:{ - trigger:{player:'useCard'}, - direct:true, - filter(event,player){ - if(player.additionalSkills.nsbaiming) return false; - return event.card&&event.card.name=='sha'&&player.storage.nsbaiming&&player.storage.nsbaiming.length>0; + content() { + trigger.num += player.maxHp - player.hp; + }, + }, }, - group:'nsbaiming_clear', - init(player){ - var check=function(list){ - for(var i=0;i 0 + ); + }, + group: "nsbaiming_clear", + init(player) { + var check = function (list) { + for (var i = 0; i < list.length; i++) { + var info = lib.skill[list[i]]; + if (info && info.shaRelated) return true; + if (info && info.trigger) { + for (var j in info.trigger) { + var cond = info.trigger[j]; + if (typeof cond == "string") { + cond = [cond]; } - if(j=='player'||j=='global'){ - if(cond.indexOf('shaBefore')!=-1) return true; - if(cond.indexOf('shaBegin')!=-1) return true; - if(cond.indexOf('shaEnd')!=-1) return true; - if(cond.indexOf('shaAfter')!=-1) return true; + if (j == "player" || j == "global") { + if (cond.indexOf("shaBefore") != -1) return true; + if (cond.indexOf("shaBegin") != -1) return true; + if (cond.indexOf("shaEnd") != -1) return true; + if (cond.indexOf("shaAfter") != -1) return true; } - if(j=='source'||j=='global'){ - if(cond.indexOf('damageBefore')!=-1) return true; - if(cond.indexOf('damageBegin')!=-1) return true; - if(cond.indexOf('damageBegin1')!=-1) return true; - if(cond.indexOf('damageBegin2')!=-1) return true; - if(cond.indexOf('damageEnd')!=-1) return true; - if(cond.indexOf('damageSource')!=-1) return true; - if(cond.indexOf('damageAfter')!=-1) return true; + if (j == "source" || j == "global") { + if (cond.indexOf("damageBefore") != -1) return true; + if (cond.indexOf("damageBegin") != -1) return true; + if (cond.indexOf("damageBegin1") != -1) return true; + if (cond.indexOf("damageBegin2") != -1) return true; + if (cond.indexOf("damageEnd") != -1) return true; + if (cond.indexOf("damageSource") != -1) return true; + if (cond.indexOf("damageAfter") != -1) return true; } } } } return false; }; - player.storage.nsbaiming=get.gainableSkills(function(info,skill){ - var list=[skill]; + player.storage.nsbaiming = get.gainableSkills(function (info, skill) { + var list = [skill]; game.expandSkills(list); return check(list); - },player); + }, player); }, - content(){ - 'step 0' - var list=player.storage.nsbaiming.slice(0); - event.skillai=function(){ - return get.max(list,get.skillRank,'item'); + content() { + "step 0"; + var list = player.storage.nsbaiming.slice(0); + event.skillai = function () { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - var dialog=ui.create.dialog('forcebutton'); - dialog.add(get.prompt('nsbaiming')); - var clickItem=function(){ - _status.event._result=this.link; + if (event.isMine()) { + var dialog = ui.create.dialog("forcebutton"); + dialog.add(get.prompt("nsbaiming")); + var clickItem = function () { + _status.event._result = this.link; dialog.close(); game.resume(); }; - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.switchToAuto=function(){ - event._result=event.skillai(); + dialog.add(ui.create.div(".placeholder")); + event.switchToAuto = function () { + event._result = event.skillai(); dialog.close(); game.resume(); }; - event.confirm=ui.create.confirm('c'); - event.custom.replace.confirm=function(){ - event._result=null; + event.confirm = ui.create.confirm("c"); + event.custom.replace.confirm = function () { + event._result = null; dialog.close(); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(); } - else{ - event._result=event.skillai(); - } - 'step 1' - _status.imchoosing=false; - if(event.confirm){ + "step 1"; + _status.imchoosing = false; + if (event.confirm) { event.confirm.close(); } - if(typeof result=='string'){ - player.logSkill('nsbaiming'); - var link=result; - player.addAdditionalSkill('nsbaiming',link); - player.logSkill('nsbaiming'); + if (typeof result == "string") { + player.logSkill("nsbaiming"); + var link = result; + player.addAdditionalSkill("nsbaiming", link); + player.logSkill("nsbaiming"); player.popup(link); - game.log(player,'获得了技能','【'+get.translation(link)+'】'); + game.log(player, "获得了技能", "【" + get.translation(link) + "】"); game.delay(); player.storage.nsbaiming.remove(link); - trigger.nsbaiming=true; + trigger.nsbaiming = true; } }, - subSkill:{ - clear:{ - trigger:{player:'useCardAfter'}, - silent:true, - filter(event){ - return event.nsbaiming==true; + subSkill: { + clear: { + trigger: { player: "useCardAfter" }, + silent: true, + filter(event) { + return event.nsbaiming == true; }, - content(){ - player.removeAdditionalSkill('nsbaiming'); - } - } - } - }, - nsxinzhan:{ - enable:'phaseUse', - filterCard:[1,Infinity], - filter(event,player){ - return player.countCards('h')>0; + content() { + player.removeAdditionalSkill("nsbaiming"); + }, + }, }, - usable:1, - selectCard:[1,Infinity], - check(card){ - var player=_status.event.player; - if(player.countCards('h')>=8&&game.hasPlayer(function(current){ - return current.isDamaged()&&get.attitude(player,current)>3; - })){ - if(ui.selected.cards.length>=6){ + }, + nsxinzhan: { + enable: "phaseUse", + filterCard: [1, Infinity], + filter(event, player) { + return player.countCards("h") > 0; + }, + usable: 1, + selectCard: [1, Infinity], + check(card) { + var player = _status.event.player; + if ( + player.countCards("h") >= 8 && + game.hasPlayer(function (current) { + return current.isDamaged() && get.attitude(player, current) > 3; + }) + ) { + if (ui.selected.cards.length >= 6) { return 0; } return 1; - } - else{ - if(ui.selected.cards.length>=2){ + } else { + if (ui.selected.cards.length >= 2) { return 0; } - if(player.countCards('h',function(card){ - return get.value(card)<0; - })){ - return 8-get.value(card,player,'raw'); - } - else{ - return 4-get.value(card,player,'raw'); + if ( + player.countCards("h", function (card) { + return get.value(card) < 0; + }) + ) { + return 8 - get.value(card, player, "raw"); + } else { + return 4 - get.value(card, player, "raw"); } } }, - discard:false, - prepare:'give2', - content(){ - target.gain(cards,player); - var num=Math.floor(cards.length/2); - if(num>=3){ + discard: false, + prepare: "give2", + content() { + target.gain(cards, player); + var num = Math.floor(cards.length / 2); + if (num >= 3) { target.loseMaxHp(true); - } - else if(num){ + } else if (num) { target.loseHp(num); } }, - filterTarget(card,player,target){ - return target!=player; + filterTarget(card, player, target) { + return target != player; }, - ai:{ - order:10, - result:{ - target(player,target){ - if(ui.selected.cards.length>=6){ - if(target.isDamaged()) return 2; + ai: { + order: 10, + result: { + target(player, target) { + if (ui.selected.cards.length >= 6) { + if (target.isDamaged()) return 2; return 1; } - if(ui.selected.cards.length==1){ + if (ui.selected.cards.length == 1) { return 1; } return -1; - } - } - } - }, - nstanbing:{ - trigger:{player:'phaseDrawBegin'}, - filter(event,player){ - return player.countCards('h')>0; + }, + }, }, - direct:true, - content(){ - 'step 0' - player.chooseToDiscard('h',get.prompt2('nstanbing')).set('ai',function(card){ - if(!player.needsToDiscard(1)){ - return get.translation(card.name).length-1; + }, + nstanbing: { + trigger: { player: "phaseDrawBegin" }, + filter(event, player) { + return player.countCards("h") > 0; + }, + direct: true, + content() { + "step 0"; + player.chooseToDiscard("h", get.prompt2("nstanbing")).set("ai", function (card) { + if (!player.needsToDiscard(1)) { + return get.translation(card.name).length - 1; } return 0; - }).logSkill='nstanbing'; - 'step 1' - if(result.bool){ + }).logSkill = "nstanbing"; + "step 1"; + if (result.bool) { player.draw(get.translation(result.cards[0].name).length); - player.addTempSkill('nstanbing_sha'); + player.addTempSkill("nstanbing_sha"); } }, - subSkill:{ - sha:{ - mod:{ - cardEnabled(card,player){ - if(card.name=='sha'){ + subSkill: { + sha: { + mod: { + cardEnabled(card, player) { + if (card.name == "sha") { return false; } }, - cardUsable(card,player){ - if(card.name=='sha'){ + cardUsable(card, player) { + if (card.name == "sha") { return false; } }, - } - } - } + }, + }, + }, }, - nswangfeng:{ - trigger:{global:'judge'}, - filter(event,player){ - return player.countCards('he',{color:'red'})>0; + nswangfeng: { + trigger: { global: "judge" }, + filter(event, player) { + return player.countCards("he", { color: "red" }) > 0; }, - direct:true, - content(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('nswangfeng'),'he',function(card){ - return get.color(card)=='red'; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result; - } - else{ - return -result; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight'); - } - else{ + direct: true, + content() { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("nswangfeng"), + "he", + function (card) { + return get.color(card) == "red"; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result; + } else { + return -result; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight"); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.logSkill('nswangfeng'); + "step 2"; + if (result.bool) { + player.logSkill("nswangfeng"); player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; - if(!get.owner(result.cards[0],'judge')){ + trigger.player.judging[0] = result.cards[0]; + if (!get.owner(result.cards[0], "judge")) { trigger.position.appendChild(result.cards[0]); } - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); } - "step 3" + "step 3"; game.delay(2); }, - ai:{ - tag:{ - rejudge:1 - } - } + ai: { + tag: { + rejudge: 1, + }, + }, }, - nsfuhuo:{ - enable:'phaseUse', - usable:1, - filterCard:true, - filterTarget(card,player,target){ - return player!=target&&!target.hasSkill('nsfuhuo2'); + nsfuhuo: { + enable: "phaseUse", + usable: 1, + filterCard: true, + filterTarget(card, player, target) { + return player != target && !target.hasSkill("nsfuhuo2"); }, - prepare:'throw', - discard:false, - content(){ + prepare: "throw", + discard: false, + content() { target.$gain2(cards); - target.storage.nsfuhuo2=cards[0]; - target.addSkill('nsfuhuo2'); - target.storage.nsfuhuo3=player; + target.storage.nsfuhuo2 = cards[0]; + target.addSkill("nsfuhuo2"); + target.storage.nsfuhuo3 = player; ui.special.appendChild(cards[0]); - target.syncStorage('nsfuhuo2'); + target.syncStorage("nsfuhuo2"); }, - check(card){ - return 6-get.value(card) + check(card) { + return 6 - get.value(card); }, - ai:{ - expose:0.1, - order:4, - result:{ - target(player,target){ - if(target.hasSkillTag('maixie')) return 0; + ai: { + expose: 0.1, + order: 4, + result: { + target(player, target) { + if (target.hasSkillTag("maixie")) return 0; return -1; - } - } + }, + }, }, - group:['nsfuhuo_die','nsfuhuo_gain'], - subSkill:{ - die:{ - trigger:{player:'dieBegin'}, - silent:true, - content(){ - for(var i=0;i0; - }, - check(event,player){ - if(player.hasShan()||player.hujia>0) return false; - var nh=player.countCards('h'); - if(player.hp==1){ - return nh<=3; - } - if(player.hp==2){ - return nh<=1; - } - return false; - }, - content(){ - var cards=player.getCards('h'); - player.discard(cards); - player.changeHujia(cards.length); - player.storage.nsbaquan=true; - }, - group:'nsbaquan_clear', - subSkill:{ - clear:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return player.storage.nsbaquan&&player.hujia>0; - }, - content(){ - player.changeHujia(-player.hujia); - game.log(player,'失去了所有护甲'); - delete player.storage.nsbaquan; - } - } - } - }, - nschangshi:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.identity=='fan'; - }, - filterTarget(card,player,target){ - if(target==player) return false; - if(ui.selected.targets.length){ - return target.hp!=ui.selected.targets[0].hp; - } - return true; - }, - multitarget:true, - selectTarget:2, - content(){ - var tmp=targets[0].hp; - targets[0].hp=targets[1].hp; - targets[1].hp=tmp; - targets[0].update(); - targets[1].update(); - if(Math.abs(targets[0].hp-targets[1].hp)==1){ - player.loseHp(); - } - //else{ - //player.die(); - //} - }, - ai:{ - order:10, - result:{ - target(player,target){ - if(target==game.zhu) return -1; - if(get.attitude(player,target)>3){ - var num=game.zhu.hp-target.hp; - if(num==1){ - return 1; - } - if(num>1){ - if(player.hp==1) return num; - if(target.hp==1) return num; - if(num>=3) return num; - } - } - return 0; - } - } - } - }, - nsjianning:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.identity=='nei'; - }, - filterTarget(card,player,target){ - return target.countCards('h')=8; - })&&player.countCards('h')-target.countCards('h')<=1){ - if(target.hp==1||player.countCards('h',function(card){ - return get.value(card)<0; - })){ - return get.damageEffect(target,player,target); - } - } - return 0; - } - } - } - }, - nscuanquan:{ - init(player){ - player.storage.nscuanquan=0; - }, - forced:true, - unique:true, - forceunique:true, - skillAnimation:true, - animationColor:'thunder', - trigger:{player:'damageAfter'}, - filter(event,player){ - return player.identity=='zhong'&&player.storage.nscuanquan==3&&game.zhu&&game.zhu.isZhu; - }, - group:'nscuanquan_count', - subSkill:{ - count:{ - trigger:{player:'damageEnd'}, - silent:true, - content(){ - player.storage.nscuanquan++; - } - } - }, - logTarget(){ - return [game.zhu]; - }, - content(){ - player.awakenSkill('nscuanquan'); - var tmp=player.maxHp; - player.identity='zhu'; - player.maxHp=game.zhu.hp; - player.showIdentity(); - player.update(); - game.zhu.identity='zhong'; - game.zhu.maxHp=tmp; - game.zhu.showIdentity(); - game.zhu.update(); - game.zhu=player; - } - }, - nstianji:{ - trigger:{global:'dying'}, - priority:6, - unique:true, - skillAnimation:true, - animationColor:'water', - filter(event,player){ - return event.player.hp<=0&&event.player!=player; - }, - logTarget:'player', - check(event,player){ - return get.attitude(player,event.player)>1; - }, - content(){ - 'step 0' - player.awakenSkill('nstianji'); - player.loseMaxHp(); - 'step 1' - trigger.player.recover(1-trigger.player.hp); - 'step 2' - trigger.player.gainMaxHp(); - } - }, - nsbugua:{ - group:'nsbugua_use', - ai:{ - threaten:1.4, - }, - subSkill:{ - use:{ - enable:'phaseUse', - usable:1, - filterCard:true, - check(card){ - return 9-get.value(card); - }, - filter(event,player){ - // if(!player.storage.nstuiyan2_done&&player.getStat().skill.nsbugua_use){ - // return false; - // } - return player.countCards('he'); - }, - position:'he', - ai:{ - order:9.5, - result:{ - player:1 - } - }, - content(){ - 'step 0' - player.throwDice(); - 'step 1' - var cards=get.cards(6); - var cards2=cards.slice(0); - var card=(cards2.splice(event.num-1,1))[0]; - player.showCards(get.translation(player)+'亮出了'+get.translation(card),cards).set('hiddencards',cards2); - card.discard(); - var name=null; - switch(get.suit(card)){ - case 'club':{ - if(card.number%2==0){ - name='guohe'; - } - else{ - name='jiedao'; - } - break; - } - case 'spade':{ - if(card.number%2==0){ - name='nanman'; - } - else{ - name='juedou'; - } - break; - } - case 'diamond':{ - if(card.number%2==0){ - name='shunshou'; - } - else{ - name='huogong'; - } - break; - } - case 'heart':{ - if(card.number%2==0){ - name='wuzhong'; - } - else{ - name='wanjian'; - } - break; - } - } - var togain=get.cardPile(name,'cardPile'); - if(togain){ - player.gain(togain,'gain2'); - } - else{ - player.draw(); - } - event.list=cards2; - 'step 2' - player.chooseCardButton(event.list,true,'按顺序将牌置于牌堆顶(先选择的在上)',event.list.length); - 'step 3' - var list=result.links.slice(0); - while(list.length){ - ui.cardPile.insertBefore(list.pop(),ui.cardPile.firstChild); - } }, }, - twice:{} - } - }, - nstuiyan:{ - trigger:{player:'useCard'}, - filter(event,player){ - return _status.currentPhase==player&&event.getParent('phaseUse',true)&&!player.hasSkill('nstuiyan_fail')&& - typeof player.storage.nstuiyan=='number'&&event.card.number>player.storage.nstuiyan; }, - frequent:true, - priority:2, - content(){ + }, + nsbaquan: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return player.countCards("h") > 0; + }, + check(event, player) { + if (player.hasShan() || player.hujia > 0) return false; + var nh = player.countCards("h"); + if (player.hp == 1) { + return nh <= 3; + } + if (player.hp == 2) { + return nh <= 1; + } + return false; + }, + content() { + var cards = player.getCards("h"); + player.discard(cards); + player.changeHujia(cards.length); + player.storage.nsbaquan = true; + }, + group: "nsbaquan_clear", + subSkill: { + clear: { + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return player.storage.nsbaquan && player.hujia > 0; + }, + content() { + player.changeHujia(-player.hujia); + game.log(player, "失去了所有护甲"); + delete player.storage.nsbaquan; + }, + }, + }, + }, + nschangshi: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.identity == "fan"; + }, + filterTarget(card, player, target) { + if (target == player) return false; + if (ui.selected.targets.length) { + return target.hp != ui.selected.targets[0].hp; + } + return true; + }, + multitarget: true, + selectTarget: 2, + content() { + var tmp = targets[0].hp; + targets[0].hp = targets[1].hp; + targets[1].hp = tmp; + targets[0].update(); + targets[1].update(); + if (Math.abs(targets[0].hp - targets[1].hp) == 1) { + player.loseHp(); + } + //else{ + //player.die(); + //} + }, + ai: { + order: 10, + result: { + target(player, target) { + if (target == game.zhu) return -1; + if (get.attitude(player, target) > 3) { + var num = game.zhu.hp - target.hp; + if (num == 1) { + return 1; + } + if (num > 1) { + if (player.hp == 1) return num; + if (target.hp == 1) return num; + if (num >= 3) return num; + } + } + return 0; + }, + }, + }, + }, + nsjianning: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.identity == "nei"; + }, + filterTarget(card, player, target) { + return target.countCards("h") < player.countCards("h"); + }, + content() { + "step 0"; + player.swapHandcards(target); + "step 1"; + target.damage(); + }, + ai: { + order: 10, + result: { + target(player, target) { + if ( + !player.countCards("h", function (card) { + return get.value(card) >= 8; + }) && + player.countCards("h") - target.countCards("h") <= 1 + ) { + if ( + target.hp == 1 || + player.countCards("h", function (card) { + return get.value(card) < 0; + }) + ) { + return get.damageEffect(target, player, target); + } + } + return 0; + }, + }, + }, + }, + nscuanquan: { + init(player) { + player.storage.nscuanquan = 0; + }, + forced: true, + unique: true, + forceunique: true, + skillAnimation: true, + animationColor: "thunder", + trigger: { player: "damageAfter" }, + filter(event, player) { + return ( + player.identity == "zhong" && + player.storage.nscuanquan == 3 && + game.zhu && + game.zhu.isZhu + ); + }, + group: "nscuanquan_count", + subSkill: { + count: { + trigger: { player: "damageEnd" }, + silent: true, + content() { + player.storage.nscuanquan++; + }, + }, + }, + logTarget() { + return [game.zhu]; + }, + content() { + player.awakenSkill("nscuanquan"); + var tmp = player.maxHp; + player.identity = "zhu"; + player.maxHp = game.zhu.hp; + player.showIdentity(); + player.update(); + game.zhu.identity = "zhong"; + game.zhu.maxHp = tmp; + game.zhu.showIdentity(); + game.zhu.update(); + game.zhu = player; + }, + }, + nstianji: { + trigger: { global: "dying" }, + priority: 6, + unique: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return event.player.hp <= 0 && event.player != player; + }, + logTarget: "player", + check(event, player) { + return get.attitude(player, event.player) > 1; + }, + content() { + "step 0"; + player.awakenSkill("nstianji"); + player.loseMaxHp(); + "step 1"; + trigger.player.recover(1 - trigger.player.hp); + "step 2"; + trigger.player.gainMaxHp(); + }, + }, + nsbugua: { + group: "nsbugua_use", + ai: { + threaten: 1.4, + }, + subSkill: { + use: { + enable: "phaseUse", + usable: 1, + filterCard: true, + check(card) { + return 9 - get.value(card); + }, + filter(event, player) { + // if(!player.storage.nstuiyan2_done&&player.getStat().skill.nsbugua_use){ + // return false; + // } + return player.countCards("he"); + }, + position: "he", + ai: { + order: 9.5, + result: { + player: 1, + }, + }, + content() { + "step 0"; + player.throwDice(); + "step 1"; + var cards = get.cards(6); + var cards2 = cards.slice(0); + var card = cards2.splice(event.num - 1, 1)[0]; + player + .showCards(get.translation(player) + "亮出了" + get.translation(card), cards) + .set("hiddencards", cards2); + card.discard(); + var name = null; + switch (get.suit(card)) { + case "club": { + if (card.number % 2 == 0) { + name = "guohe"; + } else { + name = "jiedao"; + } + break; + } + case "spade": { + if (card.number % 2 == 0) { + name = "nanman"; + } else { + name = "juedou"; + } + break; + } + case "diamond": { + if (card.number % 2 == 0) { + name = "shunshou"; + } else { + name = "huogong"; + } + break; + } + case "heart": { + if (card.number % 2 == 0) { + name = "wuzhong"; + } else { + name = "wanjian"; + } + break; + } + } + var togain = get.cardPile(name, "cardPile"); + if (togain) { + player.gain(togain, "gain2"); + } else { + player.draw(); + } + event.list = cards2; + "step 2"; + player.chooseCardButton( + event.list, + true, + "按顺序将牌置于牌堆顶(先选择的在上)", + event.list.length + ); + "step 3"; + var list = result.links.slice(0); + while (list.length) { + ui.cardPile.insertBefore(list.pop(), ui.cardPile.firstChild); + } + }, + }, + twice: {}, + }, + }, + nstuiyan: { + trigger: { player: "useCard" }, + filter(event, player) { + return ( + _status.currentPhase == player && + event.getParent("phaseUse", true) && + !player.hasSkill("nstuiyan_fail") && + typeof player.storage.nstuiyan == "number" && + event.card.number > player.storage.nstuiyan + ); + }, + frequent: true, + priority: 2, + content() { player.draw(); }, - onremove(player){ + onremove(player) { delete player.storage.nstuiyan; delete player.storage.nstuiyan_done; delete player.storage.nstuiyan2; delete player.storage.nstuiyan2_done; }, - intro:{ - mark(dialog,content,player){ - if(player.storage.nstuiyan_done){ - dialog.addText('推演摸牌已结束'); + intro: { + mark(dialog, content, player) { + if (player.storage.nstuiyan_done) { + dialog.addText("推演摸牌已结束"); + } else { + dialog.addText("上一张点数:" + player.storage.nstuiyan); } - else{ - dialog.addText('上一张点数:'+player.storage.nstuiyan); - } - if(player.storage.nstuiyan2_done){ - dialog.addText('总点数8的倍数已达成'); - } - else{ - dialog.addText('总点数:'+player.storage.nstuiyan2); + if (player.storage.nstuiyan2_done) { + dialog.addText("总点数8的倍数已达成"); + } else { + dialog.addText("总点数:" + player.storage.nstuiyan2); } }, - content(storage,player){ - var str=''; - if(player.storage.nstuiyan_done){ - str+='推演摸牌已结束;' + content(storage, player) { + var str = ""; + if (player.storage.nstuiyan_done) { + str += "推演摸牌已结束;"; + } else { + str += "上一张牌点数:" + storage + ";"; } - else{ - str+='上一张牌点数:'+storage+';'; - } - if(player.storage.nstuiyan2_done){ - str+='总点数8的倍数已达成'; - } - else{ - str+='总点数:'+player.storage.nstuiyan2; + if (player.storage.nstuiyan2_done) { + str += "总点数8的倍数已达成"; + } else { + str += "总点数:" + player.storage.nstuiyan2; } return str; }, - markcount(storage,player){ - if(player.storage.nstuiyan2_done){ - if(player.storage.nstuiyan_done){ + markcount(storage, player) { + if (player.storage.nstuiyan2_done) { + if (player.storage.nstuiyan_done) { return 0; - } - else{ + } else { return player.storage.nstuiyan; } - } - else{ + } else { return player.storage.nstuiyan2; } - } + }, }, - group:['nstuiyan_use','nstuiyan_clear'], - subSkill:{ - bugua:{ - trigger:{player:'useCardAfter'}, - direct:true, - filter(event,player){ - return player.countCards('h'); + group: ["nstuiyan_use", "nstuiyan_clear"], + subSkill: { + bugua: { + trigger: { player: "useCardAfter" }, + direct: true, + filter(event, player) { + return player.countCards("h"); }, - content(){ - 'step 0' - player.removeSkill('nstuiyan_bugua'); - player.chooseToDiscard('he','推演:是否发动一次【卜卦】?').set('ai',function(card){ - return 8-get.value(card); - }).set('logSkill','nstuiyan'); - 'step 1' - if(result.bool){ - event.insert(lib.skill.nsbugua.subSkill.use.content,{player:player}); + content() { + "step 0"; + player.removeSkill("nstuiyan_bugua"); + player + .chooseToDiscard("he", "推演:是否发动一次【卜卦】?") + .set("ai", function (card) { + return 8 - get.value(card); + }) + .set("logSkill", "nstuiyan"); + "step 1"; + if (result.bool) { + event.insert(lib.skill.nsbugua.subSkill.use.content, { player: player }); } - } - }, - use:{ - trigger:{player:'useCard'}, - silent:true, - priority:-1, - filter(event,player){ - return _status.currentPhase==player&&event.getParent('phaseUse',true)&&typeof event.card.number=='number'; }, - content(){ - if(typeof player.storage.nstuiyan2!='number'){ - player.storage.nstuiyan2=0; - } - if(!player.hasSkill('nstuiyan_fail')&& - (trigger.card.number<=player.storage.nstuiyan||typeof trigger.card.number!='number')){ - player.storage.nstuiyan_done=true; - player.addTempSkill('nstuiyan_fail'); - } - player.storage.nstuiyan=trigger.card.number; - player.storage.nstuiyan2+=trigger.card.number; - if(player.storage.nstuiyan2%8==0&&!player.storage.nstuiyan2_done){ - player.storage.nstuiyan2_done=true; - player.addTempSkill('nstuiyan_bugua'); - } - player.markSkill('nstuiyan'); - } }, - clear:{ - trigger:{player:['phaseUseAfter','phaseAfter']}, - silent:true, - content(){ + use: { + trigger: { player: "useCard" }, + silent: true, + priority: -1, + filter(event, player) { + return ( + _status.currentPhase == player && + event.getParent("phaseUse", true) && + typeof event.card.number == "number" + ); + }, + content() { + if (typeof player.storage.nstuiyan2 != "number") { + player.storage.nstuiyan2 = 0; + } + if ( + !player.hasSkill("nstuiyan_fail") && + (trigger.card.number <= player.storage.nstuiyan || + typeof trigger.card.number != "number") + ) { + player.storage.nstuiyan_done = true; + player.addTempSkill("nstuiyan_fail"); + } + player.storage.nstuiyan = trigger.card.number; + player.storage.nstuiyan2 += trigger.card.number; + if (player.storage.nstuiyan2 % 8 == 0 && !player.storage.nstuiyan2_done) { + player.storage.nstuiyan2_done = true; + player.addTempSkill("nstuiyan_bugua"); + } + player.markSkill("nstuiyan"); + }, + }, + clear: { + trigger: { player: ["phaseUseAfter", "phaseAfter"] }, + silent: true, + content() { delete player.storage.nstuiyan; delete player.storage.nstuiyan_done; delete player.storage.nstuiyan2; delete player.storage.nstuiyan2_done; - player.unmarkSkill('nstuiyan'); - } + player.unmarkSkill("nstuiyan"); + }, }, - fail:{} + fail: {}, + }, + ai: { + threaten: 1.4, }, - ai:{ - threaten:1.4 - } }, - nsshijun:{ - trigger:{source:'damageBegin'}, - forced:true, - content(){ + nsshijun: { + trigger: { source: "damageBegin" }, + forced: true, + content() { trigger.num++; - trigger.nsshijun=true; + trigger.nsshijun = true; }, - subSkill:{ - hp:{ - trigger:{source:'damageAfter'}, - silent:true, - filter(event){ + subSkill: { + hp: { + trigger: { source: "damageAfter" }, + silent: true, + filter(event) { return event.nsshijun; }, - content(){ + content() { player.loseHp(); - } - } + }, + }, }, - group:'nsshijun_hp' + group: "nsshijun_hp", }, - nszhaoxin:{ - mark:true, - intro:{ - mark(dialog,content,player){ - var hs=player.getCards('h'); - if(hs.length){ + nszhaoxin: { + mark: true, + intro: { + mark(dialog, content, player) { + var hs = player.getCards("h"); + if (hs.length) { dialog.addSmall(hs); - } - else{ - dialog.addText('无手牌'); + } else { + dialog.addText("无手牌"); } }, - content(content,player){ - var hs=player.getCards('h'); - if(hs.length){ + content(content, player) { + var hs = player.getCards("h"); + if (hs.length) { return get.translation(hs); + } else { + return "无手牌"; } - else{ - return '无手牌'; - } - } + }, }, }, - nsxiuxin:{ - mod:{ - targetEnabled(card,player,target){ - var suit=get.suit(card); - if(suit&&!target.countCards('h',{suit:suit})){ + nsxiuxin: { + mod: { + targetEnabled(card, player, target) { + var suit = get.suit(card); + if (suit && !target.countCards("h", { suit: suit })) { return false; } - } - } - }, - nscangxi:{ - unique:true, - global:'nscangxi2', - zhuSkill:true, - init(player){ - player.storage.nscangxi=0; + }, }, - intro:{ - content:'手牌上限+#' - }, - mod:{ - maxHandcard(player,num){ - return num+player.storage.nscangxi; - } - } }, - nscangxi2:{ - trigger:{player:'phaseDiscardEnd'}, - filter(event,player){ - if(!event.cards||event.cards.length<=1) return false; - if(player.group!='wu') return false; - return game.hasPlayer(function(target){ - return player!=target&&target.hasZhuSkill('nscangxi',player); + nscangxi: { + unique: true, + global: "nscangxi2", + zhuSkill: true, + init(player) { + player.storage.nscangxi = 0; + }, + intro: { + content: "手牌上限+#", + }, + mod: { + maxHandcard(player, num) { + return num + player.storage.nscangxi; + }, + }, + }, + nscangxi2: { + trigger: { player: "phaseDiscardEnd" }, + filter(event, player) { + if (!event.cards || event.cards.length <= 1) return false; + if (player.group != "wu") return false; + return game.hasPlayer(function (target) { + return player != target && target.hasZhuSkill("nscangxi", player); }); }, - direct:true, - content(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current!=player&¤t.hasZhuSkill('nscangxi',player); + direct: true, + content() { + "step 0"; + var list = game.filterPlayer(function (current) { + return current != player && current.hasZhuSkill("nscangxi", player); }); list.sortBySeat(); - event.list=list; - 'step 1' - if(event.list.length){ - var current=event.list.shift(); - event.current=current; - player.chooseBool(get.prompt('nscangxi',current)).set('choice',get.attitude(player,current)>0); - } - else{ + event.list = list; + "step 1"; + if (event.list.length) { + var current = event.list.shift(); + event.current = current; + player + .chooseBool(get.prompt("nscangxi", current)) + .set("choice", get.attitude(player, current) > 0); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.logSkill('nscangxi',event.current); - player.judge(function(card){ - return _status.event.att*(get.color(card)=='black'?1:0); - }).set('att',get.sgnAttitude(player,event.current)); - } - else{ + "step 2"; + if (result.bool) { + player.logSkill("nscangxi", event.current); + player + .judge(function (card) { + return _status.event.att * (get.color(card) == "black" ? 1 : 0); + }) + .set("att", get.sgnAttitude(player, event.current)); + } else { event.goto(1); } - 'step 3' - if(result.color=='black'){ - var name=get.translation(event.current.name); - var att=0; - if(event.current.needsToDiscard()){ - att=1; + "step 3"; + if (result.color == "black") { + var name = get.translation(event.current.name); + var att = 0; + if (event.current.needsToDiscard()) { + att = 1; } - player.chooseControlList(['令'+name+'摸一张牌展示','令'+name+'手牌上永久+1','弃置一张牌并令'+name+'获得一张本回合进入弃牌堆的牌'],function(){ - return _status.event.att; - }).set('att',att); - } - else{ + player + .chooseControlList( + [ + "令" + name + "摸一张牌展示", + "令" + name + "手牌上永久+1", + "弃置一张牌并令" + name + "获得一张本回合进入弃牌堆的牌", + ], + function () { + return _status.event.att; + } + ) + .set("att", att); + } else { event.goto(1); } - 'step 4' - switch(result.index){ - case 0: event.current.draw('visible');break; + "step 4"; + switch (result.index) { + case 0: + event.current.draw("visible"); + break; case 1: { - if(typeof event.current.storage.nscangxi!='number'){ - event.current.storage.nscangxi=0; + if (typeof event.current.storage.nscangxi != "number") { + event.current.storage.nscangxi = 0; } event.current.storage.nscangxi++; - event.current.syncStorage('nscangxi'); - event.current.markSkill('nscangxi'); + event.current.syncStorage("nscangxi"); + event.current.markSkill("nscangxi"); break; } case 2: { - player.chooseToDiscard(true,'he'); + player.chooseToDiscard(true, "he"); break; } } - if(result.index!=2){ + if (result.index != 2) { event.goto(1); } - 'step 5' - if(result.bool){ - var discarded=get.discarded(); - if(discarded.length){ - event.current.chooseCardButton('选择一张获得之',discarded,true).set('ai',function(button){ - return get.value(button.link); - }); - } - else{ + "step 5"; + if (result.bool) { + var discarded = get.discarded(); + if (discarded.length) { + event.current + .chooseCardButton("选择一张获得之", discarded, true) + .set("ai", function (button) { + return get.value(button.link); + }); + } else { event.goto(1); } - } - else{ + } else { event.goto(1); } - 'step 6' - if(result.bool&&result.links&&result.links.length){ - event.current.gain(result.links,'gain2'); + "step 6"; + if (result.bool && result.links && result.links.length) { + event.current.gain(result.links, "gain2"); } event.goto(1); - } + }, }, - nswulie:{ - trigger:{player:'phaseBegin'}, - skillAnimation:true, - animationColor:'metal', - unique:true, - check(){ + nswulie: { + trigger: { player: "phaseBegin" }, + skillAnimation: true, + animationColor: "metal", + unique: true, + check() { return false; }, - filter(event,player){ - return ui.discardPile.childElementCount>0; + filter(event, player) { + return ui.discardPile.childElementCount > 0; }, - content(){ - 'step 0' - player.awakenSkill('nswulie'); + content() { + "step 0"; + player.awakenSkill("nswulie"); player.loseMaxHp(); - 'step 1' - player.chooseCardButton(Array.from(ui.discardPile.childNodes),'将至多3张任意顺置于牌堆顶(先选择的在上)',true,[1,3]); - 'step 2' - if(result.bool){ - var cards=result.links.slice(0); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop(),ui.cardPile.firstChild); + "step 1"; + player.chooseCardButton( + Array.from(ui.discardPile.childNodes), + "将至多3张任意顺置于牌堆顶(先选择的在上)", + true, + [1, 3] + ); + "step 2"; + if (result.bool) { + var cards = result.links.slice(0); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop(), ui.cardPile.firstChild); } - player.addTempSkill('nswulie_end'); + player.addTempSkill("nswulie_end"); } }, - subSkill:{ - end:{ - trigger:{player:'phaseEnd'}, - check(){ + subSkill: { + end: { + trigger: { player: "phaseEnd" }, + check() { return false; }, - filter(event,player){ - return ui.discardPile.childElementCount>0; + filter(event, player) { + return ui.discardPile.childElementCount > 0; }, - content(){ - 'step 0' + content() { + "step 0"; player.loseMaxHp(); - 'step 1' - player.chooseCardButton(Array.from(ui.discardPile.childNodes),'将至多3张任意顺置于牌堆顶(先选择的在上)',true,[1,3]); - 'step 2' - if(result.bool){ - var cards=result.links.slice(0); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop(),ui.cardPile.firstChild); + "step 1"; + player.chooseCardButton( + Array.from(ui.discardPile.childNodes), + "将至多3张任意顺置于牌堆顶(先选择的在上)", + true, + [1, 3] + ); + "step 2"; + if (result.bool) { + var cards = result.links.slice(0); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop(), ui.cardPile.firstChild); } } - } - } - } - }, - nshunyou:{ - enable:'phaseUse', - usable:1, - filterCard:{type:'basic'}, - filter(event,player){ - return player.countCards('h',{type:'basic'}); + }, + }, }, - content(){ - 'step 0' - var equip=null, trick=null; - for(var i=0;i1){ - if(!target.getEquip(_status.event.subtype)) return att; - } - return 0; - }).set('subtype',get.subtype(event.equip)); - } - else{ + "step 1"; + if (event.equip && get.owner(event.equip) == player) { + player + .chooseTarget( + "是否将" + get.translation(event.equip) + "装备给一其角色?", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 1) { + if (!target.getEquip(_status.event.subtype)) return att; + } + return 0; + }) + .set("subtype", get.subtype(event.equip)); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.line(result.targets,'green'); - player.$give(event.equip,result.targets[0]); - player.lose(event.equip,ui.special); - } - else{ + "step 2"; + if (result.bool) { + player.line(result.targets, "green"); + player.$give(event.equip, result.targets[0]); + player.lose(event.equip, ui.special); + } else { event.finish(); } - 'step 3' + "step 3"; game.delay(0.5); - 'step 4' + "step 4"; result.targets[0].equip(event.equip); - 'step 5' + "step 5"; game.delay(); }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); + }, + ai: { + order: 7, + result: { + player: 1, + }, }, - ai:{ - order:7, - result:{ - player:1 - } - } }, - nsgongjian:{ - trigger:{player:'phaseDiscardEnd'}, - forced:true, - filter(event,player){ - if(event.cards&&event.cards.length>0){ - return game.hasPlayer(function(current){ - return current.hp>player.hp; + nsgongjian: { + trigger: { player: "phaseDiscardEnd" }, + forced: true, + filter(event, player) { + if (event.cards && event.cards.length > 0) { + return game.hasPlayer(function (current) { + return current.hp > player.hp; }); } return false; }, - content(){ - 'step 0' - player.chooseTarget('恭俭:将置的牌交给一名体力值大于你的角色',function(card,player,target){ - return target.hp>player.hp; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)/Math.sqrt(target.countCards('h')+1); - }); - 'step 1' - if(result.bool){ - player.line(result.targets,'green'); - result.targets[0].gain(trigger.cards,'gain2'); + content() { + "step 0"; + player + .chooseTarget( + "恭俭:将置的牌交给一名体力值大于你的角色", + function (card, player, target) { + return target.hp > player.hp; + } + ) + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) / + Math.sqrt(target.countCards("h") + 1) + ); + }); + "step 1"; + if (result.bool) { + player.line(result.targets, "green"); + result.targets[0].gain(trigger.cards, "gain2"); } }, }, - nscaijian:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - var nh=player.countCards('h'); - return nh&&nh<=player.maxHp; + nscaijian: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + var nh = player.countCards("h"); + return nh && nh <= player.maxHp; }, - content(){ - 'step 0' + content() { + "step 0"; player.showHandcards(); - event.num=player.countCards('h'); - 'step 1' + event.num = player.countCards("h"); + "step 1"; player.directgain(get.cards(event.num)); - player.chooseCard('将'+get.cnNumber(event.num)+'张手牌以按顺序置于牌堆顶(先选择的在上)',event.num,true).set('ai',function(card){ - return -get.value(card); - }); - 'step 2' - if(result.bool){ - player.lose(result.cards,ui.special)._triggered=null; - event.cards=result.cards.slice(0); - } - else{ + player + .chooseCard( + "将" + get.cnNumber(event.num) + "张手牌以按顺序置于牌堆顶(先选择的在上)", + event.num, + true + ) + .set("ai", function (card) { + return -get.value(card); + }); + "step 2"; + if (result.bool) { + player.lose(result.cards, ui.special)._triggered = null; + event.cards = result.cards.slice(0); + } else { event.finish(); } - 'step 3' - if(player==game.me&&_status.auto){ + "step 3"; + if (player == game.me && _status.auto) { game.delay(); } - 'step 4' - while(event.cards.length){ - var current=event.cards.pop(); + "step 4"; + while (event.cards.length) { + var current = event.cards.pop(); current.fix(); - ui.cardPile.insertBefore(current,ui.cardPile.firstChild); + ui.cardPile.insertBefore(current, ui.cardPile.firstChild); } }, - ai:{ - order:10, - result:{ - player:1 - } - } + ai: { + order: 10, + result: { + player: 1, + }, + }, }, - nsdongcha:{ - trigger:{player:'damageBefore'}, - forced:true, - priority:15, - filter(event,player){ - if(get.type(event.card,'trick')=='trick'){ - if(event.getParent(2).name=='useCard'){ - return event.getParent(2).targets.length==1; + nsdongcha: { + trigger: { player: "damageBefore" }, + forced: true, + priority: 15, + filter(event, player) { + if (get.type(event.card, "trick") == "trick") { + if (event.getParent(2).name == "useCard") { + return event.getParent(2).targets.length == 1; } return true; } return false; }, - content(){ + content() { trigger.cancel(); }, - ai:{ - notrick:true, - effect:{ - target(card,player,target,current){ - if(get.type(card)=='trick'&&get.tag(card,'damage')&&!get.tag(card,'multitarget')){ - return 'zeroplayertarget'; + ai: { + notrick: true, + effect: { + target(card, player, target, current) { + if ( + get.type(card) == "trick" && + get.tag(card, "damage") && + !get.tag(card, "multitarget") + ) { + return "zeroplayertarget"; } - } - } - }, - group:'nsdongcha_cancel', - subSkill:{ - cancel:{ - trigger:{target:'useCardToAfter'}, - silent:true, - filter(event,player){ - return get.type(event.card,'trick')=='trick'&&_status.currentPhase==event.player&&event.player!=player; }, - content(){ - player.addTempSkill('nsdongcha_disable'); - } }, - disable:{ - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - onremove:true, - filter(event,player){ - return (event.player==_status.currentPhase&&get.type(event.card,'trick')=='trick'); + }, + group: "nsdongcha_cancel", + subSkill: { + cancel: { + trigger: { target: "useCardToAfter" }, + silent: true, + filter(event, player) { + return ( + get.type(event.card, "trick") == "trick" && + _status.currentPhase == event.player && + event.player != player + ); }, - content(){ + content() { + player.addTempSkill("nsdongcha_disable"); + }, + }, + disable: { + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + onremove: true, + filter(event, player) { + return ( + event.player == _status.currentPhase && + get.type(event.card, "trick") == "trick" + ); + }, + content() { trigger.cancel(); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.type(card,'trick')=='trick'&&_status.currentPhase==player) return 'zeroplayertarget'; - } - } - } - } - } + ai: { + effect: { + target(card, player, target, current) { + if (get.type(card, "trick") == "trick" && _status.currentPhase == player) + return "zeroplayertarget"; + }, + }, + }, + }, + }, }, - nsjianxiong:{ - trigger:{target:'useCardToBefore'}, - direct:true, - content(){ - 'step 0' - player.chooseToUse(function(card){ - return !get.info(card).multitarget; - },get.prompt('nsjianxiong',trigger.player),trigger.player,-1); - 'step 1' - if(event.damaged){ + nsjianxiong: { + trigger: { target: "useCardToBefore" }, + direct: true, + content() { + "step 0"; + player.chooseToUse( + function (card) { + return !get.info(card).multitarget; + }, + get.prompt("nsjianxiong", trigger.player), + trigger.player, + -1 + ); + "step 1"; + if (event.damaged) { trigger.cancel(); - if(get.color(trigger.card)=='black'){ + if (get.color(trigger.card) == "black") { player.draw(); } } }, - subSkill:{ - damage:{ - trigger:{source:'damageAfter'}, - silent:true, - filter(event,player){ - return event.getParent(4).name=='nsjianxiong'; + subSkill: { + damage: { + trigger: { source: "damageAfter" }, + silent: true, + filter(event, player) { + return event.getParent(4).name == "nsjianxiong"; }, - content(){ - trigger.getParent(4).damaged=true; - } - } + content() { + trigger.getParent(4).damaged = true; + }, + }, }, - group:'nsjianxiong_damage', - ai:{ - effect:{ - player(card,player,target){ - if(_status.currentPhase!=player) return; - if(get.tag(card,'damage')&&!player.needsToDiscard(1)&&target.hp>1){ - return 'zeroplayertarget'; + group: "nsjianxiong_damage", + ai: { + effect: { + player(card, player, target) { + if (_status.currentPhase != player) return; + if (get.tag(card, "damage") && !player.needsToDiscard(1) && target.hp > 1) { + return "zeroplayertarget"; } - } - } - } + }, + }, + }, }, - nsxionglue:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h',{color:'black'}); + nsxionglue: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h", { color: "black" }); }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - filterCard:{color:'black'}, - content(){ - 'step 0' - var list=get.inpile('trick'); - list=list.randomGets(3); - for(var i=0;i1; + nshuanhuo: { + trigger: { player: ["loseHpAfter", "damageAfter"] }, + filter(event, player) { + if ( + game.countPlayer(function (current) { + return current != player && !current.isUnseen(2); + }) < 2 + ) + return false; + if (event.name == "damage") return event.num > 1; return true; }, - direct:true, - skillAnimation:true, - animationColor:'thunder', - content(){ - 'step 0' - player.chooseTarget(2,get.prompt2('nshuanhuo'),function(card,player,target){ - return target!=player&&!target.isUnseen(2); - }).set('ai',function(target){ - var att=get.attitude(player,target); - if(ui.selected.targets.length){ - if(att<0){ - return get.rank(target,true)-get.rank(ui.selected.targets[0],true); + direct: true, + skillAnimation: true, + animationColor: "thunder", + content() { + "step 0"; + player + .chooseTarget(2, get.prompt2("nshuanhuo"), function (card, player, target) { + return target != player && !target.isUnseen(2); + }) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (ui.selected.targets.length) { + if (att < 0) { + return get.rank(target, true) - get.rank(ui.selected.targets[0], true); + } + } else { + if (att >= 0) { + return 1 / (1 + get.rank(target, true)); + } } - } - else{ - if(att>=0){ - return 1/(1+get.rank(target,true)); - } - } - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('nshuanhuo',result.targets); - } - else{ + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("nshuanhuo", result.targets); + } else { event.finish(); } - 'step 2' - var name1=result.targets[0].name; - var name2=result.targets[1].name; - result.targets[0].reinit(name1,name2,false); - result.targets[1].reinit(name2,name1,false); - } + "step 2"; + var name1 = result.targets[0].name; + var name2 = result.targets[1].name; + result.targets[0].reinit(name1, name2, false); + result.targets[1].reinit(name2, name1, false); + }, }, - nsyaowang:{ - trigger:{player:'phaseBegin'}, - direct:true, - createDialog(player,target,onlylist){ - var names=[]; - var list=[]; - 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;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); return dialog; }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('nsyaowang'),function(card,player,target){ - var names=[]; - 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 Math.random(); - return 0; - }); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('nsyaowang',event.target); - } - else{ + }) + .set("ai", function (target) { + if (get.attitude(_status.event.player, target) > 0) return Math.random(); + return 0; + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("nsyaowang", event.target); + } else { event.finish(); } - 'step 2' - event.skillai=function(list){ - return get.max(list,get.skillRank,'item'); + "step 2"; + event.skillai = function (list) { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - event.dialog=lib.skill.nsyaowang.createDialog(player,target); - event.switchToAuto=function(){ - event._result=event.skillai(event.list); + if (event.isMine()) { + event.dialog = lib.skill.nsyaowang.createDialog(player, target); + event.switchToAuto = function () { + event._result = event.skillai(event.list); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(lib.skill.nsyaowang.createDialog(player, target, true)); } - else{ - event._result=event.skillai(lib.skill.nsyaowang.createDialog(player,target,true)); - } - 'step 3' - _status.imchoosing=false; - if(event.dialog){ + "step 3"; + _status.imchoosing = false; + if (event.dialog) { event.dialog.close(); } player.addTempSkill(result); player.popup(result); - game.log(player,'获得了','【'+get.translation(result)+'】'); - var names=[]; - for(var i=0;i2){ - return att*2; + group: "nsyunxing_self", + subSkill: { + self: { + trigger: { player: "dieBegin" }, + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt("nsyunxing"), function (card, player, target) { + return target != player; + }) + .set("prompt2", "令一名其他角色翻面") + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.isTurnedOver()) { + if (att > 2) { + return att * 2; + } else { + return att; + } + } else { + return -att; } - else{ - return att; - } - } - else{ - return -att; - } - }); - 'step 1' - if(result.bool){ - player.logSkill('nsyunxing',result.targets); + }); + "step 1"; + if (result.bool) { + player.logSkill("nsyunxing", result.targets); result.targets[0].turnOver(); } - } - } - } - }, - nsguanxing:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return player.hp>0; + }, + }, }, - content(){ - 'step 0' - event.cards=get.cards(game.countPlayer()); - event.chosen=[]; - event.num=player.hp; - 'step 1' - var js=player.getCards('j'); + }, + nsguanxing: { + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return player.hp > 0; + }, + content() { + "step 0"; + event.cards = get.cards(game.countPlayer()); + event.chosen = []; + event.num = player.hp; + "step 1"; + var js = player.getCards("j"); var pos; - var choice=-1; - var getval=function(card,pos){ - if(js[pos]){ - return (get.judge(js[pos]))(card); - } - else{ + var choice = -1; + var getval = function (card, pos) { + if (js[pos]) { + return get.judge(js[pos])(card); + } else { return get.value(card); } }; - for(pos=0;posmax){ - choice=j; - max=current; + for (pos = 0; pos < Math.min(event.cards.length, js.length + 2); pos++) { + var max = getval(event.cards[pos], pos); + for (var j = pos + 1; j < event.cards.length; j++) { + var current = getval(event.cards[j], pos); + if (current > max) { + choice = j; + max = current; } } - if(choice!=-1){ + if (choice != -1) { break; } } - player.chooseCardButton('观星:选择要移动的牌(还能移动'+event.num+'张)',event.cards).set('filterButton',function(button){ - return !_status.event.chosen.includes(button.link); - }).set('chosen',event.chosen).set('ai',function(button){ - return button.link==_status.event.choice?1:0; - }).set('choice',event.cards[choice]); - event.pos=pos; - 'step 2' - if(result.bool){ - var card=result.links[0]; - var index=event.cards.indexOf(card); - event.card=card; + player + .chooseCardButton("观星:选择要移动的牌(还能移动" + event.num + "张)", event.cards) + .set("filterButton", function (button) { + return !_status.event.chosen.includes(button.link); + }) + .set("chosen", event.chosen) + .set("ai", function (button) { + return button.link == _status.event.choice ? 1 : 0; + }) + .set("choice", event.cards[choice]); + event.pos = pos; + "step 2"; + if (result.bool) { + var card = result.links[0]; + var index = event.cards.indexOf(card); + event.card = card; event.chosen.push(card); event.cards.remove(event.card); - var buttons=event.cards.slice(0); - player.chooseControl(function(){ - return _status.event.controlai; - }).set('controlai',event.pos||0).set('sortcard',buttons).set('tosort',card); - } - else{ + var buttons = event.cards.slice(0); + player + .chooseControl(function () { + return _status.event.controlai; + }) + .set("controlai", event.pos || 0) + .set("sortcard", buttons) + .set("tosort", card); + } else { event.goto(4); } - 'step 3' - if(typeof result.index=='number'){ - if(result.index>event.cards.length){ + "step 3"; + if (typeof result.index == "number") { + if (result.index > event.cards.length) { ui.cardPile.appendChild(event.card); - } - else{ - event.cards.splice(result.index,0,event.card); + } else { + event.cards.splice(result.index, 0, event.card); } event.num--; - if(event.num>0){ + if (event.num > 0) { event.goto(1); } } - 'step 4' - while(event.cards.length){ - ui.cardPile.insertBefore(event.cards.pop(),ui.cardPile.firstChild); + "step 4"; + while (event.cards.length) { + ui.cardPile.insertBefore(event.cards.pop(), ui.cardPile.firstChild); } - var js=player.getCards('j'); - if(js.length==1){ - if((get.judge(js[0]))(ui.cardPile.firstChild)<0){ - player.addTempSkill('guanxing_fail'); + var js = player.getCards("j"); + if (js.length == 1) { + if (get.judge(js[0])(ui.cardPile.firstChild) < 0) { + player.addTempSkill("guanxing_fail"); } } }, - ai:{ - guanxing:true - } - }, - nshaoling:{ - skillAnimation:true, - animationColor:'water', - unique:true, - limited:true, - enable:'phaseUse', - filterTarget(card,player,target){ - return target!=player; + ai: { + guanxing: true, }, - content(){ - "step 0" - player.awakenSkill('nshaoling'); - event.targets=game.filterPlayer(); + }, + nshaoling: { + skillAnimation: true, + animationColor: "water", + unique: true, + limited: true, + enable: "phaseUse", + filterTarget(card, player, target) { + return target != player; + }, + content() { + "step 0"; + player.awakenSkill("nshaoling"); + event.targets = game.filterPlayer(); event.targets.remove(player); event.targets.remove(target); event.targets.sortBySeat(); - "step 1" - if(event.targets.length){ - event.current=event.targets.shift(); - if(event.current.countCards('he')&&target.isAlive()){ - event.current.chooseToUse({name:'sha'},target,-1,'号令').set('prompt2','选择一项:1. 对'+get.translation(event.current)+'使用一张杀;2. 取消并交给'+get.translation(player)+'一张牌,然后视'+get.translation(player)+'为对你使用一张杀'); + "step 1"; + if (event.targets.length) { + event.current = event.targets.shift(); + if (event.current.countCards("he") && target.isAlive()) { + event.current + .chooseToUse({ name: "sha" }, target, -1, "号令") + .set( + "prompt2", + "选择一项:1. 对" + + get.translation(event.current) + + "使用一张杀;2. 取消并交给" + + get.translation(player) + + "一张牌,然后视" + + get.translation(player) + + "为对你使用一张杀" + ); } - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool==false){ - if(event.current.countCards('he')){ - event.current.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); - } - else{ + "step 2"; + if (result.bool == false) { + if (event.current.countCards("he")) { + event.current.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); + } else { event.goto(4); } - } - else{ + } else { event.goto(1); } - "step 3" - if(result.bool){ - event.current.give(result.cards,player); + "step 3"; + if (result.bool) { + event.current.give(result.cards, player); } - "step 4" - player.useCard({name:'sha'},event.current,false); + "step 4"; + player.useCard({ name: "sha" }, event.current, false); event.goto(1); }, - ai:{ - order:5, - result:{ - target(player,target){ - var players=game.filterPlayer(); - if(player.hp>1){ - if(game.phaseNumber 1) { + if (game.phaseNumber < game.players.length) return 0; + if (player.hasUnknown()) return 0; } - var effect=0; - for(var i=0;i0; + }, }, - threaten:1.5, - save:true, - respondTao:true, - } + }, }, - nscaiyi:{ - trigger:{global:'drawAfter'}, - check(event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(get.effect(event.player,{name:'sha'},player,player)<=0) return false; - if(get.effect(player,{name:'sha'},event.player,player)>=0) return true; - return player.hasShan()&&player.hp>=event.player.hp; + nsgefa: { + enable: "chooseToUse", + filter(event, player) { + return player.hp <= 0; }, - filter(event,player){ - return player!=event.player&&Array.isArray(event.result)&&event.result.length>0; + filterCard: { suit: "club" }, + position: "hse", + viewAs: { name: "tao" }, + prompt: "将一张梅花牌当桃使用", + check(card) { + return 15 - get.value(card); }, - logTarget:'player', - content(){ - 'step 0' - player.viewCards(get.translation(trigger.player)+'摸到的牌',trigger.result); - if(!event.isMine()){ + ai: { + skillTagFilter(player) { + return player.countCards("hes", { suit: "club" }) > 0; + }, + threaten: 1.5, + save: true, + respondTao: true, + }, + }, + nscaiyi: { + trigger: { global: "drawAfter" }, + check(event, player) { + if (get.attitude(player, event.player) >= 0) return false; + if (get.effect(event.player, { name: "sha" }, player, player) <= 0) return false; + if (get.effect(player, { name: "sha" }, event.player, player) >= 0) return true; + return player.hasShan() && player.hp >= event.player.hp; + }, + filter(event, player) { + return player != event.player && Array.isArray(event.result) && event.result.length > 0; + }, + logTarget: "player", + content() { + "step 0"; + player.viewCards(get.translation(trigger.player) + "摸到的牌", trigger.result); + if (!event.isMine()) { game.delayx(); } - 'step 1' - var list=[]; - for(var i=0;i0; }, - content(){ + }, + nspinmin: { + trigger: { player: "dieBefore" }, + forced: true, + filter(event, player) { + return player.maxHp > 0; + }, + content() { trigger.cancel(); - player.hp=1; + player.hp = 1; player.update(); - if(_status.currentPhase==player){ - var num=4; + if (_status.currentPhase == player) { + var num = 4; // if(game.countPlayer()>=7){ // num=5; // } - if(!player.hasSkill('nspinmin_used')&&player.maxHp=4){ + group: "nsshishou_use", + subSkill: { + use: { + mod: { + cardEnabled(card, player) { + if (_status.currentPhase != player) return; + if (get.cardCount(true, player) >= 4) { return false; } - } - } - } + }, + }, + }, }, - ai:{ - effect:{ - target(card,player,target){ - if(get.tag(card,'save')){ - if(_status.currentPhase==player) return 0; - if(target.maxHp>1&&player!=target) return 0; + ai: { + effect: { + target(card, player, target) { + if (get.tag(card, "save")) { + if (_status.currentPhase == player) return 0; + if (target.maxHp > 1 && player != target) return 0; } - if(get.tag(card,'recover')){ - if(_status.currentPhase==player) return 0; + if (get.tag(card, "recover")) { + if (_status.currentPhase == player) return 0; } - } - } - } + }, + }, + }, }, - nsduijue:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter(event,player){ - return player.countCards('h'); + nsduijue: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter(event, player) { + return player.countCards("h"); }, - content(){ - "step 0" - var color={ - black:player.countCards('h',function(card){ - return get.color(card)=='red'&&get.value(card)<8; + content() { + "step 0"; + var color = { + black: player.countCards("h", function (card) { + return get.color(card) == "red" && get.value(card) < 8; + }), + red: player.countCards("h", function (card) { + return get.color(card) == "black" && get.value(card) < 8; }), - red:player.countCards('h',function(card){ - return get.color(card)=='black'&&get.value(card)<8; - }) }; - player.chooseToDiscard(get.prompt2('nsduijue')).set('ai',function(card){ - var num=_status.event.color[get.color(card)]; - if(_status.event.goon&&num>=1){ - return 7+num-get.value(card); - } - }).set('goon',game.hasPlayer(function(current){ - return get.effect(current,{name:'juedou'},player,player)>0; - })).set('color',color).set('logSkill','nsduijue'); - "step 1" - if(result.bool){ - player.addTempSkill('nsduijue_use'); - player.storage.nsduijue_use=get.color(result.cards[0]); + player + .chooseToDiscard(get.prompt2("nsduijue")) + .set("ai", function (card) { + var num = _status.event.color[get.color(card)]; + if (_status.event.goon && num >= 1) { + return 7 + num - get.value(card); + } + }) + .set( + "goon", + game.hasPlayer(function (current) { + return get.effect(current, { name: "juedou" }, player, player) > 0; + }) + ) + .set("color", color) + .set("logSkill", "nsduijue"); + "step 1"; + if (result.bool) { + player.addTempSkill("nsduijue_use"); + player.storage.nsduijue_use = get.color(result.cards[0]); } }, - subSkill:{ - use:{ - enable:'phaseUse', - viewAs:{name:'juedou'}, - usable:2, - filter(event,player){ - return player.hasCard(function(card){ - return get.color(card)!=player.storage.nsduijue_use; - },'hs'); + subSkill: { + use: { + enable: "phaseUse", + viewAs: { name: "juedou" }, + usable: 2, + filter(event, player) { + return player.hasCard(function (card) { + return get.color(card) != player.storage.nsduijue_use; + }, "hs"); }, - position:'hs', - filterCard(card,player){ - return get.color(card)!=player.storage.nsduijue_use; + position: "hs", + filterCard(card, player) { + return get.color(card) != player.storage.nsduijue_use; }, - check(card){ - return 8-get.value(card); + check(card) { + return 8 - get.value(card); }, - ai:{ - basic:{ - order:10 - } - } - } - } + ai: { + basic: { + order: 10, + }, + }, + }, + }, }, - nsshuangxiong:{ - trigger:{player:'juedouBegin',target:'juedouBegin'}, - check(event,player){ + nsshuangxiong: { + trigger: { player: "juedouBegin", target: "juedouBegin" }, + check(event, player) { return player.isTurnedOver(); }, - content(){ + content() { player.turnOver(); - } - }, - nsguanyong:{ - enable:'chooseToRespond', - filterCard:true, - viewAs:{name:'sha'}, - viewAsFilter(player){ - if(!player.countCards('hs')) return false; }, - position:'hs', - prompt:'将一张手牌当杀打出', - check(card){return 7-get.value(card)}, - ai:{ - respondSha:true, - skillTagFilter(player,tag,arg){ - if(arg!='respond') return false; - if(!player.countCards('hs')) return false; + }, + nsguanyong: { + enable: "chooseToRespond", + filterCard: true, + viewAs: { name: "sha" }, + viewAsFilter(player) { + if (!player.countCards("hs")) return false; + }, + position: "hs", + prompt: "将一张手牌当杀打出", + check(card) { + return 7 - get.value(card); + }, + ai: { + respondSha: true, + skillTagFilter(player, tag, arg) { + if (arg != "respond") return false; + if (!player.countCards("hs")) return false; }, - } - }, - nsjihui:{ - trigger:{global:'discardAfter'}, - filter(event,player){ - return event.cards.length>=3; }, - content(){ + }, + nsjihui: { + trigger: { global: "discardAfter" }, + filter(event, player) { + return event.cards.length >= 3; + }, + content() { player.insertPhase(); - player.storage.nsjihui_use=_status.currentPhase; - player.addSkill('nsjihui_use'); + player.storage.nsjihui_use = _status.currentPhase; + player.addSkill("nsjihui_use"); }, - subSkill:{ - use:{ - mark:'character', - intro:{ - content:'使用牌只能指定自己与$为目标' + subSkill: { + use: { + mark: "character", + intro: { + content: "使用牌只能指定自己与$为目标", }, - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='nsjihui'; + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + filter(event, player) { + return event.skill == "nsjihui"; }, - onremove:true, - content(){ - player.removeSkill('nsjihui_use'); + onremove: true, + content() { + player.removeSkill("nsjihui_use"); }, - mod:{ - playerEnabled(card,player,target){ - if(player!=target&&player.storage.nsjihui_use!=target) return false; - } - } - } - } + mod: { + playerEnabled(card, player, target) { + if (player != target && player.storage.nsjihui_use != target) return false; + }, + }, + }, + }, }, - nsmouyun:{ - enable:'phaseUse', - round:2, - filterTarget(card,player,target){ - return target.isMinHp()&&target!=player&&target.isDamaged(); + nsmouyun: { + enable: "phaseUse", + round: 2, + filterTarget(card, player, target) { + return target.isMinHp() && target != player && target.isDamaged(); }, - content(){ - if(target.isDamaged()){ - player.discardPlayerCard(target,'hej',target.maxHp-target.hp,true); + content() { + if (target.isDamaged()) { + player.discardPlayerCard(target, "hej", target.maxHp - target.hp, true); } }, - ai:{ - order:10, - result:{ - target(player,target){ - return target.hp-target.maxHp; - } - } - } + ai: { + order: 10, + result: { + target(player, target) { + return target.hp - target.maxHp; + }, + }, + }, }, - nscongjun:{ - forbid:['guozhan'], - unique:true, - forceunique:true, - init(player){ - if(player.storage.nscongjun_show) return false; - var change=function(target){ - if(target==player){ + nscongjun: { + forbid: ["guozhan"], + unique: true, + forceunique: true, + init(player) { + if (player.storage.nscongjun_show) return false; + var change = function (target) { + if (target == player) { var list; - if(_status.connectMode){ - list=get.charactersOL(function(i){ - return lib.character[i][0]!='male'; + if (_status.connectMode) { + list = get.charactersOL(function (i) { + return lib.character[i][0] != "male"; + }); + } else { + list = get.gainableCharacters(function (info) { + return info[0] == "male"; }); } - else{ - list=get.gainableCharacters(function(info){ - return info[0]=='male'; - }); - } - var name=list.randomGet(); - target.reinit('ns_huamulan',name,'nosmooth'); - target.storage.nscongjun_show=name; - target.addSkill('nscongjun_show'); + var name = list.randomGet(); + target.reinit("ns_huamulan", name, "nosmooth"); + target.storage.nscongjun_show = name; + target.addSkill("nscongjun_show"); player._inits.remove(change); - player.hp=player.maxHp; + player.hp = player.maxHp; player.update(); } - } - if(!player._inits){ - player._inits=[]; + }; + if (!player._inits) { + player._inits = []; } player._inits.push(change); }, - subSkill:{ - show:{ - trigger:{global:'useCard'}, - filter(event,player){ - return player.getEnemies().includes(event.player)&&event.card.name=='wuxie'&&event.getRand()<0.1; + subSkill: { + show: { + trigger: { global: "useCard" }, + filter(event, player) { + return ( + player.getEnemies().includes(event.player) && + event.card.name == "wuxie" && + event.getRand() < 0.1 + ); }, - direct:true, - skillAnimation:true, - animationColor:'thunder', - content(){ - 'step 0' + direct: true, + skillAnimation: true, + animationColor: "thunder", + content() { + "step 0"; game.delay(0.5); - 'step 1' - player.reinit(player.storage.nscongjun_show,'ns_huamulan','nosmooth'); - player.logSkill('nscongjun_show'); - 'step 2' - player.removeSkill('nscongjun_show'); - player.line(trigger.player,'green'); + "step 1"; + player.reinit(player.storage.nscongjun_show, "ns_huamulan", "nosmooth"); + player.logSkill("nscongjun_show"); + "step 2"; + player.removeSkill("nscongjun_show"); + player.line(trigger.player, "green"); trigger.player.damage(2); - } - } - } + }, + }, + }, }, - nstaiping_nh:{ - trigger:{player:'damageEnd'}, - filter(event,player){ - return !event.nshuanxian&&player.getSubPlayers('nshuanxian').length; + nstaiping_nh: { + trigger: { player: "damageEnd" }, + filter(event, player) { + return !event.nshuanxian && player.getSubPlayers("nshuanxian").length; }, - direct:true, - priority:-0.1, - ai:{ - maixie:true, - maixie_hp:true + direct: true, + priority: -0.1, + ai: { + maixie: true, + maixie_hp: true, }, - content(){ - 'step 0' - event.num=trigger.num; - 'step 1' - var left=player.storage.nshuanxian_left; - var right=player.storage.nshuanxian_right; - var list=[]; - var choice=0; - var hpleft=0; - var maxleft=0; - if(left&&player.hasSkill(left)){ - if(player.storage[left].hp1){ + "step 3"; + if (event.num > 1) { event.num--; event.goto(1); } - } + }, + ai: { + combo: "nshuanxian" + }, }, - nsshoudao:{ - group:['nsshoudao_gain','nsshoudao_die'], - subSkill:{ - gain:{ - trigger:{player:'subPlayerDie'}, - forced:true, - filter(event,player){ - var left=player.storage.nshuanxian_left; - if(left&&player.hasSkill(left)) return false; - var right=player.storage.nshuanxian_right; - if(right&&player.hasSkill(right)) return false; - if(!player.storage.nshuanxian_damage) return false; + nsshoudao: { + group: ["nsshoudao_gain", "nsshoudao_die"], + subSkill: { + gain: { + trigger: { player: "subPlayerDie" }, + forced: true, + filter(event, player) { + var left = player.storage.nshuanxian_left; + if (left && player.hasSkill(left)) return false; + var right = player.storage.nshuanxian_right; + if (right && player.hasSkill(right)) return false; + if (!player.storage.nshuanxian_damage) return false; return true; }, - content(){ - player.addSkill('releiji'); - player.addSkill('guidao'); - } + content() { + player.addSkill("releiji"); + player.addSkill("guidao"); + }, }, - die:{ - trigger:{player:'dieBegin'}, - direct:true, - filter(event,player){ - if(game.countPlayer()<=2) return false; - var left=player.storage.nshuanxian_left; - if(left&&player.hasSkill(left)) return true; - var right=player.storage.nshuanxian_right; - if(right&&player.hasSkill(right)) return true; + die: { + trigger: { player: "dieBegin" }, + direct: true, + filter(event, player) { + if (game.countPlayer() <= 2) return false; + var left = player.storage.nshuanxian_left; + if (left && player.hasSkill(left)) return true; + var right = player.storage.nshuanxian_right; + if (right && player.hasSkill(right)) return true; return false; }, - content(){ - 'step 0' + content() { + "step 0"; var str; - var left=player.storage.nshuanxian_left; - var right=player.storage.nshuanxian_right; - if(left&&player.hasSkill(left)&&right&&player.hasSkill(right)){ - str='令一名其他角色获得技能【雷击】和【鬼道】'; + var left = player.storage.nshuanxian_left; + var right = player.storage.nshuanxian_right; + if (left && player.hasSkill(left) && right && player.hasSkill(right)) { + str = "令一名其他角色获得技能【雷击】和【鬼道】"; + } else { + str = "令一名其他角色获得技能【雷击】或【鬼道】"; } - else{ - str='令一名其他角色获得技能【雷击】或【鬼道】'; + if (trigger.source) { + str += "(" + get.translation(trigger.source) + "除外)"; } - if(trigger.source){ - str+='('+get.translation(trigger.source)+'除外)'; - } - player.chooseTarget(function(card,player,target){ - return target!=player&&target!=_status.event.source; - },get.prompt('nsshoudao')).set('ai',function(target){ - if(target.hasSkill('releiji')) return 0; - return get.attitude(_status.event.player,target); - }).set('source',trigger.source).set('prompt2',str); - 'step 1' - var goon=false; - if(result.bool){ - var target=result.targets[0]; - player.logSkill('nsshoudao',target); - var left=player.storage.nshuanxian_left; - var right=player.storage.nshuanxian_right; - if(left&&player.hasSkill(left)&&right&&player.hasSkill(right)){ - target.addSkillLog('releiji'); - target.addSkillLog('guidao'); - } - else{ - event.target=target; - player.chooseControl('releiji','guidao').set('prompt','令'+get.translation(target)+'获得一项技能'); - goon=true; + player + .chooseTarget(function (card, player, target) { + return target != player && target != _status.event.source; + }, get.prompt("nsshoudao")) + .set("ai", function (target) { + if (target.hasSkill("releiji")) return 0; + return get.attitude(_status.event.player, target); + }) + .set("source", trigger.source) + .set("prompt2", str); + "step 1"; + var goon = false; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("nsshoudao", target); + var left = player.storage.nshuanxian_left; + var right = player.storage.nshuanxian_right; + if (left && player.hasSkill(left) && right && player.hasSkill(right)) { + target.addSkillLog("releiji"); + target.addSkillLog("guidao"); + } else { + event.target = target; + player + .chooseControl("releiji", "guidao") + .set("prompt", "令" + get.translation(target) + "获得一项技能"); + goon = true; } } - if(!goon){ + if (!goon) { event.finish(); } - 'step 2' + "step 2"; event.target.addSkillLog(result.control); - } - } - } + }, + }, + }, + ai: { + combo: "nshuanxian" + }, }, - nshuanxian:{ - trigger:{global:'gameStart',player:'enterGame'}, - forced:true, - nosub:true, - unique:true, - group:['nshuanxian_left','nshuanxian_right','nshuanxian_damage','nshuanxian_swap','nshuanxian_draw'], - content(){ - player.storage.nshuanxian_right=player.addSubPlayer({ - name:'ns_nanhua_right', - skills:['nshuanxian_left','nshuanxian_draw','nshuanxian_swap'], - hp:2, - maxHp:2, - hs:get.cards(2), - skill:'nshuanxian', - intro:'你的本体回合结束后,切换至此随从并进行一个额外的回合;若你的上家与下家不同,在你的下家的准备阶段,切换至此随从', - intro2:'当前回合结束后切换回本体', - onremove(player){ + nshuanxian: { + trigger: { global: "gameStart", player: "enterGame" }, + forced: true, + nosub: true, + unique: true, + group: [ + "nshuanxian_left", + "nshuanxian_right", + "nshuanxian_damage", + "nshuanxian_swap", + "nshuanxian_draw", + ], + content() { + player.storage.nshuanxian_right = player.addSubPlayer({ + name: "ns_nanhua_right", + skills: ["nshuanxian_left", "nshuanxian_draw", "nshuanxian_swap"], + hp: 2, + maxHp: 2, + hs: get.cards(2), + skill: "nshuanxian", + intro: "你的本体回合结束后,切换至此随从并进行一个额外的回合;若你的上家与下家不同,在你的下家的准备阶段,切换至此随从", + intro2: "当前回合结束后切换回本体", + onremove(player) { delete player.storage.nshuanxian_right; - } + }, }); }, - ai:{ - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(!target.hasFriend()) return; - if(target.hp<=2) return; - if(!target.storage.nshuanxian_damage){ - if(get.attitude(player,target)<0||get.tag(card,'multineg')) return [0,1]; - return [1,1]; + ai: { + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (!target.hasFriend()) return; + if (target.hp <= 2) return; + if (!target.storage.nshuanxian_damage) { + if (get.attitude(player, target) < 0 || get.tag(card, "multineg")) + return [0, 1]; + return [1, 1]; } } - } - } + }, + }, }, // mod:{ // globalFrom(from,to,distance){ @@ -15775,3238 +18743,3656 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }, // global:'nshuanxian_choose', - subSkill:{ - chosen:{}, - leftdist:{ - mod:{ - globalFrom(from,to,distance){ - }, - globalTo(from,to,distance){ - } - } - }, - rightdist:{ - mod:{ - globalFrom(from,to,distance){ - }, - globalTo(from,to,distance){ - } - } - }, - swap:{ - trigger:{global:'phaseBegin'}, - forced:true, - popup:false, - filter(event,player){ - return event.player!=player; + subSkill: { + chosen: {}, + leftdist: { + mod: { + globalFrom(from, to, distance) {}, + globalTo(from, to, distance) {}, }, - priority:20, - content(){ - var next=player.getNext(); - var prev=player.getPrevious(); - var left=player.storage.nshuanxian_left; - var right=player.storage.nshuanxian_right; - if(prev==next||(trigger.player!=next&&trigger.player!=prev)){ - if(player.hasSkill('subplayer')){ + }, + rightdist: { + mod: { + globalFrom(from, to, distance) {}, + globalTo(from, to, distance) {}, + }, + }, + swap: { + trigger: { global: "phaseBegin" }, + forced: true, + popup: false, + filter(event, player) { + return event.player != player; + }, + priority: 20, + content() { + var next = player.getNext(); + var prev = player.getPrevious(); + var left = player.storage.nshuanxian_left; + var right = player.storage.nshuanxian_right; + if (prev == next || (trigger.player != next && trigger.player != prev)) { + if (player.hasSkill("subplayer")) { player.exitSubPlayer(); } - } - else if(prev==trigger.player&&player.name!=left&&left){ - if(!player.hasSkill('subplayer')){ + } else if (prev == trigger.player && player.name != left && left) { + if (!player.hasSkill("subplayer")) { player.callSubPlayer(left); - } - else{ + } else { player.toggleSubPlayer(left); } - } - else if(next==trigger.player&&player.name!=right&&right){ - if(!player.hasSkill('subplayer')){ + } else if (next == trigger.player && player.name != right && right) { + if (!player.hasSkill("subplayer")) { player.callSubPlayer(right); - } - else{ + } else { player.toggleSubPlayer(right); } } - } + }, }, - damage:{ - trigger:{player:'damageEnd'}, - forced:true, - filter(event,player){ + damage: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { return !player.storage.nshuanxian_damage; }, - content(){ - player.storage.nshuanxian_damage=true; - player.storage.nshuanxian_left=player.addSubPlayer({ - name:'ns_nanhua_left', - skills:['nshuanxian_middle','nshuanxian_draw','nshuanxian_swap'], - hp:2, - maxHp:2, - hs:get.cards(2), - skill:'nshuanxian', - intro:'你的本体回合开始前,切换至此随从并进行一个额外的回合;若你的上家与下家不同,在你的上家的准备阶段,切换至此随从', - intro2:'当前回合结束后切换回本体', - onremove(player){ + content() { + player.storage.nshuanxian_damage = true; + player.storage.nshuanxian_left = player.addSubPlayer({ + name: "ns_nanhua_left", + skills: ["nshuanxian_middle", "nshuanxian_draw", "nshuanxian_swap"], + hp: 2, + maxHp: 2, + hs: get.cards(2), + skill: "nshuanxian", + intro: "你的本体回合开始前,切换至此随从并进行一个额外的回合;若你的上家与下家不同,在你的上家的准备阶段,切换至此随从", + intro2: "当前回合结束后切换回本体", + onremove(player) { delete player.storage.nshuanxian_left; - } + }, }); - trigger.nshuanxian=true; - } - }, - draw:{ - trigger:{player:'phaseDrawBegin'}, - silent:true, - filter(event){ - return event.num>0; + trigger.nshuanxian = true; }, - content(){ - trigger.num--; - } }, - left:{ - trigger:{player:'phaseBefore'}, - forced:true, - popup:false, - priority:40, - filter(event,player){ - if(event.skill=='nshuanxian_middle') return false; - if(event.skill=='nshuanxian_right') return false; - var left=player.storage.nshuanxian_left; - if(player.hasSkill('subplayer')){ - if(!left) return player.name==player.storage.nshuanxian_right; + draw: { + trigger: { player: "phaseDrawBegin" }, + silent: true, + filter(event) { + return event.num > 0; + }, + content() { + trigger.num--; + }, + }, + left: { + trigger: { player: "phaseBefore" }, + forced: true, + popup: false, + priority: 40, + filter(event, player) { + if (event.skill == "nshuanxian_middle") return false; + if (event.skill == "nshuanxian_right") return false; + var left = player.storage.nshuanxian_left; + if (player.hasSkill("subplayer")) { + if (!left) return player.name == player.storage.nshuanxian_right; return player.storage.subplayer.skills.includes(left); - } - else{ - if(!left) return false; + } else { + if (!left) return false; return player.hasSkill(left); } }, - content(){ - if(player.hasSkill('subplayer')){ - var left=player.storage.nshuanxian_left; - if(left&&player.storage.subplayer.skills.includes(left)){ + content() { + if (player.hasSkill("subplayer")) { + var left = player.storage.nshuanxian_left; + if (left && player.storage.subplayer.skills.includes(left)) { player.toggleSubPlayer(player.storage.nshuanxian_left); - } - else{ + } else { player.exitSubPlayer(); } - } - else{ + } else { player.callSubPlayer(player.storage.nshuanxian_left); } - } + }, }, - middle:{ - trigger:{player:['phaseAfter','phaseCancelled']}, - forced:true, - popup:false, - priority:-40, - filter(event,player){ - if(player.hasSkill('nshuanxian_chosen')) return false; + middle: { + trigger: { player: ["phaseAfter", "phaseCancelled"] }, + forced: true, + popup: false, + priority: -40, + filter(event, player) { + if (player.hasSkill("nshuanxian_chosen")) return false; return true; }, - content(){ + content() { player.exitSubPlayer(); - player.insertPhase(null,true); - } + player.insertPhase(null, true); + }, }, - right:{ - trigger:{player:['phaseAfter','phaseCancelled']}, - forced:true, - popup:false, - priority:-40, - filter(event,player){ - if(player.hasSkill('nshuanxian_chosen')) return false; - if(player.hasSkill('subplayer')) return false; - var right=player.storage.nshuanxian_right; - if(!right) return false; + right: { + trigger: { player: ["phaseAfter", "phaseCancelled"] }, + forced: true, + popup: false, + priority: -40, + filter(event, player) { + if (player.hasSkill("nshuanxian_chosen")) return false; + if (player.hasSkill("subplayer")) return false; + var right = player.storage.nshuanxian_right; + if (!right) return false; return player.hasSkill(right); }, - content(){ + content() { player.callSubPlayer(player.storage.nshuanxian_right); - player.insertPhase(null,true); - player.addTempSkill('nshuanxian_chosen',['phaseBegin','phaseCancelled']); - } + player.insertPhase(null, true); + player.addTempSkill("nshuanxian_chosen", ["phaseBegin", "phaseCancelled"]); + }, }, - end:{ - trigger:{player:['phaseAfter','phaseCancelled']}, - forced:true, - popup:false, - priority:-40, - filter(event,player){ - if(player.hasSkill('nshuanxian_chosen')) return false; + end: { + trigger: { player: ["phaseAfter", "phaseCancelled"] }, + forced: true, + popup: false, + priority: -40, + filter(event, player) { + if (player.hasSkill("nshuanxian_chosen")) return false; return true; }, - content(){ - if(player.hasSkill('subplayer')){ + content() { + if (player.hasSkill("subplayer")) { player.exitSubPlayer(); } }, - content_old(){ - 'step 0' - var controls=['本体']; - var left=player.storage.nshuanxian_left; - var right=player.storage.nshuanxian_right; - if(player.hasSkill('subplayer')){ - if(player.storage.subplayer.skills.includes(left)){ - controls.unshift('幻身·左'); + content_old() { + "step 0"; + var controls = ["本体"]; + var left = player.storage.nshuanxian_left; + var right = player.storage.nshuanxian_right; + if (player.hasSkill("subplayer")) { + if (player.storage.subplayer.skills.includes(left)) { + controls.unshift("幻身·左"); } - if(player.storage.subplayer.skills.includes(right)){ - controls.push('幻身·右'); + if (player.storage.subplayer.skills.includes(right)) { + controls.push("幻身·右"); + } + } else { + if (player.hasSkill(left)) { + controls.unshift("幻身·左"); + } + if (player.hasSkill(right)) { + controls.push("幻身·右"); } } - else{ - if(player.hasSkill(left)){ - controls.unshift('幻身·左'); - } - if(player.hasSkill(right)){ - controls.push('幻身·右'); - } - } - if(controls.length>1){ - player.chooseControl(controls,function(event,player){ - return Math.floor(Math.random()*_status.event.num); - }).set('prompt','选择一个形态直到下一回合开始').set('num',controls.length); - } - else{ + if (controls.length > 1) { + player + .chooseControl(controls, function (event, player) { + return Math.floor(Math.random() * _status.event.num); + }) + .set("prompt", "选择一个形态直到下一回合开始") + .set("num", controls.length); + } else { event.finish(); } - 'step 1' - switch(result.control){ - case '幻身·左':{ - if(!player.hasSkill('subplayer')){ + "step 1"; + switch (result.control) { + case "幻身·左": { + if (!player.hasSkill("subplayer")) { player.callSubPlayer(player.storage.nshuanxian_left); - } - else{ + } else { player.toggleSubPlayer(player.storage.nshuanxian_left); } break; } - case '幻身·右':{ - if(!player.hasSkill('subplayer')){ + case "幻身·右": { + if (!player.hasSkill("subplayer")) { player.callSubPlayer(player.storage.nshuanxian_right); } break; } - default:{ - if(player.hasSkill('subplayer')){ + default: { + if (player.hasSkill("subplayer")) { player.exitSubPlayer(); } break; } } - player.addTempSkill('nshuanxian_chosen','phaseBegin'); - } - } - } - }, - nsnongquan:{ - enable:'phaseUse', - // usable:4, - filter(event,player){ - return player.countCards('h')==1&&player.canUse('wuzhong',player); - }, - direct:true, - delay:0, - content(){ - player.useCard({name:'wuzhong'},player.getCards('h'),player,'nsnongquan'); - }, - ai:{ - order:10, - result:{ - player(player,target){ - return 10-get.value(player.getCards('h')[0]); - } - } - } - }, - nsdufu:{ - trigger:{source:'damageBefore'}, - check(event,player){ - return event.player.hasSkillTag('maixie'); - }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('nsdufu'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - if(_status.event.bool){ - return -get.attitude(_status.event.player,target); - } - return 0; - }).set('bool',trigger.player.hasSkillTag('maixie_defend')); - 'step 1' - if(result.bool){ - player.logSkill('nsdufu',result.targets); - trigger.source=result.targets[0]; - } - } - }, - yiesheng:{ - enable:'phaseUse', - filterCard:{color:'black'}, - filter(event,player){ - return player.countCards('h',{color:'black'})>0; - }, - selectCard:[1,Infinity], - prompt:'弃置任意张黑色手牌并摸等量的牌', - check(card){return 5-get.value(card)}, - content(){ - player.draw(cards.length); - }, - ai:{ - order:1, - result:{ - player:1 + player.addTempSkill("nshuanxian_chosen", "phaseBegin"); + }, }, }, }, - liangji:{ - audio:["liangji",2], - enable:"phaseUse", - usable:1, - filterTarget (card,player,target){ - return target!=player&&!target.hasSkill('liangji_1'); + nsnongquan: { + enable: "phaseUse", + // usable:4, + filter(event, player) { + return player.countCards("h") == 1 && player.canUse("wuzhong", player); }, - content (){ - 'step 0' - player.chooseCard('h','环计:将一张牌置于'+get.translation(target)+'的武将牌上',true).set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - return 7-get.value(card); - } - return -get.value(card); - }); - 'step 1' - if(result.bool){ - player.$give(result.cards,target); - player.lose(result.cards,ui.special); - target.storage.liangji_1=result.cards; - target.storage.liangji_1_source=target; - target.syncStorage('liangji_1'); - target.addSkill('liangji_1'); + direct: true, + delay: 0, + content() { + player.useCard({ name: "wuzhong" }, player.getCards("h"), player, "nsnongquan"); + }, + ai: { + order: 10, + result: { + player(player, target) { + return 10 - get.value(player.getCards("h")[0]); + }, + }, + }, + }, + nsdufu: { + trigger: { source: "damageBefore" }, + check(event, player) { + return event.player.hasSkillTag("maixie"); + }, + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("nsdufu"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + if (_status.event.bool) { + return -get.attitude(_status.event.player, target); + } + return 0; + }) + .set("bool", trigger.player.hasSkillTag("maixie_defend")); + "step 1"; + if (result.bool) { + player.logSkill("nsdufu", result.targets); + trigger.source = result.targets[0]; } }, - ai:{ - order:1, - result:{ - target (player,target){ - if(get.attitude(player,target)>0){ - return Math.sqrt(target.countCards('he')); + }, + yiesheng: { + enable: "phaseUse", + filterCard: { color: "black" }, + filter(event, player) { + return player.countCards("h", { color: "black" }) > 0; + }, + selectCard: [1, Infinity], + prompt: "弃置任意张黑色手牌并摸等量的牌", + check(card) { + return 5 - get.value(card); + }, + content() { + player.draw(cards.length); + }, + ai: { + order: 1, + result: { + player: 1, + }, + }, + }, + liangji: { + audio: ["liangji", 2], + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && !target.hasSkill("liangji_1"); + }, + content() { + "step 0"; + player + .chooseCard("h", "环计:将一张牌置于" + get.translation(target) + "的武将牌上", true) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) { + return 7 - get.value(card); + } + return -get.value(card); + }); + "step 1"; + if (result.bool) { + player.$give(result.cards, target); + player.lose(result.cards, ui.special); + target.storage.liangji_1 = result.cards; + target.storage.liangji_1_source = target; + target.syncStorage("liangji_1"); + target.addSkill("liangji_1"); + } + }, + ai: { + order: 1, + result: { + target(player, target) { + if (get.attitude(player, target) > 0) { + return Math.sqrt(target.countCards("he")); } return 0; }, - player:1, + player: 1, }, }, - subSkill:{ - "1":{ - trigger:{ - player:"phaseDrawBegin", + subSkill: { + 1: { + trigger: { + player: "phaseDrawBegin", }, - forced:true, - mark:true, - intro:{ - content:"cards", + forced: true, + mark: true, + intro: { + content: "cards", }, - content (){ - 'step 0' - var cards=player.storage.liangji_1; - if(cards){ - player.gain(cards,'gain2'); + content() { + "step 0"; + var cards = player.storage.liangji_1; + if (cards) { + player.gain(cards, "gain2"); } - player.storage.liangji_1=0; - 'step 1' - if(player.sex=='male')player.addTempSkill('wushuang'); - if(player.sex=='female')player.addTempSkill('lijian'); - player.removeSkill('liangji_1'); + player.storage.liangji_1 = 0; + "step 1"; + if (player.sex == "male") player.addTempSkill("wushuang"); + if (player.sex == "female") player.addTempSkill("lijian"); + player.removeSkill("liangji_1"); }, - sub:true, + sub: true, }, }, }, - jugong:{ - audio:["jingong",2], - trigger:{ - global:"damageEnd", + jugong: { + audio: ["jingong", 2], + trigger: { + global: "damageEnd", }, - usable:1, - frequent:true, - locked:false, - notemp:true, - marktext:"功", - init (player){ - player.storage.jugong=[]; + usable: 1, + frequent: true, + locked: false, + notemp: true, + marktext: "功", + init(player) { + player.storage.jugong = []; }, - filter (event,player){ - return event.card&&(event.card.name=='sha'||event.card.name=='juedou')&&event.notLink() - &&_status.currentPhase!=player; + filter(event, player) { + return ( + event.card && + (event.card.name == "sha" || event.card.name == "juedou") && + event.notLink() && + _status.currentPhase != player + ); }, - content (){ - "step 0" + content() { + "step 0"; player.draw(); - "step 1" - if(player.countCards('h')){ - player.chooseCard('将'+get.cnNumber(1)+'张手牌置于武将牌上作为“功”',1,true); - } - else{ + "step 1"; + if (player.countCards("h")) { + player.chooseCard("将" + get.cnNumber(1) + "张手牌置于武将牌上作为“功”", 1, true); + } else { event.finish(); } - "step 2" - if(result.cards&&result.cards.length){ - player.lose(result.cards,ui.special); - player.storage.jugong=player.storage.jugong.concat(result.cards); - player.syncStorage('jugong'); - player.markSkill('jugong'); - game.log(player,'将',result.cards,'置于武将牌上作为“功”'); + "step 2"; + if (result.cards && result.cards.length) { + player.lose(result.cards, ui.special); + player.storage.jugong = player.storage.jugong.concat(result.cards); + player.syncStorage("jugong"); + player.markSkill("jugong"); + game.log(player, "将", result.cards, "置于武将牌上作为“功”"); } }, - intro:{ - content:"cards", + intro: { + content: "cards", }, - group:"jugong_1", - subSkill:{ - "1":{ - trigger:{ - player:"damageBegin", + group: "jugong_1", + subSkill: { + 1: { + trigger: { + player: "damageBegin", }, - filter (event,player){ - return player.storage.jugong.length>1; + filter(event, player) { + return player.storage.jugong.length > 1; }, - content (){ - "step 0" - player.chooseCardButton('移去两张“功”',2,player.storage.jugong,true); - "step 1" - if(event.directresult||result.bool){ - player.logSkill('jugong'); - var links=event.directresult||result.links; - for(var i=0;i=4) return [0.5,get.tag(card,'damage')*2]; - if(!target.hasSkill('paiyi')&&target.hp>1) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==3) return [0.5,get.tag(card,'damage')*0.2]; - if(target.hp==2) return [0.1,get.tag(card,'damage')*0.1]; + ai: { + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0.5, get.tag(card, "damage") * 2]; + if (!target.hasSkill("paiyi") && target.hp > 1) + return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 3) return [0.5, get.tag(card, "damage") * 0.2]; + if (target.hp == 2) return [0.1, get.tag(card, "damage") * 0.1]; } }, }, }, }, - chengmou:{ - audio:["moucheng",2], - trigger:{ - player:"phaseDrawBegin", + chengmou: { + audio: ["moucheng", 2], + trigger: { + player: "phaseDrawBegin", }, - frequent:true, - filter (event,player){ - return player.storage.jugong.length>0; + frequent: true, + filter(event, player) { + return player.storage.jugong.length > 0; }, - content (){ - 'step 0' - if(player.storage.jugong.length>2) player.loseHp(); - 'step 1' - var cards=player.storage.jugong; - if(cards){ - player.gain(cards,'gain2'); + content() { + "step 0"; + if (player.storage.jugong.length > 2) player.loseHp(); + "step 1"; + var cards = player.storage.jugong; + if (cards) { + player.gain(cards, "gain2"); } - player.storage.jugong=[]; - 'step 2' + player.storage.jugong = []; + "step 2"; trigger.cancel(); }, }, - nsxinsheng:{ - trigger:{source:'damageEnd'}, - frequent:true, - filter(event,player){ + nsxinsheng: { + trigger: { source: "damageEnd" }, + frequent: true, + filter(event, player) { return player.isHealthy(); }, - content(){ - player.gainMaxHp(trigger.num,true); + content() { + player.gainMaxHp(trigger.num, true); player.draw(trigger.num); - } + }, }, - nsdunxing:{ - trigger:{player:'damageBefore'}, - filter(event,player){ + nsdunxing: { + trigger: { player: "damageBefore" }, + filter(event, player) { return player.isDamaged(); }, - content(){ + content() { trigger.cancel(); - player.loseMaxHp(trigger.num,true); + player.loseMaxHp(trigger.num, true); player.draw(trigger.num); - } + }, }, - liangce:{ - enable:'phaseUse', - viewAs:{name:'wugu'}, - usable:1, - filterCard:{type:'basic'}, - position:'hs', - filter(event,player){ - return player.countCards('hs',{type:'basic'})>0; + liangce: { + enable: "phaseUse", + viewAs: { name: "wugu" }, + usable: 1, + filterCard: { type: "basic" }, + position: "hs", + filter(event, player) { + return player.countCards("hs", { type: "basic" }) > 0; }, - check(card){ - return 6-get.value(card); + check(card) { + return 6 - get.value(card); }, - group:'liangce2' + group: "liangce2", }, - liangce2:{ - trigger:{global:'wuguRemained'}, - direct:true, - filter(event){ - return event.remained.filterInD().length>0; + liangce2: { + trigger: { global: "wuguRemained" }, + direct: true, + filter(event) { + return event.remained.filterInD().length > 0; }, - content(){ - 'step 0' - var du=0; - for(var i=0;i=trigger.remained.length/2) return -att; + var dialog = ui.create.dialog(get.prompt("liangce"), trigger.remained, "hidden"); + dialog.classList.add("noselect"); + player.chooseTarget(dialog).set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var att = get.attitude(player, target); + if (du >= trigger.remained.length / 2) return -att; return att; }); - 'step 1' - if(result.bool){ - player.logSkill('liangce',result.targets); - result.targets[0].gain(trigger.remained.slice(0),'gain2','log'); - trigger.remained.length=0; + "step 1"; + if (result.bool) { + player.logSkill("liangce", result.targets); + result.targets[0].gain(trigger.remained.slice(0), "gain2", "log"); + trigger.remained.length = 0; } - } + }, }, - jianbi:{ - trigger:{target:'useCardToTargeted'}, - priority:5, - filter(event,player){ - if(get.type(event.card)!='trick') return false; - if(get.info(event.card).multitarget) return false; - if(event.targets.length<2) return false; + jianbi: { + trigger: { target: "useCardToTargeted" }, + priority: 5, + filter(event, player) { + if (get.type(event.card) != "trick") return false; + if (get.info(event.card).multitarget) return false; + if (event.targets.length < 2) return false; return true; }, - direct:true, - content(){ - "step 0" - player.chooseTarget(get.prompt('jianbi'), - [1,1],function(card,player,target){ - return _status.event.getTrigger().targets.includes(target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var eff=-get.effect(target,trigger.card,trigger.player,_status.event.player); - if(trigger.card.name=='wugu'&&eff==0&&get.attitude(player,target)<0){ - return 0.01; - } - return eff; - }); - "step 1" - if(result.bool){ - event.targets=result.targets; - if(event.isMine()){ - player.logSkill('jianbi',event.targets); + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt("jianbi"), [1, 1], function (card, player, target) { + return _status.event.getTrigger().targets.includes(target); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var eff = -get.effect(target, trigger.card, trigger.player, _status.event.player); + if (trigger.card.name == "wugu" && eff == 0 && get.attitude(player, target) < 0) { + return 0.01; + } + return eff; + }); + "step 1"; + if (result.bool) { + event.targets = result.targets; + if (event.isMine()) { + player.logSkill("jianbi", event.targets); event.finish(); } - for(var i=0;iplayer.hasCard(card=>lib.skill.diyjuntun.filterCard(card,player),'he'), - position:'he', - filterCard:(card,player)=>get.type(card)=='equip'&&player.canRecast(card), - check(card){ - var player=_status.event.player; - var he=player.getCards('he'); - var subtype=get.subtype(card); - var value=get.equipValue(card); - for(var i=0;i=value){ + diyjuntun: { + enable: "phaseUse", + filter: (event, player) => + player.hasCard((card) => lib.skill.diyjuntun.filterCard(card, player), "he"), + position: "he", + filterCard: (card, player) => get.type(card) == "equip" && player.canRecast(card), + check(card) { + var player = _status.event.player; + var he = player.getCards("he"); + var subtype = get.subtype(card); + var value = get.equipValue(card); + for (var i = 0; i < he.length; i++) { + if ( + he[i] != card && + get.subtype(he[i]) == subtype && + get.equipValue(he[i]) >= value + ) { return 10; } } - if(!player.needsToDiscard()){ - return 4-get.equipValue(card); + if (!player.needsToDiscard()) { + return 4 - get.equipValue(card); } return 0; }, - content(){ + content() { player.recast(cards); }, - discard:false, - lose:false, - delay:false, - prompt:'将一张装备牌置入弃牌堆并摸一张牌', - ai:{ - basic:{ - order:8.5 + discard: false, + lose: false, + delay: false, + prompt: "将一张装备牌置入弃牌堆并摸一张牌", + ai: { + basic: { + order: 8.5, }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, - choudu:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filterTarget(card,player,target){ - return lib.filter.cardEnabled({name:'diaobingqianjiang'},target); + choudu: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filterTarget(card, player, target) { + return lib.filter.cardEnabled({ name: "diaobingqianjiang" }, target); }, - check(card){ - return 6-get.value(card); + check(card) { + return 6 - get.value(card); }, - content(){ - var list=game.filterPlayer(); + content() { + var list = game.filterPlayer(); list.sortBySeat(target); - target.useCard({name:'diaobingqianjiang'},list); + target.useCard({ name: "diaobingqianjiang" }, list); }, - ai:{ - order:1, - result:{ - player(player,target){ - if(get.attitude(player,target)<=1) return 0; - return game.countPlayer(function(current){ - return get.effect(current,{name:'diaobingqianjiang'},target,player); + ai: { + order: 1, + result: { + player(player, target) { + if (get.attitude(player, target) <= 1) return 0; + return game.countPlayer(function (current) { + return get.effect(current, { name: "diaobingqianjiang" }, target, player); }); - } - } - } + }, + }, + }, }, - liduan:{ - trigger:{global:'gainAfter'}, - filter(event,player){ - if(event.player==player) return false; - if(_status.currentPhase==event.player) return false; - if(event.cards.length!=1) return false; - return get.type(event.cards[0])=='equip'&&get.position(event.cards[0])=='h'&&event.player.hasUseTarget(event.cards[0]); + liduan: { + trigger: { global: "gainAfter" }, + filter(event, player) { + if (event.player == player) return false; + if (_status.currentPhase == event.player) return false; + if (event.cards.length != 1) return false; + return ( + get.type(event.cards[0]) == "equip" && + get.position(event.cards[0]) == "h" && + event.player.hasUseTarget(event.cards[0]) + ); }, - logTarget:'player', - check(event,player){ - var att=get.attitude(player,event.player); - var subtype=get.subtype(event.cards[0]); - if(att>0){ - if(event.player.countCards('h')>=player.countCards('h')+2) return true; - return event.player.countCards('e',{subtype:subtype})==0; - } - else{ - return event.player.countCards('e',{subtype:subtype})>0; + logTarget: "player", + check(event, player) { + var att = get.attitude(player, event.player); + var subtype = get.subtype(event.cards[0]); + if (att > 0) { + if (event.player.countCards("h") >= player.countCards("h") + 2) return true; + return ( + event.player.countCards("e", { + subtype: subtype, + }) == 0 + ); + } else { + return event.player.countCards("e", { subtype: subtype }) > 0; } }, - content(){ - 'step 0' - var bool=false; - var subtype=get.subtype(trigger.cards[0]); - var current=trigger.player.getEquip('e',parseInt(subtype[5])); - var att=get.attitude(trigger.player,player); - if(current){ - if(att>0){ - bool=true; - } - else{ - if(get.equipValue(current)>get.equipValue(trigger.cards[0])){ - bool=true; + content() { + "step 0"; + var bool = false; + var subtype = get.subtype(trigger.cards[0]); + var current = trigger.player.getEquip("e", parseInt(subtype[5])); + var att = get.attitude(trigger.player, player); + if (current) { + if (att > 0) { + bool = true; + } else { + if (get.equipValue(current) > get.equipValue(trigger.cards[0])) { + bool = true; } } } - trigger.player.chooseCard('立断').set('prompt2','将一张手牌交给'+get.translation(player)+',或取消并使用'+get.translation(trigger.cards)).ai=function(card){ - if(bool){ - if(att>0){ - return 8-get.value(card); + trigger.player + .chooseCard("立断") + .set( + "prompt2", + "将一张手牌交给" + + get.translation(player) + + ",或取消并使用" + + get.translation(trigger.cards) + ).ai = function (card) { + if (bool) { + if (att > 0) { + return 8 - get.value(card); + } else { + return 4 - get.value(card); } - else{ - return 4-get.value(card); - } - } - else{ - if(att<=0) return -get.value(card); + } else { + if (att <= 0) return -get.value(card); return 0; } + }; + "step 1"; + if (result.bool) { + player.gain(result.cards, trigger.player); + trigger.player.$give(1, player); + } else { + trigger.player.chooseUseTarget(trigger.cards[0], true); } - 'step 1' - if(result.bool){ - player.gain(result.cards,trigger.player); - trigger.player.$give(1,player); - } - else{ - trigger.player.chooseUseTarget(trigger.cards[0],true); - } - } + }, }, - jinyan:{ - mod:{ - cardEnabled(card,player){ - if(_status.event.skill!='jinyan'&&player.hp<=2&&get.type(card,'trick')=='trick'&&get.color(card)=='black') return false; + jinyan: { + mod: { + cardEnabled(card, player) { + if ( + _status.event.skill != "jinyan" && + player.hp <= 2 && + get.type(card, "trick") == "trick" && + get.color(card) == "black" + ) + return false; }, - cardUsable(card,player){ - if(_status.event.skill!='jinyan'&&player.hp<=2&&get.type(card,'trick')=='trick'&&get.color(card)=='black') return false; + cardUsable(card, player) { + if ( + _status.event.skill != "jinyan" && + player.hp <= 2 && + get.type(card, "trick") == "trick" && + get.color(card) == "black" + ) + return false; }, - cardRespondable(card,player){ - if(_status.event.skill!='jinyan'&&player.hp<=2&&get.type(card,'trick')=='trick'&&get.color(card)=='black') return false; + cardRespondable(card, player) { + if ( + _status.event.skill != "jinyan" && + player.hp <= 2 && + get.type(card, "trick") == "trick" && + get.color(card) == "black" + ) + return false; }, - cardSavable(card,player){ - if(_status.event.skill!='jinyan'&&player.hp<=2&&get.type(card,'trick')=='trick'&&get.color(card)=='black') return false; + cardSavable(card, player) { + if ( + _status.event.skill != "jinyan" && + player.hp <= 2 && + get.type(card, "trick") == "trick" && + get.color(card) == "black" + ) + return false; }, }, - enable:['chooseToUse','chooseToRespond'], - filterCard(card){ - return get.type(card,'trick')=='trick'&&get.color(card)=='black'; + enable: ["chooseToUse", "chooseToRespond"], + filterCard(card) { + return get.type(card, "trick") == "trick" && get.color(card) == "black"; }, - viewAsFilter(player){ - if(player.hp>2) return false; - if(!player.hasCard(function(card){ - return get.type(card,'trick')=='trick'&&get.color(card)=='black'; - })) return false; + viewAsFilter(player) { + if (player.hp > 2) return false; + if ( + !player.hasCard(function (card) { + return get.type(card, "trick") == "trick" && get.color(card) == "black"; + }) + ) + return false; + }, + viewAs: { name: "sha" }, + prompt: "将一张黑色锦囊牌当作杀使用或打出", + check() { + return 1; + }, + ai: { + respondSha: true, + skillTagFilter(player) { + if (player.hp > 2) return false; + if ( + !player.hasCard(function (card) { + return get.type(card, "trick") == "trick" && get.color(card) == "black"; + }) + ) + return false; + }, }, - viewAs:{name:'sha'}, - prompt:'将一张黑色锦囊牌当作杀使用或打出', - check(){return 1}, - ai:{ - respondSha:true, - skillTagFilter(player){ - if(player.hp>2) return false; - if(!player.hasCard(function(card){ - return get.type(card,'trick')=='trick'&&get.color(card)=='black'; - })) return false; - } - } }, - fuchou:{ - trigger:{target:'shaBefore'}, - filter(event,player){ - return player.countCards('he')>0; + fuchou: { + trigger: { target: "shaBefore" }, + filter(event, player) { + return player.countCards("he") > 0; }, - direct:true, - content(){ - 'step 0' - var bool=false; - if(!player.hasShan()&&get.effect(player,trigger.card,trigger.player,player)<0){ - bool=true; + direct: true, + content() { + "step 0"; + var bool = false; + if (!player.hasShan() && get.effect(player, trigger.card, trigger.player, player) < 0) { + bool = true; } - player.chooseCard('he',get.prompt('fuchou',trigger.player)).set('ai',function(card){ - var player=_status.event.player; - if(bool){ - if(player.hp<=1){ - if(get.tag(card,'save')) return 0; - return 8-get.value(card); + player.chooseCard("he", get.prompt("fuchou", trigger.player)).set("ai", function (card) { + var player = _status.event.player; + if (bool) { + if (player.hp <= 1) { + if (get.tag(card, "save")) return 0; + return 8 - get.value(card); } - return 6-get.value(card); + return 6 - get.value(card); } return -get.value(card); }); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.cancel(); - player.logSkill('fuchou',trigger.player); - trigger.player.gain(result.cards,player); - if(get.position(result.cards[0])=='h'){ - player.$give(1,trigger.player); - } - else{ - player.$give(result.cards,trigger.player); + player.logSkill("fuchou", trigger.player); + trigger.player.gain(result.cards, player); + if (get.position(result.cards[0]) == "h") { + player.$give(1, trigger.player); + } else { + player.$give(result.cards, trigger.player); } player.storage.fuchou2.add(trigger.player); } }, - group:'fuchou2' + group: "fuchou2", }, - fuchou2:{ - init(player){ - player.storage.fuchou2=[]; + fuchou2: { + init(player) { + player.storage.fuchou2 = []; }, - forced:true, - trigger:{global:'phaseAfter'}, - filter(event,player){ - for(var i=0;i0); - var next=player.chooseToDiscard('he',{type:'equip'},get.prompt('youzhan',trigger.target)); - next.ai=function(card){ - if(bool){ - return 7-get.value(card); + }, + chezhen: { + mod: { + globalFrom(from, to, distance) { + if (from.countCards("e")) return distance - 1; + }, + globalTo(from, to, distance) { + if (!to.countCards("e")) return distance + 1; + }, + }, + }, + youzhan: { + trigger: { global: "shaBefore" }, + direct: true, + filter(event, player) { + return ( + get.distance(player, event.target) <= 1 && player.countCards("he", { type: "equip" }) + ); + }, + content() { + "step 0"; + var bool = + get.attitude(player, trigger.player) < 0 && get.attitude(player, trigger.target) > 0; + var next = player.chooseToDiscard( + "he", + { type: "equip" }, + get.prompt("youzhan", trigger.target) + ); + next.ai = function (card) { + if (bool) { + return 7 - get.value(card); } return 0; }; - next.logSkill=['youzhan',trigger.target]; - 'step 1' - if(result.bool){ - event.youdiinfo={ - source:trigger.player, - evt:trigger - } - trigger.target.useCard({name:'youdishenru'}); + next.logSkill = ["youzhan", trigger.target]; + "step 1"; + if (result.bool) { + event.youdiinfo = { + source: trigger.player, + evt: trigger, + }; + trigger.target.useCard({ name: "youdishenru" }); } - } - }, - kangyin:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('he')>0; }, - content(){ - 'step 0' + }, + kangyin: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("he") > 0; + }, + content() { + "step 0"; player.loseHp(); - 'step 1' - player.discardPlayerCard(target,true); - 'step 2' - if(player.isDamaged()&&result.links&&result.links.length){ - if(get.type(result.links[0])=='basic'){ - player.chooseTarget([1,player.maxHp-player.hp], - '选择至多'+get.cnNumber(player.maxHp-player.hp)+'名角色各摸一张牌').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - } - else{ - player.storage.kangyin2=player.maxHp-player.hp; - player.addTempSkill('kangyin2'); + "step 1"; + player.discardPlayerCard(target, true); + "step 2"; + if (player.isDamaged() && result.links && result.links.length) { + if (get.type(result.links[0]) == "basic") { + player + .chooseTarget( + [1, player.maxHp - player.hp], + "选择至多" + get.cnNumber(player.maxHp - player.hp) + "名角色各摸一张牌" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + } else { + player.storage.kangyin2 = player.maxHp - player.hp; + player.addTempSkill("kangyin2"); event.finish(); } - } - else{ + } else { event.finish(); } - 'step 3' - if(result.targets&&result.targets.length){ + "step 3"; + if (result.targets && result.targets.length) { result.targets.sort(lib.sort.seat); - player.line(result.targets,'green'); + player.line(result.targets, "green"); game.asyncDraw(result.targets); } }, - ai:{ - order:7, - result:{ - target(player,target){ - if(player.hp>=4) return -1; - if(player.hp==3&&!player.needsToDiscard()) return -1; + ai: { + order: 7, + result: { + target(player, target) { + if (player.hp >= 4) return -1; + if (player.hp == 3 && !player.needsToDiscard()) return -1; return 0; - } - } - } - }, - kangyin2:{ - mark:true, - intro:{ - content:'到其他角色的距离-#;使用【杀】的额外目标数上限+#' + }, + }, }, - onremove:true, - mod:{ - globalFrom(from,to,distance){ - return distance-from.storage.kangyin2; - }, - selectTarget(card,player,range){ - if(card.name=='sha'&&range[1]!=-1) range[1]+=player.storage.kangyin2; - }, - } }, - duoqi:{ - trigger:{global:'discardAfter'}, - filter(event,player){ - if(_status.currentPhase==player) return false; - if(!player.storage.zhucheng||!player.storage.zhucheng.length) return false; - var evt=event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse') return true; + kangyin2: { + mark: true, + intro: { + content: "到其他角色的距离-#;使用【杀】的额外目标数上限+#", + }, + onremove: true, + mod: { + globalFrom(from, to, distance) { + return distance - from.storage.kangyin2; + }, + selectTarget(card, player, range) { + if (card.name == "sha" && range[1] != -1) range[1] += player.storage.kangyin2; + }, + }, + }, + duoqi: { + trigger: { global: "discardAfter" }, + filter(event, player) { + if (_status.currentPhase == player) return false; + if (!player.storage.zhucheng || !player.storage.zhucheng.length) return false; + var evt = event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") return true; return false; }, - direct:true, - content(){ - 'step 0' - var bool=false; - if(get.attitude(player,trigger.player)<0&&trigger.player.needsToDiscard()){ - bool=true; + direct: true, + content() { + "step 0"; + var bool = false; + if (get.attitude(player, trigger.player) < 0 && trigger.player.needsToDiscard()) { + bool = true; } - player.chooseCardButton(get.prompt('zhucheng',_status.currentPhase),player.storage.zhucheng).set('ai',function(button){ - return _status.event.bool?1:0; - }).set('bool',bool); - 'step 1' - if(result.bool){ - player.logSkill('zhucheng',_status.currentPhase); + player + .chooseCardButton( + get.prompt("zhucheng", _status.currentPhase), + player.storage.zhucheng + ) + .set("ai", function (button) { + return _status.event.bool ? 1 : 0; + }) + .set("bool", bool); + "step 1"; + if (result.bool) { + player.logSkill("zhucheng", _status.currentPhase); player.$throw(result.links[0]); player.storage.zhucheng.remove(result.links[0]); result.links[0].discard(); - player.syncStorage('zhucheng'); - if(player.storage.zhucheng.length==0){ - player.unmarkSkill('zhucheng'); - } - else{ + player.syncStorage("zhucheng"); + if (player.storage.zhucheng.length == 0) { + player.unmarkSkill("zhucheng"); + } else { player.updateMarks(); } - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + var evt = trigger.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } } }, - ai:{ - expose:0.2 - } - }, - zhucheng:{ - trigger:{player:'phaseEnd'}, - filter(event,player){ - return !player.storage.zhucheng||!player.storage.zhucheng.length; + ai: { + expose: 0.2, }, - check(event,player){ - if(player.storage.zhucheng&&player.storage.zhucheng.length){ - if(!player.hasShan()) return false; - if(player.storage.zhucheng.length>=2) return false; + }, + zhucheng: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return !player.storage.zhucheng || !player.storage.zhucheng.length; + }, + check(event, player) { + if (player.storage.zhucheng && player.storage.zhucheng.length) { + if (!player.hasShan()) return false; + if (player.storage.zhucheng.length >= 2) return false; } return true; }, - intro:{ - content:'cards' + intro: { + content: "cards", }, - content(){ - if(player.storage.zhucheng&&player.storage.zhucheng.length){ - player.gain(player.storage.zhucheng,'gain2'); + content() { + if (player.storage.zhucheng && player.storage.zhucheng.length) { + player.gain(player.storage.zhucheng, "gain2"); delete player.storage.zhucheng; - player.unmarkSkill('zhucheng'); - } - else{ - var cards=get.cards(Math.max(1,player.maxHp-player.hp)); + player.unmarkSkill("zhucheng"); + } else { + var cards = get.cards(Math.max(1, player.maxHp - player.hp)); player.$gain2(cards); - player.storage.zhucheng=cards; - player.markSkill('zhucheng'); + player.storage.zhucheng = cards; + player.markSkill("zhucheng"); } }, - ai:{ - target(card,player,target,current){ - if(card.name=='sha'&&player.storage.zhucheng&&player.storage.zhucheng.length){ - if(player.storage.zhucheng.length>=2){ - if(!player.hasFriend()&&player.countCards('he')-2= 2) { + if ( + !player.hasFriend() && + player.countCards("he") - 2 < player.storage.zhucheng.length + ) + return "zeroplayertarget"; return 0.1; - } - else{ - var he=player.getCards('he'); - var sha=false; - for(var i=0;i0; + filter(event, player) { + return player.storage.zhucheng && player.storage.zhucheng.length > 0; }, - content(){ - 'step 0' - var bool=false; - if(get.effect(player,trigger.card,trigger.player,trigger.player)>=0){ - bool=true; + content() { + "step 0"; + var bool = false; + if (get.effect(player, trigger.card, trigger.player, trigger.player) >= 0) { + bool = true; } - var num=player.storage.zhucheng.length; - trigger.player.chooseToDiscard('弃置'+get.cnNumber(num)+'张牌,或令杀无效','he',num).set('ai',function(card){ - if(_status.event.bool){ - return 10-get.value(card); - } - return 0; - }).set('bool',bool); - 'step 1' - if(!result.bool){ + var num = player.storage.zhucheng.length; + trigger.player + .chooseToDiscard("弃置" + get.cnNumber(num) + "张牌,或令杀无效", "he", num) + .set("ai", function (card) { + if (_status.event.bool) { + return 10 - get.value(card); + } + return 0; + }) + .set("bool", bool); + "step 1"; + if (!result.bool) { trigger.cancel(); } - } - }, - diy_jiaoxia:{ - //audio:['jiaoxia',2], - trigger:{target:'useCardToBegin'}, - filter(event,player){ - return event.card&&get.color(event.card)=='red'; }, - frequent:true, - content(){ + }, + diy_jiaoxia: { + //audio:['jiaoxia',2], + trigger: { target: "useCardToBegin" }, + filter(event, player) { + return event.card && get.color(event.card) == "red"; + }, + frequent: true, + content() { player.draw(); }, - ai:{ - effect(card,player,target){ - if(get.color(card)=='red') return [1,1]; + ai: { + effect(card, player, target) { + if (get.color(card) == "red") return [1, 1]; }, - } - }, - zaiqix:{ - trigger:{player:'phaseDrawBefore'}, - filter(event,player){ - return player.hp=2; + } else if (1 + player.maxHp - player.hp == 2) { + return player.countCards("h") >= 2; } return true; }, - content(){ - "step 0" + content() { + "step 0"; trigger.cancel(); - event.cards=get.cards(player.maxHp-player.hp+1); + event.cards = get.cards(player.maxHp - player.hp + 1); player.showCards(event.cards); - "step 1" - var num=0; - for(var i=0;i=player.maxHp-1) return [0,0]; - } - } - } + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, + }, + }, }, - diykuanggu:{ - trigger:{source:'damageEnd'}, - forced:true, - content(){ - if(get.distance(trigger.player,player,'attack')>1){ + diykuanggu: { + trigger: { source: "damageEnd" }, + forced: true, + content() { + if (get.distance(trigger.player, player, "attack") > 1) { player.draw(trigger.num); - } - else{ + } else { player.recover(trigger.num); } - } + }, }, - diyduanliang:{ - group:['diyduanliang1','diyduanliang2'], - ai:{ - threaten:1.2 - } + diyduanliang: { + group: ["diyduanliang1", "diyduanliang2"], + ai: { + threaten: 1.2, + }, }, - diyduanliang1:{ - enable:'phaseUse', - usable:1, - discard:false, - filter(event,player){ - var cards=player.getCards('he',{color:'black'}); - for(var i=0;i0) return false; + ai: { + skillTagFilter(player) { + if (player.storage.guihan) return false; + if (player.hp > 0) return false; }, - save:true, - result:{ - player:4, - target(player,target){ - if(target.hp==target.maxHp) return 2; + save: true, + result: { + player: 4, + target(player, target) { + if (target.hp == target.maxHp) return 2; return 4; - } + }, + }, + threaten(player, target) { + if (!target.storage.guihan) return 0.8; }, - threaten(player,target){ - if(!target.storage.guihan) return 0.8; - } - } - }, - luweiyan:{ - enable:'phaseUse', - usable:1, - filterCard(card){ - return get.type(card)!='basic'; }, - position:'hse', - filter(event,player){ - return player.hasCard(function(card){ - return get.type(card)!='basic'; - },'hes'); - }, - viewAs:{name:'shuiyanqijun'}, - prompt:'将一张非基本牌当水淹七军使用', - check(card){return 8-get.value(card)}, - group:'luweiyan2' }, - luweiyan2:{ - trigger:{player:'useCardAfter'}, - direct:true, - filter(event,player){ - if(event.skill!='luweiyan') return false; - for(var i=0;i0; + }, + yaliang: { + inherit: "wangxi", + }, + xiongzi: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + content() { + trigger.num += 1 + Math.floor(player.countCards("e") / 2); }, - content(){ - trigger.source.discard(trigger.source.getCards('he',{color:'red'})); + }, + honglian: { + trigger: { player: "damageEnd" }, + check(event, player) { + return get.attitude(player, event.player) < 0; }, - ai:{ - expose:0.1, - result:{ - threaten:0.8, - target(card,player,target){ - if(get.tag(card,'damage')&&get.attitude(target,player)<0){ - return [1,0,0,-player.countCards('he',{color:'red'})]; + filter(event, player) { + return ( + event.source && + event.source != player && + event.source.countCards("he", { color: "red" }) > 0 + ); + }, + content() { + trigger.source.discard(trigger.source.getCards("he", { color: "red" })); + }, + ai: { + expose: 0.1, + result: { + threaten: 0.8, + target(card, player, target) { + if (get.tag(card, "damage") && get.attitude(target, player) < 0) { + return [1, 0, 0, -player.countCards("he", { color: "red" })]; } - } - } - } - }, - diyguhuo:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return player.countCards('hej')>0; + }, + }, }, - content(){ - "step 0" + }, + diyguhuo: { + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return player.countCards("hej") > 0; + }, + content() { + "step 0"; player.draw(2); - "step 1" - var next=player.discardPlayerCard(player,'hej',2,true); - next.ai=function(button){ - if(get.position(button.link)=='j') return 10; + "step 1"; + var next = player.discardPlayerCard(player, "hej", 2, true); + next.ai = function (button) { + if (get.position(button.link) == "j") return 10; return -get.value(button.link); }; - next.filterButton=function(button){ - return lib.filter.cardDiscardable(button.link,player); - } + next.filterButton = function (button) { + return lib.filter.cardDiscardable(button.link, player); + }; + }, + ai: { + effect: { + target(card) { + if (get.type(card) == "delay") return [0, 0.5]; + }, + }, }, - ai:{ - effect:{ - target(card){ - if(get.type(card)=='delay') return [0,0.5]; - } - } - } }, - diychanyuan:{ - trigger:{player:'dieBegin'}, - forced:true, - filter(event){ - return event.source!=undefined; + diychanyuan: { + trigger: { player: "dieBegin" }, + forced: true, + filter(event) { + return event.source != undefined; }, - content(){ + content() { trigger.source.loseMaxHp(true); }, - ai:{ - threaten(player,target){ - if(target.hp==1) return 0.2; + ai: { + threaten(player, target) { + if (target.hp == 1) return 0.2; }, - result:{ - target(card,player,target,current){ - if(target.hp<=1&&get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-5]; - return [1,0,0,-2]; + result: { + target(card, player, target, current) { + if (target.hp <= 1 && get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -5]; + return [1, 0, 0, -2]; } - } - } - } - }, - zonghuo:{ - trigger:{source:'damageBefore'}, - direct:true, - priority:10, - filter(event){ - return event.nature!='fire'; + }, + }, }, - content(){ - "step 0" - player.chooseToDiscard(get.prompt('zonghuo')).ai=function(card){ - var att=get.attitude(player,trigger.player); - if(trigger.player.hasSkillTag('nofire')){ - if(att>0) return 8-get.value(card); + }, + zonghuo: { + trigger: { source: "damageBefore" }, + direct: true, + priority: 10, + filter(event) { + return event.nature != "fire"; + }, + content() { + "step 0"; + player.chooseToDiscard(get.prompt("zonghuo")).ai = function (card) { + var att = get.attitude(player, trigger.player); + if (trigger.player.hasSkillTag("nofire")) { + if (att > 0) return 8 - get.value(card); return -1; } - if(att<0){ - return 7-get.value(card); + if (att < 0) { + return 7 - get.value(card); } return -1; + }; + "step 1"; + if (result.bool) { + player.logSkill("zonghuo", trigger.player, "fire"); + trigger.nature = "fire"; } - "step 1" - if(result.bool){ - player.logSkill('zonghuo',trigger.player,'fire'); - trigger.nature='fire'; - } - } - }, - shaoying:{ - trigger:{source:'damageAfter'}, - direct:true, - filter(event){ - return event.nature=='fire'; }, - content(){ - "step 0" - player.chooseTarget(get.prompt('shaoying'),function(card,player,target){ - return get.distance(trigger.player,target)<=1&&trigger.player!=target; - }).ai=function(target){ - return get.damageEffect(target,player,player,'fire'); - } - "step 1" - if(result.bool){ - var card=get.cards()[0]; + }, + shaoying: { + trigger: { source: "damageAfter" }, + direct: true, + filter(event) { + return event.nature == "fire"; + }, + content() { + "step 0"; + player.chooseTarget(get.prompt("shaoying"), function (card, player, target) { + return get.distance(trigger.player, target) <= 1 && trigger.player != target; + }).ai = function (target) { + return get.damageEffect(target, player, player, "fire"); + }; + "step 1"; + if (result.bool) { + var card = get.cards()[0]; card.discard(); player.showCards(card); - event.bool=get.color(card)=='red'; - event.target=result.targets[0]; - player.logSkill('shaoying',event.target,false); - trigger.player.line(event.target,'fire'); - } - else{ + event.bool = get.color(card) == "red"; + event.target = result.targets[0]; + player.logSkill("shaoying", event.target, false); + trigger.player.line(event.target, "fire"); + } else { event.finish(); } - "step 2" - if(event.bool){ - event.target.damage('fire'); + "step 2"; + if (event.bool) { + event.target.damage("fire"); } - } - }, - tiangong:{ - group:['tiangong2'], - trigger:{player:'damageBefore'}, - filter(event){ - if(event.nature=='thunder') return true; }, - forced:true, - content(){ + }, + tiangong: { + group: ["tiangong2"], + trigger: { player: "damageBefore" }, + filter(event) { + if (event.nature == "thunder") return true; + }, + forced: true, + content() { trigger.cancel(); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(card.name=='tiesuo') return 0; - if(get.tag(card,'thunderDamage')) return 0; - } + ai: { + effect: { + target(card, player, target, current) { + if (card.name == "tiesuo") return 0; + if (get.tag(card, "thunderDamage")) return 0; + }, }, - threaten:0.5 - } - }, - tiangong2:{ - trigger:{source:'damageAfter'}, - filter(event){ - if(event.nature=='thunder') return true; + threaten: 0.5, }, - forced:true, - popup:false, - priority:1, - content(){ + }, + tiangong2: { + trigger: { source: "damageAfter" }, + filter(event) { + if (event.nature == "thunder") return true; + }, + forced: true, + popup: false, + priority: 1, + content() { player.draw(); }, }, - xicai:{ - inherit:'jianxiong' + xicai: { + inherit: "jianxiong", }, - diyjianxiong:{ - mode:['identity'], - trigger:{global:'dieBefore'}, - forced:true, - filter(event,player){ - return event.player!=game.zhu&&_status.currentPhase==player; + diyjianxiong: { + mode: ["identity"], + trigger: { global: "dieBefore" }, + forced: true, + filter(event, player) { + return event.player != game.zhu && _status.currentPhase == player; + }, + content() { + trigger.player.identity = "fan"; + trigger.player.setIdentity("fan"); + trigger.player.identityShown = true; }, - content(){ - trigger.player.identity='fan'; - trigger.player.setIdentity('fan'); - trigger.player.identityShown=true; - } }, - nsshuaiyan:{ - trigger:{global:'recoverAfter'}, - filter(event,player){ - return event.player!=player&&_status.currentPhase!=player; + nsshuaiyan: { + trigger: { global: "recoverAfter" }, + filter(event, player) { + return event.player != player && _status.currentPhase != player; }, - logTarget:'player', - content(){ - "step 0" - var att=get.attitude(trigger.player,player); - var bool=0; - if(att<0){ - if(trigger.player.countCards('e')==0&&trigger.player.countCards('h')>2) bool=1; - else if(trigger.player.countCards('he')==0) bool=1; + logTarget: "player", + content() { + "step 0"; + var att = get.attitude(trigger.player, player); + var bool = 0; + if (att < 0) { + if (trigger.player.countCards("e") == 0 && trigger.player.countCards("h") > 2) + bool = 1; + else if (trigger.player.countCards("he") == 0) bool = 1; + } else if (att == 0 && trigger.player.countCards("he") == 0) { + bool = 1; } - else if(att==0&&trigger.player.countCards('he')==0){ - bool=1; - } - trigger.player.chooseControl(function(){ - return _status.event.bool; - }).set('prompt','率言').set('bool',bool).set('choiceList',['令'+get.translation(player)+'摸一张牌','令'+get.translation(player)+'弃置你一张牌']); - "step 1" - if(result.control=='选项一'){ + trigger.player + .chooseControl(function () { + return _status.event.bool; + }) + .set("prompt", "率言") + .set("bool", bool) + .set("choiceList", [ + "令" + get.translation(player) + "摸一张牌", + "令" + get.translation(player) + "弃置你一张牌", + ]); + "step 1"; + if (result.control == "选项一") { player.draw(); event.finish(); - } - else if(trigger.player.countCards('he')){ - player.discardPlayerCard(trigger.player,true,'he'); - } - else{ + } else if (trigger.player.countCards("he")) { + player.discardPlayerCard(trigger.player, true, "he"); + } else { event.finish(); } }, - ai:{ - threaten:1.2 - } - }, - moshou:{ - mod:{ - targetEnabled(card,player,target,now){ - if(card.name=='bingliang'||card.name=='lebu') return false; - } + ai: { + threaten: 1.2, }, }, - siji:{ - trigger:{player:'phaseDiscardEnd'}, - frequent:true, - filter(event,player){ - if(event.cards){ - for(var i=0;i=trigger.player.hp){ - trigger.player.addTempSkill('ciqiu_dying'); - player.removeSkill('ciqiu') + if (trigger.num >= trigger.player.hp) { + trigger.player.addTempSkill("ciqiu_dying"); + player.removeSkill("ciqiu"); } }, - ai:{ - effect:{ - player(card,player,target){ - if(card.name=='sha'&&target.isHealthy()&&get.attitude(player,target)>0){ - return [1,-2]; + ai: { + effect: { + player(card, player, target) { + if ( + card.name == "sha" && + target.isHealthy() && + get.attitude(player, target) > 0 + ) { + return [1, -2]; } }, }, }, }, - ciqiu_dying:{ - trigger:{player:"dyingBegin"}, - forced:true, - silent:true, - firstDo:true, - content(){ + ciqiu_dying: { + trigger: { player: "dyingBegin" }, + forced: true, + silent: true, + firstDo: true, + content() { player.die(); }, - popup:false, + popup: false, }, - juedao:{ - enable:'phaseUse', - filter(event,player){ - return player.isLinked()==false; + juedao: { + enable: "phaseUse", + filter(event, player) { + return player.isLinked() == false; }, - filterCard:true, - check(card){ - return 6-get.value(card); + filterCard: true, + check(card) { + return 6 - get.value(card); }, - content(){ - if(player.isLinked()==false) player.link(); + content() { + if (player.isLinked() == false) player.link(); }, - ai:{ - link:true, - order:2, - result:{ - player(player){ - if(player.isLinked()) return 0; + ai: { + link: true, + order: 2, + result: { + player(player) { + if (player.isLinked()) return 0; return 1; }, }, - effect:{ - target(card,player,target){ - if(card.name=='tiesuo'){ - if(target.isLinked()){ - return [0,-0.5]; - } - else{ - return [0,0.5]; + effect: { + target(card, player, target) { + if (card.name == "tiesuo") { + if (target.isLinked()) { + return [0, -0.5]; + } else { + return [0, 0.5]; } } - } - } + }, + }, }, - mod:{ - globalFrom(from,to,distance){ - if(from.isLinked()) return distance+1; + mod: { + globalFrom(from, to, distance) { + if (from.isLinked()) return distance + 1; }, - globalTo(from,to,distance){ - if(to.isLinked()) return distance+1; + globalTo(from, to, distance) { + if (to.isLinked()) return distance + 1; }, - } + }, }, - geju:{ - trigger:{player:'phaseBegin'}, - frequent:true, - filter(event,player){ - var list=[]; - var players=game.filterPlayer(); - for(var i=0;i0; + return list.length > 0; }, - content(){ - var list=[]; - var players=game.filterPlayer(); - for(var i=0;i0) player.draw(list.length); - } + if (list.length > 0) player.draw(list.length); + }, }, - diyqiangxi:{ - enable:'phaseUse', - usable:1, - filterCard(card){ - return get.subtype(card)=='equip1'; + diyqiangxi: { + enable: "phaseUse", + usable: 1, + filterCard(card) { + return get.subtype(card) == "equip1"; }, - selectCard:[0,1], - filterTarget(card,player,target){ - if(player==target) return false; - return get.distance(player,target,'attack')<=1; + selectCard: [0, 1], + filterTarget(card, player, target) { + if (player == target) return false; + return get.distance(player, target, "attack") <= 1; }, - content(){ - "step 0" - if(cards.length==0){ + content() { + "step 0"; + if (cards.length == 0) { player.loseHp(); } - "step 1" + "step 1"; target.damage(); - "step 2" - if(target.isAlive()&&target.countCards('he')){ + "step 2"; + if (target.isAlive() && target.countCards("he")) { player.discardPlayerCard(target); } }, - check(card){ - return 10-get.value(card); + check(card) { + return 10 - get.value(card); }, - position:'he', - ai:{ - order:8, - result:{ - player(player,target){ - if(ui.selected.cards.length) return 0; - if(player.hp>=target.hp) return -0.9; - if(player.hp<=2) return -10; + position: "he", + ai: { + order: 8, + result: { + player(player, target) { + if (ui.selected.cards.length) return 0; + if (player.hp >= target.hp) return -0.9; + if (player.hp <= 2) return -10; return -2; }, - target(player,target){ - if(player.hp<=1) return 0; - return get.damageEffect(target,player); - } - } + target(player, target) { + if (player.hp <= 1) return 0; + return get.damageEffect(target, player); + }, + }, }, - threaten:1.3 + threaten: 1.3, }, - nsdingzhou:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('hej')>0; + nsdingzhou: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("hej") > 0; }, - content(){ - 'step 0' - var cards=target.getCards('hej'); - if(get.isLuckyStar(player)){ - var cardx=ui.cardPile.firstChild; - if(cardx){ - var color=get.color(card),cardsx=cards.filter(function(i){ - return get.color(i)==color; - }); - if(cardsx.length>0) cards=cardsx; + content() { + "step 0"; + var cards = target.getCards("hej"); + if (get.isLuckyStar(player)) { + var cardx = ui.cardPile.firstChild; + if (cardx) { + var color = get.color(card), + cardsx = cards.filter(function (i) { + return get.color(i) == color; + }); + if (cardsx.length > 0) cards = cardsx; } } - var card=cards.randomGet(); - event.card=card; - player.gain(card,target,'giveAuto','bySelf'); + var card = cards.randomGet(); + event.card = card; + player.gain(card, target, "giveAuto", "bySelf"); player.draw(); - 'step 1' - if(Array.isArray(result)&&get.color(card)!=get.color(result[0])) player.loseHp(); + "step 1"; + if (Array.isArray(result) && get.color(card) != get.color(result[0])) player.loseHp(); }, - ai:{ - order:7, - result:{target:-1}, + ai: { + order: 7, + result: { target: -1 }, }, }, //比原版更令人难以吐槽的神孙权 - junkyuheng:{ - audio:'yuheng', - trigger:{player:'phaseBegin'}, - forced:true, - keepSkill:true, - filter(event,player){ - return player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'junkyuheng'); - },'he'); + junkyuheng: { + audio: "yuheng", + trigger: { player: "phaseBegin" }, + forced: true, + keepSkill: true, + filter(event, player) { + return player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "junkyuheng"); + }, "he"); }, - content(){ - 'step 0' - player.chooseToDiscard('he',true,[1,4],function(card,player){ - if(!ui.selected.cards.length) return true; - var suit=get.suit(card,player); - for(var i of ui.selected.cards){ - if(get.suit(i,player)==suit) return false; - } - return true; - }).set('complexCard',true).set('ai',function(card){ - if(!player.hasValueTarget(card)) return 5; - return 5-get.value(card); - }); - 'step 1' - if(result.bool){ - var skills=lib.skill.junkyuheng.derivation.randomGets(result.cards.length); - player.addAdditionalSkills('junkyuheng',skills); + content() { + "step 0"; + player + .chooseToDiscard("he", true, [1, 4], function (card, player) { + if (!ui.selected.cards.length) return true; + var suit = get.suit(card, player); + for (var i of ui.selected.cards) { + if (get.suit(i, player) == suit) return false; + } + return true; + }) + .set("complexCard", true) + .set("ai", function (card) { + if (!player.hasValueTarget(card)) return 5; + return 5 - get.value(card); + }); + "step 1"; + if (result.bool) { + var skills = lib.skill.junkyuheng.derivation.randomGets(result.cards.length); + player.addAdditionalSkills("junkyuheng", skills); } }, - group:'junkyuheng_remove', - derivation:['olbingyi','shenxing','xiashu','old_anxu','rezhiheng','xinanguo','lanjiang','xinfu_guanwei','dimeng','xindiaodu','xingxue','jiexun','olhongyuan','xinfu_youdi','bizheng'], - subSkill:{ - remove:{ - audio:'yuheng', - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.additionalSkills.junkyuheng&&player.additionalSkills.junkyuheng.length>0; + group: "junkyuheng_remove", + derivation: [ + "olbingyi", + "shenxing", + "xiashu", + "old_anxu", + "rezhiheng", + "xinanguo", + "lanjiang", + "xinfu_guanwei", + "dimeng", + "xindiaodu", + "xingxue", + "jiexun", + "olhongyuan", + "xinfu_youdi", + "bizheng", + ], + subSkill: { + remove: { + audio: "yuheng", + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return ( + player.additionalSkills.junkyuheng && + player.additionalSkills.junkyuheng.length > 0 + ); }, - async content(event,trigger,player){ + async content(event, trigger, player) { const skillslength = player.additionalSkills.junkyuheng.length; - await player.removeAdditionalSkills('junkyuheng'); + await player.removeAdditionalSkills("junkyuheng"); await player.draw(skillslength); }, }, }, }, - junkdili:{ - audio:'dili', - trigger:{player:'changeSkillsAfter'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'wood', - filter(event,player){ - if(!event.addSkill.length) return false; - var skills=player.getSkills(null,false,false).filter(function(i){ - var info=get.info(i); - return info&&!info.charlotte; + junkdili: { + audio: "dili", + trigger: { player: "changeSkillsAfter" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "wood", + filter(event, player) { + if (!event.addSkill.length) return false; + var skills = player.getSkills(null, false, false).filter(function (i) { + var info = get.info(i); + return info && !info.charlotte; }); - return skills.length>player.maxHp; + return skills.length > player.maxHp; }, - content(){ - 'step 0' - player.awakenSkill('junkdili'); + content() { + "step 0"; + player.awakenSkill("junkdili"); player.loseMaxHp(); - 'step 1' - var skills=player.getSkills(null,false,false).filter(function(i){ - if(i=='junkdili') return false; - var info=get.info(i); - return info&&!info.charlotte; + "step 1"; + var skills = player.getSkills(null, false, false).filter(function (i) { + if (i == "junkdili") return false; + var info = get.info(i); + return info && !info.charlotte; }); - var list=[]; - for(var skill of skills){ + var list = []; + for (var skill of skills) { list.push([ skill, - '', - ]) + '", + ]); } - var next=player.chooseButton([ - '请选择失去任意个技能', - [list,'textbutton'], - ]); - next.set('forced',true); - next.set('selectButton',[1,skills.length]); - next.set('ai',function(button){ - var skill=button.link,skills=_status.event.skills.slice(0); - skills.removeArray(['xinanguo','lanjiang','rezhiheng','junkyuheng']); - switch(ui.selected.buttons.length){ + var next = player.chooseButton(["请选择失去任意个技能", [list, "textbutton"]]); + next.set("forced", true); + next.set("selectButton", [1, skills.length]); + next.set("ai", function (button) { + var skill = button.link, + skills = _status.event.skills.slice(0); + skills.removeArray(["xinanguo", "lanjiang", "rezhiheng", "junkyuheng"]); + switch (ui.selected.buttons.length) { case 0: - if(skills.includes(skill)) return 2; - if(skill=='junkyuheng') return 1; + if (skills.includes(skill)) return 2; + if (skill == "junkyuheng") return 1; return Math.random(); case 1: - if(skills.length<2) return 0; - if(skills.includes(skill)) return 2; - if(skill=='junkyuheng') return 1; - return 0 - case 2: - if(skills.includes(skill)) return 2; - if(skill=='junkyuheng') return 1; + if (skills.length < 2) return 0; + if (skills.includes(skill)) return 2; + if (skill == "junkyuheng") return 1; + return 0; + case 2: + if (skills.includes(skill)) return 2; + if (skill == "junkyuheng") return 1; + return 0; + default: return 0; - default: return 0; } }); - next.set('skills',skills) - 'step 2' - if(result.bool){ - var skills=result.links; + next.set("skills", skills); + "step 2"; + if (result.bool) { + var skills = result.links; player.removeSkills(skills.slice(0)); } - var list=lib.skill.junkdili.derivation; - list=list.slice(0,Math.min(skills.length,list.length)); + var list = lib.skill.junkdili.derivation; + list = list.slice(0, Math.min(skills.length, list.length)); player.addSkills(list); }, - derivation:['junkshengzhi','junkquandao','junkchigang'], + derivation: ["junkshengzhi", "junkquandao", "junkchigang"], }, - junkshengzhi:{ - audio:'dili_shengzhi', - trigger:{player:['logSkill','useSkillAfter']}, - forced:true, - filter(event,player){ - if(event.type!='player') return false; - var skill=event.sourceSkill||event.skill; - if(get.is.locked(skill)) return false; - var info=get.info(skill); + junkshengzhi: { + audio: "dili_shengzhi", + trigger: { player: ["logSkill", "useSkillAfter"] }, + forced: true, + filter(event, player) { + if (event.type != "player") return false; + var skill = event.sourceSkill || event.skill; + if (get.is.locked(skill)) return false; + var info = get.info(skill); return !info.charlotte; }, - content(){ - player.addTempSkill('junkshengzhi_effect'); + content() { + player.addTempSkill("junkshengzhi_effect"); }, - subSkill:{ - effect:{ - mod:{ - cardUsable:()=>Infinity, - targetInRange:()=>true, + subSkill: { + effect: { + mod: { + cardUsable: () => Infinity, + targetInRange: () => true, }, - trigger:{player:'useCard1'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - content(){ - if(trigger.addCount!==false){ - trigger.addCount=false; + trigger: { player: "useCard1" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + content() { + if (trigger.addCount !== false) { + trigger.addCount = false; player.getStat().card[trigger.card.name]--; } - player.removeSkill('junkshengzhi_effect'); + player.removeSkill("junkshengzhi_effect"); }, - mark:true, - intro:{content:'使用下一张牌无距离和次数限制'}, + mark: true, + intro: { content: "使用下一张牌无距离和次数限制" }, }, }, }, - junkquandao:{ - audio:'dili_quandao', - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return event.card.name=='sha' || get.type(event.card,null,false)=='trick'; + junkquandao: { + audio: "dili_quandao", + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return event.card.name == "sha" || get.type(event.card, null, false) == "trick"; }, - async content(event, trigger, player){ - const cards1 = player.getCards('h', card => get.name(card) === 'sha'), cards2 = player.getCards('h', card => get.type(card) === 'trick'); - if (cards1.length !== cards2.length){ - const num = cards1.length - cards2.length, cards = num > 0 ? cards1 : cards2; + async content(event, trigger, player) { + const cards1 = player.getCards("h", (card) => get.name(card) === "sha"), + cards2 = player.getCards("h", (card) => get.type(card) === "trick"); + if (cards1.length !== cards2.length) { + const num = cards1.length - cards2.length, + cards = num > 0 ? cards1 : cards2; let i = 0; - cards.forEach(card => { - if (i < Math.abs(num) && lib.filter.cardDiscardable(card, player, 'junkquandao')) i++; + cards.forEach((card) => { + if (i < Math.abs(num) && lib.filter.cardDiscardable(card, player, "junkquandao")) + i++; }); if (i > 0) { - await player.chooseToDiscard(i, true, - `权道:请弃置${ get.cnNumber(i) }张${ num > 0 ? '杀' : '普通锦囊牌' }`, - num > 0 ? (card => get.name(card) === 'sha') : (card => get.type(card) === 'trick')) + await player.chooseToDiscard( + i, + true, + `权道:请弃置${get.cnNumber(i)}张${num > 0 ? "杀" : "普通锦囊牌"}`, + num > 0 + ? (card) => get.name(card) === "sha" + : (card) => get.type(card) === "trick" + ); } } await player.draw(); }, }, - junkchigang:{ - audio:'dili_chigang', - trigger:{player:'phaseJudgeBefore'}, - forced:true, - zhuanhuanji:true, - mark:true, - marktext:'☯', - content(){ - player.changeZhuanhuanji('junkchigang'); + junkchigang: { + audio: "dili_chigang", + trigger: { player: "phaseJudgeBefore" }, + forced: true, + zhuanhuanji: true, + mark: true, + marktext: "☯", + content() { + player.changeZhuanhuanji("junkchigang"); trigger.cancel(); - var next=player[player.storage.junkchigang?'phaseDraw':'phaseUse'](); + var next = player[player.storage.junkchigang ? "phaseDraw" : "phaseUse"](); event.next.remove(next); trigger.getParent().next.push(next); }, - ai:{ - effect:{ - target(card,player,target){ - if(get.type(card)=='delay') return 'zerotarget'; + ai: { + effect: { + target(card, player, target) { + if (get.type(card) == "delay") return "zerotarget"; }, }, }, - intro:{ - content(storage){ - return '转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的'+(storage?'出牌阶段':'摸牌阶段')+'。' + intro: { + content(storage) { + return ( + "转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的" + + (storage ? "出牌阶段" : "摸牌阶段") + + "。" + ); }, }, }, - nsmanzhi:{ - audio:'dcmanzhi', - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - direct:true, - filter(event,player){ - var nums=[]; - game.countPlayer(current=>{ + nsmanzhi: { + audio: "dcmanzhi", + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + direct: true, + filter(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')); + 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; + 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(){ - 'step 0' - var nums=[]; - game.countPlayer(current=>{ + content() { + "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.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; + 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; + if (goon) break; } - player.chooseButton(2,[ - '蛮智:请选择让下列等式成立的A与B的值', - '
              目标等式
              ', - `0.5 × A2 + 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)); + player + .chooseButton(2, [ + "蛮智:请选择让下列等式成立的A与B的值", + '
              目标等式
              ', + `0.5 × A2 + 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)); } - 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+2.5×${b}-${game.roundNumber}=${game.countPlayer()}`; - player.logSkill('nsmanzhi'); + equals = `0.5×${a}2+2.5×${b}-${game.roundNumber}=${game.countPlayer()}`; + player.logSkill("nsmanzhi"); player.chat(equals); - game.log(player,'的计算结果为',equals); + game.log(player, "的计算结果为", equals); player.draw(game.countPlayer()); } }, }, }, - dynamicTranslate:{ - nsjiquan(player){ - if(player.storage.nsfuwei) return '锁定技,与你距离1以内的其他角色造成或受到伤害后,你将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。'; - return '与你距离1以内的其他角色造成或受到伤害后,你可以将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。'; + dynamicTranslate: { + nsjiquan(player) { + if (player.storage.nsfuwei) + return "锁定技,与你距离1以内的其他角色造成或受到伤害后,你将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。"; + return "与你距离1以内的其他角色造成或受到伤害后,你可以将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。"; }, - abyusa_jueqing(player){ - if(player.storage.abyusa_jueqing_rewrite) return '锁定技,你即将造成的伤害均视为失去体力。'; - return '当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。'; + abyusa_jueqing(player) { + if (player.storage.abyusa_jueqing_rewrite) return "锁定技,你即将造成的伤害均视为失去体力。"; + return "当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。"; }, - tomoya_shangxian(player){ - if(player.storage.tomoya_shangxian) return '锁定技,你计算与其他角色的距离时始终从顺时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。'; - return '锁定技,你计算与其他角色的距离时始终从逆时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。'; + tomoya_shangxian(player) { + if (player.storage.tomoya_shangxian) + return "锁定技,你计算与其他角色的距离时始终从顺时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。"; + return "锁定技,你计算与其他角色的距离时始终从逆时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。"; }, - yui_lieyin(player){ - if(player.storage._ichiban_no_takaramono) return '锁定技,出牌阶段开始时,你可选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。'; - return '锁定技,出牌阶段开始时,你选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。'; + yui_lieyin(player) { + if (player.storage._ichiban_no_takaramono) + return "锁定技,出牌阶段开始时,你可选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。"; + return "锁定技,出牌阶段开始时,你选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。"; }, - yuzuru_kunfen(player){ - if(player.storage._yuzuru_sss) return '锁定技,结束阶段,你摸两张牌。然后你可以将两张牌交给一名其他角色。'; - return '锁定技,结束阶段,你失去1点体力并摸两张牌。然后你可以将两张牌交给一名其他角色。'; + yuzuru_kunfen(player) { + if (player.storage._yuzuru_sss) + return "锁定技,结束阶段,你摸两张牌。然后你可以将两张牌交给一名其他角色。"; + return "锁定技,结束阶段,你失去1点体力并摸两张牌。然后你可以将两张牌交给一名其他角色。"; }, - yuzuru_quji(player){ - if(player.storage._yuzuru_sss) return '出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。(X为你已损失的体力值)'; - return '出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。若你以此法弃置了黑色牌,则你失去1点体力。(X为你已损失的体力值)'; + yuzuru_quji(player) { + if (player.storage._yuzuru_sss) + return "出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。(X为你已损失的体力值)"; + return "出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。若你以此法弃置了黑色牌,则你失去1点体力。(X为你已损失的体力值)"; }, - kamome_jieban(player){ - if(player.storage.kamome_jieban) return '转换技。每回合限一次,当你受到或造成伤害后,阴:你可将两张牌交给一名其他角色,然后其交给你一张牌。阳:你可将一张牌交给一名其他角色,然后其交给你两张牌。'; + kamome_jieban(player) { + if (player.storage.kamome_jieban) + return '转换技。每回合限一次,当你受到或造成伤害后,阴:你可将两张牌交给一名其他角色,然后其交给你一张牌。阳:你可将一张牌交给一名其他角色,然后其交给你两张牌。'; return '转换技。每回合限一次,当你受到或造成伤害后,阴:你可将两张牌交给一名其他角色,然后其交给你一张牌。阳:你可将一张牌交给一名其他角色,然后其交给你两张牌。'; }, - shiroha_guying(player){ - var str='当你受到伤害/对其他角色造成伤害时,你'; - if(!player.storage.shiroha_jiezhao) str='锁定技,每回合限一次,'+str; - if(player.storage.shiroha_jiezhao) str+='可'; - str+='进行判定。若结果为红色/黑色,此伤害-1/+1。'; + shiroha_guying(player) { + var str = "当你受到伤害/对其他角色造成伤害时,你"; + if (!player.storage.shiroha_jiezhao) str = "锁定技,每回合限一次," + str; + if (player.storage.shiroha_jiezhao) str += "可"; + str += "进行判定。若结果为红色/黑色,此伤害-1/+1。"; return str; }, - nsdiewu(player){ - if(player.storage.nspojian) return '当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】。当你以此法使用【杀】造成伤害后,则你摸一张牌。'; - return '当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】或【闪】。当你以此法使用【杀】造成伤害后,则你摸一张牌。'; + nsdiewu(player) { + if (player.storage.nspojian) + return "当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】。当你以此法使用【杀】造成伤害后,则你摸一张牌。"; + return "当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】或【闪】。当你以此法使用【杀】造成伤害后,则你摸一张牌。"; }, - nsfuzhou(player){ - var str='出牌阶段限'; - str+=(player.storage.nstaiping?'两':'一'); - str+='次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到'; - str+=(player.storage.nsfuzhou_damage?'两':'一'); - str+='点雷属性伤害并弃置一张牌;红色,你摸两张牌,'; - str+=(player.storage.nsfuzhou_draw?'该角色回复1点体力并摸一张牌,且本回合的手牌上限+1。':'且该角色本回合手牌上限减1。'); + nsfuzhou(player) { + var str = "出牌阶段限"; + str += player.storage.nstaiping ? "两" : "一"; + str += + "次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到"; + str += player.storage.nsfuzhou_damage ? "两" : "一"; + str += "点雷属性伤害并弃置一张牌;红色,你摸两张牌,"; + str += player.storage.nsfuzhou_draw + ? "该角色回复1点体力并摸一张牌,且本回合的手牌上限+1。" + : "且该角色本回合手牌上限减1。"; return str; }, - nsguidao(player){ - if(player.storage.nstaiping) return '一名角色的判定牌生效前,你可以打出一张牌替换之。'; - return '一名角色的判定牌生效前,你可以打出一张黑色牌替换之。'; + nsguidao(player) { + if (player.storage.nstaiping) return "一名角色的判定牌生效前,你可以打出一张牌替换之。"; + return "一名角色的判定牌生效前,你可以打出一张黑色牌替换之。"; }, - junkchigang(player){ - if(player.storage.junkchigang) return '转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的:阴,摸牌阶段;阳,出牌阶段。'; + junkchigang(player) { + if (player.storage.junkchigang) + return '转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的:阴,摸牌阶段;阳,出牌阶段。'; return '转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的:阴,摸牌阶段;阳,出牌阶段。'; }, }, - characterReplace:{ - key_yuri:['key_yuri','sp_key_yuri'], - kanade:['sp_key_kanade','kanade'], + characterReplace: { + key_yuri: ["key_yuri", "sp_key_yuri"], + kanade: ["sp_key_kanade", "kanade"], }, - translate:{ - diy_liufu:'刘馥', - diy_xizhenxihong:'习珍习宏', - diy_liuzan:'留赞', - diy_zaozhirenjun:'枣祗任峻', - diy_yangyi:'杨仪', - diy_tianyu:'田豫', + translate: { + diy_liufu: "刘馥", + diy_xizhenxihong: "习珍习宏", + diy_liuzan: "留赞", + diy_zaozhirenjun: "枣祗任峻", + diy_yangyi: "杨仪", + diy_tianyu: "田豫", // diy_caocao:'曹操', - diy_menghuo:'孟获', - diy_huangzhong:'黄汉升', - diy_xuhuang:'徐公明', - diy_dianwei:'新典韦', - diy_weiyan:'魏文长', - xicai:'惜才', - diyjianxiong:'奸雄', - diy_feishi:'费诗', - nsshuaiyan:'率言', - moshou:'墨守', - diy_hanlong:'韩龙', - diy_luxun:'陆伯言', - diy_yuji:'于吉', - diy_zhouyu:'周公瑾', - diy_lukang:'陆抗', - diy_caiwenji:'蔡昭姬', - diy_zhenji:'甄宓', + diy_menghuo: "孟获", + diy_huangzhong: "黄汉升", + diy_xuhuang: "徐公明", + diy_dianwei: "新典韦", + diy_weiyan: "魏文长", + xicai: "惜才", + diyjianxiong: "奸雄", + diy_feishi: "费诗", + nsshuaiyan: "率言", + moshou: "墨守", + diy_hanlong: "韩龙", + diy_luxun: "陆伯言", + diy_yuji: "于吉", + diy_zhouyu: "周公瑾", + diy_lukang: "陆抗", + diy_caiwenji: "蔡昭姬", + diy_zhenji: "甄宓", - ns_zuoci:'左慈', - ns_wangyun:'王允', - ns_lvzhi:'吕后', - ns_nanhua:'南华', - ns_nanhua_left:'幻身·左', - ns_nanhua_right:'幻身·右', - ns_huamulan:'SP花木兰', - ns_huamulan_prefix:'SP', - ns_huangzu:'黄祖', - ns_yanliang:'颜良', - ns_wenchou:'文丑', - ns_jinke:'荆轲', + ns_zuoci: "左慈", + ns_wangyun: "王允", + ns_lvzhi: "吕后", + ns_nanhua: "南华", + ns_nanhua_left: "幻身·左", + ns_nanhua_right: "幻身·右", + ns_huamulan: "SP花木兰", + ns_huamulan_prefix: "SP", + ns_huangzu: "黄祖", + ns_yanliang: "颜良", + ns_wenchou: "文丑", + ns_jinke: "荆轲", - ns_caocao:'曹操', - ns_zhugeliang:'诸葛亮', - ns_wangyue:'王越', - ns_yuji:'于吉', - ns_caocaosp:'SP曹操', - ns_caocaosp_prefix:'SP', - ns_xinxianying:'辛宪英', - ns_sunjian:'孙坚', - ns_simazhao:'司马昭', - ns_guanlu:'管辂', + ns_caocao: "曹操", + ns_zhugeliang: "诸葛亮", + ns_wangyue: "王越", + ns_yuji: "于吉", + ns_caocaosp: "SP曹操", + ns_caocaosp_prefix: "SP", + ns_xinxianying: "辛宪英", + ns_sunjian: "孙坚", + ns_simazhao: "司马昭", + ns_guanlu: "管辂", - ns_duangui:'段珪', - ns_shenpei:'审配', - ns_zhangbao:'张宝', - ns_masu:'马谡', - ns_zhangxiu:'张绣', - ns_lvmeng:'吕蒙', + ns_duangui: "段珪", + ns_shenpei: "审配", + ns_zhangbao: "张宝", + ns_masu: "马谡", + ns_zhangxiu: "张绣", + ns_lvmeng: "吕蒙", - ns_yujisp:'于吉', - ns_lisu:'李肃', - ns_yangyi:'杨仪', - ns_liuzhang:'刘璋', - ns_xinnanhua:'南华老仙', - ns_luyusheng:'陆郁生', + ns_yujisp: "于吉", + ns_lisu: "李肃", + ns_yangyi: "杨仪", + ns_liuzhang: "刘璋", + ns_xinnanhua: "南华老仙", + ns_luyusheng: "陆郁生", - sp_key_yuri:'SP仲村由理', - sp_key_yuri_prefix:'SP', - key_lucia:'此花露西娅', - key_kyousuke:'枣恭介', - key_yuri:'仲村由理', - key_haruko:'神尾晴子', - key_umi:'加藤うみ', - key_umi2:'鹰原羽未', - key_rei:'零', - key_komari:'神北小毬', - key_yukine:'宫泽有纪宁', - key_yusa:'西森柚咲', - key_misa:'黑羽美砂', - key_masato:'井之原真人', - key_iwasawa:'岩泽雅美', - key_kengo:'宫泽谦吾', - key_yoshino:'吉野晴彦', - key_yui:'由依', - key_tsumugi:'紬文德斯', - key_saya:'朱鹭户沙耶', - key_harukakanata:'三枝叶留佳&二木佳奈多', - key_harukakanata_ab:'三枝二木', - key_inari:'稻荷', - key_shiina:'椎名', - key_sunohara:'春原阳平&春原芽衣', - key_sunohara_ab:'阳平芽衣', + sp_key_yuri: "SP仲村由理", + sp_key_yuri_prefix: "SP", + key_lucia: "此花露西娅", + key_kyousuke: "枣恭介", + key_yuri: "仲村由理", + key_haruko: "神尾晴子", + key_umi: "加藤うみ", + key_umi2: "鹰原羽未", + key_rei: "零", + key_komari: "神北小毬", + key_yukine: "宫泽有纪宁", + key_yusa: "西森柚咲", + key_misa: "黑羽美砂", + key_masato: "井之原真人", + key_iwasawa: "岩泽雅美", + key_kengo: "宫泽谦吾", + key_yoshino: "吉野晴彦", + key_yui: "由依", + key_tsumugi: "紬文德斯", + key_saya: "朱鹭户沙耶", + key_harukakanata: "三枝叶留佳&二木佳奈多", + key_harukakanata_ab: "三枝二木", + key_inari: "稻荷", + key_shiina: "椎名", + key_sunohara: "春原阳平&春原芽衣", + key_sunohara_ab: "阳平芽衣", //该武将国战模式下不可用 - key_rin:'枣铃', - key_sasami:'笹濑川佐佐美', - key_akane:'千里朱音', - key_doruji:'多鲁基', - key_yuiko:'来谷唯湖', - key_riki:'直枝理树'/*+'子'*/, - key_hisako:'渕田久子', - key_hinata:'日向秀树', - key_noda:'野田', - key_tomoya:'冈崎朋也', - key_nagisa:'古河渚', - key_ayato:'直井文人', - key_ao:'空门苍', - key_yuzuru:'音无结弦', - sp_key_kanade:'SP立华奏', - sp_key_kanade_prefix:'SP', - key_mio:'西园美鱼', - key_midori:'西园美鸟', - key_kyoko:'岬镜子', - key_shizuru:'中津静流', - key_shiorimiyuki:'关根诗织&入江美雪', - key_shiorimiyuki_ab:'关根入江', - key_miki:'野村美希', - key_shiori:'美坂栞', - key_kaori:'美坂香里', - key_akiko:'水濑秋子', - key_abyusa:'游佐', - key_godan:'松下护騨', - key_yuu:'乙坂有宇', - key_ryoichi:'三谷良一', - key_kotori:'神户小鸟', - key_jojiro:'高城丈士朗', - key_shiroha:'鸣濑白羽', - key_shizuku:'水织静久', - key_hiroto:'铃木央人', - key_sakuya:'凤咲夜', - key_youta:'成神阳太', - key_rumi:'七濑留美', - key_chihaya:'凤千早', - key_yukito:'国崎往人', - key_crow:'小空', - key_asara:'井上晶', - key_kotomi:'一之濑琴美', - key_mia:'藤川米娅', - key_kano:'雾岛佳乃', - db_key_liyingxia:'李映夏', - key_erika:'苍井绘梨花', - key_satomi:'藏里见', - key_iriya:'喵呜·喵呼', - key_iriya_ab:'喵呜喵呼', - key_fuuko:'伊吹风子', - lucia_duqu:'毒躯', - lucia_duqu_info:'锁定技,①当你对其他角色造成伤害或受到其他角色的伤害时,你令对方获得一张花色点数随机的【毒】。
              ②当你因【毒】失去体力时,你改为回复等量的体力。', - lucia_zhenren:'振刃', - lucia_zhenren_info:'锁定技,每个结束阶段,若你的装备区内有牌,则你弃置之。然后,你依次弃置场上的X张牌。(X为你以此法弃置的牌数)', - nk_shekong:'设控', - nk_shekong_info:'出牌阶段限一次,你可以弃置任意张手牌并选择一名其他角色(不能超过该角色的牌数),然后令其选择一项:弃置一张牌并令你摸X张牌,或弃置X张牌并令你摸一张牌。然后,你将你与其弃置的且位于弃牌堆中的牌以任意顺序置于牌堆顶。', - key_huanjie:'幻界', - key_huanjie_info:'锁定技,当你进行判定或摸牌时,你改为从牌堆的另一端获取相应的牌。', - yuri_xingdong:'行动', - yuri_xingdong_info:'锁定技,出牌阶段开始时,你获得一张【杀】或普通锦囊牌。出牌阶段限一次,你可以将一张【杀】或普通锦囊牌交给一名其他角色,然后该角色选择一项:对除你以外的角色使用此牌并在此牌结算完成后和你各摸一张牌;或跳过下回合的判定阶段和摸牌阶段。', + key_rin: "枣铃", + key_sasami: "笹濑川佐佐美", + key_akane: "千里朱音", + key_doruji: "多鲁基", + key_yuiko: "来谷唯湖", + key_riki: "直枝理树" /*+'子'*/, + key_hisako: "渕田久子", + key_hinata: "日向秀树", + key_noda: "野田", + key_tomoya: "冈崎朋也", + key_nagisa: "古河渚", + key_ayato: "直井文人", + key_ao: "空门苍", + key_yuzuru: "音无结弦", + sp_key_kanade: "SP立华奏", + sp_key_kanade_prefix: "SP", + key_mio: "西园美鱼", + key_midori: "西园美鸟", + key_kyoko: "岬镜子", + key_shizuru: "中津静流", + key_shiorimiyuki: "关根诗织&入江美雪", + key_shiorimiyuki_ab: "关根入江", + key_miki: "野村美希", + key_shiori: "美坂栞", + key_kaori: "美坂香里", + key_akiko: "水濑秋子", + key_abyusa: "游佐", + key_godan: "松下护騨", + key_yuu: "乙坂有宇", + key_ryoichi: "三谷良一", + key_kotori: "神户小鸟", + key_jojiro: "高城丈士朗", + key_shiroha: "鸣濑白羽", + key_shizuku: "水织静久", + key_hiroto: "铃木央人", + key_sakuya: "凤咲夜", + key_youta: "成神阳太", + key_rumi: "七濑留美", + key_chihaya: "凤千早", + key_yukito: "国崎往人", + key_crow: "小空", + key_asara: "井上晶", + key_kotomi: "一之濑琴美", + key_mia: "藤川米娅", + key_kano: "雾岛佳乃", + db_key_liyingxia: "李映夏", + key_erika: "苍井绘梨花", + key_satomi: "藏里见", + key_iriya: "喵呜·喵呼", + key_iriya_ab: "喵呜喵呼", + key_fuuko: "伊吹风子", + lucia_duqu: "毒躯", + lucia_duqu_info: + "锁定技,①当你对其他角色造成伤害或受到其他角色的伤害时,你令对方获得一张花色点数随机的【毒】。
              ②当你因【毒】失去体力时,你改为回复等量的体力。", + lucia_zhenren: "振刃", + lucia_zhenren_info: + "锁定技,每个结束阶段,若你的装备区内有牌,则你弃置之。然后,你依次弃置场上的X张牌。(X为你以此法弃置的牌数)", + nk_shekong: "设控", + nk_shekong_info: + "出牌阶段限一次,你可以弃置任意张手牌并选择一名其他角色(不能超过该角色的牌数),然后令其选择一项:弃置一张牌并令你摸X张牌,或弃置X张牌并令你摸一张牌。然后,你将你与其弃置的且位于弃牌堆中的牌以任意顺序置于牌堆顶。", + key_huanjie: "幻界", + key_huanjie_info: "锁定技,当你进行判定或摸牌时,你改为从牌堆的另一端获取相应的牌。", + yuri_xingdong: "行动", + yuri_xingdong_info: + "锁定技,出牌阶段开始时,你获得一张【杀】或普通锦囊牌。出牌阶段限一次,你可以将一张【杀】或普通锦囊牌交给一名其他角色,然后该角色选择一项:对除你以外的角色使用此牌并在此牌结算完成后和你各摸一张牌;或跳过下回合的判定阶段和摸牌阶段。", //目标角色跳过阶段的同时 该回合不能发动〖整经(郑玄)〗 - yuri_wangxi:'忘隙', - yuri_wangxi_info:'主公技,限定技,当有角色因你发动的【行动】而死亡后,若其身份不为【明忠】,则其可以将身份改为忠臣并重新加入游戏,然后将势力改为与你相同,将体力值回复至2点并摸一张牌。', - haruko_haofang:'豪放', - haruko_haofang_info:'锁定技,你的延时锦囊牌视为【无中生有】。当你因执行【无中生有】的效果而摸牌时,你令摸牌数+2。', - haruko_zhuishi:'追逝', - haruko_zhuishi_info:'一名角色的判定阶段开始时,若其判定区内有牌,则你可以获得其判定区内的所有牌。若你的体力值大于1,你失去1点体力。', - umi_chaofan:'炒饭', - umi_chaofan_info:'出牌阶段限一次,你可以弃置两张花色不同的手牌并选择一名其他角色。你摸一张牌,若你的体力值:大于2,目标角色回复1点体力;等于2,目标角色摸两张牌;小于2,目标角色受到1点无来源且对应渠道为这两张牌的火焰伤害。', - umi_lunhui:'轮回', - umi_lunhui_info:'一名其他角色的回合结束时,若你的手牌数小于体力值,则你可以失去1点体力。若如此做,你摸两张牌并进行一个额外回合,且你于此回合内计算与此角色的距离视为1。', - umi_shiroha:'轮回 - 延时效果', - umi_qihuan:'七幻', - umi_qihuan_info:'限定技,当你处于濒死状态时,你可以移去此武将牌。若如此做,你回复X点体力(X为场上势力数)。然后,你可获得场上已死亡角色武将牌上的至多两个技能。', - komari_tiankou:'甜口', - komari_tiankou_info:'锁定技,当你使用红色的非伤害性基本牌/锦囊牌选择目标时,或成为其他角色使用的这些牌的目标时,你选择一项:1.摸一张牌;2.为此牌增加一个目标。', - komari_xueshang:'血殇', - komari_xueshang_info:'锁定技,蓄能技,当有角色死亡时,你对自己造成1点伤害,然后对所有其他角色依次造成1点伤害。当有角色因此法进入濒死状态时,你加1点体力上限并回复1点体力,然后失去此技能并终止此技能的所有后续结算。', - yukine_wenzhou:'问咒', - yukine_wenzhou_info:'一名角色的出牌阶段开始时,其可以交给你一张牌。若如此做,你选择一项:交给其一张牌,或令其从牌堆中获得一张与此牌类型相同的牌,且其于此阶段内使用与此牌牌名相同的牌时无法被响应。', + yuri_wangxi: "忘隙", + yuri_wangxi_info: + "主公技,限定技,当有角色因你发动的【行动】而死亡后,若其身份不为【明忠】,则其可以将身份改为忠臣并重新加入游戏,然后将势力改为与你相同,将体力值回复至2点并摸一张牌。", + haruko_haofang: "豪放", + haruko_haofang_info: + "锁定技,你的延时锦囊牌视为【无中生有】。当你因执行【无中生有】的效果而摸牌时,你令摸牌数+2。", + haruko_zhuishi: "追逝", + haruko_zhuishi_info: + "一名角色的判定阶段开始时,若其判定区内有牌,则你可以获得其判定区内的所有牌。若你的体力值大于1,你失去1点体力。", + umi_chaofan: "炒饭", + umi_chaofan_info: + "出牌阶段限一次,你可以弃置两张花色不同的手牌并选择一名其他角色。你摸一张牌,若你的体力值:大于2,目标角色回复1点体力;等于2,目标角色摸两张牌;小于2,目标角色受到1点无来源且对应渠道为这两张牌的火焰伤害。", + umi_lunhui: "轮回", + umi_lunhui_info: + "一名其他角色的回合结束时,若你的手牌数小于体力值,则你可以失去1点体力。若如此做,你摸两张牌并进行一个额外回合,且你于此回合内计算与此角色的距离视为1。", + umi_shiroha: "轮回 - 延时效果", + umi_qihuan: "七幻", + umi_qihuan_info: + "限定技,当你处于濒死状态时,你可以移去此武将牌。若如此做,你回复X点体力(X为场上势力数)。然后,你可获得场上已死亡角色武将牌上的至多两个技能。", + komari_tiankou: "甜口", + komari_tiankou_info: + "锁定技,当你使用红色的非伤害性基本牌/锦囊牌选择目标时,或成为其他角色使用的这些牌的目标时,你选择一项:1.摸一张牌;2.为此牌增加一个目标。", + komari_xueshang: "血殇", + komari_xueshang_info: + "锁定技,蓄能技,当有角色死亡时,你对自己造成1点伤害,然后对所有其他角色依次造成1点伤害。当有角色因此法进入濒死状态时,你加1点体力上限并回复1点体力,然后失去此技能并终止此技能的所有后续结算。", + yukine_wenzhou: "问咒", + yukine_wenzhou_info: + "一名角色的出牌阶段开始时,其可以交给你一张牌。若如此做,你选择一项:交给其一张牌,或令其从牌堆中获得一张与此牌类型相同的牌,且其于此阶段内使用与此牌牌名相同的牌时无法被响应。", //如果对自己发动【问咒】,则自己可以响应这些牌。但其他角色发动【问咒】时,该角色自己并不能响应 - yusa_yanyi:'演艺', - yusa_yanyi_info:'出牌阶段限一次,你可以指定至多X名与你距离不大于你的体力值的角色。这些角色选择一项:①令你摸一张牌。②回复1点体力,然后交给你一张牌。(X为你的攻击范围且至少为1)', - misa_yehuo:'业火', - misa_yehuo_info:'一名角色的摸牌阶段开始时,若其在你的攻击范围内,你可以弃置X张牌并选择一项:①对其造成1点火属性伤害。②令其于此摸牌阶段放弃摸牌。(X为你与其的的距离)', - yusa_misa:'通灵', - yusa_misa_info:'当你发动的〖演艺〗结算完成之后,你可以将武将牌翻面。', - misa_yusa:'归魂', - misa_yusa_info:'当你发动的〖业火〗结算完成后,你可以将武将牌翻面。', - masato_baoquan:'暴拳', - masato_baoquan_info:'锁定技,当你即将造成伤害时,你选择一项:1.令此伤害+2并减1点体力上限。2.防止此伤害。', - iwasawa_yinhang:'引吭', - iwasawa_yinhang_info:'锁定技,当你的体力值变化1点时,你可以令至多两名角色摸一张牌。', - iwasawa_mysong:'My Song', - iwasawa_mysong_info:'锁定技,当你即将进行濒死结算时,取消之。回合开始时,若你的体力值小于1,则你获得技能〖奋音〗直到回合结束。回合结束时,若你的体力值小于1,你死亡。', - iwasawa_fenyin:'奋音', - iwasawa_fenyin_info:'你的回合内,当你使用牌时,若此牌与你于此回合内使用的上一张牌的颜色不同,则你可以摸一张牌。', - iwasawa_refenyin:'奋音', - iwasawa_refenyin_info:'锁定技,你的回合内,当一张牌进入弃牌堆后,若本回合内没有过与此牌花色相同的卡牌进入过弃牌堆,则你摸一张牌。', + yusa_yanyi: "演艺", + yusa_yanyi_info: + "出牌阶段限一次,你可以指定至多X名与你距离不大于你的体力值的角色。这些角色选择一项:①令你摸一张牌。②回复1点体力,然后交给你一张牌。(X为你的攻击范围且至少为1)", + misa_yehuo: "业火", + misa_yehuo_info: + "一名角色的摸牌阶段开始时,若其在你的攻击范围内,你可以弃置X张牌并选择一项:①对其造成1点火属性伤害。②令其于此摸牌阶段放弃摸牌。(X为你与其的的距离)", + yusa_misa: "通灵", + yusa_misa_info: "当你发动的〖演艺〗结算完成之后,你可以将武将牌翻面。", + misa_yusa: "归魂", + misa_yusa_info: "当你发动的〖业火〗结算完成后,你可以将武将牌翻面。", + masato_baoquan: "暴拳", + masato_baoquan_info: + "锁定技,当你即将造成伤害时,你选择一项:1.令此伤害+2并减1点体力上限。2.防止此伤害。", + iwasawa_yinhang: "引吭", + iwasawa_yinhang_info: "锁定技,当你的体力值变化1点时,你可以令至多两名角色摸一张牌。", + iwasawa_mysong: "My Song", + iwasawa_mysong_info: + "锁定技,当你即将进行濒死结算时,取消之。回合开始时,若你的体力值小于1,则你获得技能〖奋音〗直到回合结束。回合结束时,若你的体力值小于1,你死亡。", + iwasawa_fenyin: "奋音", + iwasawa_fenyin_info: + "你的回合内,当你使用牌时,若此牌与你于此回合内使用的上一张牌的颜色不同,则你可以摸一张牌。", + iwasawa_refenyin: "奋音", + iwasawa_refenyin_info: + "锁定技,你的回合内,当一张牌进入弃牌堆后,若本回合内没有过与此牌花色相同的卡牌进入过弃牌堆,则你摸一张牌。", //卡牌花色的计算不受〖红颜〗等技能的影响 - kengo_weishang:'伪伤', - kengo_weishang_sha:'伪伤', - kengo_weishang_shan:'伪伤', - kengo_weishang_info:'出牌阶段限一次,你可以废除一个装备栏并摸两张牌。若你的武器栏已废除,则你使用【杀】的次数上限+1,且当你使用【杀】指定目标后,目标角色弃置一张牌;若你的防具栏已废除,则你可以将一张牌当做【闪】使用或打出;若你的攻击/防御坐骑栏已废除,则你至其他角色的距离-1/其他角色至你的距离-1。', - kengo_guidui:'归队', - kengo_guidui_info:'锁定技,准备阶段,若你有已废除的装备栏,则你恢复这些装备栏,且本局游戏内发动【伪伤】时不能废除这些装备栏。', - yoshino_jueyi:'决义', - yoshino_jueyi_info:'出牌阶段开始时,你可以选择一名其他角色。你摸一张牌并与其猜拳(平局则重来)。若你赢,你对其造成1点伤害。若你没赢,你本阶段内使用牌时不能指定其为目标。', - yui_jiang:'激昂', - yui_jiang_info:'每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。', - yui_lieyin:'烈音', - yui_lieyin_info:'锁定技,出牌阶段开始时,你选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。', - yui_takaramono:'珍宝', - yui_takaramono_info:'觉醒技,准备阶段,若你满足以下条件中的至少两个:①体力值不大于1;②场上有已死亡的角色;③已因〖激昂〗累计获得过至少三张牌;则你获得技能〖引吭〗,将〖烈音〗描述中的「你选择」改为「你可选择」,然后加1点体力上限并回复1点体力。', + kengo_weishang: "伪伤", + kengo_weishang_sha: "伪伤", + kengo_weishang_shan: "伪伤", + kengo_weishang_info: + "出牌阶段限一次,你可以废除一个装备栏并摸两张牌。若你的武器栏已废除,则你使用【杀】的次数上限+1,且当你使用【杀】指定目标后,目标角色弃置一张牌;若你的防具栏已废除,则你可以将一张牌当做【闪】使用或打出;若你的攻击/防御坐骑栏已废除,则你至其他角色的距离-1/其他角色至你的距离-1。", + kengo_guidui: "归队", + kengo_guidui_info: + "锁定技,准备阶段,若你有已废除的装备栏,则你恢复这些装备栏,且本局游戏内发动【伪伤】时不能废除这些装备栏。", + yoshino_jueyi: "决义", + yoshino_jueyi_info: + "出牌阶段开始时,你可以选择一名其他角色。你摸一张牌并与其猜拳(平局则重来)。若你赢,你对其造成1点伤害。若你没赢,你本阶段内使用牌时不能指定其为目标。", + yui_jiang: "激昂", + yui_jiang_info: + "每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。", + yui_lieyin: "烈音", + yui_lieyin_info: + "锁定技,出牌阶段开始时,你选择一项:①本阶段内的红色牌均视为【杀】;②本阶段内的【杀】均视为【决斗】。", + yui_takaramono: "珍宝", + yui_takaramono_info: + "觉醒技,准备阶段,若你满足以下条件中的至少两个:①体力值不大于1;②场上有已死亡的角色;③已因〖激昂〗累计获得过至少三张牌;则你获得技能〖引吭〗,将〖烈音〗描述中的「你选择」改为「你可选择」,然后加1点体力上限并回复1点体力。", //ユイ/孙笨双将组合时,孙笨的〖激昂〗不计入〖珍宝〗的次数统计 - yui_yinhang:'引吭', - yui_yinhang_info:'锁定技,当你的体力值变化1点时,你可以令至多两名角色摸一张牌。', - tsumugi_mugyu:'姆啾', - tsumugi_mugyu_info:'当你成为牌的目标后,若你的手牌数小于体力上限,则你可以摸一张牌。', - tsumugi_huilang:'回廊', - tsumugi_huilang2:'回廊', - tsumugi_huilang_info:'回合结束时,你可以将任意张牌扣置于武将牌下(均称为「隐」)。回合开始时,你获得所有「隐」,然后可令等量的角色各摸一张牌。', + yui_yinhang: "引吭", + yui_yinhang_info: "锁定技,当你的体力值变化1点时,你可以令至多两名角色摸一张牌。", + tsumugi_mugyu: "姆啾", + tsumugi_mugyu_info: "当你成为牌的目标后,若你的手牌数小于体力上限,则你可以摸一张牌。", + tsumugi_huilang: "回廊", + tsumugi_huilang2: "回廊", + tsumugi_huilang_info: + "回合结束时,你可以将任意张牌扣置于武将牌下(均称为「隐」)。回合开始时,你获得所有「隐」,然后可令等量的角色各摸一张牌。", //〖回廊〗涉及的所有卡牌移动的结算不会触发〖良姻〗 - haruka_shuangche:'双掣', - kanata_shuangche:'双掣', - haruka_shuangche_backup:'双掣', - haruka_shuangche_info:'出牌阶段,你可以视为使用任意基本牌或普通锦囊牌。此牌结算完成后,你选择一项:1.弃置X张牌。2.失去1点体力且本回合内不能再发动〖双掣〗。(X为你于此回合内发动过〖双掣〗的次数)', + haruka_shuangche: "双掣", + kanata_shuangche: "双掣", + haruka_shuangche_backup: "双掣", + haruka_shuangche_info: + "出牌阶段,你可以视为使用任意基本牌或普通锦囊牌。此牌结算完成后,你选择一项:1.弃置X张牌。2.失去1点体力且本回合内不能再发动〖双掣〗。(X为你于此回合内发动过〖双掣〗的次数)", //你不能以此法使用〖回魂〗 - saya_shouji:'授计', - saya_shouji_info:'每回合限一次,当你使用的牌结算完成后,你可以将此牌对应的所有实体牌交给一名其他角色。其可以使用这些牌中的一张,若如此做,你摸一张牌。', - saya_powei:'破围', - saya_powei_info:'限定技,回合结束后,你可以选择一名体力值大于你的其他角色。你与其交替进行额外回合,直到你与其中的一名角色死亡或进行到九个回合。你于回合开始时进行判定,若结果为红色,则你对其造成1点伤害。此过程中其他角色不计入距离和座次计算。', - saya_judge:'破围', - saya_nodis:'破围', + saya_shouji: "授计", + saya_shouji_info: + "每回合限一次,当你使用的牌结算完成后,你可以将此牌对应的所有实体牌交给一名其他角色。其可以使用这些牌中的一张,若如此做,你摸一张牌。", + saya_powei: "破围", + saya_powei_info: + "限定技,回合结束后,你可以选择一名体力值大于你的其他角色。你与其交替进行额外回合,直到你与其中的一名角色死亡或进行到九个回合。你于回合开始时进行判定,若结果为红色,则你对其造成1点伤害。此过程中其他角色不计入距离和座次计算。", + saya_judge: "破围", + saya_nodis: "破围", //〖破围〗不会因为〖铁骑〗无效 - inari_baiwei:'摆尾', - inari_baiwei_draw:'摆尾', - inari_baiwei_info:'你可以将一张♦牌当做任意基本牌使用或打出。此牌结算完成后,你摸一张牌。', + inari_baiwei: "摆尾", + inari_baiwei_draw: "摆尾", + inari_baiwei_info: "你可以将一张♦牌当做任意基本牌使用或打出。此牌结算完成后,你摸一张牌。", //你不能以此法使用【毒】 - inari_baiwei_backup:'摆尾', - inari_baiwei_sha:'摆尾', - inari_baiwei_shan:'摆尾', - inari_huhun:'狐魂', - inari_huhun_info:'锁定技,你的♣牌的花色均视为♦。你的手牌上限+1。', - shiina_qingshen:'轻身', - shiina_qingshen_info:'当你受到或造成伤害后,你可以获得此次伤害的渠道对应的实体牌,然后将等量的牌置于你的武将牌上,称为「轻」。锁定技,你的手牌上限和攻击范围+X(X为「轻」数)。', - shiina_feiyan:'飞燕', - shiina_feiyan_info:'一名其他角色的回合开始时,若其在你的攻击范围内,则你可以将一张「轻」置于弃牌堆,然后视为对其使用一张【杀】。若此【杀】未造成伤害,你摸一张牌。你于此【杀】的结算流程中视为拥有技能〖铁骑〗。', - shiina_retieji:'铁骑', + inari_baiwei_backup: "摆尾", + inari_baiwei_sha: "摆尾", + inari_baiwei_shan: "摆尾", + inari_huhun: "狐魂", + inari_huhun_info: "锁定技,你的♣牌的花色均视为♦。你的手牌上限+1。", + shiina_qingshen: "轻身", + shiina_qingshen_info: + "当你受到或造成伤害后,你可以获得此次伤害的渠道对应的实体牌,然后将等量的牌置于你的武将牌上,称为「轻」。锁定技,你的手牌上限和攻击范围+X(X为「轻」数)。", + shiina_feiyan: "飞燕", + shiina_feiyan_info: + "一名其他角色的回合开始时,若其在你的攻击范围内,则你可以将一张「轻」置于弃牌堆,然后视为对其使用一张【杀】。若此【杀】未造成伤害,你摸一张牌。你于此【杀】的结算流程中视为拥有技能〖铁骑〗。", + shiina_retieji: "铁骑", //你不能对稻荷和多鲁基发动〖飞燕〗 - sunohara_chengshuang:'成双', - sunohara_chengshuang_phase:'成双', - sunohara_chengshuang_info:'锁定技,游戏开始时,你选择你的性别。回合开始时,你可以切换你的性别。', - sunohara_tiaoyin:'挑引', - sunohara_tiaoyin_info:'出牌阶段限一次,你可以弃置任意张花色各不相同的手牌,然后获得等量角色区域内的各一张牌。若你以此法获得了异性角色区域内的牌,则你失去1点体力。', - sunohara_jianren:'坚忍', - sunohara_jianren_info:'当你受到伤害后,你可以令一名角色摸一张牌。若伤害无来源或来源与你性别不同,则改为摸三张牌。', - rin_baoqiu:'暴球', - rin_baoqiu_info:'锁定技,你的攻击范围+2。当你使用【杀】指定目标后,你进行判定。若结果:为红色,此【杀】对其的伤害值基数+1;为黑色,其无法闪避此【杀】;为♠/♥,此【杀】不计入使用次数限制且你摸一张牌;为♦/♣,目标角色的所有非锁定技失效直到回合结束,且你弃置其一张牌。', - sasami_miaobian:'喵变', - sasami_miaobian_info:'当你的体力值变为:3以下时,你获得技能〖公清〗,2以下时,你获得技能〖复难〗,1以下时,你获得技能〖暴球〗。', - sasami_gongqing:"公清", - sasami_gongqing_info:"锁定技。当你受到伤害时,若伤害来源的攻击范围:<3,则你令此伤害的数值减为1。>3,你令此伤害+1。", - sasami_funan:'复难', - sasami_funan_info:'其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。', - sasami_baoqiu:'暴球', - sasami_baoqiu_info:'锁定技,你的攻击范围+2。当你使用【杀】指定目标后,你进行判定。若结果:为红色,此【杀】对其的伤害值基数+1;为黑色,其无法闪避此【杀】;为♠/♥,此【杀】不计入使用次数限制且你摸一张牌;为♦/♣,目标角色的所有非锁定技失效直到回合结束,且你弃置其一张牌。', - akane_jugu:'巨贾', - akane_jugu_info:'锁定技,1.你的手牌上限+X。2.游戏开始时,你摸X张牌(X为你的体力上限)。', - akane_quanqing:'权倾', - akane_quanqing_info:'出牌阶段,你可选择:1.弃置一张点数大于10的牌并对攻击范围内的一名其他角色造成1点伤害;2.弃置一张点数大于6的牌并弃置攻击范围内的一名其他角色区域内的一张牌。3.弃置一张牌并令攻击范围内的一名其他角色摸一张牌。', - akane_yifu:'蚁附', - akane_yifu2:'蚁附', - akane_yifu_info:'主公技,其他键势力角色的出牌阶段限一次,其可交给你一张手牌。然后你摸一张牌,并将一张手牌交给该角色。', - doruji_feiqu:'肥躯', - doruji_feiqu_info:'锁定技,当你使用【杀】时,或你成为【杀】的目标后,你令此【杀】不可被响应。', - yuiko_fenglun:'锋论', - yuiko_fenglun_info:'出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你本阶段内使用牌没有次数和距离限制。', - yuiko_dilve:'底略', - yuiko_dilve_info:'你可以使用牌堆底的一张牌进行拼点。当你拼点后,你可以获得两张拼点牌。', - riki_spwenji:'问计', - riki_spwenji_info:'出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌名称相同的牌时不能被其他角色响应。', - riki_nvzhuang:'女装', - riki_nvzhuang_info:'锁定技,此武将牌视为包含女性性别。结束阶段,若你:有手牌,你摸一张牌;没有手牌,你摸两张牌。', - riki_mengzhong:'梦终', - riki_mengzhong_info:'觉醒技,准备阶段,若你已因〖问计〗获得了三张或更多的牌,则你加1点体力上限并回复1点体力,失去〖问计〗并获得〖重振〗。', - riki_chongzhen:'重振', - riki_chongzhen_info:'出牌阶段开始时,你可以与一名角色拼点。若你赢,你获得该角色手牌区,装备区,判定区的各一张牌;若你没赢,你于此阶段内使用牌时不能指定其他角色为目标。', - hisako_yinbao:'音爆', - hisako_yinbao_info:'当你受到伤害/回复体力后,你可以判定。若结果为♠,则你对一名其他角色造成1点雷属性伤害。', - hisako_zhuanyun:'转运', - hisako_zhuanyun_info:'锁定技,你的判定会朝向对你有利的方向倾斜。', - hinata_qiulve:'球略', - hinata_qiulve_info:'你可以将一张非基本牌当做【杀】使用或打出(无距离限制)。你以此法使用的红色【杀】不可被响应,黑色【杀】不计入使用次数限制。', - hinata_ehou:'扼喉', - hinata_ehou_info:'其他角色对你使用的牌结算完成后,你可对其使用一张【杀】。若此【杀】造成伤害,则你摸一张牌。', - noda_fengcheng:'奉承', - noda_fengcheng_info:'锁定技,其他角色交给你牌后,其摸一张牌。', - noda_xunxin:'寻衅', - noda_xunxin2:'寻衅', - noda_xunxin_info:'出牌阶段限X次,你可以视为对一名体力值不小于你的角色使用【决斗】。若如此做,此【决斗】结算完成后,没赢的角色交给赢的角色一张牌。(X为你的体力值)', - tomoya_shangxian:'伤弦', - tomoya_shangxian_info:'锁定技,你计算与其他角色的距离时始终从逆时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。', - tomoya_wangjin:'往今', - tomoya_wangjin_info:'每项每轮各限一次。一名其他角色的回合结束时,若其:在你的攻击范围内,你可令其摸一张牌。若其的体力值小于你,则你摸一张牌,并可交给其一张牌。不在你的攻击范围内,则你摸两张牌,并令其弃置你的一张手牌。若其的体力值大于你,则你视为对其使用一张【杀】(无距离限制)。', - nagisa_tiandu:'天妒', - nagisa_tiandu_info:'当你的判定牌生效后,你可以获得此牌。', - nagisa_fuxin:'抚心', - nagisa_fuxin_info:'当一名角色于回合外受到伤害,或其手牌被其他角色弃置或获得后,你可以令其判定。若结果为:红色,其摸一张牌。黑色,当前回合角色弃置一张牌。', - ayato_jianshen:'僭神', - ayato_jianshen_info:'锁定技,你手牌中的【杀】均视为神属性。', - ayato_zonghuan:'纵幻', - ayato_zonghuan_info:'出牌阶段限一次,你可以观看一名其他角色的手牌,然后选择一项:将其中的一张牌置入弃牌堆,或以该角色的视角使用其中的一张,然后摸一张牌。', - ao_xishi:'习事', - ao_xishi_info:'锁定技,当你使用或打出♦牌时,或其他角色使用♦牌指定你为目标后,你摸一张牌。', - ao_kuihun:'窥魂', - ao_kuihun_info:'其他角色进入濒死状态时,你可以摸一张牌,然后观看其手牌并将其中一张牌置于你的武将牌上,称为「蝶」。你使用与一张「蝶」花色相同的牌时无距离和次数限制。你的手牌上限+X(X为蝶数)。', - ao_shixin:'释心', - ao_shixin_info:'觉醒技,准备阶段,若你的「蝶」中包含至少三种花色,则你加1点体力上限并回复1点体力,失去〖窥魂〗并获得〖蝶归〗。', - ao_diegui:'蝶归', - ao_diegui_backup:'蝶归', - ao_diegui_info:'出牌阶段限一次,你可以将一张「蝶」交给一名角色,该角色摸两张牌并复原武将牌。', - yuzuru_wuxin:'无心', - yuzuru_wuxin_info:'结束阶段,你可以选择一项:失去1点体力并令一名角色摸两张牌,或弃置两张牌并回复1点体力。', - yuzuru_deyi:'得义', - yuzuru_deyi_info:'觉醒技,当有其他角色死亡后,你减1点体力上限并回复1点体力,失去技能〖无心〗,获得技能〖往生〗〖困奋〗和〖去疾〗。', - yuzuru_wangsheng:'往生', - yuzuru_wangsheng_info:'觉醒技,当你即将死亡时,你防止此次死亡。你可以将任意张牌交给一名其他角色,然后减1点体力上限并将体力回复至2点,修改技能〖困奋〗和〖去疾〗。', - yuzuru_kunfen:'困奋', - yuzuru_kunfen_info:'锁定技,结束阶段,你失去1点体力并摸两张牌。然后你可以将两张牌交给一名其他角色。', - yuzuru_quji:'去疾', - yuzuru_quji_info:'出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。若你以此法弃置了黑色牌,则你失去1点体力。(X为你已损失的体力值)', - yuzuru_kunfen_rewrite:'困奋·改', - yuzuru_kunfen_rewrite_info:'锁定技,结束阶段,你摸两张牌。然后你可以将两张牌交给一名其他角色。', - yuzuru_quji_rewrite:'去疾·改', - yuzuru_quji_rewrite_info:'出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。(X为你已损失的体力值)', - yuzuru_bujin:'步进', - yuzuru_bujin_info:'锁定技,己方其他角色计算与其他角色的距离-1且摸牌阶段的额定摸牌数+1。', - kanade_mapo:'麻婆', - kanade_mapo_info:'你可以将一张♥牌当做【麻婆豆腐】使用。你使用的【麻婆豆腐】可以多指定一个目标。', - kanade_benzhan:'奔战', - kanade_benzhan_info:'每回合限一次。当你使用或打出牌响应其他角色,或其他角色使用或打出牌响应你后,若此牌为:基本牌,你可令一名角色弃置两张牌或令一名角色摸两张牌;非基本牌,你可对一名角色造成1点伤害或令一名其他角色回复1点体力。', - mio_tuifu:'推腐', - mio_tuifu_info:'锁定技,当一名角色对一名同性角色造成伤害时,你摸一张牌。', - mio_tishen:'替身', - mio_tishen_info:'限定技,准备阶段,你可以将体力值回复至体力上限并摸等同于回复量的牌,然后将武将牌替换为【西园美鸟】。', - midori_nonghuan:'弄幻', - midori_nonghuan_info:'出牌阶段限X次(X为你的体力值),你可以获得一名本阶段内未选择过的其他角色的区域内的一张牌。你摸一张牌,然后将一张牌交给该角色。然后你清除此技能结算过程中所有卡牌移动事件的移动记录。', + sunohara_chengshuang: "成双", + sunohara_chengshuang_phase: "成双", + sunohara_chengshuang_info: "锁定技,游戏开始时,你选择你的性别。回合开始时,你可以切换你的性别。", + sunohara_tiaoyin: "挑引", + sunohara_tiaoyin_info: + "出牌阶段限一次,你可以弃置任意张花色各不相同的手牌,然后获得等量角色区域内的各一张牌。若你以此法获得了异性角色区域内的牌,则你失去1点体力。", + sunohara_jianren: "坚忍", + sunohara_jianren_info: + "当你受到伤害后,你可以令一名角色摸一张牌。若伤害无来源或来源与你性别不同,则改为摸三张牌。", + rin_baoqiu: "暴球", + rin_baoqiu_info: + "锁定技,你的攻击范围+2。当你使用【杀】指定目标后,你进行判定。若结果:为红色,此【杀】对其的伤害值基数+1;为黑色,其无法闪避此【杀】;为♠/♥,此【杀】不计入使用次数限制且你摸一张牌;为♦/♣,目标角色的所有非锁定技失效直到回合结束,且你弃置其一张牌。", + sasami_miaobian: "喵变", + sasami_miaobian_info: + "当你的体力值变为:3以下时,你获得技能〖公清〗,2以下时,你获得技能〖复难〗,1以下时,你获得技能〖暴球〗。", + sasami_gongqing: "公清", + sasami_gongqing_info: + "锁定技。当你受到伤害时,若伤害来源的攻击范围:<3,则你令此伤害的数值减为1。>3,你令此伤害+1。", + sasami_funan: "复难", + sasami_funan_info: + "其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。", + sasami_baoqiu: "暴球", + sasami_baoqiu_info: + "锁定技,你的攻击范围+2。当你使用【杀】指定目标后,你进行判定。若结果:为红色,此【杀】对其的伤害值基数+1;为黑色,其无法闪避此【杀】;为♠/♥,此【杀】不计入使用次数限制且你摸一张牌;为♦/♣,目标角色的所有非锁定技失效直到回合结束,且你弃置其一张牌。", + akane_jugu: "巨贾", + akane_jugu_info: "锁定技,1.你的手牌上限+X。2.游戏开始时,你摸X张牌(X为你的体力上限)。", + akane_quanqing: "权倾", + akane_quanqing_info: + "出牌阶段,你可选择:1.弃置一张点数大于10的牌并对攻击范围内的一名其他角色造成1点伤害;2.弃置一张点数大于6的牌并弃置攻击范围内的一名其他角色区域内的一张牌。3.弃置一张牌并令攻击范围内的一名其他角色摸一张牌。", + akane_yifu: "蚁附", + akane_yifu2: "蚁附", + akane_yifu_info: + "主公技,其他键势力角色的出牌阶段限一次,其可交给你一张手牌。然后你摸一张牌,并将一张手牌交给该角色。", + doruji_feiqu: "肥躯", + doruji_feiqu_info: "锁定技,当你使用【杀】时,或你成为【杀】的目标后,你令此【杀】不可被响应。", + yuiko_fenglun: "锋论", + yuiko_fenglun_info: + "出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你本阶段内使用牌没有次数和距离限制。", + yuiko_dilve: "底略", + yuiko_dilve_info: "你可以使用牌堆底的一张牌进行拼点。当你拼点后,你可以获得两张拼点牌。", + riki_spwenji: "问计", + riki_spwenji_info: + "出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌名称相同的牌时不能被其他角色响应。", + riki_nvzhuang: "女装", + riki_nvzhuang_info: + "锁定技,此武将牌视为包含女性性别。结束阶段,若你:有手牌,你摸一张牌;没有手牌,你摸两张牌。", + riki_mengzhong: "梦终", + riki_mengzhong_info: + "觉醒技,准备阶段,若你已因〖问计〗获得了三张或更多的牌,则你加1点体力上限并回复1点体力,失去〖问计〗并获得〖重振〗。", + riki_chongzhen: "重振", + riki_chongzhen_info: + "出牌阶段开始时,你可以与一名角色拼点。若你赢,你获得该角色手牌区,装备区,判定区的各一张牌;若你没赢,你于此阶段内使用牌时不能指定其他角色为目标。", + hisako_yinbao: "音爆", + hisako_yinbao_info: + "当你受到伤害/回复体力后,你可以判定。若结果为♠,则你对一名其他角色造成1点雷属性伤害。", + hisako_zhuanyun: "转运", + hisako_zhuanyun_info: "锁定技,你的判定会朝向对你有利的方向倾斜。", + hinata_qiulve: "球略", + hinata_qiulve_info: + "你可以将一张非基本牌当做【杀】使用或打出(无距离限制)。你以此法使用的红色【杀】不可被响应,黑色【杀】不计入使用次数限制。", + hinata_ehou: "扼喉", + hinata_ehou_info: + "其他角色对你使用的牌结算完成后,你可对其使用一张【杀】。若此【杀】造成伤害,则你摸一张牌。", + noda_fengcheng: "奉承", + noda_fengcheng_info: "锁定技,其他角色交给你牌后,其摸一张牌。", + noda_xunxin: "寻衅", + noda_xunxin2: "寻衅", + noda_xunxin_info: + "出牌阶段限X次,你可以视为对一名体力值不小于你的角色使用【决斗】。若如此做,此【决斗】结算完成后,没赢的角色交给赢的角色一张牌。(X为你的体力值)", + tomoya_shangxian: "伤弦", + tomoya_shangxian_info: + "锁定技,你计算与其他角色的距离时始终从逆时针方向计算。出牌阶段开始时,你可摸一张牌,并改变此方向。", + tomoya_wangjin: "往今", + tomoya_wangjin_info: + "每项每轮各限一次。一名其他角色的回合结束时,若其:在你的攻击范围内,你可令其摸一张牌。若其的体力值小于你,则你摸一张牌,并可交给其一张牌。不在你的攻击范围内,则你摸两张牌,并令其弃置你的一张手牌。若其的体力值大于你,则你视为对其使用一张【杀】(无距离限制)。", + nagisa_tiandu: "天妒", + nagisa_tiandu_info: "当你的判定牌生效后,你可以获得此牌。", + nagisa_fuxin: "抚心", + nagisa_fuxin_info: + "当一名角色于回合外受到伤害,或其手牌被其他角色弃置或获得后,你可以令其判定。若结果为:红色,其摸一张牌。黑色,当前回合角色弃置一张牌。", + ayato_jianshen: "僭神", + ayato_jianshen_info: "锁定技,你手牌中的【杀】均视为神属性。", + ayato_zonghuan: "纵幻", + ayato_zonghuan_info: + "出牌阶段限一次,你可以观看一名其他角色的手牌,然后选择一项:将其中的一张牌置入弃牌堆,或以该角色的视角使用其中的一张,然后摸一张牌。", + ao_xishi: "习事", + ao_xishi_info: "锁定技,当你使用或打出♦牌时,或其他角色使用♦牌指定你为目标后,你摸一张牌。", + ao_kuihun: "窥魂", + ao_kuihun_info: + "其他角色进入濒死状态时,你可以摸一张牌,然后观看其手牌并将其中一张牌置于你的武将牌上,称为「蝶」。你使用与一张「蝶」花色相同的牌时无距离和次数限制。你的手牌上限+X(X为蝶数)。", + ao_shixin: "释心", + ao_shixin_info: + "觉醒技,准备阶段,若你的「蝶」中包含至少三种花色,则你加1点体力上限并回复1点体力,失去〖窥魂〗并获得〖蝶归〗。", + ao_diegui: "蝶归", + ao_diegui_backup: "蝶归", + ao_diegui_info: "出牌阶段限一次,你可以将一张「蝶」交给一名角色,该角色摸两张牌并复原武将牌。", + yuzuru_wuxin: "无心", + yuzuru_wuxin_info: + "结束阶段,你可以选择一项:失去1点体力并令一名角色摸两张牌,或弃置两张牌并回复1点体力。", + yuzuru_deyi: "得义", + yuzuru_deyi_info: + "觉醒技,当有其他角色死亡后,你减1点体力上限并回复1点体力,失去技能〖无心〗,获得技能〖往生〗〖困奋〗和〖去疾〗。", + yuzuru_wangsheng: "往生", + yuzuru_wangsheng_info: + "觉醒技,当你即将死亡时,你防止此次死亡。你可以将任意张牌交给一名其他角色,然后减1点体力上限并将体力回复至2点,修改技能〖困奋〗和〖去疾〗。", + yuzuru_kunfen: "困奋", + yuzuru_kunfen_info: + "锁定技,结束阶段,你失去1点体力并摸两张牌。然后你可以将两张牌交给一名其他角色。", + yuzuru_quji: "去疾", + yuzuru_quji_info: + "出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。若你以此法弃置了黑色牌,则你失去1点体力。(X为你已损失的体力值)", + yuzuru_kunfen_rewrite: "困奋·改", + yuzuru_kunfen_rewrite_info: "锁定技,结束阶段,你摸两张牌。然后你可以将两张牌交给一名其他角色。", + yuzuru_quji_rewrite: "去疾·改", + yuzuru_quji_rewrite_info: + "出牌阶段限一次,你可以弃置X张牌并选择至多等量已受伤的其他角色,这些角色各回复1点体力。(X为你已损失的体力值)", + yuzuru_bujin: "步进", + yuzuru_bujin_info: "锁定技,己方其他角色计算与其他角色的距离-1且摸牌阶段的额定摸牌数+1。", + kanade_mapo: "麻婆", + kanade_mapo_info: "你可以将一张♥牌当做【麻婆豆腐】使用。你使用的【麻婆豆腐】可以多指定一个目标。", + kanade_benzhan: "奔战", + kanade_benzhan_info: + "每回合限一次。当你使用或打出牌响应其他角色,或其他角色使用或打出牌响应你后,若此牌为:基本牌,你可令一名角色弃置两张牌或令一名角色摸两张牌;非基本牌,你可对一名角色造成1点伤害或令一名其他角色回复1点体力。", + mio_tuifu: "推腐", + mio_tuifu_info: "锁定技,当一名角色对一名同性角色造成伤害时,你摸一张牌。", + mio_tishen: "替身", + mio_tishen_info: + "限定技,准备阶段,你可以将体力值回复至体力上限并摸等同于回复量的牌,然后将武将牌替换为【西园美鸟】。", + midori_nonghuan: "弄幻", + midori_nonghuan_info: + "出牌阶段限X次(X为你的体力值),你可以获得一名本阶段内未选择过的其他角色的区域内的一张牌。你摸一张牌,然后将一张牌交给该角色。然后你清除此技能结算过程中所有卡牌移动事件的移动记录。", //即技能结算完成后,所有涉及到的牌移动事件不会再被getHistory获取 - midori_tishen:'替身', - midori_tishen_info:'限定技,准备阶段,你可以将体力值回复至体力上限并摸等同于回复量的牌,然后将武将牌替换为【西园美鱼】。', - kyoko_juwu:'聚物', - kyoko_juwu_info:'你的回合外,当有装备牌进入弃牌堆后,若这些牌不是从你的区域移动的,则你可以获得这些牌。', - kyoko_zhengyi:'整遗', - kyoko_zhengyi_info:'锁定技,若你装备区的花色数:大于等于1,你视为拥有〖精策〗;大于等于2,你视为拥有〖涉猎〗:大于等于3,你视为拥有〖制衡〗;大于等于4,你将〖精策〗和〖制衡〗改为界限突破版本。', - kyoko_jingce:'精策', - kyoko_shelie:'涉猎', - kyoko_zhiheng:'制衡', - shizuru_nianli:'念力', - shizuru_nianli_info:'每轮限一次,你可以展示一张♦/♣/♥/♠手牌,然后视为使用一张不计入次数限制和记录的雷【杀】/【闪】/【桃】/【无懈可击】。', - shizuru_benzhan:'奔战', - shizuru_benzhan_info:'每回合限一次。当你使用或打出牌响应其他角色,或其他角色使用或打出牌响应你后,若此牌为:基本牌,你可令一名角色弃置两张牌或令一名角色摸两张牌;非基本牌,你可对一名角色造成1点伤害或令一名其他角色回复1点体力。', - shiorimiyuki_banyin:'伴音', - shiorimiyuki_banyin_info:'当你受到伤害或回复体力后,你可令一名其他角色回复1点体力。', - shiorimiyuki_tingxian:'铤险', - shiorimiyuki_tingxian_info:'出牌阶段开始时,你可以摸至多三张牌。若如此做,你回复1点体力,且此阶段结束时你失去X点体力。(X为你得到的牌中仍在手牌区的牌的数量)', - shiorimiyuki_tingxian2:'铤险', - miki_shenqiang:'神枪', - miki_shenqiang_info:'锁定技,游戏开始时,你将一张【海德洛格拉迪尔特·改】和一张【望远镜】置入你的装备区。你装备区内的武器牌和宝物牌不能被其他角色弃置。', - miki_huanmeng:'幻梦', - miki_huanmeng_info:'准备阶段开始时,你可以观看牌堆顶的X+1张牌并可以按任意顺序置于牌堆顶或牌堆底。(X为你装备区内的牌数)', - miki_zhiluo:'治裸', - miki_zhiluo_info:'锁定技,一名其他角色的回合结束时,若其在你的攻击范围内且其装备区内没有牌,则你选择:①摸一张牌。②视为对其使用一张【杀】。', - miki_hydrogladiator:'海德洛', - miki_hydrogladiator_info:'全名为【海德洛格拉迪尔特·改】。锁定技,当你因执行【杀】的效果而对目标角色造成伤害后,你弃置所有至目标角色距离为1的其他角色的一张牌或弃置其两张牌。', - miki_hydrogladiator_skill:'海德洛格拉迪尔特·改', - miki_binoculars:'望远镜', - miki_binoculars_info:'锁定技,其他角色的手牌对你可见。', - shiori_huijuan:'绘卷', - shiori_huijuan_discard:'绘卷', - shiori_huijuan_info:'锁定技,其他角色的结束阶段开始时,你可以视为使用一张该角色本回合出牌阶段内使用过的基本牌或普通锦囊牌。准备阶段开始时,若你自上个回合起以此法使用的牌数不小于X,则你选择一项:①弃置装备区或判定区内的一张牌。②跳过本回合的出牌阶段。(X为场上玩家数的一半且至少为2)', - kaori_siyuan:'思愿', - kaori_siyuan_info:'出牌阶段,你可以将一张装备牌或延时锦囊牌置于一名其他角色的装备区内,然后可以视为使用一张基本牌或普通锦囊牌。', - akiko_dongcha:'洞察', - akiko_dongcha_info_identity:'锁定技,其他角色的手牌对你可见。游戏开始时,你令其他角色的身份牌对你可见。', - akiko_dongcha_info:'锁定技,其他角色的手牌对你可见。', - abyusa_jueqing:'绝情', - abyusa_jueqing_info:'当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。', - abyusa_jueqing_1st:'绝情', - abyusa_jueqing_rewrite:'绝情·改', - abyusa_jueqing_rewrite_info:'锁定技,你即将造成的伤害均视为失去体力。', - abyusa_dunying:'遁影', - abyusa_dunying_info:'锁定技,其他角色计算与你的距离时+X。准备阶段和结束阶段,你摸X张牌(X为你已损失的体力值)。', - godan_yuanyi:'远忆', - godan_yuanyi_info:'锁定技,回合开始时,你摸X张牌并进行一个额外的出牌阶段。(X为游戏轮数且至多为3)', - godan_feiqu:'肥躯', - godan_feiqu_info:'锁定技,当你使用【杀】时,或你成为【杀】的目标后,你令此【杀】不可被响应。', - godan_xiaoyuan:'消元', - godan_xiaoyuan_info:'觉醒技,当你扣减体力时,若你的体力值小于4,则你减3点体力上限并摸三张牌,失去【肥躯】。', - yuu_lveduo:'掠夺', - yuu_lveduo_info:'每轮限一次,其他角色的回合开始时,若你本局游戏内未对其发动过〖掠夺〗且你的武将牌正面朝上,你可以将武将牌翻面并获得该角色本回合内的控制权。此回合结束时,你将武将牌翻回正面。锁定技,若你的武将牌背面朝上,则你不能使用或打出牌。', - yuu_lveduo_full_info:'每轮限一次,其他角色的回合开始时,若你本局游戏内未对其发动过〖掠夺〗且你的武将牌正面朝上,你可以将武将牌翻面并获得该角色本回合内的控制权。此回合结束时,你将武将牌翻回正面,获得该角色武将牌上所有的带有「Charlotte」标签的技能,且该角色失去这些技能。锁定技,若你的武将牌背面朝上,则你不能使用或打出牌。', - ryoichi_baoyi:'爆衣', - ryoichi_baoyi_info:'锁定技,当你失去装备区内的一张牌后,你摸一张牌,然后选择一项:①令一名其他女性角色失去1点体力。②弃置一名其他非女性角色区域内的两张牌。', - ryoichi_tuipi:'褪皮', - ryoichi_tuipi_info:'锁定技,你不是【顺手牵羊】和【过河拆桥】的合法目标。你装备区的牌于弃牌阶段内计入手牌上限。', - kotori_yumo:'驭魔', - kotori_yumo_damage:'驭魔', - kotori_yumo_gain:'驭魔', - kotori_yumo_info:'锁定技,游戏开始时,你获得蓝色、红色、绿色、黄色、灰色魔物各一个。当有角色受到伤害后,若你没有对应的标记,你根据其势力获得一个对应魔物:魏:蓝、蜀:红、吴:绿、群:黄、灰:晋、键:紫。回合开始时,你可以弃置一个对应的魔物并获得以下技能之一直到回合结束:蓝:魏业、红:蜀义、绿:吴耀、黄:群心、灰:晋势、紫:键魂。', - kotori_skill_wei:'魏业', - kotori_skill_wei_info:'回合开始时,你可以弃置一张牌并指定一名其他角色,该角色须弃置一张牌,否则你摸一张牌。', - kotori_skill_shu:'蜀义', - kotori_skill_shu_info:'你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。', - kotori_skill_wu:'吴耀', - kotori_skill_wu_info:'回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。', - kotori_skill_qun:'群心', - kotori_skill_qun_info:'锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1。', - kotori_skill_key:'键魂', - kotori_skill_key_info:'出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。', - kotori_skill_jin:'晋势', - kotori_skill_jin_info:'摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。', - kotori_yumo_wei:'魔物', - kotori_yumo_shu:'魔物', - kotori_yumo_wu:'魔物', - kotori_yumo_qun:'魔物', - kotori_yumo_key:'魔物', - kotori_yumo_jin:'魔物', - kotori_huazhan:'花绽', - kotori_huazhan_info:'每回合每种魔物限一次,你可将一个蓝色/红色/绿色/黄色/紫色/灰色魔物当做【树上开花】使用。', - jojiro_shensu:'神速', - jojiro_shensu_info:'你可以选择一至三项:1. 跳过判定阶段和摸牌阶段;2. 跳过出牌阶段并弃置一张装备牌;3. 跳过弃牌阶段并将你的武将牌翻面。你每选择一项,视为你对一名其他角色使用一张没有距离限制的【杀】。', - jojiro_shensu1:'神速', - jojiro_shensu2:'神速', - jojiro_shensu4:'神速', - jojiro_shunying:'瞬影', - jojiro_shunying_info:'锁定技,回合结束时,若你本回合内跳过了阶段,则你选择一项:1.失去1点体力。2.移动至多X格并摸X张牌(X为你本回合内跳过的阶段数)。', - shiroha_yuzhao:'预兆', - shiroha_yuzhao_umi:'预兆', - shiroha_yuzhao_info:'锁定技,游戏开始时,你将牌堆顶的X张牌扣置于你的武将牌上,称为「兆」。一名角色的回合开始时,若你有「兆」且其至你的距离不大于1,则你将牌堆顶的X张牌扣置为「兆」,然后将等量的「兆」置于牌堆顶。(X为势力数)', - shiroha_guying:'孤影', - shiroha_guying_info:'锁定技,每回合限一次,当你受到伤害/对其他角色造成伤害时,你进行判定。若结果为红色/黑色,此伤害-1/+1。', - shiroha_guying_rewrite:'孤影·改', - shiroha_guying_rewrite_info:'当你受到伤害/对其他角色造成伤害时,你可进行判定。若结果为红色/黑色,此伤害-1/+1。', - shiroha_jiezhao:'解兆', - shiroha_jiezhao_info:'一名角色的判定牌生效前,你可打出一张「兆」代替之。当你以此法移去最后一张「兆」后,你加1点体力上限并回复1点体力,然后修改〖孤影〗并随机获得以下技能中的一个:〖炒饭〗/〖习事〗/〖呣啾〗/〖结伴〗。', + midori_tishen: "替身", + midori_tishen_info: + "限定技,准备阶段,你可以将体力值回复至体力上限并摸等同于回复量的牌,然后将武将牌替换为【西园美鱼】。", + kyoko_juwu: "聚物", + kyoko_juwu_info: + "你的回合外,当有装备牌进入弃牌堆后,若这些牌不是从你的区域移动的,则你可以获得这些牌。", + kyoko_zhengyi: "整遗", + kyoko_zhengyi_info: + "锁定技,若你装备区的花色数:大于等于1,你视为拥有〖精策〗;大于等于2,你视为拥有〖涉猎〗:大于等于3,你视为拥有〖制衡〗;大于等于4,你将〖精策〗和〖制衡〗改为界限突破版本。", + kyoko_jingce: "精策", + kyoko_shelie: "涉猎", + kyoko_zhiheng: "制衡", + shizuru_nianli: "念力", + shizuru_nianli_info: + "每轮限一次,你可以展示一张♦/♣/♥/♠手牌,然后视为使用一张不计入次数限制和记录的雷【杀】/【闪】/【桃】/【无懈可击】。", + shizuru_benzhan: "奔战", + shizuru_benzhan_info: + "每回合限一次。当你使用或打出牌响应其他角色,或其他角色使用或打出牌响应你后,若此牌为:基本牌,你可令一名角色弃置两张牌或令一名角色摸两张牌;非基本牌,你可对一名角色造成1点伤害或令一名其他角色回复1点体力。", + shiorimiyuki_banyin: "伴音", + shiorimiyuki_banyin_info: "当你受到伤害或回复体力后,你可令一名其他角色回复1点体力。", + shiorimiyuki_tingxian: "铤险", + shiorimiyuki_tingxian_info: + "出牌阶段开始时,你可以摸至多三张牌。若如此做,你回复1点体力,且此阶段结束时你失去X点体力。(X为你得到的牌中仍在手牌区的牌的数量)", + shiorimiyuki_tingxian2: "铤险", + miki_shenqiang: "神枪", + miki_shenqiang_info: + "锁定技,游戏开始时,你将一张【海德洛格拉迪尔特·改】和一张【望远镜】置入你的装备区。你装备区内的武器牌和宝物牌不能被其他角色弃置。", + miki_huanmeng: "幻梦", + miki_huanmeng_info: + "准备阶段开始时,你可以观看牌堆顶的X+1张牌并可以按任意顺序置于牌堆顶或牌堆底。(X为你装备区内的牌数)", + miki_zhiluo: "治裸", + miki_zhiluo_info: + "锁定技,一名其他角色的回合结束时,若其在你的攻击范围内且其装备区内没有牌,则你选择:①摸一张牌。②视为对其使用一张【杀】。", + miki_hydrogladiator: "海德洛", + miki_hydrogladiator_info: + "全名为【海德洛格拉迪尔特·改】。锁定技,当你因执行【杀】的效果而对目标角色造成伤害后,你弃置所有至目标角色距离为1的其他角色的一张牌或弃置其两张牌。", + miki_hydrogladiator_skill: "海德洛格拉迪尔特·改", + miki_binoculars: "望远镜", + miki_binoculars_info: "锁定技,其他角色的手牌对你可见。", + shiori_huijuan: "绘卷", + shiori_huijuan_discard: "绘卷", + shiori_huijuan_info: + "锁定技,其他角色的结束阶段开始时,你可以视为使用一张该角色本回合出牌阶段内使用过的基本牌或普通锦囊牌。准备阶段开始时,若你自上个回合起以此法使用的牌数不小于X,则你选择一项:①弃置装备区或判定区内的一张牌。②跳过本回合的出牌阶段。(X为场上玩家数的一半且至少为2)", + kaori_siyuan: "思愿", + kaori_siyuan_info: + "出牌阶段,你可以将一张装备牌或延时锦囊牌置于一名其他角色的装备区内,然后可以视为使用一张基本牌或普通锦囊牌。", + akiko_dongcha: "洞察", + akiko_dongcha_info_identity: + "锁定技,其他角色的手牌对你可见。游戏开始时,你令其他角色的身份牌对你可见。", + akiko_dongcha_info: "锁定技,其他角色的手牌对你可见。", + abyusa_jueqing: "绝情", + abyusa_jueqing_info: + "当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。", + abyusa_jueqing_1st: "绝情", + abyusa_jueqing_rewrite: "绝情·改", + abyusa_jueqing_rewrite_info: "锁定技,你即将造成的伤害均视为失去体力。", + abyusa_dunying: "遁影", + abyusa_dunying_info: + "锁定技,其他角色计算与你的距离时+X。准备阶段和结束阶段,你摸X张牌(X为你已损失的体力值)。", + godan_yuanyi: "远忆", + godan_yuanyi_info: + "锁定技,回合开始时,你摸X张牌并进行一个额外的出牌阶段。(X为游戏轮数且至多为3)", + godan_feiqu: "肥躯", + godan_feiqu_info: "锁定技,当你使用【杀】时,或你成为【杀】的目标后,你令此【杀】不可被响应。", + godan_xiaoyuan: "消元", + godan_xiaoyuan_info: + "觉醒技,当你扣减体力时,若你的体力值小于4,则你减3点体力上限并摸三张牌,失去【肥躯】。", + yuu_lveduo: "掠夺", + yuu_lveduo_info: + "每轮限一次,其他角色的回合开始时,若你本局游戏内未对其发动过〖掠夺〗且你的武将牌正面朝上,你可以将武将牌翻面并获得该角色本回合内的控制权。此回合结束时,你将武将牌翻回正面。锁定技,若你的武将牌背面朝上,则你不能使用或打出牌。", + yuu_lveduo_full_info: + "每轮限一次,其他角色的回合开始时,若你本局游戏内未对其发动过〖掠夺〗且你的武将牌正面朝上,你可以将武将牌翻面并获得该角色本回合内的控制权。此回合结束时,你将武将牌翻回正面,获得该角色武将牌上所有的带有「Charlotte」标签的技能,且该角色失去这些技能。锁定技,若你的武将牌背面朝上,则你不能使用或打出牌。", + ryoichi_baoyi: "爆衣", + ryoichi_baoyi_info: + "锁定技,当你失去装备区内的一张牌后,你摸一张牌,然后选择一项:①令一名其他女性角色失去1点体力。②弃置一名其他非女性角色区域内的两张牌。", + ryoichi_tuipi: "褪皮", + ryoichi_tuipi_info: + "锁定技,你不是【顺手牵羊】和【过河拆桥】的合法目标。你装备区的牌于弃牌阶段内计入手牌上限。", + kotori_yumo: "驭魔", + kotori_yumo_damage: "驭魔", + kotori_yumo_gain: "驭魔", + kotori_yumo_info: + "锁定技,游戏开始时,你获得蓝色、红色、绿色、黄色、灰色魔物各一个。当有角色受到伤害后,若你没有对应的标记,你根据其势力获得一个对应魔物:魏:蓝、蜀:红、吴:绿、群:黄、灰:晋、键:紫。回合开始时,你可以弃置一个对应的魔物并获得以下技能之一直到回合结束:蓝:魏业、红:蜀义、绿:吴耀、黄:群心、灰:晋势、紫:键魂。", + kotori_skill_wei: "魏业", + kotori_skill_wei_info: + "回合开始时,你可以弃置一张牌并指定一名其他角色,该角色须弃置一张牌,否则你摸一张牌。", + kotori_skill_shu: "蜀义", + kotori_skill_shu_info: + "你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。", + kotori_skill_wu: "吴耀", + kotori_skill_wu_info: "回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。", + kotori_skill_qun: "群心", + kotori_skill_qun_info: + "锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1。", + kotori_skill_key: "键魂", + kotori_skill_key_info: + "出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。", + kotori_skill_jin: "晋势", + kotori_skill_jin_info: + "摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。", + kotori_yumo_wei: '魔物', + kotori_yumo_shu: '魔物', + kotori_yumo_wu: '魔物', + kotori_yumo_qun: '魔物', + kotori_yumo_key: '魔物', + kotori_yumo_jin: '魔物', + kotori_huazhan: "花绽", + kotori_huazhan_info: + "每回合每种魔物限一次,你可将一个蓝色/红色/绿色/黄色/紫色/灰色魔物当做【树上开花】使用。", + jojiro_shensu: "神速", + jojiro_shensu_info: + "你可以选择一至三项:1. 跳过判定阶段和摸牌阶段;2. 跳过出牌阶段并弃置一张装备牌;3. 跳过弃牌阶段并将你的武将牌翻面。你每选择一项,视为你对一名其他角色使用一张没有距离限制的【杀】。", + jojiro_shensu1: "神速", + jojiro_shensu2: "神速", + jojiro_shensu4: "神速", + jojiro_shunying: "瞬影", + jojiro_shunying_info: + "锁定技,回合结束时,若你本回合内跳过了阶段,则你选择一项:1.失去1点体力。2.移动至多X格并摸X张牌(X为你本回合内跳过的阶段数)。", + shiroha_yuzhao: "预兆", + shiroha_yuzhao_umi: "预兆", + shiroha_yuzhao_info: + "锁定技,游戏开始时,你将牌堆顶的X张牌扣置于你的武将牌上,称为「兆」。一名角色的回合开始时,若你有「兆」且其至你的距离不大于1,则你将牌堆顶的X张牌扣置为「兆」,然后将等量的「兆」置于牌堆顶。(X为势力数)", + shiroha_guying: "孤影", + shiroha_guying_info: + "锁定技,每回合限一次,当你受到伤害/对其他角色造成伤害时,你进行判定。若结果为红色/黑色,此伤害-1/+1。", + shiroha_guying_rewrite: "孤影·改", + shiroha_guying_rewrite_info: + "当你受到伤害/对其他角色造成伤害时,你可进行判定。若结果为红色/黑色,此伤害-1/+1。", + shiroha_jiezhao: "解兆", + shiroha_jiezhao_info: + "一名角色的判定牌生效前,你可打出一张「兆」代替之。当你以此法移去最后一张「兆」后,你加1点体力上限并回复1点体力,然后修改〖孤影〗并随机获得以下技能中的一个:〖炒饭〗/〖习事〗/〖呣啾〗/〖结伴〗。", //猴年马月爆料再利用 - shizuku_sizhi:'思智', - shizuku_sizhi2:'思智', - shizuku_sizhi_info:'出牌阶段限一次,你可以弃置任意张点数之和为13的牌,然后摸两倍数量的牌。以此法得到的牌中,黑色牌本回合无距离和次数限制,红色牌本回合不计入手牌上限。', - shizuku_biyi:'避忆', - shizuku_biyi_info:'当你受到伤害后,你可以进行一次判定,然后若你弃置任意张点数之和与判定结果点数相同的牌,你回复1点体力。', - shizuku_sanhua:'散花', - shizuku_sanhua_info:'当你死亡时,你可令一名其他角色从牌堆中获得四张名称各不相同的基本牌。', - hiroto_huyu:'虎驭', - hiroto_huyu2:'虎驭', - hiroto_huyu_info:'其他角色的出牌阶段结束时,若你没有技能〖纵略〗,则其可将两张手牌交给你。若如此做,你获得〖纵略〗。你的下回合结束时,你失去〖纵略〗并将本回合内得到的所有牌交给该角色。', - hiroto_zonglve:'纵略', - hiroto_zonglve_info:'锁定技,你的手牌上限+3。出牌阶段限一次,你可以将一张手牌背面朝下放置,并展示一名其他角色的一张手牌。若这两张牌:颜色相同,你对其造成1点伤害并弃置其展示的牌。颜色不同,你获得该角色区域内的两张牌。', - hiroto_tuolao:'脱牢', - hiroto_tuolao_info:'觉醒技,回合结束后,若此回合不是你的第一个回合且你本轮内未因〖虎驭〗失去过牌,则你摸三张牌,失去〖虎驭〗并获得〖纵略〗。', - sakuya_junbu:'均步', - sakuya_junbu_info:'锁定技,若你已废除的装备栏数量:≥1,你使用牌无距离限制。≥2,你使用牌无次数限制。≥3,你使用牌时可以多指定一个目标。≥4,你使用的牌不可被响应。≥5,你使用牌造成伤害时失去1点体力,令此伤害+1。', - rumi_shuwu:'淑武', - rumi_shuwu2:'淑武', - rumi_shuwu_info:'锁定技,你使用【杀】无距离和次数限制,你使用普通锦囊牌选择目标后,可增加一个目标。出牌阶段结束时,你令X=0,且每满足一项便令X+1:①你于本阶段内使用【杀】的次数不大于1。②你于本阶段内未使用锦囊牌造成过伤害。③你的体力值不大于3。你摸X张牌,且本回合手牌上限+X。', - chihaya_liewu:'烈武', - chihaya_liewu2:'烈武', - chihaya_liewu_info:'锁定技,你使用【杀】无距离和次数限制,你使用普通锦囊牌选择目标后,可增加一个目标。当你首次废除最后一个装备栏后,你减4点体力上限并获得技能〖怀柔〗。', - chihaya_youfeng:'游凤', - chihaya_youfeng_info:'转换技,阴,每轮限一次,你可以加1点体力上限,视为使用一张普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张基本牌。', - chihaya_huairou:'怀柔', - chihaya_huairou_info:'出牌阶段,你可以重铸装备牌。', - yukito_kongwu:'控物', - yukito_kongwu_info:'出牌阶段限一次,你可以表演《小空飞天》。若如此做,你从以下项目中随机选择X项,并执行其中的一项:①令一名角色摸两张牌。②对一名角色造成1点伤害。③令一名已受伤的角色回复1点体力。④弃置一名角色区域内的两张牌。⑤移动场上的一张牌。若X=0,则你弃置两张牌。(X为你的得分)', - yukito_yaxiang:'鸦翔', - yukito_yaxiang_info:'限定技,当有角色进入濒死状态时,你可移去此武将牌,然后令该角色将体力值回复至3点,弃置判定区的所有牌并获得技能〖终愿〗。', - misuzu_zhongyuan:'终愿', - misuzu_zhongyuan_info:'限定技。当你的判定结果生效时,你可将判定结果改为任意花色和点数并结束此时机。', - asara_shelu:'摄录', - asara_shelu_info:'出牌阶段限一次,你可以弃置一张牌,然后展示一名其他角色的一张手牌并将其置于你的武将牌上,称为“影”。若你以此法弃置的牌和展示的牌:花色相同,则你摸两张牌。点数相同,则你回复1点体力。', - asara_yingwei:'影威', - asara_yingwei_info:'你可以如手牌般使用或打出“影”。锁定技,当你使用“影”时,强制触发对应的应变效果。', - kotomi_qinji:'琴击', - kotomi_qinji_info:'出牌阶段开始时,你可视为使用使用【万箭齐发】。你以此法使用【万箭齐发】造成的伤害视为失去体力。', - kotomi_chuanxiang:'传箱', - kotomi_chuanxiang2:'传箱', - kotomi_chuanxiang_info:'其他角色的出牌阶段限一次,其可以将装备区内的一张牌移动到另一名角色的装备区内,然后你摸一张牌。若你是目标角色,则你改为摸两张牌。', - mia_shihui:'时迴', - mia_shihui_info:'锁定技,摸牌阶段,你改为摸X+1张牌(X为你上回合弃置的牌数);结束阶段,你弃置一张牌并回复1点体力。', - mia_qianmeng:'潜梦', - mia_qianmeng_info:'使命技。①游戏开始时,你摸一张牌,然后将一张牌置于牌堆的正中央。②使命:当有角色获得“潜梦”牌时,其将此牌交给你。你将体力值回复至上限,失去〖时迴〗并获得〖风发〗。③失败:当你死亡时,你可令一名角色获得牌堆中所有与“潜梦”牌花色点数相同的牌。', - mia_fengfa:'风发', - mia_fengfa_info:'锁定技。摸牌阶段,你多摸X张牌(X为你上回合使用过的牌数)。', - kano_liezhen:'列阵', - kano_liezhen_info:'结束阶段,若你本回合内使用过牌且这些牌的类型:不均相同,你可视为使用【排兵布阵】或智囊;均相同,你获得仁库中的所有牌(没有则改为摸两张牌)。', - kano_paibingbuzhen:'排兵布阵', - kano_paibingbuzhen_info:'出牌阶段,对至多三名角色使用。目标角色摸一张牌,然后将一张牌置入仁库。若仁库中的牌类型或颜色均相同,则你摸一张牌。', - kano_poyu:'破羽', - kano_poyu_info:'当你成为【杀】或伤害性锦囊牌的目标后,若仁库中有牌,你可判定。然后你可从仁库中移去一张与此牌类型或花色相同的牌,令此牌对你无效。', - liyingxia_sanli:'三礼', - liyingxia_sanli_info:'锁定技。其他角色于其回合内前两次使用牌指定你为目标后,你摸一张牌;第三次使用牌指定你为目标后,你交给其一张牌。', - liyingxia_zhenjun:'振军', - liyingxia_zhenjun_info:'键势力技。结束阶段,你可以令至多X+1名角色各摸一张牌,且这些角色于自己的下个回合内第一次造成的伤害+1(X为你本回合内使用【杀】和伤害性锦囊牌的次数)。', - liyingxia_wumai:'武脉', - liyingxia_wumai_info:'蜀势力技。一轮游戏开始时,你可以选择获得其中一个未选择过的技能直到本轮结束:〖八阵〗/〖集智〗/〖观星〗/〖游龙〗。若均已选择过,则你可以摸X张牌(X为场上已受伤的角色数且至多为3)。', - erika_shisong:'识诵', - erika_shisong_info:'锁定技。①你的手牌上限+X(X为你的护甲数)。②当你于回合内使用第Y张牌时,若此牌与你上回合使用的第Y张牌类型相同,则你摸一张牌。', - erika_yousheng:'佑生', - erika_yousheng_info:'使命技。①限定技。一轮游戏开始时,你可以选择至多两名其他角色。你减2点体力上限并增加3点护甲。②当你〖佑生①〗选择的角色成为【杀】或伤害类锦囊牌的目标时,你可以弃置X张牌并将此目标转移给自己(X为你本轮内发动过〖佑生②〗的次数)。此牌结算结束后,你可令一名原目标角色获得此牌。③成功:当你失去最后的护甲后,若你已发动过〖佑生①〗,则你和所有〖佑生①〗选择的角色各摸三张牌。④失败:当一名〖佑生①〗选择的角色因【杀】或伤害类锦囊牌而受到伤害时,你失去所有护甲并弃置等量的牌。', - erika_yousheng_append:'Death is not the end of life, but the completion of life.', - satomi_luodao:'落刀', - satomi_luodao_info:'当你使用【杀】指定目标后,你可以展示目标角色的所有手牌。若其中:有【闪】,则你弃置其中的一张【闪】;没有【闪】,则你弃置一张牌。', - satomi_daohai:'稻海', - satomi_daohai_info:'结束阶段,若你本回合内弃置过牌,则你可以视为使用一张【五谷丰登】。然后你可以将你于此【五谷丰登】中得到的牌当做【乐不思蜀】使用。', - satomi_daohai_append:'五穀豊穣、刈り入れ時だね!', - tenzen_fenghuan:'封还', - tenzen_fenghuan_info:'其他角色使用的【杀】或伤害性锦囊牌结算结束后,若你是此牌的唯一目标,则你可以弃置任意张点数之和大于等于此牌点数两倍的牌,然后视为对其使用一张名称相同的牌。', - tenzen_retianquan:'天全', - tenzen_retianquan_info:'每回合限一次。当你使用【杀】指定目标后,你可失去1点体力或弃置一张牌,然后展示牌堆顶的三张牌(若你的体力值小于体力上限的50%,则改为展示五张牌)。这些牌中每有一张基本牌,响应此牌所需的【闪】的数量便+1。此牌结算结束后,若此牌造成过伤害,则你获得展示牌中的所有非基本牌。', - iriya_yinji:'殷极', - iriya_yinji_info:'锁定技。出牌阶段开始时,你将手牌摸至17张。你不能直接使用以此法得到的牌。', - iriya_haozhi:'豪掷', - iriya_haozhi_info:'出牌阶段,你可以按照斗地主牌型弃置至少两张牌,且其他角色可以依次对其进行一轮响应。最后一名进行响应的角色可以根据对应牌型执行对应效果。' - +'对子:其可以令至多两名角色各摸一张牌。' - +'三带:其可以弃置至多三名其他角色的各一张牌,然后摸一张牌。' - +'单顺:其可以弃置一名其他角色的一张牌。若其未以此法弃置过颜色相同的牌,则其可以重复此流程。然后其摸等量的牌。' - +'双顺:其可以获得一名其他角色的一张牌。若其未以此法获得过颜色相同的牌,则其可以重复此流程。然后其回复等量的体力。' - +'三顺/飞机:其可以令至多3名其他角色翻面,然后对其中一名角色造成1点火属性伤害。' - +'炸弹/四带二:其可以对一名角色造成2点雷属性伤害,然后目标角色翻面,弃置装备区的所有牌和四张手牌。', - visible_fuuko_xingdiao:'', - fuuko_xingdiao:'星雕', - fuuko_xingdiao_info:'锁定技。游戏开始时,你将手牌摸至8张,然后将所有手牌明置(称为“星”,不计入手牌上限)。每名其他角色限一次,其可以于出牌阶段选择获得你的一张“星”,然后你摸一张牌。', - fuuko_chuanyuan:'传愿', - fuuko_chuanyuan_info:'锁定技。当你失去一张“星”后,你回复1点体力,然后从牌堆中获得一张和“星”花色点数相同的牌(没有则改为摸一张牌,且使用此牌无距离和次数限制)。', + shizuku_sizhi: "思智", + shizuku_sizhi2: "思智", + shizuku_sizhi_info: + "出牌阶段限一次,你可以弃置任意张点数之和为13的牌,然后摸两倍数量的牌。以此法得到的牌中,黑色牌本回合无距离和次数限制,红色牌本回合不计入手牌上限。", + shizuku_biyi: "避忆", + shizuku_biyi_info: + "当你受到伤害后,你可以进行一次判定,然后若你弃置任意张点数之和与判定结果点数相同的牌,你回复1点体力。", + shizuku_sanhua: "散花", + shizuku_sanhua_info: "当你死亡时,你可令一名其他角色从牌堆中获得四张名称各不相同的基本牌。", + hiroto_huyu: "虎驭", + hiroto_huyu2: "虎驭", + hiroto_huyu_info: + "其他角色的出牌阶段结束时,若你没有技能〖纵略〗,则其可将两张手牌交给你。若如此做,你获得〖纵略〗。你的下回合结束时,你失去〖纵略〗并将本回合内得到的所有牌交给该角色。", + hiroto_zonglve: "纵略", + hiroto_zonglve_info: + "锁定技,你的手牌上限+3。出牌阶段限一次,你可以将一张手牌背面朝下放置,并展示一名其他角色的一张手牌。若这两张牌:颜色相同,你对其造成1点伤害并弃置其展示的牌。颜色不同,你获得该角色区域内的两张牌。", + hiroto_tuolao: "脱牢", + hiroto_tuolao_info: + "觉醒技,回合结束后,若此回合不是你的第一个回合且你本轮内未因〖虎驭〗失去过牌,则你摸三张牌,失去〖虎驭〗并获得〖纵略〗。", + sakuya_junbu: "均步", + sakuya_junbu_info: + "锁定技,若你已废除的装备栏数量:≥1,你使用牌无距离限制。≥2,你使用牌无次数限制。≥3,你使用牌时可以多指定一个目标。≥4,你使用的牌不可被响应。≥5,你使用牌造成伤害时失去1点体力,令此伤害+1。", + rumi_shuwu: "淑武", + rumi_shuwu2: "淑武", + rumi_shuwu_info: + "锁定技,你使用【杀】无距离和次数限制,你使用普通锦囊牌选择目标后,可增加一个目标。出牌阶段结束时,你令X=0,且每满足一项便令X+1:①你于本阶段内使用【杀】的次数不大于1。②你于本阶段内未使用锦囊牌造成过伤害。③你的体力值不大于3。你摸X张牌,且本回合手牌上限+X。", + chihaya_liewu: "烈武", + chihaya_liewu2: "烈武", + chihaya_liewu_info: + "锁定技,你使用【杀】无距离和次数限制,你使用普通锦囊牌选择目标后,可增加一个目标。当你首次废除最后一个装备栏后,你减4点体力上限并获得技能〖怀柔〗。", + chihaya_youfeng: "游凤", + chihaya_youfeng_info: + "转换技,阴,每轮限一次,你可以加1点体力上限,视为使用一张普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张基本牌。", + chihaya_huairou: "怀柔", + chihaya_huairou_info: "出牌阶段,你可以重铸装备牌。", + yukito_kongwu: "控物", + yukito_kongwu_info: + "出牌阶段限一次,你可以表演《小空飞天》。若如此做,你从以下项目中随机选择X项,并执行其中的一项:①令一名角色摸两张牌。②对一名角色造成1点伤害。③令一名已受伤的角色回复1点体力。④弃置一名角色区域内的两张牌。⑤移动场上的一张牌。若X=0,则你弃置两张牌。(X为你的得分)", + yukito_yaxiang: "鸦翔", + yukito_yaxiang_info: + "限定技,当有角色进入濒死状态时,你可移去此武将牌,然后令该角色将体力值回复至3点,弃置判定区的所有牌并获得技能〖终愿〗。", + misuzu_zhongyuan: "终愿", + misuzu_zhongyuan_info: + "限定技。当你的判定结果生效时,你可将判定结果改为任意花色和点数并结束此时机。", + asara_shelu: "摄录", + asara_shelu_info: + "出牌阶段限一次,你可以弃置一张牌,然后展示一名其他角色的一张手牌并将其置于你的武将牌上,称为“影”。若你以此法弃置的牌和展示的牌:花色相同,则你摸两张牌。点数相同,则你回复1点体力。", + asara_yingwei: "影威", + asara_yingwei_info: + "你可以如手牌般使用或打出“影”。锁定技,当你使用“影”时,强制触发对应的应变效果。", + kotomi_qinji: "琴击", + kotomi_qinji_info: + "出牌阶段开始时,你可视为使用使用【万箭齐发】。你以此法使用【万箭齐发】造成的伤害视为失去体力。", + kotomi_chuanxiang: "传箱", + kotomi_chuanxiang2: "传箱", + kotomi_chuanxiang_info: + "其他角色的出牌阶段限一次,其可以将装备区内的一张牌移动到另一名角色的装备区内,然后你摸一张牌。若你是目标角色,则你改为摸两张牌。", + mia_shihui: "时迴", + mia_shihui_info: + "锁定技,摸牌阶段,你改为摸X+1张牌(X为你上回合弃置的牌数);结束阶段,你弃置一张牌并回复1点体力。", + mia_qianmeng: "潜梦", + mia_qianmeng_info: + "使命技。①游戏开始时,你摸一张牌,然后将一张牌置于牌堆的正中央。②使命:当有角色获得“潜梦”牌时,其将此牌交给你。你将体力值回复至上限,失去〖时迴〗并获得〖风发〗。③失败:当你死亡时,你可令一名角色获得牌堆中所有与“潜梦”牌花色点数相同的牌。", + mia_fengfa: "风发", + mia_fengfa_info: "锁定技。摸牌阶段,你多摸X张牌(X为你上回合使用过的牌数)。", + kano_liezhen: "列阵", + kano_liezhen_info: + "结束阶段,若你本回合内使用过牌且这些牌的类型:不均相同,你可视为使用【排兵布阵】或智囊;均相同,你获得仁库中的所有牌(没有则改为摸两张牌)。", + kano_paibingbuzhen: "排兵布阵", + kano_paibingbuzhen_info: + "出牌阶段,对至多三名角色使用。目标角色摸一张牌,然后将一张牌置入仁库。若仁库中的牌类型或颜色均相同,则你摸一张牌。", + kano_poyu: "破羽", + kano_poyu_info: + "当你成为【杀】或伤害性锦囊牌的目标后,若仁库中有牌,你可判定。然后你可从仁库中移去一张与此牌类型或花色相同的牌,令此牌对你无效。", + liyingxia_sanli: "三礼", + liyingxia_sanli_info: + "锁定技。其他角色于其回合内前两次使用牌指定你为目标后,你摸一张牌;第三次使用牌指定你为目标后,你交给其一张牌。", + liyingxia_zhenjun: "振军", + liyingxia_zhenjun_info: + "键势力技。结束阶段,你可以令至多X+1名角色各摸一张牌,且这些角色于自己的下个回合内第一次造成的伤害+1(X为你本回合内使用【杀】和伤害性锦囊牌的次数)。", + liyingxia_wumai: "武脉", + liyingxia_wumai_info: + "蜀势力技。一轮游戏开始时,你可以选择获得其中一个未选择过的技能直到本轮结束:〖八阵〗/〖集智〗/〖观星〗/〖游龙〗。若均已选择过,则你可以摸X张牌(X为场上已受伤的角色数且至多为3)。", + erika_shisong: "识诵", + erika_shisong_info: + "锁定技。①你的手牌上限+X(X为你的护甲数)。②当你于回合内使用第Y张牌时,若此牌与你上回合使用的第Y张牌类型相同,则你摸一张牌。", + erika_yousheng: "佑生", + erika_yousheng_info: + "使命技。①限定技。一轮游戏开始时,你可以选择至多两名其他角色。你减2点体力上限并增加3点护甲。②当你〖佑生①〗选择的角色成为【杀】或伤害类锦囊牌的目标时,你可以弃置X张牌并将此目标转移给自己(X为你本轮内发动过〖佑生②〗的次数)。此牌结算结束后,你可令一名原目标角色获得此牌。③成功:当你失去最后的护甲后,若你已发动过〖佑生①〗,则你和所有〖佑生①〗选择的角色各摸三张牌。④失败:当一名〖佑生①〗选择的角色因【杀】或伤害类锦囊牌而受到伤害时,你失去所有护甲并弃置等量的牌。", + erika_yousheng_append: + 'Death is not the end of life, but the completion of life.', + satomi_luodao: "落刀", + satomi_luodao_info: + "当你使用【杀】指定目标后,你可以展示目标角色的所有手牌。若其中:有【闪】,则你弃置其中的一张【闪】;没有【闪】,则你弃置一张牌。", + satomi_daohai: "稻海", + satomi_daohai_info: + "结束阶段,若你本回合内弃置过牌,则你可以视为使用一张【五谷丰登】。然后你可以将你于此【五谷丰登】中得到的牌当做【乐不思蜀】使用。", + satomi_daohai_append: '五穀豊穣、刈り入れ時だね!', + tenzen_fenghuan: "封还", + tenzen_fenghuan_info: + "其他角色使用的【杀】或伤害性锦囊牌结算结束后,若你是此牌的唯一目标,则你可以弃置任意张点数之和大于等于此牌点数两倍的牌,然后视为对其使用一张名称相同的牌。", + tenzen_retianquan: "天全", + tenzen_retianquan_info: + "每回合限一次。当你使用【杀】指定目标后,你可失去1点体力或弃置一张牌,然后亮出牌堆顶的三张牌(若你的体力值小于体力上限的50%,则改为展示五张牌)。这些牌中每有一张基本牌,响应此牌所需的【闪】的数量便+1。此牌结算结束后,若此牌造成过伤害,则你获得展示牌中的所有非基本牌。", + iriya_yinji: "殷极", + iriya_yinji_info: "锁定技。出牌阶段开始时,你将手牌摸至17张。你不能直接使用以此法得到的牌。", + iriya_haozhi: "豪掷", + iriya_haozhi_info: + "出牌阶段,你可以按照斗地主牌型弃置至少两张牌,且其他角色可以依次对其进行一轮响应。最后一名进行响应的角色可以根据对应牌型执行对应效果。" + + "对子:其可以令至多两名角色各摸一张牌。" + + "三带:其可以弃置至多三名其他角色的各一张牌,然后摸一张牌。" + + "单顺:其可以弃置一名其他角色的一张牌。若其未以此法弃置过颜色相同的牌,则其可以重复此流程。然后其摸等量的牌。" + + "双顺:其可以获得一名其他角色的一张牌。若其未以此法获得过颜色相同的牌,则其可以重复此流程。然后其回复等量的体力。" + + "三顺/飞机:其可以令至多3名其他角色翻面,然后对其中一名角色造成1点火属性伤害。" + + "炸弹/四带二:其可以对一名角色造成2点雷属性伤害,然后目标角色翻面,弃置装备区的所有牌和四张手牌。", + visible_fuuko_xingdiao: '', + fuuko_xingdiao: "星雕", + fuuko_xingdiao_info: + "锁定技。游戏开始时,你将手牌摸至8张,然后将所有手牌明置(称为“星”,不计入手牌上限)。每名其他角色限一次,其可以于出牌阶段选择获得你的一张“星”,然后你摸一张牌。", + fuuko_chuanyuan: "传愿", + fuuko_chuanyuan_info: + "锁定技。当你失去一张“星”后,你回复1点体力,然后从牌堆中获得一张和“星”花色点数相同的牌(没有则改为摸一张牌,且使用此牌无距离和次数限制)。", - key_kud:'库特莉亚芙卡', - kud_qiaoshou:'巧手', - kud_qiaoshou_equip:'巧手', - kud_qiaoshou_end:'巧手', - kud_qiaoshou_backup:'巧手', - kud_qiaoshou_info:'出牌阶段/结束阶段,若你没有“巧”,则你可以将一张手牌作为“巧”置于武将牌上并摸一张牌,且视为装备了一张你选择的武器牌或进攻坐骑/防具牌或防御坐骑直到“巧”进入弃牌堆。出牌阶段结束时/准备阶段开始时,你将“巧”置入弃牌堆。', - kud_buhui:'不悔', - kud_buhui_info:'限定技,当你进入濒死状态时,你可以弃置“巧”和装备区内的所有牌(至少一张)并摸等量的牌,将体力回复至2点,获得技能〖重振〗。', - key_misuzu:'神尾观铃', - misuzu_hengzhou:'恒咒', - misuzu_hengzhou_info:'锁定技,准备阶段开始时,或当你受到1点伤害或回复1点体力后,你获得一个“诅咒”标记。你的手牌上限和摸牌阶段的额定摸牌数+X。结束阶段开始时,若X大于3,则你移去所有“诅咒”标记并失去1点体力。(X为“诅咒”标记数)', - misuzu_nongyin:'浓饮', - misuzu_nongyin_info:'当你需要使用【桃】时,你可将一张红色非锦囊牌当做【乐不思蜀】置入自己的判定区,然后视为使用一张【桃】。', - misuzu_zhongxing:'终幸', - misuzu_zhongxing_info:'每回合限一次,当你判定区的牌移动到其他区域后,你可令一名角色回复1点体力或摸两张牌。', - key_kamome:'久岛鸥', - kamome_yangfan:'扬帆', - kamome_yangfan_info:'锁定技,游戏开始时,你将一张【旅行箱】置入你的装备区。当你失去装备区内的一张牌后,你摸两张牌。', - kamome_huanmeng:'幻梦', - kamome_huanmeng_info:'准备阶段开始时,你可以观看牌堆顶的X+1张牌并可以按任意顺序置于牌堆顶或牌堆底。(X为你装备区内的牌数)', - kamome_jieban:'结伴', - kamome_jieban_info:'转换技。每回合限一次,当你受到或造成伤害后,阴:你可将两张牌交给一名其他角色,然后其交给你一张牌。阳:你可将一张牌交给一名其他角色,然后其交给你两张牌。', - kamome_suitcase:'旅行箱', - kamome_suitcase_info:'锁定技,你跳过你的判定阶段和弃牌阶段;当你即将翻面时,取消之。', - key_nao:'友利奈绪', - nao_duyin:'独隐', - nao_duyin2:'独隐', - nao_duyin_info:'一名其他角色的回合开始时,若你本局游戏内未对其发动过〖独隐〗,则你可以弃置一张牌或将武将牌翻面。若如此做,你不能成为其使用牌的目标,且对其使用牌没有距离限制且不计入使用次数直到你的下回合结束。', - nao_wanxin:'挽心', - nao_wanxin_info:'一名角色的回合结束时,你可以令一名本回合内受到过伤害的角色摸两张牌,然后你与其将武将牌重置。', - nao_shouqing:'守情', - nao_shouqing2:'守情', - nao_shouqing3:'守情', - nao_shouqing_info:'其他角色的出牌阶段内可以对你使用【桃】。若如此做,其摸一张牌且本局游戏内的手牌上限+1。', - key_yuuki:'冰室忧希', - yuuki_yicha:'异插', - yuuki_yicha_info:'出牌阶段开始时,你可依次进行两次判定并将判定牌依次置入两行三列方阵的两个随机位置中。然后你依次进行四次判定,每次可将当前判定牌置入空方格,且须与相邻方格的牌颜色均不同。若如此做,你令一名角色获得方阵内的所有牌。', - key_kyouko:'伊座并杏子', - kyouko_rongzhu:'容助', - kyouko_rongzhu_info:'其他角色不因此技能而得到你的牌后,你可摸一张牌,然后交给其一张牌。若其是当前回合角色,则其本回合使用【杀】的次数上限+1;若你是当前回合角色,则你本回合的手牌上限+1。', - kyouko_gongmian:'共勉', - kyouko_gongmian_use:'共勉', - kyouko_gongmian_exchange:'共勉', - kyouko_gongmian_info:'①出牌阶段,你可以选择一名未以此法选择过的角色,若其手牌:大于你,你获得其一张牌,然后交给其一张牌;小于你,其交给你一张牌,然后你交给其一张牌;等于你,你与其各摸一张牌。②出牌阶段结束时,你可以获得一名其他角色区域内的至多X张牌,然后交给其等量的牌。③弃牌阶段开始时,若X不小于你的体力值,你可以获得一名手牌数少于你的角色的所有手牌,然后将手牌数的一半(向上取整)交给该角色。(X为你本回合内发动过〖共勉①〗的次数)', - key_tenzen:'加纳天善', - tenzen_yixing:'弈兴', - tenzen_yixing_info:'当有角色因【杀】或【决斗】而受到伤害后,若其在你的攻击范围内或你在伤害来源的攻击范围内,你可以摸一张牌,然后将一张牌置于武将牌上,称为“兴”。当你成为其他角色使用【杀】或普通锦囊牌的唯一目标后,你可以获得一张“兴”,并可于此牌结算完成后弃置两张牌,视为对其使用一张名称相同的牌。', + key_kud: "库特莉亚芙卡", + kud_qiaoshou: "巧手", + kud_qiaoshou_equip: "巧手", + kud_qiaoshou_end: "巧手", + kud_qiaoshou_backup: "巧手", + kud_qiaoshou_info: + "出牌阶段/结束阶段,若你没有“巧”,则你可以将一张手牌作为“巧”置于武将牌上并摸一张牌,且视为装备了一张你选择的武器牌或进攻坐骑/防具牌或防御坐骑直到“巧”进入弃牌堆。出牌阶段结束时/准备阶段开始时,你将“巧”置入弃牌堆。", + kud_buhui: "不悔", + kud_buhui_info: + "限定技,当你进入濒死状态时,你可以弃置“巧”和装备区内的所有牌(至少一张)并摸等量的牌,将体力回复至2点,获得技能〖重振〗。", + key_misuzu: "神尾观铃", + misuzu_hengzhou: "恒咒", + misuzu_hengzhou_info: + "锁定技,准备阶段开始时,或当你受到1点伤害或回复1点体力后,你获得一个“诅咒”标记。你的手牌上限和摸牌阶段的额定摸牌数+X。结束阶段开始时,若X大于3,则你移去所有“诅咒”标记并失去1点体力。(X为“诅咒”标记数)", + misuzu_nongyin: "浓饮", + misuzu_nongyin_info: + "当你需要使用【桃】时,你可将一张红色非锦囊牌当做【乐不思蜀】置入自己的判定区,然后视为使用一张【桃】。", + misuzu_zhongxing: "终幸", + misuzu_zhongxing_info: + "每回合限一次,当你判定区的牌移动到其他区域后,你可令一名角色回复1点体力或摸两张牌。", + key_kamome: "久岛鸥", + kamome_yangfan: "扬帆", + kamome_yangfan_info: + "锁定技,游戏开始时,你将一张【旅行箱】置入你的装备区。当你失去装备区内的一张牌后,你摸两张牌。", + kamome_huanmeng: "幻梦", + kamome_huanmeng_info: + "准备阶段开始时,你可以观看牌堆顶的X+1张牌并可以按任意顺序置于牌堆顶或牌堆底。(X为你装备区内的牌数)", + kamome_jieban: "结伴", + kamome_jieban_info: + "转换技。每回合限一次,当你受到或造成伤害后,阴:你可将两张牌交给一名其他角色,然后其交给你一张牌。阳:你可将一张牌交给一名其他角色,然后其交给你两张牌。", + kamome_suitcase: "旅行箱", + kamome_suitcase_info: "锁定技,你跳过你的判定阶段和弃牌阶段;当你即将翻面时,取消之。", + key_nao: "友利奈绪", + nao_duyin: "独隐", + nao_duyin2: "独隐", + nao_duyin_info: + "一名其他角色的回合开始时,若你本局游戏内未对其发动过〖独隐〗,则你可以弃置一张牌或将武将牌翻面。若如此做,你不能成为其使用牌的目标,且对其使用牌没有距离限制且不计入使用次数直到你的下回合结束。", + nao_wanxin: "挽心", + nao_wanxin_info: + "一名角色的回合结束时,你可以令一名本回合内受到过伤害的角色摸两张牌,然后你与其将武将牌重置。", + nao_shouqing: "守情", + nao_shouqing2: "守情", + nao_shouqing3: "守情", + nao_shouqing_info: + "其他角色的出牌阶段内可以对你使用【桃】。若如此做,其摸一张牌且本局游戏内的手牌上限+1。", + key_yuuki: "冰室忧希", + yuuki_yicha: "异插", + yuuki_yicha_info: + "出牌阶段开始时,你可依次进行两次判定并将判定牌依次置入两行三列方阵的两个随机位置中。然后你依次进行四次判定,每次可将当前判定牌置入空方格,且须与相邻方格的牌颜色均不同。若如此做,你令一名角色获得方阵内的所有牌。", + key_kyouko: "伊座并杏子", + kyouko_rongzhu: "容助", + kyouko_rongzhu_info: + "其他角色不因此技能而得到你的牌后,你可摸一张牌,然后交给其一张牌。若其是当前回合角色,则其本回合使用【杀】的次数上限+1;若你是当前回合角色,则你本回合的手牌上限+1。", + kyouko_gongmian: "共勉", + kyouko_gongmian_use: "共勉", + kyouko_gongmian_exchange: "共勉", + kyouko_gongmian_info: + "①出牌阶段,你可以选择一名未以此法选择过的角色,若其手牌:大于你,你获得其一张牌,然后交给其一张牌;小于你,其交给你一张牌,然后你交给其一张牌;等于你,你与其各摸一张牌。②出牌阶段结束时,你可以获得一名其他角色区域内的至多X张牌,然后交给其等量的牌。③弃牌阶段开始时,若X不小于你的体力值,你可以获得一名手牌数少于你的角色的所有手牌,然后将手牌数的一半(向上取整)交给该角色。(X为你本回合内发动过〖共勉①〗的次数)", + key_tenzen: "加纳天善", + tenzen_yixing: "弈兴", + tenzen_yixing_info: + "当有角色因【杀】或【决斗】而受到伤害后,若其在你的攻击范围内或你在伤害来源的攻击范围内,你可以摸一张牌,然后将一张牌置于武将牌上,称为“兴”。当你成为其他角色使用【杀】或普通锦囊牌的唯一目标后,你可以获得一张“兴”,并可于此牌结算完成后弃置两张牌,视为对其使用一张名称相同的牌。", //若对方为水织静久则无法触发〖弈兴〗 - tenzen_lingyu:'领域', - tenzen_lingyu_info:'觉醒技,准备阶段,若你的“兴”不小于你的体力值,则你减1点体力上限并获得技能〖天全〗。若你以此法失去了体力,则你摸两张牌。', - tenzen_tianquan:'天全', - tenzen_tianquan_info:'每回合限一次,当你使用【杀】或【决斗】指定唯一目标后,你可以移去两张“兴”并展示牌堆顶的五张牌。这些牌中每有一张基本牌,响应此牌需要的【闪】/【杀】的数量便+1。此牌结算完成后,若此牌造成过伤害,则你获得这些牌中的非基本牌。', - key_kotarou:'天王寺瑚太朗', - kotarou_aurora:'丝刃', - kotarou_aurora_info:'锁定技,当扣减体力或增加体力上限后,若你的装备区内:有武器牌,你视为使用一张【杀】;没有武器牌,你使用牌堆中的一张不为赠物的武器牌。', - kotarou_rewrite:'改写', - kotarou_rewrite_damage:'改写', - kotarou_rewrite_recover:'改写', - kotarou_rewrite_sha:'改写', - kotarou_rewrite_block:'改写', - kotarou_rewrite_info:'出牌阶段,你可选择:①视为使用一张本局游戏没有以此法使用过的基本牌或普通锦囊牌;②移动场上的一张牌;③增加1点体力上限并失去1点体力(体力上限至多为5);④下一次造成的伤害+1;⑤下一次回复的体力值+1;⑥本回合内的手牌上限和使用【杀】的使用次数+1。若你于本回合内发动过〖改写〗的次数超过两次,则你令此技能失效,且于回合结束后将体力上限降至3点,失去〖丝刃〗和〖改写〗。', - key_kyou:'藤林杏', - kyou_zhidian:'掷典', - kyou_zhidian_info:'你可以将一张锦囊牌当做【杀】使用(无距离限制)。当你使用【杀】指定第一个目标后,你选择一个与上次不同的选项:①此【杀】不可被响应。②此【杀】无视防具。③此【杀】伤害+1。④此【杀】不计入次数限制。', - kyou_duanfa:'断发', - kyou_duanfa_info:'限定技,当你受到伤害时,若伤害值不小于你的体力值,则你可弃置所有手牌,防止此伤害并回复1点体力;且当你于你的下回合开始前成为【杀】或伤害性锦囊牌的目标后,你摸一张牌。', - key_seira:'樱庭星罗', - seira_xinghui:'星辉', - seira_xinghui_info:'准备阶段,你可以投掷一枚骰子,观看牌堆顶的X张牌(X为投掷点数)并以任意顺序扣置于一名没有“星屑”的角色的武将牌上,称为“星屑”。有“星屑”的角色造成的伤害+1,且当其从牌堆顶摸牌或取得判定牌时,改为从“星屑”中获取。', - seira_yuanying:'缘映', - seira_yuanying_info:'出牌阶段限一次,你可选择两名角色。这两名角色成为“姻缘者”且获得〖姻缘〗直到你下次发动〖缘映〗。', - seira_yinyuan:'姻缘', - seira_yinyuan_info:'你的手牌对其他“姻缘者”可见。出牌阶段限一次,你可以获得一名其他“姻缘者”区域内的一张牌,然后其回复1点体力。', - key_kiyu:'露娜Q', - kiyu_yuling:'玉灵', - kiyu_yuling_info:'锁定技。你不是有距离限制的锦囊牌的合法目标;你成为【杀】的目标后,使用者需弃置X张牌(X为其至你的距离)。', - kiyu_xianyu:'先预', - kiyu_xianyu_info:'每轮限一次。一名角色的出牌阶段开始时,你可观看其手牌并预测其使用这些牌的顺序。此出牌阶段结束时,你摸X张牌,且其本回合的手牌上限+X(X为你的预测与其实际使用顺序的吻合数且至多为3)。', - kiyu_rexianyu:'先预', - kiyu_rexianyu_info:'每轮限一次。出牌阶段结束时,你可以选择一名其他角色。该角色于下个出牌阶段内使用第X张牌时,其可以将一张牌当做你本阶段内使用的第X张基本牌或普通锦囊牌使用(X至多为3);若如此做,你摸一张牌,且其本回合的手牌上限+1。', - key_tomoyo:'坂上智代', - tomoyo_wuwei:'武威', - tomoyo_wuwei_info:'①每回合每种花色限一次。你可以将一张手牌当做【杀】使用或打出。②当有角色使用【闪】后,若你在其攻击范围内,你可以对其使用一张【杀】(无距离限制)。', - tomoyo_zhengfeng:'整风', - tomoyo_zhengfeng_info:'使命技。①准备阶段,你可以令攻击范围内的一名角色进行判定。若如此做,你获得如下效果直到下回合开始:你视为在该角色的攻击范围内,且当该角色使用与判定牌颜色相同的牌时,你摸一张牌。②失败:结束阶段,若你于本回合内未发动过〖整风①〗,则你可以减1点体力上限。你失去〖武威〗,摸两张牌并回复1点体力,然后获得〖长誓〗。', - tomoyo_changshi:'长誓', - tomoyo_changshi_info:'锁定技。一名攻击范围内包含你的角色回复体力后,你获得1点护甲;一名攻击范围内包含你的角色一次性获得至少两张牌后,你摸一张牌。', - key_minagi:'远野美凪', - minagi_peiquan:'配券', - minagi_peiquan_info:'锁定技。①游戏开始时,你将你所有的手牌记录为“米券”。②出牌阶段,你可以赠予一张“米券”,然后执行一项本回合内未被选择过的效果:⒈对其造成1点伤害;⒉摸两张牌;⒊弃置其的两张牌;⒋亮出牌堆顶的一张牌,然后你可以使用之。', - minagi_huanliu:'幻流', - minagi_huanliu_info:'准备阶段开始时,你可与一名其他角色进行协力,并获得“远野小满”的所有技能直到目标角色的结束阶段开始。若“协力”成功,则你可以将所有手牌记录为“米券”。', - key_michiru:'远野小满', - michiru_sheyuan:'舍愿', - michiru_sheyuan_info:'每轮限一次。若你没有“米券”,则你可以将所有手牌当做任意基本牌或普通锦囊牌使用,然后摸等量的牌。', - minagi_tag:'米券', + tenzen_lingyu: "领域", + tenzen_lingyu_info: + "觉醒技,准备阶段,若你的“兴”不小于你的体力值,则你减1点体力上限并获得技能〖天全〗。若你以此法失去了体力,则你摸两张牌。", + tenzen_tianquan: "天全", + tenzen_tianquan_info: + "每回合限一次,当你使用【杀】或【决斗】指定唯一目标后,你可以移去两张“兴”并亮出牌堆顶的五张牌。这些牌中每有一张基本牌,响应此牌需要的【闪】/【杀】的数量便+1。此牌结算完成后,若此牌造成过伤害,则你获得这些牌中的非基本牌。", + key_kotarou: "天王寺瑚太朗", + kotarou_aurora: "丝刃", + kotarou_aurora_info: + "锁定技,当扣减体力或增加体力上限后,若你的装备区内:有武器牌,你视为使用一张【杀】;没有武器牌,你使用牌堆中的一张不为赠物的武器牌。", + kotarou_rewrite: "改写", + kotarou_rewrite_damage: "改写", + kotarou_rewrite_recover: "改写", + kotarou_rewrite_sha: "改写", + kotarou_rewrite_block: "改写", + kotarou_rewrite_info: + "出牌阶段,你可选择:①视为使用一张本局游戏没有以此法使用过的基本牌或普通锦囊牌;②移动场上的一张牌;③增加1点体力上限并失去1点体力(体力上限至多为5);④下一次造成的伤害+1;⑤下一次回复的体力值+1;⑥本回合内的手牌上限和使用【杀】的使用次数+1。若你于本回合内发动过〖改写〗的次数超过两次,则你令此技能失效,且于回合结束后将体力上限降至3点,失去〖丝刃〗和〖改写〗。", + key_kyou: "藤林杏", + kyou_zhidian: "掷典", + kyou_zhidian_info: + "你可以将一张锦囊牌当做【杀】使用(无距离限制)。当你使用【杀】指定第一个目标后,你选择一个与上次不同的选项:①此【杀】不可被响应。②此【杀】无视防具。③此【杀】伤害+1。④此【杀】不计入次数限制。", + kyou_duanfa: "断发", + kyou_duanfa_info: + "限定技,当你受到伤害时,若伤害值不小于你的体力值,则你可弃置所有手牌,防止此伤害并回复1点体力;且当你于你的下回合开始前成为【杀】或伤害性锦囊牌的目标后,你摸一张牌。", + key_seira: "樱庭星罗", + seira_xinghui: "星辉", + seira_xinghui_info: + "准备阶段,你可以投掷一枚骰子,观看牌堆顶的X张牌(X为投掷点数)并以任意顺序扣置于一名没有“星屑”的角色的武将牌上,称为“星屑”。有“星屑”的角色造成的伤害+1,且当其从牌堆顶摸牌或取得判定牌时,改为从“星屑”中获取。", + seira_yuanying: "缘映", + seira_yuanying_info: + "出牌阶段限一次,你可选择两名角色。这两名角色成为“姻缘者”且获得〖姻缘〗直到你下次发动〖缘映〗。", + seira_yinyuan: "姻缘", + seira_yinyuan_info: + "你的手牌对其他“姻缘者”可见。出牌阶段限一次,你可以获得一名其他“姻缘者”区域内的一张牌,然后其回复1点体力。", + key_kiyu: "露娜Q", + kiyu_yuling: "玉灵", + kiyu_yuling_info: + "锁定技。你不是有距离限制的锦囊牌的合法目标;你成为【杀】的目标后,使用者需弃置X张牌(X为其至你的距离)。", + kiyu_xianyu: "先预", + kiyu_xianyu_info: + "每轮限一次。一名角色的出牌阶段开始时,你可观看其手牌并预测其使用这些牌的顺序。此出牌阶段结束时,你摸X张牌,且其本回合的手牌上限+X(X为你的预测与其实际使用顺序的吻合数且至多为3)。", + kiyu_rexianyu: "先预", + kiyu_rexianyu_info: + "每轮限一次。出牌阶段结束时,你可以选择一名其他角色。该角色于下个出牌阶段内使用第X张牌时,其可以将一张牌当做你本阶段内使用的第X张基本牌或普通锦囊牌使用(X至多为3);若如此做,你摸一张牌,且其本回合的手牌上限+1。", + key_tomoyo: "坂上智代", + tomoyo_wuwei: "武威", + tomoyo_wuwei_info: + "①每回合每种花色限一次。你可以将一张手牌当做【杀】使用或打出。②当有角色使用【闪】后,若你在其攻击范围内,你可以对其使用一张【杀】(无距离限制)。", + tomoyo_zhengfeng: "整风", + tomoyo_zhengfeng_info: + "使命技。①准备阶段,你可以令攻击范围内的一名角色进行判定。若如此做,你获得如下效果直到下回合开始:你视为在该角色的攻击范围内,且当该角色使用与判定牌颜色相同的牌时,你摸一张牌。②失败:结束阶段,若你于本回合内未发动过〖整风①〗,则你可以减1点体力上限。你失去〖武威〗,摸两张牌并回复1点体力,然后获得〖长誓〗。", + tomoyo_changshi: "长誓", + tomoyo_changshi_info: + "锁定技。一名攻击范围内包含你的角色回复体力后,你获得1点护甲;一名攻击范围内包含你的角色一次性获得至少两张牌后,你摸一张牌。", + key_minagi: "远野美凪", + minagi_peiquan: "配券", + minagi_peiquan_info: + "锁定技。①游戏开始时,你将你所有的手牌记录为“米券”。②出牌阶段,你可以赠予一张“米券”,然后执行一项本回合内未被选择过的效果:⒈对其造成1点伤害;⒉摸两张牌;⒊弃置其的两张牌;⒋亮出牌堆顶的一张牌,然后你可以使用之。", + minagi_huanliu: "幻流", + minagi_huanliu_info: + "准备阶段开始时,你可与一名其他角色进行协力,并获得“远野小满”的所有技能直到目标角色的结束阶段开始。若“协力”成功,则你可以将所有手牌记录为“米券”。", + key_michiru: "远野小满", + michiru_sheyuan: "舍愿", + michiru_sheyuan_info: + "每轮限一次。若你没有“米券”,则你可以将所有手牌当做任意基本牌或普通锦囊牌使用,然后摸等量的牌。", + minagi_tag: "米券", - noname:"小无", - noname_zhuyuan:"祝愿", - noname_zhuyuan_info:"①每回合每名角色限一次。出牌阶段,你可以将四张花色各不相同的牌交给一名其他角色。你与其获得技能〖铁骑〗和〖激昂〗至各自的回合结束。②锁定技,若你于当前回合内:未发动过〖祝愿〗,则你使用牌无次数限制;发动过〖祝愿〗,则你使用牌无距离限制。", - noname_duocai:"多彩", - noname_duocai_info:"每回合限一次。其他角色区域内的牌因弃置而进入弃牌堆后,你可以获得之。若你以此法得到的牌数:大于2,你弃置一名角色区域内的一张牌;等于2,你摸一张牌;小于2,你回复1点体力。", - ns_huangchengyan:'黄承彦', - nslongyue:'龙岳', - nslongyue_info:'当一名角色使用锦囊牌时,若此牌是其本回合内使用的第一张牌,则你可令其摸一张牌。', - nszhenyin:'阵引', - nszhenyin_info:'每回合限一次。一名角色的判定牌生效前,你可令当前回合角色打出一张手牌代替之。', - ns_sunchensunjun:'孙綝孙峻', - nsxianhai:'险害', - nsxianhai_info:'每轮限一次,当一名其他角色于回合内造成伤害后,若其此回合内造成过的伤害总和大于你上一回合内造成的伤害总和,则你可以减1点体力上限,令其废除一种装备栏并弃置手牌中所有的【闪】。若〖兴黜〗已发动,此回合结束后视为该限定技未发动过。', - nsxingchu:'兴黜', - nsxingchu_info:'限定技,当你杀死一名角色/你死亡时,你可以令一名角色获得其/你的所有牌并增加1点体力上限。', - ns_yuanxi:'袁熙', - nsshengyan:'盛筵', - nsshengyan3:'盛筵', - nsshengyan_info:'锁定技,你的判定牌生效后,若结果花色与你本回合内其他判定结果的花色均不同,则你令当前回合角色本回合的手牌上限+2。', - nsdaizhan:'怠战', - nsdaizhany:'怠战', - nsdaizhan_info:'准备阶段,你可以将一张非锦囊牌当做【兵粮寸断】或【乐不思蜀】对自己使用。若如此做,回合结束时,你将手牌摸至手牌上限。', - ns_caoshuang:'曹爽', - nsjiquan:'集权', - nsjiquan_mark:'集权', - nsjiquan_info:'与你距离1以内的其他角色造成或受到伤害后,你可以将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。', - nsfuwei:'附位', - nsfuwei_info:'觉醒技,结束阶段开始时,若“威”数大于4,则你加2点体力上限,获得〖喋谋〗和〖制皇〗,并将〖集权〗改为锁定技。', - nsdiemou:'喋谋', - nsdiemou_info:'锁定技,出牌阶段开始时,若“威”大于全场角色数,你移去所有“威”,减1点体力上限并摸X张牌。若X大于4,你翻面。(X为移去的“威”数)', - nszhihuang:'制皇', - nszhihuang_damage:'制皇', - nszhihuang_info:'每回合限一次,当主公使用牌时,你可以移去一张“威”,然后获得此牌。锁定技,若你的手牌数大于主公,则你使用牌造成的伤害+1。', - ns_chentai:'陈泰', - nsweiyuan:'围援', - nsweiyuan_use:'围援', - nsweiyuan_use_backup:'围援', - nsweiyuan_info:'出牌阶段限一次,当你使用牌指定其他角色A为唯一目标后,你可以令一名除该角色外的其他角色B选择一项:①交给A一张牌:然后你对B造成1点伤害;②你摸一张牌,且可以将一张手牌当做本回合使用过的一张基本牌/普通锦囊牌使用(无次数距离限制)。', - nsjuxian:'据险', - nsjuxian2:'据险', - nsjuxian_info:'当你受到伤害时,你可以摸两张并跳过下一个摸牌阶段,且在此之前不能再次发动〖据险〗。然后若你的手牌数不小于体力上限,则伤害来源弃置一张牌。', - ns_huangwudie:'黄舞蝶', - nsdiewu:'蝶舞', - nsdiewu_info:'当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】或【闪】。当你以此法使用【杀】造成伤害后,则你摸一张牌。', - nslingying:'灵影', - nslingying_info:'锁定技,你使用【杀】无距离限制,且你使用【杀】的次数上限+1。', - nspojian:'破茧', - nspojian_info:'觉醒技,准备阶段,若你的"蝶舞"标记的数量不小于你的体力值,则你减1点体力上限并摸两张牌,删除〖蝶舞〗中使用【闪】的部分并获得技能〖烈弓〗。', - ns_sunyi:'孙翊', - nsguolie:'果烈', - nsguolie2:'果烈', - nsguolie_info:'摸牌阶段开始前,你可跳过此阶段。若如此做,你的红色牌均视为【杀】,黑色牌均视为【过河拆桥】且均无视距离与次数直到回合结束,且结束阶段,你获得本回合从你以外的区域内进入弃牌堆的所有牌。', - ns_zhangning:'张宁', - nsfuzhou:'符咒', - nsfuzhou_card:'符咒', - nsfuzhou_card_info:'此牌不可被【无懈可击】响应。若判定结果为:黑色,你受到使用者造成的1点雷属性伤害且弃置一张牌;红色,使用者摸两张牌,且你本回合的手牌上限-1。', - nsfuzhou_num:'符咒', - nsfuzhou_info:'出牌阶段限一次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,且该角色本回合手牌上限减1。', - nsguidao:'鬼道', - nsguidao_info:'一名角色的判定牌生效前,你可以打出一张黑色牌替换之。', - nstaiping:'太平', - nstaiping_info:'觉醒技。准备阶段,若你:已因〖符咒〗造成了两次或更多的伤害,则你将〖鬼道〗中的“黑色牌”修改为“牌”,将〖符咒〗修改为〖符咒·邪〗;若你已因〖符咒〗摸了两次或更多的牌,则你将〖鬼道〗中的“黑色牌”修改为“牌”,将〖符咒〗修改为〖符咒·正〗。', - nsfuzhou_damage:'符咒·邪', - nsfuzhou_damage_info:'出牌阶段限两次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,且该角色本回合手牌上限-1。', - nsfuzhou_draw:'符咒·正', - nsfuzhou_draw_info:'出牌阶段限两次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,该角色回复1点体力并摸一张牌,且本回合的手牌上限+1。', - ns_yanghu:'羊祜', - nsbizhao:'避召', - nsbizhao2:'避召', - nsbizhao_info:'隐匿技,锁定技,当你于回合外明置此武将牌后,其他角色计算与你的距离+1直至你的回合开始。', - nsqingde:'清德', - nsqingde_info:'每回合限一次,当你使用【杀】或普通锦囊牌对其他角色造成伤害后,你可使用该牌与受到伤害的角色拼点。你可令输的角色摸两张牌;当你受到其他角色使用【杀】或普通锦囊牌造成的伤害后,可使用该牌与伤害来源拼点。你可令赢的角色回复1点体力。', - nsyidi:'遗敌', - nsyidi_info:'出牌阶段限一次,你可展示一张手牌,然后将其交给一名其他角色。若为基本牌,该角色可使用此牌;若不为基本牌,你摸一张牌。', + noname: "小无", + noname_zhuyuan: "祝愿", + noname_zhuyuan_info: + "①每回合每名角色限一次。出牌阶段,你可以将四张花色各不相同的牌交给一名其他角色。你与其获得技能〖铁骑〗和〖激昂〗至各自的回合结束。②锁定技,若你于当前回合内:未发动过〖祝愿〗,则你使用牌无次数限制;发动过〖祝愿〗,则你使用牌无距离限制。", + noname_duocai: "多彩", + noname_duocai_info: + "每回合限一次。其他角色区域内的牌因弃置而进入弃牌堆后,你可以获得之。若你以此法得到的牌数:大于2,你弃置一名角色区域内的一张牌;等于2,你摸一张牌;小于2,你回复1点体力。", + ns_huangchengyan: "黄承彦", + nslongyue: "龙岳", + nslongyue_info: "当一名角色使用锦囊牌时,若此牌是其本回合内使用的第一张牌,则你可令其摸一张牌。", + nszhenyin: "阵引", + nszhenyin_info: "每回合限一次。一名角色的判定牌生效前,你可令当前回合角色打出一张手牌代替之。", + ns_sunchensunjun: "孙綝孙峻", + nsxianhai: "险害", + nsxianhai_info: + "每轮限一次,当一名其他角色于回合内造成伤害后,若其此回合内造成过的伤害总和大于你上一回合内造成的伤害总和,则你可以减1点体力上限,令其废除一种装备栏并弃置手牌中所有的【闪】。若〖兴黜〗已发动,此回合结束后视为该限定技未发动过。", + nsxingchu: "兴黜", + nsxingchu_info: + "限定技,当你杀死一名角色/你死亡时,你可以令一名角色获得其/你的所有牌并增加1点体力上限。", + ns_yuanxi: "袁熙", + nsshengyan: "盛筵", + nsshengyan3: "盛筵", + nsshengyan_info: + "锁定技,你的判定牌生效后,若结果花色与你本回合内其他判定结果的花色均不同,则你令当前回合角色本回合的手牌上限+2。", + nsdaizhan: "怠战", + nsdaizhany: "怠战", + nsdaizhan_info: + "准备阶段,你可以将一张非锦囊牌当做【兵粮寸断】或【乐不思蜀】对自己使用。若如此做,回合结束时,你将手牌摸至手牌上限。", + ns_caoshuang: "曹爽", + nsjiquan: "集权", + nsjiquan_mark: "集权", + nsjiquan_info: + "与你距离1以内的其他角色造成或受到伤害后,你可以将其区域内的一张牌置于你的武将牌上(称为“威”)。你使用【杀】的次数上限+X(X为“威”数)。", + nsfuwei: "附位", + nsfuwei_info: + "觉醒技,结束阶段开始时,若“威”数大于4,则你加2点体力上限,获得〖喋谋〗和〖制皇〗,并将〖集权〗改为锁定技。", + nsdiemou: "喋谋", + nsdiemou_info: + "锁定技,出牌阶段开始时,若“威”大于全场角色数,你移去所有“威”,减1点体力上限并摸X张牌。若X大于4,你翻面。(X为移去的“威”数)", + nszhihuang: "制皇", + nszhihuang_damage: "制皇", + nszhihuang_info: + "每回合限一次,当主公使用牌时,你可以移去一张“威”,然后获得此牌。锁定技,若你的手牌数大于主公,则你使用牌造成的伤害+1。", + ns_chentai: "陈泰", + nsweiyuan: "围援", + nsweiyuan_use: "围援", + nsweiyuan_use_backup: "围援", + nsweiyuan_info: + "出牌阶段限一次,当你使用牌指定其他角色A为唯一目标后,你可以令一名除该角色外的其他角色B选择一项:①交给A一张牌:然后你对B造成1点伤害;②你摸一张牌,且可以将一张手牌当做本回合使用过的一张基本牌/普通锦囊牌使用(无次数距离限制)。", + nsjuxian: "据险", + nsjuxian2: "据险", + nsjuxian_info: + "当你受到伤害时,你可以摸两张并跳过下一个摸牌阶段,且在此之前不能再次发动〖据险〗。然后若你的手牌数不小于体力上限,则伤害来源弃置一张牌。", + ns_huangwudie: "黄舞蝶", + nsdiewu: "蝶舞", + nsdiewu_info: + "当你获得两张或更多的牌后/受到伤害后,你获得一个“蝶舞”标记;你可移去一枚“蝶舞”标记,然后视为使用一张【杀】或【闪】。当你以此法使用【杀】造成伤害后,则你摸一张牌。", + nslingying: "灵影", + nslingying_info: "锁定技,你使用【杀】无距离限制,且你使用【杀】的次数上限+1。", + nspojian: "破茧", + nspojian_info: + '觉醒技,准备阶段,若你的"蝶舞"标记的数量不小于你的体力值,则你减1点体力上限并摸两张牌,删除〖蝶舞〗中使用【闪】的部分并获得技能〖烈弓〗。', + ns_sunyi: "孙翊", + nsguolie: "果烈", + nsguolie2: "果烈", + nsguolie_info: + "摸牌阶段开始前,你可跳过此阶段。若如此做,你的红色牌均视为【杀】,黑色牌均视为【过河拆桥】且均无视距离与次数直到回合结束,且结束阶段,你获得本回合从你以外的区域内进入弃牌堆的所有牌。", + ns_zhangning: "张宁", + nsfuzhou: "符咒", + nsfuzhou_card: "符咒", + nsfuzhou_card_info: + "此牌不可被【无懈可击】响应。若判定结果为:黑色,你受到使用者造成的1点雷属性伤害且弃置一张牌;红色,使用者摸两张牌,且你本回合的手牌上限-1。", + nsfuzhou_num: "符咒", + nsfuzhou_info: + "出牌阶段限一次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,且该角色本回合手牌上限减1。", + nsguidao: "鬼道", + nsguidao_info: "一名角色的判定牌生效前,你可以打出一张黑色牌替换之。", + nstaiping: "太平", + nstaiping_info: + "觉醒技。准备阶段,若你:已因〖符咒〗造成了两次或更多的伤害,则你将〖鬼道〗中的“黑色牌”修改为“牌”,将〖符咒〗修改为〖符咒·邪〗;若你已因〖符咒〗摸了两次或更多的牌,则你将〖鬼道〗中的“黑色牌”修改为“牌”,将〖符咒〗修改为〖符咒·正〗。", + nsfuzhou_damage: "符咒·邪", + nsfuzhou_damage_info: + "出牌阶段限两次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,且该角色本回合手牌上限-1。", + nsfuzhou_draw: "符咒·正", + nsfuzhou_draw_info: + "出牌阶段限两次。你可以将一张黑色牌置于一名角色的判定区内,称为“符”。其于判定阶段进行“符”判定,若判定结果为:黑色,其受到1点雷属性伤害并弃置一张牌;红色,你摸两张牌,该角色回复1点体力并摸一张牌,且本回合的手牌上限+1。", + ns_yanghu: "羊祜", + nsbizhao: "避召", + nsbizhao2: "避召", + nsbizhao_info: + "隐匿技,锁定技,当你于回合外明置此武将牌后,其他角色计算与你的距离+1直至你的回合开始。", + nsqingde: "清德", + nsqingde_info: + "每回合限一次,当你使用【杀】或普通锦囊牌对其他角色造成伤害后,你可使用该牌与受到伤害的角色拼点。你可令输的角色摸两张牌;当你受到其他角色使用【杀】或普通锦囊牌造成的伤害后,可使用该牌与伤害来源拼点。你可令赢的角色回复1点体力。", + nsyidi: "遗敌", + nsyidi_info: + "出牌阶段限一次,你可展示一张手牌,然后将其交给一名其他角色。若为基本牌,该角色可使用此牌;若不为基本牌,你摸一张牌。", - diy_wenyang:'文鸯', - ns_zhangwei:'张葳', - nshuaishuang:'怀霜', - nshuaishuang_info:'锁定技,结束阶段,你从牌堆/弃牌堆获得一张【桃】,然后失去1点体力。', - nsfengli:'奉礼', - nsfengli2:'奉礼', - nsfengli_draw:'奉礼', - nsfengli_clear:'奉礼', - nsfengli_use:'奉礼', - visible_nsfengli:'奉礼', - nsfengli_info:'回合结束时,你可以选择一名其他角色并展示所有手牌直到你的下回合开始。当该角色于回合外需要使用或打出牌时,其可暗置你的一张明置手牌,然后视为使用或打出之。当你的明置手牌减少时,你可令一名手牌数小于你的角色摸一张牌。', - nsqiyue:'骑钺', - nsqiyue_info:'锁定技,当有角色的武将牌状态改变后,你摸一张牌。', - nsxuezhu:'血逐', - nsxuezhu_info:'当你受到伤害或造成伤害后,你可以令受到伤害的角色摸两张牌并翻面。', - ns_chuanshu:'传术', - ns_chuanshu_info:'限定技 当一名其他角色进入濒死状态时,你可以令其选择获得技能〖雷击〗或〖鬼道〗,其回复体力至1并摸两张牌。当该被【传术】的角色造成或受到一次伤害后,你摸一张牌。其阵亡后,你重置技能〖传术〗。', - ns_xiandao1:'仙道', - ns_xiandao1_info:'锁定技 游戏开始和回合结束阶段,你随机获得技能〖雷击〗或〖鬼道〗,直到下个出牌阶段开始。', - ns_xiandao2:'仙道', - ns_xiandao2_info:'锁定技 你防止受到任何属性伤害。', - ns_xiandao:'仙道', - ns_xiandao_info:'锁定技 游戏开始、你进入游戏时和回合结束阶段,你随机获得技能〖雷击〗或〖鬼道〗,直到下个出牌阶段阶段开始。你防止受到任何属性伤害。', - ns_chuanshu2:'术', - ns_chuanshu2_info:'锁定技 当你造成或受到一次伤害后,南华老仙摸一张牌。', - ns_chuanshu3:'术', - ns_chuanshu3_info:'锁定技 当你【传术】的角色阵亡后,你重置技能〖传术〗。', - ns_xiuzheng:'修真', - ns_xiuzheng_info:'出牌阶段限一次,你可选择一名其他角色,然后展示牌堆顶的两张牌,若同为红色,则其受到1点火焰伤害;若同为黑色,其受到1点雷电伤害;若颜色不相同,你弃置其一张牌。然后你获得这两张展示的牌后再弃置两张牌。', - nsanruo:'暗弱', - nsanruo_info:'锁定技,你手牌中的【杀】和普通锦囊牌(借刀杀人等带有指向目标的锦囊除外)均对你不可见。但你可以正常使用之。', - nsxunshan:'循善', - nsxunshan_info:'锁定技,你使用【暗弱】牌可以为其指定任意名合法目标(托管无效)。', - nskaicheng:'开城', - nskaicheng_info:'主公技,你的回合内,你可以将一张【暗弱】牌交给一名群势力其他角色观看,其可以选择是否告诉你此牌的名字。然后你选择一项:使用这张牌并摸一张牌;或结束此回合。', - nsjuanli:'狷戾', - nsjuanli_info:'出牌阶段限一次,你可以和一名有手牌的其他角色进行赌牌,若你赢,目标角色失去1点体力且该角色与你距离-1直到与你下次赌牌,若你没赢,目标角色回复1点体力,且该角色与你距离+1直到与你的下次赌牌。(赌牌:赌牌的两名角色分别亮开一张手牌,若花色相同则赌牌平局,若花色不同,则依次展示牌堆顶的牌直到翻开的牌与其中一人亮出牌的花色相同,则该角色获得赌牌的胜利)', - nsyuanchou:'远筹', - nsyuanchou_info:'锁定技,当你成为锦囊牌的目标时,若来源角色与你的距离大于1,则取消之。', - nsguhuo:'蛊惑', - nsguhuo_info:'锁定技,你在一个回合中使用前两张牌时,你对一名随机角色从牌堆(牌堆无则从弃牌堆)随机使用一张同类别卡牌。', - nsqinxue:'勤学', - nsqinxue_info:'每个效果每回合只能使用一次。①当你使用一张基本牌时,你从牌堆随机获得一张锦囊牌;②当你使用一张锦囊牌时,你从牌堆随机获得一张装备牌;③当你使用一张装备牌时,你从牌堆随机获得一张基本牌。', - nsbaiyi:'白衣', - nsbaiyi_info:'锁定技,若你本回合发动过勤学,你跳过弃牌阶段,改为弃置X张牌(X为本回合发动勤学次数);若你弃置了3张类别不同的牌,你获得一个额外回合(不可连续获得回合),否则你观看牌堆顶的X张牌并获得其中一张。', - nsbaiming:'百鸣', - nsbaiming_info:'当你使用【杀】时,你可以获得一项未获得过且与杀或伤害相关的技能,此【杀】结算完毕后,你失去以此法获得的技能。', - nsfuge:'覆戈', - nsfuge_info:'你的回合结束后,你可以执行一个额外的回合,此回合的摸牌阶段,你于摸牌阶段额外摸X张牌(X为你已损失的体力值);若如此做,直到洗牌前,你不能再发动此技能。', - nstanbing:'谈兵', - nstanbing_info:'摸牌阶段开始时,你可弃置一张手牌,然后摸X张牌(X为你弃置牌的名称字数),若如此做,本回合你不可使用或打出【杀】。', - nsxinzhan:'心战', - nsxinzhan_info:'出牌阶段限一次,你可将任意张手牌交给一名其他角色,若如此做,该角色失去X点体力(X为你交给其的牌张数的一半,向下取整),若你给的牌达到六张,则改为该角色失去1点体力上限。', - nsfuhuo:'符火', - nsfuhuo2:'符火', - nsfuhuo_info:'出牌阶段限一次,你可将一张手牌置于一名武将牌上没有“符”的角色的武将牌上,称为“符”,若如此做,其回合外使用或打出【闪】时,你可令其判定,若结果为:红桃,你对其造成2点火焰伤害;方块,你弃置其一张手牌,然后对其造成1点火焰伤害。你的下个回合开始时,你获得其武将牌上的“符”。', - nswangfeng:'望风', - nswangfeng_info:'在判定牌生效前,你可以打出一张红色牌替换之。', - nshunji:'混击', - nshunji_info:'出牌阶段限一次,你可以摸一张牌,视为使用一张【万箭齐发】。此【万箭齐发】造成伤害时,受伤害角色选择一项:①弃置你一张牌;②摸一张牌。', - nscuanquan:'篡权', - nscuanquan_info:'锁定技,如果你的身份为忠臣,则在受伤三次后与主公,互换身份和体力上限。', - nsjianning:'奸佞', - nsjianning_info:'出牌阶段限一次,如果你的身份为内奸,你可以与一名手牌数比你少的角色交换手牌,并对其造成1点伤害。', - nschangshi:'常仕', - nschangshi_info:'出牌阶段限一次,如果你的身份为反贼,你可以指定两名其他角色互换体力;如果两名角色体力之差等于1,你失去1点体力。', - nsbaquan:'霸权', - nsbaquan_info:'回合结束时,你可以弃置所有手牌,并获得相应点数的护甲,你的新一回合开始时清除所有护甲。', - nsbugua:'卜卦', - nsbugua_use_info:'弃置一张牌,并将牌堆顶的六张牌反面朝上逐张按先后顺序排放,然后抛骰子,展示牌序号与骰子显示的点数一致的牌,然后你根据这张牌的花色、点数随机获得牌堆中相应的一张牌。', - nsbugua_info:'出牌阶段限一次,你可以弃置一张牌,并将牌堆顶的六张牌反面朝上逐张按先后顺序排放,然后抛骰子,展示牌序号与骰子显示的点数一致的牌,然后你根据这张牌的花色、点数按以下规则随机获得牌堆中相应的一张牌:乾(红桃偶数):无中生有;坤(黑桃奇数):决斗;震(黑桃偶数):南蛮入侵;巽(红桃奇数):万箭齐发;坎(梅花偶数):过河拆桥、兑(梅花奇数):借刀杀人、艮(方片偶数):顺手牵羊、离(方片奇数):火攻。若牌堆中无此牌则摸一张牌,然后你观看未展示的另外五张牌并按任意顺序将其置于牌堆顶。', - nstuiyan:'推演', - nstuiyan_info:'出牌阶段,若你使用的牌点数比上一张使用的牌点数大,你可以摸一张牌,反之你本回合不能再以此法摸牌;当你使用的牌点数首次达到8的倍数时,你可以在结算后立即发动一次【卜卦】。', - nstianji:'天机', - nstianji_info:'限定技,当一名其他角色进入濒死状态,你可自减1点体力上限,令其回复体力至1并增加1点体力上限。', - nszhaoxin:'昭心', - nszhaoxin_info:'锁定技,你始终展示手牌。', - nsxiuxin:'修穆', - nsxiuxin_info:'锁定技,若你没有某种花色的手牌,你不能成为这种花色的牌的目标。', - nsshijun:'弑君', - nsshijun_info:'锁定技,你造成伤害时,你令此伤害+1,并在结算后失去1点体力。', - nshunyou:'魂佑', - nshunyou_info:'出阶段限一次,你可以弃置一张基本牌,获得弃牌堆底的一张装备牌和一张锦囊牌,然后你可以将那张装备牌装备给一名角色(允许替换)。如果弃牌堆没有装备以及锦囊牌,则改为摸X张牌,X为损失的体力加一(最多3张)。', - nswulie:'武烈', - nswulie_info:'限定技,准备阶段,你可以失去1点体力上限,从弃牌堆选择最多三张牌以任意顺序放置于牌堆顶。若如此做,此回合的结束阶段,你可以重复此操作。', - nscangxi:'藏玺', - nscangxi2:'藏玺', - nscangxi_info:'主公技,其他吴势力角色的弃牌阶段结束时,若其弃置了至少两张牌,则可以选择判定,若是黑色,则其选择一项,1,令主公摸一张并且展示;2,主公手牌上限永久加一;3,额外弃置一张牌,令主公获得本回合进入弃牌堆的一张牌。', - nsdongcha:'洞察', - nsdongcha_info:'锁定技,单体锦囊牌无法对你造成伤害。其它角色于其回合内第二次使用锦囊牌指定你为目标时,取消之。', - nscaijian:'才鉴', - nscaijian_info:'出牌阶段限一次,若你的手牌数不大于你的体力上限,则你可以展示你的手牌,观看牌堆顶相同数量的牌并以任意方式交换之。', - nsgongjian:'恭俭', - nsgongjian_info:'锁定技,弃牌阶段,你须将弃牌交给一名体力值大于你的其它角色。', - nsjianxiong:'奸雄', - nsjianxiong_info:'当你成为一名角色牌的目标后你可以对该角色使用一张牌,若此牌对其造成伤害,则该角色的牌失效。若失效的为黑色牌,则你摸一张牌。', - nsxionglue:'雄略', - nsxionglue_info:'出牌阶段限一次,你可以弃置一张黑色手牌,然后发现一张锦囊牌。', - nsyaowang:'妖妄', - nsyaowang_info:'回合开始阶段你可以选择一名角色然后获得其其中一项技能直到回合结束,然后该角色随机获得一项未上场武将的其中一项技能直到其回合结束。', - nshuanhuo:'幻惑', - nshuanhuo_info:'每当你失去1点体力或受到一次大于2的伤害时,你可以交换除你之外的两名角色的武将牌(体力及体力上限不变)。', - nsjianshu:'剑术', - nsjianshu_info:'锁定技:每当你的装备区有武器时,你使用【杀】指定一个目标后,该角色需要依次使用两张【闪】才能抵消此【杀】。', - nscangjian:'藏剑', - nscangjian_info:'每当你对一名角色造成伤害,你可以获得其装备区一张牌。', - nsyunxing:'陨星', - nsyunxing_info:'锁定技,当场上一名角色死亡,若为蜀,你失去1点体力;若为吴,你回复1点体力;若为魏,你摸一张牌并弃置一名角色的手牌;若为群,你强制结束当前回合;若为你,你可以使一名角色翻面。', - nsguanxing:'观星', - nsguanxing_info:'锁定技,准备阶段,你观看牌堆的X张牌(X为场上存活人数)并且任意移动Y张牌(Y为你当前体力值)。', - nscaiyi:'猜疑', - nscaiyi_info:'其他角色摸牌后,你可以观看其摸到的牌,若其中有【杀】,则视为你对其使用一张【杀】,若其中没有【杀】,则视为其对你使用一张【杀】(计入出杀次数)。', - nsgefa:'割发', - nsgefa_info:'当你的体力值等于0或更低时,你可以将任意一张♣牌当【桃】使用。', - nshaoling:'号令', - nshaoling_info:'限定技,出牌阶段,你可以指定一名其他角色,令另外所有其他角色角色选择一项:1、对该角色使用一张【杀】;2、交给你一张牌,然后视为你对其使用一张【杀】。', - nspinmin:'拼命', - nspinmin_info:'锁定技,当你于回合内死亡时,你不死亡并增加1点体力上限(每回合最多增加1点且不能超过4);当你于回合外死亡时,你不死亡并减少1点体力上限(体力上限为0会导致你死亡)。', - nsshishou:'失手', - nsshishou_info:'锁定技,当你于回合内失去手牌时,你失去1点体力并摸一张牌;你回合内使用的牌数不能超过4。', - nsduijue:'对决', - nsduijue_info:'出牌阶段开始时,你可以弃置一张手牌,若如此做,此阶段你可以将一张与此牌颜色不同的手牌当作【决斗】使用(限2次)。', - nsshuangxiong:'双雄', - nsshuangxiong_info:'当你使用【决斗】或被使用【决斗】时,你可以将武将牌翻面。', - nsshuangxiong_append:'背面武将:文丑,2体力,你可以将一张牌当【杀】打出。', - nsguanyong:'冠勇', - nsguanyong_info:'你可以将一张手牌当【杀】打出。', - nsjihui:'急恚', - nsjihui_info:'锁定技,每当一名角色一次弃置了三张或更多的牌,你获得一个额外回合;你的额外回合内,你使用牌只能指定你与上一回合角色为目标。', - nsmouyun:'谋运', - nsmouyun_info:'每两轮限一次,你可以弃置场上体力值最少的一名其他角色区域内的X张牌。(X为其损失的体力值)', - nscongjun:'从军', - nscongjun_info:'锁定技,游戏开始时,你变身为一名随机男性角色;当一名敌方角色使用无懈可击时,你有小概率亮出此武将并变回花木兰,然后对该角色造成2点伤害。', - nshuanxian:'幻仙', - nshuanxian_info:'锁定技,游戏开始时,你获得随从“幻身·右”,当你首次受到伤害时,你获得随从“幻身·左”(体力上限2,初始手牌2);你与幻身在摸牌阶段均少摸一张牌;在你的回合中(如果有对应幻身),你以【幻身·左-本体-幻身·右】的顺序进行3个连续回合。', - nstaiping_nh:'太平', - nstaiping_nh_info:'当你受到1点伤害后(首次伤害除外),你可以选择一项: ①令一个“幻身”增加1点体力上限。②令一个“幻身”回复1点体力。', - nsshoudao:'授道', - nsshoudao_info:'当左右“幻身”全部死亡时,你获得技能“雷击”和“鬼道”。当你死亡时,若此时有两个“幻身”,你可以令一名其他角色获得技能“雷击”和“鬼道”。若有一个“幻身”,你可以令一名其他角色获得技能“雷击”或“鬼道”。(杀死你的角色除外)', - nsnongquan:'弄权', - nsnongquan_info:'出牌阶段,你可以将最后一张手牌当作【无中生有】使用。', - nsdufu:'毒妇', - nsdufu_info:'每当你即将造成一次伤害时,你可以为此伤害重新指定伤害来源。', - yiesheng:'回雪', - yiesheng_info:'出牌阶段,你可以弃置任意数量的黑色手牌,然后摸等量的牌。', - liangji:'环计', - liangji_info:'出牌阶段限一次,你可以选择一名未以此法放置牌的其他角色并将一张手牌置于其武将牌上。目标角色于摸牌阶段开始时,获得此牌。若其为男性角色,则获得技能〖无双〗,若其为女性角色,则获得技能〖离间〗,直到回合结束。', - chengmou:'逞谋', - chengmou_info:'摸牌阶段开始时,若你有“功”牌,你获得之并跳过摸牌阶段,若你所获得的“功”牌多于两张,你须失去1点体力。', - jugong:'居功', - jugong_info:'回合外每名角色的回合限一次,每当场上有角色因受到【杀】或【决斗】造成的伤害,你可以摸一张牌并且将一张手牌置于你的武将牌上,称之为“功”。在你即将受到伤害时,你可以弃置两张“功”,防止此伤害。', - nsxinsheng:'新生', - nsxinsheng_info:'每当你对其他角色造成伤害后,若你未受伤,则你可以增加X点体力上限并摸X张牌,X为伤害点数。', - nsdunxing:'遁形', - nsdunxing_info:'每当你即将受到其他角色造成的伤害时,若你已受伤,则你可以防止此伤害,改为失去X点体力上限并摸X张牌,X为伤害点数。', - liangce:'粮策', - liangce_info:'①出牌阶段限一次,你可以将一张基本牌当【五谷丰登】使用。②当因执行【五谷丰登】的效果而亮出的牌因效果执行完毕而置入弃牌堆后,你可以选择一名角色,令该角色获取之。', - jianbi:'坚壁', - jianbi_info:'当你成为锦囊牌的目标时,若此牌的目标包括其他角色,你可以令此牌对1个目标无效。', - diyjuntun:'军屯', - diyjuntun_info:'出牌阶段,你可以重铸装备牌。', - choudu:'筹度', - choudu_info:'出牌阶段限一次,你可以弃置一张牌,并指定一名角色视为其使用一张调兵遣将。', - liduan:'立断', - liduan_info:'当一名其他角色于其回合外得到牌后,若其此次得到的牌数为1且为装备牌(无论是否可见),你可以令该角色选择一项:1.使用此牌;2.将一张手牌交给你。', - fuchou:'负仇', - fuchou2:'负仇', - fuchou_info:'当你成为【杀】的目标时,你可以将一张牌交给此【杀】的使用者,令此【杀】对你无效且你到其的距离于当前回合内视为1,若如此做,此回合的结束阶段开始时,其令你摸一张牌,然后你需对其使用【杀】,否则失去1点体力。', - jinyan:'噤言', - jinyan_info:'锁定技。若你的体力值不大于2,你的黑色锦囊牌视为【杀】。', - chezhen:'车阵', - chezhen_info:'锁定技。若你的装备区里:没有牌,你的防御距离+1;有牌,你的进攻距离+1。', - youzhan:'诱战', - youzhan_info:'当以你距离不大于1的角色为目标的【杀】的使用结算开始时,你可以弃置一张装备牌,令该角色视为使用【诱敌深入】。', - kangyin:'亢音', - kangyin2:'亢音', - kangyin_info:'出牌阶段限一次,你可以失去1点体力并选择一名其他角色,弃置该角色的一张牌。若此牌:为基本牌,你可以令一至X名角色各摸一张牌;不为基本牌,于此回合内:你的进攻距离+X,且你使用【杀】的额外目标数上限+X。(X为你已损失的体力值)', - zhucheng:'筑城', - zhucheng2:'筑城', - zhucheng_info:'①结束阶段开始时,若没有“筑”,你可以将牌堆顶的X张牌置于你的武将牌上〔称为“筑”〕(X为你已损失的体力值与1中的较大值),否则你可以获取所有“筑”。②当你成为【杀】的目标时,若有“筑”,你可以令此杀的使用者弃置X张牌(X为“筑”的数量),否则杀对你无效。', - duoqi:'夺气', - duoqi_info:'当一名角色于除你之外的角色的出牌阶段内因弃置而失去牌后,你可以移去一张“筑”,并结束此出牌阶段。', + diy_wenyang: "文鸯", + ns_zhangwei: "张葳", + nshuaishuang: "怀霜", + nshuaishuang_info: "锁定技,结束阶段,你从牌堆/弃牌堆获得一张【桃】,然后失去1点体力。", + nsfengli: "奉礼", + nsfengli2: "奉礼", + nsfengli_draw: "奉礼", + nsfengli_clear: "奉礼", + nsfengli_use: "奉礼", + visible_nsfengli: "奉礼", + nsfengli_info: + "回合结束时,你可以选择一名其他角色并展示所有手牌直到你的下回合开始。当该角色于回合外需要使用或打出牌时,其可暗置你的一张明置手牌,然后视为使用或打出之。当你的明置手牌减少时,你可令一名手牌数小于你的角色摸一张牌。", + nsqiyue: "骑钺", + nsqiyue_info: "锁定技,当有角色的武将牌状态改变后,你摸一张牌。", + nsxuezhu: "血逐", + nsxuezhu_info: "当你受到伤害或造成伤害后,你可以令受到伤害的角色摸两张牌并翻面。", + ns_chuanshu: "传术", + ns_chuanshu_info: + "限定技 当一名其他角色进入濒死状态时,你可以令其选择获得技能〖雷击〗或〖鬼道〗,其回复体力至1并摸两张牌。当该被【传术】的角色造成或受到一次伤害后,你摸一张牌。其阵亡后,你重置技能〖传术〗。", + ns_xiandao1: "仙道", + ns_xiandao1_info: + "锁定技 游戏开始和回合结束阶段,你随机获得技能〖雷击〗或〖鬼道〗,直到下个出牌阶段开始。", + ns_xiandao2: "仙道", + ns_xiandao2_info: "锁定技 你防止受到任何属性伤害。", + ns_xiandao: "仙道", + ns_xiandao_info: + "锁定技 游戏开始、你进入游戏时和回合结束阶段,你随机获得技能〖雷击〗或〖鬼道〗,直到下个出牌阶段阶段开始。你防止受到任何属性伤害。", + ns_chuanshu2: "术", + ns_chuanshu2_info: "锁定技 当你造成或受到一次伤害后,南华老仙摸一张牌。", + ns_chuanshu3: "术", + ns_chuanshu3_info: + "锁定技 当你【传术】的角色阵亡后,你重置技能〖传术〗。", + ns_xiuzheng: "修真", + ns_xiuzheng_info: + "出牌阶段限一次,你可选择一名其他角色,然后亮出牌堆顶的两张牌,若同为红色,则其受到1点火焰伤害;若同为黑色,其受到1点雷电伤害;若颜色不相同,你弃置其一张牌。然后你获得这两张展示的牌后再弃置两张牌。", + nsanruo: "暗弱", + nsanruo_info: + "锁定技,你手牌中的【杀】和普通锦囊牌(借刀杀人等带有指向目标的锦囊除外)均对你不可见。但你可以正常使用之。", + nsxunshan: "循善", + nsxunshan_info: "锁定技,你使用【暗弱】牌可以为其指定任意名合法目标(托管无效)。", + nskaicheng: "开城", + nskaicheng_info: + "主公技,你的回合内,你可以将一张【暗弱】牌交给一名群势力其他角色观看,其可以选择是否告诉你此牌的名字。然后你选择一项:使用这张牌并摸一张牌;或结束此回合。", + nsjuanli: "狷戾", + nsjuanli_info: + "出牌阶段限一次,你可以和一名有手牌的其他角色进行赌牌,若你赢,目标角色失去1点体力且该角色与你距离-1直到与你下次赌牌,若你没赢,目标角色回复1点体力,且该角色与你距离+1直到与你的下次赌牌。(赌牌:赌牌的两名角色分别亮开一张手牌,若花色相同则赌牌平局,若花色不同,则依次亮出牌堆顶的牌直到翻开的牌与其中一人亮出牌的花色相同,则该角色获得赌牌的胜利)", + nsyuanchou: "远筹", + nsyuanchou_info: "锁定技,当你成为锦囊牌的目标时,若来源角色与你的距离大于1,则取消之。", + nsguhuo: "蛊惑", + nsguhuo_info: + "锁定技,你在一个回合中使用前两张牌时,你对一名随机角色从牌堆(牌堆无则从弃牌堆)随机使用一张同类别卡牌。", + nsqinxue: "勤学", + nsqinxue_info: + "每个效果每回合只能使用一次。①当你使用一张基本牌时,你从牌堆随机获得一张锦囊牌;②当你使用一张锦囊牌时,你从牌堆随机获得一张装备牌;③当你使用一张装备牌时,你从牌堆随机获得一张基本牌。", + nsbaiyi: "白衣", + nsbaiyi_info: + "锁定技,若你本回合发动过勤学,你跳过弃牌阶段,改为弃置X张牌(X为本回合发动勤学次数);若你弃置了3张类别不同的牌,你获得一个额外回合(不可连续获得回合),否则你观看牌堆顶的X张牌并获得其中一张。", + nsbaiming: "百鸣", + nsbaiming_info: + "当你使用【杀】时,你可以获得一项未获得过且与杀或伤害相关的技能,此【杀】结算完毕后,你失去以此法获得的技能。", + nsfuge: "覆戈", + nsfuge_info: + "你的回合结束后,你可以执行一个额外的回合,此回合的摸牌阶段,你于摸牌阶段额外摸X张牌(X为你已损失的体力值);若如此做,直到洗牌前,你不能再发动此技能。", + nstanbing: "谈兵", + nstanbing_info: + "摸牌阶段开始时,你可弃置一张手牌,然后摸X张牌(X为你弃置牌的名称字数),若如此做,本回合你不可使用或打出【杀】。", + nsxinzhan: "心战", + nsxinzhan_info: + "出牌阶段限一次,你可将任意张手牌交给一名其他角色,若如此做,该角色失去X点体力(X为你交给其的牌张数的一半,向下取整),若你给的牌达到六张,则改为该角色失去1点体力上限。", + nsfuhuo: "符火", + nsfuhuo2: "符火", + nsfuhuo_info: + "出牌阶段限一次,你可将一张手牌置于一名武将牌上没有“符”的角色的武将牌上,称为“符”,若如此做,其回合外使用或打出【闪】时,你可令其判定,若结果为:红桃,你对其造成2点火焰伤害;方块,你弃置其一张手牌,然后对其造成1点火焰伤害。你的下个回合开始时,你获得其武将牌上的“符”。", + nswangfeng: "望风", + nswangfeng_info: "在判定牌生效前,你可以打出一张红色牌替换之。", + nshunji: "混击", + nshunji_info: + "出牌阶段限一次,你可以摸一张牌,视为使用一张【万箭齐发】。此【万箭齐发】造成伤害时,受伤害角色选择一项:①弃置你一张牌;②摸一张牌。", + nscuanquan: "篡权", + nscuanquan_info: "锁定技,如果你的身份为忠臣,则在受伤三次后与主公,互换身份和体力上限。", + nsjianning: "奸佞", + nsjianning_info: + "出牌阶段限一次,如果你的身份为内奸,你可以与一名手牌数比你少的角色交换手牌,并对其造成1点伤害。", + nschangshi: "常仕", + nschangshi_info: + "出牌阶段限一次,如果你的身份为反贼,你可以指定两名其他角色互换体力;如果两名角色体力之差等于1,你失去1点体力。", + nsbaquan: "霸权", + nsbaquan_info: + "回合结束时,你可以弃置所有手牌,并获得相应点数的护甲,你的新一回合开始时清除所有护甲。", + nsbugua: "卜卦", + nsbugua_use_info: + "弃置一张牌,并将牌堆顶的六张牌反面朝上逐张按先后顺序排放,然后抛骰子,展示牌序号与骰子显示的点数一致的牌,然后你根据这张牌的花色、点数随机获得牌堆中相应的一张牌。", + nsbugua_info: + "出牌阶段限一次,你可以弃置一张牌,并将牌堆顶的六张牌反面朝上逐张按先后顺序排放,然后抛骰子,展示牌序号与骰子显示的点数一致的牌,然后你根据这张牌的花色、点数按以下规则随机获得牌堆中相应的一张牌:乾(红桃偶数):无中生有;坤(黑桃奇数):决斗;震(黑桃偶数):南蛮入侵;巽(红桃奇数):万箭齐发;坎(梅花偶数):过河拆桥、兑(梅花奇数):借刀杀人、艮(方片偶数):顺手牵羊、离(方片奇数):火攻。若牌堆中无此牌则摸一张牌,然后你观看未展示的另外五张牌并按任意顺序将其置于牌堆顶。", + nstuiyan: "推演", + nstuiyan_info: + "出牌阶段,若你使用的牌点数比上一张使用的牌点数大,你可以摸一张牌,反之你本回合不能再以此法摸牌;当你使用的牌点数首次达到8的倍数时,你可以在结算后立即发动一次【卜卦】。", + nstianji: "天机", + nstianji_info: + "限定技,当一名其他角色进入濒死状态,你可自减1点体力上限,令其回复体力至1并增加1点体力上限。", + nszhaoxin: "昭心", + nszhaoxin_info: "锁定技,你始终展示手牌。", + nsxiuxin: "修穆", + nsxiuxin_info: "锁定技,若你没有某种花色的手牌,你不能成为这种花色的牌的目标。", + nsshijun: "弑君", + nsshijun_info: "锁定技,你造成伤害时,你令此伤害+1,并在结算后失去1点体力。", + nshunyou: "魂佑", + nshunyou_info: + "出阶段限一次,你可以弃置一张基本牌,获得弃牌堆底的一张装备牌和一张锦囊牌,然后你可以将那张装备牌装备给一名角色(允许替换)。如果弃牌堆没有装备以及锦囊牌,则改为摸X张牌,X为损失的体力加一(最多3张)。", + nswulie: "武烈", + nswulie_info: + "限定技,准备阶段,你可以失去1点体力上限,从弃牌堆选择最多三张牌以任意顺序放置于牌堆顶。若如此做,此回合的结束阶段,你可以重复此操作。", + nscangxi: "藏玺", + nscangxi2: "藏玺", + nscangxi_info: + "主公技,其他吴势力角色的弃牌阶段结束时,若其弃置了至少两张牌,则可以选择判定,若是黑色,则其选择一项,1,令主公摸一张并且展示;2,主公手牌上限永久加一;3,额外弃置一张牌,令主公获得本回合进入弃牌堆的一张牌。", + nsdongcha: "洞察", + nsdongcha_info: + "锁定技,单体锦囊牌无法对你造成伤害。其它角色于其回合内第二次使用锦囊牌指定你为目标时,取消之。", + nscaijian: "才鉴", + nscaijian_info: + "出牌阶段限一次,若你的手牌数不大于你的体力上限,则你可以展示你的手牌,观看牌堆顶相同数量的牌并以任意方式交换之。", + nsgongjian: "恭俭", + nsgongjian_info: "锁定技,弃牌阶段,你须将弃牌交给一名体力值大于你的其它角色。", + nsjianxiong: "奸雄", + nsjianxiong_info: + "当你成为一名角色牌的目标后你可以对该角色使用一张牌,若此牌对其造成伤害,则该角色的牌失效。若失效的为黑色牌,则你摸一张牌。", + nsxionglue: "雄略", + nsxionglue_info: "出牌阶段限一次,你可以弃置一张黑色手牌,然后发现一张锦囊牌。", + nsyaowang: "妖妄", + nsyaowang_info: + "回合开始阶段你可以选择一名角色然后获得其其中一项技能直到回合结束,然后该角色随机获得一项未上场武将的其中一项技能直到其回合结束。", + nshuanhuo: "幻惑", + nshuanhuo_info: + "每当你失去1点体力或受到一次大于2的伤害时,你可以交换除你之外的两名角色的武将牌(体力及体力上限不变)。", + nsjianshu: "剑术", + nsjianshu_info: + "锁定技:每当你的装备区有武器时,你使用【杀】指定一个目标后,该角色需要依次使用两张【闪】才能抵消此【杀】。", + nscangjian: "藏剑", + nscangjian_info: "每当你对一名角色造成伤害,你可以获得其装备区一张牌。", + nsyunxing: "陨星", + nsyunxing_info: + "锁定技,当场上一名角色死亡,若为蜀,你失去1点体力;若为吴,你回复1点体力;若为魏,你摸一张牌并弃置一名角色的手牌;若为群,你强制结束当前回合;若为你,你可以使一名角色翻面。", + nsguanxing: "观星", + nsguanxing_info: + "锁定技,准备阶段,你观看牌堆的X张牌(X为场上存活人数)并且任意移动Y张牌(Y为你当前体力值)。", + nscaiyi: "猜疑", + nscaiyi_info: + "其他角色摸牌后,你可以观看其摸到的牌,若其中有【杀】,则视为你对其使用一张【杀】,若其中没有【杀】,则视为其对你使用一张【杀】(计入出杀次数)。", + nsgefa: "割发", + nsgefa_info: "当你的体力值等于0或更低时,你可以将任意一张♣牌当【桃】使用。", + nshaoling: "号令", + nshaoling_info: + "限定技,出牌阶段,你可以指定一名其他角色,令另外所有其他角色角色选择一项:1、对该角色使用一张【杀】;2、交给你一张牌,然后视为你对其使用一张【杀】。", + nspinmin: "拼命", + nspinmin_info: + "锁定技,当你于回合内死亡时,你不死亡并增加1点体力上限(每回合最多增加1点且不能超过4);当你于回合外死亡时,你不死亡并减少1点体力上限(体力上限为0会导致你死亡)。", + nsshishou: "失手", + nsshishou_info: + "锁定技,当你于回合内失去手牌时,你失去1点体力并摸一张牌;你回合内使用的牌数不能超过4。", + nsduijue: "对决", + nsduijue_info: + "出牌阶段开始时,你可以弃置一张手牌,若如此做,此阶段你可以将一张与此牌颜色不同的手牌当作【决斗】使用(限2次)。", + nsshuangxiong: "双雄", + nsshuangxiong_info: "当你使用【决斗】或被使用【决斗】时,你可以将武将牌翻面。", + nsshuangxiong_append: "背面武将:文丑,2体力,你可以将一张牌当【杀】打出。", + nsguanyong: "冠勇", + nsguanyong_info: "你可以将一张手牌当【杀】打出。", + nsjihui: "急恚", + nsjihui_info: + "锁定技,每当一名角色一次弃置了三张或更多的牌,你获得一个额外回合;你的额外回合内,你使用牌只能指定你与上一回合角色为目标。", + nsmouyun: "谋运", + nsmouyun_info: + "每两轮限一次,你可以弃置场上体力值最少的一名其他角色区域内的X张牌。(X为其损失的体力值)", + nscongjun: "从军", + nscongjun_info: + "锁定技,游戏开始时,你变身为一名随机男性角色;当一名敌方角色使用无懈可击时,你有小概率亮出此武将并变回花木兰,然后对该角色造成2点伤害。", + nshuanxian: "幻仙", + nshuanxian_info: + "锁定技,游戏开始时,你获得随从“幻身·右”,当你首次受到伤害时,你获得随从“幻身·左”(体力上限2,初始手牌2);你与幻身在摸牌阶段均少摸一张牌;在你的回合中(如果有对应幻身),你以【幻身·左-本体-幻身·右】的顺序进行3个连续回合。", + nstaiping_nh: "太平", + nstaiping_nh_info: + "当你受到1点伤害后(首次伤害除外),你可以选择一项: ①令一个“幻身”增加1点体力上限。②令一个“幻身”回复1点体力。", + nsshoudao: "授道", + nsshoudao_info: + "当左右“幻身”全部死亡时,你获得技能“雷击”和“鬼道”。当你死亡时,若此时有两个“幻身”,你可以令一名其他角色获得技能“雷击”和“鬼道”。若有一个“幻身”,你可以令一名其他角色获得技能“雷击”或“鬼道”。(杀死你的角色除外)", + nsnongquan: "弄权", + nsnongquan_info: "出牌阶段,你可以将最后一张手牌当作【无中生有】使用。", + nsdufu: "毒妇", + nsdufu_info: "每当你即将造成一次伤害时,你可以为此伤害重新指定伤害来源。", + yiesheng: "回雪", + yiesheng_info: "出牌阶段,你可以弃置任意数量的黑色手牌,然后摸等量的牌。", + liangji: "环计", + liangji_info: + "出牌阶段限一次,你可以选择一名未以此法放置牌的其他角色并将一张手牌置于其武将牌上。目标角色于摸牌阶段开始时,获得此牌。若其为男性角色,则获得技能〖无双〗,若其为女性角色,则获得技能〖离间〗,直到回合结束。", + chengmou: "逞谋", + chengmou_info: + "摸牌阶段开始时,若你有“功”牌,你获得之并跳过摸牌阶段,若你所获得的“功”牌多于两张,你须失去1点体力。", + jugong: "居功", + jugong_info: + "回合外每名角色的回合限一次,每当场上有角色因受到【杀】或【决斗】造成的伤害,你可以摸一张牌并且将一张手牌置于你的武将牌上,称之为“功”。在你即将受到伤害时,你可以弃置两张“功”,防止此伤害。", + nsxinsheng: "新生", + nsxinsheng_info: + "每当你对其他角色造成伤害后,若你未受伤,则你可以增加X点体力上限并摸X张牌,X为伤害点数。", + nsdunxing: "遁形", + nsdunxing_info: + "每当你即将受到其他角色造成的伤害时,若你已受伤,则你可以防止此伤害,改为失去X点体力上限并摸X张牌,X为伤害点数。", + liangce: "粮策", + liangce_info: + "①出牌阶段限一次,你可以将一张基本牌当【五谷丰登】使用。②当因执行【五谷丰登】的效果而亮出的牌因效果执行完毕而置入弃牌堆后,你可以选择一名角色,令该角色获取之。", + jianbi: "坚壁", + jianbi_info: "当你成为锦囊牌的目标时,若此牌的目标包括其他角色,你可以令此牌对1个目标无效。", + diyjuntun: "军屯", + diyjuntun_info: "出牌阶段,你可以重铸装备牌。", + choudu: "筹度", + choudu_info: "出牌阶段限一次,你可以弃置一张牌,并指定一名角色视为其使用一张调兵遣将。", + liduan: "立断", + liduan_info: + "当一名其他角色于其回合外得到牌后,若其此次得到的牌数为1且为装备牌(无论是否可见),你可以令该角色选择一项:1.使用此牌;2.将一张手牌交给你。", + fuchou: "负仇", + fuchou2: "负仇", + fuchou_info: + "当你成为【杀】的目标时,你可以将一张牌交给此【杀】的使用者,令此【杀】对你无效且你到其的距离于当前回合内视为1,若如此做,此回合的结束阶段开始时,其令你摸一张牌,然后你需对其使用【杀】,否则失去1点体力。", + jinyan: "噤言", + jinyan_info: "锁定技。若你的体力值不大于2,你的黑色锦囊牌视为【杀】。", + chezhen: "车阵", + chezhen_info: "锁定技。若你的装备区里:没有牌,你的防御距离+1;有牌,你的进攻距离+1。", + youzhan: "诱战", + youzhan_info: + "当以你距离不大于1的角色为目标的【杀】的使用结算开始时,你可以弃置一张装备牌,令该角色视为使用【诱敌深入】。", + kangyin: "亢音", + kangyin2: "亢音", + kangyin_info: + "出牌阶段限一次,你可以失去1点体力并选择一名其他角色,弃置该角色的一张牌。若此牌:为基本牌,你可以令一至X名角色各摸一张牌;不为基本牌,于此回合内:你的进攻距离+X,且你使用【杀】的额外目标数上限+X。(X为你已损失的体力值)", + zhucheng: "筑城", + zhucheng2: "筑城", + zhucheng_info: + "①结束阶段开始时,若没有“筑”,你可以将牌堆顶的X张牌置于你的武将牌上〔称为“筑”〕(X为你已损失的体力值与1中的较大值),否则你可以获取所有“筑”。②当你成为【杀】的目标时,若有“筑”,你可以令此杀的使用者弃置X张牌(X为“筑”的数量),否则杀对你无效。", + duoqi: "夺气", + duoqi_info: + "当一名角色于除你之外的角色的出牌阶段内因弃置而失去牌后,你可以移去一张“筑”,并结束此出牌阶段。", - siji:'伺机', - ciqiu:'刺酋', - ciqiu_dying:'刺酋', - diy_liuyan:'刘焉', - juedao:'绝道', - geju:'割据', - shaoying:'烧营', - zonghuo:'纵火', - diychanyuan:'缠怨', - diyguhuo:'蛊惑', - jieyan:'劫焰', - honglian:'红莲', - xiongzi:'雄姿', - luweiyan:'围堰', - guihan:'归汉', - diyduanliang:'断粮', - diyduanliang1:'断粮', - diyduanliang2:'断粮', - diyqiangxi:'强袭', - diykuanggu:'狂骨', - diyzaiqi:'再起', - batu:'霸图', - zaiqix:'再起', - diy_jiaoxia:'皎霞', - yaliang:'雅量', - yaliang_info:'每当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可与该角色各摸一张牌。', - diy_jiaoxia_info:'每当你成为红色牌的目标,你可以摸一张牌。', - zaiqix_info:'摸牌阶段,若你已受伤,你可以改为展示牌堆顶的X+1张牌,X为你已损失的体力值,其中每有一张♥牌,你回复1点体力,然后弃掉这些♥牌,将其余的牌收入手牌。', - batu_info:'结束阶段,你可以将手牌数补至X,X为现存的势力数。', - diyzaiqi_info:'锁定技,你摸牌阶段额外摸X张牌,X为你已损失的体力值。', - diykuanggu_info:'锁定技,每当你造成1点伤害,你在其攻击范围内,你回复1点体力,否则你摸一张牌。', - diyqiangxi_info:'出牌阶段,你可以自减1点体力或弃一张武器牌,然后你对你攻击范围内的一名角色造成1点伤害并弃置其一张牌,每回合限一次。', - diyduanliang_info:'出牌阶段限一次,你可以将一张黑色的基本牌当兵粮寸断对一名角色使用,然后摸一张牌。你的兵粮寸断可以指定距离2以内的角色作为目标。', - guihan_info:'限定技,当你进入濒死状态时,可以指定一名男性角色与其各回复1点体力并摸两张牌。', - luweiyan_info:'出牌阶段限一次,你可以将一张非基本牌当作水攻使用;结算后你可以视为对其中一个目标使用一张不计入出杀次数的【杀】。', - xiongzi_info:'锁定技,你于摸牌阶段额外摸X+1张牌,X为你装备区牌数的一半,向下取整。', - honglian_info:'每当你受到来自其他角色的伤害,可以弃置伤害来源的所有红色牌。', - jieyan_info:'出牌阶段限一次,你可以弃置一张红色手牌令场上所有角色受到1点火焰伤害。', - diyguhuo_info:'锁定技,准备阶段,你摸两张牌,然后弃置区域内的两张牌。', - diychanyuan_info:'锁定技,杀死你的角色失去1点体力上限。', - zonghuo_info:'你可弃置一张牌将你即将造成的伤害变为火焰伤害。', - shaoying_info:'每当你造成一次火焰伤害,可指定距离受伤害角色1以内的另一名角色,并展示牌堆顶的一张牌,若此牌为红色,该角色受到1点火焰伤害。', - juedao_info:'出牌阶段,你可以弃置一张手牌,横置你的武将牌;锁定技,若你的武将牌横置,则你计算至其他角色的距离和其他角色计算至你的距离均+1。', - geju_info:'准备阶段开始时,你可以摸X张牌(X为攻击范围内不含有你的势力数)。', - siji_info:'弃牌阶段结束后,你可以摸2X张牌(X为你于此阶段内弃置的【杀】的数量)。', - ciqiu_info:'锁定技,每当你使用【杀】对目标角色造成伤害时,若该角色未受伤,你令此伤害+1;若其因此进入濒死状态,你令其死亡,然后你失去“刺酋”。', - nsshuaiyan_info:'每当其他角色于你的回合外回复体力后,你可以令该角色选择一项:1.令你摸一张牌;2.令你弃置其一张牌。', - moshou_info:'锁定技,你不能成为乐不思蜀和兵粮寸断的目标。', - xicai_info:'你可以立即获得对你造成伤害的牌。', - diyjianxiong_info:'锁定技,在身份局中,在你回合内死亡的角色均视为反贼,国战中,在你回合内死亡的角色若与你势力相同则随机改为另一个势力。', + siji: "伺机", + ciqiu: "刺酋", + ciqiu_dying: "刺酋", + diy_liuyan: "刘焉", + juedao: "绝道", + geju: "割据", + shaoying: "烧营", + zonghuo: "纵火", + diychanyuan: "缠怨", + diyguhuo: "蛊惑", + jieyan: "劫焰", + honglian: "红莲", + xiongzi: "雄姿", + luweiyan: "围堰", + guihan: "归汉", + diyduanliang: "断粮", + diyduanliang1: "断粮", + diyduanliang2: "断粮", + diyqiangxi: "强袭", + diykuanggu: "狂骨", + diyzaiqi: "再起", + batu: "霸图", + zaiqix: "再起", + diy_jiaoxia: "皎霞", + yaliang: "雅量", + yaliang_info: + "每当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可与该角色各摸一张牌。", + diy_jiaoxia_info: "每当你成为红色牌的目标,你可以摸一张牌。", + zaiqix_info: + "摸牌阶段,若你已受伤,你可以改为亮出牌堆顶的X+1张牌,X为你已损失的体力值,其中每有一张♥牌,你回复1点体力,然后弃掉这些♥牌,将其余的牌收入手牌。", + batu_info: "结束阶段,你可以将手牌数补至X,X为现存的势力数。", + diyzaiqi_info: "锁定技,你摸牌阶段额外摸X张牌,X为你已损失的体力值。", + diykuanggu_info: "锁定技,每当你造成1点伤害,你在其攻击范围内,你回复1点体力,否则你摸一张牌。", + diyqiangxi_info: + "出牌阶段,你可以自减1点体力或弃一张武器牌,然后你对你攻击范围内的一名角色造成1点伤害并弃置其一张牌,每回合限一次。", + diyduanliang_info: + "出牌阶段限一次,你可以将一张黑色的基本牌当兵粮寸断对一名角色使用,然后摸一张牌。你的兵粮寸断可以指定距离2以内的角色作为目标。", + guihan_info: "限定技,当你进入濒死状态时,可以指定一名男性角色与其各回复1点体力并摸两张牌。", + luweiyan_info: + "出牌阶段限一次,你可以将一张非基本牌当作水攻使用;结算后你可以视为对其中一个目标使用一张不计入出杀次数的【杀】。", + xiongzi_info: "锁定技,你于摸牌阶段额外摸X+1张牌,X为你装备区牌数的一半,向下取整。", + honglian_info: "每当你受到来自其他角色的伤害,可以弃置伤害来源的所有红色牌。", + jieyan_info: "出牌阶段限一次,你可以弃置一张红色手牌令场上所有角色受到1点火焰伤害。", + diyguhuo_info: "锁定技,准备阶段,你摸两张牌,然后弃置区域内的两张牌。", + diychanyuan_info: "锁定技,杀死你的角色失去1点体力上限。", + zonghuo_info: "你可弃置一张牌将你即将造成的伤害变为火焰伤害。", + shaoying_info: + "每当你造成一次火焰伤害,可指定距离受伤害角色1以内的另一名角色,并亮出牌堆顶的一张牌,若此牌为红色,该角色受到1点火焰伤害。", + juedao_info: + "出牌阶段,你可以弃置一张手牌,横置你的武将牌;锁定技,若你的武将牌横置,则你计算至其他角色的距离和其他角色计算至你的距离均+1。", + geju_info: "准备阶段开始时,你可以摸X张牌(X为攻击范围内不含有你的势力数)。", + siji_info: "弃牌阶段结束后,你可以摸2X张牌(X为你于此阶段内弃置的【杀】的数量)。", + ciqiu_info: + "锁定技,每当你使用【杀】对目标角色造成伤害时,若该角色未受伤,你令此伤害+1;若其因此进入濒死状态,你令其死亡,然后你失去“刺酋”。", + nsshuaiyan_info: + "每当其他角色于你的回合外回复体力后,你可以令该角色选择一项:1.令你摸一张牌;2.令你弃置其一张牌。", + moshou_info: "锁定技,你不能成为乐不思蜀和兵粮寸断的目标。", + xicai_info: "你可以立即获得对你造成伤害的牌。", + diyjianxiong_info: + "锁定技,在身份局中,在你回合内死亡的角色均视为反贼,国战中,在你回合内死亡的角色若与你势力相同则随机改为另一个势力。", - ns_zanghong:'臧洪', - nsshimeng:'誓盟', - nsshimeng_info:'出牌阶段限一次,你可以选择任意名角色。这些角色依次选择一项:⒈摸一张牌。⒉使用一张【杀】。然后若选择前者角色数大于选择后者的角色数,则你获得1点护甲并失去1点体力。', - ns_ruanji:'阮籍', - nsshizui:'酾醉', - nsshizui_info:'每回合限一次。当你成为基本牌或普通锦囊牌的目标后,你可以弃置一张牌,然后视为使用一张【酒】。若你弃置的牌与其使用的牌花色相同,则此牌对你无效;若你弃置的牌为♣,则你获得其使用的牌。', - nsxiaoye:'啸野', - nsxiaoye_info:'一名角色的结束阶段开始时,若你于当前回合内使用过【酒】,则你可以视为使用一张其于本回合内使用过的【杀】或普通锦囊牌。', - ns_limi:'李密', - nstuilun:'退论', - nstuilun_info:'结束阶段,你可以失去任意点体力(至多失去至1点)并弃置任意张手牌(至多弃置至一张)。若如此做,你获得如下效果直到你下回合开始:其他角色的回合开始时,若你的体力值小于该角色,则你可以令一名角色回复或失去1点体力;若你的手牌数小于该角色,则你可以令一名角色摸一张牌或弃置一张牌。', - ns_zhonglimu:'钟离牧', - nskuanhuai:'宽怀', - nskuanhuai_info:'出牌阶段开始时,你可以从弃牌堆中获得一张非基本牌。若如此做:你本阶段内不能使用基本牌,且本回合的弃牌阶段结束时,你可以依次使用本阶段内弃置的基本牌。', - nsdingbian:'定边', - nsdingbian_info:'锁定技。当你于回合内使用锦囊牌或装备牌后,你令自己本回合的手牌上限-1且选择一项:⒈从牌堆获得一张基本牌。⒉令一种基本牌于本回合内不计入手牌上限。', - prp_zhugeliang_ab:'诸葛亮', - prp_zhugeliang:'派对浪客', - nsxingyun:'星陨', - nsxingyun_info:'每回合限一次。你可以将一张手牌当做任意一张符合“四象天阵”的牌使用。然后若这两张牌的类型不同,则你删除此“四象天阵”并摸两张牌。当你删除“四象天阵”中的最后一个项目后,你获得技能〖八阵〗。', - nsxingyun_faq:'四象天阵', - nsxingyun_faq_info:'青龙:无标签普通锦囊牌
              朱雀:延时锦囊牌
              白虎:伤害类卡牌
              玄武:【闪】/回复类卡牌', - nshanlang:'酣浪', - nshanlang_info:'准备阶段,你可以和至多三名角色拼点。然后若这些角色中有拼点牌唯一最大的角色,则你可以令该角色从牌堆中获得一张不符合“四象天阵”的牌。', + ns_zanghong: "臧洪", + nsshimeng: "誓盟", + nsshimeng_info: + "出牌阶段限一次,你可以选择任意名角色。这些角色依次选择一项:⒈摸一张牌。⒉使用一张【杀】。然后若选择前者角色数大于选择后者的角色数,则你获得1点护甲并失去1点体力。", + ns_ruanji: "阮籍", + nsshizui: "酾醉", + nsshizui_info: + "每回合限一次。当你成为基本牌或普通锦囊牌的目标后,你可以弃置一张牌,然后视为使用一张【酒】。若你弃置的牌与其使用的牌花色相同,则此牌对你无效;若你弃置的牌为♣,则你获得其使用的牌。", + nsxiaoye: "啸野", + nsxiaoye_info: + "一名角色的结束阶段开始时,若你于当前回合内使用过【酒】,则你可以视为使用一张其于本回合内使用过的【杀】或普通锦囊牌。", + ns_limi: "李密", + nstuilun: "退论", + nstuilun_info: + "结束阶段,你可以失去任意点体力(至多失去至1点)并弃置任意张手牌(至多弃置至一张)。若如此做,你获得如下效果直到你下回合开始:其他角色的回合开始时,若你的体力值小于该角色,则你可以令一名角色回复或失去1点体力;若你的手牌数小于该角色,则你可以令一名角色摸一张牌或弃置一张牌。", + ns_zhonglimu: "钟离牧", + nskuanhuai: "宽怀", + nskuanhuai_info: + "出牌阶段开始时,你可以从弃牌堆中获得一张非基本牌。若如此做:你本阶段内不能使用基本牌,且本回合的弃牌阶段结束时,你可以依次使用本阶段内弃置的基本牌。", + nsdingbian: "定边", + nsdingbian_info: + "锁定技。当你于回合内使用锦囊牌或装备牌后,你令自己本回合的手牌上限-1且选择一项:⒈从牌堆获得一张基本牌。⒉令一种基本牌于本回合内不计入手牌上限。", + prp_zhugeliang_ab: "诸葛亮", + prp_zhugeliang: "派对浪客", + nsxingyun: "星陨", + nsxingyun_info: + "每回合限一次。你可以将一张手牌当做任意一张符合“四象天阵”的牌使用。然后若这两张牌的类型不同,则你删除此“四象天阵”并摸两张牌。当你删除“四象天阵”中的最后一个项目后,你获得技能〖八阵〗。", + nsxingyun_faq: "四象天阵", + nsxingyun_faq_info: + "青龙:无标签普通锦囊牌
              朱雀:延时锦囊牌
              白虎:伤害类卡牌
              玄武:【闪】/回复类卡牌", + nshanlang: "酣浪", + nshanlang_info: + "准备阶段,你可以和至多三名角色拼点。然后若这些角色中有拼点牌唯一最大的角色,则你可以令该角色从牌堆中获得一张不符合“四象天阵”的牌。", - junktaoluan:'滔乱', - junktaoluan_backup:'滔乱', - junktaoluan_info:'你可将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本局游戏你以此法使用过的牌,且每回合每种花色限一次),然后你令一名其他角色选择一项:1.交给你一张与“滔乱”声明的牌类别不同的牌;2.本回合“滔乱”失效且回合结束时你失去1点体力。', - ns_caimao:'蔡瑁', - nsdingzhou:'定州', - nsdingzhou_info:'出牌阶段限一次,你可以选择一名区域内有牌的其他角色。你随机获得其区域内的一张牌,然后摸一张牌。若你以此法获得了两张颜色不同的牌,则你失去1点体力。', - junkyuheng:'驭衡', - junkyuheng_info:'锁定技。①回合开始时,你须弃置任意张花色不同的牌,从东吴命运线·改中随机获得等量的技能。②回合结束时,你失去所有因〖驭衡①〗获得的技能,然后摸等量的牌。', - junkdili:'帝力', - junkdili_info:'觉醒技。当你获得技能后,若你拥有的技能数大于你的体力上限,则你减1点体力上限,选择失去任意个其他技能,然后获得以下技能中的前等量个:〖圣质〗/〖权道〗/〖持纲〗。', - junkshengzhi:'圣质', - junkshengzhi_info:'锁定技。当你发动非锁定技后,你令你本回合使用的下一张牌无距离和次数限制。', - junkquandao:'权道', - junkquandao_info:'锁定技。当你使用【杀】或普通锦囊牌时,{若你手牌中的【杀】或普通锦囊牌的数量之差X不为0,则你弃置X张数量较多的一种牌},然后你摸一张牌。', - junkchigang:'持纲', - junkchigang_info:'转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的:阴,摸牌阶段;阳,出牌阶段。', - junkrende:'仁德', - junkrende_info:'出牌阶段限一次,你可以将任意张手牌交给其他角色。若你给出的牌多于一张,则你回复1点体力。', - junkjizhi:'集智', - junkjizhi_info:'当你使用非转化的普通锦囊牌时,你可以展示牌堆顶的一张牌A。若A不为基本牌,则你获得A。否则你选择一项:⒈将A置入弃牌堆。⒉将一张手牌置于牌堆顶,然后获得A。', - junkqicai:'奇才', - junkqicai_info:'锁定技。①你使用锦囊牌无距离限制。②你装备区内的非坐骑牌不能被其他角色弃置。', - junkwangxi:'忘隙', - junkwangxi_info:'当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可以摸两张牌,然后交给其其中一张牌。', - junkwangxi_tag:'invisible', - junklangmie:'狼灭', - junklangmie_info:'其他角色的结束阶段开始时,你可以选择一项:⒈若其本回合内使用过某种类型的牌超过一张,则你弃置一张牌并摸两张牌。⒉若其本回合累计造成过的伤害大于1,则你弃置一张牌,然后对其造成1点伤害。', - junkshicai:"恃才", - junkshicai_info:"当你使用牌结束完毕后,若此牌与你本回合使用的牌类型均不同,则你可以将此牌置于牌堆顶,然后摸一张牌。", - junk_zhangrang:'新杀张让', - junk_zhangrang_prefix:'新杀', - old_jiakui:'手杀贾逵', - old_jiakui_prefix:'手杀', - ol_guohuai:'OL郭淮', - ol_guohuai_prefix:'OL', - old_bulianshi:'RE步练师', - old_bulianshi_prefix:'RE', - ol_maliang:'OL马良', - ol_maliang_prefix:'OL', - junk_lidian:'OL李典', - junk_lidian_prefix:'OL', - junk_duanwei:'新杀段煨', - junk_duanwei_prefix:'新杀', - junk_xuyou:'手杀许攸', - junk_xuyou_prefix:'手杀', - junk_liubei:'旧界刘备', - junk_liubei_prefix:'旧界', - junk_huangyueying:'旧界黄月英', - junk_huangyueying_prefix:'旧界', - old_majun:'骰子马钧', - old_majun_prefix:'骰子', - ns_mengyou:'数学孟优', - ns_mengyou_prefix:'数学', - ns_mengyou_ab:'孟优', - nsmanzhi:'蛮智', - nsmanzhi_info:'准备阶段或结束阶段开始时,你可以将场上出现的数字代入等式中的A和B。若此等式成立,你摸Y张牌。(等式为Y=0.5A2+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:'杜畿', - junk_zhangjiao:'OL神张角', - junk_zhangjiao_prefix:'OL神', - junksijun:'肆军', - junksijun_info:'准备阶段,若“黄”数大于牌堆的牌数,你可以移去所有“黄”,然后从牌堆中随机获得任意张点数之和为36的牌(若牌堆没有点数和为36的组合则获得牌堆顶点数和刚好超过36的牌组)。', - junk_guanyu:'旧谋关羽', - junk_guanyu_prefix:'旧谋', + junktaoluan: "滔乱", + junktaoluan_backup: "滔乱", + junktaoluan_info: + "你可将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本局游戏你以此法使用过的牌,且每回合每种花色限一次),然后你令一名其他角色选择一项:1.交给你一张与“滔乱”声明的牌类别不同的牌;2.本回合“滔乱”失效且回合结束时你失去1点体力。", + ns_caimao: "蔡瑁", + nsdingzhou: "定州", + nsdingzhou_info: + "出牌阶段限一次,你可以选择一名区域内有牌的其他角色。你随机获得其区域内的一张牌,然后摸一张牌。若你以此法获得了两张颜色不同的牌,则你失去1点体力。", + junkyuheng: "驭衡", + junkyuheng_info: + '锁定技。①回合开始时,你须弃置任意张花色不同的牌,从东吴命运线·改中随机获得等量的技能。②回合结束时,你失去所有因〖驭衡①〗获得的技能,然后摸等量的牌。', + junkdili: "帝力", + junkdili_info: + "觉醒技。当你获得技能后,若你拥有的技能数大于你的体力上限,则你减1点体力上限,选择失去任意个其他技能,然后获得以下技能中的前等量个:〖圣质〗/〖权道〗/〖持纲〗。", + junkshengzhi: "圣质", + junkshengzhi_info: "锁定技。当你发动非锁定技后,你令你本回合使用的下一张牌无距离和次数限制。", + junkquandao: "权道", + junkquandao_info: + "锁定技。当你使用【杀】或普通锦囊牌时,{若你手牌中的【杀】或普通锦囊牌的数量之差X不为0,则你弃置X张数量较多的一种牌},然后你摸一张牌。", + junkchigang: "持纲", + junkchigang_info: + "转换技,锁定技。判定阶段开始前,你取消此阶段。然后你获得一个额外的:阴,摸牌阶段;阳,出牌阶段。", + junkrende: "仁德", + junkrende_info: + "出牌阶段限一次,你可以将任意张手牌交给其他角色。若你给出的牌多于一张,则你回复1点体力。", + junkjizhi: "集智", + junkjizhi_info: + "当你使用非转化的普通锦囊牌时,你可以亮出牌堆顶的一张牌A。若A不为基本牌,则你获得A。否则你选择一项:⒈将A置入弃牌堆。⒉将一张手牌置于牌堆顶,然后获得A。", + junkqicai: "奇才", + junkqicai_info: "锁定技。①你使用锦囊牌无距离限制。②你装备区内的非坐骑牌不能被其他角色弃置。", + junkwangxi: "忘隙", + junkwangxi_info: + "当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可以摸两张牌,然后交给其其中一张牌。", + junkwangxi_tag: "invisible", + junklangmie: "狼灭", + junklangmie_info: + "其他角色的结束阶段开始时,你可以选择一项:⒈若其本回合内使用过某种类型的牌超过一张,则你弃置一张牌并摸两张牌。⒉若其本回合累计造成过的伤害大于1,则你弃置一张牌,然后对其造成1点伤害。", + junkshicai: "恃才", + junkshicai_info: + "当你使用牌结束完毕后,若此牌与你本回合使用的牌类型均不同,则你可以将此牌置于牌堆顶,然后摸一张牌。", + junk_zhangrang: "新杀张让", + junk_zhangrang_prefix: "新杀", + old_jiakui: "手杀贾逵", + old_jiakui_prefix: "手杀", + ol_guohuai: "OL郭淮", + ol_guohuai_prefix: "OL", + old_bulianshi: "RE步练师", + old_bulianshi_prefix: "RE", + ol_maliang: "OL马良", + ol_maliang_prefix: "OL", + junk_lidian: "OL李典", + junk_lidian_prefix: "OL", + junk_duanwei: "新杀段煨", + junk_duanwei_prefix: "新杀", + junk_xuyou: "手杀许攸", + junk_xuyou_prefix: "手杀", + junk_liubei: "旧界刘备", + junk_liubei_prefix: "旧界", + junk_huangyueying: "旧界黄月英", + junk_huangyueying_prefix: "旧界", + old_majun: "骰子马钧", + old_majun_prefix: "骰子", + ns_mengyou: "数学孟优", + ns_mengyou_prefix: "数学", + ns_mengyou_ab: "孟优", + nsmanzhi: "蛮智", + nsmanzhi_info: + "准备阶段或结束阶段开始时,你可以将场上出现的数字代入等式中的A和B。若此等式成立,你摸Y张牌。(等式为Y=0.5A2+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: "杜畿", + junk_zhangjiao: "OL神张角", + junk_zhangjiao_prefix: "OL神", + junksijun: "肆军", + junksijun_info: + "准备阶段,若“黄”数大于牌堆的牌数,你可以移去所有“黄”,然后从牌堆中随机获得任意张点数之和为36的牌(若牌堆没有点数和为36的组合则获得牌堆顶点数和刚好超过36的牌组)。", + junk_guanyu: "旧谋关羽", + junk_guanyu_prefix: "旧谋", - diy_tieba:'吧友设计', - diy_xushi:'玩点论杀·虚实篇', - diy_default:'常规', - diy_noname:'无名专属', - diy_key:'论外', - diy_yijiang:'设计比赛2020', - diy_yijiang2:'设计比赛2021', - diy_yijiang3:'设计比赛2022', - diy_fakenews:'杀海流言', - diy_trashbin:'垃圾桶', + diy_tieba: "吧友设计", + diy_xushi: "玩点论杀·虚实篇", + diy_default: "常规", + diy_noname: "无名专属", + diy_key: "论外", + diy_yijiang: "设计比赛2020", + diy_yijiang2: "设计比赛2021", + diy_yijiang3: "设计比赛2022", + diy_fakenews: "杀海流言", + diy_trashbin: "垃圾桶", }, - pinyins:{ - 加藤うみ:['Kato','Umi'], - 仲村由理:['Nakamura','Yuri'], - 此花露西娅:['Konohana','Lucia'], - 枣恭介:['Natsume','Kyousuke'], - 神尾晴子:['Kamio','Haruko'], - 神北小毬:['Kamikita','Komari'], - 宫泽有纪宁:['Miyazawa','Yukine'], - 西森柚咲:['Nishimori','Yusa'], - 黑羽美砂:['Kurobane','Misa'], - 井之原真人:['Inohara','Masato'], - 岩泽雅美:['Iwasawa','Masami'], - 宫泽谦吾:['Miyazawa','Kengo'], - 吉野晴彦:['Yoshino','Haruhiko'], - 由依:['Yui'], - 紬文德斯:['Tsumugi','Wenders'], - 朱鹭户沙耶:['Tokido','Saya'], - '三枝叶留佳&二木佳奈多':['Saigusa','Haruka','Futaki','Kanata'], - 三枝二木:['Saigusa','Haruka','Futaki','Kanata'], - 稻荷:['Inari'], - 椎名:['Shiina'], - '春原阳平&春原芽衣':['Sunohara','Youhei','Sunohara','Mei'], - 阳平芽衣:['Sunohara','Youhei','Sunohara','Mei'], - 枣铃:['Natsume','Rin'], - 笹濑川佐佐美:['Sasasegawa','Sasami'], - 千里朱音:['Senri','Akane'], - 多鲁基:['Dorj'], - 来谷唯湖:['Kurugaya','Yuiko'], - 直枝理树:['Naoe','Riki'], - 渕田久子:['Fuchita','Hisako'], - 日向秀树:['Hinata','Hideki'], - 野田:['Noda'], - 冈崎朋也:['Okazaki','Tomoya'], - 古河渚:['Furukawa','Nagisa'], - 直井文人:['Naoi','Ayato'], - 空门苍:['Sorakado','Ao'], - 音无结弦:['Otonashi','Yuzuru'], - 立华奏:['Tachibana','Kanade'], - 西园美鱼:['Nishizono','Mio'], - 西园美鸟:['Nishizono','Midori'], - 岬镜子:['Misaki','Kyoko'], - 中津静流:['Nakatsu','Shizuru'], - '关根诗织&入江美雪':['Sekine','Shiori','Irie','Miyuki'], - 关根入江:['Sekine','Shiori','Irie','Miyuki'], - 野村美希:['Nomura','Miki'], - 美坂栞:['Misaka','Shiori'], - 美坂香里:['Misaka','Kaori'], - 水濑秋子:['Minase','Akiko'], - 游佐:['Yusa'], - 松下护騨:['Matsushita','Godan'], - 乙坂有宇:['Otosaka','Yuu'], - 三谷良一:['Mitani','Ryoichi'], - 神户小鸟:['Kanbe','Kotori'], - 高城丈士朗:['Takajyo','Jyojirou'], - 鸣濑白羽:['Naruse','Shiroha'], - 水织静久:['Mizuori','Shizuku'], - 铃木央人:['Suzuki','Hiroto'], - 凤咲夜:['Ootori','Sakuya'], - 成神阳太:['Narukami','Youta'], - 七濑留美:['Nanase','Rumi'], - 凤千早:['Ootori','Chihaya'], - 国崎往人:['Kunisaki','Yukito'], - 井上晶:['Inoue','Asara'], - 一之濑琴美:['Ichinose','Kotomi'], - 藤川米娅:['Fujikawa','Mia'], - 雾岛佳乃:['Kirishima','Kano'], - 苍井绘梨花:['Aoi','Erika'], - 藏里见:['Kura','Satomi'], - '喵呜·喵呼':['Myau','Mya-fu'], - 喵呜喵呼:['Myau','Mya-fu'], - 伊吹风子:['Ibuki','Fuuko'], - 久岛鸥:['Kushima','Kamome'], - 库特莉亚芙卡:['Noumi','Kudryavka'], - 神尾观铃:['Kamio','Misuzu'], - 友利奈绪:['Tomori','Nao'], - 天王寺瑚太朗:['Tennouji','Kotarou'], - 藤林杏:['Fujibayashi','Kyou'], - 伊座并杏子:['Izanami','Kyouko'], - 加纳天善:['Kano','Tenzen'], - 冰室忧希:['Himuro','Yuuki'], - 露娜Q:['Lunar','Q'], - 远野小满:['Toono','Michiru'], - 远野美凪:['Toono','Minagi'], - 樱庭星罗:['Sakuraba','Seira'], - 坂上智代:['Sakagami','Tomoyo'], - 冈崎汐:['Okazaki','Ushio'], - 神山识:['Kamiyama','Shiki'], - 佐藤雏:['Satou','Hina'], - 篝:['Kagari'], + pinyins: { + 加藤うみ: ["Kato", "Umi"], + 仲村由理: ["Nakamura", "Yuri"], + 此花露西娅: ["Konohana", "Lucia"], + 枣恭介: ["Natsume", "Kyousuke"], + 神尾晴子: ["Kamio", "Haruko"], + 神北小毬: ["Kamikita", "Komari"], + 宫泽有纪宁: ["Miyazawa", "Yukine"], + 西森柚咲: ["Nishimori", "Yusa"], + 黑羽美砂: ["Kurobane", "Misa"], + 井之原真人: ["Inohara", "Masato"], + 岩泽雅美: ["Iwasawa", "Masami"], + 宫泽谦吾: ["Miyazawa", "Kengo"], + 吉野晴彦: ["Yoshino", "Haruhiko"], + 由依: ["Yui"], + 紬文德斯: ["Tsumugi", "Wenders"], + 朱鹭户沙耶: ["Tokido", "Saya"], + "三枝叶留佳&二木佳奈多": ["Saigusa", "Haruka", "Futaki", "Kanata"], + 三枝二木: ["Saigusa", "Haruka", "Futaki", "Kanata"], + 稻荷: ["Inari"], + 椎名: ["Shiina"], + "春原阳平&春原芽衣": ["Sunohara", "Youhei", "Sunohara", "Mei"], + 阳平芽衣: ["Sunohara", "Youhei", "Sunohara", "Mei"], + 枣铃: ["Natsume", "Rin"], + 笹濑川佐佐美: ["Sasasegawa", "Sasami"], + 千里朱音: ["Senri", "Akane"], + 多鲁基: ["Dorj"], + 来谷唯湖: ["Kurugaya", "Yuiko"], + 直枝理树: ["Naoe", "Riki"], + 渕田久子: ["Fuchita", "Hisako"], + 日向秀树: ["Hinata", "Hideki"], + 野田: ["Noda"], + 冈崎朋也: ["Okazaki", "Tomoya"], + 古河渚: ["Furukawa", "Nagisa"], + 直井文人: ["Naoi", "Ayato"], + 空门苍: ["Sorakado", "Ao"], + 音无结弦: ["Otonashi", "Yuzuru"], + 立华奏: ["Tachibana", "Kanade"], + 西园美鱼: ["Nishizono", "Mio"], + 西园美鸟: ["Nishizono", "Midori"], + 岬镜子: ["Misaki", "Kyoko"], + 中津静流: ["Nakatsu", "Shizuru"], + "关根诗织&入江美雪": ["Sekine", "Shiori", "Irie", "Miyuki"], + 关根入江: ["Sekine", "Shiori", "Irie", "Miyuki"], + 野村美希: ["Nomura", "Miki"], + 美坂栞: ["Misaka", "Shiori"], + 美坂香里: ["Misaka", "Kaori"], + 水濑秋子: ["Minase", "Akiko"], + 游佐: ["Yusa"], + 松下护騨: ["Matsushita", "Godan"], + 乙坂有宇: ["Otosaka", "Yuu"], + 三谷良一: ["Mitani", "Ryoichi"], + 神户小鸟: ["Kanbe", "Kotori"], + 高城丈士朗: ["Takajyo", "Jyojirou"], + 鸣濑白羽: ["Naruse", "Shiroha"], + 水织静久: ["Mizuori", "Shizuku"], + 铃木央人: ["Suzuki", "Hiroto"], + 凤咲夜: ["Ootori", "Sakuya"], + 成神阳太: ["Narukami", "Youta"], + 七濑留美: ["Nanase", "Rumi"], + 凤千早: ["Ootori", "Chihaya"], + 国崎往人: ["Kunisaki", "Yukito"], + 井上晶: ["Inoue", "Asara"], + 一之濑琴美: ["Ichinose", "Kotomi"], + 藤川米娅: ["Fujikawa", "Mia"], + 雾岛佳乃: ["Kirishima", "Kano"], + 苍井绘梨花: ["Aoi", "Erika"], + 藏里见: ["Kura", "Satomi"], + "喵呜·喵呼": ["Myau", "Mya-fu"], + 喵呜喵呼: ["Myau", "Mya-fu"], + 伊吹风子: ["Ibuki", "Fuuko"], + 久岛鸥: ["Kushima", "Kamome"], + 库特莉亚芙卡: ["Noumi", "Kudryavka"], + 神尾观铃: ["Kamio", "Misuzu"], + 友利奈绪: ["Tomori", "Nao"], + 天王寺瑚太朗: ["Tennouji", "Kotarou"], + 藤林杏: ["Fujibayashi", "Kyou"], + 伊座并杏子: ["Izanami", "Kyouko"], + 加纳天善: ["Kano", "Tenzen"], + 冰室忧希: ["Himuro", "Yuuki"], + 露娜Q: ["Lunar", "Q"], + 远野小满: ["Toono", "Michiru"], + 远野美凪: ["Toono", "Minagi"], + 樱庭星罗: ["Sakuraba", "Seira"], + 坂上智代: ["Sakagami", "Tomoyo"], + 冈崎汐: ["Okazaki", "Ushio"], + 神山识: ["Kamiyama", "Shiki"], + 佐藤雏: ["Satou", "Hina"], + 篝: ["Kagari"], }, }; }); diff --git a/character/extra.js b/character/extra.js index c85d11811..d38d9034e 100755 --- a/character/extra.js +++ b/character/extra.js @@ -1,1796 +1,2586 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'extra', - connect:true, - connectBanned:['shen_diaochan'], - characterSort:{ - extra:{ - extra_feng:['shen_guanyu','shen_lvmeng'], - extra_huo:['shen_zhugeliang','shen_zhouyu'], - extra_lin:['shen_caocao','shen_lvbu'], - extra_shan:['shen_zhaoyun','shen_simayi'], - extra_yin:['shen_liubei','shen_luxun'], - extra_lei:['shen_ganning','shen_zhangliao'], - extra_key:['key_kagari','key_shiki','db_key_hina'], - extra_decade:['shen_jiangwei','shen_machao','shen_zhangfei','shen_zhangjiao','shen_dengai','shen_xuzhu'], - extra_ol:['ol_zhangliao','shen_caopi','shen_zhenji','shen_sunquan'], - extra_mobilezhi:['shen_guojia','shen_xunyu'], - extra_mobilexin:['shen_taishici','shen_sunce'], - extra_mobileren:['shen_huatuo','shen_lusu'], - extra_tw:['tw_shen_guanyu','tw_shen_lvmeng'], - extra_offline:['shen_diaochan','boss_zhaoyun','shen_dianwei','le_shen_jiaxu'], + name: "extra", + connect: true, + connectBanned: ["shen_diaochan"], + characterSort: { + extra: { + extra_feng: ["shen_guanyu", "shen_lvmeng"], + extra_huo: ["shen_zhugeliang", "shen_zhouyu"], + extra_lin: ["shen_caocao", "shen_lvbu"], + extra_shan: ["shen_zhaoyun", "shen_simayi"], + extra_yin: ["shen_liubei", "shen_luxun"], + extra_lei: ["shen_ganning", "shen_zhangliao"], + extra_key: ["key_kagari", "key_shiki", "db_key_hina"], + extra_decade: [ + "shen_jiangwei", + "shen_machao", + "shen_zhangfei", + "shen_zhangjiao", + "shen_dengai", + "shen_xuzhu", + "dc_shen_huatuo", + ], + extra_ol: ["ol_zhangliao", "shen_caopi", "shen_zhenji", "shen_sunquan"], + extra_mobilezhi: ["shen_guojia", "shen_xunyu"], + extra_mobilexin: ["shen_taishici", "shen_sunce"], + extra_mobileren: ["shen_huatuo", "shen_lusu"], + extra_tw: ["tw_shen_guanyu", "tw_shen_lvmeng"], + extra_offline: ["shen_diaochan", "boss_zhaoyun", "shen_dianwei", "le_shen_jiaxu"], }, }, - character:{ - shen_xuzhu:['male','shen',5,['zhengqing','zhuangpo'],['wei']], - shen_lusu:['male','shen',3,['dingzhou','tamo','zhimeng'],['wu']], - shen_huatuo:['male','shen',3,['wuling','youyi'],['qun']], - le_shen_jiaxu:['male','shen',4,['jxlianpo','jxzhaoluan'],['qun']], - shen_dianwei:['male','shen',4,['juanjia','qiexie','cuijue'],['wei']], - shen_dengai:['male','shen',4,['dctuoyu','dcxianjin','dcqijing'],['wei']], - tw_shen_lvmeng:['male','shen',3,['twshelie','twgongxin'],['wu']], - shen_zhangjiao:['male','shen',3,['yizhao','sijun','sanshou','tianjie'],['qun']], - shen_zhangfei:['male','shen',4,['shencai','xunshi'],['shu']], - tw_shen_guanyu:['male','shen',4,['twwushen','twwuhun'],['shu']], - shen_machao:['male','shen',4,['shouli','hengwu'],['shu']], - shen_sunquan:['male','shen',4,['junkyuheng','junkdili'],['wu']], - shen_jiangwei:['male','shen',4,['jiufa','tianren','pingxiang'],['shu']], - key_kagari:['female','shen',3,['kagari_zongsi'],['key']], - key_shiki:['female','shen','3/5',['shiki_omusubi'],['key']], - db_key_hina:['female','key',3,['hina_shenshi','hina_xingzhi'],['doublegroup:key:shen']], + character: { + dc_shen_huatuo: ["male", "shen", 3, ["jingyu", "lvxin", "huandao"], ["qun"]], + shen_xuzhu: ["male", "shen", 5, ["zhengqing", "zhuangpo"], ["wei"]], + shen_lusu: ["male", "shen", 3, ["dingzhou", "tamo", "zhimeng"], ["wu"]], + shen_huatuo: ["male", "shen", 3, ["wuling", "youyi"], ["qun"]], + le_shen_jiaxu: ["male", "shen", 4, ["jxlianpo", "jxzhaoluan"], ["qun"]], + shen_dianwei: ["male", "shen", 4, ["juanjia", "qiexie", "cuijue"], ["wei"]], + shen_dengai: ["male", "shen", 4, ["dctuoyu", "dcxianjin", "dcqijing"], ["wei"]], + tw_shen_lvmeng: ["male", "shen", 3, ["twshelie", "twgongxin"], ["wu"]], + shen_zhangjiao: ["male", "shen", 3, ["yizhao", "sijun", "sanshou", "tianjie"], ["qun"]], + shen_zhangfei: ["male", "shen", 4, ["shencai", "xunshi"], ["shu"]], + tw_shen_guanyu: ["male", "shen", 4, ["twwushen", "twwuhun"], ["shu"]], + shen_machao: ["male", "shen", 4, ["shouli", "hengwu"], ["shu"]], + shen_sunquan: ["male", "shen", 4, ["junkyuheng", "junkdili"], ["wu"]], + shen_jiangwei: ["male", "shen", 4, ["jiufa", "tianren", "pingxiang"], ["shu"]], + key_kagari: ["female", "shen", 3, ["kagari_zongsi"], ["key"]], + key_shiki: ["female", "shen", "3/5", ["shiki_omusubi"], ["key"]], + db_key_hina: ["female", "key", 3, ["hina_shenshi", "hina_xingzhi"], ["doublegroup:key:shen"]], - shen_sunce:['male','shen','1/6',['yingba','scfuhai','pinghe'],['wu']], - shen_xunyu:['male','shen',3,['tianzuo','lingce','dinghan'],['wei','clan:颍川荀氏']], - shen_taishici:['male','shen',4,['dulie','tspowei'],['wu']], - shen_guojia:['male','shen',3,['reshuishi','stianyi','resghuishi'],['wei']], - shen_diaochan:['female','shen',3,['meihun','huoxin'],['qun']], - shen_guanyu:['male','shen',5,['wushen','new_wuhun'],['shu']], - shen_zhaoyun:['male','shen',2,['xinjuejing','relonghun'],['shu']], - shen_zhugeliang:['male','shen',3,['qixing','kuangfeng','dawu'],['shu']], - shen_lvmeng:['male','shen',3,['shelie','gongxin'],['wu']], - shen_zhouyu:['male','shen',4,['yeyan','qinyin'],['wu']], - shen_simayi:['male','shen',4,['renjie','sbaiyin','lianpo'],['wei']], - shen_caocao:['male','shen',3,['new_guixin','feiying'],['wei']], - shen_lvbu:['male','shen',5,['baonu','wumou','ol_wuqian','ol_shenfen'],['qun']], + shen_sunce: ["male", "shen", "1/6", ["yingba", "scfuhai", "pinghe"], ["wu"]], + shen_xunyu: ["male", "shen", 3, ["tianzuo", "lingce", "dinghan"], ["wei", "clan:颍川荀氏"]], + shen_taishici: ["male", "shen", 4, ["dulie", "tspowei"], ["wu"]], + shen_guojia: ["male", "shen", 3, ["reshuishi", "stianyi", "resghuishi"], ["wei"]], + shen_diaochan: ["female", "shen", 3, ["meihun", "huoxin"], ["qun"]], + shen_guanyu: ["male", "shen", 5, ["wushen", "new_wuhun"], ["shu"]], + shen_zhaoyun: ["male", "shen", 2, ["xinjuejing", "relonghun"], ["shu"]], + shen_zhugeliang: ["male", "shen", 3, ["qixing", "kuangfeng", "dawu"], ["shu"]], + shen_lvmeng: ["male", "shen", 3, ["shelie", "gongxin"], ["wu"]], + shen_zhouyu: ["male", "shen", 4, ["yeyan", "qinyin"], ["wu"]], + shen_simayi: ["male", "shen", 4, ["renjie", "sbaiyin", "lianpo"], ["wei"]], + shen_caocao: ["male", "shen", 3, ["new_guixin", "feiying"], ["wei"]], + shen_lvbu: ["male", "shen", 5, ["baonu", "wumou", "ol_wuqian", "ol_shenfen"], ["qun"]], - shen_liubei:["male","shen",6,["nzry_longnu","nzry_jieying"],["shu"]], - shen_luxun:["male","shen",4,["nzry_junlve","nzry_cuike","nzry_dinghuo"],["wu"]], - shen_zhangliao:["male","shen",4,["drlt_duorui","drlt_zhiti"],["wei"]], - shen_ganning:["male","shen","3/6",["drlt_poxi","drlt_jieying"],["wu"]], - ol_zhangliao:['male','shen',4,['olduorui','olzhiti'],['wei']], - shen_caopi:['male','shen',5,['chuyuan','dengji'],['wei']], - shen_zhenji:['female','shen',3,['shenfu','qixian'],['wei']], - boss_zhaoyun:['male','shen',1,['boss_juejing','xinlonghun','zhanjiang'],['shu']], + shen_liubei: ["male", "shen", 6, ["nzry_longnu", "nzry_jieying"], ["shu"]], + shen_luxun: ["male", "shen", 4, ["nzry_junlve", "nzry_cuike", "nzry_dinghuo"], ["wu"]], + shen_zhangliao: ["male", "shen", 4, ["drlt_duorui", "drlt_zhiti"], ["wei"]], + shen_ganning: ["male", "shen", "3/6", ["drlt_poxi", "drlt_jieying"], ["wu"]], + ol_zhangliao: ["male", "shen", 4, ["olduorui", "olzhiti"], ["wei"]], + shen_caopi: ["male", "shen", 5, ["chuyuan", "dengji"], ["wei"]], + shen_zhenji: ["female", "shen", 3, ["shenfu", "qixian"], ["wei"]], + boss_zhaoyun: ["male", "shen", 1, ["boss_juejing", "xinlonghun", "zhanjiang"], ["shu"]], }, - characterIntro:{ - shen_guanyu:'关羽,字云长。曾水淹七军、擒于禁、斩庞德、威震华夏,吓得曹操差点迁都躲避,但是东吴偷袭荆州,关羽兵败被害。后传说吕蒙因关羽之魂索命而死。', - shen_lvmeng:'吕蒙,字子明,汝南富陂人,东吴名将,原有“吴下阿蒙”之贬称,后受孙权劝说,奋发读书,最终成就一代名将。', - shen_zhouyu:'字公瑾,庐江舒县人。东汉末年名将。有姿貌、精音律,江东有“曲有误,周郎顾”之语。周瑜少与孙策交好,后孙策遇刺身亡,孙权继任。周瑜将兵赴丧,以中护军的身份与长史张昭共掌众事,建安十三年(208年),周瑜率东吴军与刘备军联合,在赤壁击败曹操。此战也奠定了三分天下的基础。', - shen_zhugeliang:'字孔明、号卧龙,汉族,琅琊阳都人,三国时期蜀汉丞相、杰出的政治家、军事家、发明家、文学家。在世时被封为武乡侯,死后追谥忠武侯,后来东晋政权推崇诸葛亮军事才能,特追封他为武兴王。诸葛亮为匡扶蜀汉政权,呕心沥血、鞠躬尽瘁、死而后已。其代表作有《前出师表》、《后出师表》、《诫子书》等。曾发明木牛流马等,并改造连弩,可一弩十矢俱发。于234年在宝鸡五丈原逝世。', + characterIntro: { + shen_guanyu: + "关羽,字云长。曾水淹七军、擒于禁、斩庞德、威震华夏,吓得曹操差点迁都躲避,但是东吴偷袭荆州,关羽兵败被害。后传说吕蒙因关羽之魂索命而死。", + shen_lvmeng: + "吕蒙,字子明,汝南富陂人,东吴名将,原有“吴下阿蒙”之贬称,后受孙权劝说,奋发读书,最终成就一代名将。", + shen_zhouyu: + "字公瑾,庐江舒县人。东汉末年名将。有姿貌、精音律,江东有“曲有误,周郎顾”之语。周瑜少与孙策交好,后孙策遇刺身亡,孙权继任。周瑜将兵赴丧,以中护军的身份与长史张昭共掌众事,建安十三年(208年),周瑜率东吴军与刘备军联合,在赤壁击败曹操。此战也奠定了三分天下的基础。", + shen_zhugeliang: + "字孔明、号卧龙,汉族,琅琊阳都人,三国时期蜀汉丞相、杰出的政治家、军事家、发明家、文学家。在世时被封为武乡侯,死后追谥忠武侯,后来东晋政权推崇诸葛亮军事才能,特追封他为武兴王。诸葛亮为匡扶蜀汉政权,呕心沥血、鞠躬尽瘁、死而后已。其代表作有《前出师表》、《后出师表》、《诫子书》等。曾发明木牛流马等,并改造连弩,可一弩十矢俱发。于234年在宝鸡五丈原逝世。", }, - characterReplace:{ - shen_zhangliao:['ol_zhangliao','shen_zhangliao'], - shen_zhaoyun:['shen_zhaoyun','dc_zhaoyun','old_shen_zhaoyun','boss_zhaoyun'], - shen_guanyu:['shen_guanyu','tw_shen_guanyu'], - shen_sunquan:['shen_sunquan','junk_sunquan'], - shen_lvmeng:['shen_lvmeng','tw_shen_lvmeng'], - shen_machao:['shen_machao','ps_shen_machao'], - shen_jiaxu:['le_shen_jiaxu','shen_jiaxu'], - shen_caocao:['shen_caocao','old_caocao'], - shen_zhangjiao:['shen_zhangjiao','junk_zhangjiao'], + characterReplace: { + shen_zhangliao: ["ol_zhangliao", "shen_zhangliao"], + shen_zhaoyun: ["shen_zhaoyun", "dc_zhaoyun", "old_shen_zhaoyun", "boss_zhaoyun"], + shen_guanyu: ["shen_guanyu", "tw_shen_guanyu"], + shen_sunquan: ["shen_sunquan", "junk_sunquan"], + shen_lvmeng: ["shen_lvmeng", "tw_shen_lvmeng"], + shen_machao: ["shen_machao", "ps_shen_machao"], + shen_jiaxu: ["le_shen_jiaxu", "shen_jiaxu"], + shen_caocao: ["shen_caocao", "old_caocao"], + shen_zhangjiao: ["shen_zhangjiao", "junk_zhangjiao"], + shen_huatuo: ["dc_shen_huatuo", "shen_huatuo"], }, - characterFilter:{ - shen_diaochan(mode){ - return mode=='identity'||mode=='doudizhu'||mode=='single'||(mode=='versus'&&_status.mode!='standard'&&_status.mode!='three'); + characterFilter: { + shen_diaochan(mode) { + return ( + mode == "identity" || + mode == "doudizhu" || + mode == "single" || + (mode == "versus" && _status.mode != "standard" && _status.mode != "three") + ); }, - shen_dengai(mode){ - if(['boss','chess','tafang','stone'].includes(mode)) return false; - if(mode=='versus') return _status.mode!='three'; + shen_dengai(mode) { + if (["boss", "chess", "tafang", "stone"].includes(mode)) return false; + if (mode == "versus") return _status.mode != "three"; return true; }, - le_shen_jiaxu(mode){ - return mode=='identity'&&_status.mode!='purple'; + le_shen_jiaxu(mode) { + return mode == "identity" && _status.mode != "purple"; }, }, /** @type { importCharacterConfig['skill'] } */ - skill:{ - //神许褚 - zhengqing:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - filter(){ - return game.hasPlayer(current=>{ - return current.countMark('zhengqing'); - })||lib.skill.zhengqing.getMostInfoLastRound()[0]>0; + skill: { + //十周年神华佗 + jingyu: { + audio: 2, + trigger: { + global: ["useSkill", "logSkillBegin", "useCard", "respond"], }, - getMostInfoLastRound(){ - let max=-1,players=[]; - const history=game.getAllGlobalHistory(); - if(history.length<=2) return [max,players]; - for(let i=history.length-2;i>=0;i--){ - const evts=history[i]['everything'].filter(evt=>{ - if(evt.name!=='damage') return false; - const source=evt.source; - return source&&source.isIn(); + filter(event, player) { + if (["global", "equip"].includes(event.type)) return false; + let skill = event.sourceSkill || event.skill; + if (!skill || skill === "jingyu") return false; + let info = get.info(skill); + while (true) { + if (!info || info.charlotte) return false; + if (info && !info.sourceSkill) break; + skill = info.sourceSkill; + info = get.info(skill); + } + return !player.getStorage("jingyu_used").includes(skill); + }, + forced: true, + async content(event, trigger, player) { + if (!player.storage.jingyu_used) { + player + .when({ global: "roundStart" }) + .assign({ + firstDo: true, + }) + .then(() => delete player.storage.jingyu_used); + } + let skill = trigger.sourceSkill || trigger.skill, + info = get.info(skill); + while (true) { + if (info && !info.sourceSkill) break; + skill = info.sourceSkill; + info = get.info(skill); + } + player.markAuto("jingyu_used", skill); + await player.draw(); + }, + ai: { + threaten: 6, + }, + }, + lvxin: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + filterTarget: lib.filter.notMe, + check(card) { + const round = game.roundNumber, + player = get.player(); + let valueFix = 0; + if (["sha", "shan"].includes(get.name(card, false))) valueFix += 3; + if ( + (round <= 2 && + player.hasCard((card) => { + return ["sha", "shan"].includes(get.name(card)) && get.value(card) <= 3; + })) || + game.hasPlayer((current) => { + return current !== player && get.attitude(player, current) > 0; + }) + ) + return 6 - get.value(card) + valueFix; + return 4.5 - get.value(card) + valueFix; + }, + delay: false, + discard: false, + lose: false, + async content(event, trigger, player) { + const { target, cards } = event, + round = Math.min(5, game.roundNumber); + const name = get.translation(target); + await player.give(cards, target); + const result = await player + .chooseControl(["摸牌", "弃牌"]) + .set("choiceList", [ + `令${name}摸${get.cnNumber(round)}张牌`, + `令${name}随机弃置${get.cnNumber(round)}张手牌`, + ]) + .set("prompt", "滤心:请选择一项") + .set("ai", () => { + return get.event("choice"); + }) + .set("choice", get.attitude(player, target) > 0 ? "摸牌" : "弃牌") + .forResult(); + let cards2 = []; + const makeDraw = result.index === 0; + if (makeDraw) { + cards2 = await target.draw(round).forResult(); + } else { + const cards = target.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, target, "lvxin"); }); - if(evts.length){ - let curMax=-1,curPlayers=[]; - const map={}; - for(const evt of evts){ - const source=evt.source; - const id=source.playerid; - if(typeof map[id]!=='number') map[id]=0; - map[id]+=evt.num; - if(map[id]>curMax){ - curMax=map[id]; - curPlayers=[source]; - } - else if(map[id]==curMax){ + if (cards.length > 0) { + const evt = await target + .discard(cards.randomGets(round)) + .set("discarder", target); + cards2 = evt.done.cards2; + } + } + const cardName = get.name(cards[0], player); + if ( + cards2.some((card) => { + return get.name(card, target) === cardName; + }) + ) { + const skillName = `lvxin_${makeDraw ? "recover" : "lose"}`; + target.addSkill(skillName); + target.addMark(skillName, 1, false); + } + }, + subSkill: { + recover: { + trigger: { + player: ["useSkill", "logSkillBegin", "useCard", "respond"], + }, + filter(event, player) { + if (["global", "equip"].includes(event.type)) return false; + const skill = event.sourceSkill || event.skill; + const info = get.info(skill); + return info && !info.charlotte; + }, + forced: true, + onremove: true, + charlotte: true, + async content(event, trigger, player) { + player.loseHp(player.countMark("lvxin_recover")); + player.removeSkill("lvxin_recover"); + }, + intro: { + content: "下次发动技能时回复#点体力", + }, + }, + lose: { + trigger: { + player: ["useSkill", "logSkillBegin", "useCard", "respond"], + }, + filter(event, player) { + if (["global", "equip"].includes(event.type)) return false; + const skill = event.sourceSkill || event.skill; + const info = get.info(skill); + return info && !info.charlotte; + }, + forced: true, + onremove: true, + charlotte: true, + async content(event, trigger, player) { + player.loseHp(player.countMark("lvxin_lose")); + player.removeSkill("lvxin_lose"); + }, + intro: { + content: "下次发动技能时失去#点体力", + }, + }, + }, + ai: { + order: 5, + result: { + target(player, target) { + const round = game.roundNumber; + if ( + round <= 2 && + target.countCards("h") > round * 2 && + player.getCards("h").some((card) => { + return ["sha", "shan"].includes(get.name(card)) && get.value(card) <= 3; + }) + ) + return 1; + if (get.attitude(player, target) > 0) { + return round + Math.sqrt(1 + target.getDamagedHp()); + } + return -(round + Math.sqrt(Math.max(0, 2 - target.getHp()))); + }, + }, + }, + }, + huandao: { + audio: 2, + enable: "phaseUse", + usable: 1, + limited: true, + filterTarget: lib.filter.notMe, + skillAnimation: true, + animationColor: "metal", + async content(event, trigger, player) { + player.awakenSkill("huandao"); + const { target } = event; + await target.turnOver(false); + await target.link(false); + let names = [target.name1 || target.name]; + if (target.name2) names.add(target.name2); + names = names.map((name) => get.rawName(name)); + if (!_status.characterlist) lib.skill.pingjian.initList(); + _status.characterlist.randomSort(); + let ownedSkills = target.getSkills(null, false, false), + ownedSkillsName = ownedSkills.map((skill) => get.translation(skill)); + let skillToGain = null; + outer: for (const name of _status.characterlist) { + const info = lib.character[name]; + if (!names.includes(get.rawName(name))) continue; + const skills = info[3].slice().randomSort(); + while (skills.length) { + const skill = skills.shift(), + skillName = get.translation(skill); + if (!ownedSkillsName.includes(skillName)) { + skillToGain = skill; + break outer; + } + } + } + if (!skillToGain) return; + player.popup(skillToGain); + player.line(target, "green"); + let prompt2 = "若你选择是,则你于获得此技能后须失去一个其他技能。

              "; + if (lib.skill[skillToGain].nobracket) { + prompt2 += `
              ${get.translation( + skillToGain + )}
              ${get.skillInfoTranslation( + skillToGain + )}


              `; + } else { + const translation = + lib.translate[skillToGain + "_ab"] || get.translation(skillToGain).slice(0, 2); + prompt2 += `
              【${translation}】
              ${get.skillInfoTranslation( + skillToGain + )}


              `; + } + const bool = await target + .chooseBool(`寰道:是否获得技能〖${get.translation(skillToGain)}〗?`, prompt2) + .set( + "choice", + (() => { + const rank = get.skillRank(skillToGain, "inout") + 1; + return ownedSkills.some((skill) => { + const info = get.info(skill); + if (info) { + if ( + target.awakenedSkills.includes(skill) && + (info.limited || info.juexingji || info.dutySkill) + ) + return true; + if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; + } + return get.skillRank(skill, "inout") < rank; + }); + })() + ) + .forResultBool(); + if (!bool) { + target.chat("拒绝"); + game.log(target, "拒绝获得技能", `#g【${get.translation(skillToGain)}】`); + await game.asyncDelay(); + return; + } + await target.addSkills(skillToGain); + ownedSkills = target.getSkills(null, false, false).filter((skill) => { + if (skill === skillToGain) return false; + const info = get.info(skill); + if (!info || info.charlotte || !get.skillInfoTranslation(skill, player).length) + return false; + return true; + }); + if (!ownedSkills) return; + const control = await target + .chooseControl(ownedSkills) + .set( + "choiceList", + ownedSkills.map((skill) => { + return `
              【${get.translation( + lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2) + )}】
              ${get.skillInfoTranslation(skill, target)}
              `; + }) + ) + .set("displayIndex", false) + .set("prompt", "寰道:选择失去一个技能") + .set("ai", () => { + return get.event("choice"); + }) + .set( + "choice", + (() => { + const uselessSkills = ownedSkills.filter((skill) => { + const info = get.info(skill); + if (!info) return false; + if ( + target.awakenedSkills.includes(skill) && + (info.limited || info.juexingji || info.dutySkill) + ) + return true; + if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; + return false; + }); + if (uselessSkills.length) return uselessSkills.randomGet(); + return ownedSkills.sort((a, b) => { + return get.skillRank(a, "inout") - get.skillRank(b, "inout"); + })[0]; + })() + ) + .forResultControl(); + await target.removeSkills(control); + }, + ai: { + order: 5, + result: { + target(player, target) { + if ( + game.roundNumber * game.countPlayer() <= + (1.5 * game.countPlayer2()) / Math.sqrt(player.getDamagedHp() + 1) + ) + return 0; + const ownedSkills = target.getSkills(null, false, false).filter((skill) => { + const info = get.info(skill); + if ( + !info || + info.charlotte || + !get.skillInfoTranslation(skill, player).length + ) + return false; + return true; + }); + const uselessSkills = ownedSkills.filter((skill) => { + const info = get.info(skill); + if (!info) return false; + if ( + target.awakenedSkills.includes(skill) && + (info.limited || info.juexingji || info.dutySkill) + ) + return true; + if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; + return false; + }); + if (uselessSkills.length) return 3; + let names = [target.name1 || target.name]; + if (target.name2) names.add(target.name2); + names = names.map((name) => get.rawName(name)); + if (_status.characterlist.some((name) => names.includes(get.rawName(name)))) + return 1; + return 0; + }, + }, + }, + }, + //神许褚 + zhengqing: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + filter() { + return ( + game.hasPlayer((current) => { + return current.countMark("zhengqing"); + }) || lib.skill.zhengqing.getMostInfoLastRound()[0] > 0 + ); + }, + getMostInfoLastRound() { + let max = -1, + players = []; + const history = game.getAllGlobalHistory(); + if (history.length <= 2) return [max, players]; + for (let i = history.length - 2; i >= 0; i--) { + const evts = history[i]["everything"].filter((evt) => { + if (evt.name !== "damage") return false; + const source = evt.source; + return source && source.isIn(); + }); + if (evts.length) { + let curMax = -1, + curPlayers = []; + const map = {}; + for (const evt of evts) { + const source = evt.source; + const id = source.playerid; + if (typeof map[id] !== "number") map[id] = 0; + map[id] += evt.num; + if (map[id] > curMax) { + curMax = map[id]; + curPlayers = [source]; + } else if (map[id] == curMax) { curPlayers.add(source); } } - if(curMax>max){ - max=curMax; - players=curPlayers.slice(); - } - else if(curMax===max){ + if (curMax > max) { + max = curMax; + players = curPlayers.slice(); + } else if (curMax === max) { players.addArray(curPlayers); } } - if(history[i].isRound) break; + if (history[i].isRound) break; } - return [max,players]; + return [max, players]; }, - async content(event,trigger,player){ - game.countPlayer(current=>{ - if(current.hasMark('zhengqing')) current.clearMark('zhengqing'); + async content(event, trigger, player) { + game.countPlayer((current) => { + if (current.hasMark("zhengqing")) current.clearMark("zhengqing"); }); - const [num,players]=lib.skill.zhengqing.getMostInfoLastRound(); - player.line(players,'thunder'); - const onlyMe=players.length===1&&players[0]===player; - const isMax=(player.getAllHistory('custom',evt=>evt&&evt.zhengqing_count).map(evt=>evt.zhengqing_count).sort((a,b)=>b-a)[0]||0)<=num; - players.forEach(current=>{ - current.addMark('zhengqing',num); - }) - if(onlyMe&&isMax){ - player.draw(Math.min(5,num)); - player.getHistory('custom').push({zhengqing_count:num}); - } - else{ - const drawers=[player].concat(players).sortBySeat(trigger.player); - for(const drawer of drawers){ + const [num, players] = lib.skill.zhengqing.getMostInfoLastRound(); + player.line(players, "thunder"); + const onlyMe = players.length === 1 && players[0] === player; + const isMax = + (player + .getAllHistory("custom", (evt) => evt && evt.zhengqing_count) + .map((evt) => evt.zhengqing_count) + .sort((a, b) => b - a)[0] || 0) <= num; + players.forEach((current) => { + current.addMark("zhengqing", num); + }); + if (onlyMe && isMax) { + player.draw(Math.min(5, num)); + player.getHistory("custom").push({ zhengqing_count: num }); + } else { + const drawers = [player].concat(players).sortBySeat(trigger.player); + for (const drawer of drawers) { await drawer.draw(); } } }, - marktext:'擎', - intro:{ - name:'争擎', - name2:'擎', - content:'mark', + marktext: "擎", + intro: { + name: "争擎", + name2: "擎", + content: "mark", }, }, - zhuangpo:{ - audio:2, - enable:'chooseToUse', - onChooseToUse(event){ - if(!game.online&&!event.zhuangpo_cards){ - event.set('zhuangpo_cards',event.player.getCards('hes',card=>{ - if(get.name(card,event.player)=='sha') return true; - const str=lib.skill.shencai.getStr(card); - return str.includes('【杀】'); - })); + zhuangpo: { + audio: 2, + enable: "chooseToUse", + onChooseToUse(event) { + if (!game.online && !event.zhuangpo_cards) { + event.set( + "zhuangpo_cards", + event.player.getCards("hes", (card) => { + if (get.name(card, event.player) == "sha") return true; + const str = lib.skill.shencai.getStr(card); + return str.includes("【杀】"); + }) + ); } }, - viewAs:{ - name:'juedou', - storage:{zhuangpo:true}, + viewAs: { + name: "juedou", + storage: { zhuangpo: true }, }, - viewAsFilter(){ - return get.event('zhuangpo_cards').length>0; + viewAsFilter() { + return get.event("zhuangpo_cards").length > 0; }, - prompt:'将一张牌面信息包含“【杀】”的牌当【决斗】使用', - filterCard(card,player){ - return get.event('zhuangpo_cards').includes(card); + prompt: "将一张牌面信息包含“【杀】”的牌当【决斗】使用", + filterCard(card, player) { + return get.event("zhuangpo_cards").includes(card); }, - position:'hes', - precontent(){ - player.addTempSkill('zhuangpo_effect'); + position: "hes", + precontent() { + player.addTempSkill("zhuangpo_effect"); }, - subSkill:{ - effect:{ - trigger:{ - player:'useCardToPlayered', + subSkill: { + effect: { + trigger: { + player: "useCardToPlayered", }, - filter(event,player){ - const card=event.card; - if(!card||!card.storage||!card.storage.zhuangpo) return false; - return player.hasMark('zhengqing'); + filter(event, player) { + const card = event.card; + if (!card || !card.storage || !card.storage.zhuangpo) return false; + return player.hasMark("zhengqing"); }, - direct:true, - charlotte:true, - group:'zhuangpo_damage', - async content(event,trigger,player){ - const target=trigger.target; - const list=Array.from({length:player.countMark('zhengqing')},(_,i)=>{ - return get.cnNumber(i+1,true); + direct: true, + charlotte: true, + group: "zhuangpo_damage", + async content(event, trigger, player) { + const target = trigger.target; + const list = Array.from({ length: player.countMark("zhengqing") }, (_, i) => { + return get.cnNumber(i + 1, true); }); - const result=await player.chooseControl(list,'cancel2') - .set('prompt','壮魄:是否移去任意枚“擎”?') - .set('prompt2',`若如此做,${get.translation(target)}须弃置等量的牌`) - .set('ai',()=>get.event('choice')) - .set('choice',(()=>{ - if(get.attitude(player,target)>=0) return 'cancel2'; - const markCount=list.length; - const cards=target.getCards('he',card=>lib.filter.cardDiscardable(card,target)); - let allIn=false; - if(player.hp<2||target.hp+target.countCards('h',card=>target.canSaveCard(card,target))<=1+trigger.targets.some(current=>current.hasMark('zhengqing'))) allIn=true; - if(cards.map(card=>get.value(card)).reduce((p,c)=>p+c,0)/cards.length>5) allIn=true; - if(!player.isPhaseUsing()||!player.hasCard(card=>{ - if(!lib.skill.shencai.getStr(card).includes('【杀】')) return false; - return player.hasValueTarget(get.autoViewAs({name:'juedou'},[card])); - })) allIn=true; - const maxCount=Math.min(markCount,cards.length); - const toRemoveCount=allIn?maxCount:Math.ceil(Math.random()*maxCount); - return get.cnNumber(toRemoveCount,true); - })()) + const result = await player + .chooseControl(list, "cancel2") + .set("prompt", "壮魄:是否移去任意枚“擎”?") + .set("prompt2", `若如此做,${get.translation(target)}须弃置等量的牌`) + .set("ai", () => get.event("choice")) + .set( + "choice", + (() => { + if (get.attitude(player, target) >= 0) return "cancel2"; + const markCount = list.length; + const cards = target.getCards("he", (card) => + lib.filter.cardDiscardable(card, target) + ); + let allIn = false; + if ( + player.hp < 2 || + target.hp + + target.countCards("h", (card) => + target.canSaveCard(card, target) + ) <= + 1 + + trigger.targets.some((current) => + current.hasMark("zhengqing") + ) + ) + allIn = true; + if ( + cards.map((card) => get.value(card)).reduce((p, c) => p + c, 0) / + cards.length > + 5 + ) + allIn = true; + if ( + !player.isPhaseUsing() || + !player.hasCard((card) => { + if (!lib.skill.shencai.getStr(card).includes("【杀】")) + return false; + return player.hasValueTarget( + get.autoViewAs({ name: "juedou" }, [card]) + ); + }) + ) + allIn = true; + const maxCount = Math.min(markCount, cards.length); + const toRemoveCount = allIn + ? maxCount + : Math.ceil(Math.random() * maxCount); + return get.cnNumber(toRemoveCount, true); + })() + ) .forResult(); - if(result.control==='cancel2') return; - const toRemoveCount=result.index+1; - player.logSkill('zhuangpo_effect',target); - player.popup(get.cnNumber(toRemoveCount)+'张'); - player.removeMark('zhengqing',toRemoveCount); - target.chooseToDiscard('he',toRemoveCount,true); - } - }, - damage:{ - audio:'zhuangpo', - trigger:{source:'damageBegin1'}, - filter(event,player){ - const card=event.card; - if(!card||!card.storage||!card.storage.zhuangpo) return false; - const evt=event.getParent(2); - return evt.targets&&evt.targets.some(current=>current.hasMark('zhengqing')); + if (result.control === "cancel2") return; + const toRemoveCount = result.index + 1; + player.logSkill("zhuangpo_effect", target); + player.popup(get.cnNumber(toRemoveCount) + "张"); + player.removeMark("zhengqing", toRemoveCount); + target.chooseToDiscard("he", toRemoveCount, true); }, - charlotte:true, - forced:true, - async content(event,trigger){ + }, + damage: { + audio: "zhuangpo", + trigger: { source: "damageBegin1" }, + filter(event, player) { + const card = event.card; + if (!card || !card.storage || !card.storage.zhuangpo) return false; + const evt = event.getParent(2); + return evt.targets && evt.targets.some((current) => current.hasMark("zhengqing")); + }, + charlotte: true, + forced: true, + async content(event, trigger) { trigger.num++; }, }, }, }, //神鲁肃 - dingzhou:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - const num=player.countCards('he'); - return game.hasPlayer(current=>{ - if(current==player) return false; - const total=current.countCards('ej'); - return total>0&&num>total; + dingzhou: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + const num = player.countCards("he"); + return game.hasPlayer((current) => { + if (current == player) return false; + const total = current.countCards("ej"); + return total > 0 && num > total; }); }, - filterCard:true, - selectCard(){ - return [1,Math.max(...game.filterPlayer(i=>i!=get.player()).map(i=>i.countCards('ej')))+1]; + filterCard: true, + selectCard() { + return [ + 1, + Math.max( + ...game.filterPlayer((i) => i != get.player()).map((i) => i.countCards("ej")) + ) + 1, + ]; }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - filterTarget(card,player,target){ - const num=target.countCards('ej'); - if(!num) return false; - return ui.selected.cards.length==num+1&&player!=target; + filterTarget(card, player, target) { + const num = target.countCards("ej"); + if (!num) return false; + return ui.selected.cards.length == num + 1 && player != target; }, - filterOk(){ - return ui.selected.cards.length==ui.selected.targets[0].countCards('ej')+1; + filterOk() { + return ui.selected.cards.length == ui.selected.targets[0].countCards("ej") + 1; }, - position:'he', - lose:false, - discard:false, - delay:false, - async content(event,trigger,player){ - const target=event.targets[0]; - await player.give(event.cards,target); - const cards=target.getGainableCards(player,'ej'); - if(cards.length) player.gain(cards,'give',target); + position: "he", + lose: false, + discard: false, + delay: false, + async content(event, trigger, player) { + const target = event.targets[0]; + await player.give(event.cards, target); + const cards = target.getGainableCards(player, "ej"); + if (cards.length) player.gain(cards, "give", target); }, - ai:{ - order:9, - result:{ - target(player,target){ - let eff=0; - if(ui.selected.cards.length) eff=ui.selected.cards.map(card=>get.value(card)).reduce((p,c)=>p+c,0); - if(player.hasSkill('zhimeng')) eff*=1+get.sgnAttitude(player,target)*0.15; - const es=target.getCards('e'),js=target.getCards('j'); - es.forEach(card=>{ - eff-=get.value(card,target); + ai: { + order: 9, + result: { + target(player, target) { + let eff = 0; + if (ui.selected.cards.length) + eff = ui.selected.cards + .map((card) => get.value(card)) + .reduce((p, c) => p + c, 0); + if (player.hasSkill("zhimeng")) eff *= 1 + get.sgnAttitude(player, target) * 0.15; + const es = target.getCards("e"), + js = target.getCards("j"); + es.forEach((card) => { + eff -= get.value(card, target); }); - js.forEach(card=>{ - eff-=get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },target,target); + js.forEach((card) => { + eff -= get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + target, + target + ); }); return eff; - } + }, }, }, }, - tamo:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + tamo: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.countPlayer(current=>{ - return !current.isZhu2(); - })>1; + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + game.countPlayer((current) => { + return !current.isZhu2(); + }) > 1 + ); }, - direct:true, - changeSeat:true, - async content(event,trigger,player){ - const toSortPlayers=game.filterPlayer(current=>!current.isZhu2()); - toSortPlayers.sortBySeat(game.findPlayer2(current=>current.getSeatNum()==1,true)); - const next=player.chooseToMove('榻谟:是否分配所有角色的座次?'); - next.set('list',[ - ['(以下排列的顺序即为发动技能后角色的座次顺序)', - [toSortPlayers.map(i=>`${i.getSeatNum()}|${i.name}`),(item,type,position,noclick,node)=>{ - const info=item.split('|'),_item=item; - const seat=parseInt(info[0]); - item=info[1]; - if(node){ - node.classList.add('button'); - node.classList.add('character'); - node.style.display=''; - } - else{ - node=ui.create.div('.button.character',position); - } - node._link=item; - node.link=item; - - const func=function(node,item){ - const currentPlayer=game.findPlayer(current=>current.getSeatNum()==seat); - if(currentPlayer.classList.contains('unseen_show')) node.setBackground('hidden_image','character'); - else if(item!='unknown') node.setBackground(item,'character'); - if(node.node){ - node.node.name.remove(); - node.node.hp.remove(); - node.node.group.remove(); - node.node.intro.remove(); - if(node.node.replaceButton) node.node.replaceButton.remove(); + direct: true, + changeSeat: true, + derivation: "tamo_faq", + async content(event, trigger, player) { + const toSortPlayers = game.filterPlayer((current) => { + return ( + !current.isZhu2() || + get.mode() == "doudizhu" && current.getSeatNum() == 3 + ); + }); + toSortPlayers.sortBySeat(game.findPlayer2((current) => current.getSeatNum() == 1, true)); + const next = player.chooseToMove("榻谟:是否分配" + + (game.countPlayer() > toSortPlayers.length ? + "除主公" + (get.mode() == "doudizhu" ? "和三号位外" : "外") : "") + + "所有角色的座次?" + ); + next.set("list", [ + [ + "(以下排列的顺序即为发动技能后角色的座次顺序)", + [ + toSortPlayers.map((i) => `${i.getSeatNum()}|${i.name}`), + (item, type, position, noclick, node) => { + const info = item.split("|"), + _item = item; + const seat = parseInt(info[0]); + item = info[1]; + if (node) { + node.classList.add("button"); + node.classList.add("character"); + node.style.display = ""; + } else { + node = ui.create.div(".button.character", position); } - node.node={ - name:ui.create.div('.name',node), - group:ui.create.div('.identity',node), - intro:ui.create.div('.intro',node), + node._link = item; + node.link = item; + + const func = function (node, item) { + const currentPlayer = game.findPlayer( + (current) => current.getSeatNum() == seat + ); + if (currentPlayer.classList.contains("unseen_show")) + node.setBackground("hidden_image", "character"); + else if (item != "unknown") node.setBackground(item, "character"); + if (node.node) { + node.node.name.remove(); + node.node.hp.remove(); + node.node.group.remove(); + node.node.intro.remove(); + if (node.node.replaceButton) node.node.replaceButton.remove(); + } + node.node = { + name: ui.create.div(".name", node), + group: ui.create.div(".identity", node), + intro: ui.create.div(".intro", node), + }; + const infoitem = [ + currentPlayer.sex, + currentPlayer.group, + `${currentPlayer.hp}/${currentPlayer.maxHp}/${currentPlayer.hujia}`, + ]; + node.node.name.innerHTML = get.slimName(item); + if ( + lib.config.buttoncharacter_style == "default" || + lib.config.buttoncharacter_style == "simple" + ) { + if (lib.config.buttoncharacter_style == "simple") { + node.node.group.style.display = "none"; + } + node.classList.add("newstyle"); + node.node.name.dataset.nature = get.groupnature( + get.bordergroup(infoitem) + ); + node.node.group.dataset.nature = get.groupnature( + get.bordergroup(infoitem), + "raw" + ); + } + node.node.name.style.top = "8px"; + if (node.node.name.querySelectorAll("br").length >= 4) { + node.node.name.classList.add("long"); + if (lib.config.buttoncharacter_style == "old") { + node.addEventListener("mouseenter", ui.click.buttonnameenter); + node.addEventListener("mouseleave", ui.click.buttonnameleave); + } + } + node.node.intro.innerHTML = lib.config.intro; + if (!noclick) { + lib.setIntro(node); + } + node.node.group.innerHTML = `
              ${get.cnNumber( + seat, + true + )}号
              `; + node.node.group.style.backgroundColor = get.translation( + `${get.bordergroup(infoitem)}Color` + ); }; - const infoitem=[currentPlayer.sex,currentPlayer.group,`${currentPlayer.hp}/${currentPlayer.maxHp}/${currentPlayer.hujia}`]; - node.node.name.innerHTML=get.slimName(item); - if(lib.config.buttoncharacter_style=='default'||lib.config.buttoncharacter_style=='simple'){ - if(lib.config.buttoncharacter_style=='simple'){ - node.node.group.style.display='none'; - } - node.classList.add('newstyle'); - node.node.name.dataset.nature=get.groupnature(get.bordergroup(infoitem)); - node.node.group.dataset.nature=get.groupnature(get.bordergroup(infoitem),'raw'); - } - node.node.name.style.top='8px'; - if(node.node.name.querySelectorAll('br').length>=4){ - node.node.name.classList.add('long'); - if(lib.config.buttoncharacter_style=='old'){ - node.addEventListener('mouseenter',ui.click.buttonnameenter); - node.addEventListener('mouseleave',ui.click.buttonnameleave); - } - } - node.node.intro.innerHTML=lib.config.intro; - if(!noclick){ - lib.setIntro(node); - } - node.node.group.innerHTML=`
              ${get.cnNumber(seat,true)}号
              `; - node.node.group.style.backgroundColor=get.translation(`${get.bordergroup(infoitem)}Color`); - }; - node.refresh=func; - node.refresh(node,item); + node.refresh = func; + node.refresh(node, item); - node.link=_item; - node.seatNumber=seat; - node._customintro=(uiintro)=>{ - uiintro.add(`${get.translation(node._link)}(原${get.cnNumber(node.seatNumber,true)}号位)`); - }; - return node; - }] - ] + node.link = _item; + node.seatNumber = seat; + node._customintro = (uiintro) => { + uiintro.add( + `${get.translation(node._link)}(原${get.cnNumber( + node.seatNumber, + true + )}号位)` + ); + }; + return node; + }, + ], + ], ]); - next.set('processAI',list=>{ - const listx=list[0][1][0]; - const me=listx.find(info=>parseInt(info.split('|')[0])==get.player().getSeatNum()); + next.set("processAI", (list) => { + const listx = list[0][1][0]; + const me = listx.find( + (info) => parseInt(info.split("|")[0]) == get.player().getSeatNum() + ); listx.randomSort(); - if(me){ + if (me) { listx.remove(me); listx.unshift(me); } return [listx]; }); - const {result}=await next; - if(!result.bool) return; - player.logSkill('tamo'); - const resultList=result.moved[0].map(info=>{ - return parseInt(info.split('|')[0]); + const { result } = await next; + if (!result.bool) return; + await player.logSkill("tamo"); + const resultList = result.moved[0].map((info) => { + return parseInt(info.split("|")[0]); }); - const toSwapList=[]; - const cmp=(a,b)=>{ - return resultList.indexOf(a)-resultList.indexOf(b); - } - for(let i=0;i { + return resultList.indexOf(a) - resultList.indexOf(b); + }; + for (let i = 0; i < toSortPlayers.length; i++) { + for (let j = 0; j < toSortPlayers.length; j++) { + if (cmp(toSortPlayers[i].getSeatNum(), toSortPlayers[j].getSeatNum()) < 0) { + toSwapList.push([toSortPlayers[i], toSortPlayers[j]]); + [toSortPlayers[i], toSortPlayers[j]] = [toSortPlayers[j], toSortPlayers[i]]; } } } - game.broadcastAll((toSwapList)=>{ - for(const list of toSwapList){ - game.swapSeat(list[0],list[1],false); + game.broadcastAll((toSwapList) => { + for (const list of toSwapList) { + game.swapSeat(list[0], list[1], false); } - },toSwapList); + }, toSwapList); + if (trigger.name === "phase" && !trigger.player.isZhu2() && trigger.player !== toSortPlayers[0] && !trigger._finished) { + trigger.finish(); + trigger._triggered = 5; + const evt = toSortPlayers[0].insertPhase(); + delete evt.skill; + const evt2 = trigger.getParent(); + if (evt2.name == "phaseLoop" && evt2._isStandardLoop) { + evt2.player = toSortPlayers[0]; + } + //跳过新回合的phaseBefore + evt.pushHandler("onPhase", (event, option) => { + if ( + event.step === 0 && + option.state === "begin" + ) { + event.step = 1; + } + }); + } await game.asyncDelay(); - } + }, }, //什么均贫卡 - zhimeng:{ - audio:2, - trigger:{player:'phaseAfter'}, - filter(event,player){ - return game.hasPlayer(current=>{ - return current.countCards('h')+player.countCards('h')>0&&player!=current; - }) - }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('zhimeng'),'与一名其他角色平分手牌',(card,player,target)=>{ - return target.countCards('h')+player.countCards('h')>0&&player!=target; - }).set('ai',target=>{ - const player=get.player(); - const pvalue=-player.getCards('h').map(card=>get.value(card,player)).reduce((p,c)=>p+c,0); - const tvalue=-target.getCards('h').map(card=>get.value(card,target)).reduce((p,c)=>p+c,0)*get.sgnAttitude(player,target); - return (pvalue+tvalue)/2; + zhimeng: { + audio: 2, + trigger: { player: "phaseAfter" }, + filter(event, player) { + return game.hasPlayer(target => { + if (target == player || target.countCards('h') + player.countCards('h') == 0) return false; + return get.mode() == 'identity' || target.countCards('h') <= player.countCards('h') + 1; }); - if(!bool) return; - const target=targets[0]; - player.logSkill('zhimeng',target); - const lose_list=[]; - let cards=[]; - [player,target].forEach(current=>{ - const hs=current.getCards('h'); - if(hs.length){ + }, + direct: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("zhimeng"), + "与一名其他角色平分手牌", + (card, player, target) => { + if (target == player || target.countCards('h') + player.countCards('h') == 0) return false; + return get.mode() == 'identity' || target.countCards('h') <= player.countCards('h') + 1; + } + ) + .set("ai", (target) => { + const player = get.player(); + const pvalue = -player + .getCards("h") + .map((card) => get.value(card, player)) + .reduce((p, c) => p + c, 0); + const tvalue = + -target + .getCards("h") + .map((card) => get.value(card, target)) + .reduce((p, c) => p + c, 0) * get.sgnAttitude(player, target); + return (pvalue + tvalue) / 2; + }); + if (!bool) return; + const target = targets[0]; + player.logSkill("zhimeng", target); + const lose_list = []; + let cards = []; + [player, target].forEach((current) => { + const hs = current.getCards("h"); + if (hs.length) { cards.addArray(hs); - current.$throw(hs.length,500); - game.log(current,'将',get.cnNumber(hs.length),'张牌置入了处理区'); - lose_list.push([current,hs]); + current.$throw(hs.length, 500); + game.log(current, "将", get.cnNumber(hs.length), "张牌置入了处理区"); + lose_list.push([current, hs]); } }); - await game.loseAsync({ - lose_list:lose_list, - }).setContent('chooseToCompareLose'); + await game + .loseAsync({ + lose_list: lose_list, + }) + .setContent("chooseToCompareLose"); await game.asyncDelay(); - cards=cards.filterInD(); - const pcards=cards.randomGets(Math.ceil(cards.length/2)); - const tcards=cards.removeArray(pcards); - const list=[]; - if(pcards.length){ - list.push([player,pcards]); - game.log(player,'获得了',get.cnNumber(pcards.length),'张牌'); + cards = cards.filterInD(); + const pcards = cards.randomGets(Math.ceil(cards.length / 2)); + const tcards = cards.removeArray(pcards); + const list = []; + if (pcards.length) { + list.push([player, pcards]); + game.log(player, "获得了", get.cnNumber(pcards.length), "张牌"); } - if(tcards.length){ - list.push([target,tcards]); - game.log(target,'获得了',get.cnNumber(tcards.length),'张牌'); + if (tcards.length) { + list.push([target, tcards]); + game.log(target, "获得了", get.cnNumber(tcards.length), "张牌"); } game.loseAsync({ - gain_list:list, - player:player, - animate:'draw', - }).setContent('gaincardMultiple'); + gain_list: list, + player: player, + animate: "draw", + }).setContent("gaincardMultiple"); }, - ai:{ - threaten:4, + ai: { + threaten: 4, }, }, //神华佗 - wuling:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>lib.skill.wuling.filterTarget(null,player,target)); + wuling: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => lib.skill.wuling.filterTarget(null, player, target)); }, - filterTarget(card,player,target){ - return !target.hasSkill('wuling_wuqinxi'); + filterTarget(card, player, target) { + return !target.hasSkill("wuling_wuqinxi"); }, - usable:2, - prompt:'选择一名角色,向其传授“五禽戏”', - group:'wuling_die', - content(){ - 'step 0' - target.addAdditionalSkill(`wuling_${player.playerid}`,'wuling_wuqinxi'); - var next=player.chooseToMove(`五灵:调整向${get.translation(target)}传授的“五禽戏”顺序`); - next.set('list',[ - ['',[lib.skill.wuling.wuqinxi,(item,type,position,noclick,node)=>{ - node=ui.create.buttonPresets.vcard(item,type,position,noclick); - node._customintro=[ - node=>`五禽戏:${node.link[2]}`, - node=>lib.skill.wuling.wuqinxiMap[lib.skill.wuling.wuqinxi.indexOf(node.link[2])].slice(2) - ]; - return node; - }]] + usable: 2, + prompt: "选择一名角色,向其传授“五禽戏”", + group: "wuling_die", + content() { + "step 0"; + target.addAdditionalSkill(`wuling_${player.playerid}`, "wuling_wuqinxi"); + var next = player.chooseToMove( + `五灵:调整向${get.translation(target)}传授的“五禽戏”顺序` + ); + next.set("list", [ + [ + "", + [ + lib.skill.wuling.wuqinxi, + (item, type, position, noclick, node) => { + node = ui.create.buttonPresets.vcard(item, type, position, noclick); + node._customintro = [ + (node) => `五禽戏:${node.link[2]}`, + (node) => + lib.skill.wuling.wuqinxiMap[ + lib.skill.wuling.wuqinxi.indexOf(node.link[2]) + ].slice(2), + ]; + return node; + }, + ], + ], ]); - next.set('processAI',()=>{ - const event=get.event().getParent(),player=event.player,target=event.target; - const spirits=[]; - let nextPlayer=player; - do{ - nextPlayer=nextPlayer.getNext(); - if(get.attitude(player,nextPlayer)<0){ - spirits.add('熊'); + next.set("processAI", () => { + const event = get.event().getParent(), + player = event.player, + target = event.target; + const spirits = []; + let nextPlayer = player; + do { + nextPlayer = nextPlayer.getNext(); + if (get.attitude(player, nextPlayer) < 0) { + spirits.add("熊"); break; } - } - while(nextPlayer!=target); - if(!spirits.length) spirits.add('猿'); - if(get.recoverEffect(target,player,player)>0||target.hasCard(card=>{ - return get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },target,target)<-1; - },'j')) spirits.add('鹿'); - const others=lib.skill.wuling.wuqinxi.slice().removeArray(spirits); - do{ + } while (nextPlayer != target); + if (!spirits.length) spirits.add("猿"); + if ( + get.recoverEffect(target, player, player) > 0 || + target.hasCard((card) => { + return ( + get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + target, + target + ) < -1 + ); + }, "j") + ) + spirits.add("鹿"); + const others = lib.skill.wuling.wuqinxi.slice().removeArray(spirits); + do { others.randomSort(); - } - while(others.length>1&&others[0]=='鹿'); - return [spirits.concat(others).map(i=>['','',i])]; - }) - 'step 1' - var sortedWuqinxi=result.moved[0].map(i=>i[2]); - game.log(target,'习得的五禽戏顺序为','#g'+sortedWuqinxi.join('、')); + } while (others.length > 1 && others[0] == "鹿"); + return [spirits.concat(others).map((i) => ["", "", i])]; + }); + "step 1"; + var sortedWuqinxi = result.moved[0].map((i) => i[2]); + game.log(target, "习得的五禽戏顺序为", "#g" + sortedWuqinxi.join("、")); sortedWuqinxi.unshift(sortedWuqinxi[0]); - target.storage.wuling_wuqinxi=sortedWuqinxi; + target.storage.wuling_wuqinxi = sortedWuqinxi; lib.skill.wuling.updateMark(target); }, - wuqinxi:['虎','鹿','熊','猿','鹤'], - wuqinxiMap:[ - '虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。', - '鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。', - '熊:每回合限一次,当你受到伤害时,此伤害-1。', - '猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。', - '鹤:当你获得此效果时,你摸三张牌。', + wuqinxi: ["虎", "鹿", "熊", "猿", "鹤"], + wuqinxiMap: [ + "虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。", + "鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。", + "熊:每回合限一次,当你受到伤害时,此伤害-1。", + "猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。", + "鹤:当你获得此效果时,你摸三张牌。", ], - updateMark(player){ - var wuqinxi=player.storage.wuling_wuqinxi; - if(!wuqinxi) return; - var prevMark=wuqinxi.shift(); + updateMark(player) { + var wuqinxi = player.storage.wuling_wuqinxi; + if (!wuqinxi) return; + var prevMark = wuqinxi.shift(); // wuqinxi.push(prevMark); - var curMark=wuqinxi[0]; - if(!curMark){ - for(var skill in player.additionalSkills){ - if(!skill.startsWith('wuling_')) continue; + var curMark = wuqinxi[0]; + if (!curMark) { + for (var skill in player.additionalSkills) { + if (!skill.startsWith("wuling_")) continue; player.removeAdditionalSkill(skill); } - game.log(player,'完成了五禽戏的操练'); + game.log(player, "完成了五禽戏的操练"); return; } - game.log(player,'获得了','#g【'+curMark+'】','标记'); - player.markSkill('wuling_wuqinxi'); - game.broadcastAll(function(player,curMark){ - if(player.marks.wuling_wuqinxi) player.marks.wuling_wuqinxi.firstChild.innerHTML=curMark; - },player,curMark); - var next=game.createEvent('wuling_change'); - next.player=player; - next.setContent('emptyEvent'); + game.log(player, "获得了", "#g【" + curMark + "】", "标记"); + player.markSkill("wuling_wuqinxi"); + game.broadcastAll( + function (player, curMark) { + if (player.marks.wuling_wuqinxi) + player.marks.wuling_wuqinxi.firstChild.innerHTML = curMark; + }, + player, + curMark + ); + var next = game.createEvent("wuling_change"); + next.player = player; + next.setContent("emptyEvent"); }, - ai:{ - order:7, - threaten:5, - result:{target:1}, + ai: { + order: 7, + threaten: 5, + result: { target: 1 }, }, - derivation:'wuling_wuqinxi', - subSkill:{ - wuqinxi:{ - nopop:true, - charlotte:true, - intro:{ - markcount:()=>0, - mark(dialog,storage){ - const wuqinxiMap=lib.skill.wuling.wuqinxiMap; - const str=`
            • 当前效果:${storage[0]}
            • ${wuqinxiMap.find(str=>storage[0]==str[0]).slice(2)}
              `; - dialog.addText(str,false); - const str2='
              “五禽戏”顺序:
              '+storage.join(' ')+'
              '; + derivation: "wuling_wuqinxi", + subSkill: { + wuqinxi: { + nopop: true, + charlotte: true, + intro: { + markcount: () => 0, + mark(dialog, storage) { + const wuqinxiMap = lib.skill.wuling.wuqinxiMap; + const str = `
            • 当前效果:${storage[0]}
            • ${wuqinxiMap + .find((str) => storage[0] == str[0]) + .slice(2)}
              `; + dialog.addText(str, false); + const str2 = + '
              “五禽戏”顺序:
              ' + + storage.join(" ") + + "
              "; dialog.addText(str2); - if(storage.length>1){ - const str3=`
              [下一效果] ${wuqinxiMap.find(str=>storage[1]==str[0])}
              `; + if (storage.length > 1) { + const str3 = `
              [下一效果] ${wuqinxiMap.find( + (str) => storage[1] == str[0] + )}
              `; dialog.add(str3); } }, }, - mod:{ - targetEnabled(card,player,target){ - if(get.type(card)=='delay'&&target.storage.wuling_wuqinxi&&target.storage.wuling_wuqinxi[0]=='鹿') return false; + mod: { + targetEnabled(card, player, target) { + if ( + get.type(card) == "delay" && + target.storage.wuling_wuqinxi && + target.storage.wuling_wuqinxi[0] == "鹿" + ) + return false; }, }, - trigger:{ - source:'damageBegin1', - player:['phaseZhunbeiBegin','damageBegin4','wuling_change'], + trigger: { + source: "damageBegin1", + player: ["phaseZhunbeiBegin", "damageBegin4", "wuling_change"], }, - filter(event,player,name){ - const wuqinxi=player.storage.wuling_wuqinxi&&player.storage.wuling_wuqinxi[0]; - if(!wuqinxi) return false; - if(event.name=='phaseZhunbei') return true; - switch(name){ - case 'damageBegin1': - if(wuqinxi!='虎'||!event.card) return false; - var evt=event.getParent('useCard'); - return evt.targets&&evt.targets.length==1&&evt.targets.includes(event.player); - case 'damageBegin4': - return wuqinxi=='熊'&&!player.hasSkill('wuling_xiong'); + filter(event, player, name) { + const wuqinxi = player.storage.wuling_wuqinxi && player.storage.wuling_wuqinxi[0]; + if (!wuqinxi) return false; + if (event.name == "phaseZhunbei") return true; + switch (name) { + case "damageBegin1": + if (wuqinxi != "虎" || !event.card) return false; + var evt = event.getParent("useCard"); + return ( + evt.targets && + evt.targets.length == 1 && + evt.targets.includes(event.player) + ); + case "damageBegin4": + return wuqinxi == "熊" && !player.hasSkill("wuling_xiong"); default: - switch(wuqinxi){ - case '鹿': - return player.isDamaged()||player.countCards('j'); - case '鹤': + switch (wuqinxi) { + case "鹿": + return player.isDamaged() || player.countCards("j"); + case "鹤": return true; - case '猿': - return game.hasPlayer(target=>target!=player&&target.countGainableCards(player,'e')); + case "猿": + return game.hasPlayer( + (target) => + target != player && target.countGainableCards(player, "e") + ); default: return false; } - break; } }, - forced:true, - onremove:true, - content(){ - 'step 0' - var wuqinxi=player.storage.wuling_wuqinxi[0]; - if(trigger.name=='phaseZhunbei'){ + forced: true, + onremove: true, + content() { + "step 0"; + var wuqinxi = player.storage.wuling_wuqinxi[0]; + if (trigger.name == "phaseZhunbei") { lib.skill.wuling.updateMark(player); event.finish(); - } - else{ - var name=event.triggername; - switch(name){ - case 'damageBegin1': + } else { + var name = event.triggername; + switch (name) { + case "damageBegin1": player.line(trigger.player); trigger.num++; event.finish(); break; - case 'damageBegin4': - player.addTempSkill('wuling_xiong'); + case "damageBegin4": + player.addTempSkill("wuling_xiong"); trigger.num--; event.finish(); break; default: - switch(wuqinxi){ - case '鹿': + switch (wuqinxi) { + case "鹿": player.recover(); - player.discard(player.getCards('j')).discarder=player; + player.discard(player.getCards("j")).discarder = player; event.finish(); break; - case '鹤': + case "鹤": player.draw(3); event.finish(); break; - case '猿': - player.chooseTarget('五禽戏:获得一名其他角色装备区里的一张装备牌',function(card,player,target){ - return target!=player&&target.countGainableCards(player,'e'); - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target),eff=0; - target.getCards('e',function(card){ - var val=get.value(card,target); - eff=Math.max(eff,-val*att); + case "猿": + player + .chooseTarget( + "五禽戏:获得一名其他角色装备区里的一张装备牌", + function (card, player, target) { + return ( + target != player && + target.countGainableCards(player, "e") + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target), + eff = 0; + target.getCards("e", function (card) { + var val = get.value(card, target); + eff = Math.max(eff, -val * att); + }); + return eff; }); - return eff; - }); break; } break; } } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.gainPlayerCard(target,'e',true); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.gainPlayerCard(target, "e", true); } }, - ai:{ - effect:{ - target(card,player,target){ - const wuqinxi=target.storage.wuling_wuqinxi; - if(!wuqinxi||!wuqinxi.length) return; - const curWuqinxi=wuqinxi[0]; - const nextWuqinxi=wuqinxi[1]; - if(nextWuqinxi=='鹿'&&get.type(card)=='delay') return 'zerotarget'; - if(curWuqinxi!='熊'||player.hasSkill('wuling_xiong')) return; - if(player.hasSkillTag('jueqing',false,target)) return; - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + effect: { + target(card, player, target) { + const wuqinxi = target.storage.wuling_wuqinxi; + if (!wuqinxi || !wuqinxi.length) return; + const curWuqinxi = wuqinxi[0]; + const nextWuqinxi = wuqinxi[1]; + if (nextWuqinxi == "鹿" && get.type(card) == "delay") return "zerotarget"; + if (curWuqinxi != "熊" || player.hasSkill("wuling_xiong")) return; + if (player.hasSkillTag("jueqing", false, target)) return; + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } - } - } + }, + }, }, }, - xiong:{charlotte:true}, - die:{ - trigger:{player:'die'}, - filter(event,player){ - return game.hasPlayer(current=>current.additionalSkills[`wuling_${player.playerid}`]); + xiong: { charlotte: true }, + die: { + trigger: { player: "die" }, + filter(event, player) { + return game.hasPlayer( + (current) => current.additionalSkills[`wuling_${player.playerid}`] + ); }, - forced:true, - locked:false, - forceDie:true, - content(){ - var targets=game.filterPlayer(current=>{ + forced: true, + locked: false, + forceDie: true, + content() { + var targets = game.filterPlayer((current) => { return current.additionalSkills[`wuling_${player.playerid}`]; }); player.line(targets); - targets.forEach(current=>current.removeAdditionalSkill(`wuling_${player.playerid}`)); + targets.forEach((current) => + current.removeAdditionalSkill(`wuling_${player.playerid}`) + ); }, }, }, }, - youyi:{ - init(player){ - player.storage.renku=true; + youyi: { + init(player) { + player.storage.renku = true; }, - audio:2, - enable:'phaseUse', - filter(event,player){ - return _status.renku.length>0; + audio: 2, + enable: "phaseUse", + filter(event, player) { + return _status.renku.length > 0; }, - prompt:'将仁区所有牌置入弃牌堆,令所有角色各回复1点体力', - content(){ - 'step 0' - var cards=_status.renku.slice(); - game.cardsDiscard(cards).fromRenku=true; + prompt: "将仁区所有牌置入弃牌堆,令所有角色各回复1点体力", + content() { + "step 0"; + var cards = _status.renku.slice(); + game.cardsDiscard(cards).fromRenku = true; _status.renku.removeArray(cards); - player.$throw(cards,1000); + player.$throw(cards, 1000); game.updateRenku(); - game.log(cards,'从仁库进入了弃牌堆'); - 'step 1' - var targets=game.filterPlayer(); + game.log(cards, "从仁库进入了弃牌堆"); + "step 1"; + var targets = game.filterPlayer(); player.line(targets); - targets.forEach(target=>target.recover()); + targets.forEach((target) => target.recover()); }, - ai:{ - order(item,player){ - return get.order({name:'taoyuan'},player); + ai: { + order(item, player) { + return get.order({ name: "taoyuan" }, player); }, - result:{ - player(player){ - return Math.max(0,game.filterPlayer().reduce((num,target)=>num+get.recoverEffect(target,player,player),0)); + result: { + player(player) { + return Math.max( + 0, + game + .filterPlayer() + .reduce( + (num, target) => num + get.recoverEffect(target, player, player), + 0 + ) + ); }, }, }, - group:'youyi_put', - subSkill:{ - put:{ - audio:'youyi', - trigger:{player:'phaseDiscardEnd'}, - filter(event,player){ + group: "youyi_put", + subSkill: { + put: { + audio: "youyi", + trigger: { player: "phaseDiscardEnd" }, + filter(event, player) { return lib.skill.twlijian.getCards(event).length; }, - prompt2(event,player){ - return '将'+get.translation(lib.skill.twlijian.getCards(event))+'置入仁区'; + prompt2(event, player) { + return "将" + get.translation(lib.skill.twlijian.getCards(event)) + "置入仁区"; }, - content(){ - var cards=lib.skill.twlijian.getCards(trigger); - game.log(player,'将',cards,'置于了仁库'); - game.cardsGotoSpecial(cards,'toRenku'); + content() { + var cards = lib.skill.twlijian.getCards(trigger); + game.log(player, "将", cards, "置于了仁库"); + game.cardsGotoSpecial(cards, "toRenku"); }, }, }, }, //神贾诩 - jxlianpo:{ - audio:2, - init:()=>{ - game.addGlobalSkill('jxlianpo_global'); + jxlianpo: { + audio: 2, + init: () => { + game.addGlobalSkill("jxlianpo_global"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('jxlianpo'),true)) game.removeGlobalSkill('jxlianpo_global'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("jxlianpo"), true)) + game.removeGlobalSkill("jxlianpo_global"); }, - trigger:{global:'dieAfter'}, - filter(event,player){ - if(lib.skill.jxlianpo.getMax().length<=1) return false; - return event.source&&event.source.isIn(); + trigger: { global: "dieAfter" }, + filter(event, player) { + if (lib.skill.jxlianpo.getMax().length <= 1) return false; + return event.source && event.source.isIn(); }, - forced:true, - logTarget:'source', - getMax:()=>{ - const map={ - zhu:game.countPlayer(current=>{ - const identity=current.identity; - let num=0; - if(identity=='zhu'||identity=='zhong'||identity=='mingzhong') num++; - num+=current.countMark('jxlianpo_mark_zhong'); + forced: true, + logTarget: "source", + getMax: () => { + const map = { + zhu: game.countPlayer((current) => { + const identity = current.identity; + let num = 0; + if (identity == "zhu" || identity == "zhong" || identity == "mingzhong") num++; + num += current.countMark("jxlianpo_mark_zhong"); return num; }), - fan:game.countPlayer(current=>{ - let num=0; - if(current.identity=='fan') num++; - num+=current.countMark('jxlianpo_mark_fan'); + fan: game.countPlayer((current) => { + let num = 0; + if (current.identity == "fan") num++; + num += current.countMark("jxlianpo_mark_fan"); return num; }), - nei:game.countPlayer(current=>{ - let num=0; - if(current.identity=='nei') num++; - num+=current.countMark('jxlianpo_mark_nei'); + nei: game.countPlayer((current) => { + let num = 0; + if (current.identity == "nei") num++; + num += current.countMark("jxlianpo_mark_nei"); return num; }), - commoner:game.countPlayer(current=>{ - let num=0; - if(current.identity=='commoner') num++; - num+=current.countMark('jxlianpo_mark_commoner'); + commoner: game.countPlayer((current) => { + let num = 0; + if (current.identity == "commoner") num++; + num += current.countMark("jxlianpo_mark_commoner"); return num; }), }; - let population=0,identities=[]; - for(let i in map){ - let curPopulation=map[i] - if(curPopulation>=population){ - if(curPopulation>population) identities=[]; + let population = 0, + identities = []; + for (let i in map) { + let curPopulation = map[i]; + if (curPopulation >= population) { + if (curPopulation > population) identities = []; identities.add(i); - population=curPopulation; + population = curPopulation; } } return identities; }, - group:'jxlianpo_show', - *content(event,map){ - var source=map.trigger.source; + group: "jxlianpo_show", + *content(event, map) { + var source = map.trigger.source; source.draw(2); source.recover(); }, - mark:true, - intro:{ - content:()=>`场上最大阵营为${lib.skill.jxlianpo.getMax().map(i=>{ - if(i=='zhu') return '主忠'; - return get.translation(i+'2'); - }).join('、')}`, + mark: true, + intro: { + content: () => + `场上最大阵营为${lib.skill.jxlianpo + .getMax() + .map((i) => { + if (i == "zhu") return "主忠"; + return get.translation(i + "2"); + }) + .join("、")}`, }, - $createButton(item,type,position,noclick,node){ - node=ui.create.identityCard(item,position,noclick); - node.link=item; + $createButton(item, type, position, noclick, node) { + node = ui.create.identityCard(item, position, noclick); + node.link = item; return node; }, - subSkill:{ - show:{ - audio:'jxlianpo', - trigger:{global:'roundStart'}, - filter(event,player){ - var list=lib.config.mode_config.identity.identity.lastItem.slice(); - list.removeArray(game.filterPlayer().map(i=>{ - let identity=i.identity; - if(identity=='mingzhong') identity='zhong'; - return identity; - })); + subSkill: { + show: { + audio: "jxlianpo", + trigger: { global: "roundStart" }, + filter(event, player) { + var list = lib.config.mode_config.identity.identity.lastItem.slice(); + list.removeArray( + game.filterPlayer().map((i) => { + let identity = i.identity; + if (identity == "mingzhong") identity = "zhong"; + return identity; + }) + ); return list.length; }, - forced:true, - content(){ - 'step 0' - var list=lib.config.mode_config.identity.identity.lastItem.slice(); - list.removeArray(game.filterPlayer().map(i=>{ - var identity=i.identity; - return identity=='mingzhong'?'zhong':identity; - })).unique(); - player.chooseButton([ - '###炼魄:请选择一个身份###
              你选择的身份对应的阵营角色数于本轮内视为+1
              ', - [list,function(item,type,position,noclick,node){ - return lib.skill.jxlianpo.$createButton(item,type,position,noclick,node); - }], - ],true); - 'step 1' - var choice=result.links[0],mark=`jxlianpo_mark_${choice}`; - player.when({global:'roundStart'}) - .assign({ - firstDo:true, + forced: true, + content() { + "step 0"; + var list = lib.config.mode_config.identity.identity.lastItem.slice(); + list.removeArray( + game.filterPlayer().map((i) => { + var identity = i.identity; + return identity == "mingzhong" ? "zhong" : identity; }) - .filter(evt=>evt!=trigger) - .then(()=>{ - for(var i in player.storage){ - if(i.startsWith('jxlianpo_mark_')){ + ).unique(); + player.chooseButton( + [ + '###炼魄:请选择一个身份###
              你选择的身份对应的阵营角色数于本轮内视为+1
              ', + [ + list, + function (item, type, position, noclick, node) { + return lib.skill.jxlianpo.$createButton( + item, + type, + position, + noclick, + node + ); + }, + ], + ], + true + ); + "step 1"; + var choice = result.links[0], + mark = `jxlianpo_mark_${choice}`; + player + .when({ global: "roundStart" }) + .assign({ + firstDo: true, + }) + .filter((evt) => evt != trigger) + .then(() => { + for (var i in player.storage) { + if (i.startsWith("jxlianpo_mark_")) { player.clearMark(i); } } }); - player.addMark(mark,1,false); - event.videoId=lib.status.videoId++; - var createDialog=function(player,identity,id){ - var dialog=ui.create.dialog(`${get.translation(player)}展示了“${get.translation(identity+'2')}”的身份牌
              `,'forcebutton'); - dialog.videoId=id; - ui.create.spinningIdentityCard(identity,dialog); + player.addMark(mark, 1, false); + event.videoId = lib.status.videoId++; + var createDialog = function (player, identity, id) { + var dialog = ui.create.dialog( + `${get.translation(player)}展示了“${get.translation( + identity + "2" + )}”的身份牌
              `, + "forcebutton" + ); + dialog.videoId = id; + ui.create.spinningIdentityCard(identity, dialog); }; - game.broadcastAll(createDialog,player,choice,event.videoId); - var color=''; - if(choice=='zhong') color='#y'; - else if(choice=='fan') color='#g'; - else if(choice=='nei') color='#b'; - game.log(player,'展示了',`${color}${get.translation(choice+'2')}`,'的身份牌'); + game.broadcastAll(createDialog, player, choice, event.videoId); + var color = ""; + if (choice == "zhong") color = "#y"; + else if (choice == "fan") color = "#g"; + else if (choice == "nei") color = "#b"; + game.log( + player, + "展示了", + `${color}${get.translation(choice + "2")}`, + "的身份牌" + ); game.delay(3); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - } + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + }, }, - global:{ - mod:{ - maxHandcard(player,num){ - if(!lib.skill.jxlianpo.getMax().includes('fan')) return; - return num-game.countPlayer(current=>{ - return current!=player&¤t.hasSkill('jxlianpo'); - }); + global: { + mod: { + maxHandcard(player, num) { + if (!lib.skill.jxlianpo.getMax().includes("fan")) return; + return ( + num - + game.countPlayer((current) => { + return current != player && current.hasSkill("jxlianpo"); + }) + ); }, - cardUsable(card,player,num){ - if(card.name=='sha'){ - if(!lib.skill.jxlianpo.getMax().includes('fan')) return; - return num+game.countPlayer(current=>{ - return current.hasSkill('jxlianpo'); - }); + cardUsable(card, player, num) { + if (card.name == "sha") { + if (!lib.skill.jxlianpo.getMax().includes("fan")) return; + return ( + num + + game.countPlayer((current) => { + return current.hasSkill("jxlianpo"); + }) + ); } }, - attackRange(player,num){ - if(!lib.skill.jxlianpo.getMax().includes('fan')) return; - return num+game.countPlayer(current=>{ - return current.hasSkill('jxlianpo'); - }); + attackRange(player, num) { + if (!lib.skill.jxlianpo.getMax().includes("fan")) return; + return ( + num + + game.countPlayer((current) => { + return current.hasSkill("jxlianpo"); + }) + ); }, - cardSavable(card,player,target){ - if(card.name=='tao'&&!player.hasSkill('jxlianpo')){ - if(!lib.skill.jxlianpo.getMax().includes('zhu')) return; - if(player==target) return; + cardSavable(card, player, target) { + if (card.name == "tao" && !player.hasSkill("jxlianpo")) { + if (!lib.skill.jxlianpo.getMax().includes("zhu")) return; + if (player == target) return; return false; } }, - playerEnabled(card,player,target){ - if(card.name=='tao'&&!player.hasSkill('jxlianpo')){ - if(!lib.skill.jxlianpo.getMax().includes('zhu')) return; - if(player==target) return; + playerEnabled(card, player, target) { + if (card.name == "tao" && !player.hasSkill("jxlianpo")) { + if (!lib.skill.jxlianpo.getMax().includes("zhu")) return; + if (player == target) return; return false; } - } + }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('jxlianpo'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("jxlianpo"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("jxlianpo_global"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('jxlianpo_global'); - } }, }, }, - jxzhaoluan:{ - audio:2, - trigger:{global:'dieBegin'}, - filter(event,player){ - return event.getParent().name=='dying'&&event.player.isIn(); + jxzhaoluan: { + audio: 2, + trigger: { global: "dieBegin" }, + filter(event, player) { + return event.getParent().name == "dying" && event.player.isIn(); }, - limited:true, - skillAnimation:true, - animationColor:'metal', - logTarget:'player', - check(event,player){ - if(event.source&&event.source.isIn()&&get.attitude(player,event.source)>0&&player.identity=='fan') return false; - return get.attitude(player,event.player)>3.5; + limited: true, + skillAnimation: true, + animationColor: "metal", + logTarget: "player", + check(event, player) { + if ( + event.source && + event.source.isIn() && + get.attitude(player, event.source) > 0 && + player.identity == "fan" + ) + return false; + return get.attitude(player, event.player) > 3.5; }, - *content(event,map){ - var player=map.player,trigger=map.trigger; - var target=trigger.player; - player.awakenSkill('jxzhaoluan'); + *content(event, map) { + var player = map.player, + trigger = map.trigger; + var target = trigger.player; + player.awakenSkill("jxzhaoluan"); trigger.cancel(); - const skills = target.getSkills(null,false,false).filter(skill=>{ - var info=get.info(skill); - if(info&&!info.charlotte&&!get.is.locked(skill)){ + const skills = target.getSkills(null, false, false).filter((skill) => { + var info = get.info(skill); + if (info && !info.charlotte && !get.is.locked(skill)) { return true; } }); - if(skills.length) yield target.removeSkills(skills); + if (skills.length) yield target.removeSkills(skills); yield target.gainMaxHp(3); - var num=3-target.getHp(true); - if(num>0) yield target.recover(num); + var num = 3 - target.getHp(true); + if (num > 0) yield target.recover(num); target.draw(4); - player.addSkill('jxzhaoluan_effect'); - player.markAuto('jxzhaoluan_effect',target); + player.addSkill("jxzhaoluan_effect"); + player.markAuto("jxzhaoluan_effect", target); }, - ai:{ - expose:0.5, - threaten:3, + ai: { + expose: 0.5, + threaten: 3, }, - subSkill:{ - effect:{ - audio:'jxzhaoluan', - enable:'phaseUse', - filter(event,player){ - return player.getStorage('jxzhaoluan_effect').some(i=>i.isIn()); + subSkill: { + effect: { + audio: "jxzhaoluan", + enable: "phaseUse", + filter(event, player) { + return player.getStorage("jxzhaoluan_effect").some((i) => i.isIn()); }, - filterTarget(card,player,target){ - return !player.getStorage('jxzhaoluan_hit').includes(target); + filterTarget(card, player, target) { + return !player.getStorage("jxzhaoluan_hit").includes(target); }, - line:false, - locked:true, - charlotte:true, - promptfunc(){ - var bodies=_status.event.player.getStorage('jxzhaoluan_effect').filter(i=>i.isIn()); - return `选择一名角色,你令${get.translation(bodies)}${bodies.length>1?'中的一人':''}减1点体力上限,然后你对选择的角色造成1点伤害。`; + line: false, + locked: true, + charlotte: true, + promptfunc() { + var bodies = _status.event.player + .getStorage("jxzhaoluan_effect") + .filter((i) => i.isIn()); + return `选择一名角色,你令${get.translation(bodies)}${bodies.length > 1 ? "中的一人" : "" + }减1点体力上限,然后你对选择的角色造成1点伤害。`; }, - delay:false, - content(){ - 'step 0' - var bodies=player.getStorage('jxzhaoluan_effect').filter(i=>i.isIn()); - if(bodies.length==1) event._result={bool:true,targets:bodies}; - else{ - player.chooseTarget('兆乱:请选择被减上限的傀儡',true,(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',bodies).set('ai',target=>{ - return 8-get.attitude(_status.event.player,target); - }); + delay: false, + content() { + "step 0"; + var bodies = player.getStorage("jxzhaoluan_effect").filter((i) => i.isIn()); + if (bodies.length == 1) event._result = { bool: true, targets: bodies }; + else { + player + .chooseTarget( + "兆乱:请选择被减上限的傀儡", + true, + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("targets", bodies) + .set("ai", (target) => { + return 8 - get.attitude(_status.event.player, target); + }); } - 'step 1' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.line(target); target.loseMaxHp(); game.delayex(); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; player.line(target); target.damage(); - if(!player.storage.jxzhaoluan_hit){ - player.when('phaseUseAfter') - .then(()=>{ - delete player.storage.jxzhaoluan_hit; - }); + if (!player.storage.jxzhaoluan_hit) { + player.when("phaseUseAfter").then(() => { + delete player.storage.jxzhaoluan_hit; + }); } - player.markAuto('jxzhaoluan_hit',target); + player.markAuto("jxzhaoluan_hit", target); }, - ai:{ - order:9, - result:{ - player(player){ - var bodies=player.getStorage('jxzhaoluan_effect').filter(i=>i.isIn()); + ai: { + order: 9, + result: { + player(player) { + var bodies = player + .getStorage("jxzhaoluan_effect") + .filter((i) => i.isIn()); var body; - if(bodies.length==1) body=bodies[0]; - else body=bodies.sort((a,b)=>get.attitude(player,a)-get.attitude(player,b))[0]; - if(get.attitude(player,body)>4&&!body.isDamaged()&&body.getHp()<=2) return -10; + if (bodies.length == 1) body = bodies[0]; + else + body = bodies.sort( + (a, b) => get.attitude(player, a) - get.attitude(player, b) + )[0]; + if ( + get.attitude(player, body) > 4 && + !body.isDamaged() && + body.getHp() <= 2 + ) + return -10; return 0; }, - target(player,target){ - return Math.sign(get.damageEffect(target,player,target)); - } - } - } + target(player, target) { + return Math.sign(get.damageEffect(target, player, target)); + }, + }, + }, }, }, }, //神典韦 - juanjia:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + juanjia: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.hasEnabledSlot(2); + forced: true, + filter(event, player) { + return (event.name != "phase" || game.phaseNumber == 0) && player.hasEnabledSlot(2); }, - content(){ + content() { player.disableEquip(2); player.expandEquip(1); }, }, - qiexie:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter(event,player){ - return player.countEmptySlot(1)>0; + qiexie: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter(event, player) { + return player.countEmptySlot(1) > 0; }, - content(){ - 'step 0' - if(!_status.characterlist){ + content() { + "step 0"; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } _status.characterlist.randomSort(); - var list=[]; - for(var name of _status.characterlist){ - var info=lib.character[name]; - if(info[3].some(function(skill){ - var info=get.skillInfoTranslation(skill); - if(!info.includes('【杀】')) return false; - var list=get.skillCategoriesOf(skill); - list.remove('锁定技'); - return list.length==0; - })){ + var list = []; + for (var name of _status.characterlist) { + var info = lib.character[name]; + if ( + info[3].some(function (skill) { + var info = get.skillInfoTranslation(skill); + if (!info.includes("【杀】")) return false; + var list = get.skillCategoriesOf(skill); + list.remove("锁定技"); + return list.length == 0; + }) + ) { list.push(name); - if(list.length>=5) break; + if (list.length >= 5) break; } } - if(!list.length) event.finish(); - else{ - var num=player.countEmptySlot(1); - player.chooseButton([ - '挈挟:选择'+(num>1?'至多':'')+get.cnNumber(num)+'张武将置入武器栏', - [list,function(item,type,position,noclick,node){ - return lib.skill.qiexie.$createButton(item,type,position,noclick,node); - }], - ],[1,num],true).set('ai',function(button){ - var name=button.link; - var info=lib.character[name]; - var skills=info[3].filter(function(skill){ - var info=get.skillInfoTranslation(skill); - if(!info.includes('【杀】')) return false; - var list=get.skillCategoriesOf(skill); - list.remove('锁定技'); - return list.length==0; + if (!list.length) event.finish(); + else { + var num = player.countEmptySlot(1); + player + .chooseButton( + [ + "挈挟:选择" + + (num > 1 ? "至多" : "") + + get.cnNumber(num) + + "张武将置入武器栏", + [ + list, + function (item, type, position, noclick, node) { + return lib.skill.qiexie.$createButton( + item, + type, + position, + noclick, + node + ); + }, + ], + ], + [1, num], + true + ) + .set("ai", function (button) { + var name = button.link; + var info = lib.character[name]; + var skills = info[3].filter(function (skill) { + var info = get.skillInfoTranslation(skill); + if (!info.includes("【杀】")) return false; + var list = get.skillCategoriesOf(skill); + list.remove("锁定技"); + return list.length == 0; + }); + var eff = 0.2; + for (var i of skills) { + eff += get.skillRank(i, "in"); + } + return eff; }); - var eff=0.2; - for(var i of skills){ - eff+=get.skillRank(i,'in'); - } - return eff; - }) } - 'step 1' - if(result.bool){ - var list=result.links; - game.addVideo('skill',player,['qiexie',[list]]); + "step 1"; + if (result.bool) { + var list = result.links; + game.addVideo("skill", player, ["qiexie", [list]]); _status.characterlist.removeArray(list); - game.broadcastAll(function(player,list){ - player.tempname.addArray(list); - for(var name of list) lib.skill.qiexie.createCard(name); - },player,list); - var cards=list.map(function(name){ - var card=game.createCard('qiexie_'+name,'none',get.infoMaxHp(lib.character[name][2])); + game.broadcastAll( + function (player, list) { + player.tempname.addArray(list); + for (var name of list) lib.skill.qiexie.createCard(name); + }, + player, + list + ); + var cards = list.map(function (name) { + var card = game.createCard( + "qiexie_" + name, + "none", + get.infoMaxHp(lib.character[name][2]) + ); return card; }); player.$gain2(cards); game.delayx(); - for(var card of cards) player.equip(card); + for (var card of cards) player.equip(card); } }, - $createButton(item,type,position,noclick,node){ - node=ui.create.buttonPresets.character(item,'character',position,noclick); - const info=lib.character[item]; - const skills=info[3].filter(function(skill){ - var info=get.skillInfoTranslation(skill); - if(!info.includes('【杀】')) return false; - var list=get.skillCategoriesOf(skill); - list.remove('锁定技'); - return list.length==0; + $createButton(item, type, position, noclick, node) { + node = ui.create.buttonPresets.character(item, "character", position, noclick); + const info = lib.character[item]; + const skills = info[3].filter(function (skill) { + var info = get.skillInfoTranslation(skill); + if (!info.includes("【杀】")) return false; + var list = get.skillCategoriesOf(skill); + list.remove("锁定技"); + return list.length == 0; }); - if(skills.length){ - const skillstr=skills.map(i=>`[${get.translation(i)}]`).join('
              '); - const skillnode=ui.create.caption( - `
              ${skillstr}
              `,node); - skillnode.style.left='2px'; - skillnode.style.bottom='2px'; + if (skills.length) { + const skillstr = skills.map((i) => `[${get.translation(i)}]`).join("
              "); + const skillnode = ui.create.caption( + `
              ${skillstr}
              `, + node + ); + skillnode.style.left = "2px"; + skillnode.style.bottom = "2px"; } - node._customintro=function(uiintro,evt){ - const character=node.link,characterInfo=get.character(node.link); - let capt=get.translation(character); - if(characterInfo){ - const infoHp=get.infoMaxHp(characterInfo[2]); - capt+=`  范围:${infoHp}`; + node._customintro = function (uiintro, evt) { + const character = node.link, + characterInfo = get.character(node.link); + let capt = get.translation(character); + if (characterInfo) { + const infoHp = get.infoMaxHp(characterInfo[2]); + capt += `  范围:${infoHp}`; } uiintro.add(capt); - if(lib.characterTitle[node.link]){ + if (lib.characterTitle[node.link]) { uiintro.addText(get.colorspan(lib.characterTitle[node.link])); } - for(let i=0;i
              '+get.translation(skills[i])+'
              '+get.skillInfoTranslation(skills[i])+'
              '); + for (let i = 0; i < skills.length; i++) { + if (lib.translate[skills[i] + "_info"]) { + let translation = + lib.translate[skills[i] + "_ab"] || + get.translation(skills[i]).slice(0, 2); + if (lib.skill[skills[i]] && lib.skill[skills[i]].nobracket) { + uiintro.add( + '
              ' + + get.translation(skills[i]) + + "
              " + + get.skillInfoTranslation(skills[i]) + + "
              " + ); + } else { + uiintro.add( + '
              【' + + translation + + "】
              " + + get.skillInfoTranslation(skills[i]) + + "
              " + ); } - else{ - uiintro.add('
              【'+translation+'】
              '+get.skillInfoTranslation(skills[i])+'
              '); - } - if(lib.translate[skills[i]+'_append']){ - uiintro._place_text=uiintro.add('
              '+lib.translate[skills[i]+'_append']+'
              ') + if (lib.translate[skills[i] + "_append"]) { + uiintro._place_text = uiintro.add( + '
              ' + lib.translate[skills[i] + "_append"] + "
              " + ); } } } - } + }; return node; }, - video(player,info){ - for(var name of info[0]){ + video(player, info) { + for (var name of info[0]) { lib.skill.qiexie.createCard(name); } }, - createCard(name){ - if(!_status.postReconnect.qiexie) _status.postReconnect.qiexie=[ - function(list){ - for(var name of list) lib.skill.qiexie.createCard(name); - },[] - ]; - _status.postReconnect.qiexie[1].add(name) - if(!lib.card['qiexie_'+name]){ - if(lib.translate[name+'_ab']) lib.translate['qiexie_'+name]=lib.translate[name+'_ab']; - else lib.translate['qiexie_'+name]=lib.translate[name]; - var info=lib.character[name]; - var card={ - fullimage:true, - image:'character:'+name, - type:'equip', - subtype:'equip1', - enable:true, - selectTarget:-1, - filterCard(card,player,target){ - if(player!=target) return false; - return target.canEquip(card,true); + createCard(name) { + if (!_status.postReconnect.qiexie) + _status.postReconnect.qiexie = [ + function (list) { + for (var name of list) lib.skill.qiexie.createCard(name); }, - modTarget:true, - allowMultiple:false, - content:lib.element.content.equipCard, - toself:true, - ai:{}, - skills:['qiexie_destroy'], - } - var maxHp=get.infoMaxHp(info[2]); - if(maxHp!=1) card.distance={attackFrom:(1-maxHp)}; - var skills=info[3].filter(function(skill){ - var info=get.skillInfoTranslation(skill); - if(!info.includes('【杀】')) return false; - var list=get.skillCategoriesOf(skill); - list.remove('锁定技'); - return list.length==0; + [], + ]; + _status.postReconnect.qiexie[1].add(name); + if (!lib.card["qiexie_" + name]) { + if (lib.translate[name + "_ab"]) + lib.translate["qiexie_" + name] = lib.translate[name + "_ab"]; + else lib.translate["qiexie_" + name] = lib.translate[name]; + var info = lib.character[name]; + var card = { + fullimage: true, + image: "character:" + name, + type: "equip", + subtype: "equip1", + enable: true, + selectTarget: -1, + filterCard(card, player, target) { + if (player != target) return false; + return target.canEquip(card, true); + }, + modTarget: true, + allowMultiple: false, + content: lib.element.content.equipCard, + toself: true, + ai: {}, + skills: ["qiexie_destroy"], + }; + var maxHp = get.infoMaxHp(info[2]); + if (maxHp != 1) card.distance = { attackFrom: 1 - maxHp }; + var skills = info[3].filter(function (skill) { + var info = get.skillInfoTranslation(skill); + if (!info.includes("【杀】")) return false; + var list = get.skillCategoriesOf(skill); + list.remove("锁定技"); + return list.length == 0; }); - var str='锁定技。'; - if(skills.length){ + var str = "锁定技。"; + if (skills.length) { card.skills.addArray(skills); - str+='你视为拥有技能'; - for(var skill of skills){ - str+='〖'+get.translation(skill)+'〗'; - str+='、'; + str += "你视为拥有技能"; + for (var skill of skills) { + str += "〖" + get.translation(skill) + "〗"; + str += "、"; } - str=str.slice(0,str.length-1); - str+=';'; - card.ai.equipValue=function(card,player){ - let val=maxHp; - if(player.hasSkill('qiexie')) val*=0.4; - else val*=0.6; - return val+=skills.length; + str = str.slice(0, str.length - 1); + str += ";"; + card.ai.equipValue = function (card, player) { + let val = maxHp; + if (player.hasSkill("qiexie")) val *= 0.4; + else val *= 0.6; + return (val += skills.length); }; } - str+='此牌离开你的装备区后,改为置入剩余武将牌牌堆。'; - lib.translate['qiexie_'+name+'_info']=str; - var append=''; - if(skills.length){ - for(var skill of skills){ - if(lib.skill[skill].nobracket){ - append+='
              '+get.translation(skill)+'
              '+get.skillInfoTranslation(skill)+'


              '; - } - else{ - var translation=lib.translate[skill+'_ab']||get.translation(skill).slice(0,2); - append+='
              【'+translation+'】
              '+get.skillInfoTranslation(skill)+'


              '; + str += "此牌离开你的装备区后,改为置入剩余武将牌牌堆。"; + lib.translate["qiexie_" + name + "_info"] = str; + var append = ""; + if (skills.length) { + for (var skill of skills) { + if (lib.skill[skill].nobracket) { + append += + '
              ' + + get.translation(skill) + + '
              ' + + get.skillInfoTranslation(skill) + + "


              "; + } else { + var translation = + lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2); + append += + '
              【' + + translation + + '】
              ' + + get.skillInfoTranslation(skill) + + "


              "; } } - str=str.slice(0,str.length-8); + str = str.slice(0, str.length - 8); } - lib.translate['qiexie_'+name+'_append']=append; - lib.card['qiexie_'+name]=card; + lib.translate["qiexie_" + name + "_append"] = append; + lib.card["qiexie_" + name] = card; } }, - subSkill:{ - destroy:{ - trigger:{player:'loseBegin'}, - equipSkill:true, - forceDie:true, - charlotte:true, - forced:true, - popup:false, - filter(event,player){ - return event.cards.some(card=>card.name.indexOf('qiexie_')==0) + subSkill: { + destroy: { + trigger: { player: "loseBegin" }, + equipSkill: true, + forceDie: true, + charlotte: true, + forced: true, + popup: false, + filter(event, player) { + return event.cards.some((card) => card.name.indexOf("qiexie_") == 0); }, - content(){ - for(var card of trigger.cards){ - if(card.name.indexOf('qiexie_')==0){ - card._destroy=true; - game.log(card,'被放回武将牌堆'); - var name=card.name.slice(7); - if(player.tempname&&player.tempname.includes(name)){ - game.broadcastAll((player,name)=>{ - player.tempname.remove(name); - },player,name); + content() { + for (var card of trigger.cards) { + if (card.name.indexOf("qiexie_") == 0) { + card._destroy = true; + game.log(card, "被放回武将牌堆"); + var name = card.name.slice(7); + if (player.tempname && player.tempname.includes(name)) { + game.broadcastAll( + (player, name) => { + player.tempname.remove(name); + }, + player, + name + ); } - if(lib.character[name]) _status.characterlist.add(name); + if (lib.character[name]) _status.characterlist.add(name); } } }, }, }, }, - cuijue:{ - enable:'phaseUse', - filter(event,player){ - return player.countCards('he')>0;//&&game.hasPlayer(target=>lib.skill.cuijue.filterTarget('SB',player,target)); + cuijue: { + enable: "phaseUse", + filter(event, player) { + return player.countCards("he") > 0; //&&game.hasPlayer(target=>lib.skill.cuijue.filterTarget('SB',player,target)); }, - filterCard:true, - filterTarget(card,player,target){ - if(player.getStorage('cuijue_used').includes(target)||!player.inRange(target)) return false; - var distance=get.distance(player,target); - return !game.hasPlayer(current=>(current!=target&&player.inRange(current)&&get.distance(player,current)>distance)); + filterCard: true, + filterTarget(card, player, target) { + if (player.getStorage("cuijue_used").includes(target) || !player.inRange(target)) + return false; + var distance = get.distance(player, target); + return !game.hasPlayer( + (current) => + current != target && + player.inRange(current) && + get.distance(player, current) > distance + ); }, - selectTarget:[0,1], - filterOk(){ - var player=_status.event.player; - if(game.hasPlayer(target=>lib.skill.cuijue.filterTarget('SB',player,target))) return ui.selected.targets.length>0; + selectTarget: [0, 1], + filterOk() { + var player = _status.event.player; + if (game.hasPlayer((target) => lib.skill.cuijue.filterTarget("SB", player, target))) + return ui.selected.targets.length > 0; return true; }, - position:'he', - complexTarget:true, - check:card=>{ - var player=_status.event.player,goon=0; - try{ + position: "he", + complexTarget: true, + check: (card) => { + var player = _status.event.player, + goon = 0; + try { ui.selected.cards.add(card); - if(game.hasPlayer(target=>{ - return lib.skill.cuijue.filterTarget('SB',player,target); - })){ - goon=6; + if ( + game.hasPlayer((target) => { + return lib.skill.cuijue.filterTarget("SB", player, target); + }) + ) { + goon = 6; } - }catch(e){ + } catch (e) { console.trace(e); } ui.selected.cards.remove(card); - return goon-get.value(card); + return goon - get.value(card); }, - content(){ - if(target){ - player.addTempSkill('cuijue_used','phaseUseAfter'); - player.markAuto('cuijue_used',[target]); - target.damage('nocard'); + content() { + if (target) { + player.addTempSkill("cuijue_used", "phaseUseAfter"); + player.markAuto("cuijue_used", [target]); + target.damage("nocard"); } }, - ai:{ - order:2, - result:{ - target:-1.5 + ai: { + order: 2, + result: { + target: -1.5, + }, + tag: { + damage: 1, }, - tag:{ - damage:1 - } }, - subSkill:{ - used:{ - onremove:true, - charlotte:true, + subSkill: { + used: { + onremove: true, + charlotte: true, }, }, }, //神邓艾 - dctuoyu:{ - audio:2, - trigger:{player:['phaseUseBegin','phaseUseEnd']}, - forced:true, - filter(event,player){ - return player.countCards('h')>0&&player.getStorage('dctuoyu').length>0; + dctuoyu: { + audio: 2, + trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, + forced: true, + filter(event, player) { + return player.countCards("h") > 0 && player.getStorage("dctuoyu").length > 0; }, - content(){ - 'step 0' - var hs=player.getCards('h'),tags=['dctuoyu_fengtian','dctuoyu_qingqu','dctuoyu_junshan']; - var storage=player.getStorage('dctuoyu'); - var list=[ - ['未分配手牌(对话框较长,请下滑操作)',[]], - ['丰田(伤害/回复值+1)',[]], - ['清渠(无次数和距离限制)',[]], - ['峻山(不可被响应)',[]], + content() { + "step 0"; + var hs = player.getCards("h"), + tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; + var storage = player.getStorage("dctuoyu"); + var list = [ + ["未分配手牌(对话框较长,请下滑操作)", []], + ["丰田(伤害/回复值+1)", []], + ["清渠(无次数和距离限制)", []], + ["峻山(不可被响应)", []], ]; - for(var card of hs){ - var added=false; - for(var i=0;i{ - return i.hasGaintag('sha_notshan'); - }))&&get.attitude(player,target)<0&&get.effect(target,{name:'sha'},player,player)>0; - }) - for(var card of hs){ - var name=get.name(card); - if(name=='tao'||name=='jiu'){ - addTo(card,1); - } - else if(name=='sha'){ - if(hasRuanshizi&&isEmpty(1)&&usable>0) addTo(card,1); - else if(isEmpty(3)&&usable>0) addTo(card,3); - else addTo(card,2); - } - else if(get.type(name)=='trick'){ - if(isEmpty(1)&&get.tag(card,'damage')>0&&player.hasUseTarget(card)) addTo(card,1); - else addTo(card,3); + }; + var hasRuanshizi = game.hasPlayer(function (target) { + return ( + target != player && + player.canUse("sha", target, null, true) && + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + get.attitude(player, target) < 0 && + get.effect(target, { name: "sha" }, player, player) > 0 + ); + }); + for (var card of hs) { + var name = get.name(card); + if (name == "tao" || name == "jiu") { + addTo(card, 1); + } else if (name == "sha") { + if (hasRuanshizi && isEmpty(1) && usable > 0) addTo(card, 1); + else if (isEmpty(3) && usable > 0) addTo(card, 3); + else addTo(card, 2); + } else if (get.type(name) == "trick") { + if (isEmpty(1) && get.tag(card, "damage") > 0 && player.hasUseTarget(card)) + addTo(card, 1); + else addTo(card, 3); } } moved[0].addArray(hs2); return moved; - }) - 'step 1' - if(result.bool){ - game.broadcastAll(function(moved,player){ - var tags=['dctuoyu_fengtian','dctuoyu_qingqu','dctuoyu_junshan']; - var cards=[]; - for(var i=0;i0||get.tag(card,'recover')>0){ + if (!tags.includes("dctuoyu_fengtian_tag")) { + if (get.tag(card, "damage") > 0 || get.tag(card, "recover") > 0) { trigger.baseDamage++; - game.log(card,'的伤害值/回复值+1'); + game.log(card, "的伤害值/回复值+1"); } } - if(!tags.includes('dctuoyu_qingqu_tag')){ - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat('card'); - if(stat[card.name]&&stat[card.name]>0) stat[card.name]--; - game.log(card,'不计入次数限制'); + if (!tags.includes("dctuoyu_qingqu_tag")) { + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat("card"); + if (stat[card.name] && stat[card.name] > 0) stat[card.name]--; + game.log(card, "不计入次数限制"); } } - if(!tags.includes('dctuoyu_junshan_tag')){ - game.log(card,'不可被响应'); + if (!tags.includes("dctuoyu_junshan_tag")) { + game.log(card, "不可被响应"); trigger.directHit.addArray(game.filterPlayer()); } }, }, }, + ai: { + combo: "dcxianjin", + }, }, - dcxianjin:{ - init(player){ - var num=game.getAllGlobalHistory('changeHp',evt=>{ - return evt.getParent().name=='damage'&&(evt.getParent().player==player||(evt.getParent().source&&evt.getParent().source==player)); - }).concat(game.getAllGlobalHistory('changeHp',evt=>{ - return evt.getParent().name=='damage'&&evt.getParent().player==player&&evt.getParent().source&&evt.getParent().source==player; - })).length; - if(num) player.addMark('dcxianjin',num,false); + dcxianjin: { + init(player) { + var num = game + .getAllGlobalHistory("changeHp", (evt) => { + return ( + evt.getParent().name == "damage" && + (evt.getParent().player == player || + (evt.getParent().source && evt.getParent().source == player)) + ); + }) + .concat( + game.getAllGlobalHistory("changeHp", (evt) => { + return ( + evt.getParent().name == "damage" && + evt.getParent().player == player && + evt.getParent().source && + evt.getParent().source == player + ); + }) + ).length; + if (num) player.addMark("dcxianjin", num, false); }, - onremove:true, - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + onremove: true, + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter(event,player){ - return player.countMark('dcxianjin')%2==0; + filter(event, player) { + return player.countMark("dcxianjin") % 2 == 0; }, - forced:true, - content(){ - 'step 0' - var tags=['dctuoyu_fengtian','dctuoyu_qingqu','dctuoyu_junshan']; - tags.removeArray(player.getStorage('dctuoyu')); - if(!tags.length){ - player.draw(player.isMaxHandcard()?1:3); + forced: true, + content() { + "step 0"; + var tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; + tags.removeArray(player.getStorage("dctuoyu")); + if (!tags.length) { + player.draw(player.isMaxHandcard() ? 1 : 3); event.finish(); - } - else if(tags.length==1){ - event._result={control:tags[0]}; - } - else player.chooseControl(tags).set('prompt','险峻:选择激活一个副区域标签'); - 'step 1' - var control=result.control; - game.log(player,'激活了副区域','#y'+get.translation(control)); - player.markAuto('dctuoyu',[control]); - player.popup(get.translation(control+'_tag')); - if(player.isMaxHandcard()) player.draw(); - else player.draw(player.getStorage('dctuoyu').length) + } else if (tags.length == 1) { + event._result = { control: tags[0] }; + } else player.chooseControl(tags).set("prompt", "险峻:选择激活一个副区域标签"); + "step 1"; + var control = result.control; + game.log(player, "激活了副区域", "#y" + get.translation(control)); + player.markAuto("dctuoyu", [control]); + player.popup(get.translation(control + "_tag")); + if (player.isMaxHandcard()) player.draw(); + else player.draw(player.getStorage("dctuoyu").length); }, - group:'dcxianjin_mark', - intro:{content:'已造成或受到#次伤害'}, - subSkill:{ - mark:{ - charlotte:true, - trigger:{ - player:'damageEnd', - source:'damageSource', + group: "dcxianjin_mark", + intro: { content: "已造成或受到#次伤害" }, + subSkill: { + mark: { + charlotte: true, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - popup:false, - firstDo:true, - content(){ - player.addMark('dcxianjin',1,false); + forced: true, + popup: false, + firstDo: true, + content() { + player.addMark("dcxianjin", 1, false); }, }, }, - }, - dcqijing:{ - derivation:'dccuixin', - audio:2, - trigger:{global:'phaseEnd'}, - filter(event,player){ - return player.getStorage('dctuoyu').length==3; + ai: { + combo: "dctuoyu", }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'orange', - changeSeat:true, - content(){ - 'step 0' - player.awakenSkill('dcqijing'); + }, + dcqijing: { + derivation: "dccuixin", + audio: 2, + trigger: { global: "phaseEnd" }, + filter(event, player) { + return player.getStorage("dctuoyu").length == 3; + }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "orange", + changeSeat: true, + content() { + "step 0"; + player.awakenSkill("dcqijing"); player.loseMaxHp(); - player.addSkills('dccuixin'); - 'step 1' - if(game.countPlayer()>2){ - if(player==trigger.player&&!trigger.skill){ - var evt=trigger.getParent(); - if(evt.name=='phaseLoop'&&evt._isStandardLoop) evt.player=player.next; + player.addSkills("dccuixin"); + "step 1"; + if (game.countPlayer() > 2) { + if (player == trigger.player && !trigger.skill) { + var evt = trigger.getParent(); + if (evt.name == "phaseLoop" && evt._isStandardLoop) evt.player = player.next; } - player.chooseTarget('请选择一名要更换座次的角色,将自己移动到该角色的上家位置',function(card,player,target){ - return target!=player&&target!=player.next; - },true).set('ai',function(target){ - var player=_status.event.player; - var current=_status.currentPhase.next; - var max=20,att=0; - while(max>0){ - max--; - if(current==target) return att; - att-=get.attitude(player,current); - current=current.next; - } - return att; - }) - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - game.broadcastAll(function(target1,target2){ - game.swapSeat(target1,target2,null,true); - },player,target); - } - else event.finish(); - 'step 3' + player + .chooseTarget( + "请选择一名要更换座次的角色,将自己移动到该角色的上家位置", + function (card, player, target) { + return target != player && target != player.next; + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + var current = _status.currentPhase.next; + var max = 20, + att = 0; + while (max > 0) { + max--; + if (current == target) return att; + att -= get.attitude(player, current); + current = current.next; + } + return att; + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + game.broadcastAll( + function (target1, target2) { + game.swapSeat(target1, target2, null, true); + }, + player, + target + ); + } else event.finish(); + "step 3"; player.insertPhase(); }, + ai: { + combo: "dctuoyu", + }, }, - dccuixin:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(!event._dccuixin||get.type(event.card,false)=='delay'||get.type(event.card,false)=='equip') return false; - var card={ - name:event.card.name, - nature:event.card.nature, - isCard:true, - },list=event._dccuixin; - for(var target of list){ - var targetx=player[target](); - if(lib.filter.targetEnabled2(card,targetx,player)) return true; + dccuixin: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + if ( + !event._dccuixin || + get.type(event.card, false) == "delay" || + get.type(event.card, false) == "equip" + ) + return false; + var card = { + name: event.card.name, + nature: event.card.nature, + isCard: true, + }, + list = event._dccuixin; + for (var target of list) { + var targetx = player[target](); + if (lib.filter.targetEnabled2(card, targetx, player)) return true; } return false; }, - direct:true, - content(){ - 'step 0' - var card={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, + direct: true, + content() { + "step 0"; + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, }; - event.card=card; - var list=[]; - trigger._dccuixin.forEach(target=>{ - var targetx=player[target](); - if(lib.filter.targetEnabled2(card,targetx,player)) list.add(targetx); + event.card = card; + var list = []; + trigger._dccuixin.forEach((target) => { + var targetx = player[target](); + if (lib.filter.targetEnabled2(card, targetx, player)) list.add(targetx); }); - if(list.length==1){ - event.target=list[0]; - player.chooseBool('摧心:是否视为对'+get.translation(list[0])+'使用'+get.translation(card)+'?').set('goon',get.effect(list[0],card,player,player)>0).set('ai',()=>_status.event.goon); + if (list.length == 1) { + event.target = list[0]; + player + .chooseBool( + "摧心:是否视为对" + + get.translation(list[0]) + + "使用" + + get.translation(card) + + "?" + ) + .set("goon", get.effect(list[0], card, player, player) > 0) + .set("ai", () => _status.event.goon); + } else { + player + .chooseTarget( + "摧心:是否视为对上家或下家使用" + get.translation(card) + "?", + "操作提示:从上家或下家中选择一名角色作为使用目标", + function (card, player, target) { + return ( + (target == player.getNext() || target == player.getPrevious()) && + lib.filter.targetEnabled2( + _status.event.getParent().card, + target, + player + ) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.getParent().card, player, player); + }); } - else{ - player.chooseTarget('摧心:是否视为对上家或下家使用'+get.translation(card)+'?','操作提示:从上家或下家中选择一名角色作为使用目标',function(card,player,target){ - return (target==player.getNext()||target==player.getPrevious())&&lib.filter.targetEnabled2(_status.event.getParent().card,target,player); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.getParent().card,player,player) - }) - } - 'step 1' - if(result.bool){ - var target=event.target||result.targets[0]; - player.useCard(card,target,false,'dccuixin'); + "step 1"; + if (result.bool) { + var target = event.target || result.targets[0]; + player.useCard(card, target, false, "dccuixin"); } }, - group:'dccuixin_silent', - subSkill:{ - silent:{ - trigger:{player:'useCardToPlayered'}, - silent:true, - forced:true, - popup:false, - firstDo:true, - charlotte:true, - filter(event,player){ - if(!event.isFirstTarget||event.getParent().skill=='dccuixin') return false; - if(event.targets.length==0) return false; - return event.targets.includes(player.getNext())||event.targets.includes(player.getPrevious()); + group: "dccuixin_silent", + subSkill: { + silent: { + trigger: { player: "useCardToPlayered" }, + silent: true, + forced: true, + popup: false, + firstDo: true, + charlotte: true, + filter(event, player) { + if (!event.isFirstTarget || event.getParent().skill == "dccuixin") return false; + if (event.targets.length == 0) return false; + return ( + event.targets.includes(player.getNext()) || + event.targets.includes(player.getPrevious()) + ); + }, + content() { + var list = []; + if (trigger.targets.includes(player.getNext())) list.push("getPrevious"); + if (trigger.targets.includes(player.getPrevious())) list.push("getNext"); + trigger.getParent()._dccuixin = list; }, - content(){ - var list=[]; - if(trigger.targets.includes(player.getNext())) list.push('getPrevious'); - if(trigger.targets.includes(player.getPrevious())) list.push('getNext'); - trigger.getParent()._dccuixin=list; - } }, }, }, //海外神吕蒙 - twshelie:{ - audio:'shelie', - inherit:'shelie', - prompt2:()=>lib.translate.shelie_info, - group:'twshelie_jingce', + twshelie: { + audio: "shelie", + inherit: "shelie", + prompt2: () => lib.translate.shelie_info, + group: "twshelie_jingce", //什么精策技能啊喂! - subSkill:{ - round:{charlotte:true}, - count:{ - charlotte:true, - onremove:true, - intro:{ - markcount(storage){ + subSkill: { + round: { charlotte: true }, + count: { + charlotte: true, + onremove: true, + intro: { + markcount(storage) { return storage.length; }, - content:'本回合已使用$花色的牌', + content: "本回合已使用$花色的牌", }, }, - jingce:{ - audio:'shelie', - trigger:{player:['phaseJieshuBegin','useCard1']}, - filter(event,player){ - if(player.hasSkill('twshelie_round')||player!=_status.currentPhase) return false; - var list=[]; - player.getHistory('useCard',function(evt){ - if(lib.suit.includes(get.suit(evt.card))&&!list.includes(get.suit(evt.card))) list.push(get.suit(evt.card)); + jingce: { + audio: "shelie", + trigger: { player: ["phaseJieshuBegin", "useCard1"] }, + filter(event, player) { + if (player.hasSkill("twshelie_round") || player != _status.currentPhase) + return false; + var list = []; + player.getHistory("useCard", function (evt) { + if ( + lib.suit.includes(get.suit(evt.card)) && + !list.includes(get.suit(evt.card)) + ) + list.push(get.suit(evt.card)); }); - if(list.length){ - player.addTempSkill('twshelie_count'); - player.storage.twshelie_count=list.sort(function(a,b){ - return lib.suit.indexOf(b)-lib.suit.indexOf(a); + if (list.length) { + player.addTempSkill("twshelie_count"); + player.storage.twshelie_count = list.sort(function (a, b) { + return lib.suit.indexOf(b) - lib.suit.indexOf(a); }); - player.markSkill('twshelie_count'); - player.syncStorage('twshelie_count'); + player.markSkill("twshelie_count"); + player.syncStorage("twshelie_count"); } - return event.name!='useCard'&&list.length>=player.hp; + return event.name != "useCard" && list.length >= player.hp; }, - forced:true, - locked:false, - content(){ - 'step 0' - player.addTempSkill('twshelie_round','roundStart'); - player.chooseControl('摸牌阶段','出牌阶段').set('prompt','涉猎:请选择要执行的额外阶段'); - 'step 1' - if(result.index==0){ - var next=player.phaseDraw(); + forced: true, + locked: false, + content() { + "step 0"; + player.addTempSkill("twshelie_round", "roundStart"); + player + .chooseControl("摸牌阶段", "出牌阶段") + .set("prompt", "涉猎:请选择要执行的额外阶段"); + "step 1"; + if (result.index == 0) { + var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); } - if(result.index==1){ - var next=player.phaseUse(); + if (result.index == 1) { + var next = player.phaseUse(); event.next.remove(next); trigger.getParent().next.push(next); } @@ -1798,2162 +2588,2647 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - twgongxin:{ - audio:'gongxin', - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + twgongxin: { + audio: "gongxin", + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; }, - usable:1, - content(){ - 'step 0' - event.num=target.getCards('h').reduce(function(arr,card){ - return arr.add(get.suit(card,player)),arr; - },[]).length; - 'step 1' - var cards=target.getCards('h'); - player.chooseButton(2,[ - '攻心', - cards, - [['弃置此牌','置于牌堆顶'],'tdnodes'], - ]).set('filterButton',function(button){ - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - return true; - }).set('ai',function(button){ - var target=_status.event.target; - var type=typeof button.link; - if(type=='object') return get.value(button.link,target); - }); - 'step 2' - if(result.bool){ - if(typeof result.links[0]!='string') result.links.reverse(); - var card=result.links[1],choice=result.links[0]; - if(choice=='弃置此牌') target.discard(card); + usable: 1, + content() { + "step 0"; + event.num = target.getCards("h").reduce(function (arr, card) { + return arr.add(get.suit(card, player)), arr; + }, []).length; + "step 1"; + var cards = target.getCards("h"); + player + .chooseButton(2, ["攻心", cards, [["弃置此牌", "置于牌堆顶"], "tdnodes"]]) + .set("filterButton", function (button) { + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + return true; + }) + .set("ai", function (button) { + var target = _status.event.target; + var type = typeof button.link; + if (type == "object") return get.value(button.link, target); + }); + "step 2"; + if (result.bool) { + if (typeof result.links[0] != "string") result.links.reverse(); + var card = result.links[1], + choice = result.links[0]; + if (choice == "弃置此牌") target.discard(card); else { - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【攻心】'); - target.lose(card,ui.cardPile,'visible','insert'); - game.log(card,'被置于了牌堆顶'); + player.showCards( + card, + get.translation(player) + "对" + get.translation(target) + "发动了【攻心】" + ); + target.lose(card, ui.cardPile, "visible", "insert"); + game.log(card, "被置于了牌堆顶"); } } - 'step 3' - if(event.num==target.getCards('h').reduce(function(arr,card){ - return arr.add(get.suit(card,player)),arr; - },[]).length) event.finish(); - 'step 4' - var num1=0; - for(var card of target.getCards('h')){ - if(get.color(card)=='red') num1++; + "step 3"; + if ( + event.num == + target.getCards("h").reduce(function (arr, card) { + return arr.add(get.suit(card, player)), arr; + }, []).length + ) + event.finish(); + "step 4"; + var num1 = 0; + for (var card of target.getCards("h")) { + if (get.color(card) == "red") num1++; } - var num2=target.countCards('h')-num1; - player.chooseControl(['红色','黑色','cancel2']).set('prompt','是否令'+get.translation(target)+'本回合无法使用一种颜色的牌?').set('ai',function(){ - return num1>=num2?'红色':'黑色'; - }); - 'step 5' - if(result.control!='cancel2'){ + var num2 = target.countCards("h") - num1; + player + .chooseControl(["红色", "黑色", "cancel2"]) + .set("prompt", "是否令" + get.translation(target) + "本回合无法使用一种颜色的牌?") + .set("ai", function () { + return num1 >= num2 ? "红色" : "黑色"; + }); + "step 5"; + if (result.control != "cancel2") { player.line(target); - target.addTempSkill('twgongxin2'); - target.markAuto('twgongxin2',[result.control=='红色'?'red':'black']); - game.log(target,'本回合无法使用'+result.control+'牌'); - if(!event.isMine()&&!event.isOnline()) game.delayx(); + target.addTempSkill("twgongxin2"); + target.markAuto("twgongxin2", [result.control == "红色" ? "red" : "black"]); + game.log(target, "本回合无法使用" + result.control + "牌"); + if (!event.isMine() && !event.isOnline()) game.delayx(); } }, - ai:{ - order:10, - expose:0.25, - result:{ - target(player,target){ - return -target.countCards('h'); + ai: { + order: 10, + expose: 0.25, + result: { + target(player, target) { + return -target.countCards("h"); }, }, }, }, - twgongxin2:{ - mod:{ - cardEnabled2(card,player){ + twgongxin2: { + mod: { + cardEnabled2(card, player) { const color = get.color(card); - if(color!='unsure' && player.getStorage('twgongxin2').includes(color)) return false; + if (color != "unsure" && player.getStorage("twgongxin2").includes(color)) + return false; }, }, - charlotte:true, - onremove:true, - intro:{content:'本回合内不能使用或打出$牌'}, + charlotte: true, + onremove: true, + intro: { content: "本回合内不能使用或打出$牌" }, }, //神张角 - yizhao:{ - audio:2, - trigger:{ - player:['useCard','respond'] + yizhao: { + audio: 2, + trigger: { + player: ["useCard", "respond"], }, - forced:true, - filter(event,player){ - return typeof get.number(event.card)=='number'; + forced: true, + filter(event, player) { + return typeof get.number(event.card) == "number"; }, - marktext:'黄', - intro:{ - name:'黄(异兆/肆军)', - name2:'黄', - content:'mark', - markcount(storage,player){ - return (storage||0).toString().slice(-2); + marktext: "黄", + intro: { + name: "黄(异兆/肆军)", + name2: "黄", + content: "mark", + markcount(storage, player) { + return (storage || 0).toString().slice(-2); }, }, - content(){ - 'step 0' - event.num=player.countMark('yizhao'); - player.addMark('yizhao',get.number(trigger.card)); - 'step 1' - var num=Math.floor(num/10)%10,num2=Math.floor(player.countMark('yizhao')/10)%10; - if(num!=num2){ - var card=get.cardPile2(card=>{ - return get.number(card,false)==num2; + content() { + "step 0"; + event.num = player.countMark("yizhao"); + player.addMark("yizhao", get.number(trigger.card)); + "step 1"; + var num = Math.floor(num / 10) % 10, + num2 = Math.floor(player.countMark("yizhao") / 10) % 10; + if (num != num2) { + var card = get.cardPile2((card) => { + return get.number(card, false) == num2; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } }, - mod:{ - aiOrder(player,card,num){ - if(Math.floor((get.number(card)+player.countMark('yizhao')%10)/10)==1) return num+10; + mod: { + aiOrder(player, card, num) { + if (Math.floor((get.number(card) + (player.countMark("yizhao") % 10)) / 10) == 1) + return num + 10; }, }, - ai:{ - threaten:1.5, - effect:{ - target(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,0.1]; - } - } - } - }, - sijun:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return player.countMark('yizhao')>ui.cardPile.childNodes.length; + ai: { + threaten: 1.5, + effect: { + target(card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 0.1]; + }, + }, }, - check(event,player){ + }, + sijun: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return player.countMark("yizhao") > ui.cardPile.childNodes.length; + }, + check(event, player) { return ui.cardPile.childNodes.length; }, - content(){ - 'step 0' - player.removeMark('yizhao',player.countMark('yizhao')); + content() { + "step 0"; + player.removeMark("yizhao", player.countMark("yizhao")); game.washCard(); - 'step 1' - var pile=Array.from(ui.cardPile.childNodes); - if(pile.length<3) return; - var bool=false,max=Math.pow(2,Math.min(100,pile.length)),index; - for(var i=0;i36) break; + for (var k = 0; k < index.length; k++) { + if (index[k] == "1") num += get.number(pile[k]); + if (num > 36) break; } - if(num==36){ - bool=true; + if (num == 36) { + bool = true; break; } } - if(bool){ - var cards=[]; - for(var k=0;kget.type2(evt.card))); - if(cards.filter(card=>!types.includes(get.type2(card))).length){ + }, + sanshou: { + audio: 2, + trigger: { player: "damageBegin4" }, + check(event, player) { + return get.damageEffect(player, event.source, player, event.nature) <= 0; + }, + content() { + "step 0"; + var cards = game.cardsGotoOrdering(get.cards(3)).cards; + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【三首】"); + "step 1"; + var types = []; + types.addArray(game.getGlobalHistory("useCard").map((evt) => get.type2(evt.card))); + if (cards.filter((card) => !types.includes(get.type2(card))).length) { trigger.cancel(); } game.delayx(); }, - ai:{ - effect:{ - target(card,player,target){ - if(card.name=='shandian'||card.name=='fulei') return [0,0.1]; - if(!get.tag(card,'damage')) return; - var types=[],bool=0; - types.addArray(game.getGlobalHistory('useCard').map(evt=>get.type2(evt.card))); - if(!types.includes(get.type2(card))) bool=1; - if(types.length<2) return Math.min(1,0.4+(types.length+bool)*0.2); - } - } + ai: { + effect: { + target(card, player, target) { + if (card.name == "shandian" || card.name == "fulei") return [0, 0.1]; + if (!get.tag(card, "damage")) return; + var types = [], + bool = 0; + types.addArray( + game.getGlobalHistory("useCard").map((evt) => get.type2(evt.card)) + ); + if (!types.includes(get.type2(card))) bool = 1; + if (types.length < 2) return Math.min(1, 0.4 + (types.length + bool) * 0.2); + }, + }, }, }, - tianjie:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - filter(event,player){ - return game.hasGlobalHistory('cardMove',evt=>evt.washCard)&&game.hasPlayer(current=>current!=player); + tianjie: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + filter(event, player) { + return ( + game.hasGlobalHistory("cardMove", (evt) => evt.washCard) && + game.hasPlayer((current) => current != player) + ); }, - skillAnimation:true, - animationColor:'metal', - content(){ - 'step 0' - player.chooseTarget(get.prompt('tianjie'),'选择至多三名其他角色,依次对这些角色造成X点雷电伤害(X为其手牌中【闪】的数量,至少为1)',[1,3]).set('ai',target=>{ - var player=_status.event.player; - return get.damageEffect(target,player,player,'thunder')*Math.sqrt(Math.max(1,target.countCards('h','shan'))); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; + skillAnimation: true, + animationColor: "metal", + content() { + "step 0"; + player + .chooseTarget( + get.prompt("tianjie"), + "选择至多三名其他角色,依次对这些角色造成X点雷电伤害(X为其手牌中【闪】的数量,至少为1)", + [1, 3] + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + get.damageEffect(target, player, player, "thunder") * + Math.sqrt(Math.max(1, target.countCards("h", "shan"))) + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.sortBySeat(); - player.logSkill('tianjie',targets); - for(var target of targets){ - var num=Math.max(1,target.countCards('h','shan')); - target.damage(num,'thunder'); + player.logSkill("tianjie", targets); + for (var target of targets) { + var num = Math.max(1, target.countCards("h", "shan")); + target.damage(num, "thunder"); } } }, }, - shencai:{ - audio:2, - enable:'phaseUse', - usable:5, - filter(event,player){ - var count=player.getStat('skill').shencai; - if(count&&count>player.countMark('shencai')) return false; + shencai: { + audio: 2, + enable: "phaseUse", + usable: 5, + filter(event, player) { + var count = player.getStat("skill").shencai; + if (count && count > player.countMark("shencai")) return false; return true; }, - filterTarget:lib.filter.notMe, - onremove:true, - prompt:'选择一名其他角色进行地狱审判', - content(){ - var next=target.judge(); - next.callback=lib.skill.shencai.contentx; + filterTarget: lib.filter.notMe, + onremove: true, + prompt: "选择一名其他角色进行地狱审判", + content() { + var next = target.judge(); + next.callback = lib.skill.shencai.contentx; }, - ai:{ - order:8, - result:{target:-1}, + ai: { + order: 8, + result: { target: -1 }, }, - contentx(){ - var card=event.judgeResult.card; - var player=event.getParent(2).player; - var target=event.getParent(2).target; - if(get.position(card,true)=='o') player.gain(card,'gain2'); - var list=[],str=lib.skill.shencai.getStr(card); - for(var i in lib.skill.shencai.filterx){ - if(str.indexOf(lib.skill.shencai.filterx[i])!=-1) list.push('shencai_'+i); + contentx() { + var card = event.judgeResult.card; + var player = event.getParent(2).player; + var target = event.getParent(2).target; + if (get.position(card, true) == "o") player.gain(card, "gain2"); + var list = [], + str = lib.skill.shencai.getStr(card); + for (var i in lib.skill.shencai.filterx) { + if (str.indexOf(lib.skill.shencai.filterx[i]) != -1) list.push("shencai_" + i); } - if(list.length){ - for(var i in lib.skill.shencai.filterx){ - var num=target.countMark('shencai_'+i); - if(num>0){ - target.removeMark('shencai_'+i,num); - target.removeSkill('shencai_'+i); + if (list.length) { + for (var i in lib.skill.shencai.filterx) { + var num = target.countMark("shencai_" + i); + if (num > 0) { + target.removeMark("shencai_" + i, num); + target.removeSkill("shencai_" + i); } } - if(target.isIn()){ - for(var i of list){ + if (target.isIn()) { + for (var i of list) { target.addSkill(i); - target.addMark(i,1); + target.addMark(i, 1); } } - } - else if(target.isIn()){ - player.gainPlayerCard(target,true,'hej'); - target.addMark('shencai_death',1); - target.addSkill('shencai_death'); + } else if (target.isIn()) { + player.gainPlayerCard(target, true, "hej"); + target.addMark("shencai_death", 1); + target.addSkill("shencai_death"); } }, - filterx:{ - losehp:'体力', - weapon:'武器', - respond:'打出', - distance:'距离', + filterx: { + losehp: "体力", + weapon: "武器", + respond: "打出", + distance: "距离", }, - getStr(node){ - var str='',name=node.name; - if(lib.translate[name+'_info']){ - if(lib.card[name].type&&lib.translate[lib.card[name].type]) str+=(''+get.translation(lib.card[name].type)+'牌|'); - if(get.subtype(name)){ - str+=(''+get.translation(get.subtype(name))+'|'); + getStr(node) { + var str = "", + name = node.name; + if (lib.translate[name + "_info"]) { + if (lib.card[name].type && lib.translate[lib.card[name].type]) + str += "" + get.translation(lib.card[name].type) + "牌|"; + if (get.subtype(name)) { + str += "" + get.translation(get.subtype(name)) + "|"; } - if(lib.card[name]&&lib.card[name].addinfomenu){ - str+=(''+lib.card[name].addinfomenu+'|'); + if (lib.card[name] && lib.card[name].addinfomenu) { + str += "" + lib.card[name].addinfomenu + "|"; } - if(get.subtype(name)=='equip1'){ - var added=false; - if(lib.card[node.name]&&lib.card[node.name].distance){ - var dist=lib.card[node.name].distance; - if(dist.attackFrom){ - added=true; - str+=('攻击范围:'+(-dist.attackFrom+1)+'|'); + if (get.subtype(name) == "equip1") { + var added = false; + if (lib.card[node.name] && lib.card[node.name].distance) { + var dist = lib.card[node.name].distance; + if (dist.attackFrom) { + added = true; + str += "攻击范围:" + (-dist.attackFrom + 1) + "|"; } } - if(!added){ - str+=('攻击范围:1|'); + if (!added) { + str += "攻击范围:1|"; } } } - if(lib.card[name].cardPrompt){ - str+=(''+lib.card[name].cardPrompt(node)+'|'); + if (lib.card[name].cardPrompt) { + str += "" + lib.card[name].cardPrompt(node) + "|"; + } else if (lib.translate[name + "_info"]) { + str += "" + lib.translate[name + "_info"] + "|"; } - else if(lib.translate[name+'_info']){ - str+=(''+lib.translate[name+'_info']+'|'); + if (lib.translate[name + "_append"]) { + str += "" + lib.translate[name + "_append"] + "|"; } - if(lib.translate[name+'_append']){ - str+=(''+lib.translate[name+'_append']+'|'); - } - if(get.is.yingbianConditional(node)){ - const yingbianEffects=get.yingbianEffects(node); - if(!yingbianEffects.length){ - const defaultYingbianEffect=get.defaultYingbianEffect(node); - if(lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect); + if (get.is.yingbianConditional(node)) { + const yingbianEffects = get.yingbianEffects(node); + if (!yingbianEffects.length) { + const defaultYingbianEffect = get.defaultYingbianEffect(node); + if (lib.yingbian.prompt.has(defaultYingbianEffect)) + yingbianEffects.push(defaultYingbianEffect); } - if(yingbianEffects.length) str+=`应变:${yingbianEffects.map(value=>lib.yingbian.prompt.get(value)).join(';')}|`; + if (yingbianEffects.length) + str += `应变:${yingbianEffects + .map((value) => lib.yingbian.prompt.get(value)) + .join(";")}|`; } return str; }, - subSkill:{ - losehp:{ - charlotte:true, - marktext:'笞', - trigger:{player:'damageEnd'}, - forced:true, - content(){ + subSkill: { + losehp: { + charlotte: true, + marktext: "笞", + trigger: { player: "damageEnd" }, + forced: true, + content() { player.loseHp(trigger.num); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.tag(card,'damage')&¤t<0) return 1.6; + ai: { + effect: { + target(card, player, target, current) { + if (get.tag(card, "damage") && current < 0) return 1.6; }, }, }, - intro:{ - name:'神裁 - 体力', - name2:'笞', - content:'锁定技。当你受到伤害后,你失去等量的体力。', - onunmark:true, + intro: { + name: "神裁 - 体力", + name2: "笞", + content: "锁定技。当你受到伤害后,你失去等量的体力。", + onunmark: true, }, }, - weapon:{ - charlotte:true, - marktext:'杖', - trigger:{target:'useCardToTargeted'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'; + weapon: { + charlotte: true, + marktext: "杖", + trigger: { target: "useCardToTargeted" }, + forced: true, + filter(event, player) { + return event.card.name == "sha"; }, - content(){ + content() { trigger.directHit.add(player); - game.log(player,'不可响应',trigger.card); + game.log(player, "不可响应", trigger.card); }, - intro:{ - name:'神裁 - 武器', - name2:'杖', - content:'锁定技。当你成为【杀】的目标后,你不能使用牌响应此【杀】。', - onunmark:true, + intro: { + name: "神裁 - 武器", + name2: "杖", + content: "锁定技。当你成为【杀】的目标后,你不能使用牌响应此【杀】。", + onunmark: true, }, - global:'shencai_weapon_ai', + global: "shencai_weapon_ai", }, - ai:{ - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(!arg||!arg.card||arg.card.name!='sha') return false; - if(!arg.target||!arg.target.hasSkill('shencai_weapon')) return false; + ai: { + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if (!arg || !arg.card || arg.card.name != "sha") return false; + if (!arg.target || !arg.target.hasSkill("shencai_weapon")) return false; return true; }, }, }, - respond:{ - charlotte:true, - marktext:'徒', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + respond: { + charlotte: true, + marktext: "徒", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter(event,player){ - if(!player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'shencai_respond'); - },'h')) return false; - var evt=event.getParent('shencai_respond'); - if(evt&&evt.player==player) return false; - evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length>0; + forced: true, + filter(event, player) { + if ( + !player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "shencai_respond"); + }, "h") + ) + return false; + var evt = event.getParent("shencai_respond"); + if (evt && evt.player == player) return false; + evt = event.getl(player); + return evt && evt.hs && evt.hs.length > 0; }, - content(){ - var cards=player.getCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'shencai_respond'); + content() { + var cards = player.getCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "shencai_respond"); }); - if(cards.length>0) player.discard(cards.randomGet()); + if (cards.length > 0) player.discard(cards.randomGet()); }, - intro:{ - name:'神裁 - 打出', - name2:'徒', - content:'锁定技。当你失去手牌后,你随机弃置一张手牌(不嵌套触发)。', - onunmark:true, + intro: { + name: "神裁 - 打出", + name2: "徒", + content: "锁定技。当你失去手牌后,你随机弃置一张手牌(不嵌套触发)。", + onunmark: true, }, }, - distance:{ - charlotte:true, - marktext:'流', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content(){ + distance: { + charlotte: true, + marktext: "流", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content() { player.turnOver(); }, - intro:{ - name:'神裁 - 距离', - name2:'流', - content:'锁定技。结束阶段开始时,你翻面。', - onunmark:true, + intro: { + name: "神裁 - 距离", + name2: "流", + content: "锁定技。结束阶段开始时,你翻面。", + onunmark: true, }, }, - death:{ - charlotte:true, - marktext:'死', - mod:{ - maxHandcard(player,num){ - return num-player.countMark('shencai_death'); + death: { + charlotte: true, + marktext: "死", + mod: { + maxHandcard(player, num) { + return num - player.countMark("shencai_death"); }, }, - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.countMark('shencai_death')>game.countPlayer(); + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.countMark("shencai_death") > game.countPlayer(); }, - content(){ + content() { player.die(); }, - intro:{ - name:'神裁 - 死', - name2:'死', - content:'锁定技。你的角色手牌上限-#;回合结束时,若场上存活人数小于#,则你死亡。', - onunmark:true, + intro: { + name: "神裁 - 死", + name2: "死", + content: + "锁定技。你的角色手牌上限-#;回合结束时,若场上存活人数小于#,则你死亡。", + onunmark: true, }, }, }, - intro:{ - content:'发动次数上限+#', + intro: { + content: "发动次数上限+#", }, }, - xunshi:{ - audio:2, - mod:{ - cardname(card){ - if(lib.skill.xunshi.isXunshi(card)) return 'sha'; + xunshi: { + audio: 2, + mod: { + cardname(card) { + if (lib.skill.xunshi.isXunshi(card)) return "sha"; }, - cardnature(card){ - if(lib.skill.xunshi.isXunshi(card)) return false; + cardnature(card) { + if (lib.skill.xunshi.isXunshi(card)) return false; }, - suit(card){ - if(lib.skill.xunshi.isXunshi(card)) return 'none'; + suit(card) { + if (lib.skill.xunshi.isXunshi(card)) return "none"; }, - targetInRange(card){ + targetInRange(card) { const suit = get.color(card); - if (suit=='none' || suit=='unsure') return true; + if (suit == "none" || suit == "unsure") return true; }, - cardUsable(card){ + cardUsable(card) { const suit = get.color(card); - if (suit=='none' || suit=='unsure') return Infinity; + if (suit == "none" || suit == "unsure") return Infinity; }, }, - isXunshi(card){ - var info=lib.card[card.name]; - if(!info||(info.type!='trick'&&info.type!='delay')) return false; - if(info.notarget) return false; - if(info.selectTarget!=undefined){ - if(Array.isArray(info.selectTarget)){ - if(info.selectTarget[0]<0) return !info.toself; - return info.selectTarget[0]!=1||info.selectTarget[1]!=1; - } - else{ - if(info.selectTarget<0) return !info.toself; - return info.selectTarget!=1; + isXunshi(card) { + var info = lib.card[card.name]; + if (!info || (info.type != "trick" && info.type != "delay")) return false; + if (info.notarget) return false; + if (info.selectTarget != undefined) { + if (Array.isArray(info.selectTarget)) { + if (info.selectTarget[0] < 0) return !info.toself; + return info.selectTarget[0] != 1 || info.selectTarget[1] != 1; + } else { + if (info.selectTarget < 0) return !info.toself; + return info.selectTarget != 1; } } return false; }, - trigger:{player:'useCard2'}, - forced:true, - filter(event,player){ - return get.color(event.card)=='none'; + trigger: { player: "useCard2" }, + forced: true, + filter(event, player) { + return get.color(event.card) == "none"; }, - content(){ - 'step 0' - if(player.countMark('shencai')<4&&player.hasSkill('shencai',null,null,false)) player.addMark('shencai',1,false); - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + content() { + "step 0"; + if (player.countMark("shencai") < 4 && player.hasSkill("shencai", null, null, false)) + player.addMark("shencai", 1, false); + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; } - var info=get.info(trigger.card); - if(info.allowMultiple==false) event.finish(); - else if(trigger.targets&&!info.multitarget){ - if(!game.hasPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,player,current); - })) event.finish(); - } - else event.finish(); - 'step 1' - var prompt2='为'+get.translation(trigger.card)+'增加任意个目标' - player.chooseTarget(get.prompt('xunshi'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - },[1,Infinity]).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 2' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + var info = get.info(trigger.card); + if (info.allowMultiple == false) event.finish(); + else if (trigger.targets && !info.multitarget) { + if ( + !game.hasPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, player, current) + ); + }) + ) + event.finish(); + } else event.finish(); + "step 1"; + var prompt2 = "为" + get.translation(trigger.card) + "增加任意个目标"; + player + .chooseTarget( + get.prompt("xunshi"), + function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }, + [1, Infinity] + ) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 2"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 3' - if(event.targets){ - player.line(event.targets,'fire'); + "step 3"; + if (event.targets) { + player.line(event.targets, "fire"); trigger.targets.addArray(event.targets); } }, }, - twwushen:{ - mod:{ - cardname(card,player,name){ - if(get.suit(card)=='heart') return 'sha'; + twwushen: { + mod: { + cardname(card, player, name) { + if (get.suit(card) == "heart") return "sha"; }, - cardnature(card,player){ - if(get.suit(card)=='heart') return false; + cardnature(card, player) { + if (get.suit(card) == "heart") return false; }, - targetInRange(card){ - if(card.name === 'sha'){ + targetInRange(card) { + if (card.name === "sha") { const suit = get.suit(card); - if (suit === 'heart' || suit === 'unsure') return true; + if (suit === "heart" || suit === "unsure") return true; } }, - cardUsable(card){ - if(card.name === 'sha'){ + cardUsable(card) { + if (card.name === "sha") { const suit = get.suit(card); - if (suit === 'heart' || suit === 'unsure') return Infinity; + if (suit === "heart" || suit === "unsure") return Infinity; } - } + }, }, - audio:'wushen', - trigger:{player:'useCard2'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'&&(get.suit(event.card)=='heart'||!player.hasSkill('twwushen_phase',null,null,false)); + audio: "wushen", + trigger: { player: "useCard2" }, + forced: true, + filter(event, player) { + return ( + event.card.name == "sha" && + (get.suit(event.card) == "heart" || + !player.hasSkill("twwushen_phase", null, null, false)) + ); }, - logTarget(event,player){ - if(get.suit(event.card)=='heart'){ - var targets=game.filterPlayer(function(current){ - return !event.targets.includes(current)&¤t.hasMark('twwuhun')&&lib.filter.targetEnabled(event.card,player,current); + logTarget(event, player) { + if (get.suit(event.card) == "heart") { + var targets = game.filterPlayer(function (current) { + return ( + !event.targets.includes(current) && + current.hasMark("twwuhun") && + lib.filter.targetEnabled(event.card, player, current) + ); }); - if(targets.length){ + if (targets.length) { return targets.sortBySeat(); } } return null; }, - content(){ - if(!player.hasSkill('twwushen_phase',null,null,false)){ + content() { + if (!player.hasSkill("twwushen_phase", null, null, false)) { trigger.directHit.addArray(game.players); - player.addTempSkill('twwushen_phase',['phaseZhunbeiAfter','phaseJudgeAfter','phaseDrawAfter','phaseUseAfter','phaseDiscardAfter','phaseJieshuAfter']) + player.addTempSkill("twwushen_phase", [ + "phaseZhunbeiAfter", + "phaseJudgeAfter", + "phaseDrawAfter", + "phaseUseAfter", + "phaseDiscardAfter", + "phaseJieshuAfter", + ]); } - if(get.suit(trigger.card)=='heart'){ - if(trigger.addCount!==false){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + if (get.suit(trigger.card) == "heart") { + if (trigger.addCount !== false) { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } } - var targets=game.filterPlayer(function(current){ - return !trigger.targets.includes(current)&¤t.hasMark('twwuhun')&&lib.filter.targetEnabled(trigger.card,player,current); + var targets = game.filterPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + current.hasMark("twwuhun") && + lib.filter.targetEnabled(trigger.card, player, current) + ); }); - if(targets.length){ + if (targets.length) { trigger.targets.addArray(targets.sortBySeat()); - game.log(targets,'也成为了',trigger.card,'的目标'); + game.log(targets, "也成为了", trigger.card, "的目标"); } } }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return arg.card.name=='sha'&&!player.hasSkill('twwushen_phase',null,null,false); + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return ( + arg.card.name == "sha" && !player.hasSkill("twwushen_phase", null, null, false) + ); }, }, - subSkill:{phase:{charlotte:true}}, - shaRelated:true, + subSkill: { phase: { charlotte: true } }, + shaRelated: true, }, - twwuhun:{ - audio:2, - trigger:{player:'die'}, - forceDie:true, - skillAnimation:true, - animationColor:'soil', - locked:true, - check(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.hasMark('twwuhun')&&get.attitude(player,current)<0; + twwuhun: { + audio: 2, + trigger: { player: "die" }, + forceDie: true, + skillAnimation: true, + animationColor: "soil", + locked: true, + check(event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && + current.hasMark("twwuhun") && + get.attitude(player, current) < 0 + ); }); }, - content(){ - 'step 0' - player.judge(function(card){ - var name=get.name(card,false); - if(name=='tao'||name=='taoyuan') return -25; - return 15; - }).set('forceDie',true).judge2=function(result){ - return result.bool; - }; - 'step 1' - var num=game.countPlayer(function(current){ - return current!=player&¤t.hasMark('twwuhun'); + content() { + "step 0"; + player + .judge(function (card) { + var name = get.name(card, false); + if (name == "tao" || name == "taoyuan") return -25; + return 15; + }) + .set("forceDie", true).judge2 = function (result) { + return result.bool; + }; + "step 1"; + var num = game.countPlayer(function (current) { + return current != player && current.hasMark("twwuhun"); }); - if(result.bool&&num>0){ - player.chooseTarget('请选择【武魂】的目标','选择至少一名拥有“梦魇”标记的角色。令这些角色各自失去X点体力(X为其“梦魇”标记数)',true,[1,num],function(card,player,target){ - return target!=player&&target.hasMark('twwuhun'); - }).set('forceDie',true).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - } - else event.finish(); - 'step 2' - var targets=result.targets.sortBySeat(); - player.line(targets,'fire'); - event.targets=targets; - 'step 3' - var target=targets.shift(); - var num=target.countMark('twwuhun'); - if(num>0) target.loseHp(num); - if(targets.length>0) event.redo(); + if (result.bool && num > 0) { + player + .chooseTarget( + "请选择【武魂】的目标", + "选择至少一名拥有“梦魇”标记的角色。令这些角色各自失去X点体力(X为其“梦魇”标记数)", + true, + [1, num], + function (card, player, target) { + return target != player && target.hasMark("twwuhun"); + } + ) + .set("forceDie", true) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + } else event.finish(); + "step 2"; + var targets = result.targets.sortBySeat(); + player.line(targets, "fire"); + event.targets = targets; + "step 3"; + var target = targets.shift(); + var num = target.countMark("twwuhun"); + if (num > 0) target.loseHp(num); + if (targets.length > 0) event.redo(); }, - marktext:'魇', - intro:{ - name:'梦魇', - content:'mark', - onunmark:true, + marktext: "魇", + intro: { + name: "梦魇", + content: "mark", + onunmark: true, }, - group:'twwuhun_gain', - subSkill:{ - gain:{ - audio:'twwuhun', - trigger:{ - player:'damageEnd', - source:'damageSource', + group: "twwuhun_gain", + subSkill: { + gain: { + audio: "twwuhun", + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - filter(event,player,name){ - if(event.player==event.source) return false; - var target=lib.skill.twwuhun_gain.logTarget(event,player); - if(!target||!target.isIn()) return false; - return name=='damageEnd'||target.hasMark('twwuhun'); + forced: true, + filter(event, player, name) { + if (event.player == event.source) return false; + var target = lib.skill.twwuhun_gain.logTarget(event, player); + if (!target || !target.isIn()) return false; + return name == "damageEnd" || target.hasMark("twwuhun"); }, - logTarget(event,player){ - if(player==event.player) return event.source; + logTarget(event, player) { + if (player == event.player) return event.source; return event.player; }, - content(){ - var target=lib.skill.twwuhun_gain.logTarget(trigger,player); - target.addMark('twwuhun',player==trigger.source?1:trigger.num); + content() { + var target = lib.skill.twwuhun_gain.logTarget(trigger, player); + target.addMark("twwuhun", player == trigger.source ? 1 : trigger.num); game.delayx(); }, }, }, - ai:{ - notemp:true, - maixie_defend:true, - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')||!target.hasFriend()) return; - let die=[],extra=[null,0],temp; - game.filterPlayer(i=>{ - if(!i.hasMark('twwuhun')) return false; - temp=get.attitude(target,i); - if(temp<0) die.push(i); - else{ - temp=Math.sqrt(temp)*i.countMark('twwuhun'); - if(!extra[0]||temp { + if (!get.tag(card, "damage") || !target.hasFriend()) return; + let die = [], + extra = [null, 0], + temp; + game.filterPlayer((i) => { + if (!i.hasMark("twwuhun")) return false; + temp = get.attitude(target, i); + if (temp < 0) die.push(i); + else { + temp = Math.sqrt(temp) * i.countMark("twwuhun"); + if (!extra[0] || temp < extra[1]) extra = [i, temp]; } }); - if(extra[0]&&!die.length) die.push(extra[0]); - if(target.hp+target.hujia>1&&(!die.length||get.attitude(player,target)<=0)) die.add(player); - if(die.length) return [1,0,1,die.reduce((num,i)=>{ - return num-=2*get.sgnAttitude(player,i); - },0)]; - } - } - } - }, - shouli:{ - audio:2, - mod:{ - cardUsable(card){ - if(card.storage&&card.storage.shouli) return Infinity; + if (extra[0] && !die.length) die.push(extra[0]); + if ( + target.hp + target.hujia > 1 && + (!die.length || get.attitude(player, target) <= 0) + ) + die.add(player); + if (die.length) + return [ + 1, + 0, + 1, + die.reduce((num, i) => { + return (num -= 2 * get.sgnAttitude(player, i)); + }, 0), + ]; + }, }, }, - enable:['chooseToUse','chooseToRespond'], - hiddenCard(player,name){ - if(player!=_status.currentPhase&&(name=='sha'||name=='shan')) return true; + }, + shouli: { + audio: 2, + mod: { + cardUsable(card) { + if (card.storage && card.storage.shouli) return Infinity; + }, }, - filter(event,player){ - if(event.responded||event.shouli||event.type=='wuxie') return false; - if(game.hasPlayer(function(current){ - return current.getCards('e',card=>get.is.attackingMount(card)).length>0; - })&&event.filterCard(get.autoViewAs({ - name:'sha', - storage:{shouli:true}, - },'unsure'),player,event)) return true; - if(game.hasPlayer(function(current){ - return current.getCards('e',card=>get.is.defendingMount(card)).length>0; - })&&event.filterCard(get.autoViewAs({ - name:'shan', - storage:{shouli:true}, - },'unsure'),player,event)) return true; + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard(player, name) { + if (player != _status.currentPhase && (name == "sha" || name == "shan")) return true; + }, + filter(event, player) { + if (event.responded || event.shouli || event.type == "wuxie") return false; + if ( + game.hasPlayer(function (current) { + return current.getCards("e", (card) => get.is.attackingMount(card)).length > 0; + }) && + event.filterCard( + get.autoViewAs( + { + name: "sha", + storage: { shouli: true }, + }, + "unsure" + ), + player, + event + ) + ) + return true; + if ( + game.hasPlayer(function (current) { + return current.getCards("e", (card) => get.is.defendingMount(card)).length > 0; + }) && + event.filterCard( + get.autoViewAs( + { + name: "shan", + storage: { shouli: true }, + }, + "unsure" + ), + player, + event + ) + ) + return true; return false; }, - delay:false, - locked:false, - filterTarget(card,player,target){ - var event=_status.event,evt=event; - if(event._backup) evt=event._backup; - var equip3=target.getCards('e',card=>get.is.defendingMount(card,false)); - var equip4=target.getCards('e',card=>get.is.attackingMount(card,false)); - if(equip3.length&&equip3.some(card=>evt.filterCard(get.autoViewAs({ - name:'shan', - storage:{shouli:true}, - },[card]),player,event))) return true; - return equip4.some(card=>{ - var sha=get.autoViewAs({ - name:'sha', - storage:{shouli:true}, - },[card]); - if(evt.filterCard(sha,player,event)){ - if(!evt.filterTarget) return true; - return game.hasPlayer(function(current){ - return evt.filterTarget(sha,player,current); - }) - } - }) - }, - prompt:'将场上的一张坐骑牌当做【杀】或【闪】使用或打出', - content(){ - 'step 0' - var evt=event.getParent(2); - evt.set('shouli',true); - var list=[]; - var equip3=target.getCards('e',card=>get.is.defendingMount(card,false)); - var equip4=target.getCards('e',card=>get.is.attackingMount(card,false)); - var backupx=_status.event; - _status.event=evt; - try{ - if(equip3.length&&equip3.some(card=>{ - var shan=get.autoViewAs({ - name:'shan', - storage:{shouli:true}, - },[card]); - if(evt.filterCard(shan,player,event)) return true; - return false; - })){ - list.push('shan'); - } - if(equip4.length&&equip4.some(card=>{ - var sha=get.autoViewAs({ - name:'sha', - storage:{shouli:true}, - },[card]); - if(evt.filterCard(sha,player,evt)&&(!evt.filterTarget||game.hasPlayer(function(current){ - return evt.filterTarget(sha,player,current); - }))) return true; - return false; - })){ - list.push('sha'); - } - }catch(e){game.print(e)} - _status.event=backupx; - if(list.length==1){ - event.cardName=list[0]; - var cards=list[0]=='shan'?equip3:equip4; - if(cards.length==1) event._result={ - bool:true, - links:[cards[0]], - } - else player.choosePlayerCard(true,target,'e').set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards) - } - else player.choosePlayerCard(true,target,'e').set('filterButton',function(button){ - var card=button.link; - return get.is.attackingMount(card)||get.is.defendingMount(card); - }); - 'step 1' - var evt=event.getParent(2); - if(result.bool&&result.links&&result.links.length){ - var name=(event.cardName||(get.is.attackingMount(result.links[0])?'sha':'shan')); - if(evt.name=='chooseToUse'){ - game.broadcastAll(function(result,name){ - lib.skill.shouli_backup.viewAs={ - name:name, - cards:[result], - storage:{shouli:true}, - }; - lib.skill.shouli_backup.prompt=('选择'+get.translation(name)+'('+get.translation(result)+')的目标'); - },result.links[0],name); - evt.set('_backupevent','shouli_backup'); - evt.backup('shouli_backup'); - evt.set('openskilldialog','选择'+get.translation(name)+'('+get.translation(result.links[0])+')的目标'); - evt.set('norestore',true); - evt.set('custom',{ - add:{}, - replace:{window(){}} + delay: false, + locked: false, + filterTarget(card, player, target) { + var event = _status.event, + evt = event; + if (event._backup) evt = event._backup; + var equip3 = target.getCards("e", (card) => get.is.defendingMount(card, false)); + var equip4 = target.getCards("e", (card) => get.is.attackingMount(card, false)); + if ( + equip3.length && + equip3.some((card) => + evt.filterCard( + get.autoViewAs( + { + name: "shan", + storage: { shouli: true }, + }, + [card] + ), + player, + event + ) + ) + ) + return true; + return equip4.some((card) => { + var sha = get.autoViewAs( + { + name: "sha", + storage: { shouli: true }, + }, + [card] + ); + if (evt.filterCard(sha, player, event)) { + if (!evt.filterTarget) return true; + return game.hasPlayer(function (current) { + return evt.filterTarget(sha, player, current); }); } - else{ + }); + }, + prompt: "将场上的一张坐骑牌当做【杀】或【闪】使用或打出", + content() { + "step 0"; + var evt = event.getParent(2); + evt.set("shouli", true); + var list = []; + var equip3 = target.getCards("e", (card) => get.is.defendingMount(card, false)); + var equip4 = target.getCards("e", (card) => get.is.attackingMount(card, false)); + var backupx = _status.event; + _status.event = evt; + try { + if ( + equip3.length && + equip3.some((card) => { + var shan = get.autoViewAs( + { + name: "shan", + storage: { shouli: true }, + }, + [card] + ); + if (evt.filterCard(shan, player, event)) return true; + return false; + }) + ) { + list.push("shan"); + } + if ( + equip4.length && + equip4.some((card) => { + var sha = get.autoViewAs( + { + name: "sha", + storage: { shouli: true }, + }, + [card] + ); + if ( + evt.filterCard(sha, player, evt) && + (!evt.filterTarget || + game.hasPlayer(function (current) { + return evt.filterTarget(sha, player, current); + })) + ) + return true; + return false; + }) + ) { + list.push("sha"); + } + } catch (e) { + game.print(e); + } + _status.event = backupx; + if (list.length == 1) { + event.cardName = list[0]; + var cards = list[0] == "shan" ? equip3 : equip4; + if (cards.length == 1) + event._result = { + bool: true, + links: [cards[0]], + }; + else + player + .choosePlayerCard(true, target, "e") + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set("cards", cards); + } else + player.choosePlayerCard(true, target, "e").set("filterButton", function (button) { + var card = button.link; + return get.is.attackingMount(card) || get.is.defendingMount(card); + }); + "step 1"; + var evt = event.getParent(2); + if (result.bool && result.links && result.links.length) { + var name = + event.cardName || (get.is.attackingMount(result.links[0]) ? "sha" : "shan"); + if (evt.name == "chooseToUse") { + game.broadcastAll( + function (result, name) { + lib.skill.shouli_backup.viewAs = { + name: name, + cards: [result], + storage: { shouli: true }, + }; + lib.skill.shouli_backup.prompt = + "选择" + + get.translation(name) + + "(" + + get.translation(result) + + ")的目标"; + }, + result.links[0], + name + ); + evt.set("_backupevent", "shouli_backup"); + evt.backup("shouli_backup"); + evt.set( + "openskilldialog", + "选择" + + get.translation(name) + + "(" + + get.translation(result.links[0]) + + ")的目标" + ); + evt.set("norestore", true); + evt.set("custom", { + add: {}, + replace: { window() { } }, + }); + } else { delete evt.result.skill; delete evt.result.used; - evt.result.card=get.autoViewAs({ - name:name, - cards:[result.links[0]], - storage:{shouli:true}, - },result.links); - evt.result.cards=[result.links[0]]; - target.$give(result.links[0],player,false); - if(player!=target) target.addTempSkill('fengyin'); - target.addTempSkill('shouli_thunder'); - player.addTempSkill('shouli_thunder'); + evt.result.card = get.autoViewAs( + { + name: name, + cards: [result.links[0]], + storage: { shouli: true }, + }, + result.links + ); + evt.result.cards = [result.links[0]]; + target.$give(result.links[0], player, false); + if (player != target) target.addTempSkill("fengyin"); + target.addTempSkill("shouli_thunder"); + player.addTempSkill("shouli_thunder"); evt.redo(); return; } } evt.goto(0); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ - var func=get.is[tag=='respondSha'?'attackingMount':'defendingMount']; - return game.hasPlayer(function(current){ - return current.hasCard(card=>func(card,false),'e'); + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { + var func = get.is[tag == "respondSha" ? "attackingMount" : "defendingMount"]; + return game.hasPlayer(function (current) { + return current.hasCard((card) => func(card, false), "e"); }); }, - order:2, - result:{ - player(player,target){ - var att=Math.max(8,get.attitude(player,target)); - if(_status.event.type!='phase') return 9-att; - if(!player.hasValueTarget({name:'sha'})) return 0; - return 9-att; + order: 2, + result: { + player(player, target) { + var att = Math.max(8, get.attitude(player, target)); + if (_status.event.type != "phase") return 9 - att; + if (!player.hasValueTarget({ name: "sha" })) return 0; + return 9 - att; }, }, }, - group:'shouli_init', - subSkill:{ - thunder:{ - charlotte:true, - trigger:{player:'damageBegin1'}, - forced:true, - mark:true, - content(){ + group: "shouli_init", + subSkill: { + thunder: { + charlotte: true, + trigger: { player: "damageBegin1" }, + forced: true, + mark: true, + content() { trigger.num++; - game.setNature(trigger,'thunder'); + game.setNature(trigger, "thunder"); }, - marktext:'⚡', - intro:{ - content:'受到的伤害+1且改为雷属性', + marktext: "⚡", + intro: { + content: "受到的伤害+1且改为雷属性", }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')) return; - if(target.hasSkillTag('nodamage')||target.hasSkillTag('nothunder')) return 'zeroplayertarget'; - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:new lib.element.VCard({ - name:card.name, - nature:'thunder' - },[card]) - })) return; + ai: { + effect: { + target: (card, player, target) => { + if (!get.tag(card, "damage")) return; + if (target.hasSkillTag("nodamage") || target.hasSkillTag("nothunder")) + return "zeroplayertarget"; + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: new lib.element.VCard( + { + name: card.name, + nature: "thunder", + }, + [card] + ), + }) + ) + return; return 2; - } - } - } + }, + }, + }, }, - init:{ - audio:'shouli', - trigger:{ - global:'phaseBefore', - player:'enterGame', + init: { + audio: "shouli", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + locked: false, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - logTarget:()=>game.filterPlayer(), - content(){ - 'step 0' - var targets=game.filterPlayer().sortBySeat(player.getNext()); - event.targets=targets; - event.num=0; - 'step 1' - var target=event.targets[num]; - if(target.isIn()){ - var card=get.cardPile2(function(card){ - if(get.cardtag(card,'gifts')) return false; - var type=get.subtype(card); - if(type!='equip3'&&type!='equip4'&&type!='equip6') return false; - return target.canUse(card,target); + logTarget: () => game.filterPlayer(), + content() { + "step 0"; + var targets = game.filterPlayer().sortBySeat(player.getNext()); + event.targets = targets; + event.num = 0; + "step 1"; + var target = event.targets[num]; + if (target.isIn()) { + var card = get.cardPile2(function (card) { + if (get.cardtag(card, "gifts")) return false; + var type = get.subtype(card); + if (type != "equip3" && type != "equip4" && type != "equip6") + return false; + return target.canUse(card, target); }); - if(card) target.chooseUseTarget(card,'nopopup','noanimate',true); + if (card) target.chooseUseTarget(card, "nopopup", "noanimate", true); } event.num++; - if(event.num{ - if(typeof card!=='object') return; - let suit=get.suit(card); - if(!lib.suit.includes(suit)||player.hasCard(function(i){ - return get.suit(i,player)==suit; - },'h')) return; - return [1,0.8*game.countPlayer(current=>{ - return current.countCards('e',card=>{ - return get.suit(card,current)==suit; - }); - })]; + ai: { + effect: { + player: (card, player, target) => { + if (typeof card !== "object") return; + let suit = get.suit(card); + if ( + !lib.suit.includes(suit) || + player.hasCard(function (i) { + return get.suit(i, player) == suit; + }, "h") + ) + return; + return [ + 1, + 0.8 * + game.countPlayer((current) => { + return current.countCards("e", (card) => { + return get.suit(card, current) == suit; + }); + }), + ]; }, - target:(card,player,target)=>{ - if(card.name==='sha'&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card - },true)&&game.hasPlayer(current=>{ - return current.hasCard(cardx=>{ - return get.subtype(cardx)==='equip3'; - },'e'); - })) return [0, -0.5]; - } - } - } - }, - changandajian_equip5:{ - equipSkill:true, - mod:{maxHandcard:(player,num)=>num+2}, - }, - changandajian_destroy:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + target: (card, player, target) => { + if ( + card.name === "sha" && + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) && + game.hasPlayer((current) => { + return current.hasCard((cardx) => { + return get.subtype(cardx) === "equip3"; + }, "e"); + }) + ) + return [0, -0.5]; + }, + }, }, - forced:true, - charlotte:true, - equipSkill:true, - filter(event,player){ - var evt=event.getl(player); - if(!evt||!evt.es||!evt.es.length) return false; - for(var i of evt.es){ - if(i.name.indexOf('changandajian_equip')==0) return true; + }, + changandajian_equip5: { + equipSkill: true, + mod: { maxHandcard: (player, num) => num + 2 }, + }, + changandajian_destroy: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + forced: true, + charlotte: true, + equipSkill: true, + filter(event, player) { + var evt = event.getl(player); + if (!evt || !evt.es || !evt.es.length) return false; + for (var i of evt.es) { + if (i.name.indexOf("changandajian_equip") == 0) return true; } return false; }, - getEffect(player,target){ - if(player==target) return 0; - var getRaw=function(){ - var att=get.attitude(player,target); - if(att>0){ - if(target.countCards('j',function(card){ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(target,cardj,target,player)<0; - })>0) return 3; - if(target.getEquip('baiyin')&&target.isDamaged()&& - get.recoverEffect(target,player,player)>0){ - if(target.hp==1&&!target.hujia) return 1.6; + getEffect(player, target) { + if (player == target) return 0; + var getRaw = function () { + var att = get.attitude(player, target); + if (att > 0) { + if ( + target.countCards("j", function (card) { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(target, cardj, target, player) < 0; + }) > 0 + ) + return 3; + if ( + target.getEquip("baiyin") && + target.isDamaged() && + get.recoverEffect(target, player, player) > 0 + ) { + if (target.hp == 1 && !target.hujia) return 1.6; } - if(target.countCards('e',function(card){ - if(get.position(card)=='e') return get.value(card,target)<0; - })>0) return 1; + if ( + target.countCards("e", function (card) { + if (get.position(card) == "e") return get.value(card, target) < 0; + }) > 0 + ) + return 1; } - var es=target.getCards('e'); - var noe=(es.length==0||target.hasSkillTag('noe')); - var noe2=(es.filter(function(esx){ - return get.value(esx,target)>0; - }).length==0); - if(noe||noe2) return 0; - if(att<=0&&!target.countCards('e')) return 1.5; + var es = target.getCards("e"); + var noe = es.length == 0 || target.hasSkillTag("noe"); + var noe2 = + es.filter(function (esx) { + return get.value(esx, target) > 0; + }).length == 0; + if (noe || noe2) return 0; + if (att <= 0 && !target.countCards("e")) return 1.5; return -1.5; - } - return getRaw()*get.attitude(player,target); + }; + return getRaw() * get.attitude(player, target); }, - content(){ - 'step 0' - var num=0,recover=0; - var evt=trigger.getl(player); - for(var i of evt.es){ - if(i.name.indexOf('changandajian_equip')==0) num++; - if(i.name=='changandajian_equip2') recover++; + content() { + "step 0"; + var num = 0, + recover = 0; + var evt = trigger.getl(player); + for (var i of evt.es) { + if (i.name.indexOf("changandajian_equip") == 0) num++; + if (i.name == "changandajian_equip2") recover++; } - if(recover>0) player.recover(recover); - event.count=num; - if(!game.hasPlayer(function(current){ - return current.countCards('ej')>0; - })) event.finish(); - 'step 1' + if (recover > 0) player.recover(recover); + event.count = num; + if ( + !game.hasPlayer(function (current) { + return current.countCards("ej") > 0; + }) + ) + event.finish(); + "step 1"; event.count--; - player.chooseTarget(true,'选择一名装备区或判定区有牌的角色',function(card,player,target){ - return target.countCards('ej')>0; - }).set('ai',function(target){ - return lib.skill.changandajian_destroy.getEffect(_status.event.player,target); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - player.choosePlayerCard(target,true,'ej'); - } - else event.finish(); - 'step 3' - if(result.bool){ - var card=result.cards[0]; - var num=get.number(card); - if([1,11,12,13].includes(num)){ - if(lib.filter.canBeGained(card,player,target)) player.gain(card,target,'give','bySelf'); - } - else if(lib.filter.canBeDiscarded(card,player,target)) target.discard(card); - } - else event.finish(); - 'step 4' - if(event.count>0&&game.hasPlayer(function(current){ - return current.countCards('ej')>0; - })) event.goto(1); + player + .chooseTarget( + true, + "选择一名装备区或判定区有牌的角色", + function (card, player, target) { + return target.countCards("ej") > 0; + } + ) + .set("ai", function (target) { + return lib.skill.changandajian_destroy.getEffect(_status.event.player, target); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + player.choosePlayerCard(target, true, "ej"); + } else event.finish(); + "step 3"; + if (result.bool) { + var card = result.cards[0]; + var num = get.number(card); + if ([1, 11, 12, 13].includes(num)) { + if (lib.filter.canBeGained(card, player, target)) + player.gain(card, target, "give", "bySelf"); + } else if (lib.filter.canBeDiscarded(card, player, target)) target.discard(card); + } else event.finish(); + "step 4"; + if ( + event.count > 0 && + game.hasPlayer(function (current) { + return current.countCards("ej") > 0; + }) + ) + event.goto(1); }, }, - dili:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dili: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - if(player.storage.dili) return false; - if(event.name!='phase') return true; - if(game.phaseNumber==0) return true; + forced: true, + filter(event, player) { + if (player.storage.dili) return false; + if (event.name != "phase") return true; + if (game.phaseNumber == 0) return true; //让神山识能够获得东吴命运线 - return player.name=='key_shiki'; + return player.name == "key_shiki"; }, - content(){ - player.storage.dili=true; - var skill=['dili_shengzhi','dili_chigang','dili_qionglan','dili_quandao','dili_jiaohui','dili_yuanlv'].randomGet(); + content() { + player.storage.dili = true; + var skill = [ + "dili_shengzhi", + "dili_chigang", + "dili_qionglan", + "dili_quandao", + "dili_jiaohui", + "dili_yuanlv", + ].randomGet(); player.addSkill(skill); - game.log(player,'解锁了东吴命运线:','#g【'+get.translation(skill)+'】'); + game.log( + player, + '解锁了东吴命运线:', + "#g【" + get.translation(skill) + "】" + ); }, - derivation:['dili_shengzhi','dili_chigang','dili_qionglan','dili_quandao','dili_jiaohui','dili_yuanlv','gzyinghun','hongde','rebingyi','xinfu_guanwei','bizheng','xinanguo','shelie','wengua','rebotu','rezhiheng','jiexun','reanxu','xiashu','rejieyin','oldimeng','xinfu_guanchao','drlt_jueyan','lanjiang'], - subSkill:{ - shengzhi:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - var num=get.number(event.card); - if(typeof num!='number') return false; - if(num<=1) return false; - for(var i=2;i<=Math.sqrt(num);i++){ - if(num%i==0) return false; + derivation: [ + "dili_shengzhi", + "dili_chigang", + "dili_qionglan", + "dili_quandao", + "dili_jiaohui", + "dili_yuanlv", + "gzyinghun", + "hongde", + "rebingyi", + "xinfu_guanwei", + "bizheng", + "xinanguo", + "shelie", + "wengua", + "rebotu", + "rezhiheng", + "jiexun", + "reanxu", + "xiashu", + "rejieyin", + "oldimeng", + "xinfu_guanchao", + "drlt_jueyan", + "lanjiang", + ], + subSkill: { + shengzhi: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + var num = get.number(event.card); + if (typeof num != "number") return false; + if (num <= 1) return false; + for (var i = 2; i <= Math.sqrt(num); i++) { + if (num % i == 0) return false; } - if(!player.storage.yuheng) return false; - var list=['gzyinghun','hongde','rebingyi']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return false; + if (!player.storage.yuheng) return false; + var list = ["gzyinghun", "hongde", "rebingyi"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return false; } return true; }, - content(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player; - })); + content() { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player; + }) + ); }, - init(player,skill){ - player.markAuto('yuheng_current',['gzyinghun','hongde','rebingyi']); + init(player, skill) { + player.markAuto("yuheng_current", ["gzyinghun", "hongde", "rebingyi"]); }, - mark:true, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(arg&&arg.card){ - var num=get.number(arg.card); - if(typeof num!='number') return false; - if(num<=1) return false; - for(var i=2;i<=Math.sqrt(num);i++){ - if(num%i==0) return false; + mark: true, + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if (arg && arg.card) { + var num = get.number(arg.card); + if (typeof num != "number") return false; + if (num <= 1) return false; + for (var i = 2; i <= Math.sqrt(num); i++) { + if (num % i == 0) return false; } return true; } return false; }, }, - intro:{ - name:'命运线:圣质', - content(storage,player){ - var finished=[],unfinished=['gzyinghun','hongde','rebingyi']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技。若你因〖驭衡〗获得过〖英魂〗〖弘德〗〖秉壹〗,则当你使用点数为质数的牌时,此牌不可被响应。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + "
            • 锁定技。若你因〖驭衡〗获得过〖英魂〗〖弘德〗〖秉壹〗,则当你使用点数为质数的牌时,此牌不可被响应。"; return str; }, }, }, - chigang:{ - audio:2, - trigger:{player:'phaseJudgeBefore'}, - forced:true, - filter(event,player){ - if(!player.storage.yuheng) return false; - var list=['xinfu_guanwei','bizheng','xinanguo']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return false; + chigang: { + audio: 2, + trigger: { player: "phaseJudgeBefore" }, + forced: true, + filter(event, player) { + if (!player.storage.yuheng) return false; + var list = ["xinfu_guanwei", "bizheng", "xinanguo"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return false; } return true; }, - content(){ + content() { trigger.cancel(); - var next=player.phaseDraw(); + var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); }, - init(player,skill){ - player.markAuto('yuheng_current',['xinfu_guanwei','bizheng','xinanguo']); + init(player, skill) { + player.markAuto("yuheng_current", ["xinfu_guanwei", "bizheng", "xinanguo"]); }, - ai:{ - effect:{ - target(card){ - if(get.type(card)=='delay') return 'zerotarget'; + ai: { + effect: { + target(card) { + if (get.type(card) == "delay") return "zerotarget"; }, }, }, - mark:true, - intro:{ - name:'命运线:持纲', - content(storage,player){ - var finished=[],unfinished=['xinfu_guanwei','bizheng','xinanguo']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技。若你因〖驭衡〗获得过〖观微〗〖弼政〗〖安国〗,则当你的判定阶段开始前,你跳过此阶段并获得一个额外的摸牌阶段。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + "
            • 锁定技。若你因〖驭衡〗获得过〖观微〗〖弼政〗〖安国〗,则当你的判定阶段开始前,你跳过此阶段并获得一个额外的摸牌阶段。"; return str; }, }, }, - qionglan:{ - audio:2, - init(player,skill){ - player.markAuto('yuheng_current',['shelie','wengua','rebotu']); + qionglan: { + audio: 2, + init(player, skill) { + player.markAuto("yuheng_current", ["shelie", "wengua", "rebotu"]); }, - trigger:{player:'useSkillAfter'}, - forced:true, - limited:true, - filter(event,player){ - if(!player.storage.yuheng||event.skill!='yuheng') return false; - var list=['shelie','wengua','rebotu']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return false; + trigger: { player: "useSkillAfter" }, + forced: true, + limited: true, + filter(event, player) { + if (!player.storage.yuheng || event.skill != "yuheng") return false; + var list = ["shelie", "wengua", "rebotu"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return false; } return true; }, - content(){ - player.awakenSkill('dili_qionglan'); - var list=['dili_shengzhi','dili_chigang','dili_quandao','dili_jiaohui','dili_yuanlv']; - var list2=list.randomRemove(2); - if(list2.includes('dili_quandao')&&list2.includes('dili_jiaohui')){ + content() { + player.awakenSkill("dili_qionglan"); + var list = [ + "dili_shengzhi", + "dili_chigang", + "dili_quandao", + "dili_jiaohui", + "dili_yuanlv", + ]; + var list2 = list.randomRemove(2); + if (list2.includes("dili_quandao") && list2.includes("dili_jiaohui")) { list2.randomRemove(1); list2.push(list.randomGet()); } - for(var skill of list2){ + for (var skill of list2) { player.addSkill(skill); - game.log(player,'解锁了东吴命运线:','#g【'+get.translation(skill)+'】'); + game.log( + player, + '解锁了东吴命运线:', + "#g【" + get.translation(skill) + "】" + ); } }, - mark:true, - intro:{ - name:'命运线:穹览', - content(storage,player){ - var finished=[],unfinished=['shelie','wengua','rebotu']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技,限定技。若你因〖驭衡〗获得过〖涉猎〗〖问卦〗〖博图〗,则当你发动的〖驭衡〗结算结束后,你随机获得两条其他东吴命运线。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + '
            • 锁定技,限定技。若你因〖驭衡〗获得过〖涉猎〗〖问卦〗〖博图〗,则当你发动的〖驭衡〗结算结束后,你随机获得两条其他东吴命运线。'; return str; }, }, }, - quandao:{ - audio:2, - mod:{ - cardname(card,player){ - if(player.storage.yuheng&&[1,11,12,13].includes(card.number)){ - var list=['rezhiheng','jiexun','reanxu']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return; + quandao: { + audio: 2, + mod: { + cardname(card, player) { + if (player.storage.yuheng && [1, 11, 12, 13].includes(card.number)) { + var list = ["rezhiheng", "jiexun", "reanxu"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return; } - return 'tiaojiyanmei'; + return "tiaojiyanmei"; } }, }, - init(player,skill){ - player.markAuto('yuheng_current',['rezhiheng','jiexun','reanxu']); + init(player, skill) { + player.markAuto("yuheng_current", ["rezhiheng", "jiexun", "reanxu"]); }, - mark:true, - intro:{ - name:'命运线:权道', - content(storage,player){ - var finished=[],unfinished=['rezhiheng','jiexun','reanxu']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技。若你因〖驭衡〗获得过〖制衡〗〖诫训〗〖安恤〗,则你手牌区内点数为字母的牌的牌名视为【调剂盐梅】。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + "
            • 锁定技。若你因〖驭衡〗获得过〖制衡〗〖诫训〗〖安恤〗,则你手牌区内点数为字母的牌的牌名视为【调剂盐梅】。"; return str; }, }, }, - jiaohui:{ - audio:2, - mod:{ - cardname(card,player){ - if(player.countCards('h')==1&&player.storage.yuheng){ - var list=['xiashu','rejieyin','oldimeng']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return; + jiaohui: { + audio: 2, + mod: { + cardname(card, player) { + if (player.countCards("h") == 1 && player.storage.yuheng) { + var list = ["xiashu", "rejieyin", "oldimeng"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return; } - return 'yuanjiao'; + return "yuanjiao"; } }, }, - init(player,skill){ - player.markAuto('yuheng_current',['xiashu','rejieyin','oldimeng']); + init(player, skill) { + player.markAuto("yuheng_current", ["xiashu", "rejieyin", "oldimeng"]); }, - mark:true, - intro:{ - name:'命运线:交辉', - content(storage,player){ - var finished=[],unfinished=['xiashu','rejieyin','oldimeng']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技。若你因〖驭衡〗获得过〖下书〗〖结姻〗〖缔盟〗,且你的手牌数为1,则此牌的牌名视为【远交近攻】。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + "
            • 锁定技。若你因〖驭衡〗获得过〖下书〗〖结姻〗〖缔盟〗,且你的手牌数为1,则此牌的牌名视为【远交近攻】。"; return str; }, }, }, - yuanlv:{ - audio:2, - init(player,skill){ - player.markAuto('yuheng_current',['xinfu_guanchao','drlt_jueyan','lanjiang']); + yuanlv: { + audio: 2, + init(player, skill) { + player.markAuto("yuheng_current", ["xinfu_guanchao", "drlt_jueyan", "lanjiang"]); }, - trigger:{player:'useCardToTargeted'}, - forced:true, - filter(event,player){ - if(get.type(event.card,false)!='equip'||player!=event.target||event.card.name.indexOf('changandajian_equip')==0) return false; - if(!player.storage.yuheng) return false; - var list=['xinfu_guanchao','drlt_jueyan','lanjiang']; - for(var i of list){ - if(!player.storage.yuheng.includes(i)) return false; + trigger: { player: "useCardToTargeted" }, + forced: true, + filter(event, player) { + if ( + get.type(event.card, false) != "equip" || + player != event.target || + event.card.name.indexOf("changandajian_equip") == 0 + ) + return false; + if (!player.storage.yuheng) return false; + var list = ["xinfu_guanchao", "drlt_jueyan", "lanjiang"]; + for (var i of list) { + if (!player.storage.yuheng.includes(i)) return false; } - var type=get.subtype(event.card); - if(lib.card['changandajian_'+type]&&player.hasEquipableSlot(type)) return true; + var type = get.subtype(event.card); + if (lib.card["changandajian_" + type] && player.hasEquipableSlot(type)) + return true; return false; }, - content(){ - var cards=trigger.cards.filterInD(); - if(cards.length>0) game.cardsDiscard(cards); - var type=get.subtype(trigger.card); - var card=game.createCard('changandajian_'+type,Math.random()<0.5?'spade':'heart',10); - player.useCard(card,player); + content() { + var cards = trigger.cards.filterInD(); + if (cards.length > 0) game.cardsDiscard(cards); + var type = get.subtype(trigger.card); + var card = game.createCard( + "changandajian_" + type, + Math.random() < 0.5 ? "spade" : "heart", + 10 + ); + player.useCard(card, player); }, - mark:true, - intro:{ - name:'命运线:渊虑', - content(storage,player){ - var finished=[],unfinished=['xinfu_guanchao','drlt_jueyan','lanjiang']; - if(player.storage.yuheng){ - for(var i=0;i未获得:'+get.translation(unfinished)+'
              '); - if(finished.length) str+=('
            • 已获得过:'+get.translation(finished)+'
              '); - str+='
            • 锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜江〗,则当你成为自己使用的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。'; + var str = ""; + if (unfinished.length) + str += "
            • 未获得:" + get.translation(unfinished) + "
              "; + if (finished.length) + str += "
            • 已获得过:" + get.translation(finished) + "
              "; + str += + "
            • 锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜江〗,则当你成为自己使用的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。"; return str; }, }, }, }, }, - yuheng:{ - audio:2, - enable:'phaseUse', - usable:1, - content(){ - var skills=player.getSkills(null,false,false).filter(function(i){ - if(i=='yuheng') return false; - var info=get.info(i); - return info&&!info.charlotte&&!get.is.locked(i); + yuheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + content() { + var skills = player.getSkills(null, false, false).filter(function (i) { + if (i == "yuheng") return false; + var info = get.info(i); + return info && !info.charlotte && !get.is.locked(i); }); - if(skills.length){ + if (skills.length) { player.removeSkills(skills); } //初始化技能库 - var list1=['dili_shengzhi','dili_chigang','dili_qionglan','dili_quandao','dili_jiaohui','dili_yuanlv']; - var list2=['gzyinghun','hongde','rebingyi','xinfu_guanwei','bizheng','xinanguo','shelie','wengua','rebotu','rezhiheng','jiexun','reanxu','xiashu','rejieyin','oldimeng','xinfu_guanchao','drlt_jueyan','lanjiang']; - var list3=[]; - if(!player.storage.yuheng_full) player.storage.yuheng_full=list2.slice(0); - if(player.getStorage('yuheng_current').length==0){ - for(var i=0;i0&&!player.hasHistory('useSkill',function(evt){ - if(evt.skill=='yuheng'||evt.type!='player'||!evt.sourceSkill) return false; - var info1=get.info(evt.skill); - if(info1.charlotte) return false; - var info=get.info(evt.sourceSkill); - if(info.charlotte||get.is.locked(evt.skill)) return false; - return evt.event.getParent('phaseUse')==evtx; - })){ + var evtx = event.getParent("phaseUse"); + if ( + currentskills.length > 0 && + !player.hasHistory("useSkill", function (evt) { + if (evt.skill == "yuheng" || evt.type != "player" || !evt.sourceSkill) + return false; + var info1 = get.info(evt.skill); + if (info1.charlotte) return false; + var info = get.info(evt.sourceSkill); + if (info.charlotte || get.is.locked(evt.skill)) return false; + return evt.event.getParent("phaseUse") == evtx; + }) + ) { fullskills.randomSort(); currentskills.randomSort(); - for(var i=0;i0) break; + if (skills.length > 0) break; } } //在已经发动过其他非锁定技时抽选技能 - else{ + else { skills.add(fullskills.randomRemove(1)[0]); } - for(var i of skills){ + for (var i of skills) { player.addSkills(i); } - player.markAuto('yuheng',skills); + player.markAuto("yuheng", skills); }, - ai:{ - order(item,player){ - var evtx=_status.event.getParent('phaseUse'); - if(!player.hasHistory('useSkill',function(evt){ - if(evt.skill=='yuheng'||evt.type!='player'||!evt.sourceSkill) return false; - var info1=get.info(evt.skill); - if(info1.charlotte) return false; - var info=get.info(evt.sourceSkill); - if(info.charlotte||get.is.locked(evt.skill)) return false; - return evt.event.getParent('phaseUse')==evtx; - })) return 11; + ai: { + order(item, player) { + var evtx = _status.event.getParent("phaseUse"); + if ( + !player.hasHistory("useSkill", function (evt) { + if (evt.skill == "yuheng" || evt.type != "player" || !evt.sourceSkill) + return false; + var info1 = get.info(evt.skill); + if (info1.charlotte) return false; + var info = get.info(evt.sourceSkill); + if (info.charlotte || get.is.locked(evt.skill)) return false; + return evt.event.getParent("phaseUse") == evtx; + }) + ) + return 11; return 0.8; }, - result:{player:1}, + result: { player: 1 }, }, - group:'yuheng_losehp', - subSkill:{ - losehp:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - locked:false, - filter(event,player){ - return !player.hasHistory('useSkill',function(evt){ - if(evt.skill!='yuheng') return false; - return evt.event.getParent('phaseUse')==event; + group: "yuheng_losehp", + subSkill: { + losehp: { + trigger: { player: "phaseUseEnd" }, + forced: true, + locked: false, + filter(event, player) { + return !player.hasHistory("useSkill", function (evt) { + if (evt.skill != "yuheng") return false; + return evt.event.getParent("phaseUse") == event; }); }, - content(){ + content() { player.loseHp(); }, }, }, }, - jiufa:{ - audio:2, - trigger:{player:['useCardAfter','respondAfter']}, - frequent:true, - filter(event,player){ - return event.jiufa_counted&&player.getStorage('jiufa').length>=9; + jiufa: { + audio: 2, + trigger: { player: ["useCardAfter", "respondAfter"] }, + frequent: true, + filter(event, player) { + return event.jiufa_counted && player.getStorage("jiufa").length >= 9; }, - content(){ - 'step 0' - player.unmarkSkill('jiufa'); - event.cards=get.cards(9); - event.cards.sort(function(a,b){ - return get.number(b)-get.number(a); - }) + content() { + "step 0"; + player.unmarkSkill("jiufa"); + event.cards = get.cards(9); + event.cards.sort(function (a, b) { + return get.number(b) - get.number(a); + }); game.cardsGotoOrdering(event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str; - if(player==game.me&&!_status.auto){ - str='九伐:选择任意张点数满足条件的牌'; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str; + if (player == game.me && !_status.auto) { + str = "九伐:选择任意张点数满足条件的牌"; + } else { + str = "九伐"; + } + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + event.time = get.utc(); + game.addVideo("showCards", player, ["九伐", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + "step 1"; + var next = player.chooseButton([0, 9], true); + next.set("dialog", event.videoId); + next.set("filterButton", function (button) { + var num = get.number(button.link), + cards = _status.event.getParent().cards; + for (var i of ui.selected.buttons) { + if (get.number(i.link) == num) return false; } - else{ - str='九伐'; - } - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - event.time=get.utc(); - game.addVideo('showCards',player,['九伐',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - "step 1" - var next=player.chooseButton([0,9],true); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - var num=get.number(button.link),cards=_status.event.getParent().cards; - for(var i of ui.selected.buttons){ - if(get.number(i.link)==num) return false; - } - for(var i of cards){ - if(i!=button.link&&get.number(i)==num) return true; + for (var i of cards) { + if (i != button.link && get.number(i) == num) return true; } return false; }); - next.set('ai',function(button){ - return get.value(button.link,_status.event.player) + next.set("ai", function (button) { + return get.value(button.link, _status.event.player); }); - "step 2" - if(result.bool&&result.links&&result.links.length){ - event.cards2=result.links; + "step 2"; + if (result.bool && result.links && result.links.length) { + event.cards2 = result.links; } - var time=1000-(get.utc()-event.time); - if(time>0){ - game.delay(0,time); + var time = 1000 - (get.utc() - event.time); + if (time > 0) { + game.delay(0, time); } - "step 3" - game.broadcastAll('closeDialog',event.videoId); - var cards2=event.cards2; - if(cards2&&cards2.length) player.gain(cards2,'log','gain2'); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var cards2 = event.cards2; + if (cards2 && cards2.length) player.gain(cards2, "log", "gain2"); }, - marktext:'⑨', - intro:{ - content:'已记录牌名:$', - onunmark:true, + marktext: "⑨", + intro: { + content: "已记录牌名:$", + onunmark: true, }, - group:'jiufa_count', - subSkill:{ - count:{ - trigger:{player:['useCard1','respond']}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter(event,player){ - return !player.getStorage('jiufa').includes(event.card.name); + group: "jiufa_count", + subSkill: { + count: { + trigger: { player: ["useCard1", "respond"] }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter(event, player) { + return !player.getStorage("jiufa").includes(event.card.name); }, - content(){ - trigger.jiufa_counted=true; - player.markAuto('jiufa',[trigger.card.name]); + content() { + trigger.jiufa_counted = true; + player.markAuto("jiufa", [trigger.card.name]); }, }, }, }, - tianren:{ - audio:2, - trigger:{global:['loseAfter','cardsDiscardAfter','loseAsyncAfter']}, - forced:true, - filter(event,player){ - if(event.name.indexOf('lose')==0){ - if(event.getlx===false||event.position!=ui.discardPile) return false; + tianren: { + audio: 2, + trigger: { global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter"] }, + forced: true, + filter(event, player) { + if (event.name.indexOf("lose") == 0) { + if (event.getlx === false || event.position != ui.discardPile) return false; + } else { + var evt = event.getParent(); + if (evt.relatedEvent && evt.relatedEvent.name == "useCard") return false; } - else{ - var evt=event.getParent(); - if(evt.relatedEvent&&evt.relatedEvent.name=='useCard') return false; - } - for(var i of event.cards){ - var owner=false; - if(event.hs&&event.hs.includes(i)) owner=event.player; - var type=get.type(i,null,owner); - if(type=='basic'||type=='trick') return true; + for (var i of event.cards) { + var owner = false; + if (event.hs && event.hs.includes(i)) owner = event.player; + var type = get.type(i, null, owner); + if (type == "basic" || type == "trick") return true; } return false; }, - content(){ - var num=0; - for(var i of trigger.cards){ - var owner=false; - if(trigger.hs&&trigger.hs.includes(i)) owner=trigger.player; - var type=get.type(i,null,owner); - if(type=='basic'||type=='trick') num++; + content() { + var num = 0; + for (var i of trigger.cards) { + var owner = false; + if (trigger.hs && trigger.hs.includes(i)) owner = trigger.player; + var type = get.type(i, null, owner); + if (type == "basic" || type == "trick") num++; } - player.addMark('tianren',num); + player.addMark("tianren", num); }, - group:'tianren_maxHp', - intro:{content:'mark'}, - subSkill:{ - maxHp:{ - trigger:{player:['tianrenAfter','gainMaxHpAfter','loseMaxHpAfter']}, - forced:true, - filter(event,player){ - return player.countMark('tianren')>=player.maxHp; + group: "tianren_maxHp", + intro: { content: "mark" }, + subSkill: { + maxHp: { + trigger: { player: ["tianrenAfter", "gainMaxHpAfter", "loseMaxHpAfter"] }, + forced: true, + filter(event, player) { + return player.countMark("tianren") >= player.maxHp; }, - content(){ - player.removeMark('tianren',player.maxHp); + content() { + player.removeMark("tianren", player.maxHp); player.gainMaxHp(); player.draw(2); }, }, }, }, - pingxiang:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'ice', - filter(event,player){ - return player.maxHp>9; + pingxiang: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "ice", + filter(event, player) { + return player.maxHp > 9; }, - content(){ - 'step 0' - player.awakenSkill('pingxiang'); + content() { + "step 0"; + player.awakenSkill("pingxiang"); player.loseMaxHp(9); - event.num=0; - 'step 1' + event.num = 0; + "step 1"; event.num++; - player.chooseUseTarget({ - name:'sha', - nature:'fire', - isCard:true, - },'请选择火【杀】的目标('+(event.num==9?'⑨':event.num)+'/9)',false); - 'step 2' - if(result.bool&&event.num<9) event.goto(1); - else player.removeSkills('jiufa'); - 'step 3' - player.addSkill('pingxiang_effect'); + player.chooseUseTarget( + { + name: "sha", + nature: "fire", + isCard: true, + }, + "请选择火【杀】的目标(" + (event.num == 9 ? "⑨" : event.num) + "/9)", + false + ); + "step 2"; + if (result.bool && event.num < 9) event.goto(1); + else player.removeSkills("jiufa"); + "step 3"; + player.addSkill("pingxiang_effect"); }, - ai:{ - order(){ + ai: { + order() { return get.order({ - name:'sha', - nature:'fire', - isCard:true, + name: "sha", + nature: "fire", + isCard: true, }); }, - result:{ - player(player){ - if(player.hasValueTarget({ - name:'sha', - nature:'fire', - isCard:true, - })) return 1; + result: { + player(player) { + if ( + player.hasValueTarget({ + name: "sha", + nature: "fire", + isCard: true, + }) + ) + return 1; return 0; }, }, }, - subSkill:{ - effect:{ - marktext:'襄', - intro:{content:'手牌上限基数改为体力上限'}, - mod:{ - maxHandcardBase(player){ + subSkill: { + effect: { + marktext: "襄", + intro: { content: "手牌上限基数改为体力上限" }, + mod: { + maxHandcardBase(player) { return player.maxHp; }, }, }, }, }, - hina_shenshi:{ - groupSkill:true, - trigger:{player:['phaseUseBegin','phaseUseEnd']}, - frequent:true, - filter(event,player){ - return player.group=='shen'; + hina_shenshi: { + groupSkill: true, + trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, + frequent: true, + filter(event, player) { + return player.group == "shen"; }, - content(){ - 'step 0' - player.draw(2).gaintag=['hina_shenshi']; - player.addSkill('hina_shenshi_yingbian'); - 'step 1' - var cards=player.getCards('h',function(card){ - return card.hasGaintag('hina_shenshi'); + content() { + "step 0"; + player.draw(2).gaintag = ["hina_shenshi"]; + player.addSkill("hina_shenshi_yingbian"); + "step 1"; + var cards = player.getCards("h", function (card) { + return card.hasGaintag("hina_shenshi"); }); - if(!cards.length) event.finish(); - else if(cards.length==1) event._result={bool:true,cards:cards}; - else player.chooseCard('h',true,'将一张“神视”牌置于牌堆顶',function(card){ - return card.hasGaintag('hina_shenshi'); - }); - 'step 2' - if(result.bool){ - game.log(player,'将一张牌置于了牌堆顶'); - player.lose(result.cards,ui.cardPile,'insert'); - player.$throw(1,1000); - } - else event.finish(); - 'step 3' + if (!cards.length) event.finish(); + else if (cards.length == 1) event._result = { bool: true, cards: cards }; + else + player.chooseCard("h", true, "将一张“神视”牌置于牌堆顶", function (card) { + return card.hasGaintag("hina_shenshi"); + }); + "step 2"; + if (result.bool) { + game.log(player, "将一张牌置于了牌堆顶"); + player.lose(result.cards, ui.cardPile, "insert"); + player.$throw(1, 1000); + } else event.finish(); + "step 3"; game.delayx(); }, - onremove(player){ - player.removeGaintag('hina_shenshi'); + onremove(player) { + player.removeGaintag("hina_shenshi"); }, - group:'hina_shenshi_yingbian', + group: "hina_shenshi_yingbian", }, - hina_shenshi_yingbian:{ - trigger:{player:'yingbian'}, - forced:true, - filter:(event,player)=>event.card.isCard&&player.hasHistory('lose',evt=>evt.getParent()==event&&Object.values(evt.gaintag_map).some(value=>value.includes('hina_shenshi'))), - content:()=>{ - if(!Array.isArray(trigger.temporaryYingbian)) trigger.temporaryYingbian=[]; - trigger.temporaryYingbian.add('force'); + hina_shenshi_yingbian: { + trigger: { player: "yingbian" }, + forced: true, + filter: (event, player) => + event.card.isCard && + player.hasHistory( + "lose", + (evt) => + evt.getParent() == event && + Object.values(evt.gaintag_map).some((value) => value.includes("hina_shenshi")) + ), + content: () => { + if (!Array.isArray(trigger.temporaryYingbian)) trigger.temporaryYingbian = []; + trigger.temporaryYingbian.add("force"); trigger.temporaryYingbian.addArray(get.yingbianEffects()); - } + }, }, - hina_xingzhi:{ - groupSkill:true, - trigger:{player:'yingbian'}, - usable:1, - filter:(event,player)=>player.group=='key'&&!event.card.yingbian&&lib.yingbian.condition.complex.has('zhuzhan'), - content:()=>{ - 'step 0' - trigger.yingbianZhuzhanAI=(player,card,source,targets)=>cardx=>{ - if(get.attitude(player,source)<=0) return 0; - var info=get.info(card),num=0; - if(info&&info.ai&&info.ai.yingbian){ - var ai=info.ai.yingbian(card,source,targets,player); - if(ai) num=ai; + hina_xingzhi: { + groupSkill: true, + trigger: { player: "yingbian" }, + usable: 1, + filter: (event, player) => + player.group == "key" && + !event.card.yingbian && + lib.yingbian.condition.complex.has("zhuzhan"), + content: () => { + "step 0"; + trigger.yingbianZhuzhanAI = (player, card, source, targets) => (cardx) => { + if (get.attitude(player, source) <= 0) return 0; + var info = get.info(card), + num = 0; + if (info && info.ai && info.ai.yingbian) { + var ai = info.ai.yingbian(card, source, targets, player); + if (ai) num = ai; } - return Math.max(num,6)-get.value(cardx); + return Math.max(num, 6) - get.value(cardx); }; - trigger.afterYingbianZhuzhan=event=>event.zhuzhanresult.draw(2); - lib.yingbian.condition.complex.get('zhuzhan')(trigger); - 'step 1' - if(!result.bool) return; - trigger.card.yingbian=true; - lib.yingbian.effect.forEach(value=>game.yingbianEffect(trigger,value)); - player.addTempSkill('yingbian_changeTarget'); - } + trigger.afterYingbianZhuzhan = (event) => event.zhuzhanresult.draw(2); + lib.yingbian.condition.complex.get("zhuzhan")(trigger); + "step 1"; + if (!result.bool) return; + trigger.card.yingbian = true; + lib.yingbian.effect.forEach((value) => game.yingbianEffect(trigger, value)); + player.addTempSkill("yingbian_changeTarget"); + }, }, - yingba:{ - audio:2, - mod:{ - aiOrder(player,card,num){ - if(num>0&&_status.event&&_status.event.type=='phase'&&get.tag(card,'recover')){ - if(player.needsToDiscard()) return num/3; + yingba: { + audio: 2, + mod: { + aiOrder(player, card, num) { + if ( + num > 0 && + _status.event && + _status.event.type == "phase" && + get.tag(card, "recover") + ) { + if (player.needsToDiscard()) return num / 3; return 0; } }, - targetInRange(card,player,target){ - if(target.hasMark('yingba_mark')) return true; - } + targetInRange(card, player, target) { + if (target.hasMark("yingba_mark")) return true; + }, }, - enable:'phaseUse', - usable:1, - filter:(event,player)=>(game.hasPlayer((current)=>(current!=player&¤t.maxHp>1))), - filterTarget:(card,player,target)=>(target!=player&&target.maxHp>1), - content(){ - 'step 0' + enable: "phaseUse", + usable: 1, + filter: (event, player) => + game.hasPlayer((current) => current != player && current.maxHp > 1), + filterTarget: (card, player, target) => target != player && target.maxHp > 1, + content() { + "step 0"; target.loseMaxHp(); - 'step 1' - if(target.isIn()) target.addMark('yingba_mark',1); + "step 1"; + if (target.isIn()) target.addMark("yingba_mark", 1); player.loseMaxHp(); }, - locked:false, + locked: false, //global:'yingba_mark', - ai:{ - combo:'scfuhai', - threaten:3, - order:11, - result:{ - player(player,target){ - if(player.maxHp==1) return -2.5; + ai: { + combo: "scfuhai", + threaten: 3, + order: 11, + result: { + player(player, target) { + if (player.maxHp == 1) return -2.5; return -0.25; }, - target(player,target){ - if(target.isHealthy()) return -2; - if(!target.hasMark('yingba_mark')) return -1; + target(player, target) { + if (target.isHealthy()) return -2; + if (!target.hasMark("yingba_mark")) return -1; return -0.2; }, }, }, - subSkill:{ - mark:{ - marktext:'定', - intro:{ - name:'平定', - content:'mark', - onunmark:true, + subSkill: { + mark: { + marktext: "定", + intro: { + name: "平定", + content: "mark", + onunmark: true, }, - mod:{ - maxHandcard(player,numx){ - var num=player.countMark('yingba_mark'); - if(num) return numx+num*game.countPlayer(function(current){ - return current.hasSkill('yingba'); - }); + mod: { + maxHandcard(player, numx) { + var num = player.countMark("yingba_mark"); + if (num) + return ( + numx + + num * + game.countPlayer(function (current) { + return current.hasSkill("yingba"); + }) + ); }, }, }, }, }, - scfuhai:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - forced:true, - filter(event,player){ - return event.target&&event.target.hasMark('yingba_mark'); + scfuhai: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + forced: true, + filter(event, player) { + return event.target && event.target.hasMark("yingba_mark"); }, - logTarget:'target', - content(){ + logTarget: "target", + content() { trigger.directHit.add(trigger.target); - if(player.getHistory('gain',function(evt){ - return evt.getParent(2).name=='scfuhai'; - }).length<2) player.draw(); + if ( + player.getHistory("gain", function (evt) { + return evt.getParent(2).name == "scfuhai"; + }).length < 2 + ) + player.draw(); }, - group:['scfuhai_die'], - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return arg&&arg.target&&arg.target.hasMark('yingba_mark') + group: ["scfuhai_die"], + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return arg && arg.target && arg.target.hasMark("yingba_mark"); }, + combo: "yingba", }, - subSkill:{ - usea:{ - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - return lib.skill.scfuhai_usea.logTarget(event,player).length>0; + subSkill: { + usea: { + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + return lib.skill.scfuhai_usea.logTarget(event, player).length > 0; }, - logTarget(event,player){ - return event.targets.filter(function(i){ - return i.hasMark('yingba_mark'); + logTarget(event, player) { + return event.targets.filter(function (i) { + return i.hasMark("yingba_mark"); }); }, - content(){ - var num=0; - for(var i of trigger.targets){ - var numx=i.countMark('yingba_mark'); - if(numx){ - num+=numx; - i.removeMark('yingba_mark',numx); + content() { + var num = 0; + for (var i of trigger.targets) { + var numx = i.countMark("yingba_mark"); + if (numx) { + num += numx; + i.removeMark("yingba_mark", numx); } } - if(num) player.gainMaxHp(num); + if (num) player.gainMaxHp(num); }, }, - die:{ - trigger:{global:'die'}, - forced:true, - filter(event,player){ - return event.player.countMark('yingba_mark')>0; + die: { + trigger: { global: "die" }, + forced: true, + filter(event, player) { + return event.player.countMark("yingba_mark") > 0; }, - content(){ - player.gainMaxHp(trigger.player.countMark('yingba_mark')); - player.draw(trigger.player.countMark('yingba_mark')); + content() { + player.gainMaxHp(trigger.player.countMark("yingba_mark")); + player.draw(trigger.player.countMark("yingba_mark")); }, }, }, }, - pinghe:{ - audio:2, - mod:{ - maxHandcardBase(player){ + pinghe: { + audio: 2, + mod: { + maxHandcardBase(player) { return player.getDamagedHp(); }, }, - ai:{ - effect:{ - target(card,player,target){ - if(get.tag(card,'recover')&&_status.event.type=='phase'&&!player.needsToDiscard()) return 0.2; - } - } - }, - trigger:{player:'damageBegin2'}, - forced:true, - filter(event,player){ - return event.source&&event.source!=player&&player.maxHp>1&&player.countCards('h')>0; - }, - content(){ - 'step 0' - player.chooseCardTarget({ - prompt:'请选择【冯河】的牌和目标', - prompt2:'将一张手牌交给一名其他角色并防止伤害'+(player.hasSkill('yingba')?',然后令伤害来源获得一个“平定”标记':''), - filterCard:true, - forced:true, - filterTarget:lib.filter.notMe, - ai1(card){ - if(get.tag(card,'recover')&&!game.hasPlayer(function(current){ - return get.attitude(current,player)>0&&!current.hasSkillTag('nogain'); - })) return 0; - return 1/Math.max(0.1,get.value(card)); + ai: { + effect: { + target(card, player, target) { + if ( + get.tag(card, "recover") && + _status.event.type == "phase" && + !player.needsToDiscard() + ) + return 0.2; }, - ai2(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) att/=9; - return 4+att; + }, + }, + trigger: { player: "damageBegin2" }, + forced: true, + filter(event, player) { + return ( + event.source && + event.source != player && + player.maxHp > 1 && + player.countCards("h") > 0 + ); + }, + content() { + "step 0"; + player.chooseCardTarget({ + prompt: "请选择【冯河】的牌和目标", + prompt2: + "将一张手牌交给一名其他角色并防止伤害" + + (player.hasSkill("yingba") ? ",然后令伤害来源获得一个“平定”标记" : ""), + filterCard: true, + forced: true, + filterTarget: lib.filter.notMe, + ai1(card) { + if ( + get.tag(card, "recover") && + !game.hasPlayer(function (current) { + return ( + get.attitude(current, player) > 0 && !current.hasSkillTag("nogain") + ); + }) + ) + return 0; + return 1 / Math.max(0.1, get.value(card)); + }, + ai2(target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) att /= 9; + return 4 + att; }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; //player.logSkill('pinghe',target); - player.line(target,'green'); - player.give(result.cards,target); + player.line(target, "green"); + player.give(result.cards, target); trigger.cancel(); player.loseMaxHp(); - if(player.hasSkill('yingba')){ - trigger.source.addMark('yingba_mark',1); + if (player.hasSkill("yingba")) { + trigger.source.addMark("yingba_mark", 1); } } }, }, - tianzuo:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + tianzuo: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&!lib.inpile.includes('qizhengxiangsheng'); + forced: true, + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + !lib.inpile.includes("qizhengxiangsheng") + ); }, - content(){ - game.addGlobalSkill('tianzuo_global'); - var cards=[]; - for(var i=2;i<10;i++){ - cards.push(game.createCard2('qizhengxiangsheng',i%2?'club':'spade',i)); + content() { + game.addGlobalSkill("tianzuo_global"); + var cards = []; + for (var i = 2; i < 10; i++) { + cards.push(game.createCard2("qizhengxiangsheng", i % 2 ? "club" : "spade", i)); } - game.broadcastAll(function(){lib.inpile.add('qizhengxiangsheng')}); - game.cardsGotoPile(cards,()=>{ - return ui.cardPile.childNodes[get.rand(0,ui.cardPile.childNodes.length-1)]; - }) + game.broadcastAll(function () { + lib.inpile.add("qizhengxiangsheng"); + }); + game.cardsGotoPile(cards, () => { + return ui.cardPile.childNodes[get.rand(0, ui.cardPile.childNodes.length - 1)]; + }); }, - group:'tianzuo_remove', - subSkill:{ - remove:{ - audio:2, - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - filter(event,player){ - return event.card&&event.card.name=='qizhengxiangsheng'; + group: "tianzuo_remove", + subSkill: { + remove: { + audio: 2, + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + filter(event, player) { + return event.card && event.card.name == "qizhengxiangsheng"; }, - content(){ + content() { trigger.cancel(); }, - ai:{ - effect:{ - target(card,player,target){ - if(card&&card.name=='qizhengxiangsheng') return 'zeroplayertarget'; + ai: { + effect: { + target(card, player, target) { + if (card && card.name == "qizhengxiangsheng") return "zeroplayertarget"; }, - } + }, }, }, - global:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - popup:false, - filter(event,player){ - return event.card.name=='qizhengxiangsheng'; + global: { + trigger: { player: "useCardToPlayered" }, + forced: true, + popup: false, + filter(event, player) { + return event.card.name == "qizhengxiangsheng"; }, - content(){ - 'step 0' - var target=trigger.target; - event.target=target; - player.chooseControl('奇兵','正兵').set('prompt','请选择'+get.translation(target)+'的标记').set('choice',function(){ - var e1=1.5*get.sgn(get.damageEffect(target,player,target)); - var e2=0; - if(target.countGainableCards(player,'h')>0&&!target.hasSkillTag('noh')) e2=-1; - var es=target.getGainableCards(player,'e'); - if(es.length) e2=Math.min(e2,function(){ - var max=0; - for(var i of es) max=Math.max(max,get.value(i,target)) - return -max/4; - }()); - if(Math.abs(e1-e2)<=0.3) return Math.random()<0.5?'奇兵':'正兵'; - if(e1 0 && + !target.hasSkillTag("noh") + ) + e2 = -1; + var es = target.getGainableCards(player, "e"); + if (es.length) + e2 = Math.min( + e2, + (function () { + var max = 0; + for (var i of es) + max = Math.max(max, get.value(i, target)); + return -max / 4; + })() + ); + if (Math.abs(e1 - e2) <= 0.3) + return Math.random() < 0.5 ? "奇兵" : "正兵"; + if (e1 < e2) return "奇兵"; + return "正兵"; + })() + ) + .set("ai", function () { + return _status.event.choice; + }); + "step 1"; + var map = trigger.getParent().customArgs, + id = target.playerid; + if (!map[id]) map[id] = {}; + map[id].qizheng_name = result.control; }, }, - rewrite:{ - audio:'tianzuo', - trigger:{global:'useCardToTargeted'}, - filter(event,player){ - return event.card.name=='qizhengxiangsheng'; + rewrite: { + audio: "tianzuo", + trigger: { global: "useCardToTargeted" }, + filter(event, player) { + return event.card.name == "qizhengxiangsheng"; + }, + logTarget: "target", + prompt2: "观看其手牌并修改“奇正相生”标记", + content() { + "step 0"; + var target = trigger.target; + event.target = target; + if (player != target && target.countCards("h") > 0) player.viewHandcards(target); + player + .chooseControl("奇兵", "正兵") + .set("prompt", "请选择" + get.translation(target) + "的标记") + .set( + "choice", + (function () { + var shas = target.getCards("h", "sha"), + shans = target.getCards("h", "shan"); + var e1 = 1.5 * get.sgn(get.damageEffect(target, player, target)); + var e2 = 0; + if ( + target.countGainableCards(player, "h") > 0 && + !target.hasSkillTag("noh") + ) + e2 = -1; + var es = target.getGainableCards(player, "e"); + if (es.length) + e2 = Math.min( + e2, + (function () { + var max = 0; + for (var i of es) + max = Math.max(max, get.value(i, target)); + return -max / 4; + })() + ); + if (get.attitude(player, target) > 0) { + if (shas.length >= Math.max(1, shans.length)) return "奇兵"; + if (shans.length > shas.length) return "正兵"; + return e1 > e2 ? "奇兵" : "正兵"; + } + if (shas.length) e1 = -0.5; + if (shans.length) e2 = -0.7; + if (Math.abs(e1 - e2) <= 0.3) + return Math.random() < 0.5 ? "奇兵" : "正兵"; + var rand = Math.random(); + if (e1 < e2) return rand < 0.1 ? "奇兵" : "正兵"; + return rand < 0.1 ? "正兵" : "奇兵"; + })() + ) + .set("ai", () => _status.event.choice); + "step 1"; + var map = trigger.getParent().customArgs, + id = target.playerid; + if (!map[id]) map[id] = {}; + map[id].qizheng_name = result.control; + map[id].qizheng_aibuff = get.attitude(player, target) > 0; }, - logTarget:'target', - prompt2:'观看其手牌并修改“奇正相生”标记', - content(){ - 'step 0' - var target=trigger.target; - event.target=target; - if(player!=target&&target.countCards('h')>0) player.viewHandcards(target); - player.chooseControl('奇兵','正兵').set('prompt','请选择'+get.translation(target)+'的标记').set('choice',function(){ - var shas=target.getCards('h','sha'),shans=target.getCards('h','shan'); - var e1=1.5*get.sgn(get.damageEffect(target,player,target)); - var e2=0; - if(target.countGainableCards(player,'h')>0&&!target.hasSkillTag('noh')) e2=-1; - var es=target.getGainableCards(player,'e'); - if(es.length) e2=Math.min(e2,function(){ - var max=0; - for(var i of es) max=Math.max(max,get.value(i,target)) - return -max/4; - }()); - if(get.attitude(player,target)>0){ - if(shas.length>=Math.max(1,shans.length)) return '奇兵'; - if(shans.length>shas.length) return '正兵'; - return e1>e2?'奇兵':'正兵'; - } - if(shas.length) e1=-0.5; - if(shans.length) e2=-0.7; - if(Math.abs(e1-e2)<=0.3) return Math.random()<0.5?'奇兵':'正兵'; - var rand=Math.random(); - if(e1(_status.event.choice)); - 'step 1' - var map=trigger.getParent().customArgs,id=target.playerid; - if(!map[id]) map[id]={}; - map[id].qizheng_name=result.control; - map[id].qizheng_aibuff=get.attitude(player,target)>0; - } }, }, }, - lingce:{ - audio:2, - init:(player)=>{ - game.addGlobalSkill('lingce_global'); + lingce: { + audio: 2, + init: (player) => { + game.addGlobalSkill("lingce_global"); }, - trigger:{global:'useCard'}, - forced:true, - filter(event,player){ - if(!event.card.isCard||!event.cards||event.cards.length!==1) return false; - return event.card.name=='qizhengxiangsheng'||get.zhinangs().includes(event.card.name)||player.getStorage('dinghan').includes(event.card.name); + trigger: { global: "useCard" }, + forced: true, + filter(event, player) { + if (!event.card.isCard || !event.cards || event.cards.length !== 1) return false; + return ( + event.card.name == "qizhengxiangsheng" || + get.zhinangs().includes(event.card.name) || + player.getStorage("dinghan").includes(event.card.name) + ); }, - content(){ + content() { player.draw(); }, - subSkill:{ - global:{ - ai:{ - effect:{ - player:(card,player,target)=>{ - let num=0,nohave=true; - game.countPlayer(i=>{ - if(i.hasSkill('lingce')){ - nohave=false; - if(i.isIn()&&lib.skill.lingce.filter({card:card},i)) num+=get.sgnAttitude(player,i); + subSkill: { + global: { + ai: { + effect: { + player: (card, player, target) => { + let num = 0, + nohave = true; + game.countPlayer((i) => { + if (i.hasSkill("lingce")) { + nohave = false; + if (i.isIn() && lib.skill.lingce.filter({ card: card }, i)) + num += get.sgnAttitude(player, i); } - },true); - if(nohave) game.removeGlobalSkill('lingce_global'); - else return [1,0.8*num]; - } - } - } - } - } + }, true); + if (nohave) game.removeGlobalSkill("lingce_global"); + else return [1, 0.8 * num]; + }, + }, + }, + }, + }, }, - dinghan:{ - audio:2, - trigger:{ - target:'useCardToTarget', - player:'addJudgeBefore', + dinghan: { + audio: 2, + trigger: { + target: "useCardToTarget", + player: "addJudgeBefore", }, - forced:true, - locked:false, - filter(event,player){ - if(event.name=='useCardToTarget'&&get.type(event.card,null,false)!='trick') return false; - return !player.getStorage('dinghan').includes(event.card.name); + forced: true, + locked: false, + filter(event, player) { + if (event.name == "useCardToTarget" && get.type(event.card, null, false) != "trick") + return false; + return !player.getStorage("dinghan").includes(event.card.name); }, - content(){ - player.markAuto('dinghan',[trigger.card.name]);if(trigger.name=='addJudge'){ + content() { + player.markAuto("dinghan", [trigger.card.name]); + if (trigger.name == "addJudge") { trigger.cancel(); - var owner=get.owner(trigger.card); - if(owner&&owner.getCards('hej').includes(trigger.card)) owner.lose(trigger.card,ui.discardPile); + var owner = get.owner(trigger.card); + if (owner && owner.getCards("hej").includes(trigger.card)) + owner.lose(trigger.card, ui.discardPile); else game.cardsDiscard(trigger.card); - game.log(trigger.card,'进入了弃牌堆'); - } - else{ + game.log(trigger.card, "进入了弃牌堆"); + } else { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, - onremove:true, - intro:{content:'已记录牌名:$'}, - group:'dinghan_add', - subSkill:{ - add:{ - trigger:{player:'phaseBegin'}, - direct:true, - content(){ - 'step 0' - var dialog=[get.prompt('dinghan')];list1=player.getStorage('dinghan'),list2=lib.inpile.filter(function(i){ - return get.type2(i,false)=='trick'&&!list1.includes(i); - }); - if(list1.length){ + onremove: true, + intro: { content: "已记录牌名:$" }, + group: "dinghan_add", + subSkill: { + add: { + trigger: { player: "phaseBegin" }, + direct: true, + content() { + "step 0"; + var dialog = [get.prompt("dinghan")]; + (list1 = player.getStorage("dinghan")), + (list2 = lib.inpile.filter(function (i) { + return get.type2(i, false) == "trick" && !list1.includes(i); + })); + if (list1.length) { dialog.push('
              已记录
              '); - dialog.push([list1,'vcard']); + dialog.push([list1, "vcard"]); } - if(list2.length){ + if (list2.length) { dialog.push('
              未记录
              '); - dialog.push([list2,'vcard']); + dialog.push([list2, "vcard"]); } - player.chooseButton(dialog).set('ai',function(button){ - var player=_status.event.player,name=button.link[2]; - if(player.getStorage('dinghan').includes(name)){ - return -get.effect(player,{name:name},player,player); - } - else{ - return get.effect(player,{name:name},player,player)*(1+player.countCards('hs',name)); + player.chooseButton(dialog).set("ai", function (button) { + var player = _status.event.player, + name = button.link[2]; + if (player.getStorage("dinghan").includes(name)) { + return -get.effect(player, { name: name }, player, player); + } else { + return ( + get.effect(player, { name: name }, player, player) * + (1 + player.countCards("hs", name)) + ); } }); - 'step 1' - if(result.bool){ - player.logSkill('dinghan'); - var name=result.links[0][2]; - if(player.getStorage('dinghan').includes(name)){ - player.unmarkAuto('dinghan',[name]); - game.log(player,'从定汉记录中移除了','#y'+get.translation(name)); - } - else{ - player.markAuto('dinghan',[name]); - game.log(player,'向定汉记录中添加了','#y'+get.translation(name)); + "step 1"; + if (result.bool) { + player.logSkill("dinghan"); + var name = result.links[0][2]; + if (player.getStorage("dinghan").includes(name)) { + player.unmarkAuto("dinghan", [name]); + game.log(player, "从定汉记录中移除了", "#y" + get.translation(name)); + } else { + player.markAuto("dinghan", [name]); + game.log(player, "向定汉记录中添加了", "#y" + get.translation(name)); } game.delayx(); } @@ -3961,356 +5236,436 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - dulie:{ - audio:2, - trigger:{target:'useCardToTarget'}, - forced:true, - logTarget:'player', - filter(event,player){ - return event.card.name=='sha'&&event.player.hp>player.hp; + dulie: { + audio: 2, + trigger: { target: "useCardToTarget" }, + forced: true, + logTarget: "player", + filter(event, player) { + return event.card.name == "sha" && event.player.hp > player.hp; }, - content(){ - 'step 0' - player.judge(function(result){ - if(get.suit(result)=='heart') return 2; + content() { + "step 0"; + player.judge(function (result) { + if (get.suit(result) == "heart") return 2; return -1; - }).judge2=function(result){ + }).judge2 = function (result) { return result.bool; }; - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, - ai:{ - effect:{ - target(card,player,target,current,isLink){ - if(card.name=='sha'&&!isLink&&player.hp>target.hp) return 0.5; + ai: { + effect: { + target(card, player, target, current, isLink) { + if (card.name == "sha" && !isLink && player.hp > target.hp) return 0.5; }, }, }, - marktext:'围', - intro:{ - name:'破围(围)', - name2:'围', - content:'mark', + marktext: "围", + intro: { + name: "破围(围)", + name2: "围", + content: "mark", }, }, - tspowei:{ - audio:3, - dutySkill:true, - derivation:'shenzhu', - group:['tspowei_init','tspowei_move','tspowei_achieve','tspowei_fail','tspowei_use','tspowei_remove'], - subSkill:{ - remove:{ - audio:'tspowei3', - trigger:{global:'damageEnd'}, - filter(event,player){ - return event.player&&event.player.isIn()&&event.player.hasMark('dulie'); + tspowei: { + audio: 3, + dutySkill: true, + derivation: "shenzhu", + group: [ + "tspowei_init", + "tspowei_move", + "tspowei_achieve", + "tspowei_fail", + "tspowei_use", + "tspowei_remove", + ], + subSkill: { + remove: { + audio: "tspowei3", + trigger: { global: "damageEnd" }, + filter(event, player) { + return event.player && event.player.isIn() && event.player.hasMark("dulie"); }, - forced:true, - logTarget:'player', - content(){ - trigger.player.removeMark('dulie',trigger.player.countMark('dulie')); + forced: true, + logTarget: "player", + content() { + trigger.player.removeMark("dulie", trigger.player.countMark("dulie")); }, }, - use:{ - audio:'tspowei3', - trigger:{global:'phaseBegin'}, - direct:true, - filter(event,player){ - return event.player!=player&&event.player.hasMark('dulie')&& - (player.countCards('h')>0||player.hp>=event.player.hp&&event.player.countCards('h')>0); + use: { + audio: "tspowei3", + trigger: { global: "phaseBegin" }, + direct: true, + filter(event, player) { + return ( + event.player != player && + event.player.hasMark("dulie") && + (player.countCards("h") > 0 || + (player.hp >= event.player.hp && event.player.countCards("h") > 0)) + ); }, - content(){ - 'step 0' - var list=[],target=trigger.player,choiceList=[ - '弃置一张牌并对其造成1点伤害', - '获得其一张手牌', - ]; - event.target=target; - if(player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'tspowei_use'); - },'h')) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(player.hp>=target.hp&&target.countCards('h')>0) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - player.chooseControl(list,'cancel2').set('prompt',get.prompt('tspowei',target)).set('choiceList',choiceList).set('ai',function(){ - var evt=_status.event.getParent(); - if(evt.player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,evt.player,'tspowei_use')&&get.value(card,evt.player)<7; - },'h')&&get.damageEffect(evt.target,evt.player,evt.player)>0) return '选项一'; - if(evt.player.hp>=evt.target.hp&&evt.target.countCards('h')>0&&get.attitude(evt.player,evt.target)<=0&&!evt.target.hasSkillTag('noh')) return '选项二'; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='选项二'){ - player.logSkill('tspowei_use',target); - player.gainPlayerCard(target,'h',true); + content() { + "step 0"; + var list = [], + target = trigger.player, + choiceList = ["弃置一张牌并对其造成1点伤害", "获得其一张手牌"]; + event.target = target; + if ( + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "tspowei_use"); + }, "h") + ) + list.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (player.hp >= target.hp && target.countCards("h") > 0) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + player + .chooseControl(list, "cancel2") + .set("prompt", get.prompt("tspowei", target)) + .set("choiceList", choiceList) + .set("ai", function () { + var evt = _status.event.getParent(); + if ( + evt.player.hasCard(function (card) { + return ( + lib.filter.cardDiscardable(card, evt.player, "tspowei_use") && + get.value(card, evt.player) < 7 + ); + }, "h") && + get.damageEffect(evt.target, evt.player, evt.player) > 0 + ) + return "选项一"; + if ( + evt.player.hp >= evt.target.hp && + evt.target.countCards("h") > 0 && + get.attitude(evt.player, evt.target) <= 0 && + !evt.target.hasSkillTag("noh") + ) + return "选项二"; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "选项二") { + player.logSkill("tspowei_use", target); + player.gainPlayerCard(target, "h", true); event.goto(3); } - } - else event.finish(); - 'step 2' - player.chooseToDiscard('h',true).logSkill=['tspowei_use',target]; - if(get.mode()!='identity'||player.identity!='nei') player.addExpose(0.2); + } else event.finish(); + "step 2"; + player.chooseToDiscard("h", true).logSkill = ["tspowei_use", target]; + if (get.mode() != "identity" || player.identity != "nei") player.addExpose(0.2); target.damage(); - 'step 3' - player.addTempSkill('tspowei_inRange'); + "step 3"; + player.addTempSkill("tspowei_inRange"); }, - ai:{expose:0.2}, + ai: { expose: 0.2 }, }, - inRange:{ - charlotte:true, - mod:{ - inRangeOf(from,to){ - if(from==_status.currentPhase) return true; + inRange: { + charlotte: true, + mod: { + inRangeOf(from, to) { + if (from == _status.currentPhase) return true; }, }, }, - init:{ - audio:'tspowei3', - trigger:{ - global:'phaseBefore', - player:'enterGame', + init: { + audio: "tspowei3", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - logTarget(event,player){ - return game.filterPlayer((current)=>current!=player&&!current.hasMark('dulie')); + logTarget(event, player) { + return game.filterPlayer( + (current) => current != player && !current.hasMark("dulie") + ); }, - content(){ - var list=game.filterPlayer((current)=>current!=player&&!current.hasMark('dulie')).sortBySeat(); - for(var i of list) i.addMark('dulie',1,false); + content() { + var list = game + .filterPlayer((current) => current != player && !current.hasMark("dulie")) + .sortBySeat(); + for (var i of list) i.addMark("dulie", 1, false); }, }, - move:{ - audio:'tspowei3', - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return game.hasPlayer((current)=>current!=player&¤t.hasMark('dulie')); + move: { + audio: "tspowei3", + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return game.hasPlayer((current) => current != player && current.hasMark("dulie")); }, - content(){ - var list=game.filterPlayer((current)=>current!=player&¤t.hasMark('dulie')).sortBySeat(); - var map={}; - for(var i of list){ - var num=i.countMark('dulie'); - i.removeMark('dulie',num); - map[i.playerid]=num; + content() { + var list = game + .filterPlayer((current) => current != player && current.hasMark("dulie")) + .sortBySeat(); + var map = {}; + for (var i of list) { + var num = i.countMark("dulie"); + i.removeMark("dulie", num); + map[i.playerid] = num; } - for(var i of list){ - var next=i.next; - if(next==player) next=next.next; - next.addMark('dulie',map[i.playerid]); + for (var i of list) { + var next = i.next; + if (next == player) next = next.next; + next.addMark("dulie", map[i.playerid]); } }, }, - achieve:{ - audio:'tspowei1', - trigger:{player:'phaseBegin'}, - forced:true, - skillAnimation:true, - animationColor:'metal', - filter(event,player){ - return !game.hasPlayer(function(current){ - return current.hasMark('dulie'); + achieve: { + audio: "tspowei1", + trigger: { player: "phaseBegin" }, + forced: true, + skillAnimation: true, + animationColor: "metal", + filter(event, player) { + return !game.hasPlayer(function (current) { + return current.hasMark("dulie"); }); }, - content(){ - game.log(player,'成功完成使命'); - player.awakenSkill('tspowei'); - player.addSkills('shenzhu'); + content() { + game.log(player, "成功完成使命"); + player.awakenSkill("tspowei"); + player.addSkills("shenzhu"); }, }, - fail:{ - audio:'tspowei2', - trigger:{player:'dying'}, - forced:true, - content(){ - 'step 0' - game.log(player,'使命失败'); - player.awakenSkill('tspowei'); - if(player.hp<1) player.recover(1-player.hp); - 'step 1' - var num=player.countCards('e'); - if(num>0) player.chooseToDiscard('e',true,num); + fail: { + audio: "tspowei2", + trigger: { player: "dying" }, + forced: true, + content() { + "step 0"; + game.log(player, "使命失败"); + player.awakenSkill("tspowei"); + if (player.hp < 1) player.recover(1 - player.hp); + "step 1"; + var num = player.countCards("e"); + if (num > 0) player.chooseToDiscard("e", true, num); }, }, }, }, - tspowei1:{audio:true}, - tspowei2:{audio:true}, - tspowei3:{audio:true}, - shenzhu:{ - audio:2, - trigger:{player:'useCardAfter'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'&&event.card.isCard&&event.cards.length==1; + tspowei1: { audio: true }, + tspowei2: { audio: true }, + tspowei3: { audio: true }, + shenzhu: { + audio: 2, + trigger: { player: "useCardAfter" }, + forced: true, + filter(event, player) { + return event.card.name == "sha" && event.card.isCard && event.cards.length == 1; }, - content(){ - 'step 0' - player.chooseControl().set('choiceList',[ - '摸一张牌,且本回合使用【杀】的次数上限+1', - '摸三张牌,且本回合不能再使用【杀】', - ]).set('ai',()=>_status.event.player.hasSha()?0:1); - 'step 1' - if(result.index==0){ + content() { + "step 0"; + player + .chooseControl() + .set("choiceList", [ + "摸一张牌,且本回合使用【杀】的次数上限+1", + "摸三张牌,且本回合不能再使用【杀】", + ]) + .set("ai", () => (_status.event.player.hasSha() ? 0 : 1)); + "step 1"; + if (result.index == 0) { player.draw(); - player.addTempSkill('shenzhu_more'); - player.addMark('shenzhu_more',1,false); - } - else{ + player.addTempSkill("shenzhu_more"); + player.addMark("shenzhu_more", 1, false); + } else { player.draw(3); - player.addTempSkill('shenzhu_less'); + player.addTempSkill("shenzhu_less"); } }, - subSkill:{ - more:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.countMark('shenzhu_more'); + subSkill: { + more: { + charlotte: true, + onremove: true, + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("shenzhu_more"); }, }, }, - less:{ - charlotte:true, - mod:{ - cardEnabled(card){ - if(card.name=='sha') return false; - } + less: { + charlotte: true, + mod: { + cardEnabled(card) { + if (card.name == "sha") return false; + }, }, }, }, }, - dangmo:{ - audio:2, - trigger:{player:'useCard2'}, - direct:true, - filter(event,player){ - if(event.card.name!='sha'||player.hp<=1) return false; - var evt=event.getParent('phaseUse'); - return evt&&evt.player==player&&player.getHistory('useCard',function(evtx){ - return evtx.card.name=='sha'&&evtx.getParent('phaseUse')==evt; - })[0]==event&&game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.filterTarget(event.card,player,current); - }); + dangmo: { + audio: 2, + trigger: { player: "useCard2" }, + direct: true, + filter(event, player) { + if (event.card.name != "sha" || player.hp <= 1) return false; + var evt = event.getParent("phaseUse"); + return ( + evt && + evt.player == player && + player.getHistory("useCard", function (evtx) { + return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt; + })[0] == event && + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.filterTarget(event.card, player, current) + ); + }) + ); }, - content(){ - 'step 0' - var num=Math.min(player.hp-1,game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.filterTarget(trigger.card,player,current); - })); - player.chooseTarget(get.prompt('dangmo'),'为'+get.translation(trigger.card)+'增加至多'+get.translation(num)+'个目标',[1,num],function(card,player,target){ - var evt=_status.event.getTrigger(); - return !evt.targets.includes(target)&&lib.filter.filterTarget(evt.card,player,target); - }).set('ai',function(target){ - var evt=_status.event.getTrigger(),eff=get.effect(target,evt.card,evt.player,evt.player); - if(player.hasSkill('tspowei')&&target.hasMark('dulie')) return 4*eff; - return eff; - }); - 'step 1' - if(result.bool){ - if(player!=game.me&&!player.isOnline()) game.delayx(); - event.targets=result.targets; - } - else event.finish(); - 'step 2' - player.logSkill('dangmo',targets); + content() { + "step 0"; + var num = Math.min( + player.hp - 1, + game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.filterTarget(trigger.card, player, current) + ); + }) + ); + player + .chooseTarget( + get.prompt("dangmo"), + "为" + + get.translation(trigger.card) + + "增加至多" + + get.translation(num) + + "个目标", + [1, num], + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + !evt.targets.includes(target) && + lib.filter.filterTarget(evt.card, player, target) + ); + } + ) + .set("ai", function (target) { + var evt = _status.event.getTrigger(), + eff = get.effect(target, evt.card, evt.player, evt.player); + if (player.hasSkill("tspowei") && target.hasMark("dulie")) return 4 * eff; + return eff; + }); + "step 1"; + if (result.bool) { + if (player != game.me && !player.isOnline()) game.delayx(); + event.targets = result.targets; + } else event.finish(); + "step 2"; + player.logSkill("dangmo", targets); trigger.targets.addArray(targets); }, }, - reshuishi:{ - audio:'shuishi', - enable:'phaseUse', - usable:1, - frequent:true, - filter(event,player){ - return player.maxHp<10; + reshuishi: { + audio: "shuishi", + enable: "phaseUse", + usable: 1, + frequent: true, + filter(event, player) { + return player.maxHp < 10; }, - content(){ - 'step 0' - event.cards=[]; - event.suits=[]; - 'step 1' - player.judge(function(result){ - var evt=_status.event.getParent('reshuishi'); - if(evt&&evt.suits&&evt.suits.includes(get.suit(result))) return 0; - return 1; - }).set('callback',lib.skill.reshuishi.callback).judge2=function(result){ - return result.bool?true:false; - }; - 'step 2' - var cards=cards.filterInD(); - if(cards.length) player.chooseTarget('将'+get.translation(cards)+'交给一名角色',true).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<=0) return att; - if(target.countCards('h')+_status.event.num>=_status.event.max) att/=3; - if(target.hasSkillTag('nogain')) att/=10; - return att; - }).set('num',cards.length).set('max',game.filterPlayer().reduce((num,i)=>{ - return Math.max(num,i.countCards('h')); - },0)); + content() { + "step 0"; + event.cards = []; + event.suits = []; + "step 1"; + player + .judge(function (result) { + var evt = _status.event.getParent("reshuishi"); + if (evt && evt.suits && evt.suits.includes(get.suit(result))) return 0; + return 1; + }) + .set("callback", lib.skill.reshuishi.callback).judge2 = function (result) { + return result.bool ? true : false; + }; + "step 2"; + var cards = cards.filterInD(); + if (cards.length) + player + .chooseTarget("将" + get.translation(cards) + "交给一名角色", true) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att <= 0) return att; + if (target.countCards("h") + _status.event.num >= _status.event.max) att /= 3; + if (target.hasSkillTag("nogain")) att /= 10; + return att; + }) + .set("num", cards.length) + .set( + "max", + game.filterPlayer().reduce((num, i) => { + return Math.max(num, i.countCards("h")); + }, 0) + ); else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - target.gain(cards,'gain2').giver=player; - } - else event.finish(); - 'step 4' - if(target.isMaxHandcard()) player.loseMaxHp(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + target.gain(cards, "gain2").giver = player; + } else event.finish(); + "step 4"; + if (target.isMaxHandcard()) player.loseMaxHp(); }, - callback(){ - 'step 0' - var evt=event.getParent(2); + callback() { + "step 0"; + var evt = event.getParent(2); event.getParent().orderingCards.remove(event.judgeResult.card); evt.cards.push(event.judgeResult.card); - if(event.getParent().result.bool&&player.maxHp<10){ + if (event.getParent().result.bool && player.maxHp < 10) { evt.suits.push(event.getParent().result.suit); player.gainMaxHp(); - player.chooseBool('是否继续发动【慧识】?').set('frequentSkill','reshuishi'); - } - else event._result={bool:false}; - 'step 1' - if(result.bool) event.getParent(2).redo(); + player.chooseBool("是否继续发动【慧识】?").set("frequentSkill", "reshuishi"); + } else event._result = { bool: false }; + "step 1"; + if (result.bool) event.getParent(2).redo(); }, - ai:{ - order:9, - result:{ - player:1, + ai: { + order: 9, + result: { + player: 1, }, }, }, - shuishi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.maxHp<10; + shuishi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.maxHp < 10; }, - filterTarget:true, - content(){ - 'step 0' + filterTarget: true, + content() { + "step 0"; target.draw(); - 'step 1' - if(!result||!Array.isArray(result)||result.length!=1||get.itemtype(result[0])!='card'){ + "step 1"; + if ( + !result || + !Array.isArray(result) || + result.length != 1 || + get.itemtype(result[0]) != "card" + ) { event.finish(); return; } - var suit=get.suit(result[0]),hs=target.getCards('h'); - for(var i of hs){ - if(i!=result[0]&&get.suit(i,target)==suit){ + var suit = get.suit(result[0]), + hs = target.getCards("h"); + for (var i of hs) { + if (i != result[0] && get.suit(i, target) == suit) { player.loseMaxHp(); target.showHandcards(); event.finish(); @@ -4318,4274 +5673,5219 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } player.gainMaxHp(); - 'step 2' - if(player.maxHp<10){ - player.chooseBool('是否继续发动【慧识】?'); - } - else event.finish(); - 'step 3' - if(result.bool) event.goto(0); + "step 2"; + if (player.maxHp < 10) { + player.chooseBool("是否继续发动【慧识】?"); + } else event.finish(); + "step 3"; + if (result.bool) event.goto(0); }, - ai:{ - order:0.5, - result:{ - target:0.2, - player(player,target){ - var list=[],hs=target.getCards('h'); - for(var i of hs) list.add(get.suit(i,target)); - if(list.length==0) return 0; - if(list.length==1) return player.maxHp>2?0:-2; - if(list.length==2) return player.maxHp>3?0:-2; + ai: { + order: 0.5, + result: { + target: 0.2, + player(player, target) { + var list = [], + hs = target.getCards("h"); + for (var i of hs) list.add(get.suit(i, target)); + if (list.length == 0) return 0; + if (list.length == 1) return player.maxHp > 2 ? 0 : -2; + if (list.length == 2) return player.maxHp > 3 ? 0 : -2; return -2; }, }, }, }, - stianyi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - filter(event,player){ - return !game.hasPlayer(function(current){ - return current.getAllHistory('damage').length==0; + stianyi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + filter(event, player) { + return !game.hasPlayer(function (current) { + return current.getAllHistory("damage").length == 0; }); }, - content(){ - 'step 0' - player.awakenSkill('stianyi'); + content() { + "step 0"; + player.awakenSkill("stianyi"); player.gainMaxHp(2); player.recover(); - 'step 1' - player.chooseTarget(true,'令一名角色获得技能〖佐幸〗').set('ai',function(target){ - return get.attitude(_status.event.player,target); + "step 1"; + player.chooseTarget(true, "令一名角色获得技能〖佐幸〗").set("ai", function (target) { + return get.attitude(_status.event.player, target); }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.storage.zuoxing=player; - target.addSkills('zuoxing'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.storage.zuoxing = player; + target.addSkills("zuoxing"); } }, - derivation:'zuoxing', + derivation: "zuoxing", }, - zuoxing:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - var target=player.storage.zuoxing; - if(!target||!target.isIn()||target.maxHp<2) return false; - for(var i of lib.inpile){ - if(get.type(i)=='trick'&&event.filterCard({name:i,isCard:true},player,event)) return true; + zuoxing: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + var target = player.storage.zuoxing; + if (!target || !target.isIn() || target.maxHp < 2) return false; + for (var i of lib.inpile) { + if ( + get.type(i) == "trick" && + event.filterCard({ name: i, isCard: true }, player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog(event,player){ - var list=[]; - for(var i of lib.inpile){ - if(get.type(i)=='trick'&&event.filterCard({name:i,isCard:true},player,event)) list.push(['锦囊','',i]); + chooseButton: { + dialog(event, player) { + var list = []; + for (var i of lib.inpile) { + if ( + get.type(i) == "trick" && + event.filterCard({ name: i, isCard: true }, player, event) + ) + list.push(["锦囊", "", i]); } - return ui.create.dialog('佐幸',[list,'vcard']); + return ui.create.dialog("佐幸", [list, "vcard"]); }, - check(button){ - return _status.event.player.getUseValue({name:button.link[2],isCard:true}); + check(button) { + return _status.event.player.getUseValue({ name: button.link[2], isCard: true }); }, - backup(links,player){ + backup(links, player) { return { - viewAs:{ - name:links[0][2], - isCard:true, + viewAs: { + name: links[0][2], + isCard: true, }, - filterCard:()=>false, - selectCard:-1, - popname:true, - precontent(){ - player.logSkill('zuoxing'); - var target=player.storage.zuoxing; + filterCard: () => false, + selectCard: -1, + popname: true, + precontent() { + player.logSkill("zuoxing"); + var target = player.storage.zuoxing; target.loseMaxHp(); //delete event.result.skill; }, - } + }; }, - prompt(links,player){ - return '请选择'+get.translation(links[0][2])+'的目标'; + prompt(links, player) { + return "请选择" + get.translation(links[0][2]) + "的目标"; }, }, - ai:{order:1,result:{player:1}}, + ai: { order: 1, result: { player: 1 } }, }, - resghuishi:{ - audio:'sghuishi', - inherit:'sghuishi', - filterTarget:true, - prompt(){ - var player=_status.event.player; - if(player.maxHp>=game.players.length) return '选择一名角色。若其拥有未发动过的觉醒技,则你解除其中一个觉醒技的发动限制;否则其摸四张牌。然后你减2点体力上限。'; - return '令一名角色摸四张牌,然后你减2点体力上限。'; + resghuishi: { + audio: "sghuishi", + inherit: "sghuishi", + filterTarget: true, + prompt() { + var player = _status.event.player; + if (player.maxHp >= game.players.length) + return "选择一名角色。若其拥有未发动过的觉醒技,则你解除其中一个觉醒技的发动限制;否则其摸四张牌。然后你减2点体力上限。"; + return "令一名角色摸四张牌,然后你减2点体力上限。"; }, - content(){ - 'step 0' - player.awakenSkill('resghuishi'); - var list=target.getSkills(null,false,false).filter(function(skill){ - var info=lib.skill[skill]; - return info&&info.juexingji&&!target.awakenedSkills.includes(skill); + content() { + "step 0"; + player.awakenSkill("resghuishi"); + var list = target.getSkills(null, false, false).filter(function (skill) { + var info = lib.skill[skill]; + return info && info.juexingji && !target.awakenedSkills.includes(skill); }); - if(player.maxHp>=game.players.length&&list.length>0){ - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('prompt','选择一个觉醒技,令'+get.translation(target)+'可无视条件发动该技能'); - } - else{ + if (player.maxHp >= game.players.length && list.length > 0) { + if (list.length == 1) event._result = { control: list[0] }; + else + player + .chooseControl(list) + .set( + "prompt", + "选择一个觉醒技,令" + get.translation(target) + "可无视条件发动该技能" + ); + } else { target.draw(4); event.goto(2); } - 'step 1' - target.storage.resghuishi_mark=result.control; - target.markSkill('resghuishi_mark'); - var info=lib.skill[result.control]; - if(info.filter&&!info.charlotte&&!info.resghuishi_filter){ - info.resghuishi_filter=info.filter; - info.filter=function(event,player){ - if(player.storage.resghuishi_mark) return true; - return this.resghuishi_filter.apply(this,arguments); - } + "step 1"; + target.storage.resghuishi_mark = result.control; + target.markSkill("resghuishi_mark"); + var info = lib.skill[result.control]; + if (info.filter && !info.charlotte && !info.resghuishi_filter) { + info.resghuishi_filter = info.filter; + info.filter = function (event, player) { + if (player.storage.resghuishi_mark) return true; + return this.resghuishi_filter.apply(this, arguments); + }; } - 'step 2' + "step 2"; player.loseMaxHp(2); }, - intro:{content:'未发动'}, - ai:{ - order:0.1, - expose:0.2, - result:{ - target(player,target){ - if(target!=player&&player.hasUnknown()||player.maxHp<(player.getDamagedHp()>1?5:6)) return 0; - if(target==player&&player.hasSkill('resghuishi')&&game.hasPlayer(function(current){ - return current.getAllHistory('damage').length==0; - })) return 4; - var list=target.getSkills(null,false,false).filter(function(skill){ - var info=lib.skill[skill]; - return info&&info.juexingji&&!target.awakenedSkills.includes(skill); + intro: { content: "未发动" }, + ai: { + order: 0.1, + expose: 0.2, + result: { + target(player, target) { + if ( + (target != player && player.hasUnknown()) || + player.maxHp < (player.getDamagedHp() > 1 ? 5 : 6) + ) + return 0; + if ( + target == player && + player.hasSkill("resghuishi") && + game.hasPlayer(function (current) { + return current.getAllHistory("damage").length == 0; + }) + ) + return 4; + var list = target.getSkills(null, false, false).filter(function (skill) { + var info = lib.skill[skill]; + return info && info.juexingji && !target.awakenedSkills.includes(skill); }); - if(list.length||target.hasJudge('lebu')||target.hasSkillTag('nogain')) return 0; + if (list.length || target.hasJudge("lebu") || target.hasSkillTag("nogain")) + return 0; return 4; }, }, }, - subSkill:{mark:{intro:{content:'发动【$】时无视条件'}}}, + subSkill: { mark: { intro: { content: "发动【$】时无视条件" } } }, }, - sghuishi:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'water', - filterTarget:lib.filter.notMe, - content(){ - 'step 0' - player.awakenSkill('sghuishi'); - var list=target.getSkills(null,false,false).filter(function(skill){ - var info=lib.skill[skill]; - return info&&info.juexingji; + sghuishi: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "water", + filterTarget: lib.filter.notMe, + content() { + "step 0"; + player.awakenSkill("sghuishi"); + var list = target.getSkills(null, false, false).filter(function (skill) { + var info = lib.skill[skill]; + return info && info.juexingji; }); - if(list.length){ - target.addMark('sghuishi',1,false); - for(var i of list){ - var info=lib.skill[i]; - if(info.filter&&!info.charlotte&&!info.sghuishi_filter){ - info.sghuishi_filter=info.filter; - info.filter=function(event,player){ - if(player.hasMark('sghuishi')) return true; - return this.sghuishi_filter.apply(this,arguments); - } + if (list.length) { + target.addMark("sghuishi", 1, false); + for (var i of list) { + var info = lib.skill[i]; + if (info.filter && !info.charlotte && !info.sghuishi_filter) { + info.sghuishi_filter = info.filter; + info.filter = function (event, player) { + if (player.hasMark("sghuishi")) return true; + return this.sghuishi_filter.apply(this, arguments); + }; } } - } - else target.draw(4); + } else target.draw(4); player.loseMaxHp(2); }, - intro:{content:'发动非Charlotte觉醒技时无视条件'}, - ai:{ - order:0.1, - expose:0.2, - result:{ - target(player,target){ - if(player.hasUnknown()||player.maxHp<5) return 0; - var list=target.getSkills(null,false,false).filter(function(skill){ - var info=lib.skill[skill]; - return info&&info.juexingji; + intro: { content: "发动非Charlotte觉醒技时无视条件" }, + ai: { + order: 0.1, + expose: 0.2, + result: { + target(player, target) { + if (player.hasUnknown() || player.maxHp < 5) return 0; + var list = target.getSkills(null, false, false).filter(function (skill) { + var info = lib.skill[skill]; + return info && info.juexingji; }); - if(list.length||target.hasJudge('lebu')||target.hasSkillTag('nogain')) return 0; + if (list.length || target.hasJudge("lebu") || target.hasSkillTag("nogain")) + return 0; return 4; }, }, }, }, - zhanjiang:{ - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - var players=game.filterPlayer(); - for(var i=0;i0){ + zhanjiang: { + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && players[i].getEquips("qinggang").length > 0) { return true; } } }, - content(){ - var players=game.filterPlayer(); - for(var i=0;i0){ - player.line(players[i],'green'); - player.gain(e,players[i],'give','bySelf'); + content() { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player) { + var e = players[i].getEquips("qinggang"); + if (e.length > 0) { + player.line(players[i], "green"); + player.gain(e, players[i], "give", "bySelf"); } } } - } - }, - boss_juejing:{ - audio:'juejing', - audioname2:{ - dc_zhaoyun:'dcjuejing', }, - trigger:{player:'phaseDrawBefore'}, - forced:true, - content(){ + }, + boss_juejing: { + audio: "juejing", + audioname2: { + dc_zhaoyun: "dcjuejing", + }, + trigger: { player: "phaseDrawBefore" }, + forced: true, + content() { trigger.cancel(); }, - ai:{ - noh:true, - nogain:true, + ai: { + noh: true, + nogain: true, }, - group:'boss_juejing2' + group: "boss_juejing2", }, - boss_juejing2:{ - audio:'juejing', - audioname2:{ - dc_zhaoyun:'dcjuejing', + boss_juejing2: { + audio: "juejing", + audioname2: { + dc_zhaoyun: "dcjuejing", }, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter(event,player){ - if(event.name=='gain'&&event.player==player) return player.countCards('h')>4; - var evt=event.getl(player); - if(!evt||!evt.hs||evt.hs.length==0||player.countCards('h')>=4) return false; - var evt=event; - for(var i=0;i<4;i++){ - evt=evt.getParent('boss_juejing2'); - if(evt.name!='boss_juejing2') return true; + forced: true, + filter(event, player) { + if (event.name == "gain" && event.player == player) return player.countCards("h") > 4; + var evt = event.getl(player); + if (!evt || !evt.hs || evt.hs.length == 0 || player.countCards("h") >= 4) return false; + var evt = event; + for (var i = 0; i < 4; i++) { + evt = evt.getParent("boss_juejing2"); + if (evt.name != "boss_juejing2") return true; } return false; }, - content(){ - var num=4-player.countCards('h'); - if(num>0) player.draw(num); - else player.chooseToDiscard('h',true,-num); + content() { + var num = 4 - player.countCards("h"); + if (num > 0) player.draw(num); + else player.chooseToDiscard("h", true, -num); }, }, - dcjuejing:{audio:2}, - meihun:{ - audio:2, - trigger:{ - player:'phaseJieshuBegin', - target:'useCardToTargeted', + dcjuejing: { audio: 2 }, + meihun: { + audio: 2, + trigger: { + player: "phaseJieshuBegin", + target: "useCardToTargeted", }, - direct:true, - filter(event,player){ - if(event.name!='phaseJieshu'&&event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + direct: true, + filter(event, player) { + if (event.name != "phaseJieshu" && event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('meihun'),function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0) return 0; - return 0.1-att/target.countCards('h'); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('meihun',target); - event.target=target; - player.chooseControl(lib.suit).set('prompt','请选择一种花色').set('ai',function(){ - return lib.suit.randomGet(); + content() { + "step 0"; + player + .chooseTarget(get.prompt2("meihun"), function (card, player, target) { + return target != player && target.countCards("h") > 0; }) - } - else event.finish(); - 'step 2' - var suit=result.control; - player.chat(get.translation(suit+2)); - game.log(player,'选择了','#y'+get.translation(suit+2)) - if(target.countCards('h',{suit:suit})){ - target.chooseCard('h','交给'+get.translation(player)+'一张'+get.translation(suit)+'花色的手牌',true,function(card,player){ - return get.suit(card,player)==_status.event.suit; - }).set('suit',suit); - } - else{ - player.discardPlayerCard(target,true,'h','visible'); + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) return 0; + return 0.1 - att / target.countCards("h"); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("meihun", target); + event.target = target; + player + .chooseControl(lib.suit) + .set("prompt", "请选择一种花色") + .set("ai", function () { + return lib.suit.randomGet(); + }); + } else event.finish(); + "step 2"; + var suit = result.control; + player.chat(get.translation(suit + 2)); + game.log(player, "选择了", "#y" + get.translation(suit + 2)); + if (target.countCards("h", { suit: suit })) { + target + .chooseCard( + "h", + "交给" + + get.translation(player) + + "一张" + + get.translation(suit) + + "花色的手牌", + true, + function (card, player) { + return get.suit(card, player) == _status.event.suit; + } + ) + .set("suit", suit); + } else { + player.discardPlayerCard(target, true, "h", "visible"); event.finish(); } - 'step 3' - if(result.bool&&result.cards&&result.cards.length) target.give(result.cards,player,'give'); + "step 3"; + if (result.bool && result.cards && result.cards.length) + target.give(result.cards, player, "give"); }, }, //Connect Mode support after Angel Beats! -2nd beat- - huoxin:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - if(game.countPlayer()<3) return false; - for(var i of lib.suit){ - if(player.countCards('h',{suit:i})>1) return true; + huoxin: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + if (game.countPlayer() < 3) return false; + for (var i of lib.suit) { + if (player.countCards("h", { suit: i }) > 1) return true; } return false; }, - complexCard:true, - position:'h', - filterCard(card,player){ - if(!ui.selected.cards.length){ - var suit=get.suit(card); - return player.countCards('h',function(card2){ - return card!=card2&&get.suit(card2,player)==suit; - })>0; + complexCard: true, + position: "h", + filterCard(card, player) { + if (!ui.selected.cards.length) { + var suit = get.suit(card); + return ( + player.countCards("h", function (card2) { + return card != card2 && get.suit(card2, player) == suit; + }) > 0 + ); } - return get.suit(card,player)==get.suit(ui.selected.cards[0],player); + return get.suit(card, player) == get.suit(ui.selected.cards[0], player); }, - selectCard:2, - selectTarget:2, - filterTarget:lib.filter.notMe, - multitarget:true, - multiline:true, - delay:false, - discard:false, - lose:false, - check(card){ - return 6-get.value(card); + selectCard: 2, + selectTarget: 2, + filterTarget: lib.filter.notMe, + multitarget: true, + multiline: true, + delay: false, + discard: false, + lose: false, + check(card) { + return 6 - get.value(card); }, - targetprompt:['拼点发起人','拼点目标'], - content(){ - 'step 0' - var list=[]; - for(var i=0;i1; + huoxin_control: { + audio: "huoxin", + forced: true, + trigger: { global: "phaseBeginStart" }, + filter(event, player) { + return ( + player != event.player && + !event.player._trueMe && + event.player.countMark("huoxin") > 1 + ); }, - logTarget:'player', - skillAnimation:true, - animationColor:'key', - content(){ - trigger.player.removeMark('huoxin',trigger.player.countMark('huoxin')); - trigger.player._trueMe=player; - game.addGlobalSkill('autoswap'); - if(trigger.player==game.me){ - game.notMe=true; - if(!_status.auto) ui.click.auto(); + logTarget: "player", + skillAnimation: true, + animationColor: "key", + content() { + trigger.player.removeMark("huoxin", trigger.player.countMark("huoxin")); + trigger.player._trueMe = player; + game.addGlobalSkill("autoswap"); + if (trigger.player == game.me) { + game.notMe = true; + if (!_status.auto) ui.click.auto(); } - trigger.player.addSkill('huoxin2'); + trigger.player.addSkill("huoxin2"); }, }, - huoxin2:{ - trigger:{ - player:['phaseAfter','dieAfter'], - global:'phaseBeforeStart', + huoxin2: { + trigger: { + player: ["phaseAfter", "dieAfter"], + global: "phaseBeforeStart", }, - lastDo:true, - charlotte:true, - forceDie:true, - forced:true, - silent:true, - content(){ - player.removeSkill('huoxin2'); + lastDo: true, + charlotte: true, + forceDie: true, + forced: true, + silent: true, + content() { + player.removeSkill("huoxin2"); }, - onremove(player){ - if(player==game.me){ - if(!game.notMe) game.swapPlayerAuto(player._trueMe) + onremove(player) { + if (player == game.me) { + if (!game.notMe) game.swapPlayerAuto(player._trueMe); else delete game.notMe; - if(_status.auto) ui.click.auto(); + if (_status.auto) ui.click.auto(); } delete player._trueMe; }, }, - shiki_omusubi:{ - audio:2, - trigger:{global:'roundStart'}, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('shiki_omusubi'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player.isHealthy()) return 0; - if(player.hp<3&&player.getDamagedHp()<2) return 0; - var list=[]; - if(lib.character[target.name]) list.addArray(lib.character[target.name][3]); - if(lib.character[target.name1]) list.addArray(lib.character[target.name1][3]); - if(lib.character[target.name2]) list.addArray(lib.character[target.name2][3]); - list=list.filter(function(i){ + shiki_omusubi: { + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + content() { + "step 0"; + player + .chooseTarget(get.prompt2("shiki_omusubi"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + if (player.isHealthy()) return 0; + if (player.hp < 3 && player.getDamagedHp() < 2) return 0; + var list = []; + if (lib.character[target.name]) list.addArray(lib.character[target.name][3]); + if (lib.character[target.name1]) list.addArray(lib.character[target.name1][3]); + if (lib.character[target.name2]) list.addArray(lib.character[target.name2][3]); + list = list.filter(function (i) { return !player.hasSkill(i); }); - if(!list.length) return 0; - return 1+Math.random(); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('shiki_omusubi',target); + if (!list.length) return 0; + return 1 + Math.random(); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("shiki_omusubi", target); player.loseMaxHp(); - var list=[]; - if(lib.character[target.name]) list.addArray(lib.character[target.name][3]); - if(lib.character[target.name1]) list.addArray(lib.character[target.name1][3]); - if(lib.character[target.name2]) list.addArray(lib.character[target.name2][3]); + var list = []; + if (lib.character[target.name]) list.addArray(lib.character[target.name][3]); + if (lib.character[target.name1]) list.addArray(lib.character[target.name1][3]); + if (lib.character[target.name2]) list.addArray(lib.character[target.name2][3]); player.addSkills(list); - game.broadcastAll(function(list){ + game.broadcastAll(function (list) { lib.character.key_shiki[3].addArray(list); game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.key_shiki='shiki_omusubi'; + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.key_shiki = "shiki_omusubi"; } - },list); + }, list); } }, }, - kagari_zongsi:{ - enable:'phaseUse', - usable:1, - content(){ - 'step 0' - var controls=[]; - if(ui.cardPile.hasChildNodes()) controls.push('选择牌堆中的一张牌'); - if(ui.discardPile.hasChildNodes()) controls.push('选择弃牌堆中的一张牌'); - if(game.hasPlayer(function(current){ - return current.countCards('hej')>0; - })) controls.push('选择一名角色区域内的一张牌'); - if(!controls.length){event.finish();return;} - event.controls=controls; - var next=player.chooseControl(); - next.set('choiceList',controls) - next.set('prompt','请选择要移动的卡牌的来源'); - next.ai=function(){return 0}; - 'step 1' - result.control=event.controls[result.index]; - var list=['弃牌堆','牌堆','角色']; - for(var i=0;i 0; + }) + ) + controls.push("选择一名角色区域内的一张牌"); + if (!controls.length) { + event.finish(); + return; } - if(event.index==2){ - player.chooseTarget('请选择要移动的卡牌的来源',true,function(card,kagari,target){ - return target.countCards('hej')>0; - }); + event.controls = controls; + var next = player.chooseControl(); + next.set("choiceList", controls); + next.set("prompt", "请选择要移动的卡牌的来源"); + next.ai = function () { + return 0; + }; + "step 1"; + result.control = event.controls[result.index]; + var list = ["弃牌堆", "牌堆", "角色"]; + for (var i = 0; i < list.length; i++) { + if (result.control.indexOf(list[i]) != -1) { + event.index = i; + break; + } } - else{ - var source=ui[event.index==0?'discardPile':'cardPile'].childNodes; - var list=[]; - for(var i=0;i 0; + } + ); + } else { + var source = ui[event.index == 0 ? "discardPile" : "cardPile"].childNodes; + var list = []; + for (var i = 0; i < source.length; i++) list.push(source[i]); + player.chooseButton(["请选择要移动的卡牌", list], true).ai = get.buttonValue; } - 'step 2' - if(event.index==2){ + "step 2"; + if (event.index == 2) { player.line(result.targets[0]); - event.target1=result.targets[0]; - player.choosePlayerCard(result.targets[0],true,'hej').set('visible',true); + event.target1 = result.targets[0]; + player.choosePlayerCard(result.targets[0], true, "hej").set("visible", true); + } else { + event.card = result.links[0]; } - else{ - event.card=result.links[0]; - } - 'step 3' - if(event.index==2) event.card=result.cards[0]; - var controls=[ - '将这张牌移动到牌堆的顶部或者底部', - '将这张牌移动到弃牌堆的顶部或者底部', - '将这张牌移动到一名角色对应的区域里', + "step 3"; + if (event.index == 2) event.card = result.cards[0]; + var controls = [ + "将这张牌移动到牌堆的顶部或者底部", + "将这张牌移动到弃牌堆的顶部或者底部", + "将这张牌移动到一名角色对应的区域里", ]; - event.controls=controls; - var next=player.chooseControl(); - next.set('prompt','要对'+get.translation(event.card)+'做什么呢?'); - next.set('choiceList',controls); - next.ai=function(){return 2}; - 'step 4' - result.control=event.controls[result.index]; - var list=['弃牌堆','牌堆','角色']; - for(var i=0;i0; + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h", lib.skill.caopi_xingdong.filterCard) > 0; }, - filterCard(card){ - return card.name=='sha'||get.type(card)=='trick'; + filterCard(card) { + return card.name == "sha" || get.type(card) == "trick"; }, - check(card){return 1}, - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:0, - content(){ - 'step 0' - player.give(cards,target); - 'step 1' - if(!target.getCards('h').includes(cards[0])) event._result={bool:false}; - else target.chooseUseTarget(cards[0],game.filterPlayer(function(current){ - return current!=player; - }),'请使用得到的牌,或者跳过下回合的判定阶段和摸牌阶段'); - 'step 2' - if(result.bool) game.asyncDraw([player,target]); - else{ - target.addTempSkill('caopi_xingdong_mark','phaseJudgeSkipped'); - target.skip('phaseJudge'); - target.skip('phaseDraw'); + check(card) { + return 1; + }, + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: 0, + content() { + "step 0"; + player.give(cards, target); + "step 1"; + if (!target.getCards("h").includes(cards[0])) event._result = { bool: false }; + else + target.chooseUseTarget( + cards[0], + game.filterPlayer(function (current) { + return current != player; + }), + "请使用得到的牌,或者跳过下回合的判定阶段和摸牌阶段" + ); + "step 2"; + if (result.bool) game.asyncDraw([player, target]); + else { + target.addTempSkill("caopi_xingdong_mark", "phaseJudgeSkipped"); + target.skip("phaseJudge"); + target.skip("phaseDraw"); event.finish(); } - 'step 3' + "step 3"; game.delay(); }, - ai:{ - order:12, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(target.hasSkill('pingkou')) return 1; - if(!card) return 0; - var info=get.info(card); - if(info.selectTarget==-1){ - var eff=0; - game.countPlayer(function(current){ - if(current!=player&&target.canUse(card,current)) eff+=get.effect(current,card,target,target)>0 + ai: { + order: 12, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (target.hasSkill("pingkou")) return 1; + if (!card) return 0; + var info = get.info(card); + if (info.selectTarget == -1) { + var eff = 0; + game.countPlayer(function (current) { + if (current != player && target.canUse(card, current)) + eff += get.effect(current, card, target, target) > 0; }); - if(eff>0||get.value(card)<3) return eff; + if (eff > 0 || get.value(card) < 3) return eff; return 0; - } - else if(game.hasPlayer(function(current){ - return current!=player&&target.canUse(card,current)&&get.effect(current,card,target,target)>0 - })) return 1.5; - else if(get.value(card)<3) return -1; + } else if ( + game.hasPlayer(function (current) { + return ( + current != player && + target.canUse(card, current) && + get.effect(current, card, target, target) > 0 + ); + }) + ) + return 1.5; + else if (get.value(card) < 3) return -1; return 0; }, }, }, }, - shenfu:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - content(){ - 'step 0' - event.logged=false; - event.targets=[]; - event.goto(player.countCards('h')%2==1?1:4); - 'step 1' - player.chooseTarget(get.prompt('shenfu'),'对一名其他角色造成1点雷属性伤害',function(card,player,target){ - return target!=player&&!_status.event.getParent().targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player,'thunder')*(target.hp==1?2:1); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - if(!event.logged){ - event.logged=true; - player.logSkill('shenfu',target,'thunder'); - } - else player.line(target,'thunder'); + shenfu: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + content() { + "step 0"; + event.logged = false; + event.targets = []; + event.goto(player.countCards("h") % 2 == 1 ? 1 : 4); + "step 1"; + player + .chooseTarget( + get.prompt("shenfu"), + "对一名其他角色造成1点雷属性伤害", + function (card, player, target) { + return ( + target != player && !_status.event.getParent().targets.includes(target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.damageEffect(target, player, player, "thunder") * (target.hp == 1 ? 2 : 1) + ); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + if (!event.logged) { + event.logged = true; + player.logSkill("shenfu", target, "thunder"); + } else player.line(target, "thunder"); event.targets.push(target); - target.damage('thunder'); - } + target.damage("thunder"); + } else event.finish(); + "step 3"; + if ( + target.getHistory("damage", function (evt) { + return evt.getParent("shenfu") == event && evt._dyinged; + }).length + ) + event.goto(1); else event.finish(); - 'step 3' - if(target.getHistory('damage',function(evt){ - return evt.getParent('shenfu')==event&&evt._dyinged; - }).length) event.goto(1); - else event.finish(); - 'step 4' - player.chooseTarget(get.prompt('shenfu'),'令一名角色摸一张牌或弃置其一张手牌',function(card,player,target){ - return !_status.event.getParent().targets.includes(target); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - var delta=target.hp-target.countCards('h'); - if(Math.abs(delta)==1&&get.sgn(delta)==get.sgn(att)) return 3*Math.abs(att); - if(att>0||target.countCards('h')>0) return Math.abs(att); - return 0; - }); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - if(!event.logged){ - event.logged=true; - player.logSkill('shenfu',target); - } - else player.line(target,'green'); + "step 4"; + player + .chooseTarget( + get.prompt("shenfu"), + "令一名角色摸一张牌或弃置其一张手牌", + function (card, player, target) { + return !_status.event.getParent().targets.includes(target); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + var delta = target.hp - target.countCards("h"); + if (Math.abs(delta) == 1 && get.sgn(delta) == get.sgn(att)) + return 3 * Math.abs(att); + if (att > 0 || target.countCards("h") > 0) return Math.abs(att); + return 0; + }); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + if (!event.logged) { + event.logged = true; + player.logSkill("shenfu", target); + } else player.line(target, "green"); event.targets.push(target); - if(target.countCards('h')==0) event._result={index:0}; - else player.chooseControl('摸一张牌','弃置一张手牌').set('prompt','选择一项令'+get.translation(target)+'执行…').set('goon',get.attitude(player,target)>0?0:1).set('ai',()=>_status.event.goon); + if (target.countCards("h") == 0) event._result = { index: 0 }; + else + player + .chooseControl("摸一张牌", "弃置一张手牌") + .set("prompt", "选择一项令" + get.translation(target) + "执行…") + .set("goon", get.attitude(player, target) > 0 ? 0 : 1) + .set("ai", () => _status.event.goon); //else player.discardPlayerCard(target,'h','弃置'+get.translation(target)+'一张手牌,或点【取消】令其摸一张牌。'); - } - else event.finish(); - 'step 6' - if(result.index==0) target.draw(); - else target.chooseToDiscard('h',true); - 'step 7' - if(target.hp==target.countCards('h')) event.goto(4); + } else event.finish(); + "step 6"; + if (result.index == 0) target.draw(); + else target.chooseToDiscard("h", true); + "step 7"; + if (target.hp == target.countCards("h")) event.goto(4); }, - ai:{expose:0.25}, + ai: { expose: 0.25 }, }, - qixian:{ - mod:{ - maxHandcardBase(player,num){ + qixian: { + mod: { + maxHandcardBase(player, num) { return 7; }, }, }, - chuyuan:{ - audio:2, - trigger:{global:'damageEnd'}, - filter(event,player){ - return event.player.isIn()&&player.getExpansions('chuyuan').length=3; + dengji: { + audio: 2, + derivation: [ + "tianxing", + "new_rejianxiong", + "rerende", + "rezhiheng", + "olluanji", + "caopi_xingdong", + ], + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + return player.getExpansions("chuyuan").length >= 3; }, - content(){ + content() { player.awakenSkill(event.name); - player.addSkills(['tianxing','new_rejianxiong']); + player.addSkills(["tianxing", "new_rejianxiong"]); player.loseMaxHp(); - player.gain(player.getExpansions('chuyuan'),'gain2','fromStorage'); + player.gain(player.getExpansions("chuyuan"), "gain2", "fromStorage"); + }, + ai: { + combo: "chuyuan", }, }, - tianxing:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter(event,player){ - return player.getExpansions('chuyuan').length>=3; + tianxing: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter(event, player) { + return player.getExpansions("chuyuan").length >= 3; }, - content(){ - 'step 0' + content() { + "step 0"; player.awakenSkill(event.name); player.loseMaxHp(); - player.gain(player.getExpansions('chuyuan'),'gain2','fromStorage'); - "step 1" - player.removeSkills('chuyuan'); - player.chooseControl('rerende','rezhiheng','olluanji','caopi_xingdong').set('prompt','选择获得一个技能').set('ai',function(){ - var player=_status.event.player; - if(!player.hasSkill('luanji')&&!player.hasSkill('olluanji')&&player.getUseValue({name:'wanjian'})>4) return 'olluanji'; - if(!player.hasSkill('rezhiheng')) return 'rezhiheng'; - if(!player.hasSkill('caopi_xingdong')) return 'caopi_xingdong'; - return 'rerende'; - }); - 'step 2' + player.gain(player.getExpansions("chuyuan"), "gain2", "fromStorage"); + "step 1"; + player.removeSkills("chuyuan"); + player + .chooseControl("rerende", "rezhiheng", "olluanji", "caopi_xingdong") + .set("prompt", "选择获得一个技能") + .set("ai", function () { + var player = _status.event.player; + if ( + !player.hasSkill("luanji") && + !player.hasSkill("olluanji") && + player.getUseValue({ name: "wanjian" }) > 4 + ) + return "olluanji"; + if (!player.hasSkill("rezhiheng")) return "rezhiheng"; + if (!player.hasSkill("caopi_xingdong")) return "caopi_xingdong"; + return "rerende"; + }); + "step 2"; player.addSkills(result.control); }, + ai: { + combo: "chuyuan", + }, }, - olzhiti:{ - audio:'drlt_zhiti', - global:'olzhiti2', - mod:{ - maxHandcard(player,num){ - if(game.hasPlayer(function(current){ - return current.isDamaged(); - })) return num+1; + olzhiti: { + audio: "drlt_zhiti", + global: "olzhiti2", + mod: { + maxHandcard(player, num) { + if ( + game.hasPlayer(function (current) { + return current.isDamaged(); + }) + ) + return num + 1; }, }, - trigger:{player:['phaseDrawBegin2','phaseEnd']}, - forced:true, - filter(event,player){ - var num=event.name=='phase'?5:3; - if(num==3?event.numFixed:!game.hasPlayer(function(current){ - return current.hasEnabledSlot(); - })) return false; - return game.countPlayer(function(current){ - return current.isDamaged(); - })>=num; + trigger: { player: ["phaseDrawBegin2", "phaseEnd"] }, + forced: true, + filter(event, player) { + var num = event.name == "phase" ? 5 : 3; + if ( + num == 3 + ? event.numFixed + : !game.hasPlayer(function (current) { + return current.hasEnabledSlot(); + }) + ) + return false; + return ( + game.countPlayer(function (current) { + return current.isDamaged(); + }) >= num + ); }, - direct:true, - content(){ - 'step 0' - if(trigger.name=='phaseDraw'){ - player.logSkill('olzhiti'); + direct: true, + content() { + "step 0"; + if (trigger.name == "phaseDraw") { + player.logSkill("olzhiti"); trigger.num++; event.finish(); + } else { + player + .chooseTarget( + get.prompt("olzhiti"), + "废除一名角色的一个随机装备栏", + function (card, player, target) { + return target.hasEnabledSlot(); + } + ) + .set("ai", function (target) { + return ( + -get.attitude(_status.event.player, target) * (target.countCards("e") + 1) + ); + }); } - else{ - player.chooseTarget(get.prompt('olzhiti'),'废除一名角色的一个随机装备栏',function(card,player,target){ - return target.hasEnabledSlot(); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*(target.countCards('e')+1) - }); - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('olzhiti',target); - var list=[]; - for(var i=1;i<6;i++){ - if(target.hasEnabledSlot(i)) list.add((i==3||i==4)?6:i); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("olzhiti", target); + var list = []; + for (var i = 1; i < 6; i++) { + if (target.hasEnabledSlot(i)) list.add(i == 3 || i == 4 ? 6 : i); } - var num=list.randomGet(); - if(num!=6) target.disableEquip(num); - else{ - target.disableEquip(3,4); + var num = list.randomGet(); + if (num != 6) target.disableEquip(num); + else { + target.disableEquip(3, 4); } } }, }, - olzhiti2:{ - mod:{ - maxHandcard(player,num){ - if(player.isDamaged()) return num-game.countPlayer(function(current){ - return current.hasSkill('olzhiti')&¤t.inRange(player); - }) + olzhiti2: { + mod: { + maxHandcard(player, num) { + if (player.isDamaged()) + return ( + num - + game.countPlayer(function (current) { + return current.hasSkill("olzhiti") && current.inRange(player); + }) + ); }, }, }, - olduorui:{ - audio:'drlt_duorui', - trigger:{ - source:'damageSource' + olduorui: { + audio: "drlt_duorui", + trigger: { + source: "damageSource", }, - filter(event,player){ - if(!player.isPhaseUsing()||event.player.isDead()) return false; - for(var i in event.player.disabledSkills){ - if(event.player.disabledSkills[i].includes('olduorui2')) return false; + filter(event, player) { + if (!player.isPhaseUsing() || event.player.isDead()) return false; + for (var i in event.player.disabledSkills) { + if (event.player.disabledSkills[i].includes("olduorui2")) return false; } - var list=[]; - var listm=[]; - var listv=[]; - if(event.player.name1!=undefined) listm=lib.character[event.player.name1][3]; - else listm=lib.character[event.player.name][3]; - if(event.player.name2!=undefined) listv=lib.character[event.player.name2][3]; - listm=listm.concat(listv); - var func=function(skill){ - var info=get.info(skill); - if(!info||info.charlotte) return false; + var list = []; + var listm = []; + var listv = []; + if (event.player.name1 != undefined) listm = lib.character[event.player.name1][3]; + else listm = lib.character[event.player.name][3]; + if (event.player.name2 != undefined) listv = lib.character[event.player.name2][3]; + listm = listm.concat(listv); + var func = function (skill) { + var info = get.info(skill); + if (!info || info.charlotte) return false; return true; }; - for(var i=0;i0; + return list.length > 0; }, - check(event,player){ - if(get.attitude(_status.event.player,event.player)>=0) return false; - if(event.getParent('phaseUse').skipped) return true; - var nd=player.needsToDiscard(); - return player.countCards('h',function(card){ - return player.getUseValue(card,null,true)>0&&(nd?true:get.tag(card,'damage')>0); - })==0; + check(event, player) { + if (get.attitude(_status.event.player, event.player) >= 0) return false; + if (event.getParent("phaseUse").skipped) return true; + var nd = player.needsToDiscard(); + return ( + player.countCards("h", function (card) { + return ( + player.getUseValue(card, null, true) > 0 && + (nd ? true : get.tag(card, "damage") > 0) + ); + }) == 0 + ); }, - logTarget:'player', - content(){ - 'step 0' - var list=[]; - var listm=[]; - var listv=[]; - if(trigger.player.name1!=undefined) listm=lib.character[trigger.player.name1][3]; - else listm=lib.character[trigger.player.name][3]; - if(trigger.player.name2!=undefined) listv=lib.character[trigger.player.name2][3]; - listm=listm.concat(listv); - var func=function(skill){ - var info=get.info(skill); - if(!info||info.charlotte) return false; + logTarget: "player", + content() { + "step 0"; + var list = []; + var listm = []; + var listv = []; + if (trigger.player.name1 != undefined) listm = lib.character[trigger.player.name1][3]; + else listm = lib.character[trigger.player.name][3]; + if (trigger.player.name2 != undefined) listv = lib.character[trigger.player.name2][3]; + listm = listm.concat(listv); + var func = function (skill) { + var info = get.info(skill); + if (!info || info.charlotte) return false; return true; }; - for(var i=0;i{ - if(!get.tag(card,'damage')||!target.hasFriend()) return; - if(player.hasSkillTag('jueqing',null,target)) return 1.7; - let die=[null,1],temp; - game.filterPlayer(i=>{ - temp=i.countMark('new_wuhun'); - if(i===player&&target.hp+target.hujia>1) temp++; - if(temp>=die[1]){ - if(!die[0]) die=[i,temp]; - else{ - let att=get.attitude(player,i); - if(att { + if (!get.tag(card, "damage") || !target.hasFriend()) return; + if (player.hasSkillTag("jueqing", null, target)) return 1.7; + let die = [null, 1], + temp; + game.filterPlayer((i) => { + temp = i.countMark("new_wuhun"); + if (i === player && target.hp + target.hujia > 1) temp++; + if (temp >= die[1]) { + if (!die[0]) die = [i, temp]; + else { + let att = get.attitude(player, i); + if (att < die[1]) die = [i, temp]; } } }); - if(die[0]) return [1,0,1,-6*get.sgnAttitude(player,die[0])/Math.max(1,target.hp)]; - } - } + if (die[0]) + return [ + 1, + 0, + 1, + (-6 * get.sgnAttitude(player, die[0])) / Math.max(1, target.hp), + ]; + }, + }, }, - marktext:'魇', - intro:{ - name:'梦魇', - content:'mark', - onunmark:true, + marktext: "魇", + intro: { + name: "梦魇", + content: "mark", + onunmark: true, }, - subSkill:{ - die:{ - audio:'wuhun2', - trigger:{player:'die'}, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.hasMark('new_wuhun'); + subSkill: { + die: { + audio: "wuhun2", + trigger: { player: "die" }, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.hasMark("new_wuhun"); }); }, - forced:true, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'soil', - content(){ - 'step 0' - var num=0; - for(var i=0;inum){ - num=current.countMark('new_wuhun'); + forced: true, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "soil", + content() { + "step 0"; + var num = 0; + for (var i = 0; i < game.players.length; i++) { + var current = game.players[i]; + if (current != player && current.countMark("new_wuhun") > num) { + num = current.countMark("new_wuhun"); } } - player.chooseTarget(true,'请选择【武魂】的目标','令其进行判定,若判定结果不为【桃】或【桃园结义】,则其死亡',function(card,player,target){ - return target!=player&&target.countMark('new_wuhun')==_status.event.num; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }).set('forceDie',true).set('num',num); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('new_wuhun_die',target); - player.line(target,{color:[255, 255, 0]}); + player + .chooseTarget( + true, + "请选择【武魂】的目标", + "令其进行判定,若判定结果不为【桃】或【桃园结义】,则其死亡", + function (card, player, target) { + return ( + target != player && + target.countMark("new_wuhun") == _status.event.num + ); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }) + .set("forceDie", true) + .set("num", num); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("new_wuhun_die", target); + player.line(target, { color: [255, 255, 0] }); game.delay(2); } - 'step 2' - target.judge(function(card){ - if(['tao','taoyuan'].includes(card.name)) return 10; + "step 2"; + target.judge(function (card) { + if (["tao", "taoyuan"].includes(card.name)) return 10; return -10; - }).judge2=function(result){ - return result.bool==false?true:false; + }).judge2 = function (result) { + return result.bool == false ? true : false; }; - 'step 3' - if(!result.bool) target.die(); + "step 3"; + if (!result.bool) target.die(); }, }, }, }, - "new_guixin":{ - audio:"guixin", - trigger:{ - player:"damageEnd", + new_guixin: { + audio: "guixin", + trigger: { + player: "damageEnd", }, - check (event,player){ - if(player.isTurnedOver()||event.num>1) return true; - var num=game.countPlayer(function(current){ - if(current.countCards('he')&¤t!=player&&get.attitude(player,current)<=0){ + check(event, player) { + if (player.isTurnedOver() || event.num > 1) return true; + var num = game.countPlayer(function (current) { + if ( + current.countCards("he") && + current != player && + get.attitude(player, current) <= 0 + ) { return true; } - if(current.countCards('j')&¤t!=player&&get.attitude(player,current)>0){ + if ( + current.countCards("j") && + current != player && + get.attitude(player, current) > 0 + ) { return true; } }); - return num>=2; + return num >= 2; }, - content (){ - "step 0" - var targets=game.filterPlayer(); + content() { + "step 0"; + var targets = game.filterPlayer(); targets.remove(player); targets.sort(lib.sort.seat); - event.targets=targets; - event.count=trigger.num; - "step 1" - event.num=0; - player.line(targets,'green'); - player.chooseControl('手牌区','装备区','判定区').set('ai',function(){ - if(game.hasPlayer(function(current){ - return current.countCards('j')&¤t!=player&&get.attitude(player,current)>0; - })) return 2; - return Math.floor(Math.random()*3); - }).set('prompt','请选择优先获得的区域'); - "step 2" - event.range={ - 手牌区:['h','e','j'], - 装备区:['e','h','j'], - 判定区:['j','h','e'], - }[result.control||'手牌区']; - "step 3" - if(num 0 + ); + }) + ) + return 2; + return Math.floor(Math.random() * 3); + }) + .set("prompt", "请选择优先获得的区域"); + "step 2"; + event.range = { + 手牌区: ["h", "e", "j"], + 装备区: ["e", "h", "j"], + 判定区: ["j", "h", "e"], + }[result.control || "手牌区"]; + "step 3"; + if (num < event.targets.length) { + var target = event.targets[num]; + var range = event.range; + for (var i = 0; i < range.length; i++) { + var cards = target.getCards(range[i]); + if (cards.length) { + var card = cards.randomGet(); + player.gain(card, target, "giveAuto", "bySelf"); break; } } event.num++; } - "step 4" - if(num(player.hasSkillTag('damageBonus',true,{ - card:card, - target:target - })?2:1)){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - target._new_guixin_eff=true; - let gain=game.countPlayer(function(current){ - if(target==current) return 0; - if(get.attitude(target,current)>0){ - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'new_guixin')&&get.effect(current,cardx,current,current)<0,'j')) return 1.3; + effect: { + target(card, player, target) { + if ( + !target._new_guixin_eff && + get.tag(card, "damage") && + target.hp > + (player.hasSkillTag("damageBonus", true, { + card: card, + target: target, + }) + ? 2 + : 1) + ) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + target._new_guixin_eff = true; + let gain = game.countPlayer(function (current) { + if (target == current) return 0; + if (get.attitude(target, current) > 0) { + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained( + cardx, + target, + current, + "new_guixin" + ) && get.effect(current, cardx, current, current) < 0, + "j" + ) + ) + return 1.3; return 0; } - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'new_guixin')&&get.effect(current,cardx,current,current)>0,'e')) return 1.1; - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'new_guixin'),'h')) return 0.9; + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained( + cardx, + target, + current, + "new_guixin" + ) && get.effect(current, cardx, current, current) > 0, + "e" + ) + ) + return 1.1; + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained(cardx, target, current, "new_guixin"), + "h" + ) + ) + return 0.9; return 0; }); - if(target.isTurnedOver()) gain+=2.3; - else gain-=2.3; + if (target.isTurnedOver()) gain += 2.3; + else gain -= 2.3; delete target._new_guixin_eff; - return [1,Math.max(0,gain)]; + return [1, Math.max(0, gain)]; } - } - } - }, - }, - ol_shenfen:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.countMark('baonu')>=6; - }, - usable:1, - skillAnimation:true, - animationColor:'metal', - content(){ - "step 0" - event.delay=false; - player.removeMark('baonu',6); - event.targets=game.filterPlayer(); - event.targets.remove(player); - event.targets.sort(lib.sort.seat); - player.line(event.targets,'green'); - event.targets2=event.targets.slice(0); - event.targets3=event.targets.slice(0); - "step 1" - if(event.targets2.length){ - event.targets2.shift().damage('nocard'); - event.redo(); - } - "step 2" - if(event.targets.length){ - event.current=event.targets.shift() - if(event.current.countCards('e')) event.delay=true; - event.current.discard(event.current.getCards('e')).delay=false; - } - "step 3" - if(event.delay) game.delay(0.5); - event.delay=false; - if(event.targets.length) event.goto(2); - "step 4" - if(event.targets3.length){ - var target=event.targets3.shift(); - target.chooseToDiscard(4,'h',true).delay=false; - if(target.countCards('h')) event.delay=true; - } - "step 5" - if(event.delay) game.delay(0.5); - event.delay=false; - if(event.targets3.length) event.goto(4); - "step 6" - player.turnOver(); - }, - ai:{ - combo:'baonu', - order:10, - result:{ - player(player){ - return game.countPlayer(function(current){ - if(current!=player){ - return get.sgn(get.damageEffect(current,player,player)); - } - }); - } - } - } - }, - ol_wuqian:{ - audio:2, - enable:'phaseUse', - derivation:'wushuang', - filter(event,player){ - return player.countMark('baonu')>=2&&game.hasPlayer(target=>lib.skill.ol_wuqian.filterTarget(null,player,target)); - }, - filterTarget(card,player,target){ - return target!=player&&!target.hasSkill('ol_wuqian_targeted'); - }, - content(){ - player.removeMark('baonu',2); - player.addTempSkills('wushuang'); - player.popup('无双'); - // game.log(player,'获得了技能','#g【无双】'); - target.addTempSkill('ol_wuqian_targeted'); - }, - ai:{ - order:9, - result:{ - target(player,target){ - if(player.countCards('hs',card=>{ - if(!player.getCardUsable({name:card.name})) return false; - if(!player.canUse(card,target)) return false; - var eff1=get.effect(target,card,player,player); - _status.baonuCheck=true; - var eff2=get.effect(target,card,player,player); - delete _status.baonuCheck; - return eff2>Math.max(0,eff1); - })) return -1; - return 0; }, }, }, - global:'ol_wuqian_ai', - subSkill:{ - targeted:{ - charlotte:true, - ai:{unequip2:true}, + }, + ol_shenfen: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return player.countMark("baonu") >= 6; + }, + usable: 1, + skillAnimation: true, + animationColor: "metal", + content() { + "step 0"; + event.delay = false; + player.removeMark("baonu", 6); + event.targets = game.filterPlayer(); + event.targets.remove(player); + event.targets.sort(lib.sort.seat); + player.line(event.targets, "green"); + event.targets2 = event.targets.slice(0); + event.targets3 = event.targets.slice(0); + "step 1"; + if (event.targets2.length) { + event.targets2.shift().damage("nocard"); + event.redo(); + } + "step 2"; + if (event.targets.length) { + event.current = event.targets.shift(); + if (event.current.countCards("e")) event.delay = true; + event.current.discard(event.current.getCards("e")).delay = false; + } + "step 3"; + if (event.delay) game.delay(0.5); + event.delay = false; + if (event.targets.length) event.goto(2); + "step 4"; + if (event.targets3.length) { + var target = event.targets3.shift(); + target.chooseToDiscard(4, "h", true).delay = false; + if (target.countCards("h")) event.delay = true; + } + "step 5"; + if (event.delay) game.delay(0.5); + event.delay = false; + if (event.targets3.length) event.goto(4); + "step 6"; + player.turnOver(); + }, + ai: { + combo: "baonu", + order: 10, + result: { + player(player) { + return game.countPlayer(function (current) { + if (current != player) { + return get.sgn(get.damageEffect(current, player, player)); + } + }); + }, }, - ai:{ - ai:{ - unequip2:true, - skillTagFilter(player){ - if(!_status.baonuCheck) return false; + }, + }, + ol_wuqian: { + audio: 2, + enable: "phaseUse", + derivation: "wushuang", + filter(event, player) { + return ( + player.countMark("baonu") >= 2 && + game.hasPlayer((target) => lib.skill.ol_wuqian.filterTarget(null, player, target)) + ); + }, + filterTarget(card, player, target) { + return target != player && !target.hasSkill("ol_wuqian_targeted"); + }, + content() { + player.removeMark("baonu", 2); + player.addTempSkills("wushuang"); + player.popup("无双"); + // game.log(player,'获得了技能','#g【无双】'); + target.addTempSkill("ol_wuqian_targeted"); + }, + ai: { + order: 9, + result: { + target(player, target) { + if ( + player.countCards("hs", (card) => { + if (!player.getCardUsable({ name: card.name })) return false; + if (!player.canUse(card, target)) return false; + var eff1 = get.effect(target, card, player, player); + _status.baonuCheck = true; + var eff2 = get.effect(target, card, player, player); + delete _status.baonuCheck; + return eff2 > Math.max(0, eff1); + }) + ) + return -1; + return 0; + }, + }, + combo: "baonu", + }, + global: "ol_wuqian_ai", + subSkill: { + targeted: { + charlotte: true, + ai: { unequip2: true }, + }, + ai: { + ai: { + unequip2: true, + skillTagFilter(player) { + if (!_status.baonuCheck) return false; }, }, }, }, }, - wumou:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter(event){ - return get.type(event.card)=='trick'; + wumou: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter(event) { + return get.type(event.card) == "trick"; }, - content(){ - 'step 0' - if(player.hasMark('baonu')){ - player.chooseControlList([ - '移去一枚【暴怒】标记', - '失去1点体力' - ],true).set('ai',function(event,player){ - if(get.effect(player,{name:'losehp'},player,player)>=0) return 1; - if(player.storage.baonu>6) return 0; - if(player.hp+player.num('h','tao')>3) return 1; - return 0; - }); - } - else{ + content() { + "step 0"; + if (player.hasMark("baonu")) { + player + .chooseControlList(["移去一枚【暴怒】标记", "失去1点体力"], true) + .set("ai", function (event, player) { + if (get.effect(player, { name: "losehp" }, player, player) >= 0) return 1; + if (player.storage.baonu > 6) return 0; + if (player.hp + player.num("h", "tao") > 3) return 1; + return 0; + }); + } else { player.loseHp(); event.finish(); } - 'step 1' - if(result.index==0){ - player.removeMark('baonu',1); - } - else{ + "step 1"; + if (result.index == 0) { + player.removeMark("baonu", 1); + } else { player.loseHp(); } }, - ai:{ - effect:{ - player_use(card,player){ - if (get.type(card)=='trick'&&get.value(card)<6){ - return [0,-2]; + ai: { + effect: { + player_use(card, player) { + if (get.type(card) == "trick" && get.value(card) < 6) { + return [0, -2]; } - } - } - } - }, - qinyin:{ - audio:2, - trigger:{player:'phaseDiscardEnd'}, - direct:true, - filter(event,player){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event) cards.addArray(evt.cards2); - }); - return cards.length>1; + }, + }, + neg: true, }, - content(){ - "step 0" - event.forceDie=true; - if(typeof event.count!='number'){ + }, + qinyin: { + audio: 2, + trigger: { player: "phaseDiscardEnd" }, + direct: true, + filter(event, player) { + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) + cards.addArray(evt.cards2); + }); + return cards.length > 1; + }, + content() { + "step 0"; + event.forceDie = true; + if (typeof event.count != "number") { // event.count=trigger.cards.length-1; - event.count=1; + event.count = 1; } - var recover=0,lose=0,players=game.filterPlayer(); - for(var i=0;i0){ - if(players[i].hp<2){ + var recover = 0, + lose = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].hp < players[i].maxHp) { + if (get.attitude(player, players[i]) > 0) { + if (players[i].hp < 2) { lose--; - recover+=0.5; + recover += 0.5; } lose--; recover++; - } - else if(get.attitude(player,players[i])<0){ - if(players[i].hp<2){ + } else if (get.attitude(player, players[i]) < 0) { + if (players[i].hp < 2) { lose++; - recover-=0.5; + recover -= 0.5; } lose++; recover--; } - } - else{ - if(get.attitude(player,players[i])>0){ + } else { + if (get.attitude(player, players[i]) > 0) { lose--; - } - else if(get.attitude(player,players[i])<0){ + } else if (get.attitude(player, players[i]) < 0) { lose++; } } } - var prompt=get.prompt('qinyin')+'(剩余'+get.cnNumber(event.count)+'次)'; - player.chooseControl('失去体力','回复体力','cancel2', - ui.create.dialog(get.prompt('qinyin'),'hidden')).ai=function(){ - if(lose>recover&&lose>0) return 0; - if(lose0) return 1; + var prompt = get.prompt("qinyin") + "(剩余" + get.cnNumber(event.count) + "次)"; + player.chooseControl( + "失去体力", + "回复体力", + "cancel2", + ui.create.dialog(get.prompt("qinyin"), "hidden") + ).ai = function () { + if (lose > recover && lose > 0) return 0; + if (lose < recover && recover > 0) return 1; return 2; - } - "step 1" - if(result.control=='cancel2'){ + }; + "step 1"; + if (result.control == "cancel2") { event.finish(); + } else { + player.logSkill("qinyin"); + event.bool = result.control == "回复体力"; + event.num = 0; + event.players = game.filterPlayer(); } - else{ - player.logSkill('qinyin'); - event.bool=(result.control=='回复体力'); - event.num=0; - event.players=game.filterPlayer(); - } - "step 2" - if(event.num1){ + "step 3"; + if (event.count > 1) { event.count--; event.goto(0); } }, - ai:{ - expose:0.1, - threaten:2 - } - }, - lianpo:{ - audio:2, - trigger:{global:'phaseAfter'}, - frequent:true, - filter(event,player){ - return player.getStat('kill')>0; + ai: { + expose: 0.1, + threaten: 2, }, - content(){ + }, + lianpo: { + audio: 2, + trigger: { global: "phaseAfter" }, + frequent: true, + filter(event, player) { + return player.getStat("kill") > 0; + }, + content() { player.insertPhase(); - } + }, }, - baonu:{ - audio:2, - marktext:'暴', - unique:true, - trigger:{ - source:'damageSource', - player:['damageEnd','enterGame'], - global:'phaseBefore', + baonu: { + audio: 2, + marktext: "暴", + unique: true, + trigger: { + source: "damageSource", + player: ["damageEnd", "enterGame"], + global: "phaseBefore", }, - forced:true, - filter(event){ - return (event.name!='damage'&&(event.name!='phase'||game.phaseNumber==0))||event.num>0; + forced: true, + filter(event) { + return ( + (event.name != "damage" && (event.name != "phase" || game.phaseNumber == 0)) || + event.num > 0 + ); }, - content(){ - player.addMark('baonu',trigger.name=='damage'?trigger.num:2); + content() { + player.addMark("baonu", trigger.name == "damage" ? trigger.num : 2); }, - intro:{ - name:'暴怒', - content:'mark' + intro: { + name: "暴怒", + content: "mark", + }, + ai: { + combo: "ol_shenfen", + maixie: true, + maixie_hp: true, }, - ai:{ - combo:'ol_shenfen', - maixie:true, - maixie_hp:true - } }, - shenfen:{ - audio:2, - unique:true, - enable:'phaseUse', - filter(event,player){ - return player.storage.baonu>=6; + shenfen: { + audio: 2, + unique: true, + enable: "phaseUse", + filter(event, player) { + return player.storage.baonu >= 6; }, - skillAnimation:true, - animationColor:'metal', - limited:true, - content(){ - "step 0" - player.awakenSkill('shenfen'); - player.storage.baonu-=6; - player.markSkill('baonu'); - player.syncStorage('baonu'); - event.targets=game.filterPlayer(); + skillAnimation: true, + animationColor: "metal", + limited: true, + content() { + "step 0"; + player.awakenSkill("shenfen"); + player.storage.baonu -= 6; + player.markSkill("baonu"); + player.syncStorage("baonu"); + event.targets = game.filterPlayer(); event.targets.remove(player); event.targets.sort(lib.sort.seat); - event.targets2=event.targets.slice(0); - player.line(event.targets,'green'); - "step 1" - if(event.targets.length){ + event.targets2 = event.targets.slice(0); + player.line(event.targets, "green"); + "step 1"; + if (event.targets.length) { event.targets.shift().damage(); event.redo(); } - "step 2" - if(event.targets2.length){ - var cur=event.targets2.shift(); - if(cur&&cur.countCards('he')){ - cur.chooseToDiscard('he',true,4); + "step 2"; + if (event.targets2.length) { + var cur = event.targets2.shift(); + if (cur && cur.countCards("he")) { + cur.chooseToDiscard("he", true, 4); } event.redo(); } }, - ai:{ - order:10, - result:{ - player(player){ - return game.countPlayer(function(current){ - if(current!=player){ - return get.sgn(get.damageEffect(current,player,player)); + ai: { + order: 10, + result: { + player(player) { + return game.countPlayer(function (current) { + if (current != player) { + return get.sgn(get.damageEffect(current, player, player)); } }); - } - } - } + }, + }, + combo: "baonu", + }, }, - wuqian:{ - audio:2, - enable:'phaseUse', - derivation:'wushuang', - filter(event,player){ - return player.storage.baonu>=2&&!player.hasSkill('wushuang'); + wuqian: { + audio: 2, + enable: "phaseUse", + derivation: "wushuang", + filter(event, player) { + return player.storage.baonu >= 2 && !player.hasSkill("wushuang"); }, - content(){ - player.storage.baonu-=2; - player.addTempSkill('wushuang'); + content() { + player.storage.baonu -= 2; + player.addTempSkill("wushuang"); }, - ai:{ - order:5, - result:{ - player(player){ - if(!player.storage.shenfen) return 0; - var cards=player.getCards('h','sha'); - if(cards.length){ - if(game.hasPlayer(function(current){ - return (player.canUse('sha',current)&& - get.effect(current,cards[0],player,player)>0&¤t.hasShan()); - })){ + ai: { + order: 5, + result: { + player(player) { + if (!player.storage.shenfen) return 0; + var cards = player.getCards("h", "sha"); + if (cards.length) { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + get.effect(current, cards[0], player, player) > 0 && + current.hasShan() + ); + }) + ) { return 1; } } return 0; - } - } - } + }, + }, + combo: "baonu", + }, }, - renjie:{ - audio:'renjie2', - trigger:{player:'damageEnd'}, - forced:true, - group:'renjie2', - notemp:true, + renjie: { + audio: "renjie2", + trigger: { player: "damageEnd" }, + forced: true, + group: "renjie2", + notemp: true, //mark:true, - filter(event){ - return event.num>0; + filter(event) { + return event.num > 0; }, - content(){ - player.addMark('renjie',trigger.num); + content() { + player.addMark("renjie", trigger.num); }, - intro:{ - name2:'忍', - content:'mark' + intro: { + name2: "忍", + content: "mark", }, - ai:{ - maixie:true, - maixie_hp:true, - combo:'sbaiyin', - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(get.tag(card,'damage')){ - if(target.hp==target.maxHp){ - if(!target.hasSkill('jilue')){ - return [0,1]; + ai: { + maixie: true, + maixie_hp: true, + combo: "sbaiyin", + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (get.tag(card, "damage")) { + if (target.hp == target.maxHp) { + if (!target.hasSkill("jilue")) { + return [0, 1]; } - return [0.7,1]; + return [0.7, 1]; } return 0.7; } - } - } - } - }, - renjie2:{ - audio:2, - mod:{ - aiOrder:(player,card,num)=>{ - if(num<=0||typeof card!=='object'||!player.isPhaseUsing()) return num; - if(player.hasSkill('sbaiyin')){ - if(player.countMark('renjie')<4&&player.getUseValue(card)0; - }, - content(){ - player.addMark('renjie',trigger.getl(player).cards2.length); + }, + }, }, }, - sbaiyin:{ - skillAnimation:'epic', - animationColor:'thunder', - juexingji:true, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - audio:2, - filter(event,player){ - return player.countMark('renjie')>=4; + renjie2: { + audio: 2, + mod: { + aiOrder: (player, card, num) => { + if (num <= 0 || typeof card !== "object" || !player.isPhaseUsing()) return num; + if (player.hasSkill("sbaiyin")) { + if ( + player.countMark("renjie") < 4 && + player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4) + ) + return 0; + } else if (player.hasSkill("jilue")) { + if ( + player.countMark("renjie") < 3 && + player.getUseValue(card) < Math.min(1.8, 0.18 * player.hp * player.hp) + ) + return 0; + } + }, }, - content(){ - player.awakenSkill('sbaiyin'); + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", + }, + forced: true, + filter(event, player) { + if (event.type != "discard" || event.getlx === false) return false; + var evt = event.getParent("phaseDiscard"), + evt2 = event.getl(player); + return ( + evt && + evt2 && + evt.name == "phaseDiscard" && + evt.player == player && + evt2.cards2 && + evt2.cards2.length > 0 + ); + }, + content() { + player.addMark("renjie", trigger.getl(player).cards2.length); + }, + }, + sbaiyin: { + skillAnimation: "epic", + animationColor: "thunder", + juexingji: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + audio: 2, + filter(event, player) { + return player.countMark("renjie") >= 4; + }, + content() { + player.awakenSkill("sbaiyin"); player.loseMaxHp(); - player.addSkills('jilue'); + player.addSkills("jilue"); }, - derivation:['jilue','reguicai','fangzhu','rejizhi','rezhiheng','rewansha'], - }, - jilue:{ - unique:true, - group:['jilue_guicai','jilue_fangzhu','jilue_wansha','jilue_zhiheng','jilue_jizhi'], - ai:{ - combo:'renjie' - } - }, - jilue_guicai:{ - audio:1, - trigger:{global:'judge'}, - direct:true, - filter(event,player){ - return player.countCards('hes')>0&&player.hasMark('renjie'); + derivation: ["jilue", "reguicai", "fangzhu", "rejizhi", "rezhiheng", "rewansha"], + ai: { + combo: "renjie", }, - content(){ - "step 0" - player.chooseCard('是否弃置一枚“忍”,并发动〖鬼才〗?','hes',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; + }, + jilue: { + unique: true, + group: ["jilue_guicai", "jilue_fangzhu", "jilue_wansha", "jilue_zhiheng", "jilue_jizhi"], + ai: { + combo: "renjie", + }, + }, + jilue_guicai: { + audio: 1, + trigger: { global: "judge" }, + direct: true, + filter(event, player) { + return player.countCards("hes") > 0 && player.hasMark("renjie"); + }, + content() { + "step 0"; + player.chooseCard("是否弃置一枚“忍”,并发动〖鬼才〗?", "hes", function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; return true; - }).ai=function(card){ - var trigger=_status.event.parent._trigger; - var player=_status.event.player; - var result=trigger.judge(card)-trigger.judge(trigger.player.judging[0]); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result-get.value(card)/2; - } - else{ - return -result-get.value(card)/2; + }).ai = function (card) { + var trigger = _status.event.parent._trigger; + var player = _status.event.player; + var result = trigger.judge(card) - trigger.judge(trigger.player.judging[0]); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result - get.value(card) / 2; + } else { + return -result - get.value(card) / 2; } }; - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','jilue_guicai','noOrdering'); - } - else{ + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "jilue_guicai", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.removeMark('renjie',1); - if(trigger.player.judging[0].clone){ + "step 2"; + if (result.bool) { + player.removeMark("renjie", 1); + if (trigger.player.judging[0].clone) { trigger.player.judging[0].clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } - }, - jilue_fangzhu:{ - audio:1, - trigger:{player:'damageEnd'}, - direct:true, - //priority:-1, - filter(event,player){ - return player.hasMark('renjie'); + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, }, - content(){ - "step 0" - player.chooseTarget('是否弃置一枚“忍”,并发动【放逐】?',function(card,player,target){ - return player!=target - }).set('ai',target=>{ - if(target.hasSkillTag('noturn')) return 0; - var player=_status.event.player; - var current=_status.currentPhase; - var dis=current?get.distance(current,target,'absolute'):1; - var draw=player.getDamagedHp(); - var att=get.attitude(player,target); - if(att==0) return target.hasJudge('lebu')?Math.random()/3:Math.sqrt(get.threaten(target))/5+Math.random()/2; - if(att>0){ - if(target.isTurnedOver()) return att+draw; - if(draw<4) return -1; - if(current&&target.getSeatNum()>current.getSeatNum()) return att+draw/3; - return 10*Math.sqrt(Math.max(0.01,get.threaten(target)))/(3.5-draw)+dis/(2*game.countPlayer()); - } - else{ - if(target.isTurnedOver()) return att-draw; - if(draw>=5) return -1; - if(current&&target.getSeatNum()<=current.getSeatNum()) return -att+draw/3; - return (4.25-draw)*10*Math.sqrt(Math.max(0.01,get.threaten(target)))+2*game.countPlayer()/dis; - } - }); - "step 1" - if(result.bool){ - player.removeMark('renjie',1); - player.logSkill('jilue_fangzhu',result.targets); - result.targets[0].draw(player.maxHp-player.hp); + }, + jilue_fangzhu: { + audio: 1, + trigger: { player: "damageEnd" }, + direct: true, + //priority:-1, + filter(event, player) { + return player.hasMark("renjie"); + }, + content() { + "step 0"; + player + .chooseTarget("是否弃置一枚“忍”,并发动【放逐】?", function (card, player, target) { + return player != target; + }) + .set("ai", (target) => { + if (target.hasSkillTag("noturn")) return 0; + var player = _status.event.player; + var current = _status.currentPhase; + var dis = current ? get.distance(current, target, "absolute") : 1; + var draw = player.getDamagedHp(); + var att = get.attitude(player, target); + if (att == 0) + return target.hasJudge("lebu") + ? Math.random() / 3 + : Math.sqrt(get.threaten(target)) / 5 + Math.random() / 2; + if (att > 0) { + if (target.isTurnedOver()) return att + draw; + if (draw < 4) return -1; + if (current && target.getSeatNum() > current.getSeatNum()) + return att + draw / 3; + return ( + (10 * Math.sqrt(Math.max(0.01, get.threaten(target)))) / (3.5 - draw) + + dis / (2 * game.countPlayer()) + ); + } else { + if (target.isTurnedOver()) return att - draw; + if (draw >= 5) return -1; + if (current && target.getSeatNum() <= current.getSeatNum()) + return -att + draw / 3; + return ( + (4.25 - draw) * 10 * Math.sqrt(Math.max(0.01, get.threaten(target))) + + (2 * game.countPlayer()) / dis + ); + } + }); + "step 1"; + if (result.bool) { + player.removeMark("renjie", 1); + player.logSkill("jilue_fangzhu", result.targets); + result.targets[0].draw(player.maxHp - player.hp); result.targets[0].turnOver(); } }, }, - jilue_wansha:{ - audio:'wansha', - audioname:['shen_simayi'], - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.hasMark('renjie'); + jilue_wansha: { + audio: "wansha", + audioname: ["shen_simayi"], + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.hasMark("renjie"); }, - content(){ - player.removeMark('renjie',1); - player.addTempSkill('rewansha'); + content() { + player.removeMark("renjie", 1); + player.addTempSkill("rewansha"); }, - ai:{ - order:()=>{ - let player=_status.event.player; - if(game.hasPlayer(current=>{ - if(player===current||current.hp>1||get.attitude(player,current)>=0) return false; - return player.inRange(current)&&player.countCards('hs','sha')&&player.getCardUsable('sha')|| - player.countCards('hs',card=>get.name(card)!=='sha'&&get.tag(card,'damage'))>1; - })) return 9.2; + ai: { + order: () => { + let player = _status.event.player; + if ( + game.hasPlayer((current) => { + if ( + player === current || + current.hp > 1 || + get.attitude(player, current) >= 0 + ) + return false; + return ( + (player.inRange(current) && + player.countCards("hs", "sha") && + player.getCardUsable("sha")) || + player.countCards( + "hs", + (card) => get.name(card) !== "sha" && get.tag(card, "damage") + ) > 1 + ); + }) + ) + return 9.2; return 0; }, - result:{ - player:1 + result: { + player: 1, }, - effect:{ - player(card,player,target){ - if(target&&player.hasSkill('rewansha')&&target.hp<=1&&get.tag(card,'damage')) return [1,0,1.5,-1.5]; - } - } - } + effect: { + player(card, player, target) { + if ( + target && + player.hasSkill("rewansha") && + target.hp <= 1 && + get.tag(card, "damage") + ) + return [1, 0, 1.5, -1.5]; + }, + }, + }, }, - jilue_zhiheng:{ - audio:1, - mod:{ - aiOrder(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)= 8; + }) + ) { + return 8 - get.value(card); } + return 6 - get.value(card); }, - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.hasMark('renjie'); - }, - position:'he', - filterCard:lib.filter.cardDiscardable, - discard:false, - lose:false, - delay:false, - selectCard:[1,Infinity], - prompt:'弃置一枚“忍”,然后弃置任意张牌并摸等量的牌。若弃置了所有的手牌,则可以多摸一张牌。', - check(card){ - var player=_status.event.player; - if(get.position(card)=='h'&&!player.countCards('h',function(card){ - return get.value(card)>=8; - })){ - return 8-get.value(card); - } - return 6-get.value(card) - }, - content(){ - 'step 0' - player.removeMark('renjie',1); + content() { + "step 0"; + player.removeMark("renjie", 1); player.discard(cards); - event.num=1; - var hs=player.getCards('h'); - if(!hs.length) event.num=0; - for(var i=0;iget.value(i)>Math.max(6,9-player.hp),'he')) return 1; + ai: { + order(item, player) { + if (player.hasCard((i) => get.value(i) > Math.max(6, 9 - player.hp), "he")) return 1; return 10; }, - result:{ - player(player){ - var num=0; - var cards=player.getCards('he'); - for(var i=0;i2) return 1; - if(cards.length==2&&player.storage.jilue>1); + if (cards.length > 2) return 1; + if (cards.length == 2 && player.storage.jilue > 1); return 0; - } + }, }, - nokeep:true, - skillTagFilter(player,tag,arg){ - if(tag==='nokeep') return player.isPhaseUsing()&&!player.getStat().skill.jilue_zhiheng&&player.hasCard((card)=>get.name(card)!=='tao','h'); + nokeep: true, + skillTagFilter(player, tag, arg) { + if (tag === "nokeep") + return ( + player.isPhaseUsing() && + !player.getStat().skill.jilue_zhiheng && + player.hasCard((card) => get.name(card) !== "tao", "h") + ); }, }, }, - jilue_jizhi:{ - audio:1, - trigger:{player:'useCard'}, - filter(event,player){ - return (get.type(event.card,'trick')=='trick'&&event.card.isCard&&player.hasMark('renjie')); + jilue_jizhi: { + audio: 1, + trigger: { player: "useCard" }, + filter(event, player) { + return ( + get.type(event.card, "trick") == "trick" && + event.card.isCard && + player.hasMark("renjie") + ); }, - content(){ - 'step 0' - player.removeMark('renjie',1); + content() { + "step 0"; + player.removeMark("renjie", 1); player.draw(); - 'step 1' - event.card=result[0]; - if(get.type(event.card)=='basic'){ - player.chooseBool('是否弃置'+get.translation(event.card)+'并令本回合手牌上限+1?').set('ai',function(evt,player){ - return _status.currentPhase==player&&player.needsToDiscard(-3)&&_status.event.value<6; - }).set('value',get.value(event.card,player)); + "step 1"; + event.card = result[0]; + if (get.type(event.card) == "basic") { + player + .chooseBool("是否弃置" + get.translation(event.card) + "并令本回合手牌上限+1?") + .set("ai", function (evt, player) { + return ( + _status.currentPhase == player && + player.needsToDiscard(-3) && + _status.event.value < 6 + ); + }) + .set("value", get.value(event.card, player)); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.discard(event.card); - player.addTempSkill('jilue_jizhi_clear'); - player.addMark('jilue_jizhi_clear',1,false); + player.addTempSkill("jilue_jizhi_clear"); + player.addMark("jilue_jizhi_clear", 1, false); } }, - subSkill:{ - clear:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('jilue_jizhi_clear'); + subSkill: { + clear: { + charlotte: true, + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("jilue_jizhi_clear"); }, }, - intro:{content:'手牌上限+#'}, + intro: { content: "手牌上限+#" }, }, }, }, - wushen:{ - mod:{ - cardname(card,player,name){ - if(get.suit(card)=='heart') return 'sha'; + wushen: { + mod: { + cardname(card, player, name) { + if (get.suit(card) == "heart") return "sha"; }, - cardnature(card,player){ - if(get.suit(card)=='heart') return false; + cardnature(card, player) { + if (get.suit(card) == "heart") return false; }, - targetInRange(card){ - if(card.name === 'sha'){ + targetInRange(card) { + if (card.name === "sha") { const suit = get.suit(card); - if (suit === 'heart' || suit === 'unsure') return true; + if (suit === "heart" || suit === "unsure") return true; } }, - cardUsable(card){ - if(card.name === 'sha'){ + cardUsable(card) { + if (card.name === "sha") { const suit = get.suit(card); - if (suit === 'heart' || suit === 'unsure') return Infinity; + if (suit === "heart" || suit === "unsure") return Infinity; } - } + }, }, - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'&&get.suit(event.card)=='heart'; + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return event.card.name == "sha" && get.suit(event.card) == "heart"; }, - content(){ + content() { trigger.directHit.addArray(game.players); - if(trigger.addCount!==false){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + if (trigger.addCount !== false) { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } } }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.6 - } + ai: { + effect: { + target(card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.6; + }, }, - directHit_ai:true, - skillTagFilter(player,tag,arg){ - return arg.card.name=='sha'&&get.suit(arg.card)=='heart'; + directHit_ai: true, + skillTagFilter(player, tag, arg) { + return arg.card.name == "sha" && get.suit(arg.card) == "heart"; }, - } + }, }, - wuhun:{ - audio:'wuhun2', - trigger:{player:'die'}, - filter(event){ - return event.source&&event.source.isIn(); + wuhun: { + audio: "wuhun2", + trigger: { player: "die" }, + filter(event) { + return event.source && event.source.isIn(); }, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'soil', - logTarget:'source', - content(){ - var num=trigger.source.getHp(); - if(num>0) trigger.source.loseHp(num); + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "soil", + logTarget: "source", + content() { + var num = trigger.source.getHp(); + if (num > 0) trigger.source.loseHp(num); }, - ai:{ - threaten(player,target){ - if(target.hp==1){ - if(player.getHp()<=0) return 100; + ai: { + threaten(player, target) { + if (target.hp == 1) { + if (player.getHp() <= 0) return 100; return 0.2; } return 0.8; }, - effect:{ - target(card,player,target,current){ - if(player.getHp()<=0) return; - if(!target.hasFriend()) return; - if(target.hp<=1&&get.tag(card,'damage')) return [1,0,0,-2]; + effect: { + target(card, player, target, current) { + if (player.getHp() <= 0) return; + if (!target.hasFriend()) return; + if (target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 0, -2]; }, }, }, }, - guixin:{ - audio:2, - trigger:{player:'damageEnd'}, - check(event,player){ - if(player.isTurnedOver()||event.num>1) return true; - var num=game.countPlayer(function(current){ - if(current.countCards('he')&¤t!=player&&get.attitude(player,current)<=0){ + guixin: { + audio: 2, + trigger: { player: "damageEnd" }, + check(event, player) { + if (player.isTurnedOver() || event.num > 1) return true; + var num = game.countPlayer(function (current) { + if ( + current.countCards("he") && + current != player && + get.attitude(player, current) <= 0 + ) { return true; } - if(current.countCards('j')&¤t!=player&&get.attitude(player,current)>0){ + if ( + current.countCards("j") && + current != player && + get.attitude(player, current) > 0 + ) { return true; } }); - return num>=2; + return num >= 2; }, - content(){ - 'step 0' - event.count=trigger.num; - 'step 1' - var targets=game.filterPlayer(current=>current!=player).sortBySeat(); + content() { + "step 0"; + event.count = trigger.num; + "step 1"; + var targets = game.filterPlayer((current) => current != player).sortBySeat(); player.line(targets); - player.gainMultiple(targets,'hej'); - 'step 2' + player.gainMultiple(targets, "hej"); + "step 2"; player.turnOver(); - 'step 3' + "step 3"; event.count--; - if(event.count&&player.hasSkill('guixin')){ - player.chooseBool(get.prompt2('guixin')); - } - else event.finish(); - 'step 4' - if(event.count&&result.bool) event.goto(1); + if (event.count && player.hasSkill("guixin")) { + player.chooseBool(get.prompt2("guixin")); + } else event.finish(); + "step 4"; + if (event.count && result.bool) event.goto(1); }, - ai:{ - maixie:true, - maixie_hp:true, - threaten(player,target){ - if(target.hp==1) return 2.5; + ai: { + maixie: true, + maixie_hp: true, + threaten(player, target) { + if (target.hp == 1) return 2.5; return 0.5; }, - effect:{ - target(card,player,target){ - if(!target._guixin_eff&&get.tag(card,'damage')&&target.hp>(player.hasSkillTag('damageBonus',true,{ - card:card, - target:target - })?2:1)){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - target._guixin_eff=true; - let gain=game.countPlayer(function(current){ - if(target==current) return 0; - if(get.attitude(target,current)>0){ - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'guixin')&&get.effect(current,cardx,current,current)<0,'ej')) return 1.3; + effect: { + target(card, player, target) { + if ( + !target._guixin_eff && + get.tag(card, "damage") && + target.hp > + (player.hasSkillTag("damageBonus", true, { + card: card, + target: target, + }) + ? 2 + : 1) + ) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + target._guixin_eff = true; + let gain = game.countPlayer(function (current) { + if (target == current) return 0; + if (get.attitude(target, current) > 0) { + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained( + cardx, + target, + current, + "guixin" + ) && get.effect(current, cardx, current, current) < 0, + "ej" + ) + ) + return 1.3; return 0; } - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'guixin')&&get.effect(current,cardx,current,current)>0,'ej')) return 1.1; - if(current.hasCard((cardx)=>lib.filter.canBeGained(cardx,target,current,'guixin'),'h')) return 0.9; + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained(cardx, target, current, "guixin") && + get.effect(current, cardx, current, current) > 0, + "ej" + ) + ) + return 1.1; + if ( + current.hasCard( + (cardx) => + lib.filter.canBeGained(cardx, target, current, "guixin"), + "h" + ) + ) + return 0.9; return 0; }); - if(target.isTurnedOver()) gain+=2.3; - else gain-=2.3; + if (target.isTurnedOver()) gain += 2.3; + else gain -= 2.3; delete target._guixin_eff; - return [1,Math.max(0,gain)]; + return [1, Math.max(0, gain)]; } - } - } - } + }, + }, + }, }, - qixing:{ - audio:2, - unique:true, - trigger:{ - global:'phaseBefore', - player:'enterGame', + qixing: { + audio: 2, + unique: true, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content(){ - "step 0" - player.addToExpansion(get.cards(7),'draw').gaintag.add('qixing'); - "step 1" - var cards=player.getExpansions('qixing'); - if(!cards.length||!player.countCards('h')){ + content() { + "step 0"; + player.addToExpansion(get.cards(7), "draw").gaintag.add("qixing"); + "step 1"; + var cards = player.getExpansions("qixing"); + if (!cards.length || !player.countCards("h")) { event.finish(); return; } - var next=player.chooseToMove('七星:是否交换“星”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的星',cards], - ['手牌区',player.getCards('h')], + var next = player.chooseToMove("七星:是否交换“星”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的星", cards], + ["手牌区", player.getCards("h")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return get.useful(a)-get.useful(b); - }),cards2=cards.splice(0,player.getExpansions('qixing').length); - return [cards2,cards]; + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return get.useful(a) - get.useful(b); + }), + cards2 = cards.splice(0, player.getExpansions("qixing").length); + return [cards2, cards]; }); - "step 2" - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('qixing')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.addToExpansion(pushs,player,'giveAuto').gaintag.add('qixing'); + "step 2"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("qixing")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.addToExpansion(pushs, player, "giveAuto").gaintag.add("qixing"); //game.log(player,'将',pushs,'作为“星”置于武将牌上'); - player.gain(gains,'draw'); + player.gain(gains, "draw"); } }, - intro:{ - markcount:'expansion', - mark(dialog,content,player){ - var content=player.getExpansions('qixing'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + intro: { + markcount: "expansion", + mark(dialog, content, player) { + var content = player.getExpansions("qixing"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { dialog.addAuto(content); - } - else{ - return '共有'+get.cnNumber(content.length)+'张星'; + } else { + return "共有" + get.cnNumber(content.length) + "张星"; } } }, - content(content,player){ - var content=player.getExpansions('qixing'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + content(content, player) { + var content = player.getExpansions("qixing"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { return get.translation(content); } - return '共有'+get.cnNumber(content.length)+'张星'; + return "共有" + get.cnNumber(content.length) + "张星"; } - } + }, }, - group:['qixing2'], - ai:{combo:'dawu'}, + group: ["qixing2"], + ai: { combo: "dawu" }, }, - qixing2:{ - trigger:{player:'phaseDrawAfter'}, - direct:true, - filter(event,player){ - return player.getExpansions('qixing').length>0&&player.countCards('h')>0; + qixing2: { + trigger: { player: "phaseDrawAfter" }, + direct: true, + filter(event, player) { + return player.getExpansions("qixing").length > 0 && player.countCards("h") > 0; }, - content(){ - "step 0" - var cards=player.getExpansions('qixing'); - if(!cards.length||!player.countCards('h')){ + content() { + "step 0"; + var cards = player.getExpansions("qixing"); + if (!cards.length || !player.countCards("h")) { event.finish(); return; } - var next=player.chooseToMove('七星:是否交换“星”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的星',cards], - ['手牌区',player.getCards('h')], + var next = player.chooseToMove("七星:是否交换“星”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的星", cards], + ["手牌区", player.getCards("h")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return get.value(a)-get.value(b); - }),cards2=cards.splice(0,player.getExpansions('qixing').length); - return [cards2,cards]; + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return get.value(a) - get.value(b); + }), + cards2 = cards.splice(0, player.getExpansions("qixing").length); + return [cards2, cards]; }); - "step 1" - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('qixing')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.logSkill('qixing2'); - player.addToExpansion(pushs,player,'giveAuto').gaintag.add('qixing'); - game.log(player,'将',pushs,'作为“星”置于武将牌上'); - player.gain(gains,'draw'); + "step 1"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("qixing")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.logSkill("qixing2"); + player.addToExpansion(pushs, player, "giveAuto").gaintag.add("qixing"); + game.log(player, "将", pushs, "作为“星”置于武将牌上"); + player.gain(gains, "draw"); } }, }, - dawu:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter(event,player){ - return player.getExpansions('qixing').length; + dawu: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter(event, player) { + return player.getExpansions("qixing").length; }, - audio:2, - content(){ - "step 0" - var num=Math.min(game.countPlayer(),player.getExpansions('qixing').length); - player.chooseTarget(get.prompt('dawu'),'令至多'+get.cnNumber(num)+'名角色获得“大雾”标记', - [1,num]).set('ai',function(target){ - if(target.isMin()) return 0; - if(target.hasSkill('biantian2')||target.hasSkill('dawu2')) return 0; - var att=get.attitude(player,target); - if(att>=4){ - if(target.hp>2&&(target.isHealthy()||target.hasSkillTag('maixie'))) return 0; - if(_status.event.allUse) return att; - if(target.hp==1) return att; - if(target.hp==2&&target.countCards('he')<=2) return att*0.7; - return 0; - } - return -1; - }).set('allUse',player.getExpansions('qixing').length>=game.countPlayer(function(current){ - return get.attitude(player,current)>4; - })*2); - "step 1" - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('dawu',targets,'thunder'); - var length=targets.length; - targets.forEach(target=>{ - target.addAdditionalSkill(`dawu_${player.playerid}`,'dawu2'); - target.markAuto('dawu2',[player]); + audio: 2, + content() { + "step 0"; + var num = Math.min(game.countPlayer(), player.getExpansions("qixing").length); + player + .chooseTarget( + get.prompt("dawu"), + "令至多" + get.cnNumber(num) + "名角色获得“大雾”标记", + [1, num] + ) + .set("ai", function (target) { + if (target.isMin()) return 0; + if (target.hasSkill("biantian2") || target.hasSkill("dawu2")) return 0; + var att = get.attitude(player, target); + if (att >= 4) { + if (target.hp > 2 && (target.isHealthy() || target.hasSkillTag("maixie"))) + return 0; + if (_status.event.allUse) return att; + if (target.hp == 1) return att; + if (target.hp == 2 && target.countCards("he") <= 2) return att * 0.7; + return 0; + } + return -1; + }) + .set( + "allUse", + player.getExpansions("qixing").length >= + game.countPlayer(function (current) { + return get.attitude(player, current) > 4; + }) * + 2 + ); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("dawu", targets, "thunder"); + var length = targets.length; + targets.forEach((target) => { + 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); - } - else{ + player.addTempSkill("dawu3", { player: "phaseBeginStart" }); + player.chooseCardButton( + "选择弃置" + get.cnNumber(length) + "张“星”", + length, + player.getExpansions("qixing"), + true + ); + } else { event.finish(); } - "step 2" + "step 2"; player.loseToDiscardpile(result.links); }, - ai:{combo:'qixing'}, + ai: { combo: "qixing" }, }, - dawu2:{ - charlotte:true, - ai:{ - nofire:true, - nodamage:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'damage')&&!get.tag(card,'thunderDamage')) return 'zeroplayertarget'; - } + dawu2: { + charlotte: true, + ai: { + nofire: true, + nodamage: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "damage") && !get.tag(card, "thunderDamage")) + return "zeroplayertarget"; + }, }, }, - intro:{ - content(storage){ + intro: { + content(storage) { return `共有${storage.length}枚标记`; }, - } - }, - dawu3:{ - trigger:{global:'damageBegin4'}, - filter(event,player){ - return !event.hasNature('thunder')&&event.player.getStorage('dawu2').includes(player); }, - forced:true, - charlotte:true, - logTarget:'player', - content(){ + }, + dawu3: { + trigger: { global: "damageBegin4" }, + filter(event, player) { + return !event.hasNature("thunder") && event.player.getStorage("dawu2").includes(player); + }, + forced: true, + charlotte: true, + logTarget: "player", + content() { trigger.cancel(); }, - onremove(player){ - game.countPlayer2(current=>{ - if(current.getStorage('dawu2').includes(player)){ - current.unmarkAuto('dawu2',[player]); + onremove(player) { + game.countPlayer2((current) => { + if (current.getStorage("dawu2").includes(player)) { + current.unmarkAuto("dawu2", [player]); current.removeAdditionalSkill(`dawu_${player.playerid}`); } - },true); + }, true); }, }, - kuangfeng:{ - unique:true, - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter(event,player){ - return player.getExpansions('qixing').length; + kuangfeng: { + unique: true, + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter(event, player) { + return player.getExpansions("qixing").length; }, - content(){ - "step 0" - player.chooseTarget(get.prompt('kuangfeng'),'令一名角色获得“狂风”标记').ai=function(target){ + content() { + "step 0"; + player.chooseTarget(get.prompt("kuangfeng"), "令一名角色获得“狂风”标记").ai = function ( + target + ) { return -1; - } - "step 1" - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('kuangfeng',targets,'fire'); - var length=targets.length; - targets.forEach(target=>{ - target.addAdditionalSkill(`kuangfeng_${player.playerid}`,'kuangfeng2'); - target.markAuto('kuangfeng2',[player]); + }; + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("kuangfeng", targets, "fire"); + var length = targets.length; + targets.forEach((target) => { + 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{ + player.addTempSkill("kuangfeng3", { player: "phaseBeginStart" }); + player.chooseCardButton( + "选择弃置" + get.cnNumber(length) + "张“星”", + length, + player.getExpansions("qixing"), + true + ); + } else { event.finish(); } - "step 2" + "step 2"; player.loseToDiscardpile(result.links); }, - ai:{combo:'qixing'}, + ai: { combo: "qixing" }, }, - kuangfeng2:{ - charlotte:true, - intro:{ - content(storage){ + kuangfeng2: { + charlotte: true, + intro: { + content(storage) { return `共有${storage.length}枚标记`; }, }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.tag(card,'fireDamage')&¤t<0) return 1.5; - } - } - } - }, - kuangfeng3:{ - trigger:{global:'damageBegin3'}, - filter(event,player){ - return event.hasNature('fire')&&event.player.getStorage('kuangfeng2').includes(player); + ai: { + effect: { + target(card, player, target, current) { + if (get.tag(card, "fireDamage") && current < 0) return 1.5; + }, + }, }, - charlotte:true, - forced:true, - logTarget:'player', - content(){ + }, + kuangfeng3: { + trigger: { global: "damageBegin3" }, + filter(event, player) { + return event.hasNature("fire") && event.player.getStorage("kuangfeng2").includes(player); + }, + charlotte: true, + forced: true, + logTarget: "player", + content() { trigger.num++; }, - onremove(player){ - game.countPlayer2(current=>{ - if(current.getStorage('kuangfeng2').includes(player)){ - current.unmarkAuto('kuangfeng2',player); + onremove(player) { + game.countPlayer2((current) => { + if (current.getStorage("kuangfeng2").includes(player)) { + current.unmarkAuto("kuangfeng2", player); current.removeAdditionalSkill(`kuangfeng_${player.playerid}`); } - },true); + }, true); }, }, - yeyan:{ - unique:true, - limited:true, - audio:3, - enable:'phaseUse', - filterCard(card,player){ - return !ui.selected.cards.some(cardx=>get.suit(cardx,player)==get.suit(card,player)); + yeyan: { + unique: true, + limited: true, + audio: 3, + enable: "phaseUse", + filterCard(card, player) { + return !ui.selected.cards.some( + (cardx) => get.suit(cardx, player) == get.suit(card, player) + ); }, - selectCard:[0,4], - filterTarget(card,player,target){ - var length=ui.selected.cards.length; - return length==0||length==4; + selectCard: [0, 4], + filterTarget(card, player, target) { + var length = ui.selected.cards.length; + return length == 0 || length == 4; }, - selectTarget(){ - if(ui.selected.cards.length==4) return [1,2]; - if(ui.selected.cards.length==0) return [1,3]; - game.uncheck('target'); - return [1,3]; + selectTarget() { + if (ui.selected.cards.length == 4) return [1, 2]; + if (ui.selected.cards.length == 0) return [1, 3]; + game.uncheck("target"); + return [1, 3]; }, - complexCard:true, - complexSelect:true, - line:'fire', - forceDie:true, - animationColor:'metal', - skillAnimation:'legend', - check(card){ - if(!lib.skill.yeyan.getBigFire(get.event('player'))) return -1; - return 1/(get.value(card)||0.5); + complexCard: true, + complexSelect: true, + line: "fire", + forceDie: true, + animationColor: "metal", + skillAnimation: "legend", + check(card) { + if (!lib.skill.yeyan.getBigFire(get.event("player"))) return -1; + return 1 / (get.value(card) || 0.5); }, - multitarget:true, - multiline:true, - contentBefore(){ - player.awakenSkill('yeyan'); + multitarget: true, + multiline: true, + contentBefore() { + player.awakenSkill("yeyan"); }, - content(){ - "step 0" - event.num=0; + content() { + "step 0"; + event.num = 0; targets.sortBySeat(); - "step 1" - if(cards.length==4) event.goto(2); + "step 1"; + if (cards.length == 4) event.goto(2); else { - if(event.numget.damageEffect(target,player,player,'fire')&&(!lib.skill.yeyan.getBigFire(player)||(target.hp<=3&&!target.hasSkillTag('filterDamage',null,{player:player})))); - if(!targets.includes(target)) return 0; - if(lib.skill.yeyan.getBigFire(player)){ - if(ui.selected.targets.length) return 0; - if(!(targets.length==1||(att<0&&target.identity&&target.identity.indexOf('zhu')!=-1))) return 0; - } - return att*get.damageEffect(target,player,player,'fire'); + if (event.num < targets.length) { + targets[event.num].damage("fire", 1, "nocard"); + event.num++; } + if (event.num == targets.length) event.finish(); + else event.redo(); } + "step 2"; + player.loseHp(3); + if (targets.length == 1) event.goto(4); + else { + player + .chooseTarget("请选择受到2点伤害的角色", true, function (card, player, target) { + return _status.event.targets.includes(target); + }) + .set("ai", function (target) { + return 1; + }) + .set("forceDie", true) + .set("targets", targets); + } + "step 3"; + if (event.num < targets.length) { + var dnum = 1; + if (result.bool && result.targets && targets[event.num] == result.targets[0]) + dnum = 2; + targets[event.num].damage("fire", dnum, "nocard"); + event.num++; + } + if (event.num == targets.length) event.finish(); + else event.redo(); + "step 4"; + player + .chooseControl("2点", "3点") + .set("prompt", "请选择伤害点数") + .set("ai", function () { + return "3点"; + }) + .set("forceDie", true); + "step 5"; + targets[0].damage("fire", result.control == "2点" ? 2 : 3, "nocard"); }, - getBigFire(player){ - if(player.getDiscardableCards(player,'h').reduce((list,card)=>list.add(get.suit(card,player)),[]).length<4) return false; - const targets=game.filterPlayer(target=>get.damageEffect(target,player,player,'fire')&&target.hp<=3&&!target.hasSkillTag('filterDamage',null,{player:player})); - if(!targets.length) return false; - if(targets.length==1||targets.some(target=>get.attitude(player,target)<0&&target.identity&&target.identity.indexOf('zhu')!=-1)){ - let suits=player.getDiscardableCards(player,'h').reduce((map,card)=>{ - const suit=get.suit(card,player); - if(!map[suit]) map[suit]=[]; + ai: { + order(item, player) { + return lib.skill.yeyan.getBigFire(player) ? 10 : 1; + }, + fireAttack: true, + result: { + target(player, target) { + if (player.hasUnknown()) return 0; + const att = get.sgn(get.attitude(player, target)); + const targets = game.filterPlayer( + (target) => + get.damageEffect(target, player, player, "fire") && + (!lib.skill.yeyan.getBigFire(player) || + (target.hp <= 3 && + !target.hasSkillTag("filterDamage", null, { player: player }))) + ); + if (!targets.includes(target)) return 0; + if (lib.skill.yeyan.getBigFire(player)) { + if (ui.selected.targets.length) return 0; + if ( + !( + targets.length == 1 || + (att < 0 && target.identity && target.identity.indexOf("zhu") != -1) + ) + ) + return 0; + } + return att * get.damageEffect(target, player, player, "fire"); + }, + }, + }, + getBigFire(player) { + if ( + player + .getDiscardableCards(player, "h") + .reduce((list, card) => list.add(get.suit(card, player)), []).length < 4 + ) + return false; + const targets = game.filterPlayer( + (target) => + get.damageEffect(target, player, player, "fire") && + target.hp <= 3 && + !target.hasSkillTag("filterDamage", null, { player: player }) + ); + if (!targets.length) return false; + if ( + targets.length == 1 || + targets.some( + (target) => + get.attitude(player, target) < 0 && + target.identity && + target.identity.indexOf("zhu") != -1 + ) + ) { + let suits = player.getDiscardableCards(player, "h").reduce((map, card) => { + const suit = get.suit(card, player); + if (!map[suit]) map[suit] = []; return map; - },{}),cards=[]; - Object.keys(suits).forEach(i=>{ - suits[i].addArray(player.getDiscardableCards(player,'h').filter(card=>get.suit(card)==i)); - cards.add(suits[i].sort((a,b)=>get.value(a)-get.value(b))[0]); + }, {}), + cards = []; + Object.keys(suits).forEach((i) => { + suits[i].addArray( + player.getDiscardableCards(player, "h").filter((card) => get.suit(card) == i) + ); + cards.add(suits[i].sort((a, b) => get.value(a) - get.value(b))[0]); }); - return player.hp+player.countCards('h',card=>!cards.includes(card)&&player.canSaveCard(card,player))-3>0; + return ( + player.hp + + player.countCards( + "h", + (card) => !cards.includes(card) && player.canSaveCard(card, player) + ) - + 3 > + 0 + ); } return false; }, }, - longhun:{ - audio:4, - group:['longhun1','longhun2','longhun3','longhun4'], - ai:{ - fireAttack:true, - skillTagFilter(player,tag){ - switch(tag){ - case 'respondSha':{ - if(player.countCards('he',{suit:'diamond'})=1) return [0,0]; - if(!target.hasFriend()) return; - if((get.tag(card,'damage')==1||get.tag(card,'loseHp'))&&target.hp>1) return [0,1]; - } + maixie: true, + respondSha: true, + respondShan: true, + effect: { + target(card, player, target) { + if (get.tag(card, "recover") && target.hp >= 1) return [0, 0]; + if (!target.hasFriend()) return; + if ((get.tag(card, "damage") == 1 || get.tag(card, "loseHp")) && target.hp > 1) + return [0, 1]; + }, }, - threaten(player,target){ - if(target.hp==1) return 2; + threaten(player, target) { + if (target.hp == 1) return 2; return 0.5; }, - } + }, }, - longhun1:{ - audio:true, - enable:['chooseToUse','chooseToRespond'], - prompt(){ - return '将'+get.cnNumber(Math.max(1,_status.event.player.hp))+'张红桃牌当作桃使用'; + longhun1: { + audio: true, + enable: ["chooseToUse", "chooseToRespond"], + prompt() { + return "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张红桃牌当作桃使用"; }, - position:'hes', - check(card,event){ - if(_status.event.player.hp>1) return 0; - return 10-get.value(card); + position: "hes", + check(card, event) { + if (_status.event.player.hp > 1) return 0; + return 10 - get.value(card); }, - selectCard(){ - return Math.max(1,_status.event.player.hp); + selectCard() { + return Math.max(1, _status.event.player.hp); }, - viewAs:{name:'tao'}, - viewAsFilter(player){ - return player.countCards('hes',{suit:'heart'})>=player.hp; + viewAs: { name: "tao" }, + viewAsFilter(player) { + return player.countCards("hes", { suit: "heart" }) >= player.hp; + }, + filterCard(card) { + return get.suit(card) == "heart"; }, - filterCard(card){ - return get.suit(card)=='heart'; - } }, - longhun2:{ - audio:true, - enable:['chooseToUse','chooseToRespond'], - prompt(){ - return '将'+get.cnNumber(Math.max(1,_status.event.player.hp))+'张方片当作火杀使用或打出'; + longhun2: { + audio: true, + enable: ["chooseToUse", "chooseToRespond"], + prompt() { + return ( + "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张方片当作火杀使用或打出" + ); }, - position:'hes', - check(card,event){ - if(_status.event.player.hp>1) return 0; - return 10-get.value(card); + position: "hes", + check(card, event) { + if (_status.event.player.hp > 1) return 0; + return 10 - get.value(card); }, - selectCard(){ - return Math.max(1,_status.event.player.hp); + selectCard() { + return Math.max(1, _status.event.player.hp); }, - viewAs:{name:'sha',nature:'fire'}, - viewAsFilter(player){ - return player.countCards('hes',{suit:'diamond'})>=player.hp; + viewAs: { name: "sha", nature: "fire" }, + viewAsFilter(player) { + return player.countCards("hes", { suit: "diamond" }) >= player.hp; + }, + filterCard(card) { + return get.suit(card) == "diamond"; }, - filterCard(card){ - return get.suit(card)=='diamond'; - } }, - longhun3:{ - audio:true, - enable:['chooseToUse','chooseToRespond'], - prompt(){ - return '将'+get.cnNumber(Math.max(1,_status.event.player.hp))+'张黑桃牌当作无懈可击使用'; + longhun3: { + audio: true, + enable: ["chooseToUse", "chooseToRespond"], + prompt() { + return ( + "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张黑桃牌当作无懈可击使用" + ); }, - position:'hes', - check(card,event){ - if(_status.event.player.hp>1) return 0; - return 7-get.value(card); + position: "hes", + check(card, event) { + if (_status.event.player.hp > 1) return 0; + return 7 - get.value(card); }, - selectCard(){ - return Math.max(1,_status.event.player.hp); + selectCard() { + return Math.max(1, _status.event.player.hp); }, - viewAs:{name:'wuxie'}, - viewAsFilter(player){ - return player.countCards('hes',{suit:'spade'})>=player.hp; + viewAs: { name: "wuxie" }, + viewAsFilter(player) { + return player.countCards("hes", { suit: "spade" }) >= player.hp; + }, + filterCard(card) { + return get.suit(card) == "spade"; }, - filterCard(card){ - return get.suit(card)=='spade'; - } }, - longhun4:{ - audio:true, - enable:['chooseToUse','chooseToRespond'], - prompt(){ - return '将'+get.cnNumber(Math.max(1,_status.event.player.hp))+'张梅花牌当作闪使用或打出'; + longhun4: { + audio: true, + enable: ["chooseToUse", "chooseToRespond"], + prompt() { + return ( + "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张梅花牌当作闪使用或打出" + ); }, - position:'hes', - check(card,event){ - if(_status.event.player.hp>1) return 0; - return 10-get.value(card); + position: "hes", + check(card, event) { + if (_status.event.player.hp > 1) return 0; + return 10 - get.value(card); }, - selectCard(){ - return Math.max(1,_status.event.player.hp); + selectCard() { + return Math.max(1, _status.event.player.hp); }, - viewAsFilter(player){ - return player.countCards('hes',{suit:'club'})>=player.hp; + viewAsFilter(player) { + return player.countCards("hes", { suit: "club" }) >= player.hp; + }, + viewAs: { name: "shan" }, + filterCard(card) { + return get.suit(card) == "club"; }, - viewAs:{name:'shan'}, - filterCard(card){ - return get.suit(card)=='club'; - } }, - juejing:{ - mod:{ - maxHandcard(player,num){ - return 2+num; - } + juejing: { + mod: { + maxHandcard(player, num) { + return 2 + num; + }, }, - audio:true, - trigger:{player:'phaseDrawBegin2'}, + audio: true, + trigger: { player: "phaseDrawBegin2" }, //priority:-5, - filter(event,player){ - return !event.numFixed&&player.hp0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 + ) { + var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return (name2=='diamond'?(5-get.value(card)):20-get.value(card)); + if (name2 == get.suit(card, player)) + return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, //选牌数量 - selectCard:[1,2], + selectCard: [1, 2], //确保选择第一张牌后 重新检测第二张牌的合法性 避免选择两张花色不同的牌 - complexCard:true, + complexCard: true, //选牌范围:手牌区和装备区和木马 - position:'hes', + position: "hes", //选牌合法性判断 - filterCard(card,player,event){ + filterCard(card, player, event) { //如果已经选了一张牌 那么第二张牌和第一张花色相同即可 - if(ui.selected.cards.length) return get.suit(card,player)==get.suit(ui.selected.cards[0],player); - event=event||_status.event; + if (ui.selected.cards.length) + return get.suit(card, player) == get.suit(ui.selected.cards[0], player); + event = event || _status.event; //获取当前时机的卡牌选择限制 - var filter=event._backup.filterCard; + var filter = event._backup.filterCard; //获取卡牌花色 - var name=get.suit(card,player); + var name = get.suit(card, player); //如果这张牌是梅花并且当前时机能够使用/打出闪 那么这张牌可以选择 - if(name=='club'&&filter(get.autoViewAs({name:'shan'},'unsure'),player,event)) return true; + if (name == "club" && filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) + return true; //如果这张牌是方片并且当前时机能够使用/打出火杀 那么这张牌可以选择 - if(name=='diamond'&&filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)) return true; + if ( + name == "diamond" && + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) + ) + return true; //如果这张牌是黑桃并且当前时机能够使用/打出无懈 那么这张牌可以选择 - if(name=='spade'&&filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)) return true; + if (name == "spade" && filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event)) + return true; //如果这张牌是红桃并且当前时机能够使用/打出桃 那么这张牌可以选择 - if(name=='heart'&&filter(get.autoViewAs({name:'tao'},'unsure'),player,event)) return true; + if (name == "heart" && filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event)) + return true; //上述条件都不满足 那么就不能选择这张牌 return false; }, //判断当前时机能否发动技能 - filter(event,player){ + filter(event, player) { //获取当前时机的卡牌选择限制 - var filter=event.filterCard; + var filter = event.filterCard; //如果当前时机能够使用/打出火杀并且角色有方片 那么可以发动技能 - if(filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)&&player.countCards('hes',{suit:'diamond'})) return true; + if ( + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && + player.countCards("hes", { suit: "diamond" }) + ) + return true; //如果当前时机能够使用/打出闪并且角色有梅花 那么可以发动技能 - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hes',{suit:'club'})) return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hes", { suit: "club" }) + ) + return true; //如果当前时机能够使用/打出桃并且角色有红桃 那么可以发动技能 - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hes',{suit:'heart'})) return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hes", { suit: "heart" }) + ) + return true; //如果当前时机能够使用/打出无懈可击并且角色有黑桃 那么可以发动技能 - if(filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)&&player.countCards('hes',{suit:'spade'})) return true; + if ( + filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && + player.countCards("hes", { suit: "spade" }) + ) + return true; return false; }, - ai:{ - respondSha:true, - respondShan:true, + ai: { + respondSha: true, + respondShan: true, //让系统知道角色“有杀”“有闪” - skillTagFilter(player,tag){ + skillTagFilter(player, tag) { var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hes',{suit:name})) return false; + if (!player.countCards("hes", { suit: name })) return false; }, //AI牌序 - order(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order(item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, //让系统知道玩家“有无懈”“有桃” - hiddenCard(player,name){ - if(name=='wuxie'&&_status.connectMode&&player.countCards('hs')>0) return true; - if(name=='wuxie') return player.countCards('hes',{suit:'spade'})>0; - if(name=='tao') return player.countCards('hes',{suit:'heart'})>0; + hiddenCard(player, name) { + if (name == "wuxie" && _status.connectMode && player.countCards("hs") > 0) return true; + if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; + if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, - group:['relonghun_num','relonghun_discard'], - subSkill:{ - num:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter(event){ - var evt=event; - return ['sha','tao'].includes(evt.card.name)&&evt.skill=='relonghun'&&evt.cards&&evt.cards.length==2; + group: ["relonghun_num", "relonghun_discard"], + subSkill: { + num: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter(event) { + var evt = event; + return ( + ["sha", "tao"].includes(evt.card.name) && + evt.skill == "relonghun" && + evt.cards && + evt.cards.length == 2 + ); }, - content(){ + content() { trigger.baseDamage++; - } + }, }, - discard:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - popup:false, - logTarget(){ + discard: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + popup: false, + logTarget() { return _status.currentPhase; }, - autodelay(event){ - return event.name=='respond'?0.5:false; + autodelay(event) { + return event.name == "respond" ? 0.5 : false; }, - filter(evt,player){ - return ['shan','wuxie'].includes(evt.card.name)&&evt.skill=='relonghun'&& - evt.cards&&evt.cards.length==2&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.countDiscardableCards(player,'he'); + filter(evt, player) { + return ( + ["shan", "wuxie"].includes(evt.card.name) && + evt.skill == "relonghun" && + evt.cards && + evt.cards.length == 2 && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.countDiscardableCards(player, "he") + ); }, - content(){ + content() { //game.log(trigger.card) //game.log(trigger.cards) - player.line(_status.currentPhase,'green'); - player.discardPlayerCard(_status.currentPhase,'he',true); - } - } - } + player.line(_status.currentPhase, "green"); + player.discardPlayerCard(_status.currentPhase, "he", true); + }, + }, + }, }, - xinlonghun:{ - audio:'longhun', - enable:['chooseToUse','chooseToRespond'], - prompt:'将♦手牌当做火【杀】,♥手牌当做【桃】,♣手牌当做【闪】,♠手牌当做【无懈可击】使用或打出', - viewAs(cards,player){ - if(cards.length){ - var name=false,nature=null; - switch(get.suit(cards[0],player)){ - case 'club':name='shan';break; - case 'diamond':name='sha';nature='fire';break; - case 'spade':name='wuxie';break; - case 'heart':name='tao';break; + xinlonghun: { + audio: "longhun", + enable: ["chooseToUse", "chooseToRespond"], + prompt: "将♦手牌当做火【杀】,♥手牌当做【桃】,♣手牌当做【闪】,♠手牌当做【无懈可击】使用或打出", + viewAs(cards, player) { + if (cards.length) { + var name = false, + nature = null; + switch (get.suit(cards[0], player)) { + case "club": + name = "shan"; + break; + case "diamond": + name = "sha"; + nature = "fire"; + break; + case "spade": + name = "wuxie"; + break; + case "heart": + name = "tao"; + break; } - if(name) return {name:name,nature:nature}; + if (name) return { name: name, nature: nature }; } return null; }, - check(card){ - var player=_status.event.player; - if(_status.event.type=='phase'){ - var max=0; + check(card) { + var player = _status.event.player; + if (_status.event.type == "phase") { + var max = 0; var name2; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hs", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 + ) { + var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return (name2=='diamond'?(5-get.value(card)):20-get.value(card)); + if (name2 == get.suit(card, player)) + return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, - position:'hs', - filterCard(card,player,event){ - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.suit(card,player); - if(name=='club'&&filter({name:'shan',cards:[card]},player,event)) return true; - if(name=='diamond'&&filter({name:'sha',cards:[card],nature:'fire'},player,event)) return true; - if(name=='spade'&&filter({name:'wuxie',cards:[card]},player,event)) return true; - if(name=='heart'&&filter({name:'tao',cards:[card]},player,event)) return true; + position: "hs", + filterCard(card, player, event) { + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.suit(card, player); + if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if ( + name == "diamond" && + filter({ name: "sha", cards: [card], nature: "fire" }, player, event) + ) + return true; + if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) + return true; + if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, - filter(event,player){ - var filter=event.filterCard; - if(filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)&&player.countCards('hs',{suit:'diamond'})) return true; - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hs',{suit:'club'})) return true; - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hs',{suit:'heart'})) return true; - if(filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)&&player.countCards('hs',{suit:'spade'})) return true; + filter(event, player) { + var filter = event.filterCard; + if ( + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && + player.countCards("hs", { suit: "diamond" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hs", { suit: "club" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hs", { suit: "heart" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && + player.countCards("hs", { suit: "spade" }) + ) + return true; return false; }, - precontent(){ + precontent() { delete event.result.skill; - player.logSkill('longhun'+(4-lib.suit.indexOf(get.suit(event.result.cards[0],player)))); + player.logSkill( + "longhun" + (4 - lib.suit.indexOf(get.suit(event.result.cards[0], player))) + ); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hs',{suit:name})) return false; + if (!player.countCards("hs", { suit: name })) return false; }, - order(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order(item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hs", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard(player,name){ - if(name=='wuxie'&&_status.connectMode&&player.countCards('hs')>0) return true; - if(name=='wuxie') return player.countCards('hs',{suit:'spade'})>0; - if(name=='tao') return player.countCards('hs',{suit:'heart'})>0; + hiddenCard(player, name) { + if (name == "wuxie" && _status.connectMode && player.countCards("hs") > 0) return true; + if (name == "wuxie") return player.countCards("hs", { suit: "spade" }) > 0; + if (name == "tao") return player.countCards("hs", { suit: "heart" }) > 0; }, }, - xinjuejing:{ - mod:{ - maxHandcard(player,num){ - return 2+num; - } + xinjuejing: { + mod: { + maxHandcard(player, num) { + return 2 + num; + }, }, - audio:2, - trigger:{player:['dying','dyingAfter']}, - forced:true, - content(){ + audio: 2, + trigger: { player: ["dying", "dyingAfter"] }, + forced: true, + content() { player.draw(); - } + }, }, - shelie:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter(event,player){ + shelie: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter(event, player) { return !event.numFixed; }, - content(){ - "step 0" + content() { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(5); + event.cards = get.cards(5); game.cardsGotoOrdering(event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str; - if(player==game.me&&!_status.auto){ - str='涉猎:获取花色各不相同的牌'; - } - else{ - str='涉猎'; - } - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - event.time=get.utc(); - game.addVideo('showCards',player,['涉猎',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - "step 1" - var list=[]; - for(var i of cards) list.add(get.suit(i,false)); - var next=player.chooseButton(list.length,true); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - for(var i=0;i0){ - game.delay(0,time); + var time = 1000 - (get.utc() - event.time); + if (time > 0) { + game.delay(0, time); } - "step 3" - game.broadcastAll('closeDialog',event.videoId); - var cards2=event.cards2; - player.gain(cards2,'log','gain2'); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var cards2 = event.cards2; + player.gain(cards2, "log", "gain2"); + }, + ai: { + threaten: 1.2, }, - ai:{ - threaten:1.2 - } }, - gongxin:{ - audio:2, - audioname:['re_lvmeng','gexuan'], - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h'); + gongxin: { + audio: 2, + audioname: ["re_lvmeng", "gexuan"], + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("h"); }, - content(){ - 'step 0' - var cards=target.getCards('h'); - player.chooseButton(2,[ - '攻心', - cards, - [['弃置此牌','置于牌堆顶'],'tdnodes'], - ]).set('filterButton',function(button){ - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - return type=='string'||get.suit(button.link)=='heart'; - }); - 'step 1' - if(result.bool){ - if(typeof result.links[0]!='string') result.links.reverse(); - var card=result.links[1],choice=result.links[0]; - if(choice=='弃置此牌') target.discard(card); - else{ - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【攻心】'); - target.lose(card,ui.cardPile,'visible','insert'); + content() { + "step 0"; + var cards = target.getCards("h"); + player + .chooseButton(2, ["攻心", cards, [["弃置此牌", "置于牌堆顶"], "tdnodes"]]) + .set("filterButton", function (button) { + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + return type == "string" || get.suit(button.link) == "heart"; + }); + "step 1"; + if (result.bool) { + if (typeof result.links[0] != "string") result.links.reverse(); + var card = result.links[1], + choice = result.links[0]; + if (choice == "弃置此牌") target.discard(card); + else { + player.showCards( + card, + get.translation(player) + "对" + get.translation(target) + "发动了【攻心】" + ); + target.lose(card, ui.cardPile, "visible", "insert"); } } }, - ai:{ - threaten:1.5, - result:{ - target(player,target){ - return -target.countCards('h'); - } + ai: { + threaten: 1.5, + result: { + target(player, target) { + return -target.countCards("h"); + }, }, - order:10, - expose:0.4, - } + order: 10, + expose: 0.4, + }, }, - "nzry_longnu":{ - mark:true, - locked:true, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content(storage,player,skill){ - if(player.storage.nzry_longnu==true) return '锁定技,出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷杀且无使用次数限制'; - return '锁定技,出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火杀且无距离限制'; + nzry_longnu: { + mark: true, + locked: true, + zhuanhuanji: true, + marktext: "☯", + intro: { + content(storage, player, skill) { + if (player.storage.nzry_longnu == true) + return "锁定技,出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷杀且无使用次数限制"; + return "锁定技,出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火杀且无距离限制"; }, }, - audio:2, - trigger:{ - player:'phaseUseBegin' + audio: 2, + trigger: { + player: "phaseUseBegin", }, - forced:true, - content(){ - 'step 0' - player.changeZhuanhuanji('nzry_longnu'); - if(player.storage.nzry_longnu!=true){ + forced: true, + content() { + "step 0"; + player.changeZhuanhuanji("nzry_longnu"); + if (player.storage.nzry_longnu != true) { player.loseMaxHp(); - } - else{ + } else { player.loseHp(); } player.draw(); - 'step 1' - if(player.storage.nzry_longnu!=true){ - player.addTempSkill('nzry_longnu_2','phaseUseAfter'); - } - else{ - player.addTempSkill('nzry_longnu_1','phaseUseAfter'); + "step 1"; + if (player.storage.nzry_longnu != true) { + player.addTempSkill("nzry_longnu_2", "phaseUseAfter"); + } else { + player.addTempSkill("nzry_longnu_1", "phaseUseAfter"); } }, - subSkill:{ - '1':{ - mod:{ - cardname(card,player){ - if(get.color(card)=='red') return 'sha'; + subSkill: { + 1: { + mod: { + cardname(card, player) { + if (get.color(card) == "red") return "sha"; }, - cardnature(card,player){ - if(get.color(card)=='red') return 'fire'; + cardnature(card, player) { + if (get.color(card) == "red") return "fire"; }, - targetInRange(card){ - if(get.color(card)=='red') return true; + targetInRange(card) { + if (get.color(card) == "red") return true; }, }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.6 - } + ai: { + effect: { + target(card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.6; + }, }, - respondSha:true, + respondSha: true, }, }, - '2':{ - mod:{ - cardname(card,player){ - if(['trick','delay'].includes(lib.card[card.name].type)) return 'sha'; + 2: { + mod: { + cardname(card, player) { + if (["trick", "delay"].includes(lib.card[card.name].type)) return "sha"; }, - cardnature(card,player){ - if(['trick','delay'].includes(lib.card[card.name].type)) return 'thunder'; + cardnature(card, player) { + if (["trick", "delay"].includes(lib.card[card.name].type)) return "thunder"; }, - cardUsable(card,player){ - if(card.name=='sha'&&game.hasNature(card,'thunder')) return Infinity; + cardUsable(card, player) { + if (card.name == "sha" && game.hasNature(card, "thunder")) return Infinity; }, }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.6 - } + ai: { + effect: { + target(card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.6; + }, }, - respondSha:true, + respondSha: true, }, }, }, - ai:{ - fireAttack:true, - halfneg:true, - threaten:1.05, + ai: { + fireAttack: true, + halfneg: true, + threaten: 1.05, }, }, - "nzry_jieying":{ - audio:2, - locked:true, - global:"g_nzry_jieying", - ai:{ - effect:{ - target(card){ - if(card.name=='tiesuo') return 'zeroplayertarget'; + nzry_jieying: { + audio: 2, + locked: true, + global: "g_nzry_jieying", + ai: { + effect: { + target(card) { + if (card.name == "tiesuo") return "zeroplayertarget"; }, }, }, - group:["nzry_jieying_1","nzry_jieying_2"], - subSkill:{ - '1':{ - audio:'nzry_jieying', - trigger:{ - player:['linkBefore','enterGame'], - global:'phaseBefore', + group: ["nzry_jieying_1", "nzry_jieying_2"], + subSkill: { + 1: { + audio: "nzry_jieying", + trigger: { + player: ["linkBefore", "enterGame"], + global: "phaseBefore", }, - forced:true, - filter(event,player){ - if(event.name=='link') return player.isLinked(); - return (event.name!='phase'||game.phaseNumber==0)&&!player.isLinked(); + forced: true, + filter(event, player) { + if (event.name == "link") return player.isLinked(); + return (event.name != "phase" || game.phaseNumber == 0) && !player.isLinked(); }, - content(){ - if(trigger.name!='link') player.link(true); + content() { + if (trigger.name != "link") player.link(true); else trigger.cancel(); }, }, - '2':{ - audio:'nzry_jieying', - trigger:{ - player:'phaseJieshuBegin', + 2: { + audio: "nzry_jieying", + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&!current.isLinked(); + direct: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && !current.isLinked(); }); }, - content(){ - "step 0" - player.chooseTarget(true,'请选择【结营】的目标',function(card,player,target){ - return target!=player&&!target.isLinked(); - }).ai=function(target){ - return 1+Math.random(); + content() { + "step 0"; + player.chooseTarget( + true, + "请选择【结营】的目标", + function (card, player, target) { + return target != player && !target.isLinked(); + } + ).ai = function (target) { + return 1 + Math.random(); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.line(result.targets); - player.logSkill('nzry_jieying'); + player.logSkill("nzry_jieying"); result.targets[0].link(true); - }else{ + } else { event.finish(); } }, }, }, }, - "g_nzry_jieying":{ - mod:{ - maxHandcard (player,num){ - if(game.countPlayer(function(current){return current.hasSkill('nzry_jieying')})>0&&player.isLinked()) return num+2; + g_nzry_jieying: { + mod: { + maxHandcard(player, num) { + if ( + game.countPlayer(function (current) { + return current.hasSkill("nzry_jieying"); + }) > 0 && + player.isLinked() + ) + return num + 2; }, }, }, - "nzry_junlve":{ - audio:2, + nzry_junlve: { + audio: 2, //marktext:"军", - intro:{ - content:'当前有#个标记', + intro: { + content: "当前有#个标记", }, //mark:true, - trigger:{ - player:"damageAfter", - source:"damageSource", + trigger: { + player: "damageAfter", + source: "damageSource", }, - forced:true, - content(){ - player.addMark('nzry_junlve',trigger.num); + forced: true, + content() { + player.addMark("nzry_junlve", trigger.num); + }, + ai: { + combo: "nzry_cuike", }, }, - "nzry_cuike":{ - audio:2, - trigger:{ - player:"phaseUseBegin", + nzry_cuike: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - content(){ - 'step 0' - if(player.countMark('nzry_junlve')%2==1){ - player.chooseTarget('是否发动【摧克】,对一名角色造成1点伤害?').ai=function(target){ - return -get.attitude(player,target); + direct: true, + content() { + "step 0"; + if (player.countMark("nzry_junlve") % 2 == 1) { + player.chooseTarget("是否发动【摧克】,对一名角色造成1点伤害?").ai = function ( + target + ) { + return -get.attitude(player, target); }; + } else { + player.chooseTarget("是否发动【摧克】,横置一名角色并弃置其区域内的一张牌?").ai = + function (target) { + return -get.attitude(player, target); + }; } - else{ - player.chooseTarget('是否发动【摧克】,横置一名角色并弃置其区域内的一张牌?').ai=function(target){ - return -get.attitude(player,target); - }; - } - 'step 1' - if(result.bool){ - player.logSkill('nzry_cuike',result.targets); - if(player.countMark('nzry_junlve')%2==1){ + "step 1"; + if (result.bool) { + player.logSkill("nzry_cuike", result.targets); + if (player.countMark("nzry_junlve") % 2 == 1) { result.targets[0].damage(); - } - else{ + } else { result.targets[0].link(true); - player.discardPlayerCard(result.targets[0],1,'hej',true); + player.discardPlayerCard(result.targets[0], 1, "hej", true); } } - 'step 2' - if(player.countMark('nzry_junlve')>7){ - player.chooseBool().set('ai',function(){ - return true; - }).set('prompt','是否弃置所有“军略”标记并对所有其他角色造成1点伤害?'); - }else{ + "step 2"; + if (player.countMark("nzry_junlve") > 7) { + player + .chooseBool() + .set("ai", function () { + return true; + }) + .set("prompt", "是否弃置所有“军略”标记并对所有其他角色造成1点伤害?"); + } else { event.finish(); } - 'step 3' - if(result.bool){ - var players=game.players.slice(0).sortBySeat(); + "step 3"; + if (result.bool) { + var players = game.players.slice(0).sortBySeat(); player.line(players); - player.removeMark('nzry_junlve',player.countMark('nzry_junlve')); - for(var i=0;i0; + unique: true, + mark: true, + skillAnimation: true, + animationColor: "metal", + enable: "phaseUse", + filter(event, player) { + return !player.storage.nzry_dinghuo && player.countMark("nzry_junlve") > 0; }, - check (event,player){ - var num=game.countPlayer(function(current){return get.attitude(player,current)<0&¤t.isLinked()}); - return player.storage.nzry_junlve>=num&&num==game.countPlayer(function(current){return get.attitude(player,current)<0}); + check(event, player) { + var num = game.countPlayer(function (current) { + return get.attitude(player, current) < 0 && current.isLinked(); + }); + return ( + player.storage.nzry_junlve >= num && + num == + game.countPlayer(function (current) { + return get.attitude(player, current) < 0; + }) + ); }, - filterTarget(card,player,target){ + filterTarget(card, player, target) { return target.isLinked(); }, - selectTarget(){ - return [1,_status.event.player.countMark('nzry_junlve')]; + selectTarget() { + return [1, _status.event.player.countMark("nzry_junlve")]; }, - multiline:true, - multitarget:true, - content (){ - 'step 0' - player.awakenSkill('nzry_dinghuo'); - player.storage.nzry_dinghuo=true; - 'step 1' - player.removeMark('nzry_junlve',player.countMark('nzry_junlve')); - for(var i=0;i=0) return false; - if(player.hasEnabledSlot()&&!player.hasEnabledSlot(5)) return false; + check(event, player) { + if (get.attitude(_status.event.player, event.player) >= 0) return false; + if (player.hasEnabledSlot() && !player.hasEnabledSlot(5)) return false; return true; }, - bannedList:[ - 'bifa','buqu','gzbuqu','songci','funan','xinfu_guhuo','reguhuo','huashen','rehuashen','old_guhuo','shouxi','xinpojun','taoluan','xintaoluan','yinbing','xinfu_yingshi','zhenwei','zhengnan','xinzhengnan','zhoufu', + bannedList: [ + "bifa", + "buqu", + "gzbuqu", + "songci", + "funan", + "xinfu_guhuo", + "reguhuo", + "huashen", + "rehuashen", + "old_guhuo", + "shouxi", + "xinpojun", + "taoluan", + "xintaoluan", + "yinbing", + "xinfu_yingshi", + "zhenwei", + "zhengnan", + "xinzhengnan", + "zhoufu", ], - logTarget:'player', - content(){ - 'step 0' - var list=[]; - var listm=[]; - var listv=[]; - if(trigger.player.name1!=undefined) listm=lib.character[trigger.player.name1][3]; - else listm=lib.character[trigger.player.name][3]; - if(trigger.player.name2!=undefined) listv=lib.character[trigger.player.name2][3]; - listm=listm.concat(listv); - var func=function(skill){ - var info=get.info(skill); - if(!info||info.charlotte||info.hiddenSkill||info.zhuSkill||info.juexingji||info.limited||info.dutySkill||(info.unique&&!info.gainable)||lib.skill.drlt_duorui.bannedList.includes(skill)) return false; + logTarget: "player", + content() { + "step 0"; + var list = []; + var listm = []; + var listv = []; + if (trigger.player.name1 != undefined) listm = lib.character[trigger.player.name1][3]; + else listm = lib.character[trigger.player.name][3]; + if (trigger.player.name2 != undefined) listv = lib.character[trigger.player.name2][3]; + listm = listm.concat(listv); + var func = function (skill) { + var info = get.info(skill); + if ( + !info || + info.charlotte || + info.hiddenSkill || + info.zhuSkill || + info.juexingji || + info.limited || + info.dutySkill || + (info.unique && !info.gainable) || + lib.skill.drlt_duorui.bannedList.includes(skill) + ) + return false; return true; }; - for(var i=0;i0){ - player.chooseControl(event.skills).set('prompt','请选择要获得的技能').set('ai',function(){return event.skills.randomGet()}); - } - else event.finish(); - 'step 2' - player.addTempSkills(result.control,{player:'dieAfter'}); + "step 1"; + if (event.skills.length > 0) { + player + .chooseControl(event.skills) + .set("prompt", "请选择要获得的技能") + .set("ai", function () { + return event.skills.randomGet(); + }); + } else event.finish(); + "step 2"; + player.addTempSkills(result.control, { player: "dieAfter" }); // player.popup(result.control,'thunder'); - player.storage.drlt_duorui=[result.control]; - player.storage.drlt_duorui_player=trigger.player; - trigger.player.storage.drlt_duorui=[result.control]; - trigger.player.addTempSkill('drlt_duorui1',{player:'phaseAfter'}); + player.storage.drlt_duorui = [result.control]; + player.storage.drlt_duorui_player = trigger.player; + trigger.player.storage.drlt_duorui = [result.control]; + trigger.player.addTempSkill("drlt_duorui1", { player: "phaseAfter" }); // game.log(player,'获得了技能','#g【'+get.translation(result.control)+'】') }, - group:['duorui_clear'], + group: ["duorui_clear"], }, - "duorui_clear":{ - trigger:{global:['phaseAfter','dieAfter'],}, - filter(event,player){ - if(!player.storage.drlt_duorui_player||!player.storage.drlt_duorui) return false; - return player.storage.drlt_duorui_player==event.player&&player.storage.drlt_duorui.length; + duorui_clear: { + trigger: { global: ["phaseAfter", "dieAfter"] }, + filter(event, player) { + if (!player.storage.drlt_duorui_player || !player.storage.drlt_duorui) return false; + return ( + player.storage.drlt_duorui_player == event.player && player.storage.drlt_duorui.length + ); }, - silent:true, - forced:true, - popup:false, - content(){ + silent: true, + forced: true, + popup: false, + content() { player.removeSkills(player.storage.drlt_duorui[0]); delete player.storage.drlt_duorui_player; - player.storage.drlt_duorui=[]; + player.storage.drlt_duorui = []; }, }, - "drlt_duorui1":{ - init(player,skill){ - player.disableSkill(skill,player.storage.drlt_duorui); + drlt_duorui1: { + init(player, skill) { + player.disableSkill(skill, player.storage.drlt_duorui); }, - onremove(player,skill){ + onremove(player, skill) { player.enableSkill(skill); }, - locked:true, - mark:true, - charlotte:true, - intro:{ - content(storage,player,skill){ - var list=[]; - for(var i in player.disabledSkills){ - if(player.disabledSkills[i].includes(skill)) list.push(i); + locked: true, + mark: true, + charlotte: true, + intro: { + content(storage, player, skill) { + var list = []; + for (var i in player.disabledSkills) { + if (player.disabledSkills[i].includes(skill)) list.push(i); } - if(list.length){ - var str='失效技能:'; - for(var i=0;i event.num2) { + opposite = event.target; + } else { + return false; + } + } else { + if (event.num1 < event.num2) { + opposite = event.player; + } else { + return false; + } + } + return opposite && opposite.isIn() && opposite.inRangeOf(player); }, - content(){ + forced: true, + content() { player.chooseToEnable(); }, }, - '3':{ - audio:"drlt_zhiti", - trigger:{ - player:'chooseToCompareAfter' + damage: { + audio: "drlt_zhiti", + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { + if (!player.hasDisabledSlot()) return false; + const opposite = event.source; + return opposite && opposite.isIn() && opposite.inRangeOf(player); }, - forced:true, - filter(event,player){ - return event.result.bool==true&&player.hasDisabledSlot(); - }, - content(){ - 'step 0' - player.chooseToEnable(); - }, - }, - '4':{ - audio:"drlt_zhiti", - trigger:{ - global:'chooseToCompareAfter' - }, - forced:true, - filter(event,player){ - return (event.targets!=undefined&&event.targets.includes(player)||event.target==player)&&event.result.bool==false&&player.hasDisabledSlot(); - }, - content(){ - player.chooseToEnable(); - }, - }, - '5':{ - audio:"drlt_zhiti", - trigger:{ - player:['damageEnd'] - }, - forced:true, - filter(event,player){ - return player.hasDisabledSlot(); - }, - content(){ + content() { player.chooseToEnable(); }, }, }, }, - g_drlt_zhiti:{ - mod:{ - maxHandcard (player,num){ - if(player.maxHp>player.hp&&game.countPlayer(function(current){ - return current!=player&¤t.hasSkill('drlt_zhiti')&¤t.inRange(player); - })) return num-1; + g_drlt_zhiti: { + mod: { + maxHandcard(player, num) { + if (player.isDamaged()) + return ( + num - + game.countPlayer(function (current) { + return ( + current != player && + current.hasSkill("drlt_zhiti") && + current.inRange(player) + ); + }) + ); }, }, }, - 'drlt_poxi':{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + drlt_poxi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; //return target!=player; }, - content(){ - 'step 0' - event.list1=[]; - event.list2=[]; - if(player.countCards('h')>0){ - var chooseButton=player.chooseButton(4,['你的手牌',player.getCards('h'),get.translation(target.name)+'的手牌',target.getCards('h')]); + content() { + "step 0"; + event.list1 = []; + event.list2 = []; + if (player.countCards("h") > 0) { + var chooseButton = player.chooseButton(4, [ + "你的手牌", + player.getCards("h"), + get.translation(target.name) + "的手牌", + target.getCards("h"), + ]); + } else { + var chooseButton = player.chooseButton(4, [ + get.translation(target.name) + "的手牌", + target.getCards("h"), + ]); } - else{ - var chooseButton=player.chooseButton(4,[get.translation(target.name)+'的手牌',target.getCards('h')]); - } - chooseButton.set('target',target); - chooseButton.set('ai',function(button){ - var player=_status.event.player; - var target=_status.event.target; - var ps=[]; - var ts=[]; - for(var i=0;i1) return 0; - if(ts.length==0||player.hp>3) return val; - return 2*val; + var card = button.link; + var owner = get.owner(card); + var val = get.value(card) || 1; + if (owner == target) { + if (ts.length > 1) return 0; + if (ts.length == 0 || player.hp > 3) return val; + return 2 * val; } - return 7-val; + return 7 - val; }); - chooseButton.set('filterButton',function(button){ - for(var i=0;i { + return current.hasSkill("drlt_jieying") && get.attitude(player, current) <= 0; + }) + ) + return Math.max(num, 0) + 1; }, - aiOrder(player,card,num){ - if(player.hasMark('drlt_jieying_mark')&&game.hasPlayer(current=>{ - return current.hasSkill('drlt_jieying')&&get.attitude(player,current)<=0; - })) return Math.max(num,0)+1; - } }, - audio:'drlt_jieying', - trigger:{ - player:'phaseDrawBegin2' + audio: "drlt_jieying", + trigger: { + player: "phaseDrawBegin2", }, - forced:true, - filter(event,player){ - return !event.numFixed&&player.hasMark('drlt_jieying_mark')&&game.hasPlayer(function(current){ - return current.hasSkill('drlt_jieying'); + forced: true, + filter(event, player) { + return ( + !event.numFixed && + player.hasMark("drlt_jieying_mark") && + game.hasPlayer(function (current) { + return current.hasSkill("drlt_jieying"); + }) + ); + }, + content() { + trigger.num += game.countPlayer(function (current) { + return current.hasSkill("drlt_jieying"); }); }, - content(){ - trigger.num+=game.countPlayer(function(current){ - return current.hasSkill('drlt_jieying'); - }); - }, - ai:{ - nokeep:true, - skillTagFilter(player){ - return player.hasMark('drlt_jieying_mark')&&game.hasPlayer(current=>{ - return current.hasSkill('drlt_jieying')&&get.attitude(player,current)<=0; - }); - } + ai: { + nokeep: true, + skillTagFilter(player) { + return ( + player.hasMark("drlt_jieying_mark") && + game.hasPlayer((current) => { + return current.hasSkill("drlt_jieying") && get.attitude(player, current) <= 0; + }) + ); + }, }, }, - 'drlt_jieying':{ - audio:2, - locked:false, - global:'drlt_jieying_mark', - group:["drlt_jieying_1","drlt_jieying_2","drlt_jieying_3"], - subSkill:{ - '1':{ - audio:'drlt_jieying', - trigger:{ - player:'phaseBegin' + drlt_jieying: { + audio: 2, + locked: false, + global: "drlt_jieying_mark", + group: ["drlt_jieying_1", "drlt_jieying_2", "drlt_jieying_3"], + subSkill: { + 1: { + audio: "drlt_jieying", + trigger: { + player: "phaseBegin", }, - forced:true, - filter(event,player){ - return !game.hasPlayer(function(current){ - return current.hasMark('drlt_jieying_mark'); + forced: true, + filter(event, player) { + return !game.hasPlayer(function (current) { + return current.hasMark("drlt_jieying_mark"); }); }, - content(){ - player.addMark('drlt_jieying_mark',1); + content() { + player.addMark("drlt_jieying_mark", 1); }, }, - '2':{ - audio:'drlt_jieying', - trigger:{ - player:"phaseJieshuBegin", + 2: { + audio: "drlt_jieying", + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - filter(event,player){ - return player.hasMark('drlt_jieying_mark'); + direct: true, + filter(event, player) { + return player.hasMark("drlt_jieying_mark"); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('drlt_jieying'),"将“营”交给一名角色;其摸牌阶段多摸一张牌,出牌阶段使用【杀】的次数上限+1且手牌上限+1。该角色回合结束后,其移去“营”标记,然后你获得其所有手牌。",function(card,player,target){ - return target!=player; - }).ai=function(target){ - let th=target.countCards('h'),att=get.attitude(_status.event.player,target); - for(let i in target.skills){ - let info=get.info(i); - if(info&&info.shaRelated) return Math.abs(att); + content() { + "step 0"; + player.chooseTarget( + get.prompt("drlt_jieying"), + "将“营”交给一名角色;其摸牌阶段多摸一张牌,出牌阶段使用【杀】的次数上限+1且手牌上限+1。该角色回合结束后,其移去“营”标记,然后你获得其所有手牌。", + function (card, player, target) { + return target != player; } - if(att>0){ - if(th>3&&target.hp>2) return 0.6*th; + ).ai = function (target) { + let th = target.countCards("h"), + att = get.attitude(_status.event.player, target); + for (let i in target.skills) { + let info = get.info(i); + if (info && info.shaRelated) return Math.abs(att); } - if(att<1){ - if(target.countCards('j',{name:'lebu'})) return 1+Math.min((1.5+th)*0.8,target.getHandcardLimit()*0.7); - if(!th||target.getEquip('zhangba')||target.getEquip('guanshi')) return 0; - if(!target.inRange(player)||player.countCards('hs',{name:'shan'})>1) return Math.min((1+th)*0.3,target.getHandcardLimit()*0.2); + if (att > 0) { + if (th > 3 && target.hp > 2) return 0.6 * th; + } + if (att < 1) { + if (target.countCards("j", { name: "lebu" })) + return ( + 1 + Math.min((1.5 + th) * 0.8, target.getHandcardLimit() * 0.7) + ); + if (!th || target.getEquip("zhangba") || target.getEquip("guanshi")) + return 0; + if ( + !target.inRange(player) || + player.countCards("hs", { name: "shan" }) > 1 + ) + return Math.min((1 + th) * 0.3, target.getHandcardLimit() * 0.2); } return 0; }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - player.logSkill('drlt_jieying',target); - var mark=player.countMark('drlt_jieying_mark'); - player.removeMark('drlt_jieying_mark',mark); - target.addMark('drlt_jieying_mark',mark); + player.logSkill("drlt_jieying", target); + var mark = player.countMark("drlt_jieying_mark"); + player.removeMark("drlt_jieying_mark", mark); + target.addMark("drlt_jieying_mark", mark); } }, - ai:{ - effect:{ - player(card,player,target){ - if(get.name(card)==='lebu'&&get.attitude(player,target)<0) return 1+Math.min((target.countCards('h')+1.5)*0.8,target.getHandcardLimit()*0.7); - } - } - } + ai: { + effect: { + player(card, player, target) { + if (get.name(card) === "lebu" && get.attitude(player, target) < 0) + return ( + 1 + + Math.min( + (target.countCards("h") + 1.5) * 0.8, + target.getHandcardLimit() * 0.7 + ) + ); + }, + }, + }, }, - '3':{ - audio:'drlt_jieying', - trigger:{ - global:'phaseEnd', + 3: { + audio: "drlt_jieying", + trigger: { + global: "phaseEnd", }, - forced:true, - filter(event,player){ - return player!=event.player&&event.player.hasMark('drlt_jieying_mark')&&event.player.isIn(); + forced: true, + filter(event, player) { + return ( + player != event.player && + event.player.hasMark("drlt_jieying_mark") && + event.player.isIn() + ); }, - logTarget:'player', - content(){ - if(trigger.player.countCards('h')>0){ - trigger.player.give(trigger.player.getCards('h'),player); + logTarget: "player", + content() { + if (trigger.player.countCards("h") > 0) { + trigger.player.give(trigger.player.getCards("h"), player); } - trigger.player.removeMark('drlt_jieying_mark',trigger.player.countMark('drlt_jieying_mark')); + trigger.player.removeMark( + "drlt_jieying_mark", + trigger.player.countMark("drlt_jieying_mark") + ); }, }, }, }, }, - card:{ - changandajian_equip1:{ - fullskin:true, - derivation:'shen_sunquan', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-5}, - onLose(){ + card: { + changandajian_equip1: { + fullskin: true, + derivation: "shen_sunquan", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -5 }, + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - changandajian_equip2:{ - fullskin:true, - cardimage:'changandajian_equip1', - derivation:'shen_sunquan', - type:'equip', - subtype:'equip2', - onLose(){ + changandajian_equip2: { + fullskin: true, + cardimage: "changandajian_equip1", + derivation: "shen_sunquan", + type: "equip", + subtype: "equip2", + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - changandajian_equip3:{ - fullskin:true, - cardimage:'changandajian_equip1', - derivation:'shen_sunquan', - type:'equip', - subtype:'equip3', - distance:{globalTo:2}, - onLose(){ + changandajian_equip3: { + fullskin: true, + cardimage: "changandajian_equip1", + derivation: "shen_sunquan", + type: "equip", + subtype: "equip3", + distance: { globalTo: 2 }, + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - changandajian_equip4:{ - fullskin:true, - cardimage:'changandajian_equip1', - derivation:'shen_sunquan', - type:'equip', - subtype:'equip4', - distance:{globalFrom:-2}, - onLose(){ + changandajian_equip4: { + fullskin: true, + cardimage: "changandajian_equip1", + derivation: "shen_sunquan", + type: "equip", + subtype: "equip4", + distance: { globalFrom: -2 }, + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - changandajian_equip5:{ - fullskin:true, - cardimage:'changandajian_equip1', - derivation:'shen_sunquan', - type:'equip', - subtype:'equip5', - skills:['changandajian_equip5'], - onLose(){ + changandajian_equip5: { + fullskin: true, + cardimage: "changandajian_equip1", + derivation: "shen_sunquan", + type: "equip", + subtype: "equip5", + skills: ["changandajian_equip5"], + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - changandajian_equip6:{ - fullskin:true, - cardimage:'changandajian_equip1', - derivation:'shen_sunquan', - type:'equip', - subtype:'equip6', - distance:{globalTo:2,globalFrom:-2}, - onLose(){ + changandajian_equip6: { + fullskin: true, + cardimage: "changandajian_equip1", + derivation: "shen_sunquan", + type: "equip", + subtype: "equip6", + distance: { globalTo: 2, globalFrom: -2 }, + onLose() { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); - player.addTempSkill('changandajian_destroy'); + card.destroyed = true; + game.log(card, "被销毁了"); + player.addTempSkill("changandajian_destroy"); }, - ai:{ - value(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + ai: { + value(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - equipValue(card,player){ - if(game.hasPlayer(function(current){ - return lib.skill.changandajian_destroy.getEffect(player,current)>0; - })) return 0; + equipValue(card, player) { + if ( + game.hasPlayer(function (current) { + return lib.skill.changandajian_destroy.getEffect(player, current) > 0; + }) + ) + return 0; return 8; }, - basic:{ - equipValue:2, - } + basic: { + equipValue: 2, + }, }, }, - qizhengxiangsheng:{ - enable:true, - type:'trick', - fullskin:true, - derivation:'shen_xunyu', - filterTarget:lib.filter.notMe, - content(){ - 'step 0' - if(!event.qizheng_name){ - if(player.isIn()) player.chooseControl('奇兵','正兵').set('prompt','请选择'+get.translation(target)+'的标记').set('choice',function(){ - var e1=1.5*get.sgn(get.damageEffect(target,player,target)); - var e2=0; - if(target.countGainableCards(player,'h')>0&&!target.hasSkillTag('noh')) e2=-1; - var es=target.getGainableCards(player,'e'); - if(es.length) e2=Math.min(e2,function(){ - var max=0; - for(var i of es) max=Math.max(max,get.value(i,target)) - return -max/4; - }()); - if(Math.abs(e1-e2)<=0.3) return Math.random()<0.5?'奇兵':'正兵'; - if(e1 0 && + !target.hasSkillTag("noh") + ) + e2 = -1; + var es = target.getGainableCards(player, "e"); + if (es.length) + e2 = Math.min( + e2, + (function () { + var max = 0; + for (var i of es) + max = Math.max(max, get.value(i, target)); + return -max / 4; + })() + ); + if (Math.abs(e1 - e2) <= 0.3) + return Math.random() < 0.5 ? "奇兵" : "正兵"; + if (e1 < e2) return "奇兵"; + return "正兵"; + })() + ) + .set("ai", function () { + return _status.event.choice; + }); else event.finish(); } - 'step 1' - if(!event.qizheng_name&&result&&result.control) event.qizheng_name=result.control; - if(event.directHit) event._result={bool:false}; - else target.chooseToRespond('请打出一张杀或闪响应奇正相生',function(card,player){ - var name=get.name(card); - return name=='sha'||name=='shan'; - }).set('ai',function(card){ - if(_status.event.choice=='all'){ - var rand=get.rand('qizhengxiangsheng'); - if(rand>0.5) return 0; - return 1+Math.random(); - } - if(get.name(card)==_status.event.choice) return get.order(card); - return 0; - }).set('choice',function(){ - if(target.hasSkillTag('useShan')) return 'shan'; - if(typeof event.qizheng_aibuff=='boolean'){ - var shas=target.getCards('h','sha'),shans=target.getCards('h','shan'); - if(event.qizheng_aibuff){ - if(shas.length>=Math.max(1,shans.length)) return 'shan'; - if(shans.length>shas.length) return 'sha'; - return false; - } - if(!shas.length||!shans.length) return false; - } - var e1=1.5*get.sgn(get.damageEffect(target,player,target)); - var e2=0; - if(target.countGainableCards(player,'h')>0&&!target.hasSkillTag('noh')) e2=-1; - var es=target.getGainableCards(player,'e'); - if(es.length) e2=Math.min(e2,function(){ - var max=0; - for(var i of es) max=Math.max(max,get.value(i,target)) - return -max/4; - }()); - if(e1-e2>=0.3) return 'shan'; - if(e2-e1>=0.3) return 'sha'; - return 'all'; - }()); - 'step 2' - var name=result.bool?result.card.name:null,require=event.qizheng_name; - if(require=='奇兵'&&name!='sha') target.damage(); - else if(require=='正兵'&&name!='shan'&&target.countGainableCards(player,'he')>0) player.gainPlayerCard(target,true,'he'); + "step 1"; + if (!event.qizheng_name && result && result.control) event.qizheng_name = result.control; + if (event.directHit) event._result = { bool: false }; + else + target + .chooseToRespond("请打出一张杀或闪响应奇正相生", function (card, player) { + var name = get.name(card); + return name == "sha" || name == "shan"; + }) + .set("ai", function (card) { + if (_status.event.choice == "all") { + var rand = get.rand("qizhengxiangsheng"); + if (rand > 0.5) return 0; + return 1 + Math.random(); + } + if (get.name(card) == _status.event.choice) return get.order(card); + return 0; + }) + .set( + "choice", + (function () { + if (target.hasSkillTag("useShan")) return "shan"; + if (typeof event.qizheng_aibuff == "boolean") { + var shas = target.getCards("h", "sha"), + shans = target.getCards("h", "shan"); + if (event.qizheng_aibuff) { + if (shas.length >= Math.max(1, shans.length)) return "shan"; + if (shans.length > shas.length) return "sha"; + return false; + } + if (!shas.length || !shans.length) return false; + } + var e1 = 1.5 * get.sgn(get.damageEffect(target, player, target)); + var e2 = 0; + if ( + target.countGainableCards(player, "h") > 0 && + !target.hasSkillTag("noh") + ) + e2 = -1; + var es = target.getGainableCards(player, "e"); + if (es.length) + e2 = Math.min( + e2, + (function () { + var max = 0; + for (var i of es) max = Math.max(max, get.value(i, target)); + return -max / 4; + })() + ); + if (e1 - e2 >= 0.3) return "shan"; + if (e2 - e1 >= 0.3) return "sha"; + return "all"; + })() + ); + "step 2"; + var name = result.bool ? result.card.name : null, + require = event.qizheng_name; + if (require == "奇兵" && name != "sha") target.damage(); + else if ( + require == "正兵" && + name != "shan" && + target.countGainableCards(player, "he") > 0 + ) + player.gainPlayerCard(target, true, "he"); }, - ai:{ - order:5, - tag:{ - damage:0.5, - gain:0.5, - loseCard:1, - respondShan:1, - respondSha:1, + ai: { + order: 5, + tag: { + damage: 0.5, + gain: 0.5, + loseCard: 1, + respondShan: 1, + respondSha: 1, }, - result:{ - target(player,target){ - var e1=1.5*get.sgn(get.damageEffect(target,player,target)); - var e2=0; - if(target.countGainableCards(player,'h')>0&&!target.hasSkillTag('noh')) e2=-1; - var es=target.getGainableCards(player,'e'); - if(es.length) e2=Math.min(e2,function(){ - var max=0; - for(var i of es) max=Math.max(max,get.value(i,target)) - return -max/4; - }()); - if(game.hasPlayer(function(current){ - return current.hasSkill('tianzuo')&&get.attitude(current,player)<=0; - })) return Math.max(e1,e2); - return Math.min(e1,e2); + result: { + target(player, target) { + var e1 = 1.5 * get.sgn(get.damageEffect(target, player, target)); + var e2 = 0; + if (target.countGainableCards(player, "h") > 0 && !target.hasSkillTag("noh")) + e2 = -1; + var es = target.getGainableCards(player, "e"); + if (es.length) + e2 = Math.min( + e2, + (function () { + var max = 0; + for (var i of es) max = Math.max(max, get.value(i, target)); + return -max / 4; + })() + ); + if ( + game.hasPlayer(function (current) { + return current.hasSkill("tianzuo") && get.attitude(current, player) <= 0; + }) + ) + return Math.max(e1, e2); + return Math.min(e1, e2); }, }, }, }, }, - dynamicTranslate:{ - nzry_longnu(player){ - if(player.hasSkill('nzry_longnu_2')) return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; - if(player.hasSkill('nzry_longnu_1')) return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; - if(player.storage.nzry_longnu==true) return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; + dynamicTranslate: { + nzry_longnu(player) { + if (player.hasSkill("nzry_longnu_2")) + return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; + if (player.hasSkill("nzry_longnu_1")) + return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; + if (player.storage.nzry_longnu == true) + return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; return '转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。'; }, }, - translate:{ - "shen_luxun":"神陆逊", - shen_luxun_prefix:'神', - "nzry_junlve":"军略", - "nzry_junlve_info":"锁定技,当你受到或造成伤害后,你获得X个“军略”标记(X为伤害点数)。", - "nzry_cuike":"摧克", - "nzry_cuike_info":"出牌阶段开始时,若“军略”标记的数量为奇数,你可以对一名角色造成1点伤害;若“军略”标记的数量为偶数,你可以横置一名角色并弃置其区域内的一张牌。然后,若“军略”标记的数量超过7个,你可以移去全部“军略”标记并对所有其他角色造成1点伤害。", - "nzry_dinghuo":"绽火", - "nzry_dinghuo_info":"限定技,出牌阶段,你可以移去全部“军略”标记,令至多等量的已横置角色弃置所有装备区内的牌。然后,你对其中一名角色造成1点火焰伤害。", - "shen_liubei":"神刘备", - shen_liubei_prefix:'神', - "nzry_longnu":"龙怒", - "nzry_longnu_info":"转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。", - "nzry_jieying":"结营", - "nzry_jieying_info":"锁定技,游戏开始时或当你的武将牌重置时,你横置;所有已横置的角色手牌上限+2;结束阶段,你横置一名其他角色。", + translate: { + shen_luxun: "神陆逊", + shen_luxun_prefix: "神", + nzry_junlve: "军略", + nzry_junlve_info: "锁定技,当你受到或造成伤害后,你获得X个“军略”标记(X为伤害点数)。", + nzry_cuike: "摧克", + nzry_cuike_info: + "出牌阶段开始时,若“军略”标记的数量为奇数,你可以对一名角色造成1点伤害;若“军略”标记的数量为偶数,你可以横置一名角色并弃置其区域内的一张牌。然后,若“军略”标记的数量超过7个,你可以移去全部“军略”标记并对所有其他角色造成1点伤害。", + nzry_dinghuo: "绽火", + nzry_dinghuo_info: + "限定技,出牌阶段,你可以移去全部“军略”标记,令至多等量的已横置角色弃置所有装备区内的牌。然后,你对其中一名角色造成1点火焰伤害。", + shen_liubei: "神刘备", + shen_liubei_prefix: "神", + nzry_longnu: "龙怒", + nzry_longnu_info: + "转换技,锁定技,阴:出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火【杀】且无距离限制。阳:出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷【杀】且无使用次数限制。", + nzry_jieying: "结营", + nzry_jieying_info: + "锁定技,游戏开始时或当你的武将牌重置时,你横置;所有已横置的角色手牌上限+2;结束阶段,你横置一名其他角色。", - "shen_ganning":"神甘宁", - shen_ganning_prefix:'神', - "shen_zhangliao":"神张辽", - shen_zhangliao_prefix:'神', + shen_ganning: "神甘宁", + shen_ganning_prefix: "神", + shen_zhangliao: "神张辽", + shen_zhangliao_prefix: "神", - "drlt_poxi":"魄袭", - "drlt_poxi_info":"出牌阶段限一次,你可以观看一名其他角色的手牌,然后你可以弃置你与其手牌中的四张花色不同的牌。若如此做,根据此次弃置你的牌的数量执行以下效果:零张,扣减1点体力上限;一张,你结束出牌阶段且本回合手牌上限-1;三张,你回复1点体力;四张,你摸四张牌。", - "drlt_jieying":"劫营", - "drlt_jieying_info":"回合开始时,若场上没有拥有“营”标记的角色,你获得1个“营”标记;结束阶段,你可以将你的一个“营”标记交给一名角色;有“营”标记的角色摸牌阶段多摸一张牌,出牌阶段使用【杀】的次数上限+1,手牌上限+1。有“营”的其他角色回合结束时,其移去“营”标记,然后你获得其所有手牌。", - drlt_jieying_mark:"劫营", - "drlt_duorui1":"失效技能", - "drlt_duorui1_bg":"锐", - "drlt_duorui":"夺锐", - "drlt_duorui_info":"当你于出牌阶段内对一名其他角色造成伤害后,你可以废除你装备区内的一个装备栏(若已全部废除则可以跳过此步骤),然后获得该角色的一个技能直到其的下回合结束或其死亡(觉醒技,限定技,主公技,隐匿技,使命技等特殊技能除外)。若如此做,该角色该技能失效且你不能再发动〖夺锐〗直到你失去以此法获得的技能。", - "drlt_zhiti":"止啼", - "drlt_zhiti_info":"锁定技,你攻击范围内已受伤的其他角色手牌上限-1;当你拼点或【决斗】胜利,或受到伤害后,你恢复一个装备栏。", + drlt_poxi: "魄袭", + drlt_poxi_info: + "出牌阶段限一次,你可以观看一名其他角色的手牌,然后你可以弃置你与其手牌中的四张花色不同的牌。若如此做,根据此次弃置你的牌的数量执行以下效果:零张,扣减1点体力上限;一张,你结束出牌阶段且本回合手牌上限-1;三张,你回复1点体力;四张,你摸四张牌。", + drlt_jieying: "劫营", + drlt_jieying_info: + "回合开始时,若场上没有拥有“营”标记的角色,你获得1个“营”标记;结束阶段,你可以将你的一个“营”标记交给一名角色;有“营”标记的角色摸牌阶段多摸一张牌,出牌阶段使用【杀】的次数上限+1,手牌上限+1。有“营”的其他角色回合结束时,其移去“营”标记,然后你获得其所有手牌。", + drlt_jieying_mark: "劫营", + drlt_duorui1: "失效技能", + drlt_duorui1_bg: "锐", + drlt_duorui: "夺锐", + drlt_duorui_info: + "当你于出牌阶段内对一名其他角色造成伤害后,你可以废除你装备区内的一个装备栏(若已全部废除则可以跳过此步骤),然后获得该角色的一个技能直到其的下回合结束或其死亡(觉醒技,限定技,主公技,隐匿技,使命技等特殊技能除外)。若如此做,该角色该技能失效且你不能再发动〖夺锐〗直到你失去以此法获得的技能。", + drlt_zhiti: "止啼", + drlt_zhiti_info: + "锁定技。①你攻击范围内已受伤的其他角色手牌上限-1;②当你拼点或【决斗】胜利/或受到伤害后,若对方/伤害来源在你的攻击范围内,则你恢复一个装备栏。", - shen_zhaoyun:'神赵云', - shen_zhaoyun_prefix:'神', - shen_guanyu:'神关羽', - shen_guanyu_prefix:'神', - shen_lvmeng:'神吕蒙', - shen_lvmeng_prefix:'神', - shen_simayi:'神司马懿', - shen_simayi_prefix:'神', - shen_caocao:'神曹操', - shen_caocao_prefix:'神', - shen_zhugeliang:'神诸葛亮', - shen_zhugeliang_prefix:'神', - shen_zhouyu:'神周瑜', - shen_zhouyu_prefix:'神', - shen_lvbu:'神吕布', - shen_lvbu_prefix:'神', - xinjuejing:'绝境', - xinjuejing_info:'锁定技。①你的手牌上限+2。②当你进入或脱离濒死状态时,你摸一张牌。', - relonghun:'龙魂', - relonghun_info:'你可以将同花色的一至两张牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当普【无懈可击】。若你以此法使用了两张红色牌,则此牌回复值或伤害值+1。若你以此法使用了两张黑色牌,则你弃置当前回合角色一张牌。', - xinlonghun:'龙魂', - xinlonghun_info:'你可以将你的手牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当【无懈可击】。', - longhun:'龙魂', - longhun1:'龙魂♥︎', - longhun2:'龙魂♦︎', - longhun3:'龙魂♠︎', - longhun4:'龙魂♣︎', - juejing:'绝境', - longhun_info:'你可以将同花色的X张牌按下列规则使用或打出:红桃当【桃】,方块当具火焰伤害的【杀】,梅花当【闪】,黑桃当【无懈可击】(X为你当前的体力值且至少为1)。', - juejing_info:'锁定技。①摸牌阶段,你令额定摸牌数+X(X为你已损失的体力值)。②你的手牌上限+2。', - wushen:'武神', - wushen_info:'锁定技。①你的红桃手牌均视为【杀】。②你使用红桃【杀】无距离和次数限制且不可被响应。', - wuhun:'武魂', - wuhun_info:'锁定技,杀死你的角色立即进入濒死状态。', - shelie:'涉猎', - gongxin:'攻心', - gongxin_discard:'弃置', - gongxin_top:'牌堆顶', - renjie:'忍戒', - renjie2:'忍戒', - renjie_info:'锁定技,当你受到1点伤害后,你获得一枚“忍”标记;锁定技,当你于弃牌阶段内弃置牌后,你获得等同于失去的牌数量的“忍”标记。', - sbaiyin:'拜印', - sbaiyin_info:'觉醒技,准备阶段开始时,若你的“忍”标记数不小于4,你减1点体力上限,然后获得〖极略〗。', - jilue:'极略', - jilue_info:'当一名角色的判定牌生效前,你可以弃1枚“忍”标记并发动〖鬼才〗;每当你受到伤害后,你可以弃1枚“忍”标记并发动〖放逐〗;当你使用锦囊牌时,你可以弃1枚“忍”标记并发动〖集智〗;出牌阶段限一次,你可以弃1枚“忍”标记并发动〖制衡〗;出牌阶段,你可以弃1枚“忍”标记并获得〖完杀〗直到回合结束。', - jilue_guicai:'鬼才', - jilue_fangzhu:'放逐', - jilue_wansha:'完杀', - jilue_zhiheng:'制衡', - jilue_jizhi:'集智', - lianpo:'连破', - lianpo_info:'一名角色的回合结束时,若你本回合内杀死过角色,则你可以进行一个额外的回合。', - guixin:'归心', - qinyin:'琴音', - yeyan:'业炎', - shelie_info:'摸牌阶段,你可以改为从牌堆顶亮出五张牌,然后选择获得不同花色的牌各一张。', - gongxin_info:'出牌阶段限一次,你可以观看一名其他角色的手牌,并可以展示其中一张红桃牌,然后将其弃置或置于牌堆顶。', - guixin_info:'当你受到1点伤害后,你可以获得每名其他角色区域里的一张牌,然后你翻面。', - guixin_info_alter:'当你受到1点伤害后,你可以随机获得每名其他角色区域里的一张牌,然后你翻面。', - qinyin_info:'弃牌阶段结束时,若你于此阶段内弃置过两张或更多的牌,则你可以选择一项:1. 令所有角色各回复1点体力;2. 令所有角色各失去1点体力。', + shen_zhaoyun: "神赵云", + shen_zhaoyun_prefix: "神", + shen_guanyu: "神关羽", + shen_guanyu_prefix: "神", + shen_lvmeng: "神吕蒙", + shen_lvmeng_prefix: "神", + shen_simayi: "神司马懿", + shen_simayi_prefix: "神", + shen_caocao: "神曹操", + shen_caocao_prefix: "神", + shen_zhugeliang: "神诸葛亮", + shen_zhugeliang_prefix: "神", + shen_zhouyu: "神周瑜", + shen_zhouyu_prefix: "神", + shen_lvbu: "神吕布", + shen_lvbu_prefix: "神", + xinjuejing: "绝境", + xinjuejing_info: "锁定技。①你的手牌上限+2。②当你进入或脱离濒死状态时,你摸一张牌。", + relonghun: "龙魂", + relonghun_info: + "你可以将同花色的一至两张牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当普【无懈可击】。若你以此法使用了两张红色牌,则此牌回复值或伤害值+1。若你以此法使用了两张黑色牌,则你弃置当前回合角色一张牌。", + xinlonghun: "龙魂", + xinlonghun_info: + "你可以将你的手牌按下列规则使用或打出:红桃当【桃】,方块当火【杀】,梅花当【闪】,黑桃当【无懈可击】。", + longhun: "龙魂", + longhun1: "龙魂♥︎", + longhun2: "龙魂♦︎", + longhun3: "龙魂♠︎", + longhun4: "龙魂♣︎", + juejing: "绝境", + longhun_info: + "你可以将同花色的X张牌按下列规则使用或打出:红桃当【桃】,方块当具火焰伤害的【杀】,梅花当【闪】,黑桃当【无懈可击】(X为你当前的体力值且至少为1)。", + juejing_info: "锁定技。①摸牌阶段,你令额定摸牌数+X(X为你已损失的体力值)。②你的手牌上限+2。", + wushen: "武神", + wushen_info: "锁定技。①你的红桃手牌均视为【杀】。②你使用红桃【杀】无距离和次数限制且不可被响应。", + wuhun: "武魂", + wuhun_info: "锁定技,杀死你的角色立即进入濒死状态。", + shelie: "涉猎", + gongxin: "攻心", + gongxin_discard: "弃置", + gongxin_top: "牌堆顶", + renjie: "忍戒", + renjie2: "忍戒", + renjie_info: + "锁定技,当你受到1点伤害后,你获得一枚“忍”标记;锁定技,当你于弃牌阶段内弃置牌后,你获得等同于失去的牌数量的“忍”标记。", + sbaiyin: "拜印", + sbaiyin_info: + "觉醒技,准备阶段开始时,若你的“忍”标记数不小于4,你减1点体力上限,然后获得〖极略〗。", + jilue: "极略", + jilue_info: + "当一名角色的判定牌生效前,你可以弃1枚“忍”标记并发动〖鬼才〗;每当你受到伤害后,你可以弃1枚“忍”标记并发动〖放逐〗;当你使用锦囊牌时,你可以弃1枚“忍”标记并发动〖集智〗;出牌阶段限一次,你可以弃1枚“忍”标记并发动〖制衡〗;出牌阶段,你可以弃1枚“忍”标记并获得〖完杀〗直到回合结束。", + jilue_guicai: "鬼才", + jilue_fangzhu: "放逐", + jilue_wansha: "完杀", + jilue_zhiheng: "制衡", + jilue_jizhi: "集智", + lianpo: "连破", + lianpo_info: "一名角色的回合结束时,若你本回合内杀死过角色,则你可以进行一个额外的回合。", + guixin: "归心", + qinyin: "琴音", + yeyan: "业炎", + shelie_info: "摸牌阶段,你可以改为从牌堆顶亮出五张牌,然后选择获得不同花色的牌各一张。", + gongxin_info: + "出牌阶段限一次,你可以观看一名其他角色的手牌,并可以展示其中一张红桃牌,然后将其弃置或置于牌堆顶。", + guixin_info: "当你受到1点伤害后,你可以获得每名其他角色区域里的一张牌,然后你翻面。", + guixin_info_alter: "当你受到1点伤害后,你可以随机获得每名其他角色区域里的一张牌,然后你翻面。", + qinyin_info: + "弃牌阶段结束时,若你于此阶段内弃置过两张或更多的牌,则你可以选择一项:1. 令所有角色各回复1点体力;2. 令所有角色各失去1点体力。", // qinyin_info:'每当你于弃牌阶段内因你的弃置而失去第X张手牌时(X至少为2),你可以选择一项:1.令所有角色各回复1点体力;2.令所有角色各失去1点体力。每阶段限一次。', - yeyan_info:'限定技,出牌阶段,你可以对一至三名角色造成至多共3点火焰伤害(你可以任意分配每名目标角色受到的伤害点数),若你将对一名角色分配2点或更多的火焰伤害,你须先弃置四张不同花色的手牌再失去3点体力。', - qixing:'七星', - qixing_bg:'星', - qixing2:'七星', - qixing3:'七星', - qixing_info:'游戏开始时,你将牌堆顶的七张牌置于你的武将牌上,称之为“星”。然后/摸牌阶段结束后,你可用任意数量的手牌等量交换这些“星”。', - dawu:'大雾', - dawu2_bg:'雾', - dawu2:'大雾', - dawu3:'大雾', + yeyan_info: + "限定技,出牌阶段,你可以对一至三名角色造成至多共3点火焰伤害(你可以任意分配每名目标角色受到的伤害点数),若你将对一名角色分配2点或更多的火焰伤害,你须先弃置四张不同花色的手牌再失去3点体力。", + qixing: "七星", + qixing_bg: "星", + qixing2: "七星", + qixing3: "七星", + qixing_info: + "游戏开始时,你将牌堆顶的七张牌置于你的武将牌上,称之为“星”。然后/摸牌阶段结束后,你可用任意数量的手牌等量交换这些“星”。", + dawu: "大雾", + dawu2_bg: "雾", + dawu2: "大雾", + dawu3: "大雾", // dawu2_info:'已获得大雾标记', - dawu_info:'结束阶段,你可以弃置X张“星”并指定等量的角色:直到你的下回合开始,当这些角色受到非雷电伤害时,防止此伤害。', - kuangfeng:'狂风', - kuangfeng2:'狂风', - kuangfeng2_bg:'风', + dawu_info: + "结束阶段,你可以弃置X张“星”并指定等量的角色:直到你的下回合开始,当这些角色受到非雷电伤害时,防止此伤害。", + kuangfeng: "狂风", + kuangfeng2: "狂风", + kuangfeng2_bg: "风", // kuangfeng2_info:'已获得狂风标记', - kuangfeng3:'狂风', - kuangfeng_info:'结束阶段,你可以弃置1张“星”并指定一名角色:直到你的下回合开始,该角色受到火焰伤害时,此伤害+1。', - baonu:'狂暴', - baonu_bg:'暴', - baonu_info:'锁定技,游戏开始时,你获得两枚“暴怒”标记;锁定技,当你造成/受到1点伤害后,你获得1枚“暴怒”标记。', - shenfen:'神愤', - shenfen_info:'限定技,出牌阶段,你可以弃置6枚暴怒标记,对场上所有其他角色造成1点伤害,然后令其弃置四张牌。', - wuqian:'无前', - wuqian_info:'出牌阶段,你可以弃置两枚暴怒标记并获得技能〖无双〗直到回合结束。', - wumou:'无谋', - wumou_info:'锁定技,当你使用普通锦囊牌时,你选择一项:1.弃置1枚“暴怒”标记;2.失去1点体力。', - ol_wuqian:'无前', - ol_wuqian_info:'出牌阶段,你可以弃置2枚“暴怒”标记并选择一名本回合内未选择过的其他角色,你获得技能〖无双〗并令其防具无效直到回合结束。', - ol_shenfen:'神愤', - ol_shenfen_info:'出牌阶段限一次,你可以弃置6枚“暴怒”标记并选择所有其他角色,对这些角色各造成1点伤害。然后这些角色先各弃置其装备区里的牌,再各弃置四张手牌。最后你将你的武将牌翻面。', - new_wuhun:'武魂', - new_wuhun_info:'锁定技,当你受到伤害后,伤害来源获得X个“梦魇”标记(X为伤害点数)。锁定技,当你死亡时,你选择一名“梦魇”标记数量最多的其他角色。该角色进行判定:若判定结果不为【桃】或【桃园结义】,则该角色死亡。', - "new_guixin":"归心", - "new_guixin_info":"当你受到1点伤害后,你可以按照你选择的区域优先度随机获得每名其他角色区域里的一张牌,然后你翻面。", - ol_zhangliao:'OL神张辽', - ol_zhangliao_prefix:'OL神', - olduorui:'夺锐', - olduorui2:'夺锐', - olduorui_info:'当你于出牌阶段内对一名角色造成伤害后,你可以选择该角色武将牌上的一个技能。若如此做,你结束出牌阶段,且你令此技能于其下个回合结束之前无效。', - olzhiti:'止啼', - olzhiti_info:'锁定技,你攻击范围内已受伤角色的手牌上限-1。若场上已受伤的角色数:不小于1,你的手牌上限+1;不小于3,你于摸牌阶段开始时令额定摸牌数+1;不小于5,回合结束时,你废除一名角色的一个随机装备栏。', - shen_caopi:'神曹丕', - shen_caopi_prefix:'神', - chuyuan:'储元', - chuyuan_info:'一名角色受到伤害后,若你武将牌上「储」的数量小于体力上限,你可以令其摸一张牌。然后其将一张手牌置于你的武将牌上,称为「储」。', + kuangfeng3: "狂风", + kuangfeng_info: + "结束阶段,你可以弃置1张“星”并指定一名角色:直到你的下回合开始,该角色受到火焰伤害时,此伤害+1。", + baonu: "狂暴", + baonu_bg: "暴", + baonu_info: + "锁定技,游戏开始时,你获得两枚“暴怒”标记;锁定技,当你造成/受到1点伤害后,你获得1枚“暴怒”标记。", + shenfen: "神愤", + shenfen_info: + "限定技,出牌阶段,你可以弃置6枚暴怒标记,对场上所有其他角色造成1点伤害,然后令其弃置四张牌。", + wuqian: "无前", + wuqian_info: "出牌阶段,你可以弃置两枚暴怒标记并获得技能〖无双〗直到回合结束。", + wumou: "无谋", + wumou_info: "锁定技,当你使用普通锦囊牌时,你选择一项:1.弃置1枚“暴怒”标记;2.失去1点体力。", + ol_wuqian: "无前", + ol_wuqian_info: + "出牌阶段,你可以弃置2枚“暴怒”标记并选择一名本回合内未选择过的其他角色,你获得技能〖无双〗并令其防具无效直到回合结束。", + ol_shenfen: "神愤", + ol_shenfen_info: + "出牌阶段限一次,你可以弃置6枚“暴怒”标记并选择所有其他角色,对这些角色各造成1点伤害。然后这些角色先各弃置其装备区里的牌,再各弃置四张手牌。最后你将你的武将牌翻面。", + new_wuhun: "武魂", + new_wuhun_info: + "锁定技,当你受到伤害后,伤害来源获得X个“梦魇”标记(X为伤害点数)。锁定技,当你死亡时,你选择一名“梦魇”标记数量最多的其他角色。该角色进行判定:若判定结果不为【桃】或【桃园结义】,则该角色死亡。", + new_guixin: "归心", + new_guixin_info: + "当你受到1点伤害后,你可以按照你选择的区域优先度随机获得每名其他角色区域里的一张牌,然后你翻面。", + ol_zhangliao: "OL神张辽", + ol_zhangliao_prefix: "OL神", + olduorui: "夺锐", + olduorui2: "夺锐", + olduorui_info: + "当你于出牌阶段内对一名角色造成伤害后,你可以选择该角色武将牌上的一个技能。若如此做,你结束出牌阶段,且你令此技能于其下个回合结束之前无效。", + olzhiti: "止啼", + olzhiti_info: + "锁定技,你攻击范围内已受伤角色的手牌上限-1。若场上已受伤的角色数:不小于1,你的手牌上限+1;不小于3,你于摸牌阶段开始时令额定摸牌数+1;不小于5,回合结束时,你废除一名角色的一个随机装备栏。", + shen_caopi: "神曹丕", + shen_caopi_prefix: "神", + chuyuan: "储元", + chuyuan_info: + "一名角色受到伤害后,若你武将牌上「储」的数量小于体力上限,你可以令其摸一张牌。然后其将一张手牌置于你的武将牌上,称为「储」。", //chuyuan_info:'一名角色受到伤害后,你可以令其摸一张牌。然后其将一张手牌置于你的武将牌上,称为「储」。你的手牌上限+X(X为你武将牌上的「储」数)。', - dengji:'登极', - dengji_info:'觉醒技,准备阶段,若你武将牌上的「储」数不小于3,则你减1点体力上限并获得所有「储」,然后获得技能〖天行〗和〖奸雄〗。', - tianxing:'天行', - tianxing_info:'觉醒技,准备阶段,若你武将牌上的「储」数不小于3,则你减1点体力上限并获得所有「储」,然后失去技能〖储元〗,选择获得以下技能中的一个:〖仁德〗/〖制衡〗/〖乱击〗/〖行动〗。', - shen_zhenji:'神甄宓', - shen_zhenji_prefix:'神', - shenfu:'神赋', - shenfu_info:'回合结束时,若你的手牌数为:奇数,你可对一名其他角色造成1点雷属性伤害。若其因此进入过濒死状态,你可重复此流程(不能选择本次已选择过的角色)。偶数,你可选择一名角色,你令其摸一张牌或弃置一张手牌。若其手牌数等于体力值,你可重复此流程(不能选择本次已选择过的角色)。', - qixian:'七弦', - qixian_info:'锁定技,你的手牌上限视为7。', - caopi_xingdong:'行动', - caopi_xingdong_info:'出牌阶段限一次,你可以将一张【杀】或普通锦囊牌交给一名其他角色,然后该角色选择一项:对除你以外的角色使用此牌并在此牌结算完成后和你各摸一张牌;或跳过下回合的判定阶段和摸牌阶段。', - shen_diaochan:'神貂蝉', - shen_diaochan_prefix:'神', - meihun:'魅魂', - meihun_info:'结束阶段或当你成为【杀】的目标后,你可以令一名其他角色交给你一张你声明的花色的手牌,若其没有则你观看其手牌然后弃置其中一张。', - huoxin_control:'惑心', - huoxin:'惑心', - huoxin_info:'出牌阶段限一次,你可以展示两张花色相同的手牌并分别交给两名其他角色,然后令这两名角色拼点,没赢的角色获得1个“魅惑”标记。拥有2个或更多“魅惑”的角色回合即将开始时,该角色移去其所有“魅惑”,此回合改为由你操控。', - boss_zhaoyun:'高达一号', - boss_zhaoyun_ab:'神赵云', - boss_zhaoyun_prefix:'神', - boss_juejing:'绝境', - boss_juejing2:'绝境', - boss_juejing_info:'锁定技,摸牌阶段开始前,你跳过此阶段。当你得到牌/失去手牌后,若你的手牌数大于4/小于4,则你将手牌摸至4张/弃置至4张。', - zhanjiang:'斩将', - zhanjiang_info:'准备阶段开始时,如果其他角色的装备区内有【青釭剑】,你可以获得之。', - shen_guojia:'神郭嘉', - shen_guojia_prefix:'神', - shuishi:'慧识', - shuishi_info:'出牌阶段限一次,若你的体力上限小于10,则你可选择一名角色。你令其摸一张牌,若其以此法得到的牌:与该角色的其他手牌花色均不相同,则你加1点体力上限,若你的体力上限小于10,则你可以重复此流程;否则你减1点体力上限,且其展示所有手牌。', - stianyi:'天翊', - stianyi_info:'觉醒技,准备阶段,若场上的所有存活角色均于本局游戏内受到过伤害,则你加2点体力上限并回复1点体力,然后令一名角色获得技能〖佐幸〗。', - zuoxing:'佐幸', - zuoxing2:'佐幸', - zuoxing_info:'出牌阶段限一次,若令你获得〖佐幸〗的角色存活且体力上限大于1,则你可以令其减1点体力上限,并视为使用一张普通锦囊牌。', - sghuishi:'辉逝', - sghuishi_info:'限定技,出牌阶段,你可以选择一名其他角色:若其有未发动过的觉醒技,则你令其发动这些觉醒技时无视原有条件;否则其摸四张牌。然后你减2点体力上限。', - shen_taishici:'神太史慈', - shen_taishici_prefix:'神', - dulie:'笃烈', - dulie_info:'锁定技。当你成为【杀】的目标时,若使用者的体力值大于你,则你进行判定。若结果为红桃,则取消此目标。', - tspowei:'破围', - tspowei_info:'使命技。①游戏开始时,你令所有其他角色获得一个“围”。②一名角色受到伤害后,若其有“围”,则其移去“围”。③回合开始时,你选择所有有“围”的角色。这些角色失去“围”,然后这些角色的第一个不为你的下家获得等量的“围”。④一名其他角色的回合开始时,若其有“围”,则你可以选择一项:⒈弃置一张手牌并对其造成1点伤害。⒉若其体力值不大于你,则你获得其一张手牌。选择完成后,你视为在其攻击范围内直到回合结束。⑤使命:回合开始时,若场上没有“围”,则你获得技能〖神著〗。⑥失败:当你进入濒死状态时,你将体力值回复至1点,然后弃置装备区的所有牌。', - shenzhu:'神著', - shenzhu_info:'锁定技,当你使用有对应实体牌的非转化【杀】结算结束后,你选择一项:①摸一张牌,且本回合使用【杀】的次数上限+1。②摸三张牌,且本回合不能再使用【杀】。', - dangmo:'荡魔', - dangmo_info:'当你于出牌阶段内使用第一张【杀】选择目标后,你可以为此牌增加至多Y-1个目标(Y为你的体力值)。', - reshuishi:'慧识', - reshuishi_info:'出牌阶段限一次。若你的体力上限小于10,你可进行判定牌不置入弃牌堆的判定。若判定结果与本次发动技能时的其他判定结果的花色均不相同且你的体力上限小于10,则你加1点体力上限,且可以重复此流程。然后你将所有位于处理区的判定牌交给一名角色。若其手牌数为全场最多,则你减1点体力上限。', - resghuishi:'辉逝', - resghuishi_info:'限定技,出牌阶段,你可选择一名角色。若你的体力上限不小于存活人数且其有未发动的觉醒技,则你令其中一个技能无视发动条件;否则其摸四张牌。然后你减2点体力上限。', - qizhengxiangsheng:'奇正相生', - qizhengxiangsheng_info:'出牌阶段,对一名其他角色使用。你将目标角色标记为“奇兵”或“正兵”(对其他角色不可见)。然后目标角色可以打出一张【杀】或【闪】。若其是“奇兵”且未打出【杀】,则你对其造成1点伤害;若其是“正兵”且未打出【闪】,则你获得其一张牌。', - shen_xunyu:'神荀彧', - shen_xunyu_prefix:'神', - tianzuo:'天佐', - tianzuo_info:'锁定技。①游戏开始时,你将8张【奇正相生】加入牌堆。②【奇正相生】对你无效。', - lingce:'灵策', - lingce_info:'锁定技。当有【奇正相生】或智囊或〖定汉①〗记录过的锦囊牌被使用时,若此牌不为转化牌且对应实体牌数量为1,则你摸一张牌。', - dinghan:'定汉', - dinghan_info:'①当你成为未记录过的普通锦囊牌的目标时,或有未记录过的延时锦囊牌进入你的判定区时,你记录此牌名并取消之。②准备阶段,你可在〖定汉①〗的记录中添加或减少一种锦囊牌的牌名。', - shen_sunce:'神孙策', - shen_sunce_prefix:'神', - yingba:'英霸', - yingba_info:'①出牌阶段限一次,你可令一名体力上限大于1的其他角色减少1点体力上限并获得“平定”标记,然后你减少1点体力上限。②你对拥有“平定”标记的角色使用牌没有距离限制。', - scfuhai:'覆海', - scfuhai_info:'锁定技。①当你使用牌指定目标后,若目标角色有“平定”标记,则其不可响应此牌。若你本回合内以此法得到的牌数小于2,则你摸一张牌。②拥有“平定”标记的角色死亡时,你增加X点体力上限并摸X张牌。(X为其拥有的“平定”标记数)。', - pinghe:'冯河', - pinghe_info:'锁定技。①你的手牌上限基数等于你已损失的体力值。②当你受到其他角色造成的伤害时,若你有牌且你的体力上限大于1,则你防止此伤害,减1点体力上限并将一张手牌交给一名其他角色。然后若你拥有〖英霸〗,则伤害来源获得一个“平定”标记。', - shen_jiangwei:'神姜维', - shen_jiangwei_prefix:'神', - jiufa:'九伐', - jiufa_info:'①当你声明使用牌后或打出牌时,你记录此牌的牌名。②当你使用或打出的牌结算结束后,若你的〖九伐〗记录中包含至少⑨种不同的牌名,则你可以展示牌堆顶的⑨张牌,选择并获得其中任意张点数各不相同且{这九张牌中存在未被选择且和已选择的牌点数相同}的牌,清除所有的记录,将其余牌置入弃牌堆。', - tianren:'天任', - tianren_info:'锁定技。①当有一张基本牌或普通锦囊牌不因使用而进入弃牌堆后,你获得一枚“天任”标记。②当你获得“天任”标记或体力上限变化后,若你的“天任”数不小于X,则你移去X枚“天任”,加1点体力上限并摸两张牌(X为你的体力上限)。', - pingxiang:'平襄', - pingxiang_info:'限定技。出牌阶段,若你的体力上限大于⑨,则你可减⑨点体力上限,视为使用至多⑨张火【杀】,然后失去〖九伐〗,并将手牌上限基数改为体力上限直到游戏结束。', - shen_sunquan:'神孙权', - shen_sunquan_prefix:'神', - dili:'帝力', - dili_info:'锁定技。游戏开始时,你随机获得一条东吴命运线。', - yuheng:'驭衡', - yuheng_info:'①出牌阶段限一次。你可以失去所有不为〖驭衡〗的非锁定技,然后随机获得全部东吴命运线涉及的一个技能。若你本阶段内没有发动过其他非锁定技,则你随机获得当前东吴命运线涉及的一个内容。②出牌阶段结束时,若你未于本阶段内发动过〖驭衡①〗,则你失去1点体力。', - yuheng_append:'天下英雄谁敌手?曹刘。生子当如孙仲谋!', - dili_shengzhi:'圣质', - dili_shengzhi_info:'锁定技。若你因〖驭衡〗获得过〖英魂〗〖弘德〗〖秉壹〗,则当你使用点数为质数的牌时,此牌不可被响应。', - dili_chigang:'持纲', - dili_chigang_info:'锁定技。若你因〖驭衡〗获得过〖观微〗〖弼政〗〖安国〗,则当你的判定阶段开始前,你跳过此阶段并获得一个额外的摸牌阶段。', - dili_qionglan:'穹览', - dili_qionglan_info:'锁定技,限定技。若你因〖驭衡〗获得过〖涉猎〗〖问卦〗〖博图〗,则当你发动的〖驭衡〗结算结束后,你随机获得两条其他东吴命运线。', - dili_quandao:'权道', - dili_quandao_info:'锁定技。若你因〖驭衡〗获得过〖制衡〗〖诫训〗〖安恤〗,则你手牌区内点数为字母的牌的牌名视为【调剂盐梅】。', - dili_jiaohui:'交辉', - dili_jiaohui_info:'锁定技。若你因〖驭衡〗获得过〖下书〗〖结姻〗〖缔盟〗,且你的手牌数为1,则此牌的牌名视为【远交近攻】。', - dili_yuanlv:'渊虑', - dili_yuanlv_info:'锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜江〗,则当你成为自己使用的不为【长安大舰】的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。', - changandajian_equip1:'长安大舰', - changandajian_equip2:'长安大舰', - changandajian_equip3:'长安大舰', - changandajian_equip4:'长安大舰', - changandajian_equip5:'长安大舰', - changandajian_equip6:'长安大舰', - changandajian_destroy:'长安大舰', - changandajian_equip1_info:'锁定技。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - changandajian_equip2_info:'锁定技。当你失去装备区内的【长安大舰】后,你销毁之并回复1点体力。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - changandajian_equip3_info:'锁定技。其他角色至你的距离+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - changandajian_equip4_info:'锁定技。你至其他角色的距离-2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - changandajian_equip5_info:'锁定技。你的手牌上限+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - changandajian_equip6_info:'锁定技。你至其他角色的距离-2,其他角色至你的距离+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。', - shen_machao:'神马超', - shen_machao_prefix:'神', - shouli:'狩骊', - shouli_backup:'狩骊', - shouli_info:'①锁定技,游戏开始时,你令场上所有角色从你的下家起,依次使用牌堆中的一张不为赠物的坐骑牌。②你可以将场上的一张进攻坐骑牌当做【杀】(无任何次数限制),防御坐骑牌当做【闪】使用或打出。若此坐骑牌的拥有者不为你,则其非锁定技于本回合内失效。且当你或其于本回合内受到伤害时,此伤害+1且改为雷属性。', - hengwu:'横骛', - hengwu_info:'当你使用或打出有花色的牌时,若你的手牌区内没有与此牌花色相同的牌,则你可以摸X张牌(X为场上装备区内花色与此牌相同的牌数)。', - hengwu_append:'棘手,怀念,摧毁!', + dengji: "登极", + dengji_info: + "觉醒技,准备阶段,若你武将牌上的「储」数不小于3,则你减1点体力上限并获得所有「储」,然后获得技能〖天行〗和〖奸雄〗。", + tianxing: "天行", + tianxing_info: + "觉醒技,准备阶段,若你武将牌上的「储」数不小于3,则你减1点体力上限并获得所有「储」,然后失去技能〖储元〗,选择获得以下技能中的一个:〖仁德〗/〖制衡〗/〖乱击〗/〖行动〗。", + shen_zhenji: "神甄宓", + shen_zhenji_prefix: "神", + shenfu: "神赋", + shenfu_info: + "回合结束时,若你的手牌数为:奇数,你可对一名其他角色造成1点雷属性伤害。若其因此进入过濒死状态,你可重复此流程(不能选择本次已选择过的角色)。偶数,你可选择一名角色,你令其摸一张牌或弃置一张手牌。若其手牌数等于体力值,你可重复此流程(不能选择本次已选择过的角色)。", + qixian: "七弦", + qixian_info: "锁定技,你的手牌上限视为7。", + caopi_xingdong: "行动", + caopi_xingdong_info: + "出牌阶段限一次,你可以将一张【杀】或普通锦囊牌交给一名其他角色,然后该角色选择一项:对除你以外的角色使用此牌并在此牌结算完成后和你各摸一张牌;或跳过下回合的判定阶段和摸牌阶段。", + shen_diaochan: "神貂蝉", + shen_diaochan_prefix: "神", + meihun: "魅魂", + meihun_info: + "结束阶段或当你成为【杀】的目标后,你可以令一名其他角色交给你一张你声明的花色的手牌,若其没有则你观看其手牌然后弃置其中一张。", + huoxin_control: "惑心", + huoxin: "惑心", + huoxin_info: + "出牌阶段限一次,你可以展示两张花色相同的手牌并分别交给两名其他角色,然后令这两名角色拼点,没赢的角色获得1个“魅惑”标记。拥有2个或更多“魅惑”的角色回合即将开始时,该角色移去其所有“魅惑”,此回合改为由你操控。", + boss_zhaoyun: "高达一号", + boss_zhaoyun_ab: "神赵云", + boss_zhaoyun_prefix: "神", + boss_juejing: "绝境", + boss_juejing2: "绝境", + boss_juejing_info: + "锁定技,摸牌阶段开始前,你跳过此阶段。当你得到牌/失去手牌后,若你的手牌数大于4/小于4,则你将手牌摸至4张/弃置至4张。", + zhanjiang: "斩将", + zhanjiang_info: "准备阶段开始时,如果其他角色的装备区内有【青釭剑】,你可以获得之。", + shen_guojia: "神郭嘉", + shen_guojia_prefix: "神", + shuishi: "慧识", + shuishi_info: + "出牌阶段限一次,若你的体力上限小于10,则你可选择一名角色。你令其摸一张牌,若其以此法得到的牌:与该角色的其他手牌花色均不相同,则你加1点体力上限,若你的体力上限小于10,则你可以重复此流程;否则你减1点体力上限,且其展示所有手牌。", + stianyi: "天翊", + stianyi_info: + "觉醒技,准备阶段,若场上的所有存活角色均于本局游戏内受到过伤害,则你加2点体力上限并回复1点体力,然后令一名角色获得技能〖佐幸〗。", + zuoxing: "佐幸", + zuoxing2: "佐幸", + zuoxing_info: + "出牌阶段限一次,若令你获得〖佐幸〗的角色存活且体力上限大于1,则你可以令其减1点体力上限,并视为使用一张普通锦囊牌。", + sghuishi: "辉逝", + sghuishi_info: + "限定技,出牌阶段,你可以选择一名其他角色:若其有未发动过的觉醒技,则你令其发动这些觉醒技时无视原有条件;否则其摸四张牌。然后你减2点体力上限。", + shen_taishici: "神太史慈", + shen_taishici_prefix: "神", + dulie: "笃烈", + dulie_info: + "锁定技。当你成为【杀】的目标时,若使用者的体力值大于你,则你进行判定。若结果为红桃,则取消此目标。", + tspowei: "破围", + tspowei_info: + "使命技。①游戏开始时,你令所有其他角色获得一个“围”。②一名角色受到伤害后,若其有“围”,则其移去“围”。③回合开始时,你选择所有有“围”的角色。这些角色失去“围”,然后这些角色的第一个不为你的下家获得等量的“围”。④一名其他角色的回合开始时,若其有“围”,则你可以选择一项:⒈弃置一张手牌并对其造成1点伤害。⒉若其体力值不大于你,则你获得其一张手牌。选择完成后,你视为在其攻击范围内直到回合结束。⑤使命:回合开始时,若场上没有“围”,则你获得技能〖神著〗。⑥失败:当你进入濒死状态时,你将体力值回复至1点,然后弃置装备区的所有牌。", + shenzhu: "神著", + shenzhu_info: + "锁定技,当你使用有对应实体牌的非转化【杀】结算结束后,你选择一项:①摸一张牌,且本回合使用【杀】的次数上限+1。②摸三张牌,且本回合不能再使用【杀】。", + dangmo: "荡魔", + dangmo_info: + "当你于出牌阶段内使用第一张【杀】选择目标后,你可以为此牌增加至多Y-1个目标(Y为你的体力值)。", + reshuishi: "慧识", + reshuishi_info: + "出牌阶段限一次。若你的体力上限小于10,你可进行判定牌不置入弃牌堆的判定。若判定结果与本次发动技能时的其他判定结果的花色均不相同且你的体力上限小于10,则你加1点体力上限,且可以重复此流程。然后你将所有位于处理区的判定牌交给一名角色。若其手牌数为全场最多,则你减1点体力上限。", + resghuishi: "辉逝", + resghuishi_info: + "限定技,出牌阶段,你可选择一名角色。若你的体力上限不小于存活人数且其有未发动的觉醒技,则你令其中一个技能无视发动条件;否则其摸四张牌。然后你减2点体力上限。", + qizhengxiangsheng: "奇正相生", + qizhengxiangsheng_info: + "出牌阶段,对一名其他角色使用。你将目标角色标记为“奇兵”或“正兵”(对其他角色不可见)。然后目标角色可以打出一张【杀】或【闪】。若其是“奇兵”且未打出【杀】,则你对其造成1点伤害;若其是“正兵”且未打出【闪】,则你获得其一张牌。", + shen_xunyu: "神荀彧", + shen_xunyu_prefix: "神", + tianzuo: "天佐", + tianzuo_info: "锁定技。①游戏开始时,你将8张【奇正相生】加入牌堆。②【奇正相生】对你无效。", + lingce: "灵策", + lingce_info: + "锁定技。当有【奇正相生】或智囊或〖定汉①〗记录过的锦囊牌被使用时,若此牌不为转化牌且对应实体牌数量为1,则你摸一张牌。", + dinghan: "定汉", + dinghan_info: + "①当你成为未记录过的普通锦囊牌的目标时,或有未记录过的延时锦囊牌进入你的判定区时,你记录此牌名并取消之。②准备阶段,你可在〖定汉①〗的记录中添加或减少一种锦囊牌的牌名。", + shen_sunce: "神孙策", + shen_sunce_prefix: "神", + yingba: "英霸", + yingba_info: + "①出牌阶段限一次,你可令一名体力上限大于1的其他角色减少1点体力上限并获得“平定”标记,然后你减少1点体力上限。②你对拥有“平定”标记的角色使用牌没有距离限制。", + scfuhai: "覆海", + scfuhai_info: + "锁定技。①当你使用牌指定目标后,若目标角色有“平定”标记,则其不可响应此牌。若你本回合内以此法得到的牌数小于2,则你摸一张牌。②拥有“平定”标记的角色死亡时,你增加X点体力上限并摸X张牌。(X为其拥有的“平定”标记数)。", + pinghe: "冯河", + pinghe_info: + "锁定技。①你的手牌上限基数等于你已损失的体力值。②当你受到其他角色造成的伤害时,若你有牌且你的体力上限大于1,则你防止此伤害,减1点体力上限并将一张手牌交给一名其他角色。然后若你拥有〖英霸〗,则伤害来源获得一个“平定”标记。", + shen_jiangwei: "神姜维", + shen_jiangwei_prefix: "神", + jiufa: "九伐", + jiufa_info: + "①当你声明使用牌后或打出牌时,你记录此牌的牌名。②当你使用或打出的牌结算结束后,若你的〖九伐〗记录中包含至少⑨种不同的牌名,则你可以亮出牌堆顶的⑨张牌,选择并获得其中任意张点数各不相同且{这九张牌中存在未被选择且和已选择的牌点数相同}的牌,清除所有的记录,将其余牌置入弃牌堆。", + tianren: "天任", + tianren_info: + "锁定技。①当有一张基本牌或普通锦囊牌不因使用而进入弃牌堆后,你获得一枚“天任”标记。②当你获得“天任”标记或体力上限变化后,若你的“天任”数不小于X,则你移去X枚“天任”,加1点体力上限并摸两张牌(X为你的体力上限)。", + pingxiang: "平襄", + pingxiang_info: + "限定技。出牌阶段,若你的体力上限大于⑨,则你可减⑨点体力上限,视为使用至多⑨张火【杀】,然后失去〖九伐〗,并将手牌上限基数改为体力上限直到游戏结束。", + shen_sunquan: "神孙权", + shen_sunquan_prefix: "神", + dili: "帝力", + dili_info: + '锁定技。游戏开始时,你随机获得一条东吴命运线。', + yuheng: "驭衡", + yuheng_info: + '①出牌阶段限一次。你可以失去所有不为〖驭衡〗的非锁定技,然后随机获得全部东吴命运线涉及的一个技能。若你本阶段内没有发动过其他非锁定技,则你随机获得当前东吴命运线涉及的一个内容。②出牌阶段结束时,若你未于本阶段内发动过〖驭衡①〗,则你失去1点体力。', + yuheng_append: '天下英雄谁敌手?曹刘。生子当如孙仲谋!', + dili_shengzhi: "圣质", + dili_shengzhi_info: + "锁定技。若你因〖驭衡〗获得过〖英魂〗〖弘德〗〖秉壹〗,则当你使用点数为质数的牌时,此牌不可被响应。", + dili_chigang: "持纲", + dili_chigang_info: + "锁定技。若你因〖驭衡〗获得过〖观微〗〖弼政〗〖安国〗,则当你的判定阶段开始前,你跳过此阶段并获得一个额外的摸牌阶段。", + dili_qionglan: "穹览", + dili_qionglan_info: + '锁定技,限定技。若你因〖驭衡〗获得过〖涉猎〗〖问卦〗〖博图〗,则当你发动的〖驭衡〗结算结束后,你随机获得两条其他东吴命运线。', + dili_quandao: "权道", + dili_quandao_info: + "锁定技。若你因〖驭衡〗获得过〖制衡〗〖诫训〗〖安恤〗,则你手牌区内点数为字母的牌的牌名视为【调剂盐梅】。", + dili_jiaohui: "交辉", + dili_jiaohui_info: + "锁定技。若你因〖驭衡〗获得过〖下书〗〖结姻〗〖缔盟〗,且你的手牌数为1,则此牌的牌名视为【远交近攻】。", + dili_yuanlv: "渊虑", + dili_yuanlv_info: + "锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜江〗,则当你成为自己使用的不为【长安大舰】的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。", + changandajian_equip1: "长安大舰", + changandajian_equip2: "长安大舰", + changandajian_equip3: "长安大舰", + changandajian_equip4: "长安大舰", + changandajian_equip5: "长安大舰", + changandajian_equip6: "长安大舰", + changandajian_destroy: "长安大舰", + changandajian_equip1_info: + "锁定技。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + changandajian_equip2_info: + "锁定技。当你失去装备区内的【长安大舰】后,你销毁之并回复1点体力。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + changandajian_equip3_info: + "锁定技。其他角色至你的距离+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + changandajian_equip4_info: + "锁定技。你至其他角色的距离-2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + changandajian_equip5_info: + "锁定技。你的手牌上限+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + changandajian_equip6_info: + "锁定技。你至其他角色的距离-2,其他角色至你的距离+2。当你失去装备区内的【长安大舰】后,你销毁之。然后你选择场上的一张牌。若此牌点数为字母,则你获得之,否则弃置之。", + shen_machao: "神马超", + shen_machao_prefix: "神", + shouli: "狩骊", + shouli_backup: "狩骊", + shouli_info: + "①锁定技,游戏开始时,你令场上所有角色从你的下家起,依次使用牌堆中的一张不为赠物的坐骑牌。②你可以将场上的一张进攻坐骑牌当做【杀】(无任何次数限制),防御坐骑牌当做【闪】使用或打出。若此坐骑牌的拥有者不为你,则其非锁定技于本回合内失效。且当你或其于本回合内受到伤害时,此伤害+1且改为雷属性。", + hengwu: "横骛", + hengwu_info: + "当你使用或打出有花色的牌时,若你的手牌区内没有与此牌花色相同的牌,则你可以摸X张牌(X为场上装备区内花色与此牌相同的牌数)。", + hengwu_append: '棘手,怀念,摧毁!', - key_kagari:'篝', - kagari_zongsi:'纵丝', - kagari_zongsi_info:'出牌阶段限一次,你可以选择一张不在游戏外的牌,然后将其置于牌堆/弃牌堆的顶部/底部或一名角色的对应区域内。', - key_shiki:'神山识', - key_shiki_ab:'神山识', - shiki_omusubi:'御结', - shiki_omusubi_info:'一轮游戏开始时,你可以减1点体力上限,然后将一名其他角色武将牌上的技能加入到你的武将牌上。', - shiki_omusubi_append:'来吧,羽依里。用你的手,让我变成那只真正的鬼吧!', - db_key_hina:'佐藤雏', - hina_shenshi:'神视', - hina_shenshi_yingbian:'神视', - hina_shenshi_info:'神势力技。出牌阶段开始时/结束时,你可摸两张牌,然后将其中一张牌置于牌堆顶。你以此法得到的牌视为拥有全部应变效果,且可以无条件发动。', - hina_xingzhi:'幸凪', - hina_xingzhi_info:'键势力技。每回合限一次,你可以通过“助战”触发一张牌的全部应变效果,且响应助战的角色摸两张牌。', - tw_shen_guanyu:'TW神关羽', - tw_shen_guanyu_prefix:'TW神', - twwushen:'武神', - twwushen_info:'锁定技。①你的♥手牌均视为普【杀】。②你于每阶段使用的第一张【杀】不可被响应。③你使用♥【杀】无距离和次数限制。④当你使用♥【杀】选择目标后,你令所有拥有“梦魇”标记的角色均成为此【杀】的目标。', - twwuhun:'武魂', - twwuhun_info:'锁定技。①当你受到其他角色造成的1点伤害后,你令伤害来源获得1枚“梦魇”标记。②当你对有“梦魇”标记的其他角色造成伤害后,你令其获得一枚“梦魇”标记。③当你死亡时,你可进行判定。若结果不为【桃】或【桃园结义】,则你选择至少一名拥有“梦魇”标记的角色。令这些角色各自失去X点体力(X为其“梦魇”标记数)。', - shen_zhangfei:'神张飞', - shen_zhangfei_prefix:'神', - shencai:'神裁', - shencai_info:'出牌阶段限一次,你可以令一名其他角色进行判定。你获得此判定牌,然后若此判定牌:包含以下要素中的任意一个,则其失去已有的下列效果,并获得对应的效果:{⒈体力:当其受到伤害后,其失去等量的体力、⒉武器:其不能使用牌响应【杀】、⒊打出:当其失去手牌后,其再随机弃置一张手牌(不嵌套触发)、⒋距离:其的结束阶段开始时,其翻面};若均不包含,你获得其区域里的一张牌,其获得一枚“死”并获得如下效果:其的角色手牌上限-X、其的回合结束时,若X大于场上存活人数,则其死亡(X为其“死”标记数)。', - xunshi:'巡使', - xunshi_info:'锁定技。①你手牌区内所有的多目标锦囊牌均视为花色为none的普【杀】。②你使用颜色为none的牌无距离和次数限制。③当你使用无颜色的牌选择目标后,你令你的〖神裁〗的发动次数上限+1(至多为5),然后可以为此牌增加任意个目标。', - shen_zhangjiao:'神张角', - shen_zhangjiao_prefix:'神', - yizhao:'异兆', - yizhao_info:'锁定技。当你使用或打出牌时,你获得等同于此牌点数枚“黄”标记。然后若“黄”的十位数发生变化,你获得牌堆中一张点数为你“黄”的十位数的牌。', - sijun:'肆军', - sijun_info:'准备阶段,若“黄”数大于牌堆的牌数,你可以移去所有“黄”并洗牌,然后随机获得任意张点数之和为36的牌。', - sanshou:'三首', - sanshou_info:'当你受到伤害时,你可以亮出牌堆顶三张牌。若其中有本回合未被使用过的牌的类型,防止此伤害。', - tianjie:'天劫', - tianjie_info:'一名角色的回合结束时,若本回合牌堆洗过牌,你可以选择至多三名其他角色。你依次对每名目标角色造成X点雷电伤害(X为其手牌中【闪】的数量,至少为1)。', - tw_shen_lvmeng:'TW神吕蒙', - tw_shen_lvmeng_prefix:'TW神', - twshelie:'涉猎', - twshelie_info:'①摸牌阶段,你可放弃摸牌并亮出牌堆顶的五张牌,然后选择获得其中每种花色的牌各一张。②每轮限一次。结束阶段,若你本回合使用的花色数不小于你的体力值,你执行一个额外的摸牌阶段或出牌阶段。', - twgongxin:'攻心', - twgongxin2:'攻心', - twgongxin_info:'出牌阶段限一次。你可以观看一名其他角色的手牌,然后你可以展示其中一张牌并选择一项:1.弃置此牌;2.将此牌置于牌堆顶。若该角色手牌中的花色数因此减少,你选择一种颜色,其于本回合不能使用或打出该颜色的牌。', - shen_dengai:'神邓艾', - shen_dengai_prefix:'神', - dctuoyu:'拓域', - dctuoyu_fengtian:'丰田', - dctuoyu_qingqu:'清渠', - dctuoyu_junshan:'峻山', - dctuoyu_fengtian_tag:'丰田', - dctuoyu_qingqu_tag:'清渠', - dctuoyu_junshan_tag:'峻山', - dctuoyu_info:'①锁定技。当你使用拥有对应副区域标签的牌时,你令此牌获得对应效果。
              丰田:伤害值或回复值+1;清渠:无次数和距离限制;峻山:不可被响应。②出牌阶段开始时和结束时,你给你的手牌分配对应的已激活副区域标签(每个区域至多五张)。', - dcxianjin:'险进', - dcxianjin_info:'锁定技。当你每造成或受到两次伤害后,你激活一个副区域标签并摸X张牌(X为你已激活的副区域数,若你的手牌数为全场最多则改为摸一张牌)。', - dcqijing:'奇径', - dcqijing_info:'觉醒技。一名角色的回合结束后,若你的三个副区域标签均被激活,则你减1点体力上限,获得〖摧心〗,将座位移动至两名相邻的其他角色之间并执行一个额外回合。', - dccuixin:'摧心', - dccuixin_info:'当你不因此技能使用的基本牌或普通锦囊牌结算结束后,若此牌的目标于你使用此牌指定第一个目标时包含你的上家或下家,则你可以视为对下家或上家再使用一张牌名和元素相同的牌。', - shen_dianwei:'神典韦', - shen_dianwei_prefix:'神', - juanjia:'捐甲', - juanjia_info:'锁定技。游戏开始时,你废除一个防具栏,然后获得一个额外的武器栏。', - qiexie:'挈挟', - qiexie_info:'锁定技。准备阶段,你在剩余武将牌堆中随机观看五张牌,选择其中的任意张,将其按照如下规则转化为武器牌置入你的武器栏:{⒈此牌不具有花色,且其攻击范围和点数等于此武将牌的体力上限。⒉此武器牌的技能为该武将牌上所有描述中包含“【杀】”且不具有锁定技以外的标签的技能。⒊此武器牌离开你的装备区时,改为放回武将牌堆。}', - cuijue:'摧决', - cuijue_info:'每回合每名角色限一次。出牌阶段,你可以弃置一张牌,然后对攻击范围内距离最远的一名其他角色造成1点伤害(没有则不选)。', - le_shen_jiaxu:'神贾诩', - le_shen_jiaxu_prefix:'神', - jxlianpo:'炼魄', - jxlianpo_info:'锁定技。①若场上最大阵营为:反贼,其他角色的手牌上限-1,所有角色使用【杀】的次数上限和攻击范围+1;主忠,其他角色不能对其以外的角色使用【桃】。其他角色死亡后,若有多个最大阵营,来源摸两张牌并回复1点体力。②一轮游戏开始时,你展示一张未加入游戏或已死亡角色的身份牌,本轮视为该身份对应阵营的角色数+1。', - jxzhaoluan:'兆乱', - jxzhaoluan_info:'限定技。一名角色死亡前,若其此次进入过濒死状态,你可以取消之,令其加3点体力上限并失去所有非锁定技,回复体力至3点,摸四张牌。然后你获得如下效果:出牌阶段,你可以令一名成为过你〖兆乱〗目标的角色减1点体力上限,然后对一名此阶段未以此法选择过的角色造成1点伤害。', - shen_huatuo:'神华佗', - shen_huatuo_prefix:'神', - wuling:'五灵', - wuling_info:'①出牌阶段限两次。你可以选择一名没有“五禽戏”的角色,按照你选择的顺序向其传授“五禽戏”,且其获得如下效果:其获得你选择的第一种“五禽戏”的效果,并在其每个准备阶段移除当前“五禽戏”的效果并切换为下一种。②当你死亡时,你令场上的角色失去你传授的“五禽戏”。', - wuling_wuqinxi:'五禽戏', - wuling_wuqinxi_info:'
            • “五禽戏”分为“虎、鹿、熊、猿、鹤”五个不同的效果:'+ - '
            • 虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。'+ - '
            • 鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。'+ - '
            • 熊:每回合限一次,当你受到伤害时,此伤害-1。'+ - '
            • 猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。'+ - '
            • 鹤:当你获得此效果时,你摸三张牌。', - youyi:'游医', - youyi_info:'①弃牌阶段结束时,你可以将所有于此阶段弃置的牌置入仁区。②出牌阶段限一次。你可以将仁区的所有牌置入弃牌堆,令所有角色各回复1点体力。', - shen_lusu:'神鲁肃', - shen_lusu_prefix:'神', - dingzhou:'定州', - dingzhou_info:'出牌阶段限一次。你可以将X张牌交给一名场上有牌的角色,然后你获得其场上的所有牌(X为其场上的牌数+1)。', - tamo:'榻谟', - tamo_info:'游戏开始时,你可以重新分配除主公外所有角色的座次。', - zhimeng:'智盟', - zhimeng_info:'回合结束后,你可以与一名其他角色将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。', - shen_xuzhu:'神许褚', - shen_xuzhu_prefix:'神', - zhengqing:'争擎', - zhengqing_info:'锁定技。一轮游戏开始时,你移去所有角色的“擎”标记,令上一轮于一回合内造成伤害值最多的角色各获得X枚“擎”,且你与这些角色各摸一张牌(X为这些角色该回合内造成的伤害值)。若该角色为你且本次获得的“擎”数为本局游戏最多的一次,你改为摸X张牌(至多摸五张)。', - zhuangpo:'壮魄', - zhuangpo_info:'你可以将牌名为【杀】或牌面信息中包含“【杀】”的牌当【决斗】使用,然后你获得如下效果:1.当此【决斗】指定目标后,若你有“擎”,你可以移去任意枚“擎”,令目标角色弃置等量的牌;2.当你造成渠道为此牌的伤害时,若此牌的所有目标角色中存在有“擎”的角色,此伤害+1。', + key_kagari: "篝", + kagari_zongsi: "纵丝", + kagari_zongsi_info: + "出牌阶段限一次,你可以选择一张不在游戏外的牌,然后将其置于牌堆/弃牌堆的顶部/底部或一名角色的对应区域内。", + key_shiki: "神山识", + key_shiki_ab: "神山识", + shiki_omusubi: "御结", + shiki_omusubi_info: + "一轮游戏开始时,你可以减1点体力上限,然后将一名其他角色武将牌上的技能加入到你的武将牌上。", + shiki_omusubi_append: + '来吧,羽依里。用你的手,让我变成那只真正的鬼吧!', + db_key_hina: "佐藤雏", + hina_shenshi: "神视", + hina_shenshi_yingbian: "神视", + hina_shenshi_info: + "神势力技。出牌阶段开始时/结束时,你可摸两张牌,然后将其中一张牌置于牌堆顶。你以此法得到的牌视为拥有全部应变效果,且可以无条件发动。", + hina_xingzhi: "幸凪", + hina_xingzhi_info: + "键势力技。每回合限一次,你可以通过“助战”触发一张牌的全部应变效果,且响应助战的角色摸两张牌。", + tw_shen_guanyu: "TW神关羽", + tw_shen_guanyu_prefix: "TW神", + twwushen: "武神", + twwushen_info: + "锁定技。①你的♥手牌均视为普【杀】。②你于每阶段使用的第一张【杀】不可被响应。③你使用♥【杀】无距离和次数限制。④当你使用♥【杀】选择目标后,你令所有拥有“梦魇”标记的角色均成为此【杀】的目标。", + twwuhun: "武魂", + twwuhun_info: + "锁定技。①当你受到其他角色造成的1点伤害后,你令伤害来源获得1枚“梦魇”标记。②当你对有“梦魇”标记的其他角色造成伤害后,你令其获得一枚“梦魇”标记。③当你死亡时,你可进行判定。若结果不为【桃】或【桃园结义】,则你选择至少一名拥有“梦魇”标记的角色。令这些角色各自失去X点体力(X为其“梦魇”标记数)。", + shen_zhangfei: "神张飞", + shen_zhangfei_prefix: "神", + shencai: "神裁", + shencai_info: + "出牌阶段限一次,你可以令一名其他角色进行判定。你获得此判定牌,然后若此判定牌:包含以下要素中的任意一个,则其失去已有的下列效果,并获得对应的效果:{⒈体力:当其受到伤害后,其失去等量的体力、⒉武器:其不能使用牌响应【杀】、⒊打出:当其失去手牌后,其再随机弃置一张手牌(不嵌套触发)、⒋距离:其的结束阶段开始时,其翻面};若均不包含,你获得其区域里的一张牌,其获得一枚“死”并获得如下效果:其的角色手牌上限-X、其的回合结束时,若X大于场上存活人数,则其死亡(X为其“死”标记数)。", + xunshi: "巡使", + xunshi_info: + "锁定技。①你手牌区内所有的多目标锦囊牌均视为花色为none的普【杀】。②你使用颜色为none的牌无距离和次数限制。③当你使用无颜色的牌选择目标后,你令你的〖神裁〗的发动次数上限+1(至多为5),然后可以为此牌增加任意个目标。", + shen_zhangjiao: "神张角", + shen_zhangjiao_prefix: "神", + yizhao: "异兆", + yizhao_info: + "锁定技。当你使用或打出牌时,你获得等同于此牌点数枚“黄”标记。然后若“黄”的十位数发生变化,你获得牌堆中一张点数为你“黄”的十位数的牌。", + sijun: "肆军", + sijun_info: + "准备阶段,若“黄”数大于牌堆的牌数,你可以移去所有“黄”并洗牌,然后随机获得任意张点数之和为36的牌。", + sanshou: "三首", + sanshou_info: + "当你受到伤害时,你可以亮出牌堆顶三张牌。若其中有本回合未被使用过的牌的类型,防止此伤害。", + tianjie: "天劫", + tianjie_info: + "一名角色的回合结束时,若本回合牌堆洗过牌,你可以选择至多三名其他角色。你依次对每名目标角色造成X点雷电伤害(X为其手牌中【闪】的数量,至少为1)。", + tw_shen_lvmeng: "TW神吕蒙", + tw_shen_lvmeng_prefix: "TW神", + twshelie: "涉猎", + twshelie_info: + "①摸牌阶段,你可放弃摸牌并亮出牌堆顶的五张牌,然后选择获得其中每种花色的牌各一张。②每轮限一次。结束阶段,若你本回合使用的花色数不小于你的体力值,你执行一个额外的摸牌阶段或出牌阶段。", + twgongxin: "攻心", + twgongxin2: "攻心", + twgongxin_info: + "出牌阶段限一次。你可以观看一名其他角色的手牌,然后你可以展示其中一张牌并选择一项:1.弃置此牌;2.将此牌置于牌堆顶。若该角色手牌中的花色数因此减少,你选择一种颜色,其于本回合不能使用或打出该颜色的牌。", + shen_dengai: "神邓艾", + shen_dengai_prefix: "神", + dctuoyu: "拓域", + dctuoyu_fengtian: "丰田", + dctuoyu_qingqu: "清渠", + dctuoyu_junshan: "峻山", + dctuoyu_fengtian_tag: '丰田', + dctuoyu_qingqu_tag: '清渠', + dctuoyu_junshan_tag: '峻山', + dctuoyu_info: + "①锁定技。当你使用拥有对应副区域标签的牌时,你令此牌获得对应效果。
              丰田:伤害值或回复值+1;清渠:无次数和距离限制;峻山:不可被响应。②出牌阶段开始时和结束时,你给你的手牌分配对应的已激活副区域标签(每个区域至多五张)。", + dcxianjin: "险进", + dcxianjin_info: + "锁定技。当你每造成或受到两次伤害后,你激活一个副区域标签并摸X张牌(X为你已激活的副区域数,若你的手牌数为全场最多则改为摸一张牌)。", + dcqijing: "奇径", + dcqijing_info: + "觉醒技。一名角色的回合结束后,若你的三个副区域标签均被激活,则你减1点体力上限,获得〖摧心〗,将座位移动至两名相邻的其他角色之间并执行一个额外回合。", + dccuixin: "摧心", + dccuixin_info: + "当你不因此技能使用的基本牌或普通锦囊牌结算结束后,若此牌的目标于你使用此牌指定第一个目标时包含你的上家或下家,则你可以视为对下家或上家再使用一张牌名和元素相同的牌。", + shen_dianwei: "神典韦", + shen_dianwei_prefix: "神", + juanjia: "捐甲", + juanjia_info: "锁定技。游戏开始时,你废除一个防具栏,然后获得一个额外的武器栏。", + qiexie: "挈挟", + qiexie_info: + "锁定技。准备阶段,你在剩余武将牌堆中随机观看五张牌,选择其中的任意张,将其按照如下规则转化为武器牌置入你的武器栏:{⒈此牌不具有花色,且其攻击范围和点数等于此武将牌的体力上限。⒉此武器牌的技能为该武将牌上所有描述中包含“【杀】”且不具有锁定技以外的标签的技能。⒊此武器牌离开你的装备区时,改为放回武将牌堆。}", + cuijue: "摧决", + cuijue_info: + "每回合每名角色限一次。出牌阶段,你可以弃置一张牌,然后对攻击范围内距离最远的一名其他角色造成1点伤害(没有则不选)。", + le_shen_jiaxu: "神贾诩", + le_shen_jiaxu_prefix: "神", + jxlianpo: "炼魄", + jxlianpo_info: + "锁定技。①若场上最大阵营为:反贼,其他角色的手牌上限-1,所有角色使用【杀】的次数上限和攻击范围+1;主忠,其他角色不能对其以外的角色使用【桃】。其他角色死亡后,若有多个最大阵营,来源摸两张牌并回复1点体力。②一轮游戏开始时,你展示一张未加入游戏或已死亡角色的身份牌,本轮视为该身份对应阵营的角色数+1。", + jxzhaoluan: "兆乱", + jxzhaoluan_info: + "限定技。一名角色死亡前,若其此次进入过濒死状态,你可以取消之,令其加3点体力上限并失去所有非锁定技,回复体力至3点,摸四张牌。然后你获得如下效果:出牌阶段,你可以令一名成为过你〖兆乱〗目标的角色减1点体力上限,然后对一名此阶段未以此法选择过的角色造成1点伤害。", + shen_huatuo: "手杀神华佗", + shen_huatuo_prefix: "手杀神", + wuling: "五灵", + wuling_info: + "①出牌阶段限两次。你可以选择一名没有“五禽戏”的角色,按照你选择的顺序向其传授“五禽戏”,且其获得如下效果:其获得你选择的第一种“五禽戏”的效果,并在其每个准备阶段移除当前“五禽戏”的效果并切换为下一种。②当你死亡时,你令场上的角色失去你传授的“五禽戏”。", + wuling_wuqinxi: "五禽戏", + wuling_wuqinxi_info: + "
            • “五禽戏”分为“虎、鹿、熊、猿、鹤”五个不同的效果:" + + "
            • 虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。" + + "
            • 鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。" + + "
            • 熊:每回合限一次,当你受到伤害时,此伤害-1。" + + "
            • 猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。" + + "
            • 鹤:当你获得此效果时,你摸三张牌。", + youyi: "游医", + youyi_info: + "①弃牌阶段结束时,你可以将所有于此阶段弃置的牌置入仁区。②出牌阶段限一次。你可以将仁区的所有牌置入弃牌堆,令所有角色各回复1点体力。", + shen_lusu: "神鲁肃", + shen_lusu_prefix: "神", + dingzhou: "定州", + dingzhou_info: + "出牌阶段限一次。你可以将X张牌交给一名场上有牌的角色,然后你获得其场上的所有牌(X为其场上的牌数+1)。", + tamo: "榻谟", + tamo_info: + "游戏开始时,你可以重新分配除主公外所有角色的座次。", + tamo_info_doudizhu: + "游戏开始时,你可以重新分配除主公和三号位外所有角色的座次。", + tamo_faq: "FAQ", + tamo_faq_info: + "
            • Q:在一号位不为主公的情况下,〖榻谟〗如何结算?
            • A:该角色可以正常进行座次交换。若受此技能影响导致一号位角色发生了变化,则以排列后的一号位角色为起始角色开始本局游戏。
            • ", + zhimeng: "智盟", + zhimeng_info_identity: '回合结束后,你可以选择一名其他角色。若如此做,你与其将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。', + zhimeng_info: '回合结束后,你可以选择一名手牌数不大于Y的其他角色(Y为你的手牌数+1)。若如此做,你与其将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。', + shen_xuzhu: "神许褚", + shen_xuzhu_prefix: "神", + zhengqing: "争擎", + zhengqing_info: + "锁定技。一轮游戏开始时,你移去所有角色的“擎”标记,令上一轮于一回合内造成伤害值最多的角色各获得X枚“擎”,且你与这些角色各摸一张牌(X为这些角色该回合内造成的伤害值)。若该角色为你且本次获得的“擎”数为本局游戏最多的一次,你改为摸X张牌(至多摸五张)。", + zhuangpo: "壮魄", + zhuangpo_info: + "你可以将牌名为【杀】或牌面信息中包含“【杀】”的牌当【决斗】使用,然后你获得如下效果:1.当此【决斗】指定目标后,若你有“擎”,你可以移去任意枚“擎”,令目标角色弃置等量的牌;2.当你造成渠道为此牌的伤害时,若此牌的所有目标角色中存在有“擎”的角色,此伤害+1。", + dc_shen_huatuo: "神华佗", + dc_shen_huatuo_prefix: "神", + jingyu: "静域", + jingyu_info: "锁定技。每个技能每轮限一次,当一名角色发动不为〖静域〗的技能时,你摸一张牌。", + lvxin: "滤心", + lvxin_info: + "出牌阶段限一次。你可以交给一名其他角色一张手牌并选择一项:⒈令其摸X张牌;⒉令其随机弃置X张手牌(X为游戏轮数,至多为5)。然后若其以此法得到/弃置了与你交给其的牌牌名相同的牌,其于其下次发动技能时回复/失去1点体力。", + huandao: "寰道", + huandao_info: + "限定技。出牌阶段,你可以选择一名其他角色。你令其复原武将牌,系统随机生成一个与其同名的武将的武将牌上的一个与其拥有的技能均不同名的技能。其可以选择获得此技能,然后选择失去一个其他技能。", - extra_feng:'神话再临·风', - extra_huo:'神话再临·火', - extra_lin:'神话再临·林', - extra_shan:'神话再临·山', - extra_yin:'神话再临·阴', - extra_lei:'神话再临·雷', - extra_key:'论外', - extra_ol:'神话再临OL', - extra_mobilezhi:'始计篇·智', - extra_mobilexin:'始计篇·信', - extra_mobileren:'始计篇·仁', - extra_offline:'神话再临·线下', - extra_decade:'神·武', - extra_tw:'海外服神将', + extra_feng: "神话再临·风", + extra_huo: "神话再临·火", + extra_lin: "神话再临·林", + extra_shan: "神话再临·山", + extra_yin: "神话再临·阴", + extra_lei: "神话再临·雷", + extra_key: "论外", + extra_ol: "神话再临OL", + extra_mobilezhi: "始计篇·智", + extra_mobilexin: "始计篇·信", + extra_mobileren: "始计篇·仁", + extra_offline: "神话再临·线下", + extra_decade: "神·武", + extra_tw: "海外服神将", }, }; }); diff --git a/character/gujian.js b/character/gujian.js index e066e6d8a..4585eab0c 100644 --- a/character/gujian.js +++ b/character/gujian.js @@ -1,870 +1,956 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'gujian', - character:{ - gjqt_bailitusu:['male','shu',4,['xuelu','fanshi','shahun']], - gjqt_fengqingxue:['female','wu',3,['qinglan','yuehua','swd_wuxie']], - gjqt_xiangling:['female','wu',3,['xlqianhuan','meihu','xidie']], - gjqt_fanglansheng:['male','wu',3,['fanyin','mingkong','fumo']], - gjqt_yinqianshang:['male','qun',4,['zuiji','zuizhan']], - gjqt_hongyu:['female','shu',4,['jianwu','meiying']], + name: "gujian", + character: { + gjqt_bailitusu: ["male", "shu", 4, ["xuelu", "fanshi", "shahun"]], + gjqt_fengqingxue: ["female", "wu", 3, ["qinglan", "yuehua", "swd_wuxie"]], + gjqt_xiangling: ["female", "wu", 3, ["xlqianhuan", "meihu", "xidie"]], + gjqt_fanglansheng: ["male", "wu", 3, ["fanyin", "mingkong", "fumo"]], + gjqt_yinqianshang: ["male", "qun", 4, ["zuiji", "zuizhan"]], + gjqt_hongyu: ["female", "shu", 4, ["jianwu", "meiying"]], - gjqt_yuewuyi:['male','wei',4,['yanjia','xiuhua','liuying']], - gjqt_wenrenyu:['female','shu',4,['chizhen','dangping']], - gjqt_xiayize:['male','qun',3,['xuanning','liuguang','yangming']], - gjqt_aruan:['female','wu',3,['zhaolu','jiehuo','yuling']], + gjqt_yuewuyi: ["male", "wei", 4, ["yanjia", "xiuhua", "liuying"]], + gjqt_wenrenyu: ["female", "shu", 4, ["chizhen", "dangping"]], + gjqt_xiayize: ["male", "qun", 3, ["xuanning", "liuguang", "yangming"]], + gjqt_aruan: ["female", "wu", 3, ["zhaolu", "jiehuo", "yuling"]], - gjqt_xunfang:['female','shu',3,['manwu','xfanghua']], - gjqt_ouyangshaogong:['male','shu',3,['yunyin','shishui','duhun']], + gjqt_xunfang: ["female", "shu", 3, ["manwu", "xfanghua"]], + gjqt_ouyangshaogong: ["male", "shu", 3, ["yunyin", "shishui", "duhun"]], - gjqt_xieyi:['male','qun',3,['lingyan','xunjian','humeng']], - gjqt_yanjiaxieyi:['male','qun',2,['xianju'],['unseen']], - gjqt_chuqi:['male','qun',2,['xuanci'],['unseen']], + gjqt_xieyi: ["male", "qun", 3, ["lingyan", "xunjian", "humeng"]], + gjqt_yanjiaxieyi: ["male", "qun", 2, ["xianju"], ["unseen"]], + gjqt_chuqi: ["male", "qun", 2, ["xuanci"], ["unseen"]], // gjqt_xuange:['male','qun',4,['zhenlu','zhuixing']], - gjqt_beiluo:['male','qun',4,['lingnu','zhenying','cihong']], - gjqt_yunwuyue:['female','wei',3,['yange','woxue','lianjing']], - gjqt_cenying:['female','shu',3,['yunyou','xuanzhen','qingshu']], + gjqt_beiluo: ["male", "qun", 4, ["lingnu", "zhenying", "cihong"]], + gjqt_yunwuyue: ["female", "wei", 3, ["yange", "woxue", "lianjing"]], + gjqt_cenying: ["female", "shu", 3, ["yunyou", "xuanzhen", "qingshu"]], // gjqt_changliu:['male','qun',4,['xiange']], // gjqt_fenglishuang:['female','wei',3,[]], // gjqt_nishang:[], }, - characterIntro:{ - gjqt_bailitusu:'原名韩云溪,太子长琴半身。幼时经历灭族之灾,本来已死去,但因体内被封进了太子长琴一半魂魄而得以死而复生。身怀凶剑焚寂的煞气,在某次煞气发作中被紫胤真人所救,后拜入昆仑山天墉城,以“屠绝鬼气,苏醒人魂”之意更名为“百里屠苏”。', - gjqt_fengqingxue:'来自幽暗无边的地界,大哥为幽都娲皇神殿“十巫”之一的巫咸——风广陌。奉命寻兄而来到人间,邂逅百里屠苏,陷入了焚寂的宿命纠葛。后与百里屠苏相知相爱。终局,百里屠苏化为永世无法轮回的荒魂,她为寻找重生之法,放弃自己的轮回,换取下长久的寿命,在人间执着不悔地寻觅了九百年。最后,与重生后的屠苏回到桃花谷相守。', - gjqt_xiangling:'青丘之国国主九尾天狐与人界女子所生,半人半妖。由南疆紫榕林榕爷爷抚养,在山林间无拘无束长大,娇俏可爱。后来下江南寻找生母,却被抓进翻云寨,偶然被百里屠苏相救,为报答救命之恩,便一直跟随百里屠苏。在漫漫征途中成长起来,变得成熟懂事。得知方兰生对自己的感情,十分矛盾,后来终于错过。最后结局,启程前往青丘之国。', - gjqt_fanglansheng:'家住琴川的一介书生,家境殷实,母亲在家常住庵堂,吃斋念佛,父亲虽是琴川附近某间寺庙的住持,但却比商人还会敛财。跟随父亲学过降妖除鬼的佛家法术,并以此自傲。梦想能找一个娇小可爱,温柔美丽的女子共渡此生。对襄铃一见钟情。', - gjqt_yinqianshang:'原名风广陌,是幽都“十巫”之一的巫咸。奉女娲之命前往乌蒙灵谷增强焚寂封印。但因为欧阳少恭与雷严的争夺关系,他受到焚寂之力力量冲击,失去记忆,后为欧阳少恭所救。尹千觞为了报恩,跟随在百里屠苏等人身边监视。在这个过程中,他慢慢恢复过往的记忆。后为阻止欧阳少恭,随众人前往蓬莱决战。最后,对曾给予他一次重生的欧阳少恭以死相陪,一起归于火海。', - gjqt_hongyu:'上古庆枫族族人,紫胤真人的剑灵,宿体为古剑·红玉。在百里屠苏离开昆仑山天墉城后,奉命随行保护。终局之后,她依然回到了天墉城,陪伴在紫胤真人身边。', + characterIntro: { + gjqt_bailitusu: + "原名韩云溪,太子长琴半身。幼时经历灭族之灾,本来已死去,但因体内被封进了太子长琴一半魂魄而得以死而复生。身怀凶剑焚寂的煞气,在某次煞气发作中被紫胤真人所救,后拜入昆仑山天墉城,以“屠绝鬼气,苏醒人魂”之意更名为“百里屠苏”。", + gjqt_fengqingxue: + "来自幽暗无边的地界,大哥为幽都娲皇神殿“十巫”之一的巫咸——风广陌。奉命寻兄而来到人间,邂逅百里屠苏,陷入了焚寂的宿命纠葛。后与百里屠苏相知相爱。终局,百里屠苏化为永世无法轮回的荒魂,她为寻找重生之法,放弃自己的轮回,换取下长久的寿命,在人间执着不悔地寻觅了九百年。最后,与重生后的屠苏回到桃花谷相守。", + gjqt_xiangling: + "青丘之国国主九尾天狐与人界女子所生,半人半妖。由南疆紫榕林榕爷爷抚养,在山林间无拘无束长大,娇俏可爱。后来下江南寻找生母,却被抓进翻云寨,偶然被百里屠苏相救,为报答救命之恩,便一直跟随百里屠苏。在漫漫征途中成长起来,变得成熟懂事。得知方兰生对自己的感情,十分矛盾,后来终于错过。最后结局,启程前往青丘之国。", + gjqt_fanglansheng: + "家住琴川的一介书生,家境殷实,母亲在家常住庵堂,吃斋念佛,父亲虽是琴川附近某间寺庙的住持,但却比商人还会敛财。跟随父亲学过降妖除鬼的佛家法术,并以此自傲。梦想能找一个娇小可爱,温柔美丽的女子共渡此生。对襄铃一见钟情。", + gjqt_yinqianshang: + "原名风广陌,是幽都“十巫”之一的巫咸。奉女娲之命前往乌蒙灵谷增强焚寂封印。但因为欧阳少恭与雷严的争夺关系,他受到焚寂之力力量冲击,失去记忆,后为欧阳少恭所救。尹千觞为了报恩,跟随在百里屠苏等人身边监视。在这个过程中,他慢慢恢复过往的记忆。后为阻止欧阳少恭,随众人前往蓬莱决战。最后,对曾给予他一次重生的欧阳少恭以死相陪,一起归于火海。", + gjqt_hongyu: + "上古庆枫族族人,紫胤真人的剑灵,宿体为古剑·红玉。在百里屠苏离开昆仑山天墉城后,奉命随行保护。终局之后,她依然回到了天墉城,陪伴在紫胤真人身边。", - gjqt_yuewuyi:'成长于长安富商家庭。其养父曾是战功显赫的将军,退隐后从商,很快就富甲一方;其养母是精擅偃术的南疆天玄教偃女族传人,待无异一如己出般疼爱有加;无异的生父是捐毒大将兀火罗,亡母是一名中原女子,因此他具有一半胡人的血统。', - gjqt_wenrenyu:'出身于百草谷“天罡”部队。从小在军中生活的她见惯生死,拥有超越其年龄的沉着果敢,头脑冷静严谨,洞察力敏锐,性格大方爽快。', - gjqt_xiayize:'本为当朝圣元帝三子李焱,天资聪颖,勤奋好学,于道术一途颇具天赋。幼时体弱,因身世原因被太华山的诀微长老清和真人带走,从此过上了道家清修的生活。', - gjqt_aruan:'千年前,昭明崩裂损毁,剑心为神农所得,其将剑心植入用辟邪之骨所造之人,是为巫山神女。神女爱慕司幽,却始终得不到司幽回应,心绪起伏加速灵力散逸,不久后死去,司幽自责不已,失去踪迹。神女死后,剑心碎片落地生根,吸纳灵气变为露草,露草渐渐化为人形,形貌与巫山神女一样,而且保留了她零散的记忆,阿阮正是这些露草中的一个。当阿阮灵气耗尽就会重新变为露草,并失去人时的记忆,直到重新吸纳足够的灵力才能恢复人形。', + gjqt_yuewuyi: + "成长于长安富商家庭。其养父曾是战功显赫的将军,退隐后从商,很快就富甲一方;其养母是精擅偃术的南疆天玄教偃女族传人,待无异一如己出般疼爱有加;无异的生父是捐毒大将兀火罗,亡母是一名中原女子,因此他具有一半胡人的血统。", + gjqt_wenrenyu: + "出身于百草谷“天罡”部队。从小在军中生活的她见惯生死,拥有超越其年龄的沉着果敢,头脑冷静严谨,洞察力敏锐,性格大方爽快。", + gjqt_xiayize: + "本为当朝圣元帝三子李焱,天资聪颖,勤奋好学,于道术一途颇具天赋。幼时体弱,因身世原因被太华山的诀微长老清和真人带走,从此过上了道家清修的生活。", + gjqt_aruan: + "千年前,昭明崩裂损毁,剑心为神农所得,其将剑心植入用辟邪之骨所造之人,是为巫山神女。神女爱慕司幽,却始终得不到司幽回应,心绪起伏加速灵力散逸,不久后死去,司幽自责不已,失去踪迹。神女死后,剑心碎片落地生根,吸纳灵气变为露草,露草渐渐化为人形,形貌与巫山神女一样,而且保留了她零散的记忆,阿阮正是这些露草中的一个。当阿阮灵气耗尽就会重新变为露草,并失去人时的记忆,直到重新吸纳足够的灵力才能恢复人形。", - gjqt_xunfang:'蓬莱国公主,美丽善良,为欧阳少恭前世妻子,太子长琴转世后,巽芳为寻找丈夫来到中原。蓬莱人寿命虽长却终有极限,终究躲不过容颜老去。当巽芳找到分离多年后的少恭时,自惭形秽,不愿相认,她希望少恭心中的自己永远都是青春貌美,于是化名“寂桐”守护在其身旁。', - gjqt_ouyangshaogong:'前身为太子长琴,今生只有一半仙灵,另一半仙灵被铸进焚寂之中,成为焚寂剑灵。他在漫长时光中经历太多悲欢离合,渐渐迷失自我。后与蓬莱国公主巽芳相爱,度过一段美好时光。之后蓬莱毁于天灾,他误以为巽芳已死,便不再压抑内心的疯狂与憎恨,为逆天改命不惜一切。', + gjqt_xunfang: + "蓬莱国公主,美丽善良,为欧阳少恭前世妻子,太子长琴转世后,巽芳为寻找丈夫来到中原。蓬莱人寿命虽长却终有极限,终究躲不过容颜老去。当巽芳找到分离多年后的少恭时,自惭形秽,不愿相认,她希望少恭心中的自己永远都是青春貌美,于是化名“寂桐”守护在其身旁。", + gjqt_ouyangshaogong: + "前身为太子长琴,今生只有一半仙灵,另一半仙灵被铸进焚寂之中,成为焚寂剑灵。他在漫长时光中经历太多悲欢离合,渐渐迷失自我。后与蓬莱国公主巽芳相爱,度过一段美好时光。之后蓬莱毁于天灾,他误以为巽芳已死,便不再压抑内心的疯狂与憎恨,为逆天改命不惜一切。", - gjqt_xieyi:'偃术大师,流月城大祭司沈夜之徒。于偃术一途冠绝古今,其制造的偃甲精妙绝伦,为世人所称颂。男主角乐无异对其十分崇拜。曾任流月城破军祭司,精通偃术和法术,在一百年前寻找神剑昭明的西域之行中被沈夜捉拿回流月城,毁去记忆仅靠偃甲和蛊虫心脏跳动,并更名为初七,最终在巫山为抢救昭明剑心、保护乐无异被埋在坍塌的神女墓下。他以自己为原型制作,并放入自己部分记忆的偃甲人谢衣曾收乐无异为徒。', + gjqt_xieyi: + "偃术大师,流月城大祭司沈夜之徒。于偃术一途冠绝古今,其制造的偃甲精妙绝伦,为世人所称颂。男主角乐无异对其十分崇拜。曾任流月城破军祭司,精通偃术和法术,在一百年前寻找神剑昭明的西域之行中被沈夜捉拿回流月城,毁去记忆仅靠偃甲和蛊虫心脏跳动,并更名为初七,最终在巫山为抢救昭明剑心、保护乐无异被埋在坍塌的神女墓下。他以自己为原型制作,并放入自己部分记忆的偃甲人谢衣曾收乐无异为徒。", - gjqt_beiluo:'身负辟邪王族之血的大妖,辟邪先王玄戈的孪生兄弟。北洛幼时流落人界,从此便在那里长大。他对自己的血脉并无认同之感,常年抑制妖力,希望以“人”的身份留在人间。后因先王玄戈的逝世,即位为辟邪王', - gjqt_yunwuyue:'本体是一只魇兽,该族喜独居,以人的梦境为食,以精神力为长,被称为“最接近魔的妖族”。云无月幼时居住在有熊城旁的白梦泽,自幼便与轩辕黄帝的大将缙云结识,对缙云有着一种依赖和仰慕,深受缙云的影响,对人族以及其他生灵有感情,不忍看到眼前的生灵遭到痛苦,会加以援手。', - gjqt_cenying:'出身于一个颇有底蕴的大家族,性格开朗随和、温柔坚韧、心如琉璃。岑缨受到开明长辈的影响,自小多思善学,年纪不大却已经加入了博物学会,有时跟随师长在外游历,探寻更广阔的天地。', + gjqt_beiluo: + "身负辟邪王族之血的大妖,辟邪先王玄戈的孪生兄弟。北洛幼时流落人界,从此便在那里长大。他对自己的血脉并无认同之感,常年抑制妖力,希望以“人”的身份留在人间。后因先王玄戈的逝世,即位为辟邪王", + gjqt_yunwuyue: + "本体是一只魇兽,该族喜独居,以人的梦境为食,以精神力为长,被称为“最接近魔的妖族”。云无月幼时居住在有熊城旁的白梦泽,自幼便与轩辕黄帝的大将缙云结识,对缙云有着一种依赖和仰慕,深受缙云的影响,对人族以及其他生灵有感情,不忍看到眼前的生灵遭到痛苦,会加以援手。", + gjqt_cenying: + "出身于一个颇有底蕴的大家族,性格开朗随和、温柔坚韧、心如琉璃。岑缨受到开明长辈的影响,自小多思善学,年纪不大却已经加入了博物学会,有时跟随师长在外游历,探寻更广阔的天地。", }, - card:{ - yanjiadan_heart:{ - type:'jiguan', - cardcolor:'heart', - fullskin:true, - derivation:'gjqt_xieyi', - enable:true, - notarget:true, - content(){ - 'step 0' - var choice=null; - var targets=game.filterPlayer(function(current){ - return get.attitude(player,current)>0; + card: { + yanjiadan_heart: { + type: "jiguan", + cardcolor: "heart", + fullskin: true, + derivation: "gjqt_xieyi", + enable: true, + notarget: true, + content() { + "step 0"; + var choice = null; + var targets = game.filterPlayer(function (current) { + return get.attitude(player, current) > 0; }); - for(var i=0;i0; - })){ - choice='shatang'; + if ( + !choice && + game.hasPlayer(function (current) { + return ( + current.hp == 1 && + get.attitude(player, current) < 0 && + get.damageEffect(current, player, player, "fire") > 0 + ); + }) + ) { + choice = "shatang"; } - if(!choice){ - for(var i=0;i=0) return false; - if(current.hp==1&&eff<0) return true; - if(get.attitude(player,current)<0&&get.attitude(player,current.getNext()<0)&&get.attitude(player,current.getPrevious())<0){ - return true; - } - return false; - })){ - choice='shenhuofeiya'; + yanjiadan_diamond: { + type: "jiguan", + cardcolor: "diamond", + fullskin: true, + derivation: "gjqt_xieyi", + enable: true, + notarget: true, + content() { + "step 0"; + var choice = "liufengsan"; + if ( + game.hasPlayer(function (current) { + var eff = get.effect(current, { name: "shenhuofeiya" }, player, player); + if (eff >= 0) return false; + if (current.hp == 1 && eff < 0) return true; + if ( + get.attitude(player, current) < 0 && + get.attitude(player, current.getNext() < 0) && + get.attitude(player, current.getPrevious()) < 0 + ) { + return true; + } + return false; + }) + ) { + choice = "shenhuofeiya"; } - player.chooseVCardButton('选择一张牌视为使用之',['liufengsan','shujinsan','shenhuofeiya']).set('ai',function(button){ - if(button.link[2]==_status.event.choice) return 2; - return Math.random(); - }).set('choice',choice).set('filterButton',function(button){ - return _status.event.player.hasUseTarget(button.link[2]); - }); - 'step 1' - player.chooseUseTarget(true,result.links[0][2]); + player + .chooseVCardButton("选择一张牌视为使用之", [ + "liufengsan", + "shujinsan", + "shenhuofeiya", + ]) + .set("ai", function (button) { + if (button.link[2] == _status.event.choice) return 2; + return Math.random(); + }) + .set("choice", choice) + .set("filterButton", function (button) { + return _status.event.player.hasUseTarget(button.link[2]); + }); + "step 1"; + player.chooseUseTarget(true, result.links[0][2]); + }, + ai: { + order: 5, + result: { + player: 1, + }, }, - ai:{ - order:5, - result:{ - player:1 - } - } }, - yanjiadan_club:{ - type:'jiguan', - cardcolor:'club', - fullskin:true, - derivation:'gjqt_xieyi', - enable:true, - notarget:true, - content(){ - 'step 0' - var choice='liutouge'; - player.chooseVCardButton('选择一张牌视为使用之',['bingpotong','liutouge','mianlijinzhen']).set('ai',function(button){ - if(button.link[2]==_status.event.choice) return 2; - return Math.random(); - }).set('choice',choice).set('filterButton',function(button){ - return _status.event.player.hasUseTarget(button.link[2]); - }); - 'step 1' - player.chooseUseTarget(true,result.links[0][2]); + yanjiadan_club: { + type: "jiguan", + cardcolor: "club", + fullskin: true, + derivation: "gjqt_xieyi", + enable: true, + notarget: true, + content() { + "step 0"; + var choice = "liutouge"; + player + .chooseVCardButton("选择一张牌视为使用之", [ + "bingpotong", + "liutouge", + "mianlijinzhen", + ]) + .set("ai", function (button) { + if (button.link[2] == _status.event.choice) return 2; + return Math.random(); + }) + .set("choice", choice) + .set("filterButton", function (button) { + return _status.event.player.hasUseTarget(button.link[2]); + }); + "step 1"; + player.chooseUseTarget(true, result.links[0][2]); + }, + ai: { + order: 5, + result: { + player: 1, + }, }, - ai:{ - order:5, - result:{ - player:1 - } - } }, - yanjiadan_spade:{ - type:'jiguan', - cardcolor:'spade', - fullskin:true, - derivation:'gjqt_xieyi', - enable:true, - notarget:true, - content(){ - 'step 0' - var choice=null; - if(player.getUseValue('longxugou')>0){ - choice='longxugou'; + yanjiadan_spade: { + type: "jiguan", + cardcolor: "spade", + fullskin: true, + derivation: "gjqt_xieyi", + enable: true, + notarget: true, + content() { + "step 0"; + var choice = null; + if (player.getUseValue("longxugou") > 0) { + choice = "longxugou"; + } else if (player.getUseValue("qiankunbiao") > 0) { + choice = "qiankunbiao"; + } else if (player.getUseValue("feibiao") > 0) { + choice = "qiankunbiao"; } - else if(player.getUseValue('qiankunbiao')>0){ - choice='qiankunbiao'; - } - else if(player.getUseValue('feibiao')>0){ - choice='qiankunbiao'; - } - player.chooseVCardButton('选择一张牌视为使用之',['feibiao','qiankunbiao','longxugou']).set('ai',function(button){ - if(button.link[2]==_status.event.choice) return 2; - return Math.random(); - }).set('choice',choice).set('filterButton',function(button){ - return _status.event.player.hasUseTarget(button.link[2]); - }); - 'step 1' - player.chooseUseTarget(true,result.links[0][2]); + player + .chooseVCardButton("选择一张牌视为使用之", ["feibiao", "qiankunbiao", "longxugou"]) + .set("ai", function (button) { + if (button.link[2] == _status.event.choice) return 2; + return Math.random(); + }) + .set("choice", choice) + .set("filterButton", function (button) { + return _status.event.player.hasUseTarget(button.link[2]); + }); + "step 1"; + player.chooseUseTarget(true, result.links[0][2]); }, - ai:{ - order:5, - result:{ - player(player){ - if(player.getUseValue('feibiao')>0) return 1; - if(player.getUseValue('qiankunbiao')>0) return 1; - if(player.getUseValue('longxugou')>0) return 1; + ai: { + order: 5, + result: { + player(player) { + if (player.getUseValue("feibiao") > 0) return 1; + if (player.getUseValue("qiankunbiao") > 0) return 1; + if (player.getUseValue("longxugou") > 0) return 1; return 0; - } - } - } - } + }, + }, + }, + }, }, /** @type { importCharacterConfig['skill'] } */ - skill:{ - qingshu:{ - ai:{ - threaten:1.4 + skill: { + qingshu: { + ai: { + threaten: 1.4, }, - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - for(var i=0;iplayer.storage.yunyou.length; + filter(event, player) { + return ( + !player.hasSkill("land_used") && + get.inpile("land").length > player.storage.yunyou.length + ); }, - delay:0, - content(){ - var list=get.inpile('land'); - for(var i=0;i0; + enable: "phaseUse", + usable: 1, + viewAs: { name: "feibiao" }, + filterCard: { suit: "club" }, + position: "he", + filter(event, player) { + return player.countCards("he", { suit: "club" }) > 0; }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - group:'xuanci_sha', - subSkill:{ - sha:{ - trigger:{player:'useCardToAfter'}, - forced:true, - filter(event,player){ - if(event.card.name=='feibiao'){ - return event.target.isIn()&&player.canUse('sha',event.target,false); + group: "xuanci_sha", + subSkill: { + sha: { + trigger: { player: "useCardToAfter" }, + forced: true, + filter(event, player) { + if (event.card.name == "feibiao") { + return event.target.isIn() && player.canUse("sha", event.target, false); } return false; }, - logTarget:'target', - autodelay:0.5, - content(){ - player.useCard(trigger.target,{name:'sha'},false).line=false; - } - } - } + logTarget: "target", + autodelay: 0.5, + content() { + player.useCard(trigger.target, { name: "sha" }, false).line = false; + }, + }, + }, }, - xianju:{ - trigger:{global:'roundStart'}, - forced:true, - init(player){ - if(game.roundNumber%2==1){ - player.addTempSkill('qianxing','roundStart'); + xianju: { + trigger: { global: "roundStart" }, + forced: true, + init(player) { + if (game.roundNumber % 2 == 1) { + player.addTempSkill("qianxing", "roundStart"); } }, - filter(event,player){ - return game.roundNumber%2==1; + filter(event, player) { + return game.roundNumber % 2 == 1; }, - content(){ - if(game.roundNumber%2==1){ - player.addTempSkill('qianxing','roundStart'); - } - else { - var list=get.typeCard('jiguan'); - for(var i=0;iplayer.storage.lingyan.length/13) return false; - return get.cardPile2(event.card.name)?true:false; + xunjian_old: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return player.storage.lingyan && player.storage.lingyan.length == 13; + }, + forced: true, + unique: true, + skillAnimation: true, + content() { + player.awakenSkill("xunjian"); + player.removeSkill("lingyan"); + player.addSkill("tongtian"); }, - content(){ - var card=get.cardPile2(trigger.card.name); - if(card){ - player.gain(card,'gain2'); - } - } }, - tongtian:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - filter(event,player){ - var name=event.card.name; - var enemies=player.getEnemies(); - for(var i=0;i player.storage.lingyan.length / 13) return false; + return get.cardPile2(event.card.name) ? true : false; + }, + content() { + var card = get.cardPile2(trigger.card.name); + if (card) { + player.gain(card, "gain2"); + } + }, + }, + tongtian: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + filter(event, player) { + var name = event.card.name; + var enemies = player.getEnemies(); + for (var i = 0; i < enemies.length; i++) { + if (enemies[i].countCards("h", name)) { return true; } } }, - content(){ - var list=[]; - var name=trigger.card.name; - var enemies=player.getEnemies(); - for(var i=0;i0) { - player.markSkill('yange'); + yange: { + trigger: { player: "phaseBeginStart" }, + direct: true, + init(player) { + if (player.storage.yange > 0) { + player.markSkill("yange"); } }, - filter(event,player){ - return player.storage.yange>0; + filter(event, player) { + return player.storage.yange > 0; }, - content(){ - 'step 0' - player.chooseTarget(function(card,player,target){ - return player!=target; - },get.prompt2('yange')).set('pskill',trigger.skill).set('ai',function(target){ - if(_status.event.pskill) return 0; - var player=_status.event.player; - var nh=player.countCards('h'); - var nh2=target.countCards('h'); - var num=nh2-nh; - if(player.hp==1){ - return num; - } - if(get.threaten(target)>=1.5){ - if(num<2) return 0; - } - else{ - if(num<3) return 0; - } - return num+Math.sqrt(get.threaten(target)); - }); - 'step 1' - if(result.bool){ + content() { + "step 0"; + player + .chooseTarget(function (card, player, target) { + return player != target; + }, get.prompt2("yange")) + .set("pskill", trigger.skill) + .set("ai", function (target) { + if (_status.event.pskill) return 0; + var player = _status.event.player; + var nh = player.countCards("h"); + var nh2 = target.countCards("h"); + var num = nh2 - nh; + if (player.hp == 1) { + return num; + } + if (get.threaten(target) >= 1.5) { + if (num < 2) return 0; + } else { + if (num < 3) return 0; + } + return num + Math.sqrt(get.threaten(target)); + }); + "step 1"; + if (result.bool) { player.storage.yange--; - if(player.storage.yange<=0){ - player.unmarkSkill('yange'); - } - else{ + if (player.storage.yange <= 0) { + player.unmarkSkill("yange"); + } else { player.updateMarks(); } - var target=result.targets[0]; - player.logSkill('yange',target); - var clone=function(pos){ - var cloned=[]; - var cards=target.getCards(pos); - for(var i=0;i 0) { + if (target.isTurnedOver()) return 2.5; + if (target.hp == 1) { + if (nh == 0) return 2; + if (nh == 1) return 0.9; + if (ui.selected.targets.length) return 0.3; + } else if (target.hp == 2) { + if (nh == 0) return 1.5; + if (nh == 1) return 0.5; + if (ui.selected.targets.length) return 0.2; + } else if (target.hp == 3) { + if (nh == 0) return 0.4; + if (nh == 1) return 0.35; + if (ui.selected.targets.length) return 0.1; + } + if (!target.needsToDiscard(2)) return 0.2; + if (ui.selected.targets.length || !player.needsToDiscard(2)) return 0.05; } - if(target.hp==1){ - if(nh==0) return 2; - if(nh==1) return 1; - } - } - else if(att>0){ - if(target.isTurnedOver()) return 2.5; - if(target.hp==1){ - if(nh==0) return 2; - if(nh==1) return 0.9; - if(ui.selected.targets.length) return 0.3; - } - else if(target.hp==2){ - if(nh==0) return 1.5; - if(nh==1) return 0.5; - if(ui.selected.targets.length) return 0.2; - } - else if(target.hp==3){ - if(nh==0) return 0.4; - if(nh==1) return 0.35; - if(ui.selected.targets.length) return 0.1; - } - if(!target.needsToDiscard(2)) return 0.2; - if(ui.selected.targets.length||!player.needsToDiscard(2)) return 0.05; - } - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('lianjing',result.targets); - player.insertEvent('lianjing',lib.skill.lianjing.content_phase); - player.storage.lianjing_targets=result.targets.slice(0); + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("lianjing", result.targets); + player.insertEvent("lianjing", lib.skill.lianjing.content_phase); + player.storage.lianjing_targets = result.targets.slice(0); // player.storage.lianjing--; // if(player.storage.lianjing<=0){ // player.unmarkSkill('lianjing'); @@ -872,1893 +958,2000 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.delay(); } }, - content_phase(){ - 'step 0' - event.forceDie=true; - event.list=[player].concat(player.storage.lianjing_targets); - event.exlist=[]; + content_phase() { + "step 0"; + event.forceDie = true; + event.list = [player].concat(player.storage.lianjing_targets); + event.exlist = []; event.list.sortBySeat(); delete player.storage.lianjing_targets; - for(var i=0;i0; - })){ - if(player.hp>1||!player.isTurnedOver()){ - goon=true; + cihong: { + round: 3, + trigger: { player: "phaseEnd" }, + direct: true, + content() { + "step 0"; + var goon = false; + if ( + player.countCards("he", function (card) { + return get.value(card) < 8 && get.color(card) == "red"; + }) + ) { + goon = true; + } else if ( + game.hasPlayer(function (current) { + return ( + current.hp == 1 && + player.canUse("sha", current, false) && + get.attitude(player, current) < 0 && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { + if (player.hp > 1 || !player.isTurnedOver()) { + goon = true; } } - player.chooseTarget(get.prompt('cihong'),function(card,playe,target){ - return player.canUse('sha',target,false); - }).set('ai',function(target){ - if(!_status.event.goon) return false; - var player=_status.event.player; - if(get.attitude(player,target)>=0) return false; - if(target.hp>3) return false; - return get.effect(target,{name:'sha'},player,player); - }).set('goon',goon); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('cihong',event.target); - } - else{ + player + .chooseTarget(get.prompt("cihong"), function (card, playe, target) { + return player.canUse("sha", target, false); + }) + .set("ai", function (target) { + if (!_status.event.goon) return false; + var player = _status.event.player; + if (get.attitude(player, target) >= 0) return false; + if (target.hp > 3) return false; + return get.effect(target, { name: "sha" }, player, player); + }) + .set("goon", goon); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("cihong", event.target); + } else { event.finish(); } - 'step 2' - if(event.target.isAlive()&&player.countCards('he',{color:'red'})){ - player.chooseToDiscard('he',{color:'red'},'是否弃置一张红色牌视为对'+get.translation(event.target)+'使用一张杀?').set('ai',function(card){ - return 8-get.value(card); - }) - } - else{ + "step 2"; + if (event.target.isAlive() && player.countCards("he", { color: "red" })) { + player + .chooseToDiscard( + "he", + { color: "red" }, + "是否弃置一张红色牌视为对" + get.translation(event.target) + "使用一张杀?" + ) + .set("ai", function (card) { + return 8 - get.value(card); + }); + } else { event.goto(4); } - 'step 3' - if(result.bool){ - player.useCard({name:'sha'},event.target); + "step 3"; + if (result.bool) { + player.useCard({ name: "sha" }, event.target); } - 'step 4' - if(event.target.isAlive()){ - player.chooseBool('是否失去1点体力并视为对'+get.translation(event.target)+'使用一张杀?').set('choice', - player.hp>event.target.hp&&player.hp>1&&event.target.hp>0 - ); - } - else{ + "step 4"; + if (event.target.isAlive()) { + player + .chooseBool( + "是否失去1点体力并视为对" + get.translation(event.target) + "使用一张杀?" + ) + .set( + "choice", + player.hp > event.target.hp && player.hp > 1 && event.target.hp > 0 + ); + } else { event.finish(); } - 'step 5' - if(result.bool){ + "step 5"; + if (result.bool) { player.loseHp(); - player.useCard({name:'sha'},event.target); + player.useCard({ name: "sha" }, event.target); } - 'step 6' - if(event.target.isAlive()&&!player.isTurnedOver()){ - player.chooseBool('是将武将牌翻至背面并视为对'+get.translation(event.target)+'使用一张杀?').set('choice', - event.target.hp==1 - ); - } - else{ + "step 6"; + if (event.target.isAlive() && !player.isTurnedOver()) { + player + .chooseBool( + "是将武将牌翻至背面并视为对" + get.translation(event.target) + "使用一张杀?" + ) + .set("choice", event.target.hp == 1); + } else { event.finish(); } - 'step 7' - if(result.bool){ + "step 7"; + if (result.bool) { player.turnOver(true); - player.useCard({name:'sha'},event.target); + player.useCard({ name: "sha" }, event.target); } }, - ai:{ - threaten:1.5 - } + ai: { + threaten: 1.5, + }, }, - zhenying:{ - trigger:{player:['useCard','respond']}, - forced:true, - filter(event,player){ - if(!event.card.isCard) return false; - if(event.cards[0]&&event.cards[0].zhenying_link) return false; - if(get.color(event.card)!='black') return false; - if(['delay','equip'].includes(get.type(event.card))) return false; + zhenying: { + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter(event, player) { + if (!event.card.isCard) return false; + if (event.cards[0] && event.cards[0].zhenying_link) return false; + if (get.color(event.card) != "black") return false; + if (["delay", "equip"].includes(get.type(event.card))) return false; return true; }, - content(){ - var fake=game.createCard(trigger.card); - fake.zhenying_link=true; - player.gain(fake,'draw')._triggered=null; - fake.classList.add('glow'); - fake._destroy='zhenying'; - fake._modUseful=function(){return 0.1}; - fake._modValue=function(){return 0.1}; + content() { + var fake = game.createCard(trigger.card); + fake.zhenying_link = true; + player.gain(fake, "draw")._triggered = null; + fake.classList.add("glow"); + fake._destroy = "zhenying"; + fake._modUseful = function () { + return 0.1; + }; + fake._modValue = function () { + return 0.1; + }; }, - group:['zhenying_discard','zhenying_lose'], - subSkill:{ - discard:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - filter(event,player){ - if(get.is.converted(event)) return false; - if(!player.countCards('he')) return false; - if(event.cards[0]&&event.cards[0].zhenying_link) return true; + group: ["zhenying_discard", "zhenying_lose"], + subSkill: { + discard: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + filter(event, player) { + if (get.is.converted(event)) return false; + if (!player.countCards("he")) return false; + if (event.cards[0] && event.cards[0].zhenying_link) return true; return false; }, - popup:false, - content(){ - player.chooseToDiscard('he',true); - } + popup: false, + content() { + player.chooseToDiscard("he", true); + }, }, - lose:{ - trigger:{global:'phaseAfter'}, - silent:true, - content(){ - var hs=player.getCards('h',function(card){ - return card.zhenying_link?true:false; + lose: { + trigger: { global: "phaseAfter" }, + silent: true, + content() { + var hs = player.getCards("h", function (card) { + return card.zhenying_link ? true : false; }); - if(hs.length){ - player.lose(hs)._triggered=null; + if (hs.length) { + player.lose(hs)._triggered = null; } - } - } - } + }, + }, + }, }, - lingnu:{ - trigger:{source:'damageEnd'}, - forced:true, - init(player){ - player.storage.lingnu={}; + lingnu: { + trigger: { source: "damageEnd" }, + forced: true, + init(player) { + player.storage.lingnu = {}; }, - ai:{ - threaten:1.3 + ai: { + threaten: 1.3, }, - filter(event,player){ - var num=0; - for(var i in player.storage.lingnu){ + filter(event, player) { + var num = 0; + for (var i in player.storage.lingnu) { num++; - if(num>=3) return false; + if (num >= 3) return false; } - return event.num>0; + return event.num > 0; }, - content(){ - var check=function(list){ - for(var i=0;i=3) break; - if(list.length){ - var skill=list.randomGet(); - player.addAdditionalSkill('lingnu',skill,true); - player.storage.lingnu[skill]=3; + for (var i = 0; i < trigger.num; i++) { + if (num >= 3) break; + if (list.length) { + var skill = list.randomGet(); + player.addAdditionalSkill("lingnu", skill, true); + player.storage.lingnu[skill] = 3; player.popup(skill); - game.log(player,'获得了技能','【'+get.translation(skill)+'】'); - player.markSkill('lingnu'); + game.log(player, "获得了技能", "【" + get.translation(skill) + "】"); + player.markSkill("lingnu"); num++; } } }, - intro:{ - content(storage){ - var str='
                '; - for(var i in storage){ - str+='
              • '+get.translation(i)+':剩余'+storage[i]+'回合'; + intro: { + content(storage) { + var str = '
                  '; + for (var i in storage) { + str += "
                • " + get.translation(i) + ":剩余" + storage[i] + "回合"; } - str+='
                ' + str += "
              "; return str; }, - markcount(storage){ - var num=0; - for(var i in storage){ + markcount(storage) { + var num = 0; + for (var i in storage) { num++; } return num; - } + }, }, - group:'lingnu_remove', - subSkill:{ - remove:{ - trigger:{player:'phaseAfter'}, - silent:true, - content(){ - var clear=true; - for(var i in player.storage.lingnu){ + group: "lingnu_remove", + subSkill: { + remove: { + trigger: { player: "phaseAfter" }, + silent: true, + content() { + var clear = true; + for (var i in player.storage.lingnu) { player.storage.lingnu[i]--; - if(player.storage.lingnu[i]<=0){ + if (player.storage.lingnu[i] <= 0) { delete player.storage.lingnu[i]; - player.removeAdditionalSkill('lingnu',i); - } - else{ - clear=false; + player.removeAdditionalSkill("lingnu", i); + } else { + clear = false; } } - if(clear){ - player.unmarkSkill('lingnu'); - } - else{ + if (clear) { + player.unmarkSkill("lingnu"); + } else { player.updateMarks(); } - } - } - } + }, + }, + }, }, - zuiji:{ - enable:'phaseUse', - filterCard:true, - position:'he', - viewAs:{name:'jiu'}, - viewAsFilter(player){ - if(!player.countCards('he')) return false; + zuiji: { + enable: "phaseUse", + filterCard: true, + position: "he", + viewAs: { name: "jiu" }, + viewAsFilter(player) { + if (!player.countCards("he")) return false; }, - prompt:'将一张手牌或装备牌当酒使用', - check(card){ - return 5-get.value(card); + prompt: "将一张手牌或装备牌当酒使用", + check(card) { + return 5 - get.value(card); + }, + ai: { + threaten: 1.2, }, - ai:{ - threaten:1.2 - } }, - manwu:{ - trigger:{global:'phaseEnd'}, - check(event,player){ - return get.attitude(player,event.player)>0; + manwu: { + trigger: { global: "phaseEnd" }, + check(event, player) { + return get.attitude(player, event.player) > 0; }, - filter(event,player){ + filter(event, player) { return event.player.isMinHandcard(); }, - logTarget:'player', - content(){ + logTarget: "player", + content() { trigger.player.draw(); }, - ai:{ - expose:0.1 - } - }, - xfanghua:{ - trigger:{target:'useCardToBegin'}, - priority:-1, - filter(event,player){ - return get.color(event.card)=='red'&&player.isDamaged(); + ai: { + expose: 0.1, }, - frequent:true, - content(){ + }, + xfanghua: { + trigger: { target: "useCardToBegin" }, + priority: -1, + filter(event, player) { + return get.color(event.card) == "red" && player.isDamaged(); + }, + frequent: true, + content() { player.recover(); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(get.color(card)=='red'&&target.isDamaged()) return [1,1]; - } - } - } + ai: { + effect: { + target(card, player, target, current) { + if (get.color(card) == "red" && target.isDamaged()) return [1, 1]; + }, + }, + }, }, - duhun:{ - enable:'chooseToUse', - filter(event,player){ - if(event.type!='dying') return false; - if(player!=event.dying) return false; - if(player.maxHp<=1) return false; - if(player.countCards('h')==0) return false; + duhun: { + enable: "chooseToUse", + filter(event, player) { + if (event.type != "dying") return false; + if (player != event.dying) return false; + if (player.maxHp <= 1) return false; + if (player.countCards("h") == 0) return false; return true; }, // alter:true, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0&&target.hp>0&&target.hp<=player.maxHp; + filterTarget(card, player, target) { + return ( + target != player && + target.countCards("h") > 0 && + target.hp > 0 && + target.hp <= player.maxHp + ); }, - content(){ - 'step 0' + content() { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(!result.bool){ + "step 1"; + if (!result.bool) { player.die(); event.finish(); - } - else{ - event.num=target.hp-player.hp; + } else { + event.num = target.hp - player.hp; player.loseMaxHp(); } - 'step 2' + "step 2"; player.changeHp(event.num); - if(get.is.altered('duhun')){ + if (get.is.altered("duhun")) { event.finish(); } - 'step 3' + "step 3"; event.target.changeHp(-event.num); - 'step 4' - if(event.target.hp<=0){ - event.target.dying({source:player}); + "step 4"; + if (event.target.hp <= 0) { + event.target.dying({ source: player }); } }, - ai:{ - order:1, - skillTagFilter(player){ - if(player.maxHp<=1) return false; - if(player.hp>0) return false; - if(player.countCards('h')==0) return false; + ai: { + order: 1, + skillTagFilter(player) { + if (player.maxHp <= 1) return false; + if (player.hp > 0) return false; + if (player.countCards("h") == 0) return false; }, - save:true, - result:{ - target:-1, - player:1 + save: true, + result: { + target: -1, + player: 1, }, - threaten:2 + threaten: 2, }, }, - yunyin:{ - trigger:{player:'phaseEnd'}, - direct:true, - subSkill:{ - count:{ - trigger:{player:'useCard'}, - silent:true, - filter(event,player){ - return _status.currentPhase==player; + yunyin: { + trigger: { player: "phaseEnd" }, + direct: true, + subSkill: { + count: { + trigger: { player: "useCard" }, + silent: true, + filter(event, player) { + return _status.currentPhase == player; }, - content(){ - if(!player.storage.yunyin){ - player.storage.yunyin=[]; + content() { + if (!player.storage.yunyin) { + player.storage.yunyin = []; } - var suit=get.suit(trigger.card); - if(suit){ + var suit = get.suit(trigger.card); + if (suit) { player.storage.yunyin.add(suit); } - } + }, }, - set:{ - trigger:{player:'phaseAfter'}, - silent:true, - content(){ + set: { + trigger: { player: "phaseAfter" }, + silent: true, + content() { delete player.storage.yunyin; - } - } + }, + }, }, - filter(event,player){ - if(!player.storage.yunyin) return true; - var hs=player.getCards('h'); - for(var i=0;i0){ + var dialog = ui.create.dialog("云音", [list, "vcard"]); + var taoyuan = 0, + nanman = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var eff1 = get.effect(players[i], { name: "taoyuan" }, player, player); + var eff2 = get.effect(players[i], { name: "nanman" }, player, player); + if (eff1 > 0) { taoyuan++; - } - else if(eff1<0){ + } else if (eff1 < 0) { taoyuan--; } - if(eff2>0){ + if (eff2 > 0) { nanman++; - } - else if(eff2<0){ + } else if (eff2 < 0) { nanman--; } } - player.chooseButton(dialog).ai=function(button){ - var name=button.link[2]; - if(Math.max(taoyuan,nanman)>1){ - if(taoyuan>nanman) return name=='taoyuan'?1:0; - return name=='nanman'?1:0; + player.chooseButton(dialog).ai = function (button) { + var name = button.link[2]; + if (Math.max(taoyuan, nanman) > 1) { + if (taoyuan > nanman) return name == "taoyuan" ? 1 : 0; + return name == "nanman" ? 1 : 0; } - if(player.countCards('h')=2){ - return name=='wuzhong'?1:0; + if (player.countCards("h") < player.hp && player.hp >= 2) { + return name == "wuzhong" ? 1 : 0; } - if(player.hp=2) return true; + if (num >= 2) return true; } } }, - filterCard(card){ - if(ui.selected.cards.length&&card.name==ui.selected.cards[0].name) return false; - var info=get.info(card); - return info.type=='equip'&&!info.nomod&&!info.unique&&lib.inpile.includes(card.name); + filterCard(card) { + if (ui.selected.cards.length && card.name == ui.selected.cards[0].name) return false; + var info = get.info(card); + return ( + info.type == "equip" && !info.nomod && !info.unique && lib.inpile.includes(card.name) + ); }, - selectCard:2, - position:'he', - check(card){ + selectCard: 2, + position: "he", + check(card) { return get.value(card); }, - content(){ - var name=cards[0].name+'_'+cards[1].name; - var info1=get.info(cards[0]),info2=get.info(cards[1]); - if(!lib.card[name]){ - var info={ - enable:true, - type:'equip', - subtype:get.subtype(cards[0]), - vanish:true, - cardimage:info1.cardimage||cards[0].name, - filterTarget(card,player,target){ - return target==player; + content() { + var name = cards[0].name + "_" + cards[1].name; + var info1 = get.info(cards[0]), + info2 = get.info(cards[1]); + if (!lib.card[name]) { + var info = { + enable: true, + type: "equip", + subtype: get.subtype(cards[0]), + vanish: true, + cardimage: info1.cardimage || cards[0].name, + filterTarget(card, player, target) { + return target == player; }, - selectTarget:-1, - modTarget:true, - content:lib.element.content.equipCard, - legend:true, - source:[cards[0].name,cards[1].name], - onEquip:[], - onLose:[], - skills:[], - distance:{}, - ai:{ - order:8.9, - equipValue:10, - useful:2.5, - value(card,player){ - var value=0; - var info=get.info(card); - var current=player.getEquip(info.subtype); - if(current&&card!=current){ - value=get.value(current,player); + selectTarget: -1, + modTarget: true, + content: lib.element.content.equipCard, + legend: true, + source: [cards[0].name, cards[1].name], + onEquip: [], + onLose: [], + skills: [], + distance: {}, + ai: { + order: 8.9, + equipValue: 10, + useful: 2.5, + value(card, player) { + var value = 0; + var info = get.info(card); + var current = player.getEquip(info.subtype); + if (current && card != current) { + value = get.value(current, player); } - var equipValue=info.ai.equipValue||info.ai.basic.equipValue; - if(typeof equipValue=='function') return equipValue(card,player)-value; - return equipValue-value; + var equipValue = info.ai.equipValue || info.ai.basic.equipValue; + if (typeof equipValue == "function") + return equipValue(card, player) - value; + return equipValue - value; }, - result:{ - target(player,target){ - return get.equipResult(player,target,name); - } - } + result: { + target(player, target) { + return get.equipResult(player, target, name); + }, + }, + }, + }; + for (var i in info1.distance) { + info.distance[i] = info1.distance[i]; + } + for (var i in info2.distance) { + if (typeof info.distance[i] == "number") { + info.distance[i] += info2.distance[i]; + } else { + info.distance[i] = info2.distance[i]; } } - for(var i in info1.distance){ - info.distance[i]=info1.distance[i]; + if (info1.skills) { + info.skills = info.skills.concat(info1.skills); } - for(var i in info2.distance){ - if(typeof info.distance[i]=='number'){ - info.distance[i]+=info2.distance[i]; - } - else{ - info.distance[i]=info2.distance[i]; - } + if (info2.skills) { + info.skills = info.skills.concat(info2.skills); } - if(info1.skills){ - info.skills=info.skills.concat(info1.skills); - } - if(info2.skills){ - info.skills=info.skills.concat(info2.skills); - } - if(info1.onEquip){ - if(Array.isArray(info1.onEquip)){ - info.onEquip=info.onEquip.concat(info1.onEquip); - } - else{ + if (info1.onEquip) { + if (Array.isArray(info1.onEquip)) { + info.onEquip = info.onEquip.concat(info1.onEquip); + } else { info.onEquip.push(info1.onEquip); } } - if(info2.onEquip){ - if(Array.isArray(info2.onEquip)){ - info.onEquip=info.onEquip.concat(info2.onEquip); - } - else{ + if (info2.onEquip) { + if (Array.isArray(info2.onEquip)) { + info.onEquip = info.onEquip.concat(info2.onEquip); + } else { info.onEquip.push(info2.onEquip); } } - if(info1.onLose){ - if(Array.isArray(info1.onLose)){ - info.onLose=info.onLose.concat(info1.onLose); - } - else{ + if (info1.onLose) { + if (Array.isArray(info1.onLose)) { + info.onLose = info.onLose.concat(info1.onLose); + } else { info.onLose.push(info1.onLose); } } - if(info2.onLose){ - if(Array.isArray(info2.onLose)){ - info.onLose=info.onLose.concat(info2.onLose); - } - else{ + if (info2.onLose) { + if (Array.isArray(info2.onLose)) { + info.onLose = info.onLose.concat(info2.onLose); + } else { info.onLose.push(info2.onLose); } } - if(info.onEquip.length==0) delete info.onEquip; - if(info.onLose.length==0) delete info.onLose; - lib.card[name]=info; - lib.translate[name]=get.translation(cards[0].name,'skill')+get.translation(cards[1].name,'skill'); - var str=lib.translate[cards[0].name+'_info']; - if(str[str.length-1]=='.'||str[str.length-1]=='。'){ - str=str.slice(0,str.length-1); + if (info.onEquip.length == 0) delete info.onEquip; + if (info.onLose.length == 0) delete info.onLose; + lib.card[name] = info; + lib.translate[name] = + get.translation(cards[0].name, "skill") + get.translation(cards[1].name, "skill"); + var str = lib.translate[cards[0].name + "_info"]; + if (str[str.length - 1] == "." || str[str.length - 1] == "。") { + str = str.slice(0, str.length - 1); } - lib.translate[name+'_info']=str+';'+lib.translate[cards[1].name+'_info']; - try{ - game.addVideo('newcard',null,{ - name:name, - translate:lib.translate[name], - info:lib.translate[name+'_info'], - card:cards[0].name, - legend:true, + lib.translate[name + "_info"] = str + ";" + lib.translate[cards[1].name + "_info"]; + try { + game.addVideo("newcard", null, { + name: name, + translate: lib.translate[name], + info: lib.translate[name + "_info"], + card: cards[0].name, + legend: true, }); - } - catch(e){ + } catch (e) { console.log(e); } } - player.gain(game.createCard({name:name,suit:cards[0].suit,number:cards[0].number}),'gain2'); + player.gain( + game.createCard({ name: name, suit: cards[0].suit, number: cards[0].number }), + "gain2" + ); + }, + ai: { + order: 9.5, + result: { + player: 1, + }, }, - ai:{ - order:9.5, - result:{ - player:1 - } - } }, - meiying:{ - globalSilent:true, - trigger:{global:'phaseEnd'}, - filter(event,player){ - return event.player!=player&&event.player.isAlive()&&player.countCards('he',{color:'red'})>0&&event.player.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.some(i=>i!==event.player); - }).length===0; + meiying: { + globalSilent: true, + trigger: { global: "phaseEnd" }, + filter(event, player) { + return ( + event.player != player && + event.player.isAlive() && + player.countCards("he", { color: "red" }) > 0 && + event.player.getHistory("useCard", (evt) => { + return evt.targets && evt.targets.some((i) => i !== event.player); + }).length === 0 + ); }, - direct:true, - content(){ - "step 0" - var next=player.chooseToDiscard('he','魅影:是否弃置一张红色牌视为对'+get.translation(trigger.player)+'使用一张杀?'); - next.logSkill=['meiying',trigger.player]; - var eff=get.effect(trigger.player,{name:'sha'},player,player); - next.ai=function(card){ - if(eff>0){ - return 7-get.value(card); + direct: true, + content() { + "step 0"; + var next = player.chooseToDiscard( + "he", + "魅影:是否弃置一张红色牌视为对" + get.translation(trigger.player) + "使用一张杀?" + ); + next.logSkill = ["meiying", trigger.player]; + var eff = get.effect(trigger.player, { name: "sha" }, player, player); + next.ai = function (card) { + if (eff > 0) { + return 7 - get.value(card); } return 0; - } - "step 1" - if(result.bool){ - player.useCard({name:'sha'},trigger.player).animate=false; + }; + "step 1"; + if (result.bool) { + player.useCard({ name: "sha" }, trigger.player).animate = false; } }, - ai:{ - expose:0.1 - } - }, - jianwu:{ - trigger:{player:'shaBegin'}, - forced:true, - filter(event,player){ - return get.distance(event.target,player,'attack')>1; + ai: { + expose: 0.1, }, - content(){ - trigger.directHit=true; - } }, - zuizhan:{ - trigger:{player:'useCard'}, - popup:false, - filter(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return (event.targets.includes(current)==false&¤t!=player&& - lib.filter.targetEnabled(event.card,player,current)) + jianwu: { + trigger: { player: "shaBegin" }, + forced: true, + filter(event, player) { + return get.distance(event.target, player, "attack") > 1; + }, + content() { + trigger.directHit = true; + }, + }, + zuizhan: { + trigger: { player: "useCard" }, + popup: false, + filter(event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return ( + event.targets.includes(current) == false && + current != player && + lib.filter.targetEnabled(event.card, player, current) + ); }); }, - content(){ - var list=game.filterPlayer(function(current){ - return (trigger.targets.includes(current)==false&¤t!=player&& - lib.filter.targetEnabled(trigger.card,player,current)) + content() { + var list = game.filterPlayer(function (current) { + return ( + trigger.targets.includes(current) == false && + current != player && + lib.filter.targetEnabled(trigger.card, player, current) + ); }); - if(list.length){ - event.target=list.randomGet(); - player.line(event.target,'green'); - game.log(event.target,'被追加为额外目标'); + if (list.length) { + event.target = list.randomGet(); + player.line(event.target, "green"); + game.log(event.target, "被追加为额外目标"); trigger.targets.push(event.target); player.draw(); } - } + }, }, - xidie:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ - return player.countCards('h')>player.hp; + xidie: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { + return player.countCards("h") > player.hp; }, - content(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('xidie'),[1,Math.min(3,player.countCards('h')-player.hp)]); - next.ai=function(card){ - return 6-get.value(card); - } - next.logSkill='xidie'; - "step 1" - if(result.bool){ - player.storage.xidie=result.cards.length; - } - }, - group:'xidie2' - }, - xidie2:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.storage.xidie>0; - }, - content(){ - player.draw(player.storage.xidie); - player.storage.xidie=0; - } - }, - meihu:{ - trigger:{player:'damageEnd'}, - check(event,player){ - return get.attitude(player,event.source)<4; - }, - filter(event,player){ - return event.source&&event.source!=player&&event.source.countCards('h')>0; - }, - logTarget:'source', - content(){ - "step 0" - trigger.source.chooseCard('交给'+get.translation(player)+'一张手牌',true).ai=function(card){ - return -get.value(card); + content() { + "step 0"; + var next = player.chooseToDiscard(get.prompt("xidie"), [ + 1, + Math.min(3, player.countCards("h") - player.hp), + ]); + next.ai = function (card) { + return 6 - get.value(card); }; - "step 1" - if(result.bool){ - player.gain(result.cards[0],trigger.source); - trigger.source.$give(1,player); + next.logSkill = "xidie"; + "step 1"; + if (result.bool) { + player.storage.xidie = result.cards.length; } }, - ai:{ - maixie_defend:true, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - return [1,0,0,-0.5]; - } - } - } - } + group: "xidie2", }, - xlqianhuan:{ - trigger:{player:'phaseAfter'}, - check(event,player){ - return player.hp==1||player.isTurnedOver(); + xidie2: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.storage.xidie > 0; }, - filter(event,player){ - return player.hp 0; + }, + logTarget: "source", + content() { + "step 0"; + trigger.source.chooseCard("交给" + get.translation(player) + "一张手牌", true).ai = + function (card) { + return -get.value(card); + }; + "step 1"; + if (result.bool) { + player.gain(result.cards[0], trigger.source); + trigger.source.$give(1, player); + } + }, + ai: { + maixie_defend: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + return [1, 0, 0, -0.5]; + } + }, + }, + }, + }, + xlqianhuan: { + trigger: { player: "phaseAfter" }, + check(event, player) { + return player.hp == 1 || player.isTurnedOver(); + }, + filter(event, player) { + return player.hp < player.maxHp; + }, + content() { + "step 0"; player.recover(); - "step 1" + "step 1"; player.turnOver(); }, - mod:{ - targetEnabled(card,player,target){ - if(target.isTurnedOver()) return false; + mod: { + targetEnabled(card, player, target) { + if (target.isTurnedOver()) return false; + }, + cardEnabled(card, player) { + if (player.isTurnedOver()) return false; }, - cardEnabled(card,player){ - if(player.isTurnedOver()) return false; - } - } - }, - fumo:{ - trigger:{player:'damageAfter'}, - filter(event,player){ - return event.source&&event.source.isAlive()&&player.countCards('h',{color:'red'})>1||player.countCards('h',{color:'black'})>1; }, - direct:true, - content(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('fumo',trigger.source),2,function(card){ - if(get.damageEffect(trigger.source,player,player,'thunder')<=0) return 0; - if(ui.selected.cards.length){ - return get.color(card)==get.color(ui.selected.cards[0]); - } - return player.countCards('h',{color:get.color(card)})>1; - }).set('complexCard',true); - next.ai=function(card){ - if(get.damageEffect(trigger.source,player,player,'thunder')>0){ - return 8-get.value(card); + }, + fumo: { + trigger: { player: "damageAfter" }, + filter(event, player) { + return ( + (event.source && + event.source.isAlive() && + player.countCards("h", { color: "red" }) > 1) || + player.countCards("h", { color: "black" }) > 1 + ); + }, + direct: true, + content() { + "step 0"; + var next = player + .chooseToDiscard(get.prompt("fumo", trigger.source), 2, function (card) { + if (get.damageEffect(trigger.source, player, player, "thunder") <= 0) return 0; + if (ui.selected.cards.length) { + return get.color(card) == get.color(ui.selected.cards[0]); + } + return player.countCards("h", { color: get.color(card) }) > 1; + }) + .set("complexCard", true); + next.ai = function (card) { + if (get.damageEffect(trigger.source, player, player, "thunder") > 0) { + return 8 - get.value(card); } return 0; }; - next.logSkill=['fumo',trigger.source,'thunder']; - "step 1" - if(result.bool){ - trigger.source.damage('thunder'); + next.logSkill = ["fumo", trigger.source, "thunder"]; + "step 1"; + if (result.bool) { + trigger.source.damage("thunder"); } }, - ai:{ - maixie_defend:true, - threaten:0.8 - } + ai: { + maixie_defend: true, + threaten: 0.8, + }, }, - fanyin:{ - trigger:{player:'phaseEnd'}, - direct:true, - content(){ - "step 0" - player.chooseTarget(get.prompt('fanyin'),function(card,player,target){ + fanyin: { + trigger: { player: "phaseEnd" }, + direct: true, + content() { + "step 0"; + player.chooseTarget(get.prompt("fanyin"), function (card, player, target) { // if(player==target) return false; - if(target.isLinked()) return true; - if(target.isTurnedOver()) return true; - if(target.countCards('j')) return true; - if(target.isMinHp()&&target.isDamaged()) return true; + if (target.isLinked()) return true; + if (target.isTurnedOver()) return true; + if (target.countCards("j")) return true; + if (target.isMinHp() && target.isDamaged()) return true; return false; - }).ai=function(target){ - var num=0; - var att=get.attitude(player,target); - if(att>0){ - if(target.isMinHp()){ - num+=5; + }).ai = function (target) { + var num = 0; + var att = get.attitude(player, target); + if (att > 0) { + if (target.isMinHp()) { + num += 5; } - if(target.isTurnedOver()){ - num+=5; + if (target.isTurnedOver()) { + num += 5; } - if(target.countCards('j')){ - num+=2; + if (target.countCards("j")) { + num += 2; } - if(target.isLinked()){ + if (target.isLinked()) { num++; } - if(num>0){ - return num+att; + if (num > 0) { + return num + att; } } return num; - } - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('fanyin',event.target); - } - else{ + }; + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("fanyin", event.target); + } else { event.finish(); } - "step 2" - if(event.target.isLinked()){ + "step 2"; + if (event.target.isLinked()) { event.target.link(); } - "step 3" - if(event.target.isTurnedOver()){ + "step 3"; + if (event.target.isTurnedOver()) { event.target.turnOver(); } - "step 4" - var cards=event.target.getCards('j'); - if(cards.length){ + "step 4"; + var cards = event.target.getCards("j"); + if (cards.length) { event.target.discard(cards); } - "step 5" - if(event.target.isMinHp()){ + "step 5"; + if (event.target.isMinHp()) { event.target.recover(); } }, - ai:{ - expose:0.2, - threaten:1.3 - } - }, - mingkong:{ - trigger:{player:'damageBegin'}, - forced:true, - filter(event,player){ - return player.countCards('h')==0&&event.num>=1; + ai: { + expose: 0.2, + threaten: 1.3, }, - content(){ - if(trigger.num>=1){ + }, + mingkong: { + trigger: { player: "damageBegin" }, + forced: true, + filter(event, player) { + return player.countCards("h") == 0 && event.num >= 1; + }, + content() { + if (trigger.num >= 1) { trigger.num--; } - if(trigger.source){ - trigger.source.storage.mingkong=true; - trigger.source.addTempSkill('mingkong2'); + if (trigger.source) { + trigger.source.storage.mingkong = true; + trigger.source.addTempSkill("mingkong2"); } }, - ai:{ - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')&&target.countCards('h')==0){ - if(player.hasSkillTag('jueqing',false,target)) return; + ai: { + effect: { + target(card, player, target) { + if (get.tag(card, "damage") && target.countCards("h") == 0) { + if (player.hasSkillTag("jueqing", false, target)) return; return 0.1; } - } - } + }, + }, }, }, - mingkong2:{ - trigger:{source:['damageEnd','damageZero']}, - forced:true, - popup:false, - audio:false, - vanish:true, - filter(event,player){ - return player.storage.mingkong?true:false; + mingkong2: { + trigger: { source: ["damageEnd", "damageZero"] }, + forced: true, + popup: false, + audio: false, + vanish: true, + filter(event, player) { + return player.storage.mingkong ? true : false; }, - content(){ + content() { player.draw(); - player.storage.mingkong=false; - player.removeSkill('mingkong2'); - } + player.storage.mingkong = false; + player.removeSkill("mingkong2"); + }, }, - yuehua:{ - trigger:{player:['useCardAfter','respondAfter','discardAfter']}, - frequent:true, - filter(event,player){ - if(player==_status.currentPhase) return false; - if(event.cards){ - for(var i=0;i0; + ai: { + threaten: 0.7, }, - direct:true, - priority:-5, - content(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('qinglan',trigger.player),'he'); - next.logSkill=['qinglan',trigger.player]; - next.ai=function(card){ - if(trigger.num>1||!trigger.source){ - if(get.attitude(player,trigger.player)>0){ - return 9-get.value(card); + }, + qinglan: { + trigger: { global: "damageBefore" }, + filter(event, player) { + return Boolean(event.nature) && player.countCards("he") > 0; + }, + direct: true, + priority: -5, + content() { + "step 0"; + var next = player.chooseToDiscard(get.prompt("qinglan", trigger.player), "he"); + next.logSkill = ["qinglan", trigger.player]; + next.ai = function (card) { + if (trigger.num > 1 || !trigger.source) { + if (get.attitude(player, trigger.player) > 0) { + return 9 - get.value(card); } return -1; - } - else if(get.attitude(player,trigger.player)>0){ - if(trigger.player.hp==1){ - return 8-get.value(card); + } else if (get.attitude(player, trigger.player) > 0) { + if (trigger.player.hp == 1) { + return 8 - get.value(card); } - if(trigger.source.hp==trigger.source.maxHp){ - return 6-get.value(card); + if (trigger.source.hp == trigger.source.maxHp) { + return 6 - get.value(card); } - } - else if(get.attitude(player,trigger.source)>0&& - trigger.source.hp1){ - if(get.color(card)=='red') return 5-get.value(card); + } else if ( + get.attitude(player, trigger.source) > 0 && + trigger.source.hp < trigger.source.maxHp && + trigger.num <= 1 && + trigger.player.hp > 1 + ) { + if (get.color(card) == "red") return 5 - get.value(card); } return -1; - } - "step 1" - if(result.bool){ + }; + "step 1"; + if (result.bool) { trigger.cancel(); - if(trigger.source){ + if (trigger.source) { trigger.source.recover(); } - } - else{ + } else { event.finish(); } - "step 2" - if(trigger.source){ + "step 2"; + if (trigger.source) { trigger.source.draw(); } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - fanshi:{ - trigger:{player:'phaseDiscardAfter'}, - forced:true, - filter(event,player){ - return player.getStat('damage')>0; + fanshi: { + trigger: { player: "phaseDiscardAfter" }, + forced: true, + filter(event, player) { + return player.getStat("damage") > 0; }, - check(event,player){ - return player.hp==player.maxHp; + check(event, player) { + return player.hp == player.maxHp; }, - content(){ - "step 0" + content() { + "step 0"; player.loseHp(); - "step 1" + "step 1"; player.draw(); - } + }, }, - xuelu:{ - unique:true, - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return player.maxHp>player.hp&&player.countCards('he',{color:'red'})>0; + xuelu: { + unique: true, + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return player.maxHp > player.hp && player.countCards("he", { color: "red" }) > 0; }, // alter:true, - content(){ - "step 0" + content() { + "step 0"; player.chooseCardTarget({ - position:'he', - filterTarget(card,player,target){ - return player!=target; + position: "he", + filterTarget(card, player, target) { + return player != target; }, - filterCard(card,player){ - return get.color(card)=='red'&&lib.filter.cardDiscardable(card,player); + filterCard(card, player) { + return get.color(card) == "red" && lib.filter.cardDiscardable(card, player); }, - ai1(card){ - return 9-get.value(card); + ai1(card) { + return 9 - get.value(card); }, - ai2(target){ - return get.damageEffect(target,player,player,'fire'); + ai2(target) { + return get.damageEffect(target, player, player, "fire"); }, - prompt:get.prompt('xuelu') + prompt: get.prompt("xuelu"), }); - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('xuelu',event.target,'fire'); - if(get.is.altered('xuelu')){ - event.num=1; - } - else{ - event.num=Math.min(2,Math.ceil((player.maxHp-player.hp)/2)); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("xuelu", event.target, "fire"); + if (get.is.altered("xuelu")) { + event.num = 1; + } else { + event.num = Math.min(2, Math.ceil((player.maxHp - player.hp) / 2)); } player.discard(result.cards); - } - else{ + } else { event.finish(); } - "step 2" - if(event.target){ - event.target.damage(event.num,'fire'); + "step 2"; + if (event.target) { + event.target.damage(event.num, "fire"); } }, - ai:{ - maixie:true, - expose:0.2, - threaten(player,target){ - if(target.hp==1) return 3; - if(target.hp==2) return 1.5; + ai: { + maixie: true, + expose: 0.2, + threaten(player, target) { + if (target.hp == 1) return 3; + if (target.hp == 2) return 1.5; return 0.5; }, - effect:{ - target(card,player,target){ - if(!target.hasFriend()) return; - if(get.tag(card,'damage')){ - if(target.hp==target.maxHp) return [0,1]; + effect: { + target(card, player, target) { + if (!target.hasFriend()) return; + if (get.tag(card, "damage")) { + if (target.hp == target.maxHp) return [0, 1]; } - if(get.tag(card,'recover')&&player.hp>=player.maxHp-1) return [0,0]; - } - } - } - }, - xiuhua_old:{ - changeSeat:true, - trigger:{player:'shaHit'}, - filter(event,player){ - return event.target!=player.previous; - }, - content(){ - game.swapSeat(trigger.target,player,true,true); - } - }, - shahun:{ - enable:'chooseToUse', - skillAnimation:true, - animationColor:'fire', - derivation:'juejing', - // alter:true, - filter(event,player){ - return !player.storage.shahun&&player.hp<=0; - }, - content(){ - "step 0" - var cards=player.getCards('hej'); - player.discard(cards); - "step 1" - if(player.isLinked()) player.link(); - "step 2" - if(player.isTurnedOver()) player.turnOver(); - "step 3" - player.draw(3); - "step 4" - player.recover(1-player.hp); - player.removeSkill('fanshi'); - player.addSkill('juejing'); - player.storage.shahun=2; - player.markSkill('shahun'); - game.addVideo('storage',player,['shahun',player.storage.shahun]); - }, - group:'shahun2', - intro:{ - content:'turn' - }, - ai:{ - save:true, - skillTagFilter(player){ - if(player.storage.shahun) return false; - if(player.hp>0) return false; - }, - result:{ - player:3 - } - } - }, - shahun2:{ - trigger:{player:'phaseAfter'}, - forced:true, - filter(event,player){ - return player.storage.shahun?true:false; - }, - content(){ - if(player.storage.shahun>1){ - player.storage.shahun--; - game.addVideo('storage',player,['shahun',player.storage.shahun]); - } - else{ - player.die(); - } - } - }, - yanjia_old:{ - enable:'chooseToUse', - filter(event,player){ - return player.countCards('he',{type:'equip'})>0; - }, - filterCard(card){ - return get.type(card)=='equip'; - }, - position:'he', - viewAs:{name:'wuzhong'}, - prompt:'将一张装备牌当无中生有使用', - check(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); - } - if(player.countCards('h')= player.maxHp - 1) return [0, 0]; }, }, - order:4, - } + }, }, - qianjun:{ - trigger:{player:'useCard'}, - direct:true, - filter(event,player){ - if(event.card.name!='sha') return false; - if(event.targets.length!=1) return false; - if(!player.countCards('he')) return false; - var target=event.targets[0]; - return game.hasPlayer(function(current){ - return player!=current&&target!=current&&get.distance(target,current)<=1; + xiuhua_old: { + changeSeat: true, + trigger: { player: "shaHit" }, + filter(event, player) { + return event.target != player.previous; + }, + content() { + game.swapSeat(trigger.target, player, true, true); + }, + }, + shahun: { + enable: "chooseToUse", + skillAnimation: true, + animationColor: "fire", + derivation: "juejing", + // alter:true, + filter(event, player) { + return !player.storage.shahun && player.hp <= 0; + }, + content() { + "step 0"; + var cards = player.getCards("hej"); + player.discard(cards); + "step 1"; + if (player.isLinked()) player.link(); + "step 2"; + if (player.isTurnedOver()) player.turnOver(); + "step 3"; + player.draw(3); + "step 4"; + player.recover(1 - player.hp); + player.removeSkill("fanshi"); + player.addSkill("juejing"); + player.storage.shahun = 2; + player.markSkill("shahun"); + game.addVideo("storage", player, ["shahun", player.storage.shahun]); + }, + group: "shahun2", + intro: { + content: "turn", + }, + ai: { + save: true, + skillTagFilter(player) { + if (player.storage.shahun) return false; + if (player.hp > 0) return false; + }, + result: { + player: 3, + }, + }, + }, + shahun2: { + trigger: { player: "phaseAfter" }, + forced: true, + filter(event, player) { + return player.storage.shahun ? true : false; + }, + content() { + if (player.storage.shahun > 1) { + player.storage.shahun--; + game.addVideo("storage", player, ["shahun", player.storage.shahun]); + } else { + player.die(); + } + }, + }, + yanjia_old: { + enable: "chooseToUse", + filter(event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + filterCard(card) { + return get.type(card) == "equip"; + }, + position: "he", + viewAs: { name: "wuzhong" }, + prompt: "将一张装备牌当无中生有使用", + check(card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); + } + if (player.countCards("h") < player.hp) { + return 6 - get.value(card); + } + return 2 - get.equipValue(card); + }, + ai: { + order: 9, + threaten: 1.1, + }, + }, + jizhan: { + enable: "phaseUse", + usable: 1, + changeSeat: true, + filterTarget(card, player, target) { + return player != target && player.next != target && player.canUse("sha", target, false); + }, + filter(event, player) { + var min = Math.max(1, player.maxHp - player.hp); + return lib.filter.filterCard({ name: "sha" }, player); + }, + content() { + game.swapSeat(player, target, true, true); + player.useCard({ name: "sha" }, target, false); + }, + ai: { + result: { + target(player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, + }, + order: 4, + }, + }, + qianjun: { + trigger: { player: "useCard" }, + direct: true, + filter(event, player) { + if (event.card.name != "sha") return false; + if (event.targets.length != 1) return false; + if (!player.countCards("he")) return false; + var target = event.targets[0]; + return game.hasPlayer(function (current) { + return player != current && target != current && get.distance(target, current) <= 1; }); }, - content(){ - "step 0" - event.targets=game.filterPlayer(function(current){ - var target=trigger.targets[0]; - return player!=current&&target!=current&&get.distance(target,current)<=1; + content() { + "step 0"; + event.targets = game.filterPlayer(function (current) { + var target = trigger.targets[0]; + return player != current && target != current && get.distance(target, current) <= 1; }); - var num=0; - for(var i=0;i0&&player.storage.xuanning!=3; + xuanning1: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h", { type: "basic" }) > 0 && player.storage.xuanning != 3; }, - filterCard(card){ - return get.type(card)=='basic'; + filterCard(card) { + return get.type(card) == "basic"; }, - check(card){ - return 7-get.useful(card); + check(card) { + return 7 - get.useful(card); }, - content(){ - player.storage.xuanning=3; - player.markSkill('xuanning'); - game.addVideo('storage',player,['xuanning',player.storage.xuanning]); + content() { + player.storage.xuanning = 3; + player.markSkill("xuanning"); + game.addVideo("storage", player, ["xuanning", player.storage.xuanning]); }, - ai:{ - result:{ - player(player){ - var num=player.countCards('h'); - if(num>player.hp+1) return 1; - if(player.storage.xuanning>=2) return 0; - if(num>player.hp) return 1 - if(player.storage.xuanning>=1) return 0; + ai: { + result: { + player(player) { + var num = player.countCards("h"); + if (num > player.hp + 1) return 1; + if (player.storage.xuanning >= 2) return 0; + if (num > player.hp) return 1; + if (player.storage.xuanning >= 1) return 0; return 1; }, }, - order:5 - } + order: 5, + }, }, - xuanning2:{ - trigger:{player:'damageEnd'}, - forced:true, - filter(event,player){ - if(player.storage.xuanning){ - return (event.source&&event.source.countCards('he')>0); + xuanning2: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { + if (player.storage.xuanning) { + return event.source && event.source.countCards("he") > 0; } return false; }, - logTarget:'source', - content(){ - var he=trigger.source.getCards('he'); - if(he.length){ + logTarget: "source", + content() { + var he = trigger.source.getCards("he"); + if (he.length) { trigger.source.discard(he.randomGet()); } player.storage.xuanning--; - if(!player.storage.xuanning){ - player.unmarkSkill('xuanning'); + if (!player.storage.xuanning) { + player.unmarkSkill("xuanning"); } - game.addVideo('storage',player,['xuanning',player.storage.xuanning]); + game.addVideo("storage", player, ["xuanning", player.storage.xuanning]); + }, + ai: { + maixie_defend: true, }, - ai:{ - maixie_defend:true, - } }, - liuguang:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ - if(player.storage.xuanning) return true; + liuguang: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { + if (player.storage.xuanning) return true; return false; }, - content(){ - "step 0" - player.chooseTarget(function(card,player,target){ - return player!=target; - },get.prompt('liuguang'),[1,3]).ai=function(target){ - return get.damageEffect(target,player,player); - } - "step 1" - if(result.bool){ + content() { + "step 0"; + player.chooseTarget( + function (card, player, target) { + return player != target; + }, + get.prompt("liuguang"), + [1, 3] + ).ai = function (target) { + return get.damageEffect(target, player, player); + }; + "step 1"; + if (result.bool) { player.storage.xuanning--; - if(!player.storage.xuanning){ - player.unmarkSkill('xuanning'); + if (!player.storage.xuanning) { + player.unmarkSkill("xuanning"); } - event.targets=result.targets.slice(0); + event.targets = result.targets.slice(0); event.targets.sort(lib.sort.seat); - player.logSkill('liuguang',result.targets); - game.addVideo('storage',player,['xuanning',player.storage.xuanning]); - } - else{ + player.logSkill("liuguang", result.targets); + game.addVideo("storage", player, ["xuanning", player.storage.xuanning]); + } else { event.finish(); } - "step 2" - if(event.targets.length){ - var target=event.targets.shift(); - var next=target.chooseToDiscard('流光:弃置一张牌或受到1点伤害','he'); - next.ai=function(card){ - if(get.damageEffect(_status.event.player,player,_status.event.player)>=0) return -1; - if(_status.event.player.hp==1) return 9-get.value(card); - return 8-get.value(card); + "step 2"; + if (event.targets.length) { + var target = event.targets.shift(); + var next = target.chooseToDiscard("流光:弃置一张牌或受到1点伤害", "he"); + next.ai = function (card) { + if (get.damageEffect(_status.event.player, player, _status.event.player) >= 0) + return -1; + if (_status.event.player.hp == 1) return 9 - get.value(card); + return 8 - get.value(card); }; - next.autochoose=function(){ - return this.player.countCards('he')==0; + next.autochoose = function () { + return this.player.countCards("he") == 0; }; - event.current=target; - } - else{ + event.current = target; + } else { event.finish(); } - "step 3" - if(result.bool&&result.cards&&result.cards.length){ + "step 3"; + if (result.bool && result.cards && result.cards.length) { event.goto(2); - } - else{ + } else { event.current.damage(); } }, - ai:{ - expose:0.2, - threaten:1.3 - } + ai: { + expose: 0.2, + threaten: 1.3, + }, }, - yangming:{ - enable:'phaseUse', - filter(event,player){ - if(player.storage.yangming2>0) return false; - return player.countCards('h',{color:'red'})>0; + yangming: { + enable: "phaseUse", + filter(event, player) { + if (player.storage.yangming2 > 0) return false; + return player.countCards("h", { color: "red" }) > 0; }, - filterCard(card){ - return get.color(card)=='red'; + filterCard(card) { + return get.color(card) == "red"; }, - content(){ - player.storage.yangming2=2; - player.addSkill('yangming2'); - game.addVideo('storage',player,['yangming2',player.storage.yangming2]); + content() { + player.storage.yangming2 = 2; + player.addSkill("yangming2"); + game.addVideo("storage", player, ["yangming2", player.storage.yangming2]); }, - check(card){ - return 6-get.value(card); + check(card) { + return 6 - get.value(card); }, - ai:{ - result:{ - player(player){ - if(player.countCards('h')<=player.hp&&player.hp==player.maxHp){ + ai: { + result: { + player(player) { + if (player.countCards("h") <= player.hp && player.hp == player.maxHp) { return 0; } return 1; - } + }, }, - order:6, - threaten:1.3 - } + order: 6, + threaten: 1.3, + }, }, - yangming2:{ - trigger:{player:'phaseUseEnd'}, - direct:true, - mark:true, - content(){ - "step 0" + yangming2: { + trigger: { player: "phaseUseEnd" }, + direct: true, + mark: true, + content() { + "step 0"; player.storage.yangming2--; - game.addVideo('storage',player,['yangming2',player.storage.yangming2]); - if(player.storage.yangming2>0){ + game.addVideo("storage", player, ["yangming2", player.storage.yangming2]); + if (player.storage.yangming2 > 0) { event.finish(); - } - else{ - player.removeSkill('yangming2'); - var num=game.countPlayer(function(current){ - return get.distance(player,current)<=1&¤t.isDamaged(); + } else { + player.removeSkill("yangming2"); + var num = game.countPlayer(function (current) { + return get.distance(player, current) <= 1 && current.isDamaged(); }); - if(num==0){ + if (num == 0) { event.finish(); - } - else{ - player.chooseTarget(function(card,player,target){ - return get.distance(player,target)<=1&&target.hp1) return false; - if(target.hp>2) return false; - if(get.attitude(player,target)>=0) return false; - return get.damageEffect(target,player,player,'fire'); - } - } - } + ai: { + order: 1, + result: { + player(player, target) { + if (player.hp > 1) return false; + if (target.hp > 2) return false; + if (get.attitude(player, target) >= 0) return false; + return get.damageEffect(target, player, player, "fire"); + }, + }, + }, }, - jiehuo_old:{ - unique:true, - forbid:['infinity'], - skillAnimation:true, - animationColor:'fire', - init(player){ - player.storage.jiehuo=false; + jiehuo_old: { + unique: true, + forbid: ["infinity"], + skillAnimation: true, + animationColor: "fire", + init(player) { + player.storage.jiehuo = false; }, - enable:'phaseUse', - filter(event,player){ + enable: "phaseUse", + filter(event, player) { //if(player.maxHp<=1) return false; - return !player.storage.jiehuo + return !player.storage.jiehuo; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, // mark:true, - line:'fire', - filterTarget(card,player,target){ - return player!=target; + line: "fire", + filterTarget(card, player, target) { + return player != target; }, - selectTarget:-1, - content(){ - if(!player.storage.jiehuo2){ - player.storage.jiehuo2=player.maxHp; - player.addSkill('jiehuo2'); + selectTarget: -1, + content() { + if (!player.storage.jiehuo2) { + player.storage.jiehuo2 = player.maxHp; + player.addSkill("jiehuo2"); } - player.storage.jiehuo=true; - target.damage(Math.min(target.hp,player.storage.jiehuo2),'fire'); - } + player.storage.jiehuo = true; + target.damage(Math.min(target.hp, player.storage.jiehuo2), "fire"); + }, }, - jiehuo2:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - content(){ + jiehuo2: { + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + content() { player.die(); - } + }, }, - yuling:{ - unique:true, - locked:true, - group:['yuling1','yuling2','yuling3','yuling4','yuling5','yuling6'], - intro:{ - content:'time' + yuling: { + unique: true, + locked: true, + group: ["yuling1", "yuling2", "yuling3", "yuling4", "yuling5", "yuling6"], + intro: { + content: "time", }, // alter:true, - ai:{ - noh:true, - threaten:0.8, - effect:{ - target(card,player,target){ - if(card.name=='bingliang') return 0; - if(card.name=='lebu') return 1.5; - if(card.name=='guohe'){ - if(!target.countCards('e')) return 0; + ai: { + noh: true, + threaten: 0.8, + effect: { + target(card, player, target) { + if (card.name == "bingliang") return 0; + if (card.name == "lebu") return 1.5; + if (card.name == "guohe") { + if (!target.countCards("e")) return 0; return 0.5; } - if(card.name=='liuxinghuoyu') return 0; - } - } - } + if (card.name == "liuxinghuoyu") return 0; + }, + }, + }, }, - yuling1:{ - trigger:{player:['phaseDrawBefore','phaseDiscardBefore']}, - priority:10, - forced:true, - popup:false, - check(){ + yuling1: { + trigger: { player: ["phaseDrawBefore", "phaseDiscardBefore"] }, + priority: 10, + forced: true, + popup: false, + check() { return false; }, - content(){ + content() { trigger.cancel(); - } - }, - yuling2:{ - trigger:{player:['loseEnd','drawEnd'],global:'gameDrawAfter'}, - check(event,player){ - return player.countCards('h')<2; }, - priority:10, - forced:true, - filter(event,player){ - return player.countCards('h')<5; + }, + yuling2: { + trigger: { player: ["loseEnd", "drawEnd"], global: "gameDrawAfter" }, + check(event, player) { + return player.countCards("h") < 2; }, - content(){ - player.draw(5-player.countCards('h')); - } - }, - yuling3:{ - trigger:{player:'gainEnd'}, - priority:10, - forced:true, - filter(event,player){ - return player.countCards('h')>5; + priority: 10, + forced: true, + filter(event, player) { + return player.countCards("h") < 5; }, - check(event,player){ - return player.countCards('h')<2; + content() { + player.draw(5 - player.countCards("h")); }, - content(){ - player.chooseToDiscard(true,player.countCards('h')-5); - } }, - yuling4:{ - mod:{ - cardEnabled(card,player){ - if(_status.currentPhase!=player) return; - var num=2; - if(get.is.altered('yuling')) num=1; - if(player.countUsed()>=player.maxHp+num) return false; - } - } + yuling3: { + trigger: { player: "gainEnd" }, + priority: 10, + forced: true, + filter(event, player) { + return player.countCards("h") > 5; + }, + check(event, player) { + return player.countCards("h") < 2; + }, + content() { + player.chooseToDiscard(true, player.countCards("h") - 5); + }, }, - yuling5:{ - trigger:{player:['useCardAfter','phaseBegin']}, - silent:true, - content(){ - player.storage.yuling=player.maxHp+2-player.countUsed(); - } + yuling4: { + mod: { + cardEnabled(card, player) { + if (_status.currentPhase != player) return; + var num = 2; + if (get.is.altered("yuling")) num = 1; + if (player.countUsed() >= player.maxHp + num) return false; + }, + }, }, - yuling6:{ - trigger:{player:'phaseAfter'}, - silent:true, - content(){ + yuling5: { + trigger: { player: ["useCardAfter", "phaseBegin"] }, + silent: true, + content() { + player.storage.yuling = player.maxHp + 2 - player.countUsed(); + }, + }, + yuling6: { + trigger: { player: "phaseAfter" }, + silent: true, + content() { delete player.storage.yuling; - } + }, }, }, - translate:{ - gjqt_bailitusu:'百里屠苏', - gjqt_fengqingxue:'风晴雪', - gjqt_fanglansheng:'方兰生', - gjqt_xiangling:'襄铃', - gjqt_yinqianshang:'尹千觞', - gjqt_hongyu:'红玉', - gjqt_ouyangshaogong:'欧阳少恭', - gjqt_xunfang:'巽芳', + translate: { + gjqt_bailitusu: "百里屠苏", + gjqt_fengqingxue: "风晴雪", + gjqt_fanglansheng: "方兰生", + gjqt_xiangling: "襄铃", + gjqt_yinqianshang: "尹千觞", + gjqt_hongyu: "红玉", + gjqt_ouyangshaogong: "欧阳少恭", + gjqt_xunfang: "巽芳", - gjqt_yuewuyi:'乐无异', - gjqt_wenrenyu:'闻人羽', - gjqt_xiayize:'夏夷则', - gjqt_aruan:'阿阮', - gjqt_xieyi:'谢衣', - gjqt_yanjiaxieyi:'偃甲谢衣', - gjqt_chuqi:'初七', + gjqt_yuewuyi: "乐无异", + gjqt_wenrenyu: "闻人羽", + gjqt_xiayize: "夏夷则", + gjqt_aruan: "阿阮", + gjqt_xieyi: "谢衣", + gjqt_yanjiaxieyi: "偃甲谢衣", + gjqt_chuqi: "初七", - gjqt_beiluo:'北洛', - gjqt_yunwuyue:'云无月', - gjqt_cenying:'岑缨', + gjqt_beiluo: "北洛", + gjqt_yunwuyue: "云无月", + gjqt_cenying: "岑缨", - yunyou:'云游', - yunyou_info:'每两轮限一次,出牌阶段,你可以发现一张地图牌本局未使用过的地图牌并使用之。', - xuanzhen:'玄阵', + yunyou: "云游", + yunyou_info: "每两轮限一次,出牌阶段,你可以发现一张地图牌本局未使用过的地图牌并使用之。", + xuanzhen: "玄阵", // xuanzhen_bg:'阵', - xuanzhen_info:'每轮限一次,当你成为一名其他角色的卡牌惟一目标时,你可以发现一张牌代替此牌。', - qingshu:'青书', - qingshu_info:'结束阶段,你可以令一名角色永久获得一个你使用过且不是当前地图的地图牌效果(每个地图最多发动一次)。', - yanjiadan_heart:'偃甲蛋', - yanjiadan_heart_info:'可以当作紫阳丹、玉女元参或沙棠使用。', - yanjiadan_diamond:'偃甲蛋', - yanjiadan_diamond_info:'可以当作流风散、舒筋散或神火飞鸦使用。', - yanjiadan_club:'偃甲蛋', - yanjiadan_club_info:'可以当作天女散花、六骰格或锦里针使用。', - yanjiadan_spade:'偃甲蛋', - yanjiadan_spade_info:'可以当作飞镖、乾坤镖或龙须钩使用。', - lingyan:'灵偃', - lingyan_bg:'偃', - lingyan_info:'出牌阶段限一次,你可以将一张点数与武将牌上的牌均不同的手牌置于武将牌上,然后获得与其花色对应的一枚偃甲蛋。', - xunjian:'寻剑', - xunjian_info:'锁定技,每当你使用或打出一张牌,若牌堆中有同名牌,你有X的机率获得之,X为你的“灵偃”牌数/13。', - xunjian_old_info:'觉醒技,结束阶段,若你武将牌上有十三张牌,你失去技能灵偃并获得技能通天。', - tongtian:'通天', - tongtian_info:'锁定技,在你使用或打出一张牌后,若敌方角色手中有同名牌,你随机获得其中一张。', - xianju:'仙居', - xianju_info:'锁定技,奇数游戏轮次开始时,你获得潜行直到下一轮开始;偶数游戏轮次开始时,你随机获得一张机关牌。', - xuanci:'旋刺', - xuanci_info:'出牌阶段限一次,你可以将一张梅花牌当作飞镖使用;锁定技,你使用飞镖无距离限制,你使用飞镖后对目标结算后视为对目标使用一张杀。', - humeng:'湖梦', - humeng_sub:'偃甲谢衣', - humeng_info:'觉醒技,当你使用过4种不同的偃甲蛋后,你获得替身偃甲谢衣;觉醒技,当你进入濒死状态时,你弃置所有牌,摸四张牌,变身为初七并激活偃甲谢衣。', - yange:'魇歌', - yange_info:'游戏开始时,你获得数量等于敌方角色数的“魇”标记;准备阶段开始时,你可以移去一枚“魇”标记并变为一名其他存活角色的复制,此回合结束后你变回原角色。', - woxue:'卧雪', - woxue_info:'每当你于回合外使用或打出一张牌,你可以视为对当前回合角色使用【白霜】。', - lingnu:'灵怒', - lingnu_info:'锁定技,每当你造成1点伤害,你随机获得一个与杀相关的技能,技能在你行动3回合后消失(同一时间最多拥有3个以此法获得的技能)。', - zhenying:'振影', - zhenying_info:'每当你使用或打出一张非转化的黑色牌(装备或延时锦囊牌除外),你可以获得一张此牌的“替身”;你使用或打出“替身”牌后需弃置一张牌(没有则不弃);当前回合结束后,“替身”牌消失。', - cihong:'刺鸿', - cihong_bg:'鸿', - cihong_info:'每三轮限一次,结束阶段,你可以指定一名其他角色并可以依次选择:1. 弃置一张红色牌;2. 失去1点体力;3. 将武将牌翻至背面;每选择一项,视为对目标使用一张杀。', - lianjing:'莲境', - lianjing_info:'每两轮限一次,回合结束后,你可以选择至多2名其他角色,将其他角色移出游戏,然后你与所选的角色依次进行一个回合。', - zuiji:'醉饮', - zuiji_info:'出牌阶段,你可以将一张手牌或装备牌当作酒使用。', - manwu:'曼舞', - manwu_info:'在一名角色的结束阶段,若其手牌数为全场最少或之一,你可以令其摸一张牌。', - xfanghua:'芳华', - xfanghua_info:'在你成为红色牌的目标后,你可以回复1点体力。', - yunyin:'云音', - yunyin_info:'结束阶段,你可以弃置一张与本回合使用过的卡牌花色均不相同的手牌,视为使用一张基本牌或普通锦囊牌。', - shishui:'逝水', - shishui_info:'锁定技,每当你使用一张红色牌,你令目标失去1点体力。', - duhun:'渡魂', - duhun_info:'濒死阶段,你可以与一名体力值不超过你的体力上限的角色拼点,若你赢,你失去1点体力上限并与该角色交换体力值;若你没赢,你立即死亡。', - duhun_info_alter:'濒死阶段,你可以与一名体力值不超过你的体力上限的角色拼点,若你赢,你失去1点体力上限并将体力值回复至与该角色相同;若你没赢,你立即死亡。', - chizhen:'驰阵', - chizhen_info:'出牌阶段开始时,你可以摸X张牌并弃置X张牌,若你弃置了杀,可以视为使用一张决斗(X为你已损失的体力值且至少为1)。', - xidie:'戏蝶', - xidie2:'戏蝶', - xidie_info:'准备阶段,若你的手牌数大于体力值,可以弃置至多X张牌,并于结束阶段摸等量的牌,X为你的体力值与手牌数之差且不超过3。', - meihu:'魅狐', - meihu2:'魅狐', - meihu_info:'当你受到伤害后,可令伤害来源交给你一张手牌。', - jianwu:'剑舞', - jianwu_info:'锁定技,攻击范围不含你的角色无法闪避你的杀。', - meiying:'魅影', - meiying_info:'一名其他角色的回合结束时,若其未于此回合内使用过指定另一名角色为目标的牌,你可以弃置一张红色牌视为对其使用一张杀。', - zuizhan:'乱斩', - zuizhan_info:'每当你使用一张杀,可以摸一张牌,然后此杀随机增加一个额外目标。', - xlqianhuan:'千幻', - xlqianhuan_info:'回合结束后,若你已受伤,你可以回复1点体力并将武将牌翻面。若你的武将牌背面朝上,你不能使用卡牌,也不能成为卡牌的目标。', - fumo:'伏魔', - fumo_info:'每当你受到一次伤害,可以弃置两张颜色相同的手牌并对伤害来源造成1点雷电伤害。', - fanyin:'梵音', - fanyin_info:'结束阶段,你可以令一名角色复原武将牌并移除判定区内的牌;若其体力值是全场最少的之一,其回复1点体力。', - mingkong:'明空', - mingkong_info:'锁定技,若你没有手牌,你受到的伤害-1,然后伤害来源摸一张牌。', - qinglan:'晴岚', - qinglan_info:'每当有一名角色即将受到属性伤害,你可以弃置一张牌令其防止此伤害,然后伤害来源摸一张牌并回复1点体力。', - yuehua:'月华', - yuehua_info:'每当你于回合外使用、打出或弃置红色牌,你可以摸一张牌。', - xuelu:'血戮', - xuelu_info:'结束阶段,若你已受伤,你可以弃置一张红色牌并对一名其他角色造成1点火焰伤害;若你已损失体力值不少于3,改为造成2点火焰伤害。', - xuelu_info_alter:'结束阶段,若你已受伤,你可以弃置一张红色牌并对一名其他角色造成1点火焰伤害。', - fanshi:'反噬', - fanshi_info:'锁定技,弃牌阶段结束时,若你本回合内造成过伤害,你失去1点体力并摸一张牌。', - shahun:'煞魂', - shahun2:'煞魂', - shahun_info:'限定技,濒死阶段,你可以复原武将牌,弃置所有牌并摸三张牌,然后将体力回复至1;若如此做,你失去技能〖反噬〗,获得技能〖绝境〗,并于两回合后立即死亡。', - shahun_info_alter:'限定技,濒死阶段,你可以复原武将牌,弃置所有牌并摸三张牌,然后将体力回复至1;若如此做,你失去技能〖反噬〗,获得技能〖绝境〗,并于两回合后立即死亡。', + xuanzhen_info: "每轮限一次,当你成为一名其他角色的卡牌惟一目标时,你可以发现一张牌代替此牌。", + qingshu: "青书", + qingshu_info: + "结束阶段,你可以令一名角色永久获得一个你使用过且不是当前地图的地图牌效果(每个地图最多发动一次)。", + yanjiadan_heart: "偃甲蛋", + yanjiadan_heart_info: "可以当作紫阳丹、玉女元参或沙棠使用。", + yanjiadan_diamond: "偃甲蛋", + yanjiadan_diamond_info: "可以当作流风散、舒筋散或神火飞鸦使用。", + yanjiadan_club: "偃甲蛋", + yanjiadan_club_info: "可以当作天女散花、六骰格或锦里针使用。", + yanjiadan_spade: "偃甲蛋", + yanjiadan_spade_info: "可以当作飞镖、乾坤镖或龙须钩使用。", + lingyan: "灵偃", + lingyan_bg: "偃", + lingyan_info: + "出牌阶段限一次,你可以将一张点数与武将牌上的牌均不同的手牌置于武将牌上,然后获得与其花色对应的一枚偃甲蛋。", + xunjian: "寻剑", + xunjian_info: + "锁定技,每当你使用或打出一张牌,若牌堆中有同名牌,你有X的机率获得之,X为你的“灵偃”牌数/13。", + xunjian_old_info: "觉醒技,结束阶段,若你武将牌上有十三张牌,你失去技能灵偃并获得技能通天。", + tongtian: "通天", + tongtian_info: "锁定技,在你使用或打出一张牌后,若敌方角色手中有同名牌,你随机获得其中一张。", + xianju: "仙居", + xianju_info: + "锁定技,奇数游戏轮次开始时,你获得潜行直到下一轮开始;偶数游戏轮次开始时,你随机获得一张机关牌。", + xuanci: "旋刺", + xuanci_info: + "出牌阶段限一次,你可以将一张梅花牌当作飞镖使用;锁定技,你使用飞镖无距离限制,你使用飞镖后对目标结算后视为对目标使用一张杀。", + humeng: "湖梦", + humeng_sub: "偃甲谢衣", + humeng_info: + "觉醒技,当你使用过4种不同的偃甲蛋后,你获得替身偃甲谢衣;觉醒技,当你进入濒死状态时,你弃置所有牌,摸四张牌,变身为初七并激活偃甲谢衣。", + yange: "魇歌", + yange_info: + "游戏开始时,你获得数量等于敌方角色数的“魇”标记;准备阶段开始时,你可以移去一枚“魇”标记并变为一名其他存活角色的复制,此回合结束后你变回原角色。", + woxue: "卧雪", + woxue_info: "每当你于回合外使用或打出一张牌,你可以视为对当前回合角色使用【白霜】。", + lingnu: "灵怒", + lingnu_info: + "锁定技,每当你造成1点伤害,你随机获得一个与杀相关的技能,技能在你行动3回合后消失(同一时间最多拥有3个以此法获得的技能)。", + zhenying: "振影", + zhenying_info: + "每当你使用或打出一张非转化的黑色牌(装备或延时锦囊牌除外),你可以获得一张此牌的“替身”;你使用或打出“替身”牌后需弃置一张牌(没有则不弃);当前回合结束后,“替身”牌消失。", + cihong: "刺鸿", + cihong_bg: "鸿", + cihong_info: + "每三轮限一次,结束阶段,你可以指定一名其他角色并可以依次选择:1. 弃置一张红色牌;2. 失去1点体力;3. 将武将牌翻至背面;每选择一项,视为对目标使用一张杀。", + lianjing: "莲境", + lianjing_info: + "每两轮限一次,回合结束后,你可以选择至多2名其他角色,将其他角色移出游戏,然后你与所选的角色依次进行一个回合。", + zuiji: "醉饮", + zuiji_info: "出牌阶段,你可以将一张手牌或装备牌当作酒使用。", + manwu: "曼舞", + manwu_info: "在一名角色的结束阶段,若其手牌数为全场最少或之一,你可以令其摸一张牌。", + xfanghua: "芳华", + xfanghua_info: "在你成为红色牌的目标后,你可以回复1点体力。", + yunyin: "云音", + yunyin_info: + "结束阶段,你可以弃置一张与本回合使用过的卡牌花色均不相同的手牌,视为使用一张基本牌或普通锦囊牌。", + shishui: "逝水", + shishui_info: "锁定技,每当你使用一张红色牌,你令目标失去1点体力。", + duhun: "渡魂", + duhun_info: + "濒死阶段,你可以与一名体力值不超过你的体力上限的角色拼点,若你赢,你失去1点体力上限并与该角色交换体力值;若你没赢,你立即死亡。", + duhun_info_alter: + "濒死阶段,你可以与一名体力值不超过你的体力上限的角色拼点,若你赢,你失去1点体力上限并将体力值回复至与该角色相同;若你没赢,你立即死亡。", + chizhen: "驰阵", + chizhen_info: + "出牌阶段开始时,你可以摸X张牌并弃置X张牌,若你弃置了杀,可以视为使用一张决斗(X为你已损失的体力值且至少为1)。", + xidie: "戏蝶", + xidie2: "戏蝶", + xidie_info: + "准备阶段,若你的手牌数大于体力值,可以弃置至多X张牌,并于结束阶段摸等量的牌,X为你的体力值与手牌数之差且不超过3。", + meihu: "魅狐", + meihu2: "魅狐", + meihu_info: "当你受到伤害后,可令伤害来源交给你一张手牌。", + jianwu: "剑舞", + jianwu_info: "锁定技,攻击范围不含你的角色无法闪避你的杀。", + meiying: "魅影", + meiying_info: + "一名其他角色的回合结束时,若其未于此回合内使用过指定另一名角色为目标的牌,你可以弃置一张红色牌视为对其使用一张杀。", + zuizhan: "乱斩", + zuizhan_info: "每当你使用一张杀,可以摸一张牌,然后此杀随机增加一个额外目标。", + xlqianhuan: "千幻", + xlqianhuan_info: + "回合结束后,若你已受伤,你可以回复1点体力并将武将牌翻面。若你的武将牌背面朝上,你不能使用卡牌,也不能成为卡牌的目标。", + fumo: "伏魔", + fumo_info: "每当你受到一次伤害,可以弃置两张颜色相同的手牌并对伤害来源造成1点雷电伤害。", + fanyin: "梵音", + fanyin_info: + "结束阶段,你可以令一名角色复原武将牌并移除判定区内的牌;若其体力值是全场最少的之一,其回复1点体力。", + mingkong: "明空", + mingkong_info: "锁定技,若你没有手牌,你受到的伤害-1,然后伤害来源摸一张牌。", + qinglan: "晴岚", + qinglan_info: + "每当有一名角色即将受到属性伤害,你可以弃置一张牌令其防止此伤害,然后伤害来源摸一张牌并回复1点体力。", + yuehua: "月华", + yuehua_info: "每当你于回合外使用、打出或弃置红色牌,你可以摸一张牌。", + xuelu: "血戮", + xuelu_info: + "结束阶段,若你已受伤,你可以弃置一张红色牌并对一名其他角色造成1点火焰伤害;若你已损失体力值不少于3,改为造成2点火焰伤害。", + xuelu_info_alter: "结束阶段,若你已受伤,你可以弃置一张红色牌并对一名其他角色造成1点火焰伤害。", + fanshi: "反噬", + fanshi_info: "锁定技,弃牌阶段结束时,若你本回合内造成过伤害,你失去1点体力并摸一张牌。", + shahun: "煞魂", + shahun2: "煞魂", + shahun_info: + "限定技,濒死阶段,你可以复原武将牌,弃置所有牌并摸三张牌,然后将体力回复至1;若如此做,你失去技能〖反噬〗,获得技能〖绝境〗,并于两回合后立即死亡。", + shahun_info_alter: + "限定技,濒死阶段,你可以复原武将牌,弃置所有牌并摸三张牌,然后将体力回复至1;若如此做,你失去技能〖反噬〗,获得技能〖绝境〗,并于两回合后立即死亡。", - yanjia:'偃甲', - yanjia_info:'出牌阶段,你可以将两张非特殊装备牌合成为一张强化装备。', - xiuhua:'袖花', - xiuhua_info:'每当一件其他角色的装备因被替换或弃置进入弃牌堆,你可以获得之。', - liuying:'流影', - liuying_info:'每当你使用一张杀结算完毕后,你可以指定一名本回合未成为过你的杀的目标的角色,并亮出牌堆顶的一张牌,若为黑色,你对该角色使用一张杀。', - boyun:'拨云', - boyun1:'拨云', - boyun2:'拨云', - boyun_info:'在你的回合内,你可以弃置一张装备牌,并展示牌堆顶的一张牌,若其为装备牌,你须将其交给任意一张角色并对其造成1点伤害,否则你摸一张牌。', - jizhan:'疾战', - jizhan_info:'出牌阶段限一次,你可以将移动到任意一名角色的前一位,视为对其使用了一张不计入出杀次数的杀。', - qianjun:'千军', - qianjun_info:'每当你使用一张杀,你可以弃置一张牌,令距离目标1以内的所有角色成为额外目标。', - xuanning:'玄凝', - xuanning1:'玄凝', - xuanning2:'玄凝', - liuguang:'流光', - yangming:'养命', - yangming2:'养命', - xuanning_info:'出牌阶段,你可以弃置一基本牌,获得至多3个玄凝标记。当你受到伤害时,你失去一枚玄凝标记,伤害来源随机弃置一张牌。', - liuguang_info:'准备阶段,若你有玄凝标记,你可以弃置一枚玄凝标记,选择至多三名角色依次令其选择一项:弃置一张牌,或受到1点伤害,并终止流光结算。', - yangming_info:'出牌阶段,你可以弃置一张红色牌,并在下个出牌阶段结束时令距离1以内的任意名角色回复1点体力,在此之前不可再次发动。', - zhaolu:'朝露', - jiehuo:'劫火', - yuling:'御灵', - yuling1:'御灵', - yuling2:'御灵', - yuling3:'御灵', - yuling4:'御灵', - zhaolu_info:'锁定技,每隔X回合,你失去1点体力上限,每当你受到1点伤害或有人死亡,视为减少两个回合,X为现存角色数且至多为5。', - jiehuo_info:'限定技,出牌阶段,你可以对一名其他角色造成2点火焰伤害,然后死亡。', - yuling_info:'锁定技,你没有摸牌和弃牌阶段,你的手牌数始终为5,你在一个出牌阶段最多使用X+2张牌,X为你的体力上限。', - yuling_info_alter:'锁定技,你没有摸牌和弃牌阶段,你的手牌数始终为5,你在一个出牌阶段最多使用X+1张牌,X为你的体力上限。', + yanjia: "偃甲", + yanjia_info: "出牌阶段,你可以将两张非特殊装备牌合成为一张强化装备。", + xiuhua: "袖花", + xiuhua_info: "每当一件其他角色的装备因被替换或弃置进入弃牌堆,你可以获得之。", + liuying: "流影", + liuying_info: + "每当你使用一张杀结算完毕后,你可以指定一名本回合未成为过你的杀的目标的角色,并亮出牌堆顶的一张牌,若为黑色,你对该角色使用一张杀。", + boyun: "拨云", + boyun1: "拨云", + boyun2: "拨云", + boyun_info: + "在你的回合内,你可以弃置一张装备牌,并展示牌堆顶的一张牌,若其为装备牌,你须将其交给任意一张角色并对其造成1点伤害,否则你摸一张牌。", + jizhan: "疾战", + jizhan_info: + "出牌阶段限一次,你可以将移动到任意一名角色的前一位,视为对其使用了一张不计入出杀次数的杀。", + qianjun: "千军", + qianjun_info: "每当你使用一张杀,你可以弃置一张牌,令距离目标1以内的所有角色成为额外目标。", + xuanning: "玄凝", + xuanning1: "玄凝", + xuanning2: "玄凝", + liuguang: "流光", + yangming: "养命", + yangming2: "养命", + xuanning_info: + "出牌阶段,你可以弃置一基本牌,获得至多3个玄凝标记。当你受到伤害时,你失去一枚玄凝标记,伤害来源随机弃置一张牌。", + liuguang_info: + "准备阶段,若你有玄凝标记,你可以弃置一枚玄凝标记,选择至多三名角色依次令其选择一项:弃置一张牌,或受到1点伤害,并终止流光结算。", + yangming_info: + "出牌阶段,你可以弃置一张红色牌,并在下个出牌阶段结束时令距离1以内的任意名角色回复1点体力,在此之前不可再次发动。", + zhaolu: "朝露", + jiehuo: "劫火", + yuling: "御灵", + yuling1: "御灵", + yuling2: "御灵", + yuling3: "御灵", + yuling4: "御灵", + zhaolu_info: + "锁定技,每隔X回合,你失去1点体力上限,每当你受到1点伤害或有人死亡,视为减少两个回合,X为现存角色数且至多为5。", + jiehuo_info: "限定技,出牌阶段,你可以对一名其他角色造成2点火焰伤害,然后死亡。", + yuling_info: + "锁定技,你没有摸牌和弃牌阶段,你的手牌数始终为5,你在一个出牌阶段最多使用X+2张牌,X为你的体力上限。", + yuling_info_alter: + "锁定技,你没有摸牌和弃牌阶段,你的手牌数始终为5,你在一个出牌阶段最多使用X+1张牌,X为你的体力上限。", }, }; }); diff --git a/character/gwent.js b/character/gwent.js index c4bfeeee0..0847264da 100644 --- a/character/gwent.js +++ b/character/gwent.js @@ -1,749 +1,818 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'gwent', - character:{ - gw_huoge:['male','qun',3,['gwjinli']], - gw_aisinie:['female','wu',3,['huihun']], - gw_enxier:['male','wei',4,['gwbaquan']], + name: "gwent", + character: { + gw_huoge: ["male", "qun", 3, ["gwjinli"]], + gw_aisinie: ["female", "wu", 3, ["huihun"]], + gw_enxier: ["male", "wei", 4, ["gwbaquan"]], - gw_kaerweite:['male','shu',4,['gwjiquan']], - gw_falanxisika:['female','wu',3,['shewu']], - gw_haluo:['male','qun',4,['nuhou']], + gw_kaerweite: ["male", "shu", 4, ["gwjiquan"]], + gw_falanxisika: ["female", "wu", 3, ["shewu"]], + gw_haluo: ["male", "qun", 4, ["nuhou"]], - gw_airuiting:['male','wei',4,['kuanglie']], - gw_laduoweide:['male','wei',4,['gwxiaoshou']], - gw_dagong:['male','qun',4,['gwtianbian']], + gw_airuiting: ["male", "wei", 4, ["kuanglie"]], + gw_laduoweide: ["male", "wei", 4, ["gwxiaoshou"]], + gw_dagong: ["male", "qun", 4, ["gwtianbian"]], - gw_bulanwang:['male','qun',4,['bolang']], - gw_kuite:['male','qun',4,['gwxuezhan']], - gw_fuertaisite:['male','wei',3,['zhengjun']], - gw_hengsaite:['male','wei',3,['jielue']], - gw_fulisi:['male','qun',3,['lanquan']], - gw_gaier:['male','shu',3,['hunmo']], + gw_bulanwang: ["male", "qun", 4, ["bolang"]], + gw_kuite: ["male", "qun", 4, ["gwxuezhan"]], + gw_fuertaisite: ["male", "wei", 3, ["zhengjun"]], + gw_hengsaite: ["male", "wei", 3, ["jielue"]], + gw_fulisi: ["male", "qun", 3, ["lanquan"]], + gw_gaier: ["male", "shu", 3, ["hunmo"]], - gw_jieluote:['male','qun',6,['fayin']], - gw_yenaifa:['female','qun',3,['xuezhou']], - gw_telisi:['female','wei',3,['huandie']], - gw_xili:['female','wu',3,['fengjian']], - gw_luoqi:['male','wei',4,['gwzhanjiang']], + gw_jieluote: ["male", "qun", 6, ["fayin"]], + gw_yenaifa: ["female", "qun", 3, ["xuezhou"]], + gw_telisi: ["female", "wei", 3, ["huandie"]], + gw_xili: ["female", "wu", 3, ["fengjian"]], + gw_luoqi: ["male", "wei", 4, ["gwzhanjiang"]], // gw_yioufeisi:['male','wu',4,['gwchuanxin']], - gw_aigeleisi:['female','wu',3,['gwshenyu']], - gw_aokeweisite:['male','qun',4,['yunhuo']], - gw_kaxier:['male','shu',4,['gwfengchi']], - gw_luobo:['male','qun',3,['junchi']], - gw_mieren:['male','shu',3,['lingji']], - gw_sanhanya:['male','shu',3,['gwjinyan']], - gw_shanhu:['female','qun',3,['shuijian']], - gw_zhangyujushou:['male','wu',4,['gwjushi']], - gw_zhuoertan:['male','wu',3,['hupeng']], + gw_aigeleisi: ["female", "wu", 3, ["gwshenyu"]], + gw_aokeweisite: ["male", "qun", 4, ["yunhuo"]], + gw_kaxier: ["male", "shu", 4, ["gwfengchi"]], + gw_luobo: ["male", "qun", 3, ["junchi"]], + gw_mieren: ["male", "shu", 3, ["lingji"]], + gw_sanhanya: ["male", "shu", 3, ["gwjinyan"]], + gw_shanhu: ["female", "qun", 3, ["shuijian"]], + gw_zhangyujushou: ["male", "wu", 4, ["gwjushi"]], + gw_zhuoertan: ["male", "wu", 3, ["hupeng"]], - gw_meizi:['female','wei',3,['gwjieyin']], - gw_aimin:['female','wu',3,['huanshu']], - gw_puxila:['female','qun',3,['gwqinwu']], + gw_meizi: ["female", "wei", 3, ["gwjieyin"]], + gw_aimin: ["female", "wu", 3, ["huanshu"]], + gw_puxila: ["female", "qun", 3, ["gwqinwu"]], - gw_xigedelifa:['female','qun',3,['gwfusheng']], - gw_laomaotou:['male','qun',4,['gwchenshui']], - gw_qigaiwang:['male','qun',4,['julian']], + gw_xigedelifa: ["female", "qun", 3, ["gwfusheng"]], + gw_laomaotou: ["male", "qun", 4, ["gwchenshui"]], + gw_qigaiwang: ["male", "qun", 4, ["julian"]], - gw_bierna:['female','qun',3,['gwfengshi']], - gw_haizhiyezhu:['male','qun',4,['yangfan']], - gw_nitelila:['male','wei',4,['shuangxi']], + gw_bierna: ["female", "qun", 3, ["gwfengshi"]], + gw_haizhiyezhu: ["male", "qun", 4, ["yangfan"]], + gw_nitelila: ["male", "wei", 4, ["shuangxi"]], - gw_linjing:['male','wu',4,['gwyewu']], - gw_kanbi:['male','qun',1,['gwfutian']], - gw_nvyemo:['female','shu',3,['gwgouhun']], + gw_linjing: ["male", "wu", 4, ["gwyewu"]], + gw_kanbi: ["male", "qun", 1, ["gwfutian"]], + gw_nvyemo: ["female", "shu", 3, ["gwgouhun"]], - gw_kairuisi:['female','qun',3,['gwweitu']], - gw_oudimu:['male','shu',3,['gwjingshi']], - gw_shasixiwusi:['male','qun',4,['gwjingtian']], + gw_kairuisi: ["female", "qun", 3, ["gwweitu"]], + gw_oudimu: ["male", "shu", 3, ["gwjingshi"]], + gw_shasixiwusi: ["male", "qun", 4, ["gwjingtian"]], - gw_yioufeisisp:['male','wu',3,['gwminxiang']], - gw_lanbote:['male','qun',4,['gwlangshi']], - gw_fenghuang:['male','shu',4,['gwliaotian']], - gw_diandian:['male','wu',3,['gwhuanbi']], - gw_yisilinni:['female','wu',3,['gwhuanshuang']], - gw_feilafanruide:['male','wei',3,['yinzhang']], + gw_yioufeisisp: ["male", "wu", 3, ["gwminxiang"]], + gw_lanbote: ["male", "qun", 4, ["gwlangshi"]], + gw_fenghuang: ["male", "shu", 4, ["gwliaotian"]], + gw_diandian: ["male", "wu", 3, ["gwhuanbi"]], + gw_yisilinni: ["female", "wu", 3, ["gwhuanshuang"]], + gw_feilafanruide: ["male", "wei", 3, ["yinzhang"]], - gw_saqiya:['female','shu',4,['sqlongwu']] + gw_saqiya: ["female", "shu", 4, ["sqlongwu"]], }, - characterIntro:{ - gw_huoge:'那个老年痴呆?不知道他是活着还是已经被制成标本了!', - gw_aisinie:'树精皇后有着熔银做成的眼睛,冰冷铸钢的心脏。', - gw_gaier:'画作应该要传达情绪,而不是字句。', - gw_enxier:'我可没什么耐心,最好小心点,否则脑袋不保', + characterIntro: { + gw_huoge: "那个老年痴呆?不知道他是活着还是已经被制成标本了!", + gw_aisinie: "树精皇后有着熔银做成的眼睛,冰冷铸钢的心脏。", + gw_gaier: "画作应该要传达情绪,而不是字句。", + gw_enxier: "我可没什么耐心,最好小心点,否则脑袋不保", - gw_yenaifa:'魔法是艺术、混沌与科学的结合。因为魔法的确是一门技艺也是一种诅咒。', - gw_telisi:'我可以照顾我自己,相信我。', - gw_jieluote:'如果要付出这种代价才能拯救世界,那最好还是让世界消逝吧。', - gw_xili:'我想去哪,就去哪。', - gw_luoqi:'是个爱国者…还是个货真价实的王八蛋。', - gw_yioufeisi:'国王还是乞丐,两者有何区别,人类少一个算一个', + gw_yenaifa: "魔法是艺术、混沌与科学的结合。因为魔法的确是一门技艺也是一种诅咒。", + gw_telisi: "我可以照顾我自己,相信我。", + gw_jieluote: "如果要付出这种代价才能拯救世界,那最好还是让世界消逝吧。", + gw_xili: "我想去哪,就去哪。", + gw_luoqi: "是个爱国者…还是个货真价实的王八蛋。", + gw_yioufeisi: "国王还是乞丐,两者有何区别,人类少一个算一个", }, /** @type { importCharacterConfig['skill'] } */ - skill:{ - sqlongyin:{ - trigger:{player:'phaseBeginStart'}, - forced:true, - check(){ + skill: { + sqlongyin: { + trigger: { player: "phaseBeginStart" }, + forced: true, + check() { return false; }, - init(player){ - player.storage.sqlongyin='sqlongwu'; + init(player) { + player.storage.sqlongyin = "sqlongwu"; }, - content(){ - var list=['sqlongnu','sqlonghuo','sqlongwu']; - var map={ - sqlongwu:'gw_saqiya', - sqlongnu:'gw_saqiya1', - sqlonghuo:'gw_saqiya2' - } + content() { + var list = ["sqlongnu", "sqlonghuo", "sqlongwu"]; + var map = { + sqlongwu: "gw_saqiya", + sqlongnu: "gw_saqiya1", + sqlonghuo: "gw_saqiya2", + }; list.remove(player.storage.sqlongyin); - if(list.length==2){ - var name=list.randomGet(); + if (list.length == 2) { + var name = list.randomGet(); player.removeSkill(player.storage.sqlongyin); player.addSkill(name); - player.storage.sqlongyin=name; - player.setAvatar('gw_saqiya',map[name]); + player.storage.sqlongyin = name; + player.setAvatar("gw_saqiya", map[name]); } - } + }, }, - sqlongnu:{ - group:'sqlongyin', - trigger:{player:'phaseBegin'}, - frequent:true, - content(){ - 'step 0' - player.discoverCard(ui.cardPile.childNodes,function(button){ - var card=button.link; - var player=_status.event.player; - var value=get.value(card,player); - if(player.countCards('h',card.name)){ - value=Math.max(value,9); - } - return value; - },'nogain'); - 'step 1' - if(player.countCards('h',function(card){ - return card!=result.card&&card.name==result.card.name; - })){ - event.current=result.card; - player.chooseTarget('是否改为对一名角色造成1点火属性伤害?').set('ai',function(target){ - return get.damageEffect(target,null,player,player,'fire'); - }); - } - else{ - player.gain(result.card,'draw'); + sqlongnu: { + group: "sqlongyin", + trigger: { player: "phaseBegin" }, + frequent: true, + content() { + "step 0"; + player.discoverCard( + ui.cardPile.childNodes, + function (button) { + var card = button.link; + var player = _status.event.player; + var value = get.value(card, player); + if (player.countCards("h", card.name)) { + value = Math.max(value, 9); + } + return value; + }, + "nogain" + ); + "step 1"; + if ( + player.countCards("h", function (card) { + return card != result.card && card.name == result.card.name; + }) + ) { + event.current = result.card; + player + .chooseTarget("是否改为对一名角色造成1点火属性伤害?") + .set("ai", function (target) { + return get.damageEffect(target, null, player, player, "fire"); + }); + } else { + player.gain(result.card, "draw"); event.finish(); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - target.damage('fire','nocard'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + target.damage("fire", "nocard"); // player.discoverCard(ui.cardPile.childNodes); - } - else{ - player.gain(event.current,'draw'); + } else { + player.gain(event.current, "draw"); } }, }, - sqlonghuo:{ - group:'sqlongyin', - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0; + sqlonghuo: { + group: "sqlongyin", + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0; }, - delay:false, - content(){ - 'step 0' - var hs=player.getCards('h'); - player.discard(hs).set('delay',false); - event.hs=hs; - 'step 1' + delay: false, + content() { + "step 0"; + var hs = player.getCards("h"); + player.discard(hs).set("delay", false); + event.hs = hs; + "step 1"; player.draw(event.hs.length); - 'step 2' - var enemies=player.getEnemies(); - for(var i=0;i0; + ai: { + order: 5, + result: { + player: 1, + }, }, - content(){ - 'step 0' - var max=1; - var map={}; - var hs=player.getCards('h'); - for(var i=0;i 0; + }, + content() { + "step 0"; + var max = 1; + var map = {}; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { + var name = hs[i].name; + if (!map[name]) { + map[name] = 1; + } else { map[name]++; - if(map[name]>max){ - max=map[name]; + if (map[name] > max) { + max = map[name]; } } } player.draw(max); - 'step 1' + "step 1"; player.chooseToUse(); - } + }, }, - jielue:{ - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - var list=player.getFriends(); - for(var i=0;i0; + var rand = get.rand(); + var aozu = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + current.hp <= 3 && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var aozu2=game.hasPlayer(function(current){ - return player.canUse('gw_aozuzhilei',current)&¤t.hp<=2&&get.effect(current,{name:'gw_aozuzhilei'},player,player)>0; + var aozu2 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + current.hp <= 2 && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var aozu3=game.hasPlayer(function(current){ - return player.canUse('gw_aozuzhilei',current)&&get.effect(current,{name:'gw_aozuzhilei'},player,player)>0; + var aozu3 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_aozuzhilei", current) && + get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0 + ); }); - var baoxue=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&&[2,3].includes(current.countCards('h'))&&!current.hasSkillTag('noh'); + var baoxue = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + [2, 3].includes(current.countCards("h")) && + !current.hasSkillTag("noh") + ); }); - var baoxue2=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&&[2].includes(current.countCards('h'))&&!current.hasSkillTag('noh'); + var baoxue2 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + [2].includes(current.countCards("h")) && + !current.hasSkillTag("noh") + ); }); - var baoxue3=game.hasPlayer(function(current){ - return player.canUse('gw_baoxueyaoshui',current)&&get.attitude(player,current)<0&¤t.countCards('h')>=2&&!current.hasSkillTag('noh'); + var baoxue3 = game.hasPlayer(function (current) { + return ( + player.canUse("gw_baoxueyaoshui", current) && + get.attitude(player, current) < 0 && + current.countCards("h") >= 2 && + !current.hasSkillTag("noh") + ); }); - var nongwu=game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&(get.attitude(player,current.getNext())<0||get.attitude(player,current.getPrevious())<0); + var nongwu = game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + (get.attitude(player, current.getNext()) < 0 || + get.attitude(player, current.getPrevious()) < 0) + ); }); - var nongwu2=game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&get.attitude(player,current.getNext())<0&&get.attitude(player,current.getPrevious())<0; + var nongwu2 = game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + get.attitude(player, current.getNext()) < 0 && + get.attitude(player, current.getPrevious()) < 0 + ); }); - var yanzi=game.hasPlayer(function(current){ - return get.attitude(player,current)>0&¤t.isMinHandcard(); + var yanzi = game.hasPlayer(function (current) { + return get.attitude(player, current) > 0 && current.isMinHandcard(); }); - player.chooseVCardButton(get.prompt('gwhuanshuang'),list.randomGets(3),'notype').ai=function(button){ - var name=button.link[2]; - switch(name){ - case 'gw_ciguhanshuang': - if(nongwu2) return 3; - if(nongwu) return 1; - return 0; - case 'gw_baoxueyaoshui': - if(baoxue2) return 2; - if(baoxue) return 1.5; - if(baoxue3) return 0.5; - return 0; - case 'gw_aozuzhilei': - if(aozu2) return 2.5; - if(aozu) return 1.2; - if(aozu3) return 0.2; - return 0; - case 'gw_yanziyaoshui': - if(yanzi) return 2; - return 0.6; - } - if(game.hasPlayer(function(current){ - return player.canUse(name,current)&&get.effect(current,{name:name},player,player)>0; - })){ - return Math.random(); - } - return 0; - }; - 'step 1' - if(result.bool){ - player.logSkill('gwhuanshuang'); - event.cardname=result.links[0][2]; - player.chooseUseTarget(true,event.cardname); - player.addTempSkill('gwhuanshuang_disable'); + player.chooseVCardButton(get.prompt("gwhuanshuang"), list.randomGets(3), "notype").ai = + function (button) { + var name = button.link[2]; + switch (name) { + case "gw_ciguhanshuang": + if (nongwu2) return 3; + if (nongwu) return 1; + return 0; + case "gw_baoxueyaoshui": + if (baoxue2) return 2; + if (baoxue) return 1.5; + if (baoxue3) return 0.5; + return 0; + case "gw_aozuzhilei": + if (aozu2) return 2.5; + if (aozu) return 1.2; + if (aozu3) return 0.2; + return 0; + case "gw_yanziyaoshui": + if (yanzi) return 2; + return 0.6; + } + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(name, current) && + get.effect(current, { name: name }, player, player) > 0 + ); + }) + ) { + return Math.random(); + } + return 0; + }; + "step 1"; + if (result.bool) { + player.logSkill("gwhuanshuang"); + event.cardname = result.links[0][2]; + player.chooseUseTarget(true, event.cardname); + player.addTempSkill("gwhuanshuang_disable"); } - 'step 2' - if(event.cardname&&player.hasUseTarget(event.cardname)){ - player.chooseUseTarget(true,event.cardname); + "step 2"; + if (event.cardname && player.hasUseTarget(event.cardname)) { + player.chooseUseTarget(true, event.cardname); } }, - ai:{ - threaten:1.6 + ai: { + threaten: 1.6, + }, + subSkill: { + disable: {}, }, - subSkill:{ - disable:{} - } }, - gw_xianzumaijiu:{ - trigger:{source:'damageEnd'}, - filter(event){ - return (event.card&&(event.card.name=='sha')); + gw_xianzumaijiu: { + trigger: { source: "damageEnd" }, + filter(event) { + return event.card && event.card.name == "sha"; }, - forced:true, - temp:true, - vanish:true, - onremove(player){ - if(player.node.jiu){ + forced: true, + temp: true, + vanish: true, + onremove(player) { + if (player.node.jiu) { player.node.jiu.delete(); player.node.jiu2.delete(); delete player.node.jiu; delete player.node.jiu2; } }, - content(){ - var list=player.getFriends(); + content() { + var list = player.getFriends(); list.add(player); game.asyncDraw(list); - player.removeSkill('gw_xianzumaijiu'); + player.removeSkill("gw_xianzumaijiu"); + }, + ai: { + damageBonus: true, }, - ai:{ - damageBonus:true - } }, - gwjinli:{ - enable:'phaseUse', - usable:1, - filterCard:true, - filterTarget(card,player,target){ - return !target.hasSkill('gwjinli_jiu'); + gwjinli: { + enable: "phaseUse", + usable: 1, + filterCard: true, + filterTarget(card, player, target) { + return !target.hasSkill("gwjinli_jiu"); }, - check(card){ - return 8-get.value(card); + check(card) { + return 8 - get.value(card); }, - content(){ - target.addSkill('gwjinli_jiu'); + content() { + target.addSkill("gwjinli_jiu"); }, - subSkill:{ - jiu:{ - init(player){ - player.storage.gwjinli_jiu=2; + subSkill: { + jiu: { + init(player) { + player.storage.gwjinli_jiu = 2; }, - onremove:true, - mark:'image', - intro:{ - content:'结束阶段,随机获得一个正面效果;&个回合后将先祖麦酒收入手牌' + onremove: true, + mark: "image", + intro: { + content: "结束阶段,随机获得一个正面效果;&个回合后将先祖麦酒收入手牌", }, - trigger:{player:'phaseEnd'}, - forced:true, - content(){ - 'step 0' + trigger: { player: "phaseEnd" }, + forced: true, + content() { + "step 0"; player.getBuff(); - 'step 1' + "step 1"; player.storage.gwjinli_jiu--; - if(player.storage.gwjinli_jiu<=0){ - player.removeSkill('gwjinli_jiu'); - player.gain(game.createCard('gw_xianzumaijiu'),'gain2'); + if (player.storage.gwjinli_jiu <= 0) { + player.removeSkill("gwjinli_jiu"); + player.gain(game.createCard("gw_xianzumaijiu"), "gain2"); + } else { + player.updateMark("gwjinli_jiu", true); } - else{ - player.updateMark('gwjinli_jiu',true); - } - } - } + }, + }, + }, + ai: { + threaten: 1.5, + order: 2, + result: { + target(player, target) { + return 1 / (1 + target.hp) / Math.sqrt(1 + target.countCards("h")); + }, + }, }, - ai:{ - threaten:1.5, - order:2, - result:{ - target(player,target){ - return 1/(1+target.hp)/Math.sqrt(1+target.countCards('h')); - } - } - } }, - gwliaotian:{ - enable:'phaseUse', - delay:0, - usable:2, - filter(event,player){ - var hs=player.getCards('h'); - if(hs.length<2) return false; - var color=get.color(hs[0]); - for(var i=1;i0){ - return 11-get.value(card); - } - return 7-get.value(card); - }).set('promptx',[event.card]); - } - else{ + if (list.length) { + event.target = list.randomGet(); + event.target + .chooseCard( + "h", + "是否交给" + get.translation(event.player) + "一张手牌并获得冒险牌?" + ) + .set("ai", function (card) { + if (get.attitude(event.target, player) > 0) { + return 11 - get.value(card); + } + return 7 - get.value(card); + }) + .set("promptx", [event.card]); + } else { event.finish(); } - 'step 3' - if(result.bool){ - event.target.line(player,'green'); - event.target.give(result.cards,player); - event.target.gain(game.createCard(event.card),'gain2'); + "step 3"; + if (result.bool) { + event.target.line(player, "green"); + event.target.give(result.cards, player); + event.target.gain(game.createCard(event.card), "gain2"); } }, - ai:{ - order:8, - result:{ - player:1 - } - } + ai: { + order: 8, + result: { + player: 1, + }, + }, }, - gwmaoxian_old:{ - trigger:{global:'gameStart',player:['enterGame','phaseBefore']}, - forced:true, - filter(event,player){ + gwmaoxian_old: { + trigger: { global: "gameStart", player: ["enterGame", "phaseBefore"] }, + forced: true, + filter(event, player) { return !player.storage.gwmaoxian; }, - content(){ - player.storage.gwmaoxian=10; - player.storage.gwmaoxian_skill=[]; - event.insert(lib.skill.gwmaoxian.learn,{player:player}); + content() { + player.storage.gwmaoxian = 10; + player.storage.gwmaoxian_skill = []; + event.insert(lib.skill.gwmaoxian.learn, { player: player }); }, - learn(){ - var list={ - draw:{ - bronze:[1,'准备阶段,你获得一张随机铜卡法术'], - basic:[1,'准备阶段,你从牌堆中获得一张杀'], - silver:[2,'结束阶段,你获得一张随机银卡法术'], - trick:[3,'结束阶段,你发现一张普通锦囊牌'], - gold:[3,'出牌阶段开始时,你获得一张随机金卡法术'], - equip:[3,'出牌阶段开始时,你在装备区内的空余位置装备一件随机装备'], + learn() { + var list = { + draw: { + bronze: [1, "准备阶段,你获得一张随机铜卡法术"], + basic: [1, "准备阶段,你从牌堆中获得一张杀"], + silver: [2, "结束阶段,你获得一张随机银卡法术"], + trick: [3, "结束阶段,你发现一张普通锦囊牌"], + gold: [3, "出牌阶段开始时,你获得一张随机金卡法术"], + equip: [3, "出牌阶段开始时,你在装备区内的空余位置装备一件随机装备"], }, - attack:{ - sha:[1,'你可以将一张手牌当作杀使用'], - huogong:[1,'你可以将一张手牌当作火攻使用'], - aoe:[2,'出牌阶段限一次,你可以弃置两张牌,视为使用一张南蛮入侵'], - shas:[2,'每当你使用一张杀,你可以追加一名无视距离的目标'], + attack: { + sha: [1, "你可以将一张手牌当作杀使用"], + huogong: [1, "你可以将一张手牌当作火攻使用"], + aoe: [2, "出牌阶段限一次,你可以弃置两张牌,视为使用一张南蛮入侵"], + shas: [2, "每当你使用一张杀,你可以追加一名无视距离的目标"], }, - defend:{ - }, - assist:{ - }, - control:{ - } - } - } + defend: {}, + assist: {}, + control: {}, + }; + }, }, - gwminxiang_old:{ - group:['gwminxiang_count','gwminxiang_clear','gwminxiang_use'], - subSkill:{ - count:{ - trigger:{player:'phaseBegin'}, - silent:true, - content(){ - player.storage.gwminxiang=[]; - } + gwminxiang_old: { + group: ["gwminxiang_count", "gwminxiang_clear", "gwminxiang_use"], + subSkill: { + count: { + trigger: { player: "phaseBegin" }, + silent: true, + content() { + player.storage.gwminxiang = []; + }, }, - clear:{ - trigger:{player:'phaseAfter'}, - silent:true, - content(){ + clear: { + trigger: { player: "phaseAfter" }, + silent: true, + content() { delete player.storage.gwminxiang; - } + }, }, - use:{ - trigger:{player:'useCardAfter'}, - silent:true, - filter(event,player){ - if(_status.currentPhase!=player) return false; - var type=get.type(event.card); - if(type!='trick'&&type!='basic') return false; - if(get.info(event.card).multitarget) return false; - if(!player.storage.gwminxiang) return false; + use: { + trigger: { player: "useCardAfter" }, + silent: true, + filter(event, player) { + if (_status.currentPhase != player) return false; + var type = get.type(event.card); + if (type != "trick" && type != "basic") return false; + if (get.info(event.card).multitarget) return false; + if (!player.storage.gwminxiang) return false; return true; }, - content(){ + content() { player.storage.gwminxiang.add(trigger.card); - } - } + }, + }, }, - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - if(player.storage.gwminxiang){ - for(var i=0;i1){ + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + if (player.storage.gwminxiang) { + for (var i = 0; i < player.storage.gwminxiang.length; i++) { + var card = player.storage.gwminxiang[i]; + if ( + game.countPlayer(function (current) { + return ( + current != player && lib.filter.targetEnabled3(card, player, current) + ); + }) > 1 + ) { return true; } } } return false; }, - content(){ - 'step 0' - var list=[]; - for(var i=0;i1){ + content() { + "step 0"; + var list = []; + for (var i = 0; i < player.storage.gwminxiang.length; i++) { + var card = player.storage.gwminxiang[i]; + if ( + game.countPlayer(function (current) { + return current != player && lib.filter.targetEnabled3(card, player, current); + }) > 1 + ) { list.push(card); } } - var skip=['shunshou','huogong','shandianjian','jiu']; - player.chooseCardButton(get.prompt('gwminxiang'),list).set('ai',function(button){ - if(skip.includes(button.link.name)) return 0; - var val=get.value(button.link); - if(get.tag(button.link,'damage')){ - val+=3; + var skip = ["shunshou", "huogong", "shandianjian", "jiu"]; + player.chooseCardButton(get.prompt("gwminxiang"), list).set("ai", function (button) { + if (skip.includes(button.link.name)) return 0; + var val = get.value(button.link); + if (get.tag(button.link, "damage")) { + val += 3; } return val; }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('选择两个目标互相使用'+get.translation(event.card),2,function(cardx,player,target){ - return target!=player&&lib.filter.targetEnabled3(card,player,target); - }).set('ai',function(target){ - if(ui.selected.targets.length){ - return get.effect(target,card,ui.selected.targets[0],player); - } - return get.effect(target,card,target,player); - }).set('targetprompt',['先出牌','后出牌']); - } - else{ + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + "选择两个目标互相使用" + get.translation(event.card), + 2, + function (cardx, player, target) { + return ( + target != player && lib.filter.targetEnabled3(card, player, target) + ); + } + ) + .set("ai", function (target) { + if (ui.selected.targets.length) { + return get.effect(target, card, ui.selected.targets[0], player); + } + return get.effect(target, card, target, player); + }) + .set("targetprompt", ["先出牌", "后出牌"]); + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.$throw(event.card); - player.logSkill('gwminxiang',result.targets); - event.target1=result.targets[0]; - event.target2=result.targets[1]; + player.logSkill("gwminxiang", result.targets); + event.target1 = result.targets[0]; + event.target2 = result.targets[1]; game.delay(); - } - else{ + } else { event.finish(); } - 'step 3' - event.target1.useCard(event.card,event.target2,'noai'); - 'step 4' - if(event.target1.isIn()&&event.target2.isIn()){ - event.target2.useCard(event.card,event.target1,'noai'); + "step 3"; + event.target1.useCard(event.card, event.target2, "noai"); + "step 4"; + if (event.target1.isIn() && event.target2.isIn()) { + event.target2.useCard(event.card, event.target1, "noai"); } }, - ai:{ - expose:0.4, - threaten:1.6 - } + ai: { + expose: 0.4, + threaten: 1.6, + }, }, - gwminxiang:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - var hs=player.getCards('h'); - var names=[]; - for(var i=0;i1){ + for (var i = 0; i < names.length; i++) { + if ( + game.countPlayer(function (current) { + return ( + current != player && + lib.filter.targetEnabled3({ name: names[i] }, player, current) + ); + }) > 1 + ) { return true; } } return false; }, - check(card){ - if(['shunshou','huogong','shandianjian','jiu','tianxianjiu'].includes(card.name)) return 0; - if(get.tag(card,'damage')){ - return get.value(card)+2; + check(card) { + if (["shunshou", "huogong", "shandianjian", "jiu", "tianxianjiu"].includes(card.name)) + return 0; + if (get.tag(card, "damage")) { + return get.value(card) + 2; } return get.value(card); }, - filterCard(card,player){ - if(!['basic','trick'].includes(get.type(card))) return false; - return game.countPlayer(function(current){ - return current!=player&&lib.filter.targetEnabled3({name:card.name},player,current); - })>1; + filterCard(card, player) { + if (!["basic", "trick"].includes(get.type(card))) return false; + return ( + game.countPlayer(function (current) { + return ( + current != player && + lib.filter.targetEnabled3({ name: card.name }, player, current) + ); + }) > 1 + ); }, - filterTarget(card,player,target){ - if(player==target||!ui.selected.cards.length) return false; - return lib.filter.targetEnabled3({name:ui.selected.cards[0].name},player,target); + filterTarget(card, player, target) { + if (player == target || !ui.selected.cards.length) return false; + return lib.filter.targetEnabled3({ name: ui.selected.cards[0].name }, player, target); }, - targetprompt:['先出牌','后出牌'], - selectTarget:2, - multitarget:true, - delay:0, - content(){ - 'step 0' + targetprompt: ["先出牌", "后出牌"], + selectTarget: 2, + multitarget: true, + delay: 0, + content() { + "step 0"; player.draw(); - 'step 1' - targets[0].useCard({name:cards[0].name},targets[1],'noai'); - 'step 2' - if(targets[0].isIn()&&targets[1].isIn()){ - targets[1].useCard({name:cards[0].name},targets[0],'noai'); + "step 1"; + targets[0].useCard({ name: cards[0].name }, targets[1], "noai"); + "step 2"; + if (targets[0].isIn() && targets[1].isIn()) { + targets[1].useCard({ name: cards[0].name }, targets[0], "noai"); } }, // group:'gwminxiang_draw', - multiline:true, + multiline: true, // subSkill:{ // draw:{ // trigger:{global:'damageAfter'}, @@ -757,52 +826,56 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // } // }, - ai:{ - order:8, - result:{ - target(player,target){ - if(!ui.selected.cards.length) return 0; - return get.effect(target,{name:ui.selected.cards[0].name},target,target); - } + ai: { + order: 8, + result: { + target(player, target) { + if (!ui.selected.cards.length) return 0; + return get.effect(target, { name: ui.selected.cards[0].name }, target, target); + }, }, - expose:0.4, - threaten:1.6, - } + expose: 0.4, + threaten: 1.6, + }, }, - gwlangshi:{ - trigger:{source:'damageEnd'}, - direct:true, - filter(event,player){ - if(event.parent.name=='gwlangshi') return false; - return game.hasPlayer(function(current){ - return current!=event.player&¤t!=player&¤t.hp>=event.player.hp; + gwlangshi: { + trigger: { source: "damageEnd" }, + direct: true, + filter(event, player) { + if (event.parent.name == "gwlangshi") return false; + return game.hasPlayer(function (current) { + return current != event.player && current != player && current.hp >= event.player.hp; }); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('gwlangshi'),function(card,player,target){ - return target!=trigger.player&&target!=player&&target.hp>=trigger.player.hp; - }).set('ai',function(target){ - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - player.logSkill('gwlangshi',result.targets); + content() { + "step 0"; + player + .chooseTarget(get.prompt2("gwlangshi"), function (card, player, target) { + return ( + target != trigger.player && target != player && target.hp >= trigger.player.hp + ); + }) + .set("ai", function (target) { + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("gwlangshi", result.targets); result.targets[0].damage(player); } }, - ai:{ - threaten:1.5 - } + ai: { + threaten: 1.5, + }, }, - gwjingtian:{ - clickable(player){ - player.addTempSkill('gwjingtian2'); + gwjingtian: { + clickable(player) { + player.addTempSkill("gwjingtian2"); player.directgain(get.cards()); player.$draw(); player.storage.gwjingtian--; - player.updateMark('gwjingtian',true); - player.logSkill('gwjingtian'); + player.updateMark("gwjingtian", true); + player.logSkill("gwjingtian"); if (_status.imchoosing) { delete _status.event._buttonChoice; delete _status.event._cardChoice; @@ -810,511 +883,518 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.check(); } }, - clickableFilter(player){ - return player.storage.gwjingtian>0&&!player.hasSkill('gwjingtian2'); + clickableFilter(player) { + return player.storage.gwjingtian > 0 && !player.hasSkill("gwjingtian2"); }, - init(player){ - player.storage.gwjingtian=0; + init(player) { + player.storage.gwjingtian = 0; }, - trigger:{player:'phaseDrawBefore'}, - forced:true, - content(){ + trigger: { player: "phaseDrawBefore" }, + forced: true, + content() { trigger.cancel(); - player.storage.gwjingtian+=3; - player.updateMark('gwjingtian',true); + player.storage.gwjingtian += 3; + player.updateMark("gwjingtian", true); }, - group:'gwjingtian_ai', - mark:true, - intro:{ - mark(dialog,content,player){ - if(player.isUnderControl(true)){ - if(_status.gameStarted&&player.storage.gwjingtian>0&&!player.hasSkill('gwjingtian2')){ - dialog.add(ui.create.div('.menubutton.pointerdiv','点击发动',function(){ - if(!this.disabled){ - this.disabled=true; - this.classList.add('disabled'); - this.style.opacity=0.5; - lib.skill.gwjingtian.clickable(player); - } - })); + group: "gwjingtian_ai", + mark: true, + intro: { + mark(dialog, content, player) { + if (player.isUnderControl(true)) { + if ( + _status.gameStarted && + player.storage.gwjingtian > 0 && + !player.hasSkill("gwjingtian2") + ) { + dialog.add( + ui.create.div(".menubutton.pointerdiv", "点击发动", function () { + if (!this.disabled) { + this.disabled = true; + this.classList.add("disabled"); + this.style.opacity = 0.5; + lib.skill.gwjingtian.clickable(player); + } + }) + ); } - var list=[]; - var num=Math.min(9,ui.cardPile.childElementCount); - for(var i=0;i0&&!player.hasSkill('gwjingtian2'); + subSkill: { + ai: { + trigger: { global: "drawAfter" }, + filter(event, player) { + return ( + (_status.auto || !player.isUnderControl(true)) && + player.storage.gwjingtian > 0 && + !player.hasSkill("gwjingtian2") + ); }, - popup:false, - check(event,player){ - var value=0,card=ui.cardPile.firstChild; - if(card){ - value=get.value(card); + popup: false, + check(event, player) { + var value = 0, + card = ui.cardPile.firstChild; + if (card) { + value = get.value(card); } - if(value>=6) return true; - if(value>=5&&get.type(card)!='equip'&&player.storage.gwjingtian>=3) return true; - if(player.storage.gwjingtian>3&&value>3) return true; + if (value >= 6) return true; + if (value >= 5 && get.type(card) != "equip" && player.storage.gwjingtian >= 3) + return true; + if (player.storage.gwjingtian > 3 && value > 3) return true; return false; }, - content(){ + content() { lib.skill.gwjingtian.clickable(player); - } - } - } + }, + }, + }, }, - gwjingtian2:{}, - gwjingshi:{ - enable:'phaseUse', - usable:1, + gwjingtian2: {}, + gwjingshi: { + enable: "phaseUse", + usable: 1, //direct:true, //delay:0, - filter(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h'); - }) + filter(event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h"); + }); }, - content(){ - 'step 0' - var targets=game.filterPlayer(function(current){ - return current.countCards('h'); + content() { + "step 0"; + var targets = game.filterPlayer(function (current) { + return current.countCards("h"); }); - var num=targets.length; - for(var i=0;i0) return -1; + player.chooseButton(dialog, true).set("ai", function (button) { + if (get.attitude(player, get.owner(button.link)) > 0) return -1; return get.value(button.link); }); - } - else{ - player.popup('失败'); - game.log(player,'发动','【血契】','失败'); + } else { + player.popup("失败"); + game.log(player, "发动", "【血契】", "失败"); event.finish(); } - 'step 2' - if(result.bool&&result.links&&result.links.length){ - var owner=get.owner(result.links[0]); - if(owner){ - owner.give(result.links,player); + "step 2"; + if (result.bool && result.links && result.links.length) { + var owner = get.owner(result.links[0]); + if (owner) { + owner.give(result.links, player); player.line(owner); - } - else{ - player.gain(result.links,'gain2'); + } else { + player.gain(result.links, "gain2"); } } }, - ai:{ - order:10, - result:{ - player:10 - } - } + ai: { + order: 10, + result: { + player: 10, + }, + }, }, - gwweitu:{ - trigger:{player:'discardAfter'}, - forced:true, - filter(event,player){ - return player.hujia<3; + gwweitu: { + trigger: { player: "discardAfter" }, + forced: true, + filter(event, player) { + return player.hujia < 3; }, - content(){ + content() { player.changeHujia(); // var num=Math.min(trigger.cards.length,3-player.hujia); // if(num>0){ // player.changeHujia(); // } }, - init(player){ - player.storage.gwweitu=0; + init(player) { + player.storage.gwweitu = 0; }, - intro:{ - content:'护甲自上次计算起已抵挡#点伤害' + intro: { + content: "护甲自上次计算起已抵挡#点伤害", }, - group:'gwweitu_gain', - subSkill:{ - gain:{ - trigger: {player: 'changeHujiaAfter'}, + group: "gwweitu_gain", + subSkill: { + gain: { + trigger: { player: "changeHujiaAfter" }, filter: (event) => event.num < 0, - forced:true, - content(){ + forced: true, + content() { player.storage.gwweitu++; - if(player.storage.gwweitu>=3){ - player.storage.gwweitu-=3; - player.unmarkSkill('gwweitu'); - var list=get.typeCard('spell_silver'); - if(list.length){ - player.gain(game.createCard(list.randomGet()),'draw'); + if (player.storage.gwweitu >= 3) { + player.storage.gwweitu -= 3; + player.unmarkSkill("gwweitu"); + var list = get.typeCard("spell_silver"); + if (list.length) { + player.gain(game.createCard(list.randomGet()), "draw"); } + } else { + player.markSkill("gwweitu", true); } - else{ - player.markSkill('gwweitu',true); - } - } - } + }, + }, }, - ai:{ - threaten:0.7, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'discard')&&target.hujia<3&& - target.countCards('he')&¤t<0){ + ai: { + threaten: 0.7, + effect: { + target(card, player, target, current) { + if ( + get.tag(card, "discard") && + target.hujia < 3 && + target.countCards("he") && + current < 0 + ) { return 0; } }, - player(card,player){ - if(player.hujia>=3) return; - if(_status.event.name!='chooseToUse'||_status.event.player!=player) return; - if(get.type(card)=='basic') return; - if(get.tag(card,'gain')) return; - if(get.value(card,player,'raw')>=7) return; - if(player.needsToDiscard()>1) return; - return 'zeroplayertarget'; - } - } - } + player(card, player) { + if (player.hujia >= 3) return; + if (_status.event.name != "chooseToUse" || _status.event.player != player) return; + if (get.type(card) == "basic") return; + if (get.tag(card, "gain")) return; + if (get.value(card, player, "raw") >= 7) return; + if (player.needsToDiscard() > 1) return; + return "zeroplayertarget"; + }, + }, + }, }, - gwgouhun:{ - enable:'phaseUse', - usable:1, - filterCard:true, - discard:false, - prepare:'give', - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; + gwgouhun: { + enable: "phaseUse", + usable: 1, + filterCard: true, + discard: false, + prepare: "give", + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - content(){ - 'step 0' - target.gain(cards,player); - event.card=cards[0]; - event.suit=get.suit(cards[0]); - 'step 1' - var hs=target.getCards('h'); - var num1=0; - var num2=0; - for(var i=0;i2&&num2>3){ + if (num1 && num2) { + target.chooseControlList(list, true, function () { + if (num1 > 2 && num2 > 3) { return 2; } - if(num1>num2/2){ + if (num1 > num2 / 2) { return 1; - } - else if(num12) return 1; + } else if (num1) { + list.splice(1, 1); + target.chooseControlList(list, true, function () { + if (num1 > 2) return 1; return 0; }); - } - else if(num2){ - list.splice(0,1); - target.chooseControlList(list,true,function(){ - if(num2>3) return 1; + } else if (num2) { + list.splice(0, 1); + target.chooseControlList(list, true, function () { + if (num2 > 3) return 1; return 0; }); - } - else{ - target.goMad({player:'phaseAfter'}); + } else { + target.goMad({ player: "phaseAfter" }); event.finish(); } - 'step 2' - var index=result.index; - var cards1=target.getCards('h',function(card){ - return get.suit(card)==event.suit; + "step 2"; + var index = result.index; + var cards1 = target.getCards("h", function (card) { + return get.suit(card) == event.suit; }); - var cards2=target.getCards('h',function(card){ - return get.suit(card)!=event.suit; + var cards2 = target.getCards("h", function (card) { + return get.suit(card) != event.suit; }); - if(typeof index=='number'){ - if(event.num1&&event.num2){ - if(index==0){ - target.give(cards1,player); - } - else if(index==1){ + if (typeof index == "number") { + if (event.num1 && event.num2) { + if (index == 0) { + target.give(cards1, player); + } else if (index == 1) { target.discard(cards2); + } else { + target.goMad({ player: "phaseAfter" }); } - else{ - target.goMad({player:'phaseAfter'}); - } - } - else{ - if(index==1){ - target.goMad({player:'phaseAfter'}); - } - else if(event.num1){ - target.give(cards1,player); - } - else{ + } else { + if (index == 1) { + target.goMad({ player: "phaseAfter" }); + } else if (event.num1) { + target.give(cards1, player); + } else { target.discard(cards2); } } } }, - ai:{ - threaten:1.5, - order:9, - result:{ - target(player,target){ - return -Math.sqrt(target.countCards('h')); - } - } - } - }, - gwfutian:{ - trigger:{player:'damageBefore'}, - forced:true, - content(){ - trigger.cancel(); - }, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'damage')) return [0,0]; - } + ai: { + threaten: 1.5, + order: 9, + result: { + target(player, target) { + return -Math.sqrt(target.countCards("h")); + }, }, }, - init(player){ - player.storage.gwfutian=0; + }, + gwfutian: { + trigger: { player: "damageBefore" }, + forced: true, + content() { + trigger.cancel(); }, - intro:{ - content:'弃置的牌总点数:#' + ai: { + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "damage")) return [0, 0]; + }, + }, }, - unique:true, - onremove:true, - group:'gwfutian_discard', - subSkill:{ - discard:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + init(player) { + player.storage.gwfutian = 0; + }, + intro: { + content: "弃置的牌总点数:#", + }, + unique: true, + onremove: true, + group: "gwfutian_discard", + subSkill: { + discard: { + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - content(){ - 'step 0' - player.chooseTarget('覆天:弃置一名角色的一张手牌',function(card,player,target){ - return target!=player&&target.countCards('h'); - },true).set('ai',function(target){ - if(target.hasSkillTag('noh')) return 0; - return -get.attitude(player,target)/Math.sqrt(target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.discardPlayerCard(target,'h',true); - player.line(target,'green'); - } - else{ + content() { + "step 0"; + player + .chooseTarget( + "覆天:弃置一名角色的一张手牌", + function (card, player, target) { + return target != player && target.countCards("h"); + }, + true + ) + .set("ai", function (target) { + if (target.hasSkillTag("noh")) return 0; + return -get.attitude(player, target) / Math.sqrt(target.countCards("h")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.discardPlayerCard(target, "h", true); + player.line(target, "green"); + } else { event.finish(); } - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - player.storage.gwfutian+=get.number(result.cards[0]); - player.markSkill('gwfutian',true); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + player.storage.gwfutian += get.number(result.cards[0]); + player.markSkill("gwfutian", true); } - 'step 3' - if(player.storage.gwfutian>=24){ - player.$skill('覆天','legend','metal'); - player.removeSkill('gwfutian'); - player.addSkill('gwzhongmo'); - player.setAvatar('gw_kanbi','gw_hanmuduoer'); - player.maxHp+=4; - player.hp=player.maxHp; + "step 3"; + if (player.storage.gwfutian >= 24) { + player.$skill("覆天", "legend", "metal"); + player.removeSkill("gwfutian"); + player.addSkill("gwzhongmo"); + player.setAvatar("gw_kanbi", "gw_hanmuduoer"); + player.maxHp += 4; + player.hp = player.maxHp; player.update(); } - } - } - } + }, + }, + }, }, - gwzhongmo:{ - trigger:{player:'phaseDrawBefore'}, - forced:true, - content(){ + gwzhongmo: { + trigger: { player: "phaseDrawBefore" }, + forced: true, + content() { trigger.cancel(); - var list=['bronze','silver','gold']; + var list = ["bronze", "silver", "gold"]; list.randomRemove(); - var cards=[]; - for(var i=0;iget.type(event.card)!='equip'&&player.hasCard(card=>get.color(card)==get.color(event.card)&&player.canRecast(card),'h'), - content(){ - 'step 0' - var cards=player.getCards('h',card=>get.suit(card)==get.suit(trigger.card)&&player.canRecast(card)); - if(!cards.length) cards=player.getCards('h',card=>get.color(card)==get.color(trigger.card)&&player.canRecast(card)); - if(!cards.length){ + yangfan: { + trigger: { player: "useCard" }, + forced: true, + filter: (event, player) => + get.type(event.card) != "equip" && + player.hasCard( + (card) => get.color(card) == get.color(event.card) && player.canRecast(card), + "h" + ), + content() { + "step 0"; + var cards = player.getCards( + "h", + (card) => get.suit(card) == get.suit(trigger.card) && player.canRecast(card) + ); + if (!cards.length) + cards = player.getCards( + "h", + (card) => get.color(card) == get.color(trigger.card) && player.canRecast(card) + ); + if (!cards.length) { event.finish(); return; } player.recast(cards.randomGet()); }, - ai:{ - pretao:true - } + ai: { + pretao: true, + }, }, - gwfengshi:{ - trigger:{player:'phaseEnd'}, - direct:true, - content(){ - 'step 0' - player.chooseControlList(get.prompt('gwfengshi'),['为自己施加一个随机负面效果,并对两名随机敌人施加一个随机负面效果','为自己施加两个随机正面效果,并对一名随机敌人施加一个随机正面效果'],function(){ - if(player.getEnemies().length<2) return 1; - if(player.hp<=1) return 1; - if(player.hp==2&&Math.random()<0.5) return 1; - return 0; - }); - 'step 1' - if(result.index!=2){ - player.logSkill('gwfengshi'); - if(result.index==0){ - event.debuff=[player].addArray(player.getEnemies().randomGets(2)); + gwfengshi: { + trigger: { player: "phaseEnd" }, + direct: true, + content() { + "step 0"; + player.chooseControlList( + get.prompt("gwfengshi"), + [ + "为自己施加一个随机负面效果,并对两名随机敌人施加一个随机负面效果", + "为自己施加两个随机正面效果,并对一名随机敌人施加一个随机正面效果", + ], + function () { + if (player.getEnemies().length < 2) return 1; + if (player.hp <= 1) return 1; + if (player.hp == 2 && Math.random() < 0.5) return 1; + return 0; } - else{ - event.buff=[player,player,player.getEnemies().randomGet()]; + ); + "step 1"; + if (result.index != 2) { + player.logSkill("gwfengshi"); + if (result.index == 0) { + event.debuff = [player].addArray(player.getEnemies().randomGets(2)); + } else { + event.buff = [player, player, player.getEnemies().randomGet()]; } - } - else{ + } else { event.finish(); } - 'step 2' - if(event.debuff&&event.debuff.length){ - player.line(event.debuff.shift().getDebuff(false).addExpose(0.1),'green'); + "step 2"; + if (event.debuff && event.debuff.length) { + player.line(event.debuff.shift().getDebuff(false).addExpose(0.1), "green"); event.redo(); } - 'step 3' - if(event.buff&&event.buff.length){ - player.line(event.buff.shift().getBuff(false).addExpose(0.1),'green'); + "step 3"; + if (event.buff && event.buff.length) { + player.line(event.buff.shift().getBuff(false).addExpose(0.1), "green"); event.redo(); } - 'step 4' + "step 4"; game.delay(); - } + }, }, - gwchenshui:{ - trigger:{player:'damageBefore',source:'damageBefore'}, - forced:true, - init(player){ - player.storage.gwchenshui=0; + gwchenshui: { + trigger: { player: "damageBefore", source: "damageBefore" }, + forced: true, + init(player) { + player.storage.gwchenshui = 0; }, - mark:true, - intro:{ - content(storage){ - if(!storage){ - return '未发动过沉睡效果'; + mark: true, + intro: { + content(storage) { + if (!storage) { + return "未发动过沉睡效果"; + } else { + return "累计发动过" + storage + "次沉睡效果"; } - else{ - return '累计发动过'+storage+'次沉睡效果'; - } - } + }, }, - logTarget(event,player){ - if(player==event.source) return event.player; + logTarget(event, player) { + if (player == event.source) return event.player; return event.source; }, - content(){ + content() { trigger.cancel(); player.storage.gwchenshui++; player.updateMarks(); - if(trigger.source!=trigger.player&&trigger.source.isIn()&&trigger.player.isIn()){ - var cards=trigger.player.getCards('he'); - if(cards.length){ - trigger.player.give(cards.randomGet(),trigger.source); + if (trigger.source != trigger.player && trigger.source.isIn() && trigger.player.isIn()) { + var cards = trigger.player.getCards("he"); + if (cards.length) { + trigger.player.give(cards.randomGet(), trigger.source); } } }, - onremove:true, - group:'gwchenshui_juexing', - subSkill:{ - juexing:{ - trigger:{player:'phaseEnd'}, - filter(event,player){ - return player.storage.gwchenshui>=3; + onremove: true, + group: "gwchenshui_juexing", + subSkill: { + juexing: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return player.storage.gwchenshui >= 3; }, - skillAnimation:true, - animationStr:'觉醒', - forced:true, - content(){ - 'step 0' - player.removeSkill('gwchenshui'); - player.setAvatar('gw_laomaotou','gw_laomaotou2'); - event.list=player.getEnemies().sortBySeat(); - 'step 1' - if(event.list.length){ - var target=event.list.shift(); - player.line(target,'green'); + skillAnimation: true, + animationStr: "觉醒", + forced: true, + content() { + "step 0"; + player.removeSkill("gwchenshui"); + player.setAvatar("gw_laomaotou", "gw_laomaotou2"); + event.list = player.getEnemies().sortBySeat(); + "step 1"; + if (event.list.length) { + var target = event.list.shift(); + player.line(target, "green"); target.damage(); event.redo(); } - 'step 2' - player.addSkill('gwliedi'); - } - } - }, - ai:{ - threaten:0.6, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(!target.countCards('he')) return 'zeroplayertarget'; - } - } - } - } - }, - gwliedi:{ - trigger:{source:'damageBegin'}, - forced:true, - filter(event,player){ - return event.player!=player&&player.distanceTo(event.player)>=2; - }, - content(){ - trigger.num+=Math.floor(Math.max(1,player.distanceTo(trigger.player))/2); - }, - group:['gwliedi_sleep','gwliedi_damage'], - onremove:true, - subSkill:{ - damage:{ - trigger:{source:'damageEnd'}, - silent:true, - filter(event,player){ - return event.player!=player; - }, - content(){ - player.storage.gwliedi=-1; + "step 2"; + player.addSkill("gwliedi"); }, }, - sleep:{ - trigger:{player:'phaseEnd'}, - silent:true, - content(){ - if(player.storage.gwliedi!=1){ - if(player.storage.gwliedi==-1){ - player.storage.gwliedi=0; - } - else{ - player.storage.gwliedi=1; - } + }, + ai: { + threaten: 0.6, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (!target.countCards("he")) return "zeroplayertarget"; } - else{ - player.logSkill('gwliedi'); - player.addSkill('gwchenshui'); - player.removeSkill('gwliedi'); - player.setAvatar('gw_laomaotou','gw_laomaotou'); - } - } - } - } + }, + }, + }, }, - julian:{ - trigger:{player:'phaseUseBegin'}, - frequent:true, - filter(event,player){ + gwliedi: { + trigger: { source: "damageBegin" }, + forced: true, + filter(event, player) { + return event.player != player && player.distanceTo(event.player) >= 2; + }, + content() { + trigger.num += Math.floor(Math.max(1, player.distanceTo(trigger.player)) / 2); + }, + group: ["gwliedi_sleep", "gwliedi_damage"], + onremove: true, + subSkill: { + damage: { + trigger: { source: "damageEnd" }, + silent: true, + filter(event, player) { + return event.player != player; + }, + content() { + player.storage.gwliedi = -1; + }, + }, + sleep: { + trigger: { player: "phaseEnd" }, + silent: true, + content() { + if (player.storage.gwliedi != 1) { + if (player.storage.gwliedi == -1) { + player.storage.gwliedi = 0; + } else { + player.storage.gwliedi = 1; + } + } else { + player.logSkill("gwliedi"); + player.addSkill("gwchenshui"); + player.removeSkill("gwliedi"); + player.setAvatar("gw_laomaotou", "gw_laomaotou"); + } + }, + }, + }, + }, + julian: { + trigger: { player: "phaseUseBegin" }, + frequent: true, + filter(event, player) { return !player.isMaxHandcard(); }, - content(){ - var num=0; - for(var i=0;i0){ + var dh = num - player.countCards("h"); + if (dh > 0) { player.draw(dh); } - } + }, }, - gwfusheng:{ - enable:'chooseToUse', - filter(event,player){ - return event.type=='dying'&&event.dying&&!event.dying.isTurnedOver(); + gwfusheng: { + enable: "chooseToUse", + filter(event, player) { + return event.type == "dying" && event.dying && !event.dying.isTurnedOver(); }, - filterTarget(card,player,target){ - return target==_status.event.dying; + filterTarget(card, player, target) { + return target == _status.event.dying; }, - selectTarget:-1, - content(){ + selectTarget: -1, + content() { target.turnOver(); target.recover(); - if(player!=target){ - game.asyncDraw([player,target]); - } - else{ + if (player != target) { + game.asyncDraw([player, target]); + } else { player.draw(2); } }, - ai:{ - order:0.1, - skillTagFilter(player){ - if(!_status.event.dying||_status.event.dying.isTurnedOver()) return false; + ai: { + order: 0.1, + skillTagFilter(player) { + if (!_status.event.dying || _status.event.dying.isTurnedOver()) return false; }, - save:true, - result:{ - target:3 + save: true, + result: { + target: 3, }, - threaten:1.6 + threaten: 1.6, }, }, - gwqinwu:{ - trigger:{player:'useCard'}, - usable:1, - filter(event,player){ - return get.type(event.card)=='basic'; + gwqinwu: { + trigger: { player: "useCard" }, + usable: 1, + filter(event, player) { + return get.type(event.card) == "basic"; }, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt2('gwqinwu')).ai=function(target){ - var att=get.attitude(player,target); - if(att<=0) return 0; - if(att<3) return att; - att=10-get.distance(player,target,'absolute')/game.players.length; - if(target.hasSkill('gwqinwu')){ - att/=1.5; + direct: true, + content() { + "step 0"; + player.chooseTarget(get.prompt2("gwqinwu")).ai = function (target) { + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (att < 3) return att; + att = 10 - get.distance(player, target, "absolute") / game.players.length; + if (target.hasSkill("gwqinwu")) { + att /= 1.5; } - if(target.hasJudge('lebu')||target.skipList.includes('phaseUse')){ - att/=2; + if (target.hasJudge("lebu") || target.skipList.includes("phaseUse")) { + att /= 2; } return att; - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gwqinwu',target); - target.draw(); - if(!target.hasSkill('gwqinwu')){ - target.addTempSkill('gwqinwu',{player:'phaseAfter'}); - target.addTempSkill('gwqinwu2',{player:'phaseAfter'}); - } - } - }, - ai:{ - threaten:1.5 - } - }, - gwqinwu2:{ - mark:true, - intro:{ - content:'获得【琴舞】直到下一回合结束' - } - }, - huanshu:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return player.countCards('h')>0&&!player.hasSkill('huangshu2'); - }, - content(){ - "step 0" - player.chooseCard(get.prompt2('huanshu')).ai=function(card){ - return 6-get.value(card); }; - "step 1" - if(result.bool){ - player.$give(result.cards,player); - player.logSkill('huanshu'); - player.storage.huanshu2=result.cards[0]; - player.lose(result.cards,ui.special); - player.addSkill('huanshu2'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gwqinwu", target); + target.draw(); + if (!target.hasSkill("gwqinwu")) { + target.addTempSkill("gwqinwu", { player: "phaseAfter" }); + target.addTempSkill("gwqinwu2", { player: "phaseAfter" }); + } } }, - ai:{ - threaten:1.4 + ai: { + threaten: 1.5, }, }, - huanshu2:{ - intro:{ - content(storage,player){ - if(player.isUnderControl(true)){ - return '当一名敌方角色使用'+get.translation(get.color(storage))+'锦囊牌时,移去'+get.translation(storage)+',取消锦囊的效果,并摸两张牌'; - } - else{ - return '当一名敌方角色使用与“幻术”牌颜色相同的锦囊牌时,移去“幻术”牌,取消锦囊的效果,并摸两张牌'; + gwqinwu2: { + mark: true, + intro: { + content: "获得【琴舞】直到下一回合结束", + }, + }, + huanshu: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return player.countCards("h") > 0 && !player.hasSkill("huangshu2"); + }, + content() { + "step 0"; + player.chooseCard(get.prompt2("huanshu")).ai = function (card) { + return 6 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.$give(result.cards, player); + player.logSkill("huanshu"); + player.storage.huanshu2 = result.cards[0]; + player.lose(result.cards, ui.special); + player.addSkill("huanshu2"); + } + }, + ai: { + threaten: 1.4, + }, + }, + huanshu2: { + intro: { + content(storage, player) { + if (player.isUnderControl(true)) { + return ( + "当一名敌方角色使用" + + get.translation(get.color(storage)) + + "锦囊牌时,移去" + + get.translation(storage) + + ",取消锦囊的效果,并摸两张牌" + ); + } else { + return "当一名敌方角色使用与“幻术”牌颜色相同的锦囊牌时,移去“幻术”牌,取消锦囊的效果,并摸两张牌"; } }, - onunmark(storage,player){ - if(storage){ + onunmark(storage, player) { + if (storage) { storage.discard(); delete player.storage.huanshu2; } - } + }, }, - trigger:{global:'useCard'}, - forced:true, - filter(event,player){ - return player.getEnemies().includes(event.player)&& - get.type(event.card,'trick')=='trick'&&get.color(event.card)==get.color(player.storage.huanshu2); + trigger: { global: "useCard" }, + forced: true, + filter(event, player) { + return ( + player.getEnemies().includes(event.player) && + get.type(event.card, "trick") == "trick" && + get.color(event.card) == get.color(player.storage.huanshu2) + ); }, - mark:true, - content(){ - 'step 0' + mark: true, + content() { + "step 0"; game.delayx(); player.addExpose(0.1); trigger.player.addExpose(0.1); - 'step 1' - player.showCards(player.storage.huanshu2,get.translation(player)+'发动了【幻术】'); - 'step 2' - player.removeSkill('huanshu2'); + "step 1"; + player.showCards(player.storage.huanshu2, get.translation(player) + "发动了【幻术】"); + "step 2"; + player.removeSkill("huanshu2"); trigger.cancel(); player.draw(2); }, - group:'huanshu3' + group: "huanshu3", }, - huanshu3:{ - trigger:{player:'phaseBegin'}, - forced:true, - content(){ + huanshu3: { + trigger: { player: "phaseBegin" }, + forced: true, + content() { player.$throw(player.storage.huanshu2); - game.log(player,'弃置了',player.storage.huanshu2); - player.removeSkill('huanshu2'); - } + game.log(player, "弃置了", player.storage.huanshu2); + player.removeSkill("huanshu2"); + }, }, - gwjieyin:{ - group:'gwjieyin_reset', - init(player){ - player.storage.gwjieyin=[]; + gwjieyin: { + group: "gwjieyin_reset", + init(player) { + player.storage.gwjieyin = []; }, - enable:'phaseUse', - filter(event,player){ - return player.storage.gwjieyin.length<3; + enable: "phaseUse", + filter(event, player) { + return player.storage.gwjieyin.length < 3; }, - chooseButton:{ - dialog(event,player){ - return ui.create.dialog('结印',[[['','','gw_wenyi'],['','','gw_yanziyaoshui'],['','','gw_kunenfayin']],'vcard'],'hidden'); + chooseButton: { + dialog(event, player) { + return ui.create.dialog( + "结印", + [ + [ + ["", "", "gw_wenyi"], + ["", "", "gw_yanziyaoshui"], + ["", "", "gw_kunenfayin"], + ], + "vcard", + ], + "hidden" + ); }, - filter(button,player){ - if(player.storage.gwjieyin.includes(button.link[2])){ + filter(button, player) { + if (player.storage.gwjieyin.includes(button.link[2])) { return false; } return true; }, - check(button){ - var player=_status.event.player; - if(button.link[2]=='gw_yanziyaoshui'){ - if(game.hasPlayer(function(current){ - return get.attitude(player,current)>1&¤t.isMinHandcard(); - })){ + check(button) { + var player = _status.event.player; + if (button.link[2] == "gw_yanziyaoshui") { + if ( + game.hasPlayer(function (current) { + return get.attitude(player, current) > 1 && current.isMinHandcard(); + }) + ) { return 3; - } - else if((game.roundNumber-player.storage.gwjieyin_round)%2==0){ + } else if ((game.roundNumber - player.storage.gwjieyin_round) % 2 == 0) { return 0; - } - else{ + } else { return 0.5; } - } - else if(button.link[2]=='gw_wenyi'){ - if(game.countPlayer(function(current){ - if(current.isMinHp()){ - if(!current.countCards('h')){ - return -2*get.sgn(get.attitude(player,current)); + } else if (button.link[2] == "gw_wenyi") { + if ( + game.countPlayer(function (current) { + if (current.isMinHp()) { + if (!current.countCards("h")) { + return -2 * get.sgn(get.attitude(player, current)); + } else { + return -get.sgn(get.attitude(player, current)); + } } - else{ - return -get.sgn(get.attitude(player,current)); - } - } - })>0){ + }) > 0 + ) { return 2; - } - else{ + } else { return 0; } - } - else{ + } else { return 1; } }, - backup(links,player){ + backup(links, player) { return { - filterCard(){return false}, - selectCard:-1, - viewAs:{name:links[0][2]}, - popname:true, - onuse(result,player){ - player.logSkill('gwjieyin'); + filterCard() { + return false; + }, + selectCard: -1, + viewAs: { name: links[0][2] }, + popname: true, + onuse(result, player) { + player.logSkill("gwjieyin"); player.storage.gwjieyin.add(result.card.name); - } - } + }, + }; + }, + prompt(links, player) { + return "选择" + get.translation(links[0][2]) + "的目标"; }, - prompt(links,player){ - return '选择'+get.translation(links[0][2])+'的目标'; - } }, - subSkill:{ - reset:{ - trigger:{player:'phaseBegin'}, - silent:true, - content(){ - if(typeof player.storage.gwjieyin_round=='number'){ - var num=game.roundNumber-player.storage.gwjieyin_round; - if(num&&num%2==0){ - player.storage.gwjieyin.length=0; - player.storage.gwjieyin_round=game.roundNumber; + subSkill: { + reset: { + trigger: { player: "phaseBegin" }, + silent: true, + content() { + if (typeof player.storage.gwjieyin_round == "number") { + var num = game.roundNumber - player.storage.gwjieyin_round; + if (num && num % 2 == 0) { + player.storage.gwjieyin.length = 0; + player.storage.gwjieyin_round = game.roundNumber; } + } else { + player.storage.gwjieyin_round = game.roundNumber; } - else{ - player.storage.gwjieyin_round=game.roundNumber; - } - } - } + }, + }, + }, + ai: { + order: 6, + result: { + player: 1, + }, }, - ai:{ - order:6, - result:{ - player:1 - } - } }, - zhengjun:{ - init(player){ - player.storage.zhengjun=[]; - player.storage.zhengjun_one=[]; + zhengjun: { + init(player) { + player.storage.zhengjun = []; + player.storage.zhengjun_one = []; }, - trigger:{player:'zhengjun'}, - forced:true, - intro:{ - content:'已经使用或打出过至少两张同名牌的牌有:$' + trigger: { player: "zhengjun" }, + forced: true, + intro: { + content: "已经使用或打出过至少两张同名牌的牌有:$", }, - content(){ - 'step 0' - player.markSkill('zhengjun'); + content() { + "step 0"; + player.markSkill("zhengjun"); player.gainMaxHp(); - 'step 1' + "step 1"; player.recover(); }, - group:['zhengjun_one','zhengjun_draw'], - subSkill:{ - one:{ - trigger:{player:['useCard','respondAfter']}, - silent:true, - content(){ - if(player.storage.zhengjun_one.includes(trigger.card.name)){ - if(!player.storage.zhengjun.includes(trigger.card.name)){ + group: ["zhengjun_one", "zhengjun_draw"], + subSkill: { + one: { + trigger: { player: ["useCard", "respondAfter"] }, + silent: true, + content() { + if (player.storage.zhengjun_one.includes(trigger.card.name)) { + if (!player.storage.zhengjun.includes(trigger.card.name)) { player.storage.zhengjun.add(trigger.card.name); - event.trigger('zhengjun'); + event.trigger("zhengjun"); } - } - else{ + } else { player.storage.zhengjun_one.add(trigger.card.name); } - } - }, - draw:{ - trigger:{player:'phaseEnd'}, - frequent:true, - filter(event,player){ - return player.storage.zhengjun.length>=1; }, - content(){ - 'step 0' - if(player.storage.zhengjun.length==1){ + }, + draw: { + trigger: { player: "phaseEnd" }, + frequent: true, + filter(event, player) { + return player.storage.zhengjun.length >= 1; + }, + content() { + "step 0"; + if (player.storage.zhengjun.length == 1) { player.draw(); event.finish(); return; } - event.cards=get.cards(player.storage.zhengjun.length); - player.chooseCardButton('整军:获得其中一张牌',true,event.cards).set('ai',function(button){ - return get.useful(button.link); - }); - 'step 1' - if(result.bool){ - var card=result.links[0]; + event.cards = get.cards(player.storage.zhengjun.length); + player + .chooseCardButton("整军:获得其中一张牌", true, event.cards) + .set("ai", function (button) { + return get.useful(button.link); + }); + "step 1"; + if (result.bool) { + var card = result.links[0]; card.fix(); - player.gain(card,'draw'); + player.gain(card, "draw"); event.cards.remove(card); } - 'step 2' - while(event.cards.length){ - ui.cardPile.insertBefore(event.cards.pop(),ui.cardPile.firstChild); + "step 2"; + while (event.cards.length) { + ui.cardPile.insertBefore(event.cards.pop(), ui.cardPile.firstChild); } - } - } - } + }, + }, + }, }, - gwxuezhan:{ - trigger:{player:'phaseBegin'}, - filter(event,player){ + gwxuezhan: { + trigger: { player: "phaseBegin" }, + filter(event, player) { return player.isMinHandcard(); }, - frequent:true, - content(){ - player.gain(game.createCard('gw_shizizhaohuan'),'gain2'); - } - }, - jielue_old:{ - trigger:{player:'useCard'}, - frequent:true, - oncancel(event,player){ - player.addTempSkill('jielue2'); + frequent: true, + content() { + player.gain(game.createCard("gw_shizizhaohuan"), "gain2"); }, - usable:1, - filter(event,player){ - if(event.card.isCard){ - return !player.hasSkill('jielue2')&&get.type(event.card)=='basic'&&!event.card.storage.jielue; + }, + jielue_old: { + trigger: { player: "useCard" }, + frequent: true, + oncancel(event, player) { + player.addTempSkill("jielue2"); + }, + usable: 1, + filter(event, player) { + if (event.card.isCard) { + return ( + !player.hasSkill("jielue2") && + get.type(event.card) == "basic" && + !event.card.storage.jielue + ); } return false; }, - check(event,player){ - return get.value(event.card)>3; + check(event, player) { + return get.value(event.card) > 3; }, - content(){ - var card1=game.createCard(trigger.card); - var card2=game.createCard(trigger.card); - card1.storage.jielue=true; - card2.storage.jielue=true; - player.gain([card1,card2],'gain2'); + content() { + var card1 = game.createCard(trigger.card); + var card2 = game.createCard(trigger.card); + card1.storage.jielue = true; + card2.storage.jielue = true; + player.gain([card1, card2], "gain2"); + }, + ai: { + pretao: true, }, - ai:{ - pretao:true - } }, - jielue2:{}, - bolang:{ - trigger:{player:'phaseBegin'}, - frequent:true, - init(player){ - player.storage.bolang=[]; + jielue2: {}, + bolang: { + trigger: { player: "phaseBegin" }, + frequent: true, + init(player) { + player.storage.bolang = []; }, - content(){ - 'step 0' - var cards=[]; - for(var i=0;i0; + filterTarget(card, player, target) { + return ( + target != player && get.distance(player, target) <= 1 && target.countCards("he") > 0 + ); }, - content(){ - var hs=target.getCards('he'); - if(hs.length){ - var card=hs.randomGet(); - target.$give(card,player); - player.storage.gwjushi2=card; - player.storage.gwjushi3=target; - player.storage.gwjushi4=get.position(card); - target.lose(card,ui.special); - player.addSkill('gwjushi2'); + content() { + var hs = target.getCards("he"); + if (hs.length) { + var card = hs.randomGet(); + target.$give(card, player); + player.storage.gwjushi2 = card; + player.storage.gwjushi3 = target; + player.storage.gwjushi4 = get.position(card); + target.lose(card, ui.special); + player.addSkill("gwjushi2"); } }, - ai:{ - order:8, - result:{ - target:-1 - } - } + ai: { + order: 8, + result: { + target: -1, + }, + }, }, - gwjushi2:{ - mark:'card', - intro:{ - content:'受到伤害时,令此牌回归原位;准备阶段,你获得此牌' + gwjushi2: { + mark: "card", + intro: { + content: "受到伤害时,令此牌回归原位;准备阶段,你获得此牌", }, - trigger:{player:['phaseBegin','damageEnd']}, - forced:true, - content(){ - var card=player.storage.gwjushi2; - var target=player.storage.gwjushi3; - if(trigger.name=='damage'){ - if(target.isIn()){ - if(player.storage.gwjushi4=='e'&&get.type(card)=='equip'){ + trigger: { player: ["phaseBegin", "damageEnd"] }, + forced: true, + content() { + var card = player.storage.gwjushi2; + var target = player.storage.gwjushi3; + if (trigger.name == "damage") { + if (target.isIn()) { + if (player.storage.gwjushi4 == "e" && get.type(card) == "equip") { target.equip(card); - player.$give(card,target); + player.$give(card, target); game.delay(); + } else { + player.give(card, target); } - else{ - player.give(card,target); - } - } - else{ + } else { card.discard(); } + } else { + player.gain(card, "gain2"); } - else{ - player.gain(card,'gain2'); - } - player.removeSkill('gwjushi2'); + player.removeSkill("gwjushi2"); + }, + onremove: ["gwjushi2", "gwjushi3", "gwjushi4"], + ai: { + threaten: 1.5, }, - onremove:['gwjushi2','gwjushi3','gwjushi4'], - ai:{ - threaten:1.5 - } }, - gwfengchi:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - content(){ - 'step 0' - var list=get.gainableSkills(function(info){ - if(typeof info.enable=='string') return info.enable=='phaseUse'; - if(Array.isArray(info.enable)) return info.enable.includes('phaseUse'); - },player); + gwfengchi: { + trigger: { player: "phaseUseBegin" }, + forced: true, + content() { + "step 0"; + var list = get.gainableSkills(function (info) { + if (typeof info.enable == "string") return info.enable == "phaseUse"; + if (Array.isArray(info.enable)) return info.enable.includes("phaseUse"); + }, player); list.remove(player.getSkills()); - list=list.randomGets(3); - event.skillai=function(){ - return get.max(list,get.skillRank,'item'); + list = list.randomGets(3); + event.skillai = function () { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - var dialog=ui.create.dialog('forcebutton'); - dialog.add('风驰:选择获得一项技能'); - var clickItem=function(){ - _status.event._result=this.link; + if (event.isMine()) { + var dialog = ui.create.dialog("forcebutton"); + dialog.add("风驰:选择获得一项技能"); + var clickItem = function () { + _status.event._result = this.link; dialog.close(); game.resume(); }; - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.switchToAuto=function(){ - event._result=event.skillai(); + dialog.add(ui.create.div(".placeholder")); + event.switchToAuto = function () { + event._result = event.skillai(); dialog.close(); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(); } - else{ - event._result=event.skillai(); - } - 'step 1' - _status.imchoosing=false; - var link=result; - player.addTempSkill(link,'phaseUseAfter'); + "step 1"; + _status.imchoosing = false; + var link = result; + player.addTempSkill(link, "phaseUseAfter"); player.popup(link); - player.flashAvatar('gwfengchi',link); - game.log(player,'获得了技能','【'+get.translation(link)+'】'); + player.flashAvatar("gwfengchi", link); + game.log(player, "获得了技能", "【" + get.translation(link) + "】"); game.delay(); - } + }, }, - lingji:{ - enable:'phaseUse', - usable:1, - content(){ - 'step 0' + lingji: { + enable: "phaseUse", + usable: 1, + content() { + "step 0"; player.draw(2); - 'step 1' - player.chooseToDiscard('he',2,true).ai=function(card){ - var val=-get.value(card); - if(ui.selected.cards.length){ - if(get.suit(card)==get.suit(ui.selected.cards[0])) val++; - if(get.number(card)==get.number(ui.selected.cards[0])) val+=3; + "step 1"; + player.chooseToDiscard("he", 2, true).ai = function (card) { + var val = -get.value(card); + if (ui.selected.cards.length) { + if (get.suit(card) == get.suit(ui.selected.cards[0])) val++; + if (get.number(card) == get.number(ui.selected.cards[0])) val += 3; } return val; - } - 'step 2' - if(result.cards.length==2){ - var list=[]; - if(get.suit(result.cards[0])==get.suit(result.cards[1])){ - var list1=get.typeCard('spell_bronze'); - if(list1.length){ + }; + "step 2"; + if (result.cards.length == 2) { + var list = []; + if (get.suit(result.cards[0]) == get.suit(result.cards[1])) { + var list1 = get.typeCard("spell_bronze"); + if (list1.length) { list.push(game.createCard(list1.randomGet())); } } - if(get.number(result.cards[0])==get.number(result.cards[1])){ - var list2=get.typeCard('spell_silver'); - if(list2.length){ + if (get.number(result.cards[0]) == get.number(result.cards[1])) { + var list2 = get.typeCard("spell_silver"); + if (list2.length) { list.push(game.createCard(list2.randomGet())); } } - if(list.length){ - player.gain(list,'gain2'); + if (list.length) { + player.gain(list, "gain2"); } } }, - ai:{ - order:8, - result:{ - player:1 - } - } - }, - gwjinyan:{ - trigger:{player:['damageBefore']}, - forced:true, - mark:true, - filter(event,player){ - return game.roundNumber%3!=0; + ai: { + order: 8, + result: { + player: 1, + }, }, - content(){ + }, + gwjinyan: { + trigger: { player: ["damageBefore"] }, + forced: true, + mark: true, + filter(event, player) { + return game.roundNumber % 3 != 0; + }, + content() { trigger.cancel(); }, - group:['gwjinyan_gain'], - subSkill:{ - gain:{ - trigger:{player:'phaseBegin'}, - frequent:true, - filter(){ - return game.roundNumber%3==0; + group: ["gwjinyan_gain"], + subSkill: { + gain: { + trigger: { player: "phaseBegin" }, + frequent: true, + filter() { + return game.roundNumber % 3 == 0; }, - content(){ - var list=get.typeCard('spell_gold'); - if(list.length){ - player.gain(game.createCard(list.randomGet()),'gain2'); + content() { + var list = get.typeCard("spell_gold"); + if (list.length) { + player.gain(game.createCard(list.randomGet()), "gain2"); } - } - } + }, + }, }, - ai:{ - threaten(){ - if(game.roundNumber%3==0) return 1.6; + ai: { + threaten() { + if (game.roundNumber % 3 == 0) return 1.6; return 0.8; }, - nofire:true, - nothunder:true, - nodamage:true, - skillTagFilter(){ - if(game.roundNumber%3==0) return false; + nofire: true, + nothunder: true, + nodamage: true, + skillTagFilter() { + if (game.roundNumber % 3 == 0) return false; }, - effect:{ - target(card,player,target){ - if(game.roundNumber%3!=0&&get.tag(card,'damage')){ - return [0,0]; + effect: { + target(card, player, target) { + if (game.roundNumber % 3 != 0 && get.tag(card, "damage")) { + return [0, 0]; } - } - } - } + }, + }, + }, }, - gwshenyu:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ - if(game.hasPlayer(function(current){ - return current.isDamaged(); - })){ + gwshenyu: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { + if ( + game.hasPlayer(function (current) { + return current.isDamaged(); + }) + ) { return true; } - for(var i=0;i= 3 && !player.needsToDiscard()) return 1; + if (player.hp == 2 && player.hasShan() && player.countCards("h") <= 1) + return 1; + return 0; + }) + .set("choiceList", ["回复1点体力", "从弃牌堆中获得一张非金法术"]); } - else if(event.target.isHealthy()){ - event.directbool=true; - } - else{ - event.target.chooseControl(function(event,player){ - if(player.hp>=3&&!player.needsToDiscard()) return 1; - if(player.hp==2&&player.hasShan()&&player.countCards('h')<=1) return 1; - return 0; - }).set('choiceList',[ - '回复1点体力','从弃牌堆中获得一张非金法术' - ]); - } - } - else{ + } else { event.finish(); } - 'step 2' - if(!event.directbool&&result.index==0){ + "step 2"; + if (!event.directbool && result.index == 0) { event.target.recover(); event.finish(); } - 'step 3' - var list=event.list; - if(list.length){ - event.target.chooseCardButton('选择一张法术牌',list,true).ai=function(button){ + "step 3"; + var list = event.list; + if (list.length) { + event.target.chooseCardButton("选择一张法术牌", list, true).ai = function (button) { return get.value(button.link); }; - } - else{ + } else { event.finish(); } - 'step 4' - if(result.bool){ - result.links[0].vanishtag.add('_gwshenyu'); - event.target.gain(result.links,'gain2','log'); + "step 4"; + if (result.bool) { + result.links[0].vanishtag.add("_gwshenyu"); + event.target.gain(result.links, "gain2", "log"); } }, - ai:{ - threaten:2, - expose:0.2 - } - }, - junchi:{ - trigger:{global:'shaAfter'}, - direct:true, - usable:1, - filter(event,player){ - return event.player!=player&&event.target!=player&&event.target.isIn()&&player.hasCard(function(card){ - return player.canUse(card,event.target,false)&&!get.info(card).multitarget; - }); + ai: { + threaten: 2, + expose: 0.2, }, - content(){ - var next=player.chooseToUse(get.prompt('junchi'),trigger.target,-1).set('targetRequired',true); - next.prompt2='对'+get.translation(trigger.target)+'使用一张牌,并摸一张牌'; - next.filterCard=function(card){ - return player.canUse(card,trigger.target,false)&&!get.info(card).multitarget; + }, + junchi: { + trigger: { global: "shaAfter" }, + direct: true, + usable: 1, + filter(event, player) { + return ( + event.player != player && + event.target != player && + event.target.isIn() && + player.hasCard(function (card) { + return player.canUse(card, event.target, false) && !get.info(card).multitarget; + }) + ); + }, + content() { + var next = player + .chooseToUse(get.prompt("junchi"), trigger.target, -1) + .set("targetRequired", true); + next.prompt2 = "对" + get.translation(trigger.target) + "使用一张牌,并摸一张牌"; + next.filterCard = function (card) { + return player.canUse(card, trigger.target, false) && !get.info(card).multitarget; }; - next.oncard=function(){ + next.oncard = function () { player.draw(); }; - next.logSkill='junchi'; + next.logSkill = "junchi"; }, - subSkill:{ - gold:{ - trigger:{global:'useCardAfter'}, - frequent:true, - filter(event,player){ - return event.player!=player&&get.subtype(event.card)=='spell_gold'; + subSkill: { + gold: { + trigger: { global: "useCardAfter" }, + frequent: true, + filter(event, player) { + return event.player != player && get.subtype(event.card) == "spell_gold"; }, - content(){ + content() { player.insertPhase(); - } - } + }, + }, }, // group:'junchi_gold' }, - junchi_old:{ - trigger:{global:'shaAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.player!=player&&event.target!=player&&event.player.isIn()&&event.player.countCards('he')>0; + junchi_old: { + trigger: { global: "shaAfter" }, + forced: true, + popup: false, + filter(event, player) { + return ( + event.player != player && + event.target != player && + event.player.isIn() && + event.player.countCards("he") > 0 + ); }, - content(){ - 'step 0' - var att=get.attitude(trigger.player,player); - trigger.player.chooseCard('he','是否交给'+get.translation(player)+'一张牌?').ai=function(card){ - if(att>1){ - if(trigger.target.isIn()){ - return 9-get.value(card); + content() { + "step 0"; + var att = get.attitude(trigger.player, player); + trigger.player.chooseCard("he", "是否交给" + get.translation(player) + "一张牌?").ai = + function (card) { + if (att > 1) { + if (trigger.target.isIn()) { + return 9 - get.value(card); + } + return 4 - get.value(card); } - return 4-get.value(card); - } - return 0; - } - 'step 1' - if(result.bool){ - player.logSkill('junchi'); - player.gain(result.cards,trigger.player); - if(get.position(result.cards[0])=='h'){ - trigger.player.$giveAuto(result.cards,player); - } - else{ - trigger.player.$give(result.cards,player); + return 0; + }; + "step 1"; + if (result.bool) { + player.logSkill("junchi"); + player.gain(result.cards, trigger.player); + if (get.position(result.cards[0]) == "h") { + trigger.player.$giveAuto(result.cards, player); + } else { + trigger.player.$give(result.cards, player); } trigger.player.addExpose(0.2); - trigger.player.line(player,'green'); - } - else{ + trigger.player.line(player, "green"); + } else { event.finish(); } - 'step 2' - if(trigger.target.isIn()){ - var next=player.chooseToUse('是否对'+get.translation(trigger.target)+'使用一张牌?',trigger.target,-1).set('targetRequired',true); - next.filterCard=function(card){ - return player.canUse(card,trigger.target,false)&&!get.info(card).multitarget; + "step 2"; + if (trigger.target.isIn()) { + var next = player + .chooseToUse( + "是否对" + get.translation(trigger.target) + "使用一张牌?", + trigger.target, + -1 + ) + .set("targetRequired", true); + next.filterCard = function (card) { + return player.canUse(card, trigger.target, false) && !get.info(card).multitarget; }; - next.oncard=function(){ + next.oncard = function () { player.recover(); trigger.player.draw(); - } + }; } - } + }, }, - hupeng:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('he')>0; + hupeng: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - check(card){ - return 7-get.value(card); + filterCard: true, + check(card) { + return 7 - get.value(card); }, - filterTarget:true, - content(){ - 'step 0' - var att=get.attitude(player,target); - player.chooseVCardButton('选择令'+get.translation(target)+'获得的牌',['gw_dudayuanshuai1','gw_dudayuanshuai2'],true).ai=function(button){ - if(att>0){ - return button.link[2]=='gw_dudayuanshuai1'?1:-1; + filterTarget: true, + content() { + "step 0"; + var att = get.attitude(player, target); + player.chooseVCardButton( + "选择令" + get.translation(target) + "获得的牌", + ["gw_dudayuanshuai1", "gw_dudayuanshuai2"], + true + ).ai = function (button) { + if (att > 0) { + return button.link[2] == "gw_dudayuanshuai1" ? 1 : -1; + } else { + return button.link[2] == "gw_dudayuanshuai2" ? 1 : -1; } - else{ - return button.link[2]=='gw_dudayuanshuai2'?1:-1; - } - } - 'step 1' - if(result.bool){ - target.gain(game.createCard(result.links[0][2]),'gain2'); + }; + "step 1"; + if (result.bool) { + target.gain(game.createCard(result.links[0][2]), "gain2"); } }, - ai:{ - threaten:1.5, - order:6, - result:{ - target(player,target){ - var nh=target.countCards('h'); - if(get.attitude(player,target)>0){ - if(!nh) return 3; - if(!target.needsToDiscard(1)){ - if(nh==1) return 2.5; + ai: { + threaten: 1.5, + order: 6, + result: { + target(player, target) { + var nh = target.countCards("h"); + if (get.attitude(player, target) > 0) { + if (!nh) return 3; + if (!target.needsToDiscard(1)) { + if (nh == 1) return 2.5; return 2; } - if(!target.needsToDiscard()) return 1; + if (!target.needsToDiscard()) return 1; return 0.1; - } - else{ - if(!nh) return -0.05; - if(target.hp==1) return -1; - if(target.hp==2) return -2.5; - if(target.hp==3) return -2; + } else { + if (!nh) return -0.05; + if (target.hp == 1) return -1; + if (target.hp == 2) return -2.5; + if (target.hp == 3) return -2; return -0.5; } - } - } + }, + }, }, - global:['hupeng2','hupeng3','hupeng4'] + global: ["hupeng2", "hupeng3", "hupeng4"], }, - hupeng2:{ - mod:{ - cardDiscardable(card,player){ - if(card.name=='gw_dudayuanshuai2') return false; + hupeng2: { + mod: { + cardDiscardable(card, player) { + if (card.name == "gw_dudayuanshuai2") return false; }, - cardEnabled(card,player){ - if(card.name=='gw_dudayuanshuai2') return false; + cardEnabled(card, player) { + if (card.name == "gw_dudayuanshuai2") return false; }, - cardUsable(card,player){ - if(card.name=='gw_dudayuanshuai2') return false; + cardUsable(card, player) { + if (card.name == "gw_dudayuanshuai2") return false; }, - cardRespondable(card,player){ - if(card.name=='gw_dudayuanshuai2') return false; + cardRespondable(card, player) { + if (card.name == "gw_dudayuanshuai2") return false; }, - cardSavable(card,player){ - if(card.name=='gw_dudayuanshuai2') return false; + cardSavable(card, player) { + if (card.name == "gw_dudayuanshuai2") return false; }, }, - ai:{ - effect:{ - target(card,player,target){ - if(target.countCards('h','gw_dudayuanshuai1')&&get.attitude(player,target)<0){ + ai: { + effect: { + target(card, player, target) { + if ( + target.countCards("h", "gw_dudayuanshuai1") && + get.attitude(player, target) < 0 + ) { return 0.4; } - } - } - } - }, - hupeng3:{ - trigger:{player:'phaseEnd'}, - silent:true, - filter(event,player){ - return player.countCards('h','gw_dudayuanshuai2')>0; + }, + }, }, - content(){ - var hs=player.getCards('h'); - var hs2=player.getCards('h','gw_dudayuanshuai2'); + }, + hupeng3: { + trigger: { player: "phaseEnd" }, + silent: true, + filter(event, player) { + return player.countCards("h", "gw_dudayuanshuai2") > 0; + }, + content() { + var hs = player.getCards("h"); + var hs2 = player.getCards("h", "gw_dudayuanshuai2"); hs.remove(hs2); - if(hs.length){ + if (hs.length) { hs2.addArray(hs.randomGets(hs2.length)); } player.discard(hs2); - } - }, - hupeng4:{ - trigger:{target:'useCardToBefore'}, - forced:true, - popup:false, - filter(event,player){ - if(event.player==player) return false; - var num=player.countCards('h','gw_dudayuanshuai1'); - return num>0; }, - content(){ - 'step 0' - player.chooseToUse({name:'gw_dudayuanshuai1'},'是否对'+get.translation(trigger.card)+'使用【杜达元帅】?').set('ai1',function(card){ - return _status.event.bool; - }).set('bool',-get.effect(player,trigger.card,trigger.player,player)); - trigger.gw_dudayuanshuai1=true; - 'step 1' - delete trigger.gw_dudayuanshuai1; - } }, - hunmo:{ - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.hunmo.filterTarget(null,player,current); + hupeng4: { + trigger: { target: "useCardToBefore" }, + forced: true, + popup: false, + filter(event, player) { + if (event.player == player) return false; + var num = player.countCards("h", "gw_dudayuanshuai1"); + return num > 0; + }, + content() { + "step 0"; + player + .chooseToUse( + { name: "gw_dudayuanshuai1" }, + "是否对" + get.translation(trigger.card) + "使用【杜达元帅】?" + ) + .set("ai1", function (card) { + return _status.event.bool; + }) + .set("bool", -get.effect(player, trigger.card, trigger.player, player)); + trigger.gw_dudayuanshuai1 = true; + "step 1"; + delete trigger.gw_dudayuanshuai1; + }, + }, + hunmo: { + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer(function (current) { + return lib.skill.hunmo.filterTarget(null, player, current); }); }, - filterTarget(card,player,target){ - if(target==player) return false; - if(target.hasSkill('hunmo2')) return false; - var nh=player.countCards('h'); - var nh2=target.countCards('h'); - if(nh<2) return nh2<2; - return nh2>=2&&target.countDiscardableCards(player,'h')>0; + filterTarget(card, player, target) { + if (target == player) return false; + if (target.hasSkill("hunmo2")) return false; + var nh = player.countCards("h"); + var nh2 = target.countCards("h"); + if (nh < 2) return nh2 < 2; + return nh2 >= 2 && target.countDiscardableCards(player, "h") > 0; }, - prompt(event){ - var nh=event.player.countCards('h'); - if(nh<2) return '选择一名手牌数小于2的其他角色,观看牌堆顶的两张牌,你获得一张并交给其另一张'; - return '选择一名手牌数大于2的其他角色,你弃置一张手牌,然后观看并弃置其一张手牌'; + prompt(event) { + var nh = event.player.countCards("h"); + if (nh < 2) + return "选择一名手牌数小于2的其他角色,观看牌堆顶的两张牌,你获得一张并交给其另一张"; + return "选择一名手牌数大于2的其他角色,你弃置一张手牌,然后观看并弃置其一张手牌"; }, - content(){ - 'step 0' - target.addTempSkill('hunmo2'); - var nh=player.countCards('h'); - if(nh<2){ - event.cards=get.cards(2); - player.chooseCardButton(event.cards,'获得一张牌并交给'+get.translation(target)+'另一张牌',true); + content() { + "step 0"; + target.addTempSkill("hunmo2"); + var nh = player.countCards("h"); + if (nh < 2) { + event.cards = get.cards(2); + player.chooseCardButton( + event.cards, + "获得一张牌并交给" + get.translation(target) + "另一张牌", + true + ); + } else { + player.chooseToDiscard("h", true).delay = false; + event.discard = true; } - else{ - player.chooseToDiscard('h',true).delay=false; - event.discard=true; - } - 'step 1' - if(event.discard){ - player.discardPlayerCard(target,'h',true,'visible'); - } - else{ - if(result.links&&result.links.length){ - player.gain(result.links,false); + "step 1"; + if (event.discard) { + player.discardPlayerCard(target, "h", true, "visible"); + } else { + if (result.links && result.links.length) { + player.gain(result.links, false); event.cards.remove(result.links[0]); - target.gain(event.cards,false); + target.gain(event.cards, false); player.$drawAuto(result.links); target.$drawAuto(event.cards); } } - 'step 2' + "step 2"; game.delay(); }, - ai:{ - order(){ - var player=_status.event.player; - if(player.countCards('h')<2) return 11; + ai: { + order() { + var player = _status.event.player; + if (player.countCards("h") < 2) return 11; return 6; }, - threaten:1.2, - result:{ - target(player,target){ - if(player.countCards('h')<2) return 1; - if(player.hasCard(function(card){ - return get.value(card)<=5 - })){ + threaten: 1.2, + result: { + target(player, target) { + if (player.countCards("h") < 2) return 1; + if ( + player.hasCard(function (card) { + return get.value(card) <= 5; + }) + ) { return -1; } - } - } + }, + }, }, // group:'hunmo_draw', - subSkill:{ - draw:{ - trigger:{player:'phaseEnd'}, - filter(event,player){ - return player.getStat('skill').hunmo>=3; + subSkill: { + draw: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return player.getStat("skill").hunmo >= 3; }, - frequent:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('魂墨:造成1点伤害')).ai=function(target){ - return get.damageEffect(target,player,player); - } - 'step 1' - if(result.bool){ - player.logSkill('hunmo_draw',result.targets); + frequent: true, + content() { + "step 0"; + player.chooseTarget(get.prompt("魂墨:造成1点伤害")).ai = function (target) { + return get.damageEffect(target, player, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("hunmo_draw", result.targets); result.targets[0].damage(); } - } + }, }, - } - }, - hunmo2:{}, - hunmo3:{}, - shuijian:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ - return player.countCards('h')>0; }, - content(){ - 'step 0' - var targets=player.getEnemies(); - var num=0; - for(var i=0;i 0; + }, + content() { + "step 0"; + var targets = player.getEnemies(); + var num = 0; + for (var i = 0; i < targets.length; i++) { + num += get.sgn(get.effect(targets[i], { name: "wanjian" }, player, player)); } - event.targets=targets; - player.chooseToDiscard(get.prompt('shuijian')).set('ai',function(card){ - if(num>=3) return 10-get.value(card); - if(num>=2) return 9-get.value(card); - if(num>=1) return 7-get.value(card); + event.targets = targets; + player.chooseToDiscard(get.prompt("shuijian")).set("ai", function (card) { + if (num >= 3) return 10 - get.value(card); + if (num >= 2) return 9 - get.value(card); + if (num >= 1) return 7 - get.value(card); return 0; - }).logSkill='shuijian'; - 'step 1' - if(result.bool){ - for(var i=0;i0){ + } else { + game.countPlayer(function (current) { + var att = get.attitude(player, current); + if (att > 0) { num1++; - } - else if(att<0){ + } else if (att < 0) { num2++; } }); - choice=(num1>num2)?'选项一':'选项二'; + choice = num1 > num2 ? "选项一" : "选项二"; } - player.chooseControl('选项一','选项二','cancel2',function(){ - return choice; - }).set('prompt',get.prompt('gwtianbian')).set('choiceList',['随机使用一张对全场有正面效果的牌','随机使用一张对全场有负面效果的牌']); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('gwtianbian'); - var list=[]; - for(var i in lib.card){ - if(lib.inpile.includes(i)&& - lib.card[i].selectTarget==-1&& - lib.card[i].type!='equip'&& - lib.card[i].ai&&lib.card[i].ai.tag&& - lib.card[i].ai.tag.multitarget){ - if(lib.card[i].ai.tag.multineg){ - if(result.control=='选项二'){ + player + .chooseControl("选项一", "选项二", "cancel2", function () { + return choice; + }) + .set("prompt", get.prompt("gwtianbian")) + .set("choiceList", [ + "随机使用一张对全场有正面效果的牌", + "随机使用一张对全场有负面效果的牌", + ]); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("gwtianbian"); + var list = []; + for (var i in lib.card) { + if ( + lib.inpile.includes(i) && + lib.card[i].selectTarget == -1 && + lib.card[i].type != "equip" && + lib.card[i].ai && + lib.card[i].ai.tag && + lib.card[i].ai.tag.multitarget + ) { + if (lib.card[i].ai.tag.multineg) { + if (result.control == "选项二") { list.push(i); } - } - else{ - if(result.control=='选项一'){ + } else { + if (result.control == "选项一") { list.push(i); } } } } - var name=null; - while(list.length){ - name=list.randomRemove(); - if(game.hasPlayer(function(current){ - return player.canUse(name,current) - })){ + var name = null; + while (list.length) { + name = list.randomRemove(); + if ( + game.hasPlayer(function (current) { + return player.canUse(name, current); + }) + ) { break; - } - else{ - name=null; + } else { + name = null; } } - if(name){ - var targets=game.filterPlayer(function(current){ - return player.canUse(name,current); + if (name) { + var targets = game.filterPlayer(function (current) { + return player.canUse(name, current); }); targets.sortBySeat(); - player.useCard({name:name},targets); + player.useCard({ name: name }, targets); } } - } + }, }, - gwxiaoshou:{ - enable:'phaseUse', - usable:2, - filterTarget(card,player,target){ + gwxiaoshou: { + enable: "phaseUse", + usable: 2, + filterTarget(card, player, target) { return target.isMaxHp(); }, - check(card){return 7-get.value(card);}, - position:'he', - filterCard:true, - content(){ + check(card) { + return 7 - get.value(card); + }, + position: "he", + filterCard: true, + content() { target.damage(); }, - ai:{ - result:{ - target(player,target){ - return get.damageEffect(target,player); + ai: { + result: { + target(player, target) { + return get.damageEffect(target, player); }, }, - order:7 - } + order: 7, + }, }, - kuanglie:{ - trigger:{player:'useCardToBegin'}, - filter(event,player){ - return event.target&&event.target!=player&&event.target.countCards('he')>0&&get.color(event.card)=='black'; + kuanglie: { + trigger: { player: "useCardToBegin" }, + filter(event, player) { + return ( + event.target && + event.target != player && + event.target.countCards("he") > 0 && + get.color(event.card) == "black" + ); }, - init(player){ - player.storage.kuanglie=0; + init(player) { + player.storage.kuanglie = 0; }, - forced:true, - content(){ + forced: true, + content() { trigger.target.randomDiscard(); player.storage.kuanglie++; - if(player.storage.kuanglie%2==0){ + if (player.storage.kuanglie % 2 == 0) { player.draw(); } - } + }, }, - kuanglie2:{}, - gwjiquan:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('he')>0; + kuanglie2: {}, + gwjiquan: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("he") > 0; }, - selectTarget:[1,Infinity], - content(){ - 'step 0' - player.gainPlayerCard(target,'he',true); - 'step 1' - target.useCard({name:'sha'},player); + selectTarget: [1, Infinity], + content() { + "step 0"; + player.gainPlayerCard(target, "he", true); + "step 1"; + target.useCard({ name: "sha" }, player); }, - ai:{ - threaten:1.4, - order:7, - result:{ - target(player,target){ - if(player.getEquip('tengjia')||player.hasSkillTag('freeShan',false,{ - player:target, - card:new lib.element.VCard({name:'sha'}) - })) return -1; - if(get.effect(player,{name:'sha'},target,player)>=0) return -1; - if(!player.hasShan()){ - if(ui.selected.targets.length) return 0; - if(player.hp>=4) return -1; - if(player.hp>=3&&target.hp==1) return -1; + ai: { + threaten: 1.4, + order: 7, + result: { + target(player, target) { + if ( + player.getEquip("tengjia") || + player.hasSkillTag("freeShan", false, { + player: target, + card: new lib.element.VCard({ name: "sha" }), + }) + ) + return -1; + if (get.effect(player, { name: "sha" }, target, player) >= 0) return -1; + if (!player.hasShan()) { + if (ui.selected.targets.length) return 0; + if (player.hp >= 4) return -1; + if (player.hp >= 3 && target.hp == 1) return -1; return 0; } - var num=player.countCards('h','shan'); - if(num<1){ - num=1; + var num = player.countCards("h", "shan"); + if (num < 1) { + num = 1; } - if(ui.selected.targets.length>=num){ + if (ui.selected.targets.length >= num) { return 0; } return -1; - } - } - } - }, - nuhou_old:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - check(card){ - return 7-get.value(card) + }, + }, }, - content(){ - 'step 0' - var list=player.getEnemies(); + }, + nuhou_old: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + check(card) { + return 7 - get.value(card); + }, + content() { + "step 0"; + var list = player.getEnemies(); list.sortBySeat(); - event.list=list; - 'step 1' - if(event.list.length){ - var current=event.list.shift(); - var he=current.getCards('he'); - player.line(current,'green'); - if(he.length){ + event.list = list; + "step 1"; + if (event.list.length) { + var current = event.list.shift(); + var he = current.getCards("he"); + player.line(current, "green"); + if (he.length) { current.discard(he.randomGet()); current.addExpose(0.2); } event.redo(); } }, - ai:{ - order:8.5, - result:{ - player:1 + ai: { + order: 8.5, + result: { + player: 1, }, }, }, - nuhou:{ - trigger:{player:'damageEnd'}, - direct:true, - filter(event,player){ - return player.countCards('he')>0; + nuhou: { + trigger: { player: "damageEnd" }, + direct: true, + filter(event, player) { + return player.countCards("he") > 0; }, - content(){ - 'step 0' - player.chooseToDiscard(get.prompt2('nuhou'),'he').set('ai',function(card){ - return 8-get.useful(card); - }).set('logSkill','nuhou'); - 'step 1' - if(result.bool){ - var targets=player.getEnemies(); - if(targets.length){ - var target=targets.randomGet(); - player.line(target,'green'); + content() { + "step 0"; + player + .chooseToDiscard(get.prompt2("nuhou"), "he") + .set("ai", function (card) { + return 8 - get.useful(card); + }) + .set("logSkill", "nuhou"); + "step 1"; + if (result.bool) { + var targets = player.getEnemies(); + if (targets.length) { + var target = targets.randomGet(); + player.line(target, "green"); target.damage(); target.randomDiscard(); } } }, - ai:{ - threaten:0.8, - maixie:true, - maixie_hp:true, - maixie_defend:true, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - var nh=target.countCards('he'); - if(player.hasSkillTag('jueqing',false,target)||nh==0) return [1,-2]; - if(!target.hasFriend()||nh<=1) return; - if(target.hp>=2) return [1,get.tag(card,'damage')*0.5]; + ai: { + threaten: 0.8, + maixie: true, + maixie_hp: true, + maixie_defend: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + var nh = target.countCards("he"); + if (player.hasSkillTag("jueqing", false, target) || nh == 0) return [1, -2]; + if (!target.hasFriend() || nh <= 1) return; + if (target.hp >= 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } + }, + }, + }, }, - shewu:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - selectCard:[1,3], - check(card){ - if(!ui.selected.cards.length){ - return 8-get.value(card) + shewu: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + selectCard: [1, 3], + check(card) { + if (!ui.selected.cards.length) { + return 8 - get.value(card); } - var player=_status.event.player; - if(player.isDamaged()){ - var hs=player.getCards('h'); - var num=0; - for(var i=0;i=3){ - return 6-get.value(card); + if (num >= 3) { + return 6 - get.value(card); } } return 0; }, - content(){ + content() { player.draw(3); - if(cards.length>=2){ - player.addTempSkill('shewu_dist'); + if (cards.length >= 2) { + player.addTempSkill("shewu_dist"); } - if(cards.length==3){ + if (cards.length == 3) { player.recover(); } }, - ai:{ - order:4, - result:{ - player:1 + ai: { + order: 4, + result: { + player: 1, }, - threaten:1.6 + threaten: 1.6, }, - subSkill:{ - dist:{ - mod:{ - targetInRange(){ + subSkill: { + dist: { + mod: { + targetInRange() { return true; - } - } - } - } - }, - gwzhanjiang:{ - trigger:{global:'phaseBegin'}, - direct:true, - filter(event,player){ - return !player.hasSkill('gwzhanjiang2')&&event.player!=player; + }, + }, + }, }, - content(){ - 'step 0' - var bool=(get.effect(trigger.player,{name:'sha'},player,player)>0&& - Math.abs(get.attitude(player,trigger.player))>1&& - game.hasPlayer(function(current){ - return get.attitude(current,player)>0&¤t.hasSha(); - })); - var next=player.chooseToDiscard(get.prompt('gwzhanjiang',trigger.player),'he'); - next.ai=function(card){ - if(bool) return 7-get.value(card); + }, + gwzhanjiang: { + trigger: { global: "phaseBegin" }, + direct: true, + filter(event, player) { + return !player.hasSkill("gwzhanjiang2") && event.player != player; + }, + content() { + "step 0"; + var bool = + get.effect(trigger.player, { name: "sha" }, player, player) > 0 && + Math.abs(get.attitude(player, trigger.player)) > 1 && + game.hasPlayer(function (current) { + return get.attitude(current, player) > 0 && current.hasSha(); + }); + var next = player.chooseToDiscard(get.prompt("gwzhanjiang", trigger.player), "he"); + next.ai = function (card) { + if (bool) return 7 - get.value(card); return 0; }; - next.logSkill=['gwzhanjiang',trigger.player]; - 'step 1' - if(result.bool){ - player.addTempSkill('gwzhanjiang2',{player:'phaseBegin'}); - event.targets=game.filterPlayer(function(current){ - return current!=trigger.player; + next.logSkill = ["gwzhanjiang", trigger.player]; + "step 1"; + if (result.bool) { + player.addTempSkill("gwzhanjiang2", { player: "phaseBegin" }); + event.targets = game.filterPlayer(function (current) { + return current != trigger.player; }); event.targets.sortBySeat(trigger.player); - event.num=0; - } - else{ + event.num = 0; + } else { event.finish(); } - 'step 2' - if(event.targets.length){ - event.current=event.targets.shift(); - if(event.current.hasSha()){ - event.current.chooseToUse({name:'sha'},'是否对'+get.translation(trigger.player)+'使用一张杀?',trigger.player,-1).oncard=function(card,player){ + "step 2"; + if (event.targets.length) { + event.current = event.targets.shift(); + if (event.current.hasSha()) { + event.current.chooseToUse( + { name: "sha" }, + "是否对" + get.translation(trigger.player) + "使用一张杀?", + trigger.player, + -1 + ).oncard = function (card, player) { player.draw(); }; - } - else{ + } else { event.redo(); } - } - else{ + } else { event.finish(); } - 'step 3' - if(result.bool){ + "step 3"; + if (result.bool) { event.num++; - if(event.num>=2){ + if (event.num >= 2) { return; } } event.goto(2); }, - ai:{ - expose:0.2, - threaten:1.4 + ai: { + expose: 0.2, + threaten: 1.4, }, }, - gwzhanjiang2:{}, - gwzhanjiang3:{ - trigger:{player:'useCard'}, - filter(event){ - return event.card.name=='sha'&&event.getParent(2).name=='gwzhanjiang'; + gwzhanjiang2: {}, + gwzhanjiang3: { + trigger: { player: "useCard" }, + filter(event) { + return event.card.name == "sha" && event.getParent(2).name == "gwzhanjiang"; }, - forced:true, - popup:false, - content(){ + forced: true, + popup: false, + content() { player.draw(); - } + }, }, - gwchuanxin_old:{ - trigger:{player:'shaAfter'}, - filter(event,player){ - if(player.storage.gwchuanxin&&player.storage.gwchuanxin.length>=4) return false; + gwchuanxin_old: { + trigger: { player: "shaAfter" }, + filter(event, player) { + if (player.storage.gwchuanxin && player.storage.gwchuanxin.length >= 4) return false; return event.target.isAlive(); }, - check(event,player){ - return get.effect(event.target,{name:'sha'},player,player)>0 + check(event, player) { + return get.effect(event.target, { name: "sha" }, player, player) > 0; }, - logTarget:'target', - logLine:false, - content(){ - 'step 0' - event.card=get.cards()[0]; - player.showCards(event.card,get.translation(player)+'对'+get.translation(trigger.player)+'发动了【穿心】'); - 'step 1' - if(player.storage.gwchuanxin&&!player.storage.gwchuanxin.includes(get.suit(event.card))){ - player.useCard({name:'sha'},[event.card],trigger.target,false); + logTarget: "target", + logLine: false, + content() { + "step 0"; + event.card = get.cards()[0]; + player.showCards( + event.card, + get.translation(player) + "对" + get.translation(trigger.player) + "发动了【穿心】" + ); + "step 1"; + if ( + player.storage.gwchuanxin && + !player.storage.gwchuanxin.includes(get.suit(event.card)) + ) { + player.useCard({ name: "sha" }, [event.card], trigger.target, false); } }, - group:['gwchuanxin_count1','gwchuanxin_count2'], - subSkill:{ - count1:{ - trigger:{global:'phaseBegin'}, - silent:true, - content(){ - player.storage.gwchuanxin=[]; - } + group: ["gwchuanxin_count1", "gwchuanxin_count2"], + subSkill: { + count1: { + trigger: { global: "phaseBegin" }, + silent: true, + content() { + player.storage.gwchuanxin = []; + }, }, - count2:{ - trigger:{player:'useCard'}, - silent:true, + count2: { + trigger: { player: "useCard" }, + silent: true, // filter(event){ // return event.card&&event.card.name=='sha'; // }, - content(){ - for(var i=0;i0 + check(event, player) { + return get.effect(event.target, { name: "sha" }, player, player) > 0; }, - logTarget:'target', + logTarget: "target", // logLine:false, - content(){ - 'step 0' - var cards=get.cards(); - player.showCards(cards,get.translation(player)+'发动了【穿心】'); - event.bool=(get.color(cards[0])=='black'); - 'step 1' - if(event.bool){ - player.useCard({name:'sha'},trigger.target,false).animate=false; + content() { + "step 0"; + var cards = get.cards(); + player.showCards(cards, get.translation(player) + "发动了【穿心】"); + event.bool = get.color(cards[0]) == "black"; + "step 1"; + if (event.bool) { + player.useCard({ name: "sha" }, trigger.target, false).animate = false; } }, - mod:{ - attackFrom(from,to,distance){ - return distance-from.hp+1; - } - } + mod: { + attackFrom(from, to, distance) { + return distance - from.hp + 1; + }, + }, }, - fengjian:{ - trigger:{player:'useCard'}, - direct:true, - filter(event,player){ - var type=get.type(event.card,'trick'); - return type=='trick'&&game.hasPlayer(function(current){ - return player.canUse('sha',current,false)&&!event.targets.includes(current); - }); + fengjian: { + trigger: { player: "useCard" }, + direct: true, + filter(event, player) { + var type = get.type(event.card, "trick"); + return ( + type == "trick" && + game.hasPlayer(function (current) { + return player.canUse("sha", current, false) && !event.targets.includes(current); + }) + ); }, - content(){ - "step 0" - player.chooseTarget(get.prompt('fengjian'),function(card,player,target){ - return player.canUse('sha',target,false)&&!trigger.targets.includes(target); - }).ai=function(target){ - return get.effect(target,{name:'sha',nature:'thunder'},player,player); - } - "step 1" - if(result.bool){ - player.logSkill('fengjian'); - if(!event.isMine()){ + content() { + "step 0"; + player.chooseTarget(get.prompt("fengjian"), function (card, player, target) { + return player.canUse("sha", target, false) && !trigger.targets.includes(target); + }).ai = function (target) { + return get.effect(target, { name: "sha", nature: "thunder" }, player, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("fengjian"); + if (!event.isMine()) { game.delay(); } - player.useCard({name:'sha',nature:'thunder'},result.targets,false); + player.useCard({ name: "sha", nature: "thunder" }, result.targets, false); player.tempHide(); } }, - ai:{ - expose:0.2, - threaten:1.5, - noautowuxie:true, + ai: { + expose: 0.2, + threaten: 1.5, + noautowuxie: true, }, // group:'fengjian_hide', // subSkill:{ @@ -3110,1595 +3288,1719 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // } }, - huandie:{ - trigger:{player:'phaseBegin'}, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('huandie'),[0,game.countPlayer()],function(card,player,target){ - return target!=player; - }).ai=function(target){ - return get.attitude(player,target); - } - 'step 1' - if(result.bool){ + huandie: { + trigger: { player: "phaseBegin" }, + direct: true, + content() { + "step 0"; + player.chooseTarget( + get.prompt("huandie"), + [0, game.countPlayer()], + function (card, player, target) { + return target != player; + } + ).ai = function (target) { + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { result.targets.sortBySeat(); result.targets.unshift(player); - player.logSkill('huandie',result.targets); - game.asyncDrawAuto(result.targets,function(current){ - return current==player?1:2; + player.logSkill("huandie", result.targets); + game.asyncDrawAuto(result.targets, function (current) { + return current == player ? 1 : 2; }); - player.addTempSkill('huandie_discard'); + player.addTempSkill("huandie_discard"); } }, - ai:{ - threaten:1.5 + ai: { + threaten: 1.5, }, - subSkill:{ - discard:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>current.hp; + subSkill: { + discard: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") > current.hp; }); }, - logTarget(){ - return game.filterPlayer(function(current){ - return current.countCards('h')>current.hp; - }).sortBySeat(); + logTarget() { + return game + .filterPlayer(function (current) { + return current.countCards("h") > current.hp; + }) + .sortBySeat(); }, - content(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current.countCards('h')>current.hp; - }).sortBySeat(); - event.list=list; - 'step 1' - if(event.list.length){ - event.list.shift().chooseToDiscard('h',true,2); + content() { + "step 0"; + var list = game + .filterPlayer(function (current) { + return current.countCards("h") > current.hp; + }) + .sortBySeat(); + event.list = list; + "step 1"; + if (event.list.length) { + event.list.shift().chooseToDiscard("h", true, 2); event.redo(); } - } - } - } - }, - xuezhou:{ - trigger:{player:'phaseBegin'}, - direct:true, - unique:true, - forceunique:true, - intro:{ - content(storage,player){ - var name=get.translation(player); - if(storage==1){ - return '每当一名角色('+name+'除外)受到一次伤害,该角色失去1点体力,'+name+'回复1点体力'; - } - else if(storage==2){ - return '每当一名角色('+name+'除外)造成一次伤害,该角色失去1点体力,'+name+'(若不是受伤害角色)回复1点体力'; - } - else{ - return '未发动'; - } - } + }, + }, }, - content(){ - 'step 0' - var next=player.chooseControl('选项一','选项二','cancel2',function(){ - if(Math.random()<0.65) return 0; + }, + xuezhou: { + trigger: { player: "phaseBegin" }, + direct: true, + unique: true, + forceunique: true, + intro: { + content(storage, player) { + var name = get.translation(player); + if (storage == 1) { + return ( + "每当一名角色(" + + name + + "除外)受到一次伤害,该角色失去1点体力," + + name + + "回复1点体力" + ); + } else if (storage == 2) { + return ( + "每当一名角色(" + + name + + "除外)造成一次伤害,该角色失去1点体力," + + name + + "(若不是受伤害角色)回复1点体力" + ); + } else { + return "未发动"; + } + }, + }, + content() { + "step 0"; + var next = player.chooseControl("选项一", "选项二", "cancel2", function () { + if (Math.random() < 0.65) return 0; return 1; }); - next.prompt=get.prompt('xuezhou'); - next.choiceList=[ - '每当一名其他角色在一个回合中首次受到伤害,该角色失去1点体力,你回复1点体力', - '每当一名其他角色在一个回合中首次造成伤害,该角色失去1点体力,你(若不是受伤害角色)回复1点体力' + next.prompt = get.prompt("xuezhou"); + next.choiceList = [ + "每当一名其他角色在一个回合中首次受到伤害,该角色失去1点体力,你回复1点体力", + "每当一名其他角色在一个回合中首次造成伤害,该角色失去1点体力,你(若不是受伤害角色)回复1点体力", ]; - 'step 1' - if(result.control=='cancel2'){ - player.unmarkSkill('xuezhou'); + "step 1"; + if (result.control == "cancel2") { + player.unmarkSkill("xuezhou"); delete _status.xuezhou; - } - else{ - player.logSkill('xuezhou'); - player.storage.xuezhou=result.index+1; - player.syncStorage('xuezhou'); - player.markSkill('xuezhou'); - _status.xuezhou=player; + } else { + player.logSkill("xuezhou"); + player.storage.xuezhou = result.index + 1; + player.syncStorage("xuezhou"); + player.markSkill("xuezhou"); + _status.xuezhou = player; } }, - ai:{ - threaten:2.5 + ai: { + threaten: 2.5, }, - global:'xuezhou_hp' + global: "xuezhou_hp", }, - xuezhou_hp:{ - trigger:{source:'damageEnd',player:'damageEnd'}, - filter(event,player){ - if(!_status.xuezhou) return false; - if(player==_status.xuezhou) return false; - if(!player.isIn()||!_status.xuezhou.isIn()) return false; - if(_status.currentPhase.hasSkill('xuezhou_hp2')) return false; - switch(_status.xuezhou.storage.xuezhou){ - case 1:return player==event.player; - case 2:return player==event.source; - default:return false; + xuezhou_hp: { + trigger: { source: "damageEnd", player: "damageEnd" }, + filter(event, player) { + if (!_status.xuezhou) return false; + if (player == _status.xuezhou) return false; + if (!player.isIn() || !_status.xuezhou.isIn()) return false; + if (_status.currentPhase.hasSkill("xuezhou_hp2")) return false; + switch (_status.xuezhou.storage.xuezhou) { + case 1: + return player == event.player; + case 2: + return player == event.source; + default: + return false; } }, - silent:true, - content(){ - 'step 0' + silent: true, + content() { + "step 0"; game.delayx(); - _status.currentPhase.addTempSkill('xuezhou_hp2'); - 'step 1' - _status.xuezhou.logSkill('xuezhou',player); + _status.currentPhase.addTempSkill("xuezhou_hp2"); + "step 1"; + _status.xuezhou.logSkill("xuezhou", player); player.loseHp(); - if(_status.xuezhou!=trigger.player){ + if (_status.xuezhou != trigger.player) { _status.xuezhou.recover(); } - } - }, - xuezhou_hp2:{}, - fayin:{ - trigger:{player:'shaBegin'}, - direct:true, - filter(event,player){ - return player.countCards('he')>0; }, - content(){ - 'step 0' - var target=trigger.target; - var bool=get.attitude(player,target)<0; - var next=player.chooseToDiscard('he',get.prompt('fayin',target)); - next.ai=function(card){ - if(bool) return 7-get.value(card); + }, + xuezhou_hp2: {}, + fayin: { + trigger: { player: "shaBegin" }, + direct: true, + filter(event, player) { + return player.countCards("he") > 0; + }, + content() { + "step 0"; + var target = trigger.target; + var bool = get.attitude(player, target) < 0; + var next = player.chooseToDiscard("he", get.prompt("fayin", target)); + next.ai = function (card) { + if (bool) return 7 - get.value(card); return 0; }; - next.logSkill=['fayin',target]; - 'step 1' - if(result.bool){ - var target=trigger.target; - var num=5; - if(target.isMad()){ - num=4; + next.logSkill = ["fayin", target]; + "step 1"; + if (result.bool) { + var target = trigger.target; + var num = 5; + if (target.isMad()) { + num = 4; } - switch(Math.floor(Math.random()*num)){ - case 0:target.randomDiscard(2);break; - case 1:target.damage('fire');break; - case 2:player.changeHujia();break; - case 3:target.turnOver();target.draw();break; - case 4:target.goMad({player:'phaseBegin'});break; + switch (Math.floor(Math.random() * num)) { + case 0: + target.randomDiscard(2); + break; + case 1: + target.damage("fire"); + break; + case 2: + player.changeHujia(); + break; + case 3: + target.turnOver(); + target.draw(); + break; + case 4: + target.goMad({ player: "phaseBegin" }); + break; } } - } - }, - gwbaquan:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')>0; }, - content(){ - 'step 0' - var hs=target.getCards('h'); - player.gain(hs,target); - target.$giveAuto(hs,player); - event.hs=hs; - 'step 1' - var damage=(target.hp>=player.hp&&get.damageEffect(target,player,player)>0); - var hs=event.hs; - if(damage&&target.hp>1){ - for(var i=0;i=8){ - damage=false;break; + }, + gwbaquan: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; + }, + content() { + "step 0"; + var hs = target.getCards("h"); + player.gain(hs, target); + target.$giveAuto(hs, player); + event.hs = hs; + "step 1"; + var damage = target.hp >= player.hp && get.damageEffect(target, player, player) > 0; + var hs = event.hs; + if (damage && target.hp > 1) { + for (var i = 0; i < hs.length; i++) { + if (get.value(hs[i], player, "raw") >= 8) { + damage = false; + break; } } } - player.chooseCard(hs.length,true,'选择还给'+get.translation(target)+'的牌').ai=function(card){ - if(damage){ - return hs.includes(card)?1:0; - } - else{ - return -get.value(card,player,'raw'); - } - } - if(!event.isMine()) game.delay(); - 'step 2' - target.gain(result.cards,player); - player.$giveAuto(result.cards,target); - event.hs2=result.cards; - if(player.hp>target.hp){ + player.chooseCard(hs.length, true, "选择还给" + get.translation(target) + "的牌").ai = + function (card) { + if (damage) { + return hs.includes(card) ? 1 : 0; + } else { + return -get.value(card, player, "raw"); + } + }; + if (!event.isMine()) game.delay(); + "step 2"; + target.gain(result.cards, player); + player.$giveAuto(result.cards, target); + event.hs2 = result.cards; + if (player.hp > target.hp) { event.finish(); } - 'step 3' - for(var i=0;i0){ - target.draw(dh,false); + }, + hunmo_old: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target.countCards("h") != Math.min(3, player.hp); + }, + selectTarget: [1, 3], + content() { + var dh = Math.min(3, player.hp) - target.countCards("h"); + if (dh > 0) { + target.draw(dh, false); target.$draw(dh); game.delay(0.5); - } - else if(dh<0){ - target.chooseToDiscard(-dh,true); - if(player!=target) player.useCard({name:'sha'},target,false); + } else if (dh < 0) { + target.chooseToDiscard(-dh, true); + if (player != target) player.useCard({ name: "sha" }, target, false); } }, - ai:{ - order:11, - result:{ - target(player,target){ - var dh=Math.min(3,player.hp)-target.countCards('h'); - if(dh<0){ - dh+=get.sgn(get.effect(target,{name:'sha'},player,target)); + ai: { + order: 11, + result: { + target(player, target) { + var dh = Math.min(3, player.hp) - target.countCards("h"); + if (dh < 0) { + dh += get.sgn(get.effect(target, { name: "sha" }, player, target)); } return dh; - } - } - } + }, + }, + }, }, - hunmo_old2:{ - trigger:{player:['phaseBegin','phaseEnd']}, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('hunmo'),[1,game.countPlayer()],function(card,player,target){ - return target.countCards('h')!=Math.min(3,target.hp); - }).ai=function(target){ - return get.attitude(player,target)*(Math.min(3,target.hp)-target.countCards('h')); - } - 'step 1' - if(result.bool){ - player.logSkill('hunmo',result.targets); - event.targets=result.targets.slice(0); + hunmo_old2: { + trigger: { player: ["phaseBegin", "phaseEnd"] }, + direct: true, + content() { + "step 0"; + player.chooseTarget( + get.prompt("hunmo"), + [1, game.countPlayer()], + function (card, player, target) { + return target.countCards("h") != Math.min(3, target.hp); + } + ).ai = function (target) { + return ( + get.attitude(player, target) * (Math.min(3, target.hp) - target.countCards("h")) + ); + }; + "step 1"; + if (result.bool) { + player.logSkill("hunmo", result.targets); + event.targets = result.targets.slice(0); event.targets.sortBySeat(); - } - else{ + } else { event.finish(); } - 'step 2' - if(event.targets.length){ - var target=event.targets.shift(); - var dh=Math.min(3,target.hp)-target.countCards('h'); - if(dh>0){ - target.draw(dh,false); + "step 2"; + if (event.targets.length) { + var target = event.targets.shift(); + var dh = Math.min(3, target.hp) - target.countCards("h"); + if (dh > 0) { + target.draw(dh, false); target.$draw(dh); - } - else if(dh<0){ - target.chooseToDiscard(-dh,true).delay=false; + } else if (dh < 0) { + target.chooseToDiscard(-dh, true).delay = false; } game.delay(0.5); event.redo(); } - } + }, }, - huihun:{ - trigger:{player:'phaseEnd'}, - filter(event,player){ - if(!player.storage.huihun) return false; - for(var i=0;i=2) break; + if (list.length >= 2) break; } } - player.gain(list,'gain2','log'); + player.gain(list, "gain2", "log"); }, - ai:{ - threaten:1.8, + ai: { + threaten: 1.8, }, - group:['huihun_count','huihun_count2'], - subSkill:{ - count:{ - trigger:{player:'useCard'}, - silent:true, - filter(event,player){ - return _status.currentPhase==player; + group: ["huihun_count", "huihun_count2"], + subSkill: { + count: { + trigger: { player: "useCard" }, + silent: true, + filter(event, player) { + return _status.currentPhase == player; }, - content(){ - if(!player.storage.huihun){ - player.storage.huihun=[]; + content() { + if (!player.storage.huihun) { + player.storage.huihun = []; } - for(var i=0;i1){ - if(i==0) return 5; + ai: { + basic: { + useful(card, i) { + if (_status.event.player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 4; }, - value(card,player,i){ - if(player.hp>1){ - if(i==0) return 5; + value(card, player, i) { + if (player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 4; }, }, - order(){ - return get.order({name:'sha'})+0.2; + order() { + return get.order({ name: "sha" }) + 0.2; }, - result:{ - target(player,target){ - if(target&&target.isDying()) return 2; - if(lib.config.mode=='stone'&&!player.isMin()){ - if(player.getActCount()+1>=player.actcount) return false; + result: { + target(player, target) { + if (target && target.isDying()) return 2; + if (lib.config.mode == "stone" && !player.isMin()) { + if (player.getActCount() + 1 >= player.actcount) return false; } - var shas=player.getCards('h','sha'); - if(shas.length>1&&player.getCardUsable('sha')>1){ + var shas = player.getCards("h", "sha"); + if (shas.length > 1 && player.getCardUsable("sha") > 1) { return 0; } var card; - if(shas.length){ - for(var i=0;i0); - })){ + if (card) { + if ( + game.hasPlayer(function (current) { + return ( + !current.hujia && + get.attitude(target, current) < 0 && + target.canUse(card, current, true, true) && + get.effect(current, card, target) > 0 + ); + }) + ) { return 1; } } return 0; }, }, - } + }, }, - gwmaoxian_yioufeisi:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_yioufeisisp', - enable(){ - return game.countPlayer()>2; + gwmaoxian_yioufeisi: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_yioufeisisp", + enable() { + return game.countPlayer() > 2; }, - filterTarget(card,player,target){ - return target!=player; + filterTarget(card, player, target) { + return target != player; }, - selectTarget:2, - multitarget:true, - multiline:true, - content(){ - 'step 0' - targets[0].useCard({name:'sha'},targets[1],'noai'); - 'step 1' - if(targets[0].isIn()&&targets[1].isIn()){ - targets[1].useCard({name:'sha'},targets[0],'noai'); + selectTarget: 2, + multitarget: true, + multiline: true, + content() { + "step 0"; + targets[0].useCard({ name: "sha" }, targets[1], "noai"); + "step 1"; + if (targets[0].isIn() && targets[1].isIn()) { + targets[1].useCard({ name: "sha" }, targets[0], "noai"); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target(player,target){ - return get.effect(target,{name:'sha'},target,target); - } - } - } + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + return get.effect(target, { name: "sha" }, target, target); + }, + }, + }, }, - gwmaoxian_luoqi:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_luoqi', - enable:true, - filterTarget(card,player,target){ - return player.canUse('sha',target,false); + gwmaoxian_luoqi: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_luoqi", + enable: true, + filterTarget(card, player, target) { + return player.canUse("sha", target, false); }, - content(){ - 'step 0' - player.useCard({name:'sha'},target,false).animate=false; - 'step 1' - event.targets=game.filterPlayer(function(current){ - return current.canUse('sha',target,false)&¤t!=player; + content() { + "step 0"; + player.useCard({ name: "sha" }, target, false).animate = false; + "step 1"; + event.targets = game.filterPlayer(function (current) { + return current.canUse("sha", target, false) && current != player; }); event.targets.sortBySeat(); - 'step 2' - if(event.targets.length&&target.isIn()){ - event.current=event.targets.shift(); - if(event.current.hasSha()){ - event.current.chooseToUse({name:'sha'},'是否对'+get.translation(target)+'使用一张杀?',target,-1); + "step 2"; + if (event.targets.length && target.isIn()) { + event.current = event.targets.shift(); + if (event.current.hasSha()) { + event.current.chooseToUse( + { name: "sha" }, + "是否对" + get.translation(target) + "使用一张杀?", + target, + -1 + ); } event.redo(); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target(player,target){ - return get.effect(target,{name:'sha'},player,target); - } - } - } + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, + }, + }, }, - gwmaoxian_jieluote:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_jieluote', - enable:true, - filterTarget:true, - content(){ - if(target.isMaxHp()&&target.hp>2){ + gwmaoxian_jieluote: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_jieluote", + enable: true, + filterTarget: true, + content() { + if (target.isMaxHp() && target.hp > 2) { target.damage(2); - } - else{ + } else { target.damage(); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - tag:{ - damage:1 + ai: { + value: 10, + order: 1, + tag: { + damage: 1, }, - result:{ - player(player,target){ - var eff=get.damageEffect(target,player,player); - if(eff>0){ - eff=Math.sqrt(eff); - if(target.isMaxHp()&&target.hp>2){ - if(get.attitude(player,target)>0) return 0; - switch(target.hp){ - case 3:return eff*2; - case 4:return eff*1.5; - default:return eff*1.1; + result: { + player(player, target) { + var eff = get.damageEffect(target, player, player); + if (eff > 0) { + eff = Math.sqrt(eff); + if (target.isMaxHp() && target.hp > 2) { + if (get.attitude(player, target) > 0) return 0; + switch (target.hp) { + case 3: + return eff * 2; + case 4: + return eff * 1.5; + default: + return eff * 1.1; } - } - else{ - switch(target.hp){ - case 1:return eff*1.6; - case 2:return eff*1.1; - default:return eff; + } else { + switch (target.hp) { + case 1: + return eff * 1.6; + case 2: + return eff * 1.1; + default: + return eff; } } } return 0; - } - } - } + }, + }, + }, }, - gwmaoxian_yenaifa:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_yenaifa', - enable:true, - notarget:true, - content(){ - 'step 0' - event.targets=player.getEnemies().randomGets(3).sortBySeat(); - 'step 1' - if(event.targets.length){ + gwmaoxian_yenaifa: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_yenaifa", + enable: true, + notarget: true, + content() { + "step 0"; + event.targets = player.getEnemies().randomGets(3).sortBySeat(); + "step 1"; + if (event.targets.length) { player.line(event.targets.shift().getDebuff(false).addExpose(0.1)); event.redo(); } - 'step 2' + "step 2"; game.delay(); }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player:1 - } - } + ai: { + value: 10, + order: 1, + result: { + player: 1, + }, + }, }, - gwmaoxian_telisi:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_telisi', - enable:true, - notarget:true, - content(){ - 'step 0' - event.targets=player.getFriends().randomGets(3); + gwmaoxian_telisi: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_telisi", + enable: true, + notarget: true, + content() { + "step 0"; + event.targets = player.getFriends().randomGets(3); event.targets.add(player); event.targets.sortBySeat(); - 'step 1' - if(event.targets.length){ + "step 1"; + if (event.targets.length) { player.line(event.targets.shift().getBuff(false).addExpose(0.1)); event.redo(); } - 'step 2' + "step 2"; game.delay(); }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player:1 - } - } + ai: { + value: 10, + order: 1, + result: { + player: 1, + }, + }, }, - gwmaoxian_hengsaite:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_hengsaite', - enable:true, - notarget:true, - content(){ - var targets=game.filterPlayer(function(current){ - return player.canUse('wanjian',current); - }).sortBySeat(); - if(targets.length){ - player.addTempSkill('gwmaoxian_hengsaite_sha'); - player.useCard({name:'wanjian'},targets); + gwmaoxian_hengsaite: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_hengsaite", + enable: true, + notarget: true, + content() { + var targets = game + .filterPlayer(function (current) { + return player.canUse("wanjian", current); + }) + .sortBySeat(); + if (targets.length) { + player.addTempSkill("gwmaoxian_hengsaite_sha"); + player.useCard({ name: "wanjian" }, targets); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player(player,target){ - var targets=game.filterPlayer(function(current){ - return player.canUse('wanjian',current); + ai: { + value: 10, + order: 1, + result: { + player(player, target) { + var targets = game.filterPlayer(function (current) { + return player.canUse("wanjian", current); }); - var eff=0; - for(var i=0;i0) return -1; - if(dh==0&&player.needsToDiscard()) return -0.5; + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + var dh = target.countCards("h") - player.countCards("h"); + if (dh > 0) return -1; + if (dh == 0 && player.needsToDiscard()) return -0.5; return 0; - } - } - } - }, - gwmaoxian_fulisi:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_fulisi', - enable:true, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h'); + }, + }, }, - selectTarget:[1,3], - multitarget:true, - multiline:true, - content(){ - 'step 0' - var dialog=ui.create.dialog('弃置至多2张手牌','hidden'); - for(var i=0;i=player.countCards('h')&&player.canUse('juedou',target); + gwmaoxian_kuite: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_kuite", + enable: true, + filterTarget(card, player, target) { + return ( + target.countCards("h") >= player.countCards("h") && player.canUse("juedou", target) + ); }, - content(){ - 'step 0' - player.useCard({name:'juedou'},target).animate=false; - 'step 1' - if(player.isIn()&&target.isIn()){ - player.useCard({name:'juedou'},target); + content() { + "step 0"; + player.useCard({ name: "juedou" }, target).animate = false; + "step 1"; + if (player.isIn() && target.isIn()) { + player.useCard({ name: "juedou" }, target); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target(player,target){ - return get.effect(target,{name:'juedou'},player,target); - } - } - } + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + return get.effect(target, { name: "juedou" }, player, target); + }, + }, + }, }, - gwmaoxian_haluo:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_haluo', - enable:true, - filterTarget(card,player,target){ + gwmaoxian_haluo: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_haluo", + enable: true, + filterTarget(card, player, target) { return target.isMinHp(); }, - selectTarget:-1, - content(){ + selectTarget: -1, + content() { target.damage(); }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target:-1.5 + ai: { + value: 10, + order: 1, + result: { + target: -1.5, }, - tag:{ - damage:1 - } - } + tag: { + damage: 1, + }, + }, }, - gwmaoxian_dagong:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_dagong', - enable:true, - content(){ - target.addSkill('gw_ciguhanshuang'); - target.addSkill('gw_birinongwu'); - target.addSkill('gw_qinpendayu'); + gwmaoxian_dagong: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_dagong", + enable: true, + content() { + target.addSkill("gw_ciguhanshuang"); + target.addSkill("gw_birinongwu"); + target.addSkill("gw_qinpendayu"); }, - filterTarget(card,player,target){ - return !target.hasSkill('gw_ciguhanshuang')|| - !target.hasSkill('gw_qinpendayu')|| - !target.hasSkill('gw_birinongwu'); + filterTarget(card, player, target) { + return ( + !target.hasSkill("gw_ciguhanshuang") || + !target.hasSkill("gw_qinpendayu") || + !target.hasSkill("gw_birinongwu") + ); }, - changeTarget(player,targets){ - game.filterPlayer(function(current){ - return get.distance(targets[0],current,'pure')==1; - },targets); + changeTarget(player, targets) { + game.filterPlayer(function (current) { + return get.distance(targets[0], current, "pure") == 1; + }, targets); }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target(player,target){ - return get.effect(target,{name:'gw_ciguhanshuang'},player,target); - } - } - } + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + return get.effect(target, { name: "gw_ciguhanshuang" }, player, target); + }, + }, + }, }, - gwmaoxian_gaier:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_gaier', - enable:true, - filterTarget:true, - content(){ - 'step 0' - var str1='令'+get.translation(target); - var str2='1点体力和体力上限' - player.chooseControlList([str1+'增加'+str2,str1+'减少'+str2],function(){ - if(get.attitude(player,target)>0) return 0; + gwmaoxian_gaier: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_gaier", + enable: true, + filterTarget: true, + content() { + "step 0"; + var str1 = "令" + get.translation(target); + var str2 = "1点体力和体力上限"; + player.chooseControlList([str1 + "增加" + str2, str1 + "减少" + str2], function () { + if (get.attitude(player, target) > 0) return 0; return 1; }); - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { target.gainMaxHp(true); target.recover(); - } - else{ + } else { target.loseHp(); target.loseMaxHp(true); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player(player,target){ - var num=1; - if(target.hasSkillTag('maixie_hp')){ - num=1.5; + ai: { + value: 10, + order: 1, + result: { + player(player, target) { + var num = 1; + if (target.hasSkillTag("maixie_hp")) { + num = 1.5; } - return num/Math.sqrt(target.hp+1); - } - } - } - }, - gwmaoxian_airuiting:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_airuiting', - enable:true, - filterTarget(card,player,target){ - return target!=player; + return num / Math.sqrt(target.hp + 1); + }, + }, }, - selectTarget:-1, - content(){ - 'step 0' - target.chooseToUse({name:'sha'},'使用一张杀,或失去1点体力'); - 'step 1' - if(!result.bool){ + }, + gwmaoxian_airuiting: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_airuiting", + enable: true, + filterTarget(card, player, target) { + return target != player; + }, + selectTarget: -1, + content() { + "step 0"; + target.chooseToUse({ name: "sha" }, "使用一张杀,或失去1点体力"); + "step 1"; + if (!result.bool) { target.loseHp(); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - target(player,target){ - if(target.hasSha()){ - if(Math.random()<0.5) return 1; + ai: { + value: 10, + order: 1, + result: { + target(player, target) { + if (target.hasSha()) { + if (Math.random() < 0.5) return 1; return 0; } - if(target.countCards('h')>=2){ + if (target.countCards("h") >= 2) { return 0; - } - else{ + } else { return -1; } - } - } - } + }, + }, + }, }, - gwmaoxian_aisinie:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_aisinie', - enable:true, - notarget:true, - content(){ - 'step 0' + gwmaoxian_aisinie: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_aisinie", + enable: true, + notarget: true, + content() { + "step 0"; player.recover(); - 'step 1' - var list=get.typeCard('spell_silver'); - if(list.length){ - player.chooseVCardButton('获得一张银卡法术',list,true); - } - else{ + "step 1"; + var list = get.typeCard("spell_silver"); + if (list.length) { + player.chooseVCardButton("获得一张银卡法术", list, true); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.gain(game.createCard(result.links[0][2]),'gain2'); + "step 2"; + if (result.bool) { + player.gain(game.createCard(result.links[0][2]), "gain2"); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player:1 - } - } + ai: { + value: 10, + order: 1, + result: { + player: 1, + }, + }, }, - gwmaoxian_falanxisika:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_falanxisika', - enable:true, - notarget:true, - content(){ - 'step 0' - var list=get.typeCard('spell_gold'); - list.remove('gw_huangjiashenpan'); - if(list.length){ - player.chooseVCardButton('使用一张金卡法术',list.randomGets(3),true).ai=function(button){ - var info=get.info(button.link[2]); - if(info&&info.ai&&info.ai.result&&info.ai.result.player){ - return info.ai.result.player(player,player); + gwmaoxian_falanxisika: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_falanxisika", + enable: true, + notarget: true, + content() { + "step 0"; + var list = get.typeCard("spell_gold"); + list.remove("gw_huangjiashenpan"); + if (list.length) { + player.chooseVCardButton("使用一张金卡法术", list.randomGets(3), true).ai = function ( + button + ) { + var info = get.info(button.link[2]); + if (info && info.ai && info.ai.result && info.ai.result.player) { + return info.ai.result.player(player, player); } return 0; }; - } - else{ + } else { event.finish(); } - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { player.useCard(game.createCard(result.links[0][2])); } }, - contentAfter(){ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + contentAfter() { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } }, - ai:{ - value:10, - order:1, - result:{ - player:1 - } - } + ai: { + value: 10, + order: 1, + result: { + player: 1, + }, + }, }, - gwmaoxian_huoge:{ - type:'gwmaoxian', - fullborder:'gold', - vanish:true, - derivation:'gw_diandian', - image:'character:gw_huoge', - enable:true, - notarget:true, - content(){ - 'step 0' - event.cards=get.cards(6); - player.chooseCardButton(event.cards,[1,2],'选择至多两牌依次使用之').set('filterButton',function(button){ - return game.hasPlayer(function(current){ - return player.canUse(button.link,current); + gwmaoxian_huoge: { + type: "gwmaoxian", + fullborder: "gold", + vanish: true, + derivation: "gw_diandian", + image: "character:gw_huoge", + enable: true, + notarget: true, + content() { + "step 0"; + event.cards = get.cards(6); + player + .chooseCardButton(event.cards, [1, 2], "选择至多两牌依次使用之") + .set("filterButton", function (button) { + return game.hasPlayer(function (current) { + return player.canUse(button.link, current); + }); + }) + .set("ai", function (button) { + return get.value(button.link); }); - }).set('ai',function(button){ - return get.value(button.link); - }); - 'step 1' - if(result.bool){ - event.list=result.links.slice(0); - for(var i=0;i=4) return [1,get.tag(card,'damage')*2]; - if(target.hp==3) return [1,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + threaten: 0.8, + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [1, get.tag(card, "damage") * 2]; + if (target.hp == 3) return [1, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } - }, - wxuying:{ - trigger:{player:'phaseBegin'}, - forced:true, - content(){ - 'step 0' - var cards=player.getCards('h',function(card){ - return card.name=='hsfashu_anyingjingxiang'||card._wxuying; - }); - if(cards.length){ - player.lose(cards)._triggered=null; - } - 'step 1' - var card=game.createCard('hsfashu_anyingjingxiang'); - card._modUseful=function(){ - return 7; - }; - card._modValue=function(){ - return 7; - }; - player.gain(card,'gain2'); + }, + }, }, - subSkill:{ - lose:{ - trigger:{player:'loseAfter'}, - silent:true, - content(){ - for(var i=0;i0){ + while (targets.length) { + target = targets.randomRemove(); + if ( + lib.filter.targetEnabled2(card, player, target) && + get.effect(target, card, player, player) > 0 + ) { break; } target = null; } - if(target){ + if (target) { player.storage.hshuanling.remove(choice); - if(!player.storage.hshuanling.length){ - player.unmarkSkill('hshuanling'); - } - else{ - player.syncStorage('hshuanling'); + if (!player.storage.hshuanling.length) { + player.unmarkSkill("hshuanling"); + } else { + player.syncStorage("hshuanling"); player.updateMarks(); } - player.useCard(card,target); + player.useCard(card, target); break; } } @@ -624,8 +687,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.redo(); } }, - group:['hshuanling_count'], - subSkill:{ + group: ["hshuanling_count"], + subSkill: { // clear:{ // trigger:{player:'phaseAfter'}, // silent:true, @@ -633,2840 +696,3007 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // player.storage.hshuanling.length=0; // } // }, - count:{ - trigger:{global:'useCard'}, - silent:true, - filter(event,player){ - if(get.is.converted(event)) return false; - if(!event.player.isEnemiesOf(player)) return false; - if(get.type(event.card)!='trick') return false; - if(event.targets.length!=1) return false; + count: { + trigger: { global: "useCard" }, + silent: true, + filter(event, player) { + if (get.is.converted(event)) return false; + if (!event.player.isEnemiesOf(player)) return false; + if (get.type(event.card) != "trick") return false; + if (event.targets.length != 1) return false; // if(!event.targets[0].isFriendsOf(player)) return false; - if(get.info(event.card).multitarget) return false; - if(get.info(event.card).singleCard) return false; - if(!get.info(event.card).enable) return false; + if (get.info(event.card).multitarget) return false; + if (get.info(event.card).singleCard) return false; + if (!get.info(event.card).enable) return false; return true; }, - content(){ + content() { player.storage.hshuanling.add(trigger.card); - player.markSkill('hshuanling'); - } - } - } + player.markSkill("hshuanling"); + }, + }, + }, }, - hsxiujian:{ - trigger:{player:'useCardToAfter'}, - forced:true, - filter(event,player){ - return get.type2(event.card)=='trick'&&event.target.isEnemiesOf(player); + hsxiujian: { + trigger: { player: "useCardToAfter" }, + forced: true, + filter(event, player) { + return get.type2(event.card) == "trick" && event.target.isEnemiesOf(player); + }, + content() { + player.useCard({ name: "sha" }, trigger.target, false); }, - content(){ - player.useCard({name:'sha'},trigger.target,false); - } }, - hsxingyi:{ - trigger:{global:'useSkillAfter'}, - forced:true, - filter(event,player){ - if(lib.filter.skillDisabled(event.skill)) return false; - if(!game.expandSkills(event.player.getStockSkills()).includes(event.skill)) return false; - return _status.currentPhase==event.player&&event.player.isEnemiesOf(player); + hsxingyi: { + trigger: { global: "useSkillAfter" }, + forced: true, + filter(event, player) { + if (lib.filter.skillDisabled(event.skill)) return false; + if (!game.expandSkills(event.player.getStockSkills()).includes(event.skill)) return false; + return _status.currentPhase == event.player && event.player.isEnemiesOf(player); + }, + content() { + player.addTempSkill(trigger.skill, { player: "phaseAfter" }); }, - content(){ - player.addTempSkill(trigger.skill,{player:'phaseAfter'}); - } }, - hshuanling_old:{ - trigger:{player:'useCardAfter'}, - forced:true, - subSkill:{ - basic:{}, - trick:{} + hshuanling_old: { + trigger: { player: "useCardAfter" }, + forced: true, + subSkill: { + basic: {}, + trick: {}, }, - usable:1, - filter(event,player){ - if(!event.targets) return false; - if(event.targets.length>1) return false; - if(event.targets[0]==player) return false; - return get.type2(event.card)=='trick'; + usable: 1, + filter(event, player) { + if (!event.targets) return false; + if (event.targets.length > 1) return false; + if (event.targets[0] == player) return false; + return get.type2(event.card) == "trick"; }, - content(){ - var list=get.inpile2('trick'); - while(list.length){ - var name=list.randomRemove(); - if(!lib.card[name].multitarget&& - player.canUse(name,trigger.targets[0])&& - get.effect(trigger.targets[0],{name:name},player,player)>0){ - player.useCard(game.createCard(name),trigger.targets[0],false); + content() { + var list = get.inpile2("trick"); + while (list.length) { + var name = list.randomRemove(); + if ( + !lib.card[name].multitarget && + player.canUse(name, trigger.targets[0]) && + get.effect(trigger.targets[0], { name: name }, player, player) > 0 + ) { + player.useCard(game.createCard(name), trigger.targets[0], false); break; } } - } + }, }, - hshuanling_old2:{ - trigger:{player:'useCard'}, - filter(event,player){ + hshuanling_old2: { + trigger: { player: "useCard" }, + filter(event, player) { // if(get.is.converted(event)) return false; - if(!player.countCards('he')) return false; + if (!player.countCards("he")) return false; // if(!event.targets||!event.targets.includes(player)) return false; - var info=get.info(event.card); - if(info.type!='trick'&&info.type!='basic') return false; - if(info.multitarget) return false; - if(event.targets.length>1) return true; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,event.player,current); + var info = get.info(event.card); + if (info.type != "trick" && info.type != "basic") return false; + if (info.multitarget) return false; + if (event.targets.length > 1) return true; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, event.player, current) + ); }); }, - direct:true, - content(){ - 'step 0' - var bool1=(trigger.targets.length>1); - var bool2=game.hasPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,trigger.player,current); + direct: true, + content() { + "step 0"; + var bool1 = trigger.targets.length > 1; + var bool2 = game.hasPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ); }); - if(bool1&&bool2){ - player.chooseControlList(true,get.prompt('hshuanling'),[ - '弃置任意张牌 ,并为'+get.translation(trigger.card)+'增加等量的目标', - '弃置任意张牌 ,并为'+get.translation(trigger.card)+'减少等量的目标'],function(event,player){ - if(_status.event.add) return 0; - return 1; - }).set('add',get.effect(player,trigger.card,trigger.player,player)>=0); - } - else if(bool2){ - event.type='add'; + if (bool1 && bool2) { + player + .chooseControlList( + true, + get.prompt("hshuanling"), + [ + "弃置任意张牌 ,并为" + get.translation(trigger.card) + "增加等量的目标", + "弃置任意张牌 ,并为" + get.translation(trigger.card) + "减少等量的目标", + ], + function (event, player) { + if (_status.event.add) return 0; + return 1; + } + ) + .set("add", get.effect(player, trigger.card, trigger.player, player) >= 0); + } else if (bool2) { + event.type = "add"; event.goto(2); - event.unchosen=true; - } - else{ - event.type='remove'; + event.unchosen = true; + } else { + event.type = "remove"; event.goto(2); - event.unchosen=true; + event.unchosen = true; } - 'step 1' - if(result.control=='cancel2'){ + "step 1"; + if (result.control == "cancel2") { event.finish(); + } else if (result.index == 1) { + event.type = "remove"; + } else { + event.type = "add"; } - else if(result.index==1){ - event.type='remove'; - } - else{ - event.type='add'; - } - 'step 2' - if(event.type=='add'){ - var num=game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,trigger.player,current); + "step 2"; + if (event.type == "add") { + var num = game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ); }); - var num2=game.countPlayer(function(current){ - if(!trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,trigger.player,current)){ - return get.effect(current,trigger.card,player,player)>0; + var num2 = game.countPlayer(function (current) { + if ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ) { + return get.effect(current, trigger.card, player, player) > 0; } return false; }); - if(num2>2) num2=2; + if (num2 > 2) num2 = 2; player.chooseCardTarget({ - selectCard:[1,num], - selectTarget(){ + selectCard: [1, num], + selectTarget() { return ui.selected.cards.length; }, - position:'he', - prompt:event.unchosen?get.prompt('hshuanling'):null, - prompt2:'弃置任意张牌,并为'+get.translation(trigger.card)+'增加等量的目标', - filterTarget(card,player,target){ - return !trigger.targets.includes(target)&&lib.filter.targetEnabled2(trigger.card,trigger.player,target); + position: "he", + prompt: event.unchosen ? get.prompt("hshuanling") : null, + prompt2: "弃置任意张牌,并为" + get.translation(trigger.card) + "增加等量的目标", + filterTarget(card, player, target) { + return ( + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(trigger.card, trigger.player, target) + ); }, - ai1(card){ - if(ui.selected.cards.length>=num2) return 0; - return get.value(trigger.card)-get.value(card)-1; + ai1(card) { + if (ui.selected.cards.length >= num2) return 0; + return get.value(trigger.card) - get.value(card) - 1; + }, + ai2(target) { + var trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, trigger.player, _status.event.player); }, - ai2(target){ - var trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,trigger.player,_status.event.player); - } }); - } - else{ - var num=trigger.targets.length-1; - var num2=game.countPlayer(function(current){ - if(trigger.targets.includes(current)){ - return get.effect(current,trigger.card,player,player)<0; + } else { + var num = trigger.targets.length - 1; + var num2 = game.countPlayer(function (current) { + if (trigger.targets.includes(current)) { + return get.effect(current, trigger.card, player, player) < 0; } return false; }); - if(num2>2) num2=2; + if (num2 > 2) num2 = 2; player.chooseCardTarget({ - selectCard:[1,num], - selectTarget(){ + selectCard: [1, num], + selectTarget() { return ui.selected.cards.length; }, - prompt:event.unchosen?get.prompt('hshuanling'):null, - prompt2:'弃置任意张牌,并为'+get.translation(trigger.card)+'减少等量的目标', - filterTarget(card,player,target){ + prompt: event.unchosen ? get.prompt("hshuanling") : null, + prompt2: "弃置任意张牌,并为" + get.translation(trigger.card) + "减少等量的目标", + filterTarget(card, player, target) { return trigger.targets.includes(target); }, - ai1(card){ - if(!player.needsToDiscard(0,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 0; - if(ui.selected.cards.length>=num2) return 0; - return Math.max(5,get.value(trigger.card))-get.value(card)-1; + ai1(card) { + if ( + !player.needsToDiscard(0, (i, player) => { + return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); + }) + ) + return 0; + if (ui.selected.cards.length >= num2) return 0; + return Math.max(5, get.value(trigger.card)) - get.value(card) - 1; + }, + ai2(target) { + var trigger = _status.event.getTrigger(); + return -get.effect( + target, + trigger.card, + trigger.player, + _status.event.player + ); }, - ai2(target){ - var trigger=_status.event.getTrigger(); - return -get.effect(target,trigger.card,trigger.player,_status.event.player); - } }); } - 'step 3' - if(result.bool){ - if(!event.isMine()) game.delayx(); - event.targets=result.targets.slice(0); - event.cards=result.cards.slice(0); - } - else{ + "step 3"; + if (result.bool) { + if (!event.isMine()) game.delayx(); + event.targets = result.targets.slice(0); + event.cards = result.cards.slice(0); + } else { event.finish(); } - 'step 4' - player.logSkill('hshuanling',event.targets); - player.discard(event.cards).delay=false; - if(event.type=='add'){ - for(var i=0;i0; }, - content(){ + }, + draw: { + trigger: { player: "phaseDrawBegin" }, + silent: true, + filter(event) { + return event.num > 0; + }, + content() { trigger.num--; - } - }, - enter:{ - trigger:{global:'phaseAfter'}, - forced:true, - popup:false, - priority:-60, - filter(event,player){ - return event.player!=player; }, - content(){ - player.insertPhase(null,true); - } - } + }, + enter: { + trigger: { global: "phaseAfter" }, + forced: true, + popup: false, + priority: -60, + filter(event, player) { + return event.player != player; + }, + content() { + player.insertPhase(null, true); + }, + }, }, - content(){ - 'step 0' - event.num=trigger.num; - 'step 1' - if(event.num&&player.storage.ylyuchu.length<3){ - var skill=player.addSubPlayer({ - name:'hs_yelinchulong', - skills:['ylyuchu_draw','ylyuchu_exit','ylyuchu_enter'], - hp:2, - maxHp:2, - hs:get.cards(2), - skill:skill, + content() { + "step 0"; + event.num = trigger.num; + "step 1"; + if (event.num && player.storage.ylyuchu.length < 3) { + var skill = player.addSubPlayer({ + name: "hs_yelinchulong", + skills: ["ylyuchu_draw", "ylyuchu_exit", "ylyuchu_enter"], + hp: 2, + maxHp: 2, + hs: get.cards(2), + skill: skill, // intro:'下个敌方回合开始前,随机切换至此随从', - intro2:'当前回合结束后进行一个额外回合并切换回本体', - onremove(player){ + intro2: "当前回合结束后进行一个额外回合并切换回本体", + onremove(player) { player.storage.ylyuchu.remove(skill); delete lib.skill[skill]; - } + }, }); player.storage.ylyuchu.push(skill); event.num--; event.redo(); } - } + }, }, - nsaiqi:{ - trigger:{player:'useCard'}, - forced:true, - init(player){ - player.storage.nsaiqi=[]; + nsaiqi: { + trigger: { player: "useCard" }, + forced: true, + init(player) { + player.storage.nsaiqi = []; }, - intro:{ - content:'cards' + intro: { + content: "cards", }, - filter(event,player){ - if(ui.cardPile.firstChild&&ui.cardPile.firstChild.vanishtag.includes('nsaiqi')){ + filter(event, player) { + if (ui.cardPile.firstChild && ui.cardPile.firstChild.vanishtag.includes("nsaiqi")) { return false; } return true; }, - onremove:'lose', - content(){ - var cards=get.cards(3); - for(var i=0;i=9; + nsbeiming: { + trigger: { player: "nsaiqiAfter" }, + forced: true, + filter(event, player) { + return player.storage.nsaiqi.length >= 9; }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(); - 'step 1' - player.chooseCardButton(player.storage.nsaiqi,true,'将顺序将牌置于牌堆顶(先选择的在上)',player.storage.nsaiqi.length); - 'step 2' - var list=result.links.slice(0); - while(list.length){ - ui.cardPile.insertBefore(list.pop(),ui.cardPile.firstChild); + "step 1"; + player.chooseCardButton( + player.storage.nsaiqi, + true, + "将顺序将牌置于牌堆顶(先选择的在上)", + player.storage.nsaiqi.length + ); + "step 2"; + var list = result.links.slice(0); + while (list.length) { + ui.cardPile.insertBefore(list.pop(), ui.cardPile.firstChild); } - player.storage.nsaiqi.length=0; - player.unmarkSkill('nsaiqi'); - } + player.storage.nsaiqi.length = 0; + player.unmarkSkill("nsaiqi"); + }, }, - hsnitai:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - video(player,data){ - var skills=data[0]; - var name=data[1]; - lib.skill.hsnitai.process(skills,name); + hsnitai: { + trigger: { player: "phaseUseBegin" }, + forced: true, + video(player, data) { + var skills = data[0]; + var name = data[1]; + lib.skill.hsnitai.process(skills, name); }, - onremove(player){ - player.removeSkill('hsnitai_card'); + onremove(player) { + player.removeSkill("hsnitai_card"); }, - process(skills,name){ - var cardname='hsnitai_'+name; - lib.translate[cardname]=lib.translate[name]; - lib.translate[cardname+'_info']='出牌阶段对自己使用,获得'+get.translation(name)+'的一个技能(替换前一个以此法获得的技能,效果持续2回合)'; - lib.translate[cardname+'_append']=''; - for(var i=0;i
              '+ - get.skillInfoTranslation(skills[i])+'
              '; - if(i【' + + lib.translate[skills[i]] + + "】
              " + + get.skillInfoTranslation(skills[i]) + + "
              "; + if (i < skills.length) { + lib.translate[cardname + "_append"] += "
              "; } } - lib.card[cardname]=lib.card[cardname]||{ - enable:true, - type:'character', - image:'character:'+name, - fullimage:true, - vanish:true, - skills:skills, - derivation:'hs_barnes', - filterTarget(card,player,target){ - return player==target; + lib.card[cardname] = lib.card[cardname] || { + enable: true, + type: "character", + image: "character:" + name, + fullimage: true, + vanish: true, + skills: skills, + derivation: "hs_barnes", + filterTarget(card, player, target) { + return player == target; }, - selectTarget:-1, - content(){ - 'step 0' - var list=lib.card[card.name].skills; - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.switchToAuto=function(){ - event._result=event.skillai(); + dialog.add(ui.create.div(".placeholder")); + event.switchToAuto = function () { + event._result = event.skillai(); dialog.close(); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(); } - else{ - event._result=event.skillai(); - } - 'step 1' - var skill=result; - if(!target.hasSkill(skill)){ + "step 1"; + var skill = result; + if (!target.hasSkill(skill)) { player.popup(skill); target.$gain2(card); - target.removeSkill('hsnitai_card'); - target.storage.hsnitai_card=card; - target.storage.hsnitai_card_count=1; - target.storage.hsnitai_card_skill=skill; - player.syncStorage('hsnitai_card'); - player.syncStorage('hsnitai_card_skill'); - target.addAdditionalSkill('hsnitai_card',skill); - target.addSkill('hsnitai_card'); - game.log(target,'获得技能','【'+get.translation(skill)+'】'); + target.removeSkill("hsnitai_card"); + target.storage.hsnitai_card = card; + target.storage.hsnitai_card_count = 1; + target.storage.hsnitai_card_skill = skill; + player.syncStorage("hsnitai_card"); + player.syncStorage("hsnitai_card_skill"); + target.addAdditionalSkill("hsnitai_card", skill); + target.addSkill("hsnitai_card"); + game.log(target, "获得技能", "【" + get.translation(skill) + "】"); } }, - ai:{ - order(){ - if(_status.event.player.hasSkill('hsnitai_card')) return 1; + ai: { + order() { + if (_status.event.player.hasSkill("hsnitai_card")) return 1; return 9; }, - result:{ - target(player,target){ - if(!player.hasSkill('hsnitai_card')||player.needsToDiscard()) return 1; + result: { + target(player, target) { + if (!player.hasSkill("hsnitai_card") || player.needsToDiscard()) return 1; return 0; - } - } - } + }, + }, + }, }; }, - content(){ - var current=game.expandSkills(player.getSkills()); - var list=get.gainableSkills(function(info,skill,name){ - if(current.includes(skill)) return false; - return lib.characterPack.hearth&&lib.characterPack.hearth[name]; + content() { + var current = game.expandSkills(player.getSkills()); + var list = get.gainableSkills(function (info, skill, name) { + if (current.includes(skill)) return false; + return lib.characterPack.hearth && lib.characterPack.hearth[name]; }); - if(!list.length){ + if (!list.length) { return; } - var skill=list.randomGet(); - var source=[]; - for(var i in lib.characterPack.hearth){ - if(lib.characterPack.hearth[i][3].includes(skill)){ + var skill = list.randomGet(); + var source = []; + for (var i in lib.characterPack.hearth) { + if (lib.characterPack.hearth[i][3].includes(skill)) { source.push(i); } } - if(!source.length){ + if (!source.length) { return; } - var name=source.randomGet(); - var skills=[skill]; - var nameskills=lib.characterPack.hearth[name][3] - for(var i=0;i【'+lib.translate[skill]+'】
              '+ - get.skillInfoTranslation(skill)+'
              '; + return ( + '
              【' + + lib.translate[skill] + + "】
              " + + get.skillInfoTranslation(skill) + + "
              " + ); + }, + }, + trigger: { player: "phaseUseBegin" }, + priority: -10, + silent: true, + content() { + if (player.storage.hsnitai_card_count > 0) { + player.storage.hsnitai_card_count--; + } else { + player.removeSkill("hsnitai_card"); } }, - trigger:{player:'phaseUseBegin'}, - priority:-10, - silent:true, - content(){ - if(player.storage.hsnitai_card_count>0){ - player.storage.hsnitai_card_count--; - } - else{ - player.removeSkill('hsnitai_card'); - } - } - } - } + }, + }, }, - hspuzhao:{ - enable:'phaseUse', - usable:1, - filterCard:{suit:'heart'}, - position:'he', - filter(event,player){ - return player.countCards('he',{suit:'heart'})>0; + hspuzhao: { + enable: "phaseUse", + usable: 1, + filterCard: { suit: "heart" }, + position: "he", + filter(event, player) { + return player.countCards("he", { suit: "heart" }) > 0; }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - content(){ - var targets=player.getFriends(); - if(targets.length){ + content() { + var targets = player.getFriends(); + if (targets.length) { targets.push(player); - if(targets.length>3){ - targets=targets.randomGets(3); + if (targets.length > 3) { + targets = targets.randomGets(3); } targets.sortBySeat(); - player.line(targets,'green'); - for(var i=0;i0; + hstianqi: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("he") > 0; }, - position:'he', - init(player){ - player.storage.hstianqi=[]; + position: "he", + init(player) { + player.storage.hstianqi = []; }, - onremove:true, - filterCard(card,player){ - if(get.position(card)=='h'){ - if(player.getEquip(1)&&player.getEquip(2)&& - player.getEquip(3)&&player.getEquip(4)){ + onremove: true, + filterCard(card, player) { + if (get.position(card) == "h") { + if ( + player.getEquip(1) && + player.getEquip(2) && + player.getEquip(3) && + player.getEquip(4) + ) { return false; } return true; - } - else{ + } else { return true; } }, - check(card){ - var player=_status.event.player; - if(get.position(card)=='e'){ - if(card.name.indexOf('hstianqi_')==0){ - for(var i=0;i0; }, - content(){ + }, + hstianqi_shali: { + trigger: { player: "recoverEnd" }, + forced: true, + filter(event, player) { + return event.num > 0; + }, + content() { player.changeHujia(trigger.num); - } + }, }, - ysjqisha:{ - trigger:{source:'damageEnd',player:'damageEnd'}, - forced:true, - filter(event,player){ - if(event._notrigger.includes(event.player)) return false; - return (event.source!=player&&event.source.isIn())||(event.player!=player&&event.player.isIn()); + ysjqisha: { + trigger: { source: "damageEnd", player: "damageEnd" }, + forced: true, + filter(event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + (event.source != player && event.source.isIn()) || + (event.player != player && event.player.isIn()) + ); }, - content(){ - var target=trigger.source; - if(target==player){ - target=trigger.player; + content() { + var target = trigger.source; + if (target == player) { + target = trigger.player; } - var list=['ju','kuang','nu','yi','wang','hen','ao']; - for(var i=0;i0; + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return player.countCards("he") > 0; }, - content(){ + content() { game.delay(0.5); - player.chooseToDiscard(true,'he'); - } + player.chooseToDiscard(true, "he"); + }, }, - kuang:{ - mark:true, - intro:{ - content:'锁定技,每当你使用一张牌指定惟一目标,有50%的机率指定错误的目标' + kuang: { + mark: true, + intro: { + content: "锁定技,每当你使用一张牌指定惟一目标,有50%的机率指定错误的目标", }, - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return event.getRand()<0.5&&event.targets&&event.targets.length==1&&game.hasPlayer(function(current){ - return current!=event.targets[0]&&lib.filter.targetEnabled2(event.card,player,current); - }); + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return ( + event.getRand() < 0.5 && + event.targets && + event.targets.length == 1 && + game.hasPlayer(function (current) { + return ( + current != event.targets[0] && + lib.filter.targetEnabled2(event.card, player, current) + ); + }) + ); }, - content(){ - 'step 0' + content() { + "step 0"; game.delay(); - 'step 1' - var list=game.filterPlayer(function(current){ - return current!=trigger.targets[0]&&lib.filter.targetEnabled2(trigger.card,player,current); + "step 1"; + var list = game.filterPlayer(function (current) { + return ( + current != trigger.targets[0] && + lib.filter.targetEnabled2(trigger.card, player, current) + ); }); - if(list.length){ - var target=list.randomGet(); - trigger.targets[0]=target; - player.line(target,'green'); + if (list.length) { + var target = list.randomGet(); + trigger.targets[0] = target; + player.line(target, "green"); } - } + }, }, - nu:{ - mark:true, - intro:{ - content:'锁定技,你使用的卡牌造成的伤害+1;每当你使用一张牌,有65%的机率失效' + nu: { + mark: true, + intro: { + content: "锁定技,你使用的卡牌造成的伤害+1;每当你使用一张牌,有65%的机率失效", }, - forced:true, - trigger:{source:'damageBegin',player:'useCardToBefore'}, - filter(event,player){ - if(event.name=='damage') return event.notLink()&&(event.card?true:false); - var info=get.info(event.card); - if(info.multitarget&&event.targets&&event.targets.includes(player)) return false; - return event.getRand()<0.65; + forced: true, + trigger: { source: "damageBegin", player: "useCardToBefore" }, + filter(event, player) { + if (event.name == "damage") return event.notLink() && (event.card ? true : false); + var info = get.info(event.card); + if (info.multitarget && event.targets && event.targets.includes(player)) + return false; + return event.getRand() < 0.65; }, - content(){ - if(trigger.name=='damage'){ + content() { + if (trigger.name == "damage") { trigger.num++; - } - else{ + } else { trigger.cancel(); } - } - }, - yi:{ - mark:true, - intro:{ - content:'锁定技,你不能成为非敌方角色的卡牌目标' }, - mod:{ - targetEnabled(card,player,target){ - if(!player.getEnemies().includes(target)) return false; - } - } }, - wang:{ - mark:true, - intro:{ - content:'锁定技,你的摸牌数始终-1' + yi: { + mark: true, + intro: { + content: "锁定技,你不能成为非敌方角色的卡牌目标", }, - priority:5, - trigger:{player:'drawBegin'}, - forced:true, - content(){ + mod: { + targetEnabled(card, player, target) { + if (!player.getEnemies().includes(target)) return false; + }, + }, + }, + wang: { + mark: true, + intro: { + content: "锁定技,你的摸牌数始终-1", + }, + priority: 5, + trigger: { player: "drawBegin" }, + forced: true, + content() { trigger.num--; - } - }, - hen:{ - mark:true, - intro:{ - content:'锁定技,每当一名敌方角色回复1点体力,你失去1点体力' }, - trigger:{global:'recoverAfter'}, - forced:true, - filter(event,player){ + }, + hen: { + mark: true, + intro: { + content: "锁定技,每当一名敌方角色回复1点体力,你失去1点体力", + }, + trigger: { global: "recoverAfter" }, + forced: true, + filter(event, player) { return player.getEnemies().includes(event.player); }, - content(){ + content() { player.loseHp(); - } - }, - ao:{ - mark:true, - intro:{ - content:'锁定技,你的手牌上限-2' }, - mod:{ - maxHandcard(player,num){ - return num-2; - } - } }, - } + ao: { + mark: true, + intro: { + content: "锁定技,你的手牌上限-2", + }, + mod: { + maxHandcard(player, num) { + return num - 2; + }, + }, + }, + }, }, - yindan:{ - enable:'phaseUse', - filterCard:{suit:'spade'}, - check(card){ - return 8-get.value(card); + yindan: { + enable: "phaseUse", + filterCard: { suit: "spade" }, + check(card) { + return 8 - get.value(card); }, - usable:1, - filter(event,player){ - return player.countCards('he',{suit:'spade'})>0; + usable: 1, + filter(event, player) { + return player.countCards("he", { suit: "spade" }) > 0; }, - position:'he', - content(){ - 'step 0' + position: "he", + content() { + "step 0"; player.loseHp(); - 'step 1' - var cards=[]; - for(var i=0;i<2;i++){ - cards.push(game.createCard('hsjixie_zhadan')); + "step 1"; + var cards = []; + for (var i = 0; i < 2; i++) { + cards.push(game.createCard("hsjixie_zhadan")); } - player.gain(cards,'gain2'); + player.gain(cards, "gain2"); }, - ai:{ - order:7, - result:{ - player(player,target){ - if(player.hp>=3) return 1; - if(player.hp==2&&game.hasPlayer(function(current){ - return get.damageEffect(current,player,player,'fire')>0&¤t.hp==1; - })){ + ai: { + order: 7, + result: { + player(player, target) { + if (player.hp >= 3) return 1; + if ( + player.hp == 2 && + game.hasPlayer(function (current) { + return ( + get.damageEffect(current, player, player, "fire") > 0 && + current.hp == 1 + ); + }) + ) { return 1; } return 0; - } - } - } + }, + }, + }, }, - hllingxi:{ - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(function(target){ - return lib.skill.hllingxi.filterTarget(null,player,target); + hllingxi: { + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer(function (target) { + return lib.skill.hllingxi.filterTarget(null, player, target); }); }, - filterTarget(card,player,target){ - if(target.hasSkill('hllingxi_used')) return false; - return target!=player&&target.isDamaged()&&target.countCards('he')>=2; + filterTarget(card, player, target) { + if (target.hasSkill("hllingxi_used")) return false; + return target != player && target.isDamaged() && target.countCards("he") >= 2; }, - content(){ - 'step 0' - target.chooseToDiscard('he',2,true); - 'step 1' + content() { + "step 0"; + target.chooseToDiscard("he", 2, true); + "step 1"; target.recover(); - target.addTempSkill('hllingxi_used'); + target.addTempSkill("hllingxi_used"); }, - group:'hllingxi_end', - subSkill:{ - used:{}, - end:{ - trigger:{player:'phaseEnd'}, - frequent:true, - filter(event,player){ + group: "hllingxi_end", + subSkill: { + used: {}, + end: { + trigger: { player: "phaseEnd" }, + frequent: true, + filter(event, player) { return player.isDamaged(); }, - content(){ + content() { player.recover(); - } - } + }, + }, }, - ai:{ - order:6, - result:{ - target(player,target){ - var nc=target.countCards('he'); - if(target.hasSkillTag('maixie_hp')){ - if(nc>=3) return 1; - if(target.hp==1) return 1; + ai: { + order: 6, + result: { + target(player, target) { + var nc = target.countCards("he"); + if (target.hasSkillTag("maixie_hp")) { + if (nc >= 3) return 1; + if (target.hp == 1) return 1; return 0; } - if(nc>=4){ - if(target.hp<=2) return 1; + if (nc >= 4) { + if (target.hp <= 2) return 1; return 0; - } - else if(nc==3){ - if(target.hp==1) return 1; - if(target.hp>=4) return -1; + } else if (nc == 3) { + if (target.hp == 1) return 1; + if (target.hp >= 4) return -1; return 0; - } - else{ - if(target.hp==1) return 0; + } else { + if (target.hp == 1) return 0; return -1; } - } - } - } - }, - zhaochao:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.getEnemies().length>0; + }, + }, }, - content(){ - 'step 0' - event.targets=player.getEnemies(); - player.addSkill('zhaochao2'); - player.useCard({name:'sha'},event.targets.randomRemove()); - 'step 1' - player.removeSkill('zhaochao2'); - if(player.storage.zhaochao2&&event.targets.length){ - player.useCard({name:'sha'},event.targets.randomRemove()); + }, + zhaochao: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.getEnemies().length > 0; + }, + content() { + "step 0"; + event.targets = player.getEnemies(); + player.addSkill("zhaochao2"); + player.useCard({ name: "sha" }, event.targets.randomRemove()); + "step 1"; + player.removeSkill("zhaochao2"); + if (player.storage.zhaochao2 && event.targets.length) { + player.useCard({ name: "sha" }, event.targets.randomRemove()); delete player.storage.zhaochao2; } }, - ai:{ - threaten:1.7 - } - }, - zhaochao2:{ - trigger:{player:'shaMiss'}, - silent:true, - filter(event){ - return event.getParent(2).name=='zhaochao'; + ai: { + threaten: 1.7, }, - content(){ - player.storage.zhaochao2=true; - } }, - xiyong:{ - trigger:{player:'phaseEnd'}, - frequent:true, - content(){ - 'step 0' + zhaochao2: { + trigger: { player: "shaMiss" }, + silent: true, + filter(event) { + return event.getParent(2).name == "zhaochao"; + }, + content() { + player.storage.zhaochao2 = true; + }, + }, + xiyong: { + trigger: { player: "phaseEnd" }, + frequent: true, + content() { + "step 0"; player.draw(); - 'step 1' - if(Array.isArray(result)&&result.length){ - var gained=result[0]; - if(lib.filter.cardEnabled(gained,target)){ - var next=player.chooseToUse(); - next.filterCard=function(card){ - return card==gained; + "step 1"; + if (Array.isArray(result) && result.length) { + var gained = result[0]; + if (lib.filter.cardEnabled(gained, target)) { + var next = player.chooseToUse(); + next.filterCard = function (card) { + return card == gained; }; - next.prompt='是否使用'+get.translation(gained)+'?'; - } - else{ + next.prompt = "是否使用" + get.translation(gained) + "?"; + } else { event.finish(); } - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.draw(); } }, - ai:{ - threaten:1.6 - } + ai: { + threaten: 1.6, + }, }, - srjici:{ - trigger:{source:'damageEnd'}, - forced:true, - content(){ + srjici: { + trigger: { source: "damageEnd" }, + forced: true, + content() { player.draw(); - if(trigger.player&&trigger.player.isIn()&&!trigger._notrigger.includes(trigger.player)){ + if ( + trigger.player && + trigger.player.isIn() && + !trigger._notrigger.includes(trigger.player) + ) { trigger.player.randomDiscard(); } }, - ai:{ - threaten:1.4 - } + ai: { + threaten: 1.4, + }, }, - yinzong:{ - trigger:{player:'loseEnd'}, - forced:true, - filter(event,player){ - for(var i=0;i0; - })){ - switch(button.link[2]){ - case 'tao':return 5; - case 'xuejibingbao': return 4; - case 'jiu':return 3.01; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder') return 2.92; + check(button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + return 5; + case "xuejibingbao": + return 4; + case "jiu": + return 3.01; + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder") return 2.92; else return 2.9; - default:return 2+_status.event.getRand()*2; + default: + return 2 + _status.event.getRand() * 2; } } return 0; }, - backup(links,player){ + backup(links, player) { return { - filterCard(card){ - return get.type(card)=='basic'; + filterCard(card) { + return get.type(card) == "basic"; }, - viewAs:{name:links[0][2],nature:links[0][3]}, - popname:true, - ai1(card){ - return 6-get.value(card); - } - } + viewAs: { name: links[0][2], nature: links[0][3] }, + popname: true, + ai1(card) { + return 6 - get.value(card); + }, + }; + }, + prompt(links, player) { + return ( + "将一张基本牌当作" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt(links,player){ - return '将一张基本牌当作'+get.translation(links[0][3]||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order(){ - var player=_status.event.player; - var event=_status.event; - if(event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0){ + ai: { + order() { + var player = _status.event.player; + var event = _status.event; + if ( + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 + ) { return 3.1; } return 2.9; }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, - shouwang:{ - enable:'chooseToUse', - filter(event,player){ - return event.type=='dying'&&event.dying&&!event.dying.hasSkill('shouwang2'); + shouwang: { + enable: "chooseToUse", + filter(event, player) { + return event.type == "dying" && event.dying && !event.dying.hasSkill("shouwang2"); }, - filterTarget(card,player,target){ - return target==_status.event.dying; + filterTarget(card, player, target) { + return target == _status.event.dying; }, - selectTarget:-1, - content(){ + selectTarget: -1, + content() { target.recover(); target.changeHujia(); - target.addSkill('shouwang2') + target.addSkill("shouwang2"); }, - ai:{ - order:6, - skillTagFilter(player){ - if(!_status.event.dying||_status.event.dying.hasSkill('shouwang2')) return false; + ai: { + order: 6, + skillTagFilter(player) { + if (!_status.event.dying || _status.event.dying.hasSkill("shouwang2")) return false; }, - save:true, - result:{ - target:3 + save: true, + result: { + target: 3, }, - threaten:1.6 + threaten: 1.6, }, }, - shouwang2:{ + shouwang2: { charlotte: true, - mark:true, - intro:{ - content:'已发动' - } + mark: true, + intro: { + content: "已发动", + }, }, - qingtian:{ - trigger:{player:'damageBegin'}, - forced:true, - filter(event,player){ + qingtian: { + trigger: { player: "damageBegin" }, + forced: true, + filter(event, player) { return player.isMaxHp(true); }, - check(){ + check() { return false; }, - content(){ + content() { trigger.num++; - } - }, - qingtian_old:{ - trigger:{player:'recoverBefore'}, - forced:true, - filter(event,player){ - return player.hp>0&&event.num>0; }, - content(){ + }, + qingtian_old: { + trigger: { player: "recoverBefore" }, + forced: true, + filter(event, player) { + return player.hp > 0 && event.num > 0; + }, + content() { trigger.cancel(); player.changeHujia(trigger.num); }, - ai:{ - neg:true - } - }, - qianfu:{ - trigger:{player:'dieBefore'}, - forced:true, - filter(event,player){ - return !player.hasSkill('qianfu2')&&player.maxHp>0; + ai: { + neg: true, }, - unique:true, - content(){ + }, + qianfu: { + trigger: { player: "dieBefore" }, + forced: true, + filter(event, player) { + return !player.hasSkill("qianfu2") && player.maxHp > 0; + }, + unique: true, + content() { trigger.cancel(); - player.addSkill('qianfu2'); - player.hp=1; + player.addSkill("qianfu2"); + player.hp = 1; player.update(); - player.discard(player.getCards('he')); - player.setAvatar('hs_selajin','hs_selajin2'); + player.discard(player.getCards("he")); + player.setAvatar("hs_selajin", "hs_selajin2"); + }, + ai: { + threaten: 0.8, }, - ai:{ - threaten:0.8 - } }, - qianfu2:{ - mark:true, - intro:{ - content:'你防止非火焰伤害,不能使用或打出卡牌,并始终跳过你的回合' + qianfu2: { + mark: true, + intro: { + content: "你防止非火焰伤害,不能使用或打出卡牌,并始终跳过你的回合", }, - mod:{ - cardEnabled(card,player){ + mod: { + cardEnabled(card, player) { return false; }, - cardUsable(card,player){ + cardUsable(card, player) { return false; }, - cardRespondable(card,player){ + cardRespondable(card, player) { return false; }, - cardSavable(card,player){ + cardSavable(card, player) { return false; }, }, - group:['qianfu2_damage','qianfu2_phase','qianfu2_revive'], - subSkill:{ - damage:{ - trigger:{player:'damageBefore'}, - filter(event){ - if(event.nature!='fire') return true; + group: ["qianfu2_damage", "qianfu2_phase", "qianfu2_revive"], + subSkill: { + damage: { + trigger: { player: "damageBefore" }, + filter(event) { + if (event.nature != "fire") return true; return false; }, - mark:true, - forced:true, - content(){ + mark: true, + forced: true, + content() { trigger.cancel(); }, - ai:{ - nothunder:true, - nodamage:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'damage')&&!get.tag(card,'fireDamage')) return [0,0]; - } + ai: { + nothunder: true, + nodamage: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "damage") && !get.tag(card, "fireDamage")) + return [0, 0]; + }, }, }, }, - phase:{ - trigger:{player:'phaseBefore'}, - forced:true, - popup:false, - content(){ + phase: { + trigger: { player: "phaseBefore" }, + forced: true, + popup: false, + content() { trigger.cancel(); - } - }, - revive:{ - trigger:{player:['changeHp','loseMaxHpAfter']}, - forced:true, - filter(event,player){ - return player.hp>=3||player.isHealthy(); }, - content(){ - player.removeSkill('qianfu2'); + }, + revive: { + trigger: { player: ["changeHp", "loseMaxHpAfter"] }, + forced: true, + filter(event, player) { + return player.hp >= 3 || player.isHealthy(); + }, + content() { + player.removeSkill("qianfu2"); player.draw(3); - player.setAvatar('hs_selajin','hs_selajin'); - } - } - } - }, - shimo:{ - trigger:{global:'damageAfter'}, - forced:true, - filter(event,player){ - return event.player!=player&&get.distance(player,event.player)<=1; + player.setAvatar("hs_selajin", "hs_selajin"); + }, + }, }, - content(){ - if(player.isDamaged()){ + }, + shimo: { + trigger: { global: "damageAfter" }, + forced: true, + filter(event, player) { + return event.player != player && get.distance(player, event.player) <= 1; + }, + content() { + if (player.isDamaged()) { player.recover(); - } - else{ + } else { player.draw(); } - } - }, - lieyang:{ - trigger:{player:'useCard'}, - forced:true, - usable:3, - filter(event,player){ - return _status.currentPhase==player&&get.type(event.card,'trick')=='trick'; }, - content(){ - var list=get.inpile('trick','trick'); - player.gain(game.createCard(list.randomGet()),'draw'); - if(player.storage.counttrigger&&player.storage.counttrigger.lieyang>=3){ - player.addTempSkill('lieyang2'); + }, + lieyang: { + trigger: { player: "useCard" }, + forced: true, + usable: 3, + filter(event, player) { + return _status.currentPhase == player && get.type(event.card, "trick") == "trick"; + }, + content() { + var list = get.inpile("trick", "trick"); + player.gain(game.createCard(list.randomGet()), "draw"); + if (player.storage.counttrigger && player.storage.counttrigger.lieyang >= 3) { + player.addTempSkill("lieyang2"); } }, - ai:{ - threaten:1.8 - } - }, - lieyang2:{ - mod:{ - cardEnabled(card){if(get.type(card,'trick')=='trick') return false} - } - }, - zhuilie:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ - return player.countCards('he')>0; + ai: { + threaten: 1.8, }, - content(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('zhuilie')).set('ai',function(card){ - if(player.hp>=4||(player.hasSha()&&player.hasShan())){ - return 6-get.value(card); + }, + lieyang2: { + mod: { + cardEnabled(card) { + if (get.type(card, "trick") == "trick") return false; + }, + }, + }, + zhuilie: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { + return player.countCards("he") > 0; + }, + content() { + "step 0"; + player.chooseToDiscard("he", get.prompt("zhuilie")).set("ai", function (card) { + if (player.hp >= 4 || (player.hasSha() && player.hasShan())) { + return 6 - get.value(card); } - if(player.hasSha()||player.hasShan()){ - return 3-get.value(card); + if (player.hasSha() || player.hasShan()) { + return 3 - get.value(card); } return 0; - }).logSkill='zhuilie'; - 'step 1' - if(result.bool){ - var list=[]; - var list2=[]; - for(var i=0;i<6&&i3){ + player.showCards( + get.translation(player) + "将" + get.cnNumber(list2.length) + "张牌移入弃牌堆", + list2 + ); + if (list2.length > 3) { player.draw(); } } - } + }, }, - szbianshen:{ - trigger:{player:'phaseBefore'}, - unique:true, - skillAnimation:true, - forceunique:true, - filter(){ - return game.roundNumber>=3; + szbianshen: { + trigger: { player: "phaseBefore" }, + unique: true, + skillAnimation: true, + forceunique: true, + filter() { + return game.roundNumber >= 3; }, - check(event,player){ - return player.hp<=2; + check(event, player) { + return player.hp <= 2; }, - content(){ - 'step 0' - var list=get.gainableCharacters(function(info){ - return info[2]>=5; + content() { + "step 0"; + var list = get.gainableCharacters(function (info) { + return info[2] >= 5; }); - var players=game.players.concat(game.dead); - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.switchToAuto=function(){ - event._result=event.skillai(); + dialog.add(ui.create.div(".placeholder")); + event.switchToAuto = function () { + event._result = event.skillai(); dialog.close(); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(); } - else{ - event._result=event.skillai(); - } - 'step 1' - _status.imchoosing=false; - var link=result; - player.addSkill(link,true); + "step 1"; + _status.imchoosing = false; + var link = result; + player.addSkill(link, true); player.popup(link); - game.log(player,'获得了技能','【'+get.translation(link)+'】'); + game.log(player, "获得了技能", "【" + get.translation(link) + "】"); game.delay(); }, - ai:{ - effect:{ - target(card,player,target){ - if(get.type(card,'trick')=='trick'&&player==target) return [1,1]; - } - } - } + ai: { + effect: { + target(card, player, target) { + if (get.type(card, "trick") == "trick" && player == target) return [1, 1]; + }, + }, + }, }, - kqizhou:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ + kqizhou: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { return player.storage.kqizhou; }, - content(){ - 'step 0' + content() { + "step 0"; delete player.storage.kqizhou; - var list=[['','','hsqizhou_feng'], - ['','','hsqizhou_shui'], - ['','','hsqizhou_huo'], - ['','','hsqizhou_tu']]; - var dialog=ui.create.dialog(get.prompt('kqizhou'),[list,'vcard'],'hidden'); - var shui=(player.hp<=1&&player.maxHp>=3); - var tu=game.hasPlayer(function(current){ - return current.hp==1&&get.attitude(player,current)>0; + var list = [ + ["", "", "hsqizhou_feng"], + ["", "", "hsqizhou_shui"], + ["", "", "hsqizhou_huo"], + ["", "", "hsqizhou_tu"], + ]; + var dialog = ui.create.dialog(get.prompt("kqizhou"), [list, "vcard"], "hidden"); + var shui = player.hp <= 1 && player.maxHp >= 3; + var tu = game.hasPlayer(function (current) { + return current.hp == 1 && get.attitude(player, current) > 0; }); - player.chooseButton(dialog).ai=function(button){ - if(!player.hasFriend()&&button.link[2]=='hsqizhou_tu') return 0; - if(player.isHealthy()&&button.link[2]=='hsqizhou_shui') return 0; - if(shui&&button.link[2]=='hsqizhou_shui') return 3; - if(tu&&button.link[2]=='hsqizhou_tu') return 2; + player.chooseButton(dialog).ai = function (button) { + if (!player.hasFriend() && button.link[2] == "hsqizhou_tu") return 0; + if (player.isHealthy() && button.link[2] == "hsqizhou_shui") return 0; + if (shui && button.link[2] == "hsqizhou_shui") return 3; + if (tu && button.link[2] == "hsqizhou_tu") return 2; return Math.random(); }; - 'step 1' - if(result.buttons){ - player.logSkill('kqizhou'); - player.gain(game.createCard(result.buttons[0].link[2]),'draw'); + "step 1"; + if (result.buttons) { + player.logSkill("kqizhou"); + player.gain(game.createCard(result.buttons[0].link[2]), "draw"); } }, - group:'kqizhou_add', - subSkill:{ - add:{ - trigger:{player:'useCard'}, - silent:true, - filter(event,player){ - return _status.currentPhase==player&&get.type(event.card,'trick')=='trick'; + group: "kqizhou_add", + subSkill: { + add: { + trigger: { player: "useCard" }, + silent: true, + filter(event, player) { + return _status.currentPhase == player && get.type(event.card, "trick") == "trick"; }, - content(){ - player.storage.kqizhou=true; - } - } - } - }, - jingcu:{ - enable:'phaseUse', - filter(event,player){ - return player.maxHp>1; + content() { + player.storage.kqizhou = true; + }, + }, }, - content(){ - 'step 0' + }, + jingcu: { + enable: "phaseUse", + filter(event, player) { + return player.maxHp > 1; + }, + content() { + "step 0"; player.loseMaxHp(true); - 'step 1' + "step 1"; player.draw(2); }, - ai:{ - order:1.5, - threaten:1.4, - result:{ - player(player){ - if(player.isDamaged()) return 1; - if(player.hp>=3&&!player.needsToDiscard(2)) return 1; + ai: { + order: 1.5, + threaten: 1.4, + result: { + player(player) { + if (player.isDamaged()) return 1; + if (player.hp >= 3 && !player.needsToDiscard(2)) return 1; return 0; - } - } + }, + }, }, }, - shengzhang:{ - trigger:{player:'phaseDiscardEnd'}, - forced:true, - filter(event,player){ - return event.cards&&event.cards.length>0; + shengzhang: { + trigger: { player: "phaseDiscardEnd" }, + forced: true, + filter(event, player) { + return event.cards && event.cards.length > 0; }, - content(){ + content() { player.gainMaxHp(true); - } - }, - pyuhuo:{ - unique:true, - skillAnimation:true, - animationColor:'fire', - trigger:{player:'dying'}, - priority:10, - filter(event,player){ - return player.storage.pyuhuo!='over'; }, - forced:true, - content(){ - 'step 0' - player.discard(player.getCards('hej')); - 'step 1' + }, + pyuhuo: { + unique: true, + skillAnimation: true, + animationColor: "fire", + trigger: { player: "dying" }, + priority: 10, + filter(event, player) { + return player.storage.pyuhuo != "over"; + }, + forced: true, + content() { + "step 0"; + player.discard(player.getCards("hej")); + "step 1"; player.link(false); - 'step 2' + "step 2"; player.turnOver(false); - 'step 3' - if(player.storage.pyuhuo=='mid'){ - player.storage.pyuhuo='over'; - player.awakenSkill('pyuhuo'); - player.hp=6; - player.maxHp=6; + "step 3"; + if (player.storage.pyuhuo == "mid") { + player.storage.pyuhuo = "over"; + player.awakenSkill("pyuhuo"); + player.hp = 6; + player.maxHp = 6; player.draw(6); - player.setAvatar('hs_pyros','hs_pyros2'); - } - else{ - player.storage.pyuhuo='mid'; - player.hp=4; - player.maxHp=4; + player.setAvatar("hs_pyros", "hs_pyros2"); + } else { + player.storage.pyuhuo = "mid"; + player.hp = 4; + player.maxHp = 4; player.draw(4); - player.setAvatar('hs_pyros','hs_pyros1'); + player.setAvatar("hs_pyros", "hs_pyros1"); } }, - ai:{ - threaten(player,target){ - if(target.storage.pyuhuo=='mid') return 0.6; - if(target.storage.pyuhuo=='over') return 1; + ai: { + threaten(player, target) { + if (target.storage.pyuhuo == "mid") return 0.6; + if (target.storage.pyuhuo == "over") return 1; return 0.4; - } - } + }, + }, }, - mengye:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + mengye: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('mengye'),function(card,player,target){ - return target.countCards('h')>0; - }).ai=function(target){ - if(target.hasSkillTag('nodu')) return get.attitude(player,target)*1.5; - if(target.hasCard(function(card){ - return card.name!='du'; - })){ - return -get.attitude(player,target); + content() { + "step 0"; + player.chooseTarget(get.prompt("mengye"), function (card, player, target) { + return target.countCards("h") > 0; + }).ai = function (target) { + if (target.hasSkillTag("nodu")) return get.attitude(player, target) * 1.5; + if ( + target.hasCard(function (card) { + return card.name != "du"; + }) + ) { + return -get.attitude(player, target); } - return -get.attitude(player,target)/5; - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mengye',target); - var card=target.getCards('h',function(card){ - return card.name!='du'; - }).randomGet(); - if(card){ - card.init([card.suit,card.number,'du']); + return -get.attitude(player, target) / 5; + }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mengye", target); + var card = target + .getCards("h", function (card) { + return card.name != "du"; + }) + .randomGet(); + if (card) { + card.init([card.suit, card.number, "du"]); } target.changeHujia(); - game.log(target,'将一张手牌转化为',{name:'du'}); + game.log(target, "将一张手牌转化为", { name: "du" }); } }, - ai:{ - threaten:1.5 - } + ai: { + threaten: 1.5, + }, }, - mengye_old:{ - trigger:{player:'phaseAfter'}, - priority:-50, - direct:true, - filter(event,player){ - if(get.mode()=='identity'&&_status.mode=='zhong'&& - game.zhu&&!game.zhu.isZhu&&player==game.zhong){ + mengye_old: { + trigger: { player: "phaseAfter" }, + priority: -50, + direct: true, + filter(event, player) { + if ( + get.mode() == "identity" && + _status.mode == "zhong" && + game.zhu && + !game.zhu.isZhu && + player == game.zhong + ) { return false; } - if(_status.noswap){ + if (_status.noswap) { return false; } return !player.isTurnedOver(); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('mengye'),function(card,player,target){ - if(target==player){ + content() { + "step 0"; + player.chooseTarget(get.prompt("mengye"), function (card, player, target) { + if (target == player) { return false; } - if(get.mode()=='identity'&&_status.mode=='zhong'&&game.zhu&&!game.zhu.isZhu){ - return target==game.zhong; + if ( + get.mode() == "identity" && + _status.mode == "zhong" && + game.zhu && + !game.zhu.isZhu + ) { + return target == game.zhong; } - if(target.identity=='zhu'||get.is.jun(target)) return false; + if (target.identity == "zhu" || get.is.jun(target)) return false; return true; - }).ai=function(target){ - var att=-get.attitude(player,target); - if(att<=0) return 0; - if(target.needsToDiscard()) att+=3; - else if(target.needsToDiscard(1)) att++; - else if(target.countCards()<=3){ + }).ai = function (target) { + var att = -get.attitude(player, target); + if (att <= 0) return 0; + if (target.needsToDiscard()) att += 3; + else if (target.needsToDiscard(1)) att++; + else if (target.countCards() <= 3) { return 0; } - return att+target.countCards('h')+get.threaten(target); + return att + target.countCards("h") + get.threaten(target); }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mengye',target); - target.storage.mengye2=player; - target.storage.mengye4=target.ai.shown; - target.addSkill('mengye2'); - event.target=target; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mengye", target); + target.storage.mengye2 = player; + target.storage.mengye4 = target.ai.shown; + target.addSkill("mengye2"); + event.target = target; player.turnOver(); - } - else{ + } else { event.finish(); } - 'step 2' + "step 2"; game.delay(); - 'step 3' - var target=event.target; - if(player==game.me){ + "step 3"; + var target = event.target; + if (player == game.me) { game.swapPlayerAuto(target); - target.storage.mengye3=true; + target.storage.mengye3 = true; + } else { + target.addSkill("mad"); + target.unmarkSkill("mad"); } - else{ - target.addSkill('mad'); - target.unmarkSkill('mad'); - } - player.out('mengye'); + player.out("mengye"); target.insertPhase(); }, - ai:{ - threaten:2 - } + ai: { + threaten: 2, + }, }, - mengye2:{ - temp:true, - mark:'character', - vanish:true, - intro:{ - content:'由$控制本回合行动' + mengye2: { + temp: true, + mark: "character", + vanish: true, + intro: { + content: "由$控制本回合行动", }, - init(player){ - player.ai.modAttitudeFrom=function(from,to){ - return get.attitude(player.storage.mengye2,to); - } - player.ai.modAttitudeTo=function(from,to,att){ - if(from!=to) return 0; + init(player) { + player.ai.modAttitudeFrom = function (from, to) { + return get.attitude(player.storage.mengye2, to); + }; + player.ai.modAttitudeTo = function (from, to, att) { + if (from != to) return 0; return att; - } + }; }, - onremove(player){ + onremove(player) { delete player.ai.modAttitudeFrom; delete player.ai.modAttitudeTo; delete player.storage.mengye2; delete player.storage.mengye3; delete player.storage.mengye4; }, - trigger:{player:['phaseAfter','dieBegin']}, - forced:true, - popup:false, - content(){ - player.storage.mengye2.in('mengye'); - if(player==game.me&&player.storage.mengye3){ + trigger: { player: ["phaseAfter", "dieBegin"] }, + forced: true, + popup: false, + content() { + player.storage.mengye2.in("mengye"); + if (player == game.me && player.storage.mengye3) { game.swapPlayerAuto(player.storage.mengye2); } - if(typeof player.ai.shown=='number'){ - player.ai.shown=player.storage.mengye4; + if (typeof player.ai.shown == "number") { + player.ai.shown = player.storage.mengye4; } - player.removeSkill('mad'); - player.removeSkill('mengye2'); - } + player.removeSkill("mad"); + player.removeSkill("mengye2"); + }, }, - mengye3:{}, - lianzhan:{ - trigger:{source:'damageEnd'}, - forced:true, - content(){ - if(player.getStat().damage>trigger.num){ + mengye3: {}, + lianzhan: { + trigger: { source: "damageEnd" }, + forced: true, + content() { + if (player.getStat().damage > trigger.num) { player.gainMaxHp(); player.recover(); - } - else{ + } else { player.draw(2); } }, - ai:{ - damageBonus:true - } + ai: { + damageBonus: true, + }, }, - lianzhan2:{}, - kuixin:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return game.hasPlayer(function(current){ - if(current==player) return false; - var nh=current.countCards('h'); - return nh&&nh>=player.countCards('h'); + lianzhan2: {}, + kuixin: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return game.hasPlayer(function (current) { + if (current == player) return false; + var nh = current.countCards("h"); + return nh && nh >= player.countCards("h"); }); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('kuixin'),function(card,player,target){ - if(target==player) return false; - var nh=target.countCards('h'); - return nh&&nh>=player.countCards('h'); - }).ai=function(target){ - var att=get.attitude(player,target); - if(target.hasSkillTag('noe')){ - att/=3; + content() { + "step 0"; + player.chooseTarget(get.prompt("kuixin"), function (card, player, target) { + if (target == player) return false; + var nh = target.countCards("h"); + return nh && nh >= player.countCards("h"); + }).ai = function (target) { + var att = get.attitude(player, target); + if (target.hasSkillTag("noe")) { + att /= 3; } return -att; - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - var card=target.getCards('h').randomGet(); - if(card){ - player.logSkill('kuixin',target); - player.gain(card,target); - target.$giveAuto(card,player); + }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + var card = target.getCards("h").randomGet(); + if (card) { + player.logSkill("kuixin", target); + player.gain(card, target); + target.$giveAuto(card, player); } } - } + }, }, - fuhua:{ - enable:'phaseUse', - filterCard:{name:'du'}, - check(){return 1}, - filterTarget(card,player,target){ - return !target.hasSkill('moxie')&&!target.hasSkill('fuhua2'); + fuhua: { + enable: "phaseUse", + filterCard: { name: "du" }, + check() { + return 1; }, - filter(event,player){ - return player.countCards('h','du')>0; + filterTarget(card, player, target) { + return !target.hasSkill("moxie") && !target.hasSkill("fuhua2"); }, - discard:false, - prepare:'give', - content(){ - 'step 0' - target.gain(cards,player); - var choice=1; - if(get.attitude(target,player)>0||(target.hp<=1&&!target.hasSha())){ - choice=0; + filter(event, player) { + return player.countCards("h", "du") > 0; + }, + discard: false, + prepare: "give", + content() { + "step 0"; + target.gain(cards, player); + var choice = 1; + if (get.attitude(target, player) > 0 || (target.hp <= 1 && !target.hasSha())) { + choice = 0; } - target.chooseControl(function(){ - return choice; - }).set('choiceList',['获得技能魔血,每个出牌阶段开始时需交给'+get.translation(player)+'一张牌', - '视为'+get.translation(player)+'对你使用一张决斗,若你赢,本局不能再成为腐化目标']); - 'step 1' - if(result.index==0){ - target.storage.fuhua2=player; - target.addSkill('fuhua2'); - target.addSkill('moxie'); - } - else{ - player.useCard({name:'juedou'},target); + target + .chooseControl(function () { + return choice; + }) + .set("choiceList", [ + "获得技能魔血,每个出牌阶段开始时需交给" + get.translation(player) + "一张牌", + "视为" + + get.translation(player) + + "对你使用一张决斗,若你赢,本局不能再成为腐化目标", + ]); + "step 1"; + if (result.index == 0) { + target.storage.fuhua2 = player; + target.addSkill("fuhua2"); + target.addSkill("moxie"); + } else { + player.useCard({ name: "juedou" }, target); } }, - ai:{ - threaten:1.5, - order:8, - expos:0.2, - result:{ - player(player,target){ - if(player.countCards('h')<=2) return 0; - if(get.attitude(target,player)>0) return 1; - if(get.effect(target,{name:'juedou'},player,player)>0) return 1.5; + ai: { + threaten: 1.5, + order: 8, + expos: 0.2, + result: { + player(player, target) { + if (player.countCards("h") <= 2) return 0; + if (get.attitude(target, player) > 0) return 1; + if (get.effect(target, { name: "juedou" }, player, player) > 0) return 1.5; return 0; - } - } - } - }, - fuhua2:{ - trigger:{player:'phaseEnd'}, - forced:true, - priority:1, - filter(event,player){ - return player.storage.fuhua2.isIn()&&player.countCards('h')>0; - }, - mark:'character', - intro:{ - content(storage){ - return '每个结束阶段需交给'+get.translation(storage)+'一张手牌'; - } - }, - content(){ - 'step 0' - player.chooseCard('h',true,'交给'+get.translation(player.storage.fuhua2)+'一张手牌'); - 'step 1' - if(result.bool){ - player.storage.fuhua2.gain(result.cards,player); - player.$give(result.cards,player.storage.fuhua2); - player.line(player.storage.fuhua2,'green'); - } - }, - group:'fuhua2_remove', - onremove:true, - subSkill:{ - remove:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - filter(event,player){ - return event.player==player.storage.fuhua2; }, - content(){ - player.removeSkill('fuhua2'); - } - } - } - }, - fuhua3:{ - trigger:{player:'damageBefore'}, - forced:true, - popup:false, - filter(event,player){ - var evt=event.getParent(3); - return evt.name=='fuhua'&&evt.target==event.source; + }, }, - content(){ - trigger.getParent(3).target.storage.fuhua_failed=true; - } }, - moxie:{ - trigger:{player:'loseHpBegin'}, - forced:true, - filter:(event)=>event.type=='du', - content(){ + fuhua2: { + trigger: { player: "phaseEnd" }, + forced: true, + priority: 1, + filter(event, player) { + return player.storage.fuhua2.isIn() && player.countCards("h") > 0; + }, + mark: "character", + intro: { + content(storage) { + return "每个结束阶段需交给" + get.translation(storage) + "一张手牌"; + }, + }, + content() { + "step 0"; + player.chooseCard( + "h", + true, + "交给" + get.translation(player.storage.fuhua2) + "一张手牌" + ); + "step 1"; + if (result.bool) { + player.storage.fuhua2.gain(result.cards, player); + player.$give(result.cards, player.storage.fuhua2); + player.line(player.storage.fuhua2, "green"); + } + }, + group: "fuhua2_remove", + onremove: true, + subSkill: { + remove: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter(event, player) { + return event.player == player.storage.fuhua2; + }, + content() { + player.removeSkill("fuhua2"); + }, + }, + }, + }, + fuhua3: { + trigger: { player: "damageBefore" }, + forced: true, + popup: false, + filter(event, player) { + var evt = event.getParent(3); + return evt.name == "fuhua" && evt.target == event.source; + }, + content() { + trigger.getParent(3).target.storage.fuhua_failed = true; + }, + }, + moxie: { + trigger: { player: "loseHpBegin" }, + forced: true, + filter: (event) => event.type == "du", + content() { trigger.cancel(); player.draw(2); }, - ai:{ - threaten:1.2, - nodu:true, - usedu:true, + ai: { + threaten: 1.2, + nodu: true, + usedu: true, }, - group:'moxie_use', - subSkill:{ - use:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.countCards('h')>0; + group: "moxie_use", + subSkill: { + use: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.countCards("h") > 0; }, - content(){ - var hs=player.getCards('h'); - for(var i=0;iplayer.hp; + moxue_old: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + return game.hasPlayer(function (current) { + return current.hp > player.hp; }); }, - logTarget(event,player){ - return game.filterPlayer(function(current){ - return current.hp>player.hp; + logTarget(event, player) { + return game.filterPlayer(function (current) { + return current.hp > player.hp; }); }, - content(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current.hp>player.hp; + content() { + "step 0"; + event.targets = game.filterPlayer(function (current) { + return current.hp > player.hp; }); event.targets.sortBySeat(); - 'step 1' - if(event.targets.length){ - event.target=event.targets.shift(); - if(event.target.countCards('he',{color:'black'})){ - event.target.chooseCard('he','交给'+get.translation(player)+'一张黑色牌,或失去1点体力',{color:'black'}).ai=function(card){ - if(get.attitude(event.target,player)>0) return 10-get.value(card); - return 7-get.value(card); - } - } - else{ + "step 1"; + if (event.targets.length) { + event.target = event.targets.shift(); + if (event.target.countCards("he", { color: "black" })) { + event.target.chooseCard( + "he", + "交给" + get.translation(player) + "一张黑色牌,或失去1点体力", + { color: "black" } + ).ai = function (card) { + if (get.attitude(event.target, player) > 0) return 10 - get.value(card); + return 7 - get.value(card); + }; + } else { event.target.loseHp(); event.redo(); } - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.gain(result.cards,event.target); - if(get.position(result.cards[0])=='e'){ - event.target.$give(result.cards,player); + "step 2"; + if (result.bool) { + player.gain(result.cards, event.target); + if (get.position(result.cards[0]) == "e") { + event.target.$give(result.cards, player); + } else { + event.target.$give(result.cards.length, player); } - else{ - event.target.$give(result.cards.length,player); - } - } - else{ + } else { event.target.loseHp(); } event.goto(1); - } - }, - gfuhun:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return player.countCards('h')>0&&!player.isTurnedOver(); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('gfuhun'),function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).ai=function(target){ - return -get.attitude(player,target); - } - 'step 1' - if(result.bool){ - player.logSkill('gfuhun',result.targets); - event.target=result.targets[0]; + }, + gfuhun: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return player.countCards("h") > 0 && !player.isTurnedOver(); + }, + content() { + "step 0"; + player.chooseTarget(get.prompt("gfuhun"), function (card, player, target) { + return target != player && target.countCards("h") > 0; + }).ai = function (target) { + return -get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("gfuhun", result.targets); + event.target = result.targets[0]; player.chooseToCompare(event.target); - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - event.target.goMad({player:'phaseAfter'}); - if(!player.isTurnedOver()) player.turnOver(); + "step 2"; + if (result.bool) { + event.target.goMad({ player: "phaseAfter" }); + if (!player.isTurnedOver()) player.turnOver(); } }, - ai:{ - expose:0.2, - threaten:1.5 - } + ai: { + expose: 0.2, + threaten: 1.5, + }, }, - qianhou:{ - trigger:{player:'phaseBegin'}, - forced:true, - content(){ - 'step 0' - var list=[]; - for(var i=0;i0&&info.selectTarget[1]>=info.selectTarget[0]){ + qianhou: { + trigger: { player: "phaseBegin" }, + forced: true, + content() { + "step 0"; + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + if (lib.filter.filterCard({ name: lib.inpile[i] }, player)) { + var info = lib.card[lib.inpile[i]]; + if (info.type == "trick" && !info.multitarget && !info.notarget) { + if (Array.isArray(info.selectTarget)) { + if ( + info.selectTarget[0] > 0 && + info.selectTarget[1] >= info.selectTarget[0] + ) { list.push(lib.inpile[i]); } - } - else if(typeof info.selectTarget=='number'){ + } else if (typeof info.selectTarget == "number") { list.push(lib.inpile[i]); } } } } - while(list.length){ - var card={name:list.randomRemove()}; - var info=get.info(card); - var targets=game.filterPlayer(function(current){ - return lib.filter.filterTarget(card,player,current); + while (list.length) { + var card = { name: list.randomRemove() }; + var info = get.info(card); + var targets = game.filterPlayer(function (current) { + return lib.filter.filterTarget(card, player, current); }); - if(targets.length){ + if (targets.length) { targets.sort(lib.sort.seat); - if(info.selectTarget!=-1){ - var num=info.selectTarget; - if(Array.isArray(num)){ - if(targets.length0; + zhongji: { + trigger: { source: "damageBegin" }, + direct: true, + filter(event, player) { + return player.countCards("h", { color: "black" }) > 0; }, - content(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('zhongji',trigger.player),{color:'black'}); - next.logSkill=['zhongji',trigger.player]; - next.ai=function(card){ - if(get.attitude(player,trigger.player)<0){ - return 7-get.value(card); + content() { + "step 0"; + var next = player.chooseToDiscard(get.prompt("zhongji", trigger.player), { + color: "black", + }); + next.logSkill = ["zhongji", trigger.player]; + next.ai = function (card) { + if (get.attitude(player, trigger.player) < 0) { + return 7 - get.value(card); } return -1; - } - "step 1" - if(result.bool){ + }; + "step 1"; + if (result.bool) { trigger.num++; } }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - fuwen:{ - trigger:{player:'phaseDiscardEnd'}, - frequent:true, - filter(event,player){ - if(event.cards){ - for(var i=0;i0; + jinzhou: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return player.countCards("h", { suit: "spade" }) > 0; }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('jinzhou'),function(card,player,target){ - return target!=player&&!target.hasSkill('fengyin'); - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - var skills=target.getSkills(); - for(var i=0;i= 0) return 0; + var skills = target.getSkills(); + for (var i = 0; i < skills.length; i++) { + if (!get.is.locked(skills[i])) { + if (target.hasSkillTag("maixie")) return 2; return get.threaten(target); } } return 0; - } - 'step 1' - if(result.bool){ - player.logSkill('jinzhou',result.targets); - result.targets[0].addTempSkill('fengyin',{player:'phaseAfter'}); + }; + "step 1"; + if (result.bool) { + player.logSkill("jinzhou", result.targets); + result.targets[0].addTempSkill("fengyin", { player: "phaseAfter" }); } }, - ai:{ - expose:0.2, - threaten:1.4 - } + ai: { + expose: 0.2, + threaten: 1.4, + }, }, - midian:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h',{type:['trick','delay']})>0; + midian: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h", { type: ["trick", "delay"] }) > 0; }, - filterCard:{type:['trick','delay']}, - check(card){ - return 10-get.value(card); + filterCard: { type: ["trick", "delay"] }, + check(card) { + return 10 - get.value(card); }, - content(){ - var list=get.inpile('trick','trick'); - var list2=[]; - for(var i=0;i<3;i++){ + content() { + var list = get.inpile("trick", "trick"); + var list2 = []; + for (var i = 0; i < 3; i++) { list2.push(game.createCard(list.randomGet())); } - player.gain(list2,'draw'); + player.gain(list2, "draw"); + }, + ai: { + order: 9.8, + threaten: 1.8, + result: { + player: 1, + }, }, - ai:{ - order:9.8, - threaten:1.8, - result:{ - player:1 - } - } }, - xingluo:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter(event,player){ + xingluo: { + trigger: { player: "phaseBegin" }, + direct: true, + filter(event, player) { return !player.isMaxHandcard(); }, - content(){ - 'step 0' - var nh=player.countCards('h'); - var num=game.countPlayer(function(current){ - return current.countCards('h')>nh; + content() { + "step 0"; + var nh = player.countCards("h"); + var num = game.countPlayer(function (current) { + return current.countCards("h") > nh; }); - player.chooseTarget(get.prompt('xingluo'),[1,num],function(card,player,target){ - return target.countCards('h')>nh; - }).ai=function(target){ - return 0.5-get.attitude(player,target); - } - 'step 1' - if(result.bool){ - event.cards=[]; - event.list=result.targets.slice(0); + player.chooseTarget(get.prompt("xingluo"), [1, num], function (card, player, target) { + return target.countCards("h") > nh; + }).ai = function (target) { + return 0.5 - get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + event.cards = []; + event.list = result.targets.slice(0); event.list.sort(lib.sort.seat); - player.logSkill('xingluo',result.targets); - } - else{ + player.logSkill("xingluo", result.targets); + } else { event.finish(); } - 'step 2' - if(event.list.length){ - event.list.shift().chooseToDiscard('h',true); - } - else{ + "step 2"; + if (event.list.length) { + event.list.shift().chooseToDiscard("h", true); + } else { event.goto(4); } - 'step 3' - if(result.bool&&result.cards.length){ + "step 3"; + if (result.bool && result.cards.length) { event.cards.push(result.cards[0]); } event.goto(2); - 'step 4' - if(event.cards.length){ - player.chooseCardButton('选择一张加入手牌',event.cards).ai=function(button){ + "step 4"; + if (event.cards.length) { + player.chooseCardButton("选择一张加入手牌", event.cards).ai = function (button) { return get.value(button.link); }; - } - else{ + } else { event.finish(); } - 'step 5' - if(result.bool){ - player.gain(result.links,'gain2'); + "step 5"; + if (result.bool) { + player.gain(result.links, "gain2"); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - yuelu:{ - enable:'chooseToUse', - filter(event,player){ - return event.type=='dying'&&player.countCards('he',{color:'black'})>0; + yuelu: { + enable: "chooseToUse", + filter(event, player) { + return event.type == "dying" && player.countCards("he", { color: "black" }) > 0; }, // alter:true, - filterCard:{color:'black'}, - position:'he', - check(card){ - return 11-get.value(card); + filterCard: { color: "black" }, + position: "he", + check(card) { + return 11 - get.value(card); }, - filterTarget(card,player,target){ - return target==_status.event.dying; + filterTarget(card, player, target) { + return target == _status.event.dying; }, - selectTarget:-1, - content(){ + selectTarget: -1, + content() { target.recover(); - if(!get.is.altered('yuelu')) target.changeHujia(); + if (!get.is.altered("yuelu")) target.changeHujia(); }, - ai:{ - order:10, - skillTagFilter(player){ - if(player.countCards('he',{color:'black'})==0) return false; + ai: { + order: 10, + skillTagFilter(player) { + if (player.countCards("he", { color: "black" }) == 0) return false; }, - save:true, - result:{ - target:3 + save: true, + result: { + target: 3, }, - threaten:2.5 + threaten: 2.5, }, }, - yushou:{ - enable:'phaseUse', - filterCard:true, - position:'he', - check(card){ - var player=_status.event.player; - var num=0; - if(player.hasSkill('yushou_misha')) num+=1.5; - if(player.hasSkill('yushou_huofu')) num+=1.5; - if(player.hasSkill('yushou_leiouke')) num+=1.5; - return 5-num-get.value(card); + yushou: { + enable: "phaseUse", + filterCard: true, + position: "he", + check(card) { + var player = _status.event.player; + var num = 0; + if (player.hasSkill("yushou_misha")) num += 1.5; + if (player.hasSkill("yushou_huofu")) num += 1.5; + if (player.hasSkill("yushou_leiouke")) num += 1.5; + return 5 - num - get.value(card); }, - filter(event,player){ - if(player.hasSkill('yushou_misha')&&player.hasSkill('yushou_huofu')&&player.hasSkill('yushou_leiouke')) return false; + filter(event, player) { + if ( + player.hasSkill("yushou_misha") && + player.hasSkill("yushou_huofu") && + player.hasSkill("yushou_leiouke") + ) + return false; return true; }, - content(){ - if(!lib.character.stone_misha){ - lib.character.stone_misha=['male','shu',3,['lschaofeng'],['minskin','stone','mode:stone'],[3,3,'hunter']]; + content() { + if (!lib.character.stone_misha) { + lib.character.stone_misha = [ + "male", + "shu", + 3, + ["lschaofeng"], + ["minskin", "stone", "mode:stone"], + [3, 3, "hunter"], + ]; } - if(!lib.character.stone_huofu){ - lib.character.stone_huofu=['male','qun',2,['stone_chongfeng'],['minskin','stone','mode:stone'],[3,4,'hunter']]; + if (!lib.character.stone_huofu) { + lib.character.stone_huofu = [ + "male", + "qun", + 2, + ["stone_chongfeng"], + ["minskin", "stone", "mode:stone"], + [3, 4, "hunter"], + ]; } - if(!lib.character.stone_leiouke){ - lib.character.stone_leiouke=['male','shu',2,['hunter_zhanhuo'],['minskin','stone','mode:stone'],[3,1,'hunter']]; + if (!lib.character.stone_leiouke) { + lib.character.stone_leiouke = [ + "male", + "shu", + 2, + ["hunter_zhanhuo"], + ["minskin", "stone", "mode:stone"], + [3, 1, "hunter"], + ]; } - var list=['misha','leiouke','huofu']; - for(var i=0;i=1; }, - content(){ + }, + yushou_misha: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { + return event.num >= 1; + }, + content() { player.changeHujia(); }, - ai:{ - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return; + ai: { + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return; return 0.6; } - } - } - }, - }, - yushou_huofu:{ - enable:'phaseUse', - viewAs:{name:'juedou'}, - filterCard:{color:'black'}, - position:'he', - viewAsFilter(player){ - if(!player.countCards('he',{color:'black'})) return false; - }, - check(card){ - return 6-get.value(card); - }, - ai:{ - basic:{ - order:10 - } - } - }, - yushou_leiouke:{ - trigger:{source:'damageBegin'}, - forced:true, - usable:1, - content(){ - trigger.num++; - } - }, - qingzun:{ - // alter:true, - subSkill:{ - count:{ - trigger:{player:'useCard'}, - silent:true, - filter(event,player){ - return event.card.name.indexOf('hsqingyu_')==0; }, - content(){ + }, + }, + }, + yushou_huofu: { + enable: "phaseUse", + viewAs: { name: "juedou" }, + filterCard: { color: "black" }, + position: "he", + viewAsFilter(player) { + if (!player.countCards("he", { color: "black" })) return false; + }, + check(card) { + return 6 - get.value(card); + }, + ai: { + basic: { + order: 10, + }, + }, + }, + yushou_leiouke: { + trigger: { source: "damageBegin" }, + forced: true, + usable: 1, + content() { + trigger.num++; + }, + }, + qingzun: { + // alter:true, + subSkill: { + count: { + trigger: { player: "useCard" }, + silent: true, + filter(event, player) { + return event.card.name.indexOf("hsqingyu_") == 0; + }, + content() { player.storage.qingzun++; player.updateMarks(); - } - }, - draw1:{ - trigger:{player:'phaseBegin'}, - filter(event,player){ - if(get.is.altered('qingzun')) return player.storage.qingzun>=3; - return player.storage.qingzun>=2; }, - frequent:true, - content(){ - player.draw(); - } }, - draw2:{ - trigger:{player:'phaseEnd'}, - filter(event,player){ - if(get.is.altered('qingzun')) return player.storage.qingzun>=9; - return player.storage.qingzun>=6; + draw1: { + trigger: { player: "phaseBegin" }, + filter(event, player) { + if (get.is.altered("qingzun")) return player.storage.qingzun >= 3; + return player.storage.qingzun >= 2; }, - frequent:true, - content(){ + frequent: true, + content() { player.draw(); - } + }, + }, + draw2: { + trigger: { player: "phaseEnd" }, + filter(event, player) { + if (get.is.altered("qingzun")) return player.storage.qingzun >= 9; + return player.storage.qingzun >= 6; + }, + frequent: true, + content() { + player.draw(); + }, }, }, - mod:{ - maxHandcard(player,num){ - return num+player.storage.qingzun; - } + mod: { + maxHandcard(player, num) { + return num + player.storage.qingzun; + }, }, - init(player){ - player.storage.qingzun=0; + init(player) { + player.storage.qingzun = 0; }, - mark:true, - marktext:'玉', - intro:{ - content(storage,player){ - if(!storage) return '未使用过青玉牌'; - var str='手牌上限+'+storage; - var num1,num2; - if(get.is.altered('qingzun')){ - num1=3; - num2=9; + mark: true, + marktext: "玉", + intro: { + content(storage, player) { + if (!storage) return "未使用过青玉牌"; + var str = "手牌上限+" + storage; + var num1, num2; + if (get.is.altered("qingzun")) { + num1 = 3; + num2 = 9; + } else { + num1 = 2; + num2 = 6; } - else{ - num1=2; - num2=6; - } - if(storage>=num2){ - str+=';准备阶段和结束阶段,你可以摸一张牌' - } - else if(storage>=num1){ - str+=';准备阶段,你可以摸一张牌' + if (storage >= num2) { + str += ";准备阶段和结束阶段,你可以摸一张牌"; + } else if (storage >= num1) { + str += ";准备阶段,你可以摸一张牌"; } return str; - } + }, }, - group:['qingzun_count','qingzun_draw1','qingzun_draw2'], + group: ["qingzun_count", "qingzun_draw1", "qingzun_draw2"], }, - ayuling:{ - trigger:{player:'damageEnd'}, - frequent:true, - content(){ - var list=['feibiao','hufu','zhao','zhanfang','shandian']; - player.gain(game.createCard('hsqingyu_'+list.randomGet()),'draw'); + ayuling: { + trigger: { player: "damageEnd" }, + frequent: true, + content() { + var list = ["feibiao", "hufu", "zhao", "zhanfang", "shandian"]; + player.gain(game.createCard("hsqingyu_" + list.randomGet()), "draw"); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [1,get.tag(card,'damage')*2]; - if(target.hp==3) return [1,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [1, get.tag(card, "damage") * 2]; + if (target.hp == 3) return [1, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } + }, + }, + }, }, - aoshu:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard(card){ - return get.suit(card)=='spade'; + aoshu: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard(card) { + return get.suit(card) == "spade"; }, - viewAs:{name:'wuzhong'}, - viewAsFilter(player){ - if(!player.countCards('he',{suit:'spade'})) return false; + viewAs: { name: "wuzhong" }, + viewAsFilter(player) { + if (!player.countCards("he", { suit: "spade" })) return false; + }, + prompt: "将一张黑桃牌当作无中生有使用", + check(card) { + return 7 - get.value(card); + }, + ai: { + threaten: 1.4, + order: 9, }, - prompt:'将一张黑桃牌当作无中生有使用', - check(card){return 7-get.value(card)}, - ai:{ - threaten:1.4, - order:9, - } }, - bzhuiji:{ - trigger:{global:'dieAfter'}, - check(event,player){ - return get.attitude(player,event.source)<=0; + bzhuiji: { + trigger: { global: "dieAfter" }, + check(event, player) { + return get.attitude(player, event.source) <= 0; }, - filter(event,player){ - return event.source&&event.source.isAlive()&&event.source!=player; + filter(event, player) { + return event.source && event.source.isAlive() && event.source != player; }, - content(){ + content() { player.draw(2); - player.useCard({name:'juedou'},trigger.source); + player.useCard({ name: "juedou" }, trigger.source); + }, + ai: { + threaten: 1.5, + expose: 0.1, }, - ai:{ - threaten:1.5, - expose:0.1 - } }, - lianjin_old:{ - enable:'phaseUse', - usable:2, - filterCard:true, - check(card){ - return 7-get.value(card); + lianjin_old: { + enable: "phaseUse", + usable: 2, + filterCard: true, + check(card) { + return 7 - get.value(card); }, - content(){ - 'step 0' - var list=get.inpile('trick'); - list=list.randomGets(3); - for(var i=0;i=2) continue; - if(names.length>=3) continue; - var select=get.select(info.selectTarget); - if(select[0]==-1&&select[1]==-1){ + if (equip && names.length >= 2) continue; + if (names.length >= 3) continue; + var select = get.select(info.selectTarget); + if (select[0] == -1 && select[1] == -1) { names.push(inpile[i]); - if(info.modTarget) single=true; - } - else if(select[0]==1&&select[1]==1){ + if (info.modTarget) single = true; + } else if (select[0] == 1 && select[1] == 1) { names.push(inpile[i]); - single=true; + single = true; } } - if(equip){ + if (equip) { names.push(equips.randomGet()); } names.sort(lib.sort.name); - var name='hsyaoshui_'+names[0]+'_'+names[1]+'_'+names[2]; - if(!lib.card[name]){ - lib.card[name]=get.copy(lib.skill.lianjin.template); - lib.card[name].names=names; - lib.card[name].selectTarget=single?1:-1; - lib.translate[name]='药水'; - lib.translate[name+'_info']=get.translation(names[0])+'、'+ - get.translation(names[1])+'、'+get.translation(names[2]); + var name = "hsyaoshui_" + names[0] + "_" + names[1] + "_" + names[2]; + if (!lib.card[name]) { + lib.card[name] = get.copy(lib.skill.lianjin.template); + lib.card[name].names = names; + lib.card[name].selectTarget = single ? 1 : -1; + lib.translate[name] = "药水"; + lib.translate[name + "_info"] = + get.translation(names[0]) + + "、" + + get.translation(names[1]) + + "、" + + get.translation(names[2]); } - var fakecard=game.createCard(name,cards[0].suit,cards[0].number); - player.gain(fakecard,'gain2'); + var fakecard = game.createCard(name, cards[0].suit, cards[0].number); + player.gain(fakecard, "gain2"); // cards[0].style.transitionDuration='0.2s'; // ui.refresh(cards[0]); // cards[0].classList.add('opaque'); @@ -3489,3568 +3719,3747 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // cards[0].classList.remove('opaque'); // game.delay(0,200); }, - template:{ - type:'hsyaoshui', - enable:true, - fullimage:true, - image:'card/hsyaoshui', - vanish:true, - derivation:'hs_kazhakusi', - multitarget:true, - multiline:true, - filterTarget(card,player,target){ - var info=get.info(card); - var names=info.names; - for(var i=0;i=3) return -1; - var num=0; - for(var i=0;i0){ + ai: { + order: 9.1, + threaten: 1.5, + result: { + target(player, target, card) { + var info = get.info(card); + if (!info) return 0; + if (!Array.isArray(info.names)) return 0; + var names = info.names; + if (names.includes("xingjiegoutong") && target.countCards("h") >= 3) + return -1; + var num = 0; + for (var i = 0; i < names.length; i++) { + var info2 = lib.card[names[i]]; + if (get.select(info2.selectTarget)[0] == -1 && !info2.modTarget) continue; + var eff = get.effect(target, { name: names[i] }, player, target); + if (eff > 0) { num++; - } - else if(eff<0){ - num-=0.9; + } else if (eff < 0) { + num -= 0.9; } } return num; - } - } - } - }, - ai:{ - order:9, - result:{ - player:1 + }, + }, }, - threaten:1.4 }, - group:'lianjin_discard', - subSkill:{ - discard:{ - trigger:{player:'discardAfter'}, - forced:true, - filter(event){ - for(var i=0;i0; + player.gain(cards, "draw2", "log"); }, - content(){ - player.gain(game.createCard(trigger.target.getCards('h').randomGet()),'draw'); - } }, - miss:{ - trigger:{player:'shaMiss'}, - frequent:true, - usable:1, - filter(event){ - return event.target.hasCard(function(card){ - return !get.info(card).unique; - },'e'); - }, - content(){ - player.gain(game.createCard(trigger.target.getCards('e',function(card){ - return !get.info(card).unique; - }).randomGet()),'draw'); - } - } - } - }, - yingxi:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return !player.getStat('damage')&&player.countCards('he',{color:'black'})>0; }, - content(){ - 'step 0' + }, + shouji: { + group: ["shouji_begin", "shouji_miss"], + subSkill: { + begin: { + trigger: { player: "shaBegin" }, + frequent: true, + usable: 1, + filter(event) { + return event.target.countCards("h") > 0; + }, + content() { + player.gain(game.createCard(trigger.target.getCards("h").randomGet()), "draw"); + }, + }, + miss: { + trigger: { player: "shaMiss" }, + frequent: true, + usable: 1, + filter(event) { + return event.target.hasCard(function (card) { + return !get.info(card).unique; + }, "e"); + }, + content() { + player.gain( + game.createCard( + trigger.target + .getCards("e", function (card) { + return !get.info(card).unique; + }) + .randomGet() + ), + "draw" + ); + }, + }, + }, + }, + yingxi: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return !player.getStat("damage") && player.countCards("he", { color: "black" }) > 0; + }, + content() { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('yingxi'), - filterCard:{color:'black'}, - filterTarget(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); + prompt: get.prompt("yingxi"), + filterCard: { color: "black" }, + filterTarget(card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); }, - position:'he', - ai1(card){ - return 8-get.value(card); + position: "he", + ai1(card) { + return 8 - get.value(card); + }, + ai2(target) { + return get.effect(target, { name: "sha" }, player, player); }, - ai2(target){ - return get.effect(target,{name:'sha'},player,player); - } }); - 'step 1' - if(result.bool){ - player.useCard({name:'sha'},result.cards,result.targets,'yingxi'); + "step 1"; + if (result.bool) { + player.useCard({ name: "sha" }, result.cards, result.targets, "yingxi"); } }, - group:'yingxi2', + group: "yingxi2", }, - yingxi2:{ - trigger:{player:'shaBegin'}, - forced:true, - popup:false, - filter(event,player){ - return event.skill=='yingxi'&&event.target.isHealthy(); + yingxi2: { + trigger: { player: "shaBegin" }, + forced: true, + popup: false, + filter(event, player) { + return event.skill == "yingxi" && event.target.isHealthy(); + }, + content() { + trigger.directHit = true; }, - content(){ - trigger.directHit=true; - } }, - hsguimou:{ - trigger:{player:'damageEnd'}, - check(event,player){ - return get.attitude(player,event.source)<=0; + hsguimou: { + trigger: { player: "damageEnd" }, + check(event, player) { + return get.attitude(player, event.source) <= 0; }, - filter(event,player){ - return event.source&&event.source.isAlive()&&event.source!=player&&event.source.countCards('h')>0; + filter(event, player) { + return ( + event.source && + event.source.isAlive() && + event.source != player && + event.source.countCards("h") > 0 + ); }, - logTarget:'source', - content(){ - var card=trigger.source.getCards('h').randomGet(); - if(card){ - player.gain(card,trigger.source); - if(get.color(card)=='black'){ - trigger.source.$give(card,player); + logTarget: "source", + content() { + var card = trigger.source.getCards("h").randomGet(); + if (card) { + player.gain(card, trigger.source); + if (get.color(card) == "black") { + trigger.source.$give(card, player); event.redo(); - } - else{ - trigger.source.$giveAuto(card,player); + } else { + trigger.source.$giveAuto(card, player); } game.delay(0.5); } }, - ai:{ - maixie:true, - maixie_hp:true, - maixie_defend:true, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return false; - if(get.tag(card,'damage')&&player.countCards('h')>1) return [1,0,0,-1]; - } - } - } + ai: { + maixie: true, + maixie_hp: true, + maixie_defend: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return false; + if (get.tag(card, "damage") && player.countCards("h") > 1) return [1, 0, 0, -1]; + }, + }, + }, }, - peiyu:{ - trigger:{player:['phaseBegin']}, - direct:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('peiyu'),function(card,player,target){ - for(var i=1;i<=8;i++){ - if(target.hasSkill('tuteng'+i)) return false; + peiyu: { + trigger: { player: ["phaseBegin"] }, + direct: true, + content() { + "step 0"; + player.chooseTarget(get.prompt("peiyu"), function (card, player, target) { + for (var i = 1; i <= 8; i++) { + if (target.hasSkill("tuteng" + i)) return false; } return true; - }).ai=function(target){ - if(player==target&&get.attitude(player,target)>0&&event.parent.triggername=='phaseBegin'){ - return get.attitude(player,target)+10; + }).ai = function (target) { + if ( + player == target && + get.attitude(player, target) > 0 && + event.parent.triggername == "phaseBegin" + ) { + return get.attitude(player, target) + 10; } - return get.attitude(player,target); + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("peiyu", result.targets); + var rand = [ + "tuteng1", + "tuteng2", + "tuteng3", + "tuteng4", + "tuteng5", + "tuteng6", + "tuteng7", + "tuteng8", + ]; + result.targets[0].addAdditionalSkill("peiyu", ["peiyu2", rand.randomGet()]); } - 'step 1' - if(result.bool){ - player.logSkill('peiyu',result.targets); - var rand=['tuteng1','tuteng2','tuteng3','tuteng4', - 'tuteng5','tuteng6','tuteng7','tuteng8']; - result.targets[0].addAdditionalSkill('peiyu',['peiyu2',rand.randomGet()]); - } - } - }, - peiyu2:{ - trigger:{player:'damageAfter'}, - silent:true, - content(){ - player.removeAdditionalSkill('peiyu'); - } - }, - peiyu_old:{ - enable:'phaseUse', - filterCard:true, - position:'he', - filterTarget:true, - check(card){ - return 6-get.value(card); }, - content(){ - 'step 0' - var rand=['tuteng1','tuteng2','tuteng3','tuteng4', - 'tuteng5','tuteng6','tuteng7','tuteng8']; - var rand2=[]; - for(var i=0;i1){ - rand.remove('tuteng1'); + target.removeSkill(rand2.randomGet()); + } else { + if (rand2.includes("tuteng1")) { + gain = rand.randomGet(); + target.removeSkill("tuteng1"); + } else { + if (rand.length > 1) { + rand.remove("tuteng1"); } - gain=rand.randomGet(); - target.removeSkill(rand2.randomGet()) + gain = rand.randomGet(); + target.removeSkill(rand2.randomGet()); } } target.addSkill(gain); - target.storage.peiyu[gain]=player; + target.storage.peiyu[gain] = player; game.delay(); event.finish(); } - } - else{ - var gain=rand.randomGet(); + } else { + var gain = rand.randomGet(); target.addSkill(gain); - target.storage.peiyu[gain]=player; + target.storage.peiyu[gain] = player; game.delay(); event.finish(); } - 'step 1' - var skill1=result.buttons[0].name; - var skill2=result.buttons[1].name; - if(target.hasSkill(skill1)){ + "step 1"; + var skill1 = result.buttons[0].name; + var skill2 = result.buttons[1].name; + if (target.hasSkill(skill1)) { target.removeSkill(skill1); target.addSkill(skill2); - target.storage.peiyu[skill2]=player; - } - else{ + target.storage.peiyu[skill2] = player; + } else { target.removeSkill(skill2); target.addSkill(skill1); - target.storage.peiyu[skill1]=player; + target.storage.peiyu[skill1] = player; } }, - ai:{ - expose:0.2, - order:5, - result:{ - target(player,target){ - for(var i=1;i<=8;i++){ - if(target.hasSkill('tuteng'+i)) return 0; + ai: { + expose: 0.2, + order: 5, + result: { + target(player, target) { + for (var i = 1; i <= 8; i++) { + if (target.hasSkill("tuteng" + i)) return 0; } return 1; - } - } + }, + }, }, - group:'peiyu_old2' + group: "peiyu_old2", }, - peiyu_old2:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content(){ - game.countPlayer(function(current){ - for(var j in current.storage.peiyu){ - if(current.storage.peiyu[j]==player){ + peiyu_old2: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + content() { + game.countPlayer(function (current) { + for (var j in current.storage.peiyu) { + if (current.storage.peiyu[j] == player) { current.removeSkill(j); } } }); - } - }, - wzhanyi:{ - trigger:{player:'phaseUseBefore'}, - check(event,player){ - return player.countCards('h')+2<=player.hp; }, - content(){ - 'step 0' - event.cards=get.cards(3); + }, + wzhanyi: { + trigger: { player: "phaseUseBefore" }, + check(event, player) { + return player.countCards("h") + 2 <= player.hp; + }, + content() { + "step 0"; + event.cards = get.cards(3); trigger.cancel(); player.$draw(event.cards.slice(0)); - for(var i=0;i=3; + yuansu: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.maxHp - player.hp >= 3; }, - filterTarget(card,player,target){ - return player.canUse('yuansuhuimie',target); + filterTarget(card, player, target) { + return player.canUse("yuansuhuimie", target); }, - selectTarget:-1, - multitarget:true, - multiline:true, - line:'thunder', - content(){ - player.maxHp=player.hp; + selectTarget: -1, + multitarget: true, + multiline: true, + line: "thunder", + content() { + player.maxHp = player.hp; player.update(); targets.sort(lib.sort.seat); - player.useCard({name:'yuansuhuimie'},targets).animate=false; - } + player.useCard({ name: "yuansuhuimie" }, targets).animate = false; + }, }, - chouhuo:{ - unique:true, - trigger:{player:'phaseBegin'}, - forced:true, - skillAnimation:true, - animationColor:'fire', - filter(event,player){ - if(player.storage.nuyan&&player.storage.nuyan.length){ - var num=0; - for(var i=0;i0){ - if(players[i].hp<2){ + check(button) { + var player = _status.event.player; + var recover = 0, + lose = 1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].hp < players[i].maxHp) { + if (get.attitude(player, players[i]) > 0) { + if (players[i].hp < 2) { lose--; - recover+=0.5; + recover += 0.5; } lose--; recover++; - } - else if(get.attitude(player,players[i])<0){ - if(players[i].hp<2){ + } else if (get.attitude(player, players[i]) < 0) { + if (players[i].hp < 2) { lose++; - recover-=0.5; + recover -= 0.5; } lose++; recover--; } - } - else{ - if(get.attitude(player,players[i])>0){ + } else { + if (get.attitude(player, players[i]) > 0) { lose--; - } - else if(get.attitude(player,players[i])<0){ + } else if (get.attitude(player, players[i]) < 0) { lose++; } } } - if(button.link[2]=='nanman'||button.link[2]=='nanman'||button.link[2]=='yuansuhuimie'|| - button.link[2]=='chiyuxi'||button.link[2]=='jingleishan'){ - if(lose>recover&&lose>0){ + if ( + button.link[2] == "nanman" || + button.link[2] == "nanman" || + button.link[2] == "yuansuhuimie" || + button.link[2] == "chiyuxi" || + button.link[2] == "jingleishan" + ) { + if (lose > recover && lose > 0) { return 2; - } - else{ + } else { return 0; } } return 1; }, - backup(links,player){ + backup(links, player) { return { - filterCard(){return false}, - selectCard:-1, - popname:true, - viewAs:{name:links[0][2]}, - onuse(result,player){ - player.loseHp(); - } - } - }, - prompt(links,player){ - return '失去1点体力,视为使用一张'+get.translation(links[0][2]); - } - }, - ai:{ - order:6, - result:{ - player(player){ - if(player.hp>1) return 1; - return 0; - } - }, - } - }, - nuyan:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('he',{color:'red'})>0 - }, - init(player){ - player.storage.nuyan=[]; - }, - chooseButton:{ - dialog(event,player){ - var list=[]; - for(var i=0;i0){ - if(players[i].hp<2){ - lose--; - recover+=0.5; - } - lose--; - recover++; - } - else if(get.attitude(player,players[i])<0){ - if(players[i].hp<2){ - lose++; - recover-=0.5; - } - lose++; - recover--; - } - } - else{ - if(get.attitude(player,players[i])>0){ - lose--; - } - else if(get.attitude(player,players[i])<0){ - lose++; - } - } - } - if(button.link[2]=='nanman'||button.link[2]=='nanman'||button.link[2]=='yuansuhuimie'|| - button.link[2]=='chiyuxi'||button.link[2]=='jingleishan'){ - if(lose>recover&&lose>0){ - return 2; - } - else{ - return 0; - } - } - return 1; - }, - backup(links,player){ - return { - filterCard:{color:'red'}, - selectCard:1, - position:'he', - popname:true, - viewAs:{name:links[0][2]}, - ai1(card){ - return 6-get.value(card); + filterCard() { + return false; }, - onuse(result,player){ - player.storage.nuyan.add(result.card.name); + selectCard: -1, + popname: true, + viewAs: { name: links[0][2] }, + onuse(result, player) { + player.loseHp(); + }, + }; + }, + prompt(links, player) { + return "失去1点体力,视为使用一张" + get.translation(links[0][2]); + }, + }, + ai: { + order: 6, + result: { + player(player) { + if (player.hp > 1) return 1; + return 0; + }, + }, + }, + }, + nuyan: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("he", { color: "red" }) > 0; + }, + init(player) { + player.storage.nuyan = []; + }, + chooseButton: { + dialog(event, player) { + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + if (get.tag({ name: lib.inpile[i] }, "damage")) { + list.push([get.type(lib.inpile[i]), "", lib.inpile[i]]); } } + return ui.create.dialog([list, "vcard"]); }, - prompt(links,player){ - return '将一张红色牌当作'+get.translation(links[0][2])+'使用'; - } - }, - ai:{ - order:6, - result:{ - player:1 + filter(button, player) { + if (player.storage.nuyan.includes(button.link[2])) return false; + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); }, - } + check(button) { + var player = _status.event.player; + var recover = 0, + lose = 1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].hp < players[i].maxHp) { + if (get.attitude(player, players[i]) > 0) { + if (players[i].hp < 2) { + lose--; + recover += 0.5; + } + lose--; + recover++; + } else if (get.attitude(player, players[i]) < 0) { + if (players[i].hp < 2) { + lose++; + recover -= 0.5; + } + lose++; + recover--; + } + } else { + if (get.attitude(player, players[i]) > 0) { + lose--; + } else if (get.attitude(player, players[i]) < 0) { + lose++; + } + } + } + if ( + button.link[2] == "nanman" || + button.link[2] == "nanman" || + button.link[2] == "yuansuhuimie" || + button.link[2] == "chiyuxi" || + button.link[2] == "jingleishan" + ) { + if (lose > recover && lose > 0) { + return 2; + } else { + return 0; + } + } + return 1; + }, + backup(links, player) { + return { + filterCard: { color: "red" }, + selectCard: 1, + position: "he", + popname: true, + viewAs: { name: links[0][2] }, + ai1(card) { + return 6 - get.value(card); + }, + onuse(result, player) { + player.storage.nuyan.add(result.card.name); + }, + }; + }, + prompt(links, player) { + return "将一张红色牌当作" + get.translation(links[0][2]) + "使用"; + }, + }, + ai: { + order: 6, + result: { + player: 1, + }, + }, }, - duxin:{ - trigger:{player:['phaseBegin','phaseEnd']}, - frequent:true, - filter(event,player){ - return !player.countCards('h',{type:'hsdusu'}); + duxin: { + trigger: { player: ["phaseBegin", "phaseEnd"] }, + frequent: true, + filter(event, player) { + return !player.countCards("h", { type: "hsdusu" }); }, - content(){ - var list=['hsdusu_xueji','hsdusu_huangxuecao','hsdusu_kuyecao','hsdusu_shinancao','hsdusu_huoyanhua']; - if(typeof lib.cardType.hslingjian!='number'){ - list.remove('hsdusu_kuyecao'); + content() { + var list = [ + "hsdusu_xueji", + "hsdusu_huangxuecao", + "hsdusu_kuyecao", + "hsdusu_shinancao", + "hsdusu_huoyanhua", + ]; + if (typeof lib.cardType.hslingjian != "number") { + list.remove("hsdusu_kuyecao"); } - var name=list.randomGet(); - if(name=='hsdusu_huoyanhua'){ - player.gain(game.createCard({name:name,nature:'fire'}),'draw'); - } - else{ - player.gain(game.createCard(name),'draw'); + var name = list.randomGet(); + if (name == "hsdusu_huoyanhua") { + player.gain(game.createCard({ name: name, nature: "fire" }), "draw"); + } else { + player.gain(game.createCard(name), "draw"); } }, - ai:{ - threaten:1.6 - } + ai: { + threaten: 1.6, + }, }, - oldduxin:{ - trigger:{player:['phaseBegin','phaseEnd']}, - frequent:true, - content(){ - var list=['hsdusu_xueji','hsdusu_huangxuecao','hsdusu_kuyecao','hsdusu_shinancao','hsdusu_huoyanhua']; - if(typeof lib.cardType.hslingjian!='number'){ - list.remove('hsdusu_kuyecao'); + oldduxin: { + trigger: { player: ["phaseBegin", "phaseEnd"] }, + frequent: true, + content() { + var list = [ + "hsdusu_xueji", + "hsdusu_huangxuecao", + "hsdusu_kuyecao", + "hsdusu_shinancao", + "hsdusu_huoyanhua", + ]; + if (typeof lib.cardType.hslingjian != "number") { + list.remove("hsdusu_kuyecao"); } - var name=list.randomGet(); - if(name=='hsdusu_huoyanhua'){ - player.gain(game.createCard({name:name,nature:'fire'}),'draw'); - } - else{ - player.gain(game.createCard(name),'draw'); + var name = list.randomGet(); + if (name == "hsdusu_huoyanhua") { + player.gain(game.createCard({ name: name, nature: "fire" }), "draw"); + } else { + player.gain(game.createCard(name), "draw"); } }, - ai:{ - threaten:1.6 - } + ai: { + threaten: 1.6, + }, }, - hsdusu_shinancao:{ - mark:true, - marktext:'楠', - nopop:true, - intro:{ - content:'下一次造成的伤害+1' + hsdusu_shinancao: { + mark: true, + marktext: "楠", + nopop: true, + intro: { + content: "下一次造成的伤害+1", }, - logv:false, - trigger:{source:'damageBegin'}, - forced:true, - content(){ + logv: false, + trigger: { source: "damageBegin" }, + forced: true, + content() { trigger.num++; - player.removeSkill('hsdusu_shinancao'); - } + player.removeSkill("hsdusu_shinancao"); + }, }, - kuangluan_old:{ - group:['kuangluan_count1','kuangluan_count2','kuangluan_use'], - subSkill:{ - count1:{ - trigger:{player:'useCard'}, - silent:true, - filter(event,player){ - return _status.currentPhase==player&&get.type(event.card)=='trick'; + kuangluan_old: { + group: ["kuangluan_count1", "kuangluan_count2", "kuangluan_use"], + subSkill: { + count1: { + trigger: { player: "useCard" }, + silent: true, + filter(event, player) { + return _status.currentPhase == player && get.type(event.card) == "trick"; }, - content(){ + content() { player.storage.kuangluan++; - } - }, - count2:{ - trigger:{player:'phaseBegin'}, - silent:true, - content(){ - player.storage.kuangluan=0; - } - }, - use:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - filter(event,player){ - return player.storage.kuangluan>0; }, - content(){ - var list=[]; - for(var i=0;i0&&info.selectTarget[1]>=info.selectTarget[0]){ + }, + count2: { + trigger: { player: "phaseBegin" }, + silent: true, + content() { + player.storage.kuangluan = 0; + }, + }, + use: { + trigger: { player: "phaseUseEnd" }, + forced: true, + filter(event, player) { + return player.storage.kuangluan > 0; + }, + content() { + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + if (lib.filter.filterCard({ name: lib.inpile[i] }, player)) { + var info = lib.card[lib.inpile[i]]; + if (info.type == "trick" && !info.multitarget && !info.notarget) { + if (Array.isArray(info.selectTarget)) { + if ( + info.selectTarget[0] > 0 && + info.selectTarget[1] >= info.selectTarget[0] + ) { list.push(lib.inpile[i]); } - } - else if(typeof info.selectTarget=='number'){ + } else if (typeof info.selectTarget == "number") { list.push(lib.inpile[i]); } } } } - var n=player.storage.kuangluan; + var n = player.storage.kuangluan; delete player.storage.kuangluan; - while(list.length){ - var card={name:list.randomRemove()}; - var info=get.info(card); - var targets=game.filterPlayer(function(current){ - return lib.filter.filterTarget(card,player,current); + while (list.length) { + var card = { name: list.randomRemove() }; + var info = get.info(card); + var targets = game.filterPlayer(function (current) { + return lib.filter.filterTarget(card, player, current); }); - if(targets.length){ + if (targets.length) { targets.sort(lib.sort.seat); - if(info.selectTarget==-1){ - player.useCard(card,targets); - } - else{ - var num=info.selectTarget; - if(Array.isArray(num)){ - if(targets.length=2; + kuangluan2: { + trigger: { player: "phaseBegin" }, + priority: 10, + forced: true, + filter(event, player) { + return player.storage.kuangluan && player.storage.kuangluan.length >= 2; }, - content(){ + content() { player.recover(player.maxHp); - player.goMad('phaseAfter'); - } - }, - kuangluan3:{ - trigger:{player:'phaseBegin'}, - silent:true, - content(){ - player.storage.kuangluan=[]; - player.unmarkSkill('kuangluan'); - } - }, - xiubu:{ - trigger:{player:'equipEnd'}, - frequent:true, - filter(event){ - return lib.inpile.includes(event.card.name)&&get.subtype(event.card)=='equip1'&&typeof lib.cardType.hslingjian=='number'; + player.goMad("phaseAfter"); }, - content(){ - var num=1; - var info=get.info(trigger.card); - if(info&&info.distance&&typeof info.distance.attackFrom=='number'){ - num=1-info.distance.attackFrom; + }, + kuangluan3: { + trigger: { player: "phaseBegin" }, + silent: true, + content() { + player.storage.kuangluan = []; + player.unmarkSkill("kuangluan"); + }, + }, + xiubu: { + trigger: { player: "equipEnd" }, + frequent: true, + filter(event) { + return ( + lib.inpile.includes(event.card.name) && + get.subtype(event.card) == "equip1" && + typeof lib.cardType.hslingjian == "number" + ); + }, + content() { + var num = 1; + var info = get.info(trigger.card); + if (info && info.distance && typeof info.distance.attackFrom == "number") { + num = 1 - info.distance.attackFrom; } - if(num<1){ - num=1; + if (num < 1) { + num = 1; } - var list=get.typeCard('hslingjian'); - if(!list.length){ + var list = get.typeCard("hslingjian"); + if (!list.length) { return; } - var cards=[]; - while(num--){ + var cards = []; + while (num--) { cards.push(game.createCard(list.randomGet())); } - player.gain(cards,'gain2'); + player.gain(cards, "gain2"); }, - threaten:1.3 + threaten: 1.3, }, - zengli:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!=player&&!target.isMin(); + zengli: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target != player && !target.isMin(); }, - delay:false, - content(){ - 'step 0' - var list=[]; - for(var i=0;i1){ - return 6-get.value(card); - } - return 0; - }).set('logSkill',['xianji',event.target]); - } - else{ + if (event.target) { + player + .chooseToDiscard( + [1, 2], + "献祭:是否弃置1~2张手牌并令" + get.translation(event.target) + "摸等量的牌?" + ) + .set("ai", function (card) { + if ( + get.attitude(_status.event.player, _status.event.getParent().target) > 1 + ) { + return 6 - get.value(card); + } + return 0; + }) + .set("logSkill", ["xianji", event.target]); + } else { event.finish(); } - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { event.target.draw(result.cards.length); - player.storage.xianji3=event.target; - player.addSkill('xianji3'); + player.storage.xianji3 = event.target; + player.addSkill("xianji3"); player.addExpose(0.2); } - } + }, }, - xianji3:{ - mark:'character', - intro:{ - content:'每当$对你使用一张牌,你摸一张牌' + xianji3: { + mark: "character", + intro: { + content: "每当$对你使用一张牌,你摸一张牌", }, - trigger:{target:'useCardToBegin'}, - filter(event,player){ - return event.player==player.storage.xianji3; + trigger: { target: "useCardToBegin" }, + filter(event, player) { + return event.player == player.storage.xianji3; }, - forced:true, - content(){ + forced: true, + content() { player.draw(); }, }, - tanmi:{ - trigger:{global:'phaseEnd'}, - filter(event,player){ - return player.countCards('h')==0&&event.player!=player; + tanmi: { + trigger: { global: "phaseEnd" }, + filter(event, player) { + return player.countCards("h") == 0 && event.player != player; }, - frequent:true, - content(){ - 'step 0' + frequent: true, + content() { + "step 0"; player.draw(2); - 'step 1' + "step 1"; player.chooseToUse(); - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.chooseToUse(); } }, - ai:{ - noh:true, - skillTagFilter(player,tag){ - if(tag=='noh'){ - if(player.countCards('h')!=1) return false; + ai: { + noh: true, + skillTagFilter(player, tag) { + if (tag == "noh") { + if (player.countCards("h") != 1) return false; } - } - } + }, + }, }, - xueren:{ - trigger:{source:'damageEnd'}, - filter(event){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.isAlive(); + xueren: { + trigger: { source: "damageEnd" }, + filter(event) { + if (event._notrigger.includes(event.player)) return false; + return event.card && event.card.name == "sha" && event.player.isAlive(); }, - check(event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(player.hp>2) return true; - if(player.hp<2) return false; - return player.hp>=event.player.hp; + check(event, player) { + if (get.attitude(player, event.player) >= 0) return false; + if (player.hp > 2) return true; + if (player.hp < 2) return false; + return player.hp >= event.player.hp; }, - content(){ - 'step 0' + content() { + "step 0"; trigger.player.loseHp(); - 'step 1' + "step 1"; player.loseHp(); - 'step 2' + "step 2"; player.draw(2); - } + }, }, - maoxian:{ - enable:'phaseUse', - usable:2, - direct:true, - delay:false, - unique:true, - content(){ - 'step 0' - var list=get.gainableSkills(); - list.remove('maoxian'); - list=list.randomGets(3); - event.skillai=function(){ - return get.max(list,get.skillRank,'item'); + maoxian: { + enable: "phaseUse", + usable: 2, + direct: true, + delay: false, + unique: true, + content() { + "step 0"; + var list = get.gainableSkills(); + list.remove("maoxian"); + list = list.randomGets(3); + event.skillai = function () { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - var dialog=ui.create.dialog('forcebutton'); - dialog.add('选择获得一项技能'); - var clickItem=function(){ - _status.event._result=this.link; + if (event.isMine()) { + var dialog = ui.create.dialog("forcebutton"); + dialog.add("选择获得一项技能"); + var clickItem = function () { + _status.event._result = this.link; dialog.close(); game.resume(); }; - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.switchToAuto=function(){ - event._result=event.skillai(); + dialog.add(ui.create.div(".placeholder")); + event.switchToAuto = function () { + event._result = event.skillai(); dialog.close(); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai(); } - else{ - event._result=event.skillai(); - } - 'step 1' - _status.imchoosing=false; - var link=result; - player.addAdditionalSkill('maoxian',link); + "step 1"; + _status.imchoosing = false; + var link = result; + player.addAdditionalSkill("maoxian", link); player.popup(link); - game.log(player,'获得了技能','【'+get.translation(link)+'】'); + game.log(player, "获得了技能", "【" + get.translation(link) + "】"); player.checkMarks(); - player.markSkill('maoxian'); + player.markSkill("maoxian"); game.delay(); }, - intro:{ - content(storage,player){ - return '当前技能:'+get.translation(player.additionalSkills.maoxian); - } + intro: { + content(storage, player) { + return "当前技能:" + get.translation(player.additionalSkills.maoxian); + }, }, - ai:{ - order:11, - result:{ - player(player){ - if(player.getStat().skill.maoxian) return 0; + ai: { + order: 11, + result: { + player(player) { + if (player.getStat().skill.maoxian) return 0; return 1; - } - } - } + }, + }, + }, }, - maoxian_old:{ - enable:'phaseUse', - usable:2, - direct:true, - delay:false, - unique:true, - getSkills(player,current){ - var names=[]; - var list=[]; - var map={}; - for(var i=0;i=3; + selectCard: 3, + filter(event, player) { + return player.countCards("he") >= 3; }, - content(){ - 'step 0' - event.cards=get.cards(3); - if(!event.isMine()) player.showCards(event.cards); - 'step 1' - player.chooseCardButton('获得任意张类别不同的牌',[1,3],event.cards).filterButton=function(button){ - var type=get.type(button.link,'trick'); - for(var i=0;iget.value(cards[i]); + selectCard: [1, Infinity], + content() { + var cards2 = []; + for (var i = 0; i < cards.length; i++) { + var type = get.type(cards[i], "trick"); + var list = game.findCards(function (name) { + if (cards[i].name == name) return; + if (get.type({ name: name }, "trick") == type) { + return get.value({ name: name }) > get.value(cards[i]); } }); - if(!list.length){ - list=game.findCards(function(name){ - if(cards[i].name==name) return; - if(get.type({name:name},'trick')==type){ - return get.value({name:name})==get.value(cards[i]); + if (!list.length) { + list = game.findCards(function (name) { + if (cards[i].name == name) return; + if (get.type({ name: name }, "trick") == type) { + return get.value({ name: name }) == get.value(cards[i]); } }); } - if(!list.length){ - list=[cards[i].name]; + if (!list.length) { + list = [cards[i].name]; } cards2.push(game.createCard(list.randomGet())); } - player.gain(cards2,'log'); + player.gain(cards2, "log"); player.$draw(cards2); }, - ai:{ - order:8, - result:{ - player:1 - } - } - }, - zhuizong:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - selectCard:[1,Infinity], - check(card){ - if(ui.selected.cards.length) return 0; - return 6-get.value(card) + ai: { + order: 8, + result: { + player: 1, + }, }, - content(){ - 'step 0' - event.cards=get.cards(4*cards.length); - player.chooseCardButton('获得其中的一张牌',true,event.cards,true); - 'step 1' - player.gain(result.links,'draw'); + }, + zhuizong: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + selectCard: [1, Infinity], + check(card) { + if (ui.selected.cards.length) return 0; + return 6 - get.value(card); + }, + content() { + "step 0"; + event.cards = get.cards(4 * cards.length); + player.chooseCardButton("获得其中的一张牌", true, event.cards, true); + "step 1"; + player.gain(result.links, "draw"); event.cards.remove(result.links[0]); - for(var i=0;i0; + yufa3: { + trigger: { global: "phaseBegin" }, + silent: true, + content() { + player.storage.yufa = null; }, - filterTarget(card,player,target){ - if(get.color(card)=='red'){ - return player.canUse('chiyuxi',target); - } - else{ - return player.canUse('jingleishan',target); + }, + bingyan: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + if (!lib.card.chiyuxi || !lib.card.jingleishan) return false; + return player.countCards("he") > 0; + }, + filterTarget(card, player, target) { + if (get.color(card) == "red") { + return player.canUse("chiyuxi", target); + } else { + return player.canUse("jingleishan", target); } }, - selectTarget:-1, - discard:false, - delay:false, - line:false, - filterCard:true, - position:'he', - log:'notarget', - check(card){ - return 6-get.value(card); + selectTarget: -1, + discard: false, + delay: false, + line: false, + filterCard: true, + position: "he", + log: "notarget", + check(card) { + return 6 - get.value(card); }, - multitarget:true, - content(){ - if(get.color(cards[0])=='black'){ - player.useCard({name:'jingleishan'},cards,targets); - } - else{ - player.useCard({name:'chiyuxi'},cards,targets); + multitarget: true, + content() { + if (get.color(cards[0]) == "black") { + player.useCard({ name: "jingleishan" }, cards, targets); + } else { + player.useCard({ name: "chiyuxi" }, cards, targets); } }, - ai:{ - order:9.1, - result:{ - target(player,target){ - var card=ui.selected.cards[0]; - if(card&&get.color(card)=='black'){ - return get.effect(target,{name:'jingleishan'},player,target); + ai: { + order: 9.1, + result: { + target(player, target) { + var card = ui.selected.cards[0]; + if (card && get.color(card) == "black") { + return get.effect(target, { name: "jingleishan" }, player, target); } - return get.effect(target,{name:'chiyuxi'},player,target); - } - } - } + return get.effect(target, { name: "chiyuxi" }, player, target); + }, + }, + }, }, - shifa:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - content(){ - 'step 0' - var list=[]; - var target=player.getEnemies().randomGet(); - for(var i=0;i1&&event.target.countCards('he')>0; + yuanzheng: { + trigger: { player: "useCardToBegin" }, + direct: true, + filter(event, player) { + return ( + event.target && + event.target != player && + get.distance(player, event.target) > 1 && + event.target.countCards("he") > 0 + ); + }, + content() { + player.discardPlayerCard( + trigger.target, + get.prompt("yuanzheng", trigger.target), + "hej" + ).logSkill = ["yuanzheng", trigger.target]; }, - content(){ - player.discardPlayerCard(trigger.target,get.prompt('yuanzheng',trigger.target),'hej').logSkill=['yuanzheng',trigger.target]; - } }, - yuanzheng_old:{ - trigger:{player:'useCardToBegin'}, - direct:true, - filter(event,player){ - if(event.getParent(2).name=='yuanzheng') return false; - return event.target&&event.target!=player&&get.distance(player,event.target,'attack')>1; + yuanzheng_old: { + trigger: { player: "useCardToBegin" }, + direct: true, + filter(event, player) { + if (event.getParent(2).name == "yuanzheng") return false; + return ( + event.target && + event.target != player && + get.distance(player, event.target, "attack") > 1 + ); }, - content(){ - 'step 0' - player.chooseControl('draw_card','出杀','cancel2',function(){ - if(get.effect(trigger.target,{name:'sha'},player,player)>0){ - return '出杀'; + content() { + "step 0"; + player.chooseControl("draw_card", "出杀", "cancel2", function () { + if (get.effect(trigger.target, { name: "sha" }, player, player) > 0) { + return "出杀"; } - return 'draw_card'; - }).prompt='是对'+get.translation(trigger.target)+'发动否发动【远征】?'; - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='draw_card'){ + return "draw_card"; + }).prompt = "是对" + get.translation(trigger.target) + "发动否发动【远征】?"; + "step 1"; + if (result.control != "cancel2") { + if (result.control == "draw_card") { player.draw(); - player.logSkill('yuanzheng'); - } - else{ - player.logSkill('yuanzheng',trigger.target); - player.useCard({name:'sha'},trigger.target,false).animate=false; + player.logSkill("yuanzheng"); + } else { + player.logSkill("yuanzheng", trigger.target); + player.useCard({ name: "sha" }, trigger.target, false).animate = false; // player.discardPlayerCard(trigger.target,'he',true); } } - } - }, - byuhuo:{ - unique:true, - trigger:{player:'dying'}, - priority:6, - forced:true, - mark:true, - skillAnimation:true, - animationColor:'fire', - init(player){ - player.storage.byuhuo=false; }, - filter(event,player){ - if(player.hp>0) return false; - if(player.storage.byuhuo) return false; + }, + byuhuo: { + unique: true, + trigger: { player: "dying" }, + priority: 6, + forced: true, + mark: true, + skillAnimation: true, + animationColor: "fire", + init(player) { + player.storage.byuhuo = false; + }, + filter(event, player) { + if (player.hp > 0) return false; + if (player.storage.byuhuo) return false; return true; }, - content(){ - player.storage.byuhuo=true; - player.addSkill('byuhuo2'); - player.maxHp=2; - player.hp=2; + content() { + player.storage.byuhuo = true; + player.addSkill("byuhuo2"); + player.maxHp = 2; + player.hp = 2; player.update(); - if(!player.isTurnedOver()){ + if (!player.isTurnedOver()) { player.turnOver(); } }, - ai:{ - threaten(player,target){ - if(!target.storage.byuhuo) return 0.6; - } + ai: { + threaten(player, target) { + if (!target.storage.byuhuo) return 0.6; + }, }, - intro:{ - content(storage,player){ - if(storage){ - if(player.hasSkill('byuhuo2')){ - return '不能成为其他角色卡牌的目标;在下一准备阶段,对所有其他角色造成2点火焰伤害'; + intro: { + content(storage, player) { + if (storage) { + if (player.hasSkill("byuhuo2")) { + return "不能成为其他角色卡牌的目标;在下一准备阶段,对所有其他角色造成2点火焰伤害"; } - return '已发动'; + return "已发动"; + } else { + return "未发动"; } - else{ - return '未发动'; - } - } - } + }, + }, }, - byuhuo2:{ - trigger:{player:'phaseBegin'}, - forced:true, - content(){ - 'step 0' - var targets=game.filterPlayer(); + byuhuo2: { + trigger: { player: "phaseBegin" }, + forced: true, + content() { + "step 0"; + var targets = game.filterPlayer(); targets.remove(player); targets.sort(lib.sort.seat); - event.targets=targets; - event.num=0; - player.unmarkSkill('byuhuo'); - 'step 1' - if(num0; + duzhang2: { + mod: { + cardEnabled(card) { + if (get.type(card, "trick") == "trick") return false; + }, }, - content(){ - 'step 0' - var nh=player.countCards('h'); - if(nh){ + mark: true, + marktext: "瘴", + intro: { + content: "下个回合无法使用锦囊牌", + }, + }, + hannu: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { + return player.countCards("h") > 0; + }, + content() { + "step 0"; + var nh = player.countCards("h"); + if (nh) { player.draw(nh); - } - else{ + } else { event.finish(); } - 'step 1' - var hs=player.getCards('h'); - if(hs.length>10&&hs.length>player.hp){ - player.discard(hs.randomGets(hs.length-player.hp)); + "step 1"; + var hs = player.getCards("h"); + if (hs.length > 10 && hs.length > player.hp) { + player.discard(hs.randomGets(hs.length - player.hp)); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var nh=target.countCards('h'); - if(nh>5) return [1,-1]; - if(nh<=1) return [1,-0.1]; - if(nh==2){ - if(target.hp>=2) return [1,0.1]; - } - else{ - if(target.hp>=4) return [1,2]; - if(target.hp==3) return [1,1.5]; - if(target.hp==2) return [1,0.5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var nh = target.countCards("h"); + if (nh > 5) return [1, -1]; + if (nh <= 1) return [1, -0.1]; + if (nh == 2) { + if (target.hp >= 2) return [1, 0.1]; + } else { + if (target.hp >= 4) return [1, 2]; + if (target.hp == 3) return [1, 1.5]; + if (target.hp == 2) return [1, 0.5]; } } - } - } - } - }, - chuidiao:{ - trigger:{player:'phaseEnd'}, - forced:true, - content(){ - var num=Math.floor(Math.random()*3); - if(num) player.draw(num); + }, + }, }, }, - hhudun:{ - trigger:{global:'phaseBegin'}, - forced:true, - filter(event,player){ + chuidiao: { + trigger: { player: "phaseEnd" }, + forced: true, + content() { + var num = Math.floor(Math.random() * 3); + if (num) player.draw(num); + }, + }, + hhudun: { + trigger: { global: "phaseBegin" }, + forced: true, + filter(event, player) { return !player.hujia; }, - content(){ + content() { player.changeHujia(); }, - group:'hhudun_hujia', - subSkill:{ - hujia:{ - trigger:{player:'damageEnd'}, - filter(event){ - return event.hujia==event.num; + group: "hhudun_hujia", + subSkill: { + hujia: { + trigger: { player: "damageEnd" }, + filter(event) { + return event.hujia == event.num; }, - forced:true, - content(){ + forced: true, + content() { player.draw(); - } - } + }, + }, }, - ai:{ - threaten(player,target){ - if(target.hujia){ + ai: { + threaten(player, target) { + if (target.hujia) { return 0.5; - } - else{ + } else { return 2; } - } - } + }, + }, }, - fenlie:{ - audio:2, - forced:true, - trigger:{player:'gainAfter'}, - filter(event,player){ - if(event.parent.parent.name=='phaseDraw') return false; - if(event.parent.name=='fenlie') return false; - if(!event.cards) return false; - for(var i=0;i0; - } - else{ - return event.source&&event.source!=player&&event.source.countCards('e')>0; + nianfu: { + trigger: { source: "damageEnd", player: "damageEnd" }, + forced: true, + filter(event, player) { + if (event._notrigger.includes(event.player)) return false; + if (player == event.source) { + return event.player != player && event.player.countCards("e") > 0; + } else { + return event.source && event.source != player && event.source.countCards("e") > 0; } }, - logTarget(event,player){ - if(player==event.player){ + logTarget(event, player) { + if (player == event.player) { return event.source; - } - else{ + } else { return event.player; } }, - content(){ - var target=(player==trigger.player)?trigger.source:trigger.player; - if(target){ - var cards=target.getCards('e'); - if(cards.length){ - var card=cards.randomGet(); - player.gain(card,target); - target.$give(card,player); + content() { + var target = player == trigger.player ? trigger.source : trigger.player; + if (target) { + var cards = target.getCards("e"); + if (cards.length) { + var card = cards.randomGet(); + player.gain(card, target); + target.$give(card, player); } } }, }, - xiaorong:{ - mod:{ - ignoredHandcard(card,player){ - if(get.type(card)=='equip'){ + xiaorong: { + mod: { + ignoredHandcard(card, player) { + if (get.type(card) == "equip") { return true; } }, }, - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.countCards('h',{type:'equip'})>0; + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.countCards("h", { type: "equip" }) > 0; }, - content(){ - var cards=player.getCards('h',{type:'equip'}); - if(cards.length){ - player.lose(cards)._triggered=null; - var list=[]; - var names=[]; - for(var i=0;i3000&&event.player.countCards('he')>0&&event.player.isAlive(); - }, - content(){ - player.line(trigger.player,'green'); - trigger.player.chooseToDiscard('he',true,Math.floor(trigger.player.storage.shixu/3000)); - delete trigger.player.storage.shixu; - } - } - } - }, - jixuan:{ - trigger:{player:'phaseAfter'}, - forced:true, - priority:-50, - filter(event,player){ - return event.skill!='jixuan'; }, - content(){ + }, + shixu: { + group: ["shixu_begin", "shixu_end", "shixu_discard"], + subSkill: { + begin: { + trigger: { global: "phaseUseBegin" }, + silent: true, + content() { + trigger.player.storage.shixu_begin = get.time(); + }, + }, + end: { + trigger: { global: "phaseUseEnd" }, + silent: true, + filter(event, player) { + return typeof event.player.storage.shixu_begin == "number"; + }, + content() { + trigger.player.storage.shixu = get.time() - trigger.player.storage.shixu_begin; + delete trigger.player.storage.shixu_begin; + }, + }, + discard: { + trigger: { global: "phaseEnd" }, + forced: true, + check(event, player) { + return get.attitude(player, event.player) < 0; + }, + filter(event, player) { + return ( + typeof event.player.storage.shixu == "number" && + event.player.storage.shixu > 3000 && + event.player.countCards("he") > 0 && + event.player.isAlive() + ); + }, + content() { + player.line(trigger.player, "green"); + trigger.player.chooseToDiscard( + "he", + true, + Math.floor(trigger.player.storage.shixu / 3000) + ); + delete trigger.player.storage.shixu; + }, + }, + }, + }, + jixuan: { + trigger: { player: "phaseAfter" }, + forced: true, + priority: -50, + filter(event, player) { + return event.skill != "jixuan"; + }, + content() { player.draw(); player.insertPhase(); }, - ai:{ - threaten:1.8 + ai: { + threaten: 1.8, }, }, - qianghua:{ - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(event.parent.name=='qianghua') return false; - if(player.storage.qianghua>=1) return false; - if(_status.currentPhase!=player) return false; - if(event.parent.parent.name!='phaseUse') return false; - if(!event.targets||!event.card) return false; - if(get.info(event.card).complexTarget) return false; - if(!lib.filter.cardEnabled(event.card,player,event.parent)) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - var card=game.createCard(event.card.name,event.card.suit,event.card.number,event.card.nature); - var targets=event._targets||event.targets; - for(var i=0;i= 1) return false; + if (_status.currentPhase != player) return false; + if (event.parent.parent.name != "phaseUse") return false; + if (!event.targets || !event.card) return false; + if (get.info(event.card).complexTarget) return false; + if (!lib.filter.cardEnabled(event.card, player, event.parent)) return false; + var type = get.type(event.card); + if (type != "basic" && type != "trick") return false; + var card = game.createCard( + event.card.name, + event.card.suit, + event.card.number, + event.card.nature + ); + var targets = event._targets || event.targets; + for (var i = 0; i < targets.length; i++) { + if (!targets[i].isIn()) return false; + if (!player.canUse({ name: event.card.name }, targets[i], false, false)) { return false; } } return true; }, - check(event,player){ - if(get.tag({name:event.card.name},'norepeat')) return false; + check(event, player) { + if (get.tag({ name: event.card.name }, "norepeat")) return false; return true; }, - content(){ + content() { player.storage.qianghua++; - var card=game.createCard(trigger.card.name,trigger.card.suit,trigger.card.number,trigger.card.nature); - player.useCard(card,(trigger._targets||trigger.targets).slice(0)); + var card = game.createCard( + trigger.card.name, + trigger.card.suit, + trigger.card.number, + trigger.card.nature + ); + player.useCard(card, (trigger._targets || trigger.targets).slice(0)); }, - ai:{ - threaten:1.3 + ai: { + threaten: 1.3, + }, + group: "qianghua_clear", + subSkill: { + clear: { + trigger: { player: "phaseBefore" }, + silent: true, + content() { + player.storage.qianghua = 0; + }, + }, }, - group:'qianghua_clear', - subSkill:{ - clear:{ - trigger:{player:'phaseBefore'}, - silent:true, - content(){ - player.storage.qianghua=0; - } - } - } }, - qianghua2:{}, - biri:{ - trigger:{global:'useCard'}, - priority:15, - filter(event,player){ - return event.card.name=='sha'&&event.player!=player&& - get.distance(player,event.targets[0])<=1&& - player.countCards('h','shan')>0&& - event.targets.includes(player)==false&&event.targets.length==1; + qianghua2: {}, + biri: { + trigger: { global: "useCard" }, + priority: 15, + filter(event, player) { + return ( + event.card.name == "sha" && + event.player != player && + get.distance(player, event.targets[0]) <= 1 && + player.countCards("h", "shan") > 0 && + event.targets.includes(player) == false && + event.targets.length == 1 + ); }, - direct:true, - content(){ - "step 0" - var effect=0; - for(var i=0;i0; + filter(event) { + return event.num > 0; }, - content(){ + content() { trigger.num--; - player.removeSkill('stuxi2'); - } + player.removeSkill("stuxi2"); + }, }, - bingdong:{ - trigger:{source:'damageEnd'}, - forced:true, - usable:1, - filter(event,player){ - if(!lib.card.hslingjian_jinjilengdong){ + bingdong: { + trigger: { source: "damageEnd" }, + forced: true, + usable: 1, + filter(event, player) { + if (!lib.card.hslingjian_jinjilengdong) { return false; } return true; }, - content(){ - player.gain(game.createCard('hslingjian_jinjilengdong'),'gain2'); - } + content() { + player.gain(game.createCard("hslingjian_jinjilengdong"), "gain2"); + }, }, - bingdong_old:{ - enable:'phaseUse', - usable:1, - filter(event,player){ + bingdong_old: { + enable: "phaseUse", + usable: 1, + filter(event, player) { return !player.isTurnedOver(); }, - filterTarget(card,player,target){ - return !target.isTurnedOver()&&player!=target; + filterTarget(card, player, target) { + return !target.isTurnedOver() && player != target; }, - content(){ - 'step 0' - if(!player.isTurnedOver()){ + content() { + "step 0"; + if (!player.isTurnedOver()) { player.turnOver(); } - 'step 1' - if(!target.isTurnedOver()){ + "step 1"; + if (!target.isTurnedOver()) { target.turnOver(); } }, - ai:{ - order:1, - expose:0.2, - result:{ - target(player,target){ - if(get.attitude(player,target)<-3&&player.identity!='zhu'){ + ai: { + order: 1, + expose: 0.2, + result: { + target(player, target) { + if (get.attitude(player, target) < -3 && player.identity != "zhu") { return -1; } return 0; - } - } - } - }, - luoshi:{ - trigger:{player:'damageEnd'}, - forced:true, - filter(event,player){ - return player.countCards('he')>0||(event.source&&event.source.countCards('he')>0); + }, + }, }, - content(){ - 'step 0' - var hs=player.getCards('he'); - if(hs.length){ - player.discard(hs.randomGet()) + }, + luoshi: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event, player) { + return player.countCards("he") > 0 || (event.source && event.source.countCards("he") > 0); + }, + content() { + "step 0"; + var hs = player.getCards("he"); + if (hs.length) { + player.discard(hs.randomGet()); } - 'step 1' - if(trigger.source){ - var hs=trigger.source.getCards('he'); - if(hs.length){ - trigger.source.discard(hs.randomGet()) + "step 1"; + if (trigger.source) { + var hs = trigger.source.getCards("he"); + if (hs.length) { + trigger.source.discard(hs.randomGet()); } } }, - ai:{ - maixie_defend:true, - } - }, - ronghuo:{ - trigger:{player:'useCardToBefore'}, - priority:7, - filter(event,player){ - if(event.card.name=='sha'&&!event.card.nature) return true; + ai: { + maixie_defend: true, }, - check(event,player){ - var att=get.attitude(player,event.target); - if(event.target.hasSkillTag('nofire')){ - return att>0; + }, + ronghuo: { + trigger: { player: "useCardToBefore" }, + priority: 7, + filter(event, player) { + if (event.card.name == "sha" && !event.card.nature) return true; + }, + check(event, player) { + var att = get.attitude(player, event.target); + if (event.target.hasSkillTag("nofire")) { + return att > 0; } - return att<=0; + return att <= 0; + }, + forced: true, + content() { + trigger.card.nature = "fire"; + player.addSkill("ronghuo2"); + player.storage.ronghuo = trigger.card; }, - forced:true, - content(){ - trigger.card.nature='fire'; - player.addSkill('ronghuo2'); - player.storage.ronghuo=trigger.card; - } }, - ronghuo2:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - content(){ + ronghuo2: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + content() { delete player.storage.ronghuo.nature; - } - }, - fushi:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target.hp1){ - if(target.hp<=1) att+=2; - if(target.hp<=2) att++; + }, + moyao: { + mod: { + targetEnabled(card, player, target, now) { + if (player != target) { + if (get.type(card, "trick") == "trick") return false; + } + }, + }, + }, + jiaohui: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return !player.getStat("damage"); + }, + content() { + "step 0"; + player.chooseTarget(get.prompt("jiaohui")).ai = function (target) { + var att = get.attitude(player, target); + if (att > 1) { + if (target.hp <= 1) att += 2; + if (target.hp <= 2) att++; } return att; }; - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('jiaohui',event.target); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("jiaohui", event.target); event.target.chooseDrawRecover(true); } }, }, - bimeng:{ - trigger:{player:'phaseEnd'}, - frequent:true, - content(){ - var list=['hsmengjing_feicuiyoulong','hsmengjing_huanxiaojiemei', - 'hsmengjing_suxing','hsmengjing_mengye','hsmengjing_mengjing']; + bimeng: { + trigger: { player: "phaseEnd" }, + frequent: true, + content() { + var list = [ + "hsmengjing_feicuiyoulong", + "hsmengjing_huanxiaojiemei", + "hsmengjing_suxing", + "hsmengjing_mengye", + "hsmengjing_mengjing", + ]; player.gain(game.createCard(list.randomGet())); player.$draw(); }, - ai:{ - threaten:2 - } - }, - zhoujiang:{ - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return get.type(event.card)=='trick'; + ai: { + threaten: 2, }, - content(){ - var list=['hszuzhou_nvwudeganguo','hszuzhou_nvwudepingguo', - 'hszuzhou_nvwudexuetu','hszuzhou_wushushike','hszuzhou_guhuo']; - player.gain(game.createCard(list.randomGet()),'draw'); - }, - ai:{ - threaten:1.5 - } }, - liehun:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter(event,player){ - return player.hasCard(function(card){ - return get.type(card)!='basic'&&!get.info(card).unique; + zhoujiang: { + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return get.type(event.card) == "trick"; + }, + content() { + var list = [ + "hszuzhou_nvwudeganguo", + "hszuzhou_nvwudepingguo", + "hszuzhou_nvwudexuetu", + "hszuzhou_wushushike", + "hszuzhou_guhuo", + ]; + player.gain(game.createCard(list.randomGet()), "draw"); + }, + ai: { + threaten: 1.5, + }, + }, + liehun: { + trigger: { player: "phaseEnd" }, + forced: true, + filter(event, player) { + return player.hasCard(function (card) { + return get.type(card) != "basic" && !get.info(card).unique; }); }, - content(){ - var hs=player.getCards('h'); - for(var i=0;i0){ - if(target==player){ + content() { + "step 0"; + player.chooseTarget(get.prompt("lingzhou")).ai = function (target) { + var num = get.attitude(player, target); + if (num > 0) { + if (target == player) { num++; } - if(target.hp==1){ - num+=3; - } - else if(target.hp==2){ - num+=1; + if (target.hp == 1) { + num += 3; + } else if (target.hp == 2) { + num += 1; } } return num; - } - "step 1" - if(result.bool){ - player.logSkill('lingzhou',result.targets); + }; + "step 1"; + if (result.bool) { + player.logSkill("lingzhou", result.targets); result.targets[0].chooseDrawRecover(true); } }, - ai:{ - expose:0.2, - threaten:1.5, - noautowuxie:true, - } + ai: { + expose: 0.2, + threaten: 1.5, + noautowuxie: true, + }, }, - mieshi:{ - trigger:{player:'phaseEnd'}, - forced:true, - content(){ - 'step 0' + mieshi: { + trigger: { player: "phaseEnd" }, + forced: true, + content() { + "step 0"; player.loseHp(); - 'step 1' - event.target=game.filterPlayer().randomGet(player); - if(!event.target){ + "step 1"; + event.target = game.filterPlayer().randomGet(player); + if (!event.target) { event.finish(); return; } - player.line(event.target,'fire'); + player.line(event.target, "fire"); game.delayx(); - 'step 2' - event.target.damage('fire'); - } + "step 2"; + event.target.damage("fire"); + }, }, - xmojian:{ - trigger:{player:'turnOverAfter'}, - direct:true, - filter(event,player){ + xmojian: { + trigger: { player: "turnOverAfter" }, + direct: true, + filter(event, player) { return !player.isTurnedOver(); }, - content(){ - "step 0" - player.chooseTarget(get.prompt('xmojian'),function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); - }).ai=function(target){ - return get.effect(target,{name:'sha'},player); - } - "step 1" - if(result.bool){ - player.logSkill('xmojian'); - player.useCard({name:'sha'},result.targets,false); + content() { + "step 0"; + player.chooseTarget(get.prompt("xmojian"), function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); + }).ai = function (target) { + return get.effect(target, { name: "sha" }, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("xmojian"); + player.useCard({ name: "sha" }, result.targets, false); } }, - ai:{ - expose:0.2, - } + ai: { + expose: 0.2, + }, }, - xshixin:{ - trigger:{source:'damageEnd'}, - forced:true, + xshixin: { + trigger: { source: "damageEnd" }, + forced: true, // alter:true, - filter(event,player){ - if(event._notrigger.includes(event.player)) return false; - if(get.is.altered('xshixin')&&event.player.hp0){ - if(num>3){ - num=3; + content() { + var num = player.countCards("h") - target.countCards("h"); + if (num > 0) { + if (num > 3) { + num = 3; } target.draw(num); - } - else if(num<0){ - if(num<-3){ - num=-3; + } else if (num < 0) { + if (num < -3) { + num = -3; } - target.chooseToDiscard(-num,true); + target.chooseToDiscard(-num, true); } }, - ai:{ - threaten:1.8, - order(name,player){ - var max=true,num=0; - var players=game.filterPlayer(); - for(var i=0;inum){ - if(att>0){ - max=true; + ai: { + threaten: 1.8, + order(name, player) { + var max = true, + num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] == player) continue; + var att = get.attitude(player, players[i]); + var dh = player.countCards("h") - players[i].countCards("h"); + if (att * dh > num) { + if (att > 0) { + max = true; + } else if (att < 0) { + max = false; } - else if(att<0){ - max=false; - } - num=att*dh; + num = att * dh; } } - if(max) return 10; + if (max) return 10; return 0.5; }, - result:{ - player(player,target){ - return (player.countCards('h')-target.countCards('h'))*get.attitude(player,target); - } + result: { + player(player, target) { + return ( + (player.countCards("h") - target.countCards("h")) * + get.attitude(player, target) + ); + }, }, - expose:0.2 - } + expose: 0.2, + }, }, - oldenze:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return player.countCards('h')!=target.countCards('h'); + oldenze: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return player.countCards("h") != target.countCards("h"); }, // alter:true, - content(){ - var num=player.countCards('h')-target.countCards('h'); - if(num>0){ + content() { + var num = player.countCards("h") - target.countCards("h"); + if (num > 0) { target.draw(num); - } - else if(num<0){ - target.chooseToDiscard(-num,true); + } else if (num < 0) { + target.chooseToDiscard(-num, true); } }, - ai:{ - threaten:1.8, - order(name,player){ - var max=true,num=0; - var players=game.filterPlayer(); - for(var i=0;inum){ - if(att>0){ - max=true; + ai: { + threaten: 1.8, + order(name, player) { + var max = true, + num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] == player) continue; + var att = get.attitude(player, players[i]); + var dh = player.countCards("h") - players[i].countCards("h"); + if (att * dh > num) { + if (att > 0) { + max = true; + } else if (att < 0) { + max = false; } - else if(att<0){ - max=false; - } - num=att*dh; + num = att * dh; } } - if(max) return 10; + if (max) return 10; return 0.5; }, - result:{ - player(player,target){ - return (player.countCards('h')-target.countCards('h'))*get.attitude(player,target); - } + result: { + player(player, target) { + return ( + (player.countCards("h") - target.countCards("h")) * + get.attitude(player, target) + ); + }, }, - expose:0.2 - } - }, - chongsheng:{ - unique:true, - enable:'chooseToUse', - mark:true, - init(player){ - player.storage.chongsheng=2; - player.syncStorage('chongsheng'); + expose: 0.2, }, - filter(event,player){ - if(event.type!='dying') return false; - if(player!=event.dying) return false; - if(player.storage.chongsheng<=0) return false; + }, + chongsheng: { + unique: true, + enable: "chooseToUse", + mark: true, + init(player) { + player.storage.chongsheng = 2; + player.syncStorage("chongsheng"); + }, + filter(event, player) { + if (event.type != "dying") return false; + if (player != event.dying) return false; + if (player.storage.chongsheng <= 0) return false; return true; }, - content(){ - 'step 0' - player.hp=Math.min(player.storage.chongsheng,player.maxHp); - player.discard(player.getCards('hej')); + content() { + "step 0"; + player.hp = Math.min(player.storage.chongsheng, player.maxHp); + player.discard(player.getCards("hej")); player.draw(player.storage.chongsheng); player.storage.chongsheng--; - if(player.storage.chongsheng<=0){ - player.unmarkSkill('chongsheng'); + if (player.storage.chongsheng <= 0) { + player.unmarkSkill("chongsheng"); } - 'step 1' - if(player.isLinked()) player.link(); - 'step 2' - if(player.isTurnedOver()) player.turnOver(); - player.syncStorage('chongsheng'); + "step 1"; + if (player.isLinked()) player.link(); + "step 2"; + if (player.isTurnedOver()) player.turnOver(); + player.syncStorage("chongsheng"); }, - ai:{ - skillTagFilter(player){ - if(player.storage.chongsheng<=0) return false; - if(player.hp>0) return false; + ai: { + skillTagFilter(player) { + if (player.storage.chongsheng <= 0) return false; + if (player.hp > 0) return false; }, - save:true, - result:{ - player:10 + save: true, + result: { + player: 10, + }, + threaten(player, target) { + if (target.storage.chongsheng > 0) return 0.6; }, - threaten(player,target){ - if(target.storage.chongsheng>0) return 0.6; - } }, - intro:{ - content:'time' - } + intro: { + content: "time", + }, }, - guozai:{ - enable:'phaseUse', - usable:1, + guozai: { + enable: "phaseUse", + usable: 1, // alter:true, - filter(event,player){ - return player.countCards('h')<(get.is.altered('guozai')?3:4); + filter(event, player) { + return player.countCards("h") < (get.is.altered("guozai") ? 3 : 4); }, - init(player){ - player.storage.guozai2=0; + init(player) { + player.storage.guozai2 = 0; }, - content(){ - var num=(get.is.altered('guozai')?3:4)-player.countCards('h'); + content() { + var num = (get.is.altered("guozai") ? 3 : 4) - player.countCards("h"); player.draw(num); - player.addSkill('guozai2'); - player.storage.guozai2+=num; - game.addVideo('storage',player,['guozai2',player.storage.guozai2]); + player.addSkill("guozai2"); + player.storage.guozai2 += num; + game.addVideo("storage", player, ["guozai2", player.storage.guozai2]); + }, + ai: { + order: 1, + result: { + player: 1, + }, }, - ai:{ - order:1, - result:{ - player:1 - } - } }, - guozai2:{ - mark:true, - intro:{ - content:'结束阶段需弃置&张牌' + guozai2: { + mark: true, + intro: { + content: "结束阶段需弃置&张牌", + }, + trigger: { player: "phaseUseEnd" }, + forced: true, + content() { + player.chooseToDiscard("he", true, player.storage.guozai2); + player.storage.guozai2 = 0; + player.removeSkill("guozai2"); }, - trigger:{player:'phaseUseEnd'}, - forced:true, - content(){ - player.chooseToDiscard('he',true,player.storage.guozai2); - player.storage.guozai2=0; - player.removeSkill('guozai2'); - } }, - guozaix:{ - enable:'phaseUse', - usable:2, - filter(event,player){ - return player.countCards('h')<4; + guozaix: { + enable: "phaseUse", + usable: 2, + filter(event, player) { + return player.countCards("h") < 4; }, - init(player){ - player.storage.guozaix2=0; + init(player) { + player.storage.guozaix2 = 0; }, - content(){ - var num=4-player.countCards('h'); + content() { + var num = 4 - player.countCards("h"); player.draw(num); - player.addSkill('guozaix2'); - player.storage.guozaix2+=num; - game.addVideo('storage',player,['guozaix2',player.storage.guozaix2]); + player.addSkill("guozaix2"); + player.storage.guozaix2 += num; + game.addVideo("storage", player, ["guozaix2", player.storage.guozaix2]); }, - ai:{ - order:1, - result:{ - player:1 - } - } - }, - guozaix2:{ - mark:true, - intro:{ - content:'结束阶段需弃置&张牌' + ai: { + order: 1, + result: { + player: 1, + }, }, - trigger:{player:'phaseUseEnd'}, - forced:true, - content(){ - player.chooseToDiscard('he',true,player.storage.guozaix2); - player.storage.guozaix2=0; - player.removeSkill('guozaix2'); - } }, - hanshuang:{ - trigger:{source:'damageEnd'}, - forced:true, + guozaix2: { + mark: true, + intro: { + content: "结束阶段需弃置&张牌", + }, + trigger: { player: "phaseUseEnd" }, + forced: true, + content() { + player.chooseToDiscard("he", true, player.storage.guozaix2); + player.storage.guozaix2 = 0; + player.removeSkill("guozaix2"); + }, + }, + hanshuang: { + trigger: { source: "damageEnd" }, + forced: true, // alter:true, - filter(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&get.color(event.card)=='black'&& - !event.player.isTurnedOver()&&event.player.isAlive(); + filter(event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + get.color(event.card) == "black" && + !event.player.isTurnedOver() && + event.player.isAlive() + ); }, - content(){ + content() { trigger.player.turnOver(); - if(get.is.altered('hanshuang')) trigger.player.draw(); + if (get.is.altered("hanshuang")) trigger.player.draw(); player.loseHp(); }, - ai:{ - threaten:1.5, - effect:{ - player(card,player,target,current){ - if(get.color(card)=='black'&&get.tag(card,'damage')){ - return [1,0,1,-2]; + ai: { + threaten: 1.5, + effect: { + player(card, player, target, current) { + if (get.color(card) == "black" && get.tag(card, "damage")) { + return [1, 0, 1, -2]; } - } - } - } - }, - oldhanshuang:{ - trigger:{source:'damageEnd'}, - forced:true, - // alter:true, - filter(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&get.color(event.card)=='black'&& - !event.player.isTurnedOver()&&event.player.isAlive(); + }, + }, }, - content(){ + }, + oldhanshuang: { + trigger: { source: "damageEnd" }, + forced: true, + // alter:true, + filter(event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + get.color(event.card) == "black" && + !event.player.isTurnedOver() && + event.player.isAlive() + ); + }, + content() { trigger.player.turnOver(); }, - ai:{ - threaten:1.5, - effect:{ - player(card,player,target,current){ - if(get.color(card)=='black'&&get.tag(card,'damage')){ - return [1,0,1,-2]; + ai: { + threaten: 1.5, + effect: { + player(card, player, target, current) { + if (get.color(card) == "black" && get.tag(card, "damage")) { + return [1, 0, 1, -2]; } - } - } - } - }, - bingshi:{ - global:'bingshi2' - }, - bingshi2:{ - trigger:{global:'dieAfter'}, - forced:true, - globalFixed:true, - filter(event,player){ - return event.player.hasSkill('bingshi')&&event.player.isDead(); + }, + }, }, - content(){ - trigger.player.line(player,'thunder'); - player.damage('nosource','thunder').animate=false; + }, + bingshi: { + global: "bingshi2", + }, + bingshi2: { + trigger: { global: "dieAfter" }, + forced: true, + globalFixed: true, + filter(event, player) { + return event.player.hasSkill("bingshi") && event.player.isDead(); + }, + content() { + trigger.player.line(player, "thunder"); + player.damage("nosource", "thunder").animate = false; player.$damage(trigger.player); - player.$damagepop(-1,'thunder'); - if(lib.config.animation&&!lib.config.low_performance){ + player.$damagepop(-1, "thunder"); + if (lib.config.animation && !lib.config.low_performance) { player.$thunder(); } - if(!event.parent.parent.bingshi_logv){ - event.parent.parent.bingshi_logv=true; - game.logv(trigger.player,'bingshi',game.filterPlayer(),event.parent.parent); + if (!event.parent.parent.bingshi_logv) { + event.parent.parent.bingshi_logv = true; + game.logv(trigger.player, "bingshi", game.filterPlayer(), event.parent.parent); } - } + }, }, - huanwu:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ + huanwu: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { return !target.storage.huanwu; }, - content(){ + content() { target.gainMaxHp(); target.recover(); target.draw(2); - target.storage.huanwu=true; - target.mark('huanwu',{ - name:'唤雾', - content:'已发动' + target.storage.huanwu = true; + target.mark("huanwu", { + name: "唤雾", + content: "已发动", }); - game.addVideo('mark',target,{ - name:'唤雾', - content:'已发动', - id:'huanwu' + game.addVideo("mark", target, { + name: "唤雾", + content: "已发动", + id: "huanwu", }); }, - ai:{ - threaten:1.2, - result:{ - target(player,target){ - return 1/target.hp; - } + ai: { + threaten: 1.2, + result: { + target(player, target) { + return 1 / target.hp; + }, }, - order:10, - expose:0.3 - } + order: 10, + expose: 0.3, + }, }, - fengnu:{ - mod:{ - cardUsable(card){ - if(get.info(card)&&get.info(card).forceUsable) return; + fengnu: { + mod: { + cardUsable(card) { + if (get.info(card) && get.info(card).forceUsable) return; return Infinity; }, - targetInRange(){ - if(!get.is.altered('fengnu')) return true; - } + targetInRange() { + if (!get.is.altered("fengnu")) return true; + }, }, // alter:true, - trigger:{player:'useCard'}, - filter(event,player){ - if(_status.currentPhase!=player) return false; - return player.countUsed(event.card)>1; + trigger: { player: "useCard" }, + filter(event, player) { + if (_status.currentPhase != player) return false; + return player.countUsed(event.card) > 1; }, - forced:true, - usable:3, - content(){ + forced: true, + usable: 3, + content() { player.draw(); - } + }, }, - shengdun:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter(event,player){ + shengdun: { + trigger: { player: "phaseBegin" }, + forced: true, + filter(event, player) { return !player.hujia; }, - content(){ + content() { player.changeHujia(); player.update(); }, }, - shengdun_old:{ - trigger:{player:'phaseBegin'}, - silent:true, - priority:10, - init2(player){ - player.markSkill('shengdun'); + shengdun_old: { + trigger: { player: "phaseBegin" }, + silent: true, + priority: 10, + init2(player) { + player.markSkill("shengdun"); }, - content(){ - if(player.storage.shengdun){ - player.markSkill('shengdun'); + content() { + if (player.storage.shengdun) { + player.markSkill("shengdun"); } - player.storage.shengdun=false; + player.storage.shengdun = false; }, - intro:{ - content:'未发动' + intro: { + content: "未发动", }, - group:'shengdun2' + group: "shengdun2", }, - shengdun_old2:{ - trigger:{player:'damageBegin'}, - forced:true, - filter(event,player){ - return event.num>0&&!player.storage.shengdun; + shengdun_old2: { + trigger: { player: "damageBegin" }, + forced: true, + filter(event, player) { + return event.num > 0 && !player.storage.shengdun; }, - content(){ + content() { trigger.num--; - player.storage.shengdun=true; - player.unmarkSkill('shengdun'); - } - }, - jingmeng:{ - trigger:{player:'useCard'}, - frequent:true, - filter(event,player){ - return _status.currentPhase==player&&player.countUsed()==1; + player.storage.shengdun = true; + player.unmarkSkill("shengdun"); }, - content(){ - var type=get.type(trigger.card); - var card=get.cardPile2(function(card){ - return get.type(card)==type; + }, + jingmeng: { + trigger: { player: "useCard" }, + frequent: true, + filter(event, player) { + return _status.currentPhase == player && player.countUsed() == 1; + }, + content() { + var type = get.type(trigger.card); + var card = get.cardPile2(function (card) { + return get.type(card) == type; }); - if(card){ - player.gain(card,'gain2','log'); + if (card) { + player.gain(card, "gain2", "log"); } }, - ai:{ - threaten:1.1 - } + ai: { + threaten: 1.1, + }, }, - kuixin_old:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - var nh=player.countCards('h'); - var nm=1; - return game.hasPlayer(function(current){ - if(current!=player&&Math.abs(current.countCards('h')-nh)<=nm){ + kuixin_old: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + var nh = player.countCards("h"); + var nm = 1; + return game.hasPlayer(function (current) { + if (current != player && Math.abs(current.countCards("h") - nh) <= nm) { return true; } }); }, - content(){ - 'step 0' - var nh=player.countCards('h'); - var nm=1; - var check=true; - if(player.countCards('h','tao')){ - check=false; + content() { + "step 0"; + var nh = player.countCards("h"); + var nm = 1; + var check = true; + if (player.countCards("h", "tao")) { + check = false; + } else if (player.countCards("h", "shan") && player.countCards("h", "wuxie")) { + check = false; } - else if(player.countCards('h','shan')&&player.countCards('h','wuxie')){ - check=false; - } - player.chooseTarget(get.prompt('kuixin'),function(card,player,target){ - return target!=player&&Math.abs(target.countCards('h')-nh)<=nm; - }).ai=function(target){ - if(!check) return 0; - if(get.attitude(player,target)<0){ - return target.countCards('h')-nh; + player.chooseTarget(get.prompt("kuixin"), function (card, player, target) { + return target != player && Math.abs(target.countCards("h") - nh) <= nm; + }).ai = function (target) { + if (!check) return 0; + if (get.attitude(player, target) < 0) { + return target.countCards("h") - nh; } return 0; }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('kuixin',result.targets); - var cards0=target.getCards('h'); - var cards1=player.getCards('h'); - target.gain(cards1,player); - player.gain(cards0,target); - target.$give(cards0.length,player); - player.$give(cards1.length,target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("kuixin", result.targets); + var cards0 = target.getCards("h"); + var cards1 = player.getCards("h"); + target.gain(cards1, player); + player.gain(cards0, target); + target.$give(cards0.length, player); + player.$give(cards1.length, target); } }, - ai:{ - expose:0.2, - threaten:1.5 - } - }, - hswuji:{ - trigger:{player:'phaseUseEnd'}, - frequent:true, - filter(event,player){ - return player.countUsed()>0; + ai: { + expose: 0.2, + threaten: 1.5, }, - content(){ + }, + hswuji: { + trigger: { player: "phaseUseEnd" }, + frequent: true, + filter(event, player) { + return player.countUsed() > 0; + }, + content() { player.draw(player.countUsed()); }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - bingshuang:{ - trigger:{source:'damageEnd'}, - filter(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&get.type(event.card)=='trick'&& - event.player.isAlive()&&!event.player.isTurnedOver(); + bingshuang: { + trigger: { source: "damageEnd" }, + filter(event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + get.type(event.card) == "trick" && + event.player.isAlive() && + !event.player.isTurnedOver() + ); }, - check(event,player){ - if(event.player.hasSkillTag('noturn')) return; - if(event.player.isTurnedOver()){ - return get.attitude(player,event.player)>0; + check(event, player) { + if (event.player.hasSkillTag("noturn")) return; + if (event.player.isTurnedOver()) { + return get.attitude(player, event.player) > 0; } - return get.attitude(player,event.player)<=0; + return get.attitude(player, event.player) <= 0; }, - logTarget:'player', - content(){ + logTarget: "player", + content() { trigger.player.draw(2); trigger.player.turnOver(); - } + }, }, - yanshu:{ - trigger:{player:'discardAfter'}, - frequent:true, - usable:1, - filter(event,player){ - if(!event.cards) return false; - for(var i=0;i0; + logTarget: "player", + check(event, player) { + return get.attitude(player, event.player) > 0; }, - content(){ + content() { trigger.player.recover(); - player.addTempSkill('shengyan2'); + player.addTempSkill("shengyan2"); + }, + ai: { + expose: 0.2, }, - ai:{ - expose:0.2 - } }, - shengyan2:{}, - liechao:{ - enable:'phaseUse', - usable:1, + shengyan2: {}, + liechao: { + enable: "phaseUse", + usable: 1, // alter:true, - filter(event,player){ - return !player.isTurnedOver()&&player.countCards('h')<=player.hp; + filter(event, player) { + return !player.isTurnedOver() && player.countCards("h") <= player.hp; }, - content(){ - player.draw(get.is.altered('liechao')?3:4); + content() { + player.draw(get.is.altered("liechao") ? 3 : 4); player.turnOver(); - player.skip('phaseDiscard'); + player.skip("phaseDiscard"); + }, + ai: { + order: 10, + result: { + player: 1, + }, }, - ai:{ - order:10, - result:{ - player:1 - } - } }, - qingliu:{ - trigger:{player:'damageBefore'}, - filter(event){ - return event.nature=='fire'; + qingliu: { + trigger: { player: "damageBefore" }, + filter(event) { + return event.nature == "fire"; }, - forced:true, - content(){ + forced: true, + content() { trigger.cancel(); }, - ai:{ - nofire:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'fireDamage')) return 0; - } - } - } - }, - zhongjia:{ - trigger:{player:'damageEnd'}, - forced:true, - filter(event){ - return event.num>0; + ai: { + nofire: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "fireDamage")) return 0; + }, + }, }, - content(){ + }, + zhongjia: { + trigger: { player: "damageEnd" }, + forced: true, + filter(event) { + return event.num > 0; + }, + content() { player.changeHujia(); }, - ai:{ - nohujia:true, - maixie:true, - maixie_hp:true, - skillTagFilter(player){ - return player.hp>player.countCards('h')&&player.hp>1; + ai: { + nohujia: true, + maixie: true, + maixie_hp: true, + skillTagFilter(player) { + return player.hp > player.countCards("h") && player.hp > 1; }, - threaten(player,target){ - if(!target.hujia) return 0.8; + threaten(player, target) { + if (!target.hujia) return 0.8; }, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; return 0.8; } - } - } - } + }, + }, + }, }, - dunji:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.hujia?true:false; + dunji: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.hujia ? true : false; }, - filterTarget(card,player,target){ - return player!=target&&get.distance(player,target,'attack')<=1; + filterTarget(card, player, target) { + return player != target && get.distance(player, target, "attack") <= 1; }, - selectTarget(){ - return [1,_status.event.player.hujia]; + selectTarget() { + return [1, _status.event.player.hujia]; }, - contentBefore(){ + contentBefore() { player.changeHujia(-targets.length); }, - content(){ + content() { target.damage(); }, - ai:{ - order:9, - result:{ - target(player,target){ - var eff=get.damageEffect(target,player,target)+0.5; - if(eff>0&&eff<=0.5) return 0; + ai: { + order: 9, + result: { + target(player, target) { + var eff = get.damageEffect(target, player, target) + 0.5; + if (eff > 0 && eff <= 0.5) return 0; return eff; - } - } - } - }, - fengxing:{ - trigger:{player:'loseEnd'}, - direct:true, - filter(event,player){ - return _status.currentPhase!=player&&!player.hasSkill('fengxing2')&&player.countCards('he')>0; + }, + }, }, - content(){ - 'step 0' - player.addTempSkill('fengxing2'); - player.chooseToDiscard('he',get.prompt('fengxing')).set('ai',function(card){ - return 7-get.value(card); - }).set('autodelay',0.5).logSkill='fengxing'; - 'step 1' - if(result.bool){ + }, + fengxing: { + trigger: { player: "loseEnd" }, + direct: true, + filter(event, player) { + return ( + _status.currentPhase != player && + !player.hasSkill("fengxing2") && + player.countCards("he") > 0 + ); + }, + content() { + "step 0"; + player.addTempSkill("fengxing2"); + player + .chooseToDiscard("he", get.prompt("fengxing")) + .set("ai", function (card) { + return 7 - get.value(card); + }) + .set("autodelay", 0.5).logSkill = "fengxing"; + "step 1"; + if (result.bool) { player.draw(2); } }, - ai:{ - threaten:0.6 - } - }, - fengxing2:{}, - fengxian:{ - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target.countCards('h')>0; + ai: { + threaten: 0.6, }, - selectTarget:-1, - content(){ + }, + fengxing2: {}, + fengxian: { + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target.countCards("h") > 0; + }, + selectTarget: -1, + content() { target.chooseToDiscard(true); }, - ai:{ - order:8, - result:{ - target(player,target){ - var nh=target.countCards('h'); - switch(nh){ - case 0:return 0; - case 1:return -1.5; - case 2:return -1.3; - case 3:return -1; - default:return -0.8; + ai: { + order: 8, + result: { + target(player, target) { + var nh = target.countCards("h"); + switch (nh) { + case 0: + return 0; + case 1: + return -1.5; + case 2: + return -1.3; + case 3: + return -1; + default: + return -0.8; } - } - } - } + }, + }, + }, }, - qiaodong:{ - enable:['chooseToUse','chooseToRespond'], - filterCard:{type:'equip'}, - filter(event,player){ - return player.countCards('he',{type:'equip'})>0; + qiaodong: { + enable: ["chooseToUse", "chooseToRespond"], + filterCard: { type: "equip" }, + filter(event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + viewAs: { name: "shan" }, + position: "he", + prompt: "将一张装备牌当闪使用或打出", + check() { + return 1; + }, + ai: { + respondShan: true, + skillTagFilter(player) { + if (!player.countCards("he", { type: "equip" })) return false; + }, }, - viewAs:{name:'shan'}, - position:'he', - prompt:'将一张装备牌当闪使用或打出', - check(){return 1}, - ai:{ - respondShan:true, - skillTagFilter(player){ - if(!player.countCards('he',{type:'equip'})) return false; - } - } }, - hsmengjing_mengye:{ - trigger:{player:'phaseEnd'}, - forced:true, - priority:-1, - filter(event,player){ - return player.countCards('he')>0; + hsmengjing_mengye: { + trigger: { player: "phaseEnd" }, + forced: true, + priority: -1, + filter(event, player) { + return player.countCards("he") > 0; }, - content(){ - player.discard(player.getCards('he')); - player.removeSkill('hsmengjing_mengye'); + content() { + player.discard(player.getCards("he")); + player.removeSkill("hsmengjing_mengye"); + }, + mark: "image", + intro: { + content: "结束阶段,弃置所有牌", }, - mark:'image', - intro:{ - content:'结束阶段,弃置所有牌' - } }, - zhanhou:{ - enable:'phaseUse', - filterCard:{subtype:'equip2'}, - position:'he', - usable:1, - filter(event,player){ - return player.countCards('he',{subtype:'equip2'})>0; + zhanhou: { + enable: "phaseUse", + filterCard: { subtype: "equip2" }, + position: "he", + usable: 1, + filter(event, player) { + return player.countCards("he", { subtype: "equip2" }) > 0; }, - check(card){ - return 7-get.value(card); + check(card) { + return 7 - get.value(card); }, - content(){ + content() { player.changeHujia(); }, - ai:{ - order:9.5, - result:{ - player:1 - } + ai: { + order: 9.5, + result: { + player: 1, + }, }, // mod:{ // globalFrom(from,to,distance){ @@ -7058,166 +7467,169 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }, }, - oldzhanhou:{ - enable:'phaseUse', - filterCard:{subtype:'equip2'}, - position:'he', - filter(event,player){ - return player.countCards('he',{subtype:'equip2'})>0; + oldzhanhou: { + enable: "phaseUse", + filterCard: { subtype: "equip2" }, + position: "he", + filter(event, player) { + return player.countCards("he", { subtype: "equip2" }) > 0; }, - check(card){ - if(get.position(card)=='e') return 0; - return 7-get.value(card); + check(card) { + if (get.position(card) == "e") return 0; + return 7 - get.value(card); }, - content(){ + content() { player.changeHujia(); }, - ai:{ - order:6, - result:{ - player:1 - } - } + ai: { + order: 6, + result: { + player: 1, + }, + }, }, - shijie:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + shijie: { + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - content(){ - 'step 0' - player.chooseTarget(get.prompt('shijie'),function(card,player,target){ - return player!=target&&target.countCards('h')>0; - }).ai=function(target){ - return 11-get.attitude(player,target); + content() { + "step 0"; + player.chooseTarget(get.prompt("shijie"), function (card, player, target) { + return player != target && target.countCards("h") > 0; + }).ai = function (target) { + return 11 - get.attitude(player, target); }; - 'step 1' - if(result.bool){ - player.logSkill('shijie',result.targets); - var target=result.targets[0]; - var card=target.getCards('h').randomGet() - player.gain(card,target); - event.target=target; - target.$giveAuto(card,player); + "step 1"; + if (result.bool) { + player.logSkill("shijie", result.targets); + var target = result.targets[0]; + var card = target.getCards("h").randomGet(); + player.gain(card, target); + event.target = target; + target.$giveAuto(card, player); event.target.draw(); } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - shengguang:{ - enable:'phaseUse', - filterCard:{color:'red'}, - filter(event,player){ - return player.countCards('he',{color:'red'})>0; + shengguang: { + enable: "phaseUse", + filterCard: { color: "red" }, + filter(event, player) { + return player.countCards("he", { color: "red" }) > 0; }, - position:'he', - usable:1, - check(card){ - return 9-get.value(card) + position: "he", + usable: 1, + check(card) { + return 9 - get.value(card); }, - filterTarget(card,player,target){ - if(player.storage.anying) return true; - if(target.hp>=target.maxHp) return false; + filterTarget(card, player, target) { + if (player.storage.anying) return true; + if (target.hp >= target.maxHp) return false; return true; }, - content(){ - if(player.storage.anying){ + content() { + if (player.storage.anying) { target.loseHp(); - } - else{ + } else { target.recover(); } }, - ai:{ - order:9, - result:{ - target(player,target){ - if(player.storage.anying) return -1; - if(target.hp==1) return 5; - if(player==target&&player.countCards('h')>player.hp) return 5; + ai: { + order: 9, + result: { + target(player, target) { + if (player.storage.anying) return -1; + if (target.hp == 1) return 5; + if (player == target && player.countCards("h") > player.hp) return 5; return 2; - } + }, }, - threaten:2, - expose:0.2 - } + threaten: 2, + expose: 0.2, + }, }, - xinci:{ - enable:'phaseUse', - filterCard:{color:'black'}, - filter(event,player){ - return player.countCards('he',{color:'black'})>0; + xinci: { + enable: "phaseUse", + filterCard: { color: "black" }, + filter(event, player) { + return player.countCards("he", { color: "black" }) > 0; }, - position:'he', - usable:1, - mark:true, - intro:{ - content:'已进入暗影形态' + position: "he", + usable: 1, + mark: true, + intro: { + content: "已进入暗影形态", }, - check(card){ - return 9-get.value(card) + check(card) { + return 9 - get.value(card); }, - filterTarget:true, - content(){ + filterTarget: true, + content() { target.loseHp(); }, - ai:{ - order:9, - result:{ - target:-1 + ai: { + order: 9, + result: { + target: -1, }, - threaten:2, - expose:0.2 - } + threaten: 2, + expose: 0.2, + }, }, - anying:{ - unique:true, - enable:'phaseUse', - skillAnimation:'epic', - animationColor:'thunder', - derivation:'xinci', - filter(event,player){ - return !player.storage.anying&&player.countCards('he',{color:'black'})>0; + anying: { + unique: true, + enable: "phaseUse", + skillAnimation: "epic", + animationColor: "thunder", + derivation: "xinci", + filter(event, player) { + return !player.storage.anying && player.countCards("he", { color: "black" }) > 0; }, - filterCard:{color:'black'}, - position:'he', - check(card){ - return 5-get.value(card); + filterCard: { color: "black" }, + position: "he", + check(card) { + return 5 - get.value(card); }, - content(){ - player.storage.anying=true; - player.awakenSkill('anying'); - player.removeSkill('shengguang'); - player.addAdditionalSkill('anying','xinci'); + content() { + player.storage.anying = true; + player.awakenSkill("anying"); + player.removeSkill("shengguang"); + player.addAdditionalSkill("anying", "xinci"); }, - ai:{ - order:1, - result:{ - player(player){ - if(player.hasUnknown()) return 0; - return !game.hasPlayer(function(current){ - return get.attitude(player,current)>0&¤t.isDamaged()&¤t.hp<=2; + ai: { + order: 1, + result: { + player(player) { + if (player.hasUnknown()) return 0; + return !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + current.isDamaged() && + current.hp <= 2 + ); }); - } - } - } + }, + }, + }, }, - huanjue:{ - trigger:{player:'useCard1'}, - frequent:true, - filter(event,player){ - if(event._huanjue) return false; - if(event.targets.length!=1) return false; - var target=event.targets[0]; - for(var i=0;i0){ - if(eff2<=0) return 0; - return val2-val1; - } - else if(eff1<0){ - if(eff2>=0) return val2; + var eff1 = get.effect(trigger.targets[0], trigger.card, trigger.player, player); + var val1 = get.value(trigger.card, player, "raw"); + player.chooseButton(["幻觉", [list, "vcard"]]).ai = function (button) { + var card = { + suit: trigger.card.suit, + number: trigger.card.number, + name: button.link[2], + }; + var eff2 = get.effect(trigger.targets[0], card, trigger.player, player); + var val2 = get.value(card, player, "raw"); + if (eff1 > 0) { + if (eff2 <= 0) return 0; + return val2 - val1; + } else if (eff1 < 0) { + if (eff2 >= 0) return val2; return 0; - } - else if(eff1==0){ - if(eff2>0) return val2; + } else if (eff1 == 0) { + if (eff2 > 0) return val2; return 0; } }; - 'step 1' - if(result.bool){ - var stat=player.stat[player.stat.length-1].card; - if(stat[trigger.card.name]){ + "step 1"; + if (result.bool) { + var stat = player.stat[player.stat.length - 1].card; + if (stat[trigger.card.name]) { stat[trigger.card.name]--; } - var card=game.createCard({ - suit:trigger.card.suit||lib.suit.randomGet(), - number:trigger.card.number||Math.ceil(Math.random()*13), - name:result.links[0][2]} - ); - event.card=card; - game.log(player,'将',trigger.card,'变为',card); + var card = game.createCard({ + suit: trigger.card.suit || lib.suit.randomGet(), + number: trigger.card.number || Math.ceil(Math.random() * 13), + name: result.links[0][2], + }); + event.card = card; + game.log(player, "将", trigger.card, "变为", card); // if(!event.isMine()) game.delayx(); - trigger.card=get.autoViewAs(card); - trigger.cards=[card]; - game.cardsGotoOrdering(card).relatedEvent=trigger; - trigger._huanjue=true; - } - else{ + trigger.card = get.autoViewAs(card); + trigger.cards = [card]; + game.cardsGotoOrdering(card).relatedEvent = trigger; + trigger._huanjue = true; + } else { event.finish(); } - 'step 2' - player.$throw(event.card,null,null,true); - if(player==trigger.player){ - player.line(trigger.targets[0],'green'); - } - else{ - player.line(trigger.player,'green'); + "step 2"; + player.$throw(event.card, null, null, true); + if (player == trigger.player) { + player.line(trigger.targets[0], "green"); + } else { + player.line(trigger.player, "green"); } game.delayx(0.5); - 'step 3' - var stat=player.stat[player.stat.length-1].card; - if(!stat[trigger.card.name]){ - stat[trigger.card.name]=1; - } - else{ + "step 3"; + var stat = player.stat[player.stat.length - 1].card; + if (!stat[trigger.card.name]) { + stat[trigger.card.name] = 1; + } else { stat[trigger.card.name]++; } }, - draw(){ + draw() { player.draw(); }, - ai:{ - usedu:true - } + ai: { + usedu: true, + }, }, - huanjue_old:{ - trigger:{global:'useCard'}, - usable:1, - filter(event,player){ - if(event.targets.length!=1) return false; - var target=event.targets[0]; - if(event.player==target) return false; - if(player!=event.player&&player!=target) return false; - for(var i=0;i0; + mdzhoufu: { + enable: "phaseUse", + filterCard: { color: "black" }, + filter(event, player) { + return player.countCards("h", { color: "black" }) > 0; }, - filterTarget(card,player,target){ - return player!=target&&!target.hasSkill('mdzhoufu2'); + filterTarget(card, player, target) { + return player != target && !target.hasSkill("mdzhoufu2"); }, - prepare:'throw', - discard:false, - content(){ + prepare: "throw", + discard: false, + content() { target.$gain2(cards); - target.storage.mdzhoufu2=cards[0]; - target.addSkill('mdzhoufu2'); - target.storage.mdzhoufu3=player; - game.addVideo('storage',target,['mdzhoufu2',get.cardInfo(cards[0]),'card']); + target.storage.mdzhoufu2 = cards[0]; + target.addSkill("mdzhoufu2"); + target.storage.mdzhoufu3 = player; + game.addVideo("storage", target, ["mdzhoufu2", get.cardInfo(cards[0]), "card"]); ui.special.appendChild(cards[0]); }, - check(card){ - if(get.suit(card)=='spade'){ - return 6-get.value(card); + check(card) { + if (get.suit(card) == "spade") { + return 6 - get.value(card); } return -1; }, - ai:{ - tag:{ - rejudge:0.1, + ai: { + tag: { + rejudge: 0.1, }, - threaten:1.5, - expose:0.1, - order:10, - result:{ - target:-1 - } - } + threaten: 1.5, + expose: 0.1, + order: 10, + result: { + target: -1, + }, + }, }, - mdzhoufu2:{ - trigger:{player:'judge'}, - forced:true, - priority:10, - mark:'card', - content(){ - "step 0" + mdzhoufu2: { + trigger: { player: "judge" }, + forced: true, + priority: 10, + mark: "card", + content() { + "step 0"; player.storage.mdzhoufu2.discard(); player.$throw(player.storage.mdzhoufu2); - if(player.storage.mdzhoufu2.clone){ - player.storage.mdzhoufu2.clone.classList.add('thrownhighlight'); - game.addVideo('highlightnode',player,get.cardInfo(player.storage.mdzhoufu2)); + if (player.storage.mdzhoufu2.clone) { + player.storage.mdzhoufu2.clone.classList.add("thrownhighlight"); + game.addVideo("highlightnode", player, get.cardInfo(player.storage.mdzhoufu2)); } - if(player.storage.mdzhoufu3.isIn()){ - player.storage.mdzhoufu3.line(player,'green'); + if (player.storage.mdzhoufu3.isIn()) { + player.storage.mdzhoufu3.line(player, "green"); player.storage.mdzhoufu3.gain(player.judging[0]); player.storage.mdzhoufu3.$gain2(player.judging[0]); - } - else{ + } else { player.judging[0].discard(); game.delay(1.5); } - player.removeSkill('mdzhoufu2'); - "step 1" - player.judging[0]=player.storage.mdzhoufu2; + player.removeSkill("mdzhoufu2"); + "step 1"; + player.judging[0] = player.storage.mdzhoufu2; trigger.position.appendChild(player.storage.mdzhoufu2); // trigger.untrigger(); - game.log(player,'的判定牌改为',player.storage.mdzhoufu2); + game.log(player, "的判定牌改为", player.storage.mdzhoufu2); delete player.storage.mdzhoufu2; delete player.storage.mdzhoufu3; }, - intro:{ - content:'card' + intro: { + content: "card", }, }, - zuzhou_old:{ - trigger:{player:'damageEnd',source:'damageEnd'}, - check(event,player){ - var target=(player==event.player)?event.source:event.player; - return get.attitude(player,target)<0; + zuzhou_old: { + trigger: { player: "damageEnd", source: "damageEnd" }, + check(event, player) { + var target = player == event.player ? event.source : event.player; + return get.attitude(player, target) < 0; }, - filter(event,player){ - var target=(player==event.player)?event.source:event.player; + filter(event, player) { + var target = player == event.player ? event.source : event.player; return target.isAlive(); }, - prompt(event,player){ - var target=(player==event.player)?event.source:event.player; - return get.prompt('zuzhou',target); + prompt(event, player) { + var target = player == event.player ? event.source : event.player; + return get.prompt("zuzhou", target); }, - content(){ - "step 0" - event.target=(player==trigger.player)?trigger.source:trigger.player; - event.target.judge(function(card){ - return get.color(card)=='black'?-1:0; + content() { + "step 0"; + event.target = player == trigger.player ? trigger.source : trigger.player; + event.target.judge(function (card) { + return get.color(card) == "black" ? -1 : 0; }); - "step 1" - if(result.color=='black'){ + "step 1"; + if (result.color == "black") { event.target.loseHp(); } }, - ai:{ - expose:0.1, - threaten:1.3 - } - }, - xianzhi:{ - trigger:{global:'judgeBegin'}, - frequent:true, - filter(){ - return ui.cardPile.childNodes.length>1; + ai: { + expose: 0.1, + threaten: 1.3, }, - check(){ + }, + xianzhi: { + trigger: { global: "judgeBegin" }, + frequent: true, + filter() { + return ui.cardPile.childNodes.length > 1; + }, + check() { return false; }, - content(){ - 'step 0' - var str=''; - if(trigger.card) str=get.translation(trigger.card.viewAs||trigger.card.name); - else if(trigger.skill) str=get.translation(trigger.skill); - else str=get.translation(trigger.parent.name); + content() { + "step 0"; + var str = ""; + if (trigger.card) str = get.translation(trigger.card.viewAs || trigger.card.name); + else if (trigger.skill) str = get.translation(trigger.skill); + else str = get.translation(trigger.parent.name); - var cards=[ui.cardPile.childNodes[0],ui.cardPile.childNodes[1]]; - var att=get.attitude(player,trigger.player); - var delta=trigger.judge(ui.cardPile.childNodes[1])-trigger.judge(ui.cardPile.childNodes[0]); - player.chooseControl('调换顺序','cancel2', - ui.create.dialog('先知:'+get.translation(trigger.player)+'的'+str+'判定',cards,'hidden')).ai=function(){ - if(att*delta>0) return '调换顺序'; - else return 'cancel2'; + var cards = [ui.cardPile.childNodes[0], ui.cardPile.childNodes[1]]; + var att = get.attitude(player, trigger.player); + var delta = + trigger.judge(ui.cardPile.childNodes[1]) - trigger.judge(ui.cardPile.childNodes[0]); + player.chooseControl( + "调换顺序", + "cancel2", + ui.create.dialog( + "先知:" + get.translation(trigger.player) + "的" + str + "判定", + cards, + "hidden" + ) + ).ai = function () { + if (att * delta > 0) return "调换顺序"; + else return "cancel2"; }; - 'step 1' - if(result.control=='调换顺序'){ - var card=ui.cardPile.firstChild; + "step 1"; + if (result.control == "调换顺序") { + var card = ui.cardPile.firstChild; ui.cardPile.removeChild(card); - ui.cardPile.insertBefore(card,ui.cardPile.firstChild.nextSibling); - game.log(player,'调换了牌堆顶两张牌的顺序'); + ui.cardPile.insertBefore(card, ui.cardPile.firstChild.nextSibling); + game.log(player, "调换了牌堆顶两张牌的顺序"); } }, - ai:{ - expose:0.1, - tag:{ - rejudge:0.5 - } - } + ai: { + expose: 0.1, + tag: { + rejudge: 0.5, + }, + }, }, - jingxiang:{ - trigger:{player:'chooseToRespondBegin'}, - direct:true, - usable:1, + jingxiang: { + trigger: { player: "chooseToRespondBegin" }, + direct: true, + usable: 1, // alter:true, - filter(event,player){ - if(event.responded) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); + filter(event, player) { + if (event.responded) return false; + return game.hasPlayer(function (current) { + return current != player && current.countCards("h"); }); }, - content(){ - "step 0" - player.chooseTarget(get.prompt('jingxiang'),function(card,player,target){ - if(target==player) return false; - var nh=target.countCards('h'); - if(nh==0) return false; - if(get.is.altered('jingxiang')){ - return nh<=player.countCards('h'); + content() { + "step 0"; + player.chooseTarget(get.prompt("jingxiang"), function (card, player, target) { + if (target == player) return false; + var nh = target.countCards("h"); + if (nh == 0) return false; + if (get.is.altered("jingxiang")) { + return nh <= player.countCards("h"); } return true; - }).ai=function(target){ - return 1-get.attitude(player,target); + }).ai = function (target) { + return 1 - get.attitude(player, target); }; - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jingxiang',target); - event.target=target; - var cards=target.getCards('h'); - player.chooseCardButton('选择'+get.translation(target)+'的一张卡手牌打出',cards).filterButton=function(button){ + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jingxiang", target); + event.target = target; + var cards = target.getCards("h"); + player.chooseCardButton( + "选择" + get.translation(target) + "的一张卡手牌打出", + cards + ).filterButton = function (button) { return trigger.filterCard(button.link); - } - } - else{ + }; + } else { event.finish(); } - "step 2" - if(result.bool){ - game.log(player,'使用了',event.target,'的手牌'); + "step 2"; + if (result.bool) { + game.log(player, "使用了", event.target, "的手牌"); event.target.$throw(result.links); event.target.lose(result.links); trigger.untrigger(); - trigger.animate=false; - trigger.responded=true; + trigger.animate = false; + trigger.responded = true; result.buttons[0].link.remove(); - trigger.result={bool:true,card:result.buttons[0].link} - } - else{ + trigger.result = { bool: true, card: result.buttons[0].link }; + } else { player.storage.counttrigger.jingxiang--; } }, - ai:{ - respondShan:true, - effect:{ - target(card){ - if(get.tag(card,'respondShan')) return 0.4; - if(get.tag(card,'respondSha')) return 0.4; - } - } - }, - }, - wlianji:{ - trigger:{player:'phaseEnd'}, - frequent:true, - filter(event,player){ - return player.countUsed()>player.hp; - }, - content(){ - player.draw(2); - }, - init(player){player.storage.jingce=true}, - intro:{ - content(storage,player){ - if(_status.currentPhase==player) return '已使用'+player.countUsed()+'张牌'; - } - } - }, - mengun:{ - trigger:{global:'useCardToBefore'}, - priority:12, - filter(event,player){ - if(event.player==player) return false; - if(_status.currentPhase!=event.player) return false; - if(event.player.hasSkill('mengun2')) return false; - if(get.itemtype(event.card)!='card') return false; - if(!player.countCards('h',{suit:get.suit(event.card)})) return false; - return get.type(event.card)=='basic'; - }, - direct:true, - content(){ - "step 0" - var val=get.value(trigger.card); - var suit=get.suit(trigger.card); - var eff=get.effect(trigger.target,trigger.card,trigger.player,player); - var next=player.chooseToDiscard('是否对'+get.translation(trigger.player)+'使用的'+get.translation(trigger.card)+'发动【闷棍】?',function(card){ - return get.suit(card)==suit; - }); - next.logSkill=['mengun',trigger.player]; - next.ai=function(card){ - if(eff>=0) return 0; - return Math.min(8,1+val)-get.value(card); - } - "step 1" - if(result.bool){ - game.log(trigger.player,'收回了',trigger.cards); - trigger.cancel(); - game.delay(); - } - else{ - event.finish(); - } - "step 2" - trigger.player.$gain2(trigger.cards); - trigger.player.gain(trigger.cards); - trigger.player.storage.mengun2=trigger.cards[0]; - game.addVideo('storage',player,['mengun2',get.cardInfo(trigger.cards[0]),'card']); - trigger.player.addTempSkill('mengun2','phaseEnd'); - }, - ai:{ - expose:0.2 - } - }, - mengun2:{ - mark:'card', - mod:{ - cardEnabled(card,player){ - if(card==player.storage.mengun2) return false; + ai: { + respondShan: true, + effect: { + target(card) { + if (get.tag(card, "respondShan")) return 0.4; + if (get.tag(card, "respondSha")) return 0.4; + }, }, }, - intro:{ - content:'card', - onunmark(storage,player){ - delete player.storage.mengun2; - } + }, + wlianji: { + trigger: { player: "phaseEnd" }, + frequent: true, + filter(event, player) { + return player.countUsed() > player.hp; + }, + content() { + player.draw(2); + }, + init(player) { + player.storage.jingce = true; + }, + intro: { + content(storage, player) { + if (_status.currentPhase == player) return "已使用" + player.countUsed() + "张牌"; + }, }, }, - jianren:{ - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.getEquip(1)?true:false; + mengun: { + trigger: { global: "useCardToBefore" }, + priority: 12, + filter(event, player) { + if (event.player == player) return false; + if (_status.currentPhase != event.player) return false; + if (event.player.hasSkill("mengun2")) return false; + if (get.itemtype(event.card) != "card") return false; + if (!player.countCards("h", { suit: get.suit(event.card) })) return false; + return get.type(event.card) == "basic"; }, - filterCard(card,player){ - return card==player.getEquip(1); + direct: true, + content() { + "step 0"; + var val = get.value(trigger.card); + var suit = get.suit(trigger.card); + var eff = get.effect(trigger.target, trigger.card, trigger.player, player); + var next = player.chooseToDiscard( + "是否对" + + get.translation(trigger.player) + + "使用的" + + get.translation(trigger.card) + + "发动【闷棍】?", + function (card) { + return get.suit(card) == suit; + } + ); + next.logSkill = ["mengun", trigger.player]; + next.ai = function (card) { + if (eff >= 0) return 0; + return Math.min(8, 1 + val) - get.value(card); + }; + "step 1"; + if (result.bool) { + game.log(trigger.player, "收回了", trigger.cards); + trigger.cancel(); + game.delay(); + } else { + event.finish(); + } + "step 2"; + trigger.player.$gain2(trigger.cards); + trigger.player.gain(trigger.cards); + trigger.player.storage.mengun2 = trigger.cards[0]; + game.addVideo("storage", player, ["mengun2", get.cardInfo(trigger.cards[0]), "card"]); + trigger.player.addTempSkill("mengun2", "phaseEnd"); }, - position:'e', - filterTarget(card,player,target){ - return target!=player; + ai: { + expose: 0.2, }, - selectCard:-1, - selectTarget:-1, - content(){ + }, + mengun2: { + mark: "card", + mod: { + cardEnabled(card, player) { + if (card == player.storage.mengun2) return false; + }, + }, + intro: { + content: "card", + onunmark(storage, player) { + delete player.storage.mengun2; + }, + }, + }, + jianren: { + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.getEquip(1) ? true : false; + }, + filterCard(card, player) { + return card == player.getEquip(1); + }, + position: "e", + filterTarget(card, player, target) { + return target != player; + }, + selectCard: -1, + selectTarget: -1, + content() { target.damage(); }, - ai:{ - order:9, - result:{ - target(player,target){ - return get.damageEffect(target,player,target); - } - } - } - }, - jihuo:{ - trigger:{player:'phaseAfter'}, - filter(event,player){ - return player.countCards('h')>0&&event.skill!='jihuo'; + ai: { + order: 9, + result: { + target(player, target) { + return get.damageEffect(target, player, target); + }, + }, }, - direct:true, - priority:-50, - content(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('jihuo')); - next.ai=get.unuseful2; - next.logSkill='jihuo'; - "step 1" - if(result.bool){ + }, + jihuo: { + trigger: { player: "phaseAfter" }, + filter(event, player) { + return player.countCards("h") > 0 && event.skill != "jihuo"; + }, + direct: true, + priority: -50, + content() { + "step 0"; + var next = player.chooseToDiscard(get.prompt("jihuo")); + next.ai = get.unuseful2; + next.logSkill = "jihuo"; + "step 1"; + if (result.bool) { player.insertPhase(); } }, - ai:{ - threaten:1.2 - } + ai: { + threaten: 1.2, + }, }, - tzhenji:{ - trigger:{player:'discardAfter'}, - direct:true, - filter(event,player){ - if(player.hasSkill('tzhenji2')){ + tzhenji: { + trigger: { player: "discardAfter" }, + direct: true, + filter(event, player) { + if (player.hasSkill("tzhenji2")) { return false; } - if(event.cards){ - for(var i=0;i0; - return get.damageEffect(target,player,player,'thunder')-(bool?1:0); + player.chooseTarget(get.prompt("tzhenji")).ai = function (target) { + var bool = get.attitude(player, target) > 0; + return get.damageEffect(target, player, player, "thunder") - (bool ? 1 : 0); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { game.delay(0.5); - var target=result.targets[0]; - player.logSkill('tzhenji',target,'thunder'); - var cs=target.getCards('he'); - if(cs.length){ + var target = result.targets[0]; + player.logSkill("tzhenji", target, "thunder"); + var cs = target.getCards("he"); + if (cs.length) { target.discard(cs.randomGet()); } - target.damage('thunder'); - player.addTempSkill('tzhenji2'); + target.damage("thunder"); + player.addTempSkill("tzhenji2"); } }, - ai:{ - threaten:1.2, - expose:0.3, - effect:{ - target(card,player,target){ - if(get.tag(card,'loseCard')&&target.countCards('he')){ + ai: { + threaten: 1.2, + expose: 0.3, + effect: { + target(card, player, target) { + if (get.tag(card, "loseCard") && target.countCards("he")) { return 0.7; } - } + }, }, - } - }, - tzhenji2:{}, - tzhenji_old:{ - trigger:{player:['useCard','respondEnd']}, - filter(event){ - return get.suit(event.card)=='spade'; }, - direct:true, - content(){ + }, + tzhenji2: {}, + tzhenji_old: { + trigger: { player: ["useCard", "respondEnd"] }, + filter(event) { + return get.suit(event.card) == "spade"; + }, + direct: true, + content() { "step 0"; - player.chooseTarget(get.prompt('tzhenji_old')).ai=function(target){ - return get.damageEffect(target,player,player,'thunder')-1; + player.chooseTarget(get.prompt("tzhenji_old")).ai = function (target) { + return get.damageEffect(target, player, player, "thunder") - 1; }; - "step 1" - if(result.bool){ - player.logSkill('tzhenji',result.targets,'thunder'); - event.target=result.targets[0]; + "step 1"; + if (result.bool) { + player.logSkill("tzhenji", result.targets, "thunder"); + event.target = result.targets[0]; event.target.judge(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.color=='red'){ - event.target.damage('fire'); - } - else{ - event.target.damage('thunder'); - var cs=event.target.getCards('he'); - if(cs.length){ + "step 2"; + if (result.color == "red") { + event.target.damage("fire"); + } else { + event.target.damage("thunder"); + var cs = event.target.getCards("he"); + if (cs.length) { event.target.discard(cs.randomGet()); } - cs=player.getCards('he'); - if(cs.length){ + cs = player.getCards("he"); + if (cs.length) { player.discard(cs.randomGet()); } } }, - ai:{ - expose:0.2, - threaten:1.2, - effect_old:{ - target(card,player,target){ - if(get.tag(card,'respondShan')){ - var hastarget=game.hasPlayer(function(current){ - return get.attitude(player,current)<0; + ai: { + expose: 0.2, + threaten: 1.2, + effect_old: { + target(card, player, target) { + if (get.tag(card, "respondShan")) { + var hastarget = game.hasPlayer(function (current) { + return get.attitude(player, current) < 0; }); - var ns=target.countCards('h','shan'); - var nh=target.countCards('h'); - if(ns>1){ - return [0,hastarget?1:0]; + var ns = target.countCards("h", "shan"); + var nh = target.countCards("h"); + if (ns > 1) { + return [0, hastarget ? 1 : 0]; } - if(ns&&nh>=2){ - return [0,0]; + if (ns && nh >= 2) { + return [0, 0]; } - if(nh>3){ - return [0,0]; + if (nh > 3) { + return [0, 0]; } - if(nh==0){ + if (nh == 0) { return 1.5; } - return [1,0.05]; + return [1, 0.05]; } - } - } - } + }, + }, + }, }, - tuteng_s:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - filter(event,player){ - var rand=['tuteng1','tuteng2','tuteng3','tuteng4']; - for(var i=0;i=3){ + if (rand2.length >= 3) { player.removeSkill(rand2.randomGet()); } - player.addSkill(rand.randomGet('tuteng1','tuteng3')); + player.addSkill(rand.randomGet("tuteng1", "tuteng3")); + }, + ai: { + threaten: 2, }, - ai:{ - threaten:2 - } }, - tuteng:{ - enable:'phaseUse', - usable:1, - unique:true, - direct:true, - delay:0, - init(){ - for(var i=1;i<=8;i++){ - lib.translate['tuteng'+i+'_info']=lib.skill['tuteng'+i].intro.content; + tuteng: { + enable: "phaseUse", + usable: 1, + unique: true, + direct: true, + delay: 0, + init() { + for (var i = 1; i <= 8; i++) { + lib.translate["tuteng" + i + "_info"] = lib.skill["tuteng" + i].intro.content; } }, - position:'he', - filter(event,player){ - if(player.storage.tuteng_awake) return true; - var rand=['tuteng1','tuteng2','tuteng3','tuteng4']; - for(var i=0;i1||rand2.length>=4)){ - var dialog=ui.create.dialog(); - for(var i=0;i 1 || rand2.length >= 4)) { + var dialog = ui.create.dialog(); + for (var i = 0; i < rand.length; i++) { + randx[i] = ["", "", rand[i]]; } - for(var i=0;i=4){ - dialog.add('替换一个已有图腾'); - dialog.add([rand2x,'vcard']); - player.chooseButton(dialog,2,true).filterButton=function(button){ - if(ui.selected.buttons.length){ - var current=ui.selected.buttons[0].name; - if(rand.includes(current)){ + dialog.add("选择一个图腾"); + dialog.add([randx, "vcard"]); + if (rand2.length >= 4) { + dialog.add("替换一个已有图腾"); + dialog.add([rand2x, "vcard"]); + player.chooseButton(dialog, 2, true).filterButton = function (button) { + if (ui.selected.buttons.length) { + var current = ui.selected.buttons[0].name; + if (rand.includes(current)) { return rand2.includes(button.name); - } - else{ + } else { return rand.includes(button.name); } } return true; }; + } else { + player.chooseButton(dialog, true); } - else{ - player.chooseButton(dialog,true); - } - for(var i=0;i1){ - rand.remove('tuteng1'); + } else { + if (player.hp < player.maxHp && rand.includes("tuteng1")) { + player.addSkill("tuteng1"); + } else { + if (rand.length > 1) { + rand.remove("tuteng1"); } player.addSkill(rand.randomGet()); } @@ -8114,2049 +8573,2182 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.delay(); event.finish(); } - } - else{ + } else { event.finish(); } - 'step 1' - if(result.buttons.length==1){ + "step 1"; + if (result.buttons.length == 1) { player.addSkill(result.buttons[0].name); - } - else if(result.buttons.length==2){ - var skill1=result.buttons[0].name; - var skill2=result.buttons[1].name; - if(player.hasSkill(skill1)){ + } else if (result.buttons.length == 2) { + var skill1 = result.buttons[0].name; + var skill2 = result.buttons[1].name; + if (player.hasSkill(skill1)) { player.removeSkill(skill1); player.addSkill(skill2); - } - else{ + } else { player.removeSkill(skill2); player.addSkill(skill1); } } }, - ai:{ - order:11, - result:{ - player:1 + ai: { + order: 11, + result: { + player: 1, }, effect: { - player(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return; + player(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return; return 1.2; } }, }, - threaten:2 + threaten: 2, }, - group:'tuteng_lose' + group: "tuteng_lose", }, - zuling:{ - skillAnimation:'epic', - animationColor:'thunder', - trigger:{player:'phaseBegin'}, - forced:true, - unique:true, - filter(event,player){ - if(!player.storage.tuteng_awake){ - var rand=['tuteng1','tuteng2','tuteng3','tuteng4', - 'tuteng5','tuteng6','tuteng7','tuteng8']; - var num=0; - for(var i=0;i=3){ + zuling: { + skillAnimation: "epic", + animationColor: "thunder", + trigger: { player: "phaseBegin" }, + forced: true, + unique: true, + filter(event, player) { + if (!player.storage.tuteng_awake) { + var rand = [ + "tuteng1", + "tuteng2", + "tuteng3", + "tuteng4", + "tuteng5", + "tuteng6", + "tuteng7", + "tuteng8", + ]; + var num = 0; + for (var i = 0; i < player.skills.length; i++) { + if (rand.includes(player.skills[i])) num++; + if (num >= 3) { return true; } } } return false; }, - content(){ - player.storage.tuteng_awake=true; + content() { + player.storage.tuteng_awake = true; player.loseMaxHp(); - player.awakenSkill('zuling'); - } + player.awakenSkill("zuling"); + }, }, - huanfeng:{ - skillAnimation:'epic', - animationColor:'thunder', - trigger:{player:'phaseBeginStart'}, - forced:true, - unique:true, - filter(event,player){ + huanfeng: { + skillAnimation: "epic", + animationColor: "thunder", + trigger: { player: "phaseBeginStart" }, + forced: true, + unique: true, + filter(event, player) { // if(player.storage.huanfeng_awake) return false; - var skills=['tuteng1','tuteng2','tuteng3','tuteng4']; - for(var i=0;i0; + trigger: { player: "damageBegin" }, + forced: true, + filter(event) { + return event.num > 0; }, - content(){ + content() { trigger.num--; - player.removeSkill('tuteng3'); + player.removeSkill("tuteng3"); }, }, - tuteng4:{ - mark:'image', - nopop:true, - intro:{ - content:'在你的回合内,你的锦囊牌造成的首次伤害+1' + tuteng4: { + mark: "image", + nopop: true, + intro: { + content: "在你的回合内,你的锦囊牌造成的首次伤害+1", }, - trigger:{source:'damageBegin'}, - forced:true, - usable:1, - filter(event,player){ - return _status.currentPhase==player&&event.card&&get.type(event.card)=='trick'&&event.notLink(); + trigger: { source: "damageBegin" }, + forced: true, + usable: 1, + filter(event, player) { + return ( + _status.currentPhase == player && + event.card && + get.type(event.card) == "trick" && + event.notLink() + ); }, - content(){ + content() { trigger.num++; - } - }, - tuteng5:{ - mark:'image', - nopop:true, - intro:{ - content:'结束阶段,你摸一张牌' }, - trigger:{player:'phaseEnd'}, - forced:true, - content(){ + }, + tuteng5: { + mark: "image", + nopop: true, + intro: { + content: "结束阶段,你摸一张牌", + }, + trigger: { player: "phaseEnd" }, + forced: true, + content() { player.draw(); - } + }, }, - tuteng6:{ - mark:'image', - nopop:true, - intro:{ - content:'在你的回合内,你的杀造成的首次伤害+1' + tuteng6: { + mark: "image", + nopop: true, + intro: { + content: "在你的回合内,你的杀造成的首次伤害+1", }, - trigger:{source:'damageBegin'}, - forced:true, - filter(event,player){ - return _status.currentPhase==player&&event.card&&event.card.name=='sha'&&event.notLink(); + trigger: { source: "damageBegin" }, + forced: true, + filter(event, player) { + return ( + _status.currentPhase == player && + event.card && + event.card.name == "sha" && + event.notLink() + ); }, - usable:1, - content(){ + usable: 1, + content() { trigger.num++; - } - }, - tuteng7:{ - mark:'image', - nopop:true, - intro:{ - content:'结束阶段,你令一名其他角色回复1点体力' }, - trigger:{player:'phaseEnd'}, - direct:true, - filter(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged(); + }, + tuteng7: { + mark: "image", + nopop: true, + intro: { + content: "结束阶段,你令一名其他角色回复1点体力", + }, + trigger: { player: "phaseEnd" }, + direct: true, + filter(event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isDamaged(); }); }, - content(){ - 'step 0' - player.chooseTarget('活力图腾:令一名其他角色回复1点体力',function(card,player,target){ - return target!=player&&target.hp=player.hp) return -1; - if(player.hp<=2){ - if(player.hp==2&&nh==0) return 1; + ai: { + order: 4, + result: { + player(player) { + var nh = player.countCards("h"); + if (nh >= player.hp) return -1; + if (player.hp <= 2) { + if (player.hp == 2 && nh == 0) return 1; return -1; } return 1; - } + }, }, - effect:{ - target(card){ - if(get.tag(card,'damage')||get.tag(card,'loseHp')){ + effect: { + target(card) { + if (get.tag(card, "damage") || get.tag(card, "loseHp")) { return 1.5; } - } + }, }, - threaten:1.2 - } - }, - fenliu2:{ - mod:{ - maxHandcard(player,num){ - return num+1; - } - } - }, - hongxi:{ - trigger:{global:'dieAfter'}, - filter(event,player){ - return player.hp{ - var type=get.type(cards[0],'trick'),name=cards[0].name,card2=get.cardPile(card=>get.type(card,'trick')==type&&card.name!=name); - if(!card2) card2=get.cardPile(card=>get.type(card,'trick')==type); - if(card2) player.gain(card2,'draw'); - else player.draw().log=false; + fullimage: true, + type: "hsfashu", + vanish: true, + derivation: "hs_siwangxianzhi", + filterTarget: true, + content() { + "step 0"; + target.chooseCard("h", true, "重铸一张手牌", lib.filter.cardRecastable); + "step 1"; + if (result.bool && result.cards.length) { + target.recast(result.cards, null, (player, cards) => { + var type = get.type(cards[0], "trick"), + name = cards[0].name, + card2 = get.cardPile( + (card) => get.type(card, "trick") == type && card.name != name + ); + if (!card2) card2 = get.cardPile((card) => get.type(card, "trick") == type); + if (card2) player.gain(card2, "draw"); + else player.draw().log = false; }); - var clone=game.createCard(card); - player.gain(clone,'gain2'); - clone.classList.add('glow'); - clone._destroy='yibian'; - player.addTempSkill('buwendingyibian_lose','phaseBegin'); - if(target.hasSkill('buwendingyibian_ai1')){ - target.addTempSkill('buwendingyibian_ai2'); - } - else{ - target.addTempSkill('buwendingyibian_ai1'); + var clone = game.createCard(card); + player.gain(clone, "gain2"); + clone.classList.add("glow"); + clone._destroy = "yibian"; + player.addTempSkill("buwendingyibian_lose", "phaseBegin"); + if (target.hasSkill("buwendingyibian_ai1")) { + target.addTempSkill("buwendingyibian_ai2"); + } else { + target.addTempSkill("buwendingyibian_ai1"); } } }, - ai:{ - wuxie(){ + ai: { + wuxie() { return 0; }, - value(card){ - if(card._destroy) return 0; + value(card) { + if (card._destroy) return 0; return 5; }, - useful:0, - result:{ - target(player,target){ - if(target==player&&target.countCards('h',function(card){ - return card.name!='hsfashu_buwendingyibian'&&get.value(card)<=1; - })){ + useful: 0, + result: { + target(player, target) { + if ( + target == player && + target.countCards("h", function (card) { + return card.name != "hsfashu_buwendingyibian" && get.value(card) <= 1; + }) + ) { return 10; } - var num=target.countCards('h'); - var num0=num; - if(target==player) num--; - if(target.hasSkill('buwendingyibian_ai1')) num/=2; - if(target.hasSkill('buwendingyibian_ai2')) num/=2; - if(num<0){ - if(num0>0) return 0.1; + var num = target.countCards("h"); + var num0 = num; + if (target == player) num--; + if (target.hasSkill("buwendingyibian_ai1")) num /= 2; + if (target.hasSkill("buwendingyibian_ai2")) num /= 2; + if (num < 0) { + if (num0 > 0) return 0.1; return 0; } return Math.sqrt(num); - } + }, }, - order:4 - } + order: 4, + }, }, - hstianqi_dalian:{ - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - fullimage:true, - vanish:true, - destroy:'hstianqi', - derivation:'hs_heifengqishi', - skills:['hstianqi_dalian'], - ai:{ - equipValue:10 - } + hstianqi_dalian: { + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + fullimage: true, + vanish: true, + destroy: "hstianqi", + derivation: "hs_heifengqishi", + skills: ["hstianqi_dalian"], + ai: { + equipValue: 10, + }, }, - hstianqi_shali:{ - type:'equip', - subtype:'equip2', - distance:{attackFrom:-1}, - fullimage:true, - vanish:true, - destroy:'hstianqi', - derivation:'hs_heifengqishi', - skills:['hstianqi_shali'], - ai:{ - equipValue:10 - } + hstianqi_shali: { + type: "equip", + subtype: "equip2", + distance: { attackFrom: -1 }, + fullimage: true, + vanish: true, + destroy: "hstianqi", + derivation: "hs_heifengqishi", + skills: ["hstianqi_shali"], + ai: { + equipValue: 10, + }, }, - hstianqi_nazigelin:{ - type:'equip', - subtype:'equip4', - distance:{globalFrom:-1}, - fullimage:true, - vanish:true, - destroy:'hstianqi', - derivation:'hs_heifengqishi', - onEquip(){ + hstianqi_nazigelin: { + type: "equip", + subtype: "equip4", + distance: { globalFrom: -1 }, + fullimage: true, + vanish: true, + destroy: "hstianqi", + derivation: "hs_heifengqishi", + onEquip() { player.changeHujia(); }, - equipDelay:false, - ai:{ - equipValue:10 - } + equipDelay: false, + ai: { + equipValue: 10, + }, }, - hstianqi_suolasi:{ - type:'equip', - subtype:'equip3', - distance:{globalTo:1}, - fullimage:true, - vanish:true, - destroy:'hstianqi', - derivation:'hs_heifengqishi', - onLose(){ - if(player.isDamaged()){ - player.logSkill('hstianqi_suolasi'); + hstianqi_suolasi: { + type: "equip", + subtype: "equip3", + distance: { globalTo: 1 }, + fullimage: true, + vanish: true, + destroy: "hstianqi", + derivation: "hs_heifengqishi", + onLose() { + if (player.isDamaged()) { + player.logSkill("hstianqi_suolasi"); player.recover(); } }, - loseDelay:false, - ai:{ - equipValue:10 - } - }, - hsjixie_zhadan:{ - enable:true, - fullimage:true, - type:'hsjixie', - vanish:true, - derivation:'hs_pengpeng', - filterTarget(card,player,target){ - return target==player; + loseDelay: false, + ai: { + equipValue: 10, }, - modTarget:true, - selectTarget:-1, - cardcolor:'black', - content(){ - var targets=target.getEnemies(); - if(targets.length){ - var target2=targets.randomGet(); - player.line(target2,'fire'); + }, + hsjixie_zhadan: { + enable: true, + fullimage: true, + type: "hsjixie", + vanish: true, + derivation: "hs_pengpeng", + filterTarget(card, player, target) { + return target == player; + }, + modTarget: true, + selectTarget: -1, + cardcolor: "black", + content() { + var targets = target.getEnemies(); + if (targets.length) { + var target2 = targets.randomGet(); + player.line(target2, "fire"); target2.addExpose(0.2); - target2.damage('fire'); + target2.damage("fire"); } }, - ai:{ - value:8, - result:{ - target:1 + ai: { + value: 8, + result: { + target: 1, }, - order:4, - } - }, - hsqizhou_feng:{ - type:'hsqizhou', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_kalimosi', - filterTarget(card,player,target){ - return target==player; + order: 4, }, - selectTarget:-1, - content(){ - 'step 0' - event.list=target.getEnemies().sortBySeat(); - player.line(event.list,'thunder'); - 'step 1' - if(event.list.length){ - event.current=event.list.shift(); - event.current.addTempClass('target'); - var next=event.current.chooseToRespond({name:'sha'}); - next.ai=function(card){ - if(get.damageEffect(event.current,player,event.current,'thunder')>=0) return 0; - if(player.hasSkillTag('notricksource')) return 0; - if(event.current.hasSkillTag('notrick')) return 0; - return 11-get.value(card); + }, + hsqizhou_feng: { + type: "hsqizhou", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_kalimosi", + filterTarget(card, player, target) { + return target == player; + }, + selectTarget: -1, + content() { + "step 0"; + event.list = target.getEnemies().sortBySeat(); + player.line(event.list, "thunder"); + "step 1"; + if (event.list.length) { + event.current = event.list.shift(); + event.current.addTempClass("target"); + var next = event.current.chooseToRespond({ name: "sha" }); + next.ai = function (card) { + if (get.damageEffect(event.current, player, event.current, "thunder") >= 0) + return 0; + if (player.hasSkillTag("notricksource")) return 0; + if (event.current.hasSkillTag("notrick")) return 0; + return 11 - get.value(card); }; - next.autochoose=lib.filter.autoRespondSha; - } - else{ + next.autochoose = lib.filter.autoRespondSha; + } else { event.finish(); } - 'step 2' - if(!result.bool){ - event.current.damage('thunder'); + "step 2"; + if (!result.bool) { + event.current.damage("thunder"); } game.delayx(0.5); - 'step 3' + "step 3"; event.goto(1); }, - ai:{ - order:8, - useful:[5,1], - value:8, - result:{ - target:1, + ai: { + order: 8, + useful: [5, 1], + value: 8, + result: { + target: 1, }, - } + }, }, - hsqizhou_shui:{ - type:'hsqizhou', - fullimage:true, - vanish:true, - enable(event,player){ + hsqizhou_shui: { + type: "hsqizhou", + fullimage: true, + vanish: true, + enable(event, player) { return player.isDamaged(); }, - derivation:'hs_kalimosi', - filterTarget(card,player,target){ - return target==player; + derivation: "hs_kalimosi", + filterTarget(card, player, target) { + return target == player; }, - selectTarget:-1, - content(){ + selectTarget: -1, + content() { target.recover(2); }, - ai:{ - order:8, - useful:[5,1], - value:8, - tag:{ - recover:1 + ai: { + order: 8, + useful: [5, 1], + value: 8, + tag: { + recover: 1, }, - result:{ - target:2, + result: { + target: 2, }, - } - }, - hsqizhou_huo:{ - type:'hsqizhou', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_kalimosi', - filterTarget:true, - content(){ - target.damage('fire'); }, - ai:{ - order:5, - result:{ - target:-1, - }, - useful:[5,1], - value:8, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - } - } }, - hsqizhou_tu:{ - type:'hsqizhou', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_kalimosi', - filterTarget(card,player,target){ - return target!=player + hsqizhou_huo: { + type: "hsqizhou", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_kalimosi", + filterTarget: true, + content() { + target.damage("fire"); }, - selectTarget:[1,Infinity], - content(){ + ai: { + order: 5, + result: { + target: -1, + }, + useful: [5, 1], + value: 8, + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + }, + }, + }, + hsqizhou_tu: { + type: "hsqizhou", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_kalimosi", + filterTarget(card, player, target) { + return target != player; + }, + selectTarget: [1, Infinity], + content() { target.changeHujia(); }, - ai:{ - order:8, - useful:[5,1], - value:8, - result:{ - target:1, + ai: { + order: 8, + useful: [5, 1], + value: 8, + result: { + target: 1, }, - } - }, - hsqingyu_feibiao:{ - type:'hsqingyu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_aya', - filterTarget(card,player,target){ - return target.countCards('he')>0; }, - content(){ - var cards=[]; - var hs=target.getCards('h'); - var es=target.getCards('e'); - if(hs.length) cards.push(hs.randomGet()); - if(es.length) cards.push(es.randomGet()); + }, + hsqingyu_feibiao: { + type: "hsqingyu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_aya", + filterTarget(card, player, target) { + return target.countCards("he") > 0; + }, + content() { + var cards = []; + var hs = target.getCards("h"); + var es = target.getCards("e"); + if (hs.length) cards.push(hs.randomGet()); + if (es.length) cards.push(es.randomGet()); target.discard(cards); }, - ai:{ - order:8, - useful:3, - value:6, - result:{ - target(player,target){ - var num=0; - if(target.countCards('h')) num--; - if(target.countCards('e')) num--; + ai: { + order: 8, + useful: 3, + value: 6, + result: { + target(player, target) { + var num = 0; + if (target.countCards("h")) num--; + if (target.countCards("e")) num--; return num; }, }, - } + }, }, - hsqingyu_zhanfang:{ - type:'hsqingyu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_aya', - filterTarget:true, - content(){ + hsqingyu_zhanfang: { + type: "hsqingyu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_aya", + filterTarget: true, + content() { target.gainMaxHp(); target.draw(); }, - ai:{ - order:5, - useful:3, - value:4, - result:{ - target(player,target){ - if(target.hp==target.maxHp){ - if(target.maxHp<3) return 2; - if(target.maxHp==3) return 1.5; + ai: { + order: 5, + useful: 3, + value: 4, + result: { + target(player, target) { + if (target.hp == target.maxHp) { + if (target.maxHp < 3) return 2; + if (target.maxHp == 3) return 1.5; return 1.2; } return 1; }, }, - } + }, }, - hsqingyu_hufu:{ - type:'hsqingyu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_aya', - filterTarget:true, - content(){ + hsqingyu_hufu: { + type: "hsqingyu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_aya", + filterTarget: true, + content() { target.changeHujia(); }, - ai:{ - order:5, - useful:3, - value:6, - result:{ - target(player,target){ - return 2/Math.max(1,Math.sqrt(target.hp)); + ai: { + order: 5, + useful: 3, + value: 6, + result: { + target(player, target) { + return 2 / Math.max(1, Math.sqrt(target.hp)); }, }, - } - }, - hsqingyu_shandian:{ - type:'hsqingyu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_aya', - filterTarget:true, - content(){ - target.damage('thunder'); }, - ai:{ - order:5, - result:{ - target:-1, - }, - useful:5, - value:8, - tag:{ - damage:1, - thunderDamage:1, - natureDamage:1, - } - } }, - hsqingyu_zhao:{ - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - fullimage:true, - vanish:true, - derivation:'hs_aya', - onEquip(){ + hsqingyu_shandian: { + type: "hsqingyu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_aya", + filterTarget: true, + content() { + target.damage("thunder"); + }, + ai: { + order: 5, + result: { + target: -1, + }, + useful: 5, + value: 8, + tag: { + damage: 1, + thunderDamage: 1, + natureDamage: 1, + }, + }, + }, + hsqingyu_zhao: { + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + fullimage: true, + vanish: true, + derivation: "hs_aya", + onEquip() { player.draw(); }, - ai:{ - order:9, - useful:5, - value:4 - } + ai: { + order: 9, + useful: 5, + value: 4, + }, }, - hsdusu_xueji:{ - type:'hsdusu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_xialikeer', - filterTarget(card,player,target){ - return target.countCards('e')>0; + hsdusu_xueji: { + type: "hsdusu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_xialikeer", + filterTarget(card, player, target) { + return target.countCards("e") > 0; }, - content(){ - target.discard(target.getCards('e').randomGets(2)); + content() { + target.discard(target.getCards("e").randomGets(2)); }, - ai:{ - order:5, - result:{ - target(player,target){ - if(target.hasSkillTag('noe')) return 0; - if(target.countCards('e')>1) return -1.5; + ai: { + order: 5, + result: { + target(player, target) { + if (target.hasSkillTag("noe")) return 0; + if (target.countCards("e") > 1) return -1.5; return -1; }, }, - value:5, - } - }, - hsdusu_kuyecao:{ - type:'hsdusu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_xialikeer', - filterTarget(card,player,target){ - return !target.hasSkill('qianxing'); + value: 5, }, - content(){ + }, + hsdusu_kuyecao: { + type: "hsdusu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_xialikeer", + filterTarget(card, player, target) { + return !target.hasSkill("qianxing"); + }, + content() { target.tempHide(); }, - ai:{ - order:2, - result:{ - target(player,target){ - if(player!=target&&get.distance(player,target,'absolute')<=1) return 0; - var num=1; - if(target==player){ - num=1.5; + ai: { + order: 2, + result: { + target(player, target) { + if (player != target && get.distance(player, target, "absolute") <= 1) return 0; + var num = 1; + if (target == player) { + num = 1.5; } - if(target.hp==1) return 2*num; - if(target.hp==2&&target.countCards('h')<=2) return 1.2*num; + if (target.hp == 1) return 2 * num; + if (target.hp == 2 && target.countCards("h") <= 2) return 1.2 * num; return num; - } + }, }, - value:5, - } - }, - hsdusu_huangxuecao:{ - type:'hsdusu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_xialikeer', - filterTarget(card,player,target){ - return target==player; + value: 5, }, - selectTarget:-1, - modTarget:true, - content(){ + }, + hsdusu_huangxuecao: { + type: "hsdusu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_xialikeer", + filterTarget(card, player, target) { + return target == player; + }, + selectTarget: -1, + modTarget: true, + content() { target.draw(2); }, - ai:{ - order:9, - result:{ - target:1, + ai: { + order: 9, + result: { + target: 1, }, - value:10, - } - }, - hsdusu_huoyanhua:{ - type:'hsdusu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_xialikeer', - range:{attack:1}, - filterTarget:true, - content(){ - target.damage('fire'); + value: 10, }, - ai:{ - order:5, - result:{ - target:-1, + }, + hsdusu_huoyanhua: { + type: "hsdusu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_xialikeer", + range: { attack: 1 }, + filterTarget: true, + content() { + target.damage("fire"); + }, + ai: { + order: 5, + result: { + target: -1, }, - useful:5, - value:8, - tag:{ - damage:1, - fireDamage:1, - natureDamage:1, - } - } + useful: 5, + value: 8, + tag: { + damage: 1, + fireDamage: 1, + natureDamage: 1, + }, + }, }, - hsdusu_shinancao:{ - type:'hsdusu', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_xialikeer', - filterTarget(card,player,target){ - return !target.hasSkill('hsdusu_shinancao'); + hsdusu_shinancao: { + type: "hsdusu", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_xialikeer", + filterTarget(card, player, target) { + return !target.hasSkill("hsdusu_shinancao"); }, - content(){ - target.addSkill('hsdusu_shinancao'); + content() { + target.addSkill("hsdusu_shinancao"); }, - ai:{ - order:7, - result:{ - target(player,target){ - if(target.hp>1){ - if(target.countCards('h')>2) return 1; + ai: { + order: 7, + result: { + target(player, target) { + if (target.hp > 1) { + if (target.countCards("h") > 2) return 1; return 0.5; } return 0.2; }, }, - value:5, - } - }, - hsbaowu_cangbaotu:{ - type:'hsbaowu', - fullimage:true, - vanish:true, - enable:true, - gainable:false, - derivation:'hs_yelise', - filterTarget(card,player,target){ - return target==player; + value: 5, }, - selectTarget:-1, - content(){ - target.addSkill('hsbaowu_cangbaotu'); + }, + hsbaowu_cangbaotu: { + type: "hsbaowu", + fullimage: true, + vanish: true, + enable: true, + gainable: false, + derivation: "hs_yelise", + filterTarget(card, player, target) { + return target == player; + }, + selectTarget: -1, + content() { + target.addSkill("hsbaowu_cangbaotu"); target.draw(); }, - ai:{ - order:10, - result:{ - player:10 + ai: { + order: 10, + result: { + player: 10, }, - useful:10, - value:10, - } - }, - hsbaowu_huangjinyuanhou:{ - type:'hsbaowu', - fullimage:true, - vanish:true, - enable:true, - gainable:false, - derivation:'hs_yelise', - filterTarget(card,player,target){ - return target==player; + useful: 10, + value: 10, }, - selectTarget:-1, - content(){ - 'step 0' - var cards=target.getCards(); - if(cards.length){ - target.lose(cards)._triggered=null; + }, + hsbaowu_huangjinyuanhou: { + type: "hsbaowu", + fullimage: true, + vanish: true, + enable: true, + gainable: false, + derivation: "hs_yelise", + filterTarget(card, player, target) { + return target == player; + }, + selectTarget: -1, + content() { + "step 0"; + var cards = target.getCards(); + if (cards.length) { + target.lose(cards)._triggered = null; } - event.num=1+cards.length; - 'step 1' - var cards=[]; - var list=[]; - if(lib.characterPack.hearth){ - for(var i=0;i1) return 1; - if(player.hp==1) return 1; + ai: { + order: 10, + result: { + player(player) { + if (player.countCards("h") > 1) return 1; + if (player.hp == 1) return 1; return 0; - } + }, }, - useful:10, - value:10, - } + useful: 10, + value: 10, + }, }, - hsshenqi_nengliangzhiguang:{ - type:'hsshenqi', - fullimage:true, - vanish:true, - enable(card,player){ + hsshenqi_nengliangzhiguang: { + type: "hsshenqi", + fullimage: true, + vanish: true, + enable(card, player) { return !player.isTurnedOver(); }, - derivation:'hs_lafamu', - filterTarget:true, - content(){ + derivation: "hs_lafamu", + filterTarget: true, + content() { target.gainMaxHp(); target.recover(); target.draw(4); }, - contentAfter(){ - if(!player.isTurnedOver()){ + contentAfter() { + if (!player.isTurnedOver()) { player.turnOver(); } }, - ai:{ - order:5, - result:{ - target(player,target){ - if(target.hp<=1) return 2; - if(target.countCards('h')0; + derivation: "hs_lafamu", + filterTarget(card, player, target) { + return target != player && target.countCards("hej") > 0; }, - selectTarget:-1, - content(){ - if(target.countCards('hej')) player.gainPlayerCard(target,'hej',true); + selectTarget: -1, + content() { + if (target.countCards("hej")) player.gainPlayerCard(target, "hej", true); }, - contentAfter(){ - if(!player.isTurnedOver()){ + contentAfter() { + if (!player.isTurnedOver()) { player.turnOver(); } }, - ai:{ - order:9.5, - result:{ - player:1 + ai: { + order: 9.5, + result: { + player: 1, }, - tag:{ - multitarget:1, - multineg:1, - loseCard:1, - gain:1 + tag: { + multitarget: 1, + multineg: 1, + loseCard: 1, + gain: 1, }, - useful:5, - value:10, - } + useful: 5, + value: 10, + }, }, - hsmengjing_feicuiyoulong:{ - type:'hsmengjing', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_ysera', - filterTarget:true, - content(){ + hsmengjing_feicuiyoulong: { + type: "hsmengjing", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_ysera", + filterTarget: true, + content() { target.damage(); }, - ai:{ - order:5, - result:{ - target:-1 + ai: { + order: 5, + result: { + target: -1, }, - tag:{ - damage:1 + tag: { + damage: 1, }, - useful:5, - value:10, - } - }, - hsmengjing_suxing:{ - type:'hsmengjing', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_ysera', - filterTarget(card,player,target){ - return player!=target; + useful: 5, + value: 10, }, - selectTarget:-1, - content(){ + }, + hsmengjing_suxing: { + type: "hsmengjing", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_ysera", + filterTarget(card, player, target) { + return player != target; + }, + selectTarget: -1, + content() { target.loseHp(); - var he=target.getCards('he'); - if(he.length){ + var he = target.getCards("he"); + if (he.length) { target.discard(he.randomGets(2)); } }, - ai:{ - result:{ - target:-1, + ai: { + result: { + target: -1, }, - order:6, - useful:5, - value:10, - } + order: 6, + useful: 5, + value: 10, + }, }, - hsmengjing_mengye:{ - type:'hsmengjing', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_ysera', - filterTarget:true, - content(){ + hsmengjing_mengye: { + type: "hsmengjing", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_ysera", + filterTarget: true, + content() { target.draw(); - target.addSkill('hsmengjing_mengye'); + target.addSkill("hsmengjing_mengye"); + }, + ai: { + order: 1, + useful: 5, + value: 10, + result: { + target(player, target) { + if (target.hasSkill("hsmengjing_mengye")) return 0.5; + return -target.countCards("he"); + }, + }, }, - ai:{ - order:1, - useful:5, - value:10, - result:{ - target(player,target){ - if(target.hasSkill('hsmengjing_mengye')) return 0.5; - return -target.countCards('he'); - } - } - } }, - hsmengjing_mengjing:{ - type:'hsmengjing', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_ysera', - filterTarget(card,player,target){ - return !target.hasJudge('lebu')||target.countCards('e')>0; + hsmengjing_mengjing: { + type: "hsmengjing", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_ysera", + filterTarget(card, player, target) { + return !target.hasJudge("lebu") || target.countCards("e") > 0; }, - content(){ - 'step 0' - var es=target.getCards('e'); - if(es.length){ - target.gain(es,'gain2'); + content() { + "step 0"; + var es = target.getCards("e"); + if (es.length) { + target.gain(es, "gain2"); } - 'step 1' - if(!target.hasJudge('lebu')){ - target.addJudge(game.createCard('lebu')); + "step 1"; + if (!target.hasJudge("lebu")) { + target.addJudge(game.createCard("lebu")); } }, - ai:{ - order:2, - useful:5, - value:10, - result:{ - target(player,target){ - var num=target.hp-target.countCards('he')-2; - if(num>-1) return -1; - if(target.hp<3) num--; - if(target.hp<2) num--; - if(target.hp<1) num--; + ai: { + order: 2, + useful: 5, + value: 10, + result: { + target(player, target) { + var num = target.hp - target.countCards("he") - 2; + if (num > -1) return -1; + if (target.hp < 3) num--; + if (target.hp < 2) num--; + if (target.hp < 1) num--; return num; - } - } - } - }, - hsmengjing_huanxiaojiemei:{ - type:'hsmengjing', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_ysera', - filterTarget(card,player,target){ - return target.hp1&&get.threaten(target)<=1.2){ + } else if (target.countCards("h") > 1 && get.threaten(target) <= 1.2) { return 1; } - } - } - } + }, + }, + }, }, - hszuzhou_wushushike:{ - type:'hszuzhou', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_hajiasha', - filterTarget:true, - selectTarget:-1, - multitarget:true, - multiline:true, - content(){ - 'step 0' - event.targets=game.filterPlayer().sortBySeat(); - 'step 1' - if(event.targets.length){ - event.current=event.targets.shift(); - var cards=event.current.getCards('h','shan'); - if(cards.length){ - event.current.lose(cards)._triggered=null; + hszuzhou_wushushike: { + type: "hszuzhou", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_hajiasha", + filterTarget: true, + selectTarget: -1, + multitarget: true, + multiline: true, + content() { + "step 0"; + event.targets = game.filterPlayer().sortBySeat(); + "step 1"; + if (event.targets.length) { + event.current = event.targets.shift(); + var cards = event.current.getCards("h", "shan"); + if (cards.length) { + event.current.lose(cards)._triggered = null; } - event.num=cards.length; - } - else{ + event.num = cards.length; + } else { event.finish(); } - 'step 2' - var cards=[]; - for(var i=0;i0; - })){ + ai: { + order: 4, + value: 6, + result: { + player(player) { + if ( + !player.hasSha() && + player.countCards("h", "shan") && + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current, true, true) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 1; } return 0; - } - } - } - }, - hszuzhou_guhuo:{ - type:'hszuzhou', - fullimage:true, - vanish:true, - enable:true, - derivation:'hs_hajiasha', - filterTarget(card,player,target){ - return target!=player&&target.countCards('he'); + }, + }, }, - content(){ - 'step 0' - target.chooseCard('he',true); - 'step 1' - if(result.bool){ - target.give(result.cards,player); + }, + hszuzhou_guhuo: { + type: "hszuzhou", + fullimage: true, + vanish: true, + enable: true, + derivation: "hs_hajiasha", + filterTarget(card, player, target) { + return target != player && target.countCards("he"); + }, + content() { + "step 0"; + target.chooseCard("he", true); + "step 1"; + if (result.bool) { + target.give(result.cards, player); } }, - ai:{ - order:8.6, - value:8, - result:{ - target(player,target){ - return -1/Math.sqrt(1+target.countCards('he')); - } - } - } + ai: { + order: 8.6, + value: 8, + result: { + target(player, target) { + return -1 / Math.sqrt(1 + target.countCards("he")); + }, + }, + }, }, - tuteng1:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng1: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng2:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng2: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng3:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng3: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng4:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng4: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng5:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng5: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng6:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng6: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng7:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng7: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, - tuteng8:{ - noname:true, - fullimage:true, - type:'hstuteng', - derivation:'hs_sthrall', - gainable:false + tuteng8: { + noname: true, + fullimage: true, + type: "hstuteng", + derivation: "hs_sthrall", + gainable: false, }, }, - translate:{ - hs_alleria:'奥蕾莉亚', - hs_magni:'麦格尼', - hs_medivh:'麦迪文', - hs_jaina:'吉安娜', - hs_lrexxar:'雷克萨', - hs_wuther:'乌瑟尔', - hs_jgarrosh:'加尔鲁什', - hs_malfurion:'玛法里奥', - hs_guldan:'古尔丹', - hs_anduin:'安度因', - hs_sthrall:'萨尔', - hs_waleera:'瓦莉拉', - hs_liadrin:'莉亚德琳', - hs_morgl:'摩戈尔', + translate: { + hs_alleria: "奥蕾莉亚", + hs_magni: "麦格尼", + hs_medivh: "麦迪文", + hs_jaina: "吉安娜", + hs_lrexxar: "雷克萨", + hs_wuther: "乌瑟尔", + hs_jgarrosh: "加尔鲁什", + hs_malfurion: "玛法里奥", + hs_guldan: "古尔丹", + hs_anduin: "安度因", + hs_sthrall: "萨尔", + hs_waleera: "瓦莉拉", + hs_liadrin: "莉亚德琳", + hs_morgl: "摩戈尔", - hs_neptulon:'耐普图隆', - hs_wvelen:'维纶', - hs_antonidas:'安东尼达斯', - hs_alakir:'奥拉基尔', - hs_zhouzhuo:'周卓', - hs_yngvar:'伊戈瓦尔', - hs_bchillmaw:'冰喉', - hs_malorne:'玛洛恩', - hs_xsylvanas:'希尔瓦娜斯', - hs_siwangzhiyi:'死亡之翼', - hs_malygos:'玛里苟斯', - hs_xuefashi:'血法师', - hs_ysera:'伊瑟拉', - hs_alextrasza:'阿莱克斯塔', - hs_trueheart:'图哈特', - hs_nozdormu:'诺兹多姆', - hs_loatheb:'洛欧塞布', - hs_jiaziruila:'加兹瑞拉', - hs_sainaliusi:'塞纳留斯', - hs_bolvar:'伯瓦尔', - hs_lrhonin:'罗宁', - hs_fuding:'弗丁', - hs_aedwin:'艾德温', - hs_lafamu:'拉法姆', - hs_yelise:'伊莉斯', - hs_lreno:'雷诺', - hs_finley:'芬利', - hs_brann:'布莱恩', - hs_kcthun:'克苏恩', - hs_anomalus:'阿诺玛鲁斯', - hs_blingtron:'布林顿', - hs_fandral:'范达尔', - hs_hallazeal:'海纳泽尔', - hs_enzoth:'恩佐斯', - hs_walian:'瓦里安', - hs_pengpeng:'砰砰博士', - hs_aya:'艾雅', - hs_pyros:'派洛斯', - hs_jiawodun:'嘉沃顿', - hs_laila:'莱拉', - hs_selajin:'瑟拉金', - hs_bannabusi:'班纳布斯', - hs_amala:'阿玛拉', - hs_nuogefu:'诺格弗', - hs_kazhakusi:'卡扎库斯', - hs_lazi:'拉兹', - hs_shaku:'沙库尔', - hs_laxiao:'拉希奥', - hs_yashaji:'亚煞极', - hs_khadgar:'卡德加', - hs_tyrande:'泰兰德', - hs_fenjie:'芬杰', - hs_kalimosi:'卡利莫斯', - hs_yogg:'尤格萨隆', - hs_xialikeer:'夏克里尔', - hs_wolazi:'沃拉兹', - hs_tanghangu:'唐·汉古', - hs_barnes:'巴内斯', - hs_kchromaggus:'克洛玛古斯', - hs_kaituozhe:'开拓者', + hs_neptulon: "耐普图隆", + hs_wvelen: "维纶", + hs_antonidas: "安东尼达斯", + hs_alakir: "奥拉基尔", + hs_zhouzhuo: "周卓", + hs_yngvar: "伊戈瓦尔", + hs_bchillmaw: "冰喉", + hs_malorne: "玛洛恩", + hs_xsylvanas: "希尔瓦娜斯", + hs_siwangzhiyi: "死亡之翼", + hs_malygos: "玛里苟斯", + hs_xuefashi: "血法师", + hs_ysera: "伊瑟拉", + hs_alextrasza: "阿莱克斯塔", + hs_trueheart: "图哈特", + hs_nozdormu: "诺兹多姆", + hs_loatheb: "洛欧塞布", + hs_jiaziruila: "加兹瑞拉", + hs_sainaliusi: "塞纳留斯", + hs_bolvar: "伯瓦尔", + hs_lrhonin: "罗宁", + hs_fuding: "弗丁", + hs_aedwin: "艾德温", + hs_lafamu: "拉法姆", + hs_yelise: "伊莉斯", + hs_lreno: "雷诺", + hs_finley: "芬利", + hs_brann: "布莱恩", + hs_kcthun: "克苏恩", + hs_anomalus: "阿诺玛鲁斯", + hs_blingtron: "布林顿", + hs_fandral: "范达尔", + hs_hallazeal: "海纳泽尔", + hs_enzoth: "恩佐斯", + hs_walian: "瓦里安", + hs_pengpeng: "砰砰博士", + hs_aya: "艾雅", + hs_pyros: "派洛斯", + hs_jiawodun: "嘉沃顿", + hs_laila: "莱拉", + hs_selajin: "瑟拉金", + hs_bannabusi: "班纳布斯", + hs_amala: "阿玛拉", + hs_nuogefu: "诺格弗", + hs_kazhakusi: "卡扎库斯", + hs_lazi: "拉兹", + hs_shaku: "沙库尔", + hs_laxiao: "拉希奥", + hs_yashaji: "亚煞极", + hs_khadgar: "卡德加", + hs_tyrande: "泰兰德", + hs_fenjie: "芬杰", + hs_kalimosi: "卡利莫斯", + hs_yogg: "尤格萨隆", + hs_xialikeer: "夏克里尔", + hs_wolazi: "沃拉兹", + hs_tanghangu: "唐·汉古", + hs_barnes: "巴内斯", + hs_kchromaggus: "克洛玛古斯", + hs_kaituozhe: "开拓者", - hs_yelinlonghou:'夜鳞龙后', - hs_yelinchulong:'雏龙', - hs_ronghejuren:'熔核巨人', - hs_shanlingjuren:'山岭巨人', - hs_mijiaojisi:'秘教祭司', - hs_huzhixiannv:'湖之仙女', - hs_totemic:'图腾师', - hs_bilanyoulong:'碧蓝幼龙', - hs_zhishigushu:'知识古树', - hs_zhanzhenggushu:'战争古树', - hs_jinglinglong:'精灵龙', - hs_sapphiron:'萨菲隆', - hs_xuanzhuanjijia:'旋转机甲', - hs_ruanniguai:'软泥怪', - hs_hudunren:'护盾机甲', - hs_nate:'纳特', - hs_shifazhe:'嗜法者', - hs_xiangyaqishi:'象牙骑士', - hs_wujiyuansu:'无羁元素', - hs_mojinbaozi:'魔晶孢子', - hs_shuiwenxuejia:'水文学家', - hs_shizugui:'始祖龟', - hs_hemite:'赫米特', - hs_yinggencao:'萤根草', - hs_zhihuanhua:'致幻花', - hs_shirencao:'食人草', - hs_fachaotuteng:'法潮图腾', - hs_huolituteng:'活力图腾', - hs_manyututeng:'蛮鱼图腾', - hs_tgolem:'图腾魔像', - hs_heifengqishi:'黑锋骑士', - hs_yuhuozhe:'浴火者', - hs_wuyaowang:'巫妖王', - hs_aerfusi:'阿尔福斯', - hs_baiguyoulong:'白骨幼龙', - hs_yangyanwageli:'阳焰瓦格里', - hs_aiqinvyao:'哀泣女妖', - hs_ashamoer:'阿莎摩尔', - hs_fengjianhuanfengzhe:'风剪唤风者', - hs_taisi:'苔丝', - hs_hajiasha:'哈加莎', - hs_tuoqi:'托奇', - hs_siwangxianzhi:'死亡先知', - hs_xukongzhiying:'虚空之影', - hs_duyaxinshi:'渡鸦信使', + hs_yelinlonghou: "夜鳞龙后", + hs_yelinchulong: "雏龙", + hs_ronghejuren: "熔核巨人", + hs_shanlingjuren: "山岭巨人", + hs_mijiaojisi: "秘教祭司", + hs_huzhixiannv: "湖之仙女", + hs_totemic: "图腾师", + hs_bilanyoulong: "碧蓝幼龙", + hs_zhishigushu: "知识古树", + hs_zhanzhenggushu: "战争古树", + hs_jinglinglong: "精灵龙", + hs_sapphiron: "萨菲隆", + hs_xuanzhuanjijia: "旋转机甲", + hs_ruanniguai: "软泥怪", + hs_hudunren: "护盾机甲", + hs_nate: "纳特", + hs_shifazhe: "嗜法者", + hs_xiangyaqishi: "象牙骑士", + hs_wujiyuansu: "无羁元素", + hs_mojinbaozi: "魔晶孢子", + hs_shuiwenxuejia: "水文学家", + hs_shizugui: "始祖龟", + hs_hemite: "赫米特", + hs_yinggencao: "萤根草", + hs_zhihuanhua: "致幻花", + hs_shirencao: "食人草", + hs_fachaotuteng: "法潮图腾", + hs_huolituteng: "活力图腾", + hs_manyututeng: "蛮鱼图腾", + hs_tgolem: "图腾魔像", + hs_heifengqishi: "黑锋骑士", + hs_yuhuozhe: "浴火者", + hs_wuyaowang: "巫妖王", + hs_aerfusi: "阿尔福斯", + hs_baiguyoulong: "白骨幼龙", + hs_yangyanwageli: "阳焰瓦格里", + hs_aiqinvyao: "哀泣女妖", + hs_ashamoer: "阿莎摩尔", + hs_fengjianhuanfengzhe: "风剪唤风者", + hs_taisi: "苔丝", + hs_hajiasha: "哈加莎", + hs_tuoqi: "托奇", + hs_siwangxianzhi: "死亡先知", + hs_xukongzhiying: "虚空之影", + hs_duyaxinshi: "渡鸦信使", - hshuanyu:'幻羽', - hshuanyu_info:'每当你受到一次伤害,你获得发现一张炉石衍生牌。', - hsfashu:'法术', - hsfashu_anyingjingxiang:'暗影镜像', - hsfashu_anyingjingxiang_info:'当你使用或打出一张牌后,暗影镜像变为该牌的复制。', - hsfashu_buwendingyibian:'不稳定异变', - hsfashu_buwendingyibian_info:'出牌阶段对一名角色使用,目标将一张手牌重铸为同类别的牌,本回合可重复使用此牌,最多使用X次,X为当前体力值。', - hualing:'化灵', - hualing_info:'每三轮限一次,你可以选择一名其他角色,获得其一项技能,然后将其随机变形为一名强度高一级的武将。', - yibian:'异变', - yibian_info:'锁定技,出牌阶段开始时,若你没有不稳定异变,则将一张不稳定异变置于你的手牌。', - wxuying:'虚影', - wxuying_info:'锁定技,准备阶段,你移去手牌中的暗影镜像,然后获得一张暗影镜像(当你使用或打出一张牌后,暗影镜像变为该牌的复制);当你回合内使用暗影镜像时,你摸一张牌;当你回合外使用暗影镜像时,你获得潜行直到下一回合开始。', - zhoujiang:'咒降', - zhoujiang_info:'锁定技,每当你使用一张普通锦囊牌,你将一张随机“诅咒”牌置于你的手牌。', - muyin:'暮隐', - muyin_info:'锁定技,每当你失去最后一张手牌,你获得潜行直到下一回合开始。', - tqchuanyue:'穿越', - tqchuanyue_info:'锁定技,准备阶段开始时,你随机选择一个被削弱过的炉石技能,获得其未削弱的版本,替换上一个以此法获得的技能。', + hshuanyu: "幻羽", + hshuanyu_info: "每当你受到一次伤害,你获得发现一张炉石衍生牌。", + hsfashu: "法术", + hsfashu_anyingjingxiang: "暗影镜像", + hsfashu_anyingjingxiang_info: "当你使用或打出一张牌后,暗影镜像变为该牌的复制。", + hsfashu_buwendingyibian: "不稳定异变", + hsfashu_buwendingyibian_info: + "出牌阶段对一名角色使用,目标将一张手牌重铸为同类别的牌,本回合可重复使用此牌,最多使用X次,X为当前体力值。", + hualing: "化灵", + hualing_info: + "每三轮限一次,你可以选择一名其他角色,获得其一项技能,然后将其随机变形为一名强度高一级的武将。", + yibian: "异变", + yibian_info: "锁定技,出牌阶段开始时,若你没有不稳定异变,则将一张不稳定异变置于你的手牌。", + wxuying: "虚影", + wxuying_info: + "锁定技,准备阶段,你移去手牌中的暗影镜像,然后获得一张暗影镜像(当你使用或打出一张牌后,暗影镜像变为该牌的复制);当你回合内使用暗影镜像时,你摸一张牌;当你回合外使用暗影镜像时,你获得潜行直到下一回合开始。", + zhoujiang: "咒降", + zhoujiang_info: "锁定技,每当你使用一张普通锦囊牌,你将一张随机“诅咒”牌置于你的手牌。", + muyin: "暮隐", + muyin_info: "锁定技,每当你失去最后一张手牌,你获得潜行直到下一回合开始。", + tqchuanyue: "穿越", + tqchuanyue_info: + "锁定技,准备阶段开始时,你随机选择一个被削弱过的炉石技能,获得其未削弱的版本,替换上一个以此法获得的技能。", // hsxiujian:'袖箭', // hsxiujian_info:'锁定技,在你对一名敌方角色使用一张锦囊牌后,你视为对其使用一张杀。', // hsyingzong:'影踪', // hsyingzong_info:'', - hsxingyi:'星移', - hsxingyi_info:'锁定技,每当一名敌方角色于回合内使用主动技能,你获得此技能直到下一回合结束。', + hsxingyi: "星移", + hsxingyi_info: "锁定技,每当一名敌方角色于回合内使用主动技能,你获得此技能直到下一回合结束。", - hshuanling:'幻灵', - hshuanling_bg:'灵', - hshuanling_info:'结束阶段,你可以弃置至多X张牌(X为你装备区内的牌数且至少为1)并摸等量的牌,每弃置一张牌,你随机使用一张本局敌方角色使用过的单目标非转化普通锦囊牌,随机指定一个具有正收益的角色为目标。', + hshuanling: "幻灵", + hshuanling_bg: "灵", + hshuanling_info: + "结束阶段,你可以弃置至多X张牌(X为你装备区内的牌数且至少为1)并摸等量的牌,每弃置一张牌,你随机使用一张本局敌方角色使用过的单目标非转化普通锦囊牌,随机指定一个具有正收益的角色为目标。", // hshuanling_info:'锁定技,当你于回合内使用首张指定其他角色为惟一目标的锦囊牌后,你视为对其随机使用一张锦囊牌(此牌对你有正面效果)。', // hshuanling_info:'每当你使用一张基本牌或普通锦囊牌,你可以弃置任意张牌令其增加或减少等量的目标。', - huanfeng:'唤风', - huanfeng_info:'锁定技,准备阶段,若你有4个图腾,你失去所有图腾,然后获得并召唤随从奥拉基尔。', - asyouzhang:'幽瘴', - asyouzhang_info:'结束阶段,若你的手牌中没有基本牌/锦囊牌/装备牌,你可以获得牌堆顶的一张基本牌/锦囊牌/装备牌,并可以立即使用。', - ylyuchu:'育雏', - ylyuchu_info:'锁定技,每当你回复1点体力,你获得一只雏龙随从(不超过3只);结束阶段,你每有一只雏龙,便随机选择一名其他角色,在该角色的下个回合开始前你切换至该雏龙,然后在此回合结束后进行一个额外回合并切换回本体。', - nsaiqi:'哀泣', - nsaiqi_info:'锁定技,每当你使用一张牌,你移除牌堆顶的三张牌;你的手牌上限始终+1。', - nsbeiming:'悲鸣', - nsbeiming_info:'锁定技,当你移除的牌不少于9张时,你摸一张牌,然后将移除的牌以任意顺序置于牌堆顶;当被移除过的牌在牌堆顶时(洗牌后重置),你的不能发动【哀泣】移除牌。', - hstianqi_dalian:'达里安', - hstianqi_dalian_info:'每当你造成一次伤害,你回复等量的体力。', - hstianqi_shali:'莎莉', - hstianqi_shali_info:'每当你回复体力,你获得等量的护甲。', - hstianqi_nazigelin:'纳兹戈林', - hstianqi_nazigelin_info:'当你装备此牌时,你获得1点护甲。', - hstianqi_suolasi:'索拉斯', - hstianqi_suolasi_info:'当你失去此牌时,你回复1点体力。', - hschaoxi:'潮袭', - hschaoxi_info:'锁定技,每当你造成一次伤害,你获得两张随机鱼人牌。', - hsnitai:'拟态', - hsnitai_info:'锁定技,出牌阶段开始时,你获得一张随机炉石角色的技能牌。', - hstianqi:'天启', - hstianqi_info:'出牌阶段限一次,你可以选择一项:弃置一张手牌并随机装备一件天启骑士(不能替换现有装备),或弃置一张装备区内的牌并摸两张牌;当你以此法弃置天启骑士时,若你武将牌上没有对应的天启骑士,你将其置于你的武将牌上;准备阶段,若你的武将牌上有4张天启骑士,你获得游戏胜利。', - hspuzhao:'普照', - hspuzhao_info:'出牌阶段限一次,你可以弃置一张红桃牌,然后令至多三名随机友方角色各摸一张牌(若你无其他队友,改为摸两张牌)。', - hsyanxin:'炎心', - hsyanxin_info:'锁定技,在你摸牌时,若牌堆中有红色牌,你摸到的首张牌必为红色。', - ysjqisha:'七煞', - ysjqisha_ju:'惧之煞', - ysjqisha_kuang:'狂之煞', - ysjqisha_nu:'怒之煞', - ysjqisha_yi:'疑之煞', - ysjqisha_wang:'惘之煞', - ysjqisha_hen:'恨之煞', - ysjqisha_ao:'傲之煞', - ysjqisha_info:'锁定技,每当你造成或受到伤害,你令对方随机获得一种消极状态直到下一回合结束。', - zhaochao:'招潮', - zhaochao_info:'锁定技,结束阶段,你视为对一名随机敌人使用一张杀;若此杀被闪避,你视为对另一名随机敌人使用一张杀。', - hllingxi:'灵息', - hllingxi_info:'出牌阶段,你可以令一名已受伤的其他角色弃置两张牌并回复1点体力(同阶段对一名角色限用一次);结束阶段,你可以回复1点体力。', - xiyong:'汐涌', - xiyong_info:'结束阶段,你可以摸一张牌并可以使用之,若你使用了此牌,你再摸一张牌。', - hsjixie:'机械', - hsjixie_zhadan:'炸弹机器人', - hsjixie_zhadan_pop:'炸弹', - hsjixie_zhadan_info:'出牌阶段对自己使用,对一名随机敌人造成1点火属性伤害。', - yindan:'引弹', - yindan_info:'出牌阶段限一次,你可以弃置一张黑桃牌并失去1点体力,然后获得两张炸弹机器人。', - huanjue:'幻觉', - huanjue_info:'每当你使用一张牌,若此牌指定了惟一目标,你可以发现一张牌,然后可以代替此牌结算。', - oldhuanjue:'幻觉', - oldhuanjue_info:'每回合限一次,当你成为一名其他角色的卡牌惟一目标时,你可以发现一张牌代替此牌。', - zhziwu:'紫雾', - zhziwu_info:'每当你于回合外失去牌,你可以令当前回合角色不能使用杀直到回合结束。', - huanjue_info_old:'每名角色的回合限一次,当你使用卡牌指定其他角色为惟一目标,或当其他角色使用卡牌指定你为惟一目标时,你可以发现一张牌代替此牌,然后该牌的使用者在结算后摸一张牌。', - yinzong:'影踪', - yinzong_info:'锁定技,每当你失去装备区内的牌,你获得一张闪。', - tansuo:'探索', - tansuo_info:'出牌阶段限一次,你可以弃置一张牌,然后发现一张炉石衍生牌。', - srjici:'棘刺', - srjici_info:'锁定技,每当你造成一次伤害,你摸一张牌,受伤害角色随机弃置一张牌。', - lieqi:'猎奇', - lieqi_info:'准备和结束阶段,你可以指定一名角色,从一张该角色手牌与另外两张随机牌中猜测哪张为该角色手牌,若猜中,你获得一张该牌的复制(同一回合不能指定相同角色)。', - azaowu:'造物', - azaowu_backup:'造物', - azaowu_info:'出牌阶段限一次,你可以将一张基本牌当作任意一张基本牌使用。', - shouwang:'守望', - shouwang2:'守望', - shouwang_info:'每名角色每局限一次,当一名角色进入濒死状态时,你可以令其回复1点体力并获得1点护甲。', - shouwang_info_alter:'每名角色每局限一次,当一名角色进入濒死状态时,你可以令其回复1点体力。', - qingtian:'擎天', - qingtian_info:'锁定技,若你的体力值为全场最多,你受到的伤害始终+1。', - qianfu:'潜伏', - qianfu2:'潜伏', - qianfu2_bg:'伏', - qianfu_info:'锁定技,在你死亡前,若你没有进入潜伏状态,你弃置所有牌并进入潜伏状态;当你体力值回复到3(或体力上限)时,你解除潜伏状态并摸三张牌。', - shimo:'尸魔', - shimo_info:'锁定技,距离你为1的角色受到伤害时,你回复1点体力,若你没受伤,改为摸一张牌。', - lieyang:'裂阳', - lieyang_info:'锁定技,每当你于回合内使用一张锦囊牌,你获得一张随机锦囊牌;当你发动三次此技能后,你本回合不能再使用锦囊牌。', - zhuilie:'追猎', - zhuilie_info:'准备阶段,你可以弃置一张牌,然后将牌堆顶六张牌中的基本牌移至弃牌堆;若移入弃牌堆的牌超过三张,你摸一张牌。', - szbianshen:'变身', - szbianshen_info:'限定技,回合开始时,若游戏轮数不少于3,你可以随机观看5张体力上限不小于5的武将牌,将武将牌替换为其中一张。', - kekao:'科考', - kekao_info:'结束阶段,你可以发现一张延时锦囊牌。', - jinhua:'进化', - jinhua_info:'锁定技,每当你以自己为目标使用一张非转化的锦囊牌,你发现一个技能并获得之。', - hsqizhou:'祈咒', - hsqizhou_feng:'风之祈咒', - hsqizhou_feng_info:'出牌阶段对自己使用,令所有目标的敌人打出一张杀或受到1点雷属性伤害。', - hsqizhou_shui:'水之祈咒', - hsqizhou_shui_info:'出牌阶段对自己使用,回复2点体力。', - hsqizhou_huo:'火之祈咒', - hsqizhou_huo_info:'出牌阶段对任意角色使用,令目标受到1点火属性伤害。', - hsqizhou_tu:'土之祈咒', - hsqizhou_tu_info:'出牌阶段对任意其他角色使用,令目标获得1点护甲。', - kqizhou:'祈咒', - kqizhou_info:'准备阶段,若你于上回合使用过锦囊牌,则可以获得一张元素祈咒。', - jingcu:'晶簇', - jingcu_info:'出牌阶段,你可以减少1点体力上限并摸两张牌。', - shengzhang:'生长', - shengzhang_info:'锁定技,若你于弃牌阶段弃置了牌,你增加1点体力上限。', - pyuhuo:'浴火', - pyuhuo_info:'锁定技,在你首次进入濒死状态时,你弃置所有牌、重置武将牌、将体力和体力上限变为4并摸四张牌;在你第二次进入濒死状态时,你弃置所有牌、重置武将牌、将体力和体力上限变为6并摸六张牌。', - mengye:'梦魇', - mengye_info:'结束阶段,你可以选择一名有手牌的角色将其一张随机的非毒手牌转化为毒,然后令其获得1点护甲。', - mengye_old:'梦魇', - mengye_old2:'梦魇', - mengye_old_info:'回合结束后,你可以翻面并指定一名的非主公角色,由你控制其进行一个额外的回合。在此回合中,你的本体不参与游戏。', - fuhua:'腐化', - fuhua2:'腐化', - fuhua_info:'出牌阶段,你可以将一张毒交给一名没有魔血技能的其他角色,该角色选择一项:1. 获得技能魔血,此后每个结束阶段需交给你一张手牌;2. 视为你对其使用一张决斗。', - moxie:'魔血', - moxie_info:'锁定技,当你因【毒】失去体力时,你改为摸两张牌;结束阶段,你将一张随机手牌转化为毒。', - gfuhun:'附魂', - gfuhun_info:'结束阶段,若你未翻面,你可以和一名其他角色拼点,若你赢,你将武将牌翻至背面,该角色进入混乱状态直到下一回合结束。', - hlongyi:'龙裔', - hlongyi_info:'锁定技,你的黑色牌不占用手牌上限。', - zhongji:'重击', - zhongji_info:'每当你即将造成伤害,可弃置一张黑色手牌令伤害+1。', - fuwen:'符文', - fuwen_info:'若你弃牌阶段弃置了锦囊牌,你可以获得1点护甲。', - jinzhou:'禁咒', - jinzhou_info:'结束阶段,若你手牌中有黑桃牌,你可以令一名其他角色的非锁定技失效直到其下一回合结束。', - midian:'秘典', - midian_info:'出牌阶段限一次,你可以弃置一张锦囊牌,然后随机获得三张锦囊牌。', - yuelu:'月露', - yuelu_info:'在一名角色的濒死阶段,你可以弃置一张黑色牌令其回复1点体力并获得1点护甲。', - yuelu_info_alter:'在一名角色的濒死阶段,你可以弃置一张黑色牌令其回复1点体力。', - xingluo:'星落', - xingluo_info:'准备阶段,你可以令任意名手牌数多于你的角色各弃置一张手牌,然后你可以从弃置的牌中选择一张加入手牌。', - yushou:'御兽', - yushou_info:'出牌阶段,你可以弃置一张牌并召唤一个随机的野兽宠物,回合开始阶段,你随机失去一个宠物。', - yushou_misha:'米莎', - yushou_misha_info:'每当你受到一次伤害,你获得1点护甲。', - yushou_huofu:'霍弗', - yushou_huofu_info:'你可以将一张黑色牌当作决斗使用。', - yushou_leiouke:'雷欧克', - yushou_leiouke_info:'你每回合造成的首次伤害+1。', - hsqingyu_hufu:'青玉护符', - hsqingyu_hufu_info:'令一名角色获得1点护甲。', - hsqingyu_zhao:'青玉之爪', - hsqingyu_zhao_info:'当你装备此装备时,摸一张牌。', - hsqingyu_feibiao:'青玉飞镖', - hsqingyu_feibiao_info:'弃置一名角色的一张随机手牌和一张随机装备牌。', - hsqingyu_shandian:'青玉闪电', - hsqingyu_shandian_info:'对一名角色造成1点雷电伤害。', - hsqingyu_zhanfang:'青玉绽放', - hsqingyu_zhanfang_info:'令一名角色增加1点体力上限并摸一张牌。', - ayuling:'玉灵', - ayuling_info:'每当你受到一次伤害,你可以获得一张随机青玉牌。', - qingzun:'青樽', - qingzun_info:'本局对战中,每当你使用一张青玉牌,你的手牌上限+1;当你累计使用两张青玉牌后,你可以于准备阶段摸一张牌;当你累计使用六张青玉牌后,你可以于结束阶段摸一张牌。', - qingzun_info_alter:'本局对战中,每当你使用一张青玉牌,你的手牌上限+1;当你累计使用三张青玉牌后,你可以于准备阶段摸一张牌;当你累计使用九张青玉牌后,你可以于结束阶段摸一张牌。', - lianjin:'炼金', - lianjin_info:'出牌阶段限一次,你可以弃置一张牌并获得一张由三张随机牌组成的药水;当你因弃置而失去药水牌时,你随机获得药水的组成卡牌之一。', - shouji:'收集', - shouji_info:'每当你使用一张杀,你可以获得一张目标随机手牌的复制;每当你的杀被闪避,你可以获得一张目标随机非特殊装备牌的复制;每回合限各限一次。', - hsguimou:'鬼谋', - hsguimou_info:'每当你受到一次伤害,你可以获得伤害来源的一张手牌,若此牌是黑色,你展示此牌并重复此过程。', - yingxi:'影袭', - yingxi_info:'结束阶段,若你本回合未造成伤害,你可以将一张黑色牌当作杀对任意一名角色使用,若目标未受到伤害,此杀不可闪避。', - peiyu:'培育', - peiyu_info:'准备阶段,你可以令一名没有图腾的角色获得一个随机图腾直到其首次受到伤害。', - peiyu_old_info:'出牌阶段,你可以弃置一张牌令一名没有图腾的角色获得一个随机图腾,或令一名有图腾的角色替换一个图腾;你死亡时,其他角色失去以此法获得的图腾。', - wzhanyi:'战意', - wzhanyi_info:'你可以跳过出牌阶段,改为摸三张牌并展示之,将摸到的装备牌置于装备区,然后可以使用手牌中的杀。', - shengteng:'升腾', - shengteng_info:'锁定技,每当你使用锦囊牌造成伤害,你增加1点体力上限并回复1点体力。', - yuansu:'寂灭', - yuansu_info:'出牌阶段限一次,若你已损失的体力值不少于3,你可以将体力上限降至与体力值相同,视为使用一张元素毁灭。', - nuyan:'怒焰', - nuyan2:'怒焰', - nuyan_backup:'怒焰', - nuyan_info:'出牌阶段限一次,你可以将一张红色牌当作任意一张能造成伤害的牌使用(不得是你本局以此法使用过的牌)。', - nuyan2_info:'出牌阶段限三次,你可以失去1点体力,视为使用任意一张能造成伤害的牌”。', - chouhuo:'仇火', - chouhuo_info:'觉醒技,出牌阶段开始时,若你的怒焰技能已将可用的牌用完,你失去1点体力上限,获得2点护甲,然后将怒焰的描述改为“出牌阶段限三次,你可以失去1点体力,视为使用任意一张能造成伤害的牌”。', - hsdusu:'毒素', - hsdusu_xueji:'血蓟', - hsdusu_xueji_info:'随机弃置一名角色的2张装备牌。', - hsdusu_shinancao:'石楠草', - hsdusu_shinancao_info:'令一名角色下一次造成的伤害+1。', - hsdusu_kuyecao:'枯叶草', - hsdusu_kuyecao_info:'令一名角色获得技能潜行,直到其下一回合开始。', - hsdusu_huoyanhua:'火焰花', - hsdusu_huoyanhua_info:'对攻击范围内的一名角色造成1点火焰伤害。', - hsdusu_huangxuecao:'皇血草', - hsdusu_huangxuecao_info:'摸两张牌。', - duxin:'毒心', - duxin_info:'准备阶段和结束阶段,若你的手中没有毒素牌,你可以获得一张随机毒素牌。', - oldduxin:'毒心', - oldduxin_info:'准备阶段和结束阶段,你可以获得一张随机毒素牌。', - hstuteng:'图腾', - kuangluan:'狂乱', - kuangluan2:'狂乱', + huanfeng: "唤风", + huanfeng_info: "锁定技,准备阶段,若你有4个图腾,你失去所有图腾,然后获得并召唤随从奥拉基尔。", + asyouzhang: "幽瘴", + asyouzhang_info: + "结束阶段,若你的手牌中没有基本牌/锦囊牌/装备牌,你可以获得牌堆顶的一张基本牌/锦囊牌/装备牌,并可以立即使用。", + ylyuchu: "育雏", + ylyuchu_info: + "锁定技,每当你回复1点体力,你获得一只雏龙随从(不超过3只);结束阶段,你每有一只雏龙,便随机选择一名其他角色,在该角色的下个回合开始前你切换至该雏龙,然后在此回合结束后进行一个额外回合并切换回本体。", + nsaiqi: "哀泣", + nsaiqi_info: "锁定技,每当你使用一张牌,你移除牌堆顶的三张牌;你的手牌上限始终+1。", + nsbeiming: "悲鸣", + nsbeiming_info: + "锁定技,当你移除的牌不少于9张时,你摸一张牌,然后将移除的牌以任意顺序置于牌堆顶;当被移除过的牌在牌堆顶时(洗牌后重置),你的不能发动【哀泣】移除牌。", + hstianqi_dalian: "达里安", + hstianqi_dalian_info: "每当你造成一次伤害,你回复等量的体力。", + hstianqi_shali: "莎莉", + hstianqi_shali_info: "每当你回复体力,你获得等量的护甲。", + hstianqi_nazigelin: "纳兹戈林", + hstianqi_nazigelin_info: "当你装备此牌时,你获得1点护甲。", + hstianqi_suolasi: "索拉斯", + hstianqi_suolasi_info: "当你失去此牌时,你回复1点体力。", + hschaoxi: "潮袭", + hschaoxi_info: "锁定技,每当你造成一次伤害,你获得两张随机鱼人牌。", + hsnitai: "拟态", + hsnitai_info: "锁定技,出牌阶段开始时,你获得一张随机炉石角色的技能牌。", + hstianqi: "天启", + hstianqi_info: + "出牌阶段限一次,你可以选择一项:弃置一张手牌并随机装备一件天启骑士(不能替换现有装备),或弃置一张装备区内的牌并摸两张牌;当你以此法弃置天启骑士时,若你武将牌上没有对应的天启骑士,你将其置于你的武将牌上;准备阶段,若你的武将牌上有4张天启骑士,你获得游戏胜利。", + hspuzhao: "普照", + hspuzhao_info: + "出牌阶段限一次,你可以弃置一张红桃牌,然后令至多三名随机友方角色各摸一张牌(若你无其他队友,改为摸两张牌)。", + hsyanxin: "炎心", + hsyanxin_info: "锁定技,在你摸牌时,若牌堆中有红色牌,你摸到的首张牌必为红色。", + ysjqisha: "七煞", + ysjqisha_ju: "惧之煞", + ysjqisha_kuang: "狂之煞", + ysjqisha_nu: "怒之煞", + ysjqisha_yi: "疑之煞", + ysjqisha_wang: "惘之煞", + ysjqisha_hen: "恨之煞", + ysjqisha_ao: "傲之煞", + ysjqisha_info: "锁定技,每当你造成或受到伤害,你令对方随机获得一种消极状态直到下一回合结束。", + zhaochao: "招潮", + zhaochao_info: + "锁定技,结束阶段,你视为对一名随机敌人使用一张杀;若此杀被闪避,你视为对另一名随机敌人使用一张杀。", + hllingxi: "灵息", + hllingxi_info: + "出牌阶段,你可以令一名已受伤的其他角色弃置两张牌并回复1点体力(同阶段对一名角色限用一次);结束阶段,你可以回复1点体力。", + xiyong: "汐涌", + xiyong_info: "结束阶段,你可以摸一张牌并可以使用之,若你使用了此牌,你再摸一张牌。", + hsjixie: "机械", + hsjixie_zhadan: "炸弹机器人", + hsjixie_zhadan_pop: "炸弹", + hsjixie_zhadan_info: "出牌阶段对自己使用,对一名随机敌人造成1点火属性伤害。", + yindan: "引弹", + yindan_info: "出牌阶段限一次,你可以弃置一张黑桃牌并失去1点体力,然后获得两张炸弹机器人。", + huanjue: "幻觉", + huanjue_info: "每当你使用一张牌,若此牌指定了惟一目标,你可以发现一张牌,然后可以代替此牌结算。", + oldhuanjue: "幻觉", + oldhuanjue_info: "每回合限一次,当你成为一名其他角色的卡牌惟一目标时,你可以发现一张牌代替此牌。", + zhziwu: "紫雾", + zhziwu_info: "每当你于回合外失去牌,你可以令当前回合角色不能使用杀直到回合结束。", + huanjue_info_old: + "每名角色的回合限一次,当你使用卡牌指定其他角色为惟一目标,或当其他角色使用卡牌指定你为惟一目标时,你可以发现一张牌代替此牌,然后该牌的使用者在结算后摸一张牌。", + yinzong: "影踪", + yinzong_info: "锁定技,每当你失去装备区内的牌,你获得一张闪。", + tansuo: "探索", + tansuo_info: "出牌阶段限一次,你可以弃置一张牌,然后发现一张炉石衍生牌。", + srjici: "棘刺", + srjici_info: "锁定技,每当你造成一次伤害,你摸一张牌,受伤害角色随机弃置一张牌。", + lieqi: "猎奇", + lieqi_info: + "准备和结束阶段,你可以指定一名角色,从一张该角色手牌与另外两张随机牌中猜测哪张为该角色手牌,若猜中,你获得一张该牌的复制(同一回合不能指定相同角色)。", + azaowu: "造物", + azaowu_backup: "造物", + azaowu_info: "出牌阶段限一次,你可以将一张基本牌当作任意一张基本牌使用。", + shouwang: "守望", + shouwang2: "守望", + shouwang_info: + "每名角色每局限一次,当一名角色进入濒死状态时,你可以令其回复1点体力并获得1点护甲。", + shouwang_info_alter: "每名角色每局限一次,当一名角色进入濒死状态时,你可以令其回复1点体力。", + qingtian: "擎天", + qingtian_info: "锁定技,若你的体力值为全场最多,你受到的伤害始终+1。", + qianfu: "潜伏", + qianfu2: "潜伏", + qianfu2_bg: "伏", + qianfu_info: + "锁定技,在你死亡前,若你没有进入潜伏状态,你弃置所有牌并进入潜伏状态;当你体力值回复到3(或体力上限)时,你解除潜伏状态并摸三张牌。", + shimo: "尸魔", + shimo_info: "锁定技,距离你为1的角色受到伤害时,你回复1点体力,若你没受伤,改为摸一张牌。", + lieyang: "裂阳", + lieyang_info: + "锁定技,每当你于回合内使用一张锦囊牌,你获得一张随机锦囊牌;当你发动三次此技能后,你本回合不能再使用锦囊牌。", + zhuilie: "追猎", + zhuilie_info: + "准备阶段,你可以弃置一张牌,然后将牌堆顶六张牌中的基本牌移至弃牌堆;若移入弃牌堆的牌超过三张,你摸一张牌。", + szbianshen: "变身", + szbianshen_info: + "限定技,回合开始时,若游戏轮数不少于3,你可以随机观看5张体力上限不小于5的武将牌,将武将牌替换为其中一张。", + kekao: "科考", + kekao_info: "结束阶段,你可以发现一张延时锦囊牌。", + jinhua: "进化", + jinhua_info: "锁定技,每当你以自己为目标使用一张非转化的锦囊牌,你发现一个技能并获得之。", + hsqizhou: "祈咒", + hsqizhou_feng: "风之祈咒", + hsqizhou_feng_info: "出牌阶段对自己使用,令所有目标的敌人打出一张杀或受到1点雷属性伤害。", + hsqizhou_shui: "水之祈咒", + hsqizhou_shui_info: "出牌阶段对自己使用,回复2点体力。", + hsqizhou_huo: "火之祈咒", + hsqizhou_huo_info: "出牌阶段对任意角色使用,令目标受到1点火属性伤害。", + hsqizhou_tu: "土之祈咒", + hsqizhou_tu_info: "出牌阶段对任意其他角色使用,令目标获得1点护甲。", + kqizhou: "祈咒", + kqizhou_info: "准备阶段,若你于上回合使用过锦囊牌,则可以获得一张元素祈咒。", + jingcu: "晶簇", + jingcu_info: "出牌阶段,你可以减少1点体力上限并摸两张牌。", + shengzhang: "生长", + shengzhang_info: "锁定技,若你于弃牌阶段弃置了牌,你增加1点体力上限。", + pyuhuo: "浴火", + pyuhuo_info: + "锁定技,在你首次进入濒死状态时,你弃置所有牌、重置武将牌、将体力和体力上限变为4并摸四张牌;在你第二次进入濒死状态时,你弃置所有牌、重置武将牌、将体力和体力上限变为6并摸六张牌。", + mengye: "梦魇", + mengye_info: + "结束阶段,你可以选择一名有手牌的角色将其一张随机的非毒手牌转化为毒,然后令其获得1点护甲。", + mengye_old: "梦魇", + mengye_old2: "梦魇", + mengye_old_info: + "回合结束后,你可以翻面并指定一名的非主公角色,由你控制其进行一个额外的回合。在此回合中,你的本体不参与游戏。", + fuhua: "腐化", + fuhua2: "腐化", + fuhua_info: + "出牌阶段,你可以将一张毒交给一名没有魔血技能的其他角色,该角色选择一项:1. 获得技能魔血,此后每个结束阶段需交给你一张手牌;2. 视为你对其使用一张决斗。", + moxie: "魔血", + moxie_info: + "锁定技,当你因【毒】失去体力时,你改为摸两张牌;结束阶段,你将一张随机手牌转化为毒。", + gfuhun: "附魂", + gfuhun_info: + "结束阶段,若你未翻面,你可以和一名其他角色拼点,若你赢,你将武将牌翻至背面,该角色进入混乱状态直到下一回合结束。", + hlongyi: "龙裔", + hlongyi_info: "锁定技,你的黑色牌不占用手牌上限。", + zhongji: "重击", + zhongji_info: "每当你即将造成伤害,可弃置一张黑色手牌令伤害+1。", + fuwen: "符文", + fuwen_info: "若你弃牌阶段弃置了锦囊牌,你可以获得1点护甲。", + jinzhou: "禁咒", + jinzhou_info: + "结束阶段,若你手牌中有黑桃牌,你可以令一名其他角色的非锁定技失效直到其下一回合结束。", + midian: "秘典", + midian_info: "出牌阶段限一次,你可以弃置一张锦囊牌,然后随机获得三张锦囊牌。", + yuelu: "月露", + yuelu_info: "在一名角色的濒死阶段,你可以弃置一张黑色牌令其回复1点体力并获得1点护甲。", + yuelu_info_alter: "在一名角色的濒死阶段,你可以弃置一张黑色牌令其回复1点体力。", + xingluo: "星落", + xingluo_info: + "准备阶段,你可以令任意名手牌数多于你的角色各弃置一张手牌,然后你可以从弃置的牌中选择一张加入手牌。", + yushou: "御兽", + yushou_info: + "出牌阶段,你可以弃置一张牌并召唤一个随机的野兽宠物,回合开始阶段,你随机失去一个宠物。", + yushou_misha: "米莎", + yushou_misha_info: "每当你受到一次伤害,你获得1点护甲。", + yushou_huofu: "霍弗", + yushou_huofu_info: "你可以将一张黑色牌当作决斗使用。", + yushou_leiouke: "雷欧克", + yushou_leiouke_info: "你每回合造成的首次伤害+1。", + hsqingyu_hufu: "青玉护符", + hsqingyu_hufu_info: "令一名角色获得1点护甲。", + hsqingyu_zhao: "青玉之爪", + hsqingyu_zhao_info: "当你装备此装备时,摸一张牌。", + hsqingyu_feibiao: "青玉飞镖", + hsqingyu_feibiao_info: "弃置一名角色的一张随机手牌和一张随机装备牌。", + hsqingyu_shandian: "青玉闪电", + hsqingyu_shandian_info: "对一名角色造成1点雷电伤害。", + hsqingyu_zhanfang: "青玉绽放", + hsqingyu_zhanfang_info: "令一名角色增加1点体力上限并摸一张牌。", + ayuling: "玉灵", + ayuling_info: "每当你受到一次伤害,你可以获得一张随机青玉牌。", + qingzun: "青樽", + qingzun_info: + "本局对战中,每当你使用一张青玉牌,你的手牌上限+1;当你累计使用两张青玉牌后,你可以于准备阶段摸一张牌;当你累计使用六张青玉牌后,你可以于结束阶段摸一张牌。", + qingzun_info_alter: + "本局对战中,每当你使用一张青玉牌,你的手牌上限+1;当你累计使用三张青玉牌后,你可以于准备阶段摸一张牌;当你累计使用九张青玉牌后,你可以于结束阶段摸一张牌。", + lianjin: "炼金", + lianjin_info: + "出牌阶段限一次,你可以弃置一张牌并获得一张由三张随机牌组成的药水;当你因弃置而失去药水牌时,你随机获得药水的组成卡牌之一。", + shouji: "收集", + shouji_info: + "每当你使用一张杀,你可以获得一张目标随机手牌的复制;每当你的杀被闪避,你可以获得一张目标随机非特殊装备牌的复制;每回合限各限一次。", + hsguimou: "鬼谋", + hsguimou_info: + "每当你受到一次伤害,你可以获得伤害来源的一张手牌,若此牌是黑色,你展示此牌并重复此过程。", + yingxi: "影袭", + yingxi_info: + "结束阶段,若你本回合未造成伤害,你可以将一张黑色牌当作杀对任意一名角色使用,若目标未受到伤害,此杀不可闪避。", + peiyu: "培育", + peiyu_info: "准备阶段,你可以令一名没有图腾的角色获得一个随机图腾直到其首次受到伤害。", + peiyu_old_info: + "出牌阶段,你可以弃置一张牌令一名没有图腾的角色获得一个随机图腾,或令一名有图腾的角色替换一个图腾;你死亡时,其他角色失去以此法获得的图腾。", + wzhanyi: "战意", + wzhanyi_info: + "你可以跳过出牌阶段,改为摸三张牌并展示之,将摸到的装备牌置于装备区,然后可以使用手牌中的杀。", + shengteng: "升腾", + shengteng_info: "锁定技,每当你使用锦囊牌造成伤害,你增加1点体力上限并回复1点体力。", + yuansu: "寂灭", + yuansu_info: + "出牌阶段限一次,若你已损失的体力值不少于3,你可以将体力上限降至与体力值相同,视为使用一张元素毁灭。", + nuyan: "怒焰", + nuyan2: "怒焰", + nuyan_backup: "怒焰", + nuyan_info: + "出牌阶段限一次,你可以将一张红色牌当作任意一张能造成伤害的牌使用(不得是你本局以此法使用过的牌)。", + nuyan2_info: "出牌阶段限三次,你可以失去1点体力,视为使用任意一张能造成伤害的牌”。", + chouhuo: "仇火", + chouhuo_info: + "觉醒技,出牌阶段开始时,若你的怒焰技能已将可用的牌用完,你失去1点体力上限,获得2点护甲,然后将怒焰的描述改为“出牌阶段限三次,你可以失去1点体力,视为使用任意一张能造成伤害的牌”。", + hsdusu: "毒素", + hsdusu_xueji: "血蓟", + hsdusu_xueji_info: "随机弃置一名角色的2张装备牌。", + hsdusu_shinancao: "石楠草", + hsdusu_shinancao_info: "令一名角色下一次造成的伤害+1。", + hsdusu_kuyecao: "枯叶草", + hsdusu_kuyecao_info: "令一名角色获得技能潜行,直到其下一回合开始。", + hsdusu_huoyanhua: "火焰花", + hsdusu_huoyanhua_info: "对攻击范围内的一名角色造成1点火焰伤害。", + hsdusu_huangxuecao: "皇血草", + hsdusu_huangxuecao_info: "摸两张牌。", + duxin: "毒心", + duxin_info: "准备阶段和结束阶段,若你的手中没有毒素牌,你可以获得一张随机毒素牌。", + oldduxin: "毒心", + oldduxin_info: "准备阶段和结束阶段,你可以获得一张随机毒素牌。", + hstuteng: "图腾", + kuangluan: "狂乱", + kuangluan2: "狂乱", // kuangluan_info:'锁定技,每当你于回合内使用一张普通锦囊牌,便于出牌阶段结束时随机使用一张普通锦囊牌(随机指定目标)。', - kuangluan_info:'锁定技,每当一名其他角色对你造成伤害,该角色进入混乱状态直到当前回合结束。', - zengli:'赠礼', - zengli_info:'出牌阶段限一次,你指定一名其他角色与你各装备一把武器。', - xiubu:'修补', - xiubu_info:'每当你装备一把未强化的武器,你可以获得数量等同于武器攻击范围的随机零件。', - mobao:'魔爆', - mobao_info:'出牌阶段限一次,你可以弃置至多三张黑色牌,然后对所有于上轮对你造成过伤害的角色造成等同于你弃牌数的雷电伤害。', - xianji:'献祭', - xianji2:'献祭', - xianji3:'献祭', - xianji_info:'其他角色可以在其结束阶段弃置1~2张手牌并令你摸等量的牌,若如此做,直到其下一回合结束,每当你使用卡牌指定其为目标时,其摸一张牌。', - xueren:'血刃', - xueren_info:'每当你使用杀造成伤害,你可以令受伤害角色与你各失去1点体力,然后你摸两张牌。', - maoxian:'奇旅', - maoxian2:'奇旅', - maoxian_info:'出牌阶段限两次,你可以发现一个技能并获得之(替换此前发现的技能)。', - tanmi:'探秘', - tanmi_info:'在一名其他角色的结束阶段,若你没有手牌,你可以摸两张牌并可以使用两张牌。', - yiwen:'轶闻', - yiwen_info:'锁定技,每当其他角色于回合内首次使用非特殊卡牌指定你为惟一目标,你获得一张此牌的复制。', - tanbao_old:'探宝', - tanbao_old_info:'出牌阶段限一次,你可以弃置三张牌,然后展示牌堆顶的三张牌,然后获得其中任意张类别不同的牌;若三张牌类别均不相同,你回复全部体力值。', - qianghuax:'强化', - qianghuax_info:'出牌阶段限一次,你可以弃置任意张不同类别的牌,然后展示并获得与弃置的牌类别相同且价值更高的牌。', - zhuizong:'追踪', - zhuizong_info:'出牌阶段限一次,你可以弃置任意张牌,观看牌堆顶的等同于弃牌数四倍的牌,然后获得其中的一张牌。', - xunbao:'寻宝', - xunbao2:'寻宝', - xunbao_info:'准备阶段,若你的武将牌上没有藏宝图,你可以将一张藏宝图置于你的武将牌上;若你的武将牌上有藏宝图,你可以弃置一张与藏宝图点数相同的牌并获得此藏宝图。', - xieneng:'邪能', - xieneng_info:'结束阶段,你可以选择一张神器牌并获得之。', - fbeifa:'北伐', - fbeifa_info:'每当你失去最后一张手牌,你可以视为使用一张无视距离的杀,若此杀造成伤害,你摸一张牌,每回合最多发动3次。', - oldfbeifa:'北伐', - oldfbeifa_info:'每当你失去最后一张手牌,你可以视为使用一张无视距离的杀,若此杀造成伤害,你摸一张牌。', - yufa:'驭法', - yufa_info:'在任意一名其他角色的结束阶段,若你于此回合内受过其伤害,你可以将一张传送门交给除此角色外的任意一名角色。', - bingyan:'冰焰', - bingyan_info:'出牌阶段限一次,你可以将一张红色牌当作炽羽袭,或将一张黑色牌当作惊雷闪使用。', - hsshenqi:'神器', - hsshenqi_morijingxiang:'末日镜像', - hsshenqi_morijingxiang_info:'限武将牌正面朝上时使用,从所有其他角色的区域内各获得一张牌;使用后将武将牌翻至背面。', - hsshenqi_kongbusangzhong:'恐怖丧钟', - hsshenqi_kongbusangzhong_info:'限武将牌正面朝上时使用,对所有其他角色各造成1点伤害;使用后将武将牌翻至背面。', - hsshenqi_nengliangzhiguang:'能量之光', - hsshenqi_nengliangzhiguang_info:'限武将牌正面朝上时使用,令一名角色增加1点体力上限,回复1点体力,并摸四张牌;使用后将武将牌翻至背面。', - hsbaowu:'宝物', - hsbaowu_huangjinyuanhou:'黄金猿猴', - hsbaowu_huangjinyuanhou_info:'将你的手牌(含此张)替换为随机炉石衍生牌,并获得潜行直到下一回合开始。', - hsbaowu_cangbaotu:'藏宝图', - hsbaowu_cangbaotu_info:'结束阶段,将一张黄金猿猴置入你的手牌;摸一张牌。', - hsyaoshui:'药水', - hsqingyu:'青玉', + kuangluan_info: "锁定技,每当一名其他角色对你造成伤害,该角色进入混乱状态直到当前回合结束。", + zengli: "赠礼", + zengli_info: "出牌阶段限一次,你指定一名其他角色与你各装备一把武器。", + xiubu: "修补", + xiubu_info: "每当你装备一把未强化的武器,你可以获得数量等同于武器攻击范围的随机零件。", + mobao: "魔爆", + mobao_info: + "出牌阶段限一次,你可以弃置至多三张黑色牌,然后对所有于上轮对你造成过伤害的角色造成等同于你弃牌数的雷电伤害。", + xianji: "献祭", + xianji2: "献祭", + xianji3: "献祭", + xianji_info: + "其他角色可以在其结束阶段弃置1~2张手牌并令你摸等量的牌,若如此做,直到其下一回合结束,每当你使用卡牌指定其为目标时,其摸一张牌。", + xueren: "血刃", + xueren_info: "每当你使用杀造成伤害,你可以令受伤害角色与你各失去1点体力,然后你摸两张牌。", + maoxian: "奇旅", + maoxian2: "奇旅", + maoxian_info: "出牌阶段限两次,你可以发现一个技能并获得之(替换此前发现的技能)。", + tanmi: "探秘", + tanmi_info: "在一名其他角色的结束阶段,若你没有手牌,你可以摸两张牌并可以使用两张牌。", + yiwen: "轶闻", + yiwen_info: + "锁定技,每当其他角色于回合内首次使用非特殊卡牌指定你为惟一目标,你获得一张此牌的复制。", + tanbao_old: "探宝", + tanbao_old_info: + "出牌阶段限一次,你可以弃置三张牌,然后展示牌堆顶的三张牌,然后获得其中任意张类别不同的牌;若三张牌类别均不相同,你回复全部体力值。", + qianghuax: "强化", + qianghuax_info: + "出牌阶段限一次,你可以弃置任意张不同类别的牌,然后展示并获得与弃置的牌类别相同且价值更高的牌。", + zhuizong: "追踪", + zhuizong_info: + "出牌阶段限一次,你可以弃置任意张牌,观看牌堆顶的等同于弃牌数四倍的牌,然后获得其中的一张牌。", + xunbao: "寻宝", + xunbao2: "寻宝", + xunbao_info: + "准备阶段,若你的武将牌上没有藏宝图,你可以将一张藏宝图置于你的武将牌上;若你的武将牌上有藏宝图,你可以弃置一张与藏宝图点数相同的牌并获得此藏宝图。", + xieneng: "邪能", + xieneng_info: "结束阶段,你可以选择一张神器牌并获得之。", + fbeifa: "北伐", + fbeifa_info: + "每当你失去最后一张手牌,你可以视为使用一张无视距离的杀,若此杀造成伤害,你摸一张牌,每回合最多发动3次。", + oldfbeifa: "北伐", + oldfbeifa_info: + "每当你失去最后一张手牌,你可以视为使用一张无视距离的杀,若此杀造成伤害,你摸一张牌。", + yufa: "驭法", + yufa_info: + "在任意一名其他角色的结束阶段,若你于此回合内受过其伤害,你可以将一张传送门交给除此角色外的任意一名角色。", + bingyan: "冰焰", + bingyan_info: "出牌阶段限一次,你可以将一张红色牌当作炽羽袭,或将一张黑色牌当作惊雷闪使用。", + hsshenqi: "神器", + hsshenqi_morijingxiang: "末日镜像", + hsshenqi_morijingxiang_info: + "限武将牌正面朝上时使用,从所有其他角色的区域内各获得一张牌;使用后将武将牌翻至背面。", + hsshenqi_kongbusangzhong: "恐怖丧钟", + hsshenqi_kongbusangzhong_info: + "限武将牌正面朝上时使用,对所有其他角色各造成1点伤害;使用后将武将牌翻至背面。", + hsshenqi_nengliangzhiguang: "能量之光", + hsshenqi_nengliangzhiguang_info: + "限武将牌正面朝上时使用,令一名角色增加1点体力上限,回复1点体力,并摸四张牌;使用后将武将牌翻至背面。", + hsbaowu: "宝物", + hsbaowu_huangjinyuanhou: "黄金猿猴", + hsbaowu_huangjinyuanhou_info: + "将你的手牌(含此张)替换为随机炉石衍生牌,并获得潜行直到下一回合开始。", + hsbaowu_cangbaotu: "藏宝图", + hsbaowu_cangbaotu_info: "结束阶段,将一张黄金猿猴置入你的手牌;摸一张牌。", + hsyaoshui: "药水", + hsqingyu: "青玉", - lianzhan:'连斩', - lianzhan_info:'每当你造成一次伤害,若此伤害是你本回合第一次造成伤害,你摸两张牌;否则你增加1点体力上限并回复1点体力。', - shifa:'魔瘾', - shifa_info:'锁定技,每当你于回合内使用一张非转化的普通锦囊牌,你摸一张牌(每回合最多发动3次);出牌阶段开始时,你令你与一名随机敌人各获得一张随机普通锦囊牌。', - oldshifa:'魔瘾', - oldshifa_info:'锁定技,每当你于回合内使用一张非转化的普通锦囊牌,你摸一张牌;出牌阶段开始时,你令你与一名随机敌人各获得一张随机普通锦囊牌。', - yuanzheng:'远征', - yuanzheng_info:'每当你对距离1以外的角色使用一张牌,你可以弃置目标区域内的一张牌。', - bzhuiji:'追击', - bzhuiji_info:'每当一名角色死亡,你可以摸两张牌,并视为对杀死该角色的人使用一张决斗。', - byuhuo:'浴火', - byuhuo2:'浴火', - byuhuo_info:'觉醒技,当你进入濒死状态时,你须将体力和体力上限变为2,并将武将牌翻至背面;在你的下一准备阶段,你对所有其他角色造成2点火焰伤害,在此之前,你不能成为其他角色的卡牌的目标。', - yulu:'雨露', - yulu_info:'出牌阶段限一次,你可以指定任意名角色各摸一张牌,然后各弃置区域内的一张牌。', - oldyulu:'雨露', - oldyulu_info:'出牌阶段限一次,你可以指定任意名角色各摸两张牌,然后各弃置区域内的两张牌。', - duzhang:'毒瘴', - duzhang2:'毒瘴', - duzhang_info:'结束阶段,若你于本回合内未使用过锦囊牌,你可以指定一名其他角色令其下个回合无法使用锦囊牌。', - hannu:'寒怒', - hannu_info:'锁定技,每当你受到一次伤害,你将手牌数翻倍;若你的手牌数因此超过10张,你随机弃置若干张手牌直到手牌数等于你当前的体力值。', - chuidiao:'垂钓', - chuidiao_info:'锁定技,结束阶段,你随机摸0~2张牌。', - fushi:'缚誓', - fushi_info:'出牌阶段限一次,你可以令一名已受伤角色失去1点体力上限并回复1点体力。', - oldfushi:'缚誓', - oldfushi_info:'出牌阶段,你可以令一名已受伤角色失去1点体力上限并回复1点体力。', - hhudun:'护盾', - hhudun_info:'锁定技,在每名角色的准备阶段,若你没有护甲,你获得1点护甲;每当你的护甲抵消一次伤害,你摸一张牌。', - fenlie:'分裂', - fenlie_info:'锁定技,每当你于摸牌阶段外获得非特殊卡牌,你获得一张此牌的复制,每回合最多发动两次。', - oldfenlie:'分裂', - oldfenlie_info:'锁定技,每当你于摸牌阶段外获得非特殊卡牌,你获得一张此牌的复制。', - nianfu:'粘附', - nianfu_info:'锁定技,每当你造成或受到伤害,你随机获得对方装备区内的一张牌。', - xiaorong:'消融', - xiaorong_info:'锁定技,你的装备牌不占用手牌上限;结束阶段,你将手牌中的每张装备牌转化为两张随机基本牌,每转化一张装备牌便回复1点体力。', - shixu:'时序', - shixu_info:'锁定技,所有角色于出牌阶段每消耗3秒,便须于结束阶段弃置一张牌。', - qianghua:'绝手', - qianghua_info:'出牌阶段内,你可以令一张你使用的基本牌或普通锦囊牌额外结算一次,每回合限一次。', - jixuan:'疾旋', - jixuan_info:'锁定技,回合结束后,你摸一张牌进行一个额外的回合。', - biri:'蔽日', - biri_info:'每当距离你1以内的一名其他角色成为杀的惟一目标时,若杀的使用者不是你,你可以弃置一张闪取消之。', - stuxi:'吐息', - stuxi2:'吐息', - stuxi2_bg:'息', - stuxi_info:'锁定技,结束阶段,你令一名随机敌人下一个摸牌阶段摸牌数-1。', - bingdong:'冰冻', - bingdong_info:'锁定技,你在一个回合内首次造成伤害后,获得一个冰冻零件。', - ronghuo:'熔火', - ronghuo_info:'锁定技,你的普通杀均视为火杀。', - luoshi:'落石', - luoshi_info:'锁定技,每当你受到一次伤害,你与伤害来源各随机弃置一张牌。', - moyao:'魔曜', - moyao_info:'锁定技,你不能成为其他角色的锦囊牌的目标。', - jiaohui:'教诲', - jiaohui_info:'结束阶段,若你没有于本回合内造成伤害,你可以令一名角色摸一张牌或回复1点体力。', - bimeng:'碧梦', - bimeng_info:'结束阶段,你可以将一张随机梦境牌加入你的手牌。', - hsmengjing:'梦境', - hsmengjing_card_config:'梦境', - hsmengjing_feicuiyoulong:'翡翠幼龙', - hsmengjing_feicuiyoulong_info:'出牌阶段对任意一名角色使用,对目标造成1点伤害。', - hsmengjing_huanxiaojiemei:'欢笑姐妹', - hsmengjing_huanxiaojiemei_info:'出牌阶段对一名已受伤角色使用,令目标恢复1点体力。', - hsmengjing_suxing:'苏醒', - hsmengjing_suxing_info:'令所有其他角色失去1点体力并随机弃置两张牌。', - hsmengjing_mengye:'梦魇', - hsmengjing_mengye_info:'令一名角色摸一张牌,并在其下一个结束阶段弃置其所有牌。', - hsmengjing_mengjing:'梦境', - hsmengjing_mengjing_info:'令一名角色将装备区内的所有牌收入手牌,并将一张乐不思蜀置于其判定区。', - hszuzhou:'诅咒', - hszuzhou_nvwudeganguo:'女巫的钳锅', - hszuzhou_nvwudeganguo_info:'出牌阶段对一名角色使用,目标弃置一张牌,然后随机获得一张炉石衍生牌。', - hszuzhou_nvwudepingguo:'女巫的苹果', - hszuzhou_nvwudepingguo_info:'出牌阶段对一名角色使用,目标获得两张杀。', - hszuzhou_nvwudexuetu:'女巫的学徒', - hszuzhou_nvwudexuetu_info:'出牌阶段对没有咒降技能的角色使用,令目标非锁定技失效,并获得技能咒降直到下一回合结束。', - hszuzhou_wushushike:'巫术时刻', - hszuzhou_wushushike_info:'出牌阶段对所有角色使用,将手牌中的闪替换为杀。', - hszuzhou_guhuo:'蛊惑', - hszuzhou_guhuo_info:'出牌阶段对一名其他角色使用,令其交给你一张牌。', - xjumo:'聚魔', - xjumo_info:'锁定技,你的手牌上限+3;若你已受伤,改为+5。', - liehun:'裂魂', - liehun_info:'锁定技,结束阶段,你获得手牌中所有非基本、非特殊牌的复制。', - malymowang:'魔网', - malymowang_info:'锁定技,你的锦囊牌在每回合中造成的首次伤害+1;出牌阶段开始时,你发现一张普通锦囊牌。', - oldmalymowang:'魔网', - oldmalymowang_info:'锁定技,你的锦囊牌造成的伤害+1;出牌阶段开始时,你发现一张普通锦囊牌。', - lingzhou:'灵咒', - lingzhou_info:'每当你使用一张非转化的锦囊牌,可令一名角色摸一张牌或回复1点体力。', - mieshi:'灭世', - mieshi_info:'锁定技,结束阶段,你失去1点体力,并对一名随机的其他角色造成1点火焰伤害。', - xshixin:'蚀心', - xshixin_info:'锁定技,每当你对一名其他角色造成一次伤害,受伤害角色与你各失去1点体力。', - xshixin_info_alter:'锁定技,每当你对一名其他角色造成一次伤害,若受伤害角色体力值不小于你,其与你各失去1点体力。', - xmojian:'魔箭', - xmojian_info:'每当你的武将牌翻至正面时,你可以指定一名角色视为对其使用了一张杀。', - enze:'恩泽', - enze_info:'出牌阶段限一次,你可以指定一名角色令其手牌数与你相等(最多摸或弃三张牌)。', - oldenze:'恩泽', - oldenze_info:'出牌阶段限一次,你可以指定一名角色令其手牌数与你相等。', - enze_info_alter:'出牌阶段限一次,你可以指定一名角色令其手牌数与你相等(最多摸或弃两张牌)。', - chongsheng:'重生', - chongsheng_bg:'生', - chongsheng_info:'濒死阶段,你可弃置所有牌,将体力回复至2-X,并摸2-X张牌,X为你本局发动此技能的次数。每局最多发动2次。', - s_tuteng:'神谕', - s_tuteng_info:'锁定技,准备阶段,你随机获得一个图腾,若你已有至少3个图腾,则改为随机替换一个图腾。', - guozai:'过载', - guozai2:'过载', - guozai2_bg:'载', - guozai_info:'出牌阶段限一次,你可将手牌补至四张,并于此阶段结束时弃置等量的牌。', - guozai_info_alter:'出牌阶段限一次,你可将手牌补至三张,并于此阶段结束时弃置等量的牌。', - guozaix:'过载', - guozaix2:'过载', - guozaix2_bg:'载', - guozaix_info:'出牌阶段限两次,你可将手牌补至四张,并于此阶段结束时弃置等量的牌。', - oldhanshuang:'寒霜', - oldhanshuang_info:'锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面。', - hanshuang:'寒霜', - hanshuang_info:'锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面,然后你失去1点体力。', - hanshuang_info_alter:'锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面并摸一张牌,然后你失去1点体力。', - bingshi:'冰噬', - bingshi_info:'锁定技,你死亡时,对所有其他角色造成1点伤害。', - huanwu:'唤雾', - huanwu_info:'出牌阶段限一次,你可以令一名角色增加1点体力上限,回复1点体力,并摸两张牌(每名角色限发动一次)。', - fengnu:'风怒', - fengnu_info:'锁定技,你使用的任何卡牌无数量及距离限制;当你于回合内重复使用同名卡牌时,你摸一张牌(每回合最多以此法摸三张牌)。', - fengnu_info_alter:'锁定技,你使用的任何卡牌无数量限制;当你于回合内重复使用同名卡牌时,你摸一张牌(每回合最多以此法摸三张牌)。', - shengdun:'圣盾', - shengdun2:'圣盾', - shengdun_info:'锁定技,准备阶段,若你没有护甲,你获得1点护甲。', - jingmeng:'镜梦', - jingmeng_info:'每当你于回合内使用第一张牌时,你可以从牌堆中随机获得一张与之类型相同的牌。', - kuixin:'窥心', - kuixin_info:'结束阶段,你可以获得一名手牌数不少于你的角色的一张手牌。', - hswuji:'无羁', - hswuji_info:'出牌阶段结束时,你可以摸X张牌,X为你本回合使用的卡牌数。', - yanshu:'炎舞', - yanshu_info:'每回合限一次,当你弃置非基本牌后,你可以获得一张流星火雨。', - oldyanshu:'炎舞', - oldyanshu_info:'当你弃置非基本牌后,你可以获得一张流星火雨。', - bingshuang:'冰枪', - bingshuang_info:'你使用锦囊牌造成伤害后,可令目标摸两张牌并翻面。', - shengyan:'圣言', - shengyan_info:'任意一名角色回复体力后,你可以令其额外回复1点体力,每回合限发动一次。', - qingliu:'清流', - qingliu_info:'锁定技,你防止即将受到的火焰伤害。', - liechao:'猎潮', - liechao_info:'出牌阶阶段限一次,若你的武将牌正面朝上且手牌数不大于当前体力值,你可以翻面并摸四张牌,若如此做,你跳过本回合的弃牌阶段。', - liechao_info_alter:'出牌阶阶段限一次,若你的武将牌正面朝上且手牌数不大于当前体力值,你可以翻面并摸三张牌,若如此做,你跳过本回合的弃牌阶段。', - aoshu:'奥术', - aoshu_info:'出牌阶段限一次,你可以将一张黑桃牌当作无中生有使用。', + lianzhan: "连斩", + lianzhan_info: + "每当你造成一次伤害,若此伤害是你本回合第一次造成伤害,你摸两张牌;否则你增加1点体力上限并回复1点体力。", + shifa: "魔瘾", + shifa_info: + "锁定技,每当你于回合内使用一张非转化的普通锦囊牌,你摸一张牌(每回合最多发动3次);出牌阶段开始时,你令你与一名随机敌人各获得一张随机普通锦囊牌。", + oldshifa: "魔瘾", + oldshifa_info: + "锁定技,每当你于回合内使用一张非转化的普通锦囊牌,你摸一张牌;出牌阶段开始时,你令你与一名随机敌人各获得一张随机普通锦囊牌。", + yuanzheng: "远征", + yuanzheng_info: "每当你对距离1以外的角色使用一张牌,你可以弃置目标区域内的一张牌。", + bzhuiji: "追击", + bzhuiji_info: "每当一名角色死亡,你可以摸两张牌,并视为对杀死该角色的人使用一张决斗。", + byuhuo: "浴火", + byuhuo2: "浴火", + byuhuo_info: + "觉醒技,当你进入濒死状态时,你须将体力和体力上限变为2,并将武将牌翻至背面;在你的下一准备阶段,你对所有其他角色造成2点火焰伤害,在此之前,你不能成为其他角色的卡牌的目标。", + yulu: "雨露", + yulu_info: "出牌阶段限一次,你可以指定任意名角色各摸一张牌,然后各弃置区域内的一张牌。", + oldyulu: "雨露", + oldyulu_info: "出牌阶段限一次,你可以指定任意名角色各摸两张牌,然后各弃置区域内的两张牌。", + duzhang: "毒瘴", + duzhang2: "毒瘴", + duzhang_info: + "结束阶段,若你于本回合内未使用过锦囊牌,你可以指定一名其他角色令其下个回合无法使用锦囊牌。", + hannu: "寒怒", + hannu_info: + "锁定技,每当你受到一次伤害,你将手牌数翻倍;若你的手牌数因此超过10张,你随机弃置若干张手牌直到手牌数等于你当前的体力值。", + chuidiao: "垂钓", + chuidiao_info: "锁定技,结束阶段,你随机摸0~2张牌。", + fushi: "缚誓", + fushi_info: "出牌阶段限一次,你可以令一名已受伤角色失去1点体力上限并回复1点体力。", + oldfushi: "缚誓", + oldfushi_info: "出牌阶段,你可以令一名已受伤角色失去1点体力上限并回复1点体力。", + hhudun: "护盾", + hhudun_info: + "锁定技,在每名角色的准备阶段,若你没有护甲,你获得1点护甲;每当你的护甲抵消一次伤害,你摸一张牌。", + fenlie: "分裂", + fenlie_info: + "锁定技,每当你于摸牌阶段外获得非特殊卡牌,你获得一张此牌的复制,每回合最多发动两次。", + oldfenlie: "分裂", + oldfenlie_info: "锁定技,每当你于摸牌阶段外获得非特殊卡牌,你获得一张此牌的复制。", + nianfu: "粘附", + nianfu_info: "锁定技,每当你造成或受到伤害,你随机获得对方装备区内的一张牌。", + xiaorong: "消融", + xiaorong_info: + "锁定技,你的装备牌不占用手牌上限;结束阶段,你将手牌中的每张装备牌转化为两张随机基本牌,每转化一张装备牌便回复1点体力。", + shixu: "时序", + shixu_info: "锁定技,所有角色于出牌阶段每消耗3秒,便须于结束阶段弃置一张牌。", + qianghua: "绝手", + qianghua_info: "出牌阶段内,你可以令一张你使用的基本牌或普通锦囊牌额外结算一次,每回合限一次。", + jixuan: "疾旋", + jixuan_info: "锁定技,回合结束后,你摸一张牌进行一个额外的回合。", + biri: "蔽日", + biri_info: + "每当距离你1以内的一名其他角色成为杀的惟一目标时,若杀的使用者不是你,你可以弃置一张闪取消之。", + stuxi: "吐息", + stuxi2: "吐息", + stuxi2_bg: "息", + stuxi_info: "锁定技,结束阶段,你令一名随机敌人下一个摸牌阶段摸牌数-1。", + bingdong: "冰冻", + bingdong_info: "锁定技,你在一个回合内首次造成伤害后,获得一个冰冻零件。", + ronghuo: "熔火", + ronghuo_info: "锁定技,你的普通杀均视为火杀。", + luoshi: "落石", + luoshi_info: "锁定技,每当你受到一次伤害,你与伤害来源各随机弃置一张牌。", + moyao: "魔曜", + moyao_info: "锁定技,你不能成为其他角色的锦囊牌的目标。", + jiaohui: "教诲", + jiaohui_info: "结束阶段,若你没有于本回合内造成伤害,你可以令一名角色摸一张牌或回复1点体力。", + bimeng: "碧梦", + bimeng_info: "结束阶段,你可以将一张随机梦境牌加入你的手牌。", + hsmengjing: "梦境", + hsmengjing_card_config: "梦境", + hsmengjing_feicuiyoulong: "翡翠幼龙", + hsmengjing_feicuiyoulong_info: "出牌阶段对任意一名角色使用,对目标造成1点伤害。", + hsmengjing_huanxiaojiemei: "欢笑姐妹", + hsmengjing_huanxiaojiemei_info: "出牌阶段对一名已受伤角色使用,令目标恢复1点体力。", + hsmengjing_suxing: "苏醒", + hsmengjing_suxing_info: "令所有其他角色失去1点体力并随机弃置两张牌。", + hsmengjing_mengye: "梦魇", + hsmengjing_mengye_info: "令一名角色摸一张牌,并在其下一个结束阶段弃置其所有牌。", + hsmengjing_mengjing: "梦境", + hsmengjing_mengjing_info: "令一名角色将装备区内的所有牌收入手牌,并将一张乐不思蜀置于其判定区。", + hszuzhou: "诅咒", + hszuzhou_nvwudeganguo: "女巫的钳锅", + hszuzhou_nvwudeganguo_info: + "出牌阶段对一名角色使用,目标弃置一张牌,然后随机获得一张炉石衍生牌。", + hszuzhou_nvwudepingguo: "女巫的苹果", + hszuzhou_nvwudepingguo_info: "出牌阶段对一名角色使用,目标获得两张杀。", + hszuzhou_nvwudexuetu: "女巫的学徒", + hszuzhou_nvwudexuetu_info: + "出牌阶段对没有咒降技能的角色使用,令目标非锁定技失效,并获得技能咒降直到下一回合结束。", + hszuzhou_wushushike: "巫术时刻", + hszuzhou_wushushike_info: "出牌阶段对所有角色使用,将手牌中的闪替换为杀。", + hszuzhou_guhuo: "蛊惑", + hszuzhou_guhuo_info: "出牌阶段对一名其他角色使用,令其交给你一张牌。", + xjumo: "聚魔", + xjumo_info: "锁定技,你的手牌上限+3;若你已受伤,改为+5。", + liehun: "裂魂", + liehun_info: "锁定技,结束阶段,你获得手牌中所有非基本、非特殊牌的复制。", + malymowang: "魔网", + malymowang_info: + "锁定技,你的锦囊牌在每回合中造成的首次伤害+1;出牌阶段开始时,你发现一张普通锦囊牌。", + oldmalymowang: "魔网", + oldmalymowang_info: "锁定技,你的锦囊牌造成的伤害+1;出牌阶段开始时,你发现一张普通锦囊牌。", + lingzhou: "灵咒", + lingzhou_info: "每当你使用一张非转化的锦囊牌,可令一名角色摸一张牌或回复1点体力。", + mieshi: "灭世", + mieshi_info: "锁定技,结束阶段,你失去1点体力,并对一名随机的其他角色造成1点火焰伤害。", + xshixin: "蚀心", + xshixin_info: "锁定技,每当你对一名其他角色造成一次伤害,受伤害角色与你各失去1点体力。", + xshixin_info_alter: + "锁定技,每当你对一名其他角色造成一次伤害,若受伤害角色体力值不小于你,其与你各失去1点体力。", + xmojian: "魔箭", + xmojian_info: "每当你的武将牌翻至正面时,你可以指定一名角色视为对其使用了一张杀。", + enze: "恩泽", + enze_info: "出牌阶段限一次,你可以指定一名角色令其手牌数与你相等(最多摸或弃三张牌)。", + oldenze: "恩泽", + oldenze_info: "出牌阶段限一次,你可以指定一名角色令其手牌数与你相等。", + enze_info_alter: "出牌阶段限一次,你可以指定一名角色令其手牌数与你相等(最多摸或弃两张牌)。", + chongsheng: "重生", + chongsheng_bg: "生", + chongsheng_info: + "濒死阶段,你可弃置所有牌,将体力回复至2-X,并摸2-X张牌,X为你本局发动此技能的次数。每局最多发动2次。", + s_tuteng: "神谕", + s_tuteng_info: + "锁定技,准备阶段,你随机获得一个图腾,若你已有至少3个图腾,则改为随机替换一个图腾。", + guozai: "过载", + guozai2: "过载", + guozai2_bg: "载", + guozai_info: "出牌阶段限一次,你可将手牌补至四张,并于此阶段结束时弃置等量的牌。", + guozai_info_alter: "出牌阶段限一次,你可将手牌补至三张,并于此阶段结束时弃置等量的牌。", + guozaix: "过载", + guozaix2: "过载", + guozaix2_bg: "载", + guozaix_info: "出牌阶段限两次,你可将手牌补至四张,并于此阶段结束时弃置等量的牌。", + oldhanshuang: "寒霜", + oldhanshuang_info: "锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面。", + hanshuang: "寒霜", + hanshuang_info: + "锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面,然后你失去1点体力。", + hanshuang_info_alter: + "锁定技,你使用黑色牌对一名未翻面角色造成伤害后,你令受伤害角色翻面并摸一张牌,然后你失去1点体力。", + bingshi: "冰噬", + bingshi_info: "锁定技,你死亡时,对所有其他角色造成1点伤害。", + huanwu: "唤雾", + huanwu_info: + "出牌阶段限一次,你可以令一名角色增加1点体力上限,回复1点体力,并摸两张牌(每名角色限发动一次)。", + fengnu: "风怒", + fengnu_info: + "锁定技,你使用的任何卡牌无数量及距离限制;当你于回合内重复使用同名卡牌时,你摸一张牌(每回合最多以此法摸三张牌)。", + fengnu_info_alter: + "锁定技,你使用的任何卡牌无数量限制;当你于回合内重复使用同名卡牌时,你摸一张牌(每回合最多以此法摸三张牌)。", + shengdun: "圣盾", + shengdun2: "圣盾", + shengdun_info: "锁定技,准备阶段,若你没有护甲,你获得1点护甲。", + jingmeng: "镜梦", + jingmeng_info: "每当你于回合内使用第一张牌时,你可以从牌堆中随机获得一张与之类型相同的牌。", + kuixin: "窥心", + kuixin_info: "结束阶段,你可以获得一名手牌数不少于你的角色的一张手牌。", + hswuji: "无羁", + hswuji_info: "出牌阶段结束时,你可以摸X张牌,X为你本回合使用的卡牌数。", + yanshu: "炎舞", + yanshu_info: "每回合限一次,当你弃置非基本牌后,你可以获得一张流星火雨。", + oldyanshu: "炎舞", + oldyanshu_info: "当你弃置非基本牌后,你可以获得一张流星火雨。", + bingshuang: "冰枪", + bingshuang_info: "你使用锦囊牌造成伤害后,可令目标摸两张牌并翻面。", + shengyan: "圣言", + shengyan_info: "任意一名角色回复体力后,你可以令其额外回复1点体力,每回合限发动一次。", + qingliu: "清流", + qingliu_info: "锁定技,你防止即将受到的火焰伤害。", + liechao: "猎潮", + liechao_info: + "出牌阶阶段限一次,若你的武将牌正面朝上且手牌数不大于当前体力值,你可以翻面并摸四张牌,若如此做,你跳过本回合的弃牌阶段。", + liechao_info_alter: + "出牌阶阶段限一次,若你的武将牌正面朝上且手牌数不大于当前体力值,你可以翻面并摸三张牌,若如此做,你跳过本回合的弃牌阶段。", + aoshu: "奥术", + aoshu_info: "出牌阶段限一次,你可以将一张黑桃牌当作无中生有使用。", - qianhou:'千喉', - qianhou_info:'锁定技,准备阶段,你视为使用一张随机普通锦囊牌(随机指定目标);若目标只有1人且不是你,你可以弃置一张手牌并获得此锦囊。', - fengxing:'风行', - fengxing_info:'每当你于回合外首次失去牌,你可以弃置一张牌并摸两张牌。', - xinci:'心刺', - xinci_bg:'暗', - xinci_info:'出牌阶段限一次,你可以弃置一张黑色牌令一名角色失去1点体力。', - zhongjia:'战甲', - zhongjia_info:'锁定技,每当你受到一次伤害,你获得1点护甲;当你的体力值大于1且大于手牌数时,你的护甲不为你抵挡伤害。', - dunji:'盾击', - dunji_info:'出牌阶段限一次,你可以对攻击范围内的至多X名其他角色各造成1点伤害,并失去等量的护甲,X为你的护甲数。', - qiaodong:'巧动', - qiaodong_info:'你可以将一张装备牌当作闪使用或打出。', - fengxian:'奉献', - fengxian_info:'出牌阶段限一次,你可以令场上所有角色各弃置一张手牌。', - zhanhou:'战吼', - zhanhou_info:'出牌阶段限一次,你可以弃置一张防具牌并获得1点护甲。', - oldzhanhou:'战吼', - oldzhanhou_info:'出牌阶段,你可以弃置一张防具牌并获得1点护甲。', - anying:'暗影', - anying_info:'限定技,出牌阶段,你可以弃置一张黑色牌,失去技能圣光,并获得技能心刺。', - shijie:'视界', - shijie_info:'结束阶段,你可以获得一名其他角色的一张手牌,然后该角色摸一张牌。', - shengguang:'圣光', - shengguang_info:'出牌阶段限一次,你可以弃置一张红色牌令一名角色回复1点体力。', - bingjia:'冰甲', - bingjia2:'冰甲', - bingjia_info:'出牌阶段,若你武将牌上没有牌,你可以将一张手牌背面朝上置于你的武将牌上,当你成为其他角色的与此牌花色相同的牌的目标时,你移去此牌,获得1点护甲,并且本回合内防止一切伤害。', - bianxing:'变形', - bianxing_info:'当一其他角色于回合内使用卡牌指定了惟一的其他目标后,你可以用一张合理的基本牌替代此牌,每名角色的回合限一次。', - xianzhi:'先知', - xianzhi_info:'任意一名角色进行判定前,你可以观看牌堆顶的两张牌,并可以将其调换顺序。', - mdzhoufu:'缚魂', - mdzhoufu2:'缚魂', - mdzhoufu_info:'出牌阶段,你可以将一张黑色手牌置于一名其他角色的武将牌上,在其判定时以此牌作为判定结果,然后你获得亮出的判定牌。', - zuzhou:'诅咒', - zuzhou_info:'锁定技,准备阶段,若场上没有浮雷且你手牌中有黑桃牌,你将牌堆中的一张浮雷置于你的判定区;当一名角色受到浮雷伤害时,你移去此浮雷。', - zuzhou_old_info:'每当你造成或受到一次伤害,你可以令伤害目标或来源进行一次判定,若结果为黑色,其失去1点体力。', - jingxiang:'镜像', - jingxiang_info:'每回合限一次,当你需要打出卡牌时,你可以观看一名角色的手牌并将其视为你的手牌打出。', - jingxiang_info_alter:'每回合限一次,当你需要打出卡牌时,你可以观看一名手牌数不多于你的角色的手牌并将其视为你的手牌打出。', - tuteng:'图腾', - tuteng_info:'出牌阶段,你可以获得一个随机基础图腾;每当你受到一次伤害,你随机失去一个图腾。', - zuling:'祖灵', - zuling_info:'觉醒技,准备阶段,若你拥有至少3个图腾,你失去1点体力上限,并将图腾描述中的“获得一个随机基础图腾”改为“获得任意一个图腾(若有4个图腾则改为替换一个图腾)”。', - tuteng1:'治疗图腾', - tuteng1_info:'结束阶段,你回复1点体力。', - tuteng2:'灼热图腾', - tuteng2_info:'每当你造成一次伤害,你摸一张牌。', - tuteng3:'石爪图腾', - tuteng3_info:'你受到下一次伤害时,令伤害-1,然后失去此图腾。', - tuteng4:'空气图腾', - tuteng4_info:'在你的回合内,你的锦囊牌造成的首次伤害+1。', - tuteng5:'法潮图腾', - tuteng5_info:'结束阶段,你摸一张牌。', - tuteng6:'火舌图腾', - tuteng6_info:'在你的回合内,你的杀造成的首次伤害+1。', - tuteng7:'活力图腾', - tuteng7_info:'结束阶段,你令一名其他角色回复1点体力。', - tuteng8:'图腾魔像', - tuteng8_info:'你的进攻距离+1。', - tzhenji:'震击', - tzhenji_info:'每当你因弃置而失去黑色牌,可对一名角色造成1点雷电伤害,并随机弃置其一张牌,每回合限发动一次。', - fenliu:'分流', - fenliu_info:'出牌阶段限一次,你可以失去1点体力并获得三张牌。', - hongxi:'虹吸', - hongxi_info:'锁定技,每当有一名角色死亡,你将体力回复至体力上限。', - jihuo:'激活', - jihuo_info:'在你的回合结束后,你可以弃置一张手牌并进行一个额外的回合。', - jianren:'刃舞', - jianren_info:'出牌阶段限一次,你可以弃置装备区内的武器牌,对所有其他角色造成1点伤害。', - mengun:'闷棍', - mengun2:'闷棍', - mengun_info:'每当一名其他角色于回合内使用基本牌,你可以弃置一张与之花色相同的牌令其收回此牌,且在本回合内不能再次使用,每回合限一次。', - wlianji:'连击', - wlianji_info:'结束阶段,若你本回合使用的卡牌数大于你当前的体力值,你可以摸两张牌。', + qianhou: "千喉", + qianhou_info: + "锁定技,准备阶段,你视为使用一张随机普通锦囊牌(随机指定目标);若目标只有1人且不是你,你可以弃置一张手牌并获得此锦囊。", + fengxing: "风行", + fengxing_info: "每当你于回合外首次失去牌,你可以弃置一张牌并摸两张牌。", + xinci: "心刺", + xinci_bg: "暗", + xinci_info: "出牌阶段限一次,你可以弃置一张黑色牌令一名角色失去1点体力。", + zhongjia: "战甲", + zhongjia_info: + "锁定技,每当你受到一次伤害,你获得1点护甲;当你的体力值大于1且大于手牌数时,你的护甲不为你抵挡伤害。", + dunji: "盾击", + dunji_info: + "出牌阶段限一次,你可以对攻击范围内的至多X名其他角色各造成1点伤害,并失去等量的护甲,X为你的护甲数。", + qiaodong: "巧动", + qiaodong_info: "你可以将一张装备牌当作闪使用或打出。", + fengxian: "奉献", + fengxian_info: "出牌阶段限一次,你可以令场上所有角色各弃置一张手牌。", + zhanhou: "战吼", + zhanhou_info: "出牌阶段限一次,你可以弃置一张防具牌并获得1点护甲。", + oldzhanhou: "战吼", + oldzhanhou_info: "出牌阶段,你可以弃置一张防具牌并获得1点护甲。", + anying: "暗影", + anying_info: "限定技,出牌阶段,你可以弃置一张黑色牌,失去技能圣光,并获得技能心刺。", + shijie: "视界", + shijie_info: "结束阶段,你可以获得一名其他角色的一张手牌,然后该角色摸一张牌。", + shengguang: "圣光", + shengguang_info: "出牌阶段限一次,你可以弃置一张红色牌令一名角色回复1点体力。", + bingjia: "冰甲", + bingjia2: "冰甲", + bingjia_info: + "出牌阶段,若你武将牌上没有牌,你可以将一张手牌背面朝上置于你的武将牌上,当你成为其他角色的与此牌花色相同的牌的目标时,你移去此牌,获得1点护甲,并且本回合内防止一切伤害。", + bianxing: "变形", + bianxing_info: + "当一其他角色于回合内使用卡牌指定了惟一的其他目标后,你可以用一张合理的基本牌替代此牌,每名角色的回合限一次。", + xianzhi: "先知", + xianzhi_info: "任意一名角色进行判定前,你可以观看牌堆顶的两张牌,并可以将其调换顺序。", + mdzhoufu: "缚魂", + mdzhoufu2: "缚魂", + mdzhoufu_info: + "出牌阶段,你可以将一张黑色手牌置于一名其他角色的武将牌上,在其判定时以此牌作为判定结果,然后你获得亮出的判定牌。", + zuzhou: "诅咒", + zuzhou_info: + "锁定技,准备阶段,若场上没有浮雷且你手牌中有黑桃牌,你将牌堆中的一张浮雷置于你的判定区;当一名角色受到浮雷伤害时,你移去此浮雷。", + zuzhou_old_info: + "每当你造成或受到一次伤害,你可以令伤害目标或来源进行一次判定,若结果为黑色,其失去1点体力。", + jingxiang: "镜像", + jingxiang_info: + "每回合限一次,当你需要打出卡牌时,你可以观看一名角色的手牌并将其视为你的手牌打出。", + jingxiang_info_alter: + "每回合限一次,当你需要打出卡牌时,你可以观看一名手牌数不多于你的角色的手牌并将其视为你的手牌打出。", + tuteng: "图腾", + tuteng_info: "出牌阶段,你可以获得一个随机基础图腾;每当你受到一次伤害,你随机失去一个图腾。", + zuling: "祖灵", + zuling_info: + "觉醒技,准备阶段,若你拥有至少3个图腾,你失去1点体力上限,并将图腾描述中的“获得一个随机基础图腾”改为“获得任意一个图腾(若有4个图腾则改为替换一个图腾)”。", + tuteng1: "治疗图腾", + tuteng1_info: "结束阶段,你回复1点体力。", + tuteng2: "灼热图腾", + tuteng2_info: "每当你造成一次伤害,你摸一张牌。", + tuteng3: "石爪图腾", + tuteng3_info: "你受到下一次伤害时,令伤害-1,然后失去此图腾。", + tuteng4: "空气图腾", + tuteng4_info: "在你的回合内,你的锦囊牌造成的首次伤害+1。", + tuteng5: "法潮图腾", + tuteng5_info: "结束阶段,你摸一张牌。", + tuteng6: "火舌图腾", + tuteng6_info: "在你的回合内,你的杀造成的首次伤害+1。", + tuteng7: "活力图腾", + tuteng7_info: "结束阶段,你令一名其他角色回复1点体力。", + tuteng8: "图腾魔像", + tuteng8_info: "你的进攻距离+1。", + tzhenji: "震击", + tzhenji_info: + "每当你因弃置而失去黑色牌,可对一名角色造成1点雷电伤害,并随机弃置其一张牌,每回合限发动一次。", + fenliu: "分流", + fenliu_info: "出牌阶段限一次,你可以失去1点体力并获得三张牌。", + hongxi: "虹吸", + hongxi_info: "锁定技,每当有一名角色死亡,你将体力回复至体力上限。", + jihuo: "激活", + jihuo_info: "在你的回合结束后,你可以弃置一张手牌并进行一个额外的回合。", + jianren: "刃舞", + jianren_info: "出牌阶段限一次,你可以弃置装备区内的武器牌,对所有其他角色造成1点伤害。", + mengun: "闷棍", + mengun2: "闷棍", + mengun_info: + "每当一名其他角色于回合内使用基本牌,你可以弃置一张与之花色相同的牌令其收回此牌,且在本回合内不能再次使用,每回合限一次。", + wlianji: "连击", + wlianji_info: "结束阶段,若你本回合使用的卡牌数大于你当前的体力值,你可以摸两张牌。", }, }; }); diff --git a/character/huicui.js b/character/huicui.js index 0689c9478..d1bc8a563 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -1,1347 +1,1823 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'huicui', - connect:true, - character:{ - dc_caoshuang:['male','wei',4,['dcjianzhuan','dcfanshi']], - zangba:['male','wei',4,['rehengjiang']], - dc_simashi:['male','wei',3,['dcsanshi','dczhenrao','dcchenlve']], - dc_wangling:['male','wei',4,['dcjichou','dcmouli'],['clan:太原王氏']], - dc_jiangji:['male','wei',3,['dcshiju','dcyingshi']], - gongsunxiu:['male','qun',4,['dcgangu','dckuizhen']], - dc_liuli:['male','shu',3,['dcfuli','dcdehua']], - yue_daqiao:['female','wu',3,['dcqiqin','dczixi']], - dc_kongrong:['male','qun',3,['dckrmingshi','lirang']], - dc_sp_menghuo:['male','qun',4,['dcmanwang']], - dc_lingcao:['male','wu','4/5',['dcdufeng']], - yue_xiaoqiao:['female','wu',3,['dcqiqin','dcweiwan']], - dc_dongzhao:['male','wei',3,['dcyijia','dcdingji']], - kuaiqi:['male','wei',3,['dcliangxiu','dcxunjie']], - yue_caiyong:['male','qun',3,['dcjiaowei','dcfeibai']], - pangshanmin:['male','wei',3,['dccaisi','dczhuoli']], - dc_jiachong:['male','wei',3,['dcbeini','dcshizong']], - dc_sunchen:['male','wu',4,['dczigu','dczuowei']], - dc_zhangmancheng:['male','qun',4,['dclvecheng','dczhongji']], - yue_zhoufei:['female','wu',3,['dclingkong','dcxianshu']], - dc_wuban:['male','shu',4,['dcyouzhan'],['clan:陈留吴氏']], - yue_caiwenji:['female','qun',3,['dcshuangjia','dcbeifen']], - liuchongluojun:['male','qun',3,['dcminze','dcjini']], - yuechen:['male','wei',4,['dcporui','dcgonghu']], - zhangkai:['male','qun',4,['dcxiangshu']], - gaoxiang:['male','shu',4,['dcchiying']], - yuanyin:['male','qun',3,['dcmoshou','dcyunjiu']], - dongwan:['female','qun',3,['dcshengdu','dcjieling']], - zhangchu:['female','qun',3,['dcjizhong','dcrihui','dcguangshi']], - peiyuanshao:['male','qun',4,['dcmoyu']], - mengjie:['male','qun',3,['dcyinlu','dcyouqi']], - dc_huojun:['male','shu',4,['dcgue','dcsigong']], - dc_sunhanhua:['female','wu',3,['dchuiling','dcchongxu']], - dc_sunziliufang:['male','wei',3,['dcqinshen','dcweidang']], - yuantanyuanxiyuanshang:['male','qun',4,['dcneifa']], - qiaorui:['male','qun',4,['dcaishou','dcsaowei']], - xianglang:['male','shu',3,['dckanji','dcqianzheng']], - qinlang:['male','wei',4,['dchaochong','dcjinjin']], - furongfuqian:['male','shu','4/6',['dcxuewei','dcyuguan']], - zhenghun:['male','wei',3,['dcqiangzhi','dcpitian']], - dc_zhaotongzhaoguang:['male','shu',4,['yizan_use','dcqingren','dclongyuan']], - dc_huanghao:['male','shu',3,['dcqinqing','huisheng','dccunwei']], - liupi:['male','qun',4,['dcjuying']], - dc_sp_jiaxu:['male','wei',3,['zhenlue','dcjianshu','dcyongdi']], - leibo:['male','qun',4,['dcsilve','dcshuaijie']], - gongsundu:['male','qun',4,['dczhenze','dcanliao']], - panghui:['male','wei',5,['dcyiyong']], - dc_yuejiu:['male','qun',4,['dccuijin']], - chenjiao:['male','wei',3,['dcxieshou','dcqingyan','dcqizi']], - wanglie:['male','qun',3,['dcchongwang','dchuagui']], - chengui:['male','qun',3,['dcyingtu','dccongshi']], - dc_huangquan:['male','shu',3,['dcquanjian','dctujue']], - yinfuren:['female','wei',3,['dcyingyu','dcyongbi']], - dc_lvkuanglvxiang:['male','wei',4,['dcshuhe','dcliehou']], - guanhai:['male','qun',4,['suoliang','qinbao']], - huzhao:['male','qun',3,['midu','xianwang']], - dc_liuba:['male','shu',3,['dczhubi','dcliuzhuan']], - zhangxun:['male','qun',4,['suizheng']], - zongyu:['male','shu',3,['zyqiao','chengshang']], - dc_jiling:['male','qun',4,['dcshuangren']], - dc_yanghu:['male','wei',3,['dcdeshao','dcmingfa']], - caimaozhangyun:['male','wei',4,['lianzhou','jinglan']], - tenggongzhu:['female','wu',3,['xingchong','liunian']], - dc_huangchengyan:['male','qun',3,['dcjiezhen','dczecai','dcyinshi']], - dc_gaolan:['male','qun',4,['xizhen']], - guanning:['male','qun','3/7',['dunshi']], - dc_jiben:['male','qun',3,['xunli','zhishi','lieyi']], - mamidi:['male','qun','4/6',['bingjie','zhengding']], - re_dengzhi:['male','shu',3,['jianliang','weimeng']], - fengxi:['male','wu',3,['yusui','boyan']], - re_miheng:['male','qun',3,['rekuangcai','reshejian']], - re_chendeng:['male','qun',3,['refuyuan','reyingshui','rewangzu']], - wanniangongzhu:['female','qun',3,['zhenge','xinghan']], - re_xunchen:['male','qun',3,['refenglve','anyong'],['clan:颍川荀氏']], - re_kanze:['male','wu',3,['xiashu','rekuanshi']], - lvlingqi:['female','qun',4,['guowu','zhuangrong']], - zhanghu:['male','wei',4,['cuijian','zhtongyuan']], - luyusheng:['female','wu',3,['zhente','zhiwei']], - huaxin:['male','wei',3,['spwanggui','xibing']], - mengyou:['male','qun',5,['manyi','dcmanzhi']], - liuyong:['male','shu',3,['zhuning','fengxiang']], - dc_sunru:['female','wu',3,['xiecui','youxu']], - xiahoulingnv:['female','wei',4,['fuping','weilie']], - zhangyao:['female','wu',3,['yuanyu','xiyan']], - tengyin:['male','wu',3,['chenjian','xixiu']], - zhangxuan:['female','wu',4,['tongli','shezang']], - wangtao:['female','shu',3,['huguan','yaopei']], - wangyue:['female','shu',3,['huguan','mingluan']], - zhaoyan:['female','wu',3,['jinhui','qingman']], - heyan:['male','wei',3,['yachai','qingtan']], - re_sunluyu:['female','wu',3,['remeibu','remumu']], - re_dongbai:['female','qun',3,['relianzhu','rexiahui']], - zhoushan:['male','wu',4,['dcmiyun','dcdanying']], - dc_caiyang:['male','wei',4,['dcxunji','dcjiaofeng']], - xiahoujie:['male','wei',5,['liedan','zhuangdan']], - caoxing:['male','qun',4,['cxliushi','zhanwan']], - re_chunyuqiong:['male','qun',4,['recangchu','reliangying','reshishou']], - xingdaorong:['male','qun','4/6',['xuxie']], - re_panfeng:['male','qun',4,['xinkuangfu']], - jiangfei:['male','shu',3,['dcshengxi','dcshoucheng']], + name: "huicui", + connect: true, + character: { + dc_caoshuang: ["male", "wei", 4, ["dcjianzhuan", "dcfanshi"]], + zangba: ["male", "wei", 4, ["rehengjiang"]], + dc_simashi: ["male", "wei", 3, ["dcsanshi", "dczhenrao", "dcchenlve"]], + dc_wangling: ["male", "wei", 4, ["dcjichou", "dcmouli"], ["clan:太原王氏"]], + dc_jiangji: ["male", "wei", 3, ["dcshiju", "dcyingshi"]], + gongsunxiu: ["male", "qun", 4, ["dcgangu", "dckuizhen"]], + dc_liuli: ["male", "shu", 3, ["dcfuli", "dcdehua"]], + yue_daqiao: ["female", "wu", 3, ["dcqiqin", "dczixi"]], + dc_kongrong: ["male", "qun", 3, ["dckrmingshi", "lirang"]], + dc_sp_menghuo: ["male", "qun", 4, ["dcmanwang"]], + dc_lingcao: ["male", "wu", "4/5", ["dcdufeng"]], + yue_xiaoqiao: ["female", "wu", 3, ["dcqiqin", "dcweiwan"]], + dc_dongzhao: ["male", "wei", 3, ["dcyijia", "dcdingji"]], + kuaiqi: ["male", "wei", 3, ["dcliangxiu", "dcxunjie"]], + yue_caiyong: ["male", "qun", 3, ["dcjiaowei", "dcfeibai"]], + pangshanmin: ["male", "wei", 3, ["dccaisi", "dczhuoli"]], + dc_jiachong: ["male", "wei", 3, ["dcbeini", "dcshizong"]], + dc_sunchen: ["male", "wu", 4, ["dczigu", "dczuowei"]], + dc_zhangmancheng: ["male", "qun", 4, ["dclvecheng", "dczhongji"]], + yue_zhoufei: ["female", "wu", 3, ["dclingkong", "dcxianshu"]], + dc_wuban: ["male", "shu", 4, ["dcyouzhan"], ["clan:陈留吴氏"]], + yue_caiwenji: ["female", "qun", 3, ["dcshuangjia", "dcbeifen"]], + liuchongluojun: ["male", "qun", 3, ["dcminze", "dcjini"]], + yuechen: ["male", "wei", 4, ["dcporui", "dcgonghu"]], + zhangkai: ["male", "qun", 4, ["dcxiangshu"]], + gaoxiang: ["male", "shu", 4, ["dcchiying"]], + yuanyin: ["male", "qun", 3, ["dcmoshou", "dcyunjiu"]], + dongwan: ["female", "qun", 3, ["dcshengdu", "dcjieling"]], + zhangchu: ["female", "qun", 3, ["dcjizhong", "dcrihui", "dcguangshi"]], + peiyuanshao: ["male", "qun", 4, ["dcmoyu"]], + mengjie: ["male", "qun", 3, ["dcyinlu", "dcyouqi"]], + dc_huojun: ["male", "shu", 4, ["dcgue", "dcsigong"]], + dc_sunhanhua: ["female", "wu", 3, ["dchuiling", "dcchongxu"]], + dc_sunziliufang: ["male", "wei", 3, ["dcqinshen", "dcweidang"]], + yuantanyuanxiyuanshang: ["male", "qun", 4, ["dcneifa"]], + qiaorui: ["male", "qun", 4, ["dcaishou", "dcsaowei"]], + xianglang: ["male", "shu", 3, ["dckanji", "dcqianzheng"]], + qinlang: ["male", "wei", 4, ["dchaochong", "dcjinjin"]], + furongfuqian: ["male", "shu", "4/6", ["dcxuewei", "dcyuguan"]], + zhenghun: ["male", "wei", 3, ["dcqiangzhi", "dcpitian"]], + dc_zhaotongzhaoguang: ["male", "shu", 4, ["yizan_use", "dcqingren", "dclongyuan"]], + dc_huanghao: ["male", "shu", 3, ["dcqinqing", "huisheng", "dccunwei"]], + liupi: ["male", "qun", 4, ["dcjuying"]], + dc_sp_jiaxu: ["male", "wei", 3, ["zhenlue", "dcjianshu", "dcyongdi"]], + leibo: ["male", "qun", 4, ["dcsilve", "dcshuaijie"]], + gongsundu: ["male", "qun", 4, ["dczhenze", "dcanliao"]], + panghui: ["male", "wei", 5, ["dcyiyong"]], + dc_yuejiu: ["male", "qun", 4, ["dccuijin"]], + chenjiao: ["male", "wei", 3, ["dcxieshou", "dcqingyan", "dcqizi"]], + wanglie: ["male", "qun", 3, ["dcchongwang", "dchuagui"]], + chengui: ["male", "qun", 3, ["dcyingtu", "dccongshi"]], + dc_huangquan: ["male", "shu", 3, ["dcquanjian", "dctujue"]], + yinfuren: ["female", "wei", 3, ["dcyingyu", "dcyongbi"]], + dc_lvkuanglvxiang: ["male", "wei", 4, ["dcshuhe", "dcliehou"]], + guanhai: ["male", "qun", 4, ["suoliang", "qinbao"]], + huzhao: ["male", "qun", 3, ["midu", "xianwang"]], + dc_liuba: ["male", "shu", 3, ["dczhubi", "dcliuzhuan"]], + zhangxun: ["male", "qun", 4, ["suizheng"]], + zongyu: ["male", "shu", 3, ["zyqiao", "chengshang"]], + dc_jiling: ["male", "qun", 4, ["dcshuangren"]], + dc_yanghu: ["male", "wei", 3, ["dcdeshao", "dcmingfa"]], + caimaozhangyun: ["male", "wei", 4, ["lianzhou", "jinglan"]], + tenggongzhu: ["female", "wu", 3, ["xingchong", "liunian"]], + dc_huangchengyan: ["male", "qun", 3, ["dcjiezhen", "dczecai", "dcyinshi"]], + dc_gaolan: ["male", "qun", 4, ["xizhen"]], + guanning: ["male", "qun", "3/7", ["dunshi"]], + dc_jiben: ["male", "qun", 3, ["xunli", "zhishi", "lieyi"]], + mamidi: ["male", "qun", "4/6", ["bingjie", "zhengding"]], + re_dengzhi: ["male", "shu", 3, ["jianliang", "weimeng"]], + fengxi: ["male", "wu", 3, ["yusui", "boyan"]], + re_miheng: ["male", "qun", 3, ["rekuangcai", "reshejian"]], + re_chendeng: ["male", "qun", 3, ["refuyuan", "reyingshui", "rewangzu"]], + wanniangongzhu: ["female", "qun", 3, ["zhenge", "xinghan"]], + re_xunchen: ["male", "qun", 3, ["refenglve", "anyong"], ["clan:颍川荀氏"]], + re_kanze: ["male", "wu", 3, ["xiashu", "rekuanshi"]], + lvlingqi: ["female", "qun", 4, ["guowu", "zhuangrong"]], + zhanghu: ["male", "wei", 4, ["cuijian", "zhtongyuan"]], + luyusheng: ["female", "wu", 3, ["zhente", "zhiwei"]], + huaxin: ["male", "wei", 3, ["spwanggui", "xibing"]], + mengyou: ["male", "qun", 5, ["manyi", "dcmanzhi"]], + liuyong: ["male", "shu", 3, ["zhuning", "fengxiang"]], + dc_sunru: ["female", "wu", 3, ["xiecui", "youxu"]], + xiahoulingnv: ["female", "wei", 4, ["fuping", "weilie"]], + zhangyao: ["female", "wu", 3, ["yuanyu", "xiyan"]], + tengyin: ["male", "wu", 3, ["chenjian", "xixiu"]], + zhangxuan: ["female", "wu", 4, ["tongli", "shezang"]], + wangtao: ["female", "shu", 3, ["huguan", "yaopei"]], + wangyue: ["female", "shu", 3, ["huguan", "mingluan"]], + zhaoyan: ["female", "wu", 3, ["jinhui", "qingman"]], + heyan: ["male", "wei", 3, ["yachai", "qingtan"]], + re_sunluyu: ["female", "wu", 3, ["remeibu", "remumu"]], + re_dongbai: ["female", "qun", 3, ["relianzhu", "rexiahui"]], + zhoushan: ["male", "wu", 4, ["dcmiyun", "dcdanying"]], + dc_caiyang: ["male", "wei", 4, ["dcxunji", "dcjiaofeng"]], + xiahoujie: ["male", "wei", 5, ["liedan", "zhuangdan"]], + caoxing: ["male", "qun", 4, ["cxliushi", "zhanwan"]], + re_chunyuqiong: ["male", "qun", 4, ["recangchu", "reliangying", "reshishou"]], + xingdaorong: ["male", "qun", "4/6", ["xuxie"]], + re_panfeng: ["male", "qun", 4, ["xinkuangfu"]], + jiangfei: ["male", "shu", 3, ["dcshengxi", "dcshoucheng"]], }, - characterSort:{ - huicui:{ - sp_baigei:['re_panfeng','xingdaorong','caoxing','re_chunyuqiong','xiahoujie','dc_caiyang','zhoushan'], - sp_caizijiaren:['dc_kongrong','re_dongbai','re_sunluyu','heyan','zhaoyan','wangtao','wangyue','zhangxuan','tengyin','zhangyao','xiahoulingnv','dc_sunru','pangshanmin','kuaiqi'], - sp_zhilan:['dc_liuli','liuyong','wanniangongzhu','zhanghu','lvlingqi','tenggongzhu','panghui','dc_zhaotongzhaoguang','yuantanyuanxiyuanshang','yuechen','dc_lingcao'], - sp_guixin:['zangba','re_kanze','re_chendeng','caimaozhangyun','dc_lvkuanglvxiang','dc_gaolan','yinfuren','chengui','chenjiao','dc_sp_jiaxu','qinlang','dc_dongzhao'], - sp_daihan:['mamidi','dc_jiling','zhangxun','dc_yuejiu','wanglie','leibo','qiaorui','dongwan','yuanyin'], - sp_jianghu:['guanning','huzhao','dc_huangchengyan','mengjie'], - sp_zongheng:['huaxin','luyusheng','re_xunchen','re_miheng','fengxi','re_dengzhi','dc_yanghu','zongyu'], - sp_taiping:['guanhai','liupi','peiyuanshao','zhangchu','zhangkai','dc_zhangmancheng'], - sp_yanhan:['dc_liuba','dc_huangquan','furongfuqian','xianglang','dc_huojun','gaoxiang','dc_wuban','jiangfei'], - sp_jishi:['dc_jiben','zhenghun','dc_sunhanhua','liuchongluojun'], - sp_raoting:['dc_huanghao','dc_sunziliufang','dc_sunchen','dc_jiachong'], - sp_yijun:['gongsundu','mengyou','dc_sp_menghuo','gongsunxiu'], - sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong','yue_xiaoqiao','yue_daqiao'], - sp_zhonghu:['dc_jiangji','dc_wangling','dc_simashi','dc_caoshuang'], - } + characterSort: { + huicui: { + sp_baigei: [ + "re_panfeng", + "xingdaorong", + "caoxing", + "re_chunyuqiong", + "xiahoujie", + "dc_caiyang", + "zhoushan", + ], + sp_caizijiaren: [ + "dc_kongrong", + "re_dongbai", + "re_sunluyu", + "heyan", + "zhaoyan", + "wangtao", + "wangyue", + "zhangxuan", + "tengyin", + "zhangyao", + "xiahoulingnv", + "dc_sunru", + "pangshanmin", + "kuaiqi", + ], + sp_zhilan: [ + "dc_liuli", + "liuyong", + "wanniangongzhu", + "zhanghu", + "lvlingqi", + "tenggongzhu", + "panghui", + "dc_zhaotongzhaoguang", + "yuantanyuanxiyuanshang", + "yuechen", + "dc_lingcao", + ], + sp_guixin: [ + "zangba", + "re_kanze", + "re_chendeng", + "caimaozhangyun", + "dc_lvkuanglvxiang", + "dc_gaolan", + "yinfuren", + "chengui", + "chenjiao", + "dc_sp_jiaxu", + "qinlang", + "dc_dongzhao", + ], + sp_daihan: [ + "mamidi", + "dc_jiling", + "zhangxun", + "dc_yuejiu", + "leibo", + "qiaorui", + "dongwan", + "yuanyin", + ], + sp_jianghu: ["guanning", "huzhao", "dc_huangchengyan", "mengjie", "wanglie"], + sp_zongheng: [ + "huaxin", + "luyusheng", + "re_xunchen", + "re_miheng", + "fengxi", + "re_dengzhi", + "dc_yanghu", + "zongyu", + ], + sp_taiping: ["guanhai", "liupi", "peiyuanshao", "zhangchu", "zhangkai", "dc_zhangmancheng"], + sp_yanhan: [ + "dc_liuba", + "dc_huangquan", + "furongfuqian", + "xianglang", + "dc_huojun", + "gaoxiang", + "dc_wuban", + "jiangfei", + ], + sp_jishi: ["dc_jiben", "zhenghun", "dc_sunhanhua", "liuchongluojun"], + sp_raoting: ["dc_huanghao", "dc_sunziliufang", "dc_sunchen", "dc_jiachong"], + sp_yijun: ["gongsundu", "mengyou", "dc_sp_menghuo", "gongsunxiu"], + sp_zhengyin: ["yue_caiwenji", "yue_zhoufei", "yue_caiyong", "yue_xiaoqiao", "yue_daqiao"], + sp_zhonghu: ["dc_jiangji", "dc_wangling", "dc_simashi", "dc_caoshuang"], + }, }, /** @type { importCharacterConfig['skill'] } */ - skill:{ + skill: { //新杀曹爽 - dcjianzhuan:{ - audio:2, - trigger:{player:'useCard'}, - filter(event,player){ - const evtx=event.getParent('phaseUse'); - return player.isPhaseUsing()&&player.getHistory('useSkill',evt=>{ - return evt.skill=='dcjianzhuan'&&evt.event.getParent('phaseUse')==evtx; - }).length<4-player.getStorage('dcjianzhuan').length; + dcjianzhuan: { + audio: 2, + trigger: { player: "useCard" }, + filter(event, player) { + const evtx = event.getParent("phaseUse"); + return ( + player.isPhaseUsing() && + player.getHistory("useSkill", (evt) => { + return evt.skill == "dcjianzhuan" && evt.event.getParent("phaseUse") == evtx; + }).length < + 4 - player.getStorage("dcjianzhuan").length + ); }, - forced:true, - derivation:'dcjianzhuan_faq', - async content(event,trigger,player){ - const evtx=event.getParent('phaseUse'),num=player.getHistory('useSkill',evt=>{ - return evt.skill=='dcjianzhuan'&&evt.event.getParent('phaseUse')==evtx; - }).length,info=get.info('dcjianzhuan').choices; - let choices=[],choiceList=[],map={}; - for(const i in info){ - map[info[i].intro]=i; - if(player.getStorage('dcjianzhuan').includes(i)||player.getStorage('dcjianzhuan_used').includes(i)) continue; - choices.push(info[i].intro);choiceList.push(info[i].introx(num)); + forced: true, + derivation: "dcjianzhuan_faq", + async content(event, trigger, player) { + const evtx = event.getParent("phaseUse"), + num = player.getHistory("useSkill", (evt) => { + return evt.skill == "dcjianzhuan" && evt.event.getParent("phaseUse") == evtx; + }).length, + info = get.info("dcjianzhuan").choices; + let choices = [], + choiceList = [], + map = {}; + for (const i in info) { + map[info[i].intro] = i; + if ( + player.getStorage("dcjianzhuan").includes(i) || + player.getStorage("dcjianzhuan_used").includes(i) + ) + continue; + choices.push(info[i].intro); + choiceList.push(info[i].introx(num)); } - const {result:{control}}=await player.chooseControl(choices).set('choiceList',choiceList).set('ai',()=>{ - const player=get.event('player'),num=get.event('num'),info=get.info('dcjianzhuan').choices; - let choices=get.event('controls').slice(),map=get.event('map') - return choices.sort((a,b)=>info[map[b]].ai_effect(player,num)-info[map[a]].ai_effect(player,num))[0]; - }).set('num',num).set('map',map).set('prompt','渐专:请选择一项执行'); - if(control){ - if(!player.storage.dcjianzhuan_used){ - player.when('phaseUseAfter').then(()=>delete player.storage.dcjianzhuan_used); + const { + result: { control }, + } = await player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("ai", () => { + const player = get.event("player"), + num = get.event("num"), + info = get.info("dcjianzhuan").choices; + let choices = get.event("controls").slice(), + map = get.event("map"); + return choices.sort( + (a, b) => + info[map[b]].ai_effect(player, num) - info[map[a]].ai_effect(player, num) + )[0]; + }) + .set("num", num) + .set("map", map) + .set("prompt", "渐专:请选择一项执行"); + if (control) { + if (!player.storage.dcjianzhuan_used) { + player.when("phaseUseAfter").then(() => delete player.storage.dcjianzhuan_used); } - player.markAuto('dcjianzhuan_used',[map[control]]); - await info[map[control]].content(player,num); + player.markAuto("dcjianzhuan_used", [map[control]]); + await info[map[control]].content(player, num); } }, - choices:{ - discard_target:{ - intro:'拆牌', - introx:(num)=>'令一名角色弃置'+num+'张牌', - weight:1, - ai_effect(player,num){ - return game.hasPlayer(target=>{ - return get.effect(target,{name:'guohe_copy2'},player,player)>0; - })?(2+num):0; + choices: { + discard_target: { + intro: "拆牌", + introx: (num) => "令一名角色弃置" + num + "张牌", + weight: 1, + ai_effect(player, num) { + return game.hasPlayer((target) => { + return get.effect(target, { name: "guohe_copy2" }, player, player) > 0; + }) + ? 2 + num + : 0; }, - async content(player,num=1){ - const {result:{bool,targets}}=await player.chooseTarget('令一名角色弃置'+num+'张牌',true).set('ai',target=>{ - return get.effect(target,{name:'guohe_copy2'},get.event('player'),get.event('player'))*Math.sqrt(Math.min(get.event('num'),target.countDiscardableCards(target,'he'))); - }).set('num',num); - if(bool){ - const target=targets[0]; + async content(player, num = 1) { + const { + result: { bool, targets }, + } = await player + .chooseTarget("令一名角色弃置" + num + "张牌", true) + .set("ai", (target) => { + return ( + get.effect( + target, + { name: "guohe_copy2" }, + get.event("player"), + get.event("player") + ) * + Math.sqrt( + Math.min( + get.event("num"), + target.countDiscardableCards(target, "he") + ) + ) + ); + }) + .set("num", num); + if (bool) { + const target = targets[0]; player.line(target); - await target.chooseToDiscard(num,'he',true); + await target.chooseToDiscard(num, "he", true); } }, }, - draw_self:{ - intro:'摸牌', - introx:(num)=>'摸'+num+'张牌', - weight:1, - ai_effect(player,num){ + draw_self: { + intro: "摸牌", + introx: (num) => "摸" + num + "张牌", + weight: 1, + ai_effect(player, num) { return 3; }, - async content(player,num=1){ + async content(player, num = 1) { await player.draw(num); }, }, - recast_self:{ - intro:'重铸', - introx:(num)=>'重铸'+num+'张牌', - weight:1, - ai_effect(player,num){ + recast_self: { + intro: "重铸", + introx: (num) => "重铸" + num + "张牌", + weight: 1, + ai_effect(player, num) { return 1; }, - async content(player,num=1){ - if(!player.hasCard(lib.filter.cardRecastable,'he')) return; - const {result:{bool,cards}}=await player.chooseCard('重铸'+num+'张牌','he',num,lib.filter.cardRecastable,true).set('ai',lib.skill.zhiheng.check); - if(bool) await player.recast(cards); + async content(player, num = 1) { + if (!player.hasCard(lib.filter.cardRecastable, "he")) return; + const { + result: { bool, cards }, + } = await player + .chooseCard("重铸" + num + "张牌", "he", num, lib.filter.cardRecastable, true) + .set("ai", lib.skill.zhiheng.check); + if (bool) await player.recast(cards); }, }, - discard_self:{ - intro:'弃牌', - introx:(num)=>'弃置'+num+'张牌', - weight:'90%', - ai_effect(player,num){ - let cards=player.getCards('hs'); - cards.sort((a,b)=>get.value(b)-get.value(a)); - cards=cards.slice(0,-Math.min(num,cards.length)); - return cards.some(card=>player.hasValueTarget(card,true,true))?4:-4; + discard_self: { + intro: "弃牌", + introx: (num) => "弃置" + num + "张牌", + weight: "90%", + ai_effect(player, num) { + let cards = player.getCards("hs"); + cards.sort((a, b) => get.value(b) - get.value(a)); + cards = cards.slice(0, -Math.min(num, cards.length)); + return cards.some((card) => player.hasValueTarget(card, true, true)) ? 4 : -4; }, - async content(player,num=1){ - await player.chooseToDiscard(num,'he',true); + async content(player, num = 1) { + await player.chooseToDiscard(num, "he", true); }, }, }, - group:'dcjianzhuan_remove', - subSkill:{ - remove:{ - audio:'dcjianzhuan', - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - if(player.getStorage('dcjianzhuan').length>=4) return false; - return player.getStorage('dcjianzhuan_used').length>=4-player.getStorage('dcjianzhuan').length; + group: "dcjianzhuan_remove", + subSkill: { + remove: { + audio: "dcjianzhuan", + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + if (player.getStorage("dcjianzhuan").length >= 4) return false; + return ( + player.getStorage("dcjianzhuan_used").length >= + 4 - player.getStorage("dcjianzhuan").length + ); }, - forced:true, - async content(event,trigger,player){ - const info=get.info('dcjianzhuan').choices; - let map={}; - let unfixedWeightTotal=0,remainedWeight=100; - let entries=[]; - for(const i in info){ - const infox=info[i]; - map[infox.intro]=i; - if(player.getStorage('dcjianzhuan').includes(i)) continue; - let weight=(infox.weight||1).toString(); - if(weight.endsWith('%')){ - weight=Math.min(remainedWeight,parseInt(weight.slice(0,-1))); - entries.push([infox.intro,weight]); - remainedWeight-=weight; - } - else{ - weight=parseInt(weight); - unfixedWeightTotal+=weight; - entries.push([infox.intro,-weight]); + forced: true, + async content(event, trigger, player) { + const info = get.info("dcjianzhuan").choices; + let map = {}; + let unfixedWeightTotal = 0, + remainedWeight = 100; + let entries = []; + for (const i in info) { + const infox = info[i]; + map[infox.intro] = i; + if (player.getStorage("dcjianzhuan").includes(i)) continue; + let weight = (infox.weight || 1).toString(); + if (weight.endsWith("%")) { + weight = Math.min(remainedWeight, parseInt(weight.slice(0, -1))); + entries.push([infox.intro, weight]); + remainedWeight -= weight; + } else { + weight = parseInt(weight); + unfixedWeightTotal += weight; + entries.push([infox.intro, -weight]); } } - entries=entries.map(entry=>{ - let weight=entry[1]; - if(weight<0) weight=-remainedWeight/unfixedWeightTotal*weight; - return [entry[0],weight]; + entries = entries.map((entry) => { + let weight = entry[1]; + if (weight < 0) weight = (-remainedWeight / unfixedWeightTotal) * weight; + return [entry[0], weight]; }); - let rand=Math.random()*100; - let removeChoice=entries.find(entry=>{ - rand-=entry[1]; - return rand<0; + let rand = Math.random() * 100; + let removeChoice = entries.find((entry) => { + rand -= entry[1]; + return rand < 0; })[0]; - if(get.isLuckyStar(player)&&Object.keys(entries).includes('弃牌')) removeChoice='弃牌'; - player.markAuto('dcjianzhuan',[map[removeChoice]]); + if (get.isLuckyStar(player) && Object.keys(entries).includes("弃牌")) + removeChoice = "弃牌"; + player.markAuto("dcjianzhuan", [map[removeChoice]]); player.popup(removeChoice); - game.log(player,'移去了','#g'+removeChoice,'项'); + game.log(player, "移去了", "#g" + removeChoice, "项"); }, }, }, - mark:true, - intro:{ - markcount(storage){ - return 4-(storage||[]).length; + mark: true, + intro: { + markcount(storage) { + return 4 - (storage || []).length; }, - content(storage){ - if(!(storage||[]).length) return '暂未移去任何项'; - const info=get.info('dcjianzhuan').choices; - let str=''; - for(const i of storage){ - str+=info[i].intro; - str+='、'; + content(storage) { + if (!(storage || []).length) return "暂未移去任何项"; + const info = get.info("dcjianzhuan").choices; + let str = ""; + for (const i of storage) { + str += info[i].intro; + str += "、"; } - str=str.slice(0,-1); - return '已移去'+str+'项'; + str = str.slice(0, -1); + return "已移去" + str + "项"; }, }, }, - dcfanshi:{ - unique:true, - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return 4-player.getStorage('dcjianzhuan').length<2; + dcfanshi: { + unique: true, + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return 4 - player.getStorage("dcjianzhuan").length < 2; }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - async content(event,trigger,player){ - player.awakenSkill('dcfanshi'); - const info=get.info('dcjianzhuan').choices; - let choices=[]; - for(const i in info){ - if(!player.getStorage('dcjianzhuan').includes(i)) choices.push(i); + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + async content(event, trigger, player) { + player.awakenSkill("dcfanshi"); + const info = get.info("dcjianzhuan").choices; + let choices = []; + for (const i in info) { + if (!player.getStorage("dcjianzhuan").includes(i)) choices.push(i); } - if(choices.length){ - for(const choice of choices){ - for(let i=1;i<=3;i++){ - await info[choice].content(player,1); + if (choices.length) { + for (const choice of choices) { + for (let i = 1; i <= 3; i++) { + await info[choice].content(player, 1); } } } await player.gainMaxHp(2); await player.recover(2); - await player.changeSkills(['dcfudou'],['dcjianzhuan']); + await player.changeSkills(["dcfudou"], ["dcjianzhuan"]); + }, + derivation: "dcfudou", + ai: { + combo: "dcjianzhuan" }, - derivation:'dcfudou', }, - dcfudou:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(event.targets.length!=1||event.target==player) return false; - const color=get.color(event.card); - if(!['black','red'].includes(color)) return false; - const damage=event.target.getAllHistory('sourceDamage',evt=>evt.player==player).length; - return Math.min(1,damage)==(color=='black'); + dcfudou: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (event.targets.length != 1 || event.target == player) return false; + const color = get.color(event.card); + if (!["black", "red"].includes(color)) return false; + const damage = event.target.getAllHistory( + "sourceDamage", + (evt) => evt.player == player + ).length; + return Math.min(1, damage) == (color == "black"); }, - check(event,player){ - const color=get.color(event.card); - if(color=='red') return get.attitude(player,event.target)>0; - if(player.getHp()+player.countCards('hs',card=>player.canSaveCard(card,player))<=1) return false; - return get.effect(player,{name:'losehp'},player,player)>=get.effect(event.target,{name:'losehp'},player,player); + check(event, player) { + const color = get.color(event.card); + if (color == "red") return get.attitude(player, event.target) > 0; + if ( + player.getHp() + + player.countCards("hs", (card) => player.canSaveCard(card, player)) <= + 1 + ) + return false; + return ( + get.effect(player, { name: "losehp" }, player, player) >= + get.effect(event.target, { name: "losehp" }, player, player) + ); }, - prompt2(event,player){ - return '与'+get.translation(event.target)+'各'+(get.color(event.card)=='black'?'失去1点体力':'摸一张牌'); + prompt2(event, player) { + return ( + "与" + + get.translation(event.target) + + "各" + + (get.color(event.card) == "black" ? "失去1点体力" : "摸一张牌") + ); }, - logTarget:'target', - async content(event,trigger,player){ - const color=get.color(trigger.card),target=trigger.target; - if(color=='red'){ - await player.draw('nodelay'); + logTarget: "target", + async content(event, trigger, player) { + const color = get.color(trigger.card), + target = trigger.target; + if (color == "red") { + await player.draw("nodelay"); await target.draw(); - } - else{ + } else { await player.loseHp(); await target.loseHp(); } }, }, //司马师 - dcsanshi:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - filter(event,player){ - return game.roundNumber===1; + dcsanshi: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + filter(event, player) { + return game.roundNumber === 1; }, - group:['dcsanshi_gain','dcsanshi_directHit'], - async content(event,trigger,player){ - const recordedNumbers=[]; - let num=get.rand(0,ui.cardPile.childNodes.length-1); - for(let i=0;i=ui.cardPile.childNodes.length) j-=ui.cardPile.childNodes.length; - const card=ui.cardPile.childNodes[j],number=get.number(card,false); - if(!recordedNumbers.includes(number)){ + group: ["dcsanshi_gain", "dcsanshi_directHit"], + async content(event, trigger, player) { + const recordedNumbers = []; + let num = get.rand(0, ui.cardPile.childNodes.length - 1); + for (let i = 0; i < ui.cardPile.childNodes.length; i++) { + let j = i + num; + if (j >= ui.cardPile.childNodes.length) j -= ui.cardPile.childNodes.length; + const card = ui.cardPile.childNodes[j], + number = get.number(card, false); + if (!recordedNumbers.includes(number)) { recordedNumbers.add(number); - card.storage.dcsanshi=true; - num=get.rand(0,ui.cardPile.childNodes.length-1); + card.storage.dcsanshi = true; + num = get.rand(0, ui.cardPile.childNodes.length - 1); } } - player.addSkill('dcsanshi_mark'); + player.addSkill("dcsanshi_mark"); }, - subSkill:{ - gain:{ - audio:'dcsanshi', - trigger:{global:'phaseEnd'}, - filter(event,player){ - return game.hasGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'){ - if(evt.position!==ui.discardPile) return false; - } - else if(evt.name!=='cardsDiscard') return false; - if(lib.skill.dcsanshi_gain.notUseOrRespond(evt,player)){ - return evt.cards.some(card=>{ - return card.storage.dcsanshi&&get.position(card)==='d'; + subSkill: { + gain: { + audio: "dcsanshi", + trigger: { global: "phaseEnd" }, + filter(event, player) { + return game.hasGlobalHistory("cardMove", (evt) => { + if (evt.name == "lose") { + if (evt.position !== ui.discardPile) return false; + } else if (evt.name !== "cardsDiscard") return false; + if (lib.skill.dcsanshi_gain.notUseOrRespond(evt, player)) { + return evt.cards.some((card) => { + return card.storage.dcsanshi && get.position(card) === "d"; }); } return false; }); }, - forced:true, - notUseOrRespond(event,player){ - if(event.name==='cardsDiscard') return false; - const evtx=event.getParent(); - if(evtx.name==='orderingDiscard') return false; - const evt2=(evtx.relatedEvent||evtx.getParent()); - return !['useCard','respond'].includes(evt2.name)||evt2.player!==player; + forced: true, + notUseOrRespond(event, player) { + if (event.name !== "cardsDiscard") return true; + const evtx = event.getParent(); + if (evtx.name !== "orderingDiscard") return true; + const evt2 = evtx.relatedEvent || evtx.getParent(); + return !["useCard", "respond"].includes(evt2.name) || evt2.player !== player; }, - async content(event,trigger,player){ - const cards=[]; - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'){ - if(evt.position!==ui.discardPile) return false; - } - else if(evt.name!=='cardsDiscard') return false; - if(lib.skill.dcsanshi_gain.notUseOrRespond(evt,player)){ - cards.addArray(evt.cards.filter(card=>{ - return card.storage.dcsanshi&&get.position(card)==='d'; - })); + async content(event, trigger, player) { + const cards = []; + game.checkGlobalHistory("cardMove", (evt) => { + if (evt.name == "lose") { + if (evt.position !== ui.discardPile) return false; + } else if (evt.name !== "cardsDiscard") return false; + if (lib.skill.dcsanshi_gain.notUseOrRespond(evt, player)) { + cards.addArray( + evt.cards.filter((card) => { + return card.storage.dcsanshi && get.position(card) === "d"; + }) + ); } }); - if(cards.length) player.gain(cards,'gain2'); - } + if (cards.length) player.gain(cards, "gain2"); + }, }, - directHit:{ - audio:'dcsanshi', - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return event.cards&&event.cards.some(card=>{ - return card.storage.dcsanshi; - }); + directHit: { + audio: "dcsanshi", + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return ( + event.cards && + event.cards.some((card) => { + return card.storage.dcsanshi; + }) + ); }, - async content(event,trigger,player){ + async content(event, trigger, player) { trigger.directHit.addArray(game.filterPlayer()); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, }, - mark:{ - trigger:{ - player:'gainEnd', - global:'loseAsyncEnd', + mark: { + trigger: { + player: "gainEnd", + global: "loseAsyncEnd", }, - forced:true, - popup:false, - silent:true, - lastDo:true, - filter(event,player){ - if(!['dcsanshi','dcchenlve'].every(skill=>player.hasSkill(skill,null,false,false))) return false; - const cards=event.getg(player); - if(!cards.length) return false; - return cards.some(card=>card.storage.dcsanshi); + forced: true, + popup: false, + silent: true, + lastDo: true, + filter(event, player) { + if ( + !["dcsanshi", "dcchenlve"].every((skill) => + player.hasSkill(skill, null, false, false) + ) + ) + return false; + const cards = event.getg(player); + if (!cards.length) return false; + return cards.some((card) => card.storage.dcsanshi); }, - async content(event,trigger,player){ - var cards=trigger.getg(player); - if(cards.length){ - cards=cards.filter(card=>card.storage.dcsanshi); - player.addGaintag(cards,'dcsanshi_tag'); + async content(event, trigger, player) { + var cards = trigger.getg(player); + if (cards.length) { + cards = cards.filter((card) => card.storage.dcsanshi); + player.addGaintag(cards, "dcsanshi_tag"); } }, }, }, - ai:{ - threaten:3, + ai: { + threaten: 3, }, }, - dczhenrao:{ - audio:2, - trigger:{global:'useCardToPlayered'}, - filter(event,player){ - if((()=>{ - if(event.player===player){ - if(!event.isFirstTarget) return false; - return event.targets.some(target=>target!==player); - } - return event.target===player; - })()){ - return event.targets.concat(event.player).some(target=>{ - return target.countCards('h')>player.countCards('h')&&!player.getStorage('dczhenrao').includes(target); + dczhenrao: { + audio: 2, + trigger: { global: "useCardToPlayered" }, + filter(event, player) { + if ( + (() => { + if (event.player === player) { + if (!event.isFirstTarget) return false; + return event.targets.some((target) => target !== player); + } + return event.target === player; + })() + ) { + return event.targets.concat(event.player).some((target) => { + return ( + target.countCards("h") > player.countCards("h") && + !player.getStorage("dczhenrao").includes(target) + ); }); } return false; }, - direct:true, - async content(event,trigger,player){ - const result=await player.chooseTarget(get.prompt('dczhenrao'),'对一名可选角色造成1点伤害',(card,player,target)=>{ - return get.event('targets').includes(target)&&!player.getStorage('dczhenrao').includes(target); - }) - .set('targets',trigger.targets.concat(trigger.player).filter(target=>target.countCards('h')>player.countCards('h'))) - .set('ai',target=>{ - const player=get.player(); - return get.damageEffect(target,player,player); + direct: true, + async content(event, trigger, player) { + const result = await player + .chooseTarget( + get.prompt("dczhenrao"), + "对一名可选角色造成1点伤害", + (card, player, target) => { + return ( + get.event("targets").includes(target) && + !player.getStorage("dczhenrao").includes(target) + ); + } + ) + .set( + "targets", + trigger.targets + .concat(trigger.player) + .filter((target) => target.countCards("h") > player.countCards("h")) + ) + .set("ai", (target) => { + const player = get.player(); + return get.damageEffect(target, player, player); }) .forResult(); - if(!result.bool) return; - const target=result.targets[0]; - player.logSkill('dczhenrao',target); + if (!result.bool) return; + const target = result.targets[0]; + player.logSkill("dczhenrao", target); await target.damage(); await game.asyncDelayx(); - if(!player.storage.dczhenrao){ - player.when({global:'phaseAfter'}).then(()=>player.unmarkSkill('dczhenrao')); + if (!player.storage.dczhenrao) { + player.when({ global: "phaseAfter" }).then(() => player.unmarkSkill("dczhenrao")); } - player.markAuto('dczhenrao',target); + player.markAuto("dczhenrao", target); }, - intro:{ - content:'已以此法对$造成过伤害', - onunmark:true, + intro: { + content: "已以此法对$造成过伤害", + onunmark: true, }, - ai:{ - expose:0.2, - threaten:3, + ai: { + expose: 0.2, + threaten: 3, }, }, - dcchenlve:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filterCard:()=>false, - selectCard:[-2,-1], - async content(event,trigger,player){ - player.awakenSkill('dcchenlve'); - const cards=['cardPile','discardPile'].map(pos=>Array.from(ui[pos].childNodes)).flat(); - const sishiList=[]; - const isSishi=card=>card.storage.dcsanshi; - const lose_list=[],players=game.filterPlayer(); - players.forEach(current=>{ - const pos='ej'+(current===player?'h':''); - const sishis=current.getCards(pos,isSishi); - if(sishis.length>0){ + dcchenlve: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filterCard: () => false, + selectCard: [-2, -1], + async content(event, trigger, player) { + player.awakenSkill("dcchenlve"); + const cards = ["cardPile", "discardPile"] + .map((pos) => Array.from(ui[pos].childNodes)) + .flat(); + const sishiList = []; + const isSishi = (card) => card.storage.dcsanshi; + const lose_list = [], + players = game.filterPlayer(); + players.forEach((current) => { + const pos = "ej" + (current === player ? "h" : ""); + const sishis = current.getCards(pos, isSishi); + if (sishis.length > 0) { current.$throw(sishis); - lose_list.push([current,sishis]); + lose_list.push([current, sishis]); sishiList.addArray(sishis); } }); - if(lose_list.length){ - await game.loseAsync({lose_list}).setContent('chooseToCompareLose'); + if (lose_list.length) { + await game.loseAsync({ lose_list }).setContent("chooseToCompareLose"); } sishiList.addArray(cards.filter(isSishi)); - if(lose_list.length) await game.asyncDelayx(); - player.gain(sishiList,'gain2'); - player.when('phaseEnd') - .filter(evt=>evt===event.getParent('phase')) + if (lose_list.length) await game.asyncDelayx(); + player.gain(sishiList, "gain2"); + player + .when("phaseEnd") + .filter((evt) => evt === event.getParent("phase")) .vars({ - sishiList + sishiList, }) - .then(()=>{ - const lose_list=[],players=game.filterPlayer(); - players.forEach(current=>{ - const cards=current.getCards('hej').filter(card=>sishiList.includes(card)); - if(cards.length>0){ + .then(() => { + const lose_list = [], + players = game.filterPlayer(); + players.forEach((current) => { + const cards = current + .getCards("hej") + .filter((card) => sishiList.includes(card)); + if (cards.length > 0) { current.$throw(cards); - lose_list.push([current,cards]); + lose_list.push([current, cards]); } }); - if(lose_list.length){ - game.loseAsync({lose_list}).setContent('chooseToCompareLose'); + if (lose_list.length) { + game.loseAsync({ lose_list }).setContent("chooseToCompareLose"); } }) - .then(()=>{ + .then(() => { game.cardsGotoSpecial(sishiList); - game.log(sishiList,'被移出了游戏'); + game.log(sishiList, "被移出了游戏"); }); - player.when('die') + player + .when("die") .vars({ - sishiList + sishiList, }) .assign({ - forceDie:true, + forceDie: true, }) - .then(()=>{ + .then(() => { game.cardsDiscard(sishiList); - game.log(sishiList,'被置入了弃牌堆'); + game.log(sishiList, "被置入了弃牌堆"); }); }, - ai:{ - order:0.5, - result:{ - player(player){ - if(player.getHp(true)>1&&player.countCards('he')>1) return 0; - if(!player.isDamaged()&&(player.countCards('h')>1||player.countCards('e')>0)) return 0; + ai: { + order: 0.5, + result: { + player(player) { + if (player.getHp(true) > 1 && player.countCards("he") > 1) return 0; + if ( + !player.isDamaged() && + (player.countCards("h") > 1 || player.countCards("e") > 0) + ) + return 0; return 13; - } + }, }, + combo: "dcsanshi", }, }, //王凌 - dcjichou:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - const evts=player.getHistory('useCard',evt=>evt.getParent('phaseUse')===event); - const names=evts.map(evt=>evt.card.name).unique(); - return evts.length>0&&evts.length===names.length&&evts.some(evt=>evt.cards.some(card=>get.position(card)==='d')); + dcjichou: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + const evts = player.getHistory("useCard", (evt) => evt.getParent("phaseUse") === event); + const names = evts.map((evt) => evt.card.name).unique(); + return ( + evts.length > 0 && + evts.length === names.length && + evts.some((evt) => evt.cards.some((card) => get.position(card) === "d")) + ); }, - async content(event,trigger,player){ - const cards=[]; - player.checkHistory('useCard',evt=>{ - if(evt.getParent('phaseUse')!==trigger) return; - cards.addArray(evt.cards.filterInD('d')); + async content(event, trigger, player) { + const cards = []; + player.checkHistory("useCard", (evt) => { + if (evt.getParent("phaseUse") !== trigger) return; + cards.addArray(evt.cards.filterInD("d")); }); - const num=Math.min(cards.length,game.countPlayer()); - if(_status.connectMode) game.broadcastAll(()=>{_status.noclearcountdown=true}); - const [bool,links]=await player.chooseButton([ - `集筹:将${numget.attitude(player,current)>0), - game.countPlayer(current=>get.attitude(player,current)<0) + const num = Math.min(cards.length, game.countPlayer()); + if (_status.connectMode) + game.broadcastAll(() => { + _status.noclearcountdown = true; + }); + const [bool, links] = await player + .chooseButton([ + `集筹:将${ + num < cards.length ? "至多" + get.cnNumber(num) + "张牌" : "任意张牌" + }交给等量角色`, + cards, ]) - .set('ai',button=>{ - const card=button.link,population=get.event('population'); - if(ui.selected.buttons.length>population[0]+population[1]) return 0; - if(ui.selected.buttons.length>get.event('population')[0]) return 2-get.value(card); - return 2+get.value(card); + .set("selectButton", [1, num]) + .set("population", [ + game.countPlayer((current) => get.attitude(player, current) > 0), + game.countPlayer((current) => get.attitude(player, current) < 0), + ]) + .set("ai", (button) => { + const card = button.link, + population = get.event("population"); + if (ui.selected.buttons.length > population[0] + population[1]) return 0; + if (ui.selected.buttons.length > get.event("population")[0]) + return 2 - get.value(card); + return 2 + get.value(card); }) - .forResult('bool','links'); - if(bool){ - const [bool,targets]=await player.chooseTarget( + .forResult("bool", "links"); + if (bool) { + const [bool, targets] = await player + .chooseTarget( `集筹:请选择${get.cnNumber(links.length)}名角色`, - `操作提示:请按照顺序选择要交给牌的目标,令这些角色按顺序获得这些牌:${get.translation(links)}`, + `操作提示:请按照顺序选择要交给牌的目标,令这些角色按顺序获得这些牌:${get.translation( + links + )}`, true, - links.length, + links.length ) - .set('values',links.map(i=>get.value(i))) - .set('ai',target=>{ - const att=get.attitude(get.player(),target); - const chosenNum=ui.selected.targets.length,values=get.event('values'); - if(values[chosenNum]>0) return att; - return 0.01-att; - }) - .forResult('bool','targets'); - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} - if(bool){ - const gain_list=[],givenCards=[]; - targets.forEach((target,i)=>{ - player.line(target,'green'); - gain_list.push([target,links[i]]); - givenCards.push(links[i]); - game.log(player,'将',links[i],'交给了',target); - }); - event.getParent().set('givenCards',givenCards); - await game.loseAsync({ - gain_list, - player:player, - cards:givenCards, - giver:player, - animate:'gain2', - }).setContent('gaincardMultiple'); - const toDraw=player.getAllHistory('useSkill',evt=>{ - const evtx=evt.event; - return evt.skill==='dcjichou'&&evtx.givenCards&&evtx.givenCards.length; - })[0].event.givenCards.length; - await game.asyncDelayx(); - await player.draw(toDraw); - } + .set( + "values", + links.map((i) => get.value(i)) + ) + .set("ai", (target) => { + const att = get.attitude(get.player(), target); + const chosenNum = ui.selected.targets.length, + values = get.event("values"); + if (values[chosenNum] > 0) return att; + return 0.01 - att; + }) + .forResult("bool", "targets"); + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} + if (bool) { + const gain_list = [], + givenCards = []; + targets.forEach((target, i) => { + player.line(target, "green"); + gain_list.push([target, links[i]]); + givenCards.push(links[i]); + game.log(player, "将", links[i], "交给了", target); + }); + event.getParent().set("givenCards", givenCards); + await game + .loseAsync({ + gain_list, + player: player, + cards: givenCards, + giver: player, + animate: "gain2", + }) + .setContent("gaincardMultiple"); + const toDraw = player.getAllHistory("useSkill", (evt) => { + const evtx = evt.event; + return evt.skill === "dcjichou" && evtx.givenCards && evtx.givenCards.length; + })[0].event.givenCards.length; + await game.asyncDelayx(); + await player.draw(toDraw); + } + } + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } }, }, - dcmouli:{ - audio:2, - trigger:{player:'phaseEnd'}, - filter(event,player){ - const names=[]; - player.checkAllHistory('useSkill',evt=>{ - if(evt.skill!=='dcjichou') return; - const evtx=evt.event; - if(evtx.givenCards) names.addArray(evtx.givenCards.map(card=>get.name(card,false))); + dcmouli: { + audio: 2, + trigger: { player: "phaseEnd" }, + filter(event, player) { + const names = []; + player.checkAllHistory("useSkill", (evt) => { + if (evt.skill !== "dcjichou") return; + const evtx = evt.event; + if (evtx.givenCards) + names.addArray(evtx.givenCards.map((card) => get.name(card, false))); }); - return names.length>=5; + return names.length >= 5; }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'water', - derivation:['dczifu'], - async content(event,trigger,player){ - player.awakenSkill('dcmouli'); + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "water", + derivation: ["dczifu"], + async content(event, trigger, player) { + player.awakenSkill("dcmouli"); await player.gainMaxHp(); await player.recover(); - await player.addSkills('dczifu'); + await player.addSkills("dczifu"); + }, + ai: { + combo: "dcjichou", }, }, - dczifu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - async content(event,trigger,player){ - const maxLimit=Math.min(5,player.maxHp); - let count=player.countCards('h'); - if(countevt.getParent(2)===event)) return; - count=player.countCards('h'); - const toKeepCount=player.getCards('h').map(card=>get.name(card)).unique(); - if(count>toKeepCount){ - const [bool,cards]=await player.chooseCard('自缚:选择要保留的手牌','选择不同牌名的手牌各一张,然后弃置其余手牌',toKeepCount) - .set('filterCard',card=>{ - if(!ui.selected.cards.length) return true; - const name=get.name(card,player); - if(ui.selected.cards.some(card=>get.name(card,player)===name)) return false; + if (!player.hasHistory("gain", (evt) => evt.getParent(2) === event)) return; + count = player.countCards("h"); + const toKeepCount = player + .getCards("h") + .map((card) => get.name(card)) + .unique(); + if (count > toKeepCount) { + const [bool, cards] = await player + .chooseCard( + "自缚:选择要保留的手牌", + "选择不同牌名的手牌各一张,然后弃置其余手牌", + toKeepCount + ) + .set("filterCard", (card) => { + if (!ui.selected.cards.length) return true; + const name = get.name(card, player); + if (ui.selected.cards.some((card) => get.name(card, player) === name)) + return false; return true; }) - .set('complexCard',true) - .set('ai',get.value) - .forResult('bool','cards'); - if(!bool) return; - const toDiscard=player.getCards('h').removeArray(cards); - if(toDiscard.length) player.discard(toDiscard); + .set("complexCard", true) + .set("ai", get.value) + .forResult("bool", "cards"); + if (!bool) return; + const toDiscard = player.getCards("h").removeArray(cards); + if (toDiscard.length) player.discard(toDiscard); } }, - ai:{ - halfneg:true, + ai: { + halfneg: true, }, }, //蒋济 - dcshiju:{ - audio:2, - global:'dcshiju_global', - subSkill:{ - global:{ - audio:'dcshiju', - enable:'phaseUse', - usable:1, - filter(event,player){ - return game.hasPlayer(current=>{ - if(current==player||!current.hasSkill('dcshiju')) return false; - return player.countCards('he'); + dcshiju: { + audio: 2, + global: "dcshiju_global", + subSkill: { + global: { + audio: "dcshiju", + forceaudio: true, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return game.hasPlayer((current) => { + if (current == player || !current.hasSkill("dcshiju")) return false; + return player.countCards("he"); }); }, - filterTarget(card,player,target){ - return target!=player&&target.hasSkill('dcshiju'); + filterTarget(card, player, target) { + return target != player && target.hasSkill("dcshiju"); }, - selectTarget(){ - const num=game.countPlayer(current=>{ - return current.hasSkill('dcshiju'); + selectTarget() { + const num = game.countPlayer((current) => { + return current.hasSkill("dcshiju"); }); - return num>1?1:-1; + return num > 1 ? 1 : -1; }, - filterCard:true, - position:'he', - check(card){ - const player=get.player(); - if(get.type(card)==='equip'){ - const subtype=get.subtype(card); - let valueFix=0; - if(game.hasPlayer(current=>{ - if(current==player||!current.hasSkill('dcshiju')) return false; - if(current.hasUseTarget(card)&&!player.countEmptySlot(subtype)) return true; - })) valueFix+=5; - if(player.countCards('he',{subtype})>1){ - return valueFix+12-get.equipValue(card); + filterCard: true, + position: "he", + check(card) { + const player = get.player(); + if (get.type(card) === "equip") { + const subtype = get.subtype(card); + let valueFix = 0; + if ( + game.hasPlayer((current) => { + if (current == player || !current.hasSkill("dcshiju")) return false; + if (current.hasUseTarget(card) && !player.countEmptySlot(subtype)) + return true; + }) + ) + valueFix += 5; + if (player.countCards("he", { subtype }) > 1) { + return valueFix + 12 - get.equipValue(card); } - return valueFix+6-get.value(card); + return valueFix + 6 - get.value(card); } - return 4-get.value(card); + return 4 - get.value(card); }, - prompt(){ - const list=game.filterPlayer(current=>{ - return current.hasSkill('dcshiju'); + prompt() { + const list = game.filterPlayer((current) => { + return current.hasSkill("dcshiju"); }); - return `将一张牌交给${get.translation(list)}${list.length>1?'中的一人':''},若此牌为装备牌,其可以使用之,且你本回合的攻击范围+X(X为其装备区的牌数)。若其以此法替换了装备,你与其各摸两张牌。`; + return `将一张牌交给${get.translation(list)}${ + list.length > 1 ? "中的一人" : "" + },若此牌为装备牌,其可以使用之,且你本回合的攻击范围+X(X为其装备区的牌数)。若其以此法替换了装备,你与其各摸两张牌。`; }, - discard:false, - lose:false, - prepare(cards,player,targets){ - player.$give(cards,targets[0],false); + discard: false, + lose: false, + prepare(cards, player, targets) { + player.$give(cards, targets[0], false); }, - async content(event,trigger,player){ - const card=event.cards[0],target=event.target; - await player.give(card,target); - if(!target.getCards('h').includes(card)||get.type(card)!=='equip') return; - const bool=await target.chooseUseTarget(card).forResultBool(); - if(!bool) return; - const count=target.countCards('e'); - if(count>0){ - player.addTempSkill('dcshiju_range'); - player.addMark('dcshiju_range',count,false); - if(target.hasHistory('lose',evt=>{ - return evt.getParent().name==='equip'&&evt.getParent(5)===event&&evt.es&&evt.es.length>0; - })){ - for(const current of [player,target]) await current.draw(2); + async content(event, trigger, player) { + const card = event.cards[0], + target = event.target; + await player.give(card, target); + if (!target.getCards("h").includes(card) || get.type(card) !== "equip") return; + const bool = await target.chooseUseTarget(card).forResultBool(); + if (!bool) return; + const count = target.countCards("e"); + if (count > 0) { + player.addTempSkill("dcshiju_range"); + player.addMark("dcshiju_range", count, false); + if ( + target.hasHistory("lose", (evt) => { + return ( + evt.getParent().name === "equip" && + evt.getParent(5) === event && + evt.es && + evt.es.length > 0 + ); + }) + ) { + for (const current of [player, target]) await current.draw(2); } } }, - ai:{ - order:10, - result:{ - target(player,target){ - const card=ui.selected.cards[0]; - if(!card) return; - if(target.hasSkillTag('nogain')&&get.type(card)!='equip') return 0; - if(card.name=='du'&&target.hasSkillTag('nodu')) return 0; - if(get.value(card)<0) return -5; - const nh=target.countCards('h'); - return Math.max(1,5-nh); + ai: { + order: 10, + result: { + target(player, target) { + const card = ui.selected.cards[0]; + if (!card) return; + if (target.hasSkillTag("nogain") && get.type(card) != "equip") return 0; + if (card.name == "du" && target.hasSkillTag("nodu")) return 0; + if (get.value(card) < 0) return -5; + const nh = target.countCards("h"); + return Math.max(1, 5 - nh); }, }, }, }, - range:{ - charlotte:true, - onremove:true, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('dcshiju_range'); + range: { + charlotte: true, + onremove: true, + mod: { + attackRange: function (player, num) { + return num + player.countMark("dcshiju_range"); }, }, - intro:{content:'本回合攻击范围+#'}, + intro: { content: "本回合攻击范围+#" }, }, }, }, - dcyingshi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget) return false; - if(get.type(event.card)!=='trick') return false; - const evt=event.getParent(); - const evts=game.getGlobalHistory('useCard',null,evt).slice().remove(evt); - return event.targets.some(target=>{ - return evts.some(evt=>evt.targets.includes(target)); + dcyingshi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget) return false; + if (get.type(event.card) !== "trick") return false; + const evt = event.getParent(); + const evts = game.getGlobalHistory("useCard", null, evt).slice().remove(evt); + return event.targets.some((target) => { + return evts.some((evt) => evt.targets.includes(target)); }); }, - direct:true, - async content(event,trigger,player){ - const evt=trigger.getParent(); - const evts=game.getGlobalHistory('useCard',null,evt).slice().remove(evt); - const chooseableTargets=trigger.targets.filter(target=>{ - return evts.some(evt=>evt.targets.includes(target)); + direct: true, + async content(event, trigger, player) { + const evt = trigger.getParent(); + const evts = game.getGlobalHistory("useCard", null, evt).slice().remove(evt); + const chooseableTargets = trigger.targets.filter((target) => { + return evts.some((evt) => evt.targets.includes(target)); }); - const result=await player.chooseTarget() - .set('prompt',get.prompt('dcyingshi')) - .set('prompt2',`令一名可选角色选择本回合未被选择过的一项:⒈令你于此牌结算结束后视为对其使用一张${get.translation(trigger.card.name)};⒉弃置${get.cnNumber(player.countCards('e'))}张牌,此牌对其无效。`) - .set('filterTarget',(card,player,target)=>{ - return get.event('targets').includes(target); + const result = await player + .chooseTarget() + .set("prompt", get.prompt("dcyingshi")) + .set( + "prompt2", + `令一名可选角色选择本回合未被选择过的一项:⒈令你于此牌结算结束后视为对其使用一张${get.translation( + trigger.card.name + )};⒉弃置${get.cnNumber(player.countCards("e"))}张牌,此牌对其无效。` + ) + .set("filterTarget", (card, player, target) => { + return get.event("targets").includes(target); }) - .set('targets',chooseableTargets) - .set('toFriends',(()=>{ - const isPositive=chooseableTargets.some(current=>{ - return get.effect(current,trigger.card,trigger.player,player)>0; - }),isNegative=chooseableTargets.some(current=>{ - return get.effect(current,trigger.card,trigger.player,player)<-5; - }); - if((player.hasSkill('dcyingshi_choice1')||player.countCards('e')<2)&&isNegative) return true; - if(!player.hasSkill('dcyingshi_choice1')&&(get.tag(trigger.card,'norepeat')&&isNegative||isPositive)) return true; - return false; - })()) - .set('ai',target=>{ - const player=get.player(),count=player.countCards('e'),att=get.attitude(player,target); - if(att>0&&get.event('toFriends')){ - if(target.countCards('he',card=>get.value(card)<5) { + const isPositive = chooseableTargets.some((current) => { + return get.effect(current, trigger.card, trigger.player, player) > 0; + }), + isNegative = chooseableTargets.some((current) => { + return get.effect(current, trigger.card, trigger.player, player) < -5; + }); + if ( + (player.hasSkill("dcyingshi_choice1") || player.countCards("e") < 2) && + isNegative + ) + return true; + if ( + !player.hasSkill("dcyingshi_choice1") && + ((get.tag(trigger.card, "norepeat") && isNegative) || isPositive) + ) + return true; + return false; + })() + ) + .set("ai", (target) => { + const player = get.player(), + count = player.countCards("e"), + att = get.attitude(player, target); + if (att > 0 && get.event("toFriends")) { + if (target.countCards("he", (card) => get.value(card) < 5) < count) return 0; return att; } - if(player.hasSkill('dcyingshi_choice1')&&!count) return 0; - return -get.attitude(player,target); + if (player.hasSkill("dcyingshi_choice1") && !count) return 0; + return -get.attitude(player, target); }) .forResult(); - if(!result.bool) return; - const target=result.targets[0]; - player.logSkill('dcyingshi',target); + if (!result.bool) return; + const target = result.targets[0]; + player.logSkill("dcyingshi", target); let bool; - if(!player.hasSkill(`dcyingshi_choice2`)){ - const count=player.countCards('e'),forced=player.hasSkill('dcyingshi_choice1'); - if(count>0){ - const prompt=`###${get.translation(player)}对你发动了【应时】###${forced?'请':'是否'}弃置${get.cnNumber(count)}张牌,令${get.translation(trigger.card)}对你无效${forced?'。':'?或点击“取消”,令其与此牌结算后视为对你使用一张同名牌。'}`; - bool=await target.chooseToDiscard(prompt,count,forced,'he').set('ai',card=>{ - if(get.event('goon')) return 5.5-get.value(card); - return 0; - }).set('goon',!get.tag(trigger.card,'norepeat')&&get.effect(target,trigger.card,trigger.player,target)<-5).forResultBool(); - } - else bool=false; - } - else bool=player.hasSkill('dcyingshi_choice1'); - if(bool){ + if (!player.hasSkill(`dcyingshi_choice2`)) { + const count = player.countCards("e"), + forced = player.hasSkill("dcyingshi_choice1"); + if (count > 0) { + const prompt = `###${get.translation(player)}对你发动了【应时】###${ + forced ? "请" : "是否" + }弃置${get.cnNumber(count)}张牌,令${get.translation(trigger.card)}对你无效${ + forced ? "。" : "?或点击“取消”,令其与此牌结算后视为对你使用一张同名牌。" + }`; + bool = await target + .chooseToDiscard(prompt, count, forced, "he") + .set("ai", (card) => { + if (get.event("goon")) return 5.5 - get.value(card); + return 0; + }) + .set( + "goon", + !get.tag(trigger.card, "norepeat") && + get.effect(target, trigger.card, trigger.player, target) < -5 + ) + .forResultBool(); + } else bool = false; + } else bool = player.hasSkill("dcyingshi_choice1"); + if (bool) { trigger.excluded.add(target); - } - else{ - player.when({global:'useCardAfter'}) - .filter(evt=>evt===trigger.getParent()) + } else { + player + .when({ global: "useCardAfter" }) + .filter((evt) => evt === trigger.getParent()) .vars({ - targetx:target, - cardx:{ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - storage:{dcyingshi:true}, + targetx: target, + cardx: { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + storage: { dcyingshi: true }, }, }) - .then(()=>{ - const next=player.useCard(get.copy(cardx),targetx,false); - if(trigger.addedTarget) next.addedTarget=trigger.addedTarget; - if(trigger.addedTargets&&trigger.addedTargets.length) next.addedTargets=trigger.addedTargets.slice(0); + .then(() => { + const next = player.useCard(get.copy(cardx), targetx, false); + if (trigger.addedTarget) next.addedTarget = trigger.addedTarget; + if (trigger.addedTargets && trigger.addedTargets.length) + next.addedTargets = trigger.addedTargets.slice(0); }); } - player.addTempSkill(`dcyingshi_choice${bool+1}`); + player.addTempSkill(`dcyingshi_choice${bool + 1}`); }, - subSkill:{ - choice1:{charlotte:true}, - choice2:{charlotte:true}, + subSkill: { + choice1: { charlotte: true }, + choice2: { charlotte: true }, }, }, //公孙修 - dcgangu:{ - audio:2, - trigger:{global:'loseHpAfter'}, - filter(event,player){ - return event.player!==player; + dcgangu: { + audio: 2, + trigger: { global: "loseHpAfter" }, + filter(event, player) { + return event.player !== player; }, - usable:1, - forced:true, - async content(event,trigger,player){ + usable: 1, + forced: true, + async content(event, trigger, player) { await player.draw(2); await player.loseHp(); }, }, - dckuizhen:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(current=>{ - return lib.skill.dckuizhen.filterTarget(null,player,current); + dckuizhen: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((current) => { + return lib.skill.dckuizhen.filterTarget(null, player, current); }); }, - filterTarget(card,player,target){ - return target.countCards('h')>player.countCards('h')||target.getHp()>player.getHp(); + filterTarget(card, player, target) { + return target.countCards("h") > player.countCards("h") || target.getHp() > player.getHp(); }, - usable:1, - forced:true, - async content(event,trigger,player){ - const {target}=event,juedou=new lib.element.VCard({name:'juedou'}); - if(target.canUse(juedou,player,false)){ - await target.useCard(juedou,player,'noai'); + usable: 1, + forced: true, + async content(event, trigger, player) { + const { target } = event, + juedou = new lib.element.VCard({ name: "juedou" }); + if (target.canUse(juedou, player, false)) { + await target.useCard(juedou, player, "noai"); } - if(player.hasHistory('damage',evt=>{ - return evt.getParent(3)===event; - })){ + if ( + player.hasHistory("damage", (evt) => { + return evt.getParent(3) === event; + }) + ) { await player.viewHandcards(target); - const shas=target.getGainableCards(player,'h').filter(card=>get.name(card)==='sha'); - if(shas.length){ - player.addTempSkill('dckuizhen_effect'); - await player.gain(shas,'give',target).gaintag.add('dckuizhen'); + const shas = target + .getGainableCards(player, "h") + .filter((card) => get.name(card) === "sha"); + if (shas.length) { + player.addTempSkill("dckuizhen_effect"); + await player.gain(shas, "give", target).gaintag.add("dckuizhen"); } - } - else{ + } else { await target.loseHp(); } }, - ai:{ - result:{ - target(player,target){ - const [juedouEff,loseEff]=[ - get.effect(player,{name:'juedou'},target,player), - get.effect(target,{name:'losehp'},target,player) + ai: { + result: { + target(player, target) { + const [juedouEff, loseEff] = [ + get.effect(player, { name: "juedou" }, target, player), + get.effect(target, { name: "losehp" }, target, player), ]; - if(juedouEff>0) return loseEff*get.attitude(player,target)/10; + if (juedouEff > 0) return (loseEff * get.attitude(player, target)) / 10; return 0; }, - } + }, }, - subSkill:{ - effect:{ - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - charlotte:true, - filter:function(event,player){ - if(event.addCount===false) return false; - return player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - for(const i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dckuizhen')) return true; + subSkill: { + effect: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + charlotte: true, + filter: function (event, player) { + if (event.addCount === false) return false; + return player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (const i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dckuizhen")) return true; } return false; }); }, - async content(event,trigger,player){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + async content(event, trigger, player) { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; }, - mod:{ - cardUsable(card){ - if(!card.cards) return; - if(card.cards.some(card=>card.hasGaintag('dckuizhen'))) return Infinity; + mod: { + cardUsable(card) { + if (!card.cards) return; + if (card.cards.some((card) => card.hasGaintag("dckuizhen"))) return Infinity; }, }, - } - } + }, + }, }, //刘理 - dcfuli:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.countDiscardableCards(player,'h'); + dcfuli: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return player.countDiscardableCards(player, "h"); }, - usable:1, - async content(event,trigger,player){ - await player.showHandcards(get.translation(player)+'发动了【抚黎】'); - const getNum=(type)=>{ - let num=['basic','trick','equip'].indexOf(type); - if(num===-1) num=3; + usable: 1, + async content(event, trigger, player) { + await player.showHandcards(get.translation(player) + "发动了【抚黎】"); + const getNum = (type) => { + let num = ["basic", "trick", "equip"].indexOf(type); + if (num === -1) num = 3; return num; }; - const types=player.getDiscardableCards(player,'h').reduce((list,card)=>{ - return list.add(get.type2(card)); - },[]).sort((a,b)=>getNum(a)-getNum(b)); - if(types.length){ - const {result:{control}}=await player.chooseControl(types).set('ai',()=>{ - const player=get.event('player'),types=get.event('controls').slice(); - const getNum=(type)=>{ - const cards=player.getDiscardableCards(player,'h').filter(card=>get.type2(card)==type); - const countCards=(target,player,cards)=>{ - return target.countCards('h')-(target==player?cards.length:0); + const types = player + .getDiscardableCards(player, "h") + .reduce((list, card) => { + return list.add(get.type2(card)); + }, []) + .sort((a, b) => getNum(a) - getNum(b)); + if (types.length) { + const { + result: { control }, + } = await player + .chooseControl(types) + .set("ai", () => { + const player = get.event("player"), + types = get.event("controls").slice(); + const getNum = (type) => { + const cards = player + .getDiscardableCards(player, "h") + .filter((card) => get.type2(card) == type); + const countCards = (target, player, cards) => { + return target.countCards("h") - (target == player ? cards.length : 0); + }; + const max = game + .findPlayer((target) => { + return !game.hasPlayer((target2) => { + return ( + countCards(target2, player, cards) > + countCards(target, player, cards) + ); + }); + }) + .countCards("h"); + return ( + Math.min( + max, + cards.reduce((sum, card) => sum + get.cardNameLength(card), 0) + ) / cards.length + ); }; - const max=game.findPlayer(target=>{ - return !game.hasPlayer(target2=>{ - return countCards(target2,player,cards)>countCards(target,player,cards); - }); - }).countCards('h'); - return Math.min(max,cards.reduce((sum,card)=>sum+get.cardNameLength(card),0))/cards.length; - }; - return types.sort((a,b)=>{ - return getNum(b)-getNum(a); - })[0]; - }).set('prompt','弃置一种类别的所有手牌,然后摸这些牌的名字字数之和的牌'); - if(control){ - const cards=player.getDiscardableCards(player,'h').filter(card=>get.type2(card)==control); + return types.sort((a, b) => { + return getNum(b) - getNum(a); + })[0]; + }) + .set("prompt", "弃置一种类别的所有手牌,然后摸这些牌的名字字数之和的牌"); + if (control) { + const cards = player + .getDiscardableCards(player, "h") + .filter((card) => get.type2(card) == control); await player.discard(cards); - const max=game.findPlayer(target=>target.isMaxHandcard()).countCards('h'); - const num=Math.min(max,cards.reduce((sum,card)=>sum+get.cardNameLength(card),0)); - if(num) await player.draw(num); - if(cards.some(card=>card.name!='shandian'&&get.tag(card,'damage'))){ - const {result:{bool,targets}}=await player.chooseTarget('抚黎:是否令一名角色的攻击范围-1直到你的下个回合开始?') - .set('ai',target=>{ - const player=get.event('player'),num=target.getAttackRange(); - return -get.sgn(get.attitude(player,target))*(target.getAttackRange()+(num<=0?(-num+0.5):num)); - }); - if(bool){ - const target=targets[0]; + const max = game.findPlayer((target) => target.isMaxHandcard()).countCards("h"); + const num = Math.min( + max, + cards.reduce((sum, card) => sum + get.cardNameLength(card), 0) + ); + if (num) await player.draw(num); + if (cards.some((card) => card.name != "shandian" && get.tag(card, "damage"))) { + const { + result: { bool, targets }, + } = await player + .chooseTarget("抚黎:是否令一名角色的攻击范围-1直到你的下个回合开始?") + .set("ai", (target) => { + const player = get.event("player"), + num = target.getAttackRange(); + return ( + -get.sgn(get.attitude(player, target)) * + (target.getAttackRange() + (num <= 0 ? -num + 0.5 : num)) + ); + }); + if (bool) { + const target = targets[0]; player.line(target); - target.addSkill('dcfuli_range'); - target.addMark('dcfuli_range',1,false); - player.when(['phaseBegin','dieBegin']).then(()=>{ - target.removeMark('dcfuli_range',1,false); - if(!target.hasMark('dcfuli_range')) target.removeSkill('dcfuli_range'); - }).vars({target:target}); + target.addSkill("dcfuli_range"); + target.addMark("dcfuli_range", 1, false); + player + .when(["phaseBegin", "dieBegin"]) + .then(() => { + target.removeMark("dcfuli_range", 1, false); + if (!target.hasMark("dcfuli_range")) + target.removeSkill("dcfuli_range"); + }) + .vars({ target: target }); } } } } }, - ai:{ - order:1, - result:{ - player(player){ - const types=player.getDiscardableCards(player,'h').reduce((list,card)=>{ + ai: { + order: 1, + result: { + player(player) { + const types = player.getDiscardableCards(player, "h").reduce((list, card) => { return list.add(get.type2(card)); - },[]); - if(!types.some(type=>{ - const cards=player.getDiscardableCards(player,'h').filter(card=>get.type2(card)==type); - const countCards=(target,player,cards)=>{ - return target.countCards('h')-(target==player?cards.length:0); - }; - return !game.filterPlayer(target=>{ - return !game.hasPlayer(target2=>{ - return countCards(target2,player,cards)>countCards(target,player,cards); - }); - }).includes(player); - })) return 0; + }, []); + if ( + !types.some((type) => { + const cards = player + .getDiscardableCards(player, "h") + .filter((card) => get.type2(card) == type); + const countCards = (target, player, cards) => { + return target.countCards("h") - (target == player ? cards.length : 0); + }; + return !game + .filterPlayer((target) => { + return !game.hasPlayer((target2) => { + return ( + countCards(target2, player, cards) > + countCards(target, player, cards) + ); + }); + }) + .includes(player); + }) + ) + return 0; return 1; }, }, }, - subSkill:{ - range:{ - charlotte:true, - onremove:true, - mod:{ - attackRange(player,num){ - return num-player.countMark('dcfuli_range'); + subSkill: { + range: { + charlotte: true, + onremove: true, + mod: { + attackRange(player, num) { + return num - player.countMark("dcfuli_range"); }, }, - marktext:' - ', - intro:{content:'攻击范围-#'}, + marktext: " - ", + intro: { content: "攻击范围-#" }, }, }, }, - dcdehua:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - async content(event,trigger,player){ - const list=lib.inpile.filter(name=>{ - if(get.type(name)==='delay') return false; - const card=new lib.element.VCard({name:name}); - return get.tag(card,'damage')&&player.hasUseTarget(card); + dcdehua: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + async content(event, trigger, player) { + const list = lib.inpile.filter((name) => { + if (get.type(name) === "delay") return false; + const card = new lib.element.VCard({ name: name }); + return get.tag(card, "damage") && player.hasUseTarget(card); }); - if(list.length){ - const {result:{bool,links}}=await player.chooseButton(['###德化###
              视为使用一张仍可以使用的伤害类卡牌
              ',[list,'vcard']],true).set('ai',button=>{ - const name=button.link[2],player=get.player(); - let value=player.getUseValue({name,isCard:true},null,true); - if(player.countCards('h',card=>get.name(card)===name&&player.hasUseTarget(card))) value/=3; - if(name==='sha') value/=2; - if(player.getStorage('dcdehua').includes('sha')) value=Math.max(0.1,value); - return value; - }); - if(bool){ - const name=links[0][2],card=new lib.element.VCard({name:name}); - await player.chooseUseTarget(card,true); - player.markAuto('dcdehua',[name]); + if (list.length) { + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + '###德化###
              视为使用一张仍可以使用的伤害类卡牌
              ', + [list, "vcard"], + ], + true + ) + .set("ai", (button) => { + const name = button.link[2], + player = get.player(); + let value = player.getUseValue({ name, isCard: true }, null, true); + if ( + player.countCards( + "h", + (card) => get.name(card) === name && player.hasUseTarget(card) + ) + ) + value /= 3; + if (name === "sha") value /= 2; + if (player.getStorage("dcdehua").includes("sha")) + value = Math.max(0.1, value); + return value; + }); + if (bool) { + const name = links[0][2], + card = new lib.element.VCard({ name: name }); + await player.chooseUseTarget(card, true); + player.markAuto("dcdehua", [name]); } } - if(!lib.inpile.some(name=>{ - if(get.type(name)==='delay') return false; - const card=new lib.element.VCard({name:name}); - return get.tag(card,'damage')&&!player.getStorage('dcdehua').includes(name); - })) player.removeSkills('dcdehua'); + if ( + !lib.inpile.some((name) => { + if (get.type(name) === "delay") return false; + const card = new lib.element.VCard({ name: name }); + return get.tag(card, "damage") && !player.getStorage("dcdehua").includes(name); + }) + ) + player.removeSkills("dcdehua"); }, - mod:{ - maxHandcard(player,num){ - return num+player.getStorage('dcdehua').length; + mod: { + maxHandcard(player, num) { + return num + player.getStorage("dcdehua").length; }, - cardEnabled(card,player){ - if(player.getStorage('dcdehua').includes(card.name)&&(get.position(card)=='h'||card.cards&&card.cards.some(i=>get.position(i)=='h'))) return false; + cardEnabled(card, player) { + if ( + player.getStorage("dcdehua").includes(card.name) && + (get.position(card) == "h" || + (card.cards && card.cards.some((i) => get.position(i) == "h"))) + ) + return false; }, - cardSavable(card,player){ - if(player.getStorage('dcdehua').includes(card.name)&&(get.position(card)=='h'||card.cards&&card.cards.some(i=>get.position(i)=='h'))) return false; + cardSavable(card, player) { + if ( + player.getStorage("dcdehua").includes(card.name) && + (get.position(card) == "h" || + (card.cards && card.cards.some((i) => get.position(i) == "h"))) + ) + return false; }, - aiValue(player,card){ - if(player.getStorage('dcdehua').includes(get.name(card))) return 0; + aiValue(player, card) { + if (player.getStorage("dcdehua").includes(get.name(card))) return 0; }, - aiUseful(){ - return lib.skill.dcdehua.mod.aiValue.apply(this,arguments); + aiUseful() { + return lib.skill.dcdehua.mod.aiValue.apply(this, arguments); }, }, - intro:{ - content(storage){ - return '
            • 手牌上限+'+storage.length+'
            • 不能从手牌中使用'+get.translation(storage); + intro: { + content(storage) { + return ( + "
            • 手牌上限+" + + storage.length + + "
            • 不能从手牌中使用" + + get.translation(storage) + ); }, }, }, //蒋琬费祎 - dcshengxi:{ - inherit:'reshengxi', - trigger:{player:'phaseDiscardEnd'}, + dcshengxi: { + inherit: "reshengxi", + trigger: { player: "phaseDiscardEnd" }, }, - dcshoucheng:{ - audio:'shoucheng', - global:'dcshoucheng_ai', - trigger:{ - global:['equipAfter','addJudgeAfter','loseAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcshoucheng: { + audio: "shoucheng", + global: "dcshoucheng_ai", + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "loseAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - const target=_status.currentPhase; - return game.hasPlayer(current=>{ - if(target&¤t==target) return false; - let evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length&¤t.countCards('h')==0; + filter(event, player) { + const target = _status.currentPhase; + return game.hasPlayer((current) => { + if (target && current == target) return false; + let evt = event.getl(current); + return evt && evt.hs && evt.hs.length && current.countCards("h") == 0; }); }, - direct:true, - async content(event,trigger,player){ - const targetx=_status.currentPhase; - const targets=game.filterPlayer(current=>{ - if(targetx&¤t==targetx) return false; - let evt=trigger.getl(current); - return evt&&evt.hs&&evt.hs.length&¤t.countCards('h')==0; - }).sortBySeat(targetx||player); - for(const target of targets){ - if(!target.isIn()) continue; - const {result:{bool}}=await player.chooseBool(get.prompt2('dcshoucheng',target)).set('choice',get.attitude(player,target)>0); - if(bool){ - player.logSkill('dcshoucheng',target); - if(target!=player) player.addExpose(0.2); + direct: true, + async content(event, trigger, player) { + const targetx = _status.currentPhase; + const targets = game + .filterPlayer((current) => { + if (targetx && current == targetx) return false; + let evt = trigger.getl(current); + return evt && evt.hs && evt.hs.length && current.countCards("h") == 0; + }) + .sortBySeat(targetx || player); + for (const target of targets) { + if (!target.isIn()) continue; + const { + result: { bool }, + } = await player + .chooseBool(get.prompt2("dcshoucheng", target)) + .set("choice", get.attitude(player, target) > 0); + if (bool) { + player.logSkill("dcshoucheng", target); + if (target != player) player.addExpose(0.2); target.draw(2); } } }, - ai:{ - threaten(player,target){ - return Math.sqrt(game.countPlayer(i=>{ - return get.attitude(target,i)>0; - })); + ai: { + threaten(player, target) { + return Math.sqrt( + game.countPlayer((i) => { + return get.attitude(target, i) > 0; + }) + ); }, }, - subSkill:{ - ai:{ - ai:{ - noh:true, - skillTagFilter(player,tag,arg){ - if(player===_status.currentPhase||player.countCards('h')!=1) return false; - return game.hasPlayer(current=>{ - return current.hasSkill('dcshoucheng')&&get.attitude(current,player)>0; + subSkill: { + ai: { + ai: { + noh: true, + skillTagFilter(player, tag, arg) { + if (player === _status.currentPhase || player.countCards("h") != 1) + return false; + return game.hasPlayer((current) => { + return ( + current.hasSkill("dcshoucheng") && get.attitude(current, player) > 0 + ); }); - } - } - } - } + }, + }, + }, + }, }, //乐大乔 - dczixi:{ - init(){ - game.addGlobalSkill('dczixi_judge'); - game.broadcastAll(()=>lib.skill.dczixi.video()); + dczixi: { + init() { + game.addGlobalSkill("dczixi_judge"); + game.broadcastAll(() => lib.skill.dczixi.video()); }, - video(){ - const list=lib.skill.dczixi.zixiList; - for(const name of list){ - const namex='dczixi_'+name; - if(!lib.card[namex]){ - lib.card[namex]={ - type:'special_delay', - fullskin:true, - noEffect:true, - wuxieable:false, + video() { + const list = lib.skill.dczixi.zixiList; + for (const name of list) { + const namex = "dczixi_" + name; + if (!lib.card[namex]) { + lib.card[namex] = { + type: "special_delay", + fullskin: true, + noEffect: true, + wuxieable: false, }; - lib.card[namex].cardimage=name; - lib.translate[namex]=lib.translate[name]+'·姊希'; - lib.translate[namex+'_info']='由【姊希】技能创造的无效果【'+lib.translate[name]+'】'; + lib.card[namex].cardimage = name; + lib.translate[namex] = lib.translate[name] + "·姊希"; + lib.translate[namex + "_info"] = + "由【姊希】技能创造的无效果【" + lib.translate[name] + "】"; } } }, - audio:2, - trigger:{player:['phaseUseBegin','phaseUseEnd']}, - filter(event,player){ - return player.countCards('h',card=>{ - return card.hasGaintag('dcqiqin_tag')&&lib.skill.dczixi.zixiList.some(name=>{ - return game.hasPlayer(target=>target.canAddJudge(get.autoViewAs({name:'dczixi_'+name},[card]))); - }); - })>0; + audio: 2, + trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, + filter(event, player) { + return ( + player.countCards("h", (card) => { + return ( + card.hasGaintag("dcqiqin_tag") && + lib.skill.dczixi.zixiList.some((name) => { + return game.hasPlayer((target) => + target.canAddJudge(get.autoViewAs({ name: "dczixi_" + name }, [card])) + ); + }) + ); + }) > 0 + ); }, - zixiList:['lebu','bingliang','shandian'], - direct:true, - async content(event,trigger,player){ - game.addVideo('skill',player,['dczixi',[]]); - const names=lib.skill.dczixi.zixiList.filter(name=>{ - return player.countCards('h',card=>{ - return card.hasGaintag('dcqiqin_tag')&&game.hasPlayer(target=>target.canAddJudge(get.autoViewAs({name:'dczixi_'+name},[card]))); + zixiList: ["lebu", "bingliang", "shandian"], + direct: true, + async content(event, trigger, player) { + game.addVideo("skill", player, ["dczixi", []]); + const names = lib.skill.dczixi.zixiList.filter((name) => { + return player.countCards("h", (card) => { + return ( + card.hasGaintag("dcqiqin_tag") && + game.hasPlayer((target) => + target.canAddJudge(get.autoViewAs({ name: "dczixi_" + name }, [card])) + ) + ); }); }); - let map={}; - for(const name of names){ - map[get.translation(name)]=name; + let map = {}; + for (const name of names) { + map[get.translation(name)] = name; } - const {result:{bool,links}}=await player.chooseButton(2,[ - '###'+get.prompt('dczixi')+'###
              将一张“琴”以你选择的牌名置于一名角色的判定区
              ', - player.getCards('h'), - [Object.keys(map),'tdnodes'], - ]).set('filterButton',button=>{ - const type=typeof button.link,card=button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - if(type=='string') return true; - return card.hasGaintag('dcqiqin_tag')&&lib.skill.dczixi.zixiList.some(name=>{ - return game.hasPlayer(target=>target.canAddJudge(get.autoViewAs({name:'dczixi_'+name},[card]))); - }); - }).set('ai',button=>{ - const player=get.event('player'),list=Object.keys(get.event('map')); - if(typeof button.link=='string'){ - const card=player.getCards('h',card=>{ - if(get.value(card)>=7) return false; - return card.hasGaintag('dcqiqin_tag')&&game.hasPlayer(target=>target.canAddJudge(get.autoViewAs({name:'dczixi_'+name},[card]))); - }).sort((a,b)=>get.value(a)-get.value(b))[0]; - if(game.hasPlayer(current=>{ - return get.attitude(player,current)<0&&lib.skill.dczixi.zixiList.some(name=>current.canAddJudge(get.autoViewAs({name:'dczixi_'+name},[card]))); - })) return list.indexOf(button.link)+1; - return 1/(list.indexOf(button.link)+1); - } - return 7-get.value(button.link); - }).set('map',map); - if(bool){ - const name=links.find(i=>typeof i=='string'),card=links.find(j=>j!=name),cardname=map[name]; - const {result:{bool,targets}}=await player.chooseTarget('请选择【'+name+'('+get.translation(card)+')】置入的目标',(cardx,player,target)=>{ - return target.canAddJudge(get.autoViewAs({name:'dczixi_'+get.event('cardname')},[get.event('card')])); - },true).set('ai',target=>{ - const player=get.event('player'),card=get.event('card'); - if(game.hasPlayer(current=>{ - return get.attitude(player,current)<0&¤t.canAddJudge(get.autoViewAs({name:'dczixi_'+get.event('cardname')},[card])); - })) return -target.countCards('j')-1; - return target.countCards('j')+1; - }).set('card',card).set('cardname',cardname); - if(bool){ - const target=targets[0]; - player.logSkill('dczixi',target); - player.$give(card,target,false); + const { + result: { bool, links }, + } = await player + .chooseButton(2, [ + "###" + + get.prompt("dczixi") + + '###
              将一张“琴”以你选择的牌名置于一名角色的判定区
              ', + player.getCards("h"), + [Object.keys(map), "tdnodes"], + ]) + .set("filterButton", (button) => { + const type = typeof button.link, + card = button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + if (type == "string") return true; + return ( + card.hasGaintag("dcqiqin_tag") && + lib.skill.dczixi.zixiList.some((name) => { + return game.hasPlayer((target) => + target.canAddJudge(get.autoViewAs({ name: "dczixi_" + name }, [card])) + ); + }) + ); + }) + .set("ai", (button) => { + const player = get.event("player"), + list = Object.keys(get.event("map")); + if (typeof button.link == "string") { + const card = player + .getCards("h", (card) => { + if (get.value(card) >= 7) return false; + return ( + card.hasGaintag("dcqiqin_tag") && + game.hasPlayer((target) => + target.canAddJudge( + get.autoViewAs({ name: "dczixi_" + name }, [card]) + ) + ) + ); + }) + .sort((a, b) => get.value(a) - get.value(b))[0]; + if ( + game.hasPlayer((current) => { + return ( + get.attitude(player, current) < 0 && + lib.skill.dczixi.zixiList.some((name) => + current.canAddJudge( + get.autoViewAs({ name: "dczixi_" + name }, [card]) + ) + ) + ); + }) + ) + return list.indexOf(button.link) + 1; + return 1 / (list.indexOf(button.link) + 1); + } + return 7 - get.value(button.link); + }) + .set("map", map); + if (bool) { + const name = links.find((i) => typeof i == "string"), + card = links.find((j) => j != name), + cardname = map[name]; + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "请选择【" + name + "(" + get.translation(card) + ")】置入的目标", + (cardx, player, target) => { + return target.canAddJudge( + get.autoViewAs({ name: "dczixi_" + get.event("cardname") }, [ + get.event("card"), + ]) + ); + }, + true + ) + .set("ai", (target) => { + const player = get.event("player"), + card = get.event("card"); + if ( + game.hasPlayer((current) => { + return ( + get.attitude(player, current) < 0 && + current.canAddJudge( + get.autoViewAs({ name: "dczixi_" + get.event("cardname") }, [ + card, + ]) + ) + ); + }) + ) + return -target.countCards("j") - 1; + return target.countCards("j") + 1; + }) + .set("card", card) + .set("cardname", cardname); + if (bool) { + const target = targets[0]; + player.logSkill("dczixi", target); + player.$give(card, target, false); await game.asyncDelay(0.5); - target.addJudge({name:'dczixi_'+cardname},[card]); + target.addJudge({ name: "dczixi_" + cardname }, [card]); } } }, - group:'dczixi_effect', - subSkill:{ - judge:{ - mod:{ - targetEnabled(card,player,target){ - const list=lib.skill.dczixi.zixiList; - const name=(typeof card=='string')?card:(card.viewAs?card.viewAs:card.name); - if(name.indexOf('dczixi_')==0){ - const namex=name.slice('dczixi_'.length); - if(list.includes(namex)&&target.hasJudge(namex)) return false; - } - else if(list.includes(name)&&target.hasJudge('dczixi_'+name)) return false; + group: "dczixi_effect", + subSkill: { + judge: { + mod: { + targetEnabled(card, player, target) { + const list = lib.skill.dczixi.zixiList; + const name = + typeof card == "string" ? card : card.viewAs ? card.viewAs : card.name; + if (name.indexOf("dczixi_") == 0) { + const namex = name.slice("dczixi_".length); + if (list.includes(namex) && target.hasJudge(namex)) return false; + } else if (list.includes(name) && target.hasJudge("dczixi_" + name)) + return false; }, }, - ai:{ - threaten(player,target){ - if(!player.hasSkill('dczixi')||![1,2,3].includes(target.countCards('j'))) return; - return 3+target.countCards('j'); + ai: { + threaten(player, target) { + if (!player.hasSkill("dczixi") || ![1, 2, 3].includes(target.countCards("j"))) + return; + return 3 + target.countCards("j"); }, }, }, - effect:{ - audio:'dczixi', - trigger:{player:'useCardToTargeted'}, - filter(event,player){ - return event.isFirstTarget&&event.targets.length==1&&[1,2,3].includes(event.target.countCards('j'))&&(get.type(event.card)=='basic'||get.type(event.card)=='trick'); + effect: { + audio: "dczixi", + trigger: { player: "useCardToTargeted" }, + filter(event, player) { + return ( + event.isFirstTarget && + event.targets.length == 1 && + [1, 2, 3].includes(event.target.countCards("j")) && + (get.type(event.card) == "basic" || get.type(event.card) == "trick") + ); }, - prompt2(event,player){ - const target=event.target,str=get.translation(target); + prompt2(event, player) { + const target = event.target, + str = get.translation(target); return [ - '令'+get.translation(event.card)+'对'+str+'额外结算一次', - '摸两张牌', - '弃置'+str+'判定区里的所有牌,对其造成3点伤害', - ][target.countCards('j')-1]; + "令" + get.translation(event.card) + "对" + str + "额外结算一次", + "摸两张牌", + "弃置" + str + "判定区里的所有牌,对其造成3点伤害", + ][target.countCards("j") - 1]; }, - check(event,player){ - const target=event.target,num=target.countCards('j'); - if(num==2) return true; - if(num==1) return get.effect(target,event.card,player,player)>0; - return get.attitude(player,target)<0&&get.damageEffect(target,player,player)>0; + check(event, player) { + const target = event.target, + num = target.countCards("j"); + if (num == 2) return true; + if (num == 1) return get.effect(target, event.card, player, player) > 0; + return ( + get.attitude(player, target) < 0 && + get.damageEffect(target, player, player) > 0 + ); }, - logTarget:'target', - async content(event,trigger,player){ - const target=trigger.target,num=target.countCards('j'); - switch(num){ + logTarget: "target", + async content(event, trigger, player) { + const target = trigger.target, + num = target.countCards("j"); + switch (num) { case 1: trigger.getParent().effectCount++; - game.log(trigger.card,'额外结算一次'); + game.log(trigger.card, "额外结算一次"); break; case 2: player.draw(2); break; case 3: - target.discard(target.getCards('j')).discarder=player; + target.discard(target.getCards("j")).discarder = player; target.damage(3); break; } @@ -1350,107 +1826,120 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //孔融 - dckrmingshi:{ - audio:'mingshi', - trigger:{player:'damageBegin4'}, - filter(event,player){ - return event.source&&event.source.countCards('h')>player.countCards('h'); + dckrmingshi: { + audio: "mingshi", + trigger: { player: "damageBegin4" }, + filter(event, player) { + return event.source && event.source.countCards("h") > player.countCards("h"); }, - forced:true, - logTarget:'source', - async content(event,trigger,player){ - const target=trigger.source; - const {result:{bool}}=await target.chooseToDiscard('名士:弃置一张手牌,或防止对'+get.translation(player)+'造成的伤害').set('ai',card=>{ - if(get.event('goon')) return 0; - return 6-get.value(card); - }).set('goon',get.damageEffect(player,target,target)<=0); - if(!bool) trigger.cancel(); + forced: true, + logTarget: "source", + async content(event, trigger, player) { + const target = trigger.source; + const { + result: { bool }, + } = await target + .chooseToDiscard( + "名士:弃置一张手牌,或防止对" + get.translation(player) + "造成的伤害" + ) + .set("ai", (card) => { + if (get.event("goon")) return 0; + return 6 - get.value(card); + }) + .set("goon", get.damageEffect(player, target, target) <= 0); + if (!bool) trigger.cancel(); }, - ai:{ - effect:{ - target_use(card,player,target,current){ - if(get.tag(card,'damage')&&target!=player){ - if(_status.event.name=='dckrmingshi') return; - if(get.attitude(player,target)>0&¤t<0) return 'zerotarget'; - var bs=player.getCards('h'); + ai: { + effect: { + target_use(card, player, target, current) { + if (get.tag(card, "damage") && target != player) { + if (_status.event.name == "dckrmingshi") return; + if (get.attitude(player, target) > 0 && current < 0) return "zerotarget"; + var bs = player.getCards("h"); bs.remove(card); - if(card.cards) bs.removeArray(card.cards); + if (card.cards) bs.removeArray(card.cards); else bs.removeArray(ui.selected.cards); - if(bs.length>target.countCards('h')){ - if(bs.some(bsi=>get.value(bsi)<7)) return [1,0,1,-0.5]; - return [1,0,0.3,0]; + if (bs.length > target.countCards("h")) { + if (bs.some((bsi) => get.value(bsi) < 7)) return [1, 0, 1, -0.5]; + return [1, 0, 0.3, 0]; } - return [1,0,1,-0.5]; + return [1, 0, 1, -0.5]; } }, }, }, }, //新服SP孟获 - dcmanwang:{ - audio:'spmanwang', - inherit:'spmanwang', - check:function(card){ - var player=_status.event.player; - var max=Math.min(player.isDamaged()?3:2,4-player.countMark('dcmanwang')); - if(!max&&!player.hasSkill('dcpanqin')) return 0; - if(max==0&&ui.selected.length>0) return 0; - return 7-ui.selected.cards.length-get.value(card); + dcmanwang: { + audio: "spmanwang", + inherit: "spmanwang", + check: function (card) { + var player = _status.event.player; + var max = Math.min(player.isDamaged() ? 3 : 2, 4 - player.countMark("dcmanwang")); + if (!max && !player.hasSkill("dcpanqin")) return 0; + if (max == 0 && ui.selected.length > 0) return 0; + return 7 - ui.selected.cards.length - get.value(card); }, - content:function(){ - var num=Math.min(cards.length,4-player.countMark('dcmanwang')); - if(num>=1) player.addSkills('dcpanqin'); - if(num>=2) player.draw(); - if(num>=3) player.recover(); - if(num>=4){ + content: function () { + var num = Math.min(cards.length, 4 - player.countMark("dcmanwang")); + if (num >= 1) player.addSkills("dcpanqin"); + if (num >= 2) player.draw(); + if (num >= 3) player.recover(); + if (num >= 4) { player.draw(2); - player.removeSkills('dcpanqin'); + player.removeSkills("dcpanqin"); } }, - ai:{ - order:2, - result:{ - player:function(player,target){ - if(player.getUseValue({name:'nanman'})<=0) return 0; - if(player.getStat('skill').spmanwang&&player.hasSkill('dcpanqin')) return 0; + ai: { + order: 2, + result: { + player: function (player, target) { + if (player.getUseValue({ name: "nanman" }) <= 0) return 0; + if (player.getStat("skill").spmanwang && player.hasSkill("dcpanqin")) return 0; return 1; }, }, }, - derivation:'dcpanqin', + derivation: "dcpanqin", }, - dcpanqin:{ - audio:'sppanqin', - inherit:'sppanqin', - content:function(){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent(trigger.name)!=trigger) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'){ + dcpanqin: { + audio: "sppanqin", + inherit: "sppanqin", + content: function () { + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent(trigger.name) != trigger) return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d") { cards.add(i); } } }); - player.chooseUseTarget(true,{name:'nanman'},cards); - player.addTempSkill('dcpanqin_eff'); + player.chooseUseTarget(true, { name: "nanman" }, cards); + player.addTempSkill("dcpanqin_eff"); }, - subSkill:{ - eff:{ - charlotte:true, - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='nanman'&&event.getParent(2).name=='dcpanqin'&&player.countMark('dcmanwang')<4&&player.hasSkill('dcmanwang',null,null,false)&&event.cards.length<=event.targets.length; + subSkill: { + eff: { + charlotte: true, + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + event.card.name == "nanman" && + event.getParent(2).name == "dcpanqin" && + player.countMark("dcmanwang") < 4 && + player.hasSkill("dcmanwang", null, null, false) && + event.cards.length <= event.targets.length + ); }, - forced:true, - popup:false, - content:function(){ - 'step 0' - player.addMark('dcmanwang',1,false); - switch(player.countMark('dcmanwang')){ + forced: true, + popup: false, + content: function () { + "step 0"; + player.addMark("dcmanwang", 1, false); + switch (player.countMark("dcmanwang")) { case 1: player.draw(2); - player.removeSkills('dcpanqin'); + player.removeSkills("dcpanqin"); break; case 2: player.recover(); @@ -1459,196 +1948,236 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.draw(); break; case 4: - player.addSkills('dcpanqin'); + player.addSkills("dcpanqin"); break; } - 'step 1' + "step 1"; player.gainMaxHp(); player.recover(); }, - } - } + }, + }, }, //凌操 - dcdufeng:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - async content(event,trigger,player){ - const list=[]; - for(let i=1;i<6;i++){ - if(player.isDisabled(i)) continue; - list.push('equip'+i); + dcdufeng: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + async content(event, trigger, player) { + const list = []; + for (let i = 1; i < 6; i++) { + if (player.isDisabled(i)) continue; + list.push("equip" + i); } - list.push('cancel2'); - const next=player.chooseControl(list); - next.set('prompt','独锋:请废除一个装备栏,或点击“取消”失去1点体力'); - next.set('ai',()=>{ - const list=get.event().list.slice(),player=get.player(); - if(player.hp<=2&&list.length>1) list.remove('cancel2'); - const listx=list.filter(subtype=>!player.getEquips(subtype).length); - if(listx.length) return listx.randomGet(); + list.push("cancel2"); + const next = player.chooseControl(list); + next.set("prompt", "独锋:请废除一个装备栏,或点击“取消”失去1点体力"); + next.set("ai", () => { + const list = get.event().list.slice(), + player = get.player(); + if (player.hp <= 2 && list.length > 1) list.remove("cancel2"); + const listx = list.filter((subtype) => !player.getEquips(subtype).length); + if (listx.length) return listx.randomGet(); return list.randomGet(); - }) - next.set('list',list); - const {result}=await next; - if(result.control=='cancel2') await player.loseHp(); + }); + next.set("list", list); + const { result } = await next; + if (result.control == "cancel2") await player.loseHp(); else await player.disableEquip(result.control); - if(!player.isIn()) return; - const num=Math.min(player.countDisabled()+player.getDamagedHp(),player.maxHp); + if (!player.isIn()) return; + const num = Math.min(player.countDisabled() + player.getDamagedHp(), player.maxHp); await player.draw(num); - player.addTempSkill('dcdufeng_effect'); - player.addMark('dcdufeng_effect',num,false); + player.addTempSkill("dcdufeng_effect"); + player.addMark("dcdufeng_effect", num, false); }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - intro:{ - content:'本回合攻击范围与使用【杀】的次数上限均为#', + subSkill: { + effect: { + charlotte: true, + onremove: true, + intro: { + content: "本回合攻击范围与使用【杀】的次数上限均为#", }, - mod:{ - attackRangeBase(player,num){ - return player.countMark('dcdufeng_effect'); + mod: { + attackRangeBase(player, num) { + return player.countMark("dcdufeng_effect"); }, - cardUsable(card,player,num){ - if(card.name=='sha') return player.countMark('dcdufeng_effect'); + cardUsable(card, player, num) { + if (card.name == "sha") return player.countMark("dcdufeng_effect"); }, }, - } + }, }, }, //小乔 - dcqiqin:{ - audio:2, - audioname:['yue_daqiao'], - trigger:{ - global:'phaseBefore', - player:'enterGame' + dcqiqin: { + audio: 2, + audioname: ["yue_daqiao"], + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - content:function(){ - let cards=player.getCards('h'); - player.addGaintag(cards,'dcqiqin_tag'); - player.markAuto('dcqiqin',cards); + forced: true, + content: function () { + let cards = player.getCards("h"); + player.addGaintag(cards, "dcqiqin_tag"); + player.markAuto("dcqiqin", cards); }, - group:'dcqiqin_restore', - subSkill:{ - tag:{}, - restore:{ - audio:'dcqiqin', - audioname:['yue_daqiao'], - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - const targets=game.players.slice().concat(game.dead); - return targets.some(target=>target.getStorage('dcqiqin').filterInD('d').length); + group: "dcqiqin_restore", + subSkill: { + tag: {}, + restore: { + audio: "dcqiqin", + audioname: ["yue_daqiao"], + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + const targets = game.players.slice().concat(game.dead); + return targets.some( + (target) => target.getStorage("dcqiqin").filterInD("d").length + ); }, - forced:true, - content:function(){ - const targets=game.players.slice().concat(game.dead); - const cards=targets.reduce((list,target)=>list.addArray(target.getStorage('dcqiqin').filterInD('d')),[]); - player.gain(cards,'gain2').gaintag.add('dcqiqin_tag'); + forced: true, + content: function () { + const targets = game.players.slice().concat(game.dead); + const cards = targets.reduce( + (list, target) => list.addArray(target.getStorage("dcqiqin").filterInD("d")), + [] + ); + player.gain(cards, "gain2").gaintag.add("dcqiqin_tag"); }, }, }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcqiqin_tag')) return true; + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcqiqin_tag")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcqiqin_tag')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcqiqin_tag")) return false; }, }, }, - dcweiwan:{ - audio:2, - enable:'phaseUse', - filter:(event,player)=>{ - return player.countCards(lib.skill.dcweiwan.position,card=>{ - return lib.skill.dcweiwan.filterCard(card,player); - })&&game.hasPlayer(target=>{ - return lib.skill.dcweiwan.filterTarget(null,player,target); - }); + dcweiwan: { + audio: 2, + enable: "phaseUse", + filter: (event, player) => { + return ( + player.countCards(lib.skill.dcweiwan.position, (card) => { + return lib.skill.dcweiwan.filterCard(card, player); + }) && + game.hasPlayer((target) => { + return lib.skill.dcweiwan.filterTarget(null, player, target); + }) + ); }, - filterCard:(card,player)=>{ - return card.hasGaintag('dcqiqin_tag')&&lib.filter.cardDiscardable(card,player); + filterCard: (card, player) => { + return card.hasGaintag("dcqiqin_tag") && lib.filter.cardDiscardable(card, player); }, - filterTarget:(card,player,target)=>{ - return target!=player&&target.countCards('he'); + filterTarget: (card, player, target) => { + return target != player && target.countCards("he"); }, - position:'h', - check:(card)=>{ - const player=_status.event.player; - const target = game.players.reduce((result, current) => { - if (current === player) return result; - const effect = Math.abs(lib.skill.dcweiwan.ai.result.target(player, current)); - return effect > result[1] ? [current, effect] : result; - }, [null, 0])[0]; - return target?lib.skill.dcweiwan.getWeiWanEffect(player,card,target):0; + position: "h", + check: (card) => { + const player = _status.event.player; + const target = game.players.reduce( + (result, current) => { + if (current === player) return result; + const effect = Math.abs(lib.skill.dcweiwan.ai.result.target(player, current)); + return effect > result[1] ? [current, effect] : result; + }, + [null, 0] + )[0]; + return target ? lib.skill.dcweiwan.getWeiWanEffect(player, card, target) : 0; }, - usable:1, - content:function*(event,map){ - let player=map.player,target=event.target; - let suit=get.suit(event.cards[0],player); - let cards=target.getCards('hej',card=>get.suit(card,target)!=suit&&lib.filter.canBeGained(card,player,target)); - if(!cards.length){ - player.chat('无牌可得!!'); + usable: 1, + content: function* (event, map) { + let player = map.player, + target = event.target; + let suit = get.suit(event.cards[0], player); + let cards = target.getCards( + "hej", + (card) => + get.suit(card, target) != suit && lib.filter.canBeGained(card, player, target) + ); + if (!cards.length) { + player.chat("无牌可得!!"); return; } - let suits=lib.suit.slice(); + let suits = lib.suit.slice(); suits.reverse(); - suits.add('none'); - suits.forEach(suit2=>{ - let cards2=cards.filter(card=>get.suit(card,target)==suit2); - if(cards2.length){ + suits.add("none"); + suits.forEach((suit2) => { + let cards2 = cards.filter((card) => get.suit(card, target) == suit2); + if (cards2.length) { cards2.randomRemove(); cards.removeArray(cards2); } }); - if(!cards.length){ - player.chat('无牌可得!!'); + if (!cards.length) { + player.chat("无牌可得!!"); return; } - player.gain(cards,target,'give'); - switch(cards.length){ + player.gain(cards, target, "give"); + switch (cards.length) { case 1: target.loseHp(); break; case 2: - player.addTempSkill('tanbei_effect3'); - target.addTempSkill('tanbei_effect1'); + player.addTempSkill("tanbei_effect3"); + target.addTempSkill("tanbei_effect1"); break; case 3: - player.addTempSkill('tanbei_effect3'); - target.addTempSkill('tanbei_effect2'); + player.addTempSkill("tanbei_effect3"); + target.addTempSkill("tanbei_effect2"); break; } }, - ai:{ - order:9, - result:{ - target:(player,target)=>{ - const att=get.sgn(get.attitude(player,target))-1; - const cards=player.getCards(lib.skill.dcweiwan.position,card=>lib.skill.dcweiwan.filterCard(card,player)); - return att * cards.reduce((result, card) => { - const effect = lib.skill.dcweiwan.getWeiWanEffect(player, card, target); - return effect > result ? effect : result; - },0); + ai: { + order: 9, + result: { + target: (player, target) => { + const att = get.sgn(get.attitude(player, target)) - 1; + const cards = player.getCards(lib.skill.dcweiwan.position, (card) => + lib.skill.dcweiwan.filterCard(card, player) + ); + return ( + att * + cards.reduce((result, card) => { + const effect = lib.skill.dcweiwan.getWeiWanEffect(player, card, target); + return effect > result ? effect : result; + }, 0) + ); }, }, + combo: "dcqiqin", }, - getWeiWanEffect:(player,cardx,target)=>{ - const suit=get.suit(cardx,player); - const cards=target.getCards('hej',card=>get.suit(card,target)!==suit&&lib.filter.canBeGained(card,player,target)); - const num=lib.suits.filter(suit=>cards.some(card=>get.suit(card,target)===suit)).length; - switch(num){ + getWeiWanEffect: (player, cardx, target) => { + const suit = get.suit(cardx, player); + const cards = target.getCards( + "hej", + (card) => + get.suit(card, target) !== suit && lib.filter.canBeGained(card, player, target) + ); + const num = lib.suits.filter((suit) => + cards.some((card) => get.suit(card, target) === suit) + ).length; + switch (num) { case 1: - return num+Math.max(0,get.sgn(get.effect(target,{name:'losehp'},player,player))); + return ( + num + + Math.max(0, get.sgn(get.effect(target, { name: "losehp" }, player, player))) + ); case 2: - return num+player.countCards('he',card=>player.canUse(card,target,false)&&get.effect(target,card,player,player)>0); + return ( + num + + player.countCards( + "he", + (card) => + player.canUse(card, target, false) && + get.effect(target, card, player, player) > 0 + ) + ); case 3: return Math.ceil(num / 2); default: @@ -1657,313 +2186,394 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //董昭 - dcyijia:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(!event.player.isIn()) return false; - if(get.distance(player,event.player)>1) return false; - return player.canMoveCard(null,true,game.filterPlayer(i=>i!=event.player),event.player,'canReplace'); + dcyijia: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (!event.player.isIn()) return false; + if (get.distance(player, event.player) > 1) return false; + return player.canMoveCard( + null, + true, + game.filterPlayer((i) => i != event.player), + event.player, + "canReplace" + ); }, - check:function(event,player){ - return player.canMoveCard(true,true,game.filterPlayer(i=>i!=event.player),event.player,'canReplace'); + check: function (event, player) { + return player.canMoveCard( + true, + true, + game.filterPlayer((i) => i != event.player), + event.player, + "canReplace" + ); }, - prompt2:function(event,player){ - return `将场上一张装备牌移动至${get.translation(event.player)}的装备区内(替换原装备)。然后若其因此脱离了一名角色的攻击范围,你摸一张牌。`; + prompt2: function (event, player) { + return `将场上一张装备牌移动至${get.translation( + event.player + )}的装备区内(替换原装备)。然后若其因此脱离了一名角色的攻击范围,你摸一张牌。`; }, - logTarget:'player', - line:false, - content:function*(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - const inRangeList=game.filterPlayer(current=>current.inRange(target)); - yield player.moveCard(true,game.filterPlayer(i=>i!=target),target,'canReplace'); - const leaveSomeone=inRangeList.some(current=>!current.inRange(target)); - if(leaveSomeone) player.draw(); + logTarget: "player", + line: false, + content: function* (event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + const inRangeList = game.filterPlayer((current) => current.inRange(target)); + yield player.moveCard( + true, + game.filterPlayer((i) => i != target), + target, + "canReplace" + ); + const leaveSomeone = inRangeList.some((current) => !current.inRange(target)); + if (leaveSomeone) player.draw(); }, - ai:{ - maixie:true, - expose:0.2, - threaten:3.3, + ai: { + maixie: true, + expose: 0.2, + threaten: 3.3, }, }, - dcdingji:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function*(event,map){ - const player=map.player; + dcdingji: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function* (event, map) { + const player = map.player; let result; - result=yield player.chooseTarget(get.prompt2('dcdingji')).set('ai',target=>{ - let att=get.attitude(get.player(),target)/2; - const delta=5-target.countCards('h'); - let fix=1; - const hs=target.getCards('h'); - outer:for(let i=0;i { + let att = get.attitude(get.player(), target) / 2; + const delta = 5 - target.countCards("h"); + let fix = 1; + const hs = target.getCards("h"); + outer: for (let i = 0; i < hs.length - 1; i++) { + const name1 = get.name(hs[i]); + for (let j = i + 1; j < hs.length; j++) { + const name2 = get.name(hs[j]); + if (name1 == name2) { + fix = 0.5; + break outer; } } } - if(delta>0){ - if(target.hasSkillTag('nogain')) att/=3; - return Math.sqrt(delta)*att*fix; + if (delta > 0) { + if (target.hasSkillTag("nogain")) att /= 3; + return Math.sqrt(delta) * att * fix; } - if(delta>-2&&att>0) return fix==0.5?0.1:-1; - return -Math.sqrt(-delta)*att/2; + if (delta > -2 && att > 0) return fix == 0.5 ? 0.1 : -1; + return (-Math.sqrt(-delta) * att) / 2; }); - if(!result.bool) return event.finish(); - const target=result.targets[0]; - player.logSkill('dcdingji',target); - if(target!=player) player.addExpose(0.3); - const delta=5-target.countCards('h'); - if(delta!=0){ - yield target[delta>0?'draw':'chooseToDiscard'](Math.abs(delta),true); + if (!result.bool) return event.finish(); + const target = result.targets[0]; + player.logSkill("dcdingji", target); + if (target != player) player.addExpose(0.3); + const delta = 5 - target.countCards("h"); + if (delta != 0) { + yield target[delta > 0 ? "draw" : "chooseToDiscard"](Math.abs(delta), true); } target.showHandcards(); - const hs=target.getCards('h'); - let hasSame=false; - outer:for(let i=0;i{ - if(!['basic','trick'].includes(info[0])) return false; - if(!target.hasUseTarget(new lib.element.VCard({name:info[2],nature:info[3],isCard:true}))) return false; - return hs.some(card=>{ - return get.name(card)==info[2]&&get.is.sameNature([card,info[3]],true); + if (hasSame) return event.finish(); + const list = get.inpileVCardList((info) => { + if (!["basic", "trick"].includes(info[0])) return false; + if ( + !target.hasUseTarget( + new lib.element.VCard({ name: info[2], nature: info[3], isCard: true }) + ) + ) + return false; + return hs.some((card) => { + return get.name(card) == info[2] && get.is.sameNature([card, info[3]], true); }); }); - if(!list.length) return event.finish(); - result=yield target.chooseButton(['是否视为使用其中一张牌?',[list,'vcard']]).set('ai',button=>{ - return get.player().getUseValue({name:button.link[2]}); - }); - if(result.bool){ - target.chooseUseTarget(new lib.element.VCard({ - name:result.links[0][2], - nature:result.links[0][3], - isCard:true, - }),true,false); + if (!list.length) return event.finish(); + result = yield target + .chooseButton(["是否视为使用其中一张牌?", [list, "vcard"]]) + .set("ai", (button) => { + return get.player().getUseValue({ name: button.link[2] }); + }); + if (result.bool) { + target.chooseUseTarget( + new lib.element.VCard({ + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }), + true, + false + ); } }, }, //蒯祺 - dcliangxiu:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.hasCard(card=>{ - const type=get.type2(card,player); - return player.hasCard(cardx=>{ - if(card==cardx) return false; - return get.type2(cardx,player)!=type; - },'he'); - },'he'); + dcliangxiu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.hasCard((card) => { + const type = get.type2(card, player); + return player.hasCard((cardx) => { + if (card == cardx) return false; + return get.type2(cardx, player) != type; + }, "he"); + }, "he"); }, - filterCard:function(card,player){ - if(!ui.selected.cards.length) return true; - return get.type2(ui.selected.cards[0],player)!=get.type2(card,player); + filterCard: function (card, player) { + if (!ui.selected.cards.length) return true; + return get.type2(ui.selected.cards[0], player) != get.type2(card, player); }, - selectCard:2, - check:function(card){ - const player=get.player(); - const bannedTypes=[]; - bannedTypes.addArray(player.getStorage('dcliangxiu')); - if(!ui.selected.cards.length){ - let val=get.value(card); - if(val>5.5) return 0; - if(bannedTypes.includes(get.type2(card,player))) return 7.5-val; - return 5.5-val; + selectCard: 2, + check: function (card) { + const player = get.player(); + const bannedTypes = []; + bannedTypes.addArray(player.getStorage("dcliangxiu")); + if (!ui.selected.cards.length) { + let val = get.value(card); + if (val > 5.5) return 0; + if (bannedTypes.includes(get.type2(card, player))) return 7.5 - val; + return 5.5 - val; } - bannedTypes.addArray(ui.selected.cards.map(card=>get.type2(card,player))); - bannedTypes.add(get.type2(card,player)); - const filter=card=>!bannedTypes.includes(get.type2(card,player)); - if(!get.cardPile(filter)) return 0; - return 6-get.value(card); + bannedTypes.addArray(ui.selected.cards.map((card) => get.type2(card, player))); + bannedTypes.add(get.type2(card, player)); + const filter = (card) => !bannedTypes.includes(get.type2(card, player)); + if (!get.cardPile(filter)) return 0; + return 6 - get.value(card); }, - position:'he', - complexCard:true, - onremove:true, - content:function*(event,map){ - const player=map.player; - const cards=[]; - const bannedTypes=[]; - bannedTypes.addArray(event.cards.map(card=>get.type2(card,player))); - bannedTypes.addArray(player.getStorage('dcliangxiu')); + position: "he", + complexCard: true, + onremove: true, + content: function* (event, map) { + const player = map.player; + const cards = []; + const bannedTypes = []; + bannedTypes.addArray(event.cards.map((card) => get.type2(card, player))); + bannedTypes.addArray(player.getStorage("dcliangxiu")); - const filter=card=>!bannedTypes.includes(get.type2(card,player)); - const piles=['cardPile','discardPile']; - for(const pile of piles){ - for(let i=0;i !bannedTypes.includes(get.type2(card, player)); + const piles = ["cardPile", "discardPile"]; + for (const pile of piles) { + for (let i = 0; i < ui[pile].childNodes.length; i++) { + const card = ui[pile].childNodes[i]; + if (filter(card)) { cards.add(card); - if(cards.length>=2) break; + if (cards.length >= 2) break; } } - if(cards.length>=2) break; + if (cards.length >= 2) break; } let result; - if(!cards.length){ - player.chat('没牌了…'); - game.log('但是哪里都找不到没有符合条件的牌!'); + if (!cards.length) { + player.chat("没牌了…"); + game.log("但是哪里都找不到没有符合条件的牌!"); event.finish(); return; - } - else if(cards.length==1) result={bool:true,links:cards}; - else result=yield player.chooseButton(['良秀:获得一张牌',cards],true).set('ai',get.buttonValue); - if(result.bool){ - const toGain=result.links; - player.markAuto('dcliangxiu',get.type2(toGain[0],false)); - player.when({global:'phaseChange'}).then(()=>{ - player.unmarkSkill('dcliangxiu'); + } else if (cards.length == 1) result = { bool: true, links: cards }; + else + result = yield player + .chooseButton(["良秀:获得一张牌", cards], true) + .set("ai", get.buttonValue); + if (result.bool) { + const toGain = result.links; + player.markAuto("dcliangxiu", get.type2(toGain[0], false)); + player.when({ global: "phaseChange" }).then(() => { + player.unmarkSkill("dcliangxiu"); }); - player.gain(toGain,'gain2'); + player.gain(toGain, "gain2"); } }, - intro:{ - content:'已因此技能获得过$牌', - onunmark:true, + intro: { + content: "已因此技能获得过$牌", + onunmark: true, }, - ai:{ - order:2, - result:{player:1}, + ai: { + order: 2, + result: { player: 1 }, }, }, - dcxunjie:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - if(['handcard','hp'].every(i=>player.isTempBanned(`dcxunjie_${i}`))) return false; - return player.hasHistory('gain',evt=>{ - return !evt.getParent('phaseDraw',true); + dcxunjie: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + if (["handcard", "hp"].every((i) => player.isTempBanned(`dcxunjie_${i}`))) return false; + return player.hasHistory("gain", (evt) => { + return !evt.getParent("phaseDraw", true); }); }, - direct:true, - content:function*(event,map){ - const player=map.player; - const choices=[]; - const choiceList=[ - '令一名角色将手牌数摸或弃置至与其体力值相同', - '令一名角色将体力回复或失去至与其手牌数相同', + direct: true, + content: function* (event, map) { + const player = map.player; + const choices = []; + const choiceList = [ + "令一名角色将手牌数摸或弃置至与其体力值相同", + "令一名角色将体力回复或失去至与其手牌数相同", ]; - if(!player.isTempBanned('dcxunjie_handcard')) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+'(已被选择过)'; - if(!player.isTempBanned('dcxunjie_hp')) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+'(已被选择过)'; + if (!player.isTempBanned("dcxunjie_handcard")) choices.push("选项一"); + else + choiceList[0] = + '' + choiceList[0] + "(已被选择过)"; + if (!player.isTempBanned("dcxunjie_hp")) choices.push("选项二"); + else + choiceList[1] = + '' + choiceList[1] + "(已被选择过)"; let result; - if(_status.connectMode) game.broadcastAll(()=>{_status.noclearcountdown=true}); - if(choices.length==1) result={control:choices[0]}; - else result=yield player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('prompt',get.prompt('dcxunjie')).set('ai',()=>{ - return get.event('choice'); - }).set('choice',(()=>{ - const getValue=(index,target)=>{ - let att=get.attitude(player,target); - att=Math.sign(att)*Math.sqrt(Math.abs(att)); - let delt=target.getHp(true)-target.countCards('h'); - if(index==1&&delt<0) delt=0; - return (1-3*index)*att*delt; - } - const list=game.filterPlayer().map(current=>{ - const val0=getValue(0,current),val1=getValue(1,current); - return [val0,val1,Math.max(val0,val1)]; - }).sort((a,b)=>{ - return b[2]-a[2]; + if (_status.connectMode) + game.broadcastAll(() => { + _status.noclearcountdown = true; }); - const toChoose=list[0]; - if(toChoose[2]<=0) return 'cancel2'; - return toChoose[0]>toChoose[1]?0:1; - })()); - if(result.control=='cancel2'){ - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} + if (choices.length == 1) result = { control: choices[0] }; + else + result = yield player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("dcxunjie")) + .set("ai", () => { + return get.event("choice"); + }) + .set( + "choice", + (() => { + const getValue = (index, target) => { + let att = get.attitude(player, target); + att = Math.sign(att) * Math.sqrt(Math.abs(att)); + let delt = target.getHp(true) - target.countCards("h"); + if (index == 1 && delt < 0) delt = 0; + return (1 - 3 * index) * att * delt; + }; + const list = game + .filterPlayer() + .map((current) => { + const val0 = getValue(0, current), + val1 = getValue(1, current); + return [val0, val1, Math.max(val0, val1)]; + }) + .sort((a, b) => { + return b[2] - a[2]; + }); + const toChoose = list[0]; + if (toChoose[2] <= 0) return "cancel2"; + return toChoose[0] > toChoose[1] ? 0 : 1; + })() + ); + if (result.control == "cancel2") { + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } return event.finish(); } - let prompt=''; - const choice=result.control,index=choice=='选项一'?0:1; - if(choices.length==1){ - prompt=`###${get.prompt('dcxunjie')}###
              ${choiceList[index]}
              `; + let prompt = ""; + const choice = result.control, + index = choice == "选项一" ? 0 : 1; + if (choices.length == 1) { + prompt = `###${get.prompt("dcxunjie")}###
              ${ + choiceList[index] + }
              `; + } else + prompt = `###殉节:请选择一名角色###
              ${choiceList[ + index + ].replace("一名", "该")}
              `; + result = yield player + .chooseTarget(prompt) + .set("ai", (target) => { + const player = get.player(), + index = get.event("index"); + let att = get.attitude(player, target); + att = Math.sign(att) * Math.sqrt(Math.abs(att)); + let delt = target.getHp(true) - target.countCards("h"); + if (index == 1 && delt < 0) delt = 0; + return (1 - 2 * index) * att * delt; + }) + .set("index", index); + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - else prompt=`###殉节:请选择一名角色###
              ${choiceList[index].replace('一名','该')}
              `; - result=yield player.chooseTarget(prompt).set('ai',target=>{ - const player=get.player(),index=get.event('index'); - let att=get.attitude(player,target); - att=Math.sign(att)*Math.sqrt(Math.abs(att)); - let delt=target.getHp(true)-target.countCards('h'); - if(index==1&&delt<0) delt=0; - return (1-2*index)*att*delt; - }).set('index',index); - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} - if(!result.bool) return event.finish(); - const target=result.targets[0]; - player.logSkill('dcxunjie',target); - player.tempBanSkill(`dcxunjie_${index==0?'handcard':'hp'}`,'roundStart',false); - const delt=(target.getHp(true)-target.countCards('h'))*(1-2*index); - if(delt==0) event.finish(); - else if(index==0) target[delt>0?'draw':'chooseToDiscard'](Math.abs(delt),true); - else target[delt>0?'recover':'loseHp'](Math.abs(delt)); - } + if (!result.bool) return event.finish(); + const target = result.targets[0]; + player.logSkill("dcxunjie", target); + player.tempBanSkill(`dcxunjie_${index == 0 ? "handcard" : "hp"}`, "roundStart", false); + const delt = (target.getHp(true) - target.countCards("h")) * (1 - 2 * index); + if (delt == 0) event.finish(); + else if (index == 0) target[delt > 0 ? "draw" : "chooseToDiscard"](Math.abs(delt), true); + else target[delt > 0 ? "recover" : "loseHp"](Math.abs(delt)); + }, }, //乐蔡邕 - dcjiaowei:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame' + dcjiaowei: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - group:'dcjiaowei_prevent', - content:function*(event,map){ - const player=map.player; - var cards=player.getCards('h'); - player.addGaintag(cards,'dcjiaowei_tag'); + group: "dcjiaowei_prevent", + content: function* (event, map) { + const player = map.player; + var cards = player.getCards("h"); + player.addGaintag(cards, "dcjiaowei_tag"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcjiaowei_tag')) return true; + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcjiaowei_tag")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcjiaowei_tag')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcjiaowei_tag")) return false; }, }, - subSkill:{ - prevent:{ - audio:'dcjiaowei', - trigger:{ - player:'damageBegin4', + subSkill: { + prevent: { + audio: "dcjiaowei", + trigger: { + player: "damageBegin4", }, - forced:true, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - return event.source.countCards('h')<=player.countCards('h',card=>card.hasGaintag('dcjiaowei_tag')); + forced: true, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + return ( + event.source.countCards("h") <= + player.countCards("h", (card) => card.hasGaintag("dcjiaowei_tag")) + ); }, - content:function*(event,map){ + content: function* (event, map) { map.trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - const num=target.countCards('h',card=>card.hasGaintag('dcjiaowei_tag')); - let cards=[]; - if(card.cards) cards.addArray(card.cards); - if(ui.selected.cards) cards.addArray(ui.selected.cards); - cards=cards.filter(card=>{ - if(get.itemtype(card)!='card') return false; - return get.owner(card)==player&&get.position(card)=='e'; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + const num = target.countCards("h", (card) => + card.hasGaintag("dcjiaowei_tag") + ); + let cards = []; + if (card.cards) cards.addArray(card.cards); + if (ui.selected.cards) cards.addArray(ui.selected.cards); + cards = cards.filter((card) => { + if (get.itemtype(card) != "card") return false; + return get.owner(card) == player && get.position(card) == "e"; }); - if(player.countCards('h')-cards.length<=num) return 'zeroplayertarget'; + if (player.countCards("h") - cards.length <= num) + return "zeroplayertarget"; } }, }, @@ -1971,7084 +2581,8768 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - dcfeibai:{ - audio:2, - trigger:{player:'useCardAfter'}, - usable:1, - locked:false, - filter:function(event,player){ - return player.getHistory('useCard').indexOf(event)>0; + dcfeibai: { + audio: 2, + trigger: { player: "useCardAfter" }, + usable: 1, + locked: false, + filter: function (event, player) { + return player.getHistory("useCard").indexOf(event) > 0; }, - prompt2:function(event,player){ - const history=player.getHistory('useCard'); - const ind=history.indexOf(event)-1,evt=history[ind]; - const len=get.cardNameLength(event.card)+get.cardNameLength(evt.card); + prompt2: function (event, player) { + const history = player.getHistory("useCard"); + const ind = history.indexOf(event) - 1, + evt = history[ind]; + const len = get.cardNameLength(event.card) + get.cardNameLength(evt.card); return `随机获得一张字数为${len}的牌`; }, - check:function(event,player){ - const history=player.getHistory('useCard'); - const ind=history.indexOf(event)-1,evt=history[ind]; - const len=get.cardNameLength(event.card)+get.cardNameLength(evt.card); - return player.countCards('h',card=>card.hasGaintag('dcjiaowei_tag'))<=len||get.cardPile(card=>{ - return get.cardNameLength(card,false)==len; - }); + check: function (event, player) { + const history = player.getHistory("useCard"); + const ind = history.indexOf(event) - 1, + evt = history[ind]; + const len = get.cardNameLength(event.card) + get.cardNameLength(evt.card); + return ( + player.countCards("h", (card) => card.hasGaintag("dcjiaowei_tag")) <= len || + get.cardPile((card) => { + return get.cardNameLength(card, false) == len; + }) + ); }, - content:function*(event,map){ - const player=map.player,trigger=map.trigger; - const history=player.getHistory('useCard'); - const ind=history.indexOf(trigger)-1,evt=history[ind]; - const len=get.cardNameLength(trigger.card)+get.cardNameLength(evt.card); - const card=get.cardPile(card=>{ - return get.cardNameLength(card,false)==len; + content: function* (event, map) { + const player = map.player, + trigger = map.trigger; + const history = player.getHistory("useCard"); + const ind = history.indexOf(trigger) - 1, + evt = history[ind]; + const len = get.cardNameLength(trigger.card) + get.cardNameLength(evt.card); + const card = get.cardPile((card) => { + return get.cardNameLength(card, false) == len; }); - if(card){ - yield player.gain(card,'gain2'); - } - else{ - let str=`没有${len}字的牌…`; - if(len==5&&Math.random()<=0.2) str='五字不行哇'; + if (card) { + yield player.gain(card, "gain2"); + } else { + let str = `没有${len}字的牌…`; + if (len == 5 && Math.random() <= 0.2) str = "五字不行哇"; player.chat(str); game.log(`但是找不到字数为${len}的牌!`); } - if(player.countCards('h',card=>card.hasGaintag('dcjiaowei_tag'))<=len){ + if (player.countCards("h", (card) => card.hasGaintag("dcjiaowei_tag")) <= len) { player.storage.counttrigger.dcfeibai--; - game.log(player,'重置了','#【飞白】'); + game.log(player, "重置了", "#【飞白】"); } }, - mod:{ - aiOrder:function(player,card,num){ - const evt=player.getLastUsed(); - if(!evt) return; - const len=get.cardNameLength(card)+get.cardNameLength(evt.card); - const cardx=get.cardPile(card=>{ - return get.cardNameLength(card,false)==len; + mod: { + aiOrder: function (player, card, num) { + const evt = player.getLastUsed(); + if (!evt) return; + const len = get.cardNameLength(card) + get.cardNameLength(evt.card); + const cardx = get.cardPile((card) => { + return get.cardNameLength(card, false) == len; }); - if(cardx) return num+8+(len==2||len==4?2:0); + if (cardx) return num + 8 + (len == 2 || len == 4 ? 2 : 0); }, - } + }, }, //庞山民 - dccaisi:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return get.type(event.card)=='basic'&&_status.currentPhase; + dccaisi: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return get.type(event.card) == "basic" && _status.currentPhase; }, - prompt2:function(event,player){ - const num=player.countMark('dccaisi_more')+1; - return `从${player==_status.currentPhase?'牌堆':'弃牌'}堆中随机获得${get.cnNumber(num)}张非基本牌`; + prompt2: function (event, player) { + const num = player.countMark("dccaisi_more") + 1; + return `从${player == _status.currentPhase ? "牌堆" : "弃牌"}堆中随机获得${get.cnNumber( + num + )}张非基本牌`; }, - content:function*(event,map){ - const player=map.player,trigger=map.trigger; - const position=player==_status.currentPhase?'cardPile':'discardPile'; - let cards=[],num=player.countMark('dccaisi_more')+1; - while(num>0){ + content: function* (event, map) { + const player = map.player, + trigger = map.trigger; + const position = player == _status.currentPhase ? "cardPile" : "discardPile"; + let cards = [], + num = player.countMark("dccaisi_more") + 1; + while (num > 0) { num--; - let card=get[position](card=>get.type(card)!='basic'&&!cards.includes(card)); - if(card) cards.add(card); + let card = get[position]( + (card) => get.type(card) != "basic" && !cards.includes(card) + ); + if (card) cards.add(card); else break; } - if(cards.length) yield player.gain(cards,'gain2'); - else{ - player.chat('没有非基本牌…'); - game.log(`但是${position=='discardPile'?'弃':''}牌堆里没有非基本牌!`); + if (cards.length) yield player.gain(cards, "gain2"); + else { + player.chat("没有非基本牌…"); + game.log(`但是${position == "discardPile" ? "弃" : ""}牌堆里没有非基本牌!`); } - const sum=player.getHistory('useSkill',evt=>evt.skill=='dccaisi').length; - if(sum evt.skill == "dccaisi").length; + if (sum < player.maxHp) { + player.addTempSkill("dccaisi_more"); + player.addMark("dccaisi_more", 1, false); + } else player.tempBanSkill("dccaisi"); }, - subSkill:{more:{charlotte:true,onremove:true}}, + subSkill: { more: { charlotte: true, onremove: true } }, }, - dczhuoli:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player.getHistory('useCard').length>player.getHp()||player.getHistory('gain').reduce((sum,evt)=>sum+evt.cards.length,0)>player.getHp(); + dczhuoli: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return ( + player.getHistory("useCard").length > player.getHp() || + player.getHistory("gain").reduce((sum, evt) => sum + evt.cards.length, 0) > + player.getHp() + ); }, - content:function*(event,map){ - const player=map.player; - if(player.maxHp0; + dcbeini: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: function (card, player) { + const delt = player.countCards("h") - player.maxHp; + return delt > 0; }, - selectCard:function(){ - const player=get.player(); - const delt=player.countCards('h')-player.maxHp; - return delt>0?delt:-1; + selectCard: function () { + const player = get.player(); + const delt = player.countCards("h") - player.maxHp; + return delt > 0 ? delt : -1; }, - promptfunc:()=>{ - const player=get.player(); - const delt=player.countCards('h')-player.maxHp; - let str=''; - if(delt>0) str+=`弃置${get.cnNumber(delt)}张牌`; - else if(delt==0) str+=`点击“确定”`; - else str+=`摸${get.cnNumber(-delt)}张牌`; + promptfunc: () => { + const player = get.player(); + const delt = player.countCards("h") - player.maxHp; + let str = ""; + if (delt > 0) str += `弃置${get.cnNumber(delt)}张牌`; + else if (delt == 0) str += `点击“确定”`; + else str += `摸${get.cnNumber(-delt)}张牌`; return `${str},然后选择两名角色,前者视为对后者使用一张【杀】,且这两者的非锁定技失效。`; }, - content:function*(event,map){ - var player=map.player; - if(player.countCards('h'){ - var sha=new lib.element.VCard({name:'sha',isCard:true}); - if(ui.selected.targets.length){ - var targetx=ui.selected.targets[0]; - return targetx.canUse(sha,target,false); - } - return lib.filter.cardEnabled(sha,target); - }).set('targetprompt',['打人','被打']).set('multitarget',true).set('ai',target=>{ - var aiTargets=get.event('aiTargets'); - if(aiTargets){ - return aiTargets[ui.selected.targets.length]==target?10:0; - } - return 0; - }).set('aiTargets',(()=>{ - var targets=[],eff=0; - var sha=new lib.element.VCard({name:'sha',isCard:true}); - for(var user of game.filterPlayer()){ - for(var target of game.filterPlayer()){ - if(user==target) continue; - var targetsx=[user,target]; - targetsx.forEach(i=>i.addSkill('dcbeini_fengyin2')); - var effx=get.effect(target,sha,user,player); - targetsx.forEach(i=>i.removeSkill('dcbeini_fengyin2')); - if(user==player) effx+=1; - if(get.attitude(player,user)>0) effx-=0.1; - if(effx>eff){ - eff=effx; - targets=targetsx; + var result = yield player + .chooseTarget( + "悖逆:请选择两名角色", + "前者视为对后者使用一张【杀】,且这两名角色的非锁定技失效直到回合结束。", + true, + 2, + (card, player, target) => { + var sha = new lib.element.VCard({ name: "sha", isCard: true }); + if (ui.selected.targets.length) { + var targetx = ui.selected.targets[0]; + return targetx.canUse(sha, target, false); } + return lib.filter.cardEnabled(sha, target); } - } - if(targets.length) return targets; - return null; - })()); - if(result.bool){ - var user=result.targets[0],target=result.targets[1]; - result.targets.forEach(i=>i.addTempSkill('dcbeini_fengyin')); - var sha=new lib.element.VCard({name:'sha',isCard:true}); - if(user.canUse(sha,target,false)) user.useCard(sha,target,false,'noai'); + ) + .set("targetprompt", ["打人", "被打"]) + .set("multitarget", true) + .set("ai", (target) => { + var aiTargets = get.event("aiTargets"); + if (aiTargets) { + return aiTargets[ui.selected.targets.length] == target ? 10 : 0; + } + return 0; + }) + .set( + "aiTargets", + (() => { + var targets = [], + eff = 0; + var sha = new lib.element.VCard({ name: "sha", isCard: true }); + for (var user of game.filterPlayer()) { + for (var target of game.filterPlayer()) { + if (user == target) continue; + var targetsx = [user, target]; + targetsx.forEach((i) => i.addSkill("dcbeini_fengyin2")); + var effx = get.effect(target, sha, user, player); + targetsx.forEach((i) => i.removeSkill("dcbeini_fengyin2")); + if (user == player) effx += 1; + if (get.attitude(player, user) > 0) effx -= 0.1; + if (effx > eff) { + eff = effx; + targets = targetsx; + } + } + } + if (targets.length) return targets; + return null; + })() + ); + if (result.bool) { + var user = result.targets[0], + target = result.targets[1]; + result.targets.forEach((i) => i.addTempSkill("dcbeini_fengyin")); + var sha = new lib.element.VCard({ name: "sha", isCard: true }); + if (user.canUse(sha, target, false)) user.useCard(sha, target, false, "noai"); } }, - ai:{ - order:0.1, - result:{ - player:function(player){ - if(player.countCards('h')-player.maxHp>=3) return 1; - return game.hasPlayer(current=>get.attitude(player,current)<=0)?1:0; - } + ai: { + order: 0.1, + result: { + player: function (player) { + if (player.countCards("h") - player.maxHp >= 3) return 1; + return game.hasPlayer((current) => get.attitude(player, current) <= 0) ? 1 : 0; + }, }, }, - subSkill:{ - fengyin:{ - inherit:'fengyin', + subSkill: { + fengyin: { + inherit: "fengyin", }, - fengyin2:{ - inherit:'fengyin', + fengyin2: { + inherit: "fengyin", }, - } + }, }, - dcshizong:{ - audio:2, - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(get.type(name)!='basic') return false; - return player.countCards('he')>=player.countMark('dcshizong')+1; + dcshizong: { + audio: 2, + enable: "chooseToUse", + hiddenCard: function (player, name) { + if (get.type(name) != "basic") return false; + return player.countCards("he") >= player.countMark("dcshizong") + 1; }, - filter:function(event,player){ - if(event.type=='wuxie'||event.dcshizong) return false; - if(player.countCards('he'){ - if(info[0]!='basic') return; - const card={name:info[2],nature:info[3],isCard:true}; - return event.filterCard(card,player,event); - }) - return ui.create.dialog('恃纵',[vcards,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + const vcards = get.inpileVCardList((info) => { + if (info[0] != "basic") return; + const card = { name: info[2], nature: info[3], isCard: true }; + return event.filterCard(card, player, event); + }); + return ui.create.dialog("恃纵", [vcards, "vcard"], "hidden"); }, - check:function(button){ - if(get.event().getParent().type!='phase') return 1; - const player=get.player(); - const card={name:button.link[2],nature:button.link[3]}; - if(game.hasPlayer(current=>{ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch(button.link[2]){ - case 'tao':return 5; - case 'jiu':return 3.01; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder') return 2.92; + check: function (button) { + if (get.event().getParent().type != "phase") return 1; + const player = get.player(); + const card = { name: button.link[2], nature: button.link[3] }; + if ( + game.hasPlayer((current) => { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + return 5; + case "jiu": + return 3.01; + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder") return 2.92; else return 2.9; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:true, - filterTarget:lib.filter.notMe, - selectTarget:1, - selectCard:()=>get.player().countMark('dcshizong')+1, - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + filterCard: true, + filterTarget: lib.filter.notMe, + selectTarget: 1, + selectCard: () => get.player().countMark("dcshizong") + 1, + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }, - position:'he', - popname:true, - ignoreMod:true, - ai1:function(card){ - return 1/(1.1+Math.max(-1,get.value(card))); + position: "he", + popname: true, + ignoreMod: true, + ai1: function (card) { + return 1 / (1.1 + Math.max(-1, get.value(card))); }, - ai2:function(target){ - return get.attitude(get.player(),target); + ai2: function (target) { + return get.attitude(get.player(), target); }, - precontent:function*(event,map){ - var player=map.player,target=event.result.targets[0]; - player.logSkill('dcshizong',target); - if(!player.countMark('dcshizong')) player.when({global:'phaseAfter'}).then(()=>delete player.storage.dcshizong); - player.addMark('dcshizong',1,false); - yield player.give(event.result.cards.slice(),target); - var viewAs=new lib.element.VCard({name:event.result.card.name,nature:event.result.card.nature,isCard:true}); - var result=yield target.chooseCard('恃纵:是否将一张牌置于牌堆底?',`若如此做,${get.translation(player)}视为使用一张${get.translation(viewAs.nature)}【${get.translation(viewAs.name)}】`,'he').set('ai',card=>{ - if(get.event('goon')) return 7-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)*(player.getUseValue(viewAs)||1)>=1); - var card=event.result.cards[0]; - if(result.bool){ - var card=result.cards[0]; + precontent: function* (event, map) { + var player = map.player, + target = event.result.targets[0]; + player.logSkill("dcshizong", target); + if (!player.countMark("dcshizong")) + player + .when({ global: "phaseAfter" }) + .then(() => delete player.storage.dcshizong); + player.addMark("dcshizong", 1, false); + yield player.give(event.result.cards.slice(), target); + var viewAs = new lib.element.VCard({ + name: event.result.card.name, + nature: event.result.card.nature, + isCard: true, + }); + var result = yield target + .chooseCard( + "恃纵:是否将一张牌置于牌堆底?", + `若如此做,${get.translation(player)}视为使用一张${get.translation( + viewAs.nature + )}【${get.translation(viewAs.name)}】`, + "he" + ) + .set("ai", (card) => { + if (get.event("goon")) return 7 - get.value(card); + return 0; + }) + .set( + "goon", + get.attitude(target, player) * (player.getUseValue(viewAs) || 1) >= 1 + ); + var card = event.result.cards[0]; + if (result.bool) { + var card = result.cards[0]; game.delayex(); - var next=target.loseToDiscardpile(card,ui.cardPile); - next.log=false; - if(get.position(card)=='e'){ - game.log(target,'将',card,'置于了牌堆底'); + var next = target.loseToDiscardpile(card, ui.cardPile); + next.log = false; + if (get.position(card) == "e") { + game.log(target, "将", card, "置于了牌堆底"); + } else { + next.blank = true; + game.log(target, "将一张牌置于了牌堆底"); } - else{ - next.blank=true; - game.log(target,'将一张牌置于了牌堆底'); - } - result=yield next; - game.broadcastAll(viewAs=>{ - lib.skill.dcshizong_backup2.viewAs=viewAs; - },lib.skill.dcshizong_backup.viewAs); - var evt=event.getParent(); - evt.set('_backupevent','dcshizong_backup2'); - evt.set('openskilldialog',`请选择${get.translation(viewAs.nature)}${get.translation(viewAs.name)}的目标`); - evt.backup('dcshizong_backup2'); - evt.set('norestore',true); - evt.set('custom',{ - add:{}, - replace:{window:function(){}} + result = yield next; + game.broadcastAll((viewAs) => { + lib.skill.dcshizong_backup2.viewAs = viewAs; + }, lib.skill.dcshizong_backup.viewAs); + var evt = event.getParent(); + evt.set("_backupevent", "dcshizong_backup2"); + evt.set( + "openskilldialog", + `请选择${get.translation(viewAs.nature)}${get.translation( + viewAs.name + )}的目标` + ); + evt.backup("dcshizong_backup2"); + evt.set("norestore", true); + evt.set("custom", { + add: {}, + replace: { window: function () {} }, }); evt.goto(0); - if(target!=_status.currentPhase) player.tempBanSkill('dcshizong'); - } - else{ - target.chat('不放!'); - game.log(target,'选择不将牌置于牌堆底'); - var evt=event.getParent(); - evt.set('dcshizong',true); + if (target != _status.currentPhase) player.tempBanSkill("dcshizong"); + } else { + target.chat("不放!"); + game.log(target, "选择不将牌置于牌堆底"); + var evt = event.getParent(); + evt.set("dcshizong", true); evt.goto(0); } game.delayx(); }, - ai:{ - order:10, + ai: { + order: 10, }, - } + }; + }, + prompt: function (links, player) { + return `###恃纵:选择要交出的牌和目标角色###将${get.cnNumber( + player.countMark("dcshizong") + 1 + )}张牌交给一名其他角色,其可以选择将一张牌置于牌堆底,视为你使用一张${get.translation( + links[0][3] || "" + )}${get.translation(links[0][2])}。`; }, - prompt:function(links,player){ - return `###恃纵:选择要交出的牌和目标角色###将${get.cnNumber(player.countMark('dcshizong')+1)}张牌交给一名其他角色,其可以选择将一张牌置于牌堆底,视为你使用一张${get.translation(links[0][3]||'')}${get.translation(links[0][2])}。`; - } }, - ai:{ - order:function(){ - const player=get.player(),event=get.event(); - if(event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0){ - return get.order({name:'jiu'})+0.1; + ai: { + order: function () { + const player = get.player(), + event = get.event(); + if ( + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 + ) { + return get.order({ name: "jiu" }) + 0.1; } - return get.order({name:'sha'})+0.1; + return get.order({ name: "sha" }) + 0.1; }, - respondSha:true, - fireAttack:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='fireAttack') return true; - if(player.countCards('he')false, - selectCard:-1, - precontent:function(){ + subSkill: { + backup: {}, + backup2: { + filterCard: () => false, + selectCard: -1, + precontent: function () { delete event.result.skill; - } + }, }, }, }, //张曼成 - dclvecheng:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - 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'); + dclvecheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + 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:3.1, - order:3.5, - expose:0.2, - result:{ - target:function(player,target){ - if(player.getStorage('dclvecheng_xiongluan').includes(target)) return 0; - if(target.hasSkillTag('freeShan',false,{ - player:player - },true)) return -0.6; - var hs=player.countCards('h',card=>{ - if(!player.canUse(card,target)) return false; - return get.name(card)=='sha'&&get.effect(target,card,player,player)>0; + ai: { + threaten: 3.1, + order: 3.5, + expose: 0.2, + result: { + target: function (player, target) { + if (player.getStorage("dclvecheng_xiongluan").includes(target)) return 0; + if ( + target.hasSkillTag( + "freeShan", + false, + { + player: player, + }, + true + ) + ) + return -0.6; + var hs = player.countCards("h", (card) => { + if (!player.canUse(card, target)) return false; + return ( + get.name(card) == "sha" && get.effect(target, card, player, player) > 0 + ); }); - var ts=target.hp; - if(hs>=ts&&ts>1) return -2; + var ts = target.hp; + if (hs >= ts && ts > 1) return -2; return -1; - } - } + }, + }, }, - subSkill:{ - xiongluan:{ - trigger:{player:'phaseEnd'}, - charlotte:true, - forced:true, - popup:false, - onremove:function(player,skill){ - player.removeGaintag('dclvecheng_xiongluan'); + subSkill: { + xiongluan: { + trigger: { player: "phaseEnd" }, + charlotte: true, + forced: true, + popup: false, + 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()); + filter: function (event, player) { + return player.getStorage("dclvecheng_xiongluan").some((i) => i.isIn()); }, - content:function(){ - 'step 0' - event.targets=player.getStorage('dclvecheng_xiongluan').slice(); + content: function () { + "step 0"; + event.targets = player.getStorage("dclvecheng_xiongluan").slice(); event.targets.sortBySeat(); - 'step 1' - if(!event.targets.length){ + "step 1"; + if (!event.targets.length) { event.finish(); return; } - var target=event.targets.shift(); - event.target=target; + var target = event.targets.shift(); + event.target = target; target.showHandcards(); - var cards=target.getCards('h','sha'); - if(!cards.length) event.redo(); - else event.forced=false; - 'step 2' - var forced=event.forced; - var prompt2=forced?'掠城:选择对'+get.translation(player)+'使用的【杀】':'掠城:是否依次对'+get.translation(player)+'使用所有的【杀】?'; - target.chooseToUse(forced,function(card,player,event){ - if(get.itemtype(card)!='card'||get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },prompt2).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',player); - 'step 3' - if(result.bool){ - if(target.countCards('h','sha')){ - event.forced=true; + var cards = target.getCards("h", "sha"); + if (!cards.length) event.redo(); + else event.forced = false; + "step 2"; + var forced = event.forced; + var prompt2 = forced + ? "掠城:选择对" + get.translation(player) + "使用的【杀】" + : "掠城:是否依次对" + get.translation(player) + "使用所有的【杀】?"; + target + .chooseToUse( + forced, + function (card, player, event) { + if (get.itemtype(card) != "card" || get.name(card) != "sha") + return false; + return lib.filter.filterCard.apply(this, arguments); + }, + prompt2 + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", player); + "step 3"; + if (result.bool) { + if (target.countCards("h", "sha")) { + event.forced = true; event.goto(2); return; } } - event.forced=false; + event.forced = false; event.goto(1); }, - intro:{ - content:'对$使用“掠城”【杀】无任何次数限制', + intro: { + content: "对$使用“掠城”【杀】无任何次数限制", }, - mod:{ - cardUsableTarget:function(card,player,target){ - if(!card.cards||card.cards.length!=1) return; - if(card.name=='sha'&&card.cards[0].hasGaintag('dclvecheng_xiongluan')&&player.getStorage('dclvecheng_xiongluan').includes(target)) return true; + mod: { + cardUsableTarget: function (card, player, target) { + if (!card.cards || card.cards.length != 1) return; + if ( + card.name == "sha" && + card.cards[0].hasGaintag("dclvecheng_xiongluan") && + player.getStorage("dclvecheng_xiongluan").includes(target) + ) + return true; }, - } - } - } - }, - dczhongji:{ - 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.includes(suit)||!player.countCards('h',{suit:suit}); + }, + }, }, - check:function(event,player){ - var num=Math.min(20,player.maxHp-player.countCards('h')); - if(num<=0) return false; - var numx=player.getHistory('useSkill',evt=>{ - return evt.skill=='dczhongji'; - }).length+1; - if(numx>num) return false; - if(_status.currentPhase!=player) return true; - if(player.hasCard(card=>{ - var suit=get.suit(card); - return player.hasValueTarget(card)&&!player.hasCard(cardx=>{ - return cardx!=card&&get.suit(cardx)==suit; - }); - })) return false; + }, + dczhongji: { + 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.includes(suit) || !player.countCards("h", { suit: suit }); + }, + check: function (event, player) { + var num = Math.min(20, player.maxHp - player.countCards("h")); + if (num <= 0) return false; + var numx = + player.getHistory("useSkill", (evt) => { + return evt.skill == "dczhongji"; + }).length + 1; + if (numx > num) return false; + if (_status.currentPhase != player) return true; + if ( + player.hasCard((card) => { + var suit = get.suit(card); + return ( + player.hasValueTarget(card) && + !player.hasCard((cardx) => { + return cardx != card && get.suit(cardx) == suit; + }) + ); + }) + ) + return false; return true; }, - prompt2:function(event,player){ - var num=Math.min(20,player.maxHp-player.countCards('h')); - var str=num>0?'摸'+get.cnNumber(num)+'张牌,然后':''; - return str+'弃置'+get.cnNumber(1+player.getHistory('useSkill',evt=>{ - return evt.skill=='dczhongji'; - }).length)+'张牌'; + prompt2: function (event, player) { + var num = Math.min(20, player.maxHp - player.countCards("h")); + var str = num > 0 ? "摸" + get.cnNumber(num) + "张牌,然后" : ""; + return ( + str + + "弃置" + + get.cnNumber( + 1 + + player.getHistory("useSkill", (evt) => { + return evt.skill == "dczhongji"; + }).length + ) + + "张牌" + ); }, - content:function(){ - 'step 0' - var num=Math.min(20,player.maxHp-player.countCards('h')); - if(num>0) player.draw(num); - 'step 1' - var num=player.getHistory('useSkill',evt=>{ - return evt.skill=='dczhongji'; + content: function () { + "step 0"; + var num = Math.min(20, player.maxHp - player.countCards("h")); + if (num > 0) player.draw(num); + "step 1"; + var num = player.getHistory("useSkill", (evt) => { + return evt.skill == "dczhongji"; }).length; - player.chooseToDiscard('螽集:请弃置'+get.cnNumber(num)+'张牌','he',true,num).set('ai',get.unuseful); + player + .chooseToDiscard("螽集:请弃置" + get.cnNumber(num) + "张牌", "he", true, num) + .set("ai", get.unuseful); + }, + ai: { + threaten: 3.2, }, - ai:{ - threaten:3.2, - } }, //乐周妃 - dclingkong:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame' + dclingkong: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var cards=player.getCards('h'); - player.addGaintag(cards,'dclingkong_tag'); + content: function () { + "step 0"; + var cards = player.getCards("h"); + player.addGaintag(cards, "dclingkong_tag"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dclingkong_tag')){ + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dclingkong_tag")) { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dclingkong_tag')){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dclingkong_tag")) { return false; } }, }, - group:'dclingkong_marker', - subSkill:{ - marker:{ - audio:'dclingkong', - trigger:{player:['gainAfter','loseAsyncAfter']}, - forced:true, - filter:(event,player)=>{ - if(event.getParent('phaseDraw',true)) return false; - const evt=player.getHistory('gain',i=>!i.getParent('phaseDraw',true))[0]; - if(!evt) return false; - if(event.name=='gain'){ - if(evt!=event||event.getlx===false) return false; - } - else if(evt.getParent()!=event) return false; - const hs=player.getCards('h'); - if(!hs.length) return false; - const cards=event.getg(player); - return cards.some(card=>hs.includes(card)); + group: "dclingkong_marker", + subSkill: { + marker: { + audio: "dclingkong", + trigger: { player: ["gainAfter", "loseAsyncAfter"] }, + forced: true, + filter: (event, player) => { + if (event.getParent("phaseDraw", true)) return false; + const evt = player.getHistory("gain", (i) => !i.getParent("phaseDraw", true))[0]; + if (!evt) return false; + if (event.name == "gain") { + if (evt != event || event.getlx === false) return false; + } else if (evt.getParent() != event) return false; + const hs = player.getCards("h"); + if (!hs.length) return false; + const cards = event.getg(player); + return cards.some((card) => hs.includes(card)); }, - content:function(){ - var hs=player.getCards('h'),cards=trigger.getg(player); - cards=cards.filter(card=>hs.includes(card)); - player.addGaintag(cards,'dclingkong_tag'); + content: function () { + var hs = player.getCards("h"), + cards = trigger.getg(player); + cards = cards.filter((card) => hs.includes(card)); + player.addGaintag(cards, "dclingkong_tag"); game.delayx(); }, }, }, }, - dcxianshu:{ - audio:2, - enable:'phaseUse', - filter:(event,player)=>{ - return game.hasPlayer(current=>current!=player)&&player.hasCard(card=>card.hasGaintag('dclingkong_tag'),'h'); + dcxianshu: { + audio: 2, + enable: "phaseUse", + filter: (event, player) => { + return ( + game.hasPlayer((current) => current != player) && + player.hasCard((card) => card.hasGaintag("dclingkong_tag"), "h") + ); }, - filterCard:(card)=>card.hasGaintag('dclingkong_tag'), - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - position:'h', - check:card=>{ - const player=_status.event.player,event=_status.event,color=get.color(card); - if(color=='red'){ - return (event.getTempCache('dcxianshu','red') - ||event.putTempCache('dcxianshu','red',game.hasPlayer(current=>{ - return current!=player&¤t.hp<=player.hp&¤t.isDamaged()&&get.recoverEffect(current,player,player)>0; - }).toString()))=='true'?(7-get.value(card)):0; + filterCard: (card) => card.hasGaintag("dclingkong_tag"), + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + position: "h", + check: (card) => { + const player = _status.event.player, + event = _status.event, + color = get.color(card); + if (color == "red") { + return (event.getTempCache("dcxianshu", "red") || + event.putTempCache( + "dcxianshu", + "red", + game + .hasPlayer((current) => { + return ( + current != player && + current.hp <= player.hp && + current.isDamaged() && + get.recoverEffect(current, player, player) > 0 + ); + }) + .toString() + )) == "true" + ? 7 - get.value(card) + : 0; + } else if (color == "black") { + return (event.getTempCache("dcxianshu", "black") || + event.putTempCache( + "dcxianshu", + "black", + game + .hasPlayer((current) => { + return ( + current != player && + current.hp >= player.hp && + get.effect(current, { name: "losehp" }, player, player) > 0 + ); + }) + .toString() + )) == "true" + ? 7 - get.value(card) + : 0; } - else if(color=='black'){ - return (event.getTempCache('dcxianshu','black') - ||event.putTempCache('dcxianshu','black',game.hasPlayer(current=>{ - return current!=player&¤t.hp>=player.hp&&get.effect(current,{name:'losehp'},player,player)>0; - }).toString()))=='true'?(7-get.value(card)):0; - } - return 6-get.value(card); + return 6 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target,true); - event.color=get.color(cards[0],player); - 'step 1' - if(target.isIn()){ - var num=Math.min(Math.abs(target.getHp()-player.getHp()),5); - if(num>0) player.draw(num); + content: function () { + "step 0"; + player.give(cards, target, true); + event.color = get.color(cards[0], player); + "step 1"; + if (target.isIn()) { + var num = Math.min(Math.abs(target.getHp() - player.getHp()), 5); + if (num > 0) player.draw(num); } - 'step 2' - if(event.color=='red'){ - if(target.getHp()<=player.getHp()&&target.isDamaged()) target.recover(); - } - else if(event.color=='black'){ - if(target.getHp()>=player.getHp()) target.loseHp() + "step 2"; + if (event.color == "red") { + if (target.getHp() <= player.getHp() && target.isDamaged()) target.recover(); + } else if (event.color == "black") { + if (target.getHp() >= player.getHp()) target.loseHp(); } }, - ai:{ - combo:'dclingkong', - order:10, - result:{ - player:function(player,target){ - if(!ui.selected.cards.length) return 0; - let num=target.getHp()-player.getHp(); - const card=ui.selected.cards[0],color=get.color(card); - if(color=='red'&&target.getHp()<=player.getHp()&&target.isDamaged()) num++; - else if(color=='black'&&target.getHp()>=player.getHp()) num--; - return Math.min(Math.abs(num),5)*1.1; + ai: { + combo: "dclingkong", + order: 10, + result: { + player: function (player, target) { + if (!ui.selected.cards.length) return 0; + let num = target.getHp() - player.getHp(); + const card = ui.selected.cards[0], + color = get.color(card); + if (color == "red" && target.getHp() <= player.getHp() && target.isDamaged()) + num++; + else if (color == "black" && target.getHp() >= player.getHp()) num--; + return Math.min(Math.abs(num), 5) * 1.1; }, - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - const card=ui.selected.cards[0],color=get.color(card),val=get.value(card,target); - if(color=='red'&&target.getHp()<=player.getHp()&&target.isDamaged()) return get.recoverEffect(target,player,target)+val/1.4; - else if(color=='black'&&target.getHp()>=player.getHp()) return get.effect(target,{name:'losehp'},player,target)+val/1.4; - return val/1.4; + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + const card = ui.selected.cards[0], + color = get.color(card), + val = get.value(card, target); + if (color == "red" && target.getHp() <= player.getHp() && target.isDamaged()) + return get.recoverEffect(target, player, target) + val / 1.4; + else if (color == "black" && target.getHp() >= player.getHp()) + return get.effect(target, { name: "losehp" }, player, target) + val / 1.4; + return val / 1.4; }, }, }, }, //吴班 - dcyouzhan:{ - audio:2, - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcyouzhan: { + audio: 2, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - direct:true, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - return evt&&evt.cards2.length; + forced: true, + direct: true, + filter: function (event, player) { + if (player != _status.currentPhase) return false; + return game.hasPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + return evt && evt.cards2.length; }); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - if(current==player) return false; - var evt=trigger.getl(current); - return evt&&evt.cards2.length; + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => { + if (current == player) return false; + var evt = trigger.getl(current); + return evt && evt.cards2.length; }); - event.targets=targets; - player.logSkill('dcyouzhan',targets); - 'step 1' - event.target=targets.shift(); - event.num=trigger.getl(event.target).cards2.length; - 'step 2' - player.draw().gaintag=['dcyouzhan']; - player.addTempSkill('dcyouzhan_limit'); - target.addTempSkill('dcyouzhan_effect'); - target.addMark('dcyouzhan_effect',1,false); - target.addTempSkill('dcyouzhan_draw'); - if(--event.num) event.redo(); - 'step 3' - if(targets.length){ + event.targets = targets; + player.logSkill("dcyouzhan", targets); + "step 1"; + event.target = targets.shift(); + event.num = trigger.getl(event.target).cards2.length; + "step 2"; + player.draw().gaintag = ["dcyouzhan"]; + player.addTempSkill("dcyouzhan_limit"); + target.addTempSkill("dcyouzhan_effect"); + target.addMark("dcyouzhan_effect", 1, false); + target.addTempSkill("dcyouzhan_draw"); + if (--event.num) event.redo(); + "step 3"; + if (targets.length) { event.goto(1); } }, - ai:{ - damageBonus:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.target||!arg.target.hasSkill('dcyouzhan_effect')) return false; - } + ai: { + damageBonus: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.target || !arg.target.hasSkill("dcyouzhan_effect")) return false; + }, }, - subSkill:{ - effect:{ - audio:'dcyouzhan', - trigger:{ - player:'damageBegin3', + subSkill: { + effect: { + audio: "dcyouzhan", + trigger: { + player: "damageBegin3", }, - filter:function(event,player){ - return player.hasMark('dcyouzhan_effect'); + filter: function (event, player) { + return player.hasMark("dcyouzhan_effect"); }, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - 'step 0' - trigger.num+=player.countMark('dcyouzhan_effect'); - player.removeSkill('dcyouzhan_effect'); + forced: true, + charlotte: true, + onremove: true, + content: function () { + "step 0"; + trigger.num += player.countMark("dcyouzhan_effect"); + player.removeSkill("dcyouzhan_effect"); }, - mark:true, - intro:{ - content:'本回合下一次受到的伤害+#', + mark: true, + intro: { + content: "本回合下一次受到的伤害+#", }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return 1+0.5*target.countMark('dcyouzhan_effect'); - } - } - } - }, - draw:{ - trigger:{ - global:'phaseJieshuBegin', - }, - forced:true, - charlotte:true, - filter:function(event,player){ - return !player.getHistory('damage').length; - }, - content:function(){ - player.draw(Math.min(3,player.getHistory('lose').length)); - }, - }, - limit:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('dcyouzhan'); - }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcyouzhan')) return true; - }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcyouzhan')) return false; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) + return 1 + 0.5 * target.countMark("dcyouzhan_effect"); + }, }, }, - } - } + }, + draw: { + trigger: { + global: "phaseJieshuBegin", + }, + forced: true, + charlotte: true, + filter: function (event, player) { + return !player.getHistory("damage").length; + }, + content: function () { + player.draw(Math.min(3, player.getHistory("lose").length)); + }, + }, + limit: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("dcyouzhan"); + }, + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcyouzhan")) return true; + }, + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcyouzhan")) return false; + }, + }, + }, + }, }, //乐蔡文姬 - dcshuangjia:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame' + dcshuangjia: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var cards=player.getCards('h'); - player.addGaintag(cards,'dcshuangjia_tag'); + content: function () { + "step 0"; + var cards = player.getCards("h"); + player.addGaintag(cards, "dcshuangjia_tag"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcshuangjia_tag')){ + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcshuangjia_tag")) { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcshuangjia_tag')){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcshuangjia_tag")) { return false; } }, - globalTo:function(from,to,distance){ - return distance+Math.min(5,to.countCards('h',card=>card.hasGaintag('dcshuangjia_tag'))); - } + globalTo: function (from, to, distance) { + return ( + distance + + Math.min( + 5, + to.countCards("h", (card) => card.hasGaintag("dcshuangjia_tag")) + ) + ); + }, }, }, - dcbeifen:{ - audio:2, - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcbeifen: { + audio: 2, + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dcshuangjia_tag')) return true; + filter: function (event, player) { + var evt = event.getl(player); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dcshuangjia_tag")) return true; } return false; } - return player.hasHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcshuangjia_tag')) return true; + return player.hasHistory("lose", (evt) => { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcshuangjia_tag")) return true; } return false; }); }, - forced:true, - content:function(){ - var suits=lib.suit.slice(); - player.countCards('h',card=>{ - if(!card.hasGaintag('dcshuangjia_tag')) return false; + forced: true, + content: function () { + var suits = lib.suit.slice(); + player.countCards("h", (card) => { + if (!card.hasGaintag("dcshuangjia_tag")) return false; suits.remove(get.suit(card)); }); - var cards=[]; - while(suits.length){ - var suit=suits.shift(); - var card=get.cardPile(cardx=>{ - return get.suit(cardx,false)==suit; + var cards = []; + while (suits.length) { + var suit = suits.shift(); + var card = get.cardPile((cardx) => { + return get.suit(cardx, false) == suit; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length){ - player.gain(cards,'gain2'); + if (cards.length) { + player.gain(cards, "gain2"); } }, - mod:{ - cardUsable:function(card,player){ - var len=player.countCards('h'); - var cnt=player.countCards('h',card=>card.hasGaintag('dcshuangjia_tag')); - if(2*cnt card.hasGaintag("dcshuangjia_tag")); + if (2 * cnt < len) return Infinity; }, - targetInRange:function(card,player){ - var len=player.countCards('h'); - var cnt=player.countCards('h',card=>card.hasGaintag('dcshuangjia_tag')); - if(2*cnt card.hasGaintag("dcshuangjia_tag")); + if (2 * cnt < len) return true; }, - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcshuangjia_tag')){ - var suits=lib.suit.slice(); - player.countCards('h',cardx=>{ - if(!cardx.hasGaintag('dcshuangjia_tag')) return false; - if(card==cardx) return false; + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcshuangjia_tag")) { + var suits = lib.suit.slice(); + player.countCards("h", (cardx) => { + if (!cardx.hasGaintag("dcshuangjia_tag")) return false; + if (card == cardx) return false; suits.remove(get.suit(cardx)); }); - if(suits.length) return num+suits.length*2.5; + if (suits.length) return num + suits.length * 2.5; } }, }, }, //孟优 - dcmanzhi:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - filter:function(event,player){ - if(event.name=='phaseJieshu'){ - var del=0; - game.getGlobalHistory('changeHp',evt=>{ - if(evt.player!=player) return; - for(var phase of lib.phaseName){ - var evtx=evt.getParent(phase); - if(evtx&&evtx.name==phase){ - del+=evt.num; + dcmanzhi: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + filter: function (event, player) { + if (event.name == "phaseJieshu") { + var del = 0; + game.getGlobalHistory("changeHp", (evt) => { + if (evt.player != player) return; + for (var phase of lib.phaseName) { + var evtx = evt.getParent(phase); + if (evtx && evtx.name == phase) { + del += evt.num; break; } } }); - if(del!=0) return false; + if (del != 0) return false; } - return game.hasPlayer(current=>{ - if(current==player) return false; - return !player.hasSkill('dcmanzhi_1')&¤t.countCards('he')||!player.hasSkill('dcmanzhi_2')&¤t.countCards('hej'); - }) - }, - direct:true, - content:function(){ - 'step 0' - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseTarget(get.prompt2('dcmanzhi'),(card,player,target)=>{ - if(player==target) return false; - return !player.hasSkill('dcmanzhi_1')&&target.countCards('he')||!player.hasSkill('dcmanzhi_2')&&target.countCards('hej'); - }).set('ai',target=>{ - return 1-get.attitude(get.player(),target); + return game.hasPlayer((current) => { + if (current == player) return false; + return ( + (!player.hasSkill("dcmanzhi_1") && current.countCards("he")) || + (!player.hasSkill("dcmanzhi_2") && current.countCards("hej")) + ); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var choices=[]; - var choiceList=[ - '令其交给你两张牌,然后其视为使用一张无距离限制的【杀】', - '你获得其区域内的至多两张牌,然后交给其等量的牌并摸一张牌' + }, + direct: true, + content: function () { + "step 0"; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + player + .chooseTarget(get.prompt2("dcmanzhi"), (card, player, target) => { + if (player == target) return false; + return ( + (!player.hasSkill("dcmanzhi_1") && target.countCards("he")) || + (!player.hasSkill("dcmanzhi_2") && target.countCards("hej")) + ); + }) + .set("ai", (target) => { + return 1 - get.attitude(get.player(), target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var choices = []; + var choiceList = [ + "令其交给你两张牌,然后其视为使用一张无距离限制的【杀】", + "你获得其区域内的至多两张牌,然后交给其等量的牌并摸一张牌", ]; - var chosen=[player.hasSkill('dcmanzhi_1'),player.hasSkill('dcmanzhi_2')]; - if(target.countCards('he')&&(!chosen[0]||trigger.name=='phaseZhunbei')) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+(chosen[0]?'(已被选择过)':'')+''; - if(target.countCards('hej')&&(!chosen[1]||trigger.name=='phaseZhunbei')) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+(chosen[1]?'(已被选择过)':'')+''; - if(trigger.name=='phaseJieshu') choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(target.getUseValue({name:'sha'},false)>5&&!player.hasShan()&&trigger.name=='phaseZhunbei') return 1; - return 0; - }()).set('prompt','蛮智:请选择一项'); - } - else{ - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} + var chosen = [player.hasSkill("dcmanzhi_1"), player.hasSkill("dcmanzhi_2")]; + if (target.countCards("he") && (!chosen[0] || trigger.name == "phaseZhunbei")) + choices.push("选项一"); + else + choiceList[0] = + '' + + choiceList[0] + + (chosen[0] ? "(已被选择过)" : "") + + ""; + if (target.countCards("hej") && (!chosen[1] || trigger.name == "phaseZhunbei")) + choices.push("选项二"); + else + choiceList[1] = + '' + + choiceList[1] + + (chosen[1] ? "(已被选择过)" : "") + + ""; + if (trigger.name == "phaseJieshu") choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if ( + target.getUseValue({ name: "sha" }, false) > 5 && + !player.hasShan() && + trigger.name == "phaseZhunbei" + ) + return 1; + return 0; + })() + ) + .set("prompt", "蛮智:请选择一项"); + } else { + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } event.finish(); } - 'step 2' - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - if(result.control=='cancel2'){event.finish();return;} - player.logSkill('dcmanzhi',target); - if(result.control=='选项一'){ - player.addTempSkill('dcmanzhi_1'); - target.chooseCard(Math.min(2,target.countCards('he')),'he','蛮智:请交给'+get.translation(player)+'两张牌',true); + "step 2"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - else{ - player.addTempSkill('dcmanzhi_2'); - player.gainPlayerCard(target,'hej',[1,2],true); + if (result.control == "cancel2") { + event.finish(); + return; + } + player.logSkill("dcmanzhi", target); + if (result.control == "选项一") { + player.addTempSkill("dcmanzhi_1"); + target.chooseCard( + Math.min(2, target.countCards("he")), + "he", + "蛮智:请交给" + get.translation(player) + "两张牌", + true + ); + } else { + player.addTempSkill("dcmanzhi_2"); + player.gainPlayerCard(target, "hej", [1, 2], true); event.goto(5); } - 'step 3' - if(result.bool){ - target.give(result.cards,player); - } - else event.finish(); - 'step 4' - target.chooseUseTarget('sha',true,'nodistance'); + "step 3"; + if (result.bool) { + target.give(result.cards, player); + } else event.finish(); + "step 4"; + target.chooseUseTarget("sha", true, "nodistance"); event.finish(); - 'step 5' - if(result.bool&&target.isIn()){ - var num=result.cards.length,hs=player.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.lengthplayer.hasValueTarget(card),'h')){ - if(get.position(card)=='e') return 0; - return 8-get.value(card); + dczigu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + selectCard: 1, + check: function (card) { + var player = _status.event.player; + if (!player.hasSkill("dczuowei")) return 6 - get.value(card); + if ( + player.countCards("h") == player.countCards("e") + 1 && + !player.hasCard((card) => player.hasValueTarget(card), "h") + ) { + if (get.position(card) == "e") return 0; + return 8 - get.value(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - return current.countGainableCards(player,'e'); + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => { + return current.countGainableCards(player, "e"); }); - if(targets.length==0) event._result={bool:false}; - else if(targets.length==1) event._result={bool:true,targets:targets}; - else player.chooseTarget('自固:获得一名角色装备区里的一张牌',true,(card,player,target)=>{ - return target.countGainableCards(player,'e'); - }).set('ai',target=>{ - if(target==_status.event.player) return 10; - if(get.attitude(_status.event.player,target)<0){ - if(target.hasCard(card=>{ - return get.value(card,player)>=6; - })) return 12; - return 8; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.gainPlayerCard('e',target,true); + if (targets.length == 0) event._result = { bool: false }; + else if (targets.length == 1) event._result = { bool: true, targets: targets }; + else + player + .chooseTarget( + "自固:获得一名角色装备区里的一张牌", + true, + (card, player, target) => { + return target.countGainableCards(player, "e"); + } + ) + .set("ai", (target) => { + if (target == _status.event.player) return 10; + if (get.attitude(_status.event.player, target) < 0) { + if ( + target.hasCard((card) => { + return get.value(card, player) >= 6; + }) + ) + return 12; + return 8; + } + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.gainPlayerCard("e", target, true); } - 'step 2' - if(!result.bool||target==player||!result.cards||!result.cards.some(i=>get.owner(i)==player)) player.draw(); + "step 2"; + if ( + !result.bool || + target == player || + !result.cards || + !result.cards.some((i) => get.owner(i) == player) + ) + player.draw(); }, - ai:{ - order:function(item,player){ - if(!player.hasSkill('dczuowei')) return 9; - if(player.countCards('h')==player.countCards('e')+1&&!player.hasCard(card=>player.hasValueTarget(card),'h')) return 9; + ai: { + order: function (item, player) { + if (!player.hasSkill("dczuowei")) return 9; + if ( + player.countCards("h") == player.countCards("e") + 1 && + !player.hasCard((card) => player.hasValueTarget(card), "h") + ) + return 9; return 1; }, - result:{ - player:1 - } - } - }, - dczuowei:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - if(!player.hasSkill('dczuowei_ban')) return true; - return Math.sign(player.countCards('h')-Math.max(1,player.countCards('e')))>=0; + result: { + player: 1, + }, }, - direct:true, - locked:false, - content:function(){ - 'step 0' - var hs=player.countCards('h'); - var es=Math.max(1,player.countCards('e')); - var sign=Math.sign(hs-es); - event.sign=sign; - if(sign>0) player.chooseBool(get.prompt('dczuowei'),'令'+get.translation(trigger.card)+'不可被响应').set('ai',()=>1); - else if(sign==0) player.chooseTarget(get.prompt('dczuowei'),'对一名其他角色造成1点伤害',lib.filter.notMe).set('ai',target=>{ - return get.damageEffect(target,_status.event.player,_status.event.player); - }); - else player.chooseBool(get.prompt('dczuowei'),'摸两张牌,然后本回合你不能再触发该分支').set('ai',()=>1); - 'step 1' - if(!result.bool) event.finish() - else if(event.sign<=0&&!event.isMine()&&!event.isOnline()) game.delayx(); - 'step 2' - var sign=event.sign; - if(sign>0){ - player.logSkill('dczuowei'); + }, + dczuowei: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + if (_status.currentPhase != player) return false; + if (!player.hasSkill("dczuowei_ban")) return true; + return Math.sign(player.countCards("h") - Math.max(1, player.countCards("e"))) >= 0; + }, + direct: true, + locked: false, + content: function () { + "step 0"; + var hs = player.countCards("h"); + var es = Math.max(1, player.countCards("e")); + var sign = Math.sign(hs - es); + event.sign = sign; + if (sign > 0) + player + .chooseBool( + get.prompt("dczuowei"), + "令" + get.translation(trigger.card) + "不可被响应" + ) + .set("ai", () => 1); + else if (sign == 0) + player + .chooseTarget( + get.prompt("dczuowei"), + "对一名其他角色造成1点伤害", + lib.filter.notMe + ) + .set("ai", (target) => { + return get.damageEffect(target, _status.event.player, _status.event.player); + }); + else + player + .chooseBool(get.prompt("dczuowei"), "摸两张牌,然后本回合你不能再触发该分支") + .set("ai", () => 1); + "step 1"; + if (!result.bool) event.finish(); + else if (event.sign <= 0 && !event.isMine() && !event.isOnline()) game.delayx(); + "step 2"; + var sign = event.sign; + if (sign > 0) { + player.logSkill("dczuowei"); trigger.directHit.addArray(game.players); event.finish(); - } - else if(sign==0){ - var target=result.targets[0]; - player.logSkill('dczuowei',target); + } else if (sign == 0) { + var target = result.targets[0]; + player.logSkill("dczuowei", target); target.damage(); - } - else{ - player.logSkill('dczuowei'); + } else { + player.logSkill("dczuowei"); player.draw(2); - player.addTempSkill('dczuowei_ban'); + player.addTempSkill("dczuowei_ban"); } }, - subSkill:{ - ban:{charlotte:true} + subSkill: { + ban: { charlotte: true }, }, - mod:{ - aiValue:function(player,card,num){ - if(_status.currentPhase!=player) return; - const event=get.event(); - if(!player.isPhaseUsing()) return; - if(event.type!='phase') return; - const cardsh=[],cardse=[]; - for(const cardx of ui.selected.cards){ - const pos=get.position(cardx); - if(pos=='h') cardsh.add(cardx); - else if(pos=='e') cardse.add(cardx); + mod: { + aiValue: function (player, card, num) { + if (_status.currentPhase != player) return; + const event = get.event(); + if (!player.isPhaseUsing()) return; + if (event.type != "phase") return; + const cardsh = [], + cardse = []; + for (const cardx of ui.selected.cards) { + const pos = get.position(cardx); + if (pos == "h") cardsh.add(cardx); + else if (pos == "e") cardse.add(cardx); } - const hs=player.countCards('h')-cardsh.length,es=Math.max(1,player.countCards('e')-cardse.length); - const delt=hs-es; - if(delt<=0) return; - if(get.position(card)=='h'&&delt==1) return num/1.25; + const hs = player.countCards("h") - cardsh.length, + es = Math.max(1, player.countCards("e") - cardse.length); + const delt = hs - es; + if (delt <= 0) return; + if (get.position(card) == "h" && delt == 1) return num / 1.25; }, - aiUseful:function(){ - return lib.skill.dczuowei.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.dczuowei.mod.aiValue.apply(this, arguments); }, - aiOrder:function(player,card,num){ - if(player.hasSkill('dczuowei_ban')||_status.currentPhase!=player) return; - const cardsh=[],cardse=[]; - const pos=get.position(card); - if(pos=='h') cardsh.add(card); - else if(pos=='e') cardse.add(card); - if(get.tag(card,'draw')||get.tag(card,'gain')){ - const hs=player.countCards('h')-cardsh.length,es=Math.max(1,player.countCards('e')-cardse.length+(get.type(card)=='equip')); - if(player.hasSkill('dczuowei_ban')&&hsMath.max(1,player.countCards('e'))) return [1,3]; - } - } - } + ai: { + threaten: 3, + reverseEquip: true, + effect: { + player_use: function (card, player, target, current) { + if (_status.currentPhase != player) return; + if (get.type(card) == "equip" && get.cardtag(card, "gifts")) return; + if (player.countCards("h") > Math.max(1, player.countCards("e"))) return [1, 3]; + }, + }, + }, }, //刘宠骆俊 - dcminze:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - if(player.getStorage('dcminze_targeted').includes(target)) return false; - return target.countCards('h')get.name(i,player))); + selectCard: [1, 2], + complexCard: true, + position: "he", + discard: false, + lose: false, + delay: false, + group: "dcminze_draw", + content: function () { + player.give(cards, target); + player.addTempSkill("dcminze_targeted", "phaseUseAfter"); + player.markAuto("dcminze_targeted", [target]); + player.addTempSkill("dcminze_given"); + player.markAuto( + "dcminze_given", + cards.map((i) => get.name(i, player)) + ); }, - ai:{ - order:6.5, - expose:0.2, + ai: { + order: 6.5, + expose: 0.2, }, - subSkill:{ - targeted:{onremove:true,charlotte:true}, - given:{ - charlotte:true, - onremove:true, - intro:{ - content:'本回合以此法交出的牌名:$', + subSkill: { + targeted: { onremove: true, charlotte: true }, + given: { + charlotte: true, + onremove: true, + intro: { + content: "本回合以此法交出的牌名:$", }, }, - draw:{ - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getStorage('dcminze_given').length; + draw: { + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.getStorage("dcminze_given").length; }, - forced:true, - locked:false, - content:function(){ - var num=Math.min(5,player.getStorage('dcminze_given').length)-player.countCards('h'); - if(num>0) player.draw(num); - } - } - } + forced: true, + locked: false, + content: function () { + var num = + Math.min(5, player.getStorage("dcminze_given").length) - + player.countCards("h"); + if (num > 0) player.draw(num); + }, + }, + }, }, - dcjini:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.maxHp-player.countMark('dcjini_counted')>0; + dcjini: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return player.maxHp - player.countMark("dcjini_counted") > 0; }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('dcjini'),[1,player.maxHp-player.countMark('dcjini_counted')],lib.filter.cardRecastable).set('ai',card=>{ - return 6-get.value(card); - }); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.logSkill('dcjini'); - player.addTempSkill('dcjini_counted'); - player.addMark('dcjini_counted',cards.length,false); - event.recast=player.recast(cards); - } - else event.finish(); - 'step 2' - if(trigger.source&&trigger.source.isIn()&&player.hasHistory('gain',evt=>evt.getParent(2)==event.recast&&evt.cards.some(value=>get.name(value)=='sha'))){ - player.chooseToUse(function(card){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'击逆:是否对'+get.translation(trigger.source)+'使用一张不可被响应的杀?').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.source).set('oncard',()=>{ - _status.event.directHit.addArray(game.players); + content: function () { + "step 0"; + player + .chooseCard( + get.prompt2("dcjini"), + [1, player.maxHp - player.countMark("dcjini_counted")], + lib.filter.cardRecastable + ) + .set("ai", (card) => { + return 6 - get.value(card); }); + "step 1"; + if (result.bool) { + var cards = result.cards; + player.logSkill("dcjini"); + player.addTempSkill("dcjini_counted"); + player.addMark("dcjini_counted", cards.length, false); + event.recast = player.recast(cards); + } else event.finish(); + "step 2"; + if ( + trigger.source && + trigger.source.isIn() && + player.hasHistory( + "gain", + (evt) => + evt.getParent(2) == event.recast && + evt.cards.some((value) => get.name(value) == "sha") + ) + ) { + player + .chooseToUse(function (card) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "击逆:是否对" + get.translation(trigger.source) + "使用一张不可被响应的杀?") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.source) + .set("oncard", () => { + _status.event.directHit.addArray(game.players); + }); } }, - subSkill:{ - counted:{ - onremove:true, - charlotte:true - } - } + subSkill: { + counted: { + onremove: true, + charlotte: true, + }, + }, }, //乐綝 - dcporui:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - if(player==event.player) return false; - if(player.countMark('dcporui_round')>=(player.hasMark('dcgonghu_basic')?2:1)||player.countCards('h')==0) return false; - return game.hasPlayer(current=>{ - if(current==player||current==event.player) return false; - return current.hasHistory('lose',function(evt){ - return evt.cards2.length>0; - }); - })&&player.countCards('he')>0; + dcporui: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + if (player == event.player) return false; + if ( + player.countMark("dcporui_round") >= (player.hasMark("dcgonghu_basic") ? 2 : 1) || + player.countCards("h") == 0 + ) + return false; + return ( + game.hasPlayer((current) => { + if (current == player || current == event.player) return false; + return current.hasHistory("lose", function (evt) { + return evt.cards2.length > 0; + }); + }) && player.countCards("he") > 0 + ); }, - direct:true, - content:function(){ - 'step 0' - var map={}; - game.countPlayer(function(current){ - if(current==player||current==trigger.player) return false; - if(current.hasHistory('lose',function(evt){ - return evt.cards2.length>0; - })) map[current.playerid]=Math.min(5,current.getHistory('lose').reduce(function(num,evt){ - return num+evt.cards2.length; - },0))+1; + direct: true, + content: function () { + "step 0"; + var map = {}; + game.countPlayer(function (current) { + if (current == player || current == trigger.player) return false; + if ( + current.hasHistory("lose", function (evt) { + return evt.cards2.length > 0; + }) + ) + map[current.playerid] = + Math.min( + 5, + current.getHistory("lose").reduce(function (num, evt) { + return num + evt.cards2.length; + }, 0) + ) + 1; }); - player.chooseCardTarget({ - prompt:get.prompt('dcporui'), - prompt2:get.skillInfoTranslation('dcporui',player), - filterCard:function(card,player){ - return lib.filter.cardDiscardable(card,player,'dcporui'); - }, - position:'he', - filterTarget:function(card,player,target){ - return Object.keys(_status.event.map).includes(target.playerid); - }, - ai1:function(card){ - return 7-get.value(card); - }, - ai2:function(target){ - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player)*_status.event.map[target.playerid]; - } - }).set('map',map); - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - event.target=target; - player.logSkill('dcporui',target); + player + .chooseCardTarget({ + prompt: get.prompt("dcporui"), + prompt2: get.skillInfoTranslation("dcporui", player), + filterCard: function (card, player) { + return lib.filter.cardDiscardable(card, player, "dcporui"); + }, + position: "he", + filterTarget: function (card, player, target) { + return Object.keys(_status.event.map).includes(target.playerid); + }, + ai1: function (card) { + return 7 - get.value(card); + }, + ai2: function (target) { + return ( + get.effect( + target, + { name: "sha" }, + _status.event.player, + _status.event.player + ) * _status.event.map[target.playerid] + ); + }, + }) + .set("map", map); + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + event.target = target; + player.logSkill("dcporui", target); player.discard(cards); - event.num2=Math.min(5,target.getHistory('lose').reduce(function(num,evt){ - return num+evt.cards2.length; - },0)); - event.num=event.num2+1; - player.addTempSkill('dcporui_round','roundStart'); - player.addMark('dcporui_round',1,false); - } - else event.finish(); - 'step 2' - var card={name:'sha',isCard:true,storage:{dcporui:true}}; - if(player.canUse(card,target,false)&&target.isIn()){ - player.useCard(card,target); + event.num2 = Math.min( + 5, + target.getHistory("lose").reduce(function (num, evt) { + return num + evt.cards2.length; + }, 0) + ); + event.num = event.num2 + 1; + player.addTempSkill("dcporui_round", "roundStart"); + player.addMark("dcporui_round", 1, false); + } else event.finish(); + "step 2"; + var card = { name: "sha", isCard: true, storage: { dcporui: true } }; + if (player.canUse(card, target, false) && target.isIn()) { + player.useCard(card, target); event.num--; - } - else event.goto(4); - 'step 3' - if(event.num>0) event.goto(2); - 'step 4' - if(!player.hasMark('dcgonghu_damage')&&target.isIn()){ - var cards=player.getCards('h'); - if(cards.length==0) event._result={bool:false}; - else if(cards.length<=event.num2) event._result={bool:true,cards:cards}; - else player.chooseCard('破锐:交给'+get.translation(target)+get.cnNumber(event.num2)+'张手牌',true,event.num2); - } - else event.finish(); - 'step 5' - if(result.bool){ - player.give(result.cards,target); + } else event.goto(4); + "step 3"; + if (event.num > 0) event.goto(2); + "step 4"; + if (!player.hasMark("dcgonghu_damage") && target.isIn()) { + var cards = player.getCards("h"); + if (cards.length == 0) event._result = { bool: false }; + else if (cards.length <= event.num2) event._result = { bool: true, cards: cards }; + else + player.chooseCard( + "破锐:交给" + get.translation(target) + get.cnNumber(event.num2) + "张手牌", + true, + event.num2 + ); + } else event.finish(); + "step 5"; + if (result.bool) { + player.give(result.cards, target); } event.finish(); - 'step 6' - if(player.hasMark('dcgonghu_basic')){ - if(!target.hasHistory('damage',evt=>{ - return evt.card&&evt.card.storage&&evt.card.storage.dcporui&&evt.getParent('dcporui')==event; - })){ + "step 6"; + if (player.hasMark("dcgonghu_basic")) { + if ( + !target.hasHistory("damage", (evt) => { + return ( + evt.card && + evt.card.storage && + evt.card.storage.dcporui && + evt.getParent("dcporui") == event + ); + }) + ) { player.recover(); } } }, - subSkill:{ - round:{charlotte:true,onremove:true} + subSkill: { + round: { charlotte: true, onremove: true }, + }, + ai: { + expose: 0.4, + threaten: 3.8, }, - ai:{ - expose:0.4, - threaten:3.8, - } }, - dcgonghu:{ - audio:2, - trigger:{ - player:['loseAfter','damageEnd'], - source:'damageSource', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcgonghu: { + audio: 2, + trigger: { + player: ["loseAfter", "damageEnd"], + source: "damageSource", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - if(event.name=='damage'){ - if(player.hasMark('dcgonghu_damage')) return false; - var num=0; - player.getHistory('damage',evt=>num+=evt.num); - player.getHistory('sourceDamage',evt=>num+=evt.num); - return num>1; + forced: true, + filter: function (event, player) { + if (event.name == "damage") { + if (player.hasMark("dcgonghu_damage")) return false; + var num = 0; + player.getHistory("damage", (evt) => (num += evt.num)); + player.getHistory("sourceDamage", (evt) => (num += evt.num)); + return num > 1; } - if(!_status.currentPhase||_status.currentPhase==player) return false; - if(player.hasMark('dcgonghu_basic')) return false; - if(_status.currentPhase&&_status.currentPhase==player) return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.some(i=>get.type2(i,player)=='basic')) return false; - var num=0; - player.getHistory('lose',function(evtx){ - if(num<2){ - if(evtx&&evtx.cards2) num+=evtx.cards2.filter(i=>get.type2(i,player)=='basic').length; + if (!_status.currentPhase || _status.currentPhase == player) return false; + if (player.hasMark("dcgonghu_basic")) return false; + if (_status.currentPhase && _status.currentPhase == player) return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.some((i) => get.type2(i, player) == "basic")) + return false; + var num = 0; + player.getHistory("lose", function (evtx) { + if (num < 2) { + if (evtx && evtx.cards2) + num += evtx.cards2.filter((i) => get.type2(i, player) == "basic").length; } }); - return num>=2; + return num >= 2; }, - group:['dcgonghu_basic','dcgonghu_trick'], - content:function(){ - player.addMark('dcgonghu_'+(trigger.name=='damage'?'damage':'basic'),1,false); - game.log(player,'修改了技能','#g【破锐】'); + group: ["dcgonghu_basic", "dcgonghu_trick"], + content: function () { + player.addMark("dcgonghu_" + (trigger.name == "damage" ? "damage" : "basic"), 1, false); + game.log(player, "修改了技能", "#g【破锐】"); }, - subSkill:{ - trick:{ - audio:'dcgonghu', - trigger:{player:'useCard2'}, - direct:true, - locked:true, - filter:function(event,player){ - if(!player.hasMark('dcgonghu_basic')||!player.hasMark('dcgonghu_damage')) return false; - var card=event.card; - if(get.color(card,false)!='red'||get.type(card,null,true)!='trick') return false; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ + ai: { + combo: "dcporui", + }, + subSkill: { + trick: { + audio: "dcgonghu", + trigger: { player: "useCard2" }, + direct: true, + locked: true, + filter: function (event, player) { + if (!player.hasMark("dcgonghu_basic") || !player.hasMark("dcgonghu_damage")) + return false; + var card = event.card; + if (get.color(card, false) != "red" || get.type(card, null, true) != "trick") + return false; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('dcgonghu_trick'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget(get.prompt("dcgonghu_trick"), function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('dcgonghu_trick',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("dcgonghu_trick", event.targets); trigger.targets.addArray(event.targets); } }, }, - basic:{ - audio:'dcgonghu', - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(!player.hasMark('dcgonghu_basic')||!player.hasMark('dcgonghu_damage')) return false; - var card=event.card; - return (get.color(card,false)=='red'&&get.type(card,null,false)=='basic'); + basic: { + audio: "dcgonghu", + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (!player.hasMark("dcgonghu_basic") || !player.hasMark("dcgonghu_damage")) + return false; + var card = event.card; + return get.color(card, false) == "red" && get.type(card, null, false) == "basic"; }, - content:function(){ + content: function () { trigger.directHit.addArray(game.filterPlayer()); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, }, - } + }, }, //张闿 - dcxiangshu:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&event.player.countCards('h')>=event.player.hp; + dcxiangshu: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return event.player != player && event.player.countCards("h") >= event.player.hp; }, - content:function(){ - 'step 0' - var list=[0,1,2,3,4,5,'cancel2']; - player.chooseControl(list).set('prompt',get.prompt2('dcxiangshu')).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(get.attitude(player,trigger.player)>0) return 'cancel2'; - var cards=trigger.player.getCards('h'); - var num=0; - for(var card of cards){ - if(!trigger.player.hasValueTarget(card)){ - num++; - if(num>=5) break; - } - } - if(cards.length>=3&&Math.random()<0.5) num=Math.max(0,num-1); - return num; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dcxiangshu',trigger.player); - var num=result.index; - player.storage.dcxiangshu_lottery=num; - player.addTempSkill('dcxiangshu_lottery','phaseUseAfter'); - } - else event.finish(); - 'step 2' - player.chooseToDiscard('相鼠:是否弃置一张牌不公布此数字?').set('ai',card=>2-get.value(card)); - 'step 3' - if(!result.bool){ - var num=player.storage.dcxiangshu_lottery; - player.markSkill('dcxiangshu_lottery'); + content: function () { + "step 0"; + var list = [0, 1, 2, 3, 4, 5, "cancel2"]; + player + .chooseControl(list) + .set("prompt", get.prompt2("dcxiangshu")) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (get.attitude(player, trigger.player) > 0) return "cancel2"; + var cards = trigger.player.getCards("h"); + var num = 0; + for (var card of cards) { + if (!trigger.player.hasValueTarget(card)) { + num++; + if (num >= 5) break; + } + } + if (cards.length >= 3 && Math.random() < 0.5) num = Math.max(0, num - 1); + return num; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dcxiangshu", trigger.player); + var num = result.index; + player.storage.dcxiangshu_lottery = num; + player.addTempSkill("dcxiangshu_lottery", "phaseUseAfter"); + } else event.finish(); + "step 2"; + player + .chooseToDiscard("相鼠:是否弃置一张牌不公布此数字?") + .set("ai", (card) => 2 - get.value(card)); + "step 3"; + if (!result.bool) { + var num = player.storage.dcxiangshu_lottery; + player.markSkill("dcxiangshu_lottery"); player.popup(num); - game.log(player,'选择了数字','#g'+num); + game.log(player, "选择了数字", "#g" + num); } }, - subSkill:{ - lottery:{ - audio:'dcxiangshu', - trigger:{global:'phaseUseEnd'}, - charlotte:true, - forced:true, - onremove:true, - logTarget:'player', - filter:function(event,player){ - return typeof player.storage.dcxiangshu_lottery=='number'&&Math.abs(event.player.countCards('h')-player.storage.dcxiangshu_lottery)<=1; + subSkill: { + lottery: { + audio: "dcxiangshu", + trigger: { global: "phaseUseEnd" }, + charlotte: true, + forced: true, + onremove: true, + logTarget: "player", + filter: function (event, player) { + return ( + typeof player.storage.dcxiangshu_lottery == "number" && + Math.abs(event.player.countCards("h") - player.storage.dcxiangshu_lottery) <= + 1 + ); }, - content:function(){ - var delt=Math.abs(trigger.player.countCards('h')-player.storage.dcxiangshu_lottery); - if(delt<=1&&trigger.player.countGainableCards('he',player)>0){ - player.gainPlayerCard(trigger.player,'he',true); + content: function () { + var delt = Math.abs( + trigger.player.countCards("h") - player.storage.dcxiangshu_lottery + ); + if (delt <= 1 && trigger.player.countGainableCards("he", player) > 0) { + player.gainPlayerCard(trigger.player, "he", true); } - if(delt==0){ + if (delt == 0) { trigger.player.damage(player); } }, - intro:{content:'猜测的数字为#'} - } - } + intro: { content: "猜测的数字为#" }, + }, + }, }, //裴元绍 - dcmoyu:{ - audio:2, - init:()=>{ - game.addGlobalSkill('dcmoyu_ai'); + dcmoyu: { + audio: 2, + init: () => { + game.addGlobalSkill("dcmoyu_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('dcmoyu'),true)) game.removeGlobalSkill('dcmoyu_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("dcmoyu"), true)) + game.removeGlobalSkill("dcmoyu_ai"); }, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('dcmoyu_ban')&&game.hasPlayer(current=>lib.skill.dcmoyu.filterTarget(null,player,current)); + enable: "phaseUse", + filter: function (event, player) { + return ( + !player.hasSkill("dcmoyu_ban") && + game.hasPlayer((current) => lib.skill.dcmoyu.filterTarget(null, player, current)) + ); }, - filterTarget:function(card,player,target){ - return player!=target&&!player.getStorage('dcmoyu_clear').includes(target)&&target.countGainableCards(player,'hej'); + filterTarget: function (card, player, target) { + return ( + player != target && + !player.getStorage("dcmoyu_clear").includes(target) && + target.countGainableCards(player, "hej") + ); }, - content:function(){ - 'step 0' - player.addTempSkill('dcmoyu_clear'); - player.markAuto('dcmoyu_clear',[target]); - player.gainPlayerCard(target,'hej',true); - 'step 1' - var num=player.getStorage('dcmoyu_clear').length; - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'是否对'+get.translation(player)+'使用一张无距离限制的【杀】(伤害基数为'+num+')?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',player).set('num',num).set('oncard',card=>{ - _status.event.baseDamage=_status.event.getParent().num; - }); - 'step 2' - if(result.bool){ - if(player.hasHistory('damage',evt=>{ - return evt.card&&evt.card.name=='sha'&&evt.getParent(4)==event; - })) player.addTempSkill('dcmoyu_ban'); + content: function () { + "step 0"; + player.addTempSkill("dcmoyu_clear"); + player.markAuto("dcmoyu_clear", [target]); + player.gainPlayerCard(target, "hej", true); + "step 1"; + var num = player.getStorage("dcmoyu_clear").length; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "是否对" + + get.translation(player) + + "使用一张无距离限制的【杀】(伤害基数为" + + num + + ")?") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", player) + .set("num", num) + .set("oncard", (card) => { + _status.event.baseDamage = _status.event.getParent().num; + }); + "step 2"; + if (result.bool) { + if ( + player.hasHistory("damage", (evt) => { + return evt.card && evt.card.name == "sha" && evt.getParent(4) == event; + }) + ) + player.addTempSkill("dcmoyu_ban"); } }, - subSkill:{ - clear:{ - charlotte:true, - onremove:true, + subSkill: { + clear: { + charlotte: true, + onremove: true, }, - ban:{ - charlotte:true, - mark:true, - marktext:'欲', - intro:{content:'偷马贼被反打了!'}, + ban: { + charlotte: true, + mark: true, + marktext: "欲", + intro: { content: "偷马贼被反打了!" }, }, - ai:{ - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('dcmoyu'),true); + ai: { + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("dcmoyu"), true); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('dcmoyu_ai'); + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("dcmoyu_ai"); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='delay'&¤t<0){ - var currentx=_status.currentPhase; - if(!currentx||!currentx.isIn()) return; - var list=game.filterPlayer(current=>{ - if(current==target) return true; - if(!current.hasSkill('dcmoyu')) return false; - if(current.hasJudge('lebu')) return false; - return get.attitude(current,target)>0; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "delay" && current < 0) { + var currentx = _status.currentPhase; + if (!currentx || !currentx.isIn()) return; + var list = game.filterPlayer((current) => { + if (current == target) return true; + if (!current.hasSkill("dcmoyu")) return false; + if (current.hasJudge("lebu")) return false; + return get.attitude(current, target) > 0; }); list.sortBySeat(currentx); - if(list.indexOf(target)!=0) return 'zerotarget'; + if (list.indexOf(target) != 0) return "zerotarget"; } }, }, - } - } + }, + }, }, - ai:{ - order:9, - threaten:2.4, - result:{ - target:function(player,target){ - var num=get.sgn(get.attitude(player,target)); - var eff=get.effect(target,{name:'shunshou'},player,player)*num; - if(eff*num>0) return eff/10; - if(player.hasShan()&&!target.hasSkillTag('directHit_ai',true,{ - target:player, - card:{name:'sha'}, - },true)) return eff; - if(target.hasSha()&&player.hp+player.countCards('hs',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,player); - return savable; - })<=player.getStorage('dcmoyu_clear').length+1) return 0; + ai: { + order: 9, + threaten: 2.4, + result: { + target: function (player, target) { + var num = get.sgn(get.attitude(player, target)); + var eff = get.effect(target, { name: "shunshou" }, player, player) * num; + if (eff * num > 0) return eff / 10; + if ( + player.hasShan() && + !target.hasSkillTag( + "directHit_ai", + true, + { + target: player, + card: { name: "sha" }, + }, + true + ) + ) + return eff; + if ( + target.hasSha() && + player.hp + + player.countCards("hs", function (card) { + var mod2 = game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") + savable = savable(card, player, player); + return savable; + }) <= + player.getStorage("dcmoyu_clear").length + 1 + ) + return 0; return eff; - } - } - } + }, + }, + }, }, //张楚 - dcjizhong:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - selectTarget:1, - content:function(){ - 'step 0' + dcjizhong: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + selectTarget: 1, + content: function () { + "step 0"; target.draw(2); - 'step 1' - var marked=target.hasMark('dcjizhong'); - var cards=target.getCards('h'); - if(marked){ - if(cards.length<=3) event._result={bool:true,cards:cards}; - else target.chooseCard(`集众:交给${get.translation(player)}三张手牌`,3,true); + "step 1"; + var marked = target.hasMark("dcjizhong"); + var cards = target.getCards("h"); + if (marked) { + if (cards.length <= 3) event._result = { bool: true, cards: cards }; + else target.chooseCard(`集众:交给${get.translation(player)}三张手牌`, 3, true); + } else { + target + .chooseCard( + `集众:交给${get.translation(player)}三张手牌,或点击“取消”获得“信众”标记`, + 3 + ) + .set("ai", (card) => { + if (get.event("goon")) return 20 - get.value(card); + return 1 - get.value(card); + }) + .set("goon", get.attitude(target, player) > 0); } - else{ - target.chooseCard(`集众:交给${get.translation(player)}三张手牌,或点击“取消”获得“信众”标记`,3).set('ai',card=>{ - if(get.event('goon')) return 20-get.value(card); - return 1-get.value(card); - }).set('goon',get.attitude(target,player)>0); - } - 'step 2' - if(!result.bool){ - target.addMark('dcjizhong',1); - } - else{ - target.give(result.cards,player); + "step 2"; + if (!result.bool) { + target.addMark("dcjizhong", 1); + } else { + target.give(result.cards, player); } }, - marktext:'信', - intro:{ - name:'信众', - name2:'信众', - markcount:()=>0, - content:'已成为信徒', + marktext: "信", + intro: { + name: "信众", + name2: "信众", + markcount: () => 0, + content: "已成为信徒", }, - ai:{ - order:9.5, - result:{ - target:function(player,target){ - var num=target.countCards('h'); - if(num<=1) return -num; - if(get.attitude(player,target)>0) return 1; - return -1/(num/2+1); + ai: { + order: 9.5, + result: { + target: function (player, target) { + var num = target.countCards("h"); + if (num <= 1) return -num; + if (get.attitude(player, target) > 0) return 1; + return -1 / (num / 2 + 1); + }, + }, + }, + }, + dcrihui: { + audio: 2, + trigger: { player: "useCardAfter" }, + usable: 1, + filter: function (event, player) { + if (!event.targets || event.targets.length != 1 || event.targets[0] == player) + return false; + var card = event.card; + var target = event.targets[0]; + var marked = target.hasMark("dcjizhong"); + return ( + (get.type(card) == "trick" || + (get.color(card) == "black" && get.type(card) == "basic")) && + (marked || (!marked && game.hasPlayer((current) => current.hasMark("dcjizhong")))) + ); + }, + logTarget: (event) => event.targets[0], + prompt2(event, player) { + const target = event.targets[0]; + if (target.hasMark("dcjizhong")) return "获得该角色区域内的一张牌"; + else { + const card = { name: event.card.name, nature: event.card.nature, isCard: true }; + return "令所有有“信众”的角色依次视为对其使用一张" + get.translation(card); + } + }, + check(event, player) { + const target = event.targets[0]; + if (target.hasMark("dcjizhong")) { + return get.effect(target, { name: "shunshou_copy" }, event, player) > 0; + } else { + const card = { name: event.card.name, nature: event.card.nature, isCard: true }; + let eff = 0; + game.countPlayer((current) => { + if (!current.hasMark("dcjizhong") || !current.canUse(card, player, false)) return; + eff += get.effect(target, card, current, player); + }); + return eff > 0; + } + }, + async content(event, trigger, player) { + const target = trigger.targets[0]; + if (target.hasMark("dcjizhong")) { + await player.gainPlayerCard(target, "hej", true); + } else { + const card = { name: trigger.card.name, nature: trigger.card.nature, isCard: true }; + const targets = game + .filterPlayer((current) => current.hasMark("dcjizhong")) + .sortBySeat(_status.currentPhase); + for (const current of targets) { + if (target.isIn() && current.isIn() && current.canUse(card, target, false)) { + await current.useCard(card, target, false); + } } } - } - }, - dcrihui:{ - audio:2, - trigger:{player:'useCardAfter'}, - usable:1, - filter:function(event,player){ - if(!event.targets||event.targets.length!=1||event.targets[0]==player) return false; - var card=event.card; - var target=event.targets[0]; - var marked=target.hasMark('dcjizhong'); - return (get.type(card)=='trick'||get.color(card)=='black'&&get.type(card)=='basic')&& - (marked||!marked&&game.hasPlayer(current=>current.hasMark('dcjizhong'))); }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.targets[0]; - var card={name:trigger.card.name,nature:trigger.card.nature,isCard:true}; - event.target=target; - event.card=card; - if(target.hasMark('dcjizhong')) player.gainPlayerCard(get.prompt('dcrihui',target),target,'hej').set('logSkill',['dcrihui',target]); - else{ - player.chooseBool(get.prompt('dcrihui',target),'令所有有“信众”的角色依次视为对其使用一张'+get.translation(card)).set('ai',()=>{ - return _status.event.bool; - }).set('bool',function(){ - var eff=0; - game.countPlayer(current=>{ - if(!current.hasMark('dcjizhong')) return; - eff+=get.effect(target,card,current,player); - }); - return eff>0; - }()); - } - 'step 1' - if(!result.bool){ - player.storage.counttrigger.dcrihui--; - event.finish(); - return; - } - if(target.hasMark('dcjizhong')) event.finish(); - else{ - player.logSkill('dcrihui',target); - event.targets=game.filterPlayer(current=>current.hasMark('dcjizhong')); - event.targets.sortBySeat(_status.currentPhase); - } - 'step 2' - var current=event.targets.shift(); - if(current.canUse(card,target,false)){ - current.useCard(card,target,false); - } - if(event.targets.length) event.redo(); - } - }, - dcguangshi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return !game.hasPlayer(current=>current!=player&&!current.hasMark('dcjizhong')); + ai: { + combo: "dcjizhong", }, - forced:true, - content:function(){ + }, + dcguangshi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return !game.hasPlayer((current) => current != player && !current.hasMark("dcjizhong")); + }, + forced: true, + content: function () { player.draw(2); player.loseHp(); - } + }, + ai: { + combo: "dcjizhong", + }, }, //董绾 - dcshengdu:{ - audio:2, - trigger:{player:'phaseBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('dcshengdu'),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - var att=get.attitude(player,target); - var eff=get.effect(target,{ - name:'sha', - storage:{dcjieling:true}, - },player,player); - var value=att/5; - if(value<0) value=-value/1.3; - value=Math.max(value-eff/20,0.01); + dcshengdu: { + audio: 2, + trigger: { player: "phaseBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("dcshengdu"), lib.filter.notMe).set("ai", (target) => { + var player = _status.event.player; + var att = get.attitude(player, target); + var eff = get.effect( + target, + { + name: "sha", + storage: { dcjieling: true }, + }, + player, + player + ); + var value = att / 5; + if (value < 0) value = -value / 1.3; + value = Math.max(value - eff / 20, 0.01); return value; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcshengdu',target); - target.addMark('dcshengdu',1); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcshengdu", target); + target.addMark("dcshengdu", 1); } }, - intro:{content:'mark'}, - group:'dcshengdu_effect', - subSkill:{ - effect:{ - audio:'dcshengdu', - trigger:{global:'gainAfter'}, - filter:function(event,player){ - return event.getParent(2).name=='phaseDraw'&&event.player.hasMark('dcshengdu'); + intro: { content: "mark" }, + group: "dcshengdu_effect", + subSkill: { + effect: { + audio: "dcshengdu", + trigger: { global: "gainAfter" }, + filter: function (event, player) { + return ( + event.getParent(2).name == "phaseDraw" && event.player.hasMark("dcshengdu") + ); }, - forced:true, - logTarget:'player', - content:function(){ - var num=trigger.player.countMark('dcshengdu'); - player.draw(num*trigger.cards.length); - trigger.player.removeMark('dcshengdu',num); + forced: true, + logTarget: "player", + content: function () { + var num = trigger.player.countMark("dcshengdu"); + player.draw(num * trigger.cards.length); + trigger.player.removeMark("dcshengdu", num); }, - } - } + }, + }, }, - dcjieling:{ - audio:2, - enable:'phaseUse', - position:'hs', - viewAs:{ - name:'sha', - storage:{dcjieling:true} + dcjieling: { + audio: 2, + enable: "phaseUse", + position: "hs", + viewAs: { + name: "sha", + storage: { dcjieling: true }, }, - filterCard:function(card,player){ - if(player.getStorage('dcjieling_count').includes(get.suit(card))) return false; - if(ui.selected.cards.length){ - return get.suit(card)!=get.suit(ui.selected.cards[0]); + filterCard: function (card, player) { + if (player.getStorage("dcjieling_count").includes(get.suit(card))) return false; + if (ui.selected.cards.length) { + return get.suit(card) != get.suit(ui.selected.cards[0]); } return true; }, - selectCard:2, - complexCard:true, - check:function(card){ - return 6-get.value(card); + selectCard: 2, + complexCard: true, + check: function (card) { + return 6 - get.value(card); }, - precontent:function(){ - player.addTempSkill('dcjieling_after'); - event.getParent().addCount=false; - player.addTempSkill('dcjieling_count','phaseUseAfter'); - player.markAuto('dcjieling_count',event.result.cards.reduce((list,card)=>list.add(get.suit(card,player)),[])); + precontent: function () { + player.addTempSkill("dcjieling_after"); + event.getParent().addCount = false; + player.addTempSkill("dcjieling_count", "phaseUseAfter"); + player.markAuto( + "dcjieling_count", + event.result.cards.reduce((list, card) => list.add(get.suit(card, player)), []) + ); }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'})+0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }) + 0.1; }, }, - locked:false, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.dcjieling) return true; + locked: false, + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.dcjieling) return true; }, - cardUsable:function(card,player,num){ - if(card.storage&&card.storage.dcjieling) return Infinity; + cardUsable: function (card, player, num) { + if (card.storage && card.storage.dcjieling) return Infinity; }, }, - subSkill:{ - after:{ - charlotte:true, - audio:'dcjieling', - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.card.storage&&event.card.storage.dcjieling; + subSkill: { + after: { + charlotte: true, + audio: "dcjieling", + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && event.card.storage && event.card.storage.dcjieling + ); }, - direct:true, - content:function(){ - 'step 0' - var damaged=game.hasPlayer2(current=>{ - return current.hasHistory('damage',evt=>evt.card==trigger.card); + direct: true, + content: function () { + "step 0"; + var damaged = game.hasPlayer2((current) => { + return current.hasHistory("damage", (evt) => evt.card == trigger.card); }); - var targets=trigger.targets.filter(i=>i.isIn()); - player.logSkill('dcjieling_after',targets); - if(damaged){ - for(var target of targets){ + var targets = trigger.targets.filter((i) => i.isIn()); + player.logSkill("dcjieling_after", targets); + if (damaged) { + for (var target of targets) { target.loseHp(); } - } - else{ - for(var target of targets){ - target.addMark('dcshengdu',1); + } else { + for (var target of targets) { + target.addMark("dcshengdu", 1); } } - } - }, - count:{ - intro:{ - content:function(s,p){ - let str='此阶段已转化过的卡牌花色:'; - for(let i=0;ievt.skill=='dcmoshou').length%3+1; - return '摸'+get.cnNumber(num)+'张牌'; + frequent: true, + prompt2: function (event, player) { + var num = + (player.getAllHistory("useSkill", (evt) => evt.skill == "dcmoshou").length % 3) + 1; + return "摸" + get.cnNumber(num) + "张牌"; }, - content:function(){ - var num=player.getAllHistory('useSkill',evt=>evt.skill=='dcmoshou').length; - player.storage.dcmoshou=num; - player.syncStorage('dcmoshou'); - player.markSkill('dcmoshou'); - num=(num-1)%3+1; + content: function () { + var num = player.getAllHistory("useSkill", (evt) => evt.skill == "dcmoshou").length; + player.storage.dcmoshou = num; + player.syncStorage("dcmoshou"); + player.markSkill("dcmoshou"); + num = ((num - 1) % 3) + 1; player.draw(num); }, - mark:true, - marktext:'守', - intro:{ - markcount:function(storage,player){ - if(typeof storage!='number') return 1; - return storage%3+1; + mark: true, + marktext: "守", + intro: { + markcount: function (storage, player) { + if (typeof storage != "number") return 1; + return (storage % 3) + 1; }, - content:'本局游戏已发动过$次技能', - } + content: "本局游戏已发动过$次技能", + }, }, - dcyunjiu:{ - audio:2, - trigger:{global:'dieAfter'}, - direct:true, - content:function(){ - 'step 0' - var evt=trigger.player.getHistory('lose',evtx=>{ - return evtx.getParent(2)==trigger; + dcyunjiu: { + audio: 2, + trigger: { global: "dieAfter" }, + direct: true, + content: function () { + "step 0"; + var evt = trigger.player.getHistory("lose", (evtx) => { + return evtx.getParent(2) == trigger; })[0]; - if(!evt) event.finish(); - else{ - var cards=[]; + if (!evt) event.finish(); + else { + var cards = []; //冷知识,角色死亡后只有手牌区和装备区的牌是被系统弃置的,其余牌的处理方式均为置入弃牌堆 cards.addArray(evt.hs).addArray(evt.es); - event.cards=cards.filterInD('d'); - var num=cards.length; - if(num){ - event.videoId=lib.status.videoId++; - var func=function(cards,id){ - var num=cards.length; - var dialog=ui.create.dialog(get.prompt('dcyunjiu'),'
              弃置'+get.cnNumber(num)+'张牌,令一名其他角色获得以下这些牌
              ',cards); - dialog.videoId=id; + event.cards = cards.filterInD("d"); + var num = cards.length; + if (num) { + event.videoId = lib.status.videoId++; + var func = function (cards, id) { + var num = cards.length; + var dialog = ui.create.dialog( + get.prompt("dcyunjiu"), + '
              弃置' + + get.cnNumber(num) + + "张牌,令一名其他角色获得以下这些牌
              ", + cards + ); + dialog.videoId = id; return dialog; }; - if(player.isOnline2()){ - player.send(func,cards,event.videoId); + if (player.isOnline2()) { + player.send(func, cards, event.videoId); } - event.dialog=func(cards,event.videoId); - if(player!=game.me||_status.auto){ - event.dialog.style.display='none'; + event.dialog = func(cards, event.videoId); + if (player != game.me || _status.auto) { + event.dialog.style.display = "none"; } player.chooseCardTarget({ - prompt:false, - filterTarget:lib.filter.notMe, - filterCard:lib.filter.cardDiscardable, - selectCard:num, - position:'he', - goon:function(){ - if(!game.hasPlayer(current=>get.attitude(player,current))>0) return false; - var value=0; - for(var card of cards){ - value+=get.value(card,player,'raw')-1.2; + prompt: false, + filterTarget: lib.filter.notMe, + filterCard: lib.filter.cardDiscardable, + selectCard: num, + position: "he", + goon: (function () { + if (!game.hasPlayer((current) => get.attitude(player, current)) > 0) + return false; + var value = 0; + for (var card of cards) { + value += get.value(card, player, "raw") - 1.2; } - return value>0; - }(), - ai1:function(card){ - if(_status.event.goon){ - if(ui.selected.cards.length==_status.event.selectCard[1]-1&&ui.selected.cards.length>0) return 7-get.value(card); - return 5.5-get.value(card); + return value > 0; + })(), + ai1: function (card) { + if (_status.event.goon) { + if ( + ui.selected.cards.length == _status.event.selectCard[1] - 1 && + ui.selected.cards.length > 0 + ) + return 7 - get.value(card); + return 5.5 - get.value(card); } return 0; }, - ai2:function(target){ - return get.attitude(_status.event.player,target)/Math.sqrt(target.countCards('h')+1); - } + ai2: function (target) { + return ( + get.attitude(_status.event.player, target) / + Math.sqrt(target.countCards("h") + 1) + ); + }, }); - } - else event.finish(); + } else event.finish(); + } + "step 1"; + if (player.isOnline2()) { + player.send("closeDialog", event.videoId); } - 'step 1' - if(player.isOnline2()){player.send('closeDialog',event.videoId)} event.dialog.close(); - if(result.bool){ - var cardsx=result.cards,target=result.targets[0]; - player.logSkill('dcyunjiu',target); + if (result.bool) { + var cardsx = result.cards, + target = result.targets[0]; + player.logSkill("dcyunjiu", target); player.discard(cardsx); - target.gain(cards.filterInD('d'),'gain2').giver=player; - } - else event.finish(); - 'step 2' + target.gain(cards.filterInD("d"), "gain2").giver = player; + } else event.finish(); + "step 2"; player.gainMaxHp(); player.recover(); - } + }, }, //高翔 - dcchiying:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.hp<=player.hp; + dcchiying: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.hp <= player.hp; }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player).sortBySeat(player); - event.targets=targets; - if(!targets.length) event.finish(); - 'step 1' - var current=targets.shift(); - if(current.countCards('he')) current.chooseToDiscard('驰应:请弃置一张牌','he',true); - if(targets.length) event.redo(); - 'step 2' - if(target!=player){ - var cards=[]; - game.getGlobalHistory('cardMove',evt=>{ - if(evt.getParent(3)==event){ - cards.addArray(evt.cards.filter(card=>get.type(card)=='basic')); + content: function () { + "step 0"; + var targets = game + .filterPlayer((current) => target.inRange(current) && current != player) + .sortBySeat(player); + event.targets = targets; + if (!targets.length) event.finish(); + "step 1"; + var current = targets.shift(); + if (current.countCards("he")) current.chooseToDiscard("驰应:请弃置一张牌", "he", true); + if (targets.length) event.redo(); + "step 2"; + if (target != player) { + var cards = []; + game.getGlobalHistory("cardMove", (evt) => { + if (evt.getParent(3) == event) { + cards.addArray(evt.cards.filter((card) => get.type(card) == "basic")); } }); - cards=cards.filterInD('d'); - if(cards.length) target.gain(cards,'gain2'); + cards = cards.filterInD("d"); + if (cards.length) target.gain(cards, "gain2"); } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - var targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player); - var eff=0; - for(var targetx of targets){ - var effx=get.effect(targetx,{name:'guohe_copy2'},player,target); - if(get.attitude(player,targetx)<0) effx/=2; - eff+=effx; + ai: { + order: 6, + result: { + target: function (player, target) { + var targets = game.filterPlayer( + (current) => target.inRange(current) && current != player + ); + var eff = 0; + for (var targetx of targets) { + var effx = get.effect(targetx, { name: "guohe_copy2" }, player, target); + if (get.attitude(player, targetx) < 0) effx /= 2; + eff += effx; } - return (target==player?0.5:1)*eff*(get.attitude(player,target)<=0?0.75:1); - } - } - } + return ( + (target == player ? 0.5 : 1) * + eff * + (get.attitude(player, target) <= 0 ? 0.75 : 1) + ); + }, + }, + }, }, //霍峻 - dcgue:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - if(player.hasSkill('dcgue_blocker',null,null,false)) return false; - return name=='sha'||name=='shan'; + dcgue: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + if (player.hasSkill("dcgue_blocker", null, null, false)) return false; + return name == "sha" || name == "shan"; }, - filter:function(event,player){ - if(event.dcgue||event.type=='wuxie'||player==_status.currentPhase) return false; - if(player.hasSkill('dcgue_blocker',null,null,false)) return false; - for(var name of ['sha','shan']){ - if(event.filterCard({name:name,isCard:true},player,event)) return true; + filter: function (event, player) { + if (event.dcgue || event.type == "wuxie" || player == _status.currentPhase) return false; + if (player.hasSkill("dcgue_blocker", null, null, false)) return false; + for (var name of ["sha", "shan"]) { + if (event.filterCard({ name: name, isCard: true }, player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var vcards=[]; - for(var name of ['sha','shan']){ - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); + chooseButton: { + dialog: function (event, player) { + var vcards = []; + for (var name of ["sha", "shan"]) { + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); } - return ui.create.dialog('孤扼',[vcards,'vcard'],'hidden'); + return ui.create.dialog("孤扼", [vcards, "vcard"], "hidden"); }, - check:function(button){ - if(_status.event.player.countCards('h',{name:['sha','shan']})>1) return 0; + check: function (button) { + if (_status.event.player.countCards("h", { name: ["sha", "shan"] }) > 1) return 0; return 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:()=>false, - selectCard:-1, - viewAs:{ - name:links[0][2], - isCard:true, + filterCard: () => false, + selectCard: -1, + viewAs: { + name: links[0][2], + isCard: true, }, - popname:true, - precontent:function(){ - 'step 0' - player.logSkill('dcgue'); - player.addTempSkill('dcgue_blocker'); - if(player.countCards('h')) player.showHandcards(); + popname: true, + precontent: function () { + "step 0"; + player.logSkill("dcgue"); + player.addTempSkill("dcgue_blocker"); + if (player.countCards("h")) player.showHandcards(); delete event.result.skill; - 'step 1' - if(player.countCards('h',{name:['sha','shan']})>1){ - var evt=event.getParent(); - evt.set('dcgue',true); + "step 1"; + if (player.countCards("h", { name: ["sha", "shan"] }) > 1) { + var evt = event.getParent(); + evt.set("dcgue", true); evt.goto(0); delete evt.openskilldialog; return; } game.delayx(); }, - } + }; + }, + prompt: function (links, player) { + return ( + (player.countCards ? "展示所有手牌" : "") + + (player.countCards("h", { name: ["sha", "shan"] }) <= 1 + ? ",然后视为使用【" + get.translation(links[0][2]) + "】" + : "") + ); }, - prompt:function(links,player){ - return (player.countCards?'展示所有手牌':'')+(player.countCards('h',{name:['sha','shan']})<=1?',然后视为使用【'+get.translation(links[0][2])+'】':''); - } }, - subSkill:{blocker:{charlotte:true}}, - ai:{ - order:1, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - if(player.hasSkill('dcgue_blocker',null,null,false)) return false; + subSkill: { blocker: { charlotte: true } }, + ai: { + order: 1, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + if (player.hasSkill("dcgue_blocker", null, null, false)) return false; }, - result:{ - player:function(player){ - if(player.countCards('h',{name:['sha','shan']})>1) return 0; + result: { + player: function (player) { + if (player.countCards("h", { name: ["sha", "shan"] }) > 1) return 0; return 1; - } - } - } + }, + }, + }, }, - dcsigong:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - if(player.hasSkill('dcsigong_round')) return false; - if(event.player==player||!event.player.isIn()) return false; - if(!player.canUse('sha',event.player,false)) return false; - var respondEvts=[]; - game.countPlayer2(current=>respondEvts.addArray(current.getHistory('useCard')).addArray(current.getHistory('respond'))); - respondEvts=respondEvts.filter(i=>i.respondTo).map(evt=>evt.respondTo); - return event.player.hasHistory('useCard',evt=>{ - return respondEvts.some(list=>list[1]==evt.card); + dcsigong: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + if (player.hasSkill("dcsigong_round")) return false; + if (event.player == player || !event.player.isIn()) return false; + if (!player.canUse("sha", event.player, false)) return false; + var respondEvts = []; + game.countPlayer2((current) => + respondEvts + .addArray(current.getHistory("useCard")) + .addArray(current.getHistory("respond")) + ); + respondEvts = respondEvts.filter((i) => i.respondTo).map((evt) => evt.respondTo); + return event.player.hasHistory("useCard", (evt) => { + return respondEvts.some((list) => list[1] == evt.card); }); }, - direct:true, - content:function(){ - 'step 0' - var num=1-player.countCards('h'); - event.num=num; - var prompt2=''; - if(num>=0){ - var next=player.chooseBool().set('ai',()=>_status.event.goon); - prompt2+=(num>0?'摸一张牌,':'')+'视为对'+get.translation(trigger.player)+'使用一张【杀】(伤害基数+1)'; + direct: true, + content: function () { + "step 0"; + var num = 1 - player.countCards("h"); + event.num = num; + var prompt2 = ""; + if (num >= 0) { + var next = player.chooseBool().set("ai", () => _status.event.goon); + prompt2 += + (num > 0 ? "摸一张牌," : "") + + "视为对" + + get.translation(trigger.player) + + "使用一张【杀】(伤害基数+1)"; + } else { + var next = player + .chooseToDiscard(-num) + .set("ai", (card) => { + if (_status.event.goon) return 5.2 - get.value(card); + return 0; + }) + .set("logSkill", ["dcsigong", trigger.player]); + prompt2 += + "将手牌数弃置至1,视为对" + + get.translation(trigger.player) + + "使用一张【杀】(伤害基数+1)"; } - else{ - var next=player.chooseToDiscard(-num).set('ai',card=>{ - if(_status.event.goon) return 5.2-get.value(card); - return 0; - }).set('logSkill',['dcsigong',trigger.player]); - prompt2+='将手牌数弃置至1,视为对'+get.translation(trigger.player)+'使用一张【杀】(伤害基数+1)'; - } - next.set('prompt',get.prompt('dcsigong',trigger.player)); - next.set('prompt2',prompt2); - next.set('goon',get.effect(trigger.player,{name:'sha'},player,player)>0); - 'step 1' - if(result.bool){ - if(num>=0) player.logSkill('dcsigong',trigger.player); - if(num>0) player.draw(num,'nodelay'); - event.num=Math.max(1,Math.abs(num)); - } - else event.finish(); - 'step 2' - if(player.canUse('sha',trigger.player,false)){ - player.addTempSkill('dcsigong_check'); - player.useCard({name:'sha',isCard:true},trigger.player,false).set('shanReq',num).set('oncard',card=>{ - var evt=_status.event; - evt.baseDamage++; - for(var target of game.filterPlayer(null,null,true)){ - var id=target.playerid; - var map=evt.customArgs; - if(!map[id]) map[id]={}; - map[id].shanRequired=evt.shanReq; - } - }); + next.set("prompt", get.prompt("dcsigong", trigger.player)); + next.set("prompt2", prompt2); + next.set("goon", get.effect(trigger.player, { name: "sha" }, player, player) > 0); + "step 1"; + if (result.bool) { + if (num >= 0) player.logSkill("dcsigong", trigger.player); + if (num > 0) player.draw(num, "nodelay"); + event.num = Math.max(1, Math.abs(num)); + } else event.finish(); + "step 2"; + if (player.canUse("sha", trigger.player, false)) { + player.addTempSkill("dcsigong_check"); + player + .useCard({ name: "sha", isCard: true }, trigger.player, false) + .set("shanReq", num) + .set("oncard", (card) => { + var evt = _status.event; + evt.baseDamage++; + for (var target of game.filterPlayer(null, null, true)) { + var id = target.playerid; + var map = evt.customArgs; + if (!map[id]) map[id] = {}; + map[id].shanRequired = evt.shanReq; + } + }); } }, - subSkill:{ - round:{charlotte:true}, - check:{ - charlotte:true, - forced:true, - popup:false, - trigger:{source:'damageSource'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent(3).name=='dcsigong'; + subSkill: { + round: { charlotte: true }, + check: { + charlotte: true, + forced: true, + popup: false, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.getParent(3).name == "dcsigong" + ); }, - content:function(){ - player.addTempSkill('dcsigong_round','roundStart'); - } - } - } + content: function () { + player.addTempSkill("dcsigong_round", "roundStart"); + }, + }, + }, }, //孙寒华 - dchuiling:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - direct:true, - filter:function(){ - return ui.discardPile.childNodes.length>0; + dchuiling: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + direct: true, + filter: function () { + return ui.discardPile.childNodes.length > 0; }, - onremove:true, - mark:true, - marktext:'灵', - intro:{ - name2:'灵', - mark:function(dialog,storage,player){ - dialog.addText('共有'+(storage||0)+'个标记'); - dialog.addText('注:图标的颜色代表弃牌堆中较多的颜色'); + onremove: true, + mark: true, + marktext: "灵", + intro: { + name2: "灵", + mark: function (dialog, storage, player) { + dialog.addText("共有" + (storage || 0) + "个标记"); + dialog.addText("注:图标的颜色代表弃牌堆中较多的颜色"); }, }, - global:'dchuiling_hint', - content:function(){ - 'step 0' - var mark=false; - var red=0,black=0; - for(var i=0;iblack){ - player.logSkill('dchuiling'); + if (red == black) event.finish(); + else if (red > black) { + player.logSkill("dchuiling"); player.recover(); event.finish(); - if(get.color(trigger.card)=='black') mark=true; - event.logged=true; + if (get.color(trigger.card) == "black") mark = true; + event.logged = true; + } else { + if (!event.isMine() && !event.isOnline()) game.delayx(); + player + .chooseTarget( + get.prompt("dchuiling"), + "弃置一名角色的一张牌", + (card, player, target) => { + return target.countDiscardableCards(player, "he") > 0; + } + ) + .set("ai", (target) => { + return get.effect(target, { name: "guohe_copy2" }, _status.event.player); + }); + if (get.color(trigger.card) == "red") mark = true; } - else{ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - player.chooseTarget(get.prompt('dchuiling'),'弃置一名角色的一张牌',(card,player,target)=>{ - return target.countDiscardableCards(player,'he')>0; - }).set('ai',target=>{ - return get.effect(target,{name:'guohe_copy2'},_status.event.player); - }); - if(get.color(trigger.card)=='red') mark=true; + if (mark) { + if (!event.logged) player.logSkill("dchuiling"); + player.addMark("dchuiling", 1); + event.logged = true; } - if(mark){ - if(!event.logged) player.logSkill('dchuiling'); - player.addMark('dchuiling',1); - event.logged=true; - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(!event.logged) player.logSkill('dchuiling',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (!event.logged) player.logSkill("dchuiling", target); else player.line(target); - player.discardPlayerCard(target,'he',true); + player.discardPlayerCard(target, "he", true); } }, - subSkill:{ - hint:{ - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], + subSkill: { + hint: { + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - popup:false, - lastDo:true, - forceDie:true, - forceOut:true, - filter:function(event,player){ - if(event._dchuiling_checked) return false; - event._dchuiling_checked=true; - var cards=event.getd(); - if(!cards.filterInD('d').length) return false; + forced: true, + popup: false, + lastDo: true, + forceDie: true, + forceOut: true, + filter: function (event, player) { + if (event._dchuiling_checked) return false; + event._dchuiling_checked = true; + var cards = event.getd(); + if (!cards.filterInD("d").length) return false; return true; }, - markColor:[ - ['rgba(241, 42, 42, 0.75)', 'black'], - ['',''], - ['rgba(18, 4, 4, 0.75)', 'rgb(200, 200, 200)'] + markColor: [ + ["rgba(241, 42, 42, 0.75)", "black"], + ["", ""], + ["rgba(18, 4, 4, 0.75)", "rgb(200, 200, 200)"], ], - content:function(){ - 'step 0' - var red=0,black=0; - for(var i=0;i灵'; - for(var player of game.players){ - if(player.marks.dchuiling){ - player.marks.dchuiling.firstChild.style.backgroundColor=bgColor; - player.marks.dchuiling.firstChild.innerHTML=text; + game.broadcastAll(function (ind) { + var bgColor = lib.skill.dchuiling_hint.markColor[ind][0], + text = + ''; + for (var player of game.players) { + if (player.marks.dchuiling) { + player.marks.dchuiling.firstChild.style.backgroundColor = bgColor; + player.marks.dchuiling.firstChild.innerHTML = text; } } - },Math.sign(black-red)+1); + }, Math.sign(black - red) + 1); }, - } + }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)!='card') return; - var len=ui.discardPile.childNodes.length; - if(!len){ - var type=get.type(card); - if(type=='basic'||type=='trick'){ - if(player.getDamagedHp()>0){ - return num+(get.color(card)=='red'?15:10); + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) != "card") return; + var len = ui.discardPile.childNodes.length; + if (!len) { + var type = get.type(card); + if (type == "basic" || type == "trick") { + if (player.getDamagedHp() > 0) { + return num + (get.color(card) == "red" ? 15 : 10); } - return num+10; + return num + 10; } return; } - if(len>40) return; - var red=0,black=0; - for(var i=0;i 40) return; + var red = 0, + black = 0; + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var color = get.color(ui.discardPile.childNodes[i]); + if (color == "red") red++; + if (color == "black") black++; } - if(red==black){ - var type=get.type(card); - if(type=='basic'||type=='trick'){ - if(player.getDamagedHp()>0){ - return num+(get.color(card)=='red'?15:10); + if (red == black) { + var type = get.type(card); + if (type == "basic" || type == "trick") { + if (player.getDamagedHp() > 0) { + return num + (get.color(card) == "red" ? 15 : 10); } - return num+10; + return num + 10; } return; - } - else{ - var color=get.color(card); - if(color=='red'&&redblack) return num+10; + } else { + var color = get.color(card); + if ((color == "red" && red < black) || (color == "black" && red > black)) + return num + 10; } }, - } + }, }, - dcchongxu:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'wood', - derivation:['dctaji','dcqinghuang'], - filterCard:()=>false, - selectCard:[0,1], - prompt:function(){ - return '限定技。你可以失去〖汇灵〗,增加'+Math.min(game.countPlayer(),_status.event.player.countMark('dchuiling'))+'点体力上限,然后获得〖踏寂〗和〖清荒〗。' + dcchongxu: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "wood", + derivation: ["dctaji", "dcqinghuang"], + filterCard: () => false, + selectCard: [0, 1], + prompt: function () { + return ( + "限定技。你可以失去〖汇灵〗,增加" + + Math.min(game.countPlayer(), _status.event.player.countMark("dchuiling")) + + "点体力上限,然后获得〖踏寂〗和〖清荒〗。" + ); }, - filter:function(event,player){ - return player.countMark('dchuiling')>=4; + filter: function (event, player) { + return player.countMark("dchuiling") >= 4; }, - content:function(){ - 'step 0' - player.awakenSkill('dcchongxu'); - player.removeSkills('dchuiling'); - player.gainMaxHp(Math.min(game.countPlayer(),player.countMark('dchuiling'))); - 'step 1' - player.addSkills(['dctaji','dcqinghuang']); + content: function () { + "step 0"; + player.awakenSkill("dcchongxu"); + player.removeSkills("dchuiling"); + player.gainMaxHp(Math.min(game.countPlayer(), player.countMark("dchuiling"))); + "step 1"; + player.addSkills(["dctaji", "dcqinghuang"]); }, - ai:{ - order:function(itemp,player){ - if(player.hasCard(card=>{ - return get.type(card)!='equip'&&player.getUseValue(card)>1; - },'h')) return 12; + ai: { + combo: "dchuiling", + order: function (itemp, player) { + if ( + player.hasCard((card) => { + return get.type(card) != "equip" && player.getUseValue(card) > 1; + }, "h") + ) + return 12; return 0.1; }, - result:{ - player:function(player){ - var count=player.countMark('dchuiling'); - if(count>=game.countPlayer()-1) return 1; - return (count>=6||player.hp<=2)?1:0; - } - } - } + result: { + player: function (player) { + var count = player.countMark("dchuiling"); + if (count >= game.countPlayer() - 1) return 1; + return count >= 6 || player.hp <= 2 ? 1 : 0; + }, + }, + }, }, - dctaji:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dctaji: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - locked:false, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length; + forced: true, + locked: false, + filter: function (event, player) { + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length; }, - content:function(){ - 'step 0' - var evt=trigger.getParent(); - var effects=[ - ['useCard',function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - return current.countDiscardableCards(player,'he')&¤t!=player; - }); - if(!targets.length) event.finish(); - else player.chooseTarget('踏寂:弃置其他角色一张牌',true,(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',targets).set('ai',target=>{ - return get.effect(target,{name:'guohe_copy2'},_status.event.player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target); - player.discardPlayerCard(target,'he',true); - } - }], - ['respond',function(){ - player.draw(); - }], - ['discard',function(){ - player.recover(); - }], - ['other',function(){ - player.addSkill('dctaji_damage'); - player.addMark('dctaji_damage',1,false); - game.log(player,'下一次对其他角色造成的伤害','#g+1'); - }] + content: function () { + "step 0"; + var evt = trigger.getParent(); + var effects = [ + [ + "useCard", + function () { + "step 0"; + var targets = game.filterPlayer((current) => { + return current.countDiscardableCards(player, "he") && current != player; + }); + if (!targets.length) event.finish(); + else + player + .chooseTarget( + "踏寂:弃置其他角色一张牌", + true, + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("targets", targets) + .set("ai", (target) => { + return get.effect( + target, + { name: "guohe_copy2" }, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target); + player.discardPlayerCard(target, "he", true); + } + }, + ], + [ + "respond", + function () { + player.draw(); + }, + ], + [ + "discard", + function () { + player.recover(); + }, + ], + [ + "other", + function () { + player.addSkill("dctaji_damage"); + player.addMark("dctaji_damage", 1, false); + game.log(player, "下一次对其他角色造成的伤害", "#g+1"); + }, + ], ]; - var name=evt.name; - if(trigger.name=='loseAsync') name=evt.type; - var list=['useCard','respond','discard','other']; - if(!list.includes(name)) name='other'; - for(var i=0;i<1+player.countMark('dcqinghuang_add');i++){ - if(!list.length) break; - if(!list.includes(name)) name=list.randomRemove(1)[0]; - if(name=='useCard') list.remove('useCard'); - for(var effect of effects){ - if(effect[0]==name){ + var name = evt.name; + if (trigger.name == "loseAsync") name = evt.type; + var list = ["useCard", "respond", "discard", "other"]; + if (!list.includes(name)) name = "other"; + for (var i = 0; i < 1 + player.countMark("dcqinghuang_add"); i++) { + if (!list.length) break; + if (!list.includes(name)) name = list.randomRemove(1)[0]; + if (name == "useCard") list.remove("useCard"); + for (var effect of effects) { + if (effect[0] == name) { list.remove(name); - var next=game.createEvent('dctaji_'+name); - next.player=player; + var next = game.createEvent("dctaji_" + name); + next.player = player; next.setContent(effect[1]); break; } } } }, - subSkill:{ - damage:{ - trigger:{source:'damageBegin1'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.player!=player; + subSkill: { + damage: { + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return event.player != player; }, - content:function(){ - trigger.num+=player.countMark('dctaji_damage'); - player.removeSkill('dctaji_damage'); + content: function () { + trigger.num += player.countMark("dctaji_damage"); + player.removeSkill("dctaji_damage"); }, - intro:{ - content:'下次对其他角色造成伤害时,此伤害+#', - } - } - } + intro: { + content: "下次对其他角色造成伤害时,此伤害+#", + }, + }, + }, }, - dcqinghuang:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.maxHp>1; + dcqinghuang: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.maxHp > 1; }, - check:function(event,player){ - var num1=player.countCards('h'); - var num2=player.countCards('h',card=>player.hasValueTarget(card)); - var num3=player.getHandcardLimit(); - if(player.isDamaged()){ - return num2>1||num1-num2-num3>0; - } - else{ - return num2>2+Math.max(0,3-player.hp)||player.hp>2&&num1-num2-num3>2; + check: function (event, player) { + var num1 = player.countCards("h"); + var num2 = player.countCards("h", (card) => player.hasValueTarget(card)); + var num3 = player.getHandcardLimit(); + if (player.isDamaged()) { + return num2 > 1 || num1 - num2 - num3 > 0; + } else { + return ( + num2 > 2 + Math.max(0, 3 - player.hp) || (player.hp > 2 && num1 - num2 - num3 > 2) + ); } }, - content:function(){ + content: function () { player.loseMaxHp(); - player.addTempSkill('dcqinghuang_add'); - player.addMark('dcqinghuang_add',1,false); + player.addTempSkill("dcqinghuang_add"); + player.addMark("dcqinghuang_add", 1, false); + }, + ai: { + combo: "dctaji", + }, + subSkill: { + add: { + charlotte: true, + onremove: true, + }, }, - subSkill:{ - add:{ - charlotte:true, - onremove:true, - } - } }, //孟节 - dcyinlu:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dcyinlu: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - derivation:['dcyinlu_lequan','dcyinlu_huoxi','dcyinlu_zhangqi','dcyinlu_yunxiang'], - global:['dcyinlu_lequan','dcyinlu_huoxi','dcyinlu_zhangqi','dcyinlu_yunxiang'], - group:'dcyinlu_move', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + derivation: ["dcyinlu_lequan", "dcyinlu_huoxi", "dcyinlu_zhangqi", "dcyinlu_yunxiang"], + global: ["dcyinlu_lequan", "dcyinlu_huoxi", "dcyinlu_zhangqi", "dcyinlu_yunxiang"], + group: "dcyinlu_move", + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - hasMark:function(target){ - return lib.skill.dcyinlu.derivation.some(i=>target.hasMark(i)); + hasMark: function (target) { + return lib.skill.dcyinlu.derivation.some((i) => target.hasMark(i)); }, - content:function(){ - 'step 0' - event.marks=lib.skill.dcyinlu.derivation.slice(0,3); - if(game.countPlayer()<=2) event.goto(3); - 'step 1' - player.chooseTarget('引路:令三名角色分别获得〖引路〗标记',true,3).set('targetprompt',()=>{ - return get.translation(lib.skill.dcyinlu.derivation[ui.selected.targets.length-1]); - }).set('complexSelect',true).set('ai',target=>{ - var player=_status.event.player; - if(ui.selected.targets.length==2) return get.effect(target,{name:'losehp'},player,player); - return get.attitude(player,target); - }); - 'step 2' - if(result.bool){ - var targets=result.targets; + content: function () { + "step 0"; + event.marks = lib.skill.dcyinlu.derivation.slice(0, 3); + if (game.countPlayer() <= 2) event.goto(3); + "step 1"; + player + .chooseTarget("引路:令三名角色分别获得〖引路〗标记", true, 3) + .set("targetprompt", () => { + return get.translation( + lib.skill.dcyinlu.derivation[ui.selected.targets.length - 1] + ); + }) + .set("complexSelect", true) + .set("ai", (target) => { + var player = _status.event.player; + if (ui.selected.targets.length == 2) + return get.effect(target, { name: "losehp" }, player, player); + return get.attitude(player, target); + }); + "step 2"; + if (result.bool) { + var targets = result.targets; player.line(targets); - for(var i=0;i
              【'+ - get.translation(mark)+'】
              '+lib.translate[mark+'_info']+'
              ']) + "step 3"; + player.logSkill("dcyinlu", game.players); + var list = []; + for (var mark of event.marks) { + list.push([ + mark, + '", + ]); } - var target=game.filterPlayer(i=>i!=player)[0]; - if(!game.hasPlayer(current=>current!=player)) target=player; - event.target=target; - player.chooseButton(['引路:令'+get.translation(target)+'获得2枚〖引路〗标记',[list,'textbutton']]).set('ai',button=>{ - var mark=button.link; - if(mark=='dcyinlu_lequan') return 9; - if(mark=='dcyinlu_zhangqi') return 10; - return 8; - }).set('forced',true).set('selectButton',2).set('forcebutton',true); - 'step 4' - if(result.bool){ - var marks=result.links; - for(var mark of marks) target.addMark(mark,1); + var target = game.filterPlayer((i) => i != player)[0]; + if (!game.hasPlayer((current) => current != player)) target = player; + event.target = target; + player + .chooseButton([ + "引路:令" + get.translation(target) + "获得2枚〖引路〗标记", + [list, "textbutton"], + ]) + .set("ai", (button) => { + var mark = button.link; + if (mark == "dcyinlu_lequan") return 9; + if (mark == "dcyinlu_zhangqi") return 10; + return 8; + }) + .set("forced", true) + .set("selectButton", 2) + .set("forcebutton", true); + "step 4"; + if (result.bool) { + var marks = result.links; + for (var mark of marks) target.addMark(mark, 1); event.marks.removeArray(marks); - for(var mark of event.marks) player.addMark(mark,1); + for (var mark of event.marks) player.addMark(mark, 1); } - 'step 5' - player.addMark('dcyinlu_yunxiang',1); - player.addMark('dcyinlu_xiang',1); - game.log(player,'获得了1点芸香值'); + "step 5"; + player.addMark("dcyinlu_yunxiang", 1); + player.addMark("dcyinlu_xiang", 1); + game.log(player, "获得了1点芸香值"); }, - subSkill:{ - move:{ - audio:'dcyinlu', - trigger:{ - player:'phaseZhunbeiBegin', - global:'die', + subSkill: { + move: { + audio: "dcyinlu", + trigger: { + player: "phaseZhunbeiBegin", + global: "die", }, - direct:true, - filter:function(event,player){ - if(event.name=='die'){ + direct: true, + filter: function (event, player) { + if (event.name == "die") { return lib.skill.dcyinlu.hasMark(event.player); } - return game.hasPlayer(current=>{ + return game.hasPlayer((current) => { return lib.skill.dcyinlu.hasMark(current); - }) + }); }, - content:function(){ - 'step 0' - if(trigger.name=='die'){ - var marks=lib.skill.dcyinlu.derivation.filter(mark=>trigger.player.hasMark(mark)); - event.marks=marks; + content: function () { + "step 0"; + if (trigger.name == "die") { + var marks = lib.skill.dcyinlu.derivation.filter((mark) => + trigger.player.hasMark(mark) + ); + event.marks = marks; event.goto(3); + } else { + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + player + .chooseTarget( + get.prompt("dcyinlu_move"), + "移动一名角色的〖引路〗标记", + 2, + (card, player, target) => { + if (ui.selected.targets.length == 0) + return lib.skill.dcyinlu.hasMark(target); + return true; + } + ) + .set("ai", (target) => { + var player = _status.event.player; + if (ui.selected.targets.length == 0) { + var owned = lib.skill.dcyinlu.derivation.filter((i) => + target.hasMark(i) + ); + var att = get.attitude(player, target); + if (att > 0) { + if (owned.includes("dcyinlu_zhangqi")) + return target.hasCard({ suit: "spade" }, "he") ? 5 : 10; + if ( + owned.includes("dcyinlu_lequan") && + target.isHealthy() && + game.hasPlayer((current) => { + return ( + current != target && + get.recoverEffect(current, player, player) > 0 + ); + }) + ) + return 2; + return 0; + } + if (att < 0) { + if (owned.some((i) => i != "dcyinlu_zhangqi")) return 8; + return 0; + } + if ( + owned.includes("dcyinlu_zhangqi") && + game.hasPlayer((current) => { + return ( + current != target && + get.effect( + current, + { name: "losehp" }, + player, + player + ) > 0 + ); + }) + ) + return 3; + return 1; + } else { + var targetx = ui.selected.targets[0]; + var att = get.attitude(player, targetx), + att2 = get.attitude(player, target); + var owned = lib.skill.dcyinlu.derivation.filter((i) => + targetx.hasMark(i) + ); + if (att > 0) { + if (owned.includes("dcyinlu_zhangqi")) return -att2; + if (owned.includes("dcyinlu_lequan")) + return get.recoverEffect(target, player, player); + } else if (att < 0) { + if (owned.some((i) => i != "dcyinlu_zhangqi")) return att2; + } else { + if (owned.includes("dcyinlu_zhangqi")) + return get.effect( + target, + { name: "losehp" }, + player, + player + ); + return att2; + } + } + return Math.random(); + }) + .set("complexTarget", true); } - else{ - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseTarget(get.prompt('dcyinlu_move'),'移动一名角色的〖引路〗标记',2,(card,player,target)=>{ - if(ui.selected.targets.length==0) return lib.skill.dcyinlu.hasMark(target); - return true; - }).set('ai',target=>{ - var player=_status.event.player; - if(ui.selected.targets.length==0){ - var owned=lib.skill.dcyinlu.derivation.filter(i=>target.hasMark(i)); - var att=get.attitude(player,target); - if(att>0){ - if(owned.includes('dcyinlu_zhangqi')) return target.hasCard({suit:'spade'},'he')?5:10; - if(owned.includes('dcyinlu_lequan')&&target.isHealthy()&&game.hasPlayer(current=>{ - return current!=target&&get.recoverEffect(current,player,player)>0; - })) return 2; - return 0; - } - if(att<0){ - if(owned.some(i=>i!='dcyinlu_zhangqi')) return 8; - return 0; - } - if(owned.includes('dcyinlu_zhangqi')&&game.hasPlayer(current=>{ - return current!=target&&get.effect(current,{name:'losehp'},player,player)>0; - })) return 3; - return 1; - } - else{ - var targetx=ui.selected.targets[0]; - var att=get.attitude(player,targetx),att2=get.attitude(player,target); - var owned=lib.skill.dcyinlu.derivation.filter(i=>targetx.hasMark(i)); - if(att>0){ - if(owned.includes('dcyinlu_zhangqi')) return -att2; - if(owned.includes('dcyinlu_lequan')) return get.recoverEffect(target,player,player); - } - else if(att<0){ - if(owned.some(i=>i!='dcyinlu_zhangqi')) return att2; - } - else{ - if(owned.includes('dcyinlu_zhangqi')) return get.effect(target,{name:'losehp'},player,player); - return att2; - } - } - return Math.random(); - }).set('complexTarget', true); - } - 'step 1' - if(result.bool){ - var marks=lib.skill.dcyinlu.derivation; - var targets=result.targets,owned=marks.filter(mark=>targets[0].hasMark(mark)); - event.targets=targets; - if(owned.length==1) event._result={bool:true,control:owned[0]}; - else{ - player.chooseControl(owned).set('prompt','引路:选择要移动'+get.translation(targets[0])+'的标记').set('choiceList',owned.map(mark=>{ - return '
              【'+get.translation(mark)+'】
              '+lib.translate[mark+'_info']+'
              '; - })).set('displayIndex',false).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var att=get.attitude(player,targets[0]),att2=get.attitude(player,targets[1]); - if(att>0){ - if(owned.includes('dcyinlu_zhangqi')&&att2<0) return 'dcyinlu_zhangqi'; - if(owned.includes('dcyinlu_lequan')&&att2>0) return 'dcyinlu_lequan'; - } - else if(att<0){ - var marksx=owned.filter(i=>i!='dcyinlu_zhangqi'); - if(marksx.length&&att2>0) return marksx[0]; - return owned[0]; - } - else{ - if(owned.includes('dcyinlu_zhangqi')) return 'dcyinlu_zhangqi'; - } - if(owned.length>1) owned.remove('dcyinlu_zhangqi'); - return owned[0]; - }()); + "step 1"; + if (result.bool) { + var marks = lib.skill.dcyinlu.derivation; + var targets = result.targets, + owned = marks.filter((mark) => targets[0].hasMark(mark)); + event.targets = targets; + if (owned.length == 1) event._result = { bool: true, control: owned[0] }; + else { + player + .chooseControl(owned) + .set( + "prompt", + "引路:选择要移动" + get.translation(targets[0]) + "的标记" + ) + .set( + "choiceList", + owned.map((mark) => { + return ( + '
              【' + + get.translation(mark) + + "】
              " + + lib.translate[mark + "_info"] + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var att = get.attitude(player, targets[0]), + att2 = get.attitude(player, targets[1]); + if (att > 0) { + if (owned.includes("dcyinlu_zhangqi") && att2 < 0) + return "dcyinlu_zhangqi"; + if (owned.includes("dcyinlu_lequan") && att2 > 0) + return "dcyinlu_lequan"; + } else if (att < 0) { + var marksx = owned.filter((i) => i != "dcyinlu_zhangqi"); + if (marksx.length && att2 > 0) return marksx[0]; + return owned[0]; + } else { + if (owned.includes("dcyinlu_zhangqi")) + return "dcyinlu_zhangqi"; + } + if (owned.length > 1) owned.remove("dcyinlu_zhangqi"); + return owned[0]; + })() + ); } - } - else{ - if(_status.connectMode) game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + } else { + if (_status.connectMode) + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); event.finish(); } - 'step 2' - if(_status.connectMode) game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - var mark=result.control,count=targets[0].countMark(mark); - player.logSkill('dcyinlu_move',targets,false); - player.line2(targets,mark=='dcyinlu_zhangqi'?'fire':'green'); - targets[0].removeMark(mark,count); - targets[1].addMark(mark,count); + "step 2"; + if (_status.connectMode) + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + var mark = result.control, + count = targets[0].countMark(mark); + player.logSkill("dcyinlu_move", targets, false); + player.line2(targets, mark == "dcyinlu_zhangqi" ? "fire" : "green"); + targets[0].removeMark(mark, count); + targets[1].addMark(mark, count); event.finish(); - 'step 3' - player.chooseTarget('引路:是否转移“'+get.translation(event.marks[0])+'”标记?').set('ai',target=>{ - var player=_status.event.player,mark=_status.event.mark; - if(mark=='dcyinlu_zhangqi') return get.effect(target,{name:'losehp'},player,player)+0.1; - if(mark=='dcyinlu_lequan') return get.recoverEffect(target,player,player)+get.attitude(player,target)/5; - return get.attitude(player,target); - }).set('mark',event.marks[0]); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcyinlu_move',target); - var count=trigger.player.countMark(event.marks[0]); - trigger.player.removeMark(event.marks[0],count,false); - target.addMark(event.marks[0],count); + "step 3"; + player + .chooseTarget("引路:是否转移“" + get.translation(event.marks[0]) + "”标记?") + .set("ai", (target) => { + var player = _status.event.player, + mark = _status.event.mark; + if (mark == "dcyinlu_zhangqi") + return get.effect(target, { name: "losehp" }, player, player) + 0.1; + if (mark == "dcyinlu_lequan") + return ( + get.recoverEffect(target, player, player) + + get.attitude(player, target) / 5 + ); + return get.attitude(player, target); + }) + .set("mark", event.marks[0]); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcyinlu_move", target); + var count = trigger.player.countMark(event.marks[0]); + trigger.player.removeMark(event.marks[0], count, false); + target.addMark(event.marks[0], count); } - 'step 5' + "step 5"; event.marks.shift(); - if(event.marks.length) event.goto(3); - } + if (event.marks.length) event.goto(3); + }, }, - lequan:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - charlotte:true, - filter:function(event,player){ - return player.hasMark('dcyinlu_lequan')&&game.hasPlayer(current=>current.hasSkill('dcyinlu')); + lequan: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + charlotte: true, + filter: function (event, player) { + return ( + player.hasMark("dcyinlu_lequan") && + game.hasPlayer((current) => current.hasSkill("dcyinlu")) + ); }, - marktext:'乐', - intro:{ - name:'乐泉', - name2:'乐泉', - markcount:()=>0, - content:'结束阶段,你可以弃置一张♦牌并回复1点体力。' + marktext: "乐", + intro: { + name: "乐泉", + name2: "乐泉", + markcount: () => 0, + content: "结束阶段,你可以弃置一张♦牌并回复1点体力。", }, - content:function(){ - 'step 0' - player.chooseToDiscard('乐泉:是否弃置一张♦牌并回复1点体力?',{suit:'diamond'},'he').set('ai',card=>{ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('logSkill','dcyinlu_lequan').set('goon',get.recoverEffect(player,player)); - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard( + "乐泉:是否弃置一张♦牌并回复1点体力?", + { suit: "diamond" }, + "he" + ) + .set("ai", (card) => { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("logSkill", "dcyinlu_lequan") + .set("goon", get.recoverEffect(player, player)); + "step 1"; + if (result.bool) { player.recover(); } - } + }, }, - huoxi:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - charlotte:true, - filter:function(event,player){ - return player.hasMark('dcyinlu_huoxi')&&game.hasPlayer(current=>current.hasSkill('dcyinlu')); + huoxi: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + charlotte: true, + filter: function (event, player) { + return ( + player.hasMark("dcyinlu_huoxi") && + game.hasPlayer((current) => current.hasSkill("dcyinlu")) + ); }, - marktext:'藿', - intro:{ - name:'藿溪', - name2:'藿溪', - markcount:()=>0, - content:'结束阶段,你可以弃置一张♥牌并摸两张牌。' + marktext: "藿", + intro: { + name: "藿溪", + name2: "藿溪", + markcount: () => 0, + content: "结束阶段,你可以弃置一张♥牌并摸两张牌。", }, - content:function(){ - 'step 0' - player.chooseToDiscard('藿溪:是否弃置一张♥牌并摸两张牌?',{suit:'heart'},'he').set('ai',card=>{ - return 6-get.value(card); - }).set('logSkill','dcyinlu_huoxi'); - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard("藿溪:是否弃置一张♥牌并摸两张牌?", { suit: "heart" }, "he") + .set("ai", (card) => { + return 6 - get.value(card); + }) + .set("logSkill", "dcyinlu_huoxi"); + "step 1"; + if (result.bool) { player.draw(2); } }, }, - zhangqi:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - direct:true, - charlotte:true, - filter:function(event,player){ - return player.hasMark('dcyinlu_zhangqi')&&game.hasPlayer(current=>current.hasSkill('dcyinlu')); + zhangqi: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + direct: true, + charlotte: true, + filter: function (event, player) { + return ( + player.hasMark("dcyinlu_zhangqi") && + game.hasPlayer((current) => current.hasSkill("dcyinlu")) + ); }, - marktext:'瘴', - intro:{ - name:'瘴气', - name2:'瘴气', - markcount:()=>0, - content:'锁定技。结束阶段,你须弃置一张♠牌,否则失去1点体力。' + marktext: "瘴", + intro: { + name: "瘴气", + name2: "瘴气", + markcount: () => 0, + content: "锁定技。结束阶段,你须弃置一张♠牌,否则失去1点体力。", }, - content:function(){ - 'step 0' - player.chooseToDiscard('瘴气:弃置一张♠牌,或失去1点体力',{suit:'spade'},'he').set('ai',card=>{ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('logSkill','dcyinlu_zhangqi').set('goon',get.effect(player,{name:'losehp'},player)<0); - 'step 1' - if(!result.bool){ - player.logSkill('dcyinlu_zhangqi'); + content: function () { + "step 0"; + player + .chooseToDiscard("瘴气:弃置一张♠牌,或失去1点体力", { suit: "spade" }, "he") + .set("ai", (card) => { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("logSkill", "dcyinlu_zhangqi") + .set("goon", get.effect(player, { name: "losehp" }, player) < 0); + "step 1"; + if (!result.bool) { + player.logSkill("dcyinlu_zhangqi"); player.loseHp(); } - } - }, - yunxiang:{ - trigger:{player:['phaseJieshuBegin','damageBegin4']}, - direct:true, - charlotte:true, - filter:function(event,player){ - if(!game.hasPlayer(current=>current.hasSkill('dcyinlu'))) return false; - if(event.name=='phaseJieshu') return player.hasMark('dcyinlu_yunxiang'); - return player.hasMark('dcyinlu_yunxiang')&&player.hasMark('dcyinlu_xiang'); }, - onremove:function(player){ + }, + yunxiang: { + trigger: { player: ["phaseJieshuBegin", "damageBegin4"] }, + direct: true, + charlotte: true, + filter: function (event, player) { + if (!game.hasPlayer((current) => current.hasSkill("dcyinlu"))) return false; + if (event.name == "phaseJieshu") return player.hasMark("dcyinlu_yunxiang"); + return player.hasMark("dcyinlu_yunxiang") && player.hasMark("dcyinlu_xiang"); + }, + onremove: function (player) { delete player.storage.dcyinlu_xiang; }, - marktext:'芸', - intro:{ - name:'芸香', - name2:'芸香', - markcount:function(storage,player){ - return player.countMark('dcyinlu_xiang'); + marktext: "芸", + intro: { + name: "芸香", + name2: "芸香", + markcount: function (storage, player) { + return player.countMark("dcyinlu_xiang"); }, - content:function(storage,player){ - return '①结束阶段,你可以弃置一张♣牌,获得1点“芸香”值。②当你受到伤害时,你可以扣减所有“芸香”值,减少等量的伤害。
            • 当前芸香值:'+player.countMark('dcyinlu_xiang'); + content: function (storage, player) { + return ( + "①结束阶段,你可以弃置一张♣牌,获得1点“芸香”值。②当你受到伤害时,你可以扣减所有“芸香”值,减少等量的伤害。
            • 当前芸香值:" + + player.countMark("dcyinlu_xiang") + ); + }, + }, + content: function () { + "step 0"; + if (trigger.name == "phaseJieshu") { + player + .chooseToDiscard( + "芸香:是否弃置一张♣牌,获得1枚“香”?", + { suit: "club" }, + "he" + ) + .set("ai", (card) => { + return ( + 6 - + get.value(card) + + 2.5 * _status.event.player.countMark("dcyinlu_xiang") + ); + }) + .set("logSkill", "dcyinlu_yunxiang"); + } else { + player + .chooseBool( + "芸香:是否移去所有“香”,令此伤害-" + + player.countMark("dcyinlu_xiang") + + "?" + ) + .set("ai", () => { + return _status.event.bool; + }) + .set("bool", get.damageEffect(player, trigger.source, player) < 0); + } + "step 1"; + if (result.bool) { + if (trigger.name == "phaseJieshu") { + player.addMark("dcyinlu_xiang", 1, false); + game.log(player, "获得了1点芸香值"); + } else { + player.logSkill("dcyinlu_yunxiang"); + var num = player.countMark("dcyinlu_xiang"); + player.removeMark("dcyinlu_xiang", num, false); + game.log(player, "扣减了", num, "点芸香值"); + trigger.num = Math.max(0, trigger.num - num); + } } }, - content:function(){ - 'step 0' - if(trigger.name=='phaseJieshu'){ - player.chooseToDiscard('芸香:是否弃置一张♣牌,获得1枚“香”?',{suit:'club'},'he').set('ai',card=>{ - return 6-get.value(card)+2.5*_status.event.player.countMark('dcyinlu_xiang'); - }).set('logSkill','dcyinlu_yunxiang'); - } - else{ - player.chooseBool('芸香:是否移去所有“香”,令此伤害-'+player.countMark('dcyinlu_xiang')+'?').set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.damageEffect(player,trigger.source,player)<0); - } - 'step 1' - if(result.bool){ - if(trigger.name=='phaseJieshu'){ - player.addMark('dcyinlu_xiang',1,false); - game.log(player,'获得了1点芸香值'); - } - else{ - player.logSkill('dcyinlu_yunxiang'); - var num=player.countMark('dcyinlu_xiang'); - player.removeMark('dcyinlu_xiang',num,false); - game.log(player,'扣减了',num,'点芸香值'); - trigger.num=Math.max(0,trigger.num-num); - } - } - } - } - } + }, + }, }, - dcyouqi:{ - audio:2, - trigger:{global:'loseAfter'}, - filter:function(event,player){ - if(event.getParent(3).name.indexOf('dcyinlu_')!=0||player==event.player) return false; + dcyouqi: { + audio: 2, + trigger: { global: "loseAfter" }, + filter: function (event, player) { + if (event.getParent(3).name.indexOf("dcyinlu_") != 0 || player == event.player) + return false; return true; }, - derivation:'dcyouqi_faq', - direct:true, - forced:true, - content:function(){ - if(Math.random()<1.25-0.25*get.distance(player,trigger.player)||get.isLuckyStar(player)){ - player.logSkill('dcyouqi'); - player.gain(trigger.cards.filterInD('d'),'gain2'); + derivation: "dcyouqi_faq", + direct: true, + forced: true, + content: function () { + if ( + Math.random() < 1.25 - 0.25 * get.distance(player, trigger.player) || + get.isLuckyStar(player) + ) { + player.logSkill("dcyouqi"); + player.gain(trigger.cards.filterInD("d"), "gain2"); } }, + ai: { + combo: "dcyinlu", + }, }, //孙资刘放 - dcqinshen:{ - audio:2, - trigger:{player:'phaseDiscardEnd'}, - frequent:true, - prompt2:function(){ - return '摸'+get.cnNumber(lib.skill.dcqinshen.getNum())+'张牌'; + dcqinshen: { + audio: 2, + trigger: { player: "phaseDiscardEnd" }, + frequent: true, + prompt2: function () { + return "摸" + get.cnNumber(lib.skill.dcqinshen.getNum()) + "张牌"; }, - getNum:function(){ - var list=lib.suit.slice(); - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='lose'&&evt.name!='cardsDiscard') return false; - if(evt.name=='lose'&&evt.position!=ui.discardPile) return false; - for(var card of evt.cards) list.remove(get.suit(card,false)); + getNum: function () { + var list = lib.suit.slice(); + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" && evt.name != "cardsDiscard") return false; + if (evt.name == "lose" && evt.position != ui.discardPile) return false; + for (var card of evt.cards) list.remove(get.suit(card, false)); }); return list.length; }, - filter:function(event,player){ - return lib.skill.dcqinshen.getNum()>0; + filter: function (event, player) { + return lib.skill.dcqinshen.getNum() > 0; }, - content:function(){ + content: function () { player.draw(lib.skill.dcqinshen.getNum()); - } + }, }, - dcweidang:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, + dcweidang: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, /** * @deprecated */ - getLength:card=>get.cardNameLength(card), - direct:true, - filter:function(event,player){ - var num=lib.skill.dcqinshen.getNum(); - return event.player!=player&&(_status.connectMode?player.countCards('he'):player.hasCard(card=>get.cardNameLength(card)==num,'he')); + getLength: (card) => get.cardNameLength(card), + direct: true, + filter: function (event, player) { + var num = lib.skill.dcqinshen.getNum(); + return ( + event.player != player && + (_status.connectMode + ? player.countCards("he") + : player.hasCard((card) => get.cardNameLength(card) == num, "he")) + ); }, - content:function(){ - 'step 0' - var num=lib.skill.dcqinshen.getNum(); - event.num=num; - player.chooseCard(get.prompt('dcweidang'),'将一张字数为'+num+'的牌置于牌堆底,然后获得一张字数为'+num+'的牌。若你能使用此牌,你使用之。','he',(card,player,target)=>{ - return get.cardNameLength(card)==_status.event.num; - }).set('num',num).set('ai',card=>{ - return 5-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('dcweidang'), - player.lose(result.cards[0],ui.cardPile); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },player); + content: function () { + "step 0"; + var num = lib.skill.dcqinshen.getNum(); + event.num = num; + player + .chooseCard( + get.prompt("dcweidang"), + "将一张字数为" + + num + + "的牌置于牌堆底,然后获得一张字数为" + + num + + "的牌。若你能使用此牌,你使用之。", + "he", + (card, player, target) => { + return get.cardNameLength(card) == _status.event.num; + } + ) + .set("num", num) + .set("ai", (card) => { + return 5 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("dcweidang"), player.lose(result.cards[0], ui.cardPile); + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, player); game.delayx(); - } - else event.finish(); - 'step 2' - var card=get.cardPile(cardx=>get.cardNameLength(cardx)==num); - if(card){ - player.gain(card,'gain2'); - if(player.hasUseTarget(card)){ - player.chooseUseTarget(card,true); + } else event.finish(); + "step 2"; + var card = get.cardPile((cardx) => get.cardNameLength(cardx) == num); + if (card) { + player.gain(card, "gain2"); + if (player.hasUseTarget(card)) { + player.chooseUseTarget(card, true); } } - } + }, }, //三袁 - dcneifa:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - content:function(){ - 'step 0' + dcneifa: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + content: function () { + "step 0"; player.draw(3); - player.chooseToDiscard(true,'he').set('ai',function(cardx){ - var player=_status.event.player; - var num=0; - var hs=player.getCards('h'); - var muniu=player.getEquip('muniu'); - if(muniu&&muniu.cards) hs=hs.concat(muniu.cards); - if(get.type(cardx)=='basic'){ - var shas=hs.filter(function(card){ - return card!=cardx&&get.name(card,player)=='sha'&&player.hasValueTarget(card,false); + player.chooseToDiscard(true, "he").set("ai", function (cardx) { + var player = _status.event.player; + var num = 0; + var hs = player.getCards("h"); + var muniu = player.getEquip("muniu"); + if (muniu && muniu.cards) hs = hs.concat(muniu.cards); + if (get.type(cardx) == "basic") { + var shas = hs.filter(function (card) { + return ( + card != cardx && + get.name(card, player) == "sha" && + player.hasValueTarget(card, false) + ); }); - var numx=player.countCards('h',function(card){ - return get.type2(card,player)=='trick'; + var numx = player.countCards("h", function (card) { + return get.type2(card, player) == "trick"; }); - num+=Math.min(numx,Math.max(0,shas.length-player.getCardUsable('sha')))*0.65; - num+=Math.min(player.getCardUsable('sha')+numx,shas.filter(function(card){ - return game.countPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })>1; - }).length)*1.1; - var taos=Math.min(player.maxHp-player.hp,hs.filter(function(card){ - return cardx!=card&&get.name(card,player)=='tao'; - }).length); - num+=taos*player.getDamagedHp()*1.2; - } - else if(get.type2(cardx)=='trick'){ - var numx=Math.sqrt(Math.min(5,player.countCards('h',function(card){ - return get.type(card,player)=='basic'; - }))); - num+=hs.filter(function(card){ - return card!=cardx&&get.type2(card)=='trick'&&player.hasValueTarget(card); - }).length*0.65; - } - else num=4; - return num*1.5-get.value(cardx); + num += + Math.min(numx, Math.max(0, shas.length - player.getCardUsable("sha"))) * 0.65; + num += + Math.min( + player.getCardUsable("sha") + numx, + shas.filter(function (card) { + return ( + game.countPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) > 1 + ); + }).length + ) * 1.1; + var taos = Math.min( + player.maxHp - player.hp, + hs.filter(function (card) { + return cardx != card && get.name(card, player) == "tao"; + }).length + ); + num += taos * player.getDamagedHp() * 1.2; + } else if (get.type2(cardx) == "trick") { + var numx = Math.sqrt( + Math.min( + 5, + player.countCards("h", function (card) { + return get.type(card, player) == "basic"; + }) + ) + ); + num += + hs.filter(function (card) { + return ( + card != cardx && + get.type2(card) == "trick" && + player.hasValueTarget(card) + ); + }).length * 0.65; + } else num = 4; + return num * 1.5 - get.value(cardx); }); - 'step 1' - if(result.bool&&result.cards&&result.cards.length&&get.type(result.cards[0])!='equip'){ - var name=get.type(result.cards[0])=='basic'?'dcneifa_basic':'dcneifa_trick'; - player.addTempSkill(name,'phaseUseAfter'); - var num=Math.min(5,player.countCards('h',function(cardx){ - var type=get.type(cardx,player); - return (name=='dcneifa_basic')!=(type=='basic')&&type!='equip'; - })); - if(num>0) player.addMark(name,num,false); - else player.storage[name]=0; + "step 1"; + if ( + result.bool && + result.cards && + result.cards.length && + get.type(result.cards[0]) != "equip" + ) { + var name = get.type(result.cards[0]) == "basic" ? "dcneifa_basic" : "dcneifa_trick"; + player.addTempSkill(name, "phaseUseAfter"); + var num = Math.min( + 5, + player.countCards("h", function (cardx) { + var type = get.type(cardx, player); + return (name == "dcneifa_basic") != (type == "basic") && type != "equip"; + }) + ); + if (num > 0) player.addMark(name, num, false); + else player.storage[name] = 0; } }, - ai:{ - threaten:2.33, + ai: { + threaten: 2.33, }, }, - dcneifa_basic:{ - mark:true, - marktext:'伐', - onremove:true, - intro:{ - name:'内伐 - 基本牌', - content:'本回合内不能使用锦囊牌,使用【杀】选择目标时可以额外指定一个目标且使用【杀】的目标次数上限+#。', + dcneifa_basic: { + mark: true, + marktext: "伐", + onremove: true, + intro: { + name: "内伐 - 基本牌", + content: + "本回合内不能使用锦囊牌,使用【杀】选择目标时可以额外指定一个目标且使用【杀】的目标次数上限+#。", }, - mod:{ - cardEnabled:function(card,player){ - if(get.type(card,'trick')=='trick') return false; + mod: { + cardEnabled: function (card, player) { + if (get.type(card, "trick") == "trick") return false; }, - cardSavable:function(card,player){ - if(get.type(card,'trick')=='trick') return false; + cardSavable: function (card, player) { + if (get.type(card, "trick") == "trick") return false; }, - cardUsable:function(card,player,num){ - if(card.name=='sha'){ - return num+player.countMark('dcneifa_basic'); + cardUsable: function (card, player, num) { + if (card.name == "sha") { + return num + player.countMark("dcneifa_basic"); } }, }, - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current,false); + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current, false); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('dcneifa'),'为'+get.translation(trigger.card)+'额外指定一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target,false); - }).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.delayx(); - event.targets=result.targets; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("dcneifa"), + "为" + get.translation(trigger.card) + "额外指定一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target, false) + ); + } + ) + .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.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - player.logSkill('dcneifa',event.targets); + "step 2"; + player.logSkill("dcneifa", event.targets); trigger.targets.addArray(event.targets); }, }, - dcneifa_trick:{ - trigger:{player:'useCard2'}, - direct:true, - mark:true, - marktext:'伐', - onremove:true, - mod:{ - cardEnabled:function(card,player){ - if(get.type(card)=='basic') return false; + dcneifa_trick: { + trigger: { player: "useCard2" }, + direct: true, + mark: true, + marktext: "伐", + onremove: true, + mod: { + cardEnabled: function (card, player) { + if (get.type(card) == "basic") return false; }, - cardSavable:function(card,player){ - if(get.type(card)=='basic') return false; + cardSavable: function (card, player) { + if (get.type(card) == "basic") return false; }, }, - intro:{ - name:'内伐 - 锦囊牌', - content:'本回合内不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标。' + intro: { + name: "内伐 - 锦囊牌", + content: "本回合内不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标。", }, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(event.targets&&event.targets.length>0) return true; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })){ + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + if (event.targets && event.targets.length > 0) return true; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加或减少一个目标' - player.chooseTarget(get.prompt('dcneifa'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return true; - return lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加或减少一个目标"; + player + .chooseTarget(get.prompt("dcneifa"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return true; + return lib.filter.targetEnabled2(_status.event.card, player, target); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('dcneifa',event.targets); - if(trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets); + "step 2"; + if (event.targets) { + player.logSkill("dcneifa", event.targets); + if (trigger.targets.includes(event.targets[0])) + trigger.targets.removeArray(event.targets); else trigger.targets.addArray(event.targets); } - } + }, }, //桥蕤 - dcaishou:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.hasCard(card=>card.hasGaintag('dcaishou_tag'),'h'); + dcaishou: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.hasCard((card) => card.hasGaintag("dcaishou_tag"), "h"); }, - forced:true, - locked:false, - group:['dcaishou_draw','dcaishou_lose'], - subfrequent:['draw'], - content:function(){ - 'step 0' - player.discard(player.getCards('h',card=>card.hasGaintag('dcaishou_tag'))); - 'step 1' - var len=0; - player.getHistory('lose',evt=>{ - if(evt.getParent(2)==event) len+=evt.cards.length; + forced: true, + locked: false, + group: ["dcaishou_draw", "dcaishou_lose"], + subfrequent: ["draw"], + content: function () { + "step 0"; + player.discard(player.getCards("h", (card) => card.hasGaintag("dcaishou_tag"))); + "step 1"; + var len = 0; + player.getHistory("lose", (evt) => { + if (evt.getParent(2) == event) len += evt.cards.length; }); - if(len>Math.max(0,player.hp)&&player.maxHp<9){ + if (len > Math.max(0, player.hp) && player.maxHp < 9) { player.gainMaxHp(); } }, - subSkill:{ - draw:{ - audio:'dcaishou', - trigger:{player:'phaseJieshuBegin'}, - frequent:function(event,player){ - return player.maxHp>1; + subSkill: { + draw: { + audio: "dcaishou", + trigger: { player: "phaseJieshuBegin" }, + frequent: function (event, player) { + return player.maxHp > 1; }, - prompt2:function(event,player){ - return '摸'+get.cnNumber(player.maxHp)+'张牌,称为“隘”'; + prompt2: function (event, player) { + return "摸" + get.cnNumber(player.maxHp) + "张牌,称为“隘”"; }, - check:function(event,player){ - return player.maxHp>1; + check: function (event, player) { + return player.maxHp > 1; + }, + content: function () { + player.draw(player.maxHp).gaintag = ["dcaishou_tag"]; }, - content:function(){ - player.draw(player.maxHp).gaintag=['dcaishou_tag']; - } }, - lose:{ - audio:'dcaishou', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + lose: { + audio: "dcaishou", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - locked:false, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.length||player.hasCard(card=>card.hasGaintag('dcaishou_tag'),'h')) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dcaishou_tag')) return true; + forced: true, + locked: false, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + var evt = event.getl(player); + if ( + !evt || + !evt.hs || + !evt.hs.length || + player.hasCard((card) => card.hasGaintag("dcaishou_tag"), "h") + ) + return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dcaishou_tag")) return true; } return false; } - return player.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcaishou_tag')) return true; + return player.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcaishou_tag")) return true; } return false; }); }, - content:function(){ + content: function () { player.loseMaxHp(); - } + }, }, - } - }, - dcsaowei:{ - audio:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.player!=player&&event.card.name=='sha'&&event.targets.length&&!event.targets.includes(player)&& - event.targets.every(current=>player.inRange(current)&¤t.isIn())&&player.hasCard(card=>card.hasGaintag('dcaishou_tag'),'h'); }, - direct:true, - content:function(){ - 'step 0' + }, + dcsaowei: { + audio: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + event.player != player && + event.card.name == "sha" && + event.targets.length && + !event.targets.includes(player) && + event.targets.every((current) => player.inRange(current) && current.isIn()) && + player.hasCard((card) => card.hasGaintag("dcaishou_tag"), "h") + ); + }, + direct: true, + content: function () { + "step 0"; player.chooseCardTarget({ - position:'hs', - prompt:get.prompt('dcsaowei'), - prompt2:'将一张“隘”当做【杀】对'+get.translation(trigger.targets)+'使用', - targets:trigger.targets, - filterCard:function(card,player){ - if(get.itemtype(card)=='card'&&!card.hasGaintag('dcaishou_tag')) return false; - return _status.event.targets.every(current=>player.canUse(get.autoViewAs({name:'sha'},[card]),current,false)); + position: "hs", + prompt: get.prompt("dcsaowei"), + prompt2: "将一张“隘”当做【杀】对" + get.translation(trigger.targets) + "使用", + targets: trigger.targets, + filterCard: function (card, player) { + if (get.itemtype(card) == "card" && !card.hasGaintag("dcaishou_tag")) + return false; + return _status.event.targets.every((current) => + player.canUse(get.autoViewAs({ name: "sha" }, [card]), current, false) + ); }, - filterTarget:function(card,player,target){ - if(!_status.event.targets.includes(target)) return false; - card=get.autoViewAs({name:'sha'},[card]); - return lib.filter.filterTarget.apply(this,arguments); + filterTarget: function (card, player, target) { + if (!_status.event.targets.includes(target)) return false; + card = get.autoViewAs({ name: "sha" }, [card]); + return lib.filter.filterTarget.apply(this, arguments); }, - selectTarget:-1, - ai1:function(card){ - var player=_status.event.player; - if(player.isHealthy()&&player.hasSkill('dcaishou')&&player.countCards('h',card=>card.hasGaintag('dcaishou_tag')==1)) return 0; - var eff=0; - for(var target of _status.event.targets){ - eff+=get.effect(target,get.autoViewAs({name:'sha'},[card]),player,player); + selectTarget: -1, + ai1: function (card) { + var player = _status.event.player; + if ( + player.isHealthy() && + player.hasSkill("dcaishou") && + player.countCards("h", (card) => card.hasGaintag("dcaishou_tag") == 1) + ) + return 0; + var eff = 0; + for (var target of _status.event.targets) { + eff += get.effect( + target, + get.autoViewAs({ name: "sha" }, [card]), + player, + player + ); } - if(eff>0) return 6.5+eff/10-get.value(card); + if (eff > 0) return 6.5 + eff / 10 - get.value(card); return 0; }, - ai2:()=>1, + ai2: () => 1, }); - 'step 1' - if(result.bool){ - var cards=result.cards,targets=result.targets; - event.cards=cards; - var next=player.useCard({name:'sha'},cards,targets,false,'dcsaowei'); - player.when('useCardAfter') - .filter(event=>event==next) - .then(()=>{ - if(player.hasHistory('sourceDamage',evt=>evt.card==trigger.card)){ - var cards=trigger.cards.filterInD(); - if(cards.length>0) player.gain(cards,'gain2'); + "step 1"; + if (result.bool) { + var cards = result.cards, + targets = result.targets; + event.cards = cards; + var next = player.useCard({ name: "sha" }, cards, targets, false, "dcsaowei"); + player + .when("useCardAfter") + .filter((event) => event == next) + .then(() => { + if (player.hasHistory("sourceDamage", (evt) => evt.card == trigger.card)) { + var cards = trigger.cards.filterInD(); + if (cards.length > 0) player.gain(cards, "gain2"); } }); } }, }, //向朗 - dckanji:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return player.countCards('h'); + dckanji: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return player.countCards("h"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - var suits=[]; - player.getCards('h',card=>suits.add(get.suit(card))); - if(suits.length==player.countCards('h')){ + "step 1"; + var suits = []; + player.getCards("h", (card) => suits.add(get.suit(card))); + if (suits.length == player.countCards("h")) { player.draw(2); - event.suitsLength=suits.length; - player.addTempSkill('dckanji_check'); + event.suitsLength = suits.length; + player.addTempSkill("dckanji_check"); } }, - subSkill:{ - check:{ - trigger:{player:'gainAfter'}, - filter:function(event,player){ - if(event.getParent(2).name!='dckanji') return false; - var len=event.getParent(2).suitsLength; - var suits=[]; - player.getCards('h',card=>suits.add(get.suit(card))); - return suits.length>=4&&len<4; + subSkill: { + check: { + trigger: { player: "gainAfter" }, + filter: function (event, player) { + if (event.getParent(2).name != "dckanji") return false; + var len = event.getParent(2).suitsLength; + var suits = []; + player.getCards("h", (card) => suits.add(get.suit(card))); + return suits.length >= 4 && len < 4; }, - charlotte:true, - forced:true, - popup:false, - content:function(){ - player.skip('phaseDiscard'); - game.log(player,'跳过了','#y弃牌阶段'); + charlotte: true, + forced: true, + popup: false, + content: function () { + player.skip("phaseDiscard"); + game.log(player, "跳过了", "#y弃牌阶段"); }, - } + }, + }, + ai: { + order: 9, + result: { + player: function (player, target) { + var count = player.countCards("h"); + if (count > 4) return false; + var suits = []; + player.getCards("h", (card) => suits.add(get.suit(card))); + return suits.length == count ? 1 : 0; + }, + }, }, - ai:{ - order:9, - result:{ - player:function(player,target){ - var count=player.countCards('h'); - if(count>4) return false; - var suits=[]; - player.getCards('h',card=>suits.add(get.suit(card))); - return suits.length==count?1:0; - } - } - } }, - dcqianzheng:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - usable:2, - direct:true, - filter:function(event,player){ - return event.player!=player&&(get.type(event.card)=='trick'||event.card.name=='sha')&&player.countCards('he')>1; + dcqianzheng: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + usable: 2, + filter: function (event, player) { + return ( + event.player != player && + (get.type(event.card) == "trick" || event.card.name == "sha") && + player.countCards("he") > 1 + ); }, - content:function(){ - 'step 0' - var str=',若重铸的牌中没有'+get.translation(get.type2(trigger.card))+'牌,你于'+get.translation(trigger.cards)+'进入弃牌堆后获得之'; - player.chooseCard(get.prompt('dcqianzheng'),'重铸两张牌'+(trigger.cards.length?str:'')+'。',2,'he',lib.filter.cardRecastable).set('ai',card=>{ - var val=get.value(card); - if(get.type2(card)==_status.event.type) val+=0.5; - return 6-val; - }).set('type',get.type2(trigger.card)); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.logSkill('dcqianzheng'); - player.recast(cards); - if(cards.every(card=>get.type2(card)!=get.type2(trigger.card))){ - trigger.getParent().dcqianzheng=true; - player.addTempSkill('dcqianzheng_gain'); - } - } - else player.storage.counttrigger.dcqianzheng--; + async cost(event, trigger, player) { + const str = + ",若重铸的牌中没有" + + get.translation(get.type2(trigger.card)) + + "牌,你于" + + get.translation(trigger.cards) + + "进入弃牌堆后获得之"; + event.result = await player + .chooseCard( + get.prompt("dcqianzheng"), + "重铸两张牌" + (trigger.cards.length ? str : "") + "。", + 2, + "he", + lib.filter.cardRecastable + ) + .set("ai", (card) => { + var val = get.value(card); + if (get.type2(card) == _status.event.type) val += 0.5; + return 6 - val; + }) + .set("type", get.type2(trigger.card)) + .forResult(); }, - subSkill:{ - gain:{ - trigger:{global:'cardsDiscardAfter'}, - filter:function(event,player){ - var evt=event.getParent(); - if(evt.name!='orderingDiscard') return false; - return evt.relatedEvent.dcqianzheng&&event.cards.filterInD('d').length; - }, - charlotte:true, - forced:true, - popup:false, - content:function(){ - player.gain(trigger.cards.filterInD('d'),'gain2'); - }, + async content(event, trigger, player) { + if (event.cards.every((card) => get.type2(card) != get.type2(trigger.card))) { + trigger.getParent().dcqianzheng = true; + player.addTempSkill("dcqianzheng_gain"); } + await player.recast(event.cards); + }, + subSkill: { + gain: { + trigger: { global: "cardsDiscardAfter" }, + filter: function (event, player) { + var evt = event.getParent(); + if (evt.name != "orderingDiscard") return false; + return evt.relatedEvent.dcqianzheng && event.cards.filterInD("d").length; + }, + charlotte: true, + forced: true, + popup: false, + content: function () { + player.gain(trigger.cards.filterInD("d"), "gain2"); + }, + }, }, }, //秦朗 - dchaochong:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return player.getHandcardLimit()!=player.countCards('h'); + dchaochong: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return player.getHandcardLimit() != player.countCards("h"); }, - direct:true, - locked:false, - content:function(){ - 'step 0' - var del=player.getHandcardLimit()-player.countCards('h'); - event.delta=del; - if(del>0){ - player.chooseBool(get.prompt('dchaochong'),'摸'+get.cnNumber(Math.min(5,del))+'张牌,然后令你的手牌上限-1').set('ai',()=>{ - var player=_status.event.player; - if(player.isPhaseUsing()&&player.hasCard(cardx=>player.hasUseTarget(cardx)&&player.hasValueTarget(cardx),'hs')) return false; - return true; - }); + direct: true, + locked: false, + content: function () { + "step 0"; + var del = player.getHandcardLimit() - player.countCards("h"); + event.delta = del; + if (del > 0) { + player + .chooseBool( + get.prompt("dchaochong"), + "摸" + get.cnNumber(Math.min(5, del)) + "张牌,然后令你的手牌上限-1" + ) + .set("ai", () => { + var player = _status.event.player; + if ( + player.isPhaseUsing() && + player.hasCard( + (cardx) => player.hasUseTarget(cardx) && player.hasValueTarget(cardx), + "hs" + ) + ) + return false; + return true; + }); + } else if (del < 0) { + player + .chooseToDiscard( + get.prompt("dchaochong"), + "弃置" + get.cnNumber(-del) + "张手牌,然后令你的手牌上限+1", + -del + ) + .set("ai", (card) => { + var player = _status.event.player; + if ( + player.isPhaseUsing() && + player.hasCard((cardx) => player.hasValueTarget(cardx), "hs") + ) + return 6 - player.getUseValue(card); + return 5 - get.value(card); + }) + .set("logSkill", "dchaochong"); } - else if(del<0){ - player.chooseToDiscard(get.prompt('dchaochong'),'弃置'+get.cnNumber(-del)+'张手牌,然后令你的手牌上限+1',-del).set('ai',card=>{ - var player=_status.event.player; - if(player.isPhaseUsing()&&player.hasCard(cardx=>player.hasValueTarget(cardx),'hs')) return 6-player.getUseValue(card); - return 5-get.value(card); - }).set('logSkill','dchaochong'); - } - 'step 1' - if(result.bool){ - if(event.delta>0){ - player.logSkill('dchaochong'); - player.draw(Math.min(5,event.delta)); - lib.skill.dchaochong.change(player,-1); - } - else if(event.delta<0){ - lib.skill.dchaochong.change(player,1); + "step 1"; + if (result.bool) { + if (event.delta > 0) { + player.logSkill("dchaochong"); + player.draw(Math.min(5, event.delta)); + lib.skill.dchaochong.change(player, -1); + } else if (event.delta < 0) { + lib.skill.dchaochong.change(player, 1); } } }, - change:function(player,num){ - if(typeof player.storage.dchaochong!=='number') player.storage.dchaochong=0; - if(!num) return; - player.storage.dchaochong+=num; - player.markSkill('dchaochong'); - game.log(player,'的手牌上限','#g'+(num>0?'+':'')+num); + change: function (player, num) { + if (typeof player.storage.dchaochong !== "number") player.storage.dchaochong = 0; + if (!num) return; + player.storage.dchaochong += num; + player.markSkill("dchaochong"); + game.log(player, "的手牌上限", "#g" + (num > 0 ? "+" : "") + num); }, - markimage:'image/card/handcard.png', - intro:{ - content:function(storage,player){ - var num=player.storage.dchaochong; - return '手牌上限'+(num>=0?'+':'')+num; - } + markimage: "image/card/handcard.png", + intro: { + content: function (storage, player) { + var num = player.storage.dchaochong; + return "手牌上限" + (num >= 0 ? "+" : "") + num; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('dchaochong'); - } + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("dchaochong"); + }, }, - ai:{threaten:2.2} + ai: { threaten: 2.2 }, }, - dcjinjin:{ - audio:2, - trigger:{ - source:'damageSource', - player:'damageEnd', + dcjinjin: { + audio: 2, + trigger: { + source: "damageSource", + player: "damageEnd", }, - usable:2, - logTarget:'source', - check:function(event,player){ - if(typeof player.storage.dchaochong!='number'||player.storage.dchaochong==0) return true; - var evt=event.getParent('useCard'); - if(evt&&evt.player==player&&event.source==player) return false; - if(player.isPhaseUsing()&&player.storage.dchaochong==-1) return true; - return Math.abs(player.storage.dchaochong)>=2; + usable: 2, + logTarget: "source", + check: function (event, player) { + if (typeof player.storage.dchaochong != "number" || player.storage.dchaochong == 0) + return true; + var evt = event.getParent("useCard"); + if (evt && evt.player == player && event.source == player) return false; + if (player.isPhaseUsing() && player.storage.dchaochong == -1) return true; + return Math.abs(player.storage.dchaochong) >= 2; }, - prompt2:function(event,player){ - var str=''; - if(typeof player.storage.dchaochong=='number'&&player.storage.dchaochong!=0){ - str +='重置因〖佞宠〗增加或减少的手牌上限,'; + prompt2: function (event, player) { + var str = ""; + if (typeof player.storage.dchaochong == "number" && player.storage.dchaochong != 0) { + str += "重置因〖佞宠〗增加或减少的手牌上限,"; } - var num=Math.abs(player.countMark('dchaochong'))||1; - if(event.source&&event.source.isIn()){ - str+='令伤害来源弃置至多'+get.cnNumber(num)+'张牌,然后你摸'+num+'-X张牌(X为其弃置的牌数)'; - } - else str+='你摸'+get.cnNumber(num)+'张牌'; + var num = Math.abs(player.countMark("dchaochong")) || 1; + if (event.source && event.source.isIn()) { + str += + "令伤害来源弃置至多" + + get.cnNumber(num) + + "张牌,然后你摸" + + num + + "-X张牌(X为其弃置的牌数)"; + } else str += "你摸" + get.cnNumber(num) + "张牌"; return str; }, - content:function(){ - 'step 0' - var del=Math.abs(player.countMark('dchaochong'))||1; - event.delta=del; - player.storage.dchaochong=0; - if(player.hasSkill('dchaochong',null,false,false)) player.markSkill('dchaochong'); - game.log(player,'重置了手牌上限'); - if(trigger.source&&trigger.source.isIn()){ - trigger.source.chooseToDiscard(get.translation(player)+'对你发动了【矜谨】','弃置至多'+get.cnNumber(del)+'张牌,然后'+get.translation(player)+'摸'+del+'-X张牌(X为你弃置的牌数)。',[1,del],'he').set('ai',card=>{ - if(_status.event.goon) return 5.5-get.value(card); - return 0; - }).set('goon',get.attitude(trigger.source,player)<0); + content: function () { + "step 0"; + var del = Math.abs(player.countMark("dchaochong")) || 1; + event.delta = del; + player.storage.dchaochong = 0; + if (player.hasSkill("dchaochong", null, false, false)) player.markSkill("dchaochong"); + game.log(player, "重置了手牌上限"); + if (trigger.source && trigger.source.isIn()) { + trigger.source + .chooseToDiscard( + get.translation(player) + "对你发动了【矜谨】", + "弃置至多" + + get.cnNumber(del) + + "张牌,然后" + + get.translation(player) + + "摸" + + del + + "-X张牌(X为你弃置的牌数)。", + [1, del], + "he" + ) + .set("ai", (card) => { + if (_status.event.goon) return 5.5 - get.value(card); + return 0; + }) + .set("goon", get.attitude(trigger.source, player) < 0); } - 'step 1' - var num=event.delta; - if(result.bool) num-=result.cards.length; - if(num>0) player.draw(num); + "step 1"; + var num = event.delta; + if (result.bool) num -= result.cards.length; + if (num > 0) player.draw(num); }, - ai:{ - combo:'dchaochong', - maixie:true, - maixie_hp:true, - threaten:0.85, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=0; - if(typeof target.storage.dcninchong=='number') num=Math.abs(target.storage.dcninchong); - if(num<=0) return; - return [1,Math.min(1,num/3)]; + ai: { + combo: "dchaochong", + maixie: true, + maixie_hp: true, + threaten: 0.85, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 0; + if (typeof target.storage.dcninchong == "number") + num = Math.abs(target.storage.dcninchong); + if (num <= 0) return; + return [1, Math.min(1, num / 3)]; } }, }, }, }, //二傅 - dcxuewei:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('dcxuewei'),(card,player,target)=>{ - return target.hp<=player.hp; - }).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'tao'},player,player)+0.1; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcxuewei',target); - player.addTempSkill('dcxuewei_shelter',{player:'phaseBegin'}); - player.markAuto('dcxuewei_shelter',[target]); + dcxuewei: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("dcxuewei"), (card, player, target) => { + return target.hp <= player.hp; + }) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "tao" }, player, player) + 0.1; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcxuewei", target); + player.addTempSkill("dcxuewei_shelter", { player: "phaseBegin" }); + player.markAuto("dcxuewei_shelter", [target]); } }, - ai:{threaten:1.1}, - subSkill:{ - shelter:{ - audio:'dcxuewei', - trigger:{global:'damageBegin4'}, - filter:function(event,player){ - return player.getStorage('dcxuewei_shelter').includes(event.player); + ai: { threaten: 1.1 }, + subSkill: { + shelter: { + audio: "dcxuewei", + trigger: { global: "damageBegin4" }, + filter: function (event, player) { + return player.getStorage("dcxuewei_shelter").includes(event.player); }, - charlotte:true, - forced:true, - onremove:true, - logTarget:'player', - marktext:'卫', - intro:{content:'保护对象:$'}, - content:function(){ - 'step 0' + charlotte: true, + forced: true, + onremove: true, + logTarget: "player", + marktext: "卫", + intro: { content: "保护对象:$" }, + content: function () { + "step 0"; trigger.cancel(); - 'step 1' + "step 1"; player.loseHp(); - if(trigger.player!=player) game.asyncDraw([player,trigger.player]); - else player.draw('nodelay'); - 'step 2' + if (trigger.player != player) game.asyncDraw([player, trigger.player]); + else player.draw("nodelay"); + "step 2"; game.delayx(); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player&&arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.player && arg.player.hasSkillTag("jueqing", false, player)) + return false; return true; - } + }, }, - } + }, }, }, - dcyuguan:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - var num=player.getDamagedHp(); - if(num==0) return false; - return !game.hasPlayer(current=>{ - return current.getDamagedHp()>num; + dcyuguan: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + var num = player.getDamagedHp(); + if (num == 0) return false; + return !game.hasPlayer((current) => { + return current.getDamagedHp() > num; }); }, - check:function(event,player){ - var num=player.getDamagedHp()-1; - if(num<=0) return false; - return game.hasPlayer(target=>{ - return get.attitude(player,target)>0&&target.maxHp-target.countCards('h')>1; + check: function (event, player) { + var num = player.getDamagedHp() - 1; + if (num <= 0) return false; + return game.hasPlayer((target) => { + return get.attitude(player, target) > 0 && target.maxHp - target.countCards("h") > 1; }); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' - var num=player.getDamagedHp(); - if(!player.isIn()||!num) event.finish(); - else player.chooseTarget('御关:令'+get.cnNumber(num)+'名角色将手牌摸至体力上限',Math.min(game.countPlayer(),[1,num]),true).set('ai',target=>{ - return get.attitude(_status.event.player,target)*Math.max(0.1,target.maxHp-target.countCards('h')); - }); - 'step 2' - if(result.bool){ - var targets=result.targets.sortBySeat(_status.currentPhase); + "step 1"; + var num = player.getDamagedHp(); + if (!player.isIn() || !num) event.finish(); + else + player + .chooseTarget( + "御关:令至多" + get.cnNumber(num) + "名角色将手牌摸至体力上限", + Math.min(game.countPlayer(), [1, num]), + true + ) + .set("ai", (target) => { + return ( + get.attitude(_status.event.player, target) * + Math.max(0.1, target.maxHp - target.countCards("h")) + ); + }); + "step 2"; + if (result.bool) { + var targets = result.targets.sortBySeat(_status.currentPhase); player.line(targets); - for(var target of targets){ + for (var target of targets) { target.drawTo(target.maxHp); } } - } + }, }, //郑浑 - dcqiangzhi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - if(target==player) return false; - return target.countDiscardableCards(player,'he')+player.countDiscardableCards(player,'he')>=3; + dcqiangzhi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + if (target == player) return false; + return ( + target.countDiscardableCards(player, "he") + + player.countDiscardableCards(player, "he") >= + 3 + ); }, - content:function(){ - 'step 0' - var dialog=[]; - dialog.push('强峙:弃置你与'+get.translation(target)+'的共计三张牌'); - if(player.countCards('h')) dialog.addArray(['
              你的手牌
              ',player.getCards('h')]); - if(player.countCards('e')) dialog.addArray(['
              你的装备
              ',player.getCards('e')]); - if(target.countCards('h')){ - dialog.add('
              '+get.translation(target)+'的手牌
              '); - if(player.hasSkillTag('viewHandcard',null,target,true)) dialog.push(target.getCards('h')); - else dialog.push([target.getCards('h'),'blank']); + content: function () { + "step 0"; + var dialog = []; + dialog.push("强峙:弃置你与" + get.translation(target) + "的共计三张牌"); + if (player.countCards("h")) + dialog.addArray(['
              你的手牌
              ', player.getCards("h")]); + if (player.countCards("e")) + dialog.addArray(['
              你的装备
              ', player.getCards("e")]); + if (target.countCards("h")) { + dialog.add('
              ' + get.translation(target) + "的手牌
              "); + if (player.hasSkillTag("viewHandcard", null, target, true)) + dialog.push(target.getCards("h")); + else dialog.push([target.getCards("h"), "blank"]); } - if(target.countCards('e')) dialog.addArray(['
              '+get.translation(target)+'的装备
              ',target.getCards('e')]); - player.chooseButton(3,true).set('createDialog',dialog).set('filterButton',button=>{ - if(!lib.filter.canBeDiscarded(button.link,_status.event.player,get.owner(button.link))) return false; - return true; - }).set('filterOk',()=>{ - return ui.selected.buttons.length==3; - }).set('ai',button=>{ - var player=_status.event.player; - var target=_status.event.getParent().target; - var card=button.link; - if(get.owner(card)==player){ - if(_status.event.damage) return 15-get.value(card); - if(player.hp>=3||get.damageEffect(player,target,player)>=0||player.hasSkill('dcpitian')&&player.getHandcardLimit()-player.countCards('h')>=1&&player.hp>1) return 0; - if(ui.selected.buttons.length==0) return 10-get.value(card); - return 0; - } - else{ - if(_status.event.damage) return 0; - return -(get.sgnAttitude(player,target)||1)*get.value(card); - } - }).set('damage',get.damageEffect(target,player,player)>10&&player.countCards('he',card=>{ - return lib.filter.canBeDiscarded(card,player,player)&&get.value(card)<5; - })>=3); - 'step 1' - if(result.bool){ - var links=result.links; - var list1=[],list2=[]; - event.players=[player,target]; - for(var card of links){ - if(get.owner(card)==player) list1.push(card); + if (target.countCards("e")) + dialog.addArray([ + '
              ' + get.translation(target) + "的装备
              ", + target.getCards("e"), + ]); + player + .chooseButton(3, true) + .set("createDialog", dialog) + .set("filterButton", (button) => { + if ( + !lib.filter.canBeDiscarded( + button.link, + _status.event.player, + get.owner(button.link) + ) + ) + return false; + return true; + }) + .set("filterOk", () => { + return ui.selected.buttons.length == 3; + }) + .set("ai", (button) => { + var player = _status.event.player; + var target = _status.event.getParent().target; + var card = button.link; + if (get.owner(card) == player) { + if (_status.event.damage) return 15 - get.value(card); + if ( + player.hp >= 3 || + get.damageEffect(player, target, player) >= 0 || + (player.hasSkill("dcpitian") && + player.getHandcardLimit() - player.countCards("h") >= 1 && + player.hp > 1) + ) + return 0; + if (ui.selected.buttons.length == 0) return 10 - get.value(card); + return 0; + } else { + if (_status.event.damage) return 0; + return -(get.sgnAttitude(player, target) || 1) * get.value(card); + } + }) + .set( + "damage", + get.damageEffect(target, player, player) > 10 && + player.countCards("he", (card) => { + return ( + lib.filter.canBeDiscarded(card, player, player) && get.value(card) < 5 + ); + }) >= 3 + ); + "step 1"; + if (result.bool) { + var links = result.links; + var list1 = [], + list2 = []; + event.players = [player, target]; + for (var card of links) { + if (get.owner(card) == player) list1.push(card); else list2.push(card); } - if(list1.length&&list2.length){ + if (list1.length && list2.length) { game.loseAsync({ - lose_list:[ - [player,list1], - [target,list2] + lose_list: [ + [player, list1], + [target, list2], ], - discarder:player, - }).setContent('discardMultiple'); + discarder: player, + }).setContent("discardMultiple"); event.finish(); - } - else if(list2.length) target.discard(list2); + } else if (list2.length) target.discard(list2); else player.discard(list1); - if(list2.length>=3) event.players.reverse(); - } - else event.finish(); - 'step 2' + if (list2.length >= 3) event.players.reverse(); + } else event.finish(); + "step 2"; event.players[0].line(event.players[1]); event.players[1].damage(event.players[0]); }, - ai:{ - expose:0.2, - order:4, - result:{ - target:function(player,target){ - return get.effect(target,{name:'guohe_copy2'},player,target)/2*(target.countDiscardableCards(player,'he')>=2?1.25:1)+get.damageEffect(target,player,target)/3; - } - } - } - }, - dcpitian:{ - audio:2, - trigger:{ - player:['loseAfter','damageEnd'], - global:'loseAsyncAfter', - }, - forced:true, - locked:false, - group:'dcpitian_draw', - filter:function(event,player){ - if(event.name=='damage') return true; - return event.type=='discard'&&event.getl(player).cards2.length>0; - }, - content:function(){ - player.addMark('dcpitian_handcard',1,false); - player.addSkill('dcpitian_handcard'); - game.log(player,'的手牌上限','#y+1'); - }, - subSkill:{ - draw:{ - audio:'dcpitian', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h')= 2 ? 1.25 : 1) + + get.damageEffect(target, player, target) / 3 + ); }, - prompt2:function(event,player){ - return '摸'+get.cnNumber(Math.min(5,player.getHandcardLimit()-player.countCards('h')))+'张牌,重置因〖辟田〗增加的手牌上限'; - }, - check:function(event,player){ - return player.getHandcardLimit()-player.countCards('h')>Math.min(2,player.hp-1); - }, - content:function(){ - 'step 0' - var num=Math.min(5,player.getHandcardLimit()-player.countCards('h')); - if(num>0) player.draw(num); - 'step 1' - player.removeMark('dcpitian_handcard',player.countMark('dcpitian_handcard'),false); - game.log(player,'重置了','#g【辟田】','增加的手牌上限'); - } }, - handcard:{ - markimage:'image/card/handcard.png', - intro:{ - content:function(storage,player){ - return '手牌上限+'+storage; - } - }, - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('dcpitian_handcard'); - } - }, - } }, - ai:{ - effect:{ - target:function (card,player,target){ - if(get.tag(card,'discard')) return 0.9; - if(get.tag(card,'damage')) return 0.95; + }, + dcpitian: { + audio: 2, + trigger: { + player: ["loseAfter", "damageEnd"], + global: "loseAsyncAfter", + }, + forced: true, + locked: false, + group: "dcpitian_draw", + filter: function (event, player) { + if (event.name == "damage") return true; + return event.type == "discard" && event.getl(player).cards2.length > 0; + }, + content: function () { + player.addMark("dcpitian_handcard", 1, false); + player.addSkill("dcpitian_handcard"); + game.log(player, "的手牌上限", "#y+1"); + }, + subSkill: { + draw: { + audio: "dcpitian", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h") < player.getHandcardLimit(); + }, + prompt2: function (event, player) { + return ( + "摸" + + get.cnNumber( + Math.min(5, player.getHandcardLimit() - player.countCards("h")) + ) + + "张牌,重置因〖辟田〗增加的手牌上限" + ); + }, + check: function (event, player) { + return ( + player.getHandcardLimit() - player.countCards("h") > + Math.min(2, player.hp - 1) + ); + }, + content: function () { + "step 0"; + var num = Math.min(5, player.getHandcardLimit() - player.countCards("h")); + if (num > 0) player.draw(num); + "step 1"; + player.removeMark( + "dcpitian_handcard", + player.countMark("dcpitian_handcard"), + false + ); + game.log(player, "重置了", "#g【辟田】", "增加的手牌上限"); + }, + }, + handcard: { + markimage: "image/card/handcard.png", + intro: { + content: function (storage, player) { + return "手牌上限+" + storage; + }, + }, + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("dcpitian_handcard"); + }, + }, + }, + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "discard")) return 0.9; + if (get.tag(card, "damage")) return 0.95; }, }, }, }, //新服二赵 - dcqingren:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - return player.hasHistory('useSkill',evt=>['yizan_use','yizan_use_backup'].includes(evt.sourceSkill||evt.skill)); + dcqingren: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { + return player.hasHistory("useSkill", (evt) => + ["yizan_use", "yizan_use_backup"].includes(evt.sourceSkill || evt.skill) + ); }, - content:function(){ - player.draw(player.getHistory('useSkill',evt=>['yizan_use','yizan_use_backup'].includes(evt.sourceSkill||evt.skill)).length) + content: function () { + player.draw( + player.getHistory("useSkill", (evt) => + ["yizan_use", "yizan_use_backup"].includes(evt.sourceSkill || evt.skill) + ).length + ); + }, + ai: { + combo: "yizan_use", }, }, - dclongyuan:{ - audio:'xinfu_longyuan', - forced:true, - unique:true, - juexingji:true, - trigger:{ - global:'phaseEnd', + dclongyuan: { + audio: "xinfu_longyuan", + forced: true, + unique: true, + juexingji: true, + trigger: { + global: "phaseEnd", }, - skillAnimation:true, - animationColor:'orange', - filter:function(event,player){ - return player.countMark('yizan_use')>=3; + skillAnimation: true, + animationColor: "orange", + filter: function (event, player) { + return player.countMark("yizan_use") >= 3; }, - content:function(){ - player.awakenSkill('dclongyuan'); + content: function () { + player.awakenSkill("dclongyuan"); player.draw(2); player.recover(); - player.storage.yizan=true; + player.storage.yizan = true; + }, + derivation: "yizan_rewrite", + ai: { + combo: "yizan_use", }, - derivation:'yizan_rewrite', }, //黄皓 - dcqinqing:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - var zhu=game.filterPlayer(current=>current.getSeatNum()==1)[0]; - if(!zhu||!zhu.isIn()) return false; - return game.hasPlayer(current=>{ - return current!=player&¤t.inRange(zhu); + dcqinqing: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + var zhu = game.filterPlayer((current) => current.getSeatNum() == 1)[0]; + if (!zhu || !zhu.isIn()) return false; + return game.hasPlayer((current) => { + return current != player && current.inRange(zhu); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('dcqinqing'),function(card,player,target){ - var zhu=game.filterPlayer(current=>current.getSeatNum()==1)[0]; - return target!=player&&target.inRange(zhu)&&target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var zhu=game.filterPlayer(current=>current.getSeatNum()==1)[0]; - var he=target.countCards('he'); - if(get.attitude(_status.event.player,target)>0){ - if(target.countCards('h')>zhu.countCards('h')+1) return 0.1; - } - else{ - if(he>zhu.countCards('h')+1) return 2; - if(he>0) return 1; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dcqinqing',target); - if(target.countCards('he')) player.discardPlayerCard(target,'he',true); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("dcqinqing"), function (card, player, target) { + var zhu = game.filterPlayer((current) => current.getSeatNum() == 1)[0]; + return ( + target != player && + target.inRange(zhu) && + target.countDiscardableCards(player, "he") > 0 + ); + }) + .set("ai", function (target) { + var zhu = game.filterPlayer((current) => current.getSeatNum() == 1)[0]; + var he = target.countCards("he"); + if (get.attitude(_status.event.player, target) > 0) { + if (target.countCards("h") > zhu.countCards("h") + 1) return 0.1; + } else { + if (he > zhu.countCards("h") + 1) return 2; + if (he > 0) return 1; + } + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dcqinqing", target); + if (target.countCards("he")) player.discardPlayerCard(target, "he", true); + } else { event.finish(); } - 'step 2' - var zhu=game.filterPlayer(current=>current.getSeatNum()==1)[0]; - if(zhu&&zhu.isIn()){ - if(target.countCards('h')>zhu.countCards('h')) player.draw(); + "step 2"; + var zhu = game.filterPlayer((current) => current.getSeatNum() == 1)[0]; + if (zhu && zhu.isIn()) { + if (target.countCards("h") > zhu.countCards("h")) player.draw(); } - } - }, - dccunwei:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&get.type2(event.card)=='trick'&&(event.targets.length==1||player.countCards('he')>0); }, - content:function(){ - if(trigger.targets.length==1) player.draw(); - else if(player.countCards('he')>0) player.chooseToDiscard('he',true,'存畏:请弃置一张牌'); - } + }, + dccunwei: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + return ( + player != event.player && + get.type2(event.card) == "trick" && + (event.targets.length == 1 || player.countCards("he") > 0) + ); + }, + content: function () { + if (trigger.targets.length == 1) player.draw(); + else if (player.countCards("he") > 0) + player.chooseToDiscard("he", true, "存畏:请弃置一张牌"); + }, }, //刘辟 - dcjuying:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getCardUsable('sha',true)>player.getHistory('useCard',evt=>{ - return evt.getParent('phaseUse')==event&&evt.card.name=='sha'&&evt.addCount!==false; - }).length; + dcjuying: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return ( + player.getCardUsable("sha", true) > + player.getHistory("useCard", (evt) => { + return ( + evt.getParent("phaseUse") == event && + evt.card.name == "sha" && + evt.addCount !== false + ); + }).length + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseButton([ - get.prompt('dcjuying'), - [[ - ['sha','你于下回合使用【杀】的次数上限+1'], - ['hand','本回合手牌上限+2'], - ['draw','摸三张牌'], - ],'textbutton'] - ]).set('ai',function(button){ - var player=_status.event.player,choice=button.link; - if(choice=='draw') return 10; - if(choice=='sha') return 9; - var del=3-player.hp; - if(choice=='hand'&&player.needsToDiscard()>0&&del<=0) return 8; - return 0; - }).set('selectButton',[1,3]); - 'step 1' - if(result.bool){ - player.logSkill('dcjuying'); - var choices=result.links; - event.choices=choices; - if(choices.includes('sha')){ - player.addMark('dcjuying_sha',1,false); - player.addSkill('dcjuying_sha'); + direct: true, + content: function () { + "step 0"; + player + .chooseButton([ + get.prompt("dcjuying"), + [ + [ + ["sha", "你于下回合使用【杀】的次数上限+1"], + ["hand", "本回合手牌上限+2"], + ["draw", "摸三张牌"], + ], + "textbutton", + ], + ]) + .set("ai", function (button) { + var player = _status.event.player, + choice = button.link; + if (choice == "draw") return 10; + if (choice == "sha") return 9; + var del = 3 - player.hp; + if (choice == "hand" && player.needsToDiscard() > 0 && del <= 0) return 8; + return 0; + }) + .set("selectButton", [1, 3]); + "step 1"; + if (result.bool) { + player.logSkill("dcjuying"); + var choices = result.links; + event.choices = choices; + if (choices.includes("sha")) { + player.addMark("dcjuying_sha", 1, false); + player.addSkill("dcjuying_sha"); } - if(choices.includes('hand')){ - player.addMark('dcjuying_hand',1,false); - player.addTempSkill('dcjuying_hand'); + if (choices.includes("hand")) { + player.addMark("dcjuying_hand", 1, false); + player.addTempSkill("dcjuying_hand"); } - if(choices.includes('draw')){ + if (choices.includes("draw")) { player.draw(3); } - } - else event.finish(); - 'step 2' - var num=event.choices.length-Math.max(0,player.hp); - if(num>0){ - player.chooseToDiscard(true,'he'); + } else event.finish(); + "step 2"; + var num = event.choices.length - Math.max(0, player.hp); + if (num > 0) { + player.chooseToDiscard(true, "he"); } }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card=='object'&&player.isPhaseUsing()&&card.name=='sha'&&player.getCardUsable('sha')==1) return 'zeroplayertarget'; + ai: { + effect: { + player_use: function (card, player, target) { + if ( + typeof card == "object" && + player.isPhaseUsing() && + card.name == "sha" && + player.getCardUsable("sha") == 1 + ) + return "zeroplayertarget"; + }, + target_use: function (card, player, target) { + if (card.name == "jiu" && player.getCardUsable("sha") == 2) return [1, 1]; }, - target_use:function(card,player,target){ - if(card.name=='jiu'&&player.getCardUsable('sha')==2) return [1,1]; - } }, }, - subSkill:{ - sha:{ - trigger:{player:'phaseBegin'}, - filter:function(event,player){ - return player.countMark('dcjuying_sha')>0; + subSkill: { + sha: { + trigger: { player: "phaseBegin" }, + filter: function (event, player) { + return player.countMark("dcjuying_sha") > 0; }, - silent:true, - firstDo:true, - charlotte:true, - onremove:true, - content:function(){ - player.addMark('dcjuying_effect',player.countMark('dcjuying_sha'),false); - player.addTempSkill('dcjuying_effect'); - player.removeSkill('dcjuying_sha'); + silent: true, + firstDo: true, + charlotte: true, + onremove: true, + content: function () { + player.addMark("dcjuying_effect", player.countMark("dcjuying_sha"), false); + player.addTempSkill("dcjuying_effect"); + player.removeSkill("dcjuying_sha"); }, - intro:{content:'下回合使用【杀】的次数上限+#'} + intro: { content: "下回合使用【杀】的次数上限+#" }, }, - effect:{ - onremove:true, - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('dcjuying_effect'); + effect: { + onremove: true, + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("dcjuying_effect"); + }, + }, + intro: { content: "本回合使用【杀】的次数上限+#" }, + }, + hand: { + onremove: true, + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + 2 * player.countMark("dcjuying_hand"); }, }, - intro:{content:'本回合使用【杀】的次数上限+#'} }, - hand:{ - onremove:true, - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+2*player.countMark('dcjuying_hand'); - } - } - } }, }, //新服加强魏贾诩 - dcjianshu:{ - audio:'jianshu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h',{color:'black'})>0; + dcjianshu: { + audio: "jianshu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", { color: "black" }) > 0; }, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(ui.selected.targets.length){ - return ui.selected.targets[0]!=target&&!ui.selected.targets[0].hasSkillTag('noCompareSource')&&target.countCards('h') - &&!target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + if (target == player) return false; + if (ui.selected.targets.length) { + return ( + ui.selected.targets[0] != target && + !ui.selected.targets[0].hasSkillTag("noCompareSource") && + target.countCards("h") && + !target.hasSkillTag("noCompareTarget") + ); } return true; }, - targetprompt:['发起者','拼点目标'], - filterCard:{color:'black'}, - discard:false, - lose:false, - delay:false, - check:function(card){ - if(_status.event.player.hp==1) return 8-get.value(card); - return 6-get.value(card); + targetprompt: ["发起者", "拼点目标"], + filterCard: { color: "black" }, + discard: false, + lose: false, + delay: false, + check: function (card) { + if (_status.event.player.hp == 1) return 8 - get.value(card); + return 6 - get.value(card); }, - selectTarget:2, - multitarget:true, - content:function(){ - 'step 0' - player.give(cards,targets[0],'give'); - 'step 1' + selectTarget: 2, + multitarget: true, + content: function () { + "step 0"; + player.give(cards, targets[0], "give"); + "step 1"; targets[0].chooseToCompare(targets[1]); - 'step 2' - player.addTempSkill('dcjianshu_check','phaseUseAfter'); - if(result.bool){ - var cards=targets[0].getCards('he',function(card){ - return lib.filter.cardDiscardable(card,targets[0],'dcjianshu'); + "step 2"; + player.addTempSkill("dcjianshu_check", "phaseUseAfter"); + if (result.bool) { + var cards = targets[0].getCards("he", function (card) { + return lib.filter.cardDiscardable(card, targets[0], "dcjianshu"); }); - if(cards.length>0) targets[0].discard(cards.randomGet()); + if (cards.length > 0) targets[0].discard(cards.randomGet()); targets[1].loseHp(); - } - else if(result.tie){ + } else if (result.tie) { targets[0].loseHp(); targets[1].loseHp(); - } - else{ - var cards=targets[1].getCards('he',function(card){ - return lib.filter.cardDiscardable(card,targets[1],'dcjianshu'); + } else { + var cards = targets[1].getCards("he", function (card) { + return lib.filter.cardDiscardable(card, targets[1], "dcjianshu"); }); - if(cards.length>0) targets[1].discard(cards.randomGet()); + if (cards.length > 0) targets[1].discard(cards.randomGet()); targets[0].loseHp(); } }, - subSkill:{ - check:{ - trigger:{global:'dieAfter'}, - charlotte:true, - forced:true, - popup:false, - filter:function(event,player){ - return event.getParent(3).name=='dcjianshu'; + subSkill: { + check: { + trigger: { global: "dieAfter" }, + charlotte: true, + forced: true, + popup: false, + filter: function (event, player) { + return event.getParent(3).name == "dcjianshu"; }, - content:function(){ - delete player.getStat('skill').dcjianshu; - } - } + content: function () { + delete player.getStat("skill").dcjianshu; + }, + }, }, - ai:{ - expose:0.4, - order:4, - result:{ - target:function(player,target){ - if(ui.selected.targets.length) return -1; + ai: { + expose: 0.4, + order: 4, + result: { + target: function (player, target) { + if (ui.selected.targets.length) return -1; return -0.5; - } - } - } + }, + }, + }, }, - dcyongdi:{ - audio:'yongdi', - audioname:['xinping'], - unique:true, - limited:true, - enable:'phaseUse', - filterTarget:function(card,player,target){ - return target.hasSex('male'); + dcyongdi: { + audio: "yongdi", + audioname: ["xinping"], + unique: true, + limited: true, + enable: "phaseUse", + filterTarget: function (card, player, target) { + return target.hasSex("male"); }, - animationColor:'thunder', - skillAnimation:'legend', - mark:true, - intro:{ - content:'limited' + animationColor: "thunder", + skillAnimation: "legend", + mark: true, + intro: { + content: "limited", }, - content:function(){ - 'step 0' - player.awakenSkill('dcyongdi'); + content: function () { + "step 0"; + player.awakenSkill("dcyongdi"); //player.logSkill('dcyongdi',target); - if(!game.hasPlayer(current=>current.maxHp current.maxHp < target.maxHp)) { target.gainMaxHp(); } - 'step 1' - if(target.isMinHp()){ + "step 1"; + if (target.isMinHp()) { target.recover(); } - 'step 2' - if(target.isMinHandcard()){ - target.draw(Math.min(5,target.maxHp)); + "step 2"; + if (target.isMinHandcard()) { + target.draw(Math.min(5, target.maxHp)); } - 'step 3' + "step 3"; game.delayx(); }, - ai:{ - expose:0.3, - order:1, - result:{ - target:function(player,target){ - var val=0; - var bool1=!game.hasPlayer(current=>current.maxHp current.maxHp < target.maxHp), + bool2 = target.isMinHp(), + bool3 = target.isMinHandcard(); + if (bool1) val += 6.5; + if (bool2) { + if (bool1) target.maxHp++; + val += Math.max(0, get.recoverEffect(target, player, player)); + if (bool1) target.maxHp--; } - if(bool3){ - var num=Math.max(0,Math.min(5,target.maxHp+(bool1?1:0))); - val+=5*num; + if (bool3) { + var num = Math.max(0, Math.min(5, target.maxHp + (bool1 ? 1 : 0))); + val += 5 * num; } return val; - } - } - } + }, + }, + }, }, //雷普 - dcsilve:{ - audio:2, - trigger:{ - player:'enterGame', - global:'phaseBefore', + dcsilve: { + audio: 2, + trigger: { + player: "enterGame", + global: "phaseBefore", }, - forced:true, - locked:false, - direct:true, - onremove:['dcsilve','dcsilve_self'], - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + direct: true, + onremove: ["dcsilve", "dcsilve_self"], + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - content:function(){ - 'step 0' - player.chooseTarget('私掠:请选择一名其他角色','选择一名其他角色(暂时仅你可见),称为“私掠”角色,且你获得后续效果',true,(card,player,target)=>{ - return target!=player&&!player.getStorage('dcsilve').includes(target); - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(att>0) return att+1; - if(att==0) return Math.random(); - return att; - }).set('animate',false); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcsilve'); - player.markAuto('dcsilve',[target]); - player.addSkill('dcsilve_rob'); - player.addSkill('dcsilve_revenge'); - target.addSkill('dcsilve_target'); - if(!target.storage.dcsilve_target) target.storage.dcsilve_target=[]; + content: function () { + "step 0"; + player + .chooseTarget( + "私掠:请选择一名其他角色", + "选择一名其他角色(暂时仅你可见),称为“私掠”角色,且你获得后续效果", + true, + (card, player, target) => { + return target != player && !player.getStorage("dcsilve").includes(target); + } + ) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (att > 0) return att + 1; + if (att == 0) return Math.random(); + return att; + }) + .set("animate", false); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcsilve"); + player.markAuto("dcsilve", [target]); + player.addSkill("dcsilve_rob"); + player.addSkill("dcsilve_revenge"); + target.addSkill("dcsilve_target"); + if (!target.storage.dcsilve_target) target.storage.dcsilve_target = []; target.storage.dcsilve_target.push(player); } }, - subSkill:{ - rob:{ - audio:'dcsilve', - trigger:{global:'damageSource'}, - filter:function(event,player){ - if(!player.getStorage('dcsilve').includes(event.source)) return false; - if(!event.player.isIn()||event.player==player) return false; - if(player.getStorage('dcsilve_robbed').includes(event.player)) return false; - return event.player.countCards('he')>0; + subSkill: { + rob: { + audio: "dcsilve", + trigger: { global: "damageSource" }, + filter: function (event, player) { + if (!player.getStorage("dcsilve").includes(event.source)) return false; + if (!event.player.isIn() || event.player == player) return false; + if (player.getStorage("dcsilve_robbed").includes(event.player)) return false; + return event.player.countCards("he") > 0; }, - charlotte:true, - prompt2:function(event,player){ - return '获得'+get.translation(event.player)+'一张牌'; + charlotte: true, + prompt2: function (event, player) { + return "获得" + get.translation(event.player) + "一张牌"; }, - logTarget:'player', - content:function(){ - player.addTempSkill('dcsilve_robbed'); - player.markAuto('dcsilve_self',[trigger.player]); - if(trigger.player.countGainableCards(player,'he')>0){ - player.markAuto('dcsilve_robbed',[trigger.player]); - player.gainPlayerCard(trigger.player,'he',true); + logTarget: "player", + content: function () { + player.addTempSkill("dcsilve_robbed"); + player.markAuto("dcsilve_self", [trigger.player]); + if (trigger.player.countGainableCards(player, "he") > 0) { + player.markAuto("dcsilve_robbed", [trigger.player]); + player.gainPlayerCard(trigger.player, "he", true); } - if(trigger.source&&trigger.source!=player) trigger.source.markSkill('dcsilve_target'); - } + if (trigger.source && trigger.source != player) + trigger.source.markSkill("dcsilve_target"); + }, }, - revenge:{ - audio:'dcsilve', - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(!player.getStorage('dcsilve').includes(event.player)) return false; - if(!event.player.isIn()||!event.source||!event.source.isIn()||event.source==player) return false; + revenge: { + audio: "dcsilve", + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (!player.getStorage("dcsilve").includes(event.player)) return false; + if ( + !event.player.isIn() || + !event.source || + !event.source.isIn() || + event.source == player + ) + return false; return true; }, - forced:true, - locked:false, - charlotte:true, - direct:true, - content:function(){ - 'step 0' - if(trigger.player&&trigger.player!=player) trigger.player.markSkill('dcsilve_target'); - player.markAuto('dcsilve_self',[trigger.player]); - player.chooseToUse('私掠:对'+get.translation(trigger.source)+'使用一张【杀】,或弃置一张手牌',function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - }).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.source&&!ui.selected.targets.includes(_status.event.source)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('source',trigger.source).set('logSkill','dcsilve_revenge'); - 'step 1' - if(!result.bool){ - if(player.countCards('h')>0) player.chooseToDiscard('h',true).set('logSkill','dcsilve_revenge'); - } - } - }, - self:{ - marktext:'私', - intro:{ - name:'私掠', - content:function(storage,player){ - if(!storage||!storage.length) return '没有打劫对象'; - if(storage[0]==player) return '已绑定'+get.translation(player)+'自己'; - return '打劫对象:'+get.translation(storage); + forced: true, + locked: false, + charlotte: true, + direct: true, + content: function () { + "step 0"; + if (trigger.player && trigger.player != player) + trigger.player.markSkill("dcsilve_target"); + player.markAuto("dcsilve_self", [trigger.player]); + player + .chooseToUse( + "私掠:对" + + get.translation(trigger.source) + + "使用一张【杀】,或弃置一张手牌", + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + } + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.source && + !ui.selected.targets.includes(_status.event.source) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("source", trigger.source) + .set("logSkill", "dcsilve_revenge"); + "step 1"; + if (!result.bool) { + if (player.countCards("h") > 0) + player.chooseToDiscard("h", true).set("logSkill", "dcsilve_revenge"); } }, }, - target:{ - marktext:'掠', - intro:{ - name:'私掠', - content:function(storage,player){ - return '被'+get.translation(storage)+'盯上了!'; - } - } + self: { + marktext: "私", + intro: { + name: "私掠", + content: function (storage, player) { + if (!storage || !storage.length) return "没有打劫对象"; + if (storage[0] == player) return "已绑定" + get.translation(player) + "自己"; + return "打劫对象:" + get.translation(storage); + }, + }, }, - robbed:{onremove:true,charlotte:true}, - } - }, - dcshuaijie:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - var targets=player.getStorage('dcsilve').filter(i=>i.isIn()); - if(!targets.length) return true; - return targets.filter(target=>{ - return player.hp>target.hp&&player.countCards('e')>target.countCards('e'); - }).length==targets.length; + target: { + marktext: "掠", + intro: { + name: "私掠", + content: function (storage, player) { + return "被" + get.translation(storage) + "盯上了!"; + }, + }, + }, + robbed: { onremove: true, charlotte: true }, }, - content:function(){ - 'step 0' - player.awakenSkill('dcshuaijie'); + }, + dcshuaijie: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + var targets = player.getStorage("dcsilve").filter((i) => i.isIn()); + if (!targets.length) return true; + return ( + targets.filter((target) => { + return player.hp > target.hp && player.countCards("e") > target.countCards("e"); + }).length == targets.length + ); + }, + content: function () { + "step 0"; + player.awakenSkill("dcshuaijie"); player.loseMaxHp(); - var choices=[]; - var choiceList=[ - '获得“私掠”角色至多三张牌', - '从牌堆中获得三张类型各不相同的牌' - ]; - var targets=player.getStorage('dcsilve').filter(i=>i.isIn()); - event.targets=targets; - if(targets.length) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - choices.push('选项二'); - player.chooseControl(choices).set('prompt','衰劫:选择一项').set('choiceList',choiceList).set('ai',()=>_status.event.choice).set('choice',function(){ - var eff=0; - for(var target of targets){ - eff+=get.effect(target,{name:'shunshou_copy2'},player,player)*2; - } - eff-=get.effect(player,{name:'dongzhuxianji'},player,player); - return eff>0&&choices.includes('选项一')?'选项一':'选项二'; - }()); - 'step 1' - if(result.control=='选项一'){ - if(targets.length){ - for(var target of targets){ - if(target.countGainableCards(player,'he')>0) { + var choices = []; + var choiceList = ["获得“私掠”角色至多三张牌", "从牌堆中获得三张类型各不相同的牌"]; + var targets = player.getStorage("dcsilve").filter((i) => i.isIn()); + event.targets = targets; + if (targets.length) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + choices.push("选项二"); + player + .chooseControl(choices) + .set("prompt", "衰劫:选择一项") + .set("choiceList", choiceList) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + var eff = 0; + for (var target of targets) { + eff += get.effect(target, { name: "shunshou_copy2" }, player, player) * 2; + } + eff -= get.effect(player, { name: "dongzhuxianji" }, player, player); + return eff > 0 && choices.includes("选项一") ? "选项一" : "选项二"; + })() + ); + "step 1"; + if (result.control == "选项一") { + if (targets.length) { + for (var target of targets) { + if (target.countGainableCards(player, "he") > 0) { player.line(target); - player.gainPlayerCard(target,'he',true,[1,3]); + player.gainPlayerCard(target, "he", true, [1, 3]); } } } - } - else{ - var cards=[]; - for(var i=0;i<3;i++){ - var card=get.cardPile(cardx=>{ - return cards.filter(cardxx=>get.type2(cardxx)==get.type2(cardx)).length==0; + } else { + var cards = []; + for (var i = 0; i < 3; i++) { + var card = get.cardPile((cardx) => { + return ( + cards.filter((cardxx) => get.type2(cardxx) == get.type2(cardx)).length == + 0 + ); }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); } - 'step 2' - var targets=player.getStorage('dcsilve').filter(i=>i.isIn()); - for(var target of targets){ - target.unmarkAuto('dcsilve_target',[player]); + "step 2"; + var targets = player.getStorage("dcsilve").filter((i) => i.isIn()); + for (var target of targets) { + target.unmarkAuto("dcsilve_target", [player]); } delete player.storage.dcsilve; delete player.storage.dcsilve_self; - player.markAuto('dcsilve',[player]); - player.markAuto('dcsilve_self',[player]); + player.markAuto("dcsilve", [player]); + player.markAuto("dcsilve_self", [player]); }, - ai:{ - combo:'dcsilve', - order:8, - result:{ - player:function(player){ - var targets=player.getStorage('dcsilve').filter(i=>i.isIn()); - if(!targets.length) return 1; - var att=0; - targets.forEach(i=>att+=get.attitude(player,i)); - if(att<0) return 1; + ai: { + combo: "dcsilve", + order: 8, + result: { + player: function (player) { + var targets = player.getStorage("dcsilve").filter((i) => i.isIn()); + if (!targets.length) return 1; + var att = 0; + targets.forEach((i) => (att += get.attitude(player, i))); + if (att < 0) return 1; return 0; - } - } - } + }, + }, + }, }, //庞会 - dcyiyong:{ - audio:2, - trigger:{ - source:'damageBegin1', + dcyiyong: { + audio: 2, + trigger: { + source: "damageBegin1", }, //usable:2, - filter:function(event,player){ - return player.countDiscardableCards(player,'he')>0&&player!=event.player; + filter: function (event, player) { + return player.countDiscardableCards(player, "he") > 0 && player != event.player; }, - check:function(event,player){ - return get.attitude(player,event.player)<0&&player.countCards('he',card=>lib.filter.cardDiscardable(card,player,'dcyiyong')&&get.value(card,player)<7)>0; + check: function (event, player) { + return ( + get.attitude(player, event.player) < 0 && + player.countCards( + "he", + (card) => + lib.filter.cardDiscardable(card, player, "dcyiyong") && + get.value(card, player) < 7 + ) > 0 + ); }, - logTarget:'player', - content:function(){ - 'step 0' - event.list=[player]; - event.cards0=[];event.cards1=[]; - if(trigger.player.countDiscardableCards(trigger.player,'he')>0){ + logTarget: "player", + content: function () { + "step 0"; + event.list = [player]; + event.cards0 = []; + event.cards1 = []; + if (trigger.player.countDiscardableCards(trigger.player, "he") > 0) { event.list.push(trigger.player); } - if(!event.isMine()&&!event.isOnline()) game.delayx(); - player.chooseCardOL(event.list,'he',true,[1,Infinity],'异勇:弃置任意张牌',(card,player,target)=>{ - return lib.filter.cardDiscardable(card,player,'dcyiyong'); - }).set('ai',card=>{ - var evt=_status.event.getParent(2); - var source=evt.player,player=_status.event.player,target=evt.list[1]; - if(!target) return get.unuseful(card); - if(player==source){ - var total=0,need=0; - target.countCards('he',card=>{ - if(lib.filter.cardDiscardable(card,target,'dcyiyong')&&get.value(card)<5) need+=get.number(card); - }); - for(var i of ui.selected.cards) total+=get.number(i); - if(total>=need+5) return 0; - var val=6; - if(target.hp<=2&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:evt.getTrigger().card, - })) val+=2+get.number(card)/5; - if(target.countCards('he',card=>get.value(card)<5)>=3) val-=3+get.number(card)/5; - return val-get.value(card); - } - if(ui.selected.cards.length>1&&ui.selected.cards.length+2>=source.countCards('he')) return 0; - if(player.hp<=2&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:evt.getTrigger().card, - })) return 10-get.value(card); - return 5-get.value(card); - }); - 'step 1' - var lose_list=[],cards=[]; - for(var i=0; i { + return lib.filter.cardDiscardable(card, player, "dcyiyong"); + } + ) + .set("ai", (card) => { + var evt = _status.event.getParent(2); + var source = evt.player, + player = _status.event.player, + target = evt.list[1]; + if (!target) return get.unuseful(card); + if (player == source) { + var total = 0, + need = 0; + target.countCards("he", (card) => { + if ( + lib.filter.cardDiscardable(card, target, "dcyiyong") && + get.value(card) < 5 + ) + need += get.number(card); + }); + for (var i of ui.selected.cards) total += get.number(i); + if (total >= need + 5) return 0; + var val = 6; + if ( + target.hp <= 2 && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: evt.getTrigger().card, + }) + ) + val += 2 + get.number(card) / 5; + if (target.countCards("he", (card) => get.value(card) < 5) >= 3) + val -= 3 + get.number(card) / 5; + return val - get.value(card); + } + if ( + ui.selected.cards.length > 1 && + ui.selected.cards.length + 2 >= source.countCards("he") + ) + return 0; + if ( + player.hp <= 2 && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: evt.getTrigger().card, + }) + ) + return 10 - get.value(card); + return 5 - get.value(card); + }); + "step 1"; + var lose_list = [], + cards = []; + for (var i = 0; i < result.length; i++) { + var current = event.list[i], + cards2 = result[i].cards; cards.push(cards2); - event['cards'+i]=cards2; - event.cards=cards; - lose_list.push([current,cards2]); + event["cards" + i] = cards2; + event.cards = cards; + lose_list.push([current, cards2]); } - game.loseAsync({lose_list:lose_list}).setContent('discardMultiple'); - 'step 2' - var getn=function(cards){ - return cards.map(i=>get.number(i,false)).reduce((p,c)=>p+c,0) - } - var num0=getn(event.cards0),num1=getn(event.cards1); - if(num0<=num1){ + game.loseAsync({ lose_list: lose_list }).setContent("discardMultiple"); + "step 2"; + var getn = function (cards) { + return cards.map((i) => get.number(i, false)).reduce((p, c) => p + c, 0); + }; + var num0 = getn(event.cards0), + num1 = getn(event.cards1); + if (num0 <= num1) { player.draw(event.cards1.length); } - if(num0>=num1){ + if (num0 >= num1) { trigger.num++; } - } + }, }, //乐就 - dccuijin:{ - audio:2, - trigger:{global:'useCard'}, - filter:function(event,player){ - return (event.card.name=='sha'||event.card.name=='juedou')&&(event.player==player||player.inRange(event.player))&&player.countCards('he')>0; + dccuijin: { + audio: 2, + trigger: { global: "useCard" }, + filter: function (event, player) { + return ( + (event.card.name == "sha" || event.card.name == "juedou") && + (event.player == player || player.inRange(event.player)) && + player.countCards("he") > 0 + ); }, - direct:true, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isOnline()) game.delayx(); - var target=trigger.player; - event.target=target; - player.chooseToDiscard('he',get.prompt('dccuijin',target),'弃置一张牌并令'+get.translation(trigger.player)+'使用的'+get.translation(trigger.card)+'伤害+1,但若其未造成伤害,则你摸两张牌并对其造成1点伤害。').set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('goon',lib.skill.cuijin.checkx(trigger,player)).logSkill=['dccuijin',target]; - 'step 1' - if(result.bool){ - if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + direct: true, + content: function () { + "step 0"; + if (player != game.me && !player.isOnline()) game.delayx(); + var target = trigger.player; + event.target = target; + player + .chooseToDiscard( + "he", + get.prompt("dccuijin", target), + "弃置一张牌并令" + + get.translation(trigger.player) + + "使用的" + + get.translation(trigger.card) + + "伤害+1,但若其未造成伤害,则你摸两张牌并对其造成1点伤害。" + ) + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", lib.skill.cuijin.checkx(trigger, player)).logSkill = [ + "dccuijin", + target, + ]; + "step 1"; + if (result.bool) { + if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1; trigger.baseDamage++; - player.addSkill('dccuijin_damage'); - player.markAuto('dccuijin_damage',[trigger.card]); - if(!player.storage.dccuijin_map) player.storage.dccuijin_map={cards:[],targets:[]}; + player.addSkill("dccuijin_damage"); + player.markAuto("dccuijin_damage", [trigger.card]); + if (!player.storage.dccuijin_map) + player.storage.dccuijin_map = { cards: [], targets: [] }; player.storage.dccuijin_map.cards.push(trigger.card); player.storage.dccuijin_map.targets.push(trigger.targets.slice()); } }, - subSkill:{ - damage:{ - trigger:{ - global:['damage','damageCancelled','damageZero','shaMiss','useCardToExcluded','useCardToEnd','eventNeutralized','useCardAfter','shaCancelled'], + subSkill: { + damage: { + trigger: { + global: [ + "damage", + "damageCancelled", + "damageZero", + "shaMiss", + "useCardToExcluded", + "useCardToEnd", + "eventNeutralized", + "useCardAfter", + "shaCancelled", + ], }, - forced:true, - silent:true, - firstDo:true, - charlotte:true, - onremove:true, - filter:function(event,player,name){ - if(!event.card) return false; - var cards=player.getStorage('dccuijin_damage'); - if(!cards.includes(event.card)) return false; + forced: true, + silent: true, + firstDo: true, + charlotte: true, + onremove: true, + filter: function (event, player, name) { + if (!event.card) return false; + var cards = player.getStorage("dccuijin_damage"); + if (!cards.includes(event.card)) return false; return true; }, - content:function(){ - 'step 0' - var card=trigger.card,idx=player.storage.dccuijin_map.cards.indexOf(card); - if(event.triggername=='useCardAfter'){ - var cards=player.getStorage('dccuijin_damage'); - cards=cards.remove(card); - if(!cards.length){ - player.removeSkill('dccuijin_damage'); + content: function () { + "step 0"; + var card = trigger.card, + idx = player.storage.dccuijin_map.cards.indexOf(card); + if (event.triggername == "useCardAfter") { + var cards = player.getStorage("dccuijin_damage"); + cards = cards.remove(card); + if (!cards.length) { + player.removeSkill("dccuijin_damage"); delete player.storage.dccuijin_map; - } - else if(idx!==-1){ - player.storage.dccuijin_map.cards.splice(idx,1); - player.storage.dccuijin_map.targets.splice(idx,1); + } else if (idx !== -1) { + player.storage.dccuijin_map.cards.splice(idx, 1); + player.storage.dccuijin_map.targets.splice(idx, 1); } event.finish(); - } - else if(idx!==-1){ - var target,source; - if(trigger.name.indexOf('damage')==0){ - target=trigger.player; - source=trigger.source; + } else if (idx !== -1) { + var target, source; + if (trigger.name.indexOf("damage") == 0) { + target = trigger.player; + source = trigger.source; + } else { + target = trigger.target; + source = trigger.player; } - else{ - target=trigger.target; - source=trigger.player; - } - if(player.storage.dccuijin_map.targets[idx].includes(target)&&!target.hasHistory('damage',evt=>{ - return evt.card==card; - })){ - player.logSkill('dccuijin_damage',source); + if ( + player.storage.dccuijin_map.targets[idx].includes(target) && + !target.hasHistory("damage", (evt) => { + return evt.card == card; + }) + ) { + player.logSkill("dccuijin_damage", source); player.storage.dccuijin_map.targets[idx].remove(target); player.draw(2); - if(source&&source.isIn()){ - player.line(trigger.player,'green'); + if (source && source.isIn()) { + player.line(trigger.player, "green"); trigger.player.damage(); } } } - 'step 1' + "step 1"; game.delayx(); }, }, }, }, //陈矫 - dcxieshou:{ - trigger:{ - global:'damageEnd', + dcxieshou: { + trigger: { + global: "damageEnd", }, - usable:1, - filter:function(event,player){ - return get.distance(player,event.player)<=2&&event.player.isIn(); + usable: 1, + filter: function (event, player) { + return get.distance(player, event.player) <= 2 && event.player.isIn(); }, - check:function(event,player){ - return get.attitude(player,event.player)>4; + check: function (event, player) { + return get.attitude(player, event.player) > 4; }, - locked:false, - logTarget:'player', - onremove:true, - change:function(player,num){ - player.addSkill('dcxieshoux'); - if(typeof player.storage.dcxieshoux!=='number') player.storage.dcxieshoux=0; - if(!num) return; - player.storage.dcxieshoux+=num; - if(player.storage.dcxieshoux!=0) player.markSkill('dcxieshoux'); - else player.unmarkSkill('dcxieshoux'); - game.log(player,'的手牌上限',(num>0?'+':'')+num); + locked: false, + logTarget: "player", + onremove: true, + change: function (player, num) { + player.addSkill("dcxieshoux"); + if (typeof player.storage.dcxieshoux !== "number") player.storage.dcxieshoux = 0; + if (!num) return; + player.storage.dcxieshoux += num; + if (player.storage.dcxieshoux != 0) player.markSkill("dcxieshoux"); + else player.unmarkSkill("dcxieshoux"); + game.log(player, "的手牌上限", (num > 0 ? "+" : "") + num); }, - content:function(){ - 'step 0' - lib.skill.dcxieshou.change(player,-1); - 'step 1' - var list=[],target=trigger.player; - event.target=target; - var choiceList=['回复1点体力','复原,摸两张牌']; - if(target.getDamagedHp()==0) choiceList[0]=''+choiceList[0]+''; - else list.push('选项一'); - list.push('选项二'); - target.chooseControl(list).set('choiceList',choiceList).set('prompt',get.translation(player)+'对你发动了【协守】,请选择一项'); - 'step 2' - if(result.control=='选项一'){ + content: function () { + "step 0"; + lib.skill.dcxieshou.change(player, -1); + "step 1"; + var list = [], + target = trigger.player; + event.target = target; + var choiceList = ["回复1点体力", "复原,摸两张牌"]; + if (target.getDamagedHp() == 0) + choiceList[0] = '' + choiceList[0] + ""; + else list.push("选项一"); + list.push("选项二"); + target + .chooseControl(list) + .set("choiceList", choiceList) + .set("prompt", get.translation(player) + "对你发动了【协守】,请选择一项"); + "step 2"; + if (result.control == "选项一") { target.recover(); - } - else { + } else { target.link(false); target.draw(2); } }, - ai:{ - expose:0.3, + ai: { + expose: 0.3, }, }, - dcxieshoux:{ - markimage:'image/card/handcard.png', - intro:{ - content:function(storage,player){ - var num=player.storage.dcxieshoux; - return '手牌上限'+(num >= 0?'+':'')+num; - } - }, - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+(player.storage.dcxieshoux||0); - } - }, - }, - dcqingyan:{ - trigger:{ - target:'useCardToTargeted', - }, - filter:function(event,player){ - return event.player!=player&&get.color(event.card)=='black'; - }, - usable:2, - direct:true, - content:function(){ - 'step 0' - if(player.countCards('h')1); - }else{ - player.chooseToDiscard(get.prompt('dcqingyan'),'弃置一张手牌令你的手牌上限+1').set('ai',card=>6-get.value(card)).set('logSkill','dcqingyan'); - } - 'step 1' - if(result.bool){ - if(result.cards&&result.cards.length){ - lib.skill.dcxieshou.change(player,1); - }else{ - player.logSkill('dcqingyan'); - player.drawTo(player.maxHp); - } - } else player.storage.counttrigger.dcqingyan--; - } - }, - dcqizi:{ - mod:{ - cardSavable:function(card,player,target){ - if(get.distance(player,target)>2&&card.name=='tao'&&target==_status.event.dying) return false; + dcxieshoux: { + markimage: "image/card/handcard.png", + intro: { + content: function (storage, player) { + var num = player.storage.dcxieshoux; + return "手牌上限" + (num >= 0 ? "+" : "") + num; }, - } + }, + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + (player.storage.dcxieshoux || 0); + }, + }, + }, + dcqingyan: { + trigger: { + target: "useCardToTargeted", + }, + filter: function (event, player) { + return event.player != player && get.color(event.card) == "black"; + }, + usable: 2, + async cost(event, trigger, player) { + if (player.countCards("h") < player.hp) { + event.result = await player + .chooseBool( + get.prompt("dcqingyan"), + "将手牌摸至体力上限(摸" + + get.cnNumber(player.maxHp - player.countCards("h")) + + "张牌)" + ) + .set("ai", () => 1) + .forResult(); + } else { + event.result = await player + .chooseToDiscard( + get.prompt("dcqingyan"), + "弃置一张手牌令你的手牌上限+1", + "chooseonly" + ) + .set("ai", (card) => 6 - get.value(card)) + .forResult(); + } + }, + async content(event, trigger, player) { + if (event.cards && event.cards.length) { + await player.discard(event.cards); + lib.skill.dcxieshou.change(player, 1); + } else { + player.drawTo(player.maxHp); + } + }, + }, + dcqizi: { + mod: { + cardSavable: function (card, player, target) { + if ( + get.distance(player, target) > 2 && + card.name == "tao" && + target == _status.event.dying + ) + return false; + }, + }, + ai: { + neg: true + }, }, //公孙度 - dczhenze:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - direct:true, - content:function(){ - 'step 0' - var getCond=(player)=>Math.sign(player.countCards('h')-Math.max(0,player.hp)); - var me=getCond(player); - var recovers=game.filterPlayer(current=>getCond(current)==me),loses=game.filterPlayer().removeArray(recovers); - event.recovers=recovers; event.loses=loses; - var list=[]; - if(loses.length) list.push('选项一'); - if(recovers.length) list.push('选项二'); - list.push('cancel2'); - var sign=[['≥','<'],['≠','='],['≤','>']]; - var choiceList=[ - '令所有手牌数'+sign[me+1][0]+'体力值的角色失去1点体力'+(loses.length?'('+get.translation(loses)+')':''), - '令所有手牌数'+sign[me+1][1]+'体力值的角色回复1点体力'+(recovers.length?'('+get.translation(recovers)+')':'') + dczhenze: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + direct: true, + content: function () { + "step 0"; + var getCond = (player) => Math.sign(player.countCards("h") - Math.max(0, player.hp)); + var me = getCond(player); + var recovers = game.filterPlayer((current) => getCond(current) == me), + loses = game.filterPlayer().removeArray(recovers); + event.recovers = recovers; + event.loses = loses; + var list = []; + if (loses.length) list.push("选项一"); + if (recovers.length) list.push("选项二"); + list.push("cancel2"); + var sign = [ + ["≥", "<"], + ["≠", "="], + ["≤", ">"], ]; - if(!loses.length) choiceList[0]=''+choiceList[0]+''; - if(!recovers.length) choiceList[1]=''+choiceList[1]+''; - player.chooseControl(list).set('choiceList',choiceList).set('prompt',get.prompt('dczhenze')).set('ai',()=>_status.event.choice).set('choice',(()=>{ - var effect=0; - if(list.length==2){ - if(list.includes('选项一')){ - loses.forEach(i=>effect+=get.effect(i,{name:'losehp'},player,player)); - if(effect>0) return '选项一'; - }else{ - recovers.forEach(i=>effect+=get.recoverEffect(i,player,player)); - if(effect>0) return '选项二'; - } - }else{ - loses.forEach(i=>effect+=get.effect(i,{name:'losehp'},player,player)); - recovers.forEach(i=>effect+=get.recoverEffect(i,player,player)); - if(effect>0) return '选项二'; - return '选项一'; - } - })()); - 'step 1' - if(result.control=='cancel2'){ + var choiceList = [ + "令所有手牌数" + + sign[me + 1][0] + + "体力值的角色失去1点体力" + + (loses.length ? "(" + get.translation(loses) + ")" : ""), + "令所有手牌数" + + sign[me + 1][1] + + "体力值的角色回复1点体力" + + (recovers.length ? "(" + get.translation(recovers) + ")" : ""), + ]; + if (!loses.length) + choiceList[0] = '' + choiceList[0] + ""; + if (!recovers.length) + choiceList[1] = '' + choiceList[1] + ""; + player + .chooseControl(list) + .set("choiceList", choiceList) + .set("prompt", get.prompt("dczhenze")) + .set("ai", () => _status.event.choice) + .set( + "choice", + (() => { + var effect = 0; + if (list.length == 2) { + if (list.includes("选项一")) { + loses.forEach( + (i) => + (effect += get.effect(i, { name: "losehp" }, player, player)) + ); + if (effect > 0) return "选项一"; + } else { + recovers.forEach( + (i) => (effect += get.recoverEffect(i, player, player)) + ); + if (effect > 0) return "选项二"; + } + } else { + loses.forEach( + (i) => (effect += get.effect(i, { name: "losehp" }, player, player)) + ); + recovers.forEach((i) => (effect += get.recoverEffect(i, player, player))); + if (effect > 0) return "选项二"; + return "选项一"; + } + })() + ); + "step 1"; + if (result.control == "cancel2") { event.finish(); - } - else { - var lose=result.control=='选项一',targets=event[lose?'loses':'recovers']; - player.logSkill('dczhenze',targets); - for(var i of targets){ - i[lose?'loseHp':'recover'](); + } else { + var lose = result.control == "选项一", + targets = event[lose ? "loses" : "recovers"]; + player.logSkill("dczhenze", targets); + for (var i of targets) { + i[lose ? "loseHp" : "recover"](); } } - } + }, }, - dcanliao:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if((player.getStat().skill.dcanliao||0)>=game.countPlayer(current=>current.group=='qun')) return false; + dcanliao: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if ( + (player.getStat().skill.dcanliao || 0) >= + game.countPlayer((current) => current.group == "qun") + ) + return false; return true; }, - filterTarget:function(card,player,target){ - return target.countCards('he'); + filterTarget: function (card, player, target) { + return target.countCards("he"); }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'he',true).set('filterButton',function(button){ - var card=button.link,owner=get.owner(card); - return !owner||owner.canRecast(card,_status.event.player); - }).set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().target)>=0) return -get.buttonValue(card); - return get.buttonValue(card); - }); - 'step 1' - if(result.bool) target.recast(result.links); + content: function () { + "step 0"; + player + .choosePlayerCard(target, "he", true) + .set("filterButton", function (button) { + var card = button.link, + owner = get.owner(card); + return !owner || owner.canRecast(card, _status.event.player); + }) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.getParent().target) >= 0) + return -get.buttonValue(card); + return get.buttonValue(card); + }); + "step 1"; + if (result.bool) target.recast(result.links); }, - ai:{ - expose:0.1, - result:{ - target:function(player,target){ - if(target.hasCard(card=>get.value(card)>=6,'e')&&get.attitude(player,target)<0) return -1; + ai: { + expose: 0.1, + result: { + target: function (player, target) { + if ( + target.hasCard((card) => get.value(card) >= 6, "e") && + get.attitude(player, target) < 0 + ) + return -1; return 1; - } - } - } + }, + }, + }, }, //王烈 - dcchongwang:{ - audio:2, - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - if(player==event.player) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - var history=game.getAllGlobalHistory('useCard'); - var index=history.indexOf(event); - if(index>0) return history[index-1].player==player; + dcchongwang: { + audio: 2, + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + if (player == event.player) return false; + var type = get.type(event.card); + if (type != "basic" && type != "trick") return false; + var history = game.getAllGlobalHistory("useCard"); + var index = history.indexOf(event); + if (index > 0) return history[index - 1].player == player; return false; }, - content:function(){ - 'step 0' - var source=trigger.player; - var list=[['exclude','令'+get.translation(trigger.card)+'无效']]; - var cards=trigger.cards.filterInD(); - if(source.isIn()&&cards.length>0) list.push(['gain','令'+get.translation(source)+'收回'+get.translation(cards)]); - player.chooseButton([ - get.prompt('dcchongwang',source), - [list,'textbutton'], - 'noforcebutton', - ]).set('ai',function(button){ - var player=_status.event.player,choice=button.link; - var evt=_status.event.getTrigger(); - if(choice=='exclude'){ - var effect=0; - if(!evt.targets.length&&get.info(evt.card,false).notarget) effect-=get.effect(evt.player,evt.card,evt.player,player); - for(var i of evt.targets){ - effect-=get.effect(i,evt.card,evt.player,player); + content: function () { + "step 0"; + var source = trigger.player; + var list = [["exclude", "令" + get.translation(trigger.card) + "无效"]]; + var cards = trigger.cards.filterInD(); + if (source.isIn() && cards.length > 0) + list.push(["gain", "令" + get.translation(source) + "收回" + get.translation(cards)]); + player + .chooseButton([ + get.prompt("dcchongwang", source), + [list, "textbutton"], + "noforcebutton", + ]) + .set("ai", function (button) { + var player = _status.event.player, + choice = button.link; + var evt = _status.event.getTrigger(); + if (choice == "exclude") { + var effect = 0; + if (!evt.targets.length && get.info(evt.card, false).notarget) + effect -= get.effect(evt.player, evt.card, evt.player, player); + for (var i of evt.targets) { + effect -= get.effect(i, evt.card, evt.player, player); + } + return effect; + } else { + var cards = evt.cards.filterInD(); + return get.value(cards, evt.player) * get.attitude(player, evt.player); } - return effect; - } - else{ - var cards=evt.cards.filterInD(); - return get.value(cards,evt.player)*get.attitude(player,evt.player); - } - }) - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.logSkill('dcchongwang',trigger.player); - if(result.links[0]=='gain'){ - player.addTempSkill('dcchongwang_gain'); - trigger._dcchongwang=true; - } - else{ - trigger.targets.length=0; - trigger.all_excluded=true; - game.log(trigger.card,'被无效了'); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + if (result.bool) { + player.logSkill("dcchongwang", trigger.player); + if (result.links[0] == "gain") { + player.addTempSkill("dcchongwang_gain"); + trigger._dcchongwang = true; + } else { + trigger.targets.length = 0; + trigger.all_excluded = true; + game.log(trigger.card, "被无效了"); } } }, - ai:{ - threaten:3.5, - directHit_ai:true, + ai: { + threaten: 3.5, + directHit_ai: true, }, - subSkill:{ - gain:{ - trigger:{global:'useCardAfter'}, - charlotte:true, - forced:true, - popup:false, - filter:function(event,player){ + subSkill: { + gain: { + trigger: { global: "useCardAfter" }, + charlotte: true, + forced: true, + popup: false, + filter: function (event, player) { return event._dcchongwang; }, - content:function(){ - trigger.player.gain(trigger.cards.filterInD(),'gain2'); - } - } - } + content: function () { + trigger.player.gain(trigger.cards.filterInD(), "gain2"); + }, + }, + }, }, - dchuagui:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; + dchuagui: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; }); }, - content:function(){ - 'step 0' - var min=Math.max.apply(Math,game.filterPlayer().map(function(current){ - return 1+current.getFriends().length; - })); - var max=Math.min(min,game.countPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - })); - player.chooseTarget(get.prompt('dchuagui'),'令至多'+get.cnNumber(max)+'名角色进行囚徒困境选择',[1,max],function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('animate',false).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - player.logSkill('dchuagui'); - event.players=result.targets.slice(0); - event._global_waiting=true; - } - else event.finish(); - 'step 2' - var send=function(source){ - var next=game.createEvent('dchuagui_choose',false); - next.player=game.me; - next.source=source; + content: function () { + "step 0"; + var min = Math.max.apply( + Math, + game.filterPlayer().map(function (current) { + return 1 + current.getFriends().length; + }) + ); + var max = Math.min( + min, + game.countPlayer(function (current) { + return current != player && current.countCards("he") > 0; + }) + ); + player + .chooseTarget( + get.prompt("dchuagui"), + "令至多" + get.cnNumber(max) + "名角色进行囚徒困境选择", + [1, max], + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("animate", false) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("dchuagui"); + event.players = result.targets.slice(0); + event._global_waiting = true; + } else event.finish(); + "step 2"; + var send = function (source) { + var next = game.createEvent("dchuagui_choose", false); + next.player = game.me; + next.source = source; next.setContent(lib.skill.dchuagui.contentx); game.resume(); }; - var sendback=function(result,player){ - if(!Array.isArray(result)){ - result=[ - Math.random()<0.5?'仅展示牌':'交出牌', - player.getCards('he').randomGet() + var sendback = function (result, player) { + if (!Array.isArray(result)) { + result = [ + Math.random() < 0.5 ? "仅展示牌" : "交出牌", + player.getCards("he").randomGet(), ]; } - event.results.push([player,result]); + event.results.push([player, result]); }; - event.ai_targets=[]; - event.results=[]; - var players=game.filterPlayer(function(current){ - return current!=player; - }).sortBySeat(); - var time=10000; - if(lib.configOL&&lib.configOL.choose_timeout) time=parseInt(lib.configOL.choose_timeout)*1000; - for(var i=0;iget.value(b,target)-get.value(a,target)); - var choice='仅展示牌',card=hs[0]; - if(att<-2&&Math.random()>((get.value(card,target)-3)/5)) choice='交出牌'; - sendback([choice,card],target); - if(!event.ai_targets.length){ - clearInterval(event.interval); - if(event.withai) game.resume(); - } - },_status.connectMove?750:75); - },500) + setTimeout(function () { + event.interval = setInterval( + function () { + var target = event.ai_targets.shift(); + var att = get.attitude(target, player), + hs = target.getCards("he"); + hs.sort((b, a) => get.value(b, target) - get.value(a, target)); + var choice = "仅展示牌", + card = hs[0]; + if (att < -2 && Math.random() > (get.value(card, target) - 3) / 5) + choice = "交出牌"; + sendback([choice, card], target); + if (!event.ai_targets.length) { + clearInterval(event.interval); + if (event.withai) game.resume(); + } + }, + _status.connectMove ? 750 : 75 + ); + }, 500); } - 'step 3' - if(event.withme){ - if(_status.connectMode) game.me.unwait(result,game.me); - else{ - if(!Array.isArray(result)){ - result=[ - Math.random()<0.5?'仅展示牌':'交出牌', - player.getCards('he').randomGet() + "step 3"; + if (event.withme) { + if (_status.connectMode) game.me.unwait(result, game.me); + else { + if (!Array.isArray(result)) { + result = [ + Math.random() < 0.5 ? "仅展示牌" : "交出牌", + player.getCards("he").randomGet(), ]; } - event.results.push([player,result]); + event.results.push([player, result]); } } - 'step 4' - if(event.withol&&!event.resultOL){ + "step 4"; + if (event.withol && !event.resultOL) { game.pause(); } - 'step 5' - if(event.ai_targets.length>0){ - event.withai=true; + "step 5"; + if (event.ai_targets.length > 0) { + event.withai = true; game.pause(); } - 'step 6' + "step 6"; delete event._global_waiting; - for(var i of game.players) i.hideTimer(); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(name,id,results){ - var dialog=ui.create.dialog(name+'发动了技能【化归】','hidden','forcebutton'); - dialog.videoId=id; - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.buttonss=[]; + for (var i of game.players) i.hideTimer(); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (name, id, results) { + var dialog = ui.create.dialog( + name + "发动了技能【化归】", + "hidden", + "forcebutton" + ); + dialog.videoId = id; + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.buttonss = []; - var list=['仅展示牌的玩家','交出牌的玩家'] - for(var i=0;i'+list[i]+''); - var buttons=ui.create.div('.buttons',dialog.content); - dialog.buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - } - dialog.open(); + var list = ["仅展示牌的玩家", "交出牌的玩家"]; + for (var i = 0; i < list.length; i++) { + dialog.add('
              ' + list[i] + "
              "); + var buttons = ui.create.div(".buttons", dialog.content); + dialog.buttonss.push(buttons); + buttons.classList.add("popup"); + buttons.classList.add("guanxing"); + } + dialog.open(); - var getx=function(){ - var item=results.shift(); - var card=item[1][1],index=item[1][0]=='仅展示牌'?0:1; - var button=ui.create.button(card,'card',dialog.buttonss[index]); - button.querySelector('.info').innerHTML=(function(target){ - if(target._tempTranslate) return target._tempTranslate; - var name=target.name; - if(lib.translate[name+'_ab']) return lib.translate[name+'_ab']; - return get.translation(name); - }(item[0])); - if(results.length>0) setTimeout(getx,500); - } - setTimeout(getx,500); - },get.translation(player),event.videoId,event.results.slice(0)); - game.delay(0,2000+event.results.length*500) - 'step 7' - game.broadcastAll('closeDialog',event.videoId); - var shown=[],given=[]; - for(var i of event.results){ - (i[1][0]=='仅展示牌'?shown:given).push(i); + var getx = function () { + var item = results.shift(); + var card = item[1][1], + index = item[1][0] == "仅展示牌" ? 0 : 1; + var button = ui.create.button(card, "card", dialog.buttonss[index]); + button.querySelector(".info").innerHTML = (function (target) { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; + return get.translation(name); + })(item[0]); + if (results.length > 0) setTimeout(getx, 500); + }; + setTimeout(getx, 500); + }, + get.translation(player), + event.videoId, + event.results.slice(0) + ); + game.delay(0, 2000 + event.results.length * 500); + "step 7"; + game.broadcastAll("closeDialog", event.videoId); + var shown = [], + given = []; + for (var i of event.results) { + (i[1][0] == "仅展示牌" ? shown : given).push(i); } - var list=given.length>0?given:shown; - var cards=[],targets=[]; - for(var i of list){ + var list = given.length > 0 ? given : shown; + var cards = [], + targets = []; + for (var i of list) { cards.push(i[1][1]); targets.push(i[0]); //i[0].$give(i[1][1],player); } player.line(targets); - player.gain(cards,'give'); + player.gain(cards, "give"); //step 8 //game.delayx(); }, - contentx:function(){ - 'step 0' - event._global_waiting=true; - event.result=['仅展示牌',player.getCards('he').randomGet()]; - var str=get.translation(source); - player.chooseControl('仅展示牌','交出牌').set('choiceList',[ - '仅展示一张牌。但如果所有人都选择了仅展示,则'+str+'获得这张牌', - '将一张牌交给'+str, - ]).set('_global_waiting',true); - 'step 1' - event.result[0]=result.control; - player.chooseCard('he',true).set('_global_waiting',true); - 'step 2' - event.result[1]=result.cards[0]; + contentx: function () { + "step 0"; + event._global_waiting = true; + event.result = ["仅展示牌", player.getCards("he").randomGet()]; + var str = get.translation(source); + player + .chooseControl("仅展示牌", "交出牌") + .set("choiceList", [ + "仅展示一张牌。但如果所有人都选择了仅展示,则" + str + "获得这张牌", + "将一张牌交给" + str, + ]) + .set("_global_waiting", true); + "step 1"; + event.result[0] = result.control; + player.chooseCard("he", true).set("_global_waiting", true); + "step 2"; + event.result[1] = result.cards[0]; }, }, //陈珪 - dcyingtu:{ - audio:2, - trigger:{ - global:['gainAfter','loseAsyncAfter'], + dcyingtu: { + audio: 2, + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - usable:1, - filter:function(event,player){ - return lib.skill.dcyingtu.filterx(event,player,player.getNext())||lib.skill.dcyingtu.filterx(event,player,player.getPrevious()); + usable: 1, + getIndex(event, player) { + var targets = []; + if (lib.skill.dcyingtu.filterx(event, player, player.getNext())) + targets.add(player.getNext()); + if (lib.skill.dcyingtu.filterx(event, player, player.getPrevious())) + targets.add(player.getPrevious()); + return targets.sortBySeat(_status.currentPhase); }, - filterx:function(event,player,target){ - var evt=event.getParent('phaseDraw'); - if(evt&&target==evt.player) return false; - return event.getg(target).length>0&&target.hasCard(function(card){ - return lib.filter.canBeGained(card,target,player) - },'he'); + filterx: function (event, player, target) { + var evt = event.getParent("phaseDraw"); + if (evt && target == evt.player) return false; + return ( + event.getg(target).length > 0 && + target.hasCard(function (card) { + return lib.filter.canBeGained(card, target, player); + }, "he") + ); }, - logTarget:'player', - direct:true, - checkx:function(player,source){ - var target=(source==player.getNext()?player.getPrevious():player.getNext()); - return Math.min(0,get.attitude(player,target))>=get.attitude(player,source); + logTarget(event, player, triggername, target) { + return target; }, - content:function(){ - 'step 0' - var targets=[]; - event.targets=targets; - if(lib.skill.dcyingtu.filterx(trigger,player,player.getNext())) targets.add(player.getNext()); - if(lib.skill.dcyingtu.filterx(trigger,player,player.getPrevious())) targets.add(player.getPrevious()); - 'step 1' - var target=targets.shift(); - event.target=target; - player.chooseBool( - get.prompt('dcyingtu',target), - '获得该角色的一张牌,然后将一张牌交给该角色的对位角色。若你给出的是装备牌,则其使用其得到的牌。' - ).set('goon',lib.skill.dcyingtu.checkx(player,target)).set('ai',function(){ - return _status.event.goon; - }); - 'step 2' - if(result.bool){ - player.logSkill('dcyingtu',target); - var next=game.createEvent('dcyingtu_insert'); - next.player=player; - next.target=target; - next.setContent(lib.skill.dcyingtu.contentx); - event.finish(); - } - else if(targets.length>0) event.goto(1); - else player.storage.counttrigger.dcyingtu--; + check(event, player, triggername, source) { + var target = source == player.getNext() ? player.getPrevious() : player.getNext(); + return Math.min(0, get.attitude(player, target)) >= get.attitude(player, source); }, - contentx:function(){ - 'step 0' - event.side=(target==player.getPrevious()?'getNext':'getPrevious'); - player.gainPlayerCard(target,true,'he'); - 'step 1' - var he=player.getCards('he'); - if(he.length>0){ - var target=player[event.side](); - event.target=target; - if(he.length==1) event._result={bool:true,cards:he}; - else player.chooseCard('he',true,'交给'+get.translation(target)+'一张牌') - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - event.card=card; + prompt2: + "获得该角色的一张牌,然后将一张牌交给该角色的对位角色。若你给出的是装备牌,则其使用其得到的牌。", + content: function () { + "step 0"; + var target = event.targets[0]; + event.target = target; + event.side = target == player.getPrevious() ? "getNext" : "getPrevious"; + player.gainPlayerCard(target, true, "he"); + "step 1"; + var he = player.getCards("he"); + if (he.length > 0) { + var target = player[event.side](); + event.target = target; + if (he.length == 1) event._result = { bool: true, cards: he }; + else player.chooseCard("he", true, "交给" + get.translation(target) + "一张牌"); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; player.line(target); - player.give(card,target); - } - else event.finish(); - 'step 3' - if(target.getCards('h').includes(card)&&get.type(card,null,target)=='equip'&&target.canUse(card,target)) target.chooseUseTarget(card,true,'nopopup'); + player.give(card, target); + } else event.finish(); + "step 3"; + if ( + target.getCards("h").includes(card) && + get.type(card, null, target) == "equip" && + target.canUse(card, target) + ) + target.chooseUseTarget(card, true, "nopopup"); }, }, - dccongshi:{ - audio:2, - trigger:{global:'useCardAfter'}, - forced:true, - locked:false, - filter:function(event,player){ - return get.type(event.card,null,false)=='equip'&&event.player.isMaxEquip(); + dccongshi: { + audio: 2, + trigger: { global: "useCardAfter" }, + forced: true, + filter: function (event, player) { + return get.type(event.card, null, false) == "equip" && event.player.isMaxEquip(); }, - content:function(){ + content: function () { player.draw(); }, }, //黄权 - dcquanjian:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player); + dcquanjian: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return game.hasPlayer((current) => current != player); }, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('劝谏:令一名其他角色…','hidden'); - dialog.add([[ - ['damage','对其攻击范围内的一名角色造成1点伤害'], - ['draw','将其手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用手牌'] - ],'textbutton']); + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("劝谏:令一名其他角色…", "hidden"); + dialog.add([ + [ + ["damage", "对其攻击范围内的一名角色造成1点伤害"], + [ + "draw", + "将其手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用手牌", + ], + ], + "textbutton", + ]); return dialog; }, - filter:function(button,player){ - return !player.hasSkill('dcquanjian_'+button.link,null,null,false); + filter: function (button, player) { + return !player.hasSkill("dcquanjian_" + button.link, null, null, false); }, - check:()=>1+Math.random(), - backup:function(links){ - return get.copy(lib.skill['dcquanjian_'+links[0]]); + check: () => 1 + Math.random(), + backup: function (links) { + return get.copy(lib.skill["dcquanjian_" + links[0]]); }, - prompt:function(links){ - if(links[0]=='damage') return '令一名其他角色对攻击范围内的另一名角色造成1点伤害'; - return '令一名其他角色将手牌数调整至手牌上限(至多摸至五张)且本回合内不能使用手牌'; + prompt: function (links) { + if (links[0] == "damage") return "令一名其他角色对攻击范围内的另一名角色造成1点伤害"; + return "令一名其他角色将手牌数调整至手牌上限(至多摸至五张)且本回合内不能使用手牌"; }, }, - ai:{ - order:2, - result:{player:1}, + ai: { + order: 2, + result: { player: 1 }, }, - subSkill:{ - backup:{audio:'dcquanjian'}, - damage:{ - audio:'dcquanjian', - selectTarget:2, - filterTarget:function(card,player,target){ - if(!ui.selected.targets.length) return target!=player; + subSkill: { + backup: { audio: "dcquanjian" }, + damage: { + audio: "dcquanjian", + selectTarget: 2, + filterTarget: function (card, player, target) { + if (!ui.selected.targets.length) return target != player; return ui.selected.targets[0].inRange(target); }, - complexTarget:true, - complexSelect:true, - filterCard:()=>false, - selectCard:-1, - targetprompt:['造成伤害','受到伤害'], - multitarget:true, - content:function(){ - 'step 0' - player.addTempSkill('dcquanjian_damage','phaseUseAfter'); - targets[0].chooseControl().set('choiceList',[ - '对'+get.translation(targets[1])+'造成1点伤害', - '本回合下次受到的伤害+1', - ]).set('ai',function(){ - return _status.event.eff>=0?0:1; - }).set('eff',get.damageEffect(targets[1],targets[0],targets[0])); - 'step 1' - if(result.index==0){ + complexTarget: true, + complexSelect: true, + filterCard: () => false, + selectCard: -1, + targetprompt: ["造成伤害", "受到伤害"], + multitarget: true, + content: function () { + "step 0"; + player.addTempSkill("dcquanjian_damage", "phaseUseAfter"); + targets[0] + .chooseControl() + .set("choiceList", [ + "对" + get.translation(targets[1]) + "造成1点伤害", + "本回合下次受到的伤害+1", + ]) + .set("ai", function () { + return _status.event.eff >= 0 ? 0 : 1; + }) + .set("eff", get.damageEffect(targets[1], targets[0], targets[0])); + "step 1"; + if (result.index == 0) { targets[1].damage(targets[0]); - } - else{ - target.addMark('dcquanjian_effect',1,false); - target.addTempSkill('dcquanjian_effect'); + } else { + target.addMark("dcquanjian_effect", 1, false); + target.addTempSkill("dcquanjian_effect"); } }, - ai:{ - result:{ - player:function(player,target){ - if(ui.selected.targets.length==0){ - if(!game.hasPlayer((current)=>current.inRangeOf(target)&&get.damageEffect(current,target,player)>0)) return 0; - if(get.attitude(player,target)>0) return 2; + ai: { + result: { + player: function (player, target) { + if (ui.selected.targets.length == 0) { + if ( + !game.hasPlayer( + (current) => + current.inRangeOf(target) && + get.damageEffect(current, target, player) > 0 + ) + ) + return 0; + if (get.attitude(player, target) > 0) return 2; return 1; } - return get.damageEffect(target,ui.selected.targets[0],player,player); + return get.damageEffect(target, ui.selected.targets[0], player, player); }, }, }, }, - draw:{ - audio:'dcquanjian', - filterTarget:function(card,player,target){ - if(target==player) return false; - var num=target.countCards('h'); - if(num>target.getHandcardLimit()) return true; - return num target.getHandcardLimit()) return true; + return num < Math.min(5, target.getHandcardLimit()); }, - filterCard:()=>false, - selectCard:-1, - content:function(){ - 'step 0' - player.addTempSkill('dcquanjian_draw','phaseUseAfter'); - var num1=target.countCards('h'),num2=target.getHandcardLimit(); - var num=0; - if(num1>num2){ - event.index=0; - num=num1-num2; - target.chooseControl().set('choiceList',[ - '弃置'+get.cnNumber(num)+'张手牌', - '本回合下次受到的伤害+1', - ]).set('ai',function(){ - var player=_status.event.player; - if(_status.event.number==1&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'dcquanjian_draw')&&get.value(card)<5; - },'h')) return 0; - return 1; - }).set('number',num); + filterCard: () => false, + selectCard: -1, + content: function () { + "step 0"; + player.addTempSkill("dcquanjian_draw", "phaseUseAfter"); + var num1 = target.countCards("h"), + num2 = target.getHandcardLimit(); + var num = 0; + if (num1 > num2) { + event.index = 0; + num = num1 - num2; + target + .chooseControl() + .set("choiceList", [ + "弃置" + get.cnNumber(num) + "张手牌", + "本回合下次受到的伤害+1", + ]) + .set("ai", function () { + var player = _status.event.player; + if ( + _status.event.number == 1 && + player.hasCard(function (card) { + return ( + lib.filter.cardDiscardable( + card, + player, + "dcquanjian_draw" + ) && get.value(card) < 5 + ); + }, "h") + ) + return 0; + return 1; + }) + .set("number", num); + } else { + event.index = 1; + num = Math.min(num2, 5) - num1; + if (num <= 0) event.finish(); + else + target + .chooseControl() + .set("choiceList", [ + "摸" + get.cnNumber(num) + "张牌,且本回合内不能使用或打出手牌", + "本回合下次受到的伤害+1", + ]) + .set("ai", function () { + return 0; + }); } - else{ - event.index=1; - num=Math.min(num2,5)-num1; - if(num<=0) event.finish(); - else target.chooseControl().set('choiceList',[ - '摸'+get.cnNumber(num)+'张牌,且本回合内不能使用或打出手牌', - '本回合下次受到的伤害+1', - ]).set('ai',function(){ - return 0; - }); - } - event.num=num; - 'step 1' - if(result.index==0){ - if(event.index==0) target.chooseToDiscard('h',true,num); + event.num = num; + "step 1"; + if (result.index == 0) { + if (event.index == 0) target.chooseToDiscard("h", true, num); else target.draw(num); - } - else{ - target.addMark('dcquanjian_effect',1,false); - target.addTempSkill('dcquanjian_effect'); + } else { + target.addMark("dcquanjian_effect", 1, false); + target.addTempSkill("dcquanjian_effect"); event.finish(); } - 'step 2' - target.addTempSkill('dcquanjian_disable'); + "step 2"; + target.addTempSkill("dcquanjian_disable"); }, - ai:{ - result:{ - target:function(player,target){ - var num1=target.countCards('h'),num2=target.getHandcardLimit(); - if(num1>num2) return -1; - return Math.min(5,num2)-num1; + ai: { + result: { + target: function (player, target) { + var num1 = target.countCards("h"), + num2 = target.getHandcardLimit(); + if (num1 > num2) return -1; + return Math.min(5, num2) - num1; }, }, }, }, - effect:{ - charlotte:true, - trigger:{player:'damageBegin3'}, - forced:true, - onremove:true, - marktext:'谏', - content:function(){ - trigger.num+=player.countMark(event.name); + effect: { + charlotte: true, + trigger: { player: "damageBegin3" }, + forced: true, + onremove: true, + marktext: "谏", + content: function () { + trigger.num += player.countMark(event.name); player.removeSkill(event.name); }, - intro:{content:'下次受到的伤害+#'}, - ai:{threaten:2.5}, + intro: { content: "下次受到的伤害+#" }, + ai: { threaten: 2.5 }, }, - disable:{ - charlotte:true, - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + disable: { + charlotte: true, + mod: { + cardEnabled(card, player) { + if (card.cards) { + const hs = player.getCards("h"); + if (card.cards.some((card) => hs.includes(card))) return false; + } + }, + cardSavable(card, player) { + if (card.cards) { + const hs = player.getCards("h"); + if (card.cards.some((card) => hs.includes(card))) return false; + } }, }, - mark:true, - marktext:'禁', - intro:{content:'不能使用或打出手牌'}, - ai:{threaten:2.5}, + mark: true, + marktext: "禁", + intro: { content: "不能使用或打出手牌" }, + ai: { threaten: 2.5 }, }, }, }, - dctujue:{ - audio:2, - trigger:{player:'dying'}, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.countCards('he')>0; + dctujue: { + audio: 2, + trigger: { player: "dying" }, + direct: true, + limited: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt2('dctujue')).set('ai',function(target){ - if(_status.event.skip) return 0; - return 200+get.attitude(_status.event.player,target); - }).set('skip',player.countCards('hs',{name:['tao','jiu']})+player.hp>0); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dctujue',target); - player.awakenSkill('dctujue'); - var cards=player.getCards('he'); - player.give(cards,target); + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, get.prompt2("dctujue")) + .set("ai", function (target) { + if (_status.event.skip) return 0; + return 200 + get.attitude(_status.event.player, target); + }) + .set("skip", player.countCards("hs", { name: ["tao", "jiu"] }) + player.hp > 0); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dctujue", target); + player.awakenSkill("dctujue"); + var cards = player.getCards("he"); + player.give(cards, target); player.recover(cards.length); player.draw(cards.length); } }, }, //尹夫人 - dcyingyu:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - direct:true, - filter:function(event,player){ - if(event.name=='phaseJieshu'&&!player.storage.dcyingyu) return false; - return game.countPlayer(function(current){ - return current.countCards('h')>0; - })>1; + dcyingyu: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + direct: true, + filter: function (event, player) { + if (event.name == "phaseJieshu" && !player.storage.dcyingyu) return false; + return ( + game.countPlayer(function (current) { + return current.countCards("h") > 0; + }) > 1 + ); }, - content:function(){ - 'step 0' - player.chooseTarget(2,get.prompt('dcyingyu'),'展示两名角色的各一张手牌。若这两张牌花色不同,则你可以令其中一名角色获得另一名角色的展示牌。',function(card,player,target){ - return target.countCards('h')>0; - }).set('ai',function(target){ - var player=_status.event.player; - if(!ui.selected.targets.length) return get.attitude(player,target); - return 1-get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - event.targets=targets; - event.cards=[]; - player.logSkill('dcyingyu',targets); - player.choosePlayerCard(targets[0],true,'h'); - } - else event.finish(); - 'step 2' - var card=result.cards[0]; + content: function () { + "step 0"; + player + .chooseTarget( + 2, + get.prompt("dcyingyu"), + "展示两名角色的各一张手牌。若这两张牌花色不同,则你可以令其中一名角色获得另一名角色的展示牌。", + function (card, player, target) { + return target.countCards("h") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (!ui.selected.targets.length) return get.attitude(player, target); + return 1 - get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + event.targets = targets; + event.cards = []; + player.logSkill("dcyingyu", targets); + player.choosePlayerCard(targets[0], true, "h"); + } else event.finish(); + "step 2"; + var card = result.cards[0]; player.line(targets[0]); - player.showCards(card,get.translation(player)+'对'+get.translation(targets[0])+'发动了【媵予】') + player.showCards( + card, + get.translation(player) + "对" + get.translation(targets[0]) + "发动了【媵予】" + ); event.cards.push(card); - player.choosePlayerCard(targets[1],true,'h'); - 'step 3' - var card=result.cards[0]; + player.choosePlayerCard(targets[1], true, "h"); + "step 3"; + var card = result.cards[0]; player.line(targets[1]); - player.showCards(card,get.translation(player)+'对'+get.translation(targets[1])+'发动了【媵予】') + player.showCards( + card, + get.translation(player) + "对" + get.translation(targets[1]) + "发动了【媵予】" + ); event.cards.push(card); - if(get.suit(cards[0],targets[0])==get.suit(cards[1],targets[1])) event.finish(); - 'step 4' - var str1=get.translation(targets[0]),str2=get.translation(targets[1]); - player.chooseControl('cancel2').set('choiceList',[ - '令'+str1+'获得'+str2+'的'+get.translation(cards[1]), - '令'+str2+'获得'+str1+'的'+get.translation(cards[0]), - ]).set('goon',get.attitude(player,targets[0])>0?0:1).set('ai',()=>_status.event.goon); - 'step 5' - if(result.control!='cancel2'){ - var i=result.index; - targets[1-i].give(cards[1-i],targets[i],'give'); + if (get.suit(cards[0], targets[0]) == get.suit(cards[1], targets[1])) event.finish(); + "step 4"; + var str1 = get.translation(targets[0]), + str2 = get.translation(targets[1]); + player + .chooseControl("cancel2") + .set("choiceList", [ + "令" + str1 + "获得" + str2 + "的" + get.translation(cards[1]), + "令" + str2 + "获得" + str1 + "的" + get.translation(cards[0]), + ]) + .set("goon", get.attitude(player, targets[0]) > 0 ? 0 : 1) + .set("ai", () => _status.event.goon); + "step 5"; + if (result.control != "cancel2") { + var i = result.index; + targets[1 - i].give(cards[1 - i], targets[i], "give"); } }, - onremove:true, + onremove: true, }, - dcyongbi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer((current)=>lib.skill.dcyongbi.filterTarget(null,player,current)); + dcyongbi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer((current) => lib.skill.dcyongbi.filterTarget(null, player, current)) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.hasSex('male'); + filterTarget: function (card, player, target) { + return target != player && target.hasSex("male"); }, - selectCard:-1, - filterCard:true, - position:'h', - limited:true, - skillAnimation:true, - animationColor:'fire', - discard:false, - lose:false, - content:function(){ - 'step 0' - player.awakenSkill('dcyongbi'); - if(player.hasSkill('dcyingyu',null,null,false)) player.storage.dcyingyu=true; - player.give(cards,target); - 'step 1' - var list=[]; - for(var i of cards){ - list.add(get.suit(i,player)); - if(list.length>=3) break; + selectCard: -1, + filterCard: true, + position: "h", + limited: true, + skillAnimation: true, + animationColor: "fire", + discard: false, + lose: false, + content: function () { + "step 0"; + player.awakenSkill("dcyongbi"); + if (player.hasSkill("dcyingyu", null, null, false)) player.storage.dcyingyu = true; + player.give(cards, target); + "step 1"; + var list = []; + for (var i of cards) { + list.add(get.suit(i, player)); + if (list.length >= 3) break; } - if(list.length>=2){ - player.addMark('dcyongbi_eff1',2,false); - player.addSkill('dcyongbi_eff1'); - target.addMark('dcyongbi_eff1',2,false); - target.addSkill('dcyongbi_eff1'); + if (list.length >= 2) { + player.addMark("dcyongbi_eff1", 2, false); + player.addSkill("dcyongbi_eff1"); + target.addMark("dcyongbi_eff1", 2, false); + target.addSkill("dcyongbi_eff1"); } - if(list.length>=3){ - player.addMark('dcyongbi_eff2',1,false); - player.addSkill('dcyongbi_eff2'); - target.addMark('dcyongbi_eff2',1,false); - target.addSkill('dcyongbi_eff2'); + if (list.length >= 3) { + player.addMark("dcyongbi_eff2", 1, false); + player.addSkill("dcyongbi_eff2"); + target.addMark("dcyongbi_eff2", 1, false); + target.addSkill("dcyongbi_eff2"); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(player.hasUnknown()) return 0; - var zhu=get.zhu(player); - if(zhu&&get.attitude(player,zhu)>0){ - if(target==zhu) return 4; + ai: { + order: 1, + result: { + target: function (player, target) { + if (player.hasUnknown()) return 0; + var zhu = get.zhu(player); + if (zhu && get.attitude(player, zhu) > 0) { + if (target == zhu) return 4; } return 1; }, }, }, - subSkill:{ - eff1:{ - mod:{ - maxHandcard:(player,num)=>num+player.countMark('dcyongbi_eff1'), + subSkill: { + eff1: { + mod: { + maxHandcard: (player, num) => num + player.countMark("dcyongbi_eff1"), }, - charlotte:true, - onremove:true, - marktext:'拥', - intro:{content:'手牌上限+#'}, + charlotte: true, + onremove: true, + marktext: "拥", + intro: { content: "手牌上限+#" }, }, - eff2:{ - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return event.num>1; + eff2: { + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return event.num > 1; }, - content:function(){ - trigger.num-=player.countMark('dcyongbi_eff2'); + content: function () { + trigger.num -= player.countMark("dcyongbi_eff2"); }, - charlotte:true, - onremove:true, - marktext:'嬖', - intro:{content:'受到大于1的伤害时,此伤害-#'}, + charlotte: true, + onremove: true, + marktext: "嬖", + intro: { content: "受到大于1的伤害时,此伤害-#" }, }, }, }, //吕旷吕翔 - dcshuhe:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + dcshuhe: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - position:'h', - discard:false, - lose:false, - delay:false, - check:function(cardx){ - var player=_status.event.player; - var num1=get.number(cardx),players=game.filterPlayer(); - var goon=false,effect=0; - for(var current of players){ - var cards=current.getCards('ej',function(card){ - var num=get.number(card); - return num==num1; + filterCard: true, + position: "h", + discard: false, + lose: false, + delay: false, + check: function (cardx) { + var player = _status.event.player; + var num1 = get.number(cardx), + players = game.filterPlayer(); + var goon = false, + effect = 0; + for (var current of players) { + var cards = current.getCards("ej", function (card) { + var num = get.number(card); + return num == num1; }); - if(cards.length){ - goon=true; - var att=get.attitude(player,current); - for(var card of cards){ - if(get.position(card)=='e'){ - var val=get.value(card,current); - if(att<=0) effect+=val; - else effect-=val/2; - } - else{ - var eff=get.effect(current,{name:card.viewAs||card.name},player,player); - effect-=get.sgn(att)*eff; + if (cards.length) { + goon = true; + var att = get.attitude(player, current); + for (var card of cards) { + if (get.position(card) == "e") { + var val = get.value(card, current); + if (att <= 0) effect += val; + else effect -= val / 2; + } else { + var eff = get.effect( + current, + { name: card.viewAs || card.name }, + player, + player + ); + effect -= get.sgn(att) * eff; } } } } - if(goon){ - if(effect>0) return 6+effect-get.value(cardx); + if (goon) { + if (effect > 0) return 6 + effect - get.value(cardx); return 0; } - return game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })?(6-get.value(cardx)):0; + return game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ? 6 - get.value(cardx) + : 0; }, - content:function(){ - 'step 0' - player.showCards(cards,get.translation(player)+'发动了【数合】'); - player.addMark('dcliehou',1); - 'step 1' - event.cards2=[]; - var num1=get.number(cards[0],player); - var lose_list=[],players=game.filterPlayer(); - for(var current of players){ - var cards=current.getCards('ej',function(card){ - var num=get.number(card); - return num==num1; + content: function () { + "step 0"; + player.showCards(cards, get.translation(player) + "发动了【数合】"); + player.addMark("dcliehou", 1); + "step 1"; + event.cards2 = []; + var num1 = get.number(cards[0], player); + var lose_list = [], + players = game.filterPlayer(); + for (var current of players) { + var cards = current.getCards("ej", function (card) { + var num = get.number(card); + return num == num1; }); - if(cards.length>0){ - player.line(current,'thunder'); + if (cards.length > 0) { + player.line(current, "thunder"); current.$throw(cards); - lose_list.push([current,cards]); + lose_list.push([current, cards]); event.cards2.addArray(cards); } } - if(lose_list.length){ - event.lose_list=lose_list; + if (lose_list.length) { + event.lose_list = lose_list; game.loseAsync({ - lose_list:lose_list, - }).setContent('chooseToCompareLose'); - } - else{ + lose_list: lose_list, + }).setContent("chooseToCompareLose"); + } else { event.goto(3); - player.chooseTarget(true,lib.filter.notMe,'将'+get.translation(event.cards[0])+'交给一名其他角色').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); + player + .chooseTarget( + true, + lib.filter.notMe, + "将" + get.translation(event.cards[0]) + "交给一名其他角色" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); } - 'step 2' - var cards=event.cards2; - if(cards.length>0){ - if(event.lose_list) game.delayx(); - player.gain(cards,'gain2'); + "step 2"; + var cards = event.cards2; + if (cards.length > 0) { + if (event.lose_list) game.delayx(); + player.gain(cards, "gain2"); } event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.give(cards,target); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.give(cards, target); } }, - ai:{ - order:2, - result:{ - player:1, + ai: { + order: 2, + result: { + player: 1, }, }, }, - dcliehou:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ + dcliehou: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - var num=Math.min(5,1+player.countMark('dcliehou')); - trigger.num+=num; - trigger._dcliehou=num; + content: function () { + var num = Math.min(5, 1 + player.countMark("dcliehou")); + trigger.num += num; + trigger._dcliehou = num; }, - group:'dcliehou_discard', - subSkill:{ - discard:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - filter:function(event,player){ - return typeof event._dcliehou=='number'; + group: "dcliehou_discard", + subSkill: { + discard: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + filter: function (event, player) { + return typeof event._dcliehou == "number"; }, - content:function(){ - 'step 0' - var num=trigger._dcliehou; - player.chooseToDiscard(num,'he','弃置'+get.cnNumber(num)+'张牌,或失去1点体力').set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 26-get.value(card); - }).set('goon',player.hp>Math.max(1,4-num)||get.effect(player,{name:'losehp'},player,player)>0); - 'step 1' - if(!result.bool) player.loseHp(); + content: function () { + "step 0"; + var num = trigger._dcliehou; + player + .chooseToDiscard( + num, + "he", + "弃置" + get.cnNumber(num) + "张牌,或失去1点体力" + ) + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 26 - get.value(card); + }) + .set( + "goon", + player.hp > Math.max(1, 4 - num) || + get.effect(player, { name: "losehp" }, player, player) > 0 + ); + "step 1"; + if (!result.bool) player.loseHp(); }, }, }, - marktext:'爵', - intro:{ - name:'列侯(爵)', - name2:'爵', - content:'〖列侯〗的摸牌数+#', + marktext: "爵", + intro: { + name: "列侯(爵)", + name2: "爵", + content: "〖列侯〗的摸牌数+#", }, }, //管亥 - suoliang:{ - audio:2, - trigger:{source:'damageSource'}, - logTarget:'player', - usable:1, - filter:function(event,player){ - return event.player!=player&&event.player.maxHp>0&&event.player.countCards('he')>0; + suoliang: { + audio: 2, + trigger: { source: "damageSource" }, + logTarget: "player", + usable: 1, + filter: function (event, player) { + return ( + event.player != player && event.player.maxHp > 0 && event.player.countCards("he") > 0 + ); }, - check:function(event,player){ - return get.attitude(player,event.player)<=0; + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - player.choosePlayerCard(target,true,'he',[1,target.maxHp],'选择'+get.translation(target)+'的至多'+get.cnNumber(target.maxHp)+'张牌'); - 'step 1' - if(result.bool){ - player.showCards(result.cards,get.translation(player)+'对'+get.translation(target)+'发动了【索粮】') - var cards=result.cards.filter(function(card){ - var suit=get.suit(card,target); - if(suit!='heart'&&suit!='club') return false; - return lib.filter.canBeGained(card,target,player) + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + player.choosePlayerCard( + target, + true, + "he", + [1, target.maxHp], + "选择" + get.translation(target) + "的至多" + get.cnNumber(target.maxHp) + "张牌" + ); + "step 1"; + if (result.bool) { + player.showCards( + result.cards, + get.translation(player) + "对" + get.translation(target) + "发动了【索粮】" + ); + var cards = result.cards.filter(function (card) { + var suit = get.suit(card, target); + if (suit != "heart" && suit != "club") return false; + return lib.filter.canBeGained(card, target, player); }); - if(cards.length) player.gain(cards,target,'giveAuto','bySelf'); - else{ - var cards=result.cards.filter(function(card){ - return lib.filter.canBeDiscarded(card,target,player) + if (cards.length) player.gain(cards, target, "giveAuto", "bySelf"); + else { + var cards = result.cards.filter(function (card) { + return lib.filter.canBeDiscarded(card, target, player); }); - if(cards.length) target.discard(cards,'notBySelf'); + if (cards.length) target.discard(cards, "notBySelf"); } } }, }, - qinbao:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return (event.card.name=='sha'||get.type(event.card,null,false)=='trick')&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>=player.countCards('h'); - }); + qinbao: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return ( + (event.card.name == "sha" || get.type(event.card, null, false) == "trick") && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") >= player.countCards("h"); + }) + ); }, - content:function(){ - var hs=player.countCards('h'); - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player&¤t.countCards('h')>=hs; - })); + content: function () { + var hs = player.countCards("h"); + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player && current.countCards("h") >= hs; + }) + ); }, - ai:{ - threaten:1.4, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return player.countCards('h',function(card){ - return !ui.selected.cards.includes(card); - })<=arg.target.countCards('h'); + ai: { + threaten: 1.4, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return ( + player.countCards("h", function (card) { + return !ui.selected.cards.includes(card); + }) <= arg.target.countCards("h") + ); }, }, }, //胡昭 - midu:{ - audio:2, - enable:'phaseUse', - usable:1, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('弥笃:选择要废除或恢复的装备栏或判定区','hidden'); - dialog.classList.add('withbg'); - dialog.noforcebutton=true; - var list1=[],list2=[]; - for(var i=1;i<6;i++){ - for(var j=0;j0?get.translation('equip'+i)+'栏':'判定区')]); + (player.isDisabledJudge() ? list2 : list1).push(-1); + var addTable = function (list, bool) { + const adds = []; + for (var i of list) { + adds.push([ + [i, bool], + i > 0 ? get.translation("equip" + i) + "栏" : "判定区", + ]); } - dialog.add([adds,'tdnodes']) + dialog.add([adds, "tdnodes"]); + }; + if (list1.length) { + dialog.addText("未废除"); + addTable(list1, true); } - if(list1.length){ - dialog.addText('未废除'); - addTable(list1,true); - } - if(list2.length){ - dialog.addText('已废除'); - addTable(list2,false); + if (list2.length) { + dialog.addText("已废除"); + addTable(list2, false); } return dialog; }, - filter:function(button,player){ - if(!ui.selected.buttons.length) return true; - if(!ui.selected.buttons[0].link[1]) return false; - return button.link[1] + filter: function (button, player) { + if (!ui.selected.buttons.length) return true; + if (!ui.selected.buttons[0].link[1]) return false; + return button.link[1]; }, - check:function(button){ - var player=_status.event.player; - if(!button.link[1]){ - if(button.link[0]<=0) return -10; - if(player.hasCard(function(card){ - return get.subtype(card)==('equip'+button.link[0]); - },'hs')) return 15; + check: function (button) { + var player = _status.event.player; + if (!button.link[1]) { + if (button.link[0] <= 0) return -10; + if ( + player.hasCard(function (card) { + return get.subtype(card) == "equip" + button.link[0]; + }, "hs") + ) + return 15; return 10; } - if(button.link[0]<=0||player.hasEmptySlot(button.link[0])&&!player.hasCard(function(card){ - return get.subtype(card)==('equip'+button.link[0])&&player.canUse(card,player)&&get.effect(player,card,player,player)>0; - },'hs')) return 5; + if ( + button.link[0] <= 0 || + (player.hasEmptySlot(button.link[0]) && + !player.hasCard(function (card) { + return ( + get.subtype(card) == "equip" + button.link[0] && + player.canUse(card, player) && + get.effect(player, card, player, player) > 0 + ); + }, "hs")) + ) + return 5; return 0; }, - select:[1,Infinity], - backup:function(links,player){ - if(!links[0][1]){ + select: [1, Infinity], + backup: function (links, player) { + if (!links[0][1]) { return { - audio:'midu', - selectCard:-1, - selectTarget:-1, - filterCard:()=>false, - filterTarget:()=>false, - equip:links[0][0], - content:function(){ - var pos=lib.skill.midu_backup.equip; - if(pos<=0) player.enableJudge(); + audio: "midu", + selectCard: -1, + selectTarget: -1, + filterCard: () => false, + filterTarget: () => false, + equip: links[0][0], + content: function () { + var pos = lib.skill.midu_backup.equip; + if (pos <= 0) player.enableJudge(); else player.enableEquip(pos); - player.addTempSkills('rehuomo',{player:'phaseBegin'}); + player.addTempSkills("rehuomo", { player: "phaseBegin" }); }, - } - } - else{ + }; + } else { return { - audio:'midu', - selectCard:-1, - filterCard:()=>false, - filterTarget:true, - equip:links.map(i=>i[0]).sort(), - content:function(){ - var list=lib.skill.midu_backup.equip,num=list.length,bool=false; - if(list.includes(-1)){ + audio: "midu", + selectCard: -1, + filterCard: () => false, + filterTarget: true, + equip: links.map((i) => i[0]).sort(), + content: function () { + var list = lib.skill.midu_backup.equip, + num = list.length, + bool = false; + if (list.includes(-1)) { list.remove(-1); - bool=true; + bool = true; } - if(list.length>0) player.disableEquip(list); - if(bool) player.disableJudge(); - target.draw(num) + if (list.length > 0) player.disableEquip(list); + if (bool) player.disableJudge(); + target.draw(num); }, - ai:{ - tag:{ - draw:1, + ai: { + tag: { + draw: 1, }, - result:{ - target:2, + result: { + target: 2, }, }, - } + }; } }, - prompt:function(links,player){ - if(!links[0][1]){ - return '恢复一个装备栏或判定区并获得〖活墨〗'; + prompt: function (links, player) { + if (!links[0][1]) { + return "恢复一个装备栏或判定区并获得〖活墨〗"; } - var numc=get.cnNumber(links.length); - return '废除'+numc+'个区域并令一名角色摸'+numc+'张牌'; + var numc = get.cnNumber(links.length); + return "废除" + numc + "个区域并令一名角色摸" + numc + "张牌"; }, }, - derivation:'rehuomo', - ai:{ - order:8, - result:{player:1}, + derivation: "rehuomo", + ai: { + order: 8, + result: { player: 1 }, }, - subSkill:{backup:{}}, + subSkill: { backup: {} }, }, - xianwang:{ - mod:{ - globalTo:function(source,player,distance){ - var num=player.countDisabledSlot(); - if(num>0) return distance+(num>2?2:1); + xianwang: { + mod: { + globalTo: function (source, player, distance) { + var num = player.countDisabledSlot(); + if (num > 0) return distance + (num > 2 ? 2 : 1); }, - globalFrom:function(source,player,distance){ - var num=source.countDisabledSlot(); - if(num>0) return distance-(num>2?2:1); + globalFrom: function (source, player, distance) { + var num = source.countDisabledSlot(); + if (num > 0) return distance - (num > 2 ? 2 : 1); }, }, }, //刘巴 - dczhubi:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + dczhubi: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - for(var i of event.cards){ - if(get.suit(i,event.player)=='diamond') return true; + filter: function (event, player) { + if (event.type != "discard" || event.getlx === false) return false; + for (var i of event.cards) { + if (get.suit(i, event.player) == "diamond") return true; } return false; }, - prompt2:'检索一张【无中生有】并置于牌堆顶', - content:function(){ - var card=get.cardPile(function(card){ - return card.name=='wuzhong'&&get.suit(card)!='diamond'; + prompt2: "检索一张【无中生有】并置于牌堆顶", + content: function () { + var card = get.cardPile(function (card) { + return card.name == "wuzhong" && get.suit(card) != "diamond"; }); - if(card){ - game.log(player,'将',card,'置于牌堆顶'); + if (card) { + game.log(player, "将", card, "置于牌堆顶"); card.fix(); - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); game.updateRoundNumber(); game.delayx(); } }, }, - dcliuzhuan:{ - audio:2, - group:['dcliuzhuan_mark','dcliuzhuan_gain'], - mod:{ - targetEnabled:function(card){ - if(card.cards){ - for(var i of card.cards){ - if(i.hasGaintag('dcliuzhuan_tag')) return false; + dcliuzhuan: { + audio: 2, + group: ["dcliuzhuan_mark", "dcliuzhuan_gain"], + mod: { + targetEnabled: function (card) { + if (card.cards) { + for (var i of card.cards) { + if (i.hasGaintag("dcliuzhuan_tag")) return false; } - } - else if(get.itemtype(card)=='card'){ - if(card.hasGaintag('dcliuzhuan_tag')) return false; + } else if (get.itemtype(card) == "card") { + if (card.hasGaintag("dcliuzhuan_tag")) return false; } }, }, - subSkill:{ - gain:{ - audio:'dcliuzhuan', - trigger:{global:['loseAfter','loseAsyncAfter','cardsDiscardAfter']}, - forced:true, - logTarget:()=>_status.currentPhase, - filter:function(event,player){ - var current=_status.currentPhase; - if(!current) return false; - if(event.name=='cardsDiscard'){ - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evtx2=(evtx.relatedEvent||evtx.getParent()); - return current.hasHistory('lose',function(evtx3){ - var evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evtx2!=evtx4) return false; - for(var i in evtx3.gaintag_map){ - if(evtx3.gaintag_map[i].includes('dcliuzhuan_tag')) return true; + subSkill: { + gain: { + audio: "dcliuzhuan", + trigger: { global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter"] }, + forced: true, + logTarget: () => _status.currentPhase, + filter: function (event, player) { + var current = _status.currentPhase; + if (!current) return false; + if (event.name == "cardsDiscard") { + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evtx2 = evtx.relatedEvent || evtx.getParent(); + return current.hasHistory("lose", function (evtx3) { + var evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evtx2 != evtx4) return false; + for (var i in evtx3.gaintag_map) { + if (evtx3.gaintag_map[i].includes("dcliuzhuan_tag")) return true; } }); //return false; - } - else if(event.name=='lose'){ - if(event.player!=current||event.position!=ui.discardPile) return false; - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dcliuzhuan_tag')) return true; + } else if (event.name == "lose") { + if (event.player != current || event.position != ui.discardPile) return false; + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dcliuzhuan_tag")) return true; } return false; } - return current.hasHistory('lose',function(evt){ - if(evt.getParent()!=event||evt.position!=ui.discardPile) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcliuzhuan_tag')) return true; + return current.hasHistory("lose", function (evt) { + if (evt.getParent() != event || evt.position != ui.discardPile) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcliuzhuan_tag")) return true; } }); }, - content:function(){ - var cards,current=_status.currentPhase; - if(trigger.name=='lose') cards=trigger.hs.filter(function(i){ - return trigger.gaintag_map[i.cardid]&&trigger.gaintag_map[i.cardid].includes('dcliuzhuan_tag')&&get.position(i,true)=='d'; - }); - else if(trigger.name=='cardsDiscard'){ - var evtx=trigger.getParent(); - var evtx2=(evtx.relatedEvent||evtx.getParent()); - var bool=false; - var history=current.getHistory('lose',function(evtx3){ - var evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evtx2!=evtx4) return false; - for(var i in evtx3.gaintag_map){ - if(evtx3.gaintag_map[i].includes('dcliuzhuan_tag')) return true; + content: function () { + var cards, + current = _status.currentPhase; + if (trigger.name == "lose") + cards = trigger.hs.filter(function (i) { + return ( + trigger.gaintag_map[i.cardid] && + trigger.gaintag_map[i.cardid].includes("dcliuzhuan_tag") && + get.position(i, true) == "d" + ); + }); + else if (trigger.name == "cardsDiscard") { + var evtx = trigger.getParent(); + var evtx2 = evtx.relatedEvent || evtx.getParent(); + var bool = false; + var history = current.getHistory("lose", function (evtx3) { + var evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evtx2 != evtx4) return false; + for (var i in evtx3.gaintag_map) { + if (evtx3.gaintag_map[i].includes("dcliuzhuan_tag")) return true; } }); - cards=trigger.cards.filter(function(i){ - for(var evt of history){ - if(evt.gaintag_map[i.cardid]&&evt.gaintag_map[i.cardid].includes('dcliuzhuan_tag')&&get.position(i,true)=='d') return true; + cards = trigger.cards.filter(function (i) { + for (var evt of history) { + if ( + evt.gaintag_map[i.cardid] && + evt.gaintag_map[i.cardid].includes("dcliuzhuan_tag") && + get.position(i, true) == "d" + ) + return true; } return false; }); - } - else{ - cards=[]; - current.getHistory('lose',function(evt){ - if(evt.getParent()!=trigger||evt.position!=ui.discardPile) return false; - for(var card of evt.hs){ - if(get.position(card,true)!='d') continue; - var i=card.cardid; - if(evt.gaintag_map[i]&&evt.gaintag_map[i].includes('dcliuzhuan_tag')) cards.push(card); + } else { + cards = []; + current.getHistory("lose", function (evt) { + if (evt.getParent() != trigger || evt.position != ui.discardPile) + return false; + for (var card of evt.hs) { + if (get.position(card, true) != "d") continue; + var i = card.cardid; + if ( + evt.gaintag_map[i] && + evt.gaintag_map[i].includes("dcliuzhuan_tag") + ) + cards.push(card); } }); } - if(cards&&cards.length>0) player.gain(cards,'gain2'); + if (cards && cards.length > 0) player.gain(cards, "gain2"); }, }, - mark:{ - trigger:{global:'gainBegin'}, - forced:true, - popup:false, - silent:true, - lastDo:true, - filter:function(event,player){ - if(player==event.player||event.player!=_status.currentPhase) return false; - var evt=event.getParent('phaseDraw'); - if(evt&&evt.name=='phaseDraw') return false; + mark: { + trigger: { global: "gainBegin" }, + forced: true, + popup: false, + silent: true, + lastDo: true, + filter: function (event, player) { + if (player == event.player || event.player != _status.currentPhase) return false; + var evt = event.getParent("phaseDraw"); + if (evt && evt.name == "phaseDraw") return false; return true; }, - content:function(){ - trigger.gaintag.add('dcliuzhuan_tag'); - trigger.player.addTempSkill('dcliuzhuan_tag'); + content: function () { + trigger.gaintag.add("dcliuzhuan_tag"); + trigger.player.addTempSkill("dcliuzhuan_tag"); }, }, - tag:{ - charlotte:true, - onremove:(player,skill)=>player.removeGaintag(skill), + tag: { + charlotte: true, + onremove: (player, skill) => player.removeGaintag(skill), }, }, }, //张勋 - suizheng:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('suizheng'),'令一名角色下回合内获得〖随征〗效果').set('',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasJudge('lebu')) return att/2; - return att*get.threaten(target)*Math.sqrt(2+player==target?(player.countCards('h','sha')*2):target.countCards('h')) - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('suizheng',target); - target.addMark('suizheng_effect',1,false); - target.markAuto('suizheng_source',[player]); - target.addTempSkill('suizheng_effect',{player:player==target?'phaseJieshuBefore':'phaseAfter'}); + suizheng: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("suizheng"), "令一名角色下回合内获得〖随征〗效果") + .set("", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasJudge("lebu")) return att / 2; + return ( + att * + get.threaten(target) * + Math.sqrt( + 2 + player == target + ? player.countCards("h", "sha") * 2 + : target.countCards("h") + ) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("suizheng", target); + target.addMark("suizheng_effect", 1, false); + target.markAuto("suizheng_source", [player]); + target.addTempSkill("suizheng_effect", { + player: player == target ? "phaseJieshuBefore" : "phaseAfter", + }); } }, - subSkill:{ - effect:{ - audio:'suizheng', - charlotte:true, - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; + subSkill: { + effect: { + audio: "suizheng", + charlotte: true, + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('suizheng_effect'); + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("suizheng_effect"); }, }, - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - var list=player.getStorage('suizheng_source'); - if(!list.filter((i)=>i.isIn().length)) return false; - return player.hasHistory('sourceDamage',function(evt){ - return evt.player.isIn()&&evt.getParent('phaseUse')==event; + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + var list = player.getStorage("suizheng_source"); + if (!list.filter((i) => i.isIn().length)) return false; + return player.hasHistory("sourceDamage", function (evt) { + return evt.player.isIn() && evt.getParent("phaseUse") == event; }); }, - content:function(){ - 'step 0' - var targets=player.getStorage('suizheng_source').slice(0).sortBySeat(); - event.targets=targets; - 'step 1' - var target=targets.shift(); - event.target=target; - var list=[]; - player.getHistory('sourceDamage',function(evt){ - if(evt.player.isIn()&&evt.getParent('phaseUse')==trigger) list.add(evt.player); + content: function () { + "step 0"; + var targets = player.getStorage("suizheng_source").slice(0).sortBySeat(); + event.targets = targets; + "step 1"; + var target = targets.shift(); + event.target = target; + var list = []; + player.getHistory("sourceDamage", function (evt) { + if (evt.player.isIn() && evt.getParent("phaseUse") == trigger) + list.add(evt.player); }); - if(!list.length) event.finish(); - else if(target.isIn()){ - list=list.filter(function(i){ - return target.canUse('sha',i,false); - }); - if(list.length>0) target.chooseTarget('随征:是否对一名角色使用【杀】?',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',list).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); + if (!list.length) event.finish(); + else if (target.isIn()) { + list = list.filter(function (i) { + return target.canUse("sha", i, false); }); + if (list.length > 0) + target + .chooseTarget( + "随征:是否对一名角色使用【杀】?", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", list) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }); + } else event._result = { bool: false }; + "step 2"; + if (result.bool) { + target.useCard( + { + name: "sha", + isCard: true, + }, + result.targets, + false, + "suizheng_effect" + ); } - else event._result={bool:false}; - 'step 2' - if(result.bool){ - target.useCard({ - name:'sha', - isCard:true, - },result.targets,false,'suizheng_effect'); - } - if(targets.length>0) event.goto(1); + if (targets.length > 0) event.goto(1); }, - onremove:function(player){ + onremove: function (player) { delete player.storage.suizheng_effect; delete player.storage.suizheng_source; }, - intro:{content:'使用【杀】无距离限制且次数上限+#'}, + intro: { content: "使用【杀】无距离限制且次数上限+#" }, }, }, }, //纪灵 - dcshuangren:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&&player.canCompare(current); - }) + dcshuangren: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && player.canCompare(current); + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var goon; - if(player.needsToDiscard()>1){ - goon=player.hasCard(function(card){ - return card.number>10&&get.value(card)<=5; + if (player.needsToDiscard() > 1) { + goon = player.hasCard(function (card) { + return card.number > 10 && get.value(card) <= 5; + }); + } else if (player.hasSha()) { + goon = player.hasCard(function (card) { + return (card.number >= 9 && get.value(card) <= 5) || get.value(card) <= 3; + }); + } else { + goon = player.hasCard(function (card) { + return get.value(card) <= 5; }); } - else if(player.hasSha()){ - goon=player.hasCard(function(card){ - return (card.number>=9&&get.value(card)<=5)||get.value(card)<=3; - }); - } - else{ - goon=player.hasCard(function(card){ - return get.value(card)<=5; - }); - } - player.chooseTarget(get.prompt2('dcshuangren'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player; - if(_status.event.goon&&get.attitude(player,target)<0){ - return get.effect(target,{name:'sha'},player,player); - } - return 0; - }).set('goon',goon).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dcshuangren',target); + player + .chooseTarget(get.prompt2("dcshuangren"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + if (_status.event.goon && get.attitude(player, target) < 0) { + return get.effect(target, { name: "sha" }, player, player); + } + return 0; + }) + .set("goon", goon) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dcshuangren", target); player.chooseToCompare(target); - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - var target=event.target; - if(game.hasPlayer(function(current){ - if(target==current||target.group!=current.group) return false; - return player.canUse('sha',current,false); - })){ - var str='请选择视为使用【杀】的目标'; - var str2='操作提示:选择一名角色B,或选择包含A('+get.translation(target)+')在内的两名角色A和B(B的势力需为'+get.translation(target.group)+'势力)'; - player.chooseTarget([1,2],str,str2,true,function(card,player,target){ - if(!player.canUse('sha',target,false)) return false; - var current=_status.event.target; - if(target==current) return true; - if(target.group!=current.group) return false; - if(!ui.selected.targets.length) return true; - return ui.selected.targets[0]==current; - //return current==target; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }).set('target',target).set('complexTarget',true); - } - else{ - player.useCard({name:'sha',isCard:true},target,false); + "step 2"; + if (result.bool) { + var target = event.target; + if ( + game.hasPlayer(function (current) { + if (target == current || target.group != current.group) return false; + return player.canUse("sha", current, false); + }) + ) { + var str = "请选择视为使用【杀】的目标"; + var str2 = + "操作提示:选择一名角色B,或选择包含A(" + + get.translation(target) + + ")在内的两名角色A和B(B的势力需为" + + get.translation(target.group) + + "势力)"; + player + .chooseTarget([1, 2], str, str2, true, function (card, player, target) { + if (!player.canUse("sha", target, false)) return false; + var current = _status.event.target; + if (target == current) return true; + if (target.group != current.group) return false; + if (!ui.selected.targets.length) return true; + return ui.selected.targets[0] == current; + //return current==target; + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }) + .set("target", target) + .set("complexTarget", true); + } else { + player.useCard({ name: "sha", isCard: true }, target, false); event.finish(); } - } - else{ - player.addTempSkill('dcshuangren_debuff','phaseUseAfter'); + } else { + player.addTempSkill("dcshuangren_debuff", "phaseUseAfter"); event.finish(); } - 'step 3' - if(result.bool&&result.targets&&result.targets.length){ - player.useCard({name:'sha',isCard:true},result.targets,false); + "step 3"; + if (result.bool && result.targets && result.targets.length) { + player.useCard({ name: "sha", isCard: true }, result.targets, false); } }, - subSkill:{ - debuff:{ - charlotte:true, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + subSkill: { + debuff: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, }, }, }, }, //羊祜 - dcdeshao:{ - audio:2, - usable:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return player!=event.player&&get.color(event.card)=='black'; + dcdeshao: { + audio: 2, + usable: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return player != event.player && get.color(event.card) == "black"; }, - logTarget:'player', - check:function(event,player){ - var eff=get.effect(player,{name:'draw'},player,player); - if(player.countCards('h')+1<=event.player.countCards('h')&&event.player.countCards('he')>0) eff+=get.effect(event.player,{name:'guohe_copy2'},player,player); + logTarget: "player", + check: function (event, player) { + var eff = get.effect(player, { name: "draw" }, player, player); + if ( + player.countCards("h") + 1 <= event.player.countCards("h") && + event.player.countCards("he") > 0 + ) + eff += get.effect(event.player, { name: "guohe_copy2" }, player, player); return eff; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - var target=trigger.player; - if(player.countCards('h')<=target.countCards('h')&&target.countCards('he')>0){ - player.discardPlayerCard(target,true,'he'); + "step 1"; + var target = trigger.player; + if (player.countCards("h") <= target.countCards("h") && target.countCards("he") > 0) { + player.discardPlayerCard(target, true, "he"); player.addExpose(0.2); } }, }, - dcmingfa:{ - audio:2, - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - return player.isPhaseUsing()&&(event.card.name=='sha'||get.type(event.card)=='trick')&&event.cards.filterInD().length>0&&!player.getExpansions('dcmingfa').length; + dcmingfa: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + return ( + player.isPhaseUsing() && + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.cards.filterInD().length > 0 && + !player.getExpansions("dcmingfa").length + ); }, - content:function(){ - 'step 0' - var str,cards=trigger.cards.filterInD(),card=trigger.card; - if(cards.length==1&&card.name==cards[0].name&&(card.nature||false)==(cards[0].nature||false)) str=get.translation(cards[0]); - else str=(get.translation(trigger.card)+'('+get.translation(cards)+')'); - var cardx={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, + content: function () { + "step 0"; + var str, + cards = trigger.cards.filterInD(), + card = trigger.card; + if ( + cards.length == 1 && + card.name == cards[0].name && + (card.nature || false) == (cards[0].nature || false) + ) + str = get.translation(cards[0]); + else str = get.translation(trigger.card) + "(" + get.translation(cards) + ")"; + var cardx = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, }; - player.chooseTarget(lib.filter.notMe,get.prompt('dcmingfa'),'将'+str+'作为“明伐”牌置于武将牌上,并选择一名其他角色。该角色下回合结束时对其执行〖明伐〗的后续效果。').set('card',cardx).set('goon',function(){ - var getMax=function(card){ - return Math.max.apply(Math,game.filterPlayer(function(current){ - return current!=player&&lib.filter.targetEnabled2(card,player,current); - }).map(function(i){ - return get.effect(i,card,player,player)*Math.sqrt(Math.min(i.getHandcardLimit(),1+i.countCards('h'))); - }).concat([0])); - } - var eff1=getMax(cardx); - if(player.hasCard(function(card){ - if((card.name!='sha'&&get.type(card)!='trick')||!player.hasValueTarget(card,null,true)) return false; - return getMax({ - name:get.name(card), - nature:get.nature(card), - isCard:true, - })>=eff1; - },'hs')) return false; - return true; - }()).set('ai',function(target){ - if(!_status.event.goon) return 0; - var player=_status.event.player,card=_status.event.card; - if(!lib.filter.targetEnabled2(card,player,target)) return 0; - return get.effect(target,card,player,player)*Math.sqrt(Math.min(target.getHandcardLimit(),1+target.countCards('h'))); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcmingfa',target); - var card={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, + player + .chooseTarget( + lib.filter.notMe, + get.prompt("dcmingfa"), + "将" + + str + + "作为“明伐”牌置于武将牌上,并选择一名其他角色。该角色下回合结束时对其执行〖明伐〗的后续效果。" + ) + .set("card", cardx) + .set( + "goon", + (function () { + var getMax = function (card) { + return Math.max.apply( + Math, + game + .filterPlayer(function (current) { + return ( + current != player && + lib.filter.targetEnabled2(card, player, current) + ); + }) + .map(function (i) { + return ( + get.effect(i, card, player, player) * + Math.sqrt( + Math.min(i.getHandcardLimit(), 1 + i.countCards("h")) + ) + ); + }) + .concat([0]) + ); + }; + var eff1 = getMax(cardx); + if ( + player.hasCard(function (card) { + if ( + (card.name != "sha" && get.type(card) != "trick") || + !player.hasValueTarget(card, null, true) + ) + return false; + return ( + getMax({ + name: get.name(card), + nature: get.nature(card), + isCard: true, + }) >= eff1 + ); + }, "hs") + ) + return false; + return true; + })() + ) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + var player = _status.event.player, + card = _status.event.card; + if (!lib.filter.targetEnabled2(card, player, target)) return 0; + return ( + get.effect(target, card, player, player) * + Math.sqrt(Math.min(target.getHandcardLimit(), 1 + target.countCards("h"))) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcmingfa", target); + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, }; - player.storage.dcmingfa_info=[card,target]; - player.addToExpansion(trigger.cards.filterInD(),'gain2').gaintag.add('dcmingfa'); + player.storage.dcmingfa_info = [card, target]; + player.addToExpansion(trigger.cards.filterInD(), "gain2").gaintag.add("dcmingfa"); } }, - group:'dcmingfa_use', - ai:{expose:0.2}, - intro:{ - mark:function(dialog,storage,player){ - var cards=player.getExpansions('dcmingfa'); - if(!cards.length) return '没有“明伐”牌'; + group: "dcmingfa_use", + ai: { expose: 0.2 }, + intro: { + mark: function (dialog, storage, player) { + var cards = player.getExpansions("dcmingfa"); + if (!cards.length) return "没有“明伐”牌"; else dialog.add(cards); - var info=player.storage.dcmingfa_info; - if(info){ - dialog.addText('记录牌:'+get.translation(info[0])+'
              记录目标:'+get.translation(info[1])); + var info = player.storage.dcmingfa_info; + if (info) { + dialog.addText( + "记录牌:" + + get.translation(info[0]) + + "
              记录目标:" + + get.translation(info[1]) + ); } }, - content:'expansion', + content: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage.dcmingfa_info; }, - subSkill:{ - use:{ - audio:'dcmingfa', - trigger:{global:['phaseEnd','die']}, - forced:true, - filter:function(event,player){ - if(!player.storage.dcmingfa_info||!player.getExpansions('dcmingfa').length) return false; - return event.player==player.storage.dcmingfa_info[1]; + subSkill: { + use: { + audio: "dcmingfa", + trigger: { global: ["phaseEnd", "die"] }, + forced: true, + filter: function (event, player) { + if (!player.storage.dcmingfa_info || !player.getExpansions("dcmingfa").length) + return false; + return event.player == player.storage.dcmingfa_info[1]; }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - var card=player.storage.dcmingfa_info[0]; + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + var card = player.storage.dcmingfa_info[0]; delete player.storage.dcmingfa_info; - event.card=card; - event.count=Math.max(1,Math.min(5,target.countCards('h'))); - if(!event.player.isIn()) event.goto(2); - 'step 1' + event.card = card; + event.count = Math.max(1, Math.min(5, target.countCards("h"))); + if (!event.player.isIn()) event.goto(2); + "step 1"; event.count--; - if(target.isIn()&&lib.filter.targetEnabled2(card,player,target)){ - player.useCard(get.copy(card),target); - if(event.count>0) event.redo(); + if (target.isIn() && lib.filter.targetEnabled2(card, player, target)) { + player.useCard(get.copy(card), target); + if (event.count > 0) event.redo(); } - 'step 2' - var cards=player.getExpansions('dcmingfa'); - if(cards.length>0) player.loseToDiscardpile(cards); + "step 2"; + var cards = player.getExpansions("dcmingfa"); + if (cards.length > 0) player.loseToDiscardpile(cards); }, }, }, }, //蔡瑁张允 - lianzhou:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - if(!player.isLinked()) return true; - return game.hasPlayer(function(current){ - return current!=player&¤t.hp==player.hp&&!current.isLinked(); + lianzhou: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + if (!player.isLinked()) return true; + return game.hasPlayer(function (current) { + return current != player && current.hp == player.hp && !current.isLinked(); }); }, - content:function(){ - 'step 0' - if(!player.isLinked()) player.link(); - 'step 1' - var num=game.countPlayer(function(current){ - return current!=player&¤t.hp==player.hp&&!current.isLinked(); + content: function () { + "step 0"; + if (!player.isLinked()) player.link(); + "step 1"; + var num = game.countPlayer(function (current) { + return current != player && current.hp == player.hp && !current.isLinked(); }); - if(num>0){ - player.chooseTarget([1,num],'选择横置任意名体力值等于你的角色',function(card,player,current){ - return current!=player&¤t.hp==player.hp&&!current.isLinked(); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'tiesuo'},player,player); - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); - for(var i of targets) i.link(); + if (num > 0) { + player + .chooseTarget( + [1, num], + "选择横置任意名体力值等于你的角色", + function (card, player, current) { + return ( + current != player && current.hp == player.hp && !current.isLinked() + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "tiesuo" }, player, player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); + for (var i of targets) i.link(); } }, - ai:{halfneg:true}, + ai: { halfneg: true }, }, - jinglan:{ - audio:2, - trigger:{source:'damageSource'}, - forced:true, - content:function(){ - var delta=player.countCards('h')-player.hp; - if(delta>0) player.chooseToDiscard('h',4,true); - else if(delta==0){ - player.chooseToDiscard('h',true); + jinglan: { + audio: 2, + trigger: { source: "damageSource" }, + forced: true, + content: function () { + var delta = player.countCards("h") - player.hp; + if (delta > 0) player.chooseToDiscard("h", 4, true); + else if (delta == 0) { + player.chooseToDiscard("h", true); player.recover(); - } - else{ - player.damage('fire','nosource'); + } else { + player.damage("fire", "nosource"); player.draw(5); } }, - ai:{halfneg:true}, + ai: { halfneg: true }, }, //滕公主 - xingchong:{ - audio:2, - trigger:{global:'roundStart'}, - direct:true, - filter:function(event,player){ - return player.maxHp>0; + xingchong: { + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + filter: function (event, player) { + return player.maxHp > 0; }, - content:function(){ - 'step 0' - var list=[]; - for(var i=0;i<=Math.min(5,player.maxHp);i++){ - list.push(get.cnNumber(i)+'张'); + content: function () { + "step 0"; + var list = []; + for (var i = 0; i <= Math.min(5, player.maxHp); i++) { + list.push(get.cnNumber(i) + "张"); } - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('xingchong')).set('prompt2','请首先选择摸牌的张数').set('ai',function(){ - var player=_status.event.player,num1=player.maxHp,num2=player.countCards('h'); - if(num1<=num2) return 0; - return Math.ceil((num1-num2)/2); - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xingchong'); - var num2=result.index; - if(num2>0) player.draw(num2); - var num=Math.min(5,player.maxHp)-num2; - if(num==0) event.finish(); - else event.num=num; - } - else event.finish(); - 'step 2' - if(player.countCards('h')>0){ - player.chooseCard('h',[1,Math.min(player.countCards('h'),event.num)],'请选择要展示的牌').set('ai',()=>1+Math.random()); - } - else event.finish(); - 'step 3' - if(result.bool){ - var cards=result.cards; - player.showCards(cards,get.translation(player)+'发动了【幸宠】'); - player.addGaintag(cards,'xingchong'); - player.addTempSkill('xingchong_effect','roundStart'); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("xingchong")) + .set("prompt2", "请首先选择摸牌的张数") + .set("ai", function () { + var player = _status.event.player, + num1 = player.maxHp, + num2 = player.countCards("h"); + if (num1 <= num2) return 0; + return Math.ceil((num1 - num2) / 2); + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xingchong"); + var num2 = result.index; + if (num2 > 0) player.draw(num2); + var num = Math.min(5, player.maxHp) - num2; + if (num == 0) event.finish(); + else event.num = num; + } else event.finish(); + "step 2"; + if (player.countCards("h") > 0) { + player + .chooseCard( + "h", + [1, Math.min(player.countCards("h"), event.num)], + "请选择要展示的牌" + ) + .set("ai", () => 1 + Math.random()); + } else event.finish(); + "step 3"; + if (result.bool) { + var cards = result.cards; + player.showCards(cards, get.translation(player) + "发动了【幸宠】"); + player.addGaintag(cards, "xingchong"); + player.addTempSkill("xingchong_effect", "roundStart"); } }, - subSkill:{ - effect:{ - audio:'xingchong', - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + effect: { + audio: "xingchong", + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('xingchong')) return true; + filter: function (event, player) { + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("xingchong")) return true; } return false; } - return player.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('xingchong')) return true; + return player.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("xingchong")) return true; } return false; }); }, - forced:true, - popup:false, - charlotte:true, - onremove:function(player){ - player.removeGaintag('xingchong'); + forced: true, + popup: false, + charlotte: true, + onremove: function (player) { + player.removeGaintag("xingchong"); }, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - 'step 1' - player.logSkill('xingchong_effect'); - var num=0; - if(trigger.name=='lose'){ - for(var i in trigger.gaintag_map){ - if(trigger.gaintag_map[i].includes('xingchong')) num++; + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + "step 1"; + player.logSkill("xingchong_effect"); + var num = 0; + if (trigger.name == "lose") { + for (var i in trigger.gaintag_map) { + if (trigger.gaintag_map[i].includes("xingchong")) num++; } - } - else player.getHistory('lose',function(evt){ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('xingchong')) num++; - } - }); - player.draw(2*num); + } else + player.getHistory("lose", function (evt) { + if (trigger != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("xingchong")) num++; + } + }); + player.draw(2 * num); }, }, }, }, - liunian:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return game.hasGlobalHistory('cardMove',function(evt){ - return evt.washCard&&(evt.shuffleNumber==1||evt.shuffleNumber==2); + liunian: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return game.hasGlobalHistory("cardMove", function (evt) { + return evt.washCard && (evt.shuffleNumber == 1 || evt.shuffleNumber == 2); }); }, - content:function(){ - 'step 0' - if(game.hasGlobalHistory('cardMove',function(evt){ - return evt.washCard&&evt.shuffleNumber==1; - })){ + content: function () { + "step 0"; + if ( + game.hasGlobalHistory("cardMove", function (evt) { + return evt.washCard && evt.shuffleNumber == 1; + }) + ) { player.gainMaxHp(); game.delayx(); } - 'step 1' - if(game.hasGlobalHistory('cardMove',function(evt){ - return evt.washCard&&evt.shuffleNumber==2; - })){ + "step 1"; + if ( + game.hasGlobalHistory("cardMove", function (evt) { + return evt.washCard && evt.shuffleNumber == 2; + }) + ) { player.recover(); game.delayx(); - } - else event.finish(); - 'step 2' - player.addSkill('liunian_effect'); - player.addMark('liunian_effect',10,false); + } else event.finish(); + "step 2"; + player.addSkill("liunian_effect"); + player.addMark("liunian_effect", 10, false); }, - subSkill:{ - effect:{ - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('liunian_effect'); + subSkill: { + effect: { + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("liunian_effect"); }, }, - marktext:'年', - intro:{ - content:'手牌上限+#', + marktext: "年", + intro: { + content: "手牌上限+#", }, }, }, }, //黄承彦 - dcjiezhen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + dcjiezhen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - var skills=target.getSkills(null,false,false).filter(function(i){ - if(i=='bazhen') return; - var info=get.info(i); - return info&&!get.is.locked(i)&&!info.limited&&!info.juexingji&&!info.zhuSkill&&!info.charlotte; + content: function () { + var skills = target.getSkills(null, false, false).filter(function (i) { + if (i == "bazhen") return; + var info = get.info(i); + return ( + info && + !get.is.locked(i) && + !info.limited && + !info.juexingji && + !info.zhuSkill && + !info.charlotte + ); }); - target.addAdditionalSkills('dcjiezhen_blocker','bazhen'); - target.addSkill('dcjiezhen_blocker'); - target.markAuto('dcjiezhen_blocker',skills); - player.addSkill('dcjiezhen_clear'); - player.markAuto('dcjiezhen_clear',[target]); + target.addAdditionalSkills("dcjiezhen_blocker", "bazhen"); + target.addSkill("dcjiezhen_blocker"); + target.markAuto("dcjiezhen_blocker", skills); + player.addSkill("dcjiezhen_clear"); + player.markAuto("dcjiezhen_clear", [target]); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var skills=target.getSkills(null,false,false).filter(function(i){ - if(i=='bazhen') return; - var info=get.info(i); - return info&&!get.is.locked(i)&&!info.limited&&!info.juexingji&&!info.zhuSkill&&!info.charlotte; + ai: { + order: 1, + result: { + target: function (player, target) { + var skills = target.getSkills(null, false, false).filter(function (i) { + if (i == "bazhen") return; + var info = get.info(i); + return ( + info && + !get.is.locked(i) && + !info.limited && + !info.juexingji && + !info.zhuSkill && + !info.charlotte + ); }); - if(!skills.length&&target.hasEmptySlot(2)) return 1; - return -0.5*skills.length; + if (!skills.length && target.hasEmptySlot(2)) return 1; + return -0.5 * skills.length; }, }, }, - subSkill:{ - blocker:{ - init:function(player,skill){ + subSkill: { + blocker: { + init: function (player, skill) { player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); player.removeAdditionalSkill(skill); delete player.storage.dcjiezhen_blocker; }, - charlotte:true, - locked:true, - skillBlocker:function(skill,player){ - return skill!='bazhen'&&skill!='dcjiezhen_blocker'&&!lib.skill[skill].charlotte&&player.getStorage('dcjiezhen_blocker').includes(skill); + charlotte: true, + locked: true, + skillBlocker: function (skill, player) { + return ( + skill != "bazhen" && + skill != "dcjiezhen_blocker" && + !lib.skill[skill].charlotte && + player.getStorage("dcjiezhen_blocker").includes(skill) + ); + }, + mark: true, + marktext: "阵", + intro: { + markcount: () => 0, + content: function (storage, player, skill) { + if (storage.length) return "失效技能:" + get.translation(storage); + return "无失效技能"; + }, }, - mark:true, - marktext:'阵', - intro:{ - markcount:()=>0, - content:function(storage,player,skill){ - if(storage.length) return '失效技能:'+get.translation(storage); - return '无失效技能'; - } - } }, - clear:{ - audio:'dcjiezhen', - charlotte:true, - trigger:{ - global:['judgeAfter','die'], - player:'phaseBegin', + clear: { + audio: "dcjiezhen", + charlotte: true, + trigger: { + global: ["judgeAfter", "die"], + player: "phaseBegin", }, - forced:true, - forceDie:true, - onremove:true, - filter:function(event,player){ - if(event.name=='die'){ - return player==event.player||player.getStorage('dcjiezhen_clear').includes(event.player); + forced: true, + forceDie: true, + onremove: true, + filter: function (event, player) { + if (event.name == "die") { + return ( + player == event.player || + player.getStorage("dcjiezhen_clear").includes(event.player) + ); + } else if (event.name == "judge") { + return ( + event.skill == "bagua" && + player.getStorage("dcjiezhen_clear").includes(event.player) + ); } - else if(event.name=='judge'){ - return event.skill=='bagua'&&player.getStorage('dcjiezhen_clear').includes(event.player); - } - return player.getStorage('dcjiezhen_clear').length>0; + return player.getStorage("dcjiezhen_clear").length > 0; }, - logTarget:function(event,player){ - if(event.name!='phase') return event.player; - return player.getStorage('dcjiezhen_clear'); + logTarget: function (event, player) { + if (event.name != "phase") return event.player; + return player.getStorage("dcjiezhen_clear"); }, - content:function(){ - 'step 0' - var targets=player.getStorage('dcjiezhen_clear'); - if(trigger.name=='die'&&player==trigger.player){ - for(var target of targets){ - target.removeSkill('dcjiezhen_blocker'); + content: function () { + "step 0"; + var targets = player.getStorage("dcjiezhen_clear"); + if (trigger.name == "die" && player == trigger.player) { + for (var target of targets) { + target.removeSkill("dcjiezhen_blocker"); } - player.removeSkill('dcjiezhen_clear'); + player.removeSkill("dcjiezhen_clear"); event.finish(); return; } - if(trigger.name=='phase') event.targets=targets.slice(0).sortBySeat(); - else event.targets=[trigger.player]; - 'step 1' - var target=targets.shift(); - var storage=player.getStorage('dcjiezhen_clear'); - if(storage.includes(target)){ + if (trigger.name == "phase") event.targets = targets.slice(0).sortBySeat(); + else event.targets = [trigger.player]; + "step 1"; + var target = targets.shift(); + var storage = player.getStorage("dcjiezhen_clear"); + if (storage.includes(target)) { storage.remove(target); - target.removeSkill('dcjiezhen_blocker'); - if(target.isIn()&&target.countGainableCards(player,'hej')>0) player.gainPlayerCard(target,'hej',true); + target.removeSkill("dcjiezhen_blocker"); + if (target.isIn() && target.countGainableCards(player, "hej") > 0) + player.gainPlayerCard(target, "hej", true); } - if(targets.length>0){ + if (targets.length > 0) { event.redo(); - } - else{ - player.removeSkill('dcjiezhen_clear'); + } else { + player.removeSkill("dcjiezhen_clear"); } }, }, }, - derivation:'bazhen', + derivation: "bazhen", }, - dczecai:{ - audio:2, - trigger:{global:'roundStart'}, - limited:true, - skillAnimation:true, - direct:true, - animationColor:'soil', - filter:function(event,player){ - return game.roundNumber>1; + dczecai: { + audio: 2, + trigger: { global: "roundStart" }, + limited: true, + skillAnimation: true, + direct: true, + animationColor: "soil", + filter: function (event, player) { + return game.roundNumber > 1; }, - getMax:function(){ - var getNum=function(current){ - var history=current.actionHistory; - var num=0; - for(var i=history.length-2;i>=0;i--){ - for(var j=0;j= 0; i--) { + for (var j = 0; j < history[i].useCard.length; j++) { + if (get.type2(history[i].useCard[j].card, false) == "trick") num++; } - if(history[i].isRound) break; + if (history[i].isRound) break; } return num; }; - var max=0,current=false,targets=game.filterPlayer(); - for(var target of targets){ - var num=getNum(target); - if(num>max){ - max=num; - current=target; - } - else if(num==max) current=false; + var max = 0, + current = false, + targets = game.filterPlayer(); + for (var target of targets) { + var num = getNum(target); + if (num > max) { + max = num; + current = target; + } else if (num == max) current = false; } return current; }, - content:function(){ - 'step 0' - event.target=lib.skill.dczecai.getMax(); - var str='令一名其他角色于本轮内获得〖集智〗'; - if(event.target&&event.target!=player) str+=(';若选择的目标为'+get.translation(event.target)+',则其获得一个额外的回合'); - player.chooseTarget(lib.filter.notMe,get.prompt('dczecai'),str).set('maximum',event.target).set('ai',function(target){ - if(target!=_status.event.maximum) return 0; - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - player.awakenSkill('dczecai'); - var target=result.targets[0]; - player.logSkill('dczecai',target); - target.addAdditionalSkills('dczecai_effect','rejizhi'); - target.addTempSkill('dczecai_effect','roundStart'); - if(target==event.target){ - var evt=trigger; + content: function () { + "step 0"; + event.target = lib.skill.dczecai.getMax(); + var str = "令一名其他角色于本轮内获得〖集智〗"; + if (event.target && event.target != player) + str += + ";若选择的目标为" + get.translation(event.target) + ",则其获得一个额外的回合"; + player + .chooseTarget(lib.filter.notMe, get.prompt("dczecai"), str) + .set("maximum", event.target) + .set("ai", function (target) { + if (target != _status.event.maximum) return 0; + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.awakenSkill("dczecai"); + var target = result.targets[0]; + player.logSkill("dczecai", target); + target.addAdditionalSkills("dczecai_effect", "rejizhi"); + target.addTempSkill("dczecai_effect", "roundStart"); + if (target == event.target) { + var evt = trigger; target.insertPhase(); - if(evt.player!=target&&!evt._finished){ + if (evt.player != target && !evt._finished) { evt.finish(); - evt._triggered=5; - var evtx=evt.player.insertPhase(); + evt._triggered = 5; + var evtx = evt.player.insertPhase(); delete evtx.skill; } } } }, - derivation:'rejizhi', - subSkill:{ - effect:{ - charlotte:true, - mark:true, - marktext:'才', - intro:{content:'已拥有技能〖集智〗'}, + derivation: "rejizhi", + subSkill: { + effect: { + charlotte: true, + mark: true, + marktext: "才", + intro: { content: "已拥有技能〖集智〗" }, }, }, }, - dcyinshi:{ - audio:2, - trigger:{player:'damageBegin'}, - usable:1, - filter:function(event,player){ - return !event.card||get.color(event.card)=='none'; + dcyinshi: { + audio: 2, + trigger: { player: "damageBegin" }, + usable: 1, + filter: function (event, player) { + return !event.card || get.color(event.card) == "none"; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); }, - group:'dcyinshi_gain', - subSkill:{ - gain:{ - audio:'dcyinshi', - trigger:{global:'judgeEnd'}, - forced:true, - filter:function(event,player){ - return event.skill=='bagua'&&event.result.card&&get.position(event.result.card,true)=='o'; + group: "dcyinshi_gain", + subSkill: { + gain: { + audio: "dcyinshi", + trigger: { global: "judgeEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.skill == "bagua" && + event.result.card && + get.position(event.result.card, true) == "o" + ); }, - content:function(){ - player.gain(trigger.result.card,'gain2'); + content: function () { + player.gain(trigger.result.card, "gain2"); }, }, }, }, //高览 - xizhen:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&(player.canUse('sha',current,false)||player.canUse('juedou',current,false)); - }) - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('xizhen'),'视为对一名角色使用【杀】或【决斗】',function(card,player,target){ - return target!=player&&(player.canUse('sha',target,false)||player.canUse('juedou',target,false)); - }).set('ai',function(target){ - var player=_status.event.player; - var eff1=0,eff2=0; - if(player.canUse('sha',target,false)) eff1=get.effect(target,{name:'sha'},player,player); - if(player.canUse('juedou',target,false)) eff2=get.effect(target,{name:'juedou'},player,player); - var effx=Math.max(eff1,eff2); - if(effx<=0) return 0; - if(target.isHealthy()) effx*=3; - if(get.attitude(player,target)>0) effx*=1.6; - return effx; + xizhen: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && + (player.canUse("sha", current, false) || player.canUse("juedou", current, false)) + ); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xizhen',target); - var list=[]; - if(player.canUse('sha',target,false)) list.push('sha'); - if(player.canUse('juedou',target,false)) list.push('juedou'); - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('prompt','视为对'+get.translation(target)+'使用…').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - var eff1=get.effect(target,{name:'sha'},player,player),eff2=get.effect(target,{name:'juedou'},player,player); - return eff1>eff2?0:1; + }, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xizhen"), + "视为对一名角色使用【杀】或【决斗】", + function (card, player, target) { + return ( + target != player && + (player.canUse("sha", target, false) || + player.canUse("juedou", target, false)) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var eff1 = 0, + eff2 = 0; + if (player.canUse("sha", target, false)) + eff1 = get.effect(target, { name: "sha" }, player, player); + if (player.canUse("juedou", target, false)) + eff2 = get.effect(target, { name: "juedou" }, player, player); + var effx = Math.max(eff1, eff2); + if (effx <= 0) return 0; + if (target.isHealthy()) effx *= 3; + if (get.attitude(player, target) > 0) effx *= 1.6; + return effx; }); - } - else event.finish(); - 'step 2' - player.useCard({name:result.control,isCard:true},target,false); - 'step 3' - if(target.isIn()){ - player.storage.xizhen_effect=target; - player.addTempSkill('xizhen_effect','phaseUseAfter'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xizhen", target); + var list = []; + if (player.canUse("sha", target, false)) list.push("sha"); + if (player.canUse("juedou", target, false)) list.push("juedou"); + if (list.length == 1) event._result = { control: list[0] }; + else + player + .chooseControl(list) + .set("prompt", "视为对" + get.translation(target) + "使用…") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + var eff1 = get.effect(target, { name: "sha" }, player, player), + eff2 = get.effect(target, { name: "juedou" }, player, player); + return eff1 > eff2 ? 0 : 1; + }); + } else event.finish(); + "step 2"; + player.useCard({ name: result.control, isCard: true }, target, false); + "step 3"; + if (target.isIn()) { + player.storage.xizhen_effect = target; + player.addTempSkill("xizhen_effect", "phaseUseAfter"); } }, - subSkill:{ - effect:{ - audio:'xizhen', - charlotte:true, - onremove:true, - trigger:{global:['useCard','respond']}, - logTarget:function(event,player){ + subSkill: { + effect: { + audio: "xizhen", + charlotte: true, + onremove: true, + trigger: { global: ["useCard", "respond"] }, + logTarget: function (event, player) { return player.storage.xizhen_effect; }, - forced:true, - filter:function(event,player){ - return Array.isArray(event.respondTo)&&event.respondTo[0]==player&&player.storage.xizhen_effect&&player.storage.xizhen_effect.isIn(); + forced: true, + filter: function (event, player) { + return ( + Array.isArray(event.respondTo) && + event.respondTo[0] == player && + player.storage.xizhen_effect && + player.storage.xizhen_effect.isIn() + ); }, - content:function(){ - 'step 0' - var target=player.storage.xizhen_effect; - event.target=target; + content: function () { + "step 0"; + var target = player.storage.xizhen_effect; + event.target = target; target.recover(); - 'step 1' - player.draw(target.isHealthy()?2:1); + "step 1"; + player.draw(target.isHealthy() ? 2 : 1); }, - mark:'character', - intro:{content:'已指定$为目标'}, + mark: "character", + intro: { content: "已指定$为目标" }, }, }, }, //管宁 - dunshi:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - usable:1, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[['sha','shan','tao','jiu'],0]; + dunshi: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + usable: 1, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = [["sha", "shan", "tao", "jiu"], 0]; }, - hiddenCard:function(player,name){ - if(player.storage.dunshi&&player.storage.dunshi[0].includes(name)&&!player.getStat('skill').dunshi) return true; + hiddenCard: function (player, name) { + if ( + player.storage.dunshi && + player.storage.dunshi[0].includes(name) && + !player.getStat("skill").dunshi + ) + return true; return false; }, - marktext:'席', - mark:true, - intro:{ - markcount:function(storage){ + marktext: "席", + mark: true, + intro: { + markcount: function (storage) { return storage[1]; }, - content:function(storage,player){ - if(!storage) return; - var str='
            • '; - if(!storage[0].length){ - str+='已无可用牌'; + content: function (storage, player) { + if (!storage) return; + var str = "
            • "; + if (!storage[0].length) { + str += "已无可用牌"; + } else { + str += "剩余可用牌:"; + str += get.translation(storage[0]); } - else{ - str+='剩余可用牌:'; - str+=get.translation(storage[0]); - } - str+='
            • “席”标记数量:'; - str+=(storage[1]); + str += "
            • “席”标记数量:"; + str += storage[1]; return str; }, }, - filter:function(event,player){ - if(event.type=='wuxie') return false; - var storage=player.storage.dunshi; - if(!storage||!storage[0].length) return false; - for(var i of storage[0]){ - var card={name:i,isCard:true}; - if(event.filterCard(card,player,event)) return true; + filter: function (event, player) { + if (event.type == "wuxie") return false; + var storage = player.storage.dunshi; + if (!storage || !storage[0].length) return false; + for (var i of storage[0]) { + var card = { name: i, isCard: true }; + if (event.filterCard(card, player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - var storage=player.storage.dunshi; - for(var i of storage[0]) list.push(['基本','',i]); - return ui.create.dialog('遁世',[list,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + var list = []; + var storage = player.storage.dunshi; + for (var i of storage[0]) list.push(["基本", "", i]); + return ui.create.dialog("遁世", [list, "vcard"], "hidden"); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard({name:button.link[2],isCard:true},player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard({ name: button.link[2], isCard: true }, player, evt); }, - check:function(button){ - var card={name:button.link[2]},player=_status.event.player; - if(_status.event.getParent().type!='phase') return 1; - if(card.name=='jiu') return 0; - if(card.name=='sha'&&player.hasSkill('jiu')) return 0; - return player.getUseValue(card,null,true); + check: function (button) { + var card = { name: button.link[2] }, + player = _status.event.player; + if (_status.event.getParent().type != "phase") return 1; + if (card.name == "jiu") return 0; + if (card.name == "sha" && player.hasSkill("jiu")) return 0; + return player.getUseValue(card, null, true); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'dunshi', - filterCard:function(){return false}, - popname:true, - viewAs:{ - name:links[0][2], - isCard:true, + audio: "dunshi", + filterCard: function () { + return false; }, - selectCard:-1, - precontent:function(){ - player.addTempSkill('dunshi_damage'); - player.storage.dunshi_damage=event.result.card.name; + popname: true, + viewAs: { + name: links[0][2], + isCard: true, }, - } + selectCard: -1, + precontent: function () { + player.addTempSkill("dunshi_damage"); + player.storage.dunshi_damage = event.result.card.name; + }, + }; + }, + prompt: function (links, player) { + return "选择【" + get.translation(links[0][2]) + "】的目标"; }, - prompt:function(links,player){ - return '选择【'+get.translation(links[0][2])+'】的目标'; - } }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - var storage=player.storage.dunshi; - if(!storage||!storage[0].length) return false; - if(player.getStat('skill').dunshi) return false; - switch(tag){ - case 'respondSha':return (_status.event.type!='phase'||(player==game.me||player.isUnderControl()||player.isOnline()))&&storage[0].includes('sha'); - case 'respondShan':return storage[0].includes('shan'); - case 'save': - if(arg==player&&storage[0].includes('jiu')) return true; - return storage[0].includes('tao'); + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + var storage = player.storage.dunshi; + if (!storage || !storage[0].length) return false; + if (player.getStat("skill").dunshi) return false; + switch (tag) { + case "respondSha": + return ( + (_status.event.type != "phase" || + player == game.me || + player.isUnderControl() || + player.isOnline()) && + storage[0].includes("sha") + ); + case "respondShan": + return storage[0].includes("shan"); + case "save": + if (arg == player && storage[0].includes("jiu")) return true; + return storage[0].includes("tao"); } }, - order:2, - result:{ - player:function(player){ - if(_status.event.type=='dying'){ - return get.attitude(player,_status.event.dying); + order: 2, + result: { + player: function (player) { + if (_status.event.type == "dying") { + return get.attitude(player, _status.event.dying); } return 1; }, }, }, - initList:function(){ - var list,skills=[]; - var banned=['xunyi','mbyilie']; - if(get.mode()=='guozhan'){ - list=[]; - for(var i in lib.characterPack.mode_guozhan) list.push(i); - } - else if(_status.connectMode) list=get.charactersOL(); - else{ - list=[]; - for(var i in lib.character){ - if(lib.filter.characterDisabled2(i)||lib.filter.characterDisabled(i)) continue; + initList: function () { + var list, + skills = []; + var banned = ["xunyi", "mbyilie"]; + if (get.mode() == "guozhan") { + list = []; + for (var i in lib.characterPack.mode_guozhan) list.push(i); + } else if (_status.connectMode) list = get.charactersOL(); + else { + list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled2(i) || lib.filter.characterDisabled(i)) continue; list.push(i); } } - for(var i of list){ - if(i.indexOf('gz_jun')==0) continue; - for(var j of lib.character[i][3]){ - var skill=lib.skill[j]; - if(!skill||skill.zhuSkill||banned.includes(j)) continue; - if(skill.ai&&(skill.ai.combo||skill.ai.notemp||skill.ai.neg)) continue; - var info=get.translation(j); - for(var ix=0;ix{ - return [i,item]; - }),'textbutton'] + var next = player.chooseButton([ + "遁世:请选择两项", + [ + list.map((item, i) => { + return [i, item]; + }), + "textbutton", + ], ]); - next.set('forced',true); - next.set('selectButton',2); - next.set('ai',function(button){ - var player=_status.event.player; - switch(button.link){ + next.set("forced", true); + next.set("selectButton", 2); + next.set("ai", function (button) { + var player = _status.event.player; + switch (button.link) { case 0: - if(get.attitude(player,_status.currentPhase)>0) return 3; + if (get.attitude(player, _status.currentPhase) > 0) return 3; return 0; case 1: return 1; case 2: - var num=player.storage.dunshi[1]; - for(var i of ui.selected.buttons){ - if(i.link==1) num++; + var num = player.storage.dunshi[1]; + for (var i of ui.selected.buttons) { + if (i.link == 1) num++; } - if(num>0&&player.isDamaged()) return 2; + if (num > 0 && player.isDamaged()) return 2; return 0; } }); - 'step 1' - event.links=result.links.sort(); - for(var i of event.links){ - game.log(player,'选择了','#g【遁世】','的','#y选项'+get.cnNumber(i+1,true)); + "step 1"; + event.links = result.links.sort(); + for (var i of event.links) { + game.log( + player, + "选择了", + "#g【遁世】", + "的", + "#y选项" + get.cnNumber(i + 1, true) + ); } - if(event.links.includes(0)){ + if (event.links.includes(0)) { trigger.cancel(); - if(!_status.dunshi_list) lib.skill.dunshi.initList(); - var list=_status.dunshi_list.filter(function(i){ - return !target.hasSkill(i,null,null,false); - }).randomGets(3); - if(list.length==0) event.goto(3); - else{ - event.videoId=lib.status.videoId++; - var func=function(skills,id,target){ - var dialog=ui.create.dialog('forcebutton'); - dialog.videoId=id; - dialog.add('令'+get.translation(target)+'获得一个技能'); - for(var i=0;i
              【'+get.translation(skills[i])+'】
              '+lib.translate[skills[i]+'_info']+'
              '); + if (!_status.dunshi_list) lib.skill.dunshi.initList(); + var list = _status.dunshi_list + .filter(function (i) { + return !target.hasSkill(i, null, null, false); + }) + .randomGets(3); + if (list.length == 0) event.goto(3); + else { + event.videoId = lib.status.videoId++; + var func = function (skills, id, target) { + var dialog = ui.create.dialog("forcebutton"); + dialog.videoId = id; + dialog.add("令" + get.translation(target) + "获得一个技能"); + for (var i = 0; i < skills.length; i++) { + dialog.add( + '" + ); } - dialog.addText('
              '); - } - if(player.isOnline()) player.send(func,list,event.videoId,target); - else if(player==game.me) func(list,event.videoId,target); - player.chooseControl(list).set('ai',function(){ - var controls=_status.event.controls; - if(controls.includes('cslilu')) return 'cslilu'; + dialog.addText("
              "); + }; + if (player.isOnline()) player.send(func, list, event.videoId, target); + else if (player == game.me) func(list, event.videoId, target); + player.chooseControl(list).set("ai", function () { + var controls = _status.event.controls; + if (controls.includes("cslilu")) return "cslilu"; return controls[0]; }); } - } - else event.goto(3); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); + } else event.goto(3); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); target.addSkills(result.control); - 'step 3' - var storage=player.storage.dunshi; - if(event.links.includes(1)){ + "step 3"; + var storage = player.storage.dunshi; + if (event.links.includes(1)) { storage[0].remove(event.cardname); storage[1]++; - player.markSkill('dunshi'); + player.markSkill("dunshi"); } - if(event.links.includes(2)){ + if (event.links.includes(2)) { player.loseMaxHp(); - if(storage[1]>0) player.draw(storage[1]); + if (storage[1] > 0) player.draw(storage[1]); } }, }, }, }, //吉本 - xunli:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + xunli: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - forced:true, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false||player.getExpansions('xunli').length>=9) return false; - for(var i of event.cards){ - if(get.position(i,true)=='d'&&get.color(i,event.cards2&&event.cards2.includes(i)?event.player:false)=='black') return true; + forced: true, + filter: function (event, player) { + if ( + event.type != "discard" || + event.getlx === false || + player.getExpansions("xunli").length >= 9 + ) + return false; + for (var i of event.cards) { + if ( + get.position(i, true) == "d" && + get.color(i, event.cards2 && event.cards2.includes(i) ? event.player : false) == + "black" + ) + return true; } return false; }, - content:function(){ - 'step 0' - var num=9-player.getExpansions('xunli').length; - var cards=[]; - for(var i of trigger.cards){ - if(get.position(i,true)=='d'&&get.color(i,trigger.cards2&&trigger.cards2.includes(i)?trigger.player:false)=='black') cards.push(i); + content: function () { + "step 0"; + var num = 9 - player.getExpansions("xunli").length; + var cards = []; + for (var i of trigger.cards) { + if ( + get.position(i, true) == "d" && + get.color( + i, + trigger.cards2 && trigger.cards2.includes(i) ? trigger.player : false + ) == "black" + ) + cards.push(i); } - if(cards.length<=num) event._result={ - bool:true, - links:cards, - } - else player.chooseButton(true,num,['寻疠:将'+get.cnNumber(num)+'张牌置于武将牌上',cards]).set('forceAuto',true).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); - 'step 1' - if(result.bool){ - player.addToExpansion('gain2',result.links).gaintag.add('xunli'); + if (cards.length <= num) + event._result = { + bool: true, + links: cards, + }; + else + player + .chooseButton(true, num, [ + "寻疠:将" + get.cnNumber(num) + "张牌置于武将牌上", + cards, + ]) + .set("forceAuto", true) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); + "step 1"; + if (result.bool) { + player.addToExpansion("gain2", result.links).gaintag.add("xunli"); } }, - marktext:'疠', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "疠", + intro: { + content: "expansion", + markcount: "expansion", }, - group:'xunli_exchange', - subSkill:{ - exchange:{ - audio:'xunli', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('xunli').length>0&&player.hasCard((card)=>get.color(card,player)=='black','h'); + group: "xunli_exchange", + subSkill: { + exchange: { + audio: "xunli", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getExpansions("xunli").length > 0 && + player.hasCard((card) => get.color(card, player) == "black", "h") + ); }, - content:function(){ - "step 0" - var cards=player.getExpansions('xunli'); - if(!cards.length||!player.countCards('h')){ + content: function () { + "step 0"; + var cards = player.getExpansions("xunli"); + if (!cards.length || !player.countCards("h")) { event.finish(); return; } - var next=player.chooseToMove('寻疠:是否交换“疠”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的疠',cards], - ['手牌区',player.getCards('h',(card)=>get.color(card,player)=='black')], + var next = player.chooseToMove("寻疠:是否交换“疠”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的疠", cards], + [ + "手牌区", + player.getCards("h", (card) => get.color(card, player) == "black"), + ], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player; - var getv=function(card){ - if(get.info(card).toself) return 0; - return player.getUseValue(card,false); + next.set("processAI", function (list) { + var player = _status.event.player; + var getv = function (card) { + if (get.info(card).toself) return 0; + return player.getUseValue(card, false); }; - var cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return getv(b)-getv(a); - }),cards2=cards.splice(0,player.getExpansions('xunli').length); - return [cards2,cards]; + var cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return getv(b) - getv(a); + }), + cards2 = cards.splice(0, player.getExpansions("xunli").length); + return [cards2, cards]; }); - "step 1" - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('xunli')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.logSkill('xunli_exchange'); - player.addToExpansion(pushs,player,'giveAuto').gaintag.add('xunli'); - game.log(player,'将',pushs,'作为“疠”置于武将牌上'); - player.gain(gains,'gain2'); + "step 1"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("xunli")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.logSkill("xunli_exchange"); + player.addToExpansion(pushs, player, "giveAuto").gaintag.add("xunli"); + game.log(player, "将", pushs, "作为“疠”置于武将牌上"); + player.gain(gains, "gain2"); } }, }, }, }, - zhishi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('zhishi')).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<=4) return 0; - if(target.hasSkillTag('nogain')) att/=10; + zhishi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("zhishi")).set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att <= 4) return 0; + if (target.hasSkillTag("nogain")) att /= 10; return att; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhishi',target); - player.storage.zhishi_mark=target; - player.addTempSkill('zhishi_mark',{player:'phaseBegin'}); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhishi", target); + player.storage.zhishi_mark = target; + player.addTempSkill("zhishi_mark", { player: "phaseBegin" }); } }, - ai:{expose:0.3}, - subSkill:{ - mark:{ - trigger:{ - global:['dying','useCardToTargeted'], + ai: { + combo: "xunli", + expose: 0.3 + }, + subSkill: { + mark: { + trigger: { + global: ["dying", "useCardToTargeted"], }, - direct:true, - charlotte:true, - filter:function(event,player){ - if(!player.getExpansions('xunli').length) return false; - var target=player.storage.zhishi_mark; - if(event.name=='dying') return event.player==target; - return event.card.name=='sha'&&event.target==target; + direct: true, + charlotte: true, + filter: function (event, player) { + if (!player.getExpansions("xunli").length) return false; + var target = player.storage.zhishi_mark; + if (event.name == "dying") return event.player == target; + return event.card.name == "sha" && event.target == target; }, - content:function(){ - 'step 0' - var target=player.storage.zhishi_mark; - event.target=target; - player.chooseButton([get.prompt('zhishi',target),'
              弃置任意张“疠”并令其摸等量的牌
              ',player.getExpansions('xunli')],[1,Infinity]).set('ai',function(button){ - var player=_status.event.player,target=player.storage.zhishi_mark; - if(target.hp<1&&target!=get.zhu(player)) return 0; - if(target.hasSkillTag('nogain')) return 0; - return 3-player.getUseValue(card,false); - }); - 'step 1' - if(result.bool){ - player.logSkill('zhishi',target); + content: function () { + "step 0"; + var target = player.storage.zhishi_mark; + event.target = target; + player + .chooseButton( + [ + get.prompt("zhishi", target), + '
              弃置任意张“疠”并令其摸等量的牌
              ', + player.getExpansions("xunli"), + ], + [1, Infinity] + ) + .set("ai", function (button) { + var player = _status.event.player, + target = player.storage.zhishi_mark; + if (target.hp < 1 && target != get.zhu(player)) return 0; + if (target.hasSkillTag("nogain")) return 0; + return 3 - player.getUseValue(card, false); + }); + "step 1"; + if (result.bool) { + player.logSkill("zhishi", target); player.loseToDiscardpile(result.links); target.draw(result.links.length); } }, - mark:'character', - intro:{ - content:'决定帮助$,具体帮不帮另说', + mark: "character", + intro: { + content: "决定帮助$,具体帮不帮另说", }, }, }, }, - lieyi:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.getExpansions('xunli').length>0; + lieyi: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.getExpansions("xunli").length > 0; }, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - var cards=player.getExpansions('xunli'); - var cards2=cards.filter(function(card){ - return target.isIn()&&player.canUse(card,target,false); + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + var cards = player.getExpansions("xunli"); + var cards2 = cards.filter(function (card) { + return target.isIn() && player.canUse(card, target, false); }); - if(cards2.length){ - player.chooseButton(['对'+get.translation(target)+'使用一张牌',cards2],true).set('ai',function(button){ - return get.order(button.link); - }); - } - else{ + if (cards2.length) { + player + .chooseButton(["对" + get.translation(target) + "使用一张牌", cards2], true) + .set("ai", function (button) { + return get.order(button.link); + }); + } else { event.finish(); - if(cards.length) player.loseToDiscardpile(cards); - if(target.isIn()&&!target.hasHistory('damage',function(evt){ - return evt.getParent('lieyi')==event&&evt._dyinged; - })) player.loseHp(); + if (cards.length) player.loseToDiscardpile(cards); + if ( + target.isIn() && + !target.hasHistory("damage", function (evt) { + return evt.getParent("lieyi") == event && evt._dyinged; + }) + ) + player.loseHp(); } - 'step 1' - player.useCard(result.links[0],target,false); + "step 1"; + player.useCard(result.links[0], target, false); event.goto(0); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - var cards=player.getExpansions('xunli'); - var effect=0,damage=0; - for(var i of cards){ - if(player.canUse(i,target,false)){ - effect+=get.effect(target,i,player,target); - damage+=get.tag(i,'damage'); + ai: { + order: 2, + result: { + target: function (player, target) { + var cards = player.getExpansions("xunli"); + var effect = 0, + damage = 0; + for (var i of cards) { + if (player.canUse(i, target, false)) { + effect += get.effect(target, i, player, target); + damage += get.tag(i, "damage"); } } - if(damage>=target.hp) return effect; - if(player.hp>2&&cards.length>3) return effect/3; + if (damage >= target.hp) return effect; + if (player.hp > 2 && cards.length > 3) return effect / 3; return 0; }, }, }, }, //马日磾 - bingjie:{ - trigger:{player:'phaseUseBegin'}, - check:function(event,player){ - return player.maxHp>3&&player.isDamaged()&&player.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)<0&&player.canUse(card,current,null,true)&&get.effect(current,card,player,player)>0; - })&&player.hasValueTarget(card); - },'hs'); + bingjie: { + trigger: { player: "phaseUseBegin" }, + check: function (event, player) { + return ( + player.maxHp > 3 && + player.isDamaged() && + player.hasCard(function (card) { + return ( + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) < 0 && + player.canUse(card, current, null, true) && + get.effect(current, card, player, player) > 0 + ); + }) && player.hasValueTarget(card) + ); + }, "hs") + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' - player.addTempSkill('bingjie_effect'); + "step 1"; + player.addTempSkill("bingjie_effect"); game.delayx(); }, - subSkill:{ - effect:{ - audio:'bingjie', - trigger:{player:'useCardToPlayered'}, - forced:true, - charlotte:true, - logTarget:'target', - filter:function(event,player){ - return event.target!=player&&(event.card.name=='sha'||get.type(event.card,false)=='trick')&&event.target.countCards('he')>0; + subSkill: { + effect: { + audio: "bingjie", + trigger: { player: "useCardToPlayered" }, + forced: true, + charlotte: true, + logTarget: "target", + filter: function (event, player) { + return ( + event.target != player && + (event.card.name == "sha" || get.type(event.card, false) == "trick") && + event.target.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - trigger.target.chooseToDiscard('he',true); - 'step 1' - if(result.bool&&result.cards.length&&get.color(result.cards[0],trigger.target)==get.color(trigger.card)){ - game.log(trigger.target,'不能响应',trigger.card); + content: function () { + "step 0"; + trigger.target.chooseToDiscard("he", true); + "step 1"; + if ( + result.bool && + result.cards.length && + get.color(result.cards[0], trigger.target) == get.color(trigger.card) + ) { + game.log(trigger.target, "不能响应", trigger.card); 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]; - } - } - } + 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]; + }, + }, + }, }, }, }, - zhengding:{ - audio:2, - trigger:{player:['useCard','respond']}, - forced:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(!Array.isArray(event.respondTo)) return false; - if(player==event.respondTo[0]) return false; - var color=get.color(event.card); - if(color=='none') return false; - return color==get.color(event.respondTo[1]); + zhengding: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (!Array.isArray(event.respondTo)) return false; + if (player == event.respondTo[0]) return false; + var color = get.color(event.card); + if (color == "none") return false; + return color == get.color(event.respondTo[1]); }, - content:function(){ + content: function () { player.gainMaxHp(); player.recover(); }, }, //孙茹 - xiecui:{ - audio:2, - trigger:{global:'damageBegin1'}, - filter:function(event,player){ - var source=event.source; - if(!source||source!=_status.currentPhase||event.getParent().type!='card') return false; - return !source.hasHistory('sourceDamage',function(evt){ - return evt.getParent().type=='card'; + xiecui: { + audio: 2, + trigger: { global: "damageBegin1" }, + filter: function (event, player) { + var source = event.source; + if (!source || source != _status.currentPhase || event.getParent().type != "card") + return false; + return !source.hasHistory("sourceDamage", function (evt) { + return evt.getParent().type == "card"; }); }, - logTarget:'source', - prompt2:function(event,player){ - var str=('令'+get.translation(event.player)+'即将受到的'); - str+=(''+event.num+'点'); - if(event.hasNature('linked')){ - str+=(get.translation(event.nature)+'属性'); + logTarget: "source", + prompt2: function (event, player) { + var str = "令" + get.translation(event.player) + "即将受到的"; + str += "" + event.num + "点"; + if (event.hasNature("linked")) { + str += get.translation(event.nature) + "属性"; } - str+='伤害+1'; - if(event.source.group=='wu'){ - var cards=event.cards.filterInD(); - if(cards.length){ - str+=(';然后'+get.translation(event.source)+'获得'+get.translation(cards)+',且本回合的手牌上限+1') + str += "伤害+1"; + if (event.source.group == "wu") { + var cards = event.cards.filterInD(); + if (cards.length) { + str += + ";然后" + + get.translation(event.source) + + "获得" + + get.translation(cards) + + ",且本回合的手牌上限+1"; } } return str; }, - check:function(event,player){ - var att=get.attitude(player,event.player); - if(att<0){ - if(event.source.group!='wu'||!event.cards.filterInD().length) return true; - return get.attitude(player,event.source)>0; + check: function (event, player) { + var att = get.attitude(player, event.player); + if (att < 0) { + if (event.source.group != "wu" || !event.cards.filterInD().length) return true; + return get.attitude(player, event.source) > 0; } return false; }, - content:function(){ + content: function () { trigger.num++; - var source=trigger.source; - if(source.group=='wu'){ - var cards=trigger.cards.filterInD(); - if(cards.length>0){ - source.gain(cards,'gain2'); - source.addMark('xiecui_effect',1,false); - source.addTempSkill('xiecui_effect'); + var source = trigger.source; + if (source.group == "wu") { + var cards = trigger.cards.filterInD(); + if (cards.length > 0) { + source.gain(cards, "gain2"); + source.addMark("xiecui_effect", 1, false); + source.addTempSkill("xiecui_effect"); } } }, - subSkill:{ - effect:{ - charlotte:true, - mod:{ - maxHandcard:(player,num)=>num+player.countMark('xiecui_effect'), + subSkill: { + effect: { + charlotte: true, + mod: { + maxHandcard: (player, num) => num + player.countMark("xiecui_effect"), }, - marktext:'翠', - onremove:true, - intro:{content:'手牌上限+#'}, + marktext: "翠", + onremove: true, + intro: { content: "手牌上限+#" }, }, }, - ai:{threaten:1.75}, + ai: { threaten: 1.75 }, }, - youxu:{ - audio:2, - trigger:{global:'phaseEnd'}, - logTarget:'player', - filter:function(event,player){ - return event.player.countCards('h')>event.player.hp; + youxu: { + audio: 2, + trigger: { global: "phaseEnd" }, + logTarget: "player", + filter: function (event, player) { + return event.player.countCards("h") > event.player.hp; }, - check:function(event,player){ - if(get.attitude(player,event.player)<=0) return true; - else return game.hasPlayer(function(current){ - return current!=event.player&¤t.isDamaged()&¤t.isMinHp()&& - get.attitude(player,current)>0&&get.recoverEffect(current,player,player)>0; - }); - }, - content:function(){ - 'step 0' - if(player==trigger.player){ - player.chooseCard('h',true,'请展示一张手牌'); - } - else{ - player.choosePlayerCard(trigger.player,true,'h'); - } - 'step 1' - if(result.bool){ - var card=result.cards[0]; - event.card=card; - var str=get.translation(player); - if(player!=trigger.player) str+=('对'+get.translation(trigger.player)); - str+='发动了【忧恤】'; - player.showCards(card,str); - player.chooseTarget('令一名角色获得'+get.translation(card),'若其体力值为全场最少,则其回复1点体力',function(card,player,target){ - return target!=_status.event.getTrigger().player; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<0) return 0; - if(target.isDamaged()&&target.isMinHp&&get.recoverEffect(target,player,player)>0) return 4*att; - return att; + check: function (event, player) { + if (get.attitude(player, event.player) <= 0) return true; + else + return game.hasPlayer(function (current) { + return ( + current != event.player && + current.isDamaged() && + current.isMinHp() && + get.attitude(player, current) > 0 && + get.recoverEffect(current, player, player) > 0 + ); }); + }, + content: function () { + "step 0"; + if (player == trigger.player) { + player.chooseCard("h", true, "请展示一张手牌"); + } else { + player.choosePlayerCard(trigger.player, true, "h"); } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - target.gain(card,trigger.player,'give').giver=player; - } - else event.finish(); - 'step 3' - if(target.isMinHp()) target.recover(); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + var str = get.translation(player); + if (player != trigger.player) str += "对" + get.translation(trigger.player); + str += "发动了【忧恤】"; + player.showCards(card, str); + player + .chooseTarget( + "令一名角色获得" + get.translation(card), + "若其体力值为全场最少,则其回复1点体力", + function (card, player, target) { + return target != _status.event.getTrigger().player; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att < 0) return 0; + if ( + target.isDamaged() && + target.isMinHp && + get.recoverEffect(target, player, player) > 0 + ) + return 4 * att; + return att; + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + target.gain(card, trigger.player, "give").giver = player; + } else event.finish(); + "step 3"; + if (target.isMinHp()) target.recover(); }, }, //夏侯令女 - fuping:{ - audio:2, - hiddenCard:function(player,name){ - var list=player.getStorage('fuping').slice(0); - list.removeArray(player.getStorage('fuping_round')); - return list.includes(name)&&player.hasCard((card)=>(get.type(card)!='basic'),'ehs'); + fuping: { + audio: 2, + hiddenCard: function (player, name) { + var list = player.getStorage("fuping").slice(0); + list.removeArray(player.getStorage("fuping_round")); + return list.includes(name) && player.hasCard((card) => get.type(card) != "basic", "ehs"); }, - enable:'chooseToUse', - locked:false, - filter:function(event,player){ - var list=player.getStorage('fuping').slice(0); - list.removeArray(player.getStorage('fuping_round')); - if(!list.length) return false; - if(!player.hasCard((card)=>(get.type(card)!='basic'),'ehs')) return false; - for(var i of list){ - var type=get.type2(i,false); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; + enable: "chooseToUse", + locked: false, + filter: function (event, player) { + var list = player.getStorage("fuping").slice(0); + list.removeArray(player.getStorage("fuping_round")); + if (!list.length) return false; + if (!player.hasCard((card) => get.type(card) != "basic", "ehs")) return false; + for (var i of list) { + var type = get.type2(i, false); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=player.getStorage('fuping').slice(0); - list.removeArray(player.getStorage('fuping_round')); - var list2=[]; - for(var i of list){ - var type=get.type2(i,false); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) list2.push([type,'',i]); + chooseButton: { + dialog: function (event, player) { + var list = player.getStorage("fuping").slice(0); + list.removeArray(player.getStorage("fuping_round")); + var list2 = []; + for (var i of list) { + var type = get.type2(i, false); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + list2.push([type, "", i]); } - return ui.create.dialog('浮萍',[list2,'vcard']); + return ui.create.dialog("浮萍", [list2, "vcard"]); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - return _status.event.player.getUseValue({name:button.link[2]},null,true); + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + return _status.event.player.getUseValue({ name: button.link[2] }, null, true); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'fuping', - filterCard:(card)=>get.type(card)!='basic', - position:'he', - popname:true, - viewAs:{ - name:links[0][2], + audio: "fuping", + filterCard: (card) => get.type(card) != "basic", + position: "he", + popname: true, + viewAs: { + name: links[0][2], }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - precontent:function(){ - player.addTempSkill('fuping_round'); - player.markAuto('fuping_round',[event.result.card.name]); + precontent: function () { + player.addTempSkill("fuping_round"); + player.markAuto("fuping_round", [event.result.card.name]); }, - } + }; }, - prompt:function(links,player){ - return '将一张非基本牌当做【'+get.translation(links[0][2])+'】使用'; + prompt: function (links, player) { + return "将一张非基本牌当做【" + get.translation(links[0][2]) + "】使用"; }, }, - ai:{ - order:8, - result:{player:1}, - respondSha:true, - skillTagFilter:function(player){ - var list=player.getStorage('fuping').slice(0); - list.removeArray(player.getStorage('fuping_round')); - return list.includes('sha'); + ai: { + order: 8, + result: { player: 1 }, + respondSha: true, + skillTagFilter: function (player) { + var list = player.getStorage("fuping").slice(0); + list.removeArray(player.getStorage("fuping_round")); + return list.includes("sha"); }, }, - mod:{ - targetInRange:function(card,player,target){ - if(!player.hasEnabledSlot()) return true; + mod: { + targetInRange: function (card, player, target) { + if (!player.hasEnabledSlot()) return true; }, }, - marktext:'萍', - intro:{content:'已记录$'}, - group:'fuping_mark', - subSkill:{ - mark:{ - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return player!=event.player&&event.targets.includes(player)&& - player.hasEnabledSlot()&&!player.getStorage('fuping').includes(event.card.name); + marktext: "萍", + intro: { content: "已记录$" }, + group: "fuping_mark", + subSkill: { + mark: { + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + player != event.player && + event.targets.includes(player) && + player.hasEnabledSlot() && + !player.getStorage("fuping").includes(event.card.name) + ); }, - logTarget:'player', - prompt2:(event)=>('废除一个装备栏并记录【'+get.translation(event.card.name)+'】'), - check:function(event,player){ - var list=['tao','juedou','guohe','shunshou','wuzhong','xietianzi','yuanjiao','wanjian','nanman','huoshaolianying','chuqibuyi','zhujinqiyuan','lebu','bingliang']; - if(!list.includes(event.card.name)) return false; - if(['nanman','wanjian'].includes(event.card.name)&&!player.hasValueTarget({name:event.card.name})) return false; - var list=[3,5,4,1,2]; - for(var i of list){ - if(player.hasEnabledSlot(i)){ - var card=player.getEquip(i); - if(!card||player.hasEmptySlot(i)) return true; - if(get.value(card,player)<=0) return true; + logTarget: "player", + prompt2: (event) => + "废除一个装备栏并记录【" + get.translation(event.card.name) + "】", + check: function (event, player) { + var list = [ + "tao", + "juedou", + "guohe", + "shunshou", + "wuzhong", + "xietianzi", + "yuanjiao", + "wanjian", + "nanman", + "huoshaolianying", + "chuqibuyi", + "zhujinqiyuan", + "lebu", + "bingliang", + ]; + if (!list.includes(event.card.name)) return false; + if ( + ["nanman", "wanjian"].includes(event.card.name) && + !player.hasValueTarget({ name: event.card.name }) + ) + return false; + var list = [3, 5, 4, 1, 2]; + for (var i of list) { + if (player.hasEnabledSlot(i)) { + var card = player.getEquip(i); + if (!card || player.hasEmptySlot(i)) return true; + if (get.value(card, player) <= 0) return true; } } return false; }, - content:function(){ - player.markAuto('fuping',[trigger.card.name]); - game.log(player,'记录了','#y'+get.translation(trigger.card.name)); - player.chooseToDisable().set('ai',function(event,player,list){ - var list=[3,5,4,1,2]; - for(var i of list){ - if(player.hasEnabledSlot(i)){ - var card=player.getEquip(i); - if(!card||player.hasEmptySlot(i)) return 'equip'+i; - if(get.value(card,player)<=0) return 'equip'+i; + content: function () { + player.markAuto("fuping", [trigger.card.name]); + game.log(player, "记录了", "#y" + get.translation(trigger.card.name)); + player.chooseToDisable().set("ai", function (event, player, list) { + var list = [3, 5, 4, 1, 2]; + for (var i of list) { + if (player.hasEnabledSlot(i)) { + var card = player.getEquip(i); + if (!card || player.hasEmptySlot(i)) return "equip" + i; + if (get.value(card, player) <= 0) return "equip" + i; } } return list.randomGet(); }); }, }, - backup:{audio:'fuping'}, - round:{charlotte:true,onremove:true}, + backup: { audio: "fuping" }, + round: { charlotte: true, onremove: true }, }, }, - weilie:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countMark('weilie')<=player.getStorage('fuping').length&&player.countCards('he')>0&&game.hasPlayer((current)=>current.isDamaged()) + weilie: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countMark("weilie") <= player.getStorage("fuping").length && + player.countCards("he") > 0 && + game.hasPlayer((current) => current.isDamaged()) + ); }, - filterCard:true, - position:'he', - filterTarget:(card,player,target)=>target.isDamaged(), - check:function(card){ - return 8-get.value(card); + filterCard: true, + position: "he", + filterTarget: (card, player, target) => target.isDamaged(), + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - 'step 0' - player.addMark('weilie',1,false); + content: function () { + "step 0"; + player.addMark("weilie", 1, false); target.recover(); - 'step 1' - if(target.isDamaged()) target.draw(); + "step 1"; + if (target.isDamaged()) target.draw(); }, - onremove:true, - ai:{ - order:1, - result:{ - player:function(player,target){ - var eff=get.recoverEffect(target,player,player); - if(target.getDamagedHp()>1) eff+=get.effect(target,{name:'draw'},player,player); + onremove: true, + ai: { + order: 1, + result: { + player: function (player, target) { + var eff = get.recoverEffect(target, player, player); + if (target.getDamagedHp() > 1) + eff += get.effect(target, { name: "draw" }, player, player); return eff; }, }, @@ -9056,414 +11350,491 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //张瑶 //Partly powered by 烟雨墨染 - yuanyu:{ - audio:2, - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' + yuanyu: { + audio: 2, + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.countCards('h')>0&&game.hasPlayer(current=>current!=player)){ - var suits=lib.suit.slice(0),cards=player.getExpansions('yuanyu'); - for(var i of cards) suits.remove(get.suit(i,false)); - var str='选择一张手牌,作为“怨”置于武将牌上;同时选择一名其他角色,令该角色获得〖怨语〗的后续效果。' - if(suits.length){ - str+='目前“怨”中未包含的花色:'; - for(var i of suits) str+=get.translation(i); + "step 1"; + if (player.countCards("h") > 0 && game.hasPlayer((current) => current != player)) { + var suits = lib.suit.slice(0), + cards = player.getExpansions("yuanyu"); + for (var i of cards) suits.remove(get.suit(i, false)); + var str = + "选择一张手牌,作为“怨”置于武将牌上;同时选择一名其他角色,令该角色获得〖怨语〗的后续效果。"; + if (suits.length) { + str += "目前“怨”中未包含的花色:"; + for (var i of suits) str += get.translation(i); } player.chooseCardTarget({ - filterCard:true, - filterTarget:lib.filter.notMe, - position:'h', - prompt:'怨语:选择置于武将牌上的牌和目标', - prompt2:str, - suits:suits, - forced:true, - ai1:function(card){ - var val=get.value(card),evt=_status.event; - if(evt.suits.includes(get.suit(card,false))) return 8-get.value(card); - return 5-get.value(card); + filterCard: true, + filterTarget: lib.filter.notMe, + position: "h", + prompt: "怨语:选择置于武将牌上的牌和目标", + prompt2: str, + suits: suits, + forced: true, + ai1: function (card) { + var val = get.value(card), + evt = _status.event; + if (evt.suits.includes(get.suit(card, false))) return 8 - get.value(card); + return 5 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player; - if(player.storage.yuanyu_damage&&player.storage.yuanyu_damage.includes(target)) return 0; - return -get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player; + if ( + player.storage.yuanyu_damage && + player.storage.yuanyu_damage.includes(target) + ) + return 0; + return -get.attitude(player, target); }, }); + } else event.finish(); + "step 2"; + var target = result.targets[0]; + player.addSkill("yuanyu_damage"); + player.markAuto("yuanyu_damage", result.targets); + player.line(target, "green"); + if (!target.storage.yuanyu_mark) { + target.storage.yuanyu_mark = player; + target.markSkillCharacter("yuanyu_mark", player, "怨语", "已获得〖怨语〗效果"); + target.addSkill("yuanyu_mark"); } - else event.finish(); - 'step 2' - var target=result.targets[0]; - player.addSkill('yuanyu_damage'); - player.markAuto('yuanyu_damage',result.targets); - player.line(target,'green'); - if(!target.storage.yuanyu_mark){ - target.storage.yuanyu_mark=player; - target.markSkillCharacter('yuanyu_mark',player,'怨语','已获得〖怨语〗效果'); - target.addSkill('yuanyu_mark'); - } - player.addToExpansion(result.cards,player,'give').gaintag.add('yuanyu'); + player.addToExpansion(result.cards, player, "give").gaintag.add("yuanyu"); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - player.removeSkill('yuanyu_damage'); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + player.removeSkill("yuanyu_damage"); }, - ai:{ - order:7, - result:{ - player:1, + ai: { + order: 7, + result: { + player: 1, }, }, - subSkill:{ - mark:{ - mark:'character', - charlotte:true, - intro:{ - content:'已获得〖怨语〗效果', - onunmark:true, + subSkill: { + mark: { + mark: "character", + charlotte: true, + intro: { + content: "已获得〖怨语〗效果", + onunmark: true, }, }, - damage:{ - trigger:{global:['damageSource','phaseDiscardBegin']}, - forced:true, - charlotte:true, - onremove:function(player,skill){ - if(player.storage[skill]){ - for(var i of player.storage[skill]){ - if(i.storage.yuanyu_mark==player) i.unmarkSkill('yuanyu_mark'); + damage: { + trigger: { global: ["damageSource", "phaseDiscardBegin"] }, + forced: true, + charlotte: true, + onremove: function (player, skill) { + if (player.storage[skill]) { + for (var i of player.storage[skill]) { + if (i.storage.yuanyu_mark == player) i.unmarkSkill("yuanyu_mark"); } } delete player.storage[skill]; }, - filter:function(event,player){ - if(event.name=='damage'){ - var source=event.source; - return source&&player.getStorage('yuanyu_damage').includes(source)&&source.countCards('h')>0; - } - else{ - if(player==event.player){ - return player.getStorage('yuanyu_damage').some(function(target){ - return target.isIn()&&target.countCards('h')>0; + filter: function (event, player) { + if (event.name == "damage") { + var source = event.source; + return ( + source && + player.getStorage("yuanyu_damage").includes(source) && + source.countCards("h") > 0 + ); + } else { + if (player == event.player) { + return player.getStorage("yuanyu_damage").some(function (target) { + return target.isIn() && target.countCards("h") > 0; }); - } - else if(player.getStorage('yuanyu_damage').includes(event.player)){ - return event.player.countCards('h')>0; + } else if (player.getStorage("yuanyu_damage").includes(event.player)) { + return event.player.countCards("h") > 0; } return false; } }, - content:function(){ - 'step 0' - if(trigger.name=='phaseDiscard'){ - if(trigger.player==player){ - event.targets=player.getStorage('yuanyu_damage').filter(function(target){ - return target.isIn()&&target.countCards('h')>0; - }).sortBySeat(); - } - else event.targets=[trigger.player]; - } - else event.targets=[trigger.source]; - 'step 1' - event.target=event.targets.shift(); - event.count=trigger.name=='damage'?trigger.num:1; - 'step 2' + content: function () { + "step 0"; + if (trigger.name == "phaseDiscard") { + if (trigger.player == player) { + event.targets = player + .getStorage("yuanyu_damage") + .filter(function (target) { + return target.isIn() && target.countCards("h") > 0; + }) + .sortBySeat(); + } else event.targets = [trigger.player]; + } else event.targets = [trigger.source]; + "step 1"; + event.target = event.targets.shift(); + event.count = trigger.name == "damage" ? trigger.num : 1; + "step 2"; event.count--; - var suits=lib.suit.slice(0),cards=player.getExpansions('yuanyu'); - for(var i of cards) suits.remove(get.suit(i,false)); - var next=target.chooseCard('h',true,'将一张手牌置于'+get.translation(player)+'的武将牌上'); - next.set('suits',suits); - next.set('ai',function(card){ - var val=get.value(card),evt=_status.event; - if(evt.suits.includes(get.suit(card,false))) return 5-get.value(card); - return 8-get.value(card); + var suits = lib.suit.slice(0), + cards = player.getExpansions("yuanyu"); + for (var i of cards) suits.remove(get.suit(i, false)); + var next = target.chooseCard( + "h", + true, + "将一张手牌置于" + get.translation(player) + "的武将牌上" + ); + next.set("suits", suits); + next.set("ai", function (card) { + var val = get.value(card), + evt = _status.event; + if (evt.suits.includes(get.suit(card, false))) return 5 - get.value(card); + return 8 - get.value(card); }); - if(suits.length){ - var str='目前未包含的花色:'; - for(var i of suits) str+=get.translation(i); - next.set('prompt2',str); + if (suits.length) { + var str = "目前未包含的花色:"; + for (var i of suits) str += get.translation(i); + next.set("prompt2", str); } - 'step 3' - player.addToExpansion(result.cards,target,'give').gaintag.add('yuanyu'); - 'step 4' - if(!player.hasSkill('yuanyu_damage')) event.finish(); - else if(event.count>0&&target.countCards('h')>0) event.goto(2); - else if(event.targets.length>0) event.goto(1); + "step 3"; + player.addToExpansion(result.cards, target, "give").gaintag.add("yuanyu"); + "step 4"; + if (!player.hasSkill("yuanyu_damage")) event.finish(); + else if (event.count > 0 && target.countCards("h") > 0) event.goto(2); + else if (event.targets.length > 0) event.goto(1); }, }, }, }, - xiyan:{ - audio:2, - trigger:{player:'addToExpansionAfter'}, - filter:function(event,player){ - if(!event.gaintag.includes('yuanyu')) return false; - var cards=player.getExpansions('yuanyu'); - if(cards.length_status.currentPhase, - prompt2:'获得所有“怨”', - check:()=>true, - content:function(){ - 'step 0' - player.removeSkill('yuanyu_damage'); - var cards=player.getExpansions('yuanyu'); - player.gain(cards,'gain2'); - 'step 1' - var target=_status.currentPhase; - if(player==target){ - player.addMark('xiyan_buff',4,false); - player.addTempSkill('xiyan_buff'); - delete player.getStat('skill').yuanyu; + logTarget: () => _status.currentPhase, + prompt2: "获得所有“怨”", + check: () => true, + content: function () { + "step 0"; + player.removeSkill("yuanyu_damage"); + var cards = player.getExpansions("yuanyu"); + player.gain(cards, "gain2"); + "step 1"; + var target = _status.currentPhase; + if (player == target) { + player.addMark("xiyan_buff", 4, false); + player.addTempSkill("xiyan_buff"); + delete player.getStat("skill").yuanyu; event.finish(); + } else { + player + .chooseBool( + "夕颜:是否令" + + get.translation(target) + + "本回合的手牌上限-4且不能使用基本牌?" + ) + .set("ai", function () { + return _status.event.bool; + }) + .set("bool", get.attitude(player, target) < 0); } - else{ - player.chooseBool('夕颜:是否令'+get.translation(target)+'本回合的手牌上限-4且不能使用基本牌?').set('ai',function(){ - return _status.event.bool; - }).set('bool',get.attitude(player,target)<0); - } - 'step 2' - if(result.bool){ - var target=_status.currentPhase; - target.addMark('xiyan_debuff',4,false); - target.addTempSkill('xiyan_debuff'); + "step 2"; + if (result.bool) { + var target = _status.currentPhase; + target.addMark("xiyan_debuff", 4, false); + target.addTempSkill("xiyan_debuff"); } }, - subSkill:{ - buff:{ - charlotte:true, - mark:true, - marktext:" + ", - intro:{ - content:"本回合手牌上限+#且使用牌无次数限制", + subSkill: { + buff: { + charlotte: true, + mark: true, + marktext: " + ", + intro: { + content: "本回合手牌上限+#且使用牌无次数限制", }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('xiyan_buff'); + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("xiyan_buff"); }, - cardUsable:function(card,player){ + cardUsable: function (card, player) { return Infinity; }, }, - sub:true, + sub: true, }, - debuff:{ - charlotte:true, - mark:true, - marktext:" - ", - intro:{ - content:"本回合手牌上限-#且不能使用基本牌", + debuff: { + charlotte: true, + mark: true, + marktext: " - ", + intro: { + content: "本回合手牌上限-#且不能使用基本牌", }, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('xiyan_debuff'); + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("xiyan_debuff"); }, - cardEnabled:function(card){ - if(get.type(card)=='basic') return false; + cardEnabled: function (card) { + if (get.type(card) == "basic") return false; }, - cardSavable:function(card){ - if(get.type(card)=='basic') return false; + cardSavable: function (card) { + if (get.type(card) == "basic") return false; }, }, - sub:true, + sub: true, }, }, + ai: { + combo: "yuanyu", + }, }, //滕胤 - chenjian:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - prompt2:function(event,player){ - return '展示牌堆顶的'+get.cnNumber(3+player.countMark('chenjian'))+'张牌,然后执行以下一至两项:⒈弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌。⒉使用其中剩余的一张牌。若你执行了所有选项,则你获得一枚“陈见”并重铸所有手牌'; + chenjian: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + prompt2: function (event, player) { + return ( + "亮出牌堆顶的" + + get.cnNumber(3 + player.countMark("chenjian")) + + "张牌,然后执行以下一至两项:⒈弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌。⒉使用其中剩余的一张牌。若你执行了所有选项,则你获得一枚“陈见”并重铸所有手牌" + ); }, - content:function(){ - 'step 0' - var cards=get.cards(3+player.countMark('chenjian')); - event.cards=cards; - player.showCards(cards,get.translation(player)+'发动了【陈见】'); - 'step 1' - var list=[]; - if(player.countCards('he',i=>{ - return lib.filter.cardDiscardable(i,player,'chenjian'); - })) list.push('选项一'); - if(event.cards.some(i=>{ - return player.hasUseTarget(i); - })) list.push('选项二'); - if(list.length===1) event._result={control:list[0]}; - else if(list.length>1) player.chooseControl(list).set('choiceList',[ - '弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌', - '使用'+get.translation(event.cards)+'中的一张牌' - ]).set('prompt','陈见:请选择一项').set('ai',()=>{ - let player=_status.event.player,cards=_status.event.getParent().cards; - if(cards.some(i=>{ - return player.getUseValue(i)>0; - })) return '选项二'; - return '选项一'; - }); - else event.finish(); - 'step 2' - event.goon=0; - event.choosed=result.control; - if(result.control==='cancel2') event.finish(); - else if(result.control==='选项二') event.goto(6); - 'step 3' - if(player.countCards('he',i=>{ - return lib.filter.cardDiscardable(i,player,'chenjian'); - })) player.chooseToDiscard('he',!event.goon).set('ai',function(card){ - let evt=_status.event.getParent(), - val=event.goon&&evt.player.countMark('chenjian')<2?0:-get.value(card), - suit=get.suit(card); - for(let i of evt.cards){ - if(get.suit(i,false)==suit) val+=get.value(i,'raw'); - } - return val; - }).set('prompt','陈见:'+(event.goon?'是否':'请')+'弃置一张牌,然后令一名角色获得'+get.translation(event.cards)+'中花色与之相同的牌'+(event.goon?'?':'')); - else if(event.choosed==='选项一') event.goto(6); - else event.finish(); - 'step 4' - if(result.bool){ - event.goon++; - var suit=get.suit(result.cards[0],player); - var cards2=event.cards.filter(function(i){ - return get.suit(i,false)==suit; - }); - if(cards2.length){ - event.cards2=cards2; - player.chooseTarget(true,'选择一名角色获得'+get.translation(cards2)).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0){ - return att+Math.max(0,5-target.countCards('h')); - } - return att; + content: function () { + "step 0"; + var cards = get.cards(3 + player.countMark("chenjian")); + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【陈见】"); + "step 1"; + var list = []; + if ( + player.countCards("he", (i) => { + return lib.filter.cardDiscardable(i, player, "chenjian"); + }) + ) + list.push("选项一"); + if ( + event.cards.some((i) => { + return player.hasUseTarget(i); + }) + ) + list.push("选项二"); + if (list.length === 1) event._result = { control: list[0] }; + else if (list.length > 1) + player + .chooseControl(list) + .set("choiceList", [ + "弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌", + "使用" + get.translation(event.cards) + "中的一张牌", + ]) + .set("prompt", "陈见:请选择一项") + .set("ai", () => { + let player = _status.event.player, + cards = _status.event.getParent().cards; + if ( + cards.some((i) => { + return player.getUseValue(i) > 0; + }) + ) + return "选项二"; + return "选项一"; }); - } - else if(event.choosed==='选项一') event.goto(6); - else event.goto(8); - } else event.finish(); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(event.cards2,'gain2'); + "step 2"; + event.goon = 0; + event.choosed = result.control; + if (result.control === "cancel2") event.finish(); + else if (result.control === "选项二") event.goto(6); + "step 3"; + if ( + player.countCards("he", (i) => { + return lib.filter.cardDiscardable(i, player, "chenjian"); + }) + ) + player + .chooseToDiscard("he", !event.goon) + .set("ai", function (card) { + let evt = _status.event.getParent(), + val = + event.goon && evt.player.countMark("chenjian") < 2 + ? 0 + : -get.value(card), + suit = get.suit(card); + for (let i of evt.cards) { + if (get.suit(i, false) == suit) val += get.value(i, "raw"); + } + return val; + }) + .set( + "prompt", + "陈见:" + + (event.goon ? "是否" : "请") + + "弃置一张牌,然后令一名角色获得" + + get.translation(event.cards) + + "中花色与之相同的牌" + + (event.goon ? "?" : "") + ); + else if (event.choosed === "选项一") event.goto(6); + else event.finish(); + "step 4"; + if (result.bool) { + event.goon++; + var suit = get.suit(result.cards[0], player); + var cards2 = event.cards.filter(function (i) { + return get.suit(i, false) == suit; + }); + if (cards2.length) { + event.cards2 = cards2; + player + .chooseTarget(true, "选择一名角色获得" + get.translation(cards2)) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) { + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }); + } else if (event.choosed === "选项一") event.goto(6); + else event.goto(8); + } else event.finish(); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(event.cards2, "gain2"); event.cards.removeArray(event.cards2); } - if(event.choosed==='选项二') event.goto(8); - 'step 6' - var cards2=cards.filter(function(i){ + if (event.choosed === "选项二") event.goto(8); + "step 6"; + var cards2 = cards.filter(function (i) { return player.hasUseTarget(i); }); - if(cards2.length) player.chooseButton(['陈见:'+(event.goon?'是否':'请')+'使用其中一张牌'+(event.goon?'?':''),cards2],!event.goon).set('ai',function(button){ - return player.getUseValue(button.link); - }); - else if(event.choosed==='选项二') event.goto(3); + if (cards2.length) + player + .chooseButton( + [ + "陈见:" + + (event.goon ? "是否" : "请") + + "使用其中一张牌" + + (event.goon ? "?" : ""), + cards2, + ], + !event.goon + ) + .set("ai", function (button) { + return player.getUseValue(button.link); + }); + else if (event.choosed === "选项二") event.goto(3); else event.finish(); - 'step 7' - if(result.bool){ - player.chooseUseTarget(true,result.links[0],false); + "step 7"; + if (result.bool) { + player.chooseUseTarget(true, result.links[0], false); event.cards.removeArray(result.links); - event.goon+=2; - if(event.choosed==='选项二') event.goto(3); - } - else event.finish(); - 'step 8' - if(event.goon>2){ - if(player.countMark('chenjian')<2) player.addMark('chenjian',1,false); - player.recast(player.getCards('h',lib.filter.cardRecastable)); + event.goon += 2; + if (event.choosed === "选项二") event.goto(3); + } else event.finish(); + "step 8"; + if (event.goon > 2) { + if (player.countMark("chenjian") < 2) player.addMark("chenjian", 1, false); + player.recast(player.getCards("h", lib.filter.cardRecastable)); } }, - marktext:'见', - intro:{content:'展示牌数量+#'}, + marktext: "见", + intro: { content: "展示牌数量+#" }, }, - xixiu:{ - mod:{ - canBeDiscarded:function(card,player,target){ - if(player!=target&&get.position(card)=='e'&&target.countCards('e')==1) return false; + xixiu: { + mod: { + canBeDiscarded: function (card, player, target) { + if (player != target && get.position(card) == "e" && target.countCards("e") == 1) + return false; }, }, - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - if(player==event.player||!player.countCards('e')) return false; - var suit=get.suit(event.card,false); - if(suit=='none') return false; - return player.hasCard(function(card){ - return get.suit(card,player)==suit; - },'e'); + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + if (player == event.player || !player.countCards("e")) return false; + var suit = get.suit(event.card, false); + if (suit == "none") return false; + return player.hasCard(function (card) { + return get.suit(card, player) == suit; + }, "e"); }, - content:function(){ + content: function () { player.draw(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(typeof card=='object'&&player!=target){ - var suit=get.suit(card); - if(suit=='none') return; - if(player.hasCard(function(card){ - return get.suit(card,player)==suit; - },'e')) return [1,0.08]; + ai: { + effect: { + target: function (card, player, target) { + if (typeof card == "object" && player != target) { + var suit = get.suit(card); + if (suit == "none") return; + if ( + player.hasCard(function (card) { + return get.suit(card, player) == suit; + }, "e") + ) + return [1, 0.08]; } }, }, }, }, //张嫙 - tongli:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget||(event.card.storage&&event.card.storage.tongli)) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var num1=player.getHistory('useCard',function(evtx){ - if(evtx.getParent('phaseUse')!=evt) return false; - return !evtx.card.storage||!evtx.card.storage.tongli; + tongli: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget || (event.card.storage && event.card.storage.tongli)) + return false; + var type = get.type(event.card); + if (type != "basic" && type != "trick") return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var num1 = player.getHistory("useCard", function (evtx) { + if (evtx.getParent("phaseUse") != evt) return false; + return !evtx.card.storage || !evtx.card.storage.tongli; }).length; - if(hs.length (att>-2?1.6:1)) return 'cancel2'; - } - let list = lib.suit.slice(0); - if(att <= 0 && target.getStorage('huguan_add')) for(let i of target.getStorage('huguan_add')){ - if (list.includes(i)) return i; - } - list.removeArray(target.getStorage('huguan_add')); - if(list.length) return list.randomGet(); - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.player; - player.logSkill('huguan',target); - game.log(player,'选择了','#g'+get.translation(result.control),'花色') - target.addTempSkill('huguan_add'); - target.markAuto('huguan_add',[result.control]); + content: function () { + "step 0"; + player + .chooseControl(lib.suit, "cancel2") + .set("prompt", get.prompt("huguan", trigger.player)) + .set("prompt2", "令某种花色的手牌不计入其本回合的手牌上限") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player, + att = get.attitude(player, target); + if (att <= 0) { + if ( + !player.hasSkill("yaopei") || + player.hasHistory("useSkill", function (evt) { + return evt.skill == "huguan" && evt.targets.includes(target); + }) || + target.needsToDiscard() - + target.needsToDiscard(-target.countCards("h") / 4) > + (att > -2 ? 1.6 : 1) + ) + return "cancel2"; + } + let list = lib.suit.slice(0); + if (att <= 0 && target.getStorage("huguan_add")) + for (let i of target.getStorage("huguan_add")) { + if (list.includes(i)) return i; + } + list.removeArray(target.getStorage("huguan_add")); + if (list.length) return list.randomGet(); + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.player; + player.logSkill("huguan", target); + game.log(player, "选择了", "#g" + get.translation(result.control), "花色"); + target.addTempSkill("huguan_add"); + target.markAuto("huguan_add", [result.control]); } }, - subSkill:{ - add:{ - charlotte:true, - onremove:true, - mod:{ - ignoredHandcard:function(card,player){ - if(player.getStorage('huguan_add').includes(get.suit(card,player))) return true; + subSkill: { + add: { + charlotte: true, + onremove: true, + mod: { + ignoredHandcard: function (card, player) { + if (player.getStorage("huguan_add").includes(get.suit(card, player))) + return true; + }, + cardDiscardable: function (card, player, name) { + if ( + name == "phaseDiscard" && + player.getStorage("huguan_add").includes(get.suit(card, player)) + ) + return false; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&player.getStorage('huguan_add').includes(get.suit(card,player))) return false; - } }, - intro:{content:'本回合$花色的牌不计入手牌上限'}, + intro: { content: "本回合$花色的牌不计入手牌上限" }, }, - all:{ - mod:{ - aiValue:function(player, card, num){ - if(player && player.storage.huguan_all > 0 && get.itemtype(card) == 'card' && get.color(card, player) == 'red') return num + player.storage.huguan_all; - } + all: { + mod: { + aiValue: function (player, card, num) { + if ( + player && + player.storage.huguan_all > 0 && + get.itemtype(card) == "card" && + get.color(card, player) == "red" + ) + return num + player.storage.huguan_all; + }, }, - trigger:{ - player:['phaseUseBegin', 'useCard'] + trigger: { + player: ["phaseUseBegin", "useCard"], }, - filter:function(event, player){ - if(event.name === 'useCard') return player.storage.huguan_all; + filter: function (event, player) { + if (event.name === "useCard") return player.storage.huguan_all; return true; }, - silent:true, - charlotte:true, - content:function(){ - 'step 0' - if(trigger.name === 'useCard'){ + silent: true, + charlotte: true, + content: function () { + "step 0"; + if (trigger.name === "useCard") { player.storage.huguan_all = 0; event.finish(); } - 'step 1' + "step 1"; let num = -157; - game.countPlayer(function (current){ - if(current.hasSkill('huguan')) num = Math.max(num, get.attitude(_status.event.player, current)); + game.countPlayer(function (current) { + if (current.hasSkill("huguan")) + num = Math.max(num, get.attitude(_status.event.player, current)); }, true); - if(num === -157) game.removeGlobalSkill('huguan_all'); - else if(num === 0) player.storage.huguan_all = 6; - else if(num > 0) player.storage.huguan_all = 9; - } - } + if (num === -157) game.removeGlobalSkill("huguan_all"); + else if (num === 0) player.storage.huguan_all = 6; + else if (num > 0) player.storage.huguan_all = 9; + }, + }, }, }, - yaopei:{ - audio:2, - trigger:{global:'phaseDiscardEnd'}, - direct:true, - filter:function(event,player){ - if(player==event.player||!event.player.isIn()) return false; - if(!player.hasAllHistory('useSkill',function(evt){ - return evt.skill=='huguan'&&evt.targets.includes(event.player); - })) return false; - var suits=[]; - event.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event){ - for(var i of evt.cards2) suits.add(get.suit(i,evt.hs.includes(i)?evt.player:false)); + yaopei: { + audio: 2, + trigger: { global: "phaseDiscardEnd" }, + direct: true, + filter: function (event, player) { + if (player == event.player || !event.player.isIn()) return false; + if ( + !player.hasAllHistory("useSkill", function (evt) { + return evt.skill == "huguan" && evt.targets.includes(event.player); + }) + ) + return false; + var suits = []; + event.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) { + for (var i of evt.cards2) + suits.add(get.suit(i, evt.hs.includes(i) ? evt.player : false)); } }); - if(suits.length>=lib.suit.length) return false; - if(_status.connectMode&&player.countCards('h')>0) return true; - return player.hasCard(function(card){ + if (suits.length >= lib.suit.length) return false; + if (_status.connectMode && player.countCards("h") > 0) return true; + return player.hasCard(function (card) { return !suits.includes(get.suit(card)); - },'he'); + }, "he"); }, - content:function(){ - 'step 0' - var suits=[]; - trigger.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger){ - for(var i of evt.cards2) suits.add(get.suit(i,evt.hs.includes(i)?evt.player:false)); + content: function () { + "step 0"; + var suits = []; + trigger.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) { + for (var i of evt.cards2) + suits.add(get.suit(i, evt.hs.includes(i) ? evt.player : false)); } }); player.chooseCardTarget({ - prompt:get.prompt('yaopei',trigger.player), - prompt2:'操作提示:选择要弃置的牌,并选择执行摸牌选项的角色,另一名角色执行回复体力的选项。', - suits:suits, - position:'he', - filterCard:function(card,player){ - return !_status.event.suits.includes(get.suit(card))&&lib.filter.cardDiscardable(card,player,'yaopei'); + prompt: get.prompt("yaopei", trigger.player), + prompt2: + "操作提示:选择要弃置的牌,并选择执行摸牌选项的角色,另一名角色执行回复体力的选项。", + suits: suits, + position: "he", + filterCard: function (card, player) { + return ( + !_status.event.suits.includes(get.suit(card)) && + lib.filter.cardDiscardable(card, player, "yaopei") + ); }, - filterTarget:function(card,player,target){ - return target==player||target==_status.event.getTrigger().player; + filterTarget: function (card, player, target) { + return target == player || target == _status.event.getTrigger().player; }, - ai1:function(card){ - let player = _status.event.player, source = _status.event.getTrigger().player; - if(get.attitude(player, source) > 0 && (get.recoverEffect(player, player, player) > 0 || get.recoverEffect(source, player, player) > 0)) return 12 - get.value(card); + ai1: function (card) { + let player = _status.event.player, + source = _status.event.getTrigger().player; + if ( + get.attitude(player, source) > 0 && + (get.recoverEffect(player, player, player) > 0 || + get.recoverEffect(source, player, player) > 0) + ) + return 12 - get.value(card); return 8 - get.value(card); }, - ai2:function(target){ - let player = _status.event.player, source = _status.event.getTrigger().player; + ai2: function (target) { + let player = _status.event.player, + source = _status.event.getTrigger().player; let recoverer = player === target ? source : player; - if(recoverer.isHealthy()) return get.attitude(player, target); - let att = get.attitude(player, recoverer), rec = get.recoverEffect(recoverer, player, player); - if(rec > 0) return Math.abs(att) + get.attitude(player, target); + if (recoverer.isHealthy()) return get.attitude(player, target); + let att = get.attitude(player, recoverer), + rec = get.recoverEffect(recoverer, player, player); + if (rec > 0) return Math.abs(att) + get.attitude(player, target); return 0; - } + }, }); - 'step 1' - if(result.bool){ - var target=trigger.player; - player.logSkill('yaopei',target); + "step 1"; + if (result.bool) { + var target = trigger.player; + player.logSkill("yaopei", target); player.discard(result.cards); - if(player==result.targets[0]){ - if(target.isDamaged()&&target.hptarget.hp)&&(get.mode()!='identity'||player.identity!='nei')) player.addExpose(0.15); + } else { + if ( + (player.isHealthy() || player.hp > target.hp) && + (get.mode() != "identity" || player.identity != "nei") + ) + player.addExpose(0.15); target.draw(2); player.recover(); } } }, - }, - mingluan:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&player.hasSkill('mingluan_mark')&&player.countCards('he')>0; + ai: { + combo: "huguan" }, - content:function(){ - 'step 0' - let he = player.getCards('he'), + }, + mingluan: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.isIn() && + player.hasSkill("mingluan_mark") && + player.countCards("he") > 0 + ); + }, + content: function () { + "step 0"; + let he = player.getCards("he"), disval = 0, dis = 0, spare = 30, use = true; - for(let i of he){ + for (let i of he) { let val = get.value(i, player); - if(val < 6 && get.position(i) == 'h'){ + if (val < 6 && get.position(i) == "h") { dis++; disval += val; - } - else if(val < spare) spare = val; + } else if (val < spare) spare = val; } - if(!dis){ + if (!dis) { dis = 1; disval = spare; spare = -1; } - let draw = Math.min(trigger.player.countCards('h'), 5 + dis - player.countCards('h')); - if(6 * draw < disval) use = false; - player.chooseToDiscard('he',get.prompt('mingluan'),'弃置任意张牌,并摸等同于'+get.translation(trigger.player)+'手牌数的牌(至多摸至五张)',[1,Infinity]).set('ai',function(card){ - let val = get.value(card, player); - if(val < 0 && card.name !== 'du') return 30; - if(!_status.event.use) return 0; - if(ui.selected.cards.length){ - if (get.position(card) !== 'h') return 0; - return 6 - val; - } - if(_status.event.spare < 0 || get.position(card) === 'h') return 30 - val; - return 0; - }).set('spare',spare).set('use',use).logSkill=['mingluan',trigger.player]; - 'step 1' - if(result.bool){ - var num=trigger.player.countCards('h'),num2=5-player.countCards('h'); - if(num>0&&num2>0) player.draw(Math.min(num,num2)); + let draw = Math.min(trigger.player.countCards("h"), 5 + dis - player.countCards("h")); + if (6 * draw < disval) use = false; + player + .chooseToDiscard( + "he", + get.prompt("mingluan"), + "弃置任意张牌,并摸等同于" + + get.translation(trigger.player) + + "手牌数的牌(至多摸至五张)", + [1, Infinity] + ) + .set("ai", function (card) { + let val = get.value(card, player); + if (val < 0 && card.name !== "du") return 30; + if (!_status.event.use) return 0; + if (ui.selected.cards.length) { + if (get.position(card) !== "h") return 0; + return 6 - val; + } + if (_status.event.spare < 0 || get.position(card) === "h") return 30 - val; + return 0; + }) + .set("spare", spare) + .set("use", use).logSkill = ["mingluan", trigger.player]; + "step 1"; + if (result.bool) { + var num = trigger.player.countCards("h"), + num2 = 5 - player.countCards("h"); + if (num > 0 && num2 > 0) player.draw(Math.min(num, num2)); } }, - group:'mingluan_count', - subSkill:{ - count:{ - charlotte:true, - trigger:{global:'recoverEnd'}, - silent:true, - popup:false, - firstDo:true, - filter:function(event,player){ - var current=_status.currentPhase; - return current&¤t!=player&&!player.hasSkill('mingluan_mark'); + group: "mingluan_count", + subSkill: { + count: { + charlotte: true, + trigger: { global: "recoverEnd" }, + silent: true, + popup: false, + firstDo: true, + filter: function (event, player) { + var current = _status.currentPhase; + return current && current != player && !player.hasSkill("mingluan_mark"); }, - content:function(){ - player.addTempSkill('mingluan_mark'); + content: function () { + player.addTempSkill("mingluan_mark"); }, }, - mark:{ - charlotte:true, + mark: { + charlotte: true, }, }, }, //赵嫣 - jinhui:{ - audio:2, - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' - var cards=[]; - while(cards.length<3){ - var card=get.cardPile2(function(card){ - for(var i of cards){ - if(i.name==card.name) return false; + jinhui: { + audio: 2, + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + var cards = []; + while (cards.length < 3) { + var card = get.cardPile2(function (card) { + for (var i of cards) { + if (i.name == card.name) return false; } - var info=get.info(card,false); - if(info.ai&&info.ai.tag&&info.ai.tag.damage) return false; - return !info.notarget&&(info.toself||info.singleCard||!info.selectTarget||info.selectTarget==1); + var info = get.info(card, false); + if (info.ai && info.ai.tag && info.ai.tag.damage) return false; + return ( + !info.notarget && + (info.toself || + info.singleCard || + !info.selectTarget || + info.selectTarget == 1) + ); }); - if(card) cards.push(card); + if (card) cards.push(card); else break; } - if(!cards.length) event.finish(); - else{ - player.showCards(cards,get.translation(player)+'发动了【锦绘】'); - event.cards=cards; + if (!cards.length) event.finish(); + else { + player.showCards(cards, get.translation(player) + "发动了【锦绘】"); + event.cards = cards; game.cardsGotoOrdering(cards); - if(game.hasPlayer((current)=>(current!=player))) player.chooseTarget('选择【锦绘】的目标',true,lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,cards=_status.event.getParent().cards.slice(0); - var max_effect=0,max_effect_player=0; - for(var i of cards){ - var targetx=lib.skill.jinhui.getUsableTarget(i,target,player); - if(targetx){ - var effect2=get.effect(targetx,i,target,target); - var effect3=get.effect(targetx,i,target,player); - if(effect2>max_effect){ - max_effect=effect2; - max_effect_player=effect3; + if (game.hasPlayer((current) => current != player)) + player + .chooseTarget("选择【锦绘】的目标", true, lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player, + cards = _status.event.getParent().cards.slice(0); + var max_effect = 0, + max_effect_player = 0; + for (var i of cards) { + var targetx = lib.skill.jinhui.getUsableTarget(i, target, player); + if (targetx) { + var effect2 = get.effect(targetx, i, target, target); + var effect3 = get.effect(targetx, i, target, player); + if (effect2 > max_effect) { + max_effect = effect2; + max_effect_player = effect3; + } + } } - } - } - return max_effect_player; - }); + return max_effect_player; + }); else event.finish(); } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var cards=cards.filter(function(card){ - return lib.skill.jinhui.getUsableTarget(card,target,player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var cards = cards.filter(function (card) { + return lib.skill.jinhui.getUsableTarget(card, target, player); }); - if(cards.length){ - if(cards.length==1) event._result={bool:true,links:cards}; - else target.chooseButton(['选择按“锦绘”规则使用一张牌',cards],true).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().player,card=button.link; - var targetx=lib.skill.jinhui.getUsableTarget(card,player,target); - var effect=get.effect(targetx,card,player,player),cards=_status.event.getParent().cards.slice(0); - var effect2=0,effect3=0; - cards.remove(button.link); - for(var i of cards){ - var targetx=lib.skill.jinhui.getUsableTarget(i,target,player); - if(targetx){ - effect2+=get.effect(targetx,i,target,target); - effect3+=get.effect(targetx,i,target,player); - } - } - if(effect2>0) effect+=effect3; - return effect; - }); - } - else event.goto(3); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.links[0]; + if (cards.length) { + if (cards.length == 1) event._result = { bool: true, links: cards }; + else + target + .chooseButton(["选择按“锦绘”规则使用一张牌", cards], true) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().player, + card = button.link; + var targetx = lib.skill.jinhui.getUsableTarget(card, player, target); + var effect = get.effect(targetx, card, player, player), + cards = _status.event.getParent().cards.slice(0); + var effect2 = 0, + effect3 = 0; + cards.remove(button.link); + for (var i of cards) { + var targetx = lib.skill.jinhui.getUsableTarget(i, target, player); + if (targetx) { + effect2 += get.effect(targetx, i, target, target); + effect3 += get.effect(targetx, i, target, player); + } + } + if (effect2 > 0) effect += effect3; + return effect; + }); + } else event.goto(3); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.links[0]; event.cards.remove(card); - var targetx=lib.skill.jinhui.getUsableTarget(card,target,player); - target.useCard(card,targetx,false,'noai'); + var targetx = lib.skill.jinhui.getUsableTarget(card, target, player); + target.useCard(card, targetx, false, "noai"); } - 'step 3' - var cards=cards.filter(function(card){ - return lib.skill.jinhui.getUsableTarget(card,player,target); + "step 3"; + var cards = cards.filter(function (card) { + return lib.skill.jinhui.getUsableTarget(card, player, target); }); - if(cards.length){ - player.chooseButton(['是否按“锦绘”规则使用其中一张牌?',cards]).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().target; - var card=button.link,targetx=lib.skill.jinhui.getUsableTarget(card,player,target); - return get.effect(targetx,card,player,player) - }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var card=result.links[0]; + if (cards.length) { + player + .chooseButton(["是否按“锦绘”规则使用其中一张牌?", cards]) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target; + var card = button.link, + targetx = lib.skill.jinhui.getUsableTarget(card, player, target); + return get.effect(targetx, card, player, player); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var card = result.links[0]; cards.remove(card); - var targetx=lib.skill.jinhui.getUsableTarget(card,player,target); - if(targetx){ - player.useCard(card,targetx,false,'noai'); + var targetx = lib.skill.jinhui.getUsableTarget(card, player, target); + if (targetx) { + player.useCard(card, targetx, false, "noai"); } - if(cards.length) event.goto(3); - } - else event.finish(); + if (cards.length) event.goto(3); + } else event.finish(); }, - getUsableTarget:function(card,player,target){ - var info=get.info(card,false); - if(info.toself) return player.canUse(card,player,false)?player:false; - return (target.isIn()&&player.canUse(card,target,false))?target:false; + getUsableTarget: function (card, player, target) { + var info = get.info(card, false); + if (info.toself) return player.canUse(card, player, false) ? player : false; + return target.isIn() && player.canUse(card, target, false) ? target : false; }, - ai:{ - order:5, - result:{player:1}, + ai: { + order: 5, + result: { player: 1 }, }, }, - qingman:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - if(!event.player.isIn()) return false; - var num=player.countCards('h'); - if(num>=5) return false; - var num2=0; - for(var i=1;i<=5;i++){ - num2+=event.player.countEmptySlot(i); + qingman: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + if (!event.player.isIn()) return false; + var num = player.countCards("h"); + if (num >= 5) return false; + var num2 = 0; + for (var i = 1; i <= 5; i++) { + num2 += event.player.countEmptySlot(i); } - return num0){ - event.num=Math.ceil(th/2); - var list=[ - '本回合不能使用手牌,然后'+str+'摸两张牌', - '展示所有手牌,并将其中一种花色的所有牌交给'+str, - '弃置'+get.cnNumber(event.num)+'张手牌', + content: function () { + "step 0"; + var target = trigger.source, + str = get.translation(player); + event.target = target; + var th = target.countCards("h"); + if (th > 0) { + event.num = Math.ceil(th / 2); + var list = [ + "本回合不能使用手牌,然后" + str + "摸两张牌", + "展示所有手牌,并将其中一种花色的所有牌交给" + str, + "弃置" + get.cnNumber(event.num) + "张手牌", ]; - target.chooseControl().set('choiceList',list).set('ai',function(){ - return get.rand(0,2); - }); - } - else event._result={index:0}; - 'step 1' - switch(result.index){ + target + .chooseControl() + .set("choiceList", list) + .set("ai", function () { + return get.rand(0, 2); + }); + } else event._result = { index: 0 }; + "step 1"; + switch (result.index) { case 0: - target.addTempSkill('yachai_block'); + target.addTempSkill("yachai_block"); player.draw(2); event.finish(); break; - case 1:target.showHandcards();break; - case 2:event.goto(4);break; + case 1: + target.showHandcards(); + break; + case 2: + event.goto(4); + break; } - 'step 2' - var map={},hs=target.getCards('h'); - for(var i of hs){ - map[get.suit(i,target)]=true; + "step 2"; + var map = {}, + hs = target.getCards("h"); + for (var i of hs) { + map[get.suit(i, target)] = true; } - var list=[]; - for(var i of lib.suit){ - if(map[i]) list.push(i); + var list = []; + for (var i of lib.suit) { + if (map[i]) list.push(i); } - if(!list.length) event.finish(); - else if(list.length==1) event._result={control:list[0]}; - else target.chooseControl(list).set('prompt','将一种花色的牌交给'+get.translation(player)); - 'step 3' - var cards=target.getCards('h',function(card){ - return get.suit(card,target)==result.control&&lib.filter.cardDiscardable(card,target,'yachai'); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { control: list[0] }; + else + target + .chooseControl(list) + .set("prompt", "将一种花色的牌交给" + get.translation(player)); + "step 3"; + var cards = target.getCards("h", function (card) { + return ( + get.suit(card, target) == result.control && + lib.filter.cardDiscardable(card, target, "yachai") + ); }); - if(cards.length) target.give(cards,player,'give'); + if (cards.length) target.give(cards, player, "give"); event.finish(); - 'step 4' - target.chooseToDiscard('h',true,num); + "step 4"; + target.chooseToDiscard("h", true, num); }, - subSkill:{ - block:{ - mark:true, - intro:{content:'不能使用手牌'}, - charlotte:true, - mod:{ - cardEnabled:function(card,player){ - let hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - for(let i of cards){ - if(hs.includes(i)) return false; + subSkill: { + block: { + mark: true, + intro: { content: "不能使用手牌" }, + charlotte: true, + mod: { + cardEnabled: function (card, player) { + let hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + for (let i of cards) { + if (hs.includes(i)) return false; } }, - cardSavable:function(card,player){ - let hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - for(let i of cards){ - if(hs.includes(i)) return false; + cardSavable: function (card, player) { + let hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + for (let i of cards) { + if (hs.includes(i)) return false; } }, }, }, }, }, - qingtan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>current.countCards('h')>0); + qingtan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => current.countCards("h") > 0); }, - filterTarget:function(card,player,target){ - return target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target.countCards("h") > 0; }, - selectTarget:-1, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' + selectTarget: -1, + multitarget: true, + multiline: true, + content: function () { + "step 0"; targets.sortBySeat(); - 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()]}; + 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;i'+get.translation(targetsx)+''); + dialog.push('
              ' + get.translation(targetsx) + "
              "); dialog.push(map[suit]); list.push(suit); } } - 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 (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; + } } - } - if(temp>max){ - res=s; - max=temp; - } - } - return res; - }); + return res; + }); else event.finish(); - 'step 3' - if(result.control!='cancel2'){ - event.cards2=cards.filter(function(i){ - return get.suit(i)==result.control; - }) - for(var i=0;i0&&target!=player&&target.countGainableCards(player,'h')>0; + weimeng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player.hp > 0 && target != player && target.countGainableCards(player, "h") > 0; }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'h',true,[1,player.hp]); - 'step 1' - if(result.bool&&target.isIn()){ - var num=result.cards.length,hs=player.getCards('he'); - var numx=0; - for(var i of result.cards) numx+=get.number(i,player); - event.num=numx; - event.cards=result.cards; - if(!hs.length) event.finish(); - else if(hs.length<=num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择交给'+get.translation(target)+get.cnNumber(num)+'张牌','(已得到牌的点数和:'+numx+')',num); - } - else event.finish(); - 'step 2' - player.give(result.cards,target); - var numx=0; - for(var i of result.cards) numx+=get.number(i,player); - if(numx>num) player.draw(); - else if(numx num) player.draw(); + else if (numx < num) player.discardPlayerCard(target, true, "hej"); }, - ai:{ - order:6, - tag:{ - lose:1, - loseCard:1, - gain:1, + ai: { + order: 6, + tag: { + lose: 1, + loseCard: 1, + gain: 1, }, - result:{ - target:function(player,target){ - return -Math.pow(Math.min(player.hp,target.countCards('h')),2)/4; + result: { + target: function (player, target) { + return -Math.pow(Math.min(player.hp, target.countCards("h")), 2) / 4; }, }, }, }, //冯熙 - yusui:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.player!=player&&event.player.isIn()&&get.color(event.card)=='black'; + yusui: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return event.player != player && event.player.isIn() && get.color(event.card) == "black"; }, - logTarget:'player', - check:function(event,player){ - var target=event.player; - if(player.hp<3||get.attitude(player,target)>-3) return false; - if(player.hp3) return true; + logTarget: "player", + check: function (event, player) { + var target = event.player; + if (player.hp < 3 || get.attitude(player, target) > -3) return false; + if (player.hp < target.hp) return true; + if (Math.min(target.countCards("h") - player.countCards("h"), target.countCards("h")) > 3) + return true; return false; }, - preHidden:true, - content:function(){ - 'step 0' + preHidden: true, + content: function () { + "step 0"; player.loseHp(); - event.target=trigger.player; - 'step 1' - event.addIndex=0; - var list=[],num=target.countCards('h')-player.countCards('h'); - event.num=num; - if(num>0&&target.countCards('h')>0) list.push('令其弃置'+get.cnNumber(num)+'张手牌'); + event.target = trigger.player; + "step 1"; + event.addIndex = 0; + var list = [], + num = target.countCards("h") - player.countCards("h"); + event.num = num; + if (num > 0 && target.countCards("h") > 0) + list.push("令其弃置" + get.cnNumber(num) + "张手牌"); else event.addIndex++; - if(target.hp>player.hp) list.push('令其失去'+get.cnNumber(target.hp-player.hp)+'点体力'); - if(!list.length) event.finish(); - else if(list.length==1) event._result={index:0}; - else player.chooseControl().set('choiceList',list).set('prompt','令'+get.translation(target)+'执行一项').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - return (target.hp-player.hp)>(Math.min(_status.event.getParent().num,target.countCards('h'))/2)?1:0; - }); - 'step 2' - if(result.index+event.addIndex==0) target.chooseToDiscard(num,true,'h'); - else target.loseHp(target.hp-player.hp); + if (target.hp > player.hp) + list.push("令其失去" + get.cnNumber(target.hp - player.hp) + "点体力"); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl() + .set("choiceList", list) + .set("prompt", "令" + get.translation(target) + "执行一项") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + return target.hp - player.hp > + Math.min(_status.event.getParent().num, target.countCards("h")) / 2 + ? 1 + : 0; + }); + "step 2"; + if (result.index + event.addIndex == 0) target.chooseToDiscard(num, true, "h"); + else target.loseHp(target.hp - player.hp); }, }, - boyan:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + boyan: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - 'step 0' - target.drawTo(Math.min(5,target.maxHp)); - 'step 1' - target.addTempSkill('boyan_block'); + content: function () { + "step 0"; + target.drawTo(Math.min(5, target.maxHp)); + "step 1"; + target.addTempSkill("boyan_block"); }, - subSkill:{ - block:{ - mark:true, - intro:{content:'不能使用或打出手牌'}, - charlotte:true, - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + subSkill: { + block: { + mark: true, + intro: { content: "不能使用或打出手牌" }, + charlotte: true, + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, }, }, }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0) return Math.max(0,Math.min(5,target.maxHp)-target.countCards('h')); - if(Math.max(0,Math.min(5,target.maxHp)-target.countCards('h'))<=1&&target.countCards('h','shan')&&!target.hasSkillTag('respondShan',true,null,true)&&player.countCards('h',function(card){ - return get.tag(card,'respondShan')&&player.getUseValue(card,null,true)>0&&get.effect(target,card,player,player)>0; - })) return -2; + ai: { + order: 4, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) + return Math.max(0, Math.min(5, target.maxHp) - target.countCards("h")); + if ( + Math.max(0, Math.min(5, target.maxHp) - target.countCards("h")) <= 1 && + target.countCards("h", "shan") && + !target.hasSkillTag("respondShan", true, null, true) && + player.countCards("h", function (card) { + return ( + get.tag(card, "respondShan") && + player.getUseValue(card, null, true) > 0 && + get.effect(target, card, player, player) > 0 + ); + }) + ) + return -2; }, }, }, }, //祢衡 - rekuangcai:{ - audio:2, - forced:true, - trigger:{player:'phaseDiscardBegin'}, - filter:function(event,player){ - return !player.getHistory('useCard').length||!player.getHistory('sourceDamage').length; + rekuangcai: { + audio: 2, + forced: true, + trigger: { player: "phaseDiscardBegin" }, + filter: function (event, player) { + return !player.getHistory("useCard").length || !player.getHistory("sourceDamage").length; }, - content:function(){ - lib.skill.rekuangcai.change(player,player.getHistory('useCard').length?-1:1); + content: function () { + lib.skill.rekuangcai.change(player, player.getHistory("useCard").length ? -1 : 1); }, - mod:{ - targetInRange:function(card,player){ - if(player==_status.currentPhase) return true; + mod: { + targetInRange: function (card, player) { + if (player == _status.currentPhase) return true; }, - cardUsable:function(card,player){ - if(player==_status.currentPhase) return Infinity; + cardUsable: function (card, player) { + if (player == _status.currentPhase) return Infinity; }, }, - change:function(player,num){ - if(typeof player.storage.rekuangcai_change!='number') player.storage.rekuangcai_change=0; - player.storage.rekuangcai_change+=num; - player.addSkill('rekuangcai_change'); + change: function (player, num) { + if (typeof player.storage.rekuangcai_change != "number") + player.storage.rekuangcai_change = 0; + player.storage.rekuangcai_change += num; + player.addSkill("rekuangcai_change"); }, - group:'rekuangcai_draw', - subSkill:{ - draw:{ - audio:'rekuangcai', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.getHistory('sourceDamage').length>0; + group: "rekuangcai_draw", + subSkill: { + draw: { + audio: "rekuangcai", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.getHistory("sourceDamage").length > 0; }, - content:function(){ - player.draw(Math.min(5,player.getStat('damage'))); + content: function () { + player.draw(Math.min(5, player.getStat("damage"))); }, }, - change:{ - mod:{ - maxHandcard:function(player,num){ - if(typeof player.storage.rekuangcai_change=='number') return num+player.storage.rekuangcai_change; + change: { + mod: { + maxHandcard: function (player, num) { + if (typeof player.storage.rekuangcai_change == "number") + return num + player.storage.rekuangcai_change; }, }, - charlotte:true, - mark:true, - intro:{ - content:(num)=>('手牌上限'+(num<0?'':'+')+num), + charlotte: true, + mark: true, + intro: { + content: (num) => "手牌上限" + (num < 0 ? "" : "+") + num, }, }, }, }, - reshejian:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - if(player==event.player||event.targets.length!=1) return false; - return player.countCards('h')>=2; + reshejian: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + if (player == event.player || event.targets.length != 1) return false; + return player.countCards("h") >= 2; }, - direct:true, - usable:2, - content:function(){ - 'step 0' - player.chooseToDiscard('he',[2,Infinity],get.prompt('reshejian',trigger.player),'
              弃置至少两张手牌,然后选择一项:
              ⒈弃置其等量的牌。⒉对其造成1点伤害。
              ').set('ai',function(card){ - if(_status.event.goon&&ui.selected.cards.length<2) return 5.6-get.value(card); - return 0; - }).set('goon',function(){ - var target=trigger.player; - if(get.damageEffect(target,player,player)>0) return true; - if(target.countCards('he',function(card){ - return get.value(card,target)>6; - })>=2) return true; - return false; - }()).logSkill=['reshejian',trigger.player]; - 'step 1' - if(!result.bool){ - player.storage.counttrigger.reshejian--; - event.finish(); - return; - } - var num=result.cards.length; - event.num=num; - var target=trigger.player,str=get.translation(target); - event.target=target; - if(!target.isIn()) event.finish(); - else if(!target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he')) event._result={index:1}; - else player.chooseControl().set('choiceList',[ - '弃置'+str+'的'+get.cnNumber(num)+'张牌', - '对'+str+'造成1点伤害', - ]).set('ai',function(){ - var player=_status.event.player; - var eff0=get.effect(target,{name:'guohe_copy2'},player,player)*Math.min(1.7,target.countCards('he')); - var eff1=get.damageEffect(target,player,player); - return eff0>eff1?0:1; - }); - 'step 2' - if(result.index==0) player.discardPlayerCard(target,num,true,'he'); + usable: 2, + async cost(event, trigger, player) { + event.result = await player + .chooseToDiscard( + "he", + [2, Infinity], + get.prompt("reshejian", trigger.player), + '
              弃置至少两张手牌,然后选择一项:
              ⒈弃置其等量的牌。⒉对其造成1点伤害。
              ' + ) + .set( + "ai", + function (card) { + if (_status.event.goon && ui.selected.cards.length < 2) + return 5.6 - get.value(card); + return 0; + }, + "chooseonly" + ) + .set( + "goon", + (function () { + var target = trigger.player; + if (get.damageEffect(target, player, player) > 0) return true; + if ( + target.countCards("he", function (card) { + return get.value(card, target) > 6; + }) >= 2 + ) + return true; + return false; + })() + ) + .forResult(); + }, + logTarget: "player", + content: function () { + "step 0"; + player.discard(cards); + "step 1"; + var num = cards.length; + event.num = num; + var target = targets[0], + str = get.translation(target); + event.target = target; + if (!target.isIn()) event.finish(); + else if ( + !target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ) + event._result = { index: 1 }; + else + player + .chooseControl() + .set("choiceList", [ + "弃置" + str + "的" + get.cnNumber(num) + "张牌", + "对" + str + "造成1点伤害", + ]) + .set("ai", function () { + var player = _status.event.player; + var eff0 = + get.effect(target, { name: "guohe_copy2" }, player, player) * + Math.min(1.7, target.countCards("he")); + var eff1 = get.damageEffect(target, player, player); + return eff0 > eff1 ? 0 : 1; + }); + "step 2"; + if (result.index == 0) player.discardPlayerCard(target, num, true, "he"); else target.damage(); }, }, //陈登 - refuyuan:{ - audio:2, - trigger:{global:'useCardToTargeted'}, - logTarget:'target', - filter:function(event,player){ - return event.card.name=='sha'&&event.target.isIn()&&!game.hasPlayer2(function(current){ - return current.hasHistory('useCard',function(evt){ - return evt.card!=event.card&&get.color(evt.card,false)=='red'&&evt.targets&&evt.targets.includes(event.target); - }); - }); + refuyuan: { + audio: 2, + trigger: { global: "useCardToTargeted" }, + logTarget: "target", + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.target.isIn() && + !game.hasPlayer2(function (current) { + return current.hasHistory("useCard", function (evt) { + return ( + evt.card != event.card && + get.color(evt.card, false) == "red" && + evt.targets && + evt.targets.includes(event.target) + ); + }); + }) + ); }, - check:function(event,player){ - return get.attitude(player,event.target)>0; + check: function (event, player) { + return get.attitude(player, event.target) > 0; }, - content:function(){ + content: function () { trigger.target.draw(); }, }, - reyingshui:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer((current)=>player.inRange(current)); + reyingshui: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && game.hasPlayer((current) => player.inRange(current)) + ); }, - position:'he', - filterCard:true, - filterTarget:function(card,player,target){ + position: "he", + filterCard: true, + filterTarget: function (card, player, target) { return player.inRange(target); }, - discard:false, - lose:false, - delay:false, - check:function(card){ - if(get.type(card)=='equip') return 3-get.value(card); - return 6.5-get.value(card); + discard: false, + lose: false, + delay: false, + check: function (card) { + if (get.type(card) == "equip") return 3 - get.value(card); + return 6.5 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' - var next=target.chooseCard('he',[2,Infinity],'交给'+get.translation(player)+'至少两张装备牌,否则受到1点伤害',{type:'equip'}); - if(get.damageEffect(target,player,target)>=0) next.set('ai',()=>-1); - else next.set('ai',(card)=>ui.selected.cards.length<2?(6-get.value(card)):0); - 'step 2' - if(result.bool) target.give(result.cards,player); - else target.damage('nocard'); + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + var next = target.chooseCard( + "he", + [2, Infinity], + "交给" + get.translation(player) + "至少两张装备牌,否则受到1点伤害", + { type: "equip" } + ); + if (get.damageEffect(target, player, target) >= 0) next.set("ai", () => -1); + else next.set("ai", (card) => (ui.selected.cards.length < 2 ? 6 - get.value(card) : 0)); + "step 2"; + if (result.bool) target.give(result.cards, player); + else target.damage("nocard"); }, - ai:{ - order:5, - tag:{ - damage:0.5, + ai: { + order: 5, + tag: { + damage: 0.5, }, - result:{ - target:-1.5, + result: { + target: -1.5, }, }, }, - rewangzu:{ - audio:2, - trigger:{player:'damageBegin1'}, - direct:true, - filter:function(event,player){ - return event.source&&player!=event.source&&player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'rewangzu'),'h'); + rewangzu: { + audio: 2, + trigger: { player: "damageBegin1" }, + filter: function (event, player) { + return ( + event.source && + player != event.source && + player.hasCard((card) => lib.filter.cardDiscardable(card, player, "rewangzu"), "h") + ); }, - usable:1, - content:function(){ - 'step 0' - var num=player.getFriends().length; - if(!game.hasPlayer(function(current){ - return current!=player&¤t.getFriends().length>num; - })){ - player.chooseToDiscard('h',get.prompt('rewangzu'),'弃置一张牌并令伤害-1').set('ai',function(card){ - return 7-get.value(card); - }).logSkill='rewangzu'; + usable: 1, + async cost(event, trigger, player) { + "step 0"; + var num = player.getFriends().length; + if ( + !game.hasPlayer(function (current) { + return current != player && current.getFriends().length > num; + }) + ) { + player + .chooseToDiscard( + "h", + get.prompt("rewangzu"), + "弃置一张牌并令伤害-1", + "chooseonly" + ) + .set("ai", function (card) { + return 7 - get.value(card); + }); + } else { + player.chooseBool(get.prompt("rewangzu"), "随机弃置一张牌并令伤害-1"); } - else{ - player.chooseBool(get.prompt('rewangzu'),'随机弃置一张牌并令伤害-1'); + "step 1"; + event.result = result; + }, + async content(event, trigger, player) { + trigger.num--; + if (!event.cards || !event.cards.length) { + const cards = player.getCards("h", (card) => + lib.filter.cardDiscardable(card, player, "rewangzu") + ); + if (cards.length) player.discard(cards.randomGet()); + } else { + player.discard(event.cards); } - 'step 1' - if(result.bool){ - trigger.num--; - if(!result.cards||!result.cards.length){ - player.logSkill('rewangzu'); - var cards=player.getCards('h',(card)=>lib.filter.cardDiscardable(card,player,'rewangzu')); - if(cards.length) player.discard(cards.randomGet()); - } - } - else player.storage.counttrigger.rewangzu--; }, }, //万年公主 - zhenge:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhenge'),'令一名角色的攻击范围+1').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target) - if(att>0){ - if(!target.hasMark('zhenge_effect')) att*=1.5; - if(!game.hasPlayer(function(current){ - return get.distance(target,current,'attack')>2; - })){ - var usf=Math.max.apply(Math,game.filterPlayer().map(function(current){ - if(target.canUse('sha',current,false)) return get.effect(current,{name:'sha'},target,player); - return 0; - })); - return att+usf; + zhenge: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("zhenge"), "令一名角色的攻击范围+1") + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att > 0) { + if (!target.hasMark("zhenge_effect")) att *= 1.5; + if ( + !game.hasPlayer(function (current) { + return get.distance(target, current, "attack") > 2; + }) + ) { + var usf = Math.max.apply( + Math, + game.filterPlayer().map(function (current) { + if (target.canUse("sha", current, false)) + return get.effect(current, { name: "sha" }, target, player); + return 0; + }) + ); + return att + usf; + } + return att; } - return att; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('zhenge',target); - target.addSkill('zhenge_effect'); - if(target.countMark('zhenge_effect')<5) target.addMark('zhenge_effect',1,false); - if(!game.hasPlayer(function(current){ - return current!=target&&!target.inRange(current); - })){ - player.chooseTarget('是否令'+get.translation(target)+'视为对另一名角色使用【杀】?',function(card,player,target){ - return _status.event.source.canUse('sha',target); - }).set('source',target).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,{name:'sha'},evt.source,evt.player); - }); - } - else{ + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("zhenge", target); + target.addSkill("zhenge_effect"); + if (target.countMark("zhenge_effect") < 5) target.addMark("zhenge_effect", 1, false); + if ( + !game.hasPlayer(function (current) { + return current != target && !target.inRange(current); + }) + ) { + player + .chooseTarget( + "是否令" + get.translation(target) + "视为对另一名角色使用【杀】?", + function (card, player, target) { + return _status.event.source.canUse("sha", target); + } + ) + .set("source", target) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, { name: "sha" }, evt.source, evt.player); + }); + } else { game.delayx(); event.finish(); } + } else event.finish(); + "step 2"; + if (result.bool) { + target.useCard({ name: "sha", isCard: true }, result.targets[0], false); } - else event.finish(); - 'step 2' - if(result.bool){ - target.useCard({name:'sha',isCard:true},result.targets[0],false); - } - 'step 3' + "step 3"; game.delayx(); }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('zhenge_effect'); + subSkill: { + effect: { + charlotte: true, + onremove: true, + mod: { + attackRange: function (player, num) { + return num + player.countMark("zhenge_effect"); }, }, - intro:{content:'攻击范围+#'}, + intro: { content: "攻击范围+#" }, }, }, }, - xinghan:{ - audio:2, - init:function(player){ - player.addSkill('xinghan_count'); + xinghan: { + audio: 2, + init: function (player) { + player.addSkill("xinghan_count"); }, - onremove:function(player){ - player.removeSkill('xinghan_count'); + onremove: function (player) { + player.removeSkill("xinghan_count"); }, - trigger:{global:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card==player.storage.xinghan_temp&&event.source&&event.source.hasMark('zhenge_effect'); + trigger: { global: "damageSource" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.card == player.storage.xinghan_temp && + event.source && + event.source.hasMark("zhenge_effect") + ); }, - logTarget:'source', - content:function(){ - player.draw(player.isMaxHandcard(true)?1:Math.min(5,trigger.source.getAttackRange())); + logTarget: "source", + content: function () { + player.draw( + player.isMaxHandcard(true) ? 1 : Math.min(5, trigger.source.getAttackRange()) + ); }, - subSkill:{ - count:{ - trigger:{global:'useCard1'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.card.name=='sha'&&!game.hasPlayer2(function(current){ - return current.hasHistory('useCard',function(evt){ - return evt!=event&&evt.card.name=='sha'; + subSkill: { + count: { + trigger: { global: "useCard1" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !game.hasPlayer2(function (current) { + return current.hasHistory("useCard", function (evt) { + return evt != event && evt.card.name == "sha"; + }); }) - }); + ); }, - content:function(){ - player.addTempSkill('xinghan_temp'); - player.storage.xinghan_temp=trigger.card; + content: function () { + player.addTempSkill("xinghan_temp"); + player.storage.xinghan_temp = trigger.card; }, }, - temp:{onremove:true}, + temp: { onremove: true }, }, - ai:{combo:'zhenge'}, + ai: { combo: "zhenge" }, }, //荀谌 - refenglve:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkillTag('noCompareSource')&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0&&!current.hasSkillTag('noCompareTarget'); - }); + refenglve: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.hasSkillTag("noCompareSource") && + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("h") > 0 && + !current.hasSkillTag("noCompareTarget") + ); + }) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0&&!target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + return ( + target != player && + target.countCards("h") > 0 && + !target.hasSkillTag("noCompareTarget") + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - if(!target.countCards('hej')) event.finish(); - else{ - event.giver=target; - event.gainner=player; - target.choosePlayerCard(target,true,'hej',2,'交给'+get.translation(player)+'两张牌'); + "step 1"; + if (result.bool) { + if (!target.countCards("hej")) event.finish(); + else { + event.giver = target; + event.gainner = player; + target.choosePlayerCard( + target, + true, + "hej", + 2, + "交给" + get.translation(player) + "两张牌" + ); } - } - else if(result.tie){ - delete player.getStat('skill').refenglve; + } else if (result.tie) { + delete player.getStat("skill").refenglve; event.finish(); - } - else{ - if(get.position(result.player,true)=='d') target.gain(result.player,'gain2'); + } else { + if (get.position(result.player, true) == "d") target.gain(result.player, "gain2"); event.finish(); /*if(!player.countCards('he')) event.finish(); else{ @@ -10565,415 +13200,500 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.chooseCard(true,'he','交给'+get.translation(target)+'一张牌'); }*/ } - 'step 2' - if(result.bool) event.giver.give(result.cards,event.gainner); + "step 2"; + if (result.bool) event.giver.give(result.cards, event.gainner); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(!player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=11; - } - if(val<=6){ - return card.number>=13; - } - return false; - })) return 0; - return -Math.sqrt(1+target.countCards('he'))/(1+target.countCards('j')); + ai: { + order: 8, + result: { + target: function (player, target) { + if ( + !player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 11; + } + if (val <= 6) { + return card.number >= 13; + } + return false; + }) + ) + return 0; + return -Math.sqrt(1 + target.countCards("he")) / (1 + target.countCards("j")); }, }, }, }, - anyong:{ - audio:2, - trigger:{global:'damageSource'}, - direct:true, - filter:function(event,player){ - return event.source&&event.source==_status.currentPhase&&event.num==1&& - event.player!=event.source&&event.player.isIn()&&player.countCards('he')>0&& - event.source.getHistory('sourceDamage',function(evt){ - return evt.player!=event.source; - }).indexOf(event)==0; + anyong: { + audio: 2, + trigger: { global: "damageSource" }, + direct: true, + filter: function (event, player) { + return ( + event.source && + event.source == _status.currentPhase && + event.num == 1 && + event.player != event.source && + event.player.isIn() && + player.countCards("he") > 0 && + event.source + .getHistory("sourceDamage", function (evt) { + return evt.player != event.source; + }) + .indexOf(event) == 0 + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('anyong',trigger.player),'弃置一张牌并对其造成1点伤害').set('goon',get.damageEffect(trigger.player,player,player)>0).set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).logSkill=['anyong',trigger.player]; - 'step 1' - if(result.bool) trigger.player.damage(); + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("anyong", trigger.player), + "弃置一张牌并对其造成1点伤害" + ) + .set("goon", get.damageEffect(trigger.player, player, player) > 0) + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }).logSkill = ["anyong", trigger.player]; + "step 1"; + if (result.bool) trigger.player.damage(); }, }, //刘永 - zhuning:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - if(!player.countCards('he')) return false; - return (!player.getStat('skill').zhuning||player.hasSkill('zhuning_double')); + zhuning: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + if (!player.countCards("he")) return false; + return !player.getStat("skill").zhuning || player.hasSkill("zhuning_double"); }, - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - selectCard:[1,Infinity], - delay:false, - lose:false, - discard:false, - check:function(card){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(ui.selected.cards.length>=Math.max(1,player.countCards('h')-player.hp)) return 0; - return 10-get.value(card); + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + selectCard: [1, Infinity], + delay: false, + lose: false, + discard: false, + check: function (card) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + var player = get.owner(card); + if (ui.selected.cards.length >= Math.max(1, player.countCards("h") - player.hp)) return 0; + return 10 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target).gaintag.add('fengxiang_tag'); - 'step 1' - var list=[]; - for(var name of lib.inpile){ - var type=get.type(name); - if(type!='basic'&&type!='trick') continue; - var card={name:name,isCard:true}; - if(get.tag(card,'damage')>0&&player.hasUseTarget(card)){ - list.push([type,'',name]); + content: function () { + "step 0"; + player.give(cards, target).gaintag.add("fengxiang_tag"); + "step 1"; + var list = []; + for (var name of lib.inpile) { + var type = get.type(name); + if (type != "basic" && type != "trick") continue; + var card = { name: name, isCard: true }; + if (get.tag(card, "damage") > 0 && player.hasUseTarget(card)) { + list.push([type, "", name]); } - if(name=='sha'){ - for(var i of lib.inpile_nature){ - card.nature=i; - if(player.hasUseTarget(card)) list.push([type,'',name,i]); + if (name == "sha") { + for (var i of lib.inpile_nature) { + card.nature = i; + if (player.hasUseTarget(card)) list.push([type, "", name, i]); } } } - if(list.length){ - player.chooseButton(['是否视为使用一张伤害牌?',[list,'vcard']]).set('ai',function(button){ - return _status.event.player.getUseValue({name:button.link[2]}); - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.chooseUseTarget({name:result.links[0][2],nature:result.links[0][3],isCard:true},true,false); - } - else event.finish(); - 'step 3' - if(!player.hasHistory('sourceDamage',function(evt){ - if(!evt.card) return false; - var evtx=evt.getParent('useCard'); - return evtx.card==evt.card&&evtx.getParent(2)==event; - })) player.addTempSkill('zhuning_double'); + if (list.length) { + player + .chooseButton(["是否视为使用一张伤害牌?", [list, "vcard"]]) + .set("ai", function (button) { + return _status.event.player.getUseValue({ name: button.link[2] }); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + player.chooseUseTarget( + { name: result.links[0][2], nature: result.links[0][3], isCard: true }, + true, + false + ); + } else event.finish(); + "step 3"; + if ( + !player.hasHistory("sourceDamage", function (evt) { + if (!evt.card) return false; + var evtx = evt.getParent("useCard"); + return evtx.card == evt.card && evtx.getParent(2) == event; + }) + ) + player.addTempSkill("zhuning_double"); }, - subSkill:{ - double:{}, + subSkill: { + double: {}, }, - ai:{ - fireAttack:true, - order:4, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; + ai: { + fireAttack: true, + order: 4, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - var np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.rerende<0||player.countCards('h')<=1){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + var np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.rerende < 0 || + player.countCards("h") <= 1 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); - } + return Math.max(1, 5 - nh); + }, }, - } + }, }, - fengxiang:{ - getMax:function(event){ - var max=0,max2=null,players=game.filterPlayer(); - for(var current of players){ - var num=0,cards=current.getCards('h',function(card){ - return card.hasGaintag('fengxiang_tag'); - }); - if(event){ - if(event.name=='gain'&&event.gaintag.includes('fengxiang_tag')) cards.removeArray(event.cards); - var evt=event.getl(current); - if(evt&&evt.gaintag_map){ - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('fengxiang_tag')) num++; + fengxiang: { + getMax: function (event) { + var max = 0, + max2 = null, + players = game.filterPlayer(); + for (var current of players) { + var num = 0, + cards = current.getCards("h", function (card) { + return card.hasGaintag("fengxiang_tag"); + }); + if (event) { + if (event.name == "gain" && event.gaintag.includes("fengxiang_tag")) + cards.removeArray(event.cards); + var evt = event.getl(current); + if (evt && evt.gaintag_map) { + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("fengxiang_tag")) num++; } } } - num+=cards.length; - if(num>max){ - max=num; - max2=current; - } - else if(num==max) max2=null; + num += cards.length; + if (num > max) { + max = num; + max2 = current; + } else if (num == max) max2 = null; } return max2; }, - audio:2, - init:function(player){ - game.addGlobalSkill('fengxiang_use'); + audio: 2, + init: function (player) { + game.addGlobalSkill("fengxiang_use"); }, - onremove:function(player){ - if(!game.hasPlayer(current=>current.hasSkill('fengxiang'),true)) game.removeGlobalSkill('fengxiang_use'); + onremove: function (player) { + if (!game.hasPlayer((current) => current.hasSkill("fengxiang"), true)) + game.removeGlobalSkill("fengxiang_use"); }, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - var target=lib.skill.fengxiang.getMax(); - return !target||target.isDamaged(); + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + var target = lib.skill.fengxiang.getMax(); + return !target || target.isDamaged(); }, - logTarget:function(event,player){ - return lib.skill.fengxiang.getMax()||player; + logTarget: function (event, player) { + return lib.skill.fengxiang.getMax() || player; }, - content:function(){ - var target=lib.skill.fengxiang.getMax(); - if(target) target.recover(); + content: function () { + var target = lib.skill.fengxiang.getMax(); + if (target) target.recover(); else player.draw(); }, - group:'fengxiang_draw', - subSkill:{ - draw:{ - trigger:{ - global:['equipAfter','addJudgeAfter','loseAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + group: "fengxiang_draw", + subSkill: { + draw: { + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "loseAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - if(event.name=='lose'&&event.getlx===false) return false; - return lib.skill.fengxiang.getMax()!=lib.skill.fengxiang.getMax(event); + forced: true, + filter: function (event, player) { + if (event.name == "lose" && event.getlx === false) return false; + return lib.skill.fengxiang.getMax() != lib.skill.fengxiang.getMax(event); }, - content:function(){ - if(trigger.delay===false) game.delayx(); + content: function () { + if (trigger.delay === false) game.delayx(); player.draw(); }, }, - use:{ - mod:{ - aiOrder:function(player,card,num){ - if(num>0&&get.itemtype(card)==='card'&&card.hasGaintag('fengxiang_tag')&&game.hasPlayer(current=>{ - return current.hasSkill('fengxiang')&&get.attitude(player,current)>0; - })) return num+10; - } + use: { + mod: { + aiOrder: function (player, card, num) { + if ( + num > 0 && + get.itemtype(card) === "card" && + card.hasGaintag("fengxiang_tag") && + game.hasPlayer((current) => { + return ( + current.hasSkill("fengxiang") && get.attitude(player, current) > 0 + ); + }) + ) + return num + 10; + }, }, - trigger:{player:'dieAfter'}, - filter:function(event,player){ - return !game.hasPlayer(current=>current.hasSkill('fengxiang'),true); + trigger: { player: "dieAfter" }, + filter: function (event, player) { + return !game.hasPlayer((current) => current.hasSkill("fengxiang"), true); }, - silent:true, - forceDie:true, - charlotte:true, - content:function(){ - game.removeGlobalSkill('fengxiang_use'); - } - } + silent: true, + forceDie: true, + charlotte: true, + content: function () { + game.removeGlobalSkill("fengxiang_use"); + }, + }, }, }, //阚泽 - rekuanshi:{ - audio:'kuanshi', - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('rekuanshi')).set('animate',false).set('ai',function(target){ - var att=get.attitude(player,target); - if(target.hp<3) att/=1.5; - return att; - }); - 'step 1' - if(result.bool){ - player.logSkill('rekuanshi'); - player.addTempSkill('rekuanshi_effect',{player:'phaseBegin'}); - player.storage.rekuanshi_effect=result.targets[0]; + rekuanshi: { + audio: "kuanshi", + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("rekuanshi")) + .set("animate", false) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (target.hp < 3) att /= 1.5; + return att; + }); + "step 1"; + if (result.bool) { + player.logSkill("rekuanshi"); + player.addTempSkill("rekuanshi_effect", { player: "phaseBegin" }); + player.storage.rekuanshi_effect = result.targets[0]; game.delayx(); } }, - subSkill:{ - effect:{ - audio:'kuanshi', - mark:true, - intro:{ - content:'每回合限一次,当$于一回合内受到第2点伤害后,其回复1点体力。' + subSkill: { + effect: { + audio: "kuanshi", + mark: true, + intro: { + content: "每回合限一次,当$于一回合内受到第2点伤害后,其回复1点体力。", }, - trigger:{global:'damageEnd'}, - forced:true, - charlotte:true, - logTarget:'player', - usable:1, - filter:function(event,player){ - if(event.player!=player.storage.rekuanshi_effect||event.player.isHealthy()) return false; - var history=event.player.getHistory('damage',null,event),num=0; - for(var i of history) num+=i.num; - return num>1&&(num-event.num)<2; + trigger: { global: "damageEnd" }, + forced: true, + charlotte: true, + logTarget: "player", + usable: 1, + filter: function (event, player) { + if (event.player != player.storage.rekuanshi_effect || event.player.isHealthy()) + return false; + var history = event.player.getHistory("damage", null, event), + num = 0; + for (var i of history) num += i.num; + return num > 1 && num - event.num < 2; }, - content:function(){ + content: function () { trigger.player.recover(); - } + }, }, }, }, //吕玲绮 - guowu:{ - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + guowu: { + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - preHidden:true, - content:function(){ - 'step 0' - var hs=player.getCards('h'); - player.showCards(hs,get.translation(player)+'发动了【帼舞】'); - var list=[]; - for(var i of hs){ - list.add(get.type2(i,player)); - if(list.length>=3) break; + preHidden: true, + content: function () { + "step 0"; + var hs = player.getCards("h"); + player.showCards(hs, get.translation(player) + "发动了【帼舞】"); + var list = []; + for (var i of hs) { + list.add(get.type2(i, player)); + if (list.length >= 3) break; } - if(list.length>=1){ - var card=get.discardPile(function(i){ - return i.name=='sha'; + if (list.length >= 1) { + var card = get.discardPile(function (i) { + return i.name == "sha"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } - if(list.length>=2) player.addTempSkill('guowu_dist','phaseUseAfter'); - if(list.length>=3) player.addTempSkill('guowu_add','phaseUseAfter'); + if (list.length >= 2) player.addTempSkill("guowu_dist", "phaseUseAfter"); + if (list.length >= 3) player.addTempSkill("guowu_add", "phaseUseAfter"); }, - subSkill:{ - dist:{ - charlotte:true, - mod:{targetInRange:()=>true}, + subSkill: { + dist: { + charlotte: true, + mod: { targetInRange: () => true }, }, - add:{ - charlotte:true, - trigger:{player:'useCard1'}, - direct:true, - filter:function(event,player){ - var info=get.info(event.card,false); - if(info.allowMultiple==false) return false; - if(event.card.name!='sha'&&(info.type!='trick'||get.mode()=='guozhan')) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + add: { + charlotte: true, + trigger: { player: "useCard1" }, + direct: true, + filter: function (event, player) { + var info = get.info(event.card, false); + if (info.allowMultiple == false) return false; + if (event.card.name != "sha" && (info.type != "trick" || get.mode() == "guozhan")) + return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var num=game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,player,current)&&lib.filter.targetInRange(trigger.card,player,current); + content: function () { + "step 0"; + var num = game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, player, current) && + lib.filter.targetInRange(trigger.card, player, current) + ); }); - player.chooseTarget('帼舞:是否为'+get.translation(trigger.card)+'增加'+(num>1?'至多两个':'一个')+'目标?',[1,Math.min(2,num)],function(card,player,target){ - var trigger=_status.event.getTrigger(); - var card=trigger.card; - return !trigger.targets.includes(target)&&lib.filter.targetEnabled2(card,player,target)&&lib.filter.targetInRange(card,player,target); - }).set('ai',function(target){ - var player=_status.event.player; - var card=_status.event.getTrigger().card; - return get.effect(target,card,player,player); - }); - 'step 1' - if(result.bool){ - if(player!=game.me&&!player.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - var targets=result.targets.sortBySeat(); - player.logSkill('guowu_add',targets); + player + .chooseTarget( + "帼舞:是否为" + + get.translation(trigger.card) + + "增加" + + (num > 1 ? "至多两个" : "一个") + + "目标?", + [1, Math.min(2, num)], + function (card, player, target) { + var trigger = _status.event.getTrigger(); + var card = trigger.card; + return ( + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var card = _status.event.getTrigger().card; + return get.effect(target, card, player, player); + }); + "step 1"; + if (result.bool) { + if (player != game.me && !player.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + var targets = result.targets.sortBySeat(); + player.logSkill("guowu_add", targets); trigger.targets.addArray(targets); //if(get.mode()=='guozhan') player.removeSkill('guowu_add'); }, }, }, }, - zhuangrong:{ - derivation:['llqshenwei','wushuang'], - trigger:{global:'phaseEnd'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.hp==1||player.countCards('h')==1; + zhuangrong: { + derivation: ["llqshenwei", "wushuang"], + trigger: { global: "phaseEnd" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.hp == 1 || player.countCards("h") == 1; }, - content:function(){ - 'step 0' - player.awakenSkill('zhuangrong'); + content: function () { + "step 0"; + player.awakenSkill("zhuangrong"); player.loseMaxHp(); - 'step 1' - if(player.maxHp>player.hp) player.recover(player.maxHp-player.hp); - 'step 2' - player.drawTo(Math.min(5,player.maxHp)); - player.addSkills(['llqshenwei','wushuang']); + "step 1"; + if (player.maxHp > player.hp) player.recover(player.maxHp - player.hp); + "step 2"; + player.drawTo(Math.min(5, player.maxHp)); + player.addSkills(["llqshenwei", "wushuang"]); }, }, - llqshenwei:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:(event)=>!event.numFixed, - content:function(){ - trigger.num+=2; + llqshenwei: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: (event) => !event.numFixed, + content: function () { + trigger.num += 2; }, - mod:{ - maxHandcard:(player,num)=>num+2, + mod: { + maxHandcard: (player, num) => num + 2, }, }, - cuijian:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.cuijian.filterTarget(null,player,current)); + cuijian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => lib.skill.cuijian.filterTarget(null, player, current)); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - var hs=target.getCards('h','shan'); - if(hs.length){ - hs.addArray(target.getCards('he',function(card){ - return get.subtype(card)=='equip2'; - })) - player.gain(hs,target,'give','bySelf'); - if(player.hasMark('zhtongyuan_basic')) event.finish(); - else event.num=hs.length; - } - else{ - if(player.hasMark('zhtongyuan_trick')) player.draw(2); + content: function () { + "step 0"; + var hs = target.getCards("h", "shan"); + if (hs.length) { + hs.addArray( + target.getCards("he", function (card) { + return get.subtype(card) == "equip2"; + }) + ); + player.gain(hs, target, "give", "bySelf"); + if (player.hasMark("zhtongyuan_basic")) event.finish(); + else event.num = hs.length; + } else { + if (player.hasMark("zhtongyuan_trick")) player.draw(2); event.finish(); } - 'step 1' - var hs=player.getCards('he'); - if(!hs.length||!target.isIn()) event.finish(); - else if(hs.length<=num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择交给'+get.translation(target)+get.cnNumber(num)+'张牌',num); - 'step 2' - if(result.bool&&result.cards&&result.cards.length) player.give(result.cards,target); + "step 1"; + var hs = player.getCards("he"); + if (!hs.length || !target.isIn()) event.finish(); + else if (hs.length <= num) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "he", + true, + "选择交给" + get.translation(target) + get.cnNumber(num) + "张牌", + num + ); + "step 2"; + if (result.bool && result.cards && result.cards.length) player.give(result.cards, target); }, - ai:{ - order:4, - result:{ - player:function(player,target){ - if(!target.countCards('h','shan')) return player.hasMark('zhtongyuan_trick')?2:0; + ai: { + order: 4, + result: { + player: function (player, target) { + if (!target.countCards("h", "shan")) + return player.hasMark("zhtongyuan_trick") ? 2 : 0; return 0; }, - target:function(player,target){ - if(target.countCards('h','shan')){ - var num=-target.countCards('h')/2; - var card=target.getEquip(2); - if(card) num-=(get.value(card,target)/2); + target: function (player, target) { + if (target.countCards("h", "shan")) { + var num = -target.countCards("h") / 2; + var card = target.getEquip(2); + if (card) num -= get.value(card, target) / 2; return num; } return -0.01; @@ -10981,1398 +13701,1687 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - tongyuan:{audio:2}, - zhtongyuan:{ - audio:'tongyuan', - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - filter:function(event,player){ - var type=get.type2(event.card,false); - return (type=='basic'||type=='trick')&&get.color(event.card,false)=='red'&&!player.hasMark('zhtongyuan_'+type); + tongyuan: { audio: 2 }, + zhtongyuan: { + audio: "tongyuan", + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + filter: function (event, player) { + var type = get.type2(event.card, false); + return ( + (type == "basic" || type == "trick") && + get.color(event.card, false) == "red" && + !player.hasMark("zhtongyuan_" + type) + ); }, - content:function(){ - var type=get.type2(trigger.card,false); - if(!player.hasMark('zhtongyuan_'+type)){ - player.addMark('zhtongyuan_'+type,1,false); - game.log(player,'修改了技能','#g【摧坚】'); + content: function () { + var type = get.type2(trigger.card, false); + if (!player.hasMark("zhtongyuan_" + type)) { + player.addMark("zhtongyuan_" + type, 1, false); + game.log(player, "修改了技能", "#g【摧坚】"); } }, - group:['zhtongyuan_basic','zhtongyuan_trick'], - subSkill:{ - basic:{ - trigger:{player:'useCard2'}, - direct:true, - locked:true, - filter:function(event,player){ - if(!player.hasMark('zhtongyuan_basic')||!player.hasMark('zhtongyuan_trick')) return false; - var card=event.card; - if(get.color(card,false)!='red'||get.type(card,null,true)!='basic') return false; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ + group: ["zhtongyuan_basic", "zhtongyuan_trick"], + subSkill: { + basic: { + trigger: { player: "useCard2" }, + direct: true, + locked: true, + filter: function (event, player) { + if (!player.hasMark("zhtongyuan_basic") || !player.hasMark("zhtongyuan_trick")) + return false; + var card = event.card; + if (get.color(card, false) != "red" || get.type(card, null, true) != "basic") + return false; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('zhtongyuan'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget(get.prompt("zhtongyuan"), function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('zhtongyuan',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("zhtongyuan", event.targets); trigger.targets.addArray(event.targets); } }, }, - trick:{ - audio:'zhtongyuan', - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(!player.hasMark('zhtongyuan_basic')||!player.hasMark('zhtongyuan_trick')) return false; - var card=event.card; - return (get.color(card,false)=='red'&&get.type(card,null,false)=='trick'); + trick: { + audio: "zhtongyuan", + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (!player.hasMark("zhtongyuan_basic") || !player.hasMark("zhtongyuan_trick")) + return false; + var card = event.card; + return get.color(card, false) == "red" && get.type(card, null, false) == "trick"; }, - content:function(){ + content: function () { trigger.directHit.addArray(game.filterPlayer()); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, }, }, }, //陆郁生 - zhente:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - logTarget:'player', - usable:1, - preHidden:true, - filter:function(event,player){ - var color=get.color(event.card); - if(player==event.player||event.player.isDead()||color=='none'||(get.mode()=='guozhan'&&color!='black')) return false; - var type=get.type(event.card); - return type=='basic'||type=='trick'; + zhente: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + logTarget: "player", + usable: 1, + preHidden: true, + filter: function (event, player) { + var color = get.color(event.card); + if ( + player == event.player || + event.player.isDead() || + color == "none" || + (get.mode() == "guozhan" && color != "black") + ) + return false; + var type = get.type(event.card); + return type == "basic" || type == "trick"; }, - check:function(event,player){ - return !event.excluded.includes(player)&&get.effect(player,event.card,event.player,player)<0; + check: function (event, player) { + return ( + !event.excluded.includes(player) && + get.effect(player, event.card, event.player, player) < 0 + ); }, - content:function(){ - 'step 0' - trigger.player.chooseControl().set('choiceList',[ - '本回合内不能再使用'+get.translation(get.color(trigger.card))+'牌', - '令'+get.translation(trigger.card)+'对'+get.translation(player)+'无效', - ]).set('prompt',get.translation(player)+'发动了【贞特】,请选择一项').set('ai',function(){ - var player=_status.event.player; - var target=_status.event.getParent().player; - var card=_status.event.getTrigger().card,color=get.color(card); - if(get.effect(target,card,player,player)<=0) return 1; - var hs=player.countCards('h',function(card){ - return get.color(card,player)==color&&player.hasValueTarget(card,null,true); + content: function () { + "step 0"; + trigger.player + .chooseControl() + .set("choiceList", [ + "本回合内不能再使用" + get.translation(get.color(trigger.card)) + "牌", + "令" + get.translation(trigger.card) + "对" + get.translation(player) + "无效", + ]) + .set("prompt", get.translation(player) + "发动了【贞特】,请选择一项") + .set("ai", function () { + var player = _status.event.player; + var target = _status.event.getParent().player; + var card = _status.event.getTrigger().card, + color = get.color(card); + if (get.effect(target, card, player, player) <= 0) return 1; + var hs = player.countCards("h", function (card) { + return ( + get.color(card, player) == color && + player.hasValueTarget(card, null, true) + ); + }); + if (!hs.length) return 0; + if (hs > 1) return 1; + return Math.random() > 0.5 ? 0 : 1; }); - if(!hs.length) return 0; - if(hs>1) return 1; - return Math.random()>0.5?0:1; - }); - 'step 1' - if(result.index==0){ - trigger.player.addTempSkill('zhente2'); + "step 1"; + if (result.index == 0) { + trigger.player.addTempSkill("zhente2"); trigger.player.storage.zhente2.add(get.color(trigger.card)); - trigger.player.markSkill('zhente2'); - } - else trigger.excluded.add(player); + trigger.player.markSkill("zhente2"); + } else trigger.excluded.add(player); }, }, - zhente2:{ - mod:{ + zhente2: { + mod: { cardEnabled(card, player) { const color = get.color(card); - if (color != 'unsure' && player.getStorage('zhente2').includes(color)) return false; + if (color != "unsure" && player.getStorage("zhente2").includes(color)) return false; }, - cardSavable(card,player) { + cardSavable(card, player) { const color = get.color(card); - if (color != 'unsure' && player.getStorage('zhente2').includes(color)) return false; + if (color != "unsure" && player.getStorage("zhente2").includes(color)) return false; }, }, - charlotte:true, - onremove:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + charlotte: true, + onremove: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - intro:{content:'本回合内不能使用$牌'}, + intro: { content: "本回合内不能使用$牌" }, }, - zhiwei:{ - audio:2, - trigger:{ - player:['enterGame','showCharacterAfter','phaseBegin'], - global:['phaseBefore'], + zhiwei: { + audio: 2, + trigger: { + player: ["enterGame", "showCharacterAfter", "phaseBegin"], + global: ["phaseBefore"], }, - direct:true, - filter:function(event,player,name){ - if(player.hasSkill('zhiwei2')) return false; - if(!game.hasPlayer(current=>current!=player)) return false; - if(get.mode()=='guozhan') return event.name=='showCharacter'&&(event.toShow.includes('gz_luyusheng')||event.toShow.includes('luyusheng')); - return event.name!='showCharacter'&&(name!='phaseBefore'||game.phaseNumber==0); + direct: true, + filter: function (event, player, name) { + if (player.hasSkill("zhiwei2")) return false; + if (!game.hasPlayer((current) => current != player)) return false; + if (get.mode() == "guozhan") + return ( + event.name == "showCharacter" && + (event.toShow.includes("gz_luyusheng") || event.toShow.includes("luyusheng")) + ); + return event.name != "showCharacter" && (name != "phaseBefore" || game.phaseNumber == 0); }, - content:function(){ - 'step 0' - player.chooseTarget('请选择【至微】的目标','选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。',true,lib.filter.notMe).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return 1+att; - return Math.random(); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhiwei',target); - player.storage.zhiwei2=target; - player.addSkill('zhiwei2'); + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【至微】的目标", + "选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。", + true, + lib.filter.notMe + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return 1 + att; + return Math.random(); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhiwei", target); + player.storage.zhiwei2 = target; + player.addSkill("zhiwei2"); } }, }, - zhiwei2:{ - group:['zhiwei2_draw','zhiwei2_discard','zhiwei2_gain','zhiwei2_clear'], - charlotte:true, - onremove:true, - mark:'character', - intro:{content:'$造成伤害后你摸一张牌;$受到伤害后你弃置一张牌;你于弃牌阶段弃置牌后交给$'}, - subSkill:{ - draw:{ - audio:'zhiwei', - trigger:{global:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.source==player.storage.zhiwei2; + zhiwei2: { + group: ["zhiwei2_draw", "zhiwei2_discard", "zhiwei2_gain", "zhiwei2_clear"], + charlotte: true, + onremove: true, + mark: "character", + intro: { + content: "$造成伤害后你摸一张牌;$受到伤害后你弃置一张牌;你于弃牌阶段弃置牌后交给$", + }, + subSkill: { + draw: { + audio: "zhiwei", + trigger: { global: "damageSource" }, + forced: true, + filter: function (event, player) { + return event.source == player.storage.zhiwei2; }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { player.draw(); }, }, - discard:{ - audio:'zhiwei', - trigger:{global:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.player==player.storage.zhiwei2&&player.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'zhiwei2_discard'); - }); + discard: { + audio: "zhiwei", + trigger: { global: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.player == player.storage.zhiwei2 && + player.countCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "zhiwei2_discard"); + }) + ); }, - logTarget:'player', - content:function(){ - player.discard(player.getCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'zhiwei2_discard'); - }).randomGet()); + logTarget: "player", + content: function () { + player.discard( + player + .getCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "zhiwei2_discard"); + }) + .randomGet() + ); }, }, - gain:{ - audio:'zhiwei', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + gain: { + audio: "zhiwei", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false||event.getParent('phaseDiscard').player!=player||!player.storage.zhiwei2||!player.storage.zhiwei2.isIn()) return false; - var evt=event.getl(player); - return evt&&evt.cards2.filterInD('d').length>0; + forced: true, + filter: function (event, player) { + if ( + event.type != "discard" || + event.getlx === false || + event.getParent("phaseDiscard").player != player || + !player.storage.zhiwei2 || + !player.storage.zhiwei2.isIn() + ) + return false; + var evt = event.getl(player); + return evt && evt.cards2.filterInD("d").length > 0; }, - logTarget:function(event,player){ + logTarget: function (event, player) { return player.storage.zhiwei2; }, - content:function(){ - if(trigger.delay===false) game.delay(); - player.storage.zhiwei2.gain(trigger.getl(player).cards2.filterInD('d'),'gain2'); + content: function () { + if (trigger.delay === false) game.delay(); + player.storage.zhiwei2.gain(trigger.getl(player).cards2.filterInD("d"), "gain2"); }, }, - clear:{ - audio:'zhiwei', - trigger:{ - global:'die', - player:['hideCharacterEnd','removeCharacterEnd'], + clear: { + audio: "zhiwei", + trigger: { + global: "die", + player: ["hideCharacterEnd", "removeCharacterEnd"], }, - forced:true, - filter:function(event,player){ - if(event.name=='die') return event.player==player.storage.zhiwei2; - if(event.name=='removeCharacter') return event.toRemove=='luyusheng'||event.toRemove=='gz_luyusheng'; - return event.toHide=='luyusheng'||event.toHide=='gz_luyusheng'; + forced: true, + filter: function (event, player) { + if (event.name == "die") return event.player == player.storage.zhiwei2; + if (event.name == "removeCharacter") + return event.toRemove == "luyusheng" || event.toRemove == "gz_luyusheng"; + return event.toHide == "luyusheng" || event.toHide == "gz_luyusheng"; }, - content:function(){ - 'step 0' - player.removeSkill('zhiwei2'); - if(trigger.name!='die'||get.mode()!='guozhan') event.finish(); - 'step 1' - if(player.name1=='gz_luyusheng'||player.name1=='luyusheng') player.hideCharacter(0); - if(player.name2=='gz_luyusheng'||player.name2=='luyusheng') player.hideCharacter(1); + content: function () { + "step 0"; + player.removeSkill("zhiwei2"); + if (trigger.name != "die" || get.mode() != "guozhan") event.finish(); + "step 1"; + if (player.name1 == "gz_luyusheng" || player.name1 == "luyusheng") + player.hideCharacter(0); + if (player.name2 == "gz_luyusheng" || player.name2 == "luyusheng") + player.hideCharacter(1); }, }, }, }, //华歆 - spwanggui:{ - audio:'wanggui', - trigger:{source:'damageSource'}, - direct:true, - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.group!=player.group; + spwanggui: { + audio: "wanggui", + trigger: { source: "damageSource" }, + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.group != player.group; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('spwanggui'),'对一名势力不同的其他角色造成1点伤害',function(card,player,target){ - return target.group!=player.group; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('spwanggui',target); - target.damage(); - } - else player.storage.counttrigger.spwanggui--; - }, - group:'spwanggui_draw', - subSkill:{ - draw:{ - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('spwanggui'),'令自己摸一张牌,或和一名势力相同的其他角色各摸一张牌',function(card,player,target){ - return target.group==player.group; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target!=player) att*=2; - if(target.hasSkillTag('nogain')) att/=1.7; - return att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('spwanggui',target); - if(player==target){ - player.draw(); - event.finish(); - } - else{ - var list=[player,target].sortBySeat(); - game.asyncDraw(list); - } + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("spwanggui"), + "对一名势力不同的其他角色造成1点伤害", + function (card, player, target) { + return target.group != player.group; } - else event.finish(); - 'step 2' + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }) + .forResult(); + }, + async content(event, trigger, player) { + const target = event.targets[0]; + target.damage(); + }, + group: "spwanggui_draw", + subSkill: { + draw: { + trigger: { player: "damageEnd" }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("spwanggui"), + "令自己摸一张牌,或和一名势力相同的其他角色各摸一张牌", + function (card, player, target) { + return target.group == player.group; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target != player) att *= 2; + if (target.hasSkillTag("nogain")) att /= 1.7; + return att; + }) + .forResult(); + }, + content: function () { + "step 0"; + var target = targets[0]; + if (player == target) { + player.draw(); + event.finish(); + } else { + var list = [player, target].sortBySeat(); + game.asyncDraw(list); + } + "step 1"; game.delayx(); }, }, }, }, - wanggui:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + wanggui: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - direct:true, - filter:function(event,player){ - return player.hasSkill('wanggui')&&!player.hasSkill('wanggui2'); + direct: true, + filter: function (event, player) { + return player.hasSkill("wanggui") && !player.hasSkill("wanggui2"); }, - preHidden:true, - content:function(){ - 'step 0' - player.addTempSkill('wanggui2'); - var bool=player.isUnseen(2); - if(bool){ - player.chooseTarget('望归:是否对一名势力不同的角色造成1点伤害?',function(card,player,target){ - return target.isEnemyOf(player); - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }).setHiddenSkill('wanggui'); - } - else event.goto(2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('wanggui',target); + preHidden: true, + content: function () { + "step 0"; + player.addTempSkill("wanggui2"); + var bool = player.isUnseen(2); + if (bool) { + player + .chooseTarget( + "望归:是否对一名势力不同的角色造成1点伤害?", + function (card, player, target) { + return target.isEnemyOf(player); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }) + .setHiddenSkill("wanggui"); + } else event.goto(2); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("wanggui", target); target.damage(); } event.finish(); - 'step 2' - player.chooseBool('望归:是否令所有与自己势力相同的角色各摸一张牌?').setHiddenSkill('wanggui'); - 'step 3' - if(result.bool){ - var targets=game.filterPlayer(function(current){ + "step 2"; + player + .chooseBool("望归:是否令所有与自己势力相同的角色各摸一张牌?") + .setHiddenSkill("wanggui"); + "step 3"; + if (result.bool) { + var targets = game.filterPlayer(function (current) { return current.isFriendOf(player); }); targets.sortBySeat(); - player.logSkill('wanggui',targets); + player.logSkill("wanggui", targets); game.asyncDraw(targets); - } - else event.finish(); - 'step 4' + } else event.finish(); + "step 4"; game.delayx(); }, }, - wanggui2:{}, - xibing:{ - audio:2, - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(player==event.player||event.targets.length!=1||event.player.countCards('h')>=event.player.hp) return false; - var bool=function(card){ - return (card.name=='sha'||get.type(card,false)=='trick')&&get.color(card,false)=='black'; + wanggui2: {}, + xibing: { + audio: 2, + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if ( + player == event.player || + event.targets.length != 1 || + event.player.countCards("h") >= event.player.hp + ) + return false; + var bool = function (card) { + return ( + (card.name == "sha" || get.type(card, false) == "trick") && + get.color(card, false) == "black" + ); }; - if(!bool(event.card)) return false; - var evt=event.getParent('phaseUse'); - if(evt.player!=event.player) return false; - return get.mode()!='guozhan'||event.player.getHistory('useCard',function(evtx){ - return bool(evtx.card)&&evtx.getParent('phaseUse')==evt; - })[0]==event.getParent(); + if (!bool(event.card)) return false; + var evt = event.getParent("phaseUse"); + if (evt.player != event.player) return false; + return ( + get.mode() != "guozhan" || + event.player.getHistory("useCard", function (evtx) { + return bool(evtx.card) && evtx.getParent("phaseUse") == evt; + })[0] == event.getParent() + ); }, - logTarget:'player', - check:function(event,player){ - var target=event.player; - var att=get.attitude(player,target); - var num2=Math.min(5,target.hp-target.countCards('h')); - if(num2<=0) return att<=0; - var num=target.countCards('h',function(card){ - return target.hasValueTarget(card,null,true); + logTarget: "player", + check: function (event, player) { + var target = event.player; + var att = get.attitude(player, target); + var num2 = Math.min(5, target.hp - target.countCards("h")); + if (num2 <= 0) return att <= 0; + var num = target.countCards("h", function (card) { + return target.hasValueTarget(card, null, true); }); - if(!num) return att>0; - return num>num2; + if (!num) return att > 0; + return num > num2; }, - preHidden:true, - content:function(){ - 'step 0' - var num=Math.min(5,trigger.player.hp-trigger.player.countCards('h')); - if(num>0) trigger.player.draw(num); - 'step 1' - trigger.player.addTempSkill('xibing2'); - player._xibing=true; - if(get.mode()!='guozhan'||player.isUnseen(2)||trigger.player.isUnseen(2)) event.finish(); - 'step 2' - var target=trigger.player; - var players1=[player.name1,player.name2]; - var players2=[target.name1,target.name2]; - player.chooseButton(2,[ - '是否暗置自己和'+get.translation(target)+'的各一张武将牌?', - '
              你的武将牌
              ', - [players1,'character'], - '
              '+get.translation(target)+'的武将牌
              ', - [players2,'character'], - ]).set('players',players1).set('complexSelect',true).set('filterButton',function(button){ - return !get.is.jun(button.link)&&(ui.selected.buttons.length==0)==(_status.event.players.includes(button.link)); - }); - 'step 3' - if(result.bool){ - var target=trigger.player; - player.hideCharacter(player.name1==result.links[0]?0:1); - target.hideCharacter(target.name1==result.links[1]?0:1); - player.addTempSkill('xibing3'); - target.addTempSkill('xibing3'); + preHidden: true, + content: function () { + "step 0"; + var num = Math.min(5, trigger.player.hp - trigger.player.countCards("h")); + if (num > 0) trigger.player.draw(num); + "step 1"; + trigger.player.addTempSkill("xibing2"); + player._xibing = true; + if (get.mode() != "guozhan" || player.isUnseen(2) || trigger.player.isUnseen(2)) + event.finish(); + "step 2"; + var target = trigger.player; + var players1 = [player.name1, player.name2]; + var players2 = [target.name1, target.name2]; + player + .chooseButton(2, [ + "是否暗置自己和" + get.translation(target) + "的各一张武将牌?", + '
              你的武将牌
              ', + [players1, "character"], + '
              ' + get.translation(target) + "的武将牌
              ", + [players2, "character"], + ]) + .set("players", players1) + .set("complexSelect", true) + .set("filterButton", function (button) { + return ( + !get.is.jun(button.link) && + (ui.selected.buttons.length == 0) == + _status.event.players.includes(button.link) + ); + }); + "step 3"; + if (result.bool) { + var target = trigger.player; + player.hideCharacter(player.name1 == result.links[0] ? 0 : 1); + target.hideCharacter(target.name1 == result.links[1] ? 0 : 1); + player.addTempSkill("xibing3"); + target.addTempSkill("xibing3"); } }, }, - xibing2:{ - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + xibing2: { + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, }, }, - xibing3:{ - ai:{nomingzhi:true}, + xibing3: { + ai: { nomingzhi: true }, }, //小虎 - remeibu:{ - audio:"meibu", - trigger:{ - global:"phaseUseBegin", + remeibu: { + audio: "meibu", + trigger: { + global: "phaseUseBegin", }, - filter:function(event,player){ - return event.player!=player&&event.player.isIn()&&event.player.inRange(player)&&player.countCards('he')>0; + filter: function (event, player) { + return ( + event.player != player && + event.player.isIn() && + event.player.inRange(player) && + player.countCards("he") > 0 + ); }, - direct:true, - derivation:["rezhixi"], - checkx:function(event,player){ - if(get.attitude(player,event.player)>=0) return false; - return event.player.countCards('h')>event.player.hp; + direct: true, + derivation: ["rezhixi"], + checkx: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + return event.player.countCards("h") > event.player.hp; }, - content:function(){ - "step 0" - var check=lib.skill.new_meibu.checkx(trigger,player); - player.chooseToDiscard(get.prompt2('remeibu',trigger.player),'he').set('ai',function(card){ - if(_status.event.check) return 6-get.value(card); - return 0; - }).set('check',check).set('logSkill',['remeibu',trigger.player]); - "step 1" - if(result.bool){ - var target=trigger.player; - var card=result.cards[0]; - player.line(target,'green'); - player.markAuto('remeibu_gain',[get.suit(card,player)]); - player.addTempSkill('remeibu_gain'); - target.addTempSkills('rezhixi','phaseUseEnd'); + content: function () { + "step 0"; + var check = lib.skill.new_meibu.checkx(trigger, player); + player + .chooseToDiscard(get.prompt2("remeibu", trigger.player), "he") + .set("ai", function (card) { + if (_status.event.check) return 6 - get.value(card); + return 0; + }) + .set("check", check) + .set("logSkill", ["remeibu", trigger.player]); + "step 1"; + if (result.bool) { + var target = trigger.player; + var card = result.cards[0]; + player.line(target, "green"); + player.markAuto("remeibu_gain", [get.suit(card, player)]); + player.addTempSkill("remeibu_gain"); + target.addTempSkills("rezhixi", "phaseUseEnd"); } }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, - subSkill:{ - gain:{ - trigger:{global:'loseAfter'}, - forced:true, - charlotte:true, - popup:false, - onremove:true, - filter:function(event,player){ - return event.getParent(3).name=='rezhixi'&&player.getStorage('remeibu_gain').includes(get.suit(event.cards[0],event.player))&&get.position(event.cards[0])=='d'; + subSkill: { + gain: { + trigger: { global: "loseAfter" }, + forced: true, + charlotte: true, + popup: false, + onremove: true, + filter: function (event, player) { + return ( + event.getParent(3).name == "rezhixi" && + player + .getStorage("remeibu_gain") + .includes(get.suit(event.cards[0], event.player)) && + get.position(event.cards[0]) == "d" + ); }, - content:function(){ - player.gain(trigger.cards[0],'gain2'); + content: function () { + player.gain(trigger.cards[0], "gain2"); }, }, }, }, - remumu:{ - audio:"mumu", - trigger:{ - player:"phaseUseBegin", + remumu: { + audio: "mumu", + trigger: { + player: "phaseUseBegin", }, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('e')>0; + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("e") > 0; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('remumu'),function(card,player,target){ - return target.countCards('e')>0; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target),es=target.getCards('e'),val=0; - for(var i of es){ - var eff=-(get.value(i,target)-0.1)*att; - if(eff>val) val=eff; + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("remumu"), function (card, player, target) { + return target.countCards("e") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target), + es = target.getCards("e"), + val = 0; + for (var i of es) { + var eff = -(get.value(i, target) - 0.1) * att; + if (eff > val) val = eff; + } + return eff; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("remumu", target); + if (player == target) event._result = { index: 1 }; + else { + var str = get.translation(target); + player + .chooseControl() + .set("choiceList", [ + "弃置" + str + "装备区的一张牌且本阶段使用【杀】的次数上限+1", + "获得" + str + "装备区的一张牌且本阶段使用【杀】的次数上限-1", + ]) + .set("ai", function () { + var player = _status.event.player; + if ( + player.countCards("hs", function (card) { + return ( + get.name(card, player) == "sha" && player.hasValueTarget(card) + ); + }) < Math.max(1, player.getCardUsable("sha")) + ) + return 1; + return 0; + }); } - return eff; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('remumu',target); - if(player==target) event._result={index:1}; - else{ - var str=get.translation(target); - player.chooseControl().set('choiceList',[ - '弃置'+str+'装备区的一张牌且本阶段使用【杀】的次数上限+1', - '获得'+str+'装备区的一张牌且本阶段使用【杀】的次数上限-1', - ]).set('ai',function(){ - var player=_status.event.player; - if(player.countCards('hs',function(card){ - return get.name(card,player)=='sha'&&player.hasValueTarget(card); - })0; + forced: true, + filter: function (event, player) { + return ( + (event.card.name == "sha" || get.type(event.card) == "trick") && + player.countCards("h") > 0 + ); }, - content:function(){ - player.chooseToDiscard('h',true); + content: function () { + player.chooseToDiscard("h", true); }, }, //董白 - relianzhu:{ - audio:'lianzhu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + relianzhu: { + audio: "lianzhu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - discard:false, - lose:false, - delay:false, - position:'he', - filterTarget:lib.filter.notMe, - check:function(card){ - var num=get.value(card); - if(get.color(card)=='black'){ - if(num>=6) return 0; - return 9-num; - } - else{ - return 7-num; + filterCard: true, + discard: false, + lose: false, + delay: false, + position: "he", + filterTarget: lib.filter.notMe, + check: function (card) { + var num = get.value(card); + if (get.color(card) == "black") { + if (num >= 6) return 0; + return 9 - num; + } else { + return 7 - num; } }, - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' - if(get.color(cards[0],player)=='red'){ + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + if (get.color(cards[0], player) == "red") { player.draw(); event.finish(); + } else { + target + .chooseToDiscard( + "he", + 2, + "弃置两张牌,或令" + get.translation(player) + "摸两张牌" + ) + .set("goon", get.attitude(target, player) < 0) + .set("ai", function (card) { + if (!_status.event.goon) return -get.value(card); + return 6 - get.value(card); + }); } - else{ - target.chooseToDiscard('he',2,'弃置两张牌,或令'+get.translation(player)+'摸两张牌').set('goon',get.attitude(target,player)<0).set('ai',function(card){ - if(!_status.event.goon) return -get.value(card); - return 6-get.value(card); - }); - } - 'step 2' - if(!result.bool) player.draw(2); + "step 2"; + if (!result.bool) player.draw(2); }, - ai:{ - order:3, - expose:0.2, - result:{ - target:function(player,target){ - if(ui.selected.cards.length&&get.color(ui.selected.cards[0])=='red'){ - if(target.countCards('h')0; + }, + rexiahui: { + audio: "xiahui", + mod: { + ignoredHandcard: function (card, player) { + if (get.color(card, player) == "black") return true; + }, + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.color(card, player) == "black") return false; + }, }, - content:function(){ + trigger: { global: "phaseEnd" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + var target = event.player; + return ( + target != player && + target.countCards("h", function (card) { + return card.hasGaintag("rexiahui"); + }) == 0 && + target.getHistory("lose", function (evt) { + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("rexiahui")) return true; + } + }).length > 0 + ); + }, + content: function () { trigger.player.loseHp(); }, - group:'rexiahui_gain', - subSkill:{ - gain:{ - trigger:{global:'gainEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - if(player==event.player) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.filter(function(card){ - return get.color(card,player)=='black'; - }).length>0; + group: "rexiahui_gain", + subSkill: { + gain: { + trigger: { global: "gainEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + if (player == event.player) return false; + var evt = event.getl(player); + return ( + evt && + evt.cards2 && + evt.cards2.filter(function (card) { + return get.color(card, player) == "black"; + }).length > 0 + ); }, - content:function(){ - trigger.player.addSkill('rexiahui_block'); - var cards=trigger.getl(player).cards2.filter(function(card){ - return get.color(card,player)=='black'; + content: function () { + trigger.player.addSkill("rexiahui_block"); + var cards = trigger.getl(player).cards2.filter(function (card) { + return get.color(card, player) == "black"; }); - trigger.player.addGaintag(cards,'rexiahui'); + trigger.player.addGaintag(cards, "rexiahui"); }, }, - block:{ - mod:{ - cardEnabled2:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('rexiahui')) return false; + block: { + mod: { + cardEnabled2: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("rexiahui")) return false; }, - cardDiscardable:function(card){ - if(card.hasGaintag('rexiahui')) return false; + cardDiscardable: function (card) { + if (card.hasGaintag("rexiahui")) return false; }, }, - charlotte:true, - forced:true, - popup:false, - trigger:{player:'changeHp'}, - filter:function(event,player){ - return event.num<0; + charlotte: true, + forced: true, + popup: false, + trigger: { player: "changeHp" }, + filter: function (event, player) { + return event.num < 0; }, - content:function(){ - player.removeSkill('rexiahui_block'); + content: function () { + player.removeSkill("rexiahui_block"); }, - onremove:function(player){ - player.removeGaintag('rexiahui'); + onremove: function (player) { + player.removeGaintag("rexiahui"); }, }, }, }, //周善 - dcmiyun:{ - audio:2, - trigger:{global:'roundStart'}, - forced:true, - direct:true, - group:'dcmiyun_lose', - content:function(){ - 'step 0' - if(player.hasCard(card=>card.hasGaintag('dcmiyun_tag'),'h')){ + dcmiyun: { + audio: 2, + trigger: { global: "roundStart" }, + forced: true, + direct: true, + group: "dcmiyun_lose", + content: function () { + "step 0"; + if (player.hasCard((card) => card.hasGaintag("dcmiyun_tag"), "h")) { player.chooseCardTarget({ - prompt:'密运:将包括“安”在内的任意张手牌交给一名其他角色', - forced:true, - filterTarget:lib.filter.notMe, - selectCard:[1,Infinity], - filterOk:function(){ - for(var card of ui.selected.cards){ - if(card.hasGaintag('dcmiyun_tag')) return true; + prompt: "密运:将包括“安”在内的任意张手牌交给一名其他角色", + forced: true, + filterTarget: lib.filter.notMe, + selectCard: [1, Infinity], + filterOk: function () { + for (var card of ui.selected.cards) { + if (card.hasGaintag("dcmiyun_tag")) return true; } return false; }, - goon:game.hasPlayer(current=>player!=current&&get.attitude(player,current)>0), - ai1:function(card){ - if(get.itemtype(card)!='card') return 0; - if(card.hasGaintag('dcmiyun_tag')) return 100; - if(_status.event.goon) return 8-get.value(card); + goon: game.hasPlayer( + (current) => player != current && get.attitude(player, current) > 0 + ), + ai1: function (card) { + if (get.itemtype(card) != "card") return 0; + if (card.hasGaintag("dcmiyun_tag")) return 100; + if (_status.event.goon) return 8 - get.value(card); return -get.value(card); }, - ai2:function(target){ - return get.attitude(_status.event.player,target); - } + ai2: function (target) { + return get.attitude(_status.event.player, target); + }, }); - } - else event.goto(3); - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.logSkill('dcmiyun',target); - player.give(cards,target); - } - else event.goto(3); - 'step 2' + } else event.goto(3); + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.logSkill("dcmiyun", target); + player.give(cards, target); + } else event.goto(3); + "step 2"; player.drawTo(player.maxHp); - 'step 3' - if(game.hasPlayer(current=>current!=player&¤t.countGainableCards(player,'he'))){ - player.chooseTarget('密运:获得一名其他角色的一张牌,称为“安”',true,(card,player,target)=>{ - return target!=player&&target.countGainableCards(player,'he'); - }).set('ai',target=>{ - return get.effect(target,{name:'shunshou'},_status.event.player,_status.event.player); - }) - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcmiyun',target); - player.gainPlayerCard(target,true,'visibleMove').chooseonly=true; - } - else event.finish(); - 'step 5' - if(result.bool){ - player.gain(result.cards).gaintag.add('dcmiyun_tag'); + "step 3"; + if ( + game.hasPlayer( + (current) => current != player && current.countGainableCards(player, "he") + ) + ) { + player + .chooseTarget( + "密运:获得一名其他角色的一张牌,称为“安”", + true, + (card, player, target) => { + return target != player && target.countGainableCards(player, "he"); + } + ) + .set("ai", (target) => { + return get.effect( + target, + { name: "shunshou" }, + _status.event.player, + _status.event.player + ); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcmiyun", target); + player.gainPlayerCard(target, true, "visibleMove").chooseonly = true; + } else event.finish(); + "step 5"; + if (result.bool) { + player.gain(result.cards).gaintag.add("dcmiyun_tag"); } }, - mod:{ - aiValue:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcmiyun_tag')) return Math.abs(num)*10; + mod: { + aiValue: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcmiyun_tag")) + return Math.abs(num) * 10; }, - aiUseful:function(){ - return lib.skill.dcmiyun.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.dcmiyun.mod.aiValue.apply(this, arguments); + }, + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcmiyun_tag")) return 0; }, - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcmiyun_tag')) return 0; - } }, - subSkill:{ - lose:{ - audio:'dcmiyun', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + lose: { + audio: "dcmiyun", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - if(event.getParent().name=='dcmiyun') return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dcmiyun_tag')) return true; + forced: true, + filter: function (event, player) { + if (event.getParent().name == "dcmiyun") return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dcmiyun_tag")) return true; } return false; } - return player.hasHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcmiyun_tag')) return true; + return player.hasHistory("lose", (evt) => { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcmiyun_tag")) return true; } return false; }); }, - content:function(){ + content: function () { player.loseHp(); - } - } - } + }, + }, + }, }, - 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); - } + 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){ - if(!_status.connectMode&&!player.hasCard(card=>card.hasGaintag('dcmiyun_tag'),'h')) return false; - return name=='sha'||name=='shan'; + locked: false, + enable: ["chooseToUse", "chooseToRespond"], + usable: 1, + hiddenCard: function (player, name) { + if ( + !_status.connectMode && + !player.hasCard((card) => card.hasGaintag("dcmiyun_tag"), "h") + ) + return false; + return name == "sha" || name == "shan"; }, - filter:function(event,player){ - if(event.type=='wuxie'||!player.hasCard(card=>card.hasGaintag('dcmiyun_tag'),'h')) return false; - for(var name of ['sha','shan']){ - if(event.filterCard({name:name,isCard:true},player,event)) return true; + filter: function (event, player) { + if ( + event.type == "wuxie" || + !player.hasCard((card) => card.hasGaintag("dcmiyun_tag"), "h") + ) + return false; + for (var name of ["sha", "shan"]) { + if (event.filterCard({ name: name, isCard: true }, player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var vcards=[]; - for(var name of ['sha','shan']){ - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); + chooseButton: { + dialog: function (event, player) { + var vcards = []; + for (var name of ["sha", "shan"]) { + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); } - var dialog=ui.create.dialog('胆迎',[vcards,'vcard'],'hidden'); - dialog.direct=true; + var dialog = ui.create.dialog("胆迎", [vcards, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:()=>false, - selectCard:-1, - viewAs:{ - name:links[0][2], - isCard:true, + filterCard: () => false, + selectCard: -1, + viewAs: { + name: links[0][2], + isCard: true, }, - popname:true, - precontent:function(){ - player.logSkill('dcdanying'); - player.showCards(player.getCards('h',card=>card.hasGaintag('dcmiyun_tag')),get.translation(player)+'的“安”'); - player.addTempSkill('dcdanying_discard'); + popname: true, + precontent: function () { + player.logSkill("dcdanying"); + player.showCards( + player.getCards("h", (card) => card.hasGaintag("dcmiyun_tag")), + get.translation(player) + "的“安”" + ); + player.addTempSkill("dcdanying_discard"); }, - } + }; + }, + prompt: function (links, player) { + return "展示“安”,然后视为使用【" + get.translation(links[0][2]) + "】"; }, - prompt:function(links,player){ - return '展示“安”,然后视为使用【'+get.translation(links[0][2])+'】'; - } }, - ai:{ - order:function(item,player){ - var o1=get.order({name:'sha'}),o2=get.order({name:'shan'}); - if(player.countCards('h')>3||player==_status.currentPhase) return Math.max(o1,o2)+0.1; - return Math.min(o1,o2)-0.1; + ai: { + order: function (item, player) { + var o1 = get.order({ name: "sha" }), + o2 = get.order({ name: "shan" }); + if (player.countCards("h") > 3 || player == _status.currentPhase) + return Math.max(o1, o2) + 0.1; + return Math.min(o1, o2) - 0.1; }, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(!player.hasCard(card=>card.hasGaintag('dcmiyun_tag'),'h')) return false; + combo: "dcmiyun", + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (!player.hasCard((card) => card.hasGaintag("dcmiyun_tag"), "h")) return false; + }, + result: { + player: 1, }, - result:{ - player:1 - } }, - subSkill:{ - discard:{ - trigger:{target:'useCardToTargeted'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player.countDiscardableCards(event.player,'he'); + subSkill: { + discard: { + trigger: { target: "useCardToTargeted" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return player.countDiscardableCards(event.player, "he"); }, - content:function(){ - trigger.player.discardPlayerCard(player,'he',true); - player.removeSkill('dcdanying_discard'); + content: function () { + trigger.player.discardPlayerCard(player, "he", true); + player.removeSkill("dcdanying_discard"); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(_status._dcdanying_aiChecking) return; - _status._dcdanying_aiChecking=true; - let eff=get.effect(target,{name:'guohe_copy2'},player,player); + ai: { + effect: { + target: function (card, player, target) { + if (_status._dcdanying_aiChecking) return; + _status._dcdanying_aiChecking = true; + let eff = get.effect(target, { name: "guohe_copy2" }, player, player); delete _status._dcdanying_aiChecking; - return [1,get.sgn(eff)]; - } - } - } - } + return [1, get.sgn(eff)]; + }, + }, + }, + }, }, }, //蔡阳 - dcxunji:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&!player.getStorage('dcxunji_effect').includes(target); + dcxunji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && !player.getStorage("dcxunji_effect").includes(target); }, - content:function(){ - player.markAuto('dcxunji_effect',[target]); - player.addTempSkill('dcxunji_effect',{player:'die'}); - target.addTempSkill('dcxunji_mark',{player:'phaseEnd'}); + content: function () { + player.markAuto("dcxunji_effect", [target]); + player.addTempSkill("dcxunji_effect", { player: "die" }); + target.addTempSkill("dcxunji_mark", { player: "phaseEnd" }); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.hp<2) return 0; - return get.effect(target,{name:'juedou'},player,player); + ai: { + order: 1, + result: { + player: function (player, target) { + if (player.hp < 2) return 0; + return get.effect(target, { name: "juedou" }, player, player); }, }, }, - subSkill:{ - mark:{ - mark:true, - marktext:'嫉', - intro:{content:'你已经被盯上了!'}, + subSkill: { + mark: { + mark: true, + marktext: "嫉", + intro: { content: "你已经被盯上了!" }, }, - effect:{ - audio:'dcxunji', - charlotte:true, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - popup:false, - onremove:true, - filter:function(event,player){ - return player.getStorage('dcxunji_effect').includes(event.player); + effect: { + audio: "dcxunji", + charlotte: true, + trigger: { global: "phaseJieshuBegin" }, + forced: true, + popup: false, + onremove: true, + filter: function (event, player) { + return player.getStorage("dcxunji_effect").includes(event.player); }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - if(target.getHistory('useCard',evt=>get.color(evt.card)=='black').length>0&&player.canUse('juedou',target)){ - player.useCard({name:'juedou',isCard:true},target,'dcxunji_effect'); + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + if ( + target.getHistory("useCard", (evt) => get.color(evt.card) == "black").length > + 0 && + player.canUse("juedou", target) + ) { + player.useCard({ name: "juedou", isCard: true }, target, "dcxunji_effect"); } - 'step 1' - player.unmarkAuto('dcxunji_effect',[target]); - if(!player.storage.dcxunji_effect.length) player.removeSkill('dcxunji_effect'); + "step 1"; + player.unmarkAuto("dcxunji_effect", [target]); + if (!player.storage.dcxunji_effect.length) player.removeSkill("dcxunji_effect"); }, - group:'dcxunji_loseHp', + group: "dcxunji_loseHp", }, - loseHp:{ - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='juedou'&&event.getParent().skill=='dcxunji_effect'&&event.player.isIn(); + loseHp: { + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.name == "juedou" && + event.getParent().skill == "dcxunji_effect" && + event.player.isIn() + ); }, - content:function(){ + content: function () { trigger.player.line(player); - player.damage(trigger.num,trigger.player); + player.damage(trigger.num, trigger.player); }, }, }, }, - dcjiaofeng:{ - audio:2, - trigger:{source:'damageBegin1'}, - forced:true, - usable:1, - filter:function(event,player){ - return player.isDamaged()&&!player.getHistory('sourceDamage').length; + dcjiaofeng: { + audio: 2, + trigger: { source: "damageBegin1" }, + forced: true, + usable: 1, + filter: function (event, player) { + return player.isDamaged() && !player.getHistory("sourceDamage").length; }, - content:function(){ - var num=player.getDamagedHp(); - if(num>0) player.draw(); - if(num>1) trigger.num++; - if(num>2) player.recover(); + content: function () { + var num = player.getDamagedHp(); + if (num > 0) player.draw(); + if (num > 1) trigger.num++; + if (num > 2) player.recover(); }, }, //夏侯杰 - liedan:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return (player!=event.player||player.countMark('liedan')>4)&&!player.hasSkill('zhuangdan_mark'); + liedan: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + (player != event.player || player.countMark("liedan") > 4) && + !player.hasSkill("zhuangdan_mark") + ); }, - logTarget:'player', - content:function(){ - if(player==trigger.player){ + logTarget: "player", + content: function () { + if (player == trigger.player) { player.die(); return; } - var num=0; - if(player.hp>trigger.player.hp) num++; - if(player.countCards('h')>trigger.player.countCards('h')) num++; - if(player.countCards('e')>trigger.player.countCards('e')) num++; - if(num){ + var num = 0; + if (player.hp > trigger.player.hp) num++; + if (player.countCards("h") > trigger.player.countCards("h")) num++; + if (player.countCards("e") > trigger.player.countCards("e")) num++; + if (num) { player.draw(num); - if(num==3&&player.maxHp<8) player.gainMaxHp(); - } - else{ - player.addMark('liedan',1); + if (num == 3 && player.maxHp < 8) player.gainMaxHp(); + } else { + player.addMark("liedan", 1); player.loseHp(); } }, - intro:{content:'mark'}, + intro: { content: "mark" }, }, - zhuangdan:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&player.isMaxHandcard(true); + zhuangdan: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return player != event.player && player.isMaxHandcard(true); }, - content:function(){ - player.addTempSkill('zhuangdan_mark',{player:'phaseEnd'}) + content: function () { + player.addTempSkill("zhuangdan_mark", { player: "phaseEnd" }); + }, + ai: { + combo: "zhuangdan", }, }, - zhuangdan_mark:{ - mark:true, - marktext:'胆', - intro:{content:'我超勇的'}, + zhuangdan_mark: { + mark: true, + marktext: "胆", + intro: { content: "我超勇的" }, }, //乌巢酒仙 - recangchu:{ - audio:2, - trigger:{global:'phaseBefore',player:'enterGame'}, - marktext:'粮', - forced:true, - filter:function(event,player){ - if(event.name=='phase'&&game.phaseNumber!=0) return false; - return player.countMark('recangchu')0; + forced: true, + usable: 1, + filter: function (event, player) { + return ( + player != _status.currentPhase && + player.countMark("recangchu") < game.countPlayer() && + event.getg(player).length > 0 + ); }, - content:function(){ - player.addMark('recangchu',1); + content: function () { + player.addMark("recangchu", 1); }, }, - recangchu3:{ - audio:'recangchu', - trigger:{global:'die'}, - forced:true, - filter:function(event,player){ - return player.countMark('recangchu')>game.countPlayer(); + recangchu3: { + audio: "recangchu", + trigger: { global: "die" }, + forced: true, + filter: function (event, player) { + return player.countMark("recangchu") > game.countPlayer(); }, - content:function(){ - player.removeMark('recangchu',player.countMark('recangchu')-game.countPlayer()); + content: function () { + player.removeMark("recangchu", player.countMark("recangchu") - game.countPlayer()); }, }, - reliangying:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - filter(event,player){ - return player.hasMark('recangchu'); + reliangying: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + filter(event, player) { + return player.hasMark("recangchu"); }, - direct:true, - async content(event,trigger,player){ - const draws=Array.from({length:player.countMark('recangchu')}).map((_,i)=>get.cnNumber(i+1)+'张'); - const {result:{control}}=await player.chooseControl(draws,'cancel2').set('prompt',get.prompt('reliangying')) - .set('prompt2','摸至多'+get.cnNumber(player.countMark('recangchu'))+'张牌,然后交给等量的角色各一张牌').set('ai',()=>{ - const player=get.event('player'); - const num=Math.min(player.countMark('recangchu'),game.countPlayer(current=>get.attitude(player,current)>0)); - if(num>0) return get.cnNumber(num)+'张'; - return 'cancel2'; - }); - if(control!='cancel2'){ - player.logSkill('reliangying'); - const num=draws.indexOf(control)+1,max=Math.min(num,player.countCards('he'),game.countPlayer(target=>target!=player)); + direct: true, + async content(event, trigger, player) { + const draws = Array.from({ length: player.countMark("recangchu") }).map( + (_, i) => get.cnNumber(i + 1) + "张" + ); + const { + result: { control }, + } = await player + .chooseControl(draws, "cancel2") + .set("prompt", get.prompt("reliangying")) + .set( + "prompt2", + "摸至多" + + get.cnNumber(player.countMark("recangchu")) + + "张牌,然后交给等量的角色各一张牌" + ) + .set("ai", () => { + const player = get.event("player"); + const num = Math.min( + player.countMark("recangchu"), + game.countPlayer((current) => get.attitude(player, current) > 0) + ); + if (num > 0) return get.cnNumber(num) + "张"; + return "cancel2"; + }); + if (control != "cancel2") { + player.logSkill("reliangying"); + const num = draws.indexOf(control) + 1, + max = Math.min( + num, + player.countCards("he"), + game.countPlayer((target) => target != player) + ); await player.draw(num); - let list=[]; - while(max-list.length>0){ - const {result:{bool,cards,targets}}=await player.chooseCardTarget({ - prompt:'粮营:将'+get.cnNumber(max-1)+'至'+get.cnNumber(max)+'张牌交给其他角色', - position:'he', - animate:false, - filterCard(card,player){ - return !get.event('list').some(list=>list[1]==card); - }, - filterTarget(card,player,target){ - return target!=player&&!get.event('list').some(list=>list[0]==target); - }, - ai1(card){ - if(card.name=='shan') return 1; - return Math.random(); - }, - ai2(target){ - return get.attitude(get.event('player'),target); - }, - }).set('list',list).set('forced',max-list.length>1); - if(bool){ - list.push([targets[0],cards[0]]); - player.addGaintag(cards,'olsujian_given'); - } - else break; + let list = []; + if (_status.connectMode) game.broadcastAll(() => (_status.noclearcountdown = true)); + while (max - list.length > 0) { + const { + result: { bool, cards, targets }, + } = await player + .chooseCardTarget({ + prompt: + "粮营:将" + + get.cnNumber(max - 1) + + "至" + + get.cnNumber(max) + + "张牌交给其他角色", + position: "he", + animate: false, + filterCard(card, player) { + return !get.event("list").some((list) => list[1] == card); + }, + filterTarget(card, player, target) { + return ( + target != player && + !get.event("list").some((list) => list[0] == target) + ); + }, + ai1(card) { + if (card.name == "shan") return 1; + return Math.random(); + }, + ai2(target) { + return get.attitude(get.event("player"), target); + }, + }) + .set("list", list) + .set("forced", max - list.length > 1); + if (bool) { + list.push([targets[0], cards[0]]); + player.addGaintag(cards, "olsujian_given"); + } else break; } - if(list.length){ - await game.loseAsync({ - gain_list:list, - player:player, - cards:list.slice().map(list=>list[1]), - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + if (list.length) { + await game + .loseAsync({ + gain_list: list, + player: player, + cards: list.slice().map((list) => list[1]), + giver: player, + animate: "giveAuto", + }) + .setContent("gaincardMultiple"); } } }, }, - reshishou:{ - audio:2, - trigger:{player:['useCard','damageEnd']}, - forced:true, - filter:function(event,player){ - if(!player.countMark('recangchu')) return false; - return (event.name=='damage')?event.hasNature('fire'):(event.card&&event.card.name=='jiu'); + reshishou: { + audio: 2, + trigger: { player: ["useCard", "damageEnd"] }, + forced: true, + filter: function (event, player) { + if (!player.countMark("recangchu")) return false; + return event.name == "damage" + ? event.hasNature("fire") + : event.card && event.card.name == "jiu"; }, - content:function(){ - player.removeMark('recangchu',Math.min(player.countMark('recangchu'),trigger.num||1)); + content: function () { + player.removeMark("recangchu", Math.min(player.countMark("recangchu"), trigger.num || 1)); }, - group:'reshishou2', + ai: { + combo: "recangchu", + neg: true + }, + group: "reshishou2", }, - reshishou2:{ - audio:'reshishou', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return !player.countMark('recangchu'); + reshishou2: { + audio: "reshishou", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return !player.countMark("recangchu"); }, - content:function(){ + content: function () { player.loseHp(); }, }, //曹性 - cxliushi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he',{suit:'heart'})>0; + cxliushi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he", { suit: "heart" }) > 0; }, - filterCard:{suit:'heart'}, - position:'he', - filterTarget:function(card,player,target){ - return player.canUse('sha',target,false); + filterCard: { suit: "heart" }, + position: "he", + filterTarget: function (card, player, target) { + return player.canUse("sha", target, false); }, - check:function(card){ - var player=_status.event.player; - var next=player.getNext(); - var att=get.attitude(player,next); - if(att>0){ - var js=next.getCards('j'); - if(js.length) return get.judge(js[0])+10-get.value(card); - return 9-get.value(card) + check: function (card) { + var player = _status.event.player; + var next = player.getNext(); + var att = get.attitude(player, next); + if (att > 0) { + var js = next.getCards("j"); + if (js.length) return get.judge(js[0]) + 10 - get.value(card); + return 9 - get.value(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - discard:false, - prepare:'throw', - loseTo:'cardPile', - visible:true, - insert:true, - content:function(){ - game.log(player,'将',cards,'置于牌堆顶'); - player.useCard({name:'sha',isCard:true},false,targets).card.cxliushi=true; + discard: false, + prepare: "throw", + loseTo: "cardPile", + visible: true, + insert: true, + content: function () { + game.log(player, "将", cards, "置于牌堆顶"); + player.useCard({ name: "sha", isCard: true }, false, targets).card.cxliushi = true; }, - group:'cxliushi_damage', - subSkill:{ - damage:{ - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.cxliushi==true&&event.player.isIn()&&event.getParent(3).name=='cxliushi'; + group: "cxliushi_damage", + subSkill: { + damage: { + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.cxliushi == true && + event.player.isIn() && + event.getParent(3).name == "cxliushi" + ); }, - content:function(){ - trigger.player.addMark('cxliushi2',1); - trigger.player.addSkill('cxliushi2'); + content: function () { + trigger.player.addMark("cxliushi2", 1); + trigger.player.addSkill("cxliushi2"); }, }, }, - ai:{ - order:function(){ - return get.order({name:'sha'})-0.4; + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.4; }, - result:{ - target:function(player,target){ - var eff=get.effect(target,{name:'sha'},player,target); - var damageEff=get.damageEffect(target,player,player); - if(eff>0) return damageEff>0?0:eff; - if(target.hasSkill('bagua_skill')||target.hasSkill('rw_bagua_skill')||target.hasSkill('bazhen')) return 0; + result: { + target: function (player, target) { + var eff = get.effect(target, { name: "sha" }, player, target); + var damageEff = get.damageEffect(target, player, player); + if (eff > 0) return damageEff > 0 ? 0 : eff; + if ( + target.hasSkill("bagua_skill") || + target.hasSkill("rw_bagua_skill") || + target.hasSkill("bazhen") + ) + return 0; return eff; }, }, }, }, - cxliushi2:{ - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('cxliushi2'); + cxliushi2: { + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("cxliushi2"); }, }, - onremove:true, - charlotte:true, - intro:{ - name2:'流', - content:'手牌上限-#', + onremove: true, + charlotte: true, + intro: { + name2: "流", + content: "手牌上限-#", }, }, - zhanwan:{ - audio:2, - trigger:{global:'phaseDiscardEnd'}, - forced:true, - filter:function(event,player){ - return event.player.hasSkill('cxliushi2')&&event.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event) return true; - }).length>0; + zhanwan: { + audio: 2, + trigger: { global: "phaseDiscardEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.player.hasSkill("cxliushi2") && + event.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) return true; + }).length > 0 + ); }, - logTarget:'player', - content:function(){ - trigger.player.removeSkill('cxliushi2'); - var num=0; - trigger.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) num+=evt.cards2.length; + logTarget: "player", + content: function () { + trigger.player.removeSkill("cxliushi2"); + var num = 0; + trigger.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + num += evt.cards2.length; }); player.draw(num); }, + ai: { + combo: "cxliushi", + }, }, //说出吾名吓汝一跳 - xuxie:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return get.distance(player,current)<=1; - }).sortBySeat(); + xuxie: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + logTarget: function (event, player) { + return game + .filterPlayer(function (current) { + return get.distance(player, current) <= 1; + }) + .sortBySeat(); }, - check:function(event,player){ - if(player.isHealthy()) return false; - var list=game.filterPlayer(function(current){ - return get.distance(player,current)<=1; + check: function (event, player) { + if (player.isHealthy()) return false; + var list = game.filterPlayer(function (current) { + return get.distance(player, current) <= 1; }); - var draw=0; - var discard=0; - var num=2/player.getDamagedHp(); - while(list.length){ - var target=list.shift(); - var att=get.attitude(player,target); - if(att>0){ + var draw = 0; + var discard = 0; + var num = 2 / player.getDamagedHp(); + while (list.length) { + var target = list.shift(); + var att = get.attitude(player, target); + if (att > 0) { draw++; - if(target.countDiscardableCards(player,'he')>0) discard--; + if (target.countDiscardableCards(player, "he") > 0) discard--; } - if(att==0){ + if (att == 0) { draw--; - if(target.countDiscardableCards(player,'he')>0) discard--; + if (target.countDiscardableCards(player, "he") > 0) discard--; } - if(att<0){ + if (att < 0) { draw--; - if(target.countDiscardableCards(player,'he')>0) discard++; + if (target.countDiscardableCards(player, "he") > 0) discard++; } } - return draw>=num||discard>=num; + return draw >= num || discard >= num; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' - var targets=game.filterPlayer(function(current){ - return get.distance(player,current)<=1; - }).sortBySeat(); - if(!targets.length) event.finish(); - else{ - event.targets=targets; - player.chooseControl().set('choiceList',[ - '弃置'+get.translation(targets)+'的各一张牌', - '令'+get.translation(targets)+'各摸一张牌', - ]).set('ai',function(){ - var player=_status.event.player; - var list=_status.event.getParent().targets.slice(0); - var draw=0; - var discard=0; - while(list.length){ - var target=list.shift(); - var att=get.attitude(player,target); - if(att>0){ - draw++; - if(target.countDiscardableCards(player,'he')>0) discard--; + "step 1"; + var targets = game + .filterPlayer(function (current) { + return get.distance(player, current) <= 1; + }) + .sortBySeat(); + if (!targets.length) event.finish(); + else { + event.targets = targets; + player + .chooseControl() + .set("choiceList", [ + "弃置" + get.translation(targets) + "的各一张牌", + "令" + get.translation(targets) + "各摸一张牌", + ]) + .set("ai", function () { + var player = _status.event.player; + var list = _status.event.getParent().targets.slice(0); + var draw = 0; + var discard = 0; + while (list.length) { + var target = list.shift(); + var att = get.attitude(player, target); + if (att > 0) { + draw++; + if (target.countDiscardableCards(player, "he") > 0) discard--; + } + if (att < 0) { + draw--; + if (target.countDiscardableCards(player, "he") > 0) discard++; + } } - if(att<0){ - draw--; - if(target.countDiscardableCards(player,'he')>0) discard++; - } - } - if(draw>discard) return 1; - return 0; - }); + if (draw > discard) return 1; + return 0; + }); } - 'step 2' - event.index=result.index; - if(result.index==1){ + "step 2"; + event.index = result.index; + if (result.index == 1) { game.asyncDraw(targets); - } - else event.goto(4); - 'step 3' + } else event.goto(4); + "step 3"; game.delay(); event.finish(); - 'step 4' - var target=targets.shift(); - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true); - if(targets.length) event.redo(); + "step 4"; + var target = targets.shift(); + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true); + if (targets.length) event.redo(); }, - group:'xuxie_add', + group: "xuxie_add", }, - xuxie_add:{ - audio:'xuxie', - trigger:{player:'phaseUseEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.maxHp>player.maxHp; + xuxie_add: { + audio: "xuxie", + trigger: { player: "phaseUseEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.maxHp > player.maxHp; }); }, - content:function(){ + content: function () { player.gainMaxHp(); - player.chooseDrawRecover(2,true); + player.chooseDrawRecover(2, true); }, }, //新潘凤 - xinkuangfu:{ - enable:'phaseUse', - usable:1, - audio:2, - delay:false, - filterTarget:function(card,player,target){ - if(player==target) return player.countCards('e',function(card){ - return lib.filter.cardDiscardable(card,player); - })>0; - return target.countDiscardableCards(player,'e')>0; + xinkuangfu: { + enable: "phaseUse", + usable: 1, + audio: 2, + delay: false, + filterTarget: function (card, player, target) { + if (player == target) + return ( + player.countCards("e", function (card) { + return lib.filter.cardDiscardable(card, player); + }) > 0 + ); + return target.countDiscardableCards(player, "e") > 0; }, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('e')>0; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("e") > 0; }); }, - content:function(){ - 'step 0' - if(player==target) player.chooseToDiscard('e',true); - else player.discardPlayerCard(target,'e',true); - 'step 1' - player.chooseUseTarget('sha',true,false,'nodistance'); - 'step 2' - var bool=game.hasPlayer2(function(current){ - return current.getHistory('damage',function(evt){ - return evt.getParent('xinkuangfu')==event; - }).length>0 + content: function () { + "step 0"; + if (player == target) player.chooseToDiscard("e", true); + else player.discardPlayerCard(target, "e", true); + "step 1"; + player.chooseUseTarget("sha", true, false, "nodistance"); + "step 2"; + var bool = game.hasPlayer2(function (current) { + return ( + current.getHistory("damage", function (evt) { + return evt.getParent("xinkuangfu") == event; + }).length > 0 + ); }); - if(player==target&&bool) player.draw(2); - else if(player!=target&&!bool) player.chooseToDiscard('h',2,true); + if (player == target && bool) player.draw(2); + else if (player != target && !bool) player.chooseToDiscard("h", 2, true); }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.3; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.3; }, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var max=0; - var min=1; - target.countCards('e',function(card){ - var val=get.value(card,target); - if(val>max) max=val; - if(val max) max = val; + if (val < min) min = val; }); - if(att>0&&min<=0) return target.hasSkillTag('noe')?3:1; - if(att<=0&&max>0){ - if(target.hasSkillTag('noe')) return max>6?(-max/3):0; + if (att > 0 && min <= 0) return target.hasSkillTag("noe") ? 3 : 1; + if (att <= 0 && max > 0) { + if (target.hasSkillTag("noe")) return max > 6 ? -max / 3 : 0; return -max; } - if(player===target&&!player.hasSha()){ - let ph=player.countCards('h'); - if(game.hasPlayer(i=>{ - if(!player.canUse('sha',i,true,true)||get.effect(i,{name:'sha'},player,player)<=0) return false; - return !ph||!i.mayHaveShan(player,'use',i.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - })); - })) return 1; + if (player === target && !player.hasSha()) { + let ph = player.countCards("h"); + if ( + game.hasPlayer((i) => { + if ( + !player.canUse("sha", i, true, true) || + get.effect(i, { name: "sha" }, player, player) <= 0 + ) + return false; + return ( + !ph || + !i.mayHaveShan( + player, + "use", + i.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ); + }) + ) + return 1; } return 0; }, @@ -12380,693 +15389,932 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - card:{ + card: {}, + characterIntro: { + dc_liuli: + "刘理(?—244年),字奉孝,涿郡涿县(今河北涿州)人,三国时期蜀汉昭烈帝刘备之子,蜀汉后主刘禅、甘陵王刘永异母弟。章武元年(221年),刘备称帝,派司徒许靖封刘理为梁王。建兴八年(230年),改封为安平王。延熙七年(244年),刘理去世,谥号悼王。", + xingdaorong: + "邢道荣是《三国演义》中虚构的人物,为零陵太守刘度手下武将,被评价有万夫不当之勇,于《三国演义》第五十二回登场,被赵云刺死。", + caoxing: + "曹性,东汉末年吕布部将,史载他曾与身为自己上司的反叛者郝萌交战,并砍去郝萌一臂,受到吕布的嘉奖。在罗贯中所著古典小说《三国演义》中,也有关于曹性箭射夏侯惇左目的描述,而曹性也随即被暴怒的夏侯惇所杀。在穿越小说《三国之银河射手》中,主角穿越成为曹性,经过一番闯荡之后,被封为“银河射手”。", + xiahoujie: + "夏侯杰(?—208年),是罗贯中的小说《三国演义》中曹操的部将,征战时常常带在身边。在第42回长坂坡之战中,张飞大吼,从马儿受惊跌下马来而死。", + huaxin: "华歆(157年-232年1月30日),字子鱼,汉族。平原郡高唐县人(今山东省高唐县)。汉末至三国曹魏初年名士、重臣。华歆早年拜太尉陈球为师,与卢植、郑玄、管宁等为同门,又与管宁、邴原共称一龙,华歆为龙头。汉灵帝时华歆被举为孝廉,任郎中,因病去官。又被大将军何进征召为尚书郎。后任豫章太守,甚得民心。孙策率军南下,华歆举郡投降,被奉为上宾。官渡之战时,被征为议郎、参司空军事。入为尚书、侍中,又代荀彧为尚书令。丞相曹操讨孙权时,授华歆为军师。后为魏王国的御史大夫。曹丕即王位,拜华歆为相国,封安乐乡侯。曹魏建立后,其相国职名改称司徒。魏明帝即位,升任太尉,晋封博平侯。太和五年十二月(232年1月),华歆去世,年七十五,谥号“敬”。有文集三十卷,今佚失,其余见《全三国文》。", + luyusheng: + "陆郁生(?年-?),三国时期吴国官员陆绩之女。陆郁生的父亲陆绩是吴郡公认的才子,又是当时吴郡陆氏的领袖。陆绩赴任担任郁林太守,遂取此名。陆郁生年少的时候就定下坚贞的志向。建安二十四年(219年),陆绩早亡,她与两个兄弟陆宏、陆睿当时都只有几岁,一起返回吴县,被他们的从兄陆瑁接回抚养。13周岁的陆郁生嫁给同郡出身的张白为妻。出嫁3个月后,张白因为其兄张温一族的案件遭到连坐,被处以流刑,后死于流放地,陆郁生成为了寡妇,其后公开宣言不再改嫁,困难于生计但拒绝了所有提亲,在艰苦中从未停止服侍、照顾张白的姐妹。事情传到朝廷,皇帝褒奖陆郁生,号其为“义姑”。她的表侄姚信在文集中称赞她的义举。", + fengxi: "冯熙(?—223年),字子柔,颍川郡父城县(今河南省平顶山市宝丰县)人。汉末三国时期吴国官员,东汉初年名将冯异的后人。孙权担任车骑将军时,冯熙担任其幕府东曹掾,后迁立信都尉。刘备去世时,奉命进入蜀汉吊丧,返回后,任中大夫。后奉命出使魏国,受到魏文帝曹丕和尚书令陈群招揽,宁死不从,自尽未果。孙权闻之流泪,称其“东吴苏武”。最终在曹魏死去。", + heyan: "何晏(?-249年),字平叔。南阳郡宛县(今河南省南阳市)人。三国时期曹魏大臣、玄学家,东汉大将军何进之孙(一称何进弟何苗之孙)。何晏之父早逝,司空曹操纳其母尹氏为妾,他因而被收养,为曹操所宠爱。少年时以才秀知名,喜好老庄之学,娶曹操之女金乡公主。魏文帝在位时,未被授予官职。魏明帝认为何晏虚浮不实,也只授其冗官之职。大将军曹爽秉政时,何晏与之共事,得以累官至侍中、吏部尚书,典选举,封列侯。高平陵之变后,与大将军曹爽同为太傅司马懿所杀,被夷灭三族。何晏有文集十一卷,并曾与郑冲等共撰《论语集解》,今已佚。钟嵘《诗品》称“平叔鸿鹄之篇,风规见矣。”将何晏诗列入中品。袁宏在《名士传》中将何晏等称为正始名士。他与夏侯玄、王弼等倡导玄学,竞事清谈,遂开一时风气,为魏晋玄学的创始者之一。", + zhaoyan: + "赵嫣,生卒年不详。东吴方士(一说是丞相)赵达之妹,吴大帝孙权之妃,人称赵夫人。她心灵手巧,多才多艺,有“三绝”之称。孙权曾经想要找擅长绘画之人绘制山川地势军阵之图。赵达举荐了自己的妹妹。赵嫣认为水墨容易褪色,不方便在军旅之中保存。自己擅长刺绣,可以在锦帛上绣出孙权所需之图。待制作完成后献于孙权,只见方帛锦绣之上有五岳河海城邑行阵之形,孙权大为赞叹。时人谓之“针绝”。除刺绣之外,赵嫣还擅长绘画织锦,她能用彩丝织成云霞龙蛇之锦,大则盈尺,小则方寸,宫中谓之“机绝”。孙权在昭阳宫居住之时,饱受暑气之扰,以紫绡制成帷帐缓解暑气。赵嫣认为此物不足为贵,她削下自己的头发剖为细丝,以郁夷国出产的神胶连接,花了数月功夫将其制成一顶幔帐,打开之后薄如蝉翼,轻赛寒烟。放下帐帷能笼罩一丈之地,帐内清风自生暑意顿消。收起来则可纳入枕中,携带方便。时人谓之“丝绝”。", + wangtao: + "王桃是在《花关索传》中登场的虚拟人物,盗贼王令公的两个女儿之一,王悦的姐姐,与妹妹都是关索之妻。姐妹俩原为卢塘寨山贼,以武艺与美貌而闻名,被众多男性求婚却皆不与理睬。她们在关索回西川认父途中与关索交手时不敌,因意气投合而一齐下嫁。虽为架空之人物,但四川省内有记述夫妻三人共同守护葭萌关一事,民间亦流传如夫妻三人曾共同参与诸葛亮之南蛮征伐等轶事。", + wangyue: + "王悦是在《花关索传》中登场的虚拟人物,盗贼王令公的两个女儿之一,王桃的妹妹,与姐姐都是关索之妻。姐妹俩原为卢塘寨山贼,以武艺与美貌而闻名,被众多男性求婚却皆不与理睬。她们在关索回西川认父途中与关索交手时不敌,因意气投合而一齐下嫁。虽为架空之人物,但四川省内有记述夫妻三人共同守护葭萌关一事,民间亦流传如夫妻三人曾共同参与诸葛亮之南蛮征伐等轶事。", + zhangxuan: + "张嫙,三国时期孙吴将领张布之女,孙皓后妃张媱的姐姐。初为卫尉冯朝之子冯纯的妻子,后为孙皓后妃,册封左夫人。因孙皓诛灭张布,张媱口吐怨言,被暴怒的孙皓下令棒杀。后来孙皓怀念她的容颜,于是询问侍从:“张布还有女儿吗?”侍从回答:“张布的大女儿嫁给了已故卫尉冯朝的儿子冯纯。”于是孙皓夺走了冯纯的妻子张嫙,纳入宫中。孙皓颇为宠爱张嫙,册封其为左夫人。昼夜嬉戏,纸醉金迷,不理朝政。后来张嫙也去世了,孙皓非常悲伤,下令以最高的规格埋葬张嫙。因为悲伤过度,孙皓一度半年都不出宫门,甚至由于葬礼太过奢华被宫外之人认为孙皓已经死了。", + tengyin: + "滕胤(?-256年),字承嗣,三国时期吴国重臣,北海郡剧县(今山东省昌乐县)人。滕胤仪表堂堂,少时有节操,后娶公主为妻。孙权称王后,滕胤被封都亭侯。其后历任丹杨太守、吴郡太守、会稽太守。孙亮继位后,出任太常、卫将军。诸葛恪被杀后,群臣推举滕胤为司徒,但遭权臣孙峻党羽所阻挠,滕胤也有意避嫌,最终只晋爵高密侯。孙峻死后,由其堂弟孙綝执政。滕胤的连襟、骠骑将军吕据联系北伐前线诸将推举滕胤为相,希望分割孙綝权力,但并未成功,滕胤被改任大司马,镇守武昌。不久,滕胤与吕据密谋推翻孙綝,因计划泄露而被杀,惨遭灭族。孙綝被杀后,景帝孙休为滕胤平反。", + zhangyao: + "张美人,三国东吴末帝孙皓后妃,张布之女。另有张布女,张美人姊被孙皓立为左夫人。《吴书五妃嫔传第五》:江表传曰:皓以张布女为美人,有宠,皓问曰:“汝父所在?”答曰:“贼以杀之。”皓大怒,棒杀之。后思其颜色,使巧工刻木作美人形象,恒置座侧。问左右:“布复有女否?”答曰:“布大女适故卫尉冯朝子纯。”即夺纯妻入宫,大有宠,拜为左夫人,昼夜与夫人房宴,不听朝政,使尚方以金作华燧、步摇、假髻以千数。令宫人著以相扑,朝成夕败,辄出更作,工匠因缘偷盗,府藏为空。会夫人死,皓哀愍思念,葬于苑中,大作冢,使工匠刻柏作木人,内冢中以为兵卫,以金银珍玩之物送葬,不可称计。已葬之后,皓治丧於内,半年不出。国人见葬太奢丽,皆谓皓已死,所葬者是也。皓舅子何都颜状似皓,云都代立。临海太守奚熙信讹言,举兵欲还诛都,都叔父植时为备海督,击杀熙,夷三族,讹言乃息,而人心犹疑。", + xiahoulingnv: + "夏侯令女,字令女,名不详。生卒年不详,三国时期人物。夏侯文宁之女(《三国演义》中为夏侯令之女),曹文叔之妻。其事迹见于《三国志·魏书·诸夏侯曹传第九》裴松之注引皇甫谧《列女传》。而在《三国演义》中,由于作者断句错误,便认为“夏侯令女”是“夏侯令之女”之意(见《三国演义》第107回:“乃夏侯令女也”,由其语气可推断)。", + lvlingqi: + "吕玲绮,虚拟人物,源于日本光荣株式会社(现光荣特库摩公司)旗下游戏《真·三国无双》系列,初次登场于《真三国无双7:猛将传》。吕布的女儿,寂寥而威风凛凛的战姬,发挥着不亚于父亲的武艺,非常勇敢地身先士卒立于前线。虽然有着能够直面困难的坚强意志,却由于过去的经历而有着非常害怕孤独的一面。", + liuyong: + "刘永,字公寿,涿郡涿县(今河北涿州)人,三国时期蜀汉昭烈帝刘备之子,蜀汉后主刘禅之弟。章武元年(221年)六月,封鲁王。建兴八年(230年),改封甘陵王。咸熙元年(264年),蜀汉灭亡,刘永被迁往洛阳,被任命为奉车都尉,封乡侯。", + wanniangongzhu: + "刘氏(生卒年不详),河南郡雒阳县(今河南省洛阳市)人,汉灵帝刘宏之女,汉少帝刘辩与汉献帝刘协的姐妹,封万年公主。", + mamidi: "马日磾(?~194年),字翁叔。扶风茂陵(今陕西省兴平市)人。东汉中后期大臣,经学大师马融之族孙(一作族子)。马日磾年轻时即继承马融学说,以才学入仕。曾任谏议大夫,与蔡邕、卢植等人东观典校官藏的《五经》记传,并参与续写《东观汉记》。后历任射声校尉、太尉、太常等职。初平三年(192年),掌权的李傕任命马日磾为太傅、录尚书事,与太仆赵岐共同出使关东。他到寿春袁术处后,对其多有所求,遭袁术轻鄙,袁术遂夺其符节,来随意征辟将士,并企图强迫马日磾任其军师,马日磾求去不能,忧愤发病,兴平元年(194年),卒于寿春。", + guanning: + "管宁(158年—241年),字幼安。北海郡朱虚县(今山东省安丘、临朐东南)人。汉末三国时期著名隐士。管宁与华歆、邴原并称为“一龙”。汉末天下大乱时,与邴原及王烈等人避于辽。在当地只谈经典而不问世事,做讲解《诗经》《书经》,谈祭礼、整治威仪、陈明礼让等教化工作,人们都很乐于接受他的教导。直到魏文帝黄初四年(公元223年)才返乡,辽东太守公孙恭亲自送别。此后曹魏几代帝王数次征召管宁,他都没有应命。正始二年(公元241年),管宁逝世,年八十四。著有《氏姓论》。", + tenggongzhu: + "滕公主,名讳不详,三国人物,吴大帝孙权之女。一说为养女,生父为孙权堂弟孙奂。黄武年间(222年—228年),以公主身份下嫁功臣滕胄之子滕胤,当时滕胤年仅20岁。滕胤皮肤白皙,容貌俊美,每逢入朝大臣们没有不惊叹称羡的。滕胤仕官后,上书言及时局,又对政策多有匡弼。孙权对公主也特别宠爱,因为滕胤的缘故,又格外增加对公主的赏赐,又几次探望慰劳。少帝孙亮时期,孙綝以宗室身份独揽大权作恶多端,引发群臣不满。五凤三年(256年)滕胤与连襟吕据密谋推翻孙綝,事败遭到夷三族 。公主则被亲兄孙壹救出,携其逃亡曹魏。", + caimaozhangyun: + "蔡瑁,字德珪,生卒年不详。襄阳蔡州人,东汉末年荆州名士。少年时与曹操交好。初平元年(公元190年),刘表为荆州刺史。时宗贼猖獗,蔡瑁协助刘表诛杀宗贼,平定荆州之地,蔡瑁因此得刘表重用,并在刘表任镇南将军时担任他的军师。刘表病亡后,蔡瑁拥护刘表幼子刘琮继位,并逼迫他投降南征的曹操。蔡瑁在曹操麾下历任从事中郎、司马、长水校尉,受封汉阳亭侯。张允,生卒年不详,荆州牧刘表的外甥,与蔡瑁一样是刘表幼子刘琮的党羽。刘表病重之时,张允害怕刘表会把州牧之位传给长子刘琦,于是将远赴而来的刘琦阻于门外,不准他与刘表相见。曹操大军到达新野时,张允也随蔡瑁一同投降曹操。之后便隐没于历史之中,并无记载。在《三国演义》中,蔡瑁张允擅长水战,是东吴心腹大患。周瑜用反间计诱骗曹操除掉二人,使得曹军再无能够统领水军的大将。", + zhangxun: + "张勋,东汉末年军阀袁术帐下大将,袁术称帝后受封大将军。初平四年(公元193年),袁术引兵入陈留,被曹操、袁绍合力击败,逃至雍丘。后入九江,杀死扬州刺史陈温而自领之,并任命张勋、桥蕤为大将。时孙策依附于袁术,被表为怀义校尉,张勋对其倾心敬服。袁术称帝后,任命张勋为大将军,攻打吕布,大败而还。其后曹操又以袁术称帝为名南下进攻,袁术闻之大惊,即走度淮,留张勋、桥蕤守蕲阳以拒曹。曹操破其军,斩桥蕤,张勋退走。建安四年(公元199年),袁术病死,张勋率残军欲南投孙策,途中被袁术旧部刘勋俘虏,其后下落不明。", + huzhao: "胡昭(162年-250年),字孔明,颍川(治今河南禹州)人。汉末三国时期隐士、书法家。胡昭善长隶书,与钟繇、邯郸淳、卫觊、韦诞齐名。有“钟氏小巧,胡氏豪放”之说,世人并称“钟胡”。", + guanhai: + "管亥(生卒年不详),青州黄巾军渠帅,率军侵略北海,围北海相孔融于都昌。孔融派遣太史慈突围而出,前往平原向刘备求援,刘备率军来到,击退管亥。《三国演义》中管亥在单挑中为关羽斩杀。", + yinfuren: + "尹夫人,原汉大将军何进的儿媳,丈夫早逝,生有一子何晏。曹操任司空时娶尹氏为妾,一并收养何晏,并生有一子曹矩。", + chengui: + "陈珪(生卒年不详),一作圭,字汉瑜。徐州下邳(治今江苏睢宁西北)人,广汉太守陈亹之孙,太尉陈球之侄,吴郡太守陈瑀(一作陈璃)、汝阴太守陈琮的从兄,陈登、陈应之父。官至沛相。", + wanglie: + "王烈,字彦方(141-219),平原县(今山东德州平原)人。生于永和六年(公元141年),卒于建安二十三年(公元218年)。王烈少时师从陈寔,闻名遐迩。董卓作乱时避乱辽东,并多次拒绝曹操的聘请。七十八岁时病死于辽东。", + panghui: + "庞会,(214—?),三国时期曹魏名将,庞德之子。曹丕即位后,思庞德忠烈,遂赐庞会等兄弟四人爵关内侯,邑各百户。庞会勇烈,有先父之风,官至中尉将军,封列侯。", + chenjiao: + "陈矫(?-237年7月11日),字季弼,广陵郡东阳县(治今安徽省天长市西北,今地属江苏省如皋市)人。三国时期曹魏名臣。陈矫本姓刘,因过继与母族而改姓陈。早年避乱江东,后广陵太守陈登请为功曹。曹操辟为丞相掾属,迁任相县令,转任征南长史。又为彭城、乐陵太守,迁任魏郡西部都尉。曹操东征,拜丞相长史,转西曹属、尚书。曹丕称帝,领吏部事,封高陵亭侯,迁尚书令。明帝继位后,进爵东乡侯,后转侍中,加光禄大夫,又拜司徒。景初元年(237年),陈矫去世,谥贞侯。", + gongsundu: + "公孙度 (?-204年),字升济,辽东襄平(今辽宁辽阳)人,东汉末年辽东太守。少随父迁居玄菟郡。初为玄菟小吏,建宁二年(169年),继升尚书郎、冀州刺史,后被免官。初平元年(190年),经同乡徐荣推荐,被董卓任命为辽东太守。公孙度到任后,厉行严刑峻法,打击豪强势力,使令行政通,羽翼渐丰。不久,中原地区董卓乱起,各地军阀无暇东顾。公孙度趁机自立为辽东侯、平州牧。继则东伐高句丽,西击乌桓,南取辽东半岛,越海取胶东半岛北部东莱诸县,开疆扩土;又招贤纳士,设馆开学,广招流民,威行海外,俨然以辽东王自居。建安九年(204年)病逝,子公孙康继承其位由于公孙度的锐意进取和苦心经营,使辽东地区在汉末三国的战乱年代,获得了暂时的安宁,推动了当地生产技术和封建文化的发展。", + leibo: "雷薄(生卒年不详),本为东汉末年袁术麾下部将。离开称帝后昏庸奢侈的袁术,与陈兰一起占据嵩山为山贼。后来袭击兵败的袁术,抢夺财宝。同时在《三国演义》中也有出场。", + liupi: "刘辟,东汉末年黄巾起义军将领。黄巾军将领。黄巾之乱后,与龚都一起率军盘踞在汝南。欲追随刘备,将汝南让给刘备。《三国演义》中,在与曹操的部将高览交战时,为保护刘备而战死。", + zhenghun: + "郑浑(生卒年不详),字文公。开封(今河南省开封市)人。汉末及三国时期曹魏大臣,东汉名儒郑众曾孙、名士郑泰之弟。郑浑早年避乱淮南,后转投豫章太守华歆。又被曹操辟为掾属,历任下蔡县长、邵陵县令,任内颇有政绩,深得民心。任左冯翊时,击杀扰乱郡县的梁兴,又击败作乱的山贼。历任上党太守、京兆尹、丞相掾属等职。曹丕称帝后,拜侍御史,加驸马都尉。先后任阳平、沛郡太守,任内兴修水利,使农田常年丰收,被百姓称为“郑陂”。后转任山阳和魏郡太守。魏明帝曹叡听闻郑浑的事迹之后,下诏将其政绩布告天下。官至将作大匠。卒年不详。", + furongfuqian: + "傅肜(?-222年),义阳(今湖北枣阳)人,三国时蜀汉将领。刘备攻伐吴国时,傅肜为别督。后刘备被陆逊击败,傅肜率部断后,奋战至死。死前怒斥道:“吴狗!何有汉将军降者!”
              傅佥[qiān] ( ? ~263年),义阳(治今湖北省枣阳市)人,蜀汉将领傅彤之子,三国时期蜀汉名将。金长于谋略,并颇有胆勇,姜维甚爱之。傅佥官至关中都督。魏国攻伐蜀汉时,傅佥和蒋舒防守阳安关,兵败战死。", + qinlang: + "秦朗(生卒年不详),字元明,小字阿蘇(一作阿鳔),新兴(治今山西忻州)云中人。三国时期曹魏将领,官至骁骑将军、给事中,曾率兵讨伐鲜卑轲比能和步度根的叛军。", + xianglang: + "向朗(约167年—247年),字巨达。襄阳郡宜城县(今湖北宜城)人,三国时期蜀汉官员、藏书家、学者。向朗早年师从于司马徽,并被荆州牧刘表任命为临沮县长。后随刘备入蜀,历任巴西、牂牁、房陵太守,并拜步兵校尉,领丞相长史,随丞相诸葛亮北伐。因包庇马谡被免职,后为光禄勋,转左将军、特进,封显明亭侯。曾代理丞相册封张皇后及太子刘璿。晚年专心研究典籍,诱导青年学习,家中藏书丰富,受到举国尊重。延熙十年(247年),向朗去世。《全三国文》收录有一篇《遗言戒子》", + yuantanyuanxiyuanshang: + "袁谭、袁尚的武将介绍请移步「袁谭袁尚」,此处为袁熙的介绍。
              袁熙(?-207年),字显奕(《后汉书》、《东光世系》作显雍),汝南郡汝阳县(今河南商水)人,是东汉末年占据河北的军阀袁绍次子,袁绍打败公孙瓒后,令袁熙为幽州刺史。袁绍官渡兵败后不久病死,其兄长袁谭、弟弟袁尚各自独立,互相攻伐,曹操趁机进攻袁谭、袁尚,并逐渐占河北。袁熙接纳兵败的袁尚后,因为属下叛变而逃往乌桓,被曹操击败后,逃往辽东太守公孙康帐下,却被公孙康杀死,二人首级被献给曹操。", + zhanghu: + "张虎,生卒年不详,雁门马邑(今山西朔城区大夫庄)人。张辽之子,三国时期曹魏武将。官至偏将军,封晋阳侯,有一子张统。", + mengjie: + "孟节,南中蛮王孟获之兄。是小说《三国演义》中杜撰的人物,史上并无记载。诸葛亮南征孟获之时,帐下军士因误饮哑泉之水失语。当地山神告知诸葛亮,言万安溪畔有一高士隐居彼处,号“万安隐者”。其草庵后有一泉,名安乐泉,可解哑泉之毒。庵前生有一草,名薤叶芸香,可防瘴气之染。诸葛亮于是带人连夜前往其隐居之处,求得泉水草叶解毒防瘴,拜求隐士姓名,方知其名为孟节,由此而叹:“方信盗跖、下惠之事,今亦有之。”诸葛亮欲申奏刘禅,立其为王,孟节辞之。又以金帛赠之,孟节坚辞不受。诸葛亮嗟叹不已,拜别而回。", + peiyuanshao: + "裴元绍,《三国演义》人物,原黄巾军之武将。黄巾起义失败之后,与周仓一同率领残部在山中落草当山贼。公元200年,在关羽欲返刘备旗下,在突破曹操的五道关卡后路过其落草之地,与周仓一同向关羽要求能以期成为关羽家臣。但此时仅周仓同行,其他弟兄则于山中等待。不久后,因其欲夺偶然路过的赵云之马,反遭讨伐战败身死。", + zhangchu: + "张楚,《阵面对决》第九弹“燎原”中登场的一个原创人物。她是张角的女儿,张宁的姐姐,在逃亡途中被刘备捕获。之后在诸葛亮的建议下,张楚被囚禁。在《阵面对决》的“怒焰”故事线中,张楚随着刘备入了西川,并被软禁在成都。夷陵之战后,刘备大败,全国主力外出用以支援刘备,朝内空虚,张楚趁机逃跑。", + dongwan: "董绾,袁术老婆,嫉妒冯芳女的美貌,与冯方女有矛盾。", + yuanyin: + "袁胤(生卒年不详),东汉末期人物,据说是袁隗之子,是袁术从弟。兴平二年(公元195年)被袁术任命为丹杨太守,后因孙策平定江东被逐。建安四年(公元199年),袁术卒,袁胤因畏惧曹操,遂率领袁术部曲并带着其灵柩及妻子到皖城并投奔庐江太守刘勋。6个月后皖城被孙策所破,袁胤等人迁居吴郡,此后事迹不详。", + gaoxiang: + "高翔(又作高详、高祥)(生卒年不详),荆州南郡(治今湖北省公安县)人,三国时期蜀汉将领。曾随刘备攻打汉中,后又随蜀汉丞相诸葛亮参加北伐曹魏的战争。建兴九年(公元231年)的北伐中大破司马懿。官至杂号大将军(即某杂号将军加大,但无考何杂号将军),封玄乡侯。此后,关于高翔的记载不详。", + zhoushan: + "周善,《三国演义》中人物,不见于正史记载。为吴侯孙权的家将,此人最有胆量,自幼穿房入户,多随孙策。权为骗其妹回吴,遣善将五百人,扮为商人,分作五船;更诈修国书,以备盘诘;船内暗藏兵器。周善领命,往荆州。正骗得孙夫人带刘禅上船,赵云前来抢走禅,周善在后梢挟住舵,只顾放船下水。正僵持时张飞赶到,周善见张飞上船,提刀来迎,被张飞手起一剑砍倒,提头掷于孙夫人前。", + zhangkai: + "张闿,陶谦的手下都尉。奉命截杀曹操之父曹嵩,杀死曹嵩,夺去财宝逃往淮南投奔袁术,并担任刺杀陈王刘宠和陈国相骆俊的任务。", + mengyou: + "孟优,《三国演义》里的人物,南蛮王孟获之弟。与诸葛亮的南征军交战,向败战的兄长推荐朵思大王,劝兄长借助朵思之力与蜀汉军对抗。后来与兄长一起发誓归顺蜀汉。", + liuchongluojun: + "刘宠(?~197年),汉明帝刘庄玄孙,陈敬王刘羡曾孙,陈顷王刘崇之孙,陈孝王刘承之子,陈国第六位国君,也是东汉陈国的最后一位国君。骆俊(?-197),字孝远,东汉末年扬州会稽郡乌伤县(今浙江义乌)人。宗室陈王刘宠的国相,在任期间励精图治,深得民众爱戴。刘宠勇猛过人,善使弓弩,箭法高超。在其父刘承死后,继承陈王爵位。中平年间,黄巾军起义,郡县官兵都弃城逃走,刘宠于是征兵自守卫。当时天下饥荒,诸王侯都已不再享有租赋,反屡遭抢掠,有的甚至流离在外,死于荒野。只有陈国仍很富强,邻郡百姓纷纷前去投靠,陈国拥有部众达十余万人。初平元年(190年),各州郡起兵讨伐董卓,刘宠率军屯驻阳夏,自称辅汉大将军。建安二年(197年),袁术向陈国求取粮草,遭陈国国相骆俊拒绝,袁术大为生气,便派刺客张闿假装路过陈国,乘机杀死骆俊和刘宠。", + yuechen: + "乐綝(195~257年),字号不详,阳平郡卫国县(今河南省清丰县)人。三国时期曹魏将领,右将军乐进的儿子。果毅坚毅,袭封广昌亭侯,累迁扬州刺史。甘露二年,为叛乱的征东大将军诸葛诞所杀,追赠卫尉。", + kuaiqi: "蒯祺(?~219年),南郡中卢人,荆州望族子弟,与荆州牧刘表帐下谋士蒯良、蒯越为同族,东汉末年房陵太守。建安二十四年(219年),汉中王刘备遣宜都太守孟达从秭归北攻房陵,蒯祺于战斗中被孟达所部士兵所杀。清朝任兆麟《心斋十种》中的《襄阳记》辑本引用《万历襄阳府志》“(蒯)钦从祖祺妇,即诸葛孔明之姊也”,称蒯祺娶故兖州泰山郡丞诸葛珪长女,即他是知名政治家、蜀汉丞相诸葛亮的姐夫。但在任兆麟之前的《襄阳记》辑本中,并没有这一条。", + pangshanmin: + "庞山民,荆州襄阳人,三国时期曹魏大臣。庞山民出身荆州庞氏,为隐士庞德公之子、凤雏庞统的堂兄,娶诸葛亮二姐诸葛氏(“若雪”为网络小说虚构)为妻。后出仕曹魏,历任黄门、吏部郎等职。", + gongsunxiu: + "公孙修(?-238),三国时期人物,公孙渊之子。景初元年(237年),魏明帝曹叡派出幽州刺史毌丘俭攻打公孙渊,久战不利回师。公孙渊即自立为燕王,改元绍汉,引诱鲜卑侵扰北方,背叛曹魏。景初二年(238年)春,曹魏又派司马懿和高句丽国王高位宫率军攻打公孙渊,围城日久,公孙渊粮尽之后,与儿子公孙修一起出逃后被擒获,父子二人同时被斩首示众。", }, - characterIntro:{ - dc_liuli:'刘理(?—244年),字奉孝,涿郡涿县(今河北涿州)人,三国时期蜀汉昭烈帝刘备之子,蜀汉后主刘禅、甘陵王刘永异母弟。章武元年(221年),刘备称帝,派司徒许靖封刘理为梁王。建兴八年(230年),改封为安平王。延熙七年(244年),刘理去世,谥号悼王。', - xingdaorong:'邢道荣是《三国演义》中虚构的人物,为零陵太守刘度手下武将,被评价有万夫不当之勇,于《三国演义》第五十二回登场,被赵云刺死。', - caoxing:'曹性,东汉末年吕布部将,史载他曾与身为自己上司的反叛者郝萌交战,并砍去郝萌一臂,受到吕布的嘉奖。在罗贯中所著古典小说《三国演义》中,也有关于曹性箭射夏侯惇左目的描述,而曹性也随即被暴怒的夏侯惇所杀。在穿越小说《三国之银河射手》中,主角穿越成为曹性,经过一番闯荡之后,被封为“银河射手”。', - xiahoujie:'夏侯杰(?—208年),是罗贯中的小说《三国演义》中曹操的部将,征战时常常带在身边。在第42回长坂坡之战中,张飞大吼,从马儿受惊跌下马来而死。', - huaxin:'华歆(157年-232年1月30日),字子鱼,汉族。平原郡高唐县人(今山东省高唐县)。汉末至三国曹魏初年名士、重臣。华歆早年拜太尉陈球为师,与卢植、郑玄、管宁等为同门,又与管宁、邴原共称一龙,华歆为龙头。汉灵帝时华歆被举为孝廉,任郎中,因病去官。又被大将军何进征召为尚书郎。后任豫章太守,甚得民心。孙策率军南下,华歆举郡投降,被奉为上宾。官渡之战时,被征为议郎、参司空军事。入为尚书、侍中,又代荀彧为尚书令。丞相曹操讨孙权时,授华歆为军师。后为魏王国的御史大夫。曹丕即王位,拜华歆为相国,封安乐乡侯。曹魏建立后,其相国职名改称司徒。魏明帝即位,升任太尉,晋封博平侯。太和五年十二月(232年1月),华歆去世,年七十五,谥号“敬”。有文集三十卷,今佚失,其余见《全三国文》。', - luyusheng:'陆郁生(?年-?),三国时期吴国官员陆绩之女。陆郁生的父亲陆绩是吴郡公认的才子,又是当时吴郡陆氏的领袖。陆绩赴任担任郁林太守,遂取此名。陆郁生年少的时候就定下坚贞的志向。建安二十四年(219年),陆绩早亡,她与两个兄弟陆宏、陆睿当时都只有几岁,一起返回吴县,被他们的从兄陆瑁接回抚养。13周岁的陆郁生嫁给同郡出身的张白为妻。出嫁3个月后,张白因为其兄张温一族的案件遭到连坐,被处以流刑,后死于流放地,陆郁生成为了寡妇,其后公开宣言不再改嫁,困难于生计但拒绝了所有提亲,在艰苦中从未停止服侍、照顾张白的姐妹。事情传到朝廷,皇帝褒奖陆郁生,号其为“义姑”。她的表侄姚信在文集中称赞她的义举。', - fengxi:'冯熙(?—223年),字子柔,颍川郡父城县(今河南省平顶山市宝丰县)人。汉末三国时期吴国官员,东汉初年名将冯异的后人。孙权担任车骑将军时,冯熙担任其幕府东曹掾,后迁立信都尉。刘备去世时,奉命进入蜀汉吊丧,返回后,任中大夫。后奉命出使魏国,受到魏文帝曹丕和尚书令陈群招揽,宁死不从,自尽未果。孙权闻之流泪,称其“东吴苏武”。最终在曹魏死去。', - heyan:'何晏(?-249年),字平叔。南阳郡宛县(今河南省南阳市)人。三国时期曹魏大臣、玄学家,东汉大将军何进之孙(一称何进弟何苗之孙)。何晏之父早逝,司空曹操纳其母尹氏为妾,他因而被收养,为曹操所宠爱。少年时以才秀知名,喜好老庄之学,娶曹操之女金乡公主。魏文帝在位时,未被授予官职。魏明帝认为何晏虚浮不实,也只授其冗官之职。大将军曹爽秉政时,何晏与之共事,得以累官至侍中、吏部尚书,典选举,封列侯。高平陵之变后,与大将军曹爽同为太傅司马懿所杀,被夷灭三族。何晏有文集十一卷,并曾与郑冲等共撰《论语集解》,今已佚。钟嵘《诗品》称“平叔鸿鹄之篇,风规见矣。”将何晏诗列入中品。袁宏在《名士传》中将何晏等称为正始名士。他与夏侯玄、王弼等倡导玄学,竞事清谈,遂开一时风气,为魏晋玄学的创始者之一。', - zhaoyan:'赵嫣,生卒年不详。东吴方士(一说是丞相)赵达之妹,吴大帝孙权之妃,人称赵夫人。她心灵手巧,多才多艺,有“三绝”之称。孙权曾经想要找擅长绘画之人绘制山川地势军阵之图。赵达举荐了自己的妹妹。赵嫣认为水墨容易褪色,不方便在军旅之中保存。自己擅长刺绣,可以在锦帛上绣出孙权所需之图。待制作完成后献于孙权,只见方帛锦绣之上有五岳河海城邑行阵之形,孙权大为赞叹。时人谓之“针绝”。除刺绣之外,赵嫣还擅长绘画织锦,她能用彩丝织成云霞龙蛇之锦,大则盈尺,小则方寸,宫中谓之“机绝”。孙权在昭阳宫居住之时,饱受暑气之扰,以紫绡制成帷帐缓解暑气。赵嫣认为此物不足为贵,她削下自己的头发剖为细丝,以郁夷国出产的神胶连接,花了数月功夫将其制成一顶幔帐,打开之后薄如蝉翼,轻赛寒烟。放下帐帷能笼罩一丈之地,帐内清风自生暑意顿消。收起来则可纳入枕中,携带方便。时人谓之“丝绝”。', - wangtao:'王桃是在《花关索传》中登场的虚拟人物,盗贼王令公的两个女儿之一,王悦的姐姐,与妹妹都是关索之妻。姐妹俩原为卢塘寨山贼,以武艺与美貌而闻名,被众多男性求婚却皆不与理睬。她们在关索回西川认父途中与关索交手时不敌,因意气投合而一齐下嫁。虽为架空之人物,但四川省内有记述夫妻三人共同守护葭萌关一事,民间亦流传如夫妻三人曾共同参与诸葛亮之南蛮征伐等轶事。', - wangyue:'王悦是在《花关索传》中登场的虚拟人物,盗贼王令公的两个女儿之一,王桃的妹妹,与姐姐都是关索之妻。姐妹俩原为卢塘寨山贼,以武艺与美貌而闻名,被众多男性求婚却皆不与理睬。她们在关索回西川认父途中与关索交手时不敌,因意气投合而一齐下嫁。虽为架空之人物,但四川省内有记述夫妻三人共同守护葭萌关一事,民间亦流传如夫妻三人曾共同参与诸葛亮之南蛮征伐等轶事。', - zhangxuan:'张嫙,三国时期孙吴将领张布之女,孙皓后妃张媱的姐姐。初为卫尉冯朝之子冯纯的妻子,后为孙皓后妃,册封左夫人。因孙皓诛灭张布,张媱口吐怨言,被暴怒的孙皓下令棒杀。后来孙皓怀念她的容颜,于是询问侍从:“张布还有女儿吗?”侍从回答:“张布的大女儿嫁给了已故卫尉冯朝的儿子冯纯。”于是孙皓夺走了冯纯的妻子张嫙,纳入宫中。孙皓颇为宠爱张嫙,册封其为左夫人。昼夜嬉戏,纸醉金迷,不理朝政。后来张嫙也去世了,孙皓非常悲伤,下令以最高的规格埋葬张嫙。因为悲伤过度,孙皓一度半年都不出宫门,甚至由于葬礼太过奢华被宫外之人认为孙皓已经死了。', - tengyin:'滕胤(?-256年),字承嗣,三国时期吴国重臣,北海郡剧县(今山东省昌乐县)人。滕胤仪表堂堂,少时有节操,后娶公主为妻。孙权称王后,滕胤被封都亭侯。其后历任丹杨太守、吴郡太守、会稽太守。孙亮继位后,出任太常、卫将军。诸葛恪被杀后,群臣推举滕胤为司徒,但遭权臣孙峻党羽所阻挠,滕胤也有意避嫌,最终只晋爵高密侯。孙峻死后,由其堂弟孙綝执政。滕胤的连襟、骠骑将军吕据联系北伐前线诸将推举滕胤为相,希望分割孙綝权力,但并未成功,滕胤被改任大司马,镇守武昌。不久,滕胤与吕据密谋推翻孙綝,因计划泄露而被杀,惨遭灭族。孙綝被杀后,景帝孙休为滕胤平反。', - zhangyao:'张美人,三国东吴末帝孙皓后妃,张布之女。另有张布女,张美人姊被孙皓立为左夫人。《吴书五妃嫔传第五》:江表传曰:皓以张布女为美人,有宠,皓问曰:“汝父所在?”答曰:“贼以杀之。”皓大怒,棒杀之。后思其颜色,使巧工刻木作美人形象,恒置座侧。问左右:“布复有女否?”答曰:“布大女适故卫尉冯朝子纯。”即夺纯妻入宫,大有宠,拜为左夫人,昼夜与夫人房宴,不听朝政,使尚方以金作华燧、步摇、假髻以千数。令宫人著以相扑,朝成夕败,辄出更作,工匠因缘偷盗,府藏为空。会夫人死,皓哀愍思念,葬于苑中,大作冢,使工匠刻柏作木人,内冢中以为兵卫,以金银珍玩之物送葬,不可称计。已葬之后,皓治丧於内,半年不出。国人见葬太奢丽,皆谓皓已死,所葬者是也。皓舅子何都颜状似皓,云都代立。临海太守奚熙信讹言,举兵欲还诛都,都叔父植时为备海督,击杀熙,夷三族,讹言乃息,而人心犹疑。', - xiahoulingnv:'夏侯令女,字令女,名不详。生卒年不详,三国时期人物。夏侯文宁之女(《三国演义》中为夏侯令之女),曹文叔之妻。其事迹见于《三国志·魏书·诸夏侯曹传第九》裴松之注引皇甫谧《列女传》。而在《三国演义》中,由于作者断句错误,便认为“夏侯令女”是“夏侯令之女”之意(见《三国演义》第107回:“乃夏侯令女也”,由其语气可推断)。', - lvlingqi:'吕玲绮,虚拟人物,源于日本光荣株式会社(现光荣特库摩公司)旗下游戏《真·三国无双》系列,初次登场于《真三国无双7:猛将传》。吕布的女儿,寂寥而威风凛凛的战姬,发挥着不亚于父亲的武艺,非常勇敢地身先士卒立于前线。虽然有着能够直面困难的坚强意志,却由于过去的经历而有着非常害怕孤独的一面。', - liuyong:'刘永,字公寿,涿郡涿县(今河北涿州)人,三国时期蜀汉昭烈帝刘备之子,蜀汉后主刘禅之弟。章武元年(221年)六月,封鲁王。建兴八年(230年),改封甘陵王。咸熙元年(264年),蜀汉灭亡,刘永被迁往洛阳,被任命为奉车都尉,封乡侯。', - wanniangongzhu:'刘氏(生卒年不详),河南郡雒阳县(今河南省洛阳市)人,汉灵帝刘宏之女,汉少帝刘辩与汉献帝刘协的姐妹,封万年公主。', - mamidi:'马日磾(?~194年),字翁叔。扶风茂陵(今陕西省兴平市)人。东汉中后期大臣,经学大师马融之族孙(一作族子)。马日磾年轻时即继承马融学说,以才学入仕。曾任谏议大夫,与蔡邕、卢植等人东观典校官藏的《五经》记传,并参与续写《东观汉记》。后历任射声校尉、太尉、太常等职。初平三年(192年),掌权的李傕任命马日磾为太傅、录尚书事,与太仆赵岐共同出使关东。他到寿春袁术处后,对其多有所求,遭袁术轻鄙,袁术遂夺其符节,来随意征辟将士,并企图强迫马日磾任其军师,马日磾求去不能,忧愤发病,兴平元年(194年),卒于寿春。', - guanning:'管宁(158年—241年),字幼安。北海郡朱虚县(今山东省安丘、临朐东南)人。汉末三国时期著名隐士。管宁与华歆、邴原并称为“一龙”。汉末天下大乱时,与邴原及王烈等人避于辽。在当地只谈经典而不问世事,做讲解《诗经》《书经》,谈祭礼、整治威仪、陈明礼让等教化工作,人们都很乐于接受他的教导。直到魏文帝黄初四年(公元223年)才返乡,辽东太守公孙恭亲自送别。此后曹魏几代帝王数次征召管宁,他都没有应命。正始二年(公元241年),管宁逝世,年八十四。著有《氏姓论》。', - tenggongzhu:'滕公主,名讳不详,三国人物,吴大帝孙权之女。一说为养女,生父为孙权堂弟孙奂。黄武年间(222年—228年),以公主身份下嫁功臣滕胄之子滕胤,当时滕胤年仅20岁。滕胤皮肤白皙,容貌俊美,每逢入朝大臣们没有不惊叹称羡的。滕胤仕官后,上书言及时局,又对政策多有匡弼。孙权对公主也特别宠爱,因为滕胤的缘故,又格外增加对公主的赏赐,又几次探望慰劳。少帝孙亮时期,孙綝以宗室身份独揽大权作恶多端,引发群臣不满。五凤三年(256年)滕胤与连襟吕据密谋推翻孙綝,事败遭到夷三族 。公主则被亲兄孙壹救出,携其逃亡曹魏。', - caimaozhangyun:'蔡瑁,字德珪,生卒年不详。襄阳蔡州人,东汉末年荆州名士。少年时与曹操交好。初平元年(公元190年),刘表为荆州刺史。时宗贼猖獗,蔡瑁协助刘表诛杀宗贼,平定荆州之地,蔡瑁因此得刘表重用,并在刘表任镇南将军时担任他的军师。刘表病亡后,蔡瑁拥护刘表幼子刘琮继位,并逼迫他投降南征的曹操。蔡瑁在曹操麾下历任从事中郎、司马、长水校尉,受封汉阳亭侯。张允,生卒年不详,荆州牧刘表的外甥,与蔡瑁一样是刘表幼子刘琮的党羽。刘表病重之时,张允害怕刘表会把州牧之位传给长子刘琦,于是将远赴而来的刘琦阻于门外,不准他与刘表相见。曹操大军到达新野时,张允也随蔡瑁一同投降曹操。之后便隐没于历史之中,并无记载。在《三国演义》中,蔡瑁张允擅长水战,是东吴心腹大患。周瑜用反间计诱骗曹操除掉二人,使得曹军再无能够统领水军的大将。', - zhangxun:'张勋,东汉末年军阀袁术帐下大将,袁术称帝后受封大将军。初平四年(公元193年),袁术引兵入陈留,被曹操、袁绍合力击败,逃至雍丘。后入九江,杀死扬州刺史陈温而自领之,并任命张勋、桥蕤为大将。时孙策依附于袁术,被表为怀义校尉,张勋对其倾心敬服。袁术称帝后,任命张勋为大将军,攻打吕布,大败而还。其后曹操又以袁术称帝为名南下进攻,袁术闻之大惊,即走度淮,留张勋、桥蕤守蕲阳以拒曹。曹操破其军,斩桥蕤,张勋退走。建安四年(公元199年),袁术病死,张勋率残军欲南投孙策,途中被袁术旧部刘勋俘虏,其后下落不明。', - huzhao:'胡昭(162年-250年),字孔明,颍川(治今河南禹州)人。汉末三国时期隐士、书法家。胡昭善长隶书,与钟繇、邯郸淳、卫觊、韦诞齐名。有“钟氏小巧,胡氏豪放”之说,世人并称“钟胡”。', - guanhai:'管亥(生卒年不详),青州黄巾军渠帅,率军侵略北海,围北海相孔融于都昌。孔融派遣太史慈突围而出,前往平原向刘备求援,刘备率军来到,击退管亥。《三国演义》中管亥在单挑中为关羽斩杀。', - yinfuren:'尹夫人,原汉大将军何进的儿媳,丈夫早逝,生有一子何晏。曹操任司空时娶尹氏为妾,一并收养何晏,并生有一子曹矩。', - chengui:'陈珪(生卒年不详),一作圭,字汉瑜。徐州下邳(治今江苏睢宁西北)人,广汉太守陈亹之孙,太尉陈球之侄,吴郡太守陈瑀(一作陈璃)、汝阴太守陈琮的从兄,陈登、陈应之父。官至沛相。', - wanglie:'王烈,字彦方(141-219),平原县(今山东德州平原)人。生于永和六年(公元141年),卒于建安二十三年(公元218年)。王烈少时师从陈寔,闻名遐迩。董卓作乱时避乱辽东,并多次拒绝曹操的聘请。七十八岁时病死于辽东。', - panghui:'庞会,(214—?),三国时期曹魏名将,庞德之子。曹丕即位后,思庞德忠烈,遂赐庞会等兄弟四人爵关内侯,邑各百户。庞会勇烈,有先父之风,官至中尉将军,封列侯。', - chenjiao:'陈矫(?-237年7月11日),字季弼,广陵郡东阳县(治今安徽省天长市西北,今地属江苏省如皋市)人。三国时期曹魏名臣。陈矫本姓刘,因过继与母族而改姓陈。早年避乱江东,后广陵太守陈登请为功曹。曹操辟为丞相掾属,迁任相县令,转任征南长史。又为彭城、乐陵太守,迁任魏郡西部都尉。曹操东征,拜丞相长史,转西曹属、尚书。曹丕称帝,领吏部事,封高陵亭侯,迁尚书令。明帝继位后,进爵东乡侯,后转侍中,加光禄大夫,又拜司徒。景初元年(237年),陈矫去世,谥贞侯。', - gongsundu:'公孙度 (?-204年),字升济,辽东襄平(今辽宁辽阳)人,东汉末年辽东太守。少随父迁居玄菟郡。初为玄菟小吏,建宁二年(169年),继升尚书郎、冀州刺史,后被免官。初平元年(190年),经同乡徐荣推荐,被董卓任命为辽东太守。公孙度到任后,厉行严刑峻法,打击豪强势力,使令行政通,羽翼渐丰。不久,中原地区董卓乱起,各地军阀无暇东顾。公孙度趁机自立为辽东侯、平州牧。继则东伐高句丽,西击乌桓,南取辽东半岛,越海取胶东半岛北部东莱诸县,开疆扩土;又招贤纳士,设馆开学,广招流民,威行海外,俨然以辽东王自居。建安九年(204年)病逝,子公孙康继承其位由于公孙度的锐意进取和苦心经营,使辽东地区在汉末三国的战乱年代,获得了暂时的安宁,推动了当地生产技术和封建文化的发展。', - leibo:'雷薄(生卒年不详),本为东汉末年袁术麾下部将。离开称帝后昏庸奢侈的袁术,与陈兰一起占据嵩山为山贼。后来袭击兵败的袁术,抢夺财宝。同时在《三国演义》中也有出场。', - liupi:'刘辟,东汉末年黄巾起义军将领。黄巾军将领。黄巾之乱后,与龚都一起率军盘踞在汝南。欲追随刘备,将汝南让给刘备。《三国演义》中,在与曹操的部将高览交战时,为保护刘备而战死。', - zhenghun:'郑浑(生卒年不详),字文公。开封(今河南省开封市)人。汉末及三国时期曹魏大臣,东汉名儒郑众曾孙、名士郑泰之弟。郑浑早年避乱淮南,后转投豫章太守华歆。又被曹操辟为掾属,历任下蔡县长、邵陵县令,任内颇有政绩,深得民心。任左冯翊时,击杀扰乱郡县的梁兴,又击败作乱的山贼。历任上党太守、京兆尹、丞相掾属等职。曹丕称帝后,拜侍御史,加驸马都尉。先后任阳平、沛郡太守,任内兴修水利,使农田常年丰收,被百姓称为“郑陂”。后转任山阳和魏郡太守。魏明帝曹叡听闻郑浑的事迹之后,下诏将其政绩布告天下。官至将作大匠。卒年不详。', - furongfuqian:'傅肜(?-222年),义阳(今湖北枣阳)人,三国时蜀汉将领。刘备攻伐吴国时,傅肜为别督。后刘备被陆逊击败,傅肜率部断后,奋战至死。死前怒斥道:“吴狗!何有汉将军降者!”
              傅佥[qiān] ( ? ~263年),义阳(治今湖北省枣阳市)人,蜀汉将领傅彤之子,三国时期蜀汉名将。金长于谋略,并颇有胆勇,姜维甚爱之。傅佥官至关中都督。魏国攻伐蜀汉时,傅佥和蒋舒防守阳安关,兵败战死。', - qinlang:'秦朗(生卒年不详),字元明,小字阿蘇(一作阿鳔),新兴(治今山西忻州)云中人。三国时期曹魏将领,官至骁骑将军、给事中,曾率兵讨伐鲜卑轲比能和步度根的叛军。', - xianglang:'向朗(约167年—247年),字巨达。襄阳郡宜城县(今湖北宜城)人,三国时期蜀汉官员、藏书家、学者。向朗早年师从于司马徽,并被荆州牧刘表任命为临沮县长。后随刘备入蜀,历任巴西、牂牁、房陵太守,并拜步兵校尉,领丞相长史,随丞相诸葛亮北伐。因包庇马谡被免职,后为光禄勋,转左将军、特进,封显明亭侯。曾代理丞相册封张皇后及太子刘璿。晚年专心研究典籍,诱导青年学习,家中藏书丰富,受到举国尊重。延熙十年(247年),向朗去世。《全三国文》收录有一篇《遗言戒子》', - yuantanyuanxiyuanshang:'袁谭、袁尚的武将介绍请移步「袁谭袁尚」,此处为袁熙的介绍。
              袁熙(?-207年),字显奕(《后汉书》、《东光世系》作显雍),汝南郡汝阳县(今河南商水)人,是东汉末年占据河北的军阀袁绍次子,袁绍打败公孙瓒后,令袁熙为幽州刺史。袁绍官渡兵败后不久病死,其兄长袁谭、弟弟袁尚各自独立,互相攻伐,曹操趁机进攻袁谭、袁尚,并逐渐占河北。袁熙接纳兵败的袁尚后,因为属下叛变而逃往乌桓,被曹操击败后,逃往辽东太守公孙康帐下,却被公孙康杀死,二人首级被献给曹操。', - zhanghu:'张虎,生卒年不详,雁门马邑(今山西朔城区大夫庄)人。张辽之子,三国时期曹魏武将。官至偏将军,封晋阳侯,有一子张统。', - mengjie:'孟节,南中蛮王孟获之兄。是小说《三国演义》中杜撰的人物,史上并无记载。诸葛亮南征孟获之时,帐下军士因误饮哑泉之水失语。当地山神告知诸葛亮,言万安溪畔有一高士隐居彼处,号“万安隐者”。其草庵后有一泉,名安乐泉,可解哑泉之毒。庵前生有一草,名薤叶芸香,可防瘴气之染。诸葛亮于是带人连夜前往其隐居之处,求得泉水草叶解毒防瘴,拜求隐士姓名,方知其名为孟节,由此而叹:“方信盗跖、下惠之事,今亦有之。”诸葛亮欲申奏刘禅,立其为王,孟节辞之。又以金帛赠之,孟节坚辞不受。诸葛亮嗟叹不已,拜别而回。', - peiyuanshao:'裴元绍,《三国演义》人物,原黄巾军之武将。黄巾起义失败之后,与周仓一同率领残部在山中落草当山贼。公元200年,在关羽欲返刘备旗下,在突破曹操的五道关卡后路过其落草之地,与周仓一同向关羽要求能以期成为关羽家臣。但此时仅周仓同行,其他弟兄则于山中等待。不久后,因其欲夺偶然路过的赵云之马,反遭讨伐战败身死。', - zhangchu:'张楚,《阵面对决》第九弹“燎原”中登场的一个原创人物。她是张角的女儿,张宁的姐姐,在逃亡途中被刘备捕获。之后在诸葛亮的建议下,张楚被囚禁。在《阵面对决》的“怒焰”故事线中,张楚随着刘备入了西川,并被软禁在成都。夷陵之战后,刘备大败,全国主力外出用以支援刘备,朝内空虚,张楚趁机逃跑。', - dongwan:'董绾,袁术老婆,嫉妒冯芳女的美貌,与冯方女有矛盾。', - yuanyin:'袁胤(生卒年不详),东汉末期人物,据说是袁隗之子,是袁术从弟。兴平二年(公元195年)被袁术任命为丹杨太守,后因孙策平定江东被逐。建安四年(公元199年),袁术卒,袁胤因畏惧曹操,遂率领袁术部曲并带着其灵柩及妻子到皖城并投奔庐江太守刘勋。6个月后皖城被孙策所破,袁胤等人迁居吴郡,此后事迹不详。', - gaoxiang:'高翔(又作高详、高祥)(生卒年不详),荆州南郡(治今湖北省公安县)人,三国时期蜀汉将领。曾随刘备攻打汉中,后又随蜀汉丞相诸葛亮参加北伐曹魏的战争。建兴九年(公元231年)的北伐中大破司马懿。官至杂号大将军(即某杂号将军加大,但无考何杂号将军),封玄乡侯。此后,关于高翔的记载不详。', - zhoushan:'周善,《三国演义》中人物,不见于正史记载。为吴侯孙权的家将,此人最有胆量,自幼穿房入户,多随孙策。权为骗其妹回吴,遣善将五百人,扮为商人,分作五船;更诈修国书,以备盘诘;船内暗藏兵器。周善领命,往荆州。正骗得孙夫人带刘禅上船,赵云前来抢走禅,周善在后梢挟住舵,只顾放船下水。正僵持时张飞赶到,周善见张飞上船,提刀来迎,被张飞手起一剑砍倒,提头掷于孙夫人前。', - zhangkai:'张闿,陶谦的手下都尉。奉命截杀曹操之父曹嵩,杀死曹嵩,夺去财宝逃往淮南投奔袁术,并担任刺杀陈王刘宠和陈国相骆俊的任务。', - mengyou:'孟优,《三国演义》里的人物,南蛮王孟获之弟。与诸葛亮的南征军交战,向败战的兄长推荐朵思大王,劝兄长借助朵思之力与蜀汉军对抗。后来与兄长一起发誓归顺蜀汉。', - liuchongluojun:'刘宠(?~197年),汉明帝刘庄玄孙,陈敬王刘羡曾孙,陈顷王刘崇之孙,陈孝王刘承之子,陈国第六位国君,也是东汉陈国的最后一位国君。骆俊(?-197),字孝远,东汉末年扬州会稽郡乌伤县(今浙江义乌)人。宗室陈王刘宠的国相,在任期间励精图治,深得民众爱戴。刘宠勇猛过人,善使弓弩,箭法高超。在其父刘承死后,继承陈王爵位。中平年间,黄巾军起义,郡县官兵都弃城逃走,刘宠于是征兵自守卫。当时天下饥荒,诸王侯都已不再享有租赋,反屡遭抢掠,有的甚至流离在外,死于荒野。只有陈国仍很富强,邻郡百姓纷纷前去投靠,陈国拥有部众达十余万人。初平元年(190年),各州郡起兵讨伐董卓,刘宠率军屯驻阳夏,自称辅汉大将军。建安二年(197年),袁术向陈国求取粮草,遭陈国国相骆俊拒绝,袁术大为生气,便派刺客张闿假装路过陈国,乘机杀死骆俊和刘宠。', - yuechen:'乐綝(195~257年),字号不详,阳平郡卫国县(今河南省清丰县)人。三国时期曹魏将领,右将军乐进的儿子。果毅坚毅,袭封广昌亭侯,累迁扬州刺史。甘露二年,为叛乱的征东大将军诸葛诞所杀,追赠卫尉。', - kuaiqi:'蒯祺(?~219年),南郡中卢人,荆州望族子弟,与荆州牧刘表帐下谋士蒯良、蒯越为同族,东汉末年房陵太守。建安二十四年(219年),汉中王刘备遣宜都太守孟达从秭归北攻房陵,蒯祺于战斗中被孟达所部士兵所杀。清朝任兆麟《心斋十种》中的《襄阳记》辑本引用《万历襄阳府志》“(蒯)钦从祖祺妇,即诸葛孔明之姊也”,称蒯祺娶故兖州泰山郡丞诸葛珪长女,即他是知名政治家、蜀汉丞相诸葛亮的姐夫。但在任兆麟之前的《襄阳记》辑本中,并没有这一条。', - pangshanmin:'庞山民,荆州襄阳人,三国时期曹魏大臣。庞山民出身荆州庞氏,为隐士庞德公之子、凤雏庞统的堂兄,娶诸葛亮二姐诸葛氏(“若雪”为网络小说虚构)为妻。后出仕曹魏,历任黄门、吏部郎等职。', - gongsunxiu:'公孙修(?-238),三国时期人物,公孙渊之子。景初元年(237年),魏明帝曹叡派出幽州刺史毌丘俭攻打公孙渊,久战不利回师。公孙渊即自立为燕王,改元绍汉,引诱鲜卑侵扰北方,背叛曹魏。景初二年(238年)春,曹魏又派司马懿和高句丽国王高位宫率军攻打公孙渊,围城日久,公孙渊粮尽之后,与儿子公孙修一起出逃后被擒获,父子二人同时被斩首示众。', - }, - characterTitle:{ - }, - characterFilter:{ - }, - dynamicTranslate:{ - cuijian:function(player){ - return '出牌阶段限一次,你可以选择一名有手牌的其他角色。若其手牌中有【闪】,则其将所有【闪】和防具牌交给你'+(player.hasMark('zhtongyuan_basic')?'':',然后你交给其等量的牌')+'。'+(player.hasMark('zhtongyuan_trick')?'若其手牌中没有【闪】,则你摸两张牌。':''); + characterTitle: {}, + characterFilter: {}, + dynamicTranslate: { + cuijian: function (player) { + return ( + "出牌阶段限一次,你可以选择一名有手牌的其他角色。若其手牌中有【闪】,则其将所有【闪】和防具牌交给你" + + (player.hasMark("zhtongyuan_basic") ? "" : ",然后你交给其等量的牌") + + "。" + + (player.hasMark("zhtongyuan_trick") ? "若其手牌中没有【闪】,则你摸两张牌。" : "") + ); }, - dunshi:function(player){ - var info=player.storage.dunshi; - var str='每回合限一次。你可以视为使用或打出一张'; - var list=['sha','shan','tao','jiu']; - for(var i of list){ - var strx='【'+get.translation(i)+'】'; - if(!info||!info[0].includes(i)) strx=(''+strx+''); - str+=strx; - if(i!='jiu') str+='/'; + dunshi: function (player) { + var info = player.storage.dunshi; + var str = "每回合限一次。你可以视为使用或打出一张"; + var list = ["sha", "shan", "tao", "jiu"]; + for (var i of list) { + var strx = "【" + get.translation(i) + "】"; + if (info && !info[0].includes(i)) + strx = '' + strx + ""; + str += strx; + if (i != "jiu") str += "/"; } - str+=',然后当前回合角色于本回合内下一次造成伤害时,你选择两项:⒈防止此伤害。系统从技能名中包含“仁/义/礼/智/信”字样的技能中随机选择三个其未拥有的技能,然后你令当前回合角色获得其中一个技能。⒉从〖遁世〗中删除你本次使用或打出的牌并获得一个“席”。⒊减1点体力上限并摸X张牌(X为你的“席”数)。'; + str += + ",然后当前回合角色于本回合内下一次造成伤害时,你选择两项:⒈防止此伤害。系统从技能名中包含“仁/义/礼/智/信”字样的技能中随机选择三个其未拥有的技能,然后你令当前回合角色获得其中一个技能。⒉从〖遁世〗中删除你本次使用或打出的牌并获得一个“席”。⒊减1点体力上限并摸X张牌(X为你的“席”数)。"; return str; }, - dcporui:function(player){ - return '每轮限'+(player.hasMark('dcgonghu_basic')?'两':'一')+'次。其他角色的结束阶段,你可以弃置一张牌并选择另一名于此回合内失去过牌的其他角色,你视为对其依次使用X+1张【杀】'+(player.hasMark('dcgonghu_damage')?'':',然后你交给其X张手牌')+'(X为其本回合失去的牌数且至多为5)。'; + dcporui: function (player) { + return ( + "每轮限" + + (player.hasMark("dcgonghu_basic") ? "两" : "一") + + "次。其他角色的结束阶段,你可以弃置一张牌并选择另一名于此回合内失去过牌的其他角色,你视为对其依次使用X+1张【杀】" + + (player.hasMark("dcgonghu_damage") ? "" : ",然后你交给其X张手牌") + + "(X为其本回合失去的牌数且至多为5)。" + ); }, - dcmanwang:function(player){ - var num=4-player.countMark('dcmanwang'); - var str='出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:'; - var list=[ - '⒈获得〖叛侵〗。', - '⒉摸一张牌。', - '⒊回复1点体力。', - '⒋摸两张牌并失去〖叛侵〗。', - ]; - for(var i=0;i<4;i++){ - if(i==num){ - str+=''; + dcmanwang: function (player) { + var num = 4 - player.countMark("dcmanwang"); + var str = "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:"; + var list = ["⒈获得〖叛侵〗。", "⒉摸一张牌。", "⒊回复1点体力。", "⒋摸两张牌并失去〖叛侵〗。"]; + for (var i = 0; i < 4; i++) { + if (i == num) { + str += ''; } - str+=list[i]; + str += list[i]; } - if(num<4) str+=''; + if (num < 4) str += ""; return str; }, - dcjianzhuan(player){ - let str='锁定技。①当你于出牌阶段使用牌时,你选择此阶段未执行过的一项执行:'; - const list=[ - '⒈令一名角色弃置X张牌', - ';', - '⒉摸X张牌', - ';', - '⒊重铸X张牌', - ';', - '⒋弃置X张牌', - ],info=get.info('dcjianzhuan').choices,storage=player.getStorage('dcjianzhuan'); - let choices=[]; - for(const k in info) choices.push(k); - for(let i=0;ii).includes(j); - if(goon&&storage.includes(choices[j])) str+=''; - str+=list[i]; - if(goon&&storage.includes(choices[j])) str+=''; + dcjianzhuan(player) { + let str = "锁定技。①当你于出牌阶段使用牌时,你选择此阶段未执行过的一项执行:"; + const list = [ + "⒈令一名角色弃置X张牌", + ";", + "⒉摸X张牌", + ";", + "⒊重铸X张牌", + ";", + "⒋弃置X张牌", + ], + info = get.info("dcjianzhuan").choices, + storage = player.getStorage("dcjianzhuan"); + let choices = []; + for (const k in info) choices.push(k); + for (let i = 0; i < list.length; i++) { + const j = i / 2, + goon = Array.from({ length: list.length }) + .map((_, i) => i) + .includes(j); + if (goon && storage.includes(choices[j])) + str += ''; + str += list[i]; + if (goon && storage.includes(choices[j])) str += ""; } - return str+'(X为此技能于本阶段的发动次数)。②出牌阶段结束时,若你本阶段执行过〖渐专①〗的所有选项,则你随机移除〖渐专①〗的一项。'; + return ( + str + + "(X为此技能于本阶段的发动次数)。②出牌阶段结束时,若你本阶段执行过〖渐专①〗的所有选项,则你随机移除〖渐专①〗的一项。" + ); }, }, - perfectPair:{}, - characterReplace:{ - dongbai:['dongbai','re_dongbai','jsrg_dongbai'], - chunyuqiong:['chunyuqiong','re_chunyuqiong','jsrg_chunyuqiong'], - kanze:['kanze','re_kanze'], - chendeng:['ol_chendeng','re_chendeng','chendeng','jsrg_chendeng'], - miheng:['re_miheng','miheng'], - liuba:['ol_liuba','dc_liuba','liuba'], - lvkuanglvxiang:['lvkuanglvxiang','dc_lvkuanglvxiang'], - dc_huangquan:['xf_huangquan','dc_huangquan'], - yuejiu:['dc_yuejiu','yuejiu'], - jiling:['dc_jiling','tw_jiling','jiling'], - sp_jiaxu:['sp_jiaxu','dc_sp_jiaxu','yj_jiaxu'], - qiaorui:['qiaorui','tw_qiaorui'], - mamidi:['mamidi','xin_mamidi'], - mengyou:['mengyou','ns_mengyou'], - zhangchu:['zhangchu','jsrg_zhangchu'], - xianglang:['xianglang','mb_xianglang'], - chengui:['chengui','mb_chengui'], - liuyong:['liuyong','jsrg_liuyong'], - zhangxuan:['zhangxuan','jsrg_zhangxuan'], - gaoxiang:['gaoxiang','jsrg_gaoxiang'], - lingcao:['lingcao','dc_lingcao'], - sp_menghuo:['sp_menghuo','dc_sp_menghuo'], - sunchen:['dc_sunchen','pe_sunchen'], + perfectPair: {}, + characterReplace: { + dongbai: ["dongbai", "re_dongbai", "jsrg_dongbai"], + chunyuqiong: ["chunyuqiong", "re_chunyuqiong", "jsrg_chunyuqiong"], + kanze: ["kanze", "re_kanze"], + chendeng: ["ol_chendeng", "re_chendeng", "chendeng", "jsrg_chendeng"], + miheng: ["re_miheng", "miheng"], + liuba: ["ol_liuba", "dc_liuba", "liuba"], + lvkuanglvxiang: ["lvkuanglvxiang", "dc_lvkuanglvxiang"], + dc_huangquan: ["xf_huangquan", "dc_huangquan"], + yuejiu: ["dc_yuejiu", "yuejiu"], + jiling: ["dc_jiling", "tw_jiling", "jiling"], + sp_jiaxu: ["sp_jiaxu", "dc_sp_jiaxu", "yj_jiaxu"], + qiaorui: ["qiaorui", "tw_qiaorui"], + mamidi: ["mamidi", "xin_mamidi"], + mengyou: ["mengyou", "ns_mengyou"], + zhangchu: ["zhangchu", "jsrg_zhangchu"], + xianglang: ["xianglang", "mb_xianglang"], + chengui: ["chengui", "mb_chengui"], + liuyong: ["liuyong", "jsrg_liuyong"], + zhangxuan: ["zhangxuan", "jsrg_zhangxuan"], + gaoxiang: ["gaoxiang", "jsrg_gaoxiang"], + lingcao: ["lingcao", "dc_lingcao"], + sp_menghuo: ["sp_menghuo", "dc_sp_menghuo"], + sunchen: ["dc_sunchen", "pe_sunchen"], }, - translate:{ - re_panfeng:'潘凤', - xinkuangfu:'狂斧', - xinkuangfu_info:'出牌阶段限一次,你可选择:1,弃置装备区里的一张牌,你使用无对应实体牌的普【杀】。若此【杀】造成伤害,你摸两张牌。2,弃置一名其他角色装备区里的一张牌,你使用无对应实体牌的普【杀】。若此【杀】未造成伤害,你弃置两张手牌。', - xingdaorong:'邢道荣', - xuxie:'虚猲', - xuxie_info:'出牌阶段开始时,你可以减1点体力上限并选择所有距离1以内的角色,弃置这些角色的各一张牌或令这些角色各摸一张牌。出牌阶段结束时,若你的体力上限不为全场最多,则你加1点体力上限,然后回复1点体力或摸两张牌。', - caoxing:'曹性', - cxliushi:'流矢', - cxliushi2:'流矢', - cxliushi_info:'出牌阶段,你可以将一张红桃牌置于牌堆顶,视为对一名角色使用一张【杀】(无距离限制且不计入使用次数)。当此【杀】造成伤害后,受到伤害的角色获得一个“流”。有“流”的角色手牌上限-X(X为其“流”数)。', - zhanwan:'斩腕', - zhanwan_info:'锁定技,有“流”的角色于弃牌阶段弃牌后,你摸等量的牌,然后其移去所有的“流”。', - re_chunyuqiong:'淳于琼', - recangchu:'仓储', - recangchu2:'仓储', - recangchu3:'仓储', - recangchu_info:'锁定技。①游戏开始时,你获得3个“粮”。你的手牌上限+X(X为“粮”数)。②每回合限一次,当你于回合外得到牌后,你获得一个“粮”。(你的“粮”数不能超过存活角色数)', - reliangying:'粮营', - reliangying_info:'弃牌阶段开始时,你可以摸至多X张牌,然后交给等量的角色各一张牌。(X为你的“粮”数)', - reshishou:'失守', - reshishou2:'失守', - reshishou_info:'锁定技,当你使用【酒】时或受到1点火焰伤害后,你移去一个“粮”。准备阶段,若你没有“粮”,你失去1点体力。', - xiahoujie:'夏侯杰', - liedan:'裂胆', - liedan_info:'锁定技,其他角色的准备阶段开始时,若X大于0,则你摸X张牌。若X等于3,则你加1点体力上限(至多加到8)。若X为0,则你失去1点体力并获得一枚“裂”(X为你的手牌数,体力值,装备区牌数中大于其的数量)。准备阶段,若“裂”数大于4,则你死亡。', - zhuangdan:'壮胆', - zhuangdan_mark:'壮胆', - zhuangdan_info:'锁定技,其他角色的回合结束时,若你的手牌数为全场唯一最多,则你令〖裂胆〗失效直到你下回合结束。', - dc_caiyang:'蔡阳', - dcxunji:'寻嫉', - dcxunji_info:'出牌阶段限一次,你可以选择一名其他角色。该角色的下个结束阶段开始时,若其此回合使用过黑色牌,则你视为对其使用一张【决斗】,且当此【决斗】对其造成伤害后,其对你造成等量的伤害。', - dcjiaofeng:'交锋', - dcjiaofeng_info:'锁定技。每回合限一次,当你造成伤害时,若你本回合内未造成过其他伤害且你已损失的体力值:大于0,则你摸一张牌;大于1,则此伤害+1;大于2,则你回复1点体力。', - zhoushan:'周善', - dcmiyun:'密运', - dcmiyun_tag:'安', - dcmiyun_info:'锁定技。①一轮游戏开始时,你依次执行:1.若你有“安”,你将包括“安”的在内的任意张手牌交给一名其他角色,然后你将手牌补至体力上限;2.你正面向上获得一名其他角色的一张牌,称为“安”。②当你不因〖密运①〗失去“安”后,你失去1点体力。', - dcdanying:'胆迎', - dcdanying_info:'每回合限一次。你可以展示“安”,然后视为使用或打出一张【杀】或【闪】。然后当你于本回合下一次成为牌的目标后,使用者弃置你的一张牌。', - re_sunluyu:'孙鲁育', - remeibu:'魅步', - remeibu_info:'其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌A,该角色于本阶段内拥有〖止息〗,且当其因〖止息〗弃置与牌A花色相同的牌时,你获得之。', - rezhixi:'止息', - rezhixi_info:'锁定技,当你使用【杀】或普通锦囊牌时,你弃置一张手牌。', - remumu:'穆穆', - remumu_info:'出牌阶段开始时,你可以选择一项:1.弃置一名其他角色装备区里的一张牌,然后你本回合可使用【杀】的次数+1;2.获得一名角色装备区里的一张牌,然后你本回合可使用【杀】的次数-1。', - re_dongbai:'董白', - relianzhu:'连诛', - relianzhu_info:'出牌阶段限一次,你可将一张牌正面朝上交给一名其他角色。若此牌为:红色,你摸一张牌;黑色,对方弃置两张牌或令你摸两张牌。', - rexiahui:'黠慧', - rexiahui_info:'锁定技,①你的黑色牌不计入手牌上限。②当有其他角色获得你的黑色牌后,其于下次扣减体力前不能使用,打出,弃置这些牌。③一名其他角色的回合结束时,若其本回合失去过其所有“黠慧”牌,则其失去1点体力。', - heyan:'何晏', - yachai:'崖柴', - yachai_info:'当你受到伤害后,你可令伤害来源选择一项:①其本回合不能再使用手牌,然后你摸两张牌;②其展示所有手牌,然后将其手牌中一种花色的所有牌交给你;③弃置一半数量的手牌(向上取整)。', - qingtan:'清谈', - qingtan_info:'出牌阶段限一次,你可令所有有手牌的角色同时选择一张手牌并同时展示。你可以获得其中一种花色的牌,然后展示此花色牌的角色各摸一张牌。若如此做,弃置其他的牌。', - zhaoyan:'赵嫣', - jinhui:'锦绘', - jinhui_info:'出牌阶段限一次,你可以随机展示牌堆中的三张不具有“伤害”标签且使用目标范围为“自己”或“一名角色”的牌,然后选择一名其他角色。该角色选择并按如下“锦绘”规则使用其中一张,然后你可以按如下“锦绘”规则使用剩余的任意张牌:若此牌的使用目标为“自己”,则对自己使用该牌,否则对对方使用该牌(无距离限制且不计入次数限制)。', - qingman:'轻幔', - qingman_info:'锁定技。一名角色的回合结束时,你将手牌摸至X张(X为其装备区中空栏的数量)。', - wangtao:'王桃', - wangyue:'王悦', - huguan:'护关', - huguan_info:'一名角色于出牌阶段内使用第一张牌时,若此牌为红色,则你可以声明一种花色。该花色的牌不计入其本回合的手牌上限。', - yaopei:'摇佩', - yaopei_info:'其他角色的弃牌阶段结束时,若你本局游戏内对其发动过〖护关〗,则你可以弃置一张与其于此阶段弃置的牌花色均不相同的牌。然后你选择一项:①其摸两张牌,你回复1点体力。②其回复1点体力,你摸两张牌。', - mingluan:'鸣鸾', - mingluan_info:'其他角色的结束阶段开始时,若有角色于本回合内回复过体力,则你可以弃置任意张牌,然后摸X张牌(X为当前角色的手牌数,且至多摸至5张)。', - zhangxuan:'张嫙', - tongli:'同礼', + translate: { + re_panfeng: "潘凤", + xinkuangfu: "狂斧", + xinkuangfu_info: + "出牌阶段限一次,你可选择:1,弃置装备区里的一张牌,你使用无对应实体牌的普【杀】。若此【杀】造成伤害,你摸两张牌。2,弃置一名其他角色装备区里的一张牌,你使用无对应实体牌的普【杀】。若此【杀】未造成伤害,你弃置两张手牌。(均无距离和次数限制)", + xingdaorong: "邢道荣", + xuxie: "虚猲", + xuxie_info: + "出牌阶段开始时,你可以减1点体力上限并选择所有距离1以内的角色,弃置这些角色的各一张牌或令这些角色各摸一张牌。出牌阶段结束时,若你的体力上限不为全场最多,则你加1点体力上限,然后回复1点体力或摸两张牌。", + caoxing: "曹性", + cxliushi: "流矢", + cxliushi2: "流矢", + cxliushi_info: + "出牌阶段,你可以将一张红桃牌置于牌堆顶,视为对一名角色使用一张【杀】(无距离限制且不计入使用次数)。当此【杀】造成伤害后,受到伤害的角色获得一个“流”。有“流”的角色手牌上限-X(X为其“流”数)。", + zhanwan: "斩腕", + zhanwan_info: "锁定技,有“流”的角色于弃牌阶段弃牌后,你摸等量的牌,然后其移去所有的“流”。", + re_chunyuqiong: "淳于琼", + recangchu: "仓储", + recangchu2: "仓储", + recangchu3: "仓储", + recangchu_info: + "锁定技。①游戏开始时,你获得3个“粮”。你的手牌上限+X(X为“粮”数)。②每回合限一次,当你于回合外得到牌后,你获得一个“粮”。(你的“粮”数不能超过存活角色数)", + reliangying: "粮营", + reliangying_info: + "弃牌阶段开始时,你可以摸至多X张牌,然后交给等量的角色各一张牌。(X为你的“粮”数)", + reshishou: "失守", + reshishou2: "失守", + reshishou_info: + "锁定技,当你使用【酒】时或受到1点火焰伤害后,你移去一个“粮”。准备阶段,若你没有“粮”,你失去1点体力。", + xiahoujie: "夏侯杰", + liedan: "裂胆", + liedan_info: + "锁定技,其他角色的准备阶段开始时,若X大于0,则你摸X张牌。若X等于3,则你加1点体力上限(至多加到8)。若X为0,则你失去1点体力并获得一枚“裂”(X为你的手牌数,体力值,装备区牌数中大于其的数量)。准备阶段,若“裂”数大于4,则你死亡。", + zhuangdan: "壮胆", + zhuangdan_mark: "壮胆", + zhuangdan_info: + "锁定技,其他角色的回合结束时,若你的手牌数为全场唯一最多,则你令〖裂胆〗失效直到你下回合结束。", + dc_caiyang: "蔡阳", + dcxunji: "寻嫉", + dcxunji_info: + "出牌阶段限一次,你可以选择一名其他角色。该角色的下个结束阶段开始时,若其此回合使用过黑色牌,则你视为对其使用一张【决斗】,且当此【决斗】对其造成伤害后,其对你造成等量的伤害。", + dcjiaofeng: "交锋", + dcjiaofeng_info: + "锁定技。每回合限一次,当你造成伤害时,若你本回合内未造成过其他伤害且你已损失的体力值:大于0,则你摸一张牌;大于1,则此伤害+1;大于2,则你回复1点体力。", + zhoushan: "周善", + dcmiyun: "密运", + dcmiyun_tag: "安", + dcmiyun_info: + "锁定技。①一轮游戏开始时,你依次执行:1.若你有“安”,你将包括“安”的在内的任意张手牌交给一名其他角色,然后你将手牌补至体力上限;2.你正面向上获得一名其他角色的一张牌,称为“安”。②当你不因〖密运①〗失去“安”后,你失去1点体力。", + dcdanying: "胆迎", + dcdanying_info: + "每回合限一次。你可以展示“安”,然后视为使用或打出一张【杀】或【闪】。然后当你于本回合下一次成为牌的目标后,使用者弃置你的一张牌。", + re_sunluyu: "孙鲁育", + remeibu: "魅步", + remeibu_info: + "其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌A,该角色于本阶段内拥有〖止息〗,且当其因〖止息〗弃置与牌A花色相同的牌时,你获得之。", + rezhixi: "止息", + rezhixi_info: "锁定技,当你使用【杀】或普通锦囊牌时,你弃置一张手牌。", + remumu: "穆穆", + remumu_info: + "出牌阶段开始时,你可以选择一项:1.弃置一名其他角色装备区里的一张牌,然后你本回合可使用【杀】的次数+1;2.获得一名角色装备区里的一张牌,然后你本回合可使用【杀】的次数-1。", + re_dongbai: "董白", + relianzhu: "连诛", + relianzhu_info: + "出牌阶段限一次,你可将一张牌正面朝上交给一名其他角色。若此牌为:红色,你摸一张牌;黑色,对方弃置两张牌或令你摸两张牌。", + rexiahui: "黠慧", + rexiahui_info: + "锁定技,①你的黑色牌不计入手牌上限。②当有其他角色获得你的黑色牌后,其于下次扣减体力前不能使用,打出,弃置这些牌。③一名其他角色的回合结束时,若其本回合失去过其所有“黠慧”牌,则其失去1点体力。", + heyan: "何晏", + yachai: "崖柴", + yachai_info: + "当你受到伤害后,你可令伤害来源选择一项:①其本回合不能再使用手牌,然后你摸两张牌;②其展示所有手牌,然后将其手牌中一种花色的所有牌交给你;③弃置一半数量的手牌(向上取整)。", + qingtan: "清谈", + qingtan_info: + "出牌阶段限一次,你可令所有有手牌的角色同时选择一张手牌并同时展示。你可以获得其中一种花色的牌,然后展示此花色牌的角色各摸一张牌。若如此做,弃置其他的牌。", + zhaoyan: "赵嫣", + jinhui: "锦绘", + jinhui_info: + "出牌阶段限一次,你可以随机亮出牌堆中的三张不具有“伤害”标签且使用目标范围为“自己”或“一名角色”的牌,然后选择一名其他角色。该角色选择并按如下“锦绘”规则使用其中一张,然后你可以按如下“锦绘”规则使用剩余的任意张牌:若此牌的使用目标为“自己”,则对自己使用该牌,否则对对方使用该牌(无距离限制且不计入次数限制)。", + qingman: "轻幔", + qingman_info: "锁定技。一名角色的回合结束时,你将手牌摸至X张(X为其装备区中空栏的数量)。", + wangtao: "王桃", + wangyue: "王悦", + huguan: "护关", + huguan_info: + "一名角色于出牌阶段内使用第一张牌时,若此牌为红色,则你可以声明一种花色。该花色的牌不计入其本回合的手牌上限。", + yaopei: "摇佩", + yaopei_info: + "其他角色的弃牌阶段结束时,若你本回合内对其发动过〖护关〗,则你可以弃置一张与其于此阶段弃置的牌花色均不相同的牌。然后你选择一项:①其摸两张牌,你回复1点体力。②其回复1点体力,你摸两张牌。", + mingluan: "鸣鸾", + mingluan_info: + "其他角色的结束阶段开始时,若有角色于本回合内回复过体力,则你可以弃置任意张牌,然后摸X张牌(X为当前角色的手牌数,且至多摸至5张)。", + zhangxuan: "张嫙", + tongli: "同礼", //tongli_info:'当你于出牌阶段内不因〖同礼〗而使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内不因〖同礼〗而使用过的牌数相等,则你可以于此牌结算结束后依次视为对此牌的所有目标使用X张名称和属性相同的牌(X为你手牌中的花色数)。', - tongli_info:'当你于出牌阶段内使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内使用过的牌数相等,则你可以令此牌额外结算X次(X为你手牌中的花色数)。', - shezang:'奢葬', - shezang_info:'每轮限一次。当你或你回合内的其他角色进入濒死状态时,你可以从牌堆中获得每种花色的牌各一张。', - tengyin:'滕胤', - chenjian:'陈见', - chenjian_info:'准备阶段,你可展示牌堆顶的3+X张牌(X为你“陈见”标记的数量且至多为2),然后执行以下一至两项:⒈弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌。⒉使用其中剩余的一张牌。若你执行了所有选项,则你获得一枚“陈见”并重铸所有手牌。', - xixiu:'皙秀', - xixiu_info:'锁定技。①当你成为其他角色使用牌的目标时,若你的装备区内有和此牌花色相同的牌,则你摸一张牌。②若你装备区内的牌数为1,则其他角色不能弃置你装备区内的牌。', - zhangyao:'张媱', - yuanyu:"怨语", - yuanyu_info:"出牌阶段限一次。你可以摸一张牌,然后选择一张手牌和一名其他角色。该角色获得如下效果直到你发动〖夕颜〗:{你与该角色的弃牌阶段开始时,或当该角色造成1点伤害后,其须将一张手牌作为“怨”置于你的武将牌上}。然后你将你选择的手牌作为“怨”置于你的武将牌上。", - xiyan:"夕颜", - xiyan_info:"当有牌作为“怨”移动到你的武将牌上后,若“怨”中的花色数达到4种,则你可以获得所有“怨”。然后若当前回合角色:是你,你本回合手牌上限+4且使用牌无次数限制且重置你的〖怨语〗于此阶段的发动次数;不是你,你可令当前回合角色本回合手牌上限-4且不能使用基本牌。", - xiahoulingnv:'夏侯令女', - fuping:'浮萍', - fuping_info:'①其他角色对你使用的牌结算结束后,若你未因此技能记录过此牌的名称且你有未废除的装备栏,则你可以废除一个装备栏,记录此牌的名称。②每回合每种牌名限一次。你可以将一张非基本牌当做〖浮萍①〗记录过的基本牌或锦囊牌使用或打出。③若你的所有装备栏均已被废除,则你使用牌无距离限制。', - weilie:'炜烈', - weilie_info:'每局游戏限X次。出牌阶段,你可以弃置一张牌并选择一名已受伤的角色,令该角色回复1点体力。然后若其体力值小于体力上限,则其摸一张牌(X为你〖浮萍①〗中的记录数+1)。', - dc_sunru:'孙茹', - xiecui:'撷翠', - xiecui_info:'当有角色于回合内第一次因执行牌的效果而造成伤害时,你可以令此伤害+1。若其势力为吴,则该角色获得此伤害牌对应的实体牌,且其本回合的手牌上限+1。', - youxu:'忧恤', - youxu_info:'一名角色A的回合结束时,若其手牌数大于体力值,则你可以展示A的一张牌,然后将此牌交给另一名角色B。若B的体力值为全场最少,则B回复1点体力。', - huaxin:'华歆', - wanggui:'望归', - wanggui_info:'每回合限触发一次,当你造成或受到伤害后,若你:仅明置了此武将牌,则你可对与你势力不同的一名角色造成1点伤害;武将牌均明置,则你可令与你势力相同的角色各摸一张牌。', - spwanggui:'望归', - spwanggui_info:'①当你受到伤害后,你可以摸一张牌,或和一名势力相同的其他角色各摸一张牌;②每回合限一次,当你造成伤害后,你可以对一名与你势力不同的角色造成1点伤害。', - xibing:'息兵', - xibing_info:'当一名其他角色在其出牌阶段内使用黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至当前体力值(至多摸五张)且本回合不能再使用手牌。', - xibing_info_guozhan:'当一名其他角色在其出牌阶段内使用第一张黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至当前体力(至多摸五张)值且本回合不能再使用手牌。若你与其均明置了所有武将牌,则你可以暗置你与其各一张武将牌且本回合不能再明置此武将牌。', - luyusheng:'陆郁生', - zhente:'贞特', - zhente2:'贞特', - zhente_info:'每回合限一次,当你成为其他角色使用基本牌或普通锦囊牌的目标后,你可令使用者选择一项:1.本回合不能再使用与此牌颜色相同的牌;2.此牌对你无效。', - zhente_info_guozhan:'每回合限一次,当你成为其他角色使用黑色基本牌或黑色普通锦囊牌的目标后,你可令使用者选择一项:1.本回合不能再使用黑色牌;2.此牌对你无效。', - zhiwei:'至微', - zhiwei2:'至微', - zhiwei_info:'游戏开始时/你的回合开始时,若场上没有因此法被选择过的角色存活,则你选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。', - zhiwei_info_guozhan:'你明置此武将牌时,选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。该角色死亡时,若你的两个武将牌均明置,你暗置此武将牌。', - zhanghu:'张虎', - cuijian:'摧坚', - cuijian_info:'出牌阶段限一次,你可以选择一名有手牌的其他角色。若其手牌中有【闪】,则其将所有【闪】和防具牌交给你,然后你交给其等量的牌。', - zhtongyuan:'同援', - zhtongyuan_info:'锁定技。①当你使用红色锦囊牌后,你于〖摧坚〗后增加“若其手牌中没有【闪】,则你摸两张牌”;②当你使用或打出红色基本牌后,你删除〖摧坚〗中的“,然后你交给其等量的牌”。③当你使用红色的普通锦囊牌/基本牌时,若你已发动过〖摧坚①〗和〖摧坚②〗,则此牌不可被响应/可额外增加一个目标。', - lvlingqi:'吕玲绮', - guowu:'帼舞', - guowu_info:'出牌阶段开始时,你可以展示全部手牌,根据你展示的类型数,你获得对应效果:至少一类,从弃牌堆获得一张【杀】;至少两类,此阶段使用牌无距离限制;至少三类,此阶段使用【杀】或普通锦囊牌可以多指定两个目标。', - guowu_info_guozhan:'出牌阶段开始时,你可以展示全部手牌,根据你展示的类型数,你获得对应效果:至少一类,从弃牌堆获得一张【杀】;至少两类,此阶段使用牌无距离限制;至少三类,此阶段使用【杀】可以多指定两个目标。', - zhuangrong:'妆戎', - zhuangrong_info:'觉醒技,一名角色的回合结束时,若你的体力值或手牌数为1,你减1点体力上限并回复体力至上限,将手牌摸至体力上限,然后获得〖神威〗和〖无双〗。', - llqshenwei:'神威', - llqshenwei_info:'锁定技,摸牌阶段开始时,你令额定摸牌数+2;你的手牌上限+2。', - re_kanze:'阚泽', - rekuanshi:'宽释', - rekuanshi_info:'结束阶段,你可以选择一名角色。你获得如下效果直到你下回合开始:每回合限一次,当其于一回合内受到第2点伤害后,其回复1点体力。', - liuyong:'刘永', - zhuning:'诛佞', - zhuning_info:'出牌阶段限一次。你可将任意张牌交给一名其他角色(称为“隙”),然后可视为使用一张具有伤害标签的基本牌/锦囊牌(不计入次数限制)。若你以此法使用的牌未造成伤害,则你将〖诛佞〗于本回合内改为“限两次”。', - fengxiang:'封乡', - fengxiang_info:'锁定技。①当你受到伤害后,若场上:存在“隙”唯一最多的角色,则其回复1点体力;不存在,则你摸一张牌。②当有角色的手牌移动后,若场上“隙”最多的角色因此发生变化,则你摸一张牌。', - fengxiang_tag:'隙', - re_xunchen:'荀谌', - refenglve:'锋略', - refenglve_info:'出牌阶段限一次,你可以和一名其他角色进行拼点。若你赢,其将区域内的两张牌交给你;若平局,则你令此技能于本阶段内的发动次数上限+1;若你输,其获得你的拼点牌。', - anyong:'暗涌', - anyong_info:'当一名角色于其回合内第一次对其他角色造成伤害后,若伤害值为1,则你可弃置一张牌,并对受伤角色造成1点伤害。', - wanniangongzhu:'万年公主', - zhenge:'枕戈', - zhenge_info:'准备阶段,你可以选择一名角色。该角色本局游戏的攻击范围+1(至多+5)。然后若所有其他角色都在该角色的攻击范围内,则你可以令其视为对另一名角色使用一张【杀】。', - xinghan:'兴汉', - xinghan_info:'锁定技,每回合的第一张【杀】造成伤害后,若此【杀】的使用者成为过〖枕戈〗的目标,则你摸一张牌。若你的手牌数不是全场唯一最多的,则改为摸X张牌(X为该角色的攻击范围且最多为5)。', - re_chendeng:'陈登', - refuyuan:'扶援', - refuyuan_info:'一名角色成为【杀】的目标后,若其本回合内没有成为过其他红色牌的目标,则你可以令其摸一张牌。', - reyingshui:'营说', - reyingshui_info:'出牌阶段限一次,你可将一张牌交给攻击范围内的一名其他角色,然后其选择一项:①交给你至少两张装备牌。②受到1点伤害。', - rewangzu:'望族', - rewangzu_info:'每回合限一次。当你受到其他角色造成的伤害时,你可随机弃置一张手牌,令此伤害-1。若你所在阵营的存活角色数是全场最多的,则你可以自行选择弃置的牌。', - re_miheng:'祢衡', - rekuangcai:'狂才', - rekuangcai_info:'锁定技。①你于回合内使用牌无距离和次数限制。②弃牌阶段开始时,若你本回合内:未使用过牌,则你本局游戏的手牌上限+1;使用过牌但未造成过伤害,则你本局游戏的手牌上限-1。③结束阶段开始时,你摸X张牌(X为你本回合内造成的伤害且至多为5)。', - reshejian:'舌箭', - reshejian_info:'当你成为其他角色使用牌的唯一目标后,你可以弃置至少两张手牌。若如此做,你选择一项:⒈弃置其等量的牌。⒉对其造成1点伤害。', - fengxi:'冯熙', - yusui:'玉碎', - yusui_info:'当你成为其他角色使用黑色牌的目标后,你可以失去1点体力,然后选择一项:⒈令其将手牌数弃置至与你相同;⒉令其失去Y点体力(Y为其的体力值减去你的体力值,不为正时不可选择)。', - boyan:'驳言', - boyan_info:'出牌阶段限一次,你可选择一名其他角色。其将手牌摸至体力上限(至多摸至五张),然后其本回合不能使用或打出手牌。', - re_dengzhi:'邓芝', - jianliang:'简亮', - jianliang_info:'摸牌阶段开始时,若你的手牌数不为全场最多,则你可以令至多两名角色各摸一张牌。', - weimeng:'危盟', - weimeng_info:'出牌阶段限一次,你可以获得一名其他角色的至多X张手牌,然后交给其等量的牌(X为你的体力值)。若你给出的牌点数之和:大于得到的牌,则你摸一张牌;小于得到的牌,弃置该角色区域内的一张牌。', - mamidi:'马日磾', - bingjie:'秉节', - bingjie_info:'出牌阶段开始时,你可减1点体力上限,然后当你于本阶段内使用【杀】或普通锦囊牌指定其他角色为目标后,其弃置一张牌。若其弃置的牌与你使用的牌颜色相同,其无法响应此牌。', - zhengding:'正订', - zhengding_info:'锁定技。当你于回合外使用或打出牌响应其他角色使用的牌时,若这两张牌颜色相同,则你加1点体力上限并回复1点体力。', - dc_jiben:'吉本', - xunli:'寻疠', - xunli_info:'锁定技。①当有黑色牌因弃置而进入弃牌堆后,若X大于0,则你将其中的X张牌置于武将牌上作为“疠”(X=min(这些牌的数量,9-Y),Y=你的“疠”数)。②出牌阶段开始时,你可以用任意张黑色手牌交换等量的“疠”。', - zhishi:'指誓', - zhishi_info:'结束阶段,你可选择一名角色。当该角色于你的下回合开始前{成为【杀】的目标后或进入濒死状态时},你可移去任意张“疠”,然后其摸等量的牌。', - lieyi:'烈医', - lieyi_info:'出牌阶段限一次。你可以展示所有“疠”并选择一名其他角色,对其使用其中的一张可对其使用的牌(无距离和次数限制)并重复此流程,并将其余的牌置于弃牌堆。然后若其存活且未于此流程中因受到伤害而进入过濒死状态,则你失去1点体力。', - guanning:'管宁', - dunshi:'遁世', - dunshi_info:'每回合限一次。你可以视为使用或打出一张【杀】/【闪】/【桃】/【酒】,然后当前回合角色于本回合内下一次造成伤害时,你选择两项:⒈防止此伤害。系统从技能名中包含“仁/义/礼/智/信”字样的技能中随机选择三个其未拥有的技能,然后你令当前回合角色获得其中一个技能。⒉从〖遁世〗中删除你本次使用或打出的牌并获得一个“席”。⒊减1点体力上限并摸X张牌(X为你的“席”数)。', - dc_gaolan:'高览', - xizhen:'袭阵', - xizhen_info:'出牌阶段开始时,你可选择一名其他角色,视为对其使用【杀】或【决斗】。然后当有角色于本阶段内使用或打出牌响应你时,该角色回复1点体力,你摸一张牌(若其满体力,改为两张)。', - dc_huangchengyan:'黄承彦', - dcjiezhen:'解阵', - dcjiezhen_info:'出牌阶段限一次,你可选择一名其他角色。该角色获得〖八阵〗,且其所有不为{锁定技、限定技、觉醒技、主公技、带有Charlotte标签}的技能失效。你的下回合开始时,或其因〖八卦阵〗发起的判定结算结束后,你令其恢复其以此法失效的所有技能并失去以此法获得的〖八阵〗,然后获得其区域内的一张牌。', - dczecai:'择才', - dczecai_info:'限定技。一轮游戏开始时,若游戏轮数大于1,则你可令一名其他角色获得〖集智〗直到下一轮游戏开始;若其是上一轮内使用过锦囊牌数量唯一最多的角色,则其获得一个额外的回合。', - dcyinshi:'隐世', - dcyinshi_info:'锁定技。①每回合限一次,当你受到伤害时,若此伤害的渠道不为有颜色的牌,则你防止此伤害。②当有因〖八卦阵〗发起的判定的判定牌生效时,你获得此判定牌。', - tenggongzhu:'滕公主', - xingchong:'幸宠', - xingchong_info:'一轮游戏开始时,你可声明两个自然数X和Y,且(X+Y)≤min(5, 你的体力上限)。你摸X张牌并展示Y张手牌。若如此做,当你于本轮内失去一张以此法展示的牌后,你摸两张牌。', - liunian:'流年', - liunian_info:'锁定技。一名角色的回合结束时,若本回合内进行了本次游戏的第一次洗牌,则你加1点体力上限;若本回合内进行了本次游戏的第二次洗牌,则你于本回合结束时回复1点体力,且本局游戏内的手牌上限+10。', - caimaozhangyun:'蔡瑁张允', - lianzhou:'连舟', - lianzhou_info:'锁定技。准备阶段,你横置你的武将牌。然后你可横置任意名体力值等于你的角色。', - jinglan:'惊澜', - jinglan_info:'锁定技。当你造成伤害后,若你的手牌数:大于体力值,你弃置四张手牌;等于体力值,你弃置一张手牌并回复1点体力;小于体力值,你受到1点无来源火焰伤害并摸五张牌。', - dc_yanghu:'羊祜', - dcdeshao:'德劭', - dcdeshao_info:'每回合限两次。当你成为其他角色使用的黑色牌的目标后,你可以摸一张牌,然后若其手牌数不小于你,则你弃置其一张牌。', - dcmingfa:'明伐', - dcmingfa_info:'①出牌阶段限一次。当你使用【杀】或普通锦囊牌结算结束后,若你的武将牌上没有“明伐”牌,则你可以将此牌作为“明伐”牌置于武将牌上并选择一名其他角色,记录该角色和此牌的名称。②一名角色的回合结束时,若其是你〖明伐①〗记录的角色,则你视为对其依次使用X张〖明伐①〗记录的牌,然后移去“明伐”牌(X为其手牌数且至少为1,至多为5)。③一名角色死亡时,若其是你〖明伐①〗记录的角色,则你移去“明伐”牌。', - dc_jiling:'纪灵', - dcshuangren:'双刃', - dcshuangren_info:'出牌阶段开始时,你可以和一名其他角色A进行拼点。若你赢,你选择一名角色B,或选择包含A在内的两名角色A和B(B的势力需与A相同),然后视为对被选择的角色使用一张【杀】(不计入次数限制);若你没赢,则你本阶段内不能使用【杀】。', - zhangxun:'张勋', - suizheng:'随征', - suizheng_info:'结束阶段,你可以选择一名角色A,获得如下效果直到其下回合结束:①A于下回合出牌阶段内使用【杀】的次数上限+1且无距离限制;②A下回合的出牌阶段结束时,你可以选择一名此阶段内受到过A造成的伤害的角色B,视为对B使用一张【杀】。', - dc_liuba:'刘巴', - dczhubi:'铸币', - dczhubi_info:'当有♦牌因弃置而进入弃牌堆后,你可以令系统从牌堆/弃牌堆中检索一张【无中生有】,并将此牌置于牌堆顶。', - dcliuzhuan:'流转', - dcliuzhuan_tag:'转', - dcliuzhuan_info:'锁定技。①其他角色于其回合内不于摸牌阶段而得到的牌称为“转”。②你不能成为实体牌中包含“转”的牌的目标。③当有“转”直接进入弃牌堆或经由处理区进入弃牌堆后,你获得之。', - huzhao:'胡昭', - midu:'弥笃', - midu_info:'出牌阶段限一次。你可以选择一项:⒈废除任意个装备栏或判定区,并令一名角色摸等量的牌。⒉恢复一个已经被废除的装备栏或判定区,然后你获得〖活墨〗直到下回合开始。', - xianwang:'贤望', - xianwang_info:'锁定技。若你有被废除的装备栏,则其他角色至你的距离+1,你至其他角色的距离-1;若废除的装备栏数大于2,则改为距离+2/-2。', - guanhai:'管亥', - suoliang:'索粮', - suoliang_info:'每回合限一次。当你对其他角色造成伤害后,你可以选择并展示其的至多X张牌(X为其体力上限且至多为5)。若这些牌中有♥或♣牌,则你获得这些牌;否则你弃置这些牌。', - qinbao:'侵暴', - qinbao_info:'锁定技。当你使用【杀】或普通锦囊牌时,你令所有手牌数不小于你的角色不能响应此牌。', - dc_lvkuanglvxiang:'吕旷吕翔', - dcshuhe:'数合', - dcshuhe_info:'出牌阶段限一次,你可以展示一张手牌并获得一枚“爵”。若场上有与此牌点数相同的牌,则你获得这些牌;否则你将此牌交给一名其他角色。', - dcliehou:'列侯', - dcliehou_info:'锁定技。摸牌阶段开始时,你令额定摸牌数+X;然后此摸牌阶段结束时,你选择一项:⒈弃置X张牌。⒉失去1点体力(X为你的“爵”数+1且至多为5)。', - yinfuren:'尹夫人', - dcyingyu:'媵予', - dcyingyu_info:'准备阶段开始时,你可以展示两名角色的各一张手牌。若这两张牌的花色不同,则你可以令一名角色获得另一名角色的展示牌。', - dcyongbi:'拥嬖', - dcyongbi_info:'限定技。出牌阶段,你可以将所有手牌交给一名其他男性角色。你将〖媵予〗的发动时机改为“准备阶段和结束阶段开始时”。然后若这些牌中包含的花色数:大于1,则你与其本局游戏的手牌上限+2;大于2,则当你或其于本局游戏内受到大于1的伤害时,此伤害-1。', - dc_huangquan:'黄权', - dcquanjian:'劝谏', - dcquanjian_info:'出牌阶段每项各限一次。你可以选择一项流程并选择一名其他角色A:⒈令A对其攻击范围内的另一名角色B造成1点伤害。⒉令A将手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用或打出手牌。然后A选择一项:⒈执行此流程。⒉本回合下次受到的伤害+1。', - dctujue:'途绝', - dctujue_info:'限定技。当你进入濒死状态时,你可以将所有牌交给一名其他角色。然后你回复等量的体力并摸等量的牌。', - chengui:'陈珪', - dcyingtu:'营图', - dcyingtu_info:'每回合限一次。当你的上家/下家于摸牌阶段外得到牌后,你可以获得其一张牌,然后将一张牌交给你的下家/上家。若你给出的牌为装备牌,则其使用之。', - dccongshi:'从势', - dccongshi_info:'一名角色使用的装备牌结算结束后,若其装备区内的牌数为全场最多,则你摸一张牌。', - wanglie:'王烈', - dcchongwang:'崇望', - dcchongwang_info:'其他角色使用基本牌或普通锦囊牌时,若你是本局游戏内上一张被使用的牌的使用者,则你可以选择一项:⒈令其于此牌结算结束后收回此牌对应的所有实体牌;⒉取消此牌的所有目标。', - dchuagui:'化归', - dchuagui_info:'出牌阶段开始时,你可以选择至多X名有牌的其他角色(X为场上每个阵营中最大阵营的人数,且你的选择结果不展示)。这些角色同时选择一项:⒈交给你一张牌,⒉展示一张牌。若这些角色均选择选项二,则你获得所有展示牌。', - gongsundu:'公孙度', - dczhenze:'震泽', - dczhenze_info:'弃牌阶段开始时,你可以选择一项:1.令所有手牌数与体力值大小关系与你不同的角色失去1点体力;2.令所有手牌数和体力值关系与你相同的角色回复1点体力。', - dcanliao:'安辽', - dcanliao_info:'出牌阶段限X次(X为群势力角色数)。你可以重铸一名角色的一张牌。', - dc_yuejiu:'乐就', - dccuijin:'催进', - dccuijin_info:'当你或你攻击范围内的角色使用【杀】或【决斗】时,你可以弃置一张牌,令此牌的伤害基数+1。然后当此牌被目标角色抵消或无效或防止伤害后,你摸两张牌并对使用者造成1点伤害。', - panghui:'庞会', - dcyiyong:'异勇', - dcyiyong_info:'当你对其他角色造成伤害时,若你有牌,你可以与其同时弃置至少一张牌。若你以此法弃置的牌的点数之和:不大于其,你摸X张牌;不小于其,此伤害+1(X为其以此法弃置的牌数)。', - chenjiao:'陈矫', - dcxieshoux:'协守/清严', - dcxieshou:'协守', - dcxieshou_info:'每回合限一次。当一名角色受到伤害后,若你至其的距离不大于2,你可以令你的手牌上限-1,然后其选择一项:1.回复1点体力;2.复原,摸两张牌。', - dcqingyan:'清严', - dcqingyan_info:'每回合限两次。当你成为其他角色使用黑色牌的目标后,若你的手牌数:小于体力值,你可以将手牌补至体力上限;不小于体力值,你可以弃置一张牌令你的手牌上限+1。', - dcqizi:'弃子', - dcqizi_info:'锁定技。你不能对至其的距离大于2且正在进行濒死流程的角色使用【桃】。', - leibo:'雷薄', - dcsilve:'私掠', - dcsilve_info:'游戏开始时,你选择一名其他角色(对其他角色不可见),称为“私掠”角色。然后你获得以下效果:①当“私掠”角色造成伤害后,若你本回合未因此效果得到过受伤角色的牌,你可以获得受伤角色一张牌;②当“私掠”角色受到其他角色造成的伤害后,若伤害来源存活,你须对伤害来源使用一张【杀】(无距离限制),否则你弃置一张手牌。', - dcshuaijie:'衰劫', - dcshuaijie_info:'限定技。出牌阶段,若你的体力值与装备区里的牌数均大于“私掠”角色,或没有角色有“私掠”,你可以减1点体力上限,然后选择一项:1.获得“私掠”角色至多三张牌;2.从牌堆随机获得三张类型各不同的牌。最后将你的“私掠”角色改为你。', - dc_sp_jiaxu:'新杀SP贾诩', - dc_sp_jiaxu_prefix:'新杀SP', - dcjianshu:'间书', - dcjianshu_info:'出牌阶段限一次。你可以将一张黑色手牌交给一名其他角色,并选择另一名其他角色,你令前者与后者拼点。赢的角色随机弃置一张牌,没赢的角色失去1点体力。若有角色因此死亡,你令你〖间书〗于此阶段发动的次数上限+1。', - dcyongdi:'拥嫡', - dcyongdi_info:'限定技。出牌阶段,你可以选择一名男性角色,若其:体力上限最少,其加1点体力上限;体力值最少,其回复1点体力;手牌数最少,其摸X张牌(X为其体力上限且至多为5)。', - liupi:'新杀刘辟', - liupi_prefix:'新杀', - dcjuying:'踞营', - dcjuying_info:'出牌阶段结束时,若你于此阶段内使用【杀】的次数未达到上限,你可以选择任意项:1.下回合使用【杀】的次数上限+1;2.本回合手牌上限+2;3.摸三张牌。若你选择的项数超过了你的体力值,你弃置一张牌。', - dc_huanghao:'新杀黄皓', - dc_huanghao_prefix:'新杀', - dcqinqing:'寝情', - dcqinqing_info:'结束阶段,你可以弃置一名攻击范围内包含一号位的其他角色一张牌。然后若其手牌数大于一号位,你摸一张牌。', - dccunwei:'存畏', - dccunwei_info:'锁定技。当你成为其他角色使用的锦囊牌的目标后,若你是唯一目标,你摸一张牌;否则你弃置一张牌。', - dc_zhaotongzhaoguang:'赵统赵广', - dcqingren:'青刃', - dcqingren_info:'结束阶段,你可以摸X张牌(X为你本回合发动〖翊赞〗的次数)。', - dclongyuan:'龙渊', - dclongyuan_info:'锁定技。一名角色的回合结束时,若你本局游戏已发动过至少三次〖翊赞〗,你摸两张牌并回复1点体力,修改〖翊赞〗。', - zhenghun:'郑浑', - dcqiangzhi:'强峙', - dcqiangzhi_info:'出牌阶段限一次。你可以弃置你和一名其他角色的共计三张牌。然后若你与其之中有角色因此失去了三张牌,该角色对另一名角色造成1点伤害。', - dcpitian:'辟田', - dcpitian_info:'①当你的牌被弃置后,或当你受到伤害后,你的手牌上限+1。②结束阶段,若你的手牌数小于手牌上限,你可以摸至手牌上限(至多摸五张),然后重置因〖辟田①〗增加的手牌上限。', - furongfuqian:'傅肜傅佥', - dcxuewei:'血卫', - dcxuewei_info:'结束阶段,你可以选择一名体力值不大于你的角色,然后你获得如下效果直到你的下回合开始时:当其受到伤害时,防止此伤害,然后你失去1点体力,你与其各摸一张牌(若该角色为你,则改为你摸一张牌)。', - dcyuguan:'御关', - dcyuguan_info:'一名角色的回合结束时,若你已损失的体力值为全场最多,你可以减1点体力上限,然后令至多X名角色将手牌摸至体力上限(X为你已损失的体力值)。', - qinlang:'秦朗', - dchaochong:'昊宠', - dchaochong_info:'当你使用牌后,你可以将手牌摸至或弃置至你的手牌上限数(至多摸五张)。然后若你以此法:得到牌,你的手牌上限-1;失去牌,你的手牌上限+1。', - dcjinjin:'矜谨', - dcjinjin_info:'每回合限两次。当你造成或受到伤害后,你可以重置因〖昊宠〗增加或减少的手牌上限,令伤害来源弃置至多X张牌,然后你摸Y张牌(X为你以此法变化的手牌上限且至少为1,Y为X减其以此法弃置的牌数)。', - xianglang:'向朗', - dckanji:'勘集', - dckanji_info:'出牌阶段限两次。你可以展示所有手牌,若花色均不同,你摸两张牌。然后若你的手牌因此包含了四种花色,你跳过下一个弃牌阶段。', - dcqianzheng:'愆正', - dcqianzheng_info:'每回合限两次。当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以重铸两张牌。若你以此法重铸的牌中没有与指定你为目标的牌类别相同的牌,你于此牌对应的实体牌进入弃牌堆后获得此牌对应的所有实体牌。', - qiaorui:'桥蕤', - dcaishou:'隘守', - dcaishou_tag:'隘', - dcaishou_info:'①结束阶段,你可以摸X张牌,称为“隘”(X为你的体力上限)。②准备阶段,你弃置所有“隘”,若你以此法弃置的牌数大于体力值且你的体力上限小于9,你加1点体力上限。③当你于回合外失去最后一张“隘”后,你减1点体力上限。', - dcsaowei:'扫围', - dcsaowei_info:'当一名其他角色使用【杀】结算结束后,若此牌的目标角色不包含你且均在你的攻击范围内,你可以将一张“隘”当做【杀】对所有目标角色使用。以此法转化的【杀】结算完毕后,若此【杀】造成过伤害,你获得此【杀】对应的实体牌。', - yuantanyuanxiyuanshang:'袁谭袁尚袁熙', - dcneifa:'内伐', - dcneifa_info:'出牌阶段开始时,你可以摸三张牌,然后弃置一张牌。若你弃置的牌类型为:基本牌,本阶段你不能使用锦囊牌,且【杀】的使用次数上限+X且可以额外指定一名目标;锦囊牌,本阶段你不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标(X为你发动〖内伐〗弃牌后手牌中因〖内伐〗而不能使用的牌的数量且最多为5。你以此法选择的额外目标均无距离限制)。', - dc_sunziliufang:'新杀孙资刘放', - dc_sunziliufang_prefix:'新杀', - dcqinshen:'勤慎', - dcqinshen_info:'弃牌阶段结束时,你可以摸X张牌(X为本回合未进入过弃牌堆的花色数)。', - dcweidang:'伪谠', - dcweidang_info:'其他角色的结束阶段,你可以将一张字数为X的牌置于牌堆底,然后获得牌堆里一张字数为X的牌(X为本回合未进入过弃牌堆的花色数)。若你能使用此牌,你使用之。', - mengjie:'孟节', - dcyinlu:'引路', - dcyinlu_info:'①游戏开始时,你令三名角色依次分别获得“乐泉”、“藿溪”、“瘴气”标记(若场上角色数为2则改为令一名其他角色获得其中2枚,你获得剩余标记),然后你获得“芸香”标记并获得1点“芸香”值。②准备阶段/有〖引路〗标记的角色死亡时,你可以移动一名角色的1枚/其的所有〖引路〗标记。', - dcyinlu_lequan:'乐泉', - dcyinlu_lequan_info:'结束阶段,你可以弃置一张♦牌并回复1点体力。', - dcyinlu_huoxi:'藿溪', - dcyinlu_huoxi_info:'结束阶段,你可以弃置一张♥牌并摸两张牌。', - dcyinlu_zhangqi:'瘴气', - dcyinlu_zhangqi_info:'锁定技。结束阶段,你须弃置一张♠牌,否则失去1点体力。', - dcyinlu_yunxiang:'芸香', - dcyinlu_yunxiang_info:'①结束阶段,你可以弃置一张♣牌,获得1点“芸香”值。②当你受到伤害时,你可以扣减所有“芸香”值,减少等量的伤害。', - dcyouqi:'幽栖', - dcyouqi_info:'锁定技。当其他角色因〖引路〗标记弃置牌后,你有一定概率获得此牌。', - dcyouqi_faq:'〖幽栖〗概率
              ', - dcyouqi_faq_info:'当满足〖幽栖〗条件时,系统生成一个随机数X∈[0,1)。若X小于(1.25-0.25Y),或幸运星模式已开启,你获得此牌(Y为你至该角色的距离)。', - dc_sunhanhua:'孙寒华', - dchuiling:'汇灵', - dchuiling_info:'锁定技。当你使用牌时,若此牌颜色为弃牌堆中数量较少的颜色,你获得1枚“灵”标记。若弃牌堆中:红色牌数大于黑色牌数,你回复1点体力;黑色牌数大于红色牌数,你可以弃置一名其他角色的一张牌。', - dcchongxu:'冲虚', - dcchongxu_info:'限定技。出牌阶段,若“灵”数不小于4,你可以失去〖汇灵〗,增加等同于“灵”数的体力上限(至多增加场上人数的体力上限),然后获得〖踏寂〗和〖清荒〗。', - dctaji:'踏寂', - dctaji_info:'当你失去手牌后,根据你失去牌的原因执行以下效果:1.使用:你弃置其他角色一张牌;2.打出:你摸一张牌;3.弃置:你回复1点体力;4.其他:你下一次对其他角色造成伤害时,此伤害+1。', - dcqinghuang:'清荒', - dcqinghuang_info:'出牌阶段开始时,你可以减1点体力上限,然后你于本回合发动〖踏寂〗时额外随机执行一种效果。', - dc_huojun:'霍峻', - dcgue:'孤扼', - dcgue_info:'每回合限一次。当你需要于回合外使用或打出【杀】或【闪】时,你可以发动此技能:你展示所有手牌,若其中【杀】和【闪】的数量之和不超过1,你视为使用或打出此牌。', - dcsigong:'伺攻', - dcsigong_info:'其他角色的回合结束时,若其于本回合内使用牌被响应过,你可以将手牌摸至或弃置至1,视为对其使用一张需使用X张【闪】抵消的【杀】,且此【杀】的伤害基数+1(X为你以此法弃置的牌数且至少为1)。当你以此法造成伤害后,该技能于本轮失效。', - peiyuanshao:'裴元绍', - dcmoyu:'没欲', - dcmoyu_info:'出牌阶段每名角色限一次。你可以获得一名其他角色区域里的一张牌,然后其可以对你使用一张无距离限制的【杀】,且此【杀】伤害基数为X(X为你于本回合发动此技能的次数)。若此【杀】对你造成了伤害,你令此技能于本回合失效。', - zhangchu:'张楚', - dcjizhong:'集众', - dcjizhong_info:'出牌阶段限一次。你可以令一名其他角色摸两张牌,然后其选择一项:1.若其没有“信众”标记,其获得“信众”标记;2.交给你三张手牌。', - dcrihui:'日彗', - dcrihui_info:'每回合限一次。当你使用普通锦囊牌或黑色基本牌结算结束后,若此牌的目标数为1且目标不为你,且其:没有“信众”,则所有有“信众”的角色依次视为对其使用一张与此牌牌名和属性相同的牌;有“信众”,则你可以获得其区域里的一张牌。', - dcguangshi:'光噬', - dcguangshi_info:'锁定技。准备阶段,若所有其他角色均有“信众”,你摸两张牌并失去1点体力。', - dongwan:'董绾', - dcshengdu:'生妒', - dcshengdu_info:'回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为摸牌数乘以其拥有的“生妒”标记数)。', - dcjieling:'介绫', - dcjieling_info:'出牌阶段每种花色限一次,你可以将两张花色不同的手牌当无距离限制且无任何次数限制的【杀】使用。然后若此【杀】:造成了伤害,所有目标角色失去1点体力;未造成伤害,所有目标角色依次获得1枚“生妒”标记。', - yuanyin:'袁胤', - dcmoshou:'墨守', - dcmoshou_info:'当你成为其他角色使用的黑色牌的目标后,你可以摸X张牌(X为你本局游戏此前发动过此技能的次数÷3的余数+1)。', - dcyunjiu:'运柩', - dcyunjiu_info:'一名角色死亡后,你可以弃置等同于其因死亡事件的规则而弃置的牌数,将其此次弃置的牌交给一名其他角色。然后你加1点体力上限并回复1点体力。', - gaoxiang:'高翔', - dcchiying:'驰应', - dcchiying_info:'出牌阶段限一次。你可以选择一名体力不大于你的角色,令其攻击范围内的其他角色依次弃置一张牌。然后若你选择的角色不为你,其获得以此法弃置的牌中所有的基本牌。', - zhangkai:'张闿', - dcxiangshu:'相鼠', - dcxiangshu_info:'其他角色的出牌阶段开始时,若其手牌数不小于其体力值,你可以选择一个不大于5的非负整数,然后你弃置一张牌或声明此数字。若如此做,此阶段结束时,若其手牌数与你选择的数字:差值不大于1,你获得其一张牌;相等,你对其造成1点伤害。', - mengyou:'孟优', - dcmanzhi:'蛮智', - dcmanzhi_info:'①准备阶段,你可以选择一名其他角色并选择一项:1.令其交给你两张牌,然后其视为使用一张无距离限制的【杀】;2.获得其区域内至多两张牌,然后交给其等量的牌并摸一张牌。②结束阶段,若你的体力值与本回合准备阶段时的体力值相等,你可以执行你未于本回合执行过的〖蛮智①〗的分支。', - dc_sunchen:'孙綝', - dczigu:'自固', - dczigu_info:'出牌阶段限一次。你可以弃置一张牌,然后获得场上的一张装备牌。若你没有因此获得其他角色的牌,你摸一张牌。', - dczuowei:'作威', - dczuowei_info:'当你于回合内使用牌时,你可以根据你的手牌数执行对应效果:大于X,令此牌不可被响应;等于X,对一名其他角色造成1点伤害;小于X,摸两张牌且不能于本回合再触发该选项(X为你装备区里牌的数量且至少为1)。', - liuchongluojun:'刘宠骆俊', - dcminze:'悯泽', - dcminze_info:'①出牌阶段每名角色限一次。你可以将至多两张牌名不同的牌交给一名手牌数小于你的角色。②结束阶段,你将手牌摸至X张(X为你本回合因〖悯泽①〗失去过的牌的牌名数且至多为5)。', - dcjini:'击逆', - dcjini_info:'当你受到伤害后,你可以重铸至多Y张手牌(Y为你的体力上限减本回合你以此法重铸过的牌数)。若你以此法获得了【杀】,你可以对伤害来源使用一张无视距离且不可被响应的【杀】。', - yuechen:'乐綝', - dcporui:'破锐', - dcporui_info:'每轮限一次。其他角色的结束阶段,你可以弃置一张牌并选择另一名于此回合内失去过牌的其他角色,你视为对其依次使用X+1张【杀】,然后你交给其X张手牌(X为其本回合失去的牌数且至多为5)。', - dcgonghu:'共护', - dcgonghu_info:'锁定技。①当你于回合外失去基本牌后,若你本回合内失去基本牌的数量大于1,你将〖破锐〗改为每轮限两次。②当你造成或受到伤害后,若你本回合内造成或受到的总伤害大于1,你删除〖破锐〗中的“,然后你交给其X张手牌”。③当你使用红色基本牌/红色普通锦囊牌时,若你已发动过〖共护①〗和〖共护②〗,则此牌不可被响应/可额外增加一个目标。', - yue_caiwenji:'乐蔡琰', - yue_caiwenji_prefix:'乐', - dcshuangjia:'霜笳', - dcshuangjia_tag:'胡笳', - dcshuangjia_info:'锁定技。①游戏开始,你将你的手牌标记为“胡笳”。②你的“胡笳”牌不计入手牌上限。③其他角色至你的距离+X(X为你的“胡笳”数且至多为5)。', - dcbeifen:'悲愤', - dcbeifen_info:'锁定技。①当你失去牌后,若这些牌中有“胡笳”牌,你获得与你手牌中“胡笳”牌花色均不同的每种花色的牌各一张。②若你手牌中“胡笳”牌数小于不为“胡笳”牌的牌数,你使用牌无距离和次数限制。', - dc_wuban:'吴班', - dcyouzhan:'诱战', - dcyouzhan_info:'锁定技。当其他角色于你的回合内失去一张牌后,你摸一张牌(不计入本回合的手牌上限),且其获得如下效果:1.其于此回合下一次受到的伤害+1;2.结束阶段,若其于此回合未受到过伤害,其摸X张牌(X为其此回合失去过牌的次数且至多为3)。', - yue_zhoufei:'乐周妃', - yue_zhoufei_prefix:'乐', - dclingkong:'灵箜', - dclingkong_tag:'箜篌', - dclingkong_info:'锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,你将这些牌标记为“箜篌”。', - dcxianshu:'贤淑', - dcxianshu_info:'出牌阶段,你可以将一张“箜篌”正面向上交给一名其他角色,然后你摸X张牌(X为你与其的体力值之差且至多为5)。若此牌为红色,且该角色的体力值不大于你,则其回复1点体力;若此牌为黑色,且该角色的体力值不小于你,则其失去1点体力。', - dc_zhangmancheng:'张曼成', - dclvecheng:'掠城', - dclvecheng_info:'出牌阶段限一次。你可以选择一名其他角色,你于本回合对其使用当前手牌中的【杀】无任何次数限制。然后回合结束时,其展示所有手牌,若其中有【杀】,其可以选择对你依次使用其中所有的【杀】。', - dczhongji:'螽集', - dczhongji_info:'当你使用牌时,若此牌无花色或你手牌区里没有与此牌花色相同的手牌,你可以将手牌摸至体力上限并弃置X张牌(X为本回合发动〖螽集〗的次数)。', - dc_jiachong:'贾充', - dcbeini:'悖逆', - dcbeini_info:'出牌阶段限一次。你可以将手牌调整至体力上限,然后令一名角色视为对另一名角色使用一张【杀】,且这些角色的非锁定技失效直到回合结束。', - dcshizong:'恃纵', - dcshizong_info:'当你需要使用一张基本牌时,你可以交给一名其他角色X张牌,然后其可以将一张牌置于牌堆底,视为你使用之。若其不为当前回合角色,此技能失效直到回合结束(X为你本回合发动〖恃纵〗的次数)。', - pangshanmin:'庞山民', - dccaisi:'才思', - dccaisi_info:'当你于回合内/回合外使用基本牌结算结束后,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后若你本回合发动此技能的次数:小于你的体力上限,本回合你发动此技能获得的牌数+1;大于等于你的体力上限,本回合此技能失效。', - dczhuoli:'擢吏', - dczhuoli_info:'锁定技。一名角色的回合结束时,若你本回合使用或获得的牌数大于体力值,你加1点体力上限(不能超过游戏人数),回复1点体力。', - yue_caiyong:'乐蔡邕', - yue_caiyong_prefix:'乐', - dcjiaowei:'焦尾', - dcjiaowei_tag:'弦', - dcjiaowei_info:'锁定技。①游戏开始时,你将所有手牌标记为“弦”。②你的“弦”牌不计入手牌上限。③当你受到伤害时,若来源的手牌数不大于你的“弦”牌数,防止此伤害。', - dcfeibai:'飞白', - dcfeibai_info:'每回合限一次。当你使用牌结算结束后,若你本回合使用过至少两张牌,你可以随机获得一张字数为X的牌。若你的“弦”数不大于X,你重置〖飞白〗(X为此牌与你使用的上一张牌的字数之和)。', - kuaiqi:'蒯祺', - dcliangxiu:'良秀', - dcliangxiu_info:'出牌阶段,你可以弃置两张不同类型的牌,然后从两张与你弃置的牌类型均不同的牌中选择一张获得之(每阶段每种类型限一次)。', - dcxunjie:'殉节', - dcxunjie_info:'每轮每项限一次。一名角色的回合结束时,若你本回合于摸牌阶段外得到过牌,你可以选择一项:1.令一名角色将手牌数摸或弃置至与其体力值相同;2.令一名角色将体力回复或失去至与其手牌数相同。', - dc_dongzhao:'董昭', - dcyijia:'移驾', - dcyijia_info:'一名角色受到伤害后,若你至其的距离不大于1,你可以将场上一张装备牌移动至其对应装备栏(替换原装备)。若其因此脱离了一名角色的攻击范围,你摸一张牌。', - dcdingji:'定基', - dcdingji_info:'准备阶段,你可以令一名角色将手牌摸或弃置至五张,然后其展示手牌。若牌名均不同,则其可以视为使用其中一张基本或普通锦囊牌。', - yue_xiaoqiao:'乐小乔', - yue_xiaoqiao_prefix:'乐', - dcqiqin:'绮琴', - dcqiqin_tag:'琴', - dcqiqin_info:'锁定技。①游戏开始时,你将所有手牌标记为“琴”。②你的“琴”牌不计入手牌上限。③准备阶段,你获得位于弃牌堆的所有“琴”。', - dcweiwan:'媦婉', - dcweiwan_info:'出牌阶段限一次,你可以弃置一张“琴”并随机获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。', - dc_lingcao:'新杀凌操', - dc_lingcao_prefix:'新杀', - dcdufeng:'独锋', - dcdufeng_info:'锁定技。出牌阶段开始时,你失去1点体力或废除一个装备栏,摸X张牌,然后你的攻击范围与使用【杀】的次数上限均为X直到回合结束(X为你已废除的装备栏数与损失的体力值之和,至多为你的体力上限)。', - dc_sp_menghuo:'群孟获', - dc_sp_menghuo_prefix:'群', - dcmanwang:'蛮王', - dcmanwang_info:'出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:⒈获得〖叛侵〗。⒉摸一张牌。⒊回复1点体力。⒋摸两张牌并失去〖叛侵〗。', - dcpanqin:'叛侵', - dcpanqin_info:'出牌阶段或弃牌阶段结束时,你可将你于本阶段内弃置且位于弃牌堆的所有牌当做【南蛮入侵】使用。然后若此牌被使用时对应的实体牌数不大于此牌的目标数,则你执行并移除〖蛮王〗中的最后一个选项,然后加1点体力上限并回复1点体力。', - dc_kongrong:'孔融', - dckrmingshi:'名士', - dckrmingshi_info:'锁定技,当你受到其他角色造成的伤害时,若其手牌数大于你,则其需弃置一张手牌,否则此伤害-1。', - yue_daqiao:'乐大乔', - yue_daqiao_prefix:'乐', - dczixi:'姊希', - dczixi_info:'①出牌阶段开始和结束时,你可以将一张“琴”当作一张无效果的【乐不思蜀】、【兵粮寸断】或【闪电】置于一名角色的判定区。②当你使用基本牌或普通锦囊牌指定唯一目标后,你可根据其判定区内的牌数执行对应项:1.令此牌对其额外结算一次;2.摸两张牌;3.弃置其判定区所有牌,对其造成3点伤害。', - jiangfei:'蒋琬费祎', - dcshengxi:'生息', - dcshengxi_info:'弃牌阶段结束时,若你本回合未造成过伤害,你可以摸两张牌。', - dcshoucheng:'守成', - dcshoucheng_info:'一名角色于其回合外失去最后的手牌后,你可令其摸两张牌。', - dc_liuli:'刘理', - dcfuli:'抚黎', - dcfuli_info:'出牌阶段限一次,你可以展示手牌并弃置一种类别的所有手牌,然后摸X张牌(X为这些牌的牌名字数和且X至多为场上手牌数最多的角色的手牌数)。若你因此弃置了伤害类卡牌,则你可以选择一名角色,令其攻击范围-1直到你的下个回合开始。', - dcdehua:'德化', - dcdehua_info:'锁定技。①一轮游戏开始时,若有你可以使用的非延时类伤害类牌的牌名,你选择其中一个并视为使用之,然后你不能从手牌中使用此牌名的牌,然后若你已选择过所有的伤害类牌牌名,你失去〖德化〗。②你的手牌上限+Y(Y为你〖德化①〗选择过的牌名数)。', - gongsunxiu:'公孙修', - dcgangu:'干蛊', - dcgangu_info:'锁定技。每回合限一次。当其他角色失去体力后,你摸两张牌,然后失去1点体力。', - dckuizhen:'溃阵', - dckuizhen_info:'出牌阶段限一次。你可以令一名手牌数或体力值大于你的角色视为对你使用一张【决斗】。若你:受到渠道为此牌的伤害,你观看其手牌并获得其中所有的【杀】(你使用以此法得到的牌无任何次数限制);未受到渠道为此牌的伤害,其失去1点体力。', - dc_jiangji:'蒋济', - dcshiju:'势举', - dcshiju_info:'其他角色的出牌阶段限一次。其可以交给你一张牌,若此牌为装备牌,你可以使用之,然后其本回合攻击范围+X(X为你装备区里的牌数)。若你以此法替换了装备,你与其各摸两张牌。', - dcyingshi:'应时', - dcyingshi_info:'每回合每项各限一次。当你使用普通锦囊牌指定第一个目标后,若有目标不为本回合第一次成为牌的目标,则你可以令其选择一项:⒈令你于此牌结算结束后视为对其使用一张与此牌牌名相同的牌;⒉弃置X张牌,此牌对其无效(X为你装备区里的牌数)。', - dc_wangling:'王淩', - dcjichou:'集筹', - dcjichou_info:'出牌阶段结束时,若你于此阶段使用过牌且这些牌的牌名均不同,你可以观看位于弃牌堆中的这些牌,选择任意张牌并选择等量角色,将这些牌交给这些角色各一张,然后你摸X张牌(X为你本局游戏首次发动〖集筹〗给出的牌数)。', - dcmouli:'谋立', - dcmouli_info:'觉醒技。回合结束时,若你因〖集筹〗给出的牌的牌名总数不小于5,你加1点体力上限并回复1点体力,然后获得〖自缚〗。', - dczifu:'自缚', - dczifu_info:'锁定技。出牌阶段开始时,你将手牌摸至体力上限(至多摸至五张)。若你以此法得到牌,你须选择手牌中不同牌名的牌各一张,然后弃置其余的手牌。', - dc_simashi:'司马师', - dcsanshi:'散士', - dcsanshi_tag:'死士', - dcsanshi_info:'锁定技。①第一轮游戏开始时,你令系统将牌堆中每个点数的随机一张牌永久标记为“死士”(“死士”对你可见)。②一名角色的回合结束时,若本回合有“死士”不因你使用或打出而进入弃牌堆,你于弃牌堆中获得这些牌。③你使用“死士”不能被响应。', - dczhenrao:'震扰', - dczhenrao_info:'每回合每名角色限一次。当你使用牌指定第一个目标后,若目标角色包含其他角色,或当其他角色使用牌指定你为目标后,你可以选择手牌数大于你的其中一个目标或此牌的使用者,然后对其造成1点伤害。', - dcchenlve:'沉略', - dcchenlve_info:'限定技。出牌阶段,你可以将牌堆、弃牌堆、场上及其他角色的手牌区里的所有“死士”置入处理区,然后你获得这些牌。若如此做,你获得如下效果:1.此回合结束时,你将这些牌移出游戏;2.当你死亡时,你将所有以此法移出游戏的“死士”置入弃牌堆。', - dc_caoshuang:'新杀曹爽', - dc_caoshuang_prefix:'新杀', - dcjianzhuan:'渐专', - dcjianzhuan_info:'锁定技。①当你于出牌阶段使用牌时,你选择此阶段未执行过的一项执行:⒈令一名角色弃置X张牌;⒉摸X张牌;⒊重铸X张牌;⒋弃置X张牌(X为此技能于本阶段的发动次数)。②出牌阶段结束时,若你本阶段执行过〖渐专①〗的所有选项,则你随机移除〖渐专①〗的一项。', - dcjianzhuan_faq:'渐专概率', - dcjianzhuan_faq_info:'
              当系统随机选择要删除的选项时,“弃置X张牌”的选项概率固定为90%;剩余选项平分剩余的的10%概率。
              如第一次删除时,删除弃牌选项概率为90%,其余三个选项被删除的概率均为3.33%,若删除了非弃牌选项,第二次删除时,删除弃牌选项的概率依旧是90%,其余两个选项被删除的概率均为5%。', - dcfanshi:'返势', - dcfanshi_info:'觉醒技,结束阶段,若〖渐专①〗剩余选项数小于2,则你执行三次X视为1的剩余选项,然后增加2点体力上限并回复2点体力,失去技能〖渐专〗并获得技能〖覆斗〗。', - dcfudou:'覆斗', - dcfudou_info:'当你使用黑色牌/红色牌指定唯一目标后,若该角色不为你,且其于本局游戏对你/未对你造成过伤害,则你可以与其各失去1点体力/各摸一张牌。', + tongli_info: + "当你于出牌阶段内使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内使用过的牌数相等,则你可以令此牌额外结算X次(X为你手牌中的花色数)。", + shezang: "奢葬", + shezang_info: + "每轮限一次。当你或你回合内的其他角色进入濒死状态时,你可以从牌堆中获得每种花色的牌各一张。", + tengyin: "滕胤", + chenjian: "陈见", + chenjian_info: + "准备阶段,你可亮出牌堆顶的3+X张牌(X为你“陈见”标记的数量且至多为2),然后执行以下一至两项:⒈弃置一张牌,然后令一名角色获得与你弃置牌花色相同的牌。⒉使用其中剩余的一张牌。若你执行了所有选项,则你获得一枚“陈见”并重铸所有手牌。", + xixiu: "皙秀", + xixiu_info: + "锁定技。①当你成为其他角色使用牌的目标时,若你的装备区内有和此牌花色相同的牌,则你摸一张牌。②若你装备区内的牌数为1,则其他角色不能弃置你装备区内的牌。", + zhangyao: "张媱", + yuanyu: "怨语", + yuanyu_info: + "出牌阶段限一次。你可以摸一张牌,然后选择一张手牌和一名其他角色。该角色获得如下效果直到你发动〖夕颜〗:{你与该角色的弃牌阶段开始时,或当该角色造成1点伤害后,其须将一张手牌作为“怨”置于你的武将牌上}。然后你将你选择的手牌作为“怨”置于你的武将牌上。", + xiyan: "夕颜", + xiyan_info: + "当有牌作为“怨”移动到你的武将牌上后,若“怨”中的花色数达到4种,则你可以获得所有“怨”。然后若当前回合角色:是你,你本回合手牌上限+4且使用牌无次数限制且重置你的〖怨语〗于此阶段的发动次数;不是你,你可令当前回合角色本回合手牌上限-4且不能使用基本牌。", + xiahoulingnv: "夏侯令女", + fuping: "浮萍", + fuping_info: + "①其他角色对你使用的牌结算结束后,若你未因此技能记录过此牌的名称且你有未废除的装备栏,则你可以废除一个装备栏,记录此牌的名称。②每回合每种牌名限一次。你可以将一张非基本牌当做〖浮萍①〗记录过的基本牌或锦囊牌使用或打出。③若你的所有装备栏均已被废除,则你使用牌无距离限制。", + weilie: "炜烈", + weilie_info: + "每局游戏限X次。出牌阶段,你可以弃置一张牌并选择一名已受伤的角色,令该角色回复1点体力。然后若其体力值小于体力上限,则其摸一张牌(X为你〖浮萍①〗中的记录数+1)。", + dc_sunru: "孙茹", + xiecui: "撷翠", + xiecui_info: + "当有角色于回合内第一次因执行牌的效果而造成伤害时,你可以令此伤害+1。若其势力为吴,则该角色获得此伤害牌对应的实体牌,且其本回合的手牌上限+1。", + youxu: "忧恤", + youxu_info: + "一名角色A的回合结束时,若其手牌数大于体力值,则你可以展示A的一张牌,然后将此牌交给另一名角色B。若B的体力值为全场最少,则B回复1点体力。", + huaxin: "华歆", + wanggui: "望归", + wanggui_info: + "每回合限触发一次,当你造成或受到伤害后,若你:仅明置了此武将牌,则你可对与你势力不同的一名角色造成1点伤害;武将牌均明置,则你可令与你势力相同的角色各摸一张牌。", + spwanggui: "望归", + spwanggui_info: + "①当你受到伤害后,你可以摸一张牌,或和一名势力相同的其他角色各摸一张牌;②每回合限一次,当你造成伤害后,你可以对一名与你势力不同的角色造成1点伤害。", + xibing: "息兵", + xibing_info: + "当一名其他角色在其出牌阶段内使用黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至当前体力值(至多摸五张)且本回合不能再使用手牌。", + xibing_info_guozhan: + "当一名其他角色在其出牌阶段内使用第一张黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至当前体力(至多摸五张)值且本回合不能再使用手牌。若你与其均明置了所有武将牌,则你可以暗置你与其各一张武将牌且本回合不能再明置此武将牌。", + luyusheng: "陆郁生", + zhente: "贞特", + zhente2: "贞特", + zhente_info: + "每回合限一次,当你成为其他角色使用基本牌或普通锦囊牌的目标后,你可令使用者选择一项:1.本回合不能再使用与此牌颜色相同的牌;2.此牌对你无效。", + zhente_info_guozhan: + "每回合限一次,当你成为其他角色使用黑色基本牌或黑色普通锦囊牌的目标后,你可令使用者选择一项:1.本回合不能再使用黑色牌;2.此牌对你无效。", + zhiwei: "至微", + zhiwei2: "至微", + zhiwei_info: + "游戏开始时/你的回合开始时,若场上没有因此法被选择过的角色存活,则你选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。", + zhiwei_info_guozhan: + "你明置此武将牌时,选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。该角色死亡时,若你的两个武将牌均明置,你暗置此武将牌。", + zhanghu: "张虎", + cuijian: "摧坚", + cuijian_info: + "出牌阶段限一次,你可以选择一名有手牌的其他角色。若其手牌中有【闪】,则其将所有【闪】和防具牌交给你,然后你交给其等量的牌。", + zhtongyuan: "同援", + zhtongyuan_info: + "锁定技。①当你使用红色锦囊牌后,你于〖摧坚〗后增加“若其手牌中没有【闪】,则你摸两张牌”;②当你使用或打出红色基本牌后,你删除〖摧坚〗中的“,然后你交给其等量的牌”。③当你使用红色的普通锦囊牌/基本牌时,若你已发动过〖摧坚①〗和〖摧坚②〗,则此牌不可被响应/可额外增加一个目标。", + lvlingqi: "吕玲绮", + guowu: "帼舞", + guowu_info: + "出牌阶段开始时,你可以展示全部手牌,根据你展示的类型数,你获得对应效果:至少一类,从弃牌堆获得一张【杀】;至少两类,此阶段使用牌无距离限制;至少三类,此阶段使用【杀】或普通锦囊牌可以多指定至多两个目标。", + guowu_info_guozhan: + "出牌阶段开始时,你可以展示全部手牌,根据你展示的类型数,你获得对应效果:至少一类,从弃牌堆获得一张【杀】;至少两类,此阶段使用牌无距离限制;至少三类,此阶段使用【杀】可以多指定至多两个目标。", + zhuangrong: "妆戎", + zhuangrong_info: + "觉醒技,一名角色的回合结束时,若你的体力值或手牌数为1,你减1点体力上限并回复体力至上限,将手牌摸至体力上限,然后获得〖神威〗和〖无双〗。", + llqshenwei: "神威", + llqshenwei_info: "锁定技,摸牌阶段开始时,你令额定摸牌数+2;你的手牌上限+2。", + re_kanze: "阚泽", + rekuanshi: "宽释", + rekuanshi_info: + "结束阶段,你可以选择一名角色。你获得如下效果直到你下回合开始:每回合限一次,当其于一回合内受到第2点伤害后,其回复1点体力。", + liuyong: "刘永", + zhuning: "诛佞", + zhuning_info: + "出牌阶段限一次。你可将任意张牌交给一名其他角色(称为“隙”),然后可视为使用一张具有伤害标签的基本牌/锦囊牌(不计入次数限制)。若你以此法使用的牌未造成伤害,则你将〖诛佞〗于本回合内改为“限两次”。", + fengxiang: "封乡", + fengxiang_info: + "锁定技。①当你受到伤害后,若场上:存在“隙”唯一最多的角色,则其回复1点体力;不存在,则你摸一张牌。②当有角色的手牌移动后,若场上“隙”最多的角色因此发生变化,则你摸一张牌。", + fengxiang_tag: "隙", + re_xunchen: "荀谌", + refenglve: "锋略", + refenglve_info: + "出牌阶段限一次,你可以和一名其他角色进行拼点。若你赢,其将区域内的两张牌交给你;若平局,则你令此技能于本阶段内的发动次数上限+1;若你输,其获得你的拼点牌。", + anyong: "暗涌", + anyong_info: + "当一名角色于其回合内第一次对另一名其他角色造成伤害后,若伤害值为1,则你可弃置一张牌,并对受伤角色造成1点伤害。", + wanniangongzhu: "万年公主", + zhenge: "枕戈", + zhenge_info: + "准备阶段,你可以选择一名角色。该角色本局游戏的攻击范围+1(至多+5)。然后若除其外的所有角色都在该角色的攻击范围内,则你可以令其视为对另一名角色使用一张【杀】。", + xinghan: "兴汉", + xinghan_info: + "锁定技,每回合的第一张【杀】造成伤害后,若此【杀】的使用者成为过〖枕戈〗的目标,则你摸一张牌。若你的手牌数不是全场唯一最多的,则改为摸X张牌(X为该角色的攻击范围且最多为5)。", + re_chendeng: "陈登", + refuyuan: "扶援", + refuyuan_info: + "一名角色成为【杀】的目标后,若其本回合内没有成为过其他红色牌的目标,则你可以令其摸一张牌。", + reyingshui: "营说", + reyingshui_info: + "出牌阶段限一次,你可将一张牌交给攻击范围内的一名其他角色,然后其选择一项:①交给你至少两张装备牌。②受到1点伤害。", + rewangzu: "望族", + rewangzu_info: + "每回合限一次。当你受到其他角色造成的伤害时,你可随机弃置一张手牌,令此伤害-1。若你所在阵营的存活角色数是全场最多的,则你可以自行选择弃置的牌。", + re_miheng: "祢衡", + rekuangcai: "狂才", + rekuangcai_info: + "锁定技。①你于回合内使用牌无距离和次数限制。②弃牌阶段开始时,若你本回合内:未使用过牌,则你本局游戏的手牌上限+1;使用过牌但未造成过伤害,则你本局游戏的手牌上限-1。③结束阶段开始时,你摸X张牌(X为你本回合内造成的伤害且至多为5)。", + reshejian: "舌剑", + reshejian_info: + "每回合限两次。当你成为其他角色使用牌的唯一目标后,你可以弃置至少两张手牌。若如此做,你选择一项:⒈弃置其等量的牌。⒉对其造成1点伤害。", + fengxi: "冯熙", + yusui: "玉碎", + yusui_info: + "当你成为其他角色使用黑色牌的目标后,你可以失去1点体力,然后选择一项:⒈令其将手牌数弃置至与你相同;⒉令其失去Y点体力(Y为其的体力值减去你的体力值,不为正时不可选择)。", + boyan: "驳言", + boyan_info: + "出牌阶段限一次,你可选择一名其他角色。其将手牌摸至体力上限(至多摸至五张),然后其本回合不能使用或打出手牌。", + re_dengzhi: "邓芝", + jianliang: "简亮", + jianliang_info: "摸牌阶段开始时,若你的手牌数不为全场最多,则你可以令至多两名角色各摸一张牌。", + weimeng: "危盟", + weimeng_info: + "出牌阶段限一次,你可以获得一名其他角色的至多X张手牌,然后交给其等量的牌(X为你的体力值)。若你给出的牌点数之和:大于得到的牌,则你摸一张牌;小于得到的牌,弃置该角色区域内的一张牌。", + mamidi: "马日磾", + bingjie: "秉节", + bingjie_info: + "出牌阶段开始时,你可减1点体力上限,然后当你于本阶段内使用【杀】或普通锦囊牌指定其他角色为目标后,其弃置一张牌。若其弃置的牌与你使用的牌颜色相同,其无法响应此牌。", + zhengding: "正订", + zhengding_info: + "锁定技。当你于回合外使用或打出牌响应其他角色使用的牌时,若这两张牌颜色相同,则你加1点体力上限并回复1点体力。", + dc_jiben: "吉本", + xunli: "询疠", + xunli_info: + "锁定技。①当有黑色牌因弃置而进入弃牌堆后,若X大于0,则你将其中的X张牌置于武将牌上作为“疠”(X=min(这些牌的数量,9-Y),Y=你的“疠”数)。②出牌阶段开始时,你可以用任意张黑色手牌交换等量的“疠”。", + zhishi: "指誓", + zhishi_info: + "结束阶段,你可选择一名角色。当该角色于你的下回合开始前{成为【杀】的目标后或进入濒死状态时},你可移去任意张“疠”,然后其摸等量的牌。", + lieyi: "烈医", + lieyi_info: + "出牌阶段限一次。你可以展示所有“疠”并选择一名其他角色,对其使用其中的一张可对其使用的牌(无距离和次数限制)并重复此流程,并将其余的牌置于弃牌堆。然后若其存活且未于此流程中因受到伤害而进入过濒死状态,则你失去1点体力。", + guanning: "管宁", + dunshi: "遁世", + dunshi_info: + "每回合限一次。你可以视为使用或打出一张【杀】/【闪】/【桃】/【酒】,然后当前回合角色于本回合内下一次造成伤害时,你选择两项:⒈防止此伤害。系统从技能名中包含“仁/义/礼/智/信”字样的技能中随机选择三个其未拥有的技能,然后你令当前回合角色获得其中一个技能。⒉从〖遁世〗中删除你本次使用或打出的牌并获得一个“席”。⒊减1点体力上限并摸X张牌(X为你的“席”数)。", + dc_gaolan: "高览", + xizhen: "袭阵", + xizhen_info: + "出牌阶段开始时,你可选择一名其他角色,视为对其使用【杀】或【决斗】。然后当有角色于本阶段内使用或打出牌响应你时,该角色回复1点体力,你摸一张牌(若其满体力,改为两张)。", + dc_huangchengyan: "黄承彦", + dcjiezhen: "解阵", + dcjiezhen_info: + "出牌阶段限一次,你可选择一名其他角色。该角色获得〖八阵〗,且其所有不为{锁定技、限定技、觉醒技、主公技、带有Charlotte标签}的技能失效。你的下回合开始时,或其因〖八卦阵〗发起的判定结算结束后,你令其恢复其以此法失效的所有技能并失去以此法获得的〖八阵〗,然后获得其区域内的一张牌。", + dczecai: "择才", + dczecai_info: + "限定技。一轮游戏开始时,若游戏轮数大于1,则你可令一名其他角色获得〖集智〗直到下一轮游戏开始;若其是上一轮内使用过锦囊牌数量唯一最多的角色,则其获得一个额外的回合。", + dcyinshi: "隐世", + dcyinshi_info: + "锁定技。①每回合限一次,当你受到伤害时,若此伤害的渠道不为有颜色的牌,则你防止此伤害。②当有因〖八卦阵〗发起的判定的判定牌生效时,你获得此判定牌。", + tenggongzhu: "滕公主", + xingchong: "幸宠", + xingchong_info: + "一轮游戏开始时,你可声明两个自然数X和Y,且(X+Y)≤min(5, 你的体力上限)。你摸X张牌并展示Y张手牌。若如此做,当你于本轮内失去一张以此法展示的牌后,你摸两张牌。", + liunian: "流年", + liunian_info: + "锁定技。一名角色的回合结束时,若本回合内进行了本次游戏的第一次洗牌,则你加1点体力上限;若本回合内进行了本次游戏的第二次洗牌,则你于本回合结束时回复1点体力,且本局游戏内的手牌上限+10。", + caimaozhangyun: "蔡瑁张允", + lianzhou: "连舟", + lianzhou_info: "锁定技。准备阶段,你横置你的武将牌。然后你可横置任意名体力值等于你的角色。", + jinglan: "惊澜", + jinglan_info: + "锁定技。当你造成伤害后,若你的手牌数:大于体力值,你弃置四张手牌;等于体力值,你弃置一张手牌并回复1点体力;小于体力值,你受到1点无来源火焰伤害并摸五张牌。", + dc_yanghu: "羊祜", + dcdeshao: "德劭", + dcdeshao_info: + "每回合限两次。当你成为其他角色使用的黑色牌的目标后,你可以摸一张牌,然后若其手牌数不小于你,则你弃置其一张牌。", + dcmingfa: "明伐", + dcmingfa_info: + "①出牌阶段限一次。当你使用【杀】或普通锦囊牌结算结束后,若你的武将牌上没有“明伐”牌,则你可以将此牌作为“明伐”牌置于武将牌上并选择一名其他角色,记录该角色和此牌的名称。②一名角色的回合结束时,若其是你〖明伐①〗记录的角色,则你视为对其依次使用X张〖明伐①〗记录的牌,然后移去“明伐”牌(X为其手牌数且至少为1,至多为5)。③一名角色死亡时,若其是你〖明伐①〗记录的角色,则你移去“明伐”牌。", + dc_jiling: "纪灵", + dcshuangren: "双刃", + dcshuangren_info: + "出牌阶段开始时,你可以和一名其他角色A进行拼点。若你赢,你选择一名角色B,或选择包含A在内的两名角色A和B(B的势力需与A相同),然后视为对被选择的角色使用一张【杀】(不计入次数限制);若你没赢,则你本阶段内不能使用【杀】。", + zhangxun: "张勋", + suizheng: "随征", + suizheng_info: + "结束阶段,你可以选择一名角色A,获得如下效果直到其下回合结束:①A于下回合出牌阶段内使用【杀】的次数上限+1且无距离限制;②A下回合的出牌阶段结束时,你可以选择一名此阶段内受到过A造成的伤害的角色B,视为对B使用一张【杀】。", + dc_liuba: "刘巴", + dczhubi: "铸币", + dczhubi_info: + "当有♦牌因弃置而进入弃牌堆后,你可以令系统从牌堆/弃牌堆中检索一张【无中生有】,并将此牌置于牌堆顶。", + dcliuzhuan: "流转", + dcliuzhuan_tag: "转", + dcliuzhuan_info: + "锁定技。①其他角色于其回合内不于摸牌阶段而得到的牌称为“转”。②你不能成为实体牌中包含“转”的牌的目标。③当有“转”直接进入弃牌堆或经由处理区进入弃牌堆后,你获得之。", + huzhao: "胡昭", + midu: "弥笃", + midu_info: + "出牌阶段限一次。你可以选择一项:⒈废除任意个装备栏或判定区,并令一名角色摸等量的牌。⒉恢复一个已经被废除的装备栏或判定区,然后你获得〖活墨〗直到下回合开始。", + xianwang: "贤望", + xianwang_info: + "锁定技。若你有被废除的装备栏,则其他角色至你的距离+1,你至其他角色的距离-1;若废除的装备栏数大于2,则改为距离+2/-2。", + guanhai: "管亥", + suoliang: "索粮", + suoliang_info: + "每回合限一次。当你对其他角色造成伤害后,你可以选择并展示其的至多X张牌(X为其体力上限且至多为5)。若这些牌中有♥或♣牌,则你获得这些牌;否则你弃置这些牌。", + qinbao: "侵暴", + qinbao_info: "锁定技。当你使用【杀】或普通锦囊牌时,你令所有手牌数不小于你的角色不能响应此牌。", + dc_lvkuanglvxiang: "吕旷吕翔", + dcshuhe: "数合", + dcshuhe_info: + "出牌阶段限一次,你可以展示一张手牌并获得一枚“爵”。若场上有与此牌点数相同的牌,则你获得这些牌;否则你将此牌交给一名其他角色。", + dcliehou: "列侯", + dcliehou_info: + "锁定技。摸牌阶段开始时,你令额定摸牌数+X;然后此摸牌阶段结束时,你选择一项:⒈弃置X张牌。⒉失去1点体力(X为你的“爵”数+1且至多为5)。", + yinfuren: "尹夫人", + dcyingyu: "媵予", + dcyingyu_info: + "准备阶段开始时,你可以展示两名角色的各一张手牌。若这两张牌的花色不同,则你可以令一名角色获得另一名角色的展示牌。", + dcyongbi: "拥嬖", + dcyongbi_info: + "限定技。出牌阶段,你可以将所有手牌交给一名其他男性角色。你将〖媵予〗的发动时机改为“准备阶段和结束阶段开始时”。然后若这些牌中包含的花色数:大于1,则你与其本局游戏的手牌上限+2;大于2,则当你或其于本局游戏内受到大于1的伤害时,此伤害-1。", + dc_huangquan: "黄权", + dcquanjian: "劝谏", + dcquanjian_info: + "出牌阶段每项各限一次。你可以选择一项流程并选择一名其他角色A:⒈令A对其攻击范围内的另一名角色B造成1点伤害。⒉令A将手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用手牌。然后A选择一项:⒈执行此流程。⒉本回合下次受到的伤害+1。", + dctujue: "途绝", + dctujue_info: + "限定技。当你进入濒死状态时,你可以将所有牌交给一名其他角色。然后你回复等量的体力并摸等量的牌。", + chengui: "陈珪", + dcyingtu: "营图", + dcyingtu_info: + "每回合限一次。当你的上家/下家于摸牌阶段外得到牌后,你可以获得其一张牌,然后将一张牌交给你的下家/上家。若你给出的牌为装备牌,则其使用之。", + dccongshi: "从势", + dccongshi_info: + "锁定技。一名角色使用的装备牌结算结束后,若其装备区内的牌数为全场最多,则你摸一张牌。", + wanglie: "王烈", + dcchongwang: "崇望", + dcchongwang_info: + "其他角色使用基本牌或普通锦囊牌时,若你是本局游戏内上一张被使用的牌的使用者,则你可以选择一项:⒈令其于此牌结算结束后收回此牌对应的所有实体牌;⒉取消此牌的所有目标。", + dchuagui: "化归", + dchuagui_info: + "出牌阶段开始时,你可以选择至多X名有牌的其他角色(X为场上每个阵营中最大阵营的人数,且你的选择结果不展示)。这些角色同时选择一项:⒈交给你一张牌,⒉展示一张牌。若这些角色均选择选项二,则你获得所有展示牌。", + gongsundu: "公孙度", + dczhenze: "震泽", + dczhenze_info: + "弃牌阶段开始时,你可以选择一项:1.令所有手牌数与体力值大小关系与你不同的角色失去1点体力;2.令所有手牌数和体力值关系与你相同的角色回复1点体力。", + dcanliao: "安辽", + dcanliao_info: "出牌阶段限X次(X为群势力角色数)。你可以重铸一名角色的一张牌。", + dc_yuejiu: "乐就", + dccuijin: "催进", + dccuijin_info: + "当你或你攻击范围内的角色使用【杀】或【决斗】时,你可以弃置一张牌,令此牌的伤害基数+1。然后当此牌被目标角色抵消或无效或防止伤害后,你摸两张牌并对使用者造成1点伤害。", + panghui: "庞会", + dcyiyong: "异勇", + dcyiyong_info: + "当你对其他角色造成伤害时,若你有牌,你可以与其同时弃置至少一张牌。若你以此法弃置的牌的点数之和:不大于其,你摸X张牌;不小于其,此伤害+1(X为其以此法弃置的牌数)。", + chenjiao: "陈矫", + dcxieshoux: "协守/清严", + dcxieshou: "协守", + dcxieshou_info: + "每回合限一次。当一名角色受到伤害后,若你至其的距离不大于2,你可以令你的手牌上限-1,然后其选择一项:1.回复1点体力;2.复原,摸两张牌。", + dcqingyan: "清严", + dcqingyan_info: + "每回合限两次。当你成为其他角色使用黑色牌的目标后,若你的手牌数:小于体力值,你可以将手牌补至体力上限;不小于体力值,你可以弃置一张牌令你的手牌上限+1。", + dcqizi: "弃子", + dcqizi_info: "锁定技。你不能对至其的距离大于2且正在进行濒死流程的角色使用【桃】。", + leibo: "雷薄", + dcsilve: "私掠", + dcsilve_info: + "游戏开始时,你选择一名其他角色(对其他角色不可见),称为“私掠”角色。然后你获得以下效果:①当“私掠”角色造成伤害后,若你本回合未因此效果得到过受伤角色的牌,你可以获得受伤角色一张牌;②当“私掠”角色受到其他角色造成的伤害后,若伤害来源存活,你须对伤害来源使用一张【杀】(无距离限制),否则你弃置一张手牌。", + dcshuaijie: "衰劫", + dcshuaijie_info: + "限定技。出牌阶段,若你的体力值与装备区里的牌数均大于“私掠”角色,或没有角色有“私掠”,你可以减1点体力上限,然后选择一项:1.获得“私掠”角色至多三张牌;2.从牌堆随机获得三张类型各不同的牌。最后将你的“私掠”角色改为你。", + dc_sp_jiaxu: "新杀SP贾诩", + dc_sp_jiaxu_prefix: "新杀SP", + dcjianshu: "间书", + dcjianshu_info: + "出牌阶段限一次。你可以将一张黑色手牌交给一名其他角色,并选择另一名其他角色,你令前者与后者拼点。赢的角色随机弃置一张牌,没赢的角色失去1点体力。若有角色因此死亡,你令你〖间书〗于此阶段发动的次数上限+1。", + dcyongdi: "拥嫡", + dcyongdi_info: + "限定技。出牌阶段,你可以选择一名男性角色,若其:体力上限最少,其加1点体力上限;体力值最少,其回复1点体力;手牌数最少,其摸X张牌(X为其体力上限且至多为5)。", + liupi: "新杀刘辟", + liupi_prefix: "新杀", + dcjuying: "踞营", + dcjuying_info: + "出牌阶段结束时,若你于此阶段内使用【杀】的次数未达到上限,你可以选择任意项:1.下回合使用【杀】的次数上限+1;2.本回合手牌上限+2;3.摸三张牌。若你选择的项数超过了你的体力值,你弃置一张牌。", + dc_huanghao: "新杀黄皓", + dc_huanghao_prefix: "新杀", + dcqinqing: "寝情", + dcqinqing_info: + "结束阶段,你可以弃置一名攻击范围内包含一号位的其他角色一张牌。然后若其手牌数大于一号位,你摸一张牌。", + dccunwei: "存畏", + dccunwei_info: + "锁定技。当你成为其他角色使用的锦囊牌的目标后,若你是唯一目标,你摸一张牌;否则你弃置一张牌。", + dc_zhaotongzhaoguang: "赵统赵广", + dcqingren: "青刃", + dcqingren_info: "结束阶段,你可以摸X张牌(X为你本回合发动〖翊赞〗的次数)。", + dclongyuan: "龙渊", + dclongyuan_info: + "锁定技。一名角色的回合结束时,若你本局游戏已发动过至少三次〖翊赞〗,你摸两张牌并回复1点体力,修改〖翊赞〗。", + zhenghun: "郑浑", + dcqiangzhi: "强峙", + dcqiangzhi_info: + "出牌阶段限一次。你可以弃置你和一名其他角色的共计三张牌。然后若你与其之中有角色因此失去了三张牌,该角色对另一名角色造成1点伤害。", + dcpitian: "辟田", + dcpitian_info: + "①当你的牌被弃置后,或当你受到伤害后,你的手牌上限+1。②结束阶段,若你的手牌数小于手牌上限,你可以摸至手牌上限(至多摸五张),然后重置因〖辟田①〗增加的手牌上限。", + furongfuqian: "傅肜傅佥", + dcxuewei: "血卫", + dcxuewei_info: + "结束阶段,你可以选择一名体力值不大于你的角色,然后你获得如下效果直到你的下回合开始时:当其受到伤害时,防止此伤害,然后你失去1点体力,你与其各摸一张牌(若该角色为你,则改为你摸一张牌)。", + dcyuguan: "御关", + dcyuguan_info: + "一名角色的回合结束时,若你已损失的体力值为全场最多,你可以减1点体力上限,然后令至多X名角色将手牌摸至体力上限(X为你已损失的体力值)。", + qinlang: "秦朗", + dchaochong: "昊宠", + dchaochong_info: + "当你使用牌后,你可以将手牌摸至或弃置至你的手牌上限数(至多摸五张)。然后若你以此法:得到牌,你的手牌上限-1;失去牌,你的手牌上限+1。", + dcjinjin: "矜谨", + dcjinjin_info: + "每回合限两次。当你造成或受到伤害后,你可以重置因〖昊宠〗增加或减少的手牌上限,令伤害来源弃置至多X张牌,然后你摸Y张牌(X为你以此法变化的手牌上限且至少为1,Y为X减其以此法弃置的牌数)。", + xianglang: "向朗", + dckanji: "勘集", + dckanji_info: + "出牌阶段限两次。你可以展示所有手牌,若花色均不同,你摸两张牌。然后若你的手牌因此包含了四种花色,你跳过下一个弃牌阶段。", + dcqianzheng: "愆正", + dcqianzheng_info: + "每回合限两次。当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以重铸两张牌。若你以此法重铸的牌中没有与指定你为目标的牌类别相同的牌,你于此牌对应的实体牌进入弃牌堆后获得此牌对应的所有实体牌。", + qiaorui: "桥蕤", + dcaishou: "隘守", + dcaishou_tag: "隘", + dcaishou_info: + "①结束阶段,你可以摸X张牌,称为“隘”(X为你的体力上限)。②准备阶段,你弃置所有“隘”,若你以此法弃置的牌数大于体力值且你的体力上限小于9,你加1点体力上限。③当你于回合外失去最后一张“隘”后,你减1点体力上限。", + dcsaowei: "扫围", + dcsaowei_info: + "当一名其他角色使用【杀】结算结束后,若此牌的目标角色不包含你且均在你的攻击范围内,你可以将一张“隘”当做【杀】对所有目标角色使用。以此法转化的【杀】结算完毕后,若此【杀】造成过伤害,你获得此【杀】对应的实体牌。", + yuantanyuanxiyuanshang: "袁谭袁尚袁熙", + dcneifa: "内伐", + dcneifa_info: + "出牌阶段开始时,你可以摸三张牌,然后弃置一张牌。若你弃置的牌类型为:基本牌,本阶段你不能使用锦囊牌,且【杀】的使用次数上限+X且可以额外指定一名目标;锦囊牌,本阶段你不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标(X为你发动〖内伐〗弃牌后手牌中因〖内伐〗而不能使用的牌的数量且最多为5。你以此法选择的额外目标均无距离限制)。", + dc_sunziliufang: "新杀孙资刘放", + dc_sunziliufang_prefix: "新杀", + dcqinshen: "勤慎", + dcqinshen_info: "弃牌阶段结束时,你可以摸X张牌(X为本回合未进入过弃牌堆的花色数)。", + dcweidang: "伪谠", + dcweidang_info: + "其他角色的结束阶段,你可以将一张字数为X的牌置于牌堆底,然后获得牌堆里一张字数为X的牌(X为本回合未进入过弃牌堆的花色数)。若你能使用此牌,你使用之。", + mengjie: "孟节", + dcyinlu: "引路", + dcyinlu_info: + "①游戏开始时,你令三名角色依次分别获得“乐泉”、“藿溪”、“瘴气”标记(若场上角色数为2则改为令一名其他角色获得其中2枚,你获得剩余标记),然后你获得“芸香”标记并获得1点“芸香”值。②准备阶段/有〖引路〗标记的角色死亡时,你可以移动一名角色的1枚/其的所有〖引路〗标记。", + dcyinlu_lequan: "乐泉", + dcyinlu_lequan_info: "结束阶段,你可以弃置一张♦牌并回复1点体力。", + dcyinlu_huoxi: "藿溪", + dcyinlu_huoxi_info: "结束阶段,你可以弃置一张♥牌并摸两张牌。", + dcyinlu_zhangqi: "瘴气", + dcyinlu_zhangqi_info: "锁定技。结束阶段,你须弃置一张♠牌,否则失去1点体力。", + dcyinlu_yunxiang: "芸香", + dcyinlu_yunxiang_info: + "①结束阶段,你可以弃置一张♣牌,获得1点“芸香”值。②当你受到伤害时,你可以扣减所有“芸香”值,减少等量的伤害。", + dcyouqi: "幽栖", + dcyouqi_info: "锁定技。当其他角色因〖引路〗标记弃置牌后,你有一定概率获得此牌。", + dcyouqi_faq: "〖幽栖〗概率
              ", + dcyouqi_faq_info: + "当满足〖幽栖〗条件时,系统生成一个随机数X∈[0,1)。若X小于(1.25-0.25Y),或幸运星模式已开启,你获得此牌(Y为你至该角色的距离)。", + dc_sunhanhua: "孙寒华", + dchuiling: "汇灵", + dchuiling_info: + "锁定技。当你使用牌时,若此牌颜色为弃牌堆中数量较少的颜色,你获得1枚“灵”标记。若弃牌堆中:红色牌数大于黑色牌数,你回复1点体力;黑色牌数大于红色牌数,你可以弃置一名其他角色的一张牌。", + dcchongxu: "冲虚", + dcchongxu_info: + "限定技。出牌阶段,若“灵”数不小于4,你可以失去〖汇灵〗,增加等同于“灵”数的体力上限(至多增加场上人数的体力上限),然后获得〖踏寂〗和〖清荒〗。", + dctaji: "踏寂", + dctaji_info: + "当你失去手牌后,根据你失去牌的原因执行以下效果:1.使用:你弃置其他角色一张牌;2.打出:你摸一张牌;3.弃置:你回复1点体力;4.其他:你下一次对其他角色造成伤害时,此伤害+1。", + dcqinghuang: "清荒", + dcqinghuang_info: + "出牌阶段开始时,你可以减1点体力上限,然后你于本回合发动〖踏寂〗时额外随机执行一种效果。", + dc_huojun: "霍峻", + dcgue: "孤扼", + dcgue_info: + "每回合限一次。当你需要于回合外使用或打出【杀】或【闪】时,你可以发动此技能:你展示所有手牌,若其中【杀】和【闪】的数量之和不超过1,你视为使用或打出此牌。", + dcsigong: "伺攻", + dcsigong_info: + "其他角色的回合结束时,若其于本回合内使用牌被响应过,你可以将手牌摸至或弃置至1,视为对其使用一张需使用X张【闪】抵消的【杀】,且此【杀】的伤害基数+1(X为你以此法弃置的牌数且至少为1)。当你以此法造成伤害后,该技能于本轮失效。", + peiyuanshao: "裴元绍", + dcmoyu: "没欲", + dcmoyu_info: + "出牌阶段每名角色限一次。你可以获得一名其他角色区域里的一张牌,然后其可以对你使用一张无距离限制的【杀】,且此【杀】伤害基数为X(X为你于本回合发动此技能的次数)。若此【杀】对你造成了伤害,你令此技能于本回合失效。", + zhangchu: "张楚", + dcjizhong: "集众", + dcjizhong_info: + "出牌阶段限一次。你可以令一名其他角色摸两张牌,然后其选择一项:1.若其没有“信众”标记,其获得“信众”标记;2.交给你三张手牌。", + dcrihui: "日彗", + dcrihui_info: + "每回合限一次。当你使用普通锦囊牌或黑色基本牌结算结束后,若此牌的目标数为1且目标不为你,且其:没有“信众”,则所有有“信众”的角色依次视为对其使用一张与此牌牌名和属性相同的牌;有“信众”,则你可以获得其区域里的一张牌。", + dcguangshi: "光噬", + dcguangshi_info: "锁定技。准备阶段,若所有其他角色均有“信众”,你摸两张牌并失去1点体力。", + dongwan: "董绾", + dcshengdu: "生妒", + dcshengdu_info: + "回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为摸牌数乘以其拥有的“生妒”标记数)。", + dcjieling: "介绫", + dcjieling_info: + "出牌阶段每种花色限一次,你可以将两张花色不同的手牌当无距离限制且无任何次数限制的【杀】使用。然后若此【杀】:造成了伤害,所有目标角色失去1点体力;未造成伤害,所有目标角色依次获得1枚“生妒”标记。", + yuanyin: "袁胤", + dcmoshou: "墨守", + dcmoshou_info: + "当你成为其他角色使用的黑色牌的目标后,你可以摸X张牌(X为你本局游戏此前发动过此技能的次数÷3的余数+1)。", + dcyunjiu: "运柩", + dcyunjiu_info: + "一名角色死亡后,你可以弃置等同于其因死亡事件的规则而弃置的牌数,将其此次弃置的牌交给一名其他角色。然后你加1点体力上限并回复1点体力。", + gaoxiang: "高翔", + dcchiying: "驰应", + dcchiying_info: + "出牌阶段限一次。你可以选择一名体力不大于你的角色,令其攻击范围内的其他角色依次弃置一张牌。然后若你选择的角色不为你,其获得以此法弃置的牌中所有的基本牌。", + zhangkai: "张闿", + dcxiangshu: "相鼠", + dcxiangshu_info: + "其他角色的出牌阶段开始时,若其手牌数不小于其体力值,你可以选择一个不大于5的非负整数,然后你弃置一张牌或声明此数字。若如此做,此阶段结束时,若其手牌数与你选择的数字:差值不大于1,你获得其一张牌;相等,你对其造成1点伤害。", + mengyou: "孟优", + dcmanzhi: "蛮智", + dcmanzhi_info: + "①准备阶段,你可以选择一名其他角色并选择一项:1.令其交给你两张牌,然后其视为使用一张无距离限制的【杀】;2.获得其区域内至多两张牌,然后交给其等量的牌并摸一张牌。②结束阶段,若你的体力值与本回合准备阶段时的体力值相等,你可以执行你未于本回合执行过的〖蛮智①〗的分支。", + dc_sunchen: "孙綝", + dczigu: "自固", + dczigu_info: + "出牌阶段限一次。你可以弃置一张牌,然后获得场上的一张装备牌。若你没有因此获得其他角色的牌,你摸一张牌。", + dczuowei: "作威", + dczuowei_info: + "当你于回合内使用牌时,你可以根据你的手牌数执行对应效果:大于X,令此牌不可被响应;等于X,对一名其他角色造成1点伤害;小于X,摸两张牌且不能于本回合再触发该选项(X为你装备区里牌的数量且至少为1)。", + liuchongluojun: "刘宠骆俊", + dcminze: "悯泽", + dcminze_info: + "①出牌阶段每名角色限一次。你可以将至多两张牌名不同的牌交给一名手牌数小于你的角色。②结束阶段,你将手牌摸至X张(X为你本回合因〖悯泽①〗失去过的牌的牌名数且至多为5)。", + dcjini: "击逆", + dcjini_info: + "当你受到伤害后,你可以重铸至多Y张手牌(Y为你的体力上限减本回合你以此法重铸过的牌数)。若你以此法获得了【杀】,你可以对伤害来源使用一张无视距离且不可被响应的【杀】。", + yuechen: "乐綝", + dcporui: "破锐", + dcporui_info: + "每轮限一次。其他角色的结束阶段,你可以弃置一张牌并选择另一名于此回合内失去过牌的其他角色,你视为对其依次使用X+1张【杀】,然后你交给其X张手牌(X为其本回合失去的牌数且至多为5)。", + dcgonghu: "共护", + dcgonghu_info: + "锁定技。①当你于回合外失去基本牌后,若你本回合内失去基本牌的数量大于1,你将〖破锐〗改为每轮限两次。②当你造成或受到伤害后,若你本回合内造成或受到的总伤害大于1,你删除〖破锐〗中的“,然后你交给其X张手牌”。③当你使用红色基本牌/红色普通锦囊牌时,若你已发动过〖共护①〗和〖共护②〗,则此牌不可被响应/可额外增加一个目标。", + yue_caiwenji: "乐蔡琰", + yue_caiwenji_prefix: "乐", + dcshuangjia: "霜笳", + dcshuangjia_tag: "胡笳", + dcshuangjia_info: + "锁定技。①游戏开始,你将你的手牌标记为“胡笳”。②你的“胡笳”牌不计入手牌上限。③其他角色至你的距离+X(X为你的“胡笳”数且至多为5)。", + dcbeifen: "悲愤", + dcbeifen_info: + "锁定技。①当你失去牌后,若这些牌中有“胡笳”牌,你获得与你手牌中“胡笳”牌花色均不同的每种花色的牌各一张。②若你手牌中“胡笳”牌数小于不为“胡笳”牌的牌数,你使用牌无距离和次数限制。", + dc_wuban: "吴班", + dcyouzhan: "诱战", + dcyouzhan_info: + "锁定技。当其他角色于你的回合内失去一张牌后,你摸一张牌(不计入本回合的手牌上限),且其获得如下效果:1.其于此回合下一次受到的伤害+1;2.结束阶段,若其于此回合未受到过伤害,其摸X张牌(X为其此回合失去过牌的次数且至多为3)。", + yue_zhoufei: "乐周妃", + yue_zhoufei_prefix: "乐", + dclingkong: "灵箜", + dclingkong_tag: "箜篌", + dclingkong_info: + "锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,你将这些牌标记为“箜篌”。", + dcxianshu: "贤淑", + dcxianshu_info: + "出牌阶段,你可以将一张“箜篌”正面向上交给一名其他角色,然后你摸X张牌(X为你与其的体力值之差且至多为5)。若此牌为红色,且该角色的体力值不大于你,则其回复1点体力;若此牌为黑色,且该角色的体力值不小于你,则其失去1点体力。", + dc_zhangmancheng: "张曼成", + dclvecheng: "掠城", + dclvecheng_info: + "出牌阶段限一次。你可以选择一名其他角色,你于本回合对其使用当前手牌中的【杀】无任何次数限制。然后回合结束时,其展示所有手牌,若其中有【杀】,其可以选择对你依次使用其中所有的【杀】。", + dczhongji: "螽集", + dczhongji_info: + "当你使用牌时,若此牌无花色或你手牌区里没有与此牌花色相同的手牌,你可以将手牌摸至体力上限并弃置X张牌(X为本回合发动〖螽集〗的次数)。", + dc_jiachong: "贾充", + dcbeini: "悖逆", + dcbeini_info: + "出牌阶段限一次。你可以将手牌调整至体力上限,然后令一名角色视为对另一名角色使用一张【杀】,且这些角色的非锁定技失效直到回合结束。", + dcshizong: "恃纵", + dcshizong_info: + "当你需要使用一张基本牌时,你可以交给一名其他角色X张牌,然后其可以将一张牌置于牌堆底,视为你使用之。若其不为当前回合角色,此技能失效直到回合结束(X为你本回合发动〖恃纵〗的次数)。", + pangshanmin: "庞山民", + dccaisi: "才思", + dccaisi_info: + "当你于回合内/回合外使用基本牌结算结束后,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后若你本回合发动此技能的次数:小于你的体力上限,本回合你发动此技能获得的牌数+1;大于等于你的体力上限,本回合此技能失效。", + dczhuoli: "擢吏", + dczhuoli_info: + "锁定技。一名角色的回合结束时,若你本回合使用或获得的牌数大于体力值,你加1点体力上限(不能超过游戏人数),回复1点体力。", + yue_caiyong: "乐蔡邕", + yue_caiyong_prefix: "乐", + dcjiaowei: "焦尾", + dcjiaowei_tag: "弦", + dcjiaowei_info: + "锁定技。①游戏开始时,你将所有手牌标记为“弦”。②你的“弦”牌不计入手牌上限。③当你受到伤害时,若来源的手牌数不大于你的“弦”牌数,防止此伤害。", + dcfeibai: "飞白", + dcfeibai_info: + "每回合限一次。当你使用牌结算结束后,若你本回合使用过至少两张牌,你可以随机获得一张字数为X的牌。若你的“弦”数不大于X,你重置〖飞白〗(X为此牌与你使用的上一张牌的字数之和)。", + kuaiqi: "蒯祺", + dcliangxiu: "良秀", + dcliangxiu_info: + "出牌阶段,你可以弃置两张不同类型的牌,然后从两张与你弃置的牌类型均不同的牌中选择一张获得之(每阶段每种类型限一次)。", + dcxunjie: "殉节", + dcxunjie_info: + "每轮每项限一次。一名角色的回合结束时,若你本回合于摸牌阶段外得到过牌,你可以选择一项:1.令一名角色将手牌数摸或弃置至与其体力值相同;2.令一名角色将体力回复或失去至与其手牌数相同。", + dc_dongzhao: "董昭", + dcyijia: "移驾", + dcyijia_info: + "一名角色受到伤害后,若你至其的距离不大于1,你可以将场上一张装备牌移动至其对应装备栏(替换原装备)。若其因此脱离了一名角色的攻击范围,你摸一张牌。", + dcdingji: "定基", + dcdingji_info: + "准备阶段,你可以令一名角色将手牌摸或弃置至五张,然后其展示手牌。若牌名均不同,则其可以视为使用其中一张基本或普通锦囊牌。", + yue_xiaoqiao: "乐小乔", + yue_xiaoqiao_prefix: "乐", + dcqiqin: "绮琴", + dcqiqin_tag: "琴", + dcqiqin_info: + "锁定技。①游戏开始时,你将所有手牌标记为“琴”。②你的“琴”牌不计入手牌上限。③准备阶段,你获得位于弃牌堆的所有“琴”。", + dcweiwan: "媦婉", + dcweiwan_info: + "出牌阶段限一次,你可以弃置一张“琴”并随机获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。", + dc_lingcao: "新杀凌操", + dc_lingcao_prefix: "新杀", + dcdufeng: "独锋", + dcdufeng_info: + "锁定技。出牌阶段开始时,你失去1点体力或废除一个装备栏,摸X张牌,然后你的攻击范围与使用【杀】的次数上限均为X直到回合结束(X为你已废除的装备栏数与损失的体力值之和,至多为你的体力上限)。", + dc_sp_menghuo: "群孟获", + dc_sp_menghuo_prefix: "群", + dcmanwang: "蛮王", + dcmanwang_info: + "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:⒈获得〖叛侵〗。⒉摸一张牌。⒊回复1点体力。⒋摸两张牌并失去〖叛侵〗。", + dcpanqin: "叛侵", + dcpanqin_info: + "出牌阶段或弃牌阶段结束时,你可将你于本阶段内弃置且位于弃牌堆的所有牌当做【南蛮入侵】使用。然后若此牌被使用时对应的实体牌数不大于此牌的目标数,则你执行并移除〖蛮王〗中的最后一个选项,然后加1点体力上限并回复1点体力。", + dc_kongrong: "孔融", + dckrmingshi: "名士", + dckrmingshi_info: + "锁定技,当你受到其他角色造成的伤害时,若其手牌数大于你,则其需弃置一张手牌,否则此伤害-1。", + yue_daqiao: "乐大乔", + yue_daqiao_prefix: "乐", + dczixi: "姊希", + dczixi_info: + "①出牌阶段开始和结束时,你可以将一张“琴”当作一张无效果的【乐不思蜀】、【兵粮寸断】或【闪电】置于一名角色的判定区。②当你使用基本牌或普通锦囊牌指定唯一目标后,你可根据其判定区内的牌数执行对应项:1.令此牌对其额外结算一次;2.摸两张牌;3.弃置其判定区所有牌,对其造成3点伤害。", + jiangfei: "蒋琬费祎", + dcshengxi: "生息", + dcshengxi_info: "弃牌阶段结束时,若你本回合未造成过伤害,你可以摸两张牌。", + dcshoucheng: "守成", + dcshoucheng_info: "一名角色于其回合外失去最后的手牌后,你可令其摸两张牌。", + dc_liuli: "刘理", + dcfuli: "抚黎", + dcfuli_info: + "出牌阶段限一次,你可以展示手牌并弃置一种类别的所有手牌,然后摸X张牌(X为这些牌的牌名字数和且X至多为场上手牌数最多的角色的手牌数)。若你因此弃置了伤害类卡牌,则你可以选择一名角色,令其攻击范围-1直到你的下个回合开始。", + dcdehua: "德化", + dcdehua_info: + "锁定技。①一轮游戏开始时,若有你可以使用的非延时类伤害类牌的牌名,你选择其中一个并视为使用之,然后你不能从手牌中使用此牌名的牌,然后若你已选择过所有的伤害类牌牌名,你失去〖德化〗。②你的手牌上限+Y(Y为你〖德化①〗选择过的牌名数)。", + gongsunxiu: "公孙修", + dcgangu: "干蛊", + dcgangu_info: "锁定技。每回合限一次。当其他角色失去体力后,你摸两张牌,然后失去1点体力。", + dckuizhen: "溃阵", + dckuizhen_info: + "出牌阶段限一次。你可以令一名手牌数或体力值大于你的角色视为对你使用一张【决斗】。若你:受到渠道为此牌的伤害,你观看其手牌并获得其中所有的【杀】(你使用以此法得到的牌无任何次数限制);未受到渠道为此牌的伤害,其失去1点体力。", + dc_jiangji: "蒋济", + dcshiju: "势举", + dcshiju_info: + "其他角色的出牌阶段限一次。其可以交给你一张牌,若此牌为装备牌,你可以使用之,然后其本回合攻击范围+X(X为你装备区里的牌数)。若你以此法替换了装备,你与其各摸两张牌。", + dcyingshi: "应时", + dcyingshi_info: + "每回合每项各限一次。当你使用普通锦囊牌指定第一个目标后,若有目标不为本回合第一次成为牌的目标,则你可以令其选择一项:⒈令你于此牌结算结束后视为对其使用一张与此牌牌名相同的牌;⒉弃置X张牌,此牌对其无效(X为你装备区里的牌数)。", + dc_wangling: "王淩", + dcjichou: "集筹", + dcjichou_info: + "出牌阶段结束时,若你于此阶段使用过牌且这些牌的牌名均不同,你可以观看位于弃牌堆中的这些牌,选择任意张牌并选择等量角色,将这些牌交给这些角色各一张,然后你摸X张牌(X为你本局游戏首次发动〖集筹〗给出的牌数)。", + dcmouli: "谋立", + dcmouli_info: + "觉醒技。回合结束时,若你因〖集筹〗给出的牌的牌名总数不小于5,你加1点体力上限并回复1点体力,然后获得〖自缚〗。", + dczifu: "自缚", + dczifu_info: + "锁定技。出牌阶段开始时,你将手牌摸至体力上限(至多摸至五张)。若你以此法得到牌,你须选择手牌中不同牌名的牌各一张,然后弃置其余的手牌。", + dc_simashi: "司马师", + dcsanshi: "散士", + dcsanshi_tag: "死士", + dcsanshi_info: + "锁定技。①第一轮游戏开始时,你令系统将牌堆中每个点数的随机一张牌永久标记为“死士”(“死士”对你可见)。②一名角色的回合结束时,若本回合有“死士”不因你使用或打出而进入弃牌堆,你于弃牌堆中获得这些牌。③你使用“死士”不能被响应。", + dczhenrao: "震扰", + dczhenrao_info: + "每回合每名角色限一次。当你使用牌指定第一个目标后,若目标角色包含其他角色,或当其他角色使用牌指定你为目标后,你可以选择手牌数大于你的其中一个目标或此牌的使用者,然后对其造成1点伤害。", + dcchenlve: "沉略", + dcchenlve_info: + "限定技。出牌阶段,你可以将牌堆、弃牌堆、场上及其他角色的手牌区里的所有“死士”置入处理区,然后你获得这些牌。若如此做,你获得如下效果:1.此回合结束时,你将这些牌移出游戏;2.当你死亡时,你将所有以此法移出游戏的“死士”置入弃牌堆。", + dc_caoshuang: "新杀曹爽", + dc_caoshuang_prefix: "新杀", + dcjianzhuan: "渐专", + dcjianzhuan_info: + "锁定技。①当你于出牌阶段使用牌时,你选择此阶段未执行过的一项执行:⒈令一名角色弃置X张牌;⒉摸X张牌;⒊重铸X张牌;⒋弃置X张牌(X为此技能于本阶段的发动次数)。②出牌阶段结束时,若你本阶段执行过〖渐专①〗的所有选项,则你随机移除〖渐专①〗的一项。", + dcjianzhuan_faq: "渐专概率", + dcjianzhuan_faq_info: + "
              当系统随机选择要删除的选项时,“弃置X张牌”的选项概率固定为90%;剩余选项平分剩余的的10%概率。
              如第一次删除时,删除弃牌选项概率为90%,其余三个选项被删除的概率均为3.33%,若删除了非弃牌选项,第二次删除时,删除弃牌选项的概率依旧是90%,其余两个选项被删除的概率均为5%。", + dcfanshi: "返势", + dcfanshi_info: + "觉醒技,结束阶段,若〖渐专①〗剩余选项数小于2,则你执行三次X视为1的剩余选项,然后增加2点体力上限并回复2点体力,失去技能〖渐专〗并获得技能〖覆斗〗。", + dcfudou: "覆斗", + dcfudou_info: + "当你使用黑色牌/红色牌指定唯一目标后,若该角色不为你,且其于本局游戏对你/未对你造成过伤害,则你可以与其各失去1点体力/各摸一张牌。", - sp_baigei:'无双上将', - sp_caizijiaren:'才子佳人', - sp_zhilan:'芝兰玉树', - sp_zongheng:'纵横捭阖', - sp_guixin:'天下归心', - sp_jianghu:'江湖之远', - sp_daihan:'代汉涂高', - sp_taiping:'太平甲子', - sp_yanhan:'匡鼎炎汉', - sp_jishi:'悬壶济世', - sp_raoting:'绕庭之鸦', - sp_yijun:'异军突起', - sp_zhengyin:'正音雅乐', - sp_zhonghu:'冢虎狼顾', + sp_baigei: "无双上将", + sp_caizijiaren: "才子佳人", + sp_zhilan: "芝兰玉树", + sp_zongheng: "纵横捭阖", + sp_guixin: "天下归心", + sp_jianghu: "江湖之远", + sp_daihan: "代汉涂高", + sp_taiping: "太平甲子", + sp_yanhan: "匡鼎炎汉", + sp_jishi: "悬壶济世", + sp_raoting: "绕庭之鸦", + sp_yijun: "异军突起", + sp_zhengyin: "正音雅乐", + sp_zhonghu: "冢虎狼顾", }, }; }); diff --git a/character/jiange.js b/character/jiange.js index 11b6e25cb..a2fd017bc 100644 --- a/character/jiange.js +++ b/character/jiange.js @@ -1,576 +1,609 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ - return { - name:'jiange', - character:{ - jg_pangtong:['male','shu',3,['qiwu','tianyu']], - jg_huangyueying:['female','shu',3,['zhinang','jingmiao']], - jg_zhugeliang:['male','shu',3,['biantian','bazhen']], - jg_liubei:['male','shu',4,['jizhen','lingfeng']], - jg_xiahouyuan:['male','wei',4,['xinshensu','juechen']], - jg_caozhen:['male','wei',4,['chiying','jingfan']], - jg_zhanghe:['male','wei',4,['huodi','jueji']], - jg_simayi:['male','wei',5,['xuanlei','sfanshi','konghun']], - }, - skill:{ - sfanshi:{ - trigger:{player:'phaseEnd'}, - forced:true, - check:function(){ - return false; - }, - content:function(){ - player.loseHp(); - } - }, - konghun:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - if(game.players.length>=6){ - return player.hp<=2; - } - return player.hp<=1; - }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('konghun'),function(card,player,target){ - return player!=target; - },[1,Math.min(4,Math.floor((game.players.length-1)/2))]).ai=function(target){ - return get.damageEffect(target,player,player,'thunder')+1; - } - "step 1" - if(result.bool){ - event.targets=result.targets.slice(0); - player.logSkill('konghun',event.targets,'thunder'); - event.targets.sort(lib.sort.seat); - event.num=0; - } - else{ - event.finish(); - } - "step 2" - if(event.num0&&event.player!=player&&event.player.hp1||event.targets[0]!=player); - }, - silent:true, - content:function(){ - player.addTempSkill('huodi3'); - } - }, - huodi3:{}, - jingfan:{ - trigger:{player:'phaseUseEnd'}, - unique:true, - direct:true, - content:function(){ - "step 0" - var num=player.countUsed()-player.countCards('h'); - event.num=num; - if(num>0){ - player.draw(num); - } - "step 1" - if(event.num>0){ - player.chooseTarget('选择至多'+get.cnNumber(event.num)+'名角色令其进攻距离+1',[1,event.num],function(card,player,target){ - return player!=target; - }).ai=function(target){ - return get.attitude(player,target); - } - } - else{ - event.finish(); - } - "step 2" - if(result.bool&&result.targets){ - player.logSkill('jingfan',result.targets); - for(var i=0;i0; - }, - filter:function(event,player){ - if(event.num<=1) return false; - return true; - }, - content:function(){ - trigger.num=1; - if(trigger.source){ - trigger.source.addTempSkill('chiying2','damageAfter'); - } - } - }, - chiying2:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - content:function(){ - player.draw(); - } - }, - juechen:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='sha'; - }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('juechen'),function(card,player,target){ - return player!=target&&!trigger.targets.includes(target)&&target.countCards('he')>0; - }).set('autodelay',true).ai=function(target){ - return -get.attitude(player,target); - } - "step 1" - if(result.bool){ - player.logSkill('juechen',result.targets); - player.discardPlayerCard(true,result.targets[0],'he'); - } - } - }, - lingfeng:{ - trigger:{player:'phaseDrawBefore'}, - check:function(event,player){ - for(var i=0;i0; - }).ai=function(target){ - return -get.attitude(player,target); - } - } - "step 2" - if(result.bool&&result.targets&&result.targets.length){ - player.discardPlayerCard(result.targets[0],'he',true); - } - "step 3" - player.gain(event.cards); - player.$draw(event.cards); - game.delay(); - }, - ai:{ - threaten:1.1 - } - }, - biantian4:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content:function(){ - for(var i=0;i0; - }, - content:function(){ - "step 0" - player.choosePlayerCard(trigger.player,get.prompt('jingmiao',trigger.player),'he'); - "step 1" - if(result.bool){ - player.logSkill('jingmiao',trigger.player); - trigger.player.discard(result.links); - } - }, - ai:{ - expose:0.2 - } - }, - zhinang:{ - trigger:{player:'phaseBegin'}, - frequent:true, - content:function(){ - "step 0" - event.cards=get.cards(3); - event.cards2=[]; - for(var i=0;iplayer.hp){ - if(target==player) return Math.max(1,att-2); - } - if(target==player) return att+5; - return att; - } - } - "step 2" - if(result&&result.targets&&result.targets.length){ - event.target=result.targets[0]; - } - if(event.cards2.length){ - event.target.gain(event.cards2,'gain2'); - } - }, - ai:{ - threaten:1.3 - } - }, - tianyu:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - for(var i=0;i= 6) { + return player.hp <= 2; + } + return player.hp <= 1; + }, + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("konghun"), + function (card, player, target) { + return player != target; + }, + [1, Math.min(4, Math.floor((game.players.length - 1) / 2))] + ).ai = function (target) { + return get.damageEffect(target, player, player, "thunder") + 1; + }; + "step 1"; + if (result.bool) { + event.targets = result.targets.slice(0); + player.logSkill("konghun", event.targets, "thunder"); + event.targets.sort(lib.sort.seat); + event.num = 0; + } else { + event.finish(); + } + "step 2"; + if (event.num < event.targets.length) { + event.targets[event.num].damage("thunder"); + event.num++; + event.redo(); + } + "step 3"; + player.recover(event.targets.length); + }, + }, + xuanlei: { + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player && game.players[i].countCards("j")) return true; + } + return false; + }, + content: function () { + "step 0"; + event.targets = []; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player && game.players[i].countCards("j")) { + event.targets.push(game.players[i]); + } + } + event.targets.sort(lib.sort.seat); + "step 1"; + if (event.targets.length) { + event.targets.shift().damage("thunder"); + event.redo(); + } + }, + }, + jueji: { + trigger: { global: "phaseDrawBegin" }, + direct: true, + filter: function (event, player) { + return ( + event.num > 0 && + event.player != player && + event.player.hp < event.player.maxHp && + player.countCards("he") + ); + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "是否弃置一张牌令" + get.translation(trigger.player) + "的摸牌数-1?" + ); + next.ai = function (card) { + if (get.attitude(player, trigger.player) < 0) { + return 6 - get.value(card); + } + return 0; + }; + next.logSkill = ["jueji", trigger.player]; + "step 1"; + if (result.bool) { + trigger.num--; + } + }, + ai: { + expose: 0.2, + threaten: 1.8, + }, + }, + huodi: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return !player.hasSkill("huodi3"); + }, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("huodi"), function (card, player, target) { + return target.countCards("he") && player != target; + }).ai = function (target) { + return -get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("huodi", result.targets); + player.discardPlayerCard(result.targets[0], true, "he"); + } + }, + ai: { + expose: 0.2, + threaten: 1.2, + }, + group: "huodi2", + }, + huodi2: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + _status.currentPhase == player && + event.targets && + (event.targets.length > 1 || event.targets[0] != player) + ); + }, + silent: true, + content: function () { + player.addTempSkill("huodi3"); + }, + }, + huodi3: {}, + jingfan: { + trigger: { player: "phaseUseEnd" }, + unique: true, + direct: true, + content: function () { + "step 0"; + var num = player.countUsed() - player.countCards("h"); + event.num = num; + if (num > 0) { + player.draw(num); + } + "step 1"; + if (event.num > 0) { + player.chooseTarget( + "选择至多" + get.cnNumber(event.num) + "名角色令其进攻距离+1", + [1, event.num], + function (card, player, target) { + return player != target; + } + ).ai = function (target) { + return get.attitude(player, target); + }; + } else { + event.finish(); + } + "step 2"; + if (result.bool && result.targets) { + player.logSkill("jingfan", result.targets); + for (var i = 0; i < result.targets.length; i++) { + result.targets[i].addSkill("jingfan2"); + result.targets[i].popup("jingfan"); + } + } + }, + mod: { + globalFrom: function (from, to, distance) { + if (_status.currentPhase == from) { + return distance - from.countUsed(); + } + }, + }, + ai: { + expose: 0.1, + }, + }, + jingfan2: { + mod: { + globalFrom: function (from, to, distance) { + return distance - 1; + }, + }, + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { + player.removeSkill("jingfan2"); + }, + }, + chiying: { + trigger: { global: "damageBegin2" }, + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + filter: function (event, player) { + if (event.num <= 1) return false; + return true; + }, + content: function () { + trigger.num = 1; + if (trigger.source) { + trigger.source.addTempSkill("chiying2", "damageAfter"); + } + }, + }, + chiying2: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + content: function () { + player.draw(); + }, + }, + juechen: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "sha"; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("juechen"), function (card, player, target) { + return ( + player != target && + !trigger.targets.includes(target) && + target.countCards("he") > 0 + ); + }) + .set("autodelay", true).ai = function (target) { + return -get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("juechen", result.targets); + player.discardPlayerCard(true, result.targets[0], "he"); + } + }, + }, + lingfeng: { + trigger: { player: "phaseDrawBefore" }, + check: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (player != game.players[i]) { + if (get.attitude(player, game.players[i]) < 0) return true; + } + } + return false; + }, + content: function () { + "step 0"; + trigger.cancel(); + event.cards = get.cards(2); + player.showCards(event.cards); + "step 1"; + if (get.color(event.cards[0]) != get.color(event.cards[1])) { + player.chooseTarget("是否弃置一名角色一张牌?", function (card, player, target) { + return player != target && target.countCards("he") > 0; + }).ai = function (target) { + return -get.attitude(player, target); + }; + } + "step 2"; + if (result.bool && result.targets && result.targets.length) { + player.discardPlayerCard(result.targets[0], "he", true); + } + "step 3"; + player.gain(event.cards); + player.$draw(event.cards); + game.delay(); + }, + ai: { + threaten: 1.1, + }, + }, + biantian4: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + content: function () { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].hasSkill("biantian3")) { + game.players[i].removeSkill("biantian3"); + game.players[i].popup("biantian3"); + } + } + }, + }, + biantian: { + trigger: { player: "phaseBegin" }, + forced: true, + unique: true, + group: "biantian4", + content: function () { + "step 0"; + player.removeSkill("biantian2"); + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].hasSkill("biantian3")) { + game.players[i].removeSkill("biantian3"); + game.players[i].popup("biantian3"); + } + } + player.judge(function (card) { + if (get.color(card) == "red") return 1; + if (get.suit(card) == "spade") return 3; + return -1; + }); + "step 1"; + if (result.color == "red") { + player.chooseTarget( + "选择至多三名角色获得狂风标记", + [1, 3], + function (card, player, target) { + return player != target; + } + ).ai = function (target) { + if (target.hasSkillTag("nofire")) return 0; + return -get.attitude(player, target); + }; + } else { + event.finish(); + if (result.suit == "spade") { + player.addSkill("biantian2"); + } + } + "step 2"; + if (result.bool && result.targets) { + for (var i = 0; i < result.targets.length; i++) { + result.targets[i].addSkill("biantian3"); + result.targets[i].popup("kuangfeng"); + } + player.logSkill("kuangfeng", result.targets, "fire"); + } + }, + }, + biantian2: { + trigger: { player: "damageBefore" }, + filter: function (event) { + if (event.nature != "thunder") return true; + return false; + }, + forced: 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]; + }, + }, + }, + }, + biantian3: { + trigger: { player: "damageBegin" }, + filter: function (event) { + if (event.nature == "fire") return true; + return false; + }, + forced: true, + content: function () { + trigger.num++; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "fireDamage")) return 1.5; + }, + }, + }, + }, + jingmiao: { + trigger: { global: "useCardAfter" }, + direct: true, + filter: function (event, player) { + return ( + event.player != player && + event.card.name == "wuxie" && + event.player.countCards("he") > 0 + ); + }, + content: function () { + "step 0"; + player.choosePlayerCard(trigger.player, get.prompt("jingmiao", trigger.player), "he"); + "step 1"; + if (result.bool) { + player.logSkill("jingmiao", trigger.player); + trigger.player.discard(result.links); + } + }, + ai: { + expose: 0.2, + }, + }, + zhinang: { + trigger: { player: "phaseBegin" }, + frequent: true, + content: function () { + "step 0"; + event.cards = get.cards(3); + event.cards2 = []; + for (var i = 0; i < event.cards.length; i++) { + var type = get.type(event.cards[i]); + if (type == "trick" || type == "equip") { + event.cards2.push(event.cards[i]); + } + } + if (!event.isMine() || event.cards2.length == 0) { + player.showCards(event.cards); + } + "step 1"; + if (event.cards2.length == 0) { + event.finish(); + } else { + var dialog = ui.create.dialog("将三张牌中的锦囊牌或装备牌交给一名角色", "hidden"); + dialog.add(event.cards); + for (var i = 0; i < dialog.buttons.length; i++) { + if (event.cards2.includes(dialog.buttons[i].link)) { + dialog.buttons[i].style.opacity = 1; + } else { + dialog.buttons[i].style.opacity = 0.5; + } + } + var next = player.chooseTarget(true, dialog); + next.ai = function (target) { + if (player.hasJudge("lebu")) { + if (target == player) return 0.1; + } + var att = get.attitude(player, target); + if (player.countCards("h") > player.hp) { + if (target == player) return Math.max(1, att - 2); + } + if (target == player) return att + 5; + return att; + }; + } + "step 2"; + if (result && result.targets && result.targets.length) { + event.target = result.targets[0]; + } + if (event.cards2.length) { + event.target.gain(event.cards2, "gain2"); + } + }, + ai: { + threaten: 1.3, + }, + }, + tianyu: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (!game.players[i].isLinked() && player != game.players[i]) { + return true; + } + } + }, + content: function () { + "step 0"; + var num = 0; + for (var i = 0; i < game.players.length; i++) { + if (!game.players[i].isLinked() && player != game.players[i]) { + num++; + } + } + player.chooseTarget(get.prompt("tianyu"), [1, num], function (card, player, target) { + return !target.isLinked() && player != target; + }).ai = function (target) { + return -get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("tianyu", result.targets); + event.targets = result.targets; + event.num = 0; + } else { + event.finish(); + } + "step 2"; + if (event.num < event.targets.length) { + event.targets[event.num].link(); + event.num++; + event.redo(); + } + }, + ai: { + expose: 0.3, + }, + }, + jizhen: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].hp < game.players[i].maxHp && player != game.players[i]) { + return true; + } + } + return false; + }, + content: function () { + "step 0"; + var num = 0; + for (var i = 0; i < game.players.length; i++) { + if (!game.players[i].isLinked() && player != game.players[i]) { + num++; + } + } + player.chooseTarget(get.prompt("jizhen"), [1, 2], function (card, player, target) { + return target.hp < target.maxHp && player != target; + }).ai = function (target) { + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("jizhen", result.targets); + game.asyncDraw(result.targets); + } + }, + ai: { + expose: 0.3, + threaten: 1.3, + }, + }, + }, + translate: { + jg_pangtong: "浴火士元", + jg_huangyueying: "工神月英", + jg_zhugeliang: "天侯孔明", + jg_liubei: "烈帝玄德", + jg_xiahouyuan: "绝尘妙才", + jg_caozhen: "佳人子丹", + jg_zhanghe: "巧魁儁乂", + jg_simayi: "断狱仲达", + tianyu: "天狱", + zhinang: "智囊", + jingmiao: "精妙", + biantian: "变天", + biantian2: "大雾", + biantian3: "狂风", + jizhen: "激阵", + xuanlei: "玄雷", + xuanlei_info: "锁定技,准备阶段,你令所有判定区内有牌的其他角色受到1点雷电伤害。", + sfanshi: "反噬", + sfanshi_info: "锁定技,结束阶段,你失去1点体力。", + konghun: "控魂", + konghun_info: + "出牌阶段开始时,若你的体力值不大于1(场上存活角色数不小于6时改为2),你可以对至多X名角色各造成1点雷电伤害,然后你恢复等量体力,X为场上其他存活角色数的一半(向下取整且至多为4)。", + jizhen_info: "结束阶段,你可以令所至多两名已受伤角色摸一张牌。", + // biantian2_info:'已获得大雾标记', + // biantian3_info:'已获得狂风标记', + lingfeng: "灵锋", + jueji: "绝汲", + huodi: "惑敌", + huodi_info: + "结束阶段,若你本回合内没有使用过指定其他角色为目标的卡牌,你可以弃置一名其他角色的一张牌。", + jueji_info: "其他角色的摸牌阶段开始时,若其已受伤,你可以弃置一张牌令其摸牌数-1。", + lingfeng_info: + "摸牌阶段,你可以弃置摸牌,改为亮出牌堆顶的两张牌并获得之,若两张牌颜色不同,你可以弃置一名角色的一张牌。", + biantian_info: + "锁定技,准备阶段,你进行一次判定,若为红色,你可以选择至多三名角色进入“狂风”状态直到你的下一回合开始,若为黑桃,直到下个回合开始前,你处于“大雾”状态。", + jingmiao_info: "每当有一名其他角色使用无懈可击,你可以弃置其一张牌。", + zhinang_info: "准备阶段,你可以亮出牌堆顶的三张牌,你可以将其中锦囊或装备牌交给一名角色。", + tianyu_info: "结束阶段,你可以将任意名未横置的其他角色横置。", + juechen: "绝尘", + juechen_info: "每当你使用一张杀,可以弃置一名其他角色的一张牌(不能是杀的目标)。", + chiying: "持盈", + chiying_info: "每当一名角色受到多于1伤害时,你可以令其防止其余伤害,然后令伤害来源摸一张牌。", + jingfan: "惊帆", + jingfan2: "惊帆", + jingfan_info: + "回合内,每当你使用一张卡牌,你的进攻距离+1;出牌阶段结束时,你可以将手牌数补至X,并指定至多X名角色令其进攻距离+1直到其下一回合结束,X为你回合内使用的卡牌数。", + }, + }; +}); diff --git a/character/jsrg.js b/character/jsrg.js index 984c4a4b4..1d2830e01 100644 --- a/character/jsrg.js +++ b/character/jsrg.js @@ -1,3877 +1,4825 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'jsrg', - connect:true, - characterSort:{ - jsrg:{ - jiangshanrugu_qi:['jsrg_liuhong','jsrg_hejin','jsrg_sunjian','jsrg_huangfusong','jsrg_xushao','jsrg_dongbai','jsrg_qiaoxuan','jsrg_yangbiao','jsrg_kongrong','jsrg_zhujun','jsrg_liubei','jsrg_wangyun','jsrg_liuyan','jsrg_caocao','jsrg_nanhualaoxian'], - jiangshanrugu_cheng:['jsrg_sunce','jsrg_xuyou','jsrg_lvbu','jsrg_zhanghe','jsrg_zoushi','jsrg_guanyu','jsrg_chendeng','jsrg_zhenji','jsrg_zhangliao','jsrg_xugong','jsrg_chunyuqiong'], - jiangshanrugu_zhuan:['jsrg_guojia','jsrg_zhangfei','jsrg_machao','jsrg_lougui','jsrg_zhangren','jsrg_huangzhong','jsrg_xiahourong','jsrg_sunshangxiang','jsrg_pangtong','jsrg_hansui','jsrg_zhangchu','jsrg_xiahouen','jsrg_fanjiangzhangda'], - jiangshanrugu_he:['jsrg_zhugeliang','jsrg_jiangwei','jsrg_luxun','jsrg_zhaoyun','jsrg_simayi','jsrg_guoxun','jsrg_sunlubansunluyu','jsrg_caofang','jsrg_sunjun','jsrg_liuyong','jsrg_weiwenzhugezhi','jsrg_zhangxuan','jsrg_gaoxiang','jsrg_guozhao'], + name: "jsrg", + connect: true, + characterSort: { + jsrg: { + jiangshanrugu_qi: [ + "jsrg_liuhong", + "jsrg_hejin", + "jsrg_sunjian", + "jsrg_huangfusong", + "jsrg_xushao", + "jsrg_dongbai", + "jsrg_qiaoxuan", + "jsrg_yangbiao", + "jsrg_kongrong", + "jsrg_zhujun", + "jsrg_liubei", + "jsrg_wangyun", + "jsrg_liuyan", + "jsrg_caocao", + "jsrg_nanhualaoxian", + ], + jiangshanrugu_cheng: [ + "jsrg_sunce", + "jsrg_xuyou", + "jsrg_lvbu", + "jsrg_zhanghe", + "jsrg_zoushi", + "jsrg_guanyu", + "jsrg_chendeng", + "jsrg_zhenji", + "jsrg_zhangliao", + "jsrg_xugong", + "jsrg_chunyuqiong", + ], + jiangshanrugu_zhuan: [ + "jsrg_guojia", + "jsrg_zhangfei", + "jsrg_machao", + "jsrg_lougui", + "jsrg_zhangren", + "jsrg_huangzhong", + "jsrg_xiahourong", + "jsrg_sunshangxiang", + "jsrg_pangtong", + "jsrg_hansui", + "jsrg_zhangchu", + "jsrg_xiahouen", + "jsrg_fanjiangzhangda", + ], + jiangshanrugu_he: [ + "jsrg_zhugeliang", + "jsrg_jiangwei", + "jsrg_luxun", + "jsrg_zhaoyun", + "jsrg_simayi", + "jsrg_guoxun", + "jsrg_sunlubansunluyu", + "jsrg_caofang", + "jsrg_sunjun", + "jsrg_liuyong", + "jsrg_weiwenzhugezhi", + "jsrg_zhangxuan", + "jsrg_gaoxiang", + "jsrg_guozhao", + ], }, }, - character:{ + character: { //起 - jsrg_liuhong:['male','qun',4,['jsrgchaozheng','jsrgshenchong','jsrgjulian'],['zhu']], - jsrg_hejin:['male','qun',4,['jsrgzhaobing','jsrgzhuhuan','jsrgyanhuo']], - jsrg_sunjian:['male','qun',4,['jsrgpingtao','jsrgjuelie']], - jsrg_huangfusong:['male','qun',4,['jsrgguanhuo','jsrgjuxia']], - jsrg_xushao:['male','qun',3,['sbyingmen','sbpingjian']], - jsrg_dongbai:['female','qun',3,['jsrgshichong','jsrglianzhu']], - jsrg_qiaoxuan:['male','qun',3,['jsrgjuezhi','jsrgjizhao']], - jsrg_yangbiao:['male','qun','3/4',['jsrgzhaohan','jsrgrangjie','jsrgyizheng']], - jsrg_kongrong:['male','qun',3,['jsrglirang','jsrgzhengyi']], - jsrg_zhujun:['male','qun',4,['jsrgfendi','jsrgjuxiang']], - jsrg_liubei:['male','qun',4,['jsrgjishan','jsrgzhenqiao']], - jsrg_wangyun:['male','qun',3,['jsrgshelun','jsrgfayi'],['clan:太原王氏']], - jsrg_liuyan:['male','qun',3,['xinfu_limu','jsrgtushe','jsrgtongjue'],['zhu']], - jsrg_caocao:['male','qun',4,['jsrgzhenglve','jsrghuilie']], - jsrg_nanhualaoxian:['male','qun',3,['jsrgshoushu','jsrgxundao','jsrglinghua']], + jsrg_liuhong: ["male", "qun", 4, ["jsrgchaozheng", "jsrgshenchong", "jsrgjulian"], ["zhu"]], + jsrg_hejin: ["male", "qun", 4, ["jsrgzhaobing", "jsrgzhuhuan", "jsrgyanhuo"]], + jsrg_sunjian: ["male", "qun", 4, ["jsrgpingtao", "jsrgjuelie"]], + jsrg_huangfusong: ["male", "qun", 4, ["jsrgguanhuo", "jsrgjuxia"]], + jsrg_xushao: ["male", "qun", 3, ["sbyingmen", "sbpingjian"]], + jsrg_dongbai: ["female", "qun", 3, ["jsrgshichong", "jsrglianzhu"]], + jsrg_qiaoxuan: ["male", "qun", 3, ["jsrgjuezhi", "jsrgjizhao"]], + jsrg_yangbiao: ["male", "qun", "3/4", ["jsrgzhaohan", "jsrgrangjie", "jsrgyizheng"]], + jsrg_kongrong: ["male", "qun", 3, ["jsrglirang", "jsrgzhengyi"]], + jsrg_zhujun: ["male", "qun", 4, ["jsrgfendi", "jsrgjuxiang"]], + jsrg_liubei: ["male", "qun", 4, ["jsrgjishan", "jsrgzhenqiao"]], + jsrg_wangyun: ["male", "qun", 3, ["jsrgshelun", "jsrgfayi"], ["clan:太原王氏"]], + jsrg_liuyan: ["male", "qun", 3, ["xinfu_limu", "jsrgtushe", "jsrgtongjue"], ["zhu"]], + jsrg_caocao: ["male", "qun", 4, ["jsrgzhenglve", "jsrghuilie"]], + jsrg_nanhualaoxian: ["male", "qun", 3, ["jsrgshoushu", "jsrgxundao", "jsrglinghua"]], //承 - jsrg_sunce:['male','wu',4,['jsrgduxing','jsrgzhiheng','jsrgzhasi','jsrgbashi'],['zhu']], - jsrg_xuyou:['male','wei',3,['jsrglipan','jsrgqingxi','jsrgjinmie'],['doublegroup:wei:qun']], - jsrg_lvbu:['male','qun',5,['jsrgwuchang','jsrgqingjiao','jsrgchengxu'],['doublegroup:shu:qun']], - jsrg_zhanghe:['male','wei',4,['jsrgqiongtu','jsrgxianzhu'],['doublegroup:wei:qun']], - jsrg_zoushi:['female','qun',3,['jsrgguyin','jsrgzhangdeng']], - jsrg_guanyu:['male','shu',5,['jsrgguanjue','jsrgnianen'],['border:wei']], - jsrg_chendeng:['male','qun',3,['jsrglunshi','jsrgguitu']], - jsrg_zhenji:['female','qun',3,['jsrgjixiang','jsrgchengxian']], - jsrg_zhangliao:['male','qun',4,['jsrgzhengbing','jsrgtuwei'],['doublegroup:wei:qun']], - jsrg_xugong:['male','wu',3,['jsrgbiaozhao','jsrgyechou']], - jsrg_chunyuqiong:['male','qun',4,['jsrgcangchu','jsrgshishou']], + jsrg_sunce: ["male", "wu", 4, ["jsrgduxing", "jsrgzhiheng", "jsrgzhasi", "jsrgbashi"], ["zhu"]], + jsrg_xuyou: [ + "male", + "wei", + 3, + ["jsrglipan", "jsrgqingxi", "jsrgjinmie"], + ["doublegroup:wei:qun"], + ], + jsrg_lvbu: [ + "male", + "qun", + 5, + ["jsrgwuchang", "jsrgqingjiao", "jsrgchengxu"], + ["doublegroup:shu:qun"], + ], + jsrg_zhanghe: ["male", "wei", 4, ["jsrgqiongtu", "jsrgxianzhu"], ["doublegroup:wei:qun"]], + jsrg_zoushi: ["female", "qun", 3, ["jsrgguyin", "jsrgzhangdeng"]], + jsrg_guanyu: ["male", "shu", 5, ["jsrgguanjue", "jsrgnianen"], ["border:wei"]], + jsrg_chendeng: ["male", "qun", 3, ["jsrglunshi", "jsrgguitu"]], + jsrg_zhenji: ["female", "qun", 3, ["jsrgjixiang", "jsrgchengxian"]], + jsrg_zhangliao: ["male", "qun", 4, ["jsrgzhengbing", "jsrgtuwei"], ["doublegroup:wei:qun"]], + jsrg_xugong: ["male", "wu", 3, ["jsrgbiaozhao", "jsrgyechou"]], + jsrg_chunyuqiong: ["male", "qun", 4, ["jsrgcangchu", "jsrgshishou"]], //转 - jsrg_guojia:['male','wei',3,['jsrgqingzi','jsrgdingce','jsrgzhenfeng']], - jsrg_zhangfei:['male','shu',5,['jsrgbaohe','jsrgxushi']], - jsrg_machao:['male','qun',4,['jsrgzhuiming','mashu']], - jsrg_lougui:['male','wei',3,['jsrgshacheng','jsrgninghan']], - jsrg_zhangren:['male','qun',4,['jsrgfuni','jsrgchuanxin']], - jsrg_huangzhong:['male','shu',4,['jsrgcuifeng','jsrgdengnan']], - jsrg_xiahourong:['male','wei',4,['jsrgfenjian']], - jsrg_sunshangxiang:['female','wu',3,['jsrgguiji','jsrgjiaohao']], - jsrg_pangtong:['male','qun',3,['jsrgmanjuan','jsrgyangming']], - jsrg_hansui:['male','qun',4,['jsrgniluan','jsrghuchou','jsrgjiemeng'],['zhu']], - jsrg_zhangchu:['female','qun',3,['jsrghuozhong','jsrgrihui']], - jsrg_xiahouen:['male','wei',4,['jsrghujian','jsrgshili'],['die_audio:tw_xiahouen']], - jsrg_fanjiangzhangda:['male','wu',5,['jsrgfushan']], + jsrg_guojia: ["male", "wei", 3, ["jsrgqingzi", "jsrgdingce", "jsrgzhenfeng"]], + jsrg_zhangfei: ["male", "shu", 5, ["jsrgbaohe", "jsrgxushi"]], + jsrg_machao: ["male", "qun", 4, ["jsrgzhuiming", "mashu"]], + jsrg_lougui: ["male", "wei", 3, ["jsrgshacheng", "jsrgninghan"]], + jsrg_zhangren: ["male", "qun", 4, ["jsrgfuni", "jsrgchuanxin"]], + jsrg_huangzhong: ["male", "shu", 4, ["jsrgcuifeng", "jsrgdengnan"]], + jsrg_xiahourong: ["male", "wei", 4, ["jsrgfenjian"]], + jsrg_sunshangxiang: ["female", "wu", 3, ["jsrgguiji", "jsrgjiaohao"]], + jsrg_pangtong: ["male", "qun", 3, ["jsrgmanjuan", "jsrgyangming"]], + jsrg_hansui: ["male", "qun", 4, ["jsrgniluan", "jsrghuchou", "jsrgjiemeng"], ["zhu"]], + jsrg_zhangchu: ["female", "qun", 3, ["jsrghuozhong", "jsrgrihui"]], + jsrg_xiahouen: ["male", "wei", 4, ["jsrghujian", "jsrgshili"], ["die_audio:tw_xiahouen"]], + jsrg_fanjiangzhangda: ["male", "wu", 5, ["jsrgfushan"]], //合 - jsrg_zhugeliang:['male','shu',3,['jsrgwentian','jsrgchushi','jsrgyinlve']], - jsrg_jiangwei:['male','shu',4,['jsrgjinfa','jsrgfumou','jsrgxuanfeng'],['border:wei']], - jsrg_luxun:['male','wu',3,['jsrgyoujin','jsrgdailao','jsrgzhubei']], - jsrg_zhaoyun:['male','shu',4,['jsrglonglin','jsrgzhendan']], - jsrg_simayi:['male','wei',4,['jsrgyingshi','jsrgtuigu']], - jsrg_guoxun:['male','wei',4,['jsrgeqian','jsrgfusha']], - jsrg_sunlubansunluyu:['female','wu',3,['jsrgdaimou','jsrgfangjie']], - jsrg_caofang:['male','wei','3/4',['jsrgzhaotu','jsrgjingju','jsrgweizhui'],['zhu']], - jsrg_sunjun:['male','wu',4,['jsrgyaoyan','jsrgbazheng']], - jsrg_liuyong:['male','shu',3,['jsrgdanxin','jsrgfengxiang']], - jsrg_weiwenzhugezhi:['male','wu',4,['jsrgfuhai']], - jsrg_zhangxuan:['female','wu',4,['jsrgtongli','jsrgshezang']], - jsrg_gaoxiang:['male','shu',4,['jsrgchiying']], - jsrg_guozhao:['female','wei',3,['jsrgpianchong','jsrgzunwei']], + jsrg_zhugeliang: ["male", "shu", 3, ["jsrgwentian", "jsrgchushi", "jsrgyinlve"]], + jsrg_jiangwei: ["male", "shu", 4, ["jsrgjinfa", "jsrgfumou", "jsrgxuanfeng"], ["border:wei"]], + jsrg_luxun: ["male", "wu", 3, ["jsrgyoujin", "jsrgdailao", "jsrgzhubei"]], + jsrg_zhaoyun: ["male", "shu", 4, ["jsrglonglin", "jsrgzhendan"]], + jsrg_simayi: ["male", "wei", 4, ["jsrgyingshi", "jsrgtuigu"]], + jsrg_guoxun: ["male", "wei", 4, ["jsrgeqian", "jsrgfusha"]], + jsrg_sunlubansunluyu: ["female", "wu", 3, ["jsrgdaimou", "jsrgfangjie"]], + jsrg_caofang: ["male", "wei", "3/4", ["jsrgzhaotu", "jsrgjingju", "jsrgweizhui"], ["zhu"]], + jsrg_sunjun: ["male", "wu", 4, ["jsrgyaoyan", "jsrgbazheng"]], + jsrg_liuyong: ["male", "shu", 3, ["jsrgdanxin", "jsrgfengxiang"]], + jsrg_weiwenzhugezhi: ["male", "wu", 4, ["jsrgfuhai"]], + jsrg_zhangxuan: ["female", "wu", 4, ["jsrgtongli", "jsrgshezang"]], + jsrg_gaoxiang: ["male", "shu", 4, ["jsrgchiying"]], + jsrg_guozhao: ["female", "wei", 3, ["jsrgpianchong", "jsrgzunwei"]], }, - characterIntro:{ - qiaoxuan:'桥玄(110年-184年6月6日),一作乔玄,字公祖。梁国睢阳县(今河南省商丘市睢阳区)人。东汉时期名臣。桥玄年轻时曾任睢阳县功曹,因坚持追究陈国相羊昌的恶行而闻名。后被举为孝廉,历任洛阳左尉、齐相及上谷、汉阳太守、司徒长史、将作大匠。汉桓帝末年,出任度辽将军,击败鲜卑、南匈奴、高句丽侵扰,保境安民。汉灵帝初年,迁任河南尹、少府、大鸿胪。建宁三年(170年),迁司空。次年,拜司徒。光和元年(178年),升任太尉。桥玄有感于国势日衰,于是称病请辞,改任太中大夫。光和七年(184年),桥玄去世,年七十五。桥玄性格刚强,不阿权贵,待人谦俭,尽管屡历高官,但不因为自己处在高位而有所私请。他为官清廉,去世后连下葬的钱都没有,被时人称为名臣。', - lougui:'娄圭,字子伯,荆州南阳郡(治今河南南阳)人。曹魏时期著名谋士、将军,娄圭年轻时与曹操有交情,曾经随曹操平定冀州,南征刘表,击破马超,立有功劳,连曹操都感叹他的计谋。 后来曹操和他的儿子们一起出去游玩,娄圭当时也一起随行。因言语不当,被南郡(治今湖北荆州)人习授举报,曹操认为有意诽谤,遭杀害。在小说《三国演义》里,娄圭被设定为京兆人(今陕西西安),隐居终南山,道号“梦梅居士”。于第59回登场。', - xiahourong:'夏侯荣(207年—219年) ,字幼权,名将夏侯渊之子。建安二十四年(219年)汉中之战,父亲夏侯渊战死后,夏侯荣不愿逃跑,随后拔剑冲入敌阵,战死。', - guoxun:'郭脩(?~253年),一作郭循,字孝先,凉州西平人,三国时期曹魏官员。原为曹魏中郎,被蜀汉将领姜维俘虏后降蜀汉,任左将军,后来刺杀了蜀汉大将军费祎。被曹魏追封为长乐乡侯,谥曰威侯。', - caofang:'曹芳(232年-274年),字兰卿,沛国谯县(今安徽省亳州市)人。三国时期曹魏第三位皇帝(239年1月22日-254年10月17日在位),疑为魏武帝曹操曾孙,任城威王曹彰之孙,任城王曹楷之子。太和六年(232年),生于任城王府。青龙三年(235年),选为魏明帝曹叡养子,册封齐王。景初三年(239年),立为皇太子,同日魏明帝曹叡病死,曹芳正式即位,由大将军曹爽和太尉司马懿共同辅政。正始十年,经历高平陵之变,曹爽倒台,政权落入司马氏手中。嘉平六年(254年),中书令李丰和光禄大夫张缉图谋废掉司马师,改立夏侯玄为大将军。司马师平定叛乱后,将曹芳废为齐王,拥戴高贵乡公曹髦继位。西晋建立后,册封邵陵县公。泰始十年(274年),曹芳病逝,终年四十三岁,谥号为厉。', - sunjun:'孙峻(219年-256年10月19日),字子远,扬州吴郡富春(今浙江省杭州市)人,昭义中郎将孙静曾孙,定武中郎将孙暠之孙,散骑侍郎孙恭之子。三国时期吴国宗室、权臣。孙峻从小弓马娴熟,胆量非凡。孙权晚年时,孙峻担任武卫都尉,掌握军权,然后又任侍中,开始涉足朝政。孙权临终前,孙峻接受遗诏同诸葛恪、滕胤共同辅佐朝政。此后,其身兼武卫将军,一直主持宫廷的值班、守卫等要害部门,并被封为都乡侯。孙峻生性喜好专断,容不下诸葛恪,于是与吴主孙亮密谋发动政变,在酒宴中设伏兵杀死诸葛恪。孙峻谋杀诸葛恪之后,升任丞相、大将军,督察内外一切军务,假节,晋封富春侯。此后,孙峻独揽朝政。孙峻在任职期间,滥施刑杀,淫乱宫女,和全公主孙鲁班私通。五凤元年(254年),吴侯孙英企图谋杀孙峻,后来事情被泄露,孙英自杀。时隔一年,吴国将军孙仪、张怡、林恂等人乘蜀国使节来访之机,共同谋划诛杀孙峻。后被孙峻发觉,孙仪自杀,林恂等被认为有罪诛死。太平元年(256年),孙峻梦见被诸葛恪所击,因惊悸恐惧发病而死,时年38岁。', - sunlubansunluyu:'孙鲁班,孙权之女。孙鲁班与孙权二子孙和不睦。孙权长子孙登死后,孙和被立为太子。孙鲁班向孙权进谗言废孙和太子之位,孙和被废后忧愤而死。
              孙鲁育,又名小虎,孙权与步练师之女。吴后期,孙鲁班诬陷孙鲁育参与谋反,于是孙峻杀害了孙鲁育。', - jsrg_caocao:'初平元年二月,董卓徙天子都长安,焚洛阳宫室,众诸侯畏卓兵强,莫敢进。操怒斥众人:“为人臣而临此境,当举义兵以诛暴乱,大众已合,诸君何疑?此一战而天下定矣!”遂引兵汴水,遇卓将徐荣,大破之。操迎天子,攻吕布,伐袁术,安汉室,拜为征西将军。是时,袁绍兼四州之地,将攻许都。操欲扫清寰宇,兴复汉室,遂屯兵官渡。既克绍,操曰:“若天命在吾,吾为周文王矣。”', - jsrg_sunce:'建安五年,操、绍相拒于官渡,孙策欲阴袭许昌,迎汉帝,遂密治兵,部署诸将。未发,会为许贡门客所刺,将计就计,尽托江东于权,诈死以待天时。八月,操、绍决战,孙策亲冒矢石,斩将刈旗,得扬、豫之地。曹操败走冀、青,刘备远遁荆、益。而后历时七年,孙策三分天下已有其二,帝于洛阳,建霸王未竟之功业。权表求吴王,封为仲帝,共治天下。', - jsrg_guojia:'初平元年二月,郭嘉拜见袁绍,闻曹操怒斥众诸侯,乃对曰:“董卓于汴水或有埋伏,慎之!”曹操未从,果败于徐荣。三月,曹操与郭嘉论天下事:“使孤成大业者,必此人也。”郭嘉从破袁绍,讨谭、尚,连战数克,计定辽东。时年三十八,征乌桓归途郭嘉因劳染疾,命悬之际竟意外饮下柳皮醋水而愈。建安十三年,曹操屯兵赤壁,郭嘉识破连环之计,议上中下三策,可胜刘备。尚未献策,曹操便决意采纳上策,“奉孝之才,足胜孤百倍,卿言上策,如何不取?”由此,赤壁战后曹操尽得天下。', - jsrg_zhugeliang:'建兴六年春,汉丞相诸葛亮使赵云、邓芝为先锋,马谡为副将拒箕谷,牵制曹真主力。自率三十万大军攻祁山,三郡叛魏应亮,关中响震。曹叡命张郃拒亮,亮使定军山降将姜维与郃战于街亭,张郃久攻不下。后曹真强攻赵云军,赵云死战,坚守箕谷,马谡、邓芝当场战死忠勇殉国。……既克张郃,曹真溃逃,曹叡弃守长安,迁都邺城。十月,司马懿击退孙权,回援曹真。而后三年,丞相所到之处,无不望风而降,皆箪食壶浆,以迎汉军。尽收豫、徐、兖、并之地,建兴十年春,司马懿父子三人死于诸葛武侯火计,同年,孙权上表称臣,至此四海清平,大汉一统。而后诸葛亮荐蒋琬为丞相,姜维为大将军,自回隆中归隐,后主挽留再三,皆不受。魏延亦辞官相随,侍奉左右。后主时有不决之事,便往隆中拜访相父,均未得面,童子答曰外出云游,遗数锦囊,拆而视之,皆治国之良策也。', + characterIntro: { + qiaoxuan: + "桥玄(110年-184年6月6日),一作乔玄,字公祖。梁国睢阳县(今河南省商丘市睢阳区)人。东汉时期名臣。桥玄年轻时曾任睢阳县功曹,因坚持追究陈国相羊昌的恶行而闻名。后被举为孝廉,历任洛阳左尉、齐相及上谷、汉阳太守、司徒长史、将作大匠。汉桓帝末年,出任度辽将军,击败鲜卑、南匈奴、高句丽侵扰,保境安民。汉灵帝初年,迁任河南尹、少府、大鸿胪。建宁三年(170年),迁司空。次年,拜司徒。光和元年(178年),升任太尉。桥玄有感于国势日衰,于是称病请辞,改任太中大夫。光和七年(184年),桥玄去世,年七十五。桥玄性格刚强,不阿权贵,待人谦俭,尽管屡历高官,但不因为自己处在高位而有所私请。他为官清廉,去世后连下葬的钱都没有,被时人称为名臣。", + lougui: "娄圭,字子伯,荆州南阳郡(治今河南南阳)人。曹魏时期著名谋士、将军,娄圭年轻时与曹操有交情,曾经随曹操平定冀州,南征刘表,击破马超,立有功劳,连曹操都感叹他的计谋。 后来曹操和他的儿子们一起出去游玩,娄圭当时也一起随行。因言语不当,被南郡(治今湖北荆州)人习授举报,曹操认为有意诽谤,遭杀害。在小说《三国演义》里,娄圭被设定为京兆人(今陕西西安),隐居终南山,道号“梦梅居士”。于第59回登场。", + xiahourong: + "夏侯荣(207年—219年) ,字幼权,名将夏侯渊之子。建安二十四年(219年)汉中之战,父亲夏侯渊战死后,夏侯荣不愿逃跑,随后拔剑冲入敌阵,战死。", + guoxun: "郭脩(?~253年),一作郭循,字孝先,凉州西平人,三国时期曹魏官员。原为曹魏中郎,被蜀汉将领姜维俘虏后降蜀汉,任左将军,后来刺杀了蜀汉大将军费祎。被曹魏追封为长乐乡侯,谥曰威侯。", + caofang: + "曹芳(232年-274年),字兰卿,沛国谯县(今安徽省亳州市)人。三国时期曹魏第三位皇帝(239年1月22日-254年10月17日在位),疑为魏武帝曹操曾孙,任城威王曹彰之孙,任城王曹楷之子。太和六年(232年),生于任城王府。青龙三年(235年),选为魏明帝曹叡养子,册封齐王。景初三年(239年),立为皇太子,同日魏明帝曹叡病死,曹芳正式即位,由大将军曹爽和太尉司马懿共同辅政。正始十年,经历高平陵之变,曹爽倒台,政权落入司马氏手中。嘉平六年(254年),中书令李丰和光禄大夫张缉图谋废掉司马师,改立夏侯玄为大将军。司马师平定叛乱后,将曹芳废为齐王,拥戴高贵乡公曹髦继位。西晋建立后,册封邵陵县公。泰始十年(274年),曹芳病逝,终年四十三岁,谥号为厉。", + sunjun: "孙峻(219年-256年10月19日),字子远,扬州吴郡富春(今浙江省杭州市)人,昭义中郎将孙静曾孙,定武中郎将孙暠之孙,散骑侍郎孙恭之子。三国时期吴国宗室、权臣。孙峻从小弓马娴熟,胆量非凡。孙权晚年时,孙峻担任武卫都尉,掌握军权,然后又任侍中,开始涉足朝政。孙权临终前,孙峻接受遗诏同诸葛恪、滕胤共同辅佐朝政。此后,其身兼武卫将军,一直主持宫廷的值班、守卫等要害部门,并被封为都乡侯。孙峻生性喜好专断,容不下诸葛恪,于是与吴主孙亮密谋发动政变,在酒宴中设伏兵杀死诸葛恪。孙峻谋杀诸葛恪之后,升任丞相、大将军,督察内外一切军务,假节,晋封富春侯。此后,孙峻独揽朝政。孙峻在任职期间,滥施刑杀,淫乱宫女,和全公主孙鲁班私通。五凤元年(254年),吴侯孙英企图谋杀孙峻,后来事情被泄露,孙英自杀。时隔一年,吴国将军孙仪、张怡、林恂等人乘蜀国使节来访之机,共同谋划诛杀孙峻。后被孙峻发觉,孙仪自杀,林恂等被认为有罪诛死。太平元年(256年),孙峻梦见被诸葛恪所击,因惊悸恐惧发病而死,时年38岁。", + sunlubansunluyu: + "孙鲁班,孙权之女。孙鲁班与孙权二子孙和不睦。孙权长子孙登死后,孙和被立为太子。孙鲁班向孙权进谗言废孙和太子之位,孙和被废后忧愤而死。
              孙鲁育,又名小虎,孙权与步练师之女。吴后期,孙鲁班诬陷孙鲁育参与谋反,于是孙峻杀害了孙鲁育。", + jsrg_caocao: + "初平元年二月,董卓徙天子都长安,焚洛阳宫室,众诸侯畏卓兵强,莫敢进。操怒斥众人:“为人臣而临此境,当举义兵以诛暴乱,大众已合,诸君何疑?此一战而天下定矣!”遂引兵汴水,遇卓将徐荣,大破之。操迎天子,攻吕布,伐袁术,安汉室,拜为征西将军。是时,袁绍兼四州之地,将攻许都。操欲扫清寰宇,兴复汉室,遂屯兵官渡。既克绍,操曰:“若天命在吾,吾为周文王矣。”", + jsrg_sunce: + "建安五年,操、绍相拒于官渡,孙策欲阴袭许昌,迎汉帝,遂密治兵,部署诸将。未发,会为许贡门客所刺,将计就计,尽托江东于权,诈死以待天时。八月,操、绍决战,孙策亲冒矢石,斩将刈旗,得扬、豫之地。曹操败走冀、青,刘备远遁荆、益。而后历时七年,孙策三分天下已有其二,帝于洛阳,建霸王未竟之功业。权表求吴王,封为仲帝,共治天下。", + jsrg_guojia: + "初平元年二月,郭嘉拜见袁绍,闻曹操怒斥众诸侯,乃对曰:“董卓于汴水或有埋伏,慎之!”曹操未从,果败于徐荣。三月,曹操与郭嘉论天下事:“使孤成大业者,必此人也。”郭嘉从破袁绍,讨谭、尚,连战数克,计定辽东。时年三十八,征乌桓归途郭嘉因劳染疾,命悬之际竟意外饮下柳皮醋水而愈。建安十三年,曹操屯兵赤壁,郭嘉识破连环之计,议上中下三策,可胜刘备。尚未献策,曹操便决意采纳上策,“奉孝之才,足胜孤百倍,卿言上策,如何不取?”由此,赤壁战后曹操尽得天下。", + jsrg_zhugeliang: + "建兴六年春,汉丞相诸葛亮使赵云、邓芝为先锋,马谡为副将拒箕谷,牵制曹真主力。自率三十万大军攻祁山,三郡叛魏应亮,关中响震。曹叡命张郃拒亮,亮使定军山降将姜维与郃战于街亭,张郃久攻不下。后曹真强攻赵云军,赵云死战,坚守箕谷,马谡、邓芝当场战死忠勇殉国。……既克张郃,曹真溃逃,曹叡弃守长安,迁都邺城。十月,司马懿击退孙权,回援曹真。而后三年,丞相所到之处,无不望风而降,皆箪食壶浆,以迎汉军。尽收豫、徐、兖、并之地,建兴十年春,司马懿父子三人死于诸葛武侯火计,同年,孙权上表称臣,至此四海清平,大汉一统。而后诸葛亮荐蒋琬为丞相,姜维为大将军,自回隆中归隐,后主挽留再三,皆不受。魏延亦辞官相随,侍奉左右。后主时有不决之事,便往隆中拜访相父,均未得面,童子答曰外出云游,遗数锦囊,拆而视之,皆治国之良策也。", }, - characterTitle:{ + characterTitle: {}, + characterFilter: { + jsrg_jiangwei(mode) { + return mode !== "guozhan"; + }, }, - perfectPair:{}, - card:{ - xumou_jsrg:{ - type:'special_delay', - allowDuplicate:true, - blankCard:true, - fullimage:true, - wuxieable:false, - effect:function(){ - 'step 0' - var card=get.autoViewAs(event.cards[0]); - card.storage.xumou_jsrg=true; - player.chooseUseTarget(card,event.cards,`蓄谋:是否使用${get.translation(card)}?`,`请选择要使用的目标。若不使用此牌,则判定区内的所有“蓄谋”牌都将被置入弃牌堆。`); - 'step 1' - if(!result.bool){ - var cards=player.getCards('j',card=>{ - return (card.viewAs||card.name)=='xumou_jsrg'; + perfectPair: {}, + card: { + xumou_jsrg: { + type: "special_delay", + allowDuplicate: true, + blankCard: true, + fullimage: true, + wuxieable: false, + effect: function () { + "step 0"; + var card = get.autoViewAs(event.cards[0]); + card.storage.xumou_jsrg = true; + player.chooseUseTarget( + card, + event.cards, + `蓄谋:是否使用${get.translation(card)}?`, + `请选择要使用的目标。若不使用此牌,则判定区内的所有“蓄谋”牌都将被置入弃牌堆。` + ); + "step 1"; + if (!result.bool) { + var cards = player.getCards("j", (card) => { + return (card.viewAs || card.name) == "xumou_jsrg"; }); - if(cards.length>0) player.loseToDiscardpile(cards); - } - else{ - player.addTempSkill('xumou_jsrg_temp','phaseChange'); - player.markAuto('xumou_jsrg_temp',[event.cards[0].name]) + if (cards.length > 0) player.loseToDiscardpile(cards); + } else { + player.addTempSkill("xumou_jsrg_temp", "phaseChange"); + player.markAuto("xumou_jsrg_temp", [event.cards[0].name]); } }, }, - ying:{ - audio:true, - fullskin:true, - type:'basic', - enable:false, - destroy:'discardPile', - getYing:function(count){ - var cards=[]; - if(typeof count!='number') count=1; - while(count--){ - let card=game.createCard('ying','spade',1); + ying: { + audio: true, + fullskin: true, + type: "basic", + enable: false, + destroy: "discardPile", + getYing: function (count) { + var cards = []; + if (typeof count != "number") count = 1; + while (count--) { + let card = game.createCard("ying", "spade", 1); cards.push(card); } return cards; }, - ai:{ - basic:{ - useful:0, - value:0, + ai: { + basic: { + useful: 0, + value: 0, }, }, }, }, - characterFilter:{ - jsrg_xushao:function(mode){ - return mode!='guozhan'; + characterFilter: { + jsrg_xushao: function (mode) { + return mode != "guozhan"; }, }, - skill:{ + skill: { //江山如故·合 //蓄谋临时禁用 - xumou_jsrg_temp:{ - charlotte:true, - onremove:true, - mod:{ - cardEnabled(card,player){ - if(!card.storage||!card.storage.xumou_jsrg) return; - if(player.getStorage('xumou_jsrg_temp').includes(get.name(card,false))) return false; + xumou_jsrg_temp: { + charlotte: true, + onremove: true, + mod: { + cardEnabled(card, player) { + if (!card.storage || !card.storage.xumou_jsrg) return; + if (player.getStorage("xumou_jsrg_temp").includes(get.name(card, false))) + return false; }, }, }, //404诸葛亮 - jsrgwentian:{ - audio:2, - trigger:{ - player:['phaseZhunbeiBegin','phaseJudgeBegin','phaseDrawBegin','phaseUseBegin','phaseDiscardBegin','phaseJieshuBegin'], + jsrgwentian: { + audio: 2, + trigger: { + player: [ + "phaseZhunbeiBegin", + "phaseJudgeBegin", + "phaseDrawBegin", + "phaseUseBegin", + "phaseDiscardBegin", + "phaseJieshuBegin", + ], }, - usable:1, - prompt2:'观看牌堆顶的五张牌,将其中一张交给其他角色,并将其余牌置于牌堆顶或牌堆底', - group:'jsrgwentian_viewas', - async content(event,trigger,player){ - const cards=get.cards(5); + usable: 1, + prompt2: "观看牌堆顶的五张牌,将其中一张交给其他角色,并将其余牌置于牌堆顶或牌堆底", + group: "jsrgwentian_viewas", + async content(event, trigger, player) { + const cards = get.cards(5); game.cardsGotoOrdering(cards); - const {result}=await player.chooseButton([ - '问天:将一张牌交给一名其他角色', - cards - ],true); - if(result.bool){ - const {result:result2}=await player.chooseTarget(`将${get.translation(result.links)}交给一名其他角色`,lib.filter.notMe,true).set('ai',target=>{ - return get.attitude(get.player(),target); - }); - if(result2.bool){ + const { result } = await player.chooseButton( + ["问天:将一张牌交给一名其他角色", cards], + true + ); + if (result.bool) { + const { result: result2 } = await player + .chooseTarget( + `将${get.translation(result.links)}交给一名其他角色`, + lib.filter.notMe, + true + ) + .set("ai", (target) => { + return get.attitude(get.player(), target); + }); + if (result2.bool) { cards.removeArray(result.links); - const target=result2.targets[0]; - player.line(target,'green'); - await target.gain(result.links,'gain2').set('giver',player); + const target = result2.targets[0]; + player.line(target, "green"); + await target.gain(result.links, "gain2").set("giver", player); } } - const next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards.filterInD()], - ['牌堆底'], - ]); - next.set('prompt','问天:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=list=>{ - const cards=list[0][1],player=_status.event.player; - const top=[]; - const judges=player.getCards('j'); - let stopped=false; - if(!player.hasWuxie()){ - for(let i=0;ijudge(b)-judge(a)); - if(judge(cards[0])<0){ - stopped=true;break; - } - else{ + const next = player.chooseToMove(); + next.set("list", [["牌堆顶", cards.filterInD()], ["牌堆底"]]); + next.set("prompt", "问天:点击将牌移动到牌堆顶或牌堆底"); + next.processAI = (list) => { + const cards = list[0][1], + player = _status.event.player; + const top = []; + const judges = player.getCards("j"); + let stopped = false; + if (!player.hasWuxie()) { + for (let i = 0; i < judges.length; i++) { + const judge = get.judge(judges[i]); + cards.sort((a, b) => judge(b) - judge(a)); + if (judge(cards[0]) < 0) { + stopped = true; + break; + } else { top.unshift(cards.shift()); } } } let bottom; - if(!stopped){ - cards.sort((a,b)=>get.value(b,player)-get.value(a,player)); - while(cards.length){ - if(get.value(cards[0],player)<=5) break; + if (!stopped) { + cards.sort((a, b) => get.value(b, player) - get.value(a, player)); + while (cards.length) { + if (get.value(cards[0], player) <= 5) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - const {result:{moved}}=await next; - const top=moved[0]; - const bottom=moved[1]; + bottom = cards; + return [top, bottom]; + }; + const { + result: { moved }, + } = await next; + const top = moved[0]; + const bottom = moved[1]; top.reverse(); - game.cardsGotoPile( - top.concat(bottom), - ['top_cards',top], - (event,card)=>{ - if(event.top_cards.includes(card)) return ui.cardPile.firstChild; - return null; - } - ); - player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); - game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶'); + game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => { + if (event.top_cards.includes(card)) return ui.cardPile.firstChild; + return null; + }); + player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下"); + game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶"); game.asyncDelayx(); }, - subSkill:{ - viewas:{ - audio:'jsrgwentian', - enable:'chooseToUse', - filter:function(event,player){ - for(const name of ['wuxie','huogong']){ - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) return true; + subSkill: { + viewas: { + audio: "jsrgwentian", + enable: "chooseToUse", + filter: function (event, player) { + for (const name of ["wuxie", "huogong"]) { + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) + return true; } return false; }, - hiddenCard:function(player,name){ - if(player.isTempBanned('jsrgwentian')) return false; - return name=='wuxie'; + hiddenCard: function (player, name) { + if (player.isTempBanned("jsrgwentian")) return false; + return name == "wuxie"; }, - viewAs:function(cards,player){ - const event=get.event(),filter=event._backup.filterCard; - for(const name of ['wuxie','huogong']){ - if(filter(get.autoViewAs({name},'unsure'),player,event)) return {name}; + viewAs: function (cards, player) { + const event = get.event(), + filter = event._backup.filterCard; + for (const name of ["wuxie", "huogong"]) { + if (filter(get.autoViewAs({ name }, "unsure"), player, event)) + return { name }; } return null; }, - filterCard:()=>false, - selectCard:-1, - prompt:function(){ - const player=get.player(); - const event=get.event(),filter=event._backup.filterCard; - let str='将牌堆顶的牌当【'; - for(const name of ['wuxie','huogong']){ - if(filter({name},player,event)){ - str+=get.translation(name); break; + filterCard: () => false, + selectCard: -1, + prompt: function () { + const player = get.player(); + const event = get.event(), + filter = event._backup.filterCard; + let str = "将牌堆顶的牌当【"; + for (const name of ["wuxie", "huogong"]) { + if (filter({ name }, player, event)) { + str += get.translation(name); + break; } } - str+='】使用'; + str += "】使用"; return str; }, - precontent(){ - player.logSkill('jsrgwentian'); - const cards=get.cards(); - event.result.cards=cards; + precontent() { + player.logSkill("jsrgwentian"); + const cards = get.cards(); + event.result.cards = cards; delete event.result.skill; game.cardsGotoOrdering(cards); - const color=event.result.card.name=='wuxie'?'black':'red'; - if(get.color(cards,false)!=color){ - player.tempBanSkill('jsrgwentian','roundStart'); + const color = event.result.card.name == "wuxie" ? "black" : "red"; + if (get.color(cards, false) != color) { + player.tempBanSkill("jsrgwentian", "roundStart"); } - } - } - } - }, - jsrgchushi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - const zhu=get.zhu(player); - if(!zhu||!zhu.isZhu2()||!zhu.countCards('h')) return false; - return !player.isZhu2()&&player.countCards('h'); + }, + }, }, - async content(event,trigger,player){ - player.chooseToDebate(game.filterPlayer(current=>{ - return (current==player||current.isZhu2())&¤t.countCards('h'); - })).set('callback',async event=>{ - const result=event.debateResult; - if(result.bool&&result.opinion){ - const {opinion,targets}=result; - targets.sortBySeat(); - if(opinion=='red'){ - do{ - for(const current of targets){ - await current.draw(); - } + }, + jsrgchushi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + const zhu = get.zhu(player); + if (!zhu || !zhu.isZhu2() || !zhu.countCards("h")) return false; + return !player.isZhu2() && player.countCards("h"); + }, + async content(event, trigger, player) { + player + .chooseToDebate( + game.filterPlayer((current) => { + return (current == player || current.isZhu2()) && current.countCards("h"); + }) + ) + .set("callback", async (event) => { + const result = event.debateResult; + if (result.bool && result.opinion) { + const { opinion, targets } = result; + targets.sortBySeat(); + if (opinion == "red") { + do { + for (const current of targets) { + await current.draw(); + } + } while ( + targets + .map((current) => { + return current.countCards("h"); + }) + .reduce((p, c) => { + return p + c; + }, 0) < 7 + ); + } else { + player.addMark("jsrgchushi_add", 1, false); + player.addTempSkill("jsrgchushi_add", "roundStart"); } - while(targets.map(current=>{ - return current.countCards('h'); - }).reduce((p,c)=>{ - return p+c; - },0)<7); } - else{ - player.addMark('jsrgchushi_add',1,false); - player.addTempSkill('jsrgchushi_add','roundStart'); - } - } - }) + }); }, - subSkill:{ - add:{ - audio:'jsrgchushi', - trigger:{source:'damageBegin1'}, - filter:function(event){ - return event.hasNature('linked'); + subSkill: { + add: { + audio: "jsrgchushi", + trigger: { source: "damageBegin1" }, + filter: function (event) { + return event.hasNature("linked"); }, - forced:true, - charlotte:true, - onremove:true, - async content(_,trigger,player){ - trigger.num+=player.countMark('jsrgchushi_add'); + forced: true, + charlotte: true, + onremove: true, + async content(_, trigger, player) { + trigger.num += player.countMark("jsrgchushi_add"); }, - ai:{ - damageBonus:true, - skillTagFilter:function(player,tag,arg){ - if(tag==='damageBonus') return arg&&arg.card&&game.hasNature(arg.card,'linked'); - } + ai: { + damageBonus: true, + skillTagFilter: function (player, tag, arg) { + if (tag === "damageBonus") + return arg && arg.card && game.hasNature(arg.card, "linked"); + }, }, - intro:{ - content:'造成的属性伤害+#', - } - } - } + intro: { + content: "造成的属性伤害+#", + }, + }, + }, }, - jsrgyinlve:{ - audio:2, - trigger:{ - global:'damageBegin4', + jsrgyinlve: { + audio: 2, + trigger: { + global: "damageBegin4", }, - filter:function(event,player){ - return event.player.isIn()&&['fire','thunder'].some(n=>!player.hasSkill(`jsrgyinlve_${n}`)&&event.hasNature(n)); + filter: function (event, player) { + return ( + event.player.isIn() && + ["fire", "thunder"].some( + (n) => !player.hasSkill(`jsrgyinlve_${n}`) && event.hasNature(n) + ) + ); }, - check:function(event,player){ - if(get.damageEffect(event.player,event.source,player,get.natureList(event.nature))<-5) return true; + check: function (event, player) { + if ( + get.damageEffect(event.player, event.source, player, get.natureList(event.nature)) < + -5 + ) + return true; return false; }, - logTarget:'player', - async content(event,trigger,player){ + logTarget: "player", + async content(event, trigger, player) { trigger.cancel(); - const natures=['fire','thunder']; + const natures = ["fire", "thunder"]; let index; - if(natures.every(n=>!player.hasSkill(`jsrgyinlve_${n}`)&&trigger.hasNature(n))){ - const {result}=await player.chooseControl(['摸牌阶段','弃牌阶段']).set('prompt','请选择要新回合内仅有的阶段'); - index=result.index; - } - else index=[0,1].find(i=>!player.hasSkill(`jsrgyinlve_${natures[i]}`)&&trigger.hasNature(natures[i])); - player.addTempSkill(`jsrgyinlve_${natures[index]}`,'roundStart'); - player.insertPhase().set('phaseList',[['phaseDraw','phaseDiscard'][index]]); + if (natures.every((n) => !player.hasSkill(`jsrgyinlve_${n}`) && trigger.hasNature(n))) { + const { result } = await player + .chooseControl(["摸牌阶段", "弃牌阶段"]) + .set("prompt", "请选择要新回合内仅有的阶段"); + index = result.index; + } else + index = [0, 1].find( + (i) => + !player.hasSkill(`jsrgyinlve_${natures[i]}`) && trigger.hasNature(natures[i]) + ); + player.addTempSkill(`jsrgyinlve_${natures[index]}`, "roundStart"); + player.insertPhase().set("phaseList", [["phaseDraw", "phaseDiscard"][index]]); + }, + subSkill: { + fire: { charlotte: true }, + thunder: { charlotte: true }, }, - subSkill:{ - fire:{charlotte:true}, - thunder:{charlotte:true}, - } }, //姜维 - jsrgjinfa:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:true, - position:'h', - discard:false, - lose:false, - delay:false, - check:function(){ - return 1+Math.random(); + jsrgjinfa: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "h", + discard: false, + lose: false, + delay: false, + check: function () { + return 1 + Math.random(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await player.showCards(event.cards); - player.chooseToDebate(game.filterPlayer(current=>{ - return current.maxHp<=player.maxHp; - })).set('callback',async (event)=>{ - const result=event.debateResult; - if(result.bool&&result.opinion){ - const {cards:fixedCards}=event.getParent('jsrgjinfa'); - const color=get.color(fixedCards); - const {opinion,targets}=result; - if(opinion==color){ - const {result}=await player.chooseTarget('是否令至多两名参与议事的角色将手牌摸至体力上限?',[1,2],(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('targets',targets).set('ai',target=>{ - const player=get.player(); - const att=get.attitude(player,target); - if(att<=0) return -1; - return att*Math.sqrt(Math.max(0.1,target.maxHp-target.countCards('h'))); - }); - if(result.bool){ - const targets=result.targets; - targets.sortBySeat(); - player.line(targets,'green'); - for(const current of targets){ - if(current.countCards('h') { + return current.maxHp <= player.maxHp; + }) + ) + .set("callback", async (event) => { + const result = event.debateResult; + if (result.bool && result.opinion) { + const { cards: fixedCards } = event.getParent("jsrgjinfa"); + const color = get.color(fixedCards); + const { opinion, targets } = result; + if (opinion == color) { + const { result } = await player + .chooseTarget( + "是否令至多两名参与议事的角色将手牌摸至体力上限?", + [1, 2], + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("targets", targets) + .set("ai", (target) => { + const player = get.player(); + const att = get.attitude(player, target); + if (att <= 0) return -1; + return ( + att * + Math.sqrt( + Math.max(0.1, target.maxHp - target.countCards("h")) + ) + ); + }); + if (result.bool) { + const targets = result.targets; + targets.sortBySeat(); + player.line(targets, "green"); + for (const current of targets) { + if (current.countCards("h") < current.maxHp) + await current.drawTo(current.maxHp); + } } + } else { + await player.gain(lib.card.ying.getYing(2), "gain2"); } } - else{ - await player.gain(lib.card.ying.getYing(2),'gain2'); + const { red, black } = result; + if ( + (red.length == 1 && red[0][0] == player) || + (black.length == 1 && black[0][0] == player) + ) { + const list = lib.group.slice(); + list.remove(player.group); + list.push("cancel2"); + const { + result: { control }, + } = await player + .chooseControl(list) + .set("prompt", "是否变更势力?") + .set("ai", () => { + if (!get.event("change")) return "cancel2"; + const controls = get.event("controls"); + const groups = ["wei", "shu"].filter((g) => controls.includes(g)); + if (groups.length) return groups.randomGet(); + return controls.randomGet(); + }) + .set( + "change", + ["wei", "shu"].includes(player.group) ? Math.random() < 0.5 : true + ); + if (control != "cancel2") { + player.popup(control + "2", get.groupnature(control, "raw")); + player.changeGroup(control); + } } - } - const {red,black}=result; - if(red.length==1&&red[0][0]==player||black.length==1&&black[0][0]==player){ - const list=lib.group.slice(); - list.remove(player.group); - list.push('cancel2'); - const {result:{control}}=await player.chooseControl(list).set('prompt','是否变更势力?').set('ai',()=>{ - if(!get.event('change')) return 'cancel2'; - const controls=get.event('controls'); - const groups=['wei','shu'].filter(g=>controls.includes(g)); - if(groups.length) return groups.randomGet(); - return controls.randomGet(); - }).set('change',['wei','shu'].includes(player.group)?(Math.random()<0.5):true); - if(control!='cancel2'){ - player.popup(control+'2',get.groupnature(control,'raw')); - player.changeGroup(control); - } - } - }); + }); }, - ai:{ - order:function(item,player){ - if(player.countCards('h')==1) return 10; + ai: { + order: function (item, player) { + if (player.countCards("h") == 1) return 10; return 1; }, - result:{ - player:1, + result: { + player: 1, }, - } + }, }, - jsrgfumou:{ - audio:2, - trigger:{global:'chooseToDebateAfter'}, - groupSkill:true, - forced:true, - locked:false, - filter:function(event,player){ - if(player.group!='wei') return false; - if(!event.targets.includes(player)) return false; - if(event.red.some(i=>i[0]==player)) return event.black.length; - if(event.black.some(i=>i[0]==player)) return event.red.length; + jsrgfumou: { + audio: 2, + trigger: { global: "chooseToDebateAfter" }, + groupSkill: true, + forced: true, + locked: false, + filter: function (event, player) { + if (player.group != "wei") return false; + if (!event.targets.includes(player)) return false; + if (event.red.some((i) => i[0] == player)) return event.black.length; + if (event.black.some((i) => i[0] == player)) return event.red.length; return false; }, - async content(event,trigger,player){ - const targets=[]; - if(trigger.red.some(i=>i[0]==player)) targets.addArray(trigger.black.map(i=>i[0])); - if(trigger.black.some(i=>i[0]==player)) targets.addArray(trigger.red.map(i=>i[0])); - player.line(targets,'thunder'); - targets.forEach(target=>{ - target.addTempSkill('jsrgfumou_forbid'); - target.markAuto('jsrgfumou_forbid',['red','black'].filter(color=>{ - return trigger[color].some(i=>i[0]==target); - })) + async content(event, trigger, player) { + const targets = []; + if (trigger.red.some((i) => i[0] == player)) + targets.addArray(trigger.black.map((i) => i[0])); + if (trigger.black.some((i) => i[0] == player)) + targets.addArray(trigger.red.map((i) => i[0])); + player.line(targets, "thunder"); + targets.forEach((target) => { + target.addTempSkill("jsrgfumou_forbid"); + target.markAuto( + "jsrgfumou_forbid", + ["red", "black"].filter((color) => { + return trigger[color].some((i) => i[0] == target); + }) + ); }); - game.broadcastAll(targets=>{ - lib.skill.jsrgfumou_backup.targets=targets; - },targets); - const next=player.chooseToUse(); - next.set('openskilldialog',`是否将一张【影】当【出其不意】对一名与你意见不同的角色使用?`); - next.set('norestore',true); - next.set('_backupevent','jsrgfumou_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + game.broadcastAll((targets) => { + lib.skill.jsrgfumou_backup.targets = targets; + }, targets); + const next = player.chooseToUse(); + next.set( + "openskilldialog", + `是否将一张【影】当【出其不意】对一名与你意见不同的角色使用?` + ); + next.set("norestore", true); + next.set("_backupevent", "jsrgfumou_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('jsrgfumou_backup'); + next.backup("jsrgfumou_backup"); }, - subSkill:{ - backup:{ - filterCard:function(card){ - return get.itemtype(card)=='card'&&get.name(card)=='ying'; + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card" && get.name(card) == "ying"; }, - viewAs:{ - name:'chuqibuyi', + viewAs: { + name: "chuqibuyi", }, - selectCard:1, - position:'hs', - log:false, - filterTarget:function(card,player,target){ - const targets=lib.skill.jsrgfumou_backup.targets; - if(!targets.includes(target)||ui.selected.targets.containsSome(targets)) return false; - return lib.filter.targetEnabled.apply(this,arguments); + selectCard: 1, + position: "hs", + log: false, + filterTarget: function (card, player, target) { + const targets = lib.skill.jsrgfumou_backup.targets; + if (!targets.includes(target) || ui.selected.targets.containsSome(targets)) + return false; + return lib.filter.targetEnabled.apply(this, arguments); }, - ai1:function(card){ - return 6-get.value(card); + ai1: function (card) { + return 6 - get.value(card); }, - precontent:function(){ + precontent: function () { delete event.result.skill; }, }, - forbid:{ - charlotte:true, - onremove:true, - mod:{ - cardEnabled:function(card,player){ + forbid: { + charlotte: true, + onremove: true, + mod: { + cardEnabled: function (card, player) { const color = get.color(card); - if (color != 'unsure' && player.getStorage('jsrgfumou_forbid').includes(color)) return false; + if ( + color != "unsure" && + player.getStorage("jsrgfumou_forbid").includes(color) + ) + return false; }, - cardRespondable:function(card,player){ + cardRespondable: function (card, player) { const color = get.color(card); - if (color != 'unsure' && player.getStorage('jsrgfumou_forbid').includes(color)) return false; + if ( + color != "unsure" && + player.getStorage("jsrgfumou_forbid").includes(color) + ) + return false; }, - cardSavable:function(card,player){ + cardSavable: function (card, player) { const color = get.color(card); - if (color != 'unsure' && player.getStorage('jsrgfumou_forbid').includes(color)) return false; + if ( + color != "unsure" && + player.getStorage("jsrgfumou_forbid").includes(color) + ) + return false; }, }, - mark:true, - intro:{ - content:'本回合不能使用或打出$牌', + mark: true, + intro: { + content: "本回合不能使用或打出$牌", }, - } - } - }, - jsrgxuanfeng:{ - audio:2, - enable:'chooseToUse', - filterCard:{name:'ying'}, - position:'hs', - groupSkill:true, - locked:false, - viewAs:{ - name:'sha', - nature:'stab', - storage:{jsrgxuanfeng:true}, - }, - viewAsFilter(player){ - if(player.group!='shu') return false; - if(!player.countCards('hs','ying')) return false; - }, - prompt:'将一张【影】当无距离和次数限制的刺【杀】使用', - check(card){ - const val=get.value(card); - return 5-val; - }, - mod:{ - targetInRange:function(card,player,target){ - if(card.storage&&card.storage.jsrgxuanfeng) return true; }, - cardUsable:function(card){ - if(card.storage&&card.storage.jsrgxuanfeng) return Infinity; - } }, - ai:{ - order:2, - } + }, + jsrgxuanfeng: { + audio: 2, + enable: "chooseToUse", + filterCard: { name: "ying" }, + position: "hs", + groupSkill: true, + locked: false, + viewAs: { + name: "sha", + nature: "stab", + storage: { jsrgxuanfeng: true }, + }, + viewAsFilter(player) { + if (player.group != "shu") return false; + if (!player.countCards("hs", "ying")) return false; + }, + prompt: "将一张【影】当无距离和次数限制的刺【杀】使用", + check(card) { + const val = get.value(card); + return 5 - val; + }, + mod: { + targetInRange: function (card, player, target) { + if (card.storage && card.storage.jsrgxuanfeng) return true; + }, + cardUsable: function (card) { + if (card.storage && card.storage.jsrgxuanfeng) return Infinity; + }, + }, + ai: { + order: 2, + }, }, //陆逊 - jsrgyoujin:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(current=>{ + jsrgyoujin: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((current) => { return player.canCompare(current); }); }, - direct:true, - async content(event,trigger,player){ - const {result}=await player.chooseTarget(get.prompt2('jsrgyoujin'),(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',target=>{ - if(!get.event('goon')) return 0; - return -get.attitude(get.player(),target); - }).set('goon',player.countCards('hs',['shan','caochuan'])||player.getHp()>=3); - if(!result.bool) return; - const {targets}=result,target=targets[0]; - player.logSkill('jsrgyoujin',target); - const {result:result2}=await player.chooseToCompare(target).set('small',true); - player.addTempSkill('jsrgyoujin_forbid'); - player.markAuto('jsrgyoujin_forbid',[result2.num1]); - target.addTempSkill('jsrgyoujin_forbid'); - target.markAuto('jsrgyoujin_forbid',[result2.num2]); - if(!result2.tie){ - const targets=[target,player]; - if(result2.bool) targets.reverse(); - const sha=new lib.element.VCard({name:'sha'}); - if(targets[0].canUse(sha,targets[1],false)){ - targets[0].useCard(sha,targets[1],false); + direct: true, + async content(event, trigger, player) { + const { result } = await player + .chooseTarget(get.prompt2("jsrgyoujin"), (card, player, target) => { + return player.canCompare(target); + }) + .set("ai", (target) => { + if (!get.event("goon")) return 0; + return -get.attitude(get.player(), target); + }) + .set("goon", player.countCards("hs", ["shan", "caochuan"]) || player.getHp() >= 3); + if (!result.bool) return; + const { targets } = result, + target = targets[0]; + player.logSkill("jsrgyoujin", target); + const { result: result2 } = await player.chooseToCompare(target).set("small", true); + player.addTempSkill("jsrgyoujin_forbid"); + player.markAuto("jsrgyoujin_forbid", [result2.num1]); + target.addTempSkill("jsrgyoujin_forbid"); + target.markAuto("jsrgyoujin_forbid", [result2.num2]); + if (!result2.tie) { + const targets = [target, player]; + if (result2.bool) targets.reverse(); + const sha = new lib.element.VCard({ name: "sha" }); + if (targets[0].canUse(sha, targets[1], false)) { + targets[0].useCard(sha, targets[1], false); } } }, - subSkill:{ - forbid:{ - charlotte:true, - onremove:true, - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&player.getStorage('jsrgyoujin_forbid').some(num=>num>get.number(card))) return false; + subSkill: { + forbid: { + charlotte: true, + onremove: true, + mod: { + cardEnabled2: function (card, player) { + if ( + get.itemtype(card) == "card" && + player + .getStorage("jsrgyoujin_forbid") + .some((num) => num > get.number(card)) + ) + return false; }, }, - mark:true, - intro:{ - content:'本回合不能使用或打出点数小于$的手牌', + mark: true, + intro: { + content: "本回合不能使用或打出点数小于$的手牌", }, - } - } + }, + }, }, - jsrgdailao:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return !player.hasCard(card=>{ - return player.hasUseTarget(card,true,true); + jsrgdailao: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return !player.hasCard((card) => { + return player.hasUseTarget(card, true, true); }); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await player.showHandcards(); await player.draw(2); - const evt=event.getParent('phase'); - if(evt){ + const evt = event.getParent("phase"); + if (evt) { game.resetSkills(); - _status.event=evt; + _status.event = evt; _status.event.finish(); _status.event.untrigger(true); } }, - ai:{ - order:0.0001, - result:{player:1}, - } - }, - jsrgzhubei:{ - audio:2, - trigger:{source:'damageBegin1'}, - forced:true, - init(player){ - player.addSkill('jsrgzhubei_record'); + ai: { + order: 0.0001, + result: { player: 1 }, }, - filter(event,player){ - return event.player.hasHistory('damage',evt=>{ - return evt.source==player; + }, + jsrgzhubei: { + audio: 2, + trigger: { source: "damageBegin1" }, + forced: true, + init(player) { + player.addSkill("jsrgzhubei_record"); + }, + filter(event, player) { + return event.player.hasHistory("damage", (evt) => { + return evt.source == player; }); }, - logTarget:'player', - async content(event,trigger,player){ + logTarget: "player", + async content(event, trigger, player) { trigger.num++; }, - subSkill:{ - record:{ - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + record: { + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - charlotte:true, - silent:true, - filter(event,player){ - return game.hasPlayer(current=>{ - if(current.countCards('h')) return false; - const evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length; + charlotte: true, + silent: true, + filter(event, player) { + return game.hasPlayer((current) => { + if (current.countCards("h")) return false; + const evt = event.getl(current); + return evt && evt.hs && evt.hs.length; }); }, - async content(event,trigger,player){ - game.countPlayer(current=>{ - if(current.countCards('h')) return false; - const evt=trigger.getl(current); - if(evt&&evt.hs&&evt.hs.length) current.addTempSkill('jsrgzhubei_lost'); + async content(event, trigger, player) { + game.countPlayer((current) => { + if (current.countCards("h")) return false; + const evt = trigger.getl(current); + if (evt && evt.hs && evt.hs.length) current.addTempSkill("jsrgzhubei_lost"); }); }, }, - lost:{charlotte:true}, + lost: { charlotte: true }, }, - mod:{ - cardUsableTarget(card,player,target){ - if(target.hasSkill('jsrgzhubei_lost')) return true; + mod: { + cardUsableTarget(card, player, target) { + if (target.hasSkill("jsrgzhubei_lost")) return true; }, }, }, //赵云 - jsrglonglin:{ - audio:2, - trigger:{ - global:'useCardToPlayered', + jsrglonglin: { + audio: 2, + trigger: { + global: "useCardToPlayered", }, - usable:1, - filter(event,player){ - if(event.player==player) return false; - if(event.card.name!='sha') return false; - return event.isFirstTarget&&event.player.isPhaseUsing(); + usable: 1, + filter(event, player) { + if (event.player == player) return false; + if (event.card.name != "sha") return false; + return event.isFirstTarget && event.player.isPhaseUsing(); }, - direct:true, - async content(event,trigger,player){ - const juedou=new lib.element.VCard({name:'juedou',storage:{jsrglonglin:true}}); - const {result}=await player.chooseToDiscard(get.prompt2('jsrglonglin'),'he').set('ai',card=>{ - if(get.event('goon')) return 5-get.value(card); - return 0; - }).set('goon',(trigger.player.canUse(juedou,player)?Math.max(0,get.effect(player,juedou,trigger.player,trigger.player)):0)+trigger.targets.map(target=>{ - return get.effect(target,trigger.card,trigger.player,player); - }).reduce((p,c)=>{ - return p+c; - },0)<-4).set('logSkill',['jsrglonglin',trigger.player]); - if(result.bool){ + direct: true, + async content(event, trigger, player) { + const juedou = new lib.element.VCard({ name: "juedou", storage: { jsrglonglin: true } }); + const { result } = await player + .chooseToDiscard(get.prompt2("jsrglonglin"), "he") + .set("ai", (card) => { + if (get.event("goon")) return 5 - get.value(card); + return 0; + }) + .set( + "goon", + (trigger.player.canUse(juedou, player) + ? Math.max(0, get.effect(player, juedou, trigger.player, trigger.player)) + : 0) + + trigger.targets + .map((target) => { + return get.effect(target, trigger.card, trigger.player, player); + }) + .reduce((p, c) => { + return p + c; + }, 0) < + -4 + ) + .set("logSkill", ["jsrglonglin", trigger.player]); + if (result.bool) { trigger.excluded.addArray(trigger.targets); game.asyncDelayx(); - if(trigger.player.canUse(juedou,player)){ - const {result}=await trigger.player.chooseBool(`是否视为对${get.translation(player)}使用一张【决斗】?`).set('choice',get.effect(player,juedou,trigger.player,trigger.player)>=0); - if(result.bool){ - player.addTempSkill('jsrglonglin_source'); - trigger.player.useCard(juedou,player); + if (trigger.player.canUse(juedou, player)) { + const { result } = await trigger.player + .chooseBool(`是否视为对${get.translation(player)}使用一张【决斗】?`) + .set( + "choice", + get.effect(player, juedou, trigger.player, trigger.player) >= 0 + ); + if (result.bool) { + player.addTempSkill("jsrglonglin_source"); + trigger.player.useCard(juedou, player); } } } }, - subSkill:{ - source:{ - trigger:{source:'damageSource'}, - charlotte:true, - forced:true, - popup:false, - filter(event,player){ - return event.card&&event.card.storage&&event.card.storage.jsrglonglin; + subSkill: { + source: { + trigger: { source: "damageSource" }, + charlotte: true, + forced: true, + popup: false, + filter(event, player) { + return event.card && event.card.storage && event.card.storage.jsrglonglin; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.line(trigger.player); - trigger.player.addTempSkill('jsrglonglin_forbid'); - } + trigger.player.addTempSkill("jsrglonglin_forbid"); + }, }, - forbid:{ - mod:{ - cardEnabled:function(card,player){ - if(!card.cards) return; - if(card.cards.some(cardx=>get.position(cardx)=='h')) return false; + forbid: { + mod: { + cardEnabled: function (card, player) { + if (!card.cards) return; + if (card.cards.some((cardx) => get.position(cardx) == "h")) return false; }, - cardSavable:function(card,player){ - if(!card.cards) return; - if(card.cards.some(cardx=>get.position(cardx)=='h')) return false; + cardSavable: function (card, player) { + if (!card.cards) return; + if (card.cards.some((cardx) => get.position(cardx) == "h")) return false; }, }, - charlotte:true, - mark:true, - intro:{ - content:'不能使用手牌', + charlotte: true, + mark: true, + intro: { + content: "不能使用手牌", }, }, }, }, - jsrgzhendan:{ - audio:2, - trigger:{ - player:'damageEnd', - global:'roundStart', + jsrgzhendan: { + audio: 2, + trigger: { + player: "damageEnd", + global: "roundStart", }, - filter(event,player){ - let count=0; - let roundCount=1+(event.name!='damage'); - const curLen=player.actionHistory.length; - for(let i=curLen-1;i>=0;i--){ - if(roundCount==1&&game.hasPlayer(current=>{ - const history=current.actionHistory[i]; - if(!history.isMe||history.isSkipped) return false; - return true; - })){ + filter(event, player) { + let count = 0; + let roundCount = 1 + (event.name != "damage"); + const curLen = player.actionHistory.length; + for (let i = curLen - 1; i >= 0; i--) { + if ( + roundCount == 1 && + game.hasPlayer((current) => { + const history = current.actionHistory[i]; + if (!history.isMe || history.isSkipped) return false; + return true; + }) + ) { count++; } - if(player.actionHistory[i].isRound) roundCount--; - if(roundCount<=0) break; + if (player.actionHistory[i].isRound) roundCount--; + if (roundCount <= 0) break; } - if(!player.storage.jsrgzhendan_mark&&count>0) return true; + if (!player.storage.jsrgzhendan_mark && count > 0) return true; return false; }, - forced:true, - locked:false, - group:'jsrgzhendan_viewas', - async content(event,trigger,player){ - let count=0; - let roundCount=1+(trigger.name!='damage'); - const curLen=player.actionHistory.length; - for(let i=curLen-1;i>=0;i--){ - if(roundCount==1&&game.hasPlayer(current=>{ - const history=current.actionHistory[i]; - if(!history.isMe||history.isSkipped) return false; - return true; - })){ + forced: true, + locked: false, + group: "jsrgzhendan_viewas", + async content(event, trigger, player) { + let count = 0; + let roundCount = 1 + (trigger.name != "damage"); + const curLen = player.actionHistory.length; + for (let i = curLen - 1; i >= 0; i--) { + if ( + roundCount == 1 && + game.hasPlayer((current) => { + const history = current.actionHistory[i]; + if (!history.isMe || history.isSkipped) return false; + return true; + }) + ) { count++; } - if(player.actionHistory[i].isRound) roundCount--; - if(roundCount<=0) break; + if (player.actionHistory[i].isRound) roundCount--; + if (roundCount <= 0) break; } - count=Math.min(5,count); + count = Math.min(5, count); await player.draw(count); - if(trigger.name=='damage'){ - player.tempBanSkill('jsrgzhendan','roundStart'); - player.storage.jsrgzhendan_mark=true; - player.when({global:'roundStart'}).assign({ - lastDo:true, - }).then(()=>{ - delete player.storage.jsrgzhendan_mark; - }); + if (trigger.name == "damage") { + player.tempBanSkill("jsrgzhendan", "roundStart"); + player.storage.jsrgzhendan_mark = true; + player + .when({ global: "roundStart" }) + .assign({ + lastDo: true, + }) + .then(() => { + delete player.storage.jsrgzhendan_mark; + }); } }, - subSkill:{ - viewas:{ - audio:'jsrgzhendan', - enable:['chooseToUse','chooseToRespond'], - filter(event,player){ - if(event.type=='wuxie') return false; - if(!_status.connectMode&&!player.countCards('hs',card=>{ - return get.type2(card)!='basic'; - })) return false; - return get.inpileVCardList(info=>{ - if(info[0]!='basic') return false; - return event.filterCard(get.autoViewAs({name:info[2],nature:info[3]},'unsure'),player,event); + subSkill: { + viewas: { + audio: "jsrgzhendan", + enable: ["chooseToUse", "chooseToRespond"], + filter(event, player) { + if (event.type == "wuxie") return false; + if ( + !_status.connectMode && + !player.countCards("hs", (card) => { + return get.type2(card) != "basic"; + }) + ) + return false; + return get.inpileVCardList((info) => { + if (info[0] != "basic") return false; + return event.filterCard( + get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), + player, + event + ); }).length; }, - chooseButton:{ - dialog(event,player){ - const vcards=get.inpileVCardList(info=>{ - if(info[0]!='basic') return false; - return event.filterCard(get.autoViewAs({name:info[2],nature:info[3]},'unsure'),player,event); + chooseButton: { + dialog(event, player) { + const vcards = get.inpileVCardList((info) => { + if (info[0] != "basic") return false; + return event.filterCard( + get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), + player, + event + ); }); - return ui.create.dialog('镇胆',[vcards,'vcard']); + return ui.create.dialog("镇胆", [vcards, "vcard"]); }, - check(button){ - if(get.event().getParent().type!='phase') return 1; - return get.player().getUseValue({name:button.link[2],nature:button.link[3]}); + check(button) { + if (get.event().getParent().type != "phase") return 1; + return get + .player() + .getUseValue({ name: button.link[2], nature: button.link[3] }); }, - backup(links,player){ + backup(links, player) { return { - audio:'jsrgzhendan', - popname:true, - viewAs:{name:links[0][2],nature:links[0][3]}, - filterCard(card,player){ - return get.type2(card)!='basic'; + audio: "jsrgzhendan", + popname: true, + viewAs: { name: links[0][2], nature: links[0][3] }, + filterCard(card, player) { + return get.type2(card) != "basic"; }, - selectCard:1, - position:'hs', - } + selectCard: 1, + position: "hs", + }; }, - prompt(links,player){ - return '将一张非基本手牌当'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用或打出'; - } - }, - hiddenCard(player,name){ - return get.type(name)=='basic'&&player.countCards('hs')>0; - }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter(player){ - return player.countCards('hs')>0; + prompt(links, player) { + return ( + "将一张非基本手牌当" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用或打出" + ); }, - order:0.5, - result:{ - player(player){ - if(get.event().dying){ - return get.attitude(player,get.event().dying); + }, + hiddenCard(player, name) { + return get.type(name) == "basic" && player.countCards("hs") > 0; + }, + ai: { + respondSha: true, + respondShan: true, + skillTagFilter(player) { + return player.countCards("hs") > 0; + }, + order: 0.5, + result: { + player(player) { + if (get.event().dying) { + return get.attitude(player, get.event().dying); } return 1; }, }, }, }, - viewas_backup:{}, - } + viewas_backup: {}, + }, }, //司马懿 - jsrgyingshi:{ - audio:2, - trigger:{player:'turnOverAfter'}, - async content(event,trigger,player){ - const number=(game.dead.length>2)?5:3; - const cards=get.bottomCards(number); + jsrgyingshi: { + audio: 2, + trigger: { player: "turnOverAfter" }, + async content(event, trigger, player) { + const number = game.dead.length > 2 ? 5 : 3; + const cards = get.bottomCards(number); game.cardsGotoOrdering(cards); - const next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶'], - ['牌堆底',cards.reverse()], - ]); - next.set('prompt','鹰眎:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=list=>{ - const cards=list[1][1],player=_status.event.player; - const top=[]; - const judges=player.getCards('j'); - let stopped=false; - if(!player.hasWuxie()){ - for(let i=0;ijudge(b)-judge(a)); - if(judge(cards[0])<0){ - stopped=true;break; - } - else{ + const next = player.chooseToMove(); + next.set("list", [["牌堆顶"], ["牌堆底", cards.reverse()]]); + next.set("prompt", "鹰眎:点击将牌移动到牌堆顶或牌堆底"); + next.processAI = (list) => { + const cards = list[1][1], + player = _status.event.player; + const top = []; + const judges = player.getCards("j"); + let stopped = false; + if (!player.hasWuxie()) { + for (let i = 0; i < judges.length; i++) { + const judge = get.judge(judges[i]); + cards.sort((a, b) => judge(b) - judge(a)); + if (judge(cards[0]) < 0) { + stopped = true; + break; + } else { top.unshift(cards.shift()); } } } let bottom; - if(!stopped){ - cards.sort((a,b)=>get.value(b,player)-get.value(a,player)); - while(cards.length){ - if(get.value(cards[0],player)<=5) break; + if (!stopped) { + cards.sort((a, b) => get.value(b, player) - get.value(a, player)); + while (cards.length) { + if (get.value(cards[0], player) <= 5) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - const {result:{moved}}=await next; - const top=moved[0]; - const bottom=moved[1]; + bottom = cards; + return [top, bottom]; + }; + const { + result: { moved }, + } = await next; + const top = moved[0]; + const bottom = moved[1]; top.reverse(); - game.cardsGotoPile( - top.concat(bottom), - ['top_cards',top], - (event,card)=>{ - if(event.top_cards.includes(card)) return ui.cardPile.firstChild; - return null; - } - ); - player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); - game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶'); + game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => { + if (event.top_cards.includes(card)) return ui.cardPile.firstChild; + return null; + }); + player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下"); + game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶"); game.asyncDelayx(); }, }, - jsrgtuigu:{ - audio:2, - trigger:{player:'phaseBegin'}, - prompt2(event,player){ - const num=Math.floor(game.countPlayer()/2); - return `你翻面,令你本回合的手牌上限+${num},摸${get.cnNumber(num)}张牌,视为使用一张【解甲归田】(目标角色不能使用这些牌直到其下回合结束)。`; + jsrgtuigu: { + audio: 2, + trigger: { player: "phaseBegin" }, + prompt2(event, player) { + const num = Math.floor(game.countPlayer() / 2); + return `你翻面,令你本回合的手牌上限+${num},摸${get.cnNumber( + num + )}张牌,视为使用一张【解甲归田】(目标角色不能使用这些牌直到其下回合结束)。`; }, - group:['jsrgtuigu_insert','jsrgtuigu_recover'], - async content(event,trigger,player){ + group: ["jsrgtuigu_insert", "jsrgtuigu_recover"], + async content(event, trigger, player) { await player.turnOver(); - const num=Math.floor(game.countPlayer()/2); - player.addTempSkill('jsrgtuigu_handcard'); - player.addMark('jsrgtuigu_handcard',num,false); + const num = Math.floor(game.countPlayer() / 2); + player.addTempSkill("jsrgtuigu_handcard"); + player.addMark("jsrgtuigu_handcard", num, false); await player.draw(num); - const jiejia=new lib.element.VCard({name:'jiejia',storage:{jsrgtuigu:true}}); - if(player.hasUseTarget(jiejia)){ - player.addTempSkill('jsrgtuigu_block'); - player.chooseUseTarget(jiejia,true); + const jiejia = new lib.element.VCard({ name: "jiejia", storage: { jsrgtuigu: true } }); + if (player.hasUseTarget(jiejia)) { + player.addTempSkill("jsrgtuigu_block"); + player.chooseUseTarget(jiejia, true); } }, - subSkill:{ - insert:{ - audio:'jsrgtuigu', - trigger:{global:'roundStart'}, - filter(event,player){ - const curLen=player.actionHistory.length; - if(curLen<=2) return false; - for(let i=curLen-2;i>=0;i--){ - const history=player.actionHistory[i]; - if(history.isMe&&!history.isSkipped&&!history._jsrgtuigu) return false; - if(history.isRound) break; + subSkill: { + insert: { + audio: "jsrgtuigu", + trigger: { global: "roundStart" }, + filter(event, player) { + const curLen = player.actionHistory.length; + if (curLen <= 2) return false; + for (let i = curLen - 2; i >= 0; i--) { + const history = player.actionHistory[i]; + if (history.isMe && !history.isSkipped && !history._jsrgtuigu) return false; + if (history.isRound) break; } return true; }, - forced:true, - locked:false, - async content(event,trigger,player){ - const evt=trigger,evtx=player.insertPhase(); - player.when('phaseBeforeStart') - .filter(evtt=>evtt==evtx) - .then(()=>{ - game.players.slice().concat(game.dead).forEach(current=>{ - current.getHistory()._jsrgtuigu=true; - current.getStat()._jsrgtuigu=true; + forced: true, + locked: false, + async content(event, trigger, player) { + const evt = trigger, + evtx = player.insertPhase(); + player + .when("phaseBeforeStart") + .filter((evtt) => evtt == evtx) + .then(() => { + game.players + .slice() + .concat(game.dead) + .forEach((current) => { + current.getHistory()._jsrgtuigu = true; + current.getStat()._jsrgtuigu = true; + }); }); - }); - if(evt.player!=player&&!evt._finished){ + if (evt.player != player && !evt._finished) { evt.finish(); - evt._triggered=5; - const evtxx=evt.player.insertPhase(); + evt._triggered = 5; + const evtxx = evt.player.insertPhase(); delete evtxx.skill; } }, }, - recover:{ - audio:'jsrgtuigu', - trigger:{ - player:'loseAfter', - global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'], + recover: { + audio: "jsrgtuigu", + trigger: { + player: "loseAfter", + global: [ + "gainAfter", + "equipAfter", + "addJudgeAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - if(player.isHealthy()) return false; - const evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + filter(event, player) { + if (player.isHealthy()) return false; + const evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; }, - forced:true, - locked:false, - async content(event,trigger,player){ + forced: true, + locked: false, + async content(event, trigger, player) { player.recover(); - } - }, - handcard:{ - markimage:'image/card/handcard.png', - intro:{ - content(storage,player){ - return '手牌上限+'+storage; - } - }, - onremove:true, - charlotte:true, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('jsrgtuigu_handcard'); - } }, }, - block:{ - trigger:{global:'gainAfter'}, - filter(event,player){ - if(event.getParent().name!='jiejia') return false; - const card=event.getParent(2).card; - if(card&&card.storage&&card.storage.jsrgtuigu) return true; + handcard: { + markimage: "image/card/handcard.png", + intro: { + content(storage, player) { + return "手牌上限+" + storage; + }, + }, + onremove: true, + charlotte: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("jsrgtuigu_handcard"); + }, + }, + }, + block: { + trigger: { global: "gainAfter" }, + filter(event, player) { + if (event.getParent().name != "jiejia") return false; + const card = event.getParent(2).card; + if (card && card.storage && card.storage.jsrgtuigu) return true; return false; }, - charlotte:true, - forced:true, - silent:true, - content(){ - trigger.player.addGaintag(trigger.cards,'jsrgtuigu'); - trigger.player.addTempSkill('jsrgtuigu_blocked',{player:'phaseAfter'}); - } + charlotte: true, + forced: true, + silent: true, + content() { + trigger.player.addGaintag(trigger.cards, "jsrgtuigu"); + trigger.player.addTempSkill("jsrgtuigu_blocked", { player: "phaseAfter" }); + }, }, - blocked:{ - mod:{ - cardEnabled2(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('jsrgtuigu')) return false; + blocked: { + mod: { + cardEnabled2(card) { + if (get.itemtype(card) == "card" && card.hasGaintag("jsrgtuigu")) + return false; }, }, - charlotte:true, - forced:true, - popup:false, - onremove(player){ - player.removeGaintag('jsrgtuigu'); + charlotte: true, + forced: true, + popup: false, + onremove(player) { + player.removeGaintag("jsrgtuigu"); }, }, - } + }, }, //郭循 - jsrgeqian:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget||event.targets.length!=1||event.target==player) return false; - if(event.card.name=='sha') return true; - return event.getParent(3).name=='xumou_jsrg'; + jsrgeqian: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget || event.targets.length != 1 || event.target == player) + return false; + if (event.card.name == "sha") return true; + return event.getParent(3).name == "xumou_jsrg"; }, - prompt2(event,player){ - return `令${get.translation(event.card)}不计入次数限制,且你获得${get.translation(event.target)}一张牌,然后其可以令你本回合至其的距离+2`; + prompt2(event, player) { + return `令${get.translation(event.card)}不计入次数限制,且你获得${get.translation( + event.target + )}一张牌,然后其可以令你本回合至其的距离+2`; }, - group:'jsrgeqian_prepare', - logTarget:'target', - async content(event,trigger,player){ - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + group: "jsrgeqian_prepare", + logTarget: "target", + async content(event, trigger, player) { + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; } - await player.gainPlayerCard(trigger.target,'he',true); - const {result:{bool}}=await trigger.target.chooseBool(`是否令${get.translation(player)}至你的距离于本回合内+2?`).set('ai',()=>true); - if(bool){ - player.addTempSkill('jsrgeqian_distance'); - if(!player.storage.jsrgeqian_distance) player.storage.jsrgeqian_distance={}; - const id=trigger.target.playerid; - if(typeof player.storage.jsrgeqian_distance[id]!='number') player.storage.jsrgeqian_distance[id]=0; - player.storage.jsrgeqian_distance[id]+=2; - player.markSkill('jsrgeqian_distance'); + await player.gainPlayerCard(trigger.target, "he", true); + const { + result: { bool }, + } = await trigger.target + .chooseBool(`是否令${get.translation(player)}至你的距离于本回合内+2?`) + .set("ai", () => true); + if (bool) { + player.addTempSkill("jsrgeqian_distance"); + if (!player.storage.jsrgeqian_distance) player.storage.jsrgeqian_distance = {}; + const id = trigger.target.playerid; + if (typeof player.storage.jsrgeqian_distance[id] != "number") + player.storage.jsrgeqian_distance[id] = 0; + player.storage.jsrgeqian_distance[id] += 2; + player.markSkill("jsrgeqian_distance"); } }, - subSkill:{ - prepare:{ - audio:'jsrgeqian', - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.countCards('h'); + subSkill: { + prepare: { + audio: "jsrgeqian", + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return player.countCards("h"); }, - direct:true, - async content(event,trigger,player){ - while(player.countCards('h')>0){ - const {result:{bool,cards}}=await player.chooseCard(get.prompt('jsrgeqian'),'你可以蓄谋任意次').set('ai',card=>{ - const player=get.player(); - if(player.hasValueTarget(card)) return player.getUseValue(card); - return 0; - }); - if(!bool) break; - await player.addJudge({name:'xumou_jsrg'},cards); + direct: true, + async content(event, trigger, player) { + while (player.countCards("h") > 0) { + const { + result: { bool, cards }, + } = await player + .chooseCard(get.prompt("jsrgeqian"), "你可以蓄谋任意次") + .set("ai", (card) => { + const player = get.player(); + if (player.hasValueTarget(card)) return player.getUseValue(card); + return 0; + }); + if (!bool) break; + await player.addJudge({ name: "xumou_jsrg" }, cards); } }, }, - distance:{ - onremove:true, - charlotte:true, - mod:{ - globalFrom(player,target,distance){ - if(!player.storage.jsrgeqian_distance) return; - const dis=player.storage.jsrgeqian_distance[target.playerid]; - if(typeof dis=='number') return distance+dis; + distance: { + onremove: true, + charlotte: true, + mod: { + globalFrom(player, target, distance) { + if (!player.storage.jsrgeqian_distance) return; + const dis = player.storage.jsrgeqian_distance[target.playerid]; + if (typeof dis == "number") return distance + dis; }, }, - intro:{ - content(storage,player){ - if(!storage) return; - const map=(_status.connectMode?lib.playerOL:game.playerMap); - let str=`你本回合:`; - for(const id in storage){ - str+='
            • 至'+get.translation(map[id])+'的距离+'+storage[id]; + intro: { + content(storage, player) { + if (!storage) return; + const map = _status.connectMode ? lib.playerOL : game.playerMap; + let str = `你本回合:`; + for (const id in storage) { + str += "
            • 至" + get.translation(map[id]) + "的距离+" + storage[id]; } return str; - } - } + }, + }, }, - } - }, - jsrgfusha:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'fire', - filter(event,player){ - return game.countPlayer(current=>{ - return player.inRange(current); - })==1; }, - filterTarget(card,player,target){ + }, + jsrgfusha: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "fire", + filter(event, player) { + return ( + game.countPlayer((current) => { + return player.inRange(current); + }) == 1 + ); + }, + filterTarget(card, player, target) { return player.inRange(target); }, - selectTarget:-1, - async content(event,trigger,player){ - player.awakenSkill('jsrgfusha'); - event.target.damage(Math.min(game.countPlayer(),player.getAttackRange())); + selectTarget: -1, + async content(event, trigger, player) { + player.awakenSkill("jsrgfusha"); + event.target.damage(Math.min(game.countPlayer(), player.getAttackRange())); }, - ai:{ - order:1, - result:{ - target:-2, + ai: { + order: 1, + result: { + target: -2, }, }, }, //大小虎 - jsrgdaimou:{ - audio:2, - trigger:{ - global:'useCardToPlayer', + jsrgdaimou: { + audio: 2, + trigger: { + global: "useCardToPlayer", }, - filter(event,player){ - if(event.card.name!='sha') return false; - if(event.target!=player) return !player.hasSkill('jsrgdaimou_other'); - return !player.hasSkill('jsrgdaimou_me')&&player.hasCard(card=>{ - return (card.viewAs||card.name)=='xumou_jsrg'&&lib.filter.cardDiscardable(card,player,'jsrgdaimou'); - },'j'); + filter(event, player) { + if (event.card.name != "sha") return false; + if (event.target != player) return !player.hasSkill("jsrgdaimou_other"); + return ( + !player.hasSkill("jsrgdaimou_me") && + player.hasCard((card) => { + return ( + (card.viewAs || card.name) == "xumou_jsrg" && + lib.filter.cardDiscardable(card, player, "jsrgdaimou") + ); + }, "j") + ); }, - direct:true, - async content(event,trigger,player){ - if(trigger.target==player){ - player.logSkill('jsrgdaimou'); - player.addTempSkill('jsrgdaimou_me'); - const {result:{bool,links}}=await player.chooseButton([ - '殆谋:请弃置区域里的一张蓄谋牌', - player.getCards('j',card=>{ - return (card.viewAs||card.name)=='xumou_jsrg'; + direct: true, + async content(event, trigger, player) { + if (trigger.target == player) { + player.logSkill("jsrgdaimou"); + player.addTempSkill("jsrgdaimou_me"); + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + "殆谋:请弃置区域里的一张蓄谋牌", + player.getCards("j", (card) => { + return (card.viewAs || card.name) == "xumou_jsrg"; + }), + ], + true + ) + .set("filterButton", (button) => { + return lib.filter.cardDiscardable(button.link, get.player(), "jsrgdaimou"); }) - ],true).set('filterButton',button=>{ - return lib.filter.cardDiscardable(button.link,get.player(),'jsrgdaimou'); - }).set('ai',button=>{ - const player=get.player(); - return 1/Math.max(0.01,player.getUseValue(button.link)); - }); - if(bool){ + .set("ai", (button) => { + const player = get.player(); + return 1 / Math.max(0.01, player.getUseValue(button.link)); + }); + if (bool) { player.discard(links); } - } - else{ - const {result:{bool}}=await player.chooseBool(get.prompt('jsrgdaimou'),'你可以用牌堆顶的牌蓄谋').set('ai',()=>true); - if(bool){ - player.logSkill('jsrgdaimou'); - player.addTempSkill('jsrgdaimou_other'); - player.addJudge({name:'xumou_jsrg'},get.cards()); + } else { + const { + result: { bool }, + } = await player + .chooseBool(get.prompt("jsrgdaimou"), "你可以用牌堆顶的牌蓄谋") + .set("ai", () => true); + if (bool) { + player.logSkill("jsrgdaimou"); + player.addTempSkill("jsrgdaimou_other"); + player.addJudge({ name: "xumou_jsrg" }, get.cards()); } } }, - subSkill:{ - me:{charlotte:true}, - other:{charlotte:true}, + subSkill: { + me: { charlotte: true }, + other: { charlotte: true }, }, }, - jsrgfangjie:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - async content(event,trigger,player){ - if(!player.hasCard(card=>{ - return (card.viewAs||card.name)=='xumou_jsrg'; - },'j')){ - player.logSkill('jsrgfangjie'); + jsrgfangjie: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + async content(event, trigger, player) { + if ( + !player.hasCard((card) => { + return (card.viewAs || card.name) == "xumou_jsrg"; + }, "j") + ) { + player.logSkill("jsrgfangjie"); await player.recover(); await player.draw(); - } - else{ - const {result:{bool,links}}=await player.chooseButton([ - '是否弃置区域里的任意张蓄谋牌并失去〖芳洁〗?', - player.getCards('j',card=>{ - return (card.viewAs||card.name)=='xumou_jsrg'; + } else { + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + "是否弃置区域里的任意张蓄谋牌并失去〖芳洁〗?", + player.getCards("j", (card) => { + return (card.viewAs || card.name) == "xumou_jsrg"; + }), + ], + [1, Infinity] + ) + .set("filterButton", (button) => { + return lib.filter.cardDiscardable(button.link, get.player(), "jsrgdaimou"); }) - ],[1,Infinity]).set('filterButton',button=>{ - return lib.filter.cardDiscardable(button.link,get.player(),'jsrgdaimou'); - }).set('ai',()=>0); - if(bool){ - player.logSkill('jsrgfangjie'); + .set("ai", () => 0); + if (bool) { + player.logSkill("jsrgfangjie"); await player.discard(links); - player.removeSkills('jsrgfangjie'); + player.removeSkills("jsrgfangjie"); } } }, }, //曹芳 - jsrgzhaotu:{ - audio:2, - enable:'chooseToUse', - viewAs:{name:'lebu'}, - position:'hes', - round:1, - viewAsFilter(player){ - return player.countCards('hes'); + jsrgzhaotu: { + audio: 2, + enable: "chooseToUse", + viewAs: { name: "lebu" }, + position: "hes", + round: 1, + viewAsFilter(player) { + return player.countCards("hes"); }, - filterCard(card,player){ - return get.color(card)=='red'&&get.type2(card)!='trick'; + filterCard(card, player) { + return get.color(card) == "red" && get.type2(card) != "trick"; }, - onuse(result,player){ - player.tempBanSkill('jsrgzhaotu',null,false); + onuse(result, player) { + player.tempBanSkill("jsrgzhaotu", null, false); result.targets[0].insertPhase(); - result.targets[0].addTempSkill('jsrgzhaotu_handcard',{player:'phaseAfter'}); - result.targets[0].addMark('jsrgzhaotu_handcard',2,false); + result.targets[0].addTempSkill("jsrgzhaotu_handcard", { player: "phaseAfter" }); + result.targets[0].addMark("jsrgzhaotu_handcard", 2, false); }, - subSkill:{ - handcard:{ - intro:{ - content(storage,player){ - return '手牌上限-'+storage; - } + subSkill: { + handcard: { + intro: { + content(storage, player) { + return "手牌上限-" + storage; + }, }, - charlotte:true, - onremove:true, - mod:{ - maxHandcard(player,num){ - return num-player.countMark('jsrgzhaotu_handcard'); - } + charlotte: true, + onremove: true, + mod: { + maxHandcard(player, num) { + return num - player.countMark("jsrgzhaotu_handcard"); + }, }, }, }, - ai:{ - order:5, - result:{ - target(player,target){ - let dis=0.5-0.75*target.needsToDiscard(2,null,true); - if(dis>0) return dis; - if(player.hasSkill('jsrgjingju')&&player.hasZhuSkill('jsrgweizhui')&&get.attitude(player,target)>0) return game.countPlayer(current=>{ - if(current===player||current===target||current.group!=='wei') return false; - return player.hasZhuSkill('jsrgweizhui',current)&&get.attitude(player,current)>0; - }); + ai: { + order: 5, + result: { + target(player, target) { + let dis = 0.5 - 0.75 * target.needsToDiscard(2, null, true); + if (dis > 0) return dis; + if ( + player.hasSkill("jsrgjingju") && + player.hasZhuSkill("jsrgweizhui") && + get.attitude(player, target) > 0 + ) + return game.countPlayer((current) => { + if (current === player || current === target || current.group !== "wei") + return false; + return ( + player.hasZhuSkill("jsrgweizhui", current) && + get.attitude(player, current) > 0 + ); + }); return dis; }, }, }, }, - jsrgjingju:{ - audio:2, - enable:'chooseToUse', - filter(event,player){ - if(event.type=='wuxie'||event.jsrgjingju) return false; - if(!player.canMoveCard(null,false,game.filterPlayer(i=>i!=player),player,card=>{ - return get.position(card)=='j'; - })) return false; - return get.inpileVCardList(info=>{ - if(info[0]!='basic') return false; - return event.filterCard(get.autoViewAs({name:info[2],nature:info[3]},'unsure'),player,event); + jsrgjingju: { + audio: 2, + enable: "chooseToUse", + filter(event, player) { + if (event.type == "wuxie" || event.jsrgjingju) return false; + if ( + !player.canMoveCard( + null, + false, + game.filterPlayer((i) => i != player), + player, + (card) => { + return get.position(card) == "j"; + } + ) + ) + return false; + return get.inpileVCardList((info) => { + if (info[0] != "basic") return false; + return event.filterCard( + get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), + player, + event + ); }).length; }, - chooseButton:{ - dialog:function(event,player){ - const vcards=get.inpileVCardList(info=>{ - if(info[0]!='basic') return false; - return event.filterCard(get.autoViewAs({name:info[2],nature:info[3]},'unsure'),player,event); + chooseButton: { + dialog: function (event, player) { + const vcards = get.inpileVCardList((info) => { + if (info[0] != "basic") return false; + return event.filterCard( + get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), + player, + event + ); }); - return ui.create.dialog('惊惧',[vcards,'vcard'],'hidden'); + return ui.create.dialog("惊惧", [vcards, "vcard"], "hidden"); }, - check:function(button){ - let player=_status.event.player; - if(get.event().getParent().type!='phase') return 1; - return get.player().getUseValue({name:button.link[2],nature:button.link[3]})+game.countPlayer(current=>{ - if(current===player||current.group!=='wei') return false; - return player.hasZhuSkill('jsrgweizhui',current)&&get.attitude(player,current)>0; - }); + check: function (button) { + let player = _status.event.player; + if (get.event().getParent().type != "phase") return 1; + return ( + get.player().getUseValue({ name: button.link[2], nature: button.link[3] }) + + game.countPlayer((current) => { + if (current === player || current.group !== "wei") return false; + return ( + player.hasZhuSkill("jsrgweizhui", current) && + get.attitude(player, current) > 0 + ); + }) + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:()=>false, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + filterCard: () => false, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, }, - selectCard:-1, - precontent(){ - 'step 0' - player.moveCard(`惊惧:将其他角色判定区里的牌移动至你的判定区`,game.filterPlayer(i=>i!=player),player,card=>{ - return get.position(card)=='j'; - }).set('logSkill','jsrgjingju'); - 'step 1' - if(result.bool){ + selectCard: -1, + precontent() { + "step 0"; + player + .moveCard( + `惊惧:将其他角色判定区里的牌移动至你的判定区`, + game.filterPlayer((i) => i != player), + player, + (card) => { + return get.position(card) == "j"; + } + ) + .set("logSkill", "jsrgjingju"); + "step 1"; + if (result.bool) { delete event.result.skill; - } - else{ - event.getParent().jsrgjingju=true; + } else { + event.getParent().jsrgjingju = true; event.getParent().goto(0); delete event.getParent().openskilldialog; event.finish(); } - 'step 2' + "step 2"; game.delayx(); }, - } + }; + }, + prompt: function (links, player) { + return ( + "选择" + + get.translation(links[0][3] || "") + + "【" + + get.translation(links[0][2]) + + "】的目标" + ); }, - prompt:function(links,player){ - return '选择'+get.translation(links[0][3]||'')+'【'+get.translation(links[0][2])+'】的目标'; - } }, - ai:{ - order:function(){ - const player=get.player(),event=_status.event; - if(player.canMoveCard(null,false,game.filterPlayer(),player,card=>{ - return get.position(card)=='j'; - })){ - if(event.type=='dying'){ - if(event.filterCard({name:'tao'},player,event)){ + ai: { + order: function () { + const player = get.player(), + event = _status.event; + if ( + player.canMoveCard(null, false, game.filterPlayer(), player, (card) => { + return get.position(card) == "j"; + }) + ) { + if (event.type == "dying") { + if (event.filterCard({ name: "tao" }, player, event)) { return 0.5; } - } - else{ - if(event.filterCard({name:'tao'},player,event)||event.filterCard({name:'shan'},player,event)){ + } else { + if ( + event.filterCard({ name: "tao" }, player, event) || + event.filterCard({ name: "shan" }, player, event) + ) { return 4; } - if(event.filterCard({name:'sha'},player,event)){ + if (event.filterCard({ name: "sha" }, player, event)) { return 2.9; } } } return 0; }, - save:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - return player.canMoveCard(null,false,game.filterPlayer(),player,card=>{ - return get.position(card)=='j'; - }) + save: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + return player.canMoveCard(null, false, game.filterPlayer(), player, (card) => { + return get.position(card) == "j"; + }); }, - result:{ - player:function(player){ - if(get.event().type=='dying'){ - return get.attitude(player,get.event().dying); + result: { + player: function (player) { + if (get.event().type == "dying") { + return get.attitude(player, get.event().dying); } return 1; - } - } - } - }, - jsrgweizhui:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - zhuSkill:true, - direct:true, - filter(event,player){ - return player!=event.player&&event.player.group=='wei'&&event.player.isIn()&&player.hasZhuSkill('jsrgweizhui',event.player); + }, + }, }, - async content(event,trigger,player){ - const {result:{bool,cards}}=await trigger.player.chooseCard(`是否响应${get.translation(player)}的主公技【危坠】?`,'将一张黑色手牌当【过河拆桥】对其使用',(card,player)=>{ - if(get.color(card)!='black') return false; - return player.canUse(get.autoViewAs({name:'guohe'},[card]),get.event('target')); - }).set('target',player).set('ai',card=>{ - if(get.effect(get.event('target'),get.autoViewAs({name:'guohe'},[card]),player)<=0) return 0; - return 7-get.value(card); - }); - if(bool){ - trigger.player.logSkill('jsrgweizhui',player); - trigger.player.useCard(get.autoViewAs({name:'guohe'},cards),cards,player); + }, + jsrgweizhui: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + zhuSkill: true, + direct: true, + filter(event, player) { + return ( + player != event.player && + event.player.group == "wei" && + event.player.isIn() && + player.hasZhuSkill("jsrgweizhui", event.player) + ); + }, + async content(event, trigger, player) { + const { + result: { bool, cards }, + } = await trigger.player + .chooseCard( + `是否响应${get.translation(player)}的主公技【危坠】?`, + "将一张黑色手牌当【过河拆桥】对其使用", + (card, player) => { + if (get.color(card) != "black") return false; + return player.canUse( + get.autoViewAs({ name: "guohe" }, [card]), + get.event("target") + ); + } + ) + .set("target", player) + .set("ai", (card) => { + if ( + get.effect( + get.event("target"), + get.autoViewAs({ name: "guohe" }, [card]), + player + ) <= 0 + ) + return 0; + return 7 - get.value(card); + }); + if (bool) { + trigger.player.logSkill("jsrgweizhui", player); + trigger.player.useCard(get.autoViewAs({ name: "guohe" }, cards), cards, player); } }, }, //孙峻 - jsrgyaoyan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - prompt:'是否发动【邀宴】?', - logTarget:()=>game.filterPlayer(), - async content(event,trigger,player){ - const targets=game.filterPlayer(); - const toDebateList=[]; - while(targets.length){ - const current=targets.shift(); - const {result:{bool}}=await current.chooseBool(`是否响应${get.translation(player)}的【邀宴】,于回合结束参与议事?`).set('ai',()=>Math.random()<0.5); - if(bool){ + jsrgyaoyan: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + prompt: "是否发动【邀宴】?", + logTarget: () => game.filterPlayer(), + async content(event, trigger, player) { + const targets = game.filterPlayer(); + const toDebateList = []; + while (targets.length) { + const current = targets.shift(); + const { + result: { bool }, + } = await current + .chooseBool(`是否响应${get.translation(player)}的【邀宴】,于回合结束参与议事?`) + .set("ai", () => Math.random() < 0.5); + if (bool) { toDebateList.add(current); - current.popup('同意','wood'); - game.log(current,'#g同意','参加',player,'的议事'); - } - else{ - current.popup('拒绝','fire'); - game.log(current,'#r拒绝','参加',player,'的议事'); + current.popup("同意", "wood"); + game.log(current, "#g同意", "参加", player, "的议事"); + } else { + current.popup("拒绝", "fire"); + game.log(current, "#r拒绝", "参加", player, "的议事"); } } - if(toDebateList.length){ - player.addTempSkill('jsrgyaoyan_hold'); - player.markAuto('jsrgyaoyan_hold',toDebateList); + if (toDebateList.length) { + player.addTempSkill("jsrgyaoyan_hold"); + player.markAuto("jsrgyaoyan_hold", toDebateList); } }, - subSkill:{ - hold:{ - trigger:{player:'phaseEnd'}, - charlotte:true, - forced:true, - popup:false, - onremove:true, - filter(event,player){ - return player.getStorage('jsrgyaoyan_hold').some(i=>i.isIn()); + subSkill: { + hold: { + trigger: { player: "phaseEnd" }, + charlotte: true, + forced: true, + popup: false, + onremove: true, + filter(event, player) { + return player.getStorage("jsrgyaoyan_hold").some((i) => i.isIn()); }, - async content(event,trigger,player){ - player.chooseToDebate(player.getStorage('jsrgyaoyan_hold').filter(i=>i.isIn())).set('callback',async event=>{ - const {bool,opinion,targets}=event.debateResult; - if(bool&&opinion){ - if(opinion=='red'){ - const notDebated=game.filterPlayer().removeArray(targets); - if(notDebated.length){ - const {result}=await player.chooseTarget('获得任意名未议事的角色的各一张手牌',[1,Infinity],true,(card,player,target)=>{ - return get.event('targets').includes(target)&&target.countGainableCards(player,'h'); - }).set('targets',notDebated).set('ai',target=>{ - const player=get.player(); - const att=get.attitude(player,target); - return -att; - }); - if(result.bool){ - const targets=result.targets; - targets.sortBySeat(); - player.line(targets,'green'); - for(const current of targets){ - await player.gainPlayerCard(current,'h',true); + async content(event, trigger, player) { + player + .chooseToDebate(player.getStorage("jsrgyaoyan_hold").filter((i) => i.isIn())) + .set("callback", async (event) => { + const { bool, opinion, targets } = event.debateResult; + if (bool && opinion) { + if (opinion == "red") { + const notDebated = game.filterPlayer().removeArray(targets); + if (notDebated.length) { + const { result } = await player + .chooseTarget( + "获得任意名未议事的角色的各一张手牌", + [1, Infinity], + true, + (card, player, target) => { + return ( + get.event("targets").includes(target) && + target.countGainableCards(player, "h") + ); + } + ) + .set("targets", notDebated) + .set("ai", (target) => { + const player = get.player(); + const att = get.attitude(player, target); + return -att; + }); + if (result.bool) { + const targets = result.targets; + targets.sortBySeat(); + player.line(targets, "green"); + for (const current of targets) { + await player.gainPlayerCard(current, "h", true); + } } } + } else { + const { + result: { bool, targets: targets2 }, + } = await player + .chooseTarget( + "是否对一名议事的角色造成2点伤害?", + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("targets", targets) + .set("ai", (target) => { + const player = get.player(); + const eff = get.damageEffect(target, player, player); + return eff; + }); + if (bool) { + player.line(targets2[0]); + targets2[0].damage(2); + } } } - else{ - const {result:{bool,targets:targets2}}=await player.chooseTarget('是否对一名议事的角色造成2点伤害?',(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('targets',targets).set('ai',target=>{ - const player=get.player(); - const eff=get.damageEffect(target,player,player); - return eff; - }); - if(bool){ - player.line(targets2[0]); - targets2[0].damage(2); - } - } - } - }); + }); }, - } - } - }, - jsrgbazheng:{ - audio:2, - trigger:{global:'debateShowOpinion'}, - filter(event,player){ - if(!event.targets.includes(player)) return false; - const damagedPlayers=player.getHistory('sourceDamage').map(evt=>evt.player).toUniqued(); - let dissent; - const colors=['red','black']; - for(const color of colors){ - if(event[color].some(i=>i[0]==player)){ - dissent=colors.find(i=>i!=color); - break; - } - } - return event[dissent].some(i=>damagedPlayers.includes(i[0])); + }, }, - forced:true, - locked:false, - direct:true, - async content(event,trigger,player){ - let myOpinion,dissent; - const colors=['red','black']; - for(const color of colors){ - if(trigger[color].some(i=>i[0]==player)){ - myOpinion=color; - dissent=colors.find(i=>i!=color); + }, + jsrgbazheng: { + audio: 2, + trigger: { global: "debateShowOpinion" }, + filter(event, player) { + if (!event.targets.includes(player)) return false; + const damagedPlayers = player + .getHistory("sourceDamage") + .map((evt) => evt.player) + .toUniqued(); + let dissent; + const colors = ["red", "black"]; + for (const color of colors) { + if (event[color].some((i) => i[0] == player)) { + dissent = colors.find((i) => i != color); break; } } - const damagedPlayers=player.getHistory('sourceDamage').map(evt=>evt.player).toUniqued(); - let dissident=[]; - for(let i=0;i damagedPlayers.includes(i[0])); + }, + forced: true, + locked: false, + direct: true, + async content(event, trigger, player) { + let myOpinion, dissent; + const colors = ["red", "black"]; + for (const color of colors) { + if (trigger[color].some((i) => i[0] == player)) { + myOpinion = color; + dissent = colors.find((i) => i != color); + break; + } + } + const damagedPlayers = player + .getHistory("sourceDamage") + .map((evt) => evt.player) + .toUniqued(); + let dissident = []; + for (let i = 0; i < trigger[dissent].length; i++) { + const pair = trigger[dissent][i]; + if (damagedPlayers.includes(pair[0])) { dissident.push(pair[0]); trigger[myOpinion].push(pair); - trigger[dissent].splice(i--,1); + trigger[dissent].splice(i--, 1); } } - player.logSkill('jsrgbazheng',dissident); + player.logSkill("jsrgbazheng", dissident); }, }, //刘永 - jsrgdanxin:{ - audio:2, - enable:'chooseToUse', - viewAs:{ - name:'tuixinzhifu', - storage:{jsrgdanxin:true}, + jsrgdanxin: { + audio: 2, + enable: "chooseToUse", + viewAs: { + name: "tuixinzhifu", + storage: { jsrgdanxin: true }, }, - filterCard:true, - position:'hes', - precontent(){ - player.addTempSkill('jsrgdanxin_effect'); + filterCard: true, + position: "hes", + precontent() { + player.addTempSkill("jsrgdanxin_effect"); }, - subSkill:{ - effect:{ - audio:'jsrgdanxin', - trigger:{ - global:'gainAfter', + subSkill: { + effect: { + audio: "jsrgdanxin", + trigger: { + global: "gainAfter", }, - filter(event,player){ - const level=event.player!=player?1:2; - if(event.player!=player&&event.getParent(level).name!='tuixinzhifu') return false; - if(event.player==player&&event.getParent(level).name!='tuixinzhifu') return false; - const card=event.getParent(level+1).card; - return card&&card.storage&&card.storage.jsrgdanxin; + filter(event, player) { + const level = event.player != player ? 1 : 2; + if (event.player != player && event.getParent(level).name != "tuixinzhifu") + return false; + if (event.player == player && event.getParent(level).name != "tuixinzhifu") + return false; + const card = event.getParent(level + 1).card; + return card && card.storage && card.storage.jsrgdanxin; }, - forced:true, - popup:false, - charlotte:true, - async content(event,trigger,player){ - const level=trigger.player!=player?1:2; - const {targets}=trigger.getParent(level+1); + forced: true, + popup: false, + charlotte: true, + async content(event, trigger, player) { + const level = trigger.player != player ? 1 : 2; + const { targets } = trigger.getParent(level + 1); await player.showCards(trigger.cards); - if(trigger.cards.some(card=>get.suit(card)=='heart')){ - const owners=trigger.cards.filter((card=>get.suit(card)=='heart')).map(card=>get.owner(card)).toUniqued(); - for(const owner of owners){ - if(owner&&owner.isIn()) await owner.recover(); + if (trigger.cards.some((card) => get.suit(card) == "heart")) { + const owners = trigger.cards + .filter((card) => get.suit(card) == "heart") + .map((card) => get.owner(card)) + .toUniqued(); + for (const owner of owners) { + if (owner && owner.isIn()) await owner.recover(); } } - if(trigger.player==player) return; - player.addTempSkill('jsrgdanxin_distance'); - if(!player.storage.jsrgdanxin_distance) player.storage.jsrgdanxin_distance={}; - const id=targets[0].playerid; - if(typeof player.storage.jsrgdanxin_distance[id]!='number') player.storage.jsrgdanxin_distance[id]=0; + if (trigger.player == player) return; + player.addTempSkill("jsrgdanxin_distance"); + if (!player.storage.jsrgdanxin_distance) player.storage.jsrgdanxin_distance = {}; + const id = targets[0].playerid; + if (typeof player.storage.jsrgdanxin_distance[id] != "number") + player.storage.jsrgdanxin_distance[id] = 0; player.storage.jsrgdanxin_distance[id]++; - player.markSkill('jsrgdanxin_distance'); + player.markSkill("jsrgdanxin_distance"); }, }, - distance:{ - onremove:true, - charlotte:true, - mod:{ - globalFrom(player,target,distance){ - if(!player.storage.jsrgdanxin_distance) return; - const dis=player.storage.jsrgdanxin_distance[target.playerid]; - if(typeof dis=='number') return distance+dis; + distance: { + onremove: true, + charlotte: true, + mod: { + globalFrom(player, target, distance) { + if (!player.storage.jsrgdanxin_distance) return; + const dis = player.storage.jsrgdanxin_distance[target.playerid]; + if (typeof dis == "number") return distance + dis; }, }, - intro:{ - content(storage,player){ - if(!storage) return; - const map=(_status.connectMode?lib.playerOL:game.playerMap); - let str=`你本回合:`; - for(const id in storage){ - str+='
            • 至'+get.translation(map[id])+'的距离+'+storage[id]; + intro: { + content(storage, player) { + if (!storage) return; + const map = _status.connectMode ? lib.playerOL : game.playerMap; + let str = `你本回合:`; + for (const id in storage) { + str += "
            • 至" + get.translation(map[id]) + "的距离+" + storage[id]; } return str; - } - } + }, + }, }, - } - }, - jsrgfengxiang:{ - audio:'fengxiang', - trigger:{player:'damageEnd'}, - forced:true, - direct:true, - filter(event,player){ - return game.hasPlayer(current=>{ - return current.countCards('e'); - }) }, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget('封乡:与一名其他角色交换装备区里的所有牌',(card,player,target)=>{ - return target.countCards('e')+player.countCards('e')>0&&player!=target; - },true).set('ai',target=>{ - const player=get.player(); - const att=get.attitude(player,target); - let delta=get.value(target.getCards('e'),player)-get.value(player.getCards('e'),player); - if(att>0){ - if(delta<0) delta+=att/3; - } - else{ - if(delta<0) delta-=att/3; - } - return delta; + }, + jsrgfengxiang: { + audio: "fengxiang", + trigger: { player: "damageEnd" }, + forced: true, + direct: true, + filter(event, player) { + return game.hasPlayer((current) => { + return current.countCards("e"); }); - if(bool){ - player.logSkill('jsrgfengxiang',targets[0]); - const num=player.countCards('e'); + }, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "封乡:与一名其他角色交换装备区里的所有牌", + (card, player, target) => { + return ( + target.countCards("e") + player.countCards("e") > 0 && player != target + ); + }, + true + ) + .set("ai", (target) => { + const player = get.player(); + const att = get.attitude(player, target); + let delta = + get.value(target.getCards("e"), player) - + get.value(player.getCards("e"), player); + if (att > 0) { + if (delta < 0) delta += att / 3; + } else { + if (delta < 0) delta -= att / 3; + } + return delta; + }); + if (bool) { + player.logSkill("jsrgfengxiang", targets[0]); + const num = player.countCards("e"); await player.swapEquip(targets[0]); - const delta=num-player.countCards('e'); - if(delta>0) player.draw(delta); + const delta = num - player.countCards("e"); + if (delta > 0) player.draw(delta); } }, }, - jsrgfuhai:{ - audio:'xinfu_fuhai', - enable:'phaseUse', - usable:1, - filter(event,player){ - return game.hasPlayer(current=>{ - return current.countCards('h')&¤t!=player; - }) - }, - filterTarget(card,player,target){ - return target.countCards('h')&&target!=player; - }, - selectTarget:-1, - multitarget:true, - multiline:true, - async content(event,trigger,player){ - const targets=event.targets.sortBySeat(); - const next=player.chooseCardOL(targets,'请展示一张手牌',true).set('ai',card=>{ - return -get.value(card); - }).set('aiCard',target=>{ - const hs=target.getCards('h'); - return {bool:true,cards:[hs.randomGet()]}; + jsrgfuhai: { + audio: "xinfu_fuhai", + enable: "phaseUse", + usable: 1, + filter(event, player) { + return game.hasPlayer((current) => { + return current.countCards("h") && current != player; }); - next._args.remove('glow_result'); - const {result}=await next; - const cards=[]; - const videoId=lib.status.videoId++; - for(let i=0;i { + return -get.value(card); + }) + .set("aiCard", (target) => { + const hs = target.getCards("h"); + return { bool: true, cards: [hs.randomGet()] }; + }); + next._args.remove("glow_result"); + const { result } = await next; + const cards = []; + const videoId = lib.status.videoId++; + for (let i = 0; i < targets.length; i++) { cards.push(result[i].cards[0]); - game.log(targets[i],'展示了',result[i].cards[0]); + game.log(targets[i], "展示了", result[i].cards[0]); } - game.broadcastAll((targets,cards,id,player)=>{ - var dialog=ui.create.dialog(get.translation(player)+'发动了【浮海】',cards); - dialog.videoId=id; - const getName=(target)=>{ - if(target._tempTranslate) return target._tempTranslate; - var name=target.name; - if(lib.translate[name+'_ab']) return lib.translate[name+'_ab']; - return get.translation(name); - } - for(let i=0;i { + var dialog = ui.create.dialog(get.translation(player) + "发动了【浮海】", cards); + dialog.videoId = id; + const getName = (target) => { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; + return get.translation(name); + }; + for (let i = 0; i < targets.length; i++) { + dialog.buttons[i].querySelector(".info").innerHTML = + getName(targets[i]) + "|" + get.strNumber(cards[i].number); + } + }, + targets, + cards, + videoId, + player + ); await game.asyncDelay(4); - game.broadcastAll('closeDialog',videoId); - let clock=-1,anticlock=-1; - for(let j=0;j<2;j++){ - let increase=-Infinity,decrease=Infinity,count=0; - for(let i=0;iincrease){ - increase=number; - flag=true; - } - else increase=Infinity; - if(number increase) { + increase = number; + flag = true; + } else increase = Infinity; + if (number < decrease) { + decrease = number; + flag = true; + } else decrease = -Infinity; + if (flag) count++; else break; } targets.reverse(); cards.reverse(); - if(j==0) anticlock=Math.max(1,count); - else clock=Math.max(1,count); + if (j == 0) anticlock = Math.max(1, count); + else clock = Math.max(1, count); } - const {result:{index}}=await player.chooseControl(`↖顺时针(${clock})`,`逆时针(${anticlock})↗`).set('prompt','请选择一个方向,摸对应数量的牌').set('ai',()=>get.event('choice')).set('choice',clock>anticlock?0:1) - player.draw(index==0?clock:anticlock); + const { + result: { index }, + } = await player + .chooseControl(`↖顺时针(${clock})`, `逆时针(${anticlock})↗`) + .set("prompt", "请选择一个方向,摸对应数量的牌") + .set("ai", () => get.event("choice")) + .set("choice", clock > anticlock ? 0 : 1); + player.draw(index == 0 ? clock : anticlock); + }, + ai: { + order: 8, + result: { player: 1 }, }, - ai:{ - order:8, - result:{player:1}, - } }, //张嫙 - jsrgtongli:{ - audio:'tongli', - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget) return false; - const type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - const hs=player.getCards('h'); - if(!hs.length) return false; - const evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - const num1=player.getHistory('useCard',evtx=>{ - return evtx.getParent('phaseUse')==evt; + jsrgtongli: { + audio: "tongli", + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget) return false; + const type = get.type(event.card); + if (type != "basic" && type != "trick") return false; + const hs = player.getCards("h"); + if (!hs.length) return false; + const evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + const num1 = player.getHistory("useCard", (evtx) => { + return evtx.getParent("phaseUse") == evt; }).length; - if(hs.length{ - let str='奢葬'; - if(player==game.me&&!_status.auto){ - str+=':获得任意张花色各不相同的牌'; - } - const dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,videoId,cards); - const time=get.utc(); - game.addVideo('showCards',player,['奢葬',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - const list=[]; - for(const i of cards) list.add(get.suit(i,false)); - const next=player.chooseButton([1,list.length]); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - for(var i=0;i { + let str = "奢葬"; + if (player == game.me && !_status.auto) { + str += ":获得任意张花色各不相同的牌"; + } + const dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + videoId, + cards + ); + const time = get.utc(); + game.addVideo("showCards", player, ["奢葬", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + const list = []; + for (const i of cards) list.add(get.suit(i, false)); + const next = player.chooseButton([1, list.length]); + next.set("dialog", event.videoId); + next.set("filterButton", function (button) { + for (var i = 0; i < ui.selected.buttons.length; i++) { + if (get.suit(ui.selected.buttons[i].link) == get.suit(button.link)) return false; } return true; }); - next.set('ai',function(button){ - return get.value(button.link,_status.event.player); + next.set("ai", function (button) { + return get.value(button.link, _status.event.player); }); - const {result}=await next; - if(result.bool&&result.links){ - const time2=1000-(get.utc()-time); - if(time2>0){ - await game.asyncDelay(0,time2); + const { result } = await next; + if (result.bool && result.links) { + const time2 = 1000 - (get.utc() - time); + if (time2 > 0) { + await game.asyncDelay(0, time2); } - game.broadcastAll('closeDialog',videoId); - player.gain(result.links,'gain2'); + game.broadcastAll("closeDialog", videoId); + player.gain(result.links, "gain2"); } }, }, - jsrgchiying:{ - audio:'dcchiying', - enable:'phaseUse', - usable:1, - filterTarget:true, - async content(event,trigger,player){ - const target=event.target; - const targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player).sortBySeat(player); - if(!targets.length) return; - while(targets.length){ - const current=targets.shift(); - if(current.countCards('he')) await current.chooseToDiscard('驰应:请弃置一张牌','he',true); + jsrgchiying: { + audio: "dcchiying", + enable: "phaseUse", + usable: 1, + filterTarget: true, + async content(event, trigger, player) { + const target = event.target; + const targets = game + .filterPlayer((current) => target.inRange(current) && current != player) + .sortBySeat(player); + if (!targets.length) return; + while (targets.length) { + const current = targets.shift(); + if (current.countCards("he")) + await current.chooseToDiscard("驰应:请弃置一张牌", "he", true); } - let cards=[]; - game.getGlobalHistory('cardMove',evt=>{ - if(evt.getParent(3)==event){ - cards.addArray(evt.cards.filter(card=>get.type(card)=='basic')); + let cards = []; + game.getGlobalHistory("cardMove", (evt) => { + if (evt.getParent(3) == event) { + cards.addArray(evt.cards.filter((card) => get.type(card) == "basic")); } }); - if(cards.length<=target.getHp()){ - cards=cards.filterInD('d'); - if(cards.length) target.gain(cards,'gain2'); + if (cards.length <= target.getHp()) { + cards = cards.filterInD("d"); + if (cards.length) target.gain(cards, "gain2"); } }, - ai:{ - order:6, - result:{ - target(player,target){ - const targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player); - let eff=0; - for(const targetx of targets){ - let effx=get.effect(targetx,{name:'guohe_copy2'},player,target); - if(get.attitude(player,targetx)<0) effx/=2; - eff+=effx; + ai: { + order: 6, + result: { + target(player, target) { + const targets = game.filterPlayer( + (current) => target.inRange(current) && current != player + ); + let eff = 0; + for (const targetx of targets) { + let effx = get.effect(targetx, { name: "guohe_copy2" }, player, target); + if (get.attitude(player, targetx) < 0) effx /= 2; + eff += effx; } - return eff*(get.attitude(player,target)<=0?0.75:1); - } - } - } + return eff * (get.attitude(player, target) <= 0 ? 0.75 : 1); + }, + }, + }, }, //郭照 - jsrgpianchong:{ - audio:'pianchong', - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - return player.getHistory('lose').length; + jsrgpianchong: { + audio: "pianchong", + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + return player.getHistory("lose").length; }, - frequent:true, - async content(event,trigger,player){ - const {result} = await player.judge(); + frequent: true, + async content(event, trigger, player) { + const { result } = await player.judge(); let num = 0; - game.getGlobalHistory('cardMove',evt=>{ - if(evt.name!='cardsDiscard'){ - if(evt.name!='lose'||evt.position!=ui.discardPile) return false; + game.getGlobalHistory("cardMove", (evt) => { + if (evt.name != "cardsDiscard") { + if (evt.name != "lose" || evt.position != ui.discardPile) return false; } - num += (evt.cards.filter(i=>get.color(i,false) == result.color).length); + num += evt.cards.filter((i) => get.color(i, false) == result.color).length; }); if (num > 0) player.draw(num); }, }, - jsrgzunwei:{ - audio:'zunwei', - enable:'phaseUse', - usable:1, - filter(event,player){ - const storage=player.getStorage('jsrgzunwei'); - return storage.length<3&&game.hasPlayer(current=>{ - return player.isDamaged()&¤t.getHp()>player.getHp()&&!storage.includes(2)|| - current.countCards('h')>player.countCards('h')&&!storage.includes(0)|| - current.countCards('e')>player.countCards('e')&&!storage.includes(1); - }); + jsrgzunwei: { + audio: "zunwei", + enable: "phaseUse", + usable: 1, + filter(event, player) { + const storage = player.getStorage("jsrgzunwei"); + return ( + storage.length < 3 && + game.hasPlayer((current) => { + return ( + (player.isDamaged() && + current.getHp() > player.getHp() && + !storage.includes(2)) || + (current.countCards("h") > player.countCards("h") && !storage.includes(0)) || + (current.countCards("e") > player.countCards("e") && !storage.includes(1)) + ); + }) + ); }, - chooseButton:{ - dialog(event,player){ - const list=[ - '选择手牌数大于你的一名角色', - '选择装备数大于你的一名角色', - '选择体力值大于你的一名角色', + chooseButton: { + dialog(event, player) { + const list = [ + "选择手牌数大于你的一名角色", + "选择装备数大于你的一名角色", + "选择体力值大于你的一名角色", ]; - const choiceList=ui.create.dialog('尊位:请选择一项','forcebutton','hidden'); - choiceList.add([list.map((item,i)=>{ - if(player.getStorage('jsrgzunwei').includes(i)) item=`${item}`; - return [i,item]; - }),'textbutton']) + const choiceList = ui.create.dialog("尊位:请选择一项", "forcebutton", "hidden"); + choiceList.add([ + list.map((item, i) => { + if (player.getStorage("jsrgzunwei").includes(i)) + item = `${item}`; + return [i, item]; + }), + "textbutton", + ]); return choiceList; }, - filter(button){ - const player=get.player(); - if(player.getStorage('jsrgzunwei').includes(button.link)) return false; - if(button.link==2){ - if(!player.isDamaged()) return false; - return game.hasPlayer(current=>{ - return current.getHp()>player.getHp(); + filter(button) { + const player = get.player(); + if (player.getStorage("jsrgzunwei").includes(button.link)) return false; + if (button.link == 2) { + if (!player.isDamaged()) return false; + return game.hasPlayer((current) => { + return current.getHp() > player.getHp(); }); } - if(button.link==0){ - return game.hasPlayer(current=>{ - return current.countCards('h')>player.countCards('h'); + if (button.link == 0) { + return game.hasPlayer((current) => { + return current.countCards("h") > player.countCards("h"); }); } - if(button.link==1){ - return game.hasPlayer(current=>{ - return current.countCards('e')>player.countCards('e'); + if (button.link == 1) { + return game.hasPlayer((current) => { + return current.countCards("e") > player.countCards("e"); }); } }, - backup(links){ - const next=get.copy(lib.skill.jsrgzunwei.backups[links[0]]); - next.audio='zunwei'; - next.filterCard=function(){return false}; - next.selectCard=-1; + backup(links) { + const next = get.copy(lib.skill.jsrgzunwei.backups[links[0]]); + next.audio = "zunwei"; + next.filterCard = function () { + return false; + }; + next.selectCard = -1; return next; }, - check(button){ - const player=get.player(); - switch(button.link){ - case 2:{ - const target=game.findPlayer(function(current){ + check(button) { + const player = get.player(); + switch (button.link) { + case 2: { + const target = game.findPlayer(function (current) { return current.isMaxHp(); }); - return (Math.min(target.hp,player.maxHp)-player.hp)*2; + return (Math.min(target.hp, player.maxHp) - player.hp) * 2; } - case 0:{ - const target=game.findPlayer(function(current){ + case 0: { + const target = game.findPlayer(function (current) { return current.isMaxHandcard(); }); - return Math.min(5,target.countCards('h')-player.countCards('h'))*0.8; + return Math.min(5, target.countCards("h") - player.countCards("h")) * 0.8; } - case 1:{ - const target=game.findPlayer(function(current){ + case 1: { + const target = game.findPlayer(function (current) { return current.isMaxEquip(); }); - return (target.countCards('e')-player.countCards('e'))*1.4; + return (target.countCards("e") - player.countCards("e")) * 1.4; } } }, - prompt(links){ + prompt(links) { return [ - '选择一名手牌数大于你的其他角色,将手牌数摸至与其相同(至多摸五张)', - '选择一名装备区内牌数大于你的其他角色,将其装备区里的牌移至你的装备区,直到你装备数不小于其', - '选择一名体力值大于你的其他角色,将体力值回复至与其相同', + "选择一名手牌数大于你的其他角色,将手牌数摸至与其相同(至多摸五张)", + "选择一名装备区内牌数大于你的其他角色,将其装备区里的牌移至你的装备区,直到你装备数不小于其", + "选择一名体力值大于你的其他角色,将体力值回复至与其相同", ][links[0]]; }, }, - backups:[ - { - filterTarget(card,player,target){ - return target.countCards('h')>player.countCards('h'); - }, - async content(event,trigger,player){ - player.draw(Math.min(5,event.target.countCards('h')-player.countCards('h'))); - if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[]; - player.storage.jsrgzunwei.add(0); - }, - ai:{ - order:10, - result:{ - player:function(player,target){ - return Math.min(5,target.countCards('h')-player.countCards('h')); + backups: [ + { + filterTarget(card, player, target) { + return target.countCards("h") > player.countCards("h"); + }, + async content(event, trigger, player) { + player.draw(Math.min(5, event.target.countCards("h") - player.countCards("h"))); + if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = []; + player.storage.jsrgzunwei.add(0); + }, + ai: { + order: 10, + result: { + player: function (player, target) { + return Math.min(5, target.countCards("h") - player.countCards("h")); + }, }, }, }, - }, - { - filterTarget(card,player,target){ - return target.countCards('e')>player.countCards('e'); - }, - async content(event,trigger,player){ - if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[]; - player.storage.jsrgzunwei.add(1); - const target=event.target; - do{ - if(!target.countCards('e',card=>{ - return player.canEquip(card); - })) break; - const {result:{bool,links}}=await player.chooseButton([ - `尊位:将${get.translation(target)}的一张装备牌移至你的区域内`, - target.getCards('e') - ],true).set('filterButton',button=>{ - return get.player().canEquip(button.link); - }).set('ai',get.buttonValue); - if(bool){ - target.$give(links[0],player,false); - await player.equip(links[0]); - } - } - while(player.countCards('e') player.countCards("e"); + }, + async content(event, trigger, player) { + if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = []; + player.storage.jsrgzunwei.add(1); + const target = event.target; + do { + if ( + !target.countCards("e", (card) => { + return player.canEquip(card); + }) + ) + break; + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + `尊位:将${get.translation(target)}的一张装备牌移至你的区域内`, + target.getCards("e"), + ], + true + ) + .set("filterButton", (button) => { + return get.player().canEquip(button.link); + }) + .set("ai", get.buttonValue); + if (bool) { + target.$give(links[0], player, false); + await player.equip(links[0]); + } + } while (player.countCards("e") < target.countCards("e")); + }, + ai: { + order: 10, + result: { + player(player, target) { + return target.countCards("e") - player.countCards("e"); + }, }, }, }, - }, - { - filterTarget(card,player,target){ - if(player.isHealthy()) return false; - return target.hp>player.hp; - }, - async content(event,trigger,player){ - player.recover(event.target.hp-player.hp); - if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[]; - player.storage.jsrgzunwei.add(2); - }, - ai:{ - order:10, - result:{ - player:function(player,target){ - return (Math.min(target.hp,player.maxHp)-player.hp); + { + filterTarget(card, player, target) { + if (player.isHealthy()) return false; + return target.hp > player.hp; + }, + async content(event, trigger, player) { + player.recover(event.target.hp - player.hp); + if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = []; + player.storage.jsrgzunwei.add(2); + }, + ai: { + order: 10, + result: { + player: function (player, target) { + return Math.min(target.hp, player.maxHp) - player.hp; + }, }, }, }, - }, ], - ai:{ - order:10, - result:{ - player:1, + ai: { + order: 10, + result: { + player: 1, }, }, - subSkill:{ - backup:{}, - } + subSkill: { + backup: {}, + }, }, //江山如故·转 //404郭嘉 - jsrgqingzi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(current=>{ - if(current==player) return false; - return current.hasCard(card=>{ - return lib.filter.canBeDiscarded(card,player,current); - },'e'); - }) - }, - derivation:'xinshensu', - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jsrgqingzi'),'弃置任意名其他角色装备区里的一张牌,然后令这些角色获得〖神速〗直到你的下回合开始',[1,Infinity],(card,player,target)=>{ - return target!=player&&target.hasCard(card=>{ - return lib.filter.canBeDiscarded(card,player,target); - },'e'); - }).set('ai',target=>{ - var player=_status.event.player; - return target.hasCard(card=>{ - return lib.filter.canBeDiscarded(card,player,target)&&get.value(card,target)>3||target.hp==1&&get.value(card,target)>0; - }); + jsrgqingzi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer((current) => { + if (current == player) return false; + return current.hasCard((card) => { + return lib.filter.canBeDiscarded(card, player, current); + }, "e"); }); - 'step 1' - if(result.bool){ - var targets=result.targets.slice(); + }, + derivation: "xinshensu", + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jsrgqingzi"), + "弃置任意名其他角色装备区里的一张牌,然后令这些角色获得〖神速〗直到你的下回合开始", + [1, Infinity], + (card, player, target) => { + return ( + target != player && + target.hasCard((card) => { + return lib.filter.canBeDiscarded(card, player, target); + }, "e") + ); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + return target.hasCard((card) => { + return ( + (lib.filter.canBeDiscarded(card, player, target) && + get.value(card, target) > 3) || + (target.hp == 1 && get.value(card, target) > 0) + ); + }); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.slice(); targets.sortBySeat(); - event.targets=targets; - event.num=0; - player.logSkill('jsrgqingzi',targets); - player.addSkill('jsrgqingzi_clear'); - } - else event.finish(); - 'step 2' - var target=targets[num]; - if(target.hasCard(card=>{ - return lib.filter.canBeDiscarded(card,player,target); - },'e')){ - player.discardPlayerCard(target,'e',true); - target.addAdditionalSkills('jsrgqingzi_'+player.playerid,'xinshensu'); - player.markAuto('jsrgqingzi_clear',[target]); + event.targets = targets; + event.num = 0; + player.logSkill("jsrgqingzi", targets); + player.addSkill("jsrgqingzi_clear"); + } else event.finish(); + "step 2"; + var target = targets[num]; + if ( + target.hasCard((card) => { + return lib.filter.canBeDiscarded(card, player, target); + }, "e") + ) { + player.discardPlayerCard(target, "e", true); + target.addAdditionalSkills("jsrgqingzi_" + player.playerid, "xinshensu"); + player.markAuto("jsrgqingzi_clear", [target]); } event.num++; - if(event.num0; + return player.getStorage("jsrgqingzi_clear").length > 0; }, - content:function(){ - 'step 0' - var targets=player.getStorage('jsrgqingzi_clear'); - if(trigger.name=='die'&&player==trigger.player){ - for(var target of targets){ + content: function () { + "step 0"; + var targets = player.getStorage("jsrgqingzi_clear"); + if (trigger.name == "die" && player == trigger.player) { + for (var target of targets) { target.removeAdditionalSkill(`jsrgqingzi_${player.playerid}`); } - player.removeSkill('jsrgqingzi_clear'); + player.removeSkill("jsrgqingzi_clear"); event.finish(); return; } - if(trigger.name=='phase') event.targets=targets.slice(0).sortBySeat(); - else event.targets=[trigger.player]; - 'step 1' - var target=targets.shift(); - var storage=player.getStorage('jsrgqingzi_clear'); - if(storage.includes(target)){ + if (trigger.name == "phase") event.targets = targets.slice(0).sortBySeat(); + else event.targets = [trigger.player]; + "step 1"; + var target = targets.shift(); + var storage = player.getStorage("jsrgqingzi_clear"); + if (storage.includes(target)) { storage.remove(target); target.removeAdditionalSkill(`jsrgqingzi_${player.playerid}`); } - if(targets.length>0){ + if (targets.length > 0) { event.redo(); - } - else if(!storage.length){ - player.removeSkill('jsrgqingzi_clear'); + } else if (!storage.length) { + player.removeSkill("jsrgqingzi_clear"); } }, }, }, }, - jsrgdingce:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - return player.hasCard(card=>{ - return lib.filter.cardDiscardable(card,player,'jsrgdingce'); + jsrgdingce: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + return player.hasCard((card) => { + return lib.filter.cardDiscardable(card, player, "jsrgdingce"); }); }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.source; - event.target=target; - player.chooseToDiscard(get.prompt('jsrgdingce',target),'弃置你与其的各一张手牌。若这两张牌颜色相同,你视为使用一张【洞烛先机】。').set('ai',card=>{ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',get.attitude(player,target)<0||player.getCards('h').concat(target.getCards('h')).filter(card=>{ - return get.value(card)<5.5; - }).length>=2).set('logSkill',['jsrgdingce',target]); - 'step 1' - if(result.bool){ - event.card=result.cards[0]; - if(target.countDiscardableCards(player,'h')){ - var next=player.discardPlayerCard(target,'h',true); - if(target==player) next.set('ai',button=>{ - var card=button.link; - return (get.color(card,false)==_status.event.color?7.5:5)-get.value(card); - }).set('color',get.color(event.card,false)); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - if(get.color(event.card,false)==get.color(card,false)){ + direct: true, + content: function () { + "step 0"; + var target = trigger.source; + event.target = target; + player + .chooseToDiscard( + get.prompt("jsrgdingce", target), + "弃置你与其的各一张手牌。若这两张牌颜色相同,你视为使用一张【洞烛先机】。" + ) + .set("ai", (card) => { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set( + "goon", + get.attitude(player, target) < 0 || + player + .getCards("h") + .concat(target.getCards("h")) + .filter((card) => { + return get.value(card) < 5.5; + }).length >= 2 + ) + .set("logSkill", ["jsrgdingce", target]); + "step 1"; + if (result.bool) { + event.card = result.cards[0]; + if (target.countDiscardableCards(player, "h")) { + var next = player.discardPlayerCard(target, "h", true); + if (target == player) + next.set("ai", (button) => { + var card = button.link; + return ( + (get.color(card, false) == _status.event.color ? 7.5 : 5) - + get.value(card) + ); + }).set("color", get.color(event.card, false)); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + if (get.color(event.card, false) == get.color(card, false)) { game.delayex(); - player.chooseUseTarget('dongzhuxianji',true); + player.chooseUseTarget("dongzhuxianji", true); } } }, }, - jsrgzhenfeng:{ - audio:2, - enable:'phaseUse', - locked:false, - filter:function(event,player){ - if(!event.jsrgzhenfeng) return false; - return event.jsrgzhenfeng.some(info=>event.filterCard({ - name:info[2], - nature:info[3], - storage:{jsrgzhenfeng:true}, - isCard:true, - },player,event)); + jsrgzhenfeng: { + audio: 2, + enable: "phaseUse", + locked: false, + filter: function (event, player) { + if (!event.jsrgzhenfeng) return false; + return event.jsrgzhenfeng.some((info) => + event.filterCard( + { + name: info[2], + nature: info[3], + storage: { jsrgzhenfeng: true }, + isCard: true, + }, + player, + event + ) + ); }, - onChooseToUse:function(event){ - if(!event.jsrgzhenfeng&&!game.online){ - var str=''; - game.countPlayer(current=>{ - current.getSkills(null,false,false).forEach(skill=>{ - var info=get.info(skill); - if(!info||info.charlotte) return; - var translation=get.skillInfoTranslation(skill,current); - str+=translation; + onChooseToUse: function (event) { + if (!event.jsrgzhenfeng && !game.online) { + var str = ""; + game.countPlayer((current) => { + current.getSkills(null, false, false).forEach((skill) => { + var info = get.info(skill); + if (!info || info.charlotte) return; + var translation = get.skillInfoTranslation(skill, current); + str += translation; }); }); - event.set('jsrgzhenfeng',lib.skill.jsrgzhenfeng.getInclusion(str,null,event.player)); + event.set( + "jsrgzhenfeng", + lib.skill.jsrgzhenfeng.getInclusion(str, null, event.player) + ); } }, - getInclusion:function(str,checkCard,player){ - let list=[]; - const names=Object.keys(lib.card); - for(const name of names){ - let type=get.type(name); - if(!['basic','trick'].includes(type)) continue; - if(player&&player.getStorage('jsrgzhenfeng_effect').includes(type)) continue; - const reg=`【${get.translation(name)}】`; - if(name=='sha'){ - if(str.includes(reg)){ - if(checkCard&&checkCard.name==name) return true; - list.push([type,'',name]); + getInclusion: function (str, checkCard, player) { + let list = []; + const names = Object.keys(lib.card); + for (const name of names) { + let type = get.type(name); + if (!["basic", "trick"].includes(type)) continue; + if (player && player.getStorage("jsrgzhenfeng_effect").includes(type)) continue; + const reg = `【${get.translation(name)}】`; + if (name == "sha") { + if (str.includes(reg)) { + if (checkCard && checkCard.name == name) return true; + list.push([type, "", name]); } - for(let nature of lib.inpile_nature){ - const reg1=`【${get.translation(nature)+get.translation(name)}】`,reg2=`${get.translation(nature)}【${get.translation(name)}】`; - if(str.includes(reg1)||str.includes(reg2)){ - if(checkCard&&checkCard.name==name&&checkCard.nature==nature) return true; - list.push([type,'',name,nature]); + for (let nature of lib.inpile_nature) { + const reg1 = `【${get.translation(nature) + get.translation(name)}】`, + reg2 = `${get.translation(nature)}【${get.translation(name)}】`; + if (str.includes(reg1) || str.includes(reg2)) { + if (checkCard && checkCard.name == name && checkCard.nature == nature) + return true; + list.push([type, "", name, nature]); } } - } - else{ - if(!str.includes(reg)) continue; - if(checkCard&&checkCard.name==name) return true; - list.push([type,'',name]); + } else { + if (!str.includes(reg)) continue; + if (checkCard && checkCard.name == name) return true; + list.push([type, "", name]); } } - if(checkCard) return false; + if (checkCard) return false; return list; }, - chooseButton:{ - dialog:function(event,player){ - var list=event.jsrgzhenfeng.filter(info=>{ - return event.filterCard({ - name:info[2], - nature:info[3], - storage:{jsrgzhenfeng:true}, - isCard:true, - },player,event); + chooseButton: { + dialog: function (event, player) { + var list = event.jsrgzhenfeng.filter((info) => { + return event.filterCard( + { + name: info[2], + nature: info[3], + storage: { jsrgzhenfeng: true }, + isCard: true, + }, + player, + event + ); }); - return ui.create.dialog('针锋',[list,'vcard']); + return ui.create.dialog("针锋", [list, "vcard"]); }, - filter:function(button,player){ - return _status.event.getParent().filterCard({ - name:button.link[2], - nature:button.link[3], - storage:{jsrgzhenfeng:true}, - isCard:true, - },player,_status.event.getParent()); + filter: function (button, player) { + return _status.event.getParent().filterCard( + { + name: button.link[2], + nature: button.link[3], + storage: { jsrgzhenfeng: true }, + isCard: true, + }, + player, + _status.event.getParent() + ); }, - check:function(button){ - var player=_status.event.player; - var card={ - name:button.link[2], - nature:button.link[3], - storage:{jsrgzhenfeng:true}, - isCard:true, + check: function (button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], + storage: { jsrgzhenfeng: true }, + isCard: true, }; - var eff=player.getUseValue(card); - if(['wugu','zhulu_card','yiyi','lulitongxin','lianjunshengyan','diaohulishan'].includes(button.link[2])) eff/=5; - var info=get.info(card); - if(info.toself){ - var str=player.getSkills(null,false,false).map(skill=>{ - var info=get.info(skill); - if(!info||info.charlotte) return; - return get.skillInfoTranslation(skill,player); - }).join('\n'); - if(lib.skill.jsrgzhenfeng.getInclusion(str,card)) eff+=get.damageEffect(player,player,player); + var eff = player.getUseValue(card); + if ( + [ + "wugu", + "zhulu_card", + "yiyi", + "lulitongxin", + "lianjunshengyan", + "diaohulishan", + ].includes(button.link[2]) + ) + eff /= 5; + var info = get.info(card); + if (info.toself) { + var str = player + .getSkills(null, false, false) + .map((skill) => { + var info = get.info(skill); + if (!info || info.charlotte) return; + return get.skillInfoTranslation(skill, player); + }) + .join("\n"); + if (lib.skill.jsrgzhenfeng.getInclusion(str, card)) + eff += get.damageEffect(player, player, player); } return eff; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jsrgzhenfeng', - filterCard:()=>false, - selectCard:-1, - popname:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], - storage:{jsrgzhenfeng:true}, - isCard:true, + audio: "jsrgzhenfeng", + filterCard: () => false, + selectCard: -1, + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], + storage: { jsrgzhenfeng: true }, + isCard: true, }, - precontent:function(){ + precontent: function () { delete event.result.skill; - player.logSkill('jsrgzhenfeng'); - event.getParent().addCount=false; - player.addTempSkill('jsrgzhenfeng_effect','phaseUseAfter'); - player.markAuto('jsrgzhenfeng_effect',[get.type(event.result.card)]); + player.logSkill("jsrgzhenfeng"); + event.getParent().addCount = false; + player.addTempSkill("jsrgzhenfeng_effect", "phaseUseAfter"); + player.markAuto("jsrgzhenfeng_effect", [get.type(event.result.card)]); }, - } + }; }, - prompt:function(links,player){ - return '视为使用一张'+(get.translation(links[0][3])||'')+get.translation(links[0][2]); - } - }, - mod:{ - cardUsable:function(card){ - if(card.storage&&card.storage.jsrgzhenfeng) return Infinity; - }, - targetInRange:function(card){ - if(card.storage&&card.storage.jsrgzhenfeng) return true; + prompt: function (links, player) { + return ( + "视为使用一张" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + ); }, }, - ai:{ - order:1, - result:{ - player:1, + mod: { + cardUsable: function (card) { + if (card.storage && card.storage.jsrgzhenfeng) return Infinity; + }, + targetInRange: function (card) { + if (card.storage && card.storage.jsrgzhenfeng) return true; }, }, - subSkill:{ - effect:{ - audio:'jsrgzhenfeng', - trigger:{ - global:'useCardToBegin', + ai: { + order: 1, + result: { + player: 1, + }, + }, + subSkill: { + effect: { + audio: "jsrgzhenfeng", + trigger: { + global: "useCardToBegin", }, - charlotte:true, - forced:true, - onremove:true, - filter:function(event,player){ - if(!event.card.storage||!event.card.storage.jsrgzhenfeng) return false; + charlotte: true, + forced: true, + onremove: true, + filter: function (event, player) { + if (!event.card.storage || !event.card.storage.jsrgzhenfeng) return false; // debugger - var str=event.target.getSkills(null,false,false).map(skill=>{ - var info=get.info(skill); - if(!info||info.charlotte) return; - return get.skillInfoTranslation(skill,event.target); - }).join('\n'); - return lib.skill.jsrgzhenfeng.getInclusion(str,event.card); + var str = event.target + .getSkills(null, false, false) + .map((skill) => { + var info = get.info(skill); + if (!info || info.charlotte) return; + return get.skillInfoTranslation(skill, event.target); + }) + .join("\n"); + return lib.skill.jsrgzhenfeng.getInclusion(str, event.card); }, - logTarget:'target', - content:function(){ + logTarget: "target", + content: function () { trigger.target.damage(); - } + }, }, }, }, //张飞 - jsrgbaohe:{ - audio:2, - trigger:{global:'phaseUseEnd'}, - filter:function(event,player){ - return player.countCards('he')>=2&&game.hasPlayer(current=>{ - return current.inRange(event.player)&&player.canUse('sha',current,false); - }); + jsrgbaohe: { + audio: 2, + trigger: { global: "phaseUseEnd" }, + filter: function (event, player) { + return ( + player.countCards("he") >= 2 && + game.hasPlayer((current) => { + return current.inRange(event.player) && player.canUse("sha", current, false); + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('jsrgbaohe'),2,'he').set('ai',card=>{ - var val=_status.event.val; - if(val>20) return 6-get.value(card); - if(val>0) return 4-get.value(card); - return 0; - }).set('val',game.filterPlayer(current=>{ - return current.inRange(trigger.player)&&player.canUse('sha',current,false); - }).map(i=>get.effect(i,{name:'sha'},player,player)).reduce((p,c)=>{ - return p+c; - },0)).set('logSkill','jsrgbaohe'); - 'step 1' - if(result.bool){ - var targets=game.filterPlayer(current=>{ - return current.inRange(trigger.player)&&player.canUse('sha',current,false); + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("jsrgbaohe"), 2, "he") + .set("ai", (card) => { + var val = _status.event.val; + if (val > 20) return 6 - get.value(card); + if (val > 0) return 4 - get.value(card); + return 0; + }) + .set( + "val", + game + .filterPlayer((current) => { + return ( + current.inRange(trigger.player) && + player.canUse("sha", current, false) + ); + }) + .map((i) => get.effect(i, { name: "sha" }, player, player)) + .reduce((p, c) => { + return p + c; + }, 0) + ) + .set("logSkill", "jsrgbaohe"); + "step 1"; + if (result.bool) { + var targets = game.filterPlayer((current) => { + return current.inRange(trigger.player) && player.canUse("sha", current, false); }); - if(targets.length){ + if (targets.length) { game.delayex(); - player.useCard({name:'sha',isCard:true,storage:{jsrgbaohe:true}},targets,false); - player.addTempSkill('jsrgbaohe_add'); + player.useCard( + { name: "sha", isCard: true, storage: { jsrgbaohe: true } }, + targets, + false + ); + player.addTempSkill("jsrgbaohe_add"); } } }, - subSkill:{ - add:{ - audio:'jsrgbaohe', - trigger:{ - global:'useCard', + subSkill: { + add: { + audio: "jsrgbaohe", + trigger: { + global: "useCard", }, - charlotte:true, - forced:true, - filter:function(event,player){ - let evt=event.getParent(3),respondTo=event.respondTo; - if(evt.name!='useCard'||!Array.isArray(respondTo)||!respondTo[1].storage||!respondTo[1].storage.jsrgbaohe) return false; - return evt.targets.length>evt.num+1; + charlotte: true, + forced: true, + filter: function (event, player) { + let evt = event.getParent(3), + respondTo = event.respondTo; + if ( + evt.name != "useCard" || + !Array.isArray(respondTo) || + !respondTo[1].storage || + !respondTo[1].storage.jsrgbaohe + ) + return false; + return evt.targets.length > evt.num + 1; }, - logTarget:function(event){ - let evt=event.getParent(3); - return evt.targets.slice(evt.num+1); + logTarget: function (event) { + let evt = event.getParent(3); + return evt.targets.slice(evt.num + 1); }, - content:function(){ - 'step 0' - var evt=trigger.getParent(3); - var targets=evt.targets.slice(evt.num+1); - var map=evt.customArgs; - for(var target of targets){ - var id=target.playerid; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number'){ - map[id].extraDamage=0; + content: function () { + "step 0"; + var evt = trigger.getParent(3); + var targets = evt.targets.slice(evt.num + 1); + var map = evt.customArgs; + for (var target of targets) { + var id = target.playerid; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") { + map[id].extraDamage = 0; } map[id].extraDamage++; } game.delayx(); }, - } + }, }, }, - jsrgxushi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:true, - filterTarget:lib.filter.notMe, - selectCard:[1,Infinity], - selectTarget:[1,Infinity], - position:'he', - filterOk:function(){ - return ui.selected.cards.length==ui.selected.targets.length; + jsrgxushi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + filterTarget: lib.filter.notMe, + selectCard: [1, Infinity], + selectTarget: [1, Infinity], + position: "he", + filterOk: function () { + return ui.selected.cards.length == ui.selected.targets.length; }, - check:function(card){ - var player=get.player(); - if(ui.selected.cards.length>=game.countPlayer(current=>{ - return current!=player&&get.attitude(player,current)>0; - })) return 0; - return 5-get.value(card); + check: function (card) { + var player = get.player(); + if ( + ui.selected.cards.length >= + game.countPlayer((current) => { + return current != player && get.attitude(player, current) > 0; + }) + ) + return 0; + return 5 - get.value(card); }, - prompt:'按顺序选择卡牌和角色,并将卡牌交给对应顺序的角色。然后你获得两倍数量的【影】。', - complexSelect:true, - multitarget:true, - multiline:true, - discard:false, - lose:false, - delay:false, - contentBefore:function(){ - event.getParent()._jsrgxushi_targets=targets.slice(); + prompt: "按顺序选择卡牌和角色,并将卡牌交给对应顺序的角色。然后你获得两倍数量的【影】。", + complexSelect: true, + multitarget: true, + multiline: true, + discard: false, + lose: false, + delay: false, + contentBefore: function () { + event.getParent()._jsrgxushi_targets = targets.slice(); }, - content:function(){ - 'step 0' - var targets=event.getParent()._jsrgxushi_targets; - var list=[]; - for(var i=0;i{ - var player=get.player(),target=get.event('target'),att=get.attitude(player,target)>0?1:-1; - var list=get.event('controls').map(i=>[i,target.getCards('he').map(get.value).reduce((p,c)=>p+c,0)]).sort((a,b)=>{ - return att*(a[1]-b[1]); - }); - return list[0][0]; - }).set('target',target); - var color=result.control; - if(color=='cancel2'){ - event.finish(); - return; - } - player.logSkill('jsrgzhuiming',target); - player.popup(color,color=='red'?'fire':'thunder'); - game.log(player,'声明了',color); - var prompt=`追命:${get.translation(player)}声明了${get.translation(color)}`,prompt2=`请弃置任意张牌,然后其展示你一张牌,若此牌颜色为${get.translation(color)},此【杀】不计入次数限制、不可被响应且伤害+1` - yield target.chooseToDiscard(prompt,prompt2,[1,Infinity],'he',true).set('ai',card=>{ - var color=get.event('color'),player=get.player(); - if(get.position(card)=='e'&&get.color(card)==color) return 2; - if(player.getHp()<=2&&get.color(card)==color) return Math.random()<0.5; - return 0; - }).set('color',color); - if(target.countCards('he')) result=yield player.choosePlayerCard(target,'he',true).set('ai',button=>{ - var color=get.event('color'),att=get.event('att'); - if(get.position(button.link)=='e'&&get.color(button.link)==color){ - return 100*att; - } - return 1+Math.random(); - }).set('color',color).set('att',get.attitude(player,target)>0?1:-1); - else{ - event.finish(); - return; - } - var card=result.cards[0]; - player.showCards(card,`${get.translation(target)}因【追命】被展示`); - if(get.color(card)==color){ - trigger.directHit.addArray(game.players); - var evt=trigger.getParent(); - if(evt.addCount!==false){ - evt.addCount=false; - player.getStat().card.sha--; - } - var map=trigger.getParent().customArgs; - var id=target.playerid; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number'){ - map[id].extraDamage=0; - } - map[id].extraDamage++; - game.log(trigger.card,'不计入次数限制、不可被响应、伤害+1'); - } - } - }, - //娄圭 - jsrgshacheng:{ - audio:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return event.targets.some(i=>i.isIn()&&i.hasHistory('lose',evt=>evt.cards2.length))&&player.getExpansions('jsrgshacheng').length; - }, - direct:true, - group:'jsrgshacheng_build', - content:function(){ - 'step 0' - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - var targets=trigger.targets.filter(i=>i.isIn()&&i.hasHistory('lose',evt=>evt.cards2.length)); - player.chooseTarget(get.prompt('jsrgshacheng'),'令一名目标角色摸X张牌,然后移去一张“城”(X为对应角色本回合失去过的牌数且至多为5)',(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('targets',targets).set('ai',target=>{ - return target==get.event('targetx')?1:0; - }).set('targetx',(()=>{ - let info=[]; - targets.filter(target=>{ - let att=get.attitude(player,target); - if(att<=0) return false; - if(Math.abs(att)>1) att=Math.sign(att)*Math.sqrt(Math.abs(att)); - info.push([target,att*target.getHistory('lose').map(evt=>evt.cards2.length).reduce((p,c)=>p+c,0)]); - return false; - }); - if(!info.length) return null; - info=info.sort((a,b)=>{ - return b[1]-a[1]; - })[0]; - if(info[1]<=0) return null; - return info[0]; - })()); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - var cards=player.getExpansions('jsrgshacheng'); - if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton([`沙城:移去一张“城”`,cards],true); - } - else{ - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - event.finish(); - } - 'step 2' - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - if(result.bool){ - player.logSkill('jsrgshacheng',target); - player.loseToDiscardpile(result.links); - target.draw(Math.min(5,target.getHistory('lose').map(evt=>evt.cards2.length).reduce((p,c)=>p+c,0))); - } - }, - marktext:'城', - intro:{ - content:'expansion', - markcount:'expansion', - }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - }, - subSkill:{ - build:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', - }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); - }, - content:function(){ - var cards=get.cards(2); - player.addToExpansion(cards,'gain2').gaintag.add('jsrgshacheng'); - }, - } - } - }, - jsrgninghan:{ - audio:2, - init:(player)=>{ - game.addGlobalSkill('jsrgninghan_frozen'); - }, - onremove:(player)=>{ - if(!game.hasPlayer(current=>current.hasSkill('jsrgninghan'),true)) game.removeGlobalSkill('jsrgninghan_frozen'); - }, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(!event.hasNature('ice')) return false; - return event.cards&&event.cards.filterInD().length; - }, - forced:true, - content:function(){ - var cards=trigger.cards.filterInD(); - player.addToExpansion(cards,'gain2').gaintag.add('jsrgshacheng'); - }, - subSkill:{ - frozen:{ - mod:{ - cardnature:function(card,player){ - if(card.name==='sha'&&get.suit(card)==='club') return 'ice'; - }, - aiOrder:(player,card,num)=>{ - if(num&&card.name==='sha'&&game.hasNature(card,'ice')){ - let lg=game.findPlayer(current=>current.hasSkill('jsrgninghan')); - if(lg) return num+0.15*Math.sign(get.attitude(player,lg)); - } - } - }, - trigger:{player:'dieAfter'}, - filter:(event,player)=>{ - return !game.hasPlayer(current=>!current.hasSkill('jsrgninghan'),true); - }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('jsrgninghan_frozen'); - } }, }, - ai:{ - combo:'jsrgshacheng' - } + }, + jsrgzhuiming: { + audio: 2, + trigger: { + player: "useCardToPlayered", + }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return event.isFirstTarget && event.targets.length == 1 && event.target.isIn(); + }, + direct: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger, + target = trigger.target; + var colors = Object.keys(lib.color).remove("none"); + var result = yield player + .chooseControl(colors, "cancel2") + .set("prompt", get.prompt("jsrgzhuiming")) + .set("prompt2", `声明一种颜色并令${get.translation(trigger.target)}弃置任意张牌`) + .set("ai", () => { + var player = get.player(), + target = get.event("target"), + att = get.attitude(player, target) > 0 ? 1 : -1; + var list = get + .event("controls") + .map((i) => [ + i, + target + .getCards("he") + .map(get.value) + .reduce((p, c) => p + c, 0), + ]) + .sort((a, b) => { + return att * (a[1] - b[1]); + }); + return list[0][0]; + }) + .set("target", target); + var color = result.control; + if (color == "cancel2") { + event.finish(); + return; + } + player.logSkill("jsrgzhuiming", target); + player.popup(color, color == "red" ? "fire" : "thunder"); + game.log(player, "声明了", color); + var prompt = `追命:${get.translation(player)}声明了${get.translation(color)}`, + prompt2 = `请弃置任意张牌,然后其展示你一张牌,若此牌颜色为${get.translation( + color + )},此【杀】不计入次数限制、不可被响应且伤害+1`; + yield target + .chooseToDiscard(prompt, prompt2, [1, Infinity], "he", true) + .set("ai", (card) => { + var color = get.event("color"), + player = get.player(); + if (get.position(card) == "e" && get.color(card) == color) return 2; + if (player.getHp() <= 2 && get.color(card) == color) return Math.random() < 0.5; + return 0; + }) + .set("color", color); + if (target.countCards("he")) + result = yield player + .choosePlayerCard(target, "he", true) + .set("ai", (button) => { + var color = get.event("color"), + att = get.event("att"); + if (get.position(button.link) == "e" && get.color(button.link) == color) { + return 100 * att; + } + return 1 + Math.random(); + }) + .set("color", color) + .set("att", get.attitude(player, target) > 0 ? 1 : -1); + else { + event.finish(); + return; + } + var card = result.cards[0]; + player.showCards(card, `${get.translation(target)}因【追命】被展示`); + if (get.color(card) == color) { + trigger.directHit.addArray(game.players); + var evt = trigger.getParent(); + if (evt.addCount !== false) { + evt.addCount = false; + player.getStat().card.sha--; + } + var map = trigger.getParent().customArgs; + var id = target.playerid; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") { + map[id].extraDamage = 0; + } + map[id].extraDamage++; + game.log(trigger.card, "不计入次数限制、不可被响应、伤害+1"); + } + }, + }, + //娄圭 + jsrgshacheng: { + audio: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return ( + event.targets.some( + (i) => i.isIn() && i.hasHistory("lose", (evt) => evt.cards2.length) + ) && player.getExpansions("jsrgshacheng").length + ); + }, + direct: true, + group: "jsrgshacheng_build", + content: function () { + "step 0"; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + var targets = trigger.targets.filter( + (i) => i.isIn() && i.hasHistory("lose", (evt) => evt.cards2.length) + ); + player + .chooseTarget( + get.prompt("jsrgshacheng"), + "令一名目标角色摸X张牌,然后移去一张“城”(X为对应角色本回合失去过的牌数且至多为5)", + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("targets", targets) + .set("ai", (target) => { + return target == get.event("targetx") ? 1 : 0; + }) + .set( + "targetx", + (() => { + let info = []; + targets.filter((target) => { + let att = get.attitude(player, target); + if (att <= 0) return false; + if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att)); + info.push([ + target, + att * + target + .getHistory("lose") + .map((evt) => evt.cards2.length) + .reduce((p, c) => p + c, 0), + ]); + return false; + }); + if (!info.length) return null; + info = info.sort((a, b) => { + return b[1] - a[1]; + })[0]; + if (info[1] <= 0) return null; + return info[0]; + })() + ); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + var cards = player.getExpansions("jsrgshacheng"); + if (cards.length == 1) event._result = { bool: true, links: cards }; + else player.chooseButton([`沙城:移去一张“城”`, cards], true); + } else { + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + event.finish(); + } + "step 2"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + if (result.bool) { + player.logSkill("jsrgshacheng", target); + player.loseToDiscardpile(result.links); + target.draw( + Math.min( + 5, + target + .getHistory("lose") + .map((evt) => evt.cards2.length) + .reduce((p, c) => p + c, 0) + ) + ); + } + }, + marktext: "城", + intro: { + content: "expansion", + markcount: "expansion", + }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + subSkill: { + build: { + trigger: { + global: "phaseBefore", + player: "enterGame", + }, + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; + }, + content: function () { + var cards = get.cards(2); + player.addToExpansion(cards, "gain2").gaintag.add("jsrgshacheng"); + }, + }, + }, + }, + jsrgninghan: { + audio: 2, + init: (player) => { + game.addGlobalSkill("jsrgninghan_frozen"); + }, + onremove: (player) => { + if (!game.hasPlayer((current) => current.hasSkill("jsrgninghan"), true)) + game.removeGlobalSkill("jsrgninghan_frozen"); + }, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (!event.hasNature("ice")) return false; + return event.cards && event.cards.filterInD().length; + }, + forced: true, + content: function () { + var cards = trigger.cards.filterInD(); + player.addToExpansion(cards, "gain2").gaintag.add("jsrgshacheng"); + }, + subSkill: { + frozen: { + mod: { + cardnature: function (card, player) { + if (card.name === "sha" && get.suit(card) === "club") return "ice"; + }, + aiOrder: (player, card, num) => { + if (num && card.name === "sha" && game.hasNature(card, "ice")) { + let lg = game.findPlayer((current) => current.hasSkill("jsrgninghan")); + if (lg) return num + 0.15 * Math.sign(get.attitude(player, lg)); + } + }, + }, + trigger: { player: "dieAfter" }, + filter: (event, player) => { + return !game.hasPlayer((current) => !current.hasSkill("jsrgninghan"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("jsrgninghan_frozen"); + }, + }, + }, + ai: { + combo: "jsrgshacheng", + }, }, //张任 - jsrgfuni:{ - audio:2, - trigger:{global:'roundStart'}, - group:['jsrgfuni_unlimit','jsrgfuni_zero'], - forced:true, - direct:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - var count=Math.ceil(game.countPlayer()/2); - var result=yield player.chooseTarget(`伏匿:请选择至多${get.cnNumber(count)}名角色`,`令这些角色获得共计${get.cnNumber(count)}张【影】`,true,[1,count]).set('ai',target=>{ - return get.attitude(get.player(),target)+get.event().getRand(target.playerid); - }); - if(result.bool){ - var targets=result.targets.slice().sortBySeat(_status.currentPhase); - player.logSkill('jsrgfuni',targets); - } - else event.finish(); + jsrgfuni: { + audio: 2, + trigger: { global: "roundStart" }, + group: ["jsrgfuni_unlimit", "jsrgfuni_zero"], + forced: true, + direct: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger; + var count = Math.ceil(game.countPlayer() / 2); + var result = yield player + .chooseTarget( + `伏匿:请选择至多${get.cnNumber(count)}名角色`, + `令这些角色获得共计${get.cnNumber(count)}张【影】`, + true, + [1, count] + ) + .set("ai", (target) => { + return get.attitude(get.player(), target) + get.event().getRand(target.playerid); + }); + if (result.bool) { + var targets = result.targets.slice().sortBySeat(_status.currentPhase); + player.logSkill("jsrgfuni", targets); + } else event.finish(); yield null; - var num=count/targets.length; - if(num==1||num==count){ - result={ - bool:true, - links:targets.map(current=>{ + var num = count / targets.length; + if (num == 1 || num == count) { + result = { + bool: true, + links: targets.map((current) => { return `${num}|${current.playerid}`; }), }; - } - else{ - var dialog=[ - '伏匿:选择每名角色要获得的【影】数', - ]; - var len=count-targets.length+1; - for(var target of targets){ + } else { + var dialog = ["伏匿:选择每名角色要获得的【影】数"]; + var len = count - targets.length + 1; + for (var target of targets) { dialog.addArray([ `
              ${get.translation(target)}
              `, - [Array.from({length:len}).map((_,i)=>{ - return [`${i+1}|${target.playerid}`,get.cnNumber(i+1,true)]; - }),'tdnodes'], + [ + Array.from({ length: len }).map((_, i) => { + return [`${i + 1}|${target.playerid}`, get.cnNumber(i + 1, true)]; + }), + "tdnodes", + ], ]); } - result=yield player.chooseButton(dialog,true).set('filterButton',button=>{ - var total=0,info=button.link.split('|'); - var numFix=0; - for(var buttonx of ui.selected.buttons){ - var infox=buttonx.link.split('|'); - var num=parseInt(infox[0]); - total+=num; - if(infox[1]==info[1]) numFix=num; - } - return total+parseInt(info[0])-numFix<=get.event('count'); - }).set('count',count).set('filterOk',()=>{ - var total=0; - for(var buttonx of ui.selected.buttons){ - total+=parseInt(buttonx.link.split('|')[0]); - } - return total==get.event('count'); - }).set('selectButton',()=>{ - return [get.event('len'),Math.max(get.event('len'),ui.selected.buttons.length)+1]; - }).set('len',targets.length).set('custom',{ - add:{}, - replace:{ - button:function(button){ - if(!_status.event.isMine()) return; - if(button.classList.contains('selectable')==false) return; - if(button.classList.contains('selected')){ - ui.selected.buttons.remove(button); - button.classList.remove('selected'); - if(_status.multitarget||_status.event.complexSelect){ - game.uncheck(); - game.check(); + result = yield player + .chooseButton(dialog, true) + .set("filterButton", (button) => { + var total = 0, + info = button.link.split("|"); + var numFix = 0; + for (var buttonx of ui.selected.buttons) { + var infox = buttonx.link.split("|"); + var num = parseInt(infox[0]); + total += num; + if (infox[1] == info[1]) numFix = num; + } + return total + parseInt(info[0]) - numFix <= get.event("count"); + }) + .set("count", count) + .set("filterOk", () => { + var total = 0; + for (var buttonx of ui.selected.buttons) { + total += parseInt(buttonx.link.split("|")[0]); + } + return total == get.event("count"); + }) + .set("selectButton", () => { + return [ + get.event("len"), + Math.max(get.event("len"), ui.selected.buttons.length) + 1, + ]; + }) + .set("len", targets.length) + .set("custom", { + add: {}, + replace: { + button: function (button) { + if (!_status.event.isMine()) return; + if (button.classList.contains("selectable") == false) return; + if (button.classList.contains("selected")) { + ui.selected.buttons.remove(button); + button.classList.remove("selected"); + if (_status.multitarget || _status.event.complexSelect) { + game.uncheck(); + game.check(); + } + } else { + var current = button.parentNode.querySelector(".selected"); + if (current) { + ui.selected.buttons.remove(current); + current.classList.remove("selected"); + } + button.classList.add("selected"); + ui.selected.buttons.add(button); } - } - else{ - var current=button.parentNode.querySelector('.selected'); - if(current){ - ui.selected.buttons.remove(current); - current.classList.remove('selected'); - } - button.classList.add('selected'); - ui.selected.buttons.add(button); - } - game.check(); + game.check(); + }, }, - } - }).set('processAI',()=>{ - return get.event('aiResult'); - }).set('aiResult',(()=>{ - var result=targets.map(i=>{ - return [i==player?2:1,i.playerid]; - }); - var rest=count-targets.length-1; - while(rest--) result[Math.floor(Math.random()*result.length)][0]++; - return { - bool:true, - links:result.map(i=>`${i[0]}|${i[1]}`), - }; - })()); + }) + .set("processAI", () => { + return get.event("aiResult"); + }) + .set( + "aiResult", + (() => { + var result = targets.map((i) => { + return [i == player ? 2 : 1, i.playerid]; + }); + var rest = count - targets.length - 1; + while (rest--) result[Math.floor(Math.random() * result.length)][0]++; + return { + bool: true, + links: result.map((i) => `${i[0]}|${i[1]}`), + }; + })() + ); } - if(result.bool){ - var links=result.links; - var list=[]; - for(var link of links){ - var info=link.split('|'); - var id=info[1]; - var target=(_status.connectMode?lib.playerOL:game.playerMap)[id]; + if (result.bool) { + var links = result.links; + var list = []; + for (var link of links) { + var info = link.split("|"); + var id = info[1]; + var target = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; player.line(target); - var yings=lib.card.ying.getYing(parseInt(info[0])); - list.push([target,yings]); - game.log(target,'获得了',yings); + var yings = lib.card.ying.getYing(parseInt(info[0])); + list.push([target, yings]); + game.log(target, "获得了", yings); } game.loseAsync({ - gain_list:list, - animate:'gain2', - }).setContent('gaincardMultiple'); + gain_list: list, + animate: "gain2", + }).setContent("gaincardMultiple"); } }, - subSkill:{ - zero:{ - priority:Infinity, - mod:{ - attackRange:()=>0, + subSkill: { + zero: { + priority: Infinity, + mod: { + attackRange: () => 0, }, }, - unlimit:{ - audio:'jsrgfuni', - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter'], + unlimit: { + audio: "jsrgfuni", + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter"], }, - filter:function(event,player){ - return event.getd().some(i=>get.name(i,false)=='ying'); + filter: function (event, player) { + return event.getd().some((i) => get.name(i, false) == "ying"); }, - forced:true, - content:function(){ - player.addTempSkill('jsrgfuni_buff'); + forced: true, + content: function () { + player.addTempSkill("jsrgfuni_buff"); }, }, - buff:{ - charlotte:true, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - content:function(){ + buff: { + charlotte: true, + trigger: { player: "useCard1" }, + forced: true, + popup: false, + content: function () { trigger.directHit.addArray(game.players); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, - mark:true, - intro:{ - content:'使用牌无距离限制且不能被响应', + mark: true, + intro: { + content: "使用牌无距离限制且不能被响应", }, - mod:{ - targetInRange:()=>true, + mod: { + targetInRange: () => true, }, }, }, - ai:{ - expose:0.15, + ai: { + expose: 0.15, }, }, - jsrgchuanxin:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('hes')&&game.hasPlayer(current=>player.canUse({ - name:'sha', - storage:{jsrgchuanxin:true}, - },current)); + jsrgchuanxin: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.countCards("hes") && + game.hasPlayer((current) => + player.canUse( + { + name: "sha", + storage: { jsrgchuanxin: true }, + }, + current + ) + ) + ); }, - direct:true, - content:function(){ - var next=player.chooseToUse(); - next.set('openskilldialog',`###${get.prompt('jsrgchuanxin')}###将一张牌当【杀】使用,且当一名角色受到此【杀】伤害时,此伤害+X(X为其本回合回复过的体力值)。`); - next.set('norestore',true); - next.set('_backupevent','jsrgchuanxin_backup'); - next.set('addCount',false); - next.set('logSkill','jsrgchuanxin'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + direct: true, + content: function () { + var next = player.chooseToUse(); + next.set( + "openskilldialog", + `###${get.prompt( + "jsrgchuanxin" + )}###将一张牌当【杀】使用,且当一名角色受到此【杀】伤害时,此伤害+X(X为其本回合回复过的体力值)。` + ); + next.set("norestore", true); + next.set("_backupevent", "jsrgchuanxin_backup"); + next.set("addCount", false); + next.set("logSkill", "jsrgchuanxin"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('jsrgchuanxin_backup'); + next.backup("jsrgchuanxin_backup"); }, - subSkill:{ - backup:{ - filterCard:function(card){ - return get.itemtype(card)=='card'; + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - viewAs:{ - name:'sha', - storage:{jsrgchuanxin:true}, + viewAs: { + name: "sha", + storage: { jsrgchuanxin: true }, }, - selectCard:1, - position:'hes', - ai1:function(card){ - var player=get.player(); - var maxVal=5.5; - if(get.name(card,false)=='ying'&&player.hasSkill('jsrgchuanxin')) maxVal-=3; - return maxVal-get.value(card); + selectCard: 1, + position: "hes", + ai1: function (card) { + var player = get.player(); + var maxVal = 5.5; + if (get.name(card, false) == "ying" && player.hasSkill("jsrgchuanxin")) + maxVal -= 3; + return maxVal - get.value(card); }, - precontent:function(){ + precontent: function () { delete event.result.skill; - player.addTempSkill('jsrgchuanxin_add'); + player.addTempSkill("jsrgchuanxin_add"); }, }, - add:{ - trigger:{global:'damageBegin3'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.jsrgchuanxin) return false; - if(event.getParent().type!='card') return false; - return game.hasGlobalHistory('changeHp',evt=>{ - return evt.getParent().name=='recover'&&evt.player==event.player; + add: { + trigger: { global: "damageBegin3" }, + filter: function (event, player) { + if (!event.card || !event.card.storage || !event.card.storage.jsrgchuanxin) + return false; + if (event.getParent().type != "card") return false; + return game.hasGlobalHistory("changeHp", (evt) => { + return evt.getParent().name == "recover" && evt.player == event.player; }); }, - forced:true, - charlotte:true, - content:function(){ - var num=game.getGlobalHistory('changeHp',evt=>{ - return evt.getParent().name=='recover'&&evt.player==trigger.player; - }).map(evt=>evt.num).reduce((p,c)=>p+c,0); - trigger.num+=num; - game.log(trigger.card,'的伤害+'+num); + forced: true, + charlotte: true, + content: function () { + var num = game + .getGlobalHistory("changeHp", (evt) => { + return evt.getParent().name == "recover" && evt.player == trigger.player; + }) + .map((evt) => evt.num) + .reduce((p, c) => p + c, 0); + trigger.num += num; + game.log(trigger.card, "的伤害+" + num); }, }, }, }, //黄忠 - jsrgcuifeng:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - locked:false, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - var info=lib.card[name]; - if(!info||info.notarget||(info.selectTarget&&info.selectTarget!=1)||!get.tag({name:name},'damage')) continue; - if(name=='sha'){ - list.push(['基本','','sha']); - for(var nature of lib.inpile_nature) list.push(['基本','',name,nature]); - } - else if(get.type(name)=='trick') list.push(['锦囊','',name]); - else if(get.type(name)=='basic') list.push(['基本','',name]); + jsrgcuifeng: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + locked: false, + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + var info = lib.card[name]; + if ( + !info || + info.notarget || + (info.selectTarget && info.selectTarget != 1) || + !get.tag({ name: name }, "damage") + ) + continue; + if (name == "sha") { + list.push(["基本", "", "sha"]); + for (var nature of lib.inpile_nature) list.push(["基本", "", name, nature]); + } else if (get.type(name) == "trick") list.push(["锦囊", "", name]); + else if (get.type(name) == "basic") list.push(["基本", "", name]); } - return ui.create.dialog('摧锋',[list,'vcard']); + return ui.create.dialog("摧锋", [list, "vcard"]); }, - filter:function(button,player){ - return _status.event.getParent().filterCard({name:button.link[2],nature:button.link[3],isCard:true,storage:{jsrgcuifeng:true},},player,_status.event.getParent()); + filter: function (button, player) { + return _status.event.getParent().filterCard( + { + name: button.link[2], + nature: button.link[3], + isCard: true, + storage: { jsrgcuifeng: true }, + }, + player, + _status.event.getParent() + ); }, - check:function(button){ - var player=_status.event.player; - var effect=player.getUseValue({name:button.link[2],nature:button.link[3],storage:{jsrgcuifeng:true}}); - if(effect>0) return effect; + check: function (button) { + var player = _status.event.player; + var effect = player.getUseValue({ + name: button.link[2], + nature: button.link[3], + storage: { jsrgcuifeng: true }, + }); + if (effect > 0) return effect; return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jsrgcuifeng', - selectCard:-1, - filterCard:()=>false, - popname:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, - storage:{jsrgcuifeng:true}, + audio: "jsrgcuifeng", + selectCard: -1, + filterCard: () => false, + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, + storage: { jsrgcuifeng: true }, }, - precontent:function(){ - player.logSkill('jsrgcuifeng'); - player.awakenSkill('jsrgcuifeng'); + precontent: function () { + player.logSkill("jsrgcuifeng"); + player.awakenSkill("jsrgcuifeng"); delete event.result.skill; - if(!player.storage.jsrgcuifeng_check) player.when('phaseEnd').then(()=>{ - var num=0; - player.checkHistory('sourceDamage',evt=>{ - if(evt.card.storage.jsrgcuifeng) num+=evt.num; - }); - if(num==0||num>1){ - player.restoreSkill('jsrgcuifeng'); - game.log(player,'重置了','#g【摧锋】'); - } - delete player.storage.jsrgcuifeng_check; - }).translation('摧锋'); - player.setStorage('jsrgcuifeng_check',true); - } - } + if (!player.storage.jsrgcuifeng_check) + player + .when("phaseEnd") + .then(() => { + var num = 0; + player.checkHistory("sourceDamage", (evt) => { + if (evt.card.storage.jsrgcuifeng) num += evt.num; + }); + if (num == 0 || num > 1) { + player.restoreSkill("jsrgcuifeng"); + game.log(player, "重置了", "#g【摧锋】"); + } + delete player.storage.jsrgcuifeng_check; + }) + .translation("摧锋"); + player.setStorage("jsrgcuifeng_check", true); + }, + }; }, - prompt:function(links,player){ - return '请选择'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'的目标'; - } - }, - mod:{ - targetInRange:card=>{ - if(card.storage&&card.storage.jsrgcuifeng) return true; + prompt: function (links, player) { + return ( + "请选择" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "的目标" + ); }, }, - ai:{ - order:1.9, - result:{ - player:1, + mod: { + targetInRange: (card) => { + if (card.storage && card.storage.jsrgcuifeng) return true; + }, + }, + ai: { + order: 1.9, + result: { + player: 1, }, }, }, - jsrgdengnan:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - var info=lib.card[name]; - if(!info||info.type!='trick'||info.notarget||get.tag({name:name},'damage')) continue; - list.push(['锦囊','',name]); + jsrgdengnan: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + var info = lib.card[name]; + if ( + !info || + info.type != "trick" || + info.notarget || + get.tag({ name: name }, "damage") + ) + continue; + list.push(["锦囊", "", name]); } - return ui.create.dialog('登难',[list,'vcard']); + return ui.create.dialog("登难", [list, "vcard"]); }, - filter:function(button,player){ - return _status.event.getParent().filterCard({name:button.link[2],isCard:true},player,_status.event.getParent()); + filter: function (button, player) { + return _status.event + .getParent() + .filterCard( + { name: button.link[2], isCard: true }, + player, + _status.event.getParent() + ); }, - check:function(button){ - var player=_status.event.player; + check: function (button) { + var player = _status.event.player; return player.getUseValue(button.link[2]); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jsrgdengnan', - selectCard:-1, - filterCard:()=>false, - popname:true, - viewAs:{ - name:links[0][2], - isCard:true, - storage:{jsrgdengnan:true}, + audio: "jsrgdengnan", + selectCard: -1, + filterCard: () => false, + popname: true, + viewAs: { + name: links[0][2], + isCard: true, + storage: { jsrgdengnan: true }, }, - precontent:function(){ - player.logSkill('jsrgdengnan'); - player.awakenSkill('jsrgdengnan'); + precontent: function () { + player.logSkill("jsrgdengnan"); + player.awakenSkill("jsrgdengnan"); delete event.result.skill; - if(!player.storage.jsrgdengnan_check) player.when('phaseEnd').then(()=>{ - var targets=[]; - player.checkHistory('useCard',evt=>{ - if(evt.card.storage.jsrgdengnan) targets.addArray(evt.targets); - }); - if(targets.every(current=>{ - return current.hasHistory('damage'); - })){ - player.restoreSkill('jsrgdengnan'); - game.log(player,'重置了','#g【登难】'); - } - delete player.storage.jsrgdengnan_check; - }).translation('登难'); - player.setStorage('jsrgdengnan_check',true); - } - } + if (!player.storage.jsrgdengnan_check) + player + .when("phaseEnd") + .then(() => { + var targets = []; + player.checkHistory("useCard", (evt) => { + if (evt.card.storage.jsrgdengnan) + targets.addArray(evt.targets); + }); + if ( + targets.every((current) => { + return current.hasHistory("damage"); + }) + ) { + player.restoreSkill("jsrgdengnan"); + game.log(player, "重置了", "#g【登难】"); + } + delete player.storage.jsrgdengnan_check; + }) + .translation("登难"); + player.setStorage("jsrgdengnan_check", true); + }, + }; + }, + prompt: function (links, player) { + return ( + "请选择" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "的目标" + ); }, - prompt:function(links,player){ - return '请选择'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'的目标'; - } }, - ai:{ - order:2, - result:{ - player:1, + ai: { + order: 2, + result: { + player: 1, }, }, }, //夏侯荣 - jsrgfenjian:{ - audio:2, - enable:'chooseToUse', - locked:false, - filter:function(event,player){ - return ['juedou','tao'].some(name=>{ - return !player.getStorage('jsrgfenjian_used').includes(name)&&event.filterCard({ - name:name, - isCard:true, - storage:{jsrgfenjian:true}, - },player,event); + jsrgfenjian: { + audio: 2, + enable: "chooseToUse", + locked: false, + filter: function (event, player) { + return ["juedou", "tao"].some((name) => { + return ( + !player.getStorage("jsrgfenjian_used").includes(name) && + event.filterCard( + { + name: name, + isCard: true, + storage: { jsrgfenjian: true }, + }, + player, + event + ) + ); }); }, - hiddenCard:function(player,name){ - if(['juedou','tao'].some(i=>i==name&&!player.getStorage('jsrgfenjian_used').includes(name))) return true; + hiddenCard: function (player, name) { + if ( + ["juedou", "tao"].some( + (i) => i == name && !player.getStorage("jsrgfenjian_used").includes(name) + ) + ) + return true; return false; }, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('奋剑',[['juedou','tao'].filter(name=>!player.getStorage('jsrgfenjian_used').includes(name)),'vcard']); - dialog.direct=true; + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("奋剑", [ + ["juedou", "tao"].filter( + (name) => !player.getStorage("jsrgfenjian_used").includes(name) + ), + "vcard", + ]); + dialog.direct = true; return dialog; }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard({ - name:button.link[2], - isCard:true, - storage:{jsrgfenjian:true}, - },player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard( + { + name: button.link[2], + isCard: true, + storage: { jsrgfenjian: true }, + }, + player, + evt + ); }, - check:function(button){ - if(button.link[2]==='tao'){ - let dying=_status.event.getParent(2).dying; - if(dying) return get.effect(dying,{ - name:'tao', - isCard:true, - storage:{jsrgfenjian:true}, - },_status.event.player); + check: function (button) { + if (button.link[2] === "tao") { + let dying = _status.event.getParent(2).dying; + if (dying) + return get.effect( + dying, + { + name: "tao", + isCard: true, + storage: { jsrgfenjian: true }, + }, + _status.event.player + ); } return _status.event.player.getUseValue({ - name:button.link[2], - isCard:true, - storage:{jsrgfenjian:true}, + name: button.link[2], + isCard: true, + storage: { jsrgfenjian: true }, }); }, - backup:function(links){ + backup: function (links) { return { - audio:'jsrgfenjian', - viewAs:{ - name:links[0][2], - isCard:true, - storage:{jsrgfenjian:true}, + audio: "jsrgfenjian", + viewAs: { + name: links[0][2], + isCard: true, + storage: { jsrgfenjian: true }, }, - filterCard:()=>false, - selectCard:-1, - precontent:function(){ - player.logSkill('jsrgfenjian'); + filterCard: () => false, + selectCard: -1, + precontent: function () { + player.logSkill("jsrgfenjian"); delete event.result.skill; - player.addTempSkill('jsrgfenjian_effect'); - player.addMark('jsrgfenjian_effect',1,false); - if(!player.storage.jsrgfenjian_used) player.when({global:'phaseAfter'}).then(()=>{ - delete player.storage.jsrgfenjian_used; - }); - player.markAuto('jsrgfenjian_used',[event.result.card.name]); + player.addTempSkill("jsrgfenjian_effect"); + player.addMark("jsrgfenjian_effect", 1, false); + if (!player.storage.jsrgfenjian_used) + player.when({ global: "phaseAfter" }).then(() => { + delete player.storage.jsrgfenjian_used; + }); + player.markAuto("jsrgfenjian_used", [event.result.card.name]); }, - } + }; }, - prompt:function(links){ - return '奋剑:令你本回合受到的伤害+1,视为使用'+get.translation(links[0][2]); + prompt: function (links) { + return "奋剑:令你本回合受到的伤害+1,视为使用" + get.translation(links[0][2]); }, }, - mod:{ - targetEnabled:function(card,player,target){ - if(player==target&&card.storage&&card.storage.jsrgfenjian) return false; + mod: { + targetEnabled: function (card, player, target) { + if (player == target && card.storage && card.storage.jsrgfenjian) return false; }, }, - ai:{ - order:function(item,player){ - return Math.max(get.order({name:'juedou'}),get.order({name:'tao'}))+0.2; + ai: { + order: function (item, player) { + return Math.max(get.order({ name: "juedou" }), get.order({ name: "tao" })) + 0.2; }, - result:{ - player:(player)=>{ - if(_status.event.dying) return 2*get.sgnAttitude(player,_status.event.dying); + result: { + player: (player) => { + if (_status.event.dying) return 2 * get.sgnAttitude(player, _status.event.dying); return 1; - } - } - }, - subSkill:{ - effect:{ - audio:'jsrgfenjian', - charlotte:true, - trigger:{player:'damageBegin3'}, - forced:true, - onremove:true, - content:function(){ - trigger.num+=player.countMark('jsrgfenjian_effect'); }, - intro:{content:'本回合受到的伤害+#'}, + }, + }, + subSkill: { + effect: { + audio: "jsrgfenjian", + charlotte: true, + trigger: { player: "damageBegin3" }, + forced: true, + onremove: true, + content: function () { + trigger.num += player.countMark("jsrgfenjian_effect"); + }, + intro: { content: "本回合受到的伤害+#" }, }, }, }, //孙尚香 - jsrgguiji:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(player.hasSkill('jsrgguiji_used')) return false; - return game.hasPlayer(current=>lib.skill.jsrgguiji.filterTarget('keiki',player,current)); + jsrgguiji: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("jsrgguiji_used")) return false; + return game.hasPlayer((current) => + lib.skill.jsrgguiji.filterTarget("keiki", player, current) + ); }, - filterTarget:function(card,player,target){ - return target.countCards('h')get.value(i)).reduce((p,c)=>p+c,0); - var val2=target.getCards('h').map(i=>get.value(i)).reduce((p,c)=>p+c,0); - return val-val2; - } - } + ai: { + order: 6, + result: { + target: function (player, target) { + var val = player + .getCards("h") + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0); + var val2 = target + .getCards("h") + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0); + return val - val2; + }, + }, }, - subSkill:{ - used:{charlotte:true}, - swapback:{ - audio:'jsrgguiji', - trigger:{ - global:['phaseUseEnd','dieAfter'], + subSkill: { + used: { charlotte: true }, + swapback: { + audio: "jsrgguiji", + trigger: { + global: ["phaseUseEnd", "dieAfter"], }, - filter:function(event,player){ - return player.getStorage('jsrgguiji_swapback').includes(event.player); + filter: function (event, player) { + return player.getStorage("jsrgguiji_swapback").includes(event.player); }, - charlotte:true, - direct:true, - check:function(event,player){ - return player.getCards('h').map(i=>get.value(i)).reduce((p,c)=>p+c,0)get.value(i)).reduce((p,c)=>p+c,0)+4*Math.random(); + charlotte: true, + direct: true, + check: function (event, player) { + return ( + player + .getCards("h") + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0) < + event.player + .getCards("h") + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0) + + 4 * Math.random() + ); }, - content:function(){ - 'step 0' - if(trigger.name=='phaseUse'){ - player.chooseBool(get.prompt('jsrgguiji_swapback',trigger.player),'与其交换手牌。').set('ai',()=>{ - return get.event('bool'); - }).set('bool',lib.skill.jsrgguiji_swapback.check(trigger,player)>0); - } - else{ - player.unmarkAuto('jsrgguiji_swapback',[trigger.player]); + content: function () { + "step 0"; + if (trigger.name == "phaseUse") { + player + .chooseBool( + get.prompt("jsrgguiji_swapback", trigger.player), + "与其交换手牌。" + ) + .set("ai", () => { + return get.event("bool"); + }) + .set("bool", lib.skill.jsrgguiji_swapback.check(trigger, player) > 0); + } else { + player.unmarkAuto("jsrgguiji_swapback", [trigger.player]); event.finish(); } - 'step 1' - if(result.bool){ - player.logSkill('jsrgguiji_swapback',trigger.player); + "step 1"; + if (result.bool) { + player.logSkill("jsrgguiji_swapback", trigger.player); player.swapHandcards(trigger.player); } - player.unmarkAuto('jsrgguiji_swapback',[trigger.player]); + player.unmarkAuto("jsrgguiji_swapback", [trigger.player]); }, - intro:{ - content:'$的下个出牌阶段结束时,你可以与其交换手牌' + intro: { + content: "$的下个出牌阶段结束时,你可以与其交换手牌", }, }, }, }, - jsrgjiaohao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return [1,2,3,4,5].some(i=>player.countEmptySlot(i)); + jsrgjiaohao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return [1, 2, 3, 4, 5].some((i) => player.countEmptySlot(i)); }, - forced:true, - locked:false, - global:'jsrgjiaohao_g', - content:function(){ - 'step 0' - var count=Math.ceil([1,2,3,4,5].map(i=>player.countEmptySlot(i)).reduce((p,c)=>p+c,0)/2); - player.gain(lib.card.ying.getYing(count),'gain2'); + forced: true, + locked: false, + global: "jsrgjiaohao_g", + content: function () { + "step 0"; + var count = Math.ceil( + [1, 2, 3, 4, 5].map((i) => player.countEmptySlot(i)).reduce((p, c) => p + c, 0) / 2 + ); + player.gain(lib.card.ying.getYing(count), "gain2"); }, - subSkill:{ - g:{ - audio:'jsrgjiaohao', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(current=>{ - if(current==player||!current.hasSkill('jsrgjiaohao')) return false; - return player.hasCard(card=>{ - return get.type(card)=='equip'&¤t.canEquip(card); + subSkill: { + g: { + audio: "jsrgjiaohao", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => { + if (current == player || !current.hasSkill("jsrgjiaohao")) return false; + return player.hasCard((card) => { + return get.type(card) == "equip" && current.canEquip(card); }); }); }, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - return target!=player&&target.hasSkill('jsrgjiaohao')&&target.canEquip(card); + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + return ( + target != player && target.hasSkill("jsrgjiaohao") && target.canEquip(card) + ); }, - selectTarget:function(){ - var num=game.countPlayer(current=>{ - return current.hasSkill('jsrgjiaohao'); + selectTarget: function () { + var num = game.countPlayer((current) => { + return current.hasSkill("jsrgjiaohao"); }); - return num>1?1:-1; + return num > 1 ? 1 : -1; }, - filterCard:function(card){ - return get.type(card)=='equip'; + filterCard: function (card) { + return get.type(card) == "equip"; }, - check:function(card){ - var player=get.player(); - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); + check: function (card) { + var player = get.player(); + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - prompt:function(){ - var list=game.filterPlayer(current=>{ - return current.hasSkill('jsrgjiaohao'); + prompt: function () { + var list = game.filterPlayer((current) => { + return current.hasSkill("jsrgjiaohao"); }); - return `将一张装备牌置于${get.translation(list)}${list.length>1?'中的一人':''}的装备区`; + return `将一张装备牌置于${get.translation(list)}${ + list.length > 1 ? "中的一人" : "" + }的装备区`; }, - discard:false, - lose:false, - prepare:function(cards,player,targets){ - player.$give(cards,targets[0],false); + discard: false, + lose: false, + prepare: function (cards, player, targets) { + player.$give(cards, targets[0], false); }, - content:function(){ + content: function () { target.equip(cards[0]); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - var card=ui.selected.cards[0]; - if(card) return get.effect(target,card,target,target); + ai: { + order: 10, + result: { + target: function (player, target) { + var card = ui.selected.cards[0]; + if (card) return get.effect(target, card, target, target); return 0; }, }, }, }, - } + }, }, //庞统 - jsrgmanjuan:{ - audio:2, - trigger:{ - player:'loseEnd', - global:['equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], + jsrgmanjuan: { + audio: 2, + trigger: { + player: "loseEnd", + global: ["equipEnd", "addJudgeEnd", "gainEnd", "loseAsyncEnd", "addToExpansionEnd"], }, - filter:function(event,player){ - return (player.countCards('h')==0)^player.hasSkill('jsrgmanjuan_in'); + filter: function (event, player) { + return (player.countCards("h") == 0) ^ player.hasSkill("jsrgmanjuan_in"); }, - forced:true, - locked:false, - firstDo:true, - silent:true, - content:function(){ - 'step 0' - if(!player.countCards('h')){ - var cards=[]; - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'&&evt.position==ui.discardPile||evt.name=='cardsDiscard'){ - cards.addArray(evt.cards.filterInD('d')); + forced: true, + locked: false, + firstDo: true, + silent: true, + content: function () { + "step 0"; + if (!player.countCards("h")) { + var cards = []; + game.checkGlobalHistory("cardMove", (evt) => { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) { + cards.addArray(evt.cards.filterInD("d")); } }); - var cardsx=cards.map(card=>{ - var cardx=ui.create.card(); + var cardsx = cards.map((card) => { + var cardx = ui.create.card(); cardx.init(get.cardInfo(card)); - cardx._cardid=card.cardid; + cardx._cardid = card.cardid; return cardx; }); - player.directgains(cardsx,null,'jsrgmanjuan'); - player.addSkill('jsrgmanjuan_in'); - } - else{ - player.removeSkill('jsrgmanjuan_in'); + player.directgains(cardsx, null, "jsrgmanjuan"); + player.addSkill("jsrgmanjuan_in"); + } else { + player.removeSkill("jsrgmanjuan_in"); } }, - subSkill:{ - in:{ - audio:'jsrgmanjuan', - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], + subSkill: { + in: { + audio: "jsrgmanjuan", + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - locked:false, - silent:true, - filter:function(event,player){ - var cards=event.getd(); + forced: true, + locked: false, + silent: true, + filter: function (event, player) { + var cards = event.getd(); return cards.length; }, - onremove:function(player){ - var cards2=player.getCards('s',card=>{ - return card.hasGaintag('jsrgmanjuan'); + onremove: function (player) { + var cards2 = player.getCards("s", (card) => { + return card.hasGaintag("jsrgmanjuan"); }); - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards2,player); + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards2, + player + ); } - cards2.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); + cards2.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); }, - group:['jsrgmanjuan_use','jsrgmanjuan_lose'], - content:function(){ - var cards=[]; - var idList=player.getCards('s',card=>card.hasGaintag('jsrgmanjuan')).map(i=>i._cardid); - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'&&evt.position==ui.discardPile||evt.name=='cardsDiscard'){ - cards.addArray(evt.cards.filter(i=>get.position(i,true)=='d'&&!idList.includes(i.cardid))); + group: ["jsrgmanjuan_use", "jsrgmanjuan_lose"], + content: function () { + var cards = []; + var idList = player + .getCards("s", (card) => card.hasGaintag("jsrgmanjuan")) + .map((i) => i._cardid); + game.checkGlobalHistory("cardMove", (evt) => { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) { + cards.addArray( + evt.cards.filter( + (i) => get.position(i, true) == "d" && !idList.includes(i.cardid) + ) + ); } }); - var cards2=cards.map(card=>{ - var cardx=ui.create.card(); + var cards2 = cards.map((card) => { + var cardx = ui.create.card(); cardx.init(get.cardInfo(card)); - cardx._cardid=card.cardid; + cardx._cardid = card.cardid; return cardx; }); - player.directgains(cards2,null,'jsrgmanjuan'); + player.directgains(cards2, null, "jsrgmanjuan"); }, - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('jsrgmanjuan')&&player.getStorage('jsrgmanjuan_used').includes(get.number(card,false))) return false; + mod: { + cardEnabled2: function (card, player) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("jsrgmanjuan") && + player.getStorage("jsrgmanjuan_used").includes(get.number(card, false)) + ) + return false; }, }, }, - use:{ - trigger:{ - player:['useCardBefore','respondBefore'], + use: { + trigger: { + player: ["useCardBefore", "respondBefore"], }, - charlotte:true, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - var cards=player.getCards('s',card=>card.hasGaintag('jsrgmanjuan')&&card._cardid); - return event.cards&&event.cards.some(card=>{ - return cards.includes(card); - }); + charlotte: true, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + var cards = player.getCards( + "s", + (card) => card.hasGaintag("jsrgmanjuan") && card._cardid + ); + return ( + event.cards && + event.cards.some((card) => { + return cards.includes(card); + }) + ); }, - content:function(){ - var idList=player.getCards('s',card=>card.hasGaintag('jsrgmanjuan')).map(i=>i._cardid); - var cards=[]; - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'&&evt.position==ui.discardPile||evt.name=='cardsDiscard'){ - cards.addArray(evt.cards.filter(i=>idList.includes(i.cardid))); + content: function () { + var idList = player + .getCards("s", (card) => card.hasGaintag("jsrgmanjuan")) + .map((i) => i._cardid); + var cards = []; + game.checkGlobalHistory("cardMove", (evt) => { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) { + cards.addArray(evt.cards.filter((i) => idList.includes(i.cardid))); } }); - var cards2=[]; - for(var card of trigger.cards){ - var cardx=cards.find(cardx=>cardx.cardid==card._cardid); - if(cardx) cards2.push(cardx); + var cards2 = []; + for (var card of trigger.cards) { + var cardx = cards.find((cardx) => cardx.cardid == card._cardid); + if (cardx) cards2.push(cardx); } - var cards3=trigger.cards.slice(); - trigger.cards=cards2; - trigger.card.cards=cards2; - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards3,player); + var cards3 = trigger.cards.slice(); + trigger.cards = cards2; + trigger.card.cards = cards2; + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards3, + player + ); } - cards3.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - if(!player.storage.jsrgmanjuan_used){ - player.when({global:'phaseAfter'}) - .then(()=>{ - delete player.storage.jsrgmanjuan_used; - }) + cards3.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + if (!player.storage.jsrgmanjuan_used) { + player.when({ global: "phaseAfter" }).then(() => { + delete player.storage.jsrgmanjuan_used; + }); } - player.markAuto('jsrgmanjuan_used',cards3.map(card=>get.number(card,false))); + player.markAuto( + "jsrgmanjuan_used", + cards3.map((card) => get.number(card, false)) + ); }, }, - lose:{ - trigger:{ - global:['loseEnd','equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd','cardsGotoOrderingBegin','phaseAfter'], + lose: { + trigger: { + global: [ + "loseEnd", + "equipEnd", + "addJudgeEnd", + "gainEnd", + "loseAsyncEnd", + "addToExpansionEnd", + "cardsGotoOrderingBegin", + "phaseAfter", + ], }, - charlotte:true, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(event.name=='phase') return true; - var idList=player.getCards('s',card=>card.hasGaintag('jsrgmanjuan')).map(i=>i._cardid); - return event.cards&&event.cards.some(card=>{ - return idList.includes(card.cardid); - }); - }, - content:function(){ - var cards2; - if(trigger.name=='phase'){ - cards2=player.getCards('s',card=>{ - return card.hasGaintag('jsrgmanjuan'); + charlotte: true, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if (event.name == "phase") return true; + var idList = player + .getCards("s", (card) => card.hasGaintag("jsrgmanjuan")) + .map((i) => i._cardid); + return ( + event.cards && + event.cards.some((card) => { + return idList.includes(card.cardid); }) - } - else{ - var idList=[]; - game.checkGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'&&evt.position==ui.discardPile||evt.name=='cardsDiscard'){ - idList.addArray(evt.cards.filter(i=>get.position(i,true)=='d').map(i=>i.cardid)); + ); + }, + content: function () { + var cards2; + if (trigger.name == "phase") { + cards2 = player.getCards("s", (card) => { + return card.hasGaintag("jsrgmanjuan"); + }); + } else { + var idList = []; + game.checkGlobalHistory("cardMove", (evt) => { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) { + idList.addArray( + evt.cards + .filter((i) => get.position(i, true) == "d") + .map((i) => i.cardid) + ); } }); - cards2=player.getCards('s',card=>{ - return card.hasGaintag('jsrgmanjuan')&&!idList.includes(card._cardid); + cards2 = player.getCards("s", (card) => { + return card.hasGaintag("jsrgmanjuan") && !idList.includes(card._cardid); }); } - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards2,player); + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards2, + player + ); } - cards2.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - } + cards2.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, }, - } + }, }, - jsrgyangming:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(current=>{ + jsrgyangming: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => { return player.canCompare(current); }); }, - filterTarget:function(card,player,current){ + filterTarget: function (card, player, current) { return player.canCompare(current); }, - content:function(){ - 'step 0' - event.num=0; - 'step 1' - player.chooseToCompare(target).set('small',get.attitude(player,target)>0&&(player.countCards('h',card=>{ - return get.value(card)<6; - })<=1||target.countCards('h',card=>{ - return get.value(card)<6; - })<=1)); - 'step 2' - if(result.winner!=target){ - if(!player.canCompare(target)) event._result={bool:false}; - else player.chooseBool('是否与其重复此拼点流程?').set('ai',()=>get.event('bool')).set('bool',get.effect(target,'jsrgyangming',player,player)>0); + content: function () { + "step 0"; + event.num = 0; + "step 1"; + player.chooseToCompare(target).set( + "small", + get.attitude(player, target) > 0 && + (player.countCards("h", (card) => { + return get.value(card) < 6; + }) <= 1 || + target.countCards("h", (card) => { + return get.value(card) < 6; + }) <= 1) + ); + "step 2"; + if (result.winner != target) { + if (!player.canCompare(target)) event._result = { bool: false }; + else + player + .chooseBool("是否与其重复此拼点流程?") + .set("ai", () => get.event("bool")) + .set("bool", get.effect(target, "jsrgyangming", player, player) > 0); event.num++; - } - else{ - if(event.num) target.draw(event.num); + } else { + if (event.num) target.draw(event.num); player.recover(); event.finish(); } - 'step 3' - if(result.bool){ + "step 3"; + if (result.bool) { event.goto(1); } }, - ai:{ - order:1, - expose:0.15, - result:{ - target:function(player,target){ - var maxnum=0; - var cards2=target.getCards('h'); - for(var i=0;imaxnum){ - maxnum=get.number(cards2[i]); + ai: { + order: 1, + expose: 0.15, + result: { + target: function (player, target) { + var maxnum = 0; + var cards2 = target.getCards("h"); + for (var i = 0; i < cards2.length; i++) { + if (get.number(cards2[i]) > maxnum) { + maxnum = get.number(cards2[i]); } } - if(maxnum>10) maxnum=10; - if(maxnum<5&&cards2.length>1) maxnum=5; - var cards=player.getCards('h'); - for(var i=0;i 10) maxnum = 10; + if (maxnum < 5 && cards2.length > 1) maxnum = 5; + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + if (get.number(cards[i]) < maxnum) return 1; } return 0; - } - } - } + }, + }, + }, }, //韩遂 - jsrgniluan:{ - audio:'niluan', - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - var damaged=game.filterPlayer(current=>{ - return current.hasAllHistory('sourceDamage',evt=>evt.player==player); + jsrgniluan: { + audio: "niluan", + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + var damaged = game.filterPlayer((current) => { + return current.hasAllHistory("sourceDamage", (evt) => evt.player == player); }); - var undamaged=game.filterPlayer().removeArray(damaged); + var undamaged = game.filterPlayer().removeArray(damaged); player.chooseCardTarget({ - prompt:get.prompt('jsrgniluan'), - prompt2:`${undamaged.length?'选择一张牌弃置并选择一名未对你造成过伤害的角色,你对其造成1点伤害':''}${undamaged.length&&damaged.length?';
              或':''}${damaged.length?'仅选择一名对你造成过伤害的角色,你令其摸两张牌':''}。`, - damaged:damaged, - aiTarget:(()=>{ - if(undamaged.includes(player)&&!undamaged.some(i=>{ - if(i===player) return false; - let att=get.attitude(player,i); - if(att>0) return true; - return att<0&&i.getHp(true)+i.hujia<2; - })&&(player.hp>2||get.damageEffect(player,player,player)>=0)) return player; - var info=game.filterPlayer().map(current=>{ - let damage=undamaged.includes(current),card={name:damage?'damage':'draw'}; - return [current,get.effect(current,card,player,player)*(damage?0.7:2)]; - }).sort((a,b)=>b[1]-a[1])[0]; - if(info[1]>0) return info[0]; + prompt: get.prompt("jsrgniluan"), + prompt2: `${ + undamaged.length + ? "选择一张牌弃置并选择一名未对你造成过伤害的角色,你对其造成1点伤害" + : "" + }${undamaged.length && damaged.length ? ";
              或" : ""}${ + damaged.length ? "仅选择一名对你造成过伤害的角色,你令其摸两张牌" : "" + }。`, + damaged: damaged, + aiTarget: (() => { + if ( + undamaged.includes(player) && + !undamaged.some((i) => { + if (i === player) return false; + let att = get.attitude(player, i); + if (att > 0) return true; + return att < 0 && i.getHp(true) + i.hujia < 2; + }) && + (player.hp > 2 || get.damageEffect(player, player, player) >= 0) + ) + return player; + var info = game + .filterPlayer() + .map((current) => { + let damage = undamaged.includes(current), + card = { name: damage ? "damage" : "draw" }; + return [ + current, + get.effect(current, card, player, player) * (damage ? 0.7 : 2), + ]; + }) + .sort((a, b) => b[1] - a[1])[0]; + if (info[1] > 0) return info[0]; return null; })(), - filterCard:lib.filter.cardDiscardable, - selectCard:function(){ - if(get.event('damaged').length==0) return 1; - if(get.event('damaged').length==game.countPlayer()) return 0; - return [0,1]; + filterCard: lib.filter.cardDiscardable, + selectCard: function () { + if (get.event("damaged").length == 0) return 1; + if (get.event("damaged").length == game.countPlayer()) return 0; + return [0, 1]; }, - position:'he', - filterTarget:function(card,player,target){ - var damaged=get.event('damaged'); - return damaged.includes(target)^(ui.selected.cards.length>0); + position: "he", + filterTarget: function (card, player, target) { + var damaged = get.event("damaged"); + return damaged.includes(target) ^ (ui.selected.cards.length > 0); }, - selectTarget:1, - ai1:function(card){ - if(get.event('damaged').includes(get.event('aiTarget'))) return 0; - return 6-get.value(card); + selectTarget: 1, + ai1: function (card) { + if (get.event("damaged").includes(get.event("aiTarget"))) return 0; + return 6 - get.value(card); }, - ai2:function(target){ - return target==get.event('aiTarget')?10:0; + ai2: function (target) { + return target == get.event("aiTarget") ? 10 : 0; }, }); - 'step 1' - if(result.bool){ - var cards=result.cards,target=result.targets[0]; - player.logSkill('jsrgniluan',target); - if(cards&&cards.length){ + "step 1"; + if (result.bool) { + var cards = result.cards, + target = result.targets[0]; + player.logSkill("jsrgniluan", target); + if (cards && cards.length) { player.discard(cards); game.delayex(); target.damage(); - } - else{ + } else { target.draw(2); } } }, }, - jsrghuchou:{ - audio:2, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - const history=_status.globalHistory; - for(let i=history.length-1;i>=0;i--){ - let evts=history[i]['useCard']; - for(let j=evts.length-1;j>=0;j--){ - var evt=evts[j]; - let card=evt.card,targets=evt.targets; - if(!get.tag(card,'damage')||!targets.includes(player)) continue; - return event.player==evt.player; + jsrghuchou: { + audio: 2, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + const history = _status.globalHistory; + for (let i = history.length - 1; i >= 0; i--) { + let evts = history[i]["useCard"]; + for (let j = evts.length - 1; j >= 0; j--) { + var evt = evts[j]; + let card = evt.card, + targets = evt.targets; + if (!get.tag(card, "damage") || !targets.includes(player)) continue; + return event.player == evt.player; } } return false; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num++; }, - ai:{ - damageBonus:true, - skillTagFilter:(player,tag,arg)=>{ - if(tag==='damageBonus'&&arg&&arg.target){ - const history=_status.globalHistory; - for(let i=history.length-1;i>=0;i--){ - let evts=history[i]['useCard']; - for(let j=evts.length-1;j>=0;j--){ - var evt=evts[j]; - let card=evt.card,targets=evt.targets; - if(!get.tag(card,'damage')||!targets.includes(player)) continue; - return arg.target===evt.player; + ai: { + damageBonus: true, + skillTagFilter: (player, tag, arg) => { + if (tag === "damageBonus" && arg && arg.target) { + const history = _status.globalHistory; + for (let i = history.length - 1; i >= 0; i--) { + let evts = history[i]["useCard"]; + for (let j = evts.length - 1; j >= 0; j--) { + var evt = evts[j]; + let card = evt.card, + targets = evt.targets; + if (!get.tag(card, "damage") || !targets.includes(player)) continue; + return arg.target === evt.player; } } return false; } }, - effect:{ - player:(card,player,target)=>{ - if(get.tag(card,'damage')&&target&&lib.skill.jsrghuchou.ai.skillTagFilter(player,'damageBonus',{ - card:card, - target:target - })&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })) return [1,0,2,0]; - } - } - } + effect: { + player: (card, player, target) => { + if ( + get.tag(card, "damage") && + target && + lib.skill.jsrghuchou.ai.skillTagFilter(player, "damageBonus", { + card: card, + target: target, + }) && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + return [1, 0, 2, 0]; + }, + }, + }, }, - jsrgjiemeng:{ - audio:2, - zhuSkill:true, - forced:true, - init:()=>{ - game.addGlobalSkill('jsrgjiemeng_effect'); + jsrgjiemeng: { + audio: 2, + zhuSkill: true, + forced: true, + init: () => { + game.addGlobalSkill("jsrgjiemeng_effect"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('jsrgjiemeng'),true)) game.removeGlobalSkill('jsrgjiemeng_effect'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("jsrgjiemeng"), true)) + game.removeGlobalSkill("jsrgjiemeng_effect"); }, - subSkill:{ - effect:{ - mod:{ - globalFrom:function(from,to,distance){ - if(from.group!='qun') return; - if(to.hasZhuSkill('jsrgjiemeng')) return; - return distance-game.countPlayer(current=>current.group=='qun'); + subSkill: { + effect: { + mod: { + globalFrom: function (from, to, distance) { + if (from.group != "qun") return; + if (to.hasZhuSkill("jsrgjiemeng")) return; + return distance - game.countPlayer((current) => current.group == "qun"); }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('jsrgjiemeng'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("jsrgjiemeng"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("jsrgjiemeng_effect"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('jsrgjiemeng_effect'); - } }, }, }, //张楚 - jsrghuozhong:{ - audio:'dcjizhong', - global:'jsrghuozhong_g', - subSkill:{ - g:{ - audio:'dcjizhong', - enable:'phaseUse', - usable:1, - filter:function (event,player){ - if(player.hasJudge('bingliang')) return false; - if(!game.hasPlayer(current=>current.hasSkill('jsrghuozhong'))) return false; - return player.countCards('hes',card=>get.color(card)=='black'&&get.type2(card)!='trick')>0; + jsrghuozhong: { + audio: "dcjizhong", + global: "jsrghuozhong_g", + subSkill: { + g: { + audio: "dcjizhong", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.hasJudge("bingliang")) return false; + if (!game.hasPlayer((current) => current.hasSkill("jsrghuozhong"))) return false; + return ( + player.countCards( + "hes", + (card) => get.color(card) == "black" && get.type2(card) != "trick" + ) > 0 + ); }, - viewAs:{name:'bingliang'}, - position:'hes', - discard:false, - prompt:function(){ - var list=game.filterPlayer(target=>{ - return target.hasSkill('jsrghuozhong'); + viewAs: { name: "bingliang" }, + position: "hes", + discard: false, + prompt: function () { + var list = game.filterPlayer((target) => { + return target.hasSkill("jsrghuozhong"); }); - return `将一张黑色非锦囊牌当【兵粮寸断】置于自己的判定区,然后令${get.translation(list)}${list.length>1?'中的一人':''}摸两张牌。`; + return `将一张黑色非锦囊牌当【兵粮寸断】置于自己的判定区,然后令${get.translation( + list + )}${list.length > 1 ? "中的一人" : ""}摸两张牌。`; }, - filterCard:function(card,player,event){ - return get.color(card)=='black'&&get.type2(card)!='trick'&&player.canAddJudge({name:'bingliang',cards:[card]}); + filterCard: function (card, player, event) { + return ( + get.color(card) == "black" && + get.type2(card) != "trick" && + player.canAddJudge({ name: "bingliang", cards: [card] }) + ); }, - selectTarget:-1, - filterTarget:function (card,player,target){ - return player==target; + selectTarget: -1, + filterTarget: function (card, player, target) { + return player == target; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - precontent:function*(event,map){ - var player=map.player; - var targets=game.filterPlayer(current=>current.hasSkill('jsrghuozhong')); + precontent: function* (event, map) { + var player = map.player; + var targets = game.filterPlayer((current) => current.hasSkill("jsrghuozhong")); var result; - if(targets.length) result={bool:true,targets:targets}; - else result=yield player.chooseTarget('请选择一名传教士,发动其的【惑众】',true,(card,player,target)=>{ - return get.event('targets').includes(target); - }).set('targets',targets); - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jsrghuozhong',target); - var next=game.createEvent('jsrghuozhong_draw',false); - next.set('player',player); - next.set('target',target); + if (targets.length) result = { bool: true, targets: targets }; + else + result = yield player + .chooseTarget( + "请选择一名传教士,发动其的【惑众】", + true, + (card, player, target) => { + return get.event("targets").includes(target); + } + ) + .set("targets", targets); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jsrghuozhong", target); + var next = game.createEvent("jsrghuozhong_draw", false); + next.set("player", player); + next.set("target", target); event.next.remove(next); event.getParent().after.push(next); - next.setContent(function(){ + next.setContent(function () { target.draw(2); }); } }, - ai:{ - result:{ - player:function(player){ - if(game.hasPlayer(current=>get.attitude(player,current)>2&¤t.hasSkill('jsrghuozhong'))) return 1; + ai: { + result: { + player: function (player) { + if ( + game.hasPlayer( + (current) => + get.attitude(player, current) > 2 && + current.hasSkill("jsrghuozhong") + ) + ) + return 1; return 0; }, }, - order:9, + order: 9, }, }, }, }, - jsrgrihui:{ - audio:'dcrihui', - locked:false, - trigger:{source:'damageSource'}, - filter:function(event,player){ - return event.getParent().type=='card'&&event.card&&event.card.name=='sha'&&game.hasPlayer(current=>{ - return current!=player&¤t.countCards('j'); + jsrgrihui: { + audio: "dcrihui", + locked: false, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return ( + event.getParent().type == "card" && + event.card && + event.card.name == "sha" && + game.hasPlayer((current) => { + return current != player && current.countCards("j"); + }) + ); + }, + prompt: "是否发动【日彗】?", + prompt2: function (event, player) { + var list = game.filterPlayer((current) => { + return current != player && current.countCards("j"); + }); + return `令${get.translation(list)}${list.length > 1 ? "各" : ""}摸一张牌。`; + }, + logTarget: function (event, player) { + return game.filterPlayer((current) => { + return current != player && current.countCards("j"); }); }, - prompt:'是否发动【日彗】?', - prompt2:function(event,player){ - var list=game.filterPlayer(current=>{ - return current!=player&¤t.countCards('j'); - }); - return `令${get.translation(list)}${list.length>1?'各':''}摸一张牌。`; + group: "jsrgrihui_sha", + content: function () { + game.asyncDraw(lib.skill.jsrgrihui.logTarget(trigger, player)); }, - logTarget:function(event,player){ - return game.filterPlayer(current=>{ - return current!=player&¤t.countCards('j'); - }); - }, - group:'jsrgrihui_sha', - content:function(){ - game.asyncDraw(lib.skill.jsrgrihui.logTarget(trigger,player)); - }, - mod:{ - cardUsableTarget:function(card,player,target){ - if(card.name=='sha'&&!player.getStorage('jsrgrihui_targeted').includes(target)) return true; + mod: { + cardUsableTarget: function (card, player, target) { + if (card.name == "sha" && !player.getStorage("jsrgrihui_targeted").includes(target)) + return true; }, }, - subSkill:{ - sha:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - silent:true, - firstDo:true, - content:function(){ - player.addTempSkill('jsrgrihui_targeted'); - player.markAuto('jsrgrihui_targeted',trigger.target); - } + subSkill: { + sha: { + trigger: { player: "useCardToPlayered" }, + forced: true, + silent: true, + firstDo: true, + content: function () { + player.addTempSkill("jsrgrihui_targeted"); + player.markAuto("jsrgrihui_targeted", trigger.target); + }, }, - targeted:{ - charlotte:true, - onremove:true, + targeted: { + charlotte: true, + onremove: true, }, }, }, //夏侯恩 - jsrghujian:{ - audio:'twfujian', - trigger:{ - global:'phaseEnd', + jsrghujian: { + audio: "twfujian", + trigger: { + global: "phaseEnd", }, - filter:function(event,player){ - if(!Array.from(ui.discardPile.childNodes).some(i=>i.name=='chixueqingfeng')) return false; - return game.hasGlobalHistory('everything',evt=>['useCard','respond'].includes(evt.name)&&evt.player.isIn()); + filter: function (event, player) { + if (!Array.from(ui.discardPile.childNodes).some((i) => i.name == "chixueqingfeng")) + return false; + return game.hasGlobalHistory( + "everything", + (evt) => ["useCard", "respond"].includes(evt.name) && evt.player.isIn() + ); }, - popup:false, - forced:true, - locked:false, - group:'jsrghujian_begin', - content:function(){ - 'step 0' - var cards=Array.from(ui.discardPile.childNodes).filter(i=>i.name=='chixueqingfeng'); - if(cards.length){ - event.cards=cards; - var history=_status.globalHistory,target=null; - for(var i=history.length-1;i>=0&&!target;i--){ - var evts=history[i]['everything']; - for(var j=evts.length-1;j>=0;j--){ - var evt=evts[j]; - if(!['useCard','respond'].includes(evt.name)) continue; - target=evt.player; + popup: false, + forced: true, + locked: false, + group: "jsrghujian_begin", + content: function () { + "step 0"; + var cards = Array.from(ui.discardPile.childNodes).filter( + (i) => i.name == "chixueqingfeng" + ); + if (cards.length) { + event.cards = cards; + var history = _status.globalHistory, + target = null; + for (var i = history.length - 1; i >= 0 && !target; i--) { + var evts = history[i]["everything"]; + for (var j = evts.length - 1; j >= 0; j--) { + var evt = evts[j]; + if (!["useCard", "respond"].includes(evt.name)) continue; + target = evt.player; break; } } - if(target&&target.isIn()){ - event.target=target; - target.chooseBool(`是否响应${get.translation(player)}的【护剑】?`,'获得弃牌堆里的【赤血青锋】。'); - } - else event.finish(); - } - else event.finish(); - 'step 1' - if(result.bool){ - player.logSkill('jsrghujian'); + if (target && target.isIn()) { + event.target = target; + target.chooseBool( + `是否响应${get.translation(player)}的【护剑】?`, + "获得弃牌堆里的【赤血青锋】。" + ); + } else event.finish(); + } else event.finish(); + "step 1"; + if (result.bool) { + player.logSkill("jsrghujian"); player.line(target); - target.gain(cards,'gain2'); + target.gain(cards, "gain2"); } }, - subSkill:{ - begin:{ - audio:'twfujian', - trigger:{ - global:'phaseBefore', - player:'enterGame', + subSkill: { + begin: { + audio: "twfujian", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; + }, + content: function () { + player.gain(game.createCard2("chixueqingfeng", "spade", 6), "gain2"); }, - content:function(){ - player.gain(game.createCard2('chixueqingfeng','spade',6),'gain2'); - } }, }, }, - jsrgshili:{ - audio:'twjianwei', - enable:'phaseUse', - usable:1, - viewAs:{ - name:'juedou', + jsrgshili: { + audio: "twjianwei", + enable: "phaseUse", + usable: 1, + viewAs: { + name: "juedou", }, - filterCard:{type:'equip'}, - position:'hs', - viewAsFilter:function(player){ - return player.hasCard({type:'equip'},'hs'); + filterCard: { type: "equip" }, + position: "hs", + viewAsFilter: function (player) { + return player.hasCard({ type: "equip" }, "hs"); }, - check:function(card){ - return (get.name(card,false)=='chixueqingfeng'?20:12)-_status.event.player.getUseValue(card); + check: function (card) { + return ( + (get.name(card, false) == "chixueqingfeng" ? 20 : 12) - + _status.event.player.getUseValue(card) + ); }, - ai:{ - order:0.001, + ai: { + order: 0.001, }, }, //范疆张达 - jsrgfushan:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return game.hasPlayer(i=>i!=player); + jsrgfushan: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return game.hasPlayer((i) => i != player); }, - content:function*(event,map){ - var player=map.player,trigger=map.trigger, targets=game.filterPlayer(i=>i!=player); - var shas=player.mayHaveSha(target,'use',null,'count')-player.getCardUsable('sha',true); - for(var target of targets){ - var att=get.attitude(target,player); - var result=yield target.chooseCard('he',`负山:是否交给${get.translation(player)}一张牌?`,`若如此做,其此阶段使用【杀】的次数上限+1`).set('att',att).set('ai',card=>{ - if(!get.event('goon')) return -get.value(card); - var isSha=get.name(card,get.event('target'))=='sha'; - if(get.event('att')<0) return (isSha?0:5)-get.value(card); - return (isSha?10:0)-get.value(card); - }).set('goon',att>0&&shas>=0||att<0&&target.hp>player.getCardUsable('sha',true)&&shas<-1/Math.max(1,player.hp)).set('target',player); - if(result.bool){ - target.give(result.cards,player); + content: function* (event, map) { + var player = map.player, + trigger = map.trigger, + targets = game.filterPlayer((i) => i != player); + var shas = + player.mayHaveSha(target, "use", null, "count") - player.getCardUsable("sha", true); + for (var target of targets) { + var att = get.attitude(target, player); + var result = yield target + .chooseCard( + "he", + `负山:是否交给${get.translation(player)}一张牌?`, + `若如此做,其此阶段使用【杀】的次数上限+1` + ) + .set("att", att) + .set("ai", (card) => { + if (!get.event("goon")) return -get.value(card); + var isSha = get.name(card, get.event("target")) == "sha"; + if (get.event("att") < 0) return (isSha ? 0 : 5) - get.value(card); + return (isSha ? 10 : 0) - get.value(card); + }) + .set( + "goon", + (att > 0 && shas >= 0) || + (att < 0 && + target.hp > player.getCardUsable("sha", true) && + shas < -1 / Math.max(1, player.hp)) + ) + .set("target", player); + if (result.bool) { + target.give(result.cards, player); target.line(player); - player.addTempSkill('jsrgfushan_sha','phaseAfter'); - player.addMark('jsrgfushan_sha',1,false); - player.markAuto('jsrgfushan_given',target); + player.addTempSkill("jsrgfushan_sha", "phaseAfter"); + player.addMark("jsrgfushan_sha", 1, false); + player.markAuto("jsrgfushan_given", target); } } - player.when('phaseUseAfter').filter((evt=>evt==trigger)).then(()=>{ - player.logSkill('jsrgfushan'); - if(player.getCardUsable('sha',true)>player.getHistory('useCard',evt=>{ - return evt.getParent('phaseUse')==trigger&&evt.card.name=='sha'&&evt.addCount!==false; - }).length&&player.storage.jsrgfushan_given&&player.storage.jsrgfushan_given.every(i=>i.isIn())){ - player.loseHp(2); - } - else{ - player.drawTo(player.maxHp); - } - delete player.storage.jsrgfushan_given; - }); + player + .when("phaseUseAfter") + .filter((evt) => evt == trigger) + .then(() => { + player.logSkill("jsrgfushan"); + if ( + player.getCardUsable("sha", true) > + player.getHistory("useCard", (evt) => { + return ( + evt.getParent("phaseUse") == trigger && + evt.card.name == "sha" && + evt.addCount !== false + ); + }).length && + player.storage.jsrgfushan_given && + player.storage.jsrgfushan_given.every((i) => i.isIn()) + ) { + player.loseHp(2); + } else { + player.drawTo(player.maxHp); + } + delete player.storage.jsrgfushan_given; + }); }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - marktext:'负', - intro:{content:'使用【杀】的次数上限+#'}, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('jsrgfushan_sha'); + subSkill: { + sha: { + charlotte: true, + onremove: true, + marktext: "负", + intro: { content: "使用【杀】的次数上限+#" }, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("jsrgfushan_sha"); }, }, }, @@ -3879,831 +4827,957 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //江山如故·承 //404孙策 - jsrgduxing:{ - audio:2, - enable:'phaseUse', - viewAs:{ - name:'juedou', - storage:{jsrgduxing:true}, - isCard:true, + jsrgduxing: { + audio: 2, + enable: "phaseUse", + viewAs: { + name: "juedou", + storage: { jsrgduxing: true }, + isCard: true, }, - viewAsFilter:function(player){ - if(player.hasSkill('jsrgduxing_used')) return false; + viewAsFilter: function (player) { + if (player.hasSkill("jsrgduxing_used")) return false; }, - filterCard:()=>false, - selectCard:-1, - selectTarget:[1,Infinity], - precontent:function(){ - player.logSkill('jsrgduxing'); + filterCard: () => false, + selectCard: -1, + selectTarget: [1, Infinity], + precontent: function () { + player.logSkill("jsrgduxing"); delete event.result.skill; - var targets=event.result.targets; - for(var target of targets){ - target.addTempSkill('jsrgduxing_allsha'); + var targets = event.result.targets; + for (var target of targets) { + target.addTempSkill("jsrgduxing_allsha"); } - player.addTempSkill('jsrgduxing_restore'); - player.addTempSkill('jsrgduxing_used','phaseUseAfter'); + player.addTempSkill("jsrgduxing_restore"); + player.addTempSkill("jsrgduxing_used", "phaseUseAfter"); }, - ai:{ - order:5, - result:{ - player:function(player,target){ - var eff=Math.sign(get.effect(target,{name:'juedou'},player,player)); - if(player.hasSkillTag('directHit_ai',true,{ - target:target, - card:{name:'juedou'}, - },true)||ui.selected.targets.concat(target).reduce((p,c)=>{ - return p+c.countCards('h'); - },0) { + return p + c.countCards("h"); + }, 0) < player.countCards("h", "sha") + ) { return 0; } return -114514; }, - target:-1.5, - } + target: -1.5, + }, }, - subSkill:{ - allsha:{ - charlotte:true, - mod:{ - cardname:function(card,player,name){ - return 'sha'; + subSkill: { + allsha: { + charlotte: true, + mod: { + cardname: function (card, player, name) { + return "sha"; }, - } - }, - used:{ - charlotte:true, - }, - restore:{ - charlotte:true, - trigger:{ - global:'useCardAfter', }, - forced:true, - popup:false, - forceDie:true, - forceOut:true, - filter:function(event,player){ - return event.card.name=='juedou'&&event.card.storage&&event.card.storage.jsrgduxing; + }, + used: { + charlotte: true, + }, + restore: { + charlotte: true, + trigger: { + global: "useCardAfter", + }, + forced: true, + popup: false, + forceDie: true, + forceOut: true, + filter: function (event, player) { + return ( + event.card.name == "juedou" && + event.card.storage && + event.card.storage.jsrgduxing + ); + }, + content: function () { + game.countPlayer((current) => { + current.removeSkill("jsrgduxing_allsha"); + }, true); }, - content:function(){ - game.countPlayer(current=>{ - current.removeSkill('jsrgduxing_allsha'); - },true); - } }, }, }, - jsrgzhiheng:{ - audio:2, - trigger:{ - source:'damageBegin1', + jsrgzhiheng: { + audio: 2, + trigger: { + source: "damageBegin1", }, - forced:true, - filter:function(event,player){ - if(event.getParent().type!='card') return false; - var respondEvts=[]; - respondEvts.addArray(event.player.getHistory('useCard')).addArray(event.player.getHistory('respond')); - respondEvts=respondEvts.filter(i=>i.respondTo).map(evt=>evt.respondTo); - return respondEvts.some(list=>{ - return list[0]==player; + forced: true, + filter: function (event, player) { + if (event.getParent().type != "card") return false; + var respondEvts = []; + respondEvts + .addArray(event.player.getHistory("useCard")) + .addArray(event.player.getHistory("respond")); + respondEvts = respondEvts.filter((i) => i.respondTo).map((evt) => evt.respondTo); + return respondEvts.some((list) => { + return list[0] == player; }); }, - content:function(){ + content: function () { trigger.num++; }, }, - jsrgzhasi:{ - audio:2, - trigger:{ - player:'damageBegin4', + jsrgzhasi: { + audio: 2, + trigger: { + player: "damageBegin4", }, - limited:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - return event.num>=player.getHp(); + limited: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + return event.num >= player.getHp(); }, - content:function(){ - player.awakenSkill('jsrgzhasi'); + content: function () { + player.awakenSkill("jsrgzhasi"); trigger.cancel(); - player.changeSkills(['rezhiheng'],['jsrgzhiheng']); - player.addSkill('jsrgzhasi_undist'); + player.changeSkills(["rezhiheng"], ["jsrgzhiheng"]); + player.addSkill("jsrgzhasi_undist"); }, - derivation:'rezhiheng', - subSkill:{ - undist:{ - group:'undist', - trigger:{ - player:['useCardAfter','damageEnd'], + derivation: "rezhiheng", + subSkill: { + undist: { + group: "undist", + trigger: { + player: ["useCardAfter", "damageEnd"], }, - filter:function(event,player){ - if(event.name=='useCard') return event.targets.some(target=>{ - return target!=player; - }); + filter: function (event, player) { + if (event.name == "useCard") + return event.targets.some((target) => { + return target != player; + }); return true; }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - player.removeSkill('jsrgzhasi_undist'); + forced: true, + popup: false, + charlotte: true, + content: function () { + player.removeSkill("jsrgzhasi_undist"); }, - mark:true, - intro:{ - content:'诈死中,不计入距离和座次的计算', + mark: true, + intro: { + content: "诈死中,不计入距离和座次的计算", }, }, }, }, - jsrgbashi:{ - audio:2, - trigger:{player:'chooseToRespondBefore'}, - zhuSkill:true, - filter:function(event,player){ - if(event.responded) return false; - if(player.storage.jsrgbashiing) return false; - if(!player.hasZhuSkill('jsrgbashi')) return false; - if(!event.filterCard({name:'sha'},player,event)&&!event.filterCard({name:'shan'},player,event)) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wu'; + jsrgbashi: { + audio: 2, + trigger: { player: "chooseToRespondBefore" }, + zhuSkill: true, + filter: function (event, player) { + if (event.responded) return false; + if (player.storage.jsrgbashiing) return false; + if (!player.hasZhuSkill("jsrgbashi")) return false; + if ( + !event.filterCard({ name: "sha" }, player, event) && + !event.filterCard({ name: "shan" }, player, event) + ) + return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wu"; }); }, - check:function(event,player){ - if(get.damageEffect(player,event.player,player)>=0) return false; + check: function (event, player) { + if (get.damageEffect(player, event.player, player) >= 0) return false; return true; }, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(); - 'step 1' - var target=event.targets.shift(); - event.target=target; - if(!target) event.finish(); - else if(!target.isIn()||target==player) event.redo(); - else if(target.group=='wu'){ - if((target==game.me&&!_status.auto)||( - get.attitude(target,player)>2)|| - target.isOnline()){ - player.storage.jsrgbashiing=true; - var list=['sha','shan'].filter(name=>trigger.filterCard({name:name},player,trigger)); - 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; - return (get.attitude(event.player,event.source)-2); + content: function () { + "step 0"; + event.targets = game.filterPlayer(); + "step 1"; + var target = event.targets.shift(); + event.target = target; + if (!target) event.finish(); + else if (!target.isIn() || target == player) event.redo(); + else if (target.group == "wu") { + if ( + (target == game.me && !_status.auto) || + get.attitude(target, player) > 2 || + target.isOnline() + ) { + player.storage.jsrgbashiing = true; + var list = ["sha", "shan"].filter((name) => + trigger.filterCard({ name: name }, player, trigger) + ); + 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; + return get.attitude(event.player, event.source) - 2; }); - next.set('skillwarn','替'+get.translation(player)+'打出一张'+names); - next.autochoose=function(){ - if(!lib.filter.autoRespondSha.apply(this,arguments)) return false; - return lib.filter.autoRespondShan.apply(this,arguments); + next.set("skillwarn", "替" + get.translation(player) + "打出一张" + names); + next.autochoose = function () { + if (!lib.filter.autoRespondSha.apply(this, arguments)) return false; + return lib.filter.autoRespondShan.apply(this, arguments); }; - next.set('source',player); + next.set("source", player); } } - 'step 2' + "step 2"; delete player.storage.jsrgbashiing; - if(result.bool){ + if (result.bool) { event.finish(); - var name=result.card.name; - trigger.result={bool:true,card:{name:name,isCard:true}}; - trigger.responded=true; - trigger.animate=false; - if(typeof target.ai.shown=='number'&&target.ai.shown<0.95){ - target.ai.shown+=0.3; - if(target.ai.shown>0.95) target.ai.shown=0.95; + var name = result.card.name; + trigger.result = { bool: true, card: { name: name, isCard: true } }; + trigger.responded = true; + trigger.animate = false; + if (typeof target.ai.shown == "number" && target.ai.shown < 0.95) { + target.ai.shown += 0.3; + if (target.ai.shown > 0.95) target.ai.shown = 0.95; } - } - else{ + } else { event.goto(1); } }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='use') return false; - if(player.storage.jsrgbashiing) return false; - if(!player.hasZhuSkill('jsrgbashi')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wu'; + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "use") return false; + if (player.storage.jsrgbashiing) return false; + if (!player.hasZhuSkill("jsrgbashi")) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wu"; }); }, }, }, //许攸 - jsrglipan:{ - audio:2, - trigger:{ - player:'phaseEnd', + jsrglipan: { + forbid: ["guozhan"], + audio: 2, + trigger: { + player: "phaseEnd", }, - direct:true, - content:function(){ - 'step 0' - var list=lib.group.slice(); + direct: true, + content: function () { + "step 0"; + var list = lib.group.slice(); list.remove(player.group); - var getV=function(group){ - var val=1; - if(group=='wei'||group=='qun') val++; - game.countPlayer(current=>{ - if(current.group!=group) return false; - var att=get.attitude(player,current); - if(att>0) val++; - else if(att==0) val+=0.5; + var getV = function (group) { + var val = 1; + if (group == "wei" || group == "qun") val++; + game.countPlayer((current) => { + if (current.group != group) return false; + var att = get.attitude(player, current); + if (att > 0) val++; + else if (att == 0) val += 0.5; else val--; }); return val; }; - var maxGroup=list.slice().sort((a,b)=>{ - return getV(b)-getV(a); + var maxGroup = list.slice().sort((a, b) => { + return getV(b) - getV(a); })[0]; - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('jsrglipan')).set('prompt2','变更为另一个势力').set('ai',()=>{ - return _status.event.choice; - }).set('choice',maxGroup); - 'step 1' - var group=result.control; - if(group=='cancel2') return; - player.logSkill('jsrglipan'); - player.popup(group+'2',get.groupnature(group,'raw')); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("jsrglipan")) + .set("prompt2", "变更为另一个势力") + .set("ai", () => { + return _status.event.choice; + }) + .set("choice", maxGroup); + "step 1"; + var group = result.control; + if (group == "cancel2") return; + player.logSkill("jsrglipan"); + player.popup(group + "2", get.groupnature(group, "raw")); player.changeGroup(group); - var num=game.countPlayer(current=>{ - return current.group==group&¤t!=player; + var num = game.countPlayer((current) => { + return current.group == group && current != player; }); - if(num>0) player.draw(num); - var next=player.phaseUse(); - next.jsrglipan=true; + if (num > 0) player.draw(num); + var next = player.phaseUse(); + next.jsrglipan = true; event.next.remove(next); trigger.next.push(next); - player.addTempSkill('jsrglipan_backfire'); + player.addTempSkill("jsrglipan_backfire"); }, - subSkill:{ - backfire:{ - trigger:{ - player:'phaseUseEnd', + subSkill: { + backfire: { + trigger: { + player: "phaseUseEnd", }, - charlotte:true, - forced:true, - popup:false, - filter:function(event,player){ + charlotte: true, + forced: true, + popup: false, + filter: function (event, player) { return event.jsrglipan; }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - return current.group==player.group; + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => { + return current.group == player.group; }); targets.sortBySeat(); - event.targets=targets; - 'step 1' - var target=targets.shift(); - event.target=target; - if(target&&target.isIn()&&target.canUse({name:'juedou'},player)){ + event.targets = targets; + "step 1"; + var target = targets.shift(); + event.target = target; + if (target && target.isIn() && target.canUse({ name: "juedou" }, player)) { target.chooseCardTarget({ - position:'hes', - prompt:'是否将一张牌当【决斗】对'+get.translation(player)+'使用?', - filterCard:function(card,player){ - return player.canUse(get.autoViewAs({name:'juedou'},[card]),_status.event.getParent().player); + position: "hes", + prompt: "是否将一张牌当【决斗】对" + get.translation(player) + "使用?", + filterCard: function (card, player) { + return player.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + _status.event.getParent().player + ); }, - filterTarget:function(card,player,target){ - var source=_status.event.getParent().player; - if(target!=source&&!ui.selected.targets.includes(source)) return false; - card=get.autoViewAs({name:'juedou'},[card]); - return lib.filter.filterTarget.apply(this,arguments); + filterTarget: function (card, player, target) { + var source = _status.event.getParent().player; + if (target != source && !ui.selected.targets.includes(source)) + return false; + card = get.autoViewAs({ name: "juedou" }, [card]); + return lib.filter.filterTarget.apply(this, arguments); }, - selectTarget:function(){ - var card=get.card(),player=get.player(); - if(!card) return; - card=get.autoViewAs({name:'juedou'},[card]); - var range=[1,1]; - game.checkMod(card,player,range,'selectTarget',player); + selectTarget: function () { + var card = get.card(), + player = get.player(); + if (!card) return; + card = get.autoViewAs({ name: "juedou" }, [card]); + var range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); return range; }, - ai1:function(card){ - var player=_status.event.player,target=_status.event.getParent().player; - var eff=get.effect(target,get.autoViewAs({name:'juedou'},[card]),player,player); - if(eff<=0) return 0; - return (player.hp==1?10:6)-get.value(card); + ai1: function (card) { + var player = _status.event.player, + target = _status.event.getParent().player; + var eff = get.effect( + target, + get.autoViewAs({ name: "juedou" }, [card]), + player, + player + ); + if (eff <= 0) return 0; + return (player.hp == 1 ? 10 : 6) - get.value(card); + }, + ai2: function (target) { + if (target == _status.event.getParent().player) return 100; + return get.effect(target, { name: "juedou" }, _status.event.player); }, - ai2:function(target){ - if(target==_status.event.getParent().player) return 100; - return get.effect(target,{name:'juedou'},_status.event.player); - } }); } - 'step 2' - if(result.bool){ - var cards=result.cards; - var cardx=get.autoViewAs({name:'juedou'},cards); - var targets=result.targets.filter(targetx=>{ - return target.canUse(cardx,targetx); + "step 2"; + if (result.bool) { + var cards = result.cards; + var cardx = get.autoViewAs({ name: "juedou" }, cards); + var targets = result.targets.filter((targetx) => { + return target.canUse(cardx, targetx); }); - if(targets.length) target.useCard(cardx,cards,targets); + if (targets.length) target.useCard(cardx, cards, targets); } - if(targets.length) event.goto(1); - } - } + if (targets.length) event.goto(1); + }, + }, }, }, - jsrgqingxi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(player.group!='qun') return false; - return game.hasPlayer(current=>lib.skill.jsrgqingxi.filterTarget('',player,current)); + jsrgqingxi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (player.group != "qun") return false; + return game.hasPlayer((current) => + lib.skill.jsrgqingxi.filterTarget("", player, current) + ); }, - groupSkill:true, - filterTarget:function(card,player,target){ - if(target.countCards('h')>=player.countCards('h')) return false; - return !player.getStorage('jsrgqingxi_used').includes(target); + groupSkill: true, + filterTarget: function (card, player, target) { + if (target.countCards("h") >= player.countCards("h")) return false; + return !player.getStorage("jsrgqingxi_used").includes(target); }, - content:function(){ - 'step 0' - player.addTempSkill('jsrgqingxi_used','phaseUseAfter'); - player.markAuto('jsrgqingxi_used',[target]); - var num=player.countCards('h')-target.countCards('h'); - if(num>0) player.chooseToDiscard(num,true,'轻袭:弃置'+get.cnNumber(num)+'张手牌'); - 'step 1' - var card={ - name:'sha', - nature:'stab', - isCard:true, + content: function () { + "step 0"; + player.addTempSkill("jsrgqingxi_used", "phaseUseAfter"); + player.markAuto("jsrgqingxi_used", [target]); + var num = player.countCards("h") - target.countCards("h"); + if (num > 0) + player.chooseToDiscard(num, true, "轻袭:弃置" + get.cnNumber(num) + "张手牌"); + "step 1"; + var card = { + name: "sha", + nature: "stab", + isCard: true, }; - if(player.canUse(card,target,false)) player.useCard(card,target,false); + if (player.canUse(card, target, false)) player.useCard(card, target, false); }, - ai:{ - order:8, - result:{ - target:(player,target)=>{ - let num=player.countCards('h')-target.countCards('h'), - eff=get.effect(target,{name:'sha',nature:'stab'},player,target), - val=0, - ph=_status.event.getTempCache('jsrgqingxi_result','ph'); - if(!ph){ - ph=player.getCards('h').sort((a,b)=>{ - return get.value(a)-get.value(b); + ai: { + order: 8, + result: { + target: (player, target) => { + let num = player.countCards("h") - target.countCards("h"), + eff = get.effect(target, { name: "sha", nature: "stab" }, player, target), + val = 0, + ph = _status.event.getTempCache("jsrgqingxi_result", "ph"); + if (!ph) { + ph = player.getCards("h").sort((a, b) => { + return get.value(a) - get.value(b); }); - _status.event.putTempCache('jsrgqingxi_result','ph',ph); + _status.event.putTempCache("jsrgqingxi_result", "ph", ph); } - ph.slice(0,num).forEach(i=>{ - val+=get.value(i,player); + ph.slice(0, num).forEach((i) => { + val += get.value(i, player); }); - eff=Math.sign(eff)*Math.sqrt(Math.abs(eff)); - if(val>2*Math.abs(eff)) return 0; - return eff/num; - } - } + eff = Math.sign(eff) * Math.sqrt(Math.abs(eff)); + if (val > 2 * Math.abs(eff)) return 0; + return eff / num; + }, + }, }, - subSkill:{ - used:{ - onremove:true, - charlotte:true, - } + subSkill: { + used: { + onremove: true, + charlotte: true, + }, }, }, - jsrgjinmie:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.group!='wei') return false; - return game.hasPlayer(current=>current.countCards('h')>player.countCards('h')); + jsrgjinmie: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.group != "wei") return false; + return game.hasPlayer((current) => current.countCards("h") > player.countCards("h")); }, - groupSkill:true, - filterTarget:function(card,player,target){ - return target.countCards('h')>player.countCards('h'); + groupSkill: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > player.countCards("h"); }, - content:function(){ - 'step 0' - var card={ - name:'sha', - nature:'fire', - storage:{jsrgjinmie:target}, - isCard:true, + content: function () { + "step 0"; + var card = { + name: "sha", + nature: "fire", + storage: { jsrgjinmie: target }, + isCard: true, }; - if(player.canUse(card,target,false)){ - player.useCard(card,target,false); - player.addTempSkill('jsrgjinmie_effect'); + if (player.canUse(card, target, false)) { + player.useCard(card, target, false); + player.addTempSkill("jsrgjinmie_effect"); } }, - ai:{ - order:0.5, - result:{ - target:function(player,target){ - var eff=get.effect(target,{name:'sha',nature:'fire'},player,target)/30; - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) eff*=2; - var del=target.countCards('h')-player.countCards('h')+1.5; - eff*=Math.sqrt(del); + ai: { + order: 0.5, + result: { + target: function (player, target) { + var eff = + get.effect(target, { name: "sha", nature: "fire" }, player, target) / 30; + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + eff *= 2; + var del = target.countCards("h") - player.countCards("h") + 1.5; + eff *= Math.sqrt(del); return eff; - } - } + }, + }, }, - subSkill:{ - effect:{ - trigger:{ - source:'damageSource', + subSkill: { + effect: { + trigger: { + source: "damageSource", }, - filter:function(event,player){ - return event.card&&event.card.storage&&event.card.storage.jsrgjinmie&&event.card.storage.jsrgjinmie.isIn(); + filter: function (event, player) { + return ( + event.card && + event.card.storage && + event.card.storage.jsrgjinmie && + event.card.storage.jsrgjinmie.isIn() + ); }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - 'step 0' - var target=trigger.card.storage.jsrgjinmie; - var del=target.countCards('h')-player.countCards('h'); - if(del>0){ + forced: true, + popup: false, + charlotte: true, + content: function () { + "step 0"; + var target = trigger.card.storage.jsrgjinmie; + var del = target.countCards("h") - player.countCards("h"); + if (del > 0) { player.line(target); - player.discardPlayerCard(target,'h',true,del); + player.discardPlayerCard(target, "h", true, del); } // else if(del<0){ // player.line(target); // target.draw(-del); // } - } - } + }, + }, }, }, //吕布 - jsrgwuchang:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + jsrgwuchang: { + forbid: ["guozhan"], + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - var cards=event.getg(player); - if(!cards.length) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; + forced: true, + filter: function (event, player) { + var cards = event.getg(player); + if (!cards.length) return false; + return game.hasPlayer((current) => { + if (current == player) return false; return event.getl(current).cards2.length; }); }, - group:'jsrgwuchang_add', - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - if(current==player) return false; + group: "jsrgwuchang_add", + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => { + if (current == player) return false; return trigger.getl(current).cards2.length; }); - var target=targets[0]; + var target = targets[0]; player.changeGroup(target.group); - player.popup(target.group+'2',get.groupnature(target.group,'raw')); + player.popup(target.group + "2", get.groupnature(target.group, "raw")); }, - subSkill:{ - add:{ - trigger:{ - source:'damageBegin1', + subSkill: { + add: { + trigger: { + source: "damageBegin1", }, - filter:function(event,player){ - if(!event.card||!['sha','juedou'].includes(event.card.name)||event.getParent().type!='card') return false; - return event.player.group==player.group; + filter: function (event, player) { + if ( + !event.card || + !["sha", "juedou"].includes(event.card.name) || + event.getParent().type != "card" + ) + return false; + return event.player.group == player.group; }, - forced:true, - content:function(){ - 'step 0' + forced: true, + content: function () { + "step 0"; trigger.num++; - var group='qun'; + var group = "qun"; player.changeGroup(group); - player.popup(group+'2',get.groupnature(group,'raw')); - }, - } - }, - }, - jsrgqingjiao:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(player.group!='qun') return false; - if(!player.countCards('hes')) return false; - return !player.hasSkill('jsrgqingjiao_tuixinzhifu')&&game.hasPlayer(current=>{ - return current.countCards('h')>player.countCards('h'); - })||!player.hasSkill('jsrgqingjiao_chenghuodajie')&&game.hasPlayer(current=>{ - return current.countCards('h')0?'tuixinzhifu':'chenghuodajie'; - if(player.hasSkill('jsrgqingjiao_'+name)) return false; - return player.canUse({name:name,cards:ui.selected.cards},target); - }, - content:function(){ - var del=target.countCards('h')-player.countCards('h'); - var name=del>0?'tuixinzhifu':'chenghuodajie'; - player.useCard({name:name},target,cards); - player.addTempSkill('jsrgqingjiao_'+name,'phaseUseAfter'); - }, - ai:{ - order:7, - result:{ - player:function(player,target){ - var name=(target.countCards('h')>player.countCards('h')?'tuixinzhifu':'chenghuodajie'); - var list=[]; - if(ui.selected.cards.length) list.addArray(ui.selected.cards); - var card=get.autoViewAs({name:name},list); - return get.effect(target,card,player,player); + player.popup(group + "2", get.groupnature(group, "raw")); }, }, }, - subSkill:{ - tuixinzhifu:{ - charlotte:true, - }, - chenghuodajie:{ - charlotte:true, - }, - } }, - jsrgchengxu:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - locked:false, - filter:function(event,player){ - if(player.group!='shu') return false; - return game.hasPlayer(current=>{ - return current!=player&¤t.group==player.group; + jsrgqingjiao: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (player.group != "qun") return false; + if (!player.countCards("hes")) return false; + return ( + (!player.hasSkill("jsrgqingjiao_tuixinzhifu") && + game.hasPlayer((current) => { + return current.countCards("h") > player.countCards("h"); + })) || + (!player.hasSkill("jsrgqingjiao_chenghuodajie") && + game.hasPlayer((current) => { + return current.countCards("h") < player.countCards("h"); + })) + ); + }, + groupSkill: true, + position: "hes", + filterCard: true, + selectCard: 1, + discard: false, + lose: false, + delay: false, + filterTarget: function (card, player, target) { + var mod = game.checkMod( + ui.selected.cards[0], + player, + "unchanged", + "cardEnabled2", + player + ); + if (!mod) return false; + var del = target.countCards("h") - player.countCards("h"); + if (del == 0) return false; + var name = del > 0 ? "tuixinzhifu" : "chenghuodajie"; + if (player.hasSkill("jsrgqingjiao_" + name)) return false; + return player.canUse({ name: name, cards: ui.selected.cards }, target); + }, + content: function () { + var del = target.countCards("h") - player.countCards("h"); + var name = del > 0 ? "tuixinzhifu" : "chenghuodajie"; + player.useCard({ name: name }, target, cards); + player.addTempSkill("jsrgqingjiao_" + name, "phaseUseAfter"); + }, + ai: { + order: 7, + result: { + player: function (player, target) { + var name = + target.countCards("h") > player.countCards("h") + ? "tuixinzhifu" + : "chenghuodajie"; + var list = []; + if (ui.selected.cards.length) list.addArray(ui.selected.cards); + var card = get.autoViewAs({ name: name }, list); + return get.effect(target, card, player, player); + }, + }, + }, + subSkill: { + tuixinzhifu: { + charlotte: true, + }, + chenghuodajie: { + charlotte: true, + }, + }, + }, + jsrgchengxu: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + locked: false, + filter: function (event, player) { + if (player.group != "shu") return false; + return game.hasPlayer((current) => { + return current != player && current.group == player.group; }); }, - groupSkill:true, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(current=>{ - return current!=player&¤t.group==player.group; - })); + groupSkill: true, + content: function () { + trigger.directHit.addArray( + game.filterPlayer((current) => { + return current != player && current.group == player.group; + }) + ); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return player.group=='shu'&&player.group==arg.target.group; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return player.group == "shu" && player.group == arg.target.group; }, }, }, //张郃 - jsrgqiongtu:{ - audio:2, - enable:'chooseToUse', - groupSkill:true, - viewAs:{ - name:'wuxie', - suit:'none', - number:null, - isCard:true, + jsrgqiongtu: { + audio: 2, + enable: "chooseToUse", + groupSkill: true, + viewAs: { + name: "wuxie", + suit: "none", + number: null, + isCard: true, }, - filter:function(event,player){ - if(!player.countCards('he',card=>_status.connectMode||get.type(card)!='basic')) return false; - return player.group=='qun'&&!player.hasSkill('jsrgqiongtu_check'); + filter: function (event, player) { + if (!player.countCards("he", (card) => _status.connectMode || get.type(card) != "basic")) + return false; + return player.group == "qun" && !player.hasSkill("jsrgqiongtu_check"); }, - viewAsFilter:function(player){ - if(!player.countCards('he',card=>_status.connectMode||get.type(card)!='basic')) return false; - return player.group=='qun'&&!player.hasSkill('jsrgqiongtu_check'); + viewAsFilter: function (player) { + if (!player.countCards("he", (card) => _status.connectMode || get.type(card) != "basic")) + return false; + return player.group == "qun" && !player.hasSkill("jsrgqiongtu_check"); }, - filterCard:function(card){ - return get.type(card)!='basic'; + filterCard: function (card) { + return get.type(card) != "basic"; }, - position:'he', - popname:true, - ignoreMod:true, - precontent:function(){ - 'step 0' - player.logSkill('jsrgqiongtu'); + position: "he", + popname: true, + ignoreMod: true, + precontent: function () { + "step 0"; + player.logSkill("jsrgqiongtu"); delete event.result.skill; - var card=event.result.cards[0]; - event.card=card; - event.result.card={ - name:event.result.card.name, - storage:{jsrgqiongtu:true}, - isCard:true, + var card = event.result.cards[0]; + event.card = card; + event.result.card = { + name: event.result.card.name, + storage: { jsrgqiongtu: true }, + isCard: true, }; - event.result.cards=[]; - player.addToExpansion(card,player,'give').gaintag.add('jsrgqiongtu'); - player.addTempSkill('jsrgqiongtu_check'); + event.result.cards = []; + player.addToExpansion(card, player, "give").gaintag.add("jsrgqiongtu"); + player.addTempSkill("jsrgqiongtu_check"); }, - marktext:'途', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "途", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage[skill]; }, - subSkill:{ - check:{ - trigger:{ - global:'useCardAfter', + subSkill: { + check: { + trigger: { + global: "useCardAfter", }, - filter:function(event,player){ - return event.card.name=='wuxie'&&event.card.storage&&event.card.storage.jsrgqiongtu; + filter: function (event, player) { + return ( + event.card.name == "wuxie" && + event.card.storage && + event.card.storage.jsrgqiongtu + ); }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - 'step 0' + forced: true, + popup: false, + charlotte: true, + content: function () { + "step 0"; game.delayx(); - var evt=trigger.getParent(4); - if(evt.name=='phaseJudge'){ - state=evt.cancelled; + var evt = trigger.getParent(4); + if (evt.name == "phaseJudge") { + state = evt.cancelled; + } else { + state = evt._neutralized; } - else{ - state=evt._neutralized; - } - if(state){ + if (state) { player.draw(); + } else { + player.changeGroup("wei"); + var cards = player.getExpansions("jsrgqiongtu"); + if (cards.length) player.gain(cards, "gain2"); } - else{ - player.changeGroup('wei'); - var cards=player.getExpansions('jsrgqiongtu'); - if(cards.length) player.gain(cards,'gain2'); - } - } + }, }, }, }, - jsrgxianzhu:{ - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - return player.group=='wei'&&player.hasCard(card=>{ - return _status.connectMode||get.type(card)=='trick'; - },'hs'); + jsrgxianzhu: { + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + return ( + player.group == "wei" && + player.hasCard((card) => { + return _status.connectMode || get.type(card) == "trick"; + }, "hs") + ); }, - groupSkill:true, - locked:false, - viewAs:{ - name:'sha', - storage:{jsrgxianzhu:true}, + groupSkill: true, + locked: false, + viewAs: { + name: "sha", + storage: { jsrgxianzhu: true }, }, - position:'hs', - filterCard:function(card){ - return get.type(card)=='trick'; + position: "hs", + filterCard: function (card) { + return get.type(card) == "trick"; }, - check:function(card){ - var player=_status.event.player; - var cardx={ - name:'sha', - storage:{jsrgxianzhu:true}, - cards:[card], - } - if(game.hasPlayer(current=>{ - return player.canUse(cardx,current)&&get.effect(current,card,player,player)>0&&get.effect(current,cardx,player,player)>0; - })) return 15-get.value(card); + check: function (card) { + var player = _status.event.player; + var cardx = { + name: "sha", + storage: { jsrgxianzhu: true }, + cards: [card], + }; + if ( + game.hasPlayer((current) => { + return ( + player.canUse(cardx, current) && + get.effect(current, card, player, player) > 0 && + get.effect(current, cardx, player, player) > 0 + ); + }) + ) + return 15 - get.value(card); return 0; }, - onuse:function(links,player){ - player.addTempSkill('jsrgxianzhu_after'); + onuse: function (links, player) { + player.addTempSkill("jsrgxianzhu_after"); }, - mod:{ - cardUsable:function(card){ - if(card.storage&&card.storage.jsrgxianzhu) return Infinity; + mod: { + cardUsable: function (card) { + if (card.storage && card.storage.jsrgxianzhu) return Infinity; }, }, - subSkill:{ - after:{ - trigger:{ - global:'damageSource', + subSkill: { + after: { + trigger: { + global: "damageSource", }, - filter:function(event,player){ - var targets=event.getParent(2).targets; - if(!targets||targets.length!=1) return false; - if(!event.card||!event.card.storage||!event.card.storage.jsrgxianzhu) return false; - var target=event.player,card=event.cards[0]; - if(!target.isIn()) return false; - if(get.type(card)!='trick') return false; - if(!player.canUse(card,target,false)) return false; + filter: function (event, player) { + var targets = event.getParent(2).targets; + if (!targets || targets.length != 1) return false; + if (!event.card || !event.card.storage || !event.card.storage.jsrgxianzhu) + return false; + var target = event.player, + card = event.cards[0]; + if (!target.isIn()) return false; + if (get.type(card) != "trick") return false; + if (!player.canUse(card, target, false)) return false; return true; }, - forced:true, - charlotte:true, - group:'jsrgxianzhu_inf', - content:function(){ - var card={ - name:trigger.cards[0].name, - isCard:true, - } - player.useCard(card,trigger.player,false); + forced: true, + charlotte: true, + group: "jsrgxianzhu_inf", + content: function () { + var card = { + name: trigger.cards[0].name, + isCard: true, + }; + player.useCard(card, trigger.player, false); game.delayx(); }, }, - inf:{ - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(event.card.storage&&event.card.storage.jsrgxianzhu&&event.addCount!==false) return true; + inf: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if ( + event.card.storage && + event.card.storage.jsrgxianzhu && + event.addCount !== false + ) + return true; return false; }, - content:function(){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + content: function () { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; }, }, }, }, //邹氏 - jsrgguyin:{ - audio:2, - trigger:{ - player:'phaseZhunbeiBegin', + jsrgguyin: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", }, - check:function(event,player){ - return player.isTurnedOver()||game.countPlayer2(current=>current.hasSex('male'))>=2; + check: function (event, player) { + return ( + player.isTurnedOver() || game.countPlayer2((current) => current.hasSex("male")) >= 2 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.turnOver(); - 'step 1' - var targets=game.filterPlayer(current=>current!=player&¤t.hasSex('male')); - event.targets=targets; + "step 1"; + var targets = game.filterPlayer((current) => current != player && current.hasSex("male")); + event.targets = targets; player.line(targets); game.delayx(); - 'step 2' - var target=targets.shift(); - event.target=target; - target.chooseBool('是否响应'+get.translation(player)+'的【孤吟】?','你可以翻面。').set('ai',()=>{ - return _status.event.bool; - }).set('bool',function(){ - return target.isTurnedOver()||get.attitude(target,player)>0&&(game.countPlayer2(current=>current.hasSex('male'))>=3||target.getHp()<=1&&player.hasSkill('jsrgzhangdeng')); - }()); - 'step 3' - if(result.bool){ + "step 2"; + var target = targets.shift(); + event.target = target; + target + .chooseBool("是否响应" + get.translation(player) + "的【孤吟】?", "你可以翻面。") + .set("ai", () => { + return _status.event.bool; + }) + .set( + "bool", + (function () { + return ( + target.isTurnedOver() || + (get.attitude(target, player) > 0 && + (game.countPlayer2((current) => current.hasSex("male")) >= 3 || + (target.getHp() <= 1 && player.hasSkill("jsrgzhangdeng")))) + ); + })() + ); + "step 3"; + if (result.bool) { target.turnOver(); } - if(targets.length) event.goto(2); - 'step 4' - var targets=game.filterPlayer(current=>{ - return current==player||current.isTurnedOver(); + if (targets.length) event.goto(2); + "step 4"; + var targets = game.filterPlayer((current) => { + return current == player || current.isTurnedOver(); }); - event.targets=targets; - event.num=0; - event.index=0; - 'step 5' - var target=targets[event.index]; - if(target.isIn()){ + event.targets = targets; + event.num = 0; + event.index = 0; + "step 5"; + var target = targets[event.index]; + if (target.isIn()) { target.draw(); event.num++; } event.index++; - if(event.index>=targets.length) event.index=0; - 'step 6' - if(event.num>=game.countPlayer2(current=>current.hasSex('male'))) event.finish(); + if (event.index >= targets.length) event.index = 0; + "step 6"; + if (event.num >= game.countPlayer2((current) => current.hasSex("male"))) event.finish(); else event.goto(5); }, }, - jsrgzhangdeng:{ - audio:2, - trigger:{ - global:'logSkill', + jsrgzhangdeng: { + audio: 2, + trigger: { + global: "logSkill", }, - filter:function(event,player){ - return event.player.getHistory('useSkill',evt=>{ - return evt.skill=='jsrgzhangdeng_jiu'; - }).map(evt=>evt.event).indexOf(event.log_event)==1; + filter: function (event, player) { + return ( + event.player + .getHistory("useSkill", (evt) => { + return evt.skill == "jsrgzhangdeng_jiu"; + }) + .map((evt) => evt.event) + .indexOf(event.log_event) == 1 + ); }, - global:'jsrgzhangdeng_jiu', - forced:true, - locked:false, - content:function(){ + global: "jsrgzhangdeng_jiu", + forced: true, + locked: false, + content: function () { player.turnOver(false); }, - subSkill:{ - jiu:{ - audio:'jsrgzhangdeng', - enable:'chooseToUse', - filter:function(event,player){ - return player.isTurnedOver()&&game.hasPlayer(current=>{ - return current.hasSkill('jsrgzhangdeng')&¤t.isTurnedOver(); - }); + subSkill: { + jiu: { + audio: "jsrgzhangdeng", + enable: "chooseToUse", + filter: function (event, player) { + return ( + player.isTurnedOver() && + game.hasPlayer((current) => { + return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver(); + }) + ); }, - viewAs:{name:'jiu',isCard:true}, - viewAsFilter:function(player){ - return player.isTurnedOver()&&game.hasPlayer(current=>{ - return current.hasSkill('jsrgzhangdeng')&¤t.isTurnedOver(); - }); + viewAs: { name: "jiu", isCard: true }, + viewAsFilter: function (player) { + return ( + player.isTurnedOver() && + game.hasPlayer((current) => { + return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver(); + }) + ); }, - filterCard:()=>false, - selectCard:-1, - precontent:function(){ - player.logSkill('jsrgzhangdeng_jiu'); - var targets=game.filterPlayer(current=>{ - return current.hasSkill('jsrgzhangdeng')&¤t.isTurnedOver(); + filterCard: () => false, + selectCard: -1, + precontent: function () { + player.logSkill("jsrgzhangdeng_jiu"); + var targets = game.filterPlayer((current) => { + return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver(); }); player.line(targets[0]); delete event.result.skill; @@ -4712,718 +5786,867 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //关羽 - jsrgguanjue:{ - audio:2, - trigger:{ - player:['useCard','respond'], + jsrgguanjue: { + audio: 2, + trigger: { + player: ["useCard", "respond"], }, - filter:function(event,player){ + filter: function (event, player) { return lib.suit.includes(get.suit(event.card)); }, - forced:true, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>current!=player); - var suit=get.suit(trigger.card); - for(var target of targets){ - target.addTempSkill('jsrgguanjue_ban'); - target.markAuto('jsrgguanjue_ban',[suit]); + forced: true, + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => current != player); + var suit = get.suit(trigger.card); + for (var target of targets) { + target.addTempSkill("jsrgguanjue_ban"); + target.markAuto("jsrgguanjue_ban", [suit]); } }, - subSkill:{ - ban:{ - onremove:true, - charlotte:true, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('jsrgguanjue_ban').includes(get.suit(card))) return false; + subSkill: { + ban: { + onremove: true, + charlotte: true, + mod: { + cardEnabled: function (card, player) { + if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) + return false; }, - cardRespondable:function(card,player){ - if(player.getStorage('jsrgguanjue_ban').includes(get.suit(card))) return false; + cardRespondable: function (card, player) { + if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) + return false; }, - cardSavable:function(card,player){ - if(player.getStorage('jsrgguanjue_ban').includes(get.suit(card))) return false; + cardSavable: function (card, player) { + if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) + return false; }, }, - mark:true, - marktext:'绝', - intro:{ - content:'本回合内不能使用或打出$的牌', + mark: true, + marktext: "绝", + intro: { + content: "本回合内不能使用或打出$的牌", }, }, }, }, - jsrgnianen:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - if(!player.countCards('hes')) return false; - if(player.hasSkill('jsrgnianen_blocker')) return false; - for(var name of lib.inpile){ - if(get.type2(name)!='basic') continue; - var card={name:name}; - if(event.filterCard(get.autoViewAs(card,'unsure'),player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(get.autoViewAs(card,'unsure'),player,event)) return true; + jsrgnianen: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filter: function (event, player) { + if (!player.countCards("hes")) return false; + if (player.hasSkill("jsrgnianen_blocker")) return false; + for (var name of lib.inpile) { + if (get.type2(name) != "basic") continue; + var card = { name: name }; + if (event.filterCard(get.autoViewAs(card, "unsure"), player, event)) return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(get.autoViewAs(card, "unsure"), player, event)) + return true; } } } return false; }, - derivation:'mashu', - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(name=='sha'){ - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) list.push(['基本','','sha']); - for(var nature of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name,nature},'unsure'),player,event)) list.push(['基本','','sha',nature]); + derivation: "mashu", + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (name == "sha") { + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) + list.push(["基本", "", "sha"]); + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name, nature }, "unsure"), + player, + event + ) + ) + list.push(["基本", "", "sha", nature]); } - } - else if(get.type(name)=='basic'&&event.filterCard(get.autoViewAs({name},'unsure'),player,event)) list.push(['基本','',name]); + } else if ( + get.type(name) == "basic" && + event.filterCard(get.autoViewAs({ name }, "unsure"), player, event) + ) + list.push(["基本", "", name]); } - var dialog=ui.create.dialog('念恩',[list,'vcard']); - dialog.direct=true; + var dialog = ui.create.dialog("念恩", [list, "vcard"]); + dialog.direct = true; return dialog; }, - filter:function(button,player){ - return _status.event.getParent().filterCard(get.autoViewAs({name:button.link[2],nature:button.link[3]},'unsure'),player,_status.event.getParent()); + filter: function (button, player) { + return _status.event + .getParent() + .filterCard( + get.autoViewAs({ name: button.link[2], nature: button.link[3] }, "unsure"), + player, + _status.event.getParent() + ); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; - if(['wugu','zhulu_card','yiyi','lulitongxin','lianjunshengyan','diaohulishan'].includes(button.link[2])) return 0; + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; + if ( + [ + "wugu", + "zhulu_card", + "yiyi", + "lulitongxin", + "lianjunshengyan", + "diaohulishan", + ].includes(button.link[2]) + ) + return 0; return player.getUseValue({ - name:button.link[2], - nature:button.link[3], + name: button.link[2], + nature: button.link[3], }); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jsrgnianen', - filterCard:true, - popname:true, - check:function(card){ - return 8-get.value(card); + audio: "jsrgnianen", + filterCard: true, + popname: true, + check: function (card) { + return 8 - get.value(card); }, - position:'hes', - viewAs:{name:links[0][2],nature:links[0][3]}, - precontent:function(){ - player.logSkill('jsrgnianen'); + position: "hes", + viewAs: { name: links[0][2], nature: links[0][3] }, + precontent: function () { + player.logSkill("jsrgnianen"); delete event.result.skill; - var card=event.result.card; - if(get.color(card,player)!='red'||get.name(card)!='sha'||get.natureList(card).length){ - player.addTempSkill('jsrgnianen_blocker'); - player.addAdditionalSkill('jsrgnianen_blocker','mashu'); + var card = event.result.card; + if ( + get.color(card, player) != "red" || + get.name(card) != "sha" || + get.natureList(card).length + ) { + player.addTempSkill("jsrgnianen_blocker"); + player.addAdditionalSkill("jsrgnianen_blocker", "mashu"); } }, - } + }; }, - prompt:function(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } - }, - hiddenCard:function(player,name){ - if(!lib.inpile.includes(name)) return false; - var type=get.type2(name); - return type=='basic'&&player.countCards('hes')>0&&!player.hasSkill('jsrgnianen_blocker'); - }, - ai:{ - fireAttack:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hes')||player.hasSkill('jsrgnianen_blocker')) return false; + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + }, + hiddenCard: function (player, name) { + if (!lib.inpile.includes(name)) return false; + var type = get.type2(name); + return ( + type == "basic" && + player.countCards("hes") > 0 && + !player.hasSkill("jsrgnianen_blocker") + ); + }, + ai: { + fireAttack: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hes") || player.hasSkill("jsrgnianen_blocker")) return false; + }, + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - blocker:{ - charlotte:true, - mark:true, - marktext:'恩', - intro:{content:'视为拥有〖马术〗'}, + subSkill: { + blocker: { + charlotte: true, + mark: true, + marktext: "恩", + intro: { content: "视为拥有〖马术〗" }, }, }, }, //生鱼片 - jsrglunshi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return game.hasPlayer(current=>{ + jsrglunshi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return game.hasPlayer((current) => { return current.inRangeOf(target); }); }, - content:function(){ - 'step 0' - var num=game.countPlayer(current=>{ + content: function () { + "step 0"; + var num = game.countPlayer((current) => { return current.inRangeOf(target); }); - var len=target.countCards('h'); - num=Math.max(0,Math.min(len+num,5)-len); - if(num>0) target.draw(num); - 'step 1' - var num=game.countPlayer(current=>{ + var len = target.countCards("h"); + num = Math.max(0, Math.min(len + num, 5) - len); + if (num > 0) target.draw(num); + "step 1"; + var num = game.countPlayer((current) => { return current.inRange(target); }); - if(num>0) target.chooseToDiscard(num,'he',true,get.translation(player)+'对你发动了【论势】','请弃置'+get.cnNumber(num)+'张牌'); + if (num > 0) + target.chooseToDiscard( + num, + "he", + true, + get.translation(player) + "对你发动了【论势】", + "请弃置" + get.cnNumber(num) + "张牌" + ); }, - ai:{ - order:6, - result:{ - target:function(player,target){ - var num1=game.countPlayer(current=>{ - return current.inRangeOf(target); - }),num2=game.countPlayer(current=>{ - return current.inRange(target); - }); - var len=target.countCards('h'); - num1=Math.max(0,Math.min(len+num1,5)-len); - return (num1-num2+1)/2; - } - } + ai: { + order: 6, + result: { + target: function (player, target) { + var num1 = game.countPlayer((current) => { + return current.inRangeOf(target); + }), + num2 = game.countPlayer((current) => { + return current.inRange(target); + }); + var len = target.countCards("h"); + num1 = Math.max(0, Math.min(len + num1, 5) - len); + return (num1 - num2 + 1) / 2; + }, + }, }, }, - jsrgguitu:{ - audio:2, - trigger:{ - player:'phaseZhunbeiBegin', + jsrgguitu: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", }, - direct:true, - filter:function(event,player){ - return game.countPlayer(current=>{ - return current.getEquips(1).length; - })>=2; + direct: true, + filter: function (event, player) { + return ( + game.countPlayer((current) => { + return current.getEquips(1).length; + }) >= 2 + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jsrgguitu'),(card,player,target)=>{ - return target.getEquips(1).length; - },[1,2]).set('filterOk',()=>{ - var num=0; - for(var target of ui.selected.targets){ - num+=target.getEquips(1).length; - } - return num>=2; - }).set('ai',target=>{ - var sign=-1; - var val=0; - if(ui.selected.targets.length){ - sign=1; - var targetx=ui.selected.targets[0]; - var cards=targetx.getEquips(1); - var list=cards.map(card=>{ - return [card,get.value(card,targetx)]; + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt2("jsrgguitu"), + (card, player, target) => { + return target.getEquips(1).length; + }, + [1, 2] + ) + .set("filterOk", () => { + var num = 0; + for (var target of ui.selected.targets) { + num += target.getEquips(1).length; + } + return num >= 2; + }) + .set("ai", (target) => { + var sign = -1; + var val = 0; + if (ui.selected.targets.length) { + sign = 1; + var targetx = ui.selected.targets[0]; + var cards = targetx.getEquips(1); + var list = cards.map((card) => { + return [card, get.value(card, targetx)]; + }); + list.sort((a, b) => { + return b[1] - a[1]; + }); + val = get.attitude(_status.event.player, targetx) * list[0][1]; + } + var cards = target.getEquips(1); + var list = cards.map((card) => { + return [card, get.value(card, target)]; }); - list.sort((a,b)=>{ - return b[1]-a[1]; + list.sort((a, b) => { + return b[1] - a[1]; }); - val=get.attitude(_status.event.player,targetx)*list[0][1]; - } - var cards=target.getEquips(1); - var list=cards.map(card=>{ - return [card,get.value(card,target)]; + return get.attitude(_status.event.player, target) * list[0][1] * sign - val; }); - list.sort((a,b)=>{ - return b[1]-a[1]; - }); - return get.attitude(_status.event.player,target)*list[0][1]*sign-val; - }); - 'step 1' - if(result.bool){ - var targets=result.targets.slice(); + "step 1"; + if (result.bool) { + var targets = result.targets.slice(); targets.sortBySeat(); - event.targets=targets; - player.logSkill('jsrgguitu',targets); - event.rangeList=targets.map(target=>{ + event.targets = targets; + player.logSkill("jsrgguitu", targets); + event.rangeList = targets.map((target) => { return target.getAttackRange(); }); - var weapons=[]; - for(var target of targets){ + var weapons = []; + for (var target of targets) { weapons.addArray(target.getEquips(1)); } - if(weapons.length>2){ - var list=['诡图:选择要交换的武器牌']; - for(var target of targets){ + if (weapons.length > 2) { + var list = ["诡图:选择要交换的武器牌"]; + for (var target of targets) { list.addArray([ - '
              '+get.translation(target)+'的武器牌
              ', - target.getEquips(1) - ]) + '
              ' + get.translation(target) + "的武器牌
              ", + target.getEquips(1), + ]); } - player.chooseButton(list,true,2).set('filterButton',button=>{ - var count=_status.event.count; - if(count==1) return true; - for(var i=0;i{ - var player=_status.event.player; - var card=button.link; - var owner=get.owner(card); - var att=get.attitude(player,owner); - var val=-get.value(card)*att; - return val; - }); - } - else event._result={bool:true,links:weapons}; - } - else event.finish(); - 'step 2' - if(result.bool){ - var links=result.links; - var list=[]; - for(var target of targets){ - var weapons=target.getEquips(1); - weapons=weapons.filter(i=>links.includes(i)); - if(weapons.length){ - list.push([target,weapons]); + player + .chooseButton(list, true, 2) + .set("filterButton", (button) => { + var count = _status.event.count; + if (count == 1) return true; + for (var i = 0; i < ui.selected.buttons.length; i++) { + if (get.owner(button.link) == get.owner(ui.selected.buttons[i].link)) + return false; + } + return true; + }) + .set("count", targets.length) + .set("ai", (button) => { + var player = _status.event.player; + var card = button.link; + var owner = get.owner(card); + var att = get.attitude(player, owner); + var val = -get.value(card) * att; + return val; + }); + } else event._result = { bool: true, links: weapons }; + } else event.finish(); + "step 2"; + if (result.bool) { + var links = result.links; + var list = []; + for (var target of targets) { + var weapons = target.getEquips(1); + weapons = weapons.filter((i) => links.includes(i)); + if (weapons.length) { + list.push([target, weapons]); } } - if(list.length==2){ - event.players=list.map(i=>i[0]); - event.cards=list.map(i=>i[1]); - } - else{ - event.players=[list[0][0],list[0][0]]; - event.cards=list[0][1]; + if (list.length == 2) { + event.players = list.map((i) => i[0]); + event.cards = list.map((i) => i[1]); + } else { + event.players = [list[0][0], list[0][0]]; + event.cards = list[0][1]; } game.loseAsync({ - player:event.players[0], - target:event.players[1], - cards1:event.cards[0], - cards2:event.cards[1], - }).setContent('swapHandcardsx'); + player: event.players[0], + target: event.players[1], + cards1: event.cards[0], + cards2: event.cards[1], + }).setContent("swapHandcardsx"); + } else event.finish(); + "step 3"; + for (var i = 0; i < event.cards[1].length; i++) { + if (get.position(event.cards[1][i], true) == "o") + event.players[0].equip(event.cards[1][i]); } - else event.finish(); - 'step 3' - for(var i=0;i{ + "step 4"; + var rangeList = targets.map((target) => { return target.getAttackRange(); }); - for(var i=0;ilist.includes(name)); - var str=get.translation(trigger.player)+(evt.card?'因'+get.translation(evt.card):'')+'需要'+reason+'一张'+names+',是否弃置一张牌视为其'+reason+'之'+ - (used.length?('(你不能以此法令其'+reason+get.translation(used)+')'):'')+'?若如此做,你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。'; - event.str=str; - if(!listx.length) event.finish(); - else if(listx.length==1) event._result={bool:true,links:listx}; - else{ - event.asked=true; - player.chooseButton([ - '###'+get.prompt('jsrgjixiang',trigger.player)+'###
              '+str+'
              ', - [listx,'vcard'], - ]).set('ai',()=>Math.random()+1); + names = names.slice(0, names.length - 1); + var reason = trigger.name == "chooseToUse" ? "使用" : "打出"; + var used = player.getStorage("jsrgjixiang_used").filter((name) => list.includes(name)); + var str = + get.translation(trigger.player) + + (evt.card ? "因" + get.translation(evt.card) : "") + + "需要" + + reason + + "一张" + + names + + ",是否弃置一张牌视为其" + + reason + + "之" + + (used.length ? "(你不能以此法令其" + reason + get.translation(used) + ")" : "") + + "?若如此做,你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。"; + event.str = str; + if (!listx.length) event.finish(); + else if (listx.length == 1) event._result = { bool: true, links: listx }; + else { + event.asked = true; + player + .chooseButton([ + "###" + + get.prompt("jsrgjixiang", trigger.player) + + '###
              ' + + str + + "
              ", + [listx, "vcard"], + ]) + .set("ai", () => Math.random() + 1); } - event.list=list; - 'step 1' - if(result.bool){ - var name=result.links[0][2],nature=result.links[0][3]; - var card={name:name,nature:nature,isCard:true}; - event.card=card; - var evt=trigger.getParent(); - var reason=(trigger.name=='chooseToUse'?'使用':'打出'); - var prompt=event.asked? - '济乡:是否弃置一张牌'+(trigger.filterTarget?'并选择目标角色':'')+'?': - get.prompt('jsrgjixiang',trigger.player); - var str=event.asked?'若如此做,视为'+get.translation(trigger.player)+reason+get.translation(card)+',然后你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。':event.str; - var next=player.chooseCardTarget({ - prompt:prompt, - prompt2:str, - filterCard:lib.filter.cardDiscardable, - position:'he', - goon:get.attitude(player,trigger.player)>1&&(evt.card?get.effect(trigger.player,evt.card,evt.player,player)<0:get.effect(trigger.player,{name:event.list[0]},trigger.player,player)>0), - ai1:function(card){ - if(_status.event.goon) return 6-get.value(card); + event.list = list; + "step 1"; + if (result.bool) { + var name = result.links[0][2], + nature = result.links[0][3]; + var card = { name: name, nature: nature, isCard: true }; + event.card = card; + var evt = trigger.getParent(); + var reason = trigger.name == "chooseToUse" ? "使用" : "打出"; + var prompt = event.asked + ? "济乡:是否弃置一张牌" + (trigger.filterTarget ? "并选择目标角色" : "") + "?" + : get.prompt("jsrgjixiang", trigger.player); + var str = event.asked + ? "若如此做,视为" + + get.translation(trigger.player) + + reason + + get.translation(card) + + ",然后你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。" + : event.str; + var next = player.chooseCardTarget({ + prompt: prompt, + prompt2: str, + filterCard: lib.filter.cardDiscardable, + position: "he", + goon: + get.attitude(player, trigger.player) > 1 && + (evt.card + ? get.effect(trigger.player, evt.card, evt.player, player) < 0 + : get.effect( + trigger.player, + { name: event.list[0] }, + trigger.player, + player + ) > 0), + ai1: function (card) { + if (_status.event.goon) return 6 - get.value(card); return 0; }, - _get_card:card, + _get_card: card, }); - var keys=['filterTarget','selectTarget','ai2']; - for(var key of keys) delete next[key]; - for(var i in trigger){ - if(!(i in next)) next[i]=trigger[i]; + var keys = ["filterTarget", "selectTarget", "ai2"]; + for (var key of keys) delete next[key]; + for (var i in trigger) { + if (!(i in next)) next[i] = trigger[i]; } - next.filterTargetx=trigger.filterTarget||(()=>false); - next.filterTarget=function(card,player,target){ - var filter=this.filterTargetx; - if(typeof filter!='function') filter=(()=>filter); - card=_status.event._get_card; - player=_status.event.getTrigger().player; - return this.filterTargetx.apply(this,arguments); + next.filterTargetx = trigger.filterTarget || (() => false); + next.filterTarget = function (card, player, target) { + var filter = this.filterTargetx; + if (typeof filter != "function") filter = () => filter; + card = _status.event._get_card; + player = _status.event.getTrigger().player; + return this.filterTargetx.apply(this, arguments); }; - if(typeof next.selectTarget!='number'&&typeof next.selectTarget!='function'&&get.itemtype(next.selectTarget)!='select') next.selectTarget=-1; - } - else event.finish(); - 'step 2' - if(result.bool){ - var cardx=result.cards[0]; - var targets=result.targets||[]; - event.targets=targets; - player.logSkill('jsrgjixiang',trigger.player); - player.addTempSkill('jsrgjixiang_used'); - player.markAuto('jsrgjixiang_used',[card.name]); + if ( + typeof next.selectTarget != "number" && + typeof next.selectTarget != "function" && + get.itemtype(next.selectTarget) != "select" + ) + next.selectTarget = -1; + } else event.finish(); + "step 2"; + if (result.bool) { + var cardx = result.cards[0]; + var targets = result.targets || []; + event.targets = targets; + player.logSkill("jsrgjixiang", trigger.player); + player.addTempSkill("jsrgjixiang_used"); + player.markAuto("jsrgjixiang_used", [card.name]); player.discard(cardx); trigger.untrigger(); - trigger.set('responded',true); - var result={ - bool:true, - card:card + trigger.set("responded", true); + var result = { + bool: true, + card: card, }; - if(targets.length) result.targets=targets; - trigger.result=result; + if (targets.length) result.targets = targets; + trigger.result = result; player.draw(); var phaseName; - for(var name of lib.phaseName){ - var evt=trigger.getParent(name); - if(!evt||evt.name!=name) continue; - phaseName=name; + for (var name of lib.phaseName) { + var evt = trigger.getParent(name); + if (!evt || evt.name != name) continue; + phaseName = name; break; } - if(phaseName){ - player.addTempSkill('jsrgjixiang_add',phaseName+'After'); - player.addMark('jsrgjixiang_add',1,false); + if (phaseName) { + player.addTempSkill("jsrgjixiang_add", phaseName + "After"); + player.addMark("jsrgjixiang_add", 1, false); } } }, - subSkill:{ - used:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'乡', - intro:{ - content:'已触发过牌名:$', + subSkill: { + used: { + charlotte: true, + onremove: true, + mark: true, + marktext: "乡", + intro: { + content: "已触发过牌名:$", }, }, - add:{ - charlotte:true, - onremove:true, - mark:true, - intro:{ - markcount:(storage,player)=>2+(storage||0), - content:(storage,player)=>'〖称贤〗剩余可发动次数为'+(2+(storage||0)), + add: { + charlotte: true, + onremove: true, + mark: true, + intro: { + markcount: (storage, player) => 2 + (storage || 0), + content: (storage, player) => "〖称贤〗剩余可发动次数为" + (2 + (storage || 0)), }, }, - save:{ - charlotte:true, - ai:{ - save:true, - skillTagFilter:function(player,arg,target){ - return _status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('jsrgjixiang')&&_status.currentPhase.countCards('he'); + save: { + charlotte: true, + ai: { + save: true, + skillTagFilter: function (player, arg, target) { + return ( + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("jsrgjixiang") && + _status.currentPhase.countCards("he") + ); }, }, }, }, }, - jsrgchengxian:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(!player.countCards('hs')) return false; - if(2+player.countMark('jsrgjixiang_add')<=0) return false; - for(var name of lib.inpile){ - if(get.type(name)!='trick') continue; - if(player.getStorage('jsrgchengxian_used').includes(name)) continue; - if(event.filterCard({name:name},player,event)) return true; + jsrgchengxian: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (!player.countCards("hs")) return false; + if (2 + player.countMark("jsrgjixiang_add") <= 0) return false; + for (var name of lib.inpile) { + if (get.type(name) != "trick") continue; + if (player.getStorage("jsrgchengxian_used").includes(name)) continue; + if (event.filterCard({ name: name }, player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(player.getStorage('jsrgchengxian_used').includes(name)) continue; - var info=get.info({name:name}); - if(!info||info.type!='trick') continue; - if(info.notarget) continue; - if(!info.selectTarget) continue; - if(get.type(name)=='trick'&&event.filterCard({name:name},player,event)) list.push(['锦囊','',name]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (player.getStorage("jsrgchengxian_used").includes(name)) continue; + var info = get.info({ name: name }); + if (!info || info.type != "trick") continue; + if (info.notarget) continue; + if (!info.selectTarget) continue; + if (get.type(name) == "trick" && event.filterCard({ name: name }, player, event)) + list.push(["锦囊", "", name]); } - var dialog=ui.create.dialog('称贤',[list,'vcard']); + var dialog = ui.create.dialog("称贤", [list, "vcard"]); return dialog; }, - filter:function(button,player){ - return _status.event.getParent().filterCard({name:button.link[2],nature:button.link[3]},player,_status.event.getParent()); + filter: function (button, player) { + return _status.event + .getParent() + .filterCard( + { name: button.link[2], nature: button.link[3] }, + player, + _status.event.getParent() + ); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; - if(['wugu','zhulu_card','yiyi','lulitongxin','lianjunshengyan','diaohulishan'].includes(button.link[2])) return 0; + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; + if ( + [ + "wugu", + "zhulu_card", + "yiyi", + "lulitongxin", + "lianjunshengyan", + "diaohulishan", + ].includes(button.link[2]) + ) + return 0; return player.getUseValue({ - name:button.link[2], - nature:button.link[3], + name: button.link[2], + nature: button.link[3], }); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jsrgchengxian', - filterCard:function(card,player){ - var num=game.countPlayer(current=>{ - return player.canUse(card,current); + audio: "jsrgchengxian", + filterCard: function (card, player) { + var num = game.countPlayer((current) => { + return player.canUse(card, current); }); - if(!num) return false; - var cardx=get.copy(lib.skill.jsrgchengxian_backup.viewAs); - cardx.cards=[card]; - var num2=game.countPlayer(current=>{ - return player.canUse(cardx,current); + if (!num) return false; + var cardx = get.copy(lib.skill.jsrgchengxian_backup.viewAs); + cardx.cards = [card]; + var num2 = game.countPlayer((current) => { + return player.canUse(cardx, current); }); - return num==num2; + return num == num2; }, - popname:true, - check:function(card){ - return 8-get.value(card); + popname: true, + check: function (card) { + return 8 - get.value(card); }, - position:'hs', - viewAs:{name:links[0][2]}, - precontent:function(){ - player.logSkill('jsrgchengxian'); - player.addTempSkill('jsrgjixiang_add'); - if(typeof player.storage.jsrgjixiang_add!='number') player.storage.jsrgjixiang_add=0; + position: "hs", + viewAs: { name: links[0][2] }, + precontent: function () { + player.logSkill("jsrgchengxian"); + player.addTempSkill("jsrgjixiang_add"); + if (typeof player.storage.jsrgjixiang_add != "number") + player.storage.jsrgjixiang_add = 0; player.storage.jsrgjixiang_add--; - player.addTempSkill('jsrgchengxian_used'); - player.markAuto('jsrgchengxian_used',[event.result.card.name]); + player.addTempSkill("jsrgchengxian_used"); + player.markAuto("jsrgchengxian_used", [event.result.card.name]); delete event.result.skill; }, - } + }; + }, + prompt: function (links, player) { + return ( + "将一张合法目标数与" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "相同的手牌当此牌使用" + ); }, - prompt:function(links,player){ - return '将一张合法目标数与'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'相同的手牌当此牌使用'; - } }, //理解错了,下面这个不用了 - getNumber:function(card,player){ - var rangex=null; - var info=get.info(card); - if(!info) return null; - if(info.notarget) return null; - if(info.selectTarget!=undefined){ - var select=get.select(info.selectTarget); - if(select[0]<0){ - if(!info.toself){ - var count=game.countPlayer(current=>{ - return lib.filter.targetEnabled(card,player,current); + getNumber: function (card, player) { + var rangex = null; + var info = get.info(card); + if (!info) return null; + if (info.notarget) return null; + if (info.selectTarget != undefined) { + var select = get.select(info.selectTarget); + if (select[0] < 0) { + if (!info.toself) { + var count = game.countPlayer((current) => { + return lib.filter.targetEnabled(card, player, current); }); - } - else count=1; - rangex=[count,count]; - } - else rangex=select; + } else count = 1; + rangex = [count, count]; + } else rangex = select; } return rangex; }, - ai:{ - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + ai: { + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - used:{ - charlotte:true, - onremove:true, - mark:true, - intro:{ - content:'已使用过$', + subSkill: { + used: { + charlotte: true, + onremove: true, + mark: true, + intro: { + content: "已使用过$", }, }, }, }, //张辽 - jsrgzhengbing:{ - audio:2, - enable:'phaseUse', - usable:3, - filter:function(event,player){ - return player.group=='qun'; + jsrgzhengbing: { + audio: 2, + enable: "phaseUse", + usable: 3, + filter: function (event, player) { + return player.group == "qun"; }, - filterCard:lib.filter.cardRecastable, - check:function(card){ - var player=_status.event.player,val=5+['shan','tao'].includes(get.name(card))*1.5; - if(player.needsToDiscard()>2&&get.name(card)=='sha'&&player.countCards('hs','sha')>1) val+=0.5; - return val-get.value(card); + filterCard: lib.filter.cardRecastable, + check: function (card) { + var player = _status.event.player, + val = 5 + ["shan", "tao"].includes(get.name(card)) * 1.5; + if ( + player.needsToDiscard() > 2 && + get.name(card) == "sha" && + player.countCards("hs", "sha") > 1 + ) + val += 0.5; + return val - get.value(card); }, - position:'he', - groupSkill:true, - lose:false, - discard:false, - delay:false, - content:function(){ - 'step 0' + position: "he", + groupSkill: true, + lose: false, + discard: false, + delay: false, + content: function () { + "step 0"; player.recast(cards); - switch(get.name(cards[0])){ - case 'sha': - player.addTempSkill('jsrgzhengbing_sha'); - player.addMark('jsrgzhengbing_sha',2,false); + switch (get.name(cards[0])) { + case "sha": + player.addTempSkill("jsrgzhengbing_sha"); + player.addMark("jsrgzhengbing_sha", 2, false); break; - case 'shan': + case "shan": player.draw(); break; - case 'tao': - player.changeGroup('wei'); + case "tao": + player.changeGroup("wei"); } }, - ai:{ - order:7, - result:{player:1}, + ai: { + order: 7, + result: { player: 1 }, }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('jsrgzhengbing_sha'); + subSkill: { + sha: { + charlotte: true, + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("jsrgzhengbing_sha"); }, }, - intro:{ - content:'手牌上限+#', + intro: { + content: "手牌上限+#", }, - } + }, }, }, - jsrgtuwei:{ - audio:2, - trigger:{ - player:'phaseUseBegin', + jsrgtuwei: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - filter:function(event,player){ - return player.group=='wei'&&game.hasPlayer(current=>{ - return player.inRange(current)&¤t.countGainableCards(player,'he')>0; - }); + filter: function (event, player) { + return ( + player.group == "wei" && + game.hasPlayer((current) => { + return player.inRange(current) && current.countGainableCards(player, "he") > 0; + }) + ); }, - groupSkill:true, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jsrgtuwei'),'获得攻击范围内任意名角色的各一张牌。然后回合结束时这些角色中未受过伤害的角色依次获得你的一张牌。',(card,player,target)=>{ - return player.inRange(target)&&target.countGainableCards(player,'he')>0; - },[1,Infinity]).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'shunshou_copy2'},player,player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.slice(); + groupSkill: true, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jsrgtuwei"), + "获得攻击范围内任意名角色的各一张牌。然后回合结束时这些角色中未受过伤害的角色依次获得你的一张牌。", + (card, player, target) => { + return player.inRange(target) && target.countGainableCards(player, "he") > 0; + }, + [1, Infinity] + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "shunshou_copy2" }, player, player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.slice(); targets.sortBySeat(); - player.logSkill('jsrgtuwei',targets); - player.gainMultiple(result.targets,'he'); - player.addTempSkill('jsrgtuwei_backfire'); - player.markAuto('jsrgtuwei_backfire',targets); + player.logSkill("jsrgtuwei", targets); + player.gainMultiple(result.targets, "he"); + player.addTempSkill("jsrgtuwei_backfire"); + player.markAuto("jsrgtuwei_backfire", targets); } }, - subSkill:{ - backfire:{ - audio:'jsrgtuwei', - trigger:{ - player:'phaseEnd', + subSkill: { + backfire: { + audio: "jsrgtuwei", + trigger: { + player: "phaseEnd", }, - charlotte:true, - onremove:true, - forced:true, - filter:function(event,player){ - return player.getStorage('jsrgtuwei_backfire').some(target=>{ - return !target.getHistory('damage').length&&target.isIn(); + charlotte: true, + onremove: true, + forced: true, + filter: function (event, player) { + return player.getStorage("jsrgtuwei_backfire").some((target) => { + return !target.getHistory("damage").length && target.isIn(); }); }, - content:function(){ - 'step 0' - var targets=player.getStorage('jsrgtuwei_backfire').filter(target=>{ - return !target.getHistory('damage').length&&target.isIn(); + content: function () { + "step 0"; + var targets = player.getStorage("jsrgtuwei_backfire").filter((target) => { + return !target.getHistory("damage").length && target.isIn(); }); - event.targets=targets.sortBySeat(); - 'step 1' - var target=targets.shift(); - if(target.isIn()&&player.countGainableCards(target,'he')){ + event.targets = targets.sortBySeat(); + "step 1"; + var target = targets.shift(); + if (target.isIn() && player.countGainableCards(target, "he")) { target.line(player); - target.gainPlayerCard(player,true,'he'); + target.gainPlayerCard(player, true, "he"); } - if(player.countCards('he')&&targets.length) event.redo(); + if (player.countCards("he") && targets.length) event.redo(); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(player!=target&&get.tag(card,'damage')&&target&&player.getStorage('jsrgtuwei_backfire').includes(target)&&!target.getHistory('damage').length) return [1,1,1,0]; + ai: { + effect: { + player: function (card, player, target) { + if ( + player != target && + get.tag(card, "damage") && + target && + player.getStorage("jsrgtuwei_backfire").includes(target) && + !target.getHistory("damage").length + ) + return [1, 1, 1, 0]; }, }, }, @@ -5431,296 +6654,318 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //许贡 - jsrgbiaozhao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.countPlayer(current=>current!=player)>=2; + jsrgbiaozhao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.countPlayer((current) => current != player) >= 2; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jsrgbiaozhao'),lib.filter.notMe,2).set('ai',target=>{ - var player=_status.event.player; - var att=get.attitude(player,target); - if(!ui.selected.targets.length) return att*(Math.sqrt(target.countCards('hs'))+0.1); - return -att/Math.sqrt(target.countCards('hs')+0.1); - }).set('targetprompt',['用牌无限制','打你变疼']); - 'step 1' - if(result.bool){ - var targets=result.targets; - player.logSkill('jsrgbiaozhao',targets); - player.addTempSkill('jsrgbiaozhao_syujin',{player:['phaseBegin','die']}); - if(!player.storage.jsrgbiaozhao_syujin) player.storage.jsrgbiaozhao_syujin=[]; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("jsrgbiaozhao"), lib.filter.notMe, 2) + .set("ai", (target) => { + var player = _status.event.player; + var att = get.attitude(player, target); + if (!ui.selected.targets.length) + return att * (Math.sqrt(target.countCards("hs")) + 0.1); + return -att / Math.sqrt(target.countCards("hs") + 0.1); + }) + .set("targetprompt", ["用牌无限制", "打你变疼"]); + "step 1"; + if (result.bool) { + var targets = result.targets; + player.logSkill("jsrgbiaozhao", targets); + player.addTempSkill("jsrgbiaozhao_syujin", { player: ["phaseBegin", "die"] }); + if (!player.storage.jsrgbiaozhao_syujin) player.storage.jsrgbiaozhao_syujin = []; player.storage.jsrgbiaozhao_syujin.push(targets); - targets[0].addSkill('jsrgbiaozhao_A'); - targets[0].markAuto('jsrgbiaozhao_A',[targets[1]]); - targets[1].addSkill('jsrgbiaozhao_B'); - targets[1].addMark('jsrgbiaozhao_B'+player.playerid,1,false); - targets[1].markAuto('jsrgbiaozhao_B',[player]); + targets[0].addSkill("jsrgbiaozhao_A"); + targets[0].markAuto("jsrgbiaozhao_A", [targets[1]]); + targets[1].addSkill("jsrgbiaozhao_B"); + targets[1].addMark("jsrgbiaozhao_B" + player.playerid, 1, false); + targets[1].markAuto("jsrgbiaozhao_B", [player]); } }, - subSkill:{ - syujin:{ - charlotte:true, - onremove:function(player,skill){ - var list=player.storage.jsrgbiaozhao_syujin; - for(var targets of list){ - targets[0].unmarkAuto('jsrgbiaozhao_A',[targets[1]]); - targets[1].unmarkAuto('jsrgbiaozhao_B',[player]); - delete targets[1].storage['jsrgbiaozhao_B'+player.playerid]; - if(!targets[0].getStorage('jsrgbiaozhao_A')) targets[0].removeSkill('jsrgbiaozhao_A'); - if(!targets[1].getStorage('jsrgbiaozhao_B')) targets[1].removeSkill('jsrgbiaozhao_B'); + subSkill: { + syujin: { + charlotte: true, + onremove: function (player, skill) { + var list = player.storage.jsrgbiaozhao_syujin; + for (var targets of list) { + targets[0].unmarkAuto("jsrgbiaozhao_A", [targets[1]]); + targets[1].unmarkAuto("jsrgbiaozhao_B", [player]); + delete targets[1].storage["jsrgbiaozhao_B" + player.playerid]; + if (!targets[0].getStorage("jsrgbiaozhao_A")) + targets[0].removeSkill("jsrgbiaozhao_A"); + if (!targets[1].getStorage("jsrgbiaozhao_B")) + targets[1].removeSkill("jsrgbiaozhao_B"); } delete player.storage.jsrgbiaozhao_syujin; }, }, - A:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'表', - intro:{ - content:'对$使用牌无次数和距离限制', + A: { + charlotte: true, + onremove: true, + mark: true, + marktext: "表", + intro: { + content: "对$使用牌无次数和距离限制", }, - mod:{ - targetInRange:function(card,player,target){ - if(player.getStorage('jsrgbiaozhao_A').includes(target)) return true; + mod: { + targetInRange: function (card, player, target) { + if (player.getStorage("jsrgbiaozhao_A").includes(target)) return true; }, - cardUsableTarget:function(card,player,target){ - if(player.getStorage('jsrgbiaozhao_A').includes(target)) return true; + cardUsableTarget: function (card, player, target) { + if (player.getStorage("jsrgbiaozhao_A").includes(target)) return true; }, }, }, - B:{ - trigger:{ - source:'damageBegin1', + B: { + trigger: { + source: "damageBegin1", }, - charlotte:true, - forced:true, - onremove:function(player,skill){ - for(var i in player.storage){ - if(i.indexOf('jsrgbiaozhao_B')==0) delete player.storage[i]; + charlotte: true, + forced: true, + onremove: function (player, skill) { + for (var i in player.storage) { + if (i.indexOf("jsrgbiaozhao_B") == 0) delete player.storage[i]; } }, - filter:function(event,player){ - return event.card&&player.getStorage('jsrgbiaozhao_B').includes(event.player); + filter: function (event, player) { + return event.card && player.getStorage("jsrgbiaozhao_B").includes(event.player); }, - content:function(){ - trigger.num+=player.countMark('jsrgbiaozhao_B'+trigger.player.playerid)||1; + content: function () { + trigger.num += player.countMark("jsrgbiaozhao_B" + trigger.player.playerid) || 1; }, - mark:true, - marktext:'召', - intro:{ - content:function(storage,player){ - var str=''; - for(var target of storage){ - str+='对'+get.translation(target)+'使用牌造成的伤害+'+player.countMark('jsrgbiaozhao_B'+target.playerid); + mark: true, + marktext: "召", + intro: { + content: function (storage, player) { + var str = ""; + for (var target of storage) { + str += + "对" + + get.translation(target) + + "使用牌造成的伤害+" + + player.countMark("jsrgbiaozhao_B" + target.playerid); } return str; - } + }, }, }, - } + }, }, - jsrgyechou:{ - audio:2, - trigger:{player:'die'}, - forceDie:true, - direct:true, - skillAnimation:true, - animationColor:'wood', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jsrgyechou'),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return -get.attitude(player,target); + jsrgyechou: { + audio: 2, + trigger: { player: "die" }, + forceDie: true, + direct: true, + skillAnimation: true, + animationColor: "wood", + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("jsrgyechou"), lib.filter.notMe).set("ai", (target) => { + var player = _status.event.player; + return -get.attitude(player, target); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jsrgyechou',target); - target.addSkill('jsrgyechou_effect'); - target.addMark('jsrgyechou_effect',1,false); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jsrgyechou", target); + target.addSkill("jsrgyechou_effect"); + target.addMark("jsrgyechou_effect", 1, false); } }, - subSkill:{ - effect:{ - trigger:{ - player:'damageBegin3', + subSkill: { + effect: { + trigger: { + player: "damageBegin3", }, - filter:function(event,player){ - return event.num>=player.getHp(); + filter: function (event, player) { + return event.num >= player.getHp(); }, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - trigger.num*=2*player.countMark('jsrgyechou_effect'); + forced: true, + charlotte: true, + onremove: true, + content: function () { + trigger.num *= 2 * player.countMark("jsrgyechou_effect"); }, - mark:true, - marktext:'仇', - intro:{ - content:'当你受到伤害值不小于体力值的伤害时,此伤害翻&倍', + mark: true, + marktext: "仇", + intro: { + content: "当你受到伤害值不小于体力值的伤害时,此伤害翻&倍", }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp==1) return 2; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (target.hp == 1) return 2; } - } - } + }, + }, }, }, - } + }, }, //淳于琼 - jsrgcangchu:{ - audio:'recangchu', - trigger:{ - global:'phaseJieshuBegin', + jsrgcangchu: { + audio: "recangchu", + trigger: { + global: "phaseJieshuBegin", }, - filter:function(event,player){ - if(player.hasSkill('jsrgshishou_blocker')) return false; - return player.getHistory('gain').length; + filter: function (event, player) { + if (player.hasSkill("jsrgshishou_blocker")) return false; + return player.getHistory("gain").length; }, - direct:true, - content:function(){ - 'step 0' - var num=0; - player.getHistory('gain',evt=>{ - num+=evt.cards.length; + direct: true, + content: function () { + "step 0"; + var num = 0; + player.getHistory("gain", (evt) => { + num += evt.cards.length; }); - event.num=num; - player.chooseTarget(get.prompt('jsrgcangchu'),'令至多'+get.cnNumber(num)+'名角色各摸'+get.cnNumber(num>game.countPlayer()?2:1)+'张牌',[1,num]).set('ai',target=>{ - var player=_status.event.player; - return get.attitude(player,target)/Math.sqrt(target.countCards('hs')+1); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.slice(); + event.num = num; + player + .chooseTarget( + get.prompt("jsrgcangchu"), + "令至多" + + get.cnNumber(num) + + "名角色各摸" + + get.cnNumber(num > game.countPlayer() ? 2 : 1) + + "张牌", + [1, num] + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.attitude(player, target) / Math.sqrt(target.countCards("hs") + 1); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.slice(); targets.sortBySeat(); - player.logSkill('jsrgcangchu',targets); - game.asyncDraw(targets,num>game.countPlayer()?2:1); + player.logSkill("jsrgcangchu", targets); + game.asyncDraw(targets, num > game.countPlayer() ? 2 : 1); game.delayex(); } }, }, - jsrgshishou:{ - audio:'reshishou', - trigger:{ - player:'useCard', + jsrgshishou: { + audio: "reshishou", + trigger: { + player: "useCard", }, - forced:true, - filter:function(event,player){ - return event.card.name=='jiu'; + forced: true, + filter: function (event, player) { + return event.card.name == "jiu"; }, - group:'jsrgshishou_burn', - content:function(){ - 'step 0' + group: "jsrgshishou_burn", + content: function () { + "step 0"; player.draw(3); - player.addTempSkill('jsrgshishou_nouse'); + player.addTempSkill("jsrgshishou_nouse"); }, - mod:{ - aiOrder:function(player,card,num){ - if(card.name=='jiu') return 0.01; + mod: { + aiOrder: function (player, card, num) { + if (card.name == "jiu") return 0.01; }, }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(card.name=='jiu') return [1,1]; + ai: { + effect: { + player_use: function (card, player, target) { + if (card.name == "jiu") return [1, 1]; }, - } + }, }, - subSkill:{ - nouse:{ - charlotte:true, - mod:{ - cardEnabled:function(card,player){ + subSkill: { + nouse: { + charlotte: true, + mod: { + cardEnabled: function (card, player) { return false; }, - cardUsable:function(card,player){ + cardUsable: function (card, player) { return false; }, - cardSavable:function(card,player){ + cardSavable: function (card, player) { return false; }, }, - mark:true, - marktext:'失', - intro:{ - content:'喝醉了,不能再使用牌', - } - }, - burn:{ - audio:'reshishou', - trigger:{ - player:'damageEnd', + mark: true, + marktext: "失", + intro: { + content: "喝醉了,不能再使用牌", + }, + }, + burn: { + audio: "reshishou", + trigger: { + player: "damageEnd", + }, + forced: true, + filter: function (event, player) { + return event.hasNature("fire"); + }, + content: function () { + player.addTempSkill("jsrgshishou_blocker", { player: "phaseEnd" }); + }, + }, + blocker: { + charlotte: true, + mark: true, + marktext: "守", + intro: { + content: "〖仓储〗失效直到下回合结束", }, - forced:true, - filter:function(event,player){ - return event.hasNature('fire'); - }, - content:function(){ - player.addTempSkill('jsrgshishou_blocker',{player:'phaseEnd'}); - } }, - blocker:{ - charlotte:true, - mark:true, - marktext:'守', - intro:{ - content:'〖仓储〗失效直到下回合结束', - } - } }, }, //江山如故·起 - sbyingmen:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + sbyingmen: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - if(!_status.characterlist) lib.skill.pingjian.initList(); - var characters=_status.characterlist.randomRemove(4); - lib.skill.sbyingmen.addVisitors(characters,player); + content: function () { + if (!_status.characterlist) lib.skill.pingjian.initList(); + var characters = _status.characterlist.randomRemove(4); + lib.skill.sbyingmen.addVisitors(characters, player); game.delayx(); }, - group:'sbyingmen_reload', - subSkill:{ - reload:{ - trigger:{player:'phaseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.getStorage('sbyingmen').length<4; + group: "sbyingmen_reload", + subSkill: { + reload: { + trigger: { player: "phaseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return player.getStorage("sbyingmen").length < 4; }, - content:function(){ - if(!_status.characterlist) lib.skill.pingjian.initList(); - var characters=_status.characterlist.randomRemove(4-player.getStorage('sbyingmen').length); - lib.skill.sbyingmen.addVisitors(characters,player); + content: function () { + if (!_status.characterlist) lib.skill.pingjian.initList(); + var characters = _status.characterlist.randomRemove( + 4 - player.getStorage("sbyingmen").length + ); + lib.skill.sbyingmen.addVisitors(characters, player); game.delayx(); }, }, }, - getSkills:function(characters,player){ - var skills=[]; - for(var name of characters){ - if(Array.isArray(lib.character[name])){ - for(var skill of lib.character[name][3]){ - var list=get.skillCategoriesOf(skill,player); - list.remove('锁定技'); - if(list.length>0) continue; - var info=get.info(skill); - if(info&&(!info.unique||info.gainable)){ + getSkills: function (characters, player) { + var skills = []; + for (var name of characters) { + if (Array.isArray(lib.character[name])) { + for (var skill of lib.character[name][3]) { + var list = get.skillCategoriesOf(skill, player); + list.remove("锁定技"); + if (list.length > 0) continue; + var info = get.info(skill); + if (info && (!info.unique || info.gainable)) { // lib.skill.rehuashen.createAudio(name,skill,'jsrg_xushao'); skills.add(skill); } @@ -5729,503 +6974,661 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return skills; }, - addVisitors:function(characters,player){ - player.addSkillBlocker('sbyingmen'); - game.log(player,'将','#y'+get.translation(characters),'加入了','#g“访客”'); - game.broadcastAll(function(player,characters){ - player.tempname.addArray(characters); - player.$draw(characters.map(function(name){ - var cardname='huashen_card_'+name; - lib.card[cardname]={ - fullimage:true, - image:'character:'+name - }; - lib.translate[cardname]=get.rawName2(name); - return game.createCard(cardname,' ',' '); - }),'nobroadcast'); - },player,characters); - player.markAuto('sbyingmen',characters) - var storage=player.getStorage('sbyingmen'); - var skills=lib.skill.sbyingmen.getSkills(storage,player); + addVisitors: function (characters, player) { + player.addSkillBlocker("sbyingmen"); + game.log(player, "将", "#y" + get.translation(characters), "加入了", "#g“访客”"); + game.broadcastAll( + function (player, characters) { + player.tempname.addArray(characters); + player.$draw( + characters.map(function (name) { + var cardname = "huashen_card_" + name; + lib.card[cardname] = { + fullimage: true, + image: "character:" + name, + }; + lib.translate[cardname] = get.rawName2(name); + return game.createCard(cardname, " ", " "); + }), + "nobroadcast" + ); + }, + player, + characters + ); + player.markAuto("sbyingmen", characters); + var storage = player.getStorage("sbyingmen"); + var skills = lib.skill.sbyingmen.getSkills(storage, player); player.addInvisibleSkill(skills); }, - removeVisitors:function(characters,player){ - var skills=lib.skill.sbyingmen.getSkills(characters,player); - var characters2=player.getStorage('sbyingmen').slice(0); + removeVisitors: function (characters, player) { + var skills = lib.skill.sbyingmen.getSkills(characters, player); + var characters2 = player.getStorage("sbyingmen").slice(0); characters2.removeArray(characters); - skills.removeArray(lib.skill.sbyingmen.getSkills(characters2,player)); - game.broadcastAll((player,characters)=>player.tempname.removeArray(characters),player,characters); - player.unmarkAuto('sbyingmen',characters); + skills.removeArray(lib.skill.sbyingmen.getSkills(characters2, player)); + game.broadcastAll( + (player, characters) => player.tempname.removeArray(characters), + player, + characters + ); + player.unmarkAuto("sbyingmen", characters); _status.characterlist.addArray(characters); player.removeInvisibleSkill(skills); }, - onremove:function(player,skill){ - lib.skill.sbyingmen.removeVisitors(player.getSkills('sbyingmen'),player); - player.removeSkillBlocker('sbyingmen'); + onremove: function (player, skill) { + lib.skill.sbyingmen.removeVisitors(player.getSkills("sbyingmen"), player); + player.removeSkillBlocker("sbyingmen"); }, - skillBlocker:function(skill,player){ - if(!player.invisibleSkills.includes(skill)||skill=='sbpingjian'||skill=='sbpingjian') return false; - return !player.hasSkill('sbpingjian'); + skillBlocker: function (skill, player) { + if ( + !player.invisibleSkills.includes(skill) || + skill == "sbpingjian" || + skill == "sbpingjian" + ) + return false; + return !player.hasSkill("sbpingjian"); }, - marktext:'客', - intro:{ - name:'访客', - mark:function(dialog,storage,player){ - if(!storage||!storage.length) return '当前没有“访客”'; - dialog.addSmall([storage,'character']); - var skills=lib.skill.sbyingmen.getSkills(storage,player); - if(skills.length) dialog.addText('
            • 当前可用技能:'+get.translation(skills),false); + marktext: "客", + intro: { + name: "访客", + mark: function (dialog, storage, player) { + if (!storage || !storage.length) return "当前没有“访客”"; + dialog.addSmall([storage, "character"]); + var skills = lib.skill.sbyingmen.getSkills(storage, player); + if (skills.length) + dialog.addText("
            • 当前可用技能:" + get.translation(skills), false); }, }, }, - sbpingjian:{ - trigger:{player:['useSkill','logSkillBegin']}, - forced:true, - locked:false, - filter:function(event,player){ - var skill=event.sourceSkill||event.skill; - return player.invisibleSkills.includes(skill)&&lib.skill.sbyingmen.getSkills(player.getStorage('sbyingmen'),player).includes(skill); + sbpingjian: { + trigger: { player: ["useSkill", "logSkillBegin"] }, + forced: true, + locked: false, + filter: function (event, player) { + var skill = event.sourceSkill || event.skill; + return ( + player.invisibleSkills.includes(skill) && + lib.skill.sbyingmen.getSkills(player.getStorage("sbyingmen"), player).includes(skill) + ); }, - content:function(){ - 'step 0' - var visitors=player.getStorage('sbyingmen').slice(0); - var drawers=visitors.filter(function(name){ - return Array.isArray(lib.character[name])&&lib.character[name][3].includes(trigger.sourceSkill); + content: function () { + "step 0"; + var visitors = player.getStorage("sbyingmen").slice(0); + var drawers = visitors.filter(function (name) { + return ( + Array.isArray(lib.character[name]) && + lib.character[name][3].includes(trigger.sourceSkill) + ); }); - event.drawers=drawers; - if(visitors.length==1) event._result={bool:true,links:visitors}; - else{ - var dialog=['评鉴:请选择移去一张“访客”']; - if(drawers.length) dialog.push('
              如果移去'+get.translation(drawers)+',则你摸一张牌
              '); - dialog.push([visitors,'character']); - player.chooseButton(dialog,true); + event.drawers = drawers; + if (visitors.length == 1) event._result = { bool: true, links: visitors }; + else { + var dialog = ["评鉴:请选择移去一张“访客”"]; + if (drawers.length) + dialog.push( + '
              如果移去' + + get.translation(drawers) + + ",则你摸一张牌
              " + ); + dialog.push([visitors, "character"]); + player.chooseButton(dialog, true); } - 'step 1' - if(result.bool){ - lib.skill.sbyingmen.removeVisitors(result.links,player); - game.log(player,'移去了','#y'+get.translation(result.links[0])); - if(event.drawers.includes(result.links[0])){ - player.addTempSkill('sbpingjian_draw'); + "step 1"; + if (result.bool) { + lib.skill.sbyingmen.removeVisitors(result.links, player); + game.log(player, "移去了", "#y" + get.translation(result.links[0])); + if (event.drawers.includes(result.links[0])) { + player.addTempSkill("sbpingjian_draw"); player.storage.sbpingjian_draw.push(trigger.skill); } } }, - group:'sbpingjian_trigger', - subSkill:{ - draw:{ - charlotte:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + group: "sbpingjian_trigger", + subSkill: { + draw: { + charlotte: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - onremove:true, - trigger:{player:['useSkillAfter','logSkill']}, - forced:true, - popup:false, - filter:function(event,player){ - return player.getStorage('sbpingjian_draw').includes(event.skill); + onremove: true, + trigger: { player: ["useSkillAfter", "logSkill"] }, + forced: true, + popup: false, + filter: function (event, player) { + return player.getStorage("sbpingjian_draw").includes(event.skill); }, - content:function(){ + content: function () { player.storage.sbpingjian_draw.remove(trigger.skill); player.draw(); - if(!player.storage.sbpingjian_draw.length) player.removeSkill('sbpingjian_draw'); + if (!player.storage.sbpingjian_draw.length) player.removeSkill("sbpingjian_draw"); }, }, - trigger:{ - trigger:{player:'triggerInvisible'}, - forced:true, - forceDie:true, - popup:false, - charlotte:true, - priority:10, - filter:function(event,player){ - if(event.revealed) return false; - var info=get.info(event.skill); - if(info.charlotte) return false; - var skills=lib.skill.sbyingmen.getSkills(player.getStorage('sbyingmen'),player); + trigger: { + trigger: { player: "triggerInvisible" }, + forced: true, + forceDie: true, + popup: false, + charlotte: true, + priority: 10, + filter: function (event, player) { + if (event.revealed) return false; + var info = get.info(event.skill); + if (info.charlotte) return false; + var skills = lib.skill.sbyingmen.getSkills( + player.getStorage("sbyingmen"), + player + ); game.expandSkills(skills); return skills.includes(event.skill); }, - content:function(){ - "step 0" - if(get.info(trigger.skill).silent){ + content: function () { + "step 0"; + if (get.info(trigger.skill).silent) { event.finish(); - } - else{ - var info=get.info(trigger.skill); - var event=trigger,trigger=event._trigger; + } else { + var info = get.info(trigger.skill); + var event = trigger, + trigger = event._trigger; var str; - var check=info.check; - if(info.prompt) str=info.prompt; - else{ - if(typeof info.logTarget=='string'){ - str=get.prompt(event.skill,trigger[info.logTarget],player); - } - else if(typeof info.logTarget=='function'){ - var logTarget=info.logTarget(trigger,player,trigger.triggername,trigger.indexedData); - if(get.itemtype(logTarget).indexOf('player')==0) str=get.prompt(event.skill,logTarget,player); - } - else{ - str=get.prompt(event.skill,null,player); + var check = info.check; + if (info.prompt) str = info.prompt; + else { + if (typeof info.logTarget == "string") { + str = get.prompt(event.skill, trigger[info.logTarget], player); + } else if (typeof info.logTarget == "function") { + var logTarget = info.logTarget( + trigger, + player, + trigger.triggername, + trigger.indexedData + ); + if (get.itemtype(logTarget).indexOf("player") == 0) + str = get.prompt(event.skill, logTarget, player); + } else { + str = get.prompt(event.skill, null, player); } } - if(typeof str=='function'){str=str(trigger,player,trigger.triggername,trigger.indexedData)} - var next=player.chooseBool('评鉴:'+str); - next.set('yes',!info.check||info.check(trigger,player,trigger.triggername,trigger.indexedData)); - next.set('hsskill',event.skill); - next.set('forceDie',true); - next.set('ai',function(){ + if (typeof str == "function") { + str = str(trigger, player, trigger.triggername, trigger.indexedData); + } + var next = player.chooseBool("评鉴:" + str); + next.set( + "yes", + !info.check || + info.check(trigger, player, trigger.triggername, trigger.indexedData) + ); + next.set("hsskill", event.skill); + next.set("forceDie", true); + next.set("ai", function () { return _status.event.yes; }); - if(typeof info.prompt2=='function'){ - next.set('prompt2',info.prompt2(trigger,player,trigger.triggername,trigger.indexedData)); + if (typeof info.prompt2 == "function") { + next.set( + "prompt2", + info.prompt2( + trigger, + player, + trigger.triggername, + trigger.indexedData + ) + ); + } else if (typeof info.prompt2 == "string") { + next.set("prompt2", info.prompt2); + } else if (info.prompt2 != false) { + if (lib.dynamicTranslate[event.skill]) + next.set( + "prompt2", + lib.dynamicTranslate[event.skill](player, event.skill) + ); + else if (lib.translate[event.skill + "_info"]) + next.set("prompt2", lib.translate[event.skill + "_info"]); } - else if(typeof info.prompt2=='string'){ - next.set('prompt2',info.prompt2); - } - else if(info.prompt2!=false){ - if(lib.dynamicTranslate[event.skill]) next.set('prompt2',lib.dynamicTranslate[event.skill](player,event.skill)); - else if(lib.translate[event.skill+'_info']) next.set('prompt2',lib.translate[event.skill+'_info']); - } - if(trigger.skillwarn){ - if(next.prompt2){ - next.set('prompt2',''+trigger.skillwarn+'。'+next.prompt2); - } - else{ - next.set('prompt2',trigger.skillwarn); + if (trigger.skillwarn) { + if (next.prompt2) { + next.set( + "prompt2", + '' + + trigger.skillwarn + + "。" + + next.prompt2 + ); + } else { + next.set("prompt2", trigger.skillwarn); } } } - "step 1" - if(result.bool){ - trigger.revealed=true; - } - else{ + "step 1"; + if (result.bool) { + trigger.revealed = true; + } else { trigger.untrigger(); - trigger.cancelled=true; + trigger.cancelled = true; } - } + }, + }, + }, + ai: { + combo: "sbyingmen", + }, + }, + jsrgchaozheng: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + logTarget: function (event, player) { + return game.filterPlayer((i) => i != player); + }, + prompt: "是否发动【朝争】?", + content: function () { + player + .chooseToDebate(game.filterPlayer((i) => i != player)) + .set("callback", lib.skill.jsrgchaozheng.callback); + }, + callback: function () { + var result = event.debateResult; + if (result.bool && result.opinion) { + var opinion = result.opinion, + targets = result.red.map((i) => i[0]); + targets.sortBySeat(); + targets.forEach((i) => i[opinion == "red" ? "recover" : "loseHp"]()); + if (targets.length == 0 || result.black.length == 0) + player.draw(result.targets.length); + } + }, + }, + jsrgshenchong: { + audio: 2, + enable: "phaseUse", + limited: true, + filterTarget: lib.filter.notMe, + skillAnimation: true, + animationColor: "soil", + content: function () { + "step 0"; + player.awakenSkill("jsrgshenchong"); + target.addSkillLog("jsrgfeiyang"); + target.addSkillLog("jsrgbahu"); + "step 1"; + player.addSkill("jsrgshenchong_die"); + player.markAuto("jsrgshenchong_die", [target]); + }, + ai: { + order: 1, + result: { target: 1 }, + }, + subSkill: { + die: { + audio: "jsrgshenchong", + trigger: { player: "die" }, + charlotte: true, + forced: true, + forceDie: true, + filter: function (event, player) { + return player.getStorage("jsrgshenchong_die").length; + }, + content: function () { + var targets = player.getStorage("jsrgshenchong_die"); + player.line(targets); + targets.sortBySeat().forEach((current) => { + current.clearSkills(true); + current.chooseToDiscard(current.countCards("h"), "h", true); + }); + }, }, }, }, - jsrgchaozheng:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - logTarget:function(event,player){ - return game.filterPlayer(i=>i!=player); + jsrgfeiyang: { + trigger: { player: "phaseJudgeBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("j") && player.countCards("h") > 1; }, - prompt:'是否发动【朝争】?', - content:function(){ - player.chooseToDebate(game.filterPlayer(i=>i!=player)).set('callback',lib.skill.jsrgchaozheng.callback); - }, - callback:function(){ - var result=event.debateResult; - if(result.bool&&result.opinion){ - var opinion=result.opinion,targets=result.red.map(i=>i[0]); - targets.sortBySeat(); - targets.forEach(i=>i[opinion=='red'?'recover':'loseHp']()); - if(targets.length==0||result.black.length==0) player.draw(result.targets.length); - } - } - }, - jsrgshenchong:{ - audio:2, - enable:'phaseUse', - limited:true, - filterTarget:lib.filter.notMe, - skillAnimation:true, - animationColor:'soil', - content:function(){ - 'step 0' - player.awakenSkill('jsrgshenchong'); - target.addSkillLog('jsrgfeiyang'); - target.addSkillLog('jsrgbahu'); - 'step 1' - player.addSkill('jsrgshenchong_die'); - player.markAuto('jsrgshenchong_die',[target]); - }, - ai:{ - order:1, - result:{target:1} - }, - subSkill:{ - die:{ - audio:'jsrgshenchong', - trigger:{player:'die'}, - charlotte:true, - forced:true, - forceDie:true, - filter:function(event,player){ - return player.getStorage('jsrgshenchong_die').length; - }, - content:function(){ - var targets=player.getStorage('jsrgshenchong_die'); - player.line(targets); - targets.sortBySeat().forEach(current=>{ - current.clearSkills(true); - current.chooseToDiscard(current.countCards('h'),'h',true); - }); - } - } - } - }, - jsrgfeiyang:{ - trigger:{player:'phaseJudgeBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('j')&&player.countCards('h')>1; - }, - content:function(){ - 'step 0' - player.chooseToDiscard('h',2,get.prompt('jsrgfeiyang'),'弃置两张手牌并弃置判定区里的一张牌').set('logSkill','jsrgfeiyang').set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',(()=>{ - if(player.hasSkillTag('rejudge')&&player.countCards('j')<2) return false; - return player.hasCard(function(card){ - if(get.tag(card,'damage')&&get.damageEffect(player,player,_status.event.player,get.natureList(card))>=0) return false; - return get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)<0; - },'j'); - })()); - 'step 1' - if(result.bool){ - player.discardPlayerCard(player,'j',true); + content: function () { + "step 0"; + player + .chooseToDiscard( + "h", + 2, + get.prompt("jsrgfeiyang"), + "弃置两张手牌并弃置判定区里的一张牌" + ) + .set("logSkill", "jsrgfeiyang") + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set( + "goon", + (() => { + if (player.hasSkillTag("rejudge") && player.countCards("j") < 2) return false; + return player.hasCard(function (card) { + if ( + get.tag(card, "damage") && + get.damageEffect( + player, + player, + _status.event.player, + get.natureList(card) + ) >= 0 + ) + return false; + return ( + get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) < 0 + ); + }, "j"); + })() + ); + "step 1"; + if (result.bool) { + player.discardPlayerCard(player, "j", true); } }, }, - jsrgbahu:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ + jsrgbahu: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { player.draw(); }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, - jsrgjulian:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasZhuSkill('jsrgjulian')&&lib.skill.jsrgjulian.logTarget(null,player).length; + jsrgjulian: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.hasZhuSkill("jsrgjulian") && + lib.skill.jsrgjulian.logTarget(null, player).length + ); }, - prompt:'是否发动【聚敛】?', - prompt2:'你可以获得其他所有群势力角色的各一张牌', - logTarget:function(event,player){ - return game.filterPlayer(current=>{ - return current.group=='qun'&¤t.countGainableCards(player,'he')>0&¤t!=player; - }) - }, - content:function(){ - game.filterPlayer(current=>{ - return current.group=='qun'&¤t!=player; - }).sortBySeat().forEach(i=>{ - player.gainPlayerCard(i,'he',true); + prompt: "是否发动【聚敛】?", + prompt2: "你可以获得其他所有群势力角色的各一张牌", + logTarget: function (event, player) { + return game.filterPlayer((current) => { + return ( + current.group == "qun" && + current.countGainableCards(player, "he") > 0 && + current != player + ); }); }, - group:'jsrgjulian_draw', - zhuSkill:true, - subSkill:{ - draw:{ - audio:'jsrgjulian', - trigger:{global:'gainAfter'}, - filter:function(event,player){ - var source=event.player; - if(source==player||source.group!='qun') return false; - var evt=event.getParent('phaseDraw'); - return (!evt||evt.player!=source)&&event.getParent().name=='draw'&&event.getParent(2).name!='jsrgjulian_draw'&&player.hasZhuSkill('jsrgjulian',event.player); + content: function () { + game.filterPlayer((current) => { + return current.group == "qun" && current != player; + }) + .sortBySeat() + .forEach((i) => { + player.gainPlayerCard(i, "he", true); + }); + }, + group: "jsrgjulian_draw", + zhuSkill: true, + subSkill: { + draw: { + audio: "jsrgjulian", + trigger: { global: "gainAfter" }, + filter: function (event, player) { + var source = event.player; + if (source == player || source.group != "qun") return false; + var evt = event.getParent("phaseDraw"); + return ( + (!evt || evt.player != source) && + event.getParent().name == "draw" && + event.getParent(2).name != "jsrgjulian_draw" && + player.hasZhuSkill("jsrgjulian", event.player) + ); }, - direct:true, - usable:2, - content:function(){ - 'step 0' - var source=trigger.player; - event.source=source; - source.chooseBool('是否响应'+get.translation(player)+'的【聚敛】摸一张牌?'); - 'step 1' - if(result.bool){ - source.logSkill('jsrgjulian_draw',player); + direct: true, + usable: 2, + content: function () { + "step 0"; + var source = trigger.player; + event.source = source; + source.chooseBool("是否响应" + get.translation(player) + "的【聚敛】摸一张牌?"); + "step 1"; + if (result.bool) { + source.logSkill("jsrgjulian_draw", player); source.draw(); - } - else player.storage.counttrigger.jsrgjulian_draw--; - } + } else player.storage.counttrigger.jsrgjulian_draw--; + }, }, - give:{ - charlotte:true, - onremove:true - } - } + give: { + charlotte: true, + onremove: true, + }, + }, }, //何进 - jsrgzhaobing:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of hs){ - if(!lib.filter.cardDiscardable(i,player,'jsrgzhaobing')) return false; + jsrgzhaobing: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of hs) { + if (!lib.filter.cardDiscardable(i, player, "jsrgzhaobing")) return false; } return true; }, - content:function(){ - 'step 0' - var cards=player.getCards('h'); - var num=cards.length; - var prompt2='弃置所有手牌,令至多'+get.cnNumber(num)+'名其他角色依次选择一项:1.正面向上交给你一张【杀】;2.失去1点体力'; - player.chooseTarget(get.prompt('jsrgzhaobing'),prompt2,[1,num],lib.filter.notMe).set('ai',target=>{ - if(!_status.event.goon) return 0; - return 2-get.attitude(_status.event.player,target); - }).set('goon',num/2{ - return 2-get.attitude(player,current)>0; - })); - 'step 1' - if(result.bool){ - player.logSkill('jsrgzhaobing',result.targets); - event.targets=result.targets; + content: function () { + "step 0"; + var cards = player.getCards("h"); + var num = cards.length; + var prompt2 = + "弃置所有手牌,令至多" + + get.cnNumber(num) + + "名其他角色依次选择一项:1.正面向上交给你一张【杀】;2.失去1点体力"; + player + .chooseTarget(get.prompt("jsrgzhaobing"), prompt2, [1, num], lib.filter.notMe) + .set("ai", (target) => { + if (!_status.event.goon) return 0; + return 2 - get.attitude(_status.event.player, target); + }) + .set( + "goon", + num / 2 < + game.countPlayer((current) => { + return 2 - get.attitude(player, current) > 0; + }) + ); + "step 1"; + if (result.bool) { + player.logSkill("jsrgzhaobing", result.targets); + event.targets = result.targets; event.targets.sortBySeat(); - player.chooseToDiscard(true,'h',player.countCards('h')); - } - else event.finish(); - 'step 2' - var target=targets.shift(); - event.target=target; - target.chooseCard('诏兵:交给'+get.translation(player)+'一张【杀】,或失去1点体力',(card)=>{ - return get.name(card)=='sha'; - }).set('ai',card=>{ - if(_status.event.goon) return 0; - return 6-get.value(card); - }).set('goon',get.effect(target,{name:'losehp'},target,target)>=0); - 'step 3' - if(result.bool) target.give(result.cards,player,true); + player.chooseToDiscard(true, "h", player.countCards("h")); + } else event.finish(); + "step 2"; + var target = targets.shift(); + event.target = target; + target + .chooseCard( + "诏兵:交给" + get.translation(player) + "一张【杀】,或失去1点体力", + (card) => { + return get.name(card) == "sha"; + } + ) + .set("ai", (card) => { + if (_status.event.goon) return 0; + return 6 - get.value(card); + }) + .set("goon", get.effect(target, { name: "losehp" }, target, target) >= 0); + "step 3"; + if (result.bool) target.give(result.cards, player, true); else target.loseHp(); - if(targets.length) event.goto(2); + if (targets.length) event.goto(2); + }, + ai: { + expose: 0.2, }, - ai:{ - expose:0.2 - } }, - jsrgzhuhuan:{ - audio:'mouzhu', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - var hs=player.getCards('h','sha'); - if(!hs.length) return false; - for(var i of hs){ - if(!lib.filter.cardDiscardable(i,player,'jsrgzhuhuan')) return false; + jsrgzhuhuan: { + audio: "mouzhu", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + var hs = player.getCards("h", "sha"); + if (!hs.length) return false; + for (var i of hs) { + if (!lib.filter.cardDiscardable(i, player, "jsrgzhuhuan")) return false; } return true; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jsrgzhuhuan'),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return get.damageEffect(target,player,player); + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("jsrgzhuhuan"), lib.filter.notMe).set("ai", (target) => { + var player = _status.event.player; + return get.damageEffect(target, player, player); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jsrgzhuhuan',target); - var hs=player.getCards('h','sha'); - event.num=hs.length; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jsrgzhuhuan", target); + var hs = player.getCards("h", "sha"); + event.num = hs.length; player.discard(hs); - } - else event.finish(); - 'step 2' - target.chooseToDiscard(get.translation(player)+'对你发动了【诛宦】','弃置'+get.cnNumber(num)+'张牌并失去1点体力;或点击“取消”令其回复1点体力且其摸'+get.cnNumber(num)+'张牌').set('ai',card=>{ - if(_status.event.goon) return 0; - return 5.5-get.value(card); - }).set('goon',target.hp<=2||get.attitude(target,player)>=0||player.isHealthy()); - 'step 3' - if(result.bool){ + } else event.finish(); + "step 2"; + target + .chooseToDiscard( + get.translation(player) + "对你发动了【诛宦】", + "弃置" + + get.cnNumber(num) + + "张牌并失去1点体力;或点击“取消”令其回复1点体力且其摸" + + get.cnNumber(num) + + "张牌" + ) + .set("ai", (card) => { + if (_status.event.goon) return 0; + return 5.5 - get.value(card); + }) + .set( + "goon", + target.hp <= 2 || get.attitude(target, player) >= 0 || player.isHealthy() + ); + "step 3"; + if (result.bool) { target.loseHp(); - } - else{ + } else { player.draw(num); player.recover(); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - jsrgyanhuo:{ - inherit:'spyanhuo', - forced:true, + jsrgyanhuo: { + inherit: "spyanhuo", + forced: true, }, //孙坚 - jsrgpingtao:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - var att=get.attitude(target,player); - target.chooseCard(get.translation(player)+'对你发动了【平讨】','交给其一张牌并令其此回合使用【杀】的次数上限+1;或点击“取消”令其视为对你使用一张【杀】','he').set('ai',card=>{ - if(_status.event.give){ - if(card.name=='sha'||card.name=='tao'||card.name=='jiu') return 0; - return 8-get.value(card); - } - if(_status.event.att<0&&card.name=='sha') return -1; - return 4-get.value(card); - }).set('give',(att>=0||target.hp==1&&target.countCards('hs','shan')<=1)&&get.effect(target,{name:'sha'},player,target)<0).set('att',att); - 'step 1' - if(result.bool){ - target.give(result.cards,player); - player.addTempSkill('jsrgpingtao_sha'); - player.addMark('jsrgpingtao_sha',1,false); - } - else if(player.canUse('sha',target,false)){ - player.useCard({name:'sha',isCard:true},target,false); + jsrgpingtao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + var att = get.attitude(target, player); + target + .chooseCard( + get.translation(player) + "对你发动了【平讨】", + "交给其一张牌并令其此回合使用【杀】的次数上限+1;或点击“取消”令其视为对你使用一张【杀】", + "he" + ) + .set("ai", (card) => { + if (_status.event.give) { + if (card.name == "sha" || card.name == "tao" || card.name == "jiu") return 0; + return 8 - get.value(card); + } + if (_status.event.att < 0 && card.name == "sha") return -1; + return 4 - get.value(card); + }) + .set( + "give", + (att >= 0 || (target.hp == 1 && target.countCards("hs", "shan") <= 1)) && + get.effect(target, { name: "sha" }, player, target) < 0 + ) + .set("att", att); + "step 1"; + if (result.bool) { + target.give(result.cards, player); + player.addTempSkill("jsrgpingtao_sha"); + player.addMark("jsrgpingtao_sha", 1, false); + } else if (player.canUse("sha", target, false)) { + player.useCard({ name: "sha", isCard: true }, target, false); } }, - ai:{ - expose:0.15, - order:5, - result:{target:-1} + ai: { + expose: 0.15, + order: 5, + result: { target: -1 }, }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - marktext:'讨', - intro:{ - content:'本回合使用【杀】的次数上限+#', + subSkill: { + sha: { + charlotte: true, + onremove: true, + marktext: "讨", + intro: { + content: "本回合使用【杀】的次数上限+#", }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('jsrgpingtao_sha'); + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("jsrgpingtao_sha"); }, - } - } - } - }, - jsrgjuelie:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return player.countCards('he')&&event.card.name=='sha'; + }, + }, }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('jsrgjuelie',trigger.target),'当你使用【杀】指定一名角色为目标后,你可以弃置任意张牌,然后弃置其等量的牌',[1,Infinity],'he').set('ai',card=>{ - if(ui.selected.cards.length>=_status.event.max) return 0; - if(_status.event.goon) return 4.5-get.value(card); - return 0; - }).set('max',trigger.target.countDiscardableCards(player,'he')).set('goon',get.attitude(player,trigger.target)<0).set('logSkill',['jsrgjuelie_discard',trigger.target]); - 'step 1' - if(result.bool){ - var num=result.cards.length; - if(trigger.target.countDiscardableCards(player,'he')) player.discardPlayerCard('平讨:弃置'+get.translation(trigger.target)+get.cnNumber(num)+'张牌',num,'he',trigger.target,true); + }, + jsrgjuelie: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return player.countCards("he") && event.card.name == "sha"; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("jsrgjuelie", trigger.target), + "当你使用【杀】指定一名角色为目标后,你可以弃置任意张牌,然后弃置其等量的牌", + [1, Infinity], + "he" + ) + .set("ai", (card) => { + if (ui.selected.cards.length >= _status.event.max) return 0; + if (_status.event.goon) return 4.5 - get.value(card); + return 0; + }) + .set("max", trigger.target.countDiscardableCards(player, "he")) + .set("goon", get.attitude(player, trigger.target) < 0) + .set("logSkill", ["jsrgjuelie_discard", trigger.target]); + "step 1"; + if (result.bool) { + var num = result.cards.length; + if (trigger.target.countDiscardableCards(player, "he")) + player.discardPlayerCard( + "平讨:弃置" + get.translation(trigger.target) + get.cnNumber(num) + "张牌", + num, + "he", + trigger.target, + true + ); } /* else event.finish(); @@ -6241,2132 +7644,2667 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } */ }, - shaRelated:true, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.name||arg.name!='sha') return false; - if(!arg.target) return false; - var card=arg.target.getEquip(2); - return card&&get.value(card)>0&&player.hasCard(cardx=>{ - return lib.filter.cardDiscardable(cardx,player,'jsrgjuelie_discard')&&get.value(cardx)<5; - }); + shaRelated: true, + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.name || arg.name != "sha") return false; + if (!arg.target) return false; + var card = arg.target.getEquip(2); + return ( + card && + get.value(card) > 0 && + player.hasCard((cardx) => { + return ( + lib.filter.cardDiscardable(cardx, player, "jsrgjuelie_discard") && + get.value(cardx) < 5 + ); + }) + ); }, }, - group:'jsrgjuelie_pojun', - subSkill:{ - pojun:{ - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - if(!player.isMinHandcard()&&!player.isMinHp()) return false; - return event.getParent().name=='sha'; + group: "jsrgjuelie_pojun", + subSkill: { + pojun: { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + if (!player.isMinHandcard() && !player.isMinHp()) return false; + return event.getParent().name == "sha"; }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ + forced: true, + locked: false, + logTarget: "player", + content: function () { trigger.num++; }, }, }, }, //皇甫嵩 - jsrgguanhuo:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.card.storage&&event.card.storage.jsrgguanhuo&&!game.hasPlayer2(current=>{ - return current.hasHistory('damage',evt=>evt.card==event.card); - }); + jsrgguanhuo: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.jsrgguanhuo && + !game.hasPlayer2((current) => { + return current.hasHistory("damage", (evt) => evt.card == event.card); + }) + ); }, - forced:true, - locked:false, - group:'jsrgguanhuo_viewas', - content:function(){ - 'step 0' - var count=player.getHistory('useSkill',evt=>evt.skill=='jsrgguanhuo_viewas').length; - if(count==1){ - player.addTempSkill('jsrgguanhuo_ex','phaseUseAfter'); - player.addMark('jsrgguanhuo_ex',1,false); - trigger.targets.forEach(i=>i.removeSkill('huogong2')); - } - else{ - player.removeSkills('jsrgguanhuo'); + forced: true, + locked: false, + group: "jsrgguanhuo_viewas", + content: function () { + "step 0"; + var count = player.getHistory( + "useSkill", + (evt) => evt.skill == "jsrgguanhuo_viewas" + ).length; + if (count == 1) { + player.addTempSkill("jsrgguanhuo_ex", "phaseUseAfter"); + player.addMark("jsrgguanhuo_ex", 1, false); + trigger.targets.forEach((i) => i.removeSkill("huogong2")); + } else { + player.removeSkills("jsrgguanhuo"); } }, - ai:{ - effect:{ - player:function(card,player){ - if(_status.event.getParent().skill=='jsrgguanhuo_viewas'&&player.getHistory('useSkill',evt=>evt.skill=='jsrgguanhuo_viewas').length==1) return 'zeroplayertarget'; - if(_status.event.type=='phase'&&_status.event.skill=='jsrgguanhuo_viewas'&&player.getHistory('useSkill',evt=>evt.skill=='jsrgguanhuo_viewas').length>1&&player.countCards('h')<=3) return [0,0]; - } - } - }, - subSkill:{ - viewas:{ - audio:'jsrgguanhuo', - enable:'phaseUse', - viewAs:{ - name:'huogong', - isCard:true, - storage:{ - jsrgguanhuo:true - } + ai: { + effect: { + player: function (card, player) { + if ( + _status.event.getParent().skill == "jsrgguanhuo_viewas" && + player.getHistory("useSkill", (evt) => evt.skill == "jsrgguanhuo_viewas") + .length == 1 + ) + return "zeroplayertarget"; + if ( + _status.event.type == "phase" && + _status.event.skill == "jsrgguanhuo_viewas" && + player.getHistory("useSkill", (evt) => evt.skill == "jsrgguanhuo_viewas") + .length > 1 && + player.countCards("h") <= 3 + ) + return [0, 0]; }, - filterCard:()=>false, - selectCard:-1, - prompt:'视为使用一张【火攻】', - ai:{ - order:function(item,player){ - return get.order({name:'huogong'})+0.01; - }, - } }, - ex:{ - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return event.card&&event.card.name=='huogong'&&event.getParent().type=='card'; + }, + subSkill: { + viewas: { + audio: "jsrgguanhuo", + enable: "phaseUse", + viewAs: { + name: "huogong", + isCard: true, + storage: { + jsrgguanhuo: true, + }, }, - forced:true, - charlotte:true, - onremove:true, - intro:{content:'当你造成渠道为【火攻】的伤害时,此伤害+#'}, - content:function(){ - trigger.num+=player.countMark('jsrgguanhuo_ex'); - } - } - } + filterCard: () => false, + selectCard: -1, + prompt: "视为使用一张【火攻】", + ai: { + order: function (item, player) { + return get.order({ name: "huogong" }) + 0.01; + }, + }, + }, + ex: { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + event.card && event.card.name == "huogong" && event.getParent().type == "card" + ); + }, + forced: true, + charlotte: true, + onremove: true, + intro: { content: "当你造成渠道为【火攻】的伤害时,此伤害+#" }, + content: function () { + trigger.num += player.countMark("jsrgguanhuo_ex"); + }, + }, + }, }, - jsrgjuxia:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - usable:1, - countSkill:function(player){ - return player.getSkills(null,false,false).filter(function(skill){ - var info=get.info(skill); - if(!info||info.charlotte) return false; - if(info.zhuSkill) return player.hasZhuSkill(skill); + jsrgjuxia: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + usable: 1, + countSkill: function (player) { + return player.getSkills(null, false, false).filter(function (skill) { + var info = get.info(skill); + if (!info || info.charlotte) return false; + if (info.zhuSkill) return player.hasZhuSkill(skill); return true; }).length; }, - filter:function(event,player){ - return event.player!=player&&lib.skill.jsrgjuxia.countSkill(event.player)>lib.skill.jsrgjuxia.countSkill(player); + filter: function (event, player) { + return ( + event.player != player && + lib.skill.jsrgjuxia.countSkill(event.player) > lib.skill.jsrgjuxia.countSkill(player) + ); }, - direct:true, - content:function(){ - 'step 0' - var goon=get.effect(player,trigger.card,trigger.player,trigger.player)<1; - if(goon&&!event.isMine()&&!event.isOnline()) game.delayx(); - trigger.player.chooseBool('是否对'+get.translation(player)+'发动【居下】?','令'+get.translation(trigger.card)+'对其无效,然后其摸两张牌').set('ai',()=>{ - return _status.event.goon; - }).set('goon',goon); - 'step 1' - if(result.bool){ - trigger.player.logSkill('jsrgjuxia',player); + direct: true, + content: function () { + "step 0"; + var goon = get.effect(player, trigger.card, trigger.player, trigger.player) < 1; + if (goon && !event.isMine() && !event.isOnline()) game.delayx(); + trigger.player + .chooseBool( + "是否对" + get.translation(player) + "发动【居下】?", + "令" + get.translation(trigger.card) + "对其无效,然后其摸两张牌" + ) + .set("ai", () => { + return _status.event.goon; + }) + .set("goon", goon); + "step 1"; + if (result.bool) { + trigger.player.logSkill("jsrgjuxia", player); trigger.excluded.add(player); player.draw(2); - } - else player.storage.counttrigger.jsrgjuxia--; + } else player.storage.counttrigger.jsrgjuxia--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(lib.skill.jsrgjuxia.countSkill(target)>=lib.skill.jsrgjuxia.countSkill(player)) return; - if(card&&(card.cards||card.isCard)&&get.attitude(target,player)>0&&(!target.storage.counttrigger||!target.storage.counttrigger.jsrgjuxia)) return [0,0.5,0,0.5]; + ai: { + effect: { + target: function (card, player, target) { + if ( + lib.skill.jsrgjuxia.countSkill(target) >= + lib.skill.jsrgjuxia.countSkill(player) + ) + return; + if ( + card && + (card.cards || card.isCard) && + get.attitude(target, player) > 0 && + (!target.storage.counttrigger || !target.storage.counttrigger.jsrgjuxia) + ) + return [0, 0.5, 0, 0.5]; }, }, - } + }, }, //许劭 - jsrgyingmen:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:['enterGame','phaseBegin'], + jsrgyingmen: { + audio: 2, + trigger: { + global: "phaseBefore", + player: ["enterGame", "phaseBegin"], }, - forced:true, - filter:function(event,player,name){ - if(player.getStorage('jsrgyingmen').length>=4) return false; - if(name=='phaseBefore') return game.phaseNumber==0; - return event.name!='phase'||event.player==player; + forced: true, + filter: function (event, player, name) { + if (player.getStorage("jsrgyingmen").length >= 4) return false; + if (name == "phaseBefore") return game.phaseNumber == 0; + return event.name != "phase" || event.player == player; }, - update:function(player){ - var id=player.playerid; - var characters=player.getStorage('jsrgyingmen'); - var skillName='jsrgpingjian_'+id; - var skillsx=[],skillsx2=[]; - var map={}; - var skillsy=lib.skill[skillName]?lib.skill[skillName].group:[]; - for(var name of characters){ - var skills=lib.character[name][3].slice(); - skills=skills.filter(skill=>{ - var list=get.skillCategoriesOf(skill,player); - list.removeArray(['锁定技','Charlotte']); - if(list.length) return false; - var info=get.info(skill); - return info&&(!info.unique||info.gainable); + update: function (player) { + var id = player.playerid; + var characters = player.getStorage("jsrgyingmen"); + var skillName = "jsrgpingjian_" + id; + var skillsx = [], + skillsx2 = []; + var map = {}; + var skillsy = lib.skill[skillName] ? lib.skill[skillName].group : []; + for (var name of characters) { + var skills = lib.character[name][3].slice(); + skills = skills.filter((skill) => { + var list = get.skillCategoriesOf(skill, player); + list.removeArray(["锁定技", "Charlotte"]); + if (list.length) return false; + var info = get.info(skill); + return info && (!info.unique || info.gainable); }); game.expandSkills(skills); - for(var i=0;i{ - return lib.skill.jsrgyingmen.bannedList.includes(skill); - })) continue; + for (var i = 0; i < _status.characterlist.length; i++) { + var name = _status.characterlist[i]; + var skills = lib.character[name][3].slice(); + if ( + skills.some((skill) => { + return lib.skill.jsrgyingmen.bannedList.includes(skill); + }) + ) + continue; list.push(name); _status.characterlist.remove(name); - if(list.length>=4-num) break; + if (list.length >= 4 - num) break; } - if(list.length){ - player.markAuto('jsrgyingmen',list); - if(player.hasSkill('jsrgpingjian',null,false,false)) lib.skill.jsrgyingmen.update(player); - game.log(player,'将','#g'+get.translation(list),'置为','#y访客'); - game.broadcastAll(function(player,list){ - var cards=[]; - for(var i=0;i{ - return skill.indexOf(skillx)==0||name.indexOf(skillx+'_'+player.playerid)==0; - })) return true; + var info = get.info(skill); + if (info && (info.charlotte || info.silent)) continue; + if ( + skills.some((skillx) => { + return ( + skill.indexOf(skillx) == 0 || + name.indexOf(skillx + "_" + player.playerid) == 0 + ); + }) + ) + return true; } return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var current; - var skill=trigger.skill,name=trigger.event?trigger.event.name:''; - var visitors=player.getStorage('jsrgyingmen'); - for(var visitor of visitors){ - var skills=lib.character[visitor][3].slice(); + var skill = trigger.skill, + name = trigger.event ? trigger.event.name : ""; + var visitors = player.getStorage("jsrgyingmen"); + for (var visitor of visitors) { + var skills = lib.character[visitor][3].slice(); game.expandSkills(skills); - var info=get.info(skill); - if(info&&info.charlotte) continue; - if(skills.some(skillx=>{ - return skill.indexOf(skillx)==0||name.indexOf(skillx+'_'+player.playerid)==0; - })){ - current=visitor; + var info = get.info(skill); + if (info && info.charlotte) continue; + if ( + skills.some((skillx) => { + return ( + skill.indexOf(skillx) == 0 || + name.indexOf(skillx + "_" + player.playerid) == 0 + ); + }) + ) { + current = visitor; break; } } - event.current=current; - player.chooseButton(['###评鉴:移去一名访客###
              若移去的访客为'+get.translation(current)+',则你摸一张牌
              ',[player.getStorage('jsrgyingmen'),'character']],true).set('ai',button=>{ - if(button.link==_status.event.toremove) return 1; - return Math.random(); - }).set('toremove',function(){ - var list=player.getStorage('jsrgyingmen'); - var rand=Math.random(); - if(rand<0.33) return list[0]; - if(rand<0.66) return current; - return list.randomGet(); - }()); - 'step 1' - if(result.bool){ - var visitor=result.links[0]; - game.log(player,'从','#y访客','中移去了','#g'+get.translation(visitor)); + event.current = current; + player + .chooseButton( + [ + '###评鉴:移去一名访客###
              若移去的访客为' + + get.translation(current) + + ",则你摸一张牌
              ", + [player.getStorage("jsrgyingmen"), "character"], + ], + true + ) + .set("ai", (button) => { + if (button.link == _status.event.toremove) return 1; + return Math.random(); + }) + .set( + "toremove", + (function () { + var list = player.getStorage("jsrgyingmen"); + var rand = Math.random(); + if (rand < 0.33) return list[0]; + if (rand < 0.66) return current; + return list.randomGet(); + })() + ); + "step 1"; + if (result.bool) { + var visitor = result.links[0]; + game.log(player, "从", "#y访客", "中移去了", "#g" + get.translation(visitor)); player.popup(visitor); - player.unmarkAuto('jsrgyingmen',[visitor]); + player.unmarkAuto("jsrgyingmen", [visitor]); _status.characterlist.add(visitor); - if(visitor==event.current) player.draw(); + if (visitor == event.current) player.draw(); lib.skill.jsrgyingmen.update(player); } }, - subSkill:{ - blocker:{ - init:function(player,skill){ + subSkill: { + blocker: { + init: function (player, skill) { player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); }, - charlotte:true, - locked:true, - skillBlocker:function(skill,player){ - if(skill!='jsrgpingjian_'+player.playerid) return false; - if(player._jsrgpingjian_blockerChecking) return; - player._jsrgpingjian_blockerChecking=true; - var own=player.hasSkill('jsrgpingjian'); + charlotte: true, + locked: true, + skillBlocker: function (skill, player) { + if (skill != "jsrgpingjian_" + player.playerid) return false; + if (player._jsrgpingjian_blockerChecking) return; + player._jsrgpingjian_blockerChecking = true; + var own = player.hasSkill("jsrgpingjian"); delete player._jsrgpingjian_blockerChecking; return !own; - } + }, }, - } + }, }, //董白 - jsrgshichong:{ - audio:2, - zhuanhuanji:true, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.target!=player&&event.targets.length==1&&event.target.isIn()&&event.target.countCards('h'); + jsrgshichong: { + audio: 2, + zhuanhuanji: true, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return ( + event.target != player && + event.targets.length == 1 && + event.target.isIn() && + event.target.countCards("h") + ); }, - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - var str='转换技。当你使用牌指定其他角色为唯一目标后,'; - if(storage) return str+'目标角色可以交给你一张手牌。'; - return str+'你可以获得目标角色一张手牌。'; + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + var str = "转换技。当你使用牌指定其他角色为唯一目标后,"; + if (storage) return str + "目标角色可以交给你一张手牌。"; + return str + "你可以获得目标角色一张手牌。"; }, }, - content:function(){ - 'step 0' - if(!player.storage.jsrgshichong){ - player.chooseBool(get.prompt('jsrgshichong',trigger.target),'你可以获得该角色的一张手牌').set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.attitude(player,trigger.target)<=0); + content: function () { + "step 0"; + if (!player.storage.jsrgshichong) { + player + .chooseBool( + get.prompt("jsrgshichong", trigger.target), + "你可以获得该角色的一张手牌" + ) + .set("ai", () => { + return _status.event.bool; + }) + .set("bool", get.attitude(player, trigger.target) <= 0); + } else { + trigger.target + .chooseCard( + "是否发动" + get.translation(player) + "的【恃宠】?", + "你可以选择一张手牌,并交给该角色" + ) + .set("ai", (card) => { + if (_status.event.goon) return 5 - get.value(card); + return 0 - get.value(card); + }) + .set("goon", get.attitude(trigger.target, player) > 2); } - else{ - trigger.target.chooseCard('是否发动'+get.translation(player)+'的【恃宠】?','你可以选择一张手牌,并交给该角色').set('ai',card=>{ - if(_status.event.goon) return 5-get.value(card); - return 0-get.value(card); - }).set('goon',get.attitude(trigger.target,player)>2); - } - 'step 1' - if(result.bool){ - if(!player.storage.jsrgshichong){ - player.logSkill('jsrgshichong',trigger.target); - player.gainPlayerCard(trigger.target,'h',true); + "step 1"; + if (result.bool) { + if (!player.storage.jsrgshichong) { + player.logSkill("jsrgshichong", trigger.target); + player.gainPlayerCard(trigger.target, "h", true); + } else { + trigger.target.logSkill("jsrgshichong", player); + trigger.target.give(result.cards, player); } - else{ - trigger.target.logSkill('jsrgshichong',player); - trigger.target.give(result.cards,player); - } - player.changeZhuanhuanji('jsrgshichong'); + player.changeZhuanhuanji("jsrgshichong"); } - } - }, - jsrglianzhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:{color:'black'}, - position:'h', - filterTarget:lib.filter.notMe, - lose:false, - discard:false, - delay:false, - content:function(){ - 'step 0' - player.showCards(cards,get.translation(player)+'发动了【连诛】'); - 'step 1' - player.give(cards,target); - 'step 2' - event.targets=game.filterPlayer(current=>{ - return current.group==target.group&¤t!=player; - }).sortBySeat(); - game.delayx(); - 'step 3' - var target=targets.shift(); - if(player.canUse('guohe',target)){ - player.useCard({name:'guohe',isCard:true},target); - } - if(targets.length) event.redo(); }, - ai:{ - order:4, - result:{ - target:function(player,target){ - var targets=game.filterPlayer(current=>{ - return current.group==target.group&¤t!=player; - }); - var eff=targets.reduce((p,c)=>{ - return p+get.effect(c,{name:'guohe'},player,player); - },0) - if(ui.selected.cards.length) eff+=get.value(ui.selected.cards[0],target); - return eff; - } + }, + jsrglianzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: { color: "black" }, + position: "h", + filterTarget: lib.filter.notMe, + lose: false, + discard: false, + delay: false, + content: function () { + "step 0"; + player.showCards(cards, get.translation(player) + "发动了【连诛】"); + "step 1"; + player.give(cards, target); + "step 2"; + event.targets = game + .filterPlayer((current) => { + return current.group == target.group && current != player; + }) + .sortBySeat(); + game.delayx(); + "step 3"; + var target = targets.shift(); + if (player.canUse("guohe", target)) { + player.useCard({ name: "guohe", isCard: true }, target); } - } + if (targets.length) event.redo(); + }, + ai: { + order: 4, + result: { + target: function (player, target) { + var targets = game.filterPlayer((current) => { + return current.group == target.group && current != player; + }); + var eff = targets.reduce((p, c) => { + return p + get.effect(c, { name: "guohe" }, player, player); + }, 0); + if (ui.selected.cards.length) eff += get.value(ui.selected.cards[0], target); + return eff; + }, + }, + }, }, //桥玄 - jsrgjuezhi:{ - audio:2, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - if(_status.currentPhase!=player||player.hasSkill('jsrgjuezhi_used',null,null,false)) return false; - return event.card&&event.getParent().type=='card'&&lib.skill.jsrgjuezhi.getNum(event.player,player)>0; + jsrgjuezhi: { + audio: 2, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + if ( + _status.currentPhase != player || + player.hasSkill("jsrgjuezhi_used", null, null, false) + ) + return false; + return ( + event.card && + event.getParent().type == "card" && + lib.skill.jsrgjuezhi.getNum(event.player, player) > 0 + ); }, - forced:true, - locked:false, - getNum:function(target,player){ - return target.countCards('e',card=>{ - var subtype=get.subtypes(card); - for(var i of subtype){ - if(player.hasDisabledSlot(i)) return true; + forced: true, + locked: false, + getNum: function (target, player) { + return target.countCards("e", (card) => { + var subtype = get.subtypes(card); + for (var i of subtype) { + if (player.hasDisabledSlot(i)) return true; } return false; }); }, - group:'jsrgjuezhi_disable', - content:function(){ - player.addTempSkill('jsrgjuezhi_used',['phaseZhunbeiAfter','phaseJudgeAfter','phaseDrawAfter','phaseUseAfter','phaseDiscardAfter','phaseJieshuAfter']); - trigger.num+=lib.skill.jsrgjuezhi.getNum(trigger.player,player); + group: "jsrgjuezhi_disable", + content: function () { + player.addTempSkill("jsrgjuezhi_used", [ + "phaseZhunbeiAfter", + "phaseJudgeAfter", + "phaseDrawAfter", + "phaseUseAfter", + "phaseDiscardAfter", + "phaseJieshuAfter", + ]); + trigger.num += lib.skill.jsrgjuezhi.getNum(trigger.player, player); }, - subSkill:{ - disable:{ - audio:'jsrgjuezhi', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + disable: { + audio: "jsrgjuezhi", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + direct: true, + filter: function (event, player) { + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; }, - content:function(){ - 'step 0' - event.cards=trigger.getl(player).es; - 'step 1' - var card=cards.shift(),subtypes=get.subtypes(card).filter(slot=>player.hasEnabledSlot(slot)); - event.subtypes=subtypes; - if(subtypes.length>0){ - player.chooseBool(get.prompt('jsrgjuezhi_disable'),'废除你的'+get.translation(subtypes)+'栏').set('ai',()=>1); - } - else event._result={bool:false}; - 'step 2' - if(result.bool){ - player.logSkill('jsrgjuezhi_disable'); + content: function () { + "step 0"; + event.cards = trigger.getl(player).es; + "step 1"; + var card = cards.shift(), + subtypes = get.subtypes(card).filter((slot) => player.hasEnabledSlot(slot)); + event.subtypes = subtypes; + if (subtypes.length > 0) { + player + .chooseBool( + get.prompt("jsrgjuezhi_disable"), + "废除你的" + get.translation(subtypes) + "栏" + ) + .set("ai", () => 1); + } else event._result = { bool: false }; + "step 2"; + if (result.bool) { + player.logSkill("jsrgjuezhi_disable"); player.disableEquip(event.subtypes); } - if(cards.length>0) event.goto(1); + if (cards.length > 0) event.goto(1); }, }, - used:{charlotte:true} - } + used: { charlotte: true }, + }, }, - jsrgjizhao:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jsrgjizhao')).set('ai',target=>{ - var player=_status.event.player; - if(player.countCards('j')) return player==target?10:0.1; - return 6-get.attitude(player,target); + jsrgjizhao: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("jsrgjizhao")).set("ai", (target) => { + var player = _status.event.player; + if (player.countCards("j")) return player == target ? 10 : 0.1; + return 6 - get.attitude(player, target); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jsrgjizhao',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jsrgjizhao", target); target.chooseToUse({ - filterCard:function(card,player,event){ - if(get.itemtype(card)!='card'||get.position(card)!='h'&&get.position(card)!='s') return false; - return lib.filter.filterCard.apply(this,arguments); + filterCard: function (card, player, event) { + if ( + get.itemtype(card) != "card" || + (get.position(card) != "h" && get.position(card) != "s") + ) + return false; + return lib.filter.filterCard.apply(this, arguments); }, - prompt:'急召:使用一张手牌,否则'+get.translation(player)+'可以移动你区域里的一张牌', - addCount:false, - goon:target!=player||!player.countCards('j'), - ai1:function(card){ - if(_status.event.goon) return get.order(card); + prompt: + "急召:使用一张手牌,否则" + + get.translation(player) + + "可以移动你区域里的一张牌", + addCount: false, + goon: target != player || !player.countCards("j"), + ai1: function (card) { + if (_status.event.goon) return get.order(card); return 0; - } + }, }); - } - else{ + } else { event.finish(); return; } - 'step 2' - if(result.bool){event.finish();return;} - var targets=game.filterPlayer(current=>{ - if(current==target) return false; - var hs=target.getCards('h'); - if(hs.length) return true; - var js=target.getCards('j'); - for(var i=0;i { + if (current == target) return false; + var hs = target.getCards("h"); + if (hs.length) return true; + var js = target.getCards("j"); + for (var i = 0; i < js.length; i++) { + if (current.canAddJudge(js[i])) return true; } - if(current.isMin()) return false; - var es=target.getCards('e'); - for(var i=0;i0) return att; + if ( + i == es.length && + (!from.countCards("j", function (card) { + return target.canAddJudge(card); + }) || + att2 <= 0) + ) { + if (from.countCards("h") > 0) return att; return 0; } - return -att*att2; + return -att * att2; }); - next.set('targetprompt','移动目标'); - next.set('prompt','急召:是否移动'+get.translation(target)+'的一张牌?'); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target2=result.targets[0]; - event.targets=[target,target2]; - player.line2(event.targets,'green'); - } - else{ + next.set("targetprompt", "移动目标"); + next.set("prompt", "急召:是否移动" + get.translation(target) + "的一张牌?"); + } else event.finish(); + "step 3"; + if (result.bool) { + var target2 = result.targets[0]; + event.targets = [target, target2]; + player.line2(event.targets, "green"); + } else { event.finish(); } - 'step 4' + "step 4"; game.delay(); - 'step 5' - if(targets.length==2){ - player.choosePlayerCard('hej',true,function(button){ - var player=_status.event.player; - var targets0=_status.event.targets0; - var targets1=_status.event.targets1; - if(get.attitude(player,targets0)>0&&get.attitude(player,targets1)<0){ - if(get.position(button.link)=='j') return 12; - if(get.value(button.link,targets0)<0&&get.effect(targets1,button.link,player,targets1)>0) return 10; - return 0; - } - else{ - if(get.position(button.link)=='j') return -10; - if(get.position(button.link)=='h') return 10; - return get.value(button.link)*get.effect(targets1,button.link,player,targets1); - } - },targets[0]).set('targets0',targets[0]).set('targets1',targets[1]).set('filterButton',function(button){ - var targets1=_status.event.targets1; - if(get.position(button.link)=='h'){ - return true; - } - else if(get.position(button.link)=='j'){ - return targets1.canAddJudge(button.link); - } - else{ - return targets1.canEquip(button.link); - } - }); - } - else{ + "step 5"; + if (targets.length == 2) { + player + .choosePlayerCard( + "hej", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if ( + get.attitude(player, targets0) > 0 && + get.attitude(player, targets1) < 0 + ) { + if (get.position(button.link) == "j") return 12; + if ( + get.value(button.link, targets0) < 0 && + get.effect(targets1, button.link, player, targets1) > 0 + ) + return 10; + return 0; + } else { + if (get.position(button.link) == "j") return -10; + if (get.position(button.link) == "h") return 10; + return ( + get.value(button.link) * + get.effect(targets1, button.link, player, targets1) + ); + } + }, + targets[0] + ) + .set("targets0", targets[0]) + .set("targets1", targets[1]) + .set("filterButton", function (button) { + var targets1 = _status.event.targets1; + if (get.position(button.link) == "h") { + return true; + } else if (get.position(button.link) == "j") { + return targets1.canAddJudge(button.link); + } else { + return targets1.canEquip(button.link); + } + }); + } else { event.finish(); } - 'step 6' - if(result.bool&&result.links.length){ - var link=result.links[0]; - if(get.position(link)=='h') event.targets[1].gain(link,event.targets[0],'giveAuto'); - else{ - event.targets[0].$give(link,event.targets[1],false); - if(get.position(link)=='e') event.targets[1].equip(link); - else if(link.viewAs) event.targets[1].addJudge({name:link.viewAs},[link]); + "step 6"; + if (result.bool && result.links.length) { + var link = result.links[0]; + if (get.position(link) == "h") + event.targets[1].gain(link, event.targets[0], "giveAuto"); + else { + event.targets[0].$give(link, event.targets[1], false); + if (get.position(link) == "e") event.targets[1].equip(link); + else if (link.viewAs) event.targets[1].addJudge({ name: link.viewAs }, [link]); else event.targets[1].addJudge(link); } - game.log(event.targets[0],'的',get.position(link)=='h'?'一张手牌':link,'被移动给了',event.targets[1]); + game.log( + event.targets[0], + "的", + get.position(link) == "h" ? "一张手牌" : link, + "被移动给了", + event.targets[1] + ); game.delay(); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='delay'&¤t<0){ - if(target.countCards('j')) return; - return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "delay" && current < 0) { + if (target.countCards("j")) return; + return "zerotarget"; } }, }, - } + }, }, //杨彪 - jsrgzhaohan:{ - audio:'zhaohan', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, + jsrgzhaohan: { + audio: "zhaohan", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, //locked:false, - filter:function(event,player){ - if(game.shuffleNumber==0) return player.isDamaged(); + filter: function (event, player) { + if (game.shuffleNumber == 0) return player.isDamaged(); return true; }, - content:function(){ - player[game.shuffleNumber>0?'loseHp':'recover'](); - } + content: function () { + player[game.shuffleNumber > 0 ? "loseHp" : "recover"](); + }, }, - jsrgrangjie:{ - audio:'rangjie', - trigger:{player:'damageEnd'}, - filter:function(event,player){ + jsrgrangjie: { + audio: "rangjie", + trigger: { player: "damageEnd" }, + filter: function (event, player) { return player.canMoveCard(); }, - check:function(event,player){ + check: function (event, player) { return player.canMoveCard(true); }, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; event.num--; - if(player.canMoveCard()) player.moveCard(true); - 'step 2' - if(result.bool){ - var card=result.card; - var suit=get.suit(card,false); - var cards=Array.from(ui.discardPile.childNodes); - var gains=[]; - var history=game.getGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose') return evt.position==ui.discardPile; - return evt.name=='cardsDiscard'; + if (player.canMoveCard()) player.moveCard(true); + "step 2"; + if (result.bool) { + var card = result.card; + var suit = get.suit(card, false); + var cards = Array.from(ui.discardPile.childNodes); + var gains = []; + var history = game.getGlobalHistory("cardMove", (evt) => { + if (evt.name == "lose") return evt.position == ui.discardPile; + return evt.name == "cardsDiscard"; }); - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - var cards2=evt.cards.filter(card=>{ - return cards.includes(card)&&get.suit(card,false)==suit; + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + var cards2 = evt.cards.filter((card) => { + return cards.includes(card) && get.suit(card, false) == suit; }); - if(cards2.length){ + if (cards2.length) { gains.addArray(cards2); cards.removeArray(cards2); } - if(!cards.length) break; + if (!cards.length) break; } - if(gains.length){ - player.chooseButton(['让节:是否获得一张'+get.translation(suit)+'牌?',gains]).set('ai',get.buttonValue); - } - else event._result={bool:false}; + if (gains.length) { + player + .chooseButton(["让节:是否获得一张" + get.translation(suit) + "牌?", gains]) + .set("ai", get.buttonValue); + } else event._result = { bool: false }; } - 'step 3' - if(result.bool){ - player.gain(result.links,'gain2'); + "step 3"; + if (result.bool) { + player.gain(result.links, "gain2"); } - 'step 4' - if(event.num>0&&player.hasSkill('jsrgrangjie')){ - player.chooseBool(get.prompt2('jsrgrangjie')).set('ai',()=>_status.event.bool).set('bool',lib.skill.jsrgrangjie.check(trigger,player)); - } - else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('jsrgrangjie'); + "step 4"; + if (event.num > 0 && player.hasSkill("jsrgrangjie")) { + player + .chooseBool(get.prompt2("jsrgrangjie")) + .set("ai", () => _status.event.bool) + .set("bool", lib.skill.jsrgrangjie.check(trigger, player)); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("jsrgrangjie"); event.goto(1); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target._jsrgrangjie_aiChecking) return; - target._jsrgrangjie_aiChecking=true; - var moveCard=target.canMoveCard(true); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (target._jsrgrangjie_aiChecking) return; + target._jsrgrangjie_aiChecking = true; + var moveCard = target.canMoveCard(true); delete target._jsrgrangjie_aiChecking; - if(!moveCard||!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.5; - else num=0.3; + if (!moveCard || !target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.5; + else num = 0.3; } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } }, }, }, }, - jsrgyizheng:{ - audio:'yizheng', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h')&&player.canCompare(current); + jsrgyizheng: { + audio: "yizheng", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") > player.countCards("h") && player.canCompare(current); }); }, - filterTarget:function(card,player,current){ - return current.countCards('h')>player.countCards('h')&&player.canCompare(current); + filterTarget: function (card, player, current) { + return current.countCards("h") > player.countCards("h") && player.canCompare(current); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - target.skip('phaseDraw'); - target.addTempSkill('yizheng2',{player:'phaseDrawSkipped'}); + "step 1"; + if (result.bool) { + target.skip("phaseDraw"); + target.addTempSkill("yizheng2", { player: "phaseDrawSkipped" }); event.finish(); + } else { + target + .chooseControl("1", "2", "cancel") + .set("prompt", "是否对" + get.translation(player) + "造成至多2点伤害?") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + get.damageEffect(player, target, target) > 0 + ? get.attitude(target, player) > 0 + ? 0 + : 1 + : "cancel2" + ); } - else{ - target.chooseControl('1','2','cancel').set('prompt','是否对'+get.translation(player)+'造成至多2点伤害?').set('ai',()=>{ - return _status.event.choice; - }).set('choice',get.damageEffect(player,target,target)>0?(get.attitude(target,player)>0?0:1):'cancel2'); - } - 'step 2' - if(result.control!='cancel2'){ - var num=result.index+1; + "step 2"; + if (result.control != "cancel2") { + var num = result.index + 1; target.line(player); - player.damage(target,num); + player.damage(target, num); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.skipList.includes('phaseDraw')||target.hasSkill('pingkou')) return 0; - var hs=player.getCards('h').sort(function(a,b){ - return b.number-a.number; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.skipList.includes("phaseDraw") || target.hasSkill("pingkou")) return 0; + var hs = player.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - var ts=target.getCards('h').sort(function(a,b){ - return b.number-a.number; + var ts = target.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - if(!hs.length||!ts.length) return 0; - if(hs[0].number>ts[0].number) return -1; + if (!hs.length || !ts.length) return 0; + if (hs[0].number > ts[0].number) return -1; return 0; }, }, }, }, //孔融 - jsrglirang:{ - audio:'splirang', - trigger:{global:'phaseDrawBegin'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&!player.hasSkill('jsrglirang_used')&&player.countCards('he')>1; + jsrglirang: { + audio: "splirang", + trigger: { global: "phaseDrawBegin" }, + direct: true, + filter: function (event, player) { + return ( + event.player != player && + !player.hasSkill("jsrglirang_used") && + player.countCards("he") > 1 + ); }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt('jsrglirang',trigger.player),'你可以选择两张牌,将这些牌交给该角色。若如此做,你获得其本回合弃牌阶段弃置的所有牌。',2,'he').set('ai',card=>{ - if(!_status.event.give) return 0; - var player=_status.event.player,target=_status.event.target; - return target.getUseValue(card)-player.getUseValue(card)+0.5; - }).set('give',get.attitude(player,trigger.player)>0).set('target',trigger.player); - 'step 1' - if(result.bool){ - player.logSkill('jsrglirang',trigger.player); - var cards=result.cards; - player.give(cards,trigger.player); - player.addTempSkill('jsrglirang_used','roundStart'); - player.addTempSkill('jsrglirang_given'); - player.markAuto('jsrglirang_used',[trigger.player]); + content: function () { + "step 0"; + player + .chooseCard( + get.prompt("jsrglirang", trigger.player), + "你可以选择两张牌,将这些牌交给该角色。若如此做,你获得其本回合弃牌阶段弃置的所有牌。", + 2, + "he" + ) + .set("ai", (card) => { + if (!_status.event.give) return 0; + var player = _status.event.player, + target = _status.event.target; + return target.getUseValue(card) - player.getUseValue(card) + 0.5; + }) + .set("give", get.attitude(player, trigger.player) > 0) + .set("target", trigger.player); + "step 1"; + if (result.bool) { + player.logSkill("jsrglirang", trigger.player); + var cards = result.cards; + player.give(cards, trigger.player); + player.addTempSkill("jsrglirang_used", "roundStart"); + player.addTempSkill("jsrglirang_given"); + player.markAuto("jsrglirang_used", [trigger.player]); } }, - subSkill:{ - used:{ - charlotte:true, - onremove:true, - intro:{content:'本轮〖礼让〗目标:$'}, + subSkill: { + used: { + charlotte: true, + onremove: true, + intro: { content: "本轮〖礼让〗目标:$" }, }, - given:{ - audio:'splirang', - trigger:{global:'phaseDiscardEnd'}, - filter:function(event,player){ - return event.player.hasHistory('lose',evt=>{ - return evt.type=='discard'&&evt.getParent('phaseDiscard')==event&&evt.cards2.filterInD('d').length>0; + given: { + audio: "splirang", + trigger: { global: "phaseDiscardEnd" }, + filter: function (event, player) { + return event.player.hasHistory("lose", (evt) => { + return ( + evt.type == "discard" && + evt.getParent("phaseDiscard") == event && + evt.cards2.filterInD("d").length > 0 + ); }); }, - charlotte:true, - prompt2:function(event,player){ - var cards=[]; - event.player.getHistory('lose',evt=>{ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event) cards.addArray(evt.cards2.filterInD('d')); + charlotte: true, + prompt2: function (event, player) { + var cards = []; + event.player.getHistory("lose", (evt) => { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) + cards.addArray(evt.cards2.filterInD("d")); }); - return '获得'+get.translation(cards); + return "获得" + get.translation(cards); }, - content:function(){ - var cards=[]; - trigger.player.getHistory('lose',evt=>{ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) cards.addArray(evt.cards2.filterInD('d')); + content: function () { + var cards = []; + trigger.player.getHistory("lose", (evt) => { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + cards.addArray(evt.cards2.filterInD("d")); }); - player.gain(cards,'gain2'); - } - } - } - }, - jsrgzhengyi:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - var list=player.getStorage('jsrglirang_used'); - if(!list.length) return false; - return !player.getHistory('damage').length&&list[0].isIn(); + player.gain(cards, "gain2"); + }, + }, }, - direct:true, - content:function(){ - 'step 0' - var target=player.getStorage('jsrglirang_used')[0]; - event.target=target; - target.chooseBool('是否对'+get.translation(player)+'发动【争义】?','将此'+(trigger.source?'来源为'+get.translation(trigger.source):'无来源')+'的'+trigger.num+'点伤害转移给你').set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.damageEffect(player,trigger.source,target)>get.damageEffect(target,trigger.source,target)); - 'step 1' - if(result.bool){ - target.logSkill('jsrgzhengyi',player); + }, + jsrgzhengyi: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + var list = player.getStorage("jsrglirang_used"); + if (!list.length) return false; + return !player.getHistory("damage").length && list[0].isIn(); + }, + direct: true, + content: function () { + "step 0"; + var target = player.getStorage("jsrglirang_used")[0]; + event.target = target; + target + .chooseBool( + "是否对" + get.translation(player) + "发动【争义】?", + "将此" + + (trigger.source ? "来源为" + get.translation(trigger.source) : "无来源") + + "的" + + trigger.num + + "点伤害转移给你" + ) + .set("ai", () => { + return _status.event.bool; + }) + .set( + "bool", + get.damageEffect(player, trigger.source, target) > + get.damageEffect(target, trigger.source, target) + ); + "step 1"; + if (result.bool) { + target.logSkill("jsrgzhengyi", player); trigger.cancel(); - target.damage(trigger.source,trigger.nature,trigger.num).set('card',trigger.card).set('cards',trigger.cards); + target + .damage(trigger.source, trigger.nature, trigger.num) + .set("card", trigger.card) + .set("cards", trigger.cards); } - } + }, + ai: { + combo: "jsrglirang" + }, }, //朱儁 - jsrgfendi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.targets.length==1&&event.card.name=='sha'&&event.targets[0].countCards('h')>0; + jsrgfendi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return ( + event.targets.length == 1 && + event.card.name == "sha" && + event.targets[0].countCards("h") > 0 + ); }, - usable:1, - logTarget:'target', - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - player.choosePlayerCard(target,'h',true,[1,Infinity],'分敌:展示'+get.translation(target)+'的任意张手牌').set('ai',button=>{ - if(_status.event.all) return 1; - if(ui.selected.buttons.length) return 0; - return Math.random(); - }).set('all',!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&Math.random()<0.75).set('forceAuto',true); - 'step 1' - if(result.bool){ - var cards=result.cards; - target.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【分敌】'); - target.addGaintag(cards,'jsrgfendi_tag'); - target.addTempSkill('jsrgfendi_blocker'); - player.addTempSkill('jsrgfendi_gain'); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.jsrgfendi=cards.slice(); - player.storage.jsrgfendi_gain=target; - } - else player.storage.counttrigger.jsrgfendi--; + usable: 1, + logTarget: "target", + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + player + .choosePlayerCard( + target, + "h", + true, + [1, Infinity], + "分敌:展示" + get.translation(target) + "的任意张手牌" + ) + .set("ai", (button) => { + if (_status.event.all) return 1; + if (ui.selected.buttons.length) return 0; + return Math.random(); + }) + .set( + "all", + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && Math.random() < 0.75 + ) + .set("forceAuto", true); + "step 1"; + if (result.bool) { + var cards = result.cards; + target.showCards( + cards, + get.translation(player) + "对" + get.translation(target) + "发动了【分敌】" + ); + target.addGaintag(cards, "jsrgfendi_tag"); + target.addTempSkill("jsrgfendi_blocker"); + player.addTempSkill("jsrgfendi_gain"); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.jsrgfendi = cards.slice(); + player.storage.jsrgfendi_gain = target; + } else player.storage.counttrigger.jsrgfendi--; }, - subSkill:{ - blocker:{ - trigger:{ - player:['damageBefore','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded','useCardToEnd'], - global:['useCardEnd'], + subSkill: { + blocker: { + trigger: { + player: ["damageBefore", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded", "useCardToEnd"], + global: ["useCardEnd"], }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - player.removeSkill('jsrgfendi_blocker'); + forced: true, + popup: false, + charlotte: true, + content: function () { + player.removeSkill("jsrgfendi_blocker"); }, - mod:{ - cardEnabled:function(card,player){ - if(card.cards){ - for(var i of card.cards){ - if(!i.hasGaintag('jsrgfendi_tag')) return false; + mod: { + cardEnabled: function (card, player) { + if (card.cards) { + for (var i of card.cards) { + if (!i.hasGaintag("jsrgfendi_tag")) return false; } - } - else if(get.itemtype(card)=='card'){ - if(!card.hasGaintag('jsrgfendi_tag')) return false; + } else if (get.itemtype(card) == "card") { + if (!card.hasGaintag("jsrgfendi_tag")) return false; } }, - cardRespondable:function(card,player){ - return lib.skill.jsrgfendi.cardEnabled.apply(this,arguments); + cardRespondable: function (card, player) { + return lib.skill.jsrgfendi.cardEnabled.apply(this, arguments); }, - cardSavable:function(card,player){ - return lib.skill.jsrgfendi.cardEnabled.apply(this,arguments); + cardSavable: function (card, player) { + return lib.skill.jsrgfendi.cardEnabled.apply(this, arguments); }, }, }, - gain:{ - trigger:{global:'damageSource'}, - charlotte:true, - forced:true, - direct:true, - onremove:true, - filter:function(event,player){ - if(!event.card||!event.card.storage) return false; - var cards=event.card.storage.jsrgfendi; - var target=player.storage.jsrgfendi_gain; - if(!cards||!target||!target.isIn()) return false; - var cardsx=target.getCards('h'); + gain: { + trigger: { global: "damageSource" }, + charlotte: true, + forced: true, + direct: true, + onremove: true, + filter: function (event, player) { + if (!event.card || !event.card.storage) return false; + var cards = event.card.storage.jsrgfendi; + var target = player.storage.jsrgfendi_gain; + if (!cards || !target || !target.isIn()) return false; + var cardsx = target.getCards("h"); cardsx.addArray(Array.from(ui.discardPile)); - return cards.some(i=>cardsx.includes(i)); + return cards.some((i) => cardsx.includes(i)); //target.hasCard(card=>{ // return card.hasGaintag('jsrgfendi_tag'); //},'h'); }, - content:function(){ - var target=player.storage.jsrgfendi_gain; - player.logSkill('jsrgfendi_gain',target); - var cardsx=target.getCards('h'); + content: function () { + var target = player.storage.jsrgfendi_gain; + player.logSkill("jsrgfendi_gain", target); + var cardsx = target.getCards("h"); cardsx.addArray(Array.from(ui.discardPile)); - var cards=trigger.card.storage.jsrgfendi.filter(i=>cardsx.includes(i)); - player.gain(cards,'give'); - } - } - } - }, - jsrgjuxiang:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + var cards = trigger.card.storage.jsrgfendi.filter((i) => cardsx.includes(i)); + player.gain(cards, "give"); + }, + }, }, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - if(evt&&evt.name=='phaseDraw') return false; - var hs=player.getCards('h'); - var cards=event.getg(player).filter(i=>hs.includes(i)); - if(!cards.length) return false; - for(var card of cards){ - if(!lib.filter.cardDiscardable(card,player,'jsrgjuxiang')) return false; + }, + jsrgjuxiang: { + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", + }, + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + if (evt && evt.name == "phaseDraw") return false; + var hs = player.getCards("h"); + var cards = event.getg(player).filter((i) => hs.includes(i)); + if (!cards.length) return false; + for (var card of cards) { + if (!lib.filter.cardDiscardable(card, player, "jsrgjuxiang")) return false; } return true; }, - check:function(event,player){ - var target=_status.currentPhase; - if(!target||get.attitude(player,target)<=0) return false; - var evt=event.getParent('phaseDiscard'),evt2=event.getParent('phaseJieshu'); - if(evt&&evt.name=='phaseDiscard'||evt2&&evt.name=='phaseJieshu') return false; - if(target.getCardUsable({name:'sha'})>=target.countCards('hs','sha')) return false; - if(!target.hasValueTarget({name:'sha'})) return false; - var hs=player.getCards('h'); - var cards=event.getg(player).filter(i=>hs.includes(i)); - var val=0; - for(var i of cards) val+=get.value(i); - if(val<10) return true; + check: function (event, player) { + var target = _status.currentPhase; + if (!target || get.attitude(player, target) <= 0) return false; + var evt = event.getParent("phaseDiscard"), + evt2 = event.getParent("phaseJieshu"); + if ((evt && evt.name == "phaseDiscard") || (evt2 && evt.name == "phaseJieshu")) + return false; + if (target.getCardUsable({ name: "sha" }) >= target.countCards("hs", "sha")) return false; + if (!target.hasValueTarget({ name: "sha" })) return false; + var hs = player.getCards("h"); + var cards = event.getg(player).filter((i) => hs.includes(i)); + var val = 0; + for (var i of cards) val += get.value(i); + if (val < 10) return true; return false; }, - prompt2:function(event,player){ - var hs=player.getCards('h'); - var cards=event.getg(player).filter(i=>hs.includes(i)); - var target=_status.currentPhase; - var str='弃置'+get.translation(cards); - if(target&&target.isIn()){ - var list=[]; - for(var card of cards){ - list.add(get.suit(card,player)); + prompt2: function (event, player) { + var hs = player.getCards("h"); + var cards = event.getg(player).filter((i) => hs.includes(i)); + var target = _status.currentPhase; + var str = "弃置" + get.translation(cards); + if (target && target.isIn()) { + var list = []; + for (var card of cards) { + list.add(get.suit(card, player)); } - var num=list.length; - str+=',然后令'+get.translation(target)+'于此回合额定的出牌阶段内使用【杀】的次数上限+'+num; + var num = list.length; + str += + ",然后令" + + get.translation(target) + + "于此回合额定的出牌阶段内使用【杀】的次数上限+" + + num; } return str; }, - content:function(){ - 'step 0' - var hs=player.getCards('h'); - var cards=trigger.getg(player).filter(i=>hs.includes(i)); - var list=[]; - for(var card of cards){ - list.add(get.suit(card,player)); + content: function () { + "step 0"; + var hs = player.getCards("h"); + var cards = trigger.getg(player).filter((i) => hs.includes(i)); + var list = []; + for (var card of cards) { + list.add(get.suit(card, player)); } - event.num=list.length; + event.num = list.length; player.discard(cards); - 'step 1' - var target=_status.currentPhase; - if(target&&target.isIn()){ - target.addTempSkill('jsrgjuxiang_sha'); - target.addMark('jsrgjuxiang_sha',num,false); - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'&&!evt.skill){ - evt.player.addTempSkill('jsrgjuxiang_buff','phaseUseAfter'); - evt.player.addMark('jsrgjuxiang_buff',num,false); + "step 1"; + var target = _status.currentPhase; + if (target && target.isIn()) { + target.addTempSkill("jsrgjuxiang_sha"); + target.addMark("jsrgjuxiang_sha", num, false); + var evt = trigger.getParent("phaseUse"); + if (evt && evt.name == "phaseUse" && !evt.skill) { + evt.player.addTempSkill("jsrgjuxiang_buff", "phaseUseAfter"); + evt.player.addMark("jsrgjuxiang_buff", num, false); } } }, - subSkill:{ - sha:{ - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ + subSkill: { + sha: { + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { return !event.skill; }, - silent:true, - charlotte:true, - forced:true, - onremove:true, - content:function(){ - trigger.player.addTempSkill('jsrgjuxiang_buff','phaseUseAfter'); - trigger.player.addMark('jsrgjuxiang_buff',player.countMark('jsrgjuxiang_sha'),false); - } + silent: true, + charlotte: true, + forced: true, + onremove: true, + content: function () { + trigger.player.addTempSkill("jsrgjuxiang_buff", "phaseUseAfter"); + trigger.player.addMark( + "jsrgjuxiang_buff", + player.countMark("jsrgjuxiang_sha"), + false + ); + }, }, - buff:{ - charlotte:true, - intro:{content:'使用【杀】的次数上限+#'}, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('jsrgjuxiang_buff'); + buff: { + charlotte: true, + intro: { content: "使用【杀】的次数上限+#" }, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("jsrgjuxiang_buff"); }, - } - } - } + }, + }, + }, }, //刘备 - jsrgjishan:{ - audio:2, - trigger:{global:'damageBegin4'}, - usable:1, - filter:function(event,player){ - return player.hp>0; + jsrgjishan: { + audio: 2, + trigger: { global: "damageBegin4" }, + usable: 1, + filter: function (event, player) { + return player.hp > 0; }, - logTarget:'player', - onremove:true, - prompt2:'失去1点体力并防止此伤害,然后你与其各摸一张牌', - check:function(event,player){ - return get.damageEffect(event.player,event.source,_status.event.player,event.nature)*event.num < - get.effect(player,{name:'losehp'},player,_status.event.player)+get.effect(player,{name:'draw'},player,_status.event.player)+get.effect(event.player,{name:'draw'},player,_status.event.player)/2; + logTarget: "player", + onremove: true, + prompt2: "失去1点体力并防止此伤害,然后你与其各摸一张牌", + check: function (event, player) { + return ( + get.damageEffect(event.player, event.source, _status.event.player, event.nature) * + event.num < + get.effect(player, { name: "losehp" }, player, _status.event.player) + + get.effect(player, { name: "draw" }, player, _status.event.player) + + get.effect(event.player, { name: "draw" }, player, _status.event.player) / 2 + ); }, - group:'jsrgjishan_recover', - content:function(){ - 'step 0' + group: "jsrgjishan_recover", + content: function () { + "step 0"; trigger.cancel(); player.loseHp(); - player.markAuto('jsrgjishan',[trigger.player]); - 'step 1' - if(player.isIn()&&trigger.player.isIn()){ - var targets=[player,trigger.player]; + player.markAuto("jsrgjishan", [trigger.player]); + "step 1"; + if (player.isIn() && trigger.player.isIn()) { + var targets = [player, trigger.player]; targets.sortBySeat(_status.currentPhase); - targets[0].draw('nodelay'); + targets[0].draw("nodelay"); targets[1].draw(); } }, - intro:{content:'已帮助$抵挡过伤害'}, - ai:{expose:0.2}, - subSkill:{ - recover:{ - audio:'jsrgjishan', - trigger:{source:'damageSource'}, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current.isMinHp()&&player.getStorage('jsrgjishan').includes(current); + intro: { content: "已帮助$抵挡过伤害" }, + ai: { expose: 0.2 }, + subSkill: { + recover: { + audio: "jsrgjishan", + trigger: { source: "damageSource" }, + filter: function (event, player) { + return game.hasPlayer((current) => { + return current.isMinHp() && player.getStorage("jsrgjishan").includes(current); }); }, - usable:1, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jsrgjishan_recover'),'令一名体力值最小且你对其发动过〖积善①〗的角色回复1点体力',(card,player,target)=>{ - return target.isMinHp()&&player.getStorage('jsrgjishan').includes(target); - }).set('ai',target=>{ - return get.recoverEffect(target,_status.event.player,_status.event.player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jsrgjishan_recover',target); + usable: 1, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jsrgjishan_recover"), + "令一名体力值最小且你对其发动过〖积善①〗的角色回复1点体力", + (card, player, target) => { + return ( + target.isMinHp() && + player.getStorage("jsrgjishan").includes(target) + ); + } + ) + .set("ai", (target) => { + return get.recoverEffect( + target, + _status.event.player, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jsrgjishan_recover", target); target.recover(); - } - else player.storage.counttrigger.jsrgjishan_recover--; - } - } - } - }, - jsrgzhenqiao:{ - audio:2, - trigger:{player:'useCardToTargeted'}, - forced:true, - shaRelated:true, - filter:function(event,player){ - return event.isFirstTarget&&event.card.name=='sha'&&player.hasEmptySlot(1); + } else player.storage.counttrigger.jsrgjishan_recover--; + }, + }, }, - content:function(){ + }, + jsrgzhenqiao: { + audio: 2, + trigger: { player: "useCardToTargeted" }, + forced: true, + shaRelated: true, + filter: function (event, player) { + return event.isFirstTarget && event.card.name == "sha" && player.hasEmptySlot(1); + }, + content: function () { // trigger.getParent().targets=trigger.getParent().targets.concat(trigger.targets); // trigger.getParent().triggeredTargets4=trigger.getParent().triggeredTargets4.concat(trigger.targets); trigger.getParent().effectCount++; }, - mod:{ - attackRange:function(player,num){ - return num+1; + mod: { + attackRange: function (player, num) { + return num + 1; }, - aiOrder:(player,card,num)=>{ - if(num>0&&get.itemtype(card)==='card'&&get.subtype(card)==='equip1'&&!player.getEquip(1)){ - if(card.name!=='zhuge'||player.getCardUsable('sha')||!player.needsToDiscard()||player.countCards('hs',i=>{ - return get.name(i)==='sha'&&lib.filter.cardEnabled(i,player); - })<2) return 0; + aiOrder: (player, card, num) => { + if ( + num > 0 && + get.itemtype(card) === "card" && + get.subtype(card) === "equip1" && + !player.getEquip(1) + ) { + if ( + card.name !== "zhuge" || + player.getCardUsable("sha") || + !player.needsToDiscard() || + player.countCards("hs", (i) => { + return get.name(i) === "sha" && lib.filter.cardEnabled(i, player); + }) < 2 + ) + return 0; } }, - aiValue:(player,card,num)=>{ - if(num>0&&get.itemtype(card)==='card'&&card.name!=='zhuge'&&get.subtype(card)==='equip1'&&!player.getEquip(1)) return 0.01*num; + aiValue: (player, card, num) => { + if ( + num > 0 && + get.itemtype(card) === "card" && + card.name !== "zhuge" && + get.subtype(card) === "equip1" && + !player.getEquip(1) + ) + return 0.01 * num; }, - aiUseful:()=>{ - return lib.skill.jsrgzhenqiao.mod.aiValue.apply(this,arguments); - } - } + aiUseful: () => { + return lib.skill.jsrgzhenqiao.mod.aiValue.apply(this, arguments); + }, + }, }, //王允 - jsrgshelun:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(current=>player.inRange(current)); + jsrgshelun: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => player.inRange(current)); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.inRange(target); }, - content:function(){ - var num=player.countCards('h'); - var targets=game.filterPlayer(current=>{ - return current.countCards('h')<=num&¤t!=target; + content: function () { + var num = player.countCards("h"); + var targets = game.filterPlayer((current) => { + return current.countCards("h") <= num && current != target; }); - player.chooseToDebate(targets).set('callback',function(){ - var result=event.debateResult; - if(result.bool&&result.opinion){ - var opinion=result.opinion; - var target=event.getParent(2).target; - if(opinion=='red') player.discardPlayerCard(target,'he',true); - else target.damage(); - } - }).set('ai',card=>{ - var player=_status.event.player; - var color=(player==_status.event.source||get.damageEffect(_status.event.getParent(2).target,player,player)>0)?'black':'red'; - var val=5-get.value(card); - if(get.color(card)==color) val+=10; - return val; - }).set('aiCard',target=>{ - var color=(target==_status.event.source||get.damageEffect(_status.event.getParent(2).target,target,target)>0)?'black':'red'; - var hs=target.getCards('h',{color:color}); - if(!hs.length) hs=target.getCards('h'); - return {bool:true,cards:[hs.randomGet()]}; - }).set('target',target); + player + .chooseToDebate(targets) + .set("callback", function () { + var result = event.debateResult; + if (result.bool && result.opinion) { + var opinion = result.opinion; + var target = event.getParent(2).target; + if (opinion == "red") player.discardPlayerCard(target, "he", true); + else target.damage(); + } + }) + .set("ai", (card) => { + var player = _status.event.player; + var color = + player == _status.event.source || + get.damageEffect(_status.event.getParent(2).target, player, player) > 0 + ? "black" + : "red"; + var val = 5 - get.value(card); + if (get.color(card) == color) val += 10; + return val; + }) + .set("aiCard", (target) => { + var color = + target == _status.event.source || + get.damageEffect(_status.event.getParent(2).target, target, target) > 0 + ? "black" + : "red"; + var hs = target.getCards("h", { color: color }); + if (!hs.length) hs = target.getCards("h"); + return { bool: true, cards: [hs.randomGet()] }; + }) + .set("target", target); + }, + ai: { + order: 8, + expose: 0.2, + result: { target: -1 }, }, - ai:{ - order:8, - expose:0.2, - result:{target:-1}, - } }, - jsrgfayi:{ - audio:2, - trigger:{global:'chooseToDebateAfter'}, - filter:function(event,player){ - if(!event.targets.includes(player)) return false; - if(event.red.map(i=>i[0]).includes(player)) return event.black.length; - if(event.black.map(i=>i[0]).includes(player)) return event.red.length; + jsrgfayi: { + audio: 2, + trigger: { global: "chooseToDebateAfter" }, + filter: function (event, player) { + if (!event.targets.includes(player)) return false; + if (event.red.map((i) => i[0]).includes(player)) return event.black.length; + if (event.black.map((i) => i[0]).includes(player)) return event.red.length; return false; }, - direct:true, - content:function(){ - 'step 0' - var targets=[]; - if(trigger.red.map(i=>i[0]).includes(player)) targets=trigger.black; - if(trigger.black.map(i=>i[0]).includes(player)) targets=trigger.red; - player.chooseTarget(get.prompt('jsrgfayi'),'对一名与你意见不同的角色造成1点伤害',(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',targets.map(i=>i[0])).set('ai',target=>{ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jsrgfayi',target); + direct: true, + content: function () { + "step 0"; + var targets = []; + if (trigger.red.map((i) => i[0]).includes(player)) targets = trigger.black; + if (trigger.black.map((i) => i[0]).includes(player)) targets = trigger.red; + player + .chooseTarget( + get.prompt("jsrgfayi"), + "对一名与你意见不同的角色造成1点伤害", + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set( + "targets", + targets.map((i) => i[0]) + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jsrgfayi", target); target.damage(); } - } + }, }, - jsrgtushe:{ - audio:'xinfu_tushe', + jsrgtushe: { + audio: "xinfu_tushe", mod: { aiOrder(player, card, num) { - if (get.tag(card, 'multitarget')) { - if (player.countCards('h', { type: 'basic' })) return num / 10; + if (get.tag(card, "multitarget")) { + if (player.countCards("h", { type: "basic" })) return num / 10; return num * 10; } - if (get.type(card) === 'basic') return num + 10; + if (get.type(card) === "basic") return num + 10; }, aiValue(player, card, num) { - if (card.name === 'zhangba') { + if (card.name === "zhangba") { let fact = (n) => { - if (n > 1) return n * fact(n - 1); - return 1; - }, basic = 0; - return fact(Math.min(player.countCards('hs', i => { - if (get.tag(i, 'multitarget')) return 2; - if (!['shan', 'tao', 'jiu'].includes(card.name)) return 1; - basic++; - }) / (1 + basic), player.getCardUsable('sha'))); + if (n > 1) return n * fact(n - 1); + return 1; + }, + basic = 0; + return fact( + Math.min( + player.countCards("hs", (i) => { + if (get.tag(i, "multitarget")) return 2; + if (!["shan", "tao", "jiu"].includes(card.name)) return 1; + basic++; + }) / + (1 + basic), + player.getCardUsable("sha") + ) + ); } - if (['shan', 'tao', 'jiu'].includes(card.name)) { - if (player.getEquip('zhangba') && player.countCards('hs') > 1) return 0.01; + if (["shan", "tao", "jiu"].includes(card.name)) { + if (player.getEquip("zhangba") && player.countCards("hs") > 1) return 0.01; return num / 2; } - if (get.tag(card, 'multitarget')) return num + game.players.length; + if (get.tag(card, "multitarget")) return num + game.players.length; }, aiUseful(player, card, num) { - if (get.name(card, player) === 'shan') { - if (player.countCards('hs', i => { - if (card === i || card.cards && card.cards.includes(i)) return false; - return get.name(i, player) === 'shan'; - })) return -1; + if (get.name(card, player) === "shan") { + if ( + player.countCards("hs", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) return false; + return get.name(i, player) === "shan"; + }) + ) + return -1; return num / Math.pow(Math.max(1, player.hp), 2); } - } + }, }, - trigger:{ - player:'useCardToPlayered', + trigger: { + player: "useCardToPlayered", }, - filter:function (event,player){ - if(get.type(event.card)=='equip') return false; - if(event.getParent().triggeredTargets3.length>1) return false; - return event.targets.length>0; + filter: function (event, player) { + if (get.type(event.card) == "equip") return false; + if (event.getParent().triggeredTargets3.length > 1) return false; + return event.targets.length > 0; }, - check:function(event,player){ - return !player.countCards('h',{type:'basic'}); + check: function (event, player) { + return !player.countCards("h", { type: "basic" }); }, locked: false, - content:function (){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - if(player.countCards('h',{type:'basic'})) event.finish(); - else player.chooseBool('图射:是否摸'+get.cnNumber(trigger.targets.length)+'张牌?').set('ai',()=>1); - 'step 2' - if(result.bool){ + "step 1"; + if (player.countCards("h", { type: "basic" })) event.finish(); + else + player + .chooseBool("图射:是否摸" + get.cnNumber(trigger.targets.length) + "张牌?") + .set("ai", () => 1); + "step 2"; + if (result.bool) { player.draw(trigger.targets.length); } }, - ai:{ - presha:true, - pretao:true, - threaten:1.8, + ai: { + presha: true, + pretao: true, + threaten: 1.8, effect: { player(card, player, target) { - if (typeof card === 'object' && card.name !== 'shan' && get.type(card) !== 'equip' && !player.countCards('h', i => { - if (card === i || card.cards && card.cards.includes(i)) return false; - return get.type(i) === 'basic'; - })) { - let targets = [], evt = _status.event.getParent('useCard'); + if ( + typeof card === "object" && + card.name !== "shan" && + get.type(card) !== "equip" && + !player.countCards("h", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) return false; + return get.type(i) === "basic"; + }) + ) { + let targets = [], + evt = _status.event.getParent("useCard"); targets.addArray(ui.selected.targets); if (evt && evt.card == card) targets.addArray(evt.targets); if (targets.length) return [1, targets.length]; - if (get.tag(card, 'multitarget')) return [1, game.players.length - 1]; + if (get.tag(card, "multitarget")) return [1, game.players.length - 1]; return [1, 1]; } - } - } - } + }, + }, + }, }, - jsrgtongjue:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuSkill:true, - filter:function(event,player){ - return player.hasZhuSkill('jsrgtongjue')&&game.hasPlayer(current=>current!=player&¤t.group=='qun'); + jsrgtongjue: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuSkill: true, + filter: function (event, player) { + return ( + player.hasZhuSkill("jsrgtongjue") && + game.hasPlayer((current) => current != player && current.group == "qun") + ); }, - filterCard:true, - selectCard:[1,Infinity], - filterTarget:function(card,player,target){ - return target!=player&&target.group=='qun'; + filterCard: true, + selectCard: [1, Infinity], + filterTarget: function (card, player, target) { + return target != player && target.group == "qun"; }, - selectTarget:[1,Infinity], - filterOk:function(){ - return ui.selected.cards.length==ui.selected.targets.length; + selectTarget: [1, Infinity], + filterOk: function () { + return ui.selected.cards.length == ui.selected.targets.length; }, - check:function(card){ - var player=_status.event.player; - if(player.hasCard(card=>{ - return player.hasValueTarget(card); - },'hs')){ - return 3-player.getUseValue(card); + check: function (card) { + var player = _status.event.player; + if ( + player.hasCard((card) => { + return player.hasValueTarget(card); + }, "hs") + ) { + return 3 - player.getUseValue(card); } - return 3-get.value(card); + return 3 - get.value(card); }, - multiline:true, - multitarget:true, - delay:false, - discard:false, - lose:false, - content:function(){ - 'step 0' - var list=[]; - for(var i=0;icurrent.getSeatNum()==1); - return event.player==zhu; + jsrgzhenglve: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + var zhu = get.zhu(player) || game.findPlayer((current) => current.getSeatNum() == 1); + return event.player == zhu; }, - locked:false, - group:'jsrgzhenglve_damage', - prompt2:function(event,player){ - var num=Math.min(event.player.getHistory('sourceDamage').length>0?1:2,game.countPlayer(current=>{ - return !current.hasMark('jsrgzhenglve_mark'); - })); - if(num==0) return '你可以摸一张牌'; - return '你可以摸一张牌并令'+get.cnNumber(num)+'名角色获得“猎”标记'; + locked: false, + group: "jsrgzhenglve_damage", + prompt2: function (event, player) { + var num = Math.min( + event.player.getHistory("sourceDamage").length > 0 ? 1 : 2, + game.countPlayer((current) => { + return !current.hasMark("jsrgzhenglve_mark"); + }) + ); + if (num == 0) return "你可以摸一张牌"; + return "你可以摸一张牌并令" + get.cnNumber(num) + "名角色获得“猎”标记"; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - var damaged=trigger.player.getHistory('sourceDamage').length>0; - var num=damaged?1:2; - var targets=game.filterPlayer(current=>{ - return !current.hasMark('jsrgzhenglve_mark'); + "step 1"; + var damaged = trigger.player.getHistory("sourceDamage").length > 0; + var num = damaged ? 1 : 2; + var targets = game.filterPlayer((current) => { + return !current.hasMark("jsrgzhenglve_mark"); }); - if(!targets.length) event.finish(); - else if(targets.length<=num) event._result={bool:true,targets:targets}; - else player.chooseTarget('令'+(num>1?'至多':'')+get.cnNumber(num)+'名角色获得“猎”标记',true,[1,num],(card,player,target)=>{ - return !target.hasMark('jsrgzhenglve_mark'); - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - return 100-att; - }); - 'step 2' - if(result.bool){ - var targets=result.targets; + if (!targets.length) event.finish(); + else if (targets.length <= num) event._result = { bool: true, targets: targets }; + else + player + .chooseTarget( + "令" + (num > 1 ? "至多" : "") + get.cnNumber(num) + "名角色获得“猎”标记", + true, + [1, num], + (card, player, target) => { + return !target.hasMark("jsrgzhenglve_mark"); + } + ) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + return 100 - att; + }); + "step 2"; + if (result.bool) { + var targets = result.targets; player.line(targets); - targets.forEach(i=>i.addMark('jsrgzhenglve_mark',1)); + targets.forEach((i) => i.addMark("jsrgzhenglve_mark", 1)); } }, - mod:{ - cardUsableTarget:function(card,player,target){ - if(target.hasMark('jsrgzhenglve_mark')) return true; + mod: { + cardUsableTarget: function (card, player, target) { + if (target.hasMark("jsrgzhenglve_mark")) return true; }, - targetInRange:function(card,player,target){ - if(target.hasMark('jsrgzhenglve_mark')) return true; + targetInRange: function (card, player, target) { + if (target.hasMark("jsrgzhenglve_mark")) return true; }, }, - subSkill:{ - damage:{ - audio:'jsrgzhenglve', - trigger:{source:'damageSource'}, - usable:1, - filter:function(event,player){ - return event.player.hasMark('jsrgzhenglve_mark'); + subSkill: { + damage: { + audio: "jsrgzhenglve", + trigger: { source: "damageSource" }, + usable: 1, + filter: function (event, player) { + return event.player.hasMark("jsrgzhenglve_mark"); }, - prompt2:function(event,player){ - var cards=event.cards||[]; - return '摸一张牌'+(cards.filterInD().length?'并获得'+get.translation(event.cards.filterInD()):''); + prompt2: function (event, player) { + var cards = event.cards || []; + return ( + "摸一张牌" + + (cards.filterInD().length + ? "并获得" + get.translation(event.cards.filterInD()) + : "") + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - var cards=trigger.cards; - if(cards&&cards.filterInD().length){ - player.gain(cards.filterInD(),'gain2'); + var cards = trigger.cards; + if (cards && cards.filterInD().length) { + player.gain(cards.filterInD(), "gain2"); } - } - }, - mark:{ - marktext:'猎', - intro:{ - name:'猎(政略)', - name2:'猎', - markcount:()=>0, - content:'已拥有“猎”标记', - } - } - } - }, - jsrghuilie:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'thunder', - derivation:['jsrgpingrong','feiying'], - filter:function(event,player){ - return game.countPlayer(current=>current.hasMark('jsrgzhenglve_mark'))>2; - }, - content:function(){ - 'step 0' - player.awakenSkill('jsrghuilie'); - player.loseMaxHp(); - 'step 1' - player.addSkills(['jsrgpingrong','feiying']); - } - }, - jsrgpingrong:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return !player.hasSkill('jsrgpingrong_used')&&game.hasPlayer(current=>current.hasMark('jsrgzhenglve_mark')); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jsrghuilie'),'移去一名角色的“猎”,然后你执行一个额外回合。若你在此额外回合内未造成伤害,则你失去1点体力。',(card,player,target)=>{ - return target.hasMark('jsrgzhenglve_mark'); - }).set('ai',target=>{ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jsrgpingrong',target); - player.addTempSkill('jsrgpingrong_used','roundStart'); - target.removeMark('jsrgzhenglve_mark',target.countMark('jsrgzhenglve_mark')); - player.insertPhase(); - player.addSkill('jsrgpingrong_check'); - } - }, - subSkill:{ - used:{charlotte:true}, - check:{ - audio:'jsrgpingrong', - trigger:{player:'phaseAfter'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return event.skill=='jsrgpingrong'&&!player.getHistory('sourceDamage').length; }, - content:function(){ - player.loseHp(); - } + }, + mark: { + marktext: "猎", + intro: { + name: "猎(政略)", + name2: "猎", + markcount: () => 0, + content: "已拥有“猎”标记", + }, + }, + }, + }, + jsrghuilie: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "thunder", + derivation: ["jsrgpingrong", "feiying"], + filter: function (event, player) { + return game.countPlayer((current) => current.hasMark("jsrgzhenglve_mark")) > 2; + }, + content: function () { + "step 0"; + player.awakenSkill("jsrghuilie"); + player.loseMaxHp(); + "step 1"; + player.addSkills(["jsrgpingrong", "feiying"]); + }, + ai: { + combo: "jsrgzhenglve" + }, + }, + jsrgpingrong: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return ( + !player.hasSkill("jsrgpingrong_used") && + game.hasPlayer((current) => current.hasMark("jsrgzhenglve_mark")) + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jsrghuilie"), + "移去一名角色的“猎”,然后你执行一个额外回合。若你在此额外回合内未造成伤害,则你失去1点体力。", + (card, player, target) => { + return target.hasMark("jsrgzhenglve_mark"); + } + ) + .set("ai", (target) => { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jsrgpingrong", target); + player.addTempSkill("jsrgpingrong_used", "roundStart"); + target.removeMark("jsrgzhenglve_mark", target.countMark("jsrgzhenglve_mark")); + player.insertPhase(); + player.addSkill("jsrgpingrong_check"); } - } + }, + subSkill: { + used: { charlotte: true }, + check: { + audio: "jsrgpingrong", + trigger: { player: "phaseAfter" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return event.skill == "jsrgpingrong" && !player.getHistory("sourceDamage").length; + }, + content: function () { + player.loseHp(); + }, + }, + }, }, //南华老仙 - jsrgshoushu:{ - audio:2, - forced:true, - trigger:{ + jsrgshoushu: { + audio: 2, + forced: true, + trigger: { //player:'enterGame', //global:'phaseBefore', - global:'roundStart', + global: "roundStart", }, - filter:function(event,player){ - if(game.hasPlayer(function(current){ - return current.countCards('hej','taipingyaoshu'); - })) return false; + filter: function (event, player) { + if ( + game.hasPlayer(function (current) { + return current.countCards("hej", "taipingyaoshu"); + }) + ) + return false; return true; //return event.name!='phase'||game.phaseNumber==0; }, - direct:true, - group:'jsrgshoushu_destroy', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jsrgshoushu'),'将【太平要术】置入一名角色的装备区',(card,player,target)=>{ - var card={name:'taipingyaoshu'}; - return target.canEquip(card,true); - }).set('ai',target=>{ - return target.getUseValue({name:'taipingyaoshu'})*get.attitude(_status.event.player,target); - }) - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jsrgshoushu',target); - if(!lib.inpile.includes('taipingyaoshu')){ - lib.inpile.push('taipingyaoshu'); + direct: true, + group: "jsrgshoushu_destroy", + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jsrgshoushu"), + "将【太平要术】置入一名角色的装备区", + (card, player, target) => { + var card = { name: "taipingyaoshu" }; + return target.canEquip(card, true); + } + ) + .set("ai", (target) => { + return ( + target.getUseValue({ name: "taipingyaoshu" }) * + get.attitude(_status.event.player, target) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jsrgshoushu", target); + if (!lib.inpile.includes("taipingyaoshu")) { + lib.inpile.push("taipingyaoshu"); } - event.card=game.createCard2('taipingyaoshu','heart',3); - } - else event.finish(); - 'step 2' - if(card) target.equip(card); + event.card = game.createCard2("taipingyaoshu", "heart", 3); + } else event.finish(); + "step 2"; + if (card) target.equip(card); }, - subSkill:{ - destroy:{ - audio:'jsrgshoushu', - trigger:{ - global:['loseEnd','equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], + subSkill: { + destroy: { + audio: "jsrgshoushu", + trigger: { + global: [ + "loseEnd", + "equipEnd", + "addJudgeEnd", + "gainEnd", + "loseAsyncEnd", + "addToExpansionEnd", + ], }, - forced:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - var evt=event.getl(current); - if(evt&&evt.es) return evt.es.some(i=>i.name=='taipingyaoshu'); + forced: true, + filter: function (event, player) { + return game.hasPlayer((current) => { + var evt = event.getl(current); + if (evt && evt.es) return evt.es.some((i) => i.name == "taipingyaoshu"); return false; }); }, - content:function(){ - var cards=[]; - game.countPlayer(current=>{ - var evt=trigger.getl(current); - if(evt&&evt.es) return cards.addArray(evt.es.filter(i=>i.name=='taipingyaoshu')); + content: function () { + var cards = []; + game.countPlayer((current) => { + var evt = trigger.getl(current); + if (evt && evt.es) + return cards.addArray(evt.es.filter((i) => i.name == "taipingyaoshu")); }); game.cardsGotoSpecial(cards); - game.log(cards,'被销毁了'); - } - } - } - }, - jsrgxundao:{ - audio:2, - trigger:{player:'judge'}, - filter:function(event,player){ - return game.hasPlayer(current=>current.countCards('he')); + game.log(cards, "被销毁了"); + }, + }, }, - direct:true, - content:function(){ - 'step 0' - var prompt2=get.translation(player)+'(你)的'+(trigger.judgestr||'')+'判定为'+ - get.translation(player.judging[0])+','+'是否令至多两名角色依次弃置一张牌,然后选择其中一张作为新判定牌?'; - player.chooseTarget(get.prompt('jsrgxundao'),prompt2,[1,2],(card,player,target)=>{ - return target.countCards('he'); - }).set('ai',target=>{ - var player=_status.event.player; - if(!_status.event.todiscard) return 0; - if(_status.event.todiscard!='all'){ - if(target==_status.event.todiscard) return 100; - } - return get.effect(target,{name:'guohe_copy2'},player,player)/2; - }).set('todiscard',function(){ - if(trigger.judgestr=='闪电'&&get.damageEffect(player,null,player,'thunder')>=0) return 'all'; - var friends=game.filterPlayer(i=>get.attitude(i,player)>0); - for(var friend of friends){ - var cardsx=friend.getCards('he',card=>trigger.judge(card)>0); - cardsx.sort((a,b)=>{ - return get.value(a)-get.value(b); - }); - if(cardsx.length){ - var card=cardsx[0]; - if(trigger.judge(player.judging[0])>=0){ - if(get.value(card)>4) return false; - } - return get.owner(card); + }, + jsrgxundao: { + audio: 2, + trigger: { player: "judge" }, + filter: function (event, player) { + return game.hasPlayer((current) => current.countCards("he")); + }, + direct: true, + content: function () { + "step 0"; + var prompt2 = + get.translation(player) + + "(你)的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(player.judging[0]) + + "," + + "是否令至多两名角色依次弃置一张牌,然后选择其中一张作为新判定牌?"; + player + .chooseTarget(get.prompt("jsrgxundao"), prompt2, [1, 2], (card, player, target) => { + return target.countCards("he"); + }) + .set("ai", (target) => { + var player = _status.event.player; + if (!_status.event.todiscard) return 0; + if (_status.event.todiscard != "all") { + if (target == _status.event.todiscard) return 100; } - } - return 'all'; - }()) - 'step 1' - if(result.bool){ - var targets=result.targets; + return get.effect(target, { name: "guohe_copy2" }, player, player) / 2; + }) + .set( + "todiscard", + (function () { + if ( + trigger.judgestr == "闪电" && + get.damageEffect(player, null, player, "thunder") >= 0 + ) + return "all"; + var friends = game.filterPlayer((i) => get.attitude(i, player) > 0); + for (var friend of friends) { + var cardsx = friend.getCards("he", (card) => trigger.judge(card) > 0); + cardsx.sort((a, b) => { + return get.value(a) - get.value(b); + }); + if (cardsx.length) { + var card = cardsx[0]; + if (trigger.judge(player.judging[0]) >= 0) { + if (get.value(card) > 4) return false; + } + return get.owner(card); + } + } + return "all"; + })() + ); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.sortBySeat(_status.currentPhase); - event.targets=targets; - player.logSkill('jsrgxundao',targets); - event.cards=[]; - } - else event.finish(); - 'step 2' - var target=targets.shift(); - target.chooseToDiscard('寻道:请弃置一张牌'+(target==player?'':',可能被作为新判定牌'),'he',true).set('ai',card=>{ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0.1; - if(attitude>0){ - return result+0.01; - } - else{ - return 0.01-result; - } - }); - 'step 3' - if(result.bool){ + event.targets = targets; + player.logSkill("jsrgxundao", targets); + event.cards = []; + } else event.finish(); + "step 2"; + var target = targets.shift(); + target + .chooseToDiscard( + "寻道:请弃置一张牌" + (target == player ? "" : ",可能被作为新判定牌"), + "he", + true + ) + .set("ai", (card) => { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0.1; + if (attitude > 0) { + return result + 0.01; + } else { + return 0.01 - result; + } + }); + "step 3"; + if (result.bool) { event.cards.addArray(result.cards); } - if(targets.length) event.goto(2); - 'step 4' - var cards=event.cards.filterInD('d'); - if(cards.length){ - player.chooseButton(['寻道:选择一张作为新判定牌',cards],true).set('ai',button=>{ - return trigger.judge(button.link); - }); - } - else event.finish(); - 'step 5' - if(result.bool){ - var card=result.links[0]; - event.card=card; - game.cardsGotoOrdering(card).relatedEvent=trigger; - } - else event.finish(); - 'step 6' - if(player.judging[0].clone){ - game.broadcastAll(function(card,card2,player){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); - } - var node=player.$throwordered(card2.copy(),true); - node.classList.add('thrownhighlight'); - ui.arena.classList.add('thrownhighlight'); - },player.judging[0],card,player); - game.addVideo('deletenode',player,get.cardsInfo([player.judging[0].clone])); + if (targets.length) event.goto(2); + "step 4"; + var cards = event.cards.filterInD("d"); + if (cards.length) { + player + .chooseButton(["寻道:选择一张作为新判定牌", cards], true) + .set("ai", (button) => { + return trigger.judge(button.link); + }); + } else event.finish(); + "step 5"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + game.cardsGotoOrdering(card).relatedEvent = trigger; + } else event.finish(); + "step 6"; + if (player.judging[0].clone) { + game.broadcastAll( + function (card, card2, player) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); + } + var node = player.$throwordered(card2.copy(), true); + node.classList.add("thrownhighlight"); + ui.arena.classList.add("thrownhighlight"); + }, + player.judging[0], + card, + player + ); + game.addVideo("deletenode", player, get.cardsInfo([player.judging[0].clone])); } game.cardsDiscard(player.judging[0]); - player.judging[0]=card; + player.judging[0] = card; trigger.orderingCards.add(card); - game.log(player,'的判定牌改为',card); + game.log(player, "的判定牌改为", card); game.delay(2); }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, - jsrglinghua:{ - audio:2, - trigger:{ - player:['phaseZhunbeiBegin','phaseJieshuBegin'], + jsrglinghua: { + audio: 2, + trigger: { + player: ["phaseZhunbeiBegin", "phaseJieshuBegin"], }, - prompt2:function(event,player){ - var zhunbei=event.name=='phaseZhunbei'; - return '进行目标为你'+(zhunbei?'':'且效果反转')+'的【闪电】判定。若你未因此受到伤害,你可以'+(zhunbei?'令一名角色回复1点体力':'对一名角色造成1点雷电伤害'); + prompt2: function (event, player) { + var zhunbei = event.name == "phaseZhunbei"; + return ( + "进行目标为你" + + (zhunbei ? "" : "且效果反转") + + "的【闪电】判定。若你未因此受到伤害,你可以" + + (zhunbei ? "令一名角色回复1点体力" : "对一名角色造成1点雷电伤害") + ); }, - check:function(event,player){ - var e2=player.getEquip(2); - if(e2&&e2.name=='taipingyaoshu') return true; - if(event.name=='phaseZhunbei'&&game.hasPlayer(current=>{ - return get.recoverEffect(current,player,player)>=0; - })) return true; - if(event.name=='phaseJieshu'&&game.hasPlayer(current=>{ - return get.damageEffect(current,player,player,'thunder')>=0; - })&&player.hasSkillTag('rejudge')&&player.hasCard(card=>{ - return lib.card.shandian.judge(card)<0; - },'he')) return true; + check: function (event, player) { + var e2 = player.getEquip(2); + if (e2 && e2.name == "taipingyaoshu") return true; + if ( + event.name == "phaseZhunbei" && + game.hasPlayer((current) => { + return get.recoverEffect(current, player, player) >= 0; + }) + ) + return true; + if ( + event.name == "phaseJieshu" && + game.hasPlayer((current) => { + return get.damageEffect(current, player, player, "thunder") >= 0; + }) && + player.hasSkillTag("rejudge") && + player.hasCard((card) => { + return lib.card.shandian.judge(card) < 0; + }, "he") + ) + return true; return false; }, - content:function(){ - 'step 0' - var next=event.executeDelayCardEffect=player.executeDelayCardEffect('shandian'); - if(event.triggername!='phaseJieshuBegin') return; - next.judge=card=>-lib.card.shandian.judge(card)-4; - next.judge2=result=>!lib.card.shandian.judge2(result); - 'step 1' - var executeDelayCardEffect=event.executeDelayCardEffect; - if(!player.hasHistory('damage',evt=>evt.getParent(2)==executeDelayCardEffect)){ - if(trigger.name=='phaseZhunbei'){ - player.chooseTarget('灵化:是否令一名角色回复1点体力?').set('ai',target=>{ - var player=_status.event.player; - return get.recoverEffect(target,player,player); + content: function () { + "step 0"; + var next = (event.executeDelayCardEffect = player.executeDelayCardEffect("shandian")); + if (event.triggername != "phaseJieshuBegin") return; + next.judge = (card) => -lib.card.shandian.judge(card) - 4; + next.judge2 = (result) => !lib.card.shandian.judge2(result); + "step 1"; + var executeDelayCardEffect = event.executeDelayCardEffect; + if (!player.hasHistory("damage", (evt) => evt.getParent(2) == executeDelayCardEffect)) { + if (trigger.name == "phaseZhunbei") { + player.chooseTarget("灵化:是否令一名角色回复1点体力?").set("ai", (target) => { + var player = _status.event.player; + return get.recoverEffect(target, player, player); }); + } else { + player + .chooseTarget("灵化:是否对一名角色造成1点雷电伤害?") + .set("ai", (target) => { + var player = _status.event.player; + return get.damageEffect(target, player, player, "thunder"); + }); } - else{ - player.chooseTarget('灵化:是否对一名角色造成1点雷电伤害?').set('ai',target=>{ - var player=_status.event.player; - return get.damageEffect(target,player,player,'thunder'); - }); - } - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - if(trigger.name=='phaseZhunbei') target.recover(); - else target.damage('thunder'); + if (trigger.name == "phaseZhunbei") target.recover(); + else target.damage("thunder"); } }, - ai:{ - threaten:2.8 - } + ai: { + threaten: 2.8, + }, }, }, - characterReplace:{}, - dynamicTranslate:{ - jsrgshichong:function(player){ - if(player.storage.jsrgshichong) return '转换技。当你使用牌指定其他角色为唯一目标后,阴:你可以获得目标角色一张手牌;阳:目标角色可以交给你一张手牌。'; + characterReplace: {}, + dynamicTranslate: { + jsrgshichong: function (player) { + if (player.storage.jsrgshichong) + return '转换技。当你使用牌指定其他角色为唯一目标后,阴:你可以获得目标角色一张手牌;阳:目标角色可以交给你一张手牌。'; return '转换技。当你使用牌指定其他角色为唯一目标后,阴:你可以获得目标角色一张手牌;阳:目标角色可以交给你一张手牌。'; }, }, - translate:{ + translate: { //江山如故·起 - jsrg_liuhong:'起刘宏', - jsrg_liuhong_prefix:'起', - jsrgchaozheng:'朝争', - jsrgchaozheng_info:'准备阶段,你可以令所有其他角色议事。若结果为:红色,意见为红色的角色各回复1点体力;黑色,意见为红色的角色各失去1点体力。然后若所有意见均相同,你摸X张牌(X为此次议事的角色数)。', - jsrgshenchong:'甚宠', - jsrgshenchong_info:'限定技。出牌阶段,你可以令一名其他角色获得〖飞扬〗、〖跋扈〗。若如此做,当你死亡时,其失去所有技能并弃置所有手牌。', - jsrgjulian:'聚敛', - jsrgjulian_info:'主公技。①其他群势力角色每回合限两次。当其不于摸牌阶段且不因〖聚敛〗摸牌后,其可以摸一张牌。②结束阶段,你可以获得所有其他群势力角色各一张牌。', - jsrgfeiyang:'飞扬', - jsrgfeiyang_info:'判定阶段开始时,若你的判定区里有牌,你可以弃置两张手牌并弃置你判定区里的一张牌。', - jsrgbahu:'跋扈', - jsrgbahu_info:'锁定技。①准备阶段,你摸一张牌。②你使用【杀】的次数上限+1。', - jsrg_hejin:'起何进', - jsrg_hejin_prefix:'起', - jsrgzhaobing:'诏兵', - jsrgzhaobing_info:'结束阶段,你可以弃置所有手牌,然后令至多X名其他角色依次选择一项:1.正面向上交给你一张【杀】;2.失去1点体力(X为你本次弃置的牌数)。', - jsrgzhuhuan:'诛宦', - jsrgzhuhuan_info:'准备阶段,你可以展示所有手牌并弃置所有【杀】,然后令一名其他角色选择一项:1.弃置等量的牌,然后受到1点伤害;2.令你摸等量的牌,然后你回复1点体力。', - jsrgyanhuo:'延祸', - jsrgyanhuo_info:'锁定技。当你死亡时,你增加如下全局技能:当有角色使用【杀】时,此【杀】的伤害值基数+1。', - jsrg_sunjian:'起孙坚', - jsrg_sunjian_prefix:'起', - jsrgpingtao:'平讨', - jsrgpingtao_info:'出牌阶段限一次。你可以令一名其他角色选择一项:1.交给你一张牌,然后你于此回合使用【杀】的次数上限+1;2.令你视为对其使用一张【杀】。', - jsrgjuelie:'绝烈', - jsrgjuelie_info:'①当你使用【杀】指定一名角色为目标后,你可以弃置任意张牌并弃置其等量的牌。②若你的手牌数或体力值为全场最小,则你使用【杀】造成的伤害+1。', - jsrg_huangfusong:'起皇甫嵩', - jsrg_huangfusong_prefix:'起', - jsrgguanhuo:'观火', - jsrgguanhuo_info:'①出牌阶段,你可以视为使用一张【火攻】。②当你因〖观火①〗使用的【火攻】结算结束后,若此牌未造成过伤害,且:若{你此阶段发动〖观火①〗的次数为1,则你于此阶段造成渠道为【火攻】的伤害时,此伤害+1},否则你失去〖观火〗。', - jsrgjuxia:'居下', - jsrgjuxia_info:'每回合限一次。当其他角色使用牌指定你为目标后,若其技能数多于你,其可以令此牌对你无效,然后令你摸两张牌。', - jsrg_xushao:'起许劭', - jsrg_xushao_prefix:'起', - jsrgyingmen:'盈门', - jsrgyingmen_info:'锁定技。①游戏开始时,你将武将牌堆中随机四张武将牌置于你的武将牌上,称为“访客”。②回合开始时,若你的“访客”数小于4,你随机从武将牌堆中将“访客”补至四张。', - jsrgpingjian:'评鉴', - jsrgpingjian_info:'你可以于满足你“访客”上的一个无技能标签或仅有锁定技标签的技能条件的时机发动此技能,然后你选择移去一张“访客”。若移去的是本次发动技能的“访客”,你摸一张牌。', - jsrg_dongbai:'起董白', - jsrg_dongbai_prefix:'起', - jsrgshichong:'恃宠', - jsrgshichong_info:'转换技。当你使用牌指定其他角色为唯一目标后,阴:你可以获得目标角色一张手牌;阳:目标角色可以交给你一张手牌。', - jsrglianzhu:'连诛', - jsrglianzhu_info:'出牌阶段限一次。你可以展示一张黑色手牌并交给一名其他角色,然后视为你对所有与其势力相同的其他角色依次使用一张【过河拆桥】。', - jsrg_qiaoxuan:'起桥玄', - jsrg_qiaoxuan_prefix:'起', - jsrgjuezhi:'绝质', - jsrgjuezhi_info:'①当你失去一张装备区里的装备牌后,你可以废除对应的装备栏。②你的回合每阶段限一次。当你使用牌对目标角色造成伤害时,你令此伤害+X(X为其装备区里的牌与你已废除的装备栏中相同副类别的数量)。', - jsrgjizhao:'急召', - jsrgjizhao_info:'准备阶段或结束阶段,你可以令一名角色选择一项:1.使用一张手牌;2.令你可以移动其区域里的一张牌。', - jsrg_yangbiao:'起杨彪', - jsrg_yangbiao_prefix:'起', - jsrgzhaohan:'昭汉', - jsrgzhaohan_info:'锁定技。准备阶段,若本局游戏:未洗过牌,你回复1点体力;洗过牌,你失去1点体力。', - jsrgrangjie:'让节', - jsrgrangjie_info:'当你受到1点伤害后,你可以移动场上的一张牌,然后你可以于弃牌堆中选择获得一张本回合进入弃牌堆且与此牌花色相同的牌。', - jsrgyizheng:'义争', - jsrgyizheng_info:'出牌阶段限一次。你可以与一名手牌数大于你的角色拼点。若你:赢,其跳过下一个摸牌阶段;没赢,其可以对你造成至多2点伤害。', - jsrg_kongrong:'起孔融', - jsrg_kongrong_prefix:'起', - jsrglirang:'礼让', - jsrglirang_info:'每轮限一次。其他角色的摸牌阶段开始时,你可以交给其两张牌。然后此回合的弃牌阶段结束时,你可以获得所有其于此阶段因弃置进入弃牌堆的牌。', - jsrgzhengyi:'争义', - jsrgzhengyi_info:'当你每回合首次受到伤害时,本轮因〖礼让〗得到过牌的其他角色可以将此伤害转移给其。', - jsrg_zhujun:'起朱儁', - jsrg_zhujun_prefix:'起', - jsrgfendi:'分敌', - jsrgfendi_tag:'分敌', - jsrgfendi_info:'每回合限一次。当你使用【杀】指定唯一目标后,你可以展示其任意张手牌,令其不能使用或打出对应实体牌不全为这些牌的牌直到此【杀】结算结束。然后当此【杀】对其造成伤害后,你于其手牌区或弃牌堆获得这些牌。', - jsrgjuxiang:'拒降', - jsrgjuxiang_info:'当你不于摸牌阶段得到牌后,你可以弃置之,令当前回合角色于此回合额定的出牌阶段内使用【杀】的次数上限+X(X为你以此法弃置的牌的花色数)。', - jsrg_liubei:'起刘备', - jsrg_liubei_prefix:'起', - jsrgjishan:'积善', - jsrgjishan_info:'①每回合限一次。当一名角色受到伤害时,你可以失去1点体力并防止此伤害,然后你与其各摸一张牌。②每回合限一次。当你造成伤害后,你可以令一名体力值最小且你对其发动过〖积善①〗的角色回复1点体力。', - jsrgzhenqiao:'振鞘', - jsrgzhenqiao_info:'锁定技。①你的攻击范围+1。②当你使用【杀】指定目标后,若你的武器栏为空且未废除,你令此【杀】的效果额外结算一次。', - jsrg_wangyun:'起王允', - jsrg_wangyun_prefix:'起', - jsrgshelun:'赦论', - jsrgshelun_info:'出牌阶段限一次。你可以选择一名你攻击范围内的角色,然后令除其外所有手牌数不大于你的角色议事。若结果为:红色,你弃置其一张牌;黑色,你对其造成1点伤害。', - jsrgfayi:'伐异', - jsrgfayi_info:'当你议事结算结束后,你可以对一名意见与你不同的角色造成1点伤害。', - jsrg_liuyan:'起刘焉', - jsrg_liuyan_prefix:'起', - jsrgtushe:'图射', - jsrgtushe_info:'当你使用非装备牌指定目标后,你可以展示所有手牌(无牌则不展示)。若你没有基本牌,你可以摸X张牌(X为此牌指定的目标数)。', - jsrgtongjue:'通绝', - jsrgtongjue_info:'主公技。出牌阶段限一次。你可以将任意张牌交给等量名其他群势力角色。然后你不能使用牌指定这些角色为目标直到回合结束。', - jsrg_caocao:'梦曹操', - jsrg_caocao_prefix:'梦', - jsrgzhenglve:'政略', - jsrgzhenglve_info:'①主公的回合结束时,你可以摸一张牌,然后令一名没有“猎”标记的角色获得“猎”(若主公本回合没有造成过伤害,则改为至多两名)。②你对有“猎”的角色使用牌无距离和次数限制。③每回合限一次。当你对有“猎”的角色造成伤害后,你可以摸一张牌并获得造成此伤害的牌。', - jsrghuilie:'会猎', - jsrghuilie_info:'觉醒技。准备阶段,若有“猎”的角色数大于2,你减1点体力上限,然后获得〖平戎〗和〖飞影〗。', - jsrgpingrong:'平戎', - jsrgpingrong_info:'每轮限一次。一名角色的回合结束时,你可以移去一名角色的“猎”,然后你于此回合后执行一个额外回合。该回合结束后,若你于此回合未造成过伤害,你失去1点体力。', - jsrg_nanhualaoxian:'起南华老仙', - jsrg_nanhualaoxian_prefix:'起', - jsrgshoushu:'授术', - jsrgshoushu_info:'锁定技。①一轮游戏开始时,若场上没有【太平要术】,你可以从游戏外将【太平要术】置于一名角色的装备区内。②当【太平要术】离开一名角色的装备区后,你令此牌销毁。', - jsrgxundao:'寻道', - jsrgxundao_info:'当你的判定牌生效前,你可以令至多两名角色依次弃置一张牌,然后你选择一张以此法弃置且位于弃牌堆中的牌代替此判定牌。', - jsrglinghua:'灵化', - jsrglinghua_info:'①准备阶段,你可以执行目标角色为你的【闪电】效果。若你未因此受到伤害,你可以令一名角色回复1点体力。②结束阶段,你可以执行目标角色为你且判定效果反转的【闪电】效果。若你未因此受到伤害,你可以对一名角色造成1点雷电伤害。', - sbyingmen:'盈门', - sbyingmen_info:'锁定技。①游戏开始时,你将武将牌堆中随机四张武将牌置于你的武将牌上,称为“访客”。②回合开始时,若你的“访客”数小于4,你随机从武将牌堆中将“访客”补至四张。', - sbpingjian:'评鉴', - sbpingjian_info:'你可以于满足你“访客”上的一个无技能标签或仅有锁定技标签的技能条件的时机发动此技能,然后你选择移去一张“访客”。若移去的是本次发动技能的“访客”,则你于此技能结算结束时摸一张牌。', + jsrg_liuhong: "起刘宏", + jsrg_liuhong_prefix: "起", + jsrgchaozheng: "朝争", + jsrgchaozheng_info: + "准备阶段,你可以令所有其他角色议事。若结果为:红色,意见为红色的角色各回复1点体力;黑色,意见为红色的角色各失去1点体力。然后若所有意见均相同,你摸X张牌(X为此次议事的角色数)。", + jsrgshenchong: "甚宠", + jsrgshenchong_info: + "限定技。出牌阶段,你可以令一名其他角色获得〖飞扬〗、〖跋扈〗。若如此做,当你死亡时,其失去所有技能并弃置所有手牌。", + jsrgjulian: "聚敛", + jsrgjulian_info: + "主公技。①其他群势力角色每回合限两次。当其不于摸牌阶段且不因〖聚敛〗摸牌后,其可以摸一张牌。②结束阶段,你可以获得所有其他群势力角色各一张牌。", + jsrgfeiyang: "飞扬", + jsrgfeiyang_info: + "判定阶段开始时,若你的判定区里有牌,你可以弃置两张手牌并弃置你判定区里的一张牌。", + jsrgbahu: "跋扈", + jsrgbahu_info: "锁定技。①准备阶段,你摸一张牌。②你使用【杀】的次数上限+1。", + jsrg_hejin: "起何进", + jsrg_hejin_prefix: "起", + jsrgzhaobing: "诏兵", + jsrgzhaobing_info: + "结束阶段,你可以弃置所有手牌,然后令至多X名其他角色依次选择一项:1.正面向上交给你一张【杀】;2.失去1点体力(X为你本次弃置的牌数)。", + jsrgzhuhuan: "诛宦", + jsrgzhuhuan_info: + "准备阶段,你可以展示所有手牌并弃置所有【杀】,然后令一名其他角色选择一项:1.弃置等量的牌,然后受到1点伤害;2.令你摸等量的牌,然后你回复1点体力。", + jsrgyanhuo: "延祸", + jsrgyanhuo_info: + "锁定技。当你死亡时,你增加如下全局技能:当有角色使用【杀】时,此【杀】的伤害值基数+1。", + jsrg_sunjian: "起孙坚", + jsrg_sunjian_prefix: "起", + jsrgpingtao: "平讨", + jsrgpingtao_info: + "出牌阶段限一次。你可以令一名其他角色选择一项:1.交给你一张牌,然后你于此回合使用【杀】的次数上限+1;2.令你视为对其使用一张【杀】。", + jsrgjuelie: "绝烈", + jsrgjuelie_info: + "①当你使用【杀】指定一名角色为目标后,你可以弃置任意张牌并弃置其等量的牌。②若你的手牌数或体力值为全场最小,则你使用【杀】造成的伤害+1。", + jsrg_huangfusong: "起皇甫嵩", + jsrg_huangfusong_prefix: "起", + jsrgguanhuo: "观火", + jsrgguanhuo_info: + "①出牌阶段,你可以视为使用一张【火攻】。②当你因〖观火①〗使用的【火攻】结算结束后,若此牌未造成过伤害,且:若{你此阶段发动〖观火①〗的次数为1,则你于此阶段造成渠道为【火攻】的伤害时,此伤害+1},否则你失去〖观火〗。", + jsrgjuxia: "居下", + jsrgjuxia_info: + "每回合限一次。当其他角色使用牌指定你为目标后,若其技能数多于你,其可以令此牌对你无效,然后令你摸两张牌。", + jsrg_xushao: "起许劭", + jsrg_xushao_prefix: "起", + jsrgyingmen: "盈门", + jsrgyingmen_info: + "锁定技。①游戏开始时,你将武将牌堆中随机四张武将牌置于你的武将牌上,称为“访客”。②回合开始时,若你的“访客”数小于4,你随机从武将牌堆中将“访客”补至四张。", + jsrgpingjian: "评鉴", + jsrgpingjian_info: + "你可以于满足你“访客”上的一个无技能标签或仅有锁定技标签的技能条件的时机发动此技能,然后你选择移去一张“访客”。若移去的是本次发动技能的“访客”,你摸一张牌。", + jsrg_dongbai: "起董白", + jsrg_dongbai_prefix: "起", + jsrgshichong: "恃宠", + jsrgshichong_info: + "转换技。当你使用牌指定其他角色为唯一目标后,阴:你可以获得目标角色一张手牌;阳:目标角色可以交给你一张手牌。", + jsrglianzhu: "连诛", + jsrglianzhu_info: + "出牌阶段限一次。你可以展示一张黑色手牌并交给一名其他角色,然后视为你对所有与其势力相同的其他角色依次使用一张【过河拆桥】。", + jsrg_qiaoxuan: "起桥玄", + jsrg_qiaoxuan_prefix: "起", + jsrgjuezhi: "绝质", + jsrgjuezhi_info: + "①当你失去一张装备区里的装备牌后,你可以废除对应的装备栏。②你的回合每阶段限一次。当你使用牌对目标角色造成伤害时,你令此伤害+X(X为其装备区里的牌与你已废除的装备栏中相同副类别的数量)。", + jsrgjizhao: "急召", + jsrgjizhao_info: + "准备阶段或结束阶段,你可以令一名角色选择一项:1.使用一张手牌;2.令你可以移动其区域里的一张牌。", + jsrg_yangbiao: "起杨彪", + jsrg_yangbiao_prefix: "起", + jsrgzhaohan: "昭汉", + jsrgzhaohan_info: + "锁定技。准备阶段,若本局游戏:未洗过牌,你回复1点体力;洗过牌,你失去1点体力。", + jsrgrangjie: "让节", + jsrgrangjie_info: + "当你受到1点伤害后,你可以移动场上的一张牌,然后你可以于弃牌堆中选择获得一张本回合进入弃牌堆且与此牌花色相同的牌。", + jsrgyizheng: "义争", + jsrgyizheng_info: + "出牌阶段限一次。你可以与一名手牌数大于你的角色拼点。若你:赢,其跳过下一个摸牌阶段;没赢,其可以对你造成至多2点伤害。", + jsrg_kongrong: "起孔融", + jsrg_kongrong_prefix: "起", + jsrglirang: "礼让", + jsrglirang_info: + "每轮限一次。其他角色的摸牌阶段开始时,你可以交给其两张牌。然后此回合的弃牌阶段结束时,你可以获得所有其于此阶段因弃置进入弃牌堆的牌。", + jsrgzhengyi: "争义", + jsrgzhengyi_info: + "当你每回合首次受到伤害时,本轮因〖礼让〗得到过牌的其他角色可以将此伤害转移给其。", + jsrg_zhujun: "起朱儁", + jsrg_zhujun_prefix: "起", + jsrgfendi: "分敌", + jsrgfendi_tag: "分敌", + jsrgfendi_info: + "每回合限一次。当你使用【杀】指定唯一目标后,你可以展示其任意张手牌,令其不能使用或打出对应实体牌不全为这些牌的牌直到此【杀】结算结束。然后当此【杀】对其造成伤害后,你于其手牌区或弃牌堆获得这些牌。", + jsrgjuxiang: "拒降", + jsrgjuxiang_info: + "当你不于摸牌阶段得到牌后,你可以弃置之,令当前回合角色于此回合额定的出牌阶段内使用【杀】的次数上限+X(X为你以此法弃置的牌的花色数)。", + jsrg_liubei: "起刘备", + jsrg_liubei_prefix: "起", + jsrgjishan: "积善", + jsrgjishan_info: + "①每回合限一次。当一名角色受到伤害时,你可以失去1点体力并防止此伤害,然后你与其各摸一张牌。②每回合限一次。当你造成伤害后,你可以令一名体力值最小且你对其发动过〖积善①〗的角色回复1点体力。", + jsrgzhenqiao: "振鞘", + jsrgzhenqiao_info: + "锁定技。①你的攻击范围+1。②当你使用【杀】指定目标后,若你的武器栏为空且未废除,你令此【杀】的效果额外结算一次。", + jsrg_wangyun: "起王允", + jsrg_wangyun_prefix: "起", + jsrgshelun: "赦论", + jsrgshelun_info: + "出牌阶段限一次。你可以选择一名你攻击范围内的角色,然后令除其外所有手牌数不大于你的角色议事。若结果为:红色,你弃置其一张牌;黑色,你对其造成1点伤害。", + jsrgfayi: "伐异", + jsrgfayi_info: "当你议事结算结束后,你可以对一名意见与你不同的角色造成1点伤害。", + jsrg_liuyan: "起刘焉", + jsrg_liuyan_prefix: "起", + jsrgtushe: "图射", + jsrgtushe_info: + "当你使用非装备牌指定目标后,你可以展示所有手牌(无牌则不展示)。若你没有基本牌,你可以摸X张牌(X为此牌指定的目标数)。", + jsrgtongjue: "通绝", + jsrgtongjue_info: + "主公技。出牌阶段限一次。你可以将任意张牌交给等量名其他群势力角色。然后你不能使用牌指定这些角色为目标直到回合结束。", + jsrg_caocao: "梦曹操", + jsrg_caocao_prefix: "梦", + jsrgzhenglve: "政略", + jsrgzhenglve_info: + "①主公的回合结束时,你可以摸一张牌,然后令一名没有“猎”标记的角色获得“猎”(若主公本回合没有造成过伤害,则改为至多两名)。②你对有“猎”的角色使用牌无距离和次数限制。③每回合限一次。当你对有“猎”的角色造成伤害后,你可以摸一张牌并获得造成此伤害的牌。", + jsrghuilie: "会猎", + jsrghuilie_info: + "觉醒技。准备阶段,若有“猎”的角色数大于2,你减1点体力上限,然后获得〖平戎〗和〖飞影〗。", + jsrgpingrong: "平戎", + jsrgpingrong_info: + "每轮限一次。一名角色的回合结束时,你可以移去一名角色的“猎”,然后你于此回合后执行一个额外回合。该回合结束后,若你于此回合未造成过伤害,你失去1点体力。", + jsrg_nanhualaoxian: "起南华老仙", + jsrg_nanhualaoxian_prefix: "起", + jsrgshoushu: "授术", + jsrgshoushu_info: + "锁定技。①一轮游戏开始时,若场上没有【太平要术】,你可以从游戏外将【太平要术】置于一名角色的装备区内。②当【太平要术】离开一名角色的装备区后,你令此牌销毁。", + jsrgxundao: "寻道", + jsrgxundao_info: + "当你的判定牌生效前,你可以令至多两名角色依次弃置一张牌,然后你选择一张以此法弃置且位于弃牌堆中的牌代替此判定牌。", + jsrglinghua: "灵化", + jsrglinghua_info: + "①准备阶段,你可以执行目标角色为你的【闪电】效果。若你未因此受到伤害,你可以令一名角色回复1点体力。②结束阶段,你可以执行目标角色为你且判定效果反转的【闪电】效果。若你未因此受到伤害,你可以对一名角色造成1点雷电伤害。", + sbyingmen: "盈门", + sbyingmen_info: + "锁定技。①游戏开始时,你将武将牌堆中随机四张武将牌置于你的武将牌上,称为“访客”。②回合开始时,若你的“访客”数小于4,你随机从武将牌堆中将“访客”补至四张。", + sbpingjian: "评鉴", + sbpingjian_info: + "你可以于满足你“访客”上的一个无技能标签或仅有锁定技标签的技能条件的时机发动此技能,然后你选择移去一张“访客”。若移去的是本次发动技能的“访客”,则你于此技能结算结束时摸一张牌。", //江山如故·承 - jsrg_sunce:'梦孙策', - jsrg_sunce_prefix:'梦', - jsrgduxing:'独行', - jsrgduxing_info:'出牌阶段限一次。你可以视为使用一张可以指定任意名目标角色的【决斗】,且所有目标角色的手牌均视为【杀】直到此牌结算结束。', - jsrgzhiheng:'猘横', - jsrgzhiheng_info:'锁定技。当你因执行牌的效果对目标角色造成伤害时,若其于此回合响应过你使用过的牌,此伤害+1。', - jsrgzhasi:'诈死', - jsrgzhasi_info:'限定技。当你受到伤害值不小于你的体力值的伤害时,你可以防止此伤害,然后失去〖猘横〗并获得〖制衡〗。然后你不计入距离和座次计算直到你对其他角色使用牌后或当你受到伤害后。', - jsrgbashi:'霸世', - jsrgbashi_info:'主公技。当你需要打出【杀】或【闪】时,你可以令其他吴势力角色选择是否打出一张【杀】或【闪】。若有角色响应,则视为你打出了一张【杀】或【闪】。', - jsrg_xuyou:'承许攸', - jsrg_xuyou_prefix:'承', - jsrglipan:'离叛', - jsrglipan_info:'回合结束时,你可以变更势力,然后摸X张牌并执行一个额外的出牌阶段。此阶段结束时,所有与你势力相同的角色依次可以将一张牌当【决斗】对你使用(X为与你势力相同的其他角色数)。', - jsrgqingxi:'轻袭', - jsrgqingxi_info:'群势力技。出牌阶段每名角色限一次。你可以选择一名手牌数小于你的角色,你将手牌数弃置至与其相同,然后视为对其使用一张刺【杀】。', - jsrgjinmie:'烬灭', - jsrgjinmie_info:'魏势力技。出牌阶段限一次。你可以选择一名手牌数大于你的角色,你视为对其使用一张火【杀】。当此牌造成伤害后,你将其手牌数弃置至与你相同。', - jsrg_lvbu:'承吕布', - jsrg_lvbu_prefix:'承', - jsrgwuchang:'无常', - jsrgwuchang_info:'锁定技。①当你获得其他角色的牌后,你变更势力为与其相同。②当你使用【杀】或【决斗】对与你势力相同的目标角色造成伤害时,此伤害+1,然后变更势力为群。', - jsrgqingjiao:'轻狡', - jsrgqingjiao_info:'群势力技。出牌阶段各限一次。你可以将一张牌当【推心置腹】/【趁火打劫】对一名手牌数大于/小于你的角色使用。', - jsrgchengxu:'乘虚', - jsrgchengxu_info:'蜀势力技。与你势力相同的其他角色不能响应你使用的牌。', - jsrg_zhanghe:'承张郃', - jsrg_zhanghe_prefix:'承', - jsrgqiongtu:'穷途', - jsrgqiongtu_info:'群势力技。每回合限一次。你可以将一张非基本牌置于武将牌上视为使用一张【无懈可击】。若此牌生效,你摸一张牌,否则你变更势力为魏并获得所有“穷途”牌。', - jsrgxianzhu:'先著', - jsrgxianzhu_info:'魏势力技。你可以将一张普通锦囊牌当无次数限制的【杀】使用。当此牌对唯一目标造成伤害后,你视为对该角色使用一张此普通锦囊牌。', - jsrg_zoushi:'承邹氏', - jsrg_zoushi_prefix:'承', - jsrgguyin:'孤吟', - jsrgguyin_info:'准备阶段,你可以翻面,且令所有其他男性角色依次选择是否翻面。然后你和所有背面朝上的角色轮流各摸一张牌,直到你们累计以此法得到X张牌(X为场上存活角色与死亡角色中男性角色数)。', - jsrgzhangdeng:'帐灯', - jsrgzhangdeng_info:'①当一名武将牌背面朝上的角色需要使用【酒】时,若你的武将牌背面朝上,其可以视为使用之。②当一名角色于一回合第二次发动〖帐灯①〗时,你将武将牌翻面至正面朝上。', - jsrg_guanyu:'承关羽', - jsrg_guanyu_prefix:'承', - jsrgguanjue:'冠绝', - jsrgguanjue_info:'锁定技。当你使用或打出有花色的牌时,你令所有其他角色于此回合内不能使用或打出该花色的牌。', - jsrgnianen:'念恩', - jsrgnianen_info:'你可以将一张牌当任意基本牌使用或打出,然后若此牌不为红色或你以此法使用或打出的牌不为普通【杀】,则直到此回合结束,该技能失效且你视为拥有〖马术〗。', - jsrg_chendeng:'承陈登', - jsrg_chendeng_prefix:'承', - jsrglunshi:'论势', - jsrglunshi_info:'出牌阶段限一次。你可以令一名角色摸等同于其攻击范围内角色数的牌(至多摸至五张),然后其弃置等同于攻击范围内含有其的角色数的牌。', - jsrgguitu:'诡图', - jsrgguitu_info:'准备阶段,你可以交换场上的两张武器牌,然后攻击范围以此法减少的角色回复1点体力。', - jsrg_zhenji:'承甄宓', - jsrg_zhenji_prefix:'承', - jsrgjixiang:'济乡', - jsrgjixiang_info:'回合内每种牌名限一次。当一名其他角色需要使用或打出一张基本牌时,你可以弃置一张牌令其视为使用或打出之,然后你摸一张牌并令〖称贤〗于此阶段可发动次数上限+1。', - jsrgchengxian:'称贤', - jsrgchengxian_info:'出牌阶段限两次。你可以将一张手牌当一张本回合未以此法使用过的普通锦囊牌使用(此转化牌须与以此法转化的手牌的合法目标数相同)。', - jsrg_zhangliao:'承张辽', - jsrg_zhangliao_prefix:'承', - jsrgzhengbing:'整兵', - jsrgzhengbing_info:'群势力技。出牌阶段限三次。你可以重铸一张牌,若此牌为:【杀】,你本回合手牌上限+2;【闪】,你摸一张牌;【桃】,你变更势力为魏。', - jsrgtuwei:'突围', - jsrgtuwei_info:'魏势力技。出牌阶段开始时,你可以获得攻击范围内任意名角色各一张牌。然后此回合结束时,这些角色中未于本回合受到过伤害的角色依次获得你的一张牌。', - jsrg_xugong:'承许贡', - jsrg_xugong_prefix:'承', - jsrgbiaozhao:'表召', - jsrgbiaozhao_info:'准备阶段,你可以选择两名其他角色A和B。直到你的下回合开始时或你死亡后,A对B使用牌无次数和距离限制,且B对你使用的牌造成的伤害+1。', - jsrgyechou:'业仇', - jsrgyechou_info:'当你死亡时,你可以令一名其他角色获得如下效果:当其受到伤害值不小于其体力值的伤害时,其令此伤害翻倍。', - jsrg_chunyuqiong:'承淳于琼', - jsrg_chunyuqiong_prefix:'承', - jsrgcangchu:'仓储', - jsrgcangchu_info:'一名角色的结束阶段,你可以令至多X名角色各摸一张牌,若X大于存活角色数,则改为各摸两张牌(X为你于此回合得到的牌数)。', - jsrgshishou:'失守', - jsrgshishou_info:'锁定技。①当你使用【酒】时,你摸三张牌,然后你本回合不能再使用牌。②当你受到火焰伤害后,你令〖仓储〗失效直到你的下回合结束后。', + jsrg_sunce: "梦孙策", + jsrg_sunce_prefix: "梦", + jsrgduxing: "独行", + jsrgduxing_info: + "出牌阶段限一次。你可以视为使用一张可以指定任意名目标角色的【决斗】,且所有目标角色的手牌均视为【杀】直到此牌结算结束。", + jsrgzhiheng: "猘横", + jsrgzhiheng_info: + "锁定技。当你因执行牌的效果对目标角色造成伤害时,若其于此回合响应过你使用过的牌,此伤害+1。", + jsrgzhasi: "诈死", + jsrgzhasi_info: + "限定技。当你受到伤害值不小于你的体力值的伤害时,你可以防止此伤害,然后失去〖猘横〗并获得〖制衡〗。然后你不计入距离和座次计算直到你对其他角色使用牌后或当你受到伤害后。", + jsrgbashi: "霸世", + jsrgbashi_info: + "主公技。当你需要打出【杀】或【闪】时,你可以令其他吴势力角色选择是否打出一张【杀】或【闪】。若有角色响应,则视为你打出了一张【杀】或【闪】。", + jsrg_xuyou: "承许攸", + jsrg_xuyou_prefix: "承", + jsrglipan: "离叛", + jsrglipan_info: + "回合结束时,你可以变更势力,然后摸X张牌并执行一个额外的出牌阶段。此阶段结束时,所有与你势力相同的角色依次可以将一张牌当【决斗】对你使用(X为与你势力相同的其他角色数)。", + jsrgqingxi: "轻袭", + jsrgqingxi_info: + "群势力技。出牌阶段每名角色限一次。你可以选择一名手牌数小于你的角色,你将手牌数弃置至与其相同,然后视为对其使用一张刺【杀】。", + jsrgjinmie: "烬灭", + jsrgjinmie_info: + "魏势力技。出牌阶段限一次。你可以选择一名手牌数大于你的角色,你视为对其使用一张火【杀】。当此牌造成伤害后,你将其手牌数弃置至与你相同。", + jsrg_lvbu: "承吕布", + jsrg_lvbu_prefix: "承", + jsrgwuchang: "无常", + jsrgwuchang_info: + "锁定技。①当你获得其他角色的牌后,你变更势力为与其相同。②当你使用【杀】或【决斗】对与你势力相同的目标角色造成伤害时,此伤害+1,然后变更势力为群。", + jsrgqingjiao: "轻狡", + jsrgqingjiao_info: + "群势力技。出牌阶段各限一次。你可以将一张牌当【推心置腹】/【趁火打劫】对一名手牌数大于/小于你的角色使用。", + jsrgchengxu: "乘虚", + jsrgchengxu_info: "蜀势力技。与你势力相同的其他角色不能响应你使用的牌。", + jsrg_zhanghe: "承张郃", + jsrg_zhanghe_prefix: "承", + jsrgqiongtu: "穷途", + jsrgqiongtu_info: + "群势力技。每回合限一次。你可以将一张非基本牌置于武将牌上视为使用一张【无懈可击】。若此牌生效,你摸一张牌,否则你变更势力为魏并获得所有“穷途”牌。", + jsrgxianzhu: "先著", + jsrgxianzhu_info: + "魏势力技。你可以将一张普通锦囊牌当无次数限制的【杀】使用。当此牌对唯一目标造成伤害后,你视为对该角色使用一张此普通锦囊牌。", + jsrg_zoushi: "承邹氏", + jsrg_zoushi_prefix: "承", + jsrgguyin: "孤吟", + jsrgguyin_info: + "准备阶段,你可以翻面,且令所有其他男性角色依次选择是否翻面。然后你和所有背面朝上的角色轮流各摸一张牌,直到你们累计以此法得到X张牌(X为场上存活角色与死亡角色中男性角色数)。", + jsrgzhangdeng: "帐灯", + jsrgzhangdeng_info: + "①当一名武将牌背面朝上的角色需要使用【酒】时,若你的武将牌背面朝上,其可以视为使用之。②当一名角色于一回合第二次发动〖帐灯①〗时,你将武将牌翻面至正面朝上。", + jsrg_guanyu: "承关羽", + jsrg_guanyu_prefix: "承", + jsrgguanjue: "冠绝", + jsrgguanjue_info: + "锁定技。当你使用或打出有花色的牌时,你令所有其他角色于此回合内不能使用或打出该花色的牌。", + jsrgnianen: "念恩", + jsrgnianen_info: + "你可以将一张牌当任意基本牌使用或打出,然后若此牌不为红色或你以此法使用或打出的牌不为普通【杀】,则直到此回合结束,该技能失效且你视为拥有〖马术〗。", + jsrg_chendeng: "承陈登", + jsrg_chendeng_prefix: "承", + jsrglunshi: "论势", + jsrglunshi_info: + "出牌阶段限一次。你可以令一名角色摸等同于其攻击范围内角色数的牌(至多摸至五张),然后其弃置等同于攻击范围内含有其的角色数的牌。", + jsrgguitu: "诡图", + jsrgguitu_info: "准备阶段,你可以交换场上的两张武器牌,然后攻击范围以此法减少的角色回复1点体力。", + jsrg_zhenji: "承甄宓", + jsrg_zhenji_prefix: "承", + jsrgjixiang: "济乡", + jsrgjixiang_info: + "回合内每种牌名限一次。当一名其他角色需要使用或打出一张基本牌时,你可以弃置一张牌令其视为使用或打出之,然后你摸一张牌并令〖称贤〗于此阶段可发动次数上限+1。", + jsrgchengxian: "称贤", + jsrgchengxian_info: + "出牌阶段限两次。你可以将一张手牌当一张本回合未以此法使用过的普通锦囊牌使用(此转化牌须与以此法转化的手牌的合法目标数相同)。", + jsrg_zhangliao: "承张辽", + jsrg_zhangliao_prefix: "承", + jsrgzhengbing: "整兵", + jsrgzhengbing_info: + "群势力技。出牌阶段限三次。你可以重铸一张牌,若此牌为:【杀】,你本回合手牌上限+2;【闪】,你摸一张牌;【桃】,你变更势力为魏。", + jsrgtuwei: "突围", + jsrgtuwei_info: + "魏势力技。出牌阶段开始时,你可以获得攻击范围内任意名角色各一张牌。然后此回合结束时,这些角色中未于本回合受到过伤害的角色依次获得你的一张牌。", + jsrg_xugong: "承许贡", + jsrg_xugong_prefix: "承", + jsrgbiaozhao: "表召", + jsrgbiaozhao_info: + "准备阶段,你可以选择两名其他角色A和B。直到你的下回合开始时或你死亡后,A对B使用牌无次数和距离限制,且B对你使用的牌造成的伤害+1。", + jsrgyechou: "业仇", + jsrgyechou_info: + "当你死亡时,你可以令一名其他角色获得如下效果:当其受到伤害值不小于其体力值的伤害时,其令此伤害翻倍。", + jsrg_chunyuqiong: "承淳于琼", + jsrg_chunyuqiong_prefix: "承", + jsrgcangchu: "仓储", + jsrgcangchu_info: + "一名角色的结束阶段,你可以令至多X名角色各摸一张牌,若X大于存活角色数,则改为各摸两张牌(X为你于此回合得到的牌数)。", + jsrgshishou: "失守", + jsrgshishou_info: + "锁定技。①当你使用【酒】时,你摸三张牌,然后你本回合不能再使用牌。②当你受到火焰伤害后,你令〖仓储〗失效直到你的下回合结束后。", //江山如故·转 - ying:'影', - ying_info:'当此牌进入弃牌堆后,系统将此牌移出游戏。', - jsrg_guojia:'梦郭嘉', - jsrg_guojia_prefix:'梦', - jsrgqingzi:'轻辎', - jsrgqingzi_info:'准备阶段,你可以弃置任意名其他角色装备区里的各一张牌,然后令这些角色获得〖神速〗直到你的下回合开始。', - jsrgdingce:'定策', - jsrgdingce_info:'当你受到伤害后,你可以依次弃置你与伤害来源的各一张手牌。若这两张牌颜色相同,你视为使用一张【洞烛先机】。', - jsrgzhenfeng:'针锋', - jsrgzhenfeng_info:'出牌阶段每种类别各限一次。你可以视为使用一张存活角色的技能描述中包含的基本牌或普通锦囊牌(无距离和次数限制)。当此牌对技能描述中包含此牌的角色生效时,你对其造成1点伤害。', - jsrg_zhangfei:'转张飞', - jsrg_zhangfei_prefix:'转', - jsrgbaohe:'暴喝', - jsrgbaohe_info:'一名角色的出牌阶段结束时,你可以弃置两张牌,然后视为你对攻击范围内包含其的所有角色使用一张【杀】。当一名角色使用牌响应此【杀】后,此【杀】对后续目标角色造成的伤害+1。', - jsrgxushi:'虚势', - jsrgxushi_info:'出牌阶段限一次。你可以交给任意名角色各一张牌,然后你获得两倍数量的【影】。', - jsrg_machao:'转马超', - jsrg_machao_prefix:'转', - jsrgzhuiming:'追命', - jsrgzhuiming_info:'当你使用【杀】指定唯一目标后,你可以声明一种颜色并令目标角色弃置任意张牌,然后你展示目标角色一张牌。若此牌颜色与你声明的颜色相同,则此【杀】不计入次数限制、不可被响应且伤害+1。', - jsrg_lougui:'转娄圭', - jsrg_lougui_prefix:'转', - jsrgshacheng:'沙城', - jsrgshacheng_info:'①游戏开始时,你将牌堆顶的两张牌置于武将牌上,称为“城”。②当一名角色使用【杀】结算结束后,你可以移去一张“城”,令此牌的其中一名目标角色摸X张牌(X为该角色本回合失去过的牌数且至多为5)。', - jsrgninghan:'凝寒', - jsrgninghan_info:'锁定技。①所有角色手牌中的♣【杀】均视为冰【杀】。②当一名角色受到冰冻伤害后,你将造成此伤害的牌对应的实体牌置入“城”。', - jsrg_zhangren:'转张任', - jsrg_zhangren_prefix:'转', - jsrgfuni:'伏匿', - jsrgfuni_info:'锁定技。①你的攻击范围终值为0。②一轮游戏开始时,你令任意名角色获得共计X张【影】(X为存活角色数的一半,向上取整)。③当有牌进入弃牌堆后,若其中有【影】,你于本回合使用牌无距离限制且不能被响应。', - jsrgchuanxin:'穿心', - jsrgchuanxin_info:'一名角色的结束阶段,你可以将一张牌当【杀】使用。当一名角色受到渠道为此【杀】的伤害时,此伤害+Y(Y为其本回合回复过的体力值)。', - jsrg_huangzhong:'转黄忠', - jsrg_huangzhong_prefix:'转', - jsrgcuifeng:'摧锋', - jsrgcuifeng_info:'限定技。出牌阶段,你可以视为使用一张单目标的伤害类牌(无距离限制)。此回合结束时,若此牌未造成伤害或造成的伤害值大于1,你重置〖摧锋〗。', - jsrgdengnan:'登难', - jsrgdengnan_info:'限定技。出牌阶段,你可以视为使用一张非伤害类普通锦囊牌。此回合结束时,若此牌的目标均于此回合受到过伤害,你重置〖登难〗。', - jsrg_xiahourong:'转夏侯荣', - jsrg_xiahourong_prefix:'转', - jsrgfenjian:'奋剑', - jsrgfenjian_info:'每回合各限一次。当你需要对其他角色使用【决斗】或【桃】时,你可以令你本回合受到的伤害+1,视为使用之。', - jsrg_sunshangxiang:'转孙尚香', - jsrg_sunshangxiang_prefix:'转', - jsrgguiji:'闺忌', - jsrgguiji_info:'每回合限一次。出牌阶段,你可以与一名手牌数小于你的男性角色交换手牌。然后其下个出牌阶段结束时,你可以与其交换手牌。', - jsrgjiaohao:'骄豪', - jsrgjiaohao_info:'①其他角色的出牌阶段限一次。其可以将手牌中的一张装备牌置于你的装备区。②准备阶段,你获得X张【影】(X为你空置装备栏数的一半,向上取整)。', - jsrg_pangtong:'转庞统', - jsrg_pangtong_prefix:'转', - jsrgmanjuan:'漫卷', - jsrgmanjuan_info:'若你没有手牌,你可以如手牌般使用或打出于本回合进入弃牌堆的牌(每种点数每回合限一次)。', - jsrgyangming:'养名', - jsrgyangming_info:'出牌阶段限一次。你可以与一名角色拼点,若其:没赢,你可以与其重复此流程;赢,其摸X张牌,然后你回复1点体力(X为其此阶段没赢的次数)。', - jsrg_hansui:'转韩遂', - jsrg_hansui_prefix:'转', - jsrgniluan:'逆乱', - jsrgniluan_info:'准备阶段,你可以选择一项:1.弃置一张牌,对一名未对你造成过伤害的角色造成1点伤害;2.令一名对你造成过伤害的角色摸两张牌。', - jsrghuchou:'互雠', - jsrghuchou_info:'锁定技。当你对最后对你使用伤害类牌的角色造成伤害时,此伤害+1。', - jsrgjiemeng:'皆盟', - jsrgjiemeng_info:'主公技,锁定技。所有群势力角色至其他角色的距离-X(X为群势力角色数)。', - jsrg_zhangchu:'转张楚', - jsrg_zhangchu_prefix:'转', - jsrghuozhong:'惑众', - jsrghuozhong_info:'所有角色出牌阶段限一次。其可以将一张黑色非锦囊牌当【兵粮寸断】置于其判定区,然后令你摸两张牌。', - jsrgrihui:'日彗', - jsrgrihui_info:'①当你使用【杀】对目标角色造成伤害后,你可以令判定区有牌的其他角色各摸一张牌。②你于一回合内对判定区没有牌的角色使用的第一张【杀】无任何次数限制。', - jsrg_xiahouen:'转夏侯恩', - jsrg_xiahouen_prefix:'转', - jsrghujian:'护剑', - jsrghujian_info:'①游戏开始时,你从游戏外获得一张【赤血青锋】。②一名角色的回合结束时,此回合最后一名使用或打出牌的角色可以获得弃牌堆中的【赤血青锋】。', - jsrgshili:'恃力', - jsrgshili_info:'出牌阶段限一次。你可以将一张手牌中的装备牌当【决斗】使用。', - jsrg_fanjiangzhangda:'转范强张达', - jsrg_fanjiangzhangda_ab:'转范疆张达', - jsrg_fanjiangzhangda_prefix:'转', - jsrgfushan:'负山', - jsrgfushan_info:'出牌阶段开始时,所有其他角色可以依次交给你一张牌并令你此阶段使用【杀】的次数上限+1。此阶段结束时,若你使用【杀】的次数未达到上限且此阶段以此法交给你牌的角色均存活,你失去2点体力,否则你将手牌摸至体力上限。', + ying: "影", + ying_info: "当此牌进入弃牌堆后,系统将此牌移出游戏。", + jsrg_guojia: "梦郭嘉", + jsrg_guojia_prefix: "梦", + jsrgqingzi: "轻辎", + jsrgqingzi_info: + "准备阶段,你可以弃置任意名其他角色装备区里的各一张牌,然后令这些角色获得〖神速〗直到你的下回合开始。", + jsrgdingce: "定策", + jsrgdingce_info: + "当你受到伤害后,你可以依次弃置你与伤害来源的各一张手牌。若这两张牌颜色相同,你视为使用一张【洞烛先机】。", + jsrgzhenfeng: "针锋", + jsrgzhenfeng_info: + "出牌阶段每种类别各限一次。你可以视为使用一张存活角色的技能描述中包含的基本牌或普通锦囊牌(无距离和次数限制)。当此牌对技能描述中包含此牌的角色生效时,你对其造成1点伤害。", + jsrg_zhangfei: "转张飞", + jsrg_zhangfei_prefix: "转", + jsrgbaohe: "暴喝", + jsrgbaohe_info: + "一名角色的出牌阶段结束时,你可以弃置两张牌,然后视为你对攻击范围内包含其的所有角色使用一张【杀】。当一名角色使用牌响应此【杀】后,此【杀】对后续目标角色造成的伤害+1。", + jsrgxushi: "虚势", + jsrgxushi_info: "出牌阶段限一次。你可以交给任意名角色各一张牌,然后你获得两倍数量的【影】。", + jsrg_machao: "转马超", + jsrg_machao_prefix: "转", + jsrgzhuiming: "追命", + jsrgzhuiming_info: + "当你使用【杀】指定唯一目标后,你可以声明一种颜色并令目标角色弃置任意张牌,然后你展示目标角色一张牌。若此牌颜色与你声明的颜色相同,则此【杀】不计入次数限制、不可被响应且伤害+1。", + jsrg_lougui: "转娄圭", + jsrg_lougui_prefix: "转", + jsrgshacheng: "沙城", + jsrgshacheng_info: + "①游戏开始时,你将牌堆顶的两张牌置于武将牌上,称为“城”。②当一名角色使用【杀】结算结束后,你可以移去一张“城”,令此牌的其中一名目标角色摸X张牌(X为该角色本回合失去过的牌数且至多为5)。", + jsrgninghan: "凝寒", + jsrgninghan_info: + "锁定技。①所有角色手牌中的♣【杀】均视为冰【杀】。②当一名角色受到冰冻伤害后,你将造成此伤害的牌对应的实体牌置入“城”。", + jsrg_zhangren: "转张任", + jsrg_zhangren_prefix: "转", + jsrgfuni: "伏匿", + jsrgfuni_info: + "锁定技。①你的攻击范围终值为0。②一轮游戏开始时,你令任意名角色获得共计X张【影】(X为存活角色数的一半,向上取整)。③当有牌进入弃牌堆后,若其中有【影】,你于本回合使用牌无距离限制且不能被响应。", + jsrgchuanxin: "穿心", + jsrgchuanxin_info: + "一名角色的结束阶段,你可以将一张牌当【杀】使用。当一名角色受到渠道为此【杀】的伤害时,此伤害+Y(Y为其本回合回复过的体力值)。", + jsrg_huangzhong: "转黄忠", + jsrg_huangzhong_prefix: "转", + jsrgcuifeng: "摧锋", + jsrgcuifeng_info: + "限定技。出牌阶段,你可以视为使用一张单目标的伤害类牌(无距离限制)。此回合结束时,若此牌未造成伤害或造成的伤害值大于1,你重置〖摧锋〗。", + jsrgdengnan: "登难", + jsrgdengnan_info: + "限定技。出牌阶段,你可以视为使用一张非伤害类普通锦囊牌。此回合结束时,若此牌的目标均于此回合受到过伤害,你重置〖登难〗。", + jsrg_xiahourong: "转夏侯荣", + jsrg_xiahourong_prefix: "转", + jsrgfenjian: "奋剑", + jsrgfenjian_info: + "每回合各限一次。当你需要对其他角色使用【决斗】或【桃】时,你可以令你本回合受到的伤害+1,视为使用之。", + jsrg_sunshangxiang: "转孙尚香", + jsrg_sunshangxiang_prefix: "转", + jsrgguiji: "闺忌", + jsrgguiji_info: + "每回合限一次。出牌阶段,你可以与一名手牌数小于你的男性角色交换手牌。然后其下个出牌阶段结束时,你可以与其交换手牌。", + jsrgjiaohao: "骄豪", + jsrgjiaohao_info: + "①其他角色的出牌阶段限一次。其可以将手牌中的一张装备牌置于你的装备区。②准备阶段,你获得X张【影】(X为你空置装备栏数的一半,向上取整)。", + jsrg_pangtong: "转庞统", + jsrg_pangtong_prefix: "转", + jsrgmanjuan: "漫卷", + jsrgmanjuan_info: + "若你没有手牌,你可以如手牌般使用或打出于本回合进入弃牌堆的牌(每种点数每回合限一次)。", + jsrgyangming: "养名", + jsrgyangming_info: + "出牌阶段限一次。你可以与一名角色拼点,若其:没赢,你可以与其重复此流程;赢,其摸X张牌,然后你回复1点体力(X为其此阶段没赢的次数)。", + jsrg_hansui: "转韩遂", + jsrg_hansui_prefix: "转", + jsrgniluan: "逆乱", + jsrgniluan_info: + "准备阶段,你可以选择一项:1.弃置一张牌,对一名未对你造成过伤害的角色造成1点伤害;2.令一名对你造成过伤害的角色摸两张牌。", + jsrghuchou: "互雠", + jsrghuchou_info: "锁定技。当你对最后对你使用伤害类牌的角色造成伤害时,此伤害+1。", + jsrgjiemeng: "皆盟", + jsrgjiemeng_info: "主公技,锁定技。所有群势力角色至其他角色的距离-X(X为群势力角色数)。", + jsrg_zhangchu: "转张楚", + jsrg_zhangchu_prefix: "转", + jsrghuozhong: "惑众", + jsrghuozhong_info: + "所有角色出牌阶段限一次。其可以将一张黑色非锦囊牌当【兵粮寸断】置于其判定区,然后令你摸两张牌。", + jsrgrihui: "日彗", + jsrgrihui_info: + "①当你使用【杀】对目标角色造成伤害后,你可以令判定区有牌的其他角色各摸一张牌。②你于一回合内对判定区没有牌的角色使用的第一张【杀】无任何次数限制。", + jsrg_xiahouen: "转夏侯恩", + jsrg_xiahouen_prefix: "转", + jsrghujian: "护剑", + jsrghujian_info: + "①游戏开始时,你从游戏外获得一张【赤血青锋】。②一名角色的回合结束时,此回合最后一名使用或打出牌的角色可以获得弃牌堆中的【赤血青锋】。", + jsrgshili: "恃力", + jsrgshili_info: "出牌阶段限一次。你可以将一张手牌中的装备牌当【决斗】使用。", + jsrg_fanjiangzhangda: "转范强张达", + jsrg_fanjiangzhangda_ab: "转范疆张达", + jsrg_fanjiangzhangda_prefix: "转", + jsrgfushan: "负山", + jsrgfushan_info: + "出牌阶段开始时,所有其他角色可以依次交给你一张牌并令你此阶段使用【杀】的次数上限+1。此阶段结束时,若你使用【杀】的次数未达到上限且此阶段以此法交给你牌的角色均存活,你失去2点体力,否则你将手牌摸至体力上限。", //江山如故·合 - jsrg_zhugeliang:'梦诸葛亮', - jsrg_zhugeliang_prefix:'梦', - jsrgwentian:'问天', - jsrgwentian_info:'①你可以将牌堆顶的牌当【无懈可击】/【火攻】使用,若此牌不为黑色/红色,〖问天〗于本轮失效。②每回合限一次。你的一个阶段开始时,你可以观看牌堆顶的五张牌,然后将其中一张牌交给一名其他角色,将其余牌以任意顺序置于牌堆顶或牌堆底。', - jsrgchushi:'出师', - jsrgchushi_info:'出牌阶段限一次。若你不为主公,你可以与主公议事。若结果为:红色,你与其各摸一张牌,若你与其手牌数之和小于7,重复此流程;黑色,当你于本轮内造成属性伤害时,此伤害+1。', - jsrgyinlve:'隐略', - jsrgyinlve_info:'每轮各限一次。当一名角色受到火焰/雷电伤害时,你可以防止此伤害,然后于当前回合结束后执行一个只有摸牌/弃牌阶段的回合。', - jsrg_jiangwei:'合姜维', - jsrg_jiangwei_prefix:'合', - jsrgjinfa:'矜伐', - jsrgjinfa_info:'出牌阶段限一次。你可以展示一张手牌,然后令所有体力上限不大于你的角色议事。若结果与此牌颜色:相同,你令其中至多两名角色将手牌摸至体力上限;不同,你获得两张【影】。然后若没有其他角色与你意见相同,你可以变更势力。', - jsrgfumou:'复谋', - jsrgfumou_info:'魏势力技。当你议事结算结束后,与你意见不同的角色本回合不能使用或打出与其意见颜色相同的牌,你可以将一张【影】当【出其不意】对一名与你意见不同的角色使用。', - jsrgxuanfeng:'选锋', - jsrgxuanfeng_info:'蜀势力技。你可以将一张【影】当无距离和次数限制的刺【杀】使用。', - jsrg_luxun:'合陆逊', - jsrg_luxun_prefix:'合', - jsrgyoujin:'诱进', - jsrgyoujin_info:'出牌阶段开始时,你可以与一名角色拼点,你与其本回合不能使用或打出点数小于自己拼点牌的手牌,且赢的角色视为对没赢的角色使用一张【杀】。', - jsrgdailao:'待劳', - jsrgdailao_info:'出牌阶段,若你没有可以使用的手牌,你可以展示所有手牌并摸两张牌,然后结束此回合。', - jsrgzhubei:'逐北', - jsrgzhubei_info:'锁定技。①当你对本回合受到过伤害的角色造成伤害时,此伤害+1。②你对本回合失去过最后手牌的角色使用牌无次数限制。', - jsrg_zhaoyun:'合赵云', - jsrg_zhaoyun_prefix:'合', - jsrglonglin:'龙临', - jsrglonglin_info:'其他角色于其出牌阶段内首次使用【杀】指定第一个目标后,你可以弃置一张牌令此【杀】无效,然后其可以视为对你使用一张【决斗】,你以此法造成伤害后,其本阶段不能再使用手牌。', - jsrgzhendan:'镇胆', - jsrgzhendan_info:'①你可以将一张非基本手牌当任意基本牌使用或打出。②当你受到伤害后,你摸X张牌并令该技能本轮失效(X为本轮所有角色执行过的回合数且至多为5)。③一轮游戏开始时,若上一轮该技能未因〖镇胆②〗失效过,你摸Y张牌(Y为上一轮所有角色执行过的回合数且至多为5)。', - jsrg_simayi:'合司马懿', - jsrg_simayi_prefix:'合', - jsrgyingshi:'鹰眎', - jsrgyingshi_info:'当你翻面时,你可以观看牌堆底的三张牌(若死亡角色数大于2则改为五张),然后将其中任意数量的牌以任意顺序置于牌堆顶,其余以任意顺序置于牌堆底。', - jsrgtuigu:'蜕骨', - jsrgtuigu_info:'①回合开始时,你可以翻面并令你本回合的手牌上限+X,然后摸X张牌并视为使用一张【解甲归田】(X为存活角色数的一半,向下取整),目标角色不能使用以此法得到的牌直到其回合结束。②一轮游戏开始时,若你上一轮未执行过回合(因〖蜕骨②〗执行的回合除外),你获得一个额外的回合。③当你失去装备牌里的牌后,你回复1点体力。', - jsrg_guoxun:'合郭循', - jsrg_guoxun_prefix:'合', - jsrgeqian:'遏前', - jsrgeqian_info:'①结束阶段,你可以蓄谋任意次。②当你使用【杀】或蓄谋牌指定其他角色为唯一目标后,你可以令此牌不计入次数限制并获得目标一张牌,然后其可以令你本回合至其的距离+2。', - jsrgfusha:'伏杀', - jsrgfusha_info:'限定技。出牌阶段,若你的攻击范围内仅有一名角色,你可以对其造成X点伤害(X为你的攻击范围,至多为游戏人数)。', - jsrg_sunlubansunluyu:'合大小虎', - jsrg_sunlubansunluyu_prefix:'合', - jsrgdaimou:'殆谋', - jsrgdaimou_info:'每回合各限一次。当一名角色使用【杀】指定其他角色/你为目标时,你可以用牌堆顶的牌蓄谋/你须弃置你区域里的一张蓄谋牌。', - jsrgfangjie:'芳洁', - jsrgfangjie_info:'准备阶段,若你没有蓄谋牌,你回复1点体力并摸一张牌,否则你可以弃置你区域里的任意张蓄谋牌并失去〖芳洁〗。', - jsrg_caofang:'合曹芳', - jsrg_caofang_prefix:'合', - jsrgzhaotu:'诏图', - jsrgzhaotu_info:'每轮限一次。你可以将一张红色非锦囊牌当【乐不思蜀】使用,然后当前回合结束后,目标执行一个手牌上限-2的额外回合。', - jsrgjingju:'惊惧', - jsrgjingju_info:'当你需要使用任意一种基本牌时,你可以将其他角色判定区里的一张牌移动至你的判定区,视为你使用之。', - jsrgweizhui:'危坠', - jsrgweizhui_info:'主公技。其他魏势力角色的结束阶段,其可以将一张黑色手牌当【过河拆桥】对你使用。', - jsrg_sunjun:'合孙峻', - jsrg_sunjun_prefix:'合', - jsrgyaoyan:'邀宴', - jsrgyaoyan_info:'准备阶段,你可以令所有角色依次选择是否于回合结束时议事,若议事结果为:红色,你获得任意名未议事的角色各一张手牌;黑色,你可以对一名议事的角色造成2点伤害。', - jsrgbazheng:'霸政', - jsrgbazheng_info:'当你参与的议事展示意见时,本回合受到过你伤害的角色意见视为与你相同。', - jsrg_liuyong:'合刘永', - jsrg_liuyong_prefix:'合', - jsrgdanxin:'丹心', - jsrgdanxin_info:'你可以将一张牌当【推心置腹】使用,你展示以此法交出与得到的牌,以此法得到♥牌的角色回复1点体力,然后你至目标角色的距离+1直到回合结束。', - jsrgfengxiang:'封乡', - jsrgfengxiang_info:'锁定技。当你受到伤害后,你与一名其他角色交换装备区里的所有牌。若你装备区里的牌因此减少,你摸等同于减少牌数的牌。', - jsrg_weiwenzhugezhi:'合卫温诸葛直', - jsrg_weiwenzhugezhi_prefix:'合', - jsrgfuhai:'浮海', - jsrgfuhai_info:'出牌阶段限一次。你可以令所有有手牌的其他角色同时展示一张手牌,然后你选择一个方向并摸X张牌(X为该方向上的角色展示的点数连续严格递增或严格递减的牌数,至少为1)。', - jsrg_zhangxuan:'合张嫙', - jsrg_zhangxuan_prefix:'合', - jsrgtongli:'同礼', - jsrgtongli_info:'当你于出牌阶段内使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内使用过的牌数相等,则你可以展示所有手牌,令此牌额外结算一次。', - jsrgshezang:'奢葬', - jsrgshezang_info:'每轮限一次。当你或你回合内的其他角色进入濒死状态时,你可以亮出牌堆顶的四张牌,获得其中任意张花色各不相同的牌。', - jsrg_gaoxiang:'合高翔', - jsrg_gaoxiang_prefix:'合', - jsrgchiying:'驰应', - jsrgchiying_info:'出牌阶段限一次。你可以选择一名角色,令其攻击范围内的其他角色依次弃置一张牌。若以此法弃置的基本牌数不大于其体力值,其获得这些基本牌。', - jsrg_guozhao:'合郭照', - jsrg_guozhao_prefix:'合', - jsrgpianchong:'偏宠', - jsrgpianchong_info:'一名角色的结束阶段,若你于此回合内失去过牌,你可以判定。若结果为红色/黑色,你摸此回合进入弃牌堆的红色/黑色牌数量的牌。', - jsrgzunwei:'尊位', - jsrgzunwei_info:'出牌阶段限一次。你可以选择一名其他角色并选择执行一项,然后移除该选项:1.将手牌数摸至与该角色相同(最多摸五张);2.将其装备牌移至你的装备区,直到你装备区的牌数不少于其;3.将体力值回复至与该角色相同。', + jsrg_zhugeliang: "梦诸葛亮", + jsrg_zhugeliang_prefix: "梦", + jsrgwentian: "问天", + jsrgwentian_info: + "①你可以将牌堆顶的牌当【无懈可击】/【火攻】使用,若此牌不为黑色/红色,〖问天〗于本轮失效。②每回合限一次。你的一个阶段开始时,你可以观看牌堆顶的五张牌,然后将其中一张牌交给一名其他角色,将其余牌以任意顺序置于牌堆顶或牌堆底。", + jsrgchushi: "出师", + jsrgchushi_info: + "出牌阶段限一次。若你不为主公,你可以与主公议事。若结果为:红色,你与其各摸一张牌,若你与其手牌数之和小于7,重复此流程;黑色,当你于本轮内造成属性伤害时,此伤害+1。", + jsrgyinlve: "隐略", + jsrgyinlve_info: + "每轮各限一次。当一名角色受到火焰/雷电伤害时,你可以防止此伤害,然后于当前回合结束后执行一个只有摸牌/弃牌阶段的回合。", + jsrg_jiangwei: "合姜维", + jsrg_jiangwei_prefix: "合", + jsrgjinfa: "矜伐", + jsrgjinfa_info: + "出牌阶段限一次。你可以展示一张手牌,然后令所有体力上限不大于你的角色议事。若结果与此牌颜色:相同,你令其中至多两名角色将手牌摸至体力上限;不同,你获得两张【影】。然后若没有其他角色与你意见相同,你可以变更势力。", + jsrgfumou: "复谋", + jsrgfumou_info: + "魏势力技。当你议事结算结束后,与你意见不同的角色本回合不能使用或打出与其意见颜色相同的牌,你可以将一张【影】当【出其不意】对一名与你意见不同的角色使用。", + jsrgxuanfeng: "选锋", + jsrgxuanfeng_info: "蜀势力技。你可以将一张【影】当无距离和次数限制的刺【杀】使用。", + jsrg_luxun: "合陆逊", + jsrg_luxun_prefix: "合", + jsrgyoujin: "诱进", + jsrgyoujin_info: + "出牌阶段开始时,你可以与一名角色拼点,你与其本回合不能使用或打出点数小于自己拼点牌的手牌,且赢的角色视为对没赢的角色使用一张【杀】。", + jsrgdailao: "待劳", + jsrgdailao_info: + "出牌阶段,若你没有可以使用的手牌,你可以展示所有手牌并摸两张牌,然后结束此回合。", + jsrgzhubei: "逐北", + jsrgzhubei_info: + "锁定技。①当你对本回合受到过伤害的角色造成伤害时,此伤害+1。②你对本回合失去过最后手牌的角色使用牌无次数限制。", + jsrg_zhaoyun: "合赵云", + jsrg_zhaoyun_prefix: "合", + jsrglonglin: "龙临", + jsrglonglin_info: + "其他角色于其出牌阶段内首次使用【杀】指定第一个目标后,你可以弃置一张牌令此【杀】无效,然后其可以视为对你使用一张【决斗】,你以此法造成伤害后,其本阶段不能再使用手牌。", + jsrgzhendan: "镇胆", + jsrgzhendan_info: + "①你可以将一张非基本手牌当任意基本牌使用或打出。②当你受到伤害后,你摸X张牌并令该技能本轮失效(X为本轮所有角色执行过的回合数且至多为5)。③一轮游戏开始时,若上一轮该技能未因〖镇胆②〗失效过,你摸Y张牌(Y为上一轮所有角色执行过的回合数且至多为5)。", + jsrg_simayi: "合司马懿", + jsrg_simayi_prefix: "合", + jsrgyingshi: "鹰眎", + jsrgyingshi_info: + "当你翻面时,你可以观看牌堆底的三张牌(若死亡角色数大于2则改为五张),然后将其中任意数量的牌以任意顺序置于牌堆顶,其余以任意顺序置于牌堆底。", + jsrgtuigu: "蜕骨", + jsrgtuigu_info: + "①回合开始时,你可以翻面并令你本回合的手牌上限+X,然后摸X张牌并视为使用一张【解甲归田】(X为存活角色数的一半,向下取整),目标角色不能使用以此法得到的牌直到其回合结束。②一轮游戏开始时,若你上一轮未执行过回合(因〖蜕骨②〗执行的回合除外),你获得一个额外的回合。③当你失去装备牌里的牌后,你回复1点体力。", + jsrg_guoxun: "合郭循", + jsrg_guoxun_prefix: "合", + jsrgeqian: "遏前", + jsrgeqian_info: + "①结束阶段,你可以蓄谋任意次。②当你使用【杀】或蓄谋牌指定其他角色为唯一目标后,你可以令此牌不计入次数限制并获得目标一张牌,然后其可以令你本回合至其的距离+2。", + jsrgfusha: "伏杀", + jsrgfusha_info: + "限定技。出牌阶段,若你的攻击范围内仅有一名角色,你可以对其造成X点伤害(X为你的攻击范围,至多为游戏人数)。", + jsrg_sunlubansunluyu: "合大小虎", + jsrg_sunlubansunluyu_prefix: "合", + jsrgdaimou: "殆谋", + jsrgdaimou_info: + "每回合各限一次。当一名角色使用【杀】指定其他角色/你为目标时,你可以用牌堆顶的牌蓄谋/你须弃置你区域里的一张蓄谋牌。", + jsrgfangjie: "芳洁", + jsrgfangjie_info: + "准备阶段,若你没有蓄谋牌,你回复1点体力并摸一张牌,否则你可以弃置你区域里的任意张蓄谋牌并失去〖芳洁〗。", + jsrg_caofang: "合曹芳", + jsrg_caofang_prefix: "合", + jsrgzhaotu: "诏图", + jsrgzhaotu_info: + "每轮限一次。你可以将一张红色非锦囊牌当【乐不思蜀】使用,然后当前回合结束后,目标执行一个手牌上限-2的额外回合。", + jsrgjingju: "惊惧", + jsrgjingju_info: + "当你需要使用任意一种基本牌时,你可以将其他角色判定区里的一张牌移动至你的判定区,视为你使用之。", + jsrgweizhui: "危坠", + jsrgweizhui_info: + "主公技。其他魏势力角色的结束阶段,其可以将一张黑色手牌当【过河拆桥】对你使用。", + jsrg_sunjun: "合孙峻", + jsrg_sunjun_prefix: "合", + jsrgyaoyan: "邀宴", + jsrgyaoyan_info: + "准备阶段,你可以令所有角色依次选择是否于回合结束时议事,若议事结果为:红色,你获得任意名未议事的角色各一张手牌;黑色,你可以对一名议事的角色造成2点伤害。", + jsrgbazheng: "霸政", + jsrgbazheng_info: "当你参与的议事展示意见时,本回合受到过你伤害的角色意见视为与你相同。", + jsrg_liuyong: "合刘永", + jsrg_liuyong_prefix: "合", + jsrgdanxin: "丹心", + jsrgdanxin_info: + "你可以将一张牌当【推心置腹】使用,你展示以此法交出与得到的牌,以此法得到♥牌的角色回复1点体力,然后你至目标角色的距离+1直到回合结束。", + jsrgfengxiang: "封乡", + jsrgfengxiang_info: + "锁定技。当你受到伤害后,你与一名其他角色交换装备区里的所有牌。若你装备区里的牌因此减少,你摸等同于减少牌数的牌。", + jsrg_weiwenzhugezhi: "合卫温诸葛直", + jsrg_weiwenzhugezhi_prefix: "合", + jsrgfuhai: "浮海", + jsrgfuhai_info: + "出牌阶段限一次。你可以令所有有手牌的其他角色同时展示一张手牌,然后你选择一个方向并摸X张牌(X为该方向上的角色展示的点数连续严格递增或严格递减的牌数,至少为1)。", + jsrg_zhangxuan: "合张嫙", + jsrg_zhangxuan_prefix: "合", + jsrgtongli: "同礼", + jsrgtongli_info: + "当你于出牌阶段内使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内使用过的牌数相等,则你可以展示所有手牌,令此牌额外结算一次。", + jsrgshezang: "奢葬", + jsrgshezang_info: + "每轮限一次。当你或你回合内的其他角色进入濒死状态时,你可以亮出牌堆顶的四张牌,获得其中任意张花色各不相同的牌。", + jsrg_gaoxiang: "合高翔", + jsrg_gaoxiang_prefix: "合", + jsrgchiying: "驰应", + jsrgchiying_info: + "出牌阶段限一次。你可以选择一名角色,令其攻击范围内的其他角色依次弃置一张牌。若以此法弃置的基本牌数不大于其体力值,其获得这些基本牌。", + jsrg_guozhao: "合郭照", + jsrg_guozhao_prefix: "合", + jsrgpianchong: "偏宠", + jsrgpianchong_info: + "一名角色的结束阶段,若你于此回合内失去过牌,你可以判定。若结果为红色/黑色,你摸此回合进入弃牌堆的红色/黑色牌数量的牌。", + jsrgzunwei: "尊位", + jsrgzunwei_info: + "出牌阶段限一次。你可以选择一名其他角色并选择执行一项,然后移除该选项:1.将手牌数摸至与该角色相同(最多摸五张);2.将其装备牌移至你的装备区,直到你装备区的牌数不少于其;3.将体力值回复至与该角色相同。", - xumou_jsrg:'蓄谋', - xumou_jsrg_info:'“蓄谋”牌可在判定区内重复存在。判定阶段开始时,你选择一项:⒈使用此牌对应的实体牌,然后本阶段不能再使用此牌名的牌;⒉将所有的“蓄谋”牌置入弃牌堆。', + xumou_jsrg: "蓄谋", + xumou_jsrg_info: + "“蓄谋”牌可在判定区内重复存在。判定阶段开始时,你选择一项:⒈使用此牌对应的实体牌,然后本阶段不能再使用此牌名的牌;⒉将所有的“蓄谋”牌置入弃牌堆。", - jiangshanrugu_qi:'江山如故·起', - jiangshanrugu_cheng:'江山如故·承', - jiangshanrugu_zhuan:'江山如故·转', - jiangshanrugu_he:'江山如故·合', + jiangshanrugu_qi: "江山如故·起", + jiangshanrugu_cheng: "江山如故·承", + jiangshanrugu_zhuan: "江山如故·转", + jiangshanrugu_he: "江山如故·合", }, }; }); diff --git a/character/mobile.js b/character/mobile.js index e9735ab2a..eb8d7e132 100644 --- a/character/mobile.js +++ b/character/mobile.js @@ -1,5891 +1,7368 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'mobile', + name: "mobile", //connectBanned:['miheng'], - connect:true, - characterSort:{ - mobile:{ - mobile_default:['mb_sp_guanqiujian','mb_caomao','chengji','lizhaojiaobo','xin_huojun','muludawang','mb_chengui','mb_huban','mb_xianglang','yanxiang','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','yangfeng'], - 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"], - mobile_shenhua_huo:["re_pangtong","re_sp_zhugeliang","re_xunyu","re_dianwei","re_yanwen","xin_yuanshao"], - mobile_shenhua_lin:["re_dongzhuo","re_sunjian","re_zhurong"], - mobile_shenhua_shan:["re_liushan","re_dengai","re_jiangwei","re_caiwenji",'re_zhangzhang',"re_sunben"], - mobile_shenhua_yin:['xin_sunliang'], - mobile_shenhua_lei:["re_guanqiujian"], - mobile_yijiang1:["re_xusheng","re_lingtong","ol_yujin","re_wuguotai","re_gaoshun",'re_caozhi'], - mobile_yijiang2:["xin_liaohua","xin_caozhang","re_liubiao","re_handang","xin_chengpu","xin_gongsunzan","re_zhonghui","re_bulianshi"], - mobile_yijiang3:["re_liru","xin_jianyong","xin_zhuran","xin_guohuai","xin_panzhangmazhong","xin_fuhuanghou","re_yufan"], - mobile_yijiang4:["xin_zhoucang","xin_caifuren","xin_guyong","xin_sunluban","xin_caozhen","xin_jushou","xin_wuyi","xin_zhuhuan","re_chenqun"], - mobile_yijiang5:['xin_zhangyi','xin_sunxiu','xin_quancong','xin_zhuzhi','xin_caoxiu'], - mobile_yijiang67:["re_jikang"], - mobile_changshi:['scs_zhangrang','scs_zhaozhong','scs_sunzhang','scs_bilan','scs_xiayun','scs_hankui','scs_lisong','scs_duangui','scs_guosheng','scs_gaowang'], - mobile_sp:["old_yuanshu","re_wangyun","re_baosanniang","re_weiwenzhugezhi","re_zhanggong","re_xugong","re_heqi","liuzan","xin_hansui",'mb_sunluyu'], + connect: true, + characterSort: { + mobile: { + mobile_default: [ + "mb_sp_guanqiujian", + "mb_caomao", + "chengji", + "lizhaojiaobo", + "xin_huojun", + "muludawang", + "mb_chengui", + "mb_huban", + "mb_xianglang", + "yanxiang", + "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", + "yangfeng", + ], + 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"], + mobile_shenhua_huo: [ + "re_pangtong", + "re_sp_zhugeliang", + "re_xunyu", + "re_dianwei", + "re_yanwen", + "xin_yuanshao", + ], + mobile_shenhua_lin: ["re_dongzhuo", "re_sunjian", "re_zhurong"], + mobile_shenhua_shan: [ + "re_liushan", + "re_dengai", + "re_jiangwei", + "re_caiwenji", + "re_zhangzhang", + "re_sunben", + ], + mobile_shenhua_yin: ["xin_sunliang"], + mobile_shenhua_lei: ["re_guanqiujian"], + mobile_yijiang1: [ + "re_xusheng", + "re_lingtong", + "ol_yujin", + "re_wuguotai", + "re_gaoshun", + "re_caozhi", + ], + mobile_yijiang2: [ + "xin_liaohua", + "xin_caozhang", + "re_liubiao", + "re_handang", + "xin_chengpu", + "xin_gongsunzan", + "re_zhonghui", + "re_bulianshi", + ], + mobile_yijiang3: [ + "re_liru", + "xin_jianyong", + "xin_zhuran", + "xin_guohuai", + "xin_panzhangmazhong", + "xin_fuhuanghou", + "re_yufan", + ], + mobile_yijiang4: [ + "xin_zhoucang", + "xin_caifuren", + "xin_guyong", + "xin_sunluban", + "xin_caozhen", + "xin_jushou", + "xin_wuyi", + "xin_zhuhuan", + "re_chenqun", + ], + mobile_yijiang5: ["xin_zhangyi", "xin_sunxiu", "xin_quancong", "xin_zhuzhi", "xin_caoxiu"], + mobile_yijiang67: ["re_jikang"], + mobile_changshi: [ + "scs_zhangrang", + "scs_zhaozhong", + "scs_sunzhang", + "scs_bilan", + "scs_xiayun", + "scs_hankui", + "scs_lisong", + "scs_duangui", + "scs_guosheng", + "scs_gaowang", + ], + mobile_sp: [ + "old_yuanshu", + "re_wangyun", + "re_baosanniang", + "re_weiwenzhugezhi", + "re_zhanggong", + "re_xugong", + "re_heqi", + "liuzan", + "xin_hansui", + "mb_sunluyu", + ], }, }, - character:{ - mb_sp_guanqiujian:['male','wei',4,['mbcuizhen','mbkuili']], - mb_caomao:['male','wei',3,['mbqianlong','mbweitong'],['zhu']], - chengji:['male','wei',4,['mbkuangli','mbxiongsi']], - lizhaojiaobo:['male','wei',4,['mbzuoyou','mbshishou']], - yangfeng:['male','qun',4,['mbxuetu','mbweiming']], - xin_huojun:['male','shu',4,['sidai','jieyu'],['character:tw_huojun','die_audio:tw_huojun']], - muludawang:['male','qun','3/3/1',['shoufa','zhoulin','yuxiang']], - mb_chengui:['male','qun',3,['guimou','zhouxian']], - mb_huban:['male','wei',4,['mbyilie']], - mb_xianglang:['male','shu',3,['naxue','yijie']], - yanxiang:['male','qun',3,['kujian','twruilian'],['die_audio:tw_yanxiang']], - mb_sunluyu:['female','wu',3,['mbmeibu','mbmumu']], - xin_wuban:['male','shu',4,['xinjintao'],['clan:陈留吴氏','character:wuban']], - baoxin:['male','qun',4,['mutao','yimou'],['die_audio:tw_baoxin']], - jiangji:['male','wei',3,['twjichou','jilun'],['character:tw_jiangji','die_audio:tw_jiangji']], - liwei:['male','shu',4,['jiaohua'],['die_audio: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']], - xin_sunliang:['male','wu',3,['xinzhizheng','xinkuizhu','xinlijun'],['zhu']], - re_xiaoqiao:['female','wu',3,['retianxiang','xinhongyan']], - shichangshi:['male','qun',1,['mbdanggu','mbmowang'],['sex:male_castrated']], - re_zhangzhang:['male','wu',3,['rezhijian','guzheng']], - qianzhao:['male','wei',4,['mbshihe','mbzhenfu']], - re_yanwen:["male","qun",4,["reshuangxiong"]], - xin_zhoutai:['male','wu',4,['buqu','new_fenji']], - re_caozhi:['male','wei',3,['reluoying','rejiushi','chengzhang']], - yj_weiyan:['male','qun',5,['mbguli','mbaosi']], - re_chenqun:['male','wei',3,['redingpin','refaen']], - xin_caoxiu:['male','wei',4,['qianju','xinqingxi']], - xin_zhuhuan:['male','wu',4,['fenli','xinpingkou']], - sp_pengyang:['male','shu',3,['spdaming','spxiaoni']], - wangjun:['male','qun',4,['zhujian','duansuo']], - xin_zhuzhi:['male','wu',4,['sbanguo']], - xin_wuyi:['male','shu',4,['sbbenxi']], - yangfu:['male','wei',4,['jiebing','hannan']], - sp_caosong:['male','wei',3,['yijin','guanzong']], - re_liru:['male','qun',3,['rejuece','remieji','xinfencheng']], - re_dianwei:["male","wei",4,["reqiangxi"]], - xin_mamidi:['male','qun',3,['chengye','buxu']], - ruanhui:['female','wei',3,['mingcha','jingzhong']], - xin_quancong:['male','wu',4,['sbyaoming']], - re_xunyu:["male","wei",3,["quhu","rejieming"],['clan:颍川荀氏']], - xin_jushou:['male','qun','2/3/3',['xinjianying','shibei']], - re_bulianshi:['female','wu',3,['reanxu','zhuiyi']], - re_caiwenji:['female','qun',3,['rebeige','duanchang']], - sp_jianggan:['male','wei',3,['mbdaoshu','spdaizui']], - peixiu:['male','qun',3,['xingtu','juezhi']], - re_gaoshun:['male','qun',4,['rexianzhen','rejinjiu']], - re_wuguotai:['female','wu',3,['reganlu','buyi']], - xin_sunxiu:['male','wu',3,['mobileyanzhu','mobilexingxue','zhaofu'],['zhu']], - sp_maojie:['male','wei',3,['bingqing','yingfeng']], - yj_huangzhong:['male','qun',4,['spshidi','spyishi','spqishe']], - re_yufan:['male','wu',3,['zhiyan','rezongxuan']], - sunhanhua:['female','wu',3,['chongxu','miaojian','shhlianhua']], - yanpu:['male','qun',3,['huantu','bihuo']], - mayuanyi:['male','qun',4,['jibing','wangjing','moucuan']], - simafu:['male','wei',3,['xunde','chenjie']], - fuqian:['male','shu',4,['jueyong','poxiang']], - xin_caozhen:['male','wei',4,['discretesidi']], - xin_sunluban:['female','wu',3,['xinzenhui','xinjiaojin']], - qiaozhou:['male','shu',3,['zhiming','xingbu']], - xin_guyong:['male','wu',3,['xinshenxing','xinbingyi']], - re_zhonghui:['male','wei',4,['requanji','zili'],['clan:颍川钟氏']], - xin_caifuren:['female','qun',3,['xinqieting','xianzhou']], - xin_zhoucang:['male','shu',4,['mobilezhongyong']], - ol_yujin:['male','wei',4,['rejieyue']], - zhouqun:['male','shu',3,['tiansuan']], - re_zhurong:['female','shu',4,['juxiang','relieren']], - re_jiangwei:['male','shu',4,['retiaoxin','zhiji']], - nanhualaoxian:['male','qun',3,['yufeng','tianshu']], - re_handang:['male','wu',4,['regongji','jiefan']], - re_dengai:['male','wei',4,['retuntian','zaoxian']], - xin_fuhuanghou:['female','qun',3,['xinzhuikong','xinqiuyuan']], - xin_panzhangmazhong:['male','wu',4,['xinduodao','xinanjian']], - xin_guohuai:['male','wei',4,['mobilejingce']], - gongsunkang:['male','qun',4,['juliao','taomie']], - xin_zhangfei:['male','shu',4,['new_repaoxiao','liyong']], - xin_hansui:['male','qun','4/4/1',['xinniluan','xiaoxi_hansui']], - hucheer:['male','qun',4,['daoji']], - re_lingtong:['male','wu',4,['rexuanfeng']], - re_liubiao:['male','qun',3,['zishou','rezongshi']], - simashi:['male','wei',4,['baiyi','jinglve','shanli']], - yanghuiyu:['female','wei',3,['hongyi','requanfeng']], - xin_zhuran:['male','wu',4,['mobiledanshou']], - xin_gongsunzan:['male','qun',4,['xinyicong','qiaomeng']], - dingyuan:['male','qun',4,['beizhu']], - xin_jianyong:['male','shu',3,['xinqiaoshui','xinjyzongshi']], - xin_caozhang:['male','wei',4,['rejiangchi']], - xin_liaohua:['male','shu',4,['redangxian','refuli']], - furong:['male','shu',4,['xuewei','liechi']], - re_dongzhuo:['male','qun',8,['rejiuchi','roulin','benghuai','baonue'],['zhu']], - re_xusheng:['male','wu',4,['repojun']], - sp_sufei:['male','qun',4,['zhengjian','gaoyuan']], - yj_zhangliao:['male','qun',4,['weifeng']], - yj_zhanghe:['male','qun',4,['xinzhilve']], - yj_xuhuang:['male','qun',4,['xinxhzhiyan']], - yj_ganning:['male','qun',4,['gnjinfan','gnsheque']], - re_sunjian:['male','wu',4,['gzyinghun','repolu']], - zhengxuan:['male','qun',3,['zhengjing']], - dengzhi:['male','shu',3,['jimeng','shuaiyan']], - xin_chengpu:['male','wu',4,['relihuo','chunlao']], - yangyi:['male','shu',3,['duoduan','gongsun']], - dongcheng:['male','qun',4,['chengzhao']], - re_pangtong:['male','shu',3,['xinlianhuan','niepan']], - re_guanqiujian:['male','wei',4,['rezhengrong','rehongju']], - chendeng:['male','qun',3,['zhouxuan','fengji']], - re_heqi:['male','wu',4,['reqizhou','reshanxi']], - yangbiao:['male','qun',3,['zhaohan','rangjie','yizheng']], - re_sp_zhugeliang:["male","shu",3,["bazhen","rehuoji","rekanpo"]], - xin_xiahoudun:['male','wei',4,['reganglie','xinqingjian']], - zhangyì:['male','shu',4,['rezhiyi']], - jiakui:['male','wei',3,['zhongzuo','wanlan']], - re_jikang:["male","wei",3,["new_qingxian","new_juexiang"]], - miheng:['male','qun',3,['kuangcai','shejian']], - taoqian:['male','qun',3,['zhaohuo','yixiang','yirang']], - liuzan:['male','wu',4,['fenyin']], - lingcao:['male','wu',4,['dujin']], - sunru:['female','wu',3,['yingjian','shixin']], - lifeng:['male','shu',3,['tunchu','shuliang']], - zhuling:['male','wei',4,['xinzhanyi']], - liuye:['male','wei',3,['polu','choulve']], - zhaotongzhaoguang:["male","shu",4,["yizan_use","xinfu_longyuan"]], - majun:["male","wei",3,["xinfu_jingxie1","qiaosi"]], - simazhao:["male","wei",3,["xinfu_daigong","xinfu_zhaoxin"]], - wangyuanji:["female","wei",3,["xinfu_qianchong","xinfu_shangjian"]], - pangdegong:["male","qun",3,["xinfu_pingcai","xinfu_pdgyingshi"]], - old_yuanshu:['male','qun',4,['xinyongsi','yjixi']], + character: { + mb_sp_guanqiujian: ["male", "wei", 4, ["mbcuizhen", "mbkuili"]], + mb_caomao: ["male", "wei", 3, ["mbqianlong", "mbweitong"], ["zhu"]], + chengji: ["male", "wei", 4, ["mbkuangli", "mbxiongsi"]], + lizhaojiaobo: ["male", "wei", 4, ["mbzuoyou", "mbshishou"]], + yangfeng: ["male", "qun", 4, ["mbxuetu", "mbweiming"]], + xin_huojun: [ + "male", + "shu", + 4, + ["sidai", "jieyu"], + ["character:tw_huojun", "die_audio:tw_huojun"], + ], + muludawang: ["male", "qun", "3/3/1", ["shoufa", "zhoulin", "yuxiang"]], + mb_chengui: ["male", "qun", 3, ["guimou", "zhouxian"]], + mb_huban: ["male", "wei", 4, ["mbyilie"]], + mb_xianglang: ["male", "shu", 3, ["naxue", "yijie"]], + yanxiang: ["male", "qun", 3, ["kujian", "twruilian"], ["die_audio:tw_yanxiang"]], + mb_sunluyu: ["female", "wu", 3, ["mbmeibu", "mbmumu"]], + xin_wuban: ["male", "shu", 4, ["xinjintao"], ["clan:陈留吴氏", "character:wuban"]], + baoxin: ["male", "qun", 4, ["mutao", "yimou"], ["die_audio:tw_baoxin"]], + jiangji: [ + "male", + "wei", + 3, + ["twjichou", "jilun"], + ["character:tw_jiangji", "die_audio:tw_jiangji"], + ], + liwei: ["male", "shu", 4, ["jiaohua"], ["die_audio: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"]], + xin_sunliang: ["male", "wu", 3, ["xinzhizheng", "xinkuizhu", "xinlijun"], ["zhu"]], + re_xiaoqiao: ["female", "wu", 3, ["retianxiang", "xinhongyan"]], + shichangshi: ["male", "qun", 1, ["mbdanggu", "mbmowang"], ["sex:male_castrated"]], + re_zhangzhang: ["male", "wu", 3, ["rezhijian", "guzheng"]], + qianzhao: ["male", "wei", 4, ["mbshihe", "mbzhenfu"]], + re_yanwen: ["male", "qun", 4, ["reshuangxiong"]], + xin_zhoutai: ["male", "wu", 4, ["buqu", "new_fenji"]], + re_caozhi: ["male", "wei", 3, ["reluoying", "rejiushi", "chengzhang"]], + yj_weiyan: ["male", "qun", 5, ["mbguli", "mbaosi"]], + re_chenqun: ["male", "wei", 3, ["redingpin", "refaen"]], + xin_caoxiu: ["male", "wei", 4, ["qianju", "xinqingxi"]], + xin_zhuhuan: ["male", "wu", 4, ["fenli", "xinpingkou"]], + sp_pengyang: ["male", "shu", 3, ["spdaming", "spxiaoni"]], + wangjun: ["male", "qun", 4, ["zhujian", "duansuo"]], + xin_zhuzhi: ["male", "wu", 4, ["sbanguo"]], + xin_wuyi: ["male", "shu", 4, ["sbbenxi"]], + yangfu: ["male", "wei", 4, ["jiebing", "hannan"]], + sp_caosong: ["male", "wei", 3, ["yijin", "guanzong"]], + re_liru: ["male", "qun", 3, ["rejuece", "remieji", "xinfencheng"]], + re_dianwei: ["male", "wei", 4, ["reqiangxi"]], + xin_mamidi: ["male", "qun", 3, ["chengye", "buxu"]], + ruanhui: ["female", "wei", 3, ["mingcha", "jingzhong"]], + xin_quancong: ["male", "wu", 4, ["sbyaoming"]], + re_xunyu: ["male", "wei", 3, ["quhu", "rejieming"], ["clan:颍川荀氏"]], + xin_jushou: ["male", "qun", "2/3/3", ["xinjianying", "shibei"]], + re_bulianshi: ["female", "wu", 3, ["reanxu", "zhuiyi"]], + re_caiwenji: ["female", "qun", 3, ["rebeige", "duanchang"]], + sp_jianggan: ["male", "wei", 3, ["mbdaoshu", "spdaizui"]], + peixiu: ["male", "qun", 3, ["xingtu", "juezhi"]], + re_gaoshun: ["male", "qun", 4, ["rexianzhen", "rejinjiu"]], + re_wuguotai: ["female", "wu", 3, ["reganlu", "buyi"]], + xin_sunxiu: ["male", "wu", 3, ["mobileyanzhu", "mobilexingxue", "zhaofu"], ["zhu"]], + sp_maojie: ["male", "wei", 3, ["bingqing", "yingfeng"]], + yj_huangzhong: ["male", "qun", 4, ["spshidi", "spyishi", "spqishe"]], + re_yufan: ["male", "wu", 3, ["zhiyan", "rezongxuan"]], + sunhanhua: ["female", "wu", 3, ["chongxu", "miaojian", "shhlianhua"]], + yanpu: ["male", "qun", 3, ["huantu", "bihuo"]], + mayuanyi: ["male", "qun", 4, ["jibing", "wangjing", "moucuan"]], + simafu: ["male", "wei", 3, ["xunde", "chenjie"]], + fuqian: ["male", "shu", 4, ["jueyong", "poxiang"]], + xin_caozhen: ["male", "wei", 4, ["discretesidi"]], + xin_sunluban: ["female", "wu", 3, ["xinzenhui", "xinjiaojin"]], + qiaozhou: ["male", "shu", 3, ["zhiming", "xingbu"]], + xin_guyong: ["male", "wu", 3, ["xinshenxing", "xinbingyi"]], + re_zhonghui: ["male", "wei", 4, ["requanji", "zili"], ["clan:颍川钟氏"]], + xin_caifuren: ["female", "qun", 3, ["xinqieting", "xianzhou"]], + xin_zhoucang: ["male", "shu", 4, ["mobilezhongyong"]], + ol_yujin: ["male", "wei", 4, ["rejieyue"]], + zhouqun: ["male", "shu", 3, ["tiansuan"]], + re_zhurong: ["female", "shu", 4, ["juxiang", "relieren"]], + re_jiangwei: ["male", "shu", 4, ["retiaoxin", "zhiji"]], + nanhualaoxian: ["male", "qun", 3, ["yufeng", "tianshu"]], + re_handang: ["male", "wu", 4, ["regongji", "jiefan"]], + re_dengai: ["male", "wei", 4, ["retuntian", "zaoxian"]], + xin_fuhuanghou: ["female", "qun", 3, ["xinzhuikong", "xinqiuyuan"]], + xin_panzhangmazhong: ["male", "wu", 4, ["xinduodao", "xinanjian"]], + xin_guohuai: ["male", "wei", 4, ["mobilejingce"]], + gongsunkang: ["male", "qun", 4, ["juliao", "taomie"]], + xin_zhangfei: ["male", "shu", 4, ["new_repaoxiao", "liyong"]], + xin_hansui: ["male", "qun", "4/4/1", ["xinniluan", "xiaoxi_hansui"]], + hucheer: ["male", "qun", 4, ["daoji"]], + re_lingtong: ["male", "wu", 4, ["rexuanfeng"]], + re_liubiao: ["male", "qun", 3, ["zishou", "rezongshi"]], + simashi: ["male", "wei", 4, ["baiyi", "jinglve", "shanli"]], + yanghuiyu: ["female", "wei", 3, ["hongyi", "requanfeng"]], + xin_zhuran: ["male", "wu", 4, ["mobiledanshou"]], + xin_gongsunzan: ["male", "qun", 4, ["xinyicong", "qiaomeng"]], + dingyuan: ["male", "qun", 4, ["beizhu"]], + xin_jianyong: ["male", "shu", 3, ["xinqiaoshui", "xinjyzongshi"]], + xin_caozhang: ["male", "wei", 4, ["rejiangchi"]], + xin_liaohua: ["male", "shu", 4, ["redangxian", "refuli"]], + furong: ["male", "shu", 4, ["xuewei", "liechi"]], + re_dongzhuo: ["male", "qun", 8, ["rejiuchi", "roulin", "benghuai", "baonue"], ["zhu"]], + re_xusheng: ["male", "wu", 4, ["repojun"]], + sp_sufei: ["male", "qun", 4, ["zhengjian", "gaoyuan"]], + yj_zhangliao: ["male", "qun", 4, ["weifeng"]], + yj_zhanghe: ["male", "qun", 4, ["xinzhilve"]], + yj_xuhuang: ["male", "qun", 4, ["xinxhzhiyan"]], + yj_ganning: ["male", "qun", 4, ["gnjinfan", "gnsheque"]], + re_sunjian: ["male", "wu", 4, ["gzyinghun", "repolu"]], + zhengxuan: ["male", "qun", 3, ["zhengjing"]], + dengzhi: ["male", "shu", 3, ["jimeng", "shuaiyan"]], + xin_chengpu: ["male", "wu", 4, ["relihuo", "chunlao"]], + yangyi: ["male", "shu", 3, ["duoduan", "gongsun"]], + dongcheng: ["male", "qun", 4, ["chengzhao"]], + re_pangtong: ["male", "shu", 3, ["xinlianhuan", "niepan"]], + re_guanqiujian: ["male", "wei", 4, ["rezhengrong", "rehongju"]], + chendeng: ["male", "qun", 3, ["zhouxuan", "fengji"]], + re_heqi: ["male", "wu", 4, ["reqizhou", "reshanxi"]], + yangbiao: ["male", "qun", 3, ["zhaohan", "rangjie", "yizheng"]], + re_sp_zhugeliang: ["male", "shu", 3, ["bazhen", "rehuoji", "rekanpo"]], + xin_xiahoudun: ["male", "wei", 4, ["reganglie", "xinqingjian"]], + zhangyì: ["male", "shu", 4, ["rezhiyi"]], + jiakui: ["male", "wei", 3, ["zhongzuo", "wanlan"]], + re_jikang: ["male", "wei", 3, ["new_qingxian", "new_juexiang"]], + miheng: ["male", "qun", 3, ["kuangcai", "shejian"]], + taoqian: ["male", "qun", 3, ["zhaohuo", "yixiang", "yirang"]], + liuzan: ["male", "wu", 4, ["fenyin"]], + lingcao: ["male", "wu", 4, ["dujin"]], + sunru: ["female", "wu", 3, ["yingjian", "shixin"]], + lifeng: ["male", "shu", 3, ["tunchu", "shuliang"]], + zhuling: ["male", "wei", 4, ["xinzhanyi"]], + liuye: ["male", "wei", 3, ["polu", "choulve"]], + zhaotongzhaoguang: ["male", "shu", 4, ["yizan_use", "xinfu_longyuan"]], + majun: ["male", "wei", 3, ["xinfu_jingxie1", "qiaosi"]], + simazhao: ["male", "wei", 3, ["xinfu_daigong", "xinfu_zhaoxin"]], + wangyuanji: ["female", "wei", 3, ["xinfu_qianchong", "xinfu_shangjian"]], + pangdegong: ["male", "qun", 3, ["xinfu_pingcai", "xinfu_pdgyingshi"]], + old_yuanshu: ["male", "qun", 4, ["xinyongsi", "yjixi"]], - shenpei:["male","qun","2/3",["shouye","liezhi"]], - re_wangyun:['male','qun',3,['relianji','remoucheng'],['clan:太原王氏']], + shenpei: ["male", "qun", "2/3", ["shouye", "liezhi"]], + re_wangyun: ["male", "qun", 3, ["relianji", "remoucheng"], ["clan:太原王氏"]], - re_baosanniang:['female','shu',3,['meiyong','rexushen','rezhennan']], + re_baosanniang: ["female", "shu", 3, ["meiyong", "rexushen", "rezhennan"]], - hujinding:['female','shu','2/6',['renshi','wuyuan','huaizi']], + hujinding: ["female", "shu", "2/6", ["renshi", "wuyuan", "huaizi"]], - re_zhanggong:['male','wei',3,['reqianxin','rezhenxing']], - re_xugong:['male','qun',3,['rebiaozhao','yechou'],['doublegroup:wu:qun']], - re_weiwenzhugezhi:['male','wu',4,['refuhai']], + re_zhanggong: ["male", "wei", 3, ["reqianxin", "rezhenxing"]], + re_xugong: ["male", "qun", 3, ["rebiaozhao", "yechou"], ["doublegroup:wu:qun"]], + re_weiwenzhugezhi: ["male", "wu", 4, ["refuhai"]], - xin_yuanshao:['male','qun',4,['reluanji','xueyi'],['zhu']], - re_liushan:['male','shu',3,['xiangle','refangquan','ruoyu'],['zhu']], - re_sunben:['male','wu',4,['jiang','rehunzi','zhiba'],['zhu']], + xin_yuanshao: ["male", "qun", 4, ["reluanji", "xueyi"], ["zhu"]], + re_liushan: ["male", "shu", 3, ["xiangle", "refangquan", "ruoyu"], ["zhu"]], + re_sunben: ["male", "wu", 4, ["jiang", "rehunzi", "zhiba"], ["zhu"]], - scs_zhangrang:['male','qun','',['scstaoluan'],['unseen','sex:male_castrated']], - scs_zhaozhong:['male','qun','',['scschiyan'],['unseen','sex:male_castrated']], - scs_sunzhang:['male','qun','',['scszimou'],['unseen','sex:male_castrated']], - scs_bilan:['male','qun','',['scspicai'],['unseen','sex:male_castrated']], - scs_xiayun:['male','qun','',['scsyaozhuo'],['unseen','sex:male_castrated']], - scs_hankui:['male','qun','',['scsxiaolu'],['unseen','sex:male_castrated']], - scs_lisong:['male','qun','',['scskuiji'],['unseen','sex:male_castrated']], - scs_duangui:['male','qun','',['scschihe'],['unseen','sex:male_castrated']], - scs_guosheng:['male','qun','',['scsniqu'],['unseen','sex:male_castrated']], - scs_gaowang:['male','qun','',['scsmiaoyu'],['unseen','sex:male_castrated']], + scs_zhangrang: ["male", "qun", "", ["scstaoluan"], ["unseen", "sex:male_castrated"]], + scs_zhaozhong: ["male", "qun", "", ["scschiyan"], ["unseen", "sex:male_castrated"]], + scs_sunzhang: ["male", "qun", "", ["scszimou"], ["unseen", "sex:male_castrated"]], + scs_bilan: ["male", "qun", "", ["scspicai"], ["unseen", "sex:male_castrated"]], + scs_xiayun: ["male", "qun", "", ["scsyaozhuo"], ["unseen", "sex:male_castrated"]], + scs_hankui: ["male", "qun", "", ["scsxiaolu"], ["unseen", "sex:male_castrated"]], + scs_lisong: ["male", "qun", "", ["scskuiji"], ["unseen", "sex:male_castrated"]], + scs_duangui: ["male", "qun", "", ["scschihe"], ["unseen", "sex:male_castrated"]], + scs_guosheng: ["male", "qun", "", ["scsniqu"], ["unseen", "sex:male_castrated"]], + scs_gaowang: ["male", "qun", "", ["scsmiaoyu"], ["unseen", "sex:male_castrated"]], }, - characterIntro:{ - lizhaojiaobo:'李昭(?—约公元260年),三国时期曹魏官吏,官拜冗从仆射,为魏帝曹髦的亲信。
              焦伯,三国时期人物,魏帝曹髦护卫,官拜黄门从官。
              曹髦见自己权力威势日渐削弱,感到不胜忿恨,于公元260年(甘露五年)五月初六夜里,令李昭和焦伯等在陵云台布署甲士,出讨司马昭,但最终失败,曹髦为成济所弑,李昭和焦伯等应该也战死。在《三国演义》里,焦伯挺枪出战成济,亦被成济所杀。', - chengji:'成济(?~260年6月21日),三国时期曹魏官员。官至太子舍人。在魏帝曹髦起兵讨司马昭时,受到司马昭之心腹贾充指使,刺死曹髦。司马昭为平息众怒,将成倅、成济兄弟二人杀死。', - yangfeng:'杨奉(?-197年/198年),东汉末年将领。杨奉早年参加白波军起义,曾经帮助李傕对抗郭汜,后来背叛李傕。兴平二年,加号兴义将军,护送汉献帝刘协东归雒阳,颇有功勋,加号车骑将军,屯兵于梁县。建安元年,随着汉献帝迁都许县,失去权力,先后依附于袁术、吕布,劫掠徐州和扬州地区。建安二年(一说三年),带兵进犯刘备领地,被刘备诱杀。', - muludawang:'古典小说《三国演义》中的虚构人物,八纳洞主,孟获盟友。擅驱兽法,能行风雨,控制猛兽并指挥它们作战。在法术帮助下最初对蜀军取得一些胜利,但在诸葛亮的喷火木兽将他的动物吓跑后战败,最后死于乱军之中。', - laimin:'来敏(165年—261年),字敬达,义阳新野人,东汉太中大夫来歙之后,司空来艳之子,三国时期蜀汉官员。东汉末年,逢董卓之乱,来敏跟随姐夫黄琬到荆州避难,黄琬是刘璋祖母的侄子,来敏又与姐姐来氏入蜀,被刘璋引为宾客。来敏喜欢读书,尤其喜欢《左氏春秋》。刘备平定益州后,以来敏为典学校尉,后立太子,来敏为家令。刘禅继位后,任命来敏为虎贲中郎将,诸葛亮驻汉中,请来敏为军祭酒、辅军将军。却因其口出狂言而被罢官,诸葛亮死后,来敏历任大长秋、光禄大夫、执慎将军等职,期间多次因说错话而被免官,蜀汉景耀年间,来敏去世,时年九十七岁。', - shichangshi:'十常侍,指中国东汉(公元25年—220年)灵帝时期(168年-189年)操纵政权的十二个宦官:张让、赵忠、夏恽、郭胜、孙璋、毕岚、栗嵩、段珪、高望、张恭、韩悝、宋典(在小说《三国演义》里,十常侍指的是指张让、赵忠、封谞、段珪、曹节、侯览、蹇硕、程旷、夏恽、郭胜十人),他们都任职中常侍。玩弄小皇帝于股掌之中,以至灵帝称“张常侍是我父,赵常侍是我母”。十常侍自己横征暴敛,卖官鬻爵,他们的父兄子弟遍布天下,横行乡里,祸害百姓,无官敢管。人民不堪剥削、压迫,纷纷起来反抗。当时一些比较清醒的官吏,已看出宦官集团的黑暗腐败,导致大规模农民起义的形势。郎中张钧在给皇帝的奏章中明确指出,黄巾起义是外戚宦官专权逼出来的,他说:“张角所以能兴兵作乱,万人所以乐附之者,其源皆由十常侍多放父兄、子弟、婚宗、宾客典据州郡,辜确财利,侵略百姓,百姓之怨无所告诉,故谋议不轨,聚为‘盗贼’。”后被曹操、袁绍所歼。', - sunzhang:'孙璋(?-189年?)东汉末期汉灵帝的宦官,官居中常侍,为十常侍之一,在张让、赵忠之下位居第三。光熹元年(189年),张让、赵忠、段珪等诛杀何进,袁绍率军入宫,诛杀孙璋。', - bilan:'毕岚(?—189),东汉宦官,十常侍之一。十常侍朋比为奸,祸乱朝纲,制造出党锢之祸,后被袁绍诛杀。另外,毕岚曾制造翻车,用于取河水洒路。', - xiayun:'夏恽(?—189),东汉宦官,十常侍之一。后被袁绍、曹操诛于翠花楼前。', - hankui:'韩悝(?—189),东汉宦官,十常侍之一。后被袁绍所诛。', - lisong:'栗嵩,东汉宦官,十常侍之一,与张让等人均一同任职中常侍。', - duangui:'段珪(?—189),东汉宦官,十常侍之一。段珪与张让、赵忠等人朋比为奸,党同伐异,横征暴敛,卖官鬻爵,引起了以何进为首的外戚集团的不满。何进谋诛宦官,却不纳曹操、陈琳之谏,多结外镇军阀,翘首京师,与袁绍等谋诛宦竖。终于事泄,被宦官集团查知。张让、段珪等人先下手为强,斩杀何进于嘉德殿前,却也引起了京师的变乱。袁绍等人趁机带兵冲入皇宫,大肆诛杀太监。洛阳卫军变乱后,段珪与张让等人劫持少帝刘辩、陈留王刘协出逃,后被杀。', - guosheng:'郭胜,南阳宛(今河南南阳)人。汉灵帝时为中常侍,与张让、赵忠等狼狈为奸,并皆封侯。曾助同乡何进、何太后贵幸。后被袁绍等人率兵诛灭。', - gaowang:'高望(?~189年),京兆人,东汉宦官,十常侍之一,为小黄门兼任尚药监,颇得皇子刘辩的信任。中平六年(189年),张让等人杀害大将军何进,袁绍与王匡等人率兵杀入雒阳端门,在承明堂上斩杀中常侍高望。', - qianzhao:'牵招(?—231年),字子经,安平郡观津县(今河北省武邑县)人。三国时期曹魏名将。牵招早年师从乐隐,与刘备成为刎颈之交。投靠冀州牧袁绍,担任冀州从事,统领乌丸突骑。袁绍死后,跟随冀州刺史袁尚,受到并州牧高干加害,投奔丞相曹操,授军谋掾。从平乌丸,出任护乌丸校尉。举茂才出身,从平汉中,授中护军。拜平虏校尉,平定东莱郡叛乱。魏文帝曹丕时期,授护鲜卑校尉,驻扎昌平,迁右中郎将、雁门太守,遏制鲜卑轲比能发展壮大。魏明帝即位,赐爵关内侯,营救护乌丸校尉田豫。太和五年,去世。', - fuqian:'傅佥(?~263年),义阳(治今湖北省枣阳市)人,蜀汉将领傅彤之子,三国时期蜀汉名将。金长于谋略,并颇有胆勇,姜维甚爱之。傅佥官至关中都督。魏国攻伐蜀汉时,傅佥和蒋舒防守阳安关,兵败战死。', - wangjun:'王濬(207年~286年),字士治,小名阿童,弘农郡湖县(今河南省灵宝市阌乡)人。西晋时期名将。王濬出身世家,博学多闻,容颜英俊,多谋善战。举秀才出身,起家河东郡从事。泰始八年(272年),担任广汉太守,平定益州叛乱,迁益州刺史。利用长江上游地势之利,修造战船,组建强大的水军。上书晋武帝,促成晋灭吴之战。咸宁六年(280年),率兵顺流而下,熔毁横江铁链,攻克丹阳郡,率先攻取石头城,接受吴末帝孙皓投降,完成西晋统一大业。凭借功勋,拜辅国将军、步兵校尉,册封襄阳侯。为避猜忌,纵情享受,累迁特进、抚军大将军、开府仪同三司、散骑常侍、后军将军等。太康六年十二月(286年1月18日),王濬去世,享年八十岁,谥号为“武”,安葬于柏谷山。', - yangfu:'杨阜(172年—244年),字义山,汉天水冀县(今甘谷县东南)人。三国时期曹魏名臣。汉献帝建安初年,任凉州从事,旋拜安定长史;韦康任刺史后辟为别驾,改任州参军;后因讨马超有功,赐爵关内侯。曹操征汉中时,杨阜担任益州刺史,回来后又担任武都太守。魏明帝时,由将作大匠改少府。杨阜不但卓识远见,而且刚正不阿,敢于直言,对朝廷弊政多有诤谏,六次进言谏魏明帝应勤政爱民,魏明帝对他颇有敬畏之心。杨阜勤政廉洁,在宫内担任少府时,专管宝器、珍膳、衣物等,而他死后则家无馀财。皇帝让杨阜的孙子杨豹继任了少府之职。原甘谷县文昌宫西侧有杨氏家祠,内悬“两代尚书”匾额。', - ruanhui:'阮氏女,是指三国时期曹魏名士许允之妻阮氏,陈留尉氏人。阮氏女是中国古代四大丑女之一,貌丑而见识非凡。她出身士族之家,是卫尉阮共(字伯彦)之女、阮侃(字德如)之妹。嫁与许允后生有二子:许奇,官至司隶校尉;许猛,官至幽州刺史。', - peixiu:'裴秀(224年-271年4月3日),字季彦。河东郡闻喜县(今山西省闻喜县)人。[1]魏晋时期名臣、地图学家,东汉尚书令裴茂之孙、曹魏光禄大夫裴潜之子。出身河东裴氏,少年时便颇有名气,后被大将军曹爽辟为掾属,袭爵清阳亭侯,又迁黄门侍郎。高平陵之变后,因是曹爽的故吏而被罢免。此后历任廷尉正、安东将军及卫将军司马,参与谋划军国之政,参与平定诸葛诞叛乱。因功转任尚书,进封鲁阳乡侯。魏元帝继位后,进爵鲁阳县侯,任尚书仆射。咸熙元年(264年),受命负责修改官制,又提议恢复五等爵制。五等制恢复后,获封济川侯。他建议立司马炎为世子,司马炎继位晋王后,拜裴秀为尚书令、右光禄大夫。西晋建立后,加左光禄大夫,封钜鹿郡公。泰始三年(267年),升任司空。泰始七年(271年),裴秀因服食寒食散后饮冷酒而逝世,年四十八,谥号“元”。有文集三卷。裴秀作《禹贡地域图》,开创了中国古代地图绘制学。李约瑟称他为“中国科学制图学之父”,与古希腊著名地图学家托勒密齐名,是世界古代地图学史上东西辉映的两颗灿烂明星。为纪念这位中国地图科学创始人而设立的“裴秀奖”,每两年评选一次,是中国地图学界最高奖项。由于他的贡献突出,联合国天文组织将月球正面的一个环形山命名为“裴秀环形山”,', - liucheng:'游卡桌游的原创人物。设定为黄忠的妻子。', - jiangwan:'蒋琬(?-246年),字公琰。零陵郡湘乡县人。三国时期蜀汉政治家,与诸葛亮、董允、费祎合称“蜀汉四相”。蒋琬最初随刘备入蜀,为广都县长。因其不理政事,惹怒刘备,在诸葛亮的劝说下才免于一死。后重获启用,受到诸葛亮的悉心培养,累官丞相长史兼抚军将军。建兴十二年(234年),诸葛亮去世,蒋琬继其执政,拜尚书令,又加行都护、假节,领益州刺史,再迁大将军,录尚书事,封安阳亭侯。延熙元年(238年),受命开府,加大司马,总揽蜀汉军政。曾制定由水路进攻曹魏的计划,但未被采纳。延熙九年(246年),蒋琬病逝,谥号为恭。', - sunhanhua:'孙寒华,三国时女仙。梁·陶弘景《真诰》卷一三、五代·杜光庭《墉城集仙录》卷七:其父孙贲为孙权堂兄,寒华少时与杜契有私情,后从杜契受玄白之要,颜容日少。周旋吴越诸山十馀年,得道仙去。《鉴后集》卷四:一云即吴大帝孙权之女。于茅山修道,道成,冲虚而去,因号其山为华姥山。山在茅山崇禧观前。《神异典》卷二五九人于明代,误。', - yanpu:'阎圃,生卒年不详,是益州巴西安汉(今四川省南充市)人。张鲁割据巴、汉,就以阎圃为功曹。东汉末年人物,本为张鲁部下谋士,后随张鲁一同投降曹操,封平乐乡侯。', - mayuanyi:'马元义(?—184年6月7日),东汉末年黄巾之乱的组织者之一,是黄巾大方首领。光和六年(183年),马元义奉黄巾军首领张角之命,筹划起事的准备工作。马元义聚集荆州、扬州信徒数万人约定于邺城相会,并收买中常侍封谞、徐奉等为内应,准备于次年(甲子年)三月初五(戊申日)内外同时起事。由于张角弟子济南人唐周的告密,马元义于于中平元年(184年)正月在河内郡山阳县被捕,送往洛阳车裂,同时被杀的还有教众近千人。由于马元义的被杀,迫使张角提前于二月起兵发动叛乱。', - simafu:'司马孚(180年-272年4月3日),字叔达。河内郡温县(今河南温县)人。三国曹魏至西晋初年重臣,西晋宗室,东汉京兆尹司马防第三子,晋宣帝司马懿之弟。自曹操时代起,司马孚就任文学掾,而后历仕魏国五代皇帝,累迁至太傅。司马孚在“高平陵事变”之际,协助司马懿控制京师,诛杀曹爽一党。后又督军成功防御吴、蜀的进攻,为司马氏政权的稳固多有功劳。但他性格十分谨慎,自司马懿执掌大权起,便逐渐引退,更未直接参与司马氏废立魏帝的谋划。西晋代魏后,司马孚进拜太宰,封安平王。晋武帝司马炎对他十分尊宠,但他并不以此为荣,至死仍以魏臣自称。泰始八年二月壬辰日(272年4月3日),司马孚去世,年九十三。武帝为其举哀三日,葬礼规格比照东汉东平献王刘苍,赐谥献王。', - sunchen:'孙綝(231年-259年1月18日),字子通,吴郡富春(今浙江杭州市富阳区)人。三国时期吴国宗室、权臣,昭义中郎将孙静曾孙、定武中郎将孙暠之孙、安民都尉孙绰的儿子。门荫入仕,初任偏将军。太平元年(256年),升任侍中、武卫将军、都督中外诸军事。掌权以后,诛杀大司马滕胤、骠骑将军吕据等重臣,升任大将军,册封永宁县侯。嗜好杀戮,与皇帝孙亮的矛盾激化,最终废黜孙亮,拥立琅琊王孙休即位,累迁丞相、荆州牧。永安元年十二月(259年1月),在左将军张布的协助下,遭到皇帝孙休捕杀,时年二十八岁,削除宗籍,改姓故氏。', - qiaozhou:'谯周(201年-270年),字允南,巴西郡西充国县(今四川西充县槐树镇)人。三国时期蜀汉大臣、学者、儒学家、史学家。幼年丧父,少读典籍,精研六经,颇晓天文,成为蜀地大儒之一,门下有陈寿、罗宪等学生。诸葛亮担任益州牧时,授劝学从事。诸葛亮死后,不顾朝令,前往奔丧。后主刘禅册立太子时,授太子仆,迁太子家令、光禄大夫。反对姜维北伐,著《仇国论》,力陈北伐之失。炎兴元年(263年),邓艾攻打成都时期,力劝刘禅投降,“有全国之功”,投降魏国后,受封阳城亭侯,迁骑都尉。泰始六年(270年),授散骑常侍,同年去世,时年七十岁。', - gongsunkang:'公孙康(生卒年不详),辽东襄平(今辽宁辽阳)人。东汉末年辽东地区割据军阀,辽东太守公孙度长子(一作庶子)、车骑将军公孙恭之兄。公孙康在其父死后继任辽东太守。建安十二年(207年),擒斩图谋不轨的袁尚、袁熙兄弟,将其首级献予曹操,被拜为左将军,封襄平侯。建安十四年(209年),公孙康大破高句丽,陷其国都,并讨伐韩濊,设置带方郡。死后因二子年幼,由公孙恭继任。曹丕称帝后,被追赠为大司马。', - zhouqun:'周群(生卒年不详),字仲直,巴西阆中(今四川阆中)人。周群年少时随父周舒学习占验天算之术。后来刘璋聘请周群为师友从事,其预言大多得以应验。刘备割据益州,任命周群为儒林校尉。曾劝说刘备攻汉中必定不利,事后得到应验,被举荐为茂才。', - dongzhao:'董昭(156年-236年7月4日),字公仁,济阴定陶(今山东省菏泽市定陶区)人。东汉末年曹魏谋士、重臣、开国元勋。董昭年轻时被举为孝廉,后担任袁绍帐下参军。多有战功,但是袁绍听信谗言,董昭不得已离开袁绍投奔张杨。张杨率军迎接汉献帝时,董昭随行,并拜为议郎。后与曹操在洛阳相见,又建议曹操将汉献帝迎接到许昌。董昭自此成为曹操的谋士。建安年间(198年)历任河南尹、冀州牧、徐州牧、魏郡太守等职,多有功劳,深受曹操器重。曹操受封魏公、魏王的谋划都是出自董昭之手。曹丕继魏王位后,董昭任将作大匠。曹丕称帝后,升任大鸿胪。此后先后担任侍中、太常、光禄大夫、太仆等重要职位。魏明帝曹叡即位后转任卫尉。太和六年(232年)升任司徒。青龙四年(236年)卒,时年八十一,谥曰定。', - nanhualaoxian:'南华老仙,是古典小说《三国演义》中的虚拟人物。其原型来自道教典籍中对庄子的封号,又称“南华仙人”、“南华真人”等。在古典小说《三国演义》通行本的第一回中,描述了南华老仙将《太平要术》赠送给张角的情节。', - chenzhen:'陈震(?—公元235年),字孝起。荆州南阳郡(今河南南阳)人。三国时期蜀汉官员。刘备领荆州牧时,辟陈震为从事。后随刘备入蜀,为蜀郡北部都尉、汶山太守、犍为太守。建兴三年(225年),拜尚书,迁尚书令。建兴七年(229年),孙权称帝。蜀汉以陈震为卫尉,前往祝贺,与孙权开坛歃盟,交分天下。还蜀,封城阳亭侯。建兴十三年(235年),卒。', - nanhualaoxian:'南华老仙,其原型来自道教典籍中对庄子的封号,又称“南华仙人”、“南华真人”等。在古典小说《三国演义》通行本的第一回中,描述了南华老仙将《太平要术》赠送给张角的情节。', - hucheer:'胡车儿(生卒年不详),东汉末年武将,初从张绣,为其心腹猛将,勇冠三军,与贾诩交情甚佳。宛城大战后,张绣投降曹操,曹操爱胡车儿之骁勇,手以黄金与之。后因曹操私纳张绣亡叔张济的遗孀邹氏,张绣深感其辱,欲杀曹操,与贾诩商议后决心反曹。《三国演义》中,作者考虑到典韦的勇猛,便增加了令胡车儿盗走典韦的双戟的情节。最终典韦、曹昂(曹操长子)、曹安民(曹操侄子)皆死于此次战斗。野史说胡车儿跟随曹操征战,被赵云在长坂坡上红枪挑死。', - simashi:'司马师(208年~255年3月23日),字子元,河内温县(今河南省温县)人。三国时期曹魏权臣,西晋王朝的奠基人之一,晋宣帝司马懿与宣穆皇后张春华的长子,晋文帝司马昭的同母兄,晋武帝司马炎的伯父。司马师沉着坚强,雄才大略,早年与夏侯玄、何晏齐名。高平陵政变后,以功封长平乡侯,旋加卫将军。司马懿死后,以抚军大将军辅政,独揽朝廷大权,次年升为大将军。掌权后,他制定选拔官吏的法规,命百官推荐贤才,整顿纲纪,使其各有职掌,朝野肃然。司马师也有卓越的军事才能,曾用计于新城之战击溃吴国诸葛恪的大军。嘉平六年(254年),魏帝曹芳与中书令李丰等人密谋除司马师,事情泄露,司马师杀死参与者,迫郭太后废曹芳,改立高贵乡公曹髦为帝。次年,亲自率兵平定毌丘俭、文钦之乱。回师途中病死,时年四十八岁,谥号“忠武”。后被追尊为晋景王。西晋建立后,被追尊为景皇帝,庙号世宗。', - yanghuiyu:'羊徽瑜(214年-278年),泰山南城(今山东新泰)人,晋景帝司马师第三任妻子。羊徽瑜出身官宦世家泰山羊氏,她是南阳太守羊续的孙女,上党太守羊衜之女;其母为东汉名士左中郎将蔡邕之女、蔡文姬的姐妹。羊徽瑜聪慧贤德,嫁给司马师后未有子女。以司马师之弟司马昭的次子司马攸为继子。司马师死后,司马攸侍奉羊徽瑜非常孝顺。泰始元年(265年),司马昭长子司马炎受禅登基,建立西晋,追谥伯父司马师为景皇帝。泰始二年(266年),尊奉羊徽瑜为景皇后,因居弘训宫,故称弘训太后。咸宁四年(278年),羊徽瑜去世,时年六十五岁,谥号景献皇后,与司马师合葬峻平陵。', - dingyuan:'丁原(?—189年),字建阳,兖州泰山郡南城县(山东省平邑县郑城镇)人。东汉末年军阀,官拜执金吾、并州刺史。任并州刺史期间,他亲近、善待主簿吕布,又调遣部下张杨、张辽等名将到洛阳任职。汉灵帝驾崩后,带兵进入洛阳,担任执金吾,并与大将军何进谋划诛杀十常侍,但不久事情败露,何进被宦官杀死。在宦官被诛灭之后,丁原与军阀董卓在废帝问题上意见不合产生矛盾,于是董卓诱使吕布将其杀害,其势力亦被吞并。', - furong:'傅肜(?-222年),义阳(今湖北枣阳)人,三国时蜀汉将领。刘备攻伐吴国时,傅肜为别督。后刘备被陆逊击败,傅肜率部断后,奋战至死。死前怒斥道:“吴狗!何有汉将军降者!”', - zhengxuan:'郑玄(127年-200年),字康成。北海郡高密县(今山东省高密市)人。东汉末年儒家学者、经学大师。郑玄曾入太学攻《京氏易》、《公羊春秋》及《三统历》、《九章算术》,又从张恭祖学《古文尚书》、《周礼》和《左传》等,最后从马融学古文经。游学归里之后,复客耕东莱,聚徒授课,弟子达数千人,家贫好学,终为大儒。党锢之祸起,遭禁锢,杜门注疏,潜心著述。晚年守节不仕,却遭逼迫从军,最终病逝于元城,年七十四。郑玄治学以古文经学为主,兼采今文经学。他遍注儒家经典,以毕生精力整理古代文化遗产,使经学进入了一个“小统一时代”。著有《天文七政论》、《中侯》等书,共百万余言,世称“郑学”,为汉代经学的集大成者。唐贞观年间,列郑玄于二十二“先师”之列,配享孔庙。宋代时被追封为高密伯。后人建有郑公祠以纪念。', - dengzhi:'邓芝(178年-251年),字伯苗。义阳郡新野县(今河南新野)人。东汉名将邓禹之后,三国时期蜀汉重臣。邓芝早年曾被预言能位至大将,后被刘备任为郫令,升迁为广汉太守。因任官公廉且有治绩,被征入朝为尚书。刘备逝世后,奉命出使吴国,成功修复两国关系,并深为吴大帝孙权所赏识。建兴六年(228年),丞相诸葛亮策划北伐,命邓芝与大将赵云佯攻郿城,以吸引魏国曹真军主力。建兴十二年(234年),迁前军师、前将军,领兖州刺史,封阳武亭侯,不久督领江州。延熙六年(243年),迁车骑将军,后授假节。又率军平定涪陵叛乱。延熙十四年(251年),邓芝病逝。邓芝性格正直、简单,不刻意修饰情绪。他为将二十多年,赏罚明断,体恤士卒。身上的衣食取自官府,从未经营过私产,妻儿甚至还有忍饥挨饿之时,死时家中也没有多余财物。', - yangyi:'杨仪(?-235年),字威公,襄阳(今湖北襄阳)人,三国时期蜀汉官员。最初为荆州刺史傅群的主簿,后投奔关羽,任为功曹。关羽遣其至成都,大受刘备赞赏,擢为尚书。因与尚书令刘巴不和,调为弘农太守。建兴三年(225年)任丞相参军,此后一直跟随诸葛亮战斗。亮卒,他部署安全退军。诸葛亮在生前定蒋琬继己任,杨仪仅拜中军师。建兴十三年(235年),因多出怨言,被削职流放至汉嘉郡。但杨仪仍不自省,又上书诽谤,言辞激烈,最后下狱,自杀身亡。', - dongcheng:'董承(?~200年),字号不详,冀州河间人(今河北献县)人。东汉末年外戚大臣,汉灵帝母亲董太后侄子,汉献帝嫔妃董贵人之父。初从西凉军,为董卓女婿牛辅部曲。护卫汉献帝刘协从长安东归洛阳,拜为卫将军,受封列侯。建安四年(199年),拜车骑将军。自称领受汉献帝衣带诏,联合刘备、种辑、吴子兰、王子服、吴硕等人密谋诛杀曹操。五年正月,图谋泄露,董承诸人及董贵人全部遇害。', - chendeng:'陈登(163—201),字元龙,下邳淮浦(今江苏涟水西)人。东汉末年将领、官员。沛相陈珪之子。为人爽朗,性格沈静,智谋过人,少年时有扶世济民之志,并且博览群书,学识渊博。二十五岁时,举孝廉,任东阳县长。虽然年轻,但他能够体察民情,抚弱育孤,深得百姓敬重。后来,徐州牧陶谦提拔他为典农校尉,主管一州农业生产。他亲自考察徐州的土壤状况,开发水利,发展农田灌溉,使汉末迭遭破坏的徐州农业得到一定程度的恢复,百姓们安居乐业,“秔稻丰积”。建安初奉使赴许,向曹操献灭吕布之策,被授广陵太守。以灭吕布有功,加伏波将军。又迁东城太守。年三十九卒。其子陈肃,魏文帝时追陈登之功,为郎中。', - yangbiao:'杨彪(142年-225年),字文先。弘农郡华阴县(今陕西华阴)人。东汉末年名臣,太尉杨赐之子、名士杨修之父。杨彪少年时受家学熏陶,初举孝廉、茂才。其后征拜为议郎,参与续写《东观汉记》。任京兆尹时,揭发黄门令王甫的贪赃行为,使其被定罪诛杀。累任侍中、五官中郎将、卫尉等职。汉献帝时,遍历三公(司空、司徒、太尉)之职。权臣董卓意图迁都时,他据理力争。献帝东迁时,杨彪尽节护主。曹操挟献帝定都许县后,将杨彪下狱,获释后又任太常。他见汉室衰微,便诈称脚疾,不理世事。曹魏建立后,拒绝出任太尉,改光禄大夫,待以客礼。黄初六年(225年),杨彪去世,年八十四。其著作现仅存《答曹公书》一篇。', - zhangyì:'张翼(?-264年),字伯恭,益州犍为郡武阳县人。三国时期蜀汉将领。历任梓潼、广汉、蜀郡三郡太守,出任庲降都督,后随诸葛亮和姜维北伐,官至左车骑将军,领冀州刺史。初封关内侯,进爵都亭侯。蜀汉灭亡后,魏将钟会密谋造反,成都大乱,张翼亦为乱兵所杀。张翼是蜀汉第三任庲降都督,由于执法严厉,不得南夷欢心。在北伐上,张翼认为国小民疲,不应滥用武力,是蜀汉朝廷当时极少敢当朝和姜维争辩北伐问题的大臣。', - jiakui:'贾逵(174年—228年),本名贾衢,字梁道,河东襄陵人(今山西临汾县)。汉末三国时期魏国名臣,西晋开国功臣贾充父亲。初为并州郡吏,迁渑池县令,拜弘农太守,历仕曹操、曹丕、曹叡三世,是曹魏政权中具有军政才干的人物,终其一生为魏国统一事业作出卓越贡献。担任豫州刺史期间,兴修水利,凿通运河二百余里,时称“贾侯渠”,便利民生。随同曹丕伐吴,进封阳里亭侯,加号建威将军。石亭之战,率军救出曹休。太和二年,去世,赠本官,谥号为肃,《唐会要》将其尊为魏晋八君子之一。', - shenpei:'审配(?-204年),字正南,魏郡阴安(今河北清丰北)人。为人正直, 袁绍领冀州,审配被委以腹心之任,并总幕府。河北平定,袁绍以审配、逢纪统军事,审配恃其强盛,力主与曹操决战。曾率领弓弩手大破曹军于官渡。官渡战败,审配二子被俘,反因此受谮见疑,幸得逢纪力保。袁绍病死,审配等矫诏立袁尚为嗣,导致兄弟相争,被曹操各个击破。曹操围邺,审配死守数月,终城破被擒,拒不投降,慷慨受死。', - hujinding:'胡金定,女,传说中关羽之妻。关索之母,配偶关羽,出处《花关索传》和元代《三国志评话》民间传说人物。', + characterIntro: { + lizhaojiaobo: + "李昭(?—约公元260年),三国时期曹魏官吏,官拜冗从仆射,为魏帝曹髦的亲信。
              焦伯,三国时期人物,魏帝曹髦护卫,官拜黄门从官。
              曹髦见自己权力威势日渐削弱,感到不胜忿恨,于公元260年(甘露五年)五月初六夜里,令李昭和焦伯等在陵云台布署甲士,出讨司马昭,但最终失败,曹髦为成济所弑,李昭和焦伯等应该也战死。在《三国演义》里,焦伯挺枪出战成济,亦被成济所杀。", + chengji: + "成济(?~260年6月21日),三国时期曹魏官员。官至太子舍人。在魏帝曹髦起兵讨司马昭时,受到司马昭之心腹贾充指使,刺死曹髦。司马昭为平息众怒,将成倅、成济兄弟二人杀死。", + yangfeng: + "杨奉(?-197年/198年),东汉末年将领。杨奉早年参加白波军起义,曾经帮助李傕对抗郭汜,后来背叛李傕。兴平二年,加号兴义将军,护送汉献帝刘协东归雒阳,颇有功勋,加号车骑将军,屯兵于梁县。建安元年,随着汉献帝迁都许县,失去权力,先后依附于袁术、吕布,劫掠徐州和扬州地区。建安二年(一说三年),带兵进犯刘备领地,被刘备诱杀。", + muludawang: + "古典小说《三国演义》中的虚构人物,八纳洞主,孟获盟友。擅驱兽法,能行风雨,控制猛兽并指挥它们作战。在法术帮助下最初对蜀军取得一些胜利,但在诸葛亮的喷火木兽将他的动物吓跑后战败,最后死于乱军之中。", + laimin: "来敏(165年—261年),字敬达,义阳新野人,东汉太中大夫来歙之后,司空来艳之子,三国时期蜀汉官员。东汉末年,逢董卓之乱,来敏跟随姐夫黄琬到荆州避难,黄琬是刘璋祖母的侄子,来敏又与姐姐来氏入蜀,被刘璋引为宾客。来敏喜欢读书,尤其喜欢《左氏春秋》。刘备平定益州后,以来敏为典学校尉,后立太子,来敏为家令。刘禅继位后,任命来敏为虎贲中郎将,诸葛亮驻汉中,请来敏为军祭酒、辅军将军。却因其口出狂言而被罢官,诸葛亮死后,来敏历任大长秋、光禄大夫、执慎将军等职,期间多次因说错话而被免官,蜀汉景耀年间,来敏去世,时年九十七岁。", + shichangshi: + "十常侍,指中国东汉(公元25年—220年)灵帝时期(168年-189年)操纵政权的十二个宦官:张让、赵忠、夏恽、郭胜、孙璋、毕岚、栗嵩、段珪、高望、张恭、韩悝、宋典(在小说《三国演义》里,十常侍指的是指张让、赵忠、封谞、段珪、曹节、侯览、蹇硕、程旷、夏恽、郭胜十人),他们都任职中常侍。玩弄小皇帝于股掌之中,以至灵帝称“张常侍是我父,赵常侍是我母”。十常侍自己横征暴敛,卖官鬻爵,他们的父兄子弟遍布天下,横行乡里,祸害百姓,无官敢管。人民不堪剥削、压迫,纷纷起来反抗。当时一些比较清醒的官吏,已看出宦官集团的黑暗腐败,导致大规模农民起义的形势。郎中张钧在给皇帝的奏章中明确指出,黄巾起义是外戚宦官专权逼出来的,他说:“张角所以能兴兵作乱,万人所以乐附之者,其源皆由十常侍多放父兄、子弟、婚宗、宾客典据州郡,辜确财利,侵略百姓,百姓之怨无所告诉,故谋议不轨,聚为‘盗贼’。”后被曹操、袁绍所歼。", + sunzhang: + "孙璋(?-189年?)东汉末期汉灵帝的宦官,官居中常侍,为十常侍之一,在张让、赵忠之下位居第三。光熹元年(189年),张让、赵忠、段珪等诛杀何进,袁绍率军入宫,诛杀孙璋。", + bilan: "毕岚(?—189),东汉宦官,十常侍之一。十常侍朋比为奸,祸乱朝纲,制造出党锢之祸,后被袁绍诛杀。另外,毕岚曾制造翻车,用于取河水洒路。", + xiayun: "夏恽(?—189),东汉宦官,十常侍之一。后被袁绍、曹操诛于翠花楼前。", + hankui: "韩悝(?—189),东汉宦官,十常侍之一。后被袁绍所诛。", + lisong: "栗嵩,东汉宦官,十常侍之一,与张让等人均一同任职中常侍。", + duangui: + "段珪(?—189),东汉宦官,十常侍之一。段珪与张让、赵忠等人朋比为奸,党同伐异,横征暴敛,卖官鬻爵,引起了以何进为首的外戚集团的不满。何进谋诛宦官,却不纳曹操、陈琳之谏,多结外镇军阀,翘首京师,与袁绍等谋诛宦竖。终于事泄,被宦官集团查知。张让、段珪等人先下手为强,斩杀何进于嘉德殿前,却也引起了京师的变乱。袁绍等人趁机带兵冲入皇宫,大肆诛杀太监。洛阳卫军变乱后,段珪与张让等人劫持少帝刘辩、陈留王刘协出逃,后被杀。", + guosheng: + "郭胜,南阳宛(今河南南阳)人。汉灵帝时为中常侍,与张让、赵忠等狼狈为奸,并皆封侯。曾助同乡何进、何太后贵幸。后被袁绍等人率兵诛灭。", + gaowang: + "高望(?~189年),京兆人,东汉宦官,十常侍之一,为小黄门兼任尚药监,颇得皇子刘辩的信任。中平六年(189年),张让等人杀害大将军何进,袁绍与王匡等人率兵杀入雒阳端门,在承明堂上斩杀中常侍高望。", + qianzhao: + "牵招(?—231年),字子经,安平郡观津县(今河北省武邑县)人。三国时期曹魏名将。牵招早年师从乐隐,与刘备成为刎颈之交。投靠冀州牧袁绍,担任冀州从事,统领乌丸突骑。袁绍死后,跟随冀州刺史袁尚,受到并州牧高干加害,投奔丞相曹操,授军谋掾。从平乌丸,出任护乌丸校尉。举茂才出身,从平汉中,授中护军。拜平虏校尉,平定东莱郡叛乱。魏文帝曹丕时期,授护鲜卑校尉,驻扎昌平,迁右中郎将、雁门太守,遏制鲜卑轲比能发展壮大。魏明帝即位,赐爵关内侯,营救护乌丸校尉田豫。太和五年,去世。", + fuqian: "傅佥(?~263年),义阳(治今湖北省枣阳市)人,蜀汉将领傅彤之子,三国时期蜀汉名将。金长于谋略,并颇有胆勇,姜维甚爱之。傅佥官至关中都督。魏国攻伐蜀汉时,傅佥和蒋舒防守阳安关,兵败战死。", + wangjun: + "王濬(207年~286年),字士治,小名阿童,弘农郡湖县(今河南省灵宝市阌乡)人。西晋时期名将。王濬出身世家,博学多闻,容颜英俊,多谋善战。举秀才出身,起家河东郡从事。泰始八年(272年),担任广汉太守,平定益州叛乱,迁益州刺史。利用长江上游地势之利,修造战船,组建强大的水军。上书晋武帝,促成晋灭吴之战。咸宁六年(280年),率兵顺流而下,熔毁横江铁链,攻克丹阳郡,率先攻取石头城,接受吴末帝孙皓投降,完成西晋统一大业。凭借功勋,拜辅国将军、步兵校尉,册封襄阳侯。为避猜忌,纵情享受,累迁特进、抚军大将军、开府仪同三司、散骑常侍、后军将军等。太康六年十二月(286年1月18日),王濬去世,享年八十岁,谥号为“武”,安葬于柏谷山。", + yangfu: "杨阜(172年—244年),字义山,汉天水冀县(今甘谷县东南)人。三国时期曹魏名臣。汉献帝建安初年,任凉州从事,旋拜安定长史;韦康任刺史后辟为别驾,改任州参军;后因讨马超有功,赐爵关内侯。曹操征汉中时,杨阜担任益州刺史,回来后又担任武都太守。魏明帝时,由将作大匠改少府。杨阜不但卓识远见,而且刚正不阿,敢于直言,对朝廷弊政多有诤谏,六次进言谏魏明帝应勤政爱民,魏明帝对他颇有敬畏之心。杨阜勤政廉洁,在宫内担任少府时,专管宝器、珍膳、衣物等,而他死后则家无馀财。皇帝让杨阜的孙子杨豹继任了少府之职。原甘谷县文昌宫西侧有杨氏家祠,内悬“两代尚书”匾额。", + ruanhui: + "阮氏女,是指三国时期曹魏名士许允之妻阮氏,陈留尉氏人。阮氏女是中国古代四大丑女之一,貌丑而见识非凡。她出身士族之家,是卫尉阮共(字伯彦)之女、阮侃(字德如)之妹。嫁与许允后生有二子:许奇,官至司隶校尉;许猛,官至幽州刺史。", + peixiu: "裴秀(224年-271年4月3日),字季彦。河东郡闻喜县(今山西省闻喜县)人。[1]魏晋时期名臣、地图学家,东汉尚书令裴茂之孙、曹魏光禄大夫裴潜之子。出身河东裴氏,少年时便颇有名气,后被大将军曹爽辟为掾属,袭爵清阳亭侯,又迁黄门侍郎。高平陵之变后,因是曹爽的故吏而被罢免。此后历任廷尉正、安东将军及卫将军司马,参与谋划军国之政,参与平定诸葛诞叛乱。因功转任尚书,进封鲁阳乡侯。魏元帝继位后,进爵鲁阳县侯,任尚书仆射。咸熙元年(264年),受命负责修改官制,又提议恢复五等爵制。五等制恢复后,获封济川侯。他建议立司马炎为世子,司马炎继位晋王后,拜裴秀为尚书令、右光禄大夫。西晋建立后,加左光禄大夫,封钜鹿郡公。泰始三年(267年),升任司空。泰始七年(271年),裴秀因服食寒食散后饮冷酒而逝世,年四十八,谥号“元”。有文集三卷。裴秀作《禹贡地域图》,开创了中国古代地图绘制学。李约瑟称他为“中国科学制图学之父”,与古希腊著名地图学家托勒密齐名,是世界古代地图学史上东西辉映的两颗灿烂明星。为纪念这位中国地图科学创始人而设立的“裴秀奖”,每两年评选一次,是中国地图学界最高奖项。由于他的贡献突出,联合国天文组织将月球正面的一个环形山命名为“裴秀环形山”,", + liucheng: "游卡桌游的原创人物。设定为黄忠的妻子。", + jiangwan: + "蒋琬(?-246年),字公琰。零陵郡湘乡县人。三国时期蜀汉政治家,与诸葛亮、董允、费祎合称“蜀汉四相”。蒋琬最初随刘备入蜀,为广都县长。因其不理政事,惹怒刘备,在诸葛亮的劝说下才免于一死。后重获启用,受到诸葛亮的悉心培养,累官丞相长史兼抚军将军。建兴十二年(234年),诸葛亮去世,蒋琬继其执政,拜尚书令,又加行都护、假节,领益州刺史,再迁大将军,录尚书事,封安阳亭侯。延熙元年(238年),受命开府,加大司马,总揽蜀汉军政。曾制定由水路进攻曹魏的计划,但未被采纳。延熙九年(246年),蒋琬病逝,谥号为恭。", + sunhanhua: + "孙寒华,三国时女仙。梁·陶弘景《真诰》卷一三、五代·杜光庭《墉城集仙录》卷七:其父孙贲为孙权堂兄,寒华少时与杜契有私情,后从杜契受玄白之要,颜容日少。周旋吴越诸山十馀年,得道仙去。《鉴后集》卷四:一云即吴大帝孙权之女。于茅山修道,道成,冲虚而去,因号其山为华姥山。山在茅山崇禧观前。《神异典》卷二五九人于明代,误。", + yanpu: "阎圃,生卒年不详,是益州巴西安汉(今四川省南充市)人。张鲁割据巴、汉,就以阎圃为功曹。东汉末年人物,本为张鲁部下谋士,后随张鲁一同投降曹操,封平乐乡侯。", + mayuanyi: + "马元义(?—184年6月7日),东汉末年黄巾之乱的组织者之一,是黄巾大方首领。光和六年(183年),马元义奉黄巾军首领张角之命,筹划起事的准备工作。马元义聚集荆州、扬州信徒数万人约定于邺城相会,并收买中常侍封谞、徐奉等为内应,准备于次年(甲子年)三月初五(戊申日)内外同时起事。由于张角弟子济南人唐周的告密,马元义于于中平元年(184年)正月在河内郡山阳县被捕,送往洛阳车裂,同时被杀的还有教众近千人。由于马元义的被杀,迫使张角提前于二月起兵发动叛乱。", + simafu: "司马孚(180年-272年4月3日),字叔达。河内郡温县(今河南温县)人。三国曹魏至西晋初年重臣,西晋宗室,东汉京兆尹司马防第三子,晋宣帝司马懿之弟。自曹操时代起,司马孚就任文学掾,而后历仕魏国五代皇帝,累迁至太傅。司马孚在“高平陵事变”之际,协助司马懿控制京师,诛杀曹爽一党。后又督军成功防御吴、蜀的进攻,为司马氏政权的稳固多有功劳。但他性格十分谨慎,自司马懿执掌大权起,便逐渐引退,更未直接参与司马氏废立魏帝的谋划。西晋代魏后,司马孚进拜太宰,封安平王。晋武帝司马炎对他十分尊宠,但他并不以此为荣,至死仍以魏臣自称。泰始八年二月壬辰日(272年4月3日),司马孚去世,年九十三。武帝为其举哀三日,葬礼规格比照东汉东平献王刘苍,赐谥献王。", + sunchen: + "孙綝(231年-259年1月18日),字子通,吴郡富春(今浙江杭州市富阳区)人。三国时期吴国宗室、权臣,昭义中郎将孙静曾孙、定武中郎将孙暠之孙、安民都尉孙绰的儿子。门荫入仕,初任偏将军。太平元年(256年),升任侍中、武卫将军、都督中外诸军事。掌权以后,诛杀大司马滕胤、骠骑将军吕据等重臣,升任大将军,册封永宁县侯。嗜好杀戮,与皇帝孙亮的矛盾激化,最终废黜孙亮,拥立琅琊王孙休即位,累迁丞相、荆州牧。永安元年十二月(259年1月),在左将军张布的协助下,遭到皇帝孙休捕杀,时年二十八岁,削除宗籍,改姓故氏。", + qiaozhou: + "谯周(201年-270年),字允南,巴西郡西充国县(今四川西充县槐树镇)人。三国时期蜀汉大臣、学者、儒学家、史学家。幼年丧父,少读典籍,精研六经,颇晓天文,成为蜀地大儒之一,门下有陈寿、罗宪等学生。诸葛亮担任益州牧时,授劝学从事。诸葛亮死后,不顾朝令,前往奔丧。后主刘禅册立太子时,授太子仆,迁太子家令、光禄大夫。反对姜维北伐,著《仇国论》,力陈北伐之失。炎兴元年(263年),邓艾攻打成都时期,力劝刘禅投降,“有全国之功”,投降魏国后,受封阳城亭侯,迁骑都尉。泰始六年(270年),授散骑常侍,同年去世,时年七十岁。", + gongsunkang: + "公孙康(生卒年不详),辽东襄平(今辽宁辽阳)人。东汉末年辽东地区割据军阀,辽东太守公孙度长子(一作庶子)、车骑将军公孙恭之兄。公孙康在其父死后继任辽东太守。建安十二年(207年),擒斩图谋不轨的袁尚、袁熙兄弟,将其首级献予曹操,被拜为左将军,封襄平侯。建安十四年(209年),公孙康大破高句丽,陷其国都,并讨伐韩濊,设置带方郡。死后因二子年幼,由公孙恭继任。曹丕称帝后,被追赠为大司马。", + zhouqun: + "周群(生卒年不详),字仲直,巴西阆中(今四川阆中)人。周群年少时随父周舒学习占验天算之术。后来刘璋聘请周群为师友从事,其预言大多得以应验。刘备割据益州,任命周群为儒林校尉。曾劝说刘备攻汉中必定不利,事后得到应验,被举荐为茂才。", + dongzhao: + "董昭(156年-236年7月4日),字公仁,济阴定陶(今山东省菏泽市定陶区)人。东汉末年曹魏谋士、重臣、开国元勋。董昭年轻时被举为孝廉,后担任袁绍帐下参军。多有战功,但是袁绍听信谗言,董昭不得已离开袁绍投奔张杨。张杨率军迎接汉献帝时,董昭随行,并拜为议郎。后与曹操在洛阳相见,又建议曹操将汉献帝迎接到许昌。董昭自此成为曹操的谋士。建安年间(198年)历任河南尹、冀州牧、徐州牧、魏郡太守等职,多有功劳,深受曹操器重。曹操受封魏公、魏王的谋划都是出自董昭之手。曹丕继魏王位后,董昭任将作大匠。曹丕称帝后,升任大鸿胪。此后先后担任侍中、太常、光禄大夫、太仆等重要职位。魏明帝曹叡即位后转任卫尉。太和六年(232年)升任司徒。青龙四年(236年)卒,时年八十一,谥曰定。", + nanhualaoxian: + "南华老仙,是古典小说《三国演义》中的虚拟人物。其原型来自道教典籍中对庄子的封号,又称“南华仙人”、“南华真人”等。在古典小说《三国演义》通行本的第一回中,描述了南华老仙将《太平要术》赠送给张角的情节。", + chenzhen: + "陈震(?—公元235年),字孝起。荆州南阳郡(今河南南阳)人。三国时期蜀汉官员。刘备领荆州牧时,辟陈震为从事。后随刘备入蜀,为蜀郡北部都尉、汶山太守、犍为太守。建兴三年(225年),拜尚书,迁尚书令。建兴七年(229年),孙权称帝。蜀汉以陈震为卫尉,前往祝贺,与孙权开坛歃盟,交分天下。还蜀,封城阳亭侯。建兴十三年(235年),卒。", + hucheer: + "胡车儿(生卒年不详),东汉末年武将,初从张绣,为其心腹猛将,勇冠三军,与贾诩交情甚佳。宛城大战后,张绣投降曹操,曹操爱胡车儿之骁勇,手以黄金与之。后因曹操私纳张绣亡叔张济的遗孀邹氏,张绣深感其辱,欲杀曹操,与贾诩商议后决心反曹。《三国演义》中,作者考虑到典韦的勇猛,便增加了令胡车儿盗走典韦的双戟的情节。最终典韦、曹昂(曹操长子)、曹安民(曹操侄子)皆死于此次战斗。野史说胡车儿跟随曹操征战,被赵云在长坂坡上红枪挑死。", + simashi: + "司马师(208年~255年3月23日),字子元,河内温县(今河南省温县)人。三国时期曹魏权臣,西晋王朝的奠基人之一,晋宣帝司马懿与宣穆皇后张春华的长子,晋文帝司马昭的同母兄,晋武帝司马炎的伯父。司马师沉着坚强,雄才大略,早年与夏侯玄、何晏齐名。高平陵政变后,以功封长平乡侯,旋加卫将军。司马懿死后,以抚军大将军辅政,独揽朝廷大权,次年升为大将军。掌权后,他制定选拔官吏的法规,命百官推荐贤才,整顿纲纪,使其各有职掌,朝野肃然。司马师也有卓越的军事才能,曾用计于新城之战击溃吴国诸葛恪的大军。嘉平六年(254年),魏帝曹芳与中书令李丰等人密谋除司马师,事情泄露,司马师杀死参与者,迫郭太后废曹芳,改立高贵乡公曹髦为帝。次年,亲自率兵平定毌丘俭、文钦之乱。回师途中病死,时年四十八岁,谥号“忠武”。后被追尊为晋景王。西晋建立后,被追尊为景皇帝,庙号世宗。", + yanghuiyu: + "羊徽瑜(214年-278年),泰山南城(今山东新泰)人,晋景帝司马师第三任妻子。羊徽瑜出身官宦世家泰山羊氏,她是南阳太守羊续的孙女,上党太守羊衜之女;其母为东汉名士左中郎将蔡邕之女、蔡文姬的姐妹。羊徽瑜聪慧贤德,嫁给司马师后未有子女。以司马师之弟司马昭的次子司马攸为继子。司马师死后,司马攸侍奉羊徽瑜非常孝顺。泰始元年(265年),司马昭长子司马炎受禅登基,建立西晋,追谥伯父司马师为景皇帝。泰始二年(266年),尊奉羊徽瑜为景皇后,因居弘训宫,故称弘训太后。咸宁四年(278年),羊徽瑜去世,时年六十五岁,谥号景献皇后,与司马师合葬峻平陵。", + dingyuan: + "丁原(?—189年),字建阳,兖州泰山郡南城县(山东省平邑县郑城镇)人。东汉末年军阀,官拜执金吾、并州刺史。任并州刺史期间,他亲近、善待主簿吕布,又调遣部下张杨、张辽等名将到洛阳任职。汉灵帝驾崩后,带兵进入洛阳,担任执金吾,并与大将军何进谋划诛杀十常侍,但不久事情败露,何进被宦官杀死。在宦官被诛灭之后,丁原与军阀董卓在废帝问题上意见不合产生矛盾,于是董卓诱使吕布将其杀害,其势力亦被吞并。", + furong: "傅肜(?-222年),义阳(今湖北枣阳)人,三国时蜀汉将领。刘备攻伐吴国时,傅肜为别督。后刘备被陆逊击败,傅肜率部断后,奋战至死。死前怒斥道:“吴狗!何有汉将军降者!”", + zhengxuan: + "郑玄(127年-200年),字康成。北海郡高密县(今山东省高密市)人。东汉末年儒家学者、经学大师。郑玄曾入太学攻《京氏易》、《公羊春秋》及《三统历》、《九章算术》,又从张恭祖学《古文尚书》、《周礼》和《左传》等,最后从马融学古文经。游学归里之后,复客耕东莱,聚徒授课,弟子达数千人,家贫好学,终为大儒。党锢之祸起,遭禁锢,杜门注疏,潜心著述。晚年守节不仕,却遭逼迫从军,最终病逝于元城,年七十四。郑玄治学以古文经学为主,兼采今文经学。他遍注儒家经典,以毕生精力整理古代文化遗产,使经学进入了一个“小统一时代”。著有《天文七政论》、《中侯》等书,共百万余言,世称“郑学”,为汉代经学的集大成者。唐贞观年间,列郑玄于二十二“先师”之列,配享孔庙。宋代时被追封为高密伯。后人建有郑公祠以纪念。", + dengzhi: + "邓芝(178年-251年),字伯苗。义阳郡新野县(今河南新野)人。东汉名将邓禹之后,三国时期蜀汉重臣。邓芝早年曾被预言能位至大将,后被刘备任为郫令,升迁为广汉太守。因任官公廉且有治绩,被征入朝为尚书。刘备逝世后,奉命出使吴国,成功修复两国关系,并深为吴大帝孙权所赏识。建兴六年(228年),丞相诸葛亮策划北伐,命邓芝与大将赵云佯攻郿城,以吸引魏国曹真军主力。建兴十二年(234年),迁前军师、前将军,领兖州刺史,封阳武亭侯,不久督领江州。延熙六年(243年),迁车骑将军,后授假节。又率军平定涪陵叛乱。延熙十四年(251年),邓芝病逝。邓芝性格正直、简单,不刻意修饰情绪。他为将二十多年,赏罚明断,体恤士卒。身上的衣食取自官府,从未经营过私产,妻儿甚至还有忍饥挨饿之时,死时家中也没有多余财物。", + yangyi: "杨仪(?-235年),字威公,襄阳(今湖北襄阳)人,三国时期蜀汉官员。最初为荆州刺史傅群的主簿,后投奔关羽,任为功曹。关羽遣其至成都,大受刘备赞赏,擢为尚书。因与尚书令刘巴不和,调为弘农太守。建兴三年(225年)任丞相参军,此后一直跟随诸葛亮战斗。亮卒,他部署安全退军。诸葛亮在生前定蒋琬继己任,杨仪仅拜中军师。建兴十三年(235年),因多出怨言,被削职流放至汉嘉郡。但杨仪仍不自省,又上书诽谤,言辞激烈,最后下狱,自杀身亡。", + dongcheng: + "董承(?~200年),字号不详,冀州河间人(今河北献县)人。东汉末年外戚大臣,汉灵帝母亲董太后侄子,汉献帝嫔妃董贵人之父。初从西凉军,为董卓女婿牛辅部曲。护卫汉献帝刘协从长安东归洛阳,拜为卫将军,受封列侯。建安四年(199年),拜车骑将军。自称领受汉献帝衣带诏,联合刘备、种辑、吴子兰、王子服、吴硕等人密谋诛杀曹操。五年正月,图谋泄露,董承诸人及董贵人全部遇害。", + chendeng: + "陈登(163—201),字元龙,下邳淮浦(今江苏涟水西)人。东汉末年将领、官员。沛相陈珪之子。为人爽朗,性格沈静,智谋过人,少年时有扶世济民之志,并且博览群书,学识渊博。二十五岁时,举孝廉,任东阳县长。虽然年轻,但他能够体察民情,抚弱育孤,深得百姓敬重。后来,徐州牧陶谦提拔他为典农校尉,主管一州农业生产。他亲自考察徐州的土壤状况,开发水利,发展农田灌溉,使汉末迭遭破坏的徐州农业得到一定程度的恢复,百姓们安居乐业,“秔稻丰积”。建安初奉使赴许,向曹操献灭吕布之策,被授广陵太守。以灭吕布有功,加伏波将军。又迁东城太守。年三十九卒。其子陈肃,魏文帝时追陈登之功,为郎中。", + yangbiao: + "杨彪(142年-225年),字文先。弘农郡华阴县(今陕西华阴)人。东汉末年名臣,太尉杨赐之子、名士杨修之父。杨彪少年时受家学熏陶,初举孝廉、茂才。其后征拜为议郎,参与续写《东观汉记》。任京兆尹时,揭发黄门令王甫的贪赃行为,使其被定罪诛杀。累任侍中、五官中郎将、卫尉等职。汉献帝时,遍历三公(司空、司徒、太尉)之职。权臣董卓意图迁都时,他据理力争。献帝东迁时,杨彪尽节护主。曹操挟献帝定都许县后,将杨彪下狱,获释后又任太常。他见汉室衰微,便诈称脚疾,不理世事。曹魏建立后,拒绝出任太尉,改光禄大夫,待以客礼。黄初六年(225年),杨彪去世,年八十四。其著作现仅存《答曹公书》一篇。", + zhangyì: + "张翼(?-264年),字伯恭,益州犍为郡武阳县人。三国时期蜀汉将领。历任梓潼、广汉、蜀郡三郡太守,出任庲降都督,后随诸葛亮和姜维北伐,官至左车骑将军,领冀州刺史。初封关内侯,进爵都亭侯。蜀汉灭亡后,魏将钟会密谋造反,成都大乱,张翼亦为乱兵所杀。张翼是蜀汉第三任庲降都督,由于执法严厉,不得南夷欢心。在北伐上,张翼认为国小民疲,不应滥用武力,是蜀汉朝廷当时极少敢当朝和姜维争辩北伐问题的大臣。", + jiakui: "贾逵(174年—228年),本名贾衢,字梁道,河东襄陵人(今山西临汾县)。汉末三国时期魏国名臣,西晋开国功臣贾充父亲。初为并州郡吏,迁渑池县令,拜弘农太守,历仕曹操、曹丕、曹叡三世,是曹魏政权中具有军政才干的人物,终其一生为魏国统一事业作出卓越贡献。担任豫州刺史期间,兴修水利,凿通运河二百余里,时称“贾侯渠”,便利民生。随同曹丕伐吴,进封阳里亭侯,加号建威将军。石亭之战,率军救出曹休。太和二年,去世,赠本官,谥号为肃,《唐会要》将其尊为魏晋八君子之一。", + shenpei: + "审配(?-204年),字正南,魏郡阴安(今河北清丰北)人。为人正直, 袁绍领冀州,审配被委以腹心之任,并总幕府。河北平定,袁绍以审配、逢纪统军事,审配恃其强盛,力主与曹操决战。曾率领弓弩手大破曹军于官渡。官渡战败,审配二子被俘,反因此受谮见疑,幸得逢纪力保。袁绍病死,审配等矫诏立袁尚为嗣,导致兄弟相争,被曹操各个击破。曹操围邺,审配死守数月,终城破被擒,拒不投降,慷慨受死。", + hujinding: + "胡金定,女,传说中关羽之妻。关索之母,配偶关羽,出处《花关索传》和元代《三国志评话》民间传说人物。", }, - characterTitle:{ - }, - card:{ - ly_piliche:{ - fullskin:true, + characterTitle: {}, + card: { + ly_piliche: { + fullskin: true, //vanish:true, - derivation:'liuye', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-8}, - skills:['ly_piliche'], + derivation: "liuye", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -8 }, + skills: ["ly_piliche"], //destroy:'polu' }, - "wolong_card":{ - type:"takaramono", - fullskin:true, + wolong_card: { + type: "takaramono", + fullskin: true, //derivation:"pangdegong", }, - "fengchu_card":{ - type:"takaramono", - fullskin:true, + fengchu_card: { + type: "takaramono", + fullskin: true, //derivation:"pangdegong", }, - "xuanjian_card":{ - fullskin:true, - type:"takaramono", + xuanjian_card: { + fullskin: true, + type: "takaramono", //derivation:"pangdegong", }, - "shuijing_card":{ - fullskin:true, - type:"takaramono", + shuijing_card: { + fullskin: true, + type: "takaramono", //derivation:"pangdegong", }, - "rewrite_bagua":{ - derivation:"majun", + rewrite_bagua: { + derivation: "majun", //cardimage:"bagua", - fullskin:true, - type:"equip", - subtype:"equip2", - ai:{ - basic:{ - equipValue:7.5, + fullskin: true, + type: "equip", + subtype: "equip2", + ai: { + basic: { + equipValue: 7.5, }, }, - skills:["rw_bagua_skill"], + skills: ["rw_bagua_skill"], }, - "rewrite_baiyin":{ - derivation:"majun", - fullskin:true, + rewrite_baiyin: { + derivation: "majun", + fullskin: true, //cardimage:"baiyin", - type:"equip", - subtype:"equip2", - loseDelay:false, - onLose:function(){ - player.addTempSkill('rw_baiyin_skill_lose') + type: "equip", + subtype: "equip2", + loseDelay: false, + onLose: function () { + player.addTempSkill("rw_baiyin_skill_lose"); }, - skills:["rw_baiyin_skill"], - tag:{ - recover:1, + skills: ["rw_baiyin_skill"], + tag: { + recover: 1, }, - ai:{ - order:9.5, - equipValue:function(card,player){ - if(player.hp==player.maxHp) return 5; - if(player.countCards('h','rewrite_baiyin')) return 6; + ai: { + order: 9.5, + equipValue: function (card, player) { + if (player.hp == player.maxHp) return 5; + if (player.countCards("h", "rewrite_baiyin")) return 6; return 0; }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, }, }, - "rewrite_lanyinjia":{ - derivation:"majun", + rewrite_lanyinjia: { + derivation: "majun", //cardimage:"lanyinjia", - fullskin:true, - type:"equip", - subtype:"equip2", - skills:["rw_lanyinjia","lanyinjia2"], - ai:{ - equipValue:6, - basic:{ - equipValue:1, + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["rw_lanyinjia", "lanyinjia2"], + ai: { + equipValue: 6, + basic: { + equipValue: 1, }, }, }, - "rewrite_renwang":{ - derivation:"majun", + rewrite_renwang: { + derivation: "majun", //cardimage:"renwang", - fullskin:true, - type:"equip", - subtype:"equip2", - skills:["rw_renwang_skill"], - ai:{ - basic:{ - equipValue:7.5, + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["rw_renwang_skill"], + ai: { + basic: { + equipValue: 7.5, }, }, }, - "rewrite_tengjia":{ - derivation:"majun", + rewrite_tengjia: { + derivation: "majun", //cardimage:"tengjia", - fullskin:true, - type:"equip", - subtype:"equip2", + fullskin: true, + type: "equip", + subtype: "equip2", //cardnature:"fire", - ai:{ - equipValue:function(card,player){ - if(player.hasSkillTag('maixie')&&player.hp>1) return 0; - if(player.hasSkillTag('noDirectDamage')) return 10; - if(get.damageEffect(player,player,player,'fire')>=0) return 10; - var num=3-game.countPlayer(function(current){ - return get.attitude(current,player)<0; - }); - if(player.hp==1) num+=4; - if(player.hp==2) num+=1; - if(player.hp==3) num--; - if(player.hp>3) num-=4; + ai: { + equipValue: function (card, player) { + if (player.hasSkillTag("maixie") && player.hp > 1) return 0; + if (player.hasSkillTag("noDirectDamage")) return 10; + if (get.damageEffect(player, player, player, "fire") >= 0) return 10; + var num = + 3 - + game.countPlayer(function (current) { + return get.attitude(current, player) < 0; + }); + if (player.hp == 1) num += 4; + if (player.hp == 2) num += 1; + if (player.hp == 3) num--; + if (player.hp > 3) num -= 4; return num; }, - basic:{ - equipValue:3, + basic: { + equipValue: 3, }, }, - skills:["rw_tengjia1","rw_tengjia2","rw_tengjia3","rw_tengjia4"], + skills: ["rw_tengjia1", "rw_tengjia2", "rw_tengjia3", "rw_tengjia4"], }, - "rewrite_zhuge":{ - derivation:"majun", + rewrite_zhuge: { + derivation: "majun", //cardimage:"zhuge", - distance:{ - attackFrom:-2, + distance: { + attackFrom: -2, }, - fullskin:true, - type:"equip", - subtype:"equip1", - ai:{ - equipValue:function(card,player){ - if(!game.hasPlayer(function(current){ - return player.canUse('sha',current)&&get.effect(current,{name:'sha'},player,player)>0; - })){ + fullskin: true, + type: "equip", + subtype: "equip1", + ai: { + equipValue: function (card, player) { + if ( + !game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 1; } - if(player.hasSha()&&_status.currentPhase==player){ - if(player.getEquip('zhuge')||player.getCardUsable('sha')==0){ + if (player.hasSha() && _status.currentPhase == player) { + if (player.getEquip("zhuge") || player.getCardUsable("sha") == 0) { return 10; } } - var num=player.countCards('h','sha'); - if(num>1) return 6+num; - return 3+num; + var num = player.countCards("h", "sha"); + if (num > 1) return 6 + num; + return 3 + num; }, - basic:{ - equipValue:5, + basic: { + equipValue: 5, }, - tag:{ - valueswap:1, + tag: { + valueswap: 1, }, }, - skills:["rw_zhuge_skill"], + skills: ["rw_zhuge_skill"], }, }, - characterFilter:{ - simashi:function(mode){ - if(['boss','chess','tafang','stone'].includes(mode)) return false; - if(mode=='versus') return _status.mode!='three'; + characterFilter: { + simashi: function (mode) { + if (["boss", "chess", "tafang", "stone"].includes(mode)) return false; + if (mode == "versus") return _status.mode != "three"; return true; }, }, - skill:{ + skill: { //李昭焦伯 - mbzuoyou:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuanhuanji:true, - filterTarget(card,player,target){ - if(player.storage.mbzuoyou) return target.countCards('h'); + mbzuoyou: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuanhuanji: true, + filterTarget(card, player, target) { + if (player.storage.mbzuoyou) return target.countCards("h") >= 2; return true; }, - async content(event,trigger,player){ - const storage = player.storage.mbzuoyou, target = event.target; - if (event.name === 'mbzuoyou') player.changeZhuanhuanji('mbzuoyou'); + async content(event, trigger, player) { + const storage = player.storage.mbzuoyou, + target = event.target; + if (event.name === "mbzuoyou") player.changeZhuanhuanji("mbzuoyou"); if (!storage) { - await target.draw(3); - await target.chooseToDiscard(2,true,'he'); - } - else { - await target.chooseToDiscard(target===player ? '佐佑' : `${get.translation(player)}对你发动了【佐佑】`, '请弃置一张手牌,然后获得1点护甲', true); + await target.draw(2); + await target.chooseToDiscard(1, true, "h"); + } else { + await target.chooseToDiscard( + target === player ? "佐佑" : `${get.translation(player)}对你发动了【佐佑】`, + "请弃置两张手牌,然后获得1点护甲", + 2, + true + ); await target.changeHujia(1, null, true); } }, - mark:true, - marktext:'☯', - intro:{ - content(storage,player){ - if(!storage) return '转换技。出牌阶段限一次,你可以令一名角色摸三张牌,然后其弃置两张牌。'; - return '转换技。出牌阶段限一次,你可以令一名角色弃置一张手牌,然后其获得1点护甲。'; - } + mark: true, + marktext: "☯", + intro: { + content(storage, player) { + if (!storage) + return "转换技。出牌阶段限一次,你可以令一名角色摸两张牌,然后其弃置一张手牌。"; + return "转换技。出牌阶段限一次,你可以令一名手牌数不少于二的角色弃置两张手牌,然后其获得1点护甲。"; + }, }, - ai:{ - order(item,player){ - if(player.storage.mbzuoyou&&game.hasPlayer(current=>{ - return current!==player&&get.effect(current,'mbzuoyou',player,player)>0; - })) return get.order({name:'zengbin'})+0.1; + ai: { + order(item, player) { + if ( + player.storage.mbzuoyou && + game.hasPlayer((current) => { + return ( + current !== player && get.effect(current, "mbzuoyou", player, player) > 0 + ); + }) + ) + return get.order({ name: "zengbin" }) + 0.1; return 2; }, - result:{ - target(player,target){ - let eff=0; - if(player.storage.mbzuoyou) eff=target.hujia<5?1:0; - else eff=1; - if(target===player&&player.hasSkill('mbshishou')) eff/=10; + result: { + target(player, target) { + let eff = 0; + if (player.storage.mbzuoyou) eff = target.hujia < 5 ? 1 : 0; + else eff = 1; + if (target === player && player.hasSkill("mbshishou")) eff /= 10; return eff; }, - } + }, }, }, - mbshishou:{ - audio:2, - forced:true, - trigger:{player:'useSkillAfter'}, - filter(event,player){ - return event.skill==='mbzuoyou'&&!event.targets.includes(player); + mbshishou: { + audio: 2, + trigger: { player: "useSkillAfter" }, + filter(event, player) { + return event.skill === "mbzuoyou" && !event.targets.includes(player); }, - forced:true, - async content(event,trigger,player){ - await lib.skill.mbzuoyou.content({ - target: player, - }, {}, player); + forced: true, + async content(event, trigger, player) { + await lib.skill.mbzuoyou.content( + { + target: player, + }, + {}, + player + ); + }, + ai: { + combo: "mbzuoyou" }, }, //成济 - mbkuangli:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(current=>current!==player); + mbkuangli: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((current) => current !== player); }, - forced:true, - group:['mbkuangli_target','mbkuangli_remove'], - async content(event,trigger,player){ - let targets = game.filterPlayer(current => current !== player).randomSort(); + forced: true, + group: ["mbkuangli_target", "mbkuangli_remove"], + async content(event, trigger, player) { + let targets = game.filterPlayer((current) => current !== player).randomSort(); targets = targets.slice(0, Math.ceil(Math.random() * targets.length)); targets.sortBySeat(); - player.line(targets, 'thunder'); - targets.forEach(current => { - current.addSkill('mbkuangli_mark'); + player.line(targets, "thunder"); + targets.forEach((current) => { + current.addSkill("mbkuangli_mark"); }); await game.asyncDelayx(); }, - subSkill:{ - target:{ - audio:'mbkuangli', - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return event.target.hasSkill('mbkuangli_mark')&&[player,event.target].some(current=>current.countCards('he')); + subSkill: { + target: { + audio: "mbkuangli", + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return ( + event.target.hasSkill("mbkuangli_mark") && + [player, event.target].some((current) => current.countCards("he")) + ); }, - forced:true, - logTarget:'target', - usable:2, - async content(event,trigger,player){ + forced: true, + logTarget: "target", + usable: 2, + async content(event, trigger, player) { const target = trigger.target; - const playerCards = player.getCards('he', card => { - return lib.filter.cardDiscardable(card, player, 'mbkuangli'); + const playerCards = player.getCards("he", (card) => { + return lib.filter.cardDiscardable(card, player, "mbkuangli"); }); - if(playerCards.length>0) await player.discard(playerCards.randomGet()); - const targetCards = target.getCards('he', card => { - return lib.filter.cardDiscardable(card, target, 'mbkuangli'); + if (playerCards.length > 0) await player.discard(playerCards.randomGet()); + const targetCards = target.getCards("he", (card) => { + return lib.filter.cardDiscardable(card, target, "mbkuangli"); }); - if(targetCards.length>0) await target.discard(targetCards.randomGet()); + if (targetCards.length > 0) await target.discard(targetCards.randomGet()); await game.asyncDelayx(); await player.draw(); await game.asyncDelayx(); }, - ai:{ - effect:{ - player(card,player,target,current){ - if(!target) return; - const counttrigger=player.storage.counttrigger; - if(counttrigger&&counttrigger.mbkuangli_target&&counttrigger.mbkuangli_target>=lib.skill.mbkuangli_target.usable) return; - if(target.hasSkill('mbkuangli_mark')){ - if(get.attitude(player,target)>0) return 0.75; + ai: { + effect: { + player(card, player, target, current) { + if (!target) return; + const counttrigger = player.storage.counttrigger; + if ( + counttrigger && + counttrigger.mbkuangli_target && + counttrigger.mbkuangli_target >= lib.skill.mbkuangli_target.usable + ) + return; + if (target.hasSkill("mbkuangli_mark")) { + if (get.attitude(player, target) > 0) return 0.75; return 1.25; } - } - } + }, + }, }, }, - remove:{ - audio:'mbkuangli', - trigger:{player:'phaseEnd'}, - filter(event,player){ - return game.hasPlayer(current=>current.hasSkill('mbkuangli_mark')); + remove: { + audio: "mbkuangli", + trigger: { player: "phaseEnd" }, + filter(event, player) { + return game.hasPlayer((current) => current.hasSkill("mbkuangli_mark")); }, - forced:true, - async content(event,trigger,player){ - game.countPlayer(current=>{ - if(current.hasSkill('mbkuangli_mark')){ + forced: true, + async content(event, trigger, player) { + game.countPlayer((current) => { + if (current.hasSkill("mbkuangli_mark")) { player.line(current); - current.removeSkill('mbkuangli_mark'); + current.removeSkill("mbkuangli_mark"); } }); }, }, - mark:{ - mark:true, - marktext:'戾', - charlotte:true, - intro:{ - name:'狂戾', - name2:'狂戾', - content:'已拥有“狂戾”标记', - } + mark: { + mark: true, + marktext: "戾", + charlotte: true, + intro: { + name: "狂戾", + name2: "狂戾", + content: "已拥有“狂戾”标记", + }, }, }, }, - mbxiongsi:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.countCards('h')>=3; + mbxiongsi: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return player.countCards("h") >= 3; }, - limited:true, - skillAnimation:true, - animationColor:'fire', - filterCard:true, - selectCard:[-1,-2], - async content(event,trigger,player){ - player.awakenSkill('mbxiongsi'); - const targets = game.filterPlayer(current => current !== player); + limited: true, + skillAnimation: true, + animationColor: "fire", + filterCard: true, + selectCard: [-1, -2], + async content(event, trigger, player) { + player.awakenSkill("mbxiongsi"); + const targets = game.filterPlayer((current) => current !== player); for (const target of targets) { - player.line(target, 'thunder'); + player.line(target, "thunder"); await target.loseHp(); } }, - ai:{ - order(item,player){ - if(get.effect(player,'mbxiongsi',player)<=0) return 1; - if(player.countCards('h')>3&&player.countCards('h',card=>{ - return player.hasValueTarget(card); - })>0) return 0.1; + ai: { + order(item, player) { + if (get.effect(player, "mbxiongsi", player) <= 0) return 1; + if ( + player.countCards("h") > 3 && + player.countCards("h", (card) => { + return player.hasValueTarget(card); + }) > 0 + ) + return 0.1; return 8; }, - result:{ - player(player){ - let eff=0; - game.countPlayer(current=>{ - let effx=get.effect(current,{name:'losehp'},player,player); - if(get.attitude(player,current)<-6&¤t.getHp()<=1) effx*=1.3; - eff+=effx; + result: { + player(player) { + let eff = 0; + game.countPlayer((current) => { + let effx = get.effect(current, { name: "losehp" }, player, player); + if (get.attitude(player, current) < -6 && current.getHp() <= 1) effx *= 1.3; + eff += effx; }); - eff*=player.getHp()+player.countCards('hs',card=>player.canSaveCard(card,player))<=2?1.5:0.35; - eff-=player.getCards('h').map(card=>{ - if(lib.filter.cardDiscardable(card,player,'mbxiongsi')) return get.value(card); - return 0; - }).reduce((p,c)=>p+c,0); - if(eff>0) return 2; + eff *= + player.getHp() + + player.countCards("hs", (card) => player.canSaveCard(card, player)) <= + 2 + ? 1.5 + : 0.35; + eff -= player + .getCards("h") + .map((card) => { + if (lib.filter.cardDiscardable(card, player, "mbxiongsi")) + return get.value(card); + return 0; + }) + .reduce((p, c) => p + c, 0); + if (eff > 0) return 2; return -1; }, }, }, }, //SP母兵脸 - mbcuizhen:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + mbcuizhen: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.hasPlayer(current=>{ - return current!==player&¤t.hasEnabledSlot(1); - }); + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + game.hasPlayer((current) => { + return current !== player && current.hasEnabledSlot(1); + }) && + get.mode() == "identity" + ); }, - async cost(event,trigger,player){ - event.result = await player.chooseTarget(get.prompt('mbcuizhen'), '废除至多两名其他角色的武器栏', [1, 2], (card, player, target) => { - return target !== player && target.hasEnabledSlot(1); - }).set('ai', target => { - return -get.attitude(get.player(), target); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("mbcuizhen"), + "废除至多两名其他角色的武器栏", + [1, 2], + (card, player, target) => { + return target !== player && target.hasEnabledSlot(1); + } + ) + .set("ai", (target) => { + return -get.attitude(get.player(), target); + }) + .forResult(); }, - group:['mbcuizhen_inphase','mbcuizhen_draw'], - async content(event,trigger,player){ + group: ["mbcuizhen_inphase", "mbcuizhen_draw"], + async content(event, trigger, player) { const targets = event.targets.slice().sortBySeat(); for (const target of targets) { await target.disableEquip(1); } await game.asyncDelay(); }, - subSkill:{ - inphase:{ - audio:'mbcuizhen', - trigger:{ - player:'useCardToPlayered', + subSkill: { + inphase: { + audio: "mbcuizhen", + trigger: { + player: "useCardToPlayered", }, - filter(event,player){ - if(!player.isPhaseUsing()) return false; - if(!get.tag(event.card,'damage')) return false; - const target=event.target; - return target!==player&&target.countCards('h')>=target.getHp()&&target.hasEnabledSlot(1); + filter(event, player) { + if (!player.isPhaseUsing()) return false; + if (!get.tag(event.card, "damage")) return false; + const target = event.target; + return ( + target !== player && + target.countCards("h") >= target.getHp() && + target.hasEnabledSlot(1) + ); }, - prompt2:'废除其的武器栏', - logTarget:'target', - check(event,player){ - return get.attitude(player,event.target)<=0; + prompt2: "废除其的武器栏", + logTarget: "target", + check(event, player) { + return get.attitude(player, event.target) <= 0; }, - async content(event,trigger,player){ + async content(event, trigger, player) { await trigger.target.disableEquip(1); await game.asyncDelayx(); }, }, - draw:{ - audio:'mbcuizhen', - trigger:{player:'phaseDrawBegin2'}, - forced:true, - locked:false, - filter(event,player){ - return !event.numFixed&&game.hasPlayer(current=>{ - return current.hasDisabledSlot(1); - }); + draw: { + audio: "mbcuizhen", + trigger: { player: "phaseDrawBegin2" }, + forced: true, + locked: false, + filter(event, player) { + return ( + !event.numFixed && + game.hasPlayer((current) => { + return current.hasDisabledSlot(1); + }) + ); }, - async content(event,trigger,player){ - trigger.num += Math.min(2, game.countPlayer(current => { - return current.countDisabledSlot(1); - })); + async content(event, trigger, player) { + trigger.num += Math.min( + 2, + game.countPlayer((current) => { + return current.countDisabledSlot(1); + }) + ); }, }, }, }, - mbkuili:{ - audio:2, - trigger:{ - player:'damageEnd', + mbkuili: { + audio: 2, + trigger: { + player: "damageEnd", }, - filter(event,player){ - return player.countCards('h')>0||event.source&&event.source.isIn()&&event.source.hasDisabledSlot(1); + filter(event, player) { + return ( + player.countCards("h") > 0 || + (event.source && event.source.isIn() && event.source.hasDisabledSlot(1)) + ); }, - forced:true, - async content(event,trigger,player){ - if (player.countCards('h') > 0) { - await player.chooseToDiscard(`溃离:请弃置${get.cnNumber(trigger.num)}张手牌`, trigger.num, true); + forced: true, + async content(event, trigger, player) { + if (player.countCards("h") > 0) { + await player.chooseToDiscard( + `溃离:请弃置${get.cnNumber(trigger.num)}张手牌`, + trigger.num, + true + ); } const source = trigger.source; if (source && source.isIn() && source.hasDisabledSlot(1)) { - player.line(source, 'green'); + player.line(source, "green"); await source.enableEquip(1, player); } }, - ai:{ - neg:true, - } + ai: { + neg: true, + }, }, //曹髦 史?! - mbqianlong:{ - audio:2, - trigger:{ - player:['mbqianlong_beginAfter','mbqianlong_addAfter','mbweitongAfter'], + mbqianlong: { + audio: 6, + trigger: { + player: ["mbqianlong_beginAfter", "mbqianlong_addAfter", "mbweitongAfter"], }, - filter(event,player){ - let skills=[]; - if(player.additionalSkills&&player.additionalSkills.mbqianlong) skills.addArray(player.additionalSkills.mbqianlong); - return player.countMark('mbqianlong')>=25*skills.length; + filter(event, player) { + let skills = []; + if (player.additionalSkills && player.additionalSkills.mbqianlong) + skills.addArray(player.additionalSkills.mbqianlong); + return player.countMark("mbqianlong") >= 25 * skills.length; }, - forced:true, - locked:false, - beginMarkCount:20, - maxMarkCount:100, - derivation:['mbcmqingzheng','mbcmjiushi','mbcmfangzhu','mbjuejin'], - addMark(player,num){ - num = Math.min(num, lib.skill.mbqianlong.maxMarkCount - player.countMark('mbqianlong')); - player.addMark('mbqianlong', num); + forced: true, + locked: false, + beginMarkCount: 20, + maxMarkCount: 100, + derivation: ["mbcmqingzheng", "mbcmjiushi", "mbcmfangzhu", "mbjuejin"], + addMark(player, num) { + num = Math.min(num, lib.skill.mbqianlong.maxMarkCount - player.countMark("mbqianlong")); + player.addMark("mbqianlong", num); }, - group:['mbqianlong_begin','mbqianlong_add'], - async content(event,trigger,player){ - player.addAdditionalSkill('mbqianlong', lib.skill.mbqianlong.derivation.slice(0, Math.floor(player.countMark('mbqianlong') / 25))); + group: ["mbqianlong_begin", "mbqianlong_add"], + async content(event, trigger, player) { + player.addAdditionalSkill( + "mbqianlong", + lib.skill.mbqianlong.derivation.slice( + 0, + Math.floor(player.countMark("mbqianlong") / 25) + ) + ); }, - marktext:'道', - intro:{ - name:'道心(潜龙)', - name2:'道心', - content:'当前道心数为#', + marktext: "道", + intro: { + name: "道心(潜龙)", + name2: "道心", + content: "当前道心数为#", }, - subSkill:{ - begin:{ - audio:'mbqianlong', - trigger:{ - global:'phaseBefore', - player:'enterGame', + subSkill: { + begin: { + audio: "mbqianlong", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - async content(event,trigger,player){ + forced: true, + locked: false, + async content(event, trigger, player) { lib.skill.mbqianlong.addMark(player, lib.skill.mbqianlong.beginMarkCount); }, }, - add:{ - audio:'mbqianlong', - trigger:{ - player:['gainAfter','damageEnd'], - source:'damageSource', - global:'loseAsyncAfter', + add: { + audio: "mbqianlong", + trigger: { + player: ["gainAfter", "damageEnd"], + source: "damageSource", + global: "loseAsyncAfter", }, - filter(event,player){ - if(player.countMark('mbqianlong')>=lib.skill.mbqianlong.maxMarkCount) return false; - if(event.name==='damage') return event.num>0; - return event.getg(player).length>0; + filter(event, player) { + if (player.countMark("mbqianlong") >= lib.skill.mbqianlong.maxMarkCount) + return false; + if (event.name === "damage") return event.num > 0; + return event.getg(player).length > 0; }, - getIndex(event,player,triggername){ - if(event.name==='damage') return event.num; + getIndex(event, player, triggername) { + if (event.name === "damage") return event.num; return 1; }, - forced:true, - locked:false, - async content(event,trigger,player){ - let toAdd = 5 * (1 + (trigger.name === 'damage') + (event.triggername === 'damageSource')); + forced: true, + locked: false, + async content(event, trigger, player) { + let toAdd = + 5 * + (1 + (trigger.name === "damage") + (event.triggername === "damageSource")); lib.skill.mbqianlong.addMark(player, toAdd); }, }, }, }, - mbweitong:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + mbweitong: { + audio: 1, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.hasPlayer(current=>{ - return current!==player&¤t.group==='wei'&&player.hasZhuSkill('mbweitong',current); - }); + filter(event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + game.hasPlayer((current) => { + return ( + current !== player && + current.group === "wei" && + player.hasZhuSkill("mbweitong", current) + ); + }) + ); }, - zhuSkill:true, - forced:true, - locked:false, - async content(event,trigger,player){ - lib.skill.mbqianlong.addMark(player, 20 * game.countPlayer(current => { - return current !== player && current.group === 'wei' && player.hasZhuSkill('mbweitong', current); - })); + zhuSkill: true, + forced: true, + locked: false, + async content(event, trigger, player) { + lib.skill.mbqianlong.addMark( + player, + 20 * + game.countPlayer((current) => { + return ( + current !== player && + current.group === "wei" && + player.hasZhuSkill("mbweitong", current) + ); + }) + ); + }, + ai: { + combo: "mbqianlong" }, }, - mbcmqingzheng:{ - audio:'sbqingzheng', - audioname:['mb_caomao'], - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return player.countCards('h')>0; + mbcmqingzheng: { + audio: "sbqingzheng", + audioname: ["mb_caomao"], + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return player.countCards("h") > 0; }, - direct:true, - content(){ - 'step 0' - var num=2; - var prompt='###'+get.prompt('sbqingzheng')+'###弃置'+get.cnNumber(num)+'种花色的所有牌'; - var next=player.chooseButton([prompt,[lib.suit.map(i=>['','','lukai_'+i]),'vcard']],num); - next.set('filterButton',button=>{ - var player=_status.event.player; - var cards=player.getCards('h',{suit:button.link[2].slice(6)}); - return cards.length>0&&cards.filter(card=>lib.filter.cardDiscardable(card,player,'sbqingzheng')).length==cards.length; + direct: true, + content() { + "step 0"; + var num = 2; + var prompt = + "###" + get.prompt("sbqingzheng") + "###弃置" + get.cnNumber(num) + "种花色的所有牌"; + var next = player.chooseButton( + [prompt, [lib.suit.map((i) => ["", "", "lukai_" + i]), "vcard"]], + num + ); + next.set("filterButton", (button) => { + var player = _status.event.player; + var cards = player.getCards("h", { suit: button.link[2].slice(6) }); + return ( + cards.length > 0 && + cards.filter((card) => lib.filter.cardDiscardable(card, player, "sbqingzheng")) + .length == cards.length + ); }); - next.set('ai',button=>{ - var player=_status.event.player; - return 15-player.getCards('h',{suit:button.link[2].slice(6)}).map(i=>get.value(i)).reduce((p,c)=>p+c,0); + next.set("ai", (button) => { + var player = _status.event.player; + return ( + 15 - + player + .getCards("h", { suit: button.link[2].slice(6) }) + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0) + ); }); - next.set('custom',{ - replace:{ - button:function(button){ - if(!_status.event.isMine()) return; - if(button.classList.contains('selectable')==false) return; - var cards=_status.event.player.getCards('h',{suit:button.link[2].slice(6)}); - if(cards.length){ - var chosen=cards.filter(i=>ui.selected.cards.includes(i)).length==cards.length; - if(chosen){ + next.set("custom", { + replace: { + button: function (button) { + if (!_status.event.isMine()) return; + if (button.classList.contains("selectable") == false) return; + var cards = _status.event.player.getCards("h", { + suit: button.link[2].slice(6), + }); + if (cards.length) { + var chosen = + cards.filter((i) => ui.selected.cards.includes(i)).length == + cards.length; + if (chosen) { ui.selected.cards.removeArray(cards); - cards.forEach(card=>{ - card.classList.remove('selected'); + cards.forEach((card) => { + card.classList.remove("selected"); card.updateTransform(false); }); - }else{ + } else { ui.selected.cards.addArray(cards); - cards.forEach(card=>{ - card.classList.add('selected'); + cards.forEach((card) => { + card.classList.add("selected"); card.updateTransform(true); }); } } - if(button.classList.contains('selected')){ + if (button.classList.contains("selected")) { ui.selected.buttons.remove(button); - button.classList.remove('selected'); - if(_status.multitarget||_status.event.complexSelect){ + button.classList.remove("selected"); + if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); } - } - else{ - button.classList.add('selected'); + } else { + button.classList.add("selected"); ui.selected.buttons.add(button); } - var custom=_status.event.custom; - if(custom&&custom.add&&custom.add.button){ + var custom = _status.event.custom; + if (custom && custom.add && custom.add.button) { custom.add.button(); } game.check(); - } + }, }, - add:next.custom.add + add: next.custom.add, }); - 'step 1' - if(result.bool){ - var cards=result.cards; - if(!cards.length){ - var suits=result.links.map(i=>i[2].slice(6)); - cards=player.getCards('h',card=>suits.includes(get.suit(card,player))); + "step 1"; + if (result.bool) { + var cards = result.cards; + if (!cards.length) { + var suits = result.links.map((i) => i[2].slice(6)); + cards = player.getCards("h", (card) => suits.includes(get.suit(card, player))); } - event.cards=cards; - if(!cards.length) event.finish(); - else player.chooseTarget('清正:观看一名其他角色的手牌并弃置其中一种花色的所有牌',(card,player,target)=>{ - return target!=player&&target.countCards('h'); - }).set('ai',target=>{ - var player=_status.event.player,att=get.attitude(player,target); - if(att>=0) return 0; - return 1-att/2+Math.sqrt(target.countCards('h')); - }); + event.cards = cards; + if (!cards.length) event.finish(); + else + player + .chooseTarget( + "清正:观看一名其他角色的手牌并弃置其中一种花色的所有牌", + (card, player, target) => { + return target != player && target.countCards("h"); + } + ) + .set("ai", (target) => { + var player = _status.event.player, + att = get.attitude(player, target); + if (att >= 0) return 0; + return 1 - att / 2 + Math.sqrt(target.countCards("h")); + }); } else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('sbqingzheng',target); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("sbqingzheng", target); player.discard(cards); - var list=[]; - var dialog=['清正:弃置'+get.translation(target)+'一种花色的所有牌']; - for(var suit of lib.suit.concat('none')){ - if(target.countCards('h',{suit:suit})){ - dialog.push('
              '+get.translation(suit+'2')+'牌
              '); - dialog.push(target.getCards('h',{suit:suit})); + var list = []; + var dialog = ["清正:弃置" + get.translation(target) + "一种花色的所有牌"]; + for (var suit of lib.suit.concat("none")) { + if (target.countCards("h", { suit: suit })) { + dialog.push( + '
              ' + get.translation(suit + "2") + "牌
              " + ); + dialog.push(target.getCards("h", { suit: suit })); list.push(suit); } } - if(list.length){ - player.chooseControl(list).set('dialog',dialog).set('ai',()=>{ - return _status.event.control; - }).set('control',(()=>{ - var getv=(cards)=>cards.map(i=>get.value(i)).reduce((p,c)=>p+c,0); - return list.sort((a,b)=>{ - return getv(target.getCards('h',{suit:b}))-getv(target.getCards('h',{suit:a})); - })[0]; - })()); + if (list.length) { + player + .chooseControl(list) + .set("dialog", dialog) + .set("ai", () => { + return _status.event.control; + }) + .set( + "control", + (() => { + var getv = (cards) => + cards.map((i) => get.value(i)).reduce((p, c) => p + c, 0); + return list.sort((a, b) => { + return ( + getv(target.getCards("h", { suit: b })) - + getv(target.getCards("h", { suit: a })) + ); + })[0]; + })() + ); } } else event.finish(); - 'step 3' - var cards2=target.getCards('h',{suit:result.control}); - event.cards2=cards2; - target.discard(cards2,'notBySelf').set('discarder',player); - 'step 4' - if(event.cards2.lengthcurrent!==player); + mbcmfangzhu: { + audio: "sbfangzhu", + audioname: ["mb_caomao"], + inherit: "sbfangzhu", + filter(event, player) { + return game.hasPlayer((current) => current !== player); }, - usable:1, - chooseButton:{ - dialog(){ - const dialog=ui.create.dialog('放逐:令一名其他角色...','hidden'); - dialog.add([[ - [1,'不能使用手牌中的非锦囊牌直到其回合结束'], - [2,'非Charlotte技能失效直到其回合结束'], - ],'textbutton']); + usable: 1, + chooseButton: { + dialog() { + const dialog = ui.create.dialog("放逐:令一名其他角色...", "hidden"); + dialog.add([ + [ + [1, "不能使用手牌中的非锦囊牌直到其回合结束"], + [2, "非Charlotte技能失效直到其回合结束"], + ], + "textbutton", + ]); return dialog; }, - check(button){ - const player=get.player(); - if(button.link===2){ - if(game.hasPlayer(target=>{ - if(target.hasSkill('mbcmfangzhu_ban')||target.hasSkill('fengyin')||target.hasSkill('baiban')) return false; - return get.attitude(player,target)<0&&['name','name1','name2'].map((sum,name)=>{ - if(target[name]&&(name!='name1'||target.name!=target.name1)){ - if(get.character(target[name])) return get.rank(target[name],true); - } - return 0; - }).reduce((p,c)=>{ - return p+c; - },0)>5; - })) return 6; + check(button) { + const player = get.player(); + if (button.link === 2) { + if ( + game.hasPlayer((target) => { + if ( + target.hasSkill("mbcmfangzhu_ban") || + target.hasSkill("fengyin") || + target.hasSkill("baiban") + ) + return false; + return ( + get.attitude(player, target) < 0 && + ["name", "name1", "name2"] + .map((sum, name) => { + if ( + target[name] && + (name != "name1" || target.name != target.name1) + ) { + if (get.character(target[name])) + return get.rank(target[name], true); + } + return 0; + }) + .reduce((p, c) => { + return p + c; + }, 0) > 5 + ); + }) + ) + return 6; } - return button.link===1?1:0; + return button.link === 1 ? 1 : 0; }, - backup(links,player){ + backup(links, player) { return { - num:links[0], - audio:'sbfangzhu', - filterCard:()=>false, - selectCard:-1, - filterTarget(card,player,target){ - if(target==player) return false; - const num=lib.skill.mbcmfangzhu_backup.num,storage=target.getStorage('mbcmfangzhu_ban'); - return num!=1||!storage.length; + num: links[0], + audio: "sbfangzhu", + filterCard: () => false, + selectCard: -1, + filterTarget(card, player, target) { + if (target == player) return false; + const num = lib.skill.mbcmfangzhu_backup.num, + storage = target.getStorage("mbcmfangzhu_ban"); + return num != 1 || !storage.length; }, - async content(event,trigger,player){ - const target=event.target; - const num=lib.skill.mbcmfangzhu_backup.num; - switch(num){ + async content(event, trigger, player) { + const target = event.target; + const num = lib.skill.mbcmfangzhu_backup.num; + switch (num) { case 1: - target.addTempSkill('mbcmfangzhu_ban',{player:'phaseEnd'}); - target.markAuto('mbcmfangzhu_ban',['trick']); + target.addTempSkill("mbcmfangzhu_ban", { player: "phaseEnd" }); + target.markAuto("mbcmfangzhu_ban", ["trick"]); break; case 2: - target.addTempSkill('mbcmfangzhu_baiban',{player:'phaseEnd'}); + target.addTempSkill("mbcmfangzhu_baiban", { player: "phaseEnd" }); break; } }, - ai:{ - result:{ - target(player,target){ - switch(lib.skill.mbcmfangzhu_backup.num){ + ai: { + result: { + target(player, target) { + switch (lib.skill.mbcmfangzhu_backup.num) { case 1: - return -target.countCards('h',card=>get.type(card)!='trick')-1; + return ( + -target.countCards( + "h", + (card) => get.type(card) != "trick" + ) - 1 + ); case 2: - return -target.getSkills(null,null,false).reduce((sum,skill)=>{ - return sum+Math.max(get.skillRank(skill,'out'),get.skillRank(skill,'in')); - },0); + return -target + .getSkills(null, null, false) + .reduce((sum, skill) => { + return ( + sum + + Math.max( + get.skillRank(skill, "out"), + get.skillRank(skill, "in") + ) + ); + }, 0); } }, }, }, - } + }; }, - prompt(links,player){ - const str='###放逐###'; - switch(links[0]){ + prompt(links, player) { + const str = "###放逐###"; + switch (links[0]) { case 1: - return str+'令一名其他角色不能使用手牌中的非锦囊牌直到其回合结束'; + return str + "令一名其他角色不能使用手牌中的非锦囊牌直到其回合结束"; case 2: - return str+'令一名其他角色的非Charlotte技能失效直到其回合结束'; + return str + "令一名其他角色的非Charlotte技能失效直到其回合结束"; } - } + }, }, - ai:{ - order:10, - result:{ - player(player){ - return game.hasPlayer(current=>get.attitude(player,current)<0)?1:0; + ai: { + order: 10, + result: { + player(player) { + return game.hasPlayer((current) => get.attitude(player, current) < 0) ? 1 : 0; }, }, }, - subSkill:{ - backup:{}, - baiban:{ - inherit:'baiban', - marktext:'逐', + subSkill: { + backup: {}, + baiban: { + inherit: "baiban", + marktext: "逐", }, - ban:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'禁', - intro:{ - markcount:()=>0, - content(storage){ - if(storage.length>1) return '不能使用手牌'; - return '不能使用手牌中的非'+get.translation(storage[0])+'牌'; + ban: { + charlotte: true, + onremove: true, + mark: true, + marktext: "禁", + intro: { + markcount: () => 0, + content(storage) { + if (storage.length > 1) return "不能使用手牌"; + return "不能使用手牌中的非" + get.translation(storage[0]) + "牌"; }, }, - mod:{ - cardEnabled(card,player){ - const storage=player.getStorage('mbcmfangzhu_ban'); - const hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - if(cards.containsSome(...hs)&&!storage.includes(get.type2(card))) return false; + mod: { + cardEnabled(card, player) { + const storage = player.getStorage("mbcmfangzhu_ban"); + const hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + if (cards.containsSome(...hs) && !storage.includes(get.type2(card))) + return false; }, - cardSavable(card,player){ - const storage=player.getStorage('mbcmfangzhu_ban'); - const hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - if(cards.containsSome(...hs)&&!storage.includes(get.type2(card))) return false; + cardSavable(card, player) { + const storage = player.getStorage("mbcmfangzhu_ban"); + const hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + if (cards.containsSome(...hs) && !storage.includes(get.type2(card))) + return false; }, }, }, }, }, - mbjuejin:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filterCard:()=>false, - selectCard:[-1,-2], - filterTarget:true, - selectTarget:-1, - multiline:true, - async contentBefore(event,trigger,player){ - player.awakenSkill('mbjuejin'); + mbjuejin: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filterCard: () => false, + selectCard: [-1, -2], + filterTarget: true, + selectTarget: -1, + multiline: true, + async contentBefore(event, trigger, player) { + player.awakenSkill("mbjuejin"); }, - async content(event,trigger,player){ + async content(event, trigger, player) { const target = event.target; - const delt = target.getHp(true) - 1, num = Math.abs(delt); - await target[delt > 0 ? 'loseHp' : 'recover'](num); - if (num > 0) await target.changeHujia(num, null ,true); + const delt = target.getHp(true) - 1, + num = Math.abs(delt); + await target[delt > 0 ? "loseHp" : "recover"](num); + if (num > 0) await target.changeHujia(num, null, true); }, - async contentAfter(event,trigger,player){ - game.addGlobalSkill('mbjuejin_xiangsicunwei'); - player.$fullscreenpop('向死存魏!', 'thunder'); + async contentAfter(event, trigger, player) { + game.addGlobalSkill("mbjuejin_xiangsicunwei"); + player.$fullscreenpop("向死存魏!", "thunder"); }, - ai:{ - order:0.1, - result:{ - player(player){ - let eff=1; - game.countPlayer(current=>{ - const att=get.attitude(player,current),num=Math.abs(current.getHp(true)-1); - const delt=Math.max(0,num+current.hujia-5); - eff-=att*delt; + ai: { + order: 0.1, + result: { + player(player) { + let eff = 1; + game.countPlayer((current) => { + const att = get.attitude(player, current), + num = Math.abs(current.getHp(true) - 1); + const delt = Math.max(0, num + current.hujia - 5); + eff -= att * delt; }); - return eff>0?1:0; + return eff > 0 ? 1 : 0; }, }, }, - subSkill:{ - xiangsicunwei:{ - trigger:{ - global:['loseAfter','equipAfter','loseAsyncAfter','cardsDiscardAfter'], + subSkill: { + xiangsicunwei: { + trigger: { + global: ["loseAfter", "equipAfter", "loseAsyncAfter", "cardsDiscardAfter"], }, - forced:true, - silent:true, - firstDo:true, - filter(event,player){ - const nameList=['shan','tao','jiu']; - return event.getd().some(card=>{ - return nameList.includes(get.name(card,false))&&get.position(card,true)==='d'; + forced: true, + silent: true, + firstDo: true, + filter(event, player) { + const nameList = ["shan", "tao", "jiu"]; + return event.getd().some((card) => { + return ( + nameList.includes(get.name(card, false)) && + get.position(card, true) === "d" + ); }); }, - async content(event,trigger,player){ - const nameList = ['shan','tao','jiu']; - const cards = trigger.getd().filter(card => { - return nameList.includes(get.name(card, false)) && get.position(card, true) === 'd'; + async content(event, trigger, player) { + const nameList = ["shan", "tao", "jiu"]; + const cards = trigger.getd().filter((card) => { + return ( + nameList.includes(get.name(card, false)) && + get.position(card, true) === "d" + ); }); await game.cardsGotoSpecial(cards); - game.log(cards, '被移出了游戏'); - } + game.log(cards, "被移出了游戏"); + }, }, }, }, //杨奉 - mbxuetu:{ - audio:2, - audioname:['re_yangfeng'], - enable:'phaseUse', - usable:2, - filter(event,player){ - if (player.countMark('mbxuetu_status') !== 1 && player.getStat('skill').mbxuetu) return false; - if (!player.storage.mbxuetu) return player.countCards('he'); + mbxuetu: { + audio: 2, + audioname: ["re_yangfeng"], + enable: "phaseUse", + usable: 2, + filter(event, player) { + if (player.countMark("mbxuetu_status") !== 1 && player.getStat("skill").mbxuetu) + return false; + if (!player.storage.mbxuetu) return player.countCards("he"); return true; }, - zhuanhuanji2(skill, player){ - return player.countMark('mbxuetu_status') !== 1; + zhuanhuanji2(skill, player) { + return player.countMark("mbxuetu_status") !== 1; }, - filterCard(card,player){ - if (player.countMark('mbxuetu_status') > 1) return false; - if (player.countMark('mbxuetu_status') === 1) { - if (player.getStorage('mbxuetu_used').includes(false)) return false; + filterCard(card, player) { + if (player.countMark("mbxuetu_status") > 1) return false; + if (player.countMark("mbxuetu_status") === 1) { + if (player.getStorage("mbxuetu_used").includes(false)) return false; return true; } return !player.storage.mbxuetu; }, - selectCard(){ + selectCard() { const player = get.player(); - if (player.countMark('mbxuetu_status') > 1) return -1; - if (player.countMark('mbxuetu_status') === 1) { - if (player.getStorage('mbxuetu_used').includes(false)) return -1; - if (player.getStorage('mbxuetu_used').includes(true)) return 1; - return [0,1]; + if (player.countMark("mbxuetu_status") > 1) return -1; + if (player.countMark("mbxuetu_status") === 1) { + if (player.getStorage("mbxuetu_used").includes(false)) return -1; + if (player.getStorage("mbxuetu_used").includes(true)) return 1; + return [0, 1]; } return !player.storage.mbxuetu ? 1 : -1; }, - check(card){ - return 6-get.value(card); + check(card) { + return 6 - get.value(card); }, - prompt(){ - const player = get.player(), storage = player.storage.mbxuetu, status = player.countMark('mbxuetu_status'); + prompt() { + const player = get.player(), + storage = player.storage.mbxuetu, + status = player.countMark("mbxuetu_status"); if (status === 0) { - if (storage) return '转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。'; - return '转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。'; - } - else if (status === 1) { - return '出牌阶段各限一次。⒈你可以弃置一张牌,然后令一名角色回复1点体力;⒉你可以失去1点体力,然后令一名角色摸两张牌。'; - } - else { - if (storage) return '转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。'; - return '转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。'; + if (storage) + return "转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。"; + return "转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。"; + } else if (status === 1) { + return "出牌阶段各限一次。⒈你可以弃置一张牌,然后令一名角色回复1点体力;⒉你可以失去1点体力,然后令一名角色摸两张牌。"; + } else { + if (storage) + return "转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。"; + return "转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。"; } }, - position:'he', - filterTarget:true, - onremove:['mbxuetu','mbxuetu_status'], - derivation:['mbxuetu_achieve','mbxuetu_fail'], - async content(event,trigger,player){ - const target = event.targets[0], storage = Boolean(player.storage.mbxuetu); - const status = player.countMark('mbxuetu_status'); - player.changeZhuanhuanji('mbxuetu'); + position: "he", + filterTarget: true, + onremove: ["mbxuetu", "mbxuetu_status"], + derivation: ["mbxuetu_achieve", "mbxuetu_fail"], + async content(event, trigger, player) { + const target = event.targets[0], + storage = Boolean(player.storage.mbxuetu); + const status = player.countMark("mbxuetu_status"); + player.changeZhuanhuanji("mbxuetu"); if (status < 2) { if (!player.storage.mbxuetu_used) { - player.when(['phaseUseAfter', 'mbweiming_achieveAfter']).then(() => { + player.when(["phaseUseAfter", "mbweiming_achieveAfter"]).then(() => { delete player.storage.mbxuetu_used; }); } - player.markAuto('mbxuetu_used',[status===0?storage:(!event.cards.length)]); - if (status === 0 && !storage || status === 1 && event.cards.length) { + player.markAuto("mbxuetu_used", [status === 0 ? storage : !event.cards.length]); + if ((status === 0 && !storage) || (status === 1 && event.cards.length)) { await target.recover(); - } - else { + } else { await player.loseHp(); await target.draw(2); } - } - else { + } else { if (!storage) { await player.recover(); - await target.chooseToDiscard(2,true,'he'); - } - else { + await target.chooseToDiscard(2, true, "he"); + } else { await player.draw(); await target.damage(); } } }, - mark:true, - marktext:'☯', - intro:{ - content:(storage,player)=>{ - if (!player.countMark('mbxuetu_status')) { - if (storage) return '转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。'; - return '转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。'; + mark: true, + marktext: "☯", + intro: { + content: (storage, player) => { + if (!player.countMark("mbxuetu_status")) { + if (storage) + return "转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。"; + return "转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。"; + } else { + if (storage) + return "转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。"; + return "转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。"; } - else { - if (storage) return '转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。'; - return '转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。'; - } - } + }, }, - ai:{ - order(item,player){ - const status = player.countMark('mbxuetu_status'); - if (status > 1) return Math.max(get.order({ name: 'guohe' }), get.order({ name: 'chuqibuyi' })); + ai: { + order(item, player) { + const status = player.countMark("mbxuetu_status"); + if (status > 1) + return Math.max(get.order({ name: "guohe" }), get.order({ name: "chuqibuyi" })); if (status === 1 || player.storage.mbxuetu) return 9; return 2; }, - result:{ - target(player,target){ - const status = player.countMark('mbxuetu_status'); + result: { + target(player, target) { + const status = player.countMark("mbxuetu_status"); if (status > 1) { - if (player.storage.mbxuetu) return -get.damageEffect(target, player, player) / 10; + if (player.storage.mbxuetu) + return -get.damageEffect(target, player, player) / 10; return -2; } - if (status === 0 && player.storage.mbxuetu || status === 1 && !ui.selected.cards.length) return 2; + if ( + (status === 0 && player.storage.mbxuetu) || + (status === 1 && !ui.selected.cards.length) + ) + return 2; const eff = get.recoverEffect(target, player, player); - return eff > 0 ? 2 : (eff < 0 ? -get.sgnAttitude(player, target) : 0); + return eff > 0 ? 2 : eff < 0 ? -get.sgnAttitude(player, target) : 0; }, - player(player,target){ - const status = player.countMark('mbxuetu_status'); + player(player, target) { + const status = player.countMark("mbxuetu_status"); if (status > 1) { if (player.storage.mbxuetu) return 1; return get.recoverEffect(player, player) / 6; } if (status === 1 || !player.storage.mbxuetu) return -0.5; - const eff = get.effect(player, {name: 'losehp'}, player, player); + const eff = get.effect(player, { name: "losehp" }, player, player); if (eff >= 0) return Math.min(1, eff / 2); - const hp = player.getHp() + player.countCards('hes', card => { - return player.canSaveCard(card, player); - }); + const hp = + player.getHp() + + player.countCards("hes", (card) => { + return player.canSaveCard(card, player); + }); return -1.5 * Math.max(0, 3 - hp); }, }, }, }, - mbweiming:{ - audio:3, - dutySkill:true, - locked:true, - group:['mbweiming_achieve', 'mbweiming_fail','mbweiming_effect'], - intro:{ - content: '已记录$', + mbweiming: { + audio: 3, + dutySkill: true, + locked: true, + group: ["mbweiming_achieve", "mbweiming_fail", "mbweiming_effect"], + intro: { + content: "已记录$", }, subSkill: { - effect:{ - audio:'mbweiming1.mp3', - trigger:{ - player:'phaseUseBegin', + effect: { + audio: "mbweiming1.mp3", + trigger: { + player: "phaseUseBegin", }, - filter(event,player){ - return game.hasPlayer(current => { - return !player.getStorage('mbweiming').includes(current); + filter(event, player) { + return game.hasPlayer((current) => { + return !player.getStorage("mbweiming").includes(current); }); }, - forced:true, - direct:true, - async content(event, trigger, player){ - const targets = await player.chooseTarget('威命:记录一名未记录过的角色','当你杀死没有被记录过的角色后,则〖威命〗使命成功;如果在你杀死这些角色中的一名之前,有被记录过的角色死亡,则你〖威命〗使命失败。',true) - .set('filterTarget', (card, player, target) => { - return !player.getStorage('mbweiming').includes(target); + forced: true, + direct: true, + async content(event, trigger, player) { + const targets = await player + .chooseTarget( + "威命:记录一名未记录过的角色", + "当你杀死没有被记录过的角色后,则〖威命〗使命成功;如果在你杀死这些角色中的一名之前,有被记录过的角色死亡,则你〖威命〗使命失败。", + true + ) + .set("filterTarget", (card, player, target) => { + return !player.getStorage("mbweiming").includes(target); }) - .set('ai', target => { + .set("ai", (target) => { if (target === player) return 1; - return 1 + Math.sqrt(Math.abs(get.attitude(player, target))) * Math.abs(get.threaten(target)) / Math.sqrt(target.getHp() + 1) / Math.sqrt(target.countCards('hes') + 1); + return ( + 1 + + (Math.sqrt(Math.abs(get.attitude(player, target))) * + Math.abs(get.threaten(target))) / + Math.sqrt(target.getHp() + 1) / + Math.sqrt(target.countCards("hes") + 1) + ); }) .forResultTargets(); if (targets && targets.length > 0) { const target = targets[0]; - player.logSkill('mbweiming_effect', target); - player.markAuto('mbweiming', target); + player.logSkill("mbweiming_effect", target); + player.markAuto("mbweiming", target); } }, }, achieve: { - audio:'mbweiming2.mp3', - trigger:{ - source:'dieAfter', + audio: "mbweiming2.mp3", + trigger: { + source: "dieAfter", }, - filter(event,player){ - return !player.getStorage('mbweiming').includes(event.player); + filter(event, player) { + return !player.getStorage("mbweiming").includes(event.player); }, - dutySkill:true, - forced:true, - skillAnimation:true, - animationColor:'fire', - async content(event, trigger, player){ - game.log(player,'成功完成使命'); - player.awakenSkill('mbweiming'); + dutySkill: true, + forced: true, + skillAnimation: true, + animationColor: "fire", + async content(event, trigger, player) { + game.log(player, "成功完成使命"); + player.awakenSkill("mbweiming"); player.storage.mbxuetu_status = 1; - player.unmarkSkill('mbxuetu'); + player.unmarkSkill("mbxuetu"); await game.asyncDelayx(); - } + }, }, fail: { - audio:'mbweiming3.mp3', - trigger:{ - global:'dieAfter', + audio: "mbweiming3.mp3", + trigger: { + global: "dieAfter", }, - filter(event,player){ - return player.getStorage('mbweiming').includes(event.player); + filter(event, player) { + return player.getStorage("mbweiming").includes(event.player); }, - dutySkill:true, - forced:true, - async content(event, trigger, player){ - game.log(player,'使命失败'); - player.awakenSkill('mbweiming'); + dutySkill: true, + forced: true, + async content(event, trigger, player) { + game.log(player, "使命失败"); + player.awakenSkill("mbweiming"); player.storage.mbxuetu_status = 2; - game.broadcastAll(player=>{ - player.tempname.add('re_yangfeng'); - },player); + game.broadcastAll((player) => { + player.tempname.add("re_yangfeng"); + }, player); await game.asyncDelayx(); - } + }, }, }, + ai: { + combo: "mbxuetu" + }, }, //霍骏 - sidai:{ - audio:'twsidai', - enable:'phaseUse', - usable:1, - locked:false, - limited:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - var cards=player.getCards('h',{type:'basic'}); - if(!cards.length) return false; - for(var i of cards){ - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) return false; + sidai: { + audio: "twsidai", + enable: "phaseUse", + usable: 1, + locked: false, + limited: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + var cards = player.getCards("h", { type: "basic" }); + if (!cards.length) return false; + for (var i of cards) { + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false; } - return event.filterCard(get.autoViewAs({name:'sha',storage:{sidai:true}},cards),player,event); + return event.filterCard( + get.autoViewAs({ name: "sha", storage: { sidai: true } }, cards), + player, + event + ); }, - viewAs:{name:'sha',storage:{sidai:true}}, - filterCard:{type:'basic'}, - selectCard:-1, - check:()=>1, - onuse:function(result,player){ - player.awakenSkill('sidai'); - player.addTempSkill('sidai_tao'); - player.addTempSkill('sidai_shan'); + viewAs: { name: "sha", storage: { sidai: true } }, + filterCard: { type: "basic" }, + selectCard: -1, + check: () => 1, + onuse: function (result, player) { + player.awakenSkill("sidai"); + player.addTempSkill("sidai_tao"); + player.addTempSkill("sidai_shan"); }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'},player)+0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }, player) + 0.1; }, - result:{ - target:function(player,target){ - var cards=ui.selected.cards.slice(0); - var names=[]; - for(var i of cards) names.add(i.name); - if(names.length=0) return -20; - return lib.card.sha.ai.result.target.apply(this,arguments); + result: { + target: function (player, target) { + var cards = ui.selected.cards.slice(0); + var names = []; + for (var i of cards) names.add(i.name); + if (names.length < player.hp) return 0; + if (player.hasUnknown() && (player.identity != "fan" || !target.isZhu)) return 0; + if (get.attitude(player, target) >= 0) return -20; + return lib.card.sha.ai.result.target.apply(this, arguments); }, }, }, - subSkill:{ - tao:{ - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.sidai||!event.player.isIn()) return false; - for(var i of event.cards){ - if(i.name=='tao') return true; + subSkill: { + tao: { + trigger: { source: "damageSource" }, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.sidai || + !event.player.isIn() + ) + return false; + for (var i of event.cards) { + if (i.name == "tao") return true; } return false; }, - forced:true, - popup:false, - content:function(){ + forced: true, + popup: false, + content: function () { trigger.player.loseMaxHp(); }, }, - shan:{ - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.sidai||!event.target.isIn()) return false; - for(var i of event.cards){ - if(i.name=='shan') return true; + shan: { + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.sidai || + !event.target.isIn() + ) + return false; + for (var i of event.cards) { + if (i.name == "shan") return true; } return false; }, - forced:true, - popup:false, - content:function(){ - 'step 0' - trigger.target.chooseToDiscard('h',{type:'basic'},'弃置一张基本牌,否则不能响应'+get.translation(trigger.card)).set('ai',function(card){ - var player=_status.event.player; - if(player.hasCard('hs',function(cardx){ - return cardx!=card&&get.name(cardx,player)=='shan'; - })) return 12-get.value(card); - return 0; - }); - 'step 1' - if(!result.bool) trigger.directHit.add(trigger.target); + forced: true, + popup: false, + content: function () { + "step 0"; + trigger.target + .chooseToDiscard( + "h", + { type: "basic" }, + "弃置一张基本牌,否则不能响应" + get.translation(trigger.card) + ) + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.hasCard("hs", function (cardx) { + return cardx != card && get.name(cardx, player) == "shan"; + }) + ) + return 12 - get.value(card); + return 0; + }); + "step 1"; + if (!result.bool) trigger.directHit.add(trigger.target); }, }, }, }, - jieyu:{ - audio:'twjieyu', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - for(let i=0;i1?'牌名各不相同的':'')+'基本牌'; + prompt2: function (event, player) { + const num = lib.skill.jieyu.getNum(player); + return ( + "获得弃牌堆中" + + get.cnNumber(num) + + "张" + + (num > 1 ? "牌名各不相同的" : "") + + "基本牌" + ); }, - async content(event,trigger,player){ - const num=lib.skill.jieyu.getNum(player,event); - let gains=[],names=[]; - for(let i=0;i=0;i--){ - const evt=history[i]; - if(evt.name=='jieyu'&&evt.player==player){ - if(!event||evt!=event) break; + getNum: function (player, event) { + let num = get.mode() == "identity" ? 3 : 4; + const history = game.getAllGlobalHistory("everything"); + for (let i = history.length - 1; i >= 0; i--) { + const evt = history[i]; + if (evt.name == "jieyu" && evt.player == player) { + if (!event || evt != event) break; } - if(evt.name=='useCard'&&evt.player!=player&&evt.targets&&evt.targets.includes(player)&&get.tag(evt.card,'damage')){ + if ( + evt.name == "useCard" && + evt.player != player && + evt.targets && + evt.targets.includes(player) && + get.tag(evt.card, "damage") + ) { num--; - if(num==1) break; + if (num == 1) break; } } return num; }, }, //木鹿大王 - shoufa:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + shoufa: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter:function(event,player,name){ - if(name=='damageSource'&&player.getHistory('sourceDamage').indexOf(event)!=0) return false; - return game.hasPlayer(target=>{ - if(get.mode()!='doudizhu'){ - if(name=='damageEnd'&&get.distance(player,target)<=2) return false; - if(name=='damageSource'&&get.distance(player,target)>2) return false; - } - const zhoufa=player.storage.zhoulin_zhoufa; - if(!zhoufa) return true; - if(zhoufa=='豹'||zhoufa=='兔') return true; - if(zhoufa=='鹰') return target.countCards('he'); - return target.countDiscardableCards(player,'e'); + filter: function (event, player, name) { + if (name == "damageSource" && player.getHistory("sourceDamage").indexOf(event) != 0) + return false; + return game.hasPlayer((target) => { + const num = (get.mode() == 'doudizhu' ? 1 : 2); + if (name == "damageEnd" && get.distance(player, target) <= num) return false; + if (name == "damageSource" && get.distance(player, target) > num) return false; + const zhoufa = player.storage.zhoulin_zhoufa; + if (!zhoufa) return true; + if (zhoufa == "豹" || zhoufa == "兔") return true; + if (zhoufa == "鹰") return target.countCards("he"); + return target.countDiscardableCards(player, "e"); }); }, - direct:true, - async content(event,trigger,player){ - const zhoufa=player.storage.zhoulin_zhoufa; - const str=zhoufa?[ - '令其受到1点无来源伤害', - '你随机获得其一张牌', - '你随机弃置其装备区的一张牌', - '令其摸一张牌', - ][['豹','鹰','熊','兔'].indexOf(zhoufa)]:'令其随机执行一个效果'; - const nodoudizhu=(get.mode()=='doudizhu'?'':('距离'+(event.triggername=='damageEnd'?'':'不')+'大于2的')); - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('shoufa'),'选择一名'+nodoudizhu+'角色,'+str,(card,player,target)=>{ - const name=_status.event.triggername; - if(get.mode()!='doudizhu'){ - if(name=='damageEnd'&&get.distance(player,target)<=2) return false; - if(name=='damageSource'&&get.distance(player,target)>2) return false; - } - const zhoufa=player.storage.zhoulin_zhoufa; - if(!zhoufa) return true; - if(zhoufa=='豹'||zhoufa=='兔') return true; - if(zhoufa=='鹰') return target.countCards('he'); - return target.countDiscardableCards(player,'e'); - }).set('ai',target=>{ - const player=_status.event.player; - const zhoufa=player.storage.zhoulin_zhoufa; - if(!zhoufa) return -get.attitude(player,target); - switch(zhoufa){ - case '豹': - return get.damageEffect(target,player,player); - case '鹰': - return get.effect(target,{name:'guohe_copy2'},player,player); - case '熊': - let att=get.attitude(player,target),eff=0; - target.getCards('e',card=>{ - var val=get.value(card,target); - eff=Math.max(eff,-val*att); - }); - return eff; - case '兔': - return get.effect(target,{name:'draw'},player,player); - } - }).set('triggername',event.triggername); - if(!bool) return; - const target=targets[0]; - player.logSkill('shoufa',target); - const shoufa=zhoufa?zhoufa:['豹','鹰','熊','兔'].randomGet(); - game.log(target,'执行','#g'+shoufa,'效果'); - switch(shoufa){ - case '豹': - target.damage('nosource'); + direct: true, + async content(event, trigger, player) { + const zhoufa = player.storage.zhoulin_zhoufa; + const str = zhoufa + ? [ + "令其受到1点无来源伤害", + "你随机获得其一张牌", + "你随机弃置其装备区的一张牌", + "令其摸一张牌", + ][["豹", "鹰", "熊", "兔"].indexOf(zhoufa)] + : "令其随机执行一个效果"; + const nodoudizhu = + get.mode() == "doudizhu" + ? "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于1的" + : "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于2的"; + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("shoufa"), + "选择一名" + nodoudizhu + "角色," + str, + (card, player, target) => { + const name = _status.event.triggername; + const num = (get.mode() == 'doudizhu' ? 1 : 2); + if (name == "damageEnd" && get.distance(player, target) <= num) return false; + if (name == "damageSource" && get.distance(player, target) > num) return false; + const zhoufa = player.storage.zhoulin_zhoufa; + if (!zhoufa) return true; + if (zhoufa == "豹" || zhoufa == "兔") return true; + if (zhoufa == "鹰") return target.countCards("he"); + return target.countDiscardableCards(player, "e"); + } + ) + .set("ai", (target) => { + const player = _status.event.player; + const zhoufa = player.storage.zhoulin_zhoufa; + if (!zhoufa) return -get.attitude(player, target); + switch (zhoufa) { + case "豹": + return get.damageEffect(target, player, player); + case "鹰": + return get.effect(target, { name: "guohe_copy2" }, player, player); + case "熊": + let att = get.attitude(player, target), + eff = 0; + target.getCards("e", (card) => { + var val = get.value(card, target); + eff = Math.max(eff, -val * att); + }); + return eff; + case "兔": + return get.effect(target, { name: "draw" }, player, player); + } + }) + .set("triggername", event.triggername); + if (!bool) return; + const target = targets[0]; + player.logSkill("shoufa", target); + const shoufa = zhoufa ? zhoufa : ["豹", "鹰", "熊", "兔"].randomGet(); + game.log(target, "执行", "#g" + shoufa, "效果"); + switch (shoufa) { + case "豹": + target.damage("nosource"); break; - case '鹰': - player.gain(target.getGainableCards(player,'he').randomGet(),target,'giveAuto'); + case "鹰": + player.gain( + target.getGainableCards(player, "he").randomGet(), + target, + "giveAuto" + ); break; - case '熊': - target.discard(target.getGainableCards(player,'e').randomGet()).discarder=player; + case "熊": + target.discard(target.getGainableCards(player, "e").randomGet()).discarder = + player; break; - case '兔': + case "兔": target.draw(); break; } }, }, - yuxiang:{ - mod:{ - globalFrom(from,to,distance){ - if(from.hujia>0) return distance-1; + yuxiang: { + mod: { + globalFrom(from, to, distance) { + if (from.hujia > 0) return distance - 1; }, - globalTo(from,to,distance){ - if(to.hujia>0) return distance+1; + globalTo(from, to, distance) { + if (to.hujia > 0) return distance + 1; }, }, - audio:true, - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - return player.hujia>0&&event.hasNature('fire'); + audio: true, + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + return player.hujia > 0 && event.hasNature("fire"); }, - forced:true, - async content(event,trigger,player){ + forced: true, + async content(event, trigger, player) { trigger.num++; }, }, - zhoulin:{ - audio:2, - limited:true, - unique:true, - enable:'phaseUse', - skillAnimation:true, - animationColor:'fire', - async content(event,trigger,player){ - player.awakenSkill('zhoulin'); - player.changeHujia(2,null,true); - const {result:{control}}=await player.chooseControl('豹','鹰','熊','兔').set('ai',()=>'豹').set('prompt','选择一个固定效果'); - if(control){ + zhoulin: { + audio: 2, + limited: true, + unique: true, + enable: "phaseUse", + skillAnimation: true, + animationColor: "fire", + async content(event, trigger, player) { + player.awakenSkill("zhoulin"); + player.changeHujia(2, null, true); + const { + result: { control }, + } = await player + .chooseControl("豹", "鹰", "熊", "兔") + .set("ai", () => "豹") + .set("prompt", "选择一个固定效果"); + if (control) { player.popup(control); - game.log(player,'选择了','#g'+control,'效果'); - player.addTempSkill('zhoulin_zhoufa'); - player.storage.zhoulin_zhoufa=control; - player.markSkill('zhoulin_zhoufa'); - game.broadcastAll(function(player,zhoufa){ - if(player.marks.zhoulin_zhoufa) player.marks.zhoulin_zhoufa.firstChild.innerHTML=zhoufa; - },player,control); + game.log(player, "选择了", "#g" + control, "效果"); + player.addTempSkill("zhoulin_zhoufa"); + player.storage.zhoulin_zhoufa = control; + player.markSkill("zhoulin_zhoufa"); + game.broadcastAll( + function (player, zhoufa) { + if (player.marks.zhoulin_zhoufa) + player.marks.zhoulin_zhoufa.firstChild.innerHTML = zhoufa; + }, + player, + control + ); } }, - ai:{ - order:12, - result:{player:1}, + ai: { + order: 12, + result: { player: 1 }, }, - subSkill:{ - zhoufa:{ - charlotte:true, - onremove:true, - intro:{content:'已选择$效果'}, + subSkill: { + zhoufa: { + charlotte: true, + onremove: true, + intro: { content: "已选择$效果" }, }, - } + }, }, //陈珪 - guimou:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:['enterGame','phaseEnd','phaseZhunbeiBegin'], + guimou: { + audio: 2, + trigger: { + global: "phaseBefore", + player: ["enterGame", "phaseEnd", "phaseZhunbeiBegin"], }, - filter:function(event,player,name){ - if(event.name=='phaseZhunbei'||name=='phaseEnd') return true; - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player, name) { + if (event.name == "phaseZhunbei" || name == "phaseEnd") return true; + return event.name != "phase" || game.phaseNumber == 0; }, - direct:true, - locked:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - if(trigger.name!='phaseZhunbei'){ - player.logSkill('guimou'); - var result,choiceList=[ - '惩罚期间使用牌最少的角色', - '惩罚期间弃置牌最少的角色', - '惩罚期间得到牌最少的角色', - ]; - if(trigger.name!='phase'||game.phaseNumber==0) result={index:get.rand(0,2)}; - else result=yield player.chooseControl().set('choiceList',choiceList).set('ai',()=>get.rand(0,2)); - var str=choiceList[result.index]; - game.log(player,'选择','#g'+str); - player.addSkill('guimou_'+result.index); + direct: true, + locked: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger; + if (trigger.name != "phaseZhunbei") { + player.logSkill("guimou"); + var result, + choiceList = [ + "惩罚期间使用牌最少的角色", + "惩罚期间弃置牌最少的角色", + "惩罚期间得到牌最少的角色", + ]; + if (trigger.name != "phase" || game.phaseNumber == 0) + result = { index: get.rand(0, 2) }; + else + result = yield player + .chooseControl() + .set("choiceList", choiceList) + .set("ai", () => get.rand(0, 2)); + var str = choiceList[result.index]; + game.log(player, "选择", "#g" + str); + player.addSkill("guimou_" + result.index); return; } - var targets=[]; - for(var i=0;i<=2;i++){ - var skill='guimou_'+i; - if(player.hasSkill(skill)){ - var storage=player.storage[skill],nums=storage[0].slice(); - var targetx=nums.sort((a,b)=>storage[1][storage[0].indexOf(a)]-storage[1][storage[0].indexOf(b)]); - targetx=targetx.filter(target=>storage[1][storage[0].indexOf(target)]==storage[1][storage[0].indexOf(targetx[0])]); + var targets = []; + for (var i = 0; i <= 2; i++) { + var skill = "guimou_" + i; + if (player.hasSkill(skill)) { + var storage = player.storage[skill], + nums = storage[0].slice(); + var targetx = nums.sort( + (a, b) => + storage[1][storage[0].indexOf(a)] - storage[1][storage[0].indexOf(b)] + ); + targetx = targetx.filter( + (target) => + storage[1][storage[0].indexOf(target)] == + storage[1][storage[0].indexOf(targetx[0])] + ); targets.addArray(targetx); player.removeSkill(skill); } } - targets=targets.filter(target=>target!=player&&target.countCards('h')); - if(targets.length){ - var result=yield player.chooseTarget('请选择【诡谋】的目标','观看一名可选择的角色的手牌并选择其中一张牌,然后你可以此牌交给另一名其他角色或弃置此牌',(card,player,target)=>{ - return _status.event.targets.includes(target)&&target.countCards('h'); - },true).set('ai',target=>{ - return Math.sqrt(Math.min(3,target.countCards('h')))*get.effect(target,{name:'guohe_copy2'},player,player); - }).set('targets',targets); - if(result.bool){ - var target=result.targets[0]; - player.logSkill('guimou',target); + targets = targets.filter((target) => target != player && target.countCards("h")); + if (targets.length) { + var result = yield player + .chooseTarget( + "请选择【诡谋】的目标", + "观看一名可选择的角色的手牌并选择其中一张牌,然后你可以此牌交给另一名其他角色或弃置此牌", + (card, player, target) => { + return _status.event.targets.includes(target) && target.countCards("h"); + }, + true + ) + .set("ai", (target) => { + return ( + Math.sqrt(Math.min(3, target.countCards("h"))) * + get.effect(target, { name: "guohe_copy2" }, player, player) + ); + }) + .set("targets", targets); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("guimou", target); player.addExpose(0.3); - var result2=yield player.choosePlayerCard(target,'h','visible',true).set('ai',button=>{ - return get.value(button.link); - }).set('prompt','诡谋:请选择'+get.translation(target)+'的一张手牌').set('prompt2','
              将选择的牌交给另一名其他角色或弃置此牌
              '); - if(result2.bool){ - var cards=result2.links.slice(),result3; - if(!game.hasPlayer(targetx=>targetx!=player&&targetx!=target)) result3={bool:false}; - else result3=yield player.chooseTarget('是否令另一名其他角色获得'+get.translation(cards)+'?',(card,player,target)=>{ - return target!=player&&target!=_status.event.target; - }).set('ai',target=>get.attitude(_status.event.player,target)).set('target',target); - if(result3.bool){ - var targetx=result3.targets[0]; + var result2 = yield player + .choosePlayerCard(target, "h", "visible", true) + .set("ai", (button) => { + return get.value(button.link); + }) + .set("prompt", "诡谋:请选择" + get.translation(target) + "的一张手牌") + .set( + "prompt2", + '
              将选择的牌交给另一名其他角色或弃置此牌
              ' + ); + if (result2.bool) { + var cards = result2.links.slice(), + result3; + if (!game.hasPlayer((targetx) => targetx != player && targetx != target)) + result3 = { bool: false }; + else + result3 = yield player + .chooseTarget( + "是否令另一名其他角色获得" + get.translation(cards) + "?", + (card, player, target) => { + return target != player && target != _status.event.target; + } + ) + .set("ai", (target) => get.attitude(_status.event.player, target)) + .set("target", target); + if (result3.bool) { + var targetx = result3.targets[0]; player.line(targetx); - targetx.gain(cards,target,'give'); - } - else target.discard(cards).discarder=player; + targetx.gain(cards, target, "give"); + } else target.discard(cards).discarder = player; } } } }, - subSkill:{ - '0':{ - charlotte:true, - onremove:true, - init:function(player,skill){ - if(!player.storage[skill]){ - player.storage[skill]=[[],[]]; - var targets=game.filterPlayer().sortBySeat(player); - targets.forEach(target=>{ + subSkill: { + 0: { + charlotte: true, + onremove: true, + init: function (player, skill) { + if (!player.storage[skill]) { + player.storage[skill] = [[], []]; + var targets = game.filterPlayer().sortBySeat(player); + targets.forEach((target) => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, - mark:true, - intro:{ - markcount:storage=>0, - content:function(storage,player){ - var str='当前使用牌数排行榜'; - var lose=storage[1].slice().sort((a,b)=>a-b)[0]; - storage[0].forEach(target=>{ - str+='
            • '; - var score=storage[1][storage[0].indexOf(target)]; - if(score==lose) str+=''; - str+=(' '+get.translation(target)+' '); - str+=(score+'张'); - if(score==lose) str+=''; + mark: true, + intro: { + markcount: (storage) => 0, + content: function (storage, player) { + var str = "当前使用牌数排行榜"; + var lose = storage[1].slice().sort((a, b) => a - b)[0]; + storage[0].forEach((target) => { + str += "
            • "; + var score = storage[1][storage[0].indexOf(target)]; + if (score == lose) + str += ""; + str += " " + get.translation(target) + " "; + str += score + "张"; + if (score == lose) str += ""; }); return str; }, }, - trigger:{global:'useCard1'}, - forced:true, - popup:false, - content:function(){ - var storage=player.storage['guimou_0']; - if(!storage[0].includes(trigger.player)){ + trigger: { global: "useCard1" }, + forced: true, + popup: false, + content: function () { + var storage = player.storage["guimou_0"]; + if (!storage[0].includes(trigger.player)) { storage[0].push(trigger.player); storage[1].push(0); } storage[1][storage[0].indexOf(trigger.player)]++; }, }, - '1':{ - charlotte:true, - onremove:true, - init:function(player,skill){ - if(!player.storage[skill]){ - player.storage[skill]=[[],[]]; - var targets=game.filterPlayer().sortBySeat(player); - targets.forEach(target=>{ + 1: { + charlotte: true, + onremove: true, + init: function (player, skill) { + if (!player.storage[skill]) { + player.storage[skill] = [[], []]; + var targets = game.filterPlayer().sortBySeat(player); + targets.forEach((target) => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, - mark:true, - intro:{ - markcount:storage=>0, - content:function(storage,player){ - var str='当前弃置牌数排行榜'; - var lose=storage[1].slice().sort((a,b)=>a-b)[0]; - storage[0].forEach(target=>{ - str+='
            • '; - var score=storage[1][storage[0].indexOf(target)]; - if(score==lose) str+=''; - str+=(' '+get.translation(target)+' '); - str+=(score+'张'); - if(score==lose) str+=''; + mark: true, + intro: { + markcount: (storage) => 0, + content: function (storage, player) { + var str = "当前弃置牌数排行榜"; + var lose = storage[1].slice().sort((a, b) => a - b)[0]; + storage[0].forEach((target) => { + str += "
            • "; + var score = storage[1][storage[0].indexOf(target)]; + if (score == lose) + str += ""; + str += " " + get.translation(target) + " "; + str += score + "张"; + if (score == lose) str += ""; }); return str; }, }, - trigger:{global:['loseAfter','loseAsyncAfter']}, - filter:function (event,player){ - return event.type=='discard'&&game.hasPlayer(target=>event.getl(target).cards2.length); + trigger: { global: ["loseAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + return ( + event.type == "discard" && + game.hasPlayer((target) => event.getl(target).cards2.length) + ); }, - forced:true, - popup:false, - content:function(){ - var storage=player.storage['guimou_1']; - var targets=game.filterPlayer(target=>trigger.getl(target).cards2.length); - targets.forEach(target=>{ - if(!storage[0].includes(target)){ + forced: true, + popup: false, + content: function () { + var storage = player.storage["guimou_1"]; + var targets = game.filterPlayer((target) => trigger.getl(target).cards2.length); + targets.forEach((target) => { + if (!storage[0].includes(target)) { storage[0].push(target); storage[1].push(0); } - storage[1][storage[0].indexOf(target)]+=trigger.getl(target).cards2.length; + storage[1][storage[0].indexOf(target)] += trigger.getl(target).cards2.length; }); }, }, - '2':{ - charlotte:true, - onremove:true, - init:function(player,skill){ - if(!player.storage[skill]){ - player.storage[skill]=[[],[]]; - var targets=game.filterPlayer().sortBySeat(player); - targets.forEach(target=>{ + 2: { + charlotte: true, + onremove: true, + init: function (player, skill) { + if (!player.storage[skill]) { + player.storage[skill] = [[], []]; + var targets = game.filterPlayer().sortBySeat(player); + targets.forEach((target) => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, - mark:true, - intro:{ - markcount:storage=>0, - content:function(storage,player){ - var str='当前得到牌数排行榜'; - var lose=storage[1].slice().sort((a,b)=>a-b)[0]; - storage[0].forEach(target=>{ - str+='
            • '; - var score=storage[1][storage[0].indexOf(target)]; - if(score==lose) str+=''; - str+=(' '+get.translation(target)+' '); - str+=(score+'张'); - if(score==lose) str+=''; + mark: true, + intro: { + markcount: (storage) => 0, + content: function (storage, player) { + var str = "当前得到牌数排行榜"; + var lose = storage[1].slice().sort((a, b) => a - b)[0]; + storage[0].forEach((target) => { + str += "
            • "; + var score = storage[1][storage[0].indexOf(target)]; + if (score == lose) + str += ""; + str += " " + get.translation(target) + " "; + str += score + "张"; + if (score == lose) str += ""; }); return str; }, }, - trigger:{global:['gainAfter','loseAsyncAfter']}, - forced:true, - popup:false, - content:function(){ - var storage=player.storage['guimou_2']; - var targets=game.filterPlayer(target=>trigger.getg(target).length); - targets.forEach(target=>{ - if(!storage[0].includes(target)){ + trigger: { global: ["gainAfter", "loseAsyncAfter"] }, + forced: true, + popup: false, + content: function () { + var storage = player.storage["guimou_2"]; + var targets = game.filterPlayer((target) => trigger.getg(target).length); + targets.forEach((target) => { + if (!storage[0].includes(target)) { storage[0].push(target); storage[1].push(0); } - storage[1][storage[0].indexOf(target)]+=trigger.getg(target).length; + storage[1][storage[0].indexOf(target)] += trigger.getg(target).length; }); }, }, }, }, - zhouxian:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.player!=player&&get.tag(event.card,'damage'); + zhouxian: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return event.player != player && get.tag(event.card, "damage"); }, - forced:true, - logTarget:'player', - content:function*(event,map){ - var player=map.player,trigger=map.trigger,target=trigger.player; - var cards=get.cards(3); + forced: true, + logTarget: "player", + content: function* (event, map) { + var player = map.player, + trigger = map.trigger, + target = trigger.player; + var cards = get.cards(3); yield game.cardsDiscard(cards); - player.showCards(cards,get.translation(player)+'发动了【州贤】'); - var result=yield target.chooseToDiscard('he','州贤:弃置一张其中有的类别的牌,或令此牌对'+get.translation(player)+'无效',(card,player)=>{ - return _status.event.cards.some(cardx=>get.type2(cardx)==get.type2(card)); - }).set('cards',cards).set('ai',card=>{ - if(!_status.event.goon) return 0; - return 7.5-get.value(card); - }).set('goon',get.effect(player,trigger.card,target,target)>0); - if(!result.bool) trigger.getParent().excluded.add(player); + player.showCards(cards, get.translation(player) + "发动了【州贤】"); + var result = yield target + .chooseToDiscard( + "he", + "州贤:弃置一张其中有的类别的牌,或令此牌对" + get.translation(player) + "无效", + (card, player) => { + return _status.event.cards.some( + (cardx) => get.type2(cardx) == get.type2(card) + ); + } + ) + .set("cards", cards) + .set("ai", (card) => { + if (!_status.event.goon) return 0; + return 7.5 - get.value(card); + }) + .set("goon", get.effect(player, trigger.card, target, target) > 0); + if (!result.bool) trigger.getParent().excluded.add(player); }, - ai:{ - effect:{ - target_use:function(card,player,target,current){ - if(get.tag(card,'damage')&&get.attitude(player,target)<0&&target!=player){ - if(_status.event.name=='zhouxian') return; - if(get.attitude(player,target)>0&¤t<0) return 'zerotarget'; - var bs=player.getDiscardableCards(player,'he'); + ai: { + effect: { + target_use: function (card, player, target, current) { + if ( + get.tag(card, "damage") && + get.attitude(player, target) < 0 && + target != player + ) { + if (_status.event.name == "zhouxian") return; + if (get.attitude(player, target) > 0 && current < 0) return "zerotarget"; + var bs = player.getDiscardableCards(player, "he"); bs.remove(card); - if(card.cards) bs.removeArray(card.cards); + if (card.cards) bs.removeArray(card.cards); else bs.removeArray(ui.selected.cards); - var cardx=Array.from(ui.cardPile.childNodes).slice(0,3); - bs=bs.filter(i=>cardx.some(j=>get.type2(j)==get.type2(i))); - if(!bs.length) return 'zerotarget'; - if(bs.length<=2){ - if(bs.some(bsi=>get.value(bsi)<7)) return [1,0,1,-0.5]; - return [1,0,0.3,0]; + var cardx = Array.from(ui.cardPile.childNodes).slice(0, 3); + bs = bs.filter((i) => cardx.some((j) => get.type2(j) == get.type2(i))); + if (!bs.length) return "zerotarget"; + if (bs.length <= 2) { + if (bs.some((bsi) => get.value(bsi) < 7)) return [1, 0, 1, -0.5]; + return [1, 0, 0.3, 0]; } - return [1,0,1,-0.5]; + return [1, 0, 1, -0.5]; } }, }, }, }, //胡班 - mbyilie:{ - audio:3, - trigger:{global:'phaseBefore',player:'enterGame'}, - filter:function(event,player){ - return !player.storage.mbyilie2&&(event.name!='phase'||game.phaseNumber==0); + mbyilie: { + audio: 3, + trigger: { global: "phaseBefore", player: "enterGame" }, + filter: function (event, player) { + return !player.storage.mbyilie2 && (event.name != "phase" || game.phaseNumber == 0); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('mbyilie'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return Math.max(1+get.attitude(player,target)*get.threaten(target),Math.random()); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mbyilie',target); - player.storage.mbyilie2=target; - player.addSkill('mbyilie2'); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("mbyilie"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + return Math.max( + 1 + get.attitude(player, target) * get.threaten(target), + Math.random() + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mbyilie", target); + player.storage.mbyilie2 = target; + player.addSkill("mbyilie2"); } }, - marktext:'烈', - intro:{ - name2:'烈', - content:'mark', + marktext: "烈", + intro: { + name2: "烈", + content: "mark", }, - group:'mbyilie3', + group: "mbyilie3", }, - mbyilie2:{ - charlotte:true, - audio:'mbyilie', - trigger:{global:['damageBegin4','damageSource']}, - filter:function(event,player,name){ - var target=player.storage.mbyilie2; - if(name=='damageSource') return event.source==target&&event.player!=target&&player.isDamaged(); - return event.player==target&&player.countMark('mbyilie')<2; + mbyilie2: { + charlotte: true, + audio: "mbyilie", + trigger: { global: ["damageBegin4", "damageSource"] }, + filter: function (event, player, name) { + var target = player.storage.mbyilie2; + if (name == "damageSource") + return event.source == target && event.player != target && player.isDamaged(); + return event.player == target && player.countMark("mbyilie") < 2; }, - forced:true, - logTarget:function(event,player){ + forced: true, + logTarget: function (event, player) { return player.storage.mbyilie2; }, - content:function(){ - if(event.triggername=='damageSource') player.recover(); - else{ - player.addMark('mbyilie',trigger.num); + content: function () { + if (event.triggername == "damageSource") player.recover(); + else { + player.addMark("mbyilie", trigger.num); trigger.cancel(); } }, }, - mbyilie3:{ - audio:'mbyilie', - trigger:{player:'phaseEnd'}, + mbyilie3: { + audio: "mbyilie", + trigger: { player: "phaseEnd" }, //filter:function(event,player){ // return player.countMark('mbyilie'); //}, - forced:true, - content:function(){ - 'step 0' + forced: true, + content: function () { + "step 0"; player.draw(); - 'step 1' - var num=player.countMark('mbyilie'); - if(num){ + "step 1"; + var num = player.countMark("mbyilie"); + if (num) { player.loseHp(num); - player.removeMark('mbyilie',num); + player.removeMark("mbyilie", num); } }, }, //向朗 - naxue:{ - audio:2, - trigger:{player:'phaseUseBefore'}, - check:function(event,player){ - var cards=player.getCards('h',card=>player.hasValueTarget(card)); - if(!cards.length) return true; - if(!(player.hp>=2&&player.countCards('h')<=player.hp+1)) return false; - return game.hasPlayer(function(target){ - if(target.hasJudge('lebu')||target==player) return false; - if(get.attitude(player,target)>4){ - return (get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1)>0); + naxue: { + audio: 2, + trigger: { player: "phaseUseBefore" }, + check: function (event, player) { + var cards = player.getCards("h", (card) => player.hasValueTarget(card)); + if (!cards.length) return true; + if (!(player.hp >= 2 && player.countCards("h") <= player.hp + 1)) return false; + return game.hasPlayer(function (target) { + if (target.hasJudge("lebu") || target == player) return false; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) > + 0 + ); } return false; }); }, - content:function*(event,map){ - var player=map.player; + content: function* (event, map) { + var player = map.player; map.trigger.cancel(); - var num=player.countDiscardableCards(player,'he'); - if(num){ - var result=yield player.chooseToDiscard('纳学:是否弃置任意张牌并摸等量的牌?','he',[1,num]).set('ai',lib.skill.zhiheng.check); - if(result.bool) yield player.draw(result.cards.length); + var num = player.countDiscardableCards(player, "he"); + if (num) { + var result = yield player + .chooseToDiscard("纳学:是否弃置任意张牌并摸等量的牌?", "he", [1, num]) + .set("ai", lib.skill.zhiheng.check); + if (result.bool) yield player.draw(result.cards.length); } - if(player.countCards('h')){ - var result2=yield player.chooseCardTarget({ - prompt:'是否交给至多两名其他角色各一张手牌?', - prompt2:'先按顺序选中所有要给出的牌,然后再按顺序选择等量的目标角色。', - selectCard:[1,2], - filterCard:true, - filterTarget:lib.filter.notMe, - selectTarget:function(){ + if (player.countCards("h")) { + var result2 = yield player.chooseCardTarget({ + prompt: "是否交给至多两名其他角色各一张手牌?", + prompt2: "先按顺序选中所有要给出的牌,然后再按顺序选择等量的目标角色。", + selectCard: [1, 2], + filterCard: true, + filterTarget: lib.filter.notMe, + selectTarget: function () { return ui.selected.cards.length; }, - filterOk:()=>{ - return ui.selected.cards.length==ui.selected.targets.length; + filterOk: () => { + return ui.selected.cards.length == ui.selected.targets.length; }, - position:'h', - ai1:function(card){ - if(card.name=='du') return 10; - else if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - var player=_status.event.player; - if(ui.selected.cards.length>4||!game.hasPlayer(function(current){ - return get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })) return 0; - return 1/Math.max(0.1,get.value(card)); + position: "h", + ai1: function (card) { + if (card.name == "du") return 10; + else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") + return 0; + var player = _status.event.player; + if ( + ui.selected.cards.length > 4 || + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return 0; + return 1 / Math.max(0.1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(ui.selected.cards[0].name=='du') return -att; - if(target.hasSkillTag('nogain')) att/=6; + ai2: function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (ui.selected.cards[0].name == "du") return -att; + if (target.hasSkillTag("nogain")) att /= 6; return att; }, }); - if(result2.bool){ - const list=[]; - for(let i=0;itarget!=player); + yijie: { + audio: 2, + trigger: { player: "die" }, + filter: function (event, player) { + return game.hasPlayer((target) => target != player); }, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'orange', - logTarget:function(event,player){ - return game.filterPlayer(target=>target!=player); + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "orange", + logTarget: function (event, player) { + return game.filterPlayer((target) => target != player); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(target=>target!=player); - var sum=targets.reduce((num,target)=>num+=target.hp,0); - sum=Math.max(1,Math.floor(sum/targets.length)); - event.num=sum; - event.targets=targets; - 'step 1' - var target=targets.shift(); - var delta=target.hp-num; - if(delta!=0){ - target[delta>0?'loseHp':'recover'](Math.abs(delta)); + content: function () { + "step 0"; + var targets = game.filterPlayer((target) => target != player); + var sum = targets.reduce((num, target) => (num += target.hp), 0); + sum = Math.max(1, Math.floor(sum / targets.length)); + event.num = sum; + event.targets = targets; + "step 1"; + var target = targets.shift(); + var delta = target.hp - num; + if (delta != 0) { + target[delta > 0 ? "loseHp" : "recover"](Math.abs(delta)); } - if(targets.length) event.redo(); + if (targets.length) event.redo(); }, }, //阎象 - kujian:{ - audio:'twkujian', - inherit:'twkujian', - selectCard:[1,2], - content:function(){ - player.give(cards,target).gaintag.add('twkujianx'); - player.addSkill('kujian_draw'); - player.addSkill('twkujian_discard'); + kujian: { + audio: "twkujian", + inherit: "twkujian", + selectCard: [1, 2], + content: function () { + player.give(cards, target).gaintag.add("twkujianx"); + player.addSkill("kujian_draw"); + player.addSkill("twkujian_discard"); }, - subSkill:{ - draw:{ - charlotte:true, - audio:'twkujian', - trigger:{global:['useCardAfter','respondAfter']}, - filter:function(event,player){ - return event.player.hasHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twkujianx')) return true; + subSkill: { + draw: { + charlotte: true, + audio: "twkujian", + trigger: { global: ["useCardAfter", "respondAfter"] }, + filter: function (event, player) { + return event.player.hasHistory("lose", (evt) => { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twkujianx")) return true; } }); }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' - game.asyncDraw([player,trigger.player],2); - 'step 1' + forced: true, + logTarget: "player", + content: function () { + "step 0"; + game.asyncDraw([player, trigger.player], 2); + "step 1"; game.delayx(); }, }, }, }, //手杀差异化孙鲁育 - mbmumu:{ - audio:'mumu', - inherit:'new_mumu', - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current.countCards('e')>0; + mbmumu: { + audio: "mumu", + inherit: "new_mumu", + filter: function (event, player) { + return game.hasPlayer((current) => { + return current.countCards("e") > 0; }); }, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt('mbmumu'),'弃置场上的一张装备牌,或者获得场上的一张防具牌。',function(card,player,target){ - return target.countCards('e')>0; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target) - if(target.getEquip(2)&&player.hasEmptySlot(2)){ - return -2*att; - } - return -att; - }); - 'step 1' - if(result.bool&&result.targets&&result.targets.length){ - event.target=result.targets[0]; - player.logSkill('mbmumu',event.target); - player.line(event.target,'green'); - var e=event.target.getEquips(2); - event.e=e; - if(e.length>0){ - player.chooseControl('弃置一张装备牌','获得一张防具牌').set('ai',function(){ - if(_status.event.player.getEquips(2).length>0){ - return '弃置一张装备牌'; + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("mbmumu"), + "弃置场上的一张装备牌,或者获得场上的一张防具牌。", + function (card, player, target) { + return target.countCards("e") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (target.getEquip(2) && player.hasEmptySlot(2)) { + return -2 * att; + } + return -att; + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + event.target = result.targets[0]; + player.logSkill("mbmumu", event.target); + player.line(event.target, "green"); + var e = event.target.getEquips(2); + event.e = e; + if (e.length > 0) { + player.chooseControl("弃置一张装备牌", "获得一张防具牌").set("ai", function () { + if (_status.event.player.getEquips(2).length > 0) { + return "弃置一张装备牌"; } - return '获得一张防具牌'; + return "获得一张防具牌"; }); + } else { + event.choice = "弃置一张装备牌"; } - else{ - event.choice='弃置一张装备牌'; - } - } - else event.finish(); - 'step 2' - var choice=event.choice||result.control; - if(choice=='弃置一张装备牌'){ - player.discardPlayerCard(event.target,'e',true); - } - else{ - if(event.e){ - player.gain(event.e,event.target,'give','bySelf'); - player.addTempSkill('new_mumu2'); + } else event.finish(); + "step 2"; + var choice = event.choice || result.control; + if (choice == "弃置一张装备牌") { + player.discardPlayerCard(event.target, "e", true); + } else { + if (event.e) { + player.gain(event.e, event.target, "give", "bySelf"); + player.addTempSkill("new_mumu2"); } } }, }, - mbmeibu:{ - inherit:'new_meibu', - derivation:['mbzhixi'], - content:function (){ - "step 0" - var check=lib.skill.new_meibu.checkx(trigger,player); - player.chooseToDiscard(get.prompt2('mbmeibu',trigger.player),'he').set('ai',function(card){ - if(_status.event.check) return 6-get.value(card); - return 0; - }).set('check',check).set('logSkill',['mbmeibu',trigger.player]); - "step 1" - if(result.bool){ - var target=trigger.player; - var card=result.cards[0]; - player.line(target,'green'); - target.addTempSkills('mbzhixi','phaseUseAfter'); - if(card.name!='sha'&&get.type(card)!='trick'&&get.color(card)!='black'){ - target.addTempSkill('new_meibu_range','phaseUseAfter'); - target.markAuto('new_meibu_range',player); + mbmeibu: { + inherit: "new_meibu", + derivation: ["mbzhixi"], + content: function () { + "step 0"; + var check = lib.skill.new_meibu.checkx(trigger, player); + player + .chooseToDiscard(get.prompt2("mbmeibu", trigger.player), "he") + .set("ai", function (card) { + if (_status.event.check) return 6 - get.value(card); + return 0; + }) + .set("check", check) + .set("logSkill", ["mbmeibu", trigger.player]); + "step 1"; + if (result.bool) { + var target = trigger.player; + var card = result.cards[0]; + player.line(target, "green"); + target.addTempSkills("mbzhixi", "phaseUseAfter"); + if (card.name != "sha" && get.type(card) != "trick" && get.color(card) != "black") { + target.addTempSkill("new_meibu_range", "phaseUseAfter"); + target.markAuto("new_meibu_range", player); } - target.markSkillCharacter('mbmeibu',player,'魅步','锁定技。出牌阶段,若你于此阶段使用过的牌数不小于X,你不能使用牌(X为你的体力值);当你使用锦囊牌时,你结束此阶段。'); + target.markSkillCharacter( + "mbmeibu", + player, + "魅步", + "锁定技。出牌阶段,若你于此阶段使用过的牌数不小于X,你不能使用牌(X为你的体力值);当你使用锦囊牌时,你结束此阶段。" + ); } }, }, - mbzhixi:{ - mod:{ - cardEnabled:function(card,player){ - if(player.countMark('mbzhixi')>=player.hp) return false; + mbzhixi: { + mod: { + cardEnabled: function (card, player) { + if (player.countMark("mbzhixi") >= player.hp) return false; }, - cardUsable:function(card,player){ - if(player.countMark('mbzhixi')>=player.hp) return false; + cardUsable: function (card, player) { + if (player.countMark("mbzhixi") >= player.hp) return false; }, - cardRespondable:function(card,player){ - if(player.countMark('mbzhixi')>=player.hp) return false; + cardRespondable: function (card, player) { + if (player.countMark("mbzhixi") >= player.hp) return false; }, - cardSavable:function(card,player){ - if(player.countMark('mbzhixi')>=player.hp) return false; + cardSavable: function (card, player) { + if (player.countMark("mbzhixi") >= player.hp) return false; }, }, - trigger:{ - player:"useCard1", + trigger: { + player: "useCard1", }, - forced:true, - popup:false, - onremove:true, - firstDo:true, - init:function(player,skill){ - player.storage[skill]=0; - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.player==player){ - player.getHistory('useCard',function(evtx){ - if(evtx.getParent('phaseUse')==evt){ + forced: true, + popup: false, + firstDo: true, + init: function (player, skill) { + player.storage[skill] = 0; + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.player == player) { + player.getHistory("useCard", function (evtx) { + if (evtx.getParent("phaseUse") == evt) { player.storage[skill]++; } - }) + }); } }, - onremove:function(player){ - player.unmarkSkill('mbmeibu'); + onremove: function (player) { + player.unmarkSkill("mbmeibu"); delete player.storage.mbzhixi; }, - content:function(){ - player.addMark('mbzhixi',1,false); - if(get.type2(trigger.card)=='trick'){ - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.player==player){ - evt.skipped=true; - game.log(player,'结束了出牌阶段'); + content: function () { + player.addMark("mbzhixi", 1, false); + if (get.type2(trigger.card) == "trick") { + var evt = trigger.getParent("phaseUse"); + if (evt && evt.player == player) { + evt.skipped = true; + game.log(player, "结束了出牌阶段"); } } }, - ai:{presha:true,pretao:true,nokeep:true}, + ai: { presha: true, pretao: true, nokeep: true }, }, //庞统 - 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.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })) return true; + 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.includes(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.includes(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); + 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.includes(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,'的目标'); + 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,'不可被响应'); + 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; + } 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杀','!'); + 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(); + } 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{ + } else { target.line(event.togive); - event.togive.damage(Math.min(2,event.togive.countCards('h',{name:'sha'})),target); + event.togive.damage( + Math.min(2, event.togive.countCards("h", { name: "sha" })), + target + ); } }, - intro:{ - content:'expansion', - markcount:'expansion', + 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+'摸一张牌', + 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.includes('选项二')) 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'; + 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.includes("选项二")) 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(); + 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; - }, - }); + "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]; + "step 4"; + var target = result.targets[0]; trigger.player.line(target); - trigger.player.give(result.cards,target); + trigger.player.give(result.cards, target); trigger.player.draw(); }, }, //蒋济 - jilun:{ - audio:'twjilun', - inherit:'twjilun', - filter:function(event,player){ - return player.hasSkill('twjichou',null,false,false); + jilun: { + audio: "twjilun", + inherit: "twjilun", + filter: function (event, player) { + return player.hasSkill("twjichou", null, false, false); }, - content:function(){ - 'step 0' - var choices=['选项一']; - var choiceList=[ - '摸两张牌', - '获得一个“机论”标记', - ]; - if(!player.getStorage('twjichou').length||!player.getStorage('twjichou').filter(function(name){ - return !player.getStorage('jilun').includes(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=player.getUseValue({name:'wuzhong'}); - for(var name of player.getStorage('twjichou')){ - if(player.getStorage('jilun').includes(name)) continue; - if(player.getUseValue({name:name})>val) return 1; - } - return 0; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('jilun'); - if(result.control=='选项一') player.draw(2); - else player.addMark('jilun_mark',1); + content: function () { + "step 0"; + var choices = ["选项一"]; + var choiceList = ["摸两张牌", "获得一个“机论”标记"]; + if ( + !player.getStorage("twjichou").length || + !player.getStorage("twjichou").filter(function (name) { + return ( + !player.getStorage("jilun").includes(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 = player.getUseValue({ name: "wuzhong" }); + for (var name of player.getStorage("twjichou")) { + if (player.getStorage("jilun").includes(name)) continue; + if (player.getUseValue({ name: name }) > val) return 1; + } + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("jilun"); + if (result.control == "选项一") player.draw(2); + else player.addMark("jilun_mark", 1); } }, - group:'jilun_effect', - subSkill:{ - mark:{ - intro:{content:'mark'}, + group: "jilun_effect", + subSkill: { + mark: { + intro: { content: "mark" }, }, - effect:{ - audio:'twjilun', - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasMark('jilun_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').includes(name)&&player.hasUseTarget({name:name}); - }).length){ - if(player.hasMark('jilun_mark')) player.removeMark('jilun_mark',player.countMark('jilun_mark')); + forced: true, + content: function () { + "step 0"; + if ( + !player.getStorage("twjichou").length || + !player.getStorage("twjichou").filter(function (name) { + return ( + !player.getStorage("jilun").includes(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').includes(name)){ - list.push(['锦囊','',name]); + var list = []; + for (var name of player.getStorage("twjichou")) { + if (!player.getStorage("jilun").includes(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')); + 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); + "step 2"; + if (player.hasMark("jilun_mark")) event.goto(0); }, }, }, + ai: { + combo: "twjichou", + }, }, //李遗 - jiaohua:{ - onremove:true, - audio:'twjiaohua', - enable:'phaseUse', - usable:2, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('###教化###选择一种牌的类型,令一名角色从牌堆获得此类型的一张牌'); + jiaohua: { + onremove: true, + audio: "twjiaohua", + enable: "phaseUse", + usable: 2, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "###教化###选择一种牌的类型,令一名角色从牌堆获得此类型的一张牌" + ); }, - chooseControl:function(event,player){ - var list=['basic','trick','equip'].filter(type=>!player.getStorage('jiaohua').includes(type)); - list.push('cancel2'); + chooseControl: function (event, player) { + var list = ["basic", "trick", "equip"].filter( + (type) => !player.getStorage("jiaohua").includes(type) + ); + list.push("cancel2"); return list; }, - check:function(event,player){ - var list=['trick','equip','basic'].filter(type=>!player.getStorage('jiaohua').includes(type)); + check: function (event, player) { + var list = ["trick", "equip", "basic"].filter( + (type) => !player.getStorage("jiaohua").includes(type) + ); return list[0]; }, - backup:function(result,player){ - return{ - type:result.control, - audio:'twjiaohua', - filterCard:()=>false, - selectCard:-1, - 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').includes(type))){ - player.popup('教化'); - player.unmarkAuto('jiaohua',player.getStorage('jiaohua')); - game.log(player,'清空了','#g【教化】','记录'); + backup: function (result, player) { + return { + type: result.control, + audio: "twjiaohua", + filterCard: () => false, + selectCard: -1, + 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").includes(type) + ) + ) { + player.popup("教化"); + player.unmarkAuto("jiaohua", player.getStorage("jiaohua")); + game.log(player, "清空了", "#g【教化】", "记录"); } }, - ai:{ - result:{target:1}, + ai: { + result: { target: 1 }, }, - } + }; }, - prompt:function(result,player){ - return '令一名角色从牌堆中获得一张'+get.translation(result.control)+'牌'; + prompt: function (result, player) { + return "令一名角色从牌堆中获得一张" + get.translation(result.control) + "牌"; }, }, - ai:{ - order:7, - result:{player:1}, + ai: { + order: 7, + result: { player: 1 }, }, - intro:{content:'已记录$牌'}, + 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; + 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; + return player.maxHp >= num; }, - forced:true, - content:function(){ - if(trigger.name=='damage'){ + forced: true, + content: function () { + if (trigger.name == "damage") { player.gainMaxHp(trigger.num); trigger.cancel(); - } - else player.die(); + } else player.die(); }, }, - luanqun:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h'); + 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()]}; + 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)])>0) return 0; - return get.value(button.link,player); - }).set('list',[cards,targets]); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + var card = cards[targets.indexOf(player)]; + var cardx = cards.filter( + (cardy) => + cardy != 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)]) > 0) 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"); } - 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){ + "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]); + 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; + 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').includes(target)) return false; + 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").includes(target) + ) + return false; }, }, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return player.isPhaseUsing()&&event.card.name=='sha'; + 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'); + forced: true, + content: function () { + trigger.directHit.addArray(player.getStorage("luanqun_effect")); + player.removeSkill("luanqun_effect"); }, }, }, }, //☆周不疑 - mbhuiyao:{ - audio:2, - enable:'phaseUse', - usable:1, + mbhuiyao: { + audio: 2, + enable: "phaseUse", + usable: 1, // filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - player.damage('nosource'); - 'step 1' - if(game.countPlayer()<2) event.finish(); - if(game.countPlayer()==2) event._result={bool:true,targets:[game.findPlayer(i=>i!=player),player]}; - else player.chooseTarget(`慧夭:请选择两名角色`,`令不为你的第一名角色视为对第二名角色造成过1点伤害。`,(card,player,target)=>{ - if(!ui.selected.targets.length) return player!=target; - return true; - },2,true).set('multitarget',true).set('targetprompt',['伤害来源','受伤角色']).set('ai',target=>{ - return target==get.event('aiTargets')[ui.selected.targets.length]?10:0; - }).set('aiTargets',lib.skill.mbhuiyao.getUnrealDamageTargets(player,[game.filterPlayer(i=>i!=player),game.filterPlayer()],true)); - 'step 2' - if(result.bool){ - var targets=result.targets; - player.line2(targets,'green'); + content: function () { + "step 0"; + player.damage("nosource"); + "step 1"; + if (game.countPlayer() < 2) event.finish(); + if (game.countPlayer() == 2) + event._result = { + bool: true, + targets: [game.findPlayer((i) => i != player), player], + }; + else + player + .chooseTarget( + `慧夭:请选择两名角色`, + `令不为你的第一名角色视为对第二名角色造成过1点伤害。`, + (card, player, target) => { + if (!ui.selected.targets.length) return player != target; + return true; + }, + 2, + true + ) + .set("multitarget", true) + .set("targetprompt", ["伤害来源", "受伤角色"]) + .set("ai", (target) => { + return target == get.event("aiTargets")[ui.selected.targets.length] ? 10 : 0; + }) + .set( + "aiTargets", + lib.skill.mbhuiyao.getUnrealDamageTargets( + player, + [game.filterPlayer((i) => i != player), game.filterPlayer()], + true + ) + ); + "step 2"; + if (result.bool) { + var targets = result.targets; + player.line2(targets, "green"); game.delaye(); - targets[1].damage(targets[0],'unreal'); + targets[1].damage(targets[0], "unreal"); } }, - getUnrealDamageTargets:(player,lists,forced)=>{ - const targets=[null,null]; - let sourceList,targetList; - if(lists.length==2&&lists.every(l=>Array.isArray(l))){ - sourceList=lists[0]; targetList=lists[1]; + getUnrealDamageTargets: (player, lists, forced) => { + const targets = [null, null]; + let sourceList, targetList; + if (lists.length == 2 && lists.every((l) => Array.isArray(l))) { + sourceList = lists[0]; + targetList = lists[1]; + } else { + sourceList = lists.slice(); + targetList = lists.slice(); } - else{ - sourceList=lists.slice(); targetList=lists.slice(); - } - const list=targetList.map(current=>{ - const _hp=current.hp,_maxhp=current.maxHp; - current.hp=100; current.maxHp=100; - const att=-get.sgnAttitude(player,current); - let val=get.damageEffect(current,player,current)*att; - current.getSkills(null,false,false).forEach(skill=>{ - const info=get.info(skill); - if(info&&info.ai&&(info.ai.maixie||info.ai.maixie_hp||info.ai.maixie_defend)) val=Math[val>0?'max':'min'](val>0?0.1:-0.1,val+2*att); - }); - const eff=100/val+15; - current.hp=_hp; current.maxHp=_maxhp; - return [current,eff]; - }).sort((a,b)=>b[1]-a[1])[0]; - if(list[1]<0&&!forced) return targets; - const targetx=list[0]; - targets[1]=targetx; - const list2=sourceList.filter(i=>i!=targetx).map(current=>{ - const _hp=targetx.hp,_maxhp=targetx.maxHp; - targetx.hp=100; targetx.maxHp=100; - const att=-get.sgnAttitude(player,current); - const eff=get.damageEffect(targetx,current,current)*att; - targetx.hp=_hp; targetx.maxHp=_maxhp; - return [current,eff]; - }).sort((a,b)=>b[1]-a[1])[0]; - if(!list2) return targets; - targets[0]=list2[0]; + const list = targetList + .map((current) => { + const _hp = current.hp, + _maxhp = current.maxHp; + current.hp = 100; + current.maxHp = 100; + const att = -get.sgnAttitude(player, current); + let val = get.damageEffect(current, player, current) * att; + current.getSkills(null, false, false).forEach((skill) => { + const info = get.info(skill); + if ( + info && + info.ai && + (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) + ) + val = Math[val > 0 ? "max" : "min"](val > 0 ? 0.1 : -0.1, val + 2 * att); + }); + const eff = 100 / val + 15; + current.hp = _hp; + current.maxHp = _maxhp; + return [current, eff]; + }) + .sort((a, b) => b[1] - a[1])[0]; + if (list[1] < 0 && !forced) return targets; + const targetx = list[0]; + targets[1] = targetx; + const list2 = sourceList + .filter((i) => i != targetx) + .map((current) => { + const _hp = targetx.hp, + _maxhp = targetx.maxHp; + targetx.hp = 100; + targetx.maxHp = 100; + const att = -get.sgnAttitude(player, current); + const eff = get.damageEffect(targetx, current, current) * att; + targetx.hp = _hp; + targetx.maxHp = _maxhp; + return [current, eff]; + }) + .sort((a, b) => b[1] - a[1])[0]; + if (!list2) return targets; + targets[0] = list2[0]; return targets; }, - ai:{ - order:6, - result:{ - player:function(player){ - if(player.getHp()+player.countCards('hs',card=>player.canSaveCard(card,player))<=1) return 0; - var limit=25; - var quesong=player.hasSkill('mbquesong')&&!player.getStat().damaged; - if(quesong){ - limit-=7.5; + ai: { + order: 6, + result: { + player: function (player) { + if ( + player.getHp() + + player.countCards("hs", (card) => player.canSaveCard(card, player)) <= + 1 + ) + return 0; + var limit = 25; + var quesong = player.hasSkill("mbquesong") && !player.getStat().damaged; + if (quesong) { + limit -= 7.5; } - if(quesong&&game.hasPlayer(target=>{ - var att=get.attitude(player,target); - if(att<0) return false; - return att*Math.sqrt(Math.max(1,[1,2,3,4].reduce((p,c)=>p+target.countEmptySlot(c),0)))>=10||target.getHp()<=2; - })) return 1; - if(!quesong&&game.hasPlayer(target=>{ - if(target==player) return false; - var _hp=target.hp,_maxhp=target.maxHp; - target.hp=100; target.maxHp=100; - var att=-get.sgnAttitude(player,target); - var val=get.damageEffect(target,player,target)*att; - target.getSkills(null,false,false).forEach(skill=>{ - var info=get.info(skill); - if(info&&info.ai&&(info.ai.maixie||info.ai.maixie_hp||info.ai.maixie_defend)) val=Math[val>0?'max':'min'](val>0?0.1:-0.1,val+2*att); - }); - var eff=100/val; - target.hp=_hp; target.maxHp=_maxhp; - if(eff { + var att = get.attitude(player, target); + if (att < 0) return false; + return ( + att * + Math.sqrt( + Math.max( + 1, + [1, 2, 3, 4].reduce( + (p, c) => p + target.countEmptySlot(c), + 0 + ) + ) + ) >= + 10 || target.getHp() <= 2 + ); + }) + ) + return 1; + if ( + !quesong && + game.hasPlayer((target) => { + if (target == player) return false; + var _hp = target.hp, + _maxhp = target.maxHp; + target.hp = 100; + target.maxHp = 100; + var att = -get.sgnAttitude(player, target); + var val = get.damageEffect(target, player, target) * att; + target.getSkills(null, false, false).forEach((skill) => { + var info = get.info(skill); + if ( + info && + info.ai && + (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) + ) + val = Math[val > 0 ? "max" : "min"]( + val > 0 ? 0.1 : -0.1, + val + 2 * att + ); + }); + var eff = 100 / val; + target.hp = _hp; + target.maxHp = _maxhp; + if (eff < limit) return false; + return true; + }) + ) + return 1; return 0; - } - } + }, + }, }, }, - mbquesong:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getHistory('damage').length; + mbquesong: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.getHistory("damage").length; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('mbquesong')).set('ai',target=>{ - var player=_status.event.player; - if(get.attitude(player,target)<=0) return 0; - var len=lib.skill.mbquesong.getNum(target),hp=target.getHp(); - return len+target.isTurnedOver()*2+1.5*Math.min(4,target.getDamagedHp())/(hp+1); + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("mbquesong")).set("ai", (target) => { + var player = _status.event.player; + if (get.attitude(player, target) <= 0) return 0; + var len = lib.skill.mbquesong.getNum(target), + hp = target.getHp(); + return ( + len + + target.isTurnedOver() * 2 + + (1.5 * Math.min(4, target.getDamagedHp())) / (hp + 1) + ); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('mbquesong',target); - var len=lib.skill.mbquesong.getNum(target); - if(target.isHealthy()) event._result={index:0}; - else{ - target.chooseControl().set('choiceList',[ - '摸'+get.cnNumber(len)+'张牌并复原武将牌', - '回复1点体力', - ]).set('prompt','雀颂:请选择一项').set('ai',()=>{ - var player=_status.event.player; - var len=_status.event.len; - return get.effect(player,{name:'draw'},player,player)*len>=get.recoverEffect(player,player,player)?0:1; - }).set('len',len); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("mbquesong", target); + var len = lib.skill.mbquesong.getNum(target); + if (target.isHealthy()) event._result = { index: 0 }; + else { + target + .chooseControl() + .set("choiceList", [ + "摸" + get.cnNumber(len) + "张牌并复原武将牌", + "回复1点体力", + ]) + .set("prompt", "雀颂:请选择一项") + .set("ai", () => { + var player = _status.event.player; + var len = _status.event.len; + return get.effect(player, { name: "draw" }, player, player) * len >= + get.recoverEffect(player, player, player) + ? 0 + : 1; + }) + .set("len", len); } - } - else event.finish(); - 'step 2' - if(result.index==1){ + } else event.finish(); + "step 2"; + if (result.index == 1) { target.recover(); event.finish(); - } - else target.draw(lib.skill.mbquesong.getNum(target)); - 'step 3' + } else target.draw(lib.skill.mbquesong.getNum(target)); + "step 3"; target.link(false); - 'step 4' + "step 4"; target.turnOver(false); }, - getNum:function(player){ - return player.countCards('e',card=>get.subtype(card)!='equip5')>=3?2:3; + getNum: function (player) { + return player.countCards("e", (card) => get.subtype(card) != "equip5") >= 3 ? 2 : 3; }, - ai:{ - expose:0.2, - maixie:true, - skillTagFilter:function(player,tag){ - if(player.getStat().damaged) return false; + ai: { + expose: 0.2, + maixie: true, + skillTagFilter: function (player, tag) { + if (player.getStat().damaged) return false; }, - } + }, }, //郭照 - yichong:{ - initSkill:function(skill){ - if(!lib.skill[skill]){ - lib.skill[skill]={ - charlotte:true, - onremove:true, - mark:true, - marktext:'雀', - intro:{ - markcount:function(storage){ - return (storage||0).toString(); + yichong: { + initSkill: function (skill) { + if (!lib.skill[skill]) { + lib.skill[skill] = { + charlotte: true, + onremove: true, + mark: true, + marktext: "雀", + intro: { + markcount: function (storage) { + return (storage || 0).toString(); }, - content:function(storage){ - return '已被掠夺'+(storage||0)+'张牌'; + content: function (storage) { + return "已被掠夺" + (storage || 0) + "张牌"; }, }, }; - lib.translate[skill]='易宠'; - lib.translate[skill+'_bg']='雀'; + lib.translate[skill] = "易宠"; + lib.translate[skill + "_bg"] = "雀"; } }, - getLimit:1, - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yichong'),'选择一名其他角色并选择一个花色,获得其此花色的所有牌并令其获得“雀”标记',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0) return 0; - var getNum=function(player){ - var list=[]; - for(var i of lib.suit) list.push((player.countCards('he',{suit:i})+3)); - return list.sort((a,b)=>b-a)[0]; - }; - return getNum(target)+target.countCards('h')/10; + getLimit: 1, + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("yichong"), + "选择一名其他角色并选择一个花色,获得其此花色的所有牌并令其获得“雀”标记", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) return 0; + var getNum = function (player) { + var list = []; + for (var i of lib.suit) list.push(player.countCards("he", { suit: i }) + 3); + return list.sort((a, b) => b - a)[0]; + }; + return getNum(target) + target.countCards("h") / 10; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("yichong", target); + event.target = target; + player + .chooseControl(lib.suit.slice(0).reverse()) + .set("prompt", "请声明一个花色") + .set("ai", function () { + var target = _status.event.target, + cards = target.getCards("he"); + var suits = lib.suit.slice(0); + suits.sort(function (a, b) { + var num = function (suit) { + return cards.filter(function (card) { + return get.suit(card) == suit; + }).length; + }; + return num(b) - num(a); + }); + return suits[0]; + }) + .set("target", target); + } else event.finish(); + "step 2"; + var suit = result.control; + event.suit = suit; + player.chat(get.translation(suit + 2)); + game.log(player, "选择了", "#y" + get.translation(suit + 2)); + if (target.countCards("e", { suit: suit })) + player.gain(target.getCards("e", { suit: suit }), target, "giveAuto"); + "step 3"; + var suit = event.suit; + if (target.countCards("h", { suit: suit })) { + player + .chooseButton(["选择获得其中一张牌", target.getCards("h", { suit: suit })], true) + .set("ai", (button) => get.value(button.link)); + } else event.goto(5); + "step 4"; + if (result.bool) { + var card = result.links[0]; + if (lib.filter.canBeGained(card, player, target)) + player.gain(card, target, "giveAuto", "bySelf"); + else game.log("但", card, "不能被", player, "获得!"); + } + "step 5"; + var suit = event.suit; + player.storage.yichong = suit; + player.markSkill("yichong"); + var skill = "yichong_" + player.playerid; + game.broadcastAll(lib.skill.yichong.initSkill, skill); + game.broadcastAll( + function (player, suit) { + if (player.marks.yichong) + player.marks.yichong.firstChild.innerHTML = get.translation(suit); + }, + player, + suit + ); + game.countPlayer(function (current) { + current.removeSkill("yichong_" + player.playerid); + if (current == target) target.addSkill("yichong_" + player.playerid); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('yichong',target); - event.target=target; - player.chooseControl(lib.suit.slice(0).reverse()).set('prompt','请声明一个花色').set('ai',function(){ - var target=_status.event.target,cards=target.getCards('he'); - var suits=lib.suit.slice(0); - suits.sort(function(a,b){ - var num=function(suit){ - return cards.filter(function(card){ - return get.suit(card)==suit; - }).length; - }; - return num(b)-num(a); - }); - return suits[0]; - }).set('target',target); - } - else event.finish(); - 'step 2' - var suit=result.control; - event.suit=suit; - player.chat(get.translation(suit+2)); - game.log(player,'选择了','#y'+get.translation(suit+2)); - if(target.countCards('e',{suit:suit})) player.gain(target.getCards('e',{suit:suit}),target,'giveAuto'); - 'step 3' - var suit=event.suit; - if(target.countCards('h',{suit:suit})){ - player.chooseButton(['选择获得其中一张牌',target.getCards('h',{suit:suit})],true).set('ai',button=>get.value(button.link)); - } - else event.goto(5); - 'step 4' - if(result.bool){ - var card=result.links[0]; - if(lib.filter.canBeGained(card,player,target)) player.gain(card,target,'giveAuto','bySelf'); - else game.log('但',card,'不能被',player,'获得!'); - } - 'step 5' - var suit=event.suit; - player.storage.yichong=suit; - player.markSkill('yichong'); - var skill='yichong_'+player.playerid; - game.broadcastAll(lib.skill.yichong.initSkill,skill); - game.broadcastAll(function(player,suit){ - if(player.marks.yichong) player.marks.yichong.firstChild.innerHTML=get.translation(suit); - },player,suit); - game.countPlayer(function(current){ - current.removeSkill('yichong_'+player.playerid); - if(current==target) target.addSkill('yichong_'+player.playerid); - }); - player.addTempSkill('yichong_clear',{player:'phaseBegin'}); + player.addTempSkill("yichong_clear", { player: "phaseBegin" }); }, - onremove:true, - intro:{content:'拥有“雀”标记的角色得到$牌后,你获得之'}, - group:'yichong_gain', - subSkill:{ - gain:{ - audio:'yichong', - trigger:{global:['gainAfter','loseAsyncAfter']}, - filter:function(event,player){ - 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)>=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)); + onremove: true, + intro: { content: "拥有“雀”标记的角色得到$牌后,你获得之" }, + group: "yichong_gain", + subSkill: { + gain: { + audio: "yichong", + trigger: { global: ["gainAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + 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) >= + 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) + ); }); }, - forced:true, - content:function(){ - '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)>=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)); + forced: true, + content: function () { + "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) >= + 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<=lib.skill.yichong.getLimit-target.countMark('yichong_'+player.playerid)) event._result={bool:true,links:cards}; - else{ - 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); - }); + 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 <= + lib.skill.yichong.getLimit - target.countMark("yichong_" + player.playerid) + ) + event._result = { bool: true, links: cards }; + else { + 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); + }); } - 'step 1' - if(result.bool){ - player.gain(result.links,target,'give'); - target.addMark('yichong_'+player.playerid,result.links.length,false); + "step 1"; + if (result.bool) { + player.gain(result.links, target, "give"); + target.addMark("yichong_" + player.playerid, result.links.length, false); } }, }, - clear:{ - charlotte:true, - onremove:function(player){ - game.countPlayer(function(current){ - current.removeSkill('yichong_'+player.playerid); + clear: { + charlotte: true, + onremove: function (player) { + game.countPlayer(function (current) { + current.removeSkill("yichong_" + player.playerid); }); }, }, }, }, - wufei:{ - audio:2, - trigger:{player:['useCardToPlayered','damageEnd']}, - 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>3; - return event.isFirstTarget&&(event.card.name=='sha'||(get.type(event.card)=='trick'&&get.tag(event.card,'damage'))); + wufei: { + audio: 2, + trigger: { player: ["useCardToPlayered", "damageEnd"] }, + 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 > 3; + return ( + event.isFirstTarget && + (event.card.name == "sha" || + (get.type(event.card) == "trick" && get.tag(event.card, "damage"))) + ); }, - direct:true, - content:function(){ - 'step 0' - 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); - } - else{ - player.logSkill('wufei',target); - player.addTempSkill('wufei_effect'); - player.markAuto('wufei_effect',[trigger.card]); - game.log(target,'成为了',trigger.card,'的伤害来源'); + direct: true, + content: function () { + "step 0"; + 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); + } else { + player.logSkill("wufei", target); + player.addTempSkill("wufei_effect"); + player.markAuto("wufei_effect", [trigger.card]); + game.log(target, "成为了", trigger.card, "的伤害来源"); event.finish(); } - 'step 1' - if(result.bool){ - player.logSkill('wufei',target); - target.damage('nosource'); + "step 1"; + if (result.bool) { + player.logSkill("wufei", target); + target.damage("nosource"); } }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{source:'damageBefore'}, - filter:function(event,player){ - if(!event.card) return false; - return player.getStorage('wufei_effect').includes(event.card); + subSkill: { + effect: { + charlotte: true, + trigger: { source: "damageBefore" }, + filter: function (event, player) { + if (!event.card) return false; + return player.getStorage("wufei_effect").includes(event.card); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); - if(!target) delete trigger.source; - else trigger.source=target; + forced: true, + popup: false, + firstDo: true, + content: function () { + var target = game.findPlayer((current) => + current.hasSkill("yichong_" + player.playerid) + ); + if (!target) delete trigger.source; + else trigger.source = target; }, }, }, + ai: { + combo: "yichong", + }, }, //张嶷 - xinwurong:{ - audio:3, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - player.chooseToDuiben(target).set('title','谋弈').set('namelist',[ - '反抗','归顺','镇压','安抚' - ]).set('ai',button=>1+Math.random()); - 'step 1' - if(result.bool){ - if(result.player=='db_def1'){ + xinwurong: { + audio: 3, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + player + .chooseToDuiben(target) + .set("title", "谋弈") + .set("namelist", ["反抗", "归顺", "镇压", "安抚"]) + .set("ai", (button) => 1 + Math.random()); + "step 1"; + if (result.bool) { + if (result.player == "db_def1") { target.damage(); player.draw(); event.finish(); - } - else{ - var cards=target.getCards('he'); - if(cards.length<2){ - target.skip('phaseDraw'); - target.addTempSkill('xinwurong_skip',{player:'phaseDrawSkipped'}); + } else { + var cards = target.getCards("he"); + if (cards.length < 2) { + target.skip("phaseDraw"); + target.addTempSkill("xinwurong_skip", { player: "phaseDrawSkipped" }); event.finish(); - } - else if(cards.length==2) event._result={bool:true,cards:cards}; - else target.chooseCard('怃戎:交给'+get.translation(player)+'两张牌',2,true,'he'); + } else if (cards.length == 2) event._result = { bool: true, cards: cards }; + else + target.chooseCard( + "怃戎:交给" + get.translation(player) + "两张牌", + 2, + true, + "he" + ); } - } - else{ - if(result.player=='db_def1'){ - player.gainPlayerCard(target,'he',true); + } else { + if (result.player == "db_def1") { + player.gainPlayerCard(target, "he", true); event.goto(3); - } - else{ + } else { player.damage(); player.draw(2); event.finish(); } } - 'step 2' - if(result.bool) player.gain(result.cards,target,'giveAuto'); + "step 2"; + if (result.bool) player.gain(result.cards, target, "giveAuto"); event.finish(); - 'step 3' - var cards=player.getCards('he'); - if(!cards.length) event.finish(); - else if(cards.length<=2) event._result={bool:true,cards:cards}; - else player.chooseCard('怃戎:交给'+get.translation(target)+'两张牌',2,true,'he'); - 'step 4' - if(result.bool) target.gain(result.cards,player,'giveAuto'); + "step 3"; + var cards = player.getCards("he"); + if (!cards.length) event.finish(); + else if (cards.length <= 2) event._result = { bool: true, cards: cards }; + else player.chooseCard("怃戎:交给" + get.translation(target) + "两张牌", 2, true, "he"); + "step 4"; + if (result.bool) target.gain(result.cards, player, "giveAuto"); }, - ai:{ - order:7, - result:{ - player:1, - target:-1, + ai: { + order: 7, + result: { + player: 1, + target: -1, }, }, - subSkill:{ - skip:{ - charlotte:true, - mark:true, - intro:{content:'跳过下个摸牌阶段'}, + subSkill: { + skip: { + charlotte: true, + mark: true, + intro: { content: "跳过下个摸牌阶段" }, }, }, }, //孙亮 - xinkuizhu:{ - audio:'nzry_kuizhu', - trigger:{player:'phaseDiscardAfter'}, - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - return evt.type=='discard'&&evt.getParent('phaseDiscard')==event; + xinkuizhu: { + audio: "nzry_kuizhu", + trigger: { player: "phaseDiscardAfter" }, + filter: function (event, player) { + return player.getHistory("lose", function (evt) { + return evt.type == "discard" && evt.getParent("phaseDiscard") == event; }).length; }, - direct:true, - content:function(){ - 'step 0' - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) cards.addArray(evt.cards2); + direct: true, + content: function () { + "step 0"; + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + cards.addArray(evt.cards2); }); - event.num=cards.length; - event.str1='令至多'+event.num+'名角色摸一张牌'; - event.str2='对任意名体力值之和为'+event.num+'的角色造成1点伤害'; - player.chooseControl('cancel2').set('ai',function(){ - if(game.countPlayer(function(current){return get.attitude(player,current)<0&¤t.hp==event.num})>0&&event.num<=3) return 1; - return 0; - }).set('choiceList',[event.str1,event.str2]).set('prompt','是否发动【溃诛】?'); - 'step 1' - if(result.control=='cancel2') event.finish(); - event.control=[event.str1,event.str2][result.index]; - 'step 2' - var str='请选择〖溃诛〗的目标'; - if(event.bool==false) str='
              所选目标体力之和不足'+event.num+',请重选'; - if(event.control==event.str2){ - player.chooseTarget(str,function(card,player,target){ - var targets=ui.selected.targets; - var num=0; - for(var i=0;i 0 && + event.num <= 3 + ) + return 1; + return 0; + }) + .set("choiceList", [event.str1, event.str2]) + .set("prompt", "是否发动【溃诛】?"); + "step 1"; + if (result.control == "cancel2") event.finish(); + event.control = [event.str1, event.str2][result.index]; + "step 2"; + var str = "请选择〖溃诛〗的目标"; + if (event.bool == false) str = "
              所选目标体力之和不足" + event.num + ",请重选"; + if (event.control == event.str2) { + player + .chooseTarget(str, function (card, player, target) { + var targets = ui.selected.targets; + var num = 0; + for (var i = 0; i < targets.length; i++) num += targets[i].hp; + return num + target.hp <= _status.event.num; + }) + .set("ai", function (target) { + if (ui.selected.targets[0] != undefined) return -1; + return get.attitude(player, target) < 0; + }) + .set("promptbar", "none") + .set("num", event.num) + .set("selectTarget", function () { + var targets = ui.selected.targets; + var num = 0; + for (var i = 0; i < targets.length; i++) num += targets[i].hp; + if (num == _status.event.num) return ui.selected.targets.length; + return ui.selected.targets.length + 1; + }); + } else { + player + .chooseTarget( + "请选择〖溃诛〗的目标", + "令至多" + get.cnNumber(event.num) + "名角色各摸一张牌", + [1, event.num] + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); } - else{ - player.chooseTarget('请选择〖溃诛〗的目标','令至多'+get.cnNumber(event.num)+'名角色各摸一张牌',[1,event.num]).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - } - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - if(event.control==event.str1){ - player.logSkill('xinkuizhu',targets); + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + if (event.control == event.str1) { + player.logSkill("xinkuizhu", targets); game.asyncDraw(targets); - } - else{ - var num=0; - for(var i=0;i=2) player.loseHp(); + } else { + player.logSkill("xinkuizhu", targets); + for (var i of targets) i.damage(); + if (targets.length >= 2) player.loseHp(); } } } }, }, - xinzhizheng:{ - audio:'nzry_zhizheng', - mod:{ - playerEnabled:function(card,player,target){ - var info=get.info(card); - if(target!=player&&(!info||!info.singleCard||!ui.selected.targets.length)&&player.isPhaseUsing()&&!target.inRange(player)) return false; + xinzhizheng: { + audio: "nzry_zhizheng", + mod: { + playerEnabled: function (card, player, target) { + var info = get.info(card); + if ( + target != player && + (!info || !info.singleCard || !ui.selected.targets.length) && + player.isPhaseUsing() && + !target.inRange(player) + ) + return false; }, }, - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; - }).length0); - 'step 1' - if(result.bool){ - player.logSkill('xinlijun',trigger.player); - player.gain(trigger.cards.filterInD(),'gain2'); - player.chooseBool().set('prompt','是否令'+get.translation(trigger.player)+'摸一张牌?').set('choice',get.attitude(player,trigger.player)>0); - } - else event.finish(); - 'step 2' - if(result.bool) trigger.player.draw(); + zhuSkill: true, + direct: true, + content: function () { + "step 0"; + trigger.player + .chooseBool( + get.prompt("xinlijun"), + "将" + get.translation(trigger.cards) + "交给" + get.translation(player) + ) + .set("choice", get.attitude(trigger.player, player) > 0); + "step 1"; + if (result.bool) { + player.logSkill("xinlijun", trigger.player); + player.gain(trigger.cards.filterInD(), "gain2"); + player + .chooseBool() + .set("prompt", "是否令" + get.translation(trigger.player) + "摸一张牌?") + .set("choice", get.attitude(player, trigger.player) > 0); + } else event.finish(); + "step 2"; + if (result.bool) trigger.player.draw(); }, }, //十常侍 - mbdanggu:{ - audio:2, - trigger:{ - player:'enterGame', - global:'phaseBefore', + mbdanggu: { + audio: 2, + trigger: { + player: "enterGame", + global: "phaseBefore", }, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - derivation:['mbdanggu_faq','mbdanggu_faq2'], - forced:true, - unique:true, - onremove:function(player){ + derivation: ["mbdanggu_faq", "mbdanggu_faq2"], + forced: true, + unique: true, + onremove: function (player) { delete player.storage.mbdanggu; delete player.storage.mbdanggu_current; - if(lib.skill.mbdanggu.isSingleShichangshi(player)){ - game.broadcastAll(function(player){ - player.name1=player.name; + if (lib.skill.mbdanggu.isSingleShichangshi(player)) { + game.broadcastAll(function (player) { + player.name1 = player.name; player.smoothAvatar(false); - player.node.avatar.setBackground(player.name,'character'); - player.node.name.innerHTML=get.slimName(player.name); + player.node.avatar.setBackground(player.name, "character"); + player.node.name.innerHTML = get.slimName(player.name); delete player.name2; - player.classList.remove('fullskin2'); - player.node.avatar2.classList.add('hidden'); - player.node.name2.innerHTML=''; - if(player==game.me&&ui.fakeme){ - ui.fakeme.style.backgroundImage=player.node.avatar.style.backgroundImage; + player.classList.remove("fullskin2"); + player.node.avatar2.classList.add("hidden"); + player.node.name2.innerHTML = ""; + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; } - },player); + }, player); } }, - changshi:[ - ['scs_zhangrang','scstaoluan'], - ['scs_zhaozhong','scschiyan'], - ['scs_sunzhang','scszimou'], - ['scs_bilan','scspicai'], - ['scs_xiayun','scsyaozhuo'], - ['scs_hankui','scsxiaolu'], - ['scs_lisong','scskuiji'], - ['scs_duangui','scschihe'], - ['scs_guosheng','scsniqu'], - ['scs_gaowang','scsmiaoyu'] + changshi: [ + ["scs_zhangrang", "scstaoluan"], + ["scs_zhaozhong", "scschiyan"], + ["scs_sunzhang", "scszimou"], + ["scs_bilan", "scspicai"], + ["scs_xiayun", "scsyaozhuo"], + ["scs_hankui", "scsxiaolu"], + ["scs_lisong", "scskuiji"], + ["scs_duangui", "scschihe"], + ["scs_guosheng", "scsniqu"], + ["scs_gaowang", "scsmiaoyu"], ], - conflictMap:function(player){ - if(!_status.changshiMap){ - _status.changshiMap={ - scs_zhangrang:[], - scs_zhaozhong:[], - scs_sunzhang:[], - scs_bilan:['scs_hankui'], - scs_xiayun:[], - scs_hankui:['scs_bilan'], - scs_lisong:[], - scs_duangui:['scs_guosheng'], - scs_guosheng:['scs_duangui'], - scs_gaowang:[], + conflictMap: function (player) { + if (!_status.changshiMap) { + _status.changshiMap = { + scs_zhangrang: [], + scs_zhaozhong: [], + scs_sunzhang: [], + scs_bilan: ["scs_hankui"], + scs_xiayun: [], + scs_hankui: ["scs_bilan"], + scs_lisong: [], + scs_duangui: ["scs_guosheng"], + scs_guosheng: ["scs_duangui"], + scs_gaowang: [], }; - if(!get.isLuckyStar(player)){ - var list=lib.skill.mbdanggu.changshi.map(i=>i[0]); - for(var i of list){ - var select=list.filter(scs=>scs!=i&&!_status.changshiMap[i].includes(i)); - _status.changshiMap[i].addArray(select.randomGets(get.rand(0,select.length))); + if (!get.isLuckyStar(player)) { + var list = lib.skill.mbdanggu.changshi.map((i) => i[0]); + for (var i of list) { + var select = list.filter( + (scs) => scs != i && !_status.changshiMap[i].includes(i) + ); + _status.changshiMap[i].addArray( + select.randomGets(get.rand(0, select.length)) + ); } } } return _status.changshiMap; }, - group:'mbdanggu_back', - content:function(){ - 'step 0' - var list=lib.skill.mbdanggu.changshi.map(i=>i[0]); - player.markAuto('mbdanggu',list); - game.broadcastAll(function(player,list){ - var cards=[]; - for(var i=0;i i[0]); + player.markAuto("mbdanggu", list); + game.broadcastAll( + function (player, list) { + var cards = []; + for (var i = 0; i < list.length; i++) { + var cardname = "huashen_card_" + list[i]; + lib.card[cardname] = { + fullimage: true, + image: "character/" + list[i], + }; + lib.translate[cardname] = get.rawName2(list[i]); + cards.push(game.createCard(cardname, "", "")); } - lib.translate[cardname]=get.rawName2(list[i]); - cards.push(game.createCard(cardname,'','')); - } - player.$draw(cards,'nobroadcast'); - },player,list); - 'step 1' - var next=game.createEvent('mbdanggu_clique'); - next.player=player; + player.$draw(cards, "nobroadcast"); + }, + player, + list + ); + "step 1"; + var next = game.createEvent("mbdanggu_clique"); + next.player = player; next.setContent(lib.skill.mbdanggu.contentx); }, - contentx:function(){ - 'step 0' - var list=player.getStorage('mbdanggu').slice(); - var first=list.randomRemove(); - event.first=first; - var others=list.randomGets(4); - if(others.length==1) event._result={bool:true,links:others}; - else{ - var map={ - 'scs_bilan':'scs_hankui', - 'scs_hankui':'scs_bilan', - 'scs_duangui':'scs_guosheng', - 'scs_guosheng':'scs_duangui', - },map2=lib.skill.mbdanggu.conflictMap(player); - var conflictList=others.filter(changshi=>{ - if(map[first]&&others.some(changshi2=>map[first]==changshi2)) return map[first]==changshi; - else return map2[first].includes(changshi); - }),list=others.slice(); - if(conflictList.length){ - var conflict=conflictList.randomGet(); + contentx: function () { + "step 0"; + var list = player.getStorage("mbdanggu").slice(); + var first = list.randomRemove(); + event.first = first; + var others = list.randomGets(4); + if (others.length == 1) event._result = { bool: true, links: others }; + else { + var map = { + scs_bilan: "scs_hankui", + scs_hankui: "scs_bilan", + scs_duangui: "scs_guosheng", + scs_guosheng: "scs_duangui", + }, + map2 = lib.skill.mbdanggu.conflictMap(player); + var conflictList = others.filter((changshi) => { + if (map[first] && others.some((changshi2) => map[first] == changshi2)) + return map[first] == changshi; + else return map2[first].includes(changshi); + }), + list = others.slice(); + if (conflictList.length) { + var conflict = conflictList.randomGet(); list.remove(conflict); - game.broadcastAll(function(changshi,player){ - if(lib.config.background_speak){ - if(player.isUnderControl(true)) game.playAudio('skill',changshi+'_enter'); - } - },conflict,player); + game.broadcastAll( + function (changshi, player) { + if (lib.config.background_speak) { + if (player.isUnderControl(true)) + game.playAudio("skill", changshi + "_enter"); + } + }, + conflict, + player + ); } - player.chooseButton([ - '党锢:请选择结党对象', - [[first],'character'], - '
              可选常侍
              ', - [others,'character'] - ],true).set('filterButton',button=>{ - return _status.event.canChoose.includes(button.link); - }).set('canChoose',list).set('ai',button=>Math.random()*10); + player + .chooseButton( + [ + "党锢:请选择结党对象", + [[first], "character"], + '
              可选常侍
              ', + [others, "character"], + ], + true + ) + .set("filterButton", (button) => { + return _status.event.canChoose.includes(button.link); + }) + .set("canChoose", list) + .set("ai", (button) => Math.random() * 10); } - 'step 1' - if(result.bool){ - var first=event.first; - var chosen=result.links[0]; - var skills=[]; - var list=lib.skill.mbdanggu.changshi; - var changshis=[first,chosen]; - player.unmarkAuto('mbdanggu',changshis); - player.storage.mbdanggu_current=changshis; - for(var changshi of changshis){ - for(var cs of list){ - if(changshi==cs[0]) skills.push(cs[1]); + "step 1"; + if (result.bool) { + var first = event.first; + var chosen = result.links[0]; + var skills = []; + var list = lib.skill.mbdanggu.changshi; + var changshis = [first, chosen]; + player.unmarkAuto("mbdanggu", changshis); + player.storage.mbdanggu_current = changshis; + for (var changshi of changshis) { + for (var cs of list) { + if (changshi == cs[0]) skills.push(cs[1]); } } - if(lib.skill.mbdanggu.isSingleShichangshi(player)){ - game.broadcastAll(function(player,first,chosen){ - player.name1=first; - player.node.avatar.setBackground(first,'character'); - player.node.name.innerHTML=get.slimName(first); - player.name2=chosen; - player.classList.add('fullskin2'); - player.node.avatar2.classList.remove('hidden'); - player.node.avatar2.setBackground(chosen,'character'); - player.node.name2.innerHTML=get.slimName(chosen); - if(player==game.me&&ui.fakeme){ - ui.fakeme.style.backgroundImage=player.node.avatar.style.backgroundImage; - } - },player,first,chosen); + if (lib.skill.mbdanggu.isSingleShichangshi(player)) { + game.broadcastAll( + function (player, first, chosen) { + player.name1 = first; + player.node.avatar.setBackground(first, "character"); + player.node.name.innerHTML = get.slimName(first); + player.name2 = chosen; + player.classList.add("fullskin2"); + player.node.avatar2.classList.remove("hidden"); + player.node.avatar2.setBackground(chosen, "character"); + player.node.name2.innerHTML = get.slimName(chosen); + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = + player.node.avatar.style.backgroundImage; + } + }, + player, + first, + chosen + ); } - game.log(player,'选择了常侍','#y'+get.translation(changshis)); - if(skills.length){ - player.addAdditionalSkill('mbdanggu',skills); - var str=''; - for(var i of skills){ - str+='【'+get.translation(i)+'】、'; + game.log(player, "选择了常侍", "#y" + get.translation(changshis)); + if (skills.length) { + player.addAdditionalSkill("mbdanggu", skills); + var str = ""; + for (var i of skills) { + str += "【" + get.translation(i) + "】、"; player.popup(i); } - str=str.slice(0,-1); - game.log(player,'获得了技能','#g'+str); + str = str.slice(0, -1); + game.log(player, "获得了技能", "#g" + str); } } }, - isSingleShichangshi:function(player){ - var map=lib.skill.mbdanggu.conflictMap(player); - return player.name=='shichangshi'&&(map[player.name1]&&map[player.name2]||map[player.name1]&&!player.name2||!player.name1&&!player.name2||player.name==player.name1&&!player.name2); + isSingleShichangshi: function (player) { + var map = lib.skill.mbdanggu.conflictMap(player); + return ( + player.name == "shichangshi" && + ((map[player.name1] && map[player.name2]) || + (map[player.name1] && !player.name2) || + (!player.name1 && !player.name2) || + (player.name == player.name1 && !player.name2)) + ); }, - mod:{ - aiValue:function(player,card,num){ - if(['shan','tao','wuxie','caochuan'].includes(card.name)) return num/10; + mod: { + aiValue: function (player, card, num) { + if (["shan", "tao", "wuxie", "caochuan"].includes(card.name)) return num / 10; }, - aiUseful:function(){ - return lib.skill.mbdanggu.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.mbdanggu.mod.aiValue.apply(this, arguments); }, }, - ai:{ - combo:'mbmowang', - nokeep:true, + ai: { + combo: "mbmowang", + nokeep: true, }, - intro:{ - mark:function(dialog,storage,player){ - dialog.addText('剩余常侍'); - dialog.addSmall([storage,'character']); - if(player.storage.mbdanggu_current&&player.isIn()){ - dialog.addText('当前常侍'); - dialog.addSmall([player.storage.mbdanggu_current,'character']); + intro: { + mark: function (dialog, storage, player) { + dialog.addText("剩余常侍"); + dialog.addSmall([storage, "character"]); + if (player.storage.mbdanggu_current && player.isIn()) { + dialog.addText("当前常侍"); + dialog.addSmall([player.storage.mbdanggu_current, "character"]); } - } + }, }, - subSkill:{ - back:{ - audio:'mbdanggu', - trigger:{global:'restEnd'}, - filter:function(event,player){ - return event.getTrigger().player==player; + subSkill: { + back: { + audio: "mbdanggu", + trigger: { global: "restEnd" }, + filter: function (event, player) { + return event.getTrigger().player == player; }, - forced:true, - content:function(){ - 'step 0' + forced: true, + content: function () { + "step 0"; delete player.storage.mbdanggu_current; - if(lib.skill.mbdanggu.isSingleShichangshi(player)){ - game.broadcastAll(function(player){ - player.name1=player.name; + if (lib.skill.mbdanggu.isSingleShichangshi(player)) { + game.broadcastAll(function (player) { + player.name1 = player.name; player.smoothAvatar(false); - player.node.avatar.setBackground(player.name,'character'); - player.node.name.innerHTML=get.slimName(player.name); + player.node.avatar.setBackground(player.name, "character"); + player.node.name.innerHTML = get.slimName(player.name); delete player.name2; - player.classList.remove('fullskin2'); - player.node.avatar2.classList.add('hidden'); - player.node.name2.innerHTML=''; - if(player==game.me&&ui.fakeme){ - ui.fakeme.style.backgroundImage=player.node.avatar.style.backgroundImage; + player.classList.remove("fullskin2"); + player.node.avatar2.classList.add("hidden"); + player.node.name2.innerHTML = ""; + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = + player.node.avatar.style.backgroundImage; } - },player); + }, player); } - 'step 1' - var next=game.createEvent('mbdanggu_clique'); - next.player=player; + "step 1"; + var next = game.createEvent("mbdanggu_clique"); + next.player = player; next.setContent(lib.skill.mbdanggu.contentx); player.draw(); - } - } - } - }, - mbmowang:{ - audio:2, - trigger:{player:'dieBefore'}, - filter:function(event,player){ - return player.getStorage('mbdanggu').length&&event.getParent().name!='giveup'&&player.maxHp>0; + }, + }, }, - derivation:'mbmowang_faq', - forced:true, - direct:true, - priority:15, - group:['mbmowang_die','mbmowang_return'], - content:function(){ - if(_status.mbmowang_return&&_status.mbmowang_return[player.playerid]){ + }, + mbmowang: { + audio: 2, + trigger: { player: "dieBefore" }, + filter: function (event, player) { + return ( + player.getStorage("mbdanggu").length && + event.getParent().name != "giveup" && + player.maxHp > 0 + ); + }, + derivation: "mbmowang_faq", + forced: true, + direct: true, + priority: 15, + group: ["mbmowang_die", "mbmowang_return"], + content: function () { + if (_status.mbmowang_return && _status.mbmowang_return[player.playerid]) { trigger.cancel(); - } - else{ - player.logSkill('mbmowang'); - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('die','shichangshiRest'); + } else { + player.logSkill("mbmowang"); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("die", "shichangshiRest"); }); trigger.setContent(lib.skill.mbmowang.dieContent); - trigger.includeOut=true; + trigger.includeOut = true; } }, - ai:{ - combo:'mbdanggu', - neg:true + ai: { + combo: "mbdanggu", + neg: true, }, - dieContent:function(){ - 'step 0' - event.forceDie=true; - if(source){ - game.log(player,'被',source,'杀害'); - if(source.stat[source.stat.length-1].kill==undefined){ - source.stat[source.stat.length-1].kill=1; - } - else{ - source.stat[source.stat.length-1].kill++; + dieContent: function () { + "step 0"; + event.forceDie = true; + if (source) { + game.log(player, "被", source, "杀害"); + if (source.stat[source.stat.length - 1].kill == undefined) { + source.stat[source.stat.length - 1].kill = 1; + } else { + source.stat[source.stat.length - 1].kill++; } + } else { + game.log(player, "阵亡"); } - else{ - game.log(player,'阵亡'); - } - if(player.isIn()&&(!_status.mbmowang_return||!_status.mbmowang_return[player.playerid])){ - event.reserveOut=true; - game.log(player,'进入了修整状态'); - game.log(player,'移出了游戏'); + if ( + player.isIn() && + (!_status.mbmowang_return || !_status.mbmowang_return[player.playerid]) + ) { + event.reserveOut = true; + game.log(player, "进入了修整状态"); + game.log(player, "移出了游戏"); //game.addGlobalSkill('mbmowang_return'); - if(!_status.mbmowang_return) _status.mbmowang_return={}; - _status.mbmowang_return[player.playerid]=1; + if (!_status.mbmowang_return) _status.mbmowang_return = {}; + _status.mbmowang_return[player.playerid] = 1; + } else event.finish(); + if (!game.countPlayer()) game.over(); + else if (player.hp != 0) { + player.changeHp(0 - player.hp, false).forceDie = true; } - else event.finish(); - if(!game.countPlayer()) game.over(); - else if(player.hp!=0){ - player.changeHp(0-player.hp,false).forceDie=true; - } - game.broadcastAll(function(player){ - if(player.isLinked()){ - if(get.is.linked2(player)){ - player.classList.toggle('linked2'); - } - else{ - player.classList.toggle('linked'); + game.broadcastAll(function (player) { + if (player.isLinked()) { + if (get.is.linked2(player)) { + player.classList.toggle("linked2"); + } else { + player.classList.toggle("linked"); } } - if(player.isTurnedOver()){ - player.classList.toggle('turnedover'); + if (player.isTurnedOver()) { + player.classList.toggle("turnedover"); } - },player); - game.addVideo('link',player,player.isLinked()); - game.addVideo('turnOver',player,player.classList.contains('turnedover')); - 'step 1' - event.trigger('die'); - 'step 2' - if(event.reserveOut){ - if(!game.reserveDead){ - for(var mark in player.marks){ - if(mark=='mbdanggu') continue; + }, player); + game.addVideo("link", player, player.isLinked()); + game.addVideo("turnOver", player, player.classList.contains("turnedover")); + "step 1"; + event.trigger("die"); + "step 2"; + if (event.reserveOut) { + if (!game.reserveDead) { + for (var mark in player.marks) { + if (mark == "mbdanggu") continue; player.unmarkSkill(mark); } - var count=1; - var list=Array.from(player.node.marks.childNodes); - if(list.some(i=>i.name=='mbdanggu')) count++; - while(player.node.marks.childNodes.length>count){ - var node=player.node.marks.lastChild; - if(node.name=='mbdanggu'){ - node=node.previousSibling; + var count = 1; + var list = Array.from(player.node.marks.childNodes); + if (list.some((i) => i.name == "mbdanggu")) count++; + while (player.node.marks.childNodes.length > count) { + var node = player.node.marks.lastChild; + if (node.name == "mbdanggu") { + node = node.previousSibling; } node.remove(); } - game.broadcast(function(player,count){ - while(player.node.marks.childNodes.length>count){ - var node=player.node.marks.lastChild; - if(node.name=='mbdanggu'){ - node=node.previousSibling; + game.broadcast( + function (player, count) { + while (player.node.marks.childNodes.length > count) { + var node = player.node.marks.lastChild; + if (node.name == "mbdanggu") { + node = node.previousSibling; + } + node.remove(); } - node.remove(); - } - },player,count); + }, + player, + count + ); } - for(var i in player.tempSkills){ + for (var i in player.tempSkills) { player.removeSkill(i); } - var skills=player.getSkills(); - for(var i=0;ii[0])); + "step 3"; + if (event.reserveOut) { + game.broadcastAll( + function (player, list) { + player.classList.add("out"); + if (list.includes(player.name1) || player.name1 == "shichangshi") { + player.smoothAvatar(false); + player.node.avatar.setBackground(player.name1 + "_dead", "character"); + } + if (list.includes(player.name2) || player.name2 == "shichangshi") { + player.smoothAvatar(true); + player.node.avatar2.setBackground(player.name2 + "_dead", "character"); + } + }, + player, + lib.skill.mbdanggu.changshi.map((i) => i[0]) + ); } - if(source&&lib.config.border_style=='auto'&&(lib.config.autoborder_count=='kill'||lib.config.autoborder_count=='mix')){ - switch(source.node.framebg.dataset.auto){ - case 'gold':case 'silver':source.node.framebg.dataset.auto='gold';break; - case 'bronze':source.node.framebg.dataset.auto='silver';break; - default:source.node.framebg.dataset.auto=lib.config.autoborder_start||'bronze'; + if ( + source && + lib.config.border_style == "auto" && + (lib.config.autoborder_count == "kill" || lib.config.autoborder_count == "mix") + ) { + switch (source.node.framebg.dataset.auto) { + case "gold": + case "silver": + source.node.framebg.dataset.auto = "gold"; + break; + case "bronze": + source.node.framebg.dataset.auto = "silver"; + break; + default: + source.node.framebg.dataset.auto = lib.config.autoborder_start || "bronze"; } - if(lib.config.autoborder_count=='kill'){ - source.node.framebg.dataset.decoration=source.node.framebg.dataset.auto; - } - else{ - var dnum=0; - for(var j=0;j=4) source.node.framebg.dataset.decoration='bronze';break; - case 'silver':if(dnum>=8) source.node.framebg.dataset.decoration='silver';break; - case 'gold':if(dnum>=12) source.node.framebg.dataset.decoration='gold';break; + source.node.framebg.dataset.decoration = ""; + switch (source.node.framebg.dataset.auto) { + case "bronze": + if (dnum >= 4) source.node.framebg.dataset.decoration = "bronze"; + break; + case "silver": + if (dnum >= 8) source.node.framebg.dataset.decoration = "silver"; + break; + case "gold": + if (dnum >= 12) source.node.framebg.dataset.decoration = "gold"; + break; } } - source.classList.add('topcount'); + source.classList.add("topcount"); } }, - subSkill:{ - die:{ - audio:'mbmowang', - trigger:{player:'phaseAfter'}, - forced:true, - forceDie:true, - content:function(){ - 'step 0' - if(lib.skill.mbdanggu.isSingleShichangshi(player)){ - if(!player.getStorage('mbdanggu').length){ - game.broadcastAll(function(player){ - player.name1=player.name; + subSkill: { + die: { + audio: "mbmowang", + trigger: { player: "phaseAfter" }, + forced: true, + forceDie: true, + content: function () { + "step 0"; + if (lib.skill.mbdanggu.isSingleShichangshi(player)) { + if (!player.getStorage("mbdanggu").length) { + game.broadcastAll(function (player) { + player.name1 = player.name; player.smoothAvatar(false); - player.node.avatar.setBackground(player.name+'_dead','character'); - player.node.name.innerHTML=get.slimName(player.name); + player.node.avatar.setBackground(player.name + "_dead", "character"); + player.node.name.innerHTML = get.slimName(player.name); delete player.name2; - player.classList.remove('fullskin2'); - player.node.avatar2.classList.add('hidden'); - player.node.name2.innerHTML=''; - if(player==game.me&&ui.fakeme){ - ui.fakeme.style.backgroundImage=player.node.avatar.style.backgroundImage; + player.classList.remove("fullskin2"); + player.node.avatar2.classList.add("hidden"); + player.node.name2.innerHTML = ""; + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = + player.node.avatar.style.backgroundImage; } - },player); + }, player); } } - if(!player.getStorage('mbdanggu').length){ + if (!player.getStorage("mbdanggu").length) { game.delay(); } - 'step 1' + "step 1"; player.die(); }, }, - return:{ - trigger:{player:'phaseBefore'}, - forced:true, - charlotte:true, - silent:true, - forceDie:true, - forceOut:true, - filter:function(event,player){ - return !event._mbmowang_return&&event.player.isOut()&&_status.mbmowang_return[event.player.playerid]; + return: { + trigger: { player: "phaseBefore" }, + forced: true, + charlotte: true, + silent: true, + forceDie: true, + forceOut: true, + filter: function (event, player) { + return ( + !event._mbmowang_return && + event.player.isOut() && + _status.mbmowang_return[event.player.playerid] + ); }, - content:function(){ - 'step 0' - trigger._mbmowang_return=true; - game.broadcastAll(function(player){ - player.classList.remove('out'); - },trigger.player); - game.log(trigger.player,'移回了游戏'); + content: function () { + "step 0"; + trigger._mbmowang_return = true; + game.broadcastAll(function (player) { + player.classList.remove("out"); + }, trigger.player); + game.log(trigger.player, "移回了游戏"); delete _status.mbmowang_return[trigger.player.playerid]; - trigger.player.recover(trigger.player.maxHp-trigger.player.hp); - game.broadcastAll(function(player){ - if(player.name1=='shichangshi'){ + trigger.player.recover(trigger.player.maxHp - trigger.player.hp); + game.broadcastAll(function (player) { + if (player.name1 == "shichangshi") { player.smoothAvatar(false); - player.node.avatar.setBackground(player.name1,'character'); + player.node.avatar.setBackground(player.name1, "character"); } - if(player.name2=='shichangshi'){ + if (player.name2 == "shichangshi") { player.smoothAvatar(true); - player.node.avatar2.setBackground(player.name2,'character'); + player.node.avatar2.setBackground(player.name2, "character"); } - },trigger.player); - 'step 1' - event.trigger('restEnd'); - } - } - } + }, trigger.player); + "step 1"; + event.trigger("restEnd"); + }, + }, + }, }, //张让 - scstaoluan:{ - audio:1, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('hes')>0; + scstaoluan: { + audio: 1, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("hes") > 0; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i=0;i0) return 0; - if(button.link[2]=='wugu') return; - var effect=player.getUseValue(button.link[2]); - if(effect>0) return effect; + check: function (button) { + var player = _status.event.player; + if (player.countCards("hs", button.link[2]) > 0) return 0; + if (button.link[2] == "wugu") return; + var effect = player.getUseValue(button.link[2]); + if (effect > 0) return effect; return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:true, - audio:'scstaoluan', - selectCard:1, - popname:true, - check:function(card){ - return 6-get.value(card); + filterCard: true, + audio: "scstaoluan", + selectCard: 1, + popname: true, + check: function (card) { + return 6 - get.value(card); }, - position:'hes', - viewAs:{name:links[0][2],nature:links[0][3]} - } + position: "hes", + viewAs: { name: links[0][2], nature: links[0][3] }, + }; + }, + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt:function(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order:4, - result:{ - player:1 + ai: { + order: 4, + result: { + player: 1, }, - threaten:1.9, + threaten: 1.9, }, }, //赵忠 - scschiyan:{ - audio:1, - shaRelated:true, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.hp>0&&event.target.countCards('he')>0; + scschiyan: { + audio: 1, + shaRelated: true, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && event.target.hp > 0 && event.target.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - var next=player.choosePlayerCard(trigger.target,'he',get.prompt('scschiyan',trigger.target)); - next.set('ai',function(button){ - if(!_status.event.goon) return 0; - var val=get.value(button.link); - if(button.link==_status.event.target.getEquip(2)) return 2*(val+3); + content: function () { + "step 0"; + var next = player.choosePlayerCard( + trigger.target, + "he", + get.prompt("scschiyan", trigger.target) + ); + next.set("ai", function (button) { + if (!_status.event.goon) return 0; + var val = get.value(button.link); + if (button.link == _status.event.target.getEquip(2)) return 2 * (val + 3); return val; }); - next.set('goon',get.attitude(player,trigger.target)<=0); - next.set('forceAuto',true); - 'step 1' - if(result.bool){ - var target=trigger.target; - player.logSkill('scschiyan',target); - target.addSkill('scschiyan_get'); - target.addToExpansion('giveAuto',result.cards,target).gaintag.add('scschiyan_get'); + next.set("goon", get.attitude(player, trigger.target) <= 0); + next.set("forceAuto", true); + "step 1"; + if (result.bool) { + var target = trigger.target; + player.logSkill("scschiyan", target); + target.addSkill("scschiyan_get"); + target.addToExpansion("giveAuto", result.cards, target).gaintag.add("scschiyan_get"); } }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)>0) return false; - if(tag=='directHit_ai') return arg.target.hp>=Math.max(1,arg.target.countCards('h')-1); - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (get.attitude(player, arg.target) > 0) return false; + if (tag == "directHit_ai") + return arg.target.hp >= Math.max(1, arg.target.countCards("h") - 1); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } + }, }, - group:'scschiyan_damage', - subSkill:{ - get:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('scschiyan_get').length>0; + group: "scschiyan_damage", + subSkill: { + get: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("scschiyan_get").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('scschiyan_get'); - player.gain(cards,'draw'); - game.log(player,'收回了'+get.cnNumber(cards.length)+'张“鸱咽”牌'); - 'step 1' - player.removeSkill('scschiyan_get'); + content: function () { + "step 0"; + var cards = player.getExpansions("scschiyan_get"); + player.gain(cards, "draw"); + game.log(player, "收回了" + get.cnNumber(cards.length) + "张“鸱咽”牌"); + "step 1"; + player.removeSkill("scschiyan_get"); }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('scschiyan_get'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("scschiyan_get"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, - damage:{ - audio:'scschiyan', - trigger:{source:'damageBegin1'}, - forced:true, - locked:false, - logTarget:'player', - filter:function(event,player){ - var target=event.player; - return event.getParent().name=='sha'&&player.countCards('h')>=target.countCards('h')&&player.countCards('e')>=target.countCards('e'); + damage: { + audio: "scschiyan", + trigger: { source: "damageBegin1" }, + forced: true, + locked: false, + logTarget: "player", + filter: function (event, player) { + var target = event.player; + return ( + event.getParent().name == "sha" && + player.countCards("h") >= target.countCards("h") && + player.countCards("e") >= target.countCards("e") + ); }, - content:function(){ + content: function () { trigger.num++; }, - } - } + }, + }, }, //孙璋 - scszimou:{ - audio:1, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var num=player.getHistory('useCard',evtx=>evtx.getParent('phaseUse')==evt).length; - return num==2||num==4||num==6; + scszimou: { + audio: 1, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var num = player.getHistory( + "useCard", + (evtx) => evtx.getParent("phaseUse") == evt + ).length; + return num == 2 || num == 4 || num == 6; }, - content:function(){ - var evt=trigger.getParent('phaseUse'); - var num=player.getHistory('useCard',evtx=>evtx.getParent('phaseUse')==evt).length; - var cards=[]; - if(num==2){ - var card=get.cardPile2(card=>{ - return ['jiu','xionghuangjiu'].includes(card.name); + content: function () { + var evt = trigger.getParent("phaseUse"); + var num = player.getHistory( + "useCard", + (evtx) => evtx.getParent("phaseUse") == evt + ).length; + var cards = []; + if (num == 2) { + var card = get.cardPile2((card) => { + return ["jiu", "xionghuangjiu"].includes(card.name); }); - if(card) cards.push(card); - } - else if(num==4){ - var card=get.cardPile2(card=>{ - return card.name=='sha'; + if (card) cards.push(card); + } else if (num == 4) { + var card = get.cardPile2((card) => { + return card.name == "sha"; }); - if(card) cards.push(card); - } - else if(num==6){ - var card=get.cardPile2(card=>{ - return card.name=='juedou'; + if (card) cards.push(card); + } else if (num == 6) { + var card = get.cardPile2((card) => { + return card.name == "juedou"; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, }, //毕岚 - scspicai:{ - audio:1, - enable:'phaseUse', - usable:1, - frequent:true, - content:function(){ - 'step 0' - event.cards=[]; - event.suits=[]; - 'step 1' - player.judge(function(result){ - var evt=_status.event.getParent('scspicai'); - if(evt&&evt.suits&&evt.suits.includes(get.suit(result))) return 0; - return 1; - }).set('callback',lib.skill.scspicai.callback).judge2=function(result){ - return result.bool?true:false; + scspicai: { + audio: 1, + enable: "phaseUse", + usable: 1, + frequent: true, + content: function () { + "step 0"; + event.cards = []; + event.suits = []; + "step 1"; + player + .judge(function (result) { + var evt = _status.event.getParent("scspicai"); + if (evt && evt.suits && evt.suits.includes(get.suit(result))) return 0; + return 1; + }) + .set("callback", lib.skill.scspicai.callback).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 2' - var cards=cards.filterInD(); - if(cards.length) player.chooseTarget('将'+get.translation(cards)+'交给一名角色',true).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - if(target.hasSkillTag('nogain')) att/=10; - return att; - }); - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - target.gain(cards,'gain2').giver=player; - } + "step 2"; + var cards = cards.filterInD(); + if (cards.length) + player + .chooseTarget("将" + get.translation(cards) + "交给一名角色", true) + .set("ai", function (target) { + var player = _status.event.player; + var att = + get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + if (target.hasSkillTag("nogain")) att /= 10; + return att; + }); else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + target.gain(cards, "gain2").giver = player; + } else event.finish(); }, - callback:function(){ - 'step 0' - var evt=event.getParent(2); + callback: function () { + "step 0"; + var evt = event.getParent(2); event.getParent().orderingCards.remove(event.judgeResult.card); evt.cards.push(event.judgeResult.card); - if(event.getParent().result.bool){ + if (event.getParent().result.bool) { evt.suits.push(event.getParent().result.suit); - player.chooseBool('是否继续发动【庀材】?').set('frequentSkill','scspicai'); - } - else event._result={bool:false}; - 'step 1' - if(result.bool) event.getParent(2).redo(); + player.chooseBool("是否继续发动【庀材】?").set("frequentSkill", "scspicai"); + } else event._result = { bool: false }; + "step 1"; + if (result.bool) event.getParent(2).redo(); }, - ai:{ - order:9, - result:{ - player:1, + ai: { + order: 9, + result: { + player: 1, }, }, }, //夏恽 - scsyaozhuo:{ - audio:1, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ + scsyaozhuo: { + audio: 1, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { return player.canCompare(current); }); }, - filterTarget:function(card,player,current){ + filterTarget: function (card, player, current) { return player.canCompare(current); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - target.skip('phaseDraw'); - target.addTempSkill('scsyaozhuo_skip',{player:'phaseDrawSkipped'}); - } - else player.chooseToDiscard(2,true,'he'); + "step 1"; + if (result.bool) { + target.skip("phaseDraw"); + target.addTempSkill("scsyaozhuo_skip", { player: "phaseDrawSkipped" }); + } else player.chooseToDiscard(2, true, "he"); }, - subSkill:{ - skip:{ - mark:true, - intro:{content:'跳过下一个摸牌阶段'}, - } + subSkill: { + skip: { + mark: true, + intro: { content: "跳过下一个摸牌阶段" }, + }, }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.skipList.includes('phaseDraw')||target.hasSkill('pingkou')) return 0; - var hs=player.getCards('h').sort(function(a,b){ - return b.number-a.number; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.skipList.includes("phaseDraw") || target.hasSkill("pingkou")) return 0; + var hs = player.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - var ts=target.getCards('h').sort(function(a,b){ - return b.number-a.number; + var ts = target.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - if(!hs.length||!ts.length) return 0; - if(hs[0].number>ts[0].number-2&&hs[0].number>5) return -1; + if (!hs.length || !ts.length) return 0; + if (hs[0].number > ts[0].number - 2 && hs[0].number > 5) return -1; return 0; }, }, }, }, //韩悝 - scsxiaolu:{ - audio:1, - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' + scsxiaolu: { + audio: 1, + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; player.draw(2); - 'step 1' - var num=player.countCards('he'); - if(!num) event.finish(); - else if(num<2) event._result={index:1}; - else player.chooseControl().set('choiceList',[ - '将两张牌交给一名其他角色', - '弃置两张牌', - ]).set('ai',function(){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })) return 0; - return 1; - }); - 'step 2' - if(result.index==0){ + "step 1"; + var num = player.countCards("he"); + if (!num) event.finish(); + else if (num < 2) event._result = { index: 1 }; + else + player + .chooseControl() + .set("choiceList", ["将两张牌交给一名其他角色", "弃置两张牌"]) + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) + return 0; + return 1; + }); + "step 2"; + if (result.index == 0) { player.chooseCardTarget({ - position:'he', - filterCard:true, - selectCard:2, - filterTarget:function(card,player,target){ - return player!=target; + position: "he", + filterCard: true, + selectCard: 2, + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ + ai1: function (card) { return get.unuseful(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkillTag('nogain')) att/=10; - if(target.hasJudge('lebu')) att/=5; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 10; + if (target.hasJudge("lebu")) att /= 5; return att; }, - prompt:'选择两张牌,交给一名其他角色', - forced:true, + prompt: "选择两张牌,交给一名其他角色", + forced: true, }); - } - else{ - player.chooseToDiscard(2,true,'he'); + } else { + player.chooseToDiscard(2, true, "he"); event.finish(); } - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.give(result.cards,target); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.give(result.cards, target); } }, - ai:{ - order:9, - result:{player:2} - } + ai: { + order: 9, + result: { player: 2 }, + }, }, //栗嵩 - scskuiji:{ - audio:1, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + scskuiji: { + audio: 1, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - event.list1=[]; - event.list2=[]; - if(player.countCards('h')>0){ - var chooseButton=player.chooseButton(4,['你的手牌',player.getCards('h'),get.translation(target.name)+'的手牌',target.getCards('h')]); + content: function () { + "step 0"; + event.list1 = []; + event.list2 = []; + if (player.countCards("h") > 0) { + var chooseButton = player.chooseButton(4, [ + "你的手牌", + player.getCards("h"), + get.translation(target.name) + "的手牌", + target.getCards("h"), + ]); + } else { + var chooseButton = player.chooseButton(4, [ + get.translation(target.name) + "的手牌", + target.getCards("h"), + ]); } - else{ - var chooseButton=player.chooseButton(4,[get.translation(target.name)+'的手牌',target.getCards('h')]); - } - chooseButton.set('target',target); - chooseButton.set('ai',function(button){ - var player=_status.event.player; - var target=_status.event.target; - var ps=[]; - var ts=[]; - for(var i=0;i0) return false; + logTarget: "target", + locked: false, + check: function (event, player) { + var target = event.target; + if (get.attitude(player, target) > 0) return false; return true; }, - content:function(){ - var num=2; - var evt=trigger.getParent(); - var suit=get.suit(trigger.card); - var suits=[]; - if(num>0){ - if(typeof evt.baseDamage!='number') evt.baseDamage=1; - var cards=get.cards(num); - player.showCards(cards.slice(0),get.translation(player)+'发动了【叱吓】'); - while(cards.length>0){ - var card=cards.pop(); - var suitx=get.suit(card,false); + content: function () { + var num = 2; + var evt = trigger.getParent(); + var suit = get.suit(trigger.card); + var suits = []; + if (num > 0) { + if (typeof evt.baseDamage != "number") evt.baseDamage = 1; + var cards = get.cards(num); + player.showCards(cards.slice(0), get.translation(player) + "发动了【叱吓】"); + while (cards.length > 0) { + var card = cards.pop(); + var suitx = get.suit(card, false); suits.add(suitx); - if(suit==suitx) evt.baseDamage++; + if (suit == suitx) evt.baseDamage++; } game.updateRoundNumber(); } - evt._scschihe_player=player; - var target=trigger.target; - target.addTempSkill('scschihe_block'); - if(!target.storage.scschihe_block) target.storage.scschihe_block=[]; - target.storage.scschihe_block.push([evt.card,suits]); + evt._scschihe_player = player; + var target = trigger.target; + target.addTempSkill("scschihe_block"); + if (!target.storage.scschihe_block) target.storage.scschihe_block = []; + target.storage.scschihe_block.push([evt.card, suits]); lib.skill.scschihe.updateBlocker(target); }, - updateBlocker:function(player){ - var list=[],storage=player.storage.scschihe_block; - if(storage&&storage.length){ - for(var i of storage) list.addArray(i[1]); + updateBlocker: function (player) { + var list = [], + storage = player.storage.scschihe_block; + if (storage && storage.length) { + for (var i of storage) list.addArray(i[1]); } - player.storage.scschihe_blocker=list; + player.storage.scschihe_blocker = list; }, - ai:{ - threaten:2.5, - halfneg:true, + ai: { + threaten: 2.5, + halfneg: true, }, - subSkill:{ - block:{ - mod:{ - cardEnabled:function(card,player){ - if(!player.storage.scschihe_blocker) return; - var suit=get.suit(card); - if(suit=='none'||suit=='unsure') return; - var evt=_status.event; - if(evt.name!='chooseToUse') evt=evt.getParent('chooseToUse'); - if(!evt||!evt.respondTo||evt.respondTo[1].name!='sha') return; - if(player.storage.scschihe_blocker.includes(suit)) return false; + subSkill: { + block: { + mod: { + cardEnabled: function (card, player) { + if (!player.storage.scschihe_blocker) return; + var suit = get.suit(card); + if (suit == "none" || suit == "unsure") return; + var evt = _status.event; + if (evt.name != "chooseToUse") evt = evt.getParent("chooseToUse"); + if (!evt || !evt.respondTo || evt.respondTo[1].name != "sha") return; + if (player.storage.scschihe_blocker.includes(suit)) return false; }, }, - trigger:{ - player:['damageBefore','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded','useCardToEnd'], - global:['useCardEnd'], + trigger: { + player: ["damageBefore", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded", "useCardToEnd"], + global: ["useCardEnd"], }, - forced:true, - firstDo:true, - charlotte:true, - popup:false, - onremove:function(player){ + forced: true, + firstDo: true, + charlotte: true, + popup: false, + onremove: function (player) { delete player.storage.scschihe_block; delete player.storage.scschihe_blocker; }, - filter:function(event,player){ - if(!event.card||!player.storage.scschihe_block) return false; - for(var i of player.storage.scschihe_block){ - if(i[0]==event.card) return true; + filter: function (event, player) { + if (!event.card || !player.storage.scschihe_block) return false; + for (var i of player.storage.scschihe_block) { + if (i[0] == event.card) return true; } return false; }, - content:function(){ - var storage=player.storage.scschihe_block; - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 + ) { + var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return (name2=='diamond'?(5-get.value(card)):20-get.value(card)); + if (name2 == get.suit(card, player)) + return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, - position:'hes', - filterCard:function(card,player,event){ - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.suit(card,player); - if(name=='club'&&filter({name:'shan',cards:[card]},player,event)) return true; - if(name=='diamond'&&filter({name:'sha',cards:[card],nature:'fire'},player,event)) return true; - if(name=='spade'&&filter({name:'wuxie',cards:[card]},player,event)) return true; - if(name=='heart'&&filter({name:'tao',cards:[card]},player,event)) return true; + position: "hes", + filterCard: function (card, player, event) { + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.suit(card, player); + if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if ( + name == "diamond" && + filter({ name: "sha", cards: [card], nature: "fire" }, player, event) + ) + return true; + if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) + return true; + if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, - filter:function(event,player){ - var filter=event.filterCard; - if(filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)&&player.countCards('hes',{suit:'diamond'})) return true; - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hes',{suit:'club'})) return true; - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hes',{suit:'heart'})) return true; - if(filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)&&player.countCards('hes',{suit:'spade'})) return true; + filter: function (event, player) { + var filter = event.filterCard; + if ( + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && + player.countCards("hes", { suit: "diamond" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hes", { suit: "club" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hes", { suit: "heart" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && + player.countCards("hes", { suit: "spade" }) + ) + return true; return false; }, - precontent:function(){ - 'step 0' - player.addTempSkill('scsanruo_effect'); + precontent: function () { + "step 0"; + player.addTempSkill("scsanruo_effect"); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hes',{suit:name})) return false; + if (!player.countCards("hes", { suit: name })) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard:function(player,name){ - if(name=='wuxie'&&_status.connectMode&&player.countCards('hes')>0) return true; - if(name=='wuxie') return player.countCards('hes',{suit:'spade'})>0; - if(name=='tao') return player.countCards('hes',{suit:'heart'})>0; + hiddenCard: function (player, name) { + if (name == "wuxie" && _status.connectMode && player.countCards("hes") > 0) return true; + if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; + if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, - subSkill:{ - effect:{ - audio:'scsanruo', - trigger:{ - player:['useCard','respond'], + subSkill: { + effect: { + audio: "scsanruo", + trigger: { + player: ["useCard", "respond"], }, - filter:function(event,player){ - return event.skill=='scsanruo'; + filter: function (event, player) { + return event.skill == "scsanruo"; }, - direct:true, - forced:true, - charlotte:true, - content:function(){ - 'step 0' - var name=trigger.card.name; - var next=game.createEvent('scsanruo_'+name); - next.player=player; - next.setContent(lib.skill.scsanruo_effect[name=='shan'?'sha':name]||function(){}); + direct: true, + forced: true, + charlotte: true, + content: function () { + "step 0"; + var name = trigger.card.name; + var next = game.createEvent("scsanruo_" + name); + next.player = player; + next.setContent( + lib.skill.scsanruo_effect[name == "shan" ? "sha" : name] || function () {} + ); }, - sha:function(){ - 'step 0' - var trigger=event.getParent().getTrigger(); - if(trigger.name=='useCard'){ - var target=lib.skill.chongzhen.logTarget(trigger,player); + sha: function () { + "step 0"; + var trigger = event.getParent().getTrigger(); + if (trigger.name == "useCard") { + var target = lib.skill.chongzhen.logTarget(trigger, player); + } else { + var target = trigger.source; } - else{ - var target=trigger.source; - } - event.target=target; - if(!target||!target.countGainableCards(player,'he')) event._result={bool:false}; - else player.chooseBool(get.prompt('scsanruo_effect',target),'获得该角色的一张牌').set('ai',()=>{ - return _status.event.goon; - }).set('goon',get.attitude(player,target)<1); - 'step 1' - if(result.bool){ - player.logSkill('scsanruo_effect',target); - player.gainPlayerCard(target,'he',true); + event.target = target; + if (!target || !target.countGainableCards(player, "he")) + event._result = { bool: false }; + else + player + .chooseBool(get.prompt("scsanruo_effect", target), "获得该角色的一张牌") + .set("ai", () => { + return _status.event.goon; + }) + .set("goon", get.attitude(player, target) < 1); + "step 1"; + if (result.bool) { + player.logSkill("scsanruo_effect", target); + player.gainPlayerCard(target, "he", true); } }, - tao:function(){ - 'step 0' - player.chooseTarget(get.prompt('scsanruo'),'获得一名其他角色的一张牌',(card,player,target)=>{ - return target.countGainableCards(player,'he')&&target!=player; - }).set('ai',target=>{ - return 1-get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('scsanruo_effect',target); - player.gainPlayerCard(target,'he',true); + tao: function () { + "step 0"; + player + .chooseTarget( + get.prompt("scsanruo"), + "获得一名其他角色的一张牌", + (card, player, target) => { + return target.countGainableCards(player, "he") && target != player; + } + ) + .set("ai", (target) => { + return 1 - get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("scsanruo_effect", target); + player.gainPlayerCard(target, "he", true); } }, - wuxie:function(){ - 'step 0' - var trigger=event.getParent().getTrigger(); - if(!trigger.respondTo){event.finish();return;} - var target=trigger.respondTo[0]; - event.target=target; - if(!target||!target.countGainableCards(player,player==target?'e':'he')) event._result={bool:false}; - else player.chooseBool(get.prompt('scsanruo_effect',target),'获得该角色的一张牌').set('ai',()=>{ - return _status.event.goon; - }).set('goon',get.attitude(player,target)<1); - 'step 1' - if(result.bool){ - player.logSkill('scsanruo_effect',target); - player.gainPlayerCard(target,player==target?'e':'he',true); + wuxie: function () { + "step 0"; + var trigger = event.getParent().getTrigger(); + if (!trigger.respondTo) { + event.finish(); + return; } - } + var target = trigger.respondTo[0]; + event.target = target; + if (!target || !target.countGainableCards(player, player == target ? "e" : "he")) + event._result = { bool: false }; + else + player + .chooseBool(get.prompt("scsanruo_effect", target), "获得该角色的一张牌") + .set("ai", () => { + return _status.event.goon; + }) + .set("goon", get.attitude(player, target) < 1); + "step 1"; + if (result.bool) { + player.logSkill("scsanruo_effect", target); + player.gainPlayerCard(target, player == target ? "e" : "he", true); + } + }, }, }, }, - scsmiaoyu:{ - audio:'scsanruo', - enable:['chooseToUse','chooseToRespond'], - prompt:'将至多两张♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】使用或打出', - viewAs:function(cards,player){ - var name=false; - var nature=null; - switch(get.suit(cards[0],player)){ - case 'club':name='shan';break; - case 'diamond':name='sha';nature='fire';break; - case 'spade':name='wuxie';break; - case 'heart':name='tao';break; + scsmiaoyu: { + audio: "scsanruo", + enable: ["chooseToUse", "chooseToRespond"], + prompt: "将至多两张♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】使用或打出", + viewAs: function (cards, player) { + var name = false; + var nature = null; + switch (get.suit(cards[0], player)) { + case "club": + name = "shan"; + break; + case "diamond": + name = "sha"; + nature = "fire"; + break; + case "spade": + name = "wuxie"; + break; + case "heart": + name = "tao"; + break; } //返回判断结果 - if(name) return {name:name,nature:nature}; + if (name) return { name: name, nature: nature }; return null; }, - check:function(card){ - if(ui.selected.cards.length) return 0; - var player=_status.event.player; - if(_status.event.type=='phase'){ - var max=0; + check: function (card) { + if (ui.selected.cards.length) return 0; + var player = _status.event.player; + if (_status.event.type == "phase") { + var max = 0; var name2; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 + ) { + var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.suit(card,player)) return (name2=='diamond'?(5-get.value(card)):20-get.value(card)); + if (name2 == get.suit(card, player)) + return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, - selectCard:[1,2], - complexCard:true, - position:'hes', - filterCard:function(card,player,event){ - if(ui.selected.cards.length) return get.suit(card,player)==get.suit(ui.selected.cards[0],player); - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.suit(card,player); - if(name=='club'&&filter({name:'shan',cards:[card]},player,event)) return true; - if(name=='diamond'&&filter({name:'sha',cards:[card],nature:'fire'},player,event)) return true; - if(name=='spade'&&filter({name:'wuxie',cards:[card]},player,event)) return true; - if(name=='heart'&&filter({name:'tao',cards:[card]},player,event)) return true; + selectCard: [1, 2], + complexCard: true, + position: "hes", + filterCard: function (card, player, event) { + if (ui.selected.cards.length) + return get.suit(card, player) == get.suit(ui.selected.cards[0], player); + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.suit(card, player); + if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if ( + name == "diamond" && + filter({ name: "sha", cards: [card], nature: "fire" }, player, event) + ) + return true; + if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) + return true; + if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, - filter:function(event,player){ - var filter=event.filterCard; - if(filter(get.autoViewAs({name:'sha',nature:'fire'},'unsure'),player,event)&&player.countCards('hes',{suit:'diamond'})) return true; - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hes',{suit:'club'})) return true; - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hes',{suit:'heart'})) return true; - if(filter(get.autoViewAs({name:'wuxie'},'unsure'),player,event)&&player.countCards('hes',{suit:'spade'})) return true; + filter: function (event, player) { + var filter = event.filterCard; + if ( + filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && + player.countCards("hes", { suit: "diamond" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hes", { suit: "club" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hes", { suit: "heart" }) + ) + return true; + if ( + filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && + player.countCards("hes", { suit: "spade" }) + ) + return true; return false; }, - precontent:function(){ - player.addTempSkill('scsmiaoyu_num'); - player.addTempSkill('scsmiaoyu_discard'); + precontent: function () { + player.addTempSkill("scsmiaoyu_num"); + player.addTempSkill("scsmiaoyu_discard"); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hes',{suit:name})) return false; + if (!player.countCards("hes", { suit: name })) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i0&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) > 0 && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard:function(player,name){ - if(name=='wuxie'&&_status.connectMode&&player.countCards('hs')>0) return true; - if(name=='wuxie') return player.countCards('hes',{suit:'spade'})>0; - if(name=='tao') return player.countCards('hes',{suit:'heart'})>0; + hiddenCard: function (player, name) { + if (name == "wuxie" && _status.connectMode && player.countCards("hs") > 0) return true; + if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; + if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, - subSkill:{ - num:{ - charlotte:true, - trigger:{player:'useCard'}, - filter:function(event){ - return ['sha','tao'].includes(event.card.name)&&event.skill=='scsmiaoyu'&&event.cards&&event.cards.length==2; + subSkill: { + num: { + charlotte: true, + trigger: { player: "useCard" }, + filter: function (event) { + return ( + ["sha", "tao"].includes(event.card.name) && + event.skill == "scsmiaoyu" && + event.cards && + event.cards.length == 2 + ); }, - forced:true, - popup:false, - content:function(){ + forced: true, + popup: false, + content: function () { trigger.baseDamage++; }, }, - discard:{ - charlotte:true, - trigger:{player:['useCardAfter','respondAfter']}, - autodelay:function(event){ - return event.name=='respond'?0.5:false; + discard: { + charlotte: true, + trigger: { player: ["useCardAfter", "respondAfter"] }, + autodelay: function (event) { + return event.name == "respond" ? 0.5 : false; }, - filter:function(event,player){ - return ['shan','wuxie'].includes(event.card.name)&&event.skill=='scsmiaoyu'&&event.cards&&event.cards.length==2&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.countDiscardableCards(player,'he'); + filter: function (event, player) { + return ( + ["shan", "wuxie"].includes(event.card.name) && + event.skill == "scsmiaoyu" && + event.cards && + event.cards.length == 2 && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.countDiscardableCards(player, "he") + ); }, - forced:true, - popup:false, - content:function(){ - player.line(_status.currentPhase,'green'); - player.discardPlayerCard(_status.currentPhase,'he',true); + forced: true, + popup: false, + content: function () { + player.line(_status.currentPhase, "green"); + player.discardPlayerCard(_status.currentPhase, "he", true); }, }, }, }, //牵招 - mbshihe:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(current=>player.canCompare(current)); + mbshihe: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => player.canCompare(current)); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.canCompare(target); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - target.addTempSkill('mbshihe_prevent',{player:'phaseAfter'}); - target.markAuto('mbshihe_prevent',[player]); - } - else{ - var cards=player.getCards('he',card=>{ - return lib.filter.cardDiscardable(card,player,'mbshihe'); + "step 1"; + if (result.bool) { + target.addTempSkill("mbshihe_prevent", { player: "phaseAfter" }); + target.markAuto("mbshihe_prevent", [player]); + } else { + var cards = player.getCards("he", (card) => { + return lib.filter.cardDiscardable(card, player, "mbshihe"); }); - if(cards.length>0) player.discard(cards.randomGet()); + if (cards.length > 0) player.discard(cards.randomGet()); } }, - ai:{ - order:6, - result:{ - player:function(player,target){ - if((get.realAttitude||get.attitude)(target,player)>=0||get.damageEffect(player,target,player)>=0) return 0; - var card=player.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + ai: { + order: 6, + result: { + player: function (player, target) { + if ( + (get.realAttitude || get.attitude)(target, player) >= 0 || + get.damageEffect(player, target, player) >= 0 + ) + return 0; + var card = player.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); })[0]; - return get.number(card)>=10||get.number(card)>=7&&target.countCards('h')<=2?1:-1; + return get.number(card) >= 10 || + (get.number(card) >= 7 && target.countCards("h") <= 2) + ? 1 + : -1; }, }, }, - subSkill:{ - prevent:{ - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - if(get.mode()=='identity') return player.getStorage('mbshihe_prevent').includes(event.player); - return player.getStorage('mbshihe_prevent').some(target=>event.player.isFriendOf(target)); + subSkill: { + prevent: { + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + if (get.mode() == "identity") + return player.getStorage("mbshihe_prevent").includes(event.player); + return player + .getStorage("mbshihe_prevent") + .some((target) => event.player.isFriendOf(target)); }, - onremove:true, - forced:true, - charlotte:true, - content:function(){ + onremove: true, + forced: true, + charlotte: true, + content: function () { trigger.cancel(); }, - mark:true, - marktext:'吓', - intro:{ - content:function(storage,player){ - var targets=storage.filter(i=>i.isIn()); - return '被'+get.translation(targets)+'吓到了,对他'+(targets.length>1?'们':'')+(get.mode()!='identity'?'和他的友方角色':'')+'打不出伤害'; + mark: true, + marktext: "吓", + intro: { + content: function (storage, player) { + var targets = storage.filter((i) => i.isIn()); + return ( + "被" + + get.translation(targets) + + "吓到了,对他" + + (targets.length > 1 ? "们" : "") + + (get.mode() != "identity" ? "和他的友方角色" : "") + + "打不出伤害" + ); }, }, - ai:{ - effect:{ - player:function(card,player,target,current){ - if(get.tag(card,'damage')){ - var bool=false; - if(get.mode()=='identity'&&player.getStorage('mbshihe_prevent').includes(target)) bool=true; - if(get.mode()!='identity'&&player.getStorage('mbshihe_prevent').some(targetx=>target.isFriendOf(targetx))) bool=true; - if(bool) return 'zeroplayertarget'; + ai: { + effect: { + player: function (card, player, target, current) { + if (get.tag(card, "damage")) { + var bool = false; + if ( + get.mode() == "identity" && + player.getStorage("mbshihe_prevent").includes(target) + ) + bool = true; + if ( + get.mode() != "identity" && + player + .getStorage("mbshihe_prevent") + .some((targetx) => target.isFriendOf(targetx)) + ) + bool = true; + if (bool) return "zeroplayertarget"; } - } - }, - } - } - } - }, - mbzhenfu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasHistory('lose',evt=>{ - return evt.type=='discard'; - }); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('mbzhenfu'),'令一名其他角色获得1点护甲',(card,player,target)=>{ - return target!=player&&target.hujia<5; - }).set('ai',target=>{ - return Math.max(0,get.threaten(target))*get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mbzhenfu',target); - target.changeHujia(1,null,true); - } - }, - ai:{ - expose:0.2, - }, - }, - //☆胃炎 - mbguli:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:-1, - position:'h', - filter:function(event,player){ - if(player.hasSkill('mbguli_used')) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var card of hs){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2===false) return false; - } - return event.filterCard(get.autoViewAs({name:'sha'},hs)); - }, - viewAs:{ - name:'sha', - storage:{mbguli:true} - }, - onuse:function(links,player){ - player.addTempSkill('mbguli_used','phaseUseAfter'); - }, - ai:{ - order:1, - threaten:1.14, - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.name=='sha'&&arg.card&&arg.card.storage&&arg.card.storage.mbguli) return true; - return false; - } - }, - subSkill:{ - used:{ - audio:'mbguli', - trigger:{global:'useCardAfter'}, - charlotte:true, - prompt2:'失去1点体力,然后将手牌摸至体力上限', - check:function(event,player){ - var num=player.maxHp-player.countCards('h'); - return num>=3&&player.hp>=2||num>=2&&player.hp>=3; - }, - filter:function(event,player){ - return event.card.storage&&event.card.storage.mbguli&&game.hasPlayer2(current=>{ - return current.hasHistory('sourceDamage',evt=>evt.card==event.card); - }); - }, - content:function(){ - 'step 0' - player.loseHp(); - 'step 1' - player.drawTo(player.maxHp); - }, - group:'mbguli_unequip', - }, - unequip:{ - trigger:{ - player:'useCardToPlayered', - }, - filter:function({card}){ - return card.name=='sha' && card.storage && card.storage.mbguli; - }, - forced:true, - popup:false, - logTarget:'target', - content:function(){ - trigger.target.addTempSkill('qinggang2'); - trigger.target.storage.qinggang2.add(trigger.card); - trigger.target.markSkill('qinggang2'); - }, - }, - }, - }, - mbaosi:{ - audio:2, - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - return player.inRange(event.player)&&player.isPhaseUsing()&&event.player.isIn()&&!player.getStorage('mbaosi_inf').includes(event.player); - }, - logTarget:'player', - content:function(){ - player.addTempSkill('mbaosi_inf','phaseUseAfter'); - player.markAuto('mbaosi_inf',[trigger.player]); - }, - subSkill:{ - inf:{ - charlotte:true, - onremove:true, - forced:true, - intro:{content:'对$使用牌无次数限制'}, - mod:{ - cardUsableTarget:function(card,player,target){ - if(player.getStorage('mbaosi_inf').includes(target)) return true; - }, - }, - } - } - }, - // 界曹休 - xinqingxi:{ - audio:2, - usable:1, - trigger:{source:'damageBegin1'}, - check:function(event,player){ - return get.attitude(player,event.player)<0; - }, - filter:function(event,player){ - return event.player!=player; - }, - content:function(){ - 'step 0' - var num=Math.max(1,4-get.distance(player,trigger.player)); - if(trigger.player.countCards('h')2){ - return 0; - } - return 8-get.value(card); - } - }); - } - 'step 1' - if(!result.bool){ - trigger.num++; - } - } - }, - // 界朱桓 - xinpingkou:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.getHistory('skipped').length>0; - }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.getHistory('skipped').length],get.prompt2('xinpingkou'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - player.logSkill('xinpingkou',result.targets); - event.targets=result.targets.slice(0).sortBySeat(); - } - else{ - event.finish(); - } - 'step 2' - if(event.targets&&event.targets.length){ - event.targets.shift().damage(); - event.redo(); - } - 'step 3' - var card=get.cardPile2(card=>get.type(card,false)=='equip'); - if(card) player.gain(card,'gain2'); - }, - ai:{ - combo:'fenli', - effect:{ - target:function(card){ - if(card.name=='lebu'||card.name=='bingliang') return 0.5; - } - } - } - }, - // 彭羕 - spdaming:{ - audio:3, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - locked:false, - global:'spdaming_give', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); - }, - change:function(player,num){ - if(!player.storage.spdaming) player.storage.spdaming=0; - if(!num) return; - player.storage.spdaming+=num; - player.markSkill('spdaming'); - game.log(player,(num>0?'获得了':'减少了')+get.cnNumber(Math.abs(num))+'点“达命”值'); - }, - content:function(){ - lib.skill.spdaming.change(player,1); - }, - intro:{ - name:'达命值', - markcount:function(storage,player){ - return (storage||0).toString(); - }, - content:'当前有#点“达命”值', - }, - subSkill:{ - used:{charlotte:true}, - give:{ - audio:2, - enable:'phaseUse', - nopop:true, - filter:function(event,player){ - if(!player.countCards('he')) return false; - return game.hasPlayer(current=>{ - return current!=player&¤t.hasSkill('spdaming')&&!current.hasSkill('spdaming_used'); - }); - }, - selectCard:1, - filterCard:true, - filterTarget:function(card,player,target){ - return target.hasSkill('spdaming')&&!target.hasSkill('spdaming_used'); - }, - selectTarget:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(current=>{ - return current!=player&¤t.hasSkill('spdaming')&&!current.hasSkill('spdaming_used'); - }); - return targets.length>1?1:-1; - }, - complexSelect:true, - prompt:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('spdaming')&&!current.hasSkill('spdaming_used'); - }); - return '将一张牌交给'+get.translation(targets)+(targets.length>1?'中的一人':''); - }, - position:'he', - discard:false, - lose:false, - delay:false, - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(current=>{ - return lib.skill.spdaming_give.filterTarget(null,player,current)&&get.attitude(player,current)>0; - })){ - return 6+Math.random()-get.value(card)/15; - } - return 0; - }, - content:function(){ - 'step 0' - game.trySkillAudio('spdaming',target); - player.give(cards,target); - if(!game.hasPlayer(current=>current!=player&¤t!=target)) event.finish(); - target.addTempSkill('spdaming_used','phaseUseAfter'); - 'step 1' - var type=get.type(cards[0],'trick',target); - event.cardtype=type; - var str=get.translation(type),user=get.translation(player); - target.chooseTarget('达命:选择另一名其他角色','若该角色有'+str+'牌,其将一张该类型的牌交给'+user+',你获得1点“达命”值;否则你将'+get.translation(cards)+'交给'+user,(card,player,target)=>{ - return target!=player&&target!=_status.event.getParent().player; - }).set('ai',target=>1-get.attitude(_status.event.player,target)); - 'step 2' - if(result.bool){ - var targetx=result.targets[0],type=event.cardtype; - target.line(targetx); - event.targetx=targetx; - if(targetx.countCards('he',{type:type})>0){ - targetx.chooseCard('交给'+get.translation(player)+'一张'+get.translation(type)+'牌','he',true,card=>{ - return get.type(card)==_status.event.getParent().cardtype; - }).set('ai',card=>10-get.value(card)); - } - else { - var cards=cards.filter(i=>get.owner(i)==target); - if(cards.length) target.give(cards,player); - event.finish(); - } - } else event.finish(); - 'step 3' - if(result.bool){ - event.targetx.give(result.cards,player); - event.targetx.line(player); - lib.skill.spdaming.change(target,1); - game.delayx(); - } - }, - ai:{ - expose:0.2, - order:10, - result:{target:1}, - }, - } - }, - }, - spxiaoni:{ - audio:2, - enable:'phaseUse', - usable:1, - locked:false, - filter:function(event,player){ - return (player.storage.spdaming||0)>0; - }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(name=='sha'){ - list.push(['基本','','sha']); - for(var i of lib.inpile_nature) list.push(['基本','','sha',i]); - } - if(!get.tag({name:name},'damage')) continue; - if(get.type2(name)=='trick') list.push(['锦囊','',name]); - } - return ui.create.dialog('嚣逆',[list,'vcard']); - }, - filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); - }, - check:function(button){ - var player=_status.event.player; - if(player.countCards('hs',button.link[2])>0) return 0; - var effect=player.getUseValue(button.link[2]); - if(effect>0) return effect; - return 0; - }, - backup:function(links,player){ - return { - filterCard:true, - audio:'spxiaoni', - selectCard:1, - popname:true, - check:function(card){ - return 6-get.value(card); - }, - position:'hes', - viewAs:{name:links[0][2],nature:links[0][3]}, - onuse:function(result,player){ - lib.skill.spdaming.change(player,-result.targets.length); - }, - } - }, - prompt:function(links,player){ - return '将一张牌当'+(get.translation(links[0][3])||'')+'【'+get.translation(links[0][2])+'】使用'; - } - }, - mod:{ - maxHandcardBase:function(player,num){ - return Math.min(Math.max(0,player.storage.spdaming||0),player.hp); - } - }, - ai:{ - order:4, - result:{ - player:1 - }, - threaten:1.4, - }, - subSkill:{ - backup:{}, - } - }, - // 灭霸 - zhujian:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('e')>0; - }, - selectTarget:[2,Infinity], - multiline:true, - multitarget:true, - filter:function(event,player){ - return game.countPlayer(current=>current.countCards('e')>0)>=2; - }, - content:function(){ - game.asyncDraw(targets); - }, - ai:{ - order:8, - result:{target:1}, - } - }, - duansuo:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.isLinked(); - }, - selectTarget:[1,Infinity], - multiline:true, - multitarget:true, - filter:function(event,player){ - return game.countPlayer(current=>current.isLinked()); - }, - content:function(){ - 'step 0' - event.targets=targets.sortBySeat(); - for(var i of event.targets){ - i.link(false); - } - 'step 1' - for(var i of targets){ - i.damage('fire'); - } - }, - ai:{ - order:2, - result:{target:-1}, - } - }, - // 界朱治 - sbanguo:{ - audio:3, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - locked:false, - direct:true, - group:['sbanguo_move','sbanguo_damage','sbanguo_dying'], - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); - }, - content:function(){ - 'step 0' - player.chooseTarget('安国:令一名其他角色获得“安国”标记',lib.filter.notMe,true); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbanguo',target); - target.addMark('sbanguo_mark',1,false); - target.addAdditionalSkill('sbanguo_'+player.playerid,'sbanguo_mark'); - target.addMark('sbanguo_marked',1,false); - } - }, - subSkill:{ - mark:{ - onremove:true, - marktext:'安', - charlotte:true, - intro:{ - name:'安国', - name2:'安国', - content:'已拥有“安国”标记', - }, - mod:{ - maxHandcardBase:function(player,num){ - return player.maxHp; - } - } - }, - move:{ - audio:'sbanguo', - direct:true, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return game.hasPlayer(current=>current.hasSkill('sbanguo_mark'))&&game.hasPlayer(current=>!current.hasMark('sbanguo_marked')&¤t!=player); - }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>current.hasSkill('sbanguo_mark')); - var prompt2=targets.length==1?('将'+get.translation(targets[0])+'的“安国”交给一名未获得过“安国”的其他角色'):('选择一名有“安国”的角色,将该标记交给一名未获得过“安国”的其他角色'); - player.chooseTarget(get.prompt('sbanguo'),prompt2,targets.length==1?1:2,(card,player,target)=>{ - if(ui.selected.targets.length==0&&_status.event.targets.length>1) return target.hasSkill('sbanguo_mark'); - return !target.hasMark('sbanguo_marked')&&target!=player; - }).set('ai',target=>{ - var player=_status.event.player; - if(ui.selected.targets.length==0&&_status.event.targets.length>1) return -get.attitude(player,target); - return get.attitude(player,_status.event.targets[0])current.hasSkill('sbanguo_mark'))[0]; - var target2=targets[0]; - }else{ - var target1=targets[0]; - var target2=targets[1]; - } - player.logSkill('sbanguo_move',target2,false); - player.line2([target1,target2],'green'); - var map=target1.additionalSkills; - for(var key in map){ - if(key.indexOf('sbanguo_')!=0) continue; - var id=parseInt(key.slice(8)); - target1.removeAdditionalSkill('sbanguo_'+id); - target2.addMark('sbanguo_mark',1,false); - target2.addAdditionalSkill('sbanguo_'+id,'sbanguo_mark'); - target2.addMark('sbanguo_marked',1,false); - } - } - } - }, - damage:{ - audio:'sbanguo', - forced:true, - locked:false, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - if(!game.hasPlayer(current=>current.hasSkill('sbanguo_mark'))) return false; - if(event.source&&event.source.isIn()&&event.source.hasSkill('sbanguo_mark')) return false; - return event.num>=player.hp; - }, - content:function(){ - trigger.cancel(); - }, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(!game.hasPlayer(current=>current.hasSkill('sbanguo_mark'))) return; - if(player.hasSkill('sbanguo_mark')) return; - if(get.tag(card,'damage')){ - if(target.hp<=1) return [0,0]; - return 0.5; - } - } - }, - }, - }, - dying:{ - audio:'sbanguo', - forced:true, - locked:false, - trigger:{global:'dying'}, - filter:function(event,player){ - var skills=event.player.additionalSkills['sbanguo_'+player.playerid]; - return skills&&skills.length; - }, - logTarget:'player', - content:function(){ - 'step 0' - trigger.player.removeAdditionalSkill('sbanguo_'+player.playerid); - var num=1-trigger.player.hp; - if(num>0) trigger.player.recover(num); - 'step 1' - var hp=player.hp-1,maxhp=player.maxHp-1; - if(hp>0&&maxhp>0){ - player.chooseControl().set('prompt','安国:请选择一项').set('choiceList',[ - '失去'+hp+'点体力,令'+get.translation(trigger.player)+'获得1点护甲', - '减'+maxhp+'点体力上限,令'+get.translation(trigger.player)+'获得1点护甲' - ]).set('ai',()=>'选项一'); - } - else if(hp>0) event._result={control:'选项一'}; - else if(maxhp>0) event._result={control:'选项二'}; - else event.finish(); - 'step 2' - if(result.control=='选项一'){ - var num=player.hp-1; - if(num>0) player.loseHp(num); - } - else{ - var num=player.maxHp-1; - if(num>0) player.loseMaxHp(num); - } - trigger.player.changeHujia(1,null,true); - } - } - } - }, - // 界吴懿 - sbbenxi:{ - audio:3, - trigger:{ - player:'phaseUseBegin', - }, - filter:function(event,player){ - return player.countDiscardableCards(player,'he')>0; - }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('sbbenxi'),[1,Infinity],'he').set('logSkill','sbbenxi').set('ai',card=>{ - var player=_status.event.player; - if(ui.selected.cards.length<_status.event.num) return 100-(get.useful(card,player)+player.getUseValue(card)/3); - return 0; - }).set('num',(function(){ - var count=0; - var list=[],list2=[]; - var targets=game.filterPlayer(current=>get.distance(player,current)>=1); - var cards=player.getCards('hs',card=>{ - return player.hasUseTarget(card,false)&&['basic','trick'].includes(get.type(card,false,player))&&get.info(card).allowMultiple!=false; - }); - var cards2=player.getCards('he').filter(i=>lib.filter.cardDiscardable(i,player,'sbbenxi')).sort((a,b)=>{ - return (get.useful(a,player)+player.getUseValue(a)/3)-(get.useful(b,player)+player.getUseValue(b)/3); - }); - for(var i=0; i0) count+=get.effect(player,{name:'draw'},player); - var targets2=targets.filter(current=>{ - return player.canUse(card,current,false)&&get.distance(player,current)<=num&&get.effect(current,card,player,player)>0; - }); - targets2=targets2.map(target=>get.effect(target,card,player,player)).sort((a,b)=>b-a); - targets2.slice(0,num).forEach(eff=>count+=eff); - list.push(count-1.2*get.value(cards2[i])); - } - var val=list.sort((a,b)=>b-a)[0]; - if(!isNaN(val)) list2.push([val,i]); - } - list2=list2.filter(i=>i[0]>0); - if(!list2.length) return 0; - return list2.sort((a,b)=>b[0]-a[0])[0][1]; - })()); - 'step 1' - if(result.bool){ - var num=result.cards.length; - player.addTempSkill('sbbenxi_effect','phaseUseAfter'); - player.addTempSkill('sbbenxi_effect2','phaseUseAfter'); - player.addMark('sbbenxi_effect2',num,false); - } - }, - subSkill:{ - effect:{ - audio:'sbbenxi', - trigger:{player:'useCard2'}, - forced:true, - charlotte:true, - direct:true, - onremove:true, - filter:function(event,player){ - var type=get.type(event.card,false); - return type=='basic'||type=='trick'; - }, - content:function(){ - 'step 0' - var num=player.countMark('sbbenxi_effect2'); - player.removeSkill('sbbenxi_effect'); - player.addTempSkill('sbbenxi_effect3','phaseUseAfter'); - player.markAuto('sbbenxi_effect3',[trigger.card]); - var filter=function(event,player){ - var card=event.card,info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&get.distance(player,current)==1; - })){ - return true; - } - } - return false; - } - if(!filter(trigger,player)) event.finish(); - else{ - var prompt='为'+get.translation(trigger.card)+'增加至多'+get.cnNumber(num)+'个距离为1的目标?'; - trigger.player.chooseTarget(get.prompt('sbbenxi_effect'),prompt,[1,num],function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target)&&get.distance(player,target)==1; - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - } - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - player.logSkill('sbbenxi_effect',result.targets); - game.log(result.targets,'也成为了',trigger.card,'的目标'); - trigger.targets.addArray(result.targets); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.canUse(card,target)&&get.distance(player,target)!=1) return 1.2; }, }, }, }, - effect2:{ - audio:'sbbenxi', - trigger:{ - global:'useCardAfter', + }, + }, + mbzhenfu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.hasHistory("lose", (evt) => { + return evt.type == "discard"; + }); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("mbzhenfu"), + "令一名其他角色获得1点护甲", + (card, player, target) => { + return target != player && target.hujia < 5; + } + ) + .set("ai", (target) => { + return ( + Math.max(0, get.threaten(target)) * get.attitude(_status.event.player, target) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mbzhenfu", target); + target.changeHujia(1, null, true); + } + }, + ai: { + expose: 0.2, + }, + }, + //☆胃炎 + mbguli: { + audio: 2, + enable: "phaseUse", + filterCard: true, + selectCard: -1, + position: "h", + filter: function (event, player) { + if (player.hasSkill("mbguli_used")) return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var card of hs) { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 === false) return false; + } + return event.filterCard(get.autoViewAs({ name: "sha" }, hs)); + }, + viewAs: { + name: "sha", + storage: { mbguli: true }, + }, + onuse: function (links, player) { + player.addTempSkill("mbguli_used", "phaseUseAfter"); + }, + ai: { + order: 1, + threaten: 1.14, + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + arg && + arg.name == "sha" && + arg.card && + arg.card.storage && + arg.card.storage.mbguli + ) + return true; + return false; + }, + }, + subSkill: { + used: { + audio: "mbguli", + trigger: { global: "useCardAfter" }, + charlotte: true, + prompt2: "失去1点体力,然后将手牌摸至体力上限", + check: function (event, player) { + var num = player.maxHp - player.countCards("h"); + return (num >= 3 && player.hp >= 2) || (num >= 2 && player.hp >= 3); }, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.getStorage('sbbenxi_effect3').includes(event.card)&&game.hasPlayer2(current=>{ - return current.hasHistory('damage',evt=>{ - return event.card==evt.card; - }); + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.mbguli && + game.hasPlayer2((current) => { + return current.hasHistory( + "sourceDamage", + (evt) => evt.card == event.card + ); + }) + ); + }, + content: function () { + "step 0"; + player.loseHp(); + "step 1"; + player.drawTo(player.maxHp); + }, + group: "mbguli_unequip", + }, + unequip: { + trigger: { + player: "useCardToPlayered", + }, + filter: function ({ card }) { + return card.name == "sha" && card.storage && card.storage.mbguli; + }, + forced: true, + popup: false, + logTarget: "target", + content: function () { + trigger.target.addTempSkill("qinggang2"); + trigger.target.storage.qinggang2.add(trigger.card); + trigger.target.markSkill("qinggang2"); + }, + }, + }, + }, + mbaosi: { + audio: 2, + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + return ( + player.inRange(event.player) && + player.isPhaseUsing() && + event.player.isIn() && + !player.getStorage("mbaosi_inf").includes(event.player) + ); + }, + logTarget: "player", + content: function () { + player.addTempSkill("mbaosi_inf", "phaseUseAfter"); + player.markAuto("mbaosi_inf", [trigger.player]); + }, + subSkill: { + inf: { + charlotte: true, + onremove: true, + forced: true, + intro: { content: "对$使用牌无次数限制" }, + mod: { + cardUsableTarget: function (card, player, target) { + if (player.getStorage("mbaosi_inf").includes(target)) return true; + }, + }, + }, + }, + }, + // 界曹休 + xinqingxi: { + audio: 2, + usable: 1, + trigger: { source: "damageBegin1" }, + check: function (event, player) { + return get.attitude(player, event.player) < 0; + }, + filter: function (event, player) { + return event.player != player; + }, + content: function () { + "step 0"; + var num = Math.max(1, 4 - get.distance(player, trigger.player)); + if (trigger.player.countCards("h") < num) { + event._result = { bool: false }; + } else { + trigger.player + .chooseToDiscard( + num, + "弃置" + + get.cnNumber(num) + + "张手牌,或令" + + get.translation(player) + + "对你造成的此伤害+1" + ) + .set("ai", function (card) { + var player = _status.event.player; + if (player.hp == 1) { + if (get.type(card) == "basic") { + return 8 - get.value(card); + } else { + return 10 - get.value(card); + } + } else { + if (num > 2) { + return 0; + } + return 8 - get.value(card); + } + }); + } + "step 1"; + if (!result.bool) { + trigger.num++; + } + }, + }, + // 界朱桓 + xinpingkou: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.getHistory("skipped").length > 0; + }, + content: function () { + "step 0"; + player + .chooseTarget( + [1, player.getHistory("skipped").length], + get.prompt2("xinpingkou"), + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("xinpingkou", result.targets); + event.targets = result.targets.slice(0).sortBySeat(); + } else { + event.finish(); + } + "step 2"; + if (event.targets && event.targets.length) { + event.targets.shift().damage(); + event.redo(); + } + "step 3"; + var card = get.cardPile2((card) => get.type(card, false) == "equip"); + if (card) player.gain(card, "gain2"); + }, + ai: { + combo: "fenli", + effect: { + target: function (card) { + if (card.name == "lebu" || card.name == "bingliang") return 0.5; + }, + }, + }, + }, + // 彭羕 + spdaming: { + audio: 3, + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + locked: false, + global: "spdaming_give", + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; + }, + change: function (player, num) { + if (!player.storage.spdaming) player.storage.spdaming = 0; + if (!num) return; + player.storage.spdaming += num; + player.markSkill("spdaming"); + game.log( + player, + (num > 0 ? "获得了" : "减少了") + get.cnNumber(Math.abs(num)) + "点“达命”值" + ); + }, + content: function () { + lib.skill.spdaming.change(player, 1); + }, + intro: { + name: "达命值", + markcount: function (storage, player) { + return (storage || 0).toString(); + }, + content: "当前有#点“达命”值", + }, + subSkill: { + used: { charlotte: true }, + give: { + audio: 2, + enable: "phaseUse", + nopop: true, + filter: function (event, player) { + if (!player.countCards("he")) return false; + return game.hasPlayer((current) => { + return ( + current != player && + current.hasSkill("spdaming") && + !current.hasSkill("spdaming_used") + ); }); }, - content:function(){ - player.draw(5); + selectCard: 1, + filterCard: true, + filterTarget: function (card, player, target) { + return target.hasSkill("spdaming") && !target.hasSkill("spdaming_used"); }, - mod:{ - aiOrder:function(player,card,num){ - var evt=_status.event.getParent('phaseUse'); - if(!evt||evt.player!=player) return; - if(player.hasHistory('useCard',evtx=>{ - return evtx.getParent('phaseUse')==evt&&['basic','trick'].includes(get.type(evtx.card)); - })) return; - if(get.tag(card,'damage')||get.type(card)=='equip') return num+10; - }, - globalFrom:function(from,to,distance){ - return distance-from.countMark('sbbenxi_effect2'); + selectTarget: function () { + var player = _status.event.player; + var targets = game.filterPlayer((current) => { + return ( + current != player && + current.hasSkill("spdaming") && + !current.hasSkill("spdaming_used") + ); + }); + return targets.length > 1 ? 1 : -1; + }, + complexSelect: true, + prompt: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return ( + current != player && + current.hasSkill("spdaming") && + !current.hasSkill("spdaming_used") + ); + }); + return ( + "将一张牌交给" + + get.translation(targets) + + (targets.length > 1 ? "中的一人" : "") + ); + }, + position: "he", + discard: false, + lose: false, + delay: false, + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer((current) => { + return ( + lib.skill.spdaming_give.filterTarget(null, player, current) && + get.attitude(player, current) > 0 + ); + }) + ) { + return 6 + Math.random() - get.value(card) / 15; + } + return 0; + }, + content: function () { + "step 0"; + game.trySkillAudio("spdaming", target); + player.give(cards, target); + if (!game.hasPlayer((current) => current != player && current != target)) + event.finish(); + target.addTempSkill("spdaming_used", "phaseUseAfter"); + "step 1"; + var type = get.type(cards[0], "trick", target); + event.cardtype = type; + var str = get.translation(type), + user = get.translation(player); + target + .chooseTarget( + "达命:选择另一名其他角色", + "若该角色有" + + str + + "牌,其将一张该类型的牌交给" + + user + + ",你获得1点“达命”值;否则你将" + + get.translation(cards) + + "交给" + + user, + (card, player, target) => { + return target != player && target != _status.event.getParent().player; + } + ) + .set("ai", (target) => 1 - get.attitude(_status.event.player, target)); + "step 2"; + if (result.bool) { + var targetx = result.targets[0], + type = event.cardtype; + target.line(targetx); + event.targetx = targetx; + if (targetx.countCards("he", { type: type }) > 0) { + targetx + .chooseCard( + "交给" + + get.translation(player) + + "一张" + + get.translation(type) + + "牌", + "he", + true, + (card) => { + return get.type(card) == _status.event.getParent().cardtype; + } + ) + .set("ai", (card) => 10 - get.value(card)); + } else { + var cards = cards.filter((i) => get.owner(i) == target); + if (cards.length) target.give(cards, player); + event.finish(); + } + } else event.finish(); + "step 3"; + if (result.bool) { + event.targetx.give(result.cards, player); + event.targetx.line(player); + lib.skill.spdaming.change(target, 1); + game.delayx(); } }, - marktext:'奔', - intro:{ - content:function(storage,player){ - var str='于此阶段至其他角色的距离-'+storage; - if(player.hasSkill('sbbenxi_effect')) str+=';使用下一张基本牌或普通锦囊牌选择目标后,可以增加'+get.cnNumber(storage)+'个目标'; - return str; + ai: { + expose: 0.2, + order: 10, + result: { target: 1 }, + }, + }, + }, + }, + spxiaoni: { + audio: 2, + enable: "phaseUse", + usable: 1, + locked: false, + filter: function (event, player) { + return (player.storage.spdaming || 0) > 0; + }, + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (name == "sha") { + list.push(["基本", "", "sha"]); + for (var i of lib.inpile_nature) list.push(["基本", "", "sha", i]); + } + if (!get.tag({ name: name }, "damage")) continue; + if (get.type2(name) == "trick") list.push(["锦囊", "", name]); + } + return ui.create.dialog("嚣逆", [list, "vcard"]); + }, + filter: function (button, player) { + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); + }, + check: function (button) { + var player = _status.event.player; + if (player.countCards("hs", button.link[2]) > 0) return 0; + var effect = player.getUseValue(button.link[2]); + if (effect > 0) return effect; + return 0; + }, + backup: function (links, player) { + return { + filterCard: true, + audio: "spxiaoni", + selectCard: 1, + popname: true, + check: function (card) { + return 6 - get.value(card); + }, + position: "hes", + viewAs: { name: links[0][2], nature: links[0][3] }, + onuse: function (result, player) { + lib.skill.spdaming.change(player, -result.targets.length); + }, + }; + }, + prompt: function (links, player) { + return ( + "将一张牌当" + + (get.translation(links[0][3]) || "") + + "【" + + get.translation(links[0][2]) + + "】使用" + ); + }, + }, + mod: { + maxHandcardBase: function (player, num) { + return Math.min(Math.max(0, player.storage.spdaming || 0), player.hp); + }, + }, + ai: { + order: 4, + result: { + player: 1, + }, + threaten: 1.4, + combo: "spdaming", + }, + subSkill: { + backup: {}, + }, + }, + // 灭霸 + zhujian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("e") > 0; + }, + selectTarget: [2, Infinity], + multiline: true, + multitarget: true, + filter: function (event, player) { + return game.countPlayer((current) => current.countCards("e") > 0) >= 2; + }, + content: function () { + game.asyncDraw(targets); + }, + ai: { + order: 8, + result: { target: 1 }, + }, + }, + duansuo: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.isLinked(); + }, + selectTarget: [1, Infinity], + multiline: true, + multitarget: true, + filter: function (event, player) { + return game.countPlayer((current) => current.isLinked()); + }, + content: function () { + "step 0"; + event.targets = targets.sortBySeat(); + for (var i of event.targets) { + i.link(false); + } + "step 1"; + for (var i of targets) { + i.damage("fire"); + } + }, + ai: { + order: 2, + result: { target: -1 }, + }, + }, + // 界朱治 + sbanguo: { + audio: 3, + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + locked: false, + direct: true, + group: ["sbanguo_move", "sbanguo_damage", "sbanguo_dying"], + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); + }, + content: function () { + "step 0"; + player.chooseTarget("安国:令一名其他角色获得“安国”标记", lib.filter.notMe, true); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbanguo", target); + target.addMark("sbanguo_mark", 1, false); + target.addAdditionalSkill("sbanguo_" + player.playerid, "sbanguo_mark"); + target.addMark("sbanguo_marked", 1, false); + } + }, + subSkill: { + mark: { + onremove: true, + marktext: "安", + charlotte: true, + intro: { + name: "安国", + name2: "安国", + content: "已拥有“安国”标记", + }, + mod: { + maxHandcardBase: function (player, num) { + return player.maxHp; + }, + }, + }, + move: { + audio: "sbanguo", + direct: true, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current.hasSkill("sbanguo_mark")) && + game.hasPlayer( + (current) => !current.hasMark("sbanguo_marked") && current != player + ) + ); + }, + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => current.hasSkill("sbanguo_mark")); + var prompt2 = + targets.length == 1 + ? "将" + + get.translation(targets[0]) + + "的“安国”交给一名未获得过“安国”的其他角色" + : "选择一名有“安国”的角色,将该标记交给一名未获得过“安国”的其他角色"; + player + .chooseTarget( + get.prompt("sbanguo"), + prompt2, + targets.length == 1 ? 1 : 2, + (card, player, target) => { + if ( + ui.selected.targets.length == 0 && + _status.event.targets.length > 1 + ) + return target.hasSkill("sbanguo_mark"); + return !target.hasMark("sbanguo_marked") && target != player; + } + ) + .set("ai", (target) => { + var player = _status.event.player; + if (ui.selected.targets.length == 0 && _status.event.targets.length > 1) + return -get.attitude(player, target); + return ( + get.attitude(player, _status.event.targets[0]) < + get.attitude(player, target) + ); + }) + .set("targets", targets); + "step 1"; + if (result.bool) { + var targets = result.targets; + if (targets.length == 1) { + var target1 = game.filterPlayer((current) => + current.hasSkill("sbanguo_mark") + )[0]; + var target2 = targets[0]; + } else { + var target1 = targets[0]; + var target2 = targets[1]; + } + player.logSkill("sbanguo_move", target2, false); + player.line2([target1, target2], "green"); + var map = target1.additionalSkills; + for (var key in map) { + if (key.indexOf("sbanguo_") != 0) continue; + var id = parseInt(key.slice(8)); + target1.removeAdditionalSkill("sbanguo_" + id); + target2.addMark("sbanguo_mark", 1, false); + target2.addAdditionalSkill("sbanguo_" + id, "sbanguo_mark"); + target2.addMark("sbanguo_marked", 1, false); + } } }, }, - effect3:{ - forced:true, - charlotte:true, - popup:false, - onremove:true, + damage: { + audio: "sbanguo", + forced: true, + locked: false, + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + if (!game.hasPlayer((current) => current.hasSkill("sbanguo_mark"))) return false; + if (event.source && event.source.isIn() && event.source.hasSkill("sbanguo_mark")) + return false; + return event.num >= player.hp; + }, + content: function () { + trigger.cancel(); + }, + ai: { + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (!game.hasPlayer((current) => current.hasSkill("sbanguo_mark"))) + return; + if (player.hasSkill("sbanguo_mark")) return; + if (get.tag(card, "damage")) { + if (target.hp <= 1) return [0, 0]; + return 0.5; + } + }, + }, + }, + }, + dying: { + audio: "sbanguo", + forced: true, + locked: false, + trigger: { global: "dying" }, + filter: function (event, player) { + var skills = event.player.additionalSkills["sbanguo_" + player.playerid]; + return skills && skills.length; + }, + logTarget: "player", + content: function () { + "step 0"; + trigger.player.removeAdditionalSkill("sbanguo_" + player.playerid); + var num = 1 - trigger.player.hp; + if (num > 0) trigger.player.recover(num); + "step 1"; + var hp = player.hp - 1, + maxhp = player.maxHp - 1; + if (hp > 0 && maxhp > 0) { + player + .chooseControl() + .set("prompt", "安国:请选择一项") + .set("choiceList", [ + "失去" + + hp + + "点体力,令" + + get.translation(trigger.player) + + "获得1点护甲", + "减" + + maxhp + + "点体力上限,令" + + get.translation(trigger.player) + + "获得1点护甲", + ]) + .set("ai", () => "选项一"); + } else if (hp > 0) event._result = { control: "选项一" }; + else if (maxhp > 0) event._result = { control: "选项二" }; + else event.finish(); + "step 2"; + if (result.control == "选项一") { + var num = player.hp - 1; + if (num > 0) player.loseHp(num); + } else { + var num = player.maxHp - 1; + if (num > 0) player.loseMaxHp(num); + } + trigger.player.changeHujia(1, null, true); + }, + }, + }, + }, + // 界吴懿 + sbbenxi: { + audio: 3, + trigger: { + player: "phaseUseBegin", + }, + filter: function (event, player) { + return player.countDiscardableCards(player, "he") > 0; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("sbbenxi"), [1, Infinity], "he") + .set("logSkill", "sbbenxi") + .set("ai", (card) => { + var player = _status.event.player; + if (ui.selected.cards.length < _status.event.num) + return 100 - (get.useful(card, player) + player.getUseValue(card) / 3); + return 0; + }) + .set( + "num", + (function () { + var count = 0; + var list = [], + list2 = []; + var targets = game.filterPlayer( + (current) => get.distance(player, current) >= 1 + ); + var cards = player.getCards("hs", (card) => { + return ( + player.hasUseTarget(card, false) && + ["basic", "trick"].includes(get.type(card, false, player)) && + get.info(card).allowMultiple != false + ); + }); + var cards2 = player + .getCards("he") + .filter((i) => lib.filter.cardDiscardable(i, player, "sbbenxi")) + .sort((a, b) => { + return ( + get.useful(a, player) + + player.getUseValue(a) / 3 - + (get.useful(b, player) + player.getUseValue(b) / 3) + ); + }); + for (var i = 0; i < cards2.length; i++) { + count = 0; + list = []; + for (var card of cards) { + var num = i + 1; + if (cards2.slice(0, num).includes(card)) continue; + if (get.tag(card, "damage") && i > 0) + count += get.effect(player, { name: "draw" }, player); + var targets2 = targets.filter((current) => { + return ( + player.canUse(card, current, false) && + get.distance(player, current) <= num && + get.effect(current, card, player, player) > 0 + ); + }); + targets2 = targets2 + .map((target) => get.effect(target, card, player, player)) + .sort((a, b) => b - a); + targets2.slice(0, num).forEach((eff) => (count += eff)); + list.push(count - 1.2 * get.value(cards2[i])); + } + var val = list.sort((a, b) => b - a)[0]; + if (!isNaN(val)) list2.push([val, i]); + } + list2 = list2.filter((i) => i[0] > 0); + if (!list2.length) return 0; + return list2.sort((a, b) => b[0] - a[0])[0][1]; + })() + ); + "step 1"; + if (result.bool) { + var num = result.cards.length; + player.addTempSkill("sbbenxi_effect", "phaseUseAfter"); + player.addTempSkill("sbbenxi_effect2", "phaseUseAfter"); + player.addMark("sbbenxi_effect2", num, false); } }, + subSkill: { + effect: { + audio: "sbbenxi", + trigger: { player: "useCard2" }, + forced: true, + charlotte: true, + direct: true, + onremove: true, + filter: function (event, player) { + var type = get.type(event.card, false); + return type == "basic" || type == "trick"; + }, + content: function () { + "step 0"; + var num = player.countMark("sbbenxi_effect2"); + player.removeSkill("sbbenxi_effect"); + player.addTempSkill("sbbenxi_effect3", "phaseUseAfter"); + player.markAuto("sbbenxi_effect3", [trigger.card]); + var filter = function (event, player) { + var card = event.card, + info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + get.distance(player, current) == 1 + ); + }) + ) { + return true; + } + } + return false; + }; + if (!filter(trigger, player)) event.finish(); + else { + var prompt = + "为" + + get.translation(trigger.card) + + "增加至多" + + get.cnNumber(num) + + "个距离为1的目标?"; + trigger.player + .chooseTarget( + get.prompt("sbbenxi_effect"), + prompt, + [1, num], + function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2( + _status.event.card, + player, + target + ) && + get.distance(player, target) == 1 + ); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + } + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + player.logSkill("sbbenxi_effect", result.targets); + game.log(result.targets, "也成为了", trigger.card, "的目标"); + trigger.targets.addArray(result.targets); + }, + ai: { + effect: { + target: function (card, player, target) { + if (player.canUse(card, target) && get.distance(player, target) != 1) + return 1.2; + }, + }, + }, + }, + effect2: { + audio: "sbbenxi", + trigger: { + global: "useCardAfter", + }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + player.getStorage("sbbenxi_effect3").includes(event.card) && + game.hasPlayer2((current) => { + return current.hasHistory("damage", (evt) => { + return event.card == evt.card; + }); + }) + ); + }, + content: function () { + player.draw(5); + }, + mod: { + aiOrder: function (player, card, num) { + var evt = _status.event.getParent("phaseUse"); + if (!evt || evt.player != player) return; + if ( + player.hasHistory("useCard", (evtx) => { + return ( + evtx.getParent("phaseUse") == evt && + ["basic", "trick"].includes(get.type(evtx.card)) + ); + }) + ) + return; + if (get.tag(card, "damage") || get.type(card) == "equip") return num + 10; + }, + globalFrom: function (from, to, distance) { + return distance - from.countMark("sbbenxi_effect2"); + }, + }, + marktext: "奔", + intro: { + content: function (storage, player) { + var str = "于此阶段至其他角色的距离-" + storage; + if (player.hasSkill("sbbenxi_effect")) + str += + ";使用下一张基本牌或普通锦囊牌选择目标后,可以增加" + + get.cnNumber(storage) + + "个目标"; + return str; + }, + }, + }, + effect3: { + forced: true, + charlotte: true, + popup: false, + onremove: true, + }, + }, }, // 杨阜 - jiebing:{ - audio:2, - trigger:{ - player:'damageEnd', + jiebing: { + audio: 2, + trigger: { + player: "damageEnd", }, - direct:true, - forced:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current!=event.source&¤t!=player&¤t.countGainableCards(player,'he'); + direct: true, + forced: true, + filter: function (event, player) { + return game.hasPlayer((current) => { + return ( + current != event.source && + current != player && + current.countGainableCards(player, "he") + ); }); }, - content:function(){ - 'step 0' - player.chooseTarget('借兵:选择一名其他角色',get.skillInfoTranslation('jiebing'),true,(card,player,target)=>{ - return player!=target&&target!=_status.event.getTrigger().source&&target.countGainableCards(player,'he'); - }).set('ai',target=>get.effect(target,{name:'shunshou_copy2'},player,player) /** (target.countCards('he')>1?1.5:1)*/); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jiebing',target); - if(target.ai.shown>0) player.addExpose(0.15); - var cards=target.getGainableCards(player,'he').randomGets(1); - event.cards=cards; - player.gain(target,cards,'give','bySelf'); - player.showCards(cards,'借兵'); + content: function () { + "step 0"; + player + .chooseTarget( + "借兵:选择一名其他角色", + get.skillInfoTranslation("jiebing"), + true, + (card, player, target) => { + return ( + player != target && + target != _status.event.getTrigger().source && + target.countGainableCards(player, "he") + ); + } + ) + .set( + "ai", + (target) => + get.effect( + target, + { name: "shunshou_copy2" }, + player, + player + ) /** (target.countCards('he')>1?1.5:1)*/ + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jiebing", target); + if (target.ai.shown > 0) player.addExpose(0.15); + var cards = target.getGainableCards(player, "he").randomGets(1); + event.cards = cards; + player.gain(target, cards, "give", "bySelf"); + player.showCards(cards, "借兵"); } else event.finish(); - 'step 2' - for(var card of cards){ - if(get.type(card)=='equip'&&player.hasUseTarget(card)&&get.owner(card)==player){ - player.chooseUseTarget(card,true); + "step 2"; + for (var card of cards) { + if ( + get.type(card) == "equip" && + player.hasUseTarget(card) && + get.owner(card) == player + ) { + player.chooseUseTarget(card, true); } } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(player!=target&&!player.getFriends().length) return; - if(game.hasPlayer(current=>{ - return current!=player&&get.attitude(player,current)>0&¤t.countGainableCards(target,'he')>0; - })) return [1,1]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (player != target && !player.getFriends().length) return; + if ( + game.hasPlayer((current) => { + return ( + current != player && + get.attitude(player, current) > 0 && + current.countGainableCards(target, "he") > 0 + ); + }) + ) + return [1, 1]; } }, }, }, }, - hannan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkillTag('noCompareSource'); + hannan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return !player.hasSkillTag("noCompareSource"); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.canCompare(target); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(!result.tie){ - var players=[player,target]; - if(result.bool) players.reverse(); - players[1].line(players[0],'thunder'); - players[0].damage(players[1],2); + "step 1"; + if (!result.tie) { + var players = [player, target]; + if (result.bool) players.reverse(); + players[1].line(players[0], "thunder"); + players[0].damage(players[1], 2); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - var hs=player.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + ai: { + order: 7, + result: { + target: function (player, target) { + var hs = player.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - var ts=target.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + var ts = target.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - if(!hs.length||!ts.length) return 0; - if(get.number(hs[0])>get.number(ts[0])||get.number(hs[0])-ts.length>=(9+Math.min(2,player.hp/2))) return get.sgnAttitude(player,target)*get.damageEffect(target,player,player); + if (!hs.length || !ts.length) return 0; + if ( + get.number(hs[0]) > get.number(ts[0]) || + get.number(hs[0]) - ts.length >= 9 + Math.min(2, player.hp / 2) + ) + return ( + get.sgnAttitude(player, target) * get.damageEffect(target, player, player) + ); return 0; }, }, }, }, // 曹嵩 - yijin:{ - audio:3, - trigger:{player:'phaseUseBegin'}, - forced:true, - direct:true, - group:['yijin_upstart','yijin_die'], - filter:function(event,player){ - if(!game.hasPlayer(current=>current!=player && !lib.skill.yijin.getKane(current).length)) return false; + yijin: { + audio: 3, + trigger: { player: "phaseUseBegin" }, + forced: true, + direct: true, + group: ["yijin_upstart", "yijin_die"], + filter: function (event, player) { + if ( + !game.hasPlayer( + (current) => current != player && !lib.skill.yijin.getKane(current).length + ) + ) + return false; return lib.skill.yijin.getKane(player).length; }, - getKane:function(player){ - var list=lib.skill.yijin.derivation; - return list.filter(mark=>player.hasMark(mark)); + getKane: function (player) { + var list = lib.skill.yijin.derivation; + return list.filter((mark) => player.hasMark(mark)); }, - derivation:['yijin_wushi','yijin_jinmi','yijin_guxiong','yijin_tongshen','yijin_yongbi','yijin_houren'], - getValue:function(player,mark,target){ - let dis=Math.sqrt(get.distance(player,target,'absolute')); - if(target.isTurnedOver()) dis++; - let draw=get.effect(target,{name:'draw'},target,target); - switch(mark.slice(6)){ - case 'wushi': - if(target.hasJudge('bingliang')) return 12/(1+target.getCardUsable('sha',true)); - return 5*draw/dis+12/(1+target.getCardUsable('sha',true)); - case 'jinmi': - if(target.hasJudge('lebu')&&!target.hasCard({name:'wuxie'},'hs')) return draw*target.needsToDiscard(2.2)/dis; - return get.effect(target,{name:'lebu'},player,target)+draw*target.needsToDiscard(2.2)/dis; - case 'guxiong': - if(target.hasJudge('lebu')) return -draw*target.needsToDiscard(3)/dis; - return get.effect(target,{name:'losehp'},target,target)*2/dis-draw*target.needsToDiscard(3)/dis; - case 'tongshen': - if(target.isMin()) return 0; - var eff=-get.damageEffect(target,player,target); - if(eff<=0) return 0; - if(target.hp<2) return eff*dis*2; - if(target.hp<3&&target.countCards('he')<3) return eff*dis*1.5; - if(target.hp>3) return eff*dis/target.hp; - return eff*dis; - case 'yongbi': - if(target.hasJudge('bingliang')&&!target.hasCard({name:'wuxie'},'hs')) return 0; - return get.effect(target,{name:'bingliang'},player,target)*2/dis; - case 'houren': - return Math.min(5,2+target.getDamagedHp())*get.recoverEffect(target,player,target)/dis; + derivation: [ + "yijin_wushi", + "yijin_jinmi", + "yijin_guxiong", + "yijin_tongshen", + "yijin_yongbi", + "yijin_houren", + ], + getValue: function (player, mark, target) { + let dis = Math.sqrt(get.distance(player, target, "absolute")); + if (target.isTurnedOver()) dis++; + let draw = get.effect(target, { name: "draw" }, target, target); + switch (mark.slice(6)) { + case "wushi": + if (target.hasJudge("bingliang")) + return 12 / (1 + target.getCardUsable("sha", true)); + return (5 * draw) / dis + 12 / (1 + target.getCardUsable("sha", true)); + case "jinmi": + if (target.hasJudge("lebu") && !target.hasCard({ name: "wuxie" }, "hs")) + return (draw * target.needsToDiscard(2.2)) / dis; + return ( + get.effect(target, { name: "lebu" }, player, target) + + (draw * target.needsToDiscard(2.2)) / dis + ); + case "guxiong": + if (target.hasJudge("lebu")) return (-draw * target.needsToDiscard(3)) / dis; + return ( + (get.effect(target, { name: "losehp" }, target, target) * 2) / dis - + (draw * target.needsToDiscard(3)) / dis + ); + case "tongshen": + if (target.isMin()) return 0; + var eff = -get.damageEffect(target, player, target); + if (eff <= 0) return 0; + if (target.hp < 2) return eff * dis * 2; + if (target.hp < 3 && target.countCards("he") < 3) return eff * dis * 1.5; + if (target.hp > 3) return (eff * dis) / target.hp; + return eff * dis; + case "yongbi": + if (target.hasJudge("bingliang") && !target.hasCard({ name: "wuxie" }, "hs")) + return 0; + return (get.effect(target, { name: "bingliang" }, player, target) * 2) / dis; + case "houren": + return ( + (Math.min(5, 2 + target.getDamagedHp()) * + get.recoverEffect(target, player, target)) / + dis + ); } }, - content:function(){ - 'step 0' - player.chooseTarget('亿金:令一名其他角色获得1枚“金”',true,(card,player,target)=>{ - return player!=target&&!lib.skill.yijin.getKane(target).length; - }).set('ai',target=>{ - let player=_status.event.player,att=get.attitude(player,target),kane=lib.skill.yijin.getKane(player); - if(Math.abs(att)>1) att=Math.sign(att)*Math.sqrt(Math.abs(att)); - return Math.max.apply(Math.max,kane.map(i=>{ - return att*lib.skill.yijin.getValue(player,i,target); - })); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('yijin',target); - var kane=lib.skill.yijin.getKane(player); - var choiceList=kane.map(i=>{ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              ' + - '
              '+get.skillInfoTranslation(i,player)+'
              '; + content: function () { + "step 0"; + player + .chooseTarget("亿金:令一名其他角色获得1枚“金”", true, (card, player, target) => { + return player != target && !lib.skill.yijin.getKane(target).length; + }) + .set("ai", (target) => { + let player = _status.event.player, + att = get.attitude(player, target), + kane = lib.skill.yijin.getKane(player); + if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att)); + return Math.max.apply( + Math.max, + kane.map((i) => { + return att * lib.skill.yijin.getValue(player, i, target); + }) + ); }); - player.chooseControl(kane).set('choiceList',choiceList).set('displayIndex',false).set('prompt','选择令'+get.translation(target)+'获得的“金”').set('ai',()=>{ - let controls=_status.event.controls,player=_status.event.player,target=_status.event.getParent().target,att=get.attitude(player,target); - if(Math.abs(att)>1) att=Math.sign(att)*Math.sqrt(Math.abs(att)); - let list=controls.map(i=>{ - return [i,att*lib.skill.yijin.getValue(player,i,target)]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("yijin", target); + var kane = lib.skill.yijin.getKane(player); + var choiceList = kane.map((i) => { + return ( + '
              【' + + get.translation(lib.translate[i + "_ab"] || get.translation(i).slice(0, 2)) + + "】
              " + + "
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }); + player + .chooseControl(kane) + .set("choiceList", choiceList) + .set("displayIndex", false) + .set("prompt", "选择令" + get.translation(target) + "获得的“金”") + .set("ai", () => { + let controls = _status.event.controls, + player = _status.event.player, + target = _status.event.getParent().target, + att = get.attitude(player, target); + if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att)); + let list = controls.map((i) => { + return [i, att * lib.skill.yijin.getValue(player, i, target)]; + }); + list.sort((a, b) => b[1] - a[1]); + if (list.length) return list[0][0]; + return controls.randomGet(); }); - list.sort((a,b)=>b[1]-a[1]); - if(list.length) return list[0][0]; - return controls.randomGet(); - }); } else event.finish(); - 'step 2' - var kane=result.control; - player.removeMark(kane,1); - player.popup(kane,'metal'); - player.addSkill('yijin_clear'); - target.addMark(kane,1); - target.addAdditionalSkill('yijin_'+player.playerid,kane); + "step 2"; + var kane = result.control; + player.removeMark(kane, 1); + player.popup(kane, "metal"); + player.addSkill("yijin_clear"); + target.addMark(kane, 1); + target.addAdditionalSkill("yijin_" + player.playerid, kane); game.delayx(); }, - subSkill:{ - mark:{ - mark:true, - marktext:'金', - intro:{ - name:'金(膴仕)', - name2:'金(膴仕)', - markcount:function(storage,player){ + subSkill: { + mark: { + mark: true, + marktext: "金", + intro: { + name: "金(膴仕)", + name2: "金(膴仕)", + markcount: function (storage, player) { return lib.skill.yijin.getKane(player).length; }, - content:function(storage,player){ - return '剩余金:'+get.translation(lib.skill.yijin.getKane(player)); + content: function (storage, player) { + return "剩余金:" + get.translation(lib.skill.yijin.getKane(player)); }, }, }, - upstart:{ - audio:'yijin', - trigger:{ - global:'phaseBefore', - player:'enterGame', + upstart: { + audio: "yijin", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - var kane=lib.skill.yijin.derivation; - for(var mark of kane){ - player.addMark(mark,1,false); + content: function () { + var kane = lib.skill.yijin.derivation; + for (var mark of kane) { + player.addMark(mark, 1, false); player.unmarkSkill(mark); } - player.addSkill('yijin_mark'); - } + player.addSkill("yijin_mark"); + }, }, - die:{ - audio:'yijin', - trigger:{player:'phaseBegin'}, - forced:true, - check:()=>false, - filter:function(event,player){ + die: { + audio: "yijin", + trigger: { player: "phaseBegin" }, + forced: true, + check: () => false, + filter: function (event, player) { return !lib.skill.yijin.getKane(player).length; }, - content:function(){ + content: function () { player.die(); - } + }, }, - clear:{ - trigger:{ - global:'phaseAfter', - player:'die', + clear: { + trigger: { + global: "phaseAfter", + player: "die", }, - charlotte:true, - forced:true, - popup:false, - forceDie:true, - filter:function(event,player){ - if(event.name=='die') return true; - return lib.skill.yijin.getKane(event.player).length&&event.player.additionalSkills['yijin_'+player.playerid]; + charlotte: true, + forced: true, + popup: false, + forceDie: true, + filter: function (event, player) { + if (event.name == "die") return true; + return ( + lib.skill.yijin.getKane(event.player).length && + event.player.additionalSkills["yijin_" + player.playerid] + ); }, - content:function(){ - 'step 0' - if(trigger.name=='die'){ - game.countPlayer(current=>{ - var skills=current.additionalSkills['yijin_'+player.playerid]; - if(skills&&skills.length){ - current.removeAdditionalSkill('yijin_'+player.playerid); - for(var i of skills){ + content: function () { + "step 0"; + if (trigger.name == "die") { + game.countPlayer((current) => { + var skills = current.additionalSkills["yijin_" + player.playerid]; + if (skills && skills.length) { + current.removeAdditionalSkill("yijin_" + player.playerid); + for (var i of skills) { trigger.player.removeSkill(i); } } }); event.finish(); return; + } else { + const skills = trigger.player.additionalSkills["yijin_" + player.playerid]; + for (const mark of skills) trigger.player.removeMark(mark, 1); } - else { - const skills=trigger.player.additionalSkills['yijin_'+player.playerid]; - for(const mark of skills) trigger.player.removeMark(mark,1); - } - 'step 1' - trigger.player.removeAdditionalSkill('yijin_'+player.playerid); + "step 1"; + trigger.player.removeAdditionalSkill("yijin_" + player.playerid); }, }, - wushi:{ - charlotte:true, - forced:true, - trigger:{player:'phaseDrawBegin2'}, - content:function(){ - trigger.num+=4; + wushi: { + charlotte: true, + forced: true, + trigger: { player: "phaseDrawBegin2" }, + content: function () { + trigger.num += 4; }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, - marktext:'金', - intro:{ - name:'金(膴仕)', - name2:'金(膴仕)', - content:'摸牌阶段多摸四张牌;使用【杀】的次数上限+1', + marktext: "金", + intro: { + name: "金(膴仕)", + name2: "金(膴仕)", + content: "摸牌阶段多摸四张牌;使用【杀】的次数上限+1", }, }, - jinmi:{ - charlotte:true, - forced:true, - trigger:{player:'phaseBegin'}, - content:function(){ - player.skip('phaseUse'); - player.skip('phaseDiscard'); + jinmi: { + charlotte: true, + forced: true, + trigger: { player: "phaseBegin" }, + content: function () { + player.skip("phaseUse"); + player.skip("phaseDiscard"); }, - marktext:'金', - intro:{ - name:'金(金迷)', - name2:'金(金迷)', - content:'回合开始时,跳过下一个出牌阶段和弃牌阶段', + marktext: "金", + intro: { + name: "金(金迷)", + name2: "金(金迷)", + content: "回合开始时,跳过下一个出牌阶段和弃牌阶段", }, }, - guxiong:{ - charlotte:true, - forced:true, - trigger:{player:'phaseUseBegin'}, - content:function(){ + guxiong: { + charlotte: true, + forced: true, + trigger: { player: "phaseUseBegin" }, + content: function () { player.loseHp(); }, - mod:{ - maxHandcard:function(player,num){ - return num-3; - } - }, - marktext:'金', - intro:{ - name:'金(贾凶)', - name2:'金(贾凶)', - content:'出牌阶段开始时,失去1点体力;手牌上限-3', - }, - }, - tongshen:{ - charlotte:true, - forced:true, - trigger:{player:'damageBegin4'}, - filter:function(event){ - return !event.hasNature('thunder'); - }, - 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]; - } + mod: { + maxHandcard: function (player, num) { + return num - 3; }, }, - marktext:'金', - intro:{ - name:'金(通神)', - name2:'金(通神)', - content:'当你受到非雷电伤害时,防止之', + marktext: "金", + intro: { + name: "金(贾凶)", + name2: "金(贾凶)", + content: "出牌阶段开始时,失去1点体力;手牌上限-3", }, }, - yongbi:{ - charlotte:true, - forced:true, - trigger:{player:'phaseZhunbeiBegin'}, - content:function(){ - player.skip('phaseDraw'); + tongshen: { + charlotte: true, + forced: true, + trigger: { player: "damageBegin4" }, + filter: function (event) { + return !event.hasNature("thunder"); }, - marktext:'金', - intro:{ - name:'金(拥蔽)', - name2:'金(拥蔽)', - content:'准备阶段,跳过下一个摸牌阶段', + 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]; + }, + }, + }, + marktext: "金", + intro: { + name: "金(通神)", + name2: "金(通神)", + content: "当你受到非雷电伤害时,防止之", }, }, - houren:{ - charlotte:true, - forced:true, - trigger:{player:'phaseEnd'}, - content:function(){ + yongbi: { + charlotte: true, + forced: true, + trigger: { player: "phaseZhunbeiBegin" }, + content: function () { + player.skip("phaseDraw"); + }, + marktext: "金", + intro: { + name: "金(拥蔽)", + name2: "金(拥蔽)", + content: "准备阶段,跳过下一个摸牌阶段", + }, + }, + houren: { + charlotte: true, + forced: true, + trigger: { player: "phaseEnd" }, + content: function () { player.recover(3); }, - marktext:'金', - intro:{ - name:'金(厚任)', - name2:'金(厚任)', - content:'回合结束时,回复3点体力', + marktext: "金", + intro: { + name: "金(厚任)", + name2: "金(厚任)", + content: "回合结束时,回复3点体力", }, - } - } - }, - guanzong:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.countPlayer(current=>current!=player)>=2; - }, - filterTarget:lib.filter.notMe, - selectTarget:2, - multitarget:true, - targetprompt:['伤害来源','受伤角色'], - content:function(){ - targets[1].damage(targets[0],'unreal'); - }, - ai:{ - result:{ - target:function(player,target){ - if(game.countPlayer(i=>i!=player)<2) return 0; - var list=game.filterPlayer(current=>current!=player).map(current=>{ - var _hp=current.hp,_maxhp=current.maxHp; - current.hp=10; current.maxHp=10; - var att=-get.sgnAttitude(player,current); - var val=get.damageEffect(current,player,current)*att; - current.getSkills(null,false,false).forEach(skill=>{ - var info=get.info(skill); - if(info&&info.ai&&(info.ai.maixie||info.ai.maixie_hp||info.ai.maixie_defend)) val=Math[val>0?'max':'min'](val>0?0.1:-0.1,val+2*att); - }); - var eff=100/val+15; - current.hp=_hp; current.maxHp=_maxhp; - return [current,eff]; - }).sort((a,b)=>b[1]-a[1])[0]; - if(list[1]<0) return 0; - var targetx=list[0],sign=get.sgnAttitude(player,target); - if(ui.selected.targets.length) return target==targetx?sign:0; - return sign*(game.filterPlayer(current=>{ - return current!=player&¤t!=targetx; - }).map(current=>{ - var _hp=targetx.hp,_maxhp=targetx.maxHp; - targetx.hp=10; targetx.maxHp=10; - var eff=-get.damageEffect(targetx,current,current); - targetx.hp=_hp; targetx.maxHp=_maxhp; - return [current,eff]; - }).sort((a,b)=>b[1]-a[1])[0][0]==target?10:1); - } }, - order:9.5, - expose:0.2 - } + }, + }, + guanzong: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.countPlayer((current) => current != player) >= 2; + }, + filterTarget: lib.filter.notMe, + selectTarget: 2, + multitarget: true, + targetprompt: ["伤害来源", "受伤角色"], + content: function () { + targets[1].damage(targets[0], "unreal"); + }, + ai: { + result: { + target: function (player, target) { + if (game.countPlayer((i) => i != player) < 2) return 0; + var list = game + .filterPlayer((current) => current != player) + .map((current) => { + var _hp = current.hp, + _maxhp = current.maxHp; + current.hp = 10; + current.maxHp = 10; + var att = -get.sgnAttitude(player, current); + var val = get.damageEffect(current, player, current) * att; + current.getSkills(null, false, false).forEach((skill) => { + var info = get.info(skill); + if ( + info && + info.ai && + (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) + ) + val = Math[val > 0 ? "max" : "min"]( + val > 0 ? 0.1 : -0.1, + val + 2 * att + ); + }); + var eff = 100 / val + 15; + current.hp = _hp; + current.maxHp = _maxhp; + return [current, eff]; + }) + .sort((a, b) => b[1] - a[1])[0]; + if (list[1] < 0) return 0; + var targetx = list[0], + sign = get.sgnAttitude(player, target); + if (ui.selected.targets.length) return target == targetx ? sign : 0; + return ( + sign * + (game + .filterPlayer((current) => { + return current != player && current != targetx; + }) + .map((current) => { + var _hp = targetx.hp, + _maxhp = targetx.maxHp; + targetx.hp = 10; + targetx.maxHp = 10; + var eff = -get.damageEffect(targetx, current, current); + targetx.hp = _hp; + targetx.maxHp = _maxhp; + return [current, eff]; + }) + .sort((a, b) => b[1] - a[1])[0][0] == target + ? 10 + : 1) + ); + }, + }, + order: 9.5, + expose: 0.2, + }, }, //马日磾 - chengye:{ - audio:3, - liujing_filter:[ - function(card){ - return get.type(card,false)=='trick'&&get.tag(card,'damage',null,false)>0; + chengye: { + audio: 3, + liujing_filter: [ + function (card) { + return get.type(card, false) == "trick" && get.tag(card, "damage", null, false) > 0; }, - (card)=>get.type(card,false)=='basic', - (card)=>get.name(card,false)=='wuxie', - (card)=>get.name(card,false)=='wuzhong', - (card)=>get.name(card,false)=='lebu', - (card)=>get.type(card,false)=='equip', + (card) => get.type(card, false) == "basic", + (card) => get.name(card, false) == "wuxie", + (card) => get.name(card, false) == "wuzhong", + (card) => get.name(card, false) == "lebu", + (card) => get.type(card, false) == "equip", ], - getLiujing:function(player,index){ - var filter=lib.skill.chengye.liujing_filter[index],expansion=player.getExpansions('chengye'); - for(var i of expansion){ - if(filter(i)) return i; + getLiujing: function (player, index) { + var filter = lib.skill.chengye.liujing_filter[index], + expansion = player.getExpansions("chengye"); + for (var i of expansion) { + if (filter(i)) return i; } return false; }, - trigger:{global:['useCardAfter','loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter']}, - forced:true, - filter:function(event,player){ - if(player==event.player) return false; - if(event.name=='useCard'){ - if(!event.card.isCard) return false; - var cards=event.cards.filterInD(); - if(!cards.length) return false; - } - else if(event.name!='cardsDiscard'){ - var cards=event.getd(null,'cards2').filter(function(card){ - if(get.position(card,true)!='d') return false; - var type=get.type(card,false); - return type=='delay'||type=='equip'; + trigger: { + global: [ + "useCardAfter", + "loseAfter", + "cardsDiscardAfter", + "loseAsyncAfter", + "equipAfter", + ], + }, + forced: true, + filter: function (event, player) { + if (player == event.player) return false; + if (event.name == "useCard") { + if (!event.card.isCard) return false; + var cards = event.cards.filterInD(); + if (!cards.length) return false; + } else if (event.name != "cardsDiscard") { + var cards = event.getd(null, "cards2").filter(function (card) { + if (get.position(card, true) != "d") return false; + var type = get.type(card, false); + return type == "delay" || type == "equip"; }); - cards.removeArray(event.getd(player,'cards2')); - if(!cards.length) return false; - } - else{ - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evt2=(evtx.relatedEvent||evtx.getParent()); - if(evt2.name!='phaseJudge'||evt2.player==player) return; - var cards=event.cards.filter(function(card){ - if(get.position(card,true)!='d') return false; - var type=get.type(card,false); - return type=='delay'; + cards.removeArray(event.getd(player, "cards2")); + if (!cards.length) return false; + } else { + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evt2 = evtx.relatedEvent || evtx.getParent(); + if (evt2.name != "phaseJudge" || evt2.player == player) return; + var cards = event.cards.filter(function (card) { + if (get.position(card, true) != "d") return false; + var type = get.type(card, false); + return type == "delay"; }); - if(!cards.length) return false; + if (!cards.length) return false; } - for(var i=0;i<6;i++){ - if(lib.skill.chengye.getLiujing(player,i)) continue; - for(var j of cards){ - if(lib.skill.chengye.liujing_filter[i](j)) return true; + for (var i = 0; i < 6; i++) { + if (lib.skill.chengye.getLiujing(player, i)) continue; + for (var j of cards) { + if (lib.skill.chengye.liujing_filter[i](j)) return true; } } return false; }, - content:function(){ - var cards,cards2=[]; - if(trigger.name=='useCard'){ - cards=trigger.cards.filterInD(); - } - else if(trigger.name!='cardsDiscard'){ - cards=trigger.getd().filter(function(card){ - if(card.original=='j'||get.position(card,true)!='d') return false; - var type=get.type(card,false); - return type=='delay'||type=='equip'; + content: function () { + var cards, + cards2 = []; + if (trigger.name == "useCard") { + cards = trigger.cards.filterInD(); + } else if (trigger.name != "cardsDiscard") { + cards = trigger.getd().filter(function (card) { + if (card.original == "j" || get.position(card, true) != "d") return false; + var type = get.type(card, false); + return type == "delay" || type == "equip"; }); cards.removeArray(trigger.getd(player)); - } - else{ - cards=trigger.cards.filter(function(card){ - if(get.position(card,true)!='d') return false; - var type=get.type(card,false); - return type=='delay'; + } else { + cards = trigger.cards.filter(function (card) { + if (get.position(card, true) != "d") return false; + var type = get.type(card, false); + return type == "delay"; }); } - for(var i=0;i<6;i++){ - if(lib.skill.chengye.getLiujing(player,i)) continue; - for(var j of cards){ - if(lib.skill.chengye.liujing_filter[i](j)){ + for (var i = 0; i < 6; i++) { + if (lib.skill.chengye.getLiujing(player, i)) continue; + for (var j of cards) { + if (lib.skill.chengye.liujing_filter[i](j)) { cards.remove(j); cards2.push(j); break; } } - if(!cards.length) break; + if (!cards.length) break; } - player.addToExpansion(cards2,'gain2').gaintag.add('chengye'); + player.addToExpansion(cards2, "gain2").gaintag.add("chengye"); }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'经', - intro:{ - name:'六经', - markcount:'expansion', - content:'expansion', - mark:function(dialog,storage,player){ - var list=['《诗经》','《尚书》','《仪礼》','《易经》','《乐经》','《春秋》']; - var desc=['伤害类锦囊牌','基本牌','无懈可击','无中生有','乐不思蜀','装备牌']; - for(var i=0;i<6;i++){ + marktext: "经", + intro: { + name: "六经", + markcount: "expansion", + content: "expansion", + mark: function (dialog, storage, player) { + var list = ["《诗经》", "《尚书》", "《仪礼》", "《易经》", "《乐经》", "《春秋》"]; + var desc = ["伤害类锦囊牌", "基本牌", "无懈可击", "无中生有", "乐不思蜀", "装备牌"]; + for (var i = 0; i < 6; i++) { dialog.addText(list[i]); - var card=lib.skill.chengye.getLiujing(player,i); - if(!card) dialog.addText('(缺少 '+desc[i]+')'); + var card = lib.skill.chengye.getLiujing(player, i); + if (!card) dialog.addText("(缺少 " + desc[i] + ")"); else dialog.addSmall([card]); } }, }, - group:'chengye_gain', - subSkill:{ - gain:{ - audio:'chengye', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.getExpansions('chengye').length>=6; + group: "chengye_gain", + subSkill: { + gain: { + audio: "chengye", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.getExpansions("chengye").length >= 6; }, - forced:true, - content:function(){ - player.gain(player.getExpansions('chengye'),'gain2'); + forced: true, + content: function () { + player.gain(player.getExpansions("chengye"), "gain2"); }, }, }, }, - buxu:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - var num=(player.getStat('skill').buxu||0)+1; - return player.countCards('he')>=num&&player.getExpansions('chengye').length<6; + buxu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + var num = (player.getStat("skill").buxu || 0) + 1; + return player.countCards("he") >= num && player.getExpansions("chengye").length < 6; }, - chooseButton:{ - chooseControl:function(event,player){ - var list=['诗经','尚书','仪礼','易经','乐经','春秋']; - var choices=[]; - for(var i=0;i<6;i++){ - if(!lib.skill.chengye.getLiujing(player,i)) choices.push(list[i]); + chooseButton: { + chooseControl: function (event, player) { + var list = ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"]; + var choices = []; + for (var i = 0; i < 6; i++) { + if (!lib.skill.chengye.getLiujing(player, i)) choices.push(list[i]); } - choices.push('cancel2'); + choices.push("cancel2"); return choices; }, - check:function(event,player){ - var list=[4,3,5,0,2,1]; - for(var i of list){ - if(!lib.skill.chengye.getLiujing(player,i)){ - return ['诗经','尚书','仪礼','易经','乐经','春秋'][i]; + check: function (event, player) { + var list = [4, 3, 5, 0, 2, 1]; + for (var i of list) { + if (!lib.skill.chengye.getLiujing(player, i)) { + return ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"][i]; } } - return 'cancel2'; + return "cancel2"; }, - dialog:function(event,player){ - var num=(player.getStat('skill').buxu||0)+1; - return ui.create.dialog('###补叙###弃置'+get.cnNumber(num)+'张牌并补充一张“六经”'); + dialog: function (event, player) { + var num = (player.getStat("skill").buxu || 0) + 1; + return ui.create.dialog( + "###补叙###弃置" + get.cnNumber(num) + "张牌并补充一张“六经”" + ); }, - prompt:function(links,player){ - var num=(player.getStat('skill').buxu||0)+1; - return '弃置'+get.cnNumber(num)+'张牌并补充一张《'+links.control+'》'; + prompt: function (links, player) { + var num = (player.getStat("skill").buxu || 0) + 1; + return "弃置" + get.cnNumber(num) + "张牌并补充一张《" + links.control + "》"; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'buxu', - index:['诗经','尚书','仪礼','易经','乐经','春秋'].indexOf(links.control), - filterCard:true, - position:'he', - selectCard:(player.getStat('skill').buxu||0)+1, - ai1:function(card){ - var player=_status.event.player; - if(player.needsToDiscard(0,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 10/Math.max(0.1,get.value(card)); - return 5-(player.getStat('skill').buxu||0)-get.value(card); + audio: "buxu", + index: ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"].indexOf(links.control), + filterCard: true, + position: "he", + selectCard: (player.getStat("skill").buxu || 0) + 1, + ai1: function (card) { + var player = _status.event.player; + if ( + player.needsToDiscard(0, (i, player) => { + return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); + }) + ) + return 10 / Math.max(0.1, get.value(card)); + return 5 - (player.getStat("skill").buxu || 0) - get.value(card); }, - ai2:()=>1, - content:function(){ - var filter=lib.skill.chengye.liujing_filter[lib.skill.buxu_backup.index]; - var card=get.cardPile(filter); - if(card) player.addToExpansion(card,'gain2').gaintag.add('chengye'); + ai2: () => 1, + content: function () { + var filter = lib.skill.chengye.liujing_filter[lib.skill.buxu_backup.index]; + var card = get.cardPile(filter); + if (card) player.addToExpansion(card, "gain2").gaintag.add("chengye"); }, - ai:{result:{player:1}}, - } + ai: { result: { player: 1 } }, + }; }, }, - ai:{ - combo:'chengye', - order:0.2, - result:{player:1}, + ai: { + combo: "chengye", + order: 0.2, + result: { player: 1 }, }, }, //阮慧 - mingcha:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - forced:true, - locked:false, - filter:(event)=>!event.numFixed, - content:function(){ - 'step 0' - var cards=game.cardsGotoOrdering(get.cards(3)).cards,cards2=cards.slice(0); - event.cards=cards.filter(function(i){ - return get.number(i)<9; + mingcha: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + forced: true, + locked: false, + filter: (event) => !event.numFixed, + content: function () { + "step 0"; + var cards = game.cardsGotoOrdering(get.cards(3)).cards, + cards2 = cards.slice(0); + event.cards = cards.filter(function (i) { + return get.number(i) < 9; }); // while(cards2.length>0){ // var card=cards2.pop(); @@ -5893,2133 +7370,2617 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // ui.cardPile.insertBefore(card,ui.cardPile.firstChild); // } // game.updateRoundNumber(); - player.showCards(cards,get.translation(player)+'发动了【明察】'); - if(!event.cards.length) event.finish(); - 'step 1' - player.chooseBool('是否放弃摸牌并获得'+get.translation(cards)).set('goon',trigger.num-cards.length<=1); - 'step 2' - if(result.bool){ + player.showCards(cards, get.translation(player) + "发动了【明察】"); + if (!event.cards.length) event.finish(); + "step 1"; + player + .chooseBool("是否放弃摸牌并获得" + get.translation(cards)) + .set("goon", trigger.num - cards.length <= 1); + "step 2"; + if (result.bool) { trigger.changeToZero(); - player.gain(cards,'gain2'); - } - else event.finish(); - 'step 3' - player.chooseTarget('是否随机获得其他角色的一张牌?',function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - return 3-get.attitude(player,target); - }); - 'step 4' - if(result.bool){ - var target=result.targets[0],cards=target.getGainableCards(player,'he'); - player.line(target,'green'); - if(cards.length) player.gain(cards.randomGet(),target,'giveAuto','bySelf'); + player.gain(cards, "gain2"); + } else event.finish(); + "step 3"; + player + .chooseTarget("是否随机获得其他角色的一张牌?", function (card, player, target) { + return target != player && target.countCards("he") > 0; + }) + .set("ai", function (target) { + return 3 - get.attitude(player, target); + }); + "step 4"; + if (result.bool) { + var target = result.targets[0], + cards = target.getGainableCards(player, "he"); + player.line(target, "green"); + if (cards.length) player.gain(cards.randomGet(), target, "giveAuto", "bySelf"); } }, }, - jingzhong:{ - audio:2, - trigger:{player:'phaseDiscardAfter'}, - filter:function(event,player){ - var num=0; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event){ - for(var i of evt.cards2){ - if(get.color(i,player)=='black') num++; + jingzhong: { + audio: 2, + trigger: { player: "phaseDiscardAfter" }, + filter: function (event, player) { + var num = 0; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) { + for (var i of evt.cards2) { + if (get.color(i, player) == "black") num++; } } }); - return num>1; + return num > 1; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jingzhong'),'获得一名其他角色下回合出牌阶段内使用的牌',lib.filter.notMe).set('ai',function(target){ - return Math.sqrt(target.countCards('h'))*get.threaten(target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jingzhong',target); - player.addSkill('jingzhong_effect'); - player.markAuto('jingzhong_effect',[target]); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jingzhong"), + "获得一名其他角色下回合出牌阶段内使用的牌", + lib.filter.notMe + ) + .set("ai", function (target) { + return Math.sqrt(target.countCards("h")) * get.threaten(target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jingzhong", target); + player.addSkill("jingzhong_effect"); + player.markAuto("jingzhong_effect", [target]); game.delayx(); } }, - subSkill:{ - effect:{ - trigger:{global:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(!player.getStorage('jingzhong_effect').includes(event.player)||!event.cards.filterInD().length) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - return player.getHistory('useSkill',function(evtx){ - return evtx.skill=='jingzhong_effect'&&evtx.event.getParent('phaseUse')==evt; - }).length<3; + subSkill: { + effect: { + trigger: { global: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if ( + !player.getStorage("jingzhong_effect").includes(event.player) || + !event.cards.filterInD().length + ) + return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + return ( + player.getHistory("useSkill", function (evtx) { + return ( + evtx.skill == "jingzhong_effect" && + evtx.event.getParent("phaseUse") == evt + ); + }).length < 3 + ); }, - logTarget:'player', - content:function(){ - player.gain(trigger.cards.filterInD(),'gain2'); + logTarget: "player", + content: function () { + player.gain(trigger.cards.filterInD(), "gain2"); }, - mark:true, - intro:{content:'已指定$为目标'}, - group:'jingzhong_remove', + mark: true, + intro: { content: "已指定$为目标" }, + group: "jingzhong_remove", }, - remove:{ - trigger:{global:'phaseAfter'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return player.getStorage('jingzhong_effect').includes(event.player); + remove: { + trigger: { global: "phaseAfter" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return player.getStorage("jingzhong_effect").includes(event.player); }, - content:function(){ - var storage=player.getStorage('jingzhong_effect'); + content: function () { + var storage = player.getStorage("jingzhong_effect"); storage.remove(trigger.player); - if(!storage.length) player.removeSkill('jingzhong_effect'); + if (!storage.length) player.removeSkill("jingzhong_effect"); }, }, }, }, //全琮 - sbyaoming:{ - audio:2, - chargeSkill:true, - enable:'phaseUse', - filter:function(event,player){ - return player.countMark('charge')>0; + sbyaoming: { + audio: 2, + chargeSkill: true, + enable: "phaseUse", + filter: function (event, player) { + return player.countMark("charge") > 0; }, - filterTarget:true, - prompt:function(){ - var num=_status.event.player.storage.sbyaoming_status; - var list=['弃置一名手牌数不小于你的角色的一张牌',';或令一名手牌数不大于你的角色摸一张牌'] - if(typeof num=='number') list[num]+='(上次选择)'; - return list[0]+list[1]; + filterTarget: true, + prompt: function () { + var num = _status.event.player.storage.sbyaoming_status; + var list = [ + "弃置一名手牌数不小于你的角色的一张牌", + ";或令一名手牌数不大于你的角色摸一张牌", + ]; + if (typeof num == "number") list[num] += "(上次选择)"; + return list[0] + list[1]; }, - content:function(){ - 'step 0' - player.removeMark('charge',1); - var num=target.countCards('h'),num2=player.countCards('h'); - if(num==num2&&target.countCards('he')>0){ - var choice=get.attitude(player,target)>0?1:0; - var str=get.translation(target),choiceList=[ - '弃置'+str+'的一张牌', - '令'+str+'摸一张牌', - ]; - if(typeof player.storage.sbyaoming_status=='number') choiceList[player.storage.sbyaoming_status]+='(上次选择)'; - var next=player.chooseControl().set('choiceList',choiceList); - next.set('ai_choice',choice); - next.set('ai',()=>_status.event.ai_choice); - } - else event._result={index:num>num2?0:1}; - 'step 1' - if(result.index==0){ - player.discardPlayerCard(target,true,'he'); - } - else target.draw(); - if(typeof player.storage.sbyaoming_status=='number'&&result.index!=player.storage.sbyaoming_status){ - player.addMark('charge',1); + content: function () { + "step 0"; + player.removeMark("charge", 1); + var num = target.countCards("h"), + num2 = player.countCards("h"); + if (num == num2 && target.countCards("he") > 0) { + var choice = get.attitude(player, target) > 0 ? 1 : 0; + var str = get.translation(target), + choiceList = ["弃置" + str + "的一张牌", "令" + str + "摸一张牌"]; + if (typeof player.storage.sbyaoming_status == "number") + choiceList[player.storage.sbyaoming_status] += "(上次选择)"; + var next = player.chooseControl().set("choiceList", choiceList); + next.set("ai_choice", choice); + next.set("ai", () => _status.event.ai_choice); + } else event._result = { index: num > num2 ? 0 : 1 }; + "step 1"; + if (result.index == 0) { + player.discardPlayerCard(target, true, "he"); + } else target.draw(); + if ( + typeof player.storage.sbyaoming_status == "number" && + result.index != player.storage.sbyaoming_status + ) { + player.addMark("charge", 1); delete player.storage.sbyaoming_status; - } - else{ - player.storage.sbyaoming_status=result.index; + } else { + player.storage.sbyaoming_status = result.index; } }, - ai:{ - order:6, - result:{ - player:function(player,target){ - var att=get.attitude(player,target),eff=[0,0]; - var hs=player.countCards('h'),ht=target.countCards('h'); - if(hs>=ht){ - eff[0]=get.effect(target,{name:'draw'},player,player); - if(player.storage.sbyaoming_status==0) eff[0]*=1.2; + ai: { + order: 6, + result: { + player: function (player, target) { + var att = get.attitude(player, target), + eff = [0, 0]; + var hs = player.countCards("h"), + ht = target.countCards("h"); + if (hs >= ht) { + eff[0] = get.effect(target, { name: "draw" }, player, player); + if (player.storage.sbyaoming_status == 0) eff[0] *= 1.2; } - if(hs<=ht){ - eff[1]=get.effect(target,{name:'guohe_copy2'},player,player); - if(player.storage.sbyaoming_status==1) eff[1]*=1.2; + if (hs <= ht) { + eff[1] = get.effect(target, { name: "guohe_copy2" }, player, player); + if (player.storage.sbyaoming_status == 1) eff[1] *= 1.2; } - return Math.max.apply(Math,eff); + return Math.max.apply(Math, eff); }, }, }, - group:['sbyaoming_damage','sbyaoming_init'], - subSkill:{ - damage:{ - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - 'step 0' - var num=Math.min(trigger.num,4-player.countMark('charge')); - if(num>0){ - player.logSkill('sbyaoming_damage'); - player.addMark('charge',num); + group: ["sbyaoming_damage", "sbyaoming_init"], + subSkill: { + damage: { + trigger: { player: "damageEnd" }, + direct: true, + content: function () { + "step 0"; + var num = Math.min(trigger.num, 4 - player.countMark("charge")); + if (num > 0) { + player.logSkill("sbyaoming_damage"); + player.addMark("charge", num); game.delayx(); } - 'step 1' - player.chooseTarget(get.prompt('sbyaoming'),lib.skill.sbyaoming.prompt()).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,'sbyaoming',player,player) - }); - 'step 2' - if(result.bool){ - player.useSkill('sbyaoming',result.targets); + "step 1"; + player + .chooseTarget(get.prompt("sbyaoming"), lib.skill.sbyaoming.prompt()) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, "sbyaoming", player, player); + }); + "step 2"; + if (result.bool) { + player.useSkill("sbyaoming", result.targets); } }, }, - init:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + init: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.countMark('charge')<4; + forced: true, + locked: false, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + player.countMark("charge") < 4 + ); }, - content:function(){ - player.addMark('charge',Math.min(2,4-player.countMark('charge'))); + content: function () { + player.addMark("charge", Math.min(2, 4 - player.countMark("charge"))); }, }, }, }, //手杀界荀彧 - rejieming:{ - audio:2, - trigger:{ - player:"damageEnd", + rejieming: { + audio: 2, + trigger: { + player: "damageEnd", }, - direct:true, - content:function (){ - "step 0" - event.count=trigger.num; - "step 1" - player.chooseTarget(get.prompt('rejieming'),'令一名角色摸两张牌。然后若其手牌数少于体力上限,你摸一张牌').set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>2){ - if((target.maxHp-target.countCards('h'))>2) return 2*att; - return att; - } - return att/3; - }); - "step 2" - if(result.bool){ - event.current=result.targets[0]; - player.logSkill('rejieming',event.current); - player.line(event.current,'thunder'); + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + player + .chooseTarget( + get.prompt("rejieming"), + "令一名角色摸两张牌。然后若其手牌数少于体力上限,你摸一张牌" + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 2) { + if (target.maxHp - target.countCards("h") > 2) return 2 * att; + return att; + } + return att / 3; + }); + "step 2"; + if (result.bool) { + event.current = result.targets[0]; + player.logSkill("rejieming", event.current); + player.line(event.current, "thunder"); event.current.draw(2); event.count--; - } - else event.finish(); - "step 3" - if(event.current.countCards('h')0&&player.hasSkill('rejieming')) event.goto(1); + "step 4"; + if (event.count > 0 && player.hasSkill("rejieming")) event.goto(1); }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function (card,player,target,current){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - var max=0; - var players=game.filterPlayer(); - for(var i=0;i0){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + var max = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(target, players[i]) > 0) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return 2; - case 1:return 1.5; - case 2:return [1,2]; - default:return [0,max]; + switch (max) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return [1, 2]; + default: + return [0, max]; } } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; }, }, }, }, //沮授 - xinjianying:{ - audio:2, - subfrequent:['draw'], - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(!player.countCards('he')) return false; - for(var i of lib.inpile){ - if(i!='du'&&get.type(i,false)=='basic'){ - if(event.filterCard({name:i},player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard({name:i,nature:j},player,event)) return true; + xinjianying: { + audio: 2, + subfrequent: ["draw"], + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (!player.countCards("he")) return false; + for (var i of lib.inpile) { + if (i != "du" && get.type(i, false) == "basic") { + if (event.filterCard({ name: i }, player, event)) return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: i, nature: j }, player, event)) return true; } } } } return false; }, - onChooseToUse:function(event){ - if(event.type=='phase'&&!game.online){ - var last=event.player.getLastUsed(); - if(last&&last.getParent('phaseUse')==event.getParent()){ - var suit=get.suit(last.card,false); - if(suit!='none') event.set('xinjianying_suit',suit); + onChooseToUse: function (event) { + if (event.type == "phase" && !game.online) { + var last = event.player.getLastUsed(); + if (last && last.getParent("phaseUse") == event.getParent()) { + var suit = get.suit(last.card, false); + if (suit != "none") event.set("xinjianying_suit", suit); } } }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - var suit=event.xinjianying_suit||'',str=get.translation(suit); - for(var i of lib.inpile){ - if(i!='du'&&get.type(i,false)=='basic'){ - if(event.filterCard({name:i},player,event)) list.push(['基本',str,i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard({name:i,nature:j},player,event)) list.push(['基本',str,i,j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + var suit = event.xinjianying_suit || "", + str = get.translation(suit); + for (var i of lib.inpile) { + if (i != "du" && get.type(i, false) == "basic") { + if (event.filterCard({ name: i }, player, event)) list.push(["基本", str, i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: i, nature: j }, player, event)) + list.push(["基本", str, i, j]); } } } } - return ui.create.dialog('渐营',[list,'vcard']); + return ui.create.dialog("渐营", [list, "vcard"]); }, - check:function(button){ - if(button.link[2]=='jiu') return 0; - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); + check: function (button) { + if (button.link[2] == "jiu") return 0; + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); }, - backup:function(links,player){ - var next={ - audio:'xinjianying', - filterCard:true, - popname:true, - position:'he', - viewAs:{ - name:links[0][2], - nature:links[0][3], + backup: function (links, player) { + var next = { + audio: "xinjianying", + filterCard: true, + popname: true, + position: "he", + viewAs: { + name: links[0][2], + nature: links[0][3], }, - ai1:function(card){ - return 7-_status.event.player.getUseValue(card,null,true); + ai1: function (card) { + return 7 - _status.event.player.getUseValue(card, null, true); }, }; - if(_status.event.xinjianying_suit) next.viewAs.suit=_status.event.xinjianying_suit; + if (_status.event.xinjianying_suit) next.viewAs.suit = _status.event.xinjianying_suit; return next; }, - prompt:function(links){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+(_status.event.xinjianying_suit?('('+get.translation(_status.event.xinjianying_suit)+')'):'')+'使用'; + prompt: function (links) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + (_status.event.xinjianying_suit + ? "(" + get.translation(_status.event.xinjianying_suit) + ")" + : "") + + "使用" + ); }, }, - ai:{ - order:function(item,player){ - if(_status.event.xinjianying_suit) return 16; + ai: { + order: function (item, player) { + if (_status.event.xinjianying_suit) return 16; return 3; }, - result:{player:7}, + result: { player: 7 }, }, - group:['xinjianying_draw','jianying_mark'], - init:function(player){ - if(player.isPhaseUsing()){ - var evt=_status.event.getParent('phaseUse'); - var history=player.getHistory('useCard',function(evt2){ - return evt2.getParent('phaseUse')==evt; + group: ["xinjianying_draw", "jianying_mark"], + init: function (player) { + if (player.isPhaseUsing()) { + var evt = _status.event.getParent("phaseUse"); + var history = player.getHistory("useCard", function (evt2) { + return evt2.getParent("phaseUse") == evt; }); - if(history.length){ - var trigger=history[history.length-1]; - player.storage.jianying_mark=trigger.card; - player.markSkill('jianying_mark'); - game.broadcastAll(function(player,suit){ - if(player.marks.jianying_mark) player.marks.jianying_mark.firstChild.innerHTML=get.translation(suit); - },player,get.suit(trigger.card,player)); - player.when('phaseUseAfter').then(()=>{ - player.unmarkSkill('jianying_mark'); + if (history.length) { + var trigger = history[history.length - 1]; + player.storage.jianying_mark = trigger.card; + player.markSkill("jianying_mark"); + game.broadcastAll( + function (player, suit) { + if (player.marks.jianying_mark) + player.marks.jianying_mark.firstChild.innerHTML = + get.translation(suit); + }, + player, + get.suit(trigger.card, player) + ); + player.when("phaseUseAfter").then(() => { + player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }); } } }, - onremove:function(player){ - player.unmarkSkill('jianying_mark'); + onremove: function (player) { + player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }, - subSkill:{ - draw:{inherit:'jianying',audio:'xinjianying'}, + subSkill: { + draw: { inherit: "jianying", audio: "xinjianying" }, }, }, //步练师 - reanxu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.countPlayer()>2&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); - }); - }, - selectTarget:2, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(!ui.selected.targets.length) return target.countCards('he')>0; - return target!=ui.selected.targets[0]&&ui.selected.targets[0].countGainableCards(target,'he')>0; - }, - multitarget:true, - targetprompt:['被拿牌','得到牌'], - content:function(){ - 'step 0' - targets[1].gainPlayerCard(targets[0],'he',true); - 'step 1' - if(targets[0].getHistory('lose',function(evt){ - return evt.getParent(3)==event&&!evt.es.length; - }).length) player.draw(); - 'step 2' - if(targets[0].isIn()&&targets[1].isIn()&& - targets[0].countCards('h')!=targets[1].countCards('h')){ - event.target=targets[targets[0].countCards('h')>targets[1].countCards('h')?1:0]; - player.chooseBool('是否令'+get.translation(event.target)+'摸一张牌?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0; + reanxu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + game.countPlayer() > 2 && + game.hasPlayer(function (current) { + return current != player && current.countCards("he"); }) - } - else event.finish(); - 'step 3' - if(result.bool) target.draw(); + ); }, - ai:{ - expose:0.2, - threaten:2, - order:9, - result:{ - player:function(player,target){ - if(ui.selected.targets.length) return 0.01; - return target.countCards('e')?0:0.5; + selectTarget: 2, + filterTarget: function (card, player, target) { + if (target == player) return false; + if (!ui.selected.targets.length) return target.countCards("he") > 0; + return ( + target != ui.selected.targets[0] && + ui.selected.targets[0].countGainableCards(target, "he") > 0 + ); + }, + multitarget: true, + targetprompt: ["被拿牌", "得到牌"], + content: function () { + "step 0"; + targets[1].gainPlayerCard(targets[0], "he", true); + "step 1"; + if ( + targets[0].getHistory("lose", function (evt) { + return evt.getParent(3) == event && !evt.es.length; + }).length + ) + player.draw(); + "step 2"; + if ( + targets[0].isIn() && + targets[1].isIn() && + targets[0].countCards("h") != targets[1].countCards("h") + ) { + event.target = + targets[targets[0].countCards("h") > targets[1].countCards("h") ? 1 : 0]; + player + .chooseBool("是否令" + get.translation(event.target) + "摸一张牌?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 0; + }); + } else event.finish(); + "step 3"; + if (result.bool) target.draw(); + }, + ai: { + expose: 0.2, + threaten: 2, + order: 9, + result: { + player: function (player, target) { + if (ui.selected.targets.length) return 0.01; + return target.countCards("e") ? 0 : 0.5; }, - target:function(player,target){ - if(ui.selected.targets.length){ - player=target; - target=ui.selected.targets[0]; - if(get.attitude(player,target)>1){ + target: function (player, target) { + if (ui.selected.targets.length) { + player = target; + target = ui.selected.targets[0]; + if (get.attitude(player, target) > 1) { return 0; } - return target.countCards('h')-player.countCards('h')>(target.countCards('e')?2:1)?2:1; - } - else{ - if(get.attitude(player,target)<=0) return (target.countCards('he',function(card){ - return card.name=='tengjia'||get.value(card)>0; - })>0)?-1.5:1.5; - return (target.countCards('he',function(card){ - return card.name!='tengjia'&&get.value(card)<=0; - })>0)?1.5:-1.5 + return target.countCards("h") - player.countCards("h") > + (target.countCards("e") ? 2 : 1) + ? 2 + : 1; + } else { + if (get.attitude(player, target) <= 0) + return target.countCards("he", function (card) { + return card.name == "tengjia" || get.value(card) > 0; + }) > 0 + ? -1.5 + : 1.5; + return target.countCards("he", function (card) { + return card.name != "tengjia" && get.value(card) <= 0; + }) > 0 + ? 1.5 + : -1.5; } }, }, }, }, //蒋干 - spdaoshu:{ - audio:3, - group:'spdaoshu_effect', - subSkill:{ - effect:{ - audio:'spdaoshu1', - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - var goon=(event.player!=player&&(get.mode()=='identity'||get.mode()=='guozhan'||event.player.isEnemyOf(player))); - return goon&&event.player.countCards('h')>0&&event.player.hasUseTarget({name:'jiu',isCard:true},null,true); + spdaoshu: { + audio: 3, + group: "spdaoshu_effect", + subSkill: { + effect: { + audio: "spdaoshu1", + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + var goon = + event.player != player && + (get.mode() == "identity" || + get.mode() == "guozhan" || + event.player.isEnemyOf(player)); + return ( + goon && + event.player.countCards("h") > 0 && + event.player.hasUseTarget({ name: "jiu", isCard: true }, null, true) + ); }, - round:1, - logTarget:'player', - prompt2:()=>lib.translate.spdaoshu_info, - check:function(event,player){ - var target=event.player; - var att=get.attitude(player,target); - if(att>0) return false; - if(att==0) return !player.inRangeOf(target); + round: 1, + logTarget: "player", + prompt2: () => lib.translate.spdaoshu_info, + check: function (event, player) { + var target = event.player; + var att = get.attitude(player, target); + if (att > 0) return false; + if (att == 0) return !player.inRangeOf(target); return true; }, - content:function(){ - 'step 0' - event.target=trigger.player; - event.target.chooseUseTarget('jiu',true); - 'step 1' - if(!target.countCards('h')){ + content: function () { + "step 0"; + event.target = trigger.player; + event.target.chooseUseTarget("jiu", true); + "step 1"; + if (!target.countCards("h")) { event.finish(); return; } - var list=[]; - for(var i of lib.inpile){ - if(get.type(i)=='basic') list.push(i); + var list = []; + for (var i of lib.inpile) { + if (get.type(i) == "basic") list.push(i); } - if(!list.length){ + if (!list.length) { event.finish(); return; } - target.chooseControl(list).set('prompt','请声明一种基本牌').set('ai',()=>_status.event.rand).set('rand',get.rand(0,list.length-1)); - 'step 2' - event.cardname=result.control; - target.chat('我声明'+get.translation(event.cardname)); - game.log(target,'声明的牌名为','#y'+get.translation(event.cardname)); + target + .chooseControl(list) + .set("prompt", "请声明一种基本牌") + .set("ai", () => _status.event.rand) + .set("rand", get.rand(0, list.length - 1)); + "step 2"; + event.cardname = result.control; + target.chat("我声明" + get.translation(event.cardname)); + game.log(target, "声明的牌名为", "#y" + get.translation(event.cardname)); game.delayx(); - player.chooseControl('有!','没有!').set('prompt','你觉得'+get.translation(target)+'的手牌区里有'+get.translation(event.cardname)+'吗?').set('ai',function(){ - return _status.event.choice; - }).set('choice',function(){ - var rand={ - sha:0.273, - shan:0.149, - tao:0.074, - jiu:0.031, - }[event.cardname]||0.1; - return (1-Math.pow(1-rand,target.countCards('h')))>0.5?'有!':'没有!'; - }()); - 'step 3' + player + .chooseControl("有!", "没有!") + .set( + "prompt", + "你觉得" + + get.translation(target) + + "的手牌区里有" + + get.translation(event.cardname) + + "吗?" + ) + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var rand = + { + sha: 0.273, + shan: 0.149, + tao: 0.074, + jiu: 0.031, + }[event.cardname] || 0.1; + return 1 - Math.pow(1 - rand, target.countCards("h")) > 0.5 + ? "有!" + : "没有!"; + })() + ); + "step 3"; player.chat(result.control); - game.log(player,'认为','#y'+result.control); + game.log(player, "认为", "#y" + result.control); game.delayx(); - 'step 4' - var bool1=(result.index==0); - var bool2=(target.hasCard(function(card){ - return get.name(card,target)==event.cardname; - },'h')); - if(bool1==bool2){ - player.popup('判断正确','wood'); - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spdaoshu2'); + "step 4"; + var bool1 = result.index == 0; + var bool2 = target.hasCard(function (card) { + return get.name(card, target) == event.cardname; + }, "h"); + if (bool1 == bool2) { + player.popup("判断正确", "wood"); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spdaoshu2"); }); - player.gainPlayerCard(target,'h',2,true); + player.gainPlayerCard(target, "h", 2, true); //var cards=target.getCards('h',function(card){ // return lib.filter.canBeGained(card,player,target); //}).randomGets(5); //if(cards.length>0) player.gain(cards,target,'giveAuto','bySelf'); - } - else{ - player.popup('判断错误','fire'); - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spdaoshu3'); + } else { + player.popup("判断错误", "fire"); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spdaoshu3"); }); //player.addTempSkill('spdaoshu_respond'); } }, - ai:{expose:0.3}, + ai: { expose: 0.3 }, }, - respond:{ - trigger:{global:'useCard1'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player==_status.currentPhase; + respond: { + trigger: { global: "useCard1" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == _status.currentPhase; }, - content:function(){ + content: function () { trigger.directHit.add(player); }, }, }, }, - spdaoshu1:{audio:true}, - mbdaoshu:{ - audio:3, - group:'mbdaoshu_use', - subSkill:{ - use:{ - audio:'mbdaoshu1', - enable:'phaseUse', - filter:function(event,player){ - return game.hasPlayer(target=>target!=player&&target.countCards('h')>2); + spdaoshu1: { audio: true }, + mbdaoshu: { + audio: 3, + group: "mbdaoshu_use", + subSkill: { + use: { + audio: "mbdaoshu1", + enable: "phaseUse", + filter: function (event, player) { + return game.hasPlayer((target) => target != player && target.countCards("h") > 2); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>2; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 2; }, - usable:1, - prompt:()=>lib.translate.mbdaoshu_info, - content:function*(event,map){ - var player=map.player,target=event.target; - var targets=[player],names=lib.inpile.randomGets(3); - if(!names.length) return; - var map={}; - names.forEach(name=>map[get.translation(name)]=name); - if(get.mode()!='identity'&&get.mode()!='guozhan') targets.addArray(player.getFriends()); + usable: 1, + prompt: () => lib.translate.mbdaoshu_info, + content: function* (event, map) { + var player = map.player, + target = event.target; + var targets = [player], + names = lib.inpile.randomGets(3); + if (!names.length) return; + var map = {}; + names.forEach((name) => (map[get.translation(name)] = name)); + if (get.mode() != "identity" && get.mode() != "guozhan") + targets.addArray(player.getFriends()); targets.remove(target); targets.sortBySeat(); - var result=yield target.chooseButton([ - '盗书:请选择伪装的牌和牌名', - target.getCards('h'), - [Object.keys(map),'tdnodes'], - ],2,true).set('filterButton',button=>{ - var map=_status.event.map; - if(!ui.selected.buttons.length) return true; - if(typeof button.link==typeof ui.selected.buttons[0].link) return false; - if(typeof button.link=='string') return get.name(ui.selected.buttons[0].link,false)!=map[button.link]; - return map[ui.selected.buttons[0].link]!=get.name(button.link,false); - }).set('ai',button=>{ - var map=_status.event.map; - if(!ui.selected.buttons.length){ - if(typeof button.link=='object'){ - if(Object.values(map).some(name=>lib.card.list.some(card=>card[0]==get.suit(button.link,false)&&card[1]==get.number(button.link,false)&&card[2]==name))) return 5; - return 3.5+Math.random(); + var result = yield target + .chooseButton( + [ + "盗书:请选择伪装的牌和牌名", + target.getCards("h"), + [Object.keys(map), "tdnodes"], + ], + 2, + true + ) + .set("filterButton", (button) => { + var map = _status.event.map; + if (!ui.selected.buttons.length) return true; + if (typeof button.link == typeof ui.selected.buttons[0].link) + return false; + if (typeof button.link == "string") + return ( + get.name(ui.selected.buttons[0].link, false) != map[button.link] + ); + return map[ui.selected.buttons[0].link] != get.name(button.link, false); + }) + .set("ai", (button) => { + var map = _status.event.map; + if (!ui.selected.buttons.length) { + if (typeof button.link == "object") { + if ( + Object.values(map).some((name) => + lib.card.list.some( + (card) => + card[0] == get.suit(button.link, false) && + card[1] == get.number(button.link, false) && + card[2] == name + ) + ) + ) + return 5; + return 3.5 + Math.random(); + } + return 0; + } + if (typeof button.link == "string") { + var cardx = ui.selected.buttons[0].link; + if ( + lib.card.list.some( + (card) => + card[0] == get.suit(cardx, false) && + card[1] == get.number(cardx, false) && + card[2] == map[button.link] + ) + ) + return 2 + Math.random(); + return 1; } return 0; - } - if(typeof button.link=='string'){ - var cardx=ui.selected.buttons[0].link; - if(lib.card.list.some(card=>card[0]==get.suit(cardx,false)&&card[1]==get.number(cardx,false)&&card[2]==map[button.link])) return 2+Math.random(); - return 1; - } - return 0; - }).set('map',map); - if(result.bool){ - var guessWinner=[]; - if(typeof result.links[0]=='string') result.links.reverse(); - var OriginCard=result.links[0],ChangeName=map[result.links[1]],cards=target.getCards('h').slice(); - var card=game.createCard(ChangeName,get.suit(OriginCard,false),get.number(OriginCard,false)); - cards[cards.indexOf(OriginCard)]=card; - if(_status.connectMode){ - var list=targets.map(target2=>[target2,['请猜测'+get.translation(target)+'伪装的手牌',cards],true]); - var result2=yield player.chooseButtonOL(list).set('switchToAuto',()=>_status.event.result='ai').set('processAI',()=>{ - var cards=_status.event.cards.slice(); - var card=cards.find(card=>lib.card.list.some(cardx=>cardx[2]==card.name)&&!lib.card.list.some(cardx=>cardx[2]==card.name&&cardx[0]==get.suit(card,false)&&cardx[0]==get.number(card,false))); - return { - bool:true, - links:card?card:cards.randomGet(), - } - }).set('cards',cards); - for(var i in result2){ - if(result2[i].links[0]==card) guessWinner.push(lib.playerOL[i]); + }) + .set("map", map); + if (result.bool) { + var guessWinner = []; + if (typeof result.links[0] == "string") result.links.reverse(); + var OriginCard = result.links[0], + ChangeName = map[result.links[1]], + cards = target.getCards("h").slice(); + var card = game.createCard( + ChangeName, + get.suit(OriginCard, false), + get.number(OriginCard, false) + ); + cards[cards.indexOf(OriginCard)] = card; + if (_status.connectMode) { + var list = targets.map((target2) => [ + target2, + ["请猜测" + get.translation(target) + "伪装的手牌", cards], + true, + ]); + var result2 = yield player + .chooseButtonOL(list) + .set("switchToAuto", () => (_status.event.result = "ai")) + .set("processAI", () => { + var cards = _status.event.cards.slice(); + var card = cards.find( + (card) => + lib.card.list.some((cardx) => cardx[2] == card.name) && + !lib.card.list.some( + (cardx) => + cardx[2] == card.name && + cardx[0] == get.suit(card, false) && + cardx[0] == get.number(card, false) + ) + ); + return { + bool: true, + links: card ? card : cards.randomGet(), + }; + }) + .set("cards", cards); + for (var i in result2) { + if (result2[i].links[0] == card) guessWinner.push(lib.playerOL[i]); } - } - else{ - var guessTargets=targets.slice(); - while(guessTargets.length){ - var target2=guessTargets.shift(); - var result2=yield target2.chooseButton(['请猜测'+get.translation(target)+'伪装的手牌',cards],true).set('ai',button=>{ - var cards=_status.event.cards.slice(); - var card=cards.find(card=>lib.card.list.some(cardx=>cardx[2]==get.name(card,false))&&!lib.card.list.some(cardx=>cardx[2]==get.name(card,false)&&cardx[0]==get.suit(card,false)&&cardx[0]==get.number(card,false))); - return button.link==card?3:1+Math.random(); - }).set('cards',cards); - if(result2.bool){ - if(result2.links[0]==card) guessWinner.push(target2); + } else { + var guessTargets = targets.slice(); + while (guessTargets.length) { + var target2 = guessTargets.shift(); + var result2 = yield target2 + .chooseButton( + ["请猜测" + get.translation(target) + "伪装的手牌", cards], + true + ) + .set("ai", (button) => { + var cards = _status.event.cards.slice(); + var card = cards.find( + (card) => + lib.card.list.some( + (cardx) => cardx[2] == get.name(card, false) + ) && + !lib.card.list.some( + (cardx) => + cardx[2] == get.name(card, false) && + cardx[0] == get.suit(card, false) && + cardx[0] == get.number(card, false) + ) + ); + return button.link == card ? 3 : 1 + Math.random(); + }) + .set("cards", cards); + if (result2.bool) { + if (result2.links[0] == card) guessWinner.push(target2); } } } - targets.forEach(target2=>{ - if(guessWinner.includes(target2)){ - target2.popup('判断正确','wood'); - game.log(target2,'猜测','#g正确'); - game.broadcastAll(()=>{ - if(lib.config.background_speak) game.playAudio('skill','mbdaoshu2'); + targets.forEach((target2) => { + if (guessWinner.includes(target2)) { + target2.popup("判断正确", "wood"); + game.log(target2, "猜测", "#g正确"); + game.broadcastAll(() => { + if (lib.config.background_speak) + game.playAudio("skill", "mbdaoshu2"); }); target2.line(target); - target.damage(1,target2); - } - else{ - target2.popup('判断错误','fire'); - game.log(target2,'猜测','#y错误'); - game.broadcastAll(()=>{ - if(lib.config.background_speak) game.playAudio('skill','mbdaoshu3'); + target.damage(1, target2); + } else { + target2.popup("判断错误", "fire"); + game.log(target2, "猜测", "#y错误"); + game.broadcastAll(() => { + if (lib.config.background_speak) + game.playAudio("skill", "mbdaoshu3"); }); - if(target2.countCards('h')>=2) target2.discard(target2.getCards('h').randomGets(2)); + if (target2.countCards("h") >= 2) + target2.discard(target2.getCards("h").randomGets(2)); else target2.loseHp(); } }); } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return -1/target.countCards('h'); + ai: { + order: 9, + result: { + target: function (player, target) { + return -1 / target.countCards("h"); }, }, }, }, }, }, - mbdaoshu1:{audio:true}, - spdaizui:{ - audio:2, - trigger:{player:'damageBegin2'}, - limited:true, - logTarget:'source', - filter:function(event,player){ - return event.num>=player.hp&&event.source&&event.source.isIn()&&event.cards&&event.cards.filterInD().length>0; + mbdaoshu1: { audio: true }, + spdaizui: { + audio: 2, + trigger: { player: "damageBegin2" }, + limited: true, + logTarget: "source", + filter: function (event, player) { + return ( + event.num >= player.hp && + event.source && + event.source.isIn() && + event.cards && + event.cards.filterInD().length > 0 + ); }, - prompt2:function(event){ - return '防止即将受到的'+get.cnNumber(event.num)+'点伤害,并令'+get.translation(event.source)+'将'+get.translation(event.cards.filterInD())+'置于武将牌上且回合结束时收回'; + prompt2: function (event) { + return ( + "防止即将受到的" + + get.cnNumber(event.num) + + "点伤害,并令" + + get.translation(event.source) + + "将" + + get.translation(event.cards.filterInD()) + + "置于武将牌上且回合结束时收回" + ); }, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - player.awakenSkill('spdaizui'); - trigger.source.addSkill('spdaizui2'); - trigger.source.addToExpansion(trigger.cards.filterInD(),'gain2').gaintag.add('spdaizui2'); + skillAnimation: true, + animationColor: "thunder", + content: function () { + player.awakenSkill("spdaizui"); + trigger.source.addSkill("spdaizui2"); + trigger.source + .addToExpansion(trigger.cards.filterInD(), "gain2") + .gaintag.add("spdaizui2"); trigger.cancel(); }, }, - spdaizui2:{ - trigger:{global:'phaseEnd'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('spdaizui2').length>0; + spdaizui2: { + trigger: { global: "phaseEnd" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("spdaizui2").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('spdaizui2'); - player.gain(cards,'gain2'); - 'step 1' - player.removeSkill('spdaizui2'); + content: function () { + "step 0"; + var cards = player.getExpansions("spdaizui2"); + player.gain(cards, "gain2"); + "step 1"; + player.removeSkill("spdaizui2"); }, - marktext:'释', - intro:{ - markcount:'expansion', - content:'expansion', + marktext: "释", + intro: { + markcount: "expansion", + content: "expansion", }, }, //裴秀 - xingtu:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - var evt=lib.skill.dcjianying.getLastUsed(player,event); - if(!evt||!evt.card) return false; - var num1=get.number(event.card),num2=get.number(evt.card); - return typeof num1=='number'&&typeof num2=='number'&&num2%num1==0; + xingtu: { + trigger: { player: "useCard" }, + filter: function (event, player) { + var evt = lib.skill.dcjianying.getLastUsed(player, event); + if (!evt || !evt.card) return false; + var num1 = get.number(event.card), + num2 = get.number(evt.card); + return typeof num1 == "number" && typeof num2 == "number" && num2 % num1 == 0; }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, - mod:{ - cardUsable:function(card,player){ - if(typeof card=='object'){ - var evt=lib.skill.dcjianying.getLastUsed(player); - if(!evt||!evt.card) return; - var num1=get.number(card),num2=get.number(evt.card); - if(num1==='unsure'||typeof num1=='number'&&typeof num2=='number'&&num1%num2==0) return Infinity; + mod: { + cardUsable: function (card, player) { + if (typeof card == "object") { + var evt = lib.skill.dcjianying.getLastUsed(player); + if (!evt || !evt.card) return; + var num1 = get.number(card), + num2 = get.number(evt.card); + if ( + num1 === "unsure" || + (typeof num1 == "number" && typeof num2 == "number" && num1 % num2 == 0) + ) + return Infinity; } }, - aiOrder:function(player,card,num){ - if(typeof card=='object'){ - var evt=lib.skill.dcjianying.getLastUsed(player); - if(!evt||!evt.card) return; - var num1=get.number(card),num2=num2=get.number(evt.card); - if(num1==='unsure'||typeof num1=='number'&&typeof num2=='number'&&num2%num1==0) return num+5; + aiOrder: function (player, card, num) { + if (typeof card == "object") { + var evt = lib.skill.dcjianying.getLastUsed(player); + if (!evt || !evt.card) return; + var num1 = get.number(card), + num2 = (num2 = get.number(evt.card)); + if ( + num1 === "unsure" || + (typeof num1 == "number" && typeof num2 == "number" && num2 % num1 == 0) + ) + return num + 5; } }, }, - init:function(player){ - player.addSkill('xingtu_mark'); - var history=player.getAllHistory('useCard'); - if(history.length){ - var trigger=history[history.length-1],num=get.number(trigger.card); - player.storage.xingtu_mark=num; - player[typeof num!='number'?'unmarkSkill':'markSkill']('xingtu_mark'); + init: function (player) { + player.addSkill("xingtu_mark"); + var history = player.getAllHistory("useCard"); + if (history.length) { + var trigger = history[history.length - 1], + num = get.number(trigger.card); + player.storage.xingtu_mark = num; + player[typeof num != "number" ? "unmarkSkill" : "markSkill"]("xingtu_mark"); } }, - onremove:function(player){ - player.removeSkill('xingtu_mark'); - player.removeGaintag('xingtu1'); - player.removeGaintag('xingtu2'); + onremove: function (player) { + player.removeSkill("xingtu_mark"); + player.removeGaintag("xingtu1"); + player.removeGaintag("xingtu2"); delete player.storage.xingtu_mark; }, - subSkill:{ - mark:{ - charlotte:true, - trigger:{ - player:['useCard1','gainAfter'], - global:'loseAsyncAfter', + subSkill: { + mark: { + charlotte: true, + trigger: { + player: ["useCard1", "gainAfter"], + global: "loseAsyncAfter", }, - filter:function(event,player,name){ - if(!player.countCards('h')) return false; - return name=='useCard1'||event.getg(player).length; + filter: function (event, player, name) { + if (!player.countCards("h")) return false; + return name == "useCard1" || event.getg(player).length; }, - direct:true, - firstDo:true, - content:function(){ - 'step 0' - player.removeGaintag('xingtu1'); - player.removeGaintag('xingtu2'); - if(event.triggername=='useCard1'){ - var num=get.number(trigger.card,player); - player.storage.xingtu_mark=num; - player[typeof num!='number'?'unmarkSkill':'markSkill']('xingtu_mark'); - if(typeof num!='number') event.finish(); + direct: true, + firstDo: true, + content: function () { + "step 0"; + player.removeGaintag("xingtu1"); + player.removeGaintag("xingtu2"); + if (event.triggername == "useCard1") { + var num = get.number(trigger.card, player); + player.storage.xingtu_mark = num; + player[typeof num != "number" ? "unmarkSkill" : "markSkill"]("xingtu_mark"); + if (typeof num != "number") event.finish(); } - 'step 1' - var cards1=[],cards2=[],num=player.storage.xingtu_mark; - player.getCards('h').forEach(card=>{ - var numx=get.number(card,player); - if(typeof numx=='number'){ - if(numx%num==0) cards1.push(card); - if(num%numx==0) cards2.push(card); + "step 1"; + var cards1 = [], + cards2 = [], + num = player.storage.xingtu_mark; + player.getCards("h").forEach((card) => { + var numx = get.number(card, player); + if (typeof numx == "number") { + if (numx % num == 0) cards1.push(card); + if (num % numx == 0) cards2.push(card); } }); - player.addGaintag(cards1,'xingtu1'); - player.addGaintag(cards2,'xingtu2'); + player.addGaintag(cards1, "xingtu1"); + player.addGaintag(cards2, "xingtu2"); }, - intro:{content:'上一张牌的点数:#'}, + intro: { content: "上一张牌的点数:#" }, }, }, }, - juezhi:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he')>1; + juezhi: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") > 1; }, - filterCard:true, - position:'he', - selectCard:[2,Infinity], - check:function(card){ - if(ui.selected.cards.length>1) return 0; - var player=_status.event.player; - if(player.hasSkill('xingtu')&&player.storage.xingtu){ - var cards=player.getCards('he'); - var num=player.storage.xingtu,stop=false; - for(var i=0;i<=cards.length;i++){ - if(i!=cards.length){ - var num1=get.number(cards[i],player); - if(typeof num1!='number') continue; - for(var j=0;j 1) return 0; + var player = _status.event.player; + if (player.hasSkill("xingtu") && player.storage.xingtu) { + var cards = player.getCards("he"); + var num = player.storage.xingtu, + stop = false; + for (var i = 0; i <= cards.length; i++) { + if (i != cards.length) { + var num1 = get.number(cards[i], player); + if (typeof num1 != "number") continue; + for (var j = 0; j < cards.length; j++) { + if (i == j) continue; + var num2 = get.number(cards[j], player); + if (typeof num2 != "number") continue; + var sum = num1 + num2; + if (sum % num == 0 || num % sum == 0) { + stop = true; break; } } - if(stop) break; + if (stop) break; } } - if(i!=cards.length){ - var cardx=[cards[i],cards[j]]; - if(cardx.includes(card)) return 10-get.value(card); + if (i != cards.length) { + var cardx = [cards[i], cards[j]]; + if (cardx.includes(card)) return 10 - get.value(card); } } - return 5-get.value(card); + return 5 - get.value(card); }, - content:function(){ - var num=0; - for(var i of cards) num+=get.number(i,player); - num=num%13; - if(num==0) num=13; - var card=get.cardPile2(function(card){ - return get.number(card,false)==num; + content: function () { + var num = 0; + for (var i of cards) num += get.number(i, player); + num = num % 13; + if (num == 0) num = 13; + var card = get.cardPile2(function (card) { + return get.number(card, false) == num; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, }, - reganlu:{ - enable:'phaseUse', - usable:1, - audio:2, - selectTarget:2, - delay:0, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - if(ui.selected.targets.length==0) return true; - if(ui.selected.targets[0].countCards('e')==0&&target.countCards('e')==0) return false; - return target==player||ui.selected.targets[0]==player||Math.abs(ui.selected.targets[0].countCards('e')-target.countCards('e'))<=player.maxHp-player.hp; + reganlu: { + enable: "phaseUse", + usable: 1, + audio: 2, + selectTarget: 2, + delay: 0, + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + if (ui.selected.targets.length == 0) return true; + if (ui.selected.targets[0].countCards("e") == 0 && target.countCards("e") == 0) + return false; + return ( + target == player || + ui.selected.targets[0] == player || + Math.abs(ui.selected.targets[0].countCards("e") - target.countCards("e")) <= + player.maxHp - player.hp + ); }, - multitarget:true, - multiline:true, - content:function(){ + multitarget: true, + multiline: true, + content: function () { targets[0].swapEquip(targets[1]); }, - ai:{ - order:10, - threaten:function(player,target){ - return 0.8*Math.max(1+target.maxHp-target.hp); + ai: { + order: 10, + threaten: function (player, target) { + return 0.8 * Math.max(1 + target.maxHp - target.hp); }, - result:{ - target:function(player,target){ - var list1=[]; - var list2=[]; - var num=player.maxHp-player.hp; - var players=game.filterPlayer(); - for(var i=0;i0) list1.push(players[i]); - else if(get.attitude(player,players[i])<0) list2.push(players[i]); + result: { + target: function (player, target) { + var list1 = []; + var list2 = []; + var num = player.maxHp - player.hp; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) list1.push(players[i]); + else if (get.attitude(player, players[i]) < 0) list2.push(players[i]); } - list1.sort(function(a,b){ - return a.countCards('e')-b.countCards('e'); + list1.sort(function (a, b) { + return a.countCards("e") - b.countCards("e"); }); - list2.sort(function(a,b){ - return b.countCards('e')-a.countCards('e'); + list2.sort(function (a, b) { + return b.countCards("e") - a.countCards("e"); }); var delta; - for(var i=0;i0; + mobilexingxue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return (player.storage.mobileyanzhu ? player.maxHp : player.hp) > 0; }, - direct:true, - content:function(){ - 'step 0' - var num=player.storage.mobileyanzhu?player.maxHp:player.hp; - player.chooseTarget([1,num],get.prompt2('mobilexingxue')).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countCards('he')) return att; - return att/10; + direct: true, + content: function () { + "step 0"; + var num = player.storage.mobileyanzhu ? player.maxHp : player.hp; + player.chooseTarget([1, num], get.prompt2("mobilexingxue")).set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.countCards("he")) return att; + return att / 10; }); - 'step 1' - if(result.bool){ - player.logSkill('mobilexingxue',result.targets); - event.targets=result.targets; - event.targets2=event.targets.slice(0); + "step 1"; + if (result.bool) { + player.logSkill("mobilexingxue", result.targets); + event.targets = result.targets; + event.targets2 = event.targets.slice(0); event.targets.sort(lib.sort.seat); - } - else{ + } else { event.finish(); } - 'step 2' - if(event.targets.length){ - var target=event.targets.shift(); + "step 2"; + if (event.targets.length) { + var target = event.targets.shift(); target.draw(); - event.current=target; - } - else{ + event.current = target; + } else { event.finish(); } - 'step 3' - if(event.current&&event.current.countCards('he')){ - if(!player.storage.mobileyanzhu||event.targets2.length==1) event.current.chooseCard('选择一张牌置于牌堆顶','he',true); - else event.current.chooseCardTarget({ - prompt:'将一张牌置于牌堆顶,或交给其他目标角色', - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ - return target!=player&&_status.event.getParent().targets2.includes(target); - }, - forced:true, - selectTarget:[0,1], - ai1:(card)=>6-get.value(card), - ai2:(target)=>get.attitude(_status.event.player,target), - }); - } - else{ + "step 3"; + if (event.current && event.current.countCards("he")) { + if (!player.storage.mobileyanzhu || event.targets2.length == 1) + event.current.chooseCard("选择一张牌置于牌堆顶", "he", true); + else + event.current.chooseCardTarget({ + prompt: "将一张牌置于牌堆顶,或交给其他目标角色", + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { + return ( + target != player && + _status.event.getParent().targets2.includes(target) + ); + }, + forced: true, + selectTarget: [0, 1], + ai1: (card) => 6 - get.value(card), + ai2: (target) => get.attitude(_status.event.player, target), + }); + } else { event.goto(2); } - 'step 4' - if(result&&result.cards){ - event.card=result.cards[0]; - if(!result.targets||!result.targets.length){ - event.current.lose(result.cards,ui.cardPile,'insert'); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },event.current); - } - else{ - event.current.give(result.cards,result.targets[0]); + "step 4"; + if (result && result.cards) { + event.card = result.cards[0]; + if (!result.targets || !result.targets.length) { + event.current.lose(result.cards, ui.cardPile, "insert"); + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, event.current); + } else { + event.current.give(result.cards, result.targets[0]); } + } else { + event.card = null; } - else{ - event.card=null; - } - 'step 5' + "step 5"; event.goto(2); }, - derivation:'mobilexingxuex', + derivation: "mobilexingxuex", }, - mobileyanzhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('hej')>0&&target!=player; + mobileyanzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("hej") > 0 && target != player; }, - content:function(){ - 'step 0' - if(target.countCards('e')){ - target.chooseBool('是否将装备区内的所有牌交给'+get.translation(player)+'?','若选择“取消”,则其将获得你区域里的一张牌').set('ai',function(){ - if(_status.event.effect>0) return false; - if(_status.event.player.countCards('e')>=3) return false; - return true; - }).set('effect',get.effect(target,{name:'shunshou'},player,target)); - } - else{ - player.gainPlayerCard(target,true,'he'); + content: function () { + "step 0"; + if (target.countCards("e")) { + target + .chooseBool( + "是否将装备区内的所有牌交给" + get.translation(player) + "?", + "若选择“取消”,则其将获得你区域里的一张牌" + ) + .set("ai", function () { + if (_status.event.effect > 0) return false; + if (_status.event.player.countCards("e") >= 3) return false; + return true; + }) + .set("effect", get.effect(target, { name: "shunshou" }, player, target)); + } else { + player.gainPlayerCard(target, true, "he"); event.finish(); } - 'step 1' - if(result.bool){ - var es=target.getCards('e'); - target.give(es,player,'give'); - player.removeSkills('mobileyanzhu'); - player.storage.mobileyanzhu=true; - player.popup('兴学'); - game.log(player,'修改了技能','#g【兴学】'); - } - else{ - player.gainPlayerCard(target,true,'hej'); + "step 1"; + if (result.bool) { + var es = target.getCards("e"); + target.give(es, player, "give"); + player.removeSkills("mobileyanzhu"); + player.storage.mobileyanzhu = true; + player.popup("兴学"); + game.log(player, "修改了技能", "#g【兴学】"); + } else { + player.gainPlayerCard(target, true, "hej"); } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - var ne=target.countCards('e'),nj=target.countCards('j'); - if(nj) return 2.5; - if(!ne) return -2; - if(ne>=2) return -ne; + ai: { + order: 6, + result: { + target: function (player, target) { + var ne = target.countCards("e"), + nj = target.countCards("j"); + if (nj) return 2.5; + if (!ne) return -2; + if (ne >= 2) return -ne; return 0; }, }, }, }, //毛玠 - bingqing:{ - audio:2, - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - var suit=get.suit(event.card); - if(!lib.suit.includes(suit)) return false; - var evt=event.getParent('phaseUse'); - if(!evt||player!=evt.player) return false; - var list=[],history=player.getHistory('useCard'); - if(history.length<2) return false; - for(var i of history){ - if(i.getParent('phaseUse')!=evt) continue; - var suit2=get.suit(i.card); - if(!lib.suit.includes(suit2)) continue; - if(i!=event&&suit2==suit) return false; - if(i.finished) list.add(suit2); + bingqing: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + var suit = get.suit(event.card); + if (!lib.suit.includes(suit)) return false; + var evt = event.getParent("phaseUse"); + if (!evt || player != evt.player) return false; + var list = [], + history = player.getHistory("useCard"); + if (history.length < 2) return false; + for (var i of history) { + if (i.getParent("phaseUse") != evt) continue; + var suit2 = get.suit(i.card); + if (!lib.suit.includes(suit2)) continue; + if (i != event && suit2 == suit) return false; + if (i.finished) list.add(suit2); } - return list.length>1&&list.length<5; + return list.length > 1 && list.length < 5; }, - content:function(){ - 'step 0' - var suit=get.suit(trigger.card); - var evt=event.getParent('phaseUse'); - var list=[],history=player.getHistory('useCard'); - for(var i of history){ - if(i.getParent('phaseUse')!=evt) continue; - var suit2=get.suit(i.card); - if(!lib.suit.includes(suit2)) continue; - if(i.finished) list.add(suit2); + content: function () { + "step 0"; + var suit = get.suit(trigger.card); + var evt = event.getParent("phaseUse"); + var list = [], + history = player.getHistory("useCard"); + for (var i of history) { + if (i.getParent("phaseUse") != evt) continue; + var suit2 = get.suit(i.card); + if (!lib.suit.includes(suit2)) continue; + if (i.finished) list.add(suit2); } - var prompt,filterTarget,ai; - switch(list.length){ + var prompt, filterTarget, ai; + switch (list.length) { case 2: - prompt='令一名角色摸两张牌'; - filterTarget=function(card,player,target){ + prompt = "令一名角色摸两张牌"; + filterTarget = function (card, player, target) { return true; }; - ai=function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(target.hasSkill('nogain')) att/=10; - return att/Math.sqrt(Math.min(5,1+target.countCards('h'))); - } + ai = function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (target.hasSkill("nogain")) att /= 10; + return att / Math.sqrt(Math.min(5, 1 + target.countCards("h"))); + }; break; case 3: - prompt='弃置一名角色区域内的一张牌'; - filterTarget=function(card,player,target){ - return target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'hej'); + prompt = "弃置一名角色区域内的一张牌"; + filterTarget = function (card, player, target) { + return target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "hej"); + }; + ai = function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy" }, player, player); }; - ai=function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy'},player,player); - } break; case 4: - prompt='对一名其他角色造成1点伤害'; - filterTarget=function(card,player,target){ - return target!=player; + prompt = "对一名其他角色造成1点伤害"; + filterTarget = function (card, player, target) { + return target != player; + }; + ai = function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); }; - ai=function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - } break; default: event.finish(); return; } - event.num=list.length; - player.chooseTarget(get.prompt('bingqing'),prompt,filterTarget).set('ai',ai); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('bingqing',target); - event.target=target; + event.num = list.length; + player.chooseTarget(get.prompt("bingqing"), prompt, filterTarget).set("ai", ai); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("bingqing", target); + event.target = target; event.goto(num); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; target.draw(2); event.finish(); - 'step 3' - player.discardPlayerCard(target,true,'hej'); + "step 3"; + player.discardPlayerCard(target, true, "hej"); event.finish(); - 'step 4' + "step 4"; target.damage(); }, }, - yingfeng:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yingfeng'),'令一名角色获得“奉”标记',function(card,player,target){ - return !target.hasSkill('yingfeng_mark'); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<=0) return 0; - var eff=0.1; - var preTarget=game.findPlayer(function(current){ - return (current!=target&¤t.hasSkill('yingfeng_mark')); + yingfeng: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("yingfeng"), + "令一名角色获得“奉”标记", + function (card, player, target) { + return !target.hasSkill("yingfeng_mark"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att <= 0) return 0; + var eff = 0.1; + var preTarget = game.findPlayer(function (current) { + return current != target && current.hasSkill("yingfeng_mark"); + }); + if (preTarget) { + if (get.attitude(player, preTarget) < 0) eff += 4; + else if ( + preTarget.hasValueTarget({ name: "sha" }, false) && + !preTarget.hasValueTarget({ name: "sha" }) + ) + eff -= 3; + } + if ( + target.hasValueTarget({ name: "sha" }, false) && + !target.hasValueTarget({ name: "sha" }) + ) + eff += 3; + if (player == target) att *= 1.2; + return 0.01 + att * eff; }); - if(preTarget){ - if(get.attitude(player,preTarget)<0) eff+=4; - else if(preTarget.hasValueTarget({name:'sha'},false)&&!preTarget.hasValueTarget({name:'sha'})) eff-=3; - } - if(target.hasValueTarget({name:'sha'},false)&&!target.hasValueTarget({name:'sha'})) eff+=3; - if(player==target) att*=1.2; - return 0.01+att*eff; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('yingfeng',target); - target.addAdditionalSkill('yingfeng_'+player.playerid,'yingfeng_mark'); - game.countPlayer(function(current){ - if(current!=target&¤t.hasSkill('yingfeng_mark')){ - current.removeSkill('yingfeng_mark'); - current.removeAdditionalSkill('yingfeng_'+player.playerid); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("yingfeng", target); + target.addAdditionalSkill("yingfeng_" + player.playerid, "yingfeng_mark"); + game.countPlayer(function (current) { + if (current != target && current.hasSkill("yingfeng_mark")) { + current.removeSkill("yingfeng_mark"); + current.removeAdditionalSkill("yingfeng_" + player.playerid); } }); } }, - subSkill:{ - mark:{ - charlotte:true, - mark:true, - marktext:'奉', - mod:{ - targetInRange:()=>true, + subSkill: { + mark: { + charlotte: true, + mark: true, + marktext: "奉", + mod: { + targetInRange: () => true, }, - intro:{content:'使用牌无距离限制'}, + intro: { content: "使用牌无距离限制" }, }, }, }, //猩黄忠 - spshidi:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - forced:true, - zhuanhuanji:'number', - filter:function(event,player){ - return (player.countMark('spshidi')%2)==['phaseJieshu','phaseZhunbei'].indexOf(event.name); + spshidi: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + forced: true, + zhuanhuanji: "number", + filter: function (event, player) { + return ( + player.countMark("spshidi") % 2 == ["phaseJieshu", "phaseZhunbei"].indexOf(event.name) + ); }, - content:function(){ - player.changeZhuanhuanji('spshidi'); + content: function () { + player.changeZhuanhuanji("spshidi"); }, - mod:{ - globalFrom:function(from,to,distance){ - if(from.countMark('spshidi')%2==0) return distance-1; + mod: { + globalFrom: function (from, to, distance) { + if (from.countMark("spshidi") % 2 == 0) return distance - 1; }, - globalTo:function(from,to,distance){ - if(to.countMark('spshidi')%2==1) return distance+1; + globalTo: function (from, to, distance) { + if (to.countMark("spshidi") % 2 == 1) return distance + 1; }, - aiOrder:function(player,card,num){ - if(player.countMark('spshidi')%2==0&&card.name=='sha'&&get.color(card)=='black') return num+0.1; + aiOrder: function (player, card, num) { + if ( + player.countMark("spshidi") % 2 == 0 && + card.name == "sha" && + get.color(card) == "black" + ) + return num + 0.1; }, }, - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - return '已转换过'+(storage||0)+'次'; + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + return "已转换过" + (storage || 0) + "次"; }, }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.target||(arg.card.name!='sha')) return false; - return player.countMark('spshidi')%2==0&&get.color(arg.card)=='black'; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.card || !arg.target || arg.card.name != "sha") return false; + return player.countMark("spshidi") % 2 == 0 && get.color(arg.card) == "black"; }, }, - group:['spshidi_use','spshidi_beused'], - subSkill:{ - use:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countMark('spshidi')%2==0&&get.color(event.card,false)=='black'; + group: ["spshidi_use", "spshidi_beused"], + subSkill: { + use: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.countMark("spshidi") % 2 == 0 && + get.color(event.card, false) == "black" + ); }, - content:function(){ + content: function () { trigger.directHit.addArray(game.players); }, }, - beused:{ - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countMark('spshidi')%2==1&&get.color(event.card,false)=='red'; + beused: { + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.countMark("spshidi") % 2 == 1 && + get.color(event.card, false) == "red" + ); }, - content:function(){ + content: function () { trigger.directHit.add(player); }, }, }, }, - spyishi:{ - audio:2, - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return player!=event.player&&event.player.countCards('e')>0; + spyishi: { + audio: 2, + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return player != event.player && event.player.countCards("e") > 0; }, - check:function(event,player){ - return get.damageEffect(event.player,player,player)<0||(!event.player.hasSkillTag('noe')&&event.player.hasCard(function(card){ - return get.value(card)>6; - },'e')) + check: function (event, player) { + return ( + get.damageEffect(event.player, player, player) < 0 || + (!event.player.hasSkillTag("noe") && + event.player.hasCard(function (card) { + return get.value(card) > 6; + }, "e")) + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.num--; - player.gainPlayerCard(trigger.player,'e',true); + player.gainPlayerCard(trigger.player, "e", true); }, }, - spqishe:{ - enable:'chooseToUse', - viewAs:{name:'jiu'}, - filterCard:{type:'equip'}, - position:'hes', - viewAsFilter:function(player){ - return player.hasCard({type:'equip'},'ehs'); + spqishe: { + enable: "chooseToUse", + viewAs: { name: "jiu" }, + filterCard: { type: "equip" }, + position: "hes", + viewAsFilter: function (player) { + return player.hasCard({ type: "equip" }, "ehs"); }, - check:function(card){ - if(_status.event.type=='dying') return 1/(get.value(card)||0.5); - return 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){ - return num+player.countCards('e'); + locked: false, + mod: { + maxHandcard: function (player, num) { + return num + player.countCards("e"); }, }, }, //虞翻 - rezongxuan:{ - inherit:'zongxuan', - group:'rezongxuan_place', + rezongxuan: { + inherit: "zongxuan", + group: "rezongxuan_place", }, - rezongxuan_place:{ - audio:'rezongxuan', - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' + rezongxuan_place: { + audio: "rezongxuan", + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; player.draw(); - 'step 1' - player.chooseCard('he',true,'将一张牌置于牌堆顶'); - 'step 2' - if(result&&result.cards){ - event.card=result.cards[0]; - player.lose(result.cards,ui.cardPile,'insert'); - game.log(player,'将',(get.position(event.card)=='h'?'一张牌':event.card),'置于牌堆顶'); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },player); - } - else event.finish(); + "step 1"; + player.chooseCard("he", true, "将一张牌置于牌堆顶"); + "step 2"; + if (result && result.cards) { + event.card = result.cards[0]; + player.lose(result.cards, ui.cardPile, "insert"); + game.log( + player, + "将", + get.position(event.card) == "h" ? "一张牌" : event.card, + "置于牌堆顶" + ); + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, player); + } else event.finish(); }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, }, //孙寒华 - chongxu:{ - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' + chongxu: { + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; player.chooseToPlayBeatmap(lib.skill.chongxu.beatmaps.randomGet()); - 'step 1' - var score=Math.floor(Math.min(5,result.accuracy/17)); - event.score=score; - game.log(player,'的演奏评级为','#y'+result.rank[0],',获得积分点数','#y'+score,'分'); - if(score<3){ - if(score>=2) player.draw(); + "step 1"; + var score = Math.floor(Math.min(5, result.accuracy / 17)); + event.score = score; + game.log( + player, + "的演奏评级为", + "#y" + result.rank[0], + ",获得积分点数", + "#y" + score, + "分" + ); + if (score < 3) { + if (score >= 2) player.draw(); event.finish(); return; } - var list=[]; - if(player.countMark('miaojian')<2&&player.hasSkill('miaojian')) list.push('修改【妙剑】'); - if(player.countMark('shhlianhua')<2&&player.hasSkill('shhlianhua')) list.push('修改【莲华】'); - if(list.length){ - list.push('全部摸牌'); - player.chooseControl(list).set('prompt','冲虚:修改技能'+(score==5?'并摸一张牌':'')+';或摸'+Math.floor(score/2)+'张牌'); + var list = []; + if (player.countMark("miaojian") < 2 && player.hasSkill("miaojian")) + list.push("修改【妙剑】"); + if (player.countMark("shhlianhua") < 2 && player.hasSkill("shhlianhua")) + list.push("修改【莲华】"); + if (list.length) { + list.push("全部摸牌"); + player + .chooseControl(list) + .set( + "prompt", + "冲虚:修改技能" + + (score == 5 ? "并摸一张牌" : "") + + ";或摸" + + Math.floor(score / 2) + + "张牌" + ); + } else event._result = { control: "全部摸牌" }; + "step 2"; + var score = event.score; + if (result.control != "全部摸牌") { + score -= 3; + var skill = result.control == "修改【妙剑】" ? "miaojian" : "shhlianhua"; + player.addMark(skill, 1, false); + game.log(player, "修改了技能", "#g【" + get.translation(skill) + "】"); } - else event._result={control:'全部摸牌'}; - 'step 2' - var score=event.score; - if(result.control!='全部摸牌'){ - score-=3; - var skill=result.control=='修改【妙剑】'?'miaojian':'shhlianhua'; - player.addMark(skill,1,false); - game.log(player,'修改了技能','#g【'+get.translation(skill)+'】'); - } - if(score>1) player.draw(Math.floor(score/2)); + if (score > 1) player.draw(Math.floor(score / 2)); }, - ai:{ - order:10, - result:{ - player:1, + ai: { + order: 10, + result: { + player: 1, }, }, - beatmaps:[ + beatmaps: [ { //歌曲名称 - name:'鳥の詩', + name: "鳥の詩", //歌曲文件名(默认在audio/effect文件夹下 若要重定向到扩展 请写为'ext:扩展名称/文件名'的格式) - filename:'tori_no_uta', + filename: "tori_no_uta", //每个音符的开始时间点(毫秒,相对未偏移的开始播放时间) - timeleap:[1047,3012,4978,5469,5961,6452,6698,7435,8909,10875,12840], + timeleap: [1047, 3012, 4978, 5469, 5961, 6452, 6698, 7435, 8909, 10875, 12840], //开始播放时间的偏移量(毫秒) - current:-110, + current: -110, //判定栏高度(相对整个对话框高度比例) - judgebar_height:0.16, + judgebar_height: 0.16, //Good/Great/Prefect的位置判定范围(百分比,相对于整个对话框。以滑条的底部作为判定基准) - range1:[84,110], - range2:[90,104], - range3:[94,100], + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], //滑条每相对于整个对话框下落1%所需的时间(毫秒) - speed:25, + speed: 25, }, { - name:'竹取飛翔 ~ Lunatic Princess', - filename:'taketori_hishou', - timeleap:[1021,1490,1959,2896,3834,4537,4771,5709,6646,7585,8039,8494,9403,10291,11180,11832,12049,12920,13345,13771,14196], - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(rgba(250, 170, 190, 1), rgba(240, 160, 180, 1))', - judgebar_color:'linear-gradient(rgba(240, 120, 243, 1), rgba(245, 106, 230, 1))', + name: "竹取飛翔 ~ Lunatic Princess", + filename: "taketori_hishou", + timeleap: [ + 1021, 1490, 1959, 2896, 3834, 4537, 4771, 5709, 6646, 7585, 8039, 8494, 9403, + 10291, 11180, 11832, 12049, 12920, 13345, 13771, 14196, + ], + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(rgba(250, 170, 190, 1), rgba(240, 160, 180, 1))", + judgebar_color: "linear-gradient(rgba(240, 120, 243, 1), rgba(245, 106, 230, 1))", }, { - name:'ignotus', - filename:'ignotus', + name: "ignotus", + filename: "ignotus", //Number of tracks //轨道数量 - number_of_tracks:4, + number_of_tracks: 4, //Customize the track to generate for every note (0 is the first track) //自定义每个音符生成的轨道(0是第一个轨道) - mapping:[0,2,3,1,1,0,3,0,0,3,0,0,2,1,2], + mapping: [0, 2, 3, 1, 1, 0, 3, 0, 0, 3, 0, 0, 2, 1, 2], //Convert from beats (0 is the first beat) to timeleap //将节拍(0是第一拍)转换为开始时间点 - timeleap:game.generateBeatmapTimeleap(170,[0,4,8,12,14,16,16.5,23.5,24,31,32,40,45,46,47]), - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(rgba(240, 250, 240, 1), rgba(230, 240, 230, 1))', - judgebar_color:'linear-gradient(rgba(161, 59, 150, 1), rgba(58, 43, 74, 1))', + timeleap: game.generateBeatmapTimeleap( + 170, + [0, 4, 8, 12, 14, 16, 16.5, 23.5, 24, 31, 32, 40, 45, 46, 47] + ), + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(rgba(240, 250, 240, 1), rgba(230, 240, 230, 1))", + judgebar_color: "linear-gradient(rgba(161, 59, 150, 1), rgba(58, 43, 74, 1))", }, { - name:'Super Mario 3D World Theme', - filename:'sm3dw_overworld', + name: "Super Mario 3D World Theme", + filename: "sm3dw_overworld", //Random (Randomly choose tracks to generate notes each play) //随机(每次演奏时音符会随机选择轨道生成) - mapping:'random', - timeleap:[0,1071,1518,2054,4018,4286,5357,6429,7500,8571,9643,10714,11786,12321,12589,12857,13929,15000,16071,17143,18214,18482,18750,19018,19286,20357], - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(rgba(120, 130, 240, 1), rgba(100, 100, 230, 1))', - judgebar_color:'linear-gradient(rgba(230, 40, 30, 1), rgba(220, 30, 10, 1))', + mapping: "random", + timeleap: [ + 0, 1071, 1518, 2054, 4018, 4286, 5357, 6429, 7500, 8571, 9643, 10714, 11786, + 12321, 12589, 12857, 13929, 15000, 16071, 17143, 18214, 18482, 18750, 19018, + 19286, 20357, + ], + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(rgba(120, 130, 240, 1), rgba(100, 100, 230, 1))", + judgebar_color: "linear-gradient(rgba(230, 40, 30, 1), rgba(220, 30, 10, 1))", }, { - name:'只因你太美', - filename:'chicken_you_are_so_beautiful', - number_of_tracks:7, - mapping:[3,6,4,5,6,2,3,2,1,2,0,4,3,6,5,4,3,6,3,2,3,1,0,1,2,3,4,5,6], - timeleap:game.generateBeatmapTimeleap(107,[2,3.5,4.5,5.5,6.5,8.5,10,11.5,12.5,13.5,14.5,15.5,18,19.5,20.5,21.5,22.5,24.5,26,27.5,28.5,29.5,30.5,31,31.5,32,32.5,33,33.5]), + name: "只因你太美", + filename: "chicken_you_are_so_beautiful", + number_of_tracks: 7, + mapping: [ + 3, 6, 4, 5, 6, 2, 3, 2, 1, 2, 0, 4, 3, 6, 5, 4, 3, 6, 3, 2, 3, 1, 0, 1, 2, 3, 4, + 5, 6, + ], + timeleap: game.generateBeatmapTimeleap( + 107, + [ + 2, 3.5, 4.5, 5.5, 6.5, 8.5, 10, 11.5, 12.5, 13.5, 14.5, 15.5, 18, 19.5, 20.5, + 21.5, 22.5, 24.5, 26, 27.5, 28.5, 29.5, 30.5, 31, 31.5, 32, 32.5, 33, 33.5, + ] + ), //Hitsound file name (By default in the audio/effect folder. To redirect to the extension, please write in the format of 'ext:extension_name') //打击音文件名(默认在audio/effect文件夹下 若要重定向到扩展 请写为'ext:扩展名称'的格式) - hitsound:'chickun.wav', - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(#99f, #66c)', - judgebar_color:'linear-gradient(#ccf, #99c)', + hitsound: "chickun.wav", + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(#99f, #66c)", + judgebar_color: "linear-gradient(#ccf, #99c)", }, { - name:'Croatian Rhapsody', - filename:'croatian_rhapsody', - mapping:[4,1,2,1,0,0,4,5,1,3,2,1,0,0], - timeleap:game.generateBeatmapTimeleap(96,[4,6,8,9,10,11,12,13.5,14,15.5,16,17,18,19]), - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(#fff, #ccc)', - judgebar_color:'linear-gradient(#fff, #ccc)', + name: "Croatian Rhapsody", + filename: "croatian_rhapsody", + mapping: [4, 1, 2, 1, 0, 0, 4, 5, 1, 3, 2, 1, 0, 0], + timeleap: game.generateBeatmapTimeleap( + 96, + [4, 6, 8, 9, 10, 11, 12, 13.5, 14, 15.5, 16, 17, 18, 19] + ), + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(#fff, #ccc)", + judgebar_color: "linear-gradient(#fff, #ccc)", }, { - name:'罗刹海市', - filename:'rakshasa_sea_city', - number_of_tracks:7, - mapping:'random', - timeleap:game.generateBeatmapTimeleap(150,[0,2,4,6,7,9,11,13,14,16,18,20,21,23,25,27]), - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(#333, #000)', - judgebar_color:'linear-gradient(#c66, #933)', + name: "罗刹海市", + filename: "rakshasa_sea_city", + number_of_tracks: 7, + mapping: "random", + timeleap: game.generateBeatmapTimeleap( + 150, + [0, 2, 4, 6, 7, 9, 11, 13, 14, 16, 18, 20, 21, 23, 25, 27] + ), + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(#333, #000)", + judgebar_color: "linear-gradient(#c66, #933)", }, { - name:'Pigstep (Stereo Mix)', - filename:'pigstep', - number_of_tracks:16, - timeleap:game.generateBeatmapTimeleap(170,[3,4,6,6.5,7.5,11,12,14,14.5,15.5,19,20,22,22.5,23.5,27,28,30,30.5,31.5,35,36,38,38.5,39.5,43,44,46,46.5,47.5,51,52,54,54.5,55.5,59,60,62,62.5]), - current:-110, - judgebar_height:0.16, - range1:[84,110], - range2:[90,104], - range3:[94,100], - speed:25, - node_color:'linear-gradient(#066, #033)', - judgebar_color:'linear-gradient(#633, #300)', + name: "Pigstep (Stereo Mix)", + filename: "pigstep", + number_of_tracks: 16, + timeleap: game.generateBeatmapTimeleap( + 170, + [ + 3, 4, 6, 6.5, 7.5, 11, 12, 14, 14.5, 15.5, 19, 20, 22, 22.5, 23.5, 27, 28, 30, + 30.5, 31.5, 35, 36, 38, 38.5, 39.5, 43, 44, 46, 46.5, 47.5, 51, 52, 54, 54.5, + 55.5, 59, 60, 62, 62.5, + ] + ), + current: -110, + judgebar_height: 0.16, + range1: [84, 110], + range2: [90, 104], + range3: [94, 100], + speed: 25, + node_color: "linear-gradient(#066, #033)", + judgebar_color: "linear-gradient(#633, #300)", }, ], - derivation:'chongxu_faq', + derivation: "chongxu_faq", }, - miaojian:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var level=player.countMark('miaojian'); - if(event.filterCard({name:'sha',nature:'stab'},player,event)){ - if(level==2) return true; - if(level==1&&player.hasCard(function(card){ - return get.type2(card)=='basic'; - },'hs')) return true; - if(level==0&&player.hasCard(function(card){ - return get.name(card)=='sha'; - },'hs')) return true; + miaojian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var level = player.countMark("miaojian"); + if (event.filterCard({ name: "sha", nature: "stab" }, player, event)) { + if (level == 2) return true; + if ( + level == 1 && + player.hasCard(function (card) { + return get.type2(card) == "basic"; + }, "hs") + ) + return true; + if ( + level == 0 && + player.hasCard(function (card) { + return get.name(card) == "sha"; + }, "hs") + ) + return true; } - if(event.filterCard({name:'wuzhong'},player,event)){ - if(level==2) return true; - if(level==1&&player.hasCard(function(card){ - return get.type2(card)!='basic'; - },'hes')) return true; - if(level==0&&player.hasCard(function(card){ - return get.type2(card)=='trick'; - },'hs')) return true; + if (event.filterCard({ name: "wuzhong" }, player, event)) { + if (level == 2) return true; + if ( + level == 1 && + player.hasCard(function (card) { + return get.type2(card) != "basic"; + }, "hes") + ) + return true; + if ( + level == 0 && + player.hasCard(function (card) { + return get.type2(card) == "trick"; + }, "hs") + ) + return true; } return false; }, - chooseButton:{ - dialog:function(){ - return ui.create.dialog('妙剑',[[ - ['基本','','sha','stab'], - ['锦囊','','wuzhong'], - ],'vcard']); + chooseButton: { + dialog: function () { + return ui.create.dialog("妙剑", [ + [ + ["基本", "", "sha", "stab"], + ["锦囊", "", "wuzhong"], + ], + "vcard", + ]); }, - filter:function(button,player){ - var event=_status.event.getParent(),level=player.countMark('miaojian'); - if(button.link[2]=='sha'){ - if(!event.filterCard({name:'sha',nature:'stab'},player,event)) return false; - if(level==2) return true; - if(level==1) return player.hasCard(function(card){ - return get.type2(card)=='basic'; - },'hs'); - return level==0&&player.hasCard(function(card){ - return get.name(card)=='sha'; - },'hs'); + filter: function (button, player) { + var event = _status.event.getParent(), + level = player.countMark("miaojian"); + if (button.link[2] == "sha") { + if (!event.filterCard({ name: "sha", nature: "stab" }, player, event)) + return false; + if (level == 2) return true; + if (level == 1) + return player.hasCard(function (card) { + return get.type2(card) == "basic"; + }, "hs"); + return ( + level == 0 && + player.hasCard(function (card) { + return get.name(card) == "sha"; + }, "hs") + ); } - if(button.link[2]=='wuzhong'){ - if(!event.filterCard({name:'wuzhong'},player,event)) return false; - if(level==2) return true; - if(level==1) return player.hasCard(function(card){ - return get.type2(card)!='basic'; - },'hes'); - return level==0&&player.hasCard(function(card){ - return get.type2(card)=='trick'; - },'hs'); + if (button.link[2] == "wuzhong") { + if (!event.filterCard({ name: "wuzhong" }, player, event)) return false; + if (level == 2) return true; + if (level == 1) + return player.hasCard(function (card) { + return get.type2(card) != "basic"; + }, "hes"); + return ( + level == 0 && + player.hasCard(function (card) { + return get.type2(card) == "trick"; + }, "hs") + ); } }, - check:function(button){ - var card={name:button.link[2],nature:button.link[3]},player=_status.event.player; - return get.value(card,player)*get.sgn(player.getUseValue(card)); + check: function (button) { + var card = { name: button.link[2], nature: button.link[3] }, + player = _status.event.player; + return get.value(card, player) * get.sgn(player.getUseValue(card)); }, - backup:function(links,player){ - var index=(links[0][2]=='sha'?0:1),level=player.countMark('miaojian'); - var next={ - audio:'miaojian', - filterCard:[[ - function(card){ - return get.name(card)=='sha'; - }, - function(card){ - return get.type(card)=='basic'; - }, - ()=>false, - ],[ - function(card){ - return get.type2(card)=='trick'; - }, - function(card){ - return get.type(card)!='basic'; - }, - ()=>false, - ]][index][level], - position:'hes', - check:function(card){ - if(card) return 6.5-get.value(card); + backup: function (links, player) { + var index = links[0][2] == "sha" ? 0 : 1, + level = player.countMark("miaojian"); + var next = { + audio: "miaojian", + filterCard: [ + [ + function (card) { + return get.name(card) == "sha"; + }, + function (card) { + return get.type(card) == "basic"; + }, + () => false, + ], + [ + function (card) { + return get.type2(card) == "trick"; + }, + function (card) { + return get.type(card) != "basic"; + }, + () => false, + ], + ][index][level], + position: "hes", + check: function (card) { + if (card) return 6.5 - get.value(card); return 1; }, - viewAs:[{ - name:'sha', - nature:'stab', - },{ - name:'wuzhong', - }][index], - } - if(level==2){ - next.selectCard=-1; - next.viewAs.isCard=true; + viewAs: [ + { + name: "sha", + nature: "stab", + }, + { + name: "wuzhong", + }, + ][index], + }; + if (level == 2) { + next.selectCard = -1; + next.viewAs.isCard = true; } return next; }, - prompt:function(links,player){ - var index=(links[0][2]=='sha'?0:1),level=player.countMark('miaojian'); - return [[ - '将一张【杀】当做刺【杀】使用', - '将一张基本牌当做刺【杀】使用', - '请选择刺【杀】的目标', - ],[ - '将一张锦囊牌当做【无中生有】使用', - '将一张非基本牌当做【无中生有】使用', - '请选择【无中生有】的目标', - ]][index][level]; + prompt: function (links, player) { + var index = links[0][2] == "sha" ? 0 : 1, + level = player.countMark("miaojian"); + return [ + [ + "将一张【杀】当做刺【杀】使用", + "将一张基本牌当做刺【杀】使用", + "请选择刺【杀】的目标", + ], + [ + "将一张锦囊牌当做【无中生有】使用", + "将一张非基本牌当做【无中生有】使用", + "请选择【无中生有】的目标", + ], + ][index][level]; }, }, - onremove:true, - derivation:['miaojian1','miaojian2'], - subSkill:{backup:{audio:'miaojian'}}, - ai:{ - order:7, - result:{player:1}, + onremove: true, + derivation: ["miaojian1", "miaojian2"], + subSkill: { backup: { audio: "miaojian" } }, + ai: { + order: 7, + result: { player: 1 }, }, }, - shhlianhua:{ - audio:2, - derivation:['shhlianhua1','shhlianhua2'], - trigger:{target:'useCardToTargeted'}, - forced:true, - locked:false, - filter:(event)=>event.card.name=='sha', - content:function(){ - 'step 0' + shhlianhua: { + audio: 2, + derivation: ["shhlianhua1", "shhlianhua2"], + trigger: { target: "useCardToTargeted" }, + forced: true, + locked: false, + filter: (event) => event.card.name == "sha", + content: function () { + "step 0"; player.draw(); - var level=player.countMark('shhlianhua'); - if(!level) event.finish(); - else if(level==2) event.goto(2); - else player.judge(function(result){ - return get.suit(result)=='spade'?1:-1; - }).set('judge2',(result)=>result.bool); - 'step 1' - if(result.bool) trigger.excluded.add(player); + var level = player.countMark("shhlianhua"); + if (!level) event.finish(); + else if (level == 2) event.goto(2); + else + player + .judge(function (result) { + return get.suit(result) == "spade" ? 1 : -1; + }) + .set("judge2", (result) => result.bool); + "step 1"; + if (result.bool) trigger.excluded.add(player); event.finish(); - 'step 2' - var eff=get.effect(player,trigger.card,trigger.player,trigger.player); - trigger.player.chooseToDiscard('he','弃置一张牌,或令'+get.translation(trigger.card)+'对'+get.translation(player)+'无效').set('ai',function(card){ - if(_status.event.eff>0){ - return 10-get.value(card); - } - return 0; - }).set('eff',eff); - 'step 3' - if(result.bool==false){ + "step 2"; + var eff = get.effect(player, trigger.card, trigger.player, trigger.player); + trigger.player + .chooseToDiscard( + "he", + "弃置一张牌,或令" + + get.translation(trigger.card) + + "对" + + get.translation(player) + + "无效" + ) + .set("ai", function (card) { + if (_status.event.eff > 0) { + return 10 - get.value(card); + } + return 0; + }) + .set("eff", eff); + "step 3"; + if (result.bool == false) { trigger.getParent().excluded.add(player); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&¤t<0) return 0.7; - } + ai: { + effect: { + target: function (card, player, target, current) { + if (card.name == "sha" && current < 0) return 0.7; + }, }, }, }, //阎圃 - huantu:{ - audio:2, - trigger:{global:'phaseDrawBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0&&!player.hasSkill('huantu_round')&&player.inRange(event.player); + huantu: { + audio: 2, + trigger: { global: "phaseDrawBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + !player.hasSkill("huantu_round") && + player.inRange(event.player) + ); }, - checkx:function(event,player){ - var target=event.player; - return get.attitude(player,target)>0&&(target.hasSkill('pingkou')||target.skipList.includes('phaseUse')||target.isDamaged()&&target.hp<=2||target.needsToDiscard()); + checkx: function (event, player) { + var target = event.player; + return ( + get.attitude(player, target) > 0 && + (target.hasSkill("pingkou") || + target.skipList.includes("phaseUse") || + (target.isDamaged() && target.hp <= 2) || + target.needsToDiscard()) + ); }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt('huantu',trigger.player),'交给其一张牌并令其暂时跳过摸牌阶段','he').set('ai',function(card){ - if(!_status.event.checkx) return 0; - return 1+Math.random(); - }).set('checkx',lib.skill.huantu.checkx(trigger,player)); - 'step 1' - if(result.bool){ - player.addTempSkill('huantu_round','roundStart'); - player.logSkill('huantu',trigger.player); - player.give(result.cards,trigger.player); + content: function () { + "step 0"; + player + .chooseCard( + get.prompt("huantu", trigger.player), + "交给其一张牌并令其暂时跳过摸牌阶段", + "he" + ) + .set("ai", function (card) { + if (!_status.event.checkx) return 0; + return 1 + Math.random(); + }) + .set("checkx", lib.skill.huantu.checkx(trigger, player)); + "step 1"; + if (result.bool) { + player.addTempSkill("huantu_round", "roundStart"); + player.logSkill("huantu", trigger.player); + player.give(result.cards, trigger.player); trigger.cancel(); - player.addTempSkill('huantu_effect'); + player.addTempSkill("huantu_effect"); } }, - subSkill:{ - round:{ - charlotte:true, - mark:true, - intro:{content:'本轮已发动'}, + subSkill: { + round: { + charlotte: true, + mark: true, + intro: { content: "本轮已发动" }, }, - effect:{ - audio:'huantu', - trigger:{global:'phaseJieshuBegin'}, - forced:true, - charlotte:true, - logTarget:'player', - filter:function(event,player){ + effect: { + audio: "huantu", + trigger: { global: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + logTarget: "player", + filter: function (event, player) { return event.player.isIn(); }, - content:function(){ - 'step 0' - var str=get.translation(trigger.player); - player.chooseControl().set('choiceList',[ - '令'+str+'回复1点体力并摸两张牌', - '摸三张牌,然后交给'+str+'两张手牌', - ]).set('choice',trigger.player.isDamaged()?0:1); - 'step 1' - if(result.index==0){ + content: function () { + "step 0"; + var str = get.translation(trigger.player); + player + .chooseControl() + .set("choiceList", [ + "令" + str + "回复1点体力并摸两张牌", + "摸三张牌,然后交给" + str + "两张手牌", + ]) + .set("choice", trigger.player.isDamaged() ? 0 : 1); + "step 1"; + if (result.index == 0) { trigger.player.recover(); trigger.player.draw(2); event.finish(); - } - else{ - event.target=trigger.player; + } else { + event.target = trigger.player; player.draw(3); } - 'step 2' - var hs=player.getCards('h'); - if(hs.length&&target.isIn()&&player.isIn()){ - if(hs.length<=2) event._result={bool:true,cards:hs}; - else player.chooseCard('h',2,true,'交给'+get.translation(target)+'两张手牌'); - } - else event.finish(); - 'step 3' - if(result.bool) player.give(result.cards,trigger.player); + "step 2"; + var hs = player.getCards("h"); + if (hs.length && target.isIn() && player.isIn()) { + if (hs.length <= 2) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "h", + 2, + true, + "交给" + get.translation(target) + "两张手牌" + ); + } else event.finish(); + "step 3"; + if (result.bool) player.give(result.cards, trigger.player); }, }, }, }, - bihuo:{ - trigger:{global:'dyingAfter'}, - logTarget:'player', - limited:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ + bihuo: { + trigger: { global: "dyingAfter" }, + logTarget: "player", + limited: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { return event.player.isIn(); }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - player.awakenSkill('bihuo'); + content: function () { + player.awakenSkill("bihuo"); trigger.player.draw(3); - trigger.player.addTempSkill('bihuo_effect','roundStart'); - trigger.player.addMark('bihuo_effect',game.countPlayer(),false); + trigger.player.addTempSkill("bihuo_effect", "roundStart"); + trigger.player.addMark("bihuo_effect", game.countPlayer(), false); }, - subSkill:{ - effect:{ - onremove:true, - charlotte:true, - mod:{ - globalTo:function(from,to,distance){ - return distance+to.countMark('bihuo_effect'); + subSkill: { + effect: { + onremove: true, + charlotte: true, + mod: { + globalTo: function (from, to, distance) { + return distance + to.countMark("bihuo_effect"); }, }, - intro:{content:'其他角色至你的距离+#'}, + intro: { content: "其他角色至你的距离+#" }, }, }, }, //马元义 - jibing:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - return player.getExpansions('jibing').length>0&&(event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)||event.filterCard(get.autoViewAs({name:'shan'},'unsure'),player,event)); + jibing: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filter: function (event, player) { + return ( + player.getExpansions("jibing").length > 0 && + (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) || + event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) + ); }, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('集兵','hidden'); - if(event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)&&event.filterCard(get.autoViewAs({name:'shan'},'unsure'),player,event)){ - dialog._chooseButton=2; - var list=['sha','shan']; - dialog.add([list.map(i=>{ - return [i,get.translation(i)]; - }),'tdnodes']); - } - else dialog._cardName=event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)?'sha':'shan'; - dialog.add(player.getExpansions('jibing')); + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("集兵", "hidden"); + if ( + event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) && + event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event) + ) { + dialog._chooseButton = 2; + var list = ["sha", "shan"]; + dialog.add([ + list.map((i) => { + return [i, get.translation(i)]; + }), + "tdnodes", + ]); + } else + dialog._cardName = event.filterCard( + get.autoViewAs({ name: "sha" }, "unsure"), + player, + event + ) + ? "sha" + : "shan"; + dialog.add(player.getExpansions("jibing")); return dialog; }, - filter:function(button){ - var evt=_status.event,player=_status.event.player; - if(evt.dialog){ - if(!evt.dialog._chooseButton){ - var evt2=_status.event.getParent(); - return evt2.filterCard(get.autoViewAs({name:evt.dialog._cardName},[button.link]),player,evt2); + filter: function (button) { + var evt = _status.event, + player = _status.event.player; + if (evt.dialog) { + if (!evt.dialog._chooseButton) { + var evt2 = _status.event.getParent(); + return evt2.filterCard( + get.autoViewAs({ name: evt.dialog._cardName }, [button.link]), + player, + evt2 + ); } - if(ui.selected.buttons.length){ - var str=ui.selected.buttons[0].link; - if(typeof str!='string'||typeof button.link=='string') return false; - var evt2=_status.event.getParent(); - return evt2.filterCard(get.autoViewAs({name:str},[button.link]),player,evt2); + if (ui.selected.buttons.length) { + var str = ui.selected.buttons[0].link; + if (typeof str != "string" || typeof button.link == "string") return false; + var evt2 = _status.event.getParent(); + return evt2.filterCard( + get.autoViewAs({ name: str }, [button.link]), + player, + evt2 + ); } - return typeof button.link=='string'; + return typeof button.link == "string"; } return false; }, - select:function(){ - return _status.event.dialog?(_status.event.dialog._chooseButton||1):1; + select: function () { + return _status.event.dialog ? _status.event.dialog._chooseButton || 1 : 1; }, - backup:function(links,player){ - var card,name; - if(links.length==2){ - name=links[0]; - card=links[1]; - } - else{ - card=links[0]; - var event=_status.event; - name=event.filterCard(get.autoViewAs({name:'sha'},[card]),player,event)?'sha':'shan'; + backup: function (links, player) { + var card, name; + if (links.length == 2) { + name = links[0]; + card = links[1]; + } else { + card = links[0]; + var event = _status.event; + name = event.filterCard(get.autoViewAs({ name: "sha" }, [card]), player, event) + ? "sha" + : "shan"; } return { - audio:'jibing', - filterCard:function(card){ - return card==lib.skill.jibing_backup.card; + audio: "jibing", + filterCard: function (card) { + return card == lib.skill.jibing_backup.card; }, - selectCard:-1, - position:'x', - viewAs:{name:name}, - card:card, - } + selectCard: -1, + position: "x", + viewAs: { name: name }, + card: card, + }; }, - prompt:function(links,player){ - return '请选择【杀】的目标'; + prompt: function (links, player) { + return "请选择【杀】的目标"; }, }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - return player.getExpansions('jibing').length>0; + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + return player.getExpansions("jibing").length > 0; }, - order:function(item,player){ - if(player.hasSkill('binghuo')) return 6; - return 1 + order: function (item, player) { + if (player.hasSkill("binghuo")) return 6; + return 1; }, - result:{ - player:1, + result: { + player: 1, }, }, - group:'jibing_place', - subSkill:{ - place:{ - audio:'jibing', - trigger:{player:'phaseDrawBegin1'}, - prompt2:'摸牌阶段开始时,若你的“兵”数小于势力数,则你可以改为将牌堆顶的两张牌置于你的武将牌上,称为“兵”。', - filter:function(event,player){ - return !event.numFixed&&player.getExpansions('jibing').length0&&player.isMaxHp()){ - if(get.attitude(target,player)<=0){ - return [0,0,1,0.3]; + ai: { + combo: "jibing", + mingzhi: false, + effect: { + target: function (card, player, target, current) { + if ( + (get.tag(card, "respondShan") || get.tag(card, "respondSha")) && + target.getExpansions("jibing").length > 0 && + player.isMaxHp() + ) { + if (get.attitude(target, player) <= 0) { + return [0, 0, 1, 0.3]; } } }, }, - } - }, - moucuan:{ - audio:2, - derivation:'binghuo', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'metal', - filter:function(event,player){ - return player.getExpansions('jibing').length>=game.countGroup(); }, - content:function(){ - player.awakenSkill('moucuan'); + }, + moucuan: { + audio: 2, + derivation: "binghuo", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "metal", + filter: function (event, player) { + return player.getExpansions("jibing").length >= game.countGroup(); + }, + content: function () { + player.awakenSkill("moucuan"); player.loseMaxHp(); - player.addSkills('binghuo'); + player.addSkills("binghuo"); }, - ai:{combo:'jibing'}, + ai: { combo: "jibing" }, }, - binghuo:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.hasHistory('useCard',function(evt){ - return evt.skill=='jibing_backup'; - })||player.hasHistory('respond',function(evt){ - return evt.skill=='jibing_backup'; - }); + binghuo: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.hasHistory("useCard", function (evt) { + return evt.skill == "jibing_backup"; + }) || + player.hasHistory("respond", function (evt) { + return evt.skill == "jibing_backup"; + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('binghuo')).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("binghuo")).set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('binghuo',target); - target.judge(function(card){ - if(get.color(card)=='black') return -2; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("binghuo", target); + target.judge(function (card) { + if (get.color(card) == "black") return -2; return 0.1; - }).judge2=function(result){ - return result.bool===false?true:false; + }).judge2 = function (result) { + return result.bool === false ? true : false; }; - } - else event.finish(); - 'step 2' - if(result.bool==false) target.damage('thunder'); + } else event.finish(); + "step 2"; + if (result.bool == false) target.damage("thunder"); }, - ai:{combo:'jibing',expose:0.2}, + ai: { combo: "jibing", expose: 0.2 }, }, //司马孚 - xunde:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return event.player.isIn()&&get.distance(player,event.player)<=1; + xunde: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return event.player.isIn() && get.distance(player, event.player) <= 1; }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)>0&&(!event.source||get.attitude(player,event.source)<0); + logTarget: "player", + check: function (event, player) { + return ( + get.attitude(player, event.player) > 0 && + (!event.source || get.attitude(player, event.source) < 0) + ); }, - content:function(){ - 'step 0' - player.judge().set('callback',function(){ - if(event.judgeResult.number>5){ - var player=event.getParent(2)._trigger.player; - if(get.position(card,true)=='o') player.gain(card,'gain2'); + content: function () { + "step 0"; + player.judge().set("callback", function () { + if (event.judgeResult.number > 5) { + var player = event.getParent(2)._trigger.player; + if (get.position(card, true) == "o") player.gain(card, "gain2"); } }); - 'step 1' - if(result.number<7){ - var source=trigger.source; - if(source&&source.isIn()&&source.countCards('he')>0){ + "step 1"; + if (result.number < 7) { + var source = trigger.source; + if (source && source.isIn() && source.countCards("he") > 0) { player.line(source); - source.chooseToDiscard('he',true); + source.chooseToDiscard("he", true); } } }, }, - chenjie:{ - audio:2, - trigger:{global:'judge'}, - filter:function(event,player){ - var suit=get.suit(event.player.judging[0],event.player); - return player.countCards('hes',function(card){ - if(_status.connectMode&&get.position(card)!='e') return true; - return get.suit(card)==suit; - })>0; + chenjie: { + audio: 2, + trigger: { global: "judge" }, + filter: function (event, player) { + var suit = get.suit(event.player.judging[0], event.player); + return ( + player.countCards("hes", function (card) { + if (_status.connectMode && get.position(card) != "e") return true; + return get.suit(card) == suit; + }) > 0 + ); }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - var suit=get.suit(trigger.player.judging[0],trigger.player); - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('chenjie'),'hes',function(card){ - if(get.suit(card)!=_status.event.suit) return false; - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0.1; - if(attitude>0){ - return result+0.01; - } - else{ - return 0.01-result; - } - }).set('judging',trigger.player.judging[0]).set('suit',suit).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - event.card=result.cards[0]; - player.respond(result.cards,'highlight','chenjie','noOrdering'); - } - else{ + direct: true, + preHidden: true, + content: function () { + "step 0"; + var suit = get.suit(trigger.player.judging[0], trigger.player); + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("chenjie"), + "hes", + function (card) { + if (get.suit(card) != _status.event.suit) return false; + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0.1; + if (attitude > 0) { + return result + 0.01; + } else { + return 0.01 - result; + } + }) + .set("judging", trigger.player.judging[0]) + .set("suit", suit) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + event.card = result.cards[0]; + player.respond(result.cards, "highlight", "chenjie", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=card; + trigger.player.judging[0] = card; trigger.orderingCards.add(card); - game.log(trigger.player,'的判定牌改为',card); + game.log(trigger.player, "的判定牌改为", card); player.draw(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:0.1, - } - } + ai: { + rejudge: true, + tag: { + rejudge: 0.1, + }, + }, }, //傅佥 - jueyong:{ - audio:2, - trigger:{target:'useCardToTarget'}, - forced:true, - filter:function(event,player){ - return event.card.name!='jiu'&&event.card.name!='tao'&& - event.targets.length==1&&event.card.isCard&&event.cards.length==1&&event.getParent(2).name!='jueyong_timeout'&& - get.position(event.cards[0],true)=='o'&&event.card.name==event.cards[0].name&& - (!player.storage.jueyong||player.storage.jueyong[0].length=result1) return 'zerotarget'; + ai: { + reverseEquip: true, + effect: { + target: function (card, player, target, current) { + if ( + get.type(card) == "equip" && + !get.tag(card, "gifts") && + target.storage.jueyong && + target.storage.jueyong[1].length + ) { + var result1 = get.equipResult(player, target, card.name), + subtype = get.subtype(card); + for (var i of target.storage.jueyong[0]) { + if ( + get.subtype(i, false) == subtype && + get.equipResult(target, target, i.name) >= result1 + ) + return "zerotarget"; } } }, }, }, - group:'jueyong_timeout', - subSkill:{ - timeout:{ - audio:'jueyong', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.jueyong&&player.storage.jueyong[0].length>0;//=Math.max(1,player.getDamagedHp()); + group: "jueyong_timeout", + subSkill: { + timeout: { + audio: "jueyong", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.storage.jueyong && player.storage.jueyong[0].length > 0; //=Math.max(1,player.getDamagedHp()); }, - content:function(){ - var list=player.storage.jueyong,card=list[0].shift(),source=list[1].shift(); - if(player.getExpansions('jueyong').includes(card)){ - if(source&&source.isIn()&&source.canUse(card,player,false)) source.useCard(card,player,false); + content: function () { + var list = player.storage.jueyong, + card = list[0].shift(), + source = list[1].shift(); + if (player.getExpansions("jueyong").includes(card)) { + if (source && source.isIn() && source.canUse(card, player, false)) + source.useCard(card, player, false); else player.loseToDiscardpile(card); } - if(list[0].length) event.redo(); + if (list[0].length) event.redo(); }, }, }, }, - poxiang:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:(event,player)=>player.countCards('he')>0, - filterCard:true, - filterTarget:lib.filter.notMe, - position:'he', - discard:false, - lose:false, - delay:false, - check:function(card){ - var player=_status.event.player; - if(!player.storage.jueyong||!player.storage.jueyong[0].length||player.hp<=1&&!player.storage.jueyong[0].some(function(card){ - return get.tag(card,'damage')>0; - })||!player.storage.jueyong[0].some(function(card){ - return get.effect(player,card,player.storage.jueyong[1][player.storage.jueyong[0].indexOf(card)],player)<0; - })) return -1; - return 20-get.value(card); + poxiang: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: (event, player) => player.countCards("he") > 0, + filterCard: true, + filterTarget: lib.filter.notMe, + position: "he", + discard: false, + lose: false, + delay: false, + check: function (card) { + var player = _status.event.player; + if ( + !player.storage.jueyong || + !player.storage.jueyong[0].length || + (player.hp <= 1 && + !player.storage.jueyong[0].some(function (card) { + return get.tag(card, "damage") > 0; + })) || + !player.storage.jueyong[0].some(function (card) { + return ( + get.effect( + player, + card, + player.storage.jueyong[1][player.storage.jueyong[0].indexOf(card)], + player + ) < 0 + ); + }) + ) + return -1; + return 20 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target); - player.draw(3).gaintag=['poxiang']; - player.addTempSkill('poxiang_mark') - 'step 1' - var cards=player.getExpansions('jueyong'); - if(cards.length) player.loseToDiscardpile(cards); - player.unmarkSkill('jueyong'); + content: function () { + "step 0"; + player.give(cards, target); + player.draw(3).gaintag = ["poxiang"]; + player.addTempSkill("poxiang_mark"); + "step 1"; + var cards = player.getExpansions("jueyong"); + if (cards.length) player.loseToDiscardpile(cards); + player.unmarkSkill("jueyong"); player.loseHp(); - 'step 2' + "step 2"; //player.skip('phaseDiscard'); game.delayx(); }, - ai:{ - order:12, - result:{ - player:4, - target:1, + ai: { + order: 12, + result: { + player: 4, + target: 1, }, }, - subSkill:{ - mark:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('poxiang'); + subSkill: { + mark: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("poxiang"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('poxiang')){ + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("poxiang")) { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('poxiang')){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("poxiang")) { return false; } }, @@ -8028,1280 +9989,1553 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //曹真 - disordersidi:{audio:2}, - discretesidi:{ - audio:'disordersidi', - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - return get.type(event.card,false)!='delay'&&game.hasPlayer(function(current){ - return player!=current&&(!player.storage.discretesidi||!player.storage.discretesidi.includes(current)); - }); + disordersidi: { audio: 2 }, + discretesidi: { + audio: "disordersidi", + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + return ( + get.type(event.card, false) != "delay" && + game.hasPlayer(function (current) { + return ( + player != current && + (!player.storage.discretesidi || + !player.storage.discretesidi.includes(current)) + ); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('discretesidi'),'选择两名角色a,b建立二元序偶,或仅选择一名角色,建立二元序偶',[1,2],function(card,player,target){ - if(ui.selected.targets.length) return true; - return target!=player&&(!player.storage.discretesidi||!player.storage.discretesidi.includes(target)); - }).set('complexTarget',true).set('complexSelect',true).set('targetprompt',['第一元素','第二元素']).set('ai',function(target){ - var player=_status.event.player; - if(!ui.selected.targets.length){ - if(target.getEnemies().length==1) return 2+Math.random(); - return 1+Math.random(); - } - var targetx=ui.selected.targets[0]; - if(targetx.getEnemies().includes(target)&&targetx.inRange(target)) return Math.random()-0.5; - return 0; - }).animate=false; - 'step 1' - if(result.bool&&result.targets.length){ - var targets=result.targets; - player.logSkill('discretesidi',targets[0]); - if(targets.length==1) targets.push(targets[0]); - if(!player.storage.discretesidi) player.storage.discretesidi=[]; - if(!player.storage.discretesidi2) player.storage.discretesidi2=[]; + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("discretesidi"), + "选择两名角色a,b建立二元序偶,或仅选择一名角色,建立二元序偶", + [1, 2], + function (card, player, target) { + if (ui.selected.targets.length) return true; + return ( + target != player && + (!player.storage.discretesidi || + !player.storage.discretesidi.includes(target)) + ); + } + ) + .set("complexTarget", true) + .set("complexSelect", true) + .set("targetprompt", ["第一元素", "第二元素"]) + .set("ai", function (target) { + var player = _status.event.player; + if (!ui.selected.targets.length) { + if (target.getEnemies().length == 1) return 2 + Math.random(); + return 1 + Math.random(); + } + var targetx = ui.selected.targets[0]; + if (targetx.getEnemies().includes(target) && targetx.inRange(target)) + return Math.random() - 0.5; + return 0; + }).animate = false; + "step 1"; + if (result.bool && result.targets.length) { + var targets = result.targets; + player.logSkill("discretesidi", targets[0]); + if (targets.length == 1) targets.push(targets[0]); + if (!player.storage.discretesidi) player.storage.discretesidi = []; + if (!player.storage.discretesidi2) player.storage.discretesidi2 = []; player.storage.discretesidi.push(targets[0]); player.storage.discretesidi2.push(targets[1]); - player.markSkill('discretesidi'); + player.markSkill("discretesidi"); game.delayx(); } }, - intro:{ - content:function(storage,player){ - if((player==game.me||player.isUnderControl())&&!game.observe){ - var str='R={ '; - for(var i=0;i0&&get.effect(evt.target,evt.card,evt.player,player)<0) return 0; - return 1; - }); - 'step 1' - if(result.index==0){ + var target = trigger.player; + event.target = target; + player + .chooseControl("cancel2") + .set("choiceList", [ + "取消" + + get.translation(trigger.card) + + "的所有目标并对" + + get.translation(target) + + "造成1点伤害", + "摸两张牌", + ]) + .set("ai", function () { + var player = _status.event.player, + evt = _status.event.getTrigger(); + if ( + get.damageEffect(evt.player, player, player) > 0 && + get.effect(evt.target, evt.card, evt.player, player) < 0 + ) + return 0; + return 1; + }); + "step 1"; + if (result.index == 0) { trigger.cancel(); - trigger.targets.length=0; - trigger.getParent().triggeredTargets1.length=0; - if(!_status.dying.length) target.damage(); - } - else if(result.index==1) player.draw(2); + trigger.targets.length = 0; + trigger.getParent().triggeredTargets1.length = 0; + if (!_status.dying.length) target.damage(); + } else if (result.index == 1) player.draw(2); }, }, - } + }, }, //孙鲁班 - xinzenhui:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - if(event.targets.length!=1) return false; - var card=event.card; - if(card.name!='sha'&&(get.type(card,null,false)!='trick'||get.color(card,false)!='black')) return false; - if(!player.isPhaseUsing()||player.hasSkill('xinzenhui2')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t!=event.target&&lib.filter.targetEnabled2(card,player,current)&&lib.filter.targetInRange(card,player,current); + xinzenhui: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + if (event.targets.length != 1) return false; + var card = event.card; + if ( + card.name != "sha" && + (get.type(card, null, false) != "trick" || get.color(card, false) != "black") + ) + return false; + if (!player.isPhaseUsing() || player.hasSkill("xinzenhui2")) return false; + return game.hasPlayer(function (current) { + return ( + current != player && + current != event.target && + lib.filter.targetEnabled2(card, player, current) && + lib.filter.targetInRange(card, player, current) + ); }); }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('xinzenhui'),function(card,player,target){ - if(player==target) return false; - var evt=_status.event.getTrigger(); - return !evt.targets.includes(target)&&lib.filter.targetEnabled2(evt.card,player,target)&&lib.filter.targetInRange(evt.card,player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return Math.max((target.countGainableCards(player,'he')?get.effect(target,{name:'shunshou_copy2'},player,player):0),get.effect(target,trigger.card,player,player)); - }); - "step 1" - if(result.bool){ - player.addTempSkill('xinzenhui2','phaseUseAfter'); - var target=result.targets[0],str=get.translation(target); - event.target=target; - player.logSkill('xinzenhui',target); - if(!target.countGainableCards(player,'he')) event._result={index:0}; - else player.chooseControl().set('choiceList',[ - '令'+str+'也成为'+get.translation(trigger.card)+'的目标', - '获得'+str+'的一张牌,然后其成为'+get.translation(trigger.card)+'的使用者', - ]).set('ai',function(){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player,target=_status.event.getParent().target; - return (target.countGainableCards(player,'he')?get.effect(target,{name:'shunshou_copy2'},player,player):0)>get.effect(target,trigger.card,player,player)?1:0; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("xinzenhui"), function (card, player, target) { + if (player == target) return false; + var evt = _status.event.getTrigger(); + return ( + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); }) - } - else event.finish(); - "step 2" - if(result.index==1){ + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return Math.max( + target.countGainableCards(player, "he") + ? get.effect(target, { name: "shunshou_copy2" }, player, player) + : 0, + get.effect(target, trigger.card, player, player) + ); + }); + "step 1"; + if (result.bool) { + player.addTempSkill("xinzenhui2", "phaseUseAfter"); + var target = result.targets[0], + str = get.translation(target); + event.target = target; + player.logSkill("xinzenhui", target); + if (!target.countGainableCards(player, "he")) event._result = { index: 0 }; + else + player + .chooseControl() + .set("choiceList", [ + "令" + str + "也成为" + get.translation(trigger.card) + "的目标", + "获得" + + str + + "的一张牌,然后其成为" + + get.translation(trigger.card) + + "的使用者", + ]) + .set("ai", function () { + var trigger = _status.event.getTrigger(); + var player = _status.event.player, + target = _status.event.getParent().target; + return (target.countGainableCards(player, "he") + ? get.effect(target, { name: "shunshou_copy2" }, player, player) + : 0) > get.effect(target, trigger.card, player, player) + ? 1 + : 0; + }); + } else event.finish(); + "step 2"; + if (result.index == 1) { trigger.untrigger(); - trigger.getParent().player=event.target; - game.log(event.target,'成为了',trigger.card,'的使用者'); - player.gainPlayerCard(target,true,'he'); - } - else{ - game.log(event.target,'成为了',trigger.card,'的额外目标'); + trigger.getParent().player = event.target; + game.log(event.target, "成为了", trigger.card, "的使用者"); + player.gainPlayerCard(target, true, "he"); + } else { + game.log(event.target, "成为了", trigger.card, "的额外目标"); trigger.getParent().targets.push(event.target); } - } - }, - xinzenhui2:{}, - xinjiaojin:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})&&event.source&&event.source.hasSex('male'); }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he','骄矜:是否弃置一张装备牌防止伤害?',function(card,player){ - return get.type(card)=='equip'; - }); - next.set('ai',function(card){ - var player=_status.event.player; - if(player.hp==1||_status.event.getTrigger().num>1){ - return 9-get.value(card); + }, + xinzenhui2: {}, + xinjiaojin: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return ( + player.countCards("he", { type: "equip" }) && + event.source && + event.source.hasSex("male") + ); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "骄矜:是否弃置一张装备牌防止伤害?", + function (card, player) { + return get.type(card) == "equip"; } - if(player.hp==2){ - return 8-get.value(card); + ); + next.set("ai", function (card) { + var player = _status.event.player; + if (player.hp == 1 || _status.event.getTrigger().num > 1) { + return 9 - get.value(card); } - return 7-get.value(card); + if (player.hp == 2) { + return 8 - get.value(card); + } + return 7 - get.value(card); }); - next.logSkill='xinjiaojin'; - "step 1" - if(result.bool){ + next.logSkill = "xinjiaojin"; + "step 1"; + if (result.bool) { game.delay(0.5); trigger.cancel(); } - } + }, }, //新华歆 - yuanqing:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - return player.hasHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; + yuanqing: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + return player.hasHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == event; }); }, - content:function(){ - var map={},cards=[]; - player.getHistory('useCard',function(evt){ - if(evt.getParent('phaseUse')==trigger){ - var type=get.type2(evt.card,false); - if(!map[type]) map[type]=[]; + content: function () { + var map = {}, + cards = []; + player.getHistory("useCard", function (evt) { + if (evt.getParent("phaseUse") == trigger) { + var type = get.type2(evt.card, false); + if (!map[type]) map[type] = []; } }); - for(var i=0;i3; + trigger: { global: "dying" }, + forced: true, + filter: function (event, player) { + return _status.renku.length > 3; }, - logTarget:'player', - content:function(){ - player.gain(_status.renku,'gain2','fromRenku'); - _status.renku.length=0; + logTarget: "player", + content: function () { + player.gain(_status.renku, "gain2", "fromRenku"); + _status.renku.length = 0; game.updateRenku(); trigger.player.recover(); }, }, //谯周 - zhiming:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseDiscardEnd']}, - frequent:true, - content:function(){ - 'step 0' + zhiming: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseDiscardEnd"] }, + frequent: true, + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.countCards('he')>0){ - var next=player.chooseCard('he','是否将一张牌置于牌堆顶?'); - if(trigger.name=='phaseZhunbei'){ - next.set('ai',function(card){ - var player=_status.event.player,js=player.getCards('j'); - if(js.length){ - var judge=get.judge(js[0]); - if(judge&&judge(card)>=0) return 20-get.value(card); + "step 1"; + if (player.countCards("he") > 0) { + var next = player.chooseCard("he", "是否将一张牌置于牌堆顶?"); + if (trigger.name == "phaseZhunbei") { + next.set("ai", function (card) { + var player = _status.event.player, + js = player.getCards("j"); + if (js.length) { + var judge = get.judge(js[0]); + if (judge && judge(card) >= 0) return 20 - get.value(card); } return 0; }); - } - else next.set('ai',function(card){ - var player=_status.event.player,js=player.next.getCards('j'); - if(js.length){ - var judge=get.judge(js[0]); - if(judge&&(judge(card)+0.01)*get.attitude(player,player.next)>0) return 20-get.value(card); - } - return 0; - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.$throw(get.position(result.cards[0])=='e'?result.cards[0]:1,1000); - game.log(player,'将',get.position(result.cards[0])=='e'?result.cards[0]:'#y一张手牌','置于了牌堆顶'); - player.lose(result.cards,ui.cardPile,'insert'); - } - else event.finish(); - 'step 3' + } else + next.set("ai", function (card) { + var player = _status.event.player, + js = player.next.getCards("j"); + if (js.length) { + var judge = get.judge(js[0]); + if (judge && (judge(card) + 0.01) * get.attitude(player, player.next) > 0) + return 20 - get.value(card); + } + return 0; + }); + } else event.finish(); + "step 2"; + if (result.bool) { + player.$throw(get.position(result.cards[0]) == "e" ? result.cards[0] : 1, 1000); + game.log( + player, + "将", + get.position(result.cards[0]) == "e" ? result.cards[0] : "#y一张手牌", + "置于了牌堆顶" + ); + player.lose(result.cards, ui.cardPile, "insert"); + } else event.finish(); + "step 3"; game.updateRoundNumber(); game.delayx(); }, - ai:{guanxing:true}, + ai: { guanxing: true }, }, - xingbu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - prompt2:'展示牌堆顶的三张牌,并可以根据其中红色牌的数量,令一名其他角色获得一种效果', - content:function(){ - 'step 0' - var cards=get.cards(3); - for(var i=cards.length-1;i--;i>=0){ - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); - } + xingbu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + prompt2: "亮出牌堆顶的三张牌,并可以根据其中红色牌的数量,令一名其他角色获得一种效果", + content: function () { + "step 0"; + var cards = get.cards(3); + //for(var i=cards.length-1;i--;i>=0){ + // ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); + //} game.updateRoundNumber(); - event.cards=cards; + event.cards = cards; //game.cardsGotoOrdering(cards); - player.showCards(cards,get.translation(player)+'发动了【星卜】'); - 'step 1' - var num=0; - for(var i of cards){ - if(get.color(i,false)=='red') num++; + player.showCards(cards, get.translation(player) + "发动了【星卜】"); + "step 1"; + var num = 0; + for (var i of cards) { + if (get.color(i, false) == "red") num++; } - player.chooseTarget('是否选择一名其他角色获得星卜效果('+get.cnNumber(num)+'张)?',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,num=_status.event.getParent().num; - var att=get.attitude(player,target); - if(num<3) att*=(-1); - if(num==2&&target.hasJudge('lebu')) att*=(-1.4); - return att; - }); - if(num==0) num=1; - event.num=num; - 'step 2' - if(result.bool){ - var skill='xingbu_effect'+num,target=result.targets[0]; - player.line(target,'green'); - game.log(player,'选择了',target); - target.addTempSkill(skill,{player:'phaseEnd'}); - target.addMark(skill,1,false); + player + .chooseTarget( + "是否选择一名其他角色获得星卜效果(" + get.cnNumber(num) + "张)?", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player, + num = _status.event.getParent().num; + var att = get.attitude(player, target); + if (num < 3) att *= -1; + if (num == 2 && target.hasJudge("lebu")) att *= -1.4; + return att; + }); + if (num == 0) num = 1; + event.num = num; + "step 2"; + if (result.bool) { + var skill = "xingbu_effect" + num, + target = result.targets[0]; + player.line(target, "green"); + game.log(player, "选择了", target); + target.addTempSkill(skill, { player: "phaseEnd" }); + target.addMark(skill, 1, false); game.delayx(); } }, - subSkill:{ - effect1:{ - charlotte:true, - onremove:true, - intro:{content:'准备阶段开始时弃置#张手牌'}, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.countCards('h')>0; + subSkill: { + effect1: { + charlotte: true, + onremove: true, + intro: { content: "准备阶段开始时弃置#张手牌" }, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - player.chooseToDiscard('h',true,player.countMark('xingbu_effect1')); + content: function () { + player.chooseToDiscard("h", true, player.countMark("xingbu_effect1")); }, }, - effect2:{ - charlotte:true, - onremove:true, - intro:{content:'使用【杀】的次数上限-#,跳过弃牌阶段'}, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num-player.countMark('xingbu_effect2'); + effect2: { + charlotte: true, + onremove: true, + intro: { content: "使用【杀】的次数上限-#,跳过弃牌阶段" }, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num - player.countMark("xingbu_effect2"); }, }, - trigger:{player:'phaseDiscardBegin'}, - forced:true, - content:function(){ + trigger: { player: "phaseDiscardBegin" }, + forced: true, + content: function () { trigger.cancel(); }, }, - effect3:{ - charlotte:true, - onremove:true, - intro:{content:'摸牌阶段多摸2*#张牌,使用【杀】的次数上限+#。'}, - trigger:{player:['phaseDrawBegin2']}, - forced:true, - filter:function(event,player){ + effect3: { + charlotte: true, + onremove: true, + intro: { content: "摸牌阶段多摸2*#张牌,使用【杀】的次数上限+#。" }, + trigger: { player: ["phaseDrawBegin2"] }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - if(trigger.name=='phaseDraw') trigger.num+=(player.countMark('xingbu_effect3')*2); + content: function () { + if (trigger.name == "phaseDraw") + trigger.num += player.countMark("xingbu_effect3") * 2; }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('xingbu_effect3'); + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("xingbu_effect3"); }, }, }, }, }, //顾雍 - xinshenxing:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return (player.getStat('skill').xinshenxing||0)1; + xinshenxing: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + (player.getStat("skill").xinshenxing || 0) < player.hp && player.countCards("he") > 1 + ); }, - selectCard:2, - position:'he', - check:function(card){ - if(!ui.selected.cards.length||get.color(card)!=get.color(ui.selected.cards[0])) return 6.5-get.value(card); - return 6.5-get.value(card)-get.value(ui.selected.cards[0]); + selectCard: 2, + position: "he", + check: function (card) { + if (!ui.selected.cards.length || get.color(card) != get.color(ui.selected.cards[0])) + return 6.5 - get.value(card); + return 6.5 - get.value(card) - get.value(ui.selected.cards[0]); }, - filterCard:true, - content:function(){ - player.draw(get.color(cards)=='none'?2:1); + filterCard: true, + content: function () { + player.draw(get.color(cards) == "none" ? 2 : 1); }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, }, - xinbingyi:{ - audio:'bingyi', - audioname:['xin_guyong'], - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + xinbingyi: { + audio: "bingyi", + audioname: ["xin_guyong"], + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterx:function(event,player){ - var cards=player.getCards('h'); - if(cards.length==1) return true; - var color=get.color(cards[0],player),type=get.type2(cards[0],player); - for(var i=1;i{ - if(num<=0||typeof card!=='object'||!player.isPhaseUsing()||!player.hasSkill('zili')||player.needsToDiscard()) return num; - if(player.getExpansions('quanji').length<3&&player.getUseValue(card) player.hp; + return event.num > 0; }, - trigger:{player:['damageEnd','phaseUseEnd']}, - frequent:true, - locked:false, - notemp:true, - filter:function(event,player){ - if(event.name=='phaseUse') return player.countCards('h')>player.hp; - return event.num>0; - }, - content:function(){ - "step 0" - event.count=trigger.num||1; - "step 1" + content: function () { + "step 0"; + event.count = trigger.num || 1; + "step 1"; event.count--; player.draw(); - "step 2" - if(player.countCards('h')){ - player.chooseCard('将一张手牌置于武将牌上作为“权”',true); - } - else{ + "step 2"; + if (player.countCards("h")) { + player.chooseCard("将一张手牌置于武将牌上作为“权”", true); + } else { event.goto(4); } - "step 3" - if(result.cards&&result.cards.length){ - player.addToExpansion(result.cards,player,'give').gaintag.add('quanji'); + "step 3"; + if (result.cards && result.cards.length) { + player.addToExpansion(result.cards, player, "give").gaintag.add("quanji"); } - "step 4" - if(event.count>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('requanji')).set('frequentSkill',event.name); - } - else event.finish(); - "step 5" - if(result.bool){ - player.logSkill('requanji'); + "step 4"; + if ( + event.count > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("requanji")).set("frequentSkill", event.name); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("requanji"); event.goto(1); } }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('quanji').length; - } + mod: { + maxHandcard(player, num) { + return num + player.getExpansions("quanji").length; + }, + aiOrder(player, card, num) { + if ( + num <= 0 || + typeof card !== "object" || + !player.isPhaseUsing() || + !player.hasSkill("zili") || + player.needsToDiscard() + ) + return num; + if ( + player.getExpansions("quanji").length < 3 && + player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4) + ) + return 0; + }, }, - onremove:function(player,skill){ - var cards=player.getExpansions('quanji'); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions("quanji"); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - maixie:true, - maixie_hp:true, - threaten:0.8, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [0.5,get.tag(card,'damage')*2]; - if(!target.hasSkill('paiyi')&&target.hp>1) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==3) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + maixie: true, + maixie_hp: true, + threaten: 0.8, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0.5, get.tag(card, "damage") * 2]; + if (!target.hasSkill("paiyi") && target.hp > 1) + return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 3) return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } + }, + }, + }, }, //蔡夫人 - xinqieting:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.getHistory('sourceDamage',function(evt){ - return evt.player!=event.player; - }).length==0; + xinqieting: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.getHistory("sourceDamage", function (evt) { + return evt.player != event.player; + }).length == 0 + ); }, - content:function(){ - 'step 0' - var list=['摸一张牌'],target=trigger.player,str=get.translation(target); - event.target=target; - event.addIndex=0; - if(target.countCards('h')>0) list.push('观看'+str+'的两张手牌并获得其中一张'); + content: function () { + "step 0"; + var list = ["摸一张牌"], + target = trigger.player, + str = get.translation(target); + event.target = target; + event.addIndex = 0; + if (target.countCards("h") > 0) list.push("观看" + str + "的两张手牌并获得其中一张"); else event.addIndex++; - if(target.countCards('e',function(card){ - return player.canEquip(card); - })>0) list.push('将'+str+'装备区内的一张牌移动至自己的装备区'); - player.chooseControl('cancel2').set('choiceList',list).set('prompt',get.prompt('xinqieting',target)).set('ai',function(){ - var evt=_status.event.getParent(); - if(get.attitude(evt.player,evt.target)>0) return 0; - var val=evt.target.hasSkillTag('noe')?6:0; - if(evt.target.countCards('e',function(card){ - return evt.player.canEquip(card)&&get.value(card,evt.target)>val&&get.effect(evt.player,card,evt.player,evt.player)>0; - })>0) return 2-evt.addIndex; - if(evt.target.countCards('h')>0) return 1; - return 0; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xinqieting',target); - if(result.index==0){ + if ( + target.countCards("e", function (card) { + return player.canEquip(card); + }) > 0 + ) + list.push("将" + str + "装备区内的一张牌移动至自己的装备区"); + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("prompt", get.prompt("xinqieting", target)) + .set("ai", function () { + var evt = _status.event.getParent(); + if (get.attitude(evt.player, evt.target) > 0) return 0; + var val = evt.target.hasSkillTag("noe") ? 6 : 0; + if ( + evt.target.countCards("e", function (card) { + return ( + evt.player.canEquip(card) && + get.value(card, evt.target) > val && + get.effect(evt.player, card, evt.player, evt.player) > 0 + ); + }) > 0 + ) + return 2 - evt.addIndex; + if (evt.target.countCards("h") > 0) return 1; + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xinqieting", target); + if (result.index == 0) { player.draw(); event.finish(); - } - else if(result.index+event.addIndex==1){ - player.choosePlayerCard(target,'h',2,true); + } else if (result.index + event.addIndex == 1) { + player.choosePlayerCard(target, "h", 2, true); player.addExpose(0.2); event.goto(3); - } - else{ + } else { player.addExpose(0.1); - player.choosePlayerCard(target,'e',true).set('filterButton',function(button){ - return _status.event.player.canEquip(button.link); - }).set('ai',function(button){ - var player=_status.event.player; - return get.effect(player,button.link,player,player); - }); + player + .choosePlayerCard(target, "e", true) + .set("filterButton", function (button) { + return _status.event.player.canEquip(button.link); + }) + .set("ai", function (button) { + var player = _status.event.player; + return get.effect(player, button.link, player, player); + }); } - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - target.$give(card,player,false); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + target.$give(card, player, false); game.delay(0.5); player.equip(card); } event.finish(); - 'step 3' - if(result.bool) player.chooseButton(['选择获得一张牌',result.cards],true); + "step 3"; + if (result.bool) player.chooseButton(["选择获得一张牌", result.cards], true); else event.finish(); - 'step 4' - if(result.bool){ - var card=result.links[0]; - if(lib.filter.canBeGained(card,player,target)) player.gain(card,target,'giveAuto','bySelf'); - else game.log('但',card,'不能被',player,'获得!'); + "step 4"; + if (result.bool) { + var card = result.links[0]; + if (lib.filter.canBeGained(card, player, target)) + player.gain(card, target, "giveAuto", "bySelf"); + else game.log("但", card, "不能被", player, "获得!"); } }, }, - mobilezhongyong:{ - audio:2, - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='sha'||!event.isPhaseUsing(player)) return false; - if(event.cards.filterInD().length>0) return true; - var list=lib.skill.mobilezhongyong.getResponds(event); - if(list.length){ - for(var evt of list){ - if(evt.cards.filterInD('od').length>0) return true; + mobilezhongyong: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + if (event.card.name != "sha" || !event.isPhaseUsing(player)) return false; + if (event.cards.filterInD().length > 0) return true; + var list = lib.skill.mobilezhongyong.getResponds(event); + if (list.length) { + for (var evt of list) { + if (evt.cards.filterInD("od").length > 0) return true; } } return false; }, - getResponds:function(event){ - var list=[]; - for(var i of event.targets){ - list.addArray(i.getHistory('useCard',function(evt){ - return evt.card.name=='shan'&&evt.respondTo&&evt.respondTo[1]==event.card; - })) + getResponds: function (event) { + var list = []; + for (var i of event.targets) { + list.addArray( + i.getHistory("useCard", function (evt) { + return ( + evt.card.name == "shan" && evt.respondTo && evt.respondTo[1] == event.card + ); + }) + ); } return list; }, - content:function(){ - 'step 0' - event.shas=trigger.cards.filterInD(); - var list=lib.skill.mobilezhongyong.getResponds(trigger); - if(list.length){ - event.shans=[]; - for(var evt of list){ - event.shans.addArray(evt.cards.filterInD('od')); + content: function () { + "step 0"; + event.shas = trigger.cards.filterInD(); + var list = lib.skill.mobilezhongyong.getResponds(trigger); + if (list.length) { + event.shans = []; + for (var evt of list) { + event.shans.addArray(evt.cards.filterInD("od")); } event.goto(2); - } - else player.chooseBool(get.prompt('mobilezhongyong'),'获得'+get.translation(event.shas)).set('ai',function(){ - var evt=_status.event.getParent(); - return get.value(evt.shas,evt.player)>0; - }); - 'step 1' - if(result.bool){ - player.logSkill('mobilezhongyong'); - player.addTempSkill('mobilezhongyong_buff'); - player.gain(event.shas,'gain2').gaintag.add('mobilezhongyong'); + } else + player + .chooseBool(get.prompt("mobilezhongyong"), "获得" + get.translation(event.shas)) + .set("ai", function () { + var evt = _status.event.getParent(); + return get.value(evt.shas, evt.player) > 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("mobilezhongyong"); + player.addTempSkill("mobilezhongyong_buff"); + player.gain(event.shas, "gain2").gaintag.add("mobilezhongyong"); } event.finish(); - 'step 2' - var shans=get.translation(event.shans),choiceList=[ - '获得'+shans, - ]; - if(game.hasPlayer(function(current){ - return current!=player&&!trigger.targets.includes(current); - })){ - if(event.shas.length) choiceList[0]+=(',然后可以令另一名其他角色获得'+get.translation(event.shas)); - choiceList.push('令另一名其他角色获得'+shans+',然后你于本回合内使用【杀】的次数上限+1且下一张【杀】的伤害值基数+1'); + "step 2"; + var shans = get.translation(event.shans), + choiceList = ["获得" + shans]; + if ( + game.hasPlayer(function (current) { + return current != player && !trigger.targets.includes(current); + }) + ) { + if (event.shas.length) + choiceList[0] += ",然后可以令另一名其他角色获得" + get.translation(event.shas); + choiceList.push( + "令另一名其他角色获得" + + shans + + ",然后你于本回合内使用【杀】的次数上限+1且下一张【杀】的伤害值基数+1" + ); } - player.chooseControl('cancel2').set('choiceList',choiceList).set('prompt',get.prompt('mobilezhongyong')).set('ai',function(){ - var evt=_status.event.getParent(),player=evt.player,tri=_status.event.getTrigger(); - if(game.hasPlayer(function(current){ - return current!=player&&!tri.targets.includes(current)&&get.attitude(player,current)>0; - })&&player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card); - })>player.getCardUsable({name:'sha'})) return 1; - return 0; - }); - 'step 3' - if(result.index==0){ - player.logSkill('mobilezhongyong'); - player.addTempSkill('mobilezhongyong_buff'); - player.gain(event.shans,'gain2').gaintag.add('mobilezhongyong'); + player + .chooseControl("cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("mobilezhongyong")) + .set("ai", function () { + var evt = _status.event.getParent(), + player = evt.player, + tri = _status.event.getTrigger(); + if ( + game.hasPlayer(function (current) { + return ( + current != player && + !tri.targets.includes(current) && + get.attitude(player, current) > 0 + ); + }) && + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) > player.getCardUsable({ name: "sha" }) + ) + return 1; + return 0; + }); + "step 3"; + if (result.index == 0) { + player.logSkill("mobilezhongyong"); + player.addTempSkill("mobilezhongyong_buff"); + player.gain(event.shans, "gain2").gaintag.add("mobilezhongyong"); + } else event.goto(6); + "step 4"; + event.shas = event.shas.filterInD("od"); + if ( + event.shas.length && + game.hasPlayer(function (current) { + return current != player && !trigger.targets.includes(current); + }) + ) { + player + .chooseTarget( + "是否令一名其他角色获得" + get.translation(event.shas) + "?", + function (card, player, target) { + return ( + target != player && + !_status.event.getTrigger().targets.includes(target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att <= 0) return att; + if (target.hasSkillTag("nogain")) return att / 10; + if (!target.hasSha()) return 2 * att; + return att; + }); + } else event.finish(); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(event.shas, "gain2"); } - else event.goto(6); - 'step 4' - event.shas=event.shas.filterInD('od'); - if(event.shas.length&&game.hasPlayer(function(current){ - return current!=player&&!trigger.targets.includes(current); - })){ - player.chooseTarget('是否令一名其他角色获得'+get.translation(event.shas)+'?',function(card,player,target){ - return target!=player&&!_status.event.getTrigger().targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<=0) return att; - if(target.hasSkillTag('nogain')) return att/10; - if(!target.hasSha()) return 2*att; + event.finish(); + "step 6"; + player + .chooseTarget( + "令一名其他角色获得" + get.translation(event.shans), + true, + function (card, player, target) { + return ( + target != player && !_status.event.getTrigger().targets.includes(target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att <= 0) return att; + if (target.hasSkillTag("nogain")) return att / 10; + if (!target.hasShan()) return 2 * att; return att; }); - } - else event.finish(); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(event.shas,'gain2'); - } - event.finish(); - 'step 6' - player.chooseTarget('令一名其他角色获得'+get.translation(event.shans),true,function(card,player,target){ - return target!=player&&!_status.event.getTrigger().targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<=0) return att; - if(target.hasSkillTag('nogain')) return att/10; - if(!target.hasShan()) return 2*att; - return att; - }); - 'step 7' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mobilezhongyong',target); - target.gain(event.shans,'gain2'); - player.addTempSkill('mobilezhongyong_buff'); - player.addMark('mobilezhongyong_buff',1,false); - player.addMark('mobilezhongyong_damage',1,false); + "step 7"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mobilezhongyong", target); + target.gain(event.shans, "gain2"); + player.addTempSkill("mobilezhongyong_buff"); + player.addMark("mobilezhongyong_buff", 1, false); + player.addMark("mobilezhongyong_damage", 1, false); } }, - subSkill:{ - buff:{ - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('mobilezhongyong')) return false; + subSkill: { + buff: { + mod: { + cardEnabled2: function (card, player) { + if (get.itemtype(card) == "card" && card.hasGaintag("mobilezhongyong")) + return false; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('mobilezhongyong_buff'); + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("mobilezhongyong_buff"); }, }, - trigger:{player:'useCard1'}, - firstDo:true, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return event.card.name=='sha'&&player.countMark('mobilezhongyong_damage')>0; + trigger: { player: "useCard1" }, + firstDo: true, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return event.card.name == "sha" && player.countMark("mobilezhongyong_damage") > 0; }, - content:function(){ - trigger.baseDamage+=player.storage.mobilezhongyong_damage; + content: function () { + trigger.baseDamage += player.storage.mobilezhongyong_damage; delete player.storage.mobilezhongyong_damage; }, - onremove:function(player){ + onremove: function (player) { delete player.storage.mobilezhongyong_buff; delete player.storage.mobilezhongyong_damage; - player.removeGaintag('mobilezhongyong'); + player.removeGaintag("mobilezhongyong"); }, }, }, }, - rejieyue:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + rejieyue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt2('rejieyue'), - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - ai1:function(card){ - var player=_status.event.player; - if(get.name(card)=='du') return 20; - if(get.position(card)=='e'&&get.value(card)<=0) return 14; - if(get.position(card)=='h'&&game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&¤t.getUseValue(card)>player.getUseValue(card)&¤t.getUseValue(card)>player.getUseValue(card); - })) return 12; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })){ - if(card.name=='wuxie') return 11; - if(card.name=='shan'&&player.countCards('h','shan')>1) return 9 + prompt: get.prompt2("rejieyue"), + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + ai1: function (card) { + var player = _status.event.player; + if (get.name(card) == "du") return 20; + if (get.position(card) == "e" && get.value(card) <= 0) return 14; + if ( + get.position(card) == "h" && + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) > 0 && + current.getUseValue(card) > player.getUseValue(card) && + current.getUseValue(card) > player.getUseValue(card) + ); + }) + ) + return 12; + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) { + if (card.name == "wuxie") return 11; + if (card.name == "shan" && player.countCards("h", "shan") > 1) return 9; } - return 6/Math.max(1,get.value(card)); + return 6 / Math.max(1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player; - var card=ui.selected.cards[0]; - var att=get.attitude(player,target); - if(card.name=='du') return -6*att; - if(att>0){ - if(get.position(card)=='h'&&target.getUseValue(card)>player.getUseValue(card)) return 4*att; - if(get.value(card,target)>get.value(card,player)) return 2*att; - return 1.2*att; + ai2: function (target) { + var player = _status.event.player; + var card = ui.selected.cards[0]; + var att = get.attitude(player, target); + if (card.name == "du") return -6 * att; + if (att > 0) { + if ( + get.position(card) == "h" && + target.getUseValue(card) > player.getUseValue(card) + ) + return 4 * att; + if (get.value(card, target) > get.value(card, player)) return 2 * att; + return 1.2 * att; } - return -att*Math.min(4,target.countCards('he'))/4; + return (-att * Math.min(4, target.countCards("he"))) / 4; }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('rejieyue',target); - player.give(result.cards,target); - } - else event.finish(); - 'step 2' - var num=0; - if(target.countCards('h')) num++; - if(target.countCards('e')) num++; - if(num>0){ - var next=target.chooseCard('he',num,'选择保留每个区域的各一张牌,然后弃置其余的牌。或点取消,令'+get.translation(player)+'摸三张牌',function(card){ - for(var i=0;i 0) { + var next = target.chooseCard( + "he", + num, + "选择保留每个区域的各一张牌,然后弃置其余的牌。或点取消,令" + + get.translation(player) + + "摸三张牌", + function (card) { + for (var i = 0; i < ui.selected.cards.length; i++) { + if (get.position(ui.selected.cards[i]) == get.position(card)) + return false; + } + return true; } - return true; - }); - next.set('complexCard',true); - next.set('goon',get.attitude(target,player)>=0); - next.set('maxNum',num); - next.set('ai',function(card){ - if(_status.event.goon) return -1; - var num=_status.event.maxNum; - if(ui.selected.cards.length>=num-1){ - var cards=player.getCards('he',function(cardx){ - return cardx!=card&&!ui.selected.cards.includes(cardx); + ); + next.set("complexCard", true); + next.set("goon", get.attitude(target, player) >= 0); + next.set("maxNum", num); + next.set("ai", function (card) { + if (_status.event.goon) return -1; + var num = _status.event.maxNum; + if (ui.selected.cards.length >= num - 1) { + var cards = player.getCards("he", function (cardx) { + return cardx != card && !ui.selected.cards.includes(cardx); }); - var val=0; - for(var cardx of cards) val+=get.value(cardx); - if(val>=14) return 0; + var val = 0; + for (var cardx of cards) val += get.value(cardx); + if (val >= 14) return 0; } return get.value(card); }); - } - else event._result={bool:false}; - 'step 3' - if(!result.bool) player.draw(3); + } else event._result = { bool: false }; + "step 3"; + if (!result.bool) player.draw(3); else { - var cards=target.getCards('he'); + var cards = target.getCards("he"); cards.removeArray(result.cards); - if(cards.length) target.discard(cards); + if (cards.length) target.discard(cards); } }, - ai:{ - threaten:1.3, - expose:0.2, + ai: { + threaten: 1.3, + expose: 0.2, }, }, - tiansuan:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ + tiansuan: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { return !player.storage.tiansuan2; }, - content:function(){ - 'step 0' - player.chooseControl('上上签','上签','中签','下签','下下签','cancel2').set('prompt','天算:是否增加其中一个命运签的权重?').set('ai',function(){ - return Math.random()<0.5?0:4; - }); - 'step 1' - var list=[0,1,1,2,2,2,3,3,4]; - if(result.control!='cancel2') list.push(result.index); - var num=list.randomGet(); - event.num=num; - var str=get.translation(player)+'抽取的命运签为:'+lib.skill['tiansuan2_'+num].name; - game.log(player,'抽取出了','#g'+lib.skill['tiansuan2_'+num].name); - event.dialog=ui.create.dialog(str); - event.videoId=lib.status.videoId++; - game.broadcast('createDialog',event.videoId,str); - game.pause(); - setTimeout(function(){ - game.resume(); - },1500); - 'step 2' - event.dialog.close(); - game.broadcast('closeDialog',event.videoId); - player.chooseTarget(true,'令一名角色获得“'+lib.skill['tiansuan2_'+num].name+'”').set('ai',lib.skill['tiansuan2_'+num].aiCheck); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'令',target,'获得了命运签'); - player.storage.tiansuan2=target; - player.storage.tiansuan3='tiansuan2_'+num; - player.addTempSkill('tiansuan2',{player:'phaseBegin'}); - target.addSkill('tiansuan2_'+num); - if(num<2&&target.countGainableCards(player,target==player?'e':'he')>0){ - var next=player.gainPlayerCard(target,target==player?'e':'he',true); - if(num==0) next.visible=true; - } - else game.delayx(); - } + content: function () { + "step 0"; + player + .chooseControl("上上签", "上签", "中签", "下签", "下下签", "cancel2") + .set("prompt", "天算:是否增加其中一个命运签的权重?") + .set("ai", function () { + return Math.random() < 0.5 ? 0 : 4; + }); + "step 1"; + var list = [0, 1, 1, 2, 2, 2, 3, 3, 4]; + if (result.control != "cancel2") list.push(result.index); + var num = list.randomGet(); + event.num = num; + var str = + get.translation(player) + "抽取的命运签为:" + lib.skill["tiansuan2_" + num].name; + game.log(player, "抽取出了", "#g" + lib.skill["tiansuan2_" + num].name); + event.dialog = ui.create.dialog(str); + event.videoId = lib.status.videoId++; + game.broadcast("createDialog", event.videoId, str); + game.pause(); + setTimeout(function () { + game.resume(); + }, 1500); + "step 2"; + event.dialog.close(); + game.broadcast("closeDialog", event.videoId); + player + .chooseTarget(true, "令一名角色获得“" + lib.skill["tiansuan2_" + num].name + "”") + .set("ai", lib.skill["tiansuan2_" + num].aiCheck); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "令", target, "获得了命运签"); + player.storage.tiansuan2 = target; + player.storage.tiansuan3 = "tiansuan2_" + num; + player.addTempSkill("tiansuan2", { player: "phaseBegin" }); + target.addSkill("tiansuan2_" + num); + if (num < 2 && target.countGainableCards(player, target == player ? "e" : "he") > 0) { + var next = player.gainPlayerCard(target, target == player ? "e" : "he", true); + if (num == 0) next.visible = true; + } else game.delayx(); + } }, - derivation:'tiansuan_faq', - ai:{ - order:7, - result:{ - player:1, + derivation: "tiansuan_faq", + ai: { + order: 7, + result: { + player: 1, }, }, }, - tiansuan2:{ - charlotte:true, - onremove:function(player,skill){ - if(player.storage.tiansuan2) player.storage.tiansuan2.removeSkill(player.storage.tiansuan3); + tiansuan2: { + charlotte: true, + onremove: function (player, skill) { + if (player.storage.tiansuan2) + player.storage.tiansuan2.removeSkill(player.storage.tiansuan3); delete player.storage.tiansuan2; delete player.storage.tiansuan3; }, }, - tiansuan2_0:{ - name:'上上签', - trigger:{player:'damageBegin4'}, - forced:true, - charlotte:true, - content:function(){ + tiansuan2_0: { + name: "上上签", + trigger: { player: "damageBegin4" }, + forced: true, + charlotte: true, + content: function () { trigger.cancel(); }, - mark:true, - intro:{ - content:'当你受到伤害时,防止此伤害。', + mark: true, + intro: { + content: "当你受到伤害时,防止此伤害。", }, - aiCheck:function(target){ - if(target.hasSkill('tiansuan2_0')) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })) att*=2; - return att/Math.sqrt(Math.max(1,target.hp)); + aiCheck: function (target) { + if (target.hasSkill("tiansuan2_0")) return 0; + var player = _status.event.player; + var att = get.attitude(player, target); + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) + ) + att *= 2; + return att / Math.sqrt(Math.max(1, target.hp)); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&!player.hasSkillTag('jueqing',false,target)) return 'zerotarget'; - } + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target)) + return "zerotarget"; + }, }, }, }, - tiansuan2_1:{ - name:'上签', - trigger:{player:'damageBegin4'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.num>1; + tiansuan2_1: { + name: "上签", + trigger: { player: "damageBegin4" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.num > 1; }, - content:function(){ - trigger.num=1; + content: function () { + trigger.num = 1; }, - group:'tiansuan2_damage', - mark:true, - intro:{ - content:'当你受到伤害时,你令伤害值改为1;当你受到1点伤害后,你摸一张牌。', + group: "tiansuan2_damage", + mark: true, + intro: { + content: "当你受到伤害时,你令伤害值改为1;当你受到1点伤害后,你摸一张牌。", }, - aiCheck:function(target){ - if(target.hasSkill('tiansuan2_1')) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })) att*=2; - if(target.hp==1) return att/2; - return att/Math.sqrt(Math.max(1,target.hp)); + aiCheck: function (target) { + if (target.hasSkill("tiansuan2_1")) return 0; + var player = _status.event.player; + var att = get.attitude(player, target); + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) + ) + att *= 2; + if (target.hp == 1) return att / 2; + return att / Math.sqrt(Math.max(1, target.hp)); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, - effect:{ - target:function(card,player,target,current){ - if(target&&target.hp>1&&get.tag(card,'damage')&&!player.hasSkillTag('jueqing',false,target)) return 0.8; - } + effect: { + target: function (card, player, target, current) { + if ( + target && + target.hp > 1 && + get.tag(card, "damage") && + !player.hasSkillTag("jueqing", false, target) + ) + return 0.8; + }, }, }, }, - tiansuan2_damage:{ - trigger:{player:'damageEnd'}, - charlotte:true, - content:function(){ + tiansuan2_damage: { + trigger: { player: "damageEnd" }, + charlotte: true, + content: function () { player.draw(trigger.num); }, }, - tiansuan2_2:{ - name:'中签', - trigger:{player:'damageBegin4'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.num>1; + tiansuan2_2: { + name: "中签", + trigger: { player: "damageBegin4" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.num > 1; }, - content:function(){ - trigger.num=1; + content: function () { + trigger.num = 1; }, - mark:true, - intro:{ - content:'当你受到伤害时,你令伤害属性改为火属性并将伤害值改为1。', + mark: true, + intro: { + content: "当你受到伤害时,你令伤害属性改为火属性并将伤害值改为1。", }, - aiCheck:function(target){ - if(target.hasSkill('tiansuan2_2')) return 0; - var player=_status.event.player; - target.addSkill('tiansuan2_ai'); - var num=get.damageEffect(target,player,player,'fire'); - target.removeSkill('tiansuan2_ai'); + aiCheck: function (target) { + if (target.hasSkill("tiansuan2_2")) return 0; + var player = _status.event.player; + target.addSkill("tiansuan2_ai"); + var num = get.damageEffect(target, player, player, "fire"); + target.removeSkill("tiansuan2_ai"); return num; }, - group:['tiansuan2_fire','tiansuan2_ai'], + group: ["tiansuan2_fire", "tiansuan2_ai"], }, - tiansuan2_ai:{ - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + tiansuan2_ai: { + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, - tiansuan2_fire:{ - trigger:{player:'damageBefore'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return !event.hasNature('fire'); + tiansuan2_fire: { + trigger: { player: "damageBefore" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return !event.hasNature("fire"); }, - content:function(){ - game.setNature(trigger,'fire'); + content: function () { + game.setNature(trigger, "fire"); }, }, - tiansuan2_3:{ - name:'下签', - trigger:{player:'damageBegin3'}, - forced:true, - charlotte:true, - content:function(){ + tiansuan2_3: { + name: "下签", + trigger: { player: "damageBegin3" }, + forced: true, + charlotte: true, + content: function () { trigger.num++; }, - mark:true, - intro:{ - content:'当你受到伤害时,你令此伤害+1。', + mark: true, + intro: { + content: "当你受到伤害时,你令此伤害+1。", }, - aiCheck:function(target){ - if(target.hasSkill('tiansuan2_3')) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - return -att/Math.sqrt(Math.max(1,target.hp)); + aiCheck: function (target) { + if (target.hasSkill("tiansuan2_3")) return 0; + var player = _status.event.player; + var att = get.attitude(player, target); + return -att / Math.sqrt(Math.max(1, target.hp)); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&!player.hasSkillTag('jueqing',false,target)&¤t<0) return 1.3; - } + ai: { + effect: { + target: function (card, player, target, current) { + if ( + get.tag(card, "damage") && + !player.hasSkillTag("jueqing", false, target) && + current < 0 + ) + return 1.3; + }, }, }, }, - tiansuan2_4:{ - name:'下下签', - trigger:{player:'damageBegin3'}, - forced:true, - charlotte:true, - content:function(){ + tiansuan2_4: { + name: "下下签", + trigger: { player: "damageBegin3" }, + forced: true, + charlotte: true, + content: function () { trigger.num++; }, - mod:{ - cardEnabled:function(card,player){ - if(card.name=='tao'||card.name=='jiu') return false; + mod: { + cardEnabled: function (card, player) { + if (card.name == "tao" || card.name == "jiu") return false; }, - cardSavable:function(card,player){ - if(card.name=='tao'||card.name=='jiu') return false; + cardSavable: function (card, player) { + if (card.name == "tao" || card.name == "jiu") return false; }, }, - mark:true, - intro:{ - content:'当你受到伤害时,你令此伤害+1。你不能使用【酒】或【桃】。', + mark: true, + intro: { + content: "当你受到伤害时,你令此伤害+1。你不能使用【酒】或【桃】。", }, - aiCheck:function(target){ - if(target.hasSkill('tiansuan2_4')) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - return -att/Math.sqrt(Math.max(1,target.hp)); + aiCheck: function (target) { + if (target.hasSkill("tiansuan2_4")) return 0; + var player = _status.event.player; + var att = get.attitude(player, target); + return -att / Math.sqrt(Math.max(1, target.hp)); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&!player.hasSkillTag('jueqing',false,target)&¤t<0) return 1.3; - } + ai: { + effect: { + target: function (card, player, target, current) { + if ( + get.tag(card, "damage") && + !player.hasSkillTag("jueqing", false, target) && + current < 0 + ) + return 1.3; + }, }, }, }, - relieren:{ - shaRelated:true, - audio:2, - audioname:['boss_lvbu3'], - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&player.canCompare(event.target); + relieren: { + shaRelated: true, + audio: 2, + audioname: ["boss_lvbu3"], + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha" && player.canCompare(event.target); }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, //priority:5, - content:function(){ - "step 0" - player.chooseToCompare(trigger.target).clear=false; - "step 1" - if(result.bool){ - if(trigger.target.countGainableCards(player,'he')) player.gainPlayerCard(trigger.target,true,'he'); + content: function () { + "step 0"; + player.chooseToCompare(trigger.target).clear = false; + "step 1"; + if (result.bool) { + if (trigger.target.countGainableCards(player, "he")) + player.gainPlayerCard(trigger.target, true, "he"); ui.clear(); + } else { + var card1 = result.player; + var card2 = result.target; + if (get.position(card1) == "d") trigger.target.gain(card1, "gain2"); + if (get.position(card2) == "d") player.gain(card2, "gain2"); } - else{ - var card1=result.player; - var card2=result.target; - if(get.position(card1)=='d') trigger.target.gain(card1,'gain2'); - if(get.position(card2)=='d') player.gain(card2,'gain2'); - } - } - }, - retiaoxin:{ - audio:'tiaoxin', - audioname:['sp_jiangwei','xiahouba','re_jiangwei'], - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he'); }, - content:function(){ - "step 0" - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'挑衅:对'+get.translation(player)+'使用一张杀,或令其弃置你的一张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); - "step 1" - if(result.bool==false&&target.countCards('he')>0){ - player.discardPlayerCard(target,'he',true); - } - else{ + }, + retiaoxin: { + audio: "tiaoxin", + audioname: ["sp_jiangwei", "xiahouba", "re_jiangwei"], + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he"); + }, + content: function () { + "step 0"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "挑衅:对" + get.translation(player) + "使用一张杀,或令其弃置你的一张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + if (result.bool == false && target.countCards("he") > 0) { + player.discardPlayerCard(target, "he", true); + } else { event.finish(); } }, - ai:{ - order:4, - expose:0.2, - result:{ - target:-1, - player:function(player,target){ - if(!target.canUse('sha',player)) return 0; - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.hp<=2) return -2; - if(player.countCards('h','shan')==0) return -1; + ai: { + order: 4, + expose: 0.2, + result: { + target: -1, + player: function (player, target) { + if (!target.canUse("sha", player)) return 0; + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.hp <= 2) return -2; + if (player.countCards("h", "shan") == 0) return -1; return -0.5; - } + }, }, - threaten:1.1 - } + threaten: 1.1, + }, }, //南华老仙 - yufeng:{ - inherit:'yufeng_old', - content:function(){ - "step 0" - if(_status.connectMode) event.time=lib.configOL.choose_timeout; - event.videoId=lib.status.videoId++; - var maxScore = Math.max(2,1+player.countMark('yufeng')); - if(player.isUnderControl()){ + yufeng: { + inherit: "yufeng_old", + content: function () { + "step 0"; + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + event.videoId = lib.status.videoId++; + var maxScore = Math.max(2, 1 + player.countMark("yufeng")); + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ + var switchToAuto = function () { game.pause(); game.countChoose(); - setTimeout(function(){ - _status.imchoosing=false; - var max=Math.max(2,1+player.countMark('yufeng')); - var score=Math.random()<0.5?max:get.rand(1,max); - event._result={ - bool:true, - score:score, - win:score>=max, + setTimeout(function () { + _status.imchoosing = false; + var max = Math.max(2, 1 + player.countMark("yufeng")); + var score = Math.random() < 0.5 ? max : get.rand(1, max); + event._result = { + bool: true, + score: score, + win: score >= max, }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); game.resume(); - },5000); + }, 5000); }; - var createDialog=function(player,id){ - if(_status.connectMode) lib.configOL.choose_timeout='30'; - if(player==game.me) return; - var str=get.translation(player)+'正在表演《御风飞行》...
              '; - ui.create.dialog(str).videoId=id; + var createDialog = function (player, id) { + if (_status.connectMode) lib.configOL.choose_timeout = "30"; + if (player == game.me) return; + var str = get.translation(player) + "正在表演《御风飞行》...
              "; + ui.create.dialog(str).videoId = id; + }; + var chooseButton = function (maxScore) { + lib.skill.yufeng.$playFlappyBird(maxScore); }; - var chooseButton=function(maxScore){lib.skill.yufeng.$playFlappyBird(maxScore)}; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId); - if(event.isMine()){ + game.broadcastAll(createDialog, player, event.videoId); + if (event.isMine()) { chooseButton(maxScore); - } - else if(event.isOnline()){ - event.player.send(chooseButton,maxScore); + } else if (event.isOnline()) { + event.player.send(chooseButton, maxScore); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - game.broadcastAll(function(id,time){ - if(_status.connectMode) lib.configOL.choose_timeout=time; - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - },event.videoId,event.time); - var result=event.result||result; - player.popup(get.cnNumber(result.score)+'分',result.win?'wood':'fire') - game.log(player,'御风飞行',result.win?'#g成功':'#y失败'); - game.log(player,'获得了','#g'+result.score+'分'); - var max=player.countMark('yufeng'); - if(!result.win){ - if(result.score) player.draw(result.score); - if(max) player.removeMark('yufeng',max,false); + "step 1"; + game.broadcastAll( + function (id, time) { + if (_status.connectMode) lib.configOL.choose_timeout = time; + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + }, + event.videoId, + event.time + ); + var result = event.result || result; + player.popup(get.cnNumber(result.score) + "分", result.win ? "wood" : "fire"); + game.log(player, "御风飞行", result.win ? "#g成功" : "#y失败"); + game.log(player, "获得了", "#g" + result.score + "分"); + var max = player.countMark("yufeng"); + if (!result.win) { + if (result.score) player.draw(result.score); + if (max) player.removeMark("yufeng", max, false); event.finish(); + } else { + if (max < 2) player.addMark("yufeng", 1, false); + event.score = result.score; + player + .chooseTarget( + "请选择【御风】的目标", + [1, result.score], + function (card, player, target) { + return target != player && !target.hasSkill("yufeng2"); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = -get.attitude(player, target), + attx = att * 2; + if (att <= 0 || target.hasSkill("xinfu_pdgyingshi")) return 0; + if (target.hasJudge("lebu")) attx -= att; + if (target.hasJudge("bingliang")) attx -= att; + return attx / Math.max(2.25, Math.sqrt(target.countCards("h") + 1)); + }); } - else{ - if(max<2) player.addMark('yufeng',1,false); - event.score=result.score; - player.chooseTarget('请选择【御风】的目标',[1,result.score],function(card,player,target){ - return target!=player&&!target.hasSkill('yufeng2'); - }).set('ai',function(target){ - var player=_status.event.player; - var att=-get.attitude(player,target),attx=att*2; - if(att<=0||target.hasSkill('xinfu_pdgyingshi')) return 0; - if(target.hasJudge('lebu')) attx-=att; - if(target.hasJudge('bingliang')) attx-=att; - return attx/Math.max(2.25,Math.sqrt(target.countCards('h')+1)); - }); - } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { result.targets.sortBySeat(); - player.line(result.targets,'green'); - game.log(result.targets,'获得了','#y“御风”','效果'); - for(var i of result.targets) i.addSkill('yufeng2'); - if(event.score>result.targets.length) player.draw(event.score-result.targets.length); - } - else player.draw(event.score); + player.line(result.targets, "green"); + game.log(result.targets, "获得了", "#y“御风”", "效果"); + for (var i of result.targets) i.addSkill("yufeng2"); + if (event.score > result.targets.length) + player.draw(event.score - result.targets.length); + } else player.draw(event.score); }, - $playFlappyBird:function(maxScore,title){ + $playFlappyBird: function (maxScore, title) { //Forked from: https://github.com/aaarafat/JS-Flappy-Bird - const event=_status.event; - const dialog=ui.create.dialog('forcebutton','hidden'); - dialog.textPrompt=dialog.add('
              准备好了吗?
              '); - dialog.classList.add('fixed'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.classList.add('noupdate'); - const updateText=function(str){ - dialog.textPrompt.innerHTML='
              '+str+'
              '; - } + const event = _status.event; + const dialog = ui.create.dialog("forcebutton", "hidden"); + dialog.textPrompt = dialog.add('
              准备好了吗?
              '); + dialog.classList.add("fixed"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.classList.add("noupdate"); + const updateText = function (str) { + dialog.textPrompt.innerHTML = '
              ' + str + "
              "; + }; - const canvas=document.createElement('canvas'); + const canvas = document.createElement("canvas"); dialog.appendChild(canvas); - canvas.style.position="absolute"; - canvas.style.width='276px'; - canvas.style.height='414px'; - canvas.style.left="calc(50% - 141px)"; - canvas.style.top="calc(50% - 200px)"; - canvas.width=276; - canvas.height=414; - canvas.style.border='3px solid'; + canvas.style.position = "absolute"; + canvas.style.width = "276px"; + canvas.style.height = "414px"; + canvas.style.left = "calc(50% - 141px)"; + canvas.style.top = "calc(50% - 200px)"; + canvas.width = 276; + canvas.height = 414; + canvas.style.border = "3px solid"; const RAD = Math.PI / 180; - const ctx=canvas.getContext('2d'); + const ctx = canvas.getContext("2d"); let frames = 0; let dx = 0.1; let previousDOMHighResTimeStamp = performance.now(); @@ -9311,8 +11545,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ getReady: 0, Play: 1, gameOver: 2, - gameSuccess:3, - } + gameSuccess: 3, + }; const SFX = { start: new Audio(), flap: new Audio(), @@ -9330,10 +11564,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ctx.drawImage(this.sprite, this.x, this.y); }, update: function () { - if(state.curr == state.gameOver || state.curr == state.gameSuccess) return; + if (state.curr == state.gameOver || state.curr == state.gameSuccess) return; this.x -= dx * deltaTime; const halfWidth = this.sprite.width / 4; - if(this.x <= -halfWidth) this.x += halfWidth; + if (this.x <= -halfWidth) this.x += halfWidth; }, }; const bg = { @@ -9371,7 +11605,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ this.timeElapsed -= 1600; this.pipes.push({ x: parseFloat(canvas.width), - y: -210 * Math.min(Math.random()*0.8 + 1.2, 1.8), + y: -210 * Math.min(Math.random() * 0.8 + 1.2, 1.8), }); } this.pipes.forEach((pipe) => { @@ -9412,12 +11646,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ this.totalTimeElapsed += deltaTime; let r = parseFloat(this.animations[0].sprite.width) / 2; switch (state.curr) { - case state.getReady: case state.gameSuccess: + case state.getReady: + case state.gameSuccess: this.rotatation = 0; this.timeElapsed += deltaTime; if (this.timeElapsed >= 200) { this.timeElapsed -= 200; - this.y += Math.sin(this.totalTimeElapsed / 10 * RAD); + this.y += Math.sin((this.totalTimeElapsed / 10) * RAD); this.frame++; } break; @@ -9430,17 +11665,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ this.y += this.speed * deltaTime; this.setRotation(); this.speed += this.gravity * deltaTime; - if(UI.score.curr >= maxScore){ + if (UI.score.curr >= maxScore) { state.curr = state.gameSuccess; this.timeElapsed = 0; - updateText(`${title||'御风飞行'}表演成功!`) - setTimeout(switchToAuto,2000); - } - else if (this.y + r >= gnd.y || this.collisioned()) { + updateText(`${title || "御风飞行"}表演成功!`); + setTimeout(switchToAuto, 2000); + } else if (this.y + r >= gnd.y || this.collisioned()) { state.curr = state.gameOver; this.timeElapsed = 0; - updateText(`${title||'御风飞行'}表演失败……`) - setTimeout(switchToAuto,2000); + updateText(`${title || "御风飞行"}表演失败……`); + setTimeout(switchToAuto, 2000); } break; case state.gameOver: @@ -9492,8 +11726,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ Promise.resolve(SFX.hit.play()).catch(() => void 0); return true; } - } - else if (pipe.moved) { + } else if (pipe.moved) { updateText(`当前分数:${++UI.score.curr}`); const score = SFX.score; score.currentTime = 0; @@ -9519,7 +11752,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ frame: 0, timeElapsed: 0, draw: function () { - switch (state.curr) { + switch (state.curr) { case state.getReady: this.y = parseFloat(canvas.height - this.getReady.sprite.height) / 2; this.x = parseFloat(canvas.width - this.getReady.sprite.width) / 2; @@ -9529,13 +11762,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ctx.drawImage(this.getReady.sprite, this.x, this.y); ctx.drawImage(this.tap[this.frame].sprite, this.tx, this.ty); break; - case state.gameOver: case state.gameSuccess: + case state.gameOver: + case state.gameSuccess: this.y = parseFloat(canvas.height - this.gameOver.sprite.height) / 2; this.x = parseFloat(canvas.width - this.gameOver.sprite.width) / 2; this.tx = parseFloat(canvas.width - this.tap[0].sprite.width) / 2; this.ty = this.y + this.gameOver.sprite.height - this.tap[0].sprite.height; - ctx.drawImage((state.curr == state.gameOver ? this.gameOver : this.gameClear).sprite, this.x, this.y); + ctx.drawImage( + (state.curr == state.gameOver ? this.gameOver : this.gameClear) + .sprite, + this.x, + this.y + ); } }, update: function () { @@ -9549,44 +11788,44 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if (this.frame >= tapLength) this.frame -= tapLength; }, }; - gnd.sprite.src = lib.assetURL+"image/flappybird/ground.png"; - bg.sprite.src = lib.assetURL+"image/flappybird/BG.png"; - pipe.top.sprite.src = lib.assetURL+"image/flappybird/toppipe.png"; - pipe.bot.sprite.src = lib.assetURL+"image/flappybird/botpipe.png"; - UI.gameOver.sprite.src = lib.assetURL+"image/flappybird/gameover.png"; - UI.gameClear.sprite.src = lib.assetURL+"image/flappybird/gameclear.png"; - UI.getReady.sprite.src = lib.assetURL+"image/flappybird/getready.png"; - UI.tap[0].sprite.src = lib.assetURL+"image/flappybird/tap/t0.png"; - UI.tap[1].sprite.src = lib.assetURL+"image/flappybird/tap/t1.png"; - bird.animations[0].sprite.src = lib.assetURL+"image/flappybird/bird/b0.png"; - bird.animations[1].sprite.src = lib.assetURL+"image/flappybird/bird/b1.png"; - bird.animations[2].sprite.src = lib.assetURL+"image/flappybird/bird/b2.png"; - bird.animations[3].sprite.src = lib.assetURL+"image/flappybird/bird/b0.png"; + gnd.sprite.src = lib.assetURL + "image/flappybird/ground.png"; + bg.sprite.src = lib.assetURL + "image/flappybird/BG.png"; + pipe.top.sprite.src = lib.assetURL + "image/flappybird/toppipe.png"; + pipe.bot.sprite.src = lib.assetURL + "image/flappybird/botpipe.png"; + UI.gameOver.sprite.src = lib.assetURL + "image/flappybird/gameover.png"; + UI.gameClear.sprite.src = lib.assetURL + "image/flappybird/gameclear.png"; + UI.getReady.sprite.src = lib.assetURL + "image/flappybird/getready.png"; + UI.tap[0].sprite.src = lib.assetURL + "image/flappybird/tap/t0.png"; + UI.tap[1].sprite.src = lib.assetURL + "image/flappybird/tap/t1.png"; + bird.animations[0].sprite.src = lib.assetURL + "image/flappybird/bird/b0.png"; + bird.animations[1].sprite.src = lib.assetURL + "image/flappybird/bird/b1.png"; + bird.animations[2].sprite.src = lib.assetURL + "image/flappybird/bird/b2.png"; + bird.animations[3].sprite.src = lib.assetURL + "image/flappybird/bird/b0.png"; - SFX.start.src = lib.assetURL+"audio/effect/flappybird_start.wav"; - SFX.flap.src = lib.assetURL+"audio/effect/flappybird_flap.wav"; - SFX.score.src = lib.assetURL+"audio/effect/flappybird_score.wav"; - SFX.hit.src = lib.assetURL+"audio/effect/flappybird_hit.wav"; - SFX.die.src = lib.assetURL+"audio/effect/flappybird_die.wav"; + SFX.start.src = lib.assetURL + "audio/effect/flappybird_start.wav"; + SFX.flap.src = lib.assetURL + "audio/effect/flappybird_flap.wav"; + SFX.score.src = lib.assetURL + "audio/effect/flappybird_score.wav"; + SFX.hit.src = lib.assetURL + "audio/effect/flappybird_hit.wav"; + SFX.die.src = lib.assetURL + "audio/effect/flappybird_die.wav"; - const gameLoop = domHighResTimeStamp => { - if(frames<0) return; + const gameLoop = (domHighResTimeStamp) => { + if (frames < 0) return; deltaTime = domHighResTimeStamp - previousDOMHighResTimeStamp; previousDOMHighResTimeStamp = domHighResTimeStamp; update(); draw(); frames++; window.requestAnimationFrame(gameLoop); - } + }; - const update = function(){ + const update = function () { bird.update(); gnd.update(); pipe.update(); UI.update(); - } + }; - const draw = function(){ + const draw = function () { ctx.fillStyle = "#30c0df"; ctx.fillRect(0, 0, canvas.width, canvas.height); bg.draw(); @@ -9595,9 +11834,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ bird.draw(); gnd.draw(); UI.draw(); - } + }; - const click = function(){ + const click = function () { switch (state.curr) { case state.getReady: state.curr = state.Play; @@ -9605,690 +11844,824 @@ game.import('character',function(lib,game,ui,get,ai,_status){ Promise.resolve(SFX.start.play()).catch(() => void 0); updateText(`当前分数:${UI.score.curr}`); break; - case state.Play: bird.flap(); + case state.Play: + bird.flap(); } }; - const switchToAuto = function(){ - event._result={ - bool:true, - score:UI.score.curr, - win:UI.score.curr>=maxScore, + const switchToAuto = function () { + event._result = { + bool: true, + score: UI.score.curr, + win: UI.score.curr >= maxScore, }; dialog.close(); game.resume(); - _status.imchoosing=false; - frames=-1; - document.removeEventListener(lib.config.touchscreen?'touchstart':'mousedown',click); - } + _status.imchoosing = false; + frames = -1; + document.removeEventListener( + lib.config.touchscreen ? "touchstart" : "mousedown", + click + ); + }; dialog.open(); game.pause(); game.countChoose(); - document.addEventListener(lib.config.touchscreen?'touchstart':'mousedown',click); + document.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", click); window.requestAnimationFrame(gameLoop); }, }, - yufeng_old:{ - audio:2, - enable:'phaseUse', - usable:1, - content:function(){ - "step 0" - if(_status.connectMode) event.time=lib.configOL.choose_timeout; - event.videoId=lib.status.videoId++; - if(player.isUnderControl()){ + yufeng_old: { + audio: 2, + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + event.videoId = lib.status.videoId++; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ + var switchToAuto = function () { game.pause(); game.countChoose(); - setTimeout(function(){ - _status.imchoosing=false; - var max=Math.max(2,1+game.me.countMark('yufeng')); - var score=Math.random()<0.5?max:get.rand(1,max); - event._result={ - bool:true, - score:score, - win:score>=max, + setTimeout(function () { + _status.imchoosing = false; + var max = Math.max(2, 1 + game.me.countMark("yufeng")); + var score = Math.random() < 0.5 ? max : get.rand(1, max); + event._result = { + bool: true, + score: score, + win: score >= max, }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); game.resume(); - },5000); + }, 5000); }; - var createDialog=function(player,id){ - if(_status.connectMode) lib.configOL.choose_timeout='30'; - if(player==game.me) return; - var str=get.translation(player)+'正在表演《御风飞行》...
              '; - ui.create.dialog(str).videoId=id; + var createDialog = function (player, id) { + if (_status.connectMode) lib.configOL.choose_timeout = "30"; + if (player == game.me) return; + var str = get.translation(player) + "正在表演《御风飞行》...
              "; + ui.create.dialog(str).videoId = id; }; - var chooseButton=function(){ - var roundmenu=false; - if(ui.roundmenu&&ui.roundmenu.display!='none'){ - roundmenu=true; - ui.roundmenu.style.display='none'; + var chooseButton = function () { + var roundmenu = false; + if (ui.roundmenu && ui.roundmenu.display != "none") { + roundmenu = true; + ui.roundmenu.style.display = "none"; } - var event=_status.event; - event.settleed=false; - event.score=0; - event.dialog=ui.create.dialog('forcebutton','hidden'); - event.dialog.textPrompt=event.dialog.add('
              准备好了吗?准备好了的话就点击屏幕开始吧!
              '); - var max=Math.max(2,1+game.me.countMark('yufeng')); - event.dialog.textPrompt.style["z-index"]=10; - event.switchToAuto=function(){ - event._result={ - bool:true, - score:event.score, - win:event.score>=max, + var event = _status.event; + event.settleed = false; + event.score = 0; + event.dialog = ui.create.dialog("forcebutton", "hidden"); + event.dialog.textPrompt = event.dialog.add( + '
              准备好了吗?准备好了的话就点击屏幕开始吧!
              ' + ); + var max = Math.max(2, 1 + game.me.countMark("yufeng")); + event.dialog.textPrompt.style["z-index"] = 10; + event.switchToAuto = function () { + event._result = { + bool: true, + score: event.score, + win: event.score >= max, }; event.dialog.close(); game.resume(); - _status.imchoosing=false; - if(roundmenu) ui.roundmenu.style.display=''; + _status.imchoosing = false; + if (roundmenu) ui.roundmenu.style.display = ""; }; - event.dialog.classList.add('fixed'); - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - event.dialog.classList.add('fullheight'); - event.dialog.classList.add('noupdate'); - event.dialog.style.overflow='hidden'; + event.dialog.classList.add("fixed"); + event.dialog.classList.add("scroll1"); + event.dialog.classList.add("scroll2"); + event.dialog.classList.add("fullwidth"); + event.dialog.classList.add("fullheight"); + event.dialog.classList.add("noupdate"); + event.dialog.style.overflow = "hidden"; event.dialog.open(); - var height=event.dialog.offsetHeight; - var width=event.dialog.offsetWidth; - var top=50; - var speed=0; - var start=false; + var height = event.dialog.offsetHeight; + var width = event.dialog.offsetWidth; + var top = 50; + var speed = 0; + var start = false; - var bird=ui.create.div(''); - bird.style["background-image"]='linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))'; - bird.style["border-radius"]='3px'; - var pipes=[]; - bird.style.position='absolute'; - bird.style.height='40px'; - bird.style.width='40px'; - bird.style.left=Math.ceil(width/3)+'px'; - bird.style.top=(top/100*height)+'px'; - bird.updatePosition=function(){ - bird.style.transform='translateY('+(top/100*height-bird.offsetTop)+'px)'; + var bird = ui.create.div(""); + bird.style["background-image"] = + "linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))"; + bird.style["border-radius"] = "3px"; + var pipes = []; + bird.style.position = "absolute"; + bird.style.height = "40px"; + bird.style.width = "40px"; + bird.style.left = Math.ceil(width / 3) + "px"; + bird.style.top = (top / 100) * height + "px"; + bird.updatePosition = function () { + bird.style.transform = + "translateY(" + ((top / 100) * height - bird.offsetTop) + "px)"; }; event.dialog.appendChild(bird); - var isDead=function(){ - if(top>100||top<0) return true; - var btop=top; - var bleft=100/3; - var bdown=btop+5; - var bright=bleft+5; - for(var i of pipes){ - var left2=i.left; - var right2=left2+10; - var bottom2=i.height1; - var top2=i.height2; + var isDead = function () { + if (top > 100 || top < 0) return true; + var btop = top; + var bleft = 100 / 3; + var bdown = btop + 5; + var bright = bleft + 5; + for (var i of pipes) { + var left2 = i.left; + var right2 = left2 + 10; + var bottom2 = i.height1; + var top2 = i.height2; - if(left2>bright||right2top2) return true; + if (left2 > bright || right2 < bleft) continue; + if (btop < bottom2) return true; + if (bdown > top2) return true; return false; } return false; }; - var fly=function(){ - if(!start){ - start=true; - event.dialog.textPrompt.innerHTML='
              当前分数:'+event.score+'
              '; - speed=-4; - event.fly=setInterval(function(){ - top+=speed; - if(top<0) top=0; + var fly = function () { + if (!start) { + start = true; + event.dialog.textPrompt.innerHTML = + '
              当前分数:' + event.score + "
              "; + speed = -4; + event.fly = setInterval(function () { + top += speed; + if (top < 0) top = 0; bird.updatePosition(); - for(var i of pipes){ - i.left-=0.5; + for (var i of pipes) { + i.left -= 0.5; i.updateLeft(); } - speed+=0.5; - if(speed>2.5) speed=2.5; + speed += 0.5; + if (speed > 2.5) speed = 2.5; - if(isDead()==true){ + if (isDead() == true) { event.settle(); } - },35); - var addPipe=function(){ - var num=get.rand(5,55); + }, 35); + var addPipe = function () { + var num = get.rand(5, 55); - var pipe1=ui.create.div(''); - pipe1.style["background-image"]='linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))'; - pipe1.style["border-radius"]='3px'; - pipe1.style.position='absolute'; - pipe1.height1=num; - pipe1.height2=num+50; - pipe1.left=110; - pipe1.num=1; - pipe1.style.height=Math.ceil(height*num/100)+'px'; - pipe1.style.width=(width/10)+'px'; - pipe1.style.left=(pipe1.left*width/100)+'px'; - pipe1.style.top='0px'; + var pipe1 = ui.create.div(""); + pipe1.style["background-image"] = + "linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))"; + pipe1.style["border-radius"] = "3px"; + pipe1.style.position = "absolute"; + pipe1.height1 = num; + pipe1.height2 = num + 50; + pipe1.left = 110; + pipe1.num = 1; + pipe1.style.height = Math.ceil((height * num) / 100) + "px"; + pipe1.style.width = width / 10 + "px"; + pipe1.style.left = (pipe1.left * width) / 100 + "px"; + pipe1.style.top = "0px"; - var pipe2=ui.create.div(''); - pipe2.style["background-image"]='linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))'; - pipe2.style["border-radius"]='3px'; - pipe1.pipe2=pipe2; - pipe2.style.position='absolute'; - pipe2.style.height=Math.ceil((100-pipe1.height2)*height/100)+'px'; - pipe2.style.width=(width/10)+'px'; - pipe2.style.left=(pipe1.left*width/100)+'px'; - pipe2.style.top=Math.ceil(pipe1.height2*height/100)+'px'; + var pipe2 = ui.create.div(""); + pipe2.style["background-image"] = + "linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))"; + pipe2.style["border-radius"] = "3px"; + pipe1.pipe2 = pipe2; + pipe2.style.position = "absolute"; + pipe2.style.height = + Math.ceil(((100 - pipe1.height2) * height) / 100) + "px"; + pipe2.style.width = width / 10 + "px"; + pipe2.style.left = (pipe1.left * width) / 100 + "px"; + pipe2.style.top = Math.ceil((pipe1.height2 * height) / 100) + "px"; pipes.add(pipe1); event.dialog.appendChild(pipe1); event.dialog.appendChild(pipe2); - pipe1.updateLeft=function(){ - this.style.transform='translateX('+((this.left/100*width)-this.offsetLeft)+'px)'; - this.pipe2.style.transform='translateX('+((this.left/100*width)-this.pipe2.offsetLeft)+'px)'; - if(this.left<25&&!this.score){ - this.score=true; + pipe1.updateLeft = function () { + this.style.transform = + "translateX(" + + ((this.left / 100) * width - this.offsetLeft) + + "px)"; + this.pipe2.style.transform = + "translateX(" + + ((this.left / 100) * width - this.pipe2.offsetLeft) + + "px)"; + if (this.left < 25 && !this.score) { + this.score = true; event.score++; - event.dialog.textPrompt.innerHTML='
              当前分数:'+event.score+'
              '; - if(event.score>=max){ + event.dialog.textPrompt.innerHTML = + '
              当前分数:' + + event.score + + "
              "; + if (event.score >= max) { event.settle(); } } - if(this.left<-15){ + if (this.left < -15) { this.remove(); this.pipe2.remove(); pipes.remove(this); } - } + }; }; - event.addPipe=setInterval(addPipe,2500); - } - else if(speed>0){ - speed=-4; + event.addPipe = setInterval(addPipe, 2500); + } else if (speed > 0) { + speed = -4; } }; - document.addEventListener(lib.config.touchscreen?'touchstart':'mousedown',fly); + document.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", fly); - event.settle=function(){ + event.settle = function () { clearInterval(event.fly); clearInterval(event.addPipe); - document.removeEventListener(lib.config.touchscreen?'touchstart':'mousedown',fly); - setTimeout(function(){ - event.switchToAuto() - },1000); + document.removeEventListener( + lib.config.touchscreen ? "touchstart" : "mousedown", + fly + ); + setTimeout(function () { + event.switchToAuto(); + }, 1000); }; game.pause(); game.countChoose(); }; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId); - if(event.isMine()){ + game.broadcastAll(createDialog, player, event.videoId); + if (event.isMine()) { chooseButton(); - } - else if(event.isOnline()){ + } else if (event.isOnline()) { event.player.send(chooseButton); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - game.broadcastAll(function(id,time){ - if(_status.connectMode) lib.configOL.choose_timeout=time; - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - },event.videoId,event.time); - var result=event.result||result; - player.popup(get.cnNumber(result.score)+'分',result.win?'wood':'fire') - game.log(player,'御风飞行',result.win?'#g成功':'#y失败'); - game.log(player,'获得了','#g'+result.score+'分'); - var max=player.countMark('yufeng'); - if(!result.win){ - if(result.score) player.draw(result.score); - if(max) player.removeMark('yufeng',max,false); + "step 1"; + game.broadcastAll( + function (id, time) { + if (_status.connectMode) lib.configOL.choose_timeout = time; + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + }, + event.videoId, + event.time + ); + var result = event.result || result; + player.popup(get.cnNumber(result.score) + "分", result.win ? "wood" : "fire"); + game.log(player, "御风飞行", result.win ? "#g成功" : "#y失败"); + game.log(player, "获得了", "#g" + result.score + "分"); + var max = player.countMark("yufeng"); + if (!result.win) { + if (result.score) player.draw(result.score); + if (max) player.removeMark("yufeng", max, false); event.finish(); + } else { + if (max < 2) player.addMark("yufeng", 1, false); + event.score = result.score; + player + .chooseTarget( + "请选择【御风】的目标", + [1, result.score], + function (card, player, target) { + return target != player && !target.hasSkill("yufeng2"); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = -get.attitude(player, target), + attx = att * 2; + if (att <= 0 || target.hasSkill("xinfu_pdgyingshi")) return 0; + if (target.hasJudge("lebu")) attx -= att; + if (target.hasJudge("bingliang")) attx -= att; + return attx / Math.max(2.25, Math.sqrt(target.countCards("h") + 1)); + }); } - else{ - if(max<2) player.addMark('yufeng',1,false); - event.score=result.score; - player.chooseTarget('请选择【御风】的目标',[1,result.score],function(card,player,target){ - return target!=player&&!target.hasSkill('yufeng2'); - }).set('ai',function(target){ - var player=_status.event.player; - var att=-get.attitude(player,target),attx=att*2; - if(att<=0||target.hasSkill('xinfu_pdgyingshi')) return 0; - if(target.hasJudge('lebu')) attx-=att; - if(target.hasJudge('bingliang')) attx-=att; - return attx/Math.max(2.25,Math.sqrt(target.countCards('h')+1)); - }); - } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { result.targets.sortBySeat(); - player.line(result.targets,'green'); - game.log(result.targets,'获得了','#y“御风”','效果'); - for(var i of result.targets) i.addSkill('yufeng2'); - if(event.score>result.targets.length) player.draw(event.score-result.targets.length); - } - else player.draw(event.score); + player.line(result.targets, "green"); + game.log(result.targets, "获得了", "#y“御风”", "效果"); + for (var i of result.targets) i.addSkill("yufeng2"); + if (event.score > result.targets.length) + player.draw(event.score - result.targets.length); + } else player.draw(event.score); + }, + ai: { + order: 10, + result: { player: 1 }, + threaten: 3.2, }, - ai:{ - order:10, - result:{player:1}, - threaten:3.2, - } }, - yufeng2:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:false, - forced:true, - charlotte:true, - content:function(){ - 'step 0' - player.removeSkill('yufeng2'); + yufeng2: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: false, + forced: true, + charlotte: true, + content: function () { + "step 0"; + player.removeSkill("yufeng2"); player.judge(); - 'step 1' - if(result.color=='red') player.skip('phaseDraw'); - else{ - player.skip('phaseUse'); - player.skip('phaseDiscard'); + "step 1"; + if (result.color == "red") player.skip("phaseDraw"); + else { + player.skip("phaseUse"); + player.skip("phaseDiscard"); } }, - mark:true, - intro:{ - content:'准备阶段时进行判定,结果为红则跳过摸牌阶段,为黑则跳过出牌阶段和弃牌阶段', + mark: true, + intro: { + content: "准备阶段时进行判定,结果为红则跳过摸牌阶段,为黑则跳过出牌阶段和弃牌阶段", }, - ai:{ - order:7, - result:{ - player:1, + ai: { + order: 7, + result: { + player: 1, }, }, }, - tianshu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('he')&&!game.hasPlayer(function(current){ - return current.countCards('ej','taipingyaoshu'); - }); + tianshu: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ( + player.countCards("he") && + !game.hasPlayer(function (current) { + return current.countCards("ej", "taipingyaoshu"); + }) + ); }, - direct:true, - content:function(){ - 'step 0' + direct: true, + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt2('tianshu'), - filterCard:true, - position:'he', - ai1:function(card){ - return 5-get.value(card); + prompt: get.prompt2("tianshu"), + filterCard: true, + position: "he", + ai1: function (card) { + return 5 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0&&!target.hasEmptySlot(2)) return 0; - return get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0 && !target.hasEmptySlot(2)) return 0; + return get.attitude(player, target); }, }); - 'step 1' - if(!result.bool){event.finish();return;} - var target=result.targets[0]; - event.target=target; - player.logSkill('tianshu',target); - player.discard(result.cards); - if(!lib.inpile.includes('taipingyaoshu')){ - lib.inpile.push('taipingyaoshu'); - event.card=game.createCard2('taipingyaoshu','heart',3); + "step 1"; + if (!result.bool) { + event.finish(); + return; } - else{ - event.card=get.cardPile(function(card){ - return card.name=='taipingyaoshu'; + var target = result.targets[0]; + event.target = target; + player.logSkill("tianshu", target); + player.discard(result.cards); + if (!lib.inpile.includes("taipingyaoshu")) { + lib.inpile.push("taipingyaoshu"); + event.card = game.createCard2("taipingyaoshu", "heart", 3); + } else { + event.card = get.cardPile(function (card) { + return card.name == "taipingyaoshu"; }); } - if(!event.card) event.finish(); - else target.gain(event.card,'gain2'); - 'step 2' - if(target.getCards('h').includes(card)&&get.name(card,target)=='taipingyaoshu') target.chooseUseTarget(card,'nopopup',true); + if (!event.card) event.finish(); + else target.gain(event.card, "gain2"); + "step 2"; + if (target.getCards("h").includes(card) && get.name(card, target) == "taipingyaoshu") + target.chooseUseTarget(card, "nopopup", true); }, }, //界伏寿 - xinzhuikong:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - check:function(event,player){ - if(get.attitude(player,event.player)<-2){ - var cards=player.getCards('h'); - if(cards.length>player.hp) return true; - for(var i=0;i7&&useful<7) return true; + xinzhuikong: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + check: function (event, player) { + if (get.attitude(player, event.player) < -2) { + var cards = player.getCards("h"); + if (cards.length > player.hp) return true; + for (var i = 0; i < cards.length; i++) { + var useful = get.useful(cards[i]); + if (useful < 5) return true; + if (cards[i].number > 7 && useful < 7) return true; } } return false; }, - logTarget:'player', - filter:function(event,player){ - return !player.hasSkill('xinzhuikong2')&&player.hp<=event.player.hp&&player.canCompare(event.player); + logTarget: "player", + filter: function (event, player) { + return ( + !player.hasSkill("xinzhuikong2") && + player.hp <= event.player.hp && + player.canCompare(event.player) + ); }, - content:function(){ - "step 0" - player.addTempSkill('xinzhuikong2','roundStart'); - player.chooseToCompare(trigger.player).set('small',(player.hp>1&&get.effect(player,{name:'sha'},trigger.player,player)>0&&Math.random()<0.9)); - "step 1" - if(result.bool){ - trigger.player.addTempSkill('zishou2'); + content: function () { + "step 0"; + player.addTempSkill("xinzhuikong2", "roundStart"); + player + .chooseToCompare(trigger.player) + .set( + "small", + player.hp > 1 && + get.effect(player, { name: "sha" }, trigger.player, player) > 0 && + Math.random() < 0.9 + ); + "step 1"; + if (result.bool) { + trigger.player.addTempSkill("zishou2"); event.finish(); - } - else if(result.target&&get.position(result.target)=='d') player.gain(result.target,'gain2','log'); - "step 2" - var card={name:'sha',isCard:true}; - if(trigger.player.canUse(card,player,false)) trigger.player.useCard(card,player,false); + } else if (result.target && get.position(result.target) == "d") + player.gain(result.target, "gain2", "log"); + "step 2"; + var card = { name: "sha", isCard: true }; + if (trigger.player.canUse(card, player, false)) + trigger.player.useCard(card, player, false); }, }, - xinzhuikong2:{charlotte:true}, - xinqiuyuan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&game.hasPlayer(function(current){ - return current!=player&&!event.targets.includes(current)&&lib.filter.targetEnabled(event.card,event.player,current); - }); + xinzhuikong2: { charlotte: true }, + xinqiuyuan: { + audio: 2, + trigger: { target: "useCardToTarget" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + game.hasPlayer(function (current) { + return ( + current != player && + !event.targets.includes(current) && + lib.filter.targetEnabled(event.card, event.player, current) + ); + }) + ); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('xinqiuyuan'),function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&!evt.targets.includes(target)&&lib.filter.targetEnabled(evt.card,evt.player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,trigger.player,player)+0.1; - }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('xinqiuyuan',target); - event.target=target; - target.chooseCard(function(card,player){ - var name=get.name(card,player); - return name!='sha'&&get.type(name)=='basic'; - },'h','交给'+get.translation(player)+ - '一张不为【杀】的基本牌,或成为此杀的额外目标').set('ai',function(card){ - return get.attitude(target,_status.event.sourcex)>=0?1:-1; - }).set('sourcex',player); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("xinqiuyuan"), function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled(evt.card, evt.player, target) + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, trigger.player, player) + 0.1; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("xinqiuyuan", target); + event.target = target; + target + .chooseCard( + function (card, player) { + var name = get.name(card, player); + return name != "sha" && get.type(name) == "basic"; + }, + "h", + "交给" + + get.translation(player) + + "一张不为【杀】的基本牌,或成为此杀的额外目标" + ) + .set("ai", function (card) { + return get.attitude(target, _status.event.sourcex) >= 0 ? 1 : -1; + }) + .set("sourcex", player); game.delay(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ - target.give(result.cards,player); + "step 2"; + if (result.bool) { + target.give(result.cards, player); game.delay(); - } - else{ + } else { trigger.getParent().targets.push(event.target); trigger.getParent().triggeredTargets2.push(event.target); - game.log(event.target,'成为了',trigger.card,'的额外目标'); + game.log(event.target, "成为了", trigger.card, "的额外目标"); } }, - ai:{ - expose:0.2, - effect:{ - target:function(card,player,target){ - if(card.name!='sha') return; - var players=game.filterPlayer(); - if(get.attitude(player,target)<=0){ - for(var i=0;i0&& - get.effect(target2,{name:'shacopy',nature:card.nature,suit:card.suit},player,player)<0){ - if(target.hp==target.maxHp) return 0.3; + ai: { + expose: 0.2, + effect: { + target: function (card, player, target) { + if (card.name != "sha") return; + var players = game.filterPlayer(); + if (get.attitude(player, target) <= 0) { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + target + ) > 0 && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) < 0 + ) { + if (target.hp == target.maxHp) return 0.3; return 0.6; } } - } - else{ - for(var i=0;i0){ - if(player.canUse(card,target2)) return; - if(target.hp==target.maxHp) return [0,1]; - return [0,0]; + } else { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) > 0 + ) { + if (player.canUse(card, target2)) return; + if (target.hp == target.maxHp) return [0, 1]; + return [0, 0]; } } } - } - } - } + }, + }, + }, }, //界潘璋马忠 - xinduodao:{ - audio:2, - trigger:{player:'damageEnd'}, - logTarget:'source', - filter:function(event,player){ - var source=event.source; - if(!source) return false; - var cards=source.getEquips(1); - return cards.some(card=>lib.filter.canBeGained(card,player,source)); + xinduodao: { + audio: 2, + trigger: { player: "damageEnd" }, + logTarget: "source", + filter: function (event, player) { + var source = event.source; + if (!source) return false; + var cards = source.getEquips(1); + return cards.some((card) => lib.filter.canBeGained(card, player, source)); }, - prompt2:function(event,player){ - var source=event.source; - var cards=source.getEquips(1).filter(card=>lib.filter.canBeGained(card,player,source)); - return '获得其装备区中的'+get.translation(cards); + prompt2: function (event, player) { + var source = event.source; + var cards = source + .getEquips(1) + .filter((card) => lib.filter.canBeGained(card, player, source)); + return "获得其装备区中的" + get.translation(cards); }, - check:function(event,player){ - return (get.attitude(player,event.source)+0.1)*get.value(event.source.getEquip(1),event.source); + check: function (event, player) { + return ( + (get.attitude(player, event.source) + 0.1) * + get.value(event.source.getEquip(1), event.source) + ); }, - content:function(){ - var source=trigger.source; - var cards=source.getEquips(1).filter(card=>lib.filter.canBeGained(card,player,source)); - player.gain(cards,source,'give','bySelf'); + content: function () { + var source = trigger.source; + var cards = source + .getEquips(1) + .filter((card) => lib.filter.canBeGained(card, player, source)); + player.gain(cards, source, "give", "bySelf"); }, }, - xinanjian:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - forced:true, - logTarget:'target', - filter:function(event,player){ - return event.card.name=='sha'&&!player.inRangeOf(event.target); + xinanjian: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + forced: true, + logTarget: "target", + filter: function (event, player) { + return event.card.name == "sha" && !player.inRangeOf(event.target); }, - content:function(){ - 'step 0' - var card=get.translation(trigger.card); - var target=get.translation(trigger.target); - player.chooseControl().set('prompt','暗箭:请选择一项').set('choiceList',[ - '令'+target+'不能响应'+card, - '令'+card+'对'+target+'的伤害值基数+1', - ]).set('ai',function(){ - var target=_status.event.getTrigger().target; - var player=_status.event.player; - var num=target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))?0:1; - if(get.attitude(player,target)>0) num=1-num; - return num; - }); - 'step 1' - if(result.index==0){ - game.log(player,'令',trigger.card,'不能被',trigger.target,'响应'); + content: function () { + "step 0"; + var card = get.translation(trigger.card); + var target = get.translation(trigger.target); + player + .chooseControl() + .set("prompt", "暗箭:请选择一项") + .set("choiceList", [ + "令" + target + "不能响应" + card, + "令" + card + "对" + target + "的伤害值基数+1", + ]) + .set("ai", function () { + var target = _status.event.getTrigger().target; + var player = _status.event.player; + var num = target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ? 0 + : 1; + if (get.attitude(player, target) > 0) num = 1 - num; + return num; + }); + "step 1"; + if (result.index == 0) { + game.log(player, "令", trigger.card, "不能被", trigger.target, "响应"); trigger.directHit.push(trigger.target); - } - else{ - game.log(player,'令',trigger.card,'对',trigger.target,'的伤害+1'); - var id=trigger.target.playerid; - var map=trigger.customArgs; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + } else { + game.log(player, "令", trigger.card, "对", trigger.target, "的伤害+1"); + var id = trigger.target.playerid; + var map = trigger.customArgs; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.target||arg.card.name!='sha'||arg.target.inRange(player)||get.attitude(player,arg.target)>0) return false; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + !arg || + !arg.card || + !arg.target || + arg.card.name != "sha" || + arg.target.inRange(player) || + get.attitude(player, arg.target) > 0 + ) + return false; }, }, }, //界郭笨 - mobilejingce:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - var num=0; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='cardsDiscard') return; - var evtx=evt.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evt2=(evtx.relatedEvent||evtx.getParent()); - if(evt2&&(evt2.name=='useCard'||evt2.name=='respond')) num+=evt.cards.length; + mobilejingce: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { + var num = 0; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "cardsDiscard") return; + var evtx = evt.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evt2 = evtx.relatedEvent || evtx.getParent(); + if (evt2 && (evt2.name == "useCard" || evt2.name == "respond")) + num += evt.cards.length; }); - return num>=player.hp; + return num >= player.hp; }, - content:function(){ + content: function () { player.draw(2); }, - group:'mobilejingce_count', - intro:{ - content:function(num,player){ - if(num==0) return '一张都没有?就这?'; - if(num 0; + if (bool1 && bool2 && target.hp <= evt.num + 1) return 2; + if (bool1) return 0; + return 1; }); - var bool2=get.effect(target,{name:'shunshou'},player,player)>0; - if(bool1&&bool2&&target.hp<=evt.num+1) return 2; - if(bool1) return 0; - return 1; - }); - 'step 1' - if(result.index==2){ - trigger.taomie_player=trigger.player; - trigger.player.addTempSkill('taomie4'); + "step 1"; + if (result.index == 2) { + trigger.taomie_player = trigger.player; + trigger.player.addTempSkill("taomie4"); } - if(result.index!=1){ + if (result.index != 1) { trigger.num++; } - if(result.index!=0&&trigger.player.countGainableCards(player,'hej')>0){ - player.gainPlayerCard(trigger.player,'hej',true); + if (result.index != 0 && trigger.player.countGainableCards(player, "hej") > 0) { + player.gainPlayerCard(trigger.player, "hej", true); + } else event.finish(); + "step 2"; + var card = result.cards[0]; + if ( + card && + player.getCards("h").includes(card) && + game.hasPlayer(function (current) { + return current != player && current != trigger.player; + }) + ) { + event.card = card; + player + .chooseTarget( + "是否将" + get.translation(card) + "交给一名其他角色?", + function (card, player, target) { + return target != player && target != _status.event.getTrigger().player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var card = _status.event.getParent().card; + if ( + target.hasSkillTag("nogain") || + !player.needsToDiscard() || + (get.tag(card, "damage") && + player.hasValueTarget(card, null, false) && + get.effect(_status.event.getTrigger().player, card, null, false) > 0) + ) + return 0; + return get.attitude(player, target) / (1 + target.countCards("h")); + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target); + player.give(card, target); } - else event.finish(); - 'step 2' - var card=result.cards[0]; - if(card&&player.getCards('h').includes(card)&&game.hasPlayer(function(current){ - return current!=player&¤t!=trigger.player; - })){ - event.card=card; - player.chooseTarget('是否将'+get.translation(card)+'交给一名其他角色?',function(card,player,target){ - return target!=player&&target!=_status.event.getTrigger().player; - }).set('ai',function(target){ - var player=_status.event.player; - var card=_status.event.getParent().card; - if(target.hasSkillTag('nogain')||!player.needsToDiscard()||(get.tag(card,'damage')&&player.hasValueTarget(card,null,false)&&get.effect(_status.event.getTrigger().player,card,null,false)>0)) return 0; - return get.attitude(player,target)/(1+target.countCards('h')); - }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target); - player.give(card,target); - } }, - mod:{ - inRangeOf:function(from,to){ - if(from.hasMark('taomie')) return true; + mod: { + inRangeOf: function (from, to) { + if (from.hasMark("taomie")) return true; }, - inRange:function(from,to){ - if(to.hasMark('taomie')) return true; + inRange: function (from, to) { + if (to.hasMark("taomie")) return true; }, }, - intro:{ - content:'mark', + intro: { + content: "mark", }, - ai:{ - effect:{ - player:function(card,player,target){ - if(target&&get.tag(card,'damage')&&target.hasMark('taomie')){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.attitude(player,target)>0){ + ai: { + effect: { + player: function (card, player, target) { + if (target && get.tag(card, "damage") && target.hasMark("taomie")) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.attitude(player, target) > 0) { return 0.7; } return 1.2; @@ -10297,255 +12670,295 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - taomie1:{ - audio:true, - trigger:{ - player:'damageEnd', - source:'damageSource', + taomie1: { + audio: true, + trigger: { + player: "damageEnd", + source: "damageSource", }, - logTarget:function(trigger,player){ - if(player==trigger.player) return trigger.source; + logTarget: function (trigger, player) { + if (player == trigger.player) return trigger.source; return trigger.player; }, - filter:function(event,player){ - var target=lib.skill.taomie1.logTarget(event,player); - return target&&target.isIn()&&!target.hasMark('taomie'); + filter: function (event, player) { + var target = lib.skill.taomie1.logTarget(event, player); + return target && target.isIn() && !target.hasMark("taomie"); }, - check:function(event,player){ - var target=lib.skill.taomie1.logTarget(event,player); - if(get.attitude(player,target)>0) return false; - var target0=game.findPlayer(function(current){ - return current.hasMark('taomie'); + check: function (event, player) { + var target = lib.skill.taomie1.logTarget(event, player); + if (get.attitude(player, target) > 0) return false; + var target0 = game.findPlayer(function (current) { + return current.hasMark("taomie"); }); - if(!target0) return true; - var eff1=0,eff2=0; - player.countCards('h',function(card){ - if(!get.tag(card,'damage')) return false; - if(player.hasValueTarget(card,null,true)>0){ - if(player.canUse(card,target,null,true)){ - var eff=get.effect(target,card,player,player); - if(eff>0) eff1+=eff; + if (!target0) return true; + var eff1 = 0, + eff2 = 0; + player.countCards("h", function (card) { + if (!get.tag(card, "damage")) return false; + if (player.hasValueTarget(card, null, true) > 0) { + if (player.canUse(card, target, null, true)) { + var eff = get.effect(target, card, player, player); + if (eff > 0) eff1 += eff; } - if(player.canUse(card,target0,null,true)){ - var eff=get.effect(target0,card,player,player); - if(eff>0) eff2+=eff; + if (player.canUse(card, target0, null, true)) { + var eff = get.effect(target0, card, player, player); + if (eff > 0) eff2 += eff; } } }); - return eff1>eff2; + return eff1 > eff2; }, - prompt2:function(event,player){ - var target=lib.skill.taomie1.logTarget(event,player); - var str='令'+get.translation(target)+'获得“讨灭”标记'; - if(game.hasPlayer(function(current){ - return current.hasMark('taomie'); - })) str+=',并移去场上已有的“讨灭”标记'; + prompt2: function (event, player) { + var target = lib.skill.taomie1.logTarget(event, player); + var str = "令" + get.translation(target) + "获得“讨灭”标记"; + if ( + game.hasPlayer(function (current) { + return current.hasMark("taomie"); + }) + ) + str += ",并移去场上已有的“讨灭”标记"; return str; }, - content:function(){ - game.countPlayer(function(current){ - var num=current.countMark('taomie'); - if(num) current.removeMark('taomie'); + content: function () { + game.countPlayer(function (current) { + var num = current.countMark("taomie"); + if (num) current.removeMark("taomie"); }); - lib.skill.taomie1.logTarget(trigger,player).addMark('taomie',1); + lib.skill.taomie1.logTarget(trigger, player).addMark("taomie", 1); }, }, - taomie2:{audio:true}, - taomie3:{audio:true}, - taomie4:{ - trigger:{ - global:['damageAfter','damageCancelled','damageZero'], - player:'dieBegin', + taomie2: { audio: true }, + taomie3: { audio: true }, + taomie4: { + trigger: { + global: ["damageAfter", "damageCancelled", "damageZero"], + player: "dieBegin", }, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.hasMark('taomie')&&(event.name=='die'||event.taomie_player==player); + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.hasMark("taomie") && (event.name == "die" || event.taomie_player == player); }, - content:function(){ - player.removeMark('taomie',player.countMark('taomie')); - player.removeSkill('taomie2'); + content: function () { + player.removeMark("taomie", player.countMark("taomie")); + player.removeSkill("taomie2"); }, }, //铁骑飞 - liyong:{ - audio:'retishen', - trigger:{player:'shaMiss'}, - forced:true, - filter:function(event,player){ + liyong: { + audio: "retishen", + trigger: { player: "shaMiss" }, + forced: true, + filter: function (event, player) { return player.isPhaseUsing(); }, - content:function(){ - trigger.getParent().liyong=true; - player.addTempSkill('liyong2','phaseUseEnd'); + content: function () { + trigger.getParent().liyong = true; + player.addTempSkill("liyong2", "phaseUseEnd"); }, }, - liyong2:{ - audio:'retishen', - mark:true, - intro:{ - content:'铁骑!强命!加伤!然后掉血嘞…', + liyong2: { + audio: "retishen", + mark: true, + intro: { + content: "铁骑!强命!加伤!然后掉血嘞…", }, - trigger:{player:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - if(!event.card||event.card.name!='sha') return false; - var evt=event.getParent(); - if(evt.liyong) return false; - var history=player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; + trigger: { player: "useCardToPlayered" }, + forced: true, + filter: function (event, player) { + if (!event.card || event.card.name != "sha") return false; + var evt = event.getParent(); + if (evt.liyong) return false; + var history = player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - var evt2=history[history.indexOf(evt)-1]; - return evt2&&evt2.liyong; + var evt2 = history[history.indexOf(evt) - 1]; + return evt2 && evt2.liyong; }, - logTarget:'target', - content:function(){ - var target=trigger.target; - target.addTempSkill('fengyin'); + logTarget: "target", + content: function () { + var target = trigger.target; + target.addTempSkill("fengyin"); trigger.directHit.add(target); - var id=target.playerid; - var map=trigger.customArgs; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + var id = target.playerid; + var map = trigger.customArgs; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; - trigger.getParent().liyong2=true; + trigger.getParent().liyong2 = true; }, - group:['liyong3','liyong4'], + group: ["liyong3", "liyong4"], }, - liyong3:{ - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&& - event.player.isIn()&&event.getParent(2).liyong2==true; + liyong3: { + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.player.isIn() && + event.getParent(2).liyong2 == true + ); }, - content:function(){ + content: function () { player.loseHp(); }, }, - liyong4:{ - trigger:{player:'useCardAfter'}, - forced:true, - silent:true, - filter:function(evt,player){ - if(!evt.card||evt.card.name!='sha') return false; - if(evt.liyong) return false; - var history=player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; + liyong4: { + trigger: { player: "useCardAfter" }, + forced: true, + silent: true, + filter: function (evt, player) { + if (!evt.card || evt.card.name != "sha") return false; + if (evt.liyong) return false; + var history = player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - var evt2=history[history.indexOf(evt)-1]; - return evt2&&evt2.liyong; + var evt2 = history[history.indexOf(evt) - 1]; + return evt2 && evt2.liyong; }, - content:function(){ - player.removeSkill('liyong2'); + content: function () { + player.removeSkill("liyong2"); }, }, //韩遂 - xinniluan:{ - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&event.player.getHistory('useCard',function(evt){ - if(evt.targets&&evt.targets.length){ - var targets=evt.targets.slice(0); - while(targets.includes(event.player)) targets.remove(event.player); - return targets.length>0; - } - return false; - }).length>0&&(_status.connectMode||player.hasSha()); + xinniluan: { + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.isIn() && + event.player.getHistory("useCard", function (evt) { + if (evt.targets && evt.targets.length) { + var targets = evt.targets.slice(0); + while (targets.includes(event.player)) targets.remove(event.player); + return targets.length > 0; + } + return false; + }).length > 0 && + (_status.connectMode || player.hasSha()) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToUse({ - logSkill:'xinniluan', - preTarget:trigger.player, - prompt:'是否发动【逆乱】,对'+get.translation(trigger.player)+'使用一张【杀】?', - filterCard:function(card,player){ - return get.name(card)=='sha'&&lib.filter.filterCard.apply(this,arguments); + logSkill: "xinniluan", + preTarget: trigger.player, + prompt: "是否发动【逆乱】,对" + get.translation(trigger.player) + "使用一张【杀】?", + filterCard: function (card, player) { + return get.name(card) == "sha" && lib.filter.filterCard.apply(this, arguments); }, - filterTarget:function(card,player,target){ - return target==_status.event.preTarget&&lib.filter.targetEnabled.apply(this,arguments); + filterTarget: function (card, player, target) { + return ( + target == _status.event.preTarget && + lib.filter.targetEnabled.apply(this, arguments) + ); }, - addCount:false, + addCount: false, }); - 'step 1' - if(result.bool&&player.getHistory('sourceDamage',function(evt){ - return evt.getParent(4)==event; - }).length&&trigger.player.countDiscardableCards(player,'he')>0) player.discardPlayerCard(trigger.player,true,'he').boolline=true; + "step 1"; + if ( + result.bool && + player.getHistory("sourceDamage", function (evt) { + return evt.getParent(4) == event; + }).length && + trigger.player.countDiscardableCards(player, "he") > 0 + ) + player.discardPlayerCard(trigger.player, true, "he").boolline = true; }, }, - xiaoxi_hansui:{ - audio:2, - enable:['chooseToRespond','chooseToUse'], - filterCard:function(card,player){ - return get.color(card)=='black'; + xiaoxi_hansui: { + audio: 2, + enable: ["chooseToRespond", "chooseToUse"], + filterCard: function (card, player) { + return get.color(card) == "black"; }, - position:'hse', - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(!player.countCards('hse',{color:'black'})) return false; + position: "hse", + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (!player.countCards("hse", { color: "black" })) return false; }, - prompt:'将一张黑色牌当杀使用或打出', - check:function(card){return 4.5-get.value(card)}, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('hes',{color:'black'})) return false; + prompt: "将一张黑色牌当杀使用或打出", + check: function (card) { + return 4.5 - get.value(card); + }, + ai: { + skillTagFilter: function (player) { + if (!player.countCards("hes", { color: "black" })) return false; }, - respondSha:true, - } + respondSha: true, + }, }, //胡车儿 - daoji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',function(card){ - return get.type(card)!='basic'; - })&&game.hasPlayer(function(target){ - return target!=player&&target.countCards('e')>0; - }); + daoji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + return get.type(card) != "basic"; + }) && + game.hasPlayer(function (target) { + return target != player && target.countCards("e") > 0; + }) + ); }, - filterCard:function(card){ - return get.type(card)!='basic'; + filterCard: function (card) { + return get.type(card) != "basic"; }, - position:'he', - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('e')>0; + position: "he", + filterTarget: function (card, player, target) { + return target != player && target.countCards("e") > 0; }, - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)<0&&get.damageEffect(current,player,player)>0&¤t.getEquip(1); - })) return 8-get.value(card); - return 5-get.value(card) + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) < 0 && + get.damageEffect(current, player, player) > 0 && + current.getEquip(1) + ); + }) + ) + return 8 - get.value(card); + return 5 - get.value(card); }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'e',true).set('ai',function(button){ - var card=button.link; - var player=_status.event.player; - if(get.subtype(card)=='equip1'&&get.damageEffect(_status.event.target,player,player)>0) return 6+get.value(card); + content: function () { + "step 0"; + player.gainPlayerCard(target, "e", true).set("ai", function (button) { + var card = button.link; + var player = _status.event.player; + if ( + get.subtype(card) == "equip1" && + get.damageEffect(_status.event.target, player, player) > 0 + ) + return 6 + get.value(card); return get.value(card); }); - 'step 1' - if(!result||!result.bool||!result.cards||!result.cards.length){ + "step 1"; + if (!result || !result.bool || !result.cards || !result.cards.length) { event.finish(); return; } - var card=result.cards[0]; - event.card=card; - if(player.getCards('h').includes(card)&&get.type(card)=='equip') player.chooseUseTarget(card,true).nopopup=true; - 'step 2' - if(get.subtype(card,false)=='equip1') target.damage(); + var card = result.cards[0]; + event.card = card; + if (player.getCards("h").includes(card) && get.type(card) == "equip") + player.chooseUseTarget(card, true).nopopup = true; + "step 2"; + if (get.subtype(card, false) == "equip1") target.damage(); }, - ai:{ - order:6, - result:{ - target:function(player,current){ - if(get.damageEffect(current,player,player)>0&¤t.getEquip(1)) return -1.5; + ai: { + order: 6, + result: { + target: function (player, current) { + if (get.damageEffect(current, player, player) > 0 && current.getEquip(1)) + return -1.5; return -1; }, }, @@ -10553,213 +12966,246 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //司马师夫妇 //垃圾 - baiyi:{ - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - selectTarget:2, - limited:true, - skillAnimation:false, + baiyi: { + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + selectTarget: 2, + limited: true, + skillAnimation: false, //animationColor:'thunder', - filter:function(event,player){ - return player.isDamaged()&&game.players.length>2; + filter: function (event, player) { + return player.isDamaged() && game.players.length > 2; }, - multitarget:true, - multiline:true, - changeSeat:true, - contentBefore:function(){ - player.$fullscreenpop('败移','thunder'); + multitarget: true, + multiline: true, + changeSeat: true, + contentBefore: function () { + player.$fullscreenpop("败移", "thunder"); }, - content:function(){ - player.awakenSkill('baiyi'); - game.broadcastAll(function(target1,target2){ - game.swapSeat(target1,target2); - },targets[0],targets[1]) + content: function () { + player.awakenSkill("baiyi"); + game.broadcastAll( + function (target1, target2) { + game.swapSeat(target1, target2); + }, + targets[0], + targets[1] + ); }, - ai:{ - order:function(){ - return get.order({name:'tao'})+1; + ai: { + order: function () { + return get.order({ name: "tao" }) + 1; }, - result:{ - target:function(player,target){ - if(player.hasUnknown()&&target!=player.next&&target!=player.previous) return 0; - var distance=Math.pow(get.distance(player,target,'absolute'),2); - if(!ui.selected.targets.length) return distance; - var distance2=Math.pow(get.distance(player,ui.selected.targets[0],'absolute'),2); - return Math.min(0,distance-distance2); - } + result: { + target: function (player, target) { + if (player.hasUnknown() && target != player.next && target != player.previous) + return 0; + var distance = Math.pow(get.distance(player, target, "absolute"), 2); + if (!ui.selected.targets.length) return distance; + var distance2 = Math.pow( + get.distance(player, ui.selected.targets[0], "absolute"), + 2 + ); + return Math.min(0, distance - distance2); + }, }, }, }, - jinglve:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.hasSkill('jinglve2')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; + jinglve: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.hasSkill("jinglve2")) return false; + return game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; }); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - if(!player.storage.jinglve4) player.storage.jinglve4=[]; + content: function () { + "step 0"; + if (!player.storage.jinglve4) player.storage.jinglve4 = []; player.storage.jinglve4.add(target); - player.chooseButton(['选择一张牌作为「死士」',target.getCards('h')],true).set('ai',function(button){ - var target=_status.event.getParent().target; - var card=button.link; - var val=target.getUseValue(card); - if(val>0) return val; - return get.value(card); - }); - 'step 1' - if(result.bool){ - player.storage.jinglve2=target; - player.storage.jinglve3=result.links[0]; - player.addSkill('jinglve2'); + player + .chooseButton(["选择一张牌作为「死士」", target.getCards("h")], true) + .set("ai", function (button) { + var target = _status.event.getParent().target; + var card = button.link; + var val = target.getUseValue(card); + if (val > 0) return val; + return get.value(card); + }); + "step 1"; + if (result.bool) { + player.storage.jinglve2 = target; + player.storage.jinglve3 = result.links[0]; + player.addSkill("jinglve2"); } }, - ai:{ - order:12, - result:{ - target:-1, + ai: { + order: 12, + result: { + target: -1, }, }, }, - jinglve2:{ - mark:true, - intro:{ - name:'死士', - mark:function(dialog,content,player){ - dialog.addText('记录目标'); + jinglve2: { + mark: true, + intro: { + name: "死士", + mark: function (dialog, content, player) { + dialog.addText("记录目标"); dialog.add([content]); - if(player==game.me||player.isUnderControl()){ - dialog.addText('死士牌'); + if (player == game.me || player.isUnderControl()) { + dialog.addText("死士牌"); dialog.add([player.storage.jinglve3]); } }, }, - onremove:function(player){ + onremove: function (player) { delete player.storage.jinglve2; delete player.storage.jinglve3; }, - trigger:{global:['dieEnd','loseEnd','gainEnd']}, - silent:true, - lastDo:true, - charlotte:true, - filter:function(event,player){ - if(event.name!='gain'&&event.player!=player.storage.jinglve2) return false; - return event.name=='die'||(event.cards.includes(player.storage.jinglve3)&&(event.name=='gain'||event.position!=ui.ordering&&event.position!=ui.discardPile)); + trigger: { global: ["dieEnd", "loseEnd", "gainEnd"] }, + silent: true, + lastDo: true, + charlotte: true, + filter: function (event, player) { + if (event.name != "gain" && event.player != player.storage.jinglve2) return false; + return ( + event.name == "die" || + (event.cards.includes(player.storage.jinglve3) && + (event.name == "gain" || + (event.position != ui.ordering && event.position != ui.discardPile))) + ); }, - content:function(){ - player.removeSkill('jinglve2'); + content: function () { + player.removeSkill("jinglve2"); }, - group:'jinglve3', + group: "jinglve3", }, - jinglve3:{ - audio:'jinglve', - trigger:{global:['loseAfter','useCard','phaseAfter','cardsDiscardAfter','loseAsyncAfter']}, - filter:function(event,player){ - if(event.player&&event.player!=player.storage.jinglve2) return false; - var card=player.storage.jinglve3; - if(event.name=='phase') return event.player.getCards('hej').includes(card); - if(event.name=='useCard') return event.cards.includes(card); - return (get.position(card,true)=='d'&&event.getd().includes(card)); + jinglve3: { + audio: "jinglve", + trigger: { + global: ["loseAfter", "useCard", "phaseAfter", "cardsDiscardAfter", "loseAsyncAfter"], }, - forced:true, - charlotte:true, - logTarget:'player', - content:function(){ - if(trigger.name=='useCard'){ - trigger.all_excluded=true; - trigger.targets.length=0; + filter: function (event, player) { + if (event.player && event.player != player.storage.jinglve2) return false; + var card = player.storage.jinglve3; + if (event.name == "phase") return event.player.getCards("hej").includes(card); + if (event.name == "useCard") return event.cards.includes(card); + return get.position(card, true) == "d" && event.getd().includes(card); + }, + forced: true, + charlotte: true, + logTarget: "player", + content: function () { + if (trigger.name == "useCard") { + trigger.all_excluded = true; + trigger.targets.length = 0; + } else { + if (trigger.name == "phase") { + player.gain(player.storage.jinglve3, trigger.player, "giveAuto", "bySelf"); + } else if (get.position(player.storage.jinglve3, true) == "d") + player.gain(player.storage.jinglve3, "gain2"); } - else{ - if(trigger.name=='phase'){ - player.gain(player.storage.jinglve3,trigger.player,'giveAuto','bySelf'); - } - else if(get.position(player.storage.jinglve3,true)=='d') player.gain(player.storage.jinglve3,'gain2'); - } - player.removeSkill('jinglve2'); + player.removeSkill("jinglve2"); }, }, - shanli:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.storage.baiyi&&player.getStorage('jinglve4').length>1; + shanli: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.storage.baiyi && player.getStorage("jinglve4").length > 1; }, - content:function(){ - 'step 0' - player.awakenSkill('shanli'); + content: function () { + "step 0"; + player.awakenSkill("shanli"); player.loseMaxHp(); - player.chooseTarget(true,'选择【擅立】的目标').set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target==game.me||target.isUnderControl()&&target.isOnline()) return 2*att; + player.chooseTarget(true, "选择【擅立】的目标").set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target == game.me || (target.isUnderControl() && target.isOnline())) + return 2 * att; return att; }); - 'step 1' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - game.log(player,'拥立',target); - var list=[]; - if(!_status.characterlist){ - if(_status.connectMode) var list=get.charactersOL(); - else{ - var list=[]; - for(var i in lib.character){ - if(lib.filter.characterDisabled2(i)||lib.filter.characterDisabled(i)) continue; + "step 1"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + game.log(player, "拥立", target); + var list = []; + if (!_status.characterlist) { + if (_status.connectMode) var list = get.charactersOL(); + else { + var list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled2(i) || lib.filter.characterDisabled(i)) + continue; list.push(i); } } - game.countPlayer2(function(current){ + game.countPlayer2(function (current) { list.remove(current.name); list.remove(current.name1); list.remove(current.name2); - if(current.storage.rehuashen&¤t.storage.rehuashen.character) list.removeArray(current.storage.rehuashen.character) + if (current.storage.rehuashen && current.storage.rehuashen.character) + list.removeArray(current.storage.rehuashen.character); }); - _status.characterlist=list; + _status.characterlist = list; } _status.characterlist.randomSort(); - var chara=[]; - var skills=[]; - for(var i of _status.characterlist){ - if(i=='key_yuri') continue; - var character=lib.character[i]; - if(character&&character[3]){ - for(var j of character[3]){ - if(skills.includes(j)||j=='yuri_wangxi'||target.hasSkill('j')) continue; - var info=get.info(j); - if(info&&info.zhuSkill){ + var chara = []; + var skills = []; + for (var i of _status.characterlist) { + if (i == "key_yuri") continue; + var character = lib.character[i]; + if (character && character[3]) { + for (var j of character[3]) { + if (skills.includes(j) || j == "yuri_wangxi" || target.hasSkill("j")) + continue; + var info = get.info(j); + if (info && info.zhuSkill) { skills.add(j); chara.add(i); continue; } } } - if(skills.length>=3) break; + if (skills.length >= 3) break; } - if(!skills.length){event.finish();return} - event.chara=chara; - event.skills=skills; - player.chooseControl(skills).set('dialog',['选择令'+get.translation(target)+'获得一个技能',[chara,'character']]); - 'step 2' + if (!skills.length) { + event.finish(); + return; + } + event.chara = chara; + event.skills = skills; + player + .chooseControl(skills) + .set("dialog", [ + "选择令" + get.translation(target) + "获得一个技能", + [chara, "character"], + ]); + "step 2"; target.addSkills(result.control); - target.setAvatarQueue(target.name1||target.name,[event.chara[event.skills.indexOf(result.control)]]); + target.setAvatarQueue(target.name1 || target.name, [ + event.chara[event.skills.indexOf(result.control)], + ]); + }, + ai: { + combo: "baiyi" }, }, - hongyi:{ - audio:2, - enable:'phaseUse', - usable:1, + hongyi: { + audio: 2, + enable: "phaseUse", + usable: 1, //filter:function(event,player){ // return player.countCards('he')>=Math.min(2,game.dead.length); //}, @@ -10767,205 +13213,252 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // return Math.min(2,game.dead.length); //}, //filterCard:true, - filterTarget:lib.filter.notMe, - check:function(card){ - var num=Math.min(2,game.dead.length); - if(!num) return 1; - if(num==1) return 7-get.value(card); - return 5-get.value(card); + filterTarget: lib.filter.notMe, + check: function (card) { + var num = Math.min(2, game.dead.length); + if (!num) return 1; + if (num == 1) return 7 - get.value(card); + return 5 - get.value(card); }, - position:'he', - content:function(){ - player.addTempSkill('hongyi2',{player:'phaseBeginStart'}); + position: "he", + content: function () { + player.addTempSkill("hongyi2", { player: "phaseBeginStart" }); player.storage.hongyi2.add(target); - player.markSkill('hongyi2'); + player.markSkill("hongyi2"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.hasJudge('lebu')) return -0.5; - return -1-target.countCards('h'); + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.hasJudge("lebu")) return -0.5; + return -1 - target.countCards("h"); }, }, }, }, - hongyi2:{ - audio:'hongyi', - trigger:{global:'damageBegin1'}, - charlotte:true, - forced:true, - logTarget:'source', - filter:function(event,player){ + hongyi2: { + audio: "hongyi", + trigger: { global: "damageBegin1" }, + charlotte: true, + forced: true, + logTarget: "source", + filter: function (event, player) { return player.storage.hongyi2.includes(event.source); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.source.judge(); - 'step 1' - if(result.color=='black') trigger.num--; + "step 1"; + if (result.color == "black") trigger.num--; else trigger.player.draw(); }, - onremove:true, - intro:{ - content:'已选中$为技能目标', + onremove: true, + intro: { + content: "已选中$为技能目标", }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, }, - requanfeng:{ - audio:'quanfeng', - enable:'chooseToUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return event.type=='dying'&&player==event.dying; + requanfeng: { + audio: "quanfeng", + enable: "chooseToUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return event.type == "dying" && player == event.dying; }, - content:function(){ - player.awakenSkill('requanfeng'); + content: function () { + player.awakenSkill("requanfeng"); player.gainMaxHp(2); player.recover(4); }, - ai:{ - save:true, - skillTagFilter:function(player,tag,arg){ - return player==arg; + ai: { + save: true, + skillTagFilter: function (player, tag, arg) { + return player == arg; }, - order:10, - result:{ - player:1, + order: 10, + result: { + player: 1, }, }, - group:'requanfeng_gain', + group: "requanfeng_gain", }, - requanfeng_gain:{ - audio:'quanfeng', - trigger:{global:'die'}, - filter:function(event,player){ - return player.hasSkill('hongyi')&&event.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; - }).length>0; + requanfeng_gain: { + audio: "quanfeng", + trigger: { global: "die" }, + filter: function (event, player) { + return ( + player.hasSkill("hongyi") && + event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; + }).length > 0 + ); }, - logTarget:'player', - skillAnimation:true, - animationColor:'thunder', - prompt2:'(限定技)失去技能【劝封】,并获得该角色武将牌上的所有技能,然后加1点体力上限并回复1点体力', - check:(event,player)=>{ - if(event.player.getStockSkills('仲村由理','天下第一').filter(skill=>{ - let info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; - }).some(i=>{ - let info=get.info(i); - if(info&&info.ai) return info.ai.neg||info.ai.halfneg; - })) return false; + logTarget: "player", + skillAnimation: true, + animationColor: "thunder", + prompt2: + "(限定技)失去技能【劝封】,并获得该角色武将牌上的所有技能,然后加1点体力上限并回复1点体力", + check: (event, player) => { + if ( + event.player + .getStockSkills("仲村由理", "天下第一") + .filter((skill) => { + let info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; + }) + .some((i) => { + let info = get.info(i); + if (info && info.ai) return info.ai.neg || info.ai.halfneg; + }) + ) + return false; return true; }, - content:function(){ - player.awakenSkill('requanfeng'); - player.removeSkills('hongyi'); - var skills=trigger.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; - }); - if(skills.length){ + content: function () { + player.awakenSkill("requanfeng"); + player.removeSkills("hongyi"); + var skills = trigger.player + .getStockSkills("仲村由理", "天下第一") + .filter(function (skill) { + var info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; + }); + if (skills.length) { player.addSkills(skills); - game.broadcastAll(function(list){ + game.broadcastAll(function (list) { game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.yanghuiyu='quanfeng'; + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.yanghuiyu = "quanfeng"; } - },skills); + }, skills); } player.gainMaxHp(); player.recover(); - } - }, - quanfeng:{ - audio:2, - trigger:{global:'die'}, - filter:function(event,player){ - return event.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; - }).length>0; }, - logTarget:'player', - skillAnimation:true, - limited:true, - forced:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.awakenSkill('quanfeng'); - var list=trigger.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; + }, + quanfeng: { + audio: 2, + trigger: { global: "die" }, + filter: function (event, player) { + return ( + event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); + }).length > 0 + ); + }, + logTarget: "player", + skillAnimation: true, + limited: true, + forced: true, + animationColor: "thunder", + content: function () { + "step 0"; + player.awakenSkill("quanfeng"); + var list = trigger.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); }); - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('prompt','选择获得'+get.translation(trigger.player)+'的一个技能').set('forceDie',true).set('ai',function(){ - return list.randomGet(); - }); - 'step 1' + if (list.length == 1) event._result = { control: list[0] }; + else + player + .chooseControl(list) + .set("prompt", "选择获得" + get.translation(trigger.player) + "的一个技能") + .set("forceDie", true) + .set("ai", function () { + return list.randomGet(); + }); + "step 1"; player.addSkills(result.control); - game.broadcastAll(function(skill){ - var list=[skill];game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.yanghuiyu='quanfeng'; + game.broadcastAll(function (skill) { + var list = [skill]; + game.expandSkills(list); + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.yanghuiyu = "quanfeng"; } - },result.control); + }, result.control); player.gainMaxHp(); player.recover(); }, }, //手杀界朱然 //设计师你改技能有瘾🐴 - mobiledanshou:{ - trigger:{global:'phaseJieshuBegin'}, - audio:2, - direct:true, - filter:function(event,player){ - if(player==event.player) return false; - var num=event.player.getHistory('useCard',function(evt){ + mobiledanshou: { + trigger: { global: "phaseJieshuBegin" }, + audio: 2, + direct: true, + filter: function (event, player) { + if (player == event.player) return false; + var num = event.player.getHistory("useCard", function (evt) { return evt.targets.includes(player); }).length; - return num==0||event.player.isIn()&&num<=player.countCards('he'); + return num == 0 || (event.player.isIn() && num <= player.countCards("he")); }, - content:function(){ - 'step 0' - var num=trigger.player.getHistory('useCard',function(evt){ + content: function () { + "step 0"; + var num = trigger.player.getHistory("useCard", function (evt) { return evt.targets.includes(player); }).length; - event.num=num; - if(num==0){ - if(player.hasSkill('mobiledanshou')) event._result={bool:true}; - else player.chooseBool('是否发动【胆守】摸一张牌?',lib.translate.mobiledanshou_info); - } - else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('mobiledanshou'); + event.num = num; + if (num == 0) { + if (player.hasSkill("mobiledanshou")) event._result = { bool: true }; + else + player.chooseBool("是否发动【胆守】摸一张牌?", lib.translate.mobiledanshou_info); + } else event.goto(2); + "step 1"; + if (result.bool) { + player.logSkill("mobiledanshou"); player.draw(); } event.finish(); - 'step 2' - player.chooseToDiscard(num,get.prompt('mobiledanshou',trigger.player),'弃置'+get.translation(num)+'张牌并对其造成1点伤害','he').set('ai',function(card){ - if(!_status.event.goon) return 0; - var num=_status.event.getParent().num; - if(num==1) return 8-get.value(card); - if(num==2) return 6.5-get.value(card); - return 5-get.value(card); - }).set('goon',get.damageEffect(trigger.player,player,player)>0).logSkill=['mobiledanshou',trigger.player]; - 'step 3' - if(result.bool){ + "step 2"; + player + .chooseToDiscard( + num, + get.prompt("mobiledanshou", trigger.player), + "弃置" + get.translation(num) + "张牌并对其造成1点伤害", + "he" + ) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + var num = _status.event.getParent().num; + if (num == 1) return 8 - get.value(card); + if (num == 2) return 6.5 - get.value(card); + return 5 - get.value(card); + }) + .set("goon", get.damageEffect(trigger.player, player, player) > 0).logSkill = [ + "mobiledanshou", + trigger.player, + ]; + "step 3"; + if (result.bool) { player.addExpose(0.2); trigger.player.damage(); } @@ -10973,128 +13466,144 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //丁原 //程序员和设计师至少有一个脑子有坑 - beizhu:{ - audio:3, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(target){ - return lib.skill.beizhu.filterTarget(null,player,target); + beizhu: { + audio: 3, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (target) { + return lib.skill.beizhu.filterTarget(null, player, target); }); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.addTempSkill('beizhu_draw'); + content: function () { + "step 0"; + player.addTempSkill("beizhu_draw"); player.viewHandcards(target); - 'step 1' - var cards=target.getCards('h','sha'); - if(cards.length){ - event.cards=cards; + "step 1"; + var cards = target.getCards("h", "sha"); + if (cards.length) { + event.cards = cards; event.goto(5); - } - else player.discardPlayerCard('he',target,'visible',true); - 'step 2' - player.chooseBool('是否令'+get.translation(target)+'获得一张【杀】?').set('choice',get.attitude(player,target)>0); - 'step 3' - if(result.bool){ - var card=get.cardPile2(function(card){ - return card.name=='sha'; + } else player.discardPlayerCard("he", target, "visible", true); + "step 2"; + player + .chooseBool("是否令" + get.translation(target) + "获得一张【杀】?") + .set("choice", get.attitude(player, target) > 0); + "step 3"; + if (result.bool) { + var card = get.cardPile2(function (card) { + return card.name == "sha"; }); - if(card) target.gain(card,'gain2'); - } - else event.finish(); - 'step 4' + if (card) target.gain(card, "gain2"); + } else event.finish(); + "step 4"; game.updateRoundNumber(); event.finish(); - 'step 5' - var hs=target.getCards('h'); - cards=cards.filter(function(card){ - return hs.includes(card)&&get.name(card,target)=='sha'&&target.canUse({ - name:'sha', - isCard:true, - cards:[card], - },player,false); + "step 5"; + var hs = target.getCards("h"); + cards = cards.filter(function (card) { + return ( + hs.includes(card) && + get.name(card, target) == "sha" && + target.canUse( + { + name: "sha", + isCard: true, + cards: [card], + }, + player, + false + ) + ); }); - if(cards.length){ - var card=cards.randomRemove(1)[0]; - target.useCard(player,false,card).card.beizhu=true; + if (cards.length) { + var card = cards.randomRemove(1)[0]; + target.useCard(player, false, card).card.beizhu = true; event.redo(); } }, - ai:{ - order:7, - threaten:1.14+5.14, - result:{ - player:function(player,target){ - var eff=get.effect(target,{name:'guohe_copy2'},player,player); - var cards=target.getCards('h',{name:'sha'}); - if(!cards.length) return eff; - return eff/(cards.length+3); + ai: { + order: 7, + threaten: 1.14 + 5.14, + result: { + player: function (player, target) { + var eff = get.effect(target, { name: "guohe_copy2" }, player, player); + var cards = target.getCards("h", { name: "sha" }); + if (!cards.length) return eff; + return eff / (cards.length + 3); }, }, }, }, - beizhu_draw:{ - trigger:{player:'damageEnd'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return event.card&&event.card.beizhu; + beizhu_draw: { + trigger: { player: "damageEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return event.card && event.card.beizhu; }, - content:function(){ + content: function () { player.draw(trigger.num); }, }, //新简雍 - xinqiaoshui:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + xinqiaoshui: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool) player.addTempSkill('qiaoshui3','phaseUseEnd'); - else{ - player.addTempSkill('qiaoshui2','phaseUseEnd'); + "step 1"; + if (result.bool) player.addTempSkill("qiaoshui3", "phaseUseEnd"); + else { + player.addTempSkill("qiaoshui2", "phaseUseEnd"); } }, - ai:{ - order:function(item,player){ - if(player.countCards('h',function(card){ - return player.hasValueTarget(card); - })) return 10; + ai: { + order: function (item, player) { + if ( + player.countCards("h", function (card) { + return player.hasValueTarget(card); + }) + ) + return 10; return 1; }, - result:{ - target:function(player,target){ - if(player.countCards('h',function(card){ - return player.hasValueTarget(card); - })){ - if(player.hasSkill('qiaoshui3')) return 0; - var nd=!player.needsToDiscard(); - if(player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card) - if(nd&&val<0) return true; - if(val<=5){ - return card.number>=12; - } - if(val<=6){ - return card.number>=13; - } - return false; - })) return -1; + result: { + target: function (player, target) { + if ( + player.countCards("h", function (card) { + return player.hasValueTarget(card); + }) + ) { + if (player.hasSkill("qiaoshui3")) return 0; + var nd = !player.needsToDiscard(); + if ( + player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (nd && val < 0) return true; + if (val <= 5) { + return card.number >= 12; + } + if (val <= 6) { + return card.number >= 13; + } + return false; + }) + ) + return -1; return 0; } return -1; @@ -11102,859 +13611,968 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - xinjyzongshi:{ - audio:2, - trigger:{ - player:['chooseToCompareAfter','compareMultipleAfter'], - target:['chooseToCompareAfter','compareMultipleAfter'] + xinjyzongshi: { + audio: 2, + trigger: { + player: ["chooseToCompareAfter", "compareMultipleAfter"], + target: ["chooseToCompareAfter", "compareMultipleAfter"], }, - filter:function(event,player){ - if(event.preserve) return false; - if(event.name=='compareMultiple') return true; + filter: function (event, player) { + if (event.preserve) return false; + if (event.name == "compareMultiple") return true; return !event.compareMultiple; }, - frequent:true, - content:function(){ - 'step 0' - var str='
              牌堆顶'; - var cards=get.cards(); - if(trigger.name=='chooseToCompare'&&trigger.compareMeanwhile){ - var result=trigger.result; - var list=[[result.num1[0],result.player]]; - list.addArray(result.num2.map(function(card,i){ - return [card,result.targets[i]]; - })); - list.sort(function(a,b){ - return a[0]-b[0]; + frequent: true, + content: function () { + "step 0"; + var str = '
              牌堆顶'; + var cards = get.cards(); + if (trigger.name == "chooseToCompare" && trigger.compareMeanwhile) { + var result = trigger.result; + var list = [[result.num1[0], result.player]]; + list.addArray( + result.num2.map(function (card, i) { + return [card, result.targets[i]]; + }) + ); + list.sort(function (a, b) { + return a[0] - b[0]; }); - if(list[0][0]trigger.num2&&get.position(trigger.card2,true)=='o'){ - str+='/拼点牌'; - cards.push(trigger.card2) - } - else if(trigger.num1 trigger.num2 && get.position(trigger.card2, true) == "o") { + str += "/拼点牌"; + cards.push(trigger.card2); + } else if ( + trigger.num1 < trigger.num2 && + get.position(trigger.card1, true) == "o" + ) { + str += "/拼点牌"; cards.push(trigger.card1); } - } - else{ - if(trigger.num1trigger.num2&&get.position(trigger.card2,true)=='o'){ - str+='/拼点牌'; + } else if ( + trigger.num1 > trigger.num2 && + get.position(trigger.card2, true) == "o" + ) { + str += "/拼点牌"; cards.push(trigger.card2); } } } - str+='
              '; - event.cards=cards; - player.chooseButton(['纵适:选择要获得的牌',str,cards],true).set('ai',get.buttonValue); - 'step 1' - if(result.bool){ - var draw=result.links[0]==cards[0]; - player.gain(result.links,draw?'draw':'gain2').log=false; - game.log(player,'获得了',draw?'牌堆顶的一张牌':result.links); - if(!draw){ + str += "
              "; + event.cards = cards; + player + .chooseButton(["纵适:选择要获得的牌", str, cards], true) + .set("ai", get.buttonValue); + "step 1"; + if (result.bool) { + var draw = result.links[0] == cards[0]; + player.gain(result.links, draw ? "draw" : "gain2").log = false; + game.log(player, "获得了", draw ? "牌堆顶的一张牌" : result.links); + if (!draw) { cards[0].fix(); - ui.cardPile.insertBefore(cards[0],ui.cardPile.firstChild); + ui.cardPile.insertBefore(cards[0], ui.cardPile.firstChild); game.updateRoundNumber(); } } - } + }, }, //通渠张恭 - rezhenxing:{ - audio:'xinfu_zhenxing', - trigger:{ - player:["damageEnd","phaseJieshuBegin"], + rezhenxing: { + audio: "xinfu_zhenxing", + trigger: { + player: ["damageEnd", "phaseJieshuBegin"], }, - frequent:true, - content:function(){ - 'step 0' - event.cards=get.cards(3); - player.chooseButton(['【镇行】:请选择要获得的牌',event.cards]).set('filterButton',function(button){ - var cards=_status.event.cards; - for(var i=0;i=0;i--){ - if(result.bool&&result.links.includes(event.cards[i])){ - player.gain(event.cards[i],'gain2'); - } - else{ + frequent: true, + content: function () { + "step 0"; + event.cards = get.cards(3); + player + .chooseButton(["【镇行】:请选择要获得的牌", event.cards]) + .set("filterButton", function (button) { + var cards = _status.event.cards; + for (var i = 0; i < cards.length; i++) { + if (button.link != cards[i] && get.suit(cards[i]) == get.suit(button.link)) + return false; + } + return true; + }) + .set("ai", function (button) { + return get.value(button.link); + }) + .set("cards", event.cards); + "step 1"; + for (var i = event.cards.length - 1; i >= 0; i--) { + if (result.bool && result.links.includes(event.cards[i])) { + player.gain(event.cards[i], "gain2"); + } else { event.cards[i].fix(); - ui.cardPile.insertBefore(event.cards[i],ui.cardPile.childNodes[0]); + ui.cardPile.insertBefore(event.cards[i], ui.cardPile.childNodes[0]); } } game.updateRoundNumber(); }, }, //芙蓉,手杀界廖化,手杀界曹彰 - rejiangchi:{ - audio:2, - trigger:{ - player:"phaseUseBegin", + rejiangchi: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - content:function(){ - "step 0" - var list=['弃牌','摸牌','取消']; - if(!player.countCards('he')) list.remove('弃牌'); - player.chooseControl(list,function(){ - var player=_status.event.player; - if(list.includes('弃牌')){ - if(player.countCards('h')>3&&player.countCards('h','sha')>1){ - return '弃牌'; + direct: true, + content: function () { + "step 0"; + var list = ["弃牌", "摸牌", "取消"]; + if (!player.countCards("he")) list.remove("弃牌"); + player + .chooseControl(list, function () { + var player = _status.event.player; + if (list.includes("弃牌")) { + if (player.countCards("h") > 3 && player.countCards("h", "sha") > 1) { + return "弃牌"; + } + if (player.countCards("h", "sha") > 2) { + return "弃牌"; + } } - if(player.countCards('h','sha')>2){ - return '弃牌'; + if (!player.countCards("h", "sha")) { + return "摸牌"; } - } - if(!player.countCards('h','sha')){ - return '摸牌'; - } - return 'cancel2'; - }).set('prompt',get.prompt2('rejiangchi')); - "step 1" - if(result.control=='弃牌'){ - player.chooseToDiscard(true,'he'); - player.addTempSkill('jiangchi2','phaseUseEnd'); - player.logSkill('rejiangchi'); - } - else if(result.control=='摸牌'){ + return "cancel2"; + }) + .set("prompt", get.prompt2("rejiangchi")); + "step 1"; + if (result.control == "弃牌") { + player.chooseToDiscard(true, "he"); + player.addTempSkill("jiangchi2", "phaseUseEnd"); + player.logSkill("rejiangchi"); + } else if (result.control == "摸牌") { player.draw(); - player.addTempSkill('rejiangchi3','phaseUseEnd'); - player.logSkill('rejiangchi'); + player.addTempSkill("rejiangchi3", "phaseUseEnd"); + player.logSkill("rejiangchi"); } }, }, - rejiangchi3:{ - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + rejiangchi3: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, }, }, - refuli:{ - skillAnimation:true, - animationColor:'soil', - audio:2, - unique:true, - limited:true, - enable:'chooseToUse', - mark:true, - filter:function(event,player){ - if(event.type!='dying') return false; - if(player!=event.dying) return false; + refuli: { + skillAnimation: true, + animationColor: "soil", + audio: 2, + unique: true, + limited: true, + enable: "chooseToUse", + mark: true, + filter: function (event, player) { + if (event.type != "dying") return false; + if (player != event.dying) return false; return true; }, - content:function(){ - "step 0" - player.awakenSkill('refuli'); - event.num=game.countGroup(); - if(event.num>player.hp) player.recover(event.num-player.hp); - "step 1" - if(player.isMaxHp(true)) player.turnOver(); + content: function () { + "step 0"; + player.awakenSkill("refuli"); + event.num = game.countGroup(); + if (event.num > player.hp) player.recover(event.num - player.hp); + "step 1"; + if (player.isMaxHp(true)) player.turnOver(); }, - ai:{ - save:true, - skillTagFilter:function(player,arg,target){ - return player==target; + ai: { + save: true, + skillTagFilter: function (player, arg, target) { + return player == target; }, - result:{ - player:10 + result: { + player: 10, + }, + threaten: function (player, target) { + if (!target.storage.refuli) return 0.9; }, - threaten:function(player,target){ - if(!target.storage.refuli) return 0.9; - } }, }, - redangxian:{ - trigger:{player:'phaseBegin'}, - forced:true, - audio:'dangxian', - audioname:['guansuo','xin_liaohua'], - content:function(){ - 'step 0' - var card=get.discardPile(function(card){ - return card.name=='sha'; + redangxian: { + trigger: { player: "phaseBegin" }, + forced: true, + audio: "dangxian", + audioname: ["guansuo", "xin_liaohua"], + content: function () { + "step 0"; + var card = get.discardPile(function (card) { + return card.name == "sha"; }); - if(card) player.gain(card,'gain2'); - 'step 1' + if (card) player.gain(card, "gain2"); + "step 1"; game.updateRoundNumber(); - var next=player.phaseUse(); + var next = player.phaseUse(); event.next.remove(next); trigger.next.push(next); }, }, - xuewei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('xuewei'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player==get.zhu(player)&&player.hp<=2) return 0; - return get.attitude(player,target)-4; - }).animate=false; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('xuewei'); - player.addTempSkill('xuewei2',{player:'phaseBegin'}); - player.storage.xuewei2=target; + xuewei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("xuewei"), lib.filter.notMe).set("ai", function (target) { + var player = _status.event.player; + if (player == get.zhu(player) && player.hp <= 2) return 0; + return get.attitude(player, target) - 4; + }).animate = false; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("xuewei"); + player.addTempSkill("xuewei2", { player: "phaseBegin" }); + player.storage.xuewei2 = target; } }, - ai:{ - threaten:1.05, + ai: { + threaten: 1.05, }, }, - xuewei2:{ - audio:'xuewei', - forced:true, - onremove:true, - trigger:{global:'damageBegin4'}, - charlotte:true, - filter:function(event,player){ - return event.player==player.storage.xuewei2; + xuewei2: { + audio: "xuewei", + forced: true, + onremove: true, + trigger: { global: "damageBegin4" }, + charlotte: true, + filter: function (event, player) { + return event.player == player.storage.xuewei2; }, - logTarget:'player', - content:function(){ - player.removeSkill('xuewei2'); + logTarget: "player", + content: function () { + player.removeSkill("xuewei2"); trigger.cancel(); - player.damage(trigger.num,trigger.source||'nosource'); - if(trigger.source&&trigger.source.isIn()) trigger.source.damage(trigger.num,trigger.nature,player); + player.damage(trigger.num, trigger.source || "nosource"); + if (trigger.source && trigger.source.isIn()) + trigger.source.damage(trigger.num, trigger.nature, player); }, }, - liechi:{ - trigger:{player:'dying'}, - forced:true, - filter:function(event,player){ - return event.getParent().name=='damage'&&event.source&&event.source.countCards('he'); + liechi: { + trigger: { player: "dying" }, + forced: true, + filter: function (event, player) { + return ( + event.getParent().name == "damage" && event.source && event.source.countCards("he") + ); }, - audio:2, - content:function(){ - trigger.source.chooseToDiscard('he',true); + audio: 2, + content: function () { + trigger.source.chooseToDiscard("he", true); }, }, - rejiuchi:{ - group:['jiuchi'], - audioname:['re_dongzhuo'], - trigger:{source:'damage'}, - forced:true, - popup:false, - locked:false, - audio:'jiuchi', - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent(2).jiu==true&&!player.hasSkill('rejiuchi_air'); + rejiuchi: { + group: ["jiuchi"], + audioname: ["re_dongzhuo"], + trigger: { source: "damage" }, + forced: true, + popup: false, + locked: false, + audio: "jiuchi", + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.getParent(2).jiu == true && + !player.hasSkill("rejiuchi_air") + ); }, - content:function(){ - player.logSkill('jiuchi'); - player.addTempSkill('rejiuchi_air'); + content: function () { + player.logSkill("jiuchi"); + player.addTempSkill("rejiuchi_air"); }, - subSkill:{ - air:{}, + subSkill: { + air: {}, }, }, //苏飞,新贾逵 - tongqu:{ - audio:2, - trigger:{ - global:['phaseBefore','dying','phaseDrawBegin2'], - player:['enterGame','phaseZhunbeiBegin'], + tongqu: { + audio: 2, + trigger: { + global: ["phaseBefore", "dying", "phaseDrawBegin2"], + player: ["enterGame", "phaseZhunbeiBegin"], }, - direct:true, - filter:function(event,player){ - if(event.name=='phaseDraw') return event.player.hasMark('tongqu'); - if(event.name=='dying') return event.player.hasMark('tongqu'); - if(event.name=='phaseZhunbei') return game.hasPlayer(function(current){ - return !current.hasMark('tongqu'); - }); - return !player.hasMark('tongqu')&&(event.name!='phase'||game.phaseNumber==0); - }, - content:function(){ - 'step 0' - if(trigger.name=='phaseDraw'){ - player.logSkill('tongqu',trigger.player); - trigger.player.draw('nodelay'); - trigger.player.addTempSkill('tongqu2','phaseDrawAfter'); - event.finish(); - } - else if(trigger.name=='dying'){ - player.logSkill('tongqu',trigger.player); - trigger.player.removeMark('tongqu',1); - event.finish(); - } - else if(trigger.name=='phaseZhunbei'){ - player.chooseTarget(get.prompt2('tongqu'),function(card,player,target){ - return !target.hasMark('tongqu'); - }).set('ai',function(target){ - if(_status.event.player.hp<3) return 0; - return get.attitude(_status.event.player,target); + direct: true, + filter: function (event, player) { + if (event.name == "phaseDraw") return event.player.hasMark("tongqu"); + if (event.name == "dying") return event.player.hasMark("tongqu"); + if (event.name == "phaseZhunbei") + return game.hasPlayer(function (current) { + return !current.hasMark("tongqu"); }); - } - else{ - player.logSkill('tongqu'); - player.addMark('tongqu',1); + return !player.hasMark("tongqu") && (event.name != "phase" || game.phaseNumber == 0); + }, + content: function () { + "step 0"; + if (trigger.name == "phaseDraw") { + player.logSkill("tongqu", trigger.player); + trigger.player.draw("nodelay"); + trigger.player.addTempSkill("tongqu2", "phaseDrawAfter"); + event.finish(); + } else if (trigger.name == "dying") { + player.logSkill("tongqu", trigger.player); + trigger.player.removeMark("tongqu", 1); + event.finish(); + } else if (trigger.name == "phaseZhunbei") { + player + .chooseTarget(get.prompt2("tongqu"), function (card, player, target) { + return !target.hasMark("tongqu"); + }) + .set("ai", function (target) { + if (_status.event.player.hp < 3) return 0; + return get.attitude(_status.event.player, target); + }); + } else { + player.logSkill("tongqu"); + player.addMark("tongqu", 1); event.finish(); } - 'step 1' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.loseHp(); - player.logSkill('tongqu',target); - target.addMark('tongqu',1); + player.logSkill("tongqu", target); + target.addMark("tongqu", 1); } }, - marktext:'渠', - intro:{content:'mark',name2:'渠'}, + marktext: "渠", + intro: { content: "mark", name2: "渠" }, }, - tongqu2:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - silent:true, - filter:function(event,player){ - var bool=game.hasPlayer(function(current){ - return current!=player&¤t.hasMark('tongqu'); + tongqu2: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + silent: true, + filter: function (event, player) { + var bool = game.hasPlayer(function (current) { + return current != player && current.hasMark("tongqu"); }); - return player.countCards('he',function(card){ - if(bool) return true; - return lib.filter.cardDiscardable(card,player); - })>0; + return ( + player.countCards("he", function (card) { + if (bool) return true; + return lib.filter.cardDiscardable(card, player); + }) > 0 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - forced:true, - position:'he', - filterCard:true, - filterTarget:function(card,player,target){ - return player!=target&&target.hasMark('tongqu'); + forced: true, + position: "he", + filterCard: true, + filterTarget: function (card, player, target) { + return player != target && target.hasMark("tongqu"); }, - selectTarget:function(){ - if(ui.selected.cards.length&&!lib.filter.cardDiscardable(ui.selected.cards[0],_status.event.player)) return [1,1]; - return [0,1]; + selectTarget: function () { + if ( + ui.selected.cards.length && + !lib.filter.cardDiscardable(ui.selected.cards[0], _status.event.player) + ) + return [1, 1]; + return [0, 1]; }, - prompt:'弃置一张牌,或将一张牌交给一名有“渠”的其他角色', - ai1:function(card){ - var player=_status.event.player; - if(get.name(card)=='du') return 20; - if(get.position(card)=='e'&&get.value(card)<=0) return 14; - if(get.position(card)=='h'&&game.hasPlayer(function(current){ - return current!=player&¤t.hasMark('tongqu')&&get.attitude(player,current)>0&¤t.getUseValue(card)>player.getUseValue(card)&¤t.getUseValue(card)>player.getUseValue(card); - })) return 12; - if(game.hasPlayer(function(current){ - return current!=player&¤t.hasMark('tongqu')&&get.attitude(player,current)>0; - })){ - if(card.name=='wuxie') return 11; - if(card.name=='shan'&&player.countCards('h','shan')>1) return 9 + prompt: "弃置一张牌,或将一张牌交给一名有“渠”的其他角色", + ai1: function (card) { + var player = _status.event.player; + if (get.name(card) == "du") return 20; + if (get.position(card) == "e" && get.value(card) <= 0) return 14; + if ( + get.position(card) == "h" && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasMark("tongqu") && + get.attitude(player, current) > 0 && + current.getUseValue(card) > player.getUseValue(card) && + current.getUseValue(card) > player.getUseValue(card) + ); + }) + ) + return 12; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.hasMark("tongqu") && + get.attitude(player, current) > 0 + ); + }) + ) { + if (card.name == "wuxie") return 11; + if (card.name == "shan" && player.countCards("h", "shan") > 1) return 9; } - return 6/Math.max(1,get.value(card)); + return 6 / Math.max(1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player; - var card=ui.selected.cards[0]; - var att=get.attitude(player,target); - if(card.name=='du') return -6*att; - if(att>0){ - if(get.position(card)=='h'&&target.getUseValue(card)>player.getUseValue(card)) return 4*att; - if(target.hasUseTarget(card)) return 2*att; - return 1.2*att; + ai2: function (target) { + var player = _status.event.player; + var card = ui.selected.cards[0]; + var att = get.attitude(player, target); + if (card.name == "du") return -6 * att; + if (att > 0) { + if ( + get.position(card) == "h" && + target.getUseValue(card) > player.getUseValue(card) + ) + return 4 * att; + if (target.hasUseTarget(card)) return 2 * att; + return 1.2 * att; } return 0; }, }); - 'step 1' - if(result.bool){ - if(result.targets.length){ - event.target=result.targets[0]; - player.give(result.cards,event.target); - event.card=result.cards[0]; - } - else{ + "step 1"; + if (result.bool) { + if (result.targets.length) { + event.target = result.targets[0]; + player.give(result.cards, event.target); + event.card = result.cards[0]; + } else { player.discard(result.cards); event.finish(); } } - 'step 2' - if(target.getCards('h').includes(card)&&get.type(card)=='equip'){ - target.chooseUseTarget(card,true); + "step 2"; + if (target.getCards("h").includes(card) && get.type(card) == "equip") { + target.chooseUseTarget(card, true); } }, }, - xinwanlan:{ - audio:'wanlan', - trigger:{global:'damageBegin4'}, - filter:function(event,player){ - return event.player.hp<=event.num&&player.countCards('e')>=1; + xinwanlan: { + audio: "wanlan", + trigger: { global: "damageBegin4" }, + filter: function (event, player) { + return event.player.hp <= event.num && player.countCards("e") >= 1; }, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)<4) return false; - if(player.countCards('hs',card=>player.canSaveCard(card,event.player))>=1+event.num-event.player.hp) return false; - if(event.player==player||event.player==get.zhu(player)) return true; + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) < 4) return false; + if ( + player.countCards("hs", (card) => player.canSaveCard(card, event.player)) >= + 1 + event.num - event.player.hp + ) + return false; + if (event.player == player || event.player == get.zhu(player)) return true; return !player.hasUnknown(); }, - content:function(){ - player.discard(player.getCards('e')); + content: function () { + player.discard(player.getCards("e")); trigger.cancel(); }, }, - zhengjian:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - locked:true, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget('请选择【诤荐】的目标',lib.translate.zhengjian_info).set('ai',function(target){ - if(target.hasSkill('zhengjian_mark')) return 0; - if(player==target) return 0.5; - return get.attitude(_status.event.player,target)*(1+target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhengjian',target); - target.addSkill('zhengjian_mark'); - } - }, - group:'zhengjian_draw', - ai:{ - notemp:true, - }, - }, - zhengjian_draw:{ - audio:'zhengjian', - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event){ - return game.hasPlayer(function(current){ - return current.hasSkill('zhengjian_mark'); - }); - }, - logTarget:function(event){ - return game.filterPlayer(function(current){ - return current.hasSkill('zhengjian_mark'); - }); - }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current.countMark('zhengjian_mark')>0; - }); - if(list.length>1){ - event.delay=true; - game.asyncDraw(list,function(target){ - return Math.min(5,target.maxHp,target.countMark('zhengjian_mark')); + zhengjian: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + locked: true, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget("请选择【诤荐】的目标", lib.translate.zhengjian_info) + .set("ai", function (target) { + if (target.hasSkill("zhengjian_mark")) return 0; + if (player == target) return 0.5; + return get.attitude(_status.event.player, target) * (1 + target.countCards("h")); }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhengjian", target); + target.addSkill("zhengjian_mark"); } - else if(list.length==1) list[0].draw(Math.min(5,list[0].maxHp,list[0].countMark('zhengjian_mark'))); - 'step 1' - game.countPlayer(function(current){ - current.removeSkill('zhengjian_mark'); - }); - if(event.delay) game.delayx(); + }, + group: "zhengjian_draw", + ai: { + notemp: true, }, }, - zhengjian_mark:{ - trigger:{player:['useCard1','respond']}, - silent:true, - firstDo:true, - onremove:true, - charlotte:true, - content:function(){ - player.addMark('zhengjian_mark',1,false); - }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=0; - }, - mark:true, - intro:{ - content:'已使用/打出过#张牌', - }, - }, - gaoyuan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(player.countCards('he')==0) return false; - return game.hasPlayer(function(current){ - return current!=event.player&¤t!=player&& - current.hasSkill('zhengjian_mark')&&lib.filter.targetEnabled(event.card,event.player,current); + zhengjian_draw: { + audio: "zhengjian", + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event) { + return game.hasPlayer(function (current) { + return current.hasSkill("zhengjian_mark"); }); }, - content:function(){ - "step 0" - var next=player.chooseCardTarget({ - position:'he', - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - var trigger=_status.event; - if(target!=player&&target!=trigger.source){ - if(target.hasSkill('zhengjian_mark')&&lib.filter.targetEnabled(trigger.card,trigger.source,target)) return true; + logTarget: function (event) { + return game.filterPlayer(function (current) { + return current.hasSkill("zhengjian_mark"); + }); + }, + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current.countMark("zhengjian_mark") > 0; + }); + if (list.length > 1) { + event.delay = true; + game.asyncDraw(list, function (target) { + return Math.min(5, target.maxHp, target.countMark("zhengjian_mark")); + }); + } else if (list.length == 1) + list[0].draw(Math.min(5, list[0].maxHp, list[0].countMark("zhengjian_mark"))); + "step 1"; + game.countPlayer(function (current) { + current.removeSkill("zhengjian_mark"); + }); + if (event.delay) game.delayx(); + }, + }, + zhengjian_mark: { + trigger: { player: ["useCard1", "respond"] }, + silent: true, + firstDo: true, + onremove: true, + charlotte: true, + content: function () { + player.addMark("zhengjian_mark", 1, false); + }, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = 0; + }, + mark: true, + intro: { + content: "已使用/打出过#张牌", + }, + }, + gaoyuan: { + audio: 2, + trigger: { target: "useCardToTarget" }, + direct: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (player.countCards("he") == 0) return false; + return game.hasPlayer(function (current) { + return ( + current != event.player && + current != player && + current.hasSkill("zhengjian_mark") && + lib.filter.targetEnabled(event.card, event.player, current) + ); + }); + }, + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + position: "he", + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + var trigger = _status.event; + if (target != player && target != trigger.source) { + if ( + target.hasSkill("zhengjian_mark") && + lib.filter.targetEnabled(trigger.card, trigger.source, target) + ) + return true; } return false; }, - ai1:function(card){ - return get.unuseful(card)+9; + ai1: function (card) { + return get.unuseful(card) + 9; }, - ai2:function(target){ - if(_status.event.player.countCards('h','shan')){ - return -get.attitude(_status.event.player,target); + ai2: function (target) { + if (_status.event.player.countCards("h", "shan")) { + return -get.attitude(_status.event.player, target); } - if(get.attitude(_status.event.player,target)<5){ - return 6-get.attitude(_status.event.player,target); + if (get.attitude(_status.event.player, target) < 5) { + return 6 - get.attitude(_status.event.player, target); } - if(_status.event.player.hp==1&&player.countCards('h','shan')==0){ - return 10-get.attitude(_status.event.player,target); + if (_status.event.player.hp == 1 && player.countCards("h", "shan") == 0) { + return 10 - get.attitude(_status.event.player, target); } - if(_status.event.player.hp==2&&player.countCards('h','shan')==0){ - return 8-get.attitude(_status.event.player,target); + if (_status.event.player.hp == 2 && player.countCards("h", "shan") == 0) { + return 8 - get.attitude(_status.event.player, target); } return -1; }, - prompt:get.prompt('gaoyuan'), - prompt2:'弃置一张牌,将此【杀】转移给一名有“诤”的角色', - source:trigger.player, - card:trigger.card, + prompt: get.prompt("gaoyuan"), + prompt2: "弃置一张牌,将此【杀】转移给一名有“诤”的角色", + source: trigger.player, + card: trigger.card, }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill(event.name,target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill(event.name, target); player.discard(result.cards); - var evt=trigger.getParent(); + var evt = trigger.getParent(); evt.triggeredTargets2.remove(player); evt.targets.remove(player); evt.targets.push(target); } }, + ai: { + combo: "zhengjian" + }, }, //一 将 成 名 - zhilve:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ - 'step 0' - if(!player.canMoveCard()) event._result={index:1}; - else player.chooseControl().set('choiceList',[ - '移动场上的一张牌', - '本回合的摸牌阶段多摸一张牌且第一张杀无距离次数限制', - ]).set('ai',function(){return 1}); - 'step 1' - if(result.index==1){ - player.addTempSkill('zhilve_yingzi'); - if(!player.getHistory('useCard',function(card){ - return card.card.name=='sha'; - }).length) player.addTempSkill('zhilve_xiandeng'); + zhilve: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { + "step 0"; + if (!player.canMoveCard()) event._result = { index: 1 }; + else + player + .chooseControl() + .set("choiceList", [ + "移动场上的一张牌", + "本回合的摸牌阶段多摸一张牌且第一张杀无距离次数限制", + ]) + .set("ai", function () { + return 1; + }); + "step 1"; + if (result.index == 1) { + player.addTempSkill("zhilve_yingzi"); + if ( + !player.getHistory("useCard", function (card) { + return card.card.name == "sha"; + }).length + ) + player.addTempSkill("zhilve_xiandeng"); event.finish(); - } - else player.moveCard(true); - 'step 2' - if(result.position=='e') player.loseHp(); - else player.addTempSkill('zhilve_dis'); + } else player.moveCard(true); + "step 2"; + if (result.position == "e") player.loseHp(); + else player.addTempSkill("zhilve_dis"); }, - subSkill:{ - dis:{ - mod:{ - maxHandcard:function(player,num){ - return num-1; + subSkill: { + dis: { + mod: { + maxHandcard: function (player, num) { + return num - 1; }, }, }, - yingzi:{ - trigger:{player:'phaseDrawBegin2'}, - popup:false, - forced:true, - filter:function(event,player){ + yingzi: { + trigger: { player: "phaseDrawBegin2" }, + popup: false, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){trigger.num++}, + content: function () { + trigger.num++; + }, }, - xiandeng:{ - mod:{ - targetInRange:function(card,player){ - if(card.name=='sha') return true; + xiandeng: { + mod: { + targetInRange: function (card, player) { + if (card.name == "sha") return true; }, }, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.card.name=='sha'; + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - content:function(){ + content: function () { player.removeSkill(event.name); - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat('card'); - if(stat&&stat.sha) stat.sha--; + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat("card"); + if (stat && stat.sha) stat.sha--; } }, }, }, }, - xhzhiyan:{ - enable:'phaseUse', - audio:2, - filter:function(event,player){ - return player.countCards('h')!=player.maxHp; + xhzhiyan: { + enable: "phaseUse", + audio: 2, + filter: function (event, player) { + return player.countCards("h") != player.maxHp; }, - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - var num=Math.max(0,player.countCards('h')-player.maxHp); - return [num,num]; + filterCard: true, + selectCard: function () { + var player = _status.event.player; + var num = Math.max(0, player.countCards("h") - player.maxHp); + return [num, num]; }, - check:function(card){ - var player=_status.event.player; - if(player.getUseValue(card)<=0&&game.hasPlayer(function(current){ - return current!=player&&get.value(card,current)*get.attitude(player,current)>0; - })) return 1; + check: function (card) { + var player = _status.event.player; + if ( + player.getUseValue(card) <= 0 && + game.hasPlayer(function (current) { + return ( + current != player && + get.value(card, current) * get.attitude(player, current) > 0 + ); + }) + ) + return 1; return 0; }, - content:function(){ - 'step 0' - if(!cards.length){ - player.draw(player.maxHp-player.countCards('h')); - player.addTempSkill('zishou2'); + content: function () { + "step 0"; + if (!cards.length) { + player.draw(player.maxHp - player.countCards("h")); + player.addTempSkill("zishou2"); event.finish(); - } - else{ - cards=cards.filterInD('d'); - if(cards.length) player.chooseButton(['是否将其中的一张牌交给一名其他角色?',cards]).set('',function(button){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&&get.value(button.link,current)*get.attitude(player,current)>0; - })) return Math.abs(get.value(button.link)); - return 0; - }); + } else { + cards = cards.filterInD("d"); + if (cards.length) + player + .chooseButton(["是否将其中的一张牌交给一名其他角色?", cards]) + .set("", function (button) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + get.value(button.link, current) * + get.attitude(player, current) > + 0 + ); + }) + ) + return Math.abs(get.value(button.link)); + return 0; + }); else event.finish(); } - 'step 1' - if(result.bool&&game.hasPlayer(current=>current!=player)){ - event.card=result.links[0]; - player.chooseTarget(true,lib.filter.notMe,'选择一名其他角色获得'+get.translation(event.card)).set('ai',function(target){ - return get.value(_status.event.getParent().card,target)*get.attitude(_status.event.player,target); - }); - } - else event.finish(); - 'step 2' - var target=result.targets[0]; - player.line(target,'green'); - target.gain(card,'gain2','log'); + "step 1"; + if (result.bool && game.hasPlayer((current) => current != player)) { + event.card = result.links[0]; + player + .chooseTarget( + true, + lib.filter.notMe, + "选择一名其他角色获得" + get.translation(event.card) + ) + .set("ai", function (target) { + return ( + get.value(_status.event.getParent().card, target) * + get.attitude(_status.event.player, target) + ); + }); + } else event.finish(); + "step 2"; + var target = result.targets[0]; + player.line(target, "green"); + target.gain(card, "gain2", "log"); }, - ai:{ - order:function(obj,player){ - if(player.countCards('h')>player.maxHp) return 10; + ai: { + order: function (obj, player) { + if (player.countCards("h") > player.maxHp) return 10; return 0.5; }, - result:{ - player:1, + result: { + player: 1, }, }, }, //水 果 忍 者 - zhengjing_guanju:{audio:true}, - zhengjing:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkill('zhengjing3'); + zhengjing_guanju: { audio: true }, + zhengjing: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return !player.hasSkill("zhengjing3"); }, - content:function(){ - "step 0" + content: function () { + "step 0"; //game.trySkillAudio('zhengjing_guanju',player); - if(_status.connectMode) event.time=lib.configOL.choose_timeout; - var cards=[]; - var names=[]; - while(true){ - var card=get.cardPile(function(carde){ - return carde.name!='du'&&!names.includes(carde.name); + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + var cards = []; + var names = []; + while (true) { + var card = get.cardPile(function (carde) { + return carde.name != "du" && !names.includes(carde.name); }); - if(card){ + if (card) { cards.push(card); names.push(card.name); - if(get.mode()=='doudizhu'){ - if(cards.length==1&&!get.isLuckyStar(player)&&Math.random()<0.33) break; - if(cards.length==2&&!get.isLuckyStar(player)&&Math.random()<0.5) break; - if(cards.length>=3) break; + if (get.mode() == "doudizhu") { + if (cards.length == 1 && !get.isLuckyStar(player) && Math.random() < 0.33) + break; + if (cards.length == 2 && !get.isLuckyStar(player) && Math.random() < 0.5) + break; + if (cards.length >= 3) break; + } else { + if (cards.length == 3 && !get.isLuckyStar(player) && Math.random() < 0.33) + break; + if (cards.length == 4 && !get.isLuckyStar(player) && Math.random() < 0.5) + break; + if (cards.length >= 5) break; } - else{ - if(cards.length==3&&!get.isLuckyStar(player)&&Math.random()<0.33) break; - if(cards.length==4&&!get.isLuckyStar(player)&&Math.random()<0.5) break; - if(cards.length>=5) break; - } - } - else break; - }; - event.cards=cards; - if(!cards.length){event.finish();return;}; - event.videoId=lib.status.videoId++; - if(player.isUnderControl()){ + } else break; + } + event.cards = cards; + if (!cards.length) { + event.finish(); + return; + } + event.videoId = lib.status.videoId++; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ - names.remove('du'); + var switchToAuto = function () { + names.remove("du"); game.pause(); game.countChoose(); - setTimeout(function(){ - _status.imchoosing=false; - event._result={ - bool:true, - links:names.slice(0), + setTimeout(function () { + _status.imchoosing = false; + event._result = { + bool: true, + links: names.slice(0), }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); game.resume(); - },5000); + }, 5000); }; - var createDialog=function(player,id){ - if(_status.connectMode) lib.configOL.choose_timeout='30'; - if(player==game.me) return; - var str=get.translation(player)+'正在整理经书...
              '; - ui.create.dialog(str).videoId=id; + var createDialog = function (player, id) { + if (_status.connectMode) lib.configOL.choose_timeout = "30"; + if (player == game.me) return; + var str = get.translation(player) + "正在整理经书...
              "; + ui.create.dialog(str).videoId = id; }; - var chooseButton=function(list){ - var roundmenu=false; - if(ui.roundmenu&&ui.roundmenu.display!='none'){ - roundmenu=true; - ui.roundmenu.style.display='none'; + var chooseButton = function (list) { + var roundmenu = false; + if (ui.roundmenu && ui.roundmenu.display != "none") { + roundmenu = true; + ui.roundmenu.style.display = "none"; } - var event=_status.event; - event.settleed=false; - event.finishedx=[]; - event.map={}; - var names=list.slice(0) - event.zhengjing_nodes=[]; - names.push('du'); - names.randomSort() - var names2=names.slice(0); - for(var i=0;i<2;i++){ + var event = _status.event; + event.settleed = false; + event.finishedx = []; + event.map = {}; + var names = list.slice(0); + event.zhengjing_nodes = []; + names.push("du"); + names.randomSort(); + var names2 = names.slice(0); + for (var i = 0; i < 2; i++) { names2.randomSort(); - names=names.concat(names2); + names = names.concat(names2); } - event.zhengjing=names; - for(var i of list){ - event.map[i]=0; + event.zhengjing = names; + for (var i of list) { + event.map[i] = 0; } - event.dialog=ui.create.dialog('forcebutton','hidden'); - event.dialog.textPrompt=event.dialog.add('
              及时点击卡牌,但不要点到毒了!
              '); - var str='
              '; - for(var i of list){ - str+=(get.translation(i)+':'+Math.min(2,event.map[i])+'/2 '); + event.dialog = ui.create.dialog("forcebutton", "hidden"); + event.dialog.textPrompt = event.dialog.add( + '
              及时点击卡牌,但不要点到毒了!
              ' + ); + var str = '
              '; + for (var i of list) { + str += get.translation(i) + ":" + Math.min(2, event.map[i]) + "/2 "; } - str+='
              '; - event.dialog.textPrompt2=event.dialog.add(str); - event.switchToAuto=function(){ - event._result={ - bool:true, - links:event.finishedx.slice(0), + str += "
              "; + event.dialog.textPrompt2 = event.dialog.add(str); + event.switchToAuto = function () { + event._result = { + bool: true, + links: event.finishedx.slice(0), }; event.dialog.close(); game.resume(); - _status.imchoosing=false; - if(roundmenu) ui.roundmenu.style.display=''; + _status.imchoosing = false; + if (roundmenu) ui.roundmenu.style.display = ""; }; - event.dialog.classList.add('fixed'); - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - event.dialog.classList.add('fullheight'); - event.dialog.classList.add('noupdate'); + event.dialog.classList.add("fixed"); + event.dialog.classList.add("scroll1"); + event.dialog.classList.add("scroll2"); + event.dialog.classList.add("fullwidth"); + event.dialog.classList.add("fullheight"); + event.dialog.classList.add("noupdate"); event.dialog.open(); - event.settle=function(du){ - if(event.settleed) return; - event.settleed=true; - event.dialog.textPrompt2.innerHTML=''; - if(du){ - if(lib.config.background_speak) game.playAudio('skill','zhengjing_boom'); - event.dialog.textPrompt.innerHTML='
              叫你别点毒你非得点 这下翻车了吧
              '; + event.settle = function (du) { + if (event.settleed) return; + event.settleed = true; + event.dialog.textPrompt2.innerHTML = ""; + if (du) { + if (lib.config.background_speak) game.playAudio("skill", "zhengjing_boom"); + event.dialog.textPrompt.innerHTML = + '
              叫你别点毒你非得点 这下翻车了吧
              '; + } else { + if (lib.config.background_speak) game.playAudio("skill", "zhengjing_finish"); + event.dialog.textPrompt.innerHTML = + '
              整理经典结束!共整理出' + + get.cnNumber(event.finishedx.length) + + "份经典
              "; } - else { - if(lib.config.background_speak) game.playAudio('skill','zhengjing_finish'); - event.dialog.textPrompt.innerHTML='
              整理经典结束!共整理出'+get.cnNumber(event.finishedx.length)+'份经典
              '; - } - while(event.zhengjing_nodes.length){ + while (event.zhengjing_nodes.length) { event.zhengjing_nodes.shift().delete(); } - setTimeout(function(){ - event.switchToAuto(); - },1000); + setTimeout(function () { + event.switchToAuto(); + }, 1000); }; - var click=function(){ - var name=this.name; - if(name=='du'){ - event.zhengjing.length=0; + var click = function () { + var name = this.name; + if (name == "du") { + event.zhengjing.length = 0; event.settle(true); - } - else{ - if(lib.config.background_speak) game.playAudio('skill','zhengjing_click'); + } else { + if (lib.config.background_speak) game.playAudio("skill", "zhengjing_click"); event.map[name]++; - if(event.map[name]>1) event.finishedx.add(name); - if(event.finishedx.length 1) event.finishedx.add(name); + if (event.finishedx.length < list.length) { + var str = '
              '; + for (var i of list) { + str += get.translation(i) + ":" + Math.min(2, event.map[i]) + "/2 "; } - str+='
              '; - event.dialog.textPrompt2.innerHTML=str; - } - else{ - event.zhengjing.length=0; + str += ""; + event.dialog.textPrompt2.innerHTML = str; + } else { + event.zhengjing.length = 0; event.settle(); } } event.zhengjing_nodes.remove(this); - this.style.transition='all 0.5s'; - this.style.transform='scale(1.2)'; + this.style.transition = "all 0.5s"; + this.style.transform = "scale(1.2)"; this.delete(); }; - var addNode=function(){ - if(event.zhengjing.length){ - var card=ui.create.card(ui.special,'noclick',true); - card.init(['','',event.zhengjing.shift()]); - card.addEventListener(lib.config.touchscreen?'touchstart':'mousedown',click); + var addNode = function () { + if (event.zhengjing.length) { + var card = ui.create.card(ui.special, "noclick", true); + card.init(["", "", event.zhengjing.shift()]); + card.addEventListener( + lib.config.touchscreen ? "touchstart" : "mousedown", + click + ); event.zhengjing_nodes.push(card); - card.style.position='absolute'; - var rand1=Math.round(Math.random()*100); - var rand2=Math.round(Math.random()*100); - var rand3=Math.round(Math.random()*40)-20; - card.style.left='calc('+rand1+'% - '+rand1+'px)'; - card.style.top='calc('+rand2+'% - '+rand2+'px)'; - card.style.transform='scale(0.8) rotate('+rand3+'deg)'; - card.style.opacity=0; + card.style.position = "absolute"; + var rand1 = Math.round(Math.random() * 100); + var rand2 = Math.round(Math.random() * 100); + var rand3 = Math.round(Math.random() * 40) - 20; + card.style.left = "calc(" + rand1 + "% - " + rand1 + "px)"; + card.style.top = "calc(" + rand2 + "% - " + rand2 + "px)"; + card.style.transform = "scale(0.8) rotate(" + rand3 + "deg)"; + card.style.opacity = 0; event.dialog.appendChild(card); ui.refresh(card); - card.style.opacity=1; - card.style.transform='scale(1) rotate('+rand3+'deg)'; + card.style.opacity = 1; + card.style.transform = "scale(1) rotate(" + rand3 + "deg)"; } - if(event.zhengjing_nodes.length>(event.zhengjing.length>0?2:0)) event.zhengjing_nodes.shift().delete(); - if(event.zhengjing.length||event.zhengjing_nodes.length) setTimeout(function(){ - addNode(); - },800); + if (event.zhengjing_nodes.length > (event.zhengjing.length > 0 ? 2 : 0)) + event.zhengjing_nodes.shift().delete(); + if (event.zhengjing.length || event.zhengjing_nodes.length) + setTimeout(function () { + addNode(); + }, 800); else event.settle(); }; @@ -11963,3202 +14581,3745 @@ game.import('character',function(lib,game,ui,get,ai,_status){ addNode(); }; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId); - if(event.isMine()){ + game.broadcastAll(createDialog, player, event.videoId); + if (event.isMine()) { chooseButton(names); - } - else if(event.isOnline()){ - event.player.send(chooseButton,names); + } else if (event.isOnline()) { + event.player.send(chooseButton, names); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - game.broadcastAll(function(id,time){ - if(_status.connectMode) lib.configOL.choose_timeout=time; - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - },event.videoId,event.time); - var result=event.result||result; - for(var i=0;i0; + next.set("filterOk", function (moved) { + return moved[0].length > 0; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(a)-get.value(b); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(a) - get.value(b); }); - return [cards.splice(0,1),cards]; - }) - "step 5" - if(result.bool){ - var cards=result.moved[0],gains=result.moved[1]; - target.addSkill('zhengjing2'); - target.addToExpansion(cards,'gain2').gaintag.add('zhengjing2'); - if(gains.length) player.gain(gains,'gain2'); + return [cards.splice(0, 1), cards]; + }); + "step 5"; + if (result.bool) { + var cards = result.moved[0], + gains = result.moved[1]; + target.addSkill("zhengjing2"); + target.addToExpansion(cards, "gain2").gaintag.add("zhengjing2"); + if (gains.length) player.gain(gains, "gain2"); } }, - ai:{ - order:10, - result:{player:1}, - threaten:3.2, - } + ai: { + order: 10, + result: { player: 1 }, + threaten: 3.2, + }, }, //恁就是仲村由理? - zhengjing2:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - charlotte:true, - intro:{content:'expansion',markcount:'expansion'}, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + zhengjing2: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + charlotte: true, + intro: { content: "expansion", markcount: "expansion" }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - 'step 0' - player.gain(player.getExpansions('zhengjing2'),'gain2'); - player.skip('phaseJudge'); - player.skip('phaseDraw'); - 'step 1' - player.removeSkill('zhengjing2'); + content: function () { + "step 0"; + player.gain(player.getExpansions("zhengjing2"), "gain2"); + player.skip("phaseJudge"); + player.skip("phaseDraw"); + "step 1"; + player.removeSkill("zhengjing2"); }, }, - zhengjing3:{}, + zhengjing3: {}, //邓芝 - jimeng:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countGainableCards(player,'he')>0; - }) - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('jimeng'),function(card,player,target){ - return target!=player&&target.countGainableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - if(player.hp>1&&get.attitude(player,target)<2) return 0; - return get.effect(target,{name:'shunshou'},player,player); + jimeng: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countGainableCards(player, "he") > 0; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jimeng',target); - player.gainPlayerCard(target,'he',true); - } - else event.finish(); - 'step 2' - var hs=player.getCards('he'); - if(player.hp>0&&hs.length){ - if(hs.length<=player.hp) event._result={bool:true,cards:hs}; - else player.chooseCard(player.hp,true,'交给'+get.translation(target)+get.cnNumber(player.hp)+'张牌','he',true); - } - else event.finish(); - 'step 3' - player.give(result.cards,target); + }, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("jimeng"), function (card, player, target) { + return target != player && target.countGainableCards(player, "he") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player; + if (player.hp > 1 && get.attitude(player, target) < 2) return 0; + return get.effect(target, { name: "shunshou" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jimeng", target); + player.gainPlayerCard(target, "he", true); + } else event.finish(); + "step 2"; + var hs = player.getCards("he"); + if (player.hp > 0 && hs.length) { + if (hs.length <= player.hp) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + player.hp, + true, + "交给" + get.translation(target) + get.cnNumber(player.hp) + "张牌", + "he", + true + ); + } else event.finish(); + "step 3"; + player.give(result.cards, target); }, }, - shuaiyan:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - filter:function(event,player){ - return player.countCards('h')>1; + shuaiyan: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + filter: function (event, player) { + return player.countCards("h") > 1; }, - check:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')&&lib.skill.shuaiyan.check2(current,player); + check: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("he") && + lib.skill.shuaiyan.check2(current, player) + ); }); }, - check2:function(target,player){ - if(get.itemtype(player)!='player') player=_status.event.player; - return -get.attitude(player,target)/target.countCards('he'); + check2: function (target, player) { + if (get.itemtype(player) != "player") player = _status.event.player; + return -get.attitude(player, target) / target.countCards("he"); }, - content:function(){ - 'step 0' - player.showHandcards(get.translation(player)+'发动了【率言】'); - 'step 1' - var filter=function(card,player,target){ - return player!=target&&target.countCards('he')>0; + content: function () { + "step 0"; + player.showHandcards(get.translation(player) + "发动了【率言】"); + "step 1"; + var filter = function (card, player, target) { + return player != target && target.countCards("he") > 0; }; - if(game.hasPlayer(function(current){ - return filter('我约等于白板',player,current); - })){ - player.chooseTarget(true,filter,'选择一名其他角色,令其交给你一张牌').set('ai',lib.skill.shuaiyan.check2); - } - else event.finish(); - 'step 2' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); - 'step 3' - target.give(result.cards,player); + if ( + game.hasPlayer(function (current) { + return filter("我约等于白板", player, current); + }) + ) { + player + .chooseTarget(true, filter, "选择一名其他角色,令其交给你一张牌") + .set("ai", lib.skill.shuaiyan.check2); + } else event.finish(); + "step 2"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); + "step 3"; + target.give(result.cards, player); }, }, - relihuo:{ - audio:2, - group:['relihuo_baigei','relihuo_damage'], - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + relihuo: { + audio: 2, + group: ["relihuo_baigei", "relihuo_damage"], + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; }, - check:function(event,player){ + check: function (event, player) { return false; }, - content:function(){ - game.setNature(trigger.card,'fire'); - trigger.relihuo=true; + content: function () { + game.setNature(trigger.card, "fire"); + trigger.relihuo = true; }, }, - relihuo_damage:{ - trigger:{source:'damageBegin1'}, - forced:true, - audio:'relihuo', - filter:function(event,player){ - return event.getParent(2).relihuo==true&&event.player.isLinked(); + relihuo_damage: { + trigger: { source: "damageBegin1" }, + forced: true, + audio: "relihuo", + filter: function (event, player) { + return event.getParent(2).relihuo == true && event.player.isLinked(); }, - content:function(){ + content: function () { trigger.num++; }, }, - relihuo_baigei:{ - trigger:{player:'useCardAfter'}, - forced:true, - audio:'relihuo', - filter:function(event,player){ - if(event.card.name!='sha'||!game.hasNature(event.card,'fire')) return false; - var num=0; - player.getHistory('sourceDamage',function(evt){ - if(evt.card==event.card) num+=evt.num; + relihuo_baigei: { + trigger: { player: "useCardAfter" }, + forced: true, + audio: "relihuo", + filter: function (event, player) { + if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; + var num = 0; + player.getHistory("sourceDamage", function (evt) { + if (evt.card == event.card) num += evt.num; }); - return num>1; + return num > 1; }, - content:function(){ - var num=0; - player.getHistory('sourceDamage',function(evt){ - if(evt.card==trigger.card) num+=evt.num; + content: function () { + var num = 0; + player.getHistory("sourceDamage", function (evt) { + if (evt.card == trigger.card) num += evt.num; }); - player.loseHp(Math.floor(num/2)); + player.loseHp(Math.floor(num / 2)); }, }, - gongsun:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>1; + gongsun: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt2('gongsun'), - selectCard:2, - filterCard:lib.filter.cardDiscardable, - filterTarget:lib.filter.notMe, - position:'he', - ai1:function(card){ - var friend=0,enemy=0,player=_status.event.player; - var num=game.countPlayer(function(target){ - var att=get.attitude(player,target); - if(att<0) enemy++; - if(target!=player&&att>0) friend++; + prompt: get.prompt2("gongsun"), + selectCard: 2, + filterCard: lib.filter.cardDiscardable, + filterTarget: lib.filter.notMe, + position: "he", + ai1: function (card) { + var friend = 0, + enemy = 0, + player = _status.event.player; + var num = game.countPlayer(function (target) { + var att = get.attitude(player, target); + if (att < 0) enemy++; + if (target != player && att > 0) friend++; return true; }); - if(num>(friend+enemy+2)) return 0; - if(friend friend + enemy + 2) return 0; + if (friend < enemy) return 0; + if (card.name == "sha") return 10 - enemy; + return 10 - enemy - get.value(card); }, - ai2:function(target){ - return -get.attitude(_status.event.player,target)*(1+target.countCards('h')); + ai2: function (target) { + return -get.attitude(_status.event.player, target) * (1 + target.countCards("h")); }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('gongsun',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gongsun", target); player.discard(result.cards); - player.addTempSkill('gongsun_shadow',{player:['phaseBegin','die']}); - var list=[]; - for(var i=0;i0) str+='
              ' - str+=get.translation(shadow[i][0]); - str+=':'; - str+=get.translation(shadow[i][1]); + marktext: "损", + onremove: true, + intro: { + content: function (shadow) { + var str = ""; + for (var i = 0; i < shadow.length; i++) { + if (i > 0) str += "
              "; + str += get.translation(shadow[i][0]); + str += ":"; + str += get.translation(shadow[i][1]); } return str; }, }, - mod:{ - cardEnabled:function(card,player){ - var list=player.storage.gongsun_shadow; - for(var i=0;i0&&!player.hasSkill('duoduan_im'); + duoduan: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.countCards("he") > 0 && + !player.hasSkill("duoduan_im") + ); }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt2('duoduan'),lib.filter.cardRecastable).set('ai',function(card){ - if(_status.event.goon) return 8-get.value(card); - return 0; - }).set('goon',function(){ - if(get.attitude(trigger.player,player)>0) return true; - if(!trigger.player.countCards('he')) return true; - if(!player.hasShan()) return true; - return event.getRand()<0.5; - }()); - 'step 1' - if(result.bool){ - player.addTempSkill('duoduan_im'); - player.logSkill('duoduan',trigger.player); + content: function () { + "step 0"; + player + .chooseCard("he", get.prompt2("duoduan"), lib.filter.cardRecastable) + .set("ai", function (card) { + if (_status.event.goon) return 8 - get.value(card); + return 0; + }) + .set( + "goon", + (function () { + if (get.attitude(trigger.player, player) > 0) return true; + if (!trigger.player.countCards("he")) return true; + if (!player.hasShan()) return true; + return event.getRand() < 0.5; + })() + ); + "step 1"; + if (result.bool) { + player.addTempSkill("duoduan_im"); + player.logSkill("duoduan", trigger.player); player.recast(result.cards); - } - else event.finish(); - 'step 2' - var sha=get.translation(trigger.card); - if(!trigger.player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,trigger.player,'duoduan'); - })) event.finish(); - else player.chooseControl().set('choiceList',[ - '令其摸两张牌,然后令'+sha+'对你无效', - '令其弃置一张牌,然后你不可响应'+sha, - ]).set('prompt','度断:令'+get.translation(trigger.player)+'执行一项').set('ai',function(){ - var player=_status.event.player; - var source=_status.event.getTrigger().player; - if(get.attitude(player,source)>0) return 0; - if(!player.hasShan()&&player.hp>=2) return 1; - return 0; - }); - 'step 3' - if(result.index==0) event.goto(5); - else trigger.player.chooseToDiscard('弃置一张牌令'+get.translation(player)+'不能闪避此【杀】','he',true); - 'step 4' - if(result.bool){ + } else event.finish(); + "step 2"; + var sha = get.translation(trigger.card); + if ( + !trigger.player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, trigger.player, "duoduan"); + }) + ) + event.finish(); + else + player + .chooseControl() + .set("choiceList", [ + "令其摸两张牌,然后令" + sha + "对你无效", + "令其弃置一张牌,然后你不可响应" + sha, + ]) + .set("prompt", "度断:令" + get.translation(trigger.player) + "执行一项") + .set("ai", function () { + var player = _status.event.player; + var source = _status.event.getTrigger().player; + if (get.attitude(player, source) > 0) return 0; + if (!player.hasShan() && player.hp >= 2) return 1; + return 0; + }); + "step 3"; + if (result.index == 0) event.goto(5); + else + trigger.player.chooseToDiscard( + "弃置一张牌令" + get.translation(player) + "不能闪避此【杀】", + "he", + true + ); + "step 4"; + if (result.bool) { trigger.directHit.add(player); } event.finish(); - 'step 5' + "step 5"; trigger.player.draw(2); trigger.excluded.add(player); }, }, - duoduan_im:{ + duoduan_im: { //'im' refers to 'Iwasawa Masami' in 'Angel Beats!' //Although she disappeared in the Episode 3 of the anime, but her route in the game is really worth to play. }, - chengzhao:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - var num=0; - player.getHistory('gain',function(evt){ - num+=evt.cards.length; - }); - if(num<2) return false; - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return player!=current&&player.canCompare(current); + chengzhao: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + var num = 0; + player.getHistory("gain", function (evt) { + num += evt.cards.length; }); + if (num < 2) return false; + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return player != current && player.canCompare(current); + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('chengzhao'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)/target.countCards('h'); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('chengzhao',target); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("chengzhao"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) / target.countCards("h"); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("chengzhao", target); player.chooseToCompare(target); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card={name:'sha',isCard:true}; - if(player.canUse(card,target,false)) player.useCard(card,target,false).card.chengzhao=true; + } else event.finish(); + "step 2"; + if (result.bool) { + var card = { name: "sha", isCard: true }; + if (player.canUse(card, target, false)) + player.useCard(card, target, false).card.chengzhao = true; } }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||arg.card.chengzhao!=true) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.card || arg.card.chengzhao != true) return false; }, }, }, - rezhengrong:{ - trigger:{player:'useCardAfter'}, - direct:true, - audio:'drlt_zhenrong', - filter:function(event,player){ - if(!event.targets) return false; - if(!event.isPhaseUsing(player)) return false; - var bool=false; - for(var i=0;i0; - }).set('ai',function(target){ - return (1-get.attitude(_status.event.player,target))/target.countCards('he'); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=result.targets[0]; - player.logSkill('rezhengrong',target); - var card=target.getCards('he').randomGet(); - player.addToExpansion(card,target,'give').gaintag.add('rezhengrong'); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("rezhengrong"), + "将一名其他角色的随机一张牌置于你的武将牌上,成为「荣」", + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return (1 - get.attitude(_status.event.player, target)) / target.countCards("he"); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = result.targets[0]; + player.logSkill("rezhengrong", target); + var card = target.getCards("he").randomGet(); + player.addToExpansion(card, target, "give").gaintag.add("rezhengrong"); } }, - marktext:'荣', - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "荣", + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, }, - rehongju:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:'drlt_hongju', - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - derivation:'reqingce', - filter:function(event,player){ - return player.getExpansions('rezhengrong').length>=3&&game.dead.length>0; + rehongju: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: "drlt_hongju", + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + derivation: "reqingce", + filter: function (event, player) { + return player.getExpansions("rezhengrong").length >= 3 && game.dead.length > 0; }, - content:function(){ - 'step 0' - player.awakenSkill('rehongju'); - player.draw(player.getExpansions('rezhengrong').length); - 'step 1' - if(player.countCards('h')==0) event.goto(3); - else{ - var dialog=['请选择要交换的手牌和「荣」,或点「取消」','
              「征荣」牌
              ',player.getExpansions('rezhengrong'),'
              手牌区
              ',player.getCards('h')]; - var next=player.chooseButton(dialog); - next.set('filterButton',function(button){ - var ss=_status.event.player.getExpansions('rezhengrong'); - var hs=_status.event.player.getCards('h'); - var sn=0; - var hn=0; - var ub=ui.selected.buttons; - for(var i=0;i「征荣」牌', + player.getExpansions("rezhengrong"), + '
              手牌区
              ', + player.getCards("h"), + ]; + var next = player.chooseButton(dialog); + next.set("filterButton", function (button) { + var ss = _status.event.player.getExpansions("rezhengrong"); + var hs = _status.event.player.getCards("h"); + var sn = 0; + var hn = 0; + var ub = ui.selected.buttons; + for (var i = 0; i < ub.length; i++) { + if (ss.includes(ub[i].link)) sn++; else hn++; } - return !(sn>=hs.length&&ss.includes(button.link)||hn>=ss.length&&hs.includes(button.link)); + return !( + (sn >= hs.length && ss.includes(button.link)) || + (hn >= ss.length && hs.includes(button.link)) + ); }); - next.set('selectButton',function(){ - if(ui.selected.buttons.length==0) return 2; - var ss=_status.event.player.getExpansions('rezhengrong'); - var hs=_status.event.player.getCards('h'); - var sn=0; - var hn=0; - var ub=ui.selected.buttons; - for(var i=0;i0; + ai: { + combo: "rezhengrong" }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('请选择要移去的「荣」',player.getExpansions('rezhengrong'),'hidden'); + }, + reqingce: { + enable: "phaseUse", + audio: "drlt_qingce", + filter: function (event, player) { + return player.getExpansions("rezhengrong").length > 0; + }, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "请选择要移去的「荣」", + player.getExpansions("rezhengrong"), + "hidden" + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - card:links[0], - filterCard:function(){return false}, - selectCard:-1, - filterTarget:function(card,player,target){ - return target.countDiscardableCards(player,'ej')>0; + card: links[0], + filterCard: function () { + return false; }, - delay:false, - audio:'drlt_qingce', - content:lib.skill.reqingce.contentx, - ai:{ - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - if(att>0&&(target.countCards('j')>0||target.countCards('e',function(card){ - return get.value(card,target)<0; - }))) return 2; - if(att<0&&target.countCards('e')>0&&!target.hasSkillTag('noe')) return -1; + selectCard: -1, + filterTarget: function (card, player, target) { + return target.countDiscardableCards(player, "ej") > 0; + }, + delay: false, + audio: "drlt_qingce", + content: lib.skill.reqingce.contentx, + ai: { + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if ( + att > 0 && + (target.countCards("j") > 0 || + target.countCards("e", function (card) { + return get.value(card, target) < 0; + })) + ) + return 2; + if ( + att < 0 && + target.countCards("e") > 0 && + !target.hasSkillTag("noe") + ) + return -1; return 0; }, }, }, - } + }; }, - prompt:function(links,player){ - return '弃置一名角色装备区或判定区内的一张牌'; + prompt: function (links, player) { + return "弃置一名角色装备区或判定区内的一张牌"; }, }, - contentx:function(){ - 'step 0' - var card=lib.skill.reqingce_backup.card; + contentx: function () { + "step 0"; + var card = lib.skill.reqingce_backup.card; player.loseToDiscardpile(card); - 'step 1' - if(target.countDiscardableCards(player,'ej')>0){ - player.discardPlayerCard('ej',true,target); + "step 1"; + if (target.countDiscardableCards(player, "ej") > 0) { + player.discardPlayerCard("ej", true, target); } }, - ai:{ - order:8, - result:{ - player:function(player){ - if(game.hasPlayer(function(current){ - var att=get.attitude(player,current); - if((att>0&¤t.countCards('j')>0)||(att<0&¤t.countCards('e')>0)) return true; - return false; - })) return 1; + ai: { + order: 8, + result: { + player: function (player) { + if ( + game.hasPlayer(function (current) { + var att = get.attitude(player, current); + if ( + (att > 0 && current.countCards("j") > 0) || + (att < 0 && current.countCards("e") > 0) + ) + return true; + return false; + }) + ) + return 1; return 0; }, }, }, }, - fengji:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return typeof player.storage.fengji=='number'&&player.countCards('h')>=player.storage.fengji; + fengji: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + typeof player.storage.fengji == "number" && + player.countCards("h") >= player.storage.fengji + ); }, - content:function(){ + content: function () { player.draw(2); - player.addTempSkill('fengji3'); + player.addTempSkill("fengji3"); }, - group:'fengji2', - intro:{ - content:'上回合结束时的手牌数:#', + group: "fengji2", + intro: { + content: "上回合结束时的手牌数:#", }, }, - fengji2:{ - trigger:{player:'phaseEnd'}, - silent:true, - content:function(){ - player.storage.fengji=player.countCards('h'); - if(player.hasSkill('fengji')) player.markSkill('fengji'); + fengji2: { + trigger: { player: "phaseEnd" }, + silent: true, + content: function () { + player.storage.fengji = player.countCards("h"); + if (player.hasSkill("fengji")) player.markSkill("fengji"); }, }, - fengji3:{ - mod:{ - maxHandcardBase:function(player,num){ + fengji3: { + mod: { + maxHandcardBase: function (player, num) { return player.maxHp; }, }, }, - zhouxuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + zhouxuan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - check:function(card){ - return 6-get.value(card); + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' - player.addSkill('zhouxuan2'); - target.addTempSkill('zhouxuan_ai',{player:'phaseUseAfter'}); - player.storage.zhouxuan2={}; - player.storage.zhouxuan2.player=target; - var list=[]; - var basic=[]; - for(var i=0;i0) return Math.max(1,target.hp)*target.countCards('h',function(card){ - return target.getUseValue(card)>0; + event.basic = basic; + player + .chooseControl(list) + .set("prompt", "请选择一种基本牌的名称或非基本牌的类别") + .set("ai", function () { + var player = _status.event.player; + var target = player.storage.zhouxuan2.player; + var cards = target.getCards("h", function (card) { + return target.hasUseTarget(card); }); + var map = {}; + for (var i = 0; i < cards.length; i++) { + var type = get.type(cards[i], "trick"); + map[type == "basic" ? get.name(cards[i]) : type] = true; + } + if (map.equip) return "equip"; + if (map.trick) return "trick"; + if (map.sha) return "sha"; + if (map.tao) return "tao"; + return 0; + }); + "step 1"; + player.storage.zhouxuan2.card = result.control; + if (event.basic.includes(result.control)) player.storage.zhouxuan2.isbasic = true; + player.markSkill("zhouxuan2"); + }, + ai: { + order: 1, + result: { + player: function (player, target) { + if (get.attitude(player, target) > 0) + return ( + Math.max(1, target.hp) * + target.countCards("h", function (card) { + return target.getUseValue(card) > 0; + }) + ); return 0; }, }, }, }, - zhouxuan_ai:{ - mod:{ - aiOrder:function(player,card,num){ - if(game.hasPlayer(function(current){ - return current.storage.zhouxuan2&¤t.storage.zhouxuan2.player==player&&get.attitude(player,current)>0&&(current.storage.zhouxuan2.isbasic?card.name:get.type(card,'trick'))==current.storage.zhouxuan2.card; - })) return num+10; - } - }, - }, - zhouxuan2:{ - intro:{ - mark:function(player,storage){ - return get.translation(storage.player)+'使用或打出下一张牌时,若此牌为'+get.translation(storage.card)+(storage.isbasic?'':'牌')+',你观看牌堆顶的三张牌并分配给任意角色'; + zhouxuan_ai: { + mod: { + aiOrder: function (player, card, num) { + if ( + game.hasPlayer(function (current) { + return ( + current.storage.zhouxuan2 && + current.storage.zhouxuan2.player == player && + get.attitude(player, current) > 0 && + (current.storage.zhouxuan2.isbasic + ? card.name + : get.type(card, "trick")) == current.storage.zhouxuan2.card + ); + }) + ) + return num + 10; }, }, - audio:'zhouxuan', - forced:true, - charlotte:true, - trigger:{global:['useCard','respond']}, - filter:function(event,player){ - if(event.zhouxuanable) return true; - if(player.storage.zhouxuan2){ - var map=player.storage.zhouxuan2; - if(map.player!=event.player) return false; + }, + zhouxuan2: { + intro: { + mark: function (player, storage) { + return ( + get.translation(storage.player) + + "使用或打出下一张牌时,若此牌为" + + get.translation(storage.card) + + (storage.isbasic ? "" : "牌") + + ",你观看牌堆顶的三张牌并分配给任意角色" + ); + }, + }, + audio: "zhouxuan", + forced: true, + charlotte: true, + trigger: { global: ["useCard", "respond"] }, + filter: function (event, player) { + if (event.zhouxuanable) return true; + if (player.storage.zhouxuan2) { + var map = player.storage.zhouxuan2; + if (map.player != event.player) return false; delete player.storage.zhouxuan2; - player.unmarkSkill('zhouxuan2'); - if(map.card!=(map.isbasic?event.card.name:get.type(event.card,'trick'))) return false; - event.zhouxuanable=true; + player.unmarkSkill("zhouxuan2"); + if (map.card != (map.isbasic ? event.card.name : get.type(event.card, "trick"))) + return false; + event.zhouxuanable = true; return true; } return false; }, - logTarget:'player', - content:function(){ - 'step 0' - event.cards=game.cardsGotoOrdering(get.cards(3)).cards; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 1' - if(event.cards.length>1){ - player.chooseCardButton('周旋:请选择要分配的牌',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return 1; - return 0; + logTarget: "player", + content: function () { + "step 0"; + event.cards = game.cardsGotoOrdering(get.cards(3)).cards; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cards.length==1){ - event._result={links:event.cards.slice(0),bool:true}; - } - else{ + event.given_map = {}; + "step 1"; + if (event.cards.length > 1) { + player + .chooseCardButton("周旋:请选择要分配的牌", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + } else if (event.cards.length == 1) { + event._result = { links: event.cards.slice(0), bool: true }; + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.cards.removeArray(result.links); - event.togive=result.links.slice(0); - player.chooseTarget('选择一名角色获得'+get.translation(result.links),true).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.enemy){ - return -att; - } - else if(att>0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); + event.togive = result.links.slice(0); + player + .chooseTarget("选择一名角色获得" + get.translation(result.links), true) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); } - 'step 3' - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + "step 3"; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(cards.length>0) event.goto(1); - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length > 0) event.goto(1); + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - list.push([source,event.given_map[i]]); + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + list.push([source, event.given_map[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'draw', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "draw", + }).setContent("gaincardMultiple"); }, }, - reshanxi:{ - audio:'shanxi', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.hp>0&&player.countCards('h',function(card){ - if(_status.connectMode) return true; - return get.color(card)=='red'&&get.type(card)=='basic'; - })>0; + reshanxi: { + audio: "shanxi", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.hp > 0 && + player.countCards("h", function (card) { + if (_status.connectMode) return true; + return get.color(card) == "red" && get.type(card) == "basic"; + }) > 0 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:function(card){ - return get.color(card)=='red'&&get.type(card)=='basic'&&lib.filter.cardDiscardable.apply(this,arguments); + filterCard: function (card) { + return ( + get.color(card) == "red" && + get.type(card) == "basic" && + lib.filter.cardDiscardable.apply(this, arguments) + ); }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; + }, + prompt: get.prompt("reshanxi"), + prompt2: + "弃置一张红色基本牌并选择一名其他角色,将其的至多X张牌置于其武将牌上直到回合结束。(X为你的体力值)", + ai1: function () { + return -1; }, - prompt:get.prompt('reshanxi'), - prompt2:'弃置一张红色基本牌并选择一名其他角色,将其的至多X张牌置于其武将牌上直到回合结束。(X为你的体力值)', - ai1:function(){return -1}, }); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('reshanxi',event.target); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("reshanxi", event.target); player.discard(result.cards); - } - else event.finish(); - 'step 2' - var max=Math.min(player.hp,target.countCards('he')); - if(max>0&&target.isIn()){ - player.choosePlayerCard('he',target,true,[1,max]).set('forceAuto',true).set('prompt','将'+get.translation(target)+'的至多'+get.cnNumber(max)+'张牌置于其武将牌上'); - } - else event.finish(); - 'step 3' - target.addSkill('reshanxi2'); - target.addToExpansion(result.cards,'giveAuto',target).gaintag.add('reshanxi2'); + } else event.finish(); + "step 2"; + var max = Math.min(player.hp, target.countCards("he")); + if (max > 0 && target.isIn()) { + player + .choosePlayerCard("he", target, true, [1, max]) + .set("forceAuto", true) + .set( + "prompt", + "将" + + get.translation(target) + + "的至多" + + get.cnNumber(max) + + "张牌置于其武将牌上" + ); + } else event.finish(); + "step 3"; + target.addSkill("reshanxi2"); + target.addToExpansion(result.cards, "giveAuto", target).gaintag.add("reshanxi2"); }, }, - reshanxi2:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + reshanxi2: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('reshanxi2'); - if(cards.length) player.gain(cards,'draw'); - 'step 1' - player.removeSkill('reshanxi2'); + content: function () { + "step 0"; + var cards = player.getExpansions("reshanxi2"); + if (cards.length) player.gain(cards, "draw"); + "step 1"; + player.removeSkill("reshanxi2"); }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('reshanxi2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("reshanxi2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, - reqizhou:{ - trigger:{player:['equipEnd','loseEnd']}, - forced:true, - popup:false, - derivation:['reyingzi','qixi','rexuanfeng'], - filter:function(event,player){ - if(player.equiping) return false; - var suits=[]; - var es=player.getCards('e'); - for(var i=0;i3) suits.length=3; - if(player.additionalSkills.reqizhou){ - return player.additionalSkills.reqizhou.length!=suits.length; - } - else{ - return suits.length>0; + if (suits.length > 3) suits.length = 3; + if (player.additionalSkills.reqizhou) { + return player.additionalSkills.reqizhou.length != suits.length; + } else { + return suits.length > 0; } }, - content:function(){ - lib.skill.reqizhou.init(player,'reqizhou'); + content: function () { + lib.skill.reqizhou.init(player, "reqizhou"); }, - init:function(player,skill){ - var suits=[]; - var es=player.getCards('e'); - for(var i=0;i3) suits.length=3; + if (suits.length > 3) suits.length = 3; player.removeAdditionalSkill(skill); - switch(suits.length){ - case 1:player.addAdditionalSkill(skill,['reyingzi']);break; - case 2:player.addAdditionalSkill(skill,['reyingzi','qixi']);break; - case 3:player.addAdditionalSkill(skill,['reyingzi','qixi','rexuanfeng']);break; + switch (suits.length) { + case 1: + player.addAdditionalSkill(skill, ["reyingzi"]); + break; + case 2: + player.addAdditionalSkill(skill, ["reyingzi", "qixi"]); + break; + case 3: + player.addAdditionalSkill(skill, ["reyingzi", "qixi", "rexuanfeng"]); + break; } }, - ai:{ - threaten:1.2 - } + ai: { + threaten: 1.2, + }, }, - zhaohan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.phaseNumber<8; + zhaohan: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.phaseNumber < 8; }, - check:function(event,player){ - return player.phaseNumber<3; + check: function (event, player) { + return player.phaseNumber < 3; }, - content:function(){ - if(player.phaseNumber<5){ + content: function () { + if (player.phaseNumber < 5) { player.gainMaxHp(); player.recover(); - } - else player.loseMaxHp(); + } else player.loseMaxHp(); }, }, - rangjie:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + rangjie: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - var choiceList=['获得一张指定类型的牌']; - if(player.canMoveCard()) choiceList.push('移动场上的一张牌'); - player.chooseControl('cancel2').set('choiceList',choiceList).set('prompt',get.prompt('rangjie')).set('ai',function(){ - var player=_status.event.player; - if(player.canMoveCard(true)) return 1; - return 0; - }); - 'step 2' - if(result.control=='cancel2') event.finish(); - else{ - player.logSkill('rangjie'); + var choiceList = ["获得一张指定类型的牌"]; + if (player.canMoveCard()) choiceList.push("移动场上的一张牌"); + player + .chooseControl("cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("rangjie")) + .set("ai", function () { + var player = _status.event.player; + if (player.canMoveCard(true)) return 1; + return 0; + }); + "step 2"; + if (result.control == "cancel2") event.finish(); + else { + player.logSkill("rangjie"); player.draw(); - if(result.index==0){ - player.chooseControl('basic','trick','equip').set('prompt','选择获得一种类型的牌').set('ai',function(){ - var player=_status.event.player; - if(player.hp<=3&&!player.countCards('h',{name:['shan','tao']})) return 'basic'; - if(player.countCards('he',{type:'equip'})<2) return 'equip'; - return 'trick'; - }); - } - else{ + if (result.index == 0) { + player + .chooseControl("basic", "trick", "equip") + .set("prompt", "选择获得一种类型的牌") + .set("ai", function () { + var player = _status.event.player; + if (player.hp <= 3 && !player.countCards("h", { name: ["shan", "tao"] })) + return "basic"; + if (player.countCards("he", { type: "equip" }) < 2) return "equip"; + return "trick"; + }); + } else { player.moveCard(true); event.goto(4); } } - 'step 3' - var card=get.cardPile2(function(card){ - return get.type(card,'trick')==result.control; + "step 3"; + var card = get.cardPile2(function (card) { + return get.type(card, "trick") == result.control; }); - if(card) player.gain(card,'gain2','log'); - 'step 4' - if(event.count>0&&player.hasSkill('rangjie')) event.goto(1); + if (card) player.gain(card, "gain2", "log"); + "step 4"; + if (event.count > 0 && player.hasSkill("rangjie")) event.goto(1); }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } }, }, }, }, - yizheng:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hp<=player.hp&&player.canCompare(current); + yizheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.hp <= player.hp && player.canCompare(current); }); }, - filterTarget:function(card,player,current){ - return current.hp<=player.hp&&player.canCompare(current); + filterTarget: function (card, player, current) { + return current.hp <= player.hp && player.canCompare(current); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - target.skip('phaseDraw'); - target.addTempSkill('yizheng2',{player:'phaseDrawSkipped'}); - } - else player.loseMaxHp(); + "step 1"; + if (result.bool) { + target.skip("phaseDraw"); + target.addTempSkill("yizheng2", { player: "phaseDrawSkipped" }); + } else player.loseMaxHp(); }, - ai:{ - order:1, - result:{ - player:(player,target)=>{ - let hs=player.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + ai: { + order: 1, + result: { + player: (player, target) => { + let hs = player.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - if(!hs.length) return 0; - let a=get.number(hs[0]),b=4; - if(player.getDamagedHp()) b=2; - return -b*(1-Math.pow((a-1)/13,target.countCards('h'))); + if (!hs.length) return 0; + let a = get.number(hs[0]), + b = 4; + if (player.getDamagedHp()) b = 2; + return -b * (1 - Math.pow((a - 1) / 13, target.countCards("h"))); }, - target:(player,target)=>{ - if(target.skipList.includes('phaseDraw')||target.hasSkill('pingkou')||target.hasSkill('xinpingkou')) return 0; - let hs=player.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + target: (player, target) => { + if ( + target.skipList.includes("phaseDraw") || + target.hasSkill("pingkou") || + target.hasSkill("xinpingkou") + ) + return 0; + let hs = player.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - if(!hs.length) return 0; - return -Math.pow((get.number(hs[0])-1)/13,target.countCards('h'))*2; - } + if (!hs.length) return 0; + return -Math.pow((get.number(hs[0]) - 1) / 13, target.countCards("h")) * 2; + }, }, }, }, - yizheng2:{ - mark:true, - intro:{content:'跳过下回合的摸牌阶段'}, + yizheng2: { + mark: true, + intro: { content: "跳过下回合的摸牌阶段" }, }, - rw_zhuge_skill:{ - equipSkill:true, - audio:true, - firstDo:true, - trigger:{player:'useCard1'}, - forced:true, - filter:function(event,player){ - return !event.audioed&&event.card.name=='sha'&&player.countUsed('sha',true)>1&&event.getParent().type=='phase'; + rw_zhuge_skill: { + equipSkill: true, + audio: true, + firstDo: true, + trigger: { player: "useCard1" }, + forced: true, + filter: function (event, player) { + return ( + !event.audioed && + event.card.name == "sha" && + player.countUsed("sha", true) > 1 && + event.getParent().type == "phase" + ); }, - content:function(){ - trigger.audioed=true; + content: function () { + trigger.audioed = true; }, - mod:{ - cardUsable:function(card,player,num){ - var cards=player.getEquips('rewrite_zhuge') - if(card.name=='sha'){ - if(!cards.length||player.hasSkill('rw_zhuge_skill',null,false)||cards.some(card=>(card!=_status.rw_zhuge_temp&&!ui.selected.cards.includes(card)))){ - if(get.is.versus()||get.is.changban()){ - return num+3; + mod: { + cardUsable: function (card, player, num) { + var cards = player.getEquips("rewrite_zhuge"); + if (card.name == "sha") { + if ( + !cards.length || + player.hasSkill("rw_zhuge_skill", null, false) || + cards.some( + (card) => + card != _status.rw_zhuge_temp && !ui.selected.cards.includes(card) + ) + ) { + if (get.is.versus() || get.is.changban()) { + return num + 3; } return Infinity; } } }, - cardEnabled2:function(card,player){ - if(!_status.event.addCount_extra||player.hasSkill('rw_zhuge_skill',null,false)) return; - var cards=player.getEquips('rewrite_zhuge'); - if(card&&cards.includes(card)){ - try{ - var cardz=get.card(); - } - catch(e){ + cardEnabled2: function (card, player) { + if (!_status.event.addCount_extra || player.hasSkill("rw_zhuge_skill", null, false)) + return; + var cards = player.getEquips("rewrite_zhuge"); + if (card && cards.includes(card)) { + try { + var cardz = get.card(); + } catch (e) { return; } - if(!cardz||cardz.name!='sha') return; - _status.rw_zhuge_temp=card; - var bool=lib.filter.cardUsable(get.autoViewAs({name:'sha'},ui.selected.cards.concat([card])),player); + if (!cardz || cardz.name != "sha") return; + _status.rw_zhuge_temp = card; + var bool = lib.filter.cardUsable( + get.autoViewAs({ name: "sha" }, ui.selected.cards.concat([card])), + player + ); delete _status.rw_zhuge_temp; - if(!bool) return false; + if (!bool) return false; } }, }, }, - xinqingjian:{ - audio:'qingjian', - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + xinqingjian: { + audio: "qingjian", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - direct:true, - usable:1, - filter:function(event,player){ - return event.getg(player).length&&event.getParent('phaseDraw').player!=player&&player.countCards('he')>0; + direct: true, + usable: 1, + filter: function (event, player) { + return ( + event.getg(player).length && + event.getParent("phaseDraw").player != player && + player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('xinqingjian'),'he',[1,player.countCards('he')]).ai=function(){return -1}; - 'step 1' - if(result.bool){ - player.logSkill('xinqingjian'); - player.addSkill('xinqingjian2'); - player.addToExpansion(result.cards,'giveAuto',player).gaintag.add('xinqingjian2'); - } - else player.storage.counttrigger.xinqingjian--; + content: function () { + "step 0"; + player.chooseCard(get.prompt2("xinqingjian"), "he", [1, player.countCards("he")]).ai = + function () { + return -1; + }; + "step 1"; + if (result.bool) { + player.logSkill("xinqingjian"); + player.addSkill("xinqingjian2"); + player.addToExpansion(result.cards, "giveAuto", player).gaintag.add("xinqingjian2"); + } else player.storage.counttrigger.xinqingjian--; }, }, - xinqingjian2:{ - audio:'xinqingjian', - charlotte:true, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('xinqingjian2').length>0; + xinqingjian2: { + audio: "xinqingjian", + charlotte: true, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("xinqingjian2").length > 0; }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('xinqingjian2'); - player.chooseTarget(true,lib.filter.notMe).set('createDialog',['清俭:将这些牌交给一名角色'+(cards.length>1?',然后摸一张牌':''),cards]); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'thunder'); - if(player.give(player.getExpansions('xinqingjian2'),target).cards.length>1) player.draw(); + content: function () { + "step 0"; + var cards = player.getExpansions("xinqingjian2"); + player + .chooseTarget(true, lib.filter.notMe) + .set("createDialog", [ + "清俭:将这些牌交给一名角色" + (cards.length > 1 ? ",然后摸一张牌" : ""), + cards, + ]); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "thunder"); + if (player.give(player.getExpansions("xinqingjian2"), target).cards.length > 1) + player.draw(); } - 'step 2' - player.removeSkill('xinqingjian2'); + "step 2"; + player.removeSkill("xinqingjian2"); }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('xinqingjian2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("xinqingjian2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, - zhongzuo:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getHistory('damage').length>0||player.getHistory('sourceDamage').length>0; + zhongzuo: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getHistory("damage").length > 0 || player.getHistory("sourceDamage").length > 0 + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhongzuo'),'令一名角色摸两张牌。若其已受伤,则你摸一张牌。').set('ai',function(target){ - if(target.hasSkillTag('nogain')) return target.isDamaged()?0:1; - let att=get.attitude(_status.event.player,target); - if(att<=0) return 0; - if(target.isDamaged()) return 1+att/5; - return att/5; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhongzuo',target); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhongzuo"), + "令一名角色摸两张牌。若其已受伤,则你摸一张牌。" + ) + .set("ai", function (target) { + if (target.hasSkillTag("nogain")) return target.isDamaged() ? 0 : 1; + let att = get.attitude(_status.event.player, target); + if (att <= 0) return 0; + if (target.isDamaged()) return 1 + att / 5; + return att / 5; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhongzuo", target); target.draw(2); - if(target.isDamaged()) player.draw(); + if (target.isDamaged()) player.draw(); } }, }, - wanlan:{ - audio:2, - trigger:{global:'dying'}, - check:function(event,player){ - if(get.attitude(player,event.player)<4) return false; - if(player.countCards('hs',card=>player.canSaveCard(card,event.player))>=1-event.player.hp) return false; - if(event.player==player||event.player==get.zhu(player)) return true; - if(_status.currentPhase&&get.damageEffect(_status.currentPhase,player,player)<0) return false; + wanlan: { + audio: 2, + trigger: { global: "dying" }, + check: function (event, player) { + if (get.attitude(player, event.player) < 4) return false; + if ( + player.countCards("hs", (card) => player.canSaveCard(card, event.player)) >= + 1 - event.player.hp + ) + return false; + if (event.player == player || event.player == get.zhu(player)) return true; + if (_status.currentPhase && get.damageEffect(_status.currentPhase, player, player) < 0) + return false; return !player.hasUnknown(); }, - limited:true, - unique:true, - filter:function(event,player){ - return event.player.hp<=0; + limited: true, + unique: true, + filter: function (event, player) { + return event.player.hp <= 0; }, - skillAnimation:true, - animationColor:'thunder', - logTarget:'player', - content:function(){ - 'step 0' - player.awakenSkill('wanlan'); - var hs=player.getCards('h') - if(hs.length) player.discard(hs); - 'step 1' - var num=1-trigger.player.hp; - if(num) trigger.player.recover(num); - 'step 2' - if(_status.currentPhase&&_status.currentPhase.isIn()){ - var next=_status.currentPhase.damage(); + skillAnimation: true, + animationColor: "thunder", + logTarget: "player", + content: function () { + "step 0"; + player.awakenSkill("wanlan"); + var hs = player.getCards("h"); + if (hs.length) player.discard(hs); + "step 1"; + var num = 1 - trigger.player.hp; + if (num) trigger.player.recover(num); + "step 2"; + if (_status.currentPhase && _status.currentPhase.isIn()) { + var next = _status.currentPhase.damage(); event.next.remove(next); trigger.after.push(next); } }, }, - rezhiyi:{ - audio:'zhiyi', - trigger:{global:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.getHistory('useCard',function(card){ - return get.type(card.card)=='basic'; - }).length>0||player.getHistory('respond',function(card){ - return get.type(card.card)=='basic'; - }).length>0; + rezhiyi: { + audio: "zhiyi", + trigger: { global: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.getHistory("useCard", function (card) { + return get.type(card.card) == "basic"; + }).length > 0 || + player.getHistory("respond", function (card) { + return get.type(card.card) == "basic"; + }).length > 0 + ); }, - content:function(){ - 'step 0' - var list=[]; - player.getHistory('useCard',function(evt){ - if(get.type(evt.card)!='basic') return; - var name=evt.card.name; - if(name=='sha'){ - var nature=evt.card.nature; - switch(nature){ - case 'fire':name='huosha';break; - case 'thunder':name='leisha';break; - case 'kami':name='kamisha';break; - case 'ice':name='icesha';break; - case 'stab':name='cisha';break; + content: function () { + "step 0"; + var list = []; + player.getHistory("useCard", function (evt) { + if (get.type(evt.card) != "basic") return; + var name = evt.card.name; + if (name == "sha") { + var nature = evt.card.nature; + switch (nature) { + case "fire": + name = "huosha"; + break; + case "thunder": + name = "leisha"; + break; + case "kami": + name = "kamisha"; + break; + case "ice": + name = "icesha"; + break; + case "stab": + name = "cisha"; + break; } } list.add(name); }); - player.getHistory('respond',function(evt){ - if(get.type(evt.card)!='basic') return; - var name=evt.card.name; - if(name=='sha'){ - var nature=evt.card.nature; - switch(nature){ - case 'fire':name='huosha';break; - case 'thunder':name='leisha';break; - case 'kami':name='kamisha';break; - case 'ice':name='icesha';break; - case 'stab':name='cisha';break; + player.getHistory("respond", function (evt) { + if (get.type(evt.card) != "basic") return; + var name = evt.card.name; + if (name == "sha") { + var nature = evt.card.nature; + switch (nature) { + case "fire": + name = "huosha"; + break; + case "thunder": + name = "leisha"; + break; + case "kami": + name = "kamisha"; + break; + case "ice": + name = "icesha"; + break; + case "stab": + name = "cisha"; + break; } } list.add(name); }); - player.chooseButton(['执义:选择要使用的牌,或点取消摸一张牌',[list.map(function(name){ - return ['基本','',name]; - }),'vcard']],function(button){ - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); - },function(button){ - return _status.event.player.hasUseTarget({name:button.link[2],nature:button.link[3]}); - }); - 'step 1' - if(!result.bool) player.draw(); - else player.chooseUseTarget({name:result.links[0][2],isCard:true,nature:result.links[0][3]},true); + player.chooseButton( + [ + "执义:选择要使用的牌,或点取消摸一张牌", + [ + list.map(function (name) { + return ["基本", "", name]; + }), + "vcard", + ], + ], + function (button) { + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }, + function (button) { + return _status.event.player.hasUseTarget({ + name: button.link[2], + nature: button.link[3], + }); + } + ); + "step 1"; + if (!result.bool) player.draw(); + else + player.chooseUseTarget( + { name: result.links[0][2], isCard: true, nature: result.links[0][3] }, + true + ); }, }, - zhiyi:{ - audio:2, - trigger:{player:['useCard','respond']}, - forced:true, - filter:function(event,player){ - if(get.type(event.card)!='basic') return false; - var history=player.getHistory('useCard',function(evt){ - return get.type(evt.card)=='basic'; - }).concat(player.getHistory('respond',function(evt){ - return get.type(evt.card)=='basic'; - })); - return history.length==1&&history[0]==event; + zhiyi: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter: function (event, player) { + if (get.type(event.card) != "basic") return false; + var history = player + .getHistory("useCard", function (evt) { + return get.type(evt.card) == "basic"; + }) + .concat( + player.getHistory("respond", function (evt) { + return get.type(evt.card) == "basic"; + }) + ); + return history.length == 1 && history[0] == event; }, - content:function(){ - 'step 0' - var info=get.info(trigger.card); - if(!info||!info.enable) event._result={index:0}; - else{ - var evt=trigger; - if(evt.respondTo&&evt.getParent('useCard').name=='useCard') evt=evt.getParent('useCard'); - event.evt=evt; - player.chooseControl().set('prompt','执义:请选择一项').set('choiceList',[ - '摸一张牌', - '于'+get.translation(evt.card)+'的使用结算结束之后视为使用一张'+get.translation({name:trigger.card.name,nature:trigger.card.nature,isCard:true}), - ]).set('ai',function(){return _status.event.choice}).set('choice',function(){ - var card={name:trigger.card.name,nature:trigger.card.nature,isCard:true}; - if(card.name=='sha'){ - if(player.getUseValue(card)>0) return 1; - } - else if(card.name=='tao'){ - var hp=player.maxHp-player.hp; - if(trigger.targets.includes(player)) hp--; - return hp>0?1:0; - } - return 0; - }()); + content: function () { + "step 0"; + var info = get.info(trigger.card); + if (!info || !info.enable) event._result = { index: 0 }; + else { + var evt = trigger; + if (evt.respondTo && evt.getParent("useCard").name == "useCard") + evt = evt.getParent("useCard"); + event.evt = evt; + player + .chooseControl() + .set("prompt", "执义:请选择一项") + .set("choiceList", [ + "摸一张牌", + "于" + + get.translation(evt.card) + + "的使用结算结束之后视为使用一张" + + get.translation({ + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + }), + ]) + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + }; + if (card.name == "sha") { + if (player.getUseValue(card) > 0) return 1; + } else if (card.name == "tao") { + var hp = player.maxHp - player.hp; + if (trigger.targets.includes(player)) hp--; + return hp > 0 ? 1 : 0; + } + return 0; + })() + ); } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { player.draw(); - } - else{ - var next=player.chooseUseTarget({name:trigger.card.name,nature:trigger.card.nature,isCard:true},false,true); + } else { + var next = player.chooseUseTarget( + { name: trigger.card.name, nature: trigger.card.nature, isCard: true }, + false, + true + ); _status.event.next.remove(next); event.evt.after.push(next); - next.logSkill='zhiyi'; + next.logSkill = "zhiyi"; } }, }, //表演测试 - qiaosi_map:{charlotte:true}, - qiaosi:{ - audio:'xinfu_qiaosi', - derivation:'qiaosi_map', - enable:'phaseUse', - usable:1, - content:function(){ - "step 0" - event.videoId=lib.status.videoId++; - if(player.isUnderControl()){ + qiaosi_map: { charlotte: true }, + qiaosi: { + audio: "xinfu_qiaosi", + derivation: "qiaosi_map", + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + event.videoId = lib.status.videoId++; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ + var switchToAuto = function () { game.pause(); game.countChoose(); - setTimeout(function(){ - _status.imchoosing=false; - event._result={ - bool:true, - links:['qiaosi_c1','qiaosi_c6'].concat(['qiaosi_c2','qiaosi_c3','qiaosi_c4','qiaosi_c5'].randomGets(1)), + setTimeout(function () { + _status.imchoosing = false; + event._result = { + bool: true, + links: ["qiaosi_c1", "qiaosi_c6"].concat( + ["qiaosi_c2", "qiaosi_c3", "qiaosi_c4", "qiaosi_c5"].randomGets(1) + ), }; - if(event.dialog) event.dialog.close(); - if(event.controls){ - for(var i of event.controls) i.close(); + if (event.dialog) event.dialog.close(); + if (event.controls) { + for (var i of event.controls) i.close(); } game.resume(); - },5000); + }, 5000); }; - var createDialog=function(player,id){ - if(player==game.me) return; - var str=get.translation(player)+'正在表演...
              '; - for(var i=1;i<7;i++){ - str+=get.translation('qiaosi_c'+i); - if(i%3!=0) str+='  '; - if(i==3) str+='
              '; + var createDialog = function (player, id) { + if (player == game.me) return; + var str = get.translation(player) + "正在表演...
              "; + for (var i = 1; i < 7; i++) { + str += get.translation("qiaosi_c" + i); + if (i % 3 != 0) str += "  "; + if (i == 3) str += "
              "; } - ui.create.dialog(str,'forcebutton').videoId=id; + ui.create.dialog(str, "forcebutton").videoId = id; }; - var chooseButton=function(player){ - var event=_status.event; - player=player||event.player; - event.status={ - qiaosi_c1:0, - qiaosi_c2:0, - qiaosi_c3:0, - qiaosi_c4:0, - qiaosi_c5:0, - qiaosi_c6:0, - } - event.map={ - qiaosi_c1:[40,60], - qiaosi_c2:[80,120], - qiaosi_c3:[90,110], - qiaosi_c4:[90,110], - qiaosi_c5:[80,120], - qiaosi_c6:[40,60], - } - event.finishedx=[]; - event.str='请开始你的表演
              qiaosi_c1% qiaosi_c2% qiaosi_c3%
              qiaosi_c4%qiaosi_c5% qiaosi_c6%'; - event.dialog=ui.create.dialog(event.str,'forcebutton','hidden'); - event.dialog.addText('
            • 点击下方的按钮,可以增加按钮对应的角色的「表演完成度」。对于不同的角色,点击时增加的完成度不同,最终获得的牌也不同。一次表演最多只能完成3名角色的进度。',false); + var chooseButton = function (player) { + var event = _status.event; + player = player || event.player; + event.status = { + qiaosi_c1: 0, + qiaosi_c2: 0, + qiaosi_c3: 0, + qiaosi_c4: 0, + qiaosi_c5: 0, + qiaosi_c6: 0, + }; + event.map = { + qiaosi_c1: [40, 60], + qiaosi_c2: [80, 120], + qiaosi_c3: [90, 110], + qiaosi_c4: [90, 110], + qiaosi_c5: [80, 120], + qiaosi_c6: [40, 60], + }; + event.finishedx = []; + event.str = + '请开始你的表演
              qiaosi_c1% qiaosi_c2% qiaosi_c3%
              qiaosi_c4%qiaosi_c5% qiaosi_c6%'; + event.dialog = ui.create.dialog(event.str, "forcebutton", "hidden"); + event.dialog.addText( + "
            • 点击下方的按钮,可以增加按钮对应的角色的「表演完成度」。对于不同的角色,点击时增加的完成度不同,最终获得的牌也不同。一次表演最多只能完成3名角色的进度。", + false + ); event.dialog.open(); - for(var i in event.status){ - event.dialog.content.childNodes[0].innerHTML=event.dialog.content.childNodes[0].innerHTML.replace(i,event.status[i]); + for (var i in event.status) { + event.dialog.content.childNodes[0].innerHTML = + event.dialog.content.childNodes[0].innerHTML.replace(i, event.status[i]); } - for(var i=0;i=100){ - event.status[link]=100; - var str=event.str.slice(0); - for(var i in event.status){ - str=str.replace(i,event.status[i]); - } - event.dialog.content.childNodes[0].innerHTML=str; - event.finishedx.push(link); - if(event.finishedx.length>=3){ - event._result={ - bool:true, - links:event.finishedx.slice(0), - }; - event.dialog.close(); - for(var i of event.controls) i.close(); - game.resume(); - _status.imchoosing=false; - } - } - else{ - var str=event.str.slice(0); - for(var i in event.status){ - str=str.replace(i,event.status[i]); - } - event.dialog.content.childNodes[0].innerHTML=str; - } - })); - for(var i=0;i= 100) { + event.status[link] = 100; + var str = event.str.slice(0); + for (var i in event.status) { + str = str.replace(i, event.status[i]); + } + event.dialog.content.childNodes[0].innerHTML = str; + event.finishedx.push(link); + if (event.finishedx.length >= 3) { + event._result = { + bool: true, + links: event.finishedx.slice(0), + }; + event.dialog.close(); + for (var i of event.controls) i.close(); + game.resume(); + _status.imchoosing = false; + } + } else { + var str = event.str.slice(0); + for (var i in event.status) { + str = str.replace(i, event.status[i]); + } + event.dialog.content.childNodes[0].innerHTML = str; + } + }) + ); + for (var i = 0; i < event.dialog.buttons.length; i++) { + event.dialog.buttons[i].classList.add("selectable"); } game.pause(); game.countChoose(); }; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId); - if(event.isMine()){ + game.broadcastAll(createDialog, player, event.videoId); + if (event.isMine()) { chooseButton(); - } - else if(event.isOnline()){ - event.player.send(chooseButton,event.player); + } else if (event.isOnline()) { + event.player.send(chooseButton, event.player); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - game.broadcastAll('closeDialog',event.videoId); - var map=event.result||result; + "step 1"; + game.broadcastAll("closeDialog", event.videoId); + var map = event.result || result; //game.print(map); - if(!map||!map.bool||!map.links){ - game.log(player,'表演失败'); + if (!map || !map.bool || !map.links) { + game.log(player, "表演失败"); event.finish(); return; } - var list=map.links; - if(!list.length){ - game.log(player,'表演失败'); + var list = map.links; + if (!list.length) { + game.log(player, "表演失败"); event.finish(); return; } - var cards=[]; - var list2=[]; - if(list.includes('qiaosi_c1')){ - list2.push('trick'); - list2.push('trick'); + var cards = []; + var list2 = []; + if (list.includes("qiaosi_c1")) { + list2.push("trick"); + list2.push("trick"); } - if(list.includes('qiaosi_c2')){ - if(list.includes('qiaosi_c1')) list2.push(['sha','jiu']); - else list2.push(Math.random()<0.66?'equip':['sha','jiu']); + if (list.includes("qiaosi_c2")) { + if (list.includes("qiaosi_c1")) list2.push(["sha", "jiu"]); + else list2.push(Math.random() < 0.66 ? "equip" : ["sha", "jiu"]); } - if(list.includes('qiaosi_c3')){ - list2.push([Math.random()<0.66?'sha':'jiu']) + if (list.includes("qiaosi_c3")) { + list2.push([Math.random() < 0.66 ? "sha" : "jiu"]); } - if(list.includes('qiaosi_c4')){ - list2.push([Math.random()<0.66?'shan':'tao']) + if (list.includes("qiaosi_c4")) { + list2.push([Math.random() < 0.66 ? "shan" : "tao"]); } - if(list.includes('qiaosi_c5')){ - if(list.includes('qiaosi_c6')) list2.push(['shan','tao']); - else list2.push(Math.random()<0.66?'trick':['shan','tao']); + if (list.includes("qiaosi_c5")) { + if (list.includes("qiaosi_c6")) list2.push(["shan", "tao"]); + else list2.push(Math.random() < 0.66 ? "trick" : ["shan", "tao"]); } - if(list.includes('qiaosi_c6')){ - list2.push('equip'); - list2.push('equip'); + if (list.includes("qiaosi_c6")) { + list2.push("equip"); + list2.push("equip"); } - while(list2.length){ - var filter=list2.shift(); - var card=get.cardPile(function(x){ - if(cards.includes(x)) return false; - if(typeof filter=='string'&&get.type(x,'trick')==filter) return true; - if(typeof filter=='object'&&filter.includes(x.name)) return true; + while (list2.length) { + var filter = list2.shift(); + var card = get.cardPile(function (x) { + if (cards.includes(x)) return false; + if (typeof filter == "string" && get.type(x, "trick") == filter) return true; + if (typeof filter == "object" && filter.includes(x.name)) return true; }); - if(card) cards.push(card); - else{ - var card=get.cardPile(function(x){ + if (card) cards.push(card); + else { + var card = get.cardPile(function (x) { return !cards.includes(x); }); - if(card) cards.push(card); + if (card) cards.push(card); } } - if(cards.length){ - event.cards=cards; - event.num=cards.length; + if (cards.length) { + event.cards = cards; + event.num = cards.length; player.showCards(cards); - } - else event.finish(); - "step 2" - player.gain(event.cards,'gain2'); - player.chooseControl().set('choiceList',[ - '将'+get.cnNumber(event.num)+'张牌交给一名其他角色', - '弃置'+get.cnNumber(event.num)+'张牌', - ]).set('ai',function(){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>2; - })) return 0; - return 1; - }); - "step 3" - if(result.index==0){ + } else event.finish(); + "step 2"; + player.gain(event.cards, "gain2"); + player + .chooseControl() + .set("choiceList", [ + "将" + get.cnNumber(event.num) + "张牌交给一名其他角色", + "弃置" + get.cnNumber(event.num) + "张牌", + ]) + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 2; + }) + ) + return 0; + return 1; + }); + "step 3"; + if (result.index == 0) { player.chooseCardTarget({ - position:'he', - filterCard:true, - selectCard:event.num, - filterTarget:function(card,player,target){ - return player!=target; + position: "he", + filterCard: true, + selectCard: event.num, + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ + ai1: function (card) { return 1; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkillTag('nogain')) att/=10; - if(target.hasJudge('lebu')) att/=5; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 10; + if (target.hasJudge("lebu")) att /= 5; return att; }, - prompt:'选择'+get.cnNumber(event.num)+'张牌,交给一名其他角色。', - forced:true, + prompt: "选择" + get.cnNumber(event.num) + "张牌,交给一名其他角色。", + forced: true, }); - } - else{ - player.chooseToDiscard(event.num,true,'he'); + } else { + player.chooseToDiscard(event.num, true, "he"); event.finish(); } - "step 4" - if(result.bool){ - var target=result.targets[0]; - player.give(result.cards,target); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.give(result.cards, target); } }, - ai:{ - order:10, - result:{player:1}, - threaten:3.2, - } + ai: { + order: 10, + result: { player: 1 }, + threaten: 3.2, + }, }, - refuhai:{ - audio:'xinfu_fuhai', - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' - event.current=player.next; - event.upper=[]; - event.lower=[]; - event.acted=[]; - event.num=0; - event.stopped=false; - 'step 1' + refuhai: { + audio: "xinfu_fuhai", + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + event.current = player.next; + event.upper = []; + event.lower = []; + event.acted = []; + event.num = 0; + event.stopped = false; + "step 1"; event.acted.push(event.current); - event.current.chooseControl('潮起','潮落').set('prompt','潮鸣起乎?潮鸣落乎?').ai=function(){ - return Math.random()<0.5?0:1; - }; - 'step 2' - if(!event.chosen) event.chosen=result.control; - if(event.chosen!=result.control) event.stopped=true; - if(!event.stopped) event.num++; - if(result.control=='潮起'){ - event.upper.push(event.current) - } - else event.lower.push(event.current); - event.current=event.current.next; - if(event.current!=player&&!event.acted.includes(event.current)) event.goto(1); - 'step 3' - for(var i=0;i1) player.draw(num); + "step 4"; + if (num > 1) player.draw(num); }, - ai:{ - order:10, - result:{player:1}, + ai: { + order: 10, + result: { player: 1 }, }, }, - rebiaozhao:{ - audio:'biaozhao', - intro:{ - content:"expansion", - markcount:'expansion', + rebiaozhao: { + audio: "biaozhao", + intro: { + content: "expansion", + markcount: "expansion", }, - trigger:{ - player:"phaseJieshuBegin", + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0&&!player.getExpansions('rebiaozhao').length; + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0 && !player.getExpansions("rebiaozhao").length; }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('rebiaozhao'),'将一张牌置于武将牌上作为“表”').ai=function(card){ - return 6-get.value(card); - } - 'step 1' - if(result.bool){ - player.logSkill('rebiaozhao'); - player.addToExpansion(player,'give',result.cards).gaintag.add('rebiaozhao'); + content: function () { + "step 0"; + player.chooseCard("he", get.prompt("rebiaozhao"), "将一张牌置于武将牌上作为“表”").ai = + function (card) { + return 6 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.logSkill("rebiaozhao"); + player.addToExpansion(player, "give", result.cards).gaintag.add("rebiaozhao"); } }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{notemp:true}, - group:['rebiaozhao2','rebiaozhao3'], + ai: { notemp: true }, + group: ["rebiaozhao2", "rebiaozhao3"], }, - rebiaozhao2:{ - trigger:{ - global:["loseAfter","cardsDiscardAfter","loseAsyncAfter",'equipAfter'], + rebiaozhao2: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - forced:true, - audio:"biaozhao", - filter:function(event,player){ - var cards=player.getExpansions('rebiaozhao'),cards2=event.getd(); - if(!cards.length||!cards2.length) return false; - var num=get.number(cards[0]); - var cards=event.getd(); - for(var card of cards){ - if(get.number(card)==num) return true; + forced: true, + audio: "biaozhao", + filter: function (event, player) { + var cards = player.getExpansions("rebiaozhao"), + cards2 = event.getd(); + if (!cards.length || !cards2.length) return false; + var num = get.number(cards[0]); + var cards = event.getd(); + for (var card of cards) { + if (get.number(card) == num) return true; } return false; }, - content:function(){ - player.loseToDiscardpile(player.getExpansions('rebiaozhao')); + content: function () { + player.loseToDiscardpile(player.getExpansions("rebiaozhao")); player.loseHp(); }, }, - rebiaozhao3:{ - trigger:{ - player:"phaseZhunbeiBegin", + rebiaozhao3: { + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - charlotte:true, - audio:"biaozhao", - filter:function(event,player){ - return player.getExpansions('rebiaozhao').length>0; + forced: true, + charlotte: true, + audio: "biaozhao", + filter: function (event, player) { + return player.getExpansions("rebiaozhao").length > 0; }, - content:function(){ - "step 0" - player.loseToDiscardpile(player.getExpansions('rebiaozhao')); - "step 1" - player.chooseTarget('令一名角色摸三张牌并回复1点体力',true).ai=function(target){ - var num=2; - if(target.isDamaged()) num++; - return num*get.attitude(_status.event.player,target); + content: function () { + "step 0"; + player.loseToDiscardpile(player.getExpansions("rebiaozhao")); + "step 1"; + player.chooseTarget("令一名角色摸三张牌并回复1点体力", true).ai = function (target) { + var num = 2; + if (target.isDamaged()) num++; + return num * get.attitude(_status.event.player, target); }; - "step 2" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(3); target.recover(); } }, }, - reqianxin:{ - audio:'xinfu_qianxin', - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:function(){ - return [1,Math.min(2,game.players.length-1)]; + reqianxin: { + audio: "xinfu_qianxin", + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: function () { + return [1, Math.min(2, game.players.length - 1)]; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - discard:false, - lose:false, - delay:false, - content:function(){ - var targets=game.filterPlayer(function(current){ - return current!=player; - }).randomGets(cards.length); - var map=[]; - for(var i=0;i0) return 0; - if(player.maxHp-player.countCards('h')>1) return 1; - return Math.random()>0.5?0:1; - }); - 'step 2' - if(result.index==0) source.draw(2); - else{ - player.addTempSkill('reqianxin3') - player.addMark('reqianxin3',2,false) + content: function () { + "step 0"; + var current = player.storage.reqianxin2.shift(); + event.source = current[1]; + if (!event.source.isIn() || !player.getCards("h").includes(current[0])) event.goto(3); + "step 1"; + source.logSkill("reqianxin", player); + player + .chooseControl() + .set("choiceList", [ + "令" + get.translation(source) + "摸两张牌", + "令自己本回合的手牌上限-2", + ]) + .set("prompt", get.translation(source) + "发动了【遣信】,请选择一项") + .set("source", source) + .set("ai", function () { + var player = _status.event.player; + if (get.attitude(player, _status.event.source) > 0) return 0; + if (player.maxHp - player.countCards("h") > 1) return 1; + return Math.random() > 0.5 ? 0 : 1; + }); + "step 2"; + if (result.index == 0) source.draw(2); + else { + player.addTempSkill("reqianxin3"); + player.addMark("reqianxin3", 2, false); } - 'step 3' - if(player.storage.reqianxin2.length) event.goto(0); - else player.removeSkill('reqianxin2'); + "step 3"; + if (player.storage.reqianxin2.length) event.goto(0); + else player.removeSkill("reqianxin2"); }, }, - reqianxin3:{ - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('reqianxin3'); + reqianxin3: { + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("reqianxin3"); }, }, }, - renshi:{ - audio:2, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return player.isDamaged()&&event.card&&event.card.name=='sha'; + renshi: { + audio: 2, + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return player.isDamaged() && event.card && event.card.name == "sha"; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.cancel(); - if(trigger.cards){ - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2','log'); + if (trigger.cards) { + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2", "log"); } - 'step 1' + "step 1"; player.loseMaxHp(); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha') return true; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha") return true; return false; }, }, }, - wuyuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h','sha')>0; + wuyuan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - filterCard:{name:'sha'}, - filterTarget:lib.filter.notMe, - check:function(card){ - var player=_status.event.player; - if(get.color(card)=='red'&&game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged()&&get.attitude(player,current)>2; - })) return 2; - if(get.natureList(card).length) return 1.5; + filterCard: { name: "sha" }, + filterTarget: lib.filter.notMe, + check: function (card) { + var player = _status.event.player; + if ( + get.color(card) == "red" && + game.hasPlayer(function (current) { + return ( + current != player && current.isDamaged() && get.attitude(player, current) > 2 + ); + }) + ) + return 2; + if (get.natureList(card).length) return 1.5; return 1; }, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.give(cards,target,'give'); + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.give(cards, target, "give"); player.recover(); - 'step 1' - var num=1; - if(get.natureList(cards[0]).length) num++; + "step 1"; + var num = 1; + if (get.natureList(cards[0]).length) num++; target.draw(num); - if(get.color(cards[0])=='red') target.recover(); + if (get.color(cards[0]) == "red") target.recover(); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.isDamaged()) return 1; + ai: { + order: 1, + result: { + player: function (player, target) { + if (player.isDamaged()) return 1; return 0; }, - target:function(player,target){ - if(ui.selected.cards.length){ - var num=1; - if(get.natureList(ui.selected.cards[0]).length) num++; - if(target.hasSkillTag('nogain')) num=0; - if(get.color(ui.selected.cards[0])=='red') return num+2 - else return num+1; + target: function (player, target) { + if (ui.selected.cards.length) { + var num = 1; + if (get.natureList(ui.selected.cards[0]).length) num++; + if (target.hasSkillTag("nogain")) num = 0; + if (get.color(ui.selected.cards[0]) == "red") return num + 2; + else return num + 1; } return 1; }, }, }, }, - huaizi:{ - mod:{ - maxHandcardBase:function(player,num){ + huaizi: { + mod: { + maxHandcardBase: function (player, num) { return player.maxHp; }, }, //audio:2, //trigger:{player:'phaseDiscardBegin'}, - forced:true, - firstDo:true, - filter:function(event,player){ - return player.isDamaged()&&player.countCards('h')>player.hp; + forced: true, + firstDo: true, + filter: function (event, player) { + return player.isDamaged() && player.countCards("h") > player.hp; }, - content:function(){}, + content: function () {}, }, - rexushen:{ - derivation:['new_rewusheng','redangxian'], - audio:'xinfu_xushen', - limited:true, - enable:'phaseUse', - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hasSex('male'); - }) + rexushen: { + derivation: ["new_rewusheng", "redangxian"], + audio: "xinfu_xushen", + limited: true, + enable: "phaseUse", + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.hasSex("male"); + }); }, - skillAnimation:true, - animationColor:'fire', - content:function(){ - player.addSkill('rexushen2'); - player.awakenSkill('rexushen'); - player.loseHp(game.countPlayer(function(current){ - return current.hasSex('male'); - })); + skillAnimation: true, + animationColor: "fire", + content: function () { + player.addSkill("rexushen2"); + player.awakenSkill("rexushen"); + player.loseHp( + game.countPlayer(function (current) { + return current.hasSex("male"); + }) + ); }, - ai:{ - order:10, - result:{ - player:function(player){ - if(player.hp!=game.countPlayer(function(current){ - return current.hasSex('male'); - })) return 0; - return game.hasPlayer(function(current){ - return get.attitude(player,current)>4&¤t.countCards('h','tao') - })?1:0; + ai: { + order: 10, + result: { + player: function (player) { + if ( + player.hp != + game.countPlayer(function (current) { + return current.hasSex("male"); + }) + ) + return 0; + return game.hasPlayer(function (current) { + return get.attitude(player, current) > 4 && current.countCards("h", "tao"); + }) + ? 1 + : 0; }, }, }, }, - rexushen2:{ - charlotte:true, - subSkill:{ - count:{ - trigger:{ - player:"recoverBegin", + rexushen2: { + charlotte: true, + subSkill: { + count: { + trigger: { + player: "recoverBegin", }, - forced:true, - silent:true, - popup:false, - filter:function(event,player){ - if(!event.source) return false; - if(!player.isDying()) return false; - var evt=event.getParent('dying').getParent(2); - return evt.name=='rexushen'&&evt.player==player; + forced: true, + silent: true, + popup: false, + filter: function (event, player) { + if (!event.source) return false; + if (!player.isDying()) return false; + var evt = event.getParent("dying").getParent(2); + return evt.name == "rexushen" && evt.player == player; }, - content:function(){ - trigger.rexushen=true; + content: function () { + trigger.rexushen = true; }, - sub:true, + sub: true, }, }, - group:["rexushen2_count"], - trigger:{ - player:"recoverAfter", + group: ["rexushen2_count"], + trigger: { + player: "recoverAfter", }, - filter:function(event,player){ - if(player.isDying()) return false; - return event.rexushen==true; + filter: function (event, player) { + if (player.isDying()) return false; + return event.rexushen == true; }, - direct:true, - silent:true, - popup:false, - content:function(){ - 'step 0' - player.removeSkill('rexushen2'); - player.chooseBool('是否令'+get.translation(trigger.source)+'获得技能〖武圣〗和〖当先〗').ai=function(){ - return get.attitude(player,trigger.source)>0; + direct: true, + silent: true, + popup: false, + content: function () { + "step 0"; + player.removeSkill("rexushen2"); + player.chooseBool( + "是否令" + get.translation(trigger.source) + "获得技能〖武圣〗和〖当先〗" + ).ai = function () { + return get.attitude(player, trigger.source) > 0; }; - 'step 1' - if(result.bool){ - player.line(trigger.source,'fire'); - trigger.source.addSkills(['new_rewusheng','redangxian']); + "step 1"; + if (result.bool) { + player.line(trigger.source, "fire"); + trigger.source.addSkills(["new_rewusheng", "redangxian"]); } }, }, - rezhennan:{ - audio:'xinfu_zhennan', - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.player!=player&&event.targets&&event.targets.length&&event.targets.length>event.player.hp; + rezhennan: { + audio: "xinfu_zhennan", + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return ( + event.player != player && + event.targets && + event.targets.length && + event.targets.length > event.player.hp + ); }, - direct:true, - content:function(){ - 'step 0' - var next=player.chooseToDiscard(get.prompt('rezhennan',trigger.player),'弃置一张牌并对其造成1点伤害','he'); - next.set('logSkill',['rezhennan',trigger.player]); - next.set('ai',function(card){ - var player=_status.event.player; - var target=_status.event.getTrigger().player; - if(get.damageEffect(target,player,player)>0) return 7-get.value(card); + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + get.prompt("rezhennan", trigger.player), + "弃置一张牌并对其造成1点伤害", + "he" + ); + next.set("logSkill", ["rezhennan", trigger.player]); + next.set("ai", function (card) { + var player = _status.event.player; + var target = _status.event.getTrigger().player; + if (get.damageEffect(target, player, player) > 0) return 7 - get.value(card); return -1; }); - 'step 1' - if(result.bool) trigger.player.damage(); + "step 1"; + if (result.bool) trigger.player.damage(); }, }, - meiyong:{ - inherit:'xinfu_wuniang', - audio:'xinfu_wuniang', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('meiyong'),'获得一名其他角色的一张牌,然后其摸一张牌。',function(card,player,target){ - if(player==target) return false; - return target.countGainableCards(player,'he')>0; - }).set('ai',function(target){ - return 10-get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('meiyong',target); - player.gainPlayerCard(target,'he',true); - } - else event.finish(); - 'step 2' + meiyong: { + inherit: "xinfu_wuniang", + audio: "xinfu_wuniang", + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("meiyong"), + "获得一名其他角色的一张牌,然后其摸一张牌。", + function (card, player, target) { + if (player == target) return false; + return target.countGainableCards(player, "he") > 0; + } + ) + .set("ai", function (target) { + return 10 - get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("meiyong", target); + player.gainPlayerCard(target, "he", true); + } else event.finish(); + "step 2"; target.draw(); }, }, - relianji:{ - audio:'wylianji', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.players.length>1; + relianji: { + audio: "wylianji", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.players.length > 1; }, - filterTarget:lib.filter.notMe, - targetprompt:['打人','被打'], - selectTarget:2, - multitarget:true, - content:function(){ - 'step 0' + filterTarget: lib.filter.notMe, + targetprompt: ["打人", "被打"], + selectTarget: 2, + multitarget: true, + content: function () { + "step 0"; game.delay(0.5); - if(!targets[0].hasEquipableSlot(1)) event.goto(2); - 'step 1' - var target=targets[0]; - var equip1=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'&&target.canUse(card,target); + if (!targets[0].hasEquipableSlot(1)) event.goto(2); + "step 1"; + var target = targets[0]; + var equip1 = get.cardPile2(function (card) { + return get.subtype(card) == "equip1" && target.canUse(card, target); }); - if(!equip1){ - player.popup('连计失败'); - game.log('牌堆中无装备'); + if (!equip1) { + player.popup("连计失败"); + game.log("牌堆中无装备"); event.finish(); return; } - if(equip1.name=='qinggang'&&!lib.inpile.includes('qibaodao')){ + if (equip1.name == "qinggang" && !lib.inpile.includes("qibaodao")) { equip1.remove(); - equip1=game.createCard('qibaodao',equip1.suit,equip1.number); + equip1 = game.createCard("qibaodao", equip1.suit, equip1.number); } target.$draw(equip1); - target.chooseUseTarget(equip1,'noanimate','nopopup',true); - 'step 2' + target.chooseUseTarget(equip1, "noanimate", "nopopup", true); + "step 2"; game.updateRoundNumber(); - var list=['nanman','wanjian','huogong','juedou','sha']; - var list2=game.players.slice(0); + var list = ["nanman", "wanjian", "huogong", "juedou", "sha"]; + var list2 = game.players.slice(0); list2.remove(player); - for(var i=0;i2; + forced: true, + filter: function (event, player) { + return player.storage.relianji && player.storage.relianji > 2; }, - audio:'moucheng', - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - player.awakenSkill('remoucheng'); - player.changeSkills(['jingong','relianji']); + audio: "moucheng", + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + player.awakenSkill("remoucheng"); + player.changeSkills(["jingong", "relianji"]); player.gainMaxHp(); player.recover(); }, + ai: { + combo: "relianji" + }, }, - shouye:{ - audio:2, - group:'shouye_after', - trigger:{target:"useCardToTarget"}, - filter:function(event,player){ - return event.player!=player&&event.targets.length==1; + shouye: { + audio: 2, + group: "shouye_after", + trigger: { target: "useCardToTarget" }, + filter: function (event, player) { + return event.player != player && event.targets.length == 1; }, - check:function(event,player){ - if(event.player==game.me||event.player.isOnline()) return get.attitude(player,event.player)<0; - return get.effect(player,event.card,event.player,player)<0; + check: function (event, player) { + if (event.player == game.me || event.player.isOnline()) + return get.attitude(player, event.player) < 0; + return get.effect(player, event.card, event.player, player) < 0; }, - usable:1, - logTarget:'player', - content:function(){ - 'step 0' - player.line(trigger.player,'green'); + usable: 1, + logTarget: "player", + content: function () { + "step 0"; + player.line(trigger.player, "green"); player.chooseToDuiben(trigger.player); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); - trigger.getParent().shouyeer=player; + trigger.getParent().shouyeer = player; } }, - subSkill:{ - after:{ - sub:true, - trigger:{global:'useCardAfter'}, - forced:true, - silent:true, - popup:false, - filter:function(event,player){ - if(event.shouyeer!=player) return false; - if(event.cards){ - for(var i=0;i0; - }).ai=function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe'},player,player); + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("liezhi"), + "弃置至多两名其他角色区域内的各一张牌", + [1, 2], + function (card, player, target) { + return target != player && target.countDiscardableCards(player, "hej") > 0; + } + ).ai = function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe" }, player, player); }; - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { result.targets.sortBySeat(); - event.targets=result.targets; - player.line(result.targets,'green'); - player.logSkill('liezhi',result.targets); - } - else event.finish(); - 'step 2' - event.current=targets.shift(); - player.discardPlayerCard(event.current,'hej',true) - if(targets.length) event.redo(); + event.targets = result.targets; + player.line(result.targets, "green"); + player.logSkill("liezhi", result.targets); + } else event.finish(); + "step 2"; + event.current = targets.shift(); + player.discardPlayerCard(event.current, "hej", true); + if (targets.length) event.redo(); }, - subSkill:{ - disable:{ - sub:true, - trigger:{player:'phaseAfter'}, - forced:true, - silent:true, - popup:false, - charlotte:true, + subSkill: { + disable: { + sub: true, + trigger: { player: "phaseAfter" }, + forced: true, + silent: true, + popup: false, + charlotte: true, //filter:function(event){return !event.liezhi}, - content:function(){player.removeSkill('liezhi_disable')}, + content: function () { + player.removeSkill("liezhi_disable"); + }, }, - damage:{ - trigger:{player:'damage'}, - forced:true, - silent:true, - popup:false, - content:function(){player.addSkill('liezhi_disable')} + damage: { + trigger: { player: "damage" }, + forced: true, + silent: true, + popup: false, + content: function () { + player.addSkill("liezhi_disable"); + }, }, }, }, - xinzhanyi:{ - audio:'zhanyi', - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - check:function(card){ - var player=_status.event.player; - if(player.hp<3) return 0; - var type=get.type(card,'trick'); - if(type=='trick'){ - return 6-get.value(card); - } - else if(type=='equip'){ - if(player.hasSha()&&game.hasPlayer(function(current){ - return (player.canUse('sha',current)&& - get.attitude(player,current)<0&& - get.effect(current,{name:'sha'},player,player)>0) - })){ - return 6-get.value(card); + xinzhanyi: { + audio: "zhanyi", + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + check: function (card) { + var player = _status.event.player; + if (player.hp < 3) return 0; + var type = get.type(card, "trick"); + if (type == "trick") { + return 6 - get.value(card); + } else if (type == "equip") { + if ( + player.hasSha() && + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + get.attitude(player, current) < 0 && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { + return 6 - get.value(card); } } return 0; }, - content:function(){ + content: function () { player.loseHp(); - switch(get.type(cards[0],'trick',cards[0].original=='h'?player:false)){ - case 'basic':player.addTempSkill('xinzhanyi_basic');player.addMark('xinzhanyi_basic1',1,false);break; - case 'equip':player.addTempSkill('xinzhanyi_equip');break; - case 'trick':player.addTempSkill('xinzhanyi_trick');player.draw(3);break; + switch (get.type(cards[0], "trick", cards[0].original == "h" ? player : false)) { + case "basic": + player.addTempSkill("xinzhanyi_basic"); + player.addMark("xinzhanyi_basic1", 1, false); + break; + case "equip": + player.addTempSkill("xinzhanyi_equip"); + break; + case "trick": + player.addTempSkill("xinzhanyi_trick"); + player.draw(3); + break; } }, - ai:{ - order:9.1, - result:{ - player:1 - } - } - }, - xinzhanyi_basic1:{ - trigger:{player:"useCard"}, - filter:function(event,player){ - return get.type(event.card,false)=='basic'&&player.hasMark('xinzhanyi_basic1'); - }, - forced:true, - silent:true, - popup:false, - content:function(){ - if(!trigger.baseDamage) trigger.baseDamage=1; - var num=player.countMark('xinzhanyi_basic1'); - trigger.baseDamage+=num; - player.removeMark('xinzhanyi_basic1',num,false); - game.log(trigger.card,'的伤害值/回复值','#y+'+num); + ai: { + order: 9.1, + result: { + player: 1, + }, }, }, - xinzhanyi_basic:{ - group:['xinzhanyi_basic1'], - onremove:function(p,s){ - delete p.storage[s+1]; + xinzhanyi_basic1: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return get.type(event.card, false) == "basic" && player.hasMark("xinzhanyi_basic1"); }, - hiddenCard:function(player,name){ - return get.type(name)=='basic'&&player.countCards('h',{type:'basic'})>0; + forced: true, + silent: true, + popup: false, + content: function () { + if (!trigger.baseDamage) trigger.baseDamage = 1; + var num = player.countMark("xinzhanyi_basic1"); + trigger.baseDamage += num; + player.removeMark("xinzhanyi_basic1", num, false); + game.log(trigger.card, "的伤害值/回复值", "#y+" + num); }, - enable:"chooseToUse", - filter:function(event,player){ - if(!player.hasCard(function(card){ - return get.type(card)=='basic'; - },'hs')) return false; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) return true; + }, + xinzhanyi_basic: { + group: ["xinzhanyi_basic1"], + onremove: function (p, s) { + delete p.storage[s + 1]; + }, + hiddenCard: function (player, name) { + return get.type(name) == "basic" && player.countCards("h", { type: "basic" }) > 0; + }, + enable: "chooseToUse", + filter: function (event, player) { + if ( + !player.hasCard(function (card) { + return get.type(card) == "basic"; + }, "hs") + ) + return false; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) list.push(['基本','',name]); - if(name!='sha') continue; - for(var j of lib.inpile_nature){ - if(event.filterCard({name:name,nature:j},player,event)) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) + list.push(["基本", "", name]); + if (name != "sha") continue; + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: name, nature: j }, player, event)) + list.push(["基本", "", "sha", j]); } } - return ui.create.dialog('战意',[list,'vcard'],'hidden'); + return ui.create.dialog("战意", [list, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch(button.link[2]){ - case 'tao':return 5; - case 'jiu':{ - if(player.countCards('hs',{type:'basic'})>=2) return 3; - }; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder'||button.link[3]=='ice') return 2.92; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + return 5; + case "jiu": { + if (player.countCards("hs", { type: "basic" }) >= 2) return 3; + } + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder" || button.link[3] == "ice") + return 2.92; else return 2.9; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'zhanyi', - filterCard:function(card,player,target){ - return get.type(card)=='basic'; + audio: "zhanyi", + filterCard: function (card, player, target) { + return get.type(card) == "basic"; }, - check:function(card,player,target){ - return 9-get.value(card); + check: function (card, player, target) { + return 9 - get.value(card); }, - viewAs:{name:links[0][2],nature:links[0][3]}, - position:'hs', - popname:true, - } + viewAs: { name: links[0][2], nature: links[0][3] }, + position: "hs", + popname: true, + }; }, - prompt:function(links,player){ - return '将一张基本牌当做'+get.translation(links[0][3]||'')+get.translation(links[0][2])+'使用'; + prompt: function (links, player) { + return ( + "将一张基本牌当做" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - order:function(){ - var player=_status.event.player; - var event=_status.event; - if(event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0&&player.countCards('hs',{type:'basic'})>=2){ + ai: { + order: function () { + var player = _status.event.player; + var event = _status.event; + if ( + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 && + player.countCards("hs", { type: "basic" }) >= 2 + ) { return 3.3; } return 3.1; }, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(player.hasCard(function(card){ - return get.type(card)=='basic'; - },'hs')){ - if(tag=='respondSha'){ - if(arg!='use') return false; + respondSha: true, + skillTagFilter: function (player, tag, arg) { + if ( + player.hasCard(function (card) { + return get.type(card) == "basic"; + }, "hs") + ) { + if (tag == "respondSha") { + if (arg != "use") return false; } - } - else{ + } else { return false; } }, - result:{ - player:1, + result: { + player: 1, }, }, }, - xinzhanyi_equip:{ - audio:'zhanyi', - trigger:{player:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('he')>0&&event.targets.length==1; + xinzhanyi_equip: { + audio: "zhanyi", + trigger: { player: "useCardToPlayered" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.target.countCards("he") > 0 && + event.targets.length == 1 + ); }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + content: function () { + "step 0"; + trigger.target.chooseToDiscard("he", true, 2); + "step 1"; + if (result.bool && result.cards && result.cards.length) { + if (result.cards.length == 1) { + event._result = { bool: true, links: result.cards.slice(0) }; + } else + player.chooseButton(["选择获得其中的一张牌", result.cards.slice(0)], true).ai = + function (button) { + return get.value(button.link); + }; + } else event.finish(); + "step 2"; + if (result.links) player.gain(result.links, "gain2"); }, - content:function(){ - 'step 0' - trigger.target.chooseToDiscard('he',true,2); - 'step 1' - if(result.bool&&result.cards&&result.cards.length){ - if(result.cards.length==1){ - event._result={bool:true,links:result.cards.slice(0)}; - } - else player.chooseButton(['选择获得其中的一张牌',result.cards.slice(0)],true).ai=function(button){ - return get.value(button.link); - }; - } - else event.finish(); - 'step 2' - if(result.links) player.gain(result.links,'gain2'); - } }, - xinzhanyi_trick:{ - mod:{ - wuxieRespondable:function(){ + xinzhanyi_trick: { + mod: { + wuxieRespondable: function () { return false; - } - } + }, + }, }, - "xinfu_daigong":{ - usable:1, - audio:2, - trigger:{ - player:"damageBegin4", + xinfu_daigong: { + usable: 1, + audio: 2, + trigger: { + player: "damageBegin4", }, - filter:function(event,player){ - return event.source!=undefined&&player.countCards('h')>0; + filter: function (event, player) { + return event.source != undefined && player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - var cards=player.getCards('h'); - var suits=[]; - for(var i=0;i0) return 6.5-get.value(card); + trigger.source + .chooseCard( + "he", + "交给" + get.translation(player) + "一张满足条件的牌,否则防止此伤害。", + function (card) { + return !_status.event.suits.includes(get.suit(card)); + } + ) + .set("suits", suits).ai = function (card) { + var player = _status.event.player; + var target = _status.event.getParent("xinfu_daigong").player; + if (get.damageEffect(target, player, player) > 0) return 6.5 - get.value(card); return 0; }; - 'step 2' - if(result.bool){ - trigger.source.give(result.cards,player,true); - } - else trigger.cancel(); + "step 2"; + if (result.bool) { + trigger.source.give(result.cards, player, true); + } else trigger.cancel(); }, }, - xinfu_zhaoxin:{ - group:["zhaoxin_give"], - intro:{ - content:'expansion', - markcount:'expansion', + xinfu_zhaoxin: { + group: ["zhaoxin_give"], + intro: { + content: "expansion", + markcount: "expansion", }, - enable:"phaseUse", - usable:1, - audio:2, - filter:function(event,player){ - return player.countCards('h')>0&&player.getExpansions('xinfu_zhaoxin').length<3; + enable: "phaseUse", + usable: 1, + audio: 2, + filter: function (event, player) { + return player.countCards("h") > 0 && player.getExpansions("xinfu_zhaoxin").length < 3; }, - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - return [1,3-player.getExpansions('xinfu_zhaoxin').length]; + filterCard: true, + selectCard: function () { + var player = _status.event.player; + return [1, 3 - player.getExpansions("xinfu_zhaoxin").length]; }, - discard:false, - lose:false, - delay:false, - content:function(){ - player.addToExpansion(player,'give',cards).gaintag.add('xinfu_zhaoxin'); + discard: false, + lose: false, + delay: false, + content: function () { + player.addToExpansion(player, "give", cards).gaintag.add("xinfu_zhaoxin"); player.draw(cards.length); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - order:1, - result:{ - player:1, + ai: { + order: 1, + result: { + player: 1, }, }, }, - zhaoxin_give:{ - trigger:{ - global:"phaseDrawAfter", + zhaoxin_give: { + trigger: { + global: "phaseDrawAfter", }, - filter:function(event,player){ - if(!player.getExpansions('xinfu_zhaoxin').length) return false; - return player==event.player||player.inRange(event.player); + filter: function (event, player) { + if (!player.getExpansions("xinfu_zhaoxin").length) return false; + return player == event.player || player.inRange(event.player); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCardButton(get.prompt('xinfu_zhaoxin',trigger.player),player.getExpansions('xinfu_zhaoxin'),function(button){ - return true; - }).set('ai',function(button){ - return 1+Math.random(); - }); - 'step 1' - if(result.bool){ - event.card=result.links[0]; - player.logSkill('xinfu_zhaoxin',target); - player.line(trigger.player,'thunder'); + direct: true, + content: function () { + "step 0"; + player + .chooseCardButton( + get.prompt("xinfu_zhaoxin", trigger.player), + player.getExpansions("xinfu_zhaoxin"), + function (button) { + return true; + } + ) + .set("ai", function (button) { + return 1 + Math.random(); + }); + "step 1"; + if (result.bool) { + event.card = result.links[0]; + player.logSkill("xinfu_zhaoxin", target); + player.line(trigger.player, "thunder"); player.showCards(event.card); - } - else event.finish(); - 'step 2' - trigger.player.chooseBool('是否获得'+get.translation(event.card)+'?').ai=function(){ - return get.attitude(trigger.player,player)>0; - }; - 'step 3' - if(result.bool){ - trigger.player.gain(event.card,'give',player,'bySelf'); - player.chooseBool('是否对'+get.translation(trigger.player)+'造成1点伤害?').ai=function(){ - return get.damageEffect(trigger.player,player,player)>0 + } else event.finish(); + "step 2"; + trigger.player.chooseBool("是否获得" + get.translation(event.card) + "?").ai = + function () { + return get.attitude(trigger.player, player) > 0; }; - } - else{ - trigger.player.chat('拒绝'); + "step 3"; + if (result.bool) { + trigger.player.gain(event.card, "give", player, "bySelf"); + player.chooseBool("是否对" + get.translation(trigger.player) + "造成1点伤害?").ai = + function () { + return get.damageEffect(trigger.player, player, player) > 0; + }; + } else { + trigger.player.chat("拒绝"); event.finish(); } - 'step 4' - if(result.bool){ - trigger.player.damage('nocard'); + "step 4"; + if (result.bool) { + trigger.player.damage("nocard"); } }, }, - "xinfu_qianchong":{ - audio:3, - group:["qc_weimu","qc_mingzhe"], - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable:function(card,player){ - var type=get.type2(card); - if(player.getStorage('xinfu_qianchong_effect').includes(type)) return Infinity; + xinfu_qianchong: { + audio: 3, + group: ["qc_weimu", "qc_mingzhe"], + subSkill: { + effect: { + charlotte: true, + onremove: true, + mod: { + cardUsable: function (card, player) { + var type = get.type2(card); + if (player.getStorage("xinfu_qianchong_effect").includes(type)) + return Infinity; }, - targetInRange:function(card,player){ - var type=get.type2(card); - if(player.getStorage('xinfu_qianchong_effect').includes(type)) return true; + targetInRange: function (card, player) { + var type = get.type2(card); + if (player.getStorage("xinfu_qianchong_effect").includes(type)) return true; }, }, }, }, - trigger:{ - player:"phaseUseBegin", + trigger: { + player: "phaseUseBegin", }, - direct:true, - filter:function(event,player){ - var es=player.getCards('e'); - if(!es.length) return true; - var col=get.color(es[0]); - for(var i=0;i1){ - player.chooseControl(list).set('ai',function(){ - return list[0]; - }).set('prompt',get.prompt('xinfu_qianchong')).set('prompt2','你可以选择一种类别的牌,然后你本回合内使用该类别的牌时没有次数和距离限制。'); - } - else event.finish(); - 'step 1' - if(result.control&&result.control!='cancel2'){ - player.logSkill('xinfu_qianchong'); - var type=result.control; - player.addTempSkill('xinfu_qianchong_effect'); - player.markAuto('xinfu_qianchong_effect',[type]); - var str=get.translation(type)+'牌'; - game.log(player,'声明了','#y'+str); - player.popup(str,'thunder'); + content: function () { + "step 0"; + var list = ["basic", "trick", "equip", "cancel2"]; + list.removeArray(player.getStorage("xinfu_qianchong_effect")); + if (list.length > 1) { + player + .chooseControl(list) + .set("ai", function () { + return list[0]; + }) + .set("prompt", get.prompt("xinfu_qianchong")) + .set( + "prompt2", + "你可以选择一种类别的牌,然后你本回合内使用该类别的牌时没有次数和距离限制。" + ); + } else event.finish(); + "step 1"; + if (result.control && result.control != "cancel2") { + player.logSkill("xinfu_qianchong"); + var type = result.control; + player.addTempSkill("xinfu_qianchong_effect"); + player.markAuto("xinfu_qianchong_effect", [type]); + var str = get.translation(type) + "牌"; + game.log(player, "声明了", "#y" + str); + player.popup(str, "thunder"); } }, }, - "qc_weimu":{ - audio:"xinfu_qianchong", - mod:{ - targetEnabled:function(card,player,target){ - var bool=true; - var es=target.getCards('e'); - if(!es.length) bool=false; - for(var i=0;i0&&num<=player.hp + return num > 0 && num <= player.hp; }, - forced:true, - content:function(){ - 'step 0' - var num=0; - player.getHistory('lose',function(evt){ - var evt2=evt.getParent(); - if(evt2.name=='useCard'&&evt2.player==player&&get.type(evt2.card,null,false)=='equip') return; - if(evt.cards2) num+=evt.cards2.length; + forced: true, + content: function () { + "step 0"; + var num = 0; + player.getHistory("lose", function (evt) { + var evt2 = evt.getParent(); + if ( + evt2.name == "useCard" && + evt2.player == player && + get.type(evt2.card, null, false) == "equip" + ) + return; + if (evt.cards2) num += evt.cards2.length; }); - if(num>0){ + if (num > 0) { player.draw(num); } }, }, - "rw_bagua_skill":{ - inherit:"bagua_skill", - audio:true, - content:function(){ - "step 0" - player.judge('rewrite_bagua',function(card){return (get.suit(card)!='spade')?1.5:-0.5}).judge2=function(result){ + rw_bagua_skill: { + inherit: "bagua_skill", + audio: true, + content: function () { + "step 0"; + player.judge("rewrite_bagua", function (card) { + return get.suit(card) != "spade" ? 1.5 : -0.5; + }).judge2 = function (result) { return result.bool; }; - "step 1" - if(result.judge>0){ + "step 1"; + if (result.judge > 0) { trigger.untrigger(); - trigger.set('responded',true); - trigger.result={bool:true,card:{name:'shan'}} + trigger.set("responded", true); + trigger.result = { bool: true, card: { name: "shan" } }; } }, }, - "rw_baiyin_skill":{ - inherit:"baiyin_skill", - audio:true, - subSkill:{ - lose:{ - audio:'rw_baiyin_skill', - forced:true, - charlotte:true, - equipSkill:true, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + rw_baiyin_skill: { + inherit: "baiyin_skill", + audio: true, + subSkill: { + lose: { + audio: "rw_baiyin_skill", + forced: true, + charlotte: true, + equipSkill: true, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:(event,player)=>{ - if(player.hasSkillTag('unequip2')) return false; - var evt=event.getl(player); - return evt&&evt.es.some(card=>card.name=='rewrite_baiyin') + filter: (event, player) => { + if (player.hasSkillTag("unequip2")) return false; + var evt = event.getl(player); + return evt && evt.es.some((card) => card.name == "rewrite_baiyin"); }, - content:function(){ - var evt=trigger.getl(player); - evt.es.forEach(card=>{ - if(card.name=='rewrite_baiyin'){ + content: function () { + var evt = trigger.getl(player); + evt.es.forEach((card) => { + if (card.name == "rewrite_baiyin") { player.recover(); player.draw(2); } - }) + }); }, }, }, }, - "rw_lanyinjia":{ - inherit:"lanyinjia", - audio:"lanyinjia", + rw_lanyinjia: { + inherit: "lanyinjia", + audio: "lanyinjia", }, - "rw_minguangkai_cancel":{ - inherit:"minguangkai_cancel", + rw_minguangkai_cancel: { + inherit: "minguangkai_cancel", }, - "rw_minguangkai_link":{ - inherit:"minguangkai_link", - trigger:{ - player:"linkBefore", + rw_minguangkai_link: { + inherit: "minguangkai_link", + trigger: { + player: "linkBefore", }, - forced:true, + forced: true, //priority:20, - filter:function(event,player){ + filter: function (event, player) { return !player.isLinked(); }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(['tiesuo','lulitongxin'].includes(card.name)){ - return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (["tiesuo", "lulitongxin"].includes(card.name)) { + return "zerotarget"; } }, }, }, }, - "rw_renwang_skill":{ - inherit:"renwang_skill", - audio:true, - filter:function(event,player){ - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return (event.card.name=='sha'&&(get.suit(event.card)=='heart'||get.color(event.card)=='black')) + rw_renwang_skill: { + inherit: "renwang_skill", + audio: true, + filter: function (event, player) { + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; + return ( + event.card.name == "sha" && + (get.suit(event.card) == "heart" || get.color(event.card) == "black") + ); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(typeof card!=='object'||target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:player, - card:card - })) return; - if(card.name=='sha'&&['spade','club','heart'].includes(get.suit(card))) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target) { + if (typeof card !== "object" || target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return; + if (card.name == "sha" && ["spade", "club", "heart"].includes(get.suit(card))) + return "zeroplayertarget"; }, }, }, }, - "rw_tengjia1":{ - inherit:"tengjia1", - audio:true, + rw_tengjia1: { + inherit: "tengjia1", + audio: true, }, - "rw_tengjia2":{ - inherit:"tengjia2", - audio:true, + rw_tengjia2: { + inherit: "tengjia2", + audio: true, }, - "rw_tengjia3":{ - audio:"rw_tengjia1", - inherit:"rw_minguangkai_link", - ai:{ - effect:{ - target:function(card,player,target,current){ - if(['tiesuo','lulitongxin'].includes(card.name)){ - return 'zeroplayertarget'; + rw_tengjia3: { + audio: "rw_tengjia1", + inherit: "rw_minguangkai_link", + ai: { + effect: { + target: function (card, player, target, current) { + if (["tiesuo", "lulitongxin"].includes(card.name)) { + return "zeroplayertarget"; } }, }, }, }, - rw_tengjia4:{ - inherit:"tengjia3", - audio:"rw_tengjia1", + rw_tengjia4: { + inherit: "tengjia3", + audio: "rw_tengjia1", }, - xinfu_pingcai:{ - subSkill:{backup:{}}, - wolong_card:function(){ - 'step 0' - var ingame=game.hasPlayer(function(current){ - return ['sp_zhugeliang','re_sp_zhugeliang','ol_sp_zhugeliang','prp_zhugeliang'].includes(current.name)||['sp_zhugeliang','re_sp_zhugeliang','ol_sp_zhugeliang','prp_zhugeliang'].includes(current.name2); - })?true:false; - var prompt='请选择'; - prompt+=ingame?'至多两名':'一名'; - prompt+='角色,对其造成1点火焰伤害'; - var range=ingame?[1,2]:[1,1] - player.chooseTarget(prompt,range).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player,'fire'); + xinfu_pingcai: { + subSkill: { backup: {} }, + wolong_card: function () { + "step 0"; + var ingame = game.hasPlayer(function (current) { + return ( + [ + "sp_zhugeliang", + "re_sp_zhugeliang", + "ol_sp_zhugeliang", + "prp_zhugeliang", + ].includes(current.name) || + [ + "sp_zhugeliang", + "re_sp_zhugeliang", + "ol_sp_zhugeliang", + "prp_zhugeliang", + ].includes(current.name2) + ); + }) + ? true + : false; + var prompt = "请选择"; + prompt += ingame ? "至多两名" : "一名"; + prompt += "角色,对其造成1点火焰伤害"; + var range = ingame ? [1, 2] : [1, 1]; + player.chooseTarget(prompt, range).set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player, "fire"); }); - 'step 1' - if(result.bool&&result.targets.length){ - player.line(result.targets,'fire'); + "step 1"; + if (result.bool && result.targets.length) { + player.line(result.targets, "fire"); result.targets.sortBySeat(); - for(var i=0;itarget.canEquip(card)) + shuijing_card: function () { + "step 0"; + event.ingame = game.hasPlayer(function (current) { + return current.name == "simahui" || current.name2 == "simahui"; + }) + ? true + : false; + var prompt = "将一名角色装备区中的"; + prompt += event.ingame ? "一张牌" : "防具牌"; + prompt += "移动到另一名角色的装备区中"; + var next = player.chooseTarget(2, function (card, player, target) { + if (ui.selected.targets.length) { + if (!_status.event.ingame) { + var cards = ui.selected.targets[0].getEquips(2); + return cards.some((card) => target.canEquip(card)); } - var from=ui.selected.targets[0]; - if(target.isMin()) return false; - var es=from.getCards('e'); - for(var i=0;i0; + return target.countCards("e") > 0; } }); - next.set('ingame',event.ingame) - next.set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(ui.selected.targets.length==0){ - if(att<0){ - if(game.hasPlayer(function(current){ - if(get.attitude(player,current)>0){ - var es=target.getCards('e'); - for(var i=0;i 0) { + var es = target.getCards("e"); + for (var i = 0; i < es.length; i++) { + if (current.canEquip(es[i])) return true; + } + return false; } - return false; - } - })) return -att; + }) + ) + return -att; } return 0; } - if(att>0){ - var es=ui.selected.targets[0].getCards('e'); + if (att > 0) { + var es = ui.selected.targets[0].getCards("e"); var i; - for(i=0;i1; - })) return 1+Math.random(); + check: function (button) { + var name = button.link[2]; + var player = _status.event.player; + if (name == "xuanjian_card") { + if ( + game.hasPlayer(function (current) { + return ( + current.isDamaged() && + current.hp < 3 && + get.attitude(player, current) > 1 + ); + }) + ) + return 1 + Math.random(); else return 1; - } - else if(name=='wolong_card'){ - if(game.hasPlayer(function(current){ - return get.damageEffect(current,player,player,'fire')>0; - })) return 1.2+Math.random(); + } else if (name == "wolong_card") { + if ( + game.hasPlayer(function (current) { + return get.damageEffect(current, player, player, "fire") > 0; + }) + ) + return 1.2 + Math.random(); else return 0.5; - } - else return 0.6; + } else return 0.6; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'xinfu_pingcai', - filterCard:()=>false, - selectCard:-1, - takara:links[0][2], - content:lib.skill.xinfu_pingcai.contentx, - } + audio: "xinfu_pingcai", + filterCard: () => false, + selectCard: -1, + takara: links[0][2], + content: lib.skill.xinfu_pingcai.contentx, + }; }, }, - contentx:function(){ - "step 0" - event.pingcai_delayed=true; - var name=lib.skill.xinfu_pingcai_backup.takara; - event.cardname=name; - event.videoId=lib.status.videoId++; - if(player.isUnderControl()){ + contentx: function () { + "step 0"; + event.pingcai_delayed = true; + var name = lib.skill.xinfu_pingcai_backup.takara; + event.cardname = name; + event.videoId = lib.status.videoId++; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ + var switchToAuto = function () { game.pause(); game.countChoose(); - event.timeout=setTimeout(function(){ - _status.imchoosing=false; - event._result={ - bool:true, + event.timeout = setTimeout(function () { + _status.imchoosing = false; + event._result = { + bool: true, }; game.resume(); - },9000); + }, 9000); }; - var createDialog=function(player,id,name){ - if(player==game.me) return; - var dialog=ui.create.dialog('forcebutton','hidden'); - var str=get.translation(player)+'正在擦拭宝物上的灰尘…'; - var canSkip=(!_status.connectMode); - if(canSkip) str+='
              (点击宝物可以跳过等待AI操作)'; - dialog.textPrompt=dialog.add('
              '+str+'
              '); - dialog.classList.add('fixed'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.classList.add('noupdate'); - dialog.videoId=id; + var createDialog = function (player, id, name) { + if (player == game.me) return; + var dialog = ui.create.dialog("forcebutton", "hidden"); + var str = get.translation(player) + "正在擦拭宝物上的灰尘…"; + var canSkip = !_status.connectMode; + if (canSkip) str += "
              (点击宝物可以跳过等待AI操作)"; + dialog.textPrompt = dialog.add('
              ' + str + "
              "); + dialog.classList.add("fixed"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.classList.add("noupdate"); + dialog.videoId = id; - var canvas2=document.createElement('canvas'); - dialog.canvas_viewer=canvas2; + var canvas2 = document.createElement("canvas"); + dialog.canvas_viewer = canvas2; dialog.appendChild(canvas2); - canvas2.classList.add('grayscale'); - canvas2.style.position="absolute"; - canvas2.style.width='249px'; - canvas2.style.height='249px'; - canvas2.style['border-radius']='6px'; - canvas2.style.left="calc(50% - 125px)"; - canvas2.style.top="calc(50% - 125px)"; - canvas2.width=249; - canvas2.height=249; - canvas2.style.border='3px solid'; + canvas2.classList.add("grayscale"); + canvas2.style.position = "absolute"; + canvas2.style.width = "249px"; + canvas2.style.height = "249px"; + canvas2.style["border-radius"] = "6px"; + canvas2.style.left = "calc(50% - 125px)"; + canvas2.style.top = "calc(50% - 125px)"; + canvas2.width = 249; + canvas2.height = 249; + canvas2.style.border = "3px solid"; - var ctx2=canvas2.getContext('2d'); - var img=new Image(); - img.src=lib.assetURL+'image/card/'+name+'.png'; - img.onload=function(){ - ctx2.drawImage(this,0,0,this.width,this.height,0,0,canvas2.width,canvas2.height); - } - if(canSkip){ - var skip=function(){ - if(event.pingcai_delayed){ + var ctx2 = canvas2.getContext("2d"); + var img = new Image(); + img.src = lib.assetURL + "image/card/" + name + ".png"; + img.onload = function () { + ctx2.drawImage( + this, + 0, + 0, + this.width, + this.height, + 0, + 0, + canvas2.width, + canvas2.height + ); + }; + if (canSkip) { + var skip = function () { + if (event.pingcai_delayed) { delete event.pingcai_delayed; clearTimeout(event.timeout); - event._result={ - bool:true, + event._result = { + bool: true, }; game.resume(); - canvas2.removeEventListener(lib.config.touchscreen?'touchend':'click',skip); + canvas2.removeEventListener( + lib.config.touchscreen ? "touchend" : "click", + skip + ); } }; - canvas2.addEventListener(lib.config.touchscreen?'touchend':'click',skip); + canvas2.addEventListener(lib.config.touchscreen ? "touchend" : "click", skip); } dialog.open(); }; - var chooseButton=function(id,name){ - var event=_status.event; - _status.xinfu_pingcai_finished=false; + var chooseButton = function (id, name) { + var event = _status.event; + _status.xinfu_pingcai_finished = false; - var dialog=ui.create.dialog('forcebutton','hidden'); - dialog.textPrompt=dialog.add('
              擦拭掉宝物上的灰尘吧!
              '); - event.switchToAuto=function(){ - event._result={ - bool:_status.xinfu_pingcai_finished, + var dialog = ui.create.dialog("forcebutton", "hidden"); + dialog.textPrompt = dialog.add( + '
              擦拭掉宝物上的灰尘吧!
              ' + ); + event.switchToAuto = function () { + event._result = { + bool: _status.xinfu_pingcai_finished, }; game.resume(); - _status.imchoosing=false; - _status.xinfu_pingcai_finished=true; + _status.imchoosing = false; + _status.xinfu_pingcai_finished = true; }; - dialog.classList.add('fixed'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.classList.add('noupdate'); - dialog.videoId=id; + dialog.classList.add("fixed"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.classList.add("noupdate"); + dialog.videoId = id; - var canvas=document.createElement('canvas'); - var canvas2=document.createElement('canvas'); + var canvas = document.createElement("canvas"); + var canvas2 = document.createElement("canvas"); dialog.appendChild(canvas2); dialog.appendChild(canvas); - canvas.style.position="absolute"; - canvas.style.width='249px'; - canvas.style.height='249px'; - canvas.style['border-radius']='6px'; - canvas.style.left="calc(50% - 125px)"; - canvas.style.top="calc(50% - 125px)"; - canvas.width=249; - canvas.height=249; - canvas.style.border='3px solid'; + canvas.style.position = "absolute"; + canvas.style.width = "249px"; + canvas.style.height = "249px"; + canvas.style["border-radius"] = "6px"; + canvas.style.left = "calc(50% - 125px)"; + canvas.style.top = "calc(50% - 125px)"; + canvas.width = 249; + canvas.height = 249; + canvas.style.border = "3px solid"; - canvas2.style.position="absolute"; - canvas2.style.width='249px'; - canvas2.style.height='249px'; - canvas2.style['border-radius']='6px'; - canvas2.style.left="calc(50% - 125px)"; - canvas2.style.top="calc(50% - 125px)"; - canvas2.width=249; - canvas2.height=249; - canvas2.style.border='3px solid'; + canvas2.style.position = "absolute"; + canvas2.style.width = "249px"; + canvas2.style.height = "249px"; + canvas2.style["border-radius"] = "6px"; + canvas2.style.left = "calc(50% - 125px)"; + canvas2.style.top = "calc(50% - 125px)"; + canvas2.width = 249; + canvas2.height = 249; + canvas2.style.border = "3px solid"; - var ctx=canvas.getContext('2d'); - var ctx2=canvas2.getContext('2d'); + var ctx = canvas.getContext("2d"); + var ctx2 = canvas2.getContext("2d"); - var img=new Image(); - img.src=lib.assetURL+'image/card/'+name+'.png'; - img.onload=function(){ - ctx2.drawImage(this,0,0,this.width,this.height,0,0,canvas2.width,canvas2.height); - } + var img = new Image(); + img.src = lib.assetURL + "image/card/" + name + ".png"; + img.onload = function () { + ctx2.drawImage( + this, + 0, + 0, + this.width, + this.height, + 0, + 0, + canvas2.width, + canvas2.height + ); + }; - ctx.fillStyle='lightgray'; - ctx.fillRect(0,0,canvas.width,canvas.height); + ctx.fillStyle = "lightgray"; + ctx.fillRect(0, 0, canvas.width, canvas.height); - canvas.onmousedown=function(ev){ + canvas.onmousedown = function (ev) { //if(_status.xinfu_pingcai_finished) return; - canvas.onmousemove=function(e){ - if(_status.xinfu_pingcai_finished) return; + canvas.onmousemove = function (e) { + if (_status.xinfu_pingcai_finished) return; ctx.beginPath(); - ctx.clearRect(e.offsetX-16,e.offsetY-16,32,32); - var data=ctx.getImageData(canvas.width*0.1,canvas.height*0.1,canvas.width*0.8,canvas.height*0.8).data; - var sum=0; - for(var i=3;i=(canvas.width*canvas.height)*0.6){ + if (sum >= canvas.width * canvas.height * 0.6) { //ctx.clearRect(0,0,canvas.width,canvas.height); - if(!_status.xinfu_pingcai_finished){ - _status.xinfu_pingcai_finished=true; + if (!_status.xinfu_pingcai_finished) { + _status.xinfu_pingcai_finished = true; event.switchToAuto(); } } - } - } - canvas.ontouchstart=function(ev){ + }; + }; + canvas.ontouchstart = function (ev) { //if(_status.xinfu_pingcai_finished) return; - canvas.ontouchmove=function(e){ - if(_status.xinfu_pingcai_finished) return; + canvas.ontouchmove = function (e) { + if (_status.xinfu_pingcai_finished) return; ctx.beginPath(); - var rect=canvas.getBoundingClientRect(); - var X=((e.touches[0].clientX-rect.left)/rect.width*canvas.width); - var Y=((e.touches[0].clientY-rect.top)/rect.height*canvas.height); - ctx.clearRect(X-16,Y-16,32,32); - var data=ctx.getImageData(canvas.width*0.1,canvas.height*0.1,canvas.width*0.8,canvas.height*0.8).data; - var sum=0; - for(var i=3;i=(canvas.width*canvas.height)*0.6){ - if(!_status.xinfu_pingcai_finished){ - _status.xinfu_pingcai_finished=true; + if (sum >= canvas.width * canvas.height * 0.6) { + if (!_status.xinfu_pingcai_finished) { + _status.xinfu_pingcai_finished = true; event.switchToAuto(); } } - } - } - canvas.onmouseup=function(ev){ - canvas.onmousemove=null; - } - canvas.ontouchend=function(ev){ - canvas.ontouchmove=null; - } + }; + }; + canvas.onmouseup = function (ev) { + canvas.onmousemove = null; + }; + canvas.ontouchend = function (ev) { + canvas.ontouchmove = null; + }; dialog.open(); @@ -15166,582 +18327,663 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.countChoose(); }; //event.switchToAuto=switchToAuto; - game.broadcastAll(createDialog,player,event.videoId,name); - if(event.isMine()){ - chooseButton(event.videoId,name); - } - else if(event.isOnline()){ - event.player.send(chooseButton,event.videoId,name); + game.broadcastAll(createDialog, player, event.videoId, name); + if (event.isMine()) { + chooseButton(event.videoId, name); + } else if (event.isOnline()) { + event.player.send(chooseButton, event.videoId, name); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - "step 1" - var result=event.result||result; - if(!result) result={bool:false}; - event._result=result; - game.broadcastAll(function(id,result,player){ - _status.xinfu_pingcai_finished=true; - var dialog=get.idDialog(id); - if(dialog){ - dialog.textPrompt.innerHTML='
              '+(get.translation(player)+'擦拭宝物'+(result.bool?'成功!':'失败…'))+'
              '; - if(result.bool&&dialog.canvas_viewer) dialog.canvas_viewer.classList.remove('grayscale'); - } - if(!_status.connectMode) delete event.pingcai_delayed; - },event.videoId,result,player); + "step 1"; + var result = event.result || result; + if (!result) result = { bool: false }; + event._result = result; + game.broadcastAll( + function (id, result, player) { + _status.xinfu_pingcai_finished = true; + var dialog = get.idDialog(id); + if (dialog) { + dialog.textPrompt.innerHTML = + '
              ' + + (get.translation(player) + + "擦拭宝物" + + (result.bool ? "成功!" : "失败…")) + + "
              "; + if (result.bool && dialog.canvas_viewer) + dialog.canvas_viewer.classList.remove("grayscale"); + } + if (!_status.connectMode) delete event.pingcai_delayed; + }, + event.videoId, + result, + player + ); game.delay(2.5); - "step 2" - game.broadcastAll('closeDialog',event.videoId); - if(result.bool){ - player.logSkill('pcaudio_'+event.cardname); - event.insert(lib.skill.xinfu_pingcai[event.cardname],{ - player:player, + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + if (result.bool) { + player.logSkill("pcaudio_" + event.cardname); + event.insert(lib.skill.xinfu_pingcai[event.cardname], { + player: player, }); } }, - ai:{ - order:7, - fireAttack:true, - threaten:1.7, - result:{ - player:1, + ai: { + order: 7, + fireAttack: true, + threaten: 1.7, + result: { + player: 1, }, }, }, - "xinfu_pdgyingshi":{ - mod:{ - targetEnabled:function(card,player,target){ - if(get.type(card)=='delay'){ + xinfu_pdgyingshi: { + mod: { + targetEnabled: function (card, player, target) { + if (get.type(card) == "delay") { return false; } }, }, - trigger:{ - player:['phaseZhunbeiBefore','phaseJieshuBefore'], + trigger: { + player: ["phaseZhunbeiBefore", "phaseJieshuBefore"], }, - forced:true, - audio:2, - group:'xinfu_pdgyingshi2', - content:function(){ + forced: true, + audio: 2, + group: "xinfu_pdgyingshi2", + content: function () { trigger.cancel(); - game.log(player,'跳过了',event.triggername=='phaseZhunbeiBefore'?'准备阶段':'结束阶段'); + game.log( + player, + "跳过了", + event.triggername == "phaseZhunbeiBefore" ? "准备阶段" : "结束阶段" + ); }, }, - xinfu_pdgyingshi2:{ - popup:false, - trigger:{ - player:"phaseJudgeBefore", + xinfu_pdgyingshi2: { + popup: false, + trigger: { + player: "phaseJudgeBefore", }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); - game.log(player,'跳过了判定阶段'); + game.log(player, "跳过了判定阶段"); }, }, - "pcaudio_wolong_card":{ - audio:true, + pcaudio_wolong_card: { + audio: true, }, - "pcaudio_fengchu_card":{ - audio:true, + pcaudio_fengchu_card: { + audio: true, }, - "pcaudio_shuijing_card":{ - audio:true, + pcaudio_shuijing_card: { + audio: true, }, - "pcaudio_xuanjian_card":{ - audio:true, + pcaudio_xuanjian_card: { + audio: true, }, - "yizan_use":{ - audio:'yizan_respond_shan', - intro:{ - content:"已发动过#次", + yizan_use: { + audio: "yizan_respond_shan", + intro: { + content: "已发动过#次", }, - enable:["chooseToUse","chooseToRespond"], - hiddenCard:function(player,name){ - if(get.type(name)!='basic') return false; - if(!player.storage.yizan&&player.countCards('hes')<2) return false; - return player.hasCard(function(card){ - return get.type(card)=='basic'; - },'hs'); + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + if (get.type(name) != "basic") return false; + if (!player.storage.yizan && player.countCards("hes") < 2) return false; + return player.hasCard(function (card) { + return get.type(card) == "basic"; + }, "hs"); }, - filter:function(event,player){ - if(!player.storage.yizan&&player.countCards('hes')<2) return false; - if(!player.hasCard(function(card){ - return get.type(card)=='basic'; - },'hs')) return false; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name,nature},'unsure'),player,event)) return true; + filter: function (event, player) { + if (!player.storage.yizan && player.countCards("hes") < 2) return false; + if ( + !player.hasCard(function (card) { + return get.type(card) == "basic"; + }, "hs") + ) + return false; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name, nature }, "unsure"), + player, + event + ) + ) + return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)){ - list.push(['基本','',name]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) { + list.push(["基本", "", name]); } - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name,nature},'unsure'),player,event)) list.push(['基本','','sha',nature]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name, nature }, "unsure"), + player, + event + ) + ) + list.push(["基本", "", "sha", nature]); } } } - return ui.create.dialog('翊赞',[list,'vcard'],'hidden'); + return ui.create.dialog("翊赞", [list, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(_status.event.getParent().type!='phase'||game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch(button.link[2]){ - case 'tao':case 'shan':return 5; - case 'jiu':{ - if(player.storage.yizan&&player.countCards('hs',{type:'basic'})>2) return 3; - }; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder'||button.link[3]=='ice') return 2.92; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + _status.event.getParent().type != "phase" || + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + case "shan": + return 5; + case "jiu": { + if ( + player.storage.yizan && + player.countCards("hs", { type: "basic" }) > 2 + ) + return 3; + } + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder" || button.link[3] == "ice") + return 2.92; else return 2.9; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'yizan_respond_shan', - filterCard:function(card,player,target){ - if(player.storage.yizan) return get.type(card)=='basic'; - else if(ui.selected.cards.length){ - if(get.type(ui.selected.cards[0])=='basic') return true; - return get.type(card)=='basic'; + audio: "yizan_respond_shan", + filterCard: function (card, player, target) { + if (player.storage.yizan) return get.type(card) == "basic"; + else if (ui.selected.cards.length) { + if (get.type(ui.selected.cards[0]) == "basic") return true; + return get.type(card) == "basic"; } return true; }, - complexCard:true, - selectCard:function(){ - var player=_status.event.player; - if(player.storage.yizan) return 1; + complexCard: true, + selectCard: function () { + var player = _status.event.player; + if (player.storage.yizan) return 1; return 2; }, - check:function(card,player,target){ - if(!ui.selected.cards.length&&get.type(card)=='basic') return 6; - else return 6-get.value(card); + check: function (card, player, target) { + if (!ui.selected.cards.length && get.type(card) == "basic") return 6; + else return 6 - get.value(card); }, - viewAs:{name:links[0][2],nature:links[0][3]}, - position:'hes', - popname:true, - precontent:function(){ - player.addMark('yizan_use',1,false); + viewAs: { name: links[0][2], nature: links[0][3] }, + position: "hes", + popname: true, + precontent: function () { + player.addMark("yizan_use", 1, false); }, - } + }; }, - prompt:function(links,player){ - var str=player.storage.yizan?'一张基本牌':'两张牌(其中至少应有一张基本牌)'; - return '将'+str+'当做'+get.translation(links[0][3]||'')+get.translation(links[0][2])+'使用或打出'; + prompt: function (links, player) { + var str = player.storage.yizan ? "一张基本牌" : "两张牌(其中至少应有一张基本牌)"; + return ( + "将" + + str + + "当做" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + + "使用或打出" + ); }, }, - ai:{ - order:function(){ - var player=_status.event.player; - var event=_status.event; - if(event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0&&player.storage.yizan&&player.countCards('hs',{type:'basic'})>2){ + ai: { + order: function () { + var player = _status.event.player; + var event = _status.event; + if ( + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 && + player.storage.yizan && + player.countCards("hs", { type: "basic" }) > 2 + ) { return 3.3; } return 3.1; }, - skillTagFilter:function(player,tag,arg){ - if(tag=='fireAttack') return true; - if(!player.storage.yizan&&player.countCards('hes')<2) return false; - if(!player.hasCard(function(card){ - return get.type(card)=='basic'; - },'hes')){ + skillTagFilter: function (player, tag, arg) { + if (tag == "fireAttack") return true; + if (!player.storage.yizan && player.countCards("hes") < 2) return false; + if ( + !player.hasCard(function (card) { + return get.type(card) == "basic"; + }, "hes") + ) { return false; } }, - result:{ - player:1, + result: { + player: 1, }, - respondSha:true, - respondShan:true, - fireAttack:true, + respondSha: true, + respondShan: true, + fireAttack: true, }, }, - "yizan_respond_shan":{ - audio:2, + yizan_respond_shan: { + audio: 2, }, - "xinfu_longyuan":{ - audio:2, - forced:true, - unique:true, - juexingji:true, - trigger:{ - player:'phaseZhunbeiBegin', + xinfu_longyuan: { + audio: 2, + forced: true, + unique: true, + juexingji: true, + trigger: { + player: "phaseZhunbeiBegin", }, - skillAnimation:true, - animationColor:'orange', - filter:function(event,player){ - return player.countMark('yizan_use')>=3; + skillAnimation: true, + animationColor: "orange", + filter: function (event, player) { + return player.countMark("yizan_use") >= 3; }, - content:function(){ - player.awakenSkill('xinfu_longyuan'); - player.storage.yizan=true; + content: function () { + player.awakenSkill("xinfu_longyuan"); + player.storage.yizan = true; + }, + derivation: "yizan_rewrite", + ai: { + combo: "yizan_use", }, - derivation:'yizan_rewrite', }, - xinfu_jingxie:{ - audio:2, - video:function(player,info){ - var l2=player.getCards(info[0]?'e':'h'),l1=info[1]; - for(var j=0;jget.subtype(card)=='equip2'&&player.canRecast(card), - filter:(event,player)=>{ - if(event.type!='dying') return false; - if(player!=event.dying) return false; - return player.hasCard(card=>lib.skill.xinfu_jingxie2.filterCard(card,player),'he'); + xinfu_jingxie2: { + prompt: "重铸一张防具牌,然后将体力回复至1点。", + audio: "xinfu_jingxie", + enable: "chooseToUse", + filterCard: (card, player) => get.subtype(card) == "equip2" && player.canRecast(card), + filter: (event, player) => { + if (event.type != "dying") return false; + if (player != event.dying) return false; + return player.hasCard((card) => lib.skill.xinfu_jingxie2.filterCard(card, player), "he"); }, - position:"he", - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' + position: "he", + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; player.recast(cards); - 'step 1' - var num=1-player.hp; - if(num) player.recover(num); + "step 1"; + var num = 1 - player.hp; + if (num) player.recover(num); }, - ai:{ - order:0.5, - skillTagFilter:function(player,arg,target){ - if(player!=target) return false; - return player.hasCard(card=>_status.connectMode&&get.position(card)=='h'||get.subtype(card)=='equip2'&&player.canRecast(card),'he'); + ai: { + order: 0.5, + skillTagFilter: function (player, arg, target) { + if (player != target) return false; + return player.hasCard( + (card) => + (_status.connectMode && get.position(card) == "h") || + (get.subtype(card) == "equip2" && player.canRecast(card)), + "he" + ); }, - save:true, - result:{ - player:function(player){ + save: true, + result: { + player: function (player) { return 10; }, }, }, }, - "xinfu_qiaosi":{ - enable:"phaseUse", - usable:1, - content:function(){ - 'step 0' - if(get.isLuckyStar(player)){ - event.num=6; + xinfu_qiaosi: { + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + if (get.isLuckyStar(player)) { + event.num = 6; player.throwDice(6); - } - else player.throwDice(); - 'step 1' - event.cards=get.cards(event.num); + } else player.throwDice(); + "step 1"; + event.cards = get.cards(event.num); player.showCards(event.cards); - 'step 2' - player.gain(event.cards,'gain2'); - player.chooseControl().set('choiceList',[ - '将'+get.cnNumber(event.num)+'张牌交给一名其他角色', - '弃置'+get.cnNumber(event.num)+'张牌', - ]).set('ai',function(){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>2; - })) return 0; - return 1; - }); - 'step 3' - if(result.index==0){ + "step 2"; + player.gain(event.cards, "gain2"); + player + .chooseControl() + .set("choiceList", [ + "将" + get.cnNumber(event.num) + "张牌交给一名其他角色", + "弃置" + get.cnNumber(event.num) + "张牌", + ]) + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 2; + }) + ) + return 0; + return 1; + }); + "step 3"; + if (result.index == 0) { player.chooseCardTarget({ - position:'he', - filterCard:true, - selectCard:event.num, - filterTarget:function(card,player,target){ - return player!=target; + position: "he", + filterCard: true, + selectCard: event.num, + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ + ai1: function (card) { return 1; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); + ai2: function (target) { + var att = get.attitude(_status.event.player, target); return att; }, - prompt:'请选择要送人的卡牌', - forced:true, + prompt: "请选择要送人的卡牌", + forced: true, }); - } - else{ - player.chooseToDiscard(event.num,true,'he'); + } else { + player.chooseToDiscard(event.num, true, "he"); event.finish(); } - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.give(result.cards,target); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.give(result.cards, target); } }, - ai:{ - order:7.5, - result:{ - player:1, + ai: { + order: 7.5, + result: { + player: 1, }, }, }, - zhaohuo:{ - audio:2, - audioname:['re_taoqian'], - trigger:{global:'dying'}, - forced:true, + zhaohuo: { + audio: 2, + audioname: ["re_taoqian"], + trigger: { global: "dying" }, + forced: true, //priority:12, - filter:function(event,player){ - return event.player!=player&&player.maxHp>1; + filter: function (event, player) { + return event.player != player && player.maxHp > 1; }, - content:function(){ - 'step 0' - event.num=player.maxHp-1; - player.loseMaxHp(event.num,true); - 'step 1' + content: function () { + "step 0"; + event.num = player.maxHp - 1; + player.loseMaxHp(event.num, true); + "step 1"; player.draw(event.num); - } + }, }, - yixiang:{ - audio:2, - audioname:['re_taoqian'], - trigger:{target:'useCardToTargeted'}, - frequent:true, - filter:function(event,player){ - if(event.player.hp<=player.hp) return false; + yixiang: { + audio: 2, + audioname: ["re_taoqian"], + trigger: { target: "useCardToTargeted" }, + frequent: true, + filter: function (event, player) { + if (event.player.hp <= player.hp) return false; //if(event.targets.length>1) return false; - var hs=player.getCards('h'); - var names=['sha','shan','tao','jiu','du']; - for(var i=0;iplayer.maxHp; + return game.hasPlayer(function (current) { + return current.maxHp > player.maxHp; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('yirang'),function(card,player,target){ - return target.maxHp>player.maxHp; - }).set('ai',function(target){ - return (get.attitude(_status.event.player,target)-2)*target.maxHp; - }); - 'step 1' - if(result.bool){ - var cards=player.getCards('he',function(card){ - return get.type(card)!='basic'; + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("yirang"), function (card, player, target) { + return target.maxHp > player.maxHp; + }) + .set("ai", function (target) { + return (get.attitude(_status.event.player, target) - 2) * target.maxHp; }); - var target=result.targets[0]; - var types=[]; - for(var i=0;i0; - }).ai=function(target){ - return -get.attitude(player,target); + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("shejian"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countDiscardableCards(player, "he") > 0; + } + ).ai = function (target) { + return -get.attitude(player, target); }; - 'step 1' - if(result.bool){ - player.logSkill('shejian',result.targets); - player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + "step 1"; + if (result.bool) { + player.logSkill("shejian", result.targets); + player.discardPlayerCard(result.targets[0], "he", true); + } else { event.finish(); } }, }, - shixin:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter:function(event){ - return event.hasNature('fire'); + shixin: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter: function (event) { + return event.hasNature("fire"); }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); }, - ai:{ - nofire:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'fireDamage')) return 'zerotarget'; - } - } - } + ai: { + nofire: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "fireDamage")) return "zerotarget"; + }, + }, + }, }, - fenyin:{ - locked:false, - mod:{ - aiOrder:function(player,card,num){ - if(typeof card=='object'&&player==_status.currentPhase){ - var evt=player.getLastUsed(); - if(evt&&evt.card&&get.color(evt.card)!='none'&&get.color(card)!='none'&&get.color(evt.card)!=get.color(card)){ - return num+10; + fenyin: { + locked: false, + mod: { + aiOrder: function (player, card, num) { + if (typeof card == "object" && player == _status.currentPhase) { + var evt = player.getLastUsed(); + if ( + evt && + evt.card && + get.color(evt.card) != "none" && + get.color(card) != "none" && + get.color(evt.card) != get.color(card) + ) { + return num + 10; } } }, }, - audio:2, - trigger:{player:'useCard'}, - frequent:true, + audio: 2, + trigger: { player: "useCard" }, + frequent: true, //usable:3, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - var evt=player.getLastUsed(1); - if(!evt) return false; - var color1=get.color(evt.card); - var color2=get.color(event.card); - return color1&&color2&&color1!='none'&&color2!='none'&&color1!=color2; + filter: function (event, player) { + if (_status.currentPhase != player) return false; + var evt = player.getLastUsed(1); + if (!evt) return false; + var color1 = get.color(evt.card); + var color2 = get.color(event.card); + return color1 && color2 && color1 != "none" && color2 != "none" && color1 != color2; }, - content:function(){ + content: function () { player.draw(); }, - ai:{ - threaten:3, + ai: { + threaten: 3, }, }, - dujin:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - preHidden:true, - filter:function(event,player){ + dujin: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + preHidden: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=1+Math.ceil(player.countCards('e')/2); - } - }, - yingjian:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - audio:'qingyi', - content:function(){ - player.chooseUseTarget('###是否发动【影箭】?###视为使用一张没有距离限制的【杀】',{name:'sha'},false,'nodistance').logSkill='yingjian'; + content: function () { + trigger.num += 1 + Math.ceil(player.countCards("e") / 2); }, - ai:{ - threaten:function(player,target){ - return 1.6; - } - } }, - tunchu:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - preHidden:true, - locked:false, - filter:function(event,player){ - if(event.numFixed||player.getExpansions('tunchu').length) return false; + yingjian: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + audio: "qingyi", + content: function () { + player.chooseUseTarget( + "###是否发动【影箭】?###视为使用一张没有距离限制的【杀】", + { name: "sha" }, + false, + "nodistance" + ).logSkill = "yingjian"; + }, + ai: { + threaten: function (player, target) { + return 1.6; + }, + }, + }, + tunchu: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + preHidden: true, + locked: false, + filter: function (event, player) { + if (event.numFixed || player.getExpansions("tunchu").length) return false; return true; }, - content:function(){ - trigger.num+=2; - player.addTempSkill('tunchu_choose','phaseDrawAfter'); + content: function () { + trigger.num += 2; + player.addTempSkill("tunchu_choose", "phaseDrawAfter"); }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - mod:{ - cardEnabled:function(card,player){ - if(player.getExpansions('tunchu').length&&card.name=='sha'){ + mod: { + cardEnabled: function (card, player) { + if (player.getExpansions("tunchu").length && card.name == "sha") { return false; } }, }, - subSkill:{ - choose:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - 'step 0' - player.removeSkill('tunchu_choose'); - var nh=player.countCards('h'); - if(nh){ - player.chooseCard('h',[1,nh],'将任意张手牌置于你的武将牌上').set('ai',function(card){ - var player=_status.event.player; - var count=game.countPlayer(function(current){ - return get.attitude(player,current)>2&¤t.hp-current.countCards('h')>1; + subSkill: { + choose: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + "step 0"; + player.removeSkill("tunchu_choose"); + var nh = player.countCards("h"); + if (nh) { + player + .chooseCard("h", [1, nh], "将任意张手牌置于你的武将牌上") + .set("ai", function (card) { + var player = _status.event.player; + var count = game.countPlayer(function (current) { + return ( + get.attitude(player, current) > 2 && + current.hp - current.countCards("h") > 1 + ); + }); + if (ui.selected.cards.length >= count) return -get.value(card); + return 5 - get.value(card); }); - if(ui.selected.cards.length>=count) return -get.value(card); - return 5-get.value(card); - }); - } - else{ + } else { event.finish(); } - 'step 1' - if(result.bool){ - player.addToExpansion(result.cards,player,'giveAuto').gaintag.add('tunchu'); + "step 1"; + if (result.bool) { + player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("tunchu"); } - } + }, }, - } - }, - shuliang:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('tunchu').length>0&&event.player.countCards('h')0); - player.chooseCardButton(get.prompt('shuliang',trigger.player),player.getExpansions('tunchu')).set('ai',function(){ - if(_status.event.goon) return 1; - return 0; - }).set('goon',goon); - 'step 1' - if(result.bool){ - player.logSkill('shuliang',trigger.player); + }, + shuliang: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getExpansions("tunchu").length > 0 && + event.player.countCards("h") < event.player.hp && + event.player.isIn() + ); + }, + content: function () { + "step 0"; + var goon = get.attitude(player, trigger.player) > 0; + player + .chooseCardButton( + get.prompt("shuliang", trigger.player), + player.getExpansions("tunchu") + ) + .set("ai", function () { + if (_status.event.goon) return 1; + return 0; + }) + .set("goon", goon); + "step 1"; + if (result.bool) { + player.logSkill("shuliang", trigger.player); player.loseToDiscardpile(result.links); trigger.player.draw(2); } }, - ai:{combo:'tunchu'}, + ai: { combo: "tunchu" }, }, - choulve:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); - }) + choulve: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he"); + }); }, - content:function(){ - 'step 0' - var str='令一名其他角色交给你一张牌'; - var history=player.getAllHistory('damage',function(evt){ - return evt.card&&evt.card.name&&lib.card[evt.card.name]; - }) - if(history.length) event.cardname=history[history.length-1].card.name; - if(event.cardname){ - str+='若其如此做,视为你使用【'+get.translation(event.cardname)+'】'; + content: function () { + "step 0"; + var str = "令一名其他角色交给你一张牌"; + var history = player.getAllHistory("damage", function (evt) { + return evt.card && evt.card.name && lib.card[evt.card.name]; + }); + if (history.length) event.cardname = history[history.length - 1].card.name; + if (event.cardname) { + str += "若其如此做,视为你使用【" + get.translation(event.cardname) + "】"; } - var goon=true; - if(event.cardname){ - goon=game.hasPlayer(function(current){ - return player.canUse(event.cardname,current)&&get.effect(current,{name:event.cardname},player,player)>0; + var goon = true; + if (event.cardname) { + goon = game.hasPlayer(function (current) { + return ( + player.canUse(event.cardname, current) && + get.effect(current, { name: event.cardname }, player, player) > 0 + ); }); } - player.chooseTarget(get.prompt('choulve'),str,function(card,player,target){ - return target!=player&&target.countCards('he'); - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - var player=_status.event.player; - if(get.attitude(player,target)>=0&&get.attitude(target,player)>=0){ - return Math.sqrt(target.countCards('he')); - } - return 0; - }).set('goon',goon); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('choulve',target); - target.chooseCard('he','是否交给'+get.translation(player)+'一张牌?', - event.cardname?('若如此做,视为'+get.translation(player)+ - '使用【'+get.translation(event.cardname)+'】'):null).set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); + player + .chooseTarget(get.prompt("choulve"), str, function (card, player, target) { + return target != player && target.countCards("he"); + }) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + var player = _status.event.player; + if (get.attitude(player, target) >= 0 && get.attitude(target, player) >= 0) { + return Math.sqrt(target.countCards("he")); + } return 0; - }).set('goon',get.attitude(target,player)>1); - event.target=target; - } - else{ + }) + .set("goon", goon); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("choulve", target); + target + .chooseCard( + "he", + "是否交给" + get.translation(player) + "一张牌?", + event.cardname + ? "若如此做,视为" + + get.translation(player) + + "使用【" + + get.translation(event.cardname) + + "】" + : null + ) + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) > 1); + event.target = target; + } else { event.finish(); } - 'step 2' - if(result.bool){ - event.target.give(result.cards,player); - if(event.cardname){ - player.chooseUseTarget(event.cardname,true,false); + "step 2"; + if (result.bool) { + event.target.give(result.cards, player); + if (event.cardname) { + player.chooseUseTarget(event.cardname, true, false); } } }, }, - polu:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - if(!lib.inpile.includes('ly_piliche')) return true; - return !!get.cardPile(function(card){ - return card.name=='ly_piliche'; + polu: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + if (!lib.inpile.includes("ly_piliche")) return true; + return !!get.cardPile(function (card) { + return card.name == "ly_piliche"; }); }, - content:function(){ + content: function () { var card; - if(!lib.inpile.includes('ly_piliche')){ - card=game.createCard2('ly_piliche','diamond',1); - lib.inpile.push('ly_piliche'); - } - else card=get.cardPile(function(card){ - return card.name=='ly_piliche'; - }); - player.chooseUseTarget(card,true,'nopopup'); + if (!lib.inpile.includes("ly_piliche")) { + card = game.createCard2("ly_piliche", "diamond", 1); + lib.inpile.push("ly_piliche"); + } else + card = get.cardPile(function (card) { + return card.name == "ly_piliche"; + }); + player.chooseUseTarget(card, true, "nopopup"); }, - group:'polu_damage', - subSkill:{ - damage:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return !player.getEquips('ly_piliche').length; + group: "polu_damage", + subSkill: { + damage: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return !player.getEquips("ly_piliche").length; }, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; player.draw(); - 'step 2' - var card=get.cardPile2(function(card){ - return get.subtype(card,false)=='equip1'&&player.canUse(card,player); + "step 2"; + var card = get.cardPile2(function (card) { + return get.subtype(card, false) == "equip1" && player.canUse(card, player); }); - if(card) player.chooseUseTarget(card,true,'nopopup'); - 'step 3' - if(event.count>0&&!player.getEquips('ly_piliche').length) event.goto(1); + if (card) player.chooseUseTarget(card, true, "nopopup"); + "step 3"; + if (event.count > 0 && !player.getEquips("ly_piliche").length) event.goto(1); }, }, }, }, - ly_piliche:{ - trigger:{source:'damageSource'}, - check:function(event,player){ - return get.attitude(player,event.player)*get.value(event.player.getDiscardableCards(player,'e'),event.player)<=0; + ly_piliche: { + trigger: { source: "damageSource" }, + check: function (event, player) { + return ( + get.attitude(player, event.player) * + get.value(event.player.getDiscardableCards(player, "e"), event.player) <= + 0 + ); }, - filter:function(event,player){ - return player!=event.player&&event.player.countDiscardableCards(player,'e')>0; + filter: function (event, player) { + return player != event.player && event.player.countDiscardableCards(player, "e") > 0; + }, + logTarget: "player", + content: function () { + player.discardPlayerCard(trigger.player, "e", true, trigger.player.countCards("e")); }, - logTarget:'player', - content:function(){ - player.discardPlayerCard(trigger.player,'e',true,trigger.player.countCards('e')); - } }, - xinzhilve:{ - enable:'phaseUse', - audio:'zhilve', - usable:1, - chooseButton:{ - dialog:function(event,player){ - var list=[ - '移动场上的一张牌', - '摸一张牌并视为使用一张【杀】', - ]; - var choiceList=ui.create.dialog('知略:失去1点体力并...','forcebutton','hidden'); - choiceList.add([list.map((item,i)=>{ - return [i,item]; - }),'textbutton']); + xinzhilve: { + enable: "phaseUse", + audio: "zhilve", + usable: 1, + chooseButton: { + dialog: function (event, player) { + var list = ["移动场上的一张牌", "摸一张牌并视为使用一张【杀】"]; + var choiceList = ui.create.dialog("知略:失去1点体力并...", "forcebutton", "hidden"); + choiceList.add([ + list.map((item, i) => { + return [i, item]; + }), + "textbutton", + ]); return choiceList; }, - filter:function(button,player){ - if(button.link==0) return player.canMoveCard(); - return player.hasUseTarget({name:'sha',isCard:true},false); + filter: function (button, player) { + if (button.link == 0) return player.canMoveCard(); + return player.hasUseTarget({ name: "sha", isCard: true }, false); }, - check:function(button){ + check: function (button) { return button.link; }, - backup:function(links){ - return lib.skill['xinzhilve_'+['move','use'][links[0]]]; + backup: function (links) { + return lib.skill["xinzhilve_" + ["move", "use"][links[0]]]; + }, + prompt: function () { + return "请选择【杀】的目标"; }, - prompt:function(){return '请选择【杀】的目标'}, }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'})+0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }) + 0.1; }, - result:{ - player:function(player){ - if(player.hp>2&&player.hasValueTarget({name:'sha'})) return 1; + result: { + player: function (player) { + if (player.hp > 2 && player.hasValueTarget({ name: "sha" })) return 1; return 0; }, }, }, }, - xinzhilve_move:{ - audio:'zhilve', - filterCard:function(){return false}, - selectCard:-1, - delay:false, - content:function(){ - 'step 0' - event.forceDie=true; - if(!player.canMoveCard(null,event.nojudge)){ + xinzhilve_move: { + audio: "zhilve", + filterCard: function () { + return false; + }, + selectCard: -1, + delay: false, + content: function () { + "step 0"; + event.forceDie = true; + if (!player.canMoveCard(null, event.nojudge)) { event.finish(); return; } - var next=player.chooseTarget(2,function(card,player,target){ - if(ui.selected.targets.length){ - var from=ui.selected.targets[0]; - var js=from.getCards('j'); - for(var i=0;i0; + } else { + var range = "ej"; + if (_status.event.nojudge) range = "e"; + return target.countCards(range) > 0; } }); - next.set('nojudge',event.nojudge||false); - next.set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - var sgnatt=get.sgn(att); - if(ui.selected.targets.length==0){ - if(att>0){ - if(!_status.event.nojudge&&target.countCards('j',function(card){ - return game.hasPlayer(function(current){ - return current.canAddJudge(card)&&get.attitude(player,current)<0; + next.set("nojudge", event.nojudge || false); + next.set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var sgnatt = get.sgn(att); + if (ui.selected.targets.length == 0) { + if (att > 0) { + if ( + !_status.event.nojudge && + target.countCards("j", function (card) { + return game.hasPlayer(function (current) { + return ( + current.canAddJudge(card) && get.attitude(player, current) < 0 + ); + }); }) - })) return 14; - if(target.countCards('e',function(card){ - return get.value(card,target)<0&&game.hasPlayer(function(current){ - return current!=target&&get.attitude(player,current)<0&¤t.canEquip(card) - }); - })>0) return 9; - } - else if(att<0){ - if(game.hasPlayer(function(current){ - if(current!=target&&get.attitude(player,current)>0){ - var es=target.getCards('e'); - for(var i=0;i0&¤t.canEquip(es[i])&&get.value(es[i],current)>0) return true; + ) + return 14; + if ( + target.countCards("e", function (card) { + return ( + get.value(card, target) < 0 && + game.hasPlayer(function (current) { + return ( + current != target && + get.attitude(player, current) < 0 && + current.canEquip(card) + ); + }) + ); + }) > 0 + ) + return 9; + } else if (att < 0) { + if ( + game.hasPlayer(function (current) { + if (current != target && get.attitude(player, current) > 0) { + var es = target.getCards("e"); + for (var i = 0; i < es.length; i++) { + if ( + get.value(es[i], target) > 0 && + current.canEquip(es[i]) && + get.value(es[i], current) > 0 + ) + return true; + } } - } - })){ + }) + ) { return -att; } } return 0; } - var es=ui.selected.targets[0].getCards('e'); + var es = ui.selected.targets[0].getCards("e"); var i; - var att2=get.sgn(get.attitude(player,ui.selected.targets[0])); - for(i=0;i0&&get.attitude(player,targets1)<0){ - if(get.position(button.link)=='j') return 12; - if(get.value(button.link,targets0)<0) return 10; - return 0; - } - else{ - if(get.position(button.link)=='j') return -10; - return get.equipValue(button.link); - } - },targets[0]).set('nojudge',event.nojudge||false).set('targets0',targets[0]).set('targets1',targets[1]).set('filterButton',function(button){ - var targets1=_status.event.targets1; - if(get.position(button.link)=='j'){ - if(_status.event.nojudge) return false; - return targets1.canAddJudge(button.link); - } - else{ - return targets1.canEquip(button.link); - } - }); - } - else{ + "step 3"; + if (targets.length == 2) { + player + .choosePlayerCard( + "ej", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if ( + get.attitude(player, targets0) > 0 && + get.attitude(player, targets1) < 0 + ) { + if (get.position(button.link) == "j") return 12; + if (get.value(button.link, targets0) < 0) return 10; + return 0; + } else { + if (get.position(button.link) == "j") return -10; + return get.equipValue(button.link); + } + }, + targets[0] + ) + .set("nojudge", event.nojudge || false) + .set("targets0", targets[0]) + .set("targets1", targets[1]) + .set("filterButton", function (button) { + var targets1 = _status.event.targets1; + if (get.position(button.link) == "j") { + if (_status.event.nojudge) return false; + return targets1.canAddJudge(button.link); + } else { + return targets1.canEquip(button.link); + } + }); + } else { event.finish(); } - 'step 4' - if(result.bool&&result.links.length){ + "step 4"; + if (result.bool && result.links.length) { player.loseHp(); } - 'step 5' - if(result.bool&&result.links.length){ - var link=result.links[0]; - if(get.position(link)=='e'){ + "step 5"; + if (result.bool && result.links.length) { + var link = result.links[0]; + if (get.position(link) == "e") { event.targets[1].equip(link); - } - else if(link.viewAs){ - event.targets[1].addJudge({name:link.viewAs},[link]); - } - else{ + } else if (link.viewAs) { + event.targets[1].addJudge({ name: link.viewAs }, [link]); + } else { event.targets[1].addJudge(link); } - event.targets[0].$give(link,event.targets[1]) - event.result.card=link; - event.result.position=get.position(link); + event.targets[0].$give(link, event.targets[1]); + event.result.card = link; + event.result.position = get.position(link); game.delay(); - player.addTempSkill('xinzhilve_mark'); - player.addMark('xinzhilve_mark',1,false); + player.addTempSkill("xinzhilve_mark"); + player.addMark("xinzhilve_mark", 1, false); } }, }, - xinzhilve_use:{ - audio:'zhilve', - filterCard:function(){return false}, - selectCard:-1, - filterTarget:function(card,player,target){ - return player.canUse({name:'sha',isCard:true},target,false); + xinzhilve_use: { + audio: "zhilve", + filterCard: function () { + return false; }, - content:function(){ + selectCard: -1, + filterTarget: function (card, player, target) { + return player.canUse({ name: "sha", isCard: true }, target, false); + }, + content: function () { player.loseHp(); player.draw(); - player.useCard({name:'sha',isCard:true},false,target).forceDie=true; - player.addTempSkill('xinzhilve_mark'); - player.addMark('xinzhilve_mark',1,false); + player.useCard({ name: "sha", isCard: true }, false, target).forceDie = true; + player.addTempSkill("xinzhilve_mark"); + player.addMark("xinzhilve_mark", 1, false); }, - ai:{ - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,target); + ai: { + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, target); }, }, }, }, - xinzhilve_mark:{ - intro:{content:'本回合手牌上限+#'}, - onremove:true, - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('xinzhilve_mark'); + xinzhilve_mark: { + intro: { content: "本回合手牌上限+#" }, + onremove: true, + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("xinzhilve_mark"); }, }, }, - xinxhzhiyan:{ - audio:'xhzhiyan', - enable:'phaseUse', - filter:function(event,player){ - return (!player.hasSkill('xinxhzhiyan_true')&&player.countCards('h')>player.hp)||(!player.hasSkill('xinxhzhiyan_false')&&player.countCards('h') player.hp) || + (!player.hasSkill("xinxhzhiyan_false") && player.countCards("h") < player.maxHp) + ); }, - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - if(player.hasSkill('xinxhzhiyan_true')) return 0; - var num=Math.max(0,player.countCards('h')-player.hp); - if(ui.selected.cards.length||player.hasSkill('xinxhzhiyan_false')||player.countCards('h')>=player.maxHp) return [num,num]; - return [0,num] + filterCard: true, + selectCard: function () { + var player = _status.event.player; + if (player.hasSkill("xinxhzhiyan_true")) return 0; + var num = Math.max(0, player.countCards("h") - player.hp); + if ( + ui.selected.cards.length || + player.hasSkill("xinxhzhiyan_false") || + player.countCards("h") >= player.maxHp + ) + return [num, num]; + return [0, num]; }, - filterTarget:lib.filter.notMe, - selectTarget:function(){ - if(ui.selected.cards.length) return [1,1]; - return [0,0]; + filterTarget: lib.filter.notMe, + selectTarget: function () { + if (ui.selected.cards.length) return [1, 1]; + return [0, 0]; }, - check:function(card){ - var player=_status.event.player; - var checkx=function(card){ - if(player.getUseValue(card,null,true)<=0&&game.hasPlayer(function(current){ - return current!=player&&get.value(card,current)>0&&get.attitude(player,current)>0; - })) return 2; + check: function (card) { + var player = _status.event.player; + var checkx = function (card) { + if ( + player.getUseValue(card, null, true) <= 0 && + game.hasPlayer(function (current) { + return ( + current != player && + get.value(card, current) > 0 && + get.attitude(player, current) > 0 + ); + }) + ) + return 2; return 1; - } - if(player.countCards('h',function(card){ - return checkx(card)>0; - })<(player.countCards('h')-player.hp)) return 0; + }; + if ( + player.countCards("h", function (card) { + return checkx(card) > 0; + }) < + player.countCards("h") - player.hp + ) + return 0; return checkx(card); }, - delay:false, - discard:false, - lose:false, - content:function(){ - var bool=(cards&&cards.length>0); - player.addTempSkill('xinxhzhiyan_'+bool,'phaseUseEnd'); - if(!bool){ - player.draw(player.maxHp-player.countCards('h')); - } - else{ - player.give(cards,target); + delay: false, + discard: false, + lose: false, + content: function () { + var bool = cards && cards.length > 0; + player.addTempSkill("xinxhzhiyan_" + bool, "phaseUseEnd"); + if (!bool) { + player.draw(player.maxHp - player.countCards("h")); + } else { + player.give(cards, target); } }, - ai:{ - order:function(obj,player){ - if(player.countCards('h')>player.hp) return 10; + ai: { + order: function (obj, player) { + if (player.countCards("h") > player.hp) return 10; return 0.5; }, - result:{ - player:function(player,target){ - if(!ui.selected.cards.length&&player.countCards('h')0) player.gainPlayerCard(trigger.player,'he',true); - trigger.player.unmarkSkill('weifeng2'); - } - else{ - game.countPlayer(function(current){ - if(current.storage.weifeng2) current.unmarkSkill('weifeng2'); - }); - player.removeSkill('weifeng3'); + content: function () { + if (trigger.name == "damage") { + player.logSkill("weifeng", trigger.player); + if (trigger.card && trigger.card.name == trigger.player.storage.weifeng2) + trigger.num++; + else if (trigger.player.countGainableCards(player, "he") > 0) + player.gainPlayerCard(trigger.player, "he", true); + trigger.player.unmarkSkill("weifeng2"); + } else { + game.countPlayer(function (current) { + if (current.storage.weifeng2) current.unmarkSkill("weifeng2"); + }); + player.removeSkill("weifeng3"); } }, }, - gnjinfan:{ - trigger:{player:'phaseDiscardBegin'}, - direct:true, - locked:false, - audio:2, - filter:function(event,player){ - var list=[]; - player.getCards('s',function(card){ - if(card.hasGaintag('gnjinfan')) list.add(get.suit(card)); + gnjinfan: { + trigger: { player: "phaseDiscardBegin" }, + direct: true, + locked: false, + audio: 2, + filter: function (event, player) { + var list = []; + player.getCards("s", function (card) { + if (card.hasGaintag("gnjinfan")) list.add(get.suit(card)); }); - if(list.length>=lib.suit.length) return false; - return player.countCards('h',function(card){ - return _status.connectMode||!list.includes(get.suit(card)); - })>0; + if (list.length >= lib.suit.length) return false; + return ( + player.countCards("h", function (card) { + return _status.connectMode || !list.includes(get.suit(card)); + }) > 0 + ); }, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('gnjinfan'),'将任意张手牌当做“铃”置于武将牌上',[1,function(){ - var list=[]; - var list2=[]; - player.getCards('s',function(card){ - if(card.hasGaintag('gnjinfan')) list.add(get.suit(card)); - }); - player.getCards('h',function(card){ - list2.add(get.suit(card)); - }); - list2.removeArray(list); - return Math.max(1,list2.length); - }()],function(card,player){ - return !player.countCards('s',function(cardx){ - return cardx.hasGaintag('gnjinfan')&&get.suit(cardx,false)==get.suit(card,player); - })&&!ui.selected.cards.filter(function(cardx){ - return get.suit(cardx,player)==get.suit(card,player); - }).length; - }).set('ai',function(card){ - var player=_status.event.player; - if(player.hasUseTarget(card)&&!player.hasValueTarget(card)) return 0; - if(['sha','shan','wuxie','caochuan'].includes(card.name)) return 2+Math.random(); - return 1+Math.random(); - }).set('complexCard',true); - 'step 1' - if(result.bool){ - player.logSkill('gnjinfan'); - game.log(player,'将',result.cards,'放到了武将牌上'); - player.loseToSpecial(result.cards,'gnjinfan').visible=true; - } - else event.finish(); - 'step 2' - player.markSkill('gnjinfan'); + content: function () { + "step 0"; + player + .chooseCard( + "h", + get.prompt("gnjinfan"), + "将任意张手牌当做“铃”置于武将牌上", + [ + 1, + (function () { + var list = []; + var list2 = []; + player.getCards("s", function (card) { + if (card.hasGaintag("gnjinfan")) list.add(get.suit(card)); + }); + player.getCards("h", function (card) { + list2.add(get.suit(card)); + }); + list2.removeArray(list); + return Math.max(1, list2.length); + })(), + ], + function (card, player) { + return ( + !player.countCards("s", function (cardx) { + return ( + cardx.hasGaintag("gnjinfan") && + get.suit(cardx, false) == get.suit(card, player) + ); + }) && + !ui.selected.cards.filter(function (cardx) { + return get.suit(cardx, player) == get.suit(card, player); + }).length + ); + } + ) + .set("ai", function (card) { + var player = _status.event.player; + if (player.hasUseTarget(card) && !player.hasValueTarget(card)) return 0; + if (["sha", "shan", "wuxie", "caochuan"].includes(card.name)) + return 2 + Math.random(); + return 1 + Math.random(); + }) + .set("complexCard", true); + "step 1"; + if (result.bool) { + player.logSkill("gnjinfan"); + game.log(player, "将", result.cards, "放到了武将牌上"); + player.loseToSpecial(result.cards, "gnjinfan").visible = true; + } else event.finish(); + "step 2"; + player.markSkill("gnjinfan"); }, - group:['gnjinfan_gain'], - marktext:'铃', - intro:{ - mark:function(dialog,storage,player){ - dialog.addAuto(player.getCards('s',function(card){ - return card.hasGaintag('gnjinfan'); - })); + group: ["gnjinfan_gain"], + marktext: "铃", + intro: { + mark: function (dialog, storage, player) { + dialog.addAuto( + player.getCards("s", function (card) { + return card.hasGaintag("gnjinfan"); + }) + ); }, - markcount:function(storage,player){ - return player.getCards('s',function(card){ - return card.hasGaintag('gnjinfan'); + markcount: function (storage, player) { + return player.getCards("s", function (card) { + return card.hasGaintag("gnjinfan"); }).length; }, - onunmark:function(storage,player){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('gnjinfan'); + onunmark: function (storage, player) { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("gnjinfan"); }); - if(cards.length){ - player.lose(cards,ui.discardPile); - player.$throw(cards,1000); - game.log(cards,'进入了弃牌堆'); + if (cards.length) { + player.lose(cards, ui.discardPile); + player.$throw(cards, 1000); + game.log(cards, "进入了弃牌堆"); } }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('gnjinfan')) return num+0.5; + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("gnjinfan")) return num + 0.5; }, }, }, - gnjinfan_gain:{ - audio:'gnjinfan', - trigger:{player:'loseAfter'}, - forced:true, - filter:function(event,player){ - if(!event.ss||!event.ss.length) return false; - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('gnjinfan')) return true; + gnjinfan_gain: { + audio: "gnjinfan", + trigger: { player: "loseAfter" }, + forced: true, + filter: function (event, player) { + if (!event.ss || !event.ss.length) return false; + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("gnjinfan")) return true; return false; } }, - content:function(){ - 'step 0' - var cards=[]; - for(var i of trigger.ss){ - if(!trigger.gaintag_map[i.cardid]||!trigger.gaintag_map[i.cardid].includes('gnjinfan')) continue; - var suit=get.suit(i,false); - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&get.suit(card,false)==suit; + content: function () { + "step 0"; + var cards = []; + for (var i of trigger.ss) { + if ( + !trigger.gaintag_map[i.cardid] || + !trigger.gaintag_map[i.cardid].includes("gnjinfan") + ) + continue; + var suit = get.suit(i, false); + var card = get.cardPile2(function (card) { + return !cards.includes(card) && get.suit(card, false) == suit; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); - var num=player.getCards('s',function(card){ - return card.hasGaintag('gnjinfan'); + if (cards.length) player.gain(cards, "gain2"); + var num = player.getCards("s", function (card) { + return card.hasGaintag("gnjinfan"); }).length; - if(num) player.markSkill('gnjinfan'); - else player.unmarkSkill('gnjinfan'); - 'step 1' + if (num) player.markSkill("gnjinfan"); + else player.unmarkSkill("gnjinfan"); + "step 1"; game.updateRoundNumber(); }, }, - gnsheque:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return event.player.isIn()&&event.player.countCards('e')>0&& - lib.filter.targetEnabled({name:'sha'},player,event.player)&&(player.hasSha()||_status.connectMode&&player.countCards('h')>0); + gnsheque: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player.countCards("e") > 0 && + lib.filter.targetEnabled({ name: "sha" }, player, event.player) && + (player.hasSha() || (_status.connectMode && player.countCards("h") > 0)) + ); }, - content:function(){ - player.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'射却:是否对'+get.translation(trigger.player)+'使用一张杀?').set('logSkill','gnsheque').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.player).set('oncard',function(card){ - try{ - card.gnsheque_tag=true; - }catch(e){ - alert('发生了一个导致【射却】无法正常触发无视防具效果的错误。请关闭十周年UI/手杀ui等扩展以解决'); - } - }); + content: function () { + player + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "射却:是否对" + get.translation(trigger.player) + "使用一张杀?") + .set("logSkill", "gnsheque") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.player) + .set("oncard", function (card) { + try { + card.gnsheque_tag = true; + } catch (e) { + alert( + "发生了一个导致【射却】无法正常触发无视防具效果的错误。请关闭十周年UI/手杀ui等扩展以解决" + ); + } + }); + }, + ai: { + unequip: true, + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "unequip_ai") { + if (_status.event.getParent().name != "gnsheque") return false; + } else if (!arg || !arg.card || !arg.card.gnsheque_tag) return false; + }, }, - ai:{ - unequip:true, - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='unequip_ai'){ - if(_status.event.getParent().name!='gnsheque') return false; - } - else if(!arg||!arg.card||!arg.card.gnsheque_tag) return false; - }, - }, }, - _doublegroup_choice:{ - trigger:{ - global:'gameStart', - player:'enterGame', + _doublegroup_choice: { + trigger: { + global: "gameStart", + player: "enterGame", }, - forced:true, - charlotte:true, - firstDo:true, - popup:false, - filter:function(event,player){ - return get.mode()!='guozhan'&&get.is.double(player.name1)&&!player._groupChosen; + forced: true, + charlotte: true, + firstDo: true, + popup: false, + filter: function (event, player) { + return get.mode() != "guozhan" && get.is.double(player.name1) && !player._groupChosen; }, - content:function(){ - 'step 0' - player._groupChosen=true; - player.chooseControl(get.is.double(player.name1,true)).set('prompt','请选择你的势力'); - 'step 1' + content: function () { + "step 0"; + player._groupChosen = true; + player.chooseControl(get.is.double(player.name1, true)).set("prompt", "请选择你的势力"); + "step 1"; player.changeGroup(result.control); }, }, }, - dynamicTranslate:{ - yizan_use:function(player){ - if(player.storage.yizan) return '你可以将一张基本牌当做任意基本牌使用或打出。'; - return '你可以将两张牌(其中至少一张为基本牌)当做任意基本牌使用或打出。'; + dynamicTranslate: { + yizan_use: function (player) { + if (player.storage.yizan) return "你可以将一张基本牌当做任意基本牌使用或打出。"; + return "你可以将两张牌(其中至少一张为基本牌)当做任意基本牌使用或打出。"; }, - miaojian:function(player){ + miaojian: function (player) { return [ - '出牌阶段限一次。你可将一张【杀】当做刺【杀】使用,或将一张锦囊牌当做【无中生有】使用。', - '出牌阶段限一次。你可将一张基本牌当做刺【杀】使用,或将一张非基本牌当做【无中生有】使用。', - '出牌阶段限一次。你可视为使用一张刺【杀】或【无中生有】。', - ][player.countMark('miaojian')]; + "出牌阶段限一次。你可将一张【杀】当做刺【杀】使用,或将一张锦囊牌当做【无中生有】使用。", + "出牌阶段限一次。你可将一张基本牌当做刺【杀】使用,或将一张非基本牌当做【无中生有】使用。", + "出牌阶段限一次。你可视为使用一张刺【杀】或【无中生有】。", + ][player.countMark("miaojian")]; }, - shhlianhua:function(player){ + shhlianhua: function (player) { return [ - '当你成为【杀】的目标后,你摸一张牌。', - '当你成为【杀】的目标后,你摸一张牌。然后你进行判定,若结果为黑桃,则此【杀】对你无效。', - '当你成为【杀】的目标后,你摸一张牌。然后此【杀】的使用者选择一项:①弃置一张牌。②令此【杀】对你无效。', - ][player.countMark('shhlianhua')]; + "当你成为【杀】的目标后,你摸一张牌。", + "当你成为【杀】的目标后,你摸一张牌。然后你进行判定,若结果为黑桃,则此【杀】对你无效。", + "当你成为【杀】的目标后,你摸一张牌。然后此【杀】的使用者选择一项:①弃置一张牌。②令此【杀】对你无效。", + ][player.countMark("shhlianhua")]; }, - spshidi:function(player){ - if(player.countMark('spshidi')%2==0) return '转换技,锁定技。①准备阶段/结束阶段开始时,若你发动此分支的累计次数为奇数/偶数,则你获得一个“☯”。②若你的“☯”数为偶数,则你至其他角色的距离-1,且你使用的黑色【杀】不可被响应。③若你的“☯”数为奇数,则其他角色至你的距离+1,且你不可响应红色【杀】。'; + spshidi: function (player) { + if (player.countMark("spshidi") % 2 == 0) + return '转换技,锁定技。①准备阶段/结束阶段开始时,若你发动此分支的累计次数为奇数/偶数,则你获得一个“☯”。②若你的“☯”数为偶数,则你至其他角色的距离-1,且你使用的黑色【杀】不可被响应。③若你的“☯”数为奇数,则其他角色至你的距离+1,且你不可响应红色【杀】。'; return '转换技,锁定技。①准备阶段/结束阶段开始时,若你发动此分支的累计次数为奇数/偶数,则你获得一个“☯”。②若你的“☯”数为偶数,则你至其他角色的距离-1,且你使用的黑色【杀】不可被响应。③若你的“☯”数为奇数,则其他角色至你的距离+1,且你不可响应红色【杀】。'; }, - mobilexingxue:function(player){ - return lib.translate[(player.storage.mobileyanzhu?'mobilexingxuex':'mobilexingxue')+'_info']; + mobilexingxue: function (player) { + return lib.translate[ + (player.storage.mobileyanzhu ? "mobilexingxuex" : "mobilexingxue") + "_info" + ]; }, - shoufa:function(player){ - const zhoufa=player.storage.zhoulin_zhoufa; - const nodoudizhu=(get.mode()=='doudizhu'?'':'与你距离大于/不大于2的'); - if(!zhoufa) return '当你受到伤害后/于一回合首次造成伤害后,你可以选择一名'+nodoudizhu+'角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。'; - let str='当你受到伤害后/于一回合首次造成伤害后,你可以选择一名'+nodoudizhu+'角色,'; - str+=[ - '令其受到1点无来源伤害', - '你随机获得其一张牌', - '你随机弃置其装备区的一张牌', - '令其摸一张牌', - ][['豹','鹰','熊','兔'].indexOf(zhoufa)]; - return str+'。'; + shoufa: function (player) { + const zhoufa = player.storage.zhoulin_zhoufa; + const nodoudizhu = get.mode() == "doudizhu" ? "与你距离大于/不大于1的" : "与你距离大于/不大于2的"; + if (!zhoufa) + return ( + "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名" + + nodoudizhu + + "角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。" + ); + let str = "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名" + nodoudizhu + "角色,"; + str += [ + "令其受到1点无来源伤害", + "你随机获得其一张牌", + "你随机弃置其装备区的一张牌", + "令其摸一张牌", + ][["豹", "鹰", "熊", "兔"].indexOf(zhoufa)]; + return str + "。"; }, - mbxuetu(player){ - const xuetu=player.storage.mbxuetu, status = player.countMark('mbxuetu_status'); + mbxuetu(player) { + const xuetu = player.storage.mbxuetu, + status = player.countMark("mbxuetu_status"); if (status === 0) { - if (!xuetu) return '转换技。出牌阶段限一次,阴:你可以弃置一张牌,然后令一名角色回复1点体力;阳:你可以失去1点体力,然后令一名角色摸两张牌。'; + if (!xuetu) + return '转换技。出牌阶段限一次,阴:你可以弃置一张牌,然后令一名角色回复1点体力;阳:你可以失去1点体力,然后令一名角色摸两张牌。'; return '转换技。出牌阶段限一次,阴:你可以弃置一张牌,然后令一名角色回复1点体力;阳:你可以失去1点体力,然后令一名角色摸两张牌。'; - } - else if (status === 1) { + } else if (status === 1) { return lib.translate.mbxuetu_achieve_info; - } - else { - if (!xuetu) return '转换技。出牌阶段限一次,阴:你可以回复1点体力,然后令一名角色弃置两张牌;阳:你可以摸一张牌,然后对一名角色造成1点伤害。'; + } else { + if (!xuetu) + return '转换技。出牌阶段限一次,阴:你可以回复1点体力,然后令一名角色弃置两张牌;阳:你可以摸一张牌,然后对一名角色造成1点伤害。'; return '转换技。出牌阶段限一次,阴:你可以回复1点体力,然后令一名角色弃置两张牌;阳:你可以摸一张牌,然后对一名角色造成1点伤害。'; } }, - mbzuoyou(player){ + mbzuoyou(player) { const mbzuoyou = player.storage.mbzuoyou; - if (mbzuoyou) return '转换技。出牌阶段限一次,阴:你可以令一名角色摸三张牌,然后其弃置两张牌;阳:你可以令一名角色弃置一张手牌,然后其获得1点护甲。' - return '转换技。出牌阶段限一次,阴:你可以令一名角色摸三张牌,然后其弃置两张牌;阳:你可以令一名角色弃置一张手牌,然后其获得1点护甲。' - } + if (mbzuoyou) + return '转换技。出牌阶段限一次,阴:你可以令一名角色摸三张牌,然后其弃置两张牌;阳:你可以令一名角色弃置一张手牌,然后其获得1点护甲。'; + return '转换技。出牌阶段限一次,阴:你可以令一名角色摸三张牌,然后其弃置两张牌;阳:你可以令一名角色弃置一张手牌,然后其获得1点护甲。'; + }, }, - perfectPair:{ - simazhao:['simayi','jin_simayi','jin_wangyuanji'], - xugong:['yanbaihu'], + perfectPair: { + simazhao: ["simayi", "jin_simayi", "jin_wangyuanji"], + xugong: ["yanbaihu"], }, - characterReplace:{ - caochun:['caochun','old_caochun'], - majun:['majun','old_majun'], - zhanggong:['zhanggong','re_zhanggong'], - baosanniang:['xin_baosanniang','re_baosanniang','baosanniang'], - heqi:['re_heqi','heqi'], - weiwenzhugezhi:['weiwenzhugezhi','re_weiwenzhugezhi','jsrg_weiwenzhugezhi'], - xugong:['xugong','re_xugong','jsrg_xugong'], - liuzan:['re_liuzan','liuzan'], - sufei:['yj_sufei','sp_sufei','xf_sufei'], - jiakui:['jiakui','old_jiakui'], - shenpei:['shenpei','sp_shenpei'], - sunru:['dc_sunru','sunru'], - liuye:['dc_liuye','liuye'], - zhaotongzhaoguang:['dc_zhaotongzhaoguang','zhaotongzhaoguang'], - yangbiao:['yangbiao','dc_yangbiao','jsrg_yangbiao'], - qiaozhou:['yj_qiaozhou','qiaozhou'], - sunhanhua:['dc_sunhanhua','sunhanhua'], - zhoubuyi:['zhoubuyi','yj_zhoubuyi'], + characterReplace: { + caochun: ["caochun", "old_caochun"], + majun: ["majun", "old_majun"], + zhanggong: ["zhanggong", "re_zhanggong"], + baosanniang: ["xin_baosanniang", "re_baosanniang", "baosanniang"], + heqi: ["re_heqi", "heqi"], + weiwenzhugezhi: ["weiwenzhugezhi", "re_weiwenzhugezhi", "jsrg_weiwenzhugezhi"], + xugong: ["xugong", "re_xugong", "jsrg_xugong"], + liuzan: ["re_liuzan", "liuzan"], + sufei: ["yj_sufei", "sp_sufei", "xf_sufei"], + jiakui: ["jiakui", "old_jiakui"], + shenpei: ["shenpei", "sp_shenpei"], + sunru: ["dc_sunru", "sunru"], + liuye: ["dc_liuye", "liuye"], + zhaotongzhaoguang: ["dc_zhaotongzhaoguang", "zhaotongzhaoguang"], + yangbiao: ["yangbiao", "dc_yangbiao", "jsrg_yangbiao"], + qiaozhou: ["yj_qiaozhou", "qiaozhou"], + sunhanhua: ["dc_sunhanhua", "sunhanhua"], + zhoubuyi: ["zhoubuyi", "yj_zhoubuyi"], }, - translate:{ - liuzan:'手杀留赞', - liuzan_prefix:'手杀', - re_sp_zhugeliang:'手杀界卧龙', - re_sp_zhugeliang_prefix:'手杀界', - ly_piliche:'霹雳车', - ly_piliche_info:'当你对其他角色造成伤害后,你可以弃置其装备区内的所有牌。', - polu:'破橹', - polu_info:'锁定技,回合开始时,若【霹雳车】未加入游戏或在牌堆/弃牌堆内,则你使用之;当你受到1点伤害后,若你的装备区里没有【霹雳车】,则你摸一张牌并使用牌堆中的一张随机武器牌。', - choulve:'筹略', - choulve_info:'出牌阶段开始时,你可以令一名其他角色交给你一张牌,若其如此做,视为你使用上一张对你过造成伤害且不为延时锦囊牌的牌。', - tunchu:'屯储', - tunchu_info:'摸牌阶段,若你没有「粮」,你可以多摸两张牌。若如此做,摸牌阶段结束时,你可以将任意张手牌置于你的武将上,称为「粮」,只要你的武将牌上有「粮」,你便不能使用【杀】。', - shuliang:'输粮', - shuliang_info:'一名角色的结束阶段开始时,若其手牌数少于体力值,你可以移去一张「粮」,然后该角色摸两张牌。', - fenyin:'奋音', - yingjian:'影箭', - fenyin_info:'你的回合内,当你使用牌时,若此牌与你于此回合内使用的上一张牌的颜色不同,则你可以摸一张牌。', - yingjian_info:'准备阶段开始时,你可以视为使用一张无距离限制的【杀】。', - dujin:'独进', - dujin_info:'摸牌阶段,你可以多摸X+1张牌(X为你装备区里牌数的一半且向上取整)。', - shixin:'释衅', - shixin_info:'锁定技,当你受到火属性伤害时,你防止此伤害。', - zhaohuo:'招祸', - zhaohuo_info:'锁定技,当其他角色进入濒死状态时,你将体力上限调整为1点。若你的体力上限因此减少,则你摸X张牌。(X为你以此法减少的体力上限)', - yixiang:'义襄', - yixiang_info:'每名角色的回合限一次,当你成为一名角色使用牌的目标后,若该角色的体力值大于你的体力值,你可以随机获得牌堆里的一张你没有的基本牌。', - yirang:'揖让', - yirang_info:'出牌阶段开始时,你可以将所有非基本牌交给一名体力上限大于你的其他角色,然后调整体力上限至与该角色相同并回复X点体力(X为你以此法交给其的牌的类别数)。', - kuangcai:'狂才', - kuangcai_info:'出牌阶段开始时,你可以令你此阶段内的主动出牌时间变为5秒。若如此做,你于此阶段内使用牌没距离和次数限制,且每当你于此阶段内使用牌时,你摸一张牌且主动出牌时间-1秒。若主动出牌时间减至0,则你结束出牌阶段。', - shejian:'舌剑', - shejian_info:'弃牌阶段结束时,若你于此阶段弃置的所有牌花色均不相同,则你可以弃置一名其他角色的一张牌。', - "xinfu_daigong":"怠攻", - "xinfu_daigong_info":"每回合限一次。当你受到伤害时,你可以展示所有手牌,然后令伤害来源选择一项:交给你一张与你所有手牌花色均不相同的一张牌,或防止此伤害。", - "xinfu_zhaoxin":"昭心", - "xinfu_zhaoxin_info":"出牌阶段限一次,你可以将任意张手牌置于武将牌上并摸等量的牌,称之为「望」(你至多拥有三张「望」)。你或你攻击范围内的一名其他角色的摸牌阶段结束后,其可以获得一张由你选择的「望」,然后你可以对其造成1点伤害。", - "zhaoxin_give":"昭心", - "zhaoxin_give_info":"", - "xinfu_qianchong":"谦冲", - "xinfu_qianchong_info":"锁定技,若你的装备区内有牌且:均为红色,则你视为拥有技能〖明哲〗。均为黑色,则你视为拥有技能〖帷幕〗。若均不满足,则出牌阶段开始时,你可以选择一种类别的牌,然后你本回合内使用该类别的牌时没有次数和距离限制。", - "qc_weimu":"帷幕", - "qc_weimu_info":"", - "qc_mingzhe":"明哲", - "qc_mingzhe_info":"", - "xinfu_shangjian":"尚俭", - "xinfu_shangjian_info":"锁定技。一名角色的结束阶段开始时,若你于此回合内不因使用装备牌而失去了X张或更少的牌,则你摸等量的牌(X为你的体力值)。", - "rw_bagua_skill":"先天八卦阵", - "rw_bagua_skill_info":"当你需要使用或打出一张【闪】时,你可以进行判定,若判定结果不为黑桃,视为你使用或打出了一张【闪】。", - "rw_baiyin_skill":"照月狮子盔", - "rw_baiyin_skill_info":"锁定技,当你受到大于1的伤害时,你将伤害值改为1;当你失去装备区里的【照月狮子盔】时,你回复1点体力并摸两张牌。", - "rw_lanyinjia":"精银甲", - "rw_lanyinjia_info":"你可以将一张手牌当做【闪】使用或打出。锁定技,【精银甲】不会无效。", - "rw_minguangkai_cancel":"耀光铠", - "rw_minguangkai_cancel_info":"锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", - "rw_minguangkai_link":"耀光铠", - "rw_minguangkai_link_info":"锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", - "rw_renwang_skill":"仁王金刚盾", - "rw_renwang_skill_info":"黑色【杀】和红桃【杀】对你无效。", - "rw_tengjia1":"桐油百韧甲", - "rw_tengjia1_info":"锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", - "rw_tengjia2":"桐油百韧甲", - "rw_tengjia2_info":"锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", - "rw_tengjia3":"桐油百韧甲", - "rw_tengjia3_info":"锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", - "rw_tengjia4":"桐油百韧甲", - "rewrite_bagua":"先天八卦阵", - "rewrite_bagua_info":"当你需要使用或打出一张【闪】时,你可以进行判定,若判定结果不为黑桃,视为你使用或打出了一张【闪】。", - "rewrite_baiyin":"照月狮子盔", - "rewrite_baiyin_info":"锁定技,当你受到大于1的伤害时,你将伤害值改为1;当你失去装备区里的【照月狮子盔】时,你回复1点体力并摸两张牌。", - "rewrite_lanyinjia":"精银甲", - "rewrite_lanyinjia_info":"你可以将一张手牌当做【闪】使用或打出。锁定技,【精银甲】不会无效。", - "rewrite_minguangkai":"耀光铠", - "rewrite_minguangkai_info":"锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", - "rewrite_renwang":"仁王金刚盾", - "rewrite_renwang_info":"黑色【杀】和红桃【杀】对你无效。", - "rewrite_tengjia":"桐油百韧甲", - "rewrite_tengjia_info":"锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", - "rewrite_zhuge":"元戎精械弩", - "rewrite_zhuge_info":"锁定技,你于出牌阶段内使用【杀】无次数限制。", - rw_zhuge_skill:'诸葛连弩', - rw_zhuge_skill_info:'锁定技,你于出牌阶段内使用【杀】无次数限制。', - takaramono:"宝物", - "wolong_card":"卧龙", - "wolong_card_info":"对一名角色造成1点火焰伤害。若场上有存活的诸葛亮(火),则改为对至多两名角色各造成1点火焰伤害。", - "fengchu_card":"凤雏", - "fengchu_card_info":"横置至多三名角色。若场上有存活的庞统(火),则改为横置至多四名角色。", - "xuanjian_card":"玄剑", - "xuanjian_card_info":"令一名角色摸一张牌并回复1点体力。若场上有存活的徐庶(将/界),则改为令一名角色摸一张牌并回复1点体力,然后你摸一张牌。", - "shuijing_card":"水镜", - "shuijing_card_info":"将一名角色装备区内的防具牌移动到另一名角色对应区域。若场上有存活的司马徽,则改为将1名角色装备区内的1件装备移动到另1角色对应区域。", - "xinfu_pingcai":"评才", - "xinfu_pingcai_info":"出牌阶段限一次,你可以挑选一个宝物并擦拭掉其上面的灰尘。然后,你可以根据宝物类型执行对应的效果。", - "xinfu_pdgyingshi":"隐世", - "xinfu_pdgyingshi2":"隐世", - "xinfu_pdgyingshi_info":"锁定技,你始终跳过准备阶段,判定阶段,结束阶段。你不能被选择为延时锦囊牌的目标。", - "pcaudio_wolong_card":"卧龙", - "pcaudio_wolong_card_info":"", - "pcaudio_fengchu_card":"凤雏", - "pcaudio_fengchu_card_info":"", - "pcaudio_shuijing_card":"水镜", - "pcaudio_shuijing_card_info":"", - "pcaudio_xuanjian_card":"玄剑", - "pcaudio_xuanjian_card_info":"", - "yizan_respond_sha":"翊赞", - "yizan_respond_sha_info":"", - "yizan_use":"翊赞", - yizan_use_backup:'翊赞', - "yizan_use_info":"你可以将两张牌(其中至少一张为基本牌)当做任意基本牌使用或打出。", - "yizan_respond_shan":"翊赞", - "yizan_respond_shan_info":"", - "xinfu_longyuan":"龙渊", - "xinfu_longyuan_info":"觉醒技,准备阶段,若你本局游戏内发动过〖翊赞〗的次数大于等于3,则你修改〖翊赞〗。", - yizan_rewrite:'翊赞·改', - yizan_rewrite_info:'你可以将一张基本牌当做任意基本牌使用或打出。', - "yizan_count":"翊赞", - "yizan_count_info":"", - "xinfu_jingxie1":"精械", - "xinfu_jingxie1_info":"出牌阶段,你可以展示一张未强化过的【诸葛连弩】或标准包/军争包/SP包中的防具牌,然后对其进行强化。当你处于濒死状态时,你可以重铸一张防具牌,然后将体力回复至1点。", - "xinfu_jingxie2":"精械", - "xinfu_jingxie2_info":"", - "xinfu_qiaosi":"巧思", - "xinfu_qiaosi_info":"出牌阶段限一次,你可以投掷一枚六面骰子,展示牌堆顶的X张牌并获得之。然后,你选择一项:1.交给一名其他角色X张牌。2.弃置X张牌。(X为骰子的点数)", - xin_xiahoudun:'手杀界夏侯惇', - xin_xiahoudun_prefix:'手杀界', - xinqingjian:'清俭', - xinqingjian2:'清俭', - xinqingjian_info:'每回合限一次。当你不因摸牌阶段的额定摸牌而得到牌后,你可以将任意张牌扣置于武将牌上。回合结束时,你将这些牌交给一名其他角色。若这些牌的数量大于1,你摸一张牌。', - zhangyì:'张翼', - jiakui:'贾逵', - zhiyi:'执义', - zhiyi_info:'锁定技,当你于一回合内使用或打出第一张基本牌时,你选择一项:1.摸一张牌。2.于此牌A(若此牌是因响应牌B而使用或打出的,则改为牌B)的使用或打出流程结算完成后,视为使用一张与此牌名称和属性相同的卡牌。', - rezhiyi:'执义', - rezhiyi_info:'锁定技,一名角色的结束阶段开始时,若你本回合内使用或打出过基本牌,则你选择一项:1.摸一张牌。2.视为使用一张本回合内使用或打出过的基本牌。', - zhongzuo:'忠佐', - zhongzuo_info:'一名角色的结束阶段开始时,若你于此回合内造成或受到过伤害,则你可以令一名角色摸两张牌。若该角色已受伤,则你摸一张牌。', - wanlan:'挽澜', - wanlan_info:'限定技,当一名角色进入濒死状态时,你可以弃置所有手牌(无牌可不弃)。其回复体力至1点,然后你对当前回合角色造成1点伤害。', - re_jikang:'手杀嵇康', - re_jikang_prefix:'手杀', - shenpei:'审配', - re_wangyun:'手杀王允', - re_wangyun_prefix:'手杀', - relianji:'连计', - relianji_info:'出牌阶段限一次,你可以选择两名其他角色。第一名角色随机使用牌堆中的一张武器牌,然后这名角色视为对另一名角色随机使用一张下列的牌名的牌:【决斗】、【火攻】、【南蛮入侵】、【万箭齐发】或普【杀】。然后若此牌造成伤害,你获得X枚“连计”标记(X为此次扣减的体力值点数)。', - remoucheng:'谋逞', - remoucheng_info:'觉醒技,当一名角色因〖连计〗造成伤害后,若你拥有的“连计”标记数大于2,你加1点体力上限,回复1点体力,失去“连计”,获得“矜功”。', + translate: { + liuzan: "手杀留赞", + liuzan_prefix: "手杀", + re_sp_zhugeliang: "手杀界卧龙", + re_sp_zhugeliang_prefix: "手杀界", + ly_piliche: "霹雳车", + ly_piliche_info: "当你对其他角色造成伤害后,你可以弃置其装备区内的所有牌。", + polu: "破橹", + polu_info: + "锁定技,回合开始时,若【霹雳车】未加入游戏或在牌堆/弃牌堆内,则你使用之;当你受到1点伤害后,若你的装备区里没有【霹雳车】,则你摸一张牌并使用牌堆中的一张随机武器牌。", + choulve: "筹略", + choulve_info: + "出牌阶段开始时,你可以令一名其他角色交给你一张牌,若其如此做,视为你使用上一张对你过造成伤害且不为延时锦囊牌的牌。", + tunchu: "屯储", + tunchu_info: + "摸牌阶段,若你没有「粮」,你可以多摸两张牌。若如此做,摸牌阶段结束时,你可以将任意张手牌置于你的武将上,称为「粮」,只要你的武将牌上有「粮」,你便不能使用【杀】。", + shuliang: "输粮", + shuliang_info: + "一名角色的结束阶段开始时,若其手牌数少于体力值,你可以移去一张「粮」,然后该角色摸两张牌。", + fenyin: "奋音", + yingjian: "影箭", + fenyin_info: + "你的回合内,当你使用牌时,若此牌与你于此回合内使用的上一张牌的颜色不同,则你可以摸一张牌。", + yingjian_info: "准备阶段开始时,你可以视为使用一张无距离限制的【杀】。", + dujin: "独进", + dujin_info: "摸牌阶段,你可以多摸X+1张牌(X为你装备区里牌数的一半且向上取整)。", + shixin: "释衅", + shixin_info: "锁定技,当你受到火属性伤害时,你防止此伤害。", + zhaohuo: "招祸", + zhaohuo_info: + "锁定技,当其他角色进入濒死状态时,你将体力上限调整为1点。若你的体力上限因此减少,则你摸X张牌。(X为你以此法减少的体力上限)", + yixiang: "义襄", + yixiang_info: + "每名角色的回合限一次,当你成为一名角色使用牌的目标后,若该角色的体力值大于你的体力值,你可以随机获得牌堆里的一张你没有的基本牌。", + yirang: "揖让", + yirang_info: + "出牌阶段开始时,你可以将所有非基本牌交给一名体力上限大于你的其他角色,然后调整体力上限至与该角色相同并回复X点体力(X为你以此法交给其的牌的类别数)。", + kuangcai: "狂才", + kuangcai_info: + "出牌阶段开始时,你可以令你此阶段内的主动出牌时间变为5秒。若如此做,你于此阶段内使用牌没距离和次数限制,且每当你于此阶段内使用牌时,你摸一张牌且主动出牌时间-1秒。若主动出牌时间减至0,则你结束出牌阶段。", + shejian: "舌剑", + shejian_info: + "弃牌阶段结束时,若你于此阶段弃置的所有牌花色均不相同,则你可以弃置一名其他角色的一张牌。", + xinfu_daigong: "怠攻", + xinfu_daigong_info: + "每回合限一次。当你受到伤害时,你可以展示所有手牌,然后令伤害来源选择一项:交给你一张与你所有手牌花色均不相同的一张牌,或防止此伤害。", + xinfu_zhaoxin: "昭心", + xinfu_zhaoxin_info: + "出牌阶段限一次,你可以将任意张手牌置于武将牌上并摸等量的牌,称之为「望」(你至多拥有三张「望」)。你或你攻击范围内的一名其他角色的摸牌阶段结束后,其可以获得一张由你选择的「望」,然后你可以对其造成1点伤害。", + zhaoxin_give: "昭心", + zhaoxin_give_info: "", + xinfu_qianchong: "谦冲", + xinfu_qianchong_info: + "锁定技,若你的装备区内有牌且:均为红色,则你视为拥有技能〖明哲〗。均为黑色,则你视为拥有技能〖帷幕〗。若均不满足,则出牌阶段开始时,你可以选择一种类别的牌,然后你本回合内使用该类别的牌时没有次数和距离限制。", + qc_weimu: "帷幕", + qc_weimu_info: "", + qc_mingzhe: "明哲", + qc_mingzhe_info: "", + xinfu_shangjian: "尚俭", + xinfu_shangjian_info: + "锁定技。一名角色的结束阶段开始时,若你于此回合内不因使用装备牌而失去了X张或更少的牌,则你摸等量的牌(X为你的体力值)。", + rw_bagua_skill: "先天八卦阵", + rw_bagua_skill_info: + "当你需要使用或打出一张【闪】时,你可以进行判定,若判定结果不为黑桃,视为你使用或打出了一张【闪】。", + rw_baiyin_skill: "照月狮子盔", + rw_baiyin_skill_info: + "锁定技,当你受到大于1的伤害时,你将伤害值改为1;当你失去装备区里的【照月狮子盔】时,你回复1点体力并摸两张牌。", + rw_lanyinjia: "精银甲", + rw_lanyinjia_info: "你可以将一张手牌当做【闪】使用或打出。锁定技,【精银甲】不会无效。", + rw_minguangkai_cancel: "耀光铠", + rw_minguangkai_cancel_info: + "锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", + rw_minguangkai_link: "耀光铠", + rw_minguangkai_link_info: + "锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", + rw_renwang_skill: "仁王金刚盾", + rw_renwang_skill_info: "黑色【杀】和红桃【杀】对你无效。", + rw_tengjia1: "桐油百韧甲", + rw_tengjia1_info: + "锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", + rw_tengjia2: "桐油百韧甲", + rw_tengjia2_info: + "锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", + rw_tengjia3: "桐油百韧甲", + rw_tengjia3_info: + "锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", + rw_tengjia4: "桐油百韧甲", + rewrite_bagua: "先天八卦阵", + rewrite_bagua_info: + "当你需要使用或打出一张【闪】时,你可以进行判定,若判定结果不为黑桃,视为你使用或打出了一张【闪】。", + rewrite_baiyin: "照月狮子盔", + rewrite_baiyin_info: + "锁定技,当你受到大于1的伤害时,你将伤害值改为1;当你失去装备区里的【照月狮子盔】时,你回复1点体力并摸两张牌。", + rewrite_lanyinjia: "精银甲", + rewrite_lanyinjia_info: "你可以将一张手牌当做【闪】使用或打出。锁定技,【精银甲】不会无效。", + rewrite_minguangkai: "耀光铠", + rewrite_minguangkai_info: + "锁定技,当你成为【火烧连营】、【火攻】或火【杀】的目标时,或即将被横置时,取消之。", + rewrite_renwang: "仁王金刚盾", + rewrite_renwang_info: "黑色【杀】和红桃【杀】对你无效。", + rewrite_tengjia: "桐油百韧甲", + rewrite_tengjia_info: + "锁定技,【南蛮入侵】、【万箭齐发】和普【杀】对你无效。当你受到火焰伤害时,此伤害+1。当你即将被横置时,取消之。", + rewrite_zhuge: "元戎精械弩", + rewrite_zhuge_info: "锁定技,你于出牌阶段内使用【杀】无次数限制。", + rw_zhuge_skill: "诸葛连弩", + rw_zhuge_skill_info: "锁定技,你于出牌阶段内使用【杀】无次数限制。", + takaramono: "宝物", + wolong_card: "卧龙", + wolong_card_info: + "对一名角色造成1点火焰伤害。若场上有存活的诸葛亮(火),则改为对至多两名角色各造成1点火焰伤害。", + fengchu_card: "凤雏", + fengchu_card_info: "横置至多三名角色。若场上有存活的庞统(火),则改为横置至多四名角色。", + xuanjian_card: "玄剑", + xuanjian_card_info: + "令一名角色摸一张牌并回复1点体力。若场上有存活的徐庶(将/界),则改为令一名角色摸一张牌并回复1点体力,然后你摸一张牌。", + shuijing_card: "水镜", + shuijing_card_info: + "将一名角色装备区内的防具牌移动到另一名角色对应区域。若场上有存活的司马徽,则改为将1名角色装备区内的1件装备移动到另1角色对应区域。", + xinfu_pingcai: "评才", + xinfu_pingcai_info: + "出牌阶段限一次,你可以挑选一个宝物并擦拭掉其上面的灰尘。然后,你可以根据宝物类型执行对应的效果。", + xinfu_pdgyingshi: "隐世", + xinfu_pdgyingshi2: "隐世", + xinfu_pdgyingshi_info: + "锁定技,你始终跳过准备阶段,判定阶段,结束阶段。你不能被选择为延时锦囊牌的目标。", + pcaudio_wolong_card: "卧龙", + pcaudio_wolong_card_info: "", + pcaudio_fengchu_card: "凤雏", + pcaudio_fengchu_card_info: "", + pcaudio_shuijing_card: "水镜", + pcaudio_shuijing_card_info: "", + pcaudio_xuanjian_card: "玄剑", + pcaudio_xuanjian_card_info: "", + yizan_respond_sha: "翊赞", + yizan_respond_sha_info: "", + yizan_use: "翊赞", + yizan_use_backup: "翊赞", + yizan_use_info: "你可以将两张牌(其中至少一张为基本牌)当做任意基本牌使用或打出。", + yizan_respond_shan: "翊赞", + yizan_respond_shan_info: "", + xinfu_longyuan: "龙渊", + xinfu_longyuan_info: + "觉醒技,准备阶段,若你本局游戏内发动过〖翊赞〗的次数大于等于3,则你修改〖翊赞〗。", + yizan_rewrite: "翊赞·改", + yizan_rewrite_info: "你可以将一张基本牌当做任意基本牌使用或打出。", + yizan_count: "翊赞", + yizan_count_info: "", + xinfu_jingxie1: "精械", + xinfu_jingxie1_info: + "出牌阶段,你可以展示一张未强化过的【诸葛连弩】或标准包/军争包/SP包中的防具牌,然后对其进行强化。当你处于濒死状态时,你可以重铸一张防具牌,然后将体力回复至1点。", + xinfu_jingxie2: "精械", + xinfu_jingxie2_info: "", + xinfu_qiaosi: "巧思", + xinfu_qiaosi_info: + "出牌阶段限一次,你可以投掷一枚六面骰子,亮出牌堆顶的X张牌并获得之。然后,你选择一项:1.交给一名其他角色X张牌。2.弃置X张牌。(X为骰子的点数)", + xin_xiahoudun: "手杀界夏侯惇", + xin_xiahoudun_prefix: "手杀界", + xinqingjian: "清俭", + xinqingjian2: "清俭", + xinqingjian_info: + "每回合限一次。当你不因摸牌阶段的额定摸牌而得到牌后,你可以将任意张牌扣置于武将牌上。回合结束时,你将这些牌交给一名其他角色。若这些牌的数量大于1,你摸一张牌。", + zhangyì: "张翼", + jiakui: "贾逵", + zhiyi: "执义", + zhiyi_info: + "锁定技,当你于一回合内使用或打出第一张基本牌时,你选择一项:1.摸一张牌。2.于此牌A(若此牌是因响应牌B而使用或打出的,则改为牌B)的使用或打出流程结算完成后,视为使用一张与此牌名称和属性相同的卡牌。", + rezhiyi: "执义", + rezhiyi_info: + "锁定技,一名角色的结束阶段开始时,若你本回合内使用或打出过基本牌,则你选择一项:1.摸一张牌。2.视为使用一张你本回合内使用或打出过的基本牌。", + zhongzuo: "忠佐", + zhongzuo_info: + "一名角色的结束阶段开始时,若你于此回合内造成或受到过伤害,则你可以令一名角色摸两张牌。若该角色已受伤,则你摸一张牌。", + wanlan: "挽澜", + wanlan_info: + "限定技,当一名角色进入濒死状态时,你可以弃置所有手牌(无牌可不弃)。其回复体力至1点,然后你对当前回合角色造成1点伤害。", + re_jikang: "手杀嵇康", + re_jikang_prefix: "手杀", + shenpei: "审配", + re_wangyun: "手杀王允", + re_wangyun_prefix: "手杀", + relianji: "连计", + relianji_info: + "出牌阶段限一次,你可以选择两名其他角色。第一名角色随机使用牌堆中的一张武器牌,然后这名角色视为对另一名角色随机使用一张下列的牌名的牌:【决斗】、【火攻】、【南蛮入侵】、【万箭齐发】或普【杀】。然后若此牌造成伤害,你获得X枚“连计”标记(X为此次扣减的体力值点数)。", + remoucheng: "谋逞", + remoucheng_info: + "觉醒技,当一名角色因〖连计〗造成伤害后,若你拥有的“连计”标记数大于2,你加1点体力上限,回复1点体力,失去“连计”,获得“矜功”。", - shouye:'守邺', - shouye_info:'每回合限一次。当其他角色使用牌指定你为唯一目标时,你可以与其进行【对策】。若你赢,则你取消此牌的目标,且你于此牌结算完成后获得其对应的所有实体牌。', - liezhi:'烈直', - liezhi_info:'准备阶段,你可以依次弃置至多两名其他角色区域内的各一张牌。若你受到过伤害,则〖烈直〗于你的下个回合无效。', + shouye: "守邺", + shouye_info: + "每回合限一次。当其他角色使用牌指定你为唯一目标时,你可以与其进行【对策】。若你赢,则你取消此牌的目标,且你于此牌结算完成后获得其对应的所有实体牌。", + liezhi: "烈直", + liezhi_info: + "准备阶段,你可以依次弃置至多两名其他角色区域内的各一张牌。若你受到过伤害,则〖烈直〗于你的下个回合无效。", - xinzhanyi:'战意', - xinzhanyi_info:'出牌阶段限一次,你可以弃置一张牌并失去1点体力,然后根据你弃置的牌获得以下效果直到回合结束:基本牌,你可以将一张基本牌当作杀、酒或桃使用,且你本回合第一次以此法使用的牌的回复值/伤害值+1;锦囊牌,摸三张牌且你使用的牌不能被【无懈可击】响应;装备牌,你使用【杀】指定唯一目标后,其弃置两张牌,然后你获得其中的一张。', - xinzhanyi_basic_backup:'战意', - xinzhanyi_basic:'战意', - xinzhanyi_equip:'战意', + xinzhanyi: "战意", + xinzhanyi_info: + "出牌阶段限一次,你可以弃置一张牌并失去1点体力,然后根据你弃置的牌获得以下效果直到回合结束:基本牌,你可以将一张基本牌当作杀、酒或桃使用,且你本回合第一次以此法使用的牌的回复值/伤害值+1;锦囊牌,摸三张牌且你使用的牌不能被【无懈可击】响应;装备牌,你使用【杀】指定唯一目标后,其弃置两张牌,然后你获得其中的一张。", + xinzhanyi_basic_backup: "战意", + xinzhanyi_basic: "战意", + xinzhanyi_equip: "战意", - meiyong:'姝勇', - meiyong_info:'当你使用或打出【杀】时,你可以获得一名其他角色的一张牌,然后其摸一张牌。', - rexushen:'许身', - rexushen_info:'限定技,出牌阶段,你可以失去X点体力(X为场上男性角色的数量)。若你以此法进入了濒死状态,则当你因一名角色而脱离此濒死状态后,你可以令其获得技能〖武圣〗和〖当先〗。', - rezhennan:'镇南', - rezhennan_info:'当你成为其他角色使用的牌的目标后,若此牌的目标数大于该角色的体力值,则你可以弃置一张牌并对其造成1点伤害。', + meiyong: "姝勇", + meiyong_info: "当你使用或打出【杀】时,你可以获得一名其他角色的一张牌,然后其摸一张牌。", + rexushen: "许身", + rexushen_info: + "限定技,出牌阶段,你可以失去X点体力(X为场上男性角色的数量)。若你以此法进入了濒死状态,则当你因一名角色而脱离此濒死状态后,你可以令其获得技能〖武圣〗和〖当先〗。", + rezhennan: "镇南", + rezhennan_info: + "当你成为其他角色使用的牌的目标后,若此牌的目标数大于该角色的体力值,则你可以弃置一张牌并对其造成1点伤害。", - hujinding:'手杀胡金定', - hujinding_prefix:'手杀', - huaizi:'怀子', - huaizi_info:'锁定技,你的手牌上限为你的体力上限。', - renshi:'仁释', - renshi_info:'锁定技,当你受到【杀】的伤害时,若你已受伤,则你防止此伤害并获得此【杀】对应的所有实体牌,然后减1点体力上限。', - wuyuan:'武缘', - wuyuan_info:'出牌阶段限一次,你可将一张【杀】交给一名其他角色,然后你回复1点体力,其摸一张牌。若此【杀】为:红色【杀】,其回复1点体力;属性【杀】,其改为摸两张牌。', + hujinding: "手杀胡金定", + hujinding_prefix: "手杀", + huaizi: "怀子", + huaizi_info: "锁定技,你的手牌上限为你的体力上限。", + renshi: "仁释", + renshi_info: + "锁定技,当你受到【杀】的伤害时,若你已受伤,则你防止此伤害并获得此【杀】对应的所有实体牌,然后减1点体力上限。", + wuyuan: "武缘", + wuyuan_info: + "出牌阶段限一次,你可将一张【杀】交给一名其他角色,然后你回复1点体力,其摸一张牌。若此【杀】为:红色【杀】,其回复1点体力;属性【杀】,其改为摸两张牌。", - re_weiwenzhugezhi:'手杀卫温诸葛直', - re_weiwenzhugezhi_prefix:'手杀', - gz_re_xugong:'许贡', - re_xugong:'手杀许贡', - re_xugong_prefix:'手杀', - re_zhanggong:'手杀张恭', - re_zhanggong_prefix:'手杀', - reqianxin:'遣信', - reqianxin_info:'出牌阶段限一次,你可将至多两张手牌随机交给等量的其他角色,称为「信」。这些角色的准备阶段开始时,若其手牌中有「信」,则其选择一项:令你摸两张牌,本回合手牌上限-2。', - rebiaozhao:"表召", - "rebiaozhao_info":"结束阶段,你可以将一张牌置于武将牌上,称为「表」。当有一张与「表」点数相同的牌进入弃牌堆后,你将「表」置入弃牌堆并失去1点体力。准备阶段,若你的武将牌上有「表」,则你移去「表」并选择一名角色,该角色回复1点体力并摸三张牌。", - "rebiaozhao2":"表召", - "rebiaozhao2_info":"", - "rebiaozhao3":"表召", - "rebiaozhao3_info":"", - refuhai:'浮海', - refuhai_info:'出牌阶段限一次,你可令其他角色同时在「潮起」和「潮落」中选择一项,并依次展示这些角色的选项。若从你下家开始选择了相同选项的角色数目大于1,则你摸X张牌(X为连续相同结果的数量)。', - qiaosi:'巧思', - qiaosi_info:'出牌阶段限一次,你可以表演「大键角色图」并根据表演结果获得相应的牌。然后,你选择一项:1.弃置X张牌。2.将X张牌交给一名其他角色。(X为你以此法得到的牌数)', - qiaosi_map:'大键角色图', - qiaosi_map_info:'
            • 星野 梦美:锦囊牌*2
            • 能美 库特莉亚芙卡:装备牌/【杀】/【酒】*1
            • 友利 奈绪:【杀】/【酒】*1
            • 神尾 观铃:【闪】/【桃】*1
            • 伊吹 风子:锦囊牌/【闪】/【桃】*1
            • 仲村 由理:装备牌*2
            • Illustration:うら;Twitter:@ura530', - qiaosi_c1:' ', + re_weiwenzhugezhi: "手杀卫温诸葛直", + re_weiwenzhugezhi_prefix: "手杀", + gz_re_xugong: "许贡", + re_xugong: "手杀许贡", + re_xugong_prefix: "手杀", + re_zhanggong: "手杀张恭", + re_zhanggong_prefix: "手杀", + reqianxin: "遣信", + reqianxin_info: + "出牌阶段限一次,你可将至多两张手牌随机交给等量的其他角色,称为「信」。这些角色的准备阶段开始时,若其手牌中有「信」,则其选择一项:令你摸两张牌,本回合手牌上限-2。", + rebiaozhao: "表召", + rebiaozhao_info: + "结束阶段,你可以将一张牌置于武将牌上,称为「表」。当有一张与「表」点数相同的牌进入弃牌堆后,你将「表」置入弃牌堆并失去1点体力。准备阶段,若你的武将牌上有「表」,则你移去「表」并选择一名角色,该角色回复1点体力并摸三张牌。", + rebiaozhao2: "表召", + rebiaozhao2_info: "", + rebiaozhao3: "表召", + rebiaozhao3_info: "", + refuhai: "浮海", + refuhai_info: + "出牌阶段限一次,你可令其他角色同时在「潮起」和「潮落」中选择一项,并依次展示这些角色的选项。若从你下家开始选择了相同选项的角色数目大于1,则你摸X张牌(X为连续相同结果的数量)。", + qiaosi: "巧思", + qiaosi_info: + "出牌阶段限一次,你可以表演「大键角色图」并根据表演结果获得相应的牌。然后,你选择一项:1.弃置X张牌。2.将X张牌交给一名其他角色。(X为你以此法得到的牌数)", + qiaosi_map: "大键角色图", + qiaosi_map_info: + "
            • 星野 梦美:锦囊牌*2
            • 能美 库特莉亚芙卡:装备牌/【杀】/【酒】*1
            • 友利 奈绪:【杀】/【酒】*1
            • 神尾 观铃:【闪】/【桃】*1
            • 伊吹 风子:锦囊牌/【闪】/【桃】*1
            • 仲村 由理:装备牌*2
            • Illustration:うら;Twitter:@ura530", + qiaosi_c1: ' ', //星野 梦美 - qiaosi_c2:' ', + qiaosi_c2: ' ', //能美 库特莉亚芙卡 - qiaosi_c3:' ', + qiaosi_c3: ' ', //友利 奈绪 - qiaosi_c4:' ', + qiaosi_c4: ' ', //神尾 观铃 - qiaosi_c5:' ', + qiaosi_c5: ' ', //伊吹 风子 - qiaosi_c6:' ', + qiaosi_c6: ' ', //仲村 由理 - yangbiao:'手杀杨彪', - yangbiao_prefix:'手杀', - zhaohan:'昭汉', - zhaohan_info:'锁定技,你的第1-4个准备阶段开始时,你加1点体力上限并回复1点体力,你的第5-7个准备阶段开始时,你减1点体力上限。', - rangjie:'让节', - rangjie_info:'当你受到1点伤害后,你可以选择一项并摸一张牌:获得牌堆里你选择的类型的一张牌,或移动场上的一张牌。', - yizheng:'义争', - yizheng2:'义争', - yizheng_info:'出牌阶段限一次,你可以和一名体力值不大于你的其他角色拼点。若你赢,其跳过下个摸牌阶段。若你没赢,你减1点体力上限。', - re_heqi:'手杀贺齐', - re_heqi_prefix:'手杀', - reqizhou:'绮胄', - reqizhou_info:'锁定技,你根据装备区里牌的花色数获得以下技能:1种或以上:〖英姿〗;2种或以上:〖奇袭〗;3种或以上:〖旋风〗。', - reshanxi:'闪袭', - reshanxi2:'闪袭', - reshanxi_info:'出牌阶段开始时,你可以弃置一张红色基本牌并选择一名有牌的其他角色,将其的至多X张牌置于其的武将牌上(X为你的体力值)。回合结束时,该角色获得这些牌。', - chendeng:'手杀陈登', - chendeng_prefix:'手杀', - zhouxuan:'周旋', - zhouxuan2:'周旋', - zhouxuan_info:'出牌阶段限一次,你可以弃置一张牌并指定一名角色,然后选择一个基本牌的名称或非基本牌的类型。其使用或打出下一张牌时,若此牌的名称或类型和你选择的相同,则你观看牌堆顶的三张牌,然后将这些牌以任意分割方式交给任意名角色。', - fengji:'丰积', - fengji_info:'锁定技,回合结束时,你记录你的手牌数。准备阶段开始时,若你的手牌数不小于你记录的手牌数,则你摸两张牌且本回合手牌上限为体力上限。', - re_guanqiujian:'手杀毌丘俭', - re_guanqiujian_prefix:'手杀', - rezhengrong:'征荣', - rehongju:'鸿举', - reqingce:'清侧', - reqingce_backup:'清侧', - rezhengrong_info:'当你于出牌阶段使用的指定了其他角色为目标的牌结算完成后,若此牌是你本局游戏内于出牌阶段使用的指定了其他角色为目标的第偶数张牌,则你可以将一名其他角色角色的随机一张牌置于你的武将牌上,称为「荣」。', - rehongju_info:'觉醒技,准备阶段,若你武将牌上「荣」的数量不小于3且有角色死亡,则你摸等同于「荣」数量的牌。然后可以用任意数量的手牌交换等量的「荣」。你减1点体力上限并获得技能〖清侧〗。', - reqingce_info:'出牌阶段,你可以将一张「荣」置入弃牌堆,然后弃置场上的一张牌。', - re_pangtong:'手杀界庞统', - re_pangtong_prefix:'手杀界', - dongcheng:'手杀董承', - dongcheng_prefix:'手杀', - chengzhao:'承诏', - chengzhao_info:'一名角色的结束阶段,若你于本回合内获得了两张以上的牌,则你可以与一名其他角色拼点。若你赢,你视为对其使用一张无视防具的【杀】。', - yangyi:'手杀杨仪', - yangyi_prefix:'手杀', - duoduan:'度断', - duoduan_info:'每回合限一次,当你成为【杀】的目标后,你可以重铸一张牌。若如此做,你选择一项:①令使用者摸两张牌,且此【杀】无效。②令使用弃置一张牌,且你不能响应此【杀】。', - gongsun:'共损', - gongsun_info:'出牌阶段开始时,你可以弃置两张牌并指定一名其他角色。你选择一个基本牌或普通锦囊牌的牌名。直到你的下回合开始或你死亡,你与其不能使用或打出或弃置此名称的牌。', - gongsun_shadow:'共损', - xin_chengpu:'手杀界程普', - xin_chengpu_prefix:'手杀界', - relihuo:'疠火', - relihuo_damage:'疠火', - relihuo_baigei:'疠火', - relihuo_info:'当你使用普【杀】时,你可以将此杀改为火属性。若如此做,当你因执行此【杀】的效果而对横置角色造成伤害时,此伤害+1;当你使用的火【杀】结算完成后,你失去X点体力(X为你因此【杀】造成的伤害总点数的一半且向下取整)。', - dengzhi:'手杀邓芝', - dengzhi_prefix:'手杀', - jimeng:'急盟', - jimeng_info:'出牌阶段开始时,你可以获得一名其他角色的一张牌,然后交给该角色X张牌(X为你当前体力值)。', - shuaiyan:'率言', - shuaiyan_info:'弃牌阶段开始时,若你的手牌数大于1,则你可以展示所有手牌,然后你令一名其他角色交给你一张牌。', - zhengxuan:'郑玄', - zhengjing:'整经', - zhengjing_info:'出牌阶段,你可以整理卡牌。然后,你将整理出的卡牌中的至少一张作为“经”置于一名角色的武将牌上,然后获得其余的牌。该角色的准备阶段获得这些牌,且跳过此回合的判定和摸牌阶段。', - zhengjing2:'整经', + yangbiao: "手杀杨彪", + yangbiao_prefix: "手杀", + zhaohan: "昭汉", + zhaohan_info: + "锁定技,你的第1-4个准备阶段开始时,你加1点体力上限并回复1点体力,你的第5-7个准备阶段开始时,你减1点体力上限。", + rangjie: "让节", + rangjie_info: + "当你受到1点伤害后,你可以选择一项并摸一张牌:获得牌堆里你选择的类型的一张牌,或移动场上的一张牌。", + yizheng: "义争", + yizheng2: "义争", + yizheng_info: + "出牌阶段限一次,你可以和一名体力值不大于你的其他角色拼点。若你赢,其跳过下个摸牌阶段。若你没赢,你减1点体力上限。", + re_heqi: "手杀贺齐", + re_heqi_prefix: "手杀", + reqizhou: "绮胄", + reqizhou_info: + "锁定技,你根据装备区里牌的花色数获得以下技能:1种或以上:〖英姿〗;2种或以上:〖奇袭〗;3种或以上:〖旋风〗。", + reshanxi: "闪袭", + reshanxi2: "闪袭", + reshanxi_info: + "出牌阶段开始时,你可以弃置一张红色基本牌并选择一名有牌的其他角色,将其的至多X张牌置于其的武将牌上(X为你的体力值)。回合结束时,该角色获得这些牌。", + chendeng: "手杀陈登", + chendeng_prefix: "手杀", + zhouxuan: "周旋", + zhouxuan2: "周旋", + zhouxuan_info: + "出牌阶段限一次,你可以弃置一张牌并指定一名角色,然后选择一个基本牌的名称或非基本牌的类型。其使用或打出下一张牌时,若此牌的名称或类型和你选择的相同,则你观看牌堆顶的三张牌,然后将这些牌以任意分割方式交给任意名角色。", + fengji: "丰积", + fengji_info: + "锁定技,回合结束时,你记录你的手牌数。准备阶段开始时,若你的手牌数不小于你记录的手牌数,则你摸两张牌且本回合手牌上限为体力上限。", + re_guanqiujian: "手杀毌丘俭", + re_guanqiujian_prefix: "手杀", + rezhengrong: "征荣", + rehongju: "鸿举", + reqingce: "清侧", + reqingce_backup: "清侧", + rezhengrong_info: + "当你于出牌阶段使用的指定了其他角色为目标的牌结算完成后,若此牌是你本局游戏内于出牌阶段使用的指定了其他角色为目标的第偶数张牌,则你可以将一名其他角色角色的随机一张牌置于你的武将牌上,称为「荣」。", + rehongju_info: + "觉醒技,准备阶段,若你武将牌上「荣」的数量不小于3且有角色死亡,则你摸等同于「荣」数量的牌。然后可以用任意数量的手牌交换等量的「荣」。你减1点体力上限并获得技能〖清侧〗。", + reqingce_info: "出牌阶段,你可以将一张「荣」置入弃牌堆,然后弃置场上的一张牌。", + re_pangtong: "手杀界庞统", + re_pangtong_prefix: "手杀界", + dongcheng: "手杀董承", + dongcheng_prefix: "手杀", + chengzhao: "承诏", + chengzhao_info: + "一名角色的结束阶段,若你于本回合内获得了两张以上的牌,则你可以与一名其他角色拼点。若你赢,你视为对其使用一张无视防具的【杀】。", + yangyi: "手杀杨仪", + yangyi_prefix: "手杀", + duoduan: "度断", + duoduan_info: + "每回合限一次,当你成为【杀】的目标后,你可以重铸一张牌。若如此做,你选择一项:①令使用者摸两张牌,且此【杀】无效。②令使用弃置一张牌,且你不能响应此【杀】。", + gongsun: "共损", + gongsun_info: + "出牌阶段开始时,你可以弃置两张牌并指定一名其他角色。你选择一个基本牌或普通锦囊牌的牌名。直到你的下回合开始或你死亡,你与其不能使用或打出或弃置此名称的牌。", + gongsun_shadow: "共损", + xin_chengpu: "手杀界程普", + xin_chengpu_prefix: "手杀界", + relihuo: "疠火", + relihuo_damage: "疠火", + relihuo_baigei: "疠火", + relihuo_info: + "当你使用普【杀】时,你可以将此杀改为火属性。若如此做,当你因执行此【杀】的效果而对横置角色造成伤害时,此伤害+1;当你使用的火【杀】结算完成后,你失去X点体力(X为你因此【杀】造成的伤害总点数的一半且向下取整)。", + dengzhi: "手杀邓芝", + dengzhi_prefix: "手杀", + jimeng: "急盟", + jimeng_info: + "出牌阶段开始时,你可以获得一名其他角色的一张牌,然后交给该角色X张牌(X为你当前体力值)。", + shuaiyan: "率言", + shuaiyan_info: + "弃牌阶段开始时,若你的手牌数大于1,则你可以展示所有手牌,然后你令一名其他角色交给你一张牌。", + zhengxuan: "郑玄", + zhengjing: "整经", + zhengjing_info: + "出牌阶段,你可以整理卡牌。然后,你将整理出的卡牌中的至少一张作为“经”置于一名角色的武将牌上,然后获得其余的牌。该角色的准备阶段获得这些牌,且跳过此回合的判定和摸牌阶段。", + zhengjing2: "整经", - mobile_yijiang:'将星独具', - yj_zhanghe:'☆张郃', - yj_zhanghe_prefix:'☆', - yj_zhangliao:'☆张辽', - yj_zhangliao_prefix:'☆', - yj_xuhuang:'☆徐晃', - yj_xuhuang_prefix:'☆', - yj_ganning:'☆甘宁', - yj_ganning_prefix:'☆', - xhzhiyan:'治严', - xhzhiyan_info:'出牌阶段,若你的手牌数不等于体力上限,则你可以将手牌摸至/弃至手牌上限,然后本回合不能对其他角色使用牌/可以将弃置的一张牌交给一名其他角色。', - zhilve:'知略', - zhilve_info:'锁定技,准备阶段,你选择一项:1.移动场上装备区的一张牌并失去1点体力。2.移动场上判定区的一张牌并令本回合手牌上限-1。3.本回合摸牌阶段多摸一张牌且使用的第一张【杀】无距离限制且不计入次数限制。', - xinzhilve:'知略', - xinzhilve_backup:'知略', - xinzhilve_mark:'知略', - xinzhilve_info:'出牌阶段限一次,你可以失去1点体力并选择一项:1.移动场上的一张牌;2.视为使用一张无距离限制且不计入次数限制的【杀】并摸一张牌。然后你本回合的手牌上限+1。', - xinxhzhiyan:'治严', - xinxhzhiyan_false:'治严', - xinxhzhiyan_info:'出牌阶段每项各限一次,若你的手牌数:大于体力值,则你可以将X张手牌交给一名其他角色(X为你的手牌数与体力值之差);小于体力上限,则你可以摸X张牌且本阶段内不能再对其他角色使用牌。(X为你的手牌数与体力上限之差)', - weifeng:'威风', - weifeng2:'威风', - weifeng3:'威风', - weifeng_info:'锁定技,当你于出牌阶段内使用第一张伤害性基本牌或普通锦囊牌后,你令此牌的一名没有“惧”的其他目标角色获得一枚名称为此牌牌名的“惧”。有“惧”的角色受到伤害时,其移去“惧”,然后若造成伤害的牌名称和“惧”:相同,此伤害+1;不同,你获得该角色的一张牌。准备阶段开始时或你死亡时,你移去场上的所有“惧”。', - gnjinfan:'锦帆', - gnjinfan_gain:'锦帆', - gnjinfan_info:'弃牌阶段开始时,你可将任意张手牌置于武将牌上,称为“铃”(每种花色的“铃”限一张)。你可以如手牌般使用或打出“铃”。当有“铃”移动到处理区后,你从牌堆中获得与“铃”花色相同的一张牌。', - gnsheque:'射却', - gnsheque_info:'一名其他角色的准备阶段开始时,若其装备区内有牌,则你可以对其使用一张【杀】(无距离关系的限制且无视防具)。', - sp_sufei:'手杀苏飞', - sp_sufei_prefix:'手杀', - zhengjian:'诤荐', - zhengjian_draw:'诤荐', - zhengjian_mark:'诤荐', - zhengjian_info:'锁定技,结束阶段,你令一名角色获得一枚“诤”。回合开始时,你令有“诤”的角色移去“诤”并摸X张牌(X为其最后一次获得“诤”后使用和打出的牌数,且至多不能超过其体力上限或5)。', - gaoyuan:'告援', - gaoyuan_info:'当你成为【杀】的目标时,你可弃置一张牌将此【杀】转移给一名有“诤”且不是此【杀】使用者的其他角色。', - tongqu:'通渠', - tongqu_info:'游戏开始时,你拥有一个“渠”标记。准备阶段,你可以失去1点体力令一名没有“渠”标记的角色获得“渠”标记。有“渠”的角色摸牌阶段额外摸一张牌,然后将一张牌交给其他有“渠”的角色或弃置。若以此法给出的是装备牌则使用之。当有“渠”的角色进入濒死状态时,移除其“渠”标记。', - xinwanlan:'挽澜', - xinwanlan_info:'当一名角色受到伤害值不小于体力值的伤害时,你可以弃置装备区中的所有牌(至少一张) 防止此伤害。', - re_xusheng:'手杀界徐盛', - re_xusheng_prefix:'手杀界', - re_dongzhuo:'手杀界董卓', - re_dongzhuo_prefix:'手杀界', - rejiuchi:'酒池', - rejiuchi_info:'你可以将一张黑桃手牌当做【酒】使用。当你于回合内使用带有【酒】效果的【杀】造成伤害时,你令你的〖崩坏〗失效直到回合结束。', - furong:'手杀傅肜', - furong_prefix:'手杀', - xuewei:'血卫', - xuewei_info:'准备阶段,你可以选择一名其他角色(仅自己可见)。若如此做,直到你的下回合开始前,当其第一次受到伤害时,你防止此伤害,改为由你受到等量的伤害并对伤害来源造成等量同属性的伤害。', - liechi:'烈斥', - liechi_info:'锁定技,当你进入濒死状态时,伤害来源弃置一张牌。', - xin_liaohua:'手杀界廖化', - xin_liaohua_prefix:'手杀界', - redangxian:'当先', - redangxian_info:'锁定技,回合开始时,你从弃牌堆中获得一张【杀】并进行一个额外的出牌阶段。', - refuli:'伏枥', - refuli_info:'限定技,当你处于濒死状态时,你可以将体力值回复至X点(X为势力数)。然后若你的体力值为全场唯一最多,你翻面。', - xin_caozhang:'手杀界曹彰', - xin_caozhang_prefix:'手杀界', - "rejiangchi":"将驰", - "rejiangchi_info":"出牌阶段开始时,你可以选择一项:1、摸一张牌,若如此做,你本阶段内不能使用【杀】。 2、弃置一张牌,若如此做,此阶段你使用【杀】无距离限制且你可以额外使用一张【杀】。", - rezhenxing:"镇行", - rezhenxing_info:"结束阶段开始时或当你受到伤害后,你可以观看牌堆顶的三张牌,然后你获得其中与其余牌花色均不相同的一张牌。", - xin_jianyong:'手杀界简雍', - xin_jianyong_prefix:'手杀界', - xinqiaoshui:'巧说', - xinqiaoshui_info:'出牌阶段限一次,你可以和一名其他角色拼点。若你赢,则你本阶段内使用的下一张基本牌或普通锦囊牌可以增加减少一个目标。若你没赢,你本阶段内不能使用锦囊牌。', - xinjyzongshi:'纵适', - xinjyzongshi_info:'当你拼点后,你可以观看牌堆顶的一张牌,然后选择一项:获得此牌,或获得两张拼点牌中点数较小的一张。', - dingyuan:'手杀丁原', - dingyuan_prefix:'手杀', - beizhu:'备诛', - beizhu_draw:'备诛', - beizhu_info:'出牌阶段限一次,你可以观看一名其他角色的手牌。若其中:没有【杀】,你弃置其一张牌,然后你可令其获得牌堆中的一张【杀】;有【杀】,其依次对你使用这些【杀】,当你因此受到1点伤害后,你摸一张牌。', - xin_zhuran:'手杀界朱然', - xin_zhuran_prefix:'手杀界', - mobiledanshou:'胆守', - mobiledanshou_info:'一名其他角色的结束阶段开始时,若X:为0,你摸一张牌;不等于0,你可弃置X张牌并对其造成1点伤害(X为其本回合内使用的目标包含你的牌的数量)。', - yanghuiyu:'羊徽瑜', - hongyi:'弘仪', - hongyi2:'弘仪', - hongyi_info:'出牌阶段限一次,你可以选择一名其他角色。你的下回合开始前,该角色造成伤害时进行判定,若结果为:黑色,此伤害-1。红色,受到伤害的角色摸一张牌。', - requanfeng:'劝封', - requanfeng_gain:'劝封', - requanfeng_info:'限定技。①其他角色死亡时,你可失去〖弘仪〗,然后获得其武将牌上的所有非主公技,非隐匿技和非Charlotte技,加1点体力上限并回复1点体力。②当你处于濒死状态时,你可以加2点体力上限,然后回复4点体力。', - quanfeng:'劝封', - quanfeng_info:'锁定技,限定技,一名角色死亡时,你选择获得其的一个技能(主公技,限定技,觉醒技,隐匿技,使命技,带有Charlotte标签的技能除外),然后加1点体力上限并回复1点体力。', - simashi:'手杀司马师', - simashi_prefix:'手杀', - baiyi:'败移', - baiyi_info:'限定技,出牌阶段,若你已受伤,你可以交换两名其他角色的座次。', - jinglve:'景略', - jinglve2:'景略', - jinglve3:'景略', - jinglve_info:'出牌阶段限一次,若场上没有与你对应的「死士」牌,则你可以观看一名其他角色的手牌,将其中一张牌标记为「死士」。当其使用对应的实体牌中包含「死士」的牌时,你取消此牌的所有目标。当「死士」牌不因使用而进入弃牌堆,或其回合结束后,若「死士」牌仍在其区域内,则你获得此牌。', - shanli:'擅立', - shanli_info:'觉醒技,准备阶段,若你已发动过〖败移〗且对至少两名角色发动过〖景略〗,则你减1点体力上限并选择一名角色。系统随机选择三个不为〖忘隙(仲村由理)〗的主公技,然后你选择其中一个技能,令其获得之。其将交互表情中的【拖鞋】和【酒杯】替换为【枷锁】和【玉玺】。', - re_lingtong:'手杀界凌统', - re_lingtong_prefix:'手杀界', - re_liubiao:'手杀界刘表', - re_liubiao_prefix:'手杀界', - hucheer:'手杀胡车儿', - hucheer_prefix:'手杀', - daoji:'盗戟', - daoji_info:'出牌阶段限一次,你可以弃置一张非基本牌并选择一名装备区里有牌的其他角色,你获得其装备区中的一张牌并使用之。若你以此法得到的牌是武器牌,则你使用此牌后对其造成1点伤害。', - xin_hansui:'手杀韩遂', - xin_hansui_prefix:'手杀', - xinniluan:'逆乱', - xinniluan_info:'其他角色的结束阶段,若其本回合对除其以外的角色使用过牌,则你可以对其使用一张【杀】。若以此法使用的【杀】造成伤害,则你弃置其一张牌。', - xiaoxi_hansui:'骁袭', - xiaoxi_hansui_info:'你可以将一张黑色牌当做【杀】使用或打出。', - xin_zhangfei:'手杀界张飞', - xin_zhangfei_prefix:'手杀界', - liyong:'厉勇', - liyong2:'厉勇', - liyong3:'厉勇', - liyong_info:'锁定技,若你于出牌阶段内使用的【杀】被【闪】抵消,则你获得如下效果:你本回合使用的下一张【杀】不可被响应且伤害+1,指定的目标本回合非锁定技失效,当此【杀】造成伤害后,若目标角色未死亡,你失去1点体力。', - gongsunkang:'公孙康', - juliao:'据辽', - juliao_info:'锁定技,其他角色计算与你的距离始终+X(X为场上势力数-1)。', - taomie:'讨灭', - taomie1:'讨灭', - taomie2:'讨灭', - taomie3:'讨灭', - taomie4:'讨灭', - taomie_info:'当你受到伤害后或当你造成伤害后,你可以令伤害来源或受伤角色获得“讨灭”标记(如场上已有标记则转移给该角色);你和拥有“讨灭”标记的角色视为在彼此的攻击范围内,且当你对该角色造成伤害时,选择一项:1. 此伤害+1;2. 你获得其区域内的一张牌并可将之交给另一名角色;3. 依次执行前两项并于伤害结算后弃置其“讨灭”标记。', - xin_guohuai:'手杀界郭淮', - xin_guohuai_prefix:'手杀界', - mobilejingce:'精策', - mobilejingce_info:'结束阶段,若此回合因使用或打出而置入弃牌堆的牌的数量不小于你的体力值,则你可以摸两张牌。', - xin_panzhangmazhong:'手杀界潘璋马忠', - xin_panzhangmazhong_prefix:'手杀界', - xinduodao:'夺刀', - xinduodao_info:'当你受到伤害后,你可以获得伤害来源装备区里的武器牌。', - xinanjian:'暗箭', - xinanjian_info:'锁定技,当你使用【杀】指定目标后,若你不在目标角色攻击范围内,你选择一项:1. 令其无法响应此【杀】;2. 其受到此【杀】造成的伤害+1。', - xin_fuhuanghou:'手杀界伏寿', - xin_fuhuanghou_prefix:'手杀界', - xinzhuikong:'惴恐', - xinzhuikong_info:'每轮限一次,其他角色的回合开始时,若其体力值不小于你,你可与其拼点。若你赢,其本回合无法使用牌指定除其以外的角色为目标;若你没赢,你获得其拼点的牌,然后其视为对你使用一张【杀】。', - xinqiuyuan:'求援', - xinqiuyuan_info:'当你成为【杀】的目标时,你可以令另一名其他角色交给你一张除【杀】以外的基本牌,否则其也成为此【杀】的目标。', - xin_gongsunzan:'手杀界公孙瓒', - xin_gongsunzan_prefix:'手杀界', - re_dengai:'手杀界邓艾', - re_dengai_prefix:'手杀界', - flappybird:'飞鸟', - flappybird_info:'出牌阶段,你可游玩一局Flappy Bird。', - re_handang:'手杀界韩当', - re_handang_prefix:'手杀界', - nanhualaoxian:'手杀南华老仙', - nanhualaoxian_prefix:'手杀', - yufeng:'御风', - yufeng2:'御风', - yufeng_info:'出牌阶段限一次,你可以表演“御风飞行”。若表演失败,则你摸X张牌。若表演成功,则你可以选择至多X名其他角色获得“御风”效果,然后摸X-Y张牌(准备阶段开始时,你进行判定。若结果为:红色,你跳过摸牌阶段;黑色,你跳过出牌阶段和弃牌阶段。X为你的得分。Y为你选择的角色数)。', - tianshu:'天书', - tianshu_info:'出牌阶段开始时,若场上没有【太平要术】,则你可以弃置一张牌并选择一名角色。该角色获得并使用【太平要术】。', - re_jiangwei:'手杀界姜维', - re_jiangwei_prefix:'手杀界', - retiaoxin:'挑衅', - retiaoxin_info:'出牌阶段限一次,你可以指定一名有牌的其他角色,该角色需对你使用一张【杀】,否则你弃置其一张牌。', - re_zhurong:'手杀界祝融', - re_zhurong_prefix:'手杀界', - relieren:'烈刃', - relieren_info:'当你使用【杀】指定目标后,你可以和目标角色进行拼点。若你赢,你获得其一张牌。若你没赢,你获得对方的拼点牌,其获得你的拼点牌。', - zhouqun:'周群', - tiansuan:'天算', - tiansuan_info:'出牌阶段限一次,若场上没有因你产生的“命运签”,则你可以抽取一张“命运签”,然后令一名角色获得“命运签”直到你的下回合开始。若你以此法抽取的“命运签”为:上上签,你观看其手牌;上上签/上签,你获得其区域内的一张牌。', - tiansuan_faq:'【命运签】说明', - tiansuan_faq_info:'当你抽取“命运签”时,你可以令其中一种命运签的权重+1。
              上上签(权重1):当你受到伤害时,防止此伤害。
              上签(权重2):当你受到伤害时,你令伤害值改为1;当你受到1点伤害后,你摸一张牌。
              中签(权重3):当你受到伤害时,你令伤害属性改为火属性并将伤害值改为1。
              下签(权重2):当你受到伤害时,你令此伤害+1。
              下下签(权重1):当你受到伤害时,你令此伤害+1。你不能使用【酒】或【桃】。', - tiansuan2_0:'命运签', - tiansuan2_1:'命运签', - tiansuan2_2:'命运签', - tiansuan2_damage:'命运签', - tiansuan2_fire:'命运签', - tiansuan2_3:'命运签', - tiansuan2_4:'命运签', - ol_yujin:'手杀界于禁', - ol_yujin_prefix:'手杀界', - rejieyue:'节钺', - rejieyue_info:'结束阶段开始时,你可以将一张牌交给一名其他角色。然后其选择一项:令你摸三张牌:或其保留一张手牌和装备区的牌,然后弃置其余的牌。', - xin_zhoucang:'手杀界周仓', - xin_zhoucang_prefix:'手杀界', - mobilezhongyong:'忠勇', - mobilezhongyong_info:'当你于出牌阶段内使用的【杀】结算结束后,若没有目标角色使用【闪】响应过此【杀】,则你可获得此【杀】;否则你可选择一项:①获得目标角色使用的【闪】,然后可将此【杀】交给另一名其他角色。②将目标角色使用的【闪】交给另一名其他角色,然后你本回合使用【杀】的次数上限+1且下一张【杀】的伤害值基数+1。(你不能使用本回合因执行〖忠勇〗的效果得到的牌)', - xin_caifuren:'手杀界蔡夫人', - xin_caifuren_prefix:'手杀界', - xinqieting:'窃听', - xinqieting_info:'其他角色的回合结束时,若其本回合内未对其他角色造成过伤害,则你可选择一项:①摸一张牌。②观看其两张手牌并获得其中的一张。③将其装备区内的一张牌移动至你的装备区。', - xinguixiu:'闺秀', - xinguixiu_info:'锁定技。结束阶段,若你的体力值为:奇数,你摸一张牌;偶数,你回复1点体力。', - re_zhonghui:'手杀界钟会', - re_zhonghui_prefix:'手杀界', - requanji:'权计', - requanji_info:'出牌阶段结束时,若你的手牌数大于体力值,或当你受到1点伤害后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。', - xin_guyong:'手杀界顾雍', - xin_guyong_prefix:'手杀界', - xinshenxing:'慎行', - xinshenxing_info:'出牌阶段限X次(X为你的体力值),你可以弃置两张牌,然后摸一张牌。若这两张牌颜色不同,则改为摸两张牌。', - xinbingyi:'秉壹', - xinbingyi_info:'结束阶段,你可展示所有手牌。若这些牌的颜色或类型均相同,则你可以令至多X名角色各摸一张牌(X为你的手牌数)。', - qiaozhou:'手杀谯周', - qiaozhou_prefix:'手杀', - zhiming:'知命', - zhiming_info:'准备阶段开始时或弃牌阶段结束时,你摸一张牌,然后可以将一张牌置于牌堆顶。', - xingbu:'星卜', - xingbu_info:'结束阶段,你可以展示牌堆顶的三张牌,然后你可以根据X值(X为这三张牌中红色牌的数量),令一名其他角色获得对应的效果直到其下回合结束:①三张:其摸牌阶段多摸两张牌,使用【杀】的次数上限+1。②两张:其使用【杀】的次数上限-1,跳过弃牌阶段。③小于两张:其于准备阶段开始时弃置一张手牌。', - xin_sunluban:'手杀界孙鲁班', - xin_sunluban_prefix:'手杀界', - xinzenhui:'谮毁', - xinzenhui_info:'出牌阶段限一次。当你使用【杀】或黑色普通锦囊牌指定目标时,你可选择另一名能成为此牌目标的其他角色并选择一项:①令其也成为此牌的目标。②获得其一张牌,然后将此牌的使用者改为该角色。', - xinjiaojin:'骄矜', - xinjiaojin_info:'当你受到男性角色造成的伤害时,你可以弃置一张装备牌并防止此伤害。', - xin_caozhen:'手杀界曹真', - xin_caozhen_prefix:'手杀界', - discretesidi:'司敌', - discretesidi_info:'①当你使用的不为延时锦囊牌的牌结算结束后,你可选择一名R内不存在以a为第一序偶的二元序偶的其他角色a,并选择一名角色b,在关系R内建立二元序偶<a,b>(b对其他角色不可见)。②一名角色a使用不为延时锦囊牌的牌指定b为目标时,若(aRb)∧(此牌目标数为1)为真,则{你从R内移除<a,b>,且:若b为你,你摸一张牌;若b不为你,你可选择:⒈取消此牌的目标,然后若场上没有处于濒死状态的角色,则你对a造成1点伤害。⒉摸两张牌};否则{你清除R内以a为第一元素的二元序偶}。', - fuqian:'傅佥', - jueyong:'绝勇', - jueyong_info:'锁定技。①当你不因〖绝勇〗成为唯一牌的目标时,若此牌不为转化牌且对应的实体牌牌数为1且不为【桃】或【酒】且你的“绝”数小于你的体力值,则你将此牌置于你的武将牌上,称为“绝”,且取消此牌的目标。②结束阶段开始时,若你有“绝”,则你令所有“绝”的原使用者依次对你使用所有“绝”,将无法使用的“绝”置入弃牌堆。', - poxiang:'破降', - poxiang_info:'出牌阶段限一次。你可以将一张牌交给一名其他角色。你摸三张牌(不计入本回合的手牌上限),移去所有“绝”并失去1点体力。', - simafu:'司马孚', - xunde:'勋德', - xunde_info:'一名角色受到伤害后,若你至其的距离不大于1,则你可判定。若判定结果:大于5,你令该角色获得判定牌;小于7,你令伤害来源弃置一张牌。', - chenjie:'臣节', - chenjie_info:'一名角色的判定牌生效前,你可打出一张花色相同的牌。系统将你打出的牌作为新判定牌,将原判定牌置入弃牌堆。然后你摸两张牌。', - mayuanyi:'马元义', - jibing:'集兵', - jibing_info:'①摸牌阶段开始时,若你的“兵”数小于势力数,则你可以改为将牌堆顶的两张牌置于你的武将牌上,称为“兵”。②你可以将一张“兵”当做【杀】或【闪】使用或打出。', - wangjing:'往京', - wangjing_info:'锁定技。当你因〖集兵〗而使用或打出牌时,若对方是场上体力值最高的角色,则你摸一张牌。', - moucuan:'谋篡', - moucuan_info:'觉醒技。准备阶段,若你的“兵”数不小于势力数,则你减1点体力上限并获得〖兵祸〗。', - binghuo:'兵祸', - binghuo_info:'一名角色的结束阶段开始时,若你本回合内因〖集兵〗而使用或打出过牌,则你可令一名角色判定。若判定结果为黑色,则你对其造成1点雷属性伤害。', - yanpu:'阎圃', - huantu:'缓图', - huantu_info:'每轮限一次。一名角色的摸牌阶段开始前,若其在你攻击范围内,则你可以交给其一张牌并令其跳过此阶段。然后你于此回合的结束阶段选择一项:①令其回复1点体力并摸两张牌。②你摸三张牌,然后交给其两张手牌。', - bihuo:'避祸', - bihuo_info:'限定技。一名角色脱离濒死状态时,你可以令其摸三张牌,然后其他角色计算至其的距离时+X直到本轮结束(X为角色数)。', - sunhanhua:'手杀孙寒华', - sunhanhua_prefix:'手杀', - chongxu:'冲虚', - chongxu_info:'出牌阶段限一次,你可以随机演奏一首音乐,并根据完成度来获得相应的分数(至多五分)。然后你可修改〖妙剑〗或〖莲华〗(消耗3分),并使用剩余的分数进行摸牌(每张2分)。', - chongxu_faq:'目前的曲库', - chongxu_faq_info:' 
              《鸟之诗》- 折户伸治
              《竹取飛翔 ~ Lunatic Princess》- ZUN
              《ignotus》- ak+q
              《Super Mario 3D World Theme》- 横田真人
              《只因你太美》- SWIN-S
              《Croatian Rhapsody》- Maksim
              《罗刹海市》- 刀郎
              《Pigstep (Stereo Mix)》- Lena Raine', - miaojian:'妙剑', - miaojian_info:'出牌阶段限一次。你可将一张【杀】当做刺【杀】使用,或将一张锦囊牌当做【无中生有】使用。', - miaojian1:'妙剑·改', - miaojian1_info:'出牌阶段限一次。你可将一张基本牌当做刺【杀】使用,或将一张非基本牌当做【无中生有】使用。', - miaojian2:'妙剑·极', - miaojian2_info:'出牌阶段限一次。你可视为使用一张刺【杀】或【无中生有】。', - shhlianhua:'莲华', - shhlianhua_info:'当你成为【杀】的目标后,你摸一张牌。', - shhlianhua1:'莲华·改', - shhlianhua1_info:'当你成为【杀】的目标后,你摸一张牌。然后你进行判定,若结果为黑桃,则此【杀】对你无效。', - shhlianhua2:'莲华·极', - shhlianhua2_info:'当你成为【杀】的目标后,你摸一张牌。然后此【杀】的使用者选择一项:①弃置一张牌。②令此【杀】对你无效。', - re_yufan:'手杀界虞翻', - re_yufan_prefix:'手杀界', - rezongxuan:'纵玄', - rezongxuan_place:'纵玄', - rezongxuan_info:'当你的牌因弃置而进入弃牌堆后,你可以将其以任意顺序置于牌堆顶。出牌阶段限一次,你可以摸一张牌,然后将一张牌置于牌堆顶。', - yj_huangzhong:'☆黄忠', - yj_huangzhong_prefix:'☆', - spshidi:'势敌', - spshidi_info:'转换技,锁定技。①准备阶段/结束阶段开始时,若你发动此分支的累计次数为奇数/偶数,则你获得一个“☯”。②若你的“☯”数为偶数,则你至其他角色的距离-1,且你使用的黑色【杀】不可被响应。③若你的“☯”数为奇数,则其他角色至你的距离+1,且你不可响应红色【杀】。', - spyishi:'义释', - spyishi_info:'当你对装备区有牌的其他角色造成伤害时,你可令此伤害-1,然后获得其装备区内的一张牌。', - spqishe:'骑射', - spqishe_info:'你可以将一张装备牌当做【酒】使用。你的手牌上限+X(X为你装备区内的牌数)。', - sp_maojie:'毛玠', - bingqing:'秉清', - bingqing_info:'当你于出牌阶段内使用的牌结算结束后,若你于本阶段内使用的所有已结算结束的其他牌与此牌花色均不相同,则你可根据X的值执行对应效果:为2,你令一名角色摸两张牌;为3,你弃置一名角色区域内的一张牌;为4,你对一名其他角色造成1点伤害。(X为你本阶段内使用过的已结算结束的牌中包含的花色数)', - yingfeng:'迎奉', - yingfeng_info:'准备阶段,你可以令一名角色获得“奉”标记并移除场上所有其他的“奉”标记。有“奉”标记的角色使用牌没有距离限制。', - xin_sunxiu:'手杀界孙休', - xin_sunxiu_prefix:'手杀界', - mobileyanzhu:'宴诛', - mobileyanzhu_info:'出牌阶段限一次,你可以令一名有牌的其他角色选择一项:①你获得其装备区里所有的牌,然后你失去技能〖宴诛〗并修改技能〖兴学〗。②你获得其区域里的一张牌。', - mobilexingxue:'兴学', - mobilexingxue_info:'结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶(X为你的体力值)。', - mobilexingxuex:'兴学·改', - mobilexingxuex_info:'结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶或交给一名其他目标角色(X为你的体力上限)。', - re_wuguotai:'手杀界吴国太', - re_wuguotai_prefix:'手杀界', - reganlu:'甘露', - reganlu_info:'出牌阶段限一次,你可以选择装备区牌数之差的绝对值不大于X的两名角色或包含你在内的两名角色,然后交换这两名角色装备区内的牌。(X为你已损失的体力值)', - taoqian:'手杀陶谦', - taoqian_prefix:'手杀', - miheng:'手杀祢衡', - miheng_prefix:'手杀', - re_gaoshun:'手杀界高顺', - re_gaoshun_prefix:'手杀界', - peixiu:'裴秀', - xingtu:'行图', - xingtu1:'倍数', - xingtu2:'约数', - xingtu_info:'锁定技。你使用点数为X的倍数的牌无次数限制,你使用点数为X的约数的牌时摸一张牌(X为你本局游戏使用的上一张牌的点数)。', - juezhi:'爵制', - juezhi_info:'出牌阶段,你可以弃置至少两张牌,然后从牌堆中获得一张点数为Y的牌(Y为这些牌的点数和对13取余,余数为0时Y取13)。', - sp_jianggan:'手杀蒋干', - sp_jianggan_prefix:'手杀', - spdaoshu:'盗书', - spdaoshu_info:'每轮限一次。一名敌方角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。', - spdaoshu_info_identity:'每轮限一次。一名其他角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。', - spdaoshu_info_guozhan:'每轮限一次。一名其他角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。', - mbdaoshu:'盗书', - mbdaoshu_info:'出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你和队友观看其手牌并猜测其伪装的手牌,猜对的角色对其造成1点伤害,猜错的角色随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。', - mbdaoshu_info_identity:'出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你观看其手牌并猜测其伪装的手牌。若猜中,你对其造成1点伤害;若猜错,你随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。', - mbdaoshu_info_guozhan:'出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你观看其手牌并猜测其伪装的手牌。若猜中,你对其造成1点伤害;若猜错,你随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。', - spdaizui:'戴罪', - spdaizui2:'戴罪', - spdaizui_info:'限定技。当你受到伤害值不小于体力值的伤害时,你可防止此伤害并将此伤害渠道对应的所有实体牌置于伤害来源的武将牌上,称为“释”。本回合结束时,其获得所有“释”。', - re_caiwenji:'手杀界蔡琰', - re_caiwenji_prefix:'手杀界', - re_bulianshi:'手杀界步练师', - re_bulianshi_prefix:'手杀界', - reanxu:'安恤', - reanxu_info:'出牌阶段限一次,你可以选择两名其他角色,令其中一名角色获得另一名角色的一张牌。若以此法移动的牌不来自装备区,则你摸一张牌。然后你可以令二者中手牌数较少的一名角色摸一张牌。', - xin_jushou:'手杀界沮授', - xin_jushou_prefix:'手杀界', - xinjianying:'渐营', - xinjianying_info:'①当你于出牌阶段内使用与此阶段你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。②出牌阶段限一次,你可以将一张牌当做任意基本牌使用。若你于此阶段内使用的上一张牌有花色,则此牌的花色视为上一张牌的花色。', - re_xunyu:'手杀界荀彧', - re_xunyu_prefix:'手杀界', - rejieming:"节命", - rejieming_info:"当你受到1点伤害后,你可以令一名角色摸两张牌。然后若其手牌数小于体力上限,则你摸一张牌。", - xin_quancong:'手杀界全琮', - xin_quancong_prefix:'手杀界', - sbyaoming:'邀名', - sbyaoming_info:'蓄力技(2/4)。①当你受到1点伤害后,你可以获得1点蓄力值。②出牌阶段或当你受到伤害后,你可消耗1点蓄力值并选择一项:⒈弃置一名手牌数不小于你的角色的一张牌。⒉令一名手牌数不大于你的角色摸一张牌。若你上次发动〖邀名②〗时未获得过蓄力值且你选择的选项和上次不同,则你获得1点蓄力值。', - ruanhui:'阮慧', - mingcha:'明察', - mingcha_info:'摸牌阶段开始时,你亮出牌堆顶的三张牌。若这三张牌中有点数小于9的牌,则你可以放弃摸牌并获得这些牌,然后你可以获得一名其他角色的随机一张牌。', - jingzhong:'敬重', - jingzhong_info:'弃牌阶段结束时,若你于本阶段内弃置过至少两张黑色牌,则你可以选择一名其他角色并获得如下效果直到其回合结束:每阶段限三次,其于出牌阶段内使用的牌结算结束后,你获得此牌对应的实体牌。', - xin_mamidi:'手杀马日磾', - xin_mamidi_prefix:'手杀', - chengye:'承业', - chengye_info:'锁定技。①其他角色使用的非转化牌结算结束后,或其他角色的装备牌和延时锦囊牌进入弃牌堆后,或有延时锦囊牌因其他角色执行判定阶段的流程而进入弃牌堆后,若你的“六经”有空缺的位置可以置入此牌,则你将此牌置于你武将牌上,填补“六经”的对应位置。②出牌阶段开始时,若你的“六经”没有空缺的位置,则你获得所有“六经”。', - chengye_append:'
            • 《诗经》:伤害类锦囊牌
            • 《尚书》:基本牌
            • 《仪礼》:无懈可击
            • 《易经》:无中生有
            • 《乐经》:乐不思蜀
            • 《春秋》:装备牌', - buxu:'补叙', - buxu_backup:'补叙', - buxu_info:'出牌阶段,若你的“六经”中有空缺的位置,则你可以弃置X+1张牌并选择一种空缺的“六经”(X为你本阶段内发动过〖补叙〗的次数)。系统从牌堆或弃牌堆中检索一张对应的牌,然后你将此牌置于你武将牌上,填补“六经”的对应位置。', - re_dianwei:'手杀界典韦', - re_dianwei_prefix:'手杀界', - liuye:'手杀刘晔', - liuye_prefix:'手杀', - sp_caosong:'手杀曹嵩', - sp_caosong_prefix:'手杀', - yijin:'亿金', - yijin_info:'锁定技。①游戏开始时,你获得“膴仕”、“金迷”、“贾凶”、“通神”、“拥蔽”、“厚任”各1枚(均称为“金”)。②出牌阶段开始时,你选择一名没有“金”的其他角色。你交给其1枚“金”,且令其获得对应效果。③一名角色的回合结束后,若其有你交给其的“金”,其移去此“金”。④当你死亡时,移去场上所有你交出的“金”。⑤回合开始时,若你没有“金”,你死亡。', - yijin_wushi:'膴仕', - yijin_wushi_info:'锁定技。①摸牌阶段,你多摸四张牌。②你使用【杀】的次数上限+1。', - yijin_jinmi:'金迷', - yijin_jinmi_info:'锁定技。回合开始时,你跳过下一个出牌阶段和弃牌阶段。', - yijin_guxiong:'贾凶', - yijin_guxiong_info:'锁定技。①出牌阶段开始时,你失去1点体力。②你的手牌上限-3。', - yijin_tongshen:'通神', - yijin_tongshen_info:'锁定技。当你受到非雷电伤害时,防止之。', - yijin_yongbi:'拥蔽', - yijin_yongbi_info:'锁定技。准备阶段,你跳过下一个摸牌阶段。', - yijin_houren:'厚任', - yijin_houren_info:'锁定技。回合结束时,你回复3点体力。', - guanzong:'惯纵', - guanzong_info:'出牌阶段限一次。你可以令一名其他角色视为对另一名其他角色造成过1点伤害。', - yangfu:'杨阜', - jiebing:'借兵', - jiebing_info:'锁定技。当你受到伤害后,你选择来源外的一名其他角色,随机获得其一张牌并展示。若此牌为装备牌,你使用之。', - hannan:'扞难', - hannan_info:'出牌阶段限一次。你可以与一名角色拼点,赢的角色对没赢的角色造成2点伤害。', - xin_wuyi:'手杀界吴懿', - xin_wuyi_prefix:'手杀界', - sbbenxi:'奔袭', - sbbenxi_info:'出牌阶段开始时,你可以弃置至少一张牌,然后你于此阶段获得如下效果:①你至其他角色距离-X;②当你使用的下一张基本牌或普通锦囊牌A选择目标后,你可以额外指定X名距离为1的角色为目标;③牌A结算结束后,若此牌造成过伤害,你摸五张牌(X为你以此法弃置的牌数)。', - xin_zhuzhi:'手杀界朱治', - xin_zhuzhi_prefix:'手杀界', - sbanguo:'安国', - sbanguo_info:'①游戏开始时,你令一名其他角色获得1枚“安国”标记(有“安国”的角色手牌上限基数等于体力上限)。②出牌阶段开始时,你可以将一名有“安国”的角色的所有“安国”移动给一名本局游戏未获得过“安国”的其他角色。③当你受到伤害时,若有有“安国”的角色且伤害值不小于你的体力值且此伤害没有来源或来源没有“安国”,防止此伤害。④一名角色进入濒死状态时,若其有你因〖安国①〗获得的“安国”,你移去其该“安国”,令其将体力回复至1点。然后你选择一项:1.若你的体力值大于1,你失去体力至1点;2.若你的体力上限大于1,你将体力上限减至1。最后你令其获得1点护甲。', - wangjun:'手杀王濬', - wangjun_prefix:'手杀', - zhujian:'筑舰', - zhujian_info:'出牌阶段限一次。你可以令至少两名装备区里有牌的角色各摸一张牌。', - duansuo:'断索', - duansuo_info:'出牌阶段限一次。你可以重置任意名处于连环状态的角色,然后对这些角色各造成1点火焰伤害。', - sp_pengyang:'手杀彭羕', - sp_pengyang_prefix:'手杀', - spdaming:'达命', - spdaming_info:'①游戏开始时,你获得1点“达命”值。②其他角色A的出牌阶段限一次。其可以交给你一张牌,然后你选择另一名其他角色B。若B有与此牌相同类型的牌,其将一张该类型的牌交给A,你获得1点“达命”值;否则你将此牌交给A。', - spxiaoni:'嚣逆', - spxiaoni_info:'①出牌阶段限一次。若你的“达命”值大于0,你可以将一张牌当任意一种【杀】或伤害类锦囊牌使用。然后你减少等同于此牌指定目标数的“达命”值。②你的手牌上限基数为X(X为“达命”值,且至多为你的体力值,至少为0)。', - xin_zhuhuan:'手杀界朱桓', - xin_zhuhuan_prefix:'手杀界', - xinpingkou:'平寇', - xinpingkou_info:'回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。然后你从牌堆中获得一张装备牌。', - xin_caoxiu:'手杀界曹休', - xin_caoxiu_prefix:'手杀界', - xinqingxi:'倾袭', - xinqingxi_info:'每回合限一次。当你对其他角色造成伤害时,你可以令其选择一项:1.弃置X张手牌(X为4减去你至其的距离,至少为1);2.令此伤害+1。', - yj_weiyan:'☆魏延', - yj_weiyan_prefix:'☆', - mbguli:'孤厉', - mbguli_info:'出牌阶段限一次。你可以将所有手牌当做一张无视防具的【杀】使用。此牌结算结束后,若此牌造成过伤害,你可以失去1点体力并将手牌摸至X张(X为你的体力上限)。', - mbaosi:'骜肆', - mbaosi_info:'锁定技。当你于出牌阶段对一名攻击范围内的角色造成伤害后,你于此阶段对其使用牌无次数限制。', - xin_zhoutai:'手杀界周泰', - xin_zhoutai_prefix:'手杀界', - re_yanwen:'手杀界颜良文丑', - re_yanwen_prefix:'手杀界', - qianzhao:'手杀牵招', - qianzhao_prefix:'手杀', - mbshihe:'势吓', - mbshihe_info_identity:'出牌阶段限一次。你可以与一名角色拼点。若你:赢,当其于其下回合结束前对你造成伤害时,取消之;没赢,你随机弃置一张牌。', - mbshihe_info:'出牌阶段限一次。你可以与一名角色拼点。若你:赢,当其于其下回合结束前对你和你的友方角色造成伤害时,取消之;没赢,你随机弃置一张牌。', - mbzhenfu:'镇抚', - mbzhenfu_info:'结束阶段,若你本回合因弃置失去过牌,你可以令一名其他角色获得1点护甲。', - shichangshi:'十常侍', - mbdanggu:'党锢', - mbdanggu_info:'锁定技。①游戏开始时,你获得十张“常侍”牌,然后你进行一次结党。②当你修整结束后,你进行一次结党并摸一张牌。③若你有亮出的“常侍”牌,你视为拥有这些牌的技能。', - mbdanggu_faq:'关于结党', - mbdanggu_faq_info:'
              系统随机选择一张未亮出过的“常侍”牌,然后选择四张未亮出过的“常侍”牌。你观看前者,然后从后者中选择一名认可前者的“常侍”牌。然后若此时不为双将模式,你将这两张武将牌作为你的武将牌(不移除原有技能);否则你获得这两张武将牌上的技能。', - mbdanggu_faq2:'关于认可', - mbdanggu_faq2_info:'
              双向不认可常侍为固定组合:
            • 郭胜、段珪
            • 韩悝、毕岚
              单向不认可常侍为系统随机分配。
              每次结党至多存在一张不认可主将的常侍牌,且若此次结党仅有一张常侍牌,则不会存在不认可情况。', - mbmowang:'殁亡', - mbmowang_info:'锁定技。①当你死亡前,若你有未亮出的“常侍”牌且体力上限大于0,你将死亡改为修整至你的下个回合开始前,然后你复原武将牌,且不于此次死亡事件中进行展示身份牌、检测游戏胜利条件与执行奖惩的流程。②回合结束后,你死亡。', - mbmowang_faq:'关于修整', - mbmowang_faq_info:'
              将武将牌移出游戏(视为你存活)。当该角色修整结束,其移回游戏。', - scs_zhangrang:'张让', - scstaoluan:'滔乱', - scstaoluan_info:'出牌阶段限一次。你可以将一张牌当任意一种基本牌或普通锦囊牌使用。', - scs_zhaozhong:'赵忠', - scschiyan:'鸱咽', - scschiyan_info:'①当你使用【杀】指定目标后,你可以将其的一张牌置于其武将牌上,然后其于当前回合结束时获得这些牌。②当你因执行【杀】的效果对一名角色造成伤害时,若该角色的手牌数和装备区内的牌数均不大于你,此伤害+1。', - scs_sunzhang:'孙璋', - scszimou:'自谋', - scszimou_info:'锁定技。出牌阶段,当你使用第二/四/六张牌时,你从牌堆中获得一张【酒】/【杀】/【决斗】。', - scs_bilan:'毕岚', - scspicai:'庀材', - scspicai_info:'出牌阶段限一次。你可进行判定牌不置入弃牌堆的判定。若判定结果与本次发动技能时的其他判定结果的花色均不相同,则你可以重复此流程。然后你将所有位于处理区的判定牌交给一名角色。', - scs_xiayun:'夏恽', - scsyaozhuo:'谣诼', - scsyaozhuo_info:'出牌阶段限一次。你可以与一名角色拼点,若你赢,其跳过下一个摸牌阶段;若你没赢,你弃置两张牌。', - scs_hankui:'韩悝', - scsxiaolu:'宵赂', - scsxiaolu_info:'出牌阶段限一次。你可以摸两张牌,然后选择一项:1.弃置两张牌;2.将两张牌交给一名其他角色。', - scs_lisong:'栗嵩', - scskuiji:'窥机', - scskuiji_info:'出牌阶段限一次。你可以观看一名其他角色的手牌,然后弃置你与其的共计四张花色各不相同的手牌。', - scs_duangui:'段珪', - scschihe:'叱吓', - scschihe_info:'当你使用【杀】指定唯一目标后,你可亮出牌堆顶的两张牌,令此【杀】的伤害值基数+X(X为亮出牌中花色与此【杀】相同的牌数),且目标角色不能使用亮出牌包含的花色的牌响应此【杀】。', - scs_guosheng:'郭胜', - scsniqu:'逆取', - scsniqu_info:'出牌阶段限一次。你可以对一名角色造成1点火焰伤害。', - scs_gaowang:'高望', - scsanruo:'安弱', - scsanruo_info:'你可以将一张♥牌当【桃】、♦牌当火【杀】、♣牌当【闪】、♠牌当【无懈可击】使用。当你以此法使用或打出【杀】或【闪】时,你可以获得对方的一张牌;当你以此法使用【桃】时,你可以获得一名其他角色的一张牌;当你以此法使用【无懈可击】时,你可以获得此牌响应的普通锦囊牌的使用者的一张牌。', - scsmiaoyu:'妙语', - scsmiaoyu_info:'你可以将至多两张相同花色的牌按照以下规则使用或打出:♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】。若你以此法使用了两张红色牌,则此牌回复值或伤害值+1。若你以此法使用了两张黑色牌,则你弃置当前回合角色一张牌。', - re_xiaoqiao:'手杀界小乔', - re_xiaoqiao_prefix:'手杀界', - xin_sunliang:'手杀孙亮', - xin_sunliang_prefix:'手杀', - xinkuizhu:'溃诛', - xinkuizhu_info:'弃牌阶段结束后,你可以选择一项:1.令至多X名角色各摸一张牌。2.对任意名体力值之和为X的角色造成1点伤害,若你以此法选择的角色数不小于2,你失去1点体力。(X为你此阶段弃置的牌数)', - xinzhizheng:'掣政', - xinzhizheng_info:'锁定技,你的出牌阶段内,攻击范围内不包含你的其他角色不能成为你使用牌的目标。出牌阶段结束时,若你本阶段内使用的牌数小于这些角色的数量,则你弃置其中一名角色的一张牌。', - xinlijun:'立军', - xinlijun_info:'主公技,其他吴势力角色于其回合内使用【杀】结算完毕后,其可以将此【杀】对应的实体牌交给你,然后你可以令其摸一张牌。', - xin_zhangyi:'手杀界张嶷', - xin_zhangyi_prefix:'手杀界', - xinwurong:'怃戎', - xinwurong_info:'出牌阶段限一次,你可以与一名其他角色进行谋弈:
            • 若你选择“镇压”且其选择“反抗”,你对其造成1点伤害,然后你摸一张牌。
            • 若你选择“安抚”且其选择“归顺”,其须交给你两张牌(若其手牌数不足两张,则改为令其跳过其下个摸牌阶段)。
            • 若你选择“镇压”且其选择“归顺”,你获得其一张牌,然后你交给其两张牌。
            • 若你选择“安抚”且其选择“反抗”,你受到1点伤害,然后你摸两张牌。', - xin_guozhao:'手杀郭照', - xin_guozhao_prefix:'手杀', - yichong:'易宠', - yichong_info:'①准备阶段,你可以选择一名其他角色并选择一个花色,然后你获得其所有此花色的装备牌和其一张此花色的手牌,移除场上的所有“雀”标记,令其获得“雀”标记直到你的下个回合开始。②拥有“雀”标记的角色获得你最后一次发动〖易宠①〗选择的花色的牌后,你获得这些牌(你至多通过每个“雀”得到一张牌)。', - wufei:'诬诽', - wufei_info:'若场上存在拥有“雀”标记的角色A,则:①当你使用【杀】或伤害类锦囊牌指定第一个目标后,你令A成为此牌伤害来源。②当你受到伤害后,若A的体力值大于3,则你可以令A受到1点无来源伤害。', - yj_zhoubuyi:'☆周不疑', - yj_zhoubuyi_prefix:'☆', - mbhuiyao:'慧夭', - mbhuiyao_info:'出牌阶段限一次。你可以受到1点无来源伤害,然后你选择一名其他角色,令其视为对另一名角色造成过1点伤害。', - mbquesong:'雀颂', - mbquesong_info:'一名角色的结束阶段,若你于本回合受到过伤害,你可以令一名角色选择一项:1.摸X张牌并复原武将牌(X为3,若其装备区非宝物牌牌数不小于三张则X为2);2.回复1点体力。', - xin_yuanshao:'手杀界袁绍', - xin_yuanshao_prefix:'手杀界', - re_baosanniang:'手杀鲍三娘', - re_baosanniang_prefix:'手杀', - re_liushan:'手杀界刘禅', - re_liushan_prefix:'手杀界', - re_sunben:'界孙笨', - re_sunben_prefix:'界', - re_zhangzhang:'手杀界张昭张纮', - re_zhangzhang_prefix:'手杀界', - re_caozhi:'手杀界曹植', - re_caozhi_prefix:'手杀界', - re_sunjian:'手杀界孙坚', - re_sunjian_prefix:'手杀界', - sunru:'手杀孙茹', - sunru_prefix:'手杀', - pangdegong:"手杀庞德公", - pangdegong_prefix:'手杀', - zhaotongzhaoguang:"手杀赵统赵广", - zhaotongzhaoguang_prefix:'手杀', - re_liru:'手杀界李儒', - re_liru_prefix:'手杀界', - re_chenqun:'手杀界陈群', - re_chenqun_prefix:'手杀界', - re_liru:'手杀界李儒', - re_liru_prefix:'手杀界', - re_chenqun:'手杀界陈群', - re_chenqun_prefix:'手杀界', - old_yuanshu:'手杀袁术', - old_yuanshu_prefix:'手杀', - baoxin:'鲍信', - mutao:'募讨', - mutao_info:'出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】置于武将牌上,然后将这些牌依次随机交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。', - yimou:'毅谋', - yimou_info:'当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色,然后摸一张牌。', - jiangji:'手杀蒋济', - jiangji_prefix:'手杀', - jilun:'机论', - jilun_info:'①当你受到伤害后,若你拥有技能〖急筹〗,则你可以一项:1.摸两张牌。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:'你可以将一张♣手牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。', - mb_sunluyu:'手杀孙鲁育', - mb_sunluyu_prefix:'手杀', - mbmumu:'穆穆', - mbmumu_info:'出牌阶段开始时,你可以选择一项:1.弃置场上的一张装备牌;2.获得场上的一张防具牌,然后你本回合不能使用或打出【杀】。', - mbmeibu:'魅步', - mbmeibu_info:'其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌,令该角色于本回合内获得〖止息〗。若你以此法弃置的牌不是【杀】或黑色锦囊牌,则本回合其与你的距离视为1。', - mbzhixi:'止息', - mbzhixi_info:'锁定技。出牌阶段,若你于此阶段使用过的牌数不小于X,你不能使用牌(X为你的体力值);当你使用锦囊牌时,你结束此阶段。', - yanxiang:'阎象', - kujian:'苦谏', - kujian_info:'出牌阶段限一次,你可以将至多两张手牌称为“谏”并交给一名其他角色,然后你获得以下效果:当其他角色使用或打出牌后,若其中有“谏”,你与其各摸两张牌;当其他角色不因使用或打出而失去牌后,若其中有“谏”,你与其各弃置一张牌。', - mb_xianglang:'手杀向朗', - mb_xianglang_prefix:'手杀', - naxue:'纳学', - naxue_info:'你可以跳过出牌阶段。若如此做,你可以弃置任意张牌并摸等量的牌,然后你可以交给至多两名其他角色各一张手牌。', - yijie:'遗诫', - yijie_info:'锁定技。当你死亡时,你令所有其他角色将体力回复或失去至X(X为所有其他角色的体力之和除以所有其他角色数,向下取整,且X至少为1)。', - mb_chengui:'手杀陈珪', - mb_chengui_prefix:'手杀', - guimou:'诡谋', - guimou_info:'锁定技。游戏开始时/回合结束时,你随机/须选择以下一项直到你的下个准备阶段:①记录场上期间角色使用牌数;②记录期间场上角色弃置牌数;③记录期间场上角色获得牌数。准备阶段,你可以选择一名场上对应记录数值最少的其他角色,观看其手牌并选择其中一张牌,然后你将此牌交给另一名其他角色或弃置此牌。', - zhouxian:'州贤', - zhouxian_info:'锁定技。当你成为其他角色使用的伤害类卡牌的目标后,你亮出牌堆顶的三张牌,然后其须选择一项:①弃置一张与亮出牌之一类别相同的牌;②令此牌对你无效。', - mb_huban:'手杀胡班', - mb_huban_prefix:'手杀', - mbyilie:'义烈', - mbyilie2:'义烈', - mbyilie3:'义烈', - mbyilie_info:'锁定技。①游戏开始时,你选择一名其他角色,然后你获得以下效果:其受到伤害时,若你没有“烈”,则你获得等同于伤害值的“烈”标记,然后防止此伤害;其对其他角色造成伤害后,你回复1点体力。②结束阶段,你摸一张牌并失去X点体力,然后移去所有“烈”(X为你拥有的“烈”标记数)。', - muludawang:'木鹿大王', - shoufa:'兽法', - shoufa_info:'当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。', - shoufa_info_doudizhu:'当你受到伤害后/于一回合首次造成伤害后,你可以选择一名角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。', - yuxiang:'御象', - yuxiang_info:'锁定技,若你有护甲值,则:①你计算与其他角色的距离-1,其他角色计算与你的距离+1;②当你受到火焰伤害时,此伤害+1。', - zhoulin:'咒鳞', - zhoulin_info:'限定技,出牌阶段,你可以获得2点护甲值,然后选择一个“兽法”效果,你发动〖兽法〗的执行效果改为你选择的效果直到你的下个回合结束。', - xin_huojun:'手杀霍峻', - xin_huojun_prefix:'手杀', - sidai:'伺怠', - sidai_info:'限定技,出牌阶段,你可以将手牌区内的所有基本牌当做【杀】使用。若此牌对应的实体牌中:包含【闪】,则目标角色成为此牌的目标后,需弃置一张基本牌,否则不可响应此牌;包含【桃】,则当目标角色受到此牌的伤害后,其减1点体力上限。', - jieyu:'竭御', - jieyu_info:'结束阶段,你可以从弃牌堆中获得共X张不同牌名的基本牌(X为4-你上次发动〖竭御〗至今你成为其他角色使用伤害类卡牌目标的次数,且X至少为1)。', - jieyu_info_identity:'结束阶段,你可以从弃牌堆中获得共X张不同牌名的基本牌(X为3-你上次发动〖竭御〗至今你成为其他角色使用伤害类卡牌目标的次数,且X至少为1)。', - yangfeng:'杨奉', - mbxuetu:'血途', - mbxuetu_info:'转换技。出牌阶段限一次,阴:你可以弃置一张牌,然后令一名角色回复1点体力;阳:你可以失去1点体力,然后令一名角色摸两张牌。', - mbxuetu_achieve:'血途·成功', - mbxuetu_achieve_info:'出牌阶段各限一次。⒈你可以弃置一张牌,然后令一名角色回复1点体力;⒉你可以失去1点体力,然后令一名角色摸两张牌。', - mbxuetu_fail:'血途·失败', - mbxuetu_fail_info:'转换技。出牌阶段限一次,阴:你可以回复1点体力,然后令一名角色弃置两张牌;阳:你可以摸一张牌,然后对一名角色造成1点伤害。', - mbweiming:'威命', - mbweiming_info:'使命技,锁定技。①出牌阶段开始时,你记录一名未以此法记录过的角色。②成功:当你杀死一名未被〖威命①〗记录过的角色后,修改〖血途〗为成功版本。③失败:当一名被〖威命①〗记录过的角色死亡后,你修改〖血途〗为失败版本。', - lizhaojiaobo:'李昭焦伯', - mbzuoyou:'佐佑', - mbzuoyou_info:'转换技。出牌阶段限一次,阴:你可以令一名角色摸三张牌,然后其弃置两张牌;阳:你可以令一名角色弃置一张手牌,然后其获得1点护甲。', - mbshishou:'侍守', - mbshishou_info:'锁定技。当你发动〖佐佑〗后,若目标角色不为你,你执行〖佐佑〗中目标角色未执行的一项。', - chengji:'成济', - mbkuangli:'狂戾', - mbkuangli_info:'锁定技。①出牌阶段开始时,你随机令场上任意名其他角色获得“狂戾”标记。②出牌阶段限两次。当你使用牌指定有“狂戾”的角色为目标后,你与其各随机弃置一张牌,然后你摸一张牌。③回合结束时,你移除所有角色的“狂戾”。', - mbxiongsi:'凶肆', - mbxiongsi_info:'限定技。出牌阶段,若你的手牌数不少于三张,你可以弃置所有手牌,然后令所有其他角色依次失去1点体力。', - mb_sp_guanqiujian:'SP毌丘俭', - mb_sp_guanqiujian_prefix:'SP', - mbcuizhen:'摧阵', - mbcuizhen_info:'①游戏开始时,你可以废除至多两名其他角色的武器栏。②当你于出牌阶段使用伤害类牌指定其他角色为目标后,若目标角色的手牌数不小于体力值,你可以废除其武器栏。③摸牌阶段,你令额定摸牌数+X(X为所有角色被废除的武器栏数之和,至多为2)。', - mbkuili:'溃离', - mbkuili_info:'锁定技。当你受到伤害后,你弃置等同于伤害值的手牌;若来源有被废除的武器栏,你令其恢复武器栏。', - mb_caomao:'手杀曹髦', - mb_caomao_prefix:'手杀', - mbqianlong:'潜龙', - mbqianlong_info:'①游戏开始时,你获得20枚“道心”标记。②当你得到牌后/受到1点伤害后/造成1点伤害后,你获得5/10/15枚“道心”(上限为100枚)。③若你的“道心”数不小于25/50/75/100,你视为拥有〖清正〗/〖酒诗〗/〖放逐〗/〖决进〗。', - mbcmqingzheng:'清正', - mbcmqingzheng_info:'出牌阶段开始时,你可以弃置两种花色的所有手牌,并观看一名有手牌的其他角色的手牌,你弃置其中一种花色的所有牌。若其被弃置的牌数小于你以此法弃置的牌数,你对其造成1点伤害。', - mbcmjiushi:'酒诗', - mbcmjiushi_info:'①当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。②当你受到伤害后,若你的武将牌背面向上,你可以翻面。③当你翻面后,你获得牌堆里的一张锦囊牌。', - mbcmfangzhu:'放逐', - mbcmfangzhu_info:'出牌阶段限一次。你可以选择一名其他角色,选择一项:⒈令其不能使用手牌中的非锦囊牌直到其回合结束;⒉令其所有非Charlotte技能失效直到其回合结束。', - mbjuejin:'决进', - mbjuejin_info:'限定技。出牌阶段,你可以令所有角色依次将体力回复或失去至1并获得X点护甲(X为一名角色以此法变化的体力值)。然后你增加如下“向死存魏”的全局技能:当有牌进入弃牌堆后,系统将这些牌中的【闪】、【桃】和【酒】移出游戏。', - mbweitong:'卫统', - mbweitong_info:'主公技。游戏开始时,若你有〖潜龙〗,你获得20X枚“道心”(X为其他魏势力角色数)。', + mobile_yijiang: "将星独具", + yj_zhanghe: "☆张郃", + yj_zhanghe_prefix: "☆", + yj_zhangliao: "☆张辽", + yj_zhangliao_prefix: "☆", + yj_xuhuang: "☆徐晃", + yj_xuhuang_prefix: "☆", + yj_ganning: "☆甘宁", + yj_ganning_prefix: "☆", + xhzhiyan: "治严", + xhzhiyan_info: + "出牌阶段,若你的手牌数不等于体力上限,则你可以将手牌摸至/弃至手牌上限,然后本回合不能对其他角色使用牌/可以将弃置的一张牌交给一名其他角色。", + zhilve: "知略", + zhilve_info: + "锁定技,准备阶段,你选择一项:1.移动场上装备区的一张牌并失去1点体力。2.移动场上判定区的一张牌并令本回合手牌上限-1。3.本回合摸牌阶段多摸一张牌且使用的第一张【杀】无距离限制且不计入次数限制。", + xinzhilve: "知略", + xinzhilve_backup: "知略", + xinzhilve_mark: "知略", + xinzhilve_info: + "出牌阶段限一次,你可以失去1点体力并选择一项:1.移动场上的一张牌;2.视为使用一张无距离限制且不计入次数限制的【杀】并摸一张牌。然后你本回合的手牌上限+1。", + xinxhzhiyan: "治严", + xinxhzhiyan_false: "治严", + xinxhzhiyan_info: + "出牌阶段每项各限一次,若你的手牌数:大于体力值,则你可以将X张手牌交给一名其他角色(X为你的手牌数与体力值之差);小于体力上限,则你可以摸X张牌且本阶段内不能再对其他角色使用牌。(X为你的手牌数与体力上限之差)", + weifeng: "威风", + weifeng2: "威风", + weifeng3: "威风", + weifeng_info: + "锁定技,当你于出牌阶段内使用第一张伤害性基本牌或普通锦囊牌后,你令此牌的一名没有“惧”的其他目标角色获得一枚名称为此牌牌名的“惧”。有“惧”的角色受到伤害时,其移去“惧”,然后若造成伤害的牌名称和“惧”:相同,此伤害+1;不同,你获得该角色的一张牌。准备阶段开始时或你死亡时,你移去场上的所有“惧”。", + gnjinfan: "锦帆", + gnjinfan_gain: "锦帆", + gnjinfan_info: + "弃牌阶段开始时,你可将任意张手牌置于武将牌上,称为“铃”(每种花色的“铃”限一张)。你可以如手牌般使用或打出“铃”。当有“铃”移动到处理区后,你从牌堆中获得与“铃”花色相同的一张牌。", + gnsheque: "射却", + gnsheque_info: + "一名其他角色的准备阶段开始时,若其装备区内有牌,则你可以对其使用一张【杀】(无距离关系的限制且无视防具)。", + sp_sufei: "手杀苏飞", + sp_sufei_prefix: "手杀", + zhengjian: "诤荐", + zhengjian_draw: "诤荐", + zhengjian_mark: "诤荐", + zhengjian_info: + "锁定技,结束阶段,你令一名角色获得一枚“诤”。回合开始时,你令有“诤”的角色移去“诤”并摸X张牌(X为其最后一次获得“诤”后使用和打出的牌数,且至多不能超过其体力上限或5)。", + gaoyuan: "告援", + gaoyuan_info: + "当你成为【杀】的目标时,你可弃置一张牌将此【杀】转移给一名有“诤”且不是此【杀】使用者的其他角色。", + tongqu: "通渠", + tongqu_info: + "游戏开始时,你拥有一个“渠”标记。准备阶段,你可以失去1点体力令一名没有“渠”标记的角色获得“渠”标记。有“渠”的角色摸牌阶段额外摸一张牌,然后将一张牌交给其他有“渠”的角色或弃置。若以此法给出的是装备牌则使用之。当有“渠”的角色进入濒死状态时,移除其“渠”标记。", + xinwanlan: "挽澜", + xinwanlan_info: + "当一名角色受到伤害值不小于体力值的伤害时,你可以弃置装备区中的所有牌(至少一张) 防止此伤害。", + re_xusheng: "手杀界徐盛", + re_xusheng_prefix: "手杀界", + re_dongzhuo: "手杀界董卓", + re_dongzhuo_prefix: "手杀界", + rejiuchi: "酒池", + rejiuchi_info: + "你可以将一张黑桃手牌当做【酒】使用。当你于回合内使用带有【酒】效果的【杀】造成伤害时,你令你的〖崩坏〗失效直到回合结束。", + furong: "手杀傅肜", + furong_prefix: "手杀", + xuewei: "血卫", + xuewei_info: + "准备阶段,你可以选择一名其他角色(仅自己可见)。若如此做,直到你的下回合开始前,当其第一次受到伤害时,你防止此伤害,改为由你受到等量的伤害并对伤害来源造成等量同属性的伤害。", + liechi: "烈斥", + liechi_info: "锁定技,当你进入濒死状态时,伤害来源弃置一张牌。", + xin_liaohua: "手杀界廖化", + xin_liaohua_prefix: "手杀界", + redangxian: "当先", + redangxian_info: "锁定技,回合开始时,你从弃牌堆中获得一张【杀】并进行一个额外的出牌阶段。", + refuli: "伏枥", + refuli_info: + "限定技,当你处于濒死状态时,你可以将体力值回复至X点(X为势力数)。然后若你的体力值为全场唯一最多,你翻面。", + xin_caozhang: "手杀界曹彰", + xin_caozhang_prefix: "手杀界", + rejiangchi: "将驰", + rejiangchi_info: + "出牌阶段开始时,你可以选择一项:1、摸一张牌,若如此做,你本阶段内不能使用【杀】。 2、弃置一张牌,若如此做,此阶段你使用【杀】无距离限制且你可以额外使用一张【杀】。", + rezhenxing: "镇行", + rezhenxing_info: + "结束阶段开始时或当你受到伤害后,你可以观看牌堆顶的三张牌,然后你获得其中与其余牌花色均不相同的一张牌。", + xin_jianyong: "手杀界简雍", + xin_jianyong_prefix: "手杀界", + xinqiaoshui: "巧说", + xinqiaoshui_info: + "出牌阶段限一次,你可以和一名其他角色拼点。若你赢,则你本阶段内使用的下一张基本牌或普通锦囊牌可以增加减少一个目标。若你没赢,你本阶段内不能使用锦囊牌。", + xinjyzongshi: "纵适", + xinjyzongshi_info: + "当你拼点后,你可以观看牌堆顶的一张牌,然后选择一项:获得此牌,或获得两张拼点牌中点数较小的一张。", + dingyuan: "手杀丁原", + dingyuan_prefix: "手杀", + beizhu: "备诛", + beizhu_draw: "备诛", + beizhu_info: + "出牌阶段限一次,你可以观看一名其他角色的手牌。若其中:没有【杀】,你弃置其一张牌,然后你可令其获得牌堆中的一张【杀】;有【杀】,其依次对你使用这些【杀】,当你因此受到1点伤害后,你摸一张牌。", + xin_zhuran: "手杀界朱然", + xin_zhuran_prefix: "手杀界", + mobiledanshou: "胆守", + mobiledanshou_info: + "一名其他角色的结束阶段开始时,若X:为0,你摸一张牌;不等于0,你可弃置X张牌并对其造成1点伤害(X为其本回合内使用的目标包含你的牌的数量)。", + yanghuiyu: "羊徽瑜", + hongyi: "弘仪", + hongyi2: "弘仪", + hongyi_info: + "出牌阶段限一次,你可以选择一名其他角色。你的下回合开始前,该角色造成伤害时进行判定,若结果为:黑色,此伤害-1。红色,受到伤害的角色摸一张牌。", + requanfeng: "劝封", + requanfeng_gain: "劝封", + requanfeng_info: + "限定技。①其他角色死亡时,你可失去〖弘仪〗,然后获得其武将牌上的所有非主公技,非隐匿技和非Charlotte技,加1点体力上限并回复1点体力。②当你处于濒死状态时,你可以加2点体力上限,然后回复4点体力。", + quanfeng: "劝封", + quanfeng_info: + "锁定技,限定技,一名角色死亡时,你选择获得其的一个技能(主公技,限定技,觉醒技,隐匿技,使命技,带有Charlotte标签的技能除外),然后加1点体力上限并回复1点体力。", + simashi: "手杀司马师", + simashi_prefix: "手杀", + baiyi: "败移", + baiyi_info: "限定技,出牌阶段,若你已受伤,你可以交换两名其他角色的座次。", + jinglve: "景略", + jinglve2: "景略", + jinglve3: "景略", + jinglve_info: + "出牌阶段限一次,若场上没有与你对应的「死士」牌,则你可以观看一名其他角色的手牌,将其中一张牌标记为「死士」。当其使用对应的实体牌中包含「死士」的牌时,你取消此牌的所有目标。当「死士」牌不因使用而进入弃牌堆,或其回合结束后,若「死士」牌仍在其区域内,则你获得此牌。", + shanli: "擅立", + shanli_info: + "觉醒技,准备阶段,若你已发动过〖败移〗且对至少两名角色发动过〖景略〗,则你减1点体力上限并选择一名角色。系统随机选择三个不为〖忘隙(仲村由理)〗的主公技,然后你选择其中一个技能,令其获得之。其将交互表情中的【拖鞋】和【酒杯】替换为【枷锁】和【玉玺】。", + re_lingtong: "手杀界凌统", + re_lingtong_prefix: "手杀界", + re_liubiao: "手杀界刘表", + re_liubiao_prefix: "手杀界", + hucheer: "手杀胡车儿", + hucheer_prefix: "手杀", + daoji: "盗戟", + daoji_info: + "出牌阶段限一次,你可以弃置一张非基本牌并选择一名装备区里有牌的其他角色,你获得其装备区中的一张牌并使用之。若你以此法得到的牌是武器牌,则你使用此牌后对其造成1点伤害。", + xin_hansui: "手杀韩遂", + xin_hansui_prefix: "手杀", + xinniluan: "逆乱", + xinniluan_info: + "其他角色的结束阶段,若其本回合对除其以外的角色使用过牌,则你可以对其使用一张【杀】。若以此法使用的【杀】造成伤害,则你弃置其一张牌。", + xiaoxi_hansui: "骁袭", + xiaoxi_hansui_info: "你可以将一张黑色牌当做【杀】使用或打出。", + xin_zhangfei: "手杀界张飞", + xin_zhangfei_prefix: "手杀界", + liyong: "厉勇", + liyong2: "厉勇", + liyong3: "厉勇", + liyong_info: + "锁定技,若你于出牌阶段内使用的【杀】被【闪】抵消,则你获得如下效果:你本回合使用的下一张【杀】不可被响应且伤害+1,指定的目标本回合非锁定技失效,当此【杀】造成伤害后,若目标角色未死亡,你失去1点体力。", + gongsunkang: "公孙康", + juliao: "据辽", + juliao_info: "锁定技,其他角色计算与你的距离始终+X(X为场上势力数-1)。", + taomie: "讨灭", + taomie1: "讨灭", + taomie2: "讨灭", + taomie3: "讨灭", + taomie4: "讨灭", + taomie_info: + "当你受到伤害后或当你造成伤害后,你可以令伤害来源或受伤角色获得“讨灭”标记(如场上已有标记则转移给该角色);你和拥有“讨灭”标记的角色视为在彼此的攻击范围内,且当你对该角色造成伤害时,选择一项:1. 此伤害+1;2. 你获得其区域内的一张牌并可将之交给另一名角色;3. 依次执行前两项并于伤害结算后弃置其“讨灭”标记。", + xin_guohuai: "手杀界郭淮", + xin_guohuai_prefix: "手杀界", + mobilejingce: "精策", + mobilejingce_info: + "结束阶段,若此回合因使用或打出而置入弃牌堆的牌的数量不小于你的体力值,则你可以摸两张牌。", + xin_panzhangmazhong: "手杀界潘璋马忠", + xin_panzhangmazhong_prefix: "手杀界", + xinduodao: "夺刀", + xinduodao_info: "当你受到伤害后,你可以获得伤害来源装备区里的武器牌。", + xinanjian: "暗箭", + xinanjian_info: + "锁定技,当你使用【杀】指定目标后,若你不在目标角色攻击范围内,你选择一项:1. 令其无法响应此【杀】;2. 其受到此【杀】造成的伤害+1。", + xin_fuhuanghou: "手杀界伏寿", + xin_fuhuanghou_prefix: "手杀界", + xinzhuikong: "惴恐", + xinzhuikong_info: + "每轮限一次,其他角色的回合开始时,若其体力值不小于你,你可与其拼点。若你赢,其本回合无法使用牌指定除其以外的角色为目标;若你没赢,你获得其拼点的牌,然后其视为对你使用一张【杀】。", + xinqiuyuan: "求援", + xinqiuyuan_info: + "当你成为【杀】的目标时,你可以令另一名其他角色交给你一张除【杀】以外的基本牌,否则其也成为此【杀】的目标。", + xin_gongsunzan: "手杀界公孙瓒", + xin_gongsunzan_prefix: "手杀界", + re_dengai: "手杀界邓艾", + re_dengai_prefix: "手杀界", + flappybird: "飞鸟", + flappybird_info: "出牌阶段,你可游玩一局Flappy Bird。", + re_handang: "手杀界韩当", + re_handang_prefix: "手杀界", + nanhualaoxian: "手杀南华老仙", + nanhualaoxian_prefix: "手杀", + yufeng: "御风", + yufeng2: "御风", + yufeng_info: + "出牌阶段限一次,你可以表演“御风飞行”。若表演失败,则你摸X张牌。若表演成功,则你可以选择至多X名其他角色获得“御风”效果,然后摸X-Y张牌(准备阶段开始时,你进行判定。若结果为:红色,你跳过摸牌阶段;黑色,你跳过出牌阶段和弃牌阶段。X为你的得分。Y为你选择的角色数)。", + tianshu: "天书", + tianshu_info: + "出牌阶段开始时,若场上没有【太平要术】,则你可以弃置一张牌并选择一名角色。该角色获得并使用【太平要术】。", + re_jiangwei: "手杀界姜维", + re_jiangwei_prefix: "手杀界", + retiaoxin: "挑衅", + retiaoxin_info: + "出牌阶段限一次,你可以指定一名有牌的其他角色,该角色需对你使用一张【杀】,否则你弃置其一张牌。", + re_zhurong: "手杀界祝融", + re_zhurong_prefix: "手杀界", + relieren: "烈刃", + relieren_info: + "当你使用【杀】指定目标后,你可以和目标角色进行拼点。若你赢,你获得其一张牌。若你没赢,你获得对方的拼点牌,其获得你的拼点牌。", + zhouqun: "周群", + tiansuan: "天算", + tiansuan_info: + "出牌阶段限一次,若场上没有因你产生的“命运签”,则你可以抽取一张“命运签”,然后令一名角色获得“命运签”直到你的下回合开始。若你以此法抽取的“命运签”为:上上签,你观看其手牌;上上签/上签,你获得其区域内的一张牌。", + tiansuan_faq: "【命运签】说明", + tiansuan_faq_info: + "当你抽取“命运签”时,你可以令其中一种命运签的权重+1。
              上上签(权重1):当你受到伤害时,防止此伤害。
              上签(权重2):当你受到伤害时,你令伤害值改为1;当你受到1点伤害后,你摸一张牌。
              中签(权重3):当你受到伤害时,你令伤害属性改为火属性并将伤害值改为1。
              下签(权重2):当你受到伤害时,你令此伤害+1。
              下下签(权重1):当你受到伤害时,你令此伤害+1。你不能使用【酒】或【桃】。", + tiansuan2_0: "命运签", + tiansuan2_1: "命运签", + tiansuan2_2: "命运签", + tiansuan2_damage: "命运签", + tiansuan2_fire: "命运签", + tiansuan2_3: "命运签", + tiansuan2_4: "命运签", + ol_yujin: "手杀界于禁", + ol_yujin_prefix: "手杀界", + rejieyue: "节钺", + rejieyue_info: + "结束阶段开始时,你可以将一张牌交给一名其他角色。然后其选择一项:令你摸三张牌:或其保留一张手牌和装备区的牌,然后弃置其余的牌。", + xin_zhoucang: "手杀界周仓", + xin_zhoucang_prefix: "手杀界", + mobilezhongyong: "忠勇", + mobilezhongyong_info: + "当你于出牌阶段内使用的【杀】结算结束后,若没有目标角色使用【闪】响应过此【杀】,则你可获得此【杀】;否则你可选择一项:①获得目标角色使用的【闪】,然后可将此【杀】交给另一名其他角色。②将目标角色使用的【闪】交给另一名其他角色,然后你本回合使用【杀】的次数上限+1且下一张【杀】的伤害值基数+1。(你不能使用本回合因执行〖忠勇〗的效果得到的牌)", + xin_caifuren: "手杀界蔡夫人", + xin_caifuren_prefix: "手杀界", + xinqieting: "窃听", + xinqieting_info: + "其他角色的回合结束时,若其本回合内未对其他角色造成过伤害,则你可选择一项:①摸一张牌。②观看其两张手牌并获得其中的一张。③将其装备区内的一张牌移动至你的装备区。", + xinguixiu: "闺秀", + xinguixiu_info: "锁定技。结束阶段,若你的体力值为:奇数,你摸一张牌;偶数,你回复1点体力。", + re_zhonghui: "手杀界钟会", + re_zhonghui_prefix: "手杀界", + requanji: "权计", + requanji_info: + "出牌阶段结束时,若你的手牌数大于体力值,或当你受到1点伤害后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。", + xin_guyong: "手杀界顾雍", + xin_guyong_prefix: "手杀界", + xinshenxing: "慎行", + xinshenxing_info: + "出牌阶段限X次(X为你的体力值),你可以弃置两张牌,然后摸一张牌。若这两张牌颜色不同,则改为摸两张牌。", + xinbingyi: "秉壹", + xinbingyi_info: + "结束阶段,你可展示所有手牌。若这些牌的颜色或类型均相同,则你可以令至多X名角色各摸一张牌(X为你的手牌数)。", + qiaozhou: "手杀谯周", + qiaozhou_prefix: "手杀", + zhiming: "知命", + zhiming_info: "准备阶段开始时或弃牌阶段结束时,你摸一张牌,然后可以将一张牌置于牌堆顶。", + xingbu: "星卜", + xingbu_info: + "结束阶段,你可以亮出牌堆顶的三张牌,然后你可以根据X值(X为这三张牌中红色牌的数量),令一名其他角色获得对应的效果直到其下回合结束:①三张:其摸牌阶段多摸两张牌,使用【杀】的次数上限+1。②两张:其使用【杀】的次数上限-1,跳过弃牌阶段。③小于两张:其于准备阶段开始时弃置一张手牌。", + xin_sunluban: "手杀界孙鲁班", + xin_sunluban_prefix: "手杀界", + xinzenhui: "谮毁", + xinzenhui_info: + "出牌阶段限一次。当你使用【杀】或黑色普通锦囊牌指定目标时,你可选择另一名能成为此牌目标的其他角色并选择一项:①令其也成为此牌的目标。②获得其一张牌,然后将此牌的使用者改为该角色。", + xinjiaojin: "骄矜", + xinjiaojin_info: "当你受到男性角色造成的伤害时,你可以弃置一张装备牌并防止此伤害。", + xin_caozhen: "手杀界曹真", + xin_caozhen_prefix: "手杀界", + discretesidi: "司敌", + discretesidi_info: + "①当你使用的不为延时锦囊牌的牌结算结束后,你可选择一名R内不存在以a为第一序偶的二元序偶的其他角色a,并选择一名角色b,在关系R内建立二元序偶<a,b>(b对其他角色不可见)。②一名角色a使用不为延时锦囊牌的牌指定b为目标时,若(aRb)∧(此牌目标数为1)为真,则{你从R内移除<a,b>,且:若b为你,你摸一张牌;若b不为你,你可选择:⒈取消此牌的目标,然后若场上没有处于濒死状态的角色,则你对a造成1点伤害。⒉摸两张牌};否则{你清除R内以a为第一元素的二元序偶}。", + fuqian: "傅佥", + jueyong: "绝勇", + jueyong_info: + "锁定技。①当你不因〖绝勇〗成为唯一牌的目标时,若此牌不为转化牌且对应的实体牌牌数为1且不为【桃】或【酒】且你的“绝”数小于你的体力值,则你将此牌置于你的武将牌上,称为“绝”,且取消此牌的目标。②结束阶段开始时,若你有“绝”,则你令所有“绝”的原使用者依次对你使用所有“绝”,将无法使用的“绝”置入弃牌堆。", + poxiang: "破降", + poxiang_info: + "出牌阶段限一次。你可以将一张牌交给一名其他角色。你摸三张牌(不计入本回合的手牌上限),移去所有“绝”并失去1点体力。", + simafu: "司马孚", + xunde: "勋德", + xunde_info: + "一名角色受到伤害后,若你至其的距离不大于1,则你可判定。若判定结果:大于5,你令该角色获得判定牌;小于7,你令伤害来源弃置一张牌。", + chenjie: "臣节", + chenjie_info: + "一名角色的判定牌生效前,你可打出一张花色相同的牌。系统将你打出的牌作为新判定牌,将原判定牌置入弃牌堆。然后你摸两张牌。", + mayuanyi: "马元义", + jibing: "集兵", + jibing_info: + "①摸牌阶段开始时,若你的“兵”数小于势力数,则你可以改为将牌堆顶的两张牌置于你的武将牌上,称为“兵”。②你可以将一张“兵”当做【杀】或【闪】使用或打出。", + wangjing: "往京", + wangjing_info: + "锁定技。当你因〖集兵〗而使用或打出牌时,若对方是场上体力值最高的角色,则你摸一张牌。", + moucuan: "谋篡", + moucuan_info: "觉醒技。准备阶段,若你的“兵”数不小于势力数,则你减1点体力上限并获得〖兵祸〗。", + binghuo: "兵祸", + binghuo_info: + "一名角色的结束阶段开始时,若你本回合内因〖集兵〗而使用或打出过牌,则你可令一名角色判定。若判定结果为黑色,则你对其造成1点雷属性伤害。", + yanpu: "阎圃", + huantu: "缓图", + huantu_info: + "每轮限一次。一名角色的摸牌阶段开始前,若其在你攻击范围内,则你可以交给其一张牌并令其跳过此阶段。然后你于此回合的结束阶段选择一项:①令其回复1点体力并摸两张牌。②你摸三张牌,然后交给其两张手牌。", + bihuo: "避祸", + bihuo_info: + "限定技。一名角色脱离濒死状态时,你可以令其摸三张牌,然后其他角色计算至其的距离时+X直到本轮结束(X为角色数)。", + sunhanhua: "手杀孙寒华", + sunhanhua_prefix: "手杀", + chongxu: "冲虚", + chongxu_info: + "出牌阶段限一次,你可以随机演奏一首音乐,并根据完成度来获得相应的分数(至多五分)。然后你可修改〖妙剑〗或〖莲华〗(消耗3分),并使用剩余的分数进行摸牌(每张2分)。", + chongxu_faq: "目前的曲库", + chongxu_faq_info: + " 
              《鸟之诗》- 折户伸治
              《竹取飛翔 ~ Lunatic Princess》- ZUN
              《ignotus》- ak+q
              《Super Mario 3D World Theme》- 横田真人
              《只因你太美》- SWIN-S
              《Croatian Rhapsody》- Maksim
              《罗刹海市》- 刀郎
              《Pigstep (Stereo Mix)》- Lena Raine", + miaojian: "妙剑", + miaojian_info: + "出牌阶段限一次。你可将一张【杀】当做刺【杀】使用,或将一张锦囊牌当做【无中生有】使用。", + miaojian1: "妙剑·改", + miaojian1_info: + "出牌阶段限一次。你可将一张基本牌当做刺【杀】使用,或将一张非基本牌当做【无中生有】使用。", + miaojian2: "妙剑·极", + miaojian2_info: "出牌阶段限一次。你可视为使用一张刺【杀】或【无中生有】。", + shhlianhua: "莲华", + shhlianhua_info: "当你成为【杀】的目标后,你摸一张牌。", + shhlianhua1: "莲华·改", + shhlianhua1_info: + "当你成为【杀】的目标后,你摸一张牌。然后你进行判定,若结果为黑桃,则此【杀】对你无效。", + shhlianhua2: "莲华·极", + shhlianhua2_info: + "当你成为【杀】的目标后,你摸一张牌。然后此【杀】的使用者选择一项:①弃置一张牌。②令此【杀】对你无效。", + re_yufan: "手杀界虞翻", + re_yufan_prefix: "手杀界", + rezongxuan: "纵玄", + rezongxuan_place: "纵玄", + rezongxuan_info: + "当你的牌因弃置而进入弃牌堆后,你可以将其以任意顺序置于牌堆顶。出牌阶段限一次,你可以摸一张牌,然后将一张牌置于牌堆顶。", + yj_huangzhong: "☆黄忠", + yj_huangzhong_prefix: "☆", + spshidi: "势敌", + spshidi_info: + "转换技,锁定技。①准备阶段/结束阶段开始时,若你发动此分支的累计次数为奇数/偶数,则你获得一个“☯”。②若你的“☯”数为偶数,则你至其他角色的距离-1,且你使用的黑色【杀】不可被响应。③若你的“☯”数为奇数,则其他角色至你的距离+1,且你不可响应红色【杀】。", + spyishi: "义释", + spyishi_info: + "当你对装备区有牌的其他角色造成伤害时,你可令此伤害-1,然后获得其装备区内的一张牌。", + spqishe: "骑射", + spqishe_info: "你可以将一张装备牌当做【酒】使用。你的手牌上限+X(X为你装备区内的牌数)。", + sp_maojie: "毛玠", + bingqing: "秉清", + bingqing_info: + "当你于出牌阶段内使用的牌结算结束后,若你于本阶段内使用的所有已结算结束的其他牌与此牌花色均不相同,则你可根据X的值执行对应效果:为2,你令一名角色摸两张牌;为3,你弃置一名角色区域内的一张牌;为4,你对一名其他角色造成1点伤害。(X为你本阶段内使用过的已结算结束的牌中包含的花色数)", + yingfeng: "迎奉", + yingfeng_info: + "准备阶段,你可以令一名角色获得“奉”标记并移除场上所有其他的“奉”标记。有“奉”标记的角色使用牌没有距离限制。", + xin_sunxiu: "手杀界孙休", + xin_sunxiu_prefix: "手杀界", + mobileyanzhu: "宴诛", + mobileyanzhu_info: + "出牌阶段限一次,你可以令一名有牌的其他角色选择一项:①你获得其装备区里所有的牌,然后你失去技能〖宴诛〗并修改技能〖兴学〗。②你获得其区域里的一张牌。", + mobilexingxue: "兴学", + mobilexingxue_info: + "结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶(X为你的体力值)。", + mobilexingxuex: "兴学·改", + mobilexingxuex_info: + "结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶或交给一名其他目标角色(X为你的体力上限)。", + re_wuguotai: "手杀界吴国太", + re_wuguotai_prefix: "手杀界", + reganlu: "甘露", + reganlu_info: + "出牌阶段限一次,你可以选择装备区牌数之差的绝对值不大于X的两名角色或包含你在内的两名角色,然后交换这两名角色装备区内的牌。(X为你已损失的体力值)", + taoqian: "手杀陶谦", + taoqian_prefix: "手杀", + miheng: "手杀祢衡", + miheng_prefix: "手杀", + re_gaoshun: "手杀界高顺", + re_gaoshun_prefix: "手杀界", + peixiu: "裴秀", + xingtu: "行图", + xingtu1: "倍数", + xingtu2: "约数", + xingtu_info: + "锁定技。你使用点数为X的倍数的牌无次数限制,你使用点数为X的约数的牌时摸一张牌(X为你本局游戏使用的上一张牌的点数)。", + juezhi: "爵制", + juezhi_info: + "出牌阶段,你可以弃置至少两张牌,然后从牌堆中获得一张点数为Y的牌(Y为这些牌的点数和对13取余,余数为0时Y取13)。", + sp_jianggan: "手杀蒋干", + sp_jianggan_prefix: "手杀", + spdaoshu: "盗书", + spdaoshu_info: + "每轮限一次。一名敌方角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。", + spdaoshu_info_identity: + "每轮限一次。一名其他角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。", + spdaoshu_info_guozhan: + "每轮限一次。一名其他角色的出牌阶段开始时,若其有手牌,则你可以令其视为使用一张【酒】。其须声明一个基本牌的牌名,然后你判断其手牌区内是否有该牌名的牌。若你判断正确,则你获得其两张手牌。", + mbdaoshu: "盗书", + mbdaoshu_info: + "出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你和队友观看其手牌并猜测其伪装的手牌,猜对的角色对其造成1点伤害,猜错的角色随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。", + mbdaoshu_info_identity: + "出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你观看其手牌并猜测其伪装的手牌。若猜中,你对其造成1点伤害;若猜错,你随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。", + mbdaoshu_info_guozhan: + "出牌阶段限一次,你可以选择一名手牌数大于两张的其他角色,其随机获得三个牌名并将一张手牌的牌名伪装成其中一个与原牌名不同的牌名,然后你观看其手牌并猜测其伪装的手牌。若猜中,你对其造成1点伤害;若猜错,你随机弃置两张手牌(手牌数不足两张则改为失去1点体力)。", + spdaizui: "戴罪", + spdaizui2: "戴罪", + spdaizui_info: + "限定技。当你受到伤害值不小于体力值的伤害时,你可防止此伤害并将此伤害渠道对应的所有实体牌置于伤害来源的武将牌上,称为“释”。本回合结束时,其获得所有“释”。", + re_caiwenji: "手杀界蔡琰", + re_caiwenji_prefix: "手杀界", + re_bulianshi: "手杀界步练师", + re_bulianshi_prefix: "手杀界", + reanxu: "安恤", + reanxu_info: + "出牌阶段限一次,你可以选择两名其他角色,令其中一名角色获得另一名角色的一张牌。若以此法移动的牌不来自装备区,则你摸一张牌。然后你可以令二者中手牌数较少的一名角色摸一张牌。", + xin_jushou: "手杀界沮授", + xin_jushou_prefix: "手杀界", + xinjianying: "渐营", + xinjianying_info: + "①当你于出牌阶段内使用与此阶段你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。②出牌阶段限一次,你可以将一张牌当做任意基本牌使用。若你于此阶段内使用的上一张牌有花色,则此牌的花色视为上一张牌的花色。", + re_xunyu: "手杀界荀彧", + re_xunyu_prefix: "手杀界", + rejieming: "节命", + rejieming_info: + "当你受到1点伤害后,你可以令一名角色摸两张牌。然后若其手牌数小于体力上限,则你摸一张牌。", + xin_quancong: "手杀界全琮", + xin_quancong_prefix: "手杀界", + sbyaoming: "邀名", + sbyaoming_info: + "蓄力技(2/4)。①当你受到1点伤害后,你可以获得1点蓄力值。②出牌阶段或当你受到伤害后,你可消耗1点蓄力值并选择一项:⒈弃置一名手牌数不小于你的角色的一张牌。⒉令一名手牌数不大于你的角色摸一张牌。若你上次发动〖邀名②〗时未获得过蓄力值且你选择的选项和上次不同,则你获得1点蓄力值。", + ruanhui: "阮慧", + mingcha: "明察", + mingcha_info: + "摸牌阶段开始时,你亮出牌堆顶的三张牌。若这三张牌中有点数小于9的牌,则你可以放弃摸牌并获得这些牌,然后你可以获得一名其他角色的随机一张牌。", + jingzhong: "敬重", + jingzhong_info: + "弃牌阶段结束时,若你于本阶段内弃置过至少两张黑色牌,则你可以选择一名其他角色并获得如下效果直到其回合结束:每阶段限三次,其于出牌阶段内使用的牌结算结束后,你获得此牌对应的实体牌。", + xin_mamidi: "手杀马日磾", + xin_mamidi_prefix: "手杀", + chengye: "承业", + chengye_info: + "锁定技。①其他角色使用的非转化牌结算结束后,或其他角色的装备牌和延时锦囊牌进入弃牌堆后,或有延时锦囊牌因其他角色执行判定阶段的流程而进入弃牌堆后,若你的“六经”有空缺的位置可以置入此牌,则你将此牌置于你武将牌上,填补“六经”的对应位置。②出牌阶段开始时,若你的“六经”没有空缺的位置,则你获得所有“六经”。", + chengye_append: + '
            • 《诗经》:伤害类锦囊牌
            • 《尚书》:基本牌
            • 《仪礼》:无懈可击
            • 《易经》:无中生有
            • 《乐经》:乐不思蜀
            • 《春秋》:装备牌', + buxu: "补叙", + buxu_backup: "补叙", + buxu_info: + "出牌阶段,若你的“六经”中有空缺的位置,则你可以弃置X+1张牌并选择一种空缺的“六经”(X为你本阶段内发动过〖补叙〗的次数)。系统从牌堆或弃牌堆中检索一张对应的牌,然后你将此牌置于你武将牌上,填补“六经”的对应位置。", + re_dianwei: "手杀界典韦", + re_dianwei_prefix: "手杀界", + liuye: "手杀刘晔", + liuye_prefix: "手杀", + sp_caosong: "手杀曹嵩", + sp_caosong_prefix: "手杀", + yijin: "亿金", + yijin_info: + "锁定技。①游戏开始时,你获得“膴仕”、“金迷”、“贾凶”、“通神”、“拥蔽”、“厚任”各1枚(均称为“金”)。②出牌阶段开始时,你选择一名没有“金”的其他角色。你交给其1枚“金”,且令其获得对应效果。③一名角色的回合结束后,若其有你交给其的“金”,其移去此“金”。④当你死亡时,移去场上所有你交出的“金”。⑤回合开始时,若你没有“金”,你死亡。", + yijin_wushi: "膴仕", + yijin_wushi_info: "锁定技。①摸牌阶段,你多摸四张牌。②你使用【杀】的次数上限+1。", + yijin_jinmi: "金迷", + yijin_jinmi_info: "锁定技。回合开始时,你跳过下一个出牌阶段和弃牌阶段。", + yijin_guxiong: "贾凶", + yijin_guxiong_info: "锁定技。①出牌阶段开始时,你失去1点体力。②你的手牌上限-3。", + yijin_tongshen: "通神", + yijin_tongshen_info: "锁定技。当你受到非雷电伤害时,防止之。", + yijin_yongbi: "拥蔽", + yijin_yongbi_info: "锁定技。准备阶段,你跳过下一个摸牌阶段。", + yijin_houren: "厚任", + yijin_houren_info: "锁定技。回合结束时,你回复3点体力。", + guanzong: "惯纵", + guanzong_info: "出牌阶段限一次。你可以令一名其他角色视为对另一名其他角色造成过1点伤害。", + yangfu: "杨阜", + jiebing: "借兵", + jiebing_info: + "锁定技。当你受到伤害后,你选择来源外的一名其他角色,随机获得其一张牌并展示。若此牌为装备牌,你使用之。", + hannan: "扞难", + hannan_info: "出牌阶段限一次。你可以与一名角色拼点,赢的角色对没赢的角色造成2点伤害。", + xin_wuyi: "手杀界吴懿", + xin_wuyi_prefix: "手杀界", + sbbenxi: "奔袭", + sbbenxi_info: + "出牌阶段开始时,你可以弃置至少一张牌,然后你于此阶段获得如下效果:①你至其他角色距离-X;②当你使用的下一张基本牌或普通锦囊牌A选择目标后,你可以额外指定X名距离为1的角色为目标;③牌A结算结束后,若此牌造成过伤害,你摸五张牌(X为你以此法弃置的牌数)。", + xin_zhuzhi: "手杀界朱治", + xin_zhuzhi_prefix: "手杀界", + sbanguo: "安国", + sbanguo_info: + "①游戏开始时,你令一名其他角色获得1枚“安国”标记(有“安国”的角色手牌上限基数等于体力上限)。②出牌阶段开始时,你可以将一名有“安国”的角色的所有“安国”移动给一名本局游戏未获得过“安国”的其他角色。③当你受到伤害时,若有有“安国”的角色且伤害值不小于你的体力值且此伤害没有来源或来源没有“安国”,防止此伤害。④一名角色进入濒死状态时,若其有你因〖安国①〗获得的“安国”,你移去其该“安国”,令其将体力回复至1点。然后你选择一项:1.若你的体力值大于1,你失去体力至1点;2.若你的体力上限大于1,你将体力上限减至1。最后你令其获得1点护甲。", + wangjun: "手杀王濬", + wangjun_prefix: "手杀", + zhujian: "筑舰", + zhujian_info: "出牌阶段限一次。你可以令至少两名装备区里有牌的角色各摸一张牌。", + duansuo: "断索", + duansuo_info: + "出牌阶段限一次。你可以重置任意名处于连环状态的角色,然后对这些角色各造成1点火焰伤害。", + sp_pengyang: "手杀彭羕", + sp_pengyang_prefix: "手杀", + spdaming: "达命", + spdaming_info: + "①游戏开始时,你获得1点“达命”值。②其他角色A的出牌阶段限一次。其可以交给你一张牌,然后你选择另一名其他角色B。若B有与此牌相同类型的牌,其将一张该类型的牌交给A,你获得1点“达命”值;否则你将此牌交给A。", + spxiaoni: "嚣逆", + spxiaoni_info: + "①出牌阶段限一次。若你的“达命”值大于0,你可以将一张牌当任意一种【杀】或伤害类锦囊牌使用。然后你减少等同于此牌指定目标数的“达命”值。②你的手牌上限基数为X(X为“达命”值,且至多为你的体力值,至少为0)。", + xin_zhuhuan: "手杀界朱桓", + xin_zhuhuan_prefix: "手杀界", + xinpingkou: "平寇", + xinpingkou_info: + "回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。然后你从牌堆中获得一张装备牌。", + xin_caoxiu: "手杀界曹休", + xin_caoxiu_prefix: "手杀界", + xinqingxi: "倾袭", + xinqingxi_info: + "每回合限一次。当你对其他角色造成伤害时,你可以令其选择一项:1.弃置X张手牌(X为4减去你至其的距离,至少为1);2.令此伤害+1。", + yj_weiyan: "☆魏延", + yj_weiyan_prefix: "☆", + mbguli: "孤厉", + mbguli_info: + "出牌阶段限一次。你可以将所有手牌当做一张无视防具的【杀】使用。此牌结算结束后,若此牌造成过伤害,你可以失去1点体力并将手牌摸至X张(X为你的体力上限)。", + mbaosi: "骜肆", + mbaosi_info: + "锁定技。当你于出牌阶段对一名攻击范围内的角色造成伤害后,你于此阶段对其使用牌无次数限制。", + xin_zhoutai: "手杀界周泰", + xin_zhoutai_prefix: "手杀界", + re_yanwen: "手杀界颜良文丑", + re_yanwen_prefix: "手杀界", + qianzhao: "手杀牵招", + qianzhao_prefix: "手杀", + mbshihe: "势吓", + mbshihe_info_identity: + "出牌阶段限一次。你可以与一名角色拼点。若你:赢,当其于其下回合结束前对你造成伤害时,取消之;没赢,你随机弃置一张牌。", + mbshihe_info: + "出牌阶段限一次。你可以与一名角色拼点。若你:赢,当其于其下回合结束前对你和你的友方角色造成伤害时,取消之;没赢,你随机弃置一张牌。", + mbzhenfu: "镇抚", + mbzhenfu_info: "结束阶段,若你本回合因弃置失去过牌,你可以令一名其他角色获得1点护甲。", + shichangshi: "十常侍", + mbdanggu: "党锢", + mbdanggu_info: + "锁定技。①游戏开始时,你获得十张“常侍”牌,然后你进行一次结党。②当你修整结束后,你进行一次结党并摸一张牌。③若你有亮出的“常侍”牌,你视为拥有这些牌的技能。", + mbdanggu_faq: "关于结党", + mbdanggu_faq_info: + "
              系统随机选择一张未亮出过的“常侍”牌,然后选择四张未亮出过的“常侍”牌。你观看前者,然后从后者中选择一名认可前者的“常侍”牌。然后若此时不为双将模式,你将这两张武将牌作为你的武将牌(不移除原有技能);否则你获得这两张武将牌上的技能。", + mbdanggu_faq2: "关于认可", + mbdanggu_faq2_info: + "
              双向不认可常侍为固定组合:
            • 郭胜、段珪
            • 韩悝、毕岚
              单向不认可常侍为系统随机分配。
              每次结党至多存在一张不认可主将的常侍牌,且若此次结党仅有一张常侍牌,则不会存在不认可情况。", + mbmowang: "殁亡", + mbmowang_info: + "锁定技。①当你死亡前,若你有未亮出的“常侍”牌且体力上限大于0,你将死亡改为修整至你的下个回合开始前,然后你复原武将牌,且不于此次死亡事件中进行展示身份牌、检测游戏胜利条件与执行奖惩的流程。②回合结束后,你死亡。", + mbmowang_faq: "关于修整", + mbmowang_faq_info: "
              将武将牌移出游戏(视为你存活)。当该角色修整结束,其移回游戏。", + scs_zhangrang: "张让", + scstaoluan: "滔乱", + scstaoluan_info: "出牌阶段限一次。你可以将一张牌当任意一种基本牌或普通锦囊牌使用。", + scs_zhaozhong: "赵忠", + scschiyan: "鸱咽", + scschiyan_info: + "①当你使用【杀】指定目标后,你可以将其的一张牌置于其武将牌上,然后其于当前回合结束时获得这些牌。②当你因执行【杀】的效果对一名角色造成伤害时,若该角色的手牌数和装备区内的牌数均不大于你,此伤害+1。", + scs_sunzhang: "孙璋", + scszimou: "自谋", + scszimou_info: + "锁定技。出牌阶段,当你使用第二/四/六张牌时,你从牌堆中获得一张【酒】/【杀】/【决斗】。", + scs_bilan: "毕岚", + scspicai: "庀材", + scspicai_info: + "出牌阶段限一次。你可进行判定牌不置入弃牌堆的判定。若判定结果与本次发动技能时的其他判定结果的花色均不相同,则你可以重复此流程。然后你将所有位于处理区的判定牌交给一名角色。", + scs_xiayun: "夏恽", + scsyaozhuo: "谣诼", + scsyaozhuo_info: + "出牌阶段限一次。你可以与一名角色拼点,若你赢,其跳过下一个摸牌阶段;若你没赢,你弃置两张牌。", + scs_hankui: "韩悝", + scsxiaolu: "宵赂", + scsxiaolu_info: + "出牌阶段限一次。你可以摸两张牌,然后选择一项:1.弃置两张牌;2.将两张牌交给一名其他角色。", + scs_lisong: "栗嵩", + scskuiji: "窥机", + scskuiji_info: + "出牌阶段限一次。你可以观看一名其他角色的手牌,然后弃置你与其的共计四张花色各不相同的手牌。", + scs_duangui: "段珪", + scschihe: "叱吓", + scschihe_info: + "当你使用【杀】指定唯一目标后,你可亮出牌堆顶的两张牌,令此【杀】的伤害值基数+X(X为亮出牌中花色与此【杀】相同的牌数),且目标角色不能使用亮出牌包含的花色的牌响应此【杀】。", + scs_guosheng: "郭胜", + scsniqu: "逆取", + scsniqu_info: "出牌阶段限一次。你可以对一名角色造成1点火焰伤害。", + scs_gaowang: "高望", + scsanruo: "安弱", + scsanruo_info: + "你可以将一张♥牌当【桃】、♦牌当火【杀】、♣牌当【闪】、♠牌当【无懈可击】使用。当你以此法使用或打出【杀】或【闪】时,你可以获得对方的一张牌;当你以此法使用【桃】时,你可以获得一名其他角色的一张牌;当你以此法使用【无懈可击】时,你可以获得此牌响应的普通锦囊牌的使用者的一张牌。", + scsmiaoyu: "妙语", + scsmiaoyu_info: + "你可以将至多两张相同花色的牌按照以下规则使用或打出:♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】。若你以此法使用了两张红色牌,则此牌回复值或伤害值+1。若你以此法使用了两张黑色牌,则你弃置当前回合角色一张牌。", + re_xiaoqiao: "手杀界小乔", + re_xiaoqiao_prefix: "手杀界", + xin_sunliang: "手杀孙亮", + xin_sunliang_prefix: "手杀", + xinkuizhu: "溃诛", + xinkuizhu_info: + "弃牌阶段结束后,你可以选择一项:1.令至多X名角色各摸一张牌。2.对任意名体力值之和为X的角色造成1点伤害,若你以此法选择的角色数不小于2,你失去1点体力。(X为你此阶段弃置的牌数)", + xinzhizheng: "掣政", + xinzhizheng_info: + "锁定技,你的出牌阶段内,攻击范围内不包含你的其他角色不能成为你使用牌的目标。出牌阶段结束时,若你本阶段内使用的牌数小于这些角色的数量,则你弃置其中一名角色的一张牌。", + xinlijun: "立军", + xinlijun_info: + "主公技,其他吴势力角色于其回合内使用【杀】结算完毕后,其可以将此【杀】对应的实体牌交给你,然后你可以令其摸一张牌。", + xin_zhangyi: "手杀界张嶷", + xin_zhangyi_prefix: "手杀界", + xinwurong: "怃戎", + xinwurong_info: + "出牌阶段限一次,你可以与一名其他角色进行谋弈:
            • 若你选择“镇压”且其选择“反抗”,你对其造成1点伤害,然后你摸一张牌。
            • 若你选择“安抚”且其选择“归顺”,其须交给你两张牌(若其牌数不足两张,则改为令其跳过其下个摸牌阶段)。
            • 若你选择“镇压”且其选择“归顺”,你获得其一张牌,然后你交给其两张牌。
            • 若你选择“安抚”且其选择“反抗”,你受到1点伤害,然后你摸两张牌。", + xin_guozhao: "手杀郭照", + xin_guozhao_prefix: "手杀", + yichong: "易宠", + yichong_info: + "①准备阶段,你可以选择一名其他角色并选择一个花色,然后你获得其所有此花色的装备牌和其一张此花色的手牌,移除场上的所有“雀”标记,令其获得“雀”标记直到你的下个回合开始。②拥有“雀”标记的角色获得你最后一次发动〖易宠①〗选择的花色的牌后,你获得这些牌(你至多通过每个“雀”得到一张牌)。", + wufei: "诬诽", + wufei_info: + "若场上存在拥有“雀”标记的角色A,则:①当你使用【杀】或伤害类锦囊牌指定第一个目标后,你令A成为此牌伤害来源。②当你受到伤害后,若A的体力值大于3,则你可以令A受到1点无来源伤害。", + yj_zhoubuyi: "☆周不疑", + yj_zhoubuyi_prefix: "☆", + mbhuiyao: "慧夭", + mbhuiyao_info: + "出牌阶段限一次。你可以受到1点无来源伤害,然后你选择一名其他角色,令其视为对另一名角色造成过1点伤害。", + mbquesong: "雀颂", + mbquesong_info: + "一名角色的结束阶段,若你于本回合受到过伤害,你可以令一名角色选择一项:1.摸X张牌并复原武将牌(X为3,若其装备区非宝物牌牌数不小于三张则X为2);2.回复1点体力。", + xin_yuanshao: "手杀界袁绍", + xin_yuanshao_prefix: "手杀界", + re_baosanniang: "手杀鲍三娘", + re_baosanniang_prefix: "手杀", + re_liushan: "手杀界刘禅", + re_liushan_prefix: "手杀界", + re_sunben: "界孙笨", + re_sunben_prefix: "界", + re_zhangzhang: "手杀界张昭张纮", + re_zhangzhang_prefix: "手杀界", + re_caozhi: "手杀界曹植", + re_caozhi_prefix: "手杀界", + re_sunjian: "手杀界孙坚", + re_sunjian_prefix: "手杀界", + sunru: "手杀孙茹", + sunru_prefix: "手杀", + pangdegong: "手杀庞德公", + pangdegong_prefix: "手杀", + zhaotongzhaoguang: "手杀赵统赵广", + zhaotongzhaoguang_prefix: "手杀", + re_liru: "手杀界李儒", + re_liru_prefix: "手杀界", + re_chenqun: "手杀界陈群", + re_chenqun_prefix: "手杀界", + old_yuanshu: "手杀袁术", + old_yuanshu_prefix: "手杀", + baoxin: "鲍信", + mutao: "募讨", + mutao_info: + "出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】置于武将牌上,然后将这些牌依次随机交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。", + yimou: "毅谋", + yimou_info: + "当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色,然后摸一张牌。", + jiangji: "手杀蒋济", + jiangji_prefix: "手杀", + jilun: "机论", + jilun_info: + "①当你受到伤害后,若你拥有技能〖急筹〗,则你可以一项:1.摸两张牌。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: + "你可以将一张♣手牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。", + mb_sunluyu: "手杀孙鲁育", + mb_sunluyu_prefix: "手杀", + mbmumu: "穆穆", + mbmumu_info: + "出牌阶段开始时,你可以选择一项:1.弃置场上的一张装备牌;2.获得场上的一张防具牌,然后你本回合不能使用或打出【杀】。", + mbmeibu: "魅步", + mbmeibu_info: + "其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌,令该角色于本回合内获得〖止息〗。若你以此法弃置的牌不是【杀】或黑色锦囊牌,则本回合其与你的距离视为1。", + mbzhixi: "止息", + mbzhixi_info: + "锁定技。出牌阶段,若你于此阶段使用过的牌数不小于X,你不能使用牌(X为你的体力值);当你使用锦囊牌时,你结束此阶段。", + yanxiang: "阎象", + kujian: "苦谏", + kujian_info: + "出牌阶段限一次,你可以将至多两张手牌称为“谏”并交给一名其他角色,然后你获得以下效果:当其他角色使用或打出牌后,若其中有“谏”,你与其各摸两张牌;当其他角色不因使用或打出而失去牌后,若其中有“谏”,你与其各弃置一张牌。", + mb_xianglang: "手杀向朗", + mb_xianglang_prefix: "手杀", + naxue: "纳学", + naxue_info: + "你可以跳过出牌阶段。若如此做,你可以弃置任意张牌并摸等量的牌,然后你可以交给至多两名其他角色各一张手牌。", + yijie: "遗诫", + yijie_info: + "锁定技。当你死亡时,你令所有其他角色将体力回复或失去至X(X为所有其他角色的体力之和除以所有其他角色数,向下取整,且X至少为1)。", + mb_chengui: "手杀陈珪", + mb_chengui_prefix: "手杀", + guimou: "诡谋", + guimou_info: + "锁定技。游戏开始时/回合结束时,你随机/须选择以下一项直到你的下个准备阶段:①记录场上期间角色使用牌数;②记录期间场上角色弃置牌数;③记录期间场上角色获得牌数。准备阶段,你可以选择一名场上对应记录数值最少的其他角色,观看其手牌并选择其中一张牌,然后你将此牌交给另一名其他角色或弃置此牌。", + zhouxian: "州贤", + zhouxian_info: + "锁定技。当你成为其他角色使用的伤害类卡牌的目标后,你亮出牌堆顶的三张牌,然后其须选择一项:①弃置一张与亮出牌之一类别相同的牌;②令此牌对你无效。", + mb_huban: "手杀胡班", + mb_huban_prefix: "手杀", + mbyilie: "义烈", + mbyilie2: "义烈", + mbyilie3: "义烈", + mbyilie_info: + "锁定技。①游戏开始时,你选择一名其他角色,然后你获得以下效果:其受到伤害时,若你没有“烈”,则你获得等同于伤害值的“烈”标记,然后防止此伤害;其对其他角色造成伤害后,你回复1点体力。②结束阶段,你摸一张牌并失去X点体力,然后移去所有“烈”(X为你拥有的“烈”标记数)。", + muludawang: "木鹿大王", + shoufa: "兽法", + shoufa_info: + "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。", + shoufa_info_doudizhu: + "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于1的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。", + yuxiang: "御象", + yuxiang_info: + "锁定技,若你有护甲值,则:①你计算与其他角色的距离-1,其他角色计算与你的距离+1;②当你受到火焰伤害时,此伤害+1。", + zhoulin: "咒鳞", + zhoulin_info: + "限定技,出牌阶段,你可以获得2点护甲值,然后选择一个“兽法”效果,你发动〖兽法〗的执行效果改为你选择的效果直到你的下个回合结束。", + xin_huojun: "手杀霍峻", + xin_huojun_prefix: "手杀", + sidai: "伺怠", + sidai_info: + "限定技,出牌阶段,你可以将手牌区内的所有基本牌当做【杀】使用。若此牌对应的实体牌中:包含【闪】,则目标角色成为此牌的目标后,需弃置一张基本牌,否则不可响应此牌;包含【桃】,则当目标角色受到此牌的伤害后,其减1点体力上限。", + jieyu: "竭御", + jieyu_info: + "结束阶段,你可以从弃牌堆中获得共X张不同牌名的基本牌(X为4-你上次发动〖竭御〗至今你成为其他角色使用伤害类卡牌目标的次数,且X至少为1)。", + jieyu_info_identity: + "结束阶段,你可以从弃牌堆中获得共X张不同牌名的基本牌(X为3-你上次发动〖竭御〗至今你成为其他角色使用伤害类卡牌目标的次数,且X至少为1)。", + yangfeng: "杨奉", + mbxuetu: "血途", + mbxuetu_info: + "转换技。出牌阶段限一次,阴:你可以弃置一张牌,然后令一名角色回复1点体力;阳:你可以失去1点体力,然后令一名角色摸两张牌。", + mbxuetu_achieve: "血途·成功", + mbxuetu_achieve_info: + "出牌阶段各限一次。⒈你可以弃置一张牌,然后令一名角色回复1点体力;⒉你可以失去1点体力,然后令一名角色摸两张牌。", + mbxuetu_fail: "血途·失败", + mbxuetu_fail_info: + "转换技。出牌阶段限一次,阴:你可以回复1点体力,然后令一名角色弃置两张牌;阳:你可以摸一张牌,然后对一名角色造成1点伤害。", + mbweiming: "威命", + mbweiming_info: + "使命技,锁定技。①出牌阶段开始时,你记录一名未以此法记录过的角色。②成功:当你杀死一名未被〖威命①〗记录过的角色后,修改〖血途〗为成功版本。③失败:当一名被〖威命①〗记录过的角色死亡后,你修改〖血途〗为失败版本。", + lizhaojiaobo: "李昭焦伯", + mbzuoyou: "佐佑", + mbzuoyou_info: + "转换技。出牌阶段限一次,阴:你可以令一名角色摸两张牌,然后其弃置一张手牌;阳:你可以令一名手牌数不少于二的角色弃置两张手牌,然后其获得1点护甲。", + mbshishou: "侍守", + mbshishou_info: + "锁定技。当你发动〖佐佑〗后,若目标角色不为你,你执行〖佐佑〗中目标角色未执行的一项。", + chengji: "成济", + mbkuangli: "狂戾", + mbkuangli_info: + "锁定技。①出牌阶段开始时,你随机令场上任意名其他角色获得“狂戾”标记。②出牌阶段限两次。当你使用牌指定有“狂戾”的角色为目标后,你与其各随机弃置一张牌,然后你摸一张牌。③回合结束时,你移除所有角色的“狂戾”。", + mbxiongsi: "凶肆", + mbxiongsi_info: + "限定技。出牌阶段,若你的手牌数不少于三张,你可以弃置所有手牌,然后令所有其他角色依次失去1点体力。", + mb_sp_guanqiujian: "SP毌丘俭", + mb_sp_guanqiujian_prefix: "SP", + mbcuizhen: "摧阵", + mbcuizhen_info_identity: + "①游戏开始时,你可以废除至多两名其他角色的武器栏。②当你于出牌阶段使用伤害类牌指定其他角色为目标后,若目标角色的手牌数不小于体力值,你可以废除其武器栏。③摸牌阶段,你令额定摸牌数+X(X为所有角色被废除的武器栏数之和,至多为2)。", + mbcuizhen_info: + "①当你于出牌阶段使用伤害类牌指定其他角色为目标后,若目标角色的手牌数不小于体力值,你可以废除其武器栏。②摸牌阶段,你令额定摸牌数+X(X为所有角色被废除的武器栏数之和,至多为2)。", + mbkuili: "溃离", + mbkuili_info: + "锁定技。当你受到伤害后,你弃置等同于伤害值的手牌;若来源有被废除的武器栏,你令其恢复武器栏。", + mb_caomao: "手杀曹髦", + mb_caomao_prefix: "手杀", + mbqianlong: "潜龙", + mbqianlong_info: + "①游戏开始时,你获得20枚“道心”标记。②当你得到牌后/受到1点伤害后/造成1点伤害后,你获得5/10/15枚“道心”(上限为100枚)。③若你的“道心”数不小于25/50/75/100,你视为拥有〖清正〗/〖酒诗〗/〖放逐〗/〖决进〗。", + mbcmqingzheng: "清正", + mbcmqingzheng_info: + "出牌阶段开始时,你可以弃置两种花色的所有手牌,并观看一名有手牌的其他角色的手牌,你弃置其中一种花色的所有牌。若其被弃置的牌数小于你以此法弃置的牌数,你对其造成1点伤害。", + mbcmjiushi: "酒诗", + mbcmjiushi_info: + "①当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。②当你受到伤害后,若你的武将牌背面向上,你可以翻面。③当你翻面后,你获得牌堆里的一张锦囊牌。", + mbcmfangzhu: "放逐", + mbcmfangzhu_info: + "出牌阶段限一次。你可以选择一名其他角色,选择一项:⒈令其不能使用手牌中的非锦囊牌直到其回合结束;⒉令其所有非Charlotte技能失效直到其回合结束。", + mbjuejin: "决进", + mbjuejin_info: + "限定技。出牌阶段,你可以令所有角色依次将体力回复或失去至1并获得X点护甲(X为一名角色以此法变化的体力值)。然后你增加如下“向死存魏”的全局技能:当有牌进入弃牌堆后,系统将这些牌中的【闪】、【桃】和【酒】移出游戏。", + mbweitong: "卫统", + mbweitong_info: "主公技。游戏开始时,若你有〖潜龙〗,你获得20X枚“道心”(X为其他魏势力角色数)。", - mobile_standard:'手杀异构·标准包', - mobile_shenhua_feng:'手杀异构·其疾如风', - mobile_shenhua_huo:'手杀异构·侵掠如火', - mobile_shenhua_lin:'手杀异构·其徐如林', - mobile_shenhua_shan:'手杀异构·不动如山', - mobile_shenhua_yin:'手杀异构·难知如阴', - mobile_shenhua_lei:'手杀异构·动如雷霆', - mobile_yijiang1:'手杀异构·将1', - mobile_yijiang2:'手杀异构·将2', - mobile_yijiang3:'手杀异构·将3', - mobile_yijiang4:'手杀异构·将4', - mobile_yijiang5:'手杀异构·将5', - mobile_yijiang67:'手杀异构·原创设计', - mobile_sp:'手杀异构·SP', - mobile_default:'袖里乾坤', - mobile_others:'其他', - mobile_changshi:'十常侍单体', - } + mobile_standard: "手杀异构·标准包", + mobile_shenhua_feng: "手杀异构·其疾如风", + mobile_shenhua_huo: "手杀异构·侵掠如火", + mobile_shenhua_lin: "手杀异构·其徐如林", + mobile_shenhua_shan: "手杀异构·不动如山", + mobile_shenhua_yin: "手杀异构·难知如阴", + mobile_shenhua_lei: "手杀异构·动如雷霆", + mobile_yijiang1: "手杀异构·将1", + mobile_yijiang2: "手杀异构·将2", + mobile_yijiang3: "手杀异构·将3", + mobile_yijiang4: "手杀异构·将4", + mobile_yijiang5: "手杀异构·将5", + mobile_yijiang67: "手杀异构·原创设计", + mobile_sp: "手杀异构·SP", + mobile_default: "袖里乾坤", + mobile_others: "其他", + mobile_changshi: "十常侍单体", + }, }; }); diff --git a/character/mtg.js b/character/mtg.js index 8502b8ac5..694c03582 100644 --- a/character/mtg.js +++ b/character/mtg.js @@ -1,492 +1,516 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'mtg', - character:{ - mtg_jiding:['male','qun',4,['mbaizhan','msilian']], + name: "mtg", + character: { + mtg_jiding: ["male", "qun", 4, ["mbaizhan", "msilian"]], // mtg_qianzhuo:['female','shu',3,[]], - mtg_jiesi:['male','wei',3,['mtongnian','msuoling','mhuanyi']], - mtg_lilianna:['female','qun',3,['lingyong','mduohun']], + mtg_jiesi: ["male", "wei", 3, ["mtongnian", "msuoling", "mhuanyi"]], + mtg_lilianna: ["female", "qun", 3, ["lingyong", "mduohun"]], // mtg_nisha:['female','wu',3,[]], // mtg_ayeni:['male','qun',4,[]], }, - characterIntro:{ - mtg_jiding:'这名白色魔法的使用者极其注重忠诚,正义和荣誉。他曾全力追捕茜卓纳拉,如今已不可思议地与这位火焰法师成为伙伴。', - mtg_qianzhuo:'茜卓纳拉是使用红色法术力的旅法师。她擅长使用火焰:除了火焰,还是火焰。茜卓性格冲动、易怒、富有激情,不断增长的火焰法术能力随时都准备爆发。她的火花在还很年轻时便已点燃,如今已是相当有经验的烈焰术士和旅法师。', - mtg_jiesi:'杰斯贝连是使用蓝色法术的鹏洛客。他擅长心灵法术:读取心灵,幻影,知识,以及欺瞒的咒语。', - mtg_lilianna:'莉莲娜维斯是一位精通死灵术的旅法师,她擅长用黑色法术力来复活死者,腐化生者,并从死亡中召唤力量。', - mtg_nisha:'赞迪卡妖精部落玖瑞加的一名战士,做事倾尽全力,与大地有密切的联系,还擅使元素魔法。她能够引导时空的魔法生机地脉,为土地赋予生命。', - mtg_ayeni:'金鬃阿耶尼是使用白色法术的鹏洛客。他长于净化身体与心灵的法术:用咒语来治疗、强化盟友,以及唤醒他人内在的心灵精华。', + characterIntro: { + mtg_jiding: + "这名白色魔法的使用者极其注重忠诚,正义和荣誉。他曾全力追捕茜卓纳拉,如今已不可思议地与这位火焰法师成为伙伴。", + mtg_qianzhuo: + "茜卓纳拉是使用红色法术力的旅法师。她擅长使用火焰:除了火焰,还是火焰。茜卓性格冲动、易怒、富有激情,不断增长的火焰法术能力随时都准备爆发。她的火花在还很年轻时便已点燃,如今已是相当有经验的烈焰术士和旅法师。", + mtg_jiesi: + "杰斯贝连是使用蓝色法术的鹏洛客。他擅长心灵法术:读取心灵,幻影,知识,以及欺瞒的咒语。", + mtg_lilianna: + "莉莲娜维斯是一位精通死灵术的旅法师,她擅长用黑色法术力来复活死者,腐化生者,并从死亡中召唤力量。", + mtg_nisha: + "赞迪卡妖精部落玖瑞加的一名战士,做事倾尽全力,与大地有密切的联系,还擅使元素魔法。她能够引导时空的魔法生机地脉,为土地赋予生命。", + mtg_ayeni: + "金鬃阿耶尼是使用白色法术的鹏洛客。他长于净化身体与心灵的法术:用咒语来治疗、强化盟友,以及唤醒他人内在的心灵精华。", }, - skill:{ - mduohun:{ - trigger:{player:'dyingAfter'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source.hp>0; + skill: { + mduohun: { + trigger: { player: "dyingAfter" }, + forced: true, + filter: function (event, player) { + return event.source && event.source.isIn() && event.source.hp > 0; }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { trigger.source.loseHp(); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 0.6; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 0.6; return 1; }, - effect:{ - target:function(card,player,target,current){ - if(!target.hasFriend()) return; - if(target.hp<=1&&get.tag(card,'damage')) return [1,0,0,-1]; - } - } - } + effect: { + target: function (card, player, target, current) { + if (!target.hasFriend()) return; + if (target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 0, -1]; + }, + }, + }, }, - lingyong:{ - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('subplayer')&&player.getSubPlayers('lingyong_get').length>0; + lingyong: { + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("subplayer") && player.getSubPlayers("lingyong_get").length > 0; }, - nosub:true, - group:'lingyong_get', - direct:true, - delay:0, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - player.callSubPlayer().set('tag','lingyong_get'); + nosub: true, + group: "lingyong_get", + direct: true, + delay: 0, + skillAnimation: true, + animationColor: "thunder", + content: function () { + player.callSubPlayer().set("tag", "lingyong_get"); }, - ai:{ - order:1, - result:{ - player:function(player,target){ + ai: { + order: 1, + result: { + player: function (player, target) { return 1; // if(player.hp<=1) return 1; // if(!player.needsToDiscard(player.hp-1)) return 1; // return 0; - } - } - }, - subSkill:{ - get:{ - trigger:{global:'dieAfter'}, - forced:true, - filter:function(event,player){ - return !event.player.isMin()&&![player.name,player.name1,player.name2].includes(event.player.name); }, - content:function(){ - var skills=lib.character[trigger.player.name][3].slice(0); - for(var i=0;i=5) return false; - return lib.skill.msuoling.getc(player).number>0; + filter: function (event, player) { + var nh = player.countCards("h"); + if (nh <= 1 || nh >= 5) return false; + return lib.skill.msuoling.getc(player).number > 0; }, - getc:function(player){ - var hs=player.getCards('h'); - for(var i=0;i1){ - for(var i=0;i 1) { + for (var i = 0; i < arr.length - 1; i++) { + for (var j = i + 1; j < arr.length; j++) { + var brr = []; + for (var k = 0; k < arr.length; k++) { + if (k != i && k != j) { brr.push(arr[k]); } } - if(lib.skill.msuoling.calc(brr.concat([arr[i]+arr[j]]),num)) return true; - if(lib.skill.msuoling.calc(brr.concat([arr[i]-arr[j]]),num)) return true; - if(lib.skill.msuoling.calc(brr.concat([arr[i]*arr[j]]),num)) return true; - if(lib.skill.msuoling.calc(brr.concat([arr[i]/arr[j]]),num)) return true; + if (lib.skill.msuoling.calc(brr.concat([arr[i] + arr[j]]), num)) return true; + if (lib.skill.msuoling.calc(brr.concat([arr[i] - arr[j]]), num)) return true; + if (lib.skill.msuoling.calc(brr.concat([arr[i] * arr[j]]), num)) return true; + if (lib.skill.msuoling.calc(brr.concat([arr[i] / arr[j]]), num)) return true; } } } return false; }, - check:function(card){ + check: function (card) { // if(player.isUnderControl(true)) return 0; - var player=_status.event.player; - if(player.hasSkill('msuoling_ai')){ + var player = _status.event.player; + if (player.hasSkill("msuoling_ai")) { return false; } - if(lib.skill.msuoling.test(player)){ + if (lib.skill.msuoling.test(player)) { return true; - } - else{ - player.addTempSkill('msuoling_ai',{player:['gainAfter','phaseAfter']}); + } else { + player.addTempSkill("msuoling_ai", { player: ["gainAfter", "phaseAfter"] }); return false; } }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - if(lib.skill.msuoling.test(player)){ - var card=lib.skill.msuoling.getc(player); - card.classList.remove('glow'); + "step 1"; + if (lib.skill.msuoling.test(player)) { + var card = lib.skill.msuoling.getc(player); + card.classList.remove("glow"); delete card.mtongnian_link; delete card._destroy; - var list=lib.skill.mtongnian.getList(player); - if(list.length){ - var card=list.randomGet(); - var fake=game.createCard(card); - fake.mtongnian_link=card; - player.gain(fake,'draw')._triggered=null; - fake.classList.add('glow'); - fake._destroy='mtongnian'; + var list = lib.skill.mtongnian.getList(player); + if (list.length) { + var card = list.randomGet(); + var fake = game.createCard(card); + fake.mtongnian_link = card; + player.gain(fake, "draw")._triggered = null; + fake.classList.add("glow"); + fake._destroy = "mtongnian"; } } }, - selectCard:[1,Infinity], - ai:{ - order:11 - } + selectCard: [1, Infinity], + ai: { + order: 11, + }, }, - mtongnian:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - var enemies=player.getEnemies(); - for(var i=0;i0; + mbaizhan: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event) { + return event.num > 0; }, - content:function(){ + content: function () { player.changeHujia(trigger.num); }, - ai:{ - damageBonus:true - } + ai: { + damageBonus: true, + }, }, - msilian:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - return player.hujia>0; + msilian: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + return player.hujia > 0; }, - check:function(event,player){ - return player.hujia>1&&player.hp>1; + check: function (event, player) { + return player.hujia > 1 && player.hp > 1; }, - content:function(){ - player.storage.msilian=player.hujia; + content: function () { + player.storage.msilian = player.hujia; player.changeHujia(-player.hujia); player.insertPhase(); }, - group:['msilian_hp','msilian_draw'], - subSkill:{ - hp:{ - trigger:{player:'phaseAfter'}, - silent:true, - filter:function(event,player){ - return event.skill=='msilian'&&!player.getStat('damage'); + group: ["msilian_hp", "msilian_draw"], + subSkill: { + hp: { + trigger: { player: "phaseAfter" }, + silent: true, + filter: function (event, player) { + return event.skill == "msilian" && !player.getStat("damage"); }, - content:function(){ + content: function () { player.loseHp(); - } - }, - draw:{ - trigger:{player:'phaseDrawBegin'}, - filter:function(event){ - return event.getParent('phase').skill=='msilian'; }, - silent:true, - content:function(){ - trigger.num+=player.storage.msilian-2; - } - } - } - } + }, + draw: { + trigger: { player: "phaseDrawBegin" }, + filter: function (event) { + return event.getParent("phase").skill == "msilian"; + }, + silent: true, + content: function () { + trigger.num += player.storage.msilian - 2; + }, + }, + }, + }, }, - translate:{ - mtg_jiding:'基定', - mtg_qianzhuo:'茜卓', - mtg_jiesi:'杰斯', - mtg_lilianna:'莉莲娜', - mtg_nisha:'妮莎', - mtg_ayeni:'阿耶尼', + translate: { + mtg_jiding: "基定", + mtg_qianzhuo: "茜卓", + mtg_jiesi: "杰斯", + mtg_lilianna: "莉莲娜", + mtg_nisha: "妮莎", + mtg_ayeni: "阿耶尼", - mduohun:'夺魂', - mduohun_info:'锁定技,当你解除濒死状态后,令你进入濒死状态的角色失去1点体力。', - lingyong:'灵俑', - lingyong2:'灵俑', - lingyong3:'灵俑', - lingyong3_bg:'俑', - lingyong_info:'锁定技,每当一名其他角色死亡,你获得一个与该角色同名且体力上限为1、初始手牌为2的随从;出牌阶段,你可以调遣以此法获得的随从(直到随从死亡不可再次切换)。', - mbaizhan:'百战', - mbaizhan_info:'锁定技,每当你造成1点伤害,你获得1点护甲。', - msilian:'祀炼', - msilian_info:'结束阶段,若你有护甲,你可以移去全部护甲,然后进行一个额外回合;在额外回合中,你的摸牌阶段摸牌基数为你移去的护甲数;额外回合结束后,若你未造成伤害,你失去1点体力。', - mtongnian:'通念', - mtongnian_info:'锁定技,出牌阶段开始时,你获得一张替身牌,此牌对应一名随机敌人的一张随机手牌;每当你使用一张非替身牌,随机更换替身牌对应的牌;当你使用替身牌时,改为使用替身牌对应的牌;当出牌阶段结束,或替身牌离开手牌区,或敌方角色没有手牌时,销毁替身牌。', - msuoling:'塑灵', - msuoling_info:'每轮限一次,当一名其他角色使用一张非转化的普通锦囊牌时,你可以弃置一张与之花色相同的牌取消之,然后你视为使用该锦囊牌。', - msuoling_old_info:'出牌阶段限一次,若你手牌中有替身牌且手牌数不超过5,你可以展示手牌,若其中的非替身手牌能通过四则运算得到你的替身牌的点数,你将替身牌转化为非替身牌,然后获得一张新的替身牌(此技能托管无效)。', - mhuanyi:'幻逸', - mhuanyi_info:'每两轮限一次,结束阶段,你可以选择一名其他角色和一种卡牌类型(选择结果对其他角色不可见),直到下一回合开始,当你首次成为该类型卡牌的惟一目标时,你将目标转移给你指定的角色(目标须合法)。', + mduohun: "夺魂", + mduohun_info: "锁定技,当你解除濒死状态后,令你进入濒死状态的角色失去1点体力。", + lingyong: "灵俑", + lingyong2: "灵俑", + lingyong3: "灵俑", + lingyong3_bg: "俑", + lingyong_info: + "锁定技,每当一名其他角色死亡,你获得一个与该角色同名且体力上限为1、初始手牌为2的随从;出牌阶段,你可以调遣以此法获得的随从(直到随从死亡不可再次切换)。", + mbaizhan: "百战", + mbaizhan_info: "锁定技,每当你造成1点伤害,你获得1点护甲。", + msilian: "祀炼", + msilian_info: + "结束阶段,若你有护甲,你可以移去全部护甲,然后进行一个额外回合;在额外回合中,你的摸牌阶段摸牌基数为你移去的护甲数;额外回合结束后,若你未造成伤害,你失去1点体力。", + mtongnian: "通念", + mtongnian_info: + "锁定技,出牌阶段开始时,你获得一张替身牌,此牌对应一名随机敌人的一张随机手牌;每当你使用一张非替身牌,随机更换替身牌对应的牌;当你使用替身牌时,改为使用替身牌对应的牌;当出牌阶段结束,或替身牌离开手牌区,或敌方角色没有手牌时,销毁替身牌。", + msuoling: "塑灵", + msuoling_info: + "每轮限一次,当一名其他角色使用一张非转化的普通锦囊牌时,你可以弃置一张与之花色相同的牌取消之,然后你视为使用该锦囊牌。", + msuoling_old_info: + "出牌阶段限一次,若你手牌中有替身牌且手牌数不超过5,你可以展示手牌,若其中的非替身手牌能通过四则运算得到你的替身牌的点数,你将替身牌转化为非替身牌,然后获得一张新的替身牌(此技能托管无效)。", + mhuanyi: "幻逸", + mhuanyi_info: + "每两轮限一次,结束阶段,你可以选择一名其他角色和一种卡牌类型(选择结果对其他角色不可见),直到下一回合开始,当你首次成为该类型卡牌的惟一目标时,你将目标转移给你指定的角色(目标须合法)。", }, }; }); diff --git a/character/offline.js b/character/offline.js index 749ac2e60..662a28be9 100644 --- a/character/offline.js +++ b/character/offline.js @@ -1,3378 +1,4900 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'offline', - connect:true, - connectBanned:['zhangliang'], - characterSort:{ - offline:{ - offline_star:['jsp_ganfuren',"sp_xiahoushi","jsp_zhaoyun","huangjinleishi","sp_pangtong","sp_daqiao","sp_ganning","sp_xiahoudun","sp_lvmeng","sp_zhangfei","sp_liubei","old_machao","zhangliang","jsp_caoren"], - offline_sticker:['sp_gongsunzan','sp_simazhao','sp_wangyuanji','sp_xinxianying','sp_liuxie'], - offline_yijiang:['ol_xinxianying'], - offline_luanwu:["ns_lijue","ns_zhangji","ns_fanchou"], - offline_yongjian:["ns_chendao","yj_caoang","yj_caocao",'yj_liru','yj_caohong','yj_zhangfei','yongjian_ganning','yj_dongzhuo','yj_xuyou','yj_jiaxu','yj_zhenji'], - offline_piracyE:['shen_jiaxu','pe_wangyun','pe_zhonghui','pe_sunchen','pe_mengda','pe_wenqin','ns_caoanmin','jiangqing','kongrong','jiling','tianfeng','mateng'], - offline_piracyS:['ns_jiaxu','longyufei','ps_guanyu','ps1059_guojia','ps2070_guojia','ps2063_zhaoyun','ps2067_zhaoyun','ps1062_zhouyu','ps2080_zhouyu','ps_caozhi','ps_jin_simayi','ps_caopi','ps_simayi','ps2068_simayi','ps_machao','ps_zhugeliang','ps2066_zhugeliang','ps_jiaxu','ps_lvbu','ps_shen_machao','jsp_liubei'], - offline_piracyK:['pk_sp_duyu'], - offline_vtuber:['vtb_xiaosha','vtb_xiaoshan','vtb_xiaotao','vtb_xiaole','vtb_xiaojiu'], + name: "offline", + connect: true, + connectBanned: ["zhangliang"], + characterSort: { + offline: { + offline_star: [ + "jsp_ganfuren", + "sp_xiahoushi", + "jsp_zhaoyun", + "huangjinleishi", + "sp_pangtong", + "sp_daqiao", + "sp_ganning", + "sp_xiahoudun", + "sp_lvmeng", + "sp_zhangfei", + "sp_liubei", + "old_machao", + "zhangliang", + "jsp_caoren", + ], + offline_sticker: [ + "sp_gongsunzan", + "sp_simazhao", + "sp_wangyuanji", + "sp_xinxianying", + "sp_liuxie", + ], + offline_yijiang: ["ol_xinxianying"], + offline_luanwu: ["ns_lijue", "ns_zhangji", "ns_fanchou"], + offline_yongjian: [ + "ns_chendao", + "yj_caoang", + "yj_caocao", + "yj_liru", + "yj_caohong", + "yj_zhangfei", + "yongjian_ganning", + "yj_dongzhuo", + "yj_xuyou", + "yj_jiaxu", + "yj_zhenji", + ], + offline_piracyE: [ + "shen_jiaxu", + "pe_wangyun", + "pe_zhonghui", + "pe_sunchen", + "pe_mengda", + "pe_wenqin", + "ns_caoanmin", + "jiangqing", + "kongrong", + "jiling", + "tianfeng", + "mateng", + ], + offline_piracyS: [ + "ns_jiaxu", + "longyufei", + "ps_guanyu", + "ps1059_guojia", + "ps2070_guojia", + "ps2063_zhaoyun", + "ps2067_zhaoyun", + "ps1062_zhouyu", + "ps2080_zhouyu", + "ps_caozhi", + "ps_jin_simayi", + "ps_caopi", + "ps_simayi", + "ps2068_simayi", + "ps_machao", + "ps_zhugeliang", + "ps2066_zhugeliang", + "ps_jiaxu", + "ps_lvbu", + "ps_shen_machao", + "jsp_liubei", + ], + offline_piracyK: ["pk_sp_duyu"], + offline_vtuber: ["vtb_xiaosha", "vtb_xiaoshan", "vtb_xiaotao", "vtb_xiaole", "vtb_xiaojiu"], + offline_longyutao: ["drag_guanyu", "drag_caoren", "drag_lvchang"], //offline_others:[""], }, }, - character:{ - jsp_ganfuren:['female','shu',3,['shushen','shenzhi'],['character:gz_ganfuren']], - ol_xinxianying:['female','wei',3,['xincaishi','xinzhongjian']], - zhangliang:["male","qun",4,["old_jijun","old_fangtong"]], - jsp_caoren:['male','wei',4,['kuiwei','yanzheng']], - old_machao:['male','qun',4,['zhuiji','oldcihuai']], - vtb_xiaosha:['female','qun',4,['vtbguisha','vtbshuli']], - vtb_xiaoshan:['female','qun',4,['vtbshanwu','vtbxianli']], - vtb_xiaotao:['female','qun',4,['vtbtaoyan','vtbyanli']], - vtb_xiaole:['female','qun',4,['vtbleyu','vtbyuanli']], - vtb_xiaojiu:['female','qun',4,['vtbmeiniang','vtbyaoli']], - ps_shen_machao:['male','shen',4,['psshouli','pshengwu'],['qun']], - mateng:['male','qun',4,['mashu','xiongyi']], - tianfeng:['male','qun',3,['sijian','gzsuishi']], - jiling:['male','qun',4,['shuangren']], - kongrong:['male','qun',3,['zymingshi','lirang']], - jiangqing:['male','wu',4,['zyshangyi']], - pk_sp_duyu:['male','qun',4,['pkwuku','pksanchen']], - ps_lvbu:['male','qun',4,['wushuang','pssheji']], - ps_jiaxu:['male','qun',4,['wansha','psqupo','psbaoquan']], - ps_machao:['male','shu',4,['mashu','tieji','psweihou']], - ps2066_zhugeliang:['male','shu',3,['pszhiji','psjiefeng','kongcheng']], - ps_zhugeliang:['male','shu',3,['psguanxing','pslongyin']], - ps_simayi:['male','wei',3,['reguicai','pshuxiao']], - ps2068_simayi:['male','wei',3,['refankui','reguicai','pszhonghu']], - ps_caopi:['male','wei',3,['psjianwei','fangzhu','songwei'],['zhu']], - ps_jin_simayi:['male','jin',3,['smyyingshi','psquanyi']], - ps_caozhi:['male','wei',3,['psliushang','psqibu']], - ps1062_zhouyu:['male','wu',3,['yingzi','psoldshiyin']], - ps2080_zhouyu:['male','wu',3,['psshiyin','psquwu','psliaozou']], - ps2063_zhaoyun:['male','shu',4,['psqijin','psqichu','pslongxin']], - ps2067_zhaoyun:['male','shu',4,['longdan','pshuiqiang','pshuntu']], - ps1059_guojia:['male','wei',3,['tiandu','psqizuo']], - ps2070_guojia:['male','wei',3,['yiji','psquanmou']], - ps_guanyu:['male','shu',4,['wusheng','pszhonghun','nuzhan']], - pe_wenqin:['male','wei',4,['gzjinfa']], - pe_sunchen:['male','wu',4,['zyshilu','zyxiongnve']], - pe_mengda:['male','wei',4,['qiuan','liangfan']], - pe_zhonghui:['male','wei',4,['zyquanji','zypaiyi'],['clan:颍川钟氏']], - pe_wangyun:['male','qun',3,['zylianji','zymoucheng'],['clan:太原王氏']], - shen_jiaxu:['male','shen',3,['weimu','zybishi','zyjianbing'],['qun']], - yj_zhenji:['female','wei',3,['yjluoshen','qingguo']], - yj_jiaxu:['male','wei',3,['yjzhenlve','yjjianshu','yjyongdi']], - yj_xuyou:['male','qun',3,['yjshicai','yjchenggong','yjzezhu']], - yj_dongzhuo:['male','qun',7,['yjtuicheng','yjyaoling','yjshicha','yjyongquan'],['zhu']], - yongjian_ganning:['male','wu',4,['yjjielve']], - yj_zhangfei:['male','shu',4,['yjmangji']], - yj_caohong:['male','wei',4,['yjlifeng']], - yj_liru:['male','qun',3,['yjdumou','yjweiquan','yjrenwang']], - yj_caocao:['male','qun',4,['yjxiandao','yjsancai','yjyibing']], - longyufei:['female','shu',3,['longyi','zhenjue']], - sp_liubei:['male','shu',4,['zhaolie','shichou'],['zhu']], - sp_zhangfei:['male','shu',4,['jie','dahe']], - sp_lvmeng:['male','wu',3,['tanhu','mouduan']], - sp_xiahoudun:['male','wei',4,['fenyong','xuehen'],['die_audio']], - sp_ganning:['male','qun',4,['yinling','junwei']], - sp_daqiao:['female','wu',3,['yanxiao','anxian']], - sp_pangtong:['male','qun',3,['xinmanjuan','zuixiang']], - huangjinleishi:['female','qun',3,['fulu','fuji']], - jsp_zhaoyun:['male','qun',3,['chixin','reyicong','suiren']], - sp_xiahoushi:["female","shu",3,["xinfu_yanyu","xinfu_xiaode"]], - sp_gongsunzan:['male','qun',4,['spyicong','sptuji']], - sp_simazhao:['male','wei',3,['spzhaoxin','splanggu']], - sp_wangyuanji:['female','wei',3,['spfuluan','spshude']], - sp_xinxianying:['female','wei',3,['spmingjian','spyinzhi']], - sp_liuxie:['male','qun',3,['sphuangen','sphantong']], - ns_lijue:['male','qun','4/6',['nsfeixiong','nscesuan']], - ns_zhangji:['male','qun',4,['nslulve']], - ns_fanchou:['male','qun',4,['nsyangwu']], - ns_jiaxu:['male','qun',3,['nsyice','luanwu']], - ns_chendao:['male','shu',4,['nsjianglie']], - yj_caoang:['male','wei',4,['yjxuepin']], - ns_caoanmin:['male','wei',4,['nskuishe']], - jsp_liubei:['male','qun',4,['jsprende']], + character: { + drag_guanyu: ["male", "shu", 4, ["dragchaojue", "dragjunshen"]], + drag_caoren: ["male", "wei", 4, ["draglizhong", "dragjuesui"]], + drag_lvchang: ["male", "wei", 3, ["dragjuwu", "dragshouxiang"]], + jsp_ganfuren: ["female", "shu", 3, ["shushen", "shenzhi"], ["character:gz_ganfuren"]], + ol_xinxianying: ["female", "wei", 3, ["xincaishi", "xinzhongjian"]], + zhangliang: ["male", "qun", 4, ["old_jijun", "old_fangtong"]], + jsp_caoren: ["male", "wei", 4, ["kuiwei", "yanzheng"]], + old_machao: ["male", "qun", 4, ["zhuiji", "oldcihuai"]], + vtb_xiaosha: ["female", "qun", 4, ["vtbguisha", "vtbshuli"]], + vtb_xiaoshan: ["female", "qun", 4, ["vtbshanwu", "vtbxianli"]], + vtb_xiaotao: ["female", "qun", 4, ["vtbtaoyan", "vtbyanli"]], + vtb_xiaole: ["female", "qun", 4, ["vtbleyu", "vtbyuanli"]], + vtb_xiaojiu: ["female", "qun", 4, ["vtbmeiniang", "vtbyaoli"]], + ps_shen_machao: ["male", "shen", 4, ["psshouli", "pshengwu"], ["qun"]], + mateng: ["male", "qun", 4, ["mashu", "xiongyi"]], + tianfeng: ["male", "qun", 3, ["sijian", "gzsuishi"]], + jiling: ["male", "qun", 4, ["shuangren"]], + kongrong: ["male", "qun", 3, ["zymingshi", "lirang"]], + jiangqing: ["male", "wu", 4, ["zyshangyi"]], + pk_sp_duyu: ["male", "qun", 4, ["pkwuku", "pksanchen"]], + ps_lvbu: ["male", "qun", 4, ["wushuang", "pssheji"]], + ps_jiaxu: ["male", "qun", 4, ["wansha", "psqupo", "psbaoquan"]], + ps_machao: ["male", "shu", 4, ["mashu", "tieji", "psweihou"]], + ps2066_zhugeliang: ["male", "shu", 3, ["pszhiji", "psjiefeng", "kongcheng"]], + ps_zhugeliang: ["male", "shu", 3, ["psguanxing", "pslongyin"]], + ps_simayi: ["male", "wei", 3, ["reguicai", "pshuxiao"]], + ps2068_simayi: ["male", "wei", 3, ["refankui", "reguicai", "pszhonghu"]], + ps_caopi: ["male", "wei", 3, ["psjianwei", "fangzhu", "songwei"], ["zhu"]], + ps_jin_simayi: ["male", "jin", 3, ["smyyingshi", "psquanyi"]], + ps_caozhi: ["male", "wei", 3, ["psliushang", "psqibu"]], + ps1062_zhouyu: ["male", "wu", 3, ["yingzi", "psoldshiyin"]], + ps2080_zhouyu: ["male", "wu", 3, ["psshiyin", "psquwu", "psliaozou"]], + ps2063_zhaoyun: ["male", "shu", 4, ["psqijin", "psqichu", "pslongxin"]], + ps2067_zhaoyun: ["male", "shu", 4, ["longdan", "pshuiqiang", "pshuntu"]], + ps1059_guojia: ["male", "wei", 3, ["tiandu", "psqizuo"]], + ps2070_guojia: ["male", "wei", 3, ["yiji", "psquanmou"]], + ps_guanyu: ["male", "shu", 4, ["wusheng", "pszhonghun", "nuzhan"]], + pe_wenqin: ["male", "wei", 4, ["gzjinfa"]], + pe_sunchen: ["male", "wu", 4, ["zyshilu", "zyxiongnve"]], + pe_mengda: ["male", "wei", 4, ["qiuan", "liangfan"]], + pe_zhonghui: ["male", "wei", 4, ["zyquanji", "zypaiyi"], ["clan:颍川钟氏"]], + pe_wangyun: ["male", "qun", 3, ["zylianji", "zymoucheng"], ["clan:太原王氏"]], + shen_jiaxu: ["male", "shen", 3, ["weimu", "zybishi", "zyjianbing"], ["qun"]], + yj_zhenji: ["female", "wei", 3, ["yjluoshen", "qingguo"]], + yj_jiaxu: ["male", "wei", 3, ["yjzhenlve", "yjjianshu", "yjyongdi"]], + yj_xuyou: ["male", "qun", 3, ["yjshicai", "yjchenggong", "yjzezhu"]], + yj_dongzhuo: ["male", "qun", 7, ["yjtuicheng", "yjyaoling", "yjshicha", "yjyongquan"], ["zhu"]], + yongjian_ganning: ["male", "wu", 4, ["yjjielve"]], + yj_zhangfei: ["male", "shu", 4, ["yjmangji"]], + yj_caohong: ["male", "wei", 4, ["yjlifeng"]], + yj_liru: ["male", "qun", 3, ["yjdumou", "yjweiquan", "yjrenwang"]], + yj_caocao: ["male", "qun", 4, ["yjxiandao", "yjsancai", "yjyibing"]], + longyufei: ["female", "shu", 3, ["longyi", "zhenjue"]], + sp_liubei: ["male", "shu", 4, ["zhaolie", "shichou"], ["zhu"]], + sp_zhangfei: ["male", "shu", 4, ["jie", "dahe"]], + sp_lvmeng: ["male", "wu", 3, ["tanhu", "mouduan"]], + sp_xiahoudun: ["male", "wei", 4, ["fenyong", "xuehen"], ["die_audio"]], + sp_ganning: ["male", "qun", 4, ["yinling", "junwei"]], + sp_daqiao: ["female", "wu", 3, ["yanxiao", "anxian"]], + sp_pangtong: ["male", "qun", 3, ["xinmanjuan", "zuixiang"]], + huangjinleishi: ["female", "qun", 3, ["fulu", "fuji"]], + jsp_zhaoyun: ["male", "qun", 3, ["chixin", "reyicong", "suiren"]], + sp_xiahoushi: ["female", "shu", 3, ["xinfu_yanyu", "xinfu_xiaode"]], + sp_gongsunzan: ["male", "qun", 4, ["spyicong", "sptuji"]], + sp_simazhao: ["male", "wei", 3, ["spzhaoxin", "splanggu"]], + sp_wangyuanji: ["female", "wei", 3, ["spfuluan", "spshude"]], + sp_xinxianying: ["female", "wei", 3, ["spmingjian", "spyinzhi"]], + sp_liuxie: ["male", "qun", 3, ["sphuangen", "sphantong"]], + ns_lijue: ["male", "qun", "4/6", ["nsfeixiong", "nscesuan"]], + ns_zhangji: ["male", "qun", 4, ["nslulve"]], + ns_fanchou: ["male", "qun", 4, ["nsyangwu"]], + ns_jiaxu: ["male", "qun", 3, ["nsyice", "luanwu"]], + ns_chendao: ["male", "shu", 4, ["nsjianglie"]], + yj_caoang: ["male", "wei", 4, ["yjxuepin"]], + ns_caoanmin: ["male", "wei", 4, ["nskuishe"]], + jsp_liubei: ["male", "qun", 4, ["jsprende"]], }, - characterIntro:{ - huangjinleishi:"黄巾军中负责施法的女祭司二人组。", - longyufei:'《三国杀·阵面对决》中的虚构角色,设定是由刘备之女夏侯岚、关羽之女关银屏、张飞之女张星彩三人在与吕布之魔魂战斗时,释放雅典娜的惊叹而召唤出来的精元化神。', - pk_sp_duyu:'杜预(222年-285年),字元凯,京兆郡杜陵县(今陕西西安)人,中国魏晋时期军事家、经学家、律学家,曹魏散骑常侍杜恕之子。杜预初仕曹魏,任尚书郎,后成为权臣司马昭的幕僚,封丰乐亭侯。西晋建立后,历任河南尹、安西军司、秦州刺史、度支尚书等职。咸宁四年(278年)接替羊祜出任镇南大将军,镇守荆州。他积极备战,支持晋武帝司马炎对孙吴作战,并在咸宁五年(279年)成为晋灭吴之战的统帅之一。战后因功进封当阳县侯,仍镇荆州。太康五年(285年),杜预被征入朝,拜司隶校尉,途中于邓县逝世,终年六十三岁。获赠征南大将军、开府仪同三司,谥号为成。杜预耽思经籍,博学多通,多有建树,时誉为“杜武库”。著有《春秋左氏传集解》及《春秋释例》等。为明朝之前唯一一个同时进入文庙和武庙之人。', - ps_shen_machao:'字孟起,扶风茂陵人。面如冠玉,目如流星,虎体猿臂,彪腹狼腰,声雄力猛。因衣着讲究,举止非凡,故人称“锦马超”。麾铁骑,捻金枪。', - xiaosha:'2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为三国杀新手菜鸡,误打误撞参加了三国杀组织的《三国之星》选秀大赛,没想到一路靠着颜值和风风火火的爽快性格过关斩将吸粉无数,获得了冠军,成为官方签约的形象代言人。
              小杀现于B站还存在对应账号,但早已荒废。', - xiaoshan:'2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为小杀同系不同班的同学,由于本身性格比较安静,所以和风风火火的小杀有些不对盘。知道小杀也玩三国杀后,外表高冷、内心傲娇的她偷偷也去玩了游戏,立志要在游戏里碾压她。
              小闪对应B站账号已销号。', - xiaotao:'2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为小杀的亲妹妹,陪姐姐去拍摄代言宣传照的时候,被导演看中,觉得三国美貌姐妹花是非常好的噱头,于是一并签下。正所谓“三国姐妹花,永远不分家!”。
              小桃对应B站账号已销号。', - xiaole:'2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上小乐家与小桃小杀家是世交,三人从小就认识。和小闪是同班同学,小乐很喜欢安静的小闪。和小酒是小杀介绍认识的,大家都是打三国杀的网友,在打游戏时候比较依赖小酒——躺赢人躺赢魂,躺赢都是人上人。
              小乐对应B站账号已销号。', - xiaojiu:'2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为非人类,是一只年龄成迷的神兽,真身是白泽。是小杀网上玩游戏认识的网友,爱好是喝酒,和小杀也有好酒友的关系。
              小酒对应B站账号已销号。', + characterIntro: { + lvchang: + "吕常(161—221年),荆州南阳博望(今河南省南阳市方城县博望镇)人,汉末至三国时期曹魏将领。吕常曾担任曹魏横海将军、章陵太守,为武猛都尉厉节中郎将裨将军,封关内侯。常以中勇,显名州司,试守雉长,执戈秉戎,慎守易,兵不顿于敌国,坠不侵于四邻,拜武猛都尉厉节中郎将裨将军,封关内侯。王师南征,与充军从,奄有江汉,舍爵册勋,封阴德亭侯,领郡。鸠集荒散,为民统纪,三考有成,转拜平狄将军,改封卢亭侯,莅国赋政,十有三年。会蜀将关羽猖獗为寇,常御之,羽不能克。文帝加其庸,转拜横海将军,徙封西鄂都乡侯,食邑并七百户。年六十一,黄初二年正月卒。", + huangjinleishi: "黄巾军中负责施法的女祭司二人组。", + longyufei: + "《三国杀·阵面对决》中的虚构角色,设定是由刘备之女夏侯岚、关羽之女关银屏、张飞之女张星彩三人在与吕布之魔魂战斗时,释放雅典娜的惊叹而召唤出来的精元化神。", + pk_sp_duyu: + "杜预(222年-285年),字元凯,京兆郡杜陵县(今陕西西安)人,中国魏晋时期军事家、经学家、律学家,曹魏散骑常侍杜恕之子。杜预初仕曹魏,任尚书郎,后成为权臣司马昭的幕僚,封丰乐亭侯。西晋建立后,历任河南尹、安西军司、秦州刺史、度支尚书等职。咸宁四年(278年)接替羊祜出任镇南大将军,镇守荆州。他积极备战,支持晋武帝司马炎对孙吴作战,并在咸宁五年(279年)成为晋灭吴之战的统帅之一。战后因功进封当阳县侯,仍镇荆州。太康五年(285年),杜预被征入朝,拜司隶校尉,途中于邓县逝世,终年六十三岁。获赠征南大将军、开府仪同三司,谥号为成。杜预耽思经籍,博学多通,多有建树,时誉为“杜武库”。著有《春秋左氏传集解》及《春秋释例》等。为明朝之前唯一一个同时进入文庙和武庙之人。", + ps_shen_machao: + "字孟起,扶风茂陵人。面如冠玉,目如流星,虎体猿臂,彪腹狼腰,声雄力猛。因衣着讲究,举止非凡,故人称“锦马超”。麾铁骑,捻金枪。", + xiaosha: + '2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为三国杀新手菜鸡,误打误撞参加了三国杀组织的《三国之星》选秀大赛,没想到一路靠着颜值和风风火火的爽快性格过关斩将吸粉无数,获得了冠军,成为官方签约的形象代言人。
              小杀现于B站还存在对应账号,但早已荒废。', + xiaoshan: + "2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为小杀同系不同班的同学,由于本身性格比较安静,所以和风风火火的小杀有些不对盘。知道小杀也玩三国杀后,外表高冷、内心傲娇的她偷偷也去玩了游戏,立志要在游戏里碾压她。
              小闪对应B站账号已销号。", + xiaotao: + "2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为小杀的亲妹妹,陪姐姐去拍摄代言宣传照的时候,被导演看中,觉得三国美貌姐妹花是非常好的噱头,于是一并签下。正所谓“三国姐妹花,永远不分家!”。
              小桃对应B站账号已销号。", + xiaole: "2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上小乐家与小桃小杀家是世交,三人从小就认识。和小闪是同班同学,小乐很喜欢安静的小闪。和小酒是小杀介绍认识的,大家都是打三国杀的网友,在打游戏时候比较依赖小酒——躺赢人躺赢魂,躺赢都是人上人。
              小乐对应B站账号已销号。", + xiaojiu: + "2021年「虚拟天团」Vtuber企划中推出的虚拟偶像之一,该企划原定培养12位虚拟偶像,然而企划由于各方面原因暴死,现虚拟偶像仅存在于各武将的皮肤中。
              设定上为非人类,是一只年龄成迷的神兽,真身是白泽。是小杀网上玩游戏认识的网友,爱好是喝酒,和小杀也有好酒友的关系。
              小酒对应B站账号已销号。", }, - characterTitle:{ - jsp_liubei:'S1019', - ns_caoanmin:'S1023', - longyufei:'S1044', - ps1059_guojia:'S1059', - ps_lvbu:'S1061', - ps1062_zhouyu:'S1062', - ps_jiaxu:'S1066', - ps_jin_simayi:'S1067', - ps_guanyu:'S2065', - ps2063_zhaoyun:'S2063', - ps2066_zhugeliang:'S2066', - ps2067_zhaoyun:'S2067', - ps2068_simayi:'S2068', - ps_machao:'S2069', - ps2070_guojia:'S2070', - ps_simayi:'S2073', - ps_zhugeliang:'S2073', - ps_caopi:'S2075', - ns_jiaxu:'S2079', - ps2080_zhouyu:'S2080', - ps_caozhi:'S2081', - ps_shen_machao:'SX015', + characterTitle: { + jsp_liubei: "S1019", + ns_caoanmin: "S1023", + longyufei: "S1044", + ps1059_guojia: "S1059", + ps_lvbu: "S1061", + ps1062_zhouyu: "S1062", + ps_jiaxu: "S1066", + ps_jin_simayi: "S1067", + ps_guanyu: "S2065", + ps2063_zhaoyun: "S2063", + ps2066_zhugeliang: "S2066", + ps2067_zhaoyun: "S2067", + ps2068_simayi: "S2068", + ps_machao: "S2069", + ps2070_guojia: "S2070", + ps_simayi: "S2073", + ps_zhugeliang: "S2073", + ps_caopi: "S2075", + ns_jiaxu: "S2079", + ps2080_zhouyu: "S2080", + ps_caozhi: "S2081", + ps_shen_machao: "SX015", }, - perfectPair:{}, - card:{ - yanxiao_card:{ - type:'special_delay', - fullimage:true, - noEffect:true, - ai:{ - basic:{ - order:1, - useful:1, - value:8, + perfectPair: {}, + card: { + yanxiao_card: { + type: "special_delay", + fullimage: true, + noEffect: true, + ai: { + basic: { + order: 1, + useful: 1, + value: 8, }, - result:{ - target:1 + result: { + target: 1, }, - } + }, }, }, - characterFilter:{ - }, - skill:{ + characterFilter: {}, + skill: { + //龙起襄樊 + //关羽 + //界界关羽 + dragchaojue: { + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + if (!game.hasPlayer((target) => target != player)) return false; + return player.countCards( + "h", + (card) => _status.connectMode || lib.filter.cardDiscardable(card, player) + ); + }, + async cost(event, trigger, player) { + event.result = await player + .chooseToDiscard(get.prompt2("dragchaojue"), "h") + .set("ai", (card) => { + const player = get.event("player"); + if (!game.hasPlayer((target) => get.attitude(player, target) < 0)) return 0; + return 7.5 - get.value(card); + }) + .set("logSkill", "dragchaojue") + .forResult(); + }, + popup: false, + async content(event, trigger, player) { + const targets = game.filterPlayer((target) => target != player).sortBySeat(); + if (targets.length) { + const suits = event.cards + .reduce((list, card) => list.add(get.suit(card, player)), []) + .sort((a, b) => { + return lib.suit.indexOf(a) - lib.suit.indexOf(b); + }); + player.line(targets); + for (const i of targets) { + i.addTempSkill("dragchaojue_buff"); + i.markAuto("dragchaojue_buff", suits); + } + for (const target of targets) { + const { + result: { bool }, + } = await target + .chooseToGive( + player, + (card, player) => { + return get.event("suits").includes(get.suit(card)); + }, + "h", + "give" + ) + .set("suits", suits) + .set("ai", (card) => { + const player = get.event("player"), + target = get.event().getParent().player; + const att = get.attitude(player, target); + if (att > 0) return 7.5 - get.value(card); + if (att == 0 && get.attitude(target, player) == 0) return 0; + if ( + att < 0 && + get.attitude(target, player) < 0 && + player.getSkills(null, false, false).some((skill) => { + if (get.is.locked(skill, player)) return false; + const info = get.info(skill); + return ( + info && + info.ai && + (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) + ); + }) && + player.getHp() > 2 + ) + return 0; + return 7.5 - get.value(card); + }) + .set( + "prompt", + "超绝:交给" + + get.translation(player) + + "一张" + + get.translation(suits) + + "手牌,或本回合非锁定技失效" + ); + if (!bool) target.addTempSkill("fengyin"); + } + } + }, + subSkill: { + buff: { + onremove: true, + charlotte: true, + mod: { + cardEnabled2(card, player) { + if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) + return false; + }, + }, + marktext: "绝", + intro: { content: "本回合内不能使用或打出$牌" }, + }, + }, + }, + dragjunshen: { + mod: { + targetInRange(card, player) { + if (get.suit(card) == "diamond" && card.name == "sha") return true; + }, + }, + locked: false, + enable: ["chooseToUse", "chooseToRespond"], + filterCard(card, player) { + return get.color(card) == "red"; + }, + viewAsFilter(player) { + return player.countCards("hes", { color: "red" }); + }, + position: "hes", + viewAs: { name: "sha" }, + prompt: "将一张红色牌当作【杀】使用或打出", + check(card) { + const val = get.value(card); + if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val); + return 5 - val; + }, + ai: { + order(item, player) { + if (!player || !_status.event.type || _status.event.type != "phase") { + return 0.1; + } + return get.order({ name: "sha" }, player) + 0.3; + }, + respondSha: true, + skillTagFilter(player) { + if (!player.countCards("hes", { color: "red" })) return false; + }, + }, + group: ["dragjunshen_add", "dragjunshen_damage"], + subSkill: { + add: { + trigger: { player: "useCard2" }, + filter(event, player) { + if (event.card.name != "sha" || get.suit(event.card) != "heart") return false; + return game.hasPlayer((target) => { + return ( + target != player && + !event.targets.includes(target) && + lib.filter.targetEnabled2(event.card, player, target) && + lib.filter.targetInRange(event.card, player, target) + ); + }); + }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("dragjunshen_add"), + "为" + get.translation(trigger.card) + "额外指定一个目标", + (card, player, target) => { + const evt = get.event().getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); + } + ) + .set("ai", (target) => + get.effect(target, _status.event.getTrigger().card, _status.event.player) + ) + .forResult(); + }, + content() { + trigger.targets.addArray(event.targets); + }, + }, + damage: { + trigger: { source: "damageBegin1" }, + filter(event, player) { + const evt = event.getParent(2); + return evt.name == "useCard" && evt.skill == "dragjunshen"; + }, + logTarget: "player", + prompt2(event, player) { + return "令" + get.translation(event.player) + "选择弃置装备区所有牌或令此伤害+1"; + }, + async content(event, trigger, player) { + const target = trigger.player; + let result; + if (!target.countDiscardableCards(target, "e")) result = { index: 1 }; + else + result = await target + .chooseControl() + .set("choiceList", ["弃置装备区所有牌", "令此伤害+1"]) + .set("ai", () => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + if ( + player.getHp() <= 2 || + player.getDiscardableCards(player, "e").reduce((sum, card) => { + return sum + get.value(card, player); + }, 0) < 7 + ) + return 0; + return 1; + }) + .forResult(); + if (result.index == 0) { + await target.discard(target.getDiscardableCards(target, "e")); + } else trigger.increase("num"); + }, + }, + }, + }, + //龙曹仁 + draglizhong: { + trigger: { player: "phaseJieshuBegin" }, + async cost(event, trigger, player) { + let choiceList = [ + "将任意张装备牌至于任意名角色的装备区", + "令你或任意名装备区里有牌的角色摸一张牌", + ], + choices = ["置入装备", "团体摸牌", "cancel2"]; + if ( + !player.countCards("he", (card) => { + if (get.type(card) != "equip") return false; + return game.hasPlayer((target) => { + return target.canEquip(card); + }); + }) + ) { + choices.shift(); + choiceList[0] = '' + choiceList[0] + ""; + } + const { + result: { control }, + } = await player + .chooseControl(choices) + .set("prompt", "###" + get.prompt("draglizhong") + "###选择首先执行的一项") + .set("choiceList", choiceList) + .set("ai", () => { + return get.event("controls")[0]; + }); + event.result = { bool: control != "cancel2", cost_data: control }; + }, + async content(event, trigger, player) { + let choices = ["置入装备", "团体摸牌"], + used = false; + if (event.cost_data == "团体摸牌") choices.reverse(); + choices.push(event.cost_data); + for (let i = 1; i <= 3; i++) { + if (i == 3 && used) break; + switch (choices[i - 1]) { + case "置入装备": + while ( + player.hasCard((card) => { + if (get.type(card) != "equip") return false; + return game.hasPlayer((target) => { + return target.canEquip(card); + }); + }, "he") + ) { + const { + result: { bool, cards, targets }, + } = await player.chooseCardTarget({ + prompt: "厉战:将一张装备牌置于一名角色的装备区", + filterCard(card) { + return get.type(card) == "equip"; + }, + position: "he", + filterTarget(card, player, target) { + return target.canEquip(card); + }, + ai1(card) { + return 6 - get.value(card); + }, + ai2(target) { + const player = get.event("player"); + const att = get.attitude(player, target); + if (att <= 0 || target.countCards("e")) return 0; + return att * (target == player ? 1 : 3); + }, + }); + if (bool) { + if (i == 1 && !used) used = true; + const card = cards[0], + target = targets[0]; + player.line(target); + if (target != player) { + player.$give(card, target, false); + } + await game.asyncDelay(0.5); + await target.equip(card); + } else break; + } + break; + case "团体摸牌": + const { result } = await player + .chooseTarget( + "厉战:令你或任意名装备区有牌的角色摸一张牌", + (card, player, target) => { + if (target != player && !target.countCards("e")) return false; + if (ui.selected.targets.length) { + const choose = ui.selected.targets[0]; + if (choose == player && !player.countCards("e")) return false; + } + return true; + }, + [1, Infinity] + ) + .set("multitarget", true) + .set("complexTarget", true) + .set("ai", (target) => { + const player = get.event("player"); + if (!player.countCards("e")) { + if ( + game.countPlayer((choose) => { + return ( + choose.countCards("e") && + get.attitude(player, choose) > 0 + ); + }) > 1 && + target == player + ) + return 0; + } + return get.attitude(player, target); + }); + if (result.bool) { + if (i == 1 && !used) used = true; + const targets = result.targets.sortBySeat(); + player.line(targets); + choices.addArray(targets); + for (let j = 0; j < targets.length; j++) { + await targets[j].draw("nodelay"); + } + await game.asyncDelayx(); + } + break; + } + } + choices = choices.slice(3); + if (choices.length) { + choices.sortBySeat(); + player.line(choices); + for (const target of choices) { + target.addTempSkill("draglizhong_effect", "roundStart"); + } + await game.asyncDelayx(); + } + }, + subSkill: { + effect: { + charlotte: true, + mod: { + maxHandcard(player, num) { + return num + 2; + }, + }, + enable: "chooseToUse", + filterCard: true, + position: "e", + viewAs: { name: "wuxie" }, + filter(event, player) { + return player.countCards("e") > 0; + }, + viewAsFilter(player) { + return player.countCards("e") > 0; + }, + prompt: "将一张装备区的牌当作【无懈可击】使用", + check(card) { + return 8 - get.equipValue(card); + }, + mark: true, + marktext: "守", + intro: { content: "手牌上限+2,可将装备区的牌当作【无懈可击】使用" }, + }, + }, + }, + //撅碎(难视 + dragjuesui: { + trigger: { global: "dying" }, + filter(event, player) { + return ( + !player.getStorage("dragjuesui").includes(event.player) && + event.player.hasEnabledSlot() + ); + }, + check(event, player) { + const target = event.player; + if (get.attitude(player, target) <= 0) return false; + return ( + player.countCards("hs", (card) => player.canSaveCard(card, target)) + + target.countCards("hs", (card) => target.canSaveCard(card, target)) < + 1 - target.hp + ); + }, + logTarget: "player", + async content(event, trigger, player) { + const target = trigger.player; + player.markAuto("dragjuesui", [target]); + const { + result: { bool }, + } = await target.chooseBool("是否将体力值回复至1点并废除装备栏?"); + if (bool) { + await target.recoverTo(1); + let disables = []; + for (let i = 1; i <= 5; i++) { + for (let j = 0; j < target.countEnabledSlot(i); j++) { + disables.push(i); + } + } + if (disables.length) await target.disableEquip(disables); + target.addSkill("dragjuesui_wusheng"); + } else { + target.chat("拒绝!"); + } + }, + init(player) { + if (player.getStorage("dragjuesui").length) { + player.markSkill("dragjuesui"); + } + }, + intro: { content: "已对$发动过此技能" }, + subSkill: { + wusheng: { + charlotte: true, + mark: true, + marktext: "碎", + intro: { content: "殊死一搏!可将黑色非基本牌当作无次数限制的【杀】使用" }, + mod: { + cardUsable(card, player, num) { + if (card.storage && card.storage.dragjuesui) return Infinity; + }, + }, + enable: ["chooseToUse", "chooseToRespond"], + filterCard(card, player) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, + position: "hse", + viewAs: { name: "sha", storage: { dragjuesui: true } }, + viewAsFilter(player) { + if ( + !player.countCards("hes", (card) => { + return get.color(card) == "black" && get.type(card) != "basic"; + }) + ) + return false; + }, + prompt: "将一张黑色非基本牌当作无次数限制的【杀】使用或打出", + check(card) { + return 7 - get.value(card); + }, + ai: { + order(item, player) { + if (!player || !_status.event.type || _status.event.type != "phase") { + return 0.1; + } + return get.order({ name: "sha" }, player) * 0.99; + }, + respondSha: true, + skillTagFilter(player) { + if ( + !player.countCards("hes", (card) => { + return get.color(card) == "black" && get.type(card) != "basic"; + }) + ) + return false; + }, + }, + }, + }, + }, + //吕常×SP淳于琼√ + dragjuwu: { + trigger: { target: "shaBefore" }, + filter(event, player) { + return game.countPlayer((target) => event.player.inRange(target)) >= 3; + }, + forced: true, + content() { + trigger.cancel(); + }, + ai: { + effect: { + target(card, player, target) { + if ( + card.name == "sha" && + game.countPlayer((targetx) => player.inRange(targetx)) >= 3 + ) + return "zerotarget"; + }, + }, + }, + }, + dragshouxiang: { + trigger: { player: "phaseDrawBegin2" }, + filter(event, player) { + if (!game.hasPlayer((target) => target.inRange(player))) return false; + return !event.numFixed; + }, + check(event, player) { + if (player.skipList.includes("phaseUse")) return true; + return ( + player.countCards("h") + + event.num + + Math.min( + 5, + game.countPlayer((target) => { + return target.inRange(player); + }) + ) - + game.countPlayer((target) => { + return target != player && get.attitude(player, target) > 0; + }) <= + player.getHandcardLimit() + ); + }, + content() { + trigger.num += Math.min( + 5, + game.countPlayer((target) => target.inRange(player)) + ); + player.skip("phaseUse"); + player.addTempSkill("dragshouxiang_effect"); + }, + subSkill: { + effect: { + charlotte: true, + trigger: { player: "phaseDiscardBegin" }, + filter(event, player) { + return game.hasPlayer((target) => target.inRange(player)); + }, + forced: true, + async content(event, trigger, player) { + const num = Math.min( + 5, + game.countPlayer((target) => target.inRange(player)) + ); + if (num) { + if (_status.connectMode) + game.broadcastAll(() => (_status.noclearcountdown = true)); + let list = []; + while ( + num - list.length > 0 && + player.hasCard((card) => { + return !list.some((list) => list[1] == card); + }, "h") && + game.hasPlayer((target) => { + return target != player && !list.some((list) => list[0] == target); + }) + ) { + const { + result: { bool, targets, cards }, + } = await player + .chooseCardTarget({ + prompt: "守襄:你可以交给任意名角色各一张手牌", + prompt2: "(还可分配" + (num - list.length) + "张)", + position: "h", + animate: false, + filterCard(card, player) { + return !get.event("list").some((list) => list[1] == card); + }, + filterTarget(card, player, target) { + return ( + target != player && + !get.event("list").some((list) => list[0] == target) + ); + }, + ai1(card) { + if (card.name == "shan") return 1; + return Math.random(); + }, + ai2(target) { + return get.attitude(get.event("player"), target); + }, + }) + .set("list", list); + if (bool) { + list.push([targets[0], cards[0]]); + player.addGaintag(cards, "olsujian_given"); + } else break; + } + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + if (list.length) { + await game + .loseAsync({ + gain_list: list, + player: player, + cards: list.slice().map((list) => list[1]), + giver: player, + animate: "giveAuto", + }) + .setContent("gaincardMultiple"); + } + } + }, + }, + }, + }, //天书乱斗虚拟偶像线下化 //小杀 - vtbguisha:{ - audio:1, - trigger:{global:'useCard'}, - direct:true, - shaRelated:true, - filter:function(event,player){ - return event.player!=player&&event.card.name=='sha'&&player.countCards('he')>0&&event.player.isPhaseUsing(); + vtbguisha: { + audio: 1, + trigger: { global: "useCard" }, + direct: true, + shaRelated: true, + filter: function (event, player) { + return ( + event.player != player && + event.card.name == "sha" && + player.countCards("he") > 0 && + event.player.isPhaseUsing() + ); }, - content:function(){ - 'step 0' - var go=false,d1=false; - if(get.attitude(player,trigger.player)>0){ - d1=true; - if(trigger.player.hasSkill('jueqing')||trigger.player.hasSkill('gangzhi')) d1=false; - for(var target of trigger.targets){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||trigger.player.hasSkillTag('directHit_ai',true,{ - target:target, - card:trigger.card, - },true)){ - if(!target.hasSkill('gangzhi')) d1=false; - if(target.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:trigger.card, - })||get.attitude(player,target)>=0) d1=false; + content: function () { + "step 0"; + var go = false, + d1 = false; + if (get.attitude(player, trigger.player) > 0) { + d1 = true; + if (trigger.player.hasSkill("jueqing") || trigger.player.hasSkill("gangzhi")) + d1 = false; + for (var target of trigger.targets) { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + trigger.player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: trigger.card, + }, + true + ) + ) { + if (!target.hasSkill("gangzhi")) d1 = false; + if ( + target.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: trigger.card, + }) || + get.attitude(player, target) >= 0 + ) + d1 = false; } } - if(trigger.addCount===false||!trigger.player.isPhaseUsing()) go=false; - else if(!trigger.player.hasSkill('paoxiao')&& - !trigger.player.hasSkill('tanlin3')&& - !trigger.player.hasSkill('zhaxiang2')&& - !trigger.player.hasSkill('fengnu')&& - !trigger.player.getEquip('zhuge')){ - var nh=trigger.player.countCards('h'); - if(player==trigger.player){ - go=(player.countCards('h','sha')>0); - } - else if(nh>=4){ - go=true; - } - else if(player.countCards('h','sha')){ - if(nh==3){ - go=Math.random()<0.8; + if (trigger.addCount === false || !trigger.player.isPhaseUsing()) go = false; + else if ( + !trigger.player.hasSkill("paoxiao") && + !trigger.player.hasSkill("tanlin3") && + !trigger.player.hasSkill("zhaxiang2") && + !trigger.player.hasSkill("fengnu") && + !trigger.player.getEquip("zhuge") + ) { + var nh = trigger.player.countCards("h"); + if (player == trigger.player) { + go = player.countCards("h", "sha") > 0; + } else if (nh >= 4) { + go = true; + } else if (player.countCards("h", "sha")) { + if (nh == 3) { + go = Math.random() < 0.8; + } else if (nh == 2) { + go = Math.random() < 0.5; } - else if(nh==2){ - go=Math.random()<0.5; - } - } - else if(nh>=3){ - if(nh==3){ - go=Math.random()<0.5; - } - else if(nh==2){ - go=Math.random()<0.2; + } else if (nh >= 3) { + if (nh == 3) { + go = Math.random() < 0.5; + } else if (nh == 2) { + go = Math.random() < 0.2; } } } } - go=go*Math.random()+d1*Math.random()>0.4; + go = go * Math.random() + d1 * Math.random() > 0.4; //AI停顿 - if(go&&!event.isMine()&&!event.isOnline()&&player.hasCard(function(card){ - return get.value(card)<6&&lib.filter.cardDiscardable(card,player,event.name); - },'he')){ + if ( + go && + !event.isMine() && + !event.isOnline() && + player.hasCard(function (card) { + return ( + get.value(card) < 6 && lib.filter.cardDiscardable(card, player, event.name) + ); + }, "he") + ) { game.delayx(); } - var next=player.chooseToDiscard(get.prompt('vtbguisha'),'弃置一张牌,令'+get.translation(trigger.player)+'本次使用的【杀】不计入使用次数,且对'+get.translation(trigger.targets)+'造成的伤害+1','he'); - next.logSkill=['vtbguisha',trigger.player]; - next.set('ai',function(card){ - if(_status.event.go){ - return 6-get.value(card); + var next = player.chooseToDiscard( + get.prompt("vtbguisha"), + "弃置一张牌,令" + + get.translation(trigger.player) + + "本次使用的【杀】不计入使用次数,且对" + + get.translation(trigger.targets) + + "造成的伤害+1", + "he" + ); + next.logSkill = ["vtbguisha", trigger.player]; + next.set("ai", function (card) { + if (_status.event.go) { + return 6 - get.value(card); } return 0; }); - next.set('go',go); - 'step 1' - if(result.bool){ - if(trigger.addCount!==false){ - trigger.addCount=false; + next.set("go", go); + "step 1"; + if (result.bool) { + if (trigger.addCount !== false) { + trigger.addCount = false; trigger.player.getStat().card.sha--; } - trigger.player.addTempSkill('vtbguisha_bonus'); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.vtbguisha_targets=trigger.targets; + trigger.player.addTempSkill("vtbguisha_bonus"); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.vtbguisha_targets = trigger.targets; } }, - ai:{ - expose:0.2 + ai: { + expose: 0.2, }, - subSkill:{ - bonus:{ - trigger:{ - source:'damageBegin1', + subSkill: { + bonus: { + trigger: { + source: "damageBegin1", }, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.card.storage&&event.card.storage.vtbguisha_targets&&event.card.storage.vtbguisha_targets.includes(event.player); + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.card.storage && + event.card.storage.vtbguisha_targets && + event.card.storage.vtbguisha_targets.includes(event.player) + ); }, - content:function(){ + content: function () { trigger.num++; - } - } - } + }, + }, + }, }, - vtbshuli:{ - audio:1, - trigger:{ - global:'damageSource', + vtbshuli: { + audio: 1, + trigger: { + global: "damageSource", }, - usable:2, - filter:function(event,player){ - return event.source&&event.source!=player&&event.card&&event.card.name=='sha'&&event.source.isIn(); + usable: 2, + filter: function (event, player) { + return ( + event.source && + event.source != player && + event.card && + event.card.name == "sha" && + event.source.isIn() + ); }, - check:function(event,player){ - return get.attitude(player,event.source)>=0||get.attitude(player,event.source)>=-4 - &&get.distance(_status.currentPhase,player,'absolute')>get.distance(_status.currentPhase,event.source,'absolute'); + check: function (event, player) { + return ( + get.attitude(player, event.source) >= 0 || + (get.attitude(player, event.source) >= -4 && + get.distance(_status.currentPhase, player, "absolute") > + get.distance(_status.currentPhase, event.source, "absolute")) + ); }, - content:function(){ - 'step 0' - var drawers=[trigger.source,player].sortBySeat(_status.currentPhase); + content: function () { + "step 0"; + var drawers = [trigger.source, player].sortBySeat(_status.currentPhase); game.asyncDraw(drawers); }, }, //小闪 - vtbshanwu:{ - audio:1, - trigger:{ - global:'useCardToTarget', + vtbshanwu: { + audio: 1, + trigger: { + global: "useCardToTarget", }, - filter:function(event,player){ - return event.card.name=='sha'&&event.target!=player&&event.isFirstTarget&&player.hasCard(card=>{ - return get.name(card)=='shan'||_status.connectMode; - }); + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.target != player && + event.isFirstTarget && + player.hasCard((card) => { + return get.name(card) == "shan" || _status.connectMode; + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('vtbshanwu'),'弃置一张【闪】,取消此【杀】对'+get.translation(trigger.targets)+'的目标',{name:'shan'}).set('logSkill','vtbshanwu').set('ai',card=>{ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',function(){ - var effect=0; - for(var target of trigger.targets){ - var eff=get.effect(target,trigger.card,trigger.player,player); - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||trigger.player.hasSkillTag('directHit_ai',true,{ - target:target, - card:trigger.card, - },true)){ - eff*=1.25; - } - if(target.hp<=2) eff*=1.1; - effect+=eff; - } - return effect<0; - }()); - 'step 1' - if(result.bool){ - game.log(player,'取消了',trigger.card,'的所有目标'); - trigger.targets.length=0; - trigger.getParent().triggeredTargets2.length=0; + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("vtbshanwu"), + "弃置一张【闪】,取消此【杀】对" + get.translation(trigger.targets) + "的目标", + { name: "shan" } + ) + .set("logSkill", "vtbshanwu") + .set("ai", (card) => { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set( + "goon", + (function () { + var effect = 0; + for (var target of trigger.targets) { + var eff = get.effect(target, trigger.card, trigger.player, player); + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + trigger.player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: trigger.card, + }, + true + ) + ) { + eff *= 1.25; + } + if (target.hp <= 2) eff *= 1.1; + effect += eff; + } + return effect < 0; + })() + ); + "step 1"; + if (result.bool) { + game.log(player, "取消了", trigger.card, "的所有目标"); + trigger.targets.length = 0; + trigger.getParent().triggeredTargets2.length = 0; trigger.untrigger(); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - vtbxianli:{ - audio:1, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + vtbxianli: { + audio: 1, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - usable:2, - filter:function(event,player){ - if(!_status.currentPhase||!_status.currentPhase.isIn()||!_status.currentPhase.countGainableCards(player,'he')) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.some(card=>{ - return get.name(card,false)=='shan'; - }); + usable: 2, + filter: function (event, player) { + if ( + !_status.currentPhase || + !_status.currentPhase.isIn() || + !_status.currentPhase.countGainableCards(player, "he") + ) + return false; + var evt = event.getl(player); + return ( + evt && + evt.cards2 && + evt.cards2.some((card) => { + return get.name(card, false) == "shan"; + }) + ); }, - check:function(event,player){ - return get.effect(_status.currentPhase,{name:'shunshou_copy2'},player,player)>0; + check: function (event, player) { + return get.effect(_status.currentPhase, { name: "shunshou_copy2" }, player, player) > 0; }, - prompt2:function(event,player){ - return '获得'+get.translation(_status.currentPhase)+'的一张牌'; + prompt2: function (event, player) { + return "获得" + get.translation(_status.currentPhase) + "的一张牌"; }, - logTarget:()=>_status.currentPhase, - content:function(){ - 'step 0' - player.gainPlayerCard(_status.currentPhase,'he',true); + logTarget: () => _status.currentPhase, + content: function () { + "step 0"; + player.gainPlayerCard(_status.currentPhase, "he", true); + }, + ai: { + expose: 0.15, }, - ai:{ - expose:0.15, - } }, //小桃 - vtbtaoyan:{ - audio:1, - trigger:{ - player:'phaseBegin', + vtbtaoyan: { + audio: 1, + trigger: { + player: "phaseBegin", }, - direct:true, - content:function(){ - 'step 0' - if(!_status.vtbtaoyan_count){ - _status.vtbtaoyan_count=5; + direct: true, + content: function () { + "step 0"; + if (!_status.vtbtaoyan_count) { + _status.vtbtaoyan_count = 5; } - player.chooseTarget(get.prompt('vtbtaoyan'),'令一或两名其他角色摸一张牌并从游戏外获得一张【桃】(♥6)',lib.filter.notMe,[1,2]).set('ai',target=>{ - var player=_status.event.player; - return get.recoverEffect(target,player,player)/2+get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.slice(); + player + .chooseTarget( + get.prompt("vtbtaoyan"), + "令一或两名其他角色摸一张牌并从游戏外获得一张【桃】(♥6)", + lib.filter.notMe, + [1, 2] + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + get.recoverEffect(target, player, player) / 2 + get.attitude(player, target) + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.slice(); targets.sortBySeat(); - player.logSkill('vtbtaoyan',targets); - game.broadcastAll(function(){ - if(!lib.inpile.includes('tao')){ - lib.inpile.add('tao'); + player.logSkill("vtbtaoyan", targets); + game.broadcastAll(function () { + if (!lib.inpile.includes("tao")) { + lib.inpile.add("tao"); } }); - player.addSkill('vtbtaoyan_remove'); - for(var target of targets){ + player.addSkill("vtbtaoyan_remove"); + for (var target of targets) { target.draw(); - if(!_status.vtbtaoyan_count) continue; - if(!_status.vtbtaoyan_cards) _status.vtbtaoyan_cards=[]; + if (!_status.vtbtaoyan_count) continue; + if (!_status.vtbtaoyan_cards) _status.vtbtaoyan_cards = []; _status.vtbtaoyan_count--; - var card=game.createCard('tao','heart',6); + var card = game.createCard("tao", "heart", 6); _status.vtbtaoyan_cards.push(card.cardid); - target.gain(card,'gain2'); + target.gain(card, "gain2"); } } }, - ai:{ - expose:0.3, - threaten:3.2, + ai: { + expose: 0.3, + threaten: 3.2, }, - subSkill:{ - remove:{ - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], + subSkill: { + remove: { + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - forceDie:true, - filter:function(event,player){ - if(typeof _status.vtbtaoyan_count!='number') return false; - var cards=event.getd(); - return cards.some(card=>{ + forced: true, + charlotte: true, + popup: false, + firstDo: true, + forceDie: true, + filter: function (event, player) { + if (typeof _status.vtbtaoyan_count != "number") return false; + var cards = event.getd(); + return cards.some((card) => { return _status.vtbtaoyan_cards.includes(card.cardid); }); }, - content:function(){ - var cards=trigger.getd(),remove=[]; - for(var card of cards){ - if(_status.vtbtaoyan_cards.includes(card.cardid)){ + content: function () { + var cards = trigger.getd(), + remove = []; + for (var card of cards) { + if (_status.vtbtaoyan_cards.includes(card.cardid)) { _status.vtbtaoyan_cards.remove(card.cardid); remove.push(card); } } - if(remove.length){ - remove.forEach(i=>{ + if (remove.length) { + remove.forEach((i) => { i.remove(); _status.vtbtaoyan_count++; }); - game.log(remove,'被移出了游戏'); + game.log(remove, "被移出了游戏"); } }, - } - } + }, + }, }, - vtbyanli:{ - audio:1, - trigger:{ - global:'dying', + vtbyanli: { + audio: 1, + trigger: { + global: "dying", }, - filter:function(event,player){ - if(player.hasSkill('vtbyanli_used')) return false; - if(_status.currentPhase==player) return false; - return event.player.hp<=0; + filter: function (event, player) { + if (player.hasSkill("vtbyanli_used")) return false; + if (_status.currentPhase == player) return false; + return event.player.hp <= 0; }, - check:function(event,player){ - return get.recoverEffect(event.player,player,player)>0; + check: function (event, player) { + return get.recoverEffect(event.player, player, player) > 0; }, - content:function(){ - 'step 0' - player.addTempSkill('vtbyanli_used','roundStart'); - trigger.player.recover(1-trigger.player.hp); + content: function () { + "step 0"; + player.addTempSkill("vtbyanli_used", "roundStart"); + trigger.player.recover(1 - trigger.player.hp); trigger.player.draw(); }, - subSkill:{ - used:{ - charlotte:true, - } - } + subSkill: { + used: { + charlotte: true, + }, + }, }, //小乐 - vtbleyu:{ - audio:1, - trigger:{ - global:'phaseBegin', - }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>=3; - }, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('vtbleyu',trigger.player),3,'he').set('ai',card=>{ - if(ui.selected.cards.length==2) return 10-get.value(card); - if(_status.event.effect>0){ - return 6-get.value(card); - } - return 0; - }).set('effect',trigger.player.hasJudge('lebu')?0:get.effect(trigger.player,{name:'lebu'},player,player)).set('logSkill',['vtbleyu',trigger.player]); - 'step 1' - if(result.bool){ - trigger.player.judge(lib.card.lebu.judge).judge2=lib.card.lebu.judge2; - } else event.finish(); - 'step 2' - if(!result.bool){ - trigger.player.skip('phaseUse'); - } - }, - ai:{ - expose:0.3, - threaten:2.9, - }, - }, - vtbyuanli:{ - audio:1, - trigger:{global:['phaseUseSkipped','phaseUseCancelled']}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('vtbyuanli'),lib.filter.notMe).set('ai',target=>get.attitude(_status.event.player,target)+1); - 'step 1' - if(result.bool){ - player.logSkill('vtbyuanli',result.targets[0]); - game.asyncDraw([player,result.targets[0]].sortBySeat(_status.currentPhase)); - } - }, - ai:{ - expose:0.1, - }, - }, - vtbmeiniang:{ - audio:1, - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player!=player; - }, - check:function(event,player){ - return get.attitude(player,event.player)>0&&event.player.getUseValue('jiu')>=0; - }, - logTarget:'player', - content:function(){ - trigger.player.chooseUseTarget('jiu',true,false); - } - }, - vtbyaoli:{ - audio:1, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.card.name=='jiu'&&event.player!=player&&event.player.isPhaseUsing(); - }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)>0; + vtbleyu: { + audio: 1, + trigger: { + global: "phaseBegin", }, - content:function(){ - trigger.player.addTempSkill('vtbyaoli_effect'); - trigger.player.addMark('vtbyaoli_effect',1,false); - }, - ai:{ - expose:0.15, - }, - subSkill:{ - effect:{ - audio:'vtbyaoli', - charlotte:true, - trigger:{player:'useCard2'}, - forced:true, - popup:false, - onremove:true, - nopop:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countMark('vtbyaoli_effect')>0; - }, - content:function(){ - 'step 0' - trigger.directHit.addArray(game.filterPlayer()); - var num=player.countMark('vtbyaoli_effect'); - if(!game.hasPlayer(current=>{ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,player,current); - })) event.finish(); - else player.chooseTarget('媱丽:是否为'+get.translation(trigger.card)+'额外指定'+(num>1?'至多':'')+get.cnNumber(num)+'个目标?',num==1?1:[1,num],(card,player,target)=>{ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target); - }).set('sourcex',trigger.targets).set('ai',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.delayx(); - event.targets=result.targets; - } - else { - event.finish(); - } - 'step 2' - player.logSkill('vtbyaoli_effect',event.targets); - trigger.targets.addArray(event.targets); - player.removeSkill('vtbyaoli_effect'); - }, - marktext:'媱', - intro:{ - content:'下一张【杀】不可被响应且可以额外指定&个目标', - }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.card.name=='sha'; - }, - } - } - } + direct: true, + filter: function (event, player) { + return player.countCards("he") >= 3; + }, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("vtbleyu", trigger.player), 3, "he") + .set("ai", (card) => { + if (ui.selected.cards.length == 2) return 10 - get.value(card); + if (_status.event.effect > 0) { + return 6 - get.value(card); + } + return 0; + }) + .set( + "effect", + trigger.player.hasJudge("lebu") + ? 0 + : get.effect(trigger.player, { name: "lebu" }, player, player) + ) + .set("logSkill", ["vtbleyu", trigger.player]); + "step 1"; + if (result.bool) { + trigger.player.judge(lib.card.lebu.judge).judge2 = lib.card.lebu.judge2; + } else event.finish(); + "step 2"; + if (!result.bool) { + trigger.player.skip("phaseUse"); + } + }, + ai: { + expose: 0.3, + threaten: 2.9, + }, + }, + vtbyuanli: { + audio: 1, + trigger: { global: ["phaseUseSkipped", "phaseUseCancelled"] }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("vtbyuanli"), lib.filter.notMe) + .set("ai", (target) => get.attitude(_status.event.player, target) + 1); + "step 1"; + if (result.bool) { + player.logSkill("vtbyuanli", result.targets[0]); + game.asyncDraw([player, result.targets[0]].sortBySeat(_status.currentPhase)); + } + }, + ai: { + expose: 0.1, + }, + }, + vtbmeiniang: { + audio: 1, + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return event.player != player; + }, + check: function (event, player) { + return get.attitude(player, event.player) > 0 && event.player.getUseValue("jiu") >= 0; + }, + logTarget: "player", + content: function () { + trigger.player.chooseUseTarget("jiu", true, false); + }, + }, + vtbyaoli: { + audio: 1, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return event.card.name == "jiu" && event.player != player && event.player.isPhaseUsing(); + }, + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + content: function () { + trigger.player.addTempSkill("vtbyaoli_effect"); + trigger.player.addMark("vtbyaoli_effect", 1, false); + }, + ai: { + expose: 0.15, + }, + subSkill: { + effect: { + audio: "vtbyaoli", + charlotte: true, + trigger: { player: "useCard2" }, + forced: true, + popup: false, + onremove: true, + nopop: true, + filter: function (event, player) { + return event.card.name == "sha" && player.countMark("vtbyaoli_effect") > 0; }, + content: function () { + "step 0"; + trigger.directHit.addArray(game.filterPlayer()); + var num = player.countMark("vtbyaoli_effect"); + if ( + !game.hasPlayer((current) => { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, player, current) + ); + }) + ) + event.finish(); + else + player + .chooseTarget( + "媱丽:是否为" + + get.translation(trigger.card) + + "额外指定" + + (num > 1 ? "至多" : "") + + get.cnNumber(num) + + "个目标?", + num == 1 ? 1 : [1, num], + (card, player, target) => { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("ai", (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.delayx(); + event.targets = result.targets; + } else { + event.finish(); + } + "step 2"; + player.logSkill("vtbyaoli_effect", event.targets); + trigger.targets.addArray(event.targets); + player.removeSkill("vtbyaoli_effect"); + }, + marktext: "媱", + intro: { + content: "下一张【杀】不可被响应且可以额外指定&个目标", + }, + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg.card.name == "sha"; + }, + }, + }, + }, + }, //官盗S特015神马超 - psshouli:{ - audio:'shouli', - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - if(player!=_status.currentPhase&&(name=='sha'||name=='shan')) return true; + psshouli: { + audio: "shouli", + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + if (player != _status.currentPhase && (name == "sha" || name == "shan")) return true; }, - filter:function(event,player){ - if(event.responded||event.psshouli||event.type=='wuxie') return false; - if(game.hasPlayer(function(current){ - return current.getEquips(4).length>0; - })&&event.filterCard(get.autoViewAs({ - name:'sha', - storage:{psshouli:true}, - },'unsure'),player,event)) return true; - if(game.hasPlayer(function(current){ - return current.getEquips(3).length>0; - })&&event.filterCard(get.autoViewAs({ - name:'shan', - storage:{psshouli:true}, - },'unsure'),player,event)) return true; + filter: function (event, player) { + if (event.responded || event.psshouli || event.type == "wuxie") return false; + if ( + game.hasPlayer(function (current) { + return current.getEquips(4).length > 0; + }) && + event.filterCard( + get.autoViewAs( + { + name: "sha", + storage: { psshouli: true }, + }, + "unsure" + ), + player, + event + ) + ) + return true; + if ( + game.hasPlayer(function (current) { + return current.getEquips(3).length > 0; + }) && + event.filterCard( + get.autoViewAs( + { + name: "shan", + storage: { psshouli: true }, + }, + "unsure" + ), + player, + event + ) + ) + return true; return false; }, - delay:false, - locked:true, - filterTarget:function(card,player,target){ - var event=_status.event,evt=event; - if(event._backup) evt=event._backup; - var equip3=target.getCards('e',card=>get.is.defendingMount(card,false)); - var equip4=target.getCards('e',card=>get.is.attackingMount(card,false)); - if(equip3.length&&equip3.some(card=>evt.filterCard(get.autoViewAs({ - name:'shan', - storage:{psshouli:true}, - },[card]),player,event))) return true; - return equip4.some(card=>{ - var sha=get.autoViewAs({ - name:'sha', - storage:{psshouli:true}, - },[card]); - if(evt.filterCard(sha,player,event)){ - if(!evt.filterTarget) return true; - return game.hasPlayer(function(current){ - return evt.filterTarget(sha,player,current); - }) - } - }) - }, - prompt:'将场上的一张坐骑牌当做【杀】或【闪】使用或打出', - content:function(){ - 'step 0' - var evt=event.getParent(2); - evt.set('psshouli',true); - var list=[]; - var equip3=target.getCards('e',card=>get.is.defendingMount(card,false)); - var equip4=target.getCards('e',card=>get.is.attackingMount(card,false)); - var backupx=_status.event; - _status.event=evt; - try{ - if(equip3.length&&equip3.some(card=>{ - var shan=get.autoViewAs({ - name:'shan', - storage:{psshouli:true}, - },[card]); - if(evt.filterCard(shan,player,event)) return true; - return false; - })){ - list.push('shan'); - } - if(equip4.length&&equip4.some(card=>{ - var sha=get.autoViewAs({ - name:'sha', - storage:{psshouli:true}, - },[card]); - if(evt.filterCard(sha,player,evt)&&(!evt.filterTarget||game.hasPlayer(function(current){ - return evt.filterTarget(sha,player,current); - }))) return true; - return false; - })){ - list.push('sha'); - } - }catch(e){game.print(e)} - _status.event=backupx; - if(list.length==1){ - event.cardName=list[0]; - var cards=list[0]=='shan'?equip3:equip4; - if(cards.length==1) event._result={ - bool:true, - links:[cards[0]], - } - else player.choosePlayerCard(true,target,'e').set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards) - } - else player.choosePlayerCard(true,target,'e').set('filterButton',function(button){ - var card=button.link; - return get.is.attackingMount(card)||get.is.defendingMount(card); - }); - 'step 1' - var evt=event.getParent(2); - if(result.bool&&result.links&&result.links.length){ - var name=(event.cardName||(get.is.attackingMount(result.links[0])?'sha':'shan')); - if(evt.name=='chooseToUse'){ - game.broadcastAll(function(result,name){ - lib.skill.psshouli_backup.viewAs={ - name:name, - cards:[result], - storage:{psshouli:true}, - }; - lib.skill.psshouli_backup.prompt=('选择'+get.translation(name)+'('+get.translation(result)+')的目标'); - },result.links[0],name); - evt.set('_backupevent','psshouli_backup'); - evt.backup('psshouli_backup'); - evt.set('openskilldialog','选择'+get.translation(name)+'('+get.translation(result.links[0])+')的目标'); - evt.set('norestore',true); - evt.set('custom',{ - add:{}, - replace:{window:function(){}} + delay: false, + locked: true, + filterTarget: function (card, player, target) { + var event = _status.event, + evt = event; + if (event._backup) evt = event._backup; + var equip3 = target.getCards("e", (card) => get.is.defendingMount(card, false)); + var equip4 = target.getCards("e", (card) => get.is.attackingMount(card, false)); + if ( + equip3.length && + equip3.some((card) => + evt.filterCard( + get.autoViewAs( + { + name: "shan", + storage: { psshouli: true }, + }, + [card] + ), + player, + event + ) + ) + ) + return true; + return equip4.some((card) => { + var sha = get.autoViewAs( + { + name: "sha", + storage: { psshouli: true }, + }, + [card] + ); + if (evt.filterCard(sha, player, event)) { + if (!evt.filterTarget) return true; + return game.hasPlayer(function (current) { + return evt.filterTarget(sha, player, current); }); } - else{ + }); + }, + prompt: "将场上的一张坐骑牌当做【杀】或【闪】使用或打出", + content: function () { + "step 0"; + var evt = event.getParent(2); + evt.set("psshouli", true); + var list = []; + var equip3 = target.getCards("e", (card) => get.is.defendingMount(card, false)); + var equip4 = target.getCards("e", (card) => get.is.attackingMount(card, false)); + var backupx = _status.event; + _status.event = evt; + try { + if ( + equip3.length && + equip3.some((card) => { + var shan = get.autoViewAs( + { + name: "shan", + storage: { psshouli: true }, + }, + [card] + ); + if (evt.filterCard(shan, player, event)) return true; + return false; + }) + ) { + list.push("shan"); + } + if ( + equip4.length && + equip4.some((card) => { + var sha = get.autoViewAs( + { + name: "sha", + storage: { psshouli: true }, + }, + [card] + ); + if ( + evt.filterCard(sha, player, evt) && + (!evt.filterTarget || + game.hasPlayer(function (current) { + return evt.filterTarget(sha, player, current); + })) + ) + return true; + return false; + }) + ) { + list.push("sha"); + } + } catch (e) { + game.print(e); + } + _status.event = backupx; + if (list.length == 1) { + event.cardName = list[0]; + var cards = list[0] == "shan" ? equip3 : equip4; + if (cards.length == 1) + event._result = { + bool: true, + links: [cards[0]], + }; + else + player + .choosePlayerCard(true, target, "e") + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set("cards", cards); + } else + player.choosePlayerCard(true, target, "e").set("filterButton", function (button) { + var card = button.link; + return get.is.attackingMount(card) || get.is.defendingMount(card); + }); + "step 1"; + var evt = event.getParent(2); + if (result.bool && result.links && result.links.length) { + var name = + event.cardName || (get.is.attackingMount(result.links[0]) ? "sha" : "shan"); + if (evt.name == "chooseToUse") { + game.broadcastAll( + function (result, name) { + lib.skill.psshouli_backup.viewAs = { + name: name, + cards: [result], + storage: { psshouli: true }, + }; + lib.skill.psshouli_backup.prompt = + "选择" + + get.translation(name) + + "(" + + get.translation(result) + + ")的目标"; + }, + result.links[0], + name + ); + evt.set("_backupevent", "psshouli_backup"); + evt.backup("psshouli_backup"); + evt.set( + "openskilldialog", + "选择" + + get.translation(name) + + "(" + + get.translation(result.links[0]) + + ")的目标" + ); + evt.set("norestore", true); + evt.set("custom", { + add: {}, + replace: { window: function () {} }, + }); + } else { delete evt.result.skill; delete evt.result.used; - evt.result.card=get.autoViewAs({ - name:name, - cards:[result.links[0]], - storage:{psshouli:true}, - },result.links); - evt.result.cards=[result.links[0]]; - target.$give(result.links[0],player,false); - if(player!=target) target.addTempSkill('fengyin'); - target.addTempSkill('psshouli_thunder'); - player.addTempSkill('psshouli_thunder'); + evt.result.card = get.autoViewAs( + { + name: name, + cards: [result.links[0]], + storage: { psshouli: true }, + }, + result.links + ); + evt.result.cards = [result.links[0]]; + target.$give(result.links[0], player, false); + if (player != target) target.addTempSkill("fengyin"); + target.addTempSkill("psshouli_thunder"); + player.addTempSkill("psshouli_thunder"); evt.redo(); return; } } evt.goto(0); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ - var func=get.is[tag=='respondSha'?'attackingMount':'defendingMount']; - return game.hasPlayer(function(current){ - return current.hasCard(card=>func(card,false),'e'); + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { + var func = get.is[tag == "respondSha" ? "attackingMount" : "defendingMount"]; + return game.hasPlayer(function (current) { + return current.hasCard((card) => func(card, false), "e"); }); }, - order:2, - result:{ - player:function(player,target){ - var att=Math.max(8,get.attitude(player,target)); - if(_status.event.type!='phase') return 9-att; - if(!player.hasValueTarget({name:'sha'})) return 0; - return 9-att; + order: 2, + result: { + player: function (player, target) { + var att = Math.max(8, get.attitude(player, target)); + if (_status.event.type != "phase") return 9 - att; + if (!player.hasValueTarget({ name: "sha" })) return 0; + return 9 - att; }, }, }, - group:'psshouli_init', - subSkill:{ - thunder:{ - charlotte:true, - trigger:{player:'damageBegin1'}, - forced:true, - mark:true, - content:function(){ + group: "psshouli_init", + subSkill: { + thunder: { + charlotte: true, + trigger: { player: "damageBegin1" }, + forced: true, + mark: true, + content: function () { trigger.num++; - game.setNature(trigger,'thunder'); + game.setNature(trigger, "thunder"); }, - marktext:'⚡', - intro:{ - content:'受到的伤害+1且改为雷属性', + marktext: "⚡", + intro: { + content: "受到的伤害+1且改为雷属性", }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')) return; - if(target.hasSkillTag('nodamage')||target.hasSkillTag('nothunder')) return 'zeroplayertarget'; - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:new lib.element.VCard({ - name:card.name, - nature:'thunder' - },[card]) - })) return; + ai: { + effect: { + target: (card, player, target) => { + if (!get.tag(card, "damage")) return; + if (target.hasSkillTag("nodamage") || target.hasSkillTag("nothunder")) + return "zeroplayertarget"; + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: new lib.element.VCard( + { + name: card.name, + nature: "thunder", + }, + [card] + ), + }) + ) + return; return 2; - } - } - } + }, + }, + }, }, - init:{ - audio:'psshouli', - trigger:{ - global:'phaseBefore', - player:'enterGame', + init: { + audio: "psshouli", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - logTarget:()=>game.filterPlayer(), - equips:[ - ['heart',5,'chitu'], - ['diamond',13,'zixin'], - ['spade',5,'jueying'], - ['diamond',13,'hualiu'], - ['club',5,'dilu'], - ['spade',13,'dawan'], - ['heart',13,'zhuahuang'], - ['heart',3,'jingfanma'] + logTarget: () => game.filterPlayer(), + equips: [ + ["heart", 5, "chitu"], + ["diamond", 13, "zixin"], + ["spade", 5, "jueying"], + ["diamond", 13, "hualiu"], + ["club", 5, "dilu"], + ["spade", 13, "dawan"], + ["heart", 13, "zhuahuang"], + ["heart", 3, "jingfanma"], ], - content:function(){ - 'step 0' - event.targets=game.filterPlayer().sortBySeat(_status.firstAct2||game.zhong||game.zhu||_status.firstAct||player); - event.target=event.targets.shift(); + content: function () { + "step 0"; + event.targets = game + .filterPlayer() + .sortBySeat( + _status.firstAct2 || game.zhong || game.zhu || _status.firstAct || player + ); + event.target = event.targets.shift(); game.delayx(); - 'step 1' - player.line(target,'green'); - target.chooseToUse('狩骊:使用一张坐骑牌并摸一张牌,或使用一张坐骑牌指示物',function(card,player,event){ - if(get.subtype(card)!='equip3'&&get.subtype(card)!='equip4'&&get.subtype(card)!='equip6') return false; - return lib.filter.filterCard.apply(this,arguments); - }).set('ai',()=>1); - 'step 2' - if(result.bool) target.draw(); - else{ - var cardx=lib.skill.psshouli_init.equips.randomRemove(); - if(!cardx) return; - cardx={ - suit:cardx[0], - number:cardx[1], - name:cardx[2], - } - var card=game.createCard(cardx); - if(!_status.psshouli_equips) _status.psshouli_equips=[]; + "step 1"; + player.line(target, "green"); + target + .chooseToUse( + "狩骊:使用一张坐骑牌并摸一张牌,或使用一张坐骑牌指示物", + function (card, player, event) { + if ( + get.subtype(card) != "equip3" && + get.subtype(card) != "equip4" && + get.subtype(card) != "equip6" + ) + return false; + return lib.filter.filterCard.apply(this, arguments); + } + ) + .set("ai", () => 1); + "step 2"; + if (result.bool) target.draw(); + else { + var cardx = lib.skill.psshouli_init.equips.randomRemove(); + if (!cardx) return; + cardx = { + suit: cardx[0], + number: cardx[1], + name: cardx[2], + }; + var card = game.createCard(cardx); + if (!_status.psshouli_equips) _status.psshouli_equips = []; _status.psshouli_equips.push(card.cardid); - if(card){ - target.chooseUseTarget(card,true,'nopopup','noanimate'); - player.addSkill('psshouli_remove'); + if (card) { + target.chooseUseTarget(card, true, "nopopup", "noanimate"); + player.addSkill("psshouli_remove"); } } - 'step 3' - event.target=event.targets.shift(); - if(event.target){ + "step 3"; + event.target = event.targets.shift(); + if (event.target) { event.goto(1); } }, }, - remove:{ - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], + remove: { + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - forceDie:true, - filter:function(event,player){ - if(!_status.psshouli_equips||!_status.psshouli_equips.length) return false; - var cards=event.getd(); - return cards.filter(i=>_status.psshouli_equips.includes(i.cardid)).length; + forced: true, + charlotte: true, + popup: false, + firstDo: true, + forceDie: true, + filter: function (event, player) { + if (!_status.psshouli_equips || !_status.psshouli_equips.length) return false; + var cards = event.getd(); + return cards.filter((i) => _status.psshouli_equips.includes(i.cardid)).length; }, - content:function(){ - var cards=trigger.getd(),remove=[]; - for(var card of cards){ - if(_status.psshouli_equips.includes(card.cardid)){ + content: function () { + var cards = trigger.getd(), + remove = []; + for (var card of cards) { + if (_status.psshouli_equips.includes(card.cardid)) { _status.psshouli_equips.remove(card.cardid); remove.push(card); } } - if(remove.length){ + if (remove.length) { game.cardsGotoSpecial(remove); - lib.skill.psshouli_init.equips.addArray(remove.map(i=>[i.suit,i.number,i.name])); - game.log('坐骑指示物',remove,'被移出了游戏'); + lib.skill.psshouli_init.equips.addArray( + remove.map((i) => [i.suit, i.number, i.name]) + ); + game.log("坐骑指示物", remove, "被移出了游戏"); } }, - } + }, }, }, - psshouli_backup:{ - sourceSkill:'psshouli', - precontent:function(){ - 'step 0' + psshouli_backup: { + sourceSkill: "psshouli", + precontent: function () { + "step 0"; delete event.result.skill; - event.result._apply_args={'throw':false}; - var cards=event.result.card.cards; - event.result.cards=cards; - var owner=get.owner(cards[0]); - event.target=owner; + event.result._apply_args = { throw: false }; + var cards = event.result.card.cards; + event.result.cards = cards; + var owner = get.owner(cards[0]); + event.target = owner; owner.$throw(cards[0]); - player.popup(event.result.card.name,'metal'); + player.popup(event.result.card.name, "metal"); game.delayx(); - event.getParent().addCount=false; - 'step 1' - if(player!=target) target.addTempSkill('fengyin'); - target.addTempSkill('psshouli_thunder'); - player.addTempSkill('psshouli_thunder'); + event.getParent().addCount = false; + "step 1"; + if (player != target) target.addTempSkill("fengyin"); + target.addTempSkill("psshouli_thunder"); + player.addTempSkill("psshouli_thunder"); }, - filterCard:function(){return false}, - prompt:'请选择【杀】的目标', - selectCard:-1, - }, - pshengwu:{ - audio:'hengwu', - mod:{ - aiOrder:(player,card,num)=>{ - if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0; - }, - aiValue:(player,card,num)=>{ - if(num>0&&card.name==='zhuge') return 20; - }, - aiUseful:(player,card,num)=>{ - if(num>0&&card.name==='zhuge') return 10; - } - }, - trigger:{player:['useCard','respond']}, - direct:true, - locked:false, - filter:function(event,player){ - return game.hasPlayer(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(event.card)==get.suit(cardx))); - }, - content:function(){ - 'step 0' - var suit=get.suit(trigger.card),extra=game.filterPlayer().map(i=>i.countCards('ej',cardx=>{ - return get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx); - })).reduce((p,c)=>p+c); - var prompt2='弃置任意张'+get.translation(suit)+'手牌,然后摸X张牌(X为你弃置的牌数+'+extra+')'; - player.chooseToDiscard('h',[1,player.countCards('h',{suit:suit})],{suit:suit}).set('prompt',get.prompt('pshengwu')).set('prompt2',prompt2).set('ai',card=>{ - if(_status.event.tie) return 0; - let player=_status.event.player; - if(_status.event.goon) return 12-get.value(card); - if(player==_status.currentPhase){ - if(['shan','caochuan','tao','wuxie'].includes(card.name)) return 8-get.value(card); - return 6-get.value(card); - } - return 5.5-get.value(card); - }).set('goon',player.countCards('h',{suit:suit})==1).set('tie',extra>ui.cardPile.childNodes.length+ui.discardPile.childNodes.length).set('logSkill','pshengwu'); - 'step 1' - if(result.bool){ - var num=result.cards.length; - player.draw(num+game.filterPlayer().map(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx))).reduce((p,c)=>p+c)); - } - }, - ai:{ - threaten:100, - reverseEquip:true, - effect:{ - player:(card,player,target)=>{ - if(typeof card!=='object') return; - let suit=get.suit(card); - if(!lib.suit.includes(suit)||player.hasCard(function(i){ - return get.suit(i,player)==suit; - },'h')) return; - return [1,game.countPlayer(current=>{ - return current.countCards('e',card=>{ - return get.suit(card,current)==suit; - }); - })]; - }, - target:(card,player,target)=>{ - if(card.name==='sha'&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card - },true)&&game.hasPlayer(current=>{ - return current.hasCard(cardx=>{ - return get.subtype(cardx)==='equip3'; - },'e'); - })) return [0, -0.5]; - } - } - } - }, - //战役篇田丰 - gzsuishi:{ - audio:'suishi', - preHidden:['gzsuishi2'], - trigger:{global:'dying'}, - forced:true, - //priority:6.5, - check:function(){ + filterCard: function () { return false; }, - filter:function(event,player){ - return event.player!=player&&event.parent.name=='damage'&&event.parent.source&&event.parent.source.isFriendOf(player); + prompt: "请选择【杀】的目标", + selectCard: -1, + }, + pshengwu: { + audio: "hengwu", + mod: { + aiOrder: (player, card, num) => { + if ( + num > 0 && + get.tag(card, "draw") && + ui.cardPile.childNodes.length + ui.discardPile.childNodes.length < 20 + ) + return 0; + }, + aiValue: (player, card, num) => { + if (num > 0 && card.name === "zhuge") return 20; + }, + aiUseful: (player, card, num) => { + if (num > 0 && card.name === "zhuge") return 10; + }, }, - content:function(){ + trigger: { player: ["useCard", "respond"] }, + direct: true, + locked: false, + filter: function (event, player) { + return game.hasPlayer((i) => + i.countCards( + "ej", + (cardx) => get.type(cardx) == "equip" && get.suit(event.card) == get.suit(cardx) + ) + ); + }, + content: function () { + "step 0"; + var suit = get.suit(trigger.card), + extra = game + .filterPlayer() + .map((i) => + i.countCards("ej", (cardx) => { + return ( + get.type(cardx) == "equip" && + get.suit(trigger.card) == get.suit(cardx) + ); + }) + ) + .reduce((p, c) => p + c); + var prompt2 = + "弃置任意张" + + get.translation(suit) + + "手牌,然后摸X张牌(X为你弃置的牌数+" + + extra + + ")"; + player + .chooseToDiscard("h", [1, player.countCards("h", { suit: suit })], { suit: suit }) + .set("prompt", get.prompt("pshengwu")) + .set("prompt2", prompt2) + .set("ai", (card) => { + if (_status.event.tie) return 0; + let player = _status.event.player; + if (_status.event.goon) return 12 - get.value(card); + if (player == _status.currentPhase) { + if (["shan", "caochuan", "tao", "wuxie"].includes(card.name)) + return 8 - get.value(card); + return 6 - get.value(card); + } + return 5.5 - get.value(card); + }) + .set("goon", player.countCards("h", { suit: suit }) == 1) + .set("tie", extra > ui.cardPile.childNodes.length + ui.discardPile.childNodes.length) + .set("logSkill", "pshengwu"); + "step 1"; + if (result.bool) { + var num = result.cards.length; + player.draw( + num + + game + .filterPlayer() + .map((i) => + i.countCards( + "ej", + (cardx) => + get.type(cardx) == "equip" && + get.suit(trigger.card) == get.suit(cardx) + ) + ) + .reduce((p, c) => p + c) + ); + } + }, + ai: { + threaten: 100, + reverseEquip: true, + effect: { + player: (card, player, target) => { + if (typeof card !== "object") return; + let suit = get.suit(card); + if ( + !lib.suit.includes(suit) || + player.hasCard(function (i) { + return get.suit(i, player) == suit; + }, "h") + ) + return; + return [ + 1, + game.countPlayer((current) => { + return current.countCards("e", (card) => { + return get.suit(card, current) == suit; + }); + }), + ]; + }, + target: (card, player, target) => { + if ( + card.name === "sha" && + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) && + game.hasPlayer((current) => { + return current.hasCard((cardx) => { + return get.subtype(cardx) === "equip3"; + }, "e"); + }) + ) + return [0, -0.5]; + }, + }, + }, + }, + //战役篇田丰 + gzsuishi: { + audio: "suishi", + preHidden: ["gzsuishi2"], + trigger: { global: "dying" }, + forced: true, + //priority:6.5, + check: function () { + return false; + }, + filter: function (event, player) { + return ( + event.player != player && + event.parent.name == "damage" && + event.parent.source && + event.parent.source.isFriendOf(player) + ); + }, + content: function () { player.draw(); }, - group:'gzsuishi2' + group: "gzsuishi2", }, - gzsuishi2:{ - audio:'suishi', - trigger:{global:'dieAfter'}, - forced:true, - check:function(){return false}, - filter:function(event,player){ + gzsuishi2: { + audio: "suishi", + trigger: { global: "dieAfter" }, + forced: true, + check: function () { + return false; + }, + filter: function (event, player) { return event.player.isFriendOf(player); }, - content:function(){ + content: function () { player.loseHp(); - } + }, }, //战役篇孔融 - zymingshi:{ - audio:'mingshi', - forced:true, - trigger:{target:'useCardToBefore'}, - priority:15, - filter:function(event,player){ - if(!player.hasEmptySlot(2)) return false; - if(event.card.name!='sha') return false; + zymingshi: { + audio: "mingshi", + forced: true, + trigger: { target: "useCardToBefore" }, + priority: 15, + filter: function (event, player) { + if (!player.hasEmptySlot(2)) return false; + if (event.card.name != "sha") return false; return game.hasNature(event.card); }, - content:function(){ + 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]; - } - } - } + 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]; + }, + }, + }, }, //战役篇蒋钦 - zyshangyi:{ - audio:'shangyi', - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target; + zyshangyi: { + audio: "shangyi", + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.viewHandcards(player); - 'step 1' - if(!target.countCards('h')) event.finish(); - else player.chooseCardButton(target,target.getCards('h')); - 'step 2' - if(result.bool){ + "step 1"; + if (!target.countCards("h")) event.finish(); + else player.chooseCardButton(target, target.getCards("h")); + "step 2"; + if (result.bool) { target.discard(result.links[0]); } }, - ai:{ - order:11, - result:{ - target:function(player,target){ - return -target.countCards('h'); - } + ai: { + order: 11, + result: { + target: function (player, target) { + return -target.countCards("h"); + }, }, - threaten:1.1 + threaten: 1.1, }, }, //官盗K系列杜预 - pkwuku:{ - audio:'spwuku', - trigger:{global:'useCard'}, - forced:true, - preHidden:true, - filter:function(event,player){ - if(get.type(event.card)!='equip') return false; - return player.countMark('pkwuku')<3; + pkwuku: { + audio: "spwuku", + trigger: { global: "useCard" }, + forced: true, + preHidden: true, + filter: function (event, player) { + if (get.type(event.card) != "equip") return false; + return player.countMark("pkwuku") < 3; }, - content:function(){ - player.addMark('pkwuku',1); + content: function () { + player.addMark("pkwuku", 1); }, - marktext:'库', - intro:{ - content:'mark', + marktext: "库", + intro: { + content: "mark", }, - ai:{ - combo:'pksanchen', - threaten:3.6, + ai: { + combo: "pksanchen", + threaten: 3.6, }, }, - pksanchen:{ - audio:'spsanchen', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.countMark('pkwuku')>2; + pksanchen: { + audio: "spsanchen", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.countMark("pkwuku") > 2; }, - content:function(){ - player.awakenSkill('pksanchen'); + content: function () { + player.awakenSkill("pksanchen"); player.gainMaxHp(); player.recover(); - player.addSkills('pkmiewu'); + player.addSkills("pkmiewu"); }, - ai:{ - combo:'wuku', + ai: { + combo: "pkwuku", }, - derivation:'pkmiewu', + derivation: "pkmiewu", }, - pkmiewu:{ - audio:'spmiewu', - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - if(!player.countMark('pkwuku')||player.hasSkill('pkmiewu2')) return false; - for(var i of lib.inpile){ - var type=get.type(i); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; + pkmiewu: { + audio: "spmiewu", + enable: ["chooseToUse", "chooseToRespond"], + filter: function (event, player) { + if (!player.countMark("pkwuku") || player.hasSkill("pkmiewu2")) return false; + for (var i of lib.inpile) { + var type = get.type(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i=0;ifalse, - selectCard:-1, - popname:true, - viewAs:{name:links[0][2],nature:links[0][3]}, - precontent:function(){ - player.addTempSkill('pkmiewu2'); - player.removeMark('pkwuku',1); + audio: "spmiewu", + filterCard: () => false, + selectCard: -1, + popname: true, + viewAs: { name: links[0][2], nature: links[0][3] }, + precontent: function () { + player.addTempSkill("pkmiewu2"); + player.removeMark("pkwuku", 1); }, - } + }; }, - prompt:function(links,player){ - return '视为使用'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'并摸一张牌'; - } - }, - hiddenCard:function(player,name){ - if(!lib.inpile.includes(name)) return false; - var type=get.type(name); - return (type=='basic'||type=='trick')&&player.countMark('pkwuku')>0&&!player.hasSkill('pkmiewu2'); - }, - ai:{ - combo:'pkwuku', - fireAttack:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - if(!player.countMark('pkwuku')||player.hasSkill('pkmiewu2')) return false; + prompt: function (links, player) { + return ( + "视为使用" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "并摸一张牌" + ); }, - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + }, + hiddenCard: function (player, name) { + if (!lib.inpile.includes(name)) return false; + var type = get.type(name); + return ( + (type == "basic" || type == "trick") && + player.countMark("pkwuku") > 0 && + !player.hasSkill("pkmiewu2") + ); + }, + ai: { + combo: "pkwuku", + fireAttack: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + if (!player.countMark("pkwuku") || player.hasSkill("pkmiewu2")) return false; + }, + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, }, - pkmiewu2:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return event.skill=='pkmiewu_backup'; + pkmiewu2: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return event.skill == "pkmiewu_backup"; }, - content:function(){ + content: function () { player.draw(); }, }, - pkmiewu_backup:{audio:'pkmiewu'}, + pkmiewu_backup: { audio: "pkmiewu" }, //官盗S系列关羽 - pszhonghun:{ - audio:'zhongyi', - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - return get.color(event.card)=='red'; + pszhonghun: { + audio: "zhongyi", + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + return get.color(event.card) == "red"; }, - frequent:true, - content:function(){ - 'step 0' - var card=game.cardsGotoOrdering(get.cards()).cards[0]; - event.card=card; + frequent: true, + content: function () { + "step 0"; + var card = game.cardsGotoOrdering(get.cards()).cards[0]; + event.card = card; game.updateRoundNumber(); - player.showCards(card,get.translation(player)+'发动了【忠魂】'); - 'step 1' - if(get.color(card)=='red') player.gain(card,'gain2'); - } + player.showCards(card, get.translation(player) + "发动了【忠魂】"); + "step 1"; + if (get.color(card) == "red") player.gain(card, "gain2"); + }, }, //官盗S系列郭嘉·一版 - psqizuo:{ - audio:2, - trigger:{global:['damageBegin1','damageBegin3']}, - filter:function(event,player,name){ - return name=='damageBegin1'&&event.source&&event.source.isIn()&&player.inRange(event.source)||name=='damageBegin3'&&event.player&&event.player.isIn()&&player.inRange(event.player); + psqizuo: { + audio: 2, + trigger: { global: ["damageBegin1", "damageBegin3"] }, + filter: function (event, player, name) { + return ( + (name == "damageBegin1" && + event.source && + event.source.isIn() && + player.inRange(event.source)) || + (name == "damageBegin3" && + event.player && + event.player.isIn() && + player.inRange(event.player)) + ); }, - direct:true, - content:function(){ - 'step 0' - var name=event.triggername; - var source=get.translation(trigger.source),target=get.translation(trigger.player),num=trigger.num; - var targetx=trigger[name=='damageBegin1'?'source':'player']; - var str=name=='damageBegin1'?(source+'即将对'+target+'造成'+num+'点伤害'):(target+'即将受到'+source+'造成的'+num+'点伤害'); - player.chooseToDiscard(get.prompt('psqizuo',targetx),str+',是否弃置一张牌并判定,若结果颜色与此牌相同,你可以令此伤害+1或-1?','he').set('ai',card=>{ - if(_status.event.goon) return 5.25-get.value(card)+(get.color(card)==get.color(_status.pileTop)?0.75:0); - return 0; - }).set('goon',function(){ - var eff=get.damageEffect(trigger.player,trigger.source,player); - if(eff>5&&!trigger.player.hasSkillTag('filterDamage',null,{ - player:player, - card:trigger.card, - })) return true; - if(eff<-5) return true; - return false; - }()).set('logSkill',['psqizuo',targetx]); - 'step 1' - if(result.bool){ - event.color=get.color(result.cards[0],player); - player.judge(function(card){ - if(get.color(card)==_status.event.getParent('psqizuo').color) return 1; + direct: true, + content: function () { + "step 0"; + var name = event.triggername; + var source = get.translation(trigger.source), + target = get.translation(trigger.player), + num = trigger.num; + var targetx = trigger[name == "damageBegin1" ? "source" : "player"]; + var str = + name == "damageBegin1" + ? source + "即将对" + target + "造成" + num + "点伤害" + : target + "即将受到" + source + "造成的" + num + "点伤害"; + player + .chooseToDiscard( + get.prompt("psqizuo", targetx), + str + ",是否弃置一张牌并判定,若结果颜色与此牌相同,你可以令此伤害+1或-1?", + "he" + ) + .set("ai", (card) => { + if (_status.event.goon) + return ( + 5.25 - + get.value(card) + + (get.color(card) == get.color(_status.pileTop) ? 0.75 : 0) + ); + return 0; + }) + .set( + "goon", + (function () { + var eff = get.damageEffect(trigger.player, trigger.source, player); + if ( + eff > 5 && + !trigger.player.hasSkillTag("filterDamage", null, { + player: player, + card: trigger.card, + }) + ) + return true; + if (eff < -5) return true; + return false; + })() + ) + .set("logSkill", ["psqizuo", targetx]); + "step 1"; + if (result.bool) { + event.color = get.color(result.cards[0], player); + player.judge(function (card) { + if (get.color(card) == _status.event.getParent("psqizuo").color) return 1; return 0; }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.chooseControl('+1','-1','cancel2').set('prompt','是否令此伤害+1或-1?').set('ai',()=>{ - if(_status.event.eff<0) return 1; - return 0; - }).set('eff',get.damageEffect(trigger.player,trigger.source,player)); - } - else event.finish(); - 'step 3' - if(result.index==0){ + } else event.finish(); + "step 2"; + if (result.bool) { + player + .chooseControl("+1", "-1", "cancel2") + .set("prompt", "是否令此伤害+1或-1?") + .set("ai", () => { + if (_status.event.eff < 0) return 1; + return 0; + }) + .set("eff", get.damageEffect(trigger.player, trigger.source, player)); + } else event.finish(); + "step 3"; + if (result.index == 0) { trigger.num++; - player.popup(' +1 ','fire'); - game.log(player,'令此伤害+1'); + player.popup(" +1 ", "fire"); + game.log(player, "令此伤害+1"); } - if(result.index==1){ + if (result.index == 1) { trigger.num--; - player.popup(' -1 ','water'); - game.log(player,'令此伤害-1'); + player.popup(" -1 ", "water"); + game.log(player, "令此伤害-1"); } }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, //官盗S系列郭嘉·二版 - psquanmou:{ - audio:2, - trigger:{ - global:'useCardAfter', + psquanmou: { + audio: 2, + trigger: { + global: "useCardAfter", }, - direct:true, - filter:function(event,player){ - return get.type2(event.card)=='trick'&&event.player!=player&&event.targets&&event.targets.includes(player)&&event.cards.filterInD('odj').length&&player.countCards('h'); + direct: true, + filter: function (event, player) { + return ( + get.type2(event.card) == "trick" && + event.player != player && + event.targets && + event.targets.includes(player) && + event.cards.filterInD("odj").length && + player.countCards("h") + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('psquanmou'),'弃置一张'+get.translation(get.color(trigger.card))+'手牌,获得'+get.translation(trigger.cards),'h',(card,player)=>{ - return get.color(card)==_status.event.color; - }).set('ai',card=>{ - return _status.event.value-get.value(card); - }).set('logSkill','psquanmou').set('value',get.value(trigger.cards,player)).set('color',get.color(trigger.card)); - 'step 1' - if(result.bool){ - var cards=trigger.cards.filterInD('odj'); - if(cards.filterInD('od').length) player.gain(cards.filterInD('od'),'gain2'); - if(cards.filterInD('j').length) player.gain(cards.filterInD('j'),get.owner(cards.filterInD('j')[0]),'give'); + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("psquanmou"), + "弃置一张" + + get.translation(get.color(trigger.card)) + + "手牌,获得" + + get.translation(trigger.cards), + "h", + (card, player) => { + return get.color(card) == _status.event.color; + } + ) + .set("ai", (card) => { + return _status.event.value - get.value(card); + }) + .set("logSkill", "psquanmou") + .set("value", get.value(trigger.cards, player)) + .set("color", get.color(trigger.card)); + "step 1"; + if (result.bool) { + var cards = trigger.cards.filterInD("odj"); + if (cards.filterInD("od").length) player.gain(cards.filterInD("od"), "gain2"); + if (cards.filterInD("j").length) + player.gain(cards.filterInD("j"), get.owner(cards.filterInD("j")[0]), "give"); } - } + }, }, //官盗S赵云·一版 - pshuiqiang:{ - audio:2, - trigger:{player:['shaMiss','eventNeutralized']}, - direct:true, - filter:function(event,player){ - if(!event.card||event.card.name!='sha') return false; - return event.target.isIn()&&player.canUse('sha',event.target,false)&&(player.hasSha()||_status.connectMode&&player.countCards('h')); + pshuiqiang: { + audio: 2, + trigger: { player: ["shaMiss", "eventNeutralized"] }, + direct: true, + filter: function (event, player) { + if (!event.card || event.card.name != "sha") return false; + return ( + event.target.isIn() && + player.canUse("sha", event.target, false) && + (player.hasSha() || (_status.connectMode && player.countCards("h"))) + ); + }, + content: function () { + "step 0"; + player + .chooseToUse( + get.prompt2("pshuiqiang", trigger.target), + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + trigger.target, + -1 + ) + .set("addCount", false).logSkill = "pshuiqiang"; }, - content:function(){ - "step 0" - player.chooseToUse(get.prompt2('pshuiqiang',trigger.target),function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },trigger.target,-1).set('addCount',false).logSkill='pshuiqiang'; - } }, - pshuntu:{ - audio:2, - trigger:{source:'damageSource'}, - usable:1, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent(2).player==player&&event.notLink()&&player.isPhaseUsing(); + pshuntu: { + audio: 2, + trigger: { source: "damageSource" }, + usable: 1, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.getParent(2).player == player && + event.notLink() && + player.isPhaseUsing() + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseToUse( + get.prompt2("pshuntu", trigger.player), + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + trigger.player, + -1 + ) + .set("addCount", false).logSkill = "pshuntu"; + "step 1"; + if (!result.bool) player.storage.counttrigger.pshuntu--; }, - direct:true, - content:function(){ - 'step 0' - player.chooseToUse(get.prompt2('pshuntu',trigger.player),function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },trigger.player,-1).set('addCount',false).logSkill='pshuntu'; - 'step 1' - if(!result.bool) player.storage.counttrigger.pshuntu--; - } }, //官盗S赵云·二版 - psqijin:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ + psqijin: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(7); + event.cards = get.cards(7); game.cardsGotoOrdering(event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str='七进'; - if(player==game.me&&!_status.auto) str+=':获得一种颜色的所有牌'; - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - event.time=get.utc(); - game.addVideo('showCards',player,['七进',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - 'step 1' - var list=[]; - for(var i of cards) list.add(get.color(i,false)); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str = "七进"; + if (player == game.me && !_status.auto) str += ":获得一种颜色的所有牌"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + event.time = get.utc(); + game.addVideo("showCards", player, ["七进", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + "step 1"; + var list = []; + for (var i of cards) list.add(get.color(i, false)); list.sort(); - var next=player.chooseControl(list); - next.set('ai',function(){ + var next = player.chooseControl(list); + next.set("ai", function () { return _status.event.choice; - }).set('choice',function(){ - if(list.length==0) return list[0]; - var color=list[0]; - var cards1=cards.filter(i=>get.color(i)==color),cards2=cards.filter(i=>get.color(i)==list[1]); - if(get.value(cards1)*cards1.length>get.value(cards2)*cards2.length) return list[0]; - return list[1]; - }()); - 'step 2' - event.color=result.control; - var time=1000-(get.utc()-event.time); - if(time>0) game.delay(0,time); - 'step 3' - game.broadcastAll('closeDialog',event.videoId); - player.gain(cards.filter(i=>get.color(i,false)==event.color),'gain2'); + }).set( + "choice", + (function () { + if (list.length == 0) return list[0]; + var color = list[0]; + var cards1 = cards.filter((i) => get.color(i) == color), + cards2 = cards.filter((i) => get.color(i) == list[1]); + if (get.value(cards1) * cards1.length > get.value(cards2) * cards2.length) + return list[0]; + return list[1]; + })() + ); + "step 2"; + event.color = result.control; + var time = 1000 - (get.utc() - event.time); + if (time > 0) game.delay(0, time); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + player.gain( + cards.filter((i) => get.color(i, false) == event.color), + "gain2" + ); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - psqichu:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - if(player!=_status.currentPhase&&!player.hasSkill('psqichu_used')&&get.type(name)=='basic'&&lib.inpile.includes(name)) return true; + psqichu: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + if ( + player != _status.currentPhase && + !player.hasSkill("psqichu_used") && + get.type(name) == "basic" && + lib.inpile.includes(name) + ) + return true; }, - filter:function(event,player){ - if(event.responded||player==_status.currentPhase||player.hasSkill('psqichu_used')) return false; - for(var i of lib.inpile){ - if(get.type(i)=='basic'&&event.filterCard({name:i},player,event)) return true; + filter: function (event, player) { + if (event.responded || player == _status.currentPhase || player.hasSkill("psqichu_used")) + return false; + for (var i of lib.inpile) { + if (get.type(i) == "basic" && event.filterCard({ name: i }, player, event)) + return true; } return false; }, - delay:false, - content:function(){ - 'step 0' - player.addTempSkill('psqichu_used'); - var evt=event.getParent(2); - var cards=get.cards(2); - for(var i=cards.length-1;i>=0;i--){ - ui.cardPile.insertBefore(cards[i].fix(),ui.cardPile.firstChild); + delay: false, + content: function () { + "step 0"; + player.addTempSkill("psqichu_used"); + var evt = event.getParent(2); + var cards = get.cards(2); + for (var i = cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(cards[i].fix(), ui.cardPile.firstChild); } - var aozhan=player.hasSkill('aozhan'); - player.chooseButton(['七出:选择要'+(evt.name=='chooseToUse'?'使用':'打出')+'的牌',cards]).set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards.filter(function(card){ - if(get.type(card)!='basic') return false; - if(aozhan&&card.name=='tao'){ - return evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)||evt.filterCard({ - name:'shan',isCard:true,cards:[card], - },evt.player,evt); + var aozhan = player.hasSkill("aozhan"); + player + .chooseButton([ + "七出:选择要" + (evt.name == "chooseToUse" ? "使用" : "打出") + "的牌", + cards, + ]) + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set( + "cards", + cards.filter(function (card) { + if (get.type(card) != "basic") return false; + if (aozhan && card.name == "tao") { + return ( + evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) || + evt.filterCard( + { + name: "shan", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ); + } + return evt.filterCard(card, evt.player, evt); + }) + ) + .set("ai", function (button) { + var evt = _status.event.getParent(3); + if (evt && evt.ai) { + var tmp = _status.event; + _status.event = evt; + var result = (evt.ai || event.ai1)(button.link, _status.event.player, evt); + _status.event = tmp; + return result; + } + return 1; + }); + "step 1"; + var evt = event.getParent(2); + if (result.bool && result.links && result.links.length) { + var name = result.links[0].name, + aozhan = player.hasSkill("aozhan") && name == "tao"; + if (aozhan) { + name = evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ? "sha" + : "shan"; } - return evt.filterCard(card,evt.player,evt); - })).set('ai',function(button){ - var evt=_status.event.getParent(3); - if(evt&&evt.ai){ - var tmp=_status.event; - _status.event=evt; - var result=(evt.ai||event.ai1)(button.link,_status.event.player,evt); - _status.event=tmp; - return result; - } - return 1; - }); - 'step 1' - var evt=event.getParent(2); - if(result.bool&&result.links&&result.links.length){ - var name=result.links[0].name,aozhan=(player.hasSkill('aozhan')&&name=='tao'); - if(aozhan){ - name=evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)?'sha':'shan'; - } - if(evt.name=='chooseToUse'){ - game.broadcastAll(function(result,name){ - lib.skill.psqichu_backup.viewAs={name:name,cards:[result],isCard:true}; - lib.skill.psqichu_backup.prompt='选择'+get.translation(result)+'的目标'; - },result.links[0],name); - evt.set('_backupevent','psqichu_backup'); - evt.backup('psqichu_backup'); - } - else{ + if (evt.name == "chooseToUse") { + game.broadcastAll( + function (result, name) { + lib.skill.psqichu_backup.viewAs = { + name: name, + cards: [result], + isCard: true, + }; + lib.skill.psqichu_backup.prompt = + "选择" + get.translation(result) + "的目标"; + }, + result.links[0], + name + ); + evt.set("_backupevent", "psqichu_backup"); + evt.backup("psqichu_backup"); + } else { delete evt.result.skill; delete evt.result.used; - evt.result.card=get.autoViewAs(result.links[0]); - if(aozhan) evt.result.card.name=name; - evt.result.cards=[result.links[0]]; + evt.result.card = get.autoViewAs(result.links[0]); + if (aozhan) evt.result.card.name = name; + evt.result.cards = [result.links[0]]; evt.redo(); return; } } evt.goto(0); }, - ai:{ - effect:{ - target:function(card,player,target,effect){ - if(target.hasSkill('psqichu_used')) return; - if(get.tag(card,'respondShan')) return 0.7; - if(get.tag(card,'respondSha')) return 0.7; - } - }, - order:11, - respondShan:true, - respondSha:true, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); - return 1; - } - } - }, - subSkill:{ - backup:{ - precontent:function(){ - delete event.result.skill; - var name=event.result.card.name; - event.result.cards=event.result.card.cards; - event.result.card=get.autoViewAs(event.result.cards[0]); - event.result.card.name=name; + ai: { + effect: { + target: function (card, player, target, effect) { + if (target.hasSkill("psqichu_used")) return; + if (get.tag(card, "respondShan")) return 0.7; + if (get.tag(card, "respondSha")) return 0.7; + }, + }, + order: 11, + respondShan: true, + respondSha: true, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); + return 1; }, - filterCard:function(){return false}, - selectCard:-1, }, - used:{charlotte:true}, - } - }, - pslongxin:{ - audio:2, - trigger:{player:'phaseJudgeBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('j')&&player.countCards('h'); }, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('pslongxin'),{type:'equip'},'he').set('logSkill','pslongxin').set('ai',card=>{ - if(_status.event.goon) return 15-get.value(card); - return 0; - }).set('goon',player.hasCard(card=>{ - var cardj=card.viewAs?{name:card.viewAs}:card; - return get.effect(player,cardj,player,player)<0; - },'j')); - 'step 1' - if(result.bool){ - player.discardPlayerCard(player,'j',true); + subSkill: { + backup: { + precontent: function () { + delete event.result.skill; + var name = event.result.card.name; + event.result.cards = event.result.card.cards; + event.result.card = get.autoViewAs(event.result.cards[0]); + event.result.card.name = name; + }, + filterCard: function () { + return false; + }, + selectCard: -1, + }, + used: { charlotte: true }, + }, + }, + pslongxin: { + audio: 2, + trigger: { player: "phaseJudgeBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("j") && player.countCards("h"); + }, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("pslongxin"), { type: "equip" }, "he") + .set("logSkill", "pslongxin") + .set("ai", (card) => { + if (_status.event.goon) return 15 - get.value(card); + return 0; + }) + .set( + "goon", + player.hasCard((card) => { + var cardj = card.viewAs ? { name: card.viewAs } : card; + return get.effect(player, cardj, player, player) < 0; + }, "j") + ); + "step 1"; + if (result.bool) { + player.discardPlayerCard(player, "j", true); } }, }, //官盗S周瑜·一版 - psoldshiyin:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + psoldshiyin: { + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - frequent:true, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - return event.getg(player).filter(i=>get.owner(i)==player).length>0; + frequent: true, + filter: function (event, player) { + if (player != _status.currentPhase) return false; + return event.getg(player).filter((i) => get.owner(i) == player).length > 0; }, - content:function(){ - 'step 0' - player.showCards(trigger.getg(player).filter(i=>get.owner(i)==player),get.translation(player)+'发动了【识音】'); - 'step 1' - var suits=[],cards=trigger.getg(player).filter(i=>get.owner(i)==player); - for(var card of cards) suits.add(get.suit(card,player)); - player.addTempSkill('psoldshiyin_effect'); - if(!player.storage.psoldshiyin_effect) player.storage.psoldshiyin_effect=0; - player.storage.psoldshiyin_effect=Math.max(player.storage.psoldshiyin_effect,suits.length); - if(suits.length>=2) player.addMark('psoldshiyin_damage',1,false); + content: function () { + "step 0"; + player.showCards( + trigger.getg(player).filter((i) => get.owner(i) == player), + get.translation(player) + "发动了【识音】" + ); + "step 1"; + var suits = [], + cards = trigger.getg(player).filter((i) => get.owner(i) == player); + for (var card of cards) suits.add(get.suit(card, player)); + player.addTempSkill("psoldshiyin_effect"); + if (!player.storage.psoldshiyin_effect) player.storage.psoldshiyin_effect = 0; + player.storage.psoldshiyin_effect = Math.max( + player.storage.psoldshiyin_effect, + suits.length + ); + if (suits.length >= 2) player.addMark("psoldshiyin_damage", 1, false); }, - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - charlotte:true, - forced:true, - onremove:['psoldshiyin_effect','psoldshiyin_damage'], - content:function(){ - var num=player.countMark('psoldshiyin_effect'); - if(num>=1) trigger.directHit.addArray(game.players); - if(num>=2&&get.tag(trigger.card,'damage')) trigger.baseDamage+=player.countMark('psoldshiyin_damage'); - if(num>=3) player.draw(); - player.removeSkill('psoldshiyin_effect'); + subSkill: { + effect: { + trigger: { player: "useCard" }, + charlotte: true, + forced: true, + onremove: ["psoldshiyin_effect", "psoldshiyin_damage"], + content: function () { + var num = player.countMark("psoldshiyin_effect"); + if (num >= 1) trigger.directHit.addArray(game.players); + if (num >= 2 && get.tag(trigger.card, "damage")) + trigger.baseDamage += player.countMark("psoldshiyin_damage"); + if (num >= 3) player.draw(); + player.removeSkill("psoldshiyin_effect"); }, - mod:{ - aiOrder:function(player,card,num){ - var numx=player.countMark('psoldshiyin_effect'); - if(numx>=2&&get.tag(card,'damage')) return num+10; + mod: { + aiOrder: function (player, card, num) { + var numx = player.countMark("psoldshiyin_effect"); + if (numx >= 2 && get.tag(card, "damage")) return num + 10; }, - } - } - } + }, + }, + }, }, //官盗S周瑜·二版 - psshiyin:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + psshiyin: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - direct:true, - group:'psshiyin_change', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + direct: true, + group: "psshiyin_change", + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt('psshiyin'),'将一张手牌置于武将牌上,称为“杂音”牌').set('ai',card=>20-get.value(card)); - 'step 1' - if(result.bool){ - player.logSkill('psshiyin'); - player.addToExpansion(result.cards,player,'give').gaintag.add('psshiyin'); + content: function () { + "step 0"; + player + .chooseCard(get.prompt("psshiyin"), "将一张手牌置于武将牌上,称为“杂音”牌") + .set("ai", (card) => 20 - get.value(card)); + "step 1"; + if (result.bool) { + player.logSkill("psshiyin"); + player.addToExpansion(result.cards, player, "give").gaintag.add("psshiyin"); } }, - marktext:'音', - intro:{ - name:'杂音', - name2:'杂音', - content:'expansion', - markcount:'expansion', + marktext: "音", + intro: { + name: "杂音", + name2: "杂音", + content: "expansion", + markcount: "expansion", }, - subSkill:{ - change:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('psshiyin').length&&player.countCards('h'); + subSkill: { + change: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.getExpansions("psshiyin").length && player.countCards("h"); }, - content:function(){ - 'step 0' - var card=player.getExpansions('psshiyin')[0]; - player.chooseCard(get.prompt('psshiyin'),'用一张手牌替换“杂音”牌('+get.translation(card)+')').set('ai',card=>{ - if(_status.event.suit&&get.suit(card)==_status.event.suit) return 8-get.value(card); - return 0; - }).set('suit',function(){ - var suits=lib.suit.slice().map(i=>[i,(get.suit(card)==i?1:0)+player.countCards('h',{suit:i})]).filter(i=>i[1]>0); - suits.sort((a,b)=>a[1]-b[1]); - if(suits.length>0) return suits[0][0]; - return null; - }()); - 'step 1' - if(result.bool){ - player.logSkill('psshiyin'); - player.addToExpansion(result.cards[0],'give',player).gaintag.add('psshiyin'); - var card=player.getExpansions('psshiyin')[0]; - if(card) player.gain(card,'gain2'); + content: function () { + "step 0"; + var card = player.getExpansions("psshiyin")[0]; + player + .chooseCard( + get.prompt("psshiyin"), + "用一张手牌替换“杂音”牌(" + get.translation(card) + ")" + ) + .set("ai", (card) => { + if (_status.event.suit && get.suit(card) == _status.event.suit) + return 8 - get.value(card); + return 0; + }) + .set( + "suit", + (function () { + var suits = lib.suit + .slice() + .map((i) => [ + i, + (get.suit(card) == i ? 1 : 0) + + player.countCards("h", { suit: i }), + ]) + .filter((i) => i[1] > 0); + suits.sort((a, b) => a[1] - b[1]); + if (suits.length > 0) return suits[0][0]; + return null; + })() + ); + "step 1"; + if (result.bool) { + player.logSkill("psshiyin"); + player + .addToExpansion(result.cards[0], "give", player) + .gaintag.add("psshiyin"); + var card = player.getExpansions("psshiyin")[0]; + if (card) player.gain(card, "gain2"); } }, - } - } - }, - psquwu:{ - audio:2, - forced:true, - trigger:{target:'useCardToBefore'}, - filter:function(event,player){ - return player.getExpansions('psshiyin').length&&get.suit(player.getExpansions('psshiyin')[0])==get.suit(event.card); + }, }, - content:function(){ + }, + psquwu: { + audio: 2, + forced: true, + trigger: { target: "useCardToBefore" }, + filter: function (event, player) { + return ( + player.getExpansions("psshiyin").length && + get.suit(player.getExpansions("psshiyin")[0]) == get.suit(event.card) + ); + }, + content: function () { trigger.cancel(); }, - ai:{ - threaten:1.1, - combo:'psshiyin', - effect:{ - target:function(card,player,target,current){ - var list=target.getExpansions('psshiyin'); - for(var cardx of list){ - if(get.suit(cardx)==get.suit(card)) return 'zeroplayertarget'; + ai: { + threaten: 1.1, + combo: "psshiyin", + effect: { + target: function (card, player, target, current) { + var list = target.getExpansions("psshiyin"); + for (var cardx of list) { + if (get.suit(cardx) == get.suit(card)) return "zeroplayertarget"; } }, - } + }, }, - mod:{ - cardEnabled2:function(card,player){ - var list=player.getExpansions('psshiyin'); - for(var cardx of list){ - if(get.suit(cardx)==get.suit(card)) return false; + mod: { + cardEnabled2: function (card, player) { + var list = player.getExpansions("psshiyin"); + for (var cardx of list) { + if (get.suit(cardx) == get.suit(card)) return false; } }, - cardRespondable:function(card,player){ - var list=player.getExpansions('psshiyin'); - for(var cardx of list){ - if(get.suit(cardx)==get.suit(card)) return false; + cardRespondable: function (card, player) { + var list = player.getExpansions("psshiyin"); + for (var cardx of list) { + if (get.suit(cardx) == get.suit(card)) return false; } }, - cardSavable:function(card,player){ - var list=player.getExpansions('psshiyin'); - for(var cardx of list){ - if(get.suit(cardx)==get.suit(card)) return false; + cardSavable: function (card, player) { + var list = player.getExpansions("psshiyin"); + for (var cardx of list) { + if (get.suit(cardx) == get.suit(card)) return false; } }, - } + }, }, - psliaozou:{ - audio:2, - enable:'phaseUse', - locked:false, - filter:function(event,player){ - return !player.hasSkill('psliaozou_blocker',null,null,false)&&player.getExpansions('psshiyin').length>0; + psliaozou: { + audio: 2, + enable: "phaseUse", + locked: false, + filter: function (event, player) { + return ( + !player.hasSkill("psliaozou_blocker", null, null, false) && + player.getExpansions("psshiyin").length > 0 + ); }, - content:function(){ - 'step 0' - player.showHandcards(get.translation(player)+'发动了【聊奏】'); - 'step 1' - var cards=player.getExpansions('psshiyin'),bool=true; - for(var card of cards){ - var suit=get.suit(card); - if(player.hasCard(cardx=>get.suit(cardx)==suit)){ - bool=false; break; + content: function () { + "step 0"; + player.showHandcards(get.translation(player) + "发动了【聊奏】"); + "step 1"; + var cards = player.getExpansions("psshiyin"), + bool = true; + for (var card of cards) { + var suit = get.suit(card); + if (player.hasCard((cardx) => get.suit(cardx) == suit)) { + bool = false; + break; } } - if(bool) player.draw(); - else player.addTempSkill('psliaozou_blocker',{player:['useCard1','useSkillBegin','phaseUseEnd']}); + if (bool) player.draw(); + else + player.addTempSkill("psliaozou_blocker", { + player: ["useCard1", "useSkillBegin", "phaseUseEnd"], + }); }, - subSkill:{ - blocker:{charlotte:true} + subSkill: { + blocker: { charlotte: true }, }, - mod:{ - aiValue:function(player,card,num){ - var suit=get.suit(card); - if(player.isPhaseUsing()&&player.getExpansions('psshiyin').some(i=>get.suit(i)==suit)) return num/5; + mod: { + aiValue: function (player, card, num) { + var suit = get.suit(card); + if ( + player.isPhaseUsing() && + player.getExpansions("psshiyin").some((i) => get.suit(i) == suit) + ) + return num / 5; }, - aiUseful:function(){ - return lib.skill.psliaozou.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.psliaozou.mod.aiValue.apply(this, arguments); }, }, - ai:{ - order:9.9, - result:{ - player:function(player){ - var cards=player.getExpansions('psshiyin'),bool=true; - for(var card of cards){ - var suit=get.suit(card); - if(player.hasCard(cardx=>get.suit(cardx)==suit)) return 0; + ai: { + combo: "psshiyin", + order: 9.9, + result: { + player: function (player) { + var cards = player.getExpansions("psshiyin"), + bool = true; + for (var card of cards) { + var suit = get.suit(card); + if (player.hasCard((cardx) => get.suit(cardx) == suit)) return 0; } return 1; - } - } - } + }, + }, + }, }, //官盗S武将传晋司马 - psquanyi:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + psquanyi: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - group:'psquanyi_tianbian', - content:function(){ - 'step 0' - player.chooseToCompare(target,function(card){ - if(typeof card=='string'&&lib.skill[card]){ - var ais=lib.skill[card].check||function(){return 0}; + group: "psquanyi_tianbian", + content: function () { + "step 0"; + player.chooseToCompare(target, function (card) { + if (typeof card == "string" && lib.skill[card]) { + var ais = + lib.skill[card].check || + function () { + return 0; + }; return ais(); } - var player=get.owner(card); - var getn=function(card){ - if(player.hasSkill('tianbian')&&get.suit(card)=='heart') return 13; + var player = get.owner(card); + var getn = function (card) { + if (player.hasSkill("tianbian") && get.suit(card) == "heart") return 13; return get.number(card); - } - var event=_status.event.getParent(); - var to=(player==event.player?event.target:event.player); - var addi=(get.value(card)>=8&&get.type(card)!='equip')?-6:0; - if(card.name=='du') addi-=5; - if(get.color(card)=='black') addi-=6; - if(player==event.player){ - if(event.small){ - return -getn(card)-get.value(card)/2+addi; + }; + var event = _status.event.getParent(); + var to = player == event.player ? event.target : event.player; + var addi = get.value(card) >= 8 && get.type(card) != "equip" ? -6 : 0; + if (card.name == "du") addi -= 5; + if (get.color(card) == "black") addi -= 6; + if (player == event.player) { + if (event.small) { + return -getn(card) - get.value(card) / 2 + addi; } - return getn(card)-get.value(card)/2+addi; - } - else{ - if((get.attitude(player,to)<=0)==Boolean(event.small)){ - return -getn(card)-get.value(card)/2+addi; + return getn(card) - get.value(card) / 2 + addi; + } else { + if (get.attitude(player, to) <= 0 == Boolean(event.small)) { + return -getn(card) - get.value(card) / 2 + addi; } - return getn(card)-get.value(card)/2+addi; + return getn(card) - get.value(card) / 2 + addi; } }); - 'step 1' - if(result.tie) event.finish(); - else{ - var targets=[player,target]; - if(!result.bool) targets.reverse(); - var suits=[result.player,result.target].map(i=>get.suit(i,false)); - event.targets=targets; - event.suits=suits; + "step 1"; + if (result.tie) event.finish(); + else { + var targets = [player, target]; + if (!result.bool) targets.reverse(); + var suits = [result.player, result.target].map((i) => get.suit(i, false)); + event.targets = targets; + event.suits = suits; } - 'step 2' - if(event.suits.includes('heart')){ - if(targets[1].countGainableCards('hej',targets[0])>0){ - targets[0].gainPlayerCard(targets[1],'hej',true); + "step 2"; + if (event.suits.includes("heart")) { + if (targets[1].countGainableCards("hej", targets[0]) > 0) { + targets[0].gainPlayerCard(targets[1], "hej", true); } } - 'step 3' - if(event.suits.includes('diamond')){ + "step 3"; + if (event.suits.includes("diamond")) { targets[1].damage(targets[0]); } - 'step 4' - if(event.suits.includes('spade')){ + "step 4"; + if (event.suits.includes("spade")) { targets[0].loseHp(); } - 'step 5' - if(event.suits.includes('club')){ - if(targets[0].countDiscardableCards(targets[0],'he')){ - targets[0].chooseToDiscard(2,true,'he'); + "step 5"; + if (event.suits.includes("club")) { + if (targets[0].countDiscardableCards(targets[0], "he")) { + targets[0].chooseToDiscard(2, true, "he"); } } }, - ai:{ - order:6, - result:{ - target:-1 - } + ai: { + order: 6, + result: { + target: -1, + }, }, - subSkill:{ - tianbian:{ - audio:'psquanyi', - enable:'chooseCard', - check:function(event){ - var player=_status.event.player; - if(player.hasSkill('smyyingshi')){ - var card=ui.cardPile.childNodes[0]; - if(get.color(card)=='black'&&get.number(card)<=4||get.color(card)=='red'&&get.number(card)>=11) return 20; + subSkill: { + tianbian: { + audio: "psquanyi", + enable: "chooseCard", + check: function (event) { + var player = _status.event.player; + if (player.hasSkill("smyyingshi")) { + var card = ui.cardPile.childNodes[0]; + if ( + (get.color(card) == "black" && get.number(card) <= 4) || + (get.color(card) == "red" && get.number(card) >= 11) + ) + return 20; } - return (!player.hasCard(function(card){ - var val=get.value(card); - return val<0||(get.color(card)=='black'&&val<=4||get.color(card)=='red'&&get.number(card)>=11); - },'h'))?20:0; + return !player.hasCard(function (card) { + var val = get.value(card); + return ( + val < 0 || + (get.color(card) == "black" && val <= 4) || + (get.color(card) == "red" && get.number(card) >= 11) + ); + }, "h") + ? 20 + : 0; }, - filter:function(event){ - return event.type=='compare'&&!event.directresult; + filter: function (event) { + return event.type == "compare" && !event.directresult; }, - onCompare:function(player){ + onCompare: function (player) { return game.cardsGotoOrdering(get.cards()).cards; }, - } - } + }, + }, }, //官盗S曹植 - psliushang:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - forced:true, - filter:function(event,player){ + psliushang: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - group:'psliushang_give', - content:function(){ - 'step 0' + group: "psliushang_give", + content: function () { + "step 0"; trigger.changeToZero(); - player.draw(1+Math.max(3,game.countPlayer())); - event.targets=game.filterPlayer(i=>i!=player); - 'step 1' - var current=targets.shift(); - if(!player.countCards('h')) event.finish(); - else player.chooseCardTarget({ - prompt:'流殇:将一张牌置于'+get.translation(current)+'武将牌上', - current:current, - filterCard:true, - forced:true, - filterTarget:function(card,player,target){ - return target==_status.event.current; - }, - selectTarget:-1, - ai1:function(card){ - var current=_status.event.current; - return get.value(card,current)*get.attitude(_status.event.player,current); - }, - ai2:()=>1 - }); - 'step 2' - if(result.bool){ - result.targets[0].addToExpansion(result.cards,player,'give').gaintag.add('psliushang'); + player.draw(1 + Math.max(3, game.countPlayer())); + event.targets = game.filterPlayer((i) => i != player); + "step 1"; + var current = targets.shift(); + if (!player.countCards("h")) event.finish(); + else + player.chooseCardTarget({ + prompt: "流殇:将一张牌置于" + get.translation(current) + "武将牌上", + current: current, + filterCard: true, + forced: true, + filterTarget: function (card, player, target) { + return target == _status.event.current; + }, + selectTarget: -1, + ai1: function (card) { + var current = _status.event.current; + return get.value(card, current) * get.attitude(_status.event.player, current); + }, + ai2: () => 1, + }); + "step 2"; + if (result.bool) { + result.targets[0] + .addToExpansion(result.cards, player, "give") + .gaintag.add("psliushang"); } - if(targets.length) event.goto(1); + if (targets.length) event.goto(1); }, - marktext:'殇', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "殇", + intro: { + content: "expansion", + markcount: "expansion", }, - subSkill:{ - give:{ - trigger:{global:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return event.player!=player&&event.player.getExpansions('psliushang').length; + subSkill: { + give: { + trigger: { global: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return event.player != player && event.player.getExpansions("psliushang").length; }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' - var cards=trigger.player.getExpansions('psliushang'),name=get.translation(cards); - event.cards=cards; - trigger.player.chooseControl().set('choiceList',[ - '获得'+name+',且于本回合防止对'+get.translation(player)+'的伤害', - '将'+name+'置入弃牌堆' - ]).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(get.damageEffect(player,trigger.player,trigger.player)<=0) return 0; - if(get.value(cards,trigger.player)<0) return 1; - if(trigger.player.hasCard(card=>{ - return get.tag(card,'damage')&&trigger.player.canUse(card,player)&&get.effect(player,card,trigger.player,trigger.player)>0; - },'hs')) return 1; - return 0; - }()); - 'step 1' - if(result.index==0){ - trigger.player.gain(cards,'gain2'); - trigger.player.addTempSkill('psliushang_prevent'); - trigger.player.markAuto('psliushang_prevent',[player]); - } - else{ + forced: true, + logTarget: "player", + content: function () { + "step 0"; + var cards = trigger.player.getExpansions("psliushang"), + name = get.translation(cards); + event.cards = cards; + trigger.player + .chooseControl() + .set("choiceList", [ + "获得" + name + ",且于本回合防止对" + get.translation(player) + "的伤害", + "将" + name + "置入弃牌堆", + ]) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (get.damageEffect(player, trigger.player, trigger.player) <= 0) + return 0; + if (get.value(cards, trigger.player) < 0) return 1; + if ( + trigger.player.hasCard((card) => { + return ( + get.tag(card, "damage") && + trigger.player.canUse(card, player) && + get.effect(player, card, trigger.player, trigger.player) > + 0 + ); + }, "hs") + ) + return 1; + return 0; + })() + ); + "step 1"; + if (result.index == 0) { + trigger.player.gain(cards, "gain2"); + trigger.player.addTempSkill("psliushang_prevent"); + trigger.player.markAuto("psliushang_prevent", [player]); + } else { trigger.player.loseToDiscardpile(cards); } - 'step 2' + "step 2"; game.delayx(); - } - }, - prevent:{ - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return player.getStorage('psliushang_prevent').includes(event.player); }, - forced:true, - onremove:true, - charlotte:true, - logTarget:'player', - content:function(){ + }, + prevent: { + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return player.getStorage("psliushang_prevent").includes(event.player); + }, + forced: true, + onremove: true, + charlotte: true, + logTarget: "player", + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function (card,player,target,current){ - if(player.getStorage('psliushang_prevent').includes(target)&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if ( + player.getStorage("psliushang_prevent").includes(target) && + get.tag(card, "damage") + ) { + return "zeroplayertarget"; } }, }, - } - } - } - }, - psqibu:{ - trigger:{player:'dying'}, - filter:function(event,player){ - return player.hp<=0; + }, + }, }, - limited:true, - skillAnimation:true, - animationColor:'water', - content:function(){ - 'step 0' - player.awakenSkill('psqibu'); - var cards=game.cardsGotoOrdering(get.cards(7)).cards; + }, + psqibu: { + trigger: { player: "dying" }, + filter: function (event, player) { + return player.hp <= 0; + }, + limited: true, + skillAnimation: true, + animationColor: "water", + content: function () { + "step 0"; + player.awakenSkill("psqibu"); + var cards = game.cardsGotoOrdering(get.cards(7)).cards; game.updateRoundNumber(); - event.cards=cards; - player.showCards(cards,get.translation(player)+'发动了【流殇】'); - 'step 1' - var num=cards.filter(i=>get.suit(i)=='heart').length; - var gains=cards.filter(i=>get.suit(i)=='club'); - if(num>0) player.recover(num); - if(gains.length) player.gain(gains,'gain2'); - } + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【流殇】"); + "step 1"; + var num = cards.filter((i) => get.suit(i) == "heart").length; + var gains = cards.filter((i) => get.suit(i) == "club"); + if (num > 0) player.recover(num); + if (gains.length) player.gain(gains, "gain2"); + }, }, //官盗S曹丕 - psjianwei:{ - audio:2, - trigger:{player:'phaseBegin'}, - skillAnimation:true, - animationColor:'water', - limited:true, - direct:true, - filter:function(event,player){ - return player.hp>=1; + psjianwei: { + audio: 2, + trigger: { player: "phaseBegin" }, + skillAnimation: true, + animationColor: "water", + limited: true, + direct: true, + filter: function (event, player) { + return player.hp >= 1; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('psjianwei'),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - if(player.hp==1&&!player.canSave(player)) return 0; - var sgn=get.sgnAttitude(player,target); - var valMine=[0,0],valHis=[0,0]; - player.getCards('hej',card=>{ - if(get.position(card)=='j'){ - valMine[0]+=get.effect(player,card,player); - valMine[1]+=get.effect(target,card,player); - } - else{ - valMine[0]+=get.value(card,player); - valMine[1]+=get.value(card,target)*sgn; + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("psjianwei"), lib.filter.notMe).set("ai", (target) => { + var player = _status.event.player; + if (player.hp == 1 && !player.canSave(player)) return 0; + var sgn = get.sgnAttitude(player, target); + var valMine = [0, 0], + valHis = [0, 0]; + player.getCards("hej", (card) => { + if (get.position(card) == "j") { + valMine[0] += get.effect(player, card, player); + valMine[1] += get.effect(target, card, player); + } else { + valMine[0] += get.value(card, player); + valMine[1] += get.value(card, target) * sgn; } }); - target.getCards('hej',card=>{ - if(get.position(card)=='j'){ - valHis[0]+=get.effect(player,card,player); - valHis[1]+=get.effect(target,card,player); - } - else{ - valHis[0]+=get.value(card,player); - valHis[1]+=get.value(card,target)*sgn; + target.getCards("hej", (card) => { + if (get.position(card) == "j") { + valHis[0] += get.effect(player, card, player); + valHis[1] += get.effect(target, card, player); + } else { + valHis[0] += get.value(card, player); + valHis[1] += get.value(card, target) * sgn; } }); - return valMine[1]-valMine[0]+valHis[0]-valHis[1]>=60; + return valMine[1] - valMine[0] + valHis[0] - valHis[1] >= 60; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('psjianwei',target); - player.awakenSkill('psjianwei'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("psjianwei", target); + player.awakenSkill("psjianwei"); player.loseHp(); - } - else event.finish(); - 'step 2' - if(player.isIn()&&target.isIn()){ - var next=game.createEvent('psjianwei_swap'); - next.player=player; - next.target=target; - next.set('cards1',player.getCards('hej')); - next.set('cards2',target.getCards('hej')); + } else event.finish(); + "step 2"; + if (player.isIn() && target.isIn()) { + var next = game.createEvent("psjianwei_swap"); + next.player = player; + next.target = target; + next.set("cards1", player.getCards("hej")); + next.set("cards2", target.getCards("hej")); next.setContent(lib.skill.psjianwei.swapRegioncards); } }, - swapRegioncards:function(){ - 'step 0' - player.$giveAuto(event.cards1,target); - target.$giveAuto(event.cards2,player); - 'step 1' - event.h1=event.cards1.filter(i=>get.position(i)=='h'); - event.e1=event.cards1.filter(i=>get.position(i)=='e'); - event.j1=event.cards1.filter(i=>get.position(i)=='j'); - event.h2=event.cards2.filter(i=>get.position(i)=='h'); - event.e2=event.cards2.filter(i=>get.position(i)=='e'); - event.j2=event.cards2.filter(i=>get.position(i)=='j'); + swapRegioncards: function () { + "step 0"; + player.$giveAuto(event.cards1, target); + target.$giveAuto(event.cards2, player); + "step 1"; + event.h1 = event.cards1.filter((i) => get.position(i) == "h"); + event.e1 = event.cards1.filter((i) => get.position(i) == "e"); + event.j1 = event.cards1.filter((i) => get.position(i) == "j"); + event.h2 = event.cards2.filter((i) => get.position(i) == "h"); + event.e2 = event.cards2.filter((i) => get.position(i) == "e"); + event.j2 = event.cards2.filter((i) => get.position(i) == "j"); game.loseAsync({ - lose_list:[ - [player,event.cards1], - [target,event.cards2] - ] - }).setContent('chooseToCompareLose'); - 'step 2' - var todis=[]; - for(var i=0;iget.position(i,true)=='o')], - [target,event.h1.filter(i=>get.position(i,true)=='o')] + lose_list: [ + [player, event.cards1], + [target, event.cards2], ], - }).setContent('gaincardMultiple'); - for(var i=0;i get.position(i, true) == "o")], + [target, event.h1.filter((i) => get.position(i, true) == "o")], + ], + }).setContent("gaincardMultiple"); + for (var i = 0; i < event.e2.length; i++) { + if (get.position(event.e2[i], true) == "o") player.equip(event.e2[i]); } - for(var i=0;i0&&!player.hasSkill('pslongyin_used'); - }, - ai:{ - fireAttack:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hse')||player.hasSkill('pslongyin_used')) return false; + prompt: function (links, player) { + return ( + "将任意张点数和为13牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + }, + hiddenCard: function (player, name) { + if (!lib.inpile.includes(name)) return false; + var type = get.type(name); + return ( + (type == "basic" || type == "trick") && + player.countCards("she") > 0 && + !player.hasSkill("pslongyin_used") + ); + }, + ai: { + fireAttack: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hse") || player.hasSkill("pslongyin_used")) return false; + }, + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - used:{charlotte:true} - } + subSkill: { + used: { charlotte: true }, + }, }, //官盗S武将传诸葛亮 - pszhiji:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - if(!ui.selected.targets.length) return true; - return target.group!=ui.selected.targets[0].group; + pszhiji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + if (!ui.selected.targets.length) return true; + return target.group != ui.selected.targets[0].group; }, - selectTarget:2, - complexTarget:true, - multitarget:true, - multiline:true, - filterCard:true, - selectCard:2, - check:function(card){ - return 6-get.value(card); + selectTarget: 2, + complexTarget: true, + multitarget: true, + multiline: true, + filterCard: true, + selectCard: 2, + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; targets.sortBySeat(); - if(targets[0].canUse('sha',targets[1],false)) targets[0].useCard({name:'sha',isCard:true},targets[1],false,'noai'); - 'step 1' - if(targets[1].canUse('sha',targets[0],false)) targets[1].useCard({name:'sha',isCard:true},targets[0],false,'noai'); + if (targets[0].canUse("sha", targets[1], false)) + targets[0].useCard({ name: "sha", isCard: true }, targets[1], false, "noai"); + "step 1"; + if (targets[1].canUse("sha", targets[0], false)) + targets[1].useCard({ name: "sha", isCard: true }, targets[0], false, "noai"); }, - ai:{ - order:2.5, - result:{ - player:1, - target:function(player,target){ - if(ui.selected.targets.length){ - var targetx=ui.selected.targets[0]; - if(get.effect(targetx,{name:'sha'},target,player)+get.effect(target,{name:'sha'},targetx,player)<0) return 0; + ai: { + order: 2.5, + result: { + player: 1, + target: function (player, target) { + if (ui.selected.targets.length) { + var targetx = ui.selected.targets[0]; + if ( + get.effect(targetx, { name: "sha" }, target, player) + + get.effect(target, { name: "sha" }, targetx, player) < + 0 + ) + return 0; return -1; } return -1; - } - } - } + }, + }, + }, }, - psjiefeng:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:2, - check:function(card){ - return 6-get.value(card); + psjiefeng: { + audio: 2, + enable: "phaseUse", + filterCard: true, + selectCard: 2, + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' - var cards=game.cardsGotoOrdering(get.cards(5)).cards; - event.cards=cards; - player.showCards(cards,get.translation(player)+'发动了【借风】'); - 'step 1' - if(cards.filter(i=>get.color(i)=='red').length>=2){ - player.chooseUseTarget('wanjian',true); + content: function () { + "step 0"; + var cards = game.cardsGotoOrdering(get.cards(5)).cards; + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【借风】"); + "step 1"; + if (cards.filter((i) => get.color(i) == "red").length >= 2) { + player.chooseUseTarget("wanjian", true); } }, - ai:{ - order:9, - result:{ - player:function(player){ - if(player.getUseValue({name:'wanjian'})<0) return 0; + ai: { + order: 9, + result: { + player: function (player) { + if (player.getUseValue({ name: "wanjian" }) < 0) return 0; return 1; - } - } - } + }, + }, + }, }, //官盗S马超 - psweihou:{ - trigger:{player:'judgeBegin'}, - filter:function(event,player){ + psweihou: { + trigger: { player: "judgeBegin" }, + filter: function (event, player) { return !event.directresult; }, - content:function(){ - 'step 0' - var cards=get.cards(2); - for(var i=cards.length-1;i>=0;i--){ - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); + content: function () { + "step 0"; + var cards = get.cards(2); + for (var i = cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); } game.updateRoundNumber(); - event.cards=cards; - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str; - if(player==game.me&&!_status.auto) str='威侯:选择一张作为本次判定结果'; - else str=get.translation(player)+'发动了【威侯】'; - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - game.addVideo('showCards',player,['威侯',get.cardsInfo(event.cards)]); - if(!event.isMine()&&!event.isOnline()) game.delayx(); - 'step 1' - player.chooseButton(['威侯:选择一张作为本次判定结果',cards],true).set('ai',button=>{ - return _status.event.getTrigger().judge(button.link); - }).set('dialog',event.videoId); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - if(result.bool){ - trigger.directresult=result.links[0]; - game.cardsDiscard(cards.removeArray(result.links).filter(i=>get.position(i)=='c')); + event.cards = cards; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str; + if (player == game.me && !_status.auto) str = "威侯:选择一张作为本次判定结果"; + else str = get.translation(player) + "发动了【威侯】"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + game.addVideo("showCards", player, ["威侯", get.cardsInfo(event.cards)]); + if (!event.isMine() && !event.isOnline()) game.delayx(); + "step 1"; + player + .chooseButton(["威侯:选择一张作为本次判定结果", cards], true) + .set("ai", (button) => { + return _status.event.getTrigger().judge(button.link); + }) + .set("dialog", event.videoId); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + if (result.bool) { + trigger.directresult = result.links[0]; + game.cardsDiscard( + cards.removeArray(result.links).filter((i) => get.position(i) == "c") + ); } - 'step 3' + "step 3"; game.updateRoundNumber(); - } + }, }, //官盗S1066★贾诩 - psqupo:{ - audio:2, - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - return player.countCards('he'); + psqupo: { + audio: 2, + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + return player.countCards("he"); }, - direct:true, - content:function(){ - 'step 0' - var cards=player.getCards('he'); - var current=trigger.player; - var ai1=function(card){ - var player=_status.event.player,current=_status.event.current; - var card=get.color(card); - if(color=='black'){ - if(!current.hasSha()||!current.hasUseTarget({name:'sha'})) return 0; - if(targets.length) return 5.5-get.value(card); - } - else if(color=='red'){ - if(get.attitude(player,current)<=0) return 0; - if(current.hasCard(card=>{ - if(!get.tag(card,'damage')) return false; - var targetsx=game.filterPlayer(currentx=>{ - if(currentx==current||current==player) return false; - return current.canUse(card,currentx)&&get.effect(currentx,card,current,player)>0; - }); - targets2.addArray(targetsx); - return targetsx.length; - },'hs')) return 5.5-get.value(card); + direct: true, + content: function () { + "step 0"; + var cards = player.getCards("he"); + var current = trigger.player; + var ai1 = function (card) { + var player = _status.event.player, + current = _status.event.current; + var card = get.color(card); + if (color == "black") { + if (!current.hasSha() || !current.hasUseTarget({ name: "sha" })) return 0; + if (targets.length) return 5.5 - get.value(card); + } else if (color == "red") { + if (get.attitude(player, current) <= 0) return 0; + if ( + current.hasCard((card) => { + if (!get.tag(card, "damage")) return false; + var targetsx = game.filterPlayer((currentx) => { + if (currentx == current || current == player) return false; + return ( + current.canUse(card, currentx) && + get.effect(currentx, card, current, player) > 0 + ); + }); + targets2.addArray(targetsx); + return targetsx.length; + }, "hs") + ) + return 5.5 - get.value(card); } return 0; - } - var targets=game.filterPlayer(currentx=>{ - if(currentx==current||current==player) return false; - return !current.canUse('sha',currentx)||get.effect(currentx,{name:'sha'},current,player)>0&&get.attitude(player,currentx)>-3; + }; + var targets = game.filterPlayer((currentx) => { + if (currentx == current || current == player) return false; + return ( + !current.canUse("sha", currentx) || + (get.effect(currentx, { name: "sha" }, current, player) > 0 && + get.attitude(player, currentx) > -3) + ); }); - targets.sort((a,b)=>get.attitude(player,b)-get.attitude(player,a)); - var targets2=[]; - var cardx=cards.sort((a,b)=>ai1(b)-ai1(a))[0]; - targets2.sort((a,b)=>get.threaten(b,current)-get.threaten(a,current)); - var next=player.chooseCardTarget({ - filterCard:true, - prompt:get.prompt2('psqupo'), - current:trigger.player, - filterTarget:function(card,player,target){ - return player!=target&&target!=_status.event.current; + targets.sort((a, b) => get.attitude(player, b) - get.attitude(player, a)); + var targets2 = []; + var cardx = cards.sort((a, b) => ai1(b) - ai1(a))[0]; + targets2.sort((a, b) => get.threaten(b, current) - get.threaten(a, current)); + var next = player.chooseCardTarget({ + filterCard: true, + prompt: get.prompt2("psqupo"), + current: trigger.player, + filterTarget: function (card, player, target) { + return player != target && target != _status.event.current; }, - ai1:function(card){ - return card==_status.event.cardx?1:0; + ai1: function (card) { + return card == _status.event.cardx ? 1 : 0; }, - ai2:function(target){ - return target==_status.event.targetx?1:0; + ai2: function (target) { + return target == _status.event.targetx ? 1 : 0; }, }); - if(ai1(cardx)>0){ - next.cardx=cardx; - if(get.color(cardx)=='black'){ - if(targets.length) next.targetx=targets[0]; - } - else{ - if(targets2.length) next.targetx=targets2[0]; + if (ai1(cardx) > 0) { + next.cardx = cardx; + if (get.color(cardx) == "black") { + if (targets.length) next.targetx = targets[0]; + } else { + if (targets2.length) next.targetx = targets2[0]; } } - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.logSkill('psqupo',target); - player.give(cards,target); - var color=get.color(cards[0]); - if(color=='black'){ - _status.currentPhase.addTempSkill('psqupo_black'); - _status.currentPhase.markAuto('psqupo_black',[target]); - } - else if(color=='red'){ - target.addTempSkill('psqupo_red'); - target.addMark('psqupo_red',1,false); + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.logSkill("psqupo", target); + player.give(cards, target); + var color = get.color(cards[0]); + if (color == "black") { + _status.currentPhase.addTempSkill("psqupo_black"); + _status.currentPhase.markAuto("psqupo_black", [target]); + } else if (color == "red") { + target.addTempSkill("psqupo_red"); + target.addMark("psqupo_red", 1, false); } } }, - subSkill:{ - black:{ - trigger:{player:'useCardToTarget'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - var targets=player.getStorage('psqupo_black').slice(); + subSkill: { + black: { + trigger: { player: "useCardToTarget" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + var targets = player.getStorage("psqupo_black").slice(); targets.remove(event.target); return targets.length; }, - content:function(){ - var targets=player.getStorage('psqupo_black').slice(); + content: function () { + var targets = player.getStorage("psqupo_black").slice(); targets.remove(trigger.target); player.loseHp(targets.length); - } + }, + }, + red: { + trigger: { player: "damageBegin3" }, + charlotte: true, + forced: true, + onremove: true, + content: function () { + player.loseHp(player.countMark("psqupo_red")); + player.removeSkill("psqupo_red"); + }, }, - red:{ - trigger:{player:'damageBegin3'}, - charlotte:true, - forced:true, - onremove:true, - content:function(){ - player.loseHp(player.countMark('psqupo_red')); - player.removeSkill('psqupo_red'); - } - } - } - }, - psbaoquan:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay']})||_status.connectMode; }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('psbaoquan'),{type:['trick','delay']}).set('logSkill','psbaoquan').set('ai',card=>{ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('goon',get.damageEffect(player,trigger.source,player)<-5); - 'step 1' - if(result.bool){ + }, + psbaoquan: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return player.countCards("h", { type: ["trick", "delay"] }) || _status.connectMode; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("psbaoquan"), { type: ["trick", "delay"] }) + .set("logSkill", "psbaoquan") + .set("ai", (card) => { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", get.damageEffect(player, trigger.source, player) < -5); + "step 1"; + if (result.bool) { trigger.cancel(); } - } + }, }, //官盗S吕布 - pssheji:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:-1, - position:'h', - locked:false, - filter:function(event,player){ - if(player.hasSkill('pssheji_used')) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var card of hs){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2===false) return false; + pssheji: { + audio: 2, + enable: "phaseUse", + filterCard: true, + selectCard: -1, + position: "h", + locked: false, + filter: function (event, player) { + if (player.hasSkill("pssheji_used")) return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var card of hs) { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 === false) return false; } - return event.filterCard(get.autoViewAs({name:'sha'},hs)); + return event.filterCard(get.autoViewAs({ name: "sha" }, hs)); }, - viewAs:{ - name:'sha', - storage:{pssheji:true} + viewAs: { + name: "sha", + storage: { pssheji: true }, }, - onuse:function(links,player){ - player.addTempSkill('pssheji_used','phaseUseAfter'); + onuse: function (links, player) { + player.addTempSkill("pssheji_used", "phaseUseAfter"); }, - ai:{ - order:1, - threaten:1.1, + ai: { + order: 1, + threaten: 1.1, }, - mod:{ - targetInRange:function(card,player,target){ - if(card.storage&&card.storage.pssheji) return true; - } + mod: { + targetInRange: function (card, player, target) { + if (card.storage && card.storage.pssheji) return true; + }, }, - subSkill:{ - used:{ - audio:'pssheji', - trigger:{source:'damageSource'}, - charlotte:true, - forced:true, - popup:false, - logTarget:'player', - filter:function(event,player){ - return event.card.storage&&event.card.storage.pssheji&&event.player.hasCard(card=>{ - if(!lib.filter.canBeGained(card,player,event.player)) return false; - return ['equip1','equip3','equip4','equip6'].includes(get.subtype(card)); - },'e'); + subSkill: { + used: { + audio: "pssheji", + trigger: { source: "damageSource" }, + charlotte: true, + forced: true, + popup: false, + logTarget: "player", + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.pssheji && + event.player.hasCard((card) => { + if (!lib.filter.canBeGained(card, player, event.player)) return false; + return ["equip1", "equip3", "equip4", "equip6"].includes( + get.subtype(card) + ); + }, "e") + ); }, - content:function(){ - var cards=trigger.player.getCards('e',card=>{ - if(!lib.filter.canBeGained(card,player,trigger.player)) return false; - return ['equip1','equip3','equip4','equip6'].includes(get.subtype(card)); + content: function () { + var cards = trigger.player.getCards("e", (card) => { + if (!lib.filter.canBeGained(card, player, trigger.player)) return false; + return ["equip1", "equip3", "equip4", "equip6"].includes(get.subtype(card)); }); - if(cards.length) player.gain(cards,'giveAuto',trigger.player); - } - } + if (cards.length) player.gain(cards, "giveAuto", trigger.player); + }, + }, }, }, //战役篇国战将转身份 //钟会 - zyquanji:{ - audio:'gzquanji', - trigger:{ - player:'damageEnd', - source:'damageSource', + zyquanji: { + audio: "gzquanji", + trigger: { + player: "damageEnd", + source: "damageSource", }, - frequent:true, - filter:function(event,player,name){ - if(name=='damageEnd') return true; - var evt=event.getParent(); - if(evt.player!=player) return false; - return evt.card&&evt.type=='card'&&evt.targets.length==1; + frequent: true, + filter: function (event, player, name) { + if (name == "damageEnd") return true; + var evt = event.getParent(); + if (evt.player != player) return false; + return evt.card && evt.type == "card" && evt.targets.length == 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - var hs=player.getCards('he'); - if(hs.length>0){ - if(hs.length==1) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择一张牌作为“权”'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var cs=result.cards; - player.addToExpansion(cs,player,'give').gaintag.add('zyquanji'); + "step 1"; + var hs = player.getCards("he"); + if (hs.length > 0) { + if (hs.length == 1) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", true, "选择一张牌作为“权”"); + } else event.finish(); + "step 2"; + if (result.bool) { + var cs = result.cards; + player.addToExpansion(cs, player, "give").gaintag.add("zyquanji"); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - locked:false, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('zyquanji').length; + locked: false, + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("zyquanji").length; }, }, }, - zypaiyi:{ - audio:'gzpaiyi', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.getExpansions('zyquanji').length>0; + zypaiyi: { + audio: "gzpaiyi", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.getExpansions("zyquanji").length > 0; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('排异',player.getExpansions('zyquanji'),'hidden') + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("排异", player.getExpansions("zyquanji"), "hidden"); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'gzpaiyi', - filterTarget:true, - filterCard:function(){return false}, - selectCard:-1, - card:links[0], - delay:false, - content:lib.skill.zypaiyi.contentx, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(target!=player) return 0; - if(player.getExpansions('zyquanji').length<=1||(player.needsToDiscard()&&!player.getEquip('zhuge')&&!player.hasSkill('new_paoxiao'))) return 0; + audio: "gzpaiyi", + filterTarget: true, + filterCard: function () { + return false; + }, + selectCard: -1, + card: links[0], + delay: false, + content: lib.skill.zypaiyi.contentx, + ai: { + order: 10, + result: { + target: function (player, target) { + if (target != player) return 0; + if ( + player.getExpansions("zyquanji").length <= 1 || + (player.needsToDiscard() && + !player.getEquip("zhuge") && + !player.hasSkill("new_paoxiao")) + ) + return 0; return 1; - } + }, }, }, - } + }; + }, + prompt: function () { + return "请选择【排异】的目标"; }, - prompt:function(){return '请选择【排异】的目标'}, }, - contentx:function(){ - "step 0" - var card=lib.skill.zypaiyi_backup.card; + contentx: function () { + "step 0"; + var card = lib.skill.zypaiyi_backup.card; player.loseToDiscardpile(card); - "step 1" - var num=player.getExpansions('zyquanji').length; - if(num>0) target.draw(Math.min(7,num)); - "step 2" - if(target.countCards('h')>player.countCards('h')){ + "step 1"; + var num = player.getExpansions("zyquanji").length; + if (num > 0) target.draw(Math.min(7, num)); + "step 2"; + if (target.countCards("h") > player.countCards("h")) { target.damage(); } }, - ai:{ - order:function(item,player){ - var num=player.getExpansions('zyquanji').length; - if(num==1) return 8; + ai: { + order: function (item, player) { + var num = player.getExpansions("zyquanji").length; + if (num == 1) return 8; return 1; }, - result:{ - player:1, + result: { + player: 1, }, + combo: "zyquanji" }, }, //孙綝 - zyshilu:{ - audio:'gzshilu', - preHidden:true, - trigger:{global:'dieAfter'}, - prompt2:function(event,player){ - return '将其的所有武将牌'+(player==event.source?'及武将牌库里的一张随机武将牌':'')+'置于武将牌上作为“戮”'; + zyshilu: { + audio: "gzshilu", + preHidden: true, + trigger: { global: "dieAfter" }, + prompt2: function (event, player) { + return ( + "将其的所有武将牌" + + (player == event.source ? "及武将牌库里的一张随机武将牌" : "") + + "置于武将牌上作为“戮”" + ); }, - logTarget:'player', - content:function(){ - var list=[],target=trigger.player; - if(target.name1&&!target.isUnseen(0)&&target.name1.indexOf('gz_shibing')!=0&&_status.characterlist.includes(target.name1)) list.push(target.name1); - if(target.name2&&!target.isUnseen(1)&&target.name2.indexOf('gz_shibing')!=0&&_status.characterlist.includes(target.name1)) list.push(target.name2); + logTarget: "player", + content: function () { + var list = [], + target = trigger.player; + if ( + target.name1 && + !target.isUnseen(0) && + target.name1.indexOf("gz_shibing") != 0 && + _status.characterlist.includes(target.name1) + ) + list.push(target.name1); + if ( + target.name2 && + !target.isUnseen(1) && + target.name2.indexOf("gz_shibing") != 0 && + _status.characterlist.includes(target.name1) + ) + list.push(target.name2); _status.characterlist.removeArray(list); - if(player==trigger.source) list.addArray(_status.characterlist.randomRemove(1)); - if(list.length){ - player.markAuto('zyshilu',list); - game.log(player,'将','#g'+get.translation(list),'置于武将牌上作为','#y“戮”'); - game.broadcastAll(function(player,list){ - var cards=[]; - for(var i=0;i0&&player.countCards('he')>0; + group: "zyshilu_zhiheng", + subSkill: { + zhiheng: { + audio: "zyshilu", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getStorage("zyshilu").length > 0 && player.countCards("he") > 0; }, - direct:true, - content:function(){ - 'step 0' - var num=Math.min(player.getStorage('zyshilu').length,player.countCards('he')); - player.chooseToDiscard('he',get.prompt('zyshilu'),'弃置至多'+get.cnNumber(num)+'张牌并摸等量的牌',[1,num]).logSkill='zyshilu_zhiheng'; - 'step 1' - if(result.bool&&result.cards&&result.cards.length) player.draw(result.cards.length); + direct: true, + content: function () { + "step 0"; + var num = Math.min(player.getStorage("zyshilu").length, player.countCards("he")); + player.chooseToDiscard( + "he", + get.prompt("zyshilu"), + "弃置至多" + get.cnNumber(num) + "张牌并摸等量的牌", + [1, num] + ).logSkill = "zyshilu_zhiheng"; + "step 1"; + if (result.bool && result.cards && result.cards.length) + player.draw(result.cards.length); }, }, }, }, - zyxiongnve:{ - audio:'gzxiongnve', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.getStorage('zyshilu').length>0; + zyxiongnve: { + audio: "gzxiongnve", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.getStorage("zyshilu").length > 0; }, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('zyxiongnve'),[player.storage.zyshilu,'character']]).set('ai',function(button){ - if(!_status.event.goon) return 0; - return 1; - }).set('goon',player.countCards('hs',function(card){ - return get.tag(card,'damage')&&player.hasValueTarget(card); - })>1); - 'step 1' - if(result.bool){ - player.logSkill('zyxiongnve'); - lib.skill.zyxiongnve.throwCharacter(player,result.links); + content: function () { + "step 0"; + player + .chooseButton([get.prompt("zyxiongnve"), [player.storage.zyshilu, "character"]]) + .set("ai", function (button) { + if (!_status.event.goon) return 0; + return 1; + }) + .set( + "goon", + player.countCards("hs", function (card) { + return get.tag(card, "damage") && player.hasValueTarget(card); + }) > 1 + ); + "step 1"; + if (result.bool) { + player.logSkill("zyxiongnve"); + lib.skill.zyxiongnve.throwCharacter(player, result.links); game.delayx(); - player.chooseControl().set('prompt','选择获得一项效果').set('choiceList',[ - '本回合造成的伤害+1', - '本回合造成伤害时,获得其一张牌', - '本回合使用牌没有次数限制', - ]).set('ai',function(){ - var player=_status.event.player; - if(player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card); - })>player.getCardUsable('sha')) return 0; - return get.rand(1,2); - }); - } - else event.finish(); - 'step 2' - var skill='zyxiongnve_effect'+result.index; + player + .chooseControl() + .set("prompt", "选择获得一项效果") + .set("choiceList", [ + "本回合造成的伤害+1", + "本回合造成伤害时,获得其一张牌", + "本回合使用牌没有次数限制", + ]) + .set("ai", function () { + var player = _status.event.player; + if ( + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) > player.getCardUsable("sha") + ) + return 0; + return get.rand(1, 2); + }); + } else event.finish(); + "step 2"; + var skill = "zyxiongnve_effect" + result.index; player.addTempSkill(skill); - game.log(player,'本回合','#g'+lib.skill[skill].promptx) + game.log(player, "本回合", "#g" + lib.skill[skill].promptx); }, - group:'zyxiongnve_end', - throwCharacter:function(player,list){ - player.unmarkAuto('zyshilu',list); + group: "zyxiongnve_end", + throwCharacter: function (player, list) { + player.unmarkAuto("zyshilu", list); _status.characterlist.addArray(list); - game.log(player,'从','#y“戮”','中移去了','#g'+get.translation(list)); - game.broadcastAll(function(player,list){ - var cards=[]; - for(var i=0;i0; + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event, player) { + return ( + player != event.player && event.player.countGainableCards(player, "he") > 0 + ); }, - logTarget:'player', - content:function(){ - player.gainPlayerCard(trigger.player,true,'he'); - } - }, - effect2:{ - promptx:'使用牌没有次数限制', - charlotte:true, - onremove:true, - intro:{ - content:'使用牌没有次数限制', - }, - mod:{ - cardUsable:()=>Infinity + logTarget: "player", + content: function () { + player.gainPlayerCard(trigger.player, true, "he"); }, }, - effect3:{ - charlotte:true, - audio:'zyxiongnve', - mark:true, - intro:{ - content:'受到的伤害-1', + effect2: { + promptx: "使用牌没有次数限制", + charlotte: true, + onremove: true, + intro: { + content: "使用牌没有次数限制", }, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return event.source!=player&&event.source&&event.source.isIn(); + mod: { + cardUsable: () => Infinity, }, - content:function(){ + }, + effect3: { + charlotte: true, + audio: "zyxiongnve", + mark: true, + intro: { + content: "受到的伤害-1", + }, + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return event.source != player && event.source && event.source.isIn(); + }, + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } - } - } + }, + }, }, }, - end:{ - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.getStorage('zyshilu').length>1; + end: { + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.getStorage("zyshilu").length > 1; }, - content:function(){ - 'step 0' - player.chooseButton(['凶虐:是否移去两张“戮”获得减伤?',[player.storage.zyshilu,'character']],2).set('ai',function(button){ - var player=_status.event.player; - if(game.countPlayer()*1.5+player.storage.zyshilu.length/2>8) return 1; - if(player.hp<=2) return 1; - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('zyxiongnve'); - lib.skill.zyxiongnve.throwCharacter(player,result.links); - player.addTempSkill('zyxiongnve_effect3',{player:'phaseBegin'}); + content: function () { + "step 0"; + player + .chooseButton( + [ + "凶虐:是否移去两张“戮”获得减伤?", + [player.storage.zyshilu, "character"], + ], + 2 + ) + .set("ai", function (button) { + var player = _status.event.player; + if (game.countPlayer() * 1.5 + player.storage.zyshilu.length / 2 > 8) + return 1; + if (player.hp <= 2) return 1; + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("zyxiongnve"); + lib.skill.zyxiongnve.throwCharacter(player, result.links); + player.addTempSkill("zyxiongnve_effect3", { player: "phaseBegin" }); game.delayx(); } }, }, }, + ai: { + combo: "zyshilu", + }, }, //孟达 - qiuan:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return event.cards&&event.cards.filterInD().length>0&&!player.getExpansions('qiuan').length; + qiuan: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return ( + event.cards && + event.cards.filterInD().length > 0 && + !player.getExpansions("qiuan").length + ); }, - check:function(event,player){ - if(get.damageEffect(player,event.source||player,player,event.nature)>=0) return false; + check: function (event, player) { + if (get.damageEffect(player, event.source || player, player, event.nature) >= 0) + return false; return true; }, - preHidden:true, - content:function(){ - var cards=trigger.cards.filterInD(); - player.addToExpansion('gain2',cards).gaintag.add('qiuan'); + preHidden: true, + content: function () { + var cards = trigger.cards.filterInD(); + player.addToExpansion("gain2", cards).gaintag.add("qiuan"); trigger.cancel(); }, - intro:{ - content:'expansion', - markcount:'expansion', + ai: { + combo: "liangfan", }, - marktext:'函', + intro: { + content: "expansion", + markcount: "expansion", + }, + marktext: "函", }, - liangfan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('qiuan').length>0; + liangfan: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("qiuan").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('qiuan'); - player.gain(cards,'gain2').gaintag.add('liangfan'); - player.addTempSkill('liangfan2'); - 'step 1' + content: function () { + "step 0"; + var cards = player.getExpansions("qiuan"); + player.gain(cards, "gain2").gaintag.add("liangfan"); + player.addTempSkill("liangfan2"); + "step 1"; player.loseHp(); }, + ai: { + combo: "qiuan", + }, }, - liangfan2:{ - audio:'liangfan', - mark:true, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('liangfan')) return num+0.1; + liangfan2: { + audio: "liangfan", + mark: true, + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("liangfan")) return num + 0.1; }, }, - intro:{content:'使用“量反”牌造成伤害后,可获得目标角色的一张牌'}, - trigger:{source:'damageEnd'}, - logTarget:'player', - charlotte:true, - onremove:function(player){ - player.removeGaintag('liangfan'); + intro: { content: "使用“量反”牌造成伤害后,可获得目标角色的一张牌" }, + trigger: { source: "damageEnd" }, + logTarget: "player", + charlotte: true, + onremove: function (player) { + player.removeGaintag("liangfan"); }, - prompt:(event)=>('量反:是否获得'+get.translation(event.player)+'的一张牌?'), - filter:function(event,player){ - var evt=event.getParent(2); - if(evt.name!='useCard'||evt.card!=event.card) return false; - if(!event.player.countGainableCards(player,'he')) return false; - return player.getHistory('lose',function(evt2){ - if(evt2.getParent()!=evt) return false; - for(var i in evt2.gaintag_map){ - if(evt2.gaintag_map[i].includes('liangfan')) return true; - } - return false; - }).length>0; + prompt: (event) => "量反:是否获得" + get.translation(event.player) + "的一张牌?", + filter: function (event, player) { + var evt = event.getParent(2); + if (evt.name != "useCard" || evt.card != event.card) return false; + if (!event.player.countGainableCards(player, "he")) return false; + return ( + player.getHistory("lose", function (evt2) { + if (evt2.getParent() != evt) return false; + for (var i in evt2.gaintag_map) { + if (evt2.gaintag_map[i].includes("liangfan")) return true; + } + return false; + }).length > 0 + ); }, - marktext:'反', - content:function(){ - player.gainPlayerCard(trigger.player,true,'he'); + marktext: "反", + content: function () { + player.gainPlayerCard(trigger.player, true, "he"); }, }, //文钦 - gzjinfa:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - }) + gzjinfa: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; + }) + ); }, - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' - target.chooseCard('he','交给'+get.translation(player)+'一张装备牌,或令其获得你的一张牌',{type:'equip'}).set('ai',function(card){ - if(_status.event.goon&&get.suit(card)=='spade') return 8-get.value(card); - return 5-get.value(card); - }).set('goon',target.canUse('sha',player,false)&&get.effect(player,{name:'sha'},target,target)>0); - 'step 1' - if(!result.bool){ - player.gainPlayerCard(target,'he',true); + content: function () { + "step 0"; + target + .chooseCard( + "he", + "交给" + get.translation(player) + "一张装备牌,或令其获得你的一张牌", + { type: "equip" } + ) + .set("ai", function (card) { + if (_status.event.goon && get.suit(card) == "spade") return 8 - get.value(card); + return 5 - get.value(card); + }) + .set( + "goon", + target.canUse("sha", player, false) && + get.effect(player, { name: "sha" }, target, target) > 0 + ); + "step 1"; + if (!result.bool) { + player.gainPlayerCard(target, "he", true); event.finish(); - } - else target.give(result.cards,player); - 'step 2' - if(result.bool&&result.cards&&result.cards.length&& - target.isIn()&&player.isIn()&&get.suit(result.cards[0],target)=='spade'&&target.canUse('sha',player,false)) target.useCard({name:'sha',isCard:true},false,player); + } else target.give(result.cards, player); + "step 2"; + if ( + result.bool && + result.cards && + result.cards.length && + target.isIn() && + player.isIn() && + get.suit(result.cards[0], target) == "spade" && + target.canUse("sha", player, false) + ) + target.useCard({ name: "sha", isCard: true }, false, player); }, - ai:{ - order:6, - result:{ - player:function(player,target){ - if(target.countCards('e',function(card){ - return get.suit(card)=='spade'&&get.value(card)<8; - })&&target.canUse('sha',player,false)) return get.effect(player,{name:'sha'},target,player); + ai: { + order: 6, + result: { + player: function (player, target) { + if ( + target.countCards("e", function (card) { + return get.suit(card) == "spade" && get.value(card) < 8; + }) && + target.canUse("sha", player, false) + ) + return get.effect(player, { name: "sha" }, target, player); return 0; }, - target:function(player,target){ - var es=target.getCards('e').sort(function(a,b){ - return get.value(b,target)-get.value(a,target); + target: function (player, target) { + var es = target.getCards("e").sort(function (a, b) { + return get.value(b, target) - get.value(a, target); }); - if(es.length) return -Math.min(2,get.value(es[0])) + if (es.length) return -Math.min(2, get.value(es[0])); return -2; }, }, }, }, //一战成名·群雄逐鹿·长安之战专属神贾诩 - zybishi:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.player!=player; + zybishi: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return event.card.name == "sha" && event.player != player; }, - check:function(event,player){ - var effect=0; - if(event.targets&&event.targets.length){ - for(var i=0; i0; + zyjianbing: { + audio: 2, + trigger: { global: "damageBegin3" }, + logTarget: "player", + filter: function (event, player) { + return ( + event.player != player && + event.player.isIn() && + event.card && + event.card.name == "sha" && + event.player.countGainableCards(player, "he") > 0 + ); }, - content:function(){ - 'step 0' - player.gainPlayerCard(trigger.player,true,'he'); - 'step 1' - if(result.bool&&result.cards&&result.cards.length){ - var card=result.cards[0]; - if(get.suit(card,trigger.player)=='heart'){ + content: function () { + "step 0"; + player.gainPlayerCard(trigger.player, true, "he"); + "step 1"; + if (result.bool && result.cards && result.cards.length) { + var card = result.cards[0]; + if (get.suit(card, trigger.player) == "heart") { trigger.player.recover(); } } }, }, //战役篇改王允 - zylianji:{ - audio:'wylianji', - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.hasHistory('useCard',evt=>evt.getParent('phaseUse')==event); + zylianji: { + audio: "wylianji", + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return player.hasHistory("useCard", (evt) => evt.getParent("phaseUse") == event); }, - direct:true, - content:function(){ - 'step 0' - var types=[]; - player.getHistory('useCard',evt=>{ - if(evt.getParent('phaseUse')!=trigger) return false; + direct: true, + content: function () { + "step 0"; + var types = []; + player.getHistory("useCard", (evt) => { + if (evt.getParent("phaseUse") != trigger) return false; types.add(get.type2(evt.card)); }); - event.num=types.length; - event.logged=false; - player.chooseTarget(get.prompt('zylianji'),'令一名角色摸一张牌').set('ai',target=>{ - var player=_status.event.player; - if(target==player&&player.needsToDiscard(1)) return 1; - return get.effect(target,{name:'draw'},player,player); + event.num = types.length; + event.logged = false; + player.chooseTarget(get.prompt("zylianji"), "令一名角色摸一张牌").set("ai", (target) => { + var player = _status.event.player; + if (target == player && player.needsToDiscard(1)) return 1; + return get.effect(target, { name: "draw" }, player, player); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(!event.logged){event.logged=true;player.logSkill('zylianji',target);} + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (!event.logged) { + event.logged = true; + player.logSkill("zylianji", target); + } target.draw(); } - if(event.num<=1) event.finish(); - 'step 2' - if(player.isHealthy()) event._result={bool:false}; - else player.chooseBool(get.prompt('zylianji'),'回复1点体力').set('ai',()=>true); - 'step 3' - if(result.bool){ - if(!event.logged){event.logged=true;player.logSkill('zylianji');} + if (event.num <= 1) event.finish(); + "step 2"; + if (player.isHealthy()) event._result = { bool: false }; + else player.chooseBool(get.prompt("zylianji"), "回复1点体力").set("ai", () => true); + "step 3"; + if (result.bool) { + if (!event.logged) { + event.logged = true; + player.logSkill("zylianji"); + } player.recover(); } - if(event.num<=2) event.finish(); - 'step 4' - player.chooseTarget(get.prompt('zylianji'),'跳过本回合的剩余阶段,然后令一名其他角色执行这些阶段',lib.filter.notMe).set('ai',target=>{ - var att=get.attitude(_status.event.player,target),num=target.needsToDiscard(),numx=player.needsToDiscard(); - if(att<0&&num>0) return -att*Math.sqrt(num)/3+numx; - var skills=target.getSkills(); - var val=0; - for(var skill of skills){ - var info=get.info(skill); - if(info.trigger&&info.trigger.player&&(info.trigger.player.indexOf('phaseJieshu')==0||Array.isArray(info.trigger.player)&&info.trigger.player.some(i=>i.indexOf('phaseJieshu')==0))){ - var threaten=info.ai&&info.ai.threaten?info.ai.threaten:1; - if(info.ai&&info.ai.neg) val-=3*threaten; - else if(info.ai&&info.ai.halfneg) val-=1.5*threaten; - else val+=threaten; + if (event.num <= 2) event.finish(); + "step 4"; + player + .chooseTarget( + get.prompt("zylianji"), + "跳过本回合的剩余阶段,然后令一名其他角色执行这些阶段", + lib.filter.notMe + ) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target), + num = target.needsToDiscard(), + numx = player.needsToDiscard(); + if (att < 0 && num > 0) return (-att * Math.sqrt(num)) / 3 + numx; + var skills = target.getSkills(); + var val = 0; + for (var skill of skills) { + var info = get.info(skill); + if ( + info.trigger && + info.trigger.player && + (info.trigger.player.indexOf("phaseJieshu") == 0 || + (Array.isArray(info.trigger.player) && + info.trigger.player.some((i) => i.indexOf("phaseJieshu") == 0))) + ) { + var threaten = info.ai && info.ai.threaten ? info.ai.threaten : 1; + if (info.ai && info.ai.neg) val -= 3 * threaten; + else if (info.ai && info.ai.halfneg) val -= 1.5 * threaten; + else val += threaten; + } } - } - return att*val/2+numx; - }); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - if(!event.logged){event.logged=true;player.logSkill('zylianji',target);} - else player.line(target); - player.addTempSkill('zylianji_skip'); - player.storage.zylianji_insert=target; + return (att * val) / 2 + numx; + }); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + if (!event.logged) { + event.logged = true; + player.logSkill("zylianji", target); + } else player.line(target); + player.addTempSkill("zylianji_skip"); + player.storage.zylianji_insert = target; } }, - subSkill:{ - skip:{ - trigger:{ - player:['phaseZhunbeiBefore','phaseJudgeBefore','phaseDrawBefore','phaseUseBefore','phaseDiscardBefore','phaseJieshuBefore'], + subSkill: { + skip: { + trigger: { + player: [ + "phaseZhunbeiBefore", + "phaseJudgeBefore", + "phaseDrawBefore", + "phaseUseBefore", + "phaseDiscardBefore", + "phaseJieshuBefore", + ], }, - init:function(player){ - if(!player.storage.zylianji_skip) player.storage.zylianji_skip=[]; + init: function (player) { + if (!player.storage.zylianji_skip) player.storage.zylianji_skip = []; }, - forced:true, - charlotte:true, - group:'zylianji_insert', - onremove:true, - content:function(){ + forced: true, + charlotte: true, + group: "zylianji_insert", + onremove: true, + content: function () { trigger.cancel(); player.storage.zylianji_skip.push(trigger.name); - } - }, - insert:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - return player.storage.zylianji_skip&&player.storage.zylianji_skip.length&&player.storage.zylianji_insert&&player.storage.zylianji_insert.isIn(); }, - forced:true, - charlotte:true, - onremove:true, - getStr:function(str){ - switch(str){ - case 'phaseDraw': - return 'player.phaseDraw();if(!player.noPhaseDelay){if(player==game.me){game.delay()}else{game.delayx()}}'; - case 'phaseDiscard': - return 'game.broadcastAll(function(){if(ui.tempnowuxie){ui.tempnowuxie.close();delete ui.tempnowuxie;}});player.phaseDiscard();if(!player.noPhaseDelay){game.delayx()};delete player._noSkill;'; + }, + insert: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + return ( + player.storage.zylianji_skip && + player.storage.zylianji_skip.length && + player.storage.zylianji_insert && + player.storage.zylianji_insert.isIn() + ); + }, + forced: true, + charlotte: true, + onremove: true, + getStr: function (str) { + switch (str) { + case "phaseDraw": + return "player.phaseDraw();if(!player.noPhaseDelay){if(player==game.me){game.delay()}else{game.delayx()}}"; + case "phaseDiscard": + return "game.broadcastAll(function(){if(ui.tempnowuxie){ui.tempnowuxie.close();delete ui.tempnowuxie;}});player.phaseDiscard();if(!player.noPhaseDelay){game.delayx()};delete player._noSkill;"; default: - return 'player.'+str+'();'; + return "player." + str + "();"; } }, - content:function(){ - 'step 0' - var func=''; - for(var i=0;i0){ + if (get.mode() != "guozhan" && !player.hasSkillTag("rejudge")) + next.set("callback", function () { + if (get.position(card, true) == "o") player.gain(card, "gain2"); + }); + else + next.set("callback", function () { + event.getParent().orderingCards.remove(card); + }); + "step 2"; + if (result.judge > 0) { event.cards.push(result.card); - player.chooseBool('是否再次发动【洛神】?').set('frequentSkill','yjluoshen'); - } - else{ - for(var i=0;i0; }, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(ui.selected.targets.length){ - return ui.selected.targets[0]!=target&&!ui.selected.targets[0].hasSkillTag('noCompareSource')&&target.countCards('h') - &&!target.hasSkillTag('noCompareTarget'); + }, + yjjianshu: { + audio: "jianshu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + filterTarget: function (card, player, target) { + if (target == player) return false; + if (ui.selected.targets.length) { + return ( + ui.selected.targets[0] != target && + !ui.selected.targets[0].hasSkillTag("noCompareSource") && + target.countCards("h") && + !target.hasSkillTag("noCompareTarget") + ); } return true; }, - filterCard:true, - discard:false, - lose:false, - delay:false, - check:function(card){ - if(_status.event.player.hp==1) return 8-get.value(card); - return 6-get.value(card); + filterCard: true, + discard: false, + lose: false, + delay: false, + check: function (card) { + if (_status.event.player.hp == 1) return 8 - get.value(card); + return 6 - get.value(card); }, - selectTarget:2, - targetprompt:['发起者','拼点对象'], - multitarget:true, - content:function(){ - 'step 0' - player.give(cards,targets[0],'give'); - 'step 1' + selectTarget: 2, + targetprompt: ["发起者", "拼点对象"], + multitarget: true, + content: function () { + "step 0"; + player.give(cards, targets[0], "give"); + "step 1"; targets[0].chooseToCompare(targets[1]); - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { targets[1].loseHp(); - } - else if(result.tie){ - targets[0].loseHp() - targets[1].loseHp() - } - else{ + } else if (result.tie) { + targets[0].loseHp(); + targets[1].loseHp(); + } else { targets[0].loseHp(); } }, - ai:{ - expose:0.4, - order:4, - result:{ - target:function(player,target){ - if(ui.selected.targets.length) return -1; + ai: { + expose: 0.4, + order: 4, + result: { + target: function (player, target) { + if (ui.selected.targets.length) return -1; return -0.5; - } - } - } - }, - yjyongdi:{ - audio:'yongdi', - unique:true, - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - animationColor:'thunder', - skillAnimation:'legend', - mark:true, - intro:{ - content:'limited' + }, + }, }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('yjyongdi'),function(card,player,target){ - return target.hasSex('male')||target.name=='key_yuri'; - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<=1) return 0; - var mode=get.mode(); - if(mode=='identity'||(mode=='versus'&&_status.mode=='four')){ - if(target.name&&lib.character[target.name]){ - for(var i=0;i1&&event.player.isIn(); + filter: function (event, player) { + return event.isFirstTarget && event.targets.length > 1 && event.player.isIn(); }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.draw(); }, - ai:{expose:0.2} + ai: { expose: 0.2 }, }, - yjzezhu:{ - audio:'zezhu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var zhu=get.mode()=='identity'?get.zhu(player):game.filterPlayer(i=>i.getSeatNum()==1)[0]; - if(!zhu) return false; - return zhu.countGainableCards(player,zhu==player?'ej':'hej'); + yjzezhu: { + audio: "zezhu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var zhu = + get.mode() == "identity" + ? get.zhu(player) + : game.filterPlayer((i) => i.getSeatNum() == 1)[0]; + if (!zhu) return false; + return zhu.countGainableCards(player, zhu == player ? "ej" : "hej"); }, - filterTarget:function(card,player,target){ - var zhu=get.mode()=='identity'?get.zhu(player):game.filterPlayer(i=>i.getSeatNum()==1)[0]; - return target==zhu; + filterTarget: function (card, player, target) { + var zhu = + get.mode() == "identity" + ? get.zhu(player) + : game.filterPlayer((i) => i.getSeatNum() == 1)[0]; + return target == zhu; }, - selectTarget:1, - content:function(){ - 'step 0' - player.gainPlayerCard(target,player==target?'ej':'hej',true); - 'step 1' - if(!player.countCards('he')||player==target) event.finish(); - else player.chooseCard('择主:交给'+get.translation(target)+'一张牌','he',true); - 'step 2' - player.give(result.cards,target); + selectTarget: 1, + content: function () { + "step 0"; + player.gainPlayerCard(target, player == target ? "ej" : "hej", true); + "step 1"; + if (!player.countCards("he") || player == target) event.finish(); + else player.chooseCard("择主:交给" + get.translation(target) + "一张牌", "he", true); + "step 2"; + player.give(result.cards, target); + }, + ai: { + order: 2.9, + result: { player: 1 }, }, - ai:{ - order:2.9, - result:{player:1} - } }, //用间beta董卓 - yjtuicheng:{ - audio:2, - enable:'phaseUse', - viewAs:{name:'tuixinzhifu',isCard:true}, - filterCard:()=>false, - selectCard:-1, - log:false, - precontent:function(){ - player.logSkill('yjtuicheng'); + yjtuicheng: { + audio: 2, + enable: "phaseUse", + viewAs: { name: "tuixinzhifu", isCard: true }, + filterCard: () => false, + selectCard: -1, + log: false, + precontent: function () { + player.logSkill("yjtuicheng"); player.loseHp(); }, - ai:{ - effect:{ - player:function(card,player){ - if(get.name(card)!='tuixinzhifu'||_status.event.skill!='yjtuicheng') return; - if(player.hp<3) return 'zeroplayertarget'; - if(player.hasSkill('yjshicha')&&!player.hasHistory('useSkill',evt=>evt.skill=='yjtuicheng')) return [1,2]; - return 'zeroplayertarget'; - } - } - } - }, - yjyaoling:{ - audio:2, - trigger:{ - player:'phaseUseEnd', + ai: { + effect: { + player: function (card, player) { + if (get.name(card) != "tuixinzhifu" || _status.event.skill != "yjtuicheng") + return; + if (player.hp < 3) return "zeroplayertarget"; + if ( + player.hasSkill("yjshicha") && + !player.hasHistory("useSkill", (evt) => evt.skill == "yjtuicheng") + ) + return [1, 2]; + return "zeroplayertarget"; + }, + }, }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yjyaoling'),'减1点体力上限,选择一名其他角色A和一名角色B,令A选择对B使用杀或被你弃牌',2,(card,player,target)=>{ - if(!ui.selected.targets.length) return target!=player; - return ui.selected.targets[0].canUse('sha',target,false); - }).set('targetprompt',['打人','被打']).set('complexSelect',true).set('ai',target=>{ - var player=_status.event.player; - if(!ui.selected.targets.length) return get.effect(target,{name:'guohe_copy2'},player,player); - var targetx=ui.selected.targets[0]; - return get.effect(target,{name:'sha'},targetx,player)+5; - }); - 'step 1' - if(result.bool){ - var targets=result.targets; - event.targets=targets; - player.logSkill('yjyaoling',targets,false); + }, + yjyaoling: { + audio: 2, + trigger: { + player: "phaseUseEnd", + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("yjyaoling"), + "减1点体力上限,选择一名其他角色A和一名角色B,令A选择对B使用杀或被你弃牌", + 2, + (card, player, target) => { + if (!ui.selected.targets.length) return target != player; + return ui.selected.targets[0].canUse("sha", target, false); + } + ) + .set("targetprompt", ["打人", "被打"]) + .set("complexSelect", true) + .set("ai", (target) => { + var player = _status.event.player; + if (!ui.selected.targets.length) + return get.effect(target, { name: "guohe_copy2" }, player, player); + var targetx = ui.selected.targets[0]; + return get.effect(target, { name: "sha" }, targetx, player) + 5; + }); + "step 1"; + if (result.bool) { + var targets = result.targets; + event.targets = targets; + player.logSkill("yjyaoling", targets, false); player.line2(targets); player.loseMaxHp(); - targets[0].chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'耀令:对'+get.translation(targets[1])+'使用一张杀,或令'+get.translation(player)+'弃置你的一张牌').set('targetRequired',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',targets[1]); - } - else event.finish(); - 'step 2' - if(!result.bool&&targets[0].countDiscardableCards(player,'he')){ - player.discardPlayerCard(targets[0],'he',true); - } - } - }, - yjshicha:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - forced:true, - filter:function(event,player){ - var tuicheng=false,yaoling=false; - player.getHistory('useSkill',evt=>{ - if(evt.skill=='yjtuicheng') tuicheng=true; - if(evt.skill=='yjyaoling') yaoling=true; - }); - return !(tuicheng&&yaoling); - }, - content:function(){ - player.addTempSkill('yjshicha_limit'); - }, - subSkill:{ - limit:{ - charlotte:true, - mark:true, - intro:{content:'本回合手牌上限为1'}, - mod:{ - maxHandcard:()=>1 - } + targets[0] + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "耀令:对" + + get.translation(targets[1]) + + "使用一张杀,或令" + + get.translation(player) + + "弃置你的一张牌") + .set("targetRequired", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", targets[1]); + } else event.finish(); + "step 2"; + if (!result.bool && targets[0].countDiscardableCards(player, "he")) { + player.discardPlayerCard(targets[0], "he", true); } }, }, - yjyongquan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - zhuSkill:true, - filter:function(event,player){ - return player.hasZhuSkill('yjyongquan')&&game.hasPlayer(current=>{ - return current!=player&&player.hasZhuSkill(current)&¤t.group=='qun'; + yjshicha: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + forced: true, + filter: function (event, player) { + var tuicheng = false, + yaoling = false; + player.getHistory("useSkill", (evt) => { + if (evt.skill == "yjtuicheng") tuicheng = true; + if (evt.skill == "yjyaoling") yaoling = true; + }); + return !(tuicheng && yaoling); + }, + content: function () { + player.addTempSkill("yjshicha_limit"); + }, + subSkill: { + limit: { + charlotte: true, + mark: true, + intro: { content: "本回合手牌上限为1" }, + mod: { + maxHandcard: () => 1, + }, + }, + }, + ai: { + neg: true, + }, + }, + yjyongquan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + zhuSkill: true, + filter: function (event, player) { + return ( + player.hasZhuSkill("yjyongquan") && + game.hasPlayer((current) => { + return current != player && player.hasZhuSkill(current) && current.group == "qun"; + }) + ); + }, + logTarget: function (event, player) { + return game.filterPlayer((current) => { + return current != player && player.hasZhuSkill(current) && current.group == "qun"; }); }, - logTarget:function(event,player){ - return game.filterPlayer(current=>{ - return current!=player&&player.hasZhuSkill(current)&¤t.group=='qun'; - }); - }, - content:function(){ - 'step 0' - var targets=lib.skill.yjyongquan.logTarget(trigger,player); - event.targets=targets; - 'step 1' - var target=targets.shift(); - event.target=target; - target.chooseCard('拥权:是否交给'+get.translation(player)+'一张牌?','he').set('ai',card=>{ - if(_status.event.goon) return 4.5-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)>3); - 'step 2' - if(result.bool){ + content: function () { + "step 0"; + var targets = lib.skill.yjyongquan.logTarget(trigger, player); + event.targets = targets; + "step 1"; + var target = targets.shift(); + event.target = target; + target + .chooseCard("拥权:是否交给" + get.translation(player) + "一张牌?", "he") + .set("ai", (card) => { + if (_status.event.goon) return 4.5 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) > 3); + "step 2"; + if (result.bool) { target.line(player); - target.give(result.cards,player); + target.give(result.cards, player); } - 'step 3' - if(targets.length) event.goto(1); - } + "step 3"; + if (targets.length) event.goto(1); + }, }, //用间beta甘宁的新版 - yjjielve:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('yjjielve_ban'); + yjjielve: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("yjjielve_ban"); }, - viewAs:{name:'chenghuodajie'}, - filterCard:function(card,player){ - if(ui.selected.cards.length) return get.color(card)==get.color(ui.selected.cards[0]); - var cards=player.getCards('hes'); - for(var cardx of cards){ - if(card!=cardx&&get.color(card)==get.color(cardx)) return true; + viewAs: { name: "chenghuodajie" }, + filterCard: function (card, player) { + if (ui.selected.cards.length) return get.color(card) == get.color(ui.selected.cards[0]); + var cards = player.getCards("hes"); + for (var cardx of cards) { + if (card != cardx && get.color(card) == get.color(cardx)) return true; } return false; }, - position:'hes', - selectCard:2, - complexCard:true, - check:function(card){ - return 5-get.value(card); + position: "hes", + selectCard: 2, + complexCard: true, + check: function (card) { + return 5 - get.value(card); }, - onuse:function(links,player){ - player.addTempSkill('yjjielve_check'); + onuse: function (links, player) { + player.addTempSkill("yjjielve_check"); }, - subSkill:{ - check:{ - trigger:{source:'damageSource'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='chenghuodajie'&&event.getParent().skill=='yjjielve'; + subSkill: { + check: { + trigger: { source: "damageSource" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.name == "chenghuodajie" && + event.getParent().skill == "yjjielve" + ); + }, + content: function () { + player.addTempSkill("yjjielve_ban"); }, - content:function(){ - player.addTempSkill('yjjielve_ban'); - } }, - ban:{charlotte:true} - } + ban: { charlotte: true }, + }, }, //用间beta张飞 - yjmangji:{ - audio:2, - forced:true, - trigger:{ - player:['loseAfter','damageEnd','loseHpEnd','recoverEnd'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + yjmangji: { + audio: 2, + forced: true, + trigger: { + player: ["loseAfter", "damageEnd", "loseHpEnd", "recoverEnd"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function (event,player){ - if(player.hp<1||!player.countDiscardableCards(player,'h')) return false; - if(['damage','loseHp','recover'].includes(event.name)) return true; - var evt=event.getl(player); - if(event.name=='equip'&&event.player==player) return !evt||evt.cards.length!=1; - if(!evt||!evt.es.length) return false; - return game.hasPlayer(current=>player.canUse('sha',current,false)); + direct: true, + filter: function (event, player) { + if (player.hp < 1 || !player.countDiscardableCards(player, "h")) return false; + if (["damage", "loseHp", "recover"].includes(event.name)) return true; + var evt = event.getl(player); + if (event.name == "equip" && event.player == player) return !evt || evt.cards.length != 1; + if (!evt || !evt.es.length) return false; + return game.hasPlayer((current) => player.canUse("sha", current, false)); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:'莽击:弃置一张手牌,视为对一名其他角色使用一张【杀】', - forced:true, - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - return player.canUse('sha',target,false); + prompt: "莽击:弃置一张手牌,视为对一名其他角色使用一张【杀】", + forced: true, + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + return player.canUse("sha", target, false); }, - ai2:function(target){ - return get.effect(target,{name:'sha'},_status.event.player); + ai2: function (target) { + return get.effect(target, { name: "sha" }, _status.event.player); }, - }) - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.logSkill('yjmangji',target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.logSkill("yjmangji", target); player.discard(cards); - if(player.canUse('sha',target,false)) player.useCard({name:'sha',isCard:true},target,false); + if (player.canUse("sha", target, false)) + player.useCard({ name: "sha", isCard: true }, target, false); } }, }, //用间beta曹洪 - yjlifeng:{ - audio:2, - enable:'phaseUse', - usable:1, - locked:false, - filter:function(event,player){ - for(var card of ui.discardPile.childNodes){ - if(get.type(card)=='equip') return true; + yjlifeng: { + audio: 2, + enable: "phaseUse", + usable: 1, + locked: false, + filter: function (event, player) { + for (var card of ui.discardPile.childNodes) { + if (get.type(card) == "equip") return true; } return false; }, - content:function(){ - 'step 0' - var cards=Array.from(ui.discardPile.childNodes).filter(i=>get.type(i)=='equip'); - player.chooseButton(['厉锋:获得一张装备牌',cards],cards.length>0).set('ai',get.buttonValue); - 'step 1' - if(result.bool){ - var card=result.links[0]; - player.gain(card,'gain2'); + content: function () { + "step 0"; + var cards = Array.from(ui.discardPile.childNodes).filter((i) => get.type(i) == "equip"); + player + .chooseButton(["厉锋:获得一张装备牌", cards], cards.length > 0) + .set("ai", get.buttonValue); + "step 1"; + if (result.bool) { + var card = result.links[0]; + player.gain(card, "gain2"); } }, - ai:{ - order:10, - result:{player:1}, - effect:{ - target:function(card,player,target){ - if(card&&get.type(card)=='equip'&&_status.event.skill=='_gifting') return 0; + ai: { + order: 10, + result: { player: 1 }, + effect: { + target: function (card, player, target) { + if (card && get.type(card) == "equip" && _status.event.skill == "_gifting") + return 0; }, }, }, - mod:{ - cardGiftable:function(card,player){ - return get.type(card)=='equip'; - } - } + mod: { + cardGiftable: function (card, player) { + return get.type(card) == "equip"; + }, + }, }, //用间篇李儒 - yjdumou:{ - audio:2, - forced:true, - mod:{ - cardname:function(card,player,name){ - if(player==_status.currentPhase&&card.name=='du') return 'guohe'; + yjdumou: { + audio: 2, + forced: true, + mod: { + cardname: function (card, player, name) { + if (player == _status.currentPhase && card.name == "du") return "guohe"; }, - aiValue:function(player,card,num){ - if(card.name=='du') return get.value({name:'guohe'}); + aiValue: function (player, card, num) { + if (card.name == "du") return get.value({ name: "guohe" }); }, }, - init:()=>{ - game.addGlobalSkill('yjdumou_du'); + init: () => { + game.addGlobalSkill("yjdumou_du"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('yjdumou'),true)) game.removeGlobalSkill('yjdumou_du'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("yjdumou"), true)) + game.removeGlobalSkill("yjdumou_du"); }, - subSkill:{ - du:{ - mod:{ - cardname:function(card,player,name){ - if(_status.currentPhase&&player!=_status.currentPhase&&_status.currentPhase.hasSkill('yjdumou')&&get.color(card)=='black') return 'du'; + subSkill: { + du: { + mod: { + cardname: function (card, player, name) { + if ( + _status.currentPhase && + player != _status.currentPhase && + _status.currentPhase.hasSkill("yjdumou") && + get.color(card) == "black" + ) + return "du"; }, - aiValue:function(player,card,num){ - if(get.name(card)=='du'&&card.name!='du') return get.value({name:card.name}); + aiValue: function (player, card, num) { + if (get.name(card) == "du" && card.name != "du") + return get.value({ name: card.name }); }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('yjdumou'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("yjdumou"), true); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('yjdumou_du'); - } - } + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("yjdumou_du"); + }, + }, }, - ai:{threaten:2.1} + ai: { threaten: 2.1 }, }, - yjweiquan:{ - audio:2, - enable:'phaseUse', - skillAnimation:true, - animationColor:'soil', - filterTarget:true, - limited:true, - selectTarget:()=>[1,game.roundNumber], - contentBefore:function(){ - 'step 0' - player.awakenSkill('yjweiquan'); - player.chooseTarget('威权:选择获得牌的角色',true).set('ai',target=>{ - var att=get.attitude(_status.event.player,target),num=target.needsToDiscard(targets.filter(i=>i!=target&&i.countCards('h')).length); - if(att>0&&num<=2) return 0; - if(att<0&&target.needsToDiscard(-5)) return -att-Math.sqrt(num); - return att-Math.sqrt(num); + yjweiquan: { + audio: 2, + enable: "phaseUse", + skillAnimation: true, + animationColor: "soil", + filterTarget: true, + limited: true, + selectTarget: () => [1, game.roundNumber], + contentBefore: function () { + "step 0"; + player.awakenSkill("yjweiquan"); + player.chooseTarget("威权:选择获得牌的角色", true).set("ai", (target) => { + var att = get.attitude(_status.event.player, target), + num = target.needsToDiscard( + targets.filter((i) => i != target && i.countCards("h")).length + ); + if (att > 0 && num <= 2) return 0; + if (att < 0 && target.needsToDiscard(-5)) return -att - Math.sqrt(num); + return att - Math.sqrt(num); }); - 'step 1' - event.getParent()._yjweiquan=result.targets[0]; + "step 1"; + event.getParent()._yjweiquan = result.targets[0]; }, - content:function(){ - 'step 0' - var targetx=event.getParent()._yjweiquan; - if(target==targetx||!target.countCards('h')) event.finish(); - else target.chooseCard('威权:将一张手牌交给'+get.translation(targetx),true); - 'step 1' - if(result.bool){ - var targetx=event.getParent()._yjweiquan; - target.give(result.cards,targetx); + content: function () { + "step 0"; + var targetx = event.getParent()._yjweiquan; + if (target == targetx || !target.countCards("h")) event.finish(); + else target.chooseCard("威权:将一张手牌交给" + get.translation(targetx), true); + "step 1"; + if (result.bool) { + var targetx = event.getParent()._yjweiquan; + target.give(result.cards, targetx); } }, - contentAfter:function(){ - var targetx=event.getParent()._yjweiquan; - if(targetx.countCards('h')>targetx.hp){ - var next=targetx.phase(); + contentAfter: function () { + var targetx = event.getParent()._yjweiquan; + if (targetx.countCards("h") > targetx.hp) { + var next = targetx.phase(); event.next.remove(next); event.getParent().after.push(next); - next.player=targetx; - next._noTurnOver=true; - next._triggered=null; - next.setContent(function(){ - game.broadcastAll(function(){ - if(ui.tempnowuxie){ + next.player = targetx; + next._noTurnOver = true; + next._triggered = null; + next.setContent(function () { + game.broadcastAll(function () { + if (ui.tempnowuxie) { ui.tempnowuxie.close(); delete ui.tempnowuxie; } }); player.phaseDiscard(); - if(!player.noPhaseDelay) game.delayx(); + if (!player.noPhaseDelay) game.delayx(); delete player._noSkill; }); } }, - ai:{ - order:6, - result:{ - player:function(player){ - var num=game.countPlayer(current=>get.attitude(player,current)<0&¤t.countCards('h')); - if(game.roundNumber2||!game.hasPlayer(current=>{ - return get.attitude(player,current)>0&¤t.needsToDiscard(num)<2||get.attitude(player,current)<0&¤t.needsToDiscard(-5); - })) return -10; + ai: { + order: 6, + result: { + player: function (player) { + var num = game.countPlayer( + (current) => get.attitude(player, current) < 0 && current.countCards("h") + ); + if ( + (game.roundNumber < num && player.hp > 2) || + !game.hasPlayer((current) => { + return ( + (get.attitude(player, current) > 0 && + current.needsToDiscard(num) < 2) || + (get.attitude(player, current) < 0 && current.needsToDiscard(-5)) + ); + }) + ) + return -10; return 1; }, - target:-1, - } - } - }, - yjrenwang:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - for(var card of ui.discardPile.childNodes){ - if(get.color(card)=='black'&&get.type(card)=='basic') return true; - } - return false; - }, - content:function(){ - 'step 0' - var cards=Array.from(ui.discardPile.childNodes).filter(i=>get.color(i)=='black'&&get.type(i)=='basic'); - player.chooseButton(['人望:选择一张黑色基本牌',cards],cards.length>0).set('ai',get.buttonValue); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('选择一名角色获得'+get.translation(card),true).set('ai',target=>get.attitude(_status.event.player,target)); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target); - target.gain(card,'gain2'); - } - }, - ai:{ - order:10, - result:{player:1} - } - }, - //群曹操 - yjxiandao:{ - trigger:{player:'giftAccepted'}, - usable:1, - forced:true, - locked:false, - filter:(event,player)=>event.target!=player&&event.target.isIn(), - logTarget:'target', - content:function(){ - 'step 0' - event.target=trigger.target; - event.card=trigger.card; - event.target.markAuto('yjxiandao_block',[get.suit(event.card,false)]); - event.target.addTempSkill('yjxiandao_block'); - 'step 1' - var type=get.type(card,false); - if(type=='trick') player.draw(2); - if(type=='equip'){ - if(target.countGainableCards(player,'he',function(cardx){ - return cardx!=card; - })>0) player.gainPlayerCard(target,'he',true).set('card',card).set('filterButton',function(button){ - return button.link!=_status.event.card; - }); - if(get.subtype(card,false)=='equip1') target.damage(); - } - }, - subSkill:{ - block:{ - charlotte:true, - onremove:true, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('yjxiandao_block').includes(get.suit(card))) return false; - }, - cardRespondable:function(card,player){ - if(player.getStorage('yjxiandao_block').includes(get.suit(card))) return false; - }, - cardSavable:function(card,player){ - if(player.getStorage('yjxiandao_block').includes(get.suit(card))) return false; - }, - }, - mark:true, - intro:{content:'不能使用或打出$牌'}, + target: -1, }, }, }, - yjsancai:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + yjrenwang: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + for (var card of ui.discardPile.childNodes) { + if (get.color(card) == "black" && get.type(card) == "basic") return true; + } + return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; + var cards = Array.from(ui.discardPile.childNodes).filter( + (i) => get.color(i) == "black" && get.type(i) == "basic" + ); + player + .chooseButton(["人望:选择一张黑色基本牌", cards], cards.length > 0) + .set("ai", get.buttonValue); + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget("选择一名角色获得" + get.translation(card), true) + .set("ai", (target) => get.attitude(_status.event.player, target)); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target); + target.gain(card, "gain2"); + } + }, + ai: { + order: 10, + result: { player: 1 }, + }, + }, + //群曹操 + yjxiandao: { + trigger: { player: "giftAccepted" }, + usable: 1, + forced: true, + locked: false, + filter: (event, player) => event.target != player && event.target.isIn(), + logTarget: "target", + content: function () { + "step 0"; + event.target = trigger.target; + event.card = trigger.card; + event.target.markAuto("yjxiandao_block", [get.suit(event.card, false)]); + event.target.addTempSkill("yjxiandao_block"); + "step 1"; + var type = get.type(card, false); + if (type == "trick") player.draw(2); + if (type == "equip") { + if ( + target.countGainableCards(player, "he", function (cardx) { + return cardx != card; + }) > 0 + ) + player + .gainPlayerCard(target, "he", true) + .set("card", card) + .set("filterButton", function (button) { + return button.link != _status.event.card; + }); + if (get.subtype(card, false) == "equip1") target.damage(); + } + }, + subSkill: { + block: { + charlotte: true, + onremove: true, + mod: { + cardEnabled: function (card, player) { + if (player.getStorage("yjxiandao_block").includes(get.suit(card))) + return false; + }, + cardRespondable: function (card, player) { + if (player.getStorage("yjxiandao_block").includes(get.suit(card))) + return false; + }, + cardSavable: function (card, player) { + if (player.getStorage("yjxiandao_block").includes(get.suit(card))) + return false; + }, + }, + mark: true, + intro: { content: "不能使用或打出$牌" }, + }, + }, + }, + yjsancai: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + content: function () { + "step 0"; player.showHandcards(); - var hs=player.getCards('h'); - if(hs.length>1){ - var type=get.type2(hs[0],player); - for(var i=1;i 1) { + var type = get.type2(hs[0], player); + for (var i = 1; i < hs.length; i++) { + if (get.type(hs[i]) != type) { event.finish(); return; } } } - 'step 1' + "step 1"; player.chooseCardTarget({ - prompt:'是否赠予一张手牌?', - filterCard:true, - filterTarget:lib.filter.notMe, + prompt: "是否赠予一张手牌?", + filterCard: true, + filterTarget: lib.filter.notMe, }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.gift(result.cards,target); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.gift(result.cards, target); } - } + }, }, - yjyibing:{ - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + yjyibing: { + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - direct:true, - filter:function(event,player){ - if(event.getParent().name=='gift') return false; - if(event.getParent('yjyibing').player==player) return false; - var evt=event.getParent('phaseDraw'),hs=player.getCards('h'),cards=event.getg(player); - return cards.length>0&&(!evt||evt.player!=player)&&cards.filter(function(card){ - return hs.includes(card)&&game.checkMod(card,player,'unchanged','cardEnabled2',player)!==false; - }).length==cards.length&&player.hasUseTarget({ - name:'sha', - cards:event.cards, - },false); + direct: true, + filter: function (event, player) { + if (event.getParent().name == "gift") return false; + if (event.getParent("yjyibing").player == player) return false; + var evt = event.getParent("phaseDraw"), + hs = player.getCards("h"), + cards = event.getg(player); + return ( + cards.length > 0 && + (!evt || evt.player != player) && + cards.filter(function (card) { + return ( + hs.includes(card) && + game.checkMod(card, player, "unchanged", "cardEnabled2", player) !== false + ); + }).length == cards.length && + player.hasUseTarget( + { + name: "sha", + cards: event.cards, + }, + false + ) + ); }, - content:function(){ - var cards=trigger.getg(player); - player.chooseUseTarget(get.prompt('yjyibing'),'将'+get.translation(cards)+'当做【杀】使用','sha',cards,false,'nodistance').logSkill='yjyibing'; + content: function () { + var cards = trigger.getg(player); + player.chooseUseTarget( + get.prompt("yjyibing"), + "将" + get.translation(cards) + "当做【杀】使用", + "sha", + cards, + false, + "nodistance" + ).logSkill = "yjyibing"; }, }, //龙羽飞 - longyi:{ - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - if(event.type=='wuxie') return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of hs){ - if(game.checkMod(i,player,'unchanged','cardEnabled2',player)===false) return false; + longyi: { + enable: ["chooseToUse", "chooseToRespond"], + filter: function (event, player) { + if (event.type == "wuxie") return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of hs) { + if (game.checkMod(i, player, "unchanged", "cardEnabled2", player) === false) + return false; } - for(var i of lib.inpile){ - if(i!='du'&&get.type(i)=='basic'&&event.filterCard({name:i,cards:hs},player,event)) return true; - if(i=='sha'){ - var list=['fire','thunder','ice']; - for(var j of list){ - if(event.filterCard({name:i,nature:j,cards:hs},player,event)) return true; + for (var i of lib.inpile) { + if ( + i != "du" && + get.type(i) == "basic" && + event.filterCard({ name: i, cards: hs }, player, event) + ) + return true; + if (i == "sha") { + var list = ["fire", "thunder", "ice"]; + for (var j of list) { + if (event.filterCard({ name: i, nature: j, cards: hs }, player, event)) + return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var vcards=[],hs=player.getCards('h'); - for(var i of lib.inpile){ - if(i!='du'&&get.type(i)=='basic'&&event.filterCard({name:i,cards:hs},player,event)) vcards.push(['基本','',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard({name:i,nature:j,cards:hs},player,event)) vcards.push(['基本','',i,j]); + chooseButton: { + dialog: function (event, player) { + var vcards = [], + hs = player.getCards("h"); + for (var i of lib.inpile) { + if ( + i != "du" && + get.type(i) == "basic" && + event.filterCard({ name: i, cards: hs }, player, event) + ) + vcards.push(["基本", "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: i, nature: j, cards: hs }, player, event)) + vcards.push(["基本", "", i, j]); } } } - return ui.create.dialog('龙裔',[vcards,'vcard']); + return ui.create.dialog("龙裔", [vcards, "vcard"]); }, - check:function(button,player){ - if(_status.event.getParent().type!='phase') return 1; - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); + check: function (button, player) { + if (_status.event.getParent().type != "phase") return 1; + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'longyi', - popname:true, - viewAs:{name:links[0][2],nature:links[0][3]}, - filterCard:true, - selectCard:-1, - position:'h', - } + audio: "longyi", + popname: true, + viewAs: { name: links[0][2], nature: links[0][3] }, + filterCard: true, + selectCard: -1, + position: "h", + }; }, - prompt:function(links,player){ - return '将所有手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用或打出'; - } - }, - hiddenCard:function(player,name){ - return name!='du'&&get.type(name)=='basic'&&player.countCards('h')>0; - }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - return player.countCards('h')>0; + prompt: function (links, player) { + return ( + "将所有手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用或打出" + ); }, - order:0.5, - result:{ - player:function(player){ - if(_status.event.dying){ - return get.attitude(player,_status.event.dying); + }, + hiddenCard: function (player, name) { + return name != "du" && get.type(name) == "basic" && player.countCards("h") > 0; + }, + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + return player.countCards("h") > 0; + }, + order: 0.5, + result: { + player: function (player) { + if (_status.event.dying) { + return get.attitude(player, _status.event.dying); } - if(_status.event.type=='respondShan') return 1; - var val=0,hs=player.getCards('h'),max=0; - for(var i of hs){ - val+=get.value(i,player); - if(get.type(i,player)=='trick') max+=5; + if (_status.event.type == "respondShan") return 1; + var val = 0, + hs = player.getCards("h"), + max = 0; + for (var i of hs) { + val += get.value(i, player); + if (get.type(i, player) == "trick") max += 5; } - if(player.hasSkill('zhenjue')) max+=7; - return val<=max?1:0; + if (player.hasSkill("zhenjue")) max += 7; + return val <= max ? 1 : 0; }, }, }, - group:'longyi_effect', - subSkill:{ - effect:{ - trigger:{player:['useCard','respond']}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - if(event.skill!='longyi_backup') return false; - for(var i of event.cards){ - var type=get.type2(i,player); - if(type=='equip'||type=='trick') return true; + group: "longyi_effect", + subSkill: { + effect: { + trigger: { player: ["useCard", "respond"] }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + if (event.skill != "longyi_backup") return false; + for (var i of event.cards) { + var type = get.type2(i, player); + if (type == "equip" || type == "trick") return true; } return false; }, - content:function(){ - var map={}; - for(var i of trigger.cards){ - map[get.type2(i,player)]=true; + content: function () { + var map = {}; + for (var i of trigger.cards) { + map[get.type2(i, player)] = true; } - if(map.trick) player.draw(); - if(map.equip&&trigger.directHit) trigger.directHit.addArray(game.players); + if (map.trick) player.draw(); + if (map.equip && trigger.directHit) trigger.directHit.addArray(game.players); }, }, - backup:{}, + backup: {}, }, }, - zhenjue:{ - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h')==0; + zhenjue: { + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h") == 0; }, - logTarget:'player', - content:function(){ - 'step 0' - trigger.player.chooseToDiscard('he','弃置一张牌,或令'+get.translation(player)+'摸一张牌').set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return -get.value(card); - }).set('goon',get.attitude(trigger.player,player)<0); - 'step 1' - if(!result.bool) player.draw(); + logTarget: "player", + content: function () { + "step 0"; + trigger.player + .chooseToDiscard("he", "弃置一张牌,或令" + get.translation(player) + "摸一张牌") + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return -get.value(card); + }) + .set("goon", get.attitude(trigger.player, player) < 0); + "step 1"; + if (!result.bool) player.draw(); }, }, //群刘备 - jsprende:{ - audio:'rerende', - enable:'phaseUse', - filterCard:true, - selectCard:[1,Infinity], - discard:false, - lose:false, - delay:false, - filterTarget:function(card,player,target){ - return player!=target; + jsprende: { + audio: "rerende", + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + discard: false, + lose: false, + delay: false, + filterTarget: function (card, player, target) { + return player != target; }, - onremove:true, - check:function(card){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(ui.selected.cards.length>=Math.max(2,player.countCards('h')-player.hp)) return 0; - if(player.hp==player.maxHp||player.storage.jsprende<0||player.countCards('h')<=1){ - var players=game.filterPlayer(); - for(var i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + onremove: true, + check: function (card) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + var player = get.owner(card); + if (ui.selected.cards.length >= Math.max(2, player.countCards("h") - player.hp)) return 0; + if ( + player.hp == player.maxHp || + player.storage.jsprende < 0 || + player.countCards("h") <= 1 + ) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - content:function(){ - 'step 0' - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'&&!evt.jsprende){ - var next=game.createEvent('jsprende_clear'); + content: function () { + "step 0"; + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse" && !evt.jsprende) { + var next = game.createEvent("jsprende_clear"); _status.event.next.remove(next); evt.after.push(next); - evt.jsprende=true; - next.player=player; - next.setContent(function(){ + evt.jsprende = true; + next.player = player; + next.setContent(function () { delete player.storage.jsprende; }); } - player.give(cards,target); - if(typeof player.storage.jsprende!='number'){ - player.storage.jsprende=0; + player.give(cards, target); + if (typeof player.storage.jsprende != "number") { + player.storage.jsprende = 0; } - if(player.storage.jsprende>=0){ - player.storage.jsprende+=cards.length; - if(player.storage.jsprende>=2){ - var list=[]; - if(lib.filter.cardUsable({name:'sha',isCard:true},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('sha',current); - })){ - list.push(['基本','','sha']); + if (player.storage.jsprende >= 0) { + player.storage.jsprende += cards.length; + if (player.storage.jsprende >= 2) { + var list = []; + if ( + lib.filter.cardUsable( + { name: "sha", isCard: true }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("sha", current); + }) + ) { + list.push(["基本", "", "sha"]); } - for(var i of lib.inpile_nature){ - if(lib.filter.cardUsable({name:'sha',nature:i,isCard:true},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse({name:'sha',nature:i,isCard:true},current); - })){ - list.push(['基本','','sha',i]); + for (var i of lib.inpile_nature) { + if ( + lib.filter.cardUsable( + { name: "sha", nature: i, isCard: true }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse( + { name: "sha", nature: i, isCard: true }, + current + ); + }) + ) { + list.push(["基本", "", "sha", i]); } } - if(lib.filter.cardUsable({name:'tao',isCard:true},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('tao',current); - })){ - list.push(['基本','','tao']); + if ( + lib.filter.cardUsable( + { name: "tao", isCard: true }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("tao", current); + }) + ) { + list.push(["基本", "", "tao"]); } - if(lib.filter.cardUsable({name:'jiu',isCard:true},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('jiu',current); - })){ - list.push(['基本','','jiu']); + if ( + lib.filter.cardUsable( + { name: "jiu", isCard: true }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("jiu", current); + }) + ) { + list.push(["基本", "", "jiu"]); } - if(list.length){ - player.chooseButton(['是否视为使用一张基本牌?',[list,'vcard']]).set('ai',function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3],isCard:true}; - if(card.name=='tao'){ - if(player.hp==1||(player.hp==2&&!player.hasShan())||player.needsToDiscard()){ - return 5; + if (list.length) { + player + .chooseButton(["是否视为使用一张基本牌?", [list, "vcard"]]) + .set("ai", function (button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }; + if (card.name == "tao") { + if ( + player.hp == 1 || + (player.hp == 2 && !player.hasShan()) || + player.needsToDiscard() + ) { + return 5; + } + return 1; } - return 1; - } - if(card.name=='sha'){ - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0 - })){ - if(card.nature=='fire') return 2.95; - if(card.nature=='thunder'||card.nature=='ice') return 2.92; - return 2.9; + if (card.name == "sha") { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + if (card.nature == "fire") return 2.95; + if (card.nature == "thunder" || card.nature == "ice") + return 2.92; + return 2.9; + } + return 0; + } + if (card.name == "jiu") { + return 0.5; } return 0; - } - if(card.name=='jiu'){ - return 0.5; - } - return 0; - }); - } - else{ + }); + } else { event.finish(); } - player.storage.jsprende=-1; - } - else{ + player.storage.jsprende = -1; + } else { event.finish(); } - } - else{ + } else { event.finish(); } - 'step 1' - if(result&&result.bool&&result.links[0]){ - var card={name:result.links[0][2],nature:result.links[0][3],isCard:true}; - player.chooseUseTarget(card,true); + "step 1"; + if (result && result.bool && result.links[0]) { + var card = { name: result.links[0][2], nature: result.links[0][3], isCard: true }; + player.chooseUseTarget(card, true); } }, - ai:{ - fireAttack:true, - order:function(skill,player){ - if(player.hp1){ + ai: { + fireAttack: true, + order: function (skill, player) { + if ( + player.hp < player.maxHp && + player.storage.jsprende < 2 && + player.countCards("h") > 1 + ) { return 10; } return 4; }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - var np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.jsprende<0||player.countCards('h')<=1){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + var np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.jsprende < 0 || + player.countCards("h") <= 1 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); - } + return Math.max(1, 5 - nh); + }, }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.type(card)=='equip'){ - if(player.countCards('e',{subtype:get.subtype(card)})){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })){ + effect: { + target: function (card, player, target) { + if (player == target && get.type(card) == "equip") { + if (player.countCards("e", { subtype: get.subtype(card) })) { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) { return 0; } } } - } + }, }, - threaten:0.8 - } + threaten: 0.8, + }, }, //曹安民 - nskuishe:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + nskuishe: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'he',true).set('ai',get.buttonValue); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - event.card=card; - player.chooseTarget('将'+get.translation(target)+'的'+(get.position(card)=='h'&&!player.hasSkillTag('viewHandcard',null,target,true)?'手牌':get.translation(card))+'交给一名角色',true,function(target){ - return target!=_status.event.getParent().target; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.du){ - if(target.hasSkillTag('nodu')) return 0; - return -att; - } - if(target.hasSkillTag('nogain')) return 0.1; - if(att>0){ - return att+Math.max(0,5-target.countCards('h')); - } - return att; - }).set('du',event.card.name=='du'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target2=result.targets[0]; - target.line(target2,'green'); - target2.gain(target,card,'giveAuto').giver=player; - } - else event.finish(); - 'step 3' - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'是否对'+get.translation(player)+'使用一张杀?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); + content: function () { + "step 0"; + player.choosePlayerCard(target, "he", true).set("ai", get.buttonValue); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + player + .chooseTarget( + "将" + + get.translation(target) + + "的" + + (get.position(card) == "h" && + !player.hasSkillTag("viewHandcard", null, target, true) + ? "手牌" + : get.translation(card)) + + "交给一名角色", + true, + function (target) { + return target != _status.event.getParent().target; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0; + return -att; + } + if (target.hasSkillTag("nogain")) return 0.1; + if (att > 0) { + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }) + .set("du", event.card.name == "du"); + } else event.finish(); + "step 2"; + if (result.bool) { + var target2 = result.targets[0]; + target.line(target2, "green"); + target2.gain(target, card, "giveAuto").giver = player; + } else event.finish(); + "step 3"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "是否对" + get.translation(player) + "使用一张杀?") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); }, - ai:{ - order:6, - expose:0.2, - result:{ - target:-1.5, - player:function(player,target){ - if(!target.canUse('sha',player)) return 0; - if(target.countCards('h')==1) return 0.1; - if(player.hasShan()) return -0.5; - if(player.hp<=1) return -2; - if(player.hp<=2) return -1; + ai: { + order: 6, + expose: 0.2, + result: { + target: -1.5, + player: function (player, target) { + if (!target.canUse("sha", player)) return 0; + if (target.countCards("h") == 1) return 0.1; + if (player.hasShan()) return -0.5; + if (player.hp <= 1) return -2; + if (player.hp <= 2) return -1; return 0; - } - }, - }, - }, - //文和乱武 - nsyangwu:{ - enable:'phaseUse', - usable:1, - filterCard:{suit:'heart'}, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>player.countCards('h'); - }, - filter:function(event,player){ - var info=lib.skill.nsyangwu; - return player.countCards('h',info.filterCard)&&game.hasPlayer(function(target){ - return info.filterTarget(null,player,target); - }); - }, - check:function(card){ - var num=0; - var player=_status.event.player; - game.countPlayer(function(current){ - if(current!=player&&get.attitude(player,current)<0) num=Math.max(num,current.countCards('h')-player.countCards('h')); - }); - return Math.ceil((num+1)/2)*2+4-get.value(card); - }, - content:function(){ - var num=Math.ceil((target.countCards('h')-player.countCards('h'))/2); - if(num) player.gainPlayerCard(target,true,'h',num,'visible'); - }, - ai:{ - order:4, - result:{ - target:function(player,target){ - return player.countCards('h')-target.countCards('h'); }, }, }, }, - nslulve:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('e')>0&¤t.countCards('e')<=player.countCards('he'); + //文和乱武 + nsyangwu: { + enable: "phaseUse", + usable: 1, + filterCard: { suit: "heart" }, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > player.countCards("h"); + }, + filter: function (event, player) { + var info = lib.skill.nsyangwu; + return ( + player.countCards("h", info.filterCard) && + game.hasPlayer(function (target) { + return info.filterTarget(null, player, target); + }) + ); + }, + check: function (card) { + var num = 0; + var player = _status.event.player; + game.countPlayer(function (current) { + if (current != player && get.attitude(player, current) < 0) + num = Math.max(num, current.countCards("h") - player.countCards("h")); + }); + return Math.ceil((num + 1) / 2) * 2 + 4 - get.value(card); + }, + content: function () { + var num = Math.ceil((target.countCards("h") - player.countCards("h")) / 2); + if (num) player.gainPlayerCard(target, true, "h", num, "visible"); + }, + ai: { + order: 4, + result: { + target: function (player, target) { + return player.countCards("h") - target.countCards("h"); + }, + }, + }, + }, + nslulve: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current.countCards("e") > 0 && current.countCards("e") <= player.countCards("he") + ); }); }, - filterCard:function(){ - if(ui.selected.targets.length) return false; + filterCard: function () { + if (ui.selected.targets.length) return false; return true; }, - position:'he', - selectCard:[1,Infinity], - complexSelect:true, - complexCard:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('e')>0&&ui.selected.cards.length==target.countCards('e'); + position: "he", + selectCard: [1, Infinity], + complexSelect: true, + complexCard: true, + filterTarget: function (card, player, target) { + return ( + target != player && + target.countCards("e") > 0 && + ui.selected.cards.length == target.countCards("e") + ); }, - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e')>0&&ui.selected.cards.length==current.countCards('e')&&get.damageEffect(current,player,player)>0; - })) return 0; - switch(ui.selected.cards.length){ - case 0:return 8-get.value(card); - case 1:return 6-get.value(card); - case 2:return 3-get.value(card); - default:return 0; - } - }, - content:function(){ - target.damage('nocard'); - }, - ai:{ - damage:true, - order:2, - result:{ - target:function(player,target){ - return get.damageEffect(target,player); - } - }, - expose:0.3 - } - }, - nsfeixiong:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&&player.canCompare(current); - }); - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('nsfeixiong'),function(card,player,target){ - return player!=target&&player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player; - var hs=player.getCards('h').sort(function(a,b){ - return b.number-a.number; - }); - var ts=target.getCards('h').sort(function(a,b){ - return b.number-a.number; - }); - if(!hs.length||!ts.length) return 0; - if(hs[0].number>ts[0].number) return get.damageEffect(target,player,player); + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("e") > 0 && + ui.selected.cards.length == current.countCards("e") && + get.damageEffect(current, player, player) > 0 + ); + }) + ) return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('nsfeixiong',target); - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.2); - player.chooseToCompare(target); + switch (ui.selected.cards.length) { + case 0: + return 8 - get.value(card); + case 1: + return 6 - get.value(card); + case 2: + return 3 - get.value(card); + default: + return 0; } - else event.finish(); - 'step 2' - if(!result.tie){ - var targets=[player,target]; - if(result.bool) targets.reverse(); + }, + content: function () { + target.damage("nocard"); + }, + ai: { + damage: true, + order: 2, + result: { + target: function (player, target) { + return get.damageEffect(target, player); + }, + }, + expose: 0.3, + }, + }, + nsfeixiong: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && player.canCompare(current); + }) + ); + }, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("nsfeixiong"), function (card, player, target) { + return player != target && player.canCompare(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + var hs = player.getCards("h").sort(function (a, b) { + return b.number - a.number; + }); + var ts = target.getCards("h").sort(function (a, b) { + return b.number - a.number; + }); + if (!hs.length || !ts.length) return 0; + if (hs[0].number > ts[0].number) return get.damageEffect(target, player, player); + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("nsfeixiong", target); + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.2); + player.chooseToCompare(target); + } else event.finish(); + "step 2"; + if (!result.tie) { + var targets = [player, target]; + if (result.bool) targets.reverse(); targets[0].damage(targets[1]); } }, }, - nscesuan:{ - trigger:{player:'damageBegin3'}, - forced:true, - content:function(){ - 'step 0' + nscesuan: { + trigger: { player: "damageBegin3" }, + forced: true, + content: function () { + "step 0"; trigger.cancel(); - event.lose=player.loseMaxHp(); - 'step 1' - if(event.lose&&event.lose.loseHp) player.draw(); + event.lose = player.loseMaxHp(); + "step 1"; + if (event.lose && event.lose.loseHp) player.draw(); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + halfneg: true, + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (tag === "filterDamage" && arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, //S贾诩 - nsyice:{ - trigger:{ - player:'loseAfter', - global:['cardsDiscardAfter','loseAsyncAfter'], + nsyice: { + trigger: { + player: "loseAfter", + global: ["cardsDiscardAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - if(event.name!='cardsDiscard'){ - if(event.type!='discard') return false; - var evt=event.getl(player); - return evt.cards2&&evt.cards2.filterInD('d').length>0; - } - else{ - var evt=event.getParent(); - if(evt.name!='orderingDiscard'||!evt.relatedEvent||evt.relatedEvent.player!=player||!['useCard','respond'].includes(evt.relatedEvent.name)) return false; - return event.cards.filterInD('d').length>0; + filter: function (event, player) { + if (event.name != "cardsDiscard") { + if (event.type != "discard") return false; + var evt = event.getl(player); + return evt.cards2 && evt.cards2.filterInD("d").length > 0; + } else { + var evt = event.getParent(); + if ( + evt.name != "orderingDiscard" || + !evt.relatedEvent || + evt.relatedEvent.player != player || + !["useCard", "respond"].includes(evt.relatedEvent.name) + ) + return false; + return event.cards.filterInD("d").length > 0; } }, - forced:true, - content:function(){ - 'step 0' - var evt=trigger.getParent().relatedEvent; - if((trigger.name=='discard'&&!trigger.delay)||evt&&evt.name=='respond') game.delayx(); - 'step 1' + forced: true, + content: function () { + "step 0"; + var evt = trigger.getParent().relatedEvent; + if ((trigger.name == "discard" && !trigger.delay) || (evt && evt.name == "respond")) + game.delayx(); + "step 1"; var cards; - if(trigger.getl) cards=trigger.getl(player).cards2.filterInD('d'); - else cards=trigger.cards.filterInD('d'); - if(cards.length==1) event._result={bool:true,links:cards}; - else{ - var dialog=['遗策:选择要放置的卡牌','
              (从左到右为从旧到新,后选择的后置入)
              ',cards]; - var cards2=player.getExpansions('nsyice'); + if (trigger.getl) cards = trigger.getl(player).cards2.filterInD("d"); + else cards = trigger.cards.filterInD("d"); + if (cards.length == 1) event._result = { bool: true, links: cards }; + else { + var dialog = [ + "遗策:选择要放置的卡牌", + '
              (从左到右为从旧到新,后选择的后置入)
              ', + cards, + ]; + var cards2 = player.getExpansions("nsyice"); cards2.reverse(); - if(cards2.length){ + if (cards2.length) { dialog.push('
              原有“策”
              '); dialog.push(cards2); } - player.chooseButton(dialog,true,cards.length).set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards); + player + .chooseButton(dialog, true, cards.length) + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set("cards", cards); } - 'step 2' - player.addToExpansion(result.links,'gain2').gaintag.add('nsyice'); - 'step 3' - var storage=player.getExpansions('nsyice'); - var bool=false; - for(var i=0;ii;j--){ - if(get.number(storage[i])==get.number(storage[j])){ - bool=true; + "step 2"; + player.addToExpansion(result.links, "gain2").gaintag.add("nsyice"); + "step 3"; + var storage = player.getExpansions("nsyice"); + var bool = false; + for (var i = 0; i < storage.length; i++) { + for (var j = storage.length - 1; j > i; j--) { + if (get.number(storage[i]) == get.number(storage[j])) { + bool = true; break; } } - if(bool) break; + if (bool) break; } - if(bool){ - event.cards=storage.splice(i,j-i+1); - } - else event.finish(); - 'step 4' - var cardsx=[]; + if (bool) { + event.cards = storage.splice(i, j - i + 1); + } else event.finish(); + "step 4"; + var cardsx = []; cardsx.push(cards.shift()); cardsx.push(cards.pop()); - if(cards.length) player.gain(cards,'gain2'); - event.cards=cardsx; - 'step 5' - player.chooseButton(['将一张牌置于牌堆顶,将另一张牌置于牌堆底',cards],true); - 'step 6' - player.lose(event.cards,ui.cardPile).set('topper',result.links[0]).insert_index=function(event,card){ - if(card==event.topper) return ui.cardPile.firstChild; - return null; - }; - if(_status.dying.length) event.finish(); - 'step 7' - player.chooseTarget('对一名角色造成1点伤害',true).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); + if (cards.length) player.gain(cards, "gain2"); + event.cards = cardsx; + "step 5"; + player.chooseButton(["将一张牌置于牌堆顶,将另一张牌置于牌堆底", cards], true); + "step 6"; + player.lose(event.cards, ui.cardPile).set("topper", result.links[0]).insert_index = + function (event, card) { + if (card == event.topper) return ui.cardPile.firstChild; + return null; + }; + if (_status.dying.length) event.finish(); + "step 7"; + player.chooseTarget("对一名角色造成1点伤害", true).set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); }); - 'step 8' - if(result.bool){ - var target=result.targets[0]; + "step 8"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - target.damage('nocard'); + target.damage("nocard"); } }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'策', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "策", + intro: { + content: "expansion", + markcount: "expansion", }, }, //用间篇 - yjxuepin:{ - enable:'phaseUse', - usable:1, - filterTarget:function(event,player,target){ - return player.inRange(target)&&target.countDiscardableCards(player,'he')>0; + yjxuepin: { + enable: "phaseUse", + usable: 1, + filterTarget: function (event, player, target) { + return player.inRange(target) && target.countDiscardableCards(player, "he") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - 'step 1' - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,2,'he',true); + "step 1"; + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, 2, "he", true); else event.finish(); - 'step 2' - if(result.bool&&result.cards.length==2&&get.type2(result.cards[0],result.cards[0].original=='h'?target:false)==get.type2(result.cards[1],result.cards[1].original=='h'?target:false)) player.recover(); + "step 2"; + if ( + result.bool && + result.cards.length == 2 && + get.type2(result.cards[0], result.cards[0].original == "h" ? target : false) == + get.type2(result.cards[1], result.cards[1].original == "h" ? target : false) + ) + player.recover(); }, - ai:{ - order:4, - result:{ - player:function(player,target){ - if(player.hp==1) return -8; - if(target.countCards('e')>1) return 0; - if(player.hp>2||target.countCards('h')>1) return -0.5; + ai: { + order: 4, + result: { + player: function (player, target) { + if (player.hp == 1) return -8; + if (target.countCards("e") > 1) return 0; + if (player.hp > 2 || target.countCards("h") > 1) return -0.5; return -2; }, - target:function(player,target){ - if(target.countDiscardableCards(player,'he')<2) return 0; + target: function (player, target) { + if (target.countDiscardableCards(player, "he") < 2) return 0; return -2; }, }, }, }, - nsjianglie:{ - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('h')>0; + nsjianglie: { + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countCards("h") > 0; }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - logTarget:'target', - content:function(){ - 'step 0' + logTarget: "target", + content: function () { + "step 0"; trigger.target.showHandcards(); - 'step 1' - var cards=trigger.target.getCards('h'); - var list=[]; - for(var i=0;i=get.value(player.getCards('h',{color:'black'}))) return 'black'; - return 'red'; - }); + trigger.target + .chooseControl(list) + .set("prompt", "选择弃置一种颜色的所有手牌") + .set("ai", function () { + var player = _status.event.player; + if ( + get.value(player.getCards("h", { color: "red" })) >= + get.value(player.getCards("h", { color: "black" })) + ) + return "black"; + return "red"; + }); } - 'step 2' - trigger.target.discard(trigger.target.getCards('h',{color:result.control})); + "step 2"; + trigger.target.discard(trigger.target.getCards("h", { color: result.control })); }, }, //桌游志贴纸 - spyinzhi:{ - trigger:{player:'damageEnd'}, - frequent:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + spyinzhi: { + trigger: { player: "damageEnd" }, + frequent: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - var cards=game.cardsGotoOrdering(get.cards(2)).cards; + var cards = game.cardsGotoOrdering(get.cards(2)).cards; player.showCards(cards); - event.count2=0; - for(var i=0;i0){ - player.chooseTarget('令一名角色获得'+get.translation(trigger.source)+'的一张手牌',function(card,player,target){ - var source=_status.event.source; - return target!=source&&source.countGainableCards(target,'h')>0; - }).set('source',trigger.source); + if (trigger.source.countCards("h") > 0) { + player + .chooseTarget( + "令一名角色获得" + get.translation(trigger.source) + "的一张手牌", + function (card, player, target) { + var source = _status.event.source; + return target != source && source.countGainableCards(target, "h") > 0; + } + ) + .set("source", trigger.source); + } else event.goto(4); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line([trigger.source, target], "green"); + target.gainPlayerCard(trigger.source, "h", true); + if (event.count2) event.goto(2); } - else event.goto(4); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line([trigger.source,target],'green'); - target.gainPlayerCard(trigger.source,'h',true); - if(event.count2) event.goto(2) - } - 'step 4' - if(cards.length) player.gain(cards,'gain2','log'); - 'step 5' - if(event.count>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('spyinzhi')).set('frequentSkill',event.name); - } - else event.finish(); - 'step 6' - if(result.bool){ - player.logSkill('spyinzhi'); + "step 4"; + if (cards.length) player.gain(cards, "gain2", "log"); + "step 5"; + if ( + event.count > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("spyinzhi")).set("frequentSkill", event.name); + } else event.finish(); + "step 6"; + if (result.bool) { + player.logSkill("spyinzhi"); event.goto(1); } }, }, - spmingjian:{ - trigger:{global:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + spmingjian: { + trigger: { global: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var next=player.chooseCard(get.prompt2('spmingjian',trigger.player),'he'); - next.set('ai',function(card){ - var target=_status.event.getTrigger().player; - var player=_status.event.player; - if(get.attitude(player,target)>0&&target.countCards('j')>0) return 5-get.value(card); + content: function () { + "step 0"; + var next = player.chooseCard(get.prompt2("spmingjian", trigger.player), "he"); + next.set("ai", function (card) { + var target = _status.event.getTrigger().player; + var player = _status.event.player; + if (get.attitude(player, target) > 0 && target.countCards("j") > 0) + return 5 - get.value(card); return -1; }); - next.set('filterCard',function(card,player){ - if(get.position(card)=='e') return lib.filter.cardDiscardable.apply(this,arguments); + next.set("filterCard", function (card, player) { + if (get.position(card) == "e") + return lib.filter.cardDiscardable.apply(this, arguments); return true; }); //next.set('logSkill',['spmingjian',trigger.player]); - 'step 1' - if(result.bool){ - player.logSkill('spmingjian',trigger.player); - var card=result.cards[0]; - event.card=card; - if(get.position(card)=='e') event._result={index:0}; - else if(!lib.filter.cardDiscardable(card,player,event)) event._result={index:1}; - else{ - var name=get.translation(trigger.player); - player.chooseControl().set('choiceList',[ - '令'+name+'跳过本回合的判定阶段', - '令'+name+'于本回合的判定中不触发「判定结果生效前」的时机', - ]).set('ai',function(){return 0}); + "step 1"; + if (result.bool) { + player.logSkill("spmingjian", trigger.player); + var card = result.cards[0]; + event.card = card; + if (get.position(card) == "e") event._result = { index: 0 }; + else if (!lib.filter.cardDiscardable(card, player, event)) + event._result = { index: 1 }; + else { + var name = get.translation(trigger.player); + player + .chooseControl() + .set("choiceList", [ + "令" + name + "跳过本回合的判定阶段", + "令" + name + "于本回合的判定中不触发「判定结果生效前」的时机", + ]) + .set("ai", function () { + return 0; + }); } - } - else event.finish(); - 'step 2' - if(result.index==0){ + } else event.finish(); + "step 2"; + if (result.index == 0) { player.discard(card); - trigger.player.skip('phaseJudge'); - } - else{ - trigger.player.addToExpansion(card,player,'giveAuto').gaintag.add('spmingjian_charlotte'); - trigger.player.addSkill('spmingjian_charlotte'); + trigger.player.skip("phaseJudge"); + } else { + trigger.player + .addToExpansion(card, player, "giveAuto") + .gaintag.add("spmingjian_charlotte"); + trigger.player.addSkill("spmingjian_charlotte"); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - spmingjian_charlotte:{ - trigger:{player:['judgeBefore','phaseAfter']}, - forced:true, - firstDo:true, - silent:true, - popup:false, - charlotte:true, - content:function(){ - if(trigger.name=='phase') player.removeSkill(event.name); - else trigger.noJudgeTrigger=true; + spmingjian_charlotte: { + trigger: { player: ["judgeBefore", "phaseAfter"] }, + forced: true, + firstDo: true, + silent: true, + popup: false, + charlotte: true, + content: function () { + if (trigger.name == "phase") player.removeSkill(event.name); + else trigger.noJudgeTrigger = true; }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'鉴', - intro:{ - name:'明鉴', - content:'expansion', - markcount:'expansion', + marktext: "鉴", + intro: { + name: "明鉴", + content: "expansion", + markcount: "expansion", }, }, - spshude:{ - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - return player.countCards('h')2; - return get.suit(card)==get.suit(ui.selected.cards[0]); + complexCard: true, + filterCard: function (card, player) { + if (!ui.selected.cards.length) + return player.countCards("he", { suit: get.suit(card) }) > 2; + return get.suit(card) == get.suit(ui.selected.cards[0]); }, - content:function(){ + content: function () { target.turnOver(); - player.addTempSkill('spfuluan2'); + player.addTempSkill("spfuluan2"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.isTurnedOver()) return 2; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.isTurnedOver()) return 2; return -1; }, }, }, }, - spfuluan2:{ - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + spfuluan2: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, }, }, - spzhaoxin:{ - trigger:{player:'phaseDrawEnd'}, - check:function(event,player){ - return player.getUseValue({name:'sha',isCard:true})>0; + spzhaoxin: { + trigger: { player: "phaseDrawEnd" }, + check: function (event, player) { + return player.getUseValue({ name: "sha", isCard: true }) > 0; }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - player.chooseUseTarget('sha',false); + "step 1"; + player.chooseUseTarget("sha", false); }, }, - splanggu:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return get.itemtype(event.source)=='player'; + splanggu: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return get.itemtype(event.source) == "player"; }, - logTarget:'source', - content:function(){ - 'step 0' + logTarget: "source", + content: function () { + "step 0"; player.judge(); - 'step 1' - if(trigger.source.countCards('h')>0){ - var next=player.discardPlayerCard(trigger.source,'h',[1,Infinity]); - next.set('suit',result.suit); - next.set('filterButton',function(button){ - return get.suit(button.link)==_status.event.suit; + "step 1"; + if (trigger.source.countCards("h") > 0) { + var next = player.discardPlayerCard(trigger.source, "h", [1, Infinity]); + next.set("suit", result.suit); + next.set("filterButton", function (button) { + return get.suit(button.link) == _status.event.suit; }); - next.set('visible',true); + next.set("visible", true); } }, - group:'splanggu_rewrite', + group: "splanggu_rewrite", }, - splanggu_rewrite:{ - trigger:{player:'judge'}, - filter:function (event,player){ - return player.countCards('hs')>0&&event.getParent().name=='splanggu'; + splanggu_rewrite: { + trigger: { player: "judge" }, + filter: function (event, player) { + return player.countCards("hs") > 0 && event.getParent().name == "splanggu"; }, - direct:true, - content:function (){ - "step 0" - player.chooseCard('狼顾的判定结果为'+ - get.translation(trigger.player.judging[0])+',是否打出一张手牌进行代替?','hs',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - return -1; - }); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','splanggu','noOrdering'); - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + "狼顾的判定结果为" + + get.translation(trigger.player.judging[0]) + + ",是否打出一张手牌进行代替?", + "hs", + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + return -1; + }); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "splanggu", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, }, - sphantong:{ - trigger:{ - player:'loseEnd', + sphantong: { + trigger: { + player: "loseEnd", }, - frequent:true, - filter:function(event,player){ - return event.type=='discard'&&event.getParent(3).name=='phaseDiscard'&&event.cards.filterInD('d').length>0; + frequent: true, + filter: function (event, player) { + return ( + event.type == "discard" && + event.getParent(3).name == "phaseDiscard" && + event.cards.filterInD("d").length > 0 + ); }, - content:function(){ - if(!player.storage.sphantong) player.storage.sphantong=[]; - var cards=trigger.cards.filterInD('d'); + content: function () { + if (!player.storage.sphantong) player.storage.sphantong = []; + var cards = trigger.cards.filterInD("d"); player.storage.sphantong.addArray(cards); player.$gain2(cards); - game.log(player,'将',cards,'置于武将牌上'); - player.markSkill('sphantong'); + game.log(player, "将", cards, "置于武将牌上"); + player.markSkill("sphantong"); }, - group:['sphantong_gain'], - derivation:['hujia','jijiang','jiuyuan','xueyi'], - marktext:'诏', - intro:{ - content:'cards', - onunmark:'throw', + group: ["sphantong_gain"], + derivation: ["hujia", "jijiang", "jiuyuan", "xueyi"], + marktext: "诏", + intro: { + content: "cards", + onunmark: "throw", }, }, - sphantong_gain:{ - trigger:{global:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return player.storage.sphantong&&player.storage.sphantong.length>0; + sphantong_gain: { + trigger: { global: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.storage.sphantong && player.storage.sphantong.length > 0; }, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('sphantong'),player.storage.sphantong],function(button){ - var player=_status.event.player; - if(_status.currentPhase==player){ - //血裔 - if((player.hasJudge('lebu')||player.skipList.includes('phaseUse'))&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='qun'; - })) return 1; - //激将 - if(!player.hasJudge('lebu')&&!player.skipList.includes('phaseUse')&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'&¤t.hasSha()&&get.attitude(player,current)>0&&get.attitude(current,player)>0; - })&&game.hasPlayer(function(target){ - return player.canUse({name:'sha'},target)&&get.effect(target,{name:'sha'},player,player)>0; - })) return 1; + content: function () { + "step 0"; + player.chooseButton( + [get.prompt("sphantong"), player.storage.sphantong], + function (button) { + var player = _status.event.player; + if (_status.currentPhase == player) { + //血裔 + if ( + (player.hasJudge("lebu") || player.skipList.includes("phaseUse")) && + game.hasPlayer(function (current) { + return current != player && current.group == "qun"; + }) + ) + return 1; + //激将 + if ( + !player.hasJudge("lebu") && + !player.skipList.includes("phaseUse") && + game.hasPlayer(function (current) { + return ( + current != player && + current.group == "shu" && + current.hasSha() && + get.attitude(player, current) > 0 && + get.attitude(current, player) > 0 + ); + }) && + game.hasPlayer(function (target) { + return ( + player.canUse({ name: "sha" }, target) && + get.effect(target, { name: "sha" }, player, player) > 0 + ); + }) + ) + return 1; + } + //护驾 + else if ( + !player.hasShan() && + game.hasPlayer(function (current) { + return ( + current != player && + current.group == "wei" && + current.mayHaveShan(player, "respond") && + get.attitude(player, current) > 0 && + get.attitude(current, player) > 0 + ); + }) + ) + return 1; + return -1; } - //护驾 - else if(!player.hasShan()&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'&¤t.mayHaveShan(player,'respond')&&get.attitude(player,current)>0&&get.attitude(current,player)>0; - })) return 1; - return -1; - }); - 'step 1' - if(result.bool){ - player.logSkill('sphantong'); - var card=result.links[0]; + ); + "step 1"; + if (result.bool) { + player.logSkill("sphantong"); + var card = result.links[0]; player.$throw(card); - game.log(player,'将',card,'置入了弃牌堆'); + game.log(player, "将", card, "置入了弃牌堆"); player.storage.sphantong.remove(card); - player[player.storage.sphantong.length>0?'markSkill':'unmarkSkill']('sphantong'); + player[player.storage.sphantong.length > 0 ? "markSkill" : "unmarkSkill"]( + "sphantong" + ); game.cardsDiscard(card); - var list=['hujia','jijiang','jiuyuan','xueyi']; - for(var i=0;i0&&get.attitude(current,player)>0; - })&&game.hasPlayer(function(target){ - return player.canUse({name:'sha'},target)&&get.effect(target,{name:'sha'},player,player)>0; - })) return 'jijiang'; - } - //护驾 - else if(!player.hasShan()&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'&¤t.mayHaveShan(player,'respond')&&get.attitude(player,current)>0&&get.attitude(current,player)>0; - })) return 'hujia'; - }); - } - else event.finish(); - } - else event.finish(); - 'step 2' - var skill=result.control; + if (list.length) { + player + .chooseControl(list) + .set("prompt", "选择获得以下技能中的一个") + .set("ai", function () { + var player = _status.event.player; + if (_status.currentPhase == player) { + //血裔 + if ( + (player.hasJudge("lebu") || + player.skipList.includes("phaseUse")) && + game.hasPlayer(function (current) { + return current != player && current.group == "qun"; + }) + ) + return "xueyi"; + //激将 + if ( + !player.hasJudge("lebu") && + !player.skipList.includes("phaseUse") && + game.hasPlayer(function (current) { + return ( + current != player && + current.group == "shu" && + current.hasSha() && + get.attitude(player, current) > 0 && + get.attitude(current, player) > 0 + ); + }) && + game.hasPlayer(function (target) { + return ( + player.canUse({ name: "sha" }, target) && + get.effect(target, { name: "sha" }, player, player) > 0 + ); + }) + ) + return "jijiang"; + } + //护驾 + else if ( + !player.hasShan() && + game.hasPlayer(function (current) { + return ( + current != player && + current.group == "wei" && + current.mayHaveShan(player, "respond") && + get.attitude(player, current) > 0 && + get.attitude(current, player) > 0 + ); + }) + ) + return "hujia"; + }); + } else event.finish(); + } else event.finish(); + "step 2"; + var skill = result.control; player.addTempSkills(skill); // player.popup(skill,'wood'); // game.log(player,'获得了技能','#g【'+get.translation(skill)+'】'); }, }, - sphuangen:{ - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget) return false; - if(get.type(event.card)!='trick') return false; - if(get.info(event.card).multitarget) return false; - if(event.targets.length<2) return false; - return player.hp>0; + sphuangen: { + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget) return false; + if (get.type(event.card) != "trick") return false; + if (get.info(event.card).multitarget) return false; + if (event.targets.length < 2) return false; + return player.hp > 0; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('sphuangen'), - [1,Math.min(player.hp,trigger.targets.length)],function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return -get.effect(target,trigger.card,trigger.player,_status.event.player); - }).set('targets',trigger.targets); - "step 1" - if(result.bool){ - player.logSkill('sphuangen',result.targets); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("sphuangen"), + [1, Math.min(player.hp, trigger.targets.length)], + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + return -get.effect(target, trigger.card, trigger.player, _status.event.player); + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + player.logSkill("sphuangen", result.targets); trigger.excluded.addArray(result.targets); player.draw(); } }, }, - spyicong:{ - trigger:{player:'phaseDiscardEnd'}, - direct:true, - locked:false, - filter:function(event,player){ - return player.countCards('he')>0; + spyicong: { + trigger: { player: "phaseDiscardEnd" }, + direct: true, + locked: false, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('he',[1,player.countCards('he')],get.prompt2('spyicong')).set('ai',function(card){ - if(card.name=='du') return 10; - if(ui.selected.cards.length) return -1; - return 4-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('spyicong'); - player.addToExpansion(result.cards,player,'give').gaintag.add('spyicong'); + content: function () { + "step 0"; + player + .chooseCard("he", [1, player.countCards("he")], get.prompt2("spyicong")) + .set("ai", function (card) { + if (card.name == "du") return 10; + if (ui.selected.cards.length) return -1; + return 4 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("spyicong"); + player.addToExpansion(result.cards, player, "give").gaintag.add("spyicong"); } }, - mod:{ - globalTo:function(from,to,num){ - return num+to.getExpansions('spyicong').length; + mod: { + globalTo: function (from, to, num) { + return num + to.getExpansions("spyicong").length; }, }, - marktext:'扈', - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "扈", + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - name:'义从', - content:function(storage,player){ - return '共有'+get.cnNumber(player.getExpansions('spyicong').length)+'张“扈”'; + intro: { + name: "义从", + content: function (storage, player) { + return "共有" + get.cnNumber(player.getExpansions("spyicong").length) + "张“扈”"; }, - markcount:'expansion', + markcount: "expansion", }, }, - sptuji:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.getExpansions('spyicong').length>0; + sptuji: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return player.getExpansions("spyicong").length > 0; }, - content:function(){ - var cards=player.getExpansions('spyicong'); - var num=cards.length; - player.addMark('sptuji2',num,false); - player.addTempSkill('sptuji2'); + content: function () { + var cards = player.getExpansions("spyicong"); + var num = cards.length; + player.addMark("sptuji2", num, false); + player.addTempSkill("sptuji2"); player.loseToDiscardpile(cards); - if(num<=1) player.draw(); + if (num <= 1) player.draw(); + }, + ai: { + combo: "spyicong" }, }, - sptuji2:{ - onremove:true, - charlotte:true, - mod:{ - globalFrom:function(from,to,num){ - return num-from.countMark('sptuji2'); + sptuji2: { + onremove: true, + charlotte: true, + mod: { + globalFrom: function (from, to, num) { + return num - from.countMark("sptuji2"); }, }, - marktext:'突', - intro:{ - name:'突骑', - content:'至其他角色的距离-#', + marktext: "突", + intro: { + name: "突骑", + content: "至其他角色的距离-#", }, }, - xinfu_yanyu:{ - trigger:{ - global:"phaseUseBegin", + xinfu_yanyu: { + trigger: { + global: "phaseUseBegin", }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var next=player.chooseToDiscard(get.prompt('xinfu_yanyu'),get.translation('xinfu_yanyu_info'),'he').set('logSkill','xinfu_yanyu'); - if(player==trigger.player){ - next.set('goon',function(){ - var map={ - basic:0, - trick:0.1, - }; - var hs=trigger.player.getCards('h'); - var sha=false; - var jiu=false; - for(var i=0;i=3) return false; - var type=player.storage.xinfu_yanyu,cards=event.getd(); - for(var i=0;i= 3) return false; + var type = player.storage.xinfu_yanyu, + cards = event.getd(); + for (var i = 0; i < cards.length; i++) { + if (get.type(cards[i], "trick") == type && get.position(cards[i], true) == "d") + return true; } return false; }, - content:function(){ - 'step 0' - event.logged=false; - event.cards=[]; - var type=player.storage.xinfu_yanyu; - var cards=trigger.getd(); - for(var i=0;i=3) event.finish(); - else player.chooseCardButton(event.cards,'【燕语】:是否将其中的一张牌交给一名角色?').ai=function(card){ - if(card.name=='du') return 10; - return get.value(card); - }; - 'step 2' - if(result.bool){ + "step 1"; + if (player.storage.xinfu_yanyu2 >= 3) event.finish(); + else + player.chooseCardButton( + event.cards, + "【燕语】:是否将其中的一张牌交给一名角色?" + ).ai = function (card) { + if (card.name == "du") return 10; + return get.value(card); + }; + "step 2"; + if (result.bool) { player.storage.xinfu_yanyu2++; - if(!event.logged){ - player.logSkill('xinfu_yanyu'); + if (!event.logged) { + player.logSkill("xinfu_yanyu"); player.addExpose(0.25); - event.logged=true; + event.logged = true; } - event.togain=result.links[0]; + event.togain = result.links[0]; event.cards.remove(event.togain); - player.chooseTarget(true,'请选择要获得'+get.translation(event.togain)+'的角色').set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - var card=_status.event.card; - var val=get.value(card); - if(player.storage.xinfu_yanyu2<3&&target==_status.currentPhase&&target.hasValueTarget(card,null,true)) att=att*5; - else if(target==player&&!player.hasJudge('lebu')&&get.type(card)=='trick') att=att*3; - if(target.hasSkillTag('nogain')) att/=10; - return att*val; - }).set('card',event.togain); - } - else event.finish(); - 'step 3' - var target=result.targets[0]; - player.line(target,'green'); - target.gain(event.togain,'gain2'); - if(event.cards.length) event.goto(1); + player + .chooseTarget(true, "请选择要获得" + get.translation(event.togain) + "的角色") + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + var card = _status.event.card; + var val = get.value(card); + if ( + player.storage.xinfu_yanyu2 < 3 && + target == _status.currentPhase && + target.hasValueTarget(card, null, true) + ) + att = att * 5; + else if ( + target == player && + !player.hasJudge("lebu") && + get.type(card) == "trick" + ) + att = att * 3; + if (target.hasSkillTag("nogain")) att /= 10; + return att * val; + }) + .set("card", event.togain); + } else event.finish(); + "step 3"; + var target = result.targets[0]; + player.line(target, "green"); + target.gain(event.togain, "gain2"); + if (event.cards.length) event.goto(1); }, }, - "xinfu_xiaode":{ - subSkill:{ - remove:{ - unique:true, - charlotte:true, - trigger:{ - player:"phaseAfter", + xinfu_xiaode: { + subSkill: { + remove: { + unique: true, + charlotte: true, + trigger: { + player: "phaseAfter", }, - forced:true, - popup:false, - content:function(){ - player.removeAdditionalSkill('xinfu_xiaode'); - player.removeSkill('xinfu_xiaode_remove'); + forced: true, + popup: false, + content: function () { + player.removeAdditionalSkill("xinfu_xiaode"); + player.removeSkill("xinfu_xiaode_remove"); }, }, }, - trigger:{ - global:"dieAfter", + trigger: { + global: "dieAfter", }, - direct:true, - filter:function (skill,event){ - return !event.hasSkill('xinfu_xiaode_remove'); + direct: true, + filter: function (skill, event) { + return !event.hasSkill("xinfu_xiaode_remove"); }, - content:function (){ - 'step 0' - var list=[]; - var listm=[]; - var listv=[]; - if(trigger.player.name1!=undefined) listm=lib.character[trigger.player.name1][3]; - else listm=lib.character[trigger.player.name][3]; - if(trigger.player.name2!=undefined) listv=lib.character[trigger.player.name2][3]; - listm=listm.concat(listv); - var func=function(skill){ - var info=get.info(skill); - if(info.charlotte||info.zhuSkill||(info.unique&&!info.limited)||info.juexingji||info.dutySkill||info.hiddenSkill) return false; + content: function () { + "step 0"; + var list = []; + var listm = []; + var listv = []; + if (trigger.player.name1 != undefined) listm = lib.character[trigger.player.name1][3]; + else listm = lib.character[trigger.player.name][3]; + if (trigger.player.name2 != undefined) listv = lib.character[trigger.player.name2][3]; + listm = listm.concat(listv); + var func = function (skill) { + var info = get.info(skill); + if ( + info.charlotte || + info.zhuSkill || + (info.unique && !info.limited) || + info.juexingji || + info.dutySkill || + info.hiddenSkill + ) + return false; return true; }; - for(var i=0;i0; + filter: function (event, player) { + var hs = player.getCards("h"); + return ( + event.type != "xinmanjuan" && + event.getg(player).filter(function (card) { + return hs.includes(card); + }).length > 0 + ); }, - content:function(){ - "step 0" - var hs=player.getCards('h'),cards=trigger.getg(player).filter(function(card){ - return hs.includes(card); - }); - event.cards=cards; - event.rawCards=cards.slice(0); + content: function () { + "step 0"; + var hs = player.getCards("h"), + cards = trigger.getg(player).filter(function (card) { + return hs.includes(card); + }); + event.cards = cards; + event.rawCards = cards.slice(0); player.loseToDiscardpile(cards); - if(_status.currentPhase!=player) event.finish(); - "step 1" - event.card=event.cards.shift(); - event.togain=[]; - var number=get.number(event.card); - for(var i=0;imaxval){ - maxval=tempval; + if (cards.length) { + var maxval = 0; + for (var i = 0; i < cards.length; i++) { + var tempval = get.value(cards[i]); + if (tempval > maxval) { + maxval = tempval; } } - maxval+=cards.length-1; - var next=player.chooseToDiscard('he',{suit:suits}); - next.set('ai',function(card){ - return _status.event.maxval-get.value(card); + maxval += cards.length - 1; + var next = player.chooseToDiscard("he", { suit: suits }); + next.set("ai", function (card) { + return _status.event.maxval - get.value(card); }); - next.set('maxval',maxval); - next.set('dialog',[get.prompt(event.name),'hidden',cards]) - next.logSkill=event.name; - event.cards=cards; + next.set("maxval", maxval); + next.set("dialog", [get.prompt(event.name), "hidden", cards]); + next.logSkill = event.name; + event.cards = cards; } - "step 2" - if(result.bool){ - player.gain(event.cards,'gain2','log'); + "step 2"; + if (result.bool) { + player.gain(event.cards, "gain2", "log"); } }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - zuixiang:{ - skillAnimation:true, - animationColor:'gray', - audio:true, - unique:true, - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - content:function(){ - 'step 0' - player.awakenSkill('zuixiang'); - event.cards=player.showCards(get.cards(3)).cards; - player.addToExpansion(event.cards,'gain2').gaintag.add('zuixiang2'); - 'step 1' - if(lib.skill.zuixiang.filterSame(cards)){ - player.gain(cards,'gain2').type='xinmanjuan'; - } - else{ - trigger._zuixiang=true; - player.addSkill('zuixiang2'); + zuixiang: { + skillAnimation: true, + animationColor: "gray", + audio: true, + unique: true, + limited: true, + trigger: { player: "phaseZhunbeiBegin" }, + content: function () { + "step 0"; + player.awakenSkill("zuixiang"); + event.cards = player.showCards(get.cards(3)).cards; + player.addToExpansion(event.cards, "gain2").gaintag.add("zuixiang2"); + "step 1"; + if (lib.skill.zuixiang.filterSame(cards)) { + player.gain(cards, "gain2").type = "xinmanjuan"; + } else { + trigger._zuixiang = true; + player.addSkill("zuixiang2"); } }, - filterSame:function(c){ - for(var i=0;i0; + position: "he", + filter: function (event, player) { + return player.countCards("he", { suit: "diamond" }) > 0; }, - discard:false, - lose:false, - delay:false, - prepare:'give', - content:function(){ - 'step 0' - game.addGlobalSkill('yanxiao_global'); - target.addJudge({name:'yanxiao_card'},cards); - 'step 1' + discard: false, + lose: false, + delay: false, + prepare: "give", + content: function () { + "step 0"; + game.addGlobalSkill("yanxiao_global"); + target.addJudge({ name: "yanxiao_card" }, cards); + "step 1"; game.delay(); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(target.countCards('j',function(card){ - return get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },target,target)<0; - })) return 1; + ai: { + order: 8, + result: { + target: function (player, target) { + if ( + target.countCards("j", function (card) { + return ( + get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + target, + target + ) < 0 + ); + }) + ) + return 1; return 0; - } - } - } - }, - yanxiao_global:{ - trigger:{player:'phaseJudgeBegin'}, - forced:true, - filter:function(event,player){ - return player.countCards('j')>0&&player.hasJudge('yanxiao_card'); - }, - content:function(){ - player.gain(player.getCards('j'),'gain2'); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.type(card)=='delay'&&target.hasJudge('yanxiao_card')) return [0,0,0,0.1]; - } - } - } - }, - anxian:{ - audio:2, - group:['anxian_source','anxian_target'], - subSkill:{ - source:{ - audio:"anxian", - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; }, - check:function(event,player){ - if(get.damageEffect(event.player,player,player)<=0) return true; + }, + }, + }, + yanxiao_global: { + trigger: { player: "phaseJudgeBegin" }, + forced: true, + filter: function (event, player) { + return player.countCards("j") > 0 && player.hasJudge("yanxiao_card"); + }, + content: function () { + player.gain(player.getCards("j"), "gain2"); + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.type(card) == "delay" && target.hasJudge("yanxiao_card")) + return [0, 0, 0, 0.1]; + }, + }, + }, + }, + anxian: { + audio: 2, + group: ["anxian_source", "anxian_target"], + subSkill: { + source: { + audio: "anxian", + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return event.card && event.card.name == "sha"; + }, + check: function (event, player) { + if (get.damageEffect(event.player, player, player) <= 0) return true; return false; }, - content:function(){ - 'step 0' - if(trigger.player.countCards('h')){ + content: function () { + "step 0"; + if (trigger.player.countCards("h")) { trigger.player.chooseToDiscard(true); } - 'step 1' + "step 1"; player.draw(); trigger.cancel(); - } - }, - target:{ - audio:"anxian", - trigger:{target:'useCardToTargeted'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countCards('h'); }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt2('anxian')); - next.set('ai',function(card){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - if(get.attitude(player,trigger.player)>0){ - return 9-get.value(card); + }, + target: { + audio: "anxian", + trigger: { target: "useCardToTargeted" }, + direct: true, + filter: function (event, player) { + return event.card.name == "sha" && player.countCards("h"); + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt2("anxian")); + next.set("ai", function (card) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + if (get.attitude(player, trigger.player) > 0) { + return 9 - get.value(card); } - if(player.countCards('h',{name:'shan'})) return -1; - return 7-get.value(card); + if (player.countCards("h", { name: "shan" })) return -1; + return 7 - get.value(card); }); - next.logSkill='anxian'; - "step 1" - if(result.bool){ + next.logSkill = "anxian"; + "step 1"; + if (result.bool) { trigger.player.draw(); trigger.getParent().excluded.push(player); } }, - } - } - }, - junwei:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('yinling').length>=3; + }, }, - content:function(){ - 'step 0' - var cards=player.getExpansions('yinling'); - if(cards.length>3){ - player.chooseButton(3,[get.prompt('junwei'),'hidden',cards]).set('ai',function(button){ - return 1; - }); - } - else{ - player.chooseBool().set('createDialog',[get.prompt('junwei'),'hidden',cards]).set('dialogselectx',true).set('choice',true); - event.cards=cards.slice(0); - } - 'step 1' - if(result.bool){ - player.logSkill('junwei'); - var cards=event.cards||result.links; - player.loseToDiscardpile(cards); - player.chooseTarget(true,function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)/Math.sqrt(1+target.hp); - }); - } - else{ - event.finish(); - } - 'step 2' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(result.targets); - event.target=target; - var nshan=target.countCards('h',function(card){ - if(_status.connectMode) return true; - return card.name=='shan'; - }); - if(nshan==0){ - event.directfalse=true; - } - else{ - target.chooseCard('交给'+get.translation(player)+'一张【闪】,或失去1点体力',function(card){ - return card.name=='shan'; - }).set('ai',function(card){ - if(_status.event.nshan>1) return 1; - if(_status.event.player.hp>=3) return 0; + }, + junwei: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.getExpansions("yinling").length >= 3; + }, + content: function () { + "step 0"; + var cards = player.getExpansions("yinling"); + if (cards.length > 3) { + player + .chooseButton(3, [get.prompt("junwei"), "hidden", cards]) + .set("ai", function (button) { return 1; - }).set('nshan',nshan); - } + }); + } else { + player + .chooseBool() + .set("createDialog", [get.prompt("junwei"), "hidden", cards]) + .set("dialogselectx", true) + .set("choice", true); + event.cards = cards.slice(0); } - else{ + "step 1"; + if (result.bool) { + player.logSkill("junwei"); + var cards = event.cards || result.links; + player.loseToDiscardpile(cards); + player + .chooseTarget(true, function (card, player, target) { + return player != target; + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) / Math.sqrt(1 + target.hp); + }); + } else { event.finish(); } - 'step 3' - if(!event.directfalse&&result.bool) game.delay(); - ui.clear(); - 'step 4' - if(!event.directfalse&&result.bool){ - event.cards=result.cards; - event.target.$throw(result.cards); - player.chooseTarget('将'+get.translation(event.cards)+'交给一名角色',true,function(card,player,target){ - return target!=_status.event.getParent().target; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)/(target.countCards('h','shan')+1); + "step 2"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(result.targets); + event.target = target; + var nshan = target.countCards("h", function (card) { + if (_status.connectMode) return true; + return card.name == "shan"; }); + if (nshan == 0) { + event.directfalse = true; + } else { + target + .chooseCard( + "交给" + get.translation(player) + "一张【闪】,或失去1点体力", + function (card) { + return card.name == "shan"; + } + ) + .set("ai", function (card) { + if (_status.event.nshan > 1) return 1; + if (_status.event.player.hp >= 3) return 0; + return 1; + }) + .set("nshan", nshan); + } + } else { + event.finish(); } - else{ + "step 3"; + if (!event.directfalse && result.bool) game.delay(); + ui.clear(); + "step 4"; + if (!event.directfalse && result.bool) { + event.cards = result.cards; + event.target.$throw(result.cards); + player + .chooseTarget( + "将" + get.translation(event.cards) + "交给一名角色", + true, + function (card, player, target) { + return target != _status.event.getParent().target; + } + ) + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) / + (target.countCards("h", "shan") + 1) + ); + }); + } else { event.target.loseHp(); delete event.cards; } - 'step 5' - if(event.cards){ - player.line(result.targets,'green'); - result.targets[0].gain(event.cards,'gain2').giver=player; - game.log(player,'将',event.cards,'交给',result.targets[0]); + "step 5"; + if (event.cards) { + player.line(result.targets, "green"); + result.targets[0].gain(event.cards, "gain2").giver = player; + game.log(player, "将", event.cards, "交给", result.targets[0]); event.finish(); - } - else{ - if(event.target.countCards('e')){ - player.choosePlayerCard('e','将'+get.translation(event.target)+'的一张装备牌移出游戏',true,event.target); - } - else{ + } else { + if (event.target.countCards("e")) { + player.choosePlayerCard( + "e", + "将" + get.translation(event.target) + "的一张装备牌移出游戏", + true, + event.target + ); + } else { event.finish(); } } - 'step 6' - if(result.bool){ - var card=result.links[0]; - target.addToExpansion(card,target,'give').gaintag.add('junwei2'); - target.addSkill('junwei2'); + "step 6"; + if (result.bool) { + var card = result.links[0]; + target.addToExpansion(card, target, "give").gaintag.add("junwei2"); + target.addSkill("junwei2"); } - } + }, + ai: { + combo: "yinling", + }, }, - junwei2:{ - mark:true, - intro:{ - content:'expansion', - markcount:'expansion', + junwei2: { + mark: true, + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - charlotte:true, - content:function(){ - 'step 0' - var cards=player.getExpansions('junwei2').filter(function(card){ - return player.canEquip(card,true); + trigger: { player: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + content: function () { + "step 0"; + var cards = player.getExpansions("junwei2").filter(function (card) { + return player.canEquip(card, true); }); - if(cards.length){ - player.$give(cards[0],player,false); + if (cards.length) { + player.$give(cards[0], player, false); game.delay(0.5); player.equip(cards[0]); event.redo(); } - 'step 1' - player.removeSkill('junwei2'); - } + "step 1"; + player.removeSkill("junwei2"); + }, }, - yinling:{ - enable:'phaseUse', - filterCard:{color:'black'}, - position:'he', - marktext:'锦', - intro:{ - content:'expansion', - markcount:'expansion' + yinling: { + enable: "phaseUse", + filterCard: { color: "black" }, + position: "he", + marktext: "锦", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - filter:function(event,player){ - return player.countCards('he',{color:'black'})>0&&player.getExpansions('yinling').length<4; + filter: function (event, player) { + return ( + player.countCards("he", { color: "black" }) > 0 && + player.getExpansions("yinling").length < 4 + ); }, - filterTarget:function(card,player,target){ - return target.countCards('he')>0&&target!=player; + filterTarget: function (card, player, target) { + return target.countCards("he") > 0 && target != player; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' - player.choosePlayerCard('hej',target,true); - 'step 1' - if(result.bool&&result.links&&result.links.length){ - player.addToExpansion(result.links,target,'give').gaintag.add('yinling'); + content: function () { + "step 0"; + player.choosePlayerCard("hej", target, true); + "step 1"; + if (result.bool && result.links && result.links.length) { + player.addToExpansion(result.links, target, "give").gaintag.add("yinling"); } }, - ai:{ - order:10.1, - expose:0.1, - result:{ - target:function(player,target){ - if(target.hasSkill('tuntian')) return 0; - var es=target.getCards('e'); - var nh=target.countCards('h'); - var noe=(es.length==0||target.hasSkillTag('noe')); - var noe2=(es.length==1&&es[0].name=='baiyin'&&target.hp=0){ + ai: { + order: 10.1, + expose: 0.1, + result: { + target: function (player, target) { + if (target.hasSkill("tuntian")) return 0; + var es = target.getCards("e"); + var nh = target.countCards("h"); + var noe = es.length == 0 || target.hasSkillTag("noe"); + var noe2 = es.length == 1 && es[0].name == "baiyin" && target.hp < target.maxHp; + var noh = nh == 0 || target.hasSkillTag("noh"); + if (noh && noe) return 0; + if (noh && noe2) return 0.01; + if (get.attitude(player, target) <= 0) + return target.countCards("he") ? -1.5 : 1.5; + var js = target.getCards("j"); + if (js.length) { + var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0]; + if (jj.name == "guohe") return 3; + if (js.length == 1 && get.effect(target, jj, target, player) >= 0) { return -1.5; } return 2; @@ -5823,1004 +7823,1167 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return -1.5; }, }, - } - }, - fenyong:{ - audio:2, - trigger:{player:'damageEnd'}, - content:function(){ - player.addTempSkill('fenyong2'); - } - }, - fenyong2:{ - audio:'fenyong', - mark:true, - intro:{ - content:'防止你受到的所有伤害' }, - trigger:{player:'damageBegin3'}, - forced:true, - content:function(){ + }, + fenyong: { + audio: 2, + trigger: { player: "damageEnd" }, + content: function () { + player.addTempSkill("fenyong2"); + }, + }, + fenyong2: { + audio: "fenyong", + mark: true, + intro: { + content: "防止你受到的所有伤害", + }, + trigger: { player: "damageBegin3" }, + forced: true, + content: function () { trigger.cancel(); }, - ai:{ - maixie:true, - maixie_hp:true, - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')) return [0,0]; - } + ai: { + maixie: true, + maixie_hp: true, + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) return [0, 0]; + }, }, - } - }, - xuehen:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.hasSkill('fenyong2')&&event.player.isIn(); }, - content:function(){ - 'step 0' - player.removeSkill('fenyong2'); - player.chooseControl('弃牌','出杀',function(){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - if(get.attitude(player,trigger.player)<0){ - var he=trigger.player.countCards('he'); - if(he<2) return '出杀'; - if(player.maxHp-player.hp>=2&&he<=3){ - return '弃牌'; - } - if(player.maxHp-player.hp>=3&&he<=5){ - return '弃牌'; - } - if(player.maxHp-player.hp>3){ - return '弃牌'; - } - return '出杀'; - } - return '出杀'; - }).set('prompt','弃置'+get.translation(trigger.player)+get.cnNumber(player.maxHp-player.hp)+'张牌,或对任意一名角色使用一张杀'); - 'step 1' - if(result.control=='弃牌'){ - player.line(trigger.player,'green'); - if(player.hp= 2 && he <= 3) { + return "弃牌"; + } + if (player.maxHp - player.hp >= 3 && he <= 5) { + return "弃牌"; + } + if (player.maxHp - player.hp > 3) { + return "弃牌"; + } + return "出杀"; + } + return "出杀"; + }) + .set( + "prompt", + "弃置" + + get.translation(trigger.player) + + get.cnNumber(player.maxHp - player.hp) + + "张牌,或对任意一名角色使用一张杀" + ); + "step 1"; + if (result.control == "弃牌") { + player.line(trigger.player, "green"); + if (player.hp < player.maxHp && trigger.player.countCards("he")) { + player.discardPlayerCard(trigger.player, true, "he", player.maxHp - player.hp); + } + } else { + player.chooseUseTarget({ name: "sha" }, true, false, "nodistance"); + } + }, + ai: { + combo: "fenyong", + }, + }, + mouduan: { + audio: 1, + init2: function (player) { + game.broadcastAll(function (player) { + player._mouduan_mark = player.mark("武", { + content: "拥有技能【激昂】、【谦逊】", }); - },player); - player.addAdditionalSkill('mouduan',['jiang','qianxun']); + }, player); + player.addAdditionalSkill("mouduan", ["jiang", "qianxun"]); }, - onremove:function(player){ - game.broadcastAll(function(player){ - if(player._mouduan_mark){ + onremove: function (player) { + game.broadcastAll(function (player) { + if (player._mouduan_mark) { player._mouduan_mark.delete(); delete player._mouduan_mark; } - },player); - player.removeAdditionalSkills('mouduan'); + }, player); + player.removeAdditionalSkills("mouduan"); }, - trigger:{player:'loseEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - return player._mouduan_mark&&player._mouduan_mark.name=='武'&&player.countCards('h')<=2; + trigger: { player: "loseEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player._mouduan_mark && + player._mouduan_mark.name == "武" && + player.countCards("h") <= 2 + ); }, - content:function(){ - game.broadcastAll(function(player){ - if(!player._mouduan_mark) return; - player._mouduan_mark.name='文'; - player._mouduan_mark.skill='文'; - player._mouduan_mark.firstChild.innerHTML='文'; - player._mouduan_mark.info.content='拥有技能【英姿】、【克己】'; - },player); - player.addAdditionalSkills('mouduan',['yingzi','keji']); + content: function () { + game.broadcastAll(function (player) { + if (!player._mouduan_mark) return; + player._mouduan_mark.name = "文"; + player._mouduan_mark.skill = "文"; + player._mouduan_mark.firstChild.innerHTML = "文"; + player._mouduan_mark.info.content = "拥有技能【英姿】、【克己】"; + }, player); + player.addAdditionalSkills("mouduan", ["yingzi", "keji"]); }, - group:'mouduan2' + group: "mouduan2", }, - mouduan2:{ - audio:1, - trigger:{global:'phaseZhunbeiBegin'}, + mouduan2: { + audio: 1, + trigger: { global: "phaseZhunbeiBegin" }, //priority:5, - filter:function(event,player){ - return player._mouduan_mark&&player._mouduan_mark.name=='文'&&player.countCards('h')>2; + filter: function (event, player) { + return ( + player._mouduan_mark && + player._mouduan_mark.name == "文" && + player.countCards("h") > 2 + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard('he','谋断:是否弃置一张牌将标记变为“武”?').ai=function(){ + direct: true, + content: function () { + "step 0"; + player.chooseToDiscard("he", "谋断:是否弃置一张牌将标记变为“武”?").ai = function () { return -1; + }; + "step 1"; + if (result.bool && player.countCards("h") > 2) { + game.broadcastAll(function (player) { + if (!player._mouduan_mark) return; + player._mouduan_mark.name = "武"; + player._mouduan_mark.skill = "武"; + player._mouduan_mark.firstChild.innerHTML = "武"; + player._mouduan_mark.info.content = "拥有技能【激昂】、【谦逊】"; + }, player); + player.addAdditionalSkills("mouduan", ["jiang", "qianxun"]); } - 'step 1' - if(result.bool&&player.countCards('h')>2){ - game.broadcastAll(function(player){ - if(!player._mouduan_mark) return; - player._mouduan_mark.name='武'; - player._mouduan_mark.skill='武'; - player._mouduan_mark.firstChild.innerHTML='武'; - player._mouduan_mark.info.content='拥有技能【激昂】、【谦逊】'; - },player); - player.addAdditionalSkills('mouduan',['jiang','qianxun']); - } - } + }, }, - tanhu:{ - audio:1, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + tanhu: { + audio: 1, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - target.addTempSkill('tanhu2'); + "step 1"; + if (result.bool) { + target.addTempSkill("tanhu2"); } }, - ai:{ - result:{ - target:function(player,target){ - var hs=player.getCards('h'); - if(hs.length<3) return 0; - var bool=false; - for(var i=0;i=9&&get.value(hs[i])<7){ - bool=true; + ai: { + result: { + target: function (player, target) { + var hs = player.getCards("h"); + if (hs.length < 3) return 0; + var bool = false; + for (var i = 0; i < hs.length; i++) { + if (hs[i].number >= 9 && get.value(hs[i]) < 7) { + bool = true; break; } } - if(!bool) return 0; + if (!bool) return 0; return -1; - } + }, }, - order:9, + order: 9, }, - group:'tanhu3' + group: "tanhu3", }, - tanhu2:{ - mark:true, - intro:{ - content:'已成为探虎目标' - } + tanhu2: { + mark: true, + intro: { + content: "已成为探虎目标", + }, }, - tanhu3:{ - mod:{ - globalFrom:function(from,to){ - if(to.hasSkill('tanhu2')) return -Infinity; + tanhu3: { + mod: { + globalFrom: function (from, to) { + if (to.hasSkill("tanhu2")) return -Infinity; + }, + wuxieRespondable: function (card, player, target) { + if (target && target.hasSkill("tanhu2")) return false; }, - wuxieRespondable:function(card,player,target){ - if(target&&target.hasSkill('tanhu2')) return false; - } - } - }, - jie:{ - audio:1, - trigger:{source:'damageBegin1'}, - filter:function(event){ - return event.card&&event.card.name=='sha'&&get.color(event.card)=='red'&&event.notLink(); }, - forced:true, - content:function(){ + }, + jie: { + audio: 1, + trigger: { source: "damageBegin1" }, + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + get.color(event.card) == "red" && + event.notLink() + ); + }, + forced: true, + content: function () { trigger.num++; - } + }, }, - dahe:{ - audio:true, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + dahe: { + audio: true, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.chooseToCompare(target).set('preserve','win'); - 'step 1' - if(result.bool&&result.target){ - event.type=true; - event.card=result.target; - player.chooseTarget('将'+get.translation(result.target)+'交给一名角色',function(card,player,target){ - return target.hp<=player.hp; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.du) return -att; - return att; - }).set('du',event.card.name=='du'); - target.addTempSkill('dahe2'); - } - else{ - event.type=false; - if(player.countCards('h')){ + content: function () { + "step 0"; + player.chooseToCompare(target).set("preserve", "win"); + "step 1"; + if (result.bool && result.target) { + event.type = true; + event.card = result.target; + player + .chooseTarget( + "将" + get.translation(result.target) + "交给一名角色", + function (card, player, target) { + return target.hp <= player.hp; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) return -att; + return att; + }) + .set("du", event.card.name == "du"); + target.addTempSkill("dahe2"); + } else { + event.type = false; + if (player.countCards("h")) { player.showHandcards(); - player.chooseToDiscard('h',true); + player.chooseToDiscard("h", true); } } - 'step 2' - if(event.type){ - if(result.bool){ - player.line(result.targets,'green'); - result.targets[0].gain(event.card,'gain2'); + "step 2"; + if (event.type) { + if (result.bool) { + player.line(result.targets, "green"); + result.targets[0].gain(event.card, "gain2"); } } }, - ai:{ - result:{ - target:function(player,target){ - var hs=player.getCards('h'); - if(hs.length<3) return 0; - var bool=false; - for(var i=0;i=9&&get.value(hs[i])<7){ - bool=true; + ai: { + result: { + target: function (player, target) { + var hs = player.getCards("h"); + if (hs.length < 3) return 0; + var bool = false; + for (var i = 0; i < hs.length; i++) { + if (hs[i].number >= 9 && get.value(hs[i]) < 7) { + bool = true; break; } } - if(!bool) return 0; - if(player.canUse('sha',target)&&(player.countCards('h','sha'))){ + if (!bool) return 0; + if (player.canUse("sha", target) && player.countCards("h", "sha")) { return -2; } return -0.5; - } + }, }, - order:9, - } - }, - dahe2:{ - mark:true, - intro:{ - content:'非红桃闪无效' + order: 9, }, - mod:{ - cardRespondable:function(card,player){ - if(card.name=='shan'){ - const suit=get.suit(card); - if(suit!='heart'&&suit!='unsure') return false; - } - }, - cardEnabled:function(card,player){ - if(card.name=='shan'){ - const suit=get.suit(card); - if(suit!='heart'&&suit!='unsure') return false; - } - }, - } }, - shichou:{ + dahe2: { + mark: true, + intro: { + content: "非红桃闪无效", + }, + mod: { + cardRespondable: function (card, player) { + if (card.name == "shan") { + const suit = get.suit(card); + if (suit != "heart" && suit != "unsure") return false; + } + }, + cardEnabled: function (card, player) { + if (card.name == "shan") { + const suit = get.suit(card); + if (suit != "heart" && suit != "unsure") return false; + } + }, + }, + }, + shichou: { //audio:1, - skillAnimation:true, - animationColor:'orange', - unique:true, - limited:true, - mark:false, - trigger:{player:'phaseZhunbeiBegin'}, - zhuSkill:true, - direct:true, - filter:function(event,player){ - if(!player.hasZhuSkill('shichou'))return false; - if(player.countCards('he')<2) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'; + skillAnimation: true, + animationColor: "orange", + unique: true, + limited: true, + mark: false, + trigger: { player: "phaseZhunbeiBegin" }, + zhuSkill: true, + direct: true, + filter: function (event, player) { + if (!player.hasZhuSkill("shichou")) return false; + if (player.countCards("he") < 2) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "shu"; }); }, - init:function(player){ - if(player.hasZhuSkill('shichou')){ - player.markSkill('shichou'); - player.storage.shichou=false; + init: function (player) { + if (player.hasZhuSkill("shichou")) { + player.markSkill("shichou"); + player.storage.shichou = false; } }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt2('shichou'), - selectCard:2, - filterTarget:function(card,player,target){ - return target.group=='shu'&&target!=player; + prompt: get.prompt2("shichou"), + selectCard: 2, + filterTarget: function (card, player, target) { + return target.group == "shu" && target != player; }, - filterCard:true, - position:'he', - ai1:function(card){ - return 7-get.value(card); + filterCard: true, + position: "he", + ai1: function (card) { + return 7 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player; - if(player.hasUnknown()) return 0; - var att=get.attitude(player,target); - if(att<=0){ - if(target.hp==1) return (10-att)/2; - return 10-att; - } - else{ - if(target.hp==1) return 0; - return (10-att)/4; + ai2: function (target) { + var player = _status.event.player; + if (player.hasUnknown()) return 0; + var att = get.attitude(player, target); + if (att <= 0) { + if (target.hp == 1) return (10 - att) / 2; + return 10 - att; + } else { + if (target.hp == 1) return 0; + return (10 - att) / 4; } }, }); - "step 1" - if(!result.bool) return; - var target=result.targets[0]; - var cards=result.cards; - player.storage.shichou=true; - player.logSkill('shichou',target); - player.awakenSkill('shichou'); - player.give(cards,target); - player.storage.shichou_target=target; - player.addSkill('shichou2'); - target.markSkillCharacter('shichou',player,'誓仇','代替'+get.translation(player)+'承受伤害直到首次进入濒死状态'); + "step 1"; + if (!result.bool) return; + var target = result.targets[0]; + var cards = result.cards; + player.storage.shichou = true; + player.logSkill("shichou", target); + player.awakenSkill("shichou"); + player.give(cards, target); + player.storage.shichou_target = target; + player.addSkill("shichou2"); + target.markSkillCharacter( + "shichou", + player, + "誓仇", + "代替" + get.translation(player) + "承受伤害直到首次进入濒死状态" + ); }, - intro:{ - content:'limited' + intro: { + content: "limited", }, }, - shichou2:{ - group:'shichou3', - trigger:{player:'damageBegin3'}, - forced:true, - popup:false, - content:function(){ - trigger.player=player.storage.shichou_target; - trigger.shichou4=true; - trigger.player.addSkill('shichou4'); - player.logSkill('shichou2',player.storage.shichou_target); + shichou2: { + group: "shichou3", + trigger: { player: "damageBegin3" }, + forced: true, + popup: false, + content: function () { + trigger.player = player.storage.shichou_target; + trigger.shichou4 = true; + trigger.player.addSkill("shichou4"); + player.logSkill("shichou2", player.storage.shichou_target); game.delay(0.5); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(get.attitude(player,target)>0) return [0,0]; - var eff=get.damageEffect(target.storage.shichou_target,player,target); - if(eff>0){ - return [0,1]; - } - else if(eff<0){ - return [0,-2]; - } - else{ - return [0,0]; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (get.attitude(player, target) > 0) return [0, 0]; + var eff = get.damageEffect(target.storage.shichou_target, player, target); + if (eff > 0) { + return [0, 1]; + } else if (eff < 0) { + return [0, -2]; + } else { + return [0, 0]; } } - } - } - } - }, - shichou3:{ - trigger:{global:['dying','dieBegin']}, - forced:true, - popup:false, - //priority:10, - filter:function(event,player){ - return event.player==player.storage.shichou_target; + }, + }, }, - content:function(){ - trigger.player.unmarkSkill('shichou'); - delete player.storage.shichou_target; - player.removeSkill('shichou2'); - } }, - shichou4:{ - trigger:{player:['damageAfter','damageCancelled']}, - forced:true, - popup:false, - audio:false, - content:function(){ - if(!trigger.shichou4) return; - if(event.triggername=='damageAfter'&&trigger.num){ + shichou3: { + trigger: { global: ["dying", "dieBegin"] }, + forced: true, + popup: false, + //priority:10, + filter: function (event, player) { + return event.player == player.storage.shichou_target; + }, + content: function () { + trigger.player.unmarkSkill("shichou"); + delete player.storage.shichou_target; + player.removeSkill("shichou2"); + }, + }, + shichou4: { + trigger: { player: ["damageAfter", "damageCancelled"] }, + forced: true, + popup: false, + audio: false, + content: function () { + if (!trigger.shichou4) return; + if (event.triggername == "damageAfter" && trigger.num) { player.draw(trigger.num); } - player.removeSkill('shichou4'); - } + player.removeSkill("shichou4"); + }, }, - zhaolie:{ - trigger:{player:'phaseDrawBegin2'}, - direct:true, - filter:function(event,player){ + zhaolie: { + trigger: { player: "phaseDrawBegin2" }, + direct: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('zhaolie'),function(card,player,target){ - return target!=player&&player.inRange(target); - }).set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0) return 0; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("zhaolie"), function (card, player, target) { + return target != player && player.inRange(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) return 0; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { trigger.num--; - player.storage.zhaolie=result.targets[0]; - player.logSkill('zhaolie',result.targets); - player.addTempSkill('zhaolie2','phaseDrawAfter'); + player.storage.zhaolie = result.targets[0]; + player.logSkill("zhaolie", result.targets); + player.addTempSkill("zhaolie2", "phaseDrawAfter"); } - } + }, }, - zhaolie2:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - popup:false, - content:function(){ - 'step 0' - event.cards=get.cards(3); + zhaolie2: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + popup: false, + content: function () { + "step 0"; + event.cards = get.cards(3); player.showCards(event.cards); - 'step 1' - event.basic=[]; - event.nonbasic=[]; - event.todis=[]; - for(var i=0;i 1 ? 0 : 7 - get.value(card); + case 2: + return 8 - get.value(card); + case 3: + return 10 - get.value(card); + default: + return 0; + } + }) + .set("num", num); } - else{ - player.storage.zhaolie.chooseToDiscard(num,'he','弃置'+get.cnNumber(num)+ - '张牌并令'+get.translation(player)+'拿牌,或受到'+get.cnNumber(num)+'点伤害并拿牌').set('ai',function(card){ - var player=_status.event.player; - switch(_status.event.num){ - case 1:return player.hp>1?0:7-get.value(card); - case 2:return 8-get.value(card); - case 3:return 10-get.value(card); - default:return 0; - } - }).set('num',num); - } - 'step 2' - var num=event.nonbasic.length; - var undone=false; - if(num==0){ - if(event.basic.length){ - result.targets[0].gain(event.basic,'gain2','log'); + "step 2"; + var num = event.nonbasic.length; + var undone = false; + if (num == 0) { + if (event.basic.length) { + result.targets[0].gain(event.basic, "gain2", "log"); } - } - else{ - if(result.bool){ - if(event.basic.length){ - player.gain(event.basic,'gain2','log'); + } else { + if (result.bool) { + if (event.basic.length) { + player.gain(event.basic, "gain2", "log"); } - } - else{ + } else { player.storage.zhaolie.damage(num); - if(event.basic.length){ - undone=true; + if (event.basic.length) { + undone = true; } } } - if(!undone){ + if (!undone) { delete player.storage.zhaolie; event.finish(); } - 'step 3' - if(player.storage.zhaolie.isIn()){ - player.storage.zhaolie.gain(event.basic,'gain2','log'); - } - else{ + "step 3"; + if (player.storage.zhaolie.isIn()) { + player.storage.zhaolie.gain(event.basic, "gain2", "log"); + } else { game.cardsDiscard(event.basic); } delete player.storage.zhaolie; - } + }, }, - fulu:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + fulu: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; }, - audio:true, - check:function(event,player){ - var eff=0; - for(var i=0;i=0; + return eff >= 0; }, - content:function(){ - game.setNature(trigger.card,'thunder'); - if(get.itemtype(trigger.card)=='card'){ - var next=game.createEvent('fulu_clear'); - next.card=trigger.card; + content: function () { + game.setNature(trigger.card, "thunder"); + if (get.itemtype(trigger.card) == "card") { + var next = game.createEvent("fulu_clear"); + next.card = trigger.card; event.next.remove(next); trigger.after.push(next); - next.setContent(function(){ - game.setNature(card,[]); + next.setContent(function () { + game.setNature(card, []); }); } - } + }, }, - fuji:{ - trigger:{global:'damageBegin1'}, - filter:function(event){ - return event.source&&event.source.isIn()&&event.hasNature('thunder'); + fuji: { + trigger: { global: "damageBegin1" }, + filter: function (event) { + return event.source && event.source.isIn() && event.hasNature("thunder"); }, - check:function(event,player){ - return get.attitude(player,event.source)>0&&get.attitude(player,event.player)<0; + check: function (event, player) { + return get.attitude(player, event.source) > 0 && get.attitude(player, event.player) < 0; }, - prompt:function(event){ - return get.translation(event.source)+'即将对'+get.translation(event.player)+'造成伤害,'+get.prompt('fuji'); + prompt: function (event) { + return ( + get.translation(event.source) + + "即将对" + + get.translation(event.player) + + "造成伤害," + + get.prompt("fuji") + ); }, - logTarget:'source', - content:function(){ - trigger.source.judge().callback=lib.skill.fuji.callback; + logTarget: "source", + content: function () { + trigger.source.judge().callback = lib.skill.fuji.callback; }, - callback:function(){ - var evt=event.getParent(2); - if(event.judgeResult.color=='black'){ + callback: function () { + var evt = event.getParent(2); + if (event.judgeResult.color == "black") { //game.cardsDiscard(card); evt._trigger.num++; - } - else{ - evt._trigger.source.gain(card,'gain2'); + } else { + evt._trigger.source.gain(card, "gain2"); } }, }, }, - characterReplace:{}, - dynamicTranslate:{ - }, - translate:{ - sp_gongsunzan:'SP公孙瓒', - sp_gongsunzan_prefix:'SP', - sp_simazhao:'SP司马昭', - sp_simazhao_prefix:'SP', - sp_wangyuanji:'SP王元姬', - sp_wangyuanji_prefix:'SP', - sp_xinxianying:'SP辛宪英', - sp_xinxianying_prefix:'SP', - sp_liuxie:'SP刘协', - sp_liuxie_prefix:'SP', - spyicong_info:'弃牌阶段结束时,你可以将任意张牌置于你的武将牌上,称为「扈」。每有一张「扈」,其他角色与你计算距离时便+1。', - spyicong:'义从', - sptuji:'突骑', - sptuji_info:'准备开始时,你将所有「扈」置于弃牌堆,然后你本回合内计算与其他角色的距离时-X。若X不大于1,你摸一张牌。(X为以此法进入弃牌堆的「扈」的数量)', - sphuangen:'皇恩', - sphuangen_info:'一名角色使用锦囊牌指定目标时,若此牌的目标数大于1,则你可以令此牌对其中的至多X个目标无效,然后摸一张牌。(X为你的体力值)', - sphantong:'汉统', - sphantong_gain:'汉统', - sphantong_info:'当你的牌因弃牌阶段的游戏规则要求而进入弃牌堆后,你可以将这些牌置于你的武将牌上,称为「诏」。一名角色的回合开始时,你可以弃置一张「诏」并获得〖护驾〗/〖激将〗/〖救援〗/〖血裔〗中的一个技能直至当前回合结束。', - spzhaoxin:'昭心', - spzhaoxin_info:'摸牌阶段结束时,你可以展示所有手牌,然后视为使用一张【杀】。', - splanggu:'狼顾', - splanggu_rewrite:'狼顾', - splanggu_info:'当你受到有来源的伤害后,你可以进行判定(此判定结果生效前,你可以打出一张手牌替换判定牌)。然后你可以观看伤害来源的手牌并弃置其中的任意张与判定结果花色相同的牌。', - spfuluan:'扶乱', - spfuluan_info:'出牌阶段限一次,你可以弃置三张花色相同的牌并选择攻击范围内的一名角色。若如此做,该角色翻面且你不能使用【杀】直到回合结束。', - spshude:'淑德', - spshude_info:'结束阶段开始时,你可以将手牌补至体力上限。', - spmingjian:'明鉴', - spmingjian_info:'一名角色的回合开始时,你可以选择一项:①弃置一张牌,然后其跳过本回合的判定阶段。②将一张手牌置于其武将牌上,然后其本回合内进行判定时不触发「判定结果生效前」的时机,且其回合结束时将此牌置入弃牌堆。', - spyinzhi:'隐智', - spyinzhi_info:'当你受到1点伤害后,你可以展示牌堆顶的两张牌。若其中有黑桃牌,则你可以进行至多X次「令一名角色获得伤害来源的一张手牌」的步骤。然后获得其余的牌。(X为其中黑桃牌的数量)', - yj_caoang:'用间曹昂', - yj_caoang_prefix:'用间', - yjxuepin:'血拼', - yjxuepin_info:'出牌阶段限一次,你可以选择攻击范围内的一名角色并失去1点体力。你弃置其两张牌。若这两张牌类型相同,你回复1点体力。', - ns_chendao:'用间陈到', - ns_chendao_prefix:'用间', - nsjianglie:'将烈', - nsjianglie_info:'当你使用【杀】指定目标后,你可以令其展示所有手牌,然后弃置其中一种颜色的牌。', - ns_jiaxu:'★贾诩', - ns_jiaxu_prefix:'★', - nsyice:'遗策', - nsyice_info:'锁定技,当你使用/打出/弃置的牌进入弃牌堆后,你将这些牌以任意顺序置于你的武将牌上,称为“策”。若这些“策”中有点数相同的牌,则你获得这两张牌中的所有牌,将这两张牌置于牌堆两端。若场上没有处于濒死状态的角色,则你对一名角色造成1点伤害。', - ns_lijue:'SP李傕', - ns_lijue_prefix:'SP', - ns_zhangji:'SP张济', - ns_zhangji_prefix:'SP', - nsfeixiong:'飞熊', - nsfeixiong_info:'出牌阶段开始时,你可以和一名其他角色拼点。赢的角色对没赢的角色造成1点伤害。', - nscesuan:'策算', - nscesuan_info:'锁定技,当你受到伤害时,你防止此伤害并失去1点体力上限。若你因以此法失去体力上限导致体力值减少,则你摸一张牌。', - nslulve:'掳掠', - nslulve_info:'出牌阶段限一次,你可以弃置X张牌并选择一名装备区内有牌的其他角色,然后对其造成1点伤害(X为其装备区内的牌数)。', - ns_fanchou:'SP樊稠', - ns_fanchou_prefix:'SP', - nsyangwu:'扬武', - nsyangwu_info:'出牌阶段限一次,你可以弃置一张♥手牌并选择一名手牌数大于你的其他角色。你观看其手牌并获得其中的X张牌(X为其与你手牌数之差的一半且向上取整)。', - jsp_liubei:'★刘备', - jsp_liubei_prefix:'★', - jsprende:'仁德', - jsprende_info:'出牌阶段,你可以将至少一张手牌交给其他角色;若你于此阶段内给出的牌首次达到两张,你可以视为使用一张基本牌。', - ns_caoanmin:'战役篇曹安民', - ns_caoanmin_prefix:'战役篇', - nskuishe:'窥舍', - nskuishe_info:'出牌阶段限一次,你可以选择一名其他角色A的一张牌,并将此牌交给不为A的一名角色。然后A可以对你使用一张【杀】。', - sp_xiahoushi:"SP夏侯氏", - sp_xiahoushi_prefix:'SP', - xinfu_yanyu:"燕语", - xinfu_yanyu_info:"一名角色的出牌阶段开始时,你可以弃置一张牌。若如此做,则该出牌阶段内限三次,当一张与你弃置的牌类别相同的其他牌进入弃牌堆后,你可令任意一名角色获得此牌。", - xinfu_yanyu2:"燕语", - xinfu_xiaode:"孝德", - xinfu_xiaode_info:"其他角色死亡后,你可以声明该角色武将牌上的一个技能(主公技、觉醒技、隐匿技、使命技除外)。若如此做,你获得此技能且不能再发动〖孝德〗直到你的回合结束。", - jsp_zhaoyun:'J.SP赵云', - jsp_zhaoyun_prefix:'J.SP', - chixin:'赤心', - chixin1:'赤心', - chixin2:'赤心', - chixin_info:'你可以将♦牌当作【杀】或【闪】使用或打出。出牌阶段,你对在你攻击范围内且本回合内未成为过你使用的【杀】的目标的角色使用的【杀】没有次数限制。', - suiren:'随仁', - suiren_info:'限定技,准备阶段开始时,你可以失去技能〖义从〗,然后加1点体力上限并回复1点体力,然后令一名角色摸三张牌。', - huangjinleishi:'黄巾雷使', - fulu:'符箓', - fulu_info:'当你声明使用普通【杀】后,你可以将此【杀】改为雷【杀】。', - fuji:'助祭', - fuji_info:'当一名角色造成雷属性伤害时,你可以令其进行判定,若结果为黑色,此伤害+1;若结果为红色,该角色获得判定牌。', - sp_pangtong:'☆SP庞统', - sp_pangtong_prefix:'☆SP', - manjuan:'漫卷', - manjuan_info:'其他角色的牌因弃置而进入弃牌堆后,你可以弃置一张花色与之不同的牌,然后获得此牌。', - xinmanjuan:'漫卷', - xinmanjuan_info:'锁定技,当你不因〖漫卷〗或〖醉乡〗而得到牌时,你将此牌置入弃牌堆。然后若此时处于你的回合内,则你可以从弃牌堆中选择获得一张与此牌点数相同的其他牌。', - zuixiang:'醉乡', - zuixiang2:'醉乡', - zuixiang_info:'限定技。准备阶段开始时,你可以展示牌堆顶的三张牌并置于你的武将牌上。你不能使用或打出与该些牌同类的牌,所有同类牌对你无效。之后的每个准备阶段,你须重复展示一次,直到这些牌中任意两张点数相同。然后,你获得这些牌。', - sp_daqiao:'☆SP大乔', - sp_daqiao_prefix:'☆SP', - yanxiao:'言笑', - yanxiao_info:'出牌阶段,你可以将一张♦牌置于一名角色的判定区内。判定区内有〖言笑〗牌的角色下个判定阶段开始时,其获得判定区里的所有牌。', - anxian:'安娴', - anxian_info:'当你使用【杀】对目标角色造成伤害时,你可以防止此伤害,令其弃置一张手牌,然后你摸一张牌;当你成为【杀】的目标后,你可以弃置一张手牌,令此【杀】对你无效,然后此【杀】的使用者摸一张牌。', - sp_ganning:'☆SP甘宁', - sp_ganning_prefix:'☆SP', - yinling:'银铃', - yinling_bg:'锦', - yinling_info:'出牌阶段,若你的“锦”小于四张,你可以弃置一张黑色牌并指定一名其他角色。若如此做,你将其的一张牌置于你的武将牌上,称为“锦”。', - junwei:'军威', - junwei2:'军威', - junwei_info:'结束阶段开始时,你可以移去三张“锦”。若如此做,你须指定一名角色并令其选择一项:1.展示一张【闪】,然后你将此【闪】交给一名其他角色。2.该角色失去1点体力,然后你将其装备区内的一张牌移出游戏。该角色的回合结束后,将以此法移出游戏的装备牌移回原处。', - sp_xiahoudun:'☆SP夏侯惇', - sp_xiahoudun_prefix:'☆SP', - fenyong:'愤勇', - fenyong2:'愤勇', - fenyong2_bg:'勇', - fenyong_info:'每当你受到一次伤害后,你可以获得一枚「愤勇」标记;当你拥有「愤勇」标记时,防止你受到的所有伤害。', - xuehen:'雪恨', - xuehen_info:'每个角色的结束阶段开始时,若你有愤勇标记,你弃置之,然后选择一项:1.弃置当前回合角色X张牌(X为你已损失的体力值);2.视为对一名任意角色使用一张【杀】。', - sp_lvmeng:'☆SP吕蒙', - sp_lvmeng_prefix:'☆SP', - tanhu:'探虎', - tanhu2:'探虎', - tanhu3:'探虎', - tanhu_info:'出牌阶段限一次,你可以与一名其他角色拼点。若你赢,你获得以下效果直到回合结束:你与该角色的距离为1,你对该角色使用的普通锦囊牌不能被【无懈可击】响应。', - mouduan:'谋断', - mouduan_info:'游戏开始时,你获得标记“武”并获得技能〖激昂〗和〖谦逊〗。当你失去手牌后,若手牌数不大于2,你须将你的标记变为“文”,将这两项技能改为〖英姿〗和〖克己〗。一名角色的回合开始前,你可弃一张牌将标记翻回。', - sp_zhangfei:'☆SP张飞', - sp_zhangfei_prefix:'☆SP', - jie:'嫉恶', - jie_info:'锁定技,当你使用红色【杀】造成伤害时,此伤害+1。', - dahe:'大喝', - dahe2:'大喝', - dahe2_bg:'喝', - dahe_info:'出牌阶段限一次,你可以与一名其他角色拼点。若你赢,该角色不能使用或打出不为♥花色的【闪】直到回合结束,且你可将该角色拼点的牌交给场上一名体力不多于你的角色。若你没赢,你须展示手牌并弃置其中的一张。', - sp_liubei:'☆SP刘备', - sp_liubei_prefix:'☆SP', - zhaolie:'昭烈', - zhaolie_info:'摸牌阶段摸牌时,你可以少摸一张牌并指定攻击范围内的一名角色。你展示牌堆顶的三张牌,将其中的非基本牌和【桃】置于弃牌堆,然后该角色选择一项:1.你对其造成X点伤害,然后其获得这些基本牌;2.其弃置X张牌,然后你获得这些基本牌。(X为其中非基本牌的数量)', - shichou:'誓仇', - shichou2:'誓仇', - shichou_info:'主公技,限定技,准备阶段,你可指定一名蜀势力角色并交给其两张牌。本局游戏中,当你受到伤害时,改为该角色受到等量的伤害并摸等量的牌,直至该角色第一次进入濒死状态。', - longyufei:'龙羽飞', - longyi:'龙裔', - longyi_info:'你可将所有手牌当做任意基本牌使用或打出。若此牌对应的实体牌中:有锦囊牌,你摸一张牌;有装备牌,此牌不可被响应。', - zhenjue:'阵绝', - zhenjue_info:'一名角色的结束阶段开始时,若你没有手牌,则你可以令其选择一项:①弃置一张牌。②令你摸一张牌。', + characterReplace: {}, + dynamicTranslate: {}, + translate: { + sp_gongsunzan: "SP公孙瓒", + sp_gongsunzan_prefix: "SP", + sp_simazhao: "SP司马昭", + sp_simazhao_prefix: "SP", + sp_wangyuanji: "SP王元姬", + sp_wangyuanji_prefix: "SP", + sp_xinxianying: "SP辛宪英", + sp_xinxianying_prefix: "SP", + sp_liuxie: "SP刘协", + sp_liuxie_prefix: "SP", + spyicong_info: + "弃牌阶段结束时,你可以将任意张牌置于你的武将牌上,称为「扈」。每有一张「扈」,其他角色与你计算距离时便+1。", + spyicong: "义从", + sptuji: "突骑", + sptuji_info: + "准备开始时,你将所有「扈」置于弃牌堆,然后你本回合内计算与其他角色的距离时-X。若X不大于1,你摸一张牌。(X为以此法进入弃牌堆的「扈」的数量)", + sphuangen: "皇恩", + sphuangen_info: + "一名角色使用锦囊牌指定目标时,若此牌的目标数大于1,则你可以令此牌对其中的至多X个目标无效,然后摸一张牌。(X为你的体力值)", + sphantong: "汉统", + sphantong_gain: "汉统", + sphantong_info: + "当你的牌因弃牌阶段的游戏规则要求而进入弃牌堆后,你可以将这些牌置于你的武将牌上,称为「诏」。一名角色的回合开始时,你可以弃置一张「诏」并获得〖护驾〗/〖激将〗/〖救援〗/〖血裔〗中的一个技能直至当前回合结束。", + spzhaoxin: "昭心", + spzhaoxin_info: "摸牌阶段结束时,你可以展示所有手牌,然后视为使用一张【杀】。", + splanggu: "狼顾", + splanggu_rewrite: "狼顾", + splanggu_info: + "当你受到有来源的伤害后,你可以进行判定(此判定结果生效前,你可以打出一张手牌替换判定牌)。然后你可以观看伤害来源的手牌并弃置其中的任意张与判定结果花色相同的牌。", + spfuluan: "扶乱", + spfuluan_info: + "出牌阶段限一次,你可以弃置三张花色相同的牌并选择攻击范围内的一名角色。若如此做,该角色翻面且你不能使用【杀】直到回合结束。", + spshude: "淑德", + spshude_info: "结束阶段开始时,你可以将手牌补至体力上限。", + spmingjian: "明鉴", + spmingjian_info: + "一名角色的回合开始时,你可以选择一项:①弃置一张牌,然后其跳过本回合的判定阶段。②将一张手牌置于其武将牌上,然后其本回合内进行判定时不触发「判定结果生效前」的时机,且其回合结束时将此牌置入弃牌堆。", + spyinzhi: "隐智", + spyinzhi_info: + "当你受到1点伤害后,你可以亮出牌堆顶的两张牌。若其中有黑桃牌,则你可以进行至多X次「令一名角色获得伤害来源的一张手牌」的步骤。然后获得其余的牌。(X为其中黑桃牌的数量)", + yj_caoang: "用间曹昂", + yj_caoang_prefix: "用间", + yjxuepin: "血拼", + yjxuepin_info: + "出牌阶段限一次,你可以选择攻击范围内的一名角色并失去1点体力。你弃置其两张牌。若这两张牌类型相同,你回复1点体力。", + ns_chendao: "用间陈到", + ns_chendao_prefix: "用间", + nsjianglie: "将烈", + nsjianglie_info: "当你使用【杀】指定目标后,你可以令其展示所有手牌,然后弃置其中一种颜色的牌。", + ns_jiaxu: "★贾诩", + ns_jiaxu_prefix: "★", + nsyice: "遗策", + nsyice_info: + "锁定技,当你使用/打出/弃置的牌进入弃牌堆后,你将这些牌以任意顺序置于你的武将牌上,称为“策”。若这些“策”中有点数相同的牌,则你获得这两张牌中的所有牌,将这两张牌置于牌堆两端。若场上没有处于濒死状态的角色,则你对一名角色造成1点伤害。", + ns_lijue: "SP李傕", + ns_lijue_prefix: "SP", + ns_zhangji: "SP张济", + ns_zhangji_prefix: "SP", + nsfeixiong: "飞熊", + nsfeixiong_info: "出牌阶段开始时,你可以和一名其他角色拼点。赢的角色对没赢的角色造成1点伤害。", + nscesuan: "策算", + nscesuan_info: + "锁定技,当你受到伤害时,你防止此伤害并失去1点体力上限。若你因以此法失去体力上限导致体力值减少,则你摸一张牌。", + nslulve: "掳掠", + nslulve_info: + "出牌阶段限一次,你可以弃置X张牌并选择一名装备区内有牌的其他角色,然后对其造成1点伤害(X为其装备区内的牌数)。", + ns_fanchou: "SP樊稠", + ns_fanchou_prefix: "SP", + nsyangwu: "扬武", + nsyangwu_info: + "出牌阶段限一次,你可以弃置一张♥手牌并选择一名手牌数大于你的其他角色。你观看其手牌并获得其中的X张牌(X为其与你手牌数之差的一半且向上取整)。", + jsp_liubei: "★刘备", + jsp_liubei_prefix: "★", + jsprende: "仁德", + jsprende_info: + "出牌阶段,你可以将至少一张手牌交给其他角色;若你于此阶段内给出的牌首次达到两张,你可以视为使用一张基本牌。", + ns_caoanmin: "战役篇曹安民", + ns_caoanmin_prefix: "战役篇", + nskuishe: "窥舍", + nskuishe_info: + "出牌阶段限一次,你可以选择一名其他角色A的一张牌,并将此牌交给不为A的一名角色。然后A可以对你使用一张【杀】。", + sp_xiahoushi: "SP夏侯氏", + sp_xiahoushi_prefix: "SP", + xinfu_yanyu: "燕语", + xinfu_yanyu_info: + "一名角色的出牌阶段开始时,你可以弃置一张牌。若如此做,则该出牌阶段内限三次,当一张与你弃置的牌类别相同的其他牌进入弃牌堆后,你可令任意一名角色获得此牌。", + xinfu_yanyu2: "燕语", + xinfu_xiaode: "孝德", + xinfu_xiaode_info: + "其他角色死亡后,你可以声明该角色武将牌上的一个技能(主公技、觉醒技、隐匿技、使命技除外)。若如此做,你获得此技能且不能再发动〖孝德〗直到你的回合结束。", + jsp_zhaoyun: "J.SP赵云", + jsp_zhaoyun_prefix: "J.SP", + chixin: "赤心", + chixin1: "赤心", + chixin2: "赤心", + chixin_info: + "你可以将♦牌当作【杀】或【闪】使用或打出。出牌阶段,你对在你攻击范围内且本回合内未成为过你使用的【杀】的目标的角色使用的【杀】没有次数限制。", + suiren: "随仁", + suiren_info: + "限定技,准备阶段开始时,你可以失去技能〖义从〗,然后加1点体力上限并回复1点体力,然后令一名角色摸三张牌。", + huangjinleishi: "黄巾雷使", + fulu: "符箓", + fulu_info: "当你声明使用普通【杀】后,你可以将此【杀】改为雷【杀】。", + fuji: "助祭", + fuji_info: + "当一名角色造成雷属性伤害时,你可以令其进行判定,若结果为黑色,此伤害+1;若结果为红色,该角色获得判定牌。", + sp_pangtong: "☆SP庞统", + sp_pangtong_prefix: "☆SP", + manjuan: "漫卷", + manjuan_info: "其他角色的牌因弃置而进入弃牌堆后,你可以弃置一张花色与之不同的牌,然后获得此牌。", + xinmanjuan: "漫卷", + xinmanjuan_info: + "锁定技,当你不因〖漫卷〗或〖醉乡〗而得到牌时,你将此牌置入弃牌堆。然后若此时处于你的回合内,则你可以从弃牌堆中选择获得一张与此牌点数相同的其他牌。", + zuixiang: "醉乡", + zuixiang2: "醉乡", + zuixiang_info: + "限定技。准备阶段开始时,你可以亮出牌堆顶的三张牌并置于你的武将牌上。你不能使用或打出与该些牌同类的牌,所有同类牌对你无效。之后的每个准备阶段,你须重复展示一次,直到这些牌中任意两张点数相同。然后,你获得这些牌。", + sp_daqiao: "☆SP大乔", + sp_daqiao_prefix: "☆SP", + yanxiao: "言笑", + yanxiao_info: + "出牌阶段,你可以将一张♦牌置于一名角色的判定区内。判定区内有〖言笑〗牌的角色下个判定阶段开始时,其获得判定区里的所有牌。", + anxian: "安娴", + anxian_info: + "当你使用【杀】对目标角色造成伤害时,你可以防止此伤害,令其弃置一张手牌,然后你摸一张牌;当你成为【杀】的目标后,你可以弃置一张手牌,令此【杀】对你无效,然后此【杀】的使用者摸一张牌。", + sp_ganning: "☆SP甘宁", + sp_ganning_prefix: "☆SP", + yinling: "银铃", + yinling_bg: "锦", + yinling_info: + "出牌阶段,若你的“锦”小于四张,你可以弃置一张黑色牌并指定一名其他角色。若如此做,你将其的一张牌置于你的武将牌上,称为“锦”。", + junwei: "军威", + junwei2: "军威", + junwei_info: + "结束阶段开始时,你可以移去三张“锦”。若如此做,你须指定一名角色并令其选择一项:1.展示一张【闪】,然后你将此【闪】交给一名其他角色。2.该角色失去1点体力,然后你将其装备区内的一张牌移出游戏。该角色的回合结束后,将以此法移出游戏的装备牌移回原处。", + sp_xiahoudun: "☆SP夏侯惇", + sp_xiahoudun_prefix: "☆SP", + fenyong: "愤勇", + fenyong2: "愤勇", + fenyong2_bg: "勇", + fenyong_info: + "每当你受到一次伤害后,你可以获得一枚「愤勇」标记;当你拥有「愤勇」标记时,防止你受到的所有伤害。", + xuehen: "雪恨", + xuehen_info: + "每个角色的结束阶段开始时,若你有愤勇标记,你弃置之,然后选择一项:1.弃置当前回合角色X张牌(X为你已损失的体力值);2.视为对一名任意角色使用一张【杀】。", + sp_lvmeng: "☆SP吕蒙", + sp_lvmeng_prefix: "☆SP", + tanhu: "探虎", + tanhu2: "探虎", + tanhu3: "探虎", + tanhu_info: + "出牌阶段限一次,你可以与一名其他角色拼点。若你赢,你获得以下效果直到回合结束:你与该角色的距离为1,你对该角色使用的普通锦囊牌不能被【无懈可击】响应。", + mouduan: "谋断", + mouduan_info: + "游戏开始时,你获得标记“武”并获得技能〖激昂〗和〖谦逊〗。当你失去手牌后,若手牌数不大于2,你须将你的标记变为“文”,将这两项技能改为〖英姿〗和〖克己〗。一名角色的回合开始前,你可弃一张牌将标记翻回。", + sp_zhangfei: "☆SP张飞", + sp_zhangfei_prefix: "☆SP", + jie: "嫉恶", + jie_info: "锁定技,当你使用红色【杀】造成伤害时,此伤害+1。", + dahe: "大喝", + dahe2: "大喝", + dahe2_bg: "喝", + dahe_info: + "出牌阶段限一次,你可以与一名其他角色拼点。若你赢,该角色不能使用或打出不为♥花色的【闪】直到回合结束,且你可将该角色拼点的牌交给场上一名体力不多于你的角色。若你没赢,你须展示手牌并弃置其中的一张。", + sp_liubei: "☆SP刘备", + sp_liubei_prefix: "☆SP", + zhaolie: "昭烈", + zhaolie_info: + "摸牌阶段摸牌时,你可以少摸一张牌并指定攻击范围内的一名角色。你亮出牌堆顶的三张牌,将其中的非基本牌和【桃】置于弃牌堆,然后该角色选择一项:1.你对其造成X点伤害,然后其获得这些基本牌;2.其弃置X张牌,然后你获得这些基本牌。(X为其中非基本牌的数量)", + shichou: "誓仇", + shichou2: "誓仇", + shichou_info: + "主公技,限定技,准备阶段,你可指定一名蜀势力角色并交给其两张牌。本局游戏中,当你受到伤害时,改为该角色受到等量的伤害并摸等量的牌,直至该角色第一次进入濒死状态。", + longyufei: "龙羽飞", + longyi: "龙裔", + longyi_info: + "你可将所有手牌当做任意基本牌使用或打出。若此牌对应的实体牌中:有锦囊牌,你摸一张牌;有装备牌,此牌不可被响应。", + zhenjue: "阵绝", + zhenjue_info: + "一名角色的结束阶段开始时,若你没有手牌,则你可以令其选择一项:①弃置一张牌。②令你摸一张牌。", //用间 - yj_caocao:'用间曹操', - yj_caocao_prefix:'用间', - yjxiandao:'献刀', - yjxiandao_info:'每回合限一次。当你赠予其他角色一张牌后,你令其不能使用或打出与本次赠予移动的牌A花色相同的牌直到回合结束。然后若牌A:为锦囊牌,你摸两张牌。为装备牌,你获得其一张不为A的牌。为武器牌,你对其造成1点伤害。', - yjsancai:'散财', - yjsancai_info:'出牌阶段限一次,你可以展示所有手牌。若这些牌的类别均相同,则你可以赠予一名其他角色一张手牌。', - yjyibing:'义兵', - yjyibing_info:'当你不因赠予且不因〖义兵〗的嵌套结算而于摸牌阶段外得到牌时,你可以将此次得到的所有牌当做【杀】使用(无距离限制且不计入使用次数)。', - yj_caohong:'用间曹洪', - yj_caohong_prefix:'用间', - yjlifeng:'厉锋', - yjlifeng_info:'①出牌阶段限一次。你可以获得弃牌堆里的一张装备牌。②你发动〖赠予〗可以选择手牌区里的装备牌或装备区里的牌。', - yj_zhangfei:'用间张飞', - yj_zhangfei_prefix:'用间', - yjmangji:'莽击', - yjmangji_info:'锁定技。当你装备区里的牌数或体力值变化后,若你的体力值不小于1,你弃置一张手牌并视为使用一张【杀】。', - yongjian_ganning:'用间甘宁', - yongjian_ganning_prefix:'用间', - yjjielve:'劫掠', - yjjielve_info:'你可以将两张颜色相同的牌当【趁火打劫】使用,若你以此法造成伤害,此技能于本回合失效。', + yj_caocao: "用间曹操", + yj_caocao_prefix: "用间", + yjxiandao: "献刀", + yjxiandao_info: + "每回合限一次。当你赠予其他角色一张牌后,你令其不能使用或打出与本次赠予移动的牌A花色相同的牌直到回合结束。然后若牌A:为锦囊牌,你摸两张牌。为装备牌,你获得其一张不为A的牌。为武器牌,你对其造成1点伤害。", + yjsancai: "散财", + yjsancai_info: + "出牌阶段限一次,你可以展示所有手牌。若这些牌的类别均相同,则你可以赠予一名其他角色一张手牌。", + yjyibing: "义兵", + yjyibing_info: + "当你不因赠予且不因〖义兵〗的嵌套结算而于摸牌阶段外得到牌时,你可以将此次得到的所有牌当做【杀】使用(无距离限制且不计入使用次数)。", + yj_caohong: "用间曹洪", + yj_caohong_prefix: "用间", + yjlifeng: "厉锋", + yjlifeng_info: + "①出牌阶段限一次。你可以获得弃牌堆里的一张装备牌。②你发动〖赠予〗可以选择手牌区里的装备牌或装备区里的牌。", + yj_zhangfei: "用间张飞", + yj_zhangfei_prefix: "用间", + yjmangji: "莽击", + yjmangji_info: + "锁定技。当你装备区里的牌数或体力值变化后,若你的体力值不小于1,你弃置一张手牌并视为使用一张【杀】。", + yongjian_ganning: "用间甘宁", + yongjian_ganning_prefix: "用间", + yjjielve: "劫掠", + yjjielve_info: + "你可以将两张颜色相同的牌当【趁火打劫】使用,若你以此法造成伤害,此技能于本回合失效。", //什么?孙鲁班?谁会做这种离谱的东西 - yj_dongzhuo:'用间董卓', - yj_dongzhuo_prefix:'用间', - yjtuicheng:'推诚', - yjtuicheng_info:'你可以失去1点体力并视为使用一张【推心置腹】。', - yjyaoling:'耀令', - yjyaoling_info:'出牌阶段结束时,你可以减1点体力上限并选择一名其他角色A和一名角色B,你令A选择一项:1.对B使用一张【杀】;2.你弃置其一张牌。', - yjshicha:'失察', - yjshicha_info:'锁定技。弃牌阶段开始时,若你本回合未发动过〖推诚〗或〖耀令〗之一,你本回合的手牌上限为1。', - yjyongquan:'拥权', - yjyongquan_info:'主公技。结束阶段,其他群势力角色依次可以交给你一张牌。', - yj_liru:'用间李儒', - yj_liru_prefix:'用间', - yjdumou:'毒谋', - yjdumou_info:'锁定技。你的回合内,其他角色的黑色手牌均视为【毒】,你的【毒】均视为【过河拆桥】。', - yjweiquan:'威权', - yjweiquan_info:'限定技。出牌阶段,你可以选择至多X名角色(X为游戏轮数),然后选择一名角色A,这些角色依次将一张手牌交给A。然后若A的手牌数大于体力值,其插入执行一个仅有弃牌阶段的回合。', - yjrenwang:'人望', - yjrenwang_info:'出牌阶段限一次。你可以选择弃牌堆中的一张黑色基本牌,令一名角色获得之。', - yj_xuyou:'用间许攸', - yj_xuyou_prefix:'用间', - yjshicai:'恃才', - yjshicai_info:'①回合内,牌堆顶的一张牌对你可见。②出牌阶段限一次。你可以弃置一张牌,展示并获得牌堆顶的一张牌。当此牌离开你的手牌区后,重置〖恃才②〗。', - yjchenggong:'逞功', - yjchenggong_info:'当一名角色使用牌指定第一个目标后,若此牌目标数大于1,你可以令其摸一张牌。', - yjzezhu:'择主', - yjzezhu_info:'出牌阶段限一次。你可以获得主公区域内的一张牌,然后交给其一张牌。', - yj_jiaxu:'用间贾诩', - yj_jiaxu_prefix:'用间', - yjzhenlve:'缜略', - yjzhenlve_info:'锁定技。①你使用的普通锦囊牌不能被响应。②你不能成为延时锦囊牌的目标。', - yjjianshu:'间书', - yjjianshu_info:'出牌阶段限一次。你可以将一张手牌交给一名其他角色,令其与你选择的另一名其他角色拼点,没赢的角色失去1点体力。', - yjyongdi:'拥嫡', - yjyongdi_info:'限定技。准备阶段,你可以令一名男性角色加1点体力上限并回复1点体力,然后若其武将牌上有主公技且其不为主公,其获得此主公技。', - yj_zhugedan:'用间诸葛诞', - yj_zhugedan_prefix:'用间', - yj_zhenji:'用间甄宓', - yj_zhenji_prefix:'用间', - yjluoshen:'洛神', - yjluoshen_info:'准备阶段,你可以判定并获得判定牌,且可重复此流程直到结果的颜色不同。', + yj_dongzhuo: "用间董卓", + yj_dongzhuo_prefix: "用间", + yjtuicheng: "推诚", + yjtuicheng_info: "你可以失去1点体力并视为使用一张【推心置腹】。", + yjyaoling: "耀令", + yjyaoling_info: + "出牌阶段结束时,你可以减1点体力上限并选择一名其他角色A和一名角色B,你令A选择一项:1.对B使用一张【杀】;2.你弃置其一张牌。", + yjshicha: "失察", + yjshicha_info: + "锁定技。弃牌阶段开始时,若你本回合未发动过〖推诚〗或〖耀令〗之一,你本回合的手牌上限为1。", + yjyongquan: "拥权", + yjyongquan_info: "主公技。结束阶段,其他群势力角色依次可以交给你一张牌。", + yj_liru: "用间李儒", + yj_liru_prefix: "用间", + yjdumou: "毒谋", + yjdumou_info: + "锁定技。你的回合内,其他角色的黑色手牌均视为【毒】,你的【毒】均视为【过河拆桥】。", + yjweiquan: "威权", + yjweiquan_info: + "限定技。出牌阶段,你可以选择至多X名角色(X为游戏轮数),然后选择一名角色A,这些角色依次将一张手牌交给A。然后若A的手牌数大于体力值,其插入执行一个仅有弃牌阶段的回合。", + yjrenwang: "人望", + yjrenwang_info: "出牌阶段限一次。你可以选择弃牌堆中的一张黑色基本牌,令一名角色获得之。", + yj_xuyou: "用间许攸", + yj_xuyou_prefix: "用间", + yjshicai: "恃才", + yjshicai_info: + "①回合内,牌堆顶的一张牌对你可见。②出牌阶段限一次。你可以弃置一张牌,展示并获得牌堆顶的一张牌。当此牌离开你的手牌区后,重置〖恃才②〗。", + yjchenggong: "逞功", + yjchenggong_info: "当一名角色使用牌指定第一个目标后,若此牌目标数大于1,你可以令其摸一张牌。", + yjzezhu: "择主", + yjzezhu_info: "出牌阶段限一次。你可以获得主公区域内的一张牌,然后交给其一张牌。", + yj_jiaxu: "用间贾诩", + yj_jiaxu_prefix: "用间", + yjzhenlve: "缜略", + yjzhenlve_info: "锁定技。①你使用的普通锦囊牌不能被响应。②你不能成为延时锦囊牌的目标。", + yjjianshu: "间书", + yjjianshu_info: + "出牌阶段限一次。你可以将一张手牌交给一名其他角色,令其与你选择的另一名其他角色拼点,没赢的角色失去1点体力。", + yjyongdi: "拥嫡", + yjyongdi_info: + "限定技。准备阶段,你可以令一名男性角色加1点体力上限并回复1点体力,然后若其武将牌上有主公技且其不为主公,其获得此主公技。", + yj_zhugedan: "用间诸葛诞", + yj_zhugedan_prefix: "用间", + yj_zhenji: "用间甄宓", + yj_zhenji_prefix: "用间", + yjluoshen: "洛神", + yjluoshen_info: "准备阶段,你可以判定并获得判定牌,且可重复此流程直到结果的颜色不同。", //线下E系列 一战成名 战役篇官盗 - shen_jiaxu:'战役篇神贾诩', - shen_jiaxu_prefix:'战役篇神', - zybishi:'避世', - zybishi_info:'当你成为【杀】的目标后,你可以令使用者摸一张牌,然后令此【杀】无效。', - zyjianbing:'谏兵', - zyjianbing_info:'当一名其他角色受到执行【杀】的效果而受到伤害时,你可以获得其一张牌。若此牌花色为♥,其回复1点体力。', - pe_wangyun:'战役篇王允', - pe_wangyun_prefix:'战役篇', - zylianji:'连计', - zylianji_info:'出牌阶段结束时,若你于此阶段使用牌的类别数达到:1,你可以令一名角色摸一张牌;2,你可以回复1点体力;3,你可以跳过本回合剩余阶段,然后令一名其他角色执行一个仅有你于此回合未执行过的阶段的回合。', - zymoucheng:'谋逞', - zymoucheng_info:'每回合限一次。你可以将一张黑色牌当【借刀杀人】使用。', - pe_zhonghui:'战役篇钟会', - pe_zhonghui_prefix:'战役篇', - zyquanji:'权计', - zyquanji_info:'①当你受到伤害后或使用牌对唯一目标造成伤害后,你可以摸一张牌并将一张牌置于武将上,称为“权”。②你的手牌上限+X(X为“权”数)。', - zypaiyi:'排异', - zypaiyi_backup:'排异', - zypaiyi_info:'出牌阶段限一次。你可以移去一张“权”并令一名角色摸X张牌(X为“权”数,且至多为7),然后若其手牌数大于你,你对其造成1点伤害。', - pe_mengda:'战役篇孟达', - pe_mengda_prefix:'战役篇', - qiuan:'求安', - qiuan_info:'当你受到伤害后,若此伤害的渠道有对应的实体牌且你的武将牌上没有“函”,则你可以防止此伤害并将这些牌置于你的武将牌上,称为“函”。', - liangfan:'量反', - liangfan2:'量反', - liangfan_info:'锁定技,准备阶段开始时,若你的武将牌上有“函”,则你获得这些牌,然后失去1点体力。当你于此回合内因使用实体牌中包含“函”的牌且执行这些牌的效果而造成伤害后,你可以获得目标角色的一张牌。', - pe_sunchen:'战役篇孙綝', - pe_sunchen_prefix:'战役篇', - zyshilu:'嗜戮', - zyshilu_info:'①一名角色死亡后,你可以将其武将牌置于你的武将牌上,称为“戮”,若杀死其的角色是你,你将一张武将牌堆里的牌置为“戮”。②回合开始时,你可以弃置至多X张牌,然后摸等量的牌(X为“戮”数)。', - zyxiongnve:'凶虐', - zyxiongnve_info:'①出牌阶段开始时,你可以将一张“戮”置入武将牌堆并选择一项直到回合结束:1.当你造成伤害时,此伤害+1;2.当你对其他角色造成伤害时,获得其一张牌;3.你使用牌无次数限制。②出牌阶段结束时,你可以将两张“戮”置入武将牌堆,然后当你于下回合开始前受到其他角色造成的伤害时,此伤害-1。', - pe_wenqin:'战役篇文钦', - pe_wenqin_prefix:'战役篇', - gzjinfa:'矜伐', - gzjinfa_info:'出牌阶段限一次。你可以弃置一张牌,令一名其他角色选择一项:1.令你获得其一张牌;2.交给你一张装备牌,若此牌花色为♠,其视为对你使用一张【杀】。', - zyshangyi:'尚义', - zyshangyi_info:'出牌阶段限一次。你可以令一名其他角色观看你的手牌,然后你观看其手牌并可以弃置其中一张牌。', - zymingshi:'名士', - zymingshi_info:'锁定技。若你有空置的防具栏,属性【杀】对你无效。', - gzsuishi:'随势', - gzsuishi2:'随势', - gzsuishi_info:'锁定技,其他角色进入濒死状态时,若伤害来源与你势力相同,你摸一张牌;其他角色死亡时,若其与你势力相同,你失去1点体力。', + shen_jiaxu: "战役篇神贾诩", + shen_jiaxu_prefix: "战役篇神", + zybishi: "避世", + zybishi_info: "当你成为【杀】的目标后,你可以令使用者摸一张牌,然后令此【杀】无效。", + zyjianbing: "谏兵", + zyjianbing_info: + "当一名其他角色受到执行【杀】的效果而受到伤害时,你可以获得其一张牌。若此牌花色为♥,其回复1点体力。", + pe_wangyun: "战役篇王允", + pe_wangyun_prefix: "战役篇", + zylianji: "连计", + zylianji_info: + "出牌阶段结束时,若你于此阶段使用牌的类别数达到:1,你可以令一名角色摸一张牌;2,你可以回复1点体力;3,你可以跳过本回合剩余阶段,然后令一名其他角色执行一个仅有你于此回合未执行过的阶段的回合。", + zymoucheng: "谋逞", + zymoucheng_info: "每回合限一次。你可以将一张黑色牌当【借刀杀人】使用。", + pe_zhonghui: "战役篇钟会", + pe_zhonghui_prefix: "战役篇", + zyquanji: "权计", + zyquanji_info: + "①当你受到伤害后或使用牌对唯一目标造成伤害后,你可以摸一张牌并将一张牌置于武将上,称为“权”。②你的手牌上限+X(X为“权”数)。", + zypaiyi: "排异", + zypaiyi_backup: "排异", + zypaiyi_info: + "出牌阶段限一次。你可以移去一张“权”并令一名角色摸X张牌(X为“权”数,且至多为7),然后若其手牌数大于你,你对其造成1点伤害。", + pe_mengda: "战役篇孟达", + pe_mengda_prefix: "战役篇", + qiuan: "求安", + qiuan_info: + "当你受到伤害后,若此伤害的渠道有对应的实体牌且你的武将牌上没有“函”,则你可以防止此伤害并将这些牌置于你的武将牌上,称为“函”。", + liangfan: "量反", + liangfan2: "量反", + liangfan_info: + "锁定技,准备阶段开始时,若你的武将牌上有“函”,则你获得这些牌,然后失去1点体力。当你于此回合内因使用实体牌中包含“函”的牌且执行这些牌的效果而造成伤害后,你可以获得目标角色的一张牌。", + pe_sunchen: "战役篇孙綝", + pe_sunchen_prefix: "战役篇", + zyshilu: "嗜戮", + zyshilu_info: + "①一名角色死亡后,你可以将其武将牌置于你的武将牌上,称为“戮”,若杀死其的角色是你,你将一张武将牌堆里的牌置为“戮”。②回合开始时,你可以弃置至多X张牌,然后摸等量的牌(X为“戮”数)。", + zyxiongnve: "凶虐", + zyxiongnve_info: + "①出牌阶段开始时,你可以将一张“戮”置入武将牌堆并选择一项直到回合结束:1.当你造成伤害时,此伤害+1;2.当你对其他角色造成伤害时,获得其一张牌;3.你使用牌无次数限制。②出牌阶段结束时,你可以将两张“戮”置入武将牌堆,然后当你于下回合开始前受到其他角色造成的伤害时,此伤害-1。", + pe_wenqin: "战役篇文钦", + pe_wenqin_prefix: "战役篇", + gzjinfa: "矜伐", + gzjinfa_info: + "出牌阶段限一次。你可以弃置一张牌,令一名其他角色选择一项:1.令你获得其一张牌;2.交给你一张装备牌,若此牌花色为♠,其视为对你使用一张【杀】。", + zyshangyi: "尚义", + zyshangyi_info: + "出牌阶段限一次。你可以令一名其他角色观看你的手牌,然后你观看其手牌并可以弃置其中一张牌。", + zymingshi: "名士", + zymingshi_info: "锁定技。若你有空置的防具栏,属性【杀】对你无效。", + gzsuishi: "随势", + gzsuishi2: "随势", + gzsuishi_info: + "锁定技,其他角色进入濒死状态时,若伤害来源与你势力相同,你摸一张牌;其他角色死亡时,若其与你势力相同,你失去1点体力。", //线下S系列 - ps_guanyu:'★关羽', - ps_guanyu_prefix:'★', - pszhonghun:'忠魂', - pszhonghun_info:'当你使用或打出红色牌时,你可以亮出牌堆顶的一张牌。若此牌为红色,你获得之。', - ps2070_guojia:'★郭嘉', - ps2070_guojia_prefix:'★', - psquanmou:'全谋', - psquanmou_info:'当其他角色使用锦囊牌结算结束后,若你是此牌目标,你可以弃置一张与此牌颜色相同的手牌并获得之。', - ps1059_guojia:'★郭嘉', - ps1059_guojia_prefix:'★', - psqizuo:'奇佐', - psqizuo_info:'当你攻击范围内的角色造成或受到伤害时,你可以弃置一张牌并判定,若此牌颜色与结果相同,你可以令此伤害+1或-1。', - ps2063_zhaoyun:'★赵云', - ps2063_zhaoyun_prefix:'★', - psqijin:'七进', - psqijin_info:'摸牌阶段,你可以改为亮出牌堆顶的七张牌,并获得其中一种颜色的所有牌。', - psqichu:'七出', - psqichu_info:'每回合限一次。当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌。若其中有此牌,你可以使用或打出之。', - pslongxin:'龙心', - pslongxin_info:'判定阶段开始时,你可以弃置一张装备牌,然后弃置你判定区里的一张牌。', - ps2080_zhouyu:'★周瑜', - ps2080_zhouyu_prefix:'★', - psshiyin:'识音', - psshiyin_info:'①游戏开始时,你可以将一张手牌置于武将牌上,称为“杂音”牌。②出牌阶段开始时,你可以用一张手牌替换“杂音”牌。', - psquwu:'曲误', - psquwu_info:'锁定技。你不能使用或打出与“杂音”牌花色相同的牌,且这些牌对你无效。', - psliaozou:'聊奏', - psliaozou_info:'出牌阶段,你可以展示所有手牌,若其中没有与“杂音”牌花色相同的牌,你摸一张牌。', - ps1062_zhouyu:'★周瑜', - ps1062_zhouyu_prefix:'★', - psoldshiyin:'识音', - psoldshiyin_info:'当你于回合内得到牌后,你可以展示之,然后根据你展示的牌包含的花色数令你本回合使用的下一张牌获得对应效果:不小于1,不能被响应;不小于2,造成的伤害+1;不小于3,使用时摸一张牌。', - ps_caozhi:'★曹植', - ps_caozhi_prefix:'★', - psliushang:'流殇', - psliushang_info:'锁定技。①摸牌阶段,你改为摸X+1张牌,然后依次将一张手牌置于所有其他角色的武将牌上,称为“流殇”牌(X为场上角色数且至少为3)。②其他角色的准备阶段,其选择一项:1.获得其“流殇”牌,且当其于本回合对你造成伤害时,防止此伤害;2.将其“流殇”牌置入弃牌堆。', - psqibu:'七步', - psqibu_info:'限定技。当你进入濒死状态时,你可以亮出牌堆顶的七张牌,回复等同于其中♥牌数的体力,并获得所有♣牌。', - ps_jin_simayi:'★司马懿', - ps_jin_simayi_prefix:'★', - psquanyi:'权奕', - psquanyi_info:'①出牌阶段限一次。你可以与一名角色拼点,赢的角色根据所有拼点牌的花色执行以下效果:♥,其获得没赢的角色区域里的一张牌;♦其对没赢的角色造成1点伤害;♠,其失去1点体力;♣,其弃置两张牌。②当你拼点时,你可以选择牌堆顶的牌作为拼点牌。', - ps2067_zhaoyun:'武将传赵云', - ps2067_zhaoyun_prefix:'武将传', - pshuiqiang:'回枪', - pshuiqiang_info:'当你使用的【杀】被【闪】抵消后,你可以对其使用一张【杀】。', - pshuntu:'魂突', - pshuntu_info:'出牌阶段限一次。当你使用【杀】对目标角色造成伤害后,你可以对其使用一张【杀】。', - ps_caopi:'★曹丕', - ps_caopi_prefix:'★', - psjianwei:'僭位', - psjianwei_info:'限定技。回合开始时,你可以失去1点体力,然后与一名其他角色交换区域里的所有牌。', - ps2068_simayi:'★司马懿', - ps2068_simayi_prefix:'★', - pszhonghu:'冢虎', - pszhonghu_info:'当一名角色于你的回合外死亡后,你可以结束此回合,然后令所有角色于其回合开始前跳过此回合直到你的回合开始前。', - ps_simayi:'★司马懿', - ps_simayi_prefix:'★', - pshuxiao:'虎啸', - pshuxiao_info:'回合开始时,你可以判定。若结果为基本牌或普通锦囊牌,你于本回合内获得如下效果:你可以将与结果点数或花色相同的手牌当与判定牌牌名和属性相同的牌使用。', - ps_zhugeliang:'★诸葛亮', - ps_zhugeliang_prefix:'★', - psguanxing:'观星', - psguanxing_info:'准备阶段,你可以观看牌堆顶的五张牌,并将其以任意顺序置于牌堆项或牌堆底。', - pslongyin:'龙吟', - pslongyin_info:'每回合限一次。你可以将任意张点数和为13的牌当做任意一张基本牌或普通锦囊牌使用或打出。', - ps2066_zhugeliang:'武将传诸葛亮', - ps2066_zhugeliang_prefix:'武将传', - pszhiji:'智激', - pszhiji_info:'出牌阶段限一次。你可以弃置两张手牌并选择两名势力不同的角色,视为这两名角色依次视为对对方使用一张【杀】。', - psjiefeng:'借风', - psjiefeng_info:'出牌阶段,你可以弃置两张手牌,然后亮出牌堆顶五张牌。若其中有至少两张红色牌,你视为使用一张【万箭齐发】。', - ps_machao:'★马超', - ps_machao_prefix:'★', - psweihou:'威侯', - psweihou_info:'当你判定前,你可以展示牌堆顶的两张牌,选择其中一张作为你的本次判定结果,然后将另一张置入弃牌堆。', - ps_lvbu:'★吕布', - ps_lvbu_prefix:'★', - pssheji:'射戟', - pssheji_info:'出牌阶段限一次。你可以将所有手牌当一张无距离限制的【杀】使用,然后当此【杀】对目标角色造成伤害后,你获得其装备区里的所有武器牌和坐骑牌。', - ps_jiaxu:'★贾诩', - ps_jiaxu_prefix:'★', - psqupo:'驱魄', - psqupo_info:'一名角色A的回合开始时,你可以将一张牌交给另一名其他角色B。若此牌为:黑色,当A使用【杀】指定不为B的角色为目标时,A失去1点体力;红色,当B于本回合下一次受到伤害时,B失去1点体力。', - psbaoquan:'保全', - psbaoquan_info:'当你受到伤害时,你可以弃置一张锦囊牌并防止此伤害。', + ps_guanyu: "★关羽", + ps_guanyu_prefix: "★", + pszhonghun: "忠魂", + pszhonghun_info: "当你使用或打出红色牌时,你可以亮出牌堆顶的一张牌。若此牌为红色,你获得之。", + ps2070_guojia: "★郭嘉", + ps2070_guojia_prefix: "★", + psquanmou: "全谋", + psquanmou_info: + "当其他角色使用锦囊牌结算结束后,若你是此牌目标,你可以弃置一张与此牌颜色相同的手牌并获得之。", + ps1059_guojia: "★郭嘉", + ps1059_guojia_prefix: "★", + psqizuo: "奇佐", + psqizuo_info: + "当你攻击范围内的角色造成或受到伤害时,你可以弃置一张牌并判定,若此牌颜色与结果相同,你可以令此伤害+1或-1。", + ps2063_zhaoyun: "★赵云", + ps2063_zhaoyun_prefix: "★", + psqijin: "七进", + psqijin_info: "摸牌阶段,你可以改为亮出牌堆顶的七张牌,并获得其中一种颜色的所有牌。", + psqichu: "七出", + psqichu_info: + "每回合限一次。当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌。若其中有此牌,你可以使用或打出之。", + pslongxin: "龙心", + pslongxin_info: "判定阶段开始时,你可以弃置一张装备牌,然后弃置你判定区里的一张牌。", + ps2080_zhouyu: "★周瑜", + ps2080_zhouyu_prefix: "★", + psshiyin: "识音", + psshiyin_info: + "①游戏开始时,你可以将一张手牌置于武将牌上,称为“杂音”牌。②出牌阶段开始时,你可以用一张手牌替换“杂音”牌。", + psquwu: "曲误", + psquwu_info: "锁定技。你不能使用或打出与“杂音”牌花色相同的牌,且这些牌对你无效。", + psliaozou: "聊奏", + psliaozou_info: "出牌阶段,你可以展示所有手牌,若其中没有与“杂音”牌花色相同的牌,你摸一张牌。", + ps1062_zhouyu: "★周瑜", + ps1062_zhouyu_prefix: "★", + psoldshiyin: "识音", + psoldshiyin_info: + "当你于回合内得到牌后,你可以展示之,然后根据你展示的牌包含的花色数令你本回合使用的下一张牌获得对应效果:不小于1,不能被响应;不小于2,造成的伤害+1;不小于3,使用时摸一张牌。", + ps_caozhi: "★曹植", + ps_caozhi_prefix: "★", + psliushang: "流殇", + psliushang_info: + "锁定技。①摸牌阶段,你改为摸X+1张牌,然后依次将一张手牌置于所有其他角色的武将牌上,称为“流殇”牌(X为场上角色数且至少为3)。②其他角色的准备阶段,其选择一项:1.获得其“流殇”牌,且当其于本回合对你造成伤害时,防止此伤害;2.将其“流殇”牌置入弃牌堆。", + psqibu: "七步", + psqibu_info: + "限定技。当你进入濒死状态时,你可以亮出牌堆顶的七张牌,回复等同于其中♥牌数的体力,并获得所有♣牌。", + ps_jin_simayi: "★司马懿", + ps_jin_simayi_prefix: "★", + psquanyi: "权奕", + psquanyi_info: + "①出牌阶段限一次。你可以与一名角色拼点,赢的角色根据所有拼点牌的花色执行以下效果:♥,其获得没赢的角色区域里的一张牌;♦其对没赢的角色造成1点伤害;♠,其失去1点体力;♣,其弃置两张牌。②当你拼点时,你可以选择牌堆顶的牌作为拼点牌。", + ps2067_zhaoyun: "武将传赵云", + ps2067_zhaoyun_prefix: "武将传", + pshuiqiang: "回枪", + pshuiqiang_info: "当你使用的【杀】被【闪】抵消后,你可以对其使用一张【杀】。", + pshuntu: "魂突", + pshuntu_info: "出牌阶段限一次。当你使用【杀】对目标角色造成伤害后,你可以对其使用一张【杀】。", + ps_caopi: "★曹丕", + ps_caopi_prefix: "★", + psjianwei: "僭位", + psjianwei_info: "限定技。回合开始时,你可以失去1点体力,然后与一名其他角色交换区域里的所有牌。", + ps2068_simayi: "★司马懿", + ps2068_simayi_prefix: "★", + pszhonghu: "冢虎", + pszhonghu_info: + "当一名角色于你的回合外死亡后,你可以结束此回合,然后令所有角色于其回合开始前跳过此回合直到你的回合开始前。", + ps_simayi: "★司马懿", + ps_simayi_prefix: "★", + pshuxiao: "虎啸", + pshuxiao_info: + "回合开始时,你可以判定。若结果为基本牌或普通锦囊牌,你于本回合内获得如下效果:你可以将与结果点数或花色相同的手牌当与判定牌牌名和属性相同的牌使用。", + ps_zhugeliang: "★诸葛亮", + ps_zhugeliang_prefix: "★", + psguanxing: "观星", + psguanxing_info: "准备阶段,你可以观看牌堆顶的五张牌,并将其以任意顺序置于牌堆项或牌堆底。", + pslongyin: "龙吟", + pslongyin_info: + "每回合限一次。你可以将任意张点数和为13的牌当做任意一张基本牌或普通锦囊牌使用或打出。", + ps2066_zhugeliang: "武将传诸葛亮", + ps2066_zhugeliang_prefix: "武将传", + pszhiji: "智激", + pszhiji_info: + "出牌阶段限一次。你可以弃置两张手牌并选择两名势力不同的角色,视为这两名角色依次视为对对方使用一张【杀】。", + psjiefeng: "借风", + psjiefeng_info: + "出牌阶段,你可以弃置两张手牌,然后亮出牌堆顶五张牌。若其中有至少两张红色牌,你视为使用一张【万箭齐发】。", + ps_machao: "★马超", + ps_machao_prefix: "★", + psweihou: "威侯", + psweihou_info: + "当你判定前,你可以亮出牌堆顶的两张牌,选择其中一张作为你的本次判定结果,然后将另一张置入弃牌堆。", + ps_lvbu: "★吕布", + ps_lvbu_prefix: "★", + pssheji: "射戟", + pssheji_info: + "出牌阶段限一次。你可以将所有手牌当一张无距离限制的【杀】使用,然后当此【杀】对目标角色造成伤害后,你获得其装备区里的所有武器牌和坐骑牌。", + ps_jiaxu: "★贾诩", + ps_jiaxu_prefix: "★", + psqupo: "驱魄", + psqupo_info: + "一名角色A的回合开始时,你可以将一张牌交给另一名其他角色B。若此牌为:黑色,当A使用【杀】指定不为B的角色为目标时,A失去1点体力;红色,当B于本回合下一次受到伤害时,B失去1点体力。", + psbaoquan: "保全", + psbaoquan_info: "当你受到伤害时,你可以弃置一张锦囊牌并防止此伤害。", //S特 - ps_shen_machao:'S特神马超', - ps_shen_machao_prefix:'S特神', - psshouli:'狩骊', - psshouli_info:'锁定技。①游戏开始时,所有角色依次选择一项:1.使用一张坐骑牌,然后摸一张牌;2.随机从游戏外的八张坐骑牌指示物中使用一张。②你可以将场上一张进攻坐骑当【杀】,防御坐骑当【闪】使用或打出,若此坐骑牌的拥有者不为你,则其非锁定技于本回合内失效。且当你或其于本回合内受到伤害时,此伤害+1且改为雷属性。', - pshengwu:'横骛', - pshengwu_info:'当你使用或打出牌时,若场上有该花色的装备牌,你可以弃置任意张该花色的手牌,然后摸X张牌(X为你弃置的牌数与场上与此牌花色相同的装备牌数之和)。', + ps_shen_machao: "S特神马超", + ps_shen_machao_prefix: "S特神", + psshouli: "狩骊", + psshouli_info: + "锁定技。①游戏开始时,所有角色依次选择一项:1.使用一张坐骑牌,然后摸一张牌;2.随机从游戏外的八张坐骑牌指示物中使用一张。②你可以将场上一张进攻坐骑当【杀】,防御坐骑当【闪】使用或打出,若此坐骑牌的拥有者不为你,则其非锁定技于本回合内失效。且当你或其于本回合内受到伤害时,此伤害+1且改为雷属性。", + pshengwu: "横骛", + pshengwu_info: + "当你使用或打出牌时,若场上有该花色的装备牌,你可以弃置任意张该花色的手牌,然后摸X张牌(X为你弃置的牌数与场上与此牌花色相同的装备牌数之和)。", //线下K系列木盒 - pk_sp_duyu:'K系列杜预', - pk_sp_duyu_prefix:'K系列', - pkwuku:'武库', - pkwuku_info:'锁定技。当有角色使用装备牌时,若你的“武库”数小于3,则你获得1枚“武库”。', - pksanchen:'三陈', - pksanchen_info:'觉醒技。结束阶段,若你的“武库”数大于2,则你加1点体力上限并回复1点体力,然后获得〖灭吴〗。', - pkmiewu:'灭吴', - pkmiewu2:'灭吴', - pkmiewu_info:'每回合限一次。你可移去1枚“武库”,视为使用或打出任意一张基本牌或普通锦囊牌,然后摸一张牌。', + pk_sp_duyu: "K系列杜预", + pk_sp_duyu_prefix: "K系列", + pkwuku: "武库", + pkwuku_info: "锁定技。当有角色使用装备牌时,若你的“武库”数小于3,则你获得1枚“武库”。", + pksanchen: "三陈", + pksanchen_info: + "觉醒技。结束阶段,若你的“武库”数大于2,则你加1点体力上限并回复1点体力,然后获得〖灭吴〗。", + pkmiewu: "灭吴", + pkmiewu2: "灭吴", + pkmiewu_info: + "每回合限一次。你可移去1枚“武库”,视为使用或打出任意一张基本牌或普通锦囊牌,然后摸一张牌。", //天书乱斗虚拟偶像 - vtb_xiaosha:'小杀', - vtbguisha:'瑰杀', - vtbguisha_info:'当其他角色使用【杀】时,你可以弃置一张牌令此【杀】不计入次数,且此【杀】对目标角色造成的伤害+1。', - vtbshuli:'淑丽', - vtbshuli_info:'每回合限两次。当其他角色使用【杀】造成伤害后,你可以与其各摸一张牌。', - vtb_xiaoshan:'小闪', - vtbshanwu:'闪舞', - vtbshanwu_info:'当其他角色成为【杀】的第一个目标时,你可以弃置一张【闪】,然后取消此【杀】的所有目标。', - vtbxianli:'娴丽', - vtbxianli_info:'每回合限两次。当你失去牌后,若其中有【闪】,你可以获得当前回合角色的一张牌。', - vtb_xiaotao:'小桃', - vtbtaoyan:'桃宴', - vtbtaoyan_info:'回合开始时,你可以令至多两名其他角色摸一张牌并于游戏外获得一张【桃】(共五张且均为♥6)。', - vtbyanli:'妍丽', - vtbyanli_info:'每轮限一次。一名角色于你的回合外进入濒死状态时,你可以令其回复至1点体力,然后其摸一张牌。', - vtb_xiaole:'小乐', - vtbleyu:'乐虞', - vtbleyu_info:'一名角色的回合开始时,你可以弃置三张牌令其判定。若结果不为♥,其跳过本回合的出牌阶段。', - vtbyuanli:'媛丽', - vtbyuanli_info:'一名角色跳过出牌阶段后,你可以与一名其他角色各摸一张牌。', - vtb_xiaojiu:'小酒', - vtbmeiniang:'美酿', - vtbmeiniang_info:'其他角色的出牌阶段开始时,你可以令其视为使用一张无次数限制且不计入次数的【酒】。', - vtbyaoli:'媱丽', - vtbyaoli_info:'其他角色于其出牌阶段内使用【酒】后,你可以令其于本回合内使用的下一张【杀】不能被响应且可以额外指定一个目标。', - old_machao:'J.SP马超', - old_machao_prefix:'J.SP', - jsp_caoren:'☆SP曹仁', - jsp_caoren_prefix:'☆SP', - jsp_ganfuren:'SP甘夫人', - jsp_ganfuren_prefix:'SP', - zhangliang:'SP张梁', - zhangliang_prefix:'SP', - ol_xinxianying:'将辛宪英', - ol_xinxianying_prefix:'将', - jiangqing:'战役篇蒋钦', - jiangqing_prefix:'战役篇', - tianfeng:'战役篇田丰', - tianfeng_prefix:'战役篇', - jiling:'战役篇纪灵', - jiling_prefix:'战役篇', - kongrong:'战役篇孔融', - kongrong_prefix:'战役篇', - mateng:'战役篇马腾', - mateng_prefix:'战役篇', + vtb_xiaosha: "小杀", + vtbguisha: "瑰杀", + vtbguisha_info: + "当其他角色使用【杀】时,你可以弃置一张牌令此【杀】不计入次数,且此【杀】对目标角色造成的伤害+1。", + vtbshuli: "淑丽", + vtbshuli_info: "每回合限两次。当其他角色使用【杀】造成伤害后,你可以与其各摸一张牌。", + vtb_xiaoshan: "小闪", + vtbshanwu: "闪舞", + vtbshanwu_info: + "当其他角色成为【杀】的第一个目标时,你可以弃置一张【闪】,然后取消此【杀】的所有目标。", + vtbxianli: "娴丽", + vtbxianli_info: "每回合限两次。当你失去牌后,若其中有【闪】,你可以获得当前回合角色的一张牌。", + vtb_xiaotao: "小桃", + vtbtaoyan: "桃宴", + vtbtaoyan_info: + "回合开始时,你可以令至多两名其他角色摸一张牌并于游戏外获得一张【桃】(共五张且均为♥6)。", + vtbyanli: "妍丽", + vtbyanli_info: + "每轮限一次。一名角色于你的回合外进入濒死状态时,你可以令其回复至1点体力,然后其摸一张牌。", + vtb_xiaole: "小乐", + vtbleyu: "乐虞", + vtbleyu_info: + "一名角色的回合开始时,你可以弃置三张牌令其判定。若结果不为♥,其跳过本回合的出牌阶段。", + vtbyuanli: "媛丽", + vtbyuanli_info: "一名角色跳过出牌阶段后,你可以与一名其他角色各摸一张牌。", + vtb_xiaojiu: "小酒", + vtbmeiniang: "美酿", + vtbmeiniang_info: + "其他角色的出牌阶段开始时,你可以令其视为使用一张无次数限制且不计入次数的【酒】。", + vtbyaoli: "媱丽", + vtbyaoli_info: + "其他角色于其出牌阶段内使用【酒】后,你可以令其于本回合内使用的下一张【杀】不能被响应且可以额外指定一个目标。", + old_machao: "J.SP马超", + old_machao_prefix: "J.SP", + jsp_caoren: "☆SP曹仁", + jsp_caoren_prefix: "☆SP", + jsp_ganfuren: "SP甘夫人", + jsp_ganfuren_prefix: "SP", + zhangliang: "SP张梁", + zhangliang_prefix: "SP", + ol_xinxianying: "将辛宪英", + ol_xinxianying_prefix: "将", + jiangqing: "战役篇蒋钦", + jiangqing_prefix: "战役篇", + tianfeng: "战役篇田丰", + tianfeng_prefix: "战役篇", + jiling: "战役篇纪灵", + jiling_prefix: "战役篇", + kongrong: "战役篇孔融", + kongrong_prefix: "战役篇", + mateng: "战役篇马腾", + mateng_prefix: "战役篇", + drag_guanyu: "龙关羽", + drag_guanyu_prefix: "龙", + drag_caoren: "龙曹仁", + drag_caoren_prefix: "龙", + drag_lvchang: "龙吕常", + drag_lvchang_prefix: "龙", + dragchaojue: "超绝", + dragchaojue_info: + "准备阶段,你可以弃置一张手牌,然后令所有其他角色本回合不能使用或打出此花色的牌,然后这些角色依次选择一项:①正面朝上交给你一张牌;②本回合非锁定技失效。", + dragjunshen: "军神", + dragjunshen_info: + "①你可以将一张红色牌当作【杀】使用或打出。②当你使用〖军神①〗转化的【杀】造成伤害时,你可以令受伤角色选择弃置装备区的所有牌或令此伤害+1。③你使用方片【杀】无距离限制,使用红桃【杀】可以额外选择一个目标。", + draglizhong: "厉众", + draglizhong_info: + "结束阶段,你可以以任意顺序选择执行任意项:①将任意张装备牌置入任意名角色的装备区;②令你或任意名装备区里有牌的角色各摸一张牌。然后本次成为〖厉众②〗的角色于本轮手牌上限+2且可以将装备区的牌当作【无懈可击】使用。", + dragjuesui: "玦碎", + dragjuesui_info: + "每名角色限一次,一名角色进入濒死状态时,你可以令其选择是否将体力值回复至1点并废除装备栏。若其选择是,则其本局游戏获得以下效果:你可以将一张黑色非基本牌当作无次数限制的【杀】使用或打出。", + dragjuwu: "拒武", + dragjuwu_info: "锁定技,攻击范围内至少包含三名角色的角色使用的无属性【杀】对你无效。", + dragshouxiang: "守襄", + dragshouxiang_info: + "摸牌阶段,你可以额外摸X张牌。若如此做,你跳过出牌阶段,且本回合的弃牌阶段开始时,你可以交给至多X名角色各一张手牌。(X为攻击范围内包含你的角色)", - offline_star:'桌游志·SP', - offline_sticker:'桌游志·贴纸', - offline_yijiang:'一将成名', - offline_luanwu:'文和乱武', - offline_yongjian:'用间篇', - offline_yongjian_prefix:'用间', - offline_feihongyingxue:'飞鸿映雪', - offline_piracyE:'官盗E系列·战役篇', - offline_piracyS:'官盗S系列', - offline_vtuber:'天书乱斗·虚拟偶像', - offline_piracyK:'官盗K系列', - offline_others:'线下其他系列', + offline_star: "桌游志·SP", + offline_sticker: "桌游志·贴纸", + offline_yijiang: "一将成名", + offline_luanwu: "文和乱武", + offline_yongjian: "用间篇", + offline_yongjian_prefix: "用间", + offline_feihongyingxue: "飞鸿映雪", + offline_piracyE: "官盗E系列·战役篇", + offline_piracyS: "官盗S系列", + offline_vtuber: "天书乱斗·虚拟偶像", + offline_piracyK: "官盗K系列", + offline_others: "线下其他系列", + offline_longyutao: "龙起襄樊", }, }; }); diff --git a/character/old.js b/character/old.js index 3da5443ee..aaf9d071f 100755 --- a/character/old.js +++ b/character/old.js @@ -1,1229 +1,1517 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'old', - connect:true, - characterSort:{ - old:{ - old_standard:['ol_yuanshu'], - old_shenhua:['old_shen_zhaoyun','old_caocao',"yuji","zhangjiao","old_zhugezhan","old_guanqiujian","xiahouyuan","weiyan","old_xiaoqiao","pangde","xuhuang",'junk_sunquan',"huangzhong","new_caoren",'old_chendao'], - old_refresh:["old_zhangfei","old_huatuo","old_zhaoyun","ol_huaxiong",'old_guanyu'], - old_yijiang1:["masu","xushu","xin_yujin","old_xusheng","old_lingtong","fazheng",'old_gaoshun','re_yujin'], - old_yijiang2:["old_zhonghui","madai",'old_handang','old_liubiao','oldre_liubiao','old_guanzhang','old_wangyi'], - old_yijiang3:["liru","old_zhuran","old_fuhuanghou","old_caochong"], - old_yijiang4:["old_caozhen","old_chenqun","old_zhuhuan",'old_caorui'], - old_yijiang5:["old_caoxiu","old_zhuzhi"], - old_yijiang67:["ol_zhangrang",'old_huanghao','old_liyan'], - old_sp:['old_shixie',"panfeng","old_wanglang","old_maliang","old_zhangxingcai","old_wangyun",'old_dingfeng','old_guanyinping'], - old_yingbian:['junk_simayi','old_yangyan','old_yangzhi'], - old_mobile:["old_caochun"], + name: "old", + connect: true, + characterSort: { + old: { + old_standard: ["ol_yuanshu"], + old_shenhua: [ + "old_shen_zhaoyun", + "old_caocao", + "yuji", + "zhangjiao", + "old_zhugezhan", + "old_guanqiujian", + "xiahouyuan", + "weiyan", + "old_xiaoqiao", + "pangde", + "xuhuang", + "junk_sunquan", + "huangzhong", + "new_caoren", + "old_chendao", + ], + old_refresh: ["old_zhangfei", "old_huatuo", "old_zhaoyun", "ol_huaxiong", "old_guanyu"], + old_yijiang1: [ + "masu", + "xushu", + "xin_yujin", + "old_xusheng", + "old_lingtong", + "fazheng", + "old_gaoshun", + "re_yujin", + ], + old_yijiang2: [ + "old_zhonghui", + "madai", + "old_handang", + "old_liubiao", + "oldre_liubiao", + "old_guanzhang", + "old_wangyi", + ], + old_yijiang3: ["liru", "old_zhuran", "old_fuhuanghou", "old_caochong"], + old_yijiang4: ["old_caozhen", "old_chenqun", "old_zhuhuan", "old_caorui"], + old_yijiang5: ["old_caoxiu", "old_zhuzhi"], + old_yijiang67: ["ol_zhangrang", "old_huanghao", "old_liyan"], + old_sp: [ + "old_shixie", + "panfeng", + "old_wanglang", + "old_maliang", + "old_zhangxingcai", + "old_wangyun", + "old_dingfeng", + "old_guanyinping", + ], + old_yingbian: ["junk_simayi", "old_yangyan", "old_yangzhi"], + old_mobile: ["old_caochun"], }, }, - character:{ - old_shixie:['male','qun',3,['biluan','lixia']], - panfeng:['male','qun',4,['kuangfu']], - old_shen_zhaoyun:['male','shen',2,['oldjuejing','oldlonghun'],['shu']], - old_guanyinping:['female','shu',3,['xueji_old','oldhuxiao','oldwuji']], - old_caocao:['male','shen',3,['junkguixin','feiying'],['die_audio']], - old_chendao:['male','shu',4,['drlt_wanglie']], - old_liyan:['male','shu',3,['duliang','fulin']], - old_guanzhang:['male','shu',4,['old_fuhun']], - new_caoren:['male','wei',4,['moon_jushou','jiewei']], - huangzhong:['male','shu',4,['liegong']], - junk_sunquan:['male','shen',4,['dili','yuheng'],['wei']], - old_dingfeng:['male','wu',4,['fenxun','duanbing']], - old_huanghao:['male','shu',3,['oldqinqing','oldhuisheng']], - oldre_liubiao:['male','qun',3,['zishou','zongshi']], - old_liubiao:['male','qun',4,['oldzishou','zongshi']], - old_gaoshun:['male','qun',4,['xianzhen','jinjiu']], - old_caorui:['male','wei',3,['huituo','oldmingjian','xingshuai'],['zhu']], - old_handang:['male','wu',4,['oldgongji','oldjiefan']], - old_yangzhi:['female','jin',3,['wanyi','maihuo']], - old_yangyan:['female','jin',3,['xuanbei','xianwan']], - madai:['male','shu',4,['mashu','oldqianxi']], - xuhuang:['male','wei',4,['gzduanliang']], - junk_simayi:['male','jin',3,['buchen','smyyingshi','xiongzhi','quanbian'],['hiddenSkill']], - fazheng:['male','shu',3,['enyuan','xuanhuo']], - ol_yuanshu:['male','qun',4,['wangzun','tongji']], - pangde:['male','qun',4,['mashu','mengjin']], - ol_huaxiong:["male","qun",6,["new_reyaowu"]], - old_wangyun:['male','qun',4,['wylianji','moucheng'],['clan:太原王氏']], - old_xiaoqiao:['female','wu',3,['tianxiang','hongyan']], - weiyan:['male','shu',4,['kuanggu']], - xiahouyuan:['male','wei',4,['shensu']], - old_zhangxingcai:['female','shu',3,['oldshenxian','qiangwu']], - old_fuhuanghou:['female','qun',3,['oldzhuikong','oldqiuyuan']], - old_caochong:['male','wei',3,['oldrenxin','oldchengxiang']], - yuji:['male','qun',3,['old_guhuo']], - zhangjiao:['male','qun',3,['leiji','guidao','huangtian'],['zhu']], - old_zhangfei:['male','shu',4,['new_repaoxiao','new_tishen']], - old_zhaoyun:['male','shu',4,['longdan','new_yajiao']], - old_huatuo:['male','qun',3,['jijiu','chulao']], - old_guanyu:['male','shu',4,['wusheng','yijue']], - old_caochun:['male','wei',4,['shanjia']], - masu:['male','shu',3,['xinzhan','huilei']], - xushu:['male','shu',3,['xswuyan','jujian'],['border:wei']], - liru:['male','qun',3,['juece','mieji','fencheng']], - xin_yujin:['male','wei',4,['jieyue']], + character: { + old_shixie: ["male", "qun", 3, ["biluan", "lixia"]], + panfeng: ["male", "qun", 4, ["kuangfu"]], + old_shen_zhaoyun: ["male", "shen", 2, ["oldjuejing", "oldlonghun"], ["shu"]], + old_guanyinping: ["female", "shu", 3, ["xueji_old", "oldhuxiao", "oldwuji"]], + old_caocao: ["male", "shen", 3, ["junkguixin", "feiying"], ["die_audio"]], + old_chendao: ["male", "shu", 4, ["drlt_wanglie"]], + old_liyan: ["male", "shu", 3, ["duliang", "fulin"]], + old_guanzhang: ["male", "shu", 4, ["old_fuhun"]], + new_caoren: ["male", "wei", 4, ["moon_jushou", "jiewei"]], + huangzhong: ["male", "shu", 4, ["liegong"]], + junk_sunquan: ["male", "shen", 4, ["dili", "yuheng"], ["wei"]], + old_dingfeng: ["male", "wu", 4, ["fenxun", "duanbing"]], + old_huanghao: ["male", "shu", 3, ["oldqinqing", "oldhuisheng"]], + oldre_liubiao: ["male", "qun", 3, ["zishou", "zongshi"]], + old_liubiao: ["male", "qun", 4, ["oldzishou", "zongshi"]], + old_gaoshun: ["male", "qun", 4, ["xianzhen", "jinjiu"]], + old_caorui: ["male", "wei", 3, ["huituo", "oldmingjian", "xingshuai"], ["zhu"]], + old_handang: ["male", "wu", 4, ["oldgongji", "oldjiefan"]], + old_yangzhi: ["female", "jin", 3, ["wanyi", "maihuo"]], + old_yangyan: ["female", "jin", 3, ["xuanbei", "xianwan"]], + madai: ["male", "shu", 4, ["mashu", "oldqianxi"]], + xuhuang: ["male", "wei", 4, ["gzduanliang"]], + junk_simayi: [ + "male", + "jin", + 3, + ["buchen", "smyyingshi", "xiongzhi", "quanbian"], + ["hiddenSkill"], + ], + fazheng: ["male", "shu", 3, ["enyuan", "xuanhuo"]], + ol_yuanshu: ["male", "qun", 4, ["wangzun", "tongji"]], + pangde: ["male", "qun", 4, ["mashu", "mengjin"]], + ol_huaxiong: ["male", "qun", 6, ["new_reyaowu"]], + old_wangyun: ["male", "qun", 4, ["wylianji", "moucheng"], ["clan:太原王氏"]], + old_xiaoqiao: ["female", "wu", 3, ["tianxiang", "hongyan"]], + weiyan: ["male", "shu", 4, ["kuanggu"]], + xiahouyuan: ["male", "wei", 4, ["shensu"]], + old_zhangxingcai: ["female", "shu", 3, ["oldshenxian", "qiangwu"]], + old_fuhuanghou: ["female", "qun", 3, ["oldzhuikong", "oldqiuyuan"]], + old_caochong: ["male", "wei", 3, ["oldrenxin", "oldchengxiang"]], + yuji: ["male", "qun", 3, ["old_guhuo"]], + zhangjiao: ["male", "qun", 3, ["leiji", "guidao", "huangtian"], ["zhu"]], + old_zhangfei: ["male", "shu", 4, ["new_repaoxiao", "new_tishen"]], + old_zhaoyun: ["male", "shu", 4, ["longdan", "new_yajiao"]], + old_huatuo: ["male", "qun", 3, ["jijiu", "chulao"]], + old_guanyu: ["male", "shu", 4, ["wusheng", "yijue"]], + old_caochun: ["male", "wei", 4, ["shanjia"]], + masu: ["male", "shu", 3, ["xinzhan", "huilei"]], + xushu: ["male", "shu", 3, ["xswuyan", "jujian"], ["border:wei"]], + liru: ["male", "qun", 3, ["juece", "mieji", "fencheng"]], + xin_yujin: ["male", "wei", 4, ["jieyue"]], //lusu:['male','wu',3,['haoshi','dimeng']], //yuanshao:['male','qun',4,['luanji','xueyi'],['zhu']], - old_zhonghui:['male','wei',3,['zzhenggong','zquanji','zbaijiang'],['clan:颍川钟氏']], - old_xusheng:['male','wu',4,['pojun']], - old_zhuran:['male','wu',4,['olddanshou']], - old_lingtong:['male','wu',4,['oldxuanfeng']], - old_caoxiu:['male','wei',4,['taoxi']], - old_caozhen:['male','wei',4,['sidi']], - old_maliang:['male','shu',3,['xiemu','naman']], - old_chenqun:['male','wei',3,['dingpin','oldfaen']], - old_zhuhuan:['male','wu',4,['youdi']], - old_zhuzhi:['male','wu',4,['anguo']], + old_zhonghui: ["male", "wei", 3, ["zzhenggong", "zquanji", "zbaijiang"], ["clan:颍川钟氏"]], + old_xusheng: ["male", "wu", 4, ["pojun"]], + old_zhuran: ["male", "wu", 4, ["olddanshou"]], + old_lingtong: ["male", "wu", 4, ["oldxuanfeng"]], + old_caoxiu: ["male", "wei", 4, ["taoxi"]], + old_caozhen: ["male", "wei", 4, ["sidi"]], + old_maliang: ["male", "shu", 3, ["xiemu", "naman"]], + old_chenqun: ["male", "wei", 3, ["dingpin", "oldfaen"]], + old_zhuhuan: ["male", "wu", 4, ["youdi"]], + old_zhuzhi: ["male", "wu", 4, ["anguo"]], - old_zhugezhan:["male","shu",3,["old_zuilun","old_fuyin"]], - ol_zhangrang:['male','qun',3,['xintaoluan'],['sex:male_castrated']], + old_zhugezhan: ["male", "shu", 3, ["old_zuilun", "old_fuyin"]], + ol_zhangrang: ["male", "qun", 3, ["xintaoluan"], ["sex:male_castrated"]], //ol_manchong:['male','wei',3,['yuce','junxing']], - old_guanqiujian:["male","wei",4,["drlt_zhenrong","drlt_hongju"],[]], - old_wanglang:['male','wei',3,['gushe','jici']], - old_wangyi:['female','wei',3,['oldzhenlie','oldmiji']], - re_yujin:['male','wei',4,['yizhong']], + old_guanqiujian: ["male", "wei", 4, ["drlt_zhenrong", "drlt_hongju"], []], + old_wanglang: ["male", "wei", 3, ["gushe", "jici"]], + old_wangyi: ["female", "wei", 3, ["oldzhenlie", "oldmiji"]], + re_yujin: ["male", "wei", 4, ["yizhong"]], }, - skill:{ + skill: { //山包初版神赵 - oldjuejing:{ - audio:'xinjuejing', - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ - return !event.numFixed&&player.getHp()num+2, + mod: { + maxHandcard: (player, num) => num + 2, }, }, - oldlonghun:{ - audio:'relonghun', - inherit:'xinlonghun', - prompt:()=>`将${get.cnNumber(Math.max(1,get.player().getHp()))}张♦牌当做杀,♥牌当做桃,♣牌当做闪,♠牌当做无懈可击使用或打出`, - selectCard:()=>Math.max(1,get.player().getHp()), - complexCard:true, - precontent:function(){ + oldlonghun: { + audio: "relonghun", + inherit: "xinlonghun", + prompt: () => + `将${get.cnNumber( + Math.max(1, get.player().getHp()) + )}张♦牌当做杀,♥牌当做桃,♣牌当做闪,♠牌当做无懈可击使用或打出`, + selectCard: () => Math.max(1, get.player().getHp()), + complexCard: true, + precontent: function () { delete event.result.skill; - player.logSkill('oldlonghun'); + player.logSkill("oldlonghun"); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { var name; - switch(tag){ - case 'respondSha':name='diamond';break; - case 'respondShan':name='club';break; - case 'save':name='heart';break; + switch (tag) { + case "respondSha": + name = "diamond"; + break; + case "respondShan": + name = "club"; + break; + case "save": + name = "heart"; + break; } - if(!player.countCards('hes',{suit:name})) return false; + if (!player.countCards("hes", { suit: name })) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao']; - var map={sha:'diamond',tao:'heart'} - for(var i=0;i=Math.max(1,player.getHp())&&player.getUseValue({name:name,nature:name=='sha'?'fire':null})>0){ - var temp=get.order({name:name,nature:name=='sha'?'fire':null}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao"]; + var map = { sha: "diamond", tao: "heart" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hes", function (card) { + return ( + (name != "sha" || get.value(card) < 5) && + get.suit(card, player) == map[name] + ); + }) >= Math.max(1, player.getHp()) && + player.getUseValue({ + name: name, + nature: name == "sha" ? "fire" : null, + }) > 0 + ) { + var temp = get.order({ + name: name, + nature: name == "sha" ? "fire" : null, + }); + if (temp > max) max = temp; } } - max/=1.1; + max /= 1.1; return max; } return 2; }, }, - hiddenCard:function(player,name){ - if(name=='wuxie'&&_status.connectMode&&player.countCards('hes')>0) return true; - if(name=='wuxie') return player.countCards('hes',{suit:'spade'})>=Math.max(1,get.player().getHp()); - if(name=='tao') return player.countCards('hes',{suit:'heart'})>=Math.max(1,get.player().getHp()); + hiddenCard: function (player, name) { + if (name == "wuxie" && _status.connectMode && player.countCards("hes") > 0) return true; + if (name == "wuxie") + return ( + player.countCards("hes", { suit: "spade" }) >= Math.max(1, get.player().getHp()) + ); + if (name == "tao") + return ( + player.countCards("hes", { suit: "heart" }) >= Math.max(1, get.player().getHp()) + ); }, }, //魏武帝 - junkguixin:{ - init:function(){ - if(!_status.junkguixin){ - _status.junkguixin=[]; - if(!_status.characterlist){ + junkguixin: { + forbid: ["guozhan"], + init: function () { + if (!_status.junkguixin) { + _status.junkguixin = []; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } - for(const name of _status.characterlist){ - if(!lib.character[name][3]) continue; - _status.junkguixin.addArray(lib.character[name][3].filter(skill=>{ - var info=get.info(skill); - return info&&info.zhuSkill&&(!info.ai||!info.ai.combo); - })); + for (const name of _status.characterlist) { + if (!lib.character[name][3]) continue; + _status.junkguixin.addArray( + lib.character[name][3].filter((skill) => { + var info = get.info(skill); + return info && info.zhuSkill && (!info.ai || !info.ai.combo); + }) + ); } } }, - unique:true, - audio:'guixin', - trigger:{player:'phaseEnd'}, - direct:true, - content:function(){ - 'step 0' - var controls=['获得技能','修改势力','cancel2']; - if(!_status.junkguixin.some(skill=>!player.hasSkill(skill,null,false,false))) controls.shift(); - player.chooseControl(controls).set('prompt',get.prompt2('junkguixin')).set('ai',()=>_status.event.controls.length==3?'获得技能':'cancel2'); - 'step 1' - if(result.control!='cancel2'){ - var next=game.createEvent('junkguixinx'); - next.player=player; - next.setContent(lib.skill.junkguixin['content_'+result.control]); + unique: true, + audio: "guixin", + trigger: { player: "phaseEnd" }, + direct: true, + content: function () { + "step 0"; + var controls = ["获得技能", "修改势力", "cancel2"]; + if (!_status.junkguixin.some((skill) => !player.hasSkill(skill, null, false, false))) + controls.shift(); + player + .chooseControl(controls) + .set("prompt", get.prompt2("junkguixin")) + .set("ai", () => (_status.event.controls.length == 3 ? "获得技能" : "cancel2")); + "step 1"; + if (result.control != "cancel2") { + var next = game.createEvent("junkguixinx"); + next.player = player; + next.setContent(lib.skill.junkguixin["content_" + result.control]); } }, - content_获得技能:function(){ - 'step 0' - var list=_status.junkguixin.slice().filter(skill=>!player.hasSkill(skill,null,false,false)); - if(!list.length){event.finish();return;} - list=list.map(skill=>{ + content_获得技能: function () { + "step 0"; + var list = _status.junkguixin + .slice() + .filter((skill) => !player.hasSkill(skill, null, false, false)); + if (!list.length) { + event.finish(); + return; + } + list = list.map((skill) => { return [ skill, - '', + '", ]; }); - player.chooseButton([ - '归心:选择获得一个主公技', - [list,'textbutton'], - ],true).set('ai',button=>1+Math.random()); - 'step 1' - if(result.bool){ - player.logSkill('junkguixin'); + player + .chooseButton(["归心:选择获得一个主公技", [list, "textbutton"]], true) + .set("ai", (button) => 1 + Math.random()); + "step 1"; + if (result.bool) { + player.logSkill("junkguixin"); player.addSkills(result.links[0]); } }, - content_修改势力:function(){ - 'step 0' - player.chooseTarget('请选择【归心】的目标','更改一名其他角色的势力',lib.filter.notMe,true).set('ai',target=>1+Math.random()); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('junkguixin',target); - var list=lib.group.slice(); - list.removeArray(['shen',target.group]); - player.chooseControl(list).set('prompt','请选择'+get.translation(target)+'变更的势力').set('ai',()=>_status.event.controls.randomGet()); - } - else event.finish(); - 'step 2' - if(result.control){ - player.popup(get.translation(result.control+'2')); + content_修改势力: function () { + "step 0"; + player + .chooseTarget( + "请选择【归心】的目标", + "更改一名其他角色的势力", + lib.filter.notMe, + true + ) + .set("ai", (target) => 1 + Math.random()); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("junkguixin", target); + var list = lib.group.slice(); + list.removeArray(["shen", target.group]); + player + .chooseControl(list) + .set("prompt", "请选择" + get.translation(target) + "变更的势力") + .set("ai", () => _status.event.controls.randomGet()); + } else event.finish(); + "step 2"; + if (result.control) { + player.popup(get.translation(result.control + "2")); target.changeGroup(result.control); } }, }, - oldqinqing:{ - audio:'qinqing', - mode:['identity','versus'], - available:function(mode){ - if(mode=='versus'&&_status.mode!='four') return false; - if(mode=='identity'&&_status.mode=='purple') return false; + oldqinqing: { + audio: "qinqing", + mode: ["identity", "versus"], + available: function (mode) { + if (mode == "versus" && _status.mode != "four") return false; + if (mode == "identity" && _status.mode == "purple") return false; }, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - var zhu=get.zhu(player); - if(!zhu||!zhu.isZhu) return false; - return game.hasPlayer(function(current){ - return current!=zhu&¤t!=player&¤t.inRange(zhu); + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + var zhu = get.zhu(player); + if (!zhu || !zhu.isZhu) return false; + return game.hasPlayer(function (current) { + return current != zhu && current != player && current.inRange(zhu); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('dcqinqing'),function(card,player,target){ - var zhu=get.zhu(player); - return target!=player&&target.inRange(zhu); - }).set('ai',function(target){ - var zhu=get.zhu(player); - var he=target.countCards('he'); - if(get.attitude(_status.event.player,target)>0){ - if(target.countCards('h')>zhu.countCards('h')+1) return 0.1; - } - else{ - if(he>zhu.countCards('h')+1) return 2; - if(he>0) return 1; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dcqinqing',target); - if(target.countDiscardableCards(player,'he')) player.discardPlayerCard(target,'he',true); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("dcqinqing"), function (card, player, target) { + var zhu = get.zhu(player); + return target != player && target.inRange(zhu); + }) + .set("ai", function (target) { + var zhu = get.zhu(player); + var he = target.countCards("he"); + if (get.attitude(_status.event.player, target) > 0) { + if (target.countCards("h") > zhu.countCards("h") + 1) return 0.1; + } else { + if (he > zhu.countCards("h") + 1) return 2; + if (he > 0) return 1; + } + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dcqinqing", target); + if (target.countDiscardableCards(player, "he")) + player.discardPlayerCard(target, "he", true); target.draw(); - } - else{ + } else { event.finish(); } - 'step 2' - var zhu=get.zhu(player); - if(zhu&&zhu.isIn()){ - if(target.countCards('h')>zhu.countCards('h')) player.draw(); + "step 2"; + var zhu = get.zhu(player); + if (zhu && zhu.isIn()) { + if (target.countCards("h") > zhu.countCards("h")) player.draw(); } - } + }, }, - oldhuisheng:{ - audio:'huisheng', - trigger:{player:'damageBegin4'}, - direct:true, - filter:function(event,player){ - if(!player.countCards('he')) return false; - if(!event.source||event.source==player||!event.source.isIn()) return false; - if(player.storage.oldhuisheng&&player.storage.oldhuisheng.includes(event.source)) return false; + oldhuisheng: { + audio: "huisheng", + trigger: { player: "damageBegin4" }, + direct: true, + filter: function (event, player) { + if (!player.countCards("he")) return false; + if (!event.source || event.source == player || !event.source.isIn()) return false; + if (player.storage.oldhuisheng && player.storage.oldhuisheng.includes(event.source)) + return false; return true; }, - init:function(player){ - if(player.storage.oldhuisheng) player.storage.oldhuisheng=[]; + init: function (player) { + if (player.storage.oldhuisheng) player.storage.oldhuisheng = []; }, - content:function(){ - 'step 0' - if(!player.storage.oldhuisheng) player.storage.oldhuisheng=[]; + content: function () { + "step 0"; + if (!player.storage.oldhuisheng) player.storage.oldhuisheng = []; player.storage.oldhuisheng.push(trigger.source); - var att=(get.attitude(player,trigger.source)>0); - var goon=false; - if(player.hp==1){ - goon=true; - } - else{ - var he=player.getCards('he'); - var num=0; - for(var i=0;i 0; + var goon = false; + if (player.hp == 1) { + goon = true; + } else { + var he = player.getCards("he"); + var num = 0; + for (var i = 0; i < he.length; i++) { + if (get.value(he[i]) < 8) { num++; - if(num>=2){ - goon=true;break; + if (num >= 2) { + goon = true; + break; } } } } - player.chooseCard('he',[1,player.countCards('he')],get.prompt2('oldhuisheng',trigger.source)).set('ai',function(card){ - if(_status.event.att){ - return 10-get.value(card); - } - if(_status.event.goon){ - return 8-get.value(card); - } - if(!ui.selected.cards.length){ - return 7-get.value(card); - } - return 0; - }).set('goon',goon).set('att',att); - 'step 1' - if(result.bool){ - player.logSkill('oldhuisheng',trigger.source); - game.delay(); - event.num=result.cards.length; - var goon=false; - if(event.num>2||get.attitude(trigger.source,player)>=0){ - goon=true; - } - var forced=false; - var str='获得其中一张牌并防止伤害'; - if(trigger.source.countCards('he') 2 || get.attitude(trigger.source, player) >= 0) { + goon = true; + } + var forced = false; + var str = "获得其中一张牌并防止伤害"; + if (trigger.source.countCards("he") < event.num) { + forced = true; + } else { + str += ",或取消并弃置" + get.cnNumber(result.cards.length) + "张牌"; + } + trigger.source + .chooseButton([str, result.cards], forced) + .set("ai", function (button) { + if (_status.event.goon) { + return get.value(button.link); + } + return get.value(button.link) - 8; + }) + .set("goon", goon); + } else { event.finish(); } - 'step 2' - if(result.bool){ - var card=result.links[0]; - trigger.source.gain(card,player,'giveAuto','bySelf'); + "step 2"; + if (result.bool) { + var card = result.links[0]; + trigger.source.gain(card, player, "giveAuto", "bySelf"); trigger.cancel(); + } else { + trigger.source.chooseToDiscard(event.num, true, "he"); } - else{ - trigger.source.chooseToDiscard(event.num,true,'he'); - } - } + }, }, - oldzishou:{ - audio:'zishou', - audioname:['re_liubiao'], - trigger:{player:'phaseDrawBegin2'}, - check:function(event,player){ - return (player.countCards('h')<=2&&player.getDamagedHp()>=2)||player.skipList.includes('phaseUse'); + oldzishou: { + audio: "zishou", + audioname: ["re_liubiao"], + trigger: { player: "phaseDrawBegin2" }, + check: function (event, player) { + return ( + (player.countCards("h") <= 2 && player.getDamagedHp() >= 2) || + player.skipList.includes("phaseUse") + ); }, - filter:function(event,player){ - return !event.numFixed&&player.isDamaged(); + filter: function (event, player) { + return !event.numFixed && player.isDamaged(); }, - content:function(){ - trigger.num+=player.getDamagedHp(); - player.skip('phaseUse'); + content: function () { + trigger.num += player.getDamagedHp(); + player.skip("phaseUse"); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - oldgongji:{ - audio:'gongji', - enable:['chooseToUse','chooseToRespond'], - locked:false, - filterCard:{type:'equip'}, - position:'hes', - viewAs:{ - name:'sha', - storage:{oldgongji:true} + oldgongji: { + audio: "gongji", + enable: ["chooseToUse", "chooseToRespond"], + locked: false, + filterCard: { type: "equip" }, + position: "hes", + viewAs: { + name: "sha", + storage: { oldgongji: true }, }, - viewAsFilter:function(player){ - if(!player.countCards('hes',{type:'equip'})) return false; + viewAsFilter: function (player) { + if (!player.countCards("hes", { type: "equip" })) return false; }, - prompt:'将一张装备牌当无距离限制的【杀】使用或打出', - check:function(card){ - var val=get.value(card); - if(_status.event.name=='chooseToRespond') return 1/Math.max(0.1,val); - return 5-val; + prompt: "将一张装备牌当无距离限制的【杀】使用或打出", + check: function (card) { + var val = get.value(card); + if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val); + return 5 - val; }, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.oldgongji) return true; + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.oldgongji) return true; }, }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - if(!player.countCards('hes',{type:'equip'})) return false; + ai: { + respondSha: true, + skillTagFilter: function (player) { + if (!player.countCards("hes", { type: "equip" })) return false; }, }, }, - oldjiefan:{ - audio:'jiefan', - enable:'chooseToUse', - filter:function(event,player){ - return event.type=='dying'&&_status.currentPhase&&_status.currentPhase.isIn(); + oldjiefan: { + audio: "jiefan", + enable: "chooseToUse", + filter: function (event, player) { + return event.type == "dying" && _status.currentPhase && _status.currentPhase.isIn(); }, - direct:true, - content:function(){ - player.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },get.prompt2('oldjiefan')).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.currentPhase&&!ui.selected.targets.includes(_status.currentPhase)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('logSkill','oldjiefan').set('oncard',function(){ - _status.event.player.addTempSkill('oldjiefan_recover'); - }).set('custom',{ - add:{}, - replace:{ - window:()=>{ - ui.click.cancel(); - } - }, - }); + direct: true, + content: function () { + player + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, get.prompt2("oldjiefan")) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.currentPhase && + !ui.selected.targets.includes(_status.currentPhase) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("logSkill", "oldjiefan") + .set("oncard", function () { + _status.event.player.addTempSkill("oldjiefan_recover"); + }) + .set("custom", { + add: {}, + replace: { + window: () => { + ui.click.cancel(); + }, + }, + }); }, - ai:{ - save:true, - order:3, - result:{player:1} + ai: { + save: true, + order: 3, + result: { player: 1 }, }, - subSkill:{ - recover:{ + subSkill: { + recover: { // audio:'jiefan', - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return event.getParent(4).name=='oldjiefan'; + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return event.getParent(4).name == "oldjiefan"; }, - forced:true, - popup:false, - charlotte:true, - content:function(){ + forced: true, + popup: false, + charlotte: true, + content: function () { trigger.cancel(); - var evt=event.getParent('_save'); - var card={name:'tao',isCard:true}; - if(evt&&evt.dying&&player.canUse(card,evt.dying)){ - player.useCard(card,evt.dying,'oldjiefan_recover'); + var evt = event.getParent("_save"); + var card = { name: "tao", isCard: true }; + if (evt && evt.dying && player.canUse(card, evt.dying)) { + player.useCard(card, evt.dying, "oldjiefan_recover"); } - } - } - } - }, - oldmingjian:{ - audio:'mingjian', - trigger:{player:'phaseUseBefore'}, - filter:function(event,player){ - return player.countCards('h'); + }, + }, }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('oldmingjian'),'跳过出牌阶段并将所有手牌交给一名其他角色,你结束此回合,然后其于此回合后获得一个额外的出牌阶段',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) return 0.01*att; - if(player.countCards('h')==player.countCards('h','du')) return -att; - if(target.hasJudge('lebu')) att*=1.25; - if(get.attitude(player,target)>3){ - var basis=get.threaten(target)*att; - if(player==get.zhu(player)&&player.hp<=2&&player.countCards('h','shan')&&!game.hasPlayer(function(current){ - return get.attitude(current,player)>3&¤t.countCards('h','tao')>0; - })) return 0; - if(target.countCards('h')+player.countCards('h')>target.hp+2) return basis*0.8; - return basis; - } - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('oldmingjian',target); - player.give(player.getCards('h'),target); + }, + oldmingjian: { + audio: "mingjian", + trigger: { player: "phaseUseBefore" }, + filter: function (event, player) { + return player.countCards("h"); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("oldmingjian"), + "跳过出牌阶段并将所有手牌交给一名其他角色,你结束此回合,然后其于此回合后获得一个额外的出牌阶段", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) return 0.01 * att; + if (player.countCards("h") == player.countCards("h", "du")) return -att; + if (target.hasJudge("lebu")) att *= 1.25; + if (get.attitude(player, target) > 3) { + var basis = get.threaten(target) * att; + if ( + player == get.zhu(player) && + player.hp <= 2 && + player.countCards("h", "shan") && + !game.hasPlayer(function (current) { + return ( + get.attitude(current, player) > 3 && + current.countCards("h", "tao") > 0 + ); + }) + ) + return 0; + if (target.countCards("h") + player.countCards("h") > target.hp + 2) + return basis * 0.8; + return basis; + } + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("oldmingjian", target); + player.give(player.getCards("h"), target); trigger.cancel(); - } - else event.finish(); - 'step 2' - var evt=trigger.getParent('phase'); - if(evt){ - game.log(player,'结束了回合'); + } else event.finish(); + "step 2"; + var evt = trigger.getParent("phase"); + if (evt) { + game.log(player, "结束了回合"); evt.finish(); } - var next=target.insertPhase(); - next._noTurnOver=true; - next.phaseList=['phaseUse']; + var next = target.insertPhase(); + next._noTurnOver = true; + next.phaseList = ["phaseUse"]; //next.setContent(lib.skill.oldmingjian.phase); }, - phase:function(){ - 'step 0' + phase: function () { + "step 0"; player.phaseUse(); - 'step 1' - game.broadcastAll(function(){ - if(ui.tempnowuxie){ + "step 1"; + game.broadcastAll(function () { + if (ui.tempnowuxie) { ui.tempnowuxie.close(); delete ui.tempnowuxie; } }); }, }, - oldshenxian:{ - audio:'shenxian', - inherit:'shenxian', + oldshenxian: { + audio: "shenxian", + inherit: "shenxian", }, - old_guhuo:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - return (lib.inpile.includes(name)&&player.countCards('hs')>0); + old_guhuo: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + return lib.inpile.includes(name) && player.countCards("hs") > 0; }, - filter:function(event,player){ - if(!player.countCards('hs')) return false; - for(var i of lib.inpile){ - var type=get.type(i); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) return true; + filter: function (event, player) { + if (!player.countCards("hs")) return false; + for (var i of lib.inpile) { + var type = get.type(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of lib.inpile){ - if(event.type!='phase') if(!event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) continue; - var type=get.type(i); - if(type=='basic'||type=='trick') list.push([type,'',i]); - if(i=='sha'){ - if(event.type!='phase') if(!event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) continue; - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of lib.inpile) { + if (event.type != "phase") + if (!event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event)) + continue; + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); + if (i == "sha") { + if (event.type != "phase") + if ( + !event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + continue; + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } - return ui.create.dialog('蛊惑',[list,'vcard']); + return ui.create.dialog("蛊惑", [list, "vcard"]); }, - check:function(button){ - var player=_status.event.player; - var order=Math.max(0,get.order(card)+1); - var enemyNum=game.countPlayer(function(current){ - return current!=player&&(get.realAttitude||get.attitude)(current,player)<0&¤t.hp>0; + check: function (button) { + var player = _status.event.player; + var order = Math.max(0, get.order(card) + 1); + var enemyNum = game.countPlayer(function (current) { + return ( + current != player && + (get.realAttitude || get.attitude)(current, player) < 0 && + current.hp > 0 + ); }); - var card={name:button.link[2],nature:button.link[3]}; - if(player.isDying()&&!player.hasCard(function(cardx){ - if(get.suit(cardx)!='heart') return false; - var mod2=game.checkMod(cardx,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(cardx,player,player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(cardx).savable; - if(typeof savable=='function') savable=savable(card,player,player); - return savable; - },'hs')){ - if(!player.getStorage('old_guhuo_cheated').includes(card.name+card.nature)&&Math.random()<0.4) return 1; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + player.isDying() && + !player.hasCard(function (cardx) { + if (get.suit(cardx) != "heart") return false; + var mod2 = game.checkMod(cardx, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + cardx, + player, + player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(cardx).savable; + if (typeof savable == "function") savable = savable(card, player, player); + return savable; + }, "hs") + ) { + if ( + !player.getStorage("old_guhuo_cheated").includes(card.name + card.nature) && + Math.random() < 0.4 + ) + return 1; return 0; } - var val=_status.event.getParent().type=='phase'?player.getUseValue(card):1; - if(player.getStorage('old_guhuo_cheated').includes(card.name+card.nature)&&!player.hasCard(function(cardx){ - if(card.name==cardx.name){ - if(card.name!='sha') return true; - return get.is.sameNature(card,cardx); - } - return false; - },'hs')&&Math.random()<0.7) return 0; - if(val<=0) return 0; - if(enemyNum){ - if(!player.hasCard(function(cardx){ - if(card.name==cardx.name){ - if(card.name!='sha') return true; - return get.is.sameNature(card,cardx); + var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; + if ( + player.getStorage("old_guhuo_cheated").includes(card.name + card.nature) && + !player.hasCard(function (cardx) { + if (card.name == cardx.name) { + if (card.name != "sha") return true; + return get.is.sameNature(card, cardx); } return false; - },'hs')){ - if(get.value(card,player,'raw')<6) return Math.sqrt(val)*(0.25+Math.random()/1.5); - if(enemyNum<=2) return Math.sqrt(val)/1.5+order*10; + }, "hs") && + Math.random() < 0.7 + ) + return 0; + if (val <= 0) return 0; + if (enemyNum) { + if ( + !player.hasCard(function (cardx) { + if (card.name == cardx.name) { + if (card.name != "sha") return true; + return get.is.sameNature(card, cardx); + } + return false; + }, "hs") + ) { + if (get.value(card, player, "raw") < 6) + return Math.sqrt(val) * (0.25 + Math.random() / 1.5); + if (enemyNum <= 2) return Math.sqrt(val) / 1.5 + order * 10; return 0; } - return 3*val+order*10; + return 3 * val + order * 10; } - return val+order*10; + return val + order * 10; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:function(card,player,target){ - var result=true; - var suit=card.suit,number=card.number; - card.suit='none';card.number=null; - var mod=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod!='unchanged') result=mod; - card.suit=suit;card.number=number; + filterCard: function (card, player, target) { + var result = true; + var suit = card.suit, + number = card.number; + card.suit = "none"; + card.number = null; + var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod != "unchanged") result = mod; + card.suit = suit; + card.number = number; return result; }, - selectCard:1, - position:'hs', - ignoreMod:true, - aiUse:Math.random(), - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null + selectCard: 1, + position: "hs", + ignoreMod: true, + aiUse: Math.random(), + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, }, - ai1:function(card){ - var player=_status.event.player; - var enemyNum=game.countPlayer(function(current){ - return current!=player&&(get.realAttitude||get.attitude)(current,player)<0&¤t.hp>0; + ai1: function (card) { + var player = _status.event.player; + var enemyNum = game.countPlayer(function (current) { + return ( + current != player && + (get.realAttitude || get.attitude)(current, player) < 0 && + current.hp > 0 + ); }); - var cardx=lib.skill.old_guhuo_backup.viewAs; - if(enemyNum){ - if(card.name==cardx.name&&(card.name!='sha'||get.is.sameNature(card,cardx))||player.getStorage('old_guhuo_cheated').includes(card.name+card.nature)) return (get.suit(card)=='heart'?8:4)+Math.random()*3; - else if(lib.skill.old_guhuo_backup.aiUse<0.5&&!player.isDying()) return 0; + var cardx = lib.skill.old_guhuo_backup.viewAs; + if (enemyNum) { + if ( + (card.name == cardx.name && + (card.name != "sha" || get.is.sameNature(card, cardx))) || + player + .getStorage("old_guhuo_cheated") + .includes(card.name + card.nature) + ) + return (get.suit(card) == "heart" ? 8 : 4) + Math.random() * 3; + else if (lib.skill.old_guhuo_backup.aiUse < 0.5 && !player.isDying()) + return 0; } - return get.value(cardx)-get.value(card); + return get.value(cardx) - get.value(card); }, - precontent:function(){ - player.logSkill('old_guhuo'); - player.addTempSkill('old_guhuo_guess'); - var card=event.result.cards[0]; - event.result.card.suit=get.suit(card); - event.result.card.number=get.number(card); + precontent: function () { + player.logSkill("old_guhuo"); + player.addTempSkill("old_guhuo_guess"); + var card = event.result.cards[0]; + event.result.card.suit = get.suit(card); + event.result.card.number = get.number(card); }, - } + }; }, - prompt:function(links,player){ - return '将一张手牌当做'+(links[0][3]?get.translation(links[0][3]):'')+'【'+get.translation(links[0][2])+'】'+(_status.event.name=='chooseToRespond'?'打出':'使用'); + prompt: function (links, player) { + return ( + "将一张手牌当做" + + (links[0][3] ? get.translation(links[0][3]) : "") + + "【" + + get.translation(links[0][2]) + + "】" + + (_status.event.name == "chooseToRespond" ? "打出" : "使用") + ); }, }, - ai:{ - save:true, - respondSha:true, - respondShan:true, - fireAttack:true, - skillTagFilter:function(player){ - if(!player.countCards('hs')) return false; + ai: { + save: true, + respondSha: true, + respondShan: true, + fireAttack: true, + skillTagFilter: function (player) { + if (!player.countCards("hs")) return false; }, - threaten:1.2, - order:10, - result:{player:1}, + threaten: 1.2, + order: 10, + result: { player: 1 }, }, - subSkill:{ - cheated:{ - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + subSkill: { + cheated: { + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - charlotte:true, - forced:true, - silent:true, - popup:false, - firstDo:true, - onremove:true, - filter:function(event,player){ - if(event.getParent().name=='draw') return true; - var cards=event.getg(player); - if(!cards.length) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(evt&&evt.cards&&evt.cards.length) return true; + charlotte: true, + forced: true, + silent: true, + popup: false, + firstDo: true, + onremove: true, + filter: function (event, player) { + if (event.getParent().name == "draw") return true; + var cards = event.getg(player); + if (!cards.length) return false; + return game.hasPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (evt && evt.cards && evt.cards.length) return true; return false; }); }, - content:function(){ - player.removeSkill('old_guhuo_cheated'); - } - } - } + content: function () { + player.removeSkill("old_guhuo_cheated"); + }, + }, + }, }, - old_guhuo_guess:{ - audio:'old_guhuo', - trigger:{ - player:['useCardBefore','respondBefore'], + old_guhuo_guess: { + audio: "old_guhuo", + trigger: { + player: ["useCardBefore", "respondBefore"], }, - forced:true, - silent:true, - popup:false, - firstDo:true, - charlotte:true, - filter:function(event,player){ - return event.skill&&event.skill.indexOf('old_guhuo_')==0; + forced: true, + silent: true, + popup: false, + firstDo: true, + charlotte: true, + filter: function (event, player) { + return event.skill && event.skill.indexOf("old_guhuo_") == 0; }, - content:function(){ - 'step 0' - event.fake=false; - event.goon=true; - event.betrayers=[]; - var card=trigger.cards[0]; - if(card.name!=trigger.card.name||(card.name=='sha'&&!get.is.sameNature(trigger.card,card))) event.fake=true; - if(event.fake){ - player.addSkill('old_guhuo_cheated'); - player.markAuto('old_guhuo_cheated',[trigger.card.name+trigger.card.nature]); + content: function () { + "step 0"; + event.fake = false; + event.goon = true; + event.betrayers = []; + var card = trigger.cards[0]; + if ( + card.name != trigger.card.name || + (card.name == "sha" && !get.is.sameNature(trigger.card, card)) + ) + event.fake = true; + if (event.fake) { + player.addSkill("old_guhuo_cheated"); + player.markAuto("old_guhuo_cheated", [trigger.card.name + trigger.card.nature]); } - player.popup(trigger.card.name,'metal'); - player.lose(card,ui.ordering).relatedEvent=trigger; - trigger.throw=false; - trigger.skill='old_guhuo_backup'; - game.log(player,'声明',trigger.targets&&trigger.targets.length?'对':'',trigger.targets||'',trigger.name=='useCard'?'使用':'打出',trigger.card); - event.prompt=get.translation(player)+'声明'+(trigger.targets&&trigger.targets.length?'对'+get.translation(trigger.targets):'')+ - (trigger.name=='useCard'?'使用':'打出')+(get.translation(trigger.card.nature)||'')+get.translation(trigger.card.name)+',是否质疑?'; - event.targets=game.filterPlayer(i=>i!=player&&i.hp>0).sortBySeat(_status.currentPhase); + player.popup(trigger.card.name, "metal"); + player.lose(card, ui.ordering).relatedEvent = trigger; + trigger.throw = false; + trigger.skill = "old_guhuo_backup"; + game.log( + player, + "声明", + trigger.targets && trigger.targets.length ? "对" : "", + trigger.targets || "", + trigger.name == "useCard" ? "使用" : "打出", + trigger.card + ); + event.prompt = + get.translation(player) + + "声明" + + (trigger.targets && trigger.targets.length + ? "对" + get.translation(trigger.targets) + : "") + + (trigger.name == "useCard" ? "使用" : "打出") + + (get.translation(trigger.card.nature) || "") + + get.translation(trigger.card.name) + + ",是否质疑?"; + event.targets = game + .filterPlayer((i) => i != player && i.hp > 0) + .sortBySeat(_status.currentPhase); - game.broadcastAll(function(card,player){ - _status.old_guhuoNode=card.copy('thrown'); - if(lib.config.cardback_style!='default'){ - _status.old_guhuoNode.style.transitionProperty='none'; - ui.refresh(_status.old_guhuoNode); - _status.old_guhuoNode.classList.add('infohidden'); - ui.refresh(_status.old_guhuoNode); - _status.old_guhuoNode.style.transitionProperty=''; - } - else{ - _status.old_guhuoNode.classList.add('infohidden'); - } - _status.old_guhuoNode.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; - player.$throwordered2(_status.old_guhuoNode); - },trigger.cards[0],player); - event.onEnd01=function(){ - _status.old_guhuoNode.removeEventListener('webkitTransitionEnd',_status.event.onEnd01); - setTimeout(function(){ - _status.old_guhuoNode.style.transition='all ease-in 0.3s'; - _status.old_guhuoNode.style.transform='perspective(600px) rotateY(270deg)'; - var onEnd=function(){ - _status.old_guhuoNode.classList.remove('infohidden'); - _status.old_guhuoNode.style.transition='all 0s'; + game.broadcastAll( + function (card, player) { + _status.old_guhuoNode = card.copy("thrown"); + if (lib.config.cardback_style != "default") { + _status.old_guhuoNode.style.transitionProperty = "none"; ui.refresh(_status.old_guhuoNode); - _status.old_guhuoNode.style.transform='perspective(600px) rotateY(-90deg)'; + _status.old_guhuoNode.classList.add("infohidden"); ui.refresh(_status.old_guhuoNode); - _status.old_guhuoNode.style.transition=''; - ui.refresh(_status.old_guhuoNode); - _status.old_guhuoNode.style.transform=''; - _status.old_guhuoNode.removeEventListener('webkitTransitionEnd',onEnd); + _status.old_guhuoNode.style.transitionProperty = ""; + } else { + _status.old_guhuoNode.classList.add("infohidden"); } + _status.old_guhuoNode.style.transform = + "perspective(600px) rotateY(180deg) translateX(0)"; + player.$throwordered2(_status.old_guhuoNode); + }, + trigger.cards[0], + player + ); + event.onEnd01 = function () { + _status.old_guhuoNode.removeEventListener( + "webkitTransitionEnd", + _status.event.onEnd01 + ); + setTimeout(function () { + _status.old_guhuoNode.style.transition = "all ease-in 0.3s"; + _status.old_guhuoNode.style.transform = "perspective(600px) rotateY(270deg)"; + var onEnd = function () { + _status.old_guhuoNode.classList.remove("infohidden"); + _status.old_guhuoNode.style.transition = "all 0s"; + ui.refresh(_status.old_guhuoNode); + _status.old_guhuoNode.style.transform = "perspective(600px) rotateY(-90deg)"; + ui.refresh(_status.old_guhuoNode); + _status.old_guhuoNode.style.transition = ""; + ui.refresh(_status.old_guhuoNode); + _status.old_guhuoNode.style.transform = ""; + _status.old_guhuoNode.removeEventListener("webkitTransitionEnd", onEnd); + }; _status.old_guhuoNode.listenTransition(onEnd); - },300); + }, 300); }; - if(!event.targets.length) event.goto(3); - 'step 1' - event.target=event.targets.shift(); - event.target.chooseButton([event.prompt,[['reguhuo_ally','reguhuo_betray'],'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - var evt=_status.event.getParent('old_guhuo_guess'),evtx=evt.getTrigger(); - if(!evt) return Math.random(); - var card={name:evtx.card.name,nature:evtx.card.nature,isCard:true}; - var ally=button.link[2]=='reguhuo_ally'; - if(ally&&(player.hp<=1||get.attitude(player,evt.player)>=0)) return 1.1; - if(!ally&&get.effect(player,{name:'losehp'},player,player)>=0) return 10; - if(!ally&&get.attitude(player,evt.player)<0){ - if(evtx.name=='useCard'){ - var eff=0; - var targetsx=evtx.targets||[]; - for(var target of targetsx){ - var isMe=target==evt.player; - eff+=get.effect(target,card,evt.player,player)/(isMe?1.35:1); + if (!event.targets.length) event.goto(3); + "step 1"; + event.target = event.targets.shift(); + event.target + .chooseButton([event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], true) + .set("ai", function (button) { + var player = _status.event.player; + var evt = _status.event.getParent("old_guhuo_guess"), + evtx = evt.getTrigger(); + if (!evt) return Math.random(); + var card = { name: evtx.card.name, nature: evtx.card.nature, isCard: true }; + var ally = button.link[2] == "reguhuo_ally"; + if (ally && (player.hp <= 1 || get.attitude(player, evt.player) >= 0)) return 1.1; + if (!ally && get.effect(player, { name: "losehp" }, player, player) >= 0) + return 10; + if (!ally && get.attitude(player, evt.player) < 0) { + if (evtx.name == "useCard") { + var eff = 0; + var targetsx = evtx.targets || []; + for (var target of targetsx) { + var isMe = target == evt.player; + eff += + get.effect(target, card, evt.player, player) / (isMe ? 1.35 : 1); + } + eff /= 1.5 * targetsx.length || 1; + if (eff > 0) return 0; + if (eff < -7) + return ( + (Math.random() + Math.pow(-(eff + 7) / 8, 2)) / + Math.sqrt(evt.betrayers.length + 1) + + (player.hp - 3) * 0.05 + + Math.max(0, 4 - evt.player.hp) * 0.05 - + (player.hp == 1 && !get.tag(card, "damage") ? 0.2 : 0) + ); + return ( + Math.pow( + (get.value(card, evt.player, "raw") - 4) / (eff == 0 ? 3.1 : 10), + 2 + ) / + Math.sqrt(evt.betrayers.length || 1) + + (player.hp - 3) * 0.05 + + Math.max(0, 4 - evt.player.hp) * 0.05 + ); } - eff/=(1.5*targetsx.length)||1; - if(eff>0) return 0; - if(eff<-7) return (Math.random()+Math.pow(-(eff+7)/8,2))/Math.sqrt(evt.betrayers.length+1)+(player.hp-3)*0.05+Math.max(0,4-evt.player.hp)*0.05-(player.hp==1&&!get.tag(card,'damage')?0.2:0); - return Math.pow((get.value(card,evt.player,'raw')-4)/(eff==0?3.1:10),2)/Math.sqrt(evt.betrayers.length||1)+(player.hp-3)*0.05+Math.max(0,4-evt.player.hp)*0.05; + if ( + evt.player + .getStorage("old_guhuo_cheated") + .includes(card.name + card.nature) + ) + return Math.random() + 0.3; } - if(evt.player.getStorage('old_guhuo_cheated').includes(card.name+card.nature)) return Math.random()+0.3; - } - return Math.random(); - }); - 'step 2' - if(result.links[0][2]=='reguhuo_betray'){ + return Math.random(); + }); + "step 2"; + if (result.links[0][2] == "reguhuo_betray") { target.addExpose(0.2); - game.log(target,'#y质疑'); - target.popup('质疑!','fire'); + game.log(target, "#y质疑"); + target.popup("质疑!", "fire"); event.betrayers.push(target); + } else { + game.log(target, "#g不质疑"); + target.popup("不质疑", "wood"); } - else{ - game.log(target,'#g不质疑'); - target.popup('不质疑','wood'); - } - if(targets.length) event.goto(1); - 'step 3' + if (targets.length) event.goto(1); + "step 3"; game.delayx(); - game.broadcastAll(function(onEnd){ - _status.event.onEnd01=onEnd; - if(_status.old_guhuoNode) _status.old_guhuoNode.listenTransition(onEnd,300); - },event.onEnd01); - 'step 4' + game.broadcastAll(function (onEnd) { + _status.event.onEnd01 = onEnd; + if (_status.old_guhuoNode) _status.old_guhuoNode.listenTransition(onEnd, 300); + }, event.onEnd01); + "step 4"; game.delay(2); - 'step 5' - if(!event.betrayers.length){ + "step 5"; + if (!event.betrayers.length) { event.goto(7); } - 'step 6' - if(event.fake){ - for(var target of event.betrayers){ - target.popup('质疑正确','wood'); + "step 6"; + if (event.fake) { + for (var target of event.betrayers) { + target.popup("质疑正确", "wood"); } - event.goon=false; - } - else{ - for(var target of event.betrayers){ - target.popup('质疑错误','fire'); + event.goon = false; + } else { + for (var target of event.betrayers) { + target.popup("质疑错误", "fire"); target.loseHp(); } - if(get.suit(trigger.cards[0],player)!='heart'){ - event.goon=false; + if (get.suit(trigger.cards[0], player) != "heart") { + event.goon = false; } } - 'step 7' - if(!event.goon){ - game.log(player,'声明的',trigger.card,'作废了'); + "step 7"; + if (!event.goon) { + game.log(player, "声明的", trigger.card, "作废了"); trigger.cancel(); trigger.getParent().goto(0); - trigger.line=false; + trigger.line = false; } - 'step 8' + "step 8"; game.delay(); - 'step 9' - if(!event.goon){ - if(event.fake) game.asyncDraw(event.betrayers); + "step 9"; + if (!event.goon) { + if (event.fake) game.asyncDraw(event.betrayers); game.broadcastAll(ui.clear); } }, }, - old_zuilun:{ - audio:'xinfu_zuilun', - subSkill:{ - e:{}, - h:{}, + old_zuilun: { + audio: "xinfu_zuilun", + subSkill: { + e: {}, + h: {}, }, - enable:"phaseUse", - usable:2, - filterTarget:function(card,player,target){ - if(player==target) return false; - var pos='he'; - if(player.hasSkill('old_zuilun_h')) pos='e'; - if(player.hasSkill('old_zuilun_e')) pos='h'; - return target.countGainableCards(player,pos)>0; + enable: "phaseUse", + usable: 2, + filterTarget: function (card, player, target) { + if (player == target) return false; + var pos = "he"; + if (player.hasSkill("old_zuilun_h")) pos = "e"; + if (player.hasSkill("old_zuilun_e")) pos = "h"; + return target.countGainableCards(player, pos) > 0; }, - content:function(){ - 'step 0' - var pos='he'; - if(player.hasSkill('old_zuilun_h')) pos='e'; - if(player.hasSkill('old_zuilun_e')) pos='h'; - player.gainPlayerCard(target,pos,true); - 'step 1' - if(result.bool&&result.cards&&result.cards.length){ + content: function () { + "step 0"; + var pos = "he"; + if (player.hasSkill("old_zuilun_h")) pos = "e"; + if (player.hasSkill("old_zuilun_e")) pos = "h"; + player.gainPlayerCard(target, pos, true); + "step 1"; + if (result.bool && result.cards && result.cards.length) { target.draw(); - var pos=result.cards[0].original; - if(pos=='h'||pos=='e') player.addTempSkill('old_zuilun_'+pos,'phaseUseAfter'); + var pos = result.cards[0].original; + if (pos == "h" || pos == "e") + player.addTempSkill("old_zuilun_" + pos, "phaseUseAfter"); } }, + ai: { + order: 7, + result: { + target: -1, + }, + }, + }, + old_fuyin: { + mod: { + targetEnabled: function (card, player, target) { + if ( + (card.name == "juedou" || card.name == "sha" || card.name == "huogong") && + player != target && + player.countCards("h") >= target.countCards("h") && + target.hasEmptySlot(2) + ) + return false; + }, + }, + }, + old_jijun: { + marktext: "方", + audio: "xinfu_jijun", + intro: { + content: "expansion", + markcount: "expansion", + }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + filter: function (event, player) { + return player.countCards("h") > 0; + }, + check: function (card) { + var player = _status.event.player; + if (36 - player.getExpansions("old_jijun").length <= player.countCards("h")) return 1; + return 5 - get.value(card); + }, + discard: false, + lose: false, + content: function () { + player.addToExpansion(cards, player, "give").gaintag.add("old_jijun"); + }, + ai: { + order: 1, + result: { + player: 1 + }, + combo: "old_fangtong" + }, + }, + old_fangtong: { + trigger: { + player: "phaseJieshuBegin", + }, + audio: "xinfu_fangtong", + forced: true, + skillAnimation: true, + animationColor: "metal", + filter: function (event, player) { + return player.getExpansions("old_jijun").length > 35; + }, + content: function () { + var winners = player.getFriends(); + game.over(player == game.me || winners.includes(game.me)); + }, ai:{ - order:7, - result:{ - target:-1, - }, + combo: "oldjijun" }, }, - old_fuyin:{ - mod:{ - targetEnabled:function(card,player,target){ - if((card.name=='juedou'||card.name=='sha'||card.name=='huogong')&&player!=target&&player.countCards('h')>=target.countCards('h')&&target.hasEmptySlot(2)) return false; - }, - }, - }, - old_jijun:{ - marktext:"方", - audio:"xinfu_jijun", - intro:{ - content:"expansion", - markcount:'expansion', - }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - }, - enable:"phaseUse", - filterCard:true, - selectCard:[1,Infinity], - filter:function(event,player){ - return player.countCards('h')>0; - }, - check:function(card){ - var player=_status.event.player; - if((36-player.getExpansions('old_jijun').length)<=player.countCards('h')) return 1; - return 5-get.value(card); - }, - discard:false, - lose:false, - content:function(){ - player.addToExpansion(cards,player,'give').gaintag.add('old_jijun'); - }, - ai:{order:1,result:{player:1}}, - }, - old_fangtong:{ - trigger:{ - player:"phaseJieshuBegin", - }, - audio:"xinfu_fangtong", - forced:true, - skillAnimation:true, - animationColor:'metal', - filter:function(event,player){ - return (player.getExpansions('old_jijun').length>35); - }, - content:function(){ - var winners=player.getFriends(); - game.over(player==game.me||winners.includes(game.me)); - }, - }, - oldanxu:{ - enable:'phaseUse', - usable:1, - multitarget:true, - audio:2, - filterTarget:function(card,player,target){ - if(player==target) return false; - var num=target.countCards('h'); - if(ui.selected.targets.length){ - return numplayers[i].countCards('h')) return true; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (num > players[i].countCards("h")) return true; } return false; }, - selectTarget:2, - content:function(){ - 'step 0' - var gainner,giver; - if(targets[0].countCards('h')0) return -1; - var players=game.filterPlayer(); - for(var i=0;i=0&&num2 0) return -1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var num2 = players[i].countCards("h"); + var att2 = get.attitude(player, players[i]); + if (att2 >= 0 && num2 < num) return -1; } return 0; - } - else{ + } else { return 1; } }, - player:0.1 - } - } + player: 0.1, + }, + }, }, - oldfaen:{ - audio:'faen', - trigger:{global:['turnOverAfter','linkAfter']}, - filter:function(event,player){ - if(event.name=='link') return event.player.isLinked(); + oldfaen: { + audio: "faen", + trigger: { global: ["turnOverAfter", "linkAfter"] }, + filter: function (event, player) { + if (event.name == "link") return event.player.isLinked(); return true; }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.draw(); }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - oldxuanfeng:{ - audio:'xuanfeng', - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + oldxuanfeng: { + audio: "xuanfeng", + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + direct: true, + filter: function (event, player) { + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('oldxuanfeng'),function(card,player,target){ - if(target==player) return false; - return get.distance(player,target)<=1||player.canUse('sha',target,false); - }).set('ai',function(target){ - if(get.distance(player,target)<=1){ - return get.damageEffect(target,player,player)*2; - } - else{ - return get.effect(target,{name:'sha'},player,player); - } - }); - 'step 1' - if(result.bool){ - player.logSkill('oldxuanfeng',result.targets); - var target=result.targets[0]; - var distance=get.distance(player,target); - if(distance<=1&&player.canUse('sha',target,false)){ - player.chooseControl('出杀','造成伤害').set('ai',function(){ - return '造成伤害'; + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("oldxuanfeng"), function (card, player, target) { + if (target == player) return false; + return get.distance(player, target) <= 1 || player.canUse("sha", target, false); + }) + .set("ai", function (target) { + if (get.distance(player, target) <= 1) { + return get.damageEffect(target, player, player) * 2; + } else { + return get.effect(target, { name: "sha" }, player, player); + } + }); + "step 1"; + if (result.bool) { + player.logSkill("oldxuanfeng", result.targets); + var target = result.targets[0]; + var distance = get.distance(player, target); + if (distance <= 1 && player.canUse("sha", target, false)) { + player.chooseControl("出杀", "造成伤害").set("ai", function () { + return "造成伤害"; }); - event.target=target; - } - else if(distance<=1){ + event.target = target; + } else if (distance <= 1) { target.damage(); event.finish(); - } - else{ - player.useCard({name:'sha',isCard:true},target,false).animate=false; + } else { + player.useCard({ name: "sha", isCard: true }, target, false).animate = false; game.delay(); event.finish(); } - } - else{ + } else { event.finish(); } - 'step 2' - var target=event.target; - if(result.control=='出杀'){ - player.useCard({name:'sha',isCard:true},target,false).animate=false; + "step 2"; + var target = event.target; + if (result.control == "出杀") { + player.useCard({ name: "sha", isCard: true }, target, false).animate = false; game.delay(); - } - else{ + } else { target.damage(); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip') return [1,3]; - } + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") return [1, 3]; + }, }, - reverseEquip:true, - noe:true - } + reverseEquip: true, + noe: true, + }, }, }, - translate:{ - old_zhangxingcai:'旧张星彩', - old_zhangxingcai_prefix:'旧', - old_xusheng:'旧徐盛', - old_xusheng_prefix:'旧', - old_lingtong:'旧凌统', - old_lingtong_prefix:'旧', - old_zhuran:'旧朱然', - old_zhuran_prefix:'旧', - old_caoxiu:'旧曹休', - old_caoxiu_prefix:'旧', - old_caozhen:'旧曹真', - old_caozhen_prefix:'旧', - old_maliang:'旧马良', - old_maliang_prefix:'旧', - old_chenqun:'旧陈群', - old_chenqun_prefix:'旧', - old_zhuhuan:'旧朱桓', - old_zhuhuan_prefix:'旧', - old_zhuzhi:'旧朱治', - old_zhuzhi_prefix:'旧', - old_zhugezhan:'旧诸葛瞻', - old_zhugezhan_prefix:'旧', - yuji:'旧于吉', - yuji_prefix:'旧', - old_zhangfei:'新杀张飞', - old_zhangfei_prefix:'新杀', - old_huatuo:'OL华佗', - old_huatuo_prefix:'OL', - old_guanyu:'旧关羽', - old_guanyu_prefix:'旧', - ol_zhangrang:'旧张让', - ol_zhangrang_prefix:'旧', - ol_liaohua:'OL廖化', - ol_liaohua_prefix:'OL', - ol_zhuran:'OL朱然', - ol_zhuran_prefix:'OL', - ol_manchong:'OL满宠', - ol_manchong_prefix:'OL', - old_fuhuanghou:'旧伏寿', - old_fuhuanghou_prefix:'旧', - old_caochong:'旧曹冲', - old_caochong_prefix:'旧', - old_guanqiujian:'旧毌丘俭', - old_guanqiujian_prefix:'旧', - old_wangyun:'旧王允', - old_wangyun_prefix:'旧', - old_zhaoyun:'新杀赵云', - old_zhaoyun_prefix:'新杀', - ol_huaxiong:'旧华雄', - ol_huaxiong_prefix:'旧', - old_xiaoqiao:'旧小乔', - old_xiaoqiao_prefix:'旧', - old_wanglang:'旧王朗', - old_wanglang_prefix:'旧', - old_wangyi:'旧王异', - old_wangyi_prefix:'旧', - xin_yujin:'节钺于禁', - xin_yujin_prefix:'节钺', - re_yujin:'毅重于禁', - re_yujin_prefix:'毅重', + translate: { + old_zhangxingcai: "旧张星彩", + old_zhangxingcai_prefix: "旧", + old_xusheng: "旧徐盛", + old_xusheng_prefix: "旧", + old_lingtong: "旧凌统", + old_lingtong_prefix: "旧", + old_zhuran: "旧朱然", + old_zhuran_prefix: "旧", + old_caoxiu: "旧曹休", + old_caoxiu_prefix: "旧", + old_caozhen: "旧曹真", + old_caozhen_prefix: "旧", + old_maliang: "旧马良", + old_maliang_prefix: "旧", + old_chenqun: "旧陈群", + old_chenqun_prefix: "旧", + old_zhuhuan: "旧朱桓", + old_zhuhuan_prefix: "旧", + old_zhuzhi: "旧朱治", + old_zhuzhi_prefix: "旧", + old_zhugezhan: "旧诸葛瞻", + old_zhugezhan_prefix: "旧", + yuji: "旧于吉", + yuji_prefix: "旧", + old_zhangfei: "新杀张飞", + old_zhangfei_prefix: "新杀", + old_huatuo: "OL华佗", + old_huatuo_prefix: "OL", + old_guanyu: "旧关羽", + old_guanyu_prefix: "旧", + ol_zhangrang: "旧张让", + ol_zhangrang_prefix: "旧", + ol_liaohua: "OL廖化", + ol_liaohua_prefix: "OL", + ol_zhuran: "OL朱然", + ol_zhuran_prefix: "OL", + ol_manchong: "OL满宠", + ol_manchong_prefix: "OL", + old_fuhuanghou: "旧伏寿", + old_fuhuanghou_prefix: "旧", + old_caochong: "旧曹冲", + old_caochong_prefix: "旧", + old_guanqiujian: "旧毌丘俭", + old_guanqiujian_prefix: "旧", + old_wangyun: "旧王允", + old_wangyun_prefix: "旧", + old_zhaoyun: "新杀赵云", + old_zhaoyun_prefix: "新杀", + ol_huaxiong: "旧华雄", + ol_huaxiong_prefix: "旧", + old_xiaoqiao: "旧小乔", + old_xiaoqiao_prefix: "旧", + old_wanglang: "旧王朗", + old_wanglang_prefix: "旧", + old_wangyi: "旧王异", + old_wangyi_prefix: "旧", + xin_yujin: "节钺于禁", + xin_yujin_prefix: "节钺", + re_yujin: "毅重于禁", + re_yujin_prefix: "毅重", - old_guhuo:"蛊惑", - old_guhuo_info:"你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出,体力值不为0的其他角色依次选择是否质疑。然后,若有质疑的角色,你展示此牌:若为假,此牌作废,这些角色摸一张牌;若为真,这些角色失去1点体力,且若此牌不为♥,此牌作废。", - old_guhuo_guess:"蛊惑", - old_jijun:"集军", - old_jijun_info:"出牌阶段,你可以将任意张手牌置于武将牌上,称为“方”。", - old_fangtong:"方统", - old_fangtong_info:"锁定技。结束阶段,若你的“方”数目不小于36,则以你的阵营胜利结束本局游戏。", - old_zuilun:"罪论", - old_zuilun_info:"出牌阶段,你可以获得一名其他角色的一张牌(手牌、装备区各一次),然后该角色摸一张牌。", - old_fuyin:"父荫", - old_fuyin_info:"锁定技。若你的装备区里没有防具牌,你不能成为手牌数不小于你的其他角色使用【杀】、【决斗】或【火攻】的目标。", - oldanxu:'安恤', - oldanxu_info:'出牌阶段限一次。你可以选择手牌数不相等的两名其他角色,其中手牌少的角色获得手牌多的角色的一张手牌并展示之,然后若此牌不为黑桃,你摸一张牌。', - oldfaen:'法恩', - oldfaen_info:'当一名角色翻面或横置后,你可以令其摸一张牌。', - oldxuanfeng:'旋风', - oldxuanfeng_info:'当你失去装备区里的牌后,你可以选择一项:1.视为对一名其他角色使用一张【杀】;2.对一名距离为1的角色造成1点伤害。', - ol_yuanshu:'旧袁术', - ol_yuanshu_prefix:'旧', - fazheng:'旧法正', - fazheng_prefix:'旧', - junk_simayi:'旧晋司马懿', - junk_simayi_prefix:'旧晋', - madai:'旧马岱', - madai_prefix:'旧', - old_yangzhi:'旧杨芷', - old_yangzhi_prefix:'旧', - old_yangyan:'旧杨艳', - old_yangyan_prefix:'旧', - old_caorui:'旧曹叡', - old_caorui_prefix:'旧', - oldmingjian:'明鉴', - oldmingjian_info:'出牌阶段开始前,你可以跳过此阶段并将所有手牌交给一名其他角色。若如此做,你结束当前回合,然后其获得一个额外的回合(仅包含出牌阶段)。', - old_handang:'旧韩当', - old_handang_prefix:'旧', - oldgongji:'弓骑', - oldgongji_info:'你可以将一张装备牌当做无距离限制的【杀】使用或打出。', - oldjiefan:'解烦', - oldjiefan_info:'当一名角色A于你的回合外处于濒死状态时,你可以对当前回合角色使用一张【杀】。当此【杀】造成伤害时,你防止此伤害,视为对A使用一张【桃】。', - old_gaoshun:'旧高顺', - old_gaoshun_prefix:'旧', - old_liubiao:'旧刘表', - old_liubiao_prefix:'旧', - oldre_liubiao:'RE刘表', - oldre_liubiao_prefix:'RE', - oldzishou:'自守', - oldzishou_info:'摸牌阶段,若你已受伤,你可令额定摸牌数+X(X为你已损失的体力值),然后跳过下一个出牌阶段。', - old_huanghao:'旧黄皓', - old_huanghao_prefix:'旧', - oldqinqing:'寝情', - oldqinqing_info:'结束阶段,你可以选择一名攻击范围内含有主公的其他角色,然后你弃置该角色的一张牌(无牌则不弃),并令其摸一张牌。若该角色的手牌数大于主公,你摸一张牌。', - oldhuisheng:'贿生', - oldhuisheng_info:'每名角色限一次。当你受到其他角色对你造成的伤害时,你可以令其观看你任意数量的牌并令其选择一项:1.获得这些牌中的一张并防止此伤害;2.弃置等量的牌。', - old_dingfeng:'旧丁奉', - old_dingfeng_prefix:'旧', - junk_sunquan:'旧神孙权', - junk_sunquan_prefix:'旧神', - new_caoren:'旧曹仁', - new_caoren_prefix:'旧', - old_liyan:'旧李严', - old_liyan_prefix:'旧', - old_chendao:'旧陈到', - old_chendao_prefix:'旧', - old_caocao:'旧神曹操', - old_caocao_prefix:'旧神', - junkguixin:'归心', - junkguixin_info:'回合结束时,你可以选择一项:①获得剩余武将牌堆的所有主公技的其中一个技能;②更改一名其他角色的势力。', - old_caochun:'旧曹纯', - old_caochun_prefix:'旧', - old_guanyinping:'旧关银屏', - old_guanyinping_prefix:'旧', - old_shen_zhaoyun:'旧神赵云', - old_shen_zhaoyun_prefix:'旧神', - oldjuejing:'绝境', - oldjuejing_info:'锁定技。①摸牌阶段,你令额定摸牌数+X(X为你已损失的体力值)。②你的手牌上限+2。', - oldlonghun:'龙魂', - oldlonghun_info:'你可以将花色相同的Y张牌按下列规则使用或打出:♥当【桃】,♦当火【杀】,♣当【闪】,♠当普【无懈可击】(Y为你的体力值且至少为1)。', - panfeng:'旧潘凤', - panfeng_prefix:'旧', - old_shixie:'旧士燮', - old_shixie_prefix:'旧', + old_guhuo: "蛊惑", + old_guhuo_info: + "你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出,体力值不为0的其他角色依次选择是否质疑。然后,若有质疑的角色,你展示此牌:若为假,此牌作废,这些角色摸一张牌;若为真,这些角色失去1点体力,且若此牌不为♥,此牌作废。", + old_guhuo_guess: "蛊惑", + old_jijun: "集军", + old_jijun_info: "出牌阶段,你可以将任意张手牌置于武将牌上,称为“方”。", + old_fangtong: "方统", + old_fangtong_info: "锁定技。结束阶段,若你的“方”数目不小于36,则以你的阵营胜利结束本局游戏。", + old_zuilun: "罪论", + old_zuilun_info: + "出牌阶段,你可以获得一名其他角色的一张牌(手牌、装备区各一次),然后该角色摸一张牌。", + old_fuyin: "父荫", + old_fuyin_info: + "锁定技。若你的装备区里没有防具牌,你不能成为手牌数不小于你的其他角色使用【杀】、【决斗】或【火攻】的目标。", + oldanxu: "安恤", + oldanxu_info: + "出牌阶段限一次。你可以选择手牌数不相等的两名其他角色,其中手牌少的角色获得手牌多的角色的一张手牌并展示之,然后若此牌不为黑桃,你摸一张牌。", + oldfaen: "法恩", + oldfaen_info: "当一名角色翻面或横置后,你可以令其摸一张牌。", + oldxuanfeng: "旋风", + oldxuanfeng_info: + "当你失去装备区里的牌后,你可以选择一项:1.视为对一名其他角色使用一张【杀】;2.对一名距离为1的角色造成1点伤害。", + ol_yuanshu: "旧袁术", + ol_yuanshu_prefix: "旧", + fazheng: "旧法正", + fazheng_prefix: "旧", + junk_simayi: "旧晋司马懿", + junk_simayi_prefix: "旧晋", + madai: "旧马岱", + madai_prefix: "旧", + old_yangzhi: "旧杨芷", + old_yangzhi_prefix: "旧", + old_yangyan: "旧杨艳", + old_yangyan_prefix: "旧", + old_caorui: "旧曹叡", + old_caorui_prefix: "旧", + oldmingjian: "明鉴", + oldmingjian_info: + "出牌阶段开始前,你可以跳过此阶段并将所有手牌交给一名其他角色。若如此做,你结束当前回合,然后其获得一个额外的回合(仅包含出牌阶段)。", + old_handang: "旧韩当", + old_handang_prefix: "旧", + oldgongji: "弓骑", + oldgongji_info: "你可以将一张装备牌当做无距离限制的【杀】使用或打出。", + oldjiefan: "解烦", + oldjiefan_info: + "当一名角色A于你的回合外处于濒死状态时,你可以对当前回合角色使用一张【杀】。当此【杀】造成伤害时,你防止此伤害,视为对A使用一张【桃】。", + old_gaoshun: "旧高顺", + old_gaoshun_prefix: "旧", + old_liubiao: "旧刘表", + old_liubiao_prefix: "旧", + oldre_liubiao: "RE刘表", + oldre_liubiao_prefix: "RE", + oldzishou: "自守", + oldzishou_info: + "摸牌阶段,若你已受伤,你可令额定摸牌数+X(X为你已损失的体力值),然后跳过下一个出牌阶段。", + old_huanghao: "旧黄皓", + old_huanghao_prefix: "旧", + oldqinqing: "寝情", + oldqinqing_info: + "结束阶段,你可以选择一名攻击范围内含有主公的其他角色,然后你弃置该角色的一张牌(无牌则不弃),并令其摸一张牌。若该角色的手牌数大于主公,你摸一张牌。", + oldhuisheng: "贿生", + oldhuisheng_info: + "每名角色限一次。当你受到其他角色对你造成的伤害时,你可以令其观看你任意数量的牌并令其选择一项:1.获得这些牌中的一张并防止此伤害;2.弃置等量的牌。", + old_dingfeng: "旧丁奉", + old_dingfeng_prefix: "旧", + junk_sunquan: "旧神孙权", + junk_sunquan_prefix: "旧神", + new_caoren: "旧曹仁", + new_caoren_prefix: "旧", + old_liyan: "旧李严", + old_liyan_prefix: "旧", + old_chendao: "旧陈到", + old_chendao_prefix: "旧", + old_caocao: "旧神曹操", + old_caocao_prefix: "旧神", + junkguixin: "归心", + junkguixin_info: + "回合结束时,你可以选择一项:①获得剩余武将牌堆的所有主公技的其中一个技能;②更改一名其他角色的势力。", + old_caochun: "旧曹纯", + old_caochun_prefix: "旧", + old_guanyinping: "旧关银屏", + old_guanyinping_prefix: "旧", + old_shen_zhaoyun: "旧神赵云", + old_shen_zhaoyun_prefix: "旧神", + oldjuejing: "绝境", + oldjuejing_info: "锁定技。①摸牌阶段,你令额定摸牌数+X(X为你已损失的体力值)。②你的手牌上限+2。", + oldlonghun: "龙魂", + oldlonghun_info: + "你可以将花色相同的Y张牌按下列规则使用或打出:♥当【桃】,♦当火【杀】,♣当【闪】,♠当普【无懈可击】(Y为你的体力值且至少为1)。", + panfeng: "旧潘凤", + panfeng_prefix: "旧", + old_shixie: "旧士燮", + old_shixie_prefix: "旧", - old_standard:'标准包', - old_shenhua:'神话再临', - old_refresh:'界限突破', - old_yijiang1:'一将成名2011', - old_yijiang2:'一将成名2012', - old_yijiang3:'一将成名2013', - old_yijiang4:'一将成名2014', - old_yijiang5:'一将成名2015', - old_yijiang67:'原创设计', - old_sp:'SP', - old_yingbian:'文德武备', - old_mobile:'移动版', - } + old_standard: "标准包", + old_shenhua: "神话再临", + old_refresh: "界限突破", + old_yijiang1: "一将成名2011", + old_yijiang2: "一将成名2012", + old_yijiang3: "一将成名2013", + old_yijiang4: "一将成名2014", + old_yijiang5: "一将成名2015", + old_yijiang67: "原创设计", + old_sp: "SP", + old_yingbian: "文德武备", + old_mobile: "移动版", + }, }; }); diff --git a/character/onlyOL.js b/character/onlyOL.js index f5f2e18d4..5593cbf57 100644 --- a/character/onlyOL.js +++ b/character/onlyOL.js @@ -1,619 +1,899 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'onlyOL', - connect:true, - character:{ - ol_sb_jiangwei:['male','shu',4,['olsbzhuri','olsbranji']], - ol_caozhang:['male','wei',4,['oljiangchi'],['die_audio:xin_caozhang']], - ol_jianyong:['male','shu',3,['olqiaoshui','jyzongshi'],['tempname:re_jianyong','die_audio:re_jianyong']], - ol_lingtong:['male','wu',4,['olxuanfeng'],['die_audio:re_lingtong']], - ol_sb_guanyu:['male','shu',4,['olsbweilin','olsbduoshou']], - ol_sb_taishici:['male','wu',4,['olsbdulie','olsbdouchan']], - ol_gaoshun:['male','qun',4,['olxianzhen','decadejinjiu'],['die_audio:re_gaoshun']], - ol_sb_yuanshao:['male','qun',4,['olsbhetao','olsbshenli','olsbyufeng','olsbshishou'],['zhu']], - ol_yufan:['male','wu',3,['olzongxuan','olzhiyan'],['tempname:re_yufan','die_audio:re_yufan']], - ol_chengpu:['male','wu',4,['dclihuo','olchunlao'],['tempname:xin_chengpu','die_audio:xin_chengpu']], - ol_wangyi:['female','wei',3,['olzhenlie','olmiji']], + name: "onlyOL", + connect: true, + character: { + ol_sb_jiangwei: ["male", "shu", 4, ["olsbzhuri", "olsbranji"]], + ol_caozhang: ["male", "wei", 4, ["oljiangchi"], ["die_audio:xin_caozhang"]], + ol_jianyong: [ + "male", + "shu", + 3, + ["olqiaoshui", "jyzongshi"], + ["tempname:re_jianyong", "die_audio:re_jianyong"], + ], + ol_lingtong: ["male", "wu", 4, ["olxuanfeng"], ["die_audio:re_lingtong"]], + ol_sb_guanyu: ["male", "shu", 4, ["olsbweilin", "olsbduoshou"]], + ol_sb_taishici: ["male", "wu", 4, ["olsbdulie", "olsbdouchan"]], + ol_gaoshun: ["male", "qun", 4, ["olxianzhen", "decadejinjiu"], ["die_audio:re_gaoshun"]], + ol_sb_yuanshao: [ + "male", + "qun", + 4, + ["olsbhetao", "olsbshenli", "olsbyufeng", "olsbshishou"], + ["zhu"], + ], + ol_yufan: [ + "male", + "wu", + 3, + ["olzongxuan", "olzhiyan"], + ["tempname:re_yufan", "die_audio:re_yufan"], + ], + ol_chengpu: [ + "male", + "wu", + 4, + ["dclihuo", "olchunlao"], + ["tempname:xin_chengpu", "die_audio:xin_chengpu"], + ], + ol_wangyi: ["female", "wei", 3, ["olzhenlie", "olmiji"]], }, - characterSort:{ - onlyOL:{ - onlyOL_yijiang1:['ol_jianyong','ol_lingtong','ol_gaoshun'], - onlyOL_yijiang2:['ol_caozhang','ol_chengpu','ol_wangyi'], - onlyOL_yijiang3:['ol_yufan'], - onlyOL_sb:['ol_sb_jiangwei','ol_sb_guanyu','ol_sb_taishici','ol_sb_yuanshao'], + characterSort: { + onlyOL: { + onlyOL_yijiang1: ["ol_jianyong", "ol_lingtong", "ol_gaoshun"], + onlyOL_yijiang2: ["ol_caozhang", "ol_chengpu", "ol_wangyi"], + onlyOL_yijiang3: ["ol_yufan"], + onlyOL_sb: ["ol_sb_jiangwei", "ol_sb_guanyu", "ol_sb_taishici", "ol_sb_yuanshao"], }, }, - characterIntro:{ + characterIntro: {}, + characterReplace: {}, + characterSubstitute: { + ol_sb_yuanshao: [], }, - characterReplace:{ - }, - characterSubstitute:{ - ol_sb_yuanshao:[ - ], - }, - card:{ - sizhaojian:{ - derivation:'ol_sb_yuanshao', - fullskin:true, - type:'equip', - subtype:'equip1', - get destroy(){ + card: { + sizhaojian: { + derivation: "ol_sb_yuanshao", + fullskin: true, + type: "equip", + subtype: "equip1", + get destroy() { return !lib.card.sizhaojian.inShanShanFestival(); }, - inShanShanFestival(){ + inShanShanFestival() { //闪闪节外离开装备区会销毁 - const date=new Date(); - return date.getMonth()+1==3&&date.getDate()>=2&&date.getDate()<=15; + const date = new Date(); + return date.getMonth() + 1 == 3 && date.getDate() >= 2 && date.getDate() <= 15; }, - distance:{attackFrom:-1}, - ai:{basic:{equipValue:7}}, - skills:['olsbyufeng_sizhaojian'], + distance: { attackFrom: -1 }, + ai: { basic: { equipValue: 7 } }, + skills: ["olsbyufeng_sizhaojian"], }, }, - skill:{ + skill: { //王异 - olzhenlie:{ - audio:2, - inherit:'zhenlie', - async content(event,trigger,player){ - const target=trigger.player; - if(get.attitude(player,target)<0&&target.countDiscardableCards(player,'he')) player.addTempSkill('zhenlie_lose'); + olzhenlie: { + audio: 2, + inherit: "zhenlie", + async content(event, trigger, player) { + const target = trigger.player; + if (get.attitude(player, target) < 0 && target.countDiscardableCards(player, "he")) + player.addTempSkill("zhenlie_lose"); await player.loseHp(); - player.removeSkill('zhenlie_lose'); + player.removeSkill("zhenlie_lose"); trigger.getParent().excluded.add(player); - if(!player.isIn()) return; - const goon=target.hasCard(card=>{ - if(get.position(card)=='h') return true; - return lib.filter.canBeGained(card,player,target); - },'he'); - if(goon||player.isDamaged()){ + if (!player.isIn()) return; + const goon = target.hasCard((card) => { + if (get.position(card) == "h") return true; + return lib.filter.canBeGained(card, player, target); + }, "he"); + if (goon || player.isDamaged()) { let result; - if(goon&&player.isDamaged()) result=await player.chooseControl().set('choiceList',[ - '获得'+get.translation(target)+'的一张牌', - '发动一次〖秘计〗', - ]).set('ai',()=>{ - const player=get.event('player'),target=get.event().getTrigger().player; - return get.effect(target,{name:'shunshou_copy2'},player,player)>get.effect(player,{name:'draw'},player,player)*player.getDamagedHp()?0:1 - }).forResult(); - else result={index:goon?0:1}; - if(result.index==0){ - await player.gainPlayerCard(target,'he',true); - } - else{ - await player.useSkill('olmiji'); + if (goon && player.isDamaged()) + result = await player + .chooseControl() + .set("choiceList", [ + "获得" + get.translation(target) + "的一张牌", + "发动一次〖秘计〗", + ]) + .set("ai", () => { + const player = get.event("player"), + target = get.event().getTrigger().player; + return get.effect(target, { name: "shunshou_copy2" }, player, player) > + get.effect(player, { name: "draw" }, player, player) * + player.getDamagedHp() + ? 0 + : 1; + }) + .forResult(); + else result = { index: goon ? 0 : 1 }; + if (result.index == 0) { + await player.gainPlayerCard(target, "he", true); + } else { + await player.useSkill("olmiji"); } } }, }, - olmiji:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ + olmiji: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { return player.isDamaged(); }, - async content(event,trigger,player){ - let num=player.getDamagedHp(); + async content(event, trigger, player) { + let num = player.getDamagedHp(); await player.draw(num); - if(player.countCards('he')&&game.hasPlayer(target=>target!=player)){ - if(_status.connectMode) game.broadcastAll(()=>_status.noclearcountdown=true); - let given_map=[]; - while(num>0&&player.hasCard(card=>!card.hasGaintag('olsujian_given'),'he')){ - const {result:{bool,cards,targets}}=await player.chooseCardTarget({ - filterCard(card,player){ - return !card.hasGaintag('olsujian_given'); + if (player.countCards("he") && game.hasPlayer((target) => target != player)) { + if (_status.connectMode) game.broadcastAll(() => (_status.noclearcountdown = true)); + let given_map = []; + while ( + num > 0 && + player.hasCard((card) => !card.hasGaintag("olsujian_given"), "he") + ) { + const { + result: { bool, cards, targets }, + } = await player.chooseCardTarget({ + filterCard(card, player) { + return !card.hasGaintag("olsujian_given"); }, - selectCard:[1,num], - position:'he', - filterTarget:lib.filter.notMe, - prompt:'秘计:请选择要分配的卡牌和目标', - prompt2:'(还可分配'+num+'张)', - ai1(card){ - return (!ui.selected.cards.length&&card.name=='du')?1:0; + selectCard: [1, num], + position: "he", + filterTarget: lib.filter.notMe, + prompt: "秘计:请选择要分配的卡牌和目标", + prompt2: "(还可分配" + num + "张)", + ai1(card) { + return !ui.selected.cards.length && card.name == "du" ? 1 : 0; }, - ai2(target){ - const player=get.event('player'); - const card=ui.selected.cards[0]; - if(card) return get.value(card,target)*get.attitude(player,target); + ai2(target) { + const player = get.event("player"); + const card = ui.selected.cards[0]; + if (card) return get.value(card, target) * get.attitude(player, target); return 0; }, }); - if(bool){ - num-=cards.length; - const target=targets[0]; - if(given_map.some(i=>i[0]==target)){ - given_map[given_map.indexOf(given_map.find(i=>i[0]==target))][1].addArray(cards); - } - else given_map.push([target,cards]); - player.addGaintag(cards,'olsujian_given'); - } - else break; + if (bool) { + num -= cards.length; + const target = targets[0]; + if (given_map.some((i) => i[0] == target)) { + given_map[ + given_map.indexOf(given_map.find((i) => i[0] == target)) + ][1].addArray(cards); + } else given_map.push([target, cards]); + player.addGaintag(cards, "olsujian_given"); + } else break; } - if(_status.connectMode){ - game.broadcastAll(()=>{ + if (_status.connectMode) { + game.broadcastAll(() => { delete _status.noclearcountdown; game.stopCountChoose(); }); } - if(given_map.length){ - await game.loseAsync({ - gain_list:given_map, - player:player, - cards:given_map.slice().map(list=>list[1]), - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + if (given_map.length) { + await game + .loseAsync({ + gain_list: given_map, + player: player, + cards: given_map.slice().map((list) => list[1]), + giver: player, + animate: "giveAuto", + }) + .setContent("gaincardMultiple"); } } }, }, //程普 - dclihuo:{ - audio:'relihuo', - trigger:{player:'useCard1'}, - filter(event,player){ - return event.card.name=='sha'&&!game.hasNature(event.card,'fire'); + dclihuo: { + audio: "relihuo", + trigger: { player: "useCard1" }, + filter(event, player) { + return event.card.name == "sha" && !game.hasNature(event.card, "fire"); }, - check(event,player){ - let card=new lib.element.VCard(get.copy(event.card)); - game.setNature(card,'fire'); - const eff1=event.targets.reduce((sum,target)=>{ - return sum+get.effect(target,event.card,player,player); - },0); - let targets=event.targets.slice(); - if(get.info('lihuo2').filter(event,player)){ - let targetx=game.filterPlayer(target=>{ - return !targets.includes(target)&&player.canUse(card,target)&&get.effect(target,card,player,player)>0; + check(event, player) { + let card = new lib.element.VCard(get.copy(event.card)); + game.setNature(card, "fire"); + const eff1 = event.targets.reduce((sum, target) => { + return sum + get.effect(target, event.card, player, player); + }, 0); + let targets = event.targets.slice(); + if (get.info("lihuo2").filter(event, player)) { + let targetx = game.filterPlayer((target) => { + return ( + !targets.includes(target) && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); }); - if(targetx.length) targets.add(targetx.sort((a,b)=>{ - return get.effect(b,card,player,player)-get.effect(a,card,player,player); - })[0]); + if (targetx.length) + targets.add( + targetx.sort((a, b) => { + return ( + get.effect(b, card, player, player) - + get.effect(a, card, player, player) + ); + })[0] + ); } - const eff2=targets.reduce((sum,target)=>{ - return sum+get.effect(target,card,player,player); - },0); - return eff2>eff1; + const eff2 = targets.reduce((sum, target) => { + return sum + get.effect(target, card, player, player); + }, 0); + return eff2 > eff1; }, - content(){ - game.log(player,'将',trigger.card,'改为了火属性'); - game.setNature(trigger.card,'fire'); - player.when('useCardAfter').filter(evt=>evt==trigger).then(()=>{ - if(game.hasPlayer2(target=>{ - return target.getHistory('damage',evt=>evt.card&&evt.card==trigger.card).length; - })){ - player.chooseToDiscard('he','疠火:弃置一张牌,或失去1点体力').set('ai',card=>{ - const player=get.event('player'); - if((get.name(card)=='tao'||get.name(card)=='jiu')&&lib.filter.cardSavable(card,player,player)) return -1; - if(player.hp<=1){ - if(cards.length{ - return (get.name(cardx)=='tao'||get.name(cardx)=='jiu')&&lib.filter.cardSavable(cardx,player,player); - },'hs')) return 7-get.value(card); - return -1; - } - return 24-5*cards.length-2*Math.min(4,player.getHp())-get.value(card); - }); - } - else event.finish(); - }).then(()=>{ - if(!result.bool) player.loseHp(); - }); + content() { + game.log(player, "将", trigger.card, "改为了火属性"); + game.setNature(trigger.card, "fire"); + player + .when("useCardAfter") + .filter((evt) => evt == trigger) + .then(() => { + if ( + game.hasPlayer2((target) => { + return target.getHistory( + "damage", + (evt) => evt.card && evt.card == trigger.card + ).length; + }) + ) { + player + .chooseToDiscard("he", "疠火:弃置一张牌,或失去1点体力") + .set("ai", (card) => { + const player = get.event("player"); + if ( + (get.name(card) == "tao" || get.name(card) == "jiu") && + lib.filter.cardSavable(card, player, player) + ) + return -1; + if (player.hp <= 1) { + if ( + cards.length < player.getEnemies().length && + player.hasCard((cardx) => { + return ( + (get.name(cardx) == "tao" || + get.name(cardx) == "jiu") && + lib.filter.cardSavable(cardx, player, player) + ); + }, "hs") + ) + return 7 - get.value(card); + return -1; + } + return ( + 24 - + 5 * cards.length - + 2 * Math.min(4, player.getHp()) - + get.value(card) + ); + }); + } else event.finish(); + }) + .then(() => { + if (!result.bool) player.loseHp(); + }); }, - ai:{fireAttack:true}, - group:'dclihuo_add', - subSkill:{ - add:{ - inherit:'lihuo2', - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('dclihuo'),'为'+get.translation(trigger.card)+'增加一个目标',(card,player,target)=>{ - const trigger=get.event().getTrigger(); - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); - }).set('card',trigger.card).set('ai',target=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - return get.effect(target,trigger.card,player,player); - }); - if(bool){ - player.logSkill('dclihuo',targets); + ai: { fireAttack: true }, + group: "dclihuo_add", + subSkill: { + add: { + inherit: "lihuo2", + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("dclihuo"), + "为" + get.translation(trigger.card) + "增加一个目标", + (card, player, target) => { + const trigger = get.event().getTrigger(); + return ( + !trigger.targets.includes(target) && + player.canUse(trigger.card, target) + ); + } + ) + .set("card", trigger.card) + .set("ai", (target) => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + return get.effect(target, trigger.card, player, player); + }); + if (bool) { + player.logSkill("dclihuo", targets); trigger.targets.addArray(targets); } }, }, }, }, - olchunlao:{ - audio:'chunlao', - audioname:['xin_chengpu'], - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + olchunlao: { + audio: "chunlao", + audioname: ["xin_chengpu"], + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - const evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.some(i=>i.name=='sha'&&get.position(i)=='d'); + filter(event, player) { + if (event.type != "discard" || event.getlx === false) return false; + const evt = event.getl(player); + return ( + evt && evt.cards2 && evt.cards2.some((i) => i.name == "sha" && get.position(i) == "d") + ); }, - forced:true, - locked:false, - content(){ - const evt=trigger.getl(player); - player.addToExpansion(evt.cards2.filter(i=>i.name=='sha'&&get.position(i)=='d'),'gain2').gaintag.add('olchunlao'); + forced: true, + locked: false, + content() { + const evt = trigger.getl(player); + player + .addToExpansion( + evt.cards2.filter((i) => i.name == "sha" && get.position(i) == "d"), + "gain2" + ) + .gaintag.add("olchunlao"); }, - ai:{ - effect:{ - player(card,player,target){ - if(_status.currentPhase!=player) return; - if(card.name=='sha'&&!player.getExpansions('olchunlao').length&&target.hp>1){ - return 'zeroplayertarget'; + ai: { + effect: { + player(card, player, target) { + if (_status.currentPhase != player) return; + if ( + card.name == "sha" && + !player.getExpansions("olchunlao").length && + target.hp > 1 + ) { + return "zeroplayertarget"; } }, }, }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'olchunlao_save', - subSkill:{ - save:{ - inherit:'chunlao2', - filter(event,player){ - return event.type=='dying'&&event.dying&&event.dying.hp<=0&&player.getExpansions('olchunlao').length; + group: "olchunlao_save", + subSkill: { + save: { + inherit: "chunlao2", + filter(event, player) { + return ( + event.type == "dying" && + event.dying && + event.dying.hp <= 0 && + player.getExpansions("olchunlao").length + ); }, - async content(event,trigger,player){ - const target=event.targets[0]; - const {result:{bool,links}}=await player.chooseCardButton(get.translation('olchunlao'),player.getExpansions('olchunlao'),true); - if(bool){ - player.logSkill('olchunlao',target); + async content(event, trigger, player) { + const target = event.targets[0]; + const { + result: { bool, links }, + } = await player.chooseCardButton( + get.translation("olchunlao"), + player.getExpansions("olchunlao"), + true + ); + if (bool) { + player.logSkill("olchunlao", target); await player.loseToDiscardpile(links); - event.type='dying'; - await target.useCard({name:'jiu',isCard:true},target); + event.type = "dying"; + await target.useCard({ name: "jiu", isCard: true }, target); } }, - ai:{ - save:true, - skillTagFilter(player){ - return player.getExpansions('olchunlao').length; + ai: { + save: true, + skillTagFilter(player) { + return player.getExpansions("olchunlao").length; }, - order:6, - result:{target:1}, + order: 6, + result: { target: 1 }, }, }, }, }, //虞翻 - olzongxuan:{ - audio:'rezongxuan', - trigger:{global:['loseAfter','loseAsyncAfter']}, - filter(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - return get.info('olzongxuan').getCards(event,player).length; + olzongxuan: { + audio: "rezongxuan", + trigger: { global: ["loseAfter", "loseAsyncAfter"] }, + filter(event, player) { + if (event.type != "discard" || event.getlx === false) return false; + return get.info("olzongxuan").getCards(event, player).length; }, - check(event,player){ - if(event.getParent(3).name!='phaseDiscard') return false; - const cards=get.info('olzongxuan').getCards(event,player); - return game.hasPlayer(target=>{ - if(cards.some(i=>get.type(i,target)=='equip')&&(get.attitude(player,target)>0||get.recoverEffect(target,player,player)>0)) return true; - if(cards.some(i=>get.type(i,target)!='equip')&&target.getHp()>=player.getHp()&&get.effect(target,{name:'losehp'},player,player)>0) return true; + check(event, player) { + if (event.getParent(3).name != "phaseDiscard") return false; + const cards = get.info("olzongxuan").getCards(event, player); + return game.hasPlayer((target) => { + if ( + cards.some((i) => get.type(i, target) == "equip") && + (get.attitude(player, target) > 0 || + get.recoverEffect(target, player, player) > 0) + ) + return true; + if ( + cards.some((i) => get.type(i, target) != "equip") && + target.getHp() >= player.getHp() && + get.effect(target, { name: "losehp" }, player, player) > 0 + ) + return true; return false; }); }, - async content(event,trigger,player){ - const {result:{bool,moved}}=await player.chooseToMove('纵玄:将任意张牌置于牌堆顶',true).set('list',[ - ['本次弃置的牌',get.info('olzongxuan').getCards(trigger,player)], - ['牌堆顶'], - ]).set('filterOk',moved=>moved[1].length).set('processAI',list=>{ - const player=get.event('player'); - const cards=list[0][1].slice(),cards2=cards.filter(card=>{ - return game.hasPlayer(target=>{ - if(get.type(card,target)=='equip'&&(get.attitude(player,target)>0||get.recoverEffect(target,player,player)>0)) return true; - if(get.type(card,target)!='equip'&&target.getHp()>=player.getHp()&&get.effect(target,{name:'losehp'},player,player)>0) return true; - return false; - }); - }),cards3=(cards2.length?cards2.randomGet():cards.randomGet()); - return [[],[cards3]]; - }); - if(bool){ - let cards=moved[1].slice(); - game.log(player,'将',cards,'置于了牌堆顶'); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); + async content(event, trigger, player) { + const { + result: { bool, moved }, + } = await player + .chooseToMove("纵玄:将任意张牌置于牌堆顶", true) + .set("list", [ + ["本次弃置的牌", get.info("olzongxuan").getCards(trigger, player)], + ["牌堆顶"], + ]) + .set("filterOk", (moved) => moved[1].length) + .set("processAI", (list) => { + const player = get.event("player"); + const cards = list[0][1].slice(), + cards2 = cards.filter((card) => { + return game.hasPlayer((target) => { + if ( + get.type(card, target) == "equip" && + (get.attitude(player, target) > 0 || + get.recoverEffect(target, player, player) > 0) + ) + return true; + if ( + get.type(card, target) != "equip" && + target.getHp() >= player.getHp() && + get.effect(target, { name: "losehp" }, player, player) > 0 + ) + return true; + return false; + }); + }), + cards3 = cards2.length ? cards2.randomGet() : cards.randomGet(); + return [[], [cards3]]; + }); + if (bool) { + let cards = moved[1].slice(); + game.log(player, "将", cards, "置于了牌堆顶"); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); } } }, - getCards(event,player){ - let cards=[]; - for(const target of [player,player.getPrevious()]){ - const evt=event.getl(target); - if(evt&&evt.cards2&&evt.cards2.some(i=>get.position(i)=='d')) cards.addArray(evt.cards2.filter(i=>get.position(i)=='d')); + getCards(event, player) { + let cards = []; + for (const target of [player, player.getPrevious()]) { + const evt = event.getl(target); + if (evt && evt.cards2 && evt.cards2.some((i) => get.position(i) == "d")) + cards.addArray(evt.cards2.filter((i) => get.position(i) == "d")); } return cards; }, }, - olzhiyan:{ - audio:'zhiyan', - audioname:['re_yufan'], - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - return event.player==player||event.player==player.getPrevious(); + olzhiyan: { + audio: "zhiyan", + audioname: ["re_yufan"], + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + return event.player == player || event.player == player.getPrevious(); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt2('olzhiyan')).set('ai',target=>{ - const player=get.event('player'),cards=get.event('cards'); - if(!cards.length) return 0; - const card=cards[0],att=get.attitude(player,target); - if(get.type(card,target)=='equip'&&(get.attitude(player,target)>0||get.recoverEffect(target,player,player)>0)) return get.recoverEffect(target,player,player)*20+att/114514; - if(get.type(card,target)!='equip'){ - if(target.getHp()>=player.getHp()) return get.effect(target,{name:'losehp'},player,player)*20-att/114514; - return get.effect(target,{name:'draw'},player,player); - } - return 0; - }).set('cards',Array.from(ui.cardPile.childNodes||[])||[]); - if(bool){ - const target=targets[0]; - player.logSkill('olzhiyan',target); - const {result}=await target.draw('visible'); - if(result){ - const card=result[0]; - if(get.type(card,target)=='equip'){ - if(target.getCards('h').includes(card)&&target.hasUseTarget(card)){ - const {result:{bool}}=await target.chooseUseTarget(card,true,'nopopup'); - if(bool) await target.recover(); - } + direct: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget(get.prompt2("olzhiyan")) + .set("ai", (target) => { + const player = get.event("player"), + cards = get.event("cards"); + if (!cards.length) return 0; + const card = cards[0], + att = get.attitude(player, target); + if ( + get.type(card, target) == "equip" && + (get.attitude(player, target) > 0 || + get.recoverEffect(target, player, player) > 0) + ) + return get.recoverEffect(target, player, player) * 20 + att / 114514; + if (get.type(card, target) != "equip") { + if (target.getHp() >= player.getHp()) + return ( + get.effect(target, { name: "losehp" }, player, player) * 20 - + att / 114514 + ); + return get.effect(target, { name: "draw" }, player, player); } - else if(target.getHp()>=player.getHp()) await target.loseHp(); + return 0; + }) + .set("cards", Array.from(ui.cardPile.childNodes || []) || []); + if (bool) { + const target = targets[0]; + player.logSkill("olzhiyan", target); + const { result } = await target.draw("visible"); + if (result) { + const card = result[0]; + if (get.type(card, target) == "equip") { + if (target.getCards("h").includes(card) && target.hasUseTarget(card)) { + const { + result: { bool }, + } = await target.chooseUseTarget(card, true, "nopopup"); + if (bool) await target.recover(); + } + } else if (target.getHp() >= player.getHp()) await target.loseHp(); } } }, - ai:{expose:0.2}, + ai: { expose: 0.2 }, }, //OL谋袁绍 //真·四世三公——袁神,启动 - olsbhetao:{ - audio:3, - audioname:['ol_sb_yuanshao_shadow'], - trigger:{global:'useCardToPlayered'}, - filter(event,player){ - return event.player!=player&&event.isFirstTarget&&event.targets.length>1&&player.countCards('he',card=>{ - if(get.position(card)=='h'&&_status.connectMode) return true; - return get.color(card)==get.color(event.card)&&lib.filter.cardDiscardable(card,player); - }); + olsbhetao: { + audio: 3, + audioname: ["ol_sb_yuanshao_shadow"], + trigger: { global: "useCardToPlayered" }, + filter(event, player) { + return ( + event.player != player && + event.isFirstTarget && + event.targets.length > 1 && + player.countCards("he", (card) => { + if (get.position(card) == "h" && _status.connectMode) return true; + return ( + get.color(card) == get.color(event.card) && + lib.filter.cardDiscardable(card, player) + ); + }) + ); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,cards,targets}}=await player.chooseCardTarget({ - prompt:get.prompt('olsbhetao'), - filterCard(card,player){ - return get.color(card)==get.color(get.event().getTrigger().card)&&lib.filter.cardDiscardable(card,player); - }, - position:'he', - filterTarget(card,player,target){ - return get.event().getTrigger().targets.includes(target); - }, - ai1(card){ - return 7.5-get.value(card); - }, - ai2(target){ - const player=get.event('player'),trigger=get.event().getTrigger(); - const att=get.attitude(player,target),eff=get.effect(target,trigger.card,trigger.player,player); - if(trigger.card.name=='tiesuo') return eff>0?0:get.sgn(att)*(2+get.sgn(att)); - const sum=trigger.targets.reduce((i,j)=>i+get.effect(j,trigger.card,trigger.player,player),0); - return get.sgn(att)*(eff*2-sum); - }, - }).set('prompt2','弃置一张'+get.translation(get.color(trigger.card))+'牌,令'+get.translation(trigger.card)+'改为对其中一个目标结算两次'); - if(bool){ - const target=targets[0]; - player.logSkill('olsbhetao',target); - player.changeSkin('olsbhetao','ol_sb_yuanshao'); + direct: true, + async content(event, trigger, player) { + const { + result: { bool, cards, targets }, + } = await player + .chooseCardTarget({ + prompt: get.prompt("olsbhetao"), + filterCard(card, player) { + return ( + get.color(card) == get.color(get.event().getTrigger().card) && + lib.filter.cardDiscardable(card, player) + ); + }, + position: "he", + filterTarget(card, player, target) { + return get.event().getTrigger().targets.includes(target); + }, + ai1(card) { + return 7.5 - get.value(card); + }, + ai2(target) { + const player = get.event("player"), + trigger = get.event().getTrigger(); + const att = get.attitude(player, target), + eff = get.effect(target, trigger.card, trigger.player, player); + if (trigger.card.name == "tiesuo") + return eff > 0 ? 0 : get.sgn(att) * (2 + get.sgn(att)); + const sum = trigger.targets.reduce( + (i, j) => i + get.effect(j, trigger.card, trigger.player, player), + 0 + ); + return get.sgn(att) * (eff * 2 - sum); + }, + }) + .set( + "prompt2", + "弃置一张" + + get.translation(get.color(trigger.card)) + + "牌,令" + + get.translation(trigger.card) + + "改为对其中一个目标结算两次" + ); + if (bool) { + const target = targets[0]; + player.logSkill("olsbhetao", target); + player.changeSkin("olsbhetao", "ol_sb_yuanshao"); player.discard(cards); trigger.getParent().effectCount++; - trigger.getParent().excluded.addArray(game.filterPlayer(i=>trigger.targets.includes(i)&&target!=i)); + trigger + .getParent() + .excluded.addArray( + game.filterPlayer((i) => trigger.targets.includes(i) && target != i) + ); } }, - ai:{threaten:3.5}, - global:'olsbhetao_ai', - subSkill:{ - ai:{ - effect:{ - player(card,player){ - if(!game.hasPlayer(target=>{ - return target.hasSkill('olsbhetao')&&(get.attitude(player,target)<0||get.attitude(target,player)<0); - })||game.countPlayer(target=>{ - return player.canUse(card,target); - })<2) return; - const select=get.copy(get.info(card).selectTarget); + ai: { threaten: 3.5 }, + global: "olsbhetao_ai", + subSkill: { + ai: { + effect: { + player(card, player) { + if ( + !game.hasPlayer((target) => { + return ( + target.hasSkill("olsbhetao") && + (get.attitude(player, target) < 0 || + get.attitude(target, player) < 0) + ); + }) || + game.countPlayer((target) => { + return player.canUse(card, target); + }) < 2 + ) + return; + const select = get.copy(get.info(card).selectTarget); let range; - if(select==undefined) range=[1,1]; - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); - if(range[1]==-1||(range[1]>1&&ui.selected.targets&&ui.selected.targets.length)) return 'zeroplayertarget'; + if (select == undefined) range = [1, 1]; + else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); + if ( + range[1] == -1 || + (range[1] > 1 && ui.selected.targets && ui.selected.targets.length) + ) + return "zeroplayertarget"; }, }, }, }, }, - olsbshenli:{ - audio:3, - audioname:['ol_sb_yuanshao_shadow'], - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!player.isPhaseUsing()||player.hasSkill('olsbshenli_used')) return false; - return event.card.name=='sha'&&game.hasPlayer(target=>{ - return !event.targets.includes(target)&&player.canUse(event.card,target,false); - })&&event.isFirstTarget; + olsbshenli: { + audio: 3, + audioname: ["ol_sb_yuanshao_shadow"], + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!player.isPhaseUsing() || player.hasSkill("olsbshenli_used")) return false; + return ( + event.card.name == "sha" && + game.hasPlayer((target) => { + return ( + !event.targets.includes(target) && player.canUse(event.card, target, false) + ); + }) && + event.isFirstTarget + ); }, - check(event,player){ - const targets=game.filterPlayer(target=>player.canUse(event.card,target,false)); - const num1=event.targets.reduce((sum,target)=>sum+get.effect(target,event.card,player,player),0); - const num2=targets.reduce((sum,target)=>sum+get.effect(target,event.card,player,player),0); - if(num2>=num1) return true; - let num=(event.baseDamage||1); - if(event.extraDamage) num+=event.extraDamage; - let extra_num=0; - for(const target of targets){ - if(target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:event.card, - },true)){ - if(player.hasSkill('jueqing')||target.hasSkill('gangzhi')) extra_num--; - else if(target.hasSkillTag('filterDamage',null,{ - player:event.player, - card:event.card, - })) extra_num++; - } - else extra_num+=num; + check(event, player) { + const targets = game.filterPlayer((target) => player.canUse(event.card, target, false)); + const num1 = event.targets.reduce( + (sum, target) => sum + get.effect(target, event.card, player, player), + 0 + ); + const num2 = targets.reduce( + (sum, target) => sum + get.effect(target, event.card, player, player), + 0 + ); + if (num2 >= num1) return true; + let num = event.baseDamage || 1; + if (event.extraDamage) num += event.extraDamage; + let extra_num = 0; + for (const target of targets) { + if ( + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: event.card, + }, + true + ) + ) { + if (player.hasSkill("jueqing") || target.hasSkill("gangzhi")) extra_num--; + else if ( + target.hasSkillTag("filterDamage", null, { + player: event.player, + card: event.card, + }) + ) + extra_num++; + } else extra_num += num; } - const sum=targets.length+extra_num; - return num2+(sum>player.countCards('h')?Math.min(5,sum):0)+(sum>player.getHp()?num2:0)>=num1; + const sum = targets.length + extra_num; + return ( + num2 + + (sum > player.countCards("h") ? Math.min(5, sum) : 0) + + (sum > player.getHp() ? num2 : 0) >= + num1 + ); }, - async content(event,trigger,player){ - player.changeSkin('olsbshenli','ol_sb_yuanshao_shadow'); - player.addTempSkill('olsbshenli_used','phaseUseAfter'); - trigger.getParent().targets.addArray(game.filterPlayer(target=>{ - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target,false); - })); - player.when('useCardAfter').filter(evt=>evt==trigger.getParent()) - .then(()=>{ - const sum=player.getHistory('sourceDamage',evt=>evt.card&&evt.card==trigger.card).reduce((num,evt)=>{ - return num+evt.num; - },0); - const bool=(sum>player.countCards('h')),goon=(sum>player.getHp()); - if(bool) player.draw(Math.min(5,sum)); - if(goon){ - const targets=game.filterPlayer(target=>trigger.targets.includes(target)&&player.canUse(trigger.card,target,false)); - if(targets.length&&(!trigger.cards||!trigger.cards.length||trigger.cards.every(card=>{ - return !get.owner(card); - }))) player.useCard(trigger.card,targets,false); - } - }); + async content(event, trigger, player) { + player.changeSkin("olsbshenli", "ol_sb_yuanshao_shadow"); + player.addTempSkill("olsbshenli_used", "phaseUseAfter"); + trigger.getParent().targets.addArray( + game.filterPlayer((target) => { + return ( + !trigger.targets.includes(target) && + player.canUse(trigger.card, target, false) + ); + }) + ); + player + .when("useCardAfter") + .filter((evt) => evt == trigger.getParent()) + .then(() => { + const sum = player + .getHistory("sourceDamage", (evt) => evt.card && evt.card == trigger.card) + .reduce((num, evt) => { + return num + evt.num; + }, 0); + const bool = sum > player.countCards("h"), + goon = sum > player.getHp(); + if (bool) player.draw(Math.min(5, sum)); + if (goon) { + const targets = game.filterPlayer( + (target) => + trigger.targets.includes(target) && + player.canUse(trigger.card, target, false) + ); + if ( + targets.length && + (!trigger.cards || + !trigger.cards.length || + trigger.cards.every((card) => { + return !get.owner(card); + })) + ) + player.useCard(trigger.card, targets, false); + } + }); }, - ai:{threaten:3.5}, - subSkill:{used:{charlotte:true}}, + ai: { threaten: 3.5 }, + subSkill: { used: { charlotte: true } }, }, - olsbyufeng:{ - audio:2, - audioname2:{ - ol_sb_yuanshao_shadow:'olsbyufeng_ol_sb_yuanshao_shadow', + olsbyufeng: { + audio: 2, + audioname2: { + ol_sb_yuanshao_shadow: "olsbyufeng_ol_sb_yuanshao_shadow", }, - trigger:{ - global:'phaseBefore', - player:'enterGame', + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter(event,player){ - const card=get.cardPile('sizhaojian','field')||game.createCard2('sizhaojian','diamond',6); - return (event.name!='phase'||game.phaseNumber==0)&&player.canEquip(card,true); + filter(event, player) { + const card = + get.cardPile("sizhaojian", "field") || game.createCard2("sizhaojian", "diamond", 6); + return (event.name != "phase" || game.phaseNumber == 0) && player.canEquip(card, true); }, - forced:true, - locked:false, - async content(event,trigger,player){ - if(lib.card.sizhaojian.inShanShanFestival()){ - game.broadcastAll(()=>lib.inpile.add('sizhaojian')); + forced: true, + locked: false, + async content(event, trigger, player) { + if (lib.card.sizhaojian.inShanShanFestival()) { + game.broadcastAll(() => lib.inpile.add("sizhaojian")); } - const card=get.cardPile('sizhaojian','field')||game.createCard2('sizhaojian','diamond',6); - if(get.owner(card)) get.owner(card).$give(card,player,false); - else{ - player.$gain2(card,false); + const card = + get.cardPile("sizhaojian", "field") || game.createCard2("sizhaojian", "diamond", 6); + if (get.owner(card)) get.owner(card).$give(card, player, false); + else { + player.$gain2(card, false); game.delayx(); } player.equip(card); }, - subSkill:{ - ol_sb_yuanshao_shadow:{ - audio:1, + subSkill: { + ol_sb_yuanshao_shadow: { + audio: 1, }, - sizhaojian:{ - equipSkill:true, - mod:{ - aiOrder(player,card,num){ - if(card.name=='sha'&&typeof get.number(card)=='number') return num+get.number(card)/114514; + sizhaojian: { + equipSkill: true, + mod: { + aiOrder(player, card, num) { + if (card.name == "sha" && typeof get.number(card) == "number") + return num + get.number(card) / 114514; }, }, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return event.card.name=='sha'&&typeof get.number(event.card)=='number'; + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return event.card.name == "sha" && typeof get.number(event.card) == "number"; }, - forced:true, - locked:false, - logTarget:'target', - async content(event,trigger,player){ - const target=trigger.target; - target.addTempSkill('olsbyufeng_block'); - target.markAuto('olsbyufeng_block',[trigger.card]); + forced: true, + locked: false, + logTarget: "target", + async content(event, trigger, player) { + const target = trigger.target; + target.addTempSkill("olsbyufeng_block"); + target.markAuto("olsbyufeng_block", [trigger.card]); }, }, - block:{ - mod:{ - cardEnabled(card,player){ - if(!player.storage.olsbyufeng_block) return; - const storage=player.getStorage('olsbyufeng_block'); - let evt=_status.event; - if(evt.name!='chooseToUse') evt=evt.getParent('chooseToUse'); - if(!evt||!evt.respondTo||!storage.includes(evt.respondTo[1])) return; - const num=get.number(card); - if(num!='unsure'&&typeof num=='number'&&num{ - if(target==player||target.group!='qun') return false; - const evt=event.getl(target); - return evt&&evt.player==target&&evt.es&&evt.es.length>0; + olsbshishou: { + unique: true, + audio: 3, + audioname: ["ol_sb_yuanshao_shadow"], + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + filter(event, player) { + if (player.getEquip(1)) return false; + const card = + get.cardPile("sizhaojian", "field") || game.createCard2("sizhaojian", "diamond", 6); + if (!player.canEquip(card, true)) return false; + return game.hasPlayer((target) => { + if (target == player || target.group != "qun") return false; + const evt = event.getl(target); + return evt && evt.player == target && evt.es && evt.es.length > 0; }); }, - direct:true, - zhuSkill:true, - async content(event,trigger,player){ - const targets=game.filterPlayer(target=>{ - if(target==player||target.group!='qun') return false; - const evt=trigger.getl(target); - return evt&&evt.player==target&&evt.es&&evt.es.length>0; - }).sortBySeat(); - const card=get.cardPile('sizhaojian','field')||game.createCard2('sizhaojian','diamond',6); - for(const target of targets){ - const {result:{bool}}=await target.chooseBool(get.prompt('olsbshishou',player),'将'+get.translation(card)+'置入'+get.translation(player)+'的装备区中').set('choice',get.attitude(target,player)>0); - if(bool){ - target.logSkill('olsbshishou',player); - if(get.owner(card)) get.owner(card).$give(card,player,false); - else{ - player.$gain2(card,false); + direct: true, + zhuSkill: true, + async content(event, trigger, player) { + const targets = game + .filterPlayer((target) => { + if (target == player || target.group != "qun") return false; + const evt = trigger.getl(target); + return evt && evt.player == target && evt.es && evt.es.length > 0; + }) + .sortBySeat(); + const card = + get.cardPile("sizhaojian", "field") || game.createCard2("sizhaojian", "diamond", 6); + for (const target of targets) { + const { + result: { bool }, + } = await target + .chooseBool( + get.prompt("olsbshishou", player), + "将" + get.translation(card) + "置入" + get.translation(player) + "的装备区中" + ) + .set("choice", get.attitude(target, player) > 0); + if (bool) { + target.logSkill("olsbshishou", player); + if (get.owner(card)) get.owner(card).$give(card, player, false); + else { + player.$gain2(card, false); game.delayx(); } player.equip(card); @@ -621,806 +901,1042 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } }, - ai:{combo:'olsbyufeng'}, + ai: { combo: "olsbyufeng" }, }, //界高顺 - olxianzhen:{ - audio:'rexianzhen', - inherit:'xianzhen', - async content(event,trigger,player){ - const target=event.target; - const {result:{bool}}=await player.chooseToCompare(target); - if(bool){ - player.storage.xinxianzhen=target; - player.addTempSkill('xinxianzhen2'); - } - else{ - player.markAuto('olxianzhen_buff',[target]); - player.addTempSkill('olxianzhen_buff'); + olxianzhen: { + audio: "rexianzhen", + inherit: "xianzhen", + async content(event, trigger, player) { + const target = event.target; + const { + result: { bool }, + } = await player.chooseToCompare(target); + if (bool) { + player.storage.xinxianzhen = target; + player.addTempSkill("xinxianzhen2"); + } else { + player.markAuto("olxianzhen_buff", [target]); + player.addTempSkill("olxianzhen_buff"); } }, - subSkill:{ - buff:{ - charlotte:true, - onremove:true, - mod:{ - playerEnabled(card,player,target){ - if(get.name(card,player)=='sha'&&player.getStorage('olxianzhen_buff').includes(target)) return false; + subSkill: { + buff: { + charlotte: true, + onremove: true, + mod: { + playerEnabled(card, player, target) { + if ( + get.name(card, player) == "sha" && + player.getStorage("olxianzhen_buff").includes(target) + ) + return false; }, - ignoredHandcard(card,player){ - if(get.name(card,player)=='sha') return true; + ignoredHandcard(card, player) { + if (get.name(card, player) == "sha") return true; }, - cardDiscardable(card,player,name){ - if(name=='phaseDiscard'&&get.name(card,player)=='sha') return false; + cardDiscardable(card, player, name) { + if (name == "phaseDiscard" && get.name(card, player) == "sha") return false; }, }, }, }, }, //新OL谋关羽 - olsbweilin:{ - audio:2, - enable:'chooseToUse', - filter(event,player){ - return get.inpileVCardList(info=>{ - const name=info[2]; - if(name!='sha'&&name!='jiu') return false; - return get.type(name)=='basic'; - }).some(card=>player.hasCard(cardx=>event.filterCard({name:card[2],nature:card[3],cards:[cardx]},player,event),'hes')); + olsbweilin: { + audio: 2, + enable: "chooseToUse", + filter(event, player) { + return get + .inpileVCardList((info) => { + const name = info[2]; + if (name != "sha" && name != "jiu") return false; + return get.type(name) == "basic"; + }) + .some((card) => + player.hasCard( + (cardx) => + event.filterCard( + { name: card[2], nature: card[3], cards: [cardx] }, + player, + event + ), + "hes" + ) + ); }, - usable:1, - chooseButton:{ - dialog(event,player){ - const list=get.inpileVCardList(info=>{ - const name=info[2]; - if(name!='sha'&&name!='jiu') return false; - return get.type(name)=='basic'; - }).filter(card=>player.hasCard(cardx=>event.filterCard({name:card[2],nature:card[3],cards:[cardx]},player,event),'hes')); - return ui.create.dialog('威临',[list,'vcard']); + usable: 1, + chooseButton: { + dialog(event, player) { + const list = get + .inpileVCardList((info) => { + const name = info[2]; + if (name != "sha" && name != "jiu") return false; + return get.type(name) == "basic"; + }) + .filter((card) => + player.hasCard( + (cardx) => + event.filterCard( + { name: card[2], nature: card[3], cards: [cardx] }, + player, + event + ), + "hes" + ) + ); + return ui.create.dialog("威临", [list, "vcard"]); }, - filter(button,player){ - return _status.event.getParent().filterCard({name:button.link[2],nature:button.link[3]},player,_status.event.getParent()); + filter(button, player) { + return _status.event + .getParent() + .filterCard( + { name: button.link[2], nature: button.link[3] }, + player, + _status.event.getParent() + ); }, - check(button){ - if(_status.event.getParent().type!='phase') return 1; - const player=get.event('player'),value=player.getUseValue({name:button.link[2],nature:button.link[3]}); - if(button.link[2]=='sha'&&!player.getHistory('useCard',evt=>get.type(evt.card)=='basic').length){ - if(value>0) return value+20; + check(button) { + if (_status.event.getParent().type != "phase") return 1; + const player = get.event("player"), + value = player.getUseValue({ name: button.link[2], nature: button.link[3] }); + if ( + button.link[2] == "sha" && + !player.getHistory("useCard", (evt) => get.type(evt.card) == "basic").length + ) { + if (value > 0) return value + 20; } return value; }, - backup(links,player){ + backup(links, player) { return { - audio:'olsbweilin', - filterCard:true, - popname:true, - check(card){ - const name=lib.skill.olsbweilin_backup.viewAs.name,color=get.color(card); - const phase=(_status.event.getParent().type=='phase'); - if(phase&&name=='sha'&&color=='red') return 10-get.value(card); - if(name=='tao') return 7+[-2,0,2][['black','red','none'].indexOf(color)]-get.value(card); - return 6-get.value(card); + audio: "olsbweilin", + filterCard: true, + popname: true, + check(card) { + const name = lib.skill.olsbweilin_backup.viewAs.name, + color = get.color(card); + const phase = _status.event.getParent().type == "phase"; + if (phase && name == "sha" && color == "red") return 10 - get.value(card); + if (name == "tao") + return ( + 7 + + [-2, 0, 2][["black", "red", "none"].indexOf(color)] - + get.value(card) + ); + return 6 - get.value(card); }, - position:'hse', - viewAs:{name:links[0][2],nature:links[0][3]}, - precontent(){ - if(!player.storage.olsbweilin_backup){ - player.storage.olsbweilin_backup=true; - player.when('useCardToTargeted') - .filter(evt=>evt.getParent().skill=='olsbweilin_backup'&&evt.getParent().triggeredTargets3.length==evt.targets.length) - .then(()=>{ - delete player.storage.olsbweilin_backup; - const targets=trigger.targets.slice().sortBySeat(); - player.line(targets); - for(const target of targets){ - target.addTempSkill('olsbweilin_wusheng'); - target.markAuto('olsbweilin_wusheng',[get.color(trigger.card)]); - } - }); + position: "hse", + viewAs: { name: links[0][2], nature: links[0][3] }, + precontent() { + if (!player.storage.olsbweilin_backup) { + player.storage.olsbweilin_backup = true; + player + .when("useCardToTargeted") + .filter( + (evt) => + evt.getParent().skill == "olsbweilin_backup" && + evt.getParent().triggeredTargets3.length == evt.targets.length + ) + .then(() => { + delete player.storage.olsbweilin_backup; + const targets = trigger.targets.slice().sortBySeat(); + player.line(targets); + for (const target of targets) { + target.addTempSkill("olsbweilin_wusheng"); + target.markAuto("olsbweilin_wusheng", [ + get.color(trigger.card), + ]); + } + }); } }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(get.event('skill')!='olsbweilin_backup') return false; - return arg&&arg.card&&arg.card.name=='sha'&&get.color(arg.card)=='red'; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if (get.event("skill") != "olsbweilin_backup") return false; + return ( + arg && + arg.card && + arg.card.name == "sha" && + get.color(arg.card) == "red" + ); }, }, - } + }; }, - prompt(links,player){ - return '将一张牌当作'+(get.translation(links[0][3])||'')+'【'+get.translation(links[0][2])+'】使用'; - } - }, - hiddenCard(player,name){ - if(!lib.inpile.includes(name)||name!='jiu') return false; - return get.type(name)=='basic'&&!player.getStat('skill').olsbweilin&&player.countCards('hes'); - }, - ai:{ - fireAttack:true, - respondSha:true, - skillTagFilter(player,tag,arg){ - if(arg=='respond') return false; - if(player.getStat('skill').olsbweilin||!player.countCards('hes')) return false; + prompt(links, player) { + return ( + "将一张牌当作" + + (get.translation(links[0][3]) || "") + + "【" + + get.translation(links[0][2]) + + "】使用" + ); }, - order(item,player){ - if(player&&_status.event.type=='phase'&&player.hasValueTarget({name:'sha'},true,true)){ - let max=0,names=get.inpileVCardList(info=>{ - const name=info[2]; - if(name!='sha'&&name!='jiu') return false; - return get.type(name)=='basic'; + }, + hiddenCard(player, name) { + if (!lib.inpile.includes(name) || name != "jiu") return false; + return ( + get.type(name) == "basic" && + !player.getStat("skill").olsbweilin && + player.countCards("hes") + ); + }, + ai: { + fireAttack: true, + respondSha: true, + skillTagFilter(player, tag, arg) { + if (arg == "respond") return false; + if (player.getStat("skill").olsbweilin || !player.countCards("hes")) return false; + }, + order(item, player) { + if ( + player && + _status.event.type == "phase" && + player.hasValueTarget({ name: "sha" }, true, true) + ) { + let max = 0, + names = get.inpileVCardList((info) => { + const name = info[2]; + if (name != "sha" && name != "jiu") return false; + return get.type(name) == "basic"; + }); + names = names.map((namex) => { + return { name: namex[2], nature: namex[3] }; }); - names=names.map(namex=>{return {name:namex[2],nature:namex[3]}}); - names.forEach(card=>{ - if(player.getUseValue(card)>0){ - let temp=get.order(card); - if(card.name=='jiu'){ - let cards=player.getCards('hs',cardx=>get.value(cardx)<8); - cards.sort((a,b)=>get.value(a)-get.value(b)); - if(!cards.some(cardx=>get.name(cardx)=='sha'&&!cards.slice(0,2).includes(cardx))) temp=0; + names.forEach((card) => { + if (player.getUseValue(card) > 0) { + let temp = get.order(card); + if (card.name == "jiu") { + let cards = player.getCards("hs", (cardx) => get.value(cardx) < 8); + cards.sort((a, b) => get.value(a) - get.value(b)); + if ( + !cards.some( + (cardx) => + get.name(cardx) == "sha" && + !cards.slice(0, 2).includes(cardx) + ) + ) + temp = 0; } - if(temp>max) max=temp; + if (temp > max) max = temp; } }); - if(max>0) max+=15; + if (max > 0) max += 15; return max; } return 0.5; }, - result:{ - player(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player(player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - backup:{}, - wusheng:{ - charlotte:true, - onremove:true, - mod:{ - cardname(card,player){ - if(player.getStorage('olsbweilin_wusheng').includes(get.color(card))) return 'sha'; + subSkill: { + backup: {}, + wusheng: { + charlotte: true, + onremove: true, + mod: { + cardname(card, player) { + if (player.getStorage("olsbweilin_wusheng").includes(get.color(card))) + return "sha"; }, }, - intro:{content:'手牌中所有$牌均视为【杀】'}, + intro: { content: "手牌中所有$牌均视为【杀】" }, }, }, }, - olsbduoshou:{ - init(player){ - if(player.getHistory('useCard',evt=>get.color(evt.card)=='red').length) player.addTempSkill('olsbduoshou_used'); + olsbduoshou: { + init(player) { + if (player.getHistory("useCard", (evt) => get.color(evt.card) == "red").length) + player.addTempSkill("olsbduoshou_used"); }, - mod:{ - targetInRange(card,player,target){ - if(get.color(card)=='red'&&!player.hasSkill('olsbduoshou_used')) return true; + mod: { + targetInRange(card, player, target) { + if (get.color(card) == "red" && !player.hasSkill("olsbduoshou_used")) return true; }, }, - audio:2, - trigger:{ - player:'useCard', - source:'damageSource', + audio: 2, + trigger: { + player: "useCard", + source: "damageSource", }, - filter(event,player){ - if(event.name=='damage') return player.getHistory('sourceDamage').indexOf(event)==0; - if(get.color(event.card)=='red'&&!player.hasSkill('olsbduoshou_used')) return true; - return get.type(event.card)=='basic'&&player.getHistory('useCard',evt=>get.type(evt.card)=='basic').indexOf(event)==0; + filter(event, player) { + if (event.name == "damage") return player.getHistory("sourceDamage").indexOf(event) == 0; + if (get.color(event.card) == "red" && !player.hasSkill("olsbduoshou_used")) return true; + return ( + get.type(event.card) == "basic" && + player.getHistory("useCard", (evt) => get.type(evt.card) == "basic").indexOf(event) == + 0 + ); }, - forced:true, - async content(event,trigger,player){ - if(trigger.name=='damage') player.draw(); - else{ - if(get.color(trigger.card)=='red'&&!player.hasSkill('olsbduoshou_used')){ - game.log(trigger.card,'无距离限制'); - player.addTempSkill('olsbduoshou_used'); + forced: true, + async content(event, trigger, player) { + if (trigger.name == "damage") player.draw(); + else { + if (get.color(trigger.card) == "red" && !player.hasSkill("olsbduoshou_used")) { + game.log(trigger.card, "无距离限制"); + player.addTempSkill("olsbduoshou_used"); } - if(get.type(trigger.card)=='basic'&&player.getHistory('useCard',evt=>get.type(evt.card)=='basic').indexOf(trigger)==0){ - game.log(trigger.card,'不计入次数上限'); + if ( + get.type(trigger.card) == "basic" && + player + .getHistory("useCard", (evt) => get.type(evt.card) == "basic") + .indexOf(trigger) == 0 + ) { + game.log(trigger.card, "不计入次数上限"); if (trigger.addCount !== false) { - trigger.addCount=false; - const stat = player.stat[player.stat.length-1].card; - if (typeof stat[trigger.card.name] === 'number') stat[trigger.card.name]--; + trigger.addCount = false; + const stat = player.stat[player.stat.length - 1].card; + if (typeof stat[trigger.card.name] === "number") stat[trigger.card.name]--; } } } }, - subSkill:{used:{charlotte:true}}, + subSkill: { used: { charlotte: true } }, }, //OL谋太史慈 - olsbdulie:{ - audio:2, - trigger:{target:'useCardToTarget'}, - filter(event,player){ - if(event.player==player||!event.isFirstTarget||event.targets.length!=1) return false; - if(player.getAttackRange()<=0) return; - return ['basic','trick'].includes(get.type(event.card)); + olsbdulie: { + audio: 2, + trigger: { target: "useCardToTarget" }, + filter(event, player) { + if (event.player == player || !event.isFirstTarget || event.targets.length != 1) + return false; + if (player.getAttackRange() <= 0) return; + return ["basic", "trick"].includes(get.type(event.card)); }, - prompt2(event,player){ - return '令'+get.translation(event.card)+'额外结算一次,此牌结算完毕后,你摸等同于你攻击范围的牌'; + prompt2(event, player) { + return ( + "令" + + get.translation(event.card) + + "额外结算一次,此牌结算完毕后,你摸等同于你攻击范围的牌" + ); }, - check(event,player){ - const num=Math.min(5,player.getAttackRange()); - if(get.effect(player,event.card,event.player,player)>0) return true; - if(event.card.name=='guohe'||event.card.name=='shunshou'||event.card.name=='zhujinqiyuan') return num>(event.effectCount||0); - if(!get.tag(event.card,'damage')) return true; - return num>1; + check(event, player) { + const num = Math.min(5, player.getAttackRange()); + if (get.effect(player, event.card, event.player, player) > 0) return true; + if ( + event.card.name == "guohe" || + event.card.name == "shunshou" || + event.card.name == "zhujinqiyuan" + ) + return num > (event.effectCount || 0); + if (!get.tag(event.card, "damage")) return true; + return num > 1; }, - usable:1, - async content(event,trigger,player){ + usable: 1, + async content(event, trigger, player) { trigger.getParent().effectCount++; - player.when({global:'useCardAfter'}) - .filter(evt=>evt==trigger.getParent()) - .then(()=>{ - const num=Math.min(5,player.getAttackRange()); - if(num>0) player.draw(num); - }); + player + .when({ global: "useCardAfter" }) + .filter((evt) => evt == trigger.getParent()) + .then(() => { + const num = Math.min(5, player.getAttackRange()); + if (num > 0) player.draw(num); + }); }, }, - olsbdouchan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - async content(event,trigger,player){ - const card=get.cardPile2(card=>card.name=='juedou'); - if(card) player.gain(card,'gain2'); - else if(player.countMark('olsbdouchan') card.name == "juedou"); + if (card) player.gain(card, "gain2"); + else if (player.countMark("olsbdouchan") < game.players.length + game.dead.length) + player.addMark("olsbdouchan", 1, false); }, - mod:{ - attackRange(player,num){ - return num+player.countMark('olsbdouchan'); + mod: { + attackRange(player, num) { + return num + player.countMark("olsbdouchan"); }, - cardUsable(card,player,num){ - if(card.name=='sha') return num+player.countMark('olsbdouchan'); + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("olsbdouchan"); }, }, - intro:{content:'
            • 攻击距离+#
            • 使用【杀】的次数上限+#'}, + intro: { content: "
            • 攻击距离+#
            • 使用【杀】的次数上限+#" }, }, //OL谋关羽 //可以和手杀谋关羽组成卧龙凤雏了 - olsbfumeng:{ - audio:2, - trigger:{global:'roundStart'}, - filter(event,player){ - return player.countCards('h',card=>{ - if(_status.connectMode) return true; - return get.name(card,player)!='sha'; + olsbfumeng: { + audio: 2, + trigger: { global: "roundStart" }, + filter(event, player) { + return player.countCards("h", (card) => { + if (_status.connectMode) return true; + return get.name(card, player) != "sha"; }); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,cards}}=await player.chooseCard(get.prompt2('olsbfumeng'),[1,Infinity],(card,player)=>{ - return get.name(card,player)!='sha'; - }).set('ai',card=>{ - const player=get.event('player'); - if(player.hasSkill('olsbfumeng')) return 7-get.value(card); - return 4.5-get.value(card); - }); - if(!bool) return; - player.logSkill('olsbfumeng'); - player.addSkill('olsbfumeng_buff'); - player.addGaintag(cards,'olsbfumeng_buff'); + direct: true, + async content(event, trigger, player) { + const { + result: { bool, cards }, + } = await player + .chooseCard(get.prompt2("olsbfumeng"), [1, Infinity], (card, player) => { + return get.name(card, player) != "sha"; + }) + .set("ai", (card) => { + const player = get.event("player"); + if (player.hasSkill("olsbfumeng")) return 7 - get.value(card); + return 4.5 - get.value(card); + }); + if (!bool) return; + player.logSkill("olsbfumeng"); + player.addSkill("olsbfumeng_buff"); + player.addGaintag(cards, "olsbfumeng_buff"); }, - subSkill:{ - buff:{ - charlotte:true, - mod:{ - cardname:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('olsbfumeng_buff')) return 'sha'; + subSkill: { + buff: { + charlotte: true, + mod: { + cardname: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("olsbfumeng_buff")) + return "sha"; }, }, }, }, }, - olsbguidao:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - if(event.olsbguidao_num>2) return false; - const card=new lib.element.VCard({name:'juedou',storage:{olsbguidao:true}}); - return game.hasPlayer(target=>{ - return player.canUse(card,target,false); - })&&player.countCards('he',cardx=>{ - return player.canRecast(cardx); - })>=2&&player.countCards('he',cardx=>{ - return get.name(cardx,player)=='sha'&&player.canRecast(cardx); - })>=event.olsbguidao_num; + olsbguidao: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + if (event.olsbguidao_num > 2) return false; + const card = new lib.element.VCard({ name: "juedou", storage: { olsbguidao: true } }); + return ( + game.hasPlayer((target) => { + return player.canUse(card, target, false); + }) && + player.countCards("he", (cardx) => { + return player.canRecast(cardx); + }) >= 2 && + player.countCards("he", (cardx) => { + return get.name(cardx, player) == "sha" && player.canRecast(cardx); + }) >= event.olsbguidao_num + ); }, - onChooseToUse(event){ - if(!game.online&&!event.olsbguidao_num){ - const player=event.player,history=player.getHistory('custom',evt=>evt.olsbguidao_num); - if(!history.length) event.set('olsbguidao_num',1); - else{ - const evt=history[history.length-1]; - event.set('olsbguidao_num',evt.olsbguidao_num); + onChooseToUse(event) { + if (!game.online && !event.olsbguidao_num) { + const player = event.player, + history = player.getHistory("custom", (evt) => evt.olsbguidao_num); + if (!history.length) event.set("olsbguidao_num", 1); + else { + const evt = history[history.length - 1]; + event.set("olsbguidao_num", evt.olsbguidao_num); } } }, - filterCard(card,player){ - const num=get.event('olsbguidao_num'); - if(ui.selected.cards.filter(cardx=>get.name(cardx,player)=='sha').length get.name(cardx, player) == "sha").length < num && + get.name(card, player) != "sha" + ) + return false; return player.canRecast(card); }, - selectCard:2, - position:'he', - check(card){ - const player=get.event('player'); - if(get.name(card,player)=='sha') return 1/(get.value(card)||0.5); - return 7-get.value(card); + selectCard: 2, + position: "he", + check(card) { + const player = get.event("player"); + if (get.name(card, player) == "sha") return 1 / (get.value(card) || 0.5); + return 7 - get.value(card); }, - complexCard:true, - lose:false, - discard:false, - delay:0, - filterTarget(card,player,target){ - const cardx=new lib.element.VCard({name:'juedou',storage:{olsbguidao:true}}); - return player.canUse(cardx,target,false); + complexCard: true, + lose: false, + discard: false, + delay: 0, + filterTarget(card, player, target) { + const cardx = new lib.element.VCard({ name: "juedou", storage: { olsbguidao: true } }); + return player.canUse(cardx, target, false); }, - prompt(){ - let str='重铸两张牌'; - const num=get.event('olsbguidao_num'); - if(num>0) str+='(至少重铸'+get.cnNumber(num)+'张【杀】)'; - str+='并视为使用【决斗】'; + prompt() { + let str = "重铸两张牌"; + const num = get.event("olsbguidao_num"); + if (num > 0) str += "(至少重铸" + get.cnNumber(num) + "张【杀】)"; + str += "并视为使用【决斗】"; return str; }, - async content(event,trigger,player){ - const target=event.target,cards=event.cards; - player.getHistory('custom').push({olsbguidao_num:cards.filter(card=>get.name(card,player)=='sha').length+1}); - const card=new lib.element.VCard({name:'juedou',storage:{olsbguidao:true}}); + async content(event, trigger, player) { + const target = event.target, + cards = event.cards; + player.getHistory("custom").push({ + olsbguidao_num: cards.filter((card) => get.name(card, player) == "sha").length + 1, + }); + const card = new lib.element.VCard({ name: "juedou", storage: { olsbguidao: true } }); await player.recast(cards); - player.addTempSkill('olsbguidao_buff'); - if(player.canUse(card,target,false)) player.useCard(card,target,false); + player.addTempSkill("olsbguidao_buff"); + if (player.canUse(card, target, false)) player.useCard(card, target, false); }, - ai:{ - order(item,player){ - const card=new lib.element.VCard({name:'juedou',storage:{olsbguidao:true}}); - const order=get.order(card,player); - if(order<=0) return 0; - return order+0.1; + ai: { + order(item, player) { + const card = new lib.element.VCard({ name: "juedou", storage: { olsbguidao: true } }); + const order = get.order(card, player); + if (order <= 0) return 0; + return order + 0.1; }, - result:{ - target(player,target){ - const card=new lib.element.VCard({name:'juedou',storage:{olsbguidao:true}}); - return get.sgn(get.attitude(player,target))*get.effect(target,card,player,player); + result: { + target(player, target) { + const card = new lib.element.VCard({ + name: "juedou", + storage: { olsbguidao: true }, + }); + return ( + get.sgn(get.attitude(player, target)) * + get.effect(target, card, player, player) + ); }, }, }, - subSkill:{ - buff:{ - charlotte:true, - trigger:{global:'damageBegin3'}, - filter(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.olsbguidao) return false; - if(!event.source||event.source!=player) return false; - const evt=event.getParent('useCard'); - return evt.player==player&&evt.targets.includes(event.player); + subSkill: { + buff: { + charlotte: true, + trigger: { global: "damageBegin3" }, + filter(event, player) { + if (!event.card || !event.card.storage || !event.card.storage.olsbguidao) + return false; + if (!event.source || event.source != player) return false; + const evt = event.getParent("useCard"); + return evt.player == player && evt.targets.includes(event.player); }, - forced:true, - popup:false, - async content(event,trigger,player){ - const target=trigger.player; - const {result:{control}}=await target.chooseControl('【杀】更多','非【杀】更多') - .set('prompt','归刀:请猜测'+get.translation(player)+'手牌中【杀】与非【杀】牌数哪个更多') - .set('prompt2','若猜错,则'+get.translation(trigger.card)+'对你造成的伤害+1') - .set('ai',()=>_status.event.controls.randomGet()); - const goon1=player.countCards('h',card=>get.name(card,player)=='sha')>=player.countCards('h',card=>get.name(card,player)!='sha'); - const goon2=player.countCards('h',card=>get.name(card,player)!='sha')>=player.countCards('h',card=>get.name(card,player)=='sha'); - if((goon1&&control=='【杀】更多')||(goon2&&control=='非【杀】更多')){ - target.popup('洗具'); - game.log(target,'猜测','#g正确'); - } - else{ - target.popup('杯具'); - game.log(target,'猜测','#y错误'); - trigger.increase('num'); + forced: true, + popup: false, + async content(event, trigger, player) { + const target = trigger.player; + const { + result: { control }, + } = await target + .chooseControl("【杀】更多", "非【杀】更多") + .set( + "prompt", + "归刀:请猜测" + + get.translation(player) + + "手牌中【杀】与非【杀】牌数哪个更多" + ) + .set( + "prompt2", + "若猜错,则" + get.translation(trigger.card) + "对你造成的伤害+1" + ) + .set("ai", () => _status.event.controls.randomGet()); + const goon1 = + player.countCards("h", (card) => get.name(card, player) == "sha") >= + player.countCards("h", (card) => get.name(card, player) != "sha"); + const goon2 = + player.countCards("h", (card) => get.name(card, player) != "sha") >= + player.countCards("h", (card) => get.name(card, player) == "sha"); + if ((goon1 && control == "【杀】更多") || (goon2 && control == "非【杀】更多")) { + target.popup("洗具"); + game.log(target, "猜测", "#g正确"); + } else { + target.popup("杯具"); + game.log(target, "猜测", "#y错误"); + trigger.increase("num"); } }, }, }, }, //OL谋姜维 - olsbzhuri:{ - audio:2, - trigger:{player:['phaseZhunbeiEnd','phaseJudgeEnd','phaseDrawEnd','phaseUseEnd','phaseDiscardEnd','phaseJieshuEnd']}, - filter:function(event,player){ - if(player.hasSkill('olsbzhuri_block')) return false; - if(!game.hasPlayer(target=>player.canCompare(target))) return false; - return player.getHistory('gain',evt=>evt.getParent(event.name)==event).length+player.getHistory('lose',evt=>evt.getParent(event.name)==event&&evt.hs.length).length; + olsbzhuri: { + audio: 2, + trigger: { + player: [ + "phaseZhunbeiEnd", + "phaseJudgeEnd", + "phaseDrawEnd", + "phaseUseEnd", + "phaseDiscardEnd", + "phaseJieshuEnd", + ], }, - direct:true, - content:function*(event,map){ - var player=map.player; - var trigger=map.trigger; - var result=yield player.chooseTarget(get.prompt('olsbzhuri'),'与一名角色进行拼点,若你赢,你可以使用其中的一张拼点牌;若你没赢,你失去1点体力或令此技能于本回合失效',(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',target=>{ - var player=_status.event.player; - var ts=target.getCards('h').sort((a,b)=>get.number(a)-get.number(b)); - if(get.attitude(player,target)<0){ - var hs=player.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - var ts=target.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - if(get.number(hs[0])>get.number(ts[0])) return 1; - if(get.effect(player,{name:'losehp'},player,player)>0) return Math.random()+0.2; - if(player.getHp()>2) return Math.random()-0.5; + filter: function (event, player) { + if (player.hasSkill("olsbzhuri_block")) return false; + if (!game.hasPlayer((target) => player.canCompare(target))) return false; + return ( + player.getHistory("gain", (evt) => evt.getParent(event.name) == event).length + + player.getHistory( + "lose", + (evt) => evt.getParent(event.name) == event && evt.hs.length + ).length + ); + }, + direct: true, + content: function* (event, map) { + var player = map.player; + var trigger = map.trigger; + var result = yield player + .chooseTarget( + get.prompt("olsbzhuri"), + "与一名角色进行拼点,若你赢,你可以使用其中的一张拼点牌;若你没赢,你失去1点体力或令此技能于本回合失效", + (card, player, target) => { + return player.canCompare(target); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + var ts = target.getCards("h").sort((a, b) => get.number(a) - get.number(b)); + if (get.attitude(player, target) < 0) { + var hs = player.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + var ts = target.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + if (get.number(hs[0]) > get.number(ts[0])) return 1; + if (get.effect(player, { name: "losehp" }, player, player) > 0) + return Math.random() + 0.2; + if (player.getHp() > 2) return Math.random() - 0.5; + return 0; + } return 0; - } - return 0; - }); - if(result.bool){ - var target=result.targets[0]; - player.logSkill('olsbzhuri',target); - var result2=yield player.chooseToCompare(target); - if(result2.bool){ - var cards=[result2.player,result2.target].filterInD('d'); - cards=cards.filter(card=>player.hasUseTarget(card)); - if(cards.length){ - var result3=yield player.chooseButton(['是否使用其中的牌?',cards]).set('ai',button=>_status.event.player.getUseValue(button.link)); - if(result3.bool){ - var card=result3.links[0]; - player.$gain2(card,false); + }); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("olsbzhuri", target); + var result2 = yield player.chooseToCompare(target); + if (result2.bool) { + var cards = [result2.player, result2.target].filterInD("d"); + cards = cards.filter((card) => player.hasUseTarget(card)); + if (cards.length) { + var result3 = yield player + .chooseButton(["是否使用其中的牌?", cards]) + .set("ai", (button) => _status.event.player.getUseValue(button.link)); + if (result3.bool) { + var card = result3.links[0]; + player.$gain2(card, false); game.delayx(); - player.chooseUseTarget(true,card,false); + player.chooseUseTarget(true, card, false); } } - } - else{ - var list=lib.skill.olsbranji.getList(trigger); - var result3=yield player.chooseControl('失去体力','技能失效').set('prompt','逐日:失去1点体力,或令此技能于本回合失效').set('ai',()=>{ - var player=_status.event.player; - if(player.getHp()>2){ - var list=_status.event.list; - list.removeArray(player.skipList); - if(list.includes('phaseDraw')||list.includes('phaseUse')) return '失去体力'; - } - if(get.effect(player,{name:'losehp'},player,player)>0) return '失去体力'; - return '技能失效'; - }).set('list',list.slice(trigger.getParent().num,list.length)); - player[result3.control=='失去体力'?'loseHp':'addTempSkill'](result3.control=='失去体力'?1:'olsbzhuri_block'); + } else { + var list = lib.skill.olsbranji.getList(trigger); + var result3 = yield player + .chooseControl("失去体力", "技能失效") + .set("prompt", "逐日:失去1点体力,或令此技能于本回合失效") + .set("ai", () => { + var player = _status.event.player; + if (player.getHp() > 2) { + var list = _status.event.list; + list.removeArray(player.skipList); + if (list.includes("phaseDraw") || list.includes("phaseUse")) + return "失去体力"; + } + if (get.effect(player, { name: "losehp" }, player, player) > 0) + return "失去体力"; + return "技能失效"; + }) + .set("list", list.slice(trigger.getParent().num, list.length)); + player[result3.control == "失去体力" ? "loseHp" : "addTempSkill"]( + result3.control == "失去体力" ? 1 : "olsbzhuri_block" + ); } } }, - subSkill:{ - block:{ - charlotte:true, - mark:true, - marktext:'', - intro:{content:'追不动太阳了'}, + subSkill: { + block: { + charlotte: true, + mark: true, + marktext: '', + intro: { content: "追不动太阳了" }, }, }, }, - olsbranji:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - prompt2:function(event,player){ - var str='获得技能'; - var num=lib.skill.olsbranji.getNum(player); - if(num>=player.getHp()) str+='【困奋】'; - if(num==player.getHp()) str+='和'; - if(num<=player.getHp()) str+='【诈降】'; - str+=',然后'; - var num1=(player.countCards('h')-player.getHandcardLimit()); - if(num1||player.isDamaged()){ - if(num1) str+=(num1<0?'摸'+get.cnNumber(-num1)+'张牌':'弃置'+get.cnNumber(num1)+'张牌'); - if(num1&&player.isDamaged()) str+='或'; - if(player.isDamaged()) str+=('回复'+player.getDamagedHp()+'点体力'); - str+=',最后'; + olsbranji: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + prompt2: function (event, player) { + var str = "获得技能"; + var num = lib.skill.olsbranji.getNum(player); + if (num >= player.getHp()) str += "【困奋】"; + if (num == player.getHp()) str += "和"; + if (num <= player.getHp()) str += "【诈降】"; + str += ",然后"; + var num1 = player.countCards("h") - player.getHandcardLimit(); + if (num1 || player.isDamaged()) { + if (num1) + str += + num1 < 0 + ? "摸" + get.cnNumber(-num1) + "张牌" + : "弃置" + get.cnNumber(num1) + "张牌"; + if (num1 && player.isDamaged()) str += "或"; + if (player.isDamaged()) str += "回复" + player.getDamagedHp() + "点体力"; + str += ",最后"; } - str+='你不能回复体力直到你杀死角色。'; + str += "你不能回复体力直到你杀死角色。"; return str; }, - check:function(event,player){ - var num=lib.skill.olsbranji.getNum(player); - if(num==player.getHp()) return true; - return player.getHandcardLimit()-player.countCards('h')>=3||player.getDamagedHp()>=2; + check: function (event, player) { + var num = lib.skill.olsbranji.getNum(player); + if (num == player.getHp()) return true; + return ( + player.getHandcardLimit() - player.countCards("h") >= 3 || player.getDamagedHp() >= 2 + ); }, - limited:true, - skillAnimation:true, - animationColor:'fire', - content:function*(event,map){ - var player=map.player; - var trigger=map.trigger; - player.awakenSkill('olsbranji'); - var num=lib.skill.olsbranji.getNum(player); + limited: true, + skillAnimation: true, + animationColor: "fire", + content: function* (event, map) { + var player = map.player; + var trigger = map.trigger; + player.awakenSkill("olsbranji"); + var num = lib.skill.olsbranji.getNum(player); const skills = []; - if(num>=player.getHp()){ - skills.push('kunfen'); - player.storage.kunfen=true; + if (num >= player.getHp()) { + skills.push("kunfen"); + player.storage.kunfen = true; } - if(num<=player.getHp()) skills.push('zhaxiang'); + if (num <= player.getHp()) skills.push("zhaxiang"); player.addSkills(skills); - if(player.countCards('h')!=player.getHandcardLimit()||player.isDamaged()){ - var result,num1=player.countCards('h')-player.getHandcardLimit(); - if(!num1) result={index:1}; - else if(player.isHealthy()) result={index:0}; - else{ - result=yield player.chooseControl('手牌数','体力值').set('choiceList',[ - num1<0?'摸'+get.cnNumber(-num1)+'张牌':'弃置'+get.cnNumber(num1)+'张牌', - '回复'+(player.getDamagedHp())+'点体力', - ]).set('ai',()=>{ - var player=_status.event.player; - var list=_status.event.list; - var num1=get.effect(player,{name:'draw'},player,player); - var num2=get.recoverEffect(player,player,player); - return num1*list[0]>num2*list[1]?0:1; - }).set('list',[-num1,player.getDamagedHp()]); + if (player.countCards("h") != player.getHandcardLimit() || player.isDamaged()) { + var result, + num1 = player.countCards("h") - player.getHandcardLimit(); + if (!num1) result = { index: 1 }; + else if (player.isHealthy()) result = { index: 0 }; + else { + result = yield player + .chooseControl("手牌数", "体力值") + .set("choiceList", [ + num1 < 0 + ? "摸" + get.cnNumber(-num1) + "张牌" + : "弃置" + get.cnNumber(num1) + "张牌", + "回复" + player.getDamagedHp() + "点体力", + ]) + .set("ai", () => { + var player = _status.event.player; + var list = _status.event.list; + var num1 = get.effect(player, { name: "draw" }, player, player); + var num2 = get.recoverEffect(player, player, player); + return num1 * list[0] > num2 * list[1] ? 0 : 1; + }) + .set("list", [-num1, player.getDamagedHp()]); } - if(result.index==0){ - if(num1<0) yield player.drawTo(player.getHandcardLimit()); - else yield player.chooseToDiscard(num1,'h',true); - } - else{ - yield player.recover(player.maxHp-player.hp); + if (result.index == 0) { + if (num1 < 0) yield player.drawTo(player.getHandcardLimit()); + else yield player.chooseToDiscard(num1, "h", true); + } else { + yield player.recover(player.maxHp - player.hp); } } - player.addSkill('olsbranji_norecover'); - player.when({source:'dieAfter'}).then(()=>player.removeSkill('olsbranji_norecover')); + player.addSkill("olsbranji_norecover"); + player.when({ source: "dieAfter" }).then(() => player.removeSkill("olsbranji_norecover")); }, - derivation:['kunfenx','zhaxiang'], - getList:function(event){ - return event.getParent().phaseList.map(list=>list.split('|')[0]); + derivation: ["kunfenx", "zhaxiang"], + getList: function (event) { + return event.getParent().phaseList.map((list) => list.split("|")[0]); }, - getNum:function(player){ - return player.getHistory('useCard',evt=>{ - return lib.phaseName.some(name=>{ - return evt.getParent(name).name==name; - }); - }).reduce((list,evt)=>{ - return list.add(evt.getParent(lib.phaseName.find(name=>evt.getParent(name).name==name))); - },[]).length; + getNum: function (player) { + return player + .getHistory("useCard", (evt) => { + return lib.phaseName.some((name) => { + return evt.getParent(name).name == name; + }); + }) + .reduce((list, evt) => { + return list.add( + evt.getParent(lib.phaseName.find((name) => evt.getParent(name).name == name)) + ); + }, []).length; }, - subSkill:{ - norecover:{ - charlotte:true, - mark:true, - intro:{content:'不能回复体力'}, - trigger:{player:'recoverBefore'}, - forced:true, - firstDo:true, - content:function(){ + subSkill: { + norecover: { + charlotte: true, + mark: true, + intro: { content: "不能回复体力" }, + trigger: { player: "recoverBefore" }, + forced: true, + firstDo: true, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'recover')) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "recover")) return "zeroplayertarget"; }, }, }, }, }, }, - kunfenx:{ - audio:'kunfen', - audioname:['ol_sb_jiangwei'], + kunfenx: { + audio: "kunfen", + audioname: ["ol_sb_jiangwei"], }, //界曹彰 - oljiangchi:{ - audio:'rejiangchi', - trigger:{player:'phaseDrawEnd'}, - direct:true, - content:function*(event,map){ - var player=map.player; - var choiceList=[ - '摸一张牌,本回合使用【杀】的次数上限-1,且【杀】不计入手牌上限。', - '重铸一张牌,本回合使用【杀】无距离限制,且使用【杀】的次数上限+1。', - ],list=['cancel2']; - if(player.countCards('he',card=>player.canRecast(card))) list.unshift('重铸,+1'); - else choiceList[1]=''+choiceList[1]+''; - list.unshift('摸牌,-1'); - var result=yield player.chooseControl(list).set('ai',()=>{ - var player=_status.event.player; - var controls=_status.event.controls.slice(); - if(controls.includes('重铸,+1')&&player.countCards('hs',card=>get.name(card)=='sha'&&player.hasValueTarget(card))>=2) return '重铸,+1'; - return '摸牌,-1'; - }).set('choiceList',choiceList).set('prompt',get.prompt('oljiangchi')); - if(result.control!='cancel2'){ - player.logSkill('oljiangchi'); - if(result.control=='摸牌,-1'){ + oljiangchi: { + audio: "rejiangchi", + trigger: { player: "phaseDrawEnd" }, + direct: true, + content: function* (event, map) { + var player = map.player; + var choiceList = [ + "摸一张牌,本回合使用【杀】的次数上限-1,且【杀】不计入手牌上限。", + "重铸一张牌,本回合使用【杀】无距离限制,且使用【杀】的次数上限+1。", + ], + list = ["cancel2"]; + if (player.countCards("he", (card) => player.canRecast(card))) list.unshift("重铸,+1"); + else choiceList[1] = '' + choiceList[1] + ""; + list.unshift("摸牌,-1"); + var result = yield player + .chooseControl(list) + .set("ai", () => { + var player = _status.event.player; + var controls = _status.event.controls.slice(); + if ( + controls.includes("重铸,+1") && + player.countCards( + "hs", + (card) => get.name(card) == "sha" && player.hasValueTarget(card) + ) >= 2 + ) + return "重铸,+1"; + return "摸牌,-1"; + }) + .set("choiceList", choiceList) + .set("prompt", get.prompt("oljiangchi")); + if (result.control != "cancel2") { + player.logSkill("oljiangchi"); + if (result.control == "摸牌,-1") { player.draw(); - player.addTempSkill('oljiangchi_less'); - player.addMark('oljiangchi_less',1,false); - } - else{ - var result2=yield player.chooseCard('he','将驰:请重铸一张牌',true,(card,player)=>player.canRecast(card)); - if(result2.bool){ + player.addTempSkill("oljiangchi_less"); + player.addMark("oljiangchi_less", 1, false); + } else { + var result2 = yield player.chooseCard( + "he", + "将驰:请重铸一张牌", + true, + (card, player) => player.canRecast(card) + ); + if (result2.bool) { player.recast(result2.cards); - player.addTempSkill('oljiangchi_more'); - player.addMark('oljiangchi_more',1,false); + player.addTempSkill("oljiangchi_more"); + player.addMark("oljiangchi_more", 1, false); } } } }, - subSkill:{ - less:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num-player.countMark('oljiangchi_less'); + subSkill: { + less: { + charlotte: true, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num - player.countMark("oljiangchi_less"); }, - ignoredHandcard:function(card,player){ - if(card.name=='sha') return true; + ignoredHandcard: function (card, player) { + if (card.name == "sha") return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.name=='sha') return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.name == "sha") return false; }, }, }, - more:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('oljiangchi_more'); + more: { + charlotte: true, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("oljiangchi_more"); }, - targetInRange:function (card,player){ - if(card.name=='sha') return true; + targetInRange: function (card, player) { + if (card.name == "sha") return true; }, }, }, }, }, //界简雍 - olqiaoshui:{ - audio:'reqiaoshui', - inherit:'reqiaoshui', - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkill('olqiaoshui_used'); + olqiaoshui: { + audio: "reqiaoshui", + inherit: "reqiaoshui", + filter: function (event, player) { + return player.countCards("h") > 0 && !player.hasSkill("olqiaoshui_used"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool) player.addTempSkill('qiaoshui3',{player:'phaseUseAfter'}); - else{ - player.addTempSkill('qiaoshui2'); - player.addTempSkill('olqiaoshui_used'); + "step 1"; + if (result.bool) player.addTempSkill("qiaoshui3", { player: "phaseUseAfter" }); + else { + player.addTempSkill("qiaoshui2"); + player.addTempSkill("olqiaoshui_used"); } }, - subSkill:{ - used:{ - charlotte:true, - mark:true, - marktext:'', - intro:{content:'被迫闭嘴'}, + subSkill: { + used: { + charlotte: true, + mark: true, + marktext: '', + intro: { content: "被迫闭嘴" }, }, }, }, //界凌统 - olxuanfeng:{ - audio:'xuanfeng', - audioname:['boss_lvbu3'], - audioname2:{ - lingtong:'xuanfeng', - ol_lingtong:'xuanfeng_re_lingtong', + olxuanfeng: { + audio: "xuanfeng", + audioname: ["boss_lvbu3"], + audioname2: { + lingtong: "xuanfeng", + ol_lingtong: "xuanfeng_re_lingtong", }, - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&(evt.es.length||evt.cards2.length>1); + filter: function (event, player) { + var evt = event.getl(player); + return evt && (evt.es.length || evt.cards2.length > 1); }, - direct:true, - content:function(){ - 'step 0' - event.count=2; - event.logged=false; - 'step 1' - player.chooseTarget(get.prompt('olxuanfeng'),'弃置一名其他角色的一张牌',function(card,player,target){ - if(player==target) return false; - return target.countDiscardableCards(player,'he'); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - 'step 2' - if(result.bool){ - if(!event.logged){ - player.logSkill('olxuanfeng',result.targets); - event.logged=true; - } - else player.line(result.targets[0],'green'); - player.discardPlayerCard(result.targets[0],'he',true); + direct: true, + content: function () { + "step 0"; + event.count = 2; + event.logged = false; + "step 1"; + player + .chooseTarget( + get.prompt("olxuanfeng"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countDiscardableCards(player, "he"); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 2"; + if (result.bool) { + if (!event.logged) { + player.logSkill("olxuanfeng", result.targets); + event.logged = true; + } else player.line(result.targets[0], "green"); + player.discardPlayerCard(result.targets[0], "he", true); event.count--; - } - else event.finish(); - 'step 3' - if(event.count) event.goto(1); + } else event.finish(); + "step 3"; + if (event.count) event.goto(1); }, - ai:{ - reverseEquip:true, - noe:true, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; + ai: { + reverseEquip: true, + noe: true, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; }, }, }, }, - xuanfeng_re_lingtong:{audio:2}, + xuanfeng_re_lingtong: { audio: 2 }, }, - dynamicTranslate:{ - }, - translate:{ - ol_lingtong:'OL界凌统', - ol_lingtong_prefix:'OL界', - olxuanfeng:'旋风', - olxuanfeng_info:'当你一次性失去至少两张牌后,或失去装备区的牌后,你可以依次弃置一至两名其他角色的共计两张牌。', - ol_jianyong:'OL界简雍', - ol_jianyong_prefix:'OL界', - olqiaoshui:'巧说', - olqiaoshui_info:'出牌阶段,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,此技能于本回合失效且本回合你不能使用锦囊牌。', - ol_caozhang:'OL界曹彰', - ol_caozhang_prefix:'OL界', - oljiangchi:'将驰', - oljiangchi_info:'摸牌阶段结束时,你可以选择一项:①摸一张牌,本回合使用【杀】的次数上限-1,且【杀】不计入手牌上限。②重铸一张牌,本回合使用【杀】无距离限制,且使用【杀】的次数上限+1。', - ol_sb_jiangwei:'OL谋姜维', - ol_sb_jiangwei_prefix:'OL谋', - olsbzhuri:'逐日', - olsbzhuri_info:'你的阶段结束时,若你本阶段失去过手牌或得到过牌,则你可以与一名角色拼点。若你赢,你可以使用其中一张拼点牌;若你没赢,你失去1点体力或令此技能于本回合无效。', - olsbranji:'燃己', - olsbranji_info:'限定技,结束阶段。若你本回合使用过牌的阶段数大于等于/小于等于体力值,你可以获得技能〖困奋〗/〖诈降〗(同时满足则都获得,以此法获得的〖困奋〗直接修改为非锁定技)。若如此做,你将手牌数调整至手牌上限或将体力值回复至体力上限,然后你不能回复体力直到你杀死角色。', - kunfenx:'困奋', - kunfenx_info:'结束阶段开始时,你可以失去1点体力,然后摸两张牌。', - ol_sb_guanyu:'OL谋关羽', - ol_sb_guanyu_prefix:'OL谋', - olsbfumeng:'赴梦', - olsbfumeng_info:'一轮游戏开始时,你可以令任意张手牌的牌名视为【杀】。', - olsbguidao:'归刀', - olsbguidao_info:'出牌阶段,你可以重铸两张牌并视为使用一张【决斗】(重铸的【杀】数须比本回合上次发动〖归刀〗重铸的【杀】数多)。目标角色受到此牌伤害时,其须猜测你手牌中牌名为【杀】的牌数量多还是牌名不为【杀】的牌数多,若其猜错,则此【决斗】对其造成的伤害+1。', - ol_sb_taishici:'OL谋太史慈', - ol_sb_taishici_prefix:'OL谋', - olsbdulie:'笃烈', - olsbdulie_info:'每回合限一次,当你成为其他角色使用基本牌或普通锦囊牌的唯一目标时,你可以令此牌额外结算一次。若如此做,此牌结算完毕后,你摸X张牌(X为你的攻击范围且至多为5)。', - olsbdouchan:'斗缠', - olsbdouchan_info:'锁定技,准备阶段,你从牌堆中获得一张【决斗】,若牌堆没有【决斗】,则你的攻击范围和出牌阶段使用【杀】的次数上限+1(增加次数不超过游戏人数)。', - olsbweilin:'威临', - olsbweilin_info:'每回合限一次,你可以将一张牌当作任意【杀】或【酒】使用,且你以此法使用的牌指定最后一个目标后,你令所有目标角色本回合与此牌颜色相同的手牌均视为【杀】。', - olsbduoshou:'夺首', - olsbduoshou_info:'锁定技。①你每回合使用的第一张红色牌无距离限制。②你每回合使用的第一张基本牌不计入使用次数。③你每回合第一次造成伤害后,你摸一张牌。', - ol_gaoshun:'OL界高顺', - ol_gaoshun_prefix:'OL界', - olxianzhen:'陷阵', - olxianzhen_info:'出牌阶段限一次,你可以与一名角色拼点。若你赢,本回合你无视该角色的防具且对其使用牌没有次数和距离限制,且当你使用【杀】或普通锦囊牌指定其他角色为唯一目标时可以令该角色也成为此牌的目标;若你没赢,本回合你不能对其使用【杀】且你的【杀】不计入手牌上限。', - ol_sb_yuanshao:'OL谋袁绍', - ol_sb_yuanshao_prefix:'OL谋', - olsbhetao:'合讨', - olsbhetao_info:'其他角色使用牌执行第一个目标后,若此牌指定的目标数大于1,则你可以弃置一张与此牌颜色相同的牌并令此牌改为对其中一名目标角色结算两次。', - olsbshenli:'神离', - olsbshenli_info:'出牌阶段限一次,当你使用【杀】指定目标后,你可以令所有可成为此牌目标的其他角色均成为此牌目标,此牌结算完毕后,若你因此牌造成的伤害值X:大于你的手牌数,你摸X张牌(至多摸五张);大于你的体力值,你再次对所有目标角色中可以成为此牌目标的角色使用此牌。', - olsbyufeng:'玉锋', - olsbyufeng_sizhaojian:'思召剑', - olsbyufeng_block:'思召剑', - olsbyufeng_info:'游戏开始时,你将【思召剑】置入装备区。', - sizhaojian:'思召剑', - sizhaojian_info:'当你使用有点数的【杀】指定目标后,你令目标角色只能使用无点数或点数大于等于此【杀】的【闪】响应此牌。', - sizhaojian_append:'【思召剑】于闪闪节(3月2日-3月15日)外离开装备区后,销毁此牌', - olsbshishou:'士首', - olsbshishou_info:'主公技,其他群势力角色失去装备区的牌后,若你的装备区中没有武器牌,其可将【思召剑】置入你的装备区。', - ol_yufan:'OL界虞翻', - ol_yufan_prefix:'OL界', - olzongxuan:'纵玄', - olzongxuan_info:'当你或你的上家因弃置而失去牌后,你可以将位于弃牌堆的这些牌中的任意牌以任意顺序置于牌堆顶。', - olzhiyan:'直言', - olzhiyan_info:'你或你的上家的结束阶段,你可以令一名角色正面朝上摸一张牌,然后若此牌:为装备牌,则其使用此牌并回复1点体力;不为装备牌且其体力值大于等于你,则其失去1点体力。', - ol_chengpu:'OL界程普', - ol_chengpu_prefix:'OL界', - dclihuo:'疠火', - dclihuo_info:'①你使用的非火【杀】可以改为火【杀】,若如此做,此牌结算完毕后,若此牌造成过伤害,则你弃置一张牌或失去1点体力。②你使用火【杀】可以额外指定一个目标。', - olchunlao:'醇醪', - olchunlao_info:'①当你的【杀】因弃置进入弃牌堆后,你将位于弃牌堆的这些牌称为“醇”置于武将牌上。②一名角色处于濒死状态时,你可以将一张“醇”置入弃牌堆,然后令其视为使用一张【酒】。', - ol_wangyi:'OL界王异', - ol_wangyi_prefix:'OL界', - olzhenlie:'贞烈', - olzhenlie_info:'当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②发动一次〖秘计〗。', - olmiji:'秘计', - olmiji_info:'结束阶段,若你已受伤,则你可以摸X张牌,然后你可以将至多X张牌任意分配给其他角色(X为你已损失的体力值)。', + dynamicTranslate: {}, + translate: { + ol_lingtong: "OL界凌统", + ol_lingtong_prefix: "OL界", + olxuanfeng: "旋风", + olxuanfeng_info: + "当你一次性失去至少两张牌后,或失去装备区的牌后,你可以依次弃置一至两名其他角色的共计两张牌。", + ol_jianyong: "OL界简雍", + ol_jianyong_prefix: "OL界", + olqiaoshui: "巧说", + olqiaoshui_info: + "出牌阶段,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,此技能于本回合失效且本回合你不能使用锦囊牌。", + ol_caozhang: "OL界曹彰", + ol_caozhang_prefix: "OL界", + oljiangchi: "将驰", + oljiangchi_info: + "摸牌阶段结束时,你可以选择一项:①摸一张牌,本回合使用【杀】的次数上限-1,且【杀】不计入手牌上限。②重铸一张牌,本回合使用【杀】无距离限制,且使用【杀】的次数上限+1。", + ol_sb_jiangwei: "OL谋姜维", + ol_sb_jiangwei_prefix: "OL谋", + olsbzhuri: "逐日", + olsbzhuri_info: + "你的阶段结束时,若你本阶段失去过手牌或得到过牌,则你可以与一名角色拼点。若你赢,你可以使用其中一张拼点牌;若你没赢,你失去1点体力或令此技能于本回合无效。", + olsbranji: "燃己", + olsbranji_info: + "限定技,结束阶段。若你本回合使用过牌的阶段数大于等于/小于等于体力值,你可以获得技能〖困奋〗/〖诈降〗(同时满足则都获得,以此法获得的〖困奋〗直接修改为非锁定技)。若如此做,你将手牌数调整至手牌上限或将体力值回复至体力上限,然后你不能回复体力直到你杀死角色。", + kunfenx: "困奋", + kunfenx_info: "结束阶段开始时,你可以失去1点体力,然后摸两张牌。", + ol_sb_guanyu: "OL谋关羽", + ol_sb_guanyu_prefix: "OL谋", + olsbfumeng: "赴梦", + olsbfumeng_info: "一轮游戏开始时,你可以令任意张手牌的牌名视为【杀】。", + olsbguidao: "归刀", + olsbguidao_info: + "出牌阶段,你可以重铸两张牌并视为使用一张【决斗】(重铸的【杀】数须比本回合上次发动〖归刀〗重铸的【杀】数多)。目标角色受到此牌伤害时,其须猜测你手牌中牌名为【杀】的牌数量多还是牌名不为【杀】的牌数多,若其猜错,则此【决斗】对其造成的伤害+1。", + ol_sb_taishici: "OL谋太史慈", + ol_sb_taishici_prefix: "OL谋", + olsbdulie: "笃烈", + olsbdulie_info: + "每回合限一次,当你成为其他角色使用基本牌或普通锦囊牌的唯一目标时,你可以令此牌额外结算一次。若如此做,此牌结算完毕后,你摸X张牌(X为你的攻击范围且至多为5)。", + olsbdouchan: "斗缠", + olsbdouchan_info: + "锁定技,准备阶段,你从牌堆中获得一张【决斗】,若牌堆没有【决斗】,则你的攻击范围和出牌阶段使用【杀】的次数上限+1(增加次数不超过游戏人数)。", + olsbweilin: "威临", + olsbweilin_info: + "每回合限一次,你可以将一张牌当作任意【杀】或【酒】使用,且你以此法使用的牌指定最后一个目标后,你令所有目标角色本回合与此牌颜色相同的手牌均视为【杀】。", + olsbduoshou: "夺首", + olsbduoshou_info: + "锁定技。①你每回合使用的第一张红色牌无距离限制。②你每回合使用的第一张基本牌不计入使用次数。③你每回合第一次造成伤害后,你摸一张牌。", + ol_gaoshun: "OL界高顺", + ol_gaoshun_prefix: "OL界", + olxianzhen: "陷阵", + olxianzhen_info: + "出牌阶段限一次,你可以与一名角色拼点。若你赢,本回合你无视该角色的防具且对其使用牌没有次数和距离限制,且当你使用【杀】或普通锦囊牌指定其他角色为唯一目标时可以令该角色也成为此牌的目标;若你没赢,本回合你不能对其使用【杀】且你的【杀】不计入手牌上限。", + ol_sb_yuanshao: "OL谋袁绍", + ol_sb_yuanshao_prefix: "OL谋", + olsbhetao: "合讨", + olsbhetao_info: + "其他角色使用牌执行第一个目标后,若此牌指定的目标数大于1,则你可以弃置一张与此牌颜色相同的牌并令此牌改为对其中一名目标角色结算两次。", + olsbshenli: "神离", + olsbshenli_info: + "出牌阶段限一次,当你使用【杀】指定目标后,你可以令所有可成为此牌目标的其他角色均成为此牌目标,此牌结算完毕后,若你因此牌造成的伤害值X:大于你的手牌数,你摸X张牌(至多摸五张);大于你的体力值,你再次对所有目标角色中可以成为此牌目标的角色使用此牌。", + olsbyufeng: "玉锋", + olsbyufeng_sizhaojian: "思召剑", + olsbyufeng_block: "思召剑", + olsbyufeng_info: "游戏开始时,你将【思召剑】置入装备区。", + sizhaojian: "思召剑", + sizhaojian_info: + "当你使用有点数的【杀】指定目标后,你令目标角色只能使用无点数或点数大于等于此【杀】的【闪】响应此牌。", + sizhaojian_append: + '【思召剑】于闪闪节(3月2日-3月15日)外离开装备区后,销毁此牌', + olsbshishou: "士首", + olsbshishou_info: + "主公技,其他群势力角色失去装备区的牌后,若你的装备区中没有武器牌,其可将【思召剑】置入你的装备区。", + ol_yufan: "OL界虞翻", + ol_yufan_prefix: "OL界", + olzongxuan: "纵玄", + olzongxuan_info: + "当你或你的上家因弃置而失去牌后,你可以将位于弃牌堆的这些牌中的任意牌以任意顺序置于牌堆顶。", + olzhiyan: "直言", + olzhiyan_info: + "你或你的上家的结束阶段,你可以令一名角色正面朝上摸一张牌,然后若此牌:为装备牌,则其使用此牌并回复1点体力;不为装备牌且其体力值大于等于你,则其失去1点体力。", + ol_chengpu: "OL界程普", + ol_chengpu_prefix: "OL界", + dclihuo: "疠火", + dclihuo_info: + "①你使用的非火【杀】可以改为火【杀】,若如此做,此牌结算完毕后,若此牌造成过伤害,则你弃置一张牌或失去1点体力。②你使用火【杀】可以额外指定一个目标。", + olchunlao: "醇醪", + olchunlao_info: + "①当你的【杀】因弃置进入弃牌堆后,你将位于弃牌堆的这些牌称为“醇”置于武将牌上。②一名角色处于濒死状态时,你可以将一张“醇”置入弃牌堆,然后令其视为使用一张【酒】。", + ol_wangyi: "OL界王异", + ol_wangyi_prefix: "OL界", + olzhenlie: "贞烈", + olzhenlie_info: + "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②发动一次〖秘计〗。", + olmiji: "秘计", + olmiji_info: + "结束阶段,若你已受伤,则你可以摸X张牌,然后你可以将至多X张牌任意分配给其他角色(X为你已损失的体力值)。", - onlyOL_yijiang1:'OL专属·将1', - onlyOL_yijiang2:'OL专属·将2', - onlyOL_yijiang3:'OL专属·将3', - onlyOL_sb:'OL专属·上兵伐谋', + onlyOL_yijiang1: "OL专属·将1", + onlyOL_yijiang2: "OL专属·将2", + onlyOL_yijiang3: "OL专属·将3", + onlyOL_sb: "OL专属·上兵伐谋", }, }; }); diff --git a/character/ow.js b/character/ow.js index daf18f2a7..c84ae460e 100644 --- a/character/ow.js +++ b/character/ow.js @@ -1,573 +1,612 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'ow', - character:{ - ow_liekong:['female','shu',3,['shanxian','shanhui']], - ow_sishen:['male','shu',4,['xiandan','yihun','shouge']], - ow_tianshi:['female','qun',3,['shouhu','ziyu','feiying']], - ow_falaozhiying:['female','shu',3,['feidan','huoyu','feiying']], - ow_zhixuzhiguang:['female','qun',3,['guangshu']], - ow_luxiao:['male','wu',3,['yuedong','kuoyin','huhuan']], - ow_shibing:['male','shu',4,['tuji','mujing','lichang']], - ow_yuanshi:['male','qun',3,['feiren','lianpo','zhanlong']], - ow_chanyata:['male','qun',3,['xie','luan','sheng']], - ow_dva:['female','shu',2,['jijia','tuijin','zihui','chongzhuang']], - ow_mei:['female','wei',3,['bingqiang','jidong','baoxue']], - ow_ana:['female','wei',3,['zhiyuan','mianzhen','aqianghua']], - ow_heibaihe:['female','qun',3,['juji','duwen','dulei']], - ow_maikelei:['male','shu',4,['shanguang','tiandan','shenqiang']], - ow_kuangshu:['male','shu',3,['liudan','shoujia','shihuo']], + name: "ow", + character: { + ow_liekong: ["female", "shu", 3, ["shanxian", "shanhui"]], + ow_sishen: ["male", "shu", 4, ["xiandan", "yihun", "shouge"]], + ow_tianshi: ["female", "qun", 3, ["shouhu", "ziyu", "feiying"]], + ow_falaozhiying: ["female", "shu", 3, ["feidan", "huoyu", "feiying"]], + ow_zhixuzhiguang: ["female", "qun", 3, ["guangshu"]], + ow_luxiao: ["male", "wu", 3, ["yuedong", "kuoyin", "huhuan"]], + ow_shibing: ["male", "shu", 4, ["tuji", "mujing", "lichang"]], + ow_yuanshi: ["male", "qun", 3, ["feiren", "lianpo", "zhanlong"]], + ow_chanyata: ["male", "qun", 3, ["xie", "luan", "sheng"]], + ow_dva: ["female", "shu", 2, ["jijia", "tuijin", "zihui", "chongzhuang"]], + ow_mei: ["female", "wei", 3, ["bingqiang", "jidong", "baoxue"]], + ow_ana: ["female", "wei", 3, ["zhiyuan", "mianzhen", "aqianghua"]], + ow_heibaihe: ["female", "qun", 3, ["juji", "duwen", "dulei"]], + ow_maikelei: ["male", "shu", 4, ["shanguang", "tiandan", "shenqiang"]], + ow_kuangshu: ["male", "shu", 3, ["liudan", "shoujia", "shihuo"]], - ow_tuobiang:['male','shu',3,['paotai','maoding']], - ow_baolei:['male','qun',4,['bshaowei','zhencha']], - ow_banzang:['male','qun',4,['bfengshi','yinbo']], - ow_laiyinhate:['male','qun',4,['zhongdun','mengji']], - ow_luba:['male','shu',4,['liangou','xiyang']], - ow_wensidun:['male','shu',4,['feitiao','dianji']], - ow_zhaliya:['female','wei',4,['pingzhang','owliyong']], + ow_tuobiang: ["male", "shu", 3, ["paotai", "maoding"]], + ow_baolei: ["male", "qun", 4, ["bshaowei", "zhencha"]], + ow_banzang: ["male", "qun", 4, ["bfengshi", "yinbo"]], + ow_laiyinhate: ["male", "qun", 4, ["zhongdun", "mengji"]], + ow_luba: ["male", "shu", 4, ["liangou", "xiyang"]], + ow_wensidun: ["male", "shu", 4, ["feitiao", "dianji"]], + ow_zhaliya: ["female", "wei", 4, ["pingzhang", "owliyong"]], - ow_heiying:['female','wei',3,['qinru','yinshen','maichong']], - ow_orisa:['female','wu',4,['qianggu','woliu']], + ow_heiying: ["female", "wei", 3, ["qinru", "yinshen", "maichong"]], + ow_orisa: ["female", "wu", 4, ["qianggu", "woliu"]], }, - characterIntro:{ - ow_orisa:'奥丽莎是用在努巴尼昙花一现的OR15防御机器人的零件组装而成的,她是这座城市的新一代守护者,但依然有很大的成长空间', - ow_liekong:'莉娜·奥克斯顿(代号:“猎空”)是守望先锋原型机试飞计划的最年轻成员。但在第一次试飞过程中,原型机的传送阵列出现故障,包括飞行员在内完全失踪。莉娜在几个月后再次出现,不过她身上的分子却无法和时间流同步。这种被称为“时间解离”的症状使她彻底变成了一个“活生生”的幽灵,时隐时现。直到一位名叫温斯顿的科学家设计出了“时间加速器”,一台可以让“猎空”维持在当前时间的装置。不仅如此,这一装置还让“猎空”有能力控制她自己的时间流,使她可以任意加速或减慢时间。有了这一全新的能力,她成了守望先锋最强大的特工之一。守望先锋解散后,“猎空”依旧选择为了正义而战,守护无辜。', - ow_sishen:'关于这个黑袍恐怖分子的传闻并不多,只知道大家都称他为“死神”。虽然没人知道他的真实身份和动机,但有一点是可以肯定的,他的出现意味着死亡。“死神”是一名极其不稳定、残暴、冷酷的雇佣兵,在世界各地犯下多起恐怖袭击案件。在过去的数十年间,他参与了许多武装冲突,但其本人却不属于任何组织。在多年的追踪后,“死神”神秘的面纱终于被慢慢揭开。据信,“死神”正在追杀前守望先锋特工并系统地逐一消灭。', - ow_tianshi:'齐格勒是瑞士一家顶尖医院的手术部门负责人。正是她在医学领域的成就,引起了守望先锋的注意。由于齐格勒的双亲都被战争夺走了生命,因此她从一开始就极其反对该组织通过军事手段进行维和。但最终,她意识到守望先锋给她提供了一个可以拯救更多人生命的机会。作为守望先锋医学研究部门的负责人,安吉拉致力于更好地在前线治疗受到致命伤的病员。尽管她对守望先锋做出了巨大的贡献,但齐格勒博士经常质疑她的上司以及守望先锋的长远目标。而当守望先锋解散之后,齐格勒博士便致力于帮助那些受战争波及的受难者。', - ow_falaozhiying:'本名法芮尔,来自一个军功卓越的军人世家,贡献与荣耀就是她最高的追求。在加入埃及军队后,她的坚韧和在战术上的天赋使她很快就晋升为了一名军官。作为一名果敢的领袖,任何在她手下服役的士兵都对她抱有绝对的忠诚。有了所有这些卓越的表现,法芮尔自然成了守望先锋最青睐的一名候选人。但在她正式加入之前,守望先锋就解散了。当她带着所有的荣誉退役后,法芮尔加入了一家名为“海力士国际安保”的私人安保公司,该公司的最重要的一笔订单就是负责保护吉萨高原地下的人工智能研究设施。尽管她对守望先锋的解散感到无比的遗憾,但她依旧梦想着能为正义而战并改变这个残破的世界。', - ow_zhixuzhiguang:'当被认为是为数不多可以成为光子建筑师的人才之后,年轻的塞特娅·法斯瓦尼离开了贫穷的家乡,成为了费斯卡光子建筑师学院的一员。她很快就成为了乌托邦最顶尖的光子建筑师。但费斯卡集团在塞特娅身上还是看到了更广阔的发展潜力。费斯卡集团称其为“秩序之光”,为了集团的利益和扩大在其他国家的影响力,将其派遣到全球执行秘密任务。虽然“秩序之光”相信她的所作所为是为了实现人性之“大善”,但有时候她也会怀疑她所希望实现的控制和秩序,是否真的是人类最需要的。', - ow_luxiao:'卢西奥•科雷亚•多斯桑托斯在里约热内卢长大。“智能危机”结束后,由于经济的一蹶不振导致这里变成了一个贫穷拥挤的贫民区。他想找到一个办法激发周围人的信心与活力:音乐。他开始在街边、社区派对进行表演,随着年龄的增长便开始了一系列传奇的地下演出。但当多国集团费斯卡集团计划重建城市的大部分地区时,卢西奥所在的社区陷入了混乱,人们失去了自由。卢西奥绝对不会容忍这一切。他偷走了费斯卡用来压迫人民的音波技术,反过来将人们团结在一起。最终,在一场暴动中,他们将费斯卡集团赶出了家园。卢西奥的领导能力让他在一夜之间成为了明星和社会正能量的象征。他的音乐在人们心中的地位如火箭般蹿升。随着影响力的不断扩大,卢西奥意识到他有机会可以改变这个世界,让这个世界变得更美好。', - ow_shibing:'被全球通缉的独行侠“士兵:76”独自一人发动了一场旨在查出守望先锋解散真相的战争。“士兵:76”在全球一系列针对金融机构、秘密集团和守望先锋基地的袭击活动中被曝光。尽管外界至今不清楚他的动机是什么,但有人认为他曾是一位守望先锋特工,决心查出守望先锋垮台的幕后黑手。', - ow_yuanshi:'岛田忍者家族大名最年轻的儿子,但对家族的非法生意毫无兴趣,被视为一个危险的累赘。在家族大名意外死亡后,他与哥哥半藏的矛盾激化,最终导致了一场生死对决,源氏也因此差点送命。后来被守望先锋救下,并被改造成机械忍者以摧毁他父亲的邪恶帝国。在完成任务后,源氏因无法接受自己的机械身躯,离开了守户先锋,并游历世界希望能找到自己存在的意义。数年之后,他遇到了智械僧侣禅雅塔,并且在这位僧侣的引导下,源氏体内的人类和机械体验终于融合在了一起。他开始明白,尽管他有一副机械身躯,但他的人类灵魂是完整的,他渐渐意识到自己的新形态是给予自己的恩赐和力量。', - ow_chanyata:'在“智能危机”结束之后,一群被放逐的智能机器人感受到了被其称为“灵魂觉醒”的升华之道,他们渐渐相信他们和人类一样,同样拥有灵魂。由神秘僧侣泰哈撒·孟达塔带领的这些僧侣开始寻找让人类和机器人重回曾经的和谐相处之道。他们最终被世人所接纳,并得到了全球数百万人的支持。但其中一位僧侣,禅雅塔并不赞同这一新道路。他认为要解决人类和机器人之间根深蒂固的问题,不能依靠循循善诱,而必须通过个体联系和互动。最终,他选择离开寺庙,游走世界,帮助那些他所遇到的人摆脱凡尘。但如果有必要,他也会为了保护无辜而拿起武器,无论人类还是机器人。', - ow_dva:'D.Va曾是一名职业玩家,而现在则利用自己的技巧驾驶一台尖端机甲保卫国家。随着智能机械不断进化,它最终干扰了MEKA的无人机控制网络,迫使军方派驾驶员驾驶这些机甲。由于难以找到合适的候选人,政府开始向那些拥有足以操控机甲尖端武器系统的必要反应和本能的国内职业玩家寻求帮助,其中就包括顶尖玩家之一的“D.Va”宋哈娜。作为一名为了获胜不惜一切代价的精英玩家,D.Va从来都不会对对手表现出丝毫的仁慈。D.Va将这次新任务视为一款全新的游戏,无所畏惧地和其他MEKA机甲冲向战场,随时准备保卫自己的国家。最近,她开始向她的粉丝直播战斗行动,而这也让她成为了世界巨星。', - ow_mei:'守望先锋为了查明全球不断升级的怪异气候现象的真正原因,在世界各个位置建立了一系列生态监测站。周美灵就是这一长久项目的成员之一。当她来到该项目的南极洲监控站时,一场突如其来的极地风暴摧毁了大部分设施并将这里与外界隔绝了开来。随着补给物资的不断消耗,科学家们进入了急冻状态希望能够撑到救援队抵达的那一天。但救援并没有抵达。几年后,当这些科学家的急冻舱最终被发现时,美是唯一的幸存者。此时,守望先锋已经解散,所有的生态监测站也都已经被废弃,他们之前收集的研究数据全部丢失。美最终决定独自继续她的工作。她带上了一台可穿戴式气候控制装置,游历世界,希望能够重新建立起生态监测网络,查出威胁着这个星球生态系统的真正原因。', - ow_ana:'守望先锋的创始成员之一,世界公认的顶级狙击手。智械危机结束后,安娜被晋升为了上尉。尽管身居要职,但已年过半百的安娜拒绝离开战场,依然亲临前线。直至在一次人质解救行动中,遭遇了一个叫做“黑百合”的黑爪特工,所有人都认为安娜死在了那场战斗中。但事实上,安娜活了下来,身受重伤并且失去了自己的右眼。在恢复期间,她感受到了战斗中生命的不可承受之重,因此决定就此隐居。然而随着时间一天天过去,看着自己家乡遭到的威胁愈演愈烈,她突然意识到自己依然有责任保护身边的亲人。在“征用”了守望先锋军械库中的装备后,安娜重新回到了这个世界,为了一个更安全、稳定的和平世界而战。', - ow_heibaihe:'“黑百合”在成为如今的杀手之前,曾与对抗恐怖组织“黑爪”的守望先锋探员杰哈·拉克瓦结婚。在多次刺杀杰哈无果之后,黑爪决定将目标转向他的妻子,艾米丽。黑爪特工绑架了艾米丽并对其进行了一项高强度神经重构计划。他们击垮了她的意志,抑制了其本身的人性,将其变成了一个潜伏特工。她最终被守望先锋探员找到并在确认无致命伤之后重新过上了以前的生活。两周之后,她杀死了睡梦中的杰哈,并回归了黑爪。', - ow_maikelei:'曾是美国西南部因非法军火交易而臭名昭著的“死局”帮中,最令人胆寒的一员,后被守望先锋逮捕。由于其枪法精湛且足智多谋,守望先锋给了他两个选择:在最高安全级别的监狱中度过余生,或加入守望先锋的秘密行动部队“暗影守望”。他选择了后者。尽管一开始他对守望先锋的理念嗤之以鼻,但他逐渐相信可以通过扫除世上的不公,来弥补自己过去犯下的罪行。后来,暗影守望内部出现了异样的气氛:废除守望先锋,独掌大权。麦克雷由于不想参与其中,于是便独自离开,销声匿迹。多年之后,他以雇佣兵的身份再次出现。尽管许多大小团体都想拉拢他,但他只为自己眼中的正义而战。', - ow_kuangshu:'由于澳大利亚智能中枢核心在遭到攻击后发生爆炸,这片地区现在变成了寸草不生的辐射荒地。但即便如此,还是有一群自称为“拾荒者”的人类生存了下来。他们在残骸中寻找一切还可利用的东西,渐渐形成了一个野蛮、危险的团体。“狂鼠”就是其中的一员。和其他人一样,他也受到了辐射,因此变成了一个痴迷于危险炸弹的疯子。当他在中枢废墟中发掘出一个极其珍贵的宝藏后,全世界都知道了这个疯子的名号。尽管几乎没人知道他到底发现了什么,但他身后总有数不清的赏金猎人、黑帮和投机分子想要杀掉他,直到他与“拾荒者”打手“路霸”达到了一个协议:只要今后找到的宝贝五五分成,“路霸”就会是“狂鼠”的私人保镖。', - ow_tuobiang:'托比昂是一个极其不信任智械的天才工程师,但他的同行都认为这只是他杞人忧天而已。但托比昂最担心的事情最终还是发生了,一场机器人对抗其人类发明者的“智能危机”在全球范围内爆发。由于其在工程学方面的天才造诣,守望先锋向他伸出了橄榄枝,并将其纳入了最早的守望先锋攻击部队,而他也证明了自己在终结这场危机中的关键价值。但在守望先锋解散后,托比昂设计出的许多武器被偷走并被藏在世界各地。出于对自己作品的责任心,托比昂便发誓不能让这些武器落入敌手,危害无辜的世人。', - ow_baolei:'“堡垒”系列在设计之初是被用于维和目的的,这一系列的机器单位拥有能够快速在突击和攻城模式之间转换的独特能力。但在“智能危机”期间,该系列却被用来对抗其人类发明者,成为了机器人叛军的中坚力量。随着后来危机的解除,几乎所有的“堡垒”系列机器人都被销毁或拆解。直到今天,“堡垒”依旧是当年那场可怕战争的代名词。但是有一台独特的“堡垒”机器人,在那场战争的决战中严重受损,因此被遗忘了数十年。直到有一天,它被意外地重新激活,它的战斗程序几乎全部受损,取而代之的是对自然世界及其住民的强烈好奇。好奇的“堡垒”于是在这个被战火蹂躏过的世界上,开始了探索和寻找自我价值的旅途。', - ow_banzang:'岛田家据传已有数百年的历史。以忍者为主要成员的岛田家,经过多年的发展,已经建立起一个以军火和非法物资交易为主的庞大黑道帝国。作为大名的长子,半藏注定要继承他的父亲统治岛田帝国。父亲过世后,家族长老就建议半藏帮助他那刚愎自用的弟弟源氏,以便两人携手管理岛田帝国。在遭到源氏拒绝后,半藏被迫亲手了结了自己的弟弟。半藏因此深受打击,他拒绝继承父亲的遗产并最终抛弃了自己的家族和所有辛苦换来的成果。现在,半藏四海为家,不断磨练着自己作为一名武士的技巧,希望终有一天能挽回自己的名誉并真正放下自己的过去。', - ow_laiyinhate:'莱因哈特•威尔海姆的行事作风就像一个属于过去的勇士,时刻铭记着骑士的信条:无畏、公正、勇敢。莱因哈特独特的道德观和舍小为大的信念,深得其上级的喜爱。他有话直说,因此成为了守望先锋最坚定的拥护者,同时在有必要时,也是守望先锋最刻薄的批评者,时刻提醒着其他人,守望先锋是一支正义之师。莱因哈特一直服役到将近六十岁,因此不得不面临强制退役。而守望先锋又深陷腐败和煽动叛乱之嫌的泥沼,莱因哈特只能眼睁睁地看着自己守护了一生的信念被吞噬。尽管守望先锋最终解散,但莱因哈特绝不会在世界陷入混乱之时袖手旁观。他再一次穿上了十字军战甲,立誓为正义而战,像曾经的白银骑士那样守护欧罗巴大陆无辜的人民,坚信光明的未来必将到来。', - ow_luba:'“路霸”马可曾是众多居住在澳洲内陆的居民之一。在智能危机爆发后,政府作出了一个极具争议的决定,将这里送给了差点摧毁整个国家的智能机器人,以求达成永久的和平协定。这一决定直接导致马可和大批居民被迫离开,因失去家园而怒不可遏的马可和其他人开始了一场暴力起义,最终,引发了一场大爆炸,导致周围数公里地区全部遭到辐射,只留下了变形的金属和残骸。为了在这种环境下生存下来,他戴上了面具、骑着破烂摩托开上了通往澳洲内陆的残破高速公路。一路上,他的人性一点一点地被消磨,马可最终消失了,而“路霸”就此诞生。', - ow_wensidun:'在“地平线”月球殖民地的居民中,有一群经过基因改造的大猩猩。其中一只大猩猩在接受了哈罗德·温斯顿博士团队的基因改造后,显示出了极快的脑部发育迹象,博士本人也将人类科学和创造力教给了这只猩猩。但当其他大猩猩发动叛乱,杀死了所有科学家并占领殖民地后,他的生活便再也回不到过去了。出于对哈罗德博士的爱戴,这只大猩猩决定继承他的姓氏:温斯顿,并设计出了一枚临时火箭逃往了地球。他找到了新家:守望先锋 —— 这是一个代表着他所憧憬的所有人性的组织。温斯顿终于有机会实现哈罗德博士生前不断教导他的英雄理念。但随着后来守望先锋的解散,温斯顿也隐居了起来,再一次与他报以厚望的世界失去联系,但他却从未放弃对英雄最终回归的期望。', - ow_zhaliya:'亚历山德拉·查莉娅诺娃是世界上最强壮的女运动员之一。然而就在世锦赛前夕,一直处于休眠状态的西伯利亚机器人控制中枢再度发动攻击,战火再次蔓延到了她的家乡。早已名利双收的亚历山德拉,毅然抛弃了一切,立即回到家乡加入了当地的防御部队。', - ow_heiying:'作为全世界最臭名昭著的黑客,“黑影”利用信息与情报操控权贵。早在她称自己为“黑影”之前,░░░░░░是千千万万在智械危机后变成孤儿的儿童之一。在家乡大部分基础设施都被摧毁的情况下,她依靠自己在黑客以及计算机方面的天赋活了下来。在黑客领域的一连串的胜利让░░░░░░对自己的实力过度自信,最终她在毫无防备的情况下,陷入了一张覆盖全球的阴谋网——并且也因此被人盯上了。由于自己的安全面临严重威胁,░░░░░░不得不删除关于自己的全部信息,从此销声匿迹。后来,她以“黑影”的身份再度出现,经过改造的她决心查出那张阴谋网背后的真相。', + characterIntro: { + ow_orisa: + "奥丽莎是用在努巴尼昙花一现的OR15防御机器人的零件组装而成的,她是这座城市的新一代守护者,但依然有很大的成长空间", + ow_liekong: + "莉娜·奥克斯顿(代号:“猎空”)是守望先锋原型机试飞计划的最年轻成员。但在第一次试飞过程中,原型机的传送阵列出现故障,包括飞行员在内完全失踪。莉娜在几个月后再次出现,不过她身上的分子却无法和时间流同步。这种被称为“时间解离”的症状使她彻底变成了一个“活生生”的幽灵,时隐时现。直到一位名叫温斯顿的科学家设计出了“时间加速器”,一台可以让“猎空”维持在当前时间的装置。不仅如此,这一装置还让“猎空”有能力控制她自己的时间流,使她可以任意加速或减慢时间。有了这一全新的能力,她成了守望先锋最强大的特工之一。守望先锋解散后,“猎空”依旧选择为了正义而战,守护无辜。", + ow_sishen: + "关于这个黑袍恐怖分子的传闻并不多,只知道大家都称他为“死神”。虽然没人知道他的真实身份和动机,但有一点是可以肯定的,他的出现意味着死亡。“死神”是一名极其不稳定、残暴、冷酷的雇佣兵,在世界各地犯下多起恐怖袭击案件。在过去的数十年间,他参与了许多武装冲突,但其本人却不属于任何组织。在多年的追踪后,“死神”神秘的面纱终于被慢慢揭开。据信,“死神”正在追杀前守望先锋特工并系统地逐一消灭。", + ow_tianshi: + "齐格勒是瑞士一家顶尖医院的手术部门负责人。正是她在医学领域的成就,引起了守望先锋的注意。由于齐格勒的双亲都被战争夺走了生命,因此她从一开始就极其反对该组织通过军事手段进行维和。但最终,她意识到守望先锋给她提供了一个可以拯救更多人生命的机会。作为守望先锋医学研究部门的负责人,安吉拉致力于更好地在前线治疗受到致命伤的病员。尽管她对守望先锋做出了巨大的贡献,但齐格勒博士经常质疑她的上司以及守望先锋的长远目标。而当守望先锋解散之后,齐格勒博士便致力于帮助那些受战争波及的受难者。", + ow_falaozhiying: + "本名法芮尔,来自一个军功卓越的军人世家,贡献与荣耀就是她最高的追求。在加入埃及军队后,她的坚韧和在战术上的天赋使她很快就晋升为了一名军官。作为一名果敢的领袖,任何在她手下服役的士兵都对她抱有绝对的忠诚。有了所有这些卓越的表现,法芮尔自然成了守望先锋最青睐的一名候选人。但在她正式加入之前,守望先锋就解散了。当她带着所有的荣誉退役后,法芮尔加入了一家名为“海力士国际安保”的私人安保公司,该公司的最重要的一笔订单就是负责保护吉萨高原地下的人工智能研究设施。尽管她对守望先锋的解散感到无比的遗憾,但她依旧梦想着能为正义而战并改变这个残破的世界。", + ow_zhixuzhiguang: + "当被认为是为数不多可以成为光子建筑师的人才之后,年轻的塞特娅·法斯瓦尼离开了贫穷的家乡,成为了费斯卡光子建筑师学院的一员。她很快就成为了乌托邦最顶尖的光子建筑师。但费斯卡集团在塞特娅身上还是看到了更广阔的发展潜力。费斯卡集团称其为“秩序之光”,为了集团的利益和扩大在其他国家的影响力,将其派遣到全球执行秘密任务。虽然“秩序之光”相信她的所作所为是为了实现人性之“大善”,但有时候她也会怀疑她所希望实现的控制和秩序,是否真的是人类最需要的。", + ow_luxiao: + "卢西奥•科雷亚•多斯桑托斯在里约热内卢长大。“智能危机”结束后,由于经济的一蹶不振导致这里变成了一个贫穷拥挤的贫民区。他想找到一个办法激发周围人的信心与活力:音乐。他开始在街边、社区派对进行表演,随着年龄的增长便开始了一系列传奇的地下演出。但当多国集团费斯卡集团计划重建城市的大部分地区时,卢西奥所在的社区陷入了混乱,人们失去了自由。卢西奥绝对不会容忍这一切。他偷走了费斯卡用来压迫人民的音波技术,反过来将人们团结在一起。最终,在一场暴动中,他们将费斯卡集团赶出了家园。卢西奥的领导能力让他在一夜之间成为了明星和社会正能量的象征。他的音乐在人们心中的地位如火箭般蹿升。随着影响力的不断扩大,卢西奥意识到他有机会可以改变这个世界,让这个世界变得更美好。", + ow_shibing: + "被全球通缉的独行侠“士兵:76”独自一人发动了一场旨在查出守望先锋解散真相的战争。“士兵:76”在全球一系列针对金融机构、秘密集团和守望先锋基地的袭击活动中被曝光。尽管外界至今不清楚他的动机是什么,但有人认为他曾是一位守望先锋特工,决心查出守望先锋垮台的幕后黑手。", + ow_yuanshi: + "岛田忍者家族大名最年轻的儿子,但对家族的非法生意毫无兴趣,被视为一个危险的累赘。在家族大名意外死亡后,他与哥哥半藏的矛盾激化,最终导致了一场生死对决,源氏也因此差点送命。后来被守望先锋救下,并被改造成机械忍者以摧毁他父亲的邪恶帝国。在完成任务后,源氏因无法接受自己的机械身躯,离开了守户先锋,并游历世界希望能找到自己存在的意义。数年之后,他遇到了智械僧侣禅雅塔,并且在这位僧侣的引导下,源氏体内的人类和机械体验终于融合在了一起。他开始明白,尽管他有一副机械身躯,但他的人类灵魂是完整的,他渐渐意识到自己的新形态是给予自己的恩赐和力量。", + ow_chanyata: + "在“智能危机”结束之后,一群被放逐的智能机器人感受到了被其称为“灵魂觉醒”的升华之道,他们渐渐相信他们和人类一样,同样拥有灵魂。由神秘僧侣泰哈撒·孟达塔带领的这些僧侣开始寻找让人类和机器人重回曾经的和谐相处之道。他们最终被世人所接纳,并得到了全球数百万人的支持。但其中一位僧侣,禅雅塔并不赞同这一新道路。他认为要解决人类和机器人之间根深蒂固的问题,不能依靠循循善诱,而必须通过个体联系和互动。最终,他选择离开寺庙,游走世界,帮助那些他所遇到的人摆脱凡尘。但如果有必要,他也会为了保护无辜而拿起武器,无论人类还是机器人。", + ow_dva: "D.Va曾是一名职业玩家,而现在则利用自己的技巧驾驶一台尖端机甲保卫国家。随着智能机械不断进化,它最终干扰了MEKA的无人机控制网络,迫使军方派驾驶员驾驶这些机甲。由于难以找到合适的候选人,政府开始向那些拥有足以操控机甲尖端武器系统的必要反应和本能的国内职业玩家寻求帮助,其中就包括顶尖玩家之一的“D.Va”宋哈娜。作为一名为了获胜不惜一切代价的精英玩家,D.Va从来都不会对对手表现出丝毫的仁慈。D.Va将这次新任务视为一款全新的游戏,无所畏惧地和其他MEKA机甲冲向战场,随时准备保卫自己的国家。最近,她开始向她的粉丝直播战斗行动,而这也让她成为了世界巨星。", + ow_mei: "守望先锋为了查明全球不断升级的怪异气候现象的真正原因,在世界各个位置建立了一系列生态监测站。周美灵就是这一长久项目的成员之一。当她来到该项目的南极洲监控站时,一场突如其来的极地风暴摧毁了大部分设施并将这里与外界隔绝了开来。随着补给物资的不断消耗,科学家们进入了急冻状态希望能够撑到救援队抵达的那一天。但救援并没有抵达。几年后,当这些科学家的急冻舱最终被发现时,美是唯一的幸存者。此时,守望先锋已经解散,所有的生态监测站也都已经被废弃,他们之前收集的研究数据全部丢失。美最终决定独自继续她的工作。她带上了一台可穿戴式气候控制装置,游历世界,希望能够重新建立起生态监测网络,查出威胁着这个星球生态系统的真正原因。", + ow_ana: "守望先锋的创始成员之一,世界公认的顶级狙击手。智械危机结束后,安娜被晋升为了上尉。尽管身居要职,但已年过半百的安娜拒绝离开战场,依然亲临前线。直至在一次人质解救行动中,遭遇了一个叫做“黑百合”的黑爪特工,所有人都认为安娜死在了那场战斗中。但事实上,安娜活了下来,身受重伤并且失去了自己的右眼。在恢复期间,她感受到了战斗中生命的不可承受之重,因此决定就此隐居。然而随着时间一天天过去,看着自己家乡遭到的威胁愈演愈烈,她突然意识到自己依然有责任保护身边的亲人。在“征用”了守望先锋军械库中的装备后,安娜重新回到了这个世界,为了一个更安全、稳定的和平世界而战。", + ow_heibaihe: + "“黑百合”在成为如今的杀手之前,曾与对抗恐怖组织“黑爪”的守望先锋探员杰哈·拉克瓦结婚。在多次刺杀杰哈无果之后,黑爪决定将目标转向他的妻子,艾米丽。黑爪特工绑架了艾米丽并对其进行了一项高强度神经重构计划。他们击垮了她的意志,抑制了其本身的人性,将其变成了一个潜伏特工。她最终被守望先锋探员找到并在确认无致命伤之后重新过上了以前的生活。两周之后,她杀死了睡梦中的杰哈,并回归了黑爪。", + ow_maikelei: + "曾是美国西南部因非法军火交易而臭名昭著的“死局”帮中,最令人胆寒的一员,后被守望先锋逮捕。由于其枪法精湛且足智多谋,守望先锋给了他两个选择:在最高安全级别的监狱中度过余生,或加入守望先锋的秘密行动部队“暗影守望”。他选择了后者。尽管一开始他对守望先锋的理念嗤之以鼻,但他逐渐相信可以通过扫除世上的不公,来弥补自己过去犯下的罪行。后来,暗影守望内部出现了异样的气氛:废除守望先锋,独掌大权。麦克雷由于不想参与其中,于是便独自离开,销声匿迹。多年之后,他以雇佣兵的身份再次出现。尽管许多大小团体都想拉拢他,但他只为自己眼中的正义而战。", + ow_kuangshu: + "由于澳大利亚智能中枢核心在遭到攻击后发生爆炸,这片地区现在变成了寸草不生的辐射荒地。但即便如此,还是有一群自称为“拾荒者”的人类生存了下来。他们在残骸中寻找一切还可利用的东西,渐渐形成了一个野蛮、危险的团体。“狂鼠”就是其中的一员。和其他人一样,他也受到了辐射,因此变成了一个痴迷于危险炸弹的疯子。当他在中枢废墟中发掘出一个极其珍贵的宝藏后,全世界都知道了这个疯子的名号。尽管几乎没人知道他到底发现了什么,但他身后总有数不清的赏金猎人、黑帮和投机分子想要杀掉他,直到他与“拾荒者”打手“路霸”达到了一个协议:只要今后找到的宝贝五五分成,“路霸”就会是“狂鼠”的私人保镖。", + ow_tuobiang: + "托比昂是一个极其不信任智械的天才工程师,但他的同行都认为这只是他杞人忧天而已。但托比昂最担心的事情最终还是发生了,一场机器人对抗其人类发明者的“智能危机”在全球范围内爆发。由于其在工程学方面的天才造诣,守望先锋向他伸出了橄榄枝,并将其纳入了最早的守望先锋攻击部队,而他也证明了自己在终结这场危机中的关键价值。但在守望先锋解散后,托比昂设计出的许多武器被偷走并被藏在世界各地。出于对自己作品的责任心,托比昂便发誓不能让这些武器落入敌手,危害无辜的世人。", + ow_baolei: + "“堡垒”系列在设计之初是被用于维和目的的,这一系列的机器单位拥有能够快速在突击和攻城模式之间转换的独特能力。但在“智能危机”期间,该系列却被用来对抗其人类发明者,成为了机器人叛军的中坚力量。随着后来危机的解除,几乎所有的“堡垒”系列机器人都被销毁或拆解。直到今天,“堡垒”依旧是当年那场可怕战争的代名词。但是有一台独特的“堡垒”机器人,在那场战争的决战中严重受损,因此被遗忘了数十年。直到有一天,它被意外地重新激活,它的战斗程序几乎全部受损,取而代之的是对自然世界及其住民的强烈好奇。好奇的“堡垒”于是在这个被战火蹂躏过的世界上,开始了探索和寻找自我价值的旅途。", + ow_banzang: + "岛田家据传已有数百年的历史。以忍者为主要成员的岛田家,经过多年的发展,已经建立起一个以军火和非法物资交易为主的庞大黑道帝国。作为大名的长子,半藏注定要继承他的父亲统治岛田帝国。父亲过世后,家族长老就建议半藏帮助他那刚愎自用的弟弟源氏,以便两人携手管理岛田帝国。在遭到源氏拒绝后,半藏被迫亲手了结了自己的弟弟。半藏因此深受打击,他拒绝继承父亲的遗产并最终抛弃了自己的家族和所有辛苦换来的成果。现在,半藏四海为家,不断磨练着自己作为一名武士的技巧,希望终有一天能挽回自己的名誉并真正放下自己的过去。", + ow_laiyinhate: + "莱因哈特•威尔海姆的行事作风就像一个属于过去的勇士,时刻铭记着骑士的信条:无畏、公正、勇敢。莱因哈特独特的道德观和舍小为大的信念,深得其上级的喜爱。他有话直说,因此成为了守望先锋最坚定的拥护者,同时在有必要时,也是守望先锋最刻薄的批评者,时刻提醒着其他人,守望先锋是一支正义之师。莱因哈特一直服役到将近六十岁,因此不得不面临强制退役。而守望先锋又深陷腐败和煽动叛乱之嫌的泥沼,莱因哈特只能眼睁睁地看着自己守护了一生的信念被吞噬。尽管守望先锋最终解散,但莱因哈特绝不会在世界陷入混乱之时袖手旁观。他再一次穿上了十字军战甲,立誓为正义而战,像曾经的白银骑士那样守护欧罗巴大陆无辜的人民,坚信光明的未来必将到来。", + ow_luba: + "“路霸”马可曾是众多居住在澳洲内陆的居民之一。在智能危机爆发后,政府作出了一个极具争议的决定,将这里送给了差点摧毁整个国家的智能机器人,以求达成永久的和平协定。这一决定直接导致马可和大批居民被迫离开,因失去家园而怒不可遏的马可和其他人开始了一场暴力起义,最终,引发了一场大爆炸,导致周围数公里地区全部遭到辐射,只留下了变形的金属和残骸。为了在这种环境下生存下来,他戴上了面具、骑着破烂摩托开上了通往澳洲内陆的残破高速公路。一路上,他的人性一点一点地被消磨,马可最终消失了,而“路霸”就此诞生。", + ow_wensidun: + "在“地平线”月球殖民地的居民中,有一群经过基因改造的大猩猩。其中一只大猩猩在接受了哈罗德·温斯顿博士团队的基因改造后,显示出了极快的脑部发育迹象,博士本人也将人类科学和创造力教给了这只猩猩。但当其他大猩猩发动叛乱,杀死了所有科学家并占领殖民地后,他的生活便再也回不到过去了。出于对哈罗德博士的爱戴,这只大猩猩决定继承他的姓氏:温斯顿,并设计出了一枚临时火箭逃往了地球。他找到了新家:守望先锋 —— 这是一个代表着他所憧憬的所有人性的组织。温斯顿终于有机会实现哈罗德博士生前不断教导他的英雄理念。但随着后来守望先锋的解散,温斯顿也隐居了起来,再一次与他报以厚望的世界失去联系,但他却从未放弃对英雄最终回归的期望。", + ow_zhaliya: + "亚历山德拉·查莉娅诺娃是世界上最强壮的女运动员之一。然而就在世锦赛前夕,一直处于休眠状态的西伯利亚机器人控制中枢再度发动攻击,战火再次蔓延到了她的家乡。早已名利双收的亚历山德拉,毅然抛弃了一切,立即回到家乡加入了当地的防御部队。", + ow_heiying: + "作为全世界最臭名昭著的黑客,“黑影”利用信息与情报操控权贵。早在她称自己为“黑影”之前,░░░░░░是千千万万在智械危机后变成孤儿的儿童之一。在家乡大部分基础设施都被摧毁的情况下,她依靠自己在黑客以及计算机方面的天赋活了下来。在黑客领域的一连串的胜利让░░░░░░对自己的实力过度自信,最终她在毫无防备的情况下,陷入了一张覆盖全球的阴谋网——并且也因此被人盯上了。由于自己的安全面临严重威胁,░░░░░░不得不删除关于自己的全部信息,从此销声匿迹。后来,她以“黑影”的身份再度出现,经过改造的她决心查出那张阴谋网背后的真相。", }, - skill:{ - woliu:{ - trigger:{player:'phaseEnd'}, - direct:true, - unique:true, - forceunique:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('woliu'),lib.filter.notMe,[1,2]).ai=function(target){ - if(get.attitude(player,target)<0){ - return get.effect(target,{name:'sha'},player,player); + skill: { + woliu: { + trigger: { player: "phaseEnd" }, + direct: true, + unique: true, + forceunique: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("woliu"), lib.filter.notMe, [1, 2]).ai = function ( + target + ) { + if (get.attitude(player, target) < 0) { + return get.effect(target, { name: "sha" }, player, player); } return 0; - } - 'step 1' - if(result.bool){ - player.logSkill('woliu',result.targets); - var list=[player].concat(result.targets); - for(var i=0;i0){ - return [0,num]; + if (target.hasSkill("qianggu2") && get.attitude(player, target) > 0) { + return [0, num]; } - if(target.hp==1&&!target.hasShan()) return; - return [1,num]; + if (target.hp == 1 && !target.hasShan()) return; + return [1, num]; } - } - } - } - }, - qianggu:{ - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:2, - position:'he', - check:function(card){ - return 8-get.value(card); - }, - filter:function(event,player){ - return player.countCards('he')>=2; - }, - content:function(){ - player.changeHujia(2); - player.addTempSkill('qianggu2',{player:'phaseBegin'}); - }, - ai:{ - result:{ - player:1 + }, }, - order:2.5 - } + }, }, - qianggu2:{ - trigger:{target:'useCardToBefore'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'; + qianggu: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 2, + position: "he", + check: function (card) { + return 8 - get.value(card); }, - mark:true, - intro:{ - content:'其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效' + filter: function (event, player) { + return player.countCards("he") >= 2; }, - content:function(){ - "step 0" + content: function () { + player.changeHujia(2); + player.addTempSkill("qianggu2", { player: "phaseBegin" }); + }, + ai: { + result: { + player: 1, + }, + order: 2.5, + }, + }, + qianggu2: { + trigger: { target: "useCardToBefore" }, + forced: true, + filter: function (event, player) { + return event.card.name == "sha"; + }, + mark: true, + intro: { + content: "其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效", + }, + content: function () { + "step 0"; var eff; - if(player.hasSkill('woliu2')){ - eff=-get.attitude(trigger.player,player); + if (player.hasSkill("woliu2")) { + eff = -get.attitude(trigger.player, player); + } else { + eff = get.effect(player, trigger.card, trigger.player, trigger.player); } - else{ - eff=get.effect(player,trigger.card,trigger.player,trigger.player); - } - trigger.player.chooseToDiscard('强固:弃置一张基本牌,否则杀对'+get.translation(player)+'无效',function(card){ - return get.type(card)=='basic'; - }).set('ai',function(card){ - if(_status.event.eff>0){ - return 10-get.value(card); - } - return 0; - }).set('eff',eff); - "step 1" - if(result.bool==false){ + trigger.player + .chooseToDiscard( + "强固:弃置一张基本牌,否则杀对" + get.translation(player) + "无效", + function (card) { + return get.type(card) == "basic"; + } + ) + .set("ai", function (card) { + if (_status.event.eff > 0) { + return 10 - get.value(card); + } + return 0; + }) + .set("eff", eff); + "step 1"; + if (result.bool == false) { trigger.cancel(); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'){ - if(_status.event.name=='qianggu2') return; - if(get.attitude(player,target)>0) return; - var bs=player.getCards('h',{type:'basic'}); - if(bs.length<2) return 0; - if(player.hasSkill('jiu')||player.hasSkill('tianxianjiu')) return; - if(bs.length<=3&&player.countCards('h','sha')<=1){ - for(var i=0;i 0) return; + var bs = player.getCards("h", { type: "basic" }); + if (bs.length < 2) return 0; + if (player.hasSkill("jiu") || player.hasSkill("tianxianjiu")) return; + if (bs.length <= 3 && player.countCards("h", "sha") <= 1) { + for (var i = 0; i < bs.length; i++) { + if (bs[i].name != "sha" && get.value(bs[i]) < 7) { + return [1, 0, 1, -0.5]; } } return 0; } - return [1,0,1,-0.5]; + return [1, 0, 1, -0.5]; } - } - } - } - }, - dianji:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0; - }, - filterCard:true, - usable:1, - viewAs:{name:'jingleishan',nature:'thunder'}, - check:function(card){ - return 8-get.value(card) - }, - ai:{ - order:8, - expose:0.2, - threaten:1.2 - }, - mod:{ - playerEnabled:function(card,player,target){ - if(_status.event.skill=='dianji'&&get.distance(player,target)>2) return false; - } - } - }, - feitiao:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; - }, - content:function(){ - 'step 0' - var next=player.chooseCardTarget({ - prompt:get.prompt('feitiao'), - position:'he', - filterCard:true, - ai1:function(card){ - return 7-get.value(card); }, - ai2:function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(!target.countCards('he')) return -0.01; - var dist=get.distance(player,target); - if(dist>2){ - att-=2; - } - else if(dist==2){ + }, + }, + }, + dianji: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h") > 0; + }, + filterCard: true, + usable: 1, + viewAs: { name: "jingleishan", nature: "thunder" }, + check: function (card) { + return 8 - get.value(card); + }, + ai: { + order: 8, + expose: 0.2, + threaten: 1.2, + }, + mod: { + playerEnabled: function (card, player, target) { + if (_status.event.skill == "dianji" && get.distance(player, target) > 2) return false; + }, + }, + }, + feitiao: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + prompt: get.prompt("feitiao"), + position: "he", + filterCard: true, + ai1: function (card) { + return 7 - get.value(card); + }, + ai2: function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if (!target.countCards("he")) return -0.01; + var dist = get.distance(player, target); + if (dist > 2) { + att -= 2; + } else if (dist == 2) { att--; } return -att; }, - filterTarget:function(card,player,target){ - return player!=target; - } + filterTarget: function (card, player, target) { + return player != target; + }, }); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - var target=result.targets[0]; - player.logSkill('feitiao',target); - player.storage.feitiao2=target; - player.addTempSkill('feitiao2'); + var target = result.targets[0]; + player.logSkill("feitiao", target); + player.storage.feitiao2 = target; + player.addTempSkill("feitiao2"); target.randomDiscard(); } - } + }, }, - feitiao2:{ - mod:{ - globalFrom:function(from,to){ - if(to==from.storage.feitiao2) return -Infinity; - } + feitiao2: { + mod: { + globalFrom: function (from, to) { + if (to == from.storage.feitiao2) return -Infinity; + }, }, - mark:'character', - intro:{ - content:'与$的距离视为1直到回合结束' + mark: "character", + intro: { + content: "与$的距离视为1直到回合结束", }, - onremove:true + onremove: true, }, - zhencha:{ - init:function(player){ - player.storage.zhencha=true; + zhencha: { + init: function (player) { + player.storage.zhencha = true; }, - mark:true, - intro:{ - content:function(storage,player){ - if(storage){ - return '每当你使用一张杀,你摸一张牌或回复1点体力'; - } - else if(player.hasSkill('bshaowei')&&player.storage.bshaowei){ - return '你的杀无视距离和防具、无数量限制且不可闪避;你不能闪避杀'; - } - else{ - return '无额外技能'; - } - } - }, - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - if(player.hasSkill('zhencha2')) return false; - return !player.storage.zhencha; - }, - content:function(){ - player.storage.bshaowei=false; - player.storage.zhencha=true; - if(player.marks.zhencha){ - player.marks.zhencha.firstChild.innerHTML='侦'; - } - player.addTempSkill('zhencha2'); - }, - subSkill:{ - sha:{ - trigger:{player:'shaBegin'}, - direct:true, - filter:function(event,player){ - return player.storage.zhencha&&event.card&&event.card.name=='sha'; - }, - content:function(){ - player.chooseDrawRecover(get.prompt('zhencha')).logSkill='zhencha'; - } - } - }, - group:'zhencha_sha' - }, - bshaowei:{ - init:function(player){ - player.storage.bshaowei=false; - }, - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - if(player.hasSkill('zhencha2')) return false; - return !player.storage.bshaowei; - }, - check:function(event,player){ - if(!player.hasShan()) return true; - if(!player.hasSha()) return false; - return Math.random()<0.5; - }, - content:function(){ - player.storage.bshaowei=true; - player.storage.zhencha=false; - if(player.marks.zhencha){ - player.marks.zhencha.firstChild.innerHTML='哨'; - } - player.addTempSkill('zhencha2'); - }, - subSkill:{ - sha:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(card.name=='sha'&&player.storage.bshaowei) return true; - }, - cardUsable:function(card,player,num){ - if(card.name=='sha'&&player.storage.bshaowei) return Infinity; - } - }, - trigger:{target:'shaBegin',player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.bshaowei; - }, - check:function(){ - return false; - }, - content:function(){ - trigger.directHit=true; - }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!player.storage.bshaowei) return false; - if(arg&&arg.name=='sha') return true; - return false; - } - } - } - }, - group:'bshaowei_sha', - ai:{ - threaten:function(player,target){ - if(target.storage.bshaowei) return 1.7; - return 1; - } - } - }, - zhencha2:{}, - pingzhang:{ - trigger:{global:'damageBegin'}, - // alter:true, - intro:{ - content:function(storage,player){ - if(player.hasSkill('pingzhang2')){ - if(player.hasSkill('pingzhang3')){ - return '已对自已和其他角色发动屏障'; - } - else{ - return '已对自已发动屏障'; - } - } - else{ - return '已对其他角色发动屏障'; + mark: true, + intro: { + content: function (storage, player) { + if (storage) { + return "每当你使用一张杀,你摸一张牌或回复1点体力"; + } else if (player.hasSkill("bshaowei") && player.storage.bshaowei) { + return "你的杀无视距离和防具、无数量限制且不可闪避;你不能闪避杀"; + } else { + return "无额外技能"; } }, - markcount:function(storage,player){ - if(player.hasSkill('pingzhang2')&&player.hasSkill('pingzhang3')){ + }, + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + if (player.hasSkill("zhencha2")) return false; + return !player.storage.zhencha; + }, + content: function () { + player.storage.bshaowei = false; + player.storage.zhencha = true; + if (player.marks.zhencha) { + player.marks.zhencha.firstChild.innerHTML = "侦"; + } + player.addTempSkill("zhencha2"); + }, + subSkill: { + sha: { + trigger: { player: "shaBegin" }, + direct: true, + filter: function (event, player) { + return player.storage.zhencha && event.card && event.card.name == "sha"; + }, + content: function () { + player.chooseDrawRecover(get.prompt("zhencha")).logSkill = "zhencha"; + }, + }, + }, + group: "zhencha_sha", + }, + bshaowei: { + init: function (player) { + player.storage.bshaowei = false; + }, + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + if (player.hasSkill("zhencha2")) return false; + return !player.storage.bshaowei; + }, + check: function (event, player) { + if (!player.hasShan()) return true; + if (!player.hasSha()) return false; + return Math.random() < 0.5; + }, + content: function () { + player.storage.bshaowei = true; + player.storage.zhencha = false; + if (player.marks.zhencha) { + player.marks.zhencha.firstChild.innerHTML = "哨"; + } + player.addTempSkill("zhencha2"); + }, + subSkill: { + sha: { + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "sha" && player.storage.bshaowei) return true; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha" && player.storage.bshaowei) return Infinity; + }, + }, + trigger: { target: "shaBegin", player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return player.storage.bshaowei; + }, + check: function () { + return false; + }, + content: function () { + trigger.directHit = true; + }, + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!player.storage.bshaowei) return false; + if (arg && arg.name == "sha") return true; + return false; + }, + }, + }, + }, + group: "bshaowei_sha", + ai: { + threaten: function (player, target) { + if (target.storage.bshaowei) return 1.7; + return 1; + }, + }, + }, + zhencha2: {}, + pingzhang: { + trigger: { global: "damageBegin" }, + // alter:true, + intro: { + content: function (storage, player) { + if (player.hasSkill("pingzhang2")) { + if (player.hasSkill("pingzhang3")) { + return "已对自已和其他角色发动屏障"; + } else { + return "已对自已发动屏障"; + } + } else { + return "已对其他角色发动屏障"; + } + }, + markcount: function (storage, player) { + if (player.hasSkill("pingzhang2") && player.hasSkill("pingzhang3")) { return 2; } return 1; + }, + }, + filter: function (event, player) { + if (event.num <= 0) return false; + var position = get.is.altered("pingzhang") ? "h" : "he"; + if (event.player == player) { + if (player.hasSkill("pingzhang2")) return false; + return player.countCards(position, { suit: "heart" }); + } else { + if (player.hasSkill("pingzhang3")) return false; + return player.countCards(position, { suit: "spade" }); } }, - filter:function(event,player){ - if(event.num<=0) return false; - var position=get.is.altered('pingzhang')?'h':'he'; - if(event.player==player){ - if(player.hasSkill('pingzhang2')) return false; - return player.countCards(position,{suit:'heart'}); - } - else{ - if(player.hasSkill('pingzhang3')) return false; - return player.countCards(position,{suit:'spade'}); - } - }, - direct:true, - content:function(){ - 'step 0' - var position=get.is.altered('pingzhang')?'h':'he'; - var suit=(player==trigger.player)?'heart':'spade'; - var next=player.chooseToDiscard(position,{suit:suit},get.prompt('pingzhang',trigger.player)); - next.ai=function(card){ - if(get.damageEffect(trigger.player,trigger.source,player)<0){ - return 8-get.value(card); + direct: true, + content: function () { + "step 0"; + var position = get.is.altered("pingzhang") ? "h" : "he"; + var suit = player == trigger.player ? "heart" : "spade"; + var next = player.chooseToDiscard( + position, + { suit: suit }, + get.prompt("pingzhang", trigger.player) + ); + next.ai = function (card) { + if (get.damageEffect(trigger.player, trigger.source, player) < 0) { + return 8 - get.value(card); } return 0; - } - next.logSkill=['pingzhang',trigger.player]; - 'step 1' - if(result.bool){ + }; + next.logSkill = ["pingzhang", trigger.player]; + "step 1"; + if (result.bool) { trigger.num--; - if(player==trigger.player){ - player.addSkill('pingzhang2'); + if (player == trigger.player) { + player.addSkill("pingzhang2"); + } else { + player.addSkill("pingzhang3"); } - else{ - player.addSkill('pingzhang3'); - } - player.markSkill('pingzhang'); + player.markSkill("pingzhang"); } }, - group:['pingzhang_count'], - subSkill:{ - count:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - player.storage.pingzhang=0; - if(player.hasSkill('pingzhang2')){ + group: ["pingzhang_count"], + subSkill: { + count: { + trigger: { player: "phaseBegin" }, + silent: true, + content: function () { + player.storage.pingzhang = 0; + if (player.hasSkill("pingzhang2")) { player.storage.pingzhang++; - player.removeSkill('pingzhang2'); + player.removeSkill("pingzhang2"); } - if(player.hasSkill('pingzhang3')){ + if (player.hasSkill("pingzhang3")) { player.storage.pingzhang++; - player.removeSkill('pingzhang3'); + player.removeSkill("pingzhang3"); } - player.unmarkSkill('pingzhang'); - } - } + player.unmarkSkill("pingzhang"); + }, + }, + }, + ai: { + expose: 0.2, + threaten: 1.5, }, - ai:{ - expose:0.2, - threaten:1.5 - } }, - pingzhang2:{}, - pingzhang3:{}, - owliyong:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.pingzhang>0; + pingzhang2: {}, + pingzhang3: {}, + owliyong: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + filter: function (event, player) { + return player.storage.pingzhang > 0; + }, + content: function () { + trigger.num += player.storage.pingzhang; }, - content:function(){ - trigger.num+=player.storage.pingzhang; - } }, - liangou:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + liangou: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - filterCard:true, - position:'he', - check:function(card){ - return 5-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - 'step 0' - player.judge(function(card){ - return get.suit(card)!='heart'?1:-1; + content: function () { + "step 0"; + player.judge(function (card) { + return get.suit(card) != "heart" ? 1 : -1; }); - 'step 1' - if(result.bool){ - target.addTempSkill('liangou2'); - target.storage.liangou2=player; + "step 1"; + if (result.bool) { + target.addTempSkill("liangou2"); + target.storage.liangou2 = player; } }, - ai:{ - order:10, - expose:0.2, - result:{ - target:function(player,target){ - if(get.damageEffect(target,player,target)<0&&player.hasCard(function(card){ - return get.tag(card,'damage')?true:false; - })){ + ai: { + order: 10, + expose: 0.2, + result: { + target: function (player, target) { + if ( + get.damageEffect(target, player, target) < 0 && + player.hasCard(function (card) { + return get.tag(card, "damage") ? true : false; + }) + ) { return -1; } return 0; - } - } - } + }, + }, + }, }, - liangou2:{ - mod:{ + liangou2: { + mod: { // cardEnabled:function(card,player){ // return false; // }, @@ -580,16 +619,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // cardSavable:function(card,player){ // return false; // }, - globalTo:function(from,to){ - if(from==to.storage.liangou2) return -Infinity; - } + globalTo: function (from, to) { + if (from == to.storage.liangou2) return -Infinity; + }, }, - onremove:true, - trigger:{player:'damageBegin'}, - usable:1, - forced:true, - popup:false, - content:function(){ + onremove: true, + trigger: { player: "damageBegin" }, + usable: 1, + forced: true, + popup: false, + content: function () { trigger.num++; }, // ai:{ @@ -601,3065 +640,3275 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // } }, - xiyang:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - return !player.isTurnedOver()&&player.isDamaged(); + xiyang: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + return !player.isTurnedOver() && player.isDamaged(); }, - check:function(event,player){ - return player.hp<=1; + check: function (event, player) { + return player.hp <= 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.turnOver(); - 'step 1' + "step 1"; player.recover(2); - } + }, }, - qinru:{ - trigger:{player:'useCardToBegin'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target!=player&&event.target&&!event.target.hasSkill('fengyin'); + qinru: { + trigger: { player: "useCardToBegin" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.target != player && + event.target && + !event.target.hasSkill("fengyin") + ); }, - logTarget:'target', - check:function(event,player){ - return get.attitude(player,event.target)<0; + logTarget: "target", + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - intro:{ - content:'players', - mark:function(dialog,storage,player){ - var one=[],two=[],three=[]; - for(var i=0;i1){ + count: { + trigger: { player: "phaseAfter" }, + silent: true, + content: function () { + for (var i = 0; i < player.storage.qinru_turn.length; i++) { + if (player.storage.qinru_turn[i] > 1) { player.storage.qinru_turn[i]--; - } - else{ - player.storage.qinru.splice(i,1); - player.storage.qinru_turn.splice(i,1); + } else { + player.storage.qinru.splice(i, 1); + player.storage.qinru_turn.splice(i, 1); i--; } } - if(!player.storage.qinru.length){ - player.unmarkSkill('qinru'); - } - else{ + if (!player.storage.qinru.length) { + player.unmarkSkill("qinru"); + } else { player.updateMarks(); } - } - } + }, + }, }, - group:['qinru_count','qinru_die'] + group: ["qinru_count", "qinru_die"], }, - yinshen:{ - trigger:{player:'loseEnd'}, - forced:true, - filter:function(event,player){ - if(player.countCards('h',{type:'basic'})) return false; - for(var i=0;i0; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('yinshen'),'he',{type:'equip'}); - next.logSkill='yinshen'; - next.ai=function(card){ - if(player.hp==1) return 8-get.value(card); - if(player.isZhu) return 7-get.value(card); - if(player.hp==2) return 6-get.value(card); - return 5-get.value(card); + }, + yinshen_old: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt("yinshen"), "he", { type: "equip" }); + next.logSkill = "yinshen"; + next.ai = function (card) { + if (player.hp == 1) return 8 - get.value(card); + if (player.isZhu) return 7 - get.value(card); + if (player.hp == 2) return 6 - get.value(card); + return 5 - get.value(card); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.tempHide(); } }, }, - maichong:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(!player.hasSkill('qinru')||!player.storage.qinru||!player.storage.qinru.length) return false; - if(get.type(event.card)=='trick'&&event.cards[0]&&event.cards[0]==event.card){ - for(var i=0;i0; + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hujia > 0; }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return !target.hujia; }, - filterCard:true, - position:'he', - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current.hp==1&&get.attitude(player,current)>2; - })){ - return 7-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return current.hp == 1 && get.attitude(player, current) > 2; + }) + ) { + return 7 - get.value(card); } - return 5-get.value(card); + return 5 - get.value(card); }, - content:function(){ + content: function () { player.changeHujia(-1); target.changeHujia(); }, - ai:{ - order:5, - expose:0.2, - result:{ - target:function(player,target){ - return 1/Math.max(1,target.hp); - } - } - } + ai: { + order: 5, + expose: 0.2, + result: { + target: function (player, target) { + return 1 / Math.max(1, target.hp); + }, + }, + }, }, - maoding:{ - trigger:{player:'damageEnd',source:'damageEnd'}, - frequent:true, - filter:function(event,player){ - if(get.is.altered('maoding')&&event.source!=player) return false; + maoding: { + trigger: { player: "damageEnd", source: "damageEnd" }, + frequent: true, + filter: function (event, player) { + if (get.is.altered("maoding") && event.source != player) return false; return true; }, // alter:true, - content:function(){ - var list=get.typeCard('hslingjian'); - if(!list.length){ + content: function () { + var list = get.typeCard("hslingjian"); + if (!list.length) { return; } - player.gain(game.createCard(list.randomGet()),'gain2'); + player.gain(game.createCard(list.randomGet()), "gain2"); + }, + group: "maoding2", + ai: { + threaten: 1.5, + maixie_defend: true, }, - group:'maoding2', - ai:{ - threaten:1.5, - maixie_defend:true - } }, - maoding2:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h',{type:'hslingjian'})>1; + maoding2: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", { type: "hslingjian" }) > 1; }, - filterCard:{type:'hslingjian'}, - filterTarget:function(card,player,target){ + filterCard: { type: "hslingjian" }, + filterTarget: function (card, player, target) { return !target.hujia; }, - selectCard:2, + selectCard: 2, // usable:1, - content:function(){ + content: function () { target.changeHujia(); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return 2/Math.max(1,Math.sqrt(target.hp)); + ai: { + order: 9, + result: { + target: function (player, target) { + return 2 / Math.max(1, Math.sqrt(target.hp)); }, }, - } + }, }, - paotai:{ - enable:'phaseUse', - intro:{ - content:function(storage){ + paotai: { + enable: "phaseUse", + intro: { + content: function (storage) { var num; - switch(storage){ - case 1:num=30;break; - case 2:num=60;break; - case 3:num=100;break; + switch (storage) { + case 1: + num = 30; + break; + case 2: + num = 60; + break; + case 3: + num = 100; + break; } - return '结束阶段,有'+num+'%机率对一名随机敌人造成1点火焰伤害'; - } + return "结束阶段,有" + num + "%机率对一名随机敌人造成1点火焰伤害"; + }, }, - init:function(player){ - player.storage.paotai=0; + init: function (player) { + player.storage.paotai = 0; }, - filter:function(event,player){ - return player.countCards('h','sha')>0&&player.storage.paotai<3; + filter: function (event, player) { + return player.countCards("h", "sha") > 0 && player.storage.paotai < 3; }, - filterCard:{name:'sha'}, - content:function(){ + filterCard: { name: "sha" }, + content: function () { player.storage.paotai++; - player.markSkill('paotai'); + player.markSkill("paotai"); }, - ai:{ - order:5, - threaten:1.5, - result:{ - player:1 - } + ai: { + order: 5, + threaten: 1.5, + result: { + player: 1, + }, }, - group:['paotai2','paotai3'] + group: ["paotai2", "paotai3"], }, - paotai2:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ - var num=0; - switch(player.storage.paotai){ - case 1:num=30;break; - case 2:num=60;break; - case 3:num=100;break; + paotai2: { + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { + var num = 0; + switch (player.storage.paotai) { + case 1: + num = 30; + break; + case 2: + num = 60; + break; + case 3: + num = 100; + break; } - return 100*Math.random()0&&event.num>0; }, - content:function(){ - player.storage.paotai-=trigger.num; - if(player.storage.paotai<=0){ - player.storage.paotai=0; - player.unmarkSkill('paotai'); - } - else{ + }, + paotai3: { + trigger: { player: "damageEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.paotai > 0 && event.num > 0; + }, + content: function () { + player.storage.paotai -= trigger.num; + if (player.storage.paotai <= 0) { + player.storage.paotai = 0; + player.unmarkSkill("paotai"); + } else { player.updateMarks(); } - } + }, }, - bfengshi:{ - trigger:{player:'shaBegin'}, - forced:true, + bfengshi: { + trigger: { player: "shaBegin" }, + forced: true, // alter:true, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - filter:function(event,player){ - if(player.hasSkill('bfengshi4')) return false; - var num=0.2; - if(get.is.altered('bfengshi')) num=0.15; - return Math.random()0; + bfengshi4: {}, + yinbo: { + enable: "phaseUse", + usable: 1, + filterCard: { suit: "spade" }, + position: "he", + filter: function (event, player) { + return player.countCards("he", { suit: "spade" }) > 0; }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' - var targets=player.getEnemies(function(target){ - return target.countCards('he')>0; + content: function () { + "step 0"; + var targets = player.getEnemies(function (target) { + return target.countCards("he") > 0; }); - if(targets.length){ - event.targets=targets.randomGets(3); + if (targets.length) { + event.targets = targets.randomGets(3); event.targets.sort(lib.sort.seat); - player.line(event.targets,'green'); + player.line(event.targets, "green"); } - 'step 1' - if(event.targets.length){ - var target=event.targets.shift(); - var he=target.getCards('he'); - if(he.length){ + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + var he = target.getCards("he"); + if (he.length) { target.addExpose(0.1); target.discard(he.randomGet()); } event.redo(); } }, - ai:{ - order:10, - expose:0.3, - result:{ - player:1 - } - } + ai: { + order: 10, + expose: 0.3, + result: { + player: 1, + }, + }, }, - aqianghua:{ - enable:'phaseUse', - usable:1, + aqianghua: { + enable: "phaseUse", + usable: 1, // alter:true, - filter:function(event,player){ - return player.countCards('h')>=1; + filter: function (event, player) { + return player.countCards("h") >= 1; }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - filterCard:true, - selectCard:-1, - discard:false, - prepare:'give', - content:function(){ + filterCard: true, + selectCard: -1, + discard: false, + prepare: "give", + content: function () { target.gain(cards); - if(!get.is.altered('aqianghua')) target.changeHujia(); - target.addSkill('aqianghua2'); + if (!get.is.altered("aqianghua")) target.changeHujia(); + target.addSkill("aqianghua2"); }, - ai:{ - threaten:1.5, - order:2.1, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(get.attitude(player,target)<3) return 0; - if(target.hasJudge('lebu')) return 0; - if(target.hasSkill('aqianghua2')) return 0.1; + ai: { + threaten: 1.5, + order: 2.1, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (get.attitude(player, target) < 3) return 0; + if (target.hasJudge("lebu")) return 0; + if (target.hasSkill("aqianghua2")) return 0.1; return 1; - } - } - } + }, + }, + }, }, - aqianghua2:{ - trigger:{source:'damageBegin'}, - forced:true, - content:function(){ + aqianghua2: { + trigger: { source: "damageBegin" }, + forced: true, + content: function () { trigger.num++; - player.unmarkSkill('aqianghua2'); - player.removeSkill('aqianghua2'); + player.unmarkSkill("aqianghua2"); + player.removeSkill("aqianghua2"); + }, + mark: true, + intro: { + content: "下一次造成的伤害+1", }, - mark:true, - intro:{ - content:'下一次造成的伤害+1' - } }, - shihuo:{ - trigger:{global:'damageEnd'}, - forced:true, - filter:function(event){ - return event.hasNature('fire'); + shihuo: { + trigger: { global: "damageEnd" }, + forced: true, + filter: function (event) { + return event.hasNature("fire"); }, - content:function(){ + content: function () { player.draw(); - } + }, }, - shoujia:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + shoujia: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - check:function(card){ - return 6-get.value(card); + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - discard:false, - prepare:'give2', - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('shoujia2'); + discard: false, + prepare: "give2", + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("shoujia2"); }, - content:function(){ - target.storage.shoujia=cards[0]; - target.storage.shoujia2=player; - target.addSkill('shoujia2'); - target.syncStorage('shoujia'); + content: function () { + target.storage.shoujia = cards[0]; + target.storage.shoujia2 = player; + target.addSkill("shoujia2"); + target.syncStorage("shoujia"); + }, + ai: { + order: 1, + expose: 0.2, + threaten: 1.4, + result: { + target: -1, + }, }, - ai:{ - order:1, - expose:0.2, - threaten:1.4, - result:{ - target:-1 - } - } }, - shoujia2:{ - mark:true, - trigger:{player:'useCardToBegin'}, - forced:true, - filter:function(event,player){ - return get.suit(event.card)==get.suit(player.storage.shoujia)&&event.target&&event.target!=player; + shoujia2: { + mark: true, + trigger: { player: "useCardToBegin" }, + forced: true, + filter: function (event, player) { + return ( + get.suit(event.card) == get.suit(player.storage.shoujia) && + event.target && + event.target != player + ); }, - content:function(){ - 'step 0' - player.showCards([player.storage.shoujia],get.translation(player)+'发动了【兽夹】'); - 'step 1' + content: function () { + "step 0"; + player.showCards([player.storage.shoujia], get.translation(player) + "发动了【兽夹】"); + "step 1"; player.storage.shoujia.discard(); delete player.storage.shoujia; delete player.storage.shoujia2; - player.removeSkill('shoujia2'); - game.addVideo('storage',player,['shoujia',null]); - game.addVideo('storage',player,['shoujia2',null]); + player.removeSkill("shoujia2"); + game.addVideo("storage", player, ["shoujia", null]); + game.addVideo("storage", player, ["shoujia2", null]); player.turnOver(true); }, - intro:{ - mark:function(dialog,content,player){ - if(player.storage.shoujia2&&player.storage.shoujia2.isUnderControl(true)){ + intro: { + mark: function (dialog, content, player) { + if (player.storage.shoujia2 && player.storage.shoujia2.isUnderControl(true)) { dialog.add([player.storage.shoujia]); - } - else{ - return '已成为'+get.translation(player.storage.shoujia2)+'的兽夹目标'; + } else { + return "已成为" + get.translation(player.storage.shoujia2) + "的兽夹目标"; } }, - content:function(content,player){ - if(player.storage.shoujia2&&player.storage.shoujia2.isUnderControl(true)){ + content: function (content, player) { + if (player.storage.shoujia2 && player.storage.shoujia2.isUnderControl(true)) { return get.translation(player.storage.shoujia); } - return '已成为'+get.translation(player.storage.shoujia2)+'的兽夹目标'; - } + return "已成为" + get.translation(player.storage.shoujia2) + "的兽夹目标"; + }, }, - group:'shoujia3' + group: "shoujia3", }, - shoujia3:{ - trigger:{global:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.player==player.storage.shoujia2; + shoujia3: { + trigger: { global: "damageEnd" }, + forced: true, + filter: function (event, player) { + return event.player == player.storage.shoujia2; }, - content:function(){ + content: function () { player.storage.shoujia.discard(); player.$throw(player.storage.shoujia); - game.log(player.storage.shoujia,'被置入弃牌堆') + game.log(player.storage.shoujia, "被置入弃牌堆"); delete player.storage.shoujia; delete player.storage.shoujia2; - player.removeSkill('shoujia2'); - game.addVideo('storage',player,['shoujia',null]); - game.addVideo('storage',player,['shoujia2',null]); - } + player.removeSkill("shoujia2"); + game.addVideo("storage", player, ["shoujia", null]); + game.addVideo("storage", player, ["shoujia2", null]); + }, }, - liudan:{ - trigger:{player:'useCard'}, - check:function(event,player){ - return game.countPlayer(function(current){ - if(event.targets.includes(current)==false&¤t!=player&& - lib.filter.targetEnabled(event.card,player,current)){ - return get.effect(current,event.card,player,player); - } - })>=0; + liudan: { + trigger: { player: "useCard" }, + check: function (event, player) { + return ( + game.countPlayer(function (current) { + if ( + event.targets.includes(current) == false && + current != player && + lib.filter.targetEnabled(event.card, player, current) + ) { + return get.effect(current, event.card, player, player); + } + }) >= 0 + ); }, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return (event.targets.includes(current)==false&¤t!=player&& - lib.filter.targetEnabled(event.card,player,current)); + filter: function (event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return ( + event.targets.includes(current) == false && + current != player && + lib.filter.targetEnabled(event.card, player, current) + ); }); }, - content:function(){ - var list=game.filterPlayer(function(current){ - return (trigger.targets.includes(current)==false&¤t!=player&& - lib.filter.targetEnabled(trigger.card,player,current)); + content: function () { + var list = game.filterPlayer(function (current) { + return ( + trigger.targets.includes(current) == false && + current != player && + lib.filter.targetEnabled(trigger.card, player, current) + ); }); - if(list.length){ - var list2=[]; - for(var i=0;iplayer.countCards('h')&&!player.skipList.includes('phaseUse')&&!player.skipList.includes('phaseDiscard'); }, - check:function(event,player){ - var nh=player.countCards('h'); - if(Math.min(5,player.hp)-nh>=2) return true; + }, + tiandan: { + trigger: { player: "phaseDrawBegin" }, + filter: function (event, player) { + return ( + Math.min(5, player.hp) > player.countCards("h") && + !player.skipList.includes("phaseUse") && + !player.skipList.includes("phaseDiscard") + ); + }, + check: function (event, player) { + var nh = player.countCards("h"); + if (Math.min(5, player.hp) - nh >= 2) return true; return false; }, - content:function(){ - var num=Math.min(5,player.hp)-player.countCards('h'); - var cards=[]; - while(num--){ - cards.push(game.createCard('sha')); + content: function () { + var num = Math.min(5, player.hp) - player.countCards("h"); + var cards = []; + while (num--) { + cards.push(game.createCard("sha")); } - player.gain(cards,'gain2'); - player.skip('phaseUse'); - player.skip('phaseDiscard'); - } + player.gain(cards, "gain2"); + player.skip("phaseUse"); + player.skip("phaseDiscard"); + }, }, - shanguang:{ - enable:'phaseUse', - usable:1, - filterCard:{suit:'diamond'}, - position:'he', - filter:function(event,player){ - return player.countCards('he',{suit:'diamond'})>0; + shanguang: { + enable: "phaseUse", + usable: 1, + filterCard: { suit: "diamond" }, + position: "he", + filter: function (event, player) { + return player.countCards("he", { suit: "diamond" }) > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&get.distance(player,target,'attack')<=1; + filterTarget: function (card, player, target) { + return target != player && get.distance(player, target, "attack") <= 1; }, - check:function(card){ - if(card.name=='sha'&&_status.event.player.countCards('h','sha')<3) return 0; - return 6-get.value(card); + check: function (card) { + if (card.name == "sha" && _status.event.player.countCards("h", "sha") < 3) return 0; + return 6 - get.value(card); }, - content:function(){ - target.addTempSkill('shanguang2'); + content: function () { + target.addTempSkill("shanguang2"); }, - ai:{ - order:7.9, - result:{ - target:function(player,target){ - var nh=target.countCards('h'); - if(get.attitude(player,target)<0&&nh>=3&& - player.canUse('sha',target)&&player.countCards('h','sha')&& - get.effect(target,{name:'sha'},player,player)>0){ - return -nh-5; + ai: { + order: 7.9, + result: { + target: function (player, target) { + var nh = target.countCards("h"); + if ( + get.attitude(player, target) < 0 && + nh >= 3 && + player.canUse("sha", target) && + player.countCards("h", "sha") && + get.effect(target, { name: "sha" }, player, player) > 0 + ) { + return -nh - 5; } return -nh; - } - } - } - }, - shanguang2:{ - mod:{ - cardEnabled:function(){ - return false; + }, }, - cardUsable:function(){ - return false; - }, - cardRespondable:function(){ - return false; - }, - cardSavable:function(){ - return false; - } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')||get.tag(card,'respondSha')){ - if(current<0) return 1.5; + }, + shanguang2: { + mod: { + cardEnabled: function () { + return false; + }, + cardUsable: function () { + return false; + }, + cardRespondable: function () { + return false; + }, + cardSavable: function () { + return false; + }, + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") || get.tag(card, "respondSha")) { + if (current < 0) return 1.5; } - } - } - } + }, + }, + }, }, - baoxue:{ - enable:'phaseUse', - init:function(player){ - player.storage.baoxue=false; + baoxue: { + enable: "phaseUse", + init: function (player) { + player.storage.baoxue = false; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - mark:true, - unique:true, - skillAnimation:true, - animationColor:'water', - line:'thunder', - filter:function(event,player){ - return !player.storage.baoxue&&player.countCards('he',{color:'black'})>0; + mark: true, + unique: true, + skillAnimation: true, + animationColor: "water", + line: "thunder", + filter: function (event, player) { + return !player.storage.baoxue && player.countCards("he", { color: "black" }) > 0; }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - selectTarget:function(){ - return [1,_status.event.player.countCards('he',{color:'black'})]; + selectTarget: function () { + return [1, _status.event.player.countCards("he", { color: "black" })]; }, // alter:true, - delay:false, - contentBefore:function(){ - 'step 0' + delay: false, + contentBefore: function () { + "step 0"; game.delayx(); - 'step 1' - player.storage.baoxue=true; - player.awakenSkill('baoxue'); + "step 1"; + player.storage.baoxue = true; + player.awakenSkill("baoxue"); player.showHandcards(); - player.discard(player.getCards('he',{color:'black'})); + player.discard(player.getCards("he", { color: "black" })); }, - content:function(){ - 'step 0' - if(!get.is.altered('baoxue')){ - var he=target.getCards('he'); - if(he.length){ + content: function () { + "step 0"; + if (!get.is.altered("baoxue")) { + var he = target.getCards("he"); + if (he.length) { target.discard(he.randomGet()); } } - 'step 1' + "step 1"; target.turnOver(true); }, - contentAfter:function(){ + contentAfter: function () { player.turnOver(true); }, - ai:{ - order:function(skill,player){ - var num=game.countPlayer(function(current){ - return get.attitude(player,current)<0; + ai: { + order: function (skill, player) { + var num = game.countPlayer(function (current) { + return get.attitude(player, current) < 0; }); - var nh=player.countCards('he',{color:'black'}); - if(nh==1&&num>1) return 0; - if(nh>num) return 1; + var nh = player.countCards("he", { color: "black" }); + if (nh == 1 && num > 1) return 0; + if (nh > num) return 1; return 11; }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noturn')) return 0; - if(player.hasUnknown()) return 0; + result: { + target: function (player, target) { + if (target.hasSkillTag("noturn")) return 0; + if (player.hasUnknown()) return 0; return -1; - } - } - } + }, + }, + }, }, - mianzhen:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + mianzhen: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('mianzhen2'); + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("mianzhen2"); }, - filterCard:true, - position:'he', - check:function(card){ - return 8-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - 'step 0' - target.chooseToRespond({name:'shan'}); - 'step 1' - if(!result.bool) target.addSkill('mianzhen2'); + content: function () { + "step 0"; + target.chooseToRespond({ name: "shan" }); + "step 1"; + if (!result.bool) target.addSkill("mianzhen2"); + }, + ai: { + order: 2.2, + result: { + target: function (player, target) { + return Math.min(-0.1, -1 - target.countCards("h") + Math.sqrt(target.hp) / 2); + }, + }, }, - ai:{ - order:2.2, - result:{ - target:function(player,target){ - return Math.min(-0.1,-1-target.countCards('h')+Math.sqrt(target.hp)/2); - } - } - } }, - mianzhen2:{ - mark:true, - intro:{ - content:'不能使用或打出手牌直到受到伤害或下一回合结束' + mianzhen2: { + mark: true, + intro: { + content: "不能使用或打出手牌直到受到伤害或下一回合结束", }, - trigger:{player:['damageEnd','phaseEnd']}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('mianzhen2'); + trigger: { player: ["damageEnd", "phaseEnd"] }, + forced: true, + popup: false, + content: function () { + player.removeSkill("mianzhen2"); }, - mod:{ - cardEnabled:function(){ + mod: { + cardEnabled: function () { return false; }, - cardUsable:function(){ + cardUsable: function () { return false; }, - cardRespondable:function(){ + cardRespondable: function () { return false; }, - cardSavable:function(){ + cardSavable: function () { return false; - } + }, + }, + ai: { + threaten: 0.6, }, - ai:{ - threaten:0.6 - } }, - zhiyuan:{ - trigger:{source:'damageBefore'}, - check:function(event,player){ - player.disableSkill('tmp','zhiyuan'); - var eff=get.damageEffect(event.player,player,player); - var att=get.attitude(player,event.player); - var bool=false; - if(att>0){ - if(eff<=0||event.player.hp 0) { + if (eff <= 0 || event.player.hp < event.player.maxHp) { + bool = true; + } + } else { + if (eff < 0 && event.player.hp == event.player.maxHp) { + bool = true; } } - else{ - if(eff<0&&event.player.hp==event.player.maxHp){ - bool=true; - } - } - player.enableSkill('tmp','zhiyuan'); + player.enableSkill("tmp", "zhiyuan"); return bool; }, - logTarget:'player', - filter:function(event,player){ - return event.num>0; + logTarget: "player", + filter: function (event, player) { + return event.num > 0; }, - content:function(){ + content: function () { trigger.cancel(); trigger.player.recover(trigger.num); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(get.tag(card,'damage')&&get.attitude(player,target)>0){ - if(target.hp==target.maxHp||get.recoverEffect(target,player,player)<=0) return 'zeroplayertarget'; - return [0,0,0,1]; + ai: { + effect: { + player: function (card, player, target) { + if (get.tag(card, "damage") && get.attitude(player, target) > 0) { + if ( + target.hp == target.maxHp || + get.recoverEffect(target, player, player) <= 0 + ) + return "zeroplayertarget"; + return [0, 0, 0, 1]; } - } - } - } + }, + }, + }, }, - duwen:{ - trigger:{source:'damageBegin'}, - check:function(event,player){ - return get.attitude(player,event.player)<=0; + duwen: { + trigger: { source: "damageBegin" }, + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - forced:true, - filter:function(event,player){ - return player.countCards('h')==event.player.countCards('h')&&event.notLink(); + forced: true, + filter: function (event, player) { + return player.countCards("h") == event.player.countCards("h") && event.notLink(); }, - content:function(){ + content: function () { trigger.num++; }, - ai:{ - threaten:1.5 + ai: { + threaten: 1.5, }, }, - duwen2:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.hp==event.player.hp&&event.notLink(); + duwen2: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + player.hp == event.player.hp && + event.notLink() + ); }, - content:function(){ + content: function () { player.draw(2); - } - }, - juji:{ - enable:'phaseUse', - usable:1, - position:'he', - filter:function(event,player){ - return player.countCards('he')>0; }, - filterCard:function(card){ - var suit=get.suit(card); - for(var i=0;i 0; + }, + filterCard: function (card) { + var suit = get.suit(card); + for (var i = 0; i < ui.selected.cards.length; i++) { + if (get.suit(ui.selected.cards[i]) == suit) return false; } return true; }, - complexCard:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + complexCard: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - check:function(card){ - if(ui.selected.cards.length>1) return 0; - return 5-get.value(card); + check: function (card) { + if (ui.selected.cards.length > 1) return 0; + return 5 - get.value(card); }, - selectCard:[1,4], - content:function(){ - var suits=[]; - for(var i=0;inum){ - min.length=0; + ai: { + order: 4, + result: { + target: function (player, target) { + if (!player.countCards("h", "sha")) return 0; + if (target.countCards("h") <= 1 && get.distance(player, target, "attack") <= 1) + return 0; + var min = []; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && player.canUse("sha", players[i], false)) { + var eff = get.effect(players[i], { name: "sha" }, player, player); + if (eff > num) { + min.length = 0; min.push(players[i]); - num=eff; + num = eff; } } } - for(var i=0;i0) return 0; - if(min[i].countCards('h')<=1&&get.distance(player,min[i],'attack')<=1) return 0; + for (var i = 0; i < min.length; i++) { + if (get.attitude(player, min[i]) > 0) return 0; + if ( + min[i].countCards("h") <= 1 && + get.distance(player, min[i], "attack") <= 1 + ) + return 0; } - if(min.includes(target)) return -1; + if (min.includes(target)) return -1; return 0; - } - } + }, + }, }, }, - juji2:{ - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name=='sha'&&target==player.storage.juji2) return [1,0,1,-1]; - } - } + juji2: { + ai: { + effect: { + player: function (card, player, target) { + if (card.name == "sha" && target == player.storage.juji2) return [1, 0, 1, -1]; + }, + }, }, - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - content:function(){ - player.unmarkSkill('juji2'); - player.removeSkill('juji2'); + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + content: function () { + player.unmarkSkill("juji2"); + player.removeSkill("juji2"); delete player.storage.juji2; }, - group:'juji3' + group: "juji3", }, - juji3:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return event.target==player.storage.juji2; + juji3: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return event.target == player.storage.juji2; }, - content:function(){ - trigger.directHit=true; + content: function () { + trigger.directHit = true; + }, + mod: { + globalFrom: function (from, to) { + if (to == from.storage.juji2) return -Infinity; + }, }, - mod:{ - globalFrom:function(from,to){ - if(to==from.storage.juji2) return -Infinity; - } - } }, - dulei:{ - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('dulei2'); + dulei: { + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("dulei2"); }, - filterCard:true, - check:function(card){ - return 6-get.value(card); + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - discard:false, - prepare:function(cards,player){ - player.$give(1,player,false); + discard: false, + prepare: function (cards, player) { + player.$give(1, player, false); }, - content:function(){ - player.storage.dulei=cards[0]; - player.addSkill('dulei2'); - player.syncStorage('dulei'); + content: function () { + player.storage.dulei = cards[0]; + player.addSkill("dulei2"); + player.syncStorage("dulei"); + }, + ai: { + order: 1, + result: { + player: 1, + }, }, - ai:{ - order:1, - result:{ - player:1 - } - } }, - dulei2:{ - mark:true, - trigger:{target:'useCardToBegin'}, - forced:true, - filter:function(event,player){ - return event.player!=player&&get.suit(event.card)==get.suit(player.storage.dulei); + dulei2: { + mark: true, + trigger: { target: "useCardToBegin" }, + forced: true, + filter: function (event, player) { + return event.player != player && get.suit(event.card) == get.suit(player.storage.dulei); }, - content:function(){ - 'step 0' - player.showCards([player.storage.dulei],get.translation(player)+'发动了【诡雷】'); - 'step 1' + content: function () { + "step 0"; + player.showCards([player.storage.dulei], get.translation(player) + "发动了【诡雷】"); + "step 1"; player.storage.dulei.discard(); delete player.storage.dulei; - player.removeSkill('dulei2'); - game.addVideo('storage',player,['dulei',null]); + player.removeSkill("dulei2"); + game.addVideo("storage", player, ["dulei", null]); trigger.player.loseHp(); - 'step 2' - var he=trigger.player.getCards('he'); - if(he.length){ + "step 2"; + var he = trigger.player.getCards("he"); + if (he.length) { trigger.player.discard(he.randomGet()); } }, - intro:{ - mark:function(dialog,content,player){ - if(player==game.me||player.isUnderControl()){ + intro: { + mark: function (dialog, content, player) { + if (player == game.me || player.isUnderControl()) { dialog.add([player.storage.dulei]); - } - else{ - return '已发动诡雷'; + } else { + return "已发动诡雷"; } }, - content:function(content,player){ - if(player==game.me||player.isUnderControl()){ + content: function (content, player) { + if (player == game.me || player.isUnderControl()) { return get.translation(player.storage.dulei); } - return '已发动诡雷'; - } - } + return "已发动诡雷"; + }, + }, }, - juji_old:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return get.distance(event.target,player,'attack')>1; + juji_old: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return get.distance(event.target, player, "attack") > 1; }, - content:function(){ - trigger.directHit=true; + content: function () { + trigger.directHit = true; }, - group:'juji2' + group: "juji2", }, - juji2_old:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + juji2_old: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - target.addTempSkill('juji3',{player:'phaseEnd'}); - if(!target.storage.juji3){ - target.storage.juji3=[]; + content: function () { + target.addTempSkill("juji3", { player: "phaseEnd" }); + if (!target.storage.juji3) { + target.storage.juji3 = []; } target.storage.juji3.push(player); }, - mod:{ - targetInRange:function(card,player,target){ - if(target.hasSkill('juji3')&&Array.isArray(target.storage.juji3)&&target.storage.juji3.includes(player)){ + mod: { + targetInRange: function (card, player, target) { + if ( + target.hasSkill("juji3") && + Array.isArray(target.storage.juji3) && + target.storage.juji3.includes(player) + ) { return true; } - } - } - }, - juji3_old:{ - mark:true, - intro:{ - nocount:true, - content:function(storage){ - return '对'+get.translation(storage)+'使用卡牌无视距离'; - } + }, }, - mod:{ - targetInRange:function(card,player,target){ - if(Array.isArray(player.storage.juji3)&&player.storage.juji3.includes(target)){ + }, + juji3_old: { + mark: true, + intro: { + nocount: true, + content: function (storage) { + return "对" + get.translation(storage) + "使用卡牌无视距离"; + }, + }, + mod: { + targetInRange: function (card, player, target) { + if (Array.isArray(player.storage.juji3) && player.storage.juji3.includes(target)) { return true; } - } - } + }, + }, }, - zhuagou:{ - enable:'phaseUse', - usable:1, - changeSeat:true, - filterTarget:function(card,player,target){ - return player!=target&&player.next!=target; + zhuagou: { + enable: "phaseUse", + usable: 1, + changeSeat: true, + filterTarget: function (card, player, target) { + return player != target && player.next != target; }, - filterCard:true, - check:function(card){ - return 4-get.value(card); + filterCard: true, + check: function (card) { + return 4 - get.value(card); }, - content:function(){ - while(player.next!=target){ - game.swapSeat(player,player.next); + content: function () { + while (player.next != target) { + game.swapSeat(player, player.next); } }, - ai:{ - order:5, - result:{ - player:function(player,target){ - var att=get.attitude(player,target); - if(target==player.previous&&att>0) return 1; - if(target==player.next.next&&get.attitude(player,player.next)<0) return 1; + ai: { + order: 5, + result: { + player: function (player, target) { + var att = get.attitude(player, target); + if (target == player.previous && att > 0) return 1; + if (target == player.next.next && get.attitude(player, player.next) < 0) return 1; return 0; - } - } - } + }, + }, + }, }, - bingqiang:{ - enable:'phaseUse', - position:'he', - filterCard:function(card){ - var color=get.color(card); - for(var i=0;imax){ - max=num; + check: function (card) { + if (ui.selected.cards.length) return 0; + var player = _status.event.player; + var max = 0, + min = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (!lib.skill.bingqiang.filterTarget(null, player, players[i])) continue; + var num = lib.skill.bingqiang.ai.result.playerx(player, players[i]); + if (num > max) { + max = num; } - if(num-min){ - if(get.color(card)=='red') return 5-get.value(card); - } - else{ - if(get.color(card)=='black') return 5-get.value(card); + if (max == -min) { + return 5 - get.value(card); + } else if (max > -min) { + if (get.color(card) == "red") return 5 - get.value(card); + } else { + if (get.color(card) == "black") return 5 - get.value(card); } return 0; }, - changeTarget:function(player,targets){ - var target=targets[0]; - var add=game.filterPlayer(function(player){ - return get.distance(target,player,'pure')==1; + changeTarget: function (player, targets) { + var target = targets[0]; + var add = game.filterPlayer(function (player) { + return get.distance(target, player, "pure") == 1; }); - for(var i=0;i0; + bingqiang_remove: { + trigger: { player: ["phaseBegin", "dieBegin"] }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.bingqiang && player.storage.bingqiang.length > 0; }, - content:function(){ - for(var i=0;i0; + bingqiang_old: { + trigger: { global: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var goon=false; - var goon2=false; - var att=get.attitude(player,trigger.player); - if(att>0){ - if(trigger.player.hp==1) goon=true; + content: function () { + "step 0"; + var goon = false; + var goon2 = false; + var att = get.attitude(player, trigger.player); + if (att > 0) { + if (trigger.player.hp == 1) goon = true; + } else { + if (Math.random() < 0.5) goon = true; } - else{ - if(Math.random()<0.5) goon=true; - } - if(Math.random()<0.3) goon2=true; - player.chooseToDiscard([1,player.countCards('h')],'he',get.prompt('bingqiang',trigger.player)).set('logSkill',['bingqiang',trigger.player]).ai=function(card){ - if(ui.selected.cards.length) return 0; - if(goon) return 6-get.value(card); - if(goon2) return 4-get.value(card); + if (Math.random() < 0.3) goon2 = true; + player + .chooseToDiscard( + [1, player.countCards("h")], + "he", + get.prompt("bingqiang", trigger.player) + ) + .set("logSkill", ["bingqiang", trigger.player]).ai = function (card) { + if (ui.selected.cards.length) return 0; + if (goon) return 6 - get.value(card); + if (goon2) return 4 - get.value(card); return 0; - } - 'step 1' - if(result.bool){ - var num=result.cards.length; - event.num=num; - player.chooseControl('选项一','选项二','选项三','选项四',function(){ - if(get.attitude(player,trigger.player)>0){ - if(Math.random()<0.7) return '选项一'; - return '选项三'; - } - else{ - if(Math.random()<0.7) return '选项四'; - return '选项二'; - } - }).set('prompt','冰墙

              选项一:防御距离+'+num+ - '

              选项二:防御距离-'+num+ - '

              选项三:进攻距离+'+num+ - '

              选项四:进攻距离-'+num+'
              '); - } - else{ + }; + "step 1"; + if (result.bool) { + var num = result.cards.length; + event.num = num; + player + .chooseControl("选项一", "选项二", "选项三", "选项四", function () { + if (get.attitude(player, trigger.player) > 0) { + if (Math.random() < 0.7) return "选项一"; + return "选项三"; + } else { + if (Math.random() < 0.7) return "选项四"; + return "选项二"; + } + }) + .set( + "prompt", + '冰墙

              选项一:防御距离+' + + num + + '

              选项二:防御距离-' + + num + + '

              选项三:进攻距离+' + + num + + '

              选项四:进攻距离-' + + num + + "
              " + ); + } else { event.finish(); } - 'step 2' - switch(result.control){ - case '选项一':{ - trigger.player.storage.bingqiang2=event.num; - trigger.player.addTempSkill('bingqiang2',{player:'phaseBegin'}); + "step 2"; + switch (result.control) { + case "选项一": { + trigger.player.storage.bingqiang2 = event.num; + trigger.player.addTempSkill("bingqiang2", { player: "phaseBegin" }); break; } - case '选项二':{ - trigger.player.storage.bingqiang3=event.num; - trigger.player.addTempSkill('bingqiang3',{player:'phaseBegin'}); + case "选项二": { + trigger.player.storage.bingqiang3 = event.num; + trigger.player.addTempSkill("bingqiang3", { player: "phaseBegin" }); break; } - case '选项三':{ - trigger.player.storage.bingqiang4=event.num; - trigger.player.addTempSkill('bingqiang4',{player:'phaseBegin'}); + case "选项三": { + trigger.player.storage.bingqiang4 = event.num; + trigger.player.addTempSkill("bingqiang4", { player: "phaseBegin" }); break; } - case '选项四':{ - trigger.player.storage.bingqiang5=event.num; - trigger.player.addTempSkill('bingqiang5',{player:'phaseBegin'}); + case "选项四": { + trigger.player.storage.bingqiang5 = event.num; + trigger.player.addTempSkill("bingqiang5", { player: "phaseBegin" }); break; } } }, - ai:{ - expose:0.1 - } - }, - bingqiang2:{ - mark:true, - intro:{ - content:'防御距离+#' + ai: { + expose: 0.1, }, - mod:{ - globalTo:function(from,to,distance){ - if(typeof to.storage.bingqiang2=='number') return distance+to.storage.bingqiang2; + }, + bingqiang2: { + mark: true, + intro: { + content: "防御距离+#", + }, + mod: { + globalTo: function (from, to, distance) { + if (typeof to.storage.bingqiang2 == "number") return distance + to.storage.bingqiang2; }, - } - }, - bingqiang3:{ - mark:true, - intro:{ - content:'防御距离-#' }, - mod:{ - globalTo:function(from,to,distance){ - if(typeof to.storage.bingqiang3=='number') return distance-to.storage.bingqiang3; + }, + bingqiang3: { + mark: true, + intro: { + content: "防御距离-#", + }, + mod: { + globalTo: function (from, to, distance) { + if (typeof to.storage.bingqiang3 == "number") return distance - to.storage.bingqiang3; }, - } + }, }, - bingqiang4:{ - mark:true, - intro:{ - content:'进攻距离+#' + bingqiang4: { + mark: true, + intro: { + content: "进攻距离+#", + }, + mod: { + globalFrom: function (from, to, distance) { + if (typeof from.storage.bingqiang4 == "number") + return distance - from.storage.bingqiang4; + }, }, - mod:{ - globalFrom:function(from,to,distance){ - if(typeof from.storage.bingqiang4=='number') return distance-from.storage.bingqiang4; - } - } }, - bingqiang5:{ - mark:true, - intro:{ - content:'进攻距离-#' + bingqiang5: { + mark: true, + intro: { + content: "进攻距离-#", + }, + mod: { + globalFrom: function (from, to, distance) { + if (typeof from.storage.bingqiang5 == "number") + return distance + from.storage.bingqiang5; + }, }, - mod:{ - globalFrom:function(from,to,distance){ - if(typeof from.storage.bingqiang5=='number') return distance+from.storage.bingqiang5; - } - } }, - shuangqiang:{ - trigger:{source:'damageBegin'}, - check:function(event,player){ - var att=get.attitude(player,event.player); - if(event.player.hp==1) return att>0; - return att<=0; + shuangqiang: { + trigger: { source: "damageBegin" }, + check: function (event, player) { + var att = get.attitude(player, event.player); + if (event.player.hp == 1) return att > 0; + return att <= 0; }, - logTarget:'player', - filter:function(event,player){ - return !event.player.isTurnedOver()&&event.num>0; + logTarget: "player", + filter: function (event, player) { + return !event.player.isTurnedOver() && event.num > 0; }, - content:function(){ + content: function () { trigger.num--; trigger.player.draw(); trigger.player.turnOver(); - } + }, }, - jidong:{ - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return player.hp==1&&!player.isTurnedOver(); + jidong: { + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return player.hp == 1 && !player.isTurnedOver(); }, // alter:true, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.turnOver(); player.recover(2); - 'step 1' - if(player.isTurnedOver()&&!get.is.altered('jidong')){ - player.addTempSkill('jidong2',{player:'turnOverAfter'}); + "step 1"; + if (player.isTurnedOver() && !get.is.altered("jidong")) { + player.addTempSkill("jidong2", { player: "turnOverAfter" }); } }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 2; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 2; return 1; - } - } - }, - jidong2:{ - trigger:{player:'damageBefore'}, - forced:true, - content:function(){ - trigger.cancel(); - }, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')) return [0,0]; - } }, }, - mod:{ - targetEnabled:function(card,player,target){ - if(player!=target) return false; - } - } }, - chongzhuang:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player.storage.jijia<=0&&event.num>0; + jidong2: { + trigger: { player: "damageBefore" }, + forced: true, + content: function () { + trigger.cancel(); }, - popup:false, - unique:true, - content:function(){ - player.storage.jijia2+=trigger.num; - if(player.storage.jijia2>=4){ - player.storage.jijia=4; - player.storage.jijia2=0; - player.markSkill('jijia'); - if(lib.config.skill_animation_type!='off'){ - player.logSkill('chongzhuang'); - player.$skill('重装') + ai: { + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) return [0, 0]; + }, + }, + }, + mod: { + targetEnabled: function (card, player, target) { + if (player != target) return false; + }, + }, + }, + chongzhuang: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player.storage.jijia <= 0 && event.num > 0; + }, + popup: false, + unique: true, + content: function () { + player.storage.jijia2 += trigger.num; + if (player.storage.jijia2 >= 4) { + player.storage.jijia = 4; + player.storage.jijia2 = 0; + player.markSkill("jijia"); + if (lib.config.skill_animation_type != "off") { + player.logSkill("chongzhuang"); + player.$skill("重装"); } } - } + }, }, - tuijin:{ - enable:'phaseUse', - usable:1, - unique:true, - filter:function(event,player){ - if(player.storage.jijia>0){ - return game.hasPlayer(function(current){ - return get.distance(player,current)>1 + tuijin: { + enable: "phaseUse", + usable: 1, + unique: true, + filter: function (event, player) { + if (player.storage.jijia > 0) { + return game.hasPlayer(function (current) { + return get.distance(player, current) > 1; }); } return false; }, - filterTarget:function(card,player,target){ - return target!=player&&get.distance(player,target)>1; + filterTarget: function (card, player, target) { + return target != player && get.distance(player, target) > 1; }, - content:function(){ - player.storage.tuijin2=target; - player.addTempSkill('tuijin2'); + content: function () { + player.storage.tuijin2 = target; + player.addTempSkill("tuijin2"); }, - ai:{ - order:11, - result:{ - target:function(player,target){ - if(get.attitude(player,target)<0){ - if(get.distance(player,target)>2) return -1.5; + ai: { + order: 11, + result: { + target: function (player, target) { + if (get.attitude(player, target) < 0) { + if (get.distance(player, target) > 2) return -1.5; return -1; } return 0.3; - } - } - } + }, + }, + }, }, - tuijin2:{ - mod:{ - globalFrom:function(from,to){ - if(to==from.storage.tuijin2) return -Infinity; - } + tuijin2: { + mod: { + globalFrom: function (from, to) { + if (to == from.storage.tuijin2) return -Infinity; + }, }, - mark:'character', - intro:{ - content:'与$的距离视为1直到回合结束' + mark: "character", + intro: { + content: "与$的距离视为1直到回合结束", }, - onremove:true + onremove: true, }, - jijia:{ - mark:true, - unique:true, - init:function(player){ - player.storage.jijia=4; - player.storage.jijia2=0; + jijia: { + mark: true, + unique: true, + init: function (player) { + player.storage.jijia = 4; + player.storage.jijia2 = 0; }, - intro:{ - content:'机甲体力值:#' + intro: { + content: "机甲体力值:#", }, - mod:{ - maxHandcard:function(player,num){ - if(player.storage.jijia>0){ - return num+player.storage.jijia; + mod: { + maxHandcard: function (player, num) { + if (player.storage.jijia > 0) { + return num + player.storage.jijia; } - } + }, }, - trigger:{player:'changeHp'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.jijia>0&&event.parent.name=='damage'&&event.num<0; + trigger: { player: "changeHp" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.jijia > 0 && event.parent.name == "damage" && event.num < 0; }, - content:function(){ - player.hp-=trigger.num; + content: function () { + player.hp -= trigger.num; player.update(); - player.storage.jijia+=trigger.num; - if(player.storage.jijia<=0){ - player.unmarkSkill('jijia'); - } - else{ + player.storage.jijia += trigger.num; + if (player.storage.jijia <= 0) { + player.unmarkSkill("jijia"); + } else { player.updateMarks(); } }, - ai:{ - threaten:function(player,target){ - if(target.storage.jijia<=0) return 2; + ai: { + threaten: function (player, target) { + if (target.storage.jijia <= 0) return 2; return 1; - } - } + }, + }, }, - zihui:{ - enable:'phaseUse', - filter:function(event,player){ - return player.storage.jijia>0; + zihui: { + enable: "phaseUse", + filter: function (event, player) { + return player.storage.jijia > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&get.distance(player,target)<=2; + filterTarget: function (card, player, target) { + return target != player && get.distance(player, target) <= 2; }, - unique:true, - selectTarget:-1, - skillAnimation:true, - animationColor:'fire', - line:'fire', + unique: true, + selectTarget: -1, + skillAnimation: true, + animationColor: "fire", + line: "fire", // alter:true, - content:function(){ - 'step 0' - var num=player.storage.jijia; - if(get.is.altered('zihui')){ - num=Math.max(1,Math.min(num,target.countCards('he'))); + content: function () { + "step 0"; + var num = player.storage.jijia; + if (get.is.altered("zihui")) { + num = Math.max(1, Math.min(num, target.countCards("he"))); } - target.chooseToDiscard(num,'he','弃置'+get.cnNumber(num)+'张牌,或受到2点火焰伤害').ai=function(card){ - if(target.hasSkillTag('nofire')) return 0; - if(get.type(card)!='basic') return 11-get.value(card); - if(target.hp>4) return 7-get.value(card); - if(target.hp==4&&num>=3) return 7-get.value(card); - if(target.hp==3&&num>=4) return 7-get.value(card); - if(num>1) return 8-get.value(card); - return 10-get.value(card); + target.chooseToDiscard( + num, + "he", + "弃置" + get.cnNumber(num) + "张牌,或受到2点火焰伤害" + ).ai = function (card) { + if (target.hasSkillTag("nofire")) return 0; + if (get.type(card) != "basic") return 11 - get.value(card); + if (target.hp > 4) return 7 - get.value(card); + if (target.hp == 4 && num >= 3) return 7 - get.value(card); + if (target.hp == 3 && num >= 4) return 7 - get.value(card); + if (num > 1) return 8 - get.value(card); + return 10 - get.value(card); }; - 'step 1' - if(!result.bool){ - target.damage(2,'fire'); + "step 1"; + if (!result.bool) { + target.damage(2, "fire"); } - if(target==targets[targets.length-1]){ - player.storage.jijia=0; - player.unmarkSkill('jijia'); + if (target == targets[targets.length - 1]) { + player.storage.jijia = 0; + player.unmarkSkill("jijia"); } }, - ai:{ - order:2, - result:{ - player:function(player){ - var num=0; - var players=game.filterPlayer(); - for(var i=0;i2) continue; - var nh=players[i].countCards('h'); - var att=get.attitude(player,players[i]); - if(nh 2 + ) + continue; + var nh = players[i].countCards("h"); + var att = get.attitude(player, players[i]); + if (nh < player.storage.jijia) { + if (att < 0) { + if (players[i].hp <= 2) { + num += 2; + } else { + num += 1.5; } - else{ - num+=1.5; + } else if (att > 0) { + if (players[i].hp <= 2) { + num -= 2; + } else { + num -= 1.5; } } - else if(att>0){ - if(players[i].hp<=2){ - num-=2; - } - else{ - num-=1.5; - } - } - } - else if(nh==player.storage.jijia){ - if(att<0){ - num+=0.5; - } - else if(att>0){ - num-=0.5; + } else if (nh == player.storage.jijia) { + if (att < 0) { + num += 0.5; + } else if (att > 0) { + num -= 0.5; } } } - if(num>=2) return 1; + if (num >= 2) return 1; return 0; - } - } - } + }, + }, + }, }, - xiandan:{ - trigger:{player:'shaBegin'}, - direct:true, - content:function(){ - "step 0" - var dis=trigger.target.countCards('h','shan')||trigger.target.hasSkillTag('freeShan',false,{ - player:player, - card:trigger.card - },true)||trigger.target.countCards('h')>2; - var att=get.attitude(player,trigger.target); - var next=player.chooseToDiscard(get.prompt('xiandan')); - next.ai=function(card){ - if(att) return 0; - if(dis) return 7-get.value(card); + xiandan: { + trigger: { player: "shaBegin" }, + direct: true, + content: function () { + "step 0"; + var dis = + trigger.target.countCards("h", "shan") || + trigger.target.hasSkillTag( + "freeShan", + false, + { + player: player, + card: trigger.card, + }, + true + ) || + trigger.target.countCards("h") > 2; + var att = get.attitude(player, trigger.target); + var next = player.chooseToDiscard(get.prompt("xiandan")); + next.ai = function (card) { + if (att) return 0; + if (dis) return 7 - get.value(card); return 0; - } - next.logSkill='xiandan'; - "step 1" - if(result.bool){ - if(get.color(result.cards[0])=='red'){ - trigger.directHit=true; - } - else{ - player.addTempSkill('xiandan2','shaAfter'); + }; + next.logSkill = "xiandan"; + "step 1"; + if (result.bool) { + if (get.color(result.cards[0]) == "red") { + trigger.directHit = true; + } else { + player.addTempSkill("xiandan2", "shaAfter"); } } - } - }, - xiandan2:{ - trigger:{source:'damageBegin'}, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.notLink(); }, - forced:true, - popup:false, - content:function(){ + }, + xiandan2: { + trigger: { source: "damageBegin" }, + filter: function (event) { + return event.card && event.card.name == "sha" && event.notLink(); + }, + forced: true, + popup: false, + content: function () { trigger.num++; - } + }, }, - shouge:{ - trigger:{source:'dieAfter'}, - frequent:true, - content:function(){ - player.gain(game.createCard('zhiliaobo'),'gain2'); - } + shouge: { + trigger: { source: "dieAfter" }, + frequent: true, + content: function () { + player.gain(game.createCard("zhiliaobo"), "gain2"); + }, }, - tuji:{ - mod:{ - globalFrom:function(from,to,distance){ - if(_status.currentPhase==from){ - return distance-from.countUsed(); + tuji: { + mod: { + globalFrom: function (from, to, distance) { + if (_status.currentPhase == from) { + return distance - from.countUsed(); } }, }, }, - mujing:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:function(card){ - return get.color(card)=='black'; + mujing: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: function (card) { + return get.color(card) == "black"; }, - position:'he', - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(!player.countCards('he',{color:'black'})) return false; + position: "he", + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (!player.countCards("he", { color: "black" })) return false; }, - prompt:'将一张黑色牌当杀使用或打出', - check:function(card){return 4-get.value(card)}, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('he',{color:'black'})) return false; + prompt: "将一张黑色牌当杀使用或打出", + check: function (card) { + return 4 - get.value(card); + }, + ai: { + skillTagFilter: function (player) { + if (!player.countCards("he", { color: "black" })) return false; }, - respondSha:true, + respondSha: true, }, - group:'mujing2' + group: "mujing2", }, - mujing2:{ - trigger:{player:'shaMiss'}, - forced:true, - popup:false, - filter:function(event){ + mujing2: { + trigger: { player: "shaMiss" }, + forced: true, + popup: false, + filter: function (event) { return !event.parent._mujinged; }, - content:function(){ - trigger.parent._mujinged=true; + content: function () { + trigger.parent._mujinged = true; player.getStat().card.sha--; - } - }, - lichang:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{color:'red'})>0; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('lichang'),'he',{color:'red'}); - next.logSkill='lichang'; - next.ai=function(card){ - return 6-get.value(card); + }, + lichang: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { color: "red" }) > 0; + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt("lichang"), "he", { color: "red" }); + next.logSkill = "lichang"; + next.ai = function (card) { + return 6 - get.value(card); }; - "step 1" - if(result.bool){ - player.addSkill('lichang2'); + "step 1"; + if (result.bool) { + player.addSkill("lichang2"); } }, }, - lichang2:{ - trigger:{player:'phaseBegin'}, - direct:true, - mark:true, - intro:{ - content:'下个准备阶段令一名距离1以内的角色回复1点体力或摸两张牌' + lichang2: { + trigger: { player: "phaseBegin" }, + direct: true, + mark: true, + intro: { + content: "下个准备阶段令一名距离1以内的角色回复1点体力或摸两张牌", }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('lichang'),function(card,player,target){ - return get.distance(player,target)<=1; - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>0){ - if(target.hp==1&&target.maxHp>1) return att*2; + content: function () { + "step 0"; + player.chooseTarget(get.prompt("lichang"), function (card, player, target) { + return get.distance(player, target) <= 1; + }).ai = function (target) { + var att = get.attitude(player, target); + if (att > 0) { + if (target.hp == 1 && target.maxHp > 1) return att * 2; } return att; }; - player.removeSkill('lichang2'); - 'step 1' - if(result.bool){ - player.logSkill('lichang',result.targets); - result.targets[0].chooseDrawRecover(2,true); + player.removeSkill("lichang2"); + "step 1"; + if (result.bool) { + player.logSkill("lichang", result.targets); + result.targets[0].chooseDrawRecover(2, true); } - } - }, - mujing_old:{ - trigger:{player:'useCardToBegin'}, - filter:function(event,player){ - return event.target&&event.target!=player&&get.distance(event.target,player,'attack')>1; }, - direct:true, - content:function(){ - 'step 0' - player.discardPlayerCard(get.prompt('mujing'),trigger.target).logSkill=['mujing']; - 'step 1' - if(result.bool&&player.countCards('h')<=trigger.target.countCards('h')){ + }, + mujing_old: { + trigger: { player: "useCardToBegin" }, + filter: function (event, player) { + return ( + event.target && + event.target != player && + get.distance(event.target, player, "attack") > 1 + ); + }, + direct: true, + content: function () { + "step 0"; + player.discardPlayerCard(get.prompt("mujing"), trigger.target).logSkill = ["mujing"]; + "step 1"; + if (result.bool && player.countCards("h") <= trigger.target.countCards("h")) { player.draw(); } - } + }, }, - zhanlong:{ - trigger:{player:'phaseBegin'}, - unique:true, - mark:true, - skillAnimation:true, - init:function(player){ - player.storage.zhanlong=false; + zhanlong: { + trigger: { player: "phaseBegin" }, + unique: true, + mark: true, + skillAnimation: true, + init: function (player) { + player.storage.zhanlong = false; }, - check:function(event,player){ - if(player.hasJudge('lebu')) return false; + check: function (event, player) { + if (player.hasJudge("lebu")) return false; return true; }, - filter:function(event,player){ - if(player.storage.zhanlong) return false; - if(player.countCards('he')==0) return false; - if(player.hp!=1) return false; + filter: function (event, player) { + if (player.storage.zhanlong) return false; + if (player.countCards("he") == 0) return false; + if (player.hp != 1) return false; return true; }, - content:function(){ - 'step 0' - player.discard(player.getCards('he')); - 'step 1' - player.addTempSkill('zhanlong2'); - player.awakenSkill('zhanlong'); - player.storage.zhanlong=true; - var cards=[]; - for(var i=0;i<3;i++){ - cards.push(game.createCard('sha')); + content: function () { + "step 0"; + player.discard(player.getCards("he")); + "step 1"; + player.addTempSkill("zhanlong2"); + player.awakenSkill("zhanlong"); + player.storage.zhanlong = true; + var cards = []; + for (var i = 0; i < 3; i++) { + cards.push(game.createCard("sha")); } - player.gain(cards,'gain2'); + player.gain(cards, "gain2"); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 3; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 3; return 1; }, - effect:{ - target:function(card,player,target){ - if(!target.hasFriend()) return; - if(get.tag(card,'damage')==1&&target.hp==2&&target.countCards('he')&& - !target.isTurnedOver()&&_status.currentPhase!=target){ - if(get.distance(_status.currentPhase,target,'absolute')<=2) return [0.5,1]; + effect: { + target: function (card, player, target) { + if (!target.hasFriend()) return; + if ( + get.tag(card, "damage") == 1 && + target.hp == 2 && + target.countCards("he") && + !target.isTurnedOver() && + _status.currentPhase != target + ) { + if (get.distance(_status.currentPhase, target, "absolute") <= 2) + return [0.5, 1]; return 0.8; } - } - } + }, + }, + }, + intro: { + content: "limited", }, - intro:{ - content:'limited' - } }, - zhanlong2:{ - mod:{ - cardUsable:function(card){ - if(card.name=='sha') return Infinity; - } - } + zhanlong2: { + mod: { + cardUsable: function (card) { + if (card.name == "sha") return Infinity; + }, + }, }, - feiren:{ - trigger:{source:'damageBegin'}, - forced:true, + feiren: { + trigger: { source: "damageBegin" }, + forced: true, // alter:true, - filter:function(event,player){ - return !get.is.altered('feiren')&&event.card&&event.card.name=='sha'&&get.suit(event.card)=='spade'&&event.notLink(); + filter: function (event, player) { + return ( + !get.is.altered("feiren") && + event.card && + event.card.name == "sha" && + get.suit(event.card) == "spade" && + event.notLink() + ); }, - content:function(){ + content: function () { trigger.num++; }, - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; }, - selectTarget:function(card,player,range){ - if(card.name=='sha'&&range[1]!=-1&&get.suit(card)=='club'){ + selectTarget: function (card, player, range) { + if (card.name == "sha" && range[1] != -1 && get.suit(card) == "club") { range[1]++; } }, }, - ai:{ - threaten:1.4 - } + ai: { + threaten: 1.4, + }, }, - feiren3:{ - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(event.parent.name=='feiren2') return false; - if(event.card.name!='sha') return false; - if(get.suit(event.card)!='spade') return false; - var card=game.createCard(event.card.name,event.card.suit,event.card.number,event.card.nature); - for(var i=0;i0){ + if (current && get.recoverEffect(current, player, player) > 0) { return 0; } - return get.recoverEffect(target,player,target); - } - } - } - }, - xie2:{ - mark:true, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - if(player.storage.xie=='now'){ - return event.player==player; - } - var num=game.phaseNumber-player.storage.xie; - return num&&num%6==0; + return get.recoverEffect(target, player, target); + }, + }, }, - content:function(){ - if(player.storage.xie=='now'){ - player.storage.xie=game.phaseNumber; + }, + xie2: { + mark: true, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + if (player.storage.xie == "now") { + return event.player == player; + } + var num = game.phaseNumber - player.storage.xie; + return num && num % 6 == 0; + }, + content: function () { + if (player.storage.xie == "now") { + player.storage.xie = game.phaseNumber; } player.recover(); }, - intro:{ - content:function(storage,player){ - var str='每隔六回合回复1点体力,直到'+get.translation(storage)+'死亡'; - if(typeof player.storage.xie=='number'){ - var num=game.phaseNumber-player.storage.xie; - num=num%6; - if(num==0){ - str+='(下次生效于本回合)' - } - else{ - str+='(下次生效于'+(6-num)+'回合后)' + intro: { + content: function (storage, player) { + var str = "每隔六回合回复1点体力,直到" + get.translation(storage) + "死亡"; + if (typeof player.storage.xie == "number") { + var num = game.phaseNumber - player.storage.xie; + num = num % 6; + if (num == 0) { + str += "(下次生效于本回合)"; + } else { + str += "(下次生效于" + (6 - num) + "回合后)"; } } return str; }, - onunmark:function(storage,player){ + onunmark: function (storage, player) { delete player.storage.xie; delete player.storage.xie2; - } + }, }, - group:['xie3','xie4'] + group: ["xie3", "xie4"], }, - xie3:{ - trigger:{global:'phaseBegin'}, - forced:true, - popup:false, - content:function(){ - var num=game.phaseNumber-player.storage.xie; - num=num%6; - if(num){ - num=6-num; + xie3: { + trigger: { global: "phaseBegin" }, + forced: true, + popup: false, + content: function () { + var num = game.phaseNumber - player.storage.xie; + num = num % 6; + if (num) { + num = 6 - num; } - player.storage.xie2_markcount=num; + player.storage.xie2_markcount = num; player.updateMarks(); - } + }, }, - xie4:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player==player.storage.xie2; + xie4: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.xie2; + }, + content: function () { + game.log(player, "解除了", "【谐】"); + player.removeSkill("xie2"); }, - content:function(){ - game.log(player,'解除了','【谐】'); - player.removeSkill('xie2'); - } }, - luan:{ - enable:'phaseUse', - unique:true, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('luan2'); + luan: { + enable: "phaseUse", + unique: true, + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("luan2"); }, - filter:function(event,player){ - return player.countCards('h',{suit:'spade'}); + filter: function (event, player) { + return player.countCards("h", { suit: "spade" }); }, - filterCard:{suit:'spade'}, - check:function(card){ - return 7-get.value(card); + filterCard: { suit: "spade" }, + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - var current=game.findPlayer(function(player){ - return player.hasSkill('luan2'); + content: function () { + var current = game.findPlayer(function (player) { + return player.hasSkill("luan2"); }); - if(current){ - current.removeSkill('luan2'); + if (current) { + current.removeSkill("luan2"); } - target.addSkill('luan2'); + target.addSkill("luan2"); // target.storage.luan='now'; - target.storage.luan2=player; + target.storage.luan2 = player; }, - ai:{ - expose:0.2, - order:9.1, - threaten:2, - result:{ - target:function(player,target){ - var current=game.findPlayer(function(player){ - return player.hasSkill('luan2'); + ai: { + expose: 0.2, + order: 9.1, + threaten: 2, + result: { + target: function (player, target) { + var current = game.findPlayer(function (player) { + return player.hasSkill("luan2"); }); - if(current&&get.attitude(player,current)<0){ + if (current && get.attitude(player, current) < 0) { return 0; } - if(target.hp==1) return 0.5; + if (target.hp == 1) return 0.5; return -1; - } - } - } - }, - luan2:{ - mark:true, - intro:{ - content:'受到的伤害后失去1点体力,直到首次进入濒死状态' + }, + }, }, - trigger:{player:'damageEnd'}, - forced:true, - content:function(){ + }, + luan2: { + mark: true, + intro: { + content: "受到的伤害后失去1点体力,直到首次进入濒死状态", + }, + trigger: { player: "damageEnd" }, + forced: true, + content: function () { player.loseHp(); }, - ai:{ - threaten:1.2 + ai: { + threaten: 1.2, }, - group:['luan3','luan4'] + group: ["luan3", "luan4"], }, - luan3:{ - trigger:{player:'dyingAfter'}, - forced:true, - popup:false, - content:function(){ - game.log(player,'解除了','【乱】'); - player.removeSkill('luan2'); - } + luan3: { + trigger: { player: "dyingAfter" }, + forced: true, + popup: false, + content: function () { + game.log(player, "解除了", "【乱】"); + player.removeSkill("luan2"); + }, }, - luan2_old:{ - mark:true, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - if(player.storage.luan=='now'){ - return event.player==player; + luan2_old: { + mark: true, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + if (player.storage.luan == "now") { + return event.player == player; } - var num=game.phaseNumber-player.storage.luan; - return num&&num%6==0; + var num = game.phaseNumber - player.storage.luan; + return num && num % 6 == 0; }, - content:function(){ - if(player.storage.luan=='now'){ - player.storage.luan=game.phaseNumber; + content: function () { + if (player.storage.luan == "now") { + player.storage.luan = game.phaseNumber; } player.loseHp(); }, - intro:{ - content:function(storage,player){ - var str='每隔六回合失去1点体力,直到'+get.translation(storage)+'死亡'; - if(typeof player.storage.luan=='number'){ - var num=game.phaseNumber-player.storage.luan; - num=num%6; - if(num==0){ - str+='(下次生效于本回合)' - } - else{ - str+='(下次生效于'+(6-num)+'回合后)' + intro: { + content: function (storage, player) { + var str = "每隔六回合失去1点体力,直到" + get.translation(storage) + "死亡"; + if (typeof player.storage.luan == "number") { + var num = game.phaseNumber - player.storage.luan; + num = num % 6; + if (num == 0) { + str += "(下次生效于本回合)"; + } else { + str += "(下次生效于" + (6 - num) + "回合后)"; } } return str; }, - onunmark:function(storage,player){ + onunmark: function (storage, player) { delete player.storage.luan; delete player.storage.luan2; - } + }, }, - group:['luan3','luan4'] + group: ["luan3", "luan4"], }, - luan3_old:{ - trigger:{global:'phaseBegin'}, - forced:true, - popup:false, - content:function(){ - var num=game.phaseNumber-player.storage.luan; - num=num%6; - if(num){ - num=6-num; + luan3_old: { + trigger: { global: "phaseBegin" }, + forced: true, + popup: false, + content: function () { + var num = game.phaseNumber - player.storage.luan; + num = num % 6; + if (num) { + num = 6 - num; } - player.storage.luan2_markcount=num; + player.storage.luan2_markcount = num; player.updateMarks(); - } - }, - luan4:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player==player.storage.luan2; }, - content:function(){ - game.log(player,'解除了','【乱】'); - player.removeSkill('luan2'); - } }, - sheng:{ - enable:'phaseUse', - unique:true, - mark:true, - skillAnimation:true, - animationColor:'metal', - init:function(player){ - player.storage.sheng=false; + luan4: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.luan2; }, - filter:function(event,player){ - if(player.storage.sheng) return false; + content: function () { + game.log(player, "解除了", "【乱】"); + player.removeSkill("luan2"); + }, + }, + sheng: { + enable: "phaseUse", + unique: true, + mark: true, + skillAnimation: true, + animationColor: "metal", + init: function (player) { + player.storage.sheng = false; + }, + filter: function (event, player) { + if (player.storage.sheng) return false; return true; }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return target.isDamaged(); }, - selectTarget:[1,Infinity], - contentBefore:function(){ + selectTarget: [1, Infinity], + contentBefore: function () { player.turnOver(); - player.addSkill('sheng2'); - player.awakenSkill('sheng'); - player.storage.sheng=true; + player.addSkill("sheng2"); + player.awakenSkill("sheng"); + player.storage.sheng = true; }, - content:function(){ + content: function () { target.recover(); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var eff=get.recoverEffect(target,player,target); - if(player.hp==1) return eff; - if(player.hasUnknown()) return 0; - var num1=0,num2=0,num3=0,players=game.filterPlayer(); - for(var i=0;i0){ + ai: { + order: 1, + result: { + target: function (player, target) { + var eff = get.recoverEffect(target, player, target); + if (player.hp == 1) return eff; + if (player.hasUnknown()) return 0; + var num1 = 0, + num2 = 0, + num3 = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) { num1++; - if(players[i].isDamaged()){ + if (players[i].isDamaged()) { num2++; - if(players[i].hp<=1){ + if (players[i].hp <= 1) { num3++; } } } } - if(num1==num2) return eff; - if(num2==num1-1&&num3) return eff; - if(num3>=2) return eff; + if (num1 == num2) return eff; + if (num2 == num1 - 1 && num3) return eff; + if (num3 >= 2) return eff; return 0; - } + }, }, }, - intro:{ - content:'limited' - } - }, - sheng2:{ - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('sheng2'); + intro: { + content: "limited", }, - mod:{ - targetEnabled:function(card,player,target){ - if(player!=target) return false; - } - } }, - yihun:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{color:'black'})>0&&!player.hasSkill('yihun2'); + sheng2: { + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("sheng2"); }, - content:function(){ - 'step 0' - var next=player.chooseCardTarget({ - prompt:get.prompt('yihun'), - position:'he', - filterCard:function(card,player){ - return get.color(card)=='black'&&lib.filter.cardDiscardable(card,player); + mod: { + targetEnabled: function (card, player, target) { + if (player != target) return false; + }, + }, + }, + yihun: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { color: "black" }) > 0 && !player.hasSkill("yihun2"); + }, + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + prompt: get.prompt("yihun"), + position: "he", + filterCard: function (card, player) { + return get.color(card) == "black" && lib.filter.cardDiscardable(card, player); }, - ai1:function(card){ - return 7-get.value(card); + ai1: function (card) { + return 7 - get.value(card); }, - ai2:function(target){ - var att=-get.attitude(player,target); - if(target==player.next){ - att/=10; + ai2: function (target) { + var att = -get.attitude(player, target); + if (target == player.next) { + att /= 10; } - if(target==player.next.next){ - att/=2; + if (target == player.next.next) { + att /= 2; } return att; }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, }); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - player.logSkill('yihun',result.targets); - player.addSkill('yihun2'); - var target=result.targets[0] - player.storage.yihun2=target; - if(target&&(get.mode()!='guozhan')||!target.isUnseen()){ - player.markSkillCharacter('yihun2',target,'移魂','在'+get.translation(target)+'的下一准备阶段视为对其使用一张杀'); + player.logSkill("yihun", result.targets); + player.addSkill("yihun2"); + var target = result.targets[0]; + player.storage.yihun2 = target; + if ((target && get.mode() != "guozhan") || !target.isUnseen()) { + player.markSkillCharacter( + "yihun2", + target, + "移魂", + "在" + get.translation(target) + "的下一准备阶段视为对其使用一张杀" + ); } } }, }, - yihun2:{ - trigger:{global:['phaseBegin','dieAfter']}, - forced:true, - filter:function(event,player){ - return event.player==player.storage.yihun2; + yihun2: { + trigger: { global: ["phaseBegin", "dieAfter"] }, + forced: true, + filter: function (event, player) { + return event.player == player.storage.yihun2; }, - content:function(){ - if(player.storage.yihun2.isIn()){ - player.useCard({name:'sha'},player.storage.yihun2); + content: function () { + if (player.storage.yihun2.isIn()) { + player.useCard({ name: "sha" }, player.storage.yihun2); } - player.removeSkill('yihun2'); + player.removeSkill("yihun2"); delete player.storage.yihun2; }, - mod:{ - targetEnabled:function(){ + mod: { + targetEnabled: function () { return false; }, - cardEnabled:function(card,player){ + cardEnabled: function (card, player) { return false; }, - } - }, - huoyu:{ - enable:'phaseUse', - unique:true, - mark:true, - skillAnimation:true, - animationColor:'fire', - init:function(player){ - player.storage.huoyu=false; }, - filter:function(event,player){ - if(player.storage.huoyu) return false; - if(player.countCards('he',{color:'red'})<2) return false; + }, + huoyu: { + enable: "phaseUse", + unique: true, + mark: true, + skillAnimation: true, + animationColor: "fire", + init: function (player) { + player.storage.huoyu = false; + }, + filter: function (event, player) { + if (player.storage.huoyu) return false; + if (player.countCards("he", { color: "red" }) < 2) return false; return true; }, - filterTarget:function(card,player,target){ - return player.canUse('chiyuxi',target); + filterTarget: function (card, player, target) { + return player.canUse("chiyuxi", target); }, - filterCard:{color:'red'}, - selectCard:2, - position:'he', - check:function(card){ - return 7-get.value(card); + filterCard: { color: "red" }, + selectCard: 2, + position: "he", + check: function (card) { + return 7 - get.value(card); }, - selectTarget:-1, - multitarget:true, - multiline:true, - line:'fire', - content:function(){ - 'step 0' + selectTarget: -1, + multitarget: true, + multiline: true, + line: "fire", + content: function () { + "step 0"; targets.sort(lib.sort.seat); - player.awakenSkill('huoyu'); - player.storage.huoyu=true; - player.useCard({name:'chiyuxi'},targets).animate=false; - 'step 1' - player.useCard({name:'chiyuxi'},targets).animate=false; + player.awakenSkill("huoyu"); + player.storage.huoyu = true; + player.useCard({ name: "chiyuxi" }, targets).animate = false; + "step 1"; + player.useCard({ name: "chiyuxi" }, targets).animate = false; }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(player.hasUnknown()) return 0; - return get.effect(target,{name:'chiyuxi'},player,target); - } + ai: { + order: 5, + result: { + target: function (player, target) { + if (player.hasUnknown()) return 0; + return get.effect(target, { name: "chiyuxi" }, player, target); + }, }, }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - feidan:{ - trigger:{source:'damageAfter'}, - direct:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - if(!event.card) return false; - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return current!=event.player&&get.distance(event.player,current)<=1 + feidan: { + trigger: { source: "damageAfter" }, + direct: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + if (!event.card) return false; + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return current != event.player && get.distance(event.player, current) <= 1; }); }, - content:function(){ - "step 0" - var eff=0; - var targets=game.filterPlayer(function(current){ - if(current!=trigger.player&&get.distance(trigger.player,current)<=1){ - eff+=get.damageEffect(current,player,player); + content: function () { + "step 0"; + var eff = 0; + var targets = game.filterPlayer(function (current) { + if (current != trigger.player && get.distance(trigger.player, current) <= 1) { + eff += get.damageEffect(current, player, player); return true; } }); - event.targets=targets; - player.chooseToDiscard(get.prompt('feidan',targets)).set('ai',function(card){ - if(eff>0) return 7-get.value(card); - return 0; - }).set('logSkill',['feidan',targets]); - "step 1" - if(result.bool){ + event.targets = targets; + player + .chooseToDiscard(get.prompt("feidan", targets)) + .set("ai", function (card) { + if (eff > 0) return 7 - get.value(card); + return 0; + }) + .set("logSkill", ["feidan", targets]); + "step 1"; + if (result.bool) { event.targets.sort(lib.sort.seat); - } - else{ + } else { event.finish(); } - "step 2" - if(event.targets.length){ + "step 2"; + if (event.targets.length) { event.targets.shift().damage(); event.redo(); } }, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'){ - if(get.distance(player,target)<=1) return false; + mod: { + targetInRange: function (card, player, target) { + if (card.name == "sha") { + if (get.distance(player, target) <= 1) return false; return true; } - } - } + }, + }, }, - yuedong:{ - trigger:{player:'phaseUseEnd'}, - direct:true, - content:function(){ - 'step 0' - var num=1+player.storage.yuedong_num; - player.chooseTarget(get.prompt('yuedong'),[1,num],function(card,player,target){ - if(player.storage.yuedong_recover){ - return target.hp1) return att/5; - if(num2==1){ - if(num>1) return att/3; - return att/4; + yuedong: { + trigger: { player: "phaseUseEnd" }, + direct: true, + content: function () { + "step 0"; + var num = 1 + player.storage.yuedong_num; + player + .chooseTarget(get.prompt("yuedong"), [1, num], function (card, player, target) { + if (player.storage.yuedong_recover) { + return target.hp < target.maxHp; } - return att*1.1; - } - return att; - }); - 'step 1' - if(result.bool){ - player.logSkill('yuedong',result.targets); - var eff=1+player.storage.yuedong_eff; - if(player.storage.yuedong_recover){ + return true; + }) + .set("ai", function (target) { + if (player.storage.yuedong_recover) { + return get.recoverEffect(target, player, player); + } + var att = get.attitude(player, target) / Math.sqrt(2 + target.countCards("h")); + if (player == target) { + var num2 = player.needsToDiscard(num); + if (num2 > 1) return att / 5; + if (num2 == 1) { + if (num > 1) return att / 3; + return att / 4; + } + return att * 1.1; + } + return att; + }); + "step 1"; + if (result.bool) { + player.logSkill("yuedong", result.targets); + var eff = 1 + player.storage.yuedong_eff; + if (player.storage.yuedong_recover) { result.targets.sort(lib.sort.seat); - for(var i=0;i1&&!player.storage.yuedong_recover; + huhuan: { + enable: "phaseUse", + filterCard: true, + selectCard: 2, + position: "he", + filter: function (event, player) { + return player.countCards("he") > 1 && !player.storage.yuedong_recover; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - player.storage.yuedong_recover=true; + content: function () { + player.storage.yuedong_recover = true; }, - ai:{ - order:10.2, - result:{ - player:function(player){ - var num1=0,num2=0,players=game.filterPlayer(); - for(var i=0;i0){ + ai: { + order: 10.2, + result: { + player: function (player) { + var num1 = 0, + num2 = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) { num2++; - if(players[i].hp<=2&&players[i].maxHp>2){ + if (players[i].hp <= 2 && players[i].maxHp > 2) { num1++; - if(players[i].hp==1){ + if (players[i].hp == 1) { num1++; } } } } - if(num1>=3){ + if (num1 >= 3) { return 1; } return 0; - } - } - } + }, + }, + }, }, - kuoyin:{ - enable:'phaseUse', - filterCard:true, - selectCard:function(){ - if(get.is.altered('kuoyin')) return 1; - if(_status.event.player.storage.yuedong_eff) return 1; - if(_status.event.player.storage.yuedong_num) return 2; - return [1,2]; + kuoyin: { + enable: "phaseUse", + filterCard: true, + selectCard: function () { + if (get.is.altered("kuoyin")) return 1; + if (_status.event.player.storage.yuedong_eff) return 1; + if (_status.event.player.storage.yuedong_num) return 2; + return [1, 2]; }, - position:'he', + position: "he", // alter:true, - filter:function(event,player){ - if(get.is.altered('kuoyin')&&player.storage.yuedong_num) return false; - if(player.storage.yuedong_eff&&player.storage.yuedong_num) return false; - return player.countCards('he')>0; + filter: function (event, player) { + if (get.is.altered("kuoyin") && player.storage.yuedong_num) return false; + if (player.storage.yuedong_eff && player.storage.yuedong_num) return false; + return player.countCards("he") > 0; }, - check:function(card){ - var player=_status.event.player; - var num1=0,num2=0,players=game.filterPlayer(); - for(var i=0;i0){ + check: function (card) { + var player = _status.event.player; + var num1 = 0, + num2 = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) { num2++; - if(players[i].hp<=2&&players[i].maxHp>2){ + if (players[i].hp <= 2 && players[i].maxHp > 2) { num1++; } } } - if(player.storage.yuedong_recover){ - if(num1>1&&!player.storage.yuedong_num){ - if(ui.selected.cards.length) return 0; - return 7-get.value(card); + if (player.storage.yuedong_recover) { + if (num1 > 1 && !player.storage.yuedong_num) { + if (ui.selected.cards.length) return 0; + return 7 - get.value(card); } return 0; - } - else{ - if(num2>1&&!player.storage.yuedong_num){ - if(ui.selected.cards.length) return 0; - return 7-get.value(card); + } else { + if (num2 > 1 && !player.storage.yuedong_num) { + if (ui.selected.cards.length) return 0; + return 7 - get.value(card); } - if(num2>2){ - return 6-get.value(card); + if (num2 > 2) { + return 6 - get.value(card); } - return 5-get.value(card); + return 5 - get.value(card); } }, - content:function(){ - if(cards.length==1){ - player.storage.yuedong_num+=2; - } - else{ + content: function () { + if (cards.length == 1) { + player.storage.yuedong_num += 2; + } else { player.storage.yuedong_eff++; } }, - ai:{ - threaten:1.6, - order:10.1, - result:{ - player:1 - } - }, - group:'kuoyin2' - }, - kuoyin2:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - player.storage.yuedong_recover=false; - player.storage.yuedong_num=0; - player.storage.yuedong_eff=0; - } - }, - guangshu:{ - enable:'phaseUse', - check:function(card){ - var player=_status.event.player; - var suit=get.suit(card); - if(suit=='heart'){ - if(game.hasPlayer(function(current){ - return current.hp==1&&get.attitude(player,current)>0 - })); - } - else if(suit=='spade'){ - return 7-get.value(card); - } - return 6-get.value(card); - }, - filter:function(event,player){ - return player.countCards('he')>0; - }, - filterTarget:function(card,player,target){ - return !target.hasSkill('guangshu_heart')&& - !target.hasSkill('guangshu_spade')&& - !target.hasSkill('guangshu_club')&& - !target.hasSkill('guangshu_diamond'); - }, - filterCard:true, - position:'he', - content:function(){ - target.addSkill('guangshu_'+get.suit(cards[0])); - }, - ai:{ - expose:0.2, - threaten:1.6, - order:5, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - switch(get.suit(ui.selected.cards[0])){ - case 'heart':if(target.hp==1) return 1;return 0.1; - case 'diamond':return 1+Math.sqrt(target.countCards('h')); - case 'club':return -target.countCards('h')-Math.sqrt(target.countCards('h','sha')); - case 'spade':return get.damageEffect(target,player,target,'thunder'); - default:return 0; - } - } - } - } - }, - guangshu_diamond:{ - mark:true, - intro:{ - content:'下次造成伤害时摸两张牌' - }, - trigger:{source:'damageEnd'}, - forced:true, - content:function(){ - player.draw(2); - player.removeSkill('guangshu_diamond'); - } - }, - guangshu_heart:{ - mark:true, - intro:{ - content:'下次受到伤害时回复1点体力' - }, - trigger:{player:'damageEnd'}, - priority:6, - forced:true, - content:function(){ - player.recover(); - player.removeSkill('guangshu_heart'); - } - }, - guangshu_club:{ - mark:true, - intro:{ - content:'无法使用杀直到下一回合结束' - }, - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('guangshu_club'); - }, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; - } - } - }, - guangshu_spade:{ - mark:true, - intro:{ - content:'下个结束阶段受到1点无来源的雷电伤害' - }, - trigger:{player:'phaseEnd'}, - forced:true, - content:function(){ - player.damage('thunder','nosource'); - player.removeSkill('guangshu_spade'); - } - }, - ziyu:{ - trigger:{global:'phaseEnd'}, - direct:true, - filter:function(event,player){ - if(get.is.altered('ziyu')) return game.phaseNumber%6==0; - return game.phaseNumber%4==0; - }, - // alter:true, - content:function(){ - player.chooseDrawRecover(get.prompt('ziyu')).logSkill='ziyu'; - } - }, - shouhu:{ - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + ai: { + threaten: 1.6, + order: 10.1, + result: { + player: 1, }, }, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h','sha')>0; - }, - filterTarget:function(card,player,target){ - return target.hpplayer.hp&&player.countCards('h','lebu')==0)||get.distance(player,event.player)>1); + }, + guangshu: { + enable: "phaseUse", + check: function (card) { + var player = _status.event.player; + var suit = get.suit(card); + if (suit == "heart") { + if ( + game.hasPlayer(function (current) { + return current.hp == 1 && get.attitude(player, current) > 0; + }) + ); + } else if (suit == "spade") { + return 7 - get.value(card); + } + return 6 - get.value(card); + }, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + filterTarget: function (card, player, target) { + return ( + !target.hasSkill("guangshu_heart") && + !target.hasSkill("guangshu_spade") && + !target.hasSkill("guangshu_club") && + !target.hasSkill("guangshu_diamond") + ); + }, + filterCard: true, + position: "he", + content: function () { + target.addSkill("guangshu_" + get.suit(cards[0])); + }, + ai: { + expose: 0.2, + threaten: 1.6, + order: 5, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + switch (get.suit(ui.selected.cards[0])) { + case "heart": + if (target.hp == 1) return 1; + return 0.1; + case "diamond": + return 1 + Math.sqrt(target.countCards("h")); + case "club": + return -target.countCards("h") - Math.sqrt(target.countCards("h", "sha")); + case "spade": + return get.damageEffect(target, player, target, "thunder"); + default: + return 0; + } + }, + }, + }, + }, + guangshu_diamond: { + mark: true, + intro: { + content: "下次造成伤害时摸两张牌", + }, + trigger: { source: "damageEnd" }, + forced: true, + content: function () { + player.draw(2); + player.removeSkill("guangshu_diamond"); + }, + }, + guangshu_heart: { + mark: true, + intro: { + content: "下次受到伤害时回复1点体力", + }, + trigger: { player: "damageEnd" }, + priority: 6, + forced: true, + content: function () { + player.recover(); + player.removeSkill("guangshu_heart"); + }, + }, + guangshu_club: { + mark: true, + intro: { + content: "无法使用杀直到下一回合结束", + }, + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("guangshu_club"); + }, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, + }, + guangshu_spade: { + mark: true, + intro: { + content: "下个结束阶段受到1点无来源的雷电伤害", + }, + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { + player.damage("thunder", "nosource"); + player.removeSkill("guangshu_spade"); + }, + }, + ziyu: { + trigger: { global: "phaseEnd" }, + direct: true, + filter: function (event, player) { + if (get.is.altered("ziyu")) return game.phaseNumber % 6 == 0; + return game.phaseNumber % 4 == 0; }, // alter:true, - intro:{ - content:function(storage,player){ - var str=''; - if(player.storage.shanxian_h.length){ - if(player.isUnderControl(true)){ - str+='手牌区:'+get.translation(player.storage.shanxian_h); - } - else{ - str+='手牌区:'+(player.storage.shanxian_h.length)+'张牌'; + content: function () { + player.chooseDrawRecover(get.prompt("ziyu")).logSkill = "ziyu"; + }, + }, + shouhu: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", "sha") > 0; + }, + filterTarget: function (card, player, target) { + return target.hp < target.maxHp && target != player; + }, + content: function () { + target.recover(); + }, + filterCard: { name: "sha" }, + ai: { + order: 7, + threaten: 2, + result: { + target: function (player, target) { + return get.recoverEffect(target, player, target); + }, + }, + }, + }, + shanxian: { + trigger: { global: "phaseBefore" }, + filter: function (event, player) { + return event.player != player && !player.isTurnedOver() && !player.storage.shanxian; + }, + check: function (event, player) { + return ( + get.attitude(player, event.player) < 0 && + ((player.countCards("h") > player.hp && player.countCards("h", "lebu") == 0) || + get.distance(player, event.player) > 1) + ); + }, + // alter:true, + intro: { + content: function (storage, player) { + var str = ""; + if (player.storage.shanxian_h.length) { + if (player.isUnderControl(true)) { + str += "手牌区:" + get.translation(player.storage.shanxian_h); + } else { + str += "手牌区:" + player.storage.shanxian_h.length + "张牌"; } } - if(player.storage.shanxian_e.length){ - if(str.length) str+='、'; - if(player.isUnderControl(true)){ - str+='装备区:'+get.translation(player.storage.shanxian_e); - } - else{ - str+='装备区:'+(player.storage.shanxian_e.length)+'张牌'; + if (player.storage.shanxian_e.length) { + if (str.length) str += "、"; + if (player.isUnderControl(true)) { + str += "装备区:" + get.translation(player.storage.shanxian_e); + } else { + str += "装备区:" + player.storage.shanxian_e.length + "张牌"; } } return str; }, - mark:function(dialog,content,player){ - if(player.storage.shanxian_h.length){ - if(player.isUnderControl(true)){ + mark: function (dialog, content, player) { + if (player.storage.shanxian_h.length) { + if (player.isUnderControl(true)) { dialog.add('
              手牌区
              '); dialog.addSmall(player.storage.shanxian_h); - } - else{ - dialog.add('
              手牌区:'+player.storage.shanxian_h.length+'张牌
              '); + } else { + dialog.add( + '
              手牌区:' + + player.storage.shanxian_h.length + + "张牌
              " + ); } } - if(player.storage.shanxian_e.length){ - if(player.isUnderControl(true)){ + if (player.storage.shanxian_e.length) { + if (player.isUnderControl(true)) { dialog.add('
              装备区
              '); dialog.addSmall(player.storage.shanxian_e); - } - else{ - dialog.add('
              装备区:'+player.storage.shanxian_e.length+'张牌
              '); + } else { + dialog.add( + '
              装备区:' + + player.storage.shanxian_e.length + + "张牌
              " + ); } } }, }, - logTarget:'player', - content:function(){ - "step 0" - if(!get.is.altered('shanxian')){ + logTarget: "player", + content: function () { + "step 0"; + if (!get.is.altered("shanxian")) { player.draw(false); player.$draw(); } - "step 1" - player.storage.shanxian_h=player.getCards('h'); - player.storage.shanxian_e=player.getCards('e'); - player.storage.shanxian_n=1; - player.syncStorage('shanxian_e'); - player.phase('shanxian'); - player.storage.shanxian=trigger.player; - player.removeSkill('shanxian2'); - player.markSkill('shanxian'); - "step 2" + "step 1"; + player.storage.shanxian_h = player.getCards("h"); + player.storage.shanxian_e = player.getCards("e"); + player.storage.shanxian_n = 1; + player.syncStorage("shanxian_e"); + player.phase("shanxian"); + player.storage.shanxian = trigger.player; + player.removeSkill("shanxian2"); + player.markSkill("shanxian"); + "step 2"; player.turnOver(true); delete player.storage.shanxian; }, - mod:{ - targetInRange:function(card,player,target,now){ - if(target==player.storage.shanxian) return true; + mod: { + targetInRange: function (card, player, target, now) { + if (target == player.storage.shanxian) return true; }, }, - ai:{ - expose:0.1, - effect:{ - target:function(card){ - if(card.name=='guiyoujie') return [0,0]; - } - } - } - }, - shanxian2:{ - trigger:{player:['gainBegin','loseBegin']}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('shanxian2'); - } - }, - shanhui:{ - unique:true, - trigger:{player:'damageEnd',source:'damageEnd'}, - filter:function(event,player){ - return player.storage.shanxian_h&&player.storage.shanxian_e&& - player.storage.shanxian_n>0&&!player.hasSkill('shanxian2'); + ai: { + expose: 0.1, + effect: { + target: function (card) { + if (card.name == "guiyoujie") return [0, 0]; + }, + }, }, - check:function(event,player){ - var n1=player.countCards('he'); - var n2=player.storage.shanxian_h.length+player.storage.shanxian_e.length; - if(n1 0 && + !player.hasSkill("shanxian2") + ); + }, + check: function (event, player) { + var n1 = player.countCards("he"); + var n2 = player.storage.shanxian_h.length + player.storage.shanxian_e.length; + if (n1 < n2) return true; + if (player.hp == player.maxHp) return false; + if (n1 == n2 + 1) return true; + if (n2 == n2 + 2 && player.hp <= 1) return true; return false; }, - video:function(player){ - var cards=player.getCards('he'); - for(var i=0;iplayer.storage.shanxian_h.length+player.storage.shanxian_e.length){ + if (cards.length > player.storage.shanxian_h.length + player.storage.shanxian_e.length) { player.recover(); } player.storage.shanxian_n--; - if(player.storage.shanxian_n<=0){ + if (player.storage.shanxian_n <= 0) { delete player.storage.shanxian_h; delete player.storage.shanxian_e; delete player.storage.shanxian_n; - player.unmarkSkill('shanxian'); + player.unmarkSkill("shanxian"); + } else { + player.addSkill("shanxian2"); } - else{ - player.addSkill('shanxian2'); - } - } - } + }, + }, + }, + translate: { + woliu: "涡流", + woliu2: "涡流", + woliu_info: + "结束阶段,你可以选择至多两名角色,当你或目标中的任意一名角色成为杀的目标时,其余角色也将被追加为目标,直到你死亡或下一回合开始。", + qianggu: "强固", + qianggu_info: + "出牌阶段限一次,你可以弃置两张牌并获得2点护甲,若如此做,直到你的下个回合开始,其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效。", + qianggu2: "强固", + qianggu2_bg: "固", + qianggu2_info: "其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效。", + pingzhang: "屏障", + pingzhang_info: + "每轮各限一次,当你受到伤害时,你可以弃置一张红桃牌令伤害-1;当一名其他角色受到伤害时,你可以弃置一张黑桃牌令伤害-1。", + pingzhang_info_alter: + "每轮各限一次,当你受到伤害时,你可以弃置一张红桃手牌令伤害-1;当一名其他角色受到伤害时,你可以弃置一张黑桃手牌令伤害-1。", + owliyong: "力涌", + owliyong_info: "锁定技,你摸牌阶段摸牌数+X,X为你上一轮发动屏障的次数。", + dianji: "电击", + dianji_info: "出牌阶段限一次,你可以将一张手牌当作惊雷闪对距离2以内的角色使用。", + feitiao: "飞跳", + feitiao2: "飞跳", + feitiao_info: + "出牌阶段开始时,你可以弃置一张牌并指定一名角色,你与该角色的距离视为1直到回合结束,然后该角色随机弃置一张牌。", + bshaowei: "哨卫", + bshaowei_info: + "结束阶段,你可以切换至哨卫模式。当处于此模式时,你的杀无视距离和防具、无数量限制且不可闪避;你不能闪避杀。", + zhencha: "侦查", + zhencha_info: + "结束阶段,你可以切换至侦查模式。当处于此模式时,每当你使用一张杀,你摸一张牌或回复1点体力。", + liangou: "链钩", + liangou_info: + "出牌阶段限一次,你可以弃置一张牌,指定一名其他角色并进行一次判定,若结果不为红桃,该角色与你距离为1且受到的首次伤害+1直到回合结束。", + xiyang: "吸氧", + xiyang_info: "结束阶段,若你武将牌正面朝上,你可以翻面并回复2点体力。", + qinru: "侵入", + qinru_info: + "每当你使用杀指定目标时,你可以令其进行一次判定,若结果不为红桃,该角色的非锁定技失效直到其下一回合结束。", + yinshen: "隐身", + yinshen_info: "锁定技,每当你失去最后一张基本牌,你获得潜行直到下一回合开始。", + yinshen_info_old: "结束阶段,你可以弃置一张装备牌并获得潜行直到下一回合开始。", + maichong: "脉冲", + maichong_info: + "锁定技,每当你使用一张普通锦囊牌,你令最近三回合内被你侵入过的角色各随机弃置一张牌。", + maichong_info_alter: "准备阶段,你可以令最近两名被你侵入的角色各随机弃置一张牌。", + lichang: "力场", + lichang2: "力场", + lichang_info: + "结束阶段,你可以弃置一张红色牌,若如此做,你可以在下个准备阶段令一名距离1以内的角色回复1点体力或摸两张牌。", + mengji: "猛击", + mengji_info: "锁定技,若你已发动重盾,当你没有护甲时,你的杀造成的伤害+1。", + zhongdun: "重盾", + zhongdun_info: + "游戏开始时,你获得8点护甲;出牌阶段限一次,你可以弃置一张牌并将1点护甲分给一名没有护甲的其他角色。", + zhongdun_info_alter: + "游戏开始时,你获得6点护甲;出牌阶段限一次,你可以弃置一张牌并将1点护甲分给一名没有护甲的其他角色。", + paotai: "炮台", + paotai2: "炮台", + paotai_info: + "出牌阶段,你可以弃置一张杀布置或升级一个炮台(最高3级);结束阶段,炮台有一定机率对一名随机敌人造成1点火焰伤害;每当你受到1点伤害,炮台降低一级。", + maoding: "铆钉", + maoding2: "铆钉", + maoding_info: + "每当你造成或受到一次伤害,你可以获得一个零件;出牌阶段,你可以弃置两张零件牌令一名没有护甲的角色获得1点护甲。", + maoding_info_alter: + "每当你造成一次伤害,你可以获得一个零件;出牌阶段,你可以弃置两张零件牌令一名没有护甲的角色获得1点护甲。", + bfengshi: "风矢", + bfengshi2: "风矢", + bfengshi_info: + "锁定技,在一合内每当你使用一张牌,你的攻击范围+1;你的首张杀增加20%的概率强制命中;你的首张杀造成伤害后增加20%的概率令伤害+1。", + bfengshi_info_alter: + "锁定技,在一合内每当你使用一张牌,你的攻击范围+1;你的首张杀增加15%的概率强制命中;你的首张杀造成伤害后增加15%的概率令伤害+1。", + yinbo: "音波", + yinbo_info: "出牌阶段限一次,你可以弃置一张黑桃牌,然后随机弃置三名敌人各一张牌。", + liudan: "榴弹", + liudan_info: "每当你使用一张杀,你可以令所有不是此杀目标的其他角色有50%概率成为此杀的额外目标。", + shoujia: "兽夹", + shoujia2: "兽夹", + shoujia3: "兽夹", + shoujia_info: + "出牌阶段限一次,你可以将一张牌背面朝上置于一名其他角色的武将牌上,当该角色使用一张与此牌花色相同的牌指定其他角色为目标时,移去此牌,该角色将武将牌翻至背面;当你受到伤害时,移去此牌。", + shihuo: "嗜火", + shihuo_info: "锁定技,每当一名角色受到火焰伤害,你摸一张牌。", + shanguang: "闪光", + shanguang_info: + "出牌阶段限一次,你可以弃置一张方片牌令攻击范围内的一名其他角色本回合内不能使用或打出卡牌。", + tiandan: "填弹", + tiandan_info: + "摸牌阶段开始时,你可以跳过出牌和弃牌阶段,然后获得若干张杀直到你的手牌数等于你的体值(最多为5)。", + shenqiang: "神枪", + shenqiang_info: "锁定技,每当你在出牌阶段使用杀造成伤害,本阶段内出杀次数上限+1。", + mianzhen: "眠针", + mianzhen2: "眠针", + mianzhen_info: + "出牌阶段限一次,你可以弃置一张牌并令一名其他角色打出一张闪,否则该角色不能使用或打出卡牌直到其受到伤害或下一回合结束。", + aqianghua: "强化", + aqianghua2: "强化", + aqianghua_info: + "出牌阶段限一次,你可以将你的全部手牌(至少一张)交给一名其他角色,该角色获得1点护甲且下一次造成的伤害+1。", + aqianghua_info_alter: + "出牌阶段限一次,你可以将你的全部手牌(至少一张)交给一名其他角色,该角色下一次造成的伤害+1。", + zhiyuan: "支援", + zhiyuan_info: "每当你即将造成伤害,你可以防止此伤害,改为令目标回复等量的体力。", + juji: "狙击", + juji2: "狙击", + juji3: "狙击", + juji_info: + "出牌阶段限一次,你可以弃置任意张花色不同的牌并指定一名有手牌的其他角色,若该角色的手牌中含有与你弃置的牌花色相同的牌,则本回合内你与其距离为1且该角色不能闪避你的杀。", + duwen: "毒吻", + duwen2: "毒吻", + duwen_info: "锁定技,当你造成伤害时,若你的手牌数与受伤害角色相等,此伤害+1。", + zhuagou: "抓钩", + zhuagou_info: "出牌阶段限一次,你可以弃置一张手牌并将你的座位移到任意位置。", + dulei: "诡雷", + dulei2: "诡雷", + dulei_info: + "出牌阶段,若你武将牌上没有牌,你可以将一张牌背面朝上置于你的武将牌上,当一名角色使用与该牌花色相同的牌指定你为目标时,你展示并移去此牌,然后该角色失去1点体力并随机弃置一张牌。", + shuangqiang: "霜枪", + shuangqiang_info: "每当你对一名未翻面的角色造成伤害,你可以令伤害-1,然后令受伤害角色翻面。", + baoxue: "暴雪", + baoxue_info: + "限定技,出牌阶段,若你未翻面,你可以展示并弃置你的所有黑色牌,然后令至多X名其他角色随机弃置一张牌并将武将牌翻至背面,X为你的弃牌数;结算后你将武将牌翻至背面。", + baoxue_info_alter: + "限定技,出牌阶段,你可以展示并弃置你的所有黑色牌,并选择等量其他角色将武将牌翻至背面,结算后你将武将牌翻至背面。", + bingqiang: "冰墙", + bingqiang2: "冰墙", + bingqiang2_bg: "墙", + bingqiang3: "冰墙", + bingqiang3_bg: "墙", + bingqiang4: "冰墙", + bingqiang4_bg: "墙", + bingqiang5: "冰墙", + bingqiang5_bg: "障", + bingqiang_info: + "出牌阶段,你可以弃置X张红色牌令一名角色和其相邻角色的防御离+X,或弃置X张黑色牌令一名角色和其相邻角色的进攻离-X,效果持续到你的下个回合开始。", + jidong: "急冻", + jidong_info: + "在一名角色的结束阶段,若你的体力值为1且未翻面,你可以翻面并回复2点体力,在你的武将牌翻至正面前,你防止所有伤害,也不能成为其他角色卡牌的目标。", + jidong_info_alter: "在一名角色的结束阶段,若你的体力值为1,你可以翻面并回复2点体力。", + jijia: "机甲", + jijia_info: + "锁定技,游戏开始时,你获得一个体力为4的机甲;你的手牌上限为你和机甲的体力之和;你受到的伤害由机甲承担。", + zihui: "自毁", + zihui_info: + "出牌阶段,你可以令距离2以内的所有其他角色选择一项:弃置数量等同你机甲体力值的牌,或受到2点火焰伤害,并在结算完毕后摧毁你的机甲。", + zihui_info_alter: + "出牌阶段,你可以令距离2以内的所有其他角色选择一项:1. 弃置数量等同你机甲体力值的牌(不足则全弃,至少弃1张);2. 或受到2点火焰伤害,并在结算完毕后摧毁你的机甲。", + tuijin: "推进", + tuijin2: "推进", + tuijin_info: "出牌阶段限一次,若你有机甲,你可以指定一名角色,本回合内视为与其距离为1。", + chongzhuang: "重装", + chongzhuang_info: "在你失去机甲后,当你累计造成了4点伤害时,你重新获得机甲。", + shouge: "收割", + shouge_info: "每当你杀死一名角色,你可以获得一张治疗波。", + tuji: "突击", + tuji_info: "锁定技,在你的回合内,每当你使用一张牌,你的进攻距离+1。", + mujing: "目镜", + mujing2: "目镜", + mujing_info: "你可以将一张黑色牌当作杀使用或打出;当你的杀被闪避后,此杀不计入出杀次数。", + mujing_old_info: + "每当你对攻击范围不含你的角色使用一张牌,你可以弃置目标一张牌;若你的手牌数不多于目标,你摸一张牌。", + feiren: "飞刃", + feiren2: "飞刃", + feiren_info: "你的杀无视距离;你的黑桃杀造成的伤害+1,梅花杀可以额外指定一个目标。", + feiren_info_alter: "你的杀无视距离;你的梅花杀可以额外指定一个目标。", + zhanlong: "斩龙", + zhanlong_info: + "限定技,准备阶段,若你体力值为1,你可以弃置所有牌(至少一张),然后将三张杀置入你的手牌,若如此做,你本回合使用杀无次数限制。", + xie: "谐", + xie2: "谐", + xie_info: + "出牌阶段,你可以弃置一张红桃手牌并指定一名角色,该角色自其下一回合开始每隔六回合回复1点体力,直到你死亡。同一时间只能对一人发动。", + luan: "乱", + luan2: "乱", + luan_old_info: + "出牌阶段,你可以弃置一张黑桃手牌并指定一名角色,该角色自其下一回合开始每隔六回合失去1点体力,直到你死亡。同一时间只能对一人发动。", + luan_info: + "出牌阶段,你可以弃置一张黑桃手牌并指定一名角色,该角色受到伤害后失去1点体力,直到你死亡或其首次进入濒死状态。同一时间只能对一人发动。", + sheng: "圣", + sheng_info: + "限定技,出牌阶段,你可以将你的武将牌翻面,然后令任意名角色回复1点体力,若如此做,你不能成为其他角色的卡牌目标直到下一回合开始。", + xiandan: "霰弹", + xiandan_info: + "每当你使用一张杀,你可以弃置一张红色牌令此杀不可闪避,或弃置一张黑色牌令此杀伤害+1。", + yihun: "移魂", + yihun_info: + "结束阶段,你可以弃置一张黑色牌并指定一名其他角色,你在该角色下一准备阶段视为对其使用一张杀;在此之前,你不能使用卡牌,也不能成为卡牌的目标。", + feidan: "飞弹", + feidan_info: + "你的杀只能对距离1以外的角色使用;每当你使用杀造成伤害后,你可以弃置一张牌对距离目标1以内的其他角色各造成1点伤害。", + huoyu: "火雨", + huoyu_info: "限定技,出牌阶段,你可以弃置两张红色牌,视为使用两张炽羽袭。", + yuedong: "乐动", + yuedong_info: "出牌阶段结束时,你可以令一名角色摸一张牌。", + kuoyin: "扩音", + kuoyin_info: + "出牌阶段,你可以弃置一张牌令本回合乐动的目标数改为3,或弃置两张牌令本回合乐动的摸牌量改为2。", + kuoyin_info_alter: "出牌阶段,你可以弃置一张牌令本回合乐动的目标数改为3。", + huhuan: "互换", + huhuan_info: "出牌阶段,你可以弃置两张牌令本回合乐动的摸牌效果改为回复等量体力。", + guangshu: "光枢", + guangshu_heart: "光盾", + guangshu_spade: "光塔", + guangshu_club: "光井", + guangshu_diamond: "光流", + guangshu_info: + "出牌阶段,你可以弃置一张牌,并指定一名角色,根据弃置牌的花色执行如下效果:♥该角色下次受到伤害时回复1点体力;♦︎该角色下次造成伤害时摸两张牌;♣该角色无法使用杀直到下一回合结束;♠该角色于下个结束阶段受到1点无来源的雷电伤害。", + ziyu: "自愈", + ziyu_info: "在一名角色的结束阶段,你可以回复1点体力或摸一张牌,每隔四回合发动一次。", + ziyu_info_alter: "在一名角色的结束阶段,你可以回复1点体力或摸一张牌,每隔六回合发动一次。", + shouhu: "守护", + shouhu_info: "你不能使用杀;出牌阶段,你可以弃置一张杀令一名其他角色回复1点体力。", + shanxian: "闪现", + shanxian_info: + "在一名其他角色的回合开始前,若你的武将牌正面朝上,你可以摸一张牌并进行一个额外回合,并在回合结束后将武将牌翻至背面。若如此做,你对其使用卡牌无视距离直到回合结束。", + shanxian_info_alter: + "在一名其他角色的回合开始前,若你的武将牌正面朝上,你可以进行一个额外回合,并在回合结束后将武将牌翻至背面。若如此做,你对其使用卡牌无视距离直到回合结束。", + shanhui: "闪回", + shanhui_info: + "当你造成或受到伤害后,你可以将你的牌重置为上次发动闪现时的状态,若你的牌数因此而减少,你回复1点体力。", + ow_liekong: "猎空", + ow_sishen: "死神", + ow_tianshi: "天使", + ow_falaozhiying: "法老之鹰", + ow_zhixuzhiguang: "秩序之光", + ow_luxiao: "卢西奥", + ow_shibing: "士兵76", + ow_yuanshi: "源氏", + ow_chanyata: "禅雅塔", + ow_dva: "DVA", + ow_mei: "小美", + ow_heibaihe: "黑百合", + ow_ana: "安娜", + ow_baolei: "堡垒", + ow_maikelei: "麦克雷", + ow_banzang: "半藏", + ow_kuangshu: "狂鼠", + ow_tuobiang: "托比昂", + ow_laiyinhate: "莱因哈特", + ow_luba: "路霸", + ow_wensidun: "温斯顿", + ow_zhaliya: "查莉娅", + ow_heiying: "黑影", + ow_orisa: "奥丽莎", }, - translate:{ - woliu:'涡流', - woliu2:'涡流', - woliu_info:'结束阶段,你可以选择至多两名角色,当你或目标中的任意一名角色成为杀的目标时,其余角色也将被追加为目标,直到你死亡或下一回合开始。', - qianggu:'强固', - qianggu_info:'出牌阶段限一次,你可以弃置两张牌并获得2点护甲,若如此做,直到你的下个回合开始,其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效。', - qianggu2:'强固', - qianggu2_bg:'固', - qianggu2_info:'其他角色对你使用杀时需要弃置一张基本牌,否则杀对你无效。', - pingzhang:'屏障', - pingzhang_info:'每轮各限一次,当你受到伤害时,你可以弃置一张红桃牌令伤害-1;当一名其他角色受到伤害时,你可以弃置一张黑桃牌令伤害-1。', - pingzhang_info_alter:'每轮各限一次,当你受到伤害时,你可以弃置一张红桃手牌令伤害-1;当一名其他角色受到伤害时,你可以弃置一张黑桃手牌令伤害-1。', - owliyong:'力涌', - owliyong_info:'锁定技,你摸牌阶段摸牌数+X,X为你上一轮发动屏障的次数。', - dianji:'电击', - dianji_info:'出牌阶段限一次,你可以将一张手牌当作惊雷闪对距离2以内的角色使用。', - feitiao:'飞跳', - feitiao2:'飞跳', - feitiao_info:'出牌阶段开始时,你可以弃置一张牌并指定一名角色,你与该角色的距离视为1直到回合结束,然后该角色随机弃置一张牌。', - bshaowei:'哨卫', - bshaowei_info:'结束阶段,你可以切换至哨卫模式。当处于此模式时,你的杀无视距离和防具、无数量限制且不可闪避;你不能闪避杀。', - zhencha:'侦查', - zhencha_info:'结束阶段,你可以切换至侦查模式。当处于此模式时,每当你使用一张杀,你摸一张牌或回复1点体力。', - liangou:'链钩', - liangou_info:'出牌阶段限一次,你可以弃置一张牌,指定一名其他角色并进行一次判定,若结果不为红桃,该角色与你距离为1且受到的首次伤害+1直到回合结束。', - xiyang:'吸氧', - xiyang_info:'结束阶段,若你武将牌正面朝上,你可以翻面并回复2点体力。', - qinru:'侵入', - qinru_info:'每当你使用杀指定目标时,你可以令其进行一次判定,若结果不为红桃,该角色的非锁定技失效直到其下一回合结束。', - yinshen:'隐身', - yinshen_info:'锁定技,每当你失去最后一张基本牌,你获得潜行直到下一回合开始。', - yinshen_info_old:'结束阶段,你可以弃置一张装备牌并获得潜行直到下一回合开始。', - maichong:'脉冲', - maichong_info:'锁定技,每当你使用一张普通锦囊牌,你令最近三回合内被你侵入过的角色各随机弃置一张牌。', - maichong_info_alter:'准备阶段,你可以令最近两名被你侵入的角色各随机弃置一张牌。', - lichang:'力场', - lichang2:'力场', - lichang_info:'结束阶段,你可以弃置一张红色牌,若如此做,你可以在下个准备阶段令一名距离1以内的角色回复1点体力或摸两张牌。', - mengji:'猛击', - mengji_info:'锁定技,若你已发动重盾,当你没有护甲时,你的杀造成的伤害+1。', - zhongdun:'重盾', - zhongdun_info:'游戏开始时,你获得8点护甲;出牌阶段限一次,你可以弃置一张牌并将1点护甲分给一名没有护甲的其他角色。', - zhongdun_info_alter:'游戏开始时,你获得6点护甲;出牌阶段限一次,你可以弃置一张牌并将1点护甲分给一名没有护甲的其他角色。', - paotai:'炮台', - paotai2:'炮台', - paotai_info:'出牌阶段,你可以弃置一张杀布置或升级一个炮台(最高3级);结束阶段,炮台有一定机率对一名随机敌人造成1点火焰伤害;每当你受到1点伤害,炮台降低一级。', - maoding:'铆钉', - maoding2:'铆钉', - maoding_info:'每当你造成或受到一次伤害,你可以获得一个零件;出牌阶段,你可以弃置两张零件牌令一名没有护甲的角色获得1点护甲。', - maoding_info_alter:'每当你造成一次伤害,你可以获得一个零件;出牌阶段,你可以弃置两张零件牌令一名没有护甲的角色获得1点护甲。', - bfengshi:'风矢', - bfengshi2:'风矢', - bfengshi_info:'锁定技,在一合内每当你使用一张牌,你的攻击范围+1;你的首张杀增加20%的概率强制命中;你的首张杀造成伤害后增加20%的概率令伤害+1。', - bfengshi_info_alter:'锁定技,在一合内每当你使用一张牌,你的攻击范围+1;你的首张杀增加15%的概率强制命中;你的首张杀造成伤害后增加15%的概率令伤害+1。', - yinbo:'音波', - yinbo_info:'出牌阶段限一次,你可以弃置一张黑桃牌,然后随机弃置三名敌人各一张牌。', - liudan:'榴弹', - liudan_info:'每当你使用一张杀,你可以令所有不是此杀目标的其他角色有50%概率成为此杀的额外目标。', - shoujia:'兽夹', - shoujia2:'兽夹', - shoujia3:'兽夹', - shoujia_info:'出牌阶段限一次,你可以将一张牌背面朝上置于一名其他角色的武将牌上,当该角色使用一张与此牌花色相同的牌指定其他角色为目标时,移去此牌,该角色将武将牌翻至背面;当你受到伤害时,移去此牌。', - shihuo:'嗜火', - shihuo_info:'锁定技,每当一名角色受到火焰伤害,你摸一张牌。', - shanguang:'闪光', - shanguang_info:'出牌阶段限一次,你可以弃置一张方片牌令攻击范围内的一名其他角色本回合内不能使用或打出卡牌。', - tiandan:'填弹', - tiandan_info:'摸牌阶段开始时,你可以跳过出牌和弃牌阶段,然后获得若干张杀直到你的手牌数等于你的体值(最多为5)。', - shenqiang:'神枪', - shenqiang_info:'锁定技,每当你在出牌阶段使用杀造成伤害,本阶段内出杀次数上限+1。', - mianzhen:'眠针', - mianzhen2:'眠针', - mianzhen_info:'出牌阶段限一次,你可以弃置一张牌并令一名其他角色打出一张闪,否则该角色不能使用或打出卡牌直到其受到伤害或下一回合结束。', - aqianghua:'强化', - aqianghua2:'强化', - aqianghua_info:'出牌阶段限一次,你可以将你的全部手牌(至少一张)交给一名其他角色,该角色获得1点护甲且下一次造成的伤害+1。', - aqianghua_info_alter:'出牌阶段限一次,你可以将你的全部手牌(至少一张)交给一名其他角色,该角色下一次造成的伤害+1。', - zhiyuan:'支援', - zhiyuan_info:'每当你即将造成伤害,你可以防止此伤害,改为令目标回复等量的体力。', - juji:'狙击', - juji2:'狙击', - juji3:'狙击', - juji_info:'出牌阶段限一次,你可以弃置任意张花色不同的牌并指定一名有手牌的其他角色,若该角色的手牌中含有与你弃置的牌花色相同的牌,则本回合内你与其距离为1且该角色不能闪避你的杀。', - duwen:'毒吻', - duwen2:'毒吻', - duwen_info:'锁定技,当你造成伤害时,若你的手牌数与受伤害角色相等,此伤害+1。', - zhuagou:'抓钩', - zhuagou_info:'出牌阶段限一次,你可以弃置一张手牌并将你的座位移到任意位置。', - dulei:'诡雷', - dulei2:'诡雷', - dulei_info:'出牌阶段,若你武将牌上没有牌,你可以将一张牌背面朝上置于你的武将牌上,当一名角色使用与该牌花色相同的牌指定你为目标时,你展示并移去此牌,然后该角色失去1点体力并随机弃置一张牌。', - shuangqiang:'霜枪', - shuangqiang_info:'每当你对一名未翻面的角色造成伤害,你可以令伤害-1,然后令受伤害角色翻面。', - baoxue:'暴雪', - baoxue_info:'限定技,出牌阶段,若你未翻面,你可以展示并弃置你的所有黑色牌,然后令至多X名其他角色随机弃置一张牌并将武将牌翻至背面,X为你的弃牌数;结算后你将武将牌翻至背面。', - baoxue_info_alter:'限定技,出牌阶段,你可以展示并弃置你的所有黑色牌,并选择等量其他角色将武将牌翻至背面,结算后你将武将牌翻至背面。', - bingqiang:'冰墙', - bingqiang2:'冰墙', - bingqiang2_bg:'墙', - bingqiang3:'冰墙', - bingqiang3_bg:'墙', - bingqiang4:'冰墙', - bingqiang4_bg:'墙', - bingqiang5:'冰墙', - bingqiang5_bg:'障', - bingqiang_info:'出牌阶段,你可以弃置X张红色牌令一名角色和其相邻角色的防御离+X,或弃置X张黑色牌令一名角色和其相邻角色的进攻离-X,效果持续到你的下个回合开始。', - jidong:'急冻', - jidong_info:'在一名角色的结束阶段,若你的体力值为1且未翻面,你可以翻面并回复2点体力,在你的武将牌翻至正面前,你防止所有伤害,也不能成为其他角色卡牌的目标。', - jidong_info_alter:'在一名角色的结束阶段,若你的体力值为1,你可以翻面并回复2点体力。', - jijia:'机甲', - jijia_info:'锁定技,游戏开始时,你获得一个体力为4的机甲;你的手牌上限为你和机甲的体力之和;你受到的伤害由机甲承担。', - zihui:'自毁', - zihui_info:'出牌阶段,你可以令距离2以内的所有其他角色选择一项:弃置数量等同你机甲体力值的牌,或受到2点火焰伤害,并在结算完毕后摧毁你的机甲。', - zihui_info_alter:'出牌阶段,你可以令距离2以内的所有其他角色选择一项:1. 弃置数量等同你机甲体力值的牌(不足则全弃,至少弃1张);2. 或受到2点火焰伤害,并在结算完毕后摧毁你的机甲。', - tuijin:'推进', - tuijin2:'推进', - tuijin_info:'出牌阶段限一次,若你有机甲,你可以指定一名角色,本回合内视为与其距离为1。', - chongzhuang:'重装', - chongzhuang_info:'在你失去机甲后,当你累计造成了4点伤害时,你重新获得机甲。', - shouge:'收割', - shouge_info:'每当你杀死一名角色,你可以获得一张治疗波。', - tuji:'突击', - tuji_info:'锁定技,在你的回合内,每当你使用一张牌,你的进攻距离+1。', - mujing:'目镜', - mujing2:'目镜', - mujing_info:'你可以将一张黑色牌当作杀使用或打出;当你的杀被闪避后,此杀不计入出杀次数。', - mujing_old_info:'每当你对攻击范围不含你的角色使用一张牌,你可以弃置目标一张牌;若你的手牌数不多于目标,你摸一张牌。', - feiren:'飞刃', - feiren2:'飞刃', - feiren_info:'你的杀无视距离;你的黑桃杀造成的伤害+1,梅花杀可以额外指定一个目标。', - feiren_info_alter:'你的杀无视距离;你的梅花杀可以额外指定一个目标。', - zhanlong:'斩龙', - zhanlong_info:'限定技,准备阶段,若你体力值为1,你可以弃置所有牌(至少一张),然后将三张杀置入你的手牌,若如此做,你本回合使用杀无次数限制。', - xie:'谐', - xie2:'谐', - xie_info:'出牌阶段,你可以弃置一张红桃手牌并指定一名角色,该角色自其下一回合开始每隔六回合回复1点体力,直到你死亡。同一时间只能对一人发动。', - luan:'乱', - luan2:'乱', - luan_old_info:'出牌阶段,你可以弃置一张黑桃手牌并指定一名角色,该角色自其下一回合开始每隔六回合失去1点体力,直到你死亡。同一时间只能对一人发动。', - luan_info:'出牌阶段,你可以弃置一张黑桃手牌并指定一名角色,该角色受到伤害后失去1点体力,直到你死亡或其首次进入濒死状态。同一时间只能对一人发动。', - sheng:'圣', - sheng_info:'限定技,出牌阶段,你可以将你的武将牌翻面,然后令任意名角色回复1点体力,若如此做,你不能成为其他角色的卡牌目标直到下一回合开始。', - xiandan:'霰弹', - xiandan_info:'每当你使用一张杀,你可以弃置一张红色牌令此杀不可闪避,或弃置一张黑色牌令此杀伤害+1。', - yihun:'移魂', - yihun_info:'结束阶段,你可以弃置一张黑色牌并指定一名其他角色,你在该角色下一准备阶段视为对其使用一张杀;在此之前,你不能使用卡牌,也不能成为卡牌的目标。', - feidan:'飞弹', - feidan_info:'你的杀只能对距离1以外的角色使用;每当你使用杀造成伤害后,你可以弃置一张牌对距离目标1以内的其他角色各造成1点伤害。', - huoyu:'火雨', - huoyu_info:'限定技,出牌阶段,你可以弃置两张红色牌,视为使用两张炽羽袭。', - yuedong:'乐动', - yuedong_info:'出牌阶段结束时,你可以令一名角色摸一张牌。', - kuoyin:'扩音', - kuoyin_info:'出牌阶段,你可以弃置一张牌令本回合乐动的目标数改为3,或弃置两张牌令本回合乐动的摸牌量改为2。', - kuoyin_info_alter:'出牌阶段,你可以弃置一张牌令本回合乐动的目标数改为3。', - huhuan:'互换', - huhuan_info:'出牌阶段,你可以弃置两张牌令本回合乐动的摸牌效果改为回复等量体力。', - guangshu:'光枢', - guangshu_heart:'光盾', - guangshu_spade:'光塔', - guangshu_club:'光井', - guangshu_diamond:'光流', - guangshu_info:'出牌阶段,你可以弃置一张牌,并指定一名角色,根据弃置牌的花色执行如下效果:♥该角色下次受到伤害时回复1点体力;♦︎该角色下次造成伤害时摸两张牌;♣该角色无法使用杀直到下一回合结束;♠该角色于下个结束阶段受到1点无来源的雷电伤害。', - ziyu:'自愈', - ziyu_info:'在一名角色的结束阶段,你可以回复1点体力或摸一张牌,每隔四回合发动一次。', - ziyu_info_alter:'在一名角色的结束阶段,你可以回复1点体力或摸一张牌,每隔六回合发动一次。', - shouhu:'守护', - shouhu_info:'你不能使用杀;出牌阶段,你可以弃置一张杀令一名其他角色回复1点体力。', - shanxian:'闪现', - shanxian_info:'在一名其他角色的回合开始前,若你的武将牌正面朝上,你可以摸一张牌并进行一个额外回合,并在回合结束后将武将牌翻至背面。若如此做,你对其使用卡牌无视距离直到回合结束。', - shanxian_info_alter:'在一名其他角色的回合开始前,若你的武将牌正面朝上,你可以进行一个额外回合,并在回合结束后将武将牌翻至背面。若如此做,你对其使用卡牌无视距离直到回合结束。', - shanhui:'闪回', - shanhui_info:'当你造成或受到伤害后,你可以将你的牌重置为上次发动闪现时的状态,若你的牌数因此而减少,你回复1点体力。', - ow_liekong:'猎空', - ow_sishen:'死神', - ow_tianshi:'天使', - ow_falaozhiying:'法老之鹰', - ow_zhixuzhiguang:'秩序之光', - ow_luxiao:'卢西奥', - ow_shibing:'士兵76', - ow_yuanshi:'源氏', - ow_chanyata:'禅雅塔', - ow_dva:'DVA', - ow_mei:'小美', - ow_heibaihe:'黑百合', - ow_ana:'安娜', - ow_baolei:'堡垒', - ow_maikelei:'麦克雷', - ow_banzang:'半藏', - ow_kuangshu:'狂鼠', - ow_tuobiang:'托比昂', - ow_laiyinhate:'莱因哈特', - ow_luba:'路霸', - ow_wensidun:'温斯顿', - ow_zhaliya:'查莉娅', - ow_heiying:'黑影', - ow_orisa:'奥丽莎', - } }; }); diff --git a/character/rank.js b/character/rank.js index 390ef215b..3ad34972e 100644 --- a/character/rank.js +++ b/character/rank.js @@ -1,2736 +1,2750 @@ -window.noname_character_rank={ - s:[ - 'gjqt_bailitusu', - 'gjqt_beiluo', - 'gjqt_xieyi', - 'hs_malorne', - 'hs_medivh', - 'hs_sthrall', - 'pal_yuejinzhao', - 'swd_cheyun', - 'swd_duguningke', - 'swd_guyue', - 'swd_huanglei', - 'swd_murongshi', - 'swd_muyun', - 'swd_septem', - 'swd_tuobayuer', - 'swd_xuanyuanjianxian', - 'swd_yuxiaoxue', - 'swd_zhaoyun', - 'key_shiki', - 'shen_zhaoyun', - 'shen_ganning', - 're_liuzan', - 'chunyuqiong', - 'yangbiao', - 'dc_zhaoxiang', - 'sp_xiahoushi', - 'ns_zhangwei', - 'wanglang', - 'caojinyu', - 'zhangmancheng', - 'wu_zhugeliang', - 'sunlingluan', - 'wu_luxun', - 'key_mio', - 'key_midori', - 'key_yuri', - 'key_yui', - 'key_lucia', - 'db_key_hina', - 'sp_key_kanade', - 'key_shizuru', - 'key_sakuya', - 'boss_zhaoyun', - 'noname', - 'sb_machao', - 'dc_zhouxuān', - 'key_iriya', - 'dc_zhaoyun', +window.noname_character_rank = { + s: [ + "sp_sunce", + "gjqt_bailitusu", + "gjqt_beiluo", + "gjqt_xieyi", + "hs_malorne", + "hs_medivh", + "hs_sthrall", + "pal_yuejinzhao", + "swd_cheyun", + "swd_duguningke", + "swd_guyue", + "swd_huanglei", + "swd_murongshi", + "swd_muyun", + "swd_septem", + "swd_tuobayuer", + "swd_xuanyuanjianxian", + "swd_yuxiaoxue", + "swd_zhaoyun", + "key_shiki", + "shen_zhaoyun", + "shen_ganning", + "re_liuzan", + "chunyuqiong", + "yangbiao", + "dc_zhaoxiang", + "sp_xiahoushi", + "ns_zhangwei", + "wanglang", + "caojinyu", + "zhangmancheng", + "wu_zhugeliang", + "sunlingluan", + "wu_luxun", + "key_mio", + "key_midori", + "key_yuri", + "key_yui", + "key_lucia", + "db_key_hina", + "sp_key_kanade", + "key_shizuru", + "key_sakuya", + "boss_zhaoyun", + "noname", + "sb_machao", + "dc_zhouxuān", + "key_iriya", + "dc_zhaoyun", ], - ap:[ - 'xia_guanyu', - 'ol_sb_yuanshao', - 'gjqt_aruan', - 'gjqt_cenying', - 'gjqt_ouyangshaogong', - 'gjqt_yunwuyue', - 'gw_diandian', - 'gw_yioufeisisp', - 'hs_alakir', - 'hs_ashamoer', - 'hs_aya', - 'hs_hajiasha', - 'hs_malygos', - 'hs_neptulon', - 'hs_tyrande', - 'hs_xsylvanas', - 'ns_nanhua', - 'ow_ana', - 'ow_dva', - 'ow_liekong', - 'ow_luxiao', - 'ow_mei', - 'ow_yuanshi', - 'pal_liumengli', - 'pal_lixiaoyao', - 'pal_murongziying', - 'pal_xiahoujinxuan', - 'pal_xuanxiao', - 'pal_yueqi', - 'pal_yuntianhe', - 'pal_zixuan', - 'swd_huanyuanzhi', - 'swd_huiyan', - 'swd_jiliang', - 'swd_jipeng', - 'swd_muyue', - 'swd_qi', - 'swd_shuijing', - 'swd_shuwaner', - 'swd_tuwei', - 'swd_yuwentuo', - 'xuyou', - 'xushi', - 'zhangrang', - 'shen_guanyu', - 'shen_caocao', - 'shen_caopi', - 'majun', - 'jiakui', - 'guozhao', - 'ol_yuanshao', - 'caoying', - 'simahui', - 'guansuo', - 'yuantanyuanshang', - 'dongyun', - 're_sunyi', - 'shen_xunyu', - 'shen_guojia', - 'yangyan', - 'liuhui', - 'luyi', - 'shen_zhangfei', - 'clan_xuncai', - 'zhujianping', - 'liuzhang', - 'ol_wanglang', - 'key_kamome', - 'key_yukine', - 'key_inari', - 'key_shiina', - 'key_kud', - 'key_yukito', - 'key_yuuki', - 'db_key_liyingxia', - 'key_kiyu', - 'jsrg_pangtong', - 'star_dongzhuo', - 'clan_xunyou', - 'caoxian', - 'sb_guanyu', - 'mb_chengui', - 'jsrg_guozhao', - 'sb_caopi', - 'xia_yuzhenzi', - 'dc_simashi', - 'dc_sb_simayi', - 'caofang', + ap: [ + "xia_guanyu", + "ol_sb_yuanshao", + "gjqt_aruan", + "gjqt_cenying", + "gjqt_ouyangshaogong", + "gjqt_yunwuyue", + "gw_diandian", + "gw_yioufeisisp", + "hs_alakir", + "hs_ashamoer", + "hs_aya", + "hs_hajiasha", + "hs_malygos", + "hs_neptulon", + "hs_tyrande", + "hs_xsylvanas", + "ns_nanhua", + "ow_ana", + "ow_dva", + "ow_liekong", + "ow_luxiao", + "ow_mei", + "ow_yuanshi", + "pal_liumengli", + "pal_lixiaoyao", + "pal_murongziying", + "pal_xiahoujinxuan", + "pal_xuanxiao", + "pal_yueqi", + "pal_yuntianhe", + "pal_zixuan", + "swd_huanyuanzhi", + "swd_huiyan", + "swd_jiliang", + "swd_jipeng", + "swd_muyue", + "swd_qi", + "swd_shuijing", + "swd_shuwaner", + "swd_tuwei", + "swd_yuwentuo", + "xuyou", + "xushi", + "zhangrang", + "shen_guanyu", + "shen_caocao", + "shen_caopi", + "majun", + "jiakui", + "guozhao", + "ol_yuanshao", + "caoying", + "simahui", + "guansuo", + "yuantanyuanshang", + "dongyun", + "re_sunyi", + "shen_xunyu", + "shen_guojia", + "yangyan", + "liuhui", + "luyi", + "shen_zhangfei", + "clan_xuncai", + "zhujianping", + "liuzhang", + "ol_wanglang", + "key_kamome", + "key_yukine", + "key_inari", + "key_shiina", + "key_kud", + "key_yukito", + "key_yuuki", + "db_key_liyingxia", + "key_kiyu", + "jsrg_pangtong", + "star_dongzhuo", + "clan_xunyou", + "caoxian", + "sb_guanyu", + "mb_chengui", + "jsrg_guozhao", + "sb_caopi", + "xia_yuzhenzi", + "dc_simashi", + "dc_sb_simayi", + "caofang", + "dc_shen_huatuo", + "sp_zhenji", + "wu_guanyu", ], - a:[ - 'star_caoren', - 'star_yuanshao', - 'xia_shitao', - 'diy_zaozhirenjun', - 'gjqt_fanglansheng', - 'gjqt_fengqingxue', - 'gjqt_xiayize', - 'gw_aigeleisi', - 'gw_aimin', - 'gw_airuiting', - 'gw_aisinie', - 'gw_bulanwang', - 'gw_dagong', - 'gw_enxier', - 'gw_falanxisika', - 'gw_fulisi', - 'gw_gaier', - 'gw_haluo', - 'gw_jieluote', - 'gw_kairuisi', - 'gw_kanbi', - 'gw_kaxier', - 'gw_linjing', - 'gw_luobo', - 'gw_luoqi', - 'gw_meizi', - 'gw_nvyemo', - 'gw_puxila', - 'gw_shasixiwusi', - 'gw_telisi', - 'gw_xili', - 'gw_yenaifa', - 'gw_yioufeisi', - 'gw_yisilinni', - 'gw_zhangyujushou', - 'hs_alleria', - 'hs_amala', - 'hs_anduin', - 'hs_antonidas', - 'hs_bannabusi', - 'hs_bchillmaw', - 'hs_enzoth', - 'hs_fandral', - 'hs_fuding', - 'hs_heifengqishi', - 'hs_jaina', - 'hs_kaituozhe', - 'hs_kalimosi', - 'hs_khadgar', - 'hs_lafamu', - 'hs_laila', - 'hs_laxiao', - 'hs_lrhonin', - 'hs_manyututeng', - 'hs_morgl', - 'hs_pengpeng', - 'hs_sainaliusi', - 'hs_sapphiron', - 'hs_shanlingjuren', - 'hs_siwangxianzhi', - 'hs_trueheart', - 'hs_tuoqi', - 'hs_walian', - 'hs_xialikeer', - 'hs_xukongzhiying', - 'hs_yashaji', - 'hs_yelinlonghou', - 'hs_yinggencao', - 'hs_yngvar', - 'hs_ysera', - 'hs_zhanzhenggushu', - 'hs_zhihuanhua', - 'hs_zhishigushu', - 'mtg_jiding', - 'mtg_jiesi', - 'mtg_lilianna', - 'ns_caocao', - 'ns_caocaosp', - 'ns_guanlu', - 'ns_jinke', - 'ns_lvmeng', - 'ns_simazhao', - 'ns_wangyun', - 'ns_yanliang', - 'ow_banzang', - 'ow_chanyata', - 'ow_heiying', - 'ow_laiyinhate', - 'ow_maikelei', - 'ow_tianshi', - 'ow_tuobiang', - 'ow_zhaliya', - 'pal_jingtian', - 'pal_longkui', - 'pal_luozhaoyan', - 'pal_mingxiu', - 'pal_muchanglan', - 'pal_nangonghuang', - 'pal_tangyurou', - 'pal_wangpengxu', - 'pal_xia', - 'pal_xingxuan', - 'swd_anka', - 'swd_chenjingchou', - 'swd_hengai', - 'swd_huzhongxian', - 'swd_kangnalishi', - 'swd_kendi', - 'swd_lanyin', - 'swd_shanxiaoxiao', - 'swd_sikongyu', - 'swd_wangsiyue', - 'swd_xiarou', - 'swd_ziqiao', - 'yxs_caocao', - 'yxs_diaochan', - 'yxs_guiguzi', - 'yxs_luobinhan', - 'yxs_luzhishen', - 'yxs_wuzetian', - 'yxs_yangyuhuan', - 'zhangxiu', - 'liuyan', - 'xin_masu', - 'zhugezhan', - 'key_kagari', - 'shen_luxun', - 'shen_zhugeliang', - 'wenyang', - 'huaman', - 'puyuan', - 'lijue', - 'zhangchangpu', - 'zhangqiying', - 'wangyuanji', - 'miheng', - 're_guojia', - 're_sunquan', - 're_zhangjiao', - 're_zuoci', - 'sunhao', - 'shixie', - 'dc_shixie', - 'ol_zhangchangpu', - 'shamoke', - 'diy_wenyang', - 'xin_lingtong', - 'wolongfengchu', - 'yanghuiyu', - 'liubian', - 'panshu', - 'caochun', - 'xin_caifuren', - 'ol_wangrong', - 're_nanhualaoxian', - 'fuqian', - 'liuyong', - 'dc_liuli', - 'sunhanhua', - 're_pangdegong', - 're_fengfangnv', - 'caomao', - 'guanning', - 'ol_puyuan', - 'ns_limi', - 'jin_zhouchu', - 'huojun', - 'xiahouxuan', - 'ol_liuba', - 'wanglie', - 'zhaozhi', - 'shen_zhangjiao', - 'junk_zhangjiao', - 'tw_jiangji', - 'tw_niufudongxie', - 'tw_shen_lvmeng', - 'dc_tengfanglan', - 'xia_lusu', - 'zhanghua', - 'zerong', - 'wangguan', - 'duanqiaoxiao', - 'old_wanglang', - 'shichangshi', - 'ol_wenqin', - 'clan_zhonghui', - 'jsrg_chunyuqiong', - 'jsrg_guanyu', - 'dc_caocao', - 'dc_liubei', - 'dc_sunquan', - 'yuechen', - 'sunli', - 'dc_zhangmancheng', - 'jsrg_guojia', - 'jsrg_lougui', - 'jsrg_zhangfei', - 'jsrg_fanjiangzhangda', - 'jsrg_hansui', - 'jsrg_zhangren', - 'key_misuzu', - 'key_sunohara', - 'key_umi', - 'key_tsumugi', - 'key_saya', - 'key_hisako', - 'key_ao', - 'key_yuzuru', - 'key_kyoko', - 'key_jojiro', - 'key_shiroha', - 'key_shiori', - 'key_iwasawa', - 'key_hiroto', - 'key_nao', - 'key_kotarou', - 'key_kyou', - 'key_tomoyo', - 'star_yuanshu', - 'jiangji', - 'tianshangyi', - 'malingli', - 'caoyi', - 'sb_sp_zhugeliang', - 'sb_zhugeliang', - 'ol_jianyong', - 'ol_sb_jiangwei', - 'dc_sb_zhouyu', - 'dc_lingcao', - 'jsrg_zhugeliang', - 'shen_lusu', - 'huzun', - 'star_zhangchunhua', - 'mb_caomao', + a: [ + "star_caoren", + "star_yuanshao", + "xia_shitao", + "diy_zaozhirenjun", + "gjqt_fanglansheng", + "gjqt_fengqingxue", + "gjqt_xiayize", + "gw_aigeleisi", + "gw_aimin", + "gw_airuiting", + "gw_aisinie", + "gw_bulanwang", + "gw_dagong", + "gw_enxier", + "gw_falanxisika", + "gw_fulisi", + "gw_gaier", + "gw_haluo", + "gw_jieluote", + "gw_kairuisi", + "gw_kanbi", + "gw_kaxier", + "gw_linjing", + "gw_luobo", + "gw_luoqi", + "gw_meizi", + "gw_nvyemo", + "gw_puxila", + "gw_shasixiwusi", + "gw_telisi", + "gw_xili", + "gw_yenaifa", + "gw_yioufeisi", + "gw_yisilinni", + "gw_zhangyujushou", + "hs_alleria", + "hs_amala", + "hs_anduin", + "hs_antonidas", + "hs_bannabusi", + "hs_bchillmaw", + "hs_enzoth", + "hs_fandral", + "hs_fuding", + "hs_heifengqishi", + "hs_jaina", + "hs_kaituozhe", + "hs_kalimosi", + "hs_khadgar", + "hs_lafamu", + "hs_laila", + "hs_laxiao", + "hs_lrhonin", + "hs_manyututeng", + "hs_morgl", + "hs_pengpeng", + "hs_sainaliusi", + "hs_sapphiron", + "hs_shanlingjuren", + "hs_siwangxianzhi", + "hs_trueheart", + "hs_tuoqi", + "hs_walian", + "hs_xialikeer", + "hs_xukongzhiying", + "hs_yashaji", + "hs_yelinlonghou", + "hs_yinggencao", + "hs_yngvar", + "hs_ysera", + "hs_zhanzhenggushu", + "hs_zhihuanhua", + "hs_zhishigushu", + "mtg_jiding", + "mtg_jiesi", + "mtg_lilianna", + "ns_caocao", + "ns_caocaosp", + "ns_guanlu", + "ns_jinke", + "ns_lvmeng", + "ns_simazhao", + "ns_wangyun", + "ns_yanliang", + "ow_banzang", + "ow_chanyata", + "ow_heiying", + "ow_laiyinhate", + "ow_maikelei", + "ow_tianshi", + "ow_tuobiang", + "ow_zhaliya", + "pal_jingtian", + "pal_longkui", + "pal_luozhaoyan", + "pal_mingxiu", + "pal_muchanglan", + "pal_nangonghuang", + "pal_tangyurou", + "pal_wangpengxu", + "pal_xia", + "pal_xingxuan", + "swd_anka", + "swd_chenjingchou", + "swd_hengai", + "swd_huzhongxian", + "swd_kangnalishi", + "swd_kendi", + "swd_lanyin", + "swd_shanxiaoxiao", + "swd_sikongyu", + "swd_wangsiyue", + "swd_xiarou", + "swd_ziqiao", + "yxs_caocao", + "yxs_diaochan", + "yxs_guiguzi", + "yxs_luobinhan", + "yxs_luzhishen", + "yxs_wuzetian", + "yxs_yangyuhuan", + "zhangxiu", + "liuyan", + "xin_masu", + "zhugezhan", + "key_kagari", + "shen_luxun", + "shen_zhugeliang", + "wenyang", + "huaman", + "puyuan", + "lijue", + "zhangchangpu", + "zhangqiying", + "wangyuanji", + "miheng", + "re_guojia", + "re_sunquan", + "re_zhangjiao", + "re_zuoci", + "sunhao", + "shixie", + "dc_shixie", + "ol_zhangchangpu", + "shamoke", + "diy_wenyang", + "xin_lingtong", + "wolongfengchu", + "yanghuiyu", + "liubian", + "panshu", + "caochun", + "xin_caifuren", + "ol_wangrong", + "re_nanhualaoxian", + "fuqian", + "liuyong", + "dc_liuli", + "sunhanhua", + "re_pangdegong", + "re_fengfangnv", + "caomao", + "guanning", + "ol_puyuan", + "ns_limi", + "jin_zhouchu", + "huojun", + "xiahouxuan", + "ol_liuba", + "wanglie", + "zhaozhi", + "shen_zhangjiao", + "junk_zhangjiao", + "tw_jiangji", + "tw_niufudongxie", + "tw_shen_lvmeng", + "dc_tengfanglan", + "xia_lusu", + "zhanghua", + "zerong", + "wangguan", + "duanqiaoxiao", + "old_wanglang", + "shichangshi", + "ol_wenqin", + "clan_zhonghui", + "jsrg_chunyuqiong", + "jsrg_guanyu", + "dc_caocao", + "dc_liubei", + "dc_sunquan", + "yuechen", + "sunli", + "dc_zhangmancheng", + "jsrg_guojia", + "jsrg_lougui", + "jsrg_zhangfei", + "jsrg_fanjiangzhangda", + "jsrg_hansui", + "jsrg_zhangren", + "key_misuzu", + "key_sunohara", + "key_umi", + "key_tsumugi", + "key_saya", + "key_hisako", + "key_ao", + "key_yuzuru", + "key_kyoko", + "key_jojiro", + "key_shiroha", + "key_shiori", + "key_iwasawa", + "key_hiroto", + "key_nao", + "key_kotarou", + "key_kyou", + "key_tomoyo", + "star_yuanshu", + "jiangji", + "tianshangyi", + "malingli", + "caoyi", + "sb_sp_zhugeliang", + "sb_zhugeliang", + "ol_jianyong", + "ol_sb_jiangwei", + "dc_sb_zhouyu", + "dc_lingcao", + "jsrg_zhugeliang", + "shen_lusu", + "huzun", + "star_zhangchunhua", + "mb_caomao", + "drag_guanyu", + "drag_caoren", + "drag_lvchang", ], - am:[ - 'tw_yanliang', - 'tw_wenchou', - 'tw_yuantan', - 'bailingyun', - 'clan_wuqiao', - 'muludawang', - 'diy_caiwenji', - 'diy_liuyan', - 'diy_zhenji', - 'diy_zhouyu', - 'gjqt_chuqi', - 'gjqt_xiangling', - 'gjqt_xunfang', - 'gjqt_yanjiaxieyi', - 'gjqt_yuewuyi', - 'gw_bierna', - 'gw_fenghuang', - 'gw_fuertaisite', - 'gw_gaier', - 'gw_haizhiyezhu', - 'gw_hengsaite', - 'gw_huoge', - 'gw_kaerweite', - 'gw_kuite', - 'gw_laduoweide', - 'gw_lanbote', - 'gw_laomaotou', - 'gw_mieren', - 'gw_nitelila', - 'gw_oudimu', - 'gw_sanhanya', - 'gw_saqiya', - 'gw_shanhu', - 'gw_xigedelifa', - 'gw_zhuoertan', - 'hs_aedwin', - 'hs_aiqinvyao', - 'hs_alextrasza', - 'hs_barnes', - 'hs_bilanyoulong', - 'hs_blingtron', - 'hs_bolvar', - 'hs_brann', - 'hs_fachaotuteng', - 'hs_jiaziruila', - 'hs_kazhakusi', - 'hs_kchromaggus', - 'hs_kcthun', - 'hs_magni', - 'hs_mijiaojisi', - 'hs_mojinbaozi', - 'hs_pyros', - 'hs_ronghejuren', - 'hs_shaku', - 'hs_shizugui', - 'hs_shuiwenxuejia', - 'hs_siwangzhiyi', - 'hs_taisi', - 'hs_totemic', - 'hs_wujiyuansu', - 'hs_wvelen', - 'hs_yangyanwageli', - 'hs_yogg', - 'ns_duangui', - 'ns_huangzu', - 'ns_masu', - 'ns_shenpei', - 'ns_sunjian', - 'ns_xinxianying', - 'ns_yuji', - 'ns_yujisp', - 'ns_zhangxiu', - 'ns_zuoci', - 'ow_baolei', - 'ow_falaozhiying', - 'ow_kuangshu', - 'ow_orisa', - 'ow_shibing', - 'ow_wensidun', - 'ow_zhixuzhiguang', - 'pal_anu', - 'pal_changqing', - 'pal_hanlingsha', - 'pal_jushifang', - 'pal_wenhui', - 'pal_xianqing', - 'pal_xuejian', - 'pal_zhaoliner', - 'swd_duanmeng', - 'swd_duopeng', - 'swd_fengyu', - 'swd_fuyan', - 'swd_jiuyou', - 'swd_kama', - 'swd_linyue', - 'swd_maixing', - 'swd_nicole', - 'swd_rongshuang', - 'swd_weida', - 'swd_xiaohuanglong', - 'swd_xiyan', - 'swd_xuanyuanjiantong', - 'swd_yeyaxi', - 'swd_yuchiyanhong', - 'swd_yuli', - 'yxs_direnjie', - 'yxs_huamulan', - 'yxs_libai', - 'yxs_luban', - 'yxs_nandinggeer', - 'yxs_napolun', - 'yxs_sunwu', - 'yxs_wangzhaojun', - 'yxs_xiangyu', - 'yxs_yangguang', - 'yxs_yingzheng', - 'yxs_zhangsanfeng', - 're_yuanshu', - 'guojia', - 'caopi', - 're_yuanshao', - 'wangping', - 'luji', - 'haozhao', - 'lukang', - 'lvdai', - 'zhoufang', - 'zhuzhi', - 're_zhuzhi', - 'guohuai', - 'caorui', - 'liuyu', - 'qinmi', - 'shen_diaochan', - 'shen_zhenji', - 'shen_simayi', - 'xushao', - 'tw_yujin', - 'xurong', - 'beimihu', - 'guanlu', - 'gexuan', - 're_xusheng', - 'pangdegong', - 'sp_sufei', - 'xin_zhuran', - 're_zhanggong', - 'zhengxuan', - 're_sunshangxiang', - 're_lvbu', - 'caoren', - 'ol_xiahouyuan', - 're_huangzhong', - 'ol_huangzhong', - 'ol_weiyan', - 'zhoutai', - 're_xunyu', - 'yujin_yujin', - 're_bulianshi', - 're_zhonghui', - 're_zhuran', - 're_wuyi', - 'zhangbao', - 'maliang', - 'zhugedan', - 'chenlin', - 'xizhicai', - 'luzhi', - 'huangfusong', - 'sp_pangtong', - 'ns_jiaxu', - 'old_jiakui', - 'jin_simayi', - 'jin_simashi', - 'jin_wangyuanji', - 'duyu', - 'yj_ganning', - 'key_kyousuke', - 'key_yusa', - 'key_misa', - 'key_masato', - 'key_harukakanata', - 'key_rin', - 'key_yuiko', - 'key_nagisa', - 'key_godan', - 'key_yuu', - 'sp_key_yuri', - 'key_kotomi', - 'tw_beimihu', - 'ns_caoshuang', - 'key_shizuku', - 'wangrong', - 're_fazheng', - 'tw_re_fazheng', - 'huaxin', - 're_chunyuqiong', - 'ns_luyusheng', - 'sp_chenzhen', - 'sp_wangcan', - 'caosong', - 'sp_duyu', - 'xiahoujie', - 'ns_huangwudie', - 'ns_chentai', - 'ns_yanghu', - 'ns_zhangning', - 'huangchengyan', - 'lvlingqi', - 'zhongyan', - 'wangling', - 'zhouchu', - 'yangwan', - 're_dongcheng', - 'ol_yujin', - 'ol_huaxin', - 'qiaozhou', - 're_xunchen', - 'sp_cuiyan', - 'ol_dongzhao', - 'xin_jushou', - 'sp_zhujun', - 're_guohuanghou', - 'tw_liuhong', - 're_zhangbao', - 're_dengzhi', - 'sp_jianggan', - 'tw_caozhao', - 'tw_guohuai', - 'shen_jiangwei', - 'dc_luotong', - 'dc_huangchengyan', - 'tengfanglan', - 'tenggongzhu', - 'sp_menghuo', - 'dc_sp_menghuo', - 'dc_qinghegongzhu', - 'ruiji', - 're_liuchen', - 'dc_gongsunzan', - 'ol_xunyu', - 'zhangxuan', - 'tw_shenguanyu', - 'dc_sunru', - 'dc_wangchang', - 'fengfang', - 'prp_zhugeliang', - 'dukui', - 'quanhuijie', - 'yinfuren', - 'dc_zhaoyǎn', - 'clan_wuxian', - 'clan_xunchen', - 'chenjiao', - 'chengbing', - 'sb_caosong', - 'guyong', - 'tw_jiangqing', - 'tw_liuzhang', - 'tw_wangling', - 'tw_zhangji', - 'tw_liyàn', - 'xuelingyun', - 'dc_zhaotongzhaoguang', - 'mengjie', - 'yj_qiaozhou', - 'yj_sufei', - 'dc_ruiji', - 'yuantanyuanxiyuanshang', - 'yanghong', - 'dc_sunhanhua', - 'shen_dianwei', - 'zhoubuyi', - 'jsrg_sunce', - 're_caorui', - 'ol_zhouqun', - 'caoxi', - 'zhaoxiang', - 'chenshi', - 'xiahoumao', - 'dc_xujing', - 'le_shen_jiaxu', - 'jsrg_xiahourong', - 'jsrg_sunshangxiang', - 'jsrg_machao', - 'sunyu', - 're_caorui', - 're_zhugedan', - 'tw_yanxiang', - 'yanxiang', - 'nezha', - 'dc_jiachong', - 'pangshanmin', - 'kuaiqi', - 'shen_huatuo', - 'dc_guansuo', - 'dc_dongzhao', - 'zhugeruoxue', - 'zhugemengxue', - 'dc_sb_lusu', - 'mb_huban', - 'jsrg_simayi', - 'jsrg_zhaoyun', - 'jsrg_zhangxuan', - 'sb_xunyu', - 'ol_sb_taishici', - 'tianchou', - 'ol_sb_guanyu', - 'gongsunxiu', - 'dc_caoshuang', - 'clan_wangling', - 'clan_wangguang', - 'lizhaojiaobo', + am: [ + "tw_yanliang", + "tw_wenchou", + "tw_yuantan", + "bailingyun", + "clan_wuqiao", + "muludawang", + "diy_caiwenji", + "diy_liuyan", + "diy_zhenji", + "diy_zhouyu", + "gjqt_chuqi", + "gjqt_xiangling", + "gjqt_xunfang", + "gjqt_yanjiaxieyi", + "gjqt_yuewuyi", + "gw_bierna", + "gw_fenghuang", + "gw_fuertaisite", + "gw_gaier", + "gw_haizhiyezhu", + "gw_hengsaite", + "gw_huoge", + "gw_kaerweite", + "gw_kuite", + "gw_laduoweide", + "gw_lanbote", + "gw_laomaotou", + "gw_mieren", + "gw_nitelila", + "gw_oudimu", + "gw_sanhanya", + "gw_saqiya", + "gw_shanhu", + "gw_xigedelifa", + "gw_zhuoertan", + "hs_aedwin", + "hs_aiqinvyao", + "hs_alextrasza", + "hs_barnes", + "hs_bilanyoulong", + "hs_blingtron", + "hs_bolvar", + "hs_brann", + "hs_fachaotuteng", + "hs_jiaziruila", + "hs_kazhakusi", + "hs_kchromaggus", + "hs_kcthun", + "hs_magni", + "hs_mijiaojisi", + "hs_mojinbaozi", + "hs_pyros", + "hs_ronghejuren", + "hs_shaku", + "hs_shizugui", + "hs_shuiwenxuejia", + "hs_siwangzhiyi", + "hs_taisi", + "hs_totemic", + "hs_wujiyuansu", + "hs_wvelen", + "hs_yangyanwageli", + "hs_yogg", + "ns_duangui", + "ns_huangzu", + "ns_masu", + "ns_shenpei", + "ns_sunjian", + "ns_xinxianying", + "ns_yuji", + "ns_yujisp", + "ns_zhangxiu", + "ns_zuoci", + "ow_baolei", + "ow_falaozhiying", + "ow_kuangshu", + "ow_orisa", + "ow_shibing", + "ow_wensidun", + "ow_zhixuzhiguang", + "pal_anu", + "pal_changqing", + "pal_hanlingsha", + "pal_jushifang", + "pal_wenhui", + "pal_xianqing", + "pal_xuejian", + "pal_zhaoliner", + "swd_duanmeng", + "swd_duopeng", + "swd_fengyu", + "swd_fuyan", + "swd_jiuyou", + "swd_kama", + "swd_linyue", + "swd_maixing", + "swd_nicole", + "swd_rongshuang", + "swd_weida", + "swd_xiaohuanglong", + "swd_xiyan", + "swd_xuanyuanjiantong", + "swd_yeyaxi", + "swd_yuchiyanhong", + "swd_yuli", + "yxs_direnjie", + "yxs_huamulan", + "yxs_libai", + "yxs_luban", + "yxs_nandinggeer", + "yxs_napolun", + "yxs_sunwu", + "yxs_wangzhaojun", + "yxs_xiangyu", + "yxs_yangguang", + "yxs_yingzheng", + "yxs_zhangsanfeng", + "re_yuanshu", + "guojia", + "caopi", + "re_yuanshao", + "wangping", + "luji", + "haozhao", + "lukang", + "lvdai", + "zhoufang", + "zhuzhi", + "re_zhuzhi", + "guohuai", + "caorui", + "liuyu", + "qinmi", + "shen_diaochan", + "shen_zhenji", + "shen_simayi", + "xushao", + "tw_yujin", + "xurong", + "beimihu", + "guanlu", + "gexuan", + "re_xusheng", + "pangdegong", + "sp_sufei", + "xin_zhuran", + "re_zhanggong", + "zhengxuan", + "re_sunshangxiang", + "re_lvbu", + "caoren", + "ol_xiahouyuan", + "re_huangzhong", + "ol_huangzhong", + "ol_weiyan", + "zhoutai", + "re_xunyu", + "yujin_yujin", + "re_bulianshi", + "re_zhonghui", + "re_zhuran", + "re_wuyi", + "zhangbao", + "maliang", + "zhugedan", + "chenlin", + "xizhicai", + "luzhi", + "huangfusong", + "sp_pangtong", + "ns_jiaxu", + "old_jiakui", + "jin_simayi", + "jin_simashi", + "jin_wangyuanji", + "duyu", + "yj_ganning", + "key_kyousuke", + "key_yusa", + "key_misa", + "key_masato", + "key_harukakanata", + "key_rin", + "key_yuiko", + "key_nagisa", + "key_godan", + "key_yuu", + "sp_key_yuri", + "key_kotomi", + "tw_beimihu", + "ns_caoshuang", + "key_shizuku", + "wangrong", + "re_fazheng", + "tw_re_fazheng", + "huaxin", + "re_chunyuqiong", + "ns_luyusheng", + "sp_chenzhen", + "sp_wangcan", + "caosong", + "sp_duyu", + "xiahoujie", + "ns_huangwudie", + "ns_chentai", + "ns_yanghu", + "ns_zhangning", + "huangchengyan", + "lvlingqi", + "zhongyan", + "wangling", + "zhouchu", + "yangwan", + "re_dongcheng", + "ol_yujin", + "ol_huaxin", + "qiaozhou", + "re_xunchen", + "sp_cuiyan", + "ol_dongzhao", + "xin_jushou", + "sp_zhujun", + "re_guohuanghou", + "tw_liuhong", + "re_zhangbao", + "re_dengzhi", + "sp_jianggan", + "tw_caozhao", + "tw_guohuai", + "shen_jiangwei", + "dc_luotong", + "dc_huangchengyan", + "tengfanglan", + "tenggongzhu", + "sp_menghuo", + "dc_sp_menghuo", + "dc_qinghegongzhu", + "ruiji", + "re_liuchen", + "dc_gongsunzan", + "ol_xunyu", + "zhangxuan", + "tw_shenguanyu", + "dc_sunru", + "dc_wangchang", + "fengfang", + "prp_zhugeliang", + "dukui", + "quanhuijie", + "yinfuren", + "dc_zhaoyǎn", + "clan_wuxian", + "clan_xunchen", + "chenjiao", + "chengbing", + "sb_caosong", + "guyong", + "tw_jiangqing", + "tw_liuzhang", + "tw_wangling", + "tw_zhangji", + "tw_liyàn", + "xuelingyun", + "dc_zhaotongzhaoguang", + "mengjie", + "yj_qiaozhou", + "yj_sufei", + "dc_ruiji", + "yuantanyuanxiyuanshang", + "yanghong", + "dc_sunhanhua", + "shen_dianwei", + "zhoubuyi", + "jsrg_sunce", + "re_caorui", + "ol_zhouqun", + "caoxi", + "zhaoxiang", + "chenshi", + "xiahoumao", + "dc_xujing", + "le_shen_jiaxu", + "jsrg_xiahourong", + "jsrg_sunshangxiang", + "jsrg_machao", + "sunyu", + "re_caorui", + "re_zhugedan", + "tw_yanxiang", + "yanxiang", + "nezha", + "dc_jiachong", + "pangshanmin", + "kuaiqi", + "shen_huatuo", + "dc_guansuo", + "dc_dongzhao", + "zhugeruoxue", + "zhugemengxue", + "dc_sb_lusu", + "mb_huban", + "jsrg_simayi", + "jsrg_zhaoyun", + "jsrg_zhangxuan", + "sb_xunyu", + "ol_sb_taishici", + "tianchou", + "ol_sb_guanyu", + "gongsunxiu", + "dc_caoshuang", + "clan_wangling", + "clan_wangguang", + "lizhaojiaobo", ], - bp:[ - 'xin_huojun', - 'chess_diaochan', - 'chess_huangzhong', - 'chess_sunshangxiang', - 'chess_taishici', - 'chess_zhangliao', - 'diy_liuzan', - 'diy_lukang', - 'diy_xuhuang', - 'diy_yangyi', - 'gjqt_hongyu', - 'gjqt_wenrenyu', - 'gjqt_yinqianshang', - 'gw_aokeweisite', - 'gw_feilafanruide', - 'gw_qigaiwang', - 'hs_anomalus', - 'hs_duyaxinshi', - 'hs_fengjianhuanfengzhe', - 'hs_finley', - 'hs_guldan', - 'hs_hallazeal', - 'hs_hemite', - 'hs_hudunren', - 'hs_huolituteng', - 'hs_jgarrosh', - 'hs_liadrin', - 'hs_loatheb', - 'hs_lreno', - 'hs_lrexxar', - 'hs_malfurion', - 'hs_nate', - 'hs_nozdormu', - 'hs_ruanniguai', - 'hs_selajin', - 'hs_shifazhe', - 'hs_tanghangu', - 'hs_tgolem', - 'hs_waleera', - 'hs_wuther', - 'hs_xuanzhuanjijia', - 'hs_xuefashi', - 'hs_yelise', - 'hs_zhouzhuo', - 'ns_huamulan', - 'ns_yangyi', - 'ns_zhangbao', - 'ns_zhugeliang', - 'ow_heibaihe', - 'ow_luba', - 'ow_sishen', - 'pal_jiangcheng', - 'pal_jiangyunfan', - 'pal_leiyuange', - 'pal_longyou', - 'pal_shenqishuang', - 'pal_sumei', - 'pal_wangxiaohu', - 'pal_xiaoman', - 'swd_chunyuheng', - 'swd_fengtianling', - 'swd_haidapang', - 'swd_hanlong', - 'swd_hupo', - 'swd_huyue', - 'swd_jiangwu', - 'swd_jiangziya', - 'swd_jiting', - 'swd_lilian', - 'swd_moye', - 'swd_qiner', - 'swd_quxian', - 'swd_shangzhang', - 'swd_shaowei', - 'swd_situqiang', - 'swd_zhiyin', - 'swd_zhuoshanzhu', - 'swd_zidashu', - 'yxs_aijiyanhou', - 'yxs_bole', - 'yxs_fuermosi', - 'yxs_jinke', - 'yxs_kaisa', - 'yxs_lanlinwang', - 'yxs_luocheng', - 'yxs_meixi', - 'yxs_mozi', - 'yxs_xiaoqiao', - 'yxs_yuefei', - 'yxs_zhaoyong', - 'yxs_zhuyuanzhang', - 'zhangliao', - 'zhenji', - 'zhugeliang', - 'sunquan', - 'daqiao', - 'diaochan', - 'liubei', - 'xf_yiji', - 'zhoufei', - 'xunyu', - 'kuailiangkuaiyue', - 'dianwei', - 're_lusu', - 'panjun', - 'ol_xinxianying', - 'liubiao', - 'zhongyao', - 'liuchen', - 'caochong', - 'liufeng', - 'zhangsong', - 'zhuhuan', - 'wuxian', - 'jikang', - 'shen_lvbu', - 'shen_liubei', - 're_maliang', - 'caobuxing', - 'caoxing', - 're_panfeng', - 'leitong', - 'sp_liuqi', - 'xf_tangzi', - 'liuzan', - 'lingcao', - 'sunyang', - 'sunru', - 'lifeng', - 'zhangyì', - 'yj_xuhuang', - 'xin_liaohua', - 'sp_sunshao', - 're_wangyun', - 're_caocao', - 're_guanyu', - 're_huanggai', - 're_liubei', - 're_zhangliao', - 're_zhugeliang', - 're_daqiao', - 're_diaochan', - 'ol_pangtong', - 'ol_pangde', - 're_zhurong', - 're_menghuo', - 're_liubiao', - 'xin_liubiao', - 're_liru', - 're_manchong', - 're_jianyong', - 're_yufan', - 're_zhangyi', - 're_sunxiu', - 'caoang', - 'sp_caoren', - 'zhugeke', - 'quyi', - 'yuanshu', - 'sp_zhaoyun', - 'zhangxingcai', - 'chengyu', - 'buzhi', - 'jsp_zhaoyun', - 'huangjinleishi', - 're_xinxianying', - 'sp_wangyuanji', - 'sp_xinxianying', - 'sp_liuxie', - 'hanfu', - 're_quyi', - 'zhanghuyuechen', - 'fanyufeng', - 'key_kengo', - 'key_riki', - 'key_hinata', - 'key_akane', - 'key_shiorimiyuki', - 'key_miki', - 'key_ryoichi', - 'key_kotori', - 'key_chihaya', - 'key_rumi', - 'nashime', - 'ns_huangchengyan', - 'ns_yuanxi', - 're_fuhuanghou', - 're_gongsunyuan', - 're_caozhen', - 'ol_lisu', - 'jin_simazhao', - 'jin_zhangchunhua', - 'xin_handang', - 'luotong', - 're_zhoucang', - 'ruanyu', - 'wujing', - 'nanhualaoxian', - 'ns_sunyi', - 'key_kyouko', - 're_guotufengji', - 'ol_jiangwei', - 'key_tenzen', - 'jsp_liubei', - 'liangxing', - 'tangji', - 'gaogan', - 'sp_xunchen', - 'duxi', - 'heyan', - 're_caifuren', - 'sp_kongrong', - 'qiaogong', - 'tw_qiaogong', - 're_guyong', - 'xin_zhonghui', - 'jiachong', - 'wuban', - 'tw_zhaoxiang', - 'ol_lusu', - 'zhangzhongjing', - 'db_wenyang', - 'dufuren', - 'yuanhuan', - 'zhouyi', - 'yangzhi', - 'wanniangongzhu', - 'sunyi', - 'sp_gaolan', - 'simafu', - 'mayuanyi', - 'fengfangnv', - 'ol_yangyi', - 'sp_zhangchangpu', - 'sp_jiangwan', - 'xinchang', - 'xin_yufan', - 'ol_yufan', - 'tw_re_caohong', - 'tw_mayunlu', - 'tw_hucheer', - 'sp_lvfan', - 'lvfan', - 'cuimao', - 'liqueguosi', - 're_chendeng', - 'wuyan', - 'wangyue', - 'xin_sunxiu', - 'sp_maojie', - 'ol_xuhuang', - 'ol_zhuling', - 'tw_zangba', - 're_miheng', - 'fengxi', - 'tw_chengpu', - 'key_satomi', - 'key_erika', - 'jin_yanghu', - 'qinghegongzhu', - 're_zhanghe', - 'wufan', - 'yanfuren', - 'tw_wangcan', - 'tw_wangchang', - 'jin_jiachong', - 'licaiwei', - 'tengyin', - 'old_yangzhi', - 'laiyinger', - 'yanrou', - 'weizi', - 'shen_machao', - 'sb_yujin', - 'sb_huangzhong', - 'dc_yanghu', - 'dc_gongsunzan', - 'caohua', - 'zhaoang', - 'ns_zhonglimu', - 'caoxiancaohua', - 'dc_liuba', - 'key_seira', - 'lukai', - 'ol_lukai', - 'niufu', - 're_liufeng', - 'huzhao', - 'guanhai', - 'zhangfen', - 'ol_dianwei', - 'wangyan', - 'chengui', - 'ol_hujinding', - 'dc_huangquan', - 'dc_huban', - 'dingshangwan', - 're_zhuhuan', - 'xin_zhuhuan', - 'dc_liuye', - 'zhugeshang', - 're_xunyou', - 'liwan', - 'ol_furong', - 'shiyi', - 'gongsundu', - 'yuanji', - 'dc_chenqun', - 'liupi', - 'ol_liupi', - 'mazhong', - 're_mazhong', - 'tw_baoxin', - 'tw_bingyuan', - 'tw_chenzhen', - 'tw_handang', - 'tw_haomeng', - 'tw_liwei', - 'tw_mateng', - 'tw_xunchen', - 'tw_zhangfei', - 'tw_zhangning', - 'xia_tongyuan', - 'xia_wangyue', - 'dc_huanghao', - 'dc_yangbiao', - 'ns_sundeng', - 'dc_huojun', - 'ol_zhangyì', - 'ol_zhujun', - 'liyan', - 're_lidian', - 'qinlang', - 'xia_dianwei', - 'xia_zhaoe', - 'zhangkai', - 'sunhong', - 'zhangjinyun', - 'dc_mengda', - 'xiaoyuehankehan', - 'zhutiexiong', - 'shen_dengai', - 'libai', - 'tw_gongsunfan', - 'yue_caiwenji', - 'yue_xiaoqiao', - 'yue_daqiao', - 'vtb_xiaole', - 'vtb_xiaojiu', - 'ol_zhangzhang', - 'ol_mengda', - 'dc_wuban', - 're_caochong', - 'jsrg_lvbu', - 'jsrg_xuyou', - 'jsrg_zhangliao', - 'jsrg_zhenji', - 'junk_xuyou', - 'sp_machao', - 'liupan', - 'mengyou', - 're_wenpin', - 'yue_zhoufei', - 'ns_mengyou', - 'zhangyan', - 'jsrg_huangzhong', - 'jsrg_zhangchu', - 'ol_dingshangwan', - 'ol_liwan', - 'chengjichengcui', - 'xin_zhangliang', - 'liwei', - 'xin_wuban', - 'ol_liuyan', - 'sunhuan', - 'yue_caiyong', - 'sb_huangyueying', - 'jsrg_jiangwei', - 'jsrg_luxun', - 'jsrg_caofang', - 'jsrg_guoxun', - 'jsrg_gaoxiang', - 'jsrg_sunlubansunluyu', - 'jsrg_weiwenzhugezhi', - 'shen_xuzhu', - 'dc_jiangji', - 'dc_wangling', - 'yangfeng', - 'sb_xiahoudun', - 'sb_gaoshun', - 're_wangyi', - 'ol_wangyi', - 'chengji', - 'mb_sp_guanqiujian', + bp: [ + "xin_huojun", + "chess_diaochan", + "chess_huangzhong", + "chess_sunshangxiang", + "chess_taishici", + "chess_zhangliao", + "diy_liuzan", + "diy_lukang", + "diy_xuhuang", + "diy_yangyi", + "gjqt_hongyu", + "gjqt_wenrenyu", + "gjqt_yinqianshang", + "gw_aokeweisite", + "gw_feilafanruide", + "gw_qigaiwang", + "hs_anomalus", + "hs_duyaxinshi", + "hs_fengjianhuanfengzhe", + "hs_finley", + "hs_guldan", + "hs_hallazeal", + "hs_hemite", + "hs_hudunren", + "hs_huolituteng", + "hs_jgarrosh", + "hs_liadrin", + "hs_loatheb", + "hs_lreno", + "hs_lrexxar", + "hs_malfurion", + "hs_nate", + "hs_nozdormu", + "hs_ruanniguai", + "hs_selajin", + "hs_shifazhe", + "hs_tanghangu", + "hs_tgolem", + "hs_waleera", + "hs_wuther", + "hs_xuanzhuanjijia", + "hs_xuefashi", + "hs_yelise", + "hs_zhouzhuo", + "ns_huamulan", + "ns_yangyi", + "ns_zhangbao", + "ns_zhugeliang", + "ow_heibaihe", + "ow_luba", + "ow_sishen", + "pal_jiangcheng", + "pal_jiangyunfan", + "pal_leiyuange", + "pal_longyou", + "pal_shenqishuang", + "pal_sumei", + "pal_wangxiaohu", + "pal_xiaoman", + "swd_chunyuheng", + "swd_fengtianling", + "swd_haidapang", + "swd_hanlong", + "swd_hupo", + "swd_huyue", + "swd_jiangwu", + "swd_jiangziya", + "swd_jiting", + "swd_lilian", + "swd_moye", + "swd_qiner", + "swd_quxian", + "swd_shangzhang", + "swd_shaowei", + "swd_situqiang", + "swd_zhiyin", + "swd_zhuoshanzhu", + "swd_zidashu", + "yxs_aijiyanhou", + "yxs_bole", + "yxs_fuermosi", + "yxs_jinke", + "yxs_kaisa", + "yxs_lanlinwang", + "yxs_luocheng", + "yxs_meixi", + "yxs_mozi", + "yxs_xiaoqiao", + "yxs_yuefei", + "yxs_zhaoyong", + "yxs_zhuyuanzhang", + "zhangliao", + "zhenji", + "zhugeliang", + "sunquan", + "daqiao", + "diaochan", + "liubei", + "xf_yiji", + "zhoufei", + "xunyu", + "kuailiangkuaiyue", + "dianwei", + "re_lusu", + "panjun", + "ol_xinxianying", + "liubiao", + "zhongyao", + "liuchen", + "caochong", + "liufeng", + "zhangsong", + "zhuhuan", + "wuxian", + "jikang", + "shen_lvbu", + "shen_liubei", + "re_maliang", + "caobuxing", + "caoxing", + "re_panfeng", + "leitong", + "sp_liuqi", + "xf_tangzi", + "liuzan", + "lingcao", + "sunyang", + "sunru", + "lifeng", + "zhangyì", + "yj_xuhuang", + "xin_liaohua", + "sp_sunshao", + "re_wangyun", + "re_caocao", + "re_guanyu", + "re_huanggai", + "re_liubei", + "re_zhangliao", + "re_zhugeliang", + "re_daqiao", + "re_diaochan", + "ol_pangtong", + "ol_pangde", + "re_zhurong", + "re_menghuo", + "re_liubiao", + "xin_liubiao", + "re_liru", + "re_manchong", + "re_jianyong", + "re_yufan", + "re_zhangyi", + "re_sunxiu", + "caoang", + "sp_caoren", + "zhugeke", + "quyi", + "yuanshu", + "sp_zhaoyun", + "zhangxingcai", + "chengyu", + "buzhi", + "jsp_zhaoyun", + "huangjinleishi", + "re_xinxianying", + "sp_wangyuanji", + "sp_xinxianying", + "sp_liuxie", + "hanfu", + "re_quyi", + "zhanghuyuechen", + "fanyufeng", + "key_kengo", + "key_riki", + "key_hinata", + "key_akane", + "key_shiorimiyuki", + "key_miki", + "key_ryoichi", + "key_kotori", + "key_chihaya", + "key_rumi", + "nashime", + "ns_huangchengyan", + "ns_yuanxi", + "re_fuhuanghou", + "re_gongsunyuan", + "re_caozhen", + "ol_lisu", + "jin_simazhao", + "jin_zhangchunhua", + "xin_handang", + "luotong", + "re_zhoucang", + "ruanyu", + "wujing", + "nanhualaoxian", + "ns_sunyi", + "key_kyouko", + "re_guotufengji", + "ol_jiangwei", + "key_tenzen", + "jsp_liubei", + "liangxing", + "tangji", + "gaogan", + "sp_xunchen", + "duxi", + "heyan", + "re_caifuren", + "sp_kongrong", + "qiaogong", + "tw_qiaogong", + "re_guyong", + "xin_zhonghui", + "jiachong", + "wuban", + "tw_zhaoxiang", + "ol_lusu", + "zhangzhongjing", + "db_wenyang", + "dufuren", + "yuanhuan", + "zhouyi", + "yangzhi", + "wanniangongzhu", + "sunyi", + "sp_gaolan", + "simafu", + "mayuanyi", + "fengfangnv", + "ol_yangyi", + "sp_zhangchangpu", + "sp_jiangwan", + "xinchang", + "xin_yufan", + "ol_yufan", + "tw_re_caohong", + "tw_mayunlu", + "tw_hucheer", + "sp_lvfan", + "lvfan", + "cuimao", + "liqueguosi", + "re_chendeng", + "wuyan", + "wangyue", + "xin_sunxiu", + "sp_maojie", + "ol_xuhuang", + "ol_zhuling", + "tw_zangba", + "re_miheng", + "fengxi", + "tw_chengpu", + "key_satomi", + "key_erika", + "jin_yanghu", + "qinghegongzhu", + "re_zhanghe", + "wufan", + "yanfuren", + "tw_wangcan", + "tw_wangchang", + "jin_jiachong", + "licaiwei", + "tengyin", + "old_yangzhi", + "laiyinger", + "yanrou", + "weizi", + "shen_machao", + "sb_yujin", + "sb_huangzhong", + "dc_yanghu", + "dc_gongsunzan", + "caohua", + "zhaoang", + "ns_zhonglimu", + "caoxiancaohua", + "dc_liuba", + "key_seira", + "lukai", + "ol_lukai", + "niufu", + "re_liufeng", + "huzhao", + "guanhai", + "zhangfen", + "ol_dianwei", + "wangyan", + "chengui", + "ol_hujinding", + "dc_huangquan", + "dc_huban", + "dingshangwan", + "re_zhuhuan", + "xin_zhuhuan", + "dc_liuye", + "zhugeshang", + "re_xunyou", + "liwan", + "ol_furong", + "shiyi", + "gongsundu", + "yuanji", + "dc_chenqun", + "liupi", + "ol_liupi", + "mazhong", + "re_mazhong", + "tw_baoxin", + "tw_bingyuan", + "tw_chenzhen", + "tw_handang", + "tw_haomeng", + "tw_liwei", + "tw_mateng", + "tw_xunchen", + "tw_zhangfei", + "tw_zhangning", + "xia_tongyuan", + "xia_wangyue", + "dc_huanghao", + "dc_yangbiao", + "ns_sundeng", + "dc_huojun", + "ol_zhangyì", + "ol_zhujun", + "liyan", + "re_lidian", + "qinlang", + "xia_dianwei", + "xia_zhaoe", + "zhangkai", + "sunhong", + "zhangjinyun", + "dc_mengda", + "xiaoyuehankehan", + "zhutiexiong", + "shen_dengai", + "libai", + "tw_gongsunfan", + "yue_caiwenji", + "yue_xiaoqiao", + "yue_daqiao", + "vtb_xiaole", + "vtb_xiaojiu", + "ol_zhangzhang", + "ol_mengda", + "dc_wuban", + "re_caochong", + "jsrg_lvbu", + "jsrg_xuyou", + "jsrg_zhangliao", + "jsrg_zhenji", + "junk_xuyou", + "sp_machao", + "liupan", + "mengyou", + "re_wenpin", + "yue_zhoufei", + "ns_mengyou", + "zhangyan", + "jsrg_huangzhong", + "jsrg_zhangchu", + "ol_dingshangwan", + "ol_liwan", + "chengjichengcui", + "xin_zhangliang", + "liwei", + "xin_wuban", + "ol_liuyan", + "sunhuan", + "yue_caiyong", + "sb_huangyueying", + "jsrg_jiangwei", + "jsrg_luxun", + "jsrg_caofang", + "jsrg_guoxun", + "jsrg_gaoxiang", + "jsrg_sunlubansunluyu", + "jsrg_weiwenzhugezhi", + "shen_xuzhu", + "dc_jiangji", + "dc_wangling", + "yangfeng", + "sb_xiahoudun", + "sb_gaoshun", + "re_wangyi", + "ol_wangyi", + "chengji", + "mb_sp_guanqiujian", ], - b:[ - 'junk_guanyu', - 'liyi', - 'diy_feishi', - 'diy_liufu', - 'diy_tianyu', - 'diy_yuji', - 'hs_huzhixiannv', - 'hs_jiawodun', - 'hs_jinglinglong', - 'hs_shirencao', - 'hs_yelinchulong', - 'pal_linyueru', - 'swd_fu', - 'swd_hanluo', - 'swd_jialanduo', - 'swd_luchengxuan', - 'swd_youzhao', - 'swd_zhanggao', - 'yxs_baosi', - 'yxs_chengjisihan', - 'yxs_chengyaojin', - 'yxs_lishimin', - 'yxs_lvzhi', - 'yxs_mingchenghuanghou', - 'yxs_tangbohu', - 'yxs_weizhongxian', - 'yxs_yujix', - 'simayi', - 'huatuo', - 'huangyueying', - 'zhouyu', - 'sunshangxiang', - 're_weiyan', - 'guanqiujian', - 'zhanghe', - 'caiwenji', - 're_xiahouyuan', - 'yl_yuanshu', - 'sunliang', - 're_pangde', - 'zuoci', - 'wangji', - 'jiaxu', - 'liushan', - 'zhangzhang', - 'yanjun', - 're_jsp_pangtong', - 'handang', - 're_zhangchunhua', - 'xunyou', - 'yufan', - 're_chengong', - 'chengong', - 'bulianshi', - 'dc_bulianshi', - 'fuhuanghou', - 'manchong', - 'chenqun', - 'yj_jushou', - 'xiahoushi', - 'zhoucang', - 'gaoshun', - 'caozhen', - 'zhangyi', - 'gongsunyuan', - 'guotufengji', - 'xin_liru', - 'old_liyan', - 'cenhun', - 'huanghao', - 'sunziliufang', - 'ol_zhangliao', - 'shen_lvmeng', - 'shen_zhouyu', - 'zhanggong', - 'weiwenzhugezhi', - 'liuhong', - 'zhujun', - 'zhangji', - 'xf_sufei', - 'xugong', - 'sp_shenpei', - 'xunchen', - 'sp_zhanghe', - 'sp_xuyou', - 'lvkuanglvxiang', - 'wulan', - 're_sunben', - 'hujinding', - 'dc_hujinding', - 'dongcheng', - 'taoqian', - 'chendeng', - 'xin_xiahoudun', - 're_jikang', - 'dc_jikang', - 'zhuling', - 'zhaotongzhaoguang', - 'simazhao', - 're_xiahoudun', - 're_machao', - 're_zhangfei', - 're_zhaoyun', - 're_zhouyu', - 're_ganning', - 're_huangyueying', - 're_zhenji', - 'xin_yuji', - 're_taishici', - 're_yanwen', - 'ol_sunjian', - 're_caopi', - 're_xuhuang', - 'ol_dongzhuo', - 're_dengai', - 're_jiangwei', - 're_caiwenji', - 'ol_liushan', - 're_zhangzhang', - 're_masu', - 'old_madai', - 're_madai', - 'wangyi', - 'guanzhang', - 're_guanzhang', - 'ns_chengpu', - 're_sunluban', - 're_caoxiu', - 'xin _caoxiu', - 'sunluyu', - 'mb_sunluyu', - 'sp_diaochan', - 'liuxie', - 'zhugejin', - 'guanyinping', - 'yangxiu', - 'sp_caiwenji', - 'sp_jiangwei', - 'dc_sp_machao', - 'yanbaihu', - 'jsp_huangyueying', - 'zumao', - 'wenpin', - 'zhangling', - 'guotu', - 'caoshuang', - 'fuwan', - 'litong', - 'mizhu', - 'dongbai', - 'sp_lvmeng', - 'sp_zhangfei', - 'sp_simazhao', - 'jianggan', - 'yj_chendao', - 'yj_caoang', - 'xin_hansui', - 'ns_caimao', - 'sp_zhangliao', - 'xinxianying', - 'sp_bianfuren', - 'tw_bianfuren', - 'key_haruko', - 'key_rei', - 'key_komari', - 'key_yoshino', - 'key_sasami', - 'key_doruji', - 'key_noda', - 'key_tomoya', - 'key_ayato', - 'key_kaori', - 'key_akiko', - 'key_abyusa', - 'key_asara', - 'ns_sunchensunjun', - 'simashi', - 'xin_panzhangmazhong', - 're_xiaoqiao', - 'caoanmin', - 'luyusheng', - 'dingfeng', - 'huangzu', - 'jin_yanghuiyu', - 'sp_mifuren', - 'sp_xinpi', - 'cheliji', - 'shibao', - 'zhangmiao', - 'ol_zhurong', - 'sp_mifangfushiren', - 'zhangheng', - 're_hucheer', - 're_guanping', - 'feiyi', - 'xiangchong', - 'qiuliju', - 're_dongbai', - 'xin_guyong', - 'duosidawang', - 're_jiaxu', - 'xin_caozhen', - 'ol_dengzhi', - 'sundeng', - 're_sundeng', - 're_duji', - 'sp_chendong', - 'sp_zongyu', - 'old_yangyan', - 'zuofen', - 're_kanze', - 'tongyuan', - 'zhangning', - 'sp_huaman', - 'sp_wangshuang', - 'yanpu', - 'sp_jiangqing', - 'tw_hejin', - 'xuangongzhu', - 'sp_huangfusong', - 'yj_huangzhong', - 're_xiahoushi', - 'sp_yangwan', - 'wangtao', - 'tianyu', - 'fanjiangzhangda', - 'zhaoyan', - 'huojun', - 'tw_caocao', - 'xin_wuguotai', - 'dc_xushu', - 'dc_jiben', - 'ol_caiwenji', - 'dc_gaolan', - 'liuba', - 'jin_guohuai', - 'tw_tianyu', - 'zhangyao', - 'sb_huaxiong', - 'shen_sunquan', - 're_jushou', - 'dc_huangzu', - 'dc_liuyu', - 'qinyilu', - 'zhaoyǎn', - 'zhangxun', - 'xiahoulingnv', - 're_sp_taishici', - 'dc_lvkuanglvxiang', - 'dengzhong', - 'dc_liru', - 'kebineng', - 'wangwei', - 'zhangzhi', - 'clan_xuncan', - 'clan_xunshu', - 'sunlang', - 'yangfu', - 'sp_pengyang', - 'tw_caoxiu', - 'tw_chendong', - 'tw_feiyi', - 'tw_fengxí', - 'tw_guyong', - 'tw_huchuquan', - 'tw_jianshuo', - 'dc_jiling', - 'tw_jiling', - 'tw_liufuren', - 'tw_madai', - 'tw_sunyi', - 'tw_xuezong', - 'tw_yufuluo', - 'tw_zongyu', - 'xia_xushu', - 'clan_hanrong', - 'clan_hanshao', - 'ns_duji', - 'yj_weiyan', - 'dc_sunziliufang', - 'maxiumatie', - 'chendao', - 'quhuang', - 'xia_xiahouzie', - 'xielingyu', - 'ol_yanwen', - 'sp_mushun', - 'tw_yangang', - 'sb_zhurong', - 'vtb_xiaoshan', - 'vtb_xiaotao', - 'zhangchu', - 'chentai', - 'clan_zhongyan', - 'sb_zhurong', - 'haopu', - 'xizheng', - 'dc_duyu', - 'clan_wanghun', - 'jsrg_chendeng', - 'jsrg_zhanghe', - 'jsrg_zoushi', - 'gaoxiang', - 'ol_qianzhao', - 'yj_zhoubuyi', - 'feiyao', - 'jsrg_xiahouen', - 'old_shen_zhaoyun', - 'sb_qiaoxiao', - 're_simalang', - 'laimin', - 'baoxin', - 'mb_xianglang', - 'lvboshe', - 'ol_caozhang', - 'ol_lingtong', - 'jsrg_liuyong', - 'jsrg_sunjun', - 'xia_shie', - 'clan_wangmingshan', + b: [ + "junk_guanyu", + "liyi", + "diy_feishi", + "diy_liufu", + "diy_tianyu", + "diy_yuji", + "hs_huzhixiannv", + "hs_jiawodun", + "hs_jinglinglong", + "hs_shirencao", + "hs_yelinchulong", + "pal_linyueru", + "swd_fu", + "swd_hanluo", + "swd_jialanduo", + "swd_luchengxuan", + "swd_youzhao", + "swd_zhanggao", + "yxs_baosi", + "yxs_chengjisihan", + "yxs_chengyaojin", + "yxs_lishimin", + "yxs_lvzhi", + "yxs_mingchenghuanghou", + "yxs_tangbohu", + "yxs_weizhongxian", + "yxs_yujix", + "simayi", + "huatuo", + "huangyueying", + "zhouyu", + "sunshangxiang", + "re_weiyan", + "guanqiujian", + "zhanghe", + "caiwenji", + "re_xiahouyuan", + "yl_yuanshu", + "sunliang", + "re_pangde", + "zuoci", + "wangji", + "jiaxu", + "liushan", + "zhangzhang", + "yanjun", + "re_jsp_pangtong", + "handang", + "re_zhangchunhua", + "xunyou", + "yufan", + "re_chengong", + "chengong", + "bulianshi", + "dc_bulianshi", + "fuhuanghou", + "manchong", + "chenqun", + "yj_jushou", + "xiahoushi", + "zhoucang", + "gaoshun", + "caozhen", + "zhangyi", + "gongsunyuan", + "guotufengji", + "xin_liru", + "old_liyan", + "cenhun", + "huanghao", + "sunziliufang", + "ol_zhangliao", + "shen_lvmeng", + "shen_zhouyu", + "zhanggong", + "weiwenzhugezhi", + "liuhong", + "zhujun", + "zhangji", + "xf_sufei", + "xugong", + "sp_shenpei", + "xunchen", + "sp_zhanghe", + "sp_xuyou", + "lvkuanglvxiang", + "wulan", + "re_sunben", + "hujinding", + "dc_hujinding", + "dongcheng", + "taoqian", + "chendeng", + "xin_xiahoudun", + "re_jikang", + "dc_jikang", + "zhuling", + "zhaotongzhaoguang", + "simazhao", + "re_xiahoudun", + "re_machao", + "re_zhangfei", + "re_zhaoyun", + "re_zhouyu", + "re_ganning", + "re_huangyueying", + "re_zhenji", + "xin_yuji", + "re_taishici", + "re_yanwen", + "ol_sunjian", + "re_caopi", + "re_xuhuang", + "ol_dongzhuo", + "re_dengai", + "re_jiangwei", + "re_caiwenji", + "ol_liushan", + "re_zhangzhang", + "re_masu", + "old_madai", + "re_madai", + "wangyi", + "guanzhang", + "re_guanzhang", + "ns_chengpu", + "re_sunluban", + "re_caoxiu", + "xin _caoxiu", + "sunluyu", + "mb_sunluyu", + "sp_diaochan", + "liuxie", + "zhugejin", + "guanyinping", + "yangxiu", + "sp_caiwenji", + "sp_jiangwei", + "dc_sp_machao", + "yanbaihu", + "jsp_huangyueying", + "zumao", + "wenpin", + "zhangling", + "guotu", + "caoshuang", + "fuwan", + "litong", + "mizhu", + "dongbai", + "sp_lvmeng", + "sp_zhangfei", + "sp_simazhao", + "jianggan", + "yj_chendao", + "yj_caoang", + "xin_hansui", + "ns_caimao", + "sp_zhangliao", + "xinxianying", + "sp_bianfuren", + "tw_bianfuren", + "key_haruko", + "key_rei", + "key_komari", + "key_yoshino", + "key_sasami", + "key_doruji", + "key_noda", + "key_tomoya", + "key_ayato", + "key_kaori", + "key_akiko", + "key_abyusa", + "key_asara", + "ns_sunchensunjun", + "simashi", + "xin_panzhangmazhong", + "re_xiaoqiao", + "caoanmin", + "luyusheng", + "dingfeng", + "huangzu", + "jin_yanghuiyu", + "sp_mifuren", + "sp_xinpi", + "cheliji", + "shibao", + "zhangmiao", + "ol_zhurong", + "sp_mifangfushiren", + "zhangheng", + "re_hucheer", + "re_guanping", + "feiyi", + "xiangchong", + "qiuliju", + "re_dongbai", + "xin_guyong", + "duosidawang", + "re_jiaxu", + "xin_caozhen", + "ol_dengzhi", + "sundeng", + "re_sundeng", + "re_duji", + "sp_chendong", + "sp_zongyu", + "old_yangyan", + "zuofen", + "re_kanze", + "tongyuan", + "zhangning", + "sp_huaman", + "sp_wangshuang", + "yanpu", + "sp_jiangqing", + "tw_hejin", + "xuangongzhu", + "sp_huangfusong", + "yj_huangzhong", + "re_xiahoushi", + "sp_yangwan", + "wangtao", + "tianyu", + "fanjiangzhangda", + "zhaoyan", + "huojun", + "tw_caocao", + "xin_wuguotai", + "dc_xushu", + "dc_jiben", + "ol_caiwenji", + "dc_gaolan", + "liuba", + "jin_guohuai", + "tw_tianyu", + "zhangyao", + "sb_huaxiong", + "shen_sunquan", + "re_jushou", + "dc_huangzu", + "dc_liuyu", + "qinyilu", + "zhaoyǎn", + "zhangxun", + "xiahoulingnv", + "re_sp_taishici", + "dc_lvkuanglvxiang", + "dengzhong", + "dc_liru", + "kebineng", + "wangwei", + "zhangzhi", + "clan_xuncan", + "clan_xunshu", + "sunlang", + "yangfu", + "sp_pengyang", + "tw_caoxiu", + "tw_chendong", + "tw_feiyi", + "tw_fengxí", + "tw_guyong", + "tw_huchuquan", + "tw_jianshuo", + "dc_jiling", + "tw_jiling", + "tw_liufuren", + "tw_madai", + "tw_sunyi", + "tw_xuezong", + "tw_yufuluo", + "tw_zongyu", + "xia_xushu", + "clan_hanrong", + "clan_hanshao", + "ns_duji", + "yj_weiyan", + "dc_sunziliufang", + "maxiumatie", + "chendao", + "quhuang", + "xia_xiahouzie", + "xielingyu", + "ol_yanwen", + "sp_mushun", + "tw_yangang", + "sb_zhurong", + "vtb_xiaoshan", + "vtb_xiaotao", + "zhangchu", + "chentai", + "clan_zhongyan", + "sb_zhurong", + "haopu", + "xizheng", + "dc_duyu", + "clan_wanghun", + "jsrg_chendeng", + "jsrg_zhanghe", + "jsrg_zoushi", + "gaoxiang", + "ol_qianzhao", + "yj_zhoubuyi", + "feiyao", + "jsrg_xiahouen", + "old_shen_zhaoyun", + "sb_qiaoxiao", + "re_simalang", + "laimin", + "baoxin", + "mb_xianglang", + "lvboshe", + "ol_caozhang", + "ol_lingtong", + "jsrg_liuyong", + "jsrg_sunjun", + "xia_shie", + "clan_wangmingshan", ], - bm:[ - 'kongrong', - 'diy_xizhenxihong', - 'ns_nanhua_left', - 'ns_nanhua_right', - 'ns_wenchou', - 'yxs_goujian', - 'machao', - 'ganning', - 'caocao', - 'huangzhong', - 'xuhuang', - 'old_chendao', - 'dongzhuo', - 'taishici', - 'yanwen', - 'menghuo', - 'sp_zhugeliang', - 'jiangwei', - 'dengai', - 'sunce', - 'sunjian', - 'zhurong', - 'xin_zhoutai', - 'old_caoren', - 'pangtong', - 'yanyan', - 'sp_zhangjiao', - 're_yuji', - 'wangcan', - 'xuezong', - 'caozhi', - 'zhonghui', - 'wuyi', - 'caifuren', - 'lingtong', - 'sunxiu', - 'quancong', - 'guohuanghou', - 'fazheng', - 'guanping', - 'old_guanzhang', - 'old_wangyi', - 'zhuran', - 'xusheng', - 'wuguotai', - 'jianyong', - 'shen_zhangliao', - 'lvkai', - 'xinpi', - 'mangyachang', - 'xin_baosanniang', - 're_sunluyu', - 'wangshuang', - 'xingdaorong', - 'fanchou', - 'guosi', - 'xf_huangquan', - 'xin_caozhang', - 're_heqi', - 're_sp_zhugeliang', - 're_liushan', - 're_pangtong', - 'xin_yuanshao', - 'liuye', - 're_weiwenzhugezhi', - 'xin_jianyong', - 're_sunjian', - 'old_bulianshi', - 're_guanqiujian', - 'shenpei', - 're_baosanniang', - 're_xugong', - 're_simayi', - 'old_re_lidian', - 're_xuzhu', - 're_xushu', - 're_lvmeng', - 're_luxun', - 're_huatuo', - 're_huaxiong', - 're_gongsunzan', - 'ol_xiaoqiao', - 'ol_sp_zhugeliang', - 're_dianwei', - 're_sunce', - 'ol_dengai', - 're_wuguotai', - 're_gaoshun', - 'ol_gaoshun', - 're_caozhi', - 're_lingtong', - 'xin_xusheng', - 'xin_fazheng', - 're_handang', - 're_liaohua', - 're_caozhang', - 're_guohuai', - 'xin_guohuai', - 're_panzhangmazhong', - 're_quancong', - 'jsp_guanyu', - 'caohong', - 'xiahouba', - 'simalang', - 'sp_sunshangxiang', - 'mayunlu', - 'zhanglu', - 'wutugu', - 'zhugeguo', - 'daxiaoqiao', - 'dc_daxiaoqiao', - 'sp_pangde', - 'sp_jiaxu', - 'dc_sp_jiaxu', - 'kanze', - 'heqi', - 'wangyun', - 'dc_wangyun', - 'sunqian', - 'xujing', - 'baosanniang', - 'cuiyan', - 'sp_daqiao', - 'sp_ganning', - 'sp_xiahoudun', - 'sp_liubei', - 'sp_gongsunzan', - 'ganfuren', - 'yuejin', - 'hetaihou', - 'niujin', - 'ns_lijue', - 'ns_zhangji', - 'ol_dingyuan', - 'hucheer', - 'jin_xiahouhui', - 'xin_zhangfei', - 'xin_fuhuanghou', - 'zhaozhong', - 'zongyu', - 'simazhou', - 'sp_fuhuanghou', - 'sp_jiben', - 'sp_fuwan', - 're_chengpu', - 'ol_chengpu', - 're_niujin', - 'wangfuzhaolei', - 'caizhenji', - 'longyufei', - 'sp_zhangwen', - 're_zoushi', - 'yuejiu', - 'dc_yuejiu', - 'xin_sunluban', - 'ol_bianfuren', - 'sp_ol_zhanghe', - 'liucheng', - 'peixiu', - 'haomeng', - 'mamidi', - 'tw_wujing', - 'dc_zhuling', - 'tw_puyangxing', - 'ruanhui', - 'xin_mamidi', - 'xin_quancong', - 'dc_caiyang', - 're_caiyong', - 'liyixiesheng', - 'panghui', - 'leibo', - 'dongguiren', - 'tw_daxiaoqiao', - 'tw_fanchou', - 'tw_qiaorui', - 'tw_weixu', - 'tw_xujing', - 'tw_yangyi', - 'tw_zhouchu', - 'tw_zhugeguo', - 'dc_caozhi', - 'hanlong', - 'oldre_liubiao', - 'wuanguo', - 'qiaorui', - 'clan_wukuang', - 'yeshiwen', - 'qianzhao', - 'vtb_xiaosha', - 'huanfan', - 'jsrg_xugong', - 'old_xiaoqiao', - 'old_guanyu', - 'dc_kongrong', + bm: [ + "kongrong", + "diy_xizhenxihong", + "ns_nanhua_left", + "ns_nanhua_right", + "ns_wenchou", + "yxs_goujian", + "machao", + "ganning", + "caocao", + "huangzhong", + "xuhuang", + "old_chendao", + "dongzhuo", + "taishici", + "yanwen", + "menghuo", + "sp_zhugeliang", + "jiangwei", + "dengai", + "sunce", + "sunjian", + "zhurong", + "xin_zhoutai", + "old_caoren", + "pangtong", + "yanyan", + "sp_zhangjiao", + "re_yuji", + "wangcan", + "xuezong", + "caozhi", + "zhonghui", + "wuyi", + "caifuren", + "lingtong", + "sunxiu", + "quancong", + "guohuanghou", + "fazheng", + "guanping", + "old_guanzhang", + "old_wangyi", + "zhuran", + "xusheng", + "wuguotai", + "jianyong", + "shen_zhangliao", + "lvkai", + "xinpi", + "mangyachang", + "xin_baosanniang", + "re_sunluyu", + "wangshuang", + "xingdaorong", + "fanchou", + "guosi", + "xf_huangquan", + "xin_caozhang", + "re_heqi", + "re_sp_zhugeliang", + "re_liushan", + "re_pangtong", + "xin_yuanshao", + "liuye", + "re_weiwenzhugezhi", + "xin_jianyong", + "re_sunjian", + "old_bulianshi", + "re_guanqiujian", + "shenpei", + "re_baosanniang", + "re_xugong", + "re_simayi", + "old_re_lidian", + "re_xuzhu", + "re_xushu", + "re_lvmeng", + "re_luxun", + "re_huatuo", + "re_huaxiong", + "re_gongsunzan", + "ol_xiaoqiao", + "ol_sp_zhugeliang", + "re_dianwei", + "re_sunce", + "ol_dengai", + "re_wuguotai", + "re_gaoshun", + "ol_gaoshun", + "re_caozhi", + "re_lingtong", + "xin_xusheng", + "xin_fazheng", + "re_handang", + "re_liaohua", + "re_caozhang", + "re_guohuai", + "xin_guohuai", + "re_panzhangmazhong", + "re_quancong", + "jsp_guanyu", + "caohong", + "xiahouba", + "simalang", + "sp_sunshangxiang", + "mayunlu", + "zhanglu", + "wutugu", + "zhugeguo", + "daxiaoqiao", + "dc_daxiaoqiao", + "sp_pangde", + "sp_jiaxu", + "dc_sp_jiaxu", + "kanze", + "heqi", + "wangyun", + "dc_wangyun", + "sunqian", + "xujing", + "baosanniang", + "cuiyan", + "sp_daqiao", + "sp_ganning", + "sp_xiahoudun", + "sp_liubei", + "sp_gongsunzan", + "ganfuren", + "yuejin", + "hetaihou", + "niujin", + "ns_lijue", + "ns_zhangji", + "ol_dingyuan", + "hucheer", + "jin_xiahouhui", + "xin_zhangfei", + "xin_fuhuanghou", + "zhaozhong", + "zongyu", + "simazhou", + "sp_fuhuanghou", + "sp_jiben", + "sp_fuwan", + "re_chengpu", + "ol_chengpu", + "re_niujin", + "wangfuzhaolei", + "caizhenji", + "longyufei", + "sp_zhangwen", + "re_zoushi", + "yuejiu", + "dc_yuejiu", + "xin_sunluban", + "ol_bianfuren", + "sp_ol_zhanghe", + "liucheng", + "peixiu", + "haomeng", + "mamidi", + "tw_wujing", + "dc_zhuling", + "tw_puyangxing", + "ruanhui", + "xin_mamidi", + "xin_quancong", + "dc_caiyang", + "re_caiyong", + "liyixiesheng", + "panghui", + "leibo", + "dongguiren", + "tw_daxiaoqiao", + "tw_fanchou", + "tw_qiaorui", + "tw_weixu", + "tw_xujing", + "tw_yangyi", + "tw_zhouchu", + "tw_zhugeguo", + "dc_caozhi", + "hanlong", + "oldre_liubiao", + "wuanguo", + "qiaorui", + "clan_wukuang", + "yeshiwen", + "qianzhao", + "vtb_xiaosha", + "huanfan", + "jsrg_xugong", + "old_xiaoqiao", + "old_guanyu", + "dc_kongrong", ], - c:[ - 'xiahoudun', - 'zhaoyun', - 'huanggai', - 'luxun', - 'lvbu', - 'guanyu', - 'zhangfei', - 'yl_luzhi', - 'lvqian', - 're_zhangliang', - 'sp_taishici', - 'liuyao', - 'panzhangmazhong', - 'caiyong', - 'caoxiu', - 'caozhang', - 'caojie', - 'hanhaoshihuan', - 'liaohua', - 'sunluban', - 'xin_xushu', - 'madai', - 'lisu', - 're_hejin', - 'hansui', - 'gaolan', - 'furong', - 'yangyi', - 'dengzhi', - 'yj_zhangliao', - 'yj_zhanghe', - 'xin_gongsunzan', - 're_dongzhuo', - 'old_yuanshu', - 're_hanhaoshihuan', - 'lingju', - 'panfeng', - 'hanba', - 'ns_fanchou', - 'zhangchunhua', - 'weiguan', - 're_chenqun', - 'sp_huaxin', - 'sp_xujing', - 'caimaozhangyun', - 'ahuinan', - 'mushun', - 'tw_dengzhi', - 'tw_furong', - 'tw_niujin', - 'tw_zhangnan', - 'macheng', - 'old_caorui', - 'old_dingfeng', - 'old_gaoshun', - 'old_huanghao', - 'old_liubiao', - 'luoxian', - 'ol_huban', - 'sb_menghuo', - 'old_caocao', - 'sb_yl_luzhi', + c: [ + "xiahoudun", + "zhaoyun", + "huanggai", + "luxun", + "lvbu", + "guanyu", + "zhangfei", + "yl_luzhi", + "lvqian", + "re_zhangliang", + "sp_taishici", + "liuyao", + "panzhangmazhong", + "caiyong", + "caoxiu", + "caozhang", + "caojie", + "hanhaoshihuan", + "liaohua", + "sunluban", + "xin_xushu", + "madai", + "lisu", + "re_hejin", + "hansui", + "gaolan", + "furong", + "yangyi", + "dengzhi", + "yj_zhangliao", + "yj_zhanghe", + "xin_gongsunzan", + "re_dongzhuo", + "old_yuanshu", + "re_hanhaoshihuan", + "lingju", + "panfeng", + "hanba", + "ns_fanchou", + "zhangchunhua", + "weiguan", + "re_chenqun", + "sp_huaxin", + "sp_xujing", + "caimaozhangyun", + "ahuinan", + "mushun", + "tw_dengzhi", + "tw_furong", + "tw_niujin", + "tw_zhangnan", + "macheng", + "old_caorui", + "old_dingfeng", + "old_gaoshun", + "old_huanghao", + "old_liubiao", + "luoxian", + "ol_huban", + "sb_menghuo", + "old_caocao", + "sb_yl_luzhi", ], - d:[ - 'chendong', - 'lvmeng', - 'huaxiong', - 'gongsunzan', - 'xuzhu', - 'old_huaxiong', - 'chengpu', - 'zhangwen', - 'dingyuan', - 'xin_chengpu', - 'sunshao', - 'tadun', - 'zangba', - 'junk_zhangrang', - 'ol_guohuai', - 'junk_simayi', - 'key_youta', - 'old_chenqun', - 'duanwei', - 'wangxiang', - 'duji', - 'bianxi', - 'junk_sunquan', - 'clan_wuban', - 'wangjun', - 'xin_wuyi', - 'xin_zhuzhi', - 'tw_guanqiujian', - 'tw_xiahouen', - 'tw_yl_luzhi', - 'junk_huangyueying', - 'junk_liubei', - 'new_caoren', - 'old_handang', - 'old_zhoutai', - 'tengfanglan', - 'junk_lidian', - 'junk_duanwei', - 'std_panfeng', - 'qianzhao', + d: [ + "chendong", + "lvmeng", + "huaxiong", + "gongsunzan", + "xuzhu", + "old_huaxiong", + "chengpu", + "zhangwen", + "dingyuan", + "xin_chengpu", + "sunshao", + "tadun", + "zangba", + "junk_zhangrang", + "ol_guohuai", + "junk_simayi", + "key_youta", + "old_chenqun", + "duanwei", + "wangxiang", + "duji", + "bianxi", + "junk_sunquan", + "clan_wuban", + "wangjun", + "xin_wuyi", + "xin_zhuzhi", + "tw_guanqiujian", + "tw_xiahouen", + "tw_yl_luzhi", + "junk_huangyueying", + "junk_liubei", + "new_caoren", + "old_handang", + "old_zhoutai", + "tengfanglan", + "junk_lidian", + "junk_duanwei", + "std_panfeng", + "qianzhao", ], - rarity:{ - legend:[ - 'star_caoren', - 'dc_zhaoyun', - 'dc_caocao', - 'dc_liubei', - 'dc_sunquan', - 'dc_sunce', - 'xia_yuzhenzi', - 'xia_guanyu', - 'ol_sb_yuanshao', - 'swd_muyun', - 'swd_zhaoyun', - 'swd_septem', - 'swd_yuwentuo', - 'swd_duguningke', - 'swd_guyue', - 'swd_yuxiaoxue', - 'swd_huanglei', - 'swd_xuanyuanjianxian', - 'swd_qi', - 'swd_huzhongxian', - 'swd_murongshi', - 'swd_huiyan', - 'gjqt_aruan', - 'hs_neptulon', - 'hs_sthrall', - 'hs_malorne', - 'hs_medivh', - 'hs_pyros', - 'hs_siwangzhiyi', - 'hs_aya', - 'hs_kazhakusi', - 'hs_malygos', - 'hs_ysera', - 'pal_liumengli', - 'pal_yuntianhe', - 'gw_jieluote', - 'gw_yenaifa', - 'gw_telisi', - 'gw_xili', - 'yxs_wuzetian', - 'diy_caiwenji', - 'shen_caocao', - 'shen_lvbu', - 'shen_zhaoyun', - 'shen_simayi', - 'shen_liubei', - 'shen_luxun', - 'shen_zhangliao', - 'shen_ganning', - 'shen_caopi', - 'shen_zhenji', - 'key_shiki', - 'key_kagari', - 'ol_zhangliao', - 'shen_diaochan', - 'guansuo', - 'xin_baosanniang', - 're_baosanniang', - 'baosanniang', - 'caoying', - 'caoshuang', - 'caochun', - 'wanglang', - 'yuantanyuanshang', - 'xurong', - 're_liuzan', - 'zhaoxiang', - 'dc_zhaoxiang', - 'liuyan', - 'miheng', - 'majun', - 'pangdegong', - 'yangbiao', - 'zhangqiying', - 'chunyuqiong', - 'lingju', - 'simahui', - 'sp_xiahoushi', - 'sp_pangtong', - 'shixie', - 'dc_shixie', - 'guohuai', - 're_zuoci', - 'ns_zhangwei', - 'ol_yuanshao', - 'guozhao', - 'boss_zhaoyun', - 'yanghuiyu', - 'nanhualaoxian', - 'panshu', - 're_nanhualaoxian', - 'shen_sunce', - 'sunhanhua', - 'caojinyu', - 're_fengfangnv', - 'key_yuri', - 'key_yuzuru', - 'sp_key_kanade', - 'key_iwasawa', - 'key_yui', - 'key_misuzu', - 'key_nagisa', - 'key_kud', - 'key_saya', - 'key_kyousuke', - 'key_umi', - 'key_nao', - 'key_yuu', - 'sp_key_yuri', - 'key_abyusa', - 'key_ayato', - 'key_godan', - 're_machao', - 're_sunben', - 'ol_dingyuan', - 'wujing', - 'yangwan', - 're_sunyi', - 'shen_guojia', - 'shen_taishici', - 'shen_xunyu', - 'tw_gexuan', - 'fengfangnv', - 'zhangmancheng', - 'guanning', - 'shen_jiangwei', - 'ol_puyuan', - 'sb_huangzhong', - 'shen_sunquan', - 'shen_machao', - 'tw_shen_guanyu', - 'huojun', - 'quanhuijie', - 'clan_wuxian', - 'luyi', - 'shen_zhangfei', - 'clan_xuncai', - 'wanglie', - 'zhujianping', - 'zhaozhi', - 'liuhui', - 'shen_zhangjiao', - 'sb_machao', - 'dc_zhouxuān', - 'dc_tengfanglan', - 're_lidian', - 'tw_jiangji', - 'tw_niufudongxie', - 'tw_shen_lvmeng', - 'zhangjinyun', - 'sunwukong', - 'libai', - 'old_lingju', - 'wu_zhugeliang', - 'yue_caiwenji', - 'clan_zhongyan', - 'shen_dianwei', - 'sunlingluan', - 'ol_zhouqun', - 'wu_luxun', - 'key_tomoya', - 'key_masato', - 'key_shiorimiyuki', - 'key_hisako', - 'key_hinata', - 'key_kotori', - 'key_inari', - 'key_kamome', - 'key_noda', - 'key_shiina', - 'key_shiroha', - 'db_key_hina', - 'key_sakuya', - 'key_yuuki', - 'key_kyouko', - 'key_tenzen', - 'key_kotarou', - 'key_kyou', - 'key_erika', - 'key_satomi', - 'key_seira', - 'key_kiyu', - 'key_tomoyo', - 'key_minagi', - 'key_michiru', - 'noname', - 'ol_wanglang', - 'xin_guozhao', - 'shichangshi', - 'dc_guansuo', - 'dc_xujing', - 'caoxian', + rarity: { + legend: [ + "sp_sunce", + "star_caoren", + "dc_zhaoyun", + "dc_caocao", + "dc_liubei", + "dc_sunquan", + "dc_sunce", + "xia_yuzhenzi", + "xia_guanyu", + "ol_sb_yuanshao", + "swd_muyun", + "swd_zhaoyun", + "swd_septem", + "swd_yuwentuo", + "swd_duguningke", + "swd_guyue", + "swd_yuxiaoxue", + "swd_huanglei", + "swd_xuanyuanjianxian", + "swd_qi", + "swd_huzhongxian", + "swd_murongshi", + "swd_huiyan", + "gjqt_aruan", + "hs_neptulon", + "hs_sthrall", + "hs_malorne", + "hs_medivh", + "hs_pyros", + "hs_siwangzhiyi", + "hs_aya", + "hs_kazhakusi", + "hs_malygos", + "hs_ysera", + "pal_liumengli", + "pal_yuntianhe", + "gw_jieluote", + "gw_yenaifa", + "gw_telisi", + "gw_xili", + "yxs_wuzetian", + "diy_caiwenji", + "shen_caocao", + "shen_lvbu", + "shen_zhaoyun", + "shen_simayi", + "shen_liubei", + "shen_luxun", + "shen_zhangliao", + "shen_ganning", + "shen_caopi", + "shen_zhenji", + "key_shiki", + "key_kagari", + "ol_zhangliao", + "shen_diaochan", + "guansuo", + "xin_baosanniang", + "re_baosanniang", + "baosanniang", + "caoying", + "caoshuang", + "caochun", + "wanglang", + "yuantanyuanshang", + "xurong", + "re_liuzan", + "zhaoxiang", + "dc_zhaoxiang", + "liuyan", + "miheng", + "majun", + "pangdegong", + "yangbiao", + "zhangqiying", + "chunyuqiong", + "lingju", + "simahui", + "sp_xiahoushi", + "sp_pangtong", + "shixie", + "dc_shixie", + "guohuai", + "re_zuoci", + "ns_zhangwei", + "ol_yuanshao", + "guozhao", + "boss_zhaoyun", + "yanghuiyu", + "nanhualaoxian", + "panshu", + "re_nanhualaoxian", + "shen_sunce", + "sunhanhua", + "caojinyu", + "re_fengfangnv", + "key_yuri", + "key_yuzuru", + "sp_key_kanade", + "key_iwasawa", + "key_yui", + "key_misuzu", + "key_nagisa", + "key_kud", + "key_saya", + "key_kyousuke", + "key_umi", + "key_nao", + "key_yuu", + "sp_key_yuri", + "key_abyusa", + "key_ayato", + "key_godan", + "re_machao", + "re_sunben", + "ol_dingyuan", + "wujing", + "yangwan", + "re_sunyi", + "shen_guojia", + "shen_taishici", + "shen_xunyu", + "tw_gexuan", + "fengfangnv", + "zhangmancheng", + "guanning", + "shen_jiangwei", + "ol_puyuan", + "sb_huangzhong", + "shen_sunquan", + "shen_machao", + "tw_shen_guanyu", + "huojun", + "quanhuijie", + "clan_wuxian", + "luyi", + "shen_zhangfei", + "clan_xuncai", + "wanglie", + "zhujianping", + "zhaozhi", + "liuhui", + "shen_zhangjiao", + "sb_machao", + "dc_zhouxuān", + "dc_tengfanglan", + "re_lidian", + "tw_jiangji", + "tw_niufudongxie", + "tw_shen_lvmeng", + "zhangjinyun", + "sunwukong", + "libai", + "old_lingju", + "wu_zhugeliang", + "yue_caiwenji", + "clan_zhongyan", + "shen_dianwei", + "sunlingluan", + "ol_zhouqun", + "wu_luxun", + "key_tomoya", + "key_masato", + "key_shiorimiyuki", + "key_hisako", + "key_hinata", + "key_kotori", + "key_inari", + "key_kamome", + "key_noda", + "key_shiina", + "key_shiroha", + "db_key_hina", + "key_sakuya", + "key_yuuki", + "key_kyouko", + "key_tenzen", + "key_kotarou", + "key_kyou", + "key_erika", + "key_satomi", + "key_seira", + "key_kiyu", + "key_tomoyo", + "key_minagi", + "key_michiru", + "noname", + "ol_wanglang", + "xin_guozhao", + "shichangshi", + "dc_guansuo", + "dc_xujing", + "caoxian", + "wu_guanyu", ], - epic:[ - 'dc_caoshuang', - 'tianchou', - 'star_yuanshao', - 'yue_xiaoqiao', - 'yue_daqiao', - 'mb_chengui', - 'ol_pengyang', - 'ol_luyusheng', - 'clan_xunchen', - 'peiyuanshao', - 'tw_zhangzhao', - 'tw_zhanghong', - 'tw_ol_sunjian', - 'yj_huangzhong', - 'clan_zhongyu', - 'zhoushan', - 'pal_yueqi', - 'pal_yuejinzhao', - 'pal_mingxiu', - 'pal_xuanxiao', - 'pal_zixuan', - 'pal_xuejian', - 'pal_murongziying', - 'pal_lixiaoyao', - 'pal_xingxuan', - 'hs_tyrande', - 'hs_amala', - 'hs_alextrasza', - 'hs_totemic', - 'hs_bchillmaw', - 'hs_aedwin', - 'hs_antonidas', - 'hs_wvelen', - 'hs_alakir', - 'hs_xsylvanas', - 'hs_blingtron', - 'hs_fuding', - 'hs_lafamu', - 'hs_nozdormu', - 'hs_jiaziruila', - 'hs_yelise', - 'hs_xuefashi', - 'hs_liadrin', - 'yxs_libai', - 'yxs_luban', - 'yxs_yangyuhuan', - 'yxs_guiguzi', - 'yxs_aijiyanhou', - 'swd_shuwaner', - 'swd_kendi', - 'swd_weida', - 'swd_lilian', - 'swd_jipeng', - 'swd_cheyun', - 'swd_tuobayuer', - 'swd_jiliang', - 'swd_muyue', - 'swd_lanyin', - 'swd_chenjingchou', - 'swd_kama', - 'swd_anka', - 'swd_huanyuanzhi', - 'swd_kangnalishi', - 'swd_zhiyin', - 'swd_xiarou', - 'swd_wangsiyue', - 'swd_qiner', - 'gjqt_fanglansheng', - 'gjqt_fengqingxue', - 'gjqt_xiayize', - 'gjqt_bailitusu', - 'gjqt_ouyangshaogong', - 'gjqt_xunfang', - 'diy_zhenji', - 'ow_yuanshi', - 'ow_tianshi', - 'ow_zhixuzhiguang', - 'gw_aisinie', - 'gw_falanxisika', - 'shen_guanyu', - 'shen_lvmeng', - 'shen_zhugeliang', - 'shen_zhouyu', - 'chenlin', - 'yangxiu', - 'chengyu', - 'zhugeke', - 'guyong', - 'litong', - 'mazhong', - 'simazhao', - 'sp_sufei', - 'taoqian', - 'zhengxuan', - 'yj_ganning', - 're_xusheng', - 'liuzan', - 'lijue', - 'beimihu', - 'zhangchangpu', - 'ol_zhangchangpu', - 'guanlu', - 'gexuan', - 'puyuan', - 'xushao', - 'wenyang', - 'huaman', - 'wangshuang', - 'xizhicai', - 'mayunlu', - 'zhugeguo', - 'sunhao', - 'wangyun', - 'zhangbao', - 'huangfusong', - 'huangjinleishi', - 'sp_liuxie', - 'shamoke', - 'jianggan', - 'wangyuanji', - 're_heqi', - 'tw_beimihu', - 'sp_machao', - 'wutugu', - 'zhangrang', - 'jikang', - 'xushi', - 'machao', - 'sunce', - 're_sunce', - 're_wangyun', - 'zuoci', - 'xuyou', - 'zhangxiu', - 're_zhangjiao', - 're_yuanshao', - 'zhugedan', - 'leitong', - 'wulan', - 'caoxing', - 'diy_wenyang', - 'ns_caoshuang', - 'ns_huangchengyan', - 'ns_sunchensunjun', - 'ns_yuanxi', - 'ns_jiaxu', - 'liubian', - 'simashi', - 'jin_simayi', - 'jin_zhangchunhua', - 'liuhong', - 'jin_wangyuanji', - 'jin_simazhao', - 'jin_xiahouhui', - 'jin_simashi', - 'zhangling', - 'guotu', - 'ns_luyusheng', - 'fanyufeng', - 're_taoqian', - 'caosong', - 'sp_duyu', - 'jin_yanghuiyu', - 'xiahoujie', - 'ruanyu', - 'zhouqun', - 'ns_chentai', - 'ns_huangwudie', - 'ns_sunyi', - 'ns_zhangning', - 'ns_yanghu', - 'ol_huaxin', - 'longyufei', - 're_panshu', - 'db_wenyang', - 'qiaozhou', - 'lvlingqi', - 'wangtao', - 'wangyue', - 're_pangdegong', - 'zhongyan', - 'kaisa', - 'tw_zhaoxiang', - 'tw_caocao', - 'tw_liuhong', - 'tw_caozhao', - 'wufan', - 'dc_luotong', - 'dc_huangchengyan', - 'laiyinger', - 'ns_ruanji', - 'ns_zanghong', - 'caohua', - 'ns_limi', - 'ol_xunyu', - 'ns_zhonglimu', - 'dc_sunru', - 'zhangfen', - 'xiahouxuan', - 'prp_zhugeliang', - 'zhangzhi', - 'ol_liuba', - 'shiyi', - 'yuanji', - 'tw_liuzhang', - 'tw_mateng', - 'dc_wangyun', - 'tw_zhangning', - 'tw_zhugeguo', - 'xuelingyun', - 'dc_zhaotongzhaoguang', - 'mengjie', - 'dc_ruiji', - 'xia_zhaoe', - 'duanqiaoxiao', - 'longwang', - 'taoshen', - 'xiaoyuehankehan', - 'zhutiexiong', - 'sunyang', - 'yeshiwen', - 'ganfurenmifuren', - 'ruanji', - 'zhangxuan', - 'zhangchu', - 'dc_sunhanhua', - 'dc_wangjun', - 'zhanghua', - 'lushi', - 'clan_zhonghui', - 'zhoubuyi', - 'dc_wangjun', - 'ns_mengyou', - 'key_kano', - 'key_haruko', - 'key_akiko', - 'key_sunohara', - 'key_yukine', - 'key_komari', - 'key_rin', - 'key_kengo', - 'key_harukakanata', - 'key_mio', - 'key_midori', - 'key_sasami', - 'key_riki', - 'key_kaori', - 'key_shiori', - 'key_yuiko', - 'key_lucia', - 'key_akane', - 'key_shizuru', - 'key_ao', - 'key_tsumugi', - 'key_kyoko', - 'key_miki', - 'key_rei', - 'key_yusa', - 'key_misa', - 'key_shizuku', - 'key_hiroto', - 'key_rumi', - 'key_chihaya', - 'key_yukito', - 'key_kotomi', - 'db_key_liyingxia', - 'key_iriya', - 'star_dongzhuo', - 'star_yuanshu', - 'clan_xunyou', - 'lvboshe', - 'yj_zhoubuyi', - 'ol_jianyong', - 'ol_sb_jiangwei', - 'dc_sb_zhouyu', - 'xia_shitao', - 'bailingyun', - 'dc_sb_simayi', - 'caofang', - 'mb_caomao', + epic: [ + "dc_caoshuang", + "tianchou", + "star_yuanshao", + "yue_xiaoqiao", + "yue_daqiao", + "mb_chengui", + "ol_pengyang", + "ol_luyusheng", + "clan_xunchen", + "peiyuanshao", + "tw_zhangzhao", + "tw_zhanghong", + "tw_ol_sunjian", + "yj_huangzhong", + "clan_zhongyu", + "zhoushan", + "pal_yueqi", + "pal_yuejinzhao", + "pal_mingxiu", + "pal_xuanxiao", + "pal_zixuan", + "pal_xuejian", + "pal_murongziying", + "pal_lixiaoyao", + "pal_xingxuan", + "hs_tyrande", + "hs_amala", + "hs_alextrasza", + "hs_totemic", + "hs_bchillmaw", + "hs_aedwin", + "hs_antonidas", + "hs_wvelen", + "hs_alakir", + "hs_xsylvanas", + "hs_blingtron", + "hs_fuding", + "hs_lafamu", + "hs_nozdormu", + "hs_jiaziruila", + "hs_yelise", + "hs_xuefashi", + "hs_liadrin", + "yxs_libai", + "yxs_luban", + "yxs_yangyuhuan", + "yxs_guiguzi", + "yxs_aijiyanhou", + "swd_shuwaner", + "swd_kendi", + "swd_weida", + "swd_lilian", + "swd_jipeng", + "swd_cheyun", + "swd_tuobayuer", + "swd_jiliang", + "swd_muyue", + "swd_lanyin", + "swd_chenjingchou", + "swd_kama", + "swd_anka", + "swd_huanyuanzhi", + "swd_kangnalishi", + "swd_zhiyin", + "swd_xiarou", + "swd_wangsiyue", + "swd_qiner", + "gjqt_fanglansheng", + "gjqt_fengqingxue", + "gjqt_xiayize", + "gjqt_bailitusu", + "gjqt_ouyangshaogong", + "gjqt_xunfang", + "diy_zhenji", + "ow_yuanshi", + "ow_tianshi", + "ow_zhixuzhiguang", + "gw_aisinie", + "gw_falanxisika", + "shen_guanyu", + "shen_lvmeng", + "shen_zhugeliang", + "shen_zhouyu", + "chenlin", + "yangxiu", + "chengyu", + "zhugeke", + "guyong", + "litong", + "mazhong", + "simazhao", + "sp_sufei", + "taoqian", + "zhengxuan", + "yj_ganning", + "re_xusheng", + "liuzan", + "lijue", + "beimihu", + "zhangchangpu", + "ol_zhangchangpu", + "guanlu", + "gexuan", + "puyuan", + "xushao", + "wenyang", + "huaman", + "wangshuang", + "xizhicai", + "mayunlu", + "zhugeguo", + "sunhao", + "wangyun", + "zhangbao", + "huangfusong", + "huangjinleishi", + "sp_liuxie", + "shamoke", + "jianggan", + "wangyuanji", + "re_heqi", + "tw_beimihu", + "sp_machao", + "wutugu", + "zhangrang", + "jikang", + "xushi", + "machao", + "sunce", + "re_sunce", + "re_wangyun", + "zuoci", + "xuyou", + "zhangxiu", + "re_zhangjiao", + "re_yuanshao", + "zhugedan", + "leitong", + "wulan", + "caoxing", + "diy_wenyang", + "ns_caoshuang", + "ns_huangchengyan", + "ns_sunchensunjun", + "ns_yuanxi", + "ns_jiaxu", + "liubian", + "simashi", + "jin_simayi", + "jin_zhangchunhua", + "liuhong", + "jin_wangyuanji", + "jin_simazhao", + "jin_xiahouhui", + "jin_simashi", + "zhangling", + "guotu", + "ns_luyusheng", + "fanyufeng", + "re_taoqian", + "caosong", + "sp_duyu", + "jin_yanghuiyu", + "xiahoujie", + "ruanyu", + "zhouqun", + "ns_chentai", + "ns_huangwudie", + "ns_sunyi", + "ns_zhangning", + "ns_yanghu", + "ol_huaxin", + "longyufei", + "re_panshu", + "db_wenyang", + "qiaozhou", + "lvlingqi", + "wangtao", + "wangyue", + "re_pangdegong", + "zhongyan", + "kaisa", + "tw_zhaoxiang", + "tw_caocao", + "tw_liuhong", + "tw_caozhao", + "wufan", + "dc_luotong", + "dc_huangchengyan", + "laiyinger", + "ns_ruanji", + "ns_zanghong", + "caohua", + "ns_limi", + "ol_xunyu", + "ns_zhonglimu", + "dc_sunru", + "zhangfen", + "xiahouxuan", + "prp_zhugeliang", + "zhangzhi", + "ol_liuba", + "shiyi", + "yuanji", + "tw_liuzhang", + "tw_mateng", + "dc_wangyun", + "tw_zhangning", + "tw_zhugeguo", + "xuelingyun", + "dc_zhaotongzhaoguang", + "mengjie", + "dc_ruiji", + "xia_zhaoe", + "duanqiaoxiao", + "longwang", + "taoshen", + "xiaoyuehankehan", + "zhutiexiong", + "sunyang", + "yeshiwen", + "ganfurenmifuren", + "ruanji", + "zhangxuan", + "zhangchu", + "dc_sunhanhua", + "dc_wangjun", + "zhanghua", + "lushi", + "clan_zhonghui", + "zhoubuyi", + "dc_wangjun", + "ns_mengyou", + "key_kano", + "key_haruko", + "key_akiko", + "key_sunohara", + "key_yukine", + "key_komari", + "key_rin", + "key_kengo", + "key_harukakanata", + "key_mio", + "key_midori", + "key_sasami", + "key_riki", + "key_kaori", + "key_shiori", + "key_yuiko", + "key_lucia", + "key_akane", + "key_shizuru", + "key_ao", + "key_tsumugi", + "key_kyoko", + "key_miki", + "key_rei", + "key_yusa", + "key_misa", + "key_shizuku", + "key_hiroto", + "key_rumi", + "key_chihaya", + "key_yukito", + "key_kotomi", + "db_key_liyingxia", + "key_iriya", + "star_dongzhuo", + "star_yuanshu", + "clan_xunyou", + "lvboshe", + "yj_zhoubuyi", + "ol_jianyong", + "ol_sb_jiangwei", + "dc_sb_zhouyu", + "xia_shitao", + "bailingyun", + "dc_sb_simayi", + "caofang", + "mb_caomao", + "dc_shen_huatuo", + "sp_zhenji", + "drag_guanyu", + "drag_caoren", ], - rare:[ - 're_wangyi', - 'ol_wangyi', - 'tw_yanliang', - 'tw_wenchou', - 'tw_yuantan', - 'zhugemengxue', - 'ol_sb_taishici', - 'clan_wuqiao', - 'xin_huojun', - 'muludawang', - 'mb_huban', - 'sp_jianggan', - 'ol_caozhang', - 'ol_lingtong', - 'luoxian', - 'ol_mengda', - 'tw_menghuo', - 'hejin', - 'hansui', - 'clan_xunshu', - 'clan_xuncan', - 'huanfan', - 'xin_zhangyi', - 'pal_shenqishuang', - 'hs_selajin', - 'hs_enzoth', - 'hs_yashaji', - 'hs_yogg', - 'hs_kcthun', - 'pal_nangonghuang', - 'pal_wangpengxu', - 'gw_yioufeisi', - 'gw_luoqi', - 'swd_xiyan', - 'ow_falaozhiying', - 'yxs_kaisa', - 'yxs_napolun', - 'hs_nate', - 'yxs_jinke', - 'yxs_yuefei', - 'hs_anomalus', - 'hs_jinglinglong', - 'hs_alleria', - 'hs_lreno', - 'hs_zhouzhuo', - 'hs_loatheb', - 'hs_finley', - 'ow_chanyata', - 'yxs_huamulan', - 'swd_quxian', - 'ow_liekong', - 'ow_zhixuzhiguang', - 'hs_xialikeer', - 'hs_sainaliusi', - 'hs_lrhonin', - 'yxs_diaochan', - 'hs_anduin', - 'swd_hengai', - 'hs_wuther', - 'swd_shuijing', - 'swd_sikongyu', - 'diy_yuji', - 'hs_zhishigushu', - 'pal_jingtian', - 'swd_shanxiaoxiao', - 'yxs_caocao', - 'swd_linyue', - 'swd_xuanyuanjiantong', - 'swd_maixing', - 'diy_xuhuang', - 'hs_jaina', - 'gjqt_xiangling', - 'swd_jiuyou', - 'diy_zhouyu', - 'pal_changqing', - 'swd_yuchiyanhong', - 'swd_duopeng', - 'swd_yuli', - 'swd_rongshuang', - 'pal_zhaoliner', - 'swd_situqiang', - 'hs_malfurion', - 'yxs_bole', - 'gjqt_yuewuyi', - 'hs_mijiaojisi', - 'yxs_mozi', - 'gjqt_hongyu', - 'hs_waleera', - 'swd_chunyuheng', - 'swd_jiangziya', - 'swd_nicole', - 'swd_zhuoshanzhu', - 'swd_shaowei', - 'pal_linyueru', - 'swd_jialanduo', - 'hs_yngvar', - 're_wuyi', - 're_zhuran', - 'key_yoshino', - 'key_kyoko', - 'jiakui', - 'hujinding', - 'dc_hujinding', - 'zhangyì', - 'lingcao', - 'sunru', - 'zhaotongzhaoguang', - 'yj_xuhuang', - 'yuanshu', - 'guosi', - 'zhangji', - 're_panfeng', - 'gaolan', - 'xunchen', - 'caobuxing', - 're_maliang', - 'sp_caiwenji', - 'luzhi', - 'guanyinping', - 'zhangxingcai', - 'xiahouba', - 'dc_xiahouba', - 'sunluyu', - 'zhugejin', - 'liuxie', - 'sp_zhaoyun', - 'sp_simazhao', - 'sp_wangyuanji', - 'sp_xinxianying', - 'liuye', - 'zhuling', - 'lifeng', - 'chendeng', - 'shenpei', - 'xin_liaohua', - 'nashime', - 'caoang', - 'sp_caoren', - 'sp_jiangwei', - 'zhanggong', - 'xugong', - 'sp_shenpei', - 'dongyun', - 'maliang', - 'mizhu', - 'buzhi', - 'dongbai', - 'jsp_huangyueying', - 'quyi', - 'yanbaihu', - 'zhanglu', - 'jsp_zhaoyun', - 'ganfuren', - 'xin_masu', - 'xunyou', - 'caochong', - 'liufeng', - 'zhuhuan', - 'caifuren', - 'zhangsong', - 'caorui', - 'zhongyao', - 're_zhongyao', - 'liuchen', - 'zhuzhi', - 'gongsunyuan', - 'liuyu', - 'ol_xinxianying', - 'xinxianying', - 'qinmi', - 'wuxian', - 'lvdai', - 're_jsp_pangtong', - 'zhoufang', - 'panjun', - 'yanjun', - 're_yuanshu', - 're_zhanggong', - 'xf_yiji', - 'xf_tangzi', - 'sp_liuqi', - 'sp_diaochan', - 'dianwei', - 're_lusu', - 'caopi', - 'jiaxu', - 'kuailiangkuaiyue', - 'wangji', - 'wangping', - 'luji', - 'haozhao', - 'zhugezhan', - 'zhoufei', - 'lukang', - 'guanqiujian', - 're_caocao', - 're_guojia', - 're_xiahoudun', - 're_zhangliao', - 're_zhenji', - 're_guanyu', - 're_huangyueying', - 're_liubei', - 're_zhangfei', - 're_zhaoyun', - 're_zhugeliang', - 're_daqiao', - 're_huanggai', - 're_sunquan', - 're_sunshangxiang', - 're_diaochan', - 're_lvbu', - 'caoren', - 'ol_weiyan', - 'ol_xiahouyuan', - 're_huangzhong', - 'ol_xiaoqiao', - 'xin_yuji', - 'zhoutai', - 're_xunyu', - 'ol_pangde', - 're_taishici', - 're_yanwen', - 're_caopi', - 're_xuhuang', - 're_menghuo', - 're_zhurong', - 'ol_sunjian', - 'ol_dongzhuo', - 're_jiangwei', - 'ol_liushan', - 're_zhangzhang', - 're_caiwenji', - 're_caozhi', - 'yujin_yujin', - 'tw_yujin', - 'gaoshun', - 're_zhonghui', - 'old_madai', - 're_bulianshi', - 're_liubiao', - 'liubiao', - 're_chengpu', - 'ol_chengpu', - 're_manchong', - 're_yufan', - 're_liru', - 're_jianyong', - 're_sunluban', - 're_sunxiu', - 'xiahoushi', - 'guotufengji', - 'ns_chendao', - 'caozhang', - 'key_jojiro', - 'key_doruji', - 'key_ryoichi', - 'key_asara', - 'tw_maliang', - 'tw_dingfeng', - 'tw_xiahouba', - 'ns_lijue', - 'ns_zhangji', - 'ns_fanchou', - 'xin_zhuran', - 'xin_lingtong', - 'xin_liubiao', - 're_xinxianying', - 'xin_zhangfei', - 'wangrong', - 're_quyi', - 'hanfu', - 'xin_hansui', - 'duyu', - 'zhanghuyuechen', - 're_fazheng', - 'tw_re_fazheng', - 're_fuhuanghou', - 'gongsunkang', - 'xin_panzhangmazhong', - 'ol_dengai', - 'caoanmin', - 're_gongsunyuan', - 're_caozhen', - 're_chunyuqiong', - 'sp_chenzhen', - 'sp_wangcan', - 'lisu', - 'ol_lisu', - 'zhaozhong', - 're_zhangchunhua', - 'xin_handang', - 'sp_bianfuren', - 'tw_bianfuren', - 'luotong', - 'feiyi', - 'sp_jiben', - 'sp_fuhuanghou', - 'ns_chengpu', - 're_zhoucang', - 'sp_mifuren', - 'cheliji', - 're_guotufengji', - 'ol_jiangwei', - 'ol_zhurong', - 'huangchengyan', - 'liangxing', - 'wangling', - 'tw_wangling', - 'zhouchu', - 'dongcheng', - 'tangji', - 'gaogan', - 'caizhenji', - 'duxi', - 'heyan', - 're_caifuren', - 're_dongbai', - 'tw_dongzhao', - 'xin_caifuren', - 'sp_yanghu', - 'qiaogong', - 'tw_qiaogong', - 'liuzhang', - 'zhangzhongjing', - 'xin_zhonghui', - 'jiachong', - 'ol_lusu', - 'xin_sunluban', - 'ol_wangrong', - 'dufuren', - 'yuanhuan', - 'zhouyi', - 'fuqian', - 'yangyan', - 'yangzhi', - 'zuofen', - 'liuyong', - 'dc_liuli', - 'zhangning', - 'wanniangongzhu', - 're_xunchen', - 'tongyuan', - 'simafu', - 'mayuanyi', - 'sp_huaman', - 'ol_yangyi', - 'sp_cuiyan', - 'sp_zhangchangpu', - 'ol_dongzhao', - 'xin_yufan', - 'ol_yufan', - 'xuangongzhu', - 'xinchang', - 'tw_mayunlu', - 'tw_re_caohong', - 'tw_hucheer', - 'sp_yangwan', - 're_xiahoushi', - 're_chendeng', - 'xin_sunxiu', - 'wuyan', - 'sp_maojie', - 'sp_zhujun', - 'ol_chendeng', - 'ol_xuhuang', - 're_guohuanghou', - 'tw_huojun', - 'zhaoyan', - 're_miheng', - 'tw_chengpu', - 'jin_yanghu', - 'qinghegongzhu', - 'tw_guohuai', - 'tw_wangcan', - 'tw_wangchang', - 'licaiwei', - 'jin_jiachong', - 'ol_caiwenji', - 'tengyin', - 'dc_gaolan', - 'caomao', - 'tw_tianyu', - 'tw_puyangxing', - 'jin_guohuai', - 'liuba', - 'sp_menghuo', - 'dc_sp_menghuo', - 'dc_qinghegongzhu', - 'tenggongzhu', - 'tengfanglan', - 'dc_bulianshi', - 'ruiji', - 'weizi', - 'yanrou', - 'zhangyao', - 're_jushou', - 'xin_jushou', - 'yj_jushou', - 're_guyong', - 'dc_yanghu', - 're_duji', - 're_liuchen', - 'dc_liuyu', - 'qinyilu', - 'dc_jiling', - 'dc_wangchang', - 'jin_zhouchu', - 'lukai', - 'ol_lukai', - 'caoxiancaohua', - 'huzhao', - 're_liufeng', - 'guanhai', - 'dukui', - 'ol_dianwei', - 'chengui', - 'ol_hujinding', - 'dingshangwan', - 're_zhuhuan', - 'xin_zhuhuan', - 'yinfuren', - 'dc_liuye', - 'dc_zhaoyǎn', - 'zhugeshang', - 're_xunyou', - 'liwan', - 'furong', - 'sunlang', - 'chengbing', - 'gongsundu', - 'xin_caoxiu', - 'dc_chenqun', - 'liupi', - 'ol_liupi', - 'tw_baoxin', - 'tw_bingyuan', - 'tw_chenzhen', - 'tw_fengxí', - 'tw_haomeng', - 'tw_huchuquan', - 'tw_jiangqing', - 'tw_jianshuo', - 'tw_jiling', - 'tw_liufuren', - 'tw_liwei', - 'tw_xunchen', - 'tw_zhangfei', - 'tw_zhangji', - 'xia_liyàn', - 'xia_tongyuan', - 'xia_wangyue', - 'clan_hanrong', - 'clan_hanshao', - 'dc_yangbiao', - 'ns_duji', - 'ns_sundeng', - 'ol_huangzhong', - 'yj_qiaozhou', - 'yj_sufei', - 'yj_weiyan', - 'dc_huojun', - 'ol_zhangyì', - 'ol_zhujun', - 'xia_dianwei', - 'xia_xiahouzie', - 'zhangkai', - 'wangguan', - 'ol_yanwen', - 'yanghong', - 're_zhuzhi', - 'dongguiren', - 'xielingyu', - 'liupi', - 'xianglang', - 'furongfuqian', - 'zhenghun', - 'clan_wangling', - 'clan_wangguang', - 'clan_wangyun', - 'quhuang', - 'ol_wenqin', - 'clan_wanghun', - 'yue_zhoufei', - 'ol_dingshangwan', - 'ol_liwan', - 'dc_sb_lusu', - 'clan_wangmingshan', - 'chengji', - 'mb_sp_guanqiujian', - 'lizhaojiaobo', + rare: [ + "drag_lvchang", + "re_wangyi", + "ol_wangyi", + "tw_yanliang", + "tw_wenchou", + "tw_yuantan", + "zhugemengxue", + "ol_sb_taishici", + "clan_wuqiao", + "xin_huojun", + "muludawang", + "mb_huban", + "sp_jianggan", + "ol_caozhang", + "ol_lingtong", + "luoxian", + "ol_mengda", + "tw_menghuo", + "hejin", + "hansui", + "clan_xunshu", + "clan_xuncan", + "huanfan", + "xin_zhangyi", + "pal_shenqishuang", + "hs_selajin", + "hs_enzoth", + "hs_yashaji", + "hs_yogg", + "hs_kcthun", + "pal_nangonghuang", + "pal_wangpengxu", + "gw_yioufeisi", + "gw_luoqi", + "swd_xiyan", + "ow_falaozhiying", + "yxs_kaisa", + "yxs_napolun", + "hs_nate", + "yxs_jinke", + "yxs_yuefei", + "hs_anomalus", + "hs_jinglinglong", + "hs_alleria", + "hs_lreno", + "hs_zhouzhuo", + "hs_loatheb", + "hs_finley", + "ow_chanyata", + "yxs_huamulan", + "swd_quxian", + "ow_liekong", + "ow_zhixuzhiguang", + "hs_xialikeer", + "hs_sainaliusi", + "hs_lrhonin", + "yxs_diaochan", + "hs_anduin", + "swd_hengai", + "hs_wuther", + "swd_shuijing", + "swd_sikongyu", + "diy_yuji", + "hs_zhishigushu", + "pal_jingtian", + "swd_shanxiaoxiao", + "yxs_caocao", + "swd_linyue", + "swd_xuanyuanjiantong", + "swd_maixing", + "diy_xuhuang", + "hs_jaina", + "gjqt_xiangling", + "swd_jiuyou", + "diy_zhouyu", + "pal_changqing", + "swd_yuchiyanhong", + "swd_duopeng", + "swd_yuli", + "swd_rongshuang", + "pal_zhaoliner", + "swd_situqiang", + "hs_malfurion", + "yxs_bole", + "gjqt_yuewuyi", + "hs_mijiaojisi", + "yxs_mozi", + "gjqt_hongyu", + "hs_waleera", + "swd_chunyuheng", + "swd_jiangziya", + "swd_nicole", + "swd_zhuoshanzhu", + "swd_shaowei", + "pal_linyueru", + "swd_jialanduo", + "hs_yngvar", + "re_wuyi", + "re_zhuran", + "key_yoshino", + "key_kyoko", + "jiakui", + "hujinding", + "dc_hujinding", + "zhangyì", + "lingcao", + "sunru", + "zhaotongzhaoguang", + "yj_xuhuang", + "yuanshu", + "guosi", + "zhangji", + "re_panfeng", + "gaolan", + "xunchen", + "caobuxing", + "re_maliang", + "sp_caiwenji", + "luzhi", + "guanyinping", + "zhangxingcai", + "xiahouba", + "dc_xiahouba", + "sunluyu", + "zhugejin", + "liuxie", + "sp_zhaoyun", + "sp_simazhao", + "sp_wangyuanji", + "sp_xinxianying", + "liuye", + "zhuling", + "lifeng", + "chendeng", + "shenpei", + "xin_liaohua", + "nashime", + "caoang", + "sp_caoren", + "sp_jiangwei", + "zhanggong", + "xugong", + "sp_shenpei", + "dongyun", + "maliang", + "mizhu", + "buzhi", + "dongbai", + "jsp_huangyueying", + "quyi", + "yanbaihu", + "zhanglu", + "jsp_zhaoyun", + "ganfuren", + "xin_masu", + "xunyou", + "caochong", + "liufeng", + "zhuhuan", + "caifuren", + "zhangsong", + "caorui", + "zhongyao", + "re_zhongyao", + "liuchen", + "zhuzhi", + "gongsunyuan", + "liuyu", + "ol_xinxianying", + "xinxianying", + "qinmi", + "wuxian", + "lvdai", + "re_jsp_pangtong", + "zhoufang", + "panjun", + "yanjun", + "re_yuanshu", + "re_zhanggong", + "xf_yiji", + "xf_tangzi", + "sp_liuqi", + "sp_diaochan", + "dianwei", + "re_lusu", + "caopi", + "jiaxu", + "kuailiangkuaiyue", + "wangji", + "wangping", + "luji", + "haozhao", + "zhugezhan", + "zhoufei", + "lukang", + "guanqiujian", + "re_caocao", + "re_guojia", + "re_xiahoudun", + "re_zhangliao", + "re_zhenji", + "re_guanyu", + "re_huangyueying", + "re_liubei", + "re_zhangfei", + "re_zhaoyun", + "re_zhugeliang", + "re_daqiao", + "re_huanggai", + "re_sunquan", + "re_sunshangxiang", + "re_diaochan", + "re_lvbu", + "caoren", + "ol_weiyan", + "ol_xiahouyuan", + "re_huangzhong", + "ol_xiaoqiao", + "xin_yuji", + "zhoutai", + "re_xunyu", + "ol_pangde", + "re_taishici", + "re_yanwen", + "re_caopi", + "re_xuhuang", + "re_menghuo", + "re_zhurong", + "ol_sunjian", + "ol_dongzhuo", + "re_jiangwei", + "ol_liushan", + "re_zhangzhang", + "re_caiwenji", + "re_caozhi", + "yujin_yujin", + "tw_yujin", + "gaoshun", + "re_zhonghui", + "old_madai", + "re_bulianshi", + "re_liubiao", + "liubiao", + "re_chengpu", + "ol_chengpu", + "re_manchong", + "re_yufan", + "re_liru", + "re_jianyong", + "re_sunluban", + "re_sunxiu", + "xiahoushi", + "guotufengji", + "ns_chendao", + "caozhang", + "key_jojiro", + "key_doruji", + "key_ryoichi", + "key_asara", + "tw_maliang", + "tw_dingfeng", + "tw_xiahouba", + "ns_lijue", + "ns_zhangji", + "ns_fanchou", + "xin_zhuran", + "xin_lingtong", + "xin_liubiao", + "re_xinxianying", + "xin_zhangfei", + "wangrong", + "re_quyi", + "hanfu", + "xin_hansui", + "duyu", + "zhanghuyuechen", + "re_fazheng", + "tw_re_fazheng", + "re_fuhuanghou", + "gongsunkang", + "xin_panzhangmazhong", + "ol_dengai", + "caoanmin", + "re_gongsunyuan", + "re_caozhen", + "re_chunyuqiong", + "sp_chenzhen", + "sp_wangcan", + "lisu", + "ol_lisu", + "zhaozhong", + "re_zhangchunhua", + "xin_handang", + "sp_bianfuren", + "tw_bianfuren", + "luotong", + "feiyi", + "sp_jiben", + "sp_fuhuanghou", + "ns_chengpu", + "re_zhoucang", + "sp_mifuren", + "cheliji", + "re_guotufengji", + "ol_jiangwei", + "ol_zhurong", + "huangchengyan", + "liangxing", + "wangling", + "tw_wangling", + "zhouchu", + "dongcheng", + "tangji", + "gaogan", + "caizhenji", + "duxi", + "heyan", + "re_caifuren", + "re_dongbai", + "tw_dongzhao", + "xin_caifuren", + "sp_yanghu", + "qiaogong", + "tw_qiaogong", + "liuzhang", + "zhangzhongjing", + "xin_zhonghui", + "jiachong", + "ol_lusu", + "xin_sunluban", + "ol_wangrong", + "dufuren", + "yuanhuan", + "zhouyi", + "fuqian", + "yangyan", + "yangzhi", + "zuofen", + "liuyong", + "dc_liuli", + "zhangning", + "wanniangongzhu", + "re_xunchen", + "tongyuan", + "simafu", + "mayuanyi", + "sp_huaman", + "ol_yangyi", + "sp_cuiyan", + "sp_zhangchangpu", + "ol_dongzhao", + "xin_yufan", + "ol_yufan", + "xuangongzhu", + "xinchang", + "tw_mayunlu", + "tw_re_caohong", + "tw_hucheer", + "sp_yangwan", + "re_xiahoushi", + "re_chendeng", + "xin_sunxiu", + "wuyan", + "sp_maojie", + "sp_zhujun", + "ol_chendeng", + "ol_xuhuang", + "re_guohuanghou", + "tw_huojun", + "zhaoyan", + "re_miheng", + "tw_chengpu", + "jin_yanghu", + "qinghegongzhu", + "tw_guohuai", + "tw_wangcan", + "tw_wangchang", + "licaiwei", + "jin_jiachong", + "ol_caiwenji", + "tengyin", + "dc_gaolan", + "caomao", + "tw_tianyu", + "tw_puyangxing", + "jin_guohuai", + "liuba", + "sp_menghuo", + "dc_sp_menghuo", + "dc_qinghegongzhu", + "tenggongzhu", + "tengfanglan", + "dc_bulianshi", + "ruiji", + "weizi", + "yanrou", + "zhangyao", + "re_jushou", + "xin_jushou", + "yj_jushou", + "re_guyong", + "dc_yanghu", + "re_duji", + "re_liuchen", + "dc_liuyu", + "qinyilu", + "dc_jiling", + "dc_wangchang", + "jin_zhouchu", + "lukai", + "ol_lukai", + "caoxiancaohua", + "huzhao", + "re_liufeng", + "guanhai", + "dukui", + "ol_dianwei", + "chengui", + "ol_hujinding", + "dingshangwan", + "re_zhuhuan", + "xin_zhuhuan", + "yinfuren", + "dc_liuye", + "dc_zhaoyǎn", + "zhugeshang", + "re_xunyou", + "liwan", + "furong", + "sunlang", + "chengbing", + "gongsundu", + "xin_caoxiu", + "dc_chenqun", + "liupi", + "ol_liupi", + "tw_baoxin", + "tw_bingyuan", + "tw_chenzhen", + "tw_fengxí", + "tw_haomeng", + "tw_huchuquan", + "tw_jiangqing", + "tw_jianshuo", + "tw_jiling", + "tw_liufuren", + "tw_liwei", + "tw_xunchen", + "tw_zhangfei", + "tw_zhangji", + "xia_liyàn", + "xia_tongyuan", + "xia_wangyue", + "clan_hanrong", + "clan_hanshao", + "dc_yangbiao", + "ns_duji", + "ns_sundeng", + "ol_huangzhong", + "yj_qiaozhou", + "yj_sufei", + "yj_weiyan", + "dc_huojun", + "ol_zhangyì", + "ol_zhujun", + "xia_dianwei", + "xia_xiahouzie", + "zhangkai", + "wangguan", + "ol_yanwen", + "yanghong", + "re_zhuzhi", + "dongguiren", + "xielingyu", + "liupi", + "xianglang", + "furongfuqian", + "zhenghun", + "clan_wangling", + "clan_wangguang", + "clan_wangyun", + "quhuang", + "ol_wenqin", + "clan_wanghun", + "yue_zhoufei", + "ol_dingshangwan", + "ol_liwan", + "dc_sb_lusu", + "clan_wangmingshan", + "chengji", + "mb_sp_guanqiujian", + "lizhaojiaobo", ], - junk:[ - 'ol_sb_guanyu', - 'junk_guanyu', - 'sunshao', - 'ol_guohuai', - 'gongsunzan', - 'chengpu', - 'zangba', - 'tianfeng', - 'dingyuan', - 'caiyong', - 'xin_chengpu', - 'junk_zhangrang', - 'wolongfengchu', - 're_chenqun', - 'sp_ol_zhanghe', - 'key_youta', - 'sp_xujing', - 'fanjiangzhangda', - 'wangxiang', - 'duji', - 'dc_liuba', - 'bianxi', - 'junk_sunquan', - 'clan_wuban', - 'clan_wukuang', - 'ahuinan', - 'sp_caosong', - 'yangfu', - 'wangjun', - 'xin_wuyi', - 'xin_zhuzhi', - 'tw_xiahouen', - 'ol_maliang', - 'old_bulianshi', - 'junk_huangyueying', - 'junk_liubei', - 'old_jiakui', - 'new_caoren', - 'old_zhoutai', - 'dongtuna', - 'junk_lidian', - 'junk_duanwei', - 'zerong', - 'std_panfeng', - 're_caochong', - 're_caorui', - 'junk_xuyou', - 're_zhongyao', - 'junk_zhangjiao', + junk: [ + "ol_sb_guanyu", + "junk_guanyu", + "sunshao", + "ol_guohuai", + "gongsunzan", + "chengpu", + "zangba", + "tianfeng", + "dingyuan", + "caiyong", + "xin_chengpu", + "junk_zhangrang", + "wolongfengchu", + "re_chenqun", + "sp_ol_zhanghe", + "key_youta", + "sp_xujing", + "fanjiangzhangda", + "wangxiang", + "duji", + "dc_liuba", + "bianxi", + "junk_sunquan", + "clan_wuban", + "clan_wukuang", + "ahuinan", + "sp_caosong", + "yangfu", + "wangjun", + "xin_wuyi", + "xin_zhuzhi", + "tw_xiahouen", + "ol_maliang", + "old_bulianshi", + "junk_huangyueying", + "junk_liubei", + "old_jiakui", + "new_caoren", + "old_zhoutai", + "dongtuna", + "junk_lidian", + "junk_duanwei", + "zerong", + "std_panfeng", + "re_caochong", + "re_caorui", + "junk_xuyou", + "re_zhongyao", + "junk_zhangjiao", ], - } + }, }; diff --git a/character/refresh.js b/character/refresh.js index 72b9abc63..295c285b7 100755 --- a/character/refresh.js +++ b/character/refresh.js @@ -1,3244 +1,3953 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'refresh', - characterSort:{ - refresh:{ - refresh_standard:["re_caocao","re_simayi","re_guojia","re_zhangliao","re_xuzhu","re_xiahoudun","re_zhangfei","re_zhaoyun","re_guanyu","re_machao","re_zhouyu","re_lvmeng","re_ganning","re_luxun","re_daqiao","re_huanggai","re_lvbu","re_huatuo","re_liubei","re_diaochan","re_huangyueying","re_sunquan","re_sunshangxiang","re_zhenji","re_zhugeliang","re_huaxiong",'re_gongsunzan',"re_lidian","re_xushu"], - refresh_feng:['caoren','ol_xiahouyuan','ol_weiyan','ol_xiaoqiao','zhoutai','re_zhangjiao','xin_yuji','ol_huangzhong'], - refresh_huo:["ol_sp_zhugeliang","ol_xunyu","ol_dianwei","ol_yanwen","ol_pangtong","ol_yuanshao","ol_pangde","re_taishici"], - refresh_lin:['re_menghuo','ol_sunjian','re_caopi','ol_xuhuang','ol_dongzhuo','ol_zhurong','re_jiaxu','ol_lusu'], - refresh_shan:['ol_jiangwei','ol_caiwenji','ol_liushan','ol_zhangzhang','re_zuoci','re_sunce','ol_dengai','re_zhanghe'], - refresh_yijiang1:['xin_wuguotai','xin_gaoshun','dc_caozhi','yujin_yujin','re_masu','xin_xusheng','re_fazheng','xin_lingtong','re_zhangchunhua','dc_xushu','re_chengong'], - refresh_yijiang2:['re_madai','re_wangyi','xin_handang','xin_zhonghui','re_liaohua','re_chengpu','re_caozhang','dc_bulianshi','xin_liubiao','re_xunyou','re_guanzhang'], - refresh_yijiang3:['re_jianyong','re_guohuai','re_zhuran','re_panzhangmazhong','xin_yufan','dc_liru','re_manchong','re_fuhuanghou','re_guanping','re_liufeng','re_caochong'], - refresh_yijiang4:['re_sunluban','re_wuyi','re_hanhaoshihuan','re_caozhen','re_zhoucang','dc_chenqun','re_caifuren','re_guyong','re_jushou','re_zhuhuan','re_zhangsong'], - refresh_yijiang5:['re_zhangyi','re_quancong','re_caoxiu','re_sunxiu','re_gongsunyuan','re_guotufengji','re_xiahoushi','re_liuchen','re_zhuzhi','re_caorui','re_zhongyao'], - refresh_yijiang6:['re_guohuanghou','re_sundeng'], - refresh_xinghuo:['xin_zhangliang','re_zhugedan','re_simalang','re_duji','dc_gongsunzan','re_sp_taishici','re_caiyong','re_mazhong','re_wenpin','re_jsp_huangyueying'], + name: "refresh", + characterSort: { + refresh: { + refresh_standard: [ + "re_caocao", + "re_simayi", + "re_guojia", + "re_zhangliao", + "re_xuzhu", + "re_xiahoudun", + "re_zhangfei", + "re_zhaoyun", + "re_guanyu", + "re_machao", + "re_zhouyu", + "re_lvmeng", + "re_ganning", + "re_luxun", + "re_daqiao", + "re_huanggai", + "re_lvbu", + "re_huatuo", + "re_liubei", + "re_diaochan", + "re_huangyueying", + "re_sunquan", + "re_sunshangxiang", + "re_zhenji", + "re_zhugeliang", + "re_huaxiong", + "re_gongsunzan", + "re_lidian", + "re_xushu", + ], + refresh_feng: [ + "caoren", + "ol_xiahouyuan", + "ol_weiyan", + "ol_xiaoqiao", + "zhoutai", + "re_zhangjiao", + "xin_yuji", + "ol_huangzhong", + ], + refresh_huo: [ + "ol_sp_zhugeliang", + "ol_xunyu", + "ol_dianwei", + "ol_yanwen", + "ol_pangtong", + "ol_yuanshao", + "ol_pangde", + "re_taishici", + ], + refresh_lin: [ + "re_menghuo", + "ol_sunjian", + "re_caopi", + "ol_xuhuang", + "ol_dongzhuo", + "ol_zhurong", + "re_jiaxu", + "ol_lusu", + ], + refresh_shan: [ + "ol_jiangwei", + "ol_caiwenji", + "ol_liushan", + "ol_zhangzhang", + "re_zuoci", + "re_sunce", + "ol_dengai", + "re_zhanghe", + ], + refresh_yijiang1: [ + "xin_wuguotai", + "xin_gaoshun", + "dc_caozhi", + "yujin_yujin", + "re_masu", + "xin_xusheng", + "re_fazheng", + "xin_lingtong", + "re_zhangchunhua", + "dc_xushu", + "re_chengong", + ], + refresh_yijiang2: [ + "re_madai", + "re_wangyi", + "xin_handang", + "xin_zhonghui", + "re_liaohua", + "re_chengpu", + "re_caozhang", + "dc_bulianshi", + "xin_liubiao", + "re_xunyou", + "re_guanzhang", + ], + refresh_yijiang3: [ + "re_jianyong", + "re_guohuai", + "re_zhuran", + "re_panzhangmazhong", + "xin_yufan", + "dc_liru", + "re_manchong", + "re_fuhuanghou", + "re_guanping", + "re_liufeng", + "re_caochong", + ], + refresh_yijiang4: [ + "re_sunluban", + "re_wuyi", + "re_hanhaoshihuan", + "re_caozhen", + "re_zhoucang", + "dc_chenqun", + "re_caifuren", + "re_guyong", + "re_jushou", + "re_zhuhuan", + "re_zhangsong", + ], + refresh_yijiang5: [ + "re_zhangyi", + "re_quancong", + "re_caoxiu", + "re_sunxiu", + "re_gongsunyuan", + "re_guotufengji", + "re_xiahoushi", + "re_liuchen", + "re_zhuzhi", + "re_caorui", + "re_zhongyao", + ], + refresh_yijiang6: ["re_guohuanghou", "re_sundeng"], + refresh_xinghuo: [ + "xin_zhangliang", + "re_zhugedan", + "re_simalang", + "re_duji", + "dc_gongsunzan", + "re_sp_taishici", + "re_caiyong", + "re_mazhong", + "re_wenpin", + "re_jsp_huangyueying", + ], }, }, - connect:true, - character:{ - re_xushu:['male','shu',4,['zhuhai','qianxin']], - re_lidian:['male','wei',3,['xunxun','xinwangxi']], - re_zhongyao:['male','wei',3,['rehuomo','zuoding'],['clan:颍川钟氏']], - xin_zhangliang:['male','qun',4,['rejijun','refangtong']], - re_simalang:['male','wei',3,['requji','rejunbing']], - re_zhugedan:['male','wei',4,['regongao','rejuyi']], - re_caorui:['male','wei',3,['huituo','remingjian','rexingshuai'],['zhu']], - re_caochong:['male','wei',3,['rechengxiang','renxin']], - ol_zhangzhang:['male','wu',3,['olzhijian','olguzheng']], - re_jsp_huangyueying:['female','qun',3,['rejiqiao','relinglong']], - re_zhangsong:['male','shu',3,['qiangzhi','rexiantu']], - re_zhuzhi:['male','wu',4,['reanguo']], - dc_caozhi:['male','wei',3,['reluoying','dcjiushi']], - ol_huangzhong:['male','shu',4,['xinliegong','remoshi']], - re_wenpin:['male','wei',5,['rezhenwei']], - re_guanzhang:['male','shu',4,['fuhun','retongxin']], - re_mazhong:['male','shu',4,['refuman']], - dc_chenqun:['male','wei',3,['repindi','dcfaen']], - re_sundeng:['male','wu',4,['rekuangbi']], - re_caiyong:['male','qun',3,['rebizhuan','retongbo']], - re_chengong:['male','qun',3,['remingce','zhichi']], - re_xunyou:['male','wei',3,['reqice','rezhiyu'],['clan:颍川荀氏']], - dc_liru:['male','qun',3,['xinjuece','dcmieji','dcfencheng']], - re_zhuhuan:['male','wu',4,['refenli','repingkou']], - ol_dianwei:['male','wei',4,['olqiangxi','olningwu']], - re_sp_taishici:['male','qun',4,['rejixu']], - re_liufeng:['male','shu',4,['rexiansi']], - ol_xunyu:['male','wei',3,['quhu','oljieming'],['clan:颍川荀氏']], - re_liuchen:['male','shu',4,['rezhanjue','reqinwang'],['zhu']], - dc_gongsunzan:['male','qun',4,['dcyicong','dcqiaomeng']], - re_duji:['male','wei',3,['reandong','reyingshi']], - re_jushou:['male','qun',3,['dcjianying','dcshibei']], - re_zhanghe:['male','wei',4,['reqiaobian']], - dc_xushu:['male','shu',4,['rezhuhai','xsqianxin']], - xin_gaoshun:['male','qun',4,['decadexianzhen','decadejinjiu']], - re_guohuanghou:['female','wei',3,['rejiaozhao','redanxin']], - re_xiahoushi:['female','shu',3,['reqiaoshi','reyanyu']], - ol_lusu:['male','wu',3,['olhaoshi','oldimeng']], - re_jiaxu:['male','qun',3,['rewansha','reluanwu','reweimu']], - re_guyong:['male','wu',3,['reshenxing','rebingyi']], - xin_zhonghui:['male','wei',4,['xinquanji','xinzili'],['clan:颍川钟氏']], - re_caifuren:['female','qun',3,['reqieting','rexianzhou']], - re_guanping:['male','shu',4,['relongyin','jiezhong']], - re_guotufengji:['male','qun',3,['rejigong','shifei']], - re_zhoucang:['male','shu',4,['rezhongyong']], - ol_zhurong:['female','shu',4,['juxiang','lieren','changbiao']], - re_zhangchunhua:['female','wei',3,['rejueqing','reshangshi']], - re_gongsunyuan:['male','qun',4,['rehuaiyi']], - re_caozhen:['male','wei',4,['residi']], - re_fuhuanghou:['female','qun',3,['rezhuikong','reqiuyuan']], - re_fazheng:['male','shu',3,['reenyuan','rexuanhuo']], - xin_lingtong:['male','wu',4,['decadexuanfeng','yongjin']], - xin_liubiao:['male','qun',3,['decadezishou','decadezongshi']], - re_caoxiu:['male','wei',4,['qianju','reqingxi']], - re_sunxiu:['male','wu',3,['reyanzhu','rexingxue','zhaofu'],['zhu']], - ol_dengai:['male','wei',4,['oltuntian','olzaoxian']], - re_gongsunzan:['male','qun',4,['reqiaomeng','reyicong']], - re_manchong:['male','wei',3,['rejunxing','yuce']], - xin_yufan:['male','wu',3,['xinzhiyan','xinzongxuan']], - dc_bulianshi:['female','wu',3,['dcanxu','dczhuiyi']], - re_hanhaoshihuan:['male','wei',4,['reshenduan','reyonglve']], - re_panzhangmazhong:['male','wu',4,['reduodao','reanjian']], - re_wangyi:['female','wei',4,['zhenlie','miji']], - re_madai:['male','shu',4,['mashu','reqianxi']], - xin_xusheng:['male','wu',4,['decadepojun']], - re_taishici:['male','wu',4,['tianyi','hanzhan']], - re_masu:['male','shu',3,['resanyao','rezhiman']], - re_sunluban:['female','wu',3,['rechanhui','rejiaojin']], - xin_handang:['male','wu',4,['xingongji','xinjiefan']], - yujin_yujin:['male','wei',4,['decadezhenjun']], - re_caozhang:['male','wei',4,['xinjiangchi']], - re_chengpu:['male','wu',4,['ollihuo','rechunlao']], - re_quancong:['male','wu',4,['xinyaoming']], - re_liaohua:['male','shu',4,['xindangxian','xinfuli']], - re_guohuai:['male','wei',4,['decadejingce']], - re_wuyi:['male','shu',4,['xinbenxi'],['clan:陈留吴氏']], - re_zhuran:['male','wu',4,['xindanshou']], - ol_pangtong:['male','shu',3,['ollianhuan','olniepan'],[]], - re_zhangyi:['male','shu',5,['rewurong','reshizhi']], - xin_wuguotai:['female','wu',3,['xinganlu','xinbuyi']], - re_caocao:['male','wei',4,['new_rejianxiong','rehujia'],['zhu']], - re_simayi:['male','wei',3,['refankui','reguicai']], - re_guojia:['male','wei',3,['tiandu','new_reyiji']], - re_zhangliao:['male','wei',4,['new_retuxi']], - re_xuzhu:['male','wei',4,['new_reluoyi']], - re_xiahoudun:['male','wei',4,['reganglie','new_qingjian']], - re_zhangfei:['male','shu',4,['olpaoxiao','oltishen']], - re_zhaoyun:['male','shu',4,['ollongdan','olyajiao']], - re_guanyu:['male','shu',4,['new_rewusheng','new_yijue']], - re_machao:['male','shu',4,['mashu','retieji']], - re_zhouyu:['male','wu',3,['reyingzi','refanjian']], - re_lvmeng:['male','wu',4,['keji','qinxue','rebotu']], - re_ganning:['male','wu',4,['qixi','fenwei']], - re_luxun:['male','wu',3,['reqianxun','relianying']], - re_daqiao:['female','wu',3,['reguose','liuli']], - re_huanggai:['male','wu',4,['rekurou','zhaxiang']], - re_lvbu:['male','qun',5,['wushuang','new_liyu']], - re_huatuo:['male','qun',3,['jijiu','new_reqingnang']], - re_liubei:['male','shu',4,['rerende','rejijiang'],['zhu']], - re_diaochan:['female','qun',3,['lijian','rebiyue']], - re_huangyueying:['female','shu',3,['rejizhi','reqicai']], - re_sunquan:['male','wu',4,['rezhiheng','rejiuyuan'],['zhu']], - re_sunshangxiang:['female','wu',3,['xiaoji','rejieyin']], - re_zhenji:['female','wei',3,['reluoshen','reqingguo']], - re_zhugeliang:['male','shu',3,['reguanxing','kongcheng']], - re_huaxiong:["male","qun",6,["reyaowu","shizhan"]], + connect: true, + character: { + re_xushu: ["male", "shu", 4, ["zhuhai", "qianxin"]], + re_lidian: ["male", "wei", 3, ["xunxun", "xinwangxi"]], + re_zhongyao: ["male", "wei", 3, ["rehuomo", "zuoding"], ["clan:颍川钟氏"]], + xin_zhangliang: ["male", "qun", 4, ["rejijun", "refangtong"]], + re_simalang: ["male", "wei", 3, ["requji", "rejunbing"]], + re_zhugedan: ["male", "wei", 4, ["regongao", "rejuyi"]], + re_caorui: ["male", "wei", 3, ["huituo", "remingjian", "rexingshuai"], ["zhu"]], + re_caochong: ["male", "wei", 3, ["rechengxiang", "renxin"]], + ol_zhangzhang: ["male", "wu", 3, ["olzhijian", "olguzheng"]], + re_jsp_huangyueying: ["female", "qun", 3, ["rejiqiao", "relinglong"]], + re_zhangsong: ["male", "shu", 3, ["qiangzhi", "rexiantu"]], + re_zhuzhi: ["male", "wu", 4, ["reanguo"]], + dc_caozhi: ["male", "wei", 3, ["reluoying", "dcjiushi"]], + ol_huangzhong: ["male", "shu", 4, ["xinliegong", "remoshi"]], + re_wenpin: ["male", "wei", 5, ["rezhenwei"]], + re_guanzhang: ["male", "shu", 4, ["fuhun", "retongxin"]], + re_mazhong: ["male", "shu", 4, ["refuman"]], + dc_chenqun: ["male", "wei", 3, ["repindi", "dcfaen"]], + re_sundeng: ["male", "wu", 4, ["rekuangbi"]], + re_caiyong: ["male", "qun", 3, ["rebizhuan", "retongbo"]], + re_chengong: ["male", "qun", 3, ["remingce", "zhichi"]], + re_xunyou: ["male", "wei", 3, ["reqice", "rezhiyu"], ["clan:颍川荀氏"]], + dc_liru: ["male", "qun", 3, ["xinjuece", "dcmieji", "dcfencheng"]], + re_zhuhuan: ["male", "wu", 4, ["refenli", "repingkou"]], + ol_dianwei: ["male", "wei", 4, ["olqiangxi", "olningwu"]], + re_sp_taishici: ["male", "qun", 4, ["rejixu"]], + re_liufeng: ["male", "shu", 4, ["rexiansi"]], + ol_xunyu: ["male", "wei", 3, ["quhu", "oljieming"], ["clan:颍川荀氏"]], + re_liuchen: ["male", "shu", 4, ["rezhanjue", "reqinwang"], ["zhu"]], + dc_gongsunzan: ["male", "qun", 4, ["dcyicong", "dcqiaomeng"]], + re_duji: ["male", "wei", 3, ["reandong", "reyingshi"]], + re_jushou: ["male", "qun", 3, ["dcjianying", "dcshibei"]], + re_zhanghe: ["male", "wei", 4, ["reqiaobian"]], + dc_xushu: ["male", "shu", 4, ["rezhuhai", "xsqianxin"]], + xin_gaoshun: ["male", "qun", 4, ["decadexianzhen", "decadejinjiu"]], + re_guohuanghou: ["female", "wei", 3, ["rejiaozhao", "redanxin"]], + re_xiahoushi: ["female", "shu", 3, ["reqiaoshi", "reyanyu"]], + ol_lusu: ["male", "wu", 3, ["olhaoshi", "oldimeng"]], + re_jiaxu: ["male", "qun", 3, ["rewansha", "reluanwu", "reweimu"]], + re_guyong: ["male", "wu", 3, ["reshenxing", "rebingyi"]], + xin_zhonghui: ["male", "wei", 4, ["xinquanji", "xinzili"], ["clan:颍川钟氏"]], + re_caifuren: ["female", "qun", 3, ["reqieting", "rexianzhou"]], + re_guanping: ["male", "shu", 4, ["relongyin", "jiezhong"]], + re_guotufengji: ["male", "qun", 3, ["rejigong", "shifei"]], + re_zhoucang: ["male", "shu", 4, ["rezhongyong"]], + ol_zhurong: ["female", "shu", 4, ["juxiang", "lieren", "changbiao"]], + re_zhangchunhua: ["female", "wei", 3, ["rejueqing", "reshangshi"]], + re_gongsunyuan: ["male", "qun", 4, ["rehuaiyi"]], + re_caozhen: ["male", "wei", 4, ["residi"]], + re_fuhuanghou: ["female", "qun", 3, ["rezhuikong", "reqiuyuan"]], + re_fazheng: ["male", "shu", 3, ["reenyuan", "rexuanhuo"]], + xin_lingtong: ["male", "wu", 4, ["decadexuanfeng", "yongjin"]], + xin_liubiao: ["male", "qun", 3, ["decadezishou", "decadezongshi"]], + re_caoxiu: ["male", "wei", 4, ["qianju", "reqingxi"]], + re_sunxiu: ["male", "wu", 3, ["reyanzhu", "rexingxue", "zhaofu"], ["zhu"]], + ol_dengai: ["male", "wei", 4, ["oltuntian", "olzaoxian"]], + re_gongsunzan: ["male", "qun", 4, ["reqiaomeng", "reyicong"]], + re_manchong: ["male", "wei", 3, ["rejunxing", "yuce"]], + xin_yufan: ["male", "wu", 3, ["xinzhiyan", "xinzongxuan"]], + dc_bulianshi: ["female", "wu", 3, ["dcanxu", "dczhuiyi"]], + re_hanhaoshihuan: ["male", "wei", 4, ["reshenduan", "reyonglve"]], + re_panzhangmazhong: ["male", "wu", 4, ["reduodao", "reanjian"]], + re_wangyi: ["female", "wei", 4, ["zhenlie", "miji"]], + re_madai: ["male", "shu", 4, ["mashu", "reqianxi"]], + xin_xusheng: ["male", "wu", 4, ["decadepojun"]], + re_taishici: ["male", "wu", 4, ["tianyi", "hanzhan"]], + re_masu: ["male", "shu", 3, ["resanyao", "rezhiman"]], + re_sunluban: ["female", "wu", 3, ["rechanhui", "rejiaojin"]], + xin_handang: ["male", "wu", 4, ["xingongji", "xinjiefan"]], + yujin_yujin: ["male", "wei", 4, ["decadezhenjun"]], + re_caozhang: ["male", "wei", 4, ["xinjiangchi"]], + re_chengpu: ["male", "wu", 4, ["ollihuo", "rechunlao"]], + re_quancong: ["male", "wu", 4, ["xinyaoming"]], + re_liaohua: ["male", "shu", 4, ["xindangxian", "xinfuli"]], + re_guohuai: ["male", "wei", 4, ["decadejingce"]], + re_wuyi: ["male", "shu", 4, ["xinbenxi"], ["clan:陈留吴氏"]], + re_zhuran: ["male", "wu", 4, ["xindanshou"]], + ol_pangtong: ["male", "shu", 3, ["ollianhuan", "olniepan"], []], + re_zhangyi: ["male", "shu", 5, ["rewurong", "reshizhi"]], + xin_wuguotai: ["female", "wu", 3, ["xinganlu", "xinbuyi"]], + re_caocao: ["male", "wei", 4, ["new_rejianxiong", "rehujia"], ["zhu"]], + re_simayi: ["male", "wei", 3, ["refankui", "reguicai"]], + re_guojia: ["male", "wei", 3, ["tiandu", "new_reyiji"]], + re_zhangliao: ["male", "wei", 4, ["new_retuxi"]], + re_xuzhu: ["male", "wei", 4, ["new_reluoyi"]], + re_xiahoudun: ["male", "wei", 4, ["reganglie", "new_qingjian"]], + re_zhangfei: ["male", "shu", 4, ["olpaoxiao", "oltishen"]], + re_zhaoyun: ["male", "shu", 4, ["ollongdan", "olyajiao"]], + re_guanyu: ["male", "shu", 4, ["new_rewusheng", "new_yijue"]], + re_machao: ["male", "shu", 4, ["mashu", "retieji"]], + re_zhouyu: ["male", "wu", 3, ["reyingzi", "refanjian"]], + re_lvmeng: ["male", "wu", 4, ["keji", "qinxue", "rebotu"]], + re_ganning: ["male", "wu", 4, ["qixi", "fenwei"]], + re_luxun: ["male", "wu", 3, ["reqianxun", "relianying"]], + re_daqiao: ["female", "wu", 3, ["reguose", "liuli"]], + re_huanggai: ["male", "wu", 4, ["rekurou", "zhaxiang"]], + re_lvbu: ["male", "qun", 5, ["wushuang", "new_liyu"]], + re_huatuo: ["male", "qun", 3, ["jijiu", "new_reqingnang"]], + re_liubei: ["male", "shu", 4, ["rerende", "rejijiang"], ["zhu"]], + re_diaochan: ["female", "qun", 3, ["lijian", "rebiyue"]], + re_huangyueying: ["female", "shu", 3, ["rejizhi", "reqicai"]], + re_sunquan: ["male", "wu", 4, ["rezhiheng", "rejiuyuan"], ["zhu"]], + re_sunshangxiang: ["female", "wu", 3, ["xiaoji", "rejieyin"]], + re_zhenji: ["female", "wei", 3, ["reluoshen", "reqingguo"]], + re_zhugeliang: ["male", "shu", 3, ["reguanxing", "kongcheng"]], + re_huaxiong: ["male", "qun", 6, ["reyaowu", "shizhan"]], - re_zhangjiao:['male','qun',3,['xinleiji','xinguidao','xinhuangtian'],['zhu']], - xin_yuji:['male','qun',3,['reguhuo']], - re_zuoci:['male','qun',3,['rehuashen','rexinsheng']], + re_zhangjiao: ["male", "qun", 3, ["xinleiji", "xinguidao", "xinhuangtian"], ["zhu"]], + xin_yuji: ["male", "qun", 3, ["reguhuo"]], + re_zuoci: ["male", "qun", 3, ["rehuashen", "rexinsheng"]], - ol_xiahouyuan:['male','wei',4,['xinshensu','shebian']], - caoren:['male','wei',4,['xinjushou','xinjiewei']], - ol_weiyan:['male','shu',4,['xinkuanggu','reqimou']], - ol_xiaoqiao:['female','wu',3,['oltianxiang','olhongyan','piaoling']], - zhoutai:['male','wu',4,['buqu','fenji']], - ol_pangde:['male','qun',4,['mashu','rejianchu']], - ol_xuhuang:['male','wei',4,['olduanliang','oljiezi']], - ol_sp_zhugeliang:["male","shu",3,["bazhen","olhuoji","olkanpo","cangzhuo"],[]], - ol_yanwen:["male","qun",4,["olshuangxiong"],[]], - ol_yuanshao:['male','qun',4,['olluanji','olxueyi'],['zhu']], - re_menghuo:['male','shu',4,['huoshou','rezaiqi']], - ol_dongzhuo:['male','qun',8,['oljiuchi','roulin','benghuai','olbaonue'],['zhu']], - ol_sunjian:['male','wu','4/5',['gzyinghun','wulie']], - re_caopi:['male','wei',3,['rexingshang','refangzhu','songwei'],['zhu']], - ol_jiangwei:['male','shu',4,['oltiaoxin','olzhiji']], - ol_caiwenji:['female','qun',3,['olbeige','duanchang']], - ol_liushan:['male','shu',3,['xiangle','olfangquan','olruoyu'],['zhu']], + ol_xiahouyuan: ["male", "wei", 4, ["xinshensu", "shebian"]], + caoren: ["male", "wei", 4, ["xinjushou", "xinjiewei"]], + ol_weiyan: ["male", "shu", 4, ["xinkuanggu", "reqimou"]], + ol_xiaoqiao: ["female", "wu", 3, ["oltianxiang", "olhongyan", "piaoling"]], + zhoutai: ["male", "wu", 4, ["buqu", "fenji"]], + ol_pangde: ["male", "qun", 4, ["mashu", "rejianchu"]], + ol_xuhuang: ["male", "wei", 4, ["olduanliang", "oljiezi"]], + ol_sp_zhugeliang: ["male", "shu", 3, ["bazhen", "olhuoji", "olkanpo", "cangzhuo"], []], + ol_yanwen: ["male", "qun", 4, ["olshuangxiong"], []], + ol_yuanshao: ["male", "qun", 4, ["olluanji", "olxueyi"], ["zhu"]], + re_menghuo: ["male", "shu", 4, ["huoshou", "rezaiqi"]], + ol_dongzhuo: ["male", "qun", 8, ["oljiuchi", "roulin", "benghuai", "olbaonue"], ["zhu"]], + ol_sunjian: ["male", "wu", "4/5", ["gzyinghun", "wulie"]], + re_caopi: ["male", "wei", 3, ["rexingshang", "refangzhu", "songwei"], ["zhu"]], + ol_jiangwei: ["male", "shu", 4, ["oltiaoxin", "olzhiji"]], + ol_caiwenji: ["female", "qun", 3, ["olbeige", "duanchang"]], + ol_liushan: ["male", "shu", 3, ["xiangle", "olfangquan", "olruoyu"], ["zhu"]], - re_sunce:['male','wu',4,['oljiang','olhunzi','olzhiba'],['zhu']], - re_jianyong:['male','shu',3,['reqiaoshui','jyzongshi']], + re_sunce: ["male", "wu", 4, ["oljiang", "olhunzi", "olzhiba"], ["zhu"]], + re_jianyong: ["male", "shu", 3, ["reqiaoshui", "jyzongshi"]], }, - characterIntro:{ - jsp_huangyueying:'荆州沔南白水人,沔阳名士黄承彦之女,诸葛亮之妻,诸葛瞻之母。容貌甚丑,而有奇才:上通天文,下察地理,韬略近于诸书无所不晓,诸葛亮在南阳闻其贤而迎娶。', - re_gongsunzan:'群雄之一。出身贵族,因母地位卑贱,只当了郡中小吏。他貌美,声音洪亮,机智善辩。后随卢植于缑氏山中读书,粗通经传。', - re_lidian:'字曼成,曹操麾下将领。李典深明大义,不与人争功,崇尚学习与高贵儒雅,尊重博学之士,在军中被称为长者。李典有长者之风,官至破虏将军,三十六岁去世。魏文帝曹丕继位后追谥号为愍侯。', - sunben:' ', + characterIntro: { + jsp_huangyueying: + "荆州沔南白水人,沔阳名士黄承彦之女,诸葛亮之妻,诸葛瞻之母。容貌甚丑,而有奇才:上通天文,下察地理,韬略近于诸书无所不晓,诸葛亮在南阳闻其贤而迎娶。", + re_gongsunzan: + "群雄之一。出身贵族,因母地位卑贱,只当了郡中小吏。他貌美,声音洪亮,机智善辩。后随卢植于缑氏山中读书,粗通经传。", + re_lidian: + "字曼成,曹操麾下将领。李典深明大义,不与人争功,崇尚学习与高贵儒雅,尊重博学之士,在军中被称为长者。李典有长者之风,官至破虏将军,三十六岁去世。魏文帝曹丕继位后追谥号为愍侯。", + sunben: " ", }, - characterFilter:{ - re_zuoci:function(mode){ - return mode!='guozhan'; - } + characterFilter: { + re_zuoci: function (mode) { + return mode != "guozhan"; + }, }, - perfectPair:{ - sunben:['zhouyu','taishici','daqiao'], - re_xushu:['zhaoyun','sp_zhugeliang'], - re_guohuai:['xiahouyuan','zhanghe'], + perfectPair: { + sunben: ["zhouyu", "taishici", "daqiao"], + re_xushu: ["zhaoyun", "sp_zhugeliang"], + 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'); + 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)); + 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.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })) return true; + 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.includes(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.includes(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); + 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.includes(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,'的目标'); + game.log(targets, "也成为了", trigger.card, "的目标"); } }, }, }, }, - rehuomo:{ - audio:'huomo', - audioname:['huzhao','re_zhongyao'], - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(get.type(name)!='basic') return false; - const list=player.getStorage('rehuomo'); - if(list.includes(name)) return false; - return player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'eh'); + rehuomo: { + audio: "huomo", + audioname: ["huzhao", "re_zhongyao"], + enable: "chooseToUse", + hiddenCard: function (player, name) { + if (get.type(name) != "basic") return false; + const list = player.getStorage("rehuomo"); + if (list.includes(name)) return false; + return player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "eh"); }, - filter:function(event,player){ - if(event.type=='wuxie'||!player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'eh')) return false; - const list=player.getStorage('rehuomo'); - for(let name of lib.inpile){ - if(get.type(name)!='basic'||list.includes(name)) continue; - let card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) return true; - if(name=='sha'){ - for(let nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) return true; + filter: function (event, player) { + if ( + event.type == "wuxie" || + !player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "eh") + ) + return false; + const list = player.getStorage("rehuomo"); + for (let name of lib.inpile) { + if (get.type(name) != "basic" || list.includes(name)) continue; + let card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) return true; + if (name == "sha") { + for (let nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - const vcards=[]; - const list=player.getStorage('rehuomo'); - for(let name of lib.inpile){ - if(get.type(name)!='basic'||list.includes(name)) continue; - let card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); - if(name=='sha'){ - for(let nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name,nature]); + chooseButton: { + dialog: function (event, player) { + const vcards = []; + const list = player.getStorage("rehuomo"); + for (let name of lib.inpile) { + if (get.type(name) != "basic" || list.includes(name)) continue; + let card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); + if (name == "sha") { + for (let nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) + vcards.push(["基本", "", name, nature]); } } } - return ui.create.dialog('活墨',[vcards,'vcard'],'hidden'); + return ui.create.dialog("活墨", [vcards, "vcard"], "hidden"); }, - check:function(button){ - const player=_status.event.player; - const card={name:button.link[2],nature:button.link[3]}; - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch(button.link[2]){ - case 'tao':return 5; - case 'jiu':return 3.01; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder') return 2.92; + check: function (button) { + const player = _status.event.player; + const card = { name: button.link[2], nature: button.link[3] }; + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + return 5; + case "jiu": + return 3.01; + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder") return 2.92; else return 2.9; - case 'shan':return 1; + case "shan": + return 1; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - check:function(card){ - return 1/Math.max(0.1,get.value(card)); + check: function (card) { + return 1 / Math.max(0.1, get.value(card)); }, - filterCard:function(card){ - return get.type(card)!='basic'&&get.color(card)=='black'; + filterCard: function (card) { + return get.type(card) != "basic" && get.color(card) == "black"; }, - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }, - position:'he', - popname:true, - ignoreMod:true, - precontent:function(){ - player.logSkill('rehuomo'); - var card=event.result.cards[0]; - game.log(player,'将',card,'置于牌堆顶'); - player.loseToDiscardpile(card,ui.cardPile,'visible','insert').log=false; - var viewAs={name:event.result.card.name,nature:event.result.card.nature}; - event.result.card=viewAs; - event.result.cards=[]; - if(!player.storage.rehuomo){ - player.when({global:'phaseAfter'}).then(()=>{player.unmarkSkill('rehuomo')}); + position: "he", + popname: true, + ignoreMod: true, + precontent: function () { + player.logSkill("rehuomo"); + var card = event.result.cards[0]; + game.log(player, "将", card, "置于牌堆顶"); + player.loseToDiscardpile(card, ui.cardPile, "visible", "insert").log = false; + var viewAs = { + name: event.result.card.name, + nature: event.result.card.nature, + }; + event.result.card = viewAs; + event.result.cards = []; + if (!player.storage.rehuomo) { + player.when({ global: "phaseAfter" }).then(() => { + player.unmarkSkill("rehuomo"); + }); } - player.markAuto('rehuomo',viewAs.name) + player.markAuto("rehuomo", viewAs.name); }, - } + }; + }, + prompt: function (links, player) { + return ( + "将一张黑色非基本牌置于牌堆顶并视为使用一张" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + ); }, - prompt:function(links,player){ - return '将一张黑色非基本牌置于牌堆顶并视为使用一张'+get.translation(links[0][3]||'')+get.translation(links[0][2]); - } }, - marktext:'墨', - intro:{ - content:'本回合已因〖活墨〗使用过$', - onunmark:true, + marktext: "墨", + intro: { + content: "本回合已因〖活墨〗使用过$", + onunmark: true, }, - ai:{ - order:function(){ - var player=_status.event.player; - var event=_status.event; - var list=player.getStorage('rehuomo'); - if(!list.includes('jiu')&&event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0){ + ai: { + order: function () { + var player = _status.event.player; + var event = _status.event; + var list = player.getStorage("rehuomo"); + if ( + !list.includes("jiu") && + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 + ) { return 3.1; } return 2.9; }, - respondSha:true, - fireAttack:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='fireAttack') return true; - if(player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'he')){ - var list=player.getStorage('rehuomo'); - if(tag=='respondSha'){ - if(arg!='use') return false; - if(list.includes('sha')) return false; + respondSha: true, + fireAttack: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "fireAttack") return true; + if ( + player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "he") + ) { + var list = player.getStorage("rehuomo"); + if (tag == "respondSha") { + if (arg != "use") return false; + if (list.includes("sha")) return false; + } else if (tag == "respondShan") { + if (list.includes("shan")) return false; } - else if(tag=='respondShan'){ - if(list.includes('shan')) return false; - } - } - else{ + } else { return false; } }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, //界张梁 - rejijun:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.targets&&event.targets.includes(player); + rejijun: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return event.targets && event.targets.includes(player); }, - frequent:true, - content:function(){ - player.judge(card=>1).callback=lib.skill.rejijun.callback; + frequent: true, + content: function () { + player.judge((card) => 1).callback = lib.skill.rejijun.callback; }, - callback:function(){ - if(typeof card.number=='number') player.addToExpansion(card,'gain2').gaintag.add('rejijun'); + callback: function () { + if (typeof card.number == "number") + player.addToExpansion(card, "gain2").gaintag.add("rejijun"); }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - marktext:'方', - ai:{combo:'refangtong'}, + marktext: "方", + ai: { combo: "refangtong" }, }, - refangtong:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h'); + refangtong: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h"); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('refangtong'),(card,player)=>typeof card.number=='number').set('ai',card=>{ - var player=_status.event.player; - if(!game.hasPlayer(target=>target!=player&&get.damageEffect(target,player,player,'thunder')>0)) return 0; - if(player.getExpansions('rejijun').reduce(function(num,card){ - return num+get.number(card,false); - },0)>36) return 1/(get.value(card)||0.5); - else{ - if(lib.skill.refangtong.thunderEffect(card,player)) return 10-get.value(card); - return 5-get.value(card); - } - }); - 'step 1' - if(result.bool){ - player.logSkill('refangtong'); - player.addToExpansion(result.cards,player,'give').gaintag.add('rejijun'); - } - else event.finish(); - 'step 2' - player.chooseButton(['###是否移去任意张“方”,对一名其他角色造成1点雷属性伤害?###若你移去的“方”的点数和大于36,则改为造成3点雷属性伤害',player.getExpansions('rejijun')],[1,player.getExpansions('rejijun').length]).set('ai',button=>{ - var player=_status.event.player; - var cards=player.getExpansions('rejijun'); - if(cards.reduce(function(num,card){ - return num+get.number(card,false); - },0)<=36){ - if(!ui.selected.buttons.length) return 1/get.number(button.link,false); - return 0; - } - else{ - var num=0,list=[]; - cards.sort((a,b)=>get.number(b,false)-get.number(a,false)); - for(var i=0;i36) break; + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.prompt2("refangtong"), + (card, player) => typeof card.number == "number" + ) + .set("ai", (card) => { + var player = _status.event.player; + if ( + !game.hasPlayer( + (target) => + target != player && + get.damageEffect(target, player, player, "thunder") > 0 + ) + ) + return 0; + if ( + player.getExpansions("rejijun").reduce(function (num, card) { + return num + get.number(card, false); + }, 0) > 36 + ) + return 1 / (get.value(card) || 0.5); + else { + if (lib.skill.refangtong.thunderEffect(card, player)) + return 10 - get.value(card); + return 5 - get.value(card); } - return list.includes(button.link)?1:0; - } - }); - 'step 3' - if(result.bool){ - var bool=(result.links.reduce(function(num,card){ - return num+get.number(card,false); - },0)>36); - event.bool=bool; + }); + "step 1"; + if (result.bool) { + player.logSkill("refangtong"); + player.addToExpansion(result.cards, player, "give").gaintag.add("rejijun"); + } else event.finish(); + "step 2"; + player + .chooseButton( + [ + "###是否移去任意张“方”,对一名其他角色造成1点雷属性伤害?###若你移去的“方”的点数和大于36,则改为造成3点雷属性伤害", + player.getExpansions("rejijun"), + ], + [1, player.getExpansions("rejijun").length] + ) + .set("ai", (button) => { + var player = _status.event.player; + var cards = player.getExpansions("rejijun"); + if ( + cards.reduce(function (num, card) { + return num + get.number(card, false); + }, 0) <= 36 + ) { + if (!ui.selected.buttons.length) return 1 / get.number(button.link, false); + return 0; + } else { + var num = 0, + list = []; + cards.sort((a, b) => get.number(b, false) - get.number(a, false)); + for (var i = 0; i < cards.length; i++) { + list.push(cards[i]); + num += get.number(cards[i], false); + if (num > 36) break; + } + return list.includes(button.link) ? 1 : 0; + } + }); + "step 3"; + if (result.bool) { + var bool = + result.links.reduce(function (num, card) { + return num + get.number(card, false); + }, 0) > 36; + event.bool = bool; player.loseToDiscardpile(result.links); - player.chooseTarget('请选择一名其他角色','对其造成'+(bool?3:1)+'点雷属性伤害',lib.filter.notMe).set('ai',target=>get.damageEffect(target,_status.event.player,_status.event.player,'thunder')); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; + player + .chooseTarget( + "请选择一名其他角色", + "对其造成" + (bool ? 3 : 1) + "点雷属性伤害", + lib.filter.notMe + ) + .set("ai", (target) => + get.damageEffect( + target, + _status.event.player, + _status.event.player, + "thunder" + ) + ); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - target.damage(event.bool?3:1,'thunder'); + target.damage(event.bool ? 3 : 1, "thunder"); } }, - thunderEffect:function(card,player){ - var cards=player.getExpansions('rejijun'),num=0; + thunderEffect: function (card, player) { + var cards = player.getExpansions("rejijun"), + num = 0; cards.push(card); - if(cards.reduce(function(num,card){ - return num+get.number(card,false); - },0)<=36) return false; - cards.sort((a,b)=>get.number(b,false)-get.number(a,false)); - var bool=false; - for(var i=0;i36) break; + if ( + cards.reduce(function (num, card) { + return num + get.number(card, false); + }, 0) <= 36 + ) + return false; + cards.sort((a, b) => get.number(b, false) - get.number(a, false)); + var bool = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i] == card) bool = true; + num += get.number(cards[i], false); + if (num > 36) break; } return bool; }, - ai:{combo:'rejijun'}, + ai: { combo: "rejijun" }, }, //界司马朗 - requji:{ - inherit:'quji', - content:function(){ - 'step 0' + requji: { + inherit: "quji", + content: function () { + "step 0"; target.recover(); - 'step 1' - if(target.isDamaged()) target.draw(); - 'step 2' - if(target==targets[targets.length-1]&&cards.some(card=>get.color(card,player)=='black')) player.loseHp(); + "step 1"; + if (target.isDamaged()) target.draw(); + "step 2"; + if ( + target == targets[targets.length - 1] && + cards.some((card) => get.color(card, player) == "black") + ) + player.loseHp(); }, }, - rejunbing:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player.countCards('h')0); - 'step 1' - if(result.bool){ - player.logSkill('rejunbing',target); - if(target!=player) game.log(target,'响应了',player,'的','#g【郡兵】'); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + event.player = player; + event.target = target; + target + .chooseBool( + target == player + ? get.prompt("rejunbing") + : "是否响应" + get.translation(player) + "的【郡兵】?", + "摸一张牌" + + (target == player + ? "" + : ",将所有手牌交给" + + get.translation(player) + + ",然后其可以交给你等量张牌") + ) + .set("choice", get.attitude(target, player) > 0); + "step 1"; + if (result.bool) { + player.logSkill("rejunbing", target); + if (target != player) game.log(target, "响应了", player, "的", "#g【郡兵】"); target.draw(); + } else event.finish(); + "step 2"; + var cards = target.getCards("h"); + if (target == player || !cards.length) { + event.finish(); + return; } - else event.finish(); - 'step 2' - var cards=target.getCards('h'); - if(target==player||!cards.length){event.finish();return;} - target.give(cards,player); - event.num=cards.length; - 'step 3' - if(player.countCards('he'){ - var player=_status.event.player; - var target=_status.event.target; - if(get.attitude(player,target)<=0){ - if(card.name=='du') return 1145141919810; - return -get.value(card); - } - return 6-get.value(card); - }).set('target',target); - 'step 4' - if(result.bool) player.give(result.cards,target); + target.give(cards, player); + event.num = cards.length; + "step 3"; + if (player.countCards("he") < num) event.finish(); + else + player + .chooseCard( + "郡兵:是否还给" + get.translation(target) + get.translation(num) + "张牌?", + "he", + num + ) + .set("ai", (card) => { + var player = _status.event.player; + var target = _status.event.target; + if (get.attitude(player, target) <= 0) { + if (card.name == "du") return 1145141919810; + return -get.value(card); + } + return 6 - get.value(card); + }) + .set("target", target); + "step 4"; + if (result.bool) player.give(result.cards, target); }, }, //界诸葛诞 - regongao:{ - audio:2, - trigger:{global:'dying'}, - filter:function(event,player){ - if(player==event.player) return false; - return !player.getAllHistory('useSkill',evt=>evt.skill=='regongao'&&evt.targets[0]==event.player).length; + regongao: { + audio: 2, + trigger: { global: "dying" }, + filter: function (event, player) { + if (player == event.player) return false; + return !player.getAllHistory( + "useSkill", + (evt) => evt.skill == "regongao" && evt.targets[0] == event.player + ).length; }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { player.gainMaxHp(); player.recover(); }, }, - rejuyi:{ - unique:true, - audio:2, - derivation:['benghuai','reweizhong'], - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.maxHp>game.countPlayer()&&player.isDamaged(); + rejuyi: { + unique: true, + audio: 2, + derivation: ["benghuai", "reweizhong"], + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.maxHp > game.countPlayer() && player.isDamaged(); }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.awakenSkill('rejuyi'); - 'step 1' + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player.awakenSkill("rejuyi"); + "step 1"; player.drawTo(player.maxHp); - 'step 2' - player.addSkills(['benghuai','reweizhong']); - } + "step 2"; + player.addSkills(["benghuai", "reweizhong"]); + }, }, - reweizhong:{ - audio:2, - inherit:'weizhong', - content:function(){ + reweizhong: { + audio: 2, + inherit: "weizhong", + content: function () { player.draw(2); }, }, //堪比界曹冲的界曹叡 - remingjian:{ - inherit:'mingjian', - content:function(){ - player.give(cards,target); - target.addTempSkill('remingjian_buff',{player:'phaseAfter'}); - if(!target.storage.remingjian_buff) target.storage.remingjian_buff=[]; + remingjian: { + inherit: "mingjian", + content: function () { + player.give(cards, target); + target.addTempSkill("remingjian_buff", { player: "phaseAfter" }); + if (!target.storage.remingjian_buff) target.storage.remingjian_buff = []; target.storage.remingjian_buff.push(player); - target.markSkill('remingjian_buff'); + target.markSkill("remingjian_buff"); }, - subSkill:{ - buff:{ - charlotte:true, - mark:true, - marktext:'鉴', - intro:{ - content:(storage,player)=>{ - const num=storage.length; - return `
            • 被${get.translation(storage.toUniqued())}鉴识
            • 手牌上限+${num},出杀次数+${num}`; + subSkill: { + buff: { + charlotte: true, + mark: true, + marktext: "鉴", + intro: { + content: (storage, player) => { + const num = storage.length; + return `
            • 被${get.translation( + storage.toUniqued() + )}鉴识
            • 手牌上限+${num},出杀次数+${num}`; }, }, - onremove:true, - trigger:{ - source:'damageSource', + onremove: true, + trigger: { + source: "damageSource", }, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - return player.getHistory('sourceDamage').indexOf(event)==0&&player.getStorage('remingjian_buff').some(i=>i.isIn()); + filter: function (event, player) { + if (_status.currentPhase != player) return false; + return ( + player.getHistory("sourceDamage").indexOf(event) == 0 && + player.getStorage("remingjian_buff").some((i) => i.isIn()) + ); }, - content:function*(event,map){ - const player=map.player; - const masters=player.getStorage('remingjian_buff').filter(i=>i.isIn()).toUniqued().sortBySeat(_status.currentPhase); - while(masters.length){ - const master=masters.shift(); - if(!master.isIn()) continue; - const result=yield player.chooseBool(`是否令${get.translation(master)}发动一次〖恢拓〗?`).set('choice',get.attitude(player,master)>0); - if(!result.bool) continue; - if(!player.isUnderControl(true)&&!event.isOnline()) game.delayx(); - player.logSkill('remingjian_buff',master); - const next=game.createEvent('huituo'); + content: function* (event, map) { + const player = map.player; + const masters = player + .getStorage("remingjian_buff") + .filter((i) => i.isIn()) + .toUniqued() + .sortBySeat(_status.currentPhase); + while (masters.length) { + const master = masters.shift(); + if (!master.isIn()) continue; + const result = yield player + .chooseBool(`是否令${get.translation(master)}发动一次〖恢拓〗?`) + .set("choice", get.attitude(player, master) > 0); + if (!result.bool) continue; + if (!player.isUnderControl(true) && !event.isOnline()) game.delayx(); + player.logSkill("remingjian_buff", master); + const next = game.createEvent("huituo"); next.setContent(lib.skill.huituo.content); - next.player=master; - next.forced=true; - next._trigger=map.trigger; + next.player = master; + next.forced = true; + next._trigger = map.trigger; yield next; } }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getStorage('remingjian_buff').length; + mod: { + maxHandcard: function (player, num) { + return num + player.getStorage("remingjian_buff").length; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha") + return num + player.getStorage("remingjian_buff").length; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.getStorage('remingjian_buff').length; - } }, - } + }, }, }, - rexingshuai:{ - audio:2, - skillAnimation:true, - animationColor:'thunder', - trigger:{player:'dying'}, - zhuSkill:true, - filter:function(event,player){ - if(player.hp>0) return false; - if(!player.hasZhuSkill('rexingshuai')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'; + rexingshuai: { + audio: 2, + skillAnimation: true, + animationColor: "thunder", + trigger: { player: "dying" }, + zhuSkill: true, + filter: function (event, player) { + if (player.hp > 0) return false; + if (!player.hasZhuSkill("rexingshuai")) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wei"; }); }, - limited:true, - mark:true, - content:function(){ - 'step 0' - player.awakenSkill('rexingshuai'); - var targets=game.filterPlayer(); + limited: true, + mark: true, + content: function () { + "step 0"; + player.awakenSkill("rexingshuai"); + var targets = game.filterPlayer(); targets.sortBySeat(_status.currentPhase); targets.remove(player); - event.targets=targets; - event.damages=[]; - player.addSkill('rexingshuai_restore'); - 'step 1' - if(event.targets.length){ - var current=event.targets.shift(); - if(current.group=='wei'){ - current.chooseBool('是否令'+get.translation(player)+'回复1点体力?').set('ai',function(){ - return get.attitude(_status.event.player,_status.event.target)>2; - }).set('target',player); - event.current=current; - } - else{ + event.targets = targets; + event.damages = []; + player.addSkill("rexingshuai_restore"); + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); + if (current.group == "wei") { + current + .chooseBool("是否令" + get.translation(player) + "回复1点体力?") + .set("ai", function () { + return get.attitude(_status.event.player, _status.event.target) > 2; + }) + .set("target", player); + event.current = current; + } else { event.redo(); } - } - else{ + } else { event.goto(3); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.damages.push(event.current); - event.current.line(player,'green'); - game.log(event.current,'令',player,'回复1点体力'); + event.current.line(player, "green"); + game.log(event.current, "令", player, "回复1点体力"); player.recover(); } - if(event.targets.length){ + if (event.targets.length) { event.goto(1); } - 'step 3' - if(event.damages.length){ - var next=game.createEvent('rexingshuai_next'); + "step 3"; + if (event.damages.length) { + var next = game.createEvent("rexingshuai_next"); event.next.remove(next); trigger.after.push(next); - next.targets=event.damages; - next.setContent(function(){ + next.targets = event.damages; + next.setContent(function () { targets.shift().damage(); - if(targets.length) event.redo(); + if (targets.length) event.redo(); }); } }, - subSkill:{ - restore:{ - trigger:{ - global:'dieAfter', + subSkill: { + restore: { + trigger: { + global: "dieAfter", }, - charlotte:true, - forced:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source.hasSkill('mingjian2'); + charlotte: true, + forced: true, + filter: function (event, player) { + return event.source && event.source.isIn() && event.source.hasSkill("mingjian2"); + }, + content: function () { + player.restoreSkill("rexingshuai"); + game.log(player, "重置了", "#g【兴衰】"); }, - content:function(){ - player.restoreSkill('rexingshuai'); - game.log(player,'重置了','#g【兴衰】'); - } }, - } + }, }, //不想突破可以不突破的界曹冲 - rechengxiang:{ - audio:2, - group:'rechengxiang_gain', - trigger:{ - player:'rechengxiang_gainEnd', + rechengxiang: { + audio: 2, + group: "rechengxiang_gain", + trigger: { + player: "rechengxiang_gainEnd", }, - direct:true, - subfrequent:['gain'], - filter:function(event,player){ - return event.cards2&&event.cards2.map(card=>{ - return get.number(card); - }).reduce((sum,num)=>{ - return sum+=num; - },0)==13; + direct: true, + subfrequent: ["gain"], + filter: function (event, player) { + return ( + event.cards2 && + event.cards2 + .map((card) => { + return get.number(card); + }) + .reduce((sum, num) => { + return (sum += num); + }, 0) == 13 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.link(false); - 'step 1' + "step 1"; player.turnOver(false); }, - subSkill:{ - gain:{ - inherit:'chengxiang', - audio:'rechengxiang', - } - } + subSkill: { + gain: { + inherit: "chengxiang", + audio: "rechengxiang", + }, + }, }, //OL界二张 - olzhijian:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0; + olzhijian: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; }, - filterCard:function(card){ - return get.type(card)=='equip'; + filterCard: function (card) { + return get.type(card) == "equip"; }, - position:'he', - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); + position: "he", + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - return player!=target&&target.canEquip(card,true); + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + return player != target && target.canEquip(card, true); }, - content:function(){ + content: function () { target.equip(cards[0]); player.draw(); }, - discard:false, - lose:false, - prepare:function(cards,player,targets){ - player.$give(cards,targets[0],false); + discard: false, + lose: false, + prepare: function (cards, player, targets) { + player.$give(cards, targets[0], false); }, - ai:{ - basic:{ - order:10 + ai: { + basic: { + order: 10, }, - result:{ - target:function(player,target){ - var card=ui.selected.cards[0]; - if(card) return get.effect(target,card,target,target); + result: { + target: function (player, target) { + var card = ui.selected.cards[0]; + if (card) return get.effect(target, card, target, target); return 0; }, }, - threaten:1.35 - } - }, - olguzheng:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + threaten: 1.35, }, - filter:function(event,player){ - if(event.type!='discard') return false; - if(player.hasSkill('olguzheng_used')) return false; + }, + olguzheng: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], + }, + filter: function (event, player) { + if (event.type != "discard") return false; + if (player.hasSkill("olguzheng_used")) return false; var phaseName; - for(var name of lib.phaseName){ - var evt=event.getParent(name); - if(!evt||evt.name!=name) continue; - phaseName=name; + for (var name of lib.phaseName) { + var evt = event.getParent(name); + if (!evt || evt.name != name) continue; + phaseName = name; break; } - if(!phaseName) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(!evt||!evt.cards2||evt.cards2.filterInD('d').length<2) return false; + if (!phaseName) return false; + return game.hasPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (!evt || !evt.cards2 || evt.cards2.filterInD("d").length < 2) return false; return true; }); }, - checkx:function(event,player,cards){ - if(cards.length>2||get.attitude(player,event.player)>0) return true; - for(var i=0;i 2 || get.attitude(player, event.player) > 0) return true; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i], event.player, "raw") < 0) return true; } return false; }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - var targets=[],cardsList=[]; - var players=game.filterPlayer().sortBySeat(_status.currentPhase); - for(var current of players){ - if(current==player) continue; - var cards=[]; - var evt=trigger.getl(current); - if(!evt||!evt.cards2) continue; - var cardsx=evt.cards2.filterInD('d'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + var targets = [], + cardsList = []; + var players = game.filterPlayer().sortBySeat(_status.currentPhase); + for (var current of players) { + if (current == player) continue; + var cards = []; + var evt = trigger.getl(current); + if (!evt || !evt.cards2) continue; + var cardsx = evt.cards2.filterInD("d"); cards.addArray(cardsx); - if(cards.length){ + if (cards.length) { targets.push(current); cardsList.push(cards); } } - event.targets=targets; - event.cardsList=cardsList; - 'step 1' - var target=targets.shift(); - var cards=event.cardsList.shift(); - event.target=target; - event.cards=cards; - player.chooseButton(2,[ - get.prompt('olguzheng',target), - '被选择的牌将成为对方收回的牌', - cards, - [['获得剩余的牌','放弃剩余的牌'],'tdnodes'], - ]).set('filterButton',function(button){ - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - return true; - }).set('check',lib.skill.olguzheng.checkx(trigger,player,cards)).set('ai',function(button){ - if(typeof button.link=='string'){ - return button.link=='获得剩余的牌'?1:0; - } - if(_status.event.check){ - return 20-get.value(button.link,_status.event.getTrigger().player); - } - return 0; - }).setHiddenSkill('olguzheng'); - 'step 2' - if(result.bool){ - player.logSkill('olguzheng',target); - player.addTempSkill('olguzheng_used',['phaseZhunbeiAfter','phaseDrawAfter','phaseJudgeAfter','phaseUseAfter','phaseDiscardAfter','phaseJieshuAfter']); - if(typeof result.links[0]!='string') result.links.reverse(); - var card=result.links[1]; - target.gain(card,'gain2'); + event.targets = targets; + event.cardsList = cardsList; + "step 1"; + var target = targets.shift(); + var cards = event.cardsList.shift(); + event.target = target; + event.cards = cards; + player + .chooseButton(2, [ + get.prompt("olguzheng", target), + '被选择的牌将成为对方收回的牌', + cards, + [["获得剩余的牌", "放弃剩余的牌"], "tdnodes"], + ]) + .set("filterButton", function (button) { + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + return true; + }) + .set("check", lib.skill.olguzheng.checkx(trigger, player, cards)) + .set("ai", function (button) { + if (typeof button.link == "string") { + return button.link == "获得剩余的牌" ? 1 : 0; + } + if (_status.event.check) { + return 20 - get.value(button.link, _status.event.getTrigger().player); + } + return 0; + }) + .setHiddenSkill("olguzheng"); + "step 2"; + if (result.bool) { + player.logSkill("olguzheng", target); + player.addTempSkill("olguzheng_used", [ + "phaseZhunbeiAfter", + "phaseDrawAfter", + "phaseJudgeAfter", + "phaseUseAfter", + "phaseDiscardAfter", + "phaseJieshuAfter", + ]); + if (typeof result.links[0] != "string") result.links.reverse(); + var card = result.links[1]; + target.gain(card, "gain2"); event.cards.remove(card); - if(result.links[0]!='获得剩余的牌') event.finish(); - } - else if(event.targets.length) event.goto(1); + if (result.links[0] != "获得剩余的牌") event.finish(); + } else if (event.targets.length) event.goto(1); else event.finish(); - 'step 3' - var cards=cards.filterInD('d'); - if(cards.length>0) player.gain(cards,'gain2'); + "step 3"; + var cards = cards.filterInD("d"); + if (cards.length > 0) player.gain(cards, "gain2"); }, - ai:{ - threaten:1.3, - expose:0.2 + ai: { + threaten: 1.3, + expose: 0.2, }, - subSkill:{ - used:{ - charlotte:true, - } + subSkill: { + used: { + charlotte: true, + }, }, }, //SP黄月英 - rejiqiao:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + rejiqiao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('rejiqiao'),[1,player.countCards('he')],'he').set('ai',function(card){ - if(card.name=='bagua') return 10; - return 7-get.value(card); - }).set('logSkill','rejiqiao'); - 'step 1' - if(result.bool){ - var num=result.cards.length; - for(var i of result.cards){ - if(get.type(i,false)=='equip') num++; + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("rejiqiao"), [1, player.countCards("he")], "he") + .set("ai", function (card) { + if (card.name == "bagua") return 10; + return 7 - get.value(card); + }) + .set("logSkill", "rejiqiao"); + "step 1"; + if (result.bool) { + var num = result.cards.length; + for (var i of result.cards) { + if (get.type(i, false) == "equip") num++; } - event.cards=game.cardsGotoOrdering(get.cards(num)).cards; + event.cards = game.cardsGotoOrdering(get.cards(num)).cards; player.showCards(event.cards); - } - else{ + } else { event.finish(); } - 'step 2' - var gained=[]; - var tothrow=[]; - for(var i=0;i get.subtypes(i).includes("equip5"))) + return false; } - else if(event.name!='phase'&&(event.name!='equip'||event.player!=player)){ - var evt=event.getl(player); - if(!evt||!evt.es||!evt.es.some(i=>get.subtypes(i).includes('equip5'))) return false; - } - var skills=player.additionalSkills['relinglong']; - return (skills&&skills.length>0)!=player.hasEmptySlot(5); + var skills = player.additionalSkills["relinglong"]; + return (skills && skills.length > 0) != player.hasEmptySlot(5); }, - direct:true, - content:function(){ - player.removeAdditionalSkill('relinglong'); - if(player.hasEmptySlot(5)){ - player.addAdditionalSkill('relinglong',['reqicai']); + direct: true, + content: function () { + player.removeAdditionalSkill("relinglong"); + if (player.hasEmptySlot(5)) { + player.addAdditionalSkill("relinglong", ["reqicai"]); } }, - group:['linglong_bagua','relinglong_directhit'], - mod:{ - maxHandcard:function(player,num){ - if(!player.hasEmptySlot(3)||!player.hasEmptySlot(4)) return; - return num+2; + group: ["linglong_bagua", "relinglong_directhit"], + mod: { + maxHandcard: function (player, num) { + if (!player.hasEmptySlot(3) || !player.hasEmptySlot(4)) return; + return num + 2; }, }, - subSkill:{ - directhit:{ - audio:'relinglong', - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha'&&get.type(event.card,false)!='trick') return false; - for(var i=2;i<6;i++){ - if(!player.hasEmptySlot(i)) return false; + subSkill: { + directhit: { + audio: "relinglong", + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha" && get.type(event.card, false) != "trick") + return false; + for (var i = 2; i < 6; i++) { + if (!player.hasEmptySlot(i)) return false; } return true; }, - content:function(){ + content: function () { trigger.directHit.addArray(game.players); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.target||(arg.card.name!='sha'&&get.type(arg.card,false)!='trick')) return false; - for(var i=2;i<6;i++){ - if(!player.hasEmptySlot(i)) return false; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + !arg || + !arg.card || + !arg.target || + (arg.card.name != "sha" && get.type(arg.card, false) != "trick") + ) + return false; + for (var i = 2; i < 6; i++) { + if (!player.hasEmptySlot(i)) return false; } return true; }, }, - } - } + }, + }, }, //张松 - rexiantu:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player!=player; + rexiantu: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return event.player != player; }, - logTarget:'player', - check:function(event,player){ - 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'); + logTarget: "player", + check: function (event, player) { + 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); + 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'); - if(!cards.length) event.finish(); - else if(cards.length<=2) event._result={cards:cards}; - else player.chooseCard(2,'he',true,'交给'+get.translation(trigger.player)+'两张牌').set('ai',function(card){ - if(ui.selected.cards.length&&card.name==ui.selected.cards[0].name) return -1; - if(get.tag(card,'damage')) return 1; - if(get.type(card)=='equip') return 1; - return 0; - }); - 'step 2' - player.give(result.cards,trigger.player); - trigger.player.addTempSkill('rexiantu_check','phaseUseAfter'); - trigger.player.markAuto('rexiantu_check',[player]); + "step 1"; + var cards = player.getCards("he"); + if (!cards.length) event.finish(); + else if (cards.length <= 2) event._result = { cards: cards }; + else + player + .chooseCard(2, "he", true, "交给" + get.translation(trigger.player) + "两张牌") + .set("ai", function (card) { + if (ui.selected.cards.length && card.name == ui.selected.cards[0].name) + return -1; + if (get.tag(card, "damage")) return 1; + if (get.type(card) == "equip") return 1; + return 0; + }); + "step 2"; + player.give(result.cards, trigger.player); + trigger.player.addTempSkill("rexiantu_check", "phaseUseAfter"); + trigger.player.markAuto("rexiantu_check", [player]); }, - ai:{ - threaten:function(player,target){ - return 1+game.countPlayer((current)=>{ - if(current!=target&&get.attitude(target,current)>0) return 0.5; - return 0; - }); + ai: { + 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 + expose: 0.3, }, - subSkill:{ - check:{ - charlotte:true, - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - onremove:true, - filter:function(event,player){ - return !player.getHistory('sourceDamage',evt=>{ - return evt.getParent('phaseUse')==event; + subSkill: { + check: { + charlotte: true, + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + onremove: true, + filter: function (event, player) { + return !player.getHistory("sourceDamage", (evt) => { + return evt.getParent("phaseUse") == event; }).length; }, - content:function(){ - var targets=player.getStorage('rexiantu_check'); + content: function () { + var targets = player.getStorage("rexiantu_check"); targets.sortBySeat(); - for(var i of targets){ - if(i.isIn()){ + for (var i of targets) { + if (i.isIn()) { i.loseHp(); } } - player.removeSkill('rexiantu_check'); - } - } - } + player.removeSkill("rexiantu_check"); + }, + }, + }, }, //新服公孙瓒 - dcyicong:{ - trigger:{ - player:["changeHp"], + dcyicong: { + trigger: { + player: ["changeHp"], }, - audio:2, - forced:true, - filter:function(event,player){ - return get.sgn(player.getDamagedHp()-1.5)!=get.sgn(player.getDamagedHp()-1.5+event.num); + audio: 2, + forced: true, + filter: function (event, player) { + return ( + get.sgn(player.getDamagedHp() - 1.5) != + get.sgn(player.getDamagedHp() - 1.5 + event.num) + ); }, - content:function (){}, - mod:{ - globalFrom:function(from,to,current){ - return current-1; + content: function () {}, + mod: { + globalFrom: function (from, to, current) { + return current - 1; }, - globalTo:function(from,to,current){ - if(to.getDamagedHp()>=2) return current+1; + globalTo: function (from, to, current) { + if (to.getDamagedHp() >= 2) return current + 1; }, }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, //朱治 - reanguo:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - if(target.isMinHandcard()){ + reanguo: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + if (target.isMinHandcard()) { target.draw(); - event.h=true; + event.h = true; } - 'step 1' - if(target.isMinHp()&&target.isDamaged()){ + "step 1"; + if (target.isMinHp() && target.isDamaged()) { target.recover(); - event.hp=true; + event.hp = true; } - 'step 2' - var equip=get.cardPile(function(card){ - return get.type(card)=='equip'&&target.hasUseTarget(card); + "step 2"; + var equip = get.cardPile(function (card) { + return get.type(card) == "equip" && target.hasUseTarget(card); }); - if(target.isMinEquip()&&equip){ - target.chooseUseTarget(equip,'nothrow','nopopup',true); - event.e=true; + if (target.isMinEquip() && equip) { + target.chooseUseTarget(equip, "nothrow", "nopopup", true); + event.e = true; } - 'step 3' + "step 3"; game.updateRoundNumber(); - if(!event.h&&player.isMinHandcard()){ + if (!event.h && player.isMinHandcard()) { player.draw(); - event.h=true; + event.h = true; } - 'step 4' - if(!event.hp&&player.isMinHp()&&player.isDamaged()){ + "step 4"; + if (!event.hp && player.isMinHp() && player.isDamaged()) { player.recover(); - event.hp=true; + event.hp = true; } - 'step 5' - if(!event.e&&player.isMinEquip()){ - var equip=get.cardPile(function(card){ - return get.type(card)=='equip'&&player.hasUseTarget(card); + "step 5"; + if (!event.e && player.isMinEquip()) { + var equip = get.cardPile(function (card) { + return get.type(card) == "equip" && player.hasUseTarget(card); }); - if(equip){ - player.chooseUseTarget(equip,'nothrow','nopopup',true); - event.e=true; + if (equip) { + player.chooseUseTarget(equip, "nothrow", "nopopup", true); + event.e = true; } } - 'step 6' - if(event.h&&event.hp&&event.e){ - player.chooseCard('安国:是否重铸任意张牌?',[1,Infinity],lib.filter.cardRecastable,'he').set('ai',card=>{ - return 6-get.value(card); - }); - } - else event.finish(); - 'step 7' - if(result.bool){ + "step 6"; + if (event.h && event.hp && event.e) { + player + .chooseCard( + "安国:是否重铸任意张牌?", + [1, Infinity], + lib.filter.cardRecastable, + "he" + ) + .set("ai", (card) => { + return 6 - get.value(card); + }); + } else event.finish(); + "step 7"; + if (result.bool) { player.recast(result.cards); } }, - ai:{ - threaten:1.65, - order:9, - result:{ - player:function(player,target){ - if(get.attitude(player,target)<=0){ - if(target.isMinHandcard()||target.isMinEquip()||target.isMinHp()) return -1; + ai: { + threaten: 1.65, + order: 9, + result: { + player: function (player, target) { + if (get.attitude(player, target) <= 0) { + if (target.isMinHandcard() || target.isMinEquip() || target.isMinHp()) + return -1; } - var num=0; - if(player.isMinHandcard()||target.isMinHandcard()) num++; - if(player.isMinEquip()||target.isMinEquip()) num++; - if((player.isMinHp()&&player.isDamaged())||(target.isMinHp()&&target.isDamaged())) num+=2.1; + var num = 0; + if (player.isMinHandcard() || target.isMinHandcard()) num++; + if (player.isMinEquip() || target.isMinEquip()) num++; + if ( + (player.isMinHp() && player.isDamaged()) || + (target.isMinHp() && target.isDamaged()) + ) + num += 2.1; return num; - } - } - } + }, + }, + }, }, //颜良文丑 - olshuangxiong:{ - audio:2, - trigger:{player:'phaseDrawEnd'}, - direct:true, - filter:(event,player)=>player.countCards('he')>0, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('olshuangxiong'),'弃置一张牌,然后你本回合内可以将一张与此牌颜色不同的牌当做【决斗】使用').set('ai',function(card){ - let player=_status.event.player; - if(!_status.event.goon||player.skipList.includes('phaseUse')) return -get.value(card); - let color=get.color(card),effect=0,cards=player.getCards('hes'),sha=false; - for(var cardx of cards){ - if(cardx==card||get.color(cardx)==color) continue; - var cardy=get.autoViewAs({name:'juedou'},[cardx]),eff1=player.getUseValue(cardy); - if(get.position(cardx)=='e'){ - var eff2=get.value(cardx); - if(eff1>eff2) effect+=(eff1-eff2); - continue; - } - else if(get.name(cardx)=='sha'){ - if(sha){ - effect+=eff1; + olshuangxiong: { + audio: 2, + trigger: { player: "phaseDrawEnd" }, + direct: true, + filter: (event, player) => player.countCards("he") > 0, + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("olshuangxiong"), + "弃置一张牌,然后你本回合内可以将一张与此牌颜色不同的牌当做【决斗】使用" + ) + .set("ai", function (card) { + let player = _status.event.player; + if (!_status.event.goon || player.skipList.includes("phaseUse")) + return -get.value(card); + let color = get.color(card), + effect = 0, + cards = player.getCards("hes"), + sha = false; + for (var cardx of cards) { + if (cardx == card || get.color(cardx) == color) continue; + var cardy = get.autoViewAs({ name: "juedou" }, [cardx]), + eff1 = player.getUseValue(cardy); + if (get.position(cardx) == "e") { + var eff2 = get.value(cardx); + if (eff1 > eff2) effect += eff1 - eff2; continue; + } else if (get.name(cardx) == "sha") { + if (sha) { + effect += eff1; + continue; + } else sha = true; } - else sha=true; + var eff2 = player.getUseValue(cardx, null, true); + if (eff1 > eff2) effect += eff1 - eff2; } - var eff2=player.getUseValue(cardx,null,true); - if(eff1>eff2) effect+=(eff1-eff2); - } - return effect-get.value(card); - }).set('goon',player.hasValueTarget({name:'juedou'})&&!player.hasSkill('olshuangxiong_effect')).logSkill='olshuangxiong'; - 'step 1' - if(result.bool){ - var color=get.color(result.cards[0],player); - player.markAuto('olshuangxiong_effect',[color]); - player.addTempSkill('olshuangxiong_effect'); + return effect - get.value(card); + }) + .set( + "goon", + player.hasValueTarget({ name: "juedou" }) && + !player.hasSkill("olshuangxiong_effect") + ).logSkill = "olshuangxiong"; + "step 1"; + if (result.bool) { + var color = get.color(result.cards[0], player); + player.markAuto("olshuangxiong_effect", [color]); + player.addTempSkill("olshuangxiong_effect"); } }, - group:'olshuangxiong_jianxiong', - subSkill:{ - effect:{ - audio:'olshuangxiong', - enable:'chooseToUse', - viewAs:{name:'juedou'}, - position:'hes', - viewAsFilter:function(player){ - return player.hasCard(card=>lib.skill.olshuangxiong_effect.filterCard(card,player),'hes'); + group: "olshuangxiong_jianxiong", + subSkill: { + effect: { + audio: "olshuangxiong", + enable: "chooseToUse", + viewAs: { name: "juedou" }, + position: "hes", + viewAsFilter: function (player) { + return player.hasCard( + (card) => lib.skill.olshuangxiong_effect.filterCard(card, player), + "hes" + ); }, - filterCard:function(card,player){ - var color=get.color(card),colors=player.getStorage('olshuangxiong_effect'); - for(var i of colors){ - if(color!=i) return true; + filterCard: function (card, player) { + var color = get.color(card), + colors = player.getStorage("olshuangxiong_effect"); + for (var i of colors) { + if (color != i) return true; } return false; }, - prompt:function(){ - var colors=_status.event.player.getStorage('olshuangxiong_effect'); - var str='将一张颜色'; - for(var i=0;i0) str+='或'; - str+='不为'; - str+=get.translation(colors[i]); + prompt: function () { + var colors = _status.event.player.getStorage("olshuangxiong_effect"); + var str = "将一张颜色"; + for (var i = 0; i < colors.length; i++) { + if (i > 0) str += "或"; + str += "不为"; + str += get.translation(colors[i]); } - str+='的牌当做【决斗】使用'; + str += "的牌当做【决斗】使用"; return str; }, - check:function(card){ - var player=_status.event.player; - if(get.position(card)=='e'){ - var raw=get.value(card); - var eff=player.getUseValue(get.autoViewAs({name:'juedou'},[card])); - return eff-raw; + check: function (card) { + var player = _status.event.player; + if (get.position(card) == "e") { + var raw = get.value(card); + var eff = player.getUseValue(get.autoViewAs({ name: "juedou" }, [card])); + return eff - raw; } - var raw=player.getUseValue(card,null,true); - var eff=player.getUseValue(get.autoViewAs({name:'juedou'},[card])); - return eff-raw; + var raw = player.getUseValue(card, null, true); + var eff = player.getUseValue(get.autoViewAs({ name: "juedou" }, [card])); + return eff - raw; }, - onremove:true, - charlotte:true, - ai:{order:7}, + onremove: true, + charlotte: true, + ai: { order: 7 }, }, - jianxiong:{ - audio:'olshuangxiong', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.hasHistory('damage',function(evt){ + jianxiong: { + audio: "olshuangxiong", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return player.hasHistory("damage", function (evt) { //Disable Umi Kato's chaofan - return evt.card&&evt.cards&&evt.cards.some(card=>get.position(card,true)); + return ( + evt.card && + evt.cards && + evt.cards.some((card) => get.position(card, true)) + ); }); }, - content:function(){ - var cards=[]; - player.getHistory('damage',function(evt){ - if(evt.card&&evt.cards) cards.addArray(evt.cards.filter(card=>get.position(card,true))); + content: function () { + var cards = []; + player.getHistory("damage", function (evt) { + if (evt.card && evt.cards) + cards.addArray(evt.cards.filter((card) => get.position(card, true))); }); - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, }, }, }, //新李典 - xinwangxi:{ - audio:'wangxi', - trigger:{player:'damageEnd',source:'damageSource'}, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.num&&event.source&&event.player&& - event.player.isIn()&&event.source.isIn()&&event.source!=event.player; + xinwangxi: { + audio: "wangxi", + trigger: { player: "damageEnd", source: "damageSource" }, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.num && + event.source && + event.player && + event.player.isIn() && + event.source.isIn() && + event.source != event.player + ); }, - check:function(event,player){ - if(player.isPhaseUsing()) return true; - if(event.player==player) return get.attitude(player,event.source)>-5; - return get.attitude(player,event.player)>-5; + check: function (event, player) { + if (player.isPhaseUsing()) return true; + if (event.player == player) return get.attitude(player, event.source) > -5; + return get.attitude(player, event.player) > -5; }, - logTarget:function(event,player){ - if(event.player==player) return event.source; + logTarget: function (event, player) { + if (event.player == player) return event.source; return event.player; }, - preHidden:true, - content:function(){ - 'step 0' - event.count=trigger.num; - event.target=lib.skill.xinwangxi.logTarget(trigger,player); - 'step 1' + preHidden: true, + content: function () { + "step 0"; + event.count = trigger.num; + event.target = lib.skill.xinwangxi.logTarget(trigger, player); + "step 1"; player.draw(2); event.count--; - 'step 2' - var cards=player.getCards('he'); - if(cards.length>0&&target.isIn()){ - if(cards.length==1) event._result={bool:true,cards:cards}; - else player.chooseCard('he','忘隙:交给'+get.translation(target)+'一张牌',true); + "step 2"; + var cards = player.getCards("he"); + if (cards.length > 0 && target.isIn()) { + if (cards.length == 1) event._result = { bool: true, cards: cards }; + else player.chooseCard("he", "忘隙:交给" + get.translation(target) + "一张牌", true); + } else event.goto(4); + "step 3"; + if (result.bool) { + player.give(result.cards, target); } - else event.goto(4); - 'step 3' - if(result.bool){ - player.give(result.cards,target); - } - 'step 4' - if(event.count&&target.isIn()&&player.hasSkill('xinwangxi')){ - player.chooseBool(get.prompt2('xinwangxi',target)); - } - else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('xinwangxi',target); + "step 4"; + if (event.count && target.isIn() && player.hasSkill("xinwangxi")) { + player.chooseBool(get.prompt2("xinwangxi", target)); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("xinwangxi", target); event.goto(1); } }, - ai:{ - maixie:true, - maixie_hp:true - } + ai: { + maixie: true, + maixie_hp: true, + }, }, //OL界火诸葛 - olhuoji:{ - audio:'rehuoji', - audioname:['ol_sp_zhugeliang'], - trigger:{player:'huogongBegin'}, - forced:true, - locked:false, - popup:false, - group:'olhuoji_viewAs', - content:function(){ + olhuoji: { + audio: "rehuoji", + audioname: ["ol_sp_zhugeliang"], + trigger: { player: "huogongBegin" }, + forced: true, + locked: false, + popup: false, + group: "olhuoji_viewAs", + content: function () { trigger.setContent(lib.skill.olhuoji.huogongContent); }, - huogongContent:function(){ - "step 0" - if(target.countCards('h')==0){ + huogongContent: function () { + "step 0"; + if (target.countCards("h") == 0) { event.finish(); return; } - event._result={cards:target.getCards('h').randomGets(1)}; - "step 1" - target.showCards(result.cards).setContent(function(){}); - event.dialog=ui.create.dialog(get.translation(target)+'展示的手牌',result.cards); - event.videoId=lib.status.videoId++; + event._result = { cards: target.getCards("h").randomGets(1) }; + "step 1"; + target.showCards(result.cards).setContent(function () {}); + event.dialog = ui.create.dialog(get.translation(target) + "展示的手牌", result.cards); + event.videoId = lib.status.videoId++; - game.broadcast('createDialog',event.videoId,get.translation(target)+'展示的手牌',result.cards); - game.addVideo('cardDialog',null,[get.translation(target)+'展示的手牌',get.cardsInfo(result.cards),event.videoId]); - event.card2=result.cards[0]; - game.log(target,'展示了',event.card2); - event._result={}; - player.chooseToDiscard({color:get.color(event.card2)},'he',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 -1; - }).set('prompt',false); + game.broadcast( + "createDialog", + event.videoId, + get.translation(target) + "展示的手牌", + result.cards + ); + game.addVideo("cardDialog", null, [ + get.translation(target) + "展示的手牌", + get.cardsInfo(result.cards), + event.videoId, + ]); + event.card2 = result.cards[0]; + game.log(target, "展示了", event.card2); + event._result = {}; + player + .chooseToDiscard({ color: get.color(event.card2) }, "he", 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 -1; + }) + .set("prompt", false); game.delay(2); - "step 2" - if(result.bool){ - target.damage('fire'); - } - else{ - target.addTempSkill('huogong2'); + "step 2"; + if (result.bool) { + target.damage("fire"); + } else { + target.addTempSkill("huogong2"); } event.dialog.close(); - game.addVideo('cardDialog',null,event.videoId); - game.broadcast('closeDialog',event.videoId); + game.addVideo("cardDialog", null, event.videoId); + game.broadcast("closeDialog", event.videoId); }, - subSkill:{viewAs:{inherit:'rehuoji',audio:'rehuoji'}} + subSkill: { viewAs: { inherit: "rehuoji", audio: "rehuoji" } }, }, - olkanpo:{ - audio:'rekanpo', - audioname:['ol_sp_zhugeliang','ol_pangtong'], - trigger:{player:'useCard'}, - forced:true, - locked:false, - popup:false, - group:'olkanpo_viewAs', - filter:function(event,player){ - return event.card.name=='wuxie'; + olkanpo: { + audio: "rekanpo", + audioname: ["ol_sp_zhugeliang", "ol_pangtong"], + trigger: { player: "useCard" }, + forced: true, + locked: false, + popup: false, + group: "olkanpo_viewAs", + filter: function (event, player) { + return event.card.name == "wuxie"; }, - content:function(){ + content: function () { trigger.directHit.addArray(game.players); }, - subSkill:{viewAs:{inherit:'rekanpo',audio:'rekanpo'}} + subSkill: { viewAs: { inherit: "rekanpo", audio: "rekanpo" } }, }, //新杀界曹植 - dcjiushi:{ - audio:2, - trigger:{ - player:'useCardAfter', + dcjiushi: { + audio: 2, + trigger: { + player: "useCardAfter", }, - filter:function(event,player){ - return event.card.name=='jiu'; + filter: function (event, player) { + return event.card.name == "jiu"; }, - forced:true, - locked:false, - content:function(){ - player.addTempSkill('dcjiushi_sha',{player:'phaseEnd'}); - player.addMark('dcjiushi_sha',1,false); + forced: true, + locked: false, + content: function () { + player.addTempSkill("dcjiushi_sha", { player: "phaseEnd" }); + player.addMark("dcjiushi_sha", 1, false); }, - group:['dcjiushi_use','dcjiushi_record','dcjiushi_damage'], - subSkill:{ - use:{ - audio:'dcjiushi', - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(name=='jiu') return !player.isTurnedOver(); + group: ["dcjiushi_use", "dcjiushi_record", "dcjiushi_damage"], + subSkill: { + use: { + audio: "dcjiushi", + enable: "chooseToUse", + hiddenCard: function (player, name) { + if (name == "jiu") return !player.isTurnedOver(); return false; }, - filter:function(event,player){ - if(player.isTurnedOver()) return false; - return event.filterCard({name:'jiu',isCard:true},player,event); + filter: function (event, player) { + if (player.isTurnedOver()) return false; + return event.filterCard({ name: "jiu", isCard: true }, player, event); }, - content:function(){ - if(_status.event.getParent(2).type=='dying'){ - event.dying=player; - event.type='dying'; + content: function () { + if (_status.event.getParent(2).type == "dying") { + event.dying = player; + event.type = "dying"; } player.turnOver(); - player.useCard({name:'jiu',isCard:true},player); + player.useCard({ name: "jiu", isCard: true }, player); }, - ai:{ - order:5, - result:{ - player:function(player){ - if(_status.event.parent.name=='phaseUse'){ - if(player.countCards('h','jiu')>0) return 0; - if(player.getEquip('zhuge')&&player.countCards('h','sha')>1) return 0; - if(!player.countCards('h','sha')) return 0; - var targets=[]; + ai: { + order: 5, + result: { + player: function (player) { + if (_status.event.parent.name == "phaseUse") { + if (player.countCards("h", "jiu") > 0) return 0; + if (player.getEquip("zhuge") && player.countCards("h", "sha") > 1) + return 0; + if (!player.countCards("h", "sha")) return 0; + var targets = []; var target; - var players=game.filterPlayer(); - for(var i=0;inum){ - target=targets[i]; - num=num2; + var num = get.effect(target, { name: "sha" }, player, player); + for (var i = 1; i < targets.length; i++) { + var num2 = get.effect( + targets[i], + { name: "sha" }, + player, + player + ); + if (num2 > num) { + target = targets[i]; + num = num2; } } - if(num<=0) return 0; - var e2=target.getEquip(2); - if(e2){ - if(e2.name=='tengjia'){ - if(!player.countCards('h',{name:'sha',nature:'fire'})&&!player.getEquip('zhuque')) return 0; + if (num <= 0) return 0; + var e2 = target.getEquip(2); + if (e2) { + if (e2.name == "tengjia") { + if ( + !player.countCards("h", { + name: "sha", + nature: "fire", + }) && + !player.getEquip("zhuque") + ) + return 0; } - if(e2.name=='renwang'){ - if(!player.countCards('h',{name:'sha',color:'red'})) return 0; + if (e2.name == "renwang") { + if (!player.countCards("h", { name: "sha", color: "red" })) + return 0; } - if(e2.name=='baiyin') return 0; + if (e2.name == "baiyin") return 0; } - if(player.getEquip('guanshi')&&player.countCards('he')>2) return 1; - return target.countCards('h')>3?0:1; + if (player.getEquip("guanshi") && player.countCards("he") > 2) + return 1; + return target.countCards("h") > 3 ? 0 : 1; } - if(player==_status.event.dying||player.isTurnedOver()) return 3; - } + if (player == _status.event.dying || player.isTurnedOver()) return 3; + }, }, - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,0.5]; - if(target.isTurnedOver()){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp==1) return; - return [1,target.countCards('h')/2]; + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 0.5]; + if (target.isTurnedOver()) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (target.hp == 1) return; + return [1, target.countCards("h") / 2]; } } - } - } + }, + }, }, }, - record:{ - trigger:{player:'damageBegin3'}, - silent:true, - firstDo:true, - filter:function(event,player){ + record: { + trigger: { player: "damageBegin3" }, + silent: true, + firstDo: true, + filter: function (event, player) { return player.isTurnedOver(); }, - content:function(){ - trigger.dcjiushi=true; - } + content: function () { + trigger.dcjiushi = true; + }, }, - damage:{ - audio:'dcjiushi', - trigger:{player:'damageEnd'}, - check:function(event,player){ + damage: { + audio: "dcjiushi", + trigger: { player: "damageEnd" }, + check: function (event, player) { return player.isTurnedOver(); }, - prompt:'是否发动【酒诗】,将武将牌翻面?', - filter:function(event,player){ - if(event.dcjiushi){ + prompt: "是否发动【酒诗】,将武将牌翻面?", + filter: function (event, player) { + if (event.dcjiushi) { return true; } return false; }, - content:function(){ + content: function () { delete trigger.dcjiushi; player.turnOver(); - } + }, }, - sha:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('dcjiushi_sha'); + sha: { + charlotte: true, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("dcjiushi_sha"); }, }, }, - } + }, }, //OL界黄忠 - remoshi:{ - audio:2, - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.player.isIn()&&event.card&&event.card.name=='sha'&&event.cards.filterInD('od').length&& - event.notLink()&&[2,3,4].some(i=>event.player.getEquips(i).length>0); + remoshi: { + audio: 2, + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + return ( + event.player.isIn() && + event.card && + event.card.name == "sha" && + event.cards.filterInD("od").length && + event.notLink() && + [2, 3, 4].some((i) => event.player.getEquips(i).length > 0) + ); }, - group:'remoshi_retrieve', - content:function(){ - trigger.player.addSkill('remoshi_stuck') - trigger.player.addToExpansion(trigger.cards.filterInD('od'),'gain2').gaintag.add('remoshi_stuck'); + group: "remoshi_retrieve", + content: function () { + trigger.player.addSkill("remoshi_stuck"); + trigger.player + .addToExpansion(trigger.cards.filterInD("od"), "gain2") + .gaintag.add("remoshi_stuck"); }, - subSkill:{ - retrieve:{ - audio:'remoshi', - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + retrieve: { + audio: "remoshi", + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var keys=['equip2','equip3','equip4']; - return game.hasPlayer(current=>{ - if(event.name=='gain'&¤t==player) return false; - var cards=current.getExpansions('remoshi_stuck'); - if(!cards.length) return false; - var evt=event.getl(current); - if(evt&&evt.cards2&&evt.cards2.some(i=>get.subtypes(i).some(slot=>keys.includes(slot)))) return true; + filter: function (event, player) { + var keys = ["equip2", "equip3", "equip4"]; + return game.hasPlayer((current) => { + if (event.name == "gain" && current == player) return false; + var cards = current.getExpansions("remoshi_stuck"); + if (!cards.length) return false; + var evt = event.getl(current); + if ( + evt && + evt.cards2 && + evt.cards2.some((i) => + get.subtypes(i).some((slot) => keys.includes(slot)) + ) + ) + return true; }); }, - direct:true, - forced:true, - content:function(){ - 'step 0' - var keys=['equip2','equip3','equip4']; - var targets=game.filterPlayer(current=>{ - var cards=current.getExpansions('remoshi_stuck'); - if(!cards.length) return false; - var evt=trigger.getl(current); - if(evt&&evt.cards2&&evt.cards2.some(i=>get.subtypes(i).some(slot=>keys.includes(slot)))) return true; + direct: true, + forced: true, + content: function () { + "step 0"; + var keys = ["equip2", "equip3", "equip4"]; + var targets = game.filterPlayer((current) => { + var cards = current.getExpansions("remoshi_stuck"); + if (!cards.length) return false; + var evt = trigger.getl(current); + if ( + evt && + evt.cards2 && + evt.cards2.some((i) => + get.subtypes(i).some((slot) => keys.includes(slot)) + ) + ) + return true; }); - event.targets=targets; - 'step 1' - var target=targets.shift(); - var cards=target.getExpansions('remoshi_stuck'); - if(cards.length){ - player.logSkill('remoshi_retrieve',target); - player.gain(cards,target,'give','bySelf'); + event.targets = targets; + "step 1"; + var target = targets.shift(); + var cards = target.getExpansions("remoshi_stuck"); + if (cards.length) { + player.logSkill("remoshi_retrieve", target); + player.gain(cards, target, "give", "bySelf"); game.delayx(); } - if(targets.length) event.redo(); + if (targets.length) event.redo(); }, }, - stuck:{ - marktext:'矢', - charlotte:true, - intro:{ - name:'没矢', - name2:'矢', - content:'expansion', - markcount:'expansion', + stuck: { + marktext: "矢", + charlotte: true, + intro: { + name: "没矢", + name2: "矢", + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - } - } + }, + }, }, //界文聘 - rezhenwei:{ - audio:'zhenwei', - inherit:'zhenwei', - filter:function(event,player){ - if(player==event.target) return false; - if(!player.countCards('he')) return false; - if(event.targets.length>1) return false; - if(!event.target) return false; - if(event.target.hp>player.hp) return false; - var card=event.card; - if(card.name=='sha') return true; - if(get.color(card)=='black'&&get.type(card,'trick')=='trick') return true; + rezhenwei: { + audio: "zhenwei", + inherit: "zhenwei", + filter: function (event, player) { + if (player == event.target) return false; + if (!player.countCards("he")) return false; + if (event.targets.length > 1) return false; + if (!event.target) return false; + if (event.target.hp > player.hp) return false; + var card = event.card; + if (card.name == "sha") return true; + if (get.color(card) == "black" && get.type(card, "trick") == "trick") return true; return false; }, }, //界关张…… - retongxin:{ - mod:{ - attackRange:(player,num)=>num+2 - } + retongxin: { + mod: { + attackRange: (player, num) => num + 2, + }, }, //马忠 - refuman:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - if(target==player) return false; - var stat=player.getStat('skill').refuman_targets; - return !stat||!stat.includes(target); + refuman: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + if (target == player) return false; + var stat = player.getStat("skill").refuman_targets; + return !stat || !stat.includes(target); }, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer((current)=>lib.skill.refuman.filterTarget(null,player,current)); + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer((current) => lib.skill.refuman.filterTarget(null, player, current)) + ); }, - filterCard:true, - content:function(){ - var card=get.discardPile(card=>card.name=='sha'); - if(card){ - target.gain(card,'gain2').gaintag.add('refuman'); - target.addTempSkill('refuman2',{player:'phaseAfter'}); - player.addSkill('refuman_draw'); + filterCard: true, + content: function () { + var card = get.discardPile((card) => card.name == "sha"); + if (card) { + target.gain(card, "gain2").gaintag.add("refuman"); + target.addTempSkill("refuman2", { player: "phaseAfter" }); + player.addSkill("refuman_draw"); } - var stat=player.getStat('skill'); - if(!stat.refuman_targets) stat.refuman_targets=[]; + var stat = player.getStat("skill"); + if (!stat.refuman_targets) stat.refuman_targets = []; stat.refuman_targets.push(target); }, - check:function(card){ - return get.discardPile(card=>card.name=='sha')?6-get.value(card):0; + check: function (card) { + return get.discardPile((card) => card.name == "sha") ? 6 - get.value(card) : 0; }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(!target.hasSha()) return 1.2; + ai: { + order: 2, + result: { + target: function (player, target) { + if (!target.hasSha()) return 1.2; return 1; - } - } + }, + }, }, - subSkill:{ - draw:{ - trigger:{global:['useCard','respond']}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('refuman')) return true; + subSkill: { + draw: { + trigger: { global: ["useCard", "respond"] }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("refuman")) return true; } return false; }); }, - logTarget:'player', - content:function(){ - game.asyncDraw([trigger.player,player]); + logTarget: "player", + content: function () { + game.asyncDraw([trigger.player, player]); }, }, }, }, - refuman2:{ - onremove:function(player){ - player.removeGaintag('refuman'); + refuman2: { + onremove: function (player) { + player.removeGaintag("refuman"); }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('refuman')) return num+1; - } + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("refuman")) return num + 1; + }, }, }, //十周年陈群 - repindi:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - return !player.getStorage('repindi_target').includes(target); + repindi: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + return !player.getStorage("repindi_target").includes(target); }, - filterCard:function(card,player){ - return !player.getStorage('repindi_type').includes(get.type2(card)); + filterCard: function (card, player) { + return !player.getStorage("repindi_type").includes(get.type2(card)); }, - check:function(card){ - var num=_status.event.player.getStat('skill').repindi||0; - return 6+num-get.value(card); + check: function (card) { + var num = _status.event.player.getStat("skill").repindi || 0; + return 6 + num - get.value(card); }, - position:'he', - content:function(){ - 'step 0' - player.addTempSkill('repindi_clear',['phaseUseAfter','phaseAfter']); - player.markAuto('repindi_target',[target]); - player.markAuto('repindi_type',[get.type2(cards[0],cards[0].original=='h'?player:false)]); - event.num=player.getStat('skill').repindi; + position: "he", + content: function () { + "step 0"; + player.addTempSkill("repindi_clear", ["phaseUseAfter", "phaseAfter"]); + player.markAuto("repindi_target", [target]); + player.markAuto("repindi_type", [ + get.type2(cards[0], cards[0].original == "h" ? player : false), + ]); + event.num = player.getStat("skill").repindi; player.syncStorage(); - if(target.countCards('he')==0) event._result={index:0}; - else{ - player.chooseControlList([ - '令'+get.translation(target)+'摸'+get.cnNumber(event.num)+'张牌', - '令'+get.translation(target)+'弃置'+get.cnNumber(event.num)+'张牌' - ],function(){ - return _status.event.choice; - }).set('choice',get.attitude(player,target)>0?0:1); + if (target.countCards("he") == 0) event._result = { index: 0 }; + else { + player + .chooseControlList( + [ + "令" + get.translation(target) + "摸" + get.cnNumber(event.num) + "张牌", + "令" + + get.translation(target) + + "弃置" + + get.cnNumber(event.num) + + "张牌", + ], + function () { + return _status.event.choice; + } + ) + .set("choice", get.attitude(player, target) > 0 ? 0 : 1); } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { target.draw(event.num); + } else { + target.chooseToDiscard(event.num, "he", true); } - else{ - target.chooseToDiscard(event.num,'he',true); - } - 'step 2' - if(target.isDamaged()){ + "step 2"; + if (target.isDamaged()) { player.link(); } }, - subSkill:{ - clear:{ - trigger:{player:'phaseAfter'}, - charlotte:true, - silent:true, - onremove:function(player){ + subSkill: { + clear: { + trigger: { player: "phaseAfter" }, + charlotte: true, + silent: true, + onremove: function (player) { delete player.storage.repindi_target; delete player.storage.repindi_type; - } - } + }, + }, }, - ai:{ - order:8, - threaten:1.9, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var num=(player.getStat('skill').repindi||0)+1; - if(att<=0&&target.countCards('he') { - return target.countCards('he')>0&&target!=player; - }).set('ai',target=>{ - var player=_status.event.player; - if(_status.event.goon) return get.attitude(player,target)*Math.sqrt(target.countCards('he')); - return -get.attitude(player,target)/(target.countCards('he')+1)*10; - }).set('goon',player.countCards('hs',card=>player.hasValueTarget(card))>=2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('rekuangbi',target); - target.chooseCard('匡弼:将至多三张牌置于'+get.translation(player)+'的武将牌上','he',[1,3],true).set('ai',card=>{ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - return 7-get.value(card); - } - return -get.value(card); - }); - }else event.finish(); - 'step 2' - if(result.bool){ - player.addToExpansion(result.cards,target,'give').gaintag.add('rekuangbi_effect'); - player.addTempSkill('rekuangbi_effect','phaseUseEnd'); - player.markAuto('rekuangbi_effect',[target]); + rekuangbi: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("rekuangbi"), (card, player, target) => { + return target.countCards("he") > 0 && target != player; + }) + .set("ai", (target) => { + var player = _status.event.player; + if (_status.event.goon) + return get.attitude(player, target) * Math.sqrt(target.countCards("he")); + return (-get.attitude(player, target) / (target.countCards("he") + 1)) * 10; + }) + .set("goon", player.countCards("hs", (card) => player.hasValueTarget(card)) >= 2); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("rekuangbi", target); + target + .chooseCard( + "匡弼:将至多三张牌置于" + get.translation(player) + "的武将牌上", + "he", + [1, 3], + true + ) + .set("ai", (card) => { + if ( + get.attitude(_status.event.player, _status.event.getParent().player) > 0 + ) { + return 7 - get.value(card); + } + return -get.value(card); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + player.addToExpansion(result.cards, target, "give").gaintag.add("rekuangbi_effect"); + player.addTempSkill("rekuangbi_effect", "phaseUseEnd"); + player.markAuto("rekuangbi_effect", [target]); } }, - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player.getExpansions('rekuangbi_effect').length>0; + subSkill: { + effect: { + trigger: { player: "useCard" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return player.getExpansions("rekuangbi_effect").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('rekuangbi_effect'); - var suit=get.suit(trigger.card),cardsx=cards.filter(card=>get.suit(card)==suit); - var len=cardsx.length; - if(len>1){ - player.chooseButton(['匡弼:移去一张同花色的“匡弼”牌',cards],true).set('filterButton',button=>{ - return get.suit(button.link)==_status.event.suit; - }).set('suit',suit); + content: function () { + "step 0"; + var cards = player.getExpansions("rekuangbi_effect"); + var suit = get.suit(trigger.card), + cardsx = cards.filter((card) => get.suit(card) == suit); + var len = cardsx.length; + if (len > 1) { + player + .chooseButton(["匡弼:移去一张同花色的“匡弼”牌", cards], true) + .set("filterButton", (button) => { + return get.suit(button.link) == _status.event.suit; + }) + .set("suit", suit); + } else if (len == 1) { + event._result = { bool: true, links: cardsx }; + } else { + event._result = { bool: false, links: [cards.randomGet()] }; } - else if(len==1){ - event._result={bool:true,links:cardsx}; - } - else{ - event._result={bool:false,links:[cards.randomGet()]}; - } - 'step 1' - if(result.links&&result.links.length){ + "step 1"; + if (result.links && result.links.length) { player.loseToDiscardpile(result.links); game.delayx(); } - if(result.bool){ - player.draw('nodelay'); - var target=player.getStorage('rekuangbi_effect')[0]; - if(target&&target.isIn()) target.draw(); - } - else{ + if (result.bool) { + player.draw("nodelay"); + var target = player.getStorage("rekuangbi_effect")[0]; + if (target && target.isIn()) target.draw(); + } else { player.draw(); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage[skill]; }, - } - } + }, + }, }, //十周年蔡邕 - rebizhuan:{ - audio:2, - trigger:{ - player:'useCard', - target:'useCardToTargeted', + rebizhuan: { + audio: 2, + trigger: { + player: "useCard", + target: "useCardToTargeted", }, - filter:function(event,player){ - if(event.name!='useCard'&&event.player==event.target) return false; - var num=4+Math.min(player.countMark('retongbo'),game.countPlayer()); - if(player.getExpansions('rebizhuan').length>=num) return false; - return get.suit(event.card)=='spade'; + filter: function (event, player) { + if (event.name != "useCard" && event.player == event.target) return false; + var num = 4 + Math.min(player.countMark("retongbo"), game.countPlayer()); + if (player.getExpansions("rebizhuan").length >= num) return false; + return get.suit(event.card) == "spade"; }, - marktext:'书', - intro:{ - name:'辟撰(书)', - name2:'书', - content:'expansion', - markcount:'expansion', + marktext: "书", + intro: { + name: "辟撰(书)", + name2: "书", + content: "expansion", + markcount: "expansion", }, - frequent:true, - locked:false, - content:function(){ - player.addToExpansion(get.cards(),'gain2').gaintag.add('rebizhuan'); + frequent: true, + locked: false, + content: function () { + player.addToExpansion(get.cards(), "gain2").gaintag.add("rebizhuan"); + }, + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("rebizhuan").length; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('rebizhuan').length; - } - } }, - retongbo:{ - audio:2, - trigger:{player:'phaseDrawAfter'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('rebizhuan').length>0&&player.countCards('he')>0; + retongbo: { + audio: 2, + trigger: { player: "phaseDrawAfter" }, + direct: true, + filter: function (event, player) { + return player.getExpansions("rebizhuan").length > 0 && player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var next=player.chooseToMove('通博:是否交换“书”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的“书”',player.getExpansions('rebizhuan')], - ['你的牌',player.getCards('he')], + content: function () { + "step 0"; + var next = player.chooseToMove("通博:是否交换“书”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的“书”", player.getExpansions("rebizhuan")], + ["你的牌", player.getCards("he")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]),cards2=[]; - cards.sort((a,b)=>{ - return get.useful(a)-get.useful(b); + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]), + cards2 = []; + cards.sort((a, b) => { + return get.useful(a) - get.useful(b); }); - cards2=cards.splice(0,player.getExpansions('rebizhuan').length); - return [cards2,cards]; + cards2 = cards.splice(0, player.getExpansions("rebizhuan").length); + return [cards2, cards]; }); - 'step 1' - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('rebizhuan')); - gains.removeArray(player.getCards('he')); - if(!pushs.length||pushs.length!=gains.length){ + "step 1"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("rebizhuan")); + gains.removeArray(player.getCards("he")); + if (!pushs.length || pushs.length != gains.length) { event.finish(); return; } - player.logSkill('retongbo'); - player.addToExpansion(pushs,'give',player).gaintag.add('rebizhuan'); - player.gain(gains,'gain2'); + player.logSkill("retongbo"); + player.addToExpansion(pushs, "give", player).gaintag.add("rebizhuan"); + player.gain(gains, "gain2"); } - 'step 2' - event.cards=player.getExpansions('rebizhuan').slice(0); - if(event.cards.length<4) event.finish(); + "step 2"; + event.cards = player.getExpansions("rebizhuan").slice(0); + if (event.cards.length < 4) event.finish(); else { - event.given=[]; - var list=[]; - event.cards.forEach(i=>list.add(get.suit(i))); - if(list.length>=4&&player.hp<=2) event.four=true; + event.given = []; + var list = []; + event.cards.forEach((i) => list.add(get.suit(i))); + if (list.length >= 4 && player.hp <= 2) event.four = true; } - 'step 3' - if(event.given.length<4){ - player.chooseCardButton('是否将'+get.cnNumber(4-event.given.length)+'张“书”交给任意名其他角色?',event.cards,[1,4-event.given.length],event.given.length>0).set('ai',function(button){ - if(!_status.event.goon) return 0; - var four=_status.event.getParent().four,given=_status.event.getParent().given; - if(four) return get.value(button.link)+(given.map(i=>get.suit(i)).includes(get.suit(button.link))?0:10); - if(ui.selected.buttons.length==0) return get.value(button.link); - return 0; - }).set('goon',game.hasPlayer(current=>current!=player&&get.attitude(player,current)>0)); - } - else{ + "step 3"; + if (event.given.length < 4) { + player + .chooseCardButton( + "是否将" + + get.cnNumber(4 - event.given.length) + + "张“书”交给任意名其他角色?", + event.cards, + [1, 4 - event.given.length], + event.given.length > 0 + ) + .set("ai", function (button) { + if (!_status.event.goon) return 0; + var four = _status.event.getParent().four, + given = _status.event.getParent().given; + if (four) + return ( + get.value(button.link) + + (given.map((i) => get.suit(i)).includes(get.suit(button.link)) + ? 0 + : 10) + ); + if (ui.selected.buttons.length == 0) return get.value(button.link); + return 0; + }) + .set( + "goon", + game.hasPlayer( + (current) => current != player && get.attitude(player, current) > 0 + ) + ); + } else { event.goto(6); } - 'step 4' - if(result.bool){ - for(var i=0;i0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); - } - else{ + player + .chooseTarget( + "将" + get.translation(result.links) + "交给一名其他角色", + true, + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); + } else { event.finish(); } - 'step 5' - if(result.targets.length){ - result.targets[0].gain(event.togive,'draw').giver=player; - player.line(result.targets[0],'green'); - game.log(result.targets[0],'获得了'+get.cnNumber(event.togive.length)+'张','#g“书”'); - if(event.given.length<4) event.goto(3); + "step 5"; + if (result.targets.length) { + result.targets[0].gain(event.togive, "draw").giver = player; + player.line(result.targets[0], "green"); + game.log( + result.targets[0], + "获得了" + get.cnNumber(event.togive.length) + "张", + "#g“书”" + ); + if (event.given.length < 4) event.goto(3); } - 'step 6' - if(event.given.length==4){ - var suits=lib.suit.slice(0); - event.given.forEach(i=>suits.remove(get.suit(i,player))); - if(suits.length==0){ + "step 6"; + if (event.given.length == 4) { + var suits = lib.suit.slice(0); + event.given.forEach((i) => suits.remove(get.suit(i, player))); + if (suits.length == 0) { player.recover(); - player.addMark('retongbo',1,false); + player.addMark("retongbo", 1, false); } } }, - marktext:'博', - intro:{ - content:function(storage,player){ - var num=4+Math.min(storage,game.countPlayer()); - return '“书”的上限+'+num; - } + marktext: "博", + intro: { + content: function (storage, player) { + var num = 4 + Math.min(storage, game.countPlayer()); + return "“书”的上限+" + num; + }, + }, + ai: { + combo: "rebizhuan", }, - ai:{ - combo:'rebizhuan', - } }, //十周年陈宫 - remingce:{ - enable:'phaseUse', - usable:1, - audio:2, - position:'he', - filterCard:function(card){ - return get.name(card)=='sha'||get.type(card)=='equip'; + remingce: { + enable: "phaseUse", + usable: 1, + audio: 2, + position: "he", + filterCard: function (card) { + return get.name(card) == "sha" || get.type(card) == "equip"; }, - filter:function(event,player){ - return player.countCards('h','sha')>0||player.countCards('he',{type:'equip'})>0; + filter: function (event, player) { + return ( + player.countCards("h", "sha") > 0 || player.countCards("he", { type: "equip" }) > 0 + ); }, - check:function(card){return 8-get.value(card)}, - selectTarget:2, - multitarget:true, - discard:false, - lose:false, - targetprompt:['得到牌','出杀目标'], - filterTarget:function(card,player,target){ - if(ui.selected.targets.length==0){ - return player!=target; + check: function (card) { + return 8 - get.value(card); + }, + selectTarget: 2, + multitarget: true, + discard: false, + lose: false, + targetprompt: ["得到牌", "出杀目标"], + filterTarget: function (card, player, target) { + if (ui.selected.targets.length == 0) { + return player != target; } return true; }, - delay:false, - content:function(){ - 'step 0' - player.give(cards,targets[0],'visible'); - 'step 1' - if(!targets[0].canUse({name:'sha',isCard:true},targets[1],false,false)) event._result={control:'选项二'}; - else targets[0].chooseControl().set('ai',function(){ - var player=_status.event.player,target=_status.event.target; - return get.effect(target,{name:'sha',isCard:true},player,player)>0?0:1; - }).set('choiceList',['视为对'+get.translation(targets[1])+'使用一张【杀】,若此杀造成伤害则执行选项二','你与'+get.translation(player)+'各摸一张牌']).set('target',targets[1]).set('prompt','对'+get.translation(targets[1])+'使用一张杀,或摸一张牌'); - 'step 2' - if(result.control=='选项二'){ - game.asyncDraw([player,targets[0]]); + delay: false, + content: function () { + "step 0"; + player.give(cards, targets[0], "visible"); + "step 1"; + if (!targets[0].canUse({ name: "sha", isCard: true }, targets[1], false, false)) + event._result = { control: "选项二" }; + else + targets[0] + .chooseControl() + .set("ai", function () { + var player = _status.event.player, + target = _status.event.target; + return get.effect(target, { name: "sha", isCard: true }, player, player) > 0 + ? 0 + : 1; + }) + .set("choiceList", [ + "视为对" + + get.translation(targets[1]) + + "使用一张【杀】,若此杀造成伤害则执行选项二", + "你与" + get.translation(player) + "各摸一张牌", + ]) + .set("target", targets[1]) + .set("prompt", "对" + get.translation(targets[1]) + "使用一张杀,或摸一张牌"); + "step 2"; + if (result.control == "选项二") { + game.asyncDraw([player, targets[0]]); event.finish(); + } else { + targets[0].useCard({ name: "sha", isCard: true }, targets[1]); } - else{ - targets[0].useCard({name:'sha',isCard:true},targets[1]); - } - 'step 3' - if(targets[0].hasHistory('useCard',evt=>{ - return evt.getParent()==event&&targets[0].hasHistory('sourceDamage',evtx=>evt.card==evtx.card); - })){ - game.asyncDraw([player,targets[0]]); + "step 3"; + if ( + targets[0].hasHistory("useCard", (evt) => { + return ( + evt.getParent() == event && + targets[0].hasHistory("sourceDamage", (evtx) => evt.card == evtx.card) + ); + }) + ) { + game.asyncDraw([player, targets[0]]); } }, - ai:{ - result:{ - player:function(player){ - var players=game.filterPlayer(); - for(var i=0;i1&&get.attitude(players[i],player)>1){ + ai: { + result: { + player: function (player) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + get.attitude(player, players[i]) > 1 && + get.attitude(players[i], player) > 1 + ) { return 1; } } return 0; }, - target:function(player,target){ - if(ui.selected.targets.length){ + target: function (player, target) { + if (ui.selected.targets.length) { return -0.1; } return 1; - } - }, - order:8.5, - expose:0.2 - } - }, - // 界荀攸 - reqice:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - const hs=player.getCards('h'); - if(!hs.length) return false; - if((player.getStat('skill').reqice||0)>=player.countMark('reqice_mark')+1) return false; - if(hs.some(card=>{ - 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){ - var list=[]; - for(var i=0; i0) return 0; - if((player.getStat('skill').reqice||0)get.tag(button.link[2],i) >= 1)) return effect*5; - } - if(effect>0) return effect; - return 0; - }, - backup:function(links,player){ - return { - filterCard:true, - selectCard:-1, - position:'h', - audio:'reqice', - popname:true, - viewAs:{name:links[0][2]}, - } - }, - prompt:function(links,player){ - return '将所有手牌当【'+get.translation(links[0][2])+'】使用'; - } - }, - ai:{ - order:1, - result:{ - player:function(player){ - var num=0; - var cards=player.getCards('h'); - if(cards.length >= 3&&player.hp >= 3&&player.countMark('reqice_mark')<2) return 0; - for(var i=0; iget.name(card)!='tao','h'); - }, - threaten:1.7, - }, - subSkill:{ - bakcup:{}, - mark:{ - charlotte:true, - onremove:true, - intro:{ - name2:'奇策', - content:'mark', }, }, - } + order: 8.5, + expose: 0.2, + }, }, - rezhiyu:{ - audio:2, - trigger:{player:'damageEnd'}, - content:function(){ - 'step 0' + // 界荀攸 + reqice: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + const hs = player.getCards("h"); + if (!hs.length) return false; + if ((player.getStat("skill").reqice || 0) >= player.countMark("reqice_mark") + 1) + return false; + if ( + hs.some((card) => { + 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) { + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + if (get.type(lib.inpile[i]) == "trick") list.push(["锦囊", "", lib.inpile[i]]); + } + return ui.create.dialog(get.translation("reqice"), [list, "vcard"]); + }, + filter: function (button, player) { + 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; + var effect = player.getUseValue(button.link[2]); + if (player.countCards("hs", button.link[2]) > 0) return 0; + if ((player.getStat("skill").reqice || 0) < player.countMark("reqice_mark") + 1) { + if (["draw", "gain"].some((i) => get.tag(button.link[2], i) >= 1)) + return effect * 5; + } + if (effect > 0) return effect; + return 0; + }, + backup: function (links, player) { + return { + filterCard: true, + selectCard: -1, + position: "h", + audio: "reqice", + popname: true, + viewAs: { name: links[0][2] }, + }; + }, + prompt: function (links, player) { + return "将所有手牌当【" + get.translation(links[0][2]) + "】使用"; + }, + }, + ai: { + order: 1, + result: { + player: function (player) { + var num = 0; + var cards = player.getCards("h"); + if (cards.length >= 3 && player.hp >= 3 && player.countMark("reqice_mark") < 2) + return 0; + for (var i = 0; i < cards.length; i++) { + num += Math.max(0, get.value(cards[i], player, "raw")); + } + num /= cards.length; + num /= (player.countMark("reqice_mark") + 1) * 1.3; + num *= Math.min(cards.length, player.hp); + 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: { + bakcup: {}, + mark: { + charlotte: true, + onremove: true, + intro: { + name2: "奇策", + content: "mark", + }, + }, + }, + }, + rezhiyu: { + audio: 2, + trigger: { player: "damageEnd" }, + content: function () { + "step 0"; player.draw(); - 'step 1' - if(!player.countCards('h')) event.finish(); + "step 1"; + if (!player.countCards("h")) event.finish(); else player.showHandcards(); - 'step 2' - if(!trigger.source||!trigger.source.isIn()) event._result={bool:false,cards:[]}; - else trigger.source.chooseToDiscard('智愚:请弃置一张手牌',true); - 'step 3' - var cards=player.getCards('h'); - var color=get.color(cards[0],player); - var bool=true; - for(var i=1; i(card.name=='juedou'||(card.name=='sha'&&get.color(card,false)=='red')); - var cards=event.getd().filter(filter); - if(!cards.filter((card)=>(get.position(card,true)=='d')).length) return false; - var searched=false; - if(game.getGlobalHistory('cardMove',function(evt){ - if(searched||evt.type!='discard'||evt.position!=ui.discardPile) return false; - var evtx=evt; - if(evtx.getlx===false) evtx=evt.getParent(); - var cards=evtx.getd().filter(filter); - if(!cards.length) return false; - searched=true; - return evtx!=event; - }).length>0) return false; + oljiang: { + audio: "jiang", + inherit: "jiang", + group: "oljiang_gain", + subSkill: { + gain: { + audio: "jiang", + audioname: ["sp_lvmeng", "re_sunben", "re_sunce"], + trigger: { global: ["loseAfter", "loseAsyncAfter"] }, + usable: 1, + filter: function (event, player) { + if (player.hp < 1 || event.type != "discard" || event.position != ui.discardPile) + return false; + var filter = (card) => + card.name == "juedou" || + (card.name == "sha" && get.color(card, false) == "red"); + var cards = event.getd().filter(filter); + if (!cards.filter((card) => get.position(card, true) == "d").length) return false; + var searched = false; + if ( + game.getGlobalHistory("cardMove", function (evt) { + if (searched || evt.type != "discard" || evt.position != ui.discardPile) + return false; + var evtx = evt; + if (evtx.getlx === false) evtx = evt.getParent(); + var cards = evtx.getd().filter(filter); + if (!cards.length) return false; + searched = true; + return evtx != event; + }).length > 0 + ) + return false; return true; }, - prompt2:function(event,player){ - var cards=event.getd().filter(function(card){ - return (card.name=='juedou'||(card.name=='sha'&&get.color(card,false)=='red'))&&get.position(card,true)=='d'; + prompt2: function (event, player) { + var cards = event.getd().filter(function (card) { + return ( + (card.name == "juedou" || + (card.name == "sha" && get.color(card, false) == "red")) && + get.position(card, true) == "d" + ); }); - return '失去1点体力并获得'+get.translation(cards); + return "失去1点体力并获得" + get.translation(cards); }, - check:function(event,player){ - return player.hp>1&&!player.storage.olhunzi; + check: function (event, player) { + return player.hp > 1 && !player.storage.olhunzi; }, - content:function(){ + content: function () { player.loseHp(); - var cards=trigger.getd().filter(function(card){ - return (card.name=='juedou'||(card.name=='sha'&&get.color(card,false)=='red'))&&get.position(card,true)=='d'; + var cards = trigger.getd().filter(function (card) { + return ( + (card.name == "juedou" || + (card.name == "sha" && get.color(card, false) == "red")) && + get.position(card, true) == "d" + ); }); - if(cards.length>0) player.gain(cards,'gain2'); + if (cards.length > 0) player.gain(cards, "gain2"); }, }, }, }, //李儒 - dcmieji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard(lib.skill.dcmieji.filterCard,'eh'); + dcmieji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hasCard(lib.skill.dcmieji.filterCard, "eh"); }, - position:'he', - filterCard:function(card){ - if(get.subtype(card)=='equip1') return true; - return get.color(card)=='black'&&get.type(card,'trick')=='trick'; + position: "he", + filterCard: function (card) { + if (get.subtype(card) == "equip1") return true; + return get.color(card) == "black" && get.type(card, "trick") == "trick"; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - discard:false, - delay:false, - check:function(card){ - return 8-get.value(card); + discard: false, + delay: false, + check: function (card) { + return 8 - get.value(card); }, - loseTo:'cardPile', - insert:true, - visible:true, - content:function(){ - 'step 0' + loseTo: "cardPile", + insert: true, + visible: true, + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - target.chooseToDiscard('he',true).set('prompt','请弃置一张锦囊牌,或依次弃置两张非锦囊牌。'); - 'step 2' - if((!result.cards||get.type(result.cards[0],'trick',result.cards[0].original=='h'?target:false)!='trick')&&target.countCards('he',function(card){ - return get.type(card,'trick')!='trick'; - })){ - target.chooseToDiscard('he',true,function(card){ - return get.type(card,'trick')!='trick'; - }).set('prompt','请弃置第二张非锦囊牌'); + "step 1"; + target + .chooseToDiscard("he", true) + .set("prompt", "请弃置一张锦囊牌,或依次弃置两张非锦囊牌。"); + "step 2"; + if ( + (!result.cards || + get.type( + result.cards[0], + "trick", + result.cards[0].original == "h" ? target : false + ) != "trick") && + target.countCards("he", function (card) { + return get.type(card, "trick") != "trick"; + }) + ) { + target + .chooseToDiscard("he", true, function (card) { + return get.type(card, "trick") != "trick"; + }) + .set("prompt", "请弃置第二张非锦囊牌"); } }, - ai:{ - order:9, - result:{ - target:-1 - } - } + ai: { + order: 9, + result: { + target: -1, + }, + }, }, - dcfencheng:{ - skillAnimation:'epic', - animationColor:'fire', - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - return player!=target; + dcfencheng: { + skillAnimation: "epic", + animationColor: "fire", + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + return player != target; }, - limited:true, - line:'fire', - content:function(){ - "step 0" - player.awakenSkill('dcfencheng'); - event.num=1; - event.targets=game.filterPlayer((current)=>current!=player); + limited: true, + line: "fire", + content: function () { + "step 0"; + player.awakenSkill("dcfencheng"); + event.num = 1; + event.targets = game.filterPlayer((current) => current != player); event.targets.sortBySeat(target); - "step 1" - if(event.targets.length){ - var target=event.targets.shift(); - if(!target.isIn()){ + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + if (!target.isIn()) { event.redo(); return; } - event.target=target; - player.line(target,'fire'); - var res=get.damageEffect(target,player,target,'fire'); - target.chooseToDiscard('he','弃置至少'+get.cnNumber(event.num)+'张牌或受到2点火焰伤害',[num,Infinity]).set('ai',function(card){ - if(ui.selected.cards.length>=_status.event.getParent().num) return -1; - if(_status.event.player.hasSkillTag('nofire')) return -1; - if(_status.event.res>=0) return 6-get.value(card); - if(get.type(card)!='basic'){ - return 10-get.value(card); - } - return 8-get.value(card); - }).set('res',res); - } - else{ + event.target = target; + player.line(target, "fire"); + var res = get.damageEffect(target, player, target, "fire"); + target + .chooseToDiscard( + "he", + "弃置至少" + get.cnNumber(event.num) + "张牌或受到2点火焰伤害", + [num, Infinity] + ) + .set("ai", function (card) { + if (ui.selected.cards.length >= _status.event.getParent().num) return -1; + if (_status.event.player.hasSkillTag("nofire")) return -1; + if (_status.event.res >= 0) return 6 - get.value(card); + if (get.type(card) != "basic") { + return 10 - get.value(card); + } + return 8 - get.value(card); + }) + .set("res", res); + } else { event.finish(); } - "step 2" - if(!result.bool){ - event.target.damage(2,'fire'); - event.num=1; - } - else{ - event.num=result.cards.length+1; + "step 2"; + if (!result.bool) { + event.target.damage(2, "fire"); + event.num = 1; + } else { + event.num = result.cards.length + 1; event.goto(1); } - "step 3" + "step 3"; game.delayx(); event.goto(1); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.hasUnknown(2)) return 0; - var num=0,eff=0,players=game.filterPlayer(function(current){ - return current!=player; - }).sortBySeat(target); - for(var target of players){ - if(get.damageEffect(target,player,target,'fire')>=0){num=0;continue} - var shao=false; - num++; - if(target.countCards('he',function(card){ - if(get.type(card)!='basic'){ - return get.value(card)<10; - } - return get.value(card)<8; - })= 0) { + num = 0; + continue; } - else eff-=num*(get.realAttitude||get.attitude)(player,target)/4; + var shao = false; + num++; + if ( + target.countCards("he", function (card) { + if (get.type(card) != "basic") { + return get.value(card) < 10; + } + return get.value(card) < 8; + }) < num + ) + shao = true; + if (shao) { + eff -= 4 * (get.realAttitude || get.attitude)(player, target); + num = 0; + } else eff -= (num * (get.realAttitude || get.attitude)(player, target)) / 4; } - if(eff<4) return 0; + if (eff < 4) return 0; return eff; - } - } + }, + }, }, }, //朱桓 - refenli:{ - audio:2, - group:['refenli_draw','refenli_use','refenli_discard'], - subfrequent:['discard'], - subSkill:{ - draw:{ - audio:'refenli', - trigger:{player:'phaseJudgeBefore'}, - prompt:'是否发动【奋励】跳过判定和摸牌阶段?', - filter:function(event,player){ + refenli: { + audio: 2, + group: ["refenli_draw", "refenli_use", "refenli_discard"], + subfrequent: ["discard"], + subSkill: { + draw: { + audio: "refenli", + trigger: { player: "phaseJudgeBefore" }, + prompt: "是否发动【奋励】跳过判定和摸牌阶段?", + filter: function (event, player) { return player.isMaxHandcard(); }, - check:function(event,player){ - if(player.hasJudge('lebu')||player.hasJudge('bingliang')) return true; - if(player.getHistory('skipped').length>0) return false; - return game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.hp==1&&get.damageEffect(current,player,player)>0; + check: function (event, player) { + if (player.hasJudge("lebu") || player.hasJudge("bingliang")) return true; + if (player.getHistory("skipped").length > 0) return false; + return game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.hp == 1 && + get.damageEffect(current, player, player) > 0 + ); }); }, - content:function(){ + content: function () { trigger.cancel(); - player.skip('phaseDraw'); - } + player.skip("phaseDraw"); + }, }, - use:{ - audio:'refenli', - trigger:{player:'phaseUseBefore'}, - prompt:'是否发动【奋励】跳过出牌阶段?', - filter:function(event,player){ + use: { + audio: "refenli", + trigger: { player: "phaseUseBefore" }, + prompt: "是否发动【奋励】跳过出牌阶段?", + filter: function (event, player) { return player.isMaxHp(); }, - check:function(event,player){ - if(!player.needsToDiscard()||(player.countCards('e')&&player.isMaxEquip())) return true; - if(player.getHistory('skipped').length>0) return false; - return game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.hp==1&&get.damageEffect(current,player,player)>0; + check: function (event, player) { + if (!player.needsToDiscard() || (player.countCards("e") && player.isMaxEquip())) + return true; + if (player.getHistory("skipped").length > 0) return false; + return game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.hp == 1 && + get.damageEffect(current, player, player) > 0 + ); }); }, - content:function(){ + content: function () { trigger.cancel(); - } - }, - discard:{ - audio:'refenli', - trigger:{player:'phaseDiscardBefore'}, - prompt:'是否发动【奋励】跳过弃牌阶段?', - frequent:true, - filter:function(event,player){ - return player.isMaxEquip()&&player.countCards('e'); }, - content:function(){ + }, + discard: { + audio: "refenli", + trigger: { player: "phaseDiscardBefore" }, + prompt: "是否发动【奋励】跳过弃牌阶段?", + frequent: true, + filter: function (event, player) { + return player.isMaxEquip() && player.countCards("e"); + }, + content: function () { trigger.cancel(); - } - } + }, + }, + }, + ai: { + combo: "repingkou", }, - ai:{ - combo:'repingkou' - } }, - repingkou:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.getHistory('skipped').length>0; + repingkou: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.getHistory("skipped").length > 0; }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.getHistory('skipped').length],get.prompt2('repingkou'),'对至多'+get.cnNumber(num)+'名其他角色各造成1点伤害。若你选择的角色数小于最大角色数,则你可以弃置其中一名目标角色装备区内的一张牌',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - player.logSkill('repingkou',result.targets); - event.targets=result.targets.slice(0).sortBySeat(); - event.num=0; - } - else{ + content: function () { + "step 0"; + player + .chooseTarget( + [1, player.getHistory("skipped").length], + get.prompt2("repingkou"), + "对至多" + + get.cnNumber(num) + + "名其他角色各造成1点伤害。若你选择的角色数小于最大角色数,则你可以弃置其中一名目标角色装备区内的一张牌", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("repingkou", result.targets); + event.targets = result.targets.slice(0).sortBySeat(); + event.num = 0; + } else { event.finish(); } - 'step 2' - var target=targets[event.num]; - if(target.isIn()) target.damage(); + "step 2"; + var target = targets[event.num]; + if (target.isIn()) target.damage(); event.num++; - if(event.num0; + if (event.num < targets.length) event.redo(); + else if (event.num == player.getHistory("skipped").length) event.finish(); + "step 3"; + var targets2 = targets.filter(function (target) { + return target.countDiscardableCards(player, "e") > 0; }); - if(targets2.length>0){ - player.chooseTarget('是否弃置一名目标角色的一张装备牌?',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',targets2).set('ai',function(target){ - var att=get.attitude(player,target),eff=0; - target.getCards('e',function(card){ - var val=get.value(card,target); - eff=Math.max(eff,-val*att); + if (targets2.length > 0) { + player + .chooseTarget( + "是否弃置一名目标角色的一张装备牌?", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", targets2) + .set("ai", function (target) { + var att = get.attitude(player, target), + eff = 0; + target.getCards("e", function (card) { + var val = get.value(card, target); + eff = Math.max(eff, -val * att); + }); + return eff; }); - return eff; - }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,'e',true); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, "e", true); } }, - ai:{ - combo:'fenli', - effect:{ - target:function(card){ - if(card.name=='lebu'||card.name=='bingliang') return 0.5; - } - } - } + ai: { + combo: "fenli", + effect: { + target: function (card) { + if (card.name == "lebu" || card.name == "bingliang") return 0.5; + }, + }, + }, }, //典韦 - olqiangxi:{ - audio:'qiangxi', - audioname:['ol_dianwei','boss_lvbu3'], - enable:'phaseUse', - usable:2, - filter:function(event,player){ - if(player.hp<1&&!player.hasCard((card)=>lib.skill.olqiangxi.filterCard(card),'he')) return false; - return game.hasPlayer((current)=>lib.skill.olqiangxi.filterTarget(null,player,current)); + olqiangxi: { + audio: "qiangxi", + audioname: ["ol_dianwei", "boss_lvbu3"], + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + if ( + player.hp < 1 && + !player.hasCard((card) => lib.skill.olqiangxi.filterCard(card), "he") + ) + return false; + return game.hasPlayer((current) => + lib.skill.olqiangxi.filterTarget(null, player, current) + ); }, - filterCard:function(card){ - return get.subtype(card)=='equip1'; + filterCard: function (card) { + return get.subtype(card) == "equip1"; }, - position:'he', - filterTarget:function(card,player,target){ - if(target==player) return false; - var stat=player.getStat()._olqiangxi; - return !stat||!stat.includes(target); + position: "he", + filterTarget: function (card, player, target) { + if (target == player) return false; + var stat = player.getStat()._olqiangxi; + return !stat || !stat.includes(target); }, - selectCard:function(){ - if(_status.event.player.hp<1) return 1; - return [0,1]; + selectCard: function () { + if (_status.event.player.hp < 1) return 1; + return [0, 1]; }, - content:function(){ - var stat=player.getStat(); - if(!stat._olqiangxi) stat._olqiangxi=[]; + content: function () { + var stat = player.getStat(); + if (!stat._olqiangxi) stat._olqiangxi = []; stat._olqiangxi.push(target); - if(!cards.length) player.damage('nosource','nocard'); - target.damage('nocard'); + if (!cards.length) player.damage("nosource", "nocard"); + target.damage("nocard"); }, - ai:{ - damage:true, - order:8, - result:{ - player:function(player,target){ - if(ui.selected.cards.length) return 0; - if(player.hp>=target.hp) return -0.9; - if(player.hp<=2) return -10; - return get.damageEffect(player,player,player); + ai: { + damage: true, + order: 8, + result: { + player: function (player, target) { + if (ui.selected.cards.length) return 0; + if (player.hp >= target.hp) return -0.9; + if (player.hp <= 2) return -10; + return get.damageEffect(player, player, player); }, - target:function(player,target){ - if(!ui.selected.cards.length){ - if(player.hp<2) return 0; - if(player.hp==2&&target.hp>=2) return 0; - if(target.hp>player.hp) return 0; + target: function (player, target) { + if (!ui.selected.cards.length) { + if (player.hp < 2) return 0; + if (player.hp == 2 && target.hp >= 2) return 0; + if (target.hp > player.hp) return 0; } - return get.damageEffect(target,player,target); - } + return get.damageEffect(target, player, target); + }, }, - threaten:1.5, + threaten: 1.5, }, }, - olningwu:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(player!=event.player&&player!=event.source) return false; - return event.player.getHistory('damage').indexOf(event)==1; + olningwu: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (player != event.player && player != event.source) return false; + return event.player.getHistory("damage").indexOf(event) == 1; }, - logTarget:'player', - forced:true, - content:function(){ + logTarget: "player", + forced: true, + content: function () { player.draw(); - player.discardPlayerCard(trigger.player,true,'ej'); + player.discardPlayerCard(trigger.player, true, "ej"); }, }, //群太史慈 - rejixu:{ - audio:2, - enable:"phaseUse", - usable:1, - filter:function(event,player){ - return player.hp>0&&player.countCards('h')>0; + rejixu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hp > 0 && player.countCards("h") > 0; }, - filterTarget:lib.filter.notMe, - selectTarget:function(){ - return [1,_status.event.player.hp]; + filterTarget: lib.filter.notMe, + selectTarget: function () { + return [1, _status.event.player.hp]; }, - multitarget:true, - multiline:true, - content:function(){ - "step 0" + multitarget: true, + multiline: true, + content: function () { + "step 0"; targets.sortBySeat(); - event.num=0; - "step 1" - if(!event.caicuolist) event.caicuolist=[]; - targets[event.num].chooseBool("是否押杀?").ai=function(event,player){ - var evt=_status.event.getParent(); - if(get.attitude(targets[event.num],evt.player)>0) return evt.player.countCards('h','sha')?false:true; - if(evt.player.hasKnownCards(targets[event.num],c=>{return c.name == 'sha';})){ + event.num = 0; + "step 1"; + if (!event.caicuolist) event.caicuolist = []; + targets[event.num].chooseBool("是否押杀?").ai = function (event, player) { + var evt = _status.event.getParent(); + if (get.attitude(targets[event.num], evt.player) > 0) + return evt.player.countCards("h", "sha") ? false : true; + if ( + evt.player.hasKnownCards(targets[event.num], (c) => { + return c.name == "sha"; + }) + ) { return true; } - return Math.random()<0.5; + return Math.random() < 0.5; }; - "step 2" - if(result.bool){ - targets[event.num].chat('有杀'); - game.log(targets[event.num],'认为',player,'#g有杀'); - if(!player.countCards('h','sha')) event.caicuolist.add(targets[event.num]); - }else{ - targets[event.num].chat('没杀'); - game.log(targets[event.num],'认为',player,'#y没有杀'); - if(player.countCards('h','sha')) event.caicuolist.add(targets[event.num]); + "step 2"; + if (result.bool) { + targets[event.num].chat("有杀"); + game.log(targets[event.num], "认为", player, "#g有杀"); + if (!player.countCards("h", "sha")) event.caicuolist.add(targets[event.num]); + } else { + targets[event.num].chat("没杀"); + game.log(targets[event.num], "认为", player, "#y没有杀"); + if (player.countCards("h", "sha")) event.caicuolist.add(targets[event.num]); } event.num++; game.delay(); - if(event.num0){ - if(player.countCards('h','sha')){ - player.markAuto('rejixu_sha',event.caicuolist); - player.addTempSkill('rejixu_sha','phaseUseAfter'); - player.draw(event.caicuolist.length) + if (event.num < targets.length) event.goto(1); + "step 3"; + player.popup(player.countCards("h", "sha") ? "有杀" : "没杀"); + game.log(player, player.countCards("h", "sha") ? "有杀" : "没杀"); + if (event.caicuolist.length > 0) { + if (player.countCards("h", "sha")) { + player.markAuto("rejixu_sha", event.caicuolist); + player.addTempSkill("rejixu_sha", "phaseUseAfter"); + player.draw(event.caicuolist.length); event.finish(); + } else { + event.num = 0; } - else{ - event.num=0; - } - } - else event.finish(); - "step 4" - var target=event.caicuolist[event.num]; - if(target.countCards('he')>0){ + } else event.finish(); + "step 4"; + var target = event.caicuolist[event.num]; + if (target.countCards("he") > 0) { player.line(target); - player.discardPlayerCard(true,'he',target); + player.discardPlayerCard(true, "he", target); } event.num++; - if(event.num0; + for (var i of list) eff += get.effect(i, event.card, player, player); + return eff > 0; }, - content:function(){ - var list=player.getStorage('rejixu_sha').filter(function(target){ - if(trigger.targets.includes(target)||!target.isIn()) return false; - return lib.filter.targetEnabled2(trigger.card,player,target) + content: function () { + var list = player.getStorage("rejixu_sha").filter(function (target) { + if (trigger.targets.includes(target) || !target.isIn()) return false; + return lib.filter.targetEnabled2(trigger.card, player, target); }); - if(list.length>0){ + if (list.length > 0) { trigger.targets.addArray(list); - game.log(list,'也成为了',trigger.card,'的目标'); + game.log(list, "也成为了", trigger.card, "的目标"); } }, }, }, }, //界刘封 - rexiansi:{ - inherit:'xiansi', - audio:'xiansi', - audioname:['re_liufeng'], - group:['rexiansi2','xiansix'], + rexiansi: { + inherit: "xiansi", + audio: "xiansi", + audioname: ["re_liufeng"], + group: ["rexiansi2", "xiansix"], }, - rexiansi2:{ - enable:'chooseToUse', - filter:function(event,player){ - return player.getExpansions('xiansi').length>Math.max(0,player.hp)&&event.filterCard({name:'sha',isCard:true},player,event); + rexiansi2: { + enable: "chooseToUse", + filter: function (event, player) { + return ( + player.getExpansions("xiansi").length > Math.max(0, player.hp) && + event.filterCard({ name: "sha", isCard: true }, player, event) + ); }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('陷嗣',player.getExpansions('xiansi'),'hidden'); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("陷嗣", player.getExpansions("xiansi"), "hidden"); }, - backup:function(links,player){ + backup: function (links, player) { return { - viewAs:{name:'sha',isCard:true}, - filterCard:()=>false, - selectCard:-1, - card:links[0], - precontent:function(){ - player.logSkill('rexiansi'); + viewAs: { name: "sha", isCard: true }, + filterCard: () => false, + selectCard: -1, + card: links[0], + precontent: function () { + player.logSkill("rexiansi"); player.loseToDiscardpile(lib.skill.rexiansi2_backup.card); delete event.result.skill; }, }; }, - prompt:()=>'请选择【杀】的目标', + prompt: () => "请选择【杀】的目标", }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.6; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.6; }, - result:{player:1}, + result: { player: 1 }, }, }, //界荀彧 - oljieming:{ - audio:2, - trigger:{player:['damageEnd','die']}, - direct:true, - forceDie:true, - filter:function(event,player){ - if(event.name=='die') return true; + oljieming: { + audio: 2, + trigger: { player: ["damageEnd", "die"] }, + direct: true, + forceDie: true, + filter: function (event, player) { + if (event.name == "die") return true; return player.isIn(); }, - content:function(){ - 'step 0' - event.count=trigger.num||1; - 'step 1' + content: function () { + "step 0"; + event.count = trigger.num || 1; + "step 1"; event.count--; - player.chooseTarget(get.prompt2('oljieming'),function(card,player,target){ - return target.maxHp>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - var draw=Math.min(5,target.maxHp)-target.countCards('h'); - if(draw>=0){ - if(target.hasSkillTag('nogain')) att/=6; - if(att>2){ - return Math.sqrt(draw+1)*att; + player + .chooseTarget(get.prompt2("oljieming"), function (card, player, target) { + return target.maxHp > 0; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + var draw = Math.min(5, target.maxHp) - target.countCards("h"); + if (draw >= 0) { + if (target.hasSkillTag("nogain")) att /= 6; + if (att > 2) { + return Math.sqrt(draw + 1) * att; + } + return att / 3; } - return att/3; - } - if(draw<-1){ - if(target.hasSkillTag('nogain')) att*=6; - if(att<-2){ - return -Math.sqrt(1-draw)*att; + if (draw < -1) { + if (target.hasSkillTag("nogain")) att *= 6; + if (att < -2) { + return -Math.sqrt(1 - draw) * att; + } } - } - return 0; - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('oljieming',target); - target.draw(Math.min(5,target.maxHp)); - } - else event.finish(); - 'step 3' - var num=target.countCards('h')-Math.min(5,target.maxHp); - if(num>0) target.chooseToDiscard('h',true,num); - 'step 4' - if(event.count>0&&player.isIn()&&player.hasSkill('oljieming')) event.goto(1); + return 0; + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("oljieming", target); + target.draw(Math.min(5, target.maxHp)); + } else event.finish(); + "step 3"; + var num = target.countCards("h") - Math.min(5, target.maxHp); + if (num > 0) target.chooseToDiscard("h", true, num); + "step 4"; + if (event.count > 0 && player.isIn() && player.hasSkill("oljieming")) event.goto(1); }, - ai:{ - expose:0.2, - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - var max=0; - var players=game.filterPlayer(); - for(var i=0;i0){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + ai: { + expose: 0.2, + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + var max = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(target, players[i]) > 0) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return 2; - case 1:return 1.5; - case 2:return [1,2]; - default:return [0,max]; + switch (max) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return [1, 2]; + default: + return [0, max]; } } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; - } + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; + }, }, - } + }, }, //OL华雄 - shizhan:{ - audio:2, - enable:'phaseUse', - usable:2, - filterTarget:function(card,player,target){ - return target!=player&&target.canUse('juedou',player); + shizhan: { + audio: 2, + enable: "phaseUse", + usable: 2, + filterTarget: function (card, player, target) { + return target != player && target.canUse("juedou", player); }, - content:function(){ - target.useCard({name:'juedou',isCard:true},player,'noai'); + content: function () { + target.useCard({ name: "juedou", isCard: true }, player, "noai"); }, - ai:{ - order:2, - result:{ - player:function(player,target){ - return get.effect(player,{name:'juedou',isCard:true},target,player); + ai: { + order: 2, + result: { + player: function (player, target) { + return get.effect(player, { name: "juedou", isCard: true }, target, player); }, }, }, }, //刘谌 - rezhanjue:{ - audio:2,enable:'phaseUse', - filterCard:function(card){ - return !card.hasGaintag('reqinwang'); + rezhanjue: { + audio: 2, + enable: "phaseUse", + filterCard: function (card) { + return !card.hasGaintag("reqinwang"); }, - selectCard:-1, - position:'h', - filter:function(event,player){ - var stat=player.getStat().skill; - if(stat.rezhanjue_draw&&stat.rezhanjue_draw>=3) return false; - var hs=player.getCards('h',function(card){ - return !card.hasGaintag('reqinwang'); + selectCard: -1, + position: "h", + filter: function (event, player) { + var stat = player.getStat().skill; + if (stat.rezhanjue_draw && stat.rezhanjue_draw >= 3) return false; + var hs = player.getCards("h", function (card) { + return !card.hasGaintag("reqinwang"); }); - if(!hs.length) return false; - for(var i=0;i0&&get.attitude(player,target)>0&&get.attitude(target,player)>0){ + if ( + get.damageEffect(target, player, target) > 0 && + get.attitude(player, target) > 0 && + get.attitude(target, player) > 0 + ) { return 0; } - var hs1=target.getCards('h','sha'); - var hs2=player.getCards('h',function(card){ - return card.hasGaintag('reqinwang')&&get.name(card)=='sha'; + var hs1 = target.getCards("h", "sha"); + var hs2 = player.getCards("h", function (card) { + return card.hasGaintag("reqinwang") && get.name(card) == "sha"; }); - if(hs1.length>hs2.length+1){ + if (hs1.length > hs2.length + 1) { return -2; } - var hsx=target.getCards('h'); - if(hsx.length>2&&hs2.length==0&&hsx[0].number<6){ + var hsx = target.getCards("h"); + if (hsx.length > 2 && hs2.length == 0 && hsx[0].number < 6) { return -2; } - if(hsx.length>3&&hs2.length==0){ + if (hsx.length > 3 && hs2.length == 0) { return -2; } - if(hs1.length>hs2.length&&(!hs2.length||hs1[0].number>hs2[0].number)){ + if (hs1.length > hs2.length && (!hs2.length || hs1[0].number > hs2[0].number)) { return -2; } 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) => { + return get.name(card) !== "tao" && !card.hasGaintag("reqinwang"); + }, "h") + ); }, - 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)=>{ - return get.name(card)!=='tao'&&!card.hasGaintag('reqinwang'); - },'h'); - } }, }, - rezhanjue_effect:{ - audio:false, - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - charlotte:true, - onremove:function(player){ + rezhanjue_effect: { + audio: false, + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + charlotte: true, + onremove: function (player) { delete player.getStat().skill.rezhanjue_draw; }, - filter:function(event,player){ - return event.skill=='rezhanjue'; + filter: function (event, player) { + return event.skill == "rezhanjue"; }, - content:function(){ - "step 0" - var stat=player.getStat().skill; - if(!stat.rezhanjue_draw) stat.rezhanjue_draw=0; + content: function () { + "step 0"; + var stat = player.getStat().skill; + if (!stat.rezhanjue_draw) stat.rezhanjue_draw = 0; stat.rezhanjue_draw++; - player.draw('nodelay'); - var list=game.filterPlayer(function(current){ - if(current.getHistory('damage',function(evt){ - return evt.card==trigger.card; - }).length>0){ - if(current==player){ + player.draw("nodelay"); + var list = game.filterPlayer(function (current) { + if ( + current.getHistory("damage", function (evt) { + return evt.card == trigger.card; + }).length > 0 + ) { + if (current == player) { stat.rezhanjue_draw++; } return true; } return false; }); - if(list.length){ + if (list.length) { list.sortBySeat(); game.asyncDraw(list); } - "step 1" + "step 1"; game.delay(); - } + }, }, - reqinwang:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuSkill:true, - filter:function(event,player){ - if(!player.hasZhuSkill('reqinwang')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'&&player.hasZhuSkill('reqinwang',current); + reqinwang: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuSkill: true, + filter: function (event, player) { + if (!player.hasZhuSkill("reqinwang")) return false; + return game.hasPlayer(function (current) { + return ( + current != player && + current.group == "shu" && + player.hasZhuSkill("reqinwang", current) + ); }); }, - selectTarget:-1, - filterTarget:function(card,player,current){ - return current!=player&¤t.group=='shu'&&player.hasZhuSkill('reqinwang',current); + selectTarget: -1, + filterTarget: function (card, player, current) { + return ( + current != player && + current.group == "shu" && + player.hasZhuSkill("reqinwang", current) + ); }, - content:function(){ - 'step 0' - if(target.hasCard(function(card){ - return _status.connectMode||get.name(card,target)=='sha'; - },'h')){ - target.chooseCard('是否交给'+get.translation(player)+'一张【杀】?',function(card,player){ - return get.name(card,player)=='sha'; - },'h').set('goon',get.attitude(target,player)>0).set('ai',function(card){ - return _status.event.goon?1:0; - }); - } - else event.finish(); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - target.give(card,player).gaintag.add('reqinwang'); - player.addTempSkill('reqinwang_clear'); - player.chooseBool('是否令'+get.translation(target)+'摸一张牌?'); - } - else event.finish(); - 'step 2' - if(result.bool) target.draw(); + content: function () { + "step 0"; + if ( + target.hasCard(function (card) { + return _status.connectMode || get.name(card, target) == "sha"; + }, "h") + ) { + target + .chooseCard( + "是否交给" + get.translation(player) + "一张【杀】?", + function (card, player) { + return get.name(card, player) == "sha"; + }, + "h" + ) + .set("goon", get.attitude(target, player) > 0) + .set("ai", function (card) { + return _status.event.goon ? 1 : 0; + }); + } else event.finish(); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + target.give(card, player).gaintag.add("reqinwang"); + player.addTempSkill("reqinwang_clear"); + player.chooseBool("是否令" + get.translation(target) + "摸一张牌?"); + } else event.finish(); + "step 2"; + if (result.bool) target.draw(); }, - ai:{ - order:5, - result:{player:1}, + ai: { + order: 5, + result: { player: 1 }, }, - subSkill:{ - clear:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('reqinwang'); + subSkill: { + clear: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("reqinwang"); }, }, }, }, //公孙瓒 - dcqiaomeng:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - if(!event.isFirstTarget||get.color(event.card)!='black') return false; - for(var i of event.targets){ - if(i!=player&&i.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,i); - },'he')) return true; + dcqiaomeng: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + if (!event.isFirstTarget || get.color(event.card) != "black") return false; + for (var i of event.targets) { + if ( + i != player && + i.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, i); + }, "he") + ) + return true; } return false; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('dcqiaomeng'),'选择一名不为自己的目标角色,然后弃置其一张牌。若以此法弃置的牌为:装备牌,你获得此牌;锦囊牌,你令'+get.translation(trigger.card)+'不可被响应。',function(card,player,target){ - return target!=player&&_status.event.getTrigger().targets.includes(target)&&target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player) - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcqiaomeng',target); - player.discardPlayerCard(target,true,'he'); - } - else event.finish(); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("dcqiaomeng"), + "选择一名不为自己的目标角色,然后弃置其一张牌。若以此法弃置的牌为:装备牌,你获得此牌;锦囊牌,你令" + + get.translation(trigger.card) + + "不可被响应。", + function (card, player, target) { + return ( + target != player && + _status.event.getTrigger().targets.includes(target) && + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcqiaomeng", target); + player.discardPlayerCard(target, true, "he"); + } else event.finish(); + "step 2"; + if (result.bool && result.cards && result.cards.length) { //为了体现白马义从野性纯真的美 直接获取卡牌原类型 不考虑维系区域 - var card=result.cards[0],type=get.type2(card,false); - if(type=='trick') trigger.directHit.addArray(game.filterPlayer((current)=>current!=player)); - if(type=='equip'&&get.position(card,true)=='d') player.gain(card,'gain2'); + var card = result.cards[0], + type = get.type2(card, false); + if (type == "trick") + trigger.directHit.addArray(game.filterPlayer((current) => current != player)); + if (type == "equip" && get.position(card, true) == "d") player.gain(card, "gain2"); } }, }, //杜畿 - reandong:{ - audio:2, - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - return event.source&&event.source.isIn(); + reandong: { + audio: 2, + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + return event.source && event.source.isIn(); }, - logTarget:'source', - content:function(){ - 'step 0' - var target=trigger.source,str=get.translation(player); - var bool=player.storage.reandong; - if(bool) str='自己'; - var choiceList=['防止'+str+'即将受到的伤害,且本回合内红桃牌不计入'+(bool?get.translation(target):'自己')+'的手牌上限。']; - if(!target.countCards('h')) choiceList.push('令'+str+'下次发动〖安东〗时改为自行选择'); - else choiceList.push('令'+str+'观看你的手牌并获得所有红桃牌'); - if(bool){ + logTarget: "source", + content: function () { + "step 0"; + var target = trigger.source, + str = get.translation(player); + var bool = player.storage.reandong; + if (bool) str = "自己"; + var choiceList = [ + "防止" + + str + + "即将受到的伤害,且本回合内红桃牌不计入" + + (bool ? get.translation(target) : "自己") + + "的手牌上限。", + ]; + if (!target.countCards("h")) + choiceList.push("令" + str + "下次发动〖安东〗时改为自行选择"); + else choiceList.push("令" + str + "观看你的手牌并获得所有红桃牌"); + if (bool) { delete player.storage.reandong; - player.chooseControl().set('choiceList',choiceList).set('prompt','安东:请选择一项'); + player + .chooseControl() + .set("choiceList", choiceList) + .set("prompt", "安东:请选择一项"); + } else { + target + .chooseControl() + .set("choiceList", choiceList) + .set("prompt", "安东:请选择一项") + .set("ai", function (event, player) { + var target = _status.event.getParent().player; + var player = _status.event.player; + if (get.attitude(player, target) > 0) return 0; + return 1; + }); } - else{ - target.chooseControl().set('choiceList',choiceList).set('prompt','安东:请选择一项').set('ai',function(event,player){ - var target=_status.event.getParent().player; - var player=_status.event.player; - if(get.attitude(player,target)>0) return 0; - return 1; - }); - } - 'step 1' - var target=trigger.source; - if(result.index==0){ - target.addTempSkill('reandong_ignore'); + "step 1"; + var target = trigger.source; + if (result.index == 0) { + target.addTempSkill("reandong_ignore"); trigger.cancel(); game.delayx(); - } - else{ - if(!target.countCards('h')){ - player.storage.reandong=true; + } else { + if (!target.countCards("h")) { + player.storage.reandong = true; game.delayx(); - } - else{ + } else { player.viewHandcards(target); - var cards=target.getCards('h',function(card){ - return get.suit(card,target)=='heart'; + var cards = target.getCards("h", function (card) { + return get.suit(card, target) == "heart"; }); - if(cards.length>0) player.gain(cards,target,'give','bySelf'); + if (cards.length > 0) player.gain(cards, target, "give", "bySelf"); } } }, - ai:{ - maixie:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target&&get.attitude(player,target)<0){ - var cards=player.getCards('h',function(cardx){ - return card!=cardx&&(!card.cards||!card.cards.includes(cardx))&&get.suit(cardx)=='heart'; + ai: { + maixie: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if ( + get.tag(card, "damage") && + player != target && + get.attitude(player, target) < 0 + ) { + var cards = player.getCards("h", function (cardx) { + return ( + card != cardx && + (!card.cards || !card.cards.includes(cardx)) && + get.suit(cardx) == "heart" + ); }); - if(!cards.length) return; - for(var i of cards){ - if(get.name(i,target)=='tao') return 'zeroplayertarget'; + if (!cards.length) return; + for (var i of cards) { + if (get.name(i, target) == "tao") return "zeroplayertarget"; } - if(get.value(cards,target)>=(6+target.getDamagedHp())) return 'zeroplayertarget'; - return [1,0.6]; + if (get.value(cards, target) >= 6 + target.getDamagedHp()) + return "zeroplayertarget"; + return [1, 0.6]; } }, }, }, - subSkill:{ - ignore:{ - mod:{ - ignoredHandcard:function(card,player){ - if(get.suit(card)=='heart'){ + subSkill: { + ignore: { + mod: { + ignoredHandcard: function (card, player) { + if (get.suit(card) == "heart") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.suit(card)=='heart') return false; - } + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.suit(card) == "heart") return false; + }, }, - charlotte:true, - marktext:'♥', - intro:'红桃牌于本回合内不计入手牌上限', + charlotte: true, + marktext: "♥", + intro: "红桃牌于本回合内不计入手牌上限", }, }, }, - reyingshi:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0&&game.countPlayer()>1; + reyingshi: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0 && game.countPlayer() > 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('reyingshi'), - prompt2:'操作提示:选择一张作为赏金的手牌,然后选择作为赏金猎人的角色A和作为出杀目标的其他角色B', - filterCard:true, - selectTarget:2, - position:'h', - filterTarget:function(card,player,target){ - if(!ui.selected.targets.length) return true; - return target!=player; + prompt: get.prompt("reyingshi"), + prompt2: + "操作提示:选择一张作为赏金的手牌,然后选择作为赏金猎人的角色A和作为出杀目标的其他角色B", + filterCard: true, + selectTarget: 2, + position: "h", + filterTarget: function (card, player, target) { + if (!ui.selected.targets.length) return true; + return target != player; }, - complexTarget:true, - targetprompt:['出杀','被杀'], - complexSelect:true, - ai1:function(card){ - return 1/Math.max(1,get.value(card)); + complexTarget: true, + targetprompt: ["出杀", "被杀"], + complexSelect: true, + ai1: function (card) { + return 1 / Math.max(1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player; - if(!ui.selected.targets.length){ - var att=get.attitude(player,target); - if(att<0) return 0; - if(target.hasSha()) return Math.pow(target.countCards('h')+1,1.1)*(player==target?3:1); - return Math.sqrt(1+target.countCards('h')); + ai2: function (target) { + var player = _status.event.player; + if (!ui.selected.targets.length) { + var att = get.attitude(player, target); + if (att < 0) return 0; + if (target.hasSha()) + return ( + Math.pow(target.countCards("h") + 1, 1.1) * (player == target ? 3 : 1) + ); + return Math.sqrt(1 + target.countCards("h")); } - return get.effect(target,{name:'sha'},ui.selected.targets[0],player); + return get.effect(target, { name: "sha" }, ui.selected.targets[0], player); }, }); - 'step 1' - if(result.bool){ - var targets=result.targets; - event.targets=targets; - player.logSkill('reyingshi',targets[1]); - var card=result.cards[0]; - event.card=card; - player.showCards(card,get.translation(player)+'对'+get.translation(targets[1])+'发动了【应势】'); - player.line(targets[0],'fire'); - } - else event.finish(); - 'step 2' - var next=targets[0].chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.cardEnabled.apply(this,arguments)&&lib.filter.targetEnabled(card,player,(event||_status.event).sourcex); - },'###是否对'+get.translation(targets[1])+'使用一张【杀】?###若选择使用,则获得赏金('+get.translation(card)+')。若造成伤害,则再从牌堆中获得与此牌花色点数相同的牌作为额外赏金。'); - next.set('addCount',false); - next.set('complexSelect',true); - next.set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); + "step 1"; + if (result.bool) { + var targets = result.targets; + event.targets = targets; + player.logSkill("reyingshi", targets[1]); + var card = result.cards[0]; + event.card = card; + player.showCards( + card, + get.translation(player) + "对" + get.translation(targets[1]) + "发动了【应势】" + ); + player.line(targets[0], "fire"); + } else event.finish(); + "step 2"; + var next = targets[0].chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return ( + lib.filter.cardEnabled.apply(this, arguments) && + lib.filter.targetEnabled(card, player, (event || _status.event).sourcex) + ); + }, "###是否对" + + get.translation(targets[1]) + + "使用一张【杀】?###若选择使用,则获得赏金(" + + get.translation(card) + + ")。若造成伤害,则再从牌堆中获得与此牌花色点数相同的牌作为额外赏金。"); + next.set("addCount", false); + next.set("complexSelect", true); + next.set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); }); - next.set('sourcex',targets[1]); - 'step 3' - var target=targets[0] - if(result.bool&&target.isIn()){ - var cards=[],slice=0; - if(player!=target&&player.getCards('h').includes(card)){ + next.set("sourcex", targets[1]); + "step 3"; + var target = targets[0]; + if (result.bool && target.isIn()) { + var cards = [], + slice = 0; + if (player != target && player.getCards("h").includes(card)) { cards.push(card); slice++; } - if(target.hasHistory('useCard',function(evt){ - if(evt.getParent(2)!=event) return false; - return target.hasHistory('sourceDamage',function(evtx){ - return evtx.card==evt.card; - }); - })){ - var suit=get.suit(card),number=get.number(card); - for(var i=0;i0){ - if(!slice) target.gain(cards,'gain2'); - else{ - setTimeout(function(){ - target.$gain2(cards.slice(slice),true); - },get.delayx(200,200)); - target.gain(cards,player,'give'); + if (cards.length > 0) { + if (!slice) target.gain(cards, "gain2"); + else { + setTimeout(function () { + target.$gain2(cards.slice(slice), true); + }, get.delayx(200, 200)); + target.gain(cards, player, "give"); } } - } - else{ - if(cards.length>0) target.gain(cards,player,'give'); + } else { + if (cards.length > 0) target.gain(cards, player, "give"); } } }, }, //十周年沮授 - dcshibei:{ - trigger:{player:'damageEnd'}, - forced:true, - audio:2, - check:function(event,player){ - return player.getHistory('damage').indexOf(event)==0; + dcshibei: { + trigger: { player: "damageEnd" }, + forced: true, + audio: 2, + check: function (event, player) { + return player.getHistory("damage").indexOf(event) == 0; }, - filter:function(event,player){ - var index=player.getHistory('damage').indexOf(event); - return index==0||index==1; + filter: function (event, player) { + var index = player.getHistory("damage").indexOf(event); + return index == 0 || index == 1; }, - content:function(){ - if(player.getHistory('damage').indexOf(trigger)>0){ + content: function () { + if (player.getHistory("damage").indexOf(trigger) > 0) { player.loseHp(); - } - else{ + } else { player.recover(); } }, - subSkill:{ - damaged:{}, - ai:{} + subSkill: { + damaged: {}, + ai: {}, }, - ai:{ - maixie_defend:true, - threaten:0.9, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing')) return; - if(target.hujia) return; - if(player._shibei_tmp) return; - if(target.hasSkill('shibei_ai')) return; - if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; - if(get.tag(card,'damage')){ - if(target.getHistory('damage').length>0){ - return [1,-2]; - } - else{ - if(get.attitude(player,target)>0&&target.hp>1){ + ai: { + maixie_defend: true, + threaten: 0.9, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing")) return; + if (target.hujia) return; + if (player._shibei_tmp) return; + if (target.hasSkill("shibei_ai")) return; + if ( + _status.event.getParent("useCard", true) || + _status.event.getParent("_wuxie", true) + ) + return; + if (get.tag(card, "damage")) { + if (target.getHistory("damage").length > 0) { + return [1, -2]; + } else { + if (get.attitude(player, target) > 0 && target.hp > 1) { return 0; } - if(get.attitude(player,target)<0&&!player.hasSkillTag('damageBonus','e',{ - target:target, - card:card - })){ - if(card.name=='sha') return; - var sha=false; - player._shibei_tmp=true; - var num=player.countCards('h',function(card){ - if(card.name=='sha'){ - if(sha){ + if ( + get.attitude(player, target) < 0 && + !player.hasSkillTag("damageBonus", "e", { + target: target, + card: card, + }) + ) { + if (card.name == "sha") return; + var sha = false; + player._shibei_tmp = true; + var num = player.countCards("h", function (card) { + if (card.name == "sha") { + if (sha) { return false; - } - else{ - sha=true; + } else { + sha = true; } } - return get.tag(card,'damage')&&player.canUse(card,target)&&get.effect(target,card,player,player)>0; + return ( + get.tag(card, "damage") && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); }); delete player._shibei_tmp; - if(player.hasSkillTag('damage')){ + if (player.hasSkillTag("damage")) { num++; } - if(num<2){ - var enemies=player.getEnemies(); - if(enemies.length==1&&enemies[0]==target&&player.needsToDiscard()){ + if (num < 2) { + var enemies = player.getEnemies(); + if ( + enemies.length == 1 && + enemies[0] == target && + player.needsToDiscard() + ) { return; } return 0; @@ -3246,91 +3955,120 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } } - } - } - } + }, + }, + }, }, - dcjianying:{ - audio:2, - locked:false, - mod:{ - aiOrder:function(player,card,num){ - if(typeof card=='object'&&player.isPhaseUsing()){ - var evt=lib.skill.dcjianying.getLastUsed(player); - if(evt&&evt.card&&(get.suit(evt.card)&&get.suit(evt.card)==get.suit(card)||evt.card.number&&evt.card.number==get.number(card))){ - return num+10; + dcjianying: { + audio: 2, + locked: false, + mod: { + aiOrder: function (player, card, num) { + if (typeof card == "object" && player.isPhaseUsing()) { + var evt = lib.skill.dcjianying.getLastUsed(player); + if ( + evt && + evt.card && + ((get.suit(evt.card) && get.suit(evt.card) == get.suit(card)) || + (evt.card.number && evt.card.number == get.number(card))) + ) { + return num + 10; } } }, }, - trigger:{player:'useCard'}, - frequent:true, - getLastUsed:function(player,event){ - var history=player.getAllHistory('useCard'); + trigger: { player: "useCard" }, + frequent: true, + getLastUsed: function (player, event) { + var history = player.getAllHistory("useCard"); var index; - if(event) index=history.indexOf(event)-1; - else index=history.length-1; - if(index>=0) return history[index]; + if (event) index = history.indexOf(event) - 1; + else index = history.length - 1; + if (index >= 0) return history[index]; return false; }, - filter:function(event,player){ - var evt=lib.skill.dcjianying.getLastUsed(player,event); - if(!evt||!evt.card) return false; - return lib.suit.includes(get.suit(evt.card))&&get.suit(evt.card)==get.suit(event.card)|| - typeof get.number(evt.card,false)=='number'&&get.number(evt.card,false)==get.number(event.card); + filter: function (event, player) { + var evt = lib.skill.dcjianying.getLastUsed(player, event); + if (!evt || !evt.card) return false; + return ( + (lib.suit.includes(get.suit(evt.card)) && + get.suit(evt.card) == get.suit(event.card)) || + (typeof get.number(evt.card, false) == "number" && + get.number(evt.card, false) == get.number(event.card)) + ); }, - content:function(){ + content: function () { player.draw(); }, - group:'dcjianying_mark', - init:function(player){ - var history=player.getAllHistory('useCard'); - if(history.length){ - var trigger=history[history.length-1]; - if(get.suit(trigger.card,player)=='none'||typeof get.number(trigger.card,player)!='number') return; - player.storage.dcjianying_mark=trigger.card; - player.markSkill('dcjianying_mark'); - game.broadcastAll(function(player,suit){ - if(player.marks.dcjianying_mark) player.marks.dcjianying_mark.firstChild.innerHTML=get.translation(suit); - },player,get.suit(trigger.card,player)); + group: "dcjianying_mark", + init: function (player) { + var history = player.getAllHistory("useCard"); + if (history.length) { + var trigger = history[history.length - 1]; + if ( + get.suit(trigger.card, player) == "none" || + typeof get.number(trigger.card, player) != "number" + ) + return; + player.storage.dcjianying_mark = trigger.card; + player.markSkill("dcjianying_mark"); + game.broadcastAll( + function (player, suit) { + if (player.marks.dcjianying_mark) + player.marks.dcjianying_mark.firstChild.innerHTML = get.translation(suit); + }, + player, + get.suit(trigger.card, player) + ); } }, - onremove:function(player){ - player.unmarkSkill('dcjianying_mark'); + onremove: function (player) { + player.unmarkSkill("dcjianying_mark"); delete player.storage.dcjianying_mark; }, - subSkill:{ - mark:{ - charlotte:true, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - content:function(){ - if(get.suit(trigger.card,player)=='none'||typeof get.number(trigger.card,player)!='number') player.unmarkSkill('dcjianying_mark'); - else{ - player.storage.dcjianying_mark=trigger.card; - player.markSkill('dcjianying_mark'); - game.broadcastAll(function(player,suit){ - if(player.marks.dcjianying_mark) player.marks.dcjianying_mark.firstChild.innerHTML=get.translation(suit); - },player,get.suit(trigger.card,player)); + subSkill: { + mark: { + charlotte: true, + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + content: function () { + if ( + get.suit(trigger.card, player) == "none" || + typeof get.number(trigger.card, player) != "number" + ) + player.unmarkSkill("dcjianying_mark"); + else { + player.storage.dcjianying_mark = trigger.card; + player.markSkill("dcjianying_mark"); + game.broadcastAll( + function (player, suit) { + if (player.marks.dcjianying_mark) + player.marks.dcjianying_mark.firstChild.innerHTML = + get.translation(suit); + }, + player, + get.suit(trigger.card, player) + ); } }, - intro:{ - markcount:function(card,player){ - var num=get.number(card,player); - var list=[1,11,12,13]; - if(list.includes(num)) return ['A','J','Q','K'][list.indexOf(num)]; + intro: { + markcount: function (card, player) { + var num = get.number(card, player); + var list = [1, 11, 12, 13]; + if (list.includes(num)) return ["A", "J", "Q", "K"][list.indexOf(num)]; return parseFloat(num); }, - content:function(card,player){ - var suit=get.suit(card,player); - var num=get.number(card,player); - var str='
            • 上一张牌的花色:'+get.translation(suit); - str+='
            • 上一张牌的点数:'; - var list=[1,11,12,13]; - if(list.includes(num)) str+=['A(1)','J(11)','Q(12)','K(13)'][list.indexOf(num)]; - else str+=parseFloat(num); + content: function (card, player) { + var suit = get.suit(card, player); + var num = get.number(card, player); + var str = "
            • 上一张牌的花色:" + get.translation(suit); + str += "
            • 上一张牌的点数:"; + var list = [1, 11, 12, 13]; + if (list.includes(num)) + str += ["A(1)", "J(11)", "Q(12)", "K(13)"][list.indexOf(num)]; + else str += parseFloat(num); return str; }, }, @@ -3338,1190 +4076,1485 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //十周年步练师 - dcanxu:{ - enable:'phaseUse', - usable:1, - multitarget:true, - audio:2, - filterTarget:function(card,player,target){ - if(player==target) return false; - var num=target.countCards('h'); - if(ui.selected.targets.length){ - return numplayers[i].countCards('h')) return true; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (num > players[i].countCards("h")) return true; } return false; }, - selectTarget:2, - content:function(){ - 'step 0' - var gainner,giver; - if(targets[0].countCards('h')0) return -1; - var players=game.filterPlayer(); - for(var i=0;i0) return -3; + ai: { + order: 10.5, + threaten: 2.3, + result: { + target: function (player, target) { + var num = target.countCards("h"); + var att = get.attitude(player, target); + if (ui.selected.targets.length == 0) { + if (att > 0) return -1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var num2 = players[i].countCards("h"); + var att2 = get.attitude(player, players[i]); + if (num2 < num) { + if (att2 > 0) return -3; return -1; } } return 0; - } - else{ + } else { return 1; } }, - player:1, - } - } + player: 1, + }, + }, }, - dczhuiyi:{ - audio:2, - trigger:{player:'die'}, - direct:true, - skillAnimation:true, - animationColor:'wood', - forceDie:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('dczhuiyi'),function(card,player,target){ - return player!=target&&_status.event.sourcex!=target; - }).set('forceDie',true).set('ai',function(target){ - var num=get.attitude(_status.event.player,target); - if(num>0){ - if(target.hp==1){ - num+=2; + dczhuiyi: { + audio: 2, + trigger: { player: "die" }, + direct: true, + skillAnimation: true, + animationColor: "wood", + forceDie: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("dczhuiyi"), function (card, player, target) { + return player != target && _status.event.sourcex != target; + }) + .set("forceDie", true) + .set("ai", function (target) { + var num = get.attitude(_status.event.player, target); + if (num > 0) { + if (target.hp == 1) { + num += 2; + } + if (target.hp < target.maxHp) { + num += 2; + } } - if(target.hp0; + olbeige: { + audio: "beige", + audioname: ["ol_caiwenji"], + trigger: { global: "damageEnd" }, + logTarget: "player", + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.player.isIn() && + player.countCards("he") > 0 + ); }, - check:function(event,player){ - let att=get.attitude(player,event.player); - if(event.player.hasSkill('xinleiji')) return att>0; - if(att>0||event.player.isHealthy()) return true; - if(!event.source) return true; - att=get.attitude(player,event.source); - return att<=0||event.source.isTurnedOver(); + check: function (event, player) { + let att = get.attitude(player, event.player); + if (event.player.hasSkill("xinleiji")) return att > 0; + if (att > 0 || event.player.isHealthy()) return true; + if (!event.source) return true; + att = get.attitude(player, event.source); + return att <= 0 || event.source.isTurnedOver(); }, - prompt2:'令其进行判定,然后你可根据判定结果,弃置一张牌并令其执行对应效果。', - content:function(){ - 'step 0' - event.target=trigger.player; - event.source=trigger.source; + prompt2: "令其进行判定,然后你可根据判定结果,弃置一张牌并令其执行对应效果。", + content: function () { + "step 0"; + event.target = trigger.player; + event.source = trigger.source; trigger.player.judge(); - 'step 1' - event.judgeResult=get.copy(result); - var str='是否弃置一张牌',strt=get.translation(target),strs=get.translation(source),goon=0; - switch(result.suit){ - case 'heart': - if(target.isIn()&&target.isDamaged()){ - str+=(',令'+strt+'回复1点体力'); - goon=get.recoverEffect(target,player,player); + "step 1"; + event.judgeResult = get.copy(result); + var str = "是否弃置一张牌", + strt = get.translation(target), + strs = get.translation(source), + goon = 0; + switch (result.suit) { + case "heart": + if (target.isIn() && target.isDamaged()) { + str += ",令" + strt + "回复1点体力"; + goon = get.recoverEffect(target, player, player); } break; - case 'diamond': - if(target.isIn()){ - str+=(',令'+strt+'摸两张牌'); - goon=2*get.effect(target,{name:'draw'},player,player); + case "diamond": + if (target.isIn()) { + str += ",令" + strt + "摸两张牌"; + goon = 2 * get.effect(target, { name: "draw" }, player, player); } break; - case 'spade': - if(source&&source.isIn()){ - str+=(',令'+strs+'翻'+(source.isTurnedOver()?'回正':'')+'面'); - goon=get.attitude(player,source)*(source.isTurnedOver()?2:-2); + case "spade": + if (source && source.isIn()) { + str += ",令" + strs + "翻" + (source.isTurnedOver() ? "回正" : "") + "面"; + goon = get.attitude(player, source) * (source.isTurnedOver() ? 2 : -2); } break; - case 'club': - if(source&&source.isIn()){ - str+=(',令'+strs+'弃置两张牌'); - var cards=source.getCards('he').sort(function(a,b){ - return get.value(a,source)-get.value(b,source); - }).slice(0,2); - for(var i of cards) goon+=get.value(i,source); - goon*=(-get.sgn(get.attitude(player,source))); + case "club": + if (source && source.isIn()) { + str += ",令" + strs + "弃置两张牌"; + var cards = source + .getCards("he") + .sort(function (a, b) { + return get.value(a, source) - get.value(b, source); + }) + .slice(0, 2); + for (var i of cards) goon += get.value(i, source); + goon *= -get.sgn(get.attitude(player, source)); } break; } - str+='?'; - var str2=('若弃置点数为'+get.strNumber(result.number)+'的牌则收回自己弃置的牌'); - if(get.position(result.card,true)=='d'){ - str2+=(';若弃置花色为'+get.translation(result.suit)+'的牌则获得'+get.translation(result.card)); + str += "?"; + var str2 = "若弃置点数为" + get.strNumber(result.number) + "的牌则收回自己弃置的牌"; + if (get.position(result.card, true) == "d") { + str2 += + ";若弃置花色为" + + get.translation(result.suit) + + "的牌则获得" + + get.translation(result.card); } - player.chooseToDiscard('he',str,str2).set('goon',goon).set('ai',function(card){ - var goon=_status.event.goon; - var player=_status.event.player; - var result=_status.event.getParent().judgeResult; - var eff=Math.min(7,goon); - if(eff<=0) return 0; - if(get.suit(card,player)==result.suit) eff+=get.value(result.card,player); - if(get.number(card,player)==result.number) return eff; - return eff-get.value(card); - }); - 'step 2' - if(result.bool){ - event.card=result.cards[0]; - switch(event.judgeResult.suit){ - case 'heart': - if(target.isIn()&&target.isDamaged()) target.recover(); + player + .chooseToDiscard("he", str, str2) + .set("goon", goon) + .set("ai", function (card) { + var goon = _status.event.goon; + var player = _status.event.player; + var result = _status.event.getParent().judgeResult; + var eff = Math.min(7, goon); + if (eff <= 0) return 0; + if (get.suit(card, player) == result.suit) eff += get.value(result.card, player); + if (get.number(card, player) == result.number) return eff; + return eff - get.value(card); + }); + "step 2"; + if (result.bool) { + event.card = result.cards[0]; + switch (event.judgeResult.suit) { + case "heart": + if (target.isIn() && target.isDamaged()) target.recover(); break; - case 'diamond': - if(target.isIn()) target.draw(2); + case "diamond": + if (target.isIn()) target.draw(2); break; - case 'spade': - if(source&&source.isIn()) source.turnOver(); + case "spade": + if (source && source.isIn()) source.turnOver(); player.addExpose(0.1); break; - case 'club': - if(source&&source.isIn()&&source.countCards('he')>0) source.chooseToDiscard(2,'he',true); + case "club": + if (source && source.isIn() && source.countCards("he") > 0) + source.chooseToDiscard(2, "he", true); player.addExpose(0.1); break; } - } - else event.finish(); - 'step 3' - var gains=[]; - if(get.position(event.judgeResult.card,true)=='d'&&get.suit(card,player)==event.judgeResult.suit) gains.push(event.judgeResult.card); - if(get.position(card,true)=='d'&&get.number(card,player)==event.judgeResult.number) gains.push(card); - if(gains.length) player.gain(gains,'gain2'); + } else event.finish(); + "step 3"; + var gains = []; + if ( + get.position(event.judgeResult.card, true) == "d" && + get.suit(card, player) == event.judgeResult.suit + ) + gains.push(event.judgeResult.card); + if ( + get.position(card, true) == "d" && + get.number(card, player) == event.judgeResult.number + ) + gains.push(card); + if (gains.length) player.gain(gains, "gain2"); }, }, //OL界张郃 - reqiaobian:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + reqiaobian: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - player.addMark('reqiaobian',2); + content: function () { + player.addMark("reqiaobian", 2); game.delayx(); }, - marktext:'变', - intro:{ - name2:'变', - content:function(storage,player){ - var str='共有'+(storage||0)+'个标记'; - if(player.storage.reqiaobian_jieshu){ - str=('
            • '+str+'
            • 已记录手牌数:'+get.translation(player.storage.reqiaobian_jieshu)); + marktext: "变", + intro: { + name2: "变", + content: function (storage, player) { + var str = "共有" + (storage || 0) + "个标记"; + if (player.storage.reqiaobian_jieshu) { + str = + "
            • " + + str + + "
            • 已记录手牌数:" + + get.translation(player.storage.reqiaobian_jieshu); } return str; }, }, - group:['reqiaobian_judge','reqiaobian_draw','reqiaobian_use','reqiaobian_discard','reqiaobian_jieshu'], - subSkill:{ - judge:{ - audio:'reqiaobian', - trigger:{player:'phaseJudgeBefore'}, - direct:true, - filter:function(event,player){ - return player.hasMark('reqiaobian')||player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_judge'),'he'); + group: [ + "reqiaobian_judge", + "reqiaobian_draw", + "reqiaobian_use", + "reqiaobian_discard", + "reqiaobian_jieshu", + ], + subSkill: { + judge: { + audio: "reqiaobian", + trigger: { player: "phaseJudgeBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.hasMark("reqiaobian") || + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_judge"), + "he" + ) + ); }, - check:function(event,player){ - return player.hasCard(function(card){ - return get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)<0; - },'j'); + check: function (event, player) { + return player.hasCard(function (card) { + return ( + get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) < 0 + ); + }, "j"); }, - content:function(){ - 'step 0' - var choices=[]; - if(player.hasMark('reqiaobian')) choices.push('弃置标记'); - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_judge'),'he')) choices.push('弃置牌'); - choices.push('cancel2'); - player.chooseControl(choices).set('prompt','巧变:是否跳过判定阶段?').set('ai',function(){ - var evt=_status.event; - if(lib.skill[evt.getParent().name].check(evt.getTrigger(),evt.player)) return 0; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='弃置牌'){ - player.chooseToDiscard('he',true).logSkill=event.name; - } - else{ + content: function () { + "step 0"; + var choices = []; + if (player.hasMark("reqiaobian")) choices.push("弃置标记"); + if ( + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_judge"), + "he" + ) + ) + choices.push("弃置牌"); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", "巧变:是否跳过判定阶段?") + .set("ai", function () { + var evt = _status.event; + if (lib.skill[evt.getParent().name].check(evt.getTrigger(), evt.player)) + return 0; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "弃置牌") { + player.chooseToDiscard("he", true).logSkill = event.name; + } else { player.logSkill(event.name); - player.removeMark('reqiaobian',1); + player.removeMark("reqiaobian", 1); } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; trigger.cancel(); }, }, - draw:{ - audio:'reqiaobian', - trigger:{player:'phaseDrawBefore'}, - direct:true, - filter:function(event,player){ - return player.hasMark('reqiaobian')||player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_judge'),'he'); + draw: { + audio: "reqiaobian", + trigger: { player: "phaseDrawBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.hasMark("reqiaobian") || + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_judge"), + "he" + ) + ); }, - check:function(event,player){ - return game.countPlayer(function(current){ - if(current==player||current.countGainableCards(player,'h')==0) return false; - var att=get.attitude(player,current); - if(current.hasSkill('tuntian')) return att>0; - return att<1; - })>1; + check: function (event, player) { + return ( + game.countPlayer(function (current) { + if (current == player || current.countGainableCards(player, "h") == 0) + return false; + var att = get.attitude(player, current); + if (current.hasSkill("tuntian")) return att > 0; + return att < 1; + }) > 1 + ); }, - content:function(){ - 'step 0' - var choices=[]; - if(player.hasMark('reqiaobian')) choices.push('弃置标记'); - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_draw'),'he')) choices.push('弃置牌'); - choices.push('cancel2'); - player.chooseControl(choices).set('prompt','巧变:是否跳过摸牌阶段?').set('ai',function(){ - var evt=_status.event; - if(lib.skill[evt.getParent().name].check(evt.getTrigger(),evt.player)) return 0; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='弃置牌'){ - player.chooseToDiscard('he',true).logSkill=event.name; - } - else{ - player.logSkill(event.name); - player.removeMark('reqiaobian',1); - } - } - else event.finish(); - 'step 2' - trigger.cancel(); - if(game.hasPlayer((current)=>current.countGainableCards(player,'h')>0)){ - player.chooseTarget('是否获得至多两名其他角色的各一张手牌?',[1,2],function(card,player,target){ - return target!=player&&target.countGainableCards(player,'h')>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkill('tuntian')) return att/10; - return 1-att; + content: function () { + "step 0"; + var choices = []; + if (player.hasMark("reqiaobian")) choices.push("弃置标记"); + if ( + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_draw"), + "he" + ) + ) + choices.push("弃置牌"); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", "巧变:是否跳过摸牌阶段?") + .set("ai", function () { + var evt = _status.event; + if (lib.skill[evt.getParent().name].check(evt.getTrigger(), evt.player)) + return 0; + return "cancel2"; }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "弃置牌") { + player.chooseToDiscard("he", true).logSkill = event.name; + } else { + player.logSkill(event.name); + player.removeMark("reqiaobian", 1); + } + } else event.finish(); + "step 2"; + trigger.cancel(); + if (game.hasPlayer((current) => current.countGainableCards(player, "h") > 0)) { + player + .chooseTarget( + "是否获得至多两名其他角色的各一张手牌?", + [1, 2], + function (card, player, target) { + return ( + target != player && target.countGainableCards(player, "h") > 0 + ); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkill("tuntian")) return att / 10; + return 1 - att; + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); player.gainMultiple(targets); } }, }, - use:{ - audio:'reqiaobian', - trigger:{player:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return player.hasMark('reqiaobian')||player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_judge'),'he'); + use: { + audio: "reqiaobian", + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.hasMark("reqiaobian") || + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_judge"), + "he" + ) + ); }, - check:function(event,player){ - if(player.countCards('h',function(card){ - return player.hasValueTarget(card,null,true); - })>1) return false; - return game.hasPlayer(function(current){ - var att=get.sgn(get.attitude(player,current)); - if(att!=0){ - var es=current.getCards('e'); - for(var i=0;i 1 + ) + return false; + return game.hasPlayer(function (current) { + var att = get.sgn(get.attitude(player, current)); + if (att != 0) { + var es = current.getCards("e"); + for (var i = 0; i < es.length; i++) { + if ( + game.hasPlayer(function (current2) { + if ( + get.sgn(get.value(es[i], current)) != -att || + get.value(es[i], current) < 5 + ) + return false; + var att2 = get.sgn(get.attitude(player, current2)); + if ( + att == att2 || + att2 != + get.sgn(get.effect(current2, es[i], player, current2)) + ) + return false; + return ( + current != current2 && + !current2.isMin() && + current2.canEquip(es[i]) + ); + }) + ) { return true; } } } - if(att>0){ - var js=current.getCards('j',function(card){ - return get.effect(current,{ - name:card.viewAs||card.name, - cards:[card], - },current,current)<-2; + if (att > 0) { + var js = current.getCards("j", function (card) { + return ( + get.effect( + current, + { + name: card.viewAs || card.name, + cards: [card], + }, + current, + current + ) < -2 + ); }); - for(var i=0;i=0) return false; - return current!=current2&¤t2.canAddJudge(js[i]); - })){ + for (var i = 0; i < js.length; i++) { + if ( + game.hasPlayer(function (current2) { + var att2 = get.attitude(player, current2); + if (att2 >= 0) return false; + return current != current2 && current2.canAddJudge(js[i]); + }) + ) { return true; } } } }); }, - content:function(){ - 'step 0' - var choices=[]; - if(player.hasMark('reqiaobian')) choices.push('弃置标记'); - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_use'),'he')) choices.push('弃置牌'); - choices.push('cancel2'); - player.chooseControl(choices).set('prompt','巧变:是否跳过出牌阶段?').set('ai',function(){ - var evt=_status.event; - if(lib.skill[evt.getParent().name].check(evt.getTrigger(),evt.player)) return 0; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='弃置牌'){ - player.chooseToDiscard('he',true).logSkill=event.name; - } - else{ + content: function () { + "step 0"; + var choices = []; + if (player.hasMark("reqiaobian")) choices.push("弃置标记"); + if ( + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_use"), + "he" + ) + ) + choices.push("弃置牌"); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", "巧变:是否跳过出牌阶段?") + .set("ai", function () { + var evt = _status.event; + if (lib.skill[evt.getParent().name].check(evt.getTrigger(), evt.player)) + return 0; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "弃置牌") { + player.chooseToDiscard("he", true).logSkill = event.name; + } else { player.logSkill(event.name); - player.removeMark('reqiaobian',1); + player.removeMark("reqiaobian", 1); } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; trigger.cancel(); player.moveCard(); }, }, - discard:{ - audio:'reqiaobian', - trigger:{player:'phaseDiscardBefore'}, - direct:true, - filter:function(event,player){ - return player.hasMark('reqiaobian')||player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_judge'),'he'); + discard: { + audio: "reqiaobian", + trigger: { player: "phaseDiscardBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.hasMark("reqiaobian") || + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_judge"), + "he" + ) + ); }, - check:function(event,player){ + check: function (event, player) { return player.needsToDiscard(); }, - content:function(){ - 'step 0' - var choices=[]; - if(player.hasMark('reqiaobian')) choices.push('弃置标记'); - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqiaobian_discard'),'he')) choices.push('弃置牌'); - choices.push('cancel2'); - player.chooseControl(choices).set('prompt','巧变:是否跳过弃牌阶段?').set('ai',function(){ - var evt=_status.event; - if(lib.skill[evt.getParent().name].check(evt.getTrigger(),evt.player)) return 0; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='弃置牌'){ - player.chooseToDiscard('he',true).logSkill=event.name; - } - else{ + content: function () { + "step 0"; + var choices = []; + if (player.hasMark("reqiaobian")) choices.push("弃置标记"); + if ( + player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "reqiaobian_discard"), + "he" + ) + ) + choices.push("弃置牌"); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", "巧变:是否跳过弃牌阶段?") + .set("ai", function () { + var evt = _status.event; + if (lib.skill[evt.getParent().name].check(evt.getTrigger(), evt.player)) + return 0; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "弃置牌") { + player.chooseToDiscard("he", true).logSkill = event.name; + } else { player.logSkill(event.name); - player.removeMark('reqiaobian',1); + player.removeMark("reqiaobian", 1); } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; trigger.cancel(); }, }, - jieshu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return !player.getStorage('reqiaobian_jieshu').includes(player.countCards('h')); + jieshu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return !player.getStorage("reqiaobian_jieshu").includes(player.countCards("h")); }, - content:function(){ - player.addMark('reqiaobian',1); - player.markAuto('reqiaobian_jieshu',[player.countCards('h')]); + content: function () { + player.addMark("reqiaobian", 1); + player.markAuto("reqiaobian_jieshu", [player.countCards("h")]); player.storage.reqiaobian_jieshu.sort(); }, }, }, }, //十周年徐庶 - rezhuhai:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.getHistory('sourceDamage').length>0&&event.player.isIn()&&(player.countCards('h')>0||player.canUse('guohe',event.player)); + rezhuhai: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.getHistory("sourceDamage").length > 0 && + event.player.isIn() && + (player.countCards("h") > 0 || player.canUse("guohe", event.player)) + ); }, - content:function(){ - 'step 0' - var target=trigger.player; - var choiceList=['将一张手牌当做【杀】对其使用','视为对其使用一张【过河拆桥】']; - var bool=false,hs=player.getCards('h'); - for(var i of hs){ - if(game.checkMod(i,player,'unchanged','cardEnabled2',player)!==false&&player.canUse(get.autoViewAs({name:'sha'},[i]),target,false)){ - bool=true; + content: function () { + "step 0"; + var target = trigger.player; + var choiceList = ["将一张手牌当做【杀】对其使用", "视为对其使用一张【过河拆桥】"]; + var bool = false, + hs = player.getCards("h"); + for (var i of hs) { + if ( + game.checkMod(i, player, "unchanged", "cardEnabled2", player) !== false && + player.canUse(get.autoViewAs({ name: "sha" }, [i]), target, false) + ) { + bool = true; break; } } - var choices=[]; - if(bool) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(player.canUse('guohe',target)) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('prompt',get.prompt('rezhuhai',target)).set('ai',function(){ - var choices=_status.event.controls; - var eff1=0,eff2=0; - var player=_status.event.player,target=_status.event.getTrigger().player; - if(choices.includes('选项一')) eff1=get.effect(target,{name:'sha'},player,player); - if(choices.includes('选项二')) eff2=get.effect(target,{name:'guohe'},player,player); - if(eff1>0&&(player.hasSkill('xsqianxin')&&player.isDamaged()||eff1>eff2)) return '选项一'; - if(eff2>0) return '选项二'; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='选项一'){ - player.chooseCard('h',true,function(card,player){ - if(!game.checkMod(card,player,'unchanged','cardEnabled2',player)) return false; - return player.canUse(get.autoViewAs({name:'sha'},[card]),_status.event.getTrigger().player,false); - },'选择一张手牌当做【杀】对'+get.translation(trigger.player)+'使用').set('ai',function(card){ - var player=_status.event.player; - return get.effect(_status.event.getTrigger().player,get.autoViewAs({name:'sha'},[card]),player,player)/Math.max(1,get.value(card)); - }); - } - else{ - player.useCard({name:'guohe',isCard:true},trigger.player,'rezhuhai'); + var choices = []; + if (bool) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (player.canUse("guohe", target)) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", get.prompt("rezhuhai", target)) + .set("ai", function () { + var choices = _status.event.controls; + var eff1 = 0, + eff2 = 0; + var player = _status.event.player, + target = _status.event.getTrigger().player; + if (choices.includes("选项一")) + eff1 = get.effect(target, { name: "sha" }, player, player); + if (choices.includes("选项二")) + eff2 = get.effect(target, { name: "guohe" }, player, player); + if ( + eff1 > 0 && + ((player.hasSkill("xsqianxin") && player.isDamaged()) || eff1 > eff2) + ) + return "选项一"; + if (eff2 > 0) return "选项二"; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "选项一") { + player + .chooseCard( + "h", + true, + function (card, player) { + if (!game.checkMod(card, player, "unchanged", "cardEnabled2", player)) + return false; + return player.canUse( + get.autoViewAs({ name: "sha" }, [card]), + _status.event.getTrigger().player, + false + ); + }, + "选择一张手牌当做【杀】对" + get.translation(trigger.player) + "使用" + ) + .set("ai", function (card) { + var player = _status.event.player; + return ( + get.effect( + _status.event.getTrigger().player, + get.autoViewAs({ name: "sha" }, [card]), + player, + player + ) / Math.max(1, get.value(card)) + ); + }); + } else { + player.useCard({ name: "guohe", isCard: true }, trigger.player, "rezhuhai"); event.finish(); } - } - else event.finish(); - 'step 2' - if(result.bool){ - player.useCard({name:'sha'},result.cards,'rezhuhai',trigger.player,false); + } else event.finish(); + "step 2"; + if (result.bool) { + player.useCard({ name: "sha" }, result.cards, "rezhuhai", trigger.player, false); } }, }, - xsqianxin:{ - trigger:{source:'damageSource'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'orange', - filter:function(event,player){ + xsqianxin: { + trigger: { source: "damageSource" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "orange", + filter: function (event, player) { return player.isDamaged(); }, - content:function(){ - player.awakenSkill('xsqianxin'); + content: function () { + player.awakenSkill("xsqianxin"); player.loseMaxHp(); - player.addSkills('rejianyan'); + player.addSkills("rejianyan"); }, - derivation:'rejianyan', + derivation: "rejianyan", }, - rejianyan:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return game.hasPlayer((current)=>current.group=='key'||current.hasSex('male')); + rejianyan: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return game.hasPlayer((current) => current.group == "key" || current.hasSex("male")); }, - chooseButton:{ - dialog:function(){ - return ui.create.dialog('###荐言###'+get.translation('rejianyan_info')); + chooseButton: { + dialog: function () { + return ui.create.dialog("###荐言###" + get.translation("rejianyan_info")); }, - chooseControl:function(event,player){ - var list=[]; - if(!player.hasSkill('rejianyan_color')) list.addArray(['red','black']); - if(!player.hasSkill('rejianyan_type')) list.addArray(['basic','trick','equip']); - list.push('cancel2'); + chooseControl: function (event, player) { + var list = []; + if (!player.hasSkill("rejianyan_color")) list.addArray(["red", "black"]); + if (!player.hasSkill("rejianyan_type")) list.addArray(["basic", "trick", "equip"]); + list.push("cancel2"); return list; }, - check:function(){ - if(!_status.event.player.hasSkill('rejianyan_color')) return 'red'; - return 'trick'; + check: function () { + if (!_status.event.player.hasSkill("rejianyan_color")) return "red"; + return "trick"; }, - backup:function(result,player){ + backup: function (result, player) { return { - audio:'rejianyan', - filterCard:()=>false, - selectCard:-1, - info:result.control, - content:function(){ - 'step 0' - var card=false,info=lib.skill.rejianyan_backup.info; - if(info=='red'||info=='black'){ - player.addTempSkill('rejianyan_color','phaseUseEnd'); - card=get.cardPile2(function(card){ - return get.color(card)==info; + audio: "rejianyan", + filterCard: () => false, + selectCard: -1, + info: result.control, + content: function () { + "step 0"; + var card = false, + info = lib.skill.rejianyan_backup.info; + if (info == "red" || info == "black") { + player.addTempSkill("rejianyan_color", "phaseUseEnd"); + card = get.cardPile2(function (card) { + return get.color(card) == info; + }); + } else { + player.addTempSkill("rejianyan_type", "phaseUseEnd"); + card = get.cardPile2(function (card) { + return get.type(card) == info; }); } - else{ - player.addTempSkill('rejianyan_type','phaseUseEnd'); - card=get.cardPile2(function(card){ - return get.type(card)==info; + if (card) { + event.card = card; + player.showCards(card, get.translation(player) + "发动了【荐言】"); + } else event.finish(); + "step 1"; + player + .chooseTarget( + true, + "选择一名角色获得" + get.translation(card), + function (card, player, target) { + return target.group == "key" || target.hasSex("male"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkill("nogain")) att /= 10; + return att / Math.sqrt(get.distance(player, target, "absolute")); }); - } - if(card){ - event.card=card; - player.showCards(card,get.translation(player)+'发动了【荐言】'); - } - else event.finish(); - 'step 1' - player.chooseTarget(true,'选择一名角色获得'+get.translation(card),function(card,player,target){ - return target.group=='key'||target.hasSex('male'); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkill('nogain')) att/=10; - return att/Math.sqrt(get.distance(player,target,'absolute')) - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(card,'gain2'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(card, "gain2"); } }, - ai:{result:{player:1}}, - } + ai: { result: { player: 1 } }, + }; }, }, - ai:{ - order:8, - result:{ - player:function(player,target){ - if(game.hasPlayer((current)=>(current.group=='key'||current.hasSex('male'))&&get.attitude(player,current)>0)) return 1; + ai: { + order: 8, + result: { + player: function (player, target) { + if ( + game.hasPlayer( + (current) => + (current.group == "key" || current.hasSex("male")) && + get.attitude(player, current) > 0 + ) + ) + return 1; return 0; }, }, }, - subSkill:{type:{},color:{},backup:{}}, + subSkill: { type: {}, color: {}, backup: {} }, }, //野兽高顺 - decadexianzhen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + decadexianzhen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkill('decadexianzhen2')&&!player.hasSkill('decadexianzhen3'); + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.hasSkill("decadexianzhen2") && + !player.hasSkill("decadexianzhen3") + ); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.bool){ - player.storage.decadexianzhen2=target; - player.addTempSkill('decadexianzhen2'); - } - else{ - player.addTempSkill('decadexianzhen3'); + "step 1"; + if (result.bool) { + player.storage.decadexianzhen2 = target; + player.addTempSkill("decadexianzhen2"); + } else { + player.addTempSkill("decadexianzhen3"); } }, - ai:{ - order:function(name,player){ - var cards=player.getCards('h'); - if(player.countCards('h','sha')==0){ + ai: { + order: function (name, player) { + var cards = player.getCards("h"); + if (player.countCards("h", "sha") == 0) { return 1; } - for(var i=0;i11&&get.value(cards[i])<7){ + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].name != "sha" && + get.number(cards[i]) > 11 && + get.value(cards[i]) < 7 + ) { return 9; } } - return get.order({name:'sha'})-1; + return get.order({ name: "sha" }) - 1; }, - result:{ - player:function(player){ - if(player.countCards('h','sha')>0) return 0; - var num=player.countCards('h'); - if(num>player.hp) return 0; - if(num==1) return -2; - if(num==2) return -1; + result: { + player: function (player) { + if (player.countCards("h", "sha") > 0) return 0; + var num = player.countCards("h"); + if (num > player.hp) return 0; + if (num == 1) return -2; + if (num == 2) return -1; return -0.7; }, - target:function(player,target){ - var num=target.countCards('h'); - if(num==1) return -1; - if(num==2) return -0.7; - return -0.5 + target: function (player, target) { + var num = target.countCards("h"); + if (num == 1) return -1; + if (num == 2) return -0.7; + return -0.5; }, }, - threaten:1.3 - } + threaten: 1.3, + }, }, - decadexianzhen2:{ - audio:'decadexianzhen', - charlotte:true, - onremove:true, - mod:{ - targetInRange:function(card,player,target){ - if(target==player.storage.decadexianzhen2) return true; + decadexianzhen2: { + audio: "decadexianzhen", + charlotte: true, + onremove: true, + mod: { + targetInRange: function (card, player, target) { + if (target == player.storage.decadexianzhen2) return true; }, - cardUsableTarget:function(card,player,target){ - if(target==player.storage.decadexianzhen2) return true; + cardUsableTarget: function (card, player, target) { + if (target == player.storage.decadexianzhen2) return true; }, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(arg.target!=player.storage.decadexianzhen2) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (arg.target != player.storage.decadexianzhen2) return false; }, }, - group:'decadexianzhen2_damage', - subSkill:{ - damage:{ - audio:'decadexianzhen', - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event,player){ - return event.card&&event.player==player.storage.decadexianzhen2&&!player.hasHistory('custom',function(evt){ - return evt.name=='decadexianzhen'&&evt.cardname==event.card.name; - }) + group: "decadexianzhen2_damage", + subSkill: { + damage: { + audio: "decadexianzhen", + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.player == player.storage.decadexianzhen2 && + !player.hasHistory("custom", function (evt) { + return evt.name == "decadexianzhen" && evt.cardname == event.card.name; + }) + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.num++; - player.getHistory('custom').push({ - name:'decadexianzhen', - cardname:trigger.card.name, + player.getHistory("custom").push({ + name: "decadexianzhen", + cardname: trigger.card.name, }); }, }, }, }, - decadexianzhen3:{ - charlotte:true, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + decadexianzhen3: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, - ignoredHandcard:function(card,player){ - if(get.name(card)=='sha'){ + ignoredHandcard: function (card, player) { + if (get.name(card) == "sha") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.name(card)=='sha'){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.name(card) == "sha") { return false; } }, }, }, - decadejinjiu:{ - global:'decadejinjiu_global', - mod:{ - cardname(card){ - if(card.name=='jiu') return 'sha'; + decadejinjiu: { + global: "decadejinjiu_global", + mod: { + cardname(card) { + if (card.name == "jiu") return "sha"; }, - cardnumber(card){ - if(card.name=='jiu') return 13; + cardnumber(card) { + if (card.name == "jiu") return 13; }, }, - audio:2, - audioname2:{ - ol_gaoshun:'rejinjiu', + audio: 2, + audioname2: { + ol_gaoshun: "rejinjiu", }, - trigger:{player:['useCard1','respond']}, - filter(event,player){ - return event.card.name=='sha'&&!event.skill&&event.cards&&event.cards.length==1&&event.cards[0].name=='jiu'; + trigger: { player: ["useCard1", "respond"] }, + filter(event, player) { + return ( + event.card.name == "sha" && + !event.skill && + event.cards && + event.cards.length == 1 && + event.cards[0].name == "jiu" + ); }, - forced:true, - firstDo:true, - content(){}, - subSkill:{ - global:{ - mod:{ - cardEnabled(card,player){ - if(card.name=='jiu'){ - var source=_status.currentPhase; - if(source&&source!=player&&source.hasSkill('decadejinjiu')) return false; + forced: true, + firstDo: true, + content() {}, + subSkill: { + global: { + mod: { + cardEnabled(card, player) { + if (card.name == "jiu") { + var source = _status.currentPhase; + if (source && source != player && source.hasSkill("decadejinjiu")) + return false; } }, - cardSavable(card,player){ - if(card.name=='jiu'){ - var source=_status.currentPhase; - if(source&&source!=player&&source.hasSkill('decadejinjiu')) return false; + cardSavable(card, player) { + if (card.name == "jiu") { + var source = _status.currentPhase; + if (source && source != player && source.hasSkill("decadejinjiu")) + return false; } }, }, }, }, }, - rebotu:{ - audio:'botu', - trigger:{player:'phaseEnd'}, - frequent:true, - filter:function(event,player){ - if(player.countMark('rebotu_count')>=Math.min(3,game.countPlayer())) return false; - var suits=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(suits.length>=4) return; - if(evt.name=='lose'){ - if(evt.position==ui.discardPile){ - for(var i of evt.cards) suits.add(get.suit(i,false)); + rebotu: { + audio: "botu", + trigger: { player: "phaseEnd" }, + frequent: true, + filter: function (event, player) { + if (player.countMark("rebotu_count") >= Math.min(3, game.countPlayer())) return false; + var suits = []; + game.getGlobalHistory("cardMove", function (evt) { + if (suits.length >= 4) return; + if (evt.name == "lose") { + if (evt.position == ui.discardPile) { + for (var i of evt.cards) suits.add(get.suit(i, false)); } - } - else{ - if(evt.name=='cardsDiscard'){ - for(var i of evt.cards) suits.add(get.suit(i,false)); + } else { + if (evt.name == "cardsDiscard") { + for (var i of evt.cards) suits.add(get.suit(i, false)); } } }); - return suits.length>=4; + return suits.length >= 4; }, - content:function(){ - player.addTempSkill('rebotu_count','roundStart'); - player.addMark('rebotu_count',1,false); + content: function () { + player.addTempSkill("rebotu_count", "roundStart"); + player.addMark("rebotu_count", 1, false); player.insertPhase(); }, - group:'rebotu_mark', - subSkill:{ - count:{ - onremove:true, - charlotte:true, + group: "rebotu_mark", + subSkill: { + count: { + onremove: true, + charlotte: true, }, - mark:{ - trigger:{ - global:['loseAfter','cardsDiscardAfter'], - player:'phaseAfter', + mark: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter"], + player: "phaseAfter", }, - forced:true, - firstDo:true, - silent:true, - filter:function(event,player){ - if(event.name=='phase') return true; - if(player!=_status.currentPhase) return false; - if(event.name=='lose') return event.position==ui.discardPile; + forced: true, + firstDo: true, + silent: true, + filter: function (event, player) { + if (event.name == "phase") return true; + if (player != _status.currentPhase) return false; + if (event.name == "lose") return event.position == ui.discardPile; return true; }, - content:function(){ - if(trigger.name=='phase'){ - player.unmarkSkill('rebotu_mark'); + content: function () { + if (trigger.name == "phase") { + player.unmarkSkill("rebotu_mark"); return; } - var suits=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(suits.length>=4) return; - if(evt.name=='lose'){ - if(evt.position==ui.discardPile){ - for(var i of evt.cards) suits.add(get.suit(i,false)); + var suits = []; + game.getGlobalHistory("cardMove", function (evt) { + if (suits.length >= 4) return; + if (evt.name == "lose") { + if (evt.position == ui.discardPile) { + for (var i of evt.cards) suits.add(get.suit(i, false)); } - } - else{ - if(evt.name=='cardsDiscard'){ - for(var i of evt.cards) suits.add(get.suit(i,false)); + } else { + if (evt.name == "cardsDiscard") { + for (var i of evt.cards) suits.add(get.suit(i, false)); } } }); - player.storage.rebotu_mark=suits; - player.markSkill('rebotu_mark'); + player.storage.rebotu_mark = suits; + player.markSkill("rebotu_mark"); }, - intro:{ - onunmark:true, - content:'本回合已有$花色的牌进入过弃牌堆', + intro: { + onunmark: true, + content: "本回合已有$花色的牌进入过弃牌堆", }, }, }, }, - xinganlu:{ - enable:'phaseUse', - usable:1, - audio:2, - selectTarget:2, - delay:0, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - if(ui.selected.targets.length==0) return true; - if(ui.selected.targets[0].countCards('e')==0&&target.countCards('e')==0) return false; + xinganlu: { + enable: "phaseUse", + usable: 1, + audio: 2, + selectTarget: 2, + delay: 0, + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + if (ui.selected.targets.length == 0) return true; + if (ui.selected.targets[0].countCards("e") == 0 && target.countCards("e") == 0) + return false; return true; }, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' + multitarget: true, + multiline: true, + content: function () { + "step 0"; targets[0].swapEquip(targets[1]); - 'step 1' + "step 1"; game.delayx(); - var num=Math.abs(targets[0].countCards('e')-targets[1].countCards('e')); - if(num>player.getDamagedHp()) player.chooseToDiscard('h',2,true); + var num = Math.abs(targets[0].countCards("e") - targets[1].countCards("e")); + if (num > player.getDamagedHp()) player.chooseToDiscard("h", 2, true); }, - ai:{ - order:10, - expose:0.2, - threaten:function(player,target){ - return 0.8*Math.max(1+target.maxHp-target.hp); + ai: { + order: 10, + expose: 0.2, + threaten: function (player, target) { + return 0.8 * Math.max(1 + target.maxHp - target.hp); }, - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return -get.value(target.getCards('e'),target); - var target2=ui.selected.targets[0]; - var eff_target=(get.value(target2.getCards('e'),target)-get.value(target.getCards('e'),target)); - if(get.sgn(eff_target)==get.sgn(-get.value(target2.getCards('e'),target2))) return 0; + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return -get.value(target.getCards("e"), target); + var target2 = ui.selected.targets[0]; + var eff_target = + get.value(target2.getCards("e"), target) - + get.value(target.getCards("e"), target); + if (get.sgn(eff_target) == get.sgn(-get.value(target2.getCards("e"), target2))) + return 0; return eff_target; - } + }, }, - } + }, }, - xinbuyi:{ - audio:2, - trigger:{global:'dying'}, - filter:function(event,player){ - return event.player.countCards('h')>0; + xinbuyi: { + audio: 2, + trigger: { global: "dying" }, + filter: function (event, player) { + return event.player.countCards("h") > 0; }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - 'step 0' - if(player==trigger.player) player.chooseCard('h',true).set('ai',function(card){ - if(get.type(card)!='basic') return 100-get.value(card); - return 0; - }); - else player.choosePlayerCard('h',trigger.player,true); - 'step 1' - var card=result.cards[0],target=trigger.player; - player.showCards(card,get.translation(player)+'对'+(player==target?'自己':get.translation(target))+'发动了【补益】'); - if(get.type(card,target)!='basic'){ + content: function () { + "step 0"; + if (player == trigger.player) + player.chooseCard("h", true).set("ai", function (card) { + if (get.type(card) != "basic") return 100 - get.value(card); + return 0; + }); + else player.choosePlayerCard("h", trigger.player, true); + "step 1"; + var card = result.cards[0], + target = trigger.player; + player.showCards( + card, + get.translation(player) + + "对" + + (player == target ? "自己" : get.translation(target)) + + "发动了【补益】" + ); + if (get.type(card, target) != "basic") { target.discard(card); target.recover(); - if(target.countCards('h')==1) target.draw(); + if (target.countCards("h") == 1) target.draw(); } }, - logTarget:'player', + logTarget: "player", }, - rejiaozhao:{ - audio:2, - enable:'phaseUse', - group:'rejiaozhao_base', - locked:false, - mod:{ - targetEnabled:function(card,player,target){ - if(player==target&&card.storage&&card.storage.rejiaozhao) return false; + rejiaozhao: { + audio: 2, + enable: "phaseUse", + group: "rejiaozhao_base", + locked: false, + mod: { + targetEnabled: function (card, player, target) { + if (player == target && card.storage && card.storage.rejiaozhao) return false; }, }, - filter:function(event,player){ - return (player.hasMark('redanxin')&&player.countCards('h')&&player.getStorage('rejiaozhao_clear').length8-get.value(card), - onuse:function(result,player){ - player.addTempSkill('rejiaozhao_clear','phaseUseAfter'); - player.markAuto('rejiaozhao_clear',[get.type(result.card)]) + backup: function (links, player) { + var next = { + audio: "redanxin", + viewAs: { name: links[0][2], nature: links[0][3] }, + filterCard: true, + position: "h", + popname: true, + ai1: (card) => 8 - get.value(card), + onuse: function (result, player) { + player.addTempSkill("rejiaozhao_clear", "phaseUseAfter"); + player.markAuto("rejiaozhao_clear", [get.type(result.card)]); }, - } - if(player.countMark('redanxin')<2) next.viewAs.storage={rejiaozhao:true}; + }; + if (player.countMark("redanxin") < 2) next.viewAs.storage = { rejiaozhao: true }; return next; }, - prompt:function(links){ - return '将一张手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt: function (links) { + return ( + "将一张手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - order:6, - result:{ - player:1 - } + ai: { + order: 6, + result: { + player: 1, + }, }, - derivation:['rejiaozhao_lv2','rejiaozhao_lv3'], - subSkill:{ - clear:{onremove:true}, - base:{ - audio:'rejiaozhao', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.hasMark('redanxin')) return false; - return player.countCards('h')>0&&game.hasPlayer((current)=>current!=player); + derivation: ["rejiaozhao_lv2", "rejiaozhao_lv3"], + subSkill: { + clear: { onremove: true }, + base: { + audio: "rejiaozhao", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.hasMark("redanxin")) return false; + return ( + player.countCards("h") > 0 && game.hasPlayer((current) => current != player) + ); }, - filterCard:true, - position:'h', - discard:false, - lose:false, - check:function(card){ - return 1/Math.max(1,_status.event.player.getUseValue(card)); + filterCard: true, + position: "h", + discard: false, + lose: false, + check: function (card) { + return 1 / Math.max(1, _status.event.player.getUseValue(card)); }, - prompt:'出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。', - content:function(){ - 'step 0' + prompt: "出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。", + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - var targets=game.filterPlayer(); + "step 1"; + var targets = game.filterPlayer(); targets.remove(player); - targets.sort(function(a,b){ - return Math.max(1,get.distance(player,a))-Math.max(1,get.distance(player,b)); + targets.sort(function (a, b) { + return ( + Math.max(1, get.distance(player, a)) - + Math.max(1, get.distance(player, b)) + ); }); - var distance=Math.max(1,get.distance(player,targets[0])); - for(var i=1;idistance){ - targets.splice(i);break; + var distance = Math.max(1, get.distance(player, targets[0])); + for (var i = 1; i < targets.length; i++) { + if (Math.max(1, get.distance(player, targets[i])) > distance) { + targets.splice(i); + break; } } - player.chooseTarget('请选择【矫诏】的目标',true,function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('targets',targets); - 'step 2' - if(!result.bool){ + player + .chooseTarget("请选择【矫诏】的目标", true, function (card, player, target) { + return _status.event.targets.includes(target); + }) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("targets", targets); + "step 2"; + if (!result.bool) { event.finish(); return; } - var target=result.targets[0]; - event.target=target; - var list=[]; - for(var i=0;i0?1:-1); - 'step 3' - var chosen=result.links[0][2]; - var nature=result.links[0][3]; - var fakecard={ - name:chosen, - storage:{rejiaozhao:true}, + target + .chooseButton(["矫诏", [list, "vcard"]], true) + .set("ai", function (button) { + var player = _status.event.getParent().player, + card = { + name: button.link[2], + nature: button.link[3], + storage: { + rejiaozhao: true, + }, + }; + return player.getUseValue(card, null, true) * _status.event.att; + }) + .set("att", get.attitude(event.target, player) > 0 ? 1 : -1); + "step 3"; + var chosen = result.links[0][2]; + var nature = result.links[0][3]; + var fakecard = { + name: chosen, + storage: { rejiaozhao: true }, }; - if(nature) fakecard.nature=nature; - event.target.showCards(game.createCard({ - name:chosen, - nature:nature, - suit:cards[0].suit, - number:cards[0].number, - }),get.translation(event.target)+'声明了'+get.translation(chosen)); - player.storage.rejiaozhao_viewas=fakecard; - cards[0].addGaintag('rejiaozhao') - player.addTempSkill('rejiaozhao_viewas','phaseUseEnd'); + if (nature) fakecard.nature = nature; + event.target.showCards( + game.createCard({ + name: chosen, + nature: nature, + suit: cards[0].suit, + number: cards[0].number, + }), + get.translation(event.target) + "声明了" + get.translation(chosen) + ); + game.broadcastAll( + (player, fakecard) => { + player.storage.rejiaozhao_viewas = fakecard; + }, + player, + fakecard + ); + cards[0].addGaintag("rejiaozhao"); + player.addTempSkill("rejiaozhao_viewas", "phaseUseEnd"); }, - ai:{ - order:9, - result:{ - player:1, - } - }, - }, - backup:{audio:'rejiaozhao'}, - viewas:{ - enable:'phaseUse', - mod:{ - targetEnabled:function(card,player,target){ - if(player==target&&card.storage&&card.storage.rejiaozhao) return false; + ai: { + order: 9, + result: { + player: 1, }, }, - filter:function(event,player){ - if(!player.storage.rejiaozhao_viewas) return false; - var cards=player.getCards('h',function(card){ - return card.hasGaintag('rejiaozhao'); - }); - if(!cards.length) return false; - if(!game.checkMod(cards[0],player,'unchanged','cardEnabled2',player)) return false; - var card=get.autoViewAs(player.storage.rejiaozhao_viewas,cards); - return event.filterCard(card,player,event); + }, + backup: { audio: "rejiaozhao" }, + viewas: { + enable: "phaseUse", + mod: { + targetEnabled: function (card, player, target) { + if (player == target && card.storage && card.storage.rejiaozhao) return false; + }, }, - viewAs:function(cards,player){ + filter: function (event, player) { + if (!player.storage.rejiaozhao_viewas) return false; + var cards = player.getCards("h", function (card) { + return card.hasGaintag("rejiaozhao"); + }); + if (!cards.length) return false; + if (!game.checkMod(cards[0], player, "unchanged", "cardEnabled2", player)) + return false; + var card = get.autoViewAs(player.storage.rejiaozhao_viewas, cards); + return event.filterCard(card, player, event); + }, + viewAs: function (cards, player) { return player.storage.rejiaozhao_viewas; }, - filterCard:function(card){ - return card.hasGaintag('rejiaozhao'); + filterCard: function (card) { + return card.hasGaintag("rejiaozhao"); }, - selectCard:-1, - position:'h', - popname:true, - prompt:function(){ - return '将“矫诏”牌当做'+get.translation(_status.event.player.storage.rejiaozhao_viewas)+'使用'; + selectCard: -1, + position: "h", + popname: true, + prompt: function () { + return ( + "将“矫诏”牌当做" + + get.translation(_status.event.player.storage.rejiaozhao_viewas) + + "使用" + ); }, - onremove:function(player){ - player.removeGaintag('rejiaozhao'); + onremove: function (player) { + player.removeGaintag("rejiaozhao"); delete player.storage.rejiaozhao_viewas; }, - ai:{order:8}, + ai: { order: 8 }, }, }, }, - redanxin:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - content:function(){ + redanxin: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + content: function () { player.draw(); - if(player.countMark('redanxin')<2) player.addMark('redanxin',1,false); + if (player.countMark("redanxin") < 2) player.addMark("redanxin", 1, false); + }, + intro: { content: "当前升级等级。:Lv#" }, + ai: { + maixie: true, + effect: { + target: (card, player, target) => { + if (!get.tag(card, "damage")) return; + if (target.hp + target.hujia < 2 || player.hasSkillTag("jueqing", false, target)) + return 2; + if (target.countMark("redanxin") > 1) return [1, 1]; + return [1, 0.8 * target.hp - 0.4]; + }, + }, }, - intro:{content:'当前升级等级。:Lv#'}, - ai:{ - maixie:true, - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')) return; - if(target.hp+target.hujia<2||player.hasSkillTag('jueqing',false,target)) return 2; - if(target.countMark('redanxin')>1) return [1,1]; - return [1,0.8*target.hp-0.4]; - } - } - } }, //马岱 - reqianxi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - content:function(){ - 'step 0' + reqianxi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'reqianxi'),'he')) player.chooseToDiscard('he',true); + "step 1"; + if (player.hasCard((card) => lib.filter.cardDiscardable(card, player, "reqianxi"), "he")) + player.chooseToDiscard("he", true); else event.finish(); - 'step 2' - if(result.bool&&game.hasPlayer((current)=>current!=player&&get.distance(player,current)<=1)){ - var color=get.color(result.cards[0],player); - event.color=color; - color=get.translation(color); - player.chooseTarget(true,'选择【潜袭】的目标','令其本回合不能使用或打出'+color+'牌,且'+color+'防具失效,且回复体力时,你摸两张牌',function(card,player,target){ - return target!=player&&get.distance(player,target)<=1; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*Math.sqrt(1+target.countCards('he')); - }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.storage.reqianxi_effect=[event.color,player]; - target.addTempSkill('reqianxi_effect'); + "step 2"; + if ( + result.bool && + game.hasPlayer((current) => current != player && get.distance(player, current) <= 1) + ) { + var color = get.color(result.cards[0], player); + event.color = color; + color = get.translation(color); + player + .chooseTarget( + true, + "选择【潜袭】的目标", + "令其本回合不能使用或打出" + + color + + "牌,且" + + color + + "防具失效,且回复体力时,你摸两张牌", + function (card, player, target) { + return target != player && get.distance(player, target) <= 1; + } + ) + .set("ai", function (target) { + return ( + -get.attitude(_status.event.player, target) * + Math.sqrt(1 + target.countCards("he")) + ); + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.storage.reqianxi_effect = [event.color, player]; + target.addTempSkill("reqianxi_effect"); } }, - subSkill:{ - effect:{ - mark:true, - intro:{ - markcount:()=>0, - content:function(storage,player){ - var color=get.translation(storage[0]),source=get.translation(storage[1]); - return '本回合不能使用或打出'+color+'牌,且'+color+'防具失效,且回复体力时,'+source+'摸两张牌'; + subSkill: { + effect: { + mark: true, + intro: { + markcount: () => 0, + content: function (storage, player) { + var color = get.translation(storage[0]), + source = get.translation(storage[1]); + return ( + "本回合不能使用或打出" + + color + + "牌,且" + + color + + "防具失效,且回复体力时," + + source + + "摸两张牌" + ); }, }, - charlotte:true, - onremove:true, - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&get.color(card)==player.getStorage('reqianxi_effect')[0]) return false; + charlotte: true, + onremove: true, + mod: { + cardEnabled2: function (card, player) { + if ( + get.itemtype(card) == "card" && + get.color(card) == player.getStorage("reqianxi_effect")[0] + ) + return false; }, }, - trigger:{player:'recoverEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.reqianxi_effect&&player.storage.reqianxi_effect[1].isIn(); + trigger: { player: "recoverEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.reqianxi_effect && player.storage.reqianxi_effect[1].isIn(); }, - content:function(){ - var target=player.storage.reqianxi_effect[1]; - target.logSkill('reqianxi',player); + content: function () { + var target = player.storage.reqianxi_effect[1]; + target.logSkill("reqianxi", player); target.draw(2); }, - ai:{ - unequip2:true, - skillTagFilter:function(player){ - var evt=_status.event,color=player.getStorage('reqianxi_effect')[0]; - if(evt.name=='lose'&&evt.loseEquip){ - var card=evt.cards[evt.num]; - if(card&&get.subtype(card,false)=='equip2'&&get.color(card)==color) return true; + ai: { + unequip2: true, + skillTagFilter: function (player) { + var evt = _status.event, + color = player.getStorage("reqianxi_effect")[0]; + if (evt.name == "lose" && evt.loseEquip) { + var card = evt.cards[evt.num]; + if ( + card && + get.subtype(card, false) == "equip2" && + get.color(card) == color + ) + return true; return false; - } - else{ - var equip=player.getEquip(2); - if(equip&&get.color(equip)==color) return true; + } else { + var equip = player.getEquip(2); + if (equip && get.color(equip) == color) return true; return false; } }, @@ -4530,956 +5563,1156 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //徐晃 - olduanliang:{ - audio:2, - locked:false, - enable:'chooseToUse', - filterCard:function(card){ - return (get.type2(card)!='trick'&&get.color(card)=='black'); + olduanliang: { + audio: 2, + locked: false, + enable: "chooseToUse", + filterCard: function (card) { + return get.type2(card) != "trick" && get.color(card) == "black"; }, - filter:function(event,player){ - return player.hasCard((card)=>(get.type2(card)!='trick'&&get.color(card)=='black'),'hes'); + filter: function (event, player) { + return player.hasCard( + (card) => get.type2(card) != "trick" && get.color(card) == "black", + "hes" + ); }, - position:'hes', - viewAs:{name:'bingliang'}, - prompt:'将一张黑色非锦囊牌当做兵粮寸断使用', - check:function(card){return 6-get.value(card)}, - ai:{ - order:9 + position: "hes", + viewAs: { name: "bingliang" }, + prompt: "将一张黑色非锦囊牌当做兵粮寸断使用", + check: function (card) { + return 6 - get.value(card); }, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='bingliang'&&!player.getStat('damage')) return true; + ai: { + order: 9, + }, + mod: { + targetInRange: function (card, player, target) { + if (card.name == "bingliang" && !player.getStat("damage")) return true; }, }, }, - oljiezi:{ - audio:2, - trigger:{global:['phaseDrawSkipped','phaseDrawCancelled']}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('oljiezi'),'你可选择一名角色。若该角色:手牌数为全场最少且没有“辎”,则其获得一枚“辎”。否则其摸一张牌。').set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(!target.hasMark('oljiezi')&&target.isMinHandcard()) att*=2; - return att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('oljiezi',target); - if(!target.hasMark('oljiezi')&&target.isMinHandcard()) target.addMark('oljiezi',1); + oljiezi: { + audio: 2, + trigger: { global: ["phaseDrawSkipped", "phaseDrawCancelled"] }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("oljiezi"), + "你可选择一名角色。若该角色:手牌数为全场最少且没有“辎”,则其获得一枚“辎”。否则其摸一张牌。" + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (!target.hasMark("oljiezi") && target.isMinHandcard()) att *= 2; + return att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("oljiezi", target); + if (!target.hasMark("oljiezi") && target.isMinHandcard()) + target.addMark("oljiezi", 1); else target.draw(); } }, - marktext:'辎', - intro:{ - name2:'辎', - content:'mark', - onunmark:true, + marktext: "辎", + intro: { + name2: "辎", + content: "mark", + onunmark: true, }, - group:'oljiezi_extra', - subSkill:{ - extra:{ - audio:'oljiezi', - trigger:{global:'phaseDrawAfter'}, - forced:true, - filter:function(event,player){ - return event.player.hasMark('oljiezi'); + group: "oljiezi_extra", + subSkill: { + extra: { + audio: "oljiezi", + trigger: { global: "phaseDrawAfter" }, + forced: true, + filter: function (event, player) { + return event.player.hasMark("oljiezi"); }, - logTarget:'player', - content:function(){ - var next=trigger.player.phaseDraw(); + logTarget: "player", + content: function () { + var next = trigger.player.phaseDraw(); event.next.remove(next); trigger.getParent().next.add(next); - trigger.player.removeMark('oljiezi',trigger.player.countMark('oljiezi')); + trigger.player.removeMark("oljiezi", trigger.player.countMark("oljiezi")); }, }, }, }, //界护驾 - rehujia:{ - audio:'hujia', - inherit:'hujia', - filter:function(event,player){ - if(event.responded) return false; - if(player.storage.hujiaing) return false; - if(!player.hasZhuSkill('rehujia')) return false; - if(!event.filterCard({name:'shan'},player,event)) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'; + rehujia: { + audio: "hujia", + inherit: "hujia", + filter: function (event, player) { + if (event.responded) return false; + if (player.storage.hujiaing) return false; + if (!player.hasZhuSkill("rehujia")) return false; + if (!event.filterCard({ name: "shan" }, player, event)) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wei"; }); }, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(player.storage.hujiaing) return false; - if(!player.hasZhuSkill('rehujia')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'; + ai: { + respondShan: true, + skillTagFilter: function (player) { + if (player.storage.hujiaing) return false; + if (!player.hasZhuSkill("rehujia")) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wei"; }); }, }, - group:'rehujia_draw', - subSkill:{ - draw:{ - trigger:{global:['useCard','respond']}, - usable:1, - direct:true, - filter:function(event,player){ - return event.card.name=='shan'&&event.player!=player&&event.player.group=='wei'&&event.player.isIn()&& - event.player!=_status.currentPhase&&player.hasZhuSkill('rehujia'); + group: "rehujia_draw", + subSkill: { + draw: { + trigger: { global: ["useCard", "respond"] }, + usable: 1, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "shan" && + event.player != player && + event.player.group == "wei" && + event.player.isIn() && + event.player != _status.currentPhase && + player.hasZhuSkill("rehujia") + ); }, - content:function(){ - 'step 0' - trigger.player.chooseBool('护驾:是否令'+get.translation(player)+'摸一张牌?').set('ai',function(){ - var evt=_status.event; - return get.attitude(evt.player,evt.getParent().player)>0; - }); - 'step 1' - if(result.bool){ - player.logSkill('rehujia'); - trigger.player.line(player,'fire'); + content: function () { + "step 0"; + trigger.player + .chooseBool("护驾:是否令" + get.translation(player) + "摸一张牌?") + .set("ai", function () { + var evt = _status.event; + return get.attitude(evt.player, evt.getParent().player) > 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("rehujia"); + trigger.player.line(player, "fire"); player.draw(); - } - else player.storage.counttrigger.rehujia_draw--; + } else player.storage.counttrigger.rehujia_draw--; }, }, }, }, //夏侯氏 - reqiaoshi:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player!=player&&event.player.countCards('h')==player.countCards('h')&&event.player.isIn(); + reqiaoshi: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player != player && + event.player.countCards("h") == player.countCards("h") && + event.player.isIn() + ); }, - check:function(event,player){ - return get.attitude(player,event.player)>=0; + check: function (event, player) { + return get.attitude(player, event.player) >= 0; }, //priority:-5, - logTarget:'player', - content:function(){ - 'step 0' - game.asyncDraw([trigger.player,player]); - 'step 1' + logTarget: "player", + content: function () { + "step 0"; + game.asyncDraw([trigger.player, player]); + "step 1"; game.delayx(); - if(player.isIn()&&trigger.player.isIn()){ - var getGainSuit=function(player){ - var last=player.getHistory('gain',function(evt){ - return evt.getParent(2)==event; + if (player.isIn() && trigger.player.isIn()) { + var getGainSuit = function (player) { + var last = player.getHistory("gain", function (evt) { + return evt.getParent(2) == event; }); - if(last.length){ - var evt=last.pop(); - if(evt.cards.length==1&&player.getCards('h').includes(evt.cards[0])) return get.suit(evt.cards[0],player); - } - else return player; - } - if(getGainSuit(player)==getGainSuit(trigger.player)) player.chooseBool('是否继续发动【樵拾】?','和'+get.translation(trigger.player)+'各摸一张牌'); - } - else event.finish(); - 'step 2' - if(result.bool) event.goto(0); + if (last.length) { + var evt = last.pop(); + if (evt.cards.length == 1 && player.getCards("h").includes(evt.cards[0])) + return get.suit(evt.cards[0], player); + } else return player; + }; + if (getGainSuit(player) == getGainSuit(trigger.player)) + player.chooseBool( + "是否继续发动【樵拾】?", + "和" + get.translation(trigger.player) + "各摸一张牌" + ); + } else event.finish(); + "step 2"; + if (result.bool) event.goto(0); + }, + ai: { + expose: 0.1, }, - ai:{ - expose:0.1 - } }, - reyanyu:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.hasCard(card=>lib.skill.reyanyu.filterCard(card,player),'h'); + reyanyu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.hasCard((card) => lib.skill.reyanyu.filterCard(card, player), "h"); }, - filterCard:(card,player)=>get.name(card)=='sha'&&player.canRecast(card), - discard:false, - lose:false, - delay:false, - content:function(){ + filterCard: (card, player) => get.name(card) == "sha" && player.canRecast(card), + discard: false, + lose: false, + delay: false, + content: function () { player.recast(cards); }, - ai:{ - basic:{ - order:1 + ai: { + basic: { + order: 1, + }, + result: { + player: 1, }, - result:{ - player:1 - } }, - group:'reyanyu2' + group: "reyanyu2", }, - reyanyu2:{ - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:(event,player)=>player.hasHistory('useSkill',evt=>evt.skill=='reyanyu'&&evt.event.getParent(2)==event)&&game.hasPlayer(target=>target.hasSex('male')&&target!=player), - content:function(){ - 'step 0' - event.num=Math.min(3,player.getHistory('useSkill',evt=>evt.skill=='reyanyu'&&evt.event.getParent(2)==trigger).length); - player.chooseTarget(get.prompt('reyanyu'),'令一名男性角色摸'+get.cnNumber(event.num)+'张牌',function(card,player,target){ - return target.hasSex('male')&&target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - player.logSkill('reyanyu',result.targets); + reyanyu2: { + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: (event, player) => + player.hasHistory( + "useSkill", + (evt) => evt.skill == "reyanyu" && evt.event.getParent(2) == event + ) && game.hasPlayer((target) => target.hasSex("male") && target != player), + content: function () { + "step 0"; + event.num = Math.min( + 3, + player.getHistory( + "useSkill", + (evt) => evt.skill == "reyanyu" && evt.event.getParent(2) == trigger + ).length + ); + player + .chooseTarget( + get.prompt("reyanyu"), + "令一名男性角色摸" + get.cnNumber(event.num) + "张牌", + function (card, player, target) { + return target.hasSex("male") && target != player; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("reyanyu", result.targets); result.targets[0].draw(event.num); } - } + }, }, //虞翻 - xinzongxuan:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + xinzongxuan: { + audio: 2, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - if(event.type!='discard') return false; - var evt=event.getl(player); - if(!evt||!evt.cards2) return false; - for(var i=0;i0&&!current.hasSkillTag('nogain'); - })) return false; - var cards=trigger.getl(player).cards2; - for(var i=0;i 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return false; + var cards = trigger.getl(player).cards2; + for (var i = 0; i < cards.length; i++) { + if (get.position(cards[i], true) == "d" && get.type2(cards[i], false) == "trick") { return true; } } return false; }, - content:function(){ - "step 0" - var cards=[],cards2=trigger.getl(player).cards2; - for(var i=0;i0; + var next = player.chooseToMove("纵玄:将任意张牌置于牌堆顶", true); + next.set("list", [["本次弃置的牌(请将要给出的锦囊牌留在这里)", cards], ["牌堆顶"]]); + next.set("filterOk", function (moved) { + if (moved[0].length == 1 && get.type2(moved[0][0], false) == "trick") return true; + return moved[1].length > 0; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0),player=_status.event.player; - var result=[[],[]]; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })){ - var max_val=0; - var max_card=false; - for(var i of cards){ - if(get.type2(i,false)=='trick'){ - var val=get.value(i,'raw'); - if(val>max_val){ - max_card=i; - max_val=val; + next.set("processAI", function (list) { + var cards = list[0][1].slice(0), + player = _status.event.player; + var result = [[], []]; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) { + var max_val = 0; + var max_card = false; + for (var i of cards) { + if (get.type2(i, false) == "trick") { + var val = get.value(i, "raw"); + if (val > max_val) { + max_card = i; + max_val = val; } } } - if(max_card){ + if (max_card) { result[0].push(max_card); cards.remove(max_card); } } - if(cards.length){ - var max_val=0; - var max_card=false; - var equip=game.hasPlayer(function(current){ - return current.isDamaged()&&get.recoverEffect(current,player,player)>0; - }) - for(var i of cards){ - var val=get.value(i); - var type=get.type2(i,false); - if(type=='basic') val+=3; - if(type=='equip'&&equip) val+=9; - if(max_val==0||val>max_val){ - max_card=i; - max_val=val; + if (cards.length) { + var max_val = 0; + var max_card = false; + var equip = game.hasPlayer(function (current) { + return current.isDamaged() && get.recoverEffect(current, player, player) > 0; + }); + for (var i of cards) { + var val = get.value(i); + var type = get.type2(i, false); + if (type == "basic") val += 3; + if (type == "equip" && equip) val += 9; + if (max_val == 0 || val > max_val) { + max_card = i; + max_val = val; } } - if(max_card){ + if (max_card) { result[1].push(max_card); cards.remove(max_card); } result[0].addArray(cards); } return result; - }) - 'step 1' - if(result.bool){ - var cards=result.moved[1].slice(0); - if(cards.length){ - game.log(player,'将',cards,'置于了牌堆顶'); - while(cards.length) ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); + }); + "step 1"; + if (result.bool) { + var cards = result.moved[1].slice(0); + if (cards.length) { + game.log(player, "将", cards, "置于了牌堆顶"); + while (cards.length) + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); } - var list=result.moved[0].filter(function(i){ - return get.type2(i,false)=='trick'; + var list = result.moved[0].filter(function (i) { + return get.type2(i, false) == "trick"; }); - if(list.length&&game.hasPlayer((current)=>(current!=player))){ - var next=player.chooseButton(['是否将一张锦囊牌交给一名其他角色?',list]).set('ai',function(button){ - if(_status.event.goon) return Math.max(0.1,get.value(button.link,'raw')); - return 0; - }).set('goon',game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })); - if(!result.moved[1].length) next.set('forced',true); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget(lib.filter.notMe,true,'令一名其他角色获得'+get.translation(card)).set('card',card).set('ai',function(target){ - var card=_status.event.card,player=_status.event.player; - var eff=Math.max(0.1,get.value(card,target))*get.attitude(player,target); - if(target.hasSkill('nogain')) eff/=10; - return eff; - }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(card,'gain2'); + if (list.length && game.hasPlayer((current) => current != player)) { + var next = player + .chooseButton(["是否将一张锦囊牌交给一名其他角色?", list]) + .set("ai", function (button) { + if (_status.event.goon) + return Math.max(0.1, get.value(button.link, "raw")); + return 0; + }) + .set( + "goon", + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ); + if (!result.moved[1].length) next.set("forced", true); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + lib.filter.notMe, + true, + "令一名其他角色获得" + get.translation(card) + ) + .set("card", card) + .set("ai", function (target) { + var card = _status.event.card, + player = _status.event.player; + var eff = + Math.max(0.1, get.value(card, target)) * get.attitude(player, target); + if (target.hasSkill("nogain")) eff /= 10; + return eff; + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(card, "gain2"); } }, }, - xinzhiyan:{ - audio:'zhiyan', - audioname:['gexuan','re_yufan','xin_yufan'], - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('zhiyan'),'令一名角色摸一张牌并展示之。若为基本牌则你摸一张牌;若为装备牌,则其回复1点体力').set('ai',function(target){ - return get.attitude(_status.event.player,target)*(target.isDamaged()?2:1); - }); - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('xinzhiyan',result.targets); - event.bool=false; - event.target.draw('visible'); - } - else{ + xinzhiyan: { + audio: "zhiyan", + audioname: ["gexuan", "re_yufan", "xin_yufan"], + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhiyan"), + "令一名角色摸一张牌并展示之。若为基本牌则你摸一张牌;若为装备牌,则其回复1点体力" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) * (target.isDamaged() ? 2 : 1); + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("xinzhiyan", result.targets); + event.bool = false; + event.target.draw("visible"); + } else { event.finish(); } - "step 2" - var card=result[0]; - event.card=card; - if(get.type(card)=='basic') player.draw(); - "step 3" - if(get.type(card)=='equip'){ - if(target.getCards('h').includes(card)&&target.hasUseTarget(card)){ - event.target.chooseUseTarget(card,true,'nopopup'); + "step 2"; + var card = result[0]; + event.card = card; + if (get.type(card) == "basic") player.draw(); + "step 3"; + if (get.type(card) == "equip") { + if (target.getCards("h").includes(card) && target.hasUseTarget(card)) { + event.target.chooseUseTarget(card, true, "nopopup"); game.delay(); } - event.bool=true; + event.bool = true; } - "step 4" - if(event.bool) target.recover(); + "step 4"; + if (event.bool) target.recover(); + }, + ai: { + expose: 0.2, + threaten: 1.2, }, - ai:{ - expose:0.2, - threaten:1.2 - } }, //新主公技 - xinhuangtian:{ - unique:true, - audio:'xinhuangtian2', - audioname:['zhangjiao','re_zhangjiao'], - global:'xinhuangtian2', - zhuSkill:true, + xinhuangtian: { + unique: true, + audio: "xinhuangtian2", + audioname: ["zhangjiao", "re_zhangjiao"], + global: "xinhuangtian2", + zhuSkill: true, }, - xinhuangtian2:{ - audio:2, - enable:'phaseUse', - discard:false, - lose:false, - delay:false, - line:true, - prepare:function(cards,player,targets){ - targets[0].logSkill('xinhuangtian'); + xinhuangtian2: { + audio: 2, + enable: "phaseUse", + discard: false, + lose: false, + delay: false, + line: true, + prepare: function (cards, player, targets) { + targets[0].logSkill("xinhuangtian"); }, - prompt:function(){ - var player=_status.event.player; - var list=game.filterPlayer(function(target){ - return target!=player&&target.hasZhuSkill('xinhuangtian',player); + prompt: function () { + var player = _status.event.player; + var list = game.filterPlayer(function (target) { + return target != player && target.hasZhuSkill("xinhuangtian", player); }); - var str='将一张【闪】或黑桃手牌交给'+get.translation(list); - if(list.length>1) str+='中的一人'; + var str = "将一张【闪】或黑桃手牌交给" + get.translation(list); + if (list.length > 1) str += "中的一人"; return str; }, - filter:function(event,player){ - if(player.group!='qun') return false; - if(!game.hasPlayer(function(target){ - return target!=player&&target.hasZhuSkill('xinhuangtian',player)&&!target.hasSkill('xinhuangtian3'); - })) return false; - return player.hasCard(function(card){ - return lib.skill.xinhuangtian2.filterCard(card,player); - },'h'); + filter: function (event, player) { + if (player.group != "qun") return false; + if ( + !game.hasPlayer(function (target) { + return ( + target != player && + target.hasZhuSkill("xinhuangtian", player) && + !target.hasSkill("xinhuangtian3") + ); + }) + ) + return false; + return player.hasCard(function (card) { + return lib.skill.xinhuangtian2.filterCard(card, player); + }, "h"); }, - filterCard:function(card,player){ - return get.name(card,player)=='shan'||get.suit(card,player)=='spade'; + filterCard: function (card, player) { + return get.name(card, player) == "shan" || get.suit(card, player) == "spade"; }, - log:false, - visible:true, - filterTarget:function(card,player,target){ - return target!=player&&target.hasZhuSkill('xinhuangtian',player)&&!target.hasSkill('xinhuangtian3'); + log: false, + visible: true, + filterTarget: function (card, player, target) { + return ( + target != player && + target.hasZhuSkill("xinhuangtian", player) && + !target.hasSkill("xinhuangtian3") + ); }, //usable:1, //forceaudio:true, - content:function(){ - player.give(cards,target); - target.addTempSkill('xinhuangtian3','phaseUseEnd'); + content: function () { + player.give(cards, target); + target.addTempSkill("xinhuangtian3", "phaseUseEnd"); }, - ai:{ - expose:0.3, - order:10, - result:{ - target:5 - } - } - }, - xinhuangtian3:{}, - rejijiang:{ - audio:'jijiang1', - audioname:['liushan','re_liubei','re_liushan','ol_liushan'], - unique:true, - group:['rejijiang1','rejijiang3'], - zhuSkill:true, - filter:function(event,player){ - if(!player.hasZhuSkill('rejijiang')||!game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'; - })) return false; - return !event.jijiang&&(event.type!='phase'||!player.hasSkill('jijiang3')); - }, - enable:['chooseToUse','chooseToRespond'], - viewAs:{name:'sha'}, - filterCard:function(){return false}, - selectCard:-1, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.3; - }, - respondSha:true, - skillTagFilter:function(player){ - if(!player.hasZhuSkill('rejijiang')||!game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'; - })) return false; + ai: { + expose: 0.3, + order: 10, + result: { + target: 5, }, }, }, - rejijiang1:{ - audio:'jijiang1', - audioname:['liushan','re_liubei','re_liushan','ol_liushan'], - trigger:{player:['useCardBegin','respondBegin']}, - logTarget:'targets', - filter:function(event,player){ - return event.skill=='rejijiang'; + xinhuangtian3: {}, + rejijiang: { + audio: "jijiang1", + audioname: ["liushan", "re_liubei", "re_liushan", "ol_liushan"], + unique: true, + group: ["rejijiang1", "rejijiang3"], + zhuSkill: true, + filter: function (event, player) { + if ( + !player.hasZhuSkill("rejijiang") || + !game.hasPlayer(function (current) { + return current != player && current.group == "shu"; + }) + ) + return false; + return !event.jijiang && (event.type != "phase" || !player.hasSkill("jijiang3")); }, - forced:true, - content:function(){ - "step 0" + enable: ["chooseToUse", "chooseToRespond"], + viewAs: { name: "sha" }, + filterCard: function () { + return false; + }, + selectCard: -1, + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.3; + }, + respondSha: true, + skillTagFilter: function (player) { + if ( + !player.hasZhuSkill("rejijiang") || + !game.hasPlayer(function (current) { + return current != player && current.group == "shu"; + }) + ) + return false; + }, + }, + }, + rejijiang1: { + audio: "jijiang1", + audioname: ["liushan", "re_liubei", "re_liushan", "ol_liushan"], + trigger: { player: ["useCardBegin", "respondBegin"] }, + logTarget: "targets", + filter: function (event, player) { + return event.skill == "rejijiang"; + }, + forced: true, + content: function () { + "step 0"; delete trigger.skill; - trigger.getParent().set('jijiang',true); - "step 1" - if(event.current==undefined) event.current=player.next; - if(event.current==player){ - player.addTempSkill('jijiang3'); + trigger.getParent().set("jijiang", true); + "step 1"; + if (event.current == undefined) event.current = player.next; + if (event.current == player) { + player.addTempSkill("jijiang3"); event.finish(); trigger.cancel(); trigger.getParent().goto(0); - } - else if(event.current.group=='shu'){ - var next=event.current.chooseToRespond('是否替'+get.translation(player)+'打出一张杀?',{name:'sha'}); - next.set('ai',function(){ - var event=_status.event; - return (get.attitude(event.player,event.source)-2); + } else if (event.current.group == "shu") { + var next = event.current.chooseToRespond( + "是否替" + get.translation(player) + "打出一张杀?", + { name: "sha" } + ); + next.set("ai", function () { + var event = _status.event; + return get.attitude(event.player, event.source) - 2; }); - next.set('source',player); - next.set('jijiang',true); - next.set('skillwarn','替'+get.translation(player)+'打出一张杀'); - next.noOrdering=true; - next.autochoose=lib.filter.autoRespondSha; - } - else{ - event.current=event.current.next; + next.set("source", player); + next.set("jijiang", true); + next.set("skillwarn", "替" + get.translation(player) + "打出一张杀"); + next.noOrdering = true; + next.autochoose = lib.filter.autoRespondSha; + } else { + event.current = event.current.next; event.redo(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { event.finish(); - trigger.card=result.card; - trigger.cards=result.cards; - trigger.throw=false; - if(typeof event.current.ai.shown=='number'&&event.current.ai.shown<0.95){ - event.current.ai.shown+=0.3; - if(event.current.ai.shown>0.95) event.current.ai.shown=0.95; + trigger.card = result.card; + trigger.cards = result.cards; + trigger.throw = false; + if (typeof event.current.ai.shown == "number" && event.current.ai.shown < 0.95) { + event.current.ai.shown += 0.3; + if (event.current.ai.shown > 0.95) event.current.ai.shown = 0.95; } - } - else{ - event.current=event.current.next; + } else { + event.current = event.current.next; event.goto(1); } - } - }, - rejijiang3:{ - trigger:{global:['useCard','respond']}, - usable:1, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.player!=player&&event.player.group=='shu'&&event.player.isIn()&& - event.player!=_status.currentPhase&&player.hasZhuSkill('rejijiang'); }, - content:function(){ - 'step 0' - trigger.player.chooseBool('激将:是否令'+get.translation(player)+'摸一张牌?').set('ai',function(){ - var evt=_status.event; - return get.attitude(evt.player,evt.getParent().player)>0; - }); - 'step 1' - if(result.bool){ - player.logSkill('rejijiang'); - trigger.player.line(player,'fire'); + }, + rejijiang3: { + trigger: { global: ["useCard", "respond"] }, + usable: 1, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.player != player && + event.player.group == "shu" && + event.player.isIn() && + event.player != _status.currentPhase && + player.hasZhuSkill("rejijiang") + ); + }, + content: function () { + "step 0"; + trigger.player + .chooseBool("激将:是否令" + get.translation(player) + "摸一张牌?") + .set("ai", function () { + var evt = _status.event; + return get.attitude(evt.player, evt.getParent().player) > 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("rejijiang"); + trigger.player.line(player, "fire"); player.draw(); - } - else player.storage.counttrigger.rejijiang3--; + } else player.storage.counttrigger.rejijiang3--; }, }, //鲁肃 - olhaoshi:{ - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ + olhaoshi: { + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { return !event.numFixed; }, - check:function(event,player){ - 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; - }); + check: function (event, player) { + return ( + player.countCards("h") + 2 + event.num <= 5 || + game.hasPlayer(function (target) { + return ( + player !== target && + !game.hasPlayer(function (current) { + return ( + current !== player && + current !== target && + current.countCards("h") < target.countCards("h") + ); + }) && + get.attitude(player, target) > 0 + ); + }) + ); }, - content:function(){ - trigger.num+=2; - player.addTempSkill('olhaoshi_give','phaseDrawAfter'); + content: function () { + trigger.num += 2; + player.addTempSkill("olhaoshi_give", "phaseDrawAfter"); }, - subSkill:{ - give:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return player.countCards('h')>5; + subSkill: { + give: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return player.countCards("h") > 5; }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(function(target){ - return target!=player&&!game.hasPlayer(function(current){ - return current!=player&¤t!=target&¤t.countCards('h')0&&get.attitude(player,i)>0) goon=true;break; + targets: targets, + selectTarget: targets.length == 1 ? -1 : 1, + selectCard: num, + prompt: "将" + get.cnNumber(num) + "张手牌交给一名手牌数最少的其他角色", + forced: true, + ai1: function (card) { + var goon = false, + player = _status.event.player; + for (var i of _status.event.targets) { + if (get.attitude(i, player) > 0 && get.attitude(player, i) > 0) + goon = true; + break; } - if(goon){ - if(!player.hasValueTarget(card)||card.name=='sha'&&player.countCards('h',function(cardx){ - return cardx.name=='sha'&&!ui.selected.cards.includes(cardx); - })>player.getCardUsable('sha')) return 2; - return Math.max(2,get.value(card)/4); + if (goon) { + if ( + !player.hasValueTarget(card) || + (card.name == "sha" && + player.countCards("h", function (cardx) { + return ( + cardx.name == "sha" && + !ui.selected.cards.includes(cardx) + ); + }) > player.getCardUsable("sha")) + ) + return 2; + return Math.max(2, get.value(card) / 4); } - return 1/Math.max(1,get.value(card)); + return 1 / Math.max(1, get.value(card)); }, - ai2:function(target){ - return get.attitude(_status.event.player,target); + ai2: function (target) { + return get.attitude(_status.event.player, target); }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.give(result.cards,target); - player.markAuto('olhaoshi_help',[target]); - player.addTempSkill('olhaoshi_help',{player:'phaseBeginStart'}); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.give(result.cards, target); + player.markAuto("olhaoshi_help", [target]); + player.addTempSkill("olhaoshi_help", { player: "phaseBeginStart" }); } }, }, - help:{ - trigger:{target:'useCardToTargeted'}, - direct:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - if(!player.storage.olhaoshi_help||!player.storage.olhaoshi_help.length) return false; - if(event.card.name!='sha'&&get.type(event.card)!='trick') return false; - for(var i of player.storage.olhaoshi_help){ - if(i.countCards('h')>0) return true; + help: { + trigger: { target: "useCardToTargeted" }, + direct: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + if (!player.storage.olhaoshi_help || !player.storage.olhaoshi_help.length) + return false; + if (event.card.name != "sha" && get.type(event.card) != "trick") return false; + for (var i of player.storage.olhaoshi_help) { + if (i.countCards("h") > 0) return true; } return false; }, - content:function(){ - 'step 0' - if(!event.targets) event.targets=player.storage.olhaoshi_help.slice(0).sortBySeat(); - event.target=event.targets.shift(); - event.target.chooseCard('h','好施:是否将一张手牌交给'+get.translation(player)+'?').set('ai',function(card){ - var player=_status.event.player,target=_status.event.getTrigger().player; - if(!_status.event.goon){ - if(get.value(card,player)<0||get.value(card,target)<0) return 1; + content: function () { + "step 0"; + if (!event.targets) + event.targets = player.storage.olhaoshi_help.slice(0).sortBySeat(); + event.target = event.targets.shift(); + event.target + .chooseCard("h", "好施:是否将一张手牌交给" + get.translation(player) + "?") + .set("ai", function (card) { + var player = _status.event.player, + target = _status.event.getTrigger().player; + if (!_status.event.goon) { + if (get.value(card, player) < 0 || get.value(card, target) < 0) + return 1; + return 0; + } + var cardx = _status.event.getTrigger().card; + if ( + card.name == "shan" && + get.tag(cardx, "respondShan") && + target.countCards("h", "shan") < player.countCards("h", "shan") + ) + return 2; + if ( + card.name == "sha" && + (cardx.name == "juedou" || + (get.tag(card, "respondSha") && + target.countCards("h", "sha") < + player.countCards("h", "sha"))) + ) + return 2; + if ( + get.value(card, target) > get.value(card, player) || + target.getUseValue(card) > player.getUseValue(card) + ) + return 1; + if (player.hasSkillTag("noh")) + return 0.5 / Math.max(1, get.value(card, player)); return 0; - } - var cardx=_status.event.getTrigger().card; - if(card.name=='shan'&&get.tag(cardx,'respondShan')&&target.countCards('h','shan')get.value(card,player)||target.getUseValue(card)>player.getUseValue(card)) return 1; - if(player.hasSkillTag('noh')) return 0.5/Math.max(1,get.value(card,player)); - return 0; - }).set('goon',get.attitude(event.target,player)>0); - 'step 1' - if(result.bool){ - target.logSkill('olhaoshi_help',player); - target.give(result.cards,player); + }) + .set("goon", get.attitude(event.target, player) > 0); + "step 1"; + if (result.bool) { + target.logSkill("olhaoshi_help", player); + target.give(result.cards, player); } - if(targets.length) event.goto(0); + if (targets.length) event.goto(0); }, }, }, }, - oldimeng:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.oldimeng.filterTarget(null,player,current)); + oldimeng: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => + lib.skill.oldimeng.filterTarget(null, player, current) + ); }, - selectTarget:2, - complexTarget:true, - filterTarget:function(card,player,target){ - if(target==player) return false; - var ps=player.countCards('he'); - if(!ui.selected.targets.length){ - var hs=target.countCards('h'); - return game.hasPlayer(function(current){ - if(current==player||current==target) return false; - var cs=current.countCards('h'); - return (hs>0||cs>0)&&Math.abs(hs-cs)<=ps; + selectTarget: 2, + complexTarget: true, + filterTarget: function (card, player, target) { + if (target == player) return false; + var ps = player.countCards("he"); + if (!ui.selected.targets.length) { + var hs = target.countCards("h"); + return game.hasPlayer(function (current) { + if (current == player || current == target) return false; + var cs = current.countCards("h"); + return (hs > 0 || cs > 0) && Math.abs(hs - cs) <= ps; }); } - var current=ui.selected.targets[0],hs=target.countCards('h'),cs=current.countCards('h'); - return (hs>0||cs>0)&&Math.abs(hs-cs)<=ps; + var current = ui.selected.targets[0], + hs = target.countCards("h"), + cs = current.countCards("h"); + return (hs > 0 || cs > 0) && Math.abs(hs - cs) <= ps; }, - multitarget:true, - multiline:true, - content:function(){ + multitarget: true, + multiline: true, + content: function () { targets[0].swapHandcards(targets[1]); - var num=Math.abs(targets[0].countCards('h')-targets[1].countCards('h')); - if(num>0){ - player.addMark('oldimeng_discard',num,false); - player.addTempSkill('oldimeng_discard','phaseUseAfter'); + var num = Math.abs(targets[0].countCards("h") - targets[1].countCards("h")); + if (num > 0) { + player.addMark("oldimeng_discard", num, false); + player.addTempSkill("oldimeng_discard", "phaseUseAfter"); } }, - ai:{ - threaten:4.5, - pretao:true, - nokeep:true, - order:1, - expose:0.2, - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return -Math.sqrt(target.countCards('h')); - var h1=ui.selected.targets[0].getCards('h'),h2=target.getCards('h'); - if(h2.length>h1.length) return 0; - var delval=get.value(h2,target)-get.value(h1,ui.selected.targets[0]); - if(delval>=0) return 0; - return -delval*(h1.length-h2.length); + ai: { + threaten: 4.5, + pretao: true, + nokeep: true, + order: 1, + expose: 0.2, + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return -Math.sqrt(target.countCards("h")); + var h1 = ui.selected.targets[0].getCards("h"), + h2 = target.getCards("h"); + if (h2.length > h1.length) return 0; + var delval = get.value(h2, target) - get.value(h1, ui.selected.targets[0]); + if (delval >= 0) return 0; + return -delval * (h1.length - h2.length); }, }, }, - subSkill:{ - discard:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.countCards('he')>0; + subSkill: { + discard: { + trigger: { player: "phaseUseEnd" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - player.chooseToDiscard('he',true,player.countMark('oldimeng_discard')); + content: function () { + player.chooseToDiscard("he", true, player.countMark("oldimeng_discard")); }, }, }, }, //贾诩 - rewansha:{ - audio:'wansha', - audioname:['re_jiaxu','shen_simayi','boss_lvbu3'], - global:'rewansha_global', - trigger:{global:'dyingBegin'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return player==_status.currentPhase; + rewansha: { + audio: "wansha", + audioname: ["re_jiaxu", "shen_simayi", "boss_lvbu3"], + global: "rewansha_global", + trigger: { global: "dyingBegin" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return player == _status.currentPhase; }, - content:function(){ - game.countPlayer(function(current){ - if(current!=player&¤t!=trigger.player) current.addSkillBlocker('rewansha_fengyin'); + content: function () { + game.countPlayer(function (current) { + if (current != player && current != trigger.player) + current.addSkillBlocker("rewansha_fengyin"); }); - player.addTempSkill('rewansha_clear'); + player.addTempSkill("rewansha_clear"); }, - subSkill:{ - global:{ - mod:{ - cardEnabled:function(card,player){ - var source=_status.currentPhase; - if(card.name=='tao'&&source&&source!=player&&source.hasSkill('rewansha')&&!player.isDying()) return false; + subSkill: { + global: { + mod: { + cardEnabled: function (card, player) { + var source = _status.currentPhase; + if ( + card.name == "tao" && + source && + source != player && + source.hasSkill("rewansha") && + !player.isDying() + ) + return false; }, - cardSavable:function(card,player){ - var source=_status.currentPhase; - if(card.name=='tao'&&source&&source!=player&&source.hasSkill('rewansha')&&!player.isDying()) return false; + cardSavable: function (card, player) { + var source = _status.currentPhase; + if ( + card.name == "tao" && + source && + source != player && + source.hasSkill("rewansha") && + !player.isDying() + ) + return false; }, }, }, - fengyin:{ - inherit:'fengyin', + fengyin: { + inherit: "fengyin", }, - clear:{ - trigger:{global:'dyingAfter'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ + clear: { + trigger: { global: "dyingAfter" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { return !_status.dying.length; }, - content:function(){ - player.removeSkill('rewansha_clear'); + content: function () { + player.removeSkill("rewansha_clear"); }, - onremove:function(){ - game.countPlayer2(function(current){ - current.removeSkillBlocker('rewansha_fengyin'); + onremove: function () { + game.countPlayer2(function (current) { + current.removeSkillBlocker("rewansha_fengyin"); }); }, }, }, }, - reluanwu:{ - audio:'luanwu', - audioname:['re_jiaxu'], - unique:true, - enable:'phaseUse', - limited:true, - skillAnimation:'epic', - animationColor:'thunder', - filterTarget:function(card,player,target){ - return target!=player; + reluanwu: { + audio: "luanwu", + audioname: ["re_jiaxu"], + unique: true, + enable: "phaseUse", + limited: true, + skillAnimation: "epic", + animationColor: "thunder", + filterTarget: function (card, player, target) { + return target != player; }, - selectTarget:-1, - multiline:true, - contentBefore:function(){ - player.awakenSkill('reluanwu'); + selectTarget: -1, + multiline: true, + contentBefore: function () { + player.awakenSkill("reluanwu"); }, - content:function(){ - "step 0" - target.chooseToUse('乱武:使用一张杀或失去1点体力',function(card){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments) - },function(card,player,target){ - if(player==target) return false; - var dist=get.distance(player,target); - if(dist>1){ - if(game.hasPlayer(function(current){ - return current!=player&&get.distance(player,current) 1) { + if ( + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) < dist; + }) + ) { + return false; + } + } + return lib.filter.filterTarget.apply(this, arguments); } - } - return lib.filter.filterTarget.apply(this,arguments) - }).set('ai2',function(){ - return get.effect_use.apply(this,arguments)-_status.event.effect; - }).set('effect',get.effect(target,{name:'losehp'},target,target)); - "step 1" - if(result.bool==false){ + ) + .set("ai2", function () { + return get.effect_use.apply(this, arguments) - _status.event.effect; + }) + .set("effect", get.effect(target, { name: "losehp" }, target, target)); + "step 1"; + if (result.bool == false) { target.loseHp(); } }, - contentAfter:function(){ - player.chooseUseTarget('sha','是否使用一张【杀】?',false,'nodistance'); + contentAfter: function () { + player.chooseUseTarget("sha", "是否使用一张【杀】?", false, "nodistance"); }, - ai:{ - order:1, - result:{ - player:function(player){ - if(lib.config.mode=='identity'&&game.zhu.isZhu&&player.identity=='fan'){ - if(game.zhu.hp==1&&game.zhu.countCards('h')<=2) return 1; + ai: { + order: 1, + result: { + player: function (player) { + if (lib.config.mode == "identity" && game.zhu.isZhu && player.identity == "fan") { + if (game.zhu.hp == 1 && game.zhu.countCards("h") <= 2) return 1; } - var num=0; - var players=game.filterPlayer(); - for(var i=0;i0) att=1; - if(att<0) att=-1; - if(players[i]!=player&&players[i].hp<=3){ - if(players[i].countCards('h')==0) num+=att/players[i].hp; - else if(players[i].countCards('h')==1) num+=att/2/players[i].hp; - else if(players[i].countCards('h')==2) num+=att/4/players[i].hp; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var att = get.attitude(player, players[i]); + if (att > 0) att = 1; + if (att < 0) att = -1; + if (players[i] != player && players[i].hp <= 3) { + if (players[i].countCards("h") == 0) num += att / players[i].hp; + else if (players[i].countCards("h") == 1) num += att / 2 / players[i].hp; + else if (players[i].countCards("h") == 2) num += att / 4 / players[i].hp; } - if(players[i].hp==1) num+=att*1.5; + if (players[i].hp == 1) num += att * 1.5; } - if(player.hp==1){ + if (player.hp == 1) { return -num; } - if(player.hp==2){ - return -game.players.length/4-num; + if (player.hp == 2) { + return -game.players.length / 4 - num; } - return -game.players.length/3-num; - } - } - } - }, - reweimu:{ - audio:2, - mod:{ - targetEnabled:function(card){ - if(get.type2(card)=='trick'&&get.color(card)=='black') return false; + return -game.players.length / 3 - num; + }, }, }, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return player==_status.currentPhase; + }, + reweimu: { + audio: 2, + mod: { + targetEnabled: function (card) { + if (get.type2(card) == "trick" && get.color(card) == "black") return false; + }, }, - content:function(){ + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return player == _status.currentPhase; + }, + content: function () { trigger.cancel(); - var num=trigger.num; - player.draw(2*num); + var num = trigger.num; + player.draw(2 * num); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target==_status.currentPhase&&get.tag(card,'damage')) return [0,1]; + ai: { + effect: { + target: function (card, player, target) { + if (target == _status.currentPhase && get.tag(card, "damage")) return [0, 1]; }, }, }, }, //顾雍 - reshenxing:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he')>=Math.min(2,(player.getStat('skill').reshenxing||0)); + reshenxing: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") >= Math.min(2, player.getStat("skill").reshenxing || 0); }, - selectCard:function(){ - return Math.min(2,(_status.event.player.getStat('skill').reshenxing||0)); + selectCard: function () { + return Math.min(2, _status.event.player.getStat("skill").reshenxing || 0); }, - prompt:function(){ - return '弃置'+get.cnNumber(Math.min(2,(_status.event.player.getStat('skill').reshenxing||0)))+'张牌并摸一张牌'; + prompt: function () { + return ( + "弃置" + + get.cnNumber(Math.min(2, _status.event.player.getStat("skill").reshenxing || 0)) + + "张牌并摸一张牌" + ); }, - check:function(card){ - var num=_status.event.player.countCards('h',{color:get.color(card)}); - if(get.position(card)=='e') num++; - return (Math.max(4,7.1-num)-get.value(card))/num; + check: function (card) { + var num = _status.event.player.countCards("h", { color: get.color(card) }); + if (get.position(card) == "e") num++; + return (Math.max(4, 7.1 - num) - get.value(card)) / num; }, - filterCard:true, - position:'he', - content:function(){ + filterCard: true, + position: "he", + content: function () { player.draw(); }, - ai:{ - order:function(item,player){ - if(!player.getStat('skill').reshenxing) return 10; + ai: { + order: function (item, player) { + if (!player.getStat("skill").reshenxing) return 10; return 1; }, - result:{player:1}, + result: { player: 1 }, }, }, - rebingyi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + rebingyi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterx:function(player){ - var cards=player.getCards('h'); - if(cards.length==1) return true; - var color=get.color(cards[0],player); - for(var i=1;iget.event().choice) + const num = player.countCards("h"); + const result = await player + .chooseTarget( + get.prompt("xinbingyi"), + `展示所有手牌,并选择至多${get.cnNumber(num)}名角色各摸一张牌${ + selfDraw ? "" : ",然后你摸一张牌" + }`, + [0, num] + ) + .set("ai", function (target) { + return get.attitude(get.player(), target); + }) .forResult(); - event.result.cost_data = {selfDraw}; + if (result.bool) + event.result = { + bool: result.bool, + cost_data: { + asyncDraw, + selfDraw, + targets: result.targets, + }, + }; + } else { + event.result = await player + .chooseBool( + get.prompt("bingyi"), + `展示所有手牌${selfDraw ? "" : ",然后你摸一张牌"}` + ) + .set("choice", selfDraw) + .set("ai", () => get.event().choice) + .forResult(); + event.result.cost_data = { selfDraw }; } }, - async content(event, trigger, player){ - await player.showHandcards(get.translation(player)+'发动了【秉壹】') + async content(event, trigger, player) { + await player.showHandcards(get.translation(player) + "发动了【秉壹】"); const data = event.cost_data; - if (data.asyncDraw && data.targets && data.targets.length){ + if (data.asyncDraw && data.targets && data.targets.length) { const targets = data.targets.sortBySeat(); game.asyncDraw(targets); } @@ -5489,1022 +6722,1196 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //钟会 - xinquanji:{ - audio:2, - trigger:{ - player:['damageEnd'], - global:['gainAfter','loseAsyncAfter'], + xinquanji: { + audio: 2, + trigger: { + player: ["damageEnd"], + global: ["gainAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - if(event.name=='damage') return true; - if(event.name=='loseAsync'){ - if(event.type!='gain'||event.giver) return false; - var cards=event.getl(player).cards2; - return game.hasPlayer(function(current){ - if(current==player) return false; - var cardsx=event.getg(current); - for(var i of cardsx){ - if(cards.includes(i)) return true; + filter: function (event, player) { + if (event.name == "damage") return true; + if (event.name == "loseAsync") { + if (event.type != "gain" || event.giver) return false; + var cards = event.getl(player).cards2; + return game.hasPlayer(function (current) { + if (current == player) return false; + var cardsx = event.getg(current); + for (var i of cardsx) { + if (cards.includes(i)) return true; } return false; }); } - if(player==event.player) return false; - if(event.giver||event.getParent().name=='gift') return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + if (player == event.player) return false; + if (event.giver || event.getParent().name == "gift") return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - frequent:true, - content:function(){ - 'step 0' - event.count=(trigger.name=='damage'?trigger.num:1); - 'step 1' + frequent: true, + content: function () { + "step 0"; + event.count = trigger.name == "damage" ? trigger.num : 1; + "step 1"; event.count--; player.draw(); - 'step 2' - var hs=player.getCards('h'); - if(hs.length){ - if(hs.length==1) event._result={bool:true,cards:hs}; - else player.chooseCard('h',true,'选择一张手牌作为“权”'); + "step 2"; + var hs = player.getCards("h"); + if (hs.length) { + if (hs.length == 1) event._result = { bool: true, cards: hs }; + else player.chooseCard("h", true, "选择一张手牌作为“权”"); + } else event.goto(4); + "step 3"; + if (result.bool && result.cards && result.cards.length) { + player.addToExpansion(result.cards, "giveAuto", player).gaintag.add("xinquanji"); } - else event.goto(4); - 'step 3' - if(result.bool&&result.cards&&result.cards.length){ - player.addToExpansion(result.cards,'giveAuto',player).gaintag.add('xinquanji'); - } - 'step 4' - if(event.count>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('xinquanji')).set('frequentSkill',event.name); - } - else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('xinquanji'); + "step 4"; + if ( + event.count > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("xinquanji")).set("frequentSkill", event.name); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("xinquanji"); event.goto(1); } }, - locked:false, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + locked: false, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('xinquanji').length; + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("xinquanji").length; }, }, - ai:{ - maixie:true, - maixie_hp:true, - threaten:0.8, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&!target.storage.xinzili){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [0.5,get.tag(card,'damage')*2]; - if(!target.hasSkill('xinpaiyi')&&target.hp>1) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==3) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + maixie: true, + maixie_hp: true, + threaten: 0.8, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage") && !target.storage.xinzili) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0.5, get.tag(card, "damage") * 2]; + if (!target.hasSkill("xinpaiyi") && target.hp > 1) + return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 3) return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } - }, - xinzili:{ - derivation:'xinpaiyi', - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.getExpansions('xinquanji').length>2; + }, + }, }, - content:function(){ - player.awakenSkill('xinzili'); + }, + xinzili: { + derivation: "xinpaiyi", + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.getExpansions("xinquanji").length > 2; + }, + content: function () { + player.awakenSkill("xinzili"); player.recover(); player.draw(2); player.loseMaxHp(); - player.addSkills('xinpaiyi'); + player.addSkills("xinpaiyi"); + }, + ai: { + combo: "xinquanji", }, }, - xinpaiyi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.getExpansions('xinquanji').length>0&&(!player.hasSkill('xinpaiyi_0')||!player.hasSkill('xinpaiyi_1')) + xinpaiyi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.getExpansions("xinquanji").length > 0 && + (!player.hasSkill("xinpaiyi_0") || !player.hasSkill("xinpaiyi_1")) + ); }, - chooseButton:{ - check:function(button){ - if(typeof button.link=='object') return 1; - var player=_status.event.player,num=player.getExpansions('xinquanji').length-1; - if(button.link==1){ - if(game.countPlayer(function(current){ - return get.damageEffect(current,player,player)>0; - }) 0; + }) < num + ) + return 0.5; return 2; } - if(num<2) return 0; + if (num < 2) return 0; return 1; }, - dialog:function(event,player){ - var dialog=ui.create.dialog('权计','hidden'); - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var list=['摸牌','造成伤害']; - dialog.add([list.map((item,i)=>{ - return [i,item]; - }),'tdnodes']); - dialog.add(player.getExpansions('xinquanji')); + dialog: function (event, player) { + var dialog = ui.create.dialog("权计", "hidden"); + var table = document.createElement("div"); + table.classList.add("add-setting"); + table.style.margin = "0"; + table.style.width = "100%"; + table.style.position = "relative"; + var list = ["摸牌", "造成伤害"]; + dialog.add([ + list.map((item, i) => { + return [i, item]; + }), + "tdnodes", + ]); + dialog.add(player.getExpansions("xinquanji")); return dialog; }, - select:2, - filter:function(button,player){ - if(typeof button.link=='number'&&player.hasSkill('xinpaiyi_'+button.link)) return false; - if(ui.selected.buttons.length) return (typeof ui.selected.buttons[0].link)!=(typeof button.link); + select: 2, + filter: function (button, player) { + if (typeof button.link == "number" && player.hasSkill("xinpaiyi_" + button.link)) + return false; + if (ui.selected.buttons.length) + return typeof ui.selected.buttons[0].link != typeof button.link; return true; }, - backup:function(links){ - if(typeof links[0]=='object') links.reverse(); - var next=get.copy(lib.skill['xinpaiyi_backup'+links[0]]); - next.card=links[1]; + backup: function (links) { + if (typeof links[0] == "object") links.reverse(); + var next = get.copy(lib.skill["xinpaiyi_backup" + links[0]]); + next.card = links[1]; return next; }, - prompt:function(links,player){ - if(typeof links[0]=='object') links.reverse(); - var num=get.cnNumber(Math.max(1,player.getExpansions('xinquanji').length-1)),card=get.translation(links[1]); - if(links[0]==0) return '移去'+card+'并令一名角色摸'+num+'张牌'; - return '移去'+card+'并对至多'+num+'名角色造成1点伤害'; + prompt: function (links, player) { + if (typeof links[0] == "object") links.reverse(); + var num = get.cnNumber(Math.max(1, player.getExpansions("xinquanji").length - 1)), + card = get.translation(links[1]); + if (links[0] == 0) return "移去" + card + "并令一名角色摸" + num + "张牌"; + return "移去" + card + "并对至多" + num + "名角色造成1点伤害"; }, }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, + combo: "xinquanji", }, - subSkill:{ - 0:{}, - 1:{}, - backup0:{ - audio:'xinpaiyi', - filterCard:()=>false, - selectCard:-1, - filterTarget:true, - delay:false, - content:function(){ - 'step 0' - player.addTempSkill('xinpaiyi_0','phaseUseEnd'); - var card=lib.skill.xinpaiyi_backup.card; + subSkill: { + 0: {}, + 1: {}, + backup0: { + audio: "xinpaiyi", + filterCard: () => false, + selectCard: -1, + filterTarget: true, + delay: false, + content: function () { + "step 0"; + player.addTempSkill("xinpaiyi_0", "phaseUseEnd"); + var card = lib.skill.xinpaiyi_backup.card; player.loseToDiscardpile(card); - 'step 1' - target.draw(Math.max(1,player.getExpansions('xinquanji').length)); + "step 1"; + target.draw(Math.max(1, player.getExpansions("xinquanji").length)); }, - ai:{ - result:{ - target:function(player,target){ - if(target.hasSkill('nogain')) return 0; - if(player==target&&!player.needsToDiscard()) return 3; + ai: { + result: { + target: function (player, target) { + if (target.hasSkill("nogain")) return 0; + if (player == target && !player.needsToDiscard()) return 3; return 1; }, }, }, }, - backup1:{ - audio:'xinpaiyi', - filterCard:()=>false, - selectCard:-1, - filterTarget:true, - delay:false, - multitarget:true, - multiline:true, - selectTarget:function(){ - return [1,Math.max(1,_status.event.player.getExpansions('xinquanji').length-1)]; + backup1: { + audio: "xinpaiyi", + filterCard: () => false, + selectCard: -1, + filterTarget: true, + delay: false, + multitarget: true, + multiline: true, + selectTarget: function () { + return [ + 1, + Math.max(1, _status.event.player.getExpansions("xinquanji").length - 1), + ]; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; targets.sortBySeat(); - player.addTempSkill('xinpaiyi_1','phaseUseEnd'); - var card=lib.skill.xinpaiyi_backup.card; + player.addTempSkill("xinpaiyi_1", "phaseUseEnd"); + var card = lib.skill.xinpaiyi_backup.card; player.loseToDiscardpile(card); - 'step 1' - for(var i of targets) i.damage(); + "step 1"; + for (var i of targets) i.damage(); }, - ai:{ - tag:{ - damage:1, + ai: { + tag: { + damage: 1, }, - result:{ - target:-1.5, + result: { + target: -1.5, }, }, }, }, }, //界蔡夫人 - reqieting:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - filter:function(event,player){ - var target=event.player; - if(player==target) return false; - if(!target.getHistory('sourceDamage').length){ - var cards=target.getCards('e'); - for(var i of cards){ - if(player.canEquip(i)) return true; + reqieting: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + filter: function (event, player) { + var target = event.player; + if (player == target) return false; + if (!target.getHistory("sourceDamage").length) { + var cards = target.getCards("e"); + for (var i of cards) { + if (player.canEquip(i)) return true; } } - return target.getHistory('useCard',function(evt){ - return evt.targets&&evt.targets.filter(function(i){ - return i!=target; - }).length>0; - }).length==0; + return ( + target.getHistory("useCard", function (evt) { + return ( + evt.targets && + evt.targets.filter(function (i) { + return i != target; + }).length > 0 + ); + }).length == 0 + ); }, - frequent:true, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - event.logged=false; - var list=[]; - if(!target.getHistory('sourceDamage').length){ - var cards=target.getCards('e'); - for(var i of cards){ - if(player.canEquip(i)) list.push(i); + frequent: true, + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + event.logged = false; + var list = []; + if (!target.getHistory("sourceDamage").length) { + var cards = target.getCards("e"); + for (var i of cards) { + if (player.canEquip(i)) list.push(i); } } - if(list.length){ - player.choosePlayerCard(target,'e',get.prompt('reqieting',target)).set('list',list).set('filterButton',function(button){ - return _status.event.list.includes(button.link); - }).set('ai',function(button){ - var evt=_status.event,val=get.value(button.link); - if(evt.target.hasSkillTag('noe')) val-=4; - if((evt.att>0)==(val>0)) return 0; - return get.effect(evt.player,button.link,evt.player,evt.player); - }).set('att',get.attitude(player,target)); - } - else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('reqieting',target); - event.logged=true; - var card=result.links[0]; - target.$give(card,player,false); + if (list.length) { + player + .choosePlayerCard(target, "e", get.prompt("reqieting", target)) + .set("list", list) + .set("filterButton", function (button) { + return _status.event.list.includes(button.link); + }) + .set("ai", function (button) { + var evt = _status.event, + val = get.value(button.link); + if (evt.target.hasSkillTag("noe")) val -= 4; + if (evt.att > 0 == val > 0) return 0; + return get.effect(evt.player, button.link, evt.player, evt.player); + }) + .set("att", get.attitude(player, target)); + } else event.goto(2); + "step 1"; + if (result.bool) { + player.logSkill("reqieting", target); + event.logged = true; + var card = result.links[0]; + target.$give(card, player, false); game.delay(0.5); player.equip(card); } - if(target.getHistory('useCard',function(evt){ - return evt.targets&&evt.targets.filter(function(i){ - return i!=target; - }).length>0; - }).length!=0) event.finish(); - 'step 2' - player.chooseBool('是否发动【窃听】摸一张牌?').set('frequentSkill','reqieting'); - 'step 3' - if(result.bool){ - if(!event.logged) player.logSkill('reqieting',target); + if ( + target.getHistory("useCard", function (evt) { + return ( + evt.targets && + evt.targets.filter(function (i) { + return i != target; + }).length > 0 + ); + }).length != 0 + ) + event.finish(); + "step 2"; + player.chooseBool("是否发动【窃听】摸一张牌?").set("frequentSkill", "reqieting"); + "step 3"; + if (result.bool) { + if (!event.logged) player.logSkill("reqieting", target); player.draw(); } }, }, - rexianzhou:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.countCards('e')>0; + rexianzhou: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.countCards("e") > 0; }, - filterCard:true, - position:'e', - selectCard:-1, - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.awakenSkill('rexianzhou'); - player.give(cards,target); - player.recover(cards.length) - 'step 1' - var list=game.filterPlayer(function(current){ + filterCard: true, + position: "e", + selectCard: -1, + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.awakenSkill("rexianzhou"); + player.give(cards, target); + player.recover(cards.length); + "step 1"; + var list = game.filterPlayer(function (current) { return target.inRange(current); }); - if(list.length){ - var max=Math.min(list.length,cards.length); - target.chooseTarget(true,[1,max],'对至多'+get.cnNumber(max)+'名范围内的角色各造成1点伤害',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',list).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); - for(var i of targets) i.damage('nocard'); + if (list.length) { + var max = Math.min(list.length, cards.length); + target + .chooseTarget( + true, + [1, max], + "对至多" + get.cnNumber(max) + "名范围内的角色各造成1点伤害", + function (card, player, target) { + return _status.event.list.includes(target); + } + ) + .set("list", list) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); + for (var i of targets) i.damage("nocard"); } }, - ai:{ - order:1, - result:{ - target:1, - player:function(player){ - var bool=true,players=game.filterPlayer(); - for(var i=0;i2&&get.attitude(players[i],player)>2){ - bool=false;break; + ai: { + order: 1, + result: { + target: 1, + player: function (player) { + var bool = true, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + get.attitude(player, players[i]) > 2 && + get.attitude(players[i], player) > 2 + ) { + bool = false; + break; } } - if(bool) return -10; - if(player.hp==1) return 1; - if(game.phaseNumber{ - game.addGlobalSkill('relongyin_order'); + relongyin: { + audio: 2, + shaRelated: true, + init: (player) => { + game.addGlobalSkill("relongyin_order"); }, - onremove:(player)=>{ - if(!game.hasPlayer(current=>current.hasSkill('relongyin'),true)) game.removeGlobalSkill('relongyin_order'); + onremove: (player) => { + if (!game.hasPlayer((current) => current.hasSkill("relongyin"), true)) + game.removeGlobalSkill("relongyin_order"); }, - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countCards('he')>0&&event.player.isPhaseUsing(); + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && player.countCards("he") > 0 && event.player.isPhaseUsing() + ); }, - content:function(){ - 'step 0' - var go=false; - if(get.attitude(player,trigger.player)>0){ - if(get.color(trigger.card)=='red'){ - go=true; - } - else if(trigger.addCount===false||!trigger.player.isPhaseUsing()) go=false; - else if(!trigger.player.hasSkill('paoxiao')&& - !trigger.player.hasSkill('tanlin3')&& - !trigger.player.hasSkill('zhaxiang2')&& - !trigger.player.hasSkill('fengnu')&& - !trigger.player.getEquip('zhuge')){ - var nh=trigger.player.countCards('h'); - if(player==trigger.player){ - go=(player.countCards('h','sha')>0); - } - else if(nh>=4){ - go=true; - } - else if(player.countCards('h','sha')){ - if(nh==3){ - go=Math.random()<0.8; + content: function () { + "step 0"; + var go = false; + if (get.attitude(player, trigger.player) > 0) { + if (get.color(trigger.card) == "red") { + go = true; + } else if (trigger.addCount === false || !trigger.player.isPhaseUsing()) go = false; + else if ( + !trigger.player.hasSkill("paoxiao") && + !trigger.player.hasSkill("tanlin3") && + !trigger.player.hasSkill("zhaxiang2") && + !trigger.player.hasSkill("fengnu") && + !trigger.player.getEquip("zhuge") + ) { + var nh = trigger.player.countCards("h"); + if (player == trigger.player) { + go = player.countCards("h", "sha") > 0; + } else if (nh >= 4) { + go = true; + } else if (player.countCards("h", "sha")) { + if (nh == 3) { + go = Math.random() < 0.8; + } else if (nh == 2) { + go = Math.random() < 0.5; } - else if(nh==2){ - go=Math.random()<0.5; - } - } - else if(nh>=3){ - if(nh==3){ - go=Math.random()<0.5; - } - else if(nh==2){ - go=Math.random()<0.2; + } else if (nh >= 3) { + if (nh == 3) { + go = Math.random() < 0.5; + } else if (nh == 2) { + go = Math.random() < 0.2; } } } } //AI停顿 - if(go&&!event.isMine()&&!event.isOnline()&&player.hasCard(function(card){ - return get.value(card)<6&&lib.filter.cardDiscardable(card,player,event.name); - },'he')){ + if ( + go && + !event.isMine() && + !event.isOnline() && + player.hasCard(function (card) { + return ( + get.value(card) < 6 && lib.filter.cardDiscardable(card, player, event.name) + ); + }, "he") + ) { game.delayx(); } - var next=player.chooseToDiscard(get.prompt('longyin'),'弃置一张牌'+(get.color(trigger.card)=='red'?'并摸一张牌':'')+',令'+get.translation(trigger.player)+'本次使用的【杀】不计入使用次数','he'); - next.logSkill=['relongyin',trigger.player]; - next.set('ai',function(card){ - if(_status.event.go){ - return 6-get.value(card); + var next = player.chooseToDiscard( + get.prompt("longyin"), + "弃置一张牌" + + (get.color(trigger.card) == "red" ? "并摸一张牌" : "") + + ",令" + + get.translation(trigger.player) + + "本次使用的【杀】不计入使用次数", + "he" + ); + next.logSkill = ["relongyin", trigger.player]; + next.set("ai", function (card) { + if (_status.event.go) { + return 6 - get.value(card); } return 0; }); - next.set('go',go); - 'step 1' - if(result.bool){ - if(trigger.addCount!==false){ - trigger.addCount=false; + next.set("go", go); + "step 1"; + if (result.bool) { + if (trigger.addCount !== false) { + trigger.addCount = false; trigger.player.getStat().card.sha--; } - if(get.color(trigger.card)=='red'){ + if (get.color(trigger.card) == "red") { player.draw(); } - if(get.number(result.cards[0],player)==get.number(trigger.card)) player.restoreSkill('jiezhong'); + if (get.number(result.cards[0], player) == get.number(trigger.card)) + player.restoreSkill("jiezhong"); } }, - ai:{ - expose:0.2 + ai: { + expose: 0.2, }, - subSkill:{ - order:{ - mod:{ - aiOrder:(player,card,num)=>{ - if(num&&card.name==='sha'&&get.color(card)==='red'){ - let gp=game.findPlayer(current=>{ - return current.hasSkill('relongyin')&¤t.hasCard(i=>true,'he'); + subSkill: { + order: { + mod: { + aiOrder: (player, card, num) => { + if (num && card.name === "sha" && get.color(card) === "red") { + let gp = game.findPlayer((current) => { + return ( + current.hasSkill("relongyin") && + current.hasCard((i) => true, "he") + ); }); - if(gp) return num+0.15*Math.sign(get.attitude(player,gp)); + if (gp) return num + 0.15 * Math.sign(get.attitude(player, gp)); } - } + }, }, - trigger:{player:'dieAfter'}, - filter:(event,player)=>{ - return !game.hasPlayer(current=>current.hasSkill('relongyin'),true); + trigger: { player: "dieAfter" }, + filter: (event, player) => { + return !game.hasPlayer((current) => current.hasSkill("relongyin"), true); }, - silent:true, - forceDie:true, - charlotte:true, - content:()=>{ - game.removeGlobalSkill('relongyin_order'); - } - } - } - }, - jiezhong:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - limited:true, - skillAnimation:true, - animationColor:'orange', - filter:function(event,player){ - return player.countCards('h') { + game.removeGlobalSkill("relongyin_order"); + }, + }, }, - content:function(){ - player.awakenSkill('jiezhong'); - player.draw(Math.min(5,player.maxHp-player.countCards('h'))); + }, + jiezhong: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + limited: true, + skillAnimation: true, + animationColor: "orange", + filter: function (event, player) { + return player.countCards("h") < player.maxHp; + }, + content: function () { + player.awakenSkill("jiezhong"); + player.draw(Math.min(5, player.maxHp - player.countCards("h"))); }, }, //新郭淮 - decadejingce:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - return player.getHistory('useCard').length>=player.hp; + decadejingce: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { + return player.getHistory("useCard").length >= player.hp; }, - content:function(){ - 'step 0' - var list=[],history=player.getHistory('useCard'); - for(var i of history){ + content: function () { + "step 0"; + var list = [], + history = player.getHistory("useCard"); + for (var i of history) { list.add(get.suit(i.card)); - if(list.length>=player.hp) break; + if (list.length >= player.hp) break; } - if(list.length>=player.hp) event.goon=true; - else player.chooseControl('摸牌阶段','出牌阶段').set('prompt','精策:选择要执行的额外阶段'); - 'step 1' - if(event.goon||result.index==0){ - var next=player.phaseDraw(); + if (list.length >= player.hp) event.goon = true; + else + player + .chooseControl("摸牌阶段", "出牌阶段") + .set("prompt", "精策:选择要执行的额外阶段"); + "step 1"; + if (event.goon || result.index == 0) { + var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); } - if(event.goon||result.index==1){ - var next=player.phaseUse(); + if (event.goon || result.index == 1) { + var next = player.phaseUse(); event.next.remove(next); trigger.getParent().next.push(next); } }, }, //新于禁 - decadezhenjun:{ - audio:2, - trigger:{ - player:['phaseZhunbeiBegin','phaseJieshuBegin'] + decadezhenjun: { + audio: 2, + trigger: { + player: ["phaseZhunbeiBegin", "phaseJieshuBegin"], }, - filter:function (event,player){ - return game.hasPlayer(function(current){ - return current.countCards('he')>0; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("he") > 0; }); }, - direct:true, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt2('decadezhenjun'),function(card,player,target){ - return target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*(target.countCards('e')+1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var num=Math.max(target.countCards('h')-target.hp,1); - player.logSkill('decadezhenjun',target); - player.discardPlayerCard(num,target,true); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("decadezhenjun"), function (card, player, target) { + return target.countCards("he") > 0; + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) * (target.countCards("e") + 1); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var num = Math.max(target.countCards("h") - target.hp, 1); + player.logSkill("decadezhenjun", target); + player.discardPlayerCard(num, target, true); } - 'step 2' - if(result.cards&&result.cards.length){ - for(var i=0;i0){ - var prompt='弃置一张牌,或令'+get.translation(event.target)+'摸'+get.cnNumber(event.num)+'张牌'; - player.chooseToDiscard(prompt,'he').ai=function(card){ - return 7-get.value(card); - } - } - else event.finish(); - } - else event.finish(); - 'step 3' - if(!result.bool){ + event.num = result.cards.length; + if (event.num > 0) { + var prompt = + "弃置一张牌,或令" + + get.translation(event.target) + + "摸" + + get.cnNumber(event.num) + + "张牌"; + player.chooseToDiscard(prompt, "he").ai = function (card) { + return 7 - get.value(card); + }; + } else event.finish(); + } else event.finish(); + "step 3"; + if (!result.bool) { event.target.draw(event.num); } }, }, //界姜维 - oltiaoxin:{ - audio:'tiaoxin', - audioname:['sp_jiangwei','xiahouba','re_jiangwei','gz_jiangwei','ol_jiangwei'], - enable:'phaseUse', - usable:2, - filter:function(event,player){ - if(player.getStat('skill').oltiaoxin) return !player.hasSkill('oltiaoxin2'); + oltiaoxin: { + audio: "tiaoxin", + audioname: ["sp_jiangwei", "xiahouba", "re_jiangwei", "gz_jiangwei", "ol_jiangwei"], + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + if (player.getStat("skill").oltiaoxin) return !player.hasSkill("oltiaoxin2"); return true; }, - filterTarget:function(card,player,target){ - return target!=player&&target.inRange(player)&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return target != player && target.inRange(player) && target.countCards("he") > 0; }, - content:function(){ - "step 0" - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'挑衅:对'+get.translation(player)+'使用一张杀,或令其弃置你的一张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); - "step 1" - if(result.bool&&player.getHistory('damage',function(evt){ - return evt.getParent().type=='card'&&evt.getParent(4)==event; - }).length>0) player.addTempSkill('oltiaoxin2','phaseUseEnd'); - else if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true).boolline=true; + content: function () { + "step 0"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "挑衅:对" + get.translation(player) + "使用一张杀,或令其弃置你的一张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + if ( + result.bool && + player.getHistory("damage", function (evt) { + return evt.getParent().type == "card" && evt.getParent(4) == event; + }).length > 0 + ) + player.addTempSkill("oltiaoxin2", "phaseUseEnd"); + else if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true).boolline = true; }, - ai:{ - order:4, - expose:0.2, - result:{ - target:-1, - player:function(player,target){ - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.hp<=2) return -2; - if(player.countCards('h','shan')==0) return -1; + ai: { + order: 4, + expose: 0.2, + result: { + target: -1, + player: function (player, target) { + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.hp <= 2) return -2; + if (player.countCards("h", "shan") == 0) return -1; return -0.5; - } + }, }, - threaten:1.1 - } - }, - oltiaoxin2:{}, - olzhiji:{ - skillAnimation:true, - animationColor:'fire', - audio:2, - unique:true, - juexingji:true, - //priority:-10, - derivation:'reguanxing', - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - forced:true, - filter:function(event,player){ - if(player.storage.zhiji) return false; - return player.countCards('h')==0; + threaten: 1.1, }, - content:function(){ - "step 0" - player.awakenSkill('olzhiji'); - player.chooseDrawRecover(2,true); - "step 1" + }, + oltiaoxin2: {}, + olzhiji: { + skillAnimation: true, + animationColor: "fire", + audio: 2, + unique: true, + juexingji: true, + //priority:-10, + derivation: "reguanxing", + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + forced: true, + filter: function (event, player) { + if (player.storage.zhiji) return false; + return player.countCards("h") == 0; + }, + content: function () { + "step 0"; + player.awakenSkill("olzhiji"); + player.chooseDrawRecover(2, true); + "step 1"; player.loseMaxHp(); - player.addSkills('reguanxing'); - } + player.addSkills("reguanxing"); + }, }, //界郭图张嶷 - rejigong:{ - audio:2, - direct:true, - trigger:{player:'phaseUseBegin'}, - content:function(){ - 'step 0' - player.chooseControl('一张','两张','三张','cancel2').set('prompt',get.prompt2('rejigong')).set('ai',()=>'三张'); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('rejigong'); - player.addTempSkill('rejigong2'); - player.draw(1+result.index); + rejigong: { + audio: 2, + direct: true, + trigger: { player: "phaseUseBegin" }, + content: function () { + "step 0"; + player + .chooseControl("一张", "两张", "三张", "cancel2") + .set("prompt", get.prompt2("rejigong")) + .set("ai", () => "三张"); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("rejigong"); + player.addTempSkill("rejigong2"); + player.draw(1 + result.index); } }, }, - rejigong2:{ - audio:'rejigong', - mod:{ - maxHandcardBase:function(player){ - if(game.online) return (player.getStat('damage')||0); - var num=0; - player.getHistory('sourceDamage',function(evt){ - num+=evt.num; + rejigong2: { + audio: "rejigong", + mod: { + maxHandcardBase: function (player) { + if (game.online) return player.getStat("damage") || 0; + var num = 0; + player.getHistory("sourceDamage", function (evt) { + num += evt.num; }); return num; }, }, - trigger:{player:'phaseDiscardBegin'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(player.isHealthy()) return false; - var num=0; - player.getHistory('sourceDamage',function(evt){ - num+=evt.num; + trigger: { player: "phaseDiscardBegin" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if (player.isHealthy()) return false; + var num = 0; + player.getHistory("sourceDamage", function (evt) { + num += evt.num; }); - if(!num) return false; - var num2=0; - player.getHistory('gain',function(evt){ - var evtx=evt.getParent(2); - if(evtx.name=='rejigong'&&evtx.player==player) num2+=evt.cards.length; + if (!num) return false; + var num2 = 0; + player.getHistory("gain", function (evt) { + var evtx = evt.getParent(2); + if (evtx.name == "rejigong" && evtx.player == player) num2 += evt.cards.length; }); - return num>=num2; + return num >= num2; }, - content:function(){ + content: function () { player.recover(); }, }, - reshizhi:{ - mod:{ - cardname:function(card,player){ - if(card.name=='shan'&&player.hp==1) return 'sha'; + reshizhi: { + mod: { + cardname: function (card, player) { + if (card.name == "shan" && player.hp == 1) return "sha"; }, }, - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.hp==1&& - event.cards&&event.cards.length==1&&event.cards[0].name=='shan'; + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + player.hp == 1 && + event.cards && + event.cards.length == 1 && + event.cards[0].name == "shan" + ); }, - content:function(){ + content: function () { player.recover(); }, }, //界陈群 - redingpin:{ - audio:2, - enable:'phaseUse', - onChooseToUse:function(event){ - if(event.type!='phase'||game.online) return; - var list=[],player=event.player; - player.getHistory('useCard',function(evt){ + redingpin: { + audio: 2, + enable: "phaseUse", + onChooseToUse: function (event) { + if (event.type != "phase" || game.online) return; + var list = [], + player = event.player; + player.getHistory("useCard", function (evt) { list.add(get.type2(evt.card)); }); - player.getHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent(2).redingpin_ignore) return; - for(var i of evt.cards2){ - list.add(get.type2(i,evt.hs.includes(i)?player:false)); + player.getHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent(2).redingpin_ignore) return; + for (var i of evt.cards2) { + list.add(get.type2(i, evt.hs.includes(i) ? player : false)); } - }) - event.set('redingpin_types',list); + }); + event.set("redingpin_types", list); }, - filter:function(event,player){ - var list=event.redingpin_types||[]; - return player.countCards('he',function(card){ - return !list.includes(get.type2(card)); - })>0; + filter: function (event, player) { + var list = event.redingpin_types || []; + return ( + player.countCards("he", function (card) { + return !list.includes(get.type2(card)); + }) > 0 + ); }, - filterCard:function(card){ - var list=_status.event.redingpin_types||[]; + filterCard: function (card) { + var list = _status.event.redingpin_types || []; return !list.includes(get.type2(card)); }, - position:'he', - filterTarget:function(card,player,target){ - return !target.hasSkill('redingpin2'); + position: "he", + filterTarget: function (card, player, target) { + return !target.hasSkill("redingpin2"); }, - content:function(){ - 'step 0' - target.judge(function(card){ - var evt=_status.event.getParent('redingpin'),suit=get.suit(card); - switch(suit){ - case 'club':case 'spade':return evt.target.hp; - case 'diamond':return get.sgn(get.attitude(evt.target,evt.player))*-3; + content: function () { + "step 0"; + target.judge(function (card) { + var evt = _status.event.getParent("redingpin"), + suit = get.suit(card); + switch (suit) { + case "club": + case "spade": + return evt.target.hp; + case "diamond": + return get.sgn(get.attitude(evt.target, evt.player)) * -3; } return 0; - }).judge2=function(result){ - if(result.color=='black') return true; + }).judge2 = function (result) { + if (result.color == "black") return true; return false; }; - 'step 1' - switch(result.suit){ - case 'spade':case 'club': - if(target.hp>0) target.draw(Math.min(3,target.hp)); - target.addTempSkill('redingpin2'); + "step 1"; + switch (result.suit) { + case "spade": + case "club": + if (target.hp > 0) target.draw(Math.min(3, target.hp)); + target.addTempSkill("redingpin2"); break; - case 'heart': - event.getParent().redingpin_ignore=true; + case "heart": + event.getParent().redingpin_ignore = true; break; - case 'diamond': + case "diamond": player.turnOver(); break; } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(player.isTurnedOver()) return target.hp; - var card=ui.cardPile.firstChild; - if(!card) return; - if(get.color(card)=='black') return target.hp; + ai: { + order: 9, + result: { + target: function (player, target) { + if (player.isTurnedOver()) return target.hp; + var card = ui.cardPile.firstChild; + if (!card) return; + if (get.color(card) == "black") return target.hp; return 0; }, }, }, }, - redingpin2:{charlotte:true}, - refaen:{ - audio:2, - audioname:['dc_chenqun'], - trigger:{global:['turnOverAfter','linkAfter']}, - logTarget:'player', - filter:function(event,player){ - if(event.name=='link') return event.player.isLinked(); + redingpin2: { charlotte: true }, + refaen: { + audio: 2, + audioname: ["dc_chenqun"], + trigger: { global: ["turnOverAfter", "linkAfter"] }, + logTarget: "player", + filter: function (event, player) { + if (event.name == "link") return event.player.isLinked(); return true; }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ + content: function () { trigger.player.draw(); }, }, - dcfaen:{ - audio:'refaen', - audioname:['dc_chenqun'], - trigger:{global:['turnOverAfter','linkAfter']}, - logTarget:'player', - filter:function(event,player){ - if(event.name=='link') return event.player.isLinked(); + dcfaen: { + audio: "refaen", + audioname: ["dc_chenqun"], + trigger: { global: ["turnOverAfter", "linkAfter"] }, + logTarget: "player", + filter: function (event, player) { + if (event.name == "link") return event.player.isLinked(); return !event.player.isTurnedOver(); }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ + content: function () { trigger.player.draw(); }, }, //界曹彰 - xinjiangchi:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - content:function(){ - 'step 0' - var list=[ - '摸一张牌', - '摸两张牌,本回合内不能使用或打出【杀】', - ]; - if(player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'xinjiangchi')>0; - })>0) list.push('弃置一张牌,本回合可以多使用一张【杀】且无距离限制'); - player.chooseControl('cancel2').set('prompt',get.prompt('xinjiangchi')).set('choiceList',list).set('ai',function(){ - var player=_status.event.player; - if(!player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card,false); - })) return 1; - return 0; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xinjiangchi'); - switch(result.index){ - case 0:{ + xinjiangchi: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + var list = ["摸一张牌", "摸两张牌,本回合内不能使用或打出【杀】"]; + if ( + player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "xinjiangchi") > 0; + }) > 0 + ) + list.push("弃置一张牌,本回合可以多使用一张【杀】且无距离限制"); + player + .chooseControl("cancel2") + .set("prompt", get.prompt("xinjiangchi")) + .set("choiceList", list) + .set("ai", function () { + var player = _status.event.player; + if ( + !player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card, false); + }) + ) + return 1; + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xinjiangchi"); + switch (result.index) { + case 0: { player.draw(); break; } - case 1:{ + case 1: { player.draw(2); - player.addTempSkill('xinjiangchi_less'); + player.addTempSkill("xinjiangchi_less"); break; } - case 2:{ - player.chooseToDiscard('he',true); - player.addTempSkill('xinjiangchi_more'); + case 2: { + player.chooseToDiscard("he", true); + player.addTempSkill("xinjiangchi_more"); break; } } } }, - subSkill:{ - less:{ - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + subSkill: { + less: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, - cardRespondable:function(card){ - if(card.name=='sha') return false; + cardRespondable: function (card) { + if (card.name == "sha") return false; }, }, - charlotte:true, + charlotte: true, }, - more:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + more: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, - targetInRange:function(card){ - if(card.name=='sha') return true; + targetInRange: function (card) { + if (card.name == "sha") return true; }, }, - charlotte:true, + charlotte: true, }, }, }, //界周仓和程普 - ollihuo:{ - mod:{ - aiOrder:function(player,card,num){ - if(card.name=='sha'&&!player.getHistory('useCard').length) return num+7; + ollihuo: { + mod: { + aiOrder: function (player, card, num) { + if (card.name == "sha" && !player.getHistory("useCard").length) return num + 7; }, }, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; return false; }, - audio:'lihuo', - locked:false, - prompt2:function(event){ - return '将'+get.translation(event.card)+'改为火属性'; + audio: "lihuo", + locked: false, + prompt2: function (event) { + return "将" + get.translation(event.card) + "改为火属性"; }, - audioname:['re_chengpu'], - check:function(event,player){ - return (event.baseDamage>1||player.getHistory('useCard').indexOf(event)==0)&&(player.hp>1||player.getExpansions('rechunlao').length)&&game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current) - &&get.attitude(player,current)<0&&!current.hasShan() - &&get.effect(current,{name:'sha',nature:'fire'},player,player)>0; - }); + audioname: ["re_chengpu"], + check: function (event, player) { + return ( + (event.baseDamage > 1 || player.getHistory("useCard").indexOf(event) == 0) && + (player.hp > 1 || player.getExpansions("rechunlao").length) && + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + player.canUse(event.card, current) && + get.attitude(player, current) < 0 && + !current.hasShan() && + get.effect(current, { name: "sha", nature: "fire" }, player, player) > 0 + ); + }) + ); }, - content:function(){ - game.setNature(trigger.card,'fire'); - trigger.lihuo_changed=true; + content: function () { + game.setNature(trigger.card, "fire"); + trigger.lihuo_changed = true; }, - group:['ollihuo2','ollihuo3','ollihuo4'], - ai:{ - fireAttack:true, + group: ["ollihuo2", "ollihuo3", "ollihuo4"], + ai: { + fireAttack: true, }, }, - ollihuo2:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha'||!game.hasNature(event.card,'fire')) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); + ollihuo2: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('ollihuo'),'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&lib.filter.targetInRange(_status.event.card,player,target)&&lib.filter.targetEnabled(_status.event.card,player,target); - }).set('sourcex',trigger.targets).set('card',trigger.card).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!_status.connectMode) game.delayx(); - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("ollihuo"), + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + lib.filter.targetInRange(_status.event.card, player, target) && + lib.filter.targetEnabled(_status.event.card, player, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("card", trigger.card) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !_status.connectMode) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - player.logSkill('ollihuo',event.target); + "step 2"; + player.logSkill("ollihuo", event.target); trigger.targets.push(event.target); }, }, - ollihuo3:{ - trigger:{player:'useCardEnd'}, - filter:function(event,player){ - return event.lihuo_changed==true&&player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length>0; + ollihuo3: { + trigger: { player: "useCardEnd" }, + filter: function (event, player) { + return ( + event.lihuo_changed == true && + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length > 0 + ); }, - forced:true, - audio:'lihuo', - audioname:['re_chengpu'], - content:function(){ + forced: true, + audio: "lihuo", + audioname: ["re_chengpu"], + content: function () { player.loseHp(); - } - }, - ollihuo4:{ - trigger:{player:'useCardAfter'}, - frequent:true, - audio:'lihuo', - audioname:['re_chengpu'], - filter:function(event,player){ - return event.card.name=='sha'&&player.getHistory('useCard').indexOf(event)==0&&event.cards.filterInD().length>0; - }, - content:function(){ - var cards=trigger.cards.filterInD(); - player.addToExpansion('gain2',cards).gaintag.add('rechunlao'); }, }, - rezhongyong:{ - trigger:{player:'useCardAfter'}, - audio:2, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'; + ollihuo4: { + trigger: { player: "useCardAfter" }, + frequent: true, + audio: "lihuo", + audioname: ["re_chengpu"], + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.getHistory("useCard").indexOf(event) == 0 && + event.cards.filterInD().length > 0 + ); }, - content:function(){ - "step 0" - event.cards=trigger.cards.filterInD(); - game.countPlayer2(function(current){ - current.getHistory('useCard',function(evt){ - if(evt.card.name=='shan'&&evt.getParent(3)==trigger) event.cards.addArray(evt.cards.filterInD('od')); + content: function () { + var cards = trigger.cards.filterInD(); + player.addToExpansion("gain2", cards).gaintag.add("rechunlao"); + }, + }, + rezhongyong: { + trigger: { player: "useCardAfter" }, + audio: 2, + direct: true, + filter: function (event, player) { + return event.card.name == "sha"; + }, + content: function () { + "step 0"; + event.cards = trigger.cards.filterInD(); + game.countPlayer2(function (current) { + current.getHistory("useCard", function (evt) { + if (evt.card.name == "shan" && evt.getParent(3) == trigger) + event.cards.addArray(evt.cards.filterInD("od")); }); }); - if(!event.cards.length) event.finish(); - player.chooseTarget(get.prompt2('rezhongyong'),'令一名其他角色获得'+get.translation(event.cards),function(card,player,target){ - return !_status.event.source.includes(target)&&target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('source',trigger.targets); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('rezhongyong',target); - target.gain(cards,'gain2'); - var red=false,black=false; - for(var i of cards){ - var color=get.color(i,false); - if(color=='red') red=true; - if(color=='black') black=true; - if(red&&black) break; + if (!event.cards.length) event.finish(); + player + .chooseTarget( + get.prompt2("rezhongyong"), + "令一名其他角色获得" + get.translation(event.cards), + function (card, player, target) { + return !_status.event.source.includes(target) && target != player; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("source", trigger.targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("rezhongyong", target); + target.gain(cards, "gain2"); + var red = false, + black = false; + for (var i of cards) { + var color = get.color(i, false); + if (color == "red") red = true; + if (color == "black") black = true; + if (red && black) break; } - if(red) target.chooseToUse('是否使用一张杀?',{name:'sha'}).set('filterTarget',function(card,player,target){ - return target!=_status.event.sourcex&&_status.event.sourcex.inRange(target)&&lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',player).set('addCount',false); - if(black) target.draw(); + if (red) + target + .chooseToUse("是否使用一张杀?", { name: "sha" }) + .set("filterTarget", function (card, player, target) { + return ( + target != _status.event.sourcex && + _status.event.sourcex.inRange(target) && + lib.filter.targetEnabled.apply(this, arguments) + ); + }) + .set("sourcex", player) + .set("addCount", false); + if (black) target.draw(); } - } + }, }, //长标 - changbiao:{ - audio:2, - mod:{ - targetInRange:function(card,player,target){ - if(card.changbiao) return true; + changbiao: { + audio: 2, + mod: { + targetInRange: function (card, player, target) { + if (card.changbiao) return true; }, }, - enable:'phaseUse', - usable:1, - viewAs:{ - name:'sha', - changbiao:true, + enable: "phaseUse", + usable: 1, + viewAs: { + name: "sha", + changbiao: true, }, - locked:false, - filter:function(event,player){ - return player.countCards('hs')>0; + locked: false, + filter: function (event, player) { + return player.countCards("hs") > 0; }, - filterCard:true, - selectCard:[1,Infinity], - position:'hs', - check:function(card){ + filterCard: true, + selectCard: [1, Infinity], + position: "hs", + check: function (card) { 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); - }); + 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; let target = list[0], cards = ui.selected.cards.concat([card]), @@ -6512,4226 +7919,5159 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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(0,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 6 - get.value(card, 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(0, (i, player) => { + return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); + }) + ) + return 6 - get.value(card, player); return 0; } return 6.3 - get.value(card); }, - onuse:function(result,player){ - player.addTempSkill('changbiao_draw'); + onuse: function (result, player) { + player.addTempSkill("changbiao_draw"); }, - subSkill:{ - draw:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getHistory('sourceDamage',function(evxt){ - var evt=evxt.getParent(); - return evt&&evt.name=='sha'&&evt.skill=='changbiao'&&evt.getParent('phaseUse')==event; - }).length>0; + subSkill: { + draw: { + trigger: { player: "phaseUseEnd" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + player.getHistory("sourceDamage", function (evxt) { + var evt = evxt.getParent(); + return ( + evt && + evt.name == "sha" && + evt.skill == "changbiao" && + evt.getParent("phaseUse") == event + ); + }).length > 0 + ); }, - content:function(){ - var num=0; - player.getHistory('sourceDamage',function(evxt){ - var evt=evxt.getParent(); - if(evt&&evt.name=='sha'&&evt.skill=='changbiao'&&evt.getParent('phaseUse')==trigger) num+=evt.cards.length; + content: function () { + var num = 0; + player.getHistory("sourceDamage", function (evxt) { + var evt = evxt.getParent(); + if ( + evt && + evt.name == "sha" && + evt.skill == "changbiao" && + evt.getParent("phaseUse") == trigger + ) + num += evt.cards.length; }); player.draw(num); }, }, }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'},player)+0.3*(Math.min(player.getCardUsable('sha'),player.countCards('hs','sha')+player.hasCard(function(card){ - return card.name!='sha'&&get.value(card,player)<6.3; - },'hs')?1:0)>1?-1:1); + ai: { + order: function (item, player) { + return ( + get.order({ name: "sha" }, player) + + 0.3 * + (Math.min( + player.getCardUsable("sha"), + player.countCards("hs", "sha") + + player.hasCard(function (card) { + 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; + 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; + return player.needsToDiscard(num) > 0; } - } + }, }, }, //国钟会 - gzquanji:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + gzquanji: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - frequent:true, - preHidden:true, - filter:function(event,player,name){ + frequent: true, + preHidden: true, + filter: function (event, player, name) { //if(name=='damageEnd') return true; //if(!event.card) return false; - if(player.hasHistory('useSkill',function(evt){ - return evt.skill=='gzquanji'&&evt.event.triggername==name; - })) return false; + if ( + player.hasHistory("useSkill", function (evt) { + return evt.skill == "gzquanji" && evt.event.triggername == name; + }) + ) + return false; return true; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - var hs=player.getCards('he'); - if(hs.length>0){ - if(hs.length==1) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择一张牌作为“权”'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var cs=result.cards; - player.addToExpansion(cs,player,'give').gaintag.add('gzquanji'); + "step 1"; + var hs = player.getCards("he"); + if (hs.length > 0) { + if (hs.length == 1) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", true, "选择一张牌作为“权”"); + } else event.finish(); + "step 2"; + if (result.bool) { + var cs = result.cards; + player.addToExpansion(cs, player, "give").gaintag.add("gzquanji"); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - locked:false, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('gzquanji').length; + locked: false, + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("gzquanji").length; }, }, }, - gzpaiyi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.getExpansions('gzquanji').length>0; + gzpaiyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.getExpansions("gzquanji").length > 0; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('排异',player.getExpansions('gzquanji'),'hidden') + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("排异", player.getExpansions("gzquanji"), "hidden"); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'gzpaiyi', - filterTarget:true, - filterCard:function(){return false}, - selectCard:-1, - card:links[0], - delay:false, - content:lib.skill.gzpaiyi.contentx, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(target!=player) return 0; - if(player.getExpansions('gzquanji').length<=1||(player.needsToDiscard()&&!player.getEquip('zhuge')&&!player.hasSkill('new_paoxiao'))) return 0; + audio: "gzpaiyi", + filterTarget: true, + filterCard: function () { + return false; + }, + selectCard: -1, + card: links[0], + delay: false, + content: lib.skill.gzpaiyi.contentx, + ai: { + order: 10, + result: { + target: function (player, target) { + if (target != player) return 0; + if ( + player.getExpansions("gzquanji").length <= 1 || + (player.needsToDiscard() && + !player.getEquip("zhuge") && + !player.hasSkill("new_paoxiao")) + ) + return 0; return 1; - } + }, }, }, - } + }; + }, + prompt: function () { + return "请选择【排异】的目标"; }, - prompt:function(){return '请选择【排异】的目标'}, }, - contentx:function(){ - "step 0" - var card=lib.skill.gzpaiyi_backup.card; + contentx: function () { + "step 0"; + var card = lib.skill.gzpaiyi_backup.card; player.loseToDiscardpile(card); - "step 1" - var num=player.getExpansions('gzquanji').length; - if(num>0) target.draw(Math.min(7,num)); - "step 2" - if(target.countCards('h')>player.countCards('h')){ + "step 1"; + var num = player.getExpansions("gzquanji").length; + if (num > 0) target.draw(Math.min(7, num)); + "step 2"; + if (target.countCards("h") > player.countCards("h")) { target.damage(); } }, - ai:{ - order:function(item,player){ - var num=player.getExpansions('gzquanji').length; - if(num==1) return 8; + ai: { + order: function (item, player) { + var num = player.getExpansions("gzquanji").length; + if (num == 1) return 8; return 1; }, - result:{ - player:1, + result: { + player: 1, }, }, }, - gzquanji2:{charlotte:true}, - xingongji:{ - enable:'phaseUse', - usable:1, - audio:2, - position:'he', - filterCard:true, - filter:function(event,player){ - return player.countCards('he')>0; + gzquanji2: { charlotte: true }, + xingongji: { + enable: "phaseUse", + usable: 1, + audio: 2, + position: "he", + filterCard: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - check:function(card){ - var base=0,player=_status.event.player,suit=get.suit(card,player),added=false,added2=false,added3; - if(get.type(card)=='equip'&&game.hasPlayer(function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - })) base+=6; - var hs=player.getCards('h'); - var muniu=player.getEquip('muniu'); - if(muniu&&card!=muniu&&muniu.cards) hs=hs.concat(muniu.cards); - for(var i of hs){ - if(i!=card&&get.name(i)=='sha'){ - if(get.suit(i,player)==suit){ - if(player.hasValueTarget(i,false)){ - added3=true; - base+=5.5; + check: function (card) { + var base = 0, + player = _status.event.player, + suit = get.suit(card, player), + added = false, + added2 = false, + added3; + if ( + get.type(card) == "equip" && + game.hasPlayer(function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + }) + ) + base += 6; + var hs = player.getCards("h"); + var muniu = player.getEquip("muniu"); + if (muniu && card != muniu && muniu.cards) hs = hs.concat(muniu.cards); + for (var i of hs) { + if (i != card && get.name(i) == "sha") { + if (get.suit(i, player) == suit) { + if (player.hasValueTarget(i, false)) { + added3 = true; + base += 5.5; } - } - else{ - if(player.hasValueTarget(i,false)) added2=true; - if(!added&&!player.hasValueTarget(i,null,true)&&player.hasValueTarget(i,false,true)){ - base+=4; - added=true; + } else { + if (player.hasValueTarget(i, false)) added2 = true; + if ( + !added && + !player.hasValueTarget(i, null, true) && + player.hasValueTarget(i, false, true) + ) { + base += 4; + added = true; } } } } - if(added3&&!added2) base-=4.5; - return base-get.value(card); + if (added3 && !added2) base -= 4.5; + return base - get.value(card); }, - content:function(){ - "step 0" - if(!player.storage.xingongji2) player.storage.xingongji2=[]; - player.storage.xingongji2.add(get.suit(cards[0],player)); - player.addTempSkill('xingongji2'); - "step 1" - if(get.type(cards[0],null,cards[0].original=='h'?player:false)=='equip'){ - player.chooseTarget('是否弃置一名角色的一张牌?',function(card,player,target){ - return player!=target&&target.countCards('he')>0; - }).set('ai',function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - return -att*0.8; - }); - } - else{ + content: function () { + "step 0"; + if (!player.storage.xingongji2) player.storage.xingongji2 = []; + player.storage.xingongji2.add(get.suit(cards[0], player)); + player.addTempSkill("xingongji2"); + "step 1"; + if (get.type(cards[0], null, cards[0].original == "h" ? player : false) == "equip") { + player + .chooseTarget("是否弃置一名角色的一张牌?", function (card, player, target) { + return player != target && target.countCards("he") > 0; + }) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + return -att * 0.8; + }); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.line(result.targets,'green'); - player.discardPlayerCard(result.targets[0],'he',true); + "step 2"; + if (result.bool) { + player.line(result.targets, "green"); + player.discardPlayerCard(result.targets[0], "he", true); } }, - ai:{ - order:4.5, - result:{ - player:1 - } - } + ai: { + order: 4.5, + result: { + player: 1, + }, + }, }, - xingongji2:{ - charlotte:true, - onremove:true, - mod:{ - attackRangeBase:function(){ + xingongji2: { + charlotte: true, + onremove: true, + mod: { + attackRangeBase: function () { return Infinity; }, - cardUsable:function(card,player){ - if(card.name=='sha'){ + cardUsable: function (card, player) { + if (card.name == "sha") { const suit = get.suit(card); - return suit === 'unsure' || player.storage.xingongji2.includes(suit); + return suit === "unsure" || player.storage.xingongji2.includes(suit); } }, - aiOrder:function(player,card,num){ - if(get.name(card)=='sha'&&!player.storage.xingongji2.includes(get.suit(card))) return num+1; + aiOrder: function (player, card, num) { + if (get.name(card) == "sha" && !player.storage.xingongji2.includes(get.suit(card))) + return num + 1; }, }, - mark:true, - intro:{ - content:'使用$花色的杀无次数限制', + mark: true, + intro: { + content: "使用$花色的杀无次数限制", }, }, - xinjiefan:{ - skillAnimation:true, - animationColor:'wood', - audio:2, - unique:true, - limited:true, - enable:'phaseUse', - filterTarget:true, - content:function(){ - "step 0" - player.awakenSkill('xinjiefan'); - event.players=game.filterPlayer(function(current){ - return current!=target&¤t.inRange(target); + xinjiefan: { + skillAnimation: true, + animationColor: "wood", + audio: 2, + unique: true, + limited: true, + enable: "phaseUse", + filterTarget: true, + content: function () { + "step 0"; + player.awakenSkill("xinjiefan"); + event.players = game.filterPlayer(function (current) { + return current != target && current.inRange(target); }); event.players.sortBySeat(); - "step 1" - if(event.players.length){ - event.current=event.players.shift(); - event.current.addTempClass('target'); - player.line(event.current,'green'); - if(event.current.countCards('he')&&target.isIn()){ - event.current.chooseToDiscard({subtype:'equip1'},'he','弃置一张武器牌或让'+ - get.translation(target)+'摸一张牌').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.target)<0) return 7-get.value(card); - return -1; - }).set('target',target); - event.tempbool=false; + "step 1"; + if (event.players.length) { + event.current = event.players.shift(); + event.current.addTempClass("target"); + player.line(event.current, "green"); + if (event.current.countCards("he") && target.isIn()) { + event.current + .chooseToDiscard( + { subtype: "equip1" }, + "he", + "弃置一张武器牌或让" + get.translation(target) + "摸一张牌" + ) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.target) < 0) + return 7 - get.value(card); + return -1; + }) + .set("target", target); + event.tempbool = false; + } else { + event.tempbool = true; } - else{ - event.tempbool=true; - } - } - else{ - if(game.roundNumber<=1) player.addTempSkill('xinjiefan2'); + } else { + if (game.roundNumber <= 1) player.addTempSkill("xinjiefan2"); event.finish(); } - "step 2" - if(event.tempbool||result.bool==false){ + "step 2"; + if (event.tempbool || result.bool == false) { target.draw(); } event.goto(1); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(player.hp>2&&game.roundNumber>1){ - if(game.phaseNumber 2 && game.roundNumber > 1) { + if (game.phaseNumber < game.players.length * 2) return 0; } - var num=0,players=game.filterPlayer(); - for(var i=0;i0; + xinjiefan2: { + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + content: function () { + player.restoreSkill("xinjiefan"); }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('residi'),'将一张非基本牌置于武将牌上作为“司”',function(card,player){ - return get.type(card)!='basic'; - }).set('ai',function(card){ - if(get.position(card)=='e') return 5+player.hp-get.value(card); - return 7-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('residi'); - player.addToExpansion(result.cards,'give',player).gaintag.add('residi'); - } - }, - intro:{ - content:'expansion', - markcount:'expansion', - }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - }, - group:'residi_push', - ai:{notemp:true}, }, - residi_push:{ - trigger:{global:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&player.getExpansions('residi').length>0; + residi: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + if (_status.connectMode) return true; + return get.type(card) != "basic"; + }) > 0 + ); }, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('residi',trigger.player),player.getExpansions('residi')]).set('ai',function(button){ - var player=_status.event.player; - var target=_status.event.getTrigger().player; - if(get.attitude(player,target)>-1) return 0; - var card=button.link; - var color=get.color(button.link,false); - var eff=target.countCards('h',function(card){ - return get.color(card,target)==color&&target.hasValueTarget(card); + content: function () { + "step 0"; + player + .chooseCard( + "he", + get.prompt("residi"), + "将一张非基本牌置于武将牌上作为“司”", + function (card, player) { + return get.type(card) != "basic"; + } + ) + .set("ai", function (card) { + if (get.position(card) == "e") return 5 + player.hp - get.value(card); + return 7 - get.value(card); }); - if(!target.countCards('h',function(card){ - return get.color(card,target)==color&&get.name(card,target)=='sha'&&target.hasValueTarget(card); - })) eff+=1.5; - if(!target.countCards('h',function(card){ - return get.color(card,target)==color&&get.type2(card,target)=='trick'&&target.hasValueTarget(card); - })) eff+=1.5; - return eff-1; - }); - 'step 1' - if(result.bool){ - if(!trigger.residi) trigger.residi=[]; + "step 1"; + if (result.bool) { + player.logSkill("residi"); + player.addToExpansion(result.cards, "give", player).gaintag.add("residi"); + } + }, + intro: { + content: "expansion", + markcount: "expansion", + }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + group: "residi_push", + ai: { notemp: true }, + }, + residi_push: { + trigger: { global: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return event.player != player && player.getExpansions("residi").length > 0; + }, + content: function () { + "step 0"; + player + .chooseButton([get.prompt("residi", trigger.player), player.getExpansions("residi")]) + .set("ai", function (button) { + var player = _status.event.player; + var target = _status.event.getTrigger().player; + if (get.attitude(player, target) > -1) return 0; + var card = button.link; + var color = get.color(button.link, false); + var eff = target.countCards("h", function (card) { + return get.color(card, target) == color && target.hasValueTarget(card); + }); + if ( + !target.countCards("h", function (card) { + return ( + get.color(card, target) == color && + get.name(card, target) == "sha" && + target.hasValueTarget(card) + ); + }) + ) + eff += 1.5; + if ( + !target.countCards("h", function (card) { + return ( + get.color(card, target) == color && + get.type2(card, target) == "trick" && + target.hasValueTarget(card) + ); + }) + ) + eff += 1.5; + return eff - 1; + }); + "step 1"; + if (result.bool) { + if (!trigger.residi) trigger.residi = []; trigger.residi.push(player); - var card=result.links[0]; - var target=trigger.player; - player.logSkill('residi',target); + var card = result.links[0]; + var target = trigger.player; + player.logSkill("residi", target); player.loseToDiscardpile(card); - var color=get.color(card,false); - if(!target.storage.residi2) target.storage.residi2=[]; + var color = get.color(card, false); + if (!target.storage.residi2) target.storage.residi2 = []; target.storage.residi2.add(color); - target.addTempSkill('residi2','phaseUseAfter'); - target.markSkill('residi2'); - player.addTempSkill('residi3','phaseUseAfter'); + target.addTempSkill("residi2", "phaseUseAfter"); + target.markSkill("residi2"); + player.addTempSkill("residi3", "phaseUseAfter"); } }, }, - residi2:{ - onremove:true, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('residi2').includes(get.color(card,player))) return false; + residi2: { + onremove: true, + mod: { + cardEnabled: function (card, player) { + if (player.getStorage("residi2").includes(get.color(card, player))) return false; }, - cardRespondable:function(card,player){ - if(player.getStorage('residi2').includes(get.color(card,player))) return false; + cardRespondable: function (card, player) { + if (player.getStorage("residi2").includes(get.color(card, player))) return false; }, - cardSavable:function(card,player){ - if(player.getStorage('residi2').includes(get.color(card,player))) return false; + cardSavable: function (card, player) { + if (player.getStorage("residi2").includes(get.color(card, player))) return false; }, }, - intro:{ - content:'不能使用或打出$牌', + intro: { + content: "不能使用或打出$牌", }, - marktext:'敌', + marktext: "敌", }, - residi3:{ - audio:'residi', - trigger:{global:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - if(!event.residi||!event.residi.includes(player)) return false; - var sha=(player.canUse('sha',event.player,false)),trick=true; - event.player.getHistory('useCard',function(evt){ - if(evt.getParent('phaseUse')!=event) return false; - if(sha&&evt.card.name=='sha') sha=false; - if(trick&&get.type2(evt.card,false)=='trick') trick=false; + residi3: { + audio: "residi", + trigger: { global: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + if (!event.residi || !event.residi.includes(player)) return false; + var sha = player.canUse("sha", event.player, false), + trick = true; + event.player.getHistory("useCard", function (evt) { + if (evt.getParent("phaseUse") != event) return false; + if (sha && evt.card.name == "sha") sha = false; + if (trick && get.type2(evt.card, false) == "trick") trick = false; }); - return sha||trick; + return sha || trick; }, - content:function(){ - var sha=(player.canUse('sha',trigger.player,false)),trick=true; - trigger.player.getHistory('useCard',function(evt){ - if(evt.getParent('phaseUse')!=trigger) return false; - if(sha&&evt.card.name=='sha') sha=false; - if(trick&&get.type2(evt.card,false)=='trick') trick=false; + content: function () { + var sha = player.canUse("sha", trigger.player, false), + trick = true; + trigger.player.getHistory("useCard", function (evt) { + if (evt.getParent("phaseUse") != trigger) return false; + if (sha && evt.card.name == "sha") sha = false; + if (trick && get.type2(evt.card, false) == "trick") trick = false; }); - if(sha) player.useCard({name:'sha',isCard:true},trigger.player); - if(trick) player.draw(2); + if (sha) player.useCard({ name: "sha", isCard: true }, trigger.player); + if (trick) player.draw(2); }, }, - rehuaiyi:{ - audio:2, - enable:'phaseUse', - usable:2, - delay:false, - filter:function(event,player){ - return player.countCards('h')>0&&(!player.getStat('skill').rehuaiyi||player.hasSkill('rehuaiyi2')); + rehuaiyi: { + audio: 2, + enable: "phaseUse", + usable: 2, + delay: false, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + (!player.getStat("skill").rehuaiyi || player.hasSkill("rehuaiyi2")) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - if(get.color(player.getCards('h'))!='none'){ + if (get.color(player.getCards("h")) != "none") { player.draw(); - player.addTempSkill('rehuaiyi2','phaseUseEnd'); + player.addTempSkill("rehuaiyi2", "phaseUseEnd"); event.finish(); } - 'step 1' - player.chooseControl('红色','黑色').set('ai',function(){ - var player=_status.event.player; - if(player.countCards('h',{color:'red'})==1&& - player.countCards('h',{color:'black'})>1) return '红色'; - return '黑色'; + "step 1"; + player.chooseControl("红色", "黑色").set("ai", function () { + var player = _status.event.player; + if ( + player.countCards("h", { color: "red" }) == 1 && + player.countCards("h", { color: "black" }) > 1 + ) + return "红色"; + return "黑色"; }); - 'step 2' - event.control=result.control; + "step 2"; + event.control = result.control; var cards; - if(event.control=='红色'){ - cards=player.getCards('h',{color:'red'}); - } - else{ - cards=player.getCards('h',{color:'black'}); + if (event.control == "红色") { + cards = player.getCards("h", { color: "red" }); + } else { + cards = player.getCards("h", { color: "black" }); } player.discard(cards); - event.num=cards.length; - 'step 3' - player.chooseTarget('请选择至多'+get.cnNumber(event.num)+'名有牌的其他角色,获得这些角色的各一张牌。',[1,event.num],function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)+0.5; - }); - 'step 4' - if(result.bool&&result.targets){ - player.line(result.targets,'green'); - event.targets=result.targets; + event.num = cards.length; + "step 3"; + player + .chooseTarget( + "请选择至多" + + get.cnNumber(event.num) + + "名有牌的其他角色,获得这些角色的各一张牌。", + [1, event.num], + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) + 0.5; + }); + "step 4"; + if (result.bool && result.targets) { + player.line(result.targets, "green"); + event.targets = result.targets; event.targets.sort(lib.sort.seat); - event.gained=0; - } - else{ + event.gained = 0; + } else { event.finish(); } - 'step 5' - if(player.isIn()&&event.targets.length){ - player.gainPlayerCard(event.targets.shift(),'he',true); + "step 5"; + if (player.isIn() && event.targets.length) { + player.gainPlayerCard(event.targets.shift(), "he", true); + } else event.finish(); + "step 6"; + if (result.bool) { + event.gained += result.cards.length; } - else event.finish(); - 'step 6' - if(result.bool){ - event.gained+=result.cards.length; - } - if(event.targets.length) event.goto(5); - 'step 7' - if(event.gained>1) player.loseHp(); + if (event.targets.length) event.goto(5); + "step 7"; + if (event.gained > 1) player.loseHp(); }, - ai:{ - order:function(item,player){ - if(player.countCards('h',{color:'red'})==0) return 10; - if(player.countCards('h',{color:'black'})==0) return 10; + ai: { + order: function (item, player) { + if (player.countCards("h", { color: "red" }) == 0) return 10; + if (player.countCards("h", { color: "black" }) == 0) return 10; return 1; }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, - rehuaiyi2:{}, - rezhuikong:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - check:function(event,player){ - if(get.attitude(player,event.player)<-2){ - var cards=player.getCards('h'); - if(cards.length>player.hp) return true; - for(var i=0;i7&&useful<7) return true; + rehuaiyi2: {}, + rezhuikong: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + check: function (event, player) { + if (get.attitude(player, event.player) < -2) { + var cards = player.getCards("h"); + if (cards.length > player.hp) return true; + for (var i = 0; i < cards.length; i++) { + var useful = get.useful(cards[i]); + if (useful < 5) return true; + if (get.number(cards[i]) > 7 && useful < 7) return true; } } return false; }, - logTarget:'player', - filter:function(event,player){ - return player.hp1&&get.effect(player,{name:'sha'},trigger.player,player)>0&&Math.random()<0.9)); - "step 1" - if(result.bool){ - trigger.player.addTempSkill('zishou2'); + content: function () { + "step 0"; + player + .chooseToCompare(trigger.player) + .set( + "small", + player.hp > 1 && + get.effect(player, { name: "sha" }, trigger.player, player) > 0 && + Math.random() < 0.9 + ); + "step 1"; + if (result.bool) { + trigger.player.addTempSkill("zishou2"); event.finish(); - } - else if(result.target&&get.position(result.target)=='d') player.gain(result.target,'gain2','log'); - "step 2" - var card={name:'sha',isCard:true}; - if(trigger.player.canUse(card,player,false)) trigger.player.useCard(card,player,false); + } else if (result.target && get.position(result.target) == "d") + player.gain(result.target, "gain2", "log"); + "step 2"; + var card = { name: "sha", isCard: true }; + if (trigger.player.canUse(card, player, false)) + trigger.player.useCard(card, player, false); }, }, - reqiuyuan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&game.hasPlayer(function(current){ - return current!=player&&!event.targets.includes(current)&&lib.filter.targetEnabled(event.card,event.player,current); - }); + reqiuyuan: { + audio: 2, + trigger: { target: "useCardToTarget" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + game.hasPlayer(function (current) { + return ( + current != player && + !event.targets.includes(current) && + lib.filter.targetEnabled(event.card, event.player, current) + ); + }) + ); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('reqiuyuan'),function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&!evt.targets.includes(target)&&lib.filter.targetEnabled(evt.card,evt.player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,trigger.player,player)+0.1; - }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('reqiuyuan',target); - event.target=target; - target.chooseCard(function(card,player){ - var name=get.name(card,player); - return name!='sha'&&get.type(name)=='basic'; - },'h','交给'+get.translation(player)+ - '一张不为【杀】的基本牌,或成为此杀的额外目标且不可响应此【杀】').set('ai',function(card){ - return get.attitude(target,_status.event.sourcex)>=0?1:-1; - }).set('sourcex',player); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("reqiuyuan"), function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled(evt.card, evt.player, target) + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, trigger.player, player) + 0.1; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("reqiuyuan", target); + event.target = target; + target + .chooseCard( + function (card, player) { + var name = get.name(card, player); + return name != "sha" && get.type(name) == "basic"; + }, + "h", + "交给" + + get.translation(player) + + "一张不为【杀】的基本牌,或成为此杀的额外目标且不可响应此【杀】" + ) + .set("ai", function (card) { + return get.attitude(target, _status.event.sourcex) >= 0 ? 1 : -1; + }) + .set("sourcex", player); game.delay(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ - target.give(result.cards,player); + "step 2"; + if (result.bool) { + target.give(result.cards, player); game.delay(); - } - else{ + } else { trigger.getParent().targets.push(event.target); trigger.getParent().triggeredTargets2.push(event.target); trigger.directHit.push(event.target); - game.log(event.target,'成为了',trigger.card,'的额外目标'); + game.log(event.target, "成为了", trigger.card, "的额外目标"); } }, - ai:{ - expose:0.2, - effect:{ - target:function(card,player,target){ - if(card.name!='sha') return; - var players=game.filterPlayer(); - if(get.attitude(player,target)<=0){ - for(var i=0;i0&& - get.effect(target2,{name:'shacopy',nature:card.nature,suit:card.suit},player,player)<0){ - if(target.hp==target.maxHp) return 0.3; + ai: { + expose: 0.2, + effect: { + target: function (card, player, target) { + if (card.name != "sha") return; + var players = game.filterPlayer(); + if (get.attitude(player, target) <= 0) { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + target + ) > 0 && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) < 0 + ) { + if (target.hp == target.maxHp) return 0.3; return 0.6; } } - } - else{ - for(var i=0;i0){ - if(player.canUse(card,target2)) return; - if(target.hp==target.maxHp) return [0,1]; - return [0,0]; + } else { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) > 0 + ) { + if (player.canUse(card, target2)) return; + if (target.hp == target.maxHp) return [0, 1]; + return [0, 0]; } } } - } - } - } - }, - reenyuan:{ - audio:2, - group:['reenyuan1','reenyuan2'], - }, - reenyuan1:{ - audio:'reenyuan', - trigger:{player:'gainEnd'}, - filter:function(event,player){ - if(!event.source||event.source==player||!event.source.isIn()||event.cards.length<2) return false; - var evt=event.getl(event.source); - return evt&&evt.cards2&&evt.cards2.length>1; + }, + }, }, - check:function(event,player){ - return get.attitude(player,event.source)>0; + }, + reenyuan: { + audio: 2, + group: ["reenyuan1", "reenyuan2"], + }, + reenyuan1: { + audio: "reenyuan", + trigger: { player: "gainEnd" }, + filter: function (event, player) { + if ( + !event.source || + event.source == player || + !event.source.isIn() || + event.cards.length < 2 + ) + return false; + var evt = event.getl(event.source); + return evt && evt.cards2 && evt.cards2.length > 1; }, - logTarget:'source', - prompt2:'令该角色摸一张牌', - content:function(){ + check: function (event, player) { + return get.attitude(player, event.source) > 0; + }, + logTarget: "source", + prompt2: "令该角色摸一张牌", + content: function () { trigger.source.draw(); }, }, - reenyuan2:{ - audio:'reenyuan', - trigger:{player:'damageEnd'}, - logTarget:'source', - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.isIn(); + reenyuan2: { + audio: "reenyuan", + trigger: { player: "damageEnd" }, + logTarget: "source", + filter: function (event, player) { + return event.source && event.source != player && event.source.isIn(); }, - check:function(event,player){ - var att=get.attitude(player,event.source); - var num=event.source.countCards('h'); - if(att<=0) return true; - if(num>2) return true; - if(num) return att<4; + check: function (event, player) { + var att = get.attitude(player, event.source); + var num = event.source.countCards("h"); + if (att <= 0) return true; + if (num > 2) return true; + if (num) return att < 4; return false; }, - prompt2:'令该角色选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。', - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' - var target=trigger.source; + prompt2: "令该角色选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。", + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + var target = trigger.source; event.count--; - if(!target.countCards('h')) event._result={bool:false}; - else target.chooseCard('h','恩怨:将一张手牌交给'+get.translation(player)+',或失去1点体力').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - if(get.suit(card)!='heart') return 15-get.value(card); - return 11-get.value(card); - } - else{ - var num=12-_status.event.player.hp*2; - if(get.suit(card)!='heart') num-=2; - return num-get.value(card); - } - }); - 'step 2' - var target=trigger.source; - if(result.bool){ - var card=result.cards[0]; - event.card=card; - target.give(card,player); - } - else{ + if (!target.countCards("h")) event._result = { bool: false }; + else + target + .chooseCard( + "h", + "恩怨:将一张手牌交给" + get.translation(player) + ",或失去1点体力" + ) + .set("ai", function (card) { + if ( + get.attitude(_status.event.player, _status.event.getParent().player) > 0 + ) { + if (get.suit(card) != "heart") return 15 - get.value(card); + return 11 - get.value(card); + } else { + var num = 12 - _status.event.player.hp * 2; + if (get.suit(card) != "heart") num -= 2; + return num - get.value(card); + } + }); + "step 2"; + var target = trigger.source; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + target.give(card, player); + } else { target.loseHp(); event.goto(4); } - 'step 3' - if(get.suit(card)!='heart') player.draw(); - 'step 4' - var target=trigger.source; - if(target.isIn()&&event.count>0&&player.hasSkill('reenyuan')) player.chooseBool(get.prompt('reenyuan',target),'令该角色选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。').set('ai',function(){ - var evt=_status.event.getTrigger(); - return lib.skill.reenyuan2.check(evt,evt.player); - }); + "step 3"; + if (get.suit(card) != "heart") player.draw(); + "step 4"; + var target = trigger.source; + if (target.isIn() && event.count > 0 && player.hasSkill("reenyuan")) + player + .chooseBool( + get.prompt("reenyuan", target), + "令该角色选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。" + ) + .set("ai", function () { + var evt = _status.event.getTrigger(); + return lib.skill.reenyuan2.check(evt, evt.player); + }); else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('reenyuan2',trigger.source); + "step 5"; + if (result.bool) { + player.logSkill("reenyuan2", trigger.source); event.goto(1); } }, }, - rexuanhuo:{ - audio:2, - trigger:{player:'phaseDrawEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>1&&game.countPlayer()>2; + rexuanhuo: { + audio: 2, + trigger: { player: "phaseDrawEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 1 && game.countPlayer() > 2; }, - content:function(){ - 'step 0' - var ai2=function(target){ - var player=_status.event.player; - if(get.attitude(player,target)<=0) return 0; - var list=[null,'juedou'].concat(lib.inpile_nature); - if(target.hasSkill('ayato_zenshen')) list.push('kami'); - var num=Math.max.apply(Math,list.map(function(i){ - if(i=='juedou') return target.getUseValue({name:'juedou',isCard:true},false); - var card={name:'sha',nature:i,isCard:true}; - return target.getUseValue(card,false); - })); - if(target.hasSkillTag('nogain')) num/=4; + content: function () { + "step 0"; + var ai2 = function (target) { + var player = _status.event.player; + if (get.attitude(player, target) <= 0) return 0; + var list = [null, "juedou"].concat(lib.inpile_nature); + if (target.hasSkill("ayato_zenshen")) list.push("kami"); + var num = Math.max.apply( + Math, + list.map(function (i) { + if (i == "juedou") + return target.getUseValue({ name: "juedou", isCard: true }, false); + var card = { name: "sha", nature: i, isCard: true }; + return target.getUseValue(card, false); + }) + ); + if (target.hasSkillTag("nogain")) num /= 4; return num; }; player.chooseCardTarget({ - prompt:get.prompt2('rexuanhuo'), - filterCard:true, - selectCard:2, - position:'h', - filterTarget:lib.filter.notMe, - goon:game.hasPlayer(function(current){ - return current!=player&&ai2(player,current)>0; + prompt: get.prompt2("rexuanhuo"), + filterCard: true, + selectCard: 2, + position: "h", + filterTarget: lib.filter.notMe, + goon: game.hasPlayer(function (current) { + return current != player && ai2(player, current) > 0; }), - ai1:function(card){ - if(!_status.event.goon) return 0; - return 7-get.value(card); + ai1: function (card) { + if (!_status.event.goon) return 0; + return 7 - get.value(card); }, - ai2:ai2, + ai2: ai2, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('rexuanhuo',target); - player.give(result.cards,target); - } + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("rexuanhuo", target); + player.give(result.cards, target); + } else event.finish(); + "step 2"; + if ( + game.hasPlayer(function (current) { + return current != player && current != target; + }) + ) + player + .chooseTarget( + function (card, player, target) { + return target != player && target != _status.event.target; + }, + "选择" + get.translation(target) + "使用【杀】或【决斗】的目标", + true + ) + .set("target", target) + .set("ai", function (target) { + var evt = _status.event; + var list = [null, "juedou"].concat(lib.inpile_nature); + if (evt.target.hasSkill("ayato_zenshen")) list.push("kami"); + return Math.max.apply( + Math, + list.map(function (i) { + var card = { name: "sha", isCard: true }; + if (i == "juedou") card.name = "juedou"; + else if (i) card.nature = i; + if (!evt.target.canUse(card, target, false)) return 0; + return get.effect(target, card, evt.target, evt.player); + }) + ); + }); else event.finish(); - 'step 2' - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target; - })) player.chooseTarget(function(card,player,target){ - return target!=player&&target!=_status.event.target; - },'选择'+get.translation(target)+'使用【杀】或【决斗】的目标',true).set('target',target).set('ai',function(target){ - var evt=_status.event; - var list=[null,'juedou'].concat(lib.inpile_nature); - if(evt.target.hasSkill('ayato_zenshen')) list.push('kami') - return Math.max.apply(Math,list.map(function(i){ - var card={name:'sha',isCard:true}; - if(i=='juedou') card.name='juedou'; - else if(i) card.nature=i; - if(!evt.target.canUse(card,target,false)) return 0; - return get.effect(target,card,evt.target,evt.player); - })); - }); - else event.finish(); - 'step 3' - var target2=result.targets[0]; - event.target2=target2; + "step 3"; + var target2 = result.targets[0]; + event.target2 = target2; player.line(target2); - game.log(player,'选择了',target2); - var list=lib.inpile_nature.slice(0); + game.log(player, "选择了", target2); + var list = lib.inpile_nature.slice(0); list.unshift(null); - var vcards=[]; - if(target.hasSkill('ayato_zenshen')) list.add('kami'); - for(var i of list){ - if(target.canUse({name:'sha',isCard:true,nature:i},target2,false)) vcards.push(['基本','','sha',i]); + var vcards = []; + if (target.hasSkill("ayato_zenshen")) list.add("kami"); + for (var i of list) { + if (target.canUse({ name: "sha", isCard: true, nature: i }, target2, false)) + vcards.push(["基本", "", "sha", i]); } - if(target.canUse({name:'juedou',isCard:true},target2,false)) vcards.push(['基本','','juedou']); - if(!vcards.length){ - if(!target.countCards('h')) event.finish(); - else event._result={index:1}; + if (target.canUse({ name: "juedou", isCard: true }, target2, false)) + vcards.push(["基本", "", "juedou"]); + if (!vcards.length) { + if (!target.countCards("h")) event.finish(); + else event._result = { index: 1 }; + } else if (!target.countCards("h")) { + event.vcards = vcards; + event._result = { index: 0 }; + } else { + event.vcards = vcards; + target + .chooseControl() + .set("choiceList", [ + "视为对" + get.translation(target2) + "使用任意一种【杀】或【决斗】", + "将所有手牌交给" + get.translation(player), + ]); } - else if(!target.countCards('h')){ - event.vcards=vcards; - event._result={index:0}; - } - else{ - event.vcards=vcards; - target.chooseControl().set('choiceList',[ - '视为对'+get.translation(target2)+'使用任意一种【杀】或【决斗】', - '将所有手牌交给'+get.translation(player), - ]); - } - 'step 4' - if(result.index==0){ - if(event.vcards.length==1) event._result={links:event.vcards,bool:true}; - else target.chooseButton(['请选择要对'+get.translation(event.target2)+'使用的牌',[event.vcards,'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - return get.effect(_status.event.getParent().target2,{name:button.link[2],isCard:true,nature:button.link[3]},player,player); - }); - } - else{ - target.give(target.getCards('h'),player,'giveAuto'); + "step 4"; + if (result.index == 0) { + if (event.vcards.length == 1) event._result = { links: event.vcards, bool: true }; + else + target + .chooseButton( + [ + "请选择要对" + get.translation(event.target2) + "使用的牌", + [event.vcards, "vcard"], + ], + true + ) + .set("ai", function (button) { + var player = _status.event.player; + return get.effect( + _status.event.getParent().target2, + { name: button.link[2], isCard: true, nature: button.link[3] }, + player, + player + ); + }); + } else { + target.give(target.getCards("h"), player, "giveAuto"); event.finish(); } - 'step 5' - if(result.bool) target.useCard({name:result.links[0][2],isCard:true,nature:result.links[0][3]},false,event.target2); + "step 5"; + if (result.bool) + target.useCard( + { name: result.links[0][2], isCard: true, nature: result.links[0][3] }, + false, + event.target2 + ); }, - ai:{ - expose:0.17, - fireAttack:true, - skillTagFilter:function(player){ + ai: { + expose: 0.17, + fireAttack: true, + skillTagFilter: function (player) { return player.hasFriend(); }, }, }, - decadezongshi:{ - audio:2, - mod:{ - maxHandcard:function(player,num){ - return num+game.countGroup(); + decadezongshi: { + audio: 2, + mod: { + maxHandcard: function (player, num) { + return num + game.countGroup(); }, }, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return player!=_status.currentPhase&&player.countCards('h')>=player.getHandcardLimit()&& - (get.type(event.card)=='delay'||get.color(event.card)=='none'); + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + return ( + player != _status.currentPhase && + player.countCards("h") >= player.getHandcardLimit() && + (get.type(event.card) == "delay" || get.color(event.card) == "none") + ); }, - content:function(){ + content: function () { trigger.excluded.add(player); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target!=_status.currentPhase&&target.countCards('h')>=target.getHandcardLimit()&& - (get.type(card)=='delay'||get.color(card)=='none')) return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target) { + if ( + target != _status.currentPhase && + target.countCards("h") >= target.getHandcardLimit() && + (get.type(card) == "delay" || get.color(card) == "none") + ) + return "zerotarget"; }, }, }, }, - decadezishou:{ - audio:2, - inherit:'rezishou', - group:'decadezishou_zhiheng', - ai:{ - threaten:1.8, + decadezishou: { + audio: 2, + inherit: "rezishou", + group: "decadezishou_zhiheng", + ai: { + threaten: 1.8, }, }, - decadezishou_zhiheng:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0&&!player.getHistory('useCard',function(evt){ - return evt.targets.filter(function(target){ - return target!=player; - }).length>0; - }).length; + decadezishou_zhiheng: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.getHistory("useCard", function (evt) { + return ( + evt.targets.filter(function (target) { + return target != player; + }).length > 0 + ); + }).length + ); }, - content:function(){ - 'step 0' - var list=[]; - var hs=player.getCards('h'); - for(var i of hs){ - list.add(get.suit(i,player)); + content: function () { + "step 0"; + var list = []; + var hs = player.getCards("h"); + for (var i of hs) { + list.add(get.suit(i, player)); } - player.chooseToDiscard('h',get.prompt('decadezishou'),'弃置任意张花色不同的手牌并摸等量的牌',[1,list.length],function(card,player){ - if(ui.selected.cards.length){ - var suit=get.suit(card,player); - for(var i of ui.selected.cards){ - if(get.suit(i,player)==suit) return false; + player + .chooseToDiscard( + "h", + get.prompt("decadezishou"), + "弃置任意张花色不同的手牌并摸等量的牌", + [1, list.length], + function (card, player) { + if (ui.selected.cards.length) { + var suit = get.suit(card, player); + for (var i of ui.selected.cards) { + if (get.suit(i, player) == suit) return false; + } + } + return true; } - } - return true; - }).set('ai',lib.skill.zhiheng.check).set('complexCard',true).logSkill='decadezishou'; - 'step 1' - if(result.bool){ + ) + .set("ai", lib.skill.zhiheng.check) + .set("complexCard", true).logSkill = "decadezishou"; + "step 1"; + if (result.bool) { player.draw(result.cards.length); } }, }, - yongjin:{ - audio:2, - audioname:['xin_lingtong'], - unique:true, - limited:true, - skillAnimation:true, - animationColor:'wood', - enable:'phaseUse', - filter:function(event,player,cards){ - return game.hasPlayer(function(current){ - var es=current.getCards('e',function(card){ - return !cards||!cards.includes(card); + yongjin: { + audio: 2, + audioname: ["xin_lingtong"], + unique: true, + limited: true, + skillAnimation: true, + animationColor: "wood", + enable: "phaseUse", + filter: function (event, player, cards) { + return game.hasPlayer(function (current) { + var es = current.getCards("e", function (card) { + return !cards || !cards.includes(card); }); - for(var i=0;i0; + } else { + return ( + target.countCards("e", function (card) { + return !_status.event.cards.includes(card); + }) > 0 + ); } }); - next.set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - var sgnatt=get.sgn(att); - if(ui.selected.targets.length==0){ - if(target==player&&player.hasSkill('decadexuanfeng')){ - if(player.countCards('e',function(card){ - return !_status.event.cards.includes(card)&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card)&&get.effect(current,card,player,player)<0; - }); - })>0) return 18; + next.set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var sgnatt = get.sgn(att); + if (ui.selected.targets.length == 0) { + if (target == player && player.hasSkill("decadexuanfeng")) { + if ( + player.countCards("e", function (card) { + return ( + !_status.event.cards.includes(card) && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) < 0 + ); + }) + ); + }) > 0 + ) + return 18; return 7; - } - else if(att>0){ - if(target.countCards('e',function(card){ - return get.value(card,target)<0&&!_status.event.cards.includes(card)&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card)&&get.effect(current,card,player,player)<0; - }); - })>0) return 9; - } - else if(att<0){ - if(game.hasPlayer(function(current){ - if(current!=target&&get.attitude(player,current)>0){ - var es=target.getCards('e',function(card){ - return !_status.event.cards.includes(card); - }); - for(var i=0;i0&¤t.canEquip(card)&&get.effect(current,es[i],player,current)>0) return true; + } else if (att > 0) { + if ( + target.countCards("e", function (card) { + return ( + get.value(card, target) < 0 && + !_status.event.cards.includes(card) && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) < 0 + ); + }) + ); + }) > 0 + ) + return 9; + } else if (att < 0) { + if ( + game.hasPlayer(function (current) { + if (current != target && get.attitude(player, current) > 0) { + var es = target.getCards("e", function (card) { + return !_status.event.cards.includes(card); + }); + for (var i = 0; i < es.length; i++) { + if ( + get.value(es[i], target) > 0 && + current.canEquip(card) && + get.effect(current, es[i], player, current) > 0 + ) + return true; + } } - } - })){ + }) + ) { return -att; } } return 0; } - var es=ui.selected.targets[0].getCards('e',function(card){ + var es = ui.selected.targets[0].getCards("e", function (card) { return !_status.event.cards.includes(card); }); var i; - var att2=get.sgn(get.attitude(player,ui.selected.targets[0])); - for(i=0;i0&&get.damageEffect(current,player,player)>0; + var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); + for (i = 0; i < es.length; i++) { + if (ui.selected.targets[0] == player && player.hasSkill("decadexuanfeng")) { + var bool = game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.countDiscardableCards(player, "he") > 0 && + get.damageEffect(current, player, player) > 0 + ); }); - if(bool&&player.countCards('e',function(card){ - return !_status.event.cards.includes(card)&&target.canEquip(card)&&get.effect(target,card,player,player)>0; - })) return 2.5*Math.abs(att); - else if(bool) return 1/Math.max(1,Math.abs(att)); - else return get.damageEffect(target,player,player); + if ( + bool && + player.countCards("e", function (card) { + return ( + !_status.event.cards.includes(card) && + target.canEquip(card) && + get.effect(target, card, player, player) > 0 + ); + }) + ) + return 2.5 * Math.abs(att); + else if (bool) return 1 / Math.max(1, Math.abs(att)); + else return get.damageEffect(target, player, player); } - if(sgnatt!=0&&att2!=0&&sgnatt!=att2&& - get.sgn(get.value(es[i],ui.selected.targets[0]))==-att2&& - get.sgn(get.effect(target,es[i],player,target))==sgnatt&& - target.canEquip(es[i])){ + if ( + sgnatt != 0 && + att2 != 0 && + sgnatt != att2 && + get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && + get.sgn(get.effect(target, es[i], player, target)) == sgnatt && + target.canEquip(es[i]) + ) { return Math.abs(att); } } - if(i==es.length){ + if (i == es.length) { return 0; } - return -att*get.attitude(player,ui.selected.targets[0]); + return -att * get.attitude(player, ui.selected.targets[0]); }); - next.set('multitarget',true); - next.set('cards',cards); - next.set('targetprompt',['被移走','移动目标']); - next.set('prompt','移动场上的一张装备牌'); - 'step 2' - if(result.bool){ - player.line2(result.targets,'green'); - event.targets=result.targets; - } - else{ + next.set("multitarget", true); + next.set("cards", cards); + next.set("targetprompt", ["被移走", "移动目标"]); + next.set("prompt", "移动场上的一张装备牌"); + "step 2"; + if (result.bool) { + player.line2(result.targets, "green"); + event.targets = result.targets; + } else { event.finish(); } - 'step 3' + "step 3"; game.delay(); - 'step 4' - if(targets.length==2){ - player.choosePlayerCard('e',true,function(button){ - var player=_status.event.player; - var targets0=_status.event.targets0; - var targets1=_status.event.targets1; - if(get.attitude(player,targets0)>0&&get.attitude(player,targets1)<0){ - if(get.value(button.link,targets0)<0&&get.effect(targets1,button.link,player,targets1)>0) return 10; - return 0; - } - else{ - return get.value(button.link)*get.effect(targets1,button.link,player,player); - } - },targets[0]).set('nojudge',event.nojudge||false).set('targets0',targets[0]).set('targets1',targets[1]).set('filterButton',function(button){ - if(_status.event.cards.includes(button.link)) return false; - var targets1=_status.event.targets1; - return targets1.canEquip(button.link); - }).set('cards',cards); - } - else{ + "step 4"; + if (targets.length == 2) { + player + .choosePlayerCard( + "e", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if ( + get.attitude(player, targets0) > 0 && + get.attitude(player, targets1) < 0 + ) { + if ( + get.value(button.link, targets0) < 0 && + get.effect(targets1, button.link, player, targets1) > 0 + ) + return 10; + return 0; + } else { + return ( + get.value(button.link) * + get.effect(targets1, button.link, player, player) + ); + } + }, + targets[0] + ) + .set("nojudge", event.nojudge || false) + .set("targets0", targets[0]) + .set("targets1", targets[1]) + .set("filterButton", function (button) { + if (_status.event.cards.includes(button.link)) return false; + var targets1 = _status.event.targets1; + return targets1.canEquip(button.link); + }) + .set("cards", cards); + } else { event.finish(); } - 'step 5' - if(result.bool&&result.links.length){ - var link=result.links[0]; + "step 5"; + if (result.bool && result.links.length) { + var link = result.links[0]; cards.add(link); event.targets[1].equip(link); - event.targets[0].$give(link,event.targets[1]) + event.targets[0].$give(link, event.targets[1]); game.delay(); - } - else event.finish(); - 'step 6' - if(event.count>0) event.goto(1); + } else event.finish(); + "step 6"; + if (event.count > 0) event.goto(1); }, - ai:{ - order:7, - result:{ - player:function(player){ - var num=0; - var friends=game.filterPlayer(function(current){ - return get.attitude(player,current)>=4; + ai: { + order: 7, + result: { + player: function (player) { + var num = 0; + var friends = game.filterPlayer(function (current) { + return get.attitude(player, current) >= 4; }); - var vacancies={ - equip1:0, - equip2:0, - equip3:0, - equip4:0, - equip5:0 + var vacancies = { + equip1: 0, + equip2: 0, + equip3: 0, + equip4: 0, + equip5: 0, }; - for(var i=0;i0&&get.value(es[j])>0){ + for (var i = 0; i < sources.length; i++) { + var es = sources[i].getCards("e"); + for (var j = 0; j < es.length; j++) { + var type = get.subtype(es[j]); + if ( + sources[i] == player || + (vacancies[type] > 0 && get.value(es[j]) > 0) + ) { num++; - if(sources[i]==player&&vacancies[type]&&game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.countDiscardableCards(player,'he')>0&&get.damageEffect(current,player,player)>0; - })) num+=0.5; - if(num>=3){ + if ( + sources[i] == player && + vacancies[type] && + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.countDiscardableCards(player, "he") > 0 && + get.damageEffect(current, player, player) > 0 + ); + }) + ) + num += 0.5; + if (num >= 3) { return 1; } vacancies[type]--; } } } - if(num&&player.hp==1){ + if (num && player.hp == 1) { return 0.5; } return 0; - } - } - } + }, + }, + }, }, - decadexuanfeng:{ - audio:'xuanfeng', - audioname:['boss_lvbu3','re_heqi','xin_lingtong'], - trigger:{ - player:['loseAfter','phaseDiscardEnd'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + decadexuanfeng: { + audio: "xuanfeng", + audioname: ["boss_lvbu3", "re_heqi", "xin_lingtong"], + trigger: { + player: ["loseAfter", "phaseDiscardEnd"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - if(_status.dying.length) return false; - if(event.name=='phaseDiscard'){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt&&evt.type=='discard'&&evt.getParent('phaseDiscard')==event&&evt.hs) cards.addArray(evt.hs); + direct: true, + filter: function (event, player) { + if (_status.dying.length) return false; + if (event.name == "phaseDiscard") { + var cards = []; + player.getHistory("lose", function (evt) { + if ( + evt && + evt.type == "discard" && + evt.getParent("phaseDiscard") == event && + evt.hs + ) + cards.addArray(evt.hs); }); - return cards.length>1; - } - else{ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + return cards.length > 1; + } else { + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; } }, - content:function(){ - "step 0" - event.count=2; - event.targets=[]; - event.logged=false; - "step 1" + content: function () { + "step 0"; + event.count = 2; + event.targets = []; + event.logged = false; + "step 1"; event.count--; - player.chooseTarget(get.prompt('decadexuanfeng'),'弃置一名其他角色的一张牌',function(card,player,target){ - if(player==target) return false; - return target.countDiscardableCards(player,'he'); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 2" - if(result.bool){ - if(!event.logged){ - player.logSkill('decadexuanfeng',result.targets); - event.logged=true; - } - else player.line(result.targets[0],'green'); - targets.add(result.targets[0]); - player.discardPlayerCard(result.targets[0],'he',true); - } - else if(!targets.length) event.finish(); - "step 3" - if(event.count) event.goto(1); - else if(player==_status.currentPhase){ - player.chooseTarget('是否对一名目标角色造成1点伤害',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',targets).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); + player + .chooseTarget( + get.prompt("decadexuanfeng"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countDiscardableCards(player, "he"); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); }); - } - else event.finish(); - "step 4" - if(result.bool){ - player.line(result.targets[0],'thunder'); + "step 2"; + if (result.bool) { + if (!event.logged) { + player.logSkill("decadexuanfeng", result.targets); + event.logged = true; + } else player.line(result.targets[0], "green"); + targets.add(result.targets[0]); + player.discardPlayerCard(result.targets[0], "he", true); + } else if (!targets.length) event.finish(); + "step 3"; + if (event.count) event.goto(1); + else if (player == _status.currentPhase) { + player + .chooseTarget("是否对一名目标角色造成1点伤害", function (card, player, target) { + return _status.event.targets.includes(target); + }) + .set("targets", targets) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + player.line(result.targets[0], "thunder"); result.targets[0].damage(); } }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(player==target&&get.type(card)=='equip'&&player.countCards('hes',function(cardx){ - return card!=cardx&&(!card.cards||!card.cards.includes(cardx))&&(player.hasSkill('yongjin')||get.subtype(card)==get.subtype(cardx))&&(get.position(cardx)=='e'||player.canUse(cardx,player)); - })>0) return; - if(!game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.countDiscardableCards(player,'he')>0&&get.damageEffect(current,player,player)>0; - })) return; - if(typeof card=='object'&&player.isPhaseUsing()&& - player.needsToDiscard()==2&&card.cards&&card.cards.filter(function(i){ - return get.position(i)=='h'; - }).length>0&&!get.tag(card,'draw')&&!get.tag(card,'gain')&&!(get.tag(card,'discard')&&target==player&&player.countCards('e')>0)) return 'zeroplayertarget'; + ai: { + effect: { + player_use: function (card, player, target) { + if ( + player == target && + get.type(card) == "equip" && + player.countCards("hes", function (cardx) { + return ( + card != cardx && + (!card.cards || !card.cards.includes(cardx)) && + (player.hasSkill("yongjin") || + get.subtype(card) == get.subtype(cardx)) && + (get.position(cardx) == "e" || player.canUse(cardx, player)) + ); + }) > 0 + ) + return; + if ( + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.countDiscardableCards(player, "he") > 0 && + get.damageEffect(current, player, player) > 0 + ); + }) + ) + return; + if ( + typeof card == "object" && + player.isPhaseUsing() && + player.needsToDiscard() == 2 && + card.cards && + card.cards.filter(function (i) { + return get.position(i) == "h"; + }).length > 0 && + !get.tag(card, "draw") && + !get.tag(card, "gain") && + !(get.tag(card, "discard") && target == player && player.countCards("e") > 0) + ) + return "zeroplayertarget"; }, - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - if(get.tag(card,'damage')&&target.hp>2){ - var num1=target.countCards('h'),num2=target.getHandcardLimit(); - if(num1>num2) return [1,1]; - if(num1==num2) return [1.1,_status.event.player==target?3:0.5]; - if(num1==num2-1) return [0.1,_status.event.player==target?4.5:0.1]; + target: function (card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; + if (get.tag(card, "damage") && target.hp > 2) { + var num1 = target.countCards("h"), + num2 = target.getHandcardLimit(); + if (num1 > num2) return [1, 1]; + if (num1 == num2) return [1.1, _status.event.player == target ? 3 : 0.5]; + if (num1 == num2 - 1) + return [0.1, _status.event.player == target ? 4.5 : 0.1]; } - if(typeof card=='object'&&(card.name=='shunshou'||card.name=='guohe'||card.name=='zhujinqiyuan')&&target.countCards('h')>0&&get.attitude(player,target)<0) return [1,-1]; - } + if ( + typeof card == "object" && + (card.name == "shunshou" || + card.name == "guohe" || + card.name == "zhujinqiyuan") && + target.countCards("h") > 0 && + get.attitude(player, target) < 0 + ) + return [1, -1]; + }, }, - reverseEquip:true, - noe:true, - expose:0.2, - } + reverseEquip: true, + noe: true, + expose: 0.2, + }, }, - oltuntian:{ - inherit:'tuntian', - filter:function(event,player){ - if(player==_status.currentPhase){ - if(event.type!='discard') return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.filter(function(i){ - return get.name(i,evt.hs.includes(i)?player:false)=='sha'; - }).length>0; + oltuntian: { + inherit: "tuntian", + filter: function (event, player) { + if (player == _status.currentPhase) { + if (event.type != "discard") return false; + var evt = event.getl(player); + return ( + evt && + evt.cards2 && + evt.cards2.filter(function (i) { + return get.name(i, evt.hs.includes(i) ? player : false) == "sha"; + }).length > 0 + ); } - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, }, - olzaoxian:{ - inherit:'zaoxian', - content:function(){ - player.awakenSkill('olzaoxian'); + olzaoxian: { + inherit: "zaoxian", + content: function () { + player.awakenSkill("olzaoxian"); player.loseMaxHp(); - player.addSkills('jixi'); + player.addSkills("jixi"); player.insertPhase(); - } + }, }, - rejunxing:{ - enable:'phaseUse', - audio:2, - usable:1, - filterCard:true, - selectCard:[1,Infinity], - filter:function(event,player){ - return player.countCards('h')>0; + rejunxing: { + enable: "phaseUse", + audio: 2, + usable: 1, + filterCard: true, + selectCard: [1, Infinity], + filter: function (event, player) { + return player.countCards("h") > 0; }, - check:function(card){ - if(ui.selected.cards.length) return -1; - return 6-get.value(card); + check: function (card) { + if (ui.selected.cards.length) return -1; + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - content:function(){ - "step 0" - target.chooseToDiscard(cards.length,'弃置'+get.cnNumber(cards.length)+'张牌并失去1点体力,或点取消将武将牌翻面并摸'+get.cnNumber(cards.length)+'张牌','he').set('ai',function(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){ + content: function () { + "step 0"; + target + .chooseToDiscard( + cards.length, + "弃置" + + get.cnNumber(cards.length) + + "张牌并失去1点体力,或点取消将武将牌翻面并摸" + + get.cnNumber(cards.length) + + "张牌", + "he" + ) + .set("ai", function (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 < target.getEnemies().length && + target.hasCard((cardx) => { + 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) { target.turnOver(); target.draw(cards.length); - } - else target.loseHp(); + } else target.loseHp(); + }, + ai: { + order: 2, + threaten: 1.8, + result: { + target: function (player, target) { + if (target.hasSkillTag("noturn")) return 0; + if (target.isTurnedOver()) return 2; + return -1 / (target.countCards("h") + 1); + }, + }, }, - ai:{ - order:2, - threaten:1.8, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noturn')) return 0; - if(target.isTurnedOver()) return 2; - return -1/(target.countCards('h')+1); - } - } - } }, - rejuece:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.getHistory('lose',function(evt){ - return evt.cards2&&evt.cards2.length>0; - }).length>0; + rejuece: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && + current.getHistory("lose", function (evt) { + return evt.cards2 && evt.cards2.length > 0; + }).length > 0 + ); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('rejuece'),'对一名本回合失去过牌的其他角色造成1点伤害',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',game.filterPlayer(function(current){ - return current!=player&¤t.getHistory('lose',function(evt){ - return evt.cards2&&evt.cards2.length>0; - }).length>0; - })).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('rejuece',target); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("rejuece"), + "对一名本回合失去过牌的其他角色造成1点伤害", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set( + "targets", + game.filterPlayer(function (current) { + return ( + current != player && + current.getHistory("lose", function (evt) { + return evt.cards2 && evt.cards2.length > 0; + }).length > 0 + ); + }) + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("rejuece", target); target.damage(); } }, }, - remieji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay'],color:'black'}); + remieji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", { type: ["trick", "delay"], color: "black" }); }, - filterCard:function(card){ - return get.color(card)=='black'&&get.type(card,'trick')=='trick'; + filterCard: function (card) { + return get.color(card) == "black" && get.type(card, "trick") == "trick"; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - discard:false, - delay:false, - loseTo:'cardPile', - insert:true, - visible:true, - check:function(card){ - return 8-get.value(card); + discard: false, + delay: false, + loseTo: "cardPile", + insert: true, + visible: true, + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - if(!target.countCards('he',function(card){ - if(get.type2(card)=='trick') return true; - return lib.filter.cardDiscardable(card,target,'remieji'); - })) event.finish(); - else target.chooseCard('he',true,function(card,player){ - if(get.type2(card)=='trick') return true; - return lib.filter.cardDiscardable(card,player,'remieji'); - }).set('prompt','选择交给'+get.translation(player)+'一张锦囊牌,或依次弃置两张非锦囊牌。'); - 'step 2' - if(result.cards&&result.cards.length){ - if(get.type2(result.cards[0])=='trick'){ - target.give(result.cards,player); + "step 1"; + if ( + !target.countCards("he", function (card) { + if (get.type2(card) == "trick") return true; + return lib.filter.cardDiscardable(card, target, "remieji"); + }) + ) + event.finish(); + else + target + .chooseCard("he", true, function (card, player) { + if (get.type2(card) == "trick") return true; + return lib.filter.cardDiscardable(card, player, "remieji"); + }) + .set( + "prompt", + "选择交给" + get.translation(player) + "一张锦囊牌,或依次弃置两张非锦囊牌。" + ); + "step 2"; + if (result.cards && result.cards.length) { + if (get.type2(result.cards[0]) == "trick") { + target.give(result.cards, player); event.finish(); - } - else target.discard(result.cards); - } - else event.finish(); - 'step 3' - if(target.countCards('he',function(card){ - return get.type2(card)!='trick'; - })) target.chooseToDiscard('he',true,function(card){ - return get.type2(card)!='trick'; - }); + } else target.discard(result.cards); + } else event.finish(); + "step 3"; + if ( + target.countCards("he", function (card) { + return get.type2(card) != "trick"; + }) + ) + target.chooseToDiscard("he", true, function (card) { + return get.type2(card) != "trick"; + }); + }, + ai: { + order: 9, + result: { + target: -1, + }, }, - ai:{ - order:9, - result:{ - target:-1 - } - } }, - decadelihuo:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + decadelihuo: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; return false; }, - audio:'lihuo', - prompt2:function(event){ - return '将'+get.translation(event.card)+'改为火属性'; + audio: "lihuo", + prompt2: function (event) { + return "将" + get.translation(event.card) + "改为火属性"; }, - audioname:['re_chengpu'], - check:function(event,player){ - return event.baseDamage>1&&game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current) - &&get.attitude(player,current)<0&&!current.hasShan() - &&get.effect(current,{name:'sha',nature:'fire'},player,player)>0; - }); + audioname: ["re_chengpu"], + check: function (event, player) { + return ( + event.baseDamage > 1 && + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + player.canUse(event.card, current) && + get.attitude(player, current) < 0 && + !current.hasShan() && + get.effect(current, { name: "sha", nature: "fire" }, player, player) > 0 + ); + }) + ); }, - content:function(){ - game.setNature(trigger.card,'fire'); + content: function () { + game.setNature(trigger.card, "fire"); }, - group:['decadelihuo2','decadelihuo3'], - ai:{ - fireAttack:true, + group: ["decadelihuo2", "decadelihuo3"], + ai: { + fireAttack: true, }, }, - decadelihuo2:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha'||!game.hasNature(event.card,'fire')) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current); + decadelihuo2: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('decadelihuo'),'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target); - }).set('sourcex',trigger.targets).set('card',trigger.card).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!_status.connectMode) game.delayx(); - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("decadelihuo"), + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("card", trigger.card) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !_status.connectMode) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - player.logSkill('decadelihuo',event.target); + "step 2"; + player.logSkill("decadelihuo", event.target); trigger.targets.push(event.target); }, }, - decadelihuo3:{ - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.card.name=='sha'&&game.hasNature(event.card,'fire')&&event.targets.length>1&&player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length>0; + decadelihuo3: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + game.hasNature(event.card, "fire") && + event.targets.length > 1 && + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length > 0 + ); }, - forced:true, - audio:'lihuo', - audioname:['re_chengpu'], - content:function(){ + forced: true, + audio: "lihuo", + audioname: ["re_chengpu"], + content: function () { player.loseHp(); - } + }, }, - decadechunlao:{ - audio:'chunlao', - audioname:['re_chengpu'], - enable:'chooseToUse', - viewAs:{name:'jiu',isCard:true}, - viewAsFilter:function(player){ + decadechunlao: { + audio: "chunlao", + audioname: ["re_chengpu"], + enable: "chooseToUse", + viewAs: { name: "jiu", isCard: true }, + viewAsFilter: function (player) { return !player.isLinked(); }, - filter:function(event,player){ + filter: function (event, player) { return !player.isLinked(); }, - filterCard:function(){return false}, - selectCard:-1, - precontent:function(){ - player.logSkill('decadechunlao'); + filterCard: function () { + return false; + }, + selectCard: -1, + precontent: function () { + player.logSkill("decadechunlao"); player.link(); delete event.result.skill; }, - group:['decadechunlao2','decadechunlaox'], - ai:{ - jiuOther:true, + group: ["decadechunlao2", "decadechunlaox"], + ai: { + jiuOther: true, }, }, - decadechunlaox:{ - trigger:{player:'damageBegin2'}, - silent:true, - lastDo:true, - filter:function(event,player){ + decadechunlaox: { + trigger: { player: "damageBegin2" }, + silent: true, + lastDo: true, + filter: function (event, player) { return !player.isLinked(); }, - content:function(){ - trigger.decadechunlaox=true; + content: function () { + trigger.decadechunlaox = true; }, }, - decadechunlao2:{ - trigger:{ - source:'damageSource', - player:'damageEnd', + decadechunlao2: { + trigger: { + source: "damageSource", + player: "damageEnd", }, - prompt:'是否发动【醇醪】将武将牌重置?', - filter:function(event,player){ - return player.isLinked()&&event.num>1&&!event.decadechunlaox; + prompt: "是否发动【醇醪】将武将牌重置?", + filter: function (event, player) { + return player.isLinked() && event.num > 1 && !event.decadechunlaox; }, - content:function(){ + content: function () { player.link(); }, }, - oltianxiang:{ - audio:'tianxiang', - audioname:['daxiaoqiao','re_xiaoqiao','ol_xiaoqiao'], - trigger:{player:'damageBegin4'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.suit(card,player)=='heart'; - })>0&&event.num>0; + oltianxiang: { + audio: "tianxiang", + audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"], + trigger: { player: "damageBegin4" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.suit(card, player) == "heart"; + }) > 0 && event.num > 0 + ); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:function(card,player){ - return get.suit(card)=='heart'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - position:'he', - ai1:function(card){ - return 10-get.value(card); + position: "he", + ai1: function (card) { + return 10 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var trigger=_status.event.getTrigger(); - var da=0; - if(_status.event.player.hp==1){ - da=10; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var trigger = _status.event.getTrigger(); + var da = 0; + if (_status.event.player.hp == 1) { + da = 10; } - var eff=get.damageEffect(target,trigger.source,target); - if(att==0) return 0.1+da; - if(eff>=0&&att>0){ - return att+da; + var eff = get.damageEffect(target, trigger.source, target); + if (att == 0) return 0.1 + da; + if (eff >= 0 && att > 0) { + return att + da; } - if(att>0&&target.hp>1){ - if(target.maxHp-target.hp>=3) return att*1.1+da; - if(target.maxHp-target.hp>=2) return att*0.9+da; + if (att > 0 && target.hp > 1) { + if (target.maxHp - target.hp >= 3) return att * 1.1 + da; + if (target.maxHp - target.hp >= 2) return att * 0.9 + da; } - return -att+da; + return -att + da; }, - prompt:get.prompt('oltianxiang'), - prompt2:lib.translate.oltianxiang_info + prompt: get.prompt("oltianxiang"), + prompt2: lib.translate.oltianxiang_info, }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - var target=result.targets[0]; - player.chooseControlList(true,function(event,player){ - var target=_status.event.target; - var att=get.attitude(player,target); - if(target.hasSkillTag('maihp')) att=-att; - if(att>0){ - return 0; - } - else{ - return 1; - } - }, - ['令'+get.translation(target)+'受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)', - '令'+get.translation(target)+'失去1点体力,然后获得'+get.translation(result.cards)]).set('target',target); - player.logSkill(event.name,target); + var target = result.targets[0]; + player + .chooseControlList( + true, + function (event, player) { + var target = _status.event.target; + var att = get.attitude(player, target); + if (target.hasSkillTag("maihp")) att = -att; + if (att > 0) { + return 0; + } else { + return 1; + } + }, + [ + "令" + + get.translation(target) + + "受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)", + "令" + + get.translation(target) + + "失去1点体力,然后获得" + + get.translation(result.cards), + ] + ) + .set("target", target); + player.logSkill(event.name, target); trigger.cancel(); - event.target=target; - event.card=result.cards[0]; - } - else{ + event.target = target; + event.card = result.cards[0]; + } else { event.finish(); } - "step 2" - if(typeof result.index=='number'){ - event.index=result.index; - if(result.index){ - event.related=event.target.loseHp(); + "step 2"; + if (typeof result.index == "number") { + event.index = result.index; + if (result.index) { + event.related = event.target.loseHp(); + } else { + event.related = event.target.damage(trigger.source || "nosource", "nocard"); } - else{ - event.related=event.target.damage(trigger.source||'nosource','nocard'); - } - } - else event.finish(); - "step 3" - if(event.related.cancelled||target.isDead()) return; - if(event.index&&card.isInPile()) target.gain(card,'gain2'); - else if(target.getDamagedHp()) target.draw(Math.min(5,target.getDamagedHp())); + } else event.finish(); + "step 3"; + if (event.related.cancelled || target.isDead()) return; + if (event.index && card.isInPile()) target.gain(card, "gain2"); + else if (target.getDamagedHp()) target.draw(Math.min(5, target.getDamagedHp())); }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&target.countCards('he')>1) return 0.7; - } - }, - } - }, - olhongyan:{ - audio:'rehongyan', - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'heart'; - }, - maxHandcardBase:function(player,num){ - if(player.countCards('e',function(card){ - return get.suit(card,player)=='heart'; - })) return player.maxHp; + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.tag(card, "damage") && target.countCards("he") > 1) return 0.7; + }, }, }, }, - piaoling:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - content:function(){ - 'step 0' - player.judge(function(card){ - return get.suit(card)=='heart'?2:0; - }).judge2=function(result){ - return result.bool?true:false; + olhongyan: { + audio: "rehongyan", + mod: { + suit: function (card, suit) { + if (suit == "spade") return "heart"; + }, + maxHandcardBase: function (player, num) { + if ( + player.countCards("e", function (card) { + return get.suit(card, player) == "heart"; + }) + ) + return player.maxHp; + }, + }, + }, + piaoling: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + content: function () { + "step 0"; + player.judge(function (card) { + return get.suit(card) == "heart" ? 2 : 0; + }).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 1' - event.card=result.card; - if(result.bool&&get.position(event.card,true)=='d'){ - player.chooseTarget('令一名角色获得'+get.translation(event.card)+',或点【取消】将其置于牌堆顶').set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(player==target) att/=2; - return att; - }); - } - else event.finish(); - 'step 2' - if(result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(card,'gain2','log'); - if(player==target) player.chooseToDiscard('he',true); - } - else{ + "step 1"; + event.card = result.card; + if (result.bool && get.position(event.card, true) == "d") { + player + .chooseTarget( + "令一名角色获得" + + get.translation(event.card) + + ",或点【取消】将其置于牌堆顶" + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (player == target) att /= 2; + return att; + }); + } else event.finish(); + "step 2"; + if (result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(card, "gain2", "log"); + if (player == target) player.chooseToDiscard("he", true); + } else { card.fix(); - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); game.updateRoundNumber(); } }, }, - xinyicong:{ - mod:{ - globalFrom:function(from,to,current){ - return current-Math.max(0,from.hp-1); + xinyicong: { + mod: { + globalFrom: function (from, to, current) { + return current - Math.max(0, from.hp - 1); }, - globalTo:function(from,to,current){ - return current+Math.max(0,to.getDamagedHp()-1); + globalTo: function (from, to, current) { + return current + Math.max(0, to.getDamagedHp() - 1); }, }, - ai:{ - threaten:0.8 - } - }, - rezongshi:{ - audio:2, - mod:{ - maxHandcard:function(player,num){ - return num+game.countGroup(); - }, - }, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.countCards('h')>player.hp; - }, - content:function(){ - player.addTempSkill('rezongshi_paoxiao'); + ai: { + threaten: 0.8, }, }, - rezongshi_paoxiao:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return Infinity; + rezongshi: { + audio: 2, + mod: { + maxHandcard: function (player, num) { + return num + game.countGroup(); + }, + }, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.countCards("h") > player.hp; + }, + content: function () { + player.addTempSkill("rezongshi_paoxiao"); + }, + }, + rezongshi_paoxiao: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return Infinity; }, }, }, - olbaonue:{ - audio:2, - unique:true, - zhuSkill:true, - trigger:{global:'damageSource'}, - filter:function(event,player){ - if(player==event.source||!event.source||event.source.group!='qun') return false; - return player.hasZhuSkill('olbaonue',event.source); + olbaonue: { + audio: 2, + unique: true, + zhuSkill: true, + trigger: { global: "damageSource" }, + filter: function (event, player) { + if (player == event.source || !event.source || event.source.group != "qun") return false; + return player.hasZhuSkill("olbaonue", event.source); }, - direct:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - player.chooseBool('是否发动【暴虐】?').set('choice',get.attitude(player,player)>0); - 'step 2' - if(result.bool){ - player.logSkill('olbaonue',trigger.source); - player.judge(function(card){ - if(get.suit(card)=='spade') return 4; - return 0; - }).set('callback',function(){ - if(event.judgeResult.suit=='spade'){ - player.recover(); - if(get.position(event.judgeResult.card,true)=='o') player.gain(event.judgeResult.card,'gain2','log') - } - }).judge2=function(result){ - return result.bool?true:false; + player.chooseBool("是否发动【暴虐】?").set("choice", get.attitude(player, player) > 0); + "step 2"; + if (result.bool) { + player.logSkill("olbaonue", trigger.source); + player + .judge(function (card) { + if (get.suit(card) == "spade") return 4; + return 0; + }) + .set("callback", function () { + if (event.judgeResult.suit == "spade") { + player.recover(); + if (get.position(event.judgeResult.card, true) == "o") + player.gain(event.judgeResult.card, "gain2", "log"); + } + }).judge2 = function (result) { + return result.bool ? true : false; }; - } - else{ + } else { event.finish(); } - 'step 3' - if(event.count&&lib.skill.olbaonue.filter(trigger,player)) event.goto(1); - } - }, - rezishou:{ - audio:'zishou', - audioname:['re_liubiao'], - trigger:{player:'phaseDrawBegin2'}, - check:function(event,player){ - return player.countCards('h')<=(player.hasSkill('zongshi')?player.maxHp:(player.hp-2))||player.skipList.includes('phaseUse')||!player.countCards('h',function(card){ - return get.tag(card,'damage')&&player.hasUseTarget(card); - }); + "step 3"; + if (event.count && lib.skill.olbaonue.filter(trigger, player)) event.goto(1); }, - filter:function(event,player){ + }, + rezishou: { + audio: "zishou", + audioname: ["re_liubiao"], + trigger: { player: "phaseDrawBegin2" }, + check: function (event, player) { + return ( + player.countCards("h") <= + (player.hasSkill("zongshi") ? player.maxHp : player.hp - 2) || + player.skipList.includes("phaseUse") || + !player.countCards("h", function (card) { + return get.tag(card, "damage") && player.hasUseTarget(card); + }) + ); + }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=game.countGroup(); - player.addTempSkill('rezishou2'); + content: function () { + trigger.num += game.countGroup(); + player.addTempSkill("rezishou2"); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - rezishou2:{ - audio:'rezishou', - trigger:{ - source:'damageBegin2', + rezishou2: { + audio: "rezishou", + trigger: { + source: "damageBegin2", //player:'phaseJieshuBegin', }, - forced:true, - filter:function(event,player){ - if(event.name=='damage') return event.player!=player; - if(player.getHistory('skipped').includes('phaseUse')) return false; - return player.getHistory('useCard',function(evt){ - if(evt.targets&&evt.targets.length&&evt.isPhaseUsing()){ - var targets=evt.targets.slice(0); - while(targets.includes(player)) targets.remove(player); - return targets.length>0; - } - return false; - }).length==0; + forced: true, + filter: function (event, player) { + if (event.name == "damage") return event.player != player; + if (player.getHistory("skipped").includes("phaseUse")) return false; + return ( + player.getHistory("useCard", function (evt) { + if (evt.targets && evt.targets.length && evt.isPhaseUsing()) { + var targets = evt.targets.slice(0); + while (targets.includes(player)) targets.remove(player); + return targets.length > 0; + } + return false; + }).length == 0 + ); }, - popup:false, - content:function(){ - 'step 0' - if(trigger.name=='damage'){ - player.logSkill('rezishou',trigger.player); + popup: false, + content: function () { + "step 0"; + if (trigger.name == "damage") { + player.logSkill("rezishou", trigger.player); trigger.cancel(); event.finish(); return; - } - else{ - var filterTarget=function(card,player,target){ - return target!=player&&target.countCards('e',function(card){ - return player.canEquip(card); - }); - } - if(game.hasPlayer(function(current){ - return filterTarget(null,player,current) - })) player.chooseTarget(filterTarget,'是否将一名其他角色装备区内的一张牌移动到自己的装备区?').set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0&&!target.hasSkillTag('noe')) return 0; - var num=0; - target.countCards('e',function(card){ - if(player.canEquip(card)){ - var eff=get.effect(player,card,player,player); - if(eff>num) num=eff; - } - }); - if(num<=0) return 0; - if(att<0) return num*-att; - return 1/num; - }); + } else { + var filterTarget = function (card, player, target) { + return ( + target != player && + target.countCards("e", function (card) { + return player.canEquip(card); + }) + ); + }; + if ( + game.hasPlayer(function (current) { + return filterTarget(null, player, current); + }) + ) + player + .chooseTarget( + filterTarget, + "是否将一名其他角色装备区内的一张牌移动到自己的装备区?" + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0 && !target.hasSkillTag("noe")) return 0; + var num = 0; + target.countCards("e", function (card) { + if (player.canEquip(card)) { + var eff = get.effect(player, card, player, player); + if (eff > num) num = eff; + } + }); + if (num <= 0) return 0; + if (att < 0) return num * -att; + return 1 / num; + }); else event.finish(); } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('rezishou',target); - player.choosePlayerCard(target,'e','将一张装备牌移至你的装备区').set('filterButton',function(button){ - return _status.event.player.canEquip(button.link); - }); - } - else event.finish(); - "step 2" - if(result&&result.links&&result.links.length){ + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("rezishou", target); + player + .choosePlayerCard(target, "e", "将一张装备牌移至你的装备区") + .set("filterButton", function (button) { + return _status.event.player.canEquip(button.link); + }); + } else event.finish(); + "step 2"; + if (result && result.links && result.links.length) { game.delay(2); - target.$give(result.links[0],player,false); + target.$give(result.links[0], player, false); player.equip(result.links[0]); player.addExpose(0.2); } }, - ai:{ - effect:{ - player:function(card,player,target){ - if(get.tag(card,'damage')) return 'zeroplayertarget'; + ai: { + effect: { + player: function (card, player, target) { + if (get.tag(card, "damage")) return "zeroplayertarget"; }, }, }, }, - decadepojun:{ - shaRelated:true, - audio:2, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.hp>0&&event.target.countCards('he')>0; + decadepojun: { + shaRelated: true, + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && event.target.hp > 0 && event.target.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - var next=player.choosePlayerCard(trigger.target,'he',[1,Math.min(trigger.target.hp,trigger.target.countCards('he'))],get.prompt('decadepojun',trigger.target)); - next.set('ai',function(button){ - if(!_status.event.goon) return 0; - var val=get.value(button.link); - if(button.link==_status.event.target.getEquip(2)) return 2*(val+3); + content: function () { + "step 0"; + var next = player.choosePlayerCard( + trigger.target, + "he", + [1, Math.min(trigger.target.hp, trigger.target.countCards("he"))], + get.prompt("decadepojun", trigger.target) + ); + next.set("ai", function (button) { + if (!_status.event.goon) return 0; + var val = get.value(button.link); + if (button.link == _status.event.target.getEquip(2)) return 2 * (val + 3); return val; }); - next.set('goon',get.attitude(player,trigger.target)<=0); - next.set('forceAuto',true); - 'step 1' - if(result.bool){ - event.cards=result.cards; - var target=trigger.target; - player.logSkill('decadepojun',trigger.target); - target.addSkill('decadepojun2'); - target.addToExpansion(result.cards,'giveAuto',target).gaintag.add('decadepojun2'); + next.set("goon", get.attitude(player, trigger.target) <= 0); + next.set("forceAuto", true); + "step 1"; + if (result.bool) { + event.cards = result.cards; + var target = trigger.target; + player.logSkill("decadepojun", trigger.target); + target.addSkill("decadepojun2"); + target.addToExpansion(result.cards, "giveAuto", target).gaintag.add("decadepojun2"); + } else event.finish(); + "step 2"; + var discard = false, + draw = false; + for (var i of cards) { + var type = get.type2(i); + if (type == "equip") discard = true; + if (type == "trick") draw = true; } - else event.finish(); - 'step 2' - var discard=false,draw=false; - for(var i of cards){ - var type=get.type2(i); - if(type=='equip') discard=true; - if(type=='trick') draw=true; + if (discard) { + event.equip = true; + player + .chooseButton( + [ + "选择一张牌置入弃牌堆", + cards.filter(function (card) { + return get.type(card) == "equip"; + }), + ], + true + ) + .set("ai", function (button) { + return get.value(button.link, _status.event.getTrigger().target); + }); } - if(discard){ - event.equip=true; - player.chooseButton(['选择一张牌置入弃牌堆',cards.filter(function(card){ - return get.type(card)=='equip'; - })],true).set('ai',function(button){ - return get.value(button.link,_status.event.getTrigger().target); - }); - } - if(draw) event.draw=true; - 'step 3' - if(event.equip&&result.links&&result.links.length){ + if (draw) event.draw = true; + "step 3"; + if (event.equip && result.links && result.links.length) { trigger.target.loseToDiscardpile(result.links); } - if(event.draw) player.draw(); + if (event.draw) player.draw(); }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)>0) return false; - if(tag=='directHit_ai') return arg.target.hp>=Math.max(1,arg.target.countCards('h')-1); - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (get.attitude(player, arg.target) > 0) return false; + if (tag == "directHit_ai") + return arg.target.hp >= Math.max(1, arg.target.countCards("h") - 1); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } - }, - }, - decadepojun2:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('decadepojun2').length>0; - }, - content:function(){ - 'step 0' - var cards=player.getExpansions('decadepojun2'); - player.gain(cards,'draw'); - game.log(player,'收回了'+get.cnNumber(cards.length)+'张“破军”牌'); - 'step 1' - player.removeSkill('decadepojun2'); - }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('decadepojun2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; }, }, }, - hanzhan:{ - audio:2, - trigger:{ - global:'chooseToCompareBegin', + decadepojun2: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("decadepojun2").length > 0; }, - filter:function(event,player){ - if(player==event.player) return true; - if(event.targets) return event.targets.includes(player); - return player==event.target; + content: function () { + "step 0"; + var cards = player.getExpansions("decadepojun2"); + player.gain(cards, "draw"); + game.log(player, "收回了" + get.cnNumber(cards.length) + "张“破军”牌"); + "step 1"; + player.removeSkill("decadepojun2"); }, - logTarget:function(event,player){ - if(player!=event.player) return event.player; - return event.targets||event.target; + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("decadepojun2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; + }, }, - prompt2:function(event,player){ - return '令其改为使用随机的手牌进行拼点' - }, - check:function(trigger,player){ - var num=0; - var targets=player==trigger.player?(trigger.targets?trigger.targets.slice(0):[trigger.target]):[trigger.player]; - while(targets.length){ - var target=targets.shift(); - if(target.getCards('h').length>1) num-=get.attitude(player,target); - } - return num>0; - }, - content:function(){ - var targets=player==trigger.player?(trigger.targets?trigger.targets.slice(0):[trigger.target]):[trigger.player]; - if(!trigger.fixedResult) trigger.fixedResult={}; - while(targets.length){ - var target=targets.shift(); - var hs=target.getCards('h'); - if(hs.length) trigger.fixedResult[target.playerid]=hs.randomGet(); - } - }, - group:'hanzhan_gain', - subfrequent:['gain'], }, - hanzhan_gain:{ - trigger:{ - global:'chooseToCompareAfter', + hanzhan: { + audio: 2, + trigger: { + global: "chooseToCompareBegin", }, - audio:'hanzhan', - filter:function(event,player){ - if(event.preserve) return false; - if(player!=event.player&&player!=event.target&&(!event.targets||!event.targets.includes(player))) return false; - for(var i of event.lose_list){ - if(Array.isArray(i[1])){ - for(var j of i[1]){ - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o') return true; + filter: function (event, player) { + if (player == event.player) return true; + if (event.targets) return event.targets.includes(player); + return player == event.target; + }, + logTarget: function (event, player) { + if (player != event.player) return event.player; + return event.targets || event.target; + }, + prompt2: function (event, player) { + return "令其改为使用随机的手牌进行拼点"; + }, + check: function (trigger, player) { + var num = 0; + var targets = + player == trigger.player + ? trigger.targets + ? trigger.targets.slice(0) + : [trigger.target] + : [trigger.player]; + while (targets.length) { + var target = targets.shift(); + if (target.getCards("h").length > 1) num -= get.attitude(player, target); + } + return num > 0; + }, + content: function () { + var targets = + player == trigger.player + ? trigger.targets + ? trigger.targets.slice(0) + : [trigger.target] + : [trigger.player]; + if (!trigger.fixedResult) trigger.fixedResult = {}; + while (targets.length) { + var target = targets.shift(); + var hs = target.getCards("h"); + if (hs.length) trigger.fixedResult[target.playerid] = hs.randomGet(); + } + }, + group: "hanzhan_gain", + subfrequent: ["gain"], + }, + hanzhan_gain: { + trigger: { + global: "chooseToCompareAfter", + }, + audio: "hanzhan", + filter: function (event, player) { + if (event.preserve) return false; + if ( + player != event.player && + player != event.target && + (!event.targets || !event.targets.includes(player)) + ) + return false; + for (var i of event.lose_list) { + if (Array.isArray(i[1])) { + for (var j of i[1]) { + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") return true; } - } - else{ - var j=i[1]; - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o') return true; + } else { + var j = i[1]; + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") return true; } } return false; }, - frequent:true, - prompt2:function(event,player){ - var cards=[],max=0; - for(var i of event.lose_list){ - if(Array.isArray(i[1])){ - for(var j of i[1]){ - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o'){ - var num=get.number(j,i[0]); - if(num>max){ - cards=[]; - max=num; + frequent: true, + prompt2: function (event, player) { + var cards = [], + max = 0; + for (var i of event.lose_list) { + if (Array.isArray(i[1])) { + for (var j of i[1]) { + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") { + var num = get.number(j, i[0]); + if (num > max) { + cards = []; + max = num; } - if(num==max) cards.push(j); + if (num == max) cards.push(j); } } - } - else{ - var j=i[1]; - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o'){ - var num=get.number(j,i[0]); - if(num>max){ - cards=[]; - max=num; + } else { + var j = i[1]; + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") { + var num = get.number(j, i[0]); + if (num > max) { + cards = []; + max = num; } - if(num==max) cards.push(j); + if (num == max) cards.push(j); } } } - return '获得'+get.translation(cards); + return "获得" + get.translation(cards); }, - content:function(){ - var cards=[],max=0; - for(var i of trigger.lose_list){ - if(Array.isArray(i[1])){ - for(var j of i[1]){ - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o'){ - var num=get.number(j,i[0]); - if(num>max){ - cards=[]; - max=num; + content: function () { + var cards = [], + max = 0; + for (var i of trigger.lose_list) { + if (Array.isArray(i[1])) { + for (var j of i[1]) { + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") { + var num = get.number(j, i[0]); + if (num > max) { + cards = []; + max = num; } - if(num==max) cards.push(j); + if (num == max) cards.push(j); } } - } - else{ - var j=i[1]; - if(get.name(j,i[0])=='sha'&&get.position(j,true)=='o'){ - var num=get.number(j,i[0]); - if(num>max){ - cards=[]; - max=num; + } else { + var j = i[1]; + if (get.name(j, i[0]) == "sha" && get.position(j, true) == "o") { + var num = get.number(j, i[0]); + if (num > max) { + cards = []; + max = num; } - if(num==max) cards.push(j); + if (num == max) cards.push(j); } } } - player.gain(cards,'gain2'); + player.gain(cards, "gain2"); }, }, - rejianchu:{ - shaRelated:true, - audio:2, - audioname:['re_pangde'], - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countDiscardableCards(player,'he')>0; + rejianchu: { + shaRelated: true, + audio: 2, + audioname: ["re_pangde"], + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countDiscardableCards(player, "he") > 0; }, - direct:true, - content:function(){ - 'step 0' - player.discardPlayerCard(trigger.target,get.prompt('rejianchu',trigger.target)).set('ai',function(button){ - if(!_status.event.att) return 0; - if(get.position(button.link)=='e'){ - if(get.subtype(button.link)=='equip2') return 2*get.value(button.link); - return get.value(button.link); - } - return 1; - }).set('logSkill',['rejianchu',trigger.target]).set('att',get.attitude(player,trigger.target)<=0); - 'step 1' - if(result.bool&&result.links&&result.links.length){ - if(get.type(result.links[0],null,result.links[0].original=='h'?player:false)!='basic'){ + direct: true, + content: function () { + "step 0"; + player + .discardPlayerCard(trigger.target, get.prompt("rejianchu", trigger.target)) + .set("ai", function (button) { + if (!_status.event.att) return 0; + if (get.position(button.link) == "e") { + if (get.subtype(button.link) == "equip2") return 2 * get.value(button.link); + return get.value(button.link); + } + return 1; + }) + .set("logSkill", ["rejianchu", trigger.target]) + .set("att", get.attitude(player, trigger.target) <= 0); + "step 1"; + if (result.bool && result.links && result.links.length) { + if ( + get.type( + result.links[0], + null, + result.links[0].original == "h" ? player : false + ) != "basic" + ) { trigger.getParent().directHit.add(trigger.target); - player.addTempSkill('rejianchu2'); - player.addMark('rejianchu2',1,false); - } - else if(trigger.cards){ - var list=[]; - for(var i=0;i1; - })>0; - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "directHit_ai") + return ( + arg.card.name == "sha" && + arg.target.countCards("e", function (card) { + return get.value(card) > 1; + }) > 0 + ); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } - }, - }, - rejianchu2:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('rejianchu2'); }, }, - onremove:true, }, - wulie:{ - trigger:{player:'phaseJieshuBegin'}, - audio:2, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'wood', - unique:true, - filter:function(event,player){ - return player.hp>0; + rejianchu2: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("rejianchu2"); + }, }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.hp],get.prompt2('wulie'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player.hasUnknown()) return 0; - if(player.hp-ui.selected.targets.length>1+player.countCards('hs',card=>player.canSaveCard(card,player))) return get.attitude(player,target); - return 0; - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('wulie',targets); - player.awakenSkill('wulie'); + onremove: true, + }, + wulie: { + trigger: { player: "phaseJieshuBegin" }, + audio: 2, + direct: true, + limited: true, + skillAnimation: true, + animationColor: "wood", + unique: true, + filter: function (event, player) { + return player.hp > 0; + }, + content: function () { + "step 0"; + player + .chooseTarget([1, player.hp], get.prompt2("wulie"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + if (player.hasUnknown()) return 0; + if ( + player.hp - ui.selected.targets.length > + 1 + player.countCards("hs", (card) => player.canSaveCard(card, player)) + ) + return get.attitude(player, target); + return 0; + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("wulie", targets); + player.awakenSkill("wulie"); player.loseHp(targets.length); - while(targets.length){ - targets[0].addSkill('wulie2'); - targets.shift().addMark('wulie2'); + while (targets.length) { + targets[0].addSkill("wulie2"); + targets.shift().addMark("wulie2"); } } }, }, - wulie2:{ - marktext:'烈', - intro:{name2:'烈',content:'mark'}, - trigger:{player:'damageBegin3'}, - forced:true, - content:function(){ + wulie2: { + marktext: "烈", + intro: { name2: "烈", content: "mark" }, + trigger: { player: "damageBegin3" }, + forced: true, + content: function () { trigger.cancel(); - player.removeMark('wulie2',1); - if(!player.storage.wulie2) player.removeSkill('wulie2'); + player.removeMark("wulie2", 1); + if (!player.storage.wulie2) player.removeSkill("wulie2"); }, }, - regongji:{ - mod:{ - attackRangeBase:function(player){ - if(player.getEquips(3).length>0||player.getEquips(4).length>0) return Infinity; + regongji: { + mod: { + attackRangeBase: function (player) { + if (player.getEquips(3).length > 0 || player.getEquips(4).length > 0) return Infinity; }, }, - locked:false, - enable:'phaseUse', - usable:1, - position:'he', - filter:function(event,player){ - return player.hasCard(function(card){ + locked: false, + enable: "phaseUse", + usable: 1, + position: "he", + filter: function (event, player) { + return player.hasCard(function (card) { return lib.skill.regongji.filterCard(card); - },'eh'); + }, "eh"); }, - filterCard:function(card,player){ - return get.type(card)!='basic'; + filterCard: function (card, player) { + return get.type(card) != "basic"; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; + filterTarget: function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; }, - check:function(card){ - return 4.5-get.value(card); + check: function (card) { + return 4.5 - get.value(card); }, - content:function(){ - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true); + content: function () { + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var nh=target.countCards('h'); - if(att>0){ - if(target.getEquip('baiyin')&&target.isDamaged()&& - get.recoverEffect(target,player,player)>0){ - if(target.hp==1&&!target.hujia) return 1.6; - if(target.hp==2) return 0.01; + ai: { + order: 5, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + var nh = target.countCards("h"); + if (att > 0) { + if ( + target.getEquip("baiyin") && + target.isDamaged() && + get.recoverEffect(target, player, player) > 0 + ) { + if (target.hp == 1 && !target.hujia) return 1.6; + if (target.hp == 2) return 0.01; return 0; } } - var es=target.getCards('e'); - var noe=(es.length==0||target.hasSkillTag('noe')); - var noe2=(es.length==1&&es[0].name!='tengjia'&&get.value(es[0])<=0); - var noh=(nh==0||target.hasSkillTag('noh')); - if(noh&&(noe||noe2)) return 0; - if(att<=0&&!target.countCards('he')) return 1.5; + var es = target.getCards("e"); + var noe = es.length == 0 || target.hasSkillTag("noe"); + var noe2 = es.length == 1 && es[0].name != "tengjia" && get.value(es[0]) <= 0; + var noh = nh == 0 || target.hasSkillTag("noh"); + if (noh && (noe || noe2)) return 0; + if (att <= 0 && !target.countCards("he")) return 1.5; return -1.5; }, }, - tag:{ - loseCard:1, - discard:1 + tag: { + loseCard: 1, + discard: 1, }, }, }, - ollongdan:{ - mod:{ - aiValue:function(player,card,num){ - if(card.name!='sha'&&card.name!='shan') return; - var geti=function(){ - var cards=player.getCards('hs',function(card){ - return card.name=='sha'||card.name=='shan'; + ollongdan: { + mod: { + aiValue: function (player, card, num) { + if (card.name != "sha" && card.name != "shan") return; + var geti = function () { + var cards = player.getCards("hs", function (card) { + return card.name == "sha" || card.name == "shan"; }); - if(cards.includes(card)){ + if (cards.includes(card)) { return cards.indexOf(card); } return cards.length; }; - return Math.max(num,[7,5,5,3][Math.min(geti(),3)]); + return Math.max(num, [7, 5, 5, 3][Math.min(geti(), 3)]); }, - aiUseful:function(){ - return lib.skill.ollongdan.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.ollongdan.mod.aiValue.apply(this, arguments); }, }, - locked:false, - audio:'longdan_sha', - audioname:['re_zhaoyun'], - audioname2:{tongyuan:'longdan_tongyuan'}, - hiddenCard:function(player,name){ - if(name=='tao') return player.countCards('hs','jiu')>0; - if(name=='jiu') return player.countCards('hs','tao')>0; + locked: false, + audio: "longdan_sha", + audioname: ["re_zhaoyun"], + audioname2: { tongyuan: "longdan_tongyuan" }, + hiddenCard: function (player, name) { + if (name == "tao") return player.countCards("hs", "jiu") > 0; + if (name == "jiu") return player.countCards("hs", "tao") > 0; return false; }, - enable:['chooseToUse','chooseToRespond'], - position:'hs', - prompt:'将杀当做闪,或将闪当做杀,或将桃当做酒,或将酒当做桃使用或打出', - viewAs:function(cards,player){ - if(cards.length){ - var name=false; - switch(get.name(cards[0],player)){ - case 'sha':name='shan';break; - case 'shan':name='sha';break; - case 'tao':name='jiu';break; - case 'jiu':name='tao';break; + enable: ["chooseToUse", "chooseToRespond"], + position: "hs", + prompt: "将杀当做闪,或将闪当做杀,或将桃当做酒,或将酒当做桃使用或打出", + viewAs: function (cards, player) { + if (cards.length) { + var name = false; + switch (get.name(cards[0], player)) { + case "sha": + name = "shan"; + break; + case "shan": + name = "sha"; + break; + case "tao": + name = "jiu"; + break; + case "jiu": + name = "tao"; + break; } - if(name) return {name:name}; + if (name) return { name: name }; } return null; }, - check:function(card){ - var player=_status.event.player; - if(_status.event.type=='phase'){ - var max=0; + check: function (card) { + var player = _status.event.player; + if (_status.event.type == "phase") { + var max = 0; var name2; - var list=['sha','tao','jiu']; - var map={sha:'shan',tao:'jiu',jiu:'tao'} - for(var i=0;i(name=='jiu'?1:0)&&player.getUseValue({name:name})>0){ - var temp=get.order({name:name}); - if(temp>max){ - max=temp; - name2=map[name]; + var list = ["sha", "tao", "jiu"]; + var map = { sha: "shan", tao: "jiu", jiu: "tao" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hs", map[name]) > (name == "jiu" ? 1 : 0) && + player.getUseValue({ name: name }) > 0 + ) { + var temp = get.order({ name: name }); + if (temp > max) { + max = temp; + name2 = map[name]; } } } - if(name2==get.name(card,player)) return 1; + if (name2 == get.name(card, player)) return 1; return 0; } return 1; }, - filterCard:function(card,player,event){ - event=event||_status.event; - var filter=event._backup.filterCard; - var name=get.name(card,player); - if(name=='sha'&&filter({name:'shan',cards:[card]},player,event)) return true; - if(name=='shan'&&filter({name:'sha',cards:[card]},player,event)) return true; - if(name=='tao'&&filter({name:'jiu',cards:[card]},player,event)) return true; - if(name=='jiu'&&filter({name:'tao',cards:[card]},player,event)) return true; + filterCard: function (card, player, event) { + event = event || _status.event; + var filter = event._backup.filterCard; + var name = get.name(card, player); + if (name == "sha" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if (name == "shan" && filter({ name: "sha", cards: [card] }, player, event)) return true; + if (name == "tao" && filter({ name: "jiu", cards: [card] }, player, event)) return true; + if (name == "jiu" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, - filter:function(event,player){ - var filter=event.filterCard; - if(filter(get.autoViewAs({name:'sha'},'unsure'),player,event)&&player.countCards('hs','shan')) return true; - if(filter(get.autoViewAs({name:'shan'},'unsure'),player,event)&&player.countCards('hs','sha')) return true; - if(filter(get.autoViewAs({name:'tao'},'unsure'),player,event)&&player.countCards('hs','jiu')) return true; - if(filter(get.autoViewAs({name:'jiu'},'unsure'),player,event)&&player.countCards('hs','tao')) return true; + filter: function (event, player) { + var filter = event.filterCard; + if ( + filter(get.autoViewAs({ name: "sha" }, "unsure"), player, event) && + player.countCards("hs", "shan") + ) + return true; + if ( + filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && + player.countCards("hs", "sha") + ) + return true; + if ( + filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + player.countCards("hs", "jiu") + ) + return true; + if ( + filter(get.autoViewAs({ name: "jiu" }, "unsure"), player, event) && + player.countCards("hs", "tao") + ) + return true; return false; }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { var name; - switch(tag){ - case 'respondSha':name='shan';break; - case 'respondShan':name='sha';break; + switch (tag) { + case "respondSha": + name = "shan"; + break; + case "respondShan": + name = "sha"; + break; } - if(!player.countCards('hs',name)) return false; + if (!player.countCards("hs", name)) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - var list=['sha','tao','jiu']; - var map={sha:'shan',tao:'jiu',jiu:'tao'} - for(var i=0;i(name=='jiu'?1:0)&&player.getUseValue({name:name})>0){ - var temp=get.order({name:name}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao", "jiu"]; + var map = { sha: "shan", tao: "jiu", jiu: "tao" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hs", map[name]) > (name == "jiu" ? 1 : 0) && + player.getUseValue({ name: name }) > 0 + ) { + var temp = get.order({ name: name }); + if (temp > max) max = temp; } } - if(max>0) max+=0.3; + if (max > 0) max += 0.3; return max; } return 4; }, }, }, - olyajiao:{ - audio:'reyajiao', - trigger:{player:'loseAfter'}, - frequent:true, - filter:function(event,player){ - return player!=_status.currentPhase&&event.hs&&event.hs.length>0&&['useCard','respond'].includes(event.getParent().name); + olyajiao: { + audio: "reyajiao", + trigger: { player: "loseAfter" }, + frequent: true, + filter: function (event, player) { + return ( + player != _status.currentPhase && + event.hs && + event.hs.length > 0 && + ["useCard", "respond"].includes(event.getParent().name) + ); }, - content:function(){ - "step 0" - event.card=get.cards()[0]; + content: function () { + "step 0"; + event.card = get.cards()[0]; game.cardsGotoOrdering(event.card); - event.videoId=lib.status.videoId++; - var judgestr=get.translation(player)+'发动了【涯角】'; - game.addVideo('judge1',player,[get.cardInfo(event.card),judgestr,event.videoId]); - game.broadcastAll(function(player,card,str,id,cardid){ - var event; - if(game.online){ - event={}; - } - else{ - event=_status.event; - } - if(game.chess){ - event.node=card.copy('thrown','center',ui.arena).addTempClass('start'); - } - else{ - event.node=player.$throwordered(card.copy(),true); - } - if(lib.cardOL) lib.cardOL[cardid]=event.node; - event.node.cardid=cardid; - event.node.classList.add('thrownhighlight'); - ui.arena.classList.add('thrownhighlight'); - event.dialog=ui.create.dialog(str); - event.dialog.classList.add('center'); - event.dialog.videoId=id; - },player,event.card,judgestr,event.videoId,get.id()); + event.videoId = lib.status.videoId++; + var judgestr = get.translation(player) + "发动了【涯角】"; + game.addVideo("judge1", player, [get.cardInfo(event.card), judgestr, event.videoId]); + game.broadcastAll( + function (player, card, str, id, cardid) { + var event; + if (game.online) { + event = {}; + } else { + event = _status.event; + } + if (game.chess) { + event.node = card.copy("thrown", "center", ui.arena).addTempClass("start"); + } else { + event.node = player.$throwordered(card.copy(), true); + } + if (lib.cardOL) lib.cardOL[cardid] = event.node; + event.node.cardid = cardid; + event.node.classList.add("thrownhighlight"); + ui.arena.classList.add("thrownhighlight"); + event.dialog = ui.create.dialog(str); + event.dialog.classList.add("center"); + event.dialog.videoId = id; + }, + player, + event.card, + judgestr, + event.videoId, + get.id() + ); - game.log(player,'展示了',event.card); + game.log(player, "展示了", event.card); game.delay(2); - if(get.type(event.card,'trick')==get.type(trigger.getParent().card,'trick')){ - player.chooseTarget('选择获得此牌的角色').set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.du){ - if(target.hasSkillTag('nodu')) return 0; - return -att; - } - if(att>0){ - return att+Math.max(0,5-target.countCards('h')); - } - return att; - }).set('du',event.card.name=='du'); + if (get.type(event.card, "trick") == get.type(trigger.getParent().card, "trick")) { + player + .chooseTarget("选择获得此牌的角色") + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0; + return -att; + } + if (att > 0) { + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }) + .set("du", event.card.name == "du"); + } else { + event.disbool = true; + player + .chooseTarget( + "是否弃置攻击范围内包含你的一名角色区域内的一张牌?", + function (card, player, target) { + return ( + target.inRange(player) && + target.countDiscardableCards(player, "hej") > 0 + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe" }, player, player); + }); } - else{ - event.disbool=true; - player.chooseTarget('是否弃置攻击范围内包含你的一名角色区域内的一张牌?',function(card,player,target){ - return target.inRange(player)&&target.countDiscardableCards(player,'hej')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe'},player,player); - }); - } - "step 1" - if(event.disbool){ - if(result.bool){ - player.line(result.targets[0],'green'); - player.discardPlayerCard(result.targets[0],'hej',true); + "step 1"; + if (event.disbool) { + if (result.bool) { + player.line(result.targets[0], "green"); + player.discardPlayerCard(result.targets[0], "hej", true); } event.dialog.close(); - game.addVideo('judge2',null,event.videoId); - game.addVideo('deletenode',player,[get.cardInfo(event.node)]); + game.addVideo("judge2", null, event.videoId); + game.addVideo("deletenode", player, [get.cardInfo(event.node)]); event.node.delete(); - game.broadcast(function(id,card){ - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - if(card.clone){ - card.clone.delete(); - } - ui.arena.classList.remove('thrownhighlight'); - },event.videoId,event.card); - ui.arena.classList.remove('thrownhighlight'); - } - else if(result.targets){ + game.broadcast( + function (id, card) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + if (card.clone) { + card.clone.delete(); + } + ui.arena.classList.remove("thrownhighlight"); + }, + event.videoId, + event.card + ); + ui.arena.classList.remove("thrownhighlight"); + } else if (result.targets) { event.dialog.close(); - game.addVideo('judge2',null,event.videoId); - player.line(result.targets,'green'); - result.targets[0].gain(event.card,'log'); + game.addVideo("judge2", null, event.videoId); + player.line(result.targets, "green"); + result.targets[0].gain(event.card, "log"); event.node.moveDelete(result.targets[0]); - game.addVideo('gain2',result.targets[0],[get.cardInfo(event.node)]); - ui.arena.classList.remove('thrownhighlight'); - game.broadcast(function(card,target,id){ - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - ui.arena.classList.remove('thrownhighlight'); - if(card.clone){ - card.clone.moveDelete(target); - } - },event.card,result.targets[0],event.videoId); - } - else{ - game.addVideo('deletenode',player,[get.cardInfo(event.node)]); + game.addVideo("gain2", result.targets[0], [get.cardInfo(event.node)]); + ui.arena.classList.remove("thrownhighlight"); + game.broadcast( + function (card, target, id) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + ui.arena.classList.remove("thrownhighlight"); + if (card.clone) { + card.clone.moveDelete(target); + } + }, + event.card, + result.targets[0], + event.videoId + ); + } else { + game.addVideo("deletenode", player, [get.cardInfo(event.node)]); event.node.delete(); - game.broadcast(function(id){ - var dialog=get.idDialog(id); - if(dialog){ - dialog.close(); - } - if(card.clone){ - card.clone.delete(); - } - ui.arena.classList.remove('thrownhighlight'); - },event.videoId,event.card); + game.broadcast( + function (id) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + if (card.clone) { + card.clone.delete(); + } + ui.arena.classList.remove("thrownhighlight"); + }, + event.videoId, + event.card + ); event.dialog.close(); - game.addVideo('judge2',null,event.videoId); - ui.arena.classList.remove('thrownhighlight'); + game.addVideo("judge2", null, event.videoId); + ui.arena.classList.remove("thrownhighlight"); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'respond')&&target.countCards('h')>1) return [1,0.2]; - } - } - } - }, - olpaoxiao:{ - audio:"paoxiao", - audioname:['re_zhangfei','guanzhang','xiahouba','re_guanzhang'], - trigger:{player:'shaMiss'}, - forced:true, - content:function(){ - player.addTempSkill('olpaoxiao2'); - player.addMark('olpaoxiao2',1,false); - }, - mod:{ - cardUsable:function (card,player,num){ - if(card.name=='sha') return Infinity; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "respond") && target.countCards("h") > 1) return [1, 0.2]; + }, }, }, }, - olpaoxiao2:{ - trigger:{source:'damageBegin1'}, - forced:true, - audio:'paoxiao', - audioname:['re_zhangfei','guanzhang','xiahouba','re_guanzhang'], - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.countMark('olpaoxiao2')>0; + olpaoxiao: { + audio: "paoxiao", + audioname: ["re_zhangfei", "guanzhang", "xiahouba", "re_guanzhang"], + trigger: { player: "shaMiss" }, + forced: true, + content: function () { + player.addTempSkill("olpaoxiao2"); + player.addMark("olpaoxiao2", 1, false); }, - onremove:true, - content:function(){ - trigger.num+=player.countMark('olpaoxiao2'); - player.removeSkill('olpaoxiao2'); + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return Infinity; + }, }, - intro:{content:'本回合内下一次使用【杀】造成伤害时令伤害值+#'}, }, - oltishen:{ - audio:'retishen', - unique:true, - mark:true, - skillAnimation:true, - animationColor:'soil', - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(player.storage.oltishen) return false; + olpaoxiao2: { + trigger: { source: "damageBegin1" }, + forced: true, + audio: "paoxiao", + audioname: ["re_zhangfei", "guanzhang", "xiahouba", "re_guanzhang"], + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.countMark("olpaoxiao2") > 0; + }, + onremove: true, + content: function () { + trigger.num += player.countMark("olpaoxiao2"); + player.removeSkill("olpaoxiao2"); + }, + intro: { content: "本回合内下一次使用【杀】造成伤害时令伤害值+#" }, + }, + oltishen: { + audio: "retishen", + unique: true, + mark: true, + skillAnimation: true, + animationColor: "soil", + limited: true, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (player.storage.oltishen) return false; return player.isDamaged(); }, - check:function(event,player){ - if(player.hp<=2||player.getDamagedHp()>2) return true; - if(player.getDamagedHp()<=1) return false; - return player.getDamagedHp() 2) return true; + if (player.getDamagedHp() <= 1) return false; + return player.getDamagedHp() < game.roundNumber; }, - content:function(){ - player.awakenSkill('oltishen'); - player.recover(player.maxHp-player.hp); - player.draw(player.maxHp-player.hp); + content: function () { + player.awakenSkill("oltishen"); + player.recover(player.maxHp - player.hp); + player.draw(player.maxHp - player.hp); }, - intro:{ - content:'limited' + intro: { + content: "limited", }, }, - rexuanfeng:{ - audio:'xuanfeng', - audioname:['boss_lvbu3','re_heqi','re_lingtong'], - trigger:{ - player:['loseAfter','phaseDiscardEnd'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + rexuanfeng: { + audio: "xuanfeng", + audioname: ["boss_lvbu3", "re_heqi", "re_lingtong"], + trigger: { + player: ["loseAfter", "phaseDiscardEnd"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - if(!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - })) return false; - if(event.name=='phaseDiscard'){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt&&evt.type=='discard'&&evt.getParent('phaseDiscard')==event&&evt.hs) cards.addArray(evt.hs); + direct: true, + filter: function (event, player) { + if ( + !game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; + }) + ) + return false; + if (event.name == "phaseDiscard") { + var cards = []; + player.getHistory("lose", function (evt) { + if ( + evt && + evt.type == "discard" && + evt.getParent("phaseDiscard") == event && + evt.hs + ) + cards.addArray(evt.hs); }); - return cards.length>1; + return cards.length > 1; } - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; }, - content:function(){ - 'step 0' - var list=['弃置至多两名其他角色的合计两张牌']; - if(lib.skill.rexuanfeng.canMoveCard(player)) list.push('将一名其他角色装备区内的一张牌移动到另一名角色的装备区内'); - player.chooseControl('cancel2').set('choiceList',list).set('prompt',get.prompt('rexuanfeng')).set('ai',function(){ - if(lib.skill.rexuanfeng.canMoveCard(player,true)) return 1; - return 0; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('rexuanfeng'); - if(result.index==1) event.goto(5); - else event.count=2; - } - else event.finish(); - 'step 2' - player.chooseTarget('弃置一名其他角色的一张牌',function(card,player,target){ - if(player==target) return false; - return target.countDiscardableCards(player,'he'); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - 'step 3' - if(result.bool){ - player.line(result.targets[0],'green'); - player.discardPlayerCard(result.targets[0],'he',true); + content: function () { + "step 0"; + var list = ["弃置至多两名其他角色的合计两张牌"]; + if (lib.skill.rexuanfeng.canMoveCard(player)) + list.push("将一名其他角色装备区内的一张牌移动到另一名角色的装备区内"); + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("prompt", get.prompt("rexuanfeng")) + .set("ai", function () { + if (lib.skill.rexuanfeng.canMoveCard(player, true)) return 1; + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("rexuanfeng"); + if (result.index == 1) event.goto(5); + else event.count = 2; + } else event.finish(); + "step 2"; + player + .chooseTarget("弃置一名其他角色的一张牌", function (card, player, target) { + if (player == target) return false; + return target.countDiscardableCards(player, "he"); + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 3"; + if (result.bool) { + player.line(result.targets[0], "green"); + player.discardPlayerCard(result.targets[0], "he", true); event.count--; - } + } else event.finish(); + "step 4"; + if (event.count) event.goto(2); else event.finish(); - 'step 4' - if(event.count) event.goto(2); - else event.finish(); - 'step 5' - var next=player.chooseTarget(2,function(card,player,target){ - if(player==target) return false; - if(ui.selected.targets.length){ - var from=ui.selected.targets[0]; - if(target.isMin()) return false; - var es=from.getCards('e'); - for(var i=0;i0; + } else { + return target.countCards("e") > 0; } }); - next.set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - var sgnatt=get.sgn(att); - if(ui.selected.targets.length==0){ - if(att>0){ - if(target.countCards('e',function(card){ - return get.value(card,target)<0&&game.hasPlayer(function(current){ - return current!=player&¤t!=target&&get.attitude(player,current)<0&¤t.canEquip(card)&&get.effect(current,card,player,player)>0; - }); - })>0) return 9; - } - else if(att<0){ - if(game.hasPlayer(function(current){ - if(current!=target&¤t!=player&&get.attitude(player,current)>0){ - var es=target.getCards('e'); - for(var i=0;i0&¤t.canEquip(es[i])&&get.effect(current,es[i],player,player)>0) return true; + next.set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var sgnatt = get.sgn(att); + if (ui.selected.targets.length == 0) { + if (att > 0) { + if ( + target.countCards("e", function (card) { + return ( + get.value(card, target) < 0 && + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + get.attitude(player, current) < 0 && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ); + }) > 0 + ) + return 9; + } else if (att < 0) { + if ( + game.hasPlayer(function (current) { + if ( + current != target && + current != player && + get.attitude(player, current) > 0 + ) { + var es = target.getCards("e"); + for (var i = 0; i < es.length; i++) { + if ( + get.value(es[i], target) > 0 && + current.canEquip(es[i]) && + get.effect(current, es[i], player, player) > 0 + ) + return true; + } } - } - })){ + }) + ) { return -att; } } return 0; } - var es=ui.selected.targets[0].getCards('e'); + var es = ui.selected.targets[0].getCards("e"); var i; - var att2=get.sgn(get.attitude(player,ui.selected.targets[0])); - for(i=0;iget.attitude(player,targets1)){ - if(get.value(button.link,targets0)<0) return get.effect(targets1,button.link,player,player); - return 0; - } - else{ - return get.value(button.link,targets0)*get.effect(targets1,button.link,player,player); - } - },targets[0]).set('targets0',targets[0]).set('targets1',targets[1]).set('filterButton',function(button){ - var targets1=_status.event.targets1; - return targets1.canEquip(button.link); - }); - } - else{ + "step 8"; + if (targets.length == 2) { + player + .choosePlayerCard( + "e", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if (get.attitude(player, targets0) > get.attitude(player, targets1)) { + if (get.value(button.link, targets0) < 0) + return get.effect(targets1, button.link, player, player); + return 0; + } else { + return ( + get.value(button.link, targets0) * + get.effect(targets1, button.link, player, player) + ); + } + }, + targets[0] + ) + .set("targets0", targets[0]) + .set("targets1", targets[1]) + .set("filterButton", function (button) { + var targets1 = _status.event.targets1; + return targets1.canEquip(button.link); + }); + } else { event.finish(); } - 'step 9' - if(result.bool&&result.links.length){ - var link=result.links[0]; + "step 9"; + if (result.bool && result.links.length) { + var link = result.links[0]; event.targets[1].equip(link); - event.targets[0].$give(link,event.targets[1]) + event.targets[0].$give(link, event.targets[1]); game.delay(); - event.result={bool:true}; + event.result = { bool: true }; } }, - canMoveCard:function(player,withatt){ - return game.hasPlayer(function(current){ - if(player==current) return false; - var att=get.sgn(get.attitude(player,current)); - if(!withatt||att!=0){ - var es=current.getCards('e'); - for(var i=0;i0&&(_status.connectMode||player.countCards('h','sha')>0)&&!player.getExpansions('rechunlao').length; + rechunlao: { + trigger: { player: "phaseUseEnd" }, + direct: true, + audio: 2, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + (_status.connectMode || player.countCards("h", "sha") > 0) && + !player.getExpansions("rechunlao").length + ); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - 'step 0' - player.chooseCard([1,Math.max(1,player.countCards('h','sha'))],get.prompt('rechunlao'),'将任意张【杀】置于武将牌上作为“醇”',{name:'sha'}).set('ai',function(){ - return 1; - }); - 'step 1' - if(result.bool){ - player.logSkill('rechunlao'); - player.addToExpansion('gain2',result.cards).gaintag.add('rechunlao'); + content: function () { + "step 0"; + player + .chooseCard( + [1, Math.max(1, player.countCards("h", "sha"))], + get.prompt("rechunlao"), + "将任意张【杀】置于武将牌上作为“醇”", + { name: "sha" } + ) + .set("ai", function () { + return 1; + }); + "step 1"; + if (result.bool) { + player.logSkill("rechunlao"); + player.addToExpansion("gain2", result.cards).gaintag.add("rechunlao"); } }, - ai:{ - threaten:1.4 + ai: { + threaten: 1.4, }, - group:'rechunlao2' + group: "rechunlao2", }, - rechunlao2:{ - enable:'chooseToUse', - filter:function(event,player){ - return event.type=='dying'&&event.dying&&event.dying.hp<=0&&player.getExpansions('rechunlao').length>0; + rechunlao2: { + enable: "chooseToUse", + filter: function (event, player) { + return ( + event.type == "dying" && + event.dying && + event.dying.hp <= 0 && + player.getExpansions("rechunlao").length > 0 + ); }, - filterTarget:function(card,player,target){ - return target==_status.event.dying; + filterTarget: function (card, player, target) { + return target == _status.event.dying; }, - direct:true, - delay:false, - selectTarget:-1, - content:function(){ - "step 0" - player.chooseCardButton(get.translation('rechunlao'),player.getExpansions('rechunlao'),true); - "step 1" - if(result.bool){ - player.logSkill('rechunlao'); - event.type='dying'; + direct: true, + delay: false, + selectTarget: -1, + content: function () { + "step 0"; + player.chooseCardButton( + get.translation("rechunlao"), + player.getExpansions("rechunlao"), + true + ); + "step 1"; + if (result.bool) { + player.logSkill("rechunlao"); + event.type = "dying"; player.loseToDiscardpile(result.links); - target.useCard({name:'jiu',isCard:true},target); - var natures=get.natureList(result.links[0]); - if(natures.includes('fire')) player.recover(); - if(natures.includes('thunder')) player.draw(2); + target.useCard({ name: "jiu", isCard: true }, target); + var natures = get.natureList(result.links[0]); + if (natures.includes("fire")) player.recover(); + if (natures.includes("thunder")) player.draw(2); } }, - ai:{ - order:6, - skillTagFilter:function(player){ - return player.getExpansions('rechunlao').length>0; + ai: { + order: 6, + skillTagFilter: function (player) { + return player.getExpansions("rechunlao").length > 0; }, - save:true, - result:{ - target:3 + save: true, + result: { + target: 3, }, - threaten:1.6 + threaten: 1.6, }, }, - reluoying:{ - audio:2, - audioname:['dc_caozhi'], - group:['reluoying_discard','reluoying_judge'], - subfrequent:['judge'], - subSkill:{ - discard:{ - audio:'reluoying', - audioname:['dc_caozhi'], - trigger:{global:['loseAfter','loseAsyncAfter']}, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - var cards=event.cards.slice(0); - var evt=event.getl(player); - if(evt&&evt.cards) cards.removeArray(evt.cards); - for(var i=0;i=7) return true; - player.getAllHistory('damage',function(evt){ - num+=evt.num; - }); - return num>7; + }, + }, }, - content:function(){ - player.markSkill('rejiushi_mark'); - player.awakenSkill('chengzhang'); - player.storage.chengzhang=true; + }, + chengzhang: { + trigger: { player: "phaseZhunbeiBegin" }, + derivation: "rejiushi_mark", + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "water", + filter: function (event, player) { + var num = 0; + player.getAllHistory("sourceDamage", function (evt) { + num += evt.num; + }); + if (num >= 7) return true; + player.getAllHistory("damage", function (evt) { + num += evt.num; + }); + return num > 7; + }, + content: function () { + player.markSkill("rejiushi_mark"); + player.awakenSkill("chengzhang"); + player.storage.chengzhang = true; player.recover(); player.draw(); }, }, - rejiushi:{ - audio:2, - audioname:['mb_caomao'], - group:['rejiushi1','rejiushi2','rejiushi3','rejiushi_gain'], - subfrequent:['gain'], - subSkill:{ - gain:{ - audio:'rejiushi', - trigger:{player:'turnOverAfter'}, - frequent:true, - filter:function(event,player){ - return player.storage.chengzhang==true; + rejiushi: { + audio: 2, + audioname: ["mb_caomao"], + group: ["rejiushi1", "rejiushi2", "rejiushi3", "rejiushi_gain"], + subfrequent: ["gain"], + subSkill: { + gain: { + audio: "rejiushi", + trigger: { player: "turnOverAfter" }, + frequent: true, + filter: function (event, player) { + return player.storage.chengzhang == true; }, - prompt:'是否发动【酒诗】,获得牌堆中的一张锦囊牌?', - content:function(){ - var card=get.cardPile2(function(card){ - return get.type2(card)=='trick'; + prompt: "是否发动【酒诗】,获得牌堆中的一张锦囊牌?", + content: function () { + var card = get.cardPile2(function (card) { + return get.type2(card) == "trick"; }); - if(card) player.gain(card,'gain2','log'); + if (card) player.gain(card, "gain2", "log"); }, }, }, }, - rejiushi1:{ - hiddenCard:function(player,name){ - if(name=='jiu') return !player.isTurnedOver(); + rejiushi1: { + hiddenCard: function (player, name) { + if (name == "jiu") return !player.isTurnedOver(); return false; }, - audio:'rejiushi', - audioname:['mb_caomao'], - enable:'chooseToUse', - filter:function(event,player){ - if(player.classList.contains('turnedover')) return false; - return event.filterCard({name:'jiu',isCard:true},player,event); + audio: "rejiushi", + audioname: ["mb_caomao"], + enable: "chooseToUse", + filter: function (event, player) { + if (player.classList.contains("turnedover")) return false; + return event.filterCard({ name: "jiu", isCard: true }, player, event); }, - content:function(){ - if(_status.event.getParent(2).type=='dying'){ - event.dying=player; - event.type='dying'; + content: function () { + if (_status.event.getParent(2).type == "dying") { + event.dying = player; + event.type = "dying"; } player.turnOver(); - player.useCard({name:'jiu',isCard:true},player); + player.useCard({ name: "jiu", isCard: true }, player); }, - ai:{ - order:5, - result:{ - player:function(player){ - if(_status.event.parent.name=='phaseUse'){ - if(player.countCards('h','jiu')>0) return 0; - if(player.getEquip('zhuge')&&player.countCards('h','sha')>1) return 0; - if(!player.countCards('h','sha')) return 0; - var targets=[]; + ai: { + order: 5, + result: { + player: function (player) { + if (_status.event.parent.name == "phaseUse") { + if (player.countCards("h", "jiu") > 0) return 0; + if (player.getEquip("zhuge") && player.countCards("h", "sha") > 1) return 0; + if (!player.countCards("h", "sha")) return 0; + var targets = []; var target; - var players=game.filterPlayer(); - for(var i=0;inum){ - target=targets[i]; - num=num2; + var num = get.effect(target, { name: "sha" }, player, player); + for (var i = 1; i < targets.length; i++) { + var num2 = get.effect(targets[i], { name: "sha" }, player, player); + if (num2 > num) { + target = targets[i]; + num = num2; } } - if(num<=0) return 0; - var e2=target.getEquip(2); - if(e2){ - if(e2.name=='tengjia'){ - if(!player.countCards('h',{name:'sha',nature:'fire'})&&!player.getEquip('zhuque')) return 0; + if (num <= 0) return 0; + var e2 = target.getEquip(2); + if (e2) { + if (e2.name == "tengjia") { + if ( + !player.countCards("h", { name: "sha", nature: "fire" }) && + !player.getEquip("zhuque") + ) + return 0; } - if(e2.name=='renwang'){ - if(!player.countCards('h',{name:'sha',color:'red'})) return 0; + if (e2.name == "renwang") { + if (!player.countCards("h", { name: "sha", color: "red" })) return 0; } - if(e2.name=='baiyin') return 0; + if (e2.name == "baiyin") return 0; } - if(player.getEquip('guanshi')&&player.countCards('he')>2) return 1; - return target.countCards('h')>3?0:1; + if (player.getEquip("guanshi") && player.countCards("he") > 2) return 1; + return target.countCards("h") > 3 ? 0 : 1; } - if(player==_status.event.dying||player.isTurnedOver()) return 3; - } + if (player == _status.event.dying || player.isTurnedOver()) return 3; + }, }, - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,0.5]; - if(target.isTurnedOver()){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp==1) return; - return [1,target.countCards('h')/2]; + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 0.5]; + if (target.isTurnedOver()) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (target.hp == 1) return; + return [1, target.countCards("h") / 2]; } } - } - } + }, + }, }, }, - rejiushi2:{ - trigger:{player:'damageBegin3'}, - silent:true, - firstDo:true, - filter:function(event,player){ - return player.classList.contains('turnedover'); + rejiushi2: { + trigger: { player: "damageBegin3" }, + silent: true, + firstDo: true, + filter: function (event, player) { + return player.classList.contains("turnedover"); + }, + content: function () { + trigger.rejiushi = true; }, - content:function(){ - trigger.rejiushi=true; - } }, - rejiushi3:{ - audio:'rejiushi', - trigger:{player:'damageEnd'}, - check:function(event,player){ + rejiushi3: { + audio: "rejiushi", + trigger: { player: "damageEnd" }, + check: function (event, player) { return player.isTurnedOver(); }, - filter:function(event,player){ - if(event.rejiushi){ + filter: function (event, player) { + if (event.rejiushi) { return true; } return false; }, - prompt:function(event,player){ - var str='是否发动【酒诗】,将武将牌翻面'; - if(!player.storage.chengzhang) str+=',并获得牌堆中的一张锦囊牌'; - str+='?' + prompt: function (event, player) { + var str = "是否发动【酒诗】,将武将牌翻面"; + if (!player.storage.chengzhang) str += ",并获得牌堆中的一张锦囊牌"; + str += "?"; return str; }, - content:function(){ + content: function () { delete trigger.rejiushi; player.turnOver(); - if(!player.storage.chengzhang){ - var card=get.cardPile2(function(card){ - return get.type2(card)=='trick'; + if (!player.storage.chengzhang) { + var card = get.cardPile2(function (card) { + return get.type2(card) == "trick"; }); - if(card) player.gain(card,'gain2','log'); - } - } - }, - rejiushi_mark:{ - mark:true, - marktext:'改', - intro:{ - content:'当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面。当你翻面时,你获得牌堆中的一张随机锦囊。', - }, - }, - rehongyan:{ - audio:2, - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'heart'; + if (card) player.gain(card, "gain2", "log"); } }, - trigger:{player:'loseEnd'}, - filter:function(event,player){ - if(player==_status.currentPhase||!event.visible||player.hp<=player.countCards('h')) return false; - for(var i=0;iplayer.canSaveCard(card,player))) mindist++; - if(game.hasPlayer(function(current){ - return (get.distance(player,current)<=mindist&& - player.canUse('sha',current,false)&& - get.effect(current,{name:'sha'},player,player)>0); - })){ + ai: { + order: 14, + result: { + player: function (player) { + if (player.hp < 3) return false; + var mindist = player.hp; + if (player.countCards("hs", (card) => player.canSaveCard(card, player))) + mindist++; + if ( + game.hasPlayer(function (current) { + return ( + get.distance(player, current) <= mindist && + player.canUse("sha", current, false) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 1; } return 0; - } - } - } + }, + }, + }, }, - reqimou2:{ - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(typeof player.storage.reqimou2=='number'&&card.name=='sha'){ - return num+player.storage.reqimou2; + reqimou2: { + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (typeof player.storage.reqimou2 == "number" && card.name == "sha") { + return num + player.storage.reqimou2; } }, - globalFrom:function(from,to,distance){ - if(typeof from.storage.reqimou2=='number'){ - return distance-from.storage.reqimou2; + globalFrom: function (from, to, distance) { + if (typeof from.storage.reqimou2 == "number") { + return distance - from.storage.reqimou2; } - } - } - }, - olniepan:{ - audio:2, - unique:true, - enable:'chooseToUse', - mark:true, - skillAnimation:true, - limited:true, - animationColor:'orange', - init:function(player){ - player.storage.olniepan=false; + }, }, - filter:function(event,player){ - if(player.storage.olniepan) return false; - if(event.type=='dying'){ - if(player!=event.dying) return false; + }, + olniepan: { + audio: 2, + unique: true, + enable: "chooseToUse", + mark: true, + skillAnimation: true, + limited: true, + animationColor: "orange", + init: function (player) { + player.storage.olniepan = false; + }, + filter: function (event, player) { + if (player.storage.olniepan) return false; + if (event.type == "dying") { + if (player != event.dying) return false; return true; } return false; }, - content:function(){ - 'step 0' - player.awakenSkill('olniepan'); - player.storage.olniepan=true; - player.discard(player.getCards('hej')); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("olniepan"); + player.storage.olniepan = true; + player.discard(player.getCards("hej")); + "step 1"; player.link(false); - 'step 2' + "step 2"; player.turnOver(false); - 'step 3' + "step 3"; player.draw(3); - 'step 4' - if(player.hp<3){ - player.recover(3-player.hp); + "step 4"; + if (player.hp < 3) { + player.recover(3 - player.hp); } - 'step 5' - player.chooseControl('bazhen','olhuoji','olkanpo').set('prompt','选择获得一个技能').ai=function(){ - return ['olhuoji','bazhen'].randomGet(); + "step 5"; + player + .chooseControl("bazhen", "olhuoji", "olkanpo") + .set("prompt", "选择获得一个技能").ai = function () { + return ["olhuoji", "bazhen"].randomGet(); }; - 'step 6' + "step 6"; player.addSkills(result.control); }, - derivation:['bazhen','olhuoji','olkanpo'], - ai:{ - order:1, - skillTagFilter:function(player,tag,target){ - if(player!=target||player.storage.olniepan) return false; + derivation: ["bazhen", "olhuoji", "olkanpo"], + ai: { + order: 1, + skillTagFilter: function (player, tag, target) { + if (player != target || player.storage.olniepan) return false; }, - save:true, - result:{ - player:function(player){ - if(player.hp<=0) return 10; - if(player.hp<=2&&player.countCards('he')<=1) return 10; + save: true, + result: { + player: function (player) { + if (player.hp <= 0) return 10; + if (player.hp <= 2 && player.countCards("he") <= 1) return 10; return 0; - } + }, + }, + threaten: function (player, target) { + if (!target.storage.olniepan) return 0.6; }, - threaten:function(player,target){ - if(!target.storage.olniepan) return 0.6; - } }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - rewurong:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + rewurong: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - "step 0" - if(target.countCards('h')==0||player.countCards('h')==0){ + content: function () { + "step 0"; + if (target.countCards("h") == 0 || player.countCards("h") == 0) { event.finish(); return; } - "step 1" - var sendback=function(){ - if(_status.event!=event){ - return function(){ - event.resultOL=_status.event.resultOL; + "step 1"; + var sendback = function () { + if (_status.event != event) { + return function () { + event.resultOL = _status.event.resultOL; }; } }; - if(player.isOnline()){ + if (player.isOnline()) { player.wait(sendback); - event.ol=true; - player.send(function(){ - game.me.chooseCard(true).set('glow_result',true).ai=function(){ + event.ol = true; + player.send(function () { + game.me.chooseCard(true).set("glow_result", true).ai = function () { return Math.random(); }; game.resume(); }); - } - else{ - event.localPlayer=true; - var hasShan=!target.countCards('h','shan'); - player.chooseCard(true).set('glow_result',true).ai=function(card){ - if(hasShan&&get.name(card)=='sha') return 1; + } else { + event.localPlayer = true; + var hasShan = !target.countCards("h", "shan"); + player.chooseCard(true).set("glow_result", true).ai = function (card) { + if (hasShan && get.name(card) == "sha") return 1; return Math.random(); - } + }; } - if(target.isOnline()){ + if (target.isOnline()) { target.wait(sendback); - event.ol=true; - target.send(function(){ - var rand=Math.random()<0.4; - game.me.chooseCard(true).set('glow_result',true).ai=function(card){ - if(rand) return card.name=='shan'?1:0; - return card.name=='shan'?0:1; + event.ol = true; + target.send(function () { + var rand = Math.random() < 0.4; + game.me.chooseCard(true).set("glow_result", true).ai = function (card) { + if (rand) return card.name == "shan" ? 1 : 0; + return card.name == "shan" ? 0 : 1; }; game.resume(); }); + } else { + event.localTarget = true; } - else{ - event.localTarget=true; + "step 2"; + if (event.localPlayer) { + event.card1 = result.cards[0]; } - "step 2" - if(event.localPlayer){ - event.card1=result.cards[0]; - } - if(event.localTarget){ - var rand=Math.random()<0.4; - target.chooseCard(true).set('glow_result',true).ai=function(card){ - if(rand) return card.name=='shan'?1:0; - return card.name=='shan'?0:1; + if (event.localTarget) { + var rand = Math.random() < 0.4; + target.chooseCard(true).set("glow_result", true).ai = function (card) { + if (rand) return card.name == "shan" ? 1 : 0; + return card.name == "shan" ? 0 : 1; }; } - "step 3" - if(event.localTarget){ - event.card2=result.cards[0]; + "step 3"; + if (event.localTarget) { + event.card2 = result.cards[0]; } - if(!event.resultOL&&event.ol){ + if (!event.resultOL && event.ol) { game.pause(); } - "step 4" - try{ - if(!event.card1) event.card1=event.resultOL[player.playerid].cards[0]; - if(!event.card2) event.card2=event.resultOL[target.playerid].cards[0]; - if(!event.card1||!event.card2){ - throw('err'); + "step 4"; + try { + if (!event.card1) event.card1 = event.resultOL[player.playerid].cards[0]; + if (!event.card2) event.card2 = event.resultOL[target.playerid].cards[0]; + if (!event.card1 || !event.card2) { + throw "err"; } - } - catch(e){ + } catch (e) { console.log(e); event.finish(); return; } - game.broadcastAll(function(card1,card2){ - card1.classList.remove('glow'); - card2.classList.remove('glow'); - },event.card1,event.card2); - "step 5" - game.broadcastAll(function(){ - ui.arena.classList.add('thrownhighlight'); + game.broadcastAll( + function (card1, card2) { + card1.classList.remove("glow"); + card2.classList.remove("glow"); + }, + event.card1, + event.card2 + ); + "step 5"; + game.broadcastAll(function () { + ui.arena.classList.add("thrownhighlight"); }); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1,target,event.card2); + game.addVideo("thrownhighlight1"); + player.$compare(event.card1, target, event.card2); game.delay(4); - "step 6" - var next=game.createEvent('showCards'); - next.player=player; - next.cards=[event.card1]; - next.setContent('emptyEvent'); - game.log(player,'展示了',event.card1); - "step 7" - var next=game.createEvent('showCards'); - next.player=target; - next.cards=[event.card2]; - next.setContent('emptyEvent'); - game.log(target,'展示了',event.card2); - "step 8" - var name1=get.name(event.card1); - var name2=get.name(event.card2); - if(name1=='sha'&&name2!='shan'){ + "step 6"; + var next = game.createEvent("showCards"); + next.player = player; + next.cards = [event.card1]; + next.setContent("emptyEvent"); + game.log(player, "展示了", event.card1); + "step 7"; + var next = game.createEvent("showCards"); + next.player = target; + next.cards = [event.card2]; + next.setContent("emptyEvent"); + game.log(target, "展示了", event.card2); + "step 8"; + var name1 = get.name(event.card1); + var name2 = get.name(event.card2); + if (name1 == "sha" && name2 != "shan") { //player.discard(event.card1).set('animate',false); target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } - game.broadcast(function(card){ - var clone=card.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + game.broadcast(function (card) { + var clone = card.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); } - },event.card1); - target.damage('nocard'); - } - else if(name1!='sha'&&name2=='shan'){ + }, event.card1); + target.damage("nocard"); + } else if (name1 != "sha" && name2 == "shan") { //player.discard(event.card1).set('animate',false); target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } - game.broadcast(function(card){ - var clone=card.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + game.broadcast(function (card) { + var clone = card.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); } - },event.card1); - player.gainPlayerCard(target,true,'he'); - } - else{ + }, event.card1); + player.gainPlayerCard(target, true, "he"); + } else { player.$gain2(event.card1); target.$gain2(event.card2); } - game.broadcastAll(function(){ - ui.arena.classList.remove('thrownhighlight'); + game.broadcastAll(function () { + ui.arena.classList.remove("thrownhighlight"); }); - game.addVideo('thrownhighlight2'); + game.addVideo("thrownhighlight2"); }, - ai:{ - order:6, - result:{ - target:-1, - } - } - }, - cangzhuo:{ - trigger:{player:'phaseDiscardBegin'}, - frequent:true, - audio:2, - filter:function(event,player){ - return player.getHistory('useCard',function(card){ - return get.type(card.card,'trick')=='trick'; - }).length==0; - }, - content:function(){ - player.addTempSkill('cangzhuo2'); + ai: { + order: 6, + result: { + target: -1, + }, }, }, - cangzhuo2:{ - mod:{ - ignoredHandcard:function(card,player){ - if(get.type(card,'trick')=='trick'){ + cangzhuo: { + trigger: { player: "phaseDiscardBegin" }, + frequent: true, + audio: 2, + filter: function (event, player) { + return ( + player.getHistory("useCard", function (card) { + return get.type(card.card, "trick") == "trick"; + }).length == 0 + ); + }, + content: function () { + player.addTempSkill("cangzhuo2"); + }, + }, + cangzhuo2: { + mod: { + ignoredHandcard: function (card, player) { + if (get.type(card, "trick") == "trick") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.type(card,'trick')=='trick') return false; - } + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.type(card, "trick") == "trick") return false; + }, }, }, - shebian:{ - trigger:{player:'turnOverEnd'}, - check:function(event,player){ - return player.canMoveCard(true,true); + shebian: { + trigger: { player: "turnOverEnd" }, + check: function (event, player) { + return player.canMoveCard(true, true); }, - filter:function(event,player){ - return player.canMoveCard(null,true); + filter: function (event, player) { + return player.canMoveCard(null, true); }, - content:function(){ - player.moveCard().nojudge=true; + content: function () { + player.moveCard().nojudge = true; }, }, - rexianzhen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + rexianzhen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.player&&get.name(result.player,player)=='sha') player.addTempSkill('rexianzhen4'); - if(result.bool){ - player.storage[event.name]=target; - player.addTempSkill(event.name+2); - } - else{ - player.addTempSkill(event.name+3); + "step 1"; + if (result.player && get.name(result.player, player) == "sha") + player.addTempSkill("rexianzhen4"); + if (result.bool) { + player.storage[event.name] = target; + player.addTempSkill(event.name + 2); + } else { + player.addTempSkill(event.name + 3); } }, - ai:{ - order:function(name,player){ - var cards=player.getCards('h'); - if(player.countCards('h','sha')==0){ + ai: { + order: function (name, player) { + var cards = player.getCards("h"); + if (player.countCards("h", "sha") == 0) { return 1; } - for(var i=0;i11&&get.value(cards[i])<7){ + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].name != "sha" && + get.number(cards[i]) > 11 && + get.value(cards[i]) < 7 + ) { return 9; } } - return get.order({name:'sha'})-1; + return get.order({ name: "sha" }) - 1; }, - result:{ - player:function(player){ - if(player.countCards('h','sha')>0) return 0; - var num=player.countCards('h'); - if(num>player.hp) return 0; - if(num==1) return -2; - if(num==2) return -1; + result: { + player: function (player) { + if (player.countCards("h", "sha") > 0) return 0; + var num = player.countCards("h"); + if (num > player.hp) return 0; + if (num == 1) return -2; + if (num == 2) return -1; return -0.7; }, - target:function(player,target){ - var num=target.countCards('h'); - if(num==1) return -1; - if(num==2) return -0.7; - return -0.5 + target: function (player, target) { + var num = target.countCards("h"); + if (num == 1) return -1; + if (num == 2) return -0.7; + return -0.5; }, }, - threaten:1.3 - } - }, - rexianzhen2:{ - charlotte:true, - mod:{ - targetInRange:function(card,player,target){ - if(target==player.storage.rexianzhen) return true; - }, - cardUsableTarget:function(card,player,target){ - if(target==player.storage.rexianzhen) return true; - } + threaten: 1.3, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(arg.target!=player.storage.rexianzhen) return false; + }, + rexianzhen2: { + charlotte: true, + mod: { + targetInRange: function (card, player, target) { + if (target == player.storage.rexianzhen) return true; }, - } + cardUsableTarget: function (card, player, target) { + if (target == player.storage.rexianzhen) return true; + }, + }, + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (arg.target != player.storage.rexianzhen) return false; + }, + }, }, - rexianzhen3:{ - charlotte:true, - mod:{ - cardEnabled:function(card){if(card.name=='sha') return false} - } + rexianzhen3: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, }, - rexianzhen4:{ - mod:{ - ignoredHandcard:function(card,player){ - if(get.name(card)=='sha'){ + rexianzhen4: { + mod: { + ignoredHandcard: function (card, player) { + if (get.name(card) == "sha") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.name(card)=='sha'){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.name(card) == "sha") { return false; } }, }, }, - rejinjiu:{ - mod:{ - cardname:function(card,player){ - if(card.name=='jiu') return 'sha'; + rejinjiu: { + mod: { + cardname: function (card, player) { + if (card.name == "jiu") return "sha"; }, }, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('h','jiu')) return false; + ai: { + skillTagFilter: function (player) { + if (!player.countCards("h", "jiu")) return false; }, - respondSha:true, + respondSha: true, }, - audio:2, - trigger:{player:['useCard1','respond']}, - firstDo:true, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.skill&& - event.cards.length==1&&event.cards[0].name=='jiu'; + audio: 2, + trigger: { player: ["useCard1", "respond"] }, + firstDo: true, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !event.skill && + event.cards.length == 1 && + event.cards[0].name == "jiu" + ); }, - content:function(){}, - group:'rejinjiu2', - global:'rejinjiu3', + content: function () {}, + group: "rejinjiu2", + global: "rejinjiu3", }, - rejinjiu3:{ - mod:{ - cardEnabled:function(card,player){ - if(card.name=='jiu'&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('rejinjiu')) return false; + rejinjiu3: { + mod: { + cardEnabled: function (card, player) { + if ( + card.name == "jiu" && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("rejinjiu") + ) + return false; }, - cardSavable:function(card,player){ - if(card.name=='jiu'&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('rejinjiu')) return false; + cardSavable: function (card, player) { + if ( + card.name == "jiu" && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("rejinjiu") + ) + return false; }, }, }, - rejinjiu2:{ - audio:'rejinjiu', - forced:true, - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - return event.getParent(2).jiu==true; + rejinjiu2: { + audio: "rejinjiu", + forced: true, + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + return event.getParent(2).jiu == true; }, - content:function(){ - trigger.num-=trigger.getParent(2).jiu_add; + content: function () { + trigger.num -= trigger.getParent(2).jiu_add; }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - return arg&&arg.jiu==true; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + return arg && arg.jiu == true; }, }, }, - repojun:{ - shaRelated:true, - audio:2, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.hp>0&&event.target.countCards('he')>0; + repojun: { + shaRelated: true, + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && event.target.hp > 0 && event.target.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - var next=player.choosePlayerCard(trigger.target,'he',[1,Math.min(trigger.target.hp,trigger.target.countCards('he'))],get.prompt('repojun',trigger.target)); - next.set('ai',function(button){ - if(!_status.event.goon) return 0; - var val=get.value(button.link); - if(button.link==_status.event.target.getEquip(2)) return 2*(val+3); + content: function () { + "step 0"; + var next = player.choosePlayerCard( + trigger.target, + "he", + [1, Math.min(trigger.target.hp, trigger.target.countCards("he"))], + get.prompt("repojun", trigger.target) + ); + next.set("ai", function (button) { + if (!_status.event.goon) return 0; + var val = get.value(button.link); + if (button.link == _status.event.target.getEquip(2)) return 2 * (val + 3); return val; }); - next.set('goon',get.attitude(player,trigger.target)<=0); - next.set('forceAuto',true); - 'step 1' - if(result.bool){ - var target=trigger.target; - player.logSkill('repojun',target); - target.addSkill('repojun2'); - target.addToExpansion('giveAuto',result.cards,target).gaintag.add('repojun2'); + next.set("goon", get.attitude(player, trigger.target) <= 0); + next.set("forceAuto", true); + "step 1"; + if (result.bool) { + var target = trigger.target; + player.logSkill("repojun", target); + target.addSkill("repojun2"); + target.addToExpansion("giveAuto", result.cards, target).gaintag.add("repojun2"); } }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)>0) return false; - if(tag=='directHit_ai') return arg.target.hp>=Math.max(1,arg.target.countCards('h')-1); - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (get.attitude(player, arg.target) > 0) return false; + if (tag == "directHit_ai") + return arg.target.hp >= Math.max(1, arg.target.countCards("h") - 1); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } + }, }, - group:'repojun3', + group: "repojun3", }, - repojun3:{ - audio:'repojun', - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - var target=event.player; - return event.card&&event.card.name=='sha'&&player.countCards('h')>=target.countCards('h')&&player.countCards('e')>=target.countCards('e'); + repojun3: { + audio: "repojun", + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + var target = event.player; + return ( + event.card && + event.card.name == "sha" && + player.countCards("h") >= target.countCards("h") && + player.countCards("e") >= target.countCards("e") + ); }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ + forced: true, + locked: false, + logTarget: "player", + content: function () { trigger.num++; }, }, - repojun2:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('repojun2').length>0; + repojun2: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("repojun2").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('repojun2'); - player.gain(cards,'draw'); - game.log(player,'收回了'+get.cnNumber(cards.length)+'张“破军”牌'); - 'step 1' - player.removeSkill('repojun2'); + content: function () { + "step 0"; + var cards = player.getExpansions("repojun2"); + player.gain(cards, "draw"); + game.log(player, "收回了" + get.cnNumber(cards.length) + "张“破军”牌"); + "step 1"; + player.removeSkill("repojun2"); }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('repojun2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("repojun2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, - sishu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('sishu')).ai=function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countMark('sishu2')%2==1) return -att; + sishu: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("sishu")).ai = function (target) { + var att = get.attitude(_status.event.player, target); + if (target.countMark("sishu2") % 2 == 1) return -att; return att; - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sishu',target) - target.addSkill('sishu2'); - target.addMark('sishu2',1,false); + }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sishu", target); + target.addSkill("sishu2"); + target.addMark("sishu2", 1, false); } }, }, - sishu2:{ - charlotte:true, - marktext:'思', - intro:{ - name:'思蜀', - content:'本局游戏内计算【乐不思蜀】的效果时反转#次', + sishu2: { + charlotte: true, + marktext: "思", + intro: { + name: "思蜀", + content: "本局游戏内计算【乐不思蜀】的效果时反转#次", }, - mod:{ - judge:function(player,result){ - if(_status.event.cardname=='lebu'&&player.countMark('sishu2')%2==1){ - if(result.bool==false){ - result.bool=true; - } - else{ - result.bool=false; + mod: { + judge: function (player, result) { + if (_status.event.cardname == "lebu" && player.countMark("sishu2") % 2 == 1) { + if (result.bool == false) { + result.bool = true; + } else { + result.bool = false; } } - } + }, }, }, - olruoyu:{ - skillAnimation:true, - animationColor:'fire', - audio:2, - unique:true, - juexingji:true, - zhuSkill:true, - keepSkill:true, - derivation:['rejijiang','sishu'], - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - if(!player.hasZhuSkill('olruoyu')) return false; + olruoyu: { + skillAnimation: true, + animationColor: "fire", + audio: 2, + unique: true, + juexingji: true, + zhuSkill: true, + keepSkill: true, + derivation: ["rejijiang", "sishu"], + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + if (!player.hasZhuSkill("olruoyu")) return false; return player.isMinHp(); }, - content:function(){ - 'step 0' - player.awakenSkill('olruoyu'); + content: function () { + "step 0"; + player.awakenSkill("olruoyu"); player.gainMaxHp(); - 'step 1' - if(player.hp<3) player.recover(3-player.hp); - player.addSkills(['sishu', 'rejijiang']); - } - }, - olfangquan:{ - audio:2, - audioname:['shen_caopi'], - trigger:{player:'phaseUseBefore'}, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkill('olfangquan3'); + "step 1"; + if (player.hp < 3) player.recover(3 - player.hp); + player.addSkills(["sishu", "rejijiang"]); }, - direct:true, - content:function(){ - "step 0" - var fang=player.countMark('olfangquan2')==0&&player.hp>=2&&player.countCards('h')<=player.hp+2; - player.chooseBool(get.prompt2('olfangquan')).set('ai',function(){ - if(!_status.event.fang) return false; - return game.hasPlayer(function(target){ - if(target.hasJudge('lebu')||target==player) return false; - if(get.attitude(player,target)>4){ - return (get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1)>0); - } - return false; - }); - }).set('fang',fang); - "step 1" - if(result.bool){ - player.logSkill('olfangquan'); + }, + olfangquan: { + audio: 2, + audioname: ["shen_caopi"], + trigger: { player: "phaseUseBefore" }, + filter: function (event, player) { + return player.countCards("h") > 0 && !player.hasSkill("olfangquan3"); + }, + direct: true, + content: function () { + "step 0"; + var fang = + player.countMark("olfangquan2") == 0 && + player.hp >= 2 && + player.countCards("h") <= player.hp + 2; + player + .chooseBool(get.prompt2("olfangquan")) + .set("ai", function () { + if (!_status.event.fang) return false; + return game.hasPlayer(function (target) { + if (target.hasJudge("lebu") || target == player) return false; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) > + 0 + ); + } + return false; + }); + }) + .set("fang", fang); + "step 1"; + if (result.bool) { + player.logSkill("olfangquan"); trigger.cancel(); - player.addTempSkill('olfangquan2'); - player.addMark('olfangquan2',1,false); + player.addTempSkill("olfangquan2"); + player.addMark("olfangquan2", 1, false); } - } + }, }, - olfangquan2:{ - trigger:{player:'phaseDiscardBegin'}, - forced:true, - popup:false, - audio:false, - onremove:true, - content:function(){ - "step 0" - event.count=player.countMark(event.name); - player.removeMark(event.name,event.count,false); - "step 1" + olfangquan2: { + trigger: { player: "phaseDiscardBegin" }, + forced: true, + popup: false, + audio: false, + onremove: true, + content: function () { + "step 0"; + event.count = player.countMark(event.name); + player.removeMark(event.name, event.count, false); + "step 1"; event.count--; - player.chooseToDiscard('是否弃置一张牌并令一名其他角色进行一个额外回合?').set('logSkill','olfangquan').ai=function(card){ - return 20-get.value(card); + player + .chooseToDiscard("是否弃置一张牌并令一名其他角色进行一个额外回合?") + .set("logSkill", "olfangquan").ai = function (card) { + return 20 - get.value(card); }; - "step 2" - if(result.bool){ - player.chooseTarget(true,'请选择进行额外回合的目标角色',lib.filter.notMe).ai=function(target){ - if(target.hasJudge('lebu')) return -1; - if(get.attitude(player,target)>4){ - return get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1); - } - return -1; - }; - } - else event.finish(); - "step 3" - var target=result.targets[0]; - player.line(target,'fire'); - target.markSkillCharacter('olfangquan',player,'放权','进行一个额外回合'); + "step 2"; + if (result.bool) { + player.chooseTarget(true, "请选择进行额外回合的目标角色", lib.filter.notMe).ai = + function (target) { + if (target.hasJudge("lebu")) return -1; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) + ); + } + return -1; + }; + } else event.finish(); + "step 3"; + var target = result.targets[0]; + player.line(target, "fire"); + target.markSkillCharacter("olfangquan", player, "放权", "进行一个额外回合"); target.insertPhase(); - target.addSkill('olfangquan3'); - if(event.count>0) event.goto(1); - } - }, - olfangquan3:{ - trigger:{player:['phaseAfter','phaseCancelled']}, - forced:true, - popup:false, - audio:false, - content:function(){ - player.unmarkSkill('olfangquan'); - player.removeSkill('olfangquan3'); - } - }, - olluanji:{ - inherit:'luanji', - audioname:['shen_caopi'], - audio:2, - line:false, - group:'olluanji_remove', - check:function(card){ - return 7-get.value(card); + target.addSkill("olfangquan3"); + if (event.count > 0) event.goto(1); }, }, - olluanji_remove:{ - trigger:{player:'useCard2'}, - direct:true, - filter:function(event,player){ - return event.card.name=='wanjian'&&event.targets.length>0; + olfangquan3: { + trigger: { player: ["phaseAfter", "phaseCancelled"] }, + forced: true, + popup: false, + audio: false, + content: function () { + player.unmarkSkill("olfangquan"); + player.removeSkill("olfangquan3"); }, - line:false, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olluanji'),'为'+get.translation(trigger.card)+'减少一个目标',function(card,player,target){ - return _status.event.targets.includes(target) - }).set('targets',trigger.targets).set('ai',function(target){ - var player=_status.event.player; - return -get.effect(target,_status.event.getTrigger().card,player,player) - }); - 'step 1' - if(result.bool){ - player.logSkill('olluanji',result.targets); + }, + olluanji: { + inherit: "luanji", + audioname: ["shen_caopi"], + audio: 2, + line: false, + group: "olluanji_remove", + check: function (card) { + return 7 - get.value(card); + }, + }, + olluanji_remove: { + trigger: { player: "useCard2" }, + direct: true, + filter: function (event, player) { + return event.card.name == "wanjian" && event.targets.length > 0; + }, + line: false, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olluanji"), + "为" + get.translation(trigger.card) + "减少一个目标", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", trigger.targets) + .set("ai", function (target) { + var player = _status.event.player; + return -get.effect(target, _status.event.getTrigger().card, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("olluanji", result.targets); trigger.targets.remove(result.targets[0]); } }, }, - olxueyi:{ - audio:2, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - zhuSkill:true, - unique:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.hasZhuSkill('olxueyi'); + olxueyi: { + audio: 2, + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + zhuSkill: true, + unique: true, + filter: function (event, player) { + return (event.name != "phase" || game.phaseNumber == 0) && player.hasZhuSkill("olxueyi"); }, - content:function(){ + content: function () { // player.storage.olxueyi_inited=true; - var num=game.countPlayer(function(current){ - return current.group=='qun'; - }) - if(num) player.addMark('olxueyi',num*2); + var num = game.countPlayer(function (current) { + return current.group == "qun"; + }); + if (num) player.addMark("olxueyi", num * 2); }, - marktext:'裔', - intro:{ - name2:'裔', - content:'mark', + marktext: "裔", + intro: { + name2: "裔", + content: "mark", }, - mod:{ - maxHandcard:function(player,num){ - if(player.hasZhuSkill('olxueyi')) return num+player.countMark('olxueyi'); + mod: { + maxHandcard: function (player, num) { + if (player.hasZhuSkill("olxueyi")) return num + player.countMark("olxueyi"); }, }, - group:'olxueyi_draw', + group: "olxueyi_draw", }, - olxueyi_draw:{ - audio:'olxueyi', - trigger:{player:'phaseUseBegin'}, - prompt2:'弃置一枚「裔」标记,然后摸一张牌', - check:function(event,player){ - return player.getUseValue('wanjian')>0||!player.needsToDiscard(); + olxueyi_draw: { + audio: "olxueyi", + trigger: { player: "phaseUseBegin" }, + prompt2: "弃置一枚「裔」标记,然后摸一张牌", + check: function (event, player) { + return player.getUseValue("wanjian") > 0 || !player.needsToDiscard(); }, - filter:function(event,player){ - return player.hasZhuSkill('olxueyi')&&player.hasMark('olxueyi'); + filter: function (event, player) { + return player.hasZhuSkill("olxueyi") && player.hasMark("olxueyi"); }, - content:function(){ - player.removeMark('olxueyi',1); + content: function () { + player.removeMark("olxueyi", 1); player.draw(); }, }, - olhunzi:{ - audio:2, - audioname:['re_sunyi'], - inherit:'hunzi', - content:function(){ + olhunzi: { + audio: 2, + audioname: ["re_sunyi"], + inherit: "hunzi", + content: function () { player.awakenSkill(event.name); player.loseMaxHp(); //player.recover(); - player.addSkills(['reyingzi','gzyinghun']); - player.addTempSkill('olhunzi_effect'); + player.addSkills(["reyingzi", "gzyinghun"]); + player.addTempSkill("olhunzi_effect"); }, - subSkill:{ - effect:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - player.chooseDrawRecover(2,true); + subSkill: { + effect: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + player.chooseDrawRecover(2, true); }, }, }, }, - olzhiba:{ - audio:2, - unique:true, - zhuSkill:true, - global:'olzhiba2', + olzhiba: { + audio: 2, + unique: true, + zhuSkill: true, + global: "olzhiba2", }, - olzhiba2:{ - ai:{ - order:1, - result:{ - target:function(player,target){ - if(player.hasZhuSkill('olzhiba')&&!player.hasSkill('olzhiba3')&&target.group=='wu'){ - if(player.countCards('h',function(card){ - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return get.number(card)>=12; - } - if(val<=6){ - return get.number(card)>=13; - } - return false; - })>0) return -1; + olzhiba2: { + ai: { + order: 1, + result: { + target: function (player, target) { + if ( + player.hasZhuSkill("olzhiba") && + !player.hasSkill("olzhiba3") && + target.group == "wu" + ) { + if ( + player.countCards("h", function (card) { + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return get.number(card) >= 12; + } + if (val <= 6) { + return get.number(card) >= 13; + } + return false; + }) > 0 + ) + return -1; return 0; - } - else{ - if(player.countCards('h','du')&&get.attitude(player,target)<0) return -1; - if(player.countCards('h')<=player.hp) return 0; - var maxnum=0; - var cards2=target.getCards('h'); - for(var i=0;imaxnum){ - maxnum=get.number(cards2[i]); + } else { + if (player.countCards("h", "du") && get.attitude(player, target) < 0) + return -1; + if (player.countCards("h") <= player.hp) return 0; + var maxnum = 0; + var cards2 = target.getCards("h"); + for (var i = 0; i < cards2.length; i++) { + if (get.number(cards2[i]) > maxnum) { + maxnum = get.number(cards2[i]); } } - if(maxnum>10) maxnum=10; - if(maxnum<5&&cards2.length>1) maxnum=5; - var cards=player.getCards('h'); - for(var i=0;i 10) maxnum = 10; + if (maxnum < 5 && cards2.length > 1) maxnum = 5; + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + if (get.number(cards[i]) < maxnum) return 1; } return 0; } }, }, }, - enable:'phaseUse', + enable: "phaseUse", //usable:1, - prompt:'请选择〖制霸〗的目标', - filter:function(event,player){ - if(player.hasZhuSkill('olzhiba')&&!player.hasSkill('olzhiba3')&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='wu'&&player.canCompare(current); - })) return true; - return (player.group=='wu'&&game.hasPlayer(function(current){ - return current!=player&¤t.hasZhuSkill('olzhiba',player)&&!current.hasSkill('olzhiba3')&&player.canCompare(current); - })); + prompt: "请选择〖制霸〗的目标", + filter: function (event, player) { + if ( + player.hasZhuSkill("olzhiba") && + !player.hasSkill("olzhiba3") && + game.hasPlayer(function (current) { + return current != player && current.group == "wu" && player.canCompare(current); + }) + ) + return true; + return ( + player.group == "wu" && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasZhuSkill("olzhiba", player) && + !current.hasSkill("olzhiba3") && + player.canCompare(current) + ); + }) + ); }, - filterTarget:function(card,player,target){ - if(player.hasZhuSkill('olzhiba')&&!player.hasSkill('olzhiba3')&&target.group=='wu'&&player.canCompare(target)) return true; - return player.group=='wu'&&target.hasZhuSkill('olzhiba',player)&&!target.hasSkill('olzhiba3')&&player.canCompare(target); + filterTarget: function (card, player, target) { + if ( + player.hasZhuSkill("olzhiba") && + !player.hasSkill("olzhiba3") && + target.group == "wu" && + player.canCompare(target) + ) + return true; + return ( + player.group == "wu" && + target.hasZhuSkill("olzhiba", player) && + !target.hasSkill("olzhiba3") && + player.canCompare(target) + ); }, - prepare:function(cards,player,targets){ - if(player.hasZhuSkill('olzhiba')) player.logSkill('olzhiba') - if(targets[0].hasZhuSkill('olzhiba',player)) targets[0].logSkill('olzhiba'); + prepare: function (cards, player, targets) { + if (player.hasZhuSkill("olzhiba")) player.logSkill("olzhiba"); + if (targets[0].hasZhuSkill("olzhiba", player)) targets[0].logSkill("olzhiba"); }, - direct:true, - clearTime:true, - contentBefore:function(){ - 'step 0' - var list=[]; - if(player.hasZhuSkill('olzhiba')&&targets[0].group=='wu'&&!player.hasSkill('olzhiba3')) list.push(player); - if(player.group=='wu'&&targets[0].hasZhuSkill('olzhiba')&&!targets[0].hasSkill('olzhiba3')) list.push(targets[0]); - if(list.length==1){ - event.target=list[0]; + direct: true, + clearTime: true, + contentBefore: function () { + "step 0"; + var list = []; + if ( + player.hasZhuSkill("olzhiba") && + targets[0].group == "wu" && + !player.hasSkill("olzhiba3") + ) + list.push(player); + if ( + player.group == "wu" && + targets[0].hasZhuSkill("olzhiba") && + !targets[0].hasSkill("olzhiba3") + ) + list.push(targets[0]); + if (list.length == 1) { + event.target = list[0]; event.goto(2); - } - else player.chooseTarget(true,'请选择获得所有拼点牌的角色',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',list); - 'step 1' - event.target=result.targets[0]; - 'step 2' - target.addTempSkill('olzhiba3','phaseUseEnd') - if(target==targets[0]){ - target.chooseBool('是否接受来自'+get.translation(player)+'的拼点请求?').set('choice',(get.attitude(target,player)>0||target.countCards('h',function(card){ - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return get.number(card)>=12; - } - if(val<=6){ - return get.number(card)>=13; - } - return false; - })>0)).set('ai',function(){return _status.event.choice}); - } - else event._result={bool:true}; - 'step 3' - if(result.bool) event.getParent().zhiba_target=target; - else{ - game.log(target,'拒绝了',player,'的拼点请求'); - target.chat('拒绝'); + } else + player + .chooseTarget( + true, + "请选择获得所有拼点牌的角色", + function (card, player, target) { + return _status.event.list.includes(target); + } + ) + .set("list", list); + "step 1"; + event.target = result.targets[0]; + "step 2"; + target.addTempSkill("olzhiba3", "phaseUseEnd"); + if (target == targets[0]) { + target + .chooseBool("是否接受来自" + get.translation(player) + "的拼点请求?") + .set( + "choice", + get.attitude(target, player) > 0 || + target.countCards("h", function (card) { + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return get.number(card) >= 12; + } + if (val <= 6) { + return get.number(card) >= 13; + } + return false; + }) > 0 + ) + .set("ai", function () { + return _status.event.choice; + }); + } else event._result = { bool: true }; + "step 3"; + if (result.bool) event.getParent().zhiba_target = target; + else { + game.log(target, "拒绝了", player, "的拼点请求"); + target.chat("拒绝"); } }, - content:function(){ - 'step 0' - event.source=event.getParent().zhiba_target; - if(!event.source){ + content: function () { + "step 0"; + event.source = event.getParent().zhiba_target; + if (!event.source) { event.finish(); } - 'step 1' - player.chooseToCompare(target).set('small',target==source&&get.attitude(player,target)>0).clear=false; - 'step 2' - if(player==source&&result.bool||target==source&&!result.bool){ - event.cards=[result.player,result.target].filterInD('d'); - if(!event.cards.length) event.finish(); - else source.chooseControl('ok','cancel2').set('dialog',['是否获得拼点牌?',event.cards]).set('ai',function(){ - if(get.value(event.cards,source,'raw')<=0) return false; - return true; - }); - } - else event.finish(); - 'step 3' - if(result.control!='cancel2') source.gain(event.cards,'gain2','log'); + "step 1"; + player + .chooseToCompare(target) + .set("small", target == source && get.attitude(player, target) > 0).clear = false; + "step 2"; + if ((player == source && result.bool) || (target == source && !result.bool)) { + event.cards = [result.player, result.target].filterInD("d"); + if (!event.cards.length) event.finish(); + else + source + .chooseControl("ok", "cancel2") + .set("dialog", ["是否获得拼点牌?", event.cards]) + .set("ai", function () { + if (get.value(event.cards, source, "raw") <= 0) return false; + return true; + }); + } else event.finish(); + "step 3"; + if (result.control != "cancel2") source.gain(event.cards, "gain2", "log"); else ui.clear(); }, }, - olzhiba3:{}, - rehuashen:{ - unique:true, - audio:2, - trigger:{ - global:'phaseBefore', - player:['enterGame','phaseBegin','phaseEnd','rehuashen'], + olzhiba3: {}, + rehuashen: { + unique: true, + audio: 2, + trigger: { + global: "phaseBefore", + player: ["enterGame", "phaseBegin", "phaseEnd", "rehuashen"], }, - filter:function(event,player,name){ - if(event.name!='phase') return true; - if(name=='phaseBefore') return game.phaseNumber==0; - return player.storage.rehuashen&&player.storage.rehuashen.character.length>0; + filter: function (event, player, name) { + if (event.name != "phase") return true; + if (name == "phaseBefore") return game.phaseNumber == 0; + return player.storage.rehuashen && player.storage.rehuashen.character.length > 0; }, - direct:true, - content:function(){ - "step 0" - var name=event.triggername; - if(trigger.name!='phase'||(name=='phaseBefore'&&game.phaseNumber==0)){ - player.logSkill('rehuashen'); - lib.skill.rehuashen.addHuashens(player,3); - event.logged=true; + direct: true, + content: function () { + "step 0"; + var name = event.triggername; + if (trigger.name != "phase" || (name == "phaseBefore" && game.phaseNumber == 0)) { + player.logSkill("rehuashen"); + lib.skill.rehuashen.addHuashens(player, 3); + event.logged = true; } - _status.noclearcountdown=true; - event.videoId=lib.status.videoId++; - var cards=player.storage.rehuashen.character.slice(0); - var skills=[]; - var sto=player.storage.rehuashen; - for(var i in player.storage.rehuashen.map){ + _status.noclearcountdown = true; + event.videoId = lib.status.videoId++; + var cards = player.storage.rehuashen.character.slice(0); + var skills = []; + var sto = player.storage.rehuashen; + for (var i in player.storage.rehuashen.map) { skills.addArray(player.storage.rehuashen.map[i]); } - var cond='out'; - if(event.triggername=='phaseBegin'){ - cond='in'; + var cond = "out"; + if (event.triggername == "phaseBegin") { + cond = "in"; } skills.randomSort(); - skills.sort(function(a,b){ - return get.skillRank(b,cond)-get.skillRank(a,cond); + skills.sort(function (a, b) { + return get.skillRank(b, cond) - get.skillRank(a, cond); }); - event.aiChoice=skills[0]; - var choice='更换技能'; - if(event.aiChoice==player.storage.rehuashen.current2||get.skillRank(event.aiChoice,cond)<1) choice='弃置化身'; - if(player.isOnline2()){ - player.send(function(cards,id){ - var dialog=ui.create.dialog('是否发动【化身】?',[cards,(item,type,position,noclick,node)=>lib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - dialog.videoId=id; - },cards,event.videoId); + event.aiChoice = skills[0]; + var choice = "更换技能"; + if ( + event.aiChoice == player.storage.rehuashen.current2 || + get.skillRank(event.aiChoice, cond) < 1 + ) + choice = "弃置化身"; + if (player.isOnline2()) { + player.send( + function (cards, id) { + var dialog = ui.create.dialog("是否发动【化身】?", [ + cards, + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton( + item, + type, + position, + noclick, + node + ), + ]); + dialog.videoId = id; + }, + cards, + event.videoId + ); } - event.dialog=ui.create.dialog(get.prompt('rehuashen'),[cards,(item,type,position,noclick,node)=>lib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - event.dialog.videoId=event.videoId; - if(!event.isMine()){ - event.dialog.style.display='none'; + event.dialog = ui.create.dialog(get.prompt("rehuashen"), [ + cards, + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton(item, type, position, noclick, node), + ]); + event.dialog.videoId = event.videoId; + if (!event.isMine()) { + event.dialog.style.display = "none"; } - if(event.logged) event._result={control:'更换技能'}; - else player.chooseControl('弃置化身','更换技能','cancel2').set('ai',function(){ - return _status.event.choice; - }).set('choice',choice); - "step 1" - event.control=result.control; - if(event.control=='cancel2'){ - if(player.isOnline2()){ - player.send('closeDialog',event.videoId); + if (event.logged) event._result = { control: "更换技能" }; + else + player + .chooseControl("弃置化身", "更换技能", "cancel2") + .set("ai", function () { + return _status.event.choice; + }) + .set("choice", choice); + "step 1"; + event.control = result.control; + if (event.control == "cancel2") { + if (player.isOnline2()) { + player.send("closeDialog", event.videoId); } delete _status.noclearcountdown; - if(!_status.noclearcountdown){ + if (!_status.noclearcountdown) { game.stopCountChoose(); } event.dialog.close(); - event.finish();return; + event.finish(); + return; } - if(!event.logged){player.logSkill('rehuashen');event.logged=true} - var next=player.chooseButton(true).set('dialog',event.videoId); - if(event.control=='弃置化身'){ - next.set('selectButton',[1,2]); - next.set('filterButton',function(button){ - return button.link!=_status.event.current; + if (!event.logged) { + player.logSkill("rehuashen"); + event.logged = true; + } + var next = player.chooseButton(true).set("dialog", event.videoId); + if (event.control == "弃置化身") { + next.set("selectButton", [1, 2]); + next.set("filterButton", function (button) { + return button.link != _status.event.current; }); - next.set('current',player.storage.rehuashen.current); - } - else{ - next.set('ai',function(button){ - return player.storage.rehuashen.map[button.link].includes(_status.event.choice)?2.5:1+Math.random(); + next.set("current", player.storage.rehuashen.current); + } else { + next.set("ai", function (button) { + return player.storage.rehuashen.map[button.link].includes(_status.event.choice) + ? 2.5 + : 1 + Math.random(); }); - next.set('choice',event.aiChoice); + next.set("choice", event.aiChoice); } - var prompt=event.control=='弃置化身'?'选择制衡至多两张化身':'选择要切换的化身'; - var func=function(id,prompt){ - var dialog=get.idDialog(id); - if(dialog){ - dialog.content.childNodes[0].innerHTML=prompt; + var prompt = event.control == "弃置化身" ? "选择制衡至多两张化身" : "选择要切换的化身"; + var func = function (id, prompt) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.content.childNodes[0].innerHTML = prompt; } + }; + if (player.isOnline2()) { + player.send(func, event.videoId, prompt); + } else if (event.isMine()) { + func(event.videoId, prompt); } - if(player.isOnline2()){ - player.send(func,event.videoId,prompt); - } - else if(event.isMine()){ - func(event.videoId,prompt); - } - "step 2" - if(result.bool&&event.control!='弃置化身'){ - event.card=result.links[0]; - var func=function(card,id){ - var dialog=get.idDialog(id); - if(dialog){ - for(var i=0;i{ - const name=player.name?player.name:player.name1; - if(name){ - const sex=get.character(name,0); - const group=get.character(name,1); - if(player.sex!=sex){ - game.broadcastAll((player,sex)=>{ - player.sex=sex; - },player,sex); - game.log(player,'将性别变为了','#y'+get.translation(sex)+'性'); + init: function (player, skill) { + if (!player.storage[skill]) + player.storage[skill] = { + character: [], + map: {}, + }; + player.when("dieBegin").then(() => { + const name = player.name ? player.name : player.name1; + if (name) { + const sex = get.character(name, 0); + const group = get.character(name, 1); + if (player.sex != sex) { + game.broadcastAll( + (player, sex) => { + player.sex = sex; + }, + player, + sex + ); + game.log(player, "将性别变为了", "#y" + get.translation(sex) + "性"); } - if(player.group!=group) player.changeGroup(group); + if (player.group != group) player.changeGroup(group); } }); }, - banned:['lisu','sp_xiahoudun','xushao','jsrg_xushao','zhoutai','old_zhoutai','shixie','xin_zhoutai','dc_shixie','old_shixie'], - bannedType:['Charlotte','主公技','觉醒技','限定技','隐匿技','使命技'], - addHuashen:function(player){ - if(!player.storage.rehuashen) return; - if(!_status.characterlist){ + banned: [ + "lisu", + "sp_xiahoudun", + "xushao", + "jsrg_xushao", + "zhoutai", + "old_zhoutai", + "shixie", + "xin_zhoutai", + "dc_shixie", + "old_shixie", + ], + bannedType: ["Charlotte", "主公技", "觉醒技", "限定技", "隐匿技", "使命技"], + addHuashen: function (player) { + if (!player.storage.rehuashen) return; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } _status.characterlist.randomSort(); - for(let i=0;i<_status.characterlist.length;i++){ - let name=_status.characterlist[i]; - if(name.indexOf('zuoci')!=-1||name.indexOf('key_')==0||name.indexOf('sp_key_')==0||get.is.double(name)||lib.skill.rehuashen.banned.includes(name)||player.storage.rehuashen.character.includes(name)) continue; - let skills=lib.character[name][3].filter(skill=>{ - const categories=get.skillCategoriesOf(skill); - return !categories.some(type=>lib.skill.rehuashen.bannedType.includes(type)); - }) - if(skills.length){ + for (let i = 0; i < _status.characterlist.length; i++) { + let name = _status.characterlist[i]; + if ( + name.indexOf("zuoci") != -1 || + name.indexOf("key_") == 0 || + name.indexOf("sp_key_") == 0 || + get.is.double(name) || + lib.skill.rehuashen.banned.includes(name) || + player.storage.rehuashen.character.includes(name) + ) + continue; + let skills = lib.character[name][3].filter((skill) => { + const categories = get.skillCategoriesOf(skill); + return !categories.some((type) => lib.skill.rehuashen.bannedType.includes(type)); + }); + if (skills.length) { player.storage.rehuashen.character.push(name); - player.storage.rehuashen.map[name]=skills; + player.storage.rehuashen.map[name] = skills; _status.characterlist.remove(name); return name; } } }, - addHuashens:function(player,num){ - var list=[]; - for(var i=0;ilib.skill.rehuashen.bannedType.includes(type)); + $createButton: function (item, type, position, noclick, node) { + node = ui.create.buttonPresets.character(item, "character", position, noclick); + const info = lib.character[item]; + const skills = info[3].filter(function (skill) { + const categories = get.skillCategoriesOf(skill); + return !categories.some((type) => lib.skill.rehuashen.bannedType.includes(type)); }); - if(skills.length){ - const skillstr=skills.map(i=>`[${get.translation(i)}]`).join('
              '); - const skillnode=ui.create.caption( - `
              ${skillstr}
              `,node); - skillnode.style.left='2px'; - skillnode.style.bottom='2px'; + if (skills.length) { + const skillstr = skills.map((i) => `[${get.translation(i)}]`).join("
              "); + const skillnode = ui.create.caption( + `
              ${skillstr}
              `, + node + ); + skillnode.style.left = "2px"; + skillnode.style.bottom = "2px"; } - node._customintro=function(uiintro,evt){ - const character=node.link,characterInfo=get.character(node.link); - let capt=get.translation(character); - if(characterInfo){ - capt+=`  ${get.translation(characterInfo[0])}`; + node._customintro = function (uiintro, evt) { + const character = node.link, + characterInfo = get.character(node.link); + let capt = get.translation(character); + if (characterInfo) { + capt += `  ${get.translation(characterInfo[0])}`; let charactergroup; - const charactergroups=get.is.double(character,true); - if(charactergroups) charactergroup=charactergroups.map(i=>get.translation(i)).join('/'); - else charactergroup=get.translation(characterInfo[1]); - capt+=`  ${charactergroup}`; + const charactergroups = get.is.double(character, true); + if (charactergroups) + charactergroup = charactergroups.map((i) => get.translation(i)).join("/"); + else charactergroup = get.translation(characterInfo[1]); + capt += `  ${charactergroup}`; } uiintro.add(capt); - if(lib.characterTitle[node.link]){ + if (lib.characterTitle[node.link]) { uiintro.addText(get.colorspan(lib.characterTitle[node.link])); } - for(let i=0;i
              '+get.translation(skills[i])+'
              '+get.skillInfoTranslation(skills[i])+'
              '); + for (let i = 0; i < skills.length; i++) { + if (lib.translate[skills[i] + "_info"]) { + let translation = + lib.translate[skills[i] + "_ab"] || + get.translation(skills[i]).slice(0, 2); + if (lib.skill[skills[i]] && lib.skill[skills[i]].nobracket) { + uiintro.add( + '
              ' + + get.translation(skills[i]) + + "
              " + + get.skillInfoTranslation(skills[i]) + + "
              " + ); + } else { + uiintro.add( + '
              【' + + translation + + "】
              " + + get.skillInfoTranslation(skills[i]) + + "
              " + ); } - else{ - uiintro.add('
              【'+translation+'】
              '+get.skillInfoTranslation(skills[i])+'
              '); - } - if(lib.translate[skills[i]+'_append']){ - uiintro._place_text=uiintro.add('
              '+lib.translate[skills[i]+'_append']+'
              ') + if (lib.translate[skills[i] + "_append"]) { + uiintro._place_text = uiintro.add( + '
              ' + lib.translate[skills[i] + "_append"] + "
              " + ); } } } - } + }; return node; }, // createAudio:(character,skillx,name)=>{ @@ -10770,2156 +13110,2613 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }); // }, - mark:true, - intro:{ - onunmark:function(storage,player){ + mark: true, + intro: { + onunmark: function (storage, player) { _status.characterlist.addArray(storage.character); - storage.character=[]; + storage.character = []; }, - mark:function(dialog,storage,player){ - if(storage&&storage.current) dialog.addSmall([[storage.current],(item,type,position,noclick,node)=>lib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - if(storage&&storage.current2) dialog.add('
              【'+get.translation(lib.translate[storage.current2+'_ab']||get.translation(storage.current2).slice(0,2))+'】
              '+get.skillInfoTranslation(storage.current2,player)+'
              '); - if(storage&&storage.character.length){ - if(player.isUnderControl(true)){ - dialog.addSmall([storage.character,(item,type,position,noclick,node)=>lib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); + mark: function (dialog, storage, player) { + if (storage && storage.current) + dialog.addSmall([ + [storage.current], + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton(item, type, position, noclick, node), + ]); + if (storage && storage.current2) + dialog.add( + '
              【' + + get.translation( + lib.translate[storage.current2 + "_ab"] || + get.translation(storage.current2).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(storage.current2, player) + + "
              " + ); + if (storage && storage.character.length) { + if (player.isUnderControl(true)) { + dialog.addSmall([ + storage.character, + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton( + item, + type, + position, + noclick, + node + ), + ]); + } else { + dialog.addText("共有" + get.cnNumber(storage.character.length) + "张“化身”"); } - else{ - dialog.addText('共有'+get.cnNumber(storage.character.length)+'张“化身”'); - } - } - else{ - return '没有化身'; + } else { + return "没有化身"; } }, - content:function(storage,player){ - return '共有'+get.cnNumber(storage.character.length)+'张“化身”' + content: function (storage, player) { + return "共有" + get.cnNumber(storage.character.length) + "张“化身”"; }, - markcount:function(storage,player){ - if(storage&&storage.character) return storage.character.length; + markcount: function (storage, player) { + if (storage && storage.character) return storage.character.length; return 0; }, }, }, - rexinsheng:{ - unique:true, - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - lib.skill.rehuashen.addHuashens(player,1); - 'step 2' - if(--event.num>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('rexinsheng')).set('frequentSkill',event.name); - } - else event.finish(); - 'step 3' - if(result.bool&&player.hasSkill('rexinsheng')){ - player.logSkill('rexinsheng'); + rexinsheng: { + unique: true, + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + lib.skill.rehuashen.addHuashens(player, 1); + "step 2"; + if ( + --event.num > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("rexinsheng")).set("frequentSkill", event.name); + } else event.finish(); + "step 3"; + if (result.bool && player.hasSkill("rexinsheng")) { + player.logSkill("rexinsheng"); event.goto(1); } }, }, - reguhuo:{ - audio:2, - derivation:'rechanyuan', - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - return lib.inpile.includes(name)&&player.countCards('h')>0&&!player.hasSkill('reguhuo_phase'); + reguhuo: { + audio: 2, + derivation: "rechanyuan", + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + return ( + lib.inpile.includes(name) && + player.countCards("h") > 0 && + !player.hasSkill("reguhuo_phase") + ); }, - filter:function(event,player){ - if(!player.countCards('hs')||player.hasSkill('reguhuo_phase')) return false; - for(var i of lib.inpile){ - var type=get.type(i); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) return true; + filter: function (event, player) { + if (!player.countCards("hs") || player.hasSkill("reguhuo_phase")) return false; + for (var i of lib.inpile) { + var type = get.type(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + return true; } } } return false; }, - chooseButton:{ - dialog:function(){ - var list=[]; - for(var i of lib.inpile){ - var type=get.type(i); - if(type=='basic'||type=='trick') list.push([type,'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function () { + var list = []; + for (var i of lib.inpile) { + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } - return ui.create.dialog('蛊惑',[list,'vcard']); + return ui.create.dialog("蛊惑", [list, "vcard"]); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard(get.autoViewAs({name:button.link[2],nature:button.link[3]},'unsure'),player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard( + get.autoViewAs({ name: button.link[2], nature: button.link[3] }, "unsure"), + player, + evt + ); }, - check:function(button){ - var player=_status.event.player; - var rand=_status.event.getParent().getRand('reguhuo'); - var hasEnemy=game.hasPlayer(function(current){ - return current!=player&&!current.hasSkill('rechanyuan')&&(get.realAttitude||get.attitude)(current,player)<0; + check: function (button) { + var player = _status.event.player; + var rand = _status.event.getParent().getRand("reguhuo"); + var hasEnemy = game.hasPlayer(function (current) { + return ( + current != player && + !current.hasSkill("rechanyuan") && + (get.realAttitude || get.attitude)(current, player) < 0 + ); }); - var card={name:button.link[2],nature:button.link[3]}; - var val=_status.event.getParent().type=='phase'?player.getUseValue(card):1; - if(val<=0) return 0; - if(hasEnemy&&rand>0.3){ - if(!player.countCards('h',function(cardx){ - if(card.name==cardx.name){ - if(card.name!='sha') return true; - return get.is.sameNature(card,cardx); - } - return false; - })) return 0; - return 3*val; + var card = { name: button.link[2], nature: button.link[3] }; + var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; + if (val <= 0) return 0; + if (hasEnemy && rand > 0.3) { + if ( + !player.countCards("h", function (cardx) { + if (card.name == cardx.name) { + if (card.name != "sha") return true; + return get.is.sameNature(card, cardx); + } + return false; + }) + ) + return 0; + return 3 * val; } return val; }, - backup:function(links,player){ + backup: function (links, player) { return { - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, }, - filterCard:function(card,player,target){ - var result=true; - var suit=card.suit,number=card.number; - card.suit='none';card.number=null; - var mod=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod!='unchanged') result=mod; - card.suit=suit;card.number=number; + filterCard: function (card, player, target) { + var result = true; + var suit = card.suit, + number = card.number; + card.suit = "none"; + card.number = null; + var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod != "unchanged") result = mod; + card.suit = suit; + card.number = number; return result; }, - position:'hs', - ignoreMod:true, - ai1:function(card){ - var player=_status.event.player; - var hasEnemy=game.hasPlayer(function(current){ - return current!=player&&!current.hasSkill('rechanyuan')&&(get.realAttitude||get.attitude)(current,player)<0; + position: "hs", + ignoreMod: true, + ai1: function (card) { + var player = _status.event.player; + var hasEnemy = game.hasPlayer(function (current) { + return ( + current != player && + !current.hasSkill("rechanyuan") && + (get.realAttitude || get.attitude)(current, player) < 0 + ); }); - var rand=_status.event.getRand('reguhuo'); - var cardx=lib.skill.reguhuo_backup.viewAs; - if(hasEnemy&&rand>0.3){ - if(card.name==cardx.name&&(card.name!='sha'||get.is.sameNature(card,cardx))) return 10; + var rand = _status.event.getRand("reguhuo"); + var cardx = lib.skill.reguhuo_backup.viewAs; + if (hasEnemy && rand > 0.3) { + if ( + card.name == cardx.name && + (card.name != "sha" || get.is.sameNature(card, cardx)) + ) + return 10; return 0; } - return 6-get.value(card); + return 6 - get.value(card); }, - precontent:function(){ - player.logSkill('reguhuo'); - player.addTempSkill('reguhuo_guess'); - var card=event.result.cards[0]; - event.result.card.suit=get.suit(card); - event.result.card.number=get.number(card); + precontent: function () { + player.logSkill("reguhuo"); + player.addTempSkill("reguhuo_guess"); + var card = event.result.cards[0]; + event.result.card.suit = get.suit(card); + event.result.card.number = get.number(card); }, - } + }; }, - prompt:function(links){ - return '将一张手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt: function (links) { + return ( + "将一张手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - fireAttack:true, - respondShan:true, - respondSha:true, - skillTagFilter:function(player){ - if(!player.countCards('hs')||player.hasSkill('reguhuo_phase')) return false; + ai: { + fireAttack: true, + respondShan: true, + respondSha: true, + skillTagFilter: function (player) { + if (!player.countCards("hs") || player.hasSkill("reguhuo_phase")) return false; }, - order:10, - result:{ - player:1, + order: 10, + result: { + player: 1, }, - threaten:1.3, + threaten: 1.3, }, }, - reguhuo_guess:{ - trigger:{ - player:['useCardBefore','respondBefore'], + reguhuo_guess: { + trigger: { + player: ["useCardBefore", "respondBefore"], }, - forced:true, - silent:true, - popup:false, - charlotte:true, - firstDo:true, - filter:function(event,player){ - return event.skill&&event.skill.indexOf('reguhuo_')==0; + forced: true, + silent: true, + popup: false, + charlotte: true, + firstDo: true, + filter: function (event, player) { + return event.skill && event.skill.indexOf("reguhuo_") == 0; }, - content:function(){ - 'step 0' - player.addTempSkill('reguhuo_phase'); - event.fake=false; - var card=trigger.cards[0]; - if(card.name!=trigger.card.name||(card.name=='sha'&&!get.is.sameNature(trigger.card,card))) event.fake=true; + content: function () { + "step 0"; + player.addTempSkill("reguhuo_phase"); + event.fake = false; + var card = trigger.cards[0]; + if ( + card.name != trigger.card.name || + (card.name == "sha" && !get.is.sameNature(trigger.card, card)) + ) + event.fake = true; //player.logSkill('reguhuo'); - player.line(trigger.targets,get.nature(trigger.card)); - event.cardTranslate=get.translation(trigger.card.name); - trigger.card.number=get.number(card); - trigger.card.suit=get.suit(card); + player.line(trigger.targets, get.nature(trigger.card)); + event.cardTranslate = get.translation(trigger.card.name); + trigger.card.number = get.number(card); + trigger.card.suit = get.suit(card); //trigger.line=false; - trigger.skill='reguhuo_backup'; - if(trigger.card.name=='sha'&&get.natureList(trigger.card).length) event.cardTranslate=get.translation(trigger.card.nature)+event.cardTranslate; - player.popup(event.cardTranslate,trigger.name=='useCard'?'metal':'wood'); - event.prompt='是否质疑'+get.translation(player)+'声明的'+event.cardTranslate+'?'; - game.log(player,'声明了','#y'+event.cardTranslate); - event.targets=game.filterPlayer(function(current){ - return current!=player&&!current.hasSkill('rechanyuan'); - }).sortBySeat(); - event.targets2=event.targets.slice(0); - player.lose(card,ui.ordering).relatedEvent=trigger; - if(!event.targets.length) event.goto(5); - else if(_status.connectMode) event.goto(3); - event.betrays=[]; - 'step 1' - event.target=targets.shift(); - event.target.chooseButton([event.prompt,[['reguhuo_ally','reguhuo_betray'],'vcard']],true,function(button){ - var player=_status.event.player; - var evt=_status.event.getParent('reguhuo_guess'); - if(!evt) return Math.random(); - var ally=button.link[2]=='reguhuo_ally'; - if(ally&&(player.hp<=1||get.attitude(player,evt.player)>=0)) return 1.1; - return Math.random(); - }); - 'step 2' - if(result.links[0][2]=='reguhuo_betray'){ + trigger.skill = "reguhuo_backup"; + if (trigger.card.name == "sha" && get.natureList(trigger.card).length) + event.cardTranslate = get.translation(trigger.card.nature) + event.cardTranslate; + player.popup(event.cardTranslate, trigger.name == "useCard" ? "metal" : "wood"); + event.prompt = + "是否质疑" + get.translation(player) + "声明的" + event.cardTranslate + "?"; + game.log(player, "声明了", "#y" + event.cardTranslate); + event.targets = game + .filterPlayer(function (current) { + return current != player && !current.hasSkill("rechanyuan"); + }) + .sortBySeat(); + event.targets2 = event.targets.slice(0); + player.lose(card, ui.ordering).relatedEvent = trigger; + if (!event.targets.length) event.goto(5); + else if (_status.connectMode) event.goto(3); + event.betrays = []; + "step 1"; + event.target = targets.shift(); + event.target.chooseButton( + [event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], + true, + function (button) { + var player = _status.event.player; + var evt = _status.event.getParent("reguhuo_guess"); + if (!evt) return Math.random(); + var ally = button.link[2] == "reguhuo_ally"; + if (ally && (player.hp <= 1 || get.attitude(player, evt.player) >= 0)) return 1.1; + return Math.random(); + } + ); + "step 2"; + if (result.links[0][2] == "reguhuo_betray") { event.betrays.push(target); target.addExpose(0.2); } - event.goto(targets.length?1:5); - 'step 3' - var list=event.targets.map(function(target){ - return [target,[event.prompt,[['reguhuo_ally','reguhuo_betray'],'vcard']],true]; + event.goto(targets.length ? 1 : 5); + "step 3"; + var list = event.targets.map(function (target) { + return [target, [event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], true]; }); - player.chooseButtonOL(list).set('switchToAuto',function(){ - _status.event.result='ai'; - }).set('processAI',function(){ - var choice=Math.random()>0.5?'reguhuo_ally':'reguhuo_betray'; - var player=_status.event.player; - var evt=_status.event.getParent('reguhuo_guess'); - if(player.hp<=1||evt&&(get.realAttitude||get.attitude)(player,evt.player)>=0) choice='reguhuo_ally'; - return { - bool:true, - links:[['','',choice]], - } - }); - 'step 4' - for(var i in result){ - if(result[i].links[0][2]=='reguhuo_betray'){ + player + .chooseButtonOL(list) + .set("switchToAuto", function () { + _status.event.result = "ai"; + }) + .set("processAI", function () { + var choice = Math.random() > 0.5 ? "reguhuo_ally" : "reguhuo_betray"; + var player = _status.event.player; + var evt = _status.event.getParent("reguhuo_guess"); + if ( + player.hp <= 1 || + (evt && (get.realAttitude || get.attitude)(player, evt.player) >= 0) + ) + choice = "reguhuo_ally"; + return { + bool: true, + links: [["", "", choice]], + }; + }); + "step 4"; + for (var i in result) { + if (result[i].links[0][2] == "reguhuo_betray") { event.betrays.push(lib.playerOL[i]); lib.playerOL[i].addExpose(0.2); } } - 'step 5' - for(var i of event.targets2){ - var b=event.betrays.includes(i); - i.popup(b?'质疑':'不质疑',b?'fire':'wood'); - game.log(i,b?'#y质疑':'#g不质疑'); + "step 5"; + for (var i of event.targets2) { + var b = event.betrays.includes(i); + i.popup(b ? "质疑" : "不质疑", b ? "fire" : "wood"); + game.log(i, b ? "#y质疑" : "#g不质疑"); } game.delay(); - 'step 6' + "step 6"; player.showCards(trigger.cards); - if(event.betrays.length){ + if (event.betrays.length) { event.betrays.sortBySeat(); - if(event.fake){ + if (event.fake) { game.asyncDraw(event.betrays); trigger.cancel(); trigger.getParent().goto(0); - game.log(player,'声明的','#y'+event.cardTranslate,'作废了') - } - else{ - var next=game.createEvent('reguhuo_final',false); + game.log(player, "声明的", "#y" + event.cardTranslate, "作废了"); + } else { + var next = game.createEvent("reguhuo_final", false); event.next.remove(next); trigger.after.push(next); - next.targets=event.betrays; + next.targets = event.betrays; next.setContent(lib.skill.reguhuo_guess.contentx); event.finish(); } - } - else event.finish(); - 'step 7' + } else event.finish(); + "step 7"; game.delayx(); }, - contentx:function(){ - 'step 0' - event.target=targets.shift(); - event.target.chooseToDiscard('弃置一张牌或失去1点体力').set('ai',function(card){ - return 9-get.value(card); + contentx: function () { + "step 0"; + event.target = targets.shift(); + event.target.chooseToDiscard("弃置一张牌或失去1点体力").set("ai", function (card) { + return 9 - get.value(card); }); - 'step 1' - if(!result.bool) target.loseHp(); - 'step 2' - target.addSkills('rechanyuan'); - if(targets.length) event.goto(0); + "step 1"; + if (!result.bool) target.loseHp(); + "step 2"; + target.addSkills("rechanyuan"); + if (targets.length) event.goto(0); }, }, - reguhuo_backup:{}, - reguhuo_phase:{}, - rechanyuan:{ - init:function(player,skill){ - if(player.hp<=1){ + reguhuo_backup: {}, + reguhuo_phase: {}, + rechanyuan: { + init: function (player, skill) { + if (player.hp <= 1) { player.logSkill(skill); - player.addSkill('rechanyuan_log'); + player.addSkill("rechanyuan_log"); } player.addSkillBlocker(skill); }, - onremove:function(player,skill){ - player.removeSkill('rechanyuan_log'); + onremove: function (player, skill) { + player.removeSkill("rechanyuan_log"); player.removeSkillBlocker(skill); }, - skillBlocker:function(skill,player){ - return skill!='chanyuan'&&skill!='rechanyuan'&&!lib.skill[skill].charlotte&&player.hp<=1; + skillBlocker: function (skill, player) { + return ( + skill != "chanyuan" && + skill != "rechanyuan" && + !lib.skill[skill].charlotte && + player.hp <= 1 + ); }, - mark:true, - intro:{ - content:function(storage,player,skill){ - var str='
            • 锁定技,你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值不大于1时,你的其他技能失效。'; - var list=player.getSkills(null,false,false).filter(function(i){ - return lib.skill.rechanyuan.skillBlocker(i,player); + mark: true, + intro: { + content: function (storage, player, skill) { + var str = + "
            • 锁定技,你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值不大于1时,你的其他技能失效。"; + var list = player.getSkills(null, false, false).filter(function (i) { + return lib.skill.rechanyuan.skillBlocker(i, player); }); - if(list.length) str+=('
            • 失效技能:'+get.translation(list)) + if (list.length) str += "
            • 失效技能:" + get.translation(list); return str; }, }, - audio:2, - trigger:{player:'changeHp'}, - filter:function(event,player){ - return (player.hp<=1)!=(player.hasSkill('rechanyuan_log')); + audio: 2, + trigger: { player: "changeHp" }, + filter: function (event, player) { + return player.hp <= 1 != player.hasSkill("rechanyuan_log"); }, - direct:true, - locked:true, - content:function(){ - if(player.hp<=1){ - player.logSkill('rechanyuan'); - player.addSkill('rechanyuan_log'); - } - else player.removeSkill('rechanyuan_log'); + direct: true, + locked: true, + content: function () { + if (player.hp <= 1) { + player.logSkill("rechanyuan"); + player.addSkill("rechanyuan_log"); + } else player.removeSkill("rechanyuan_log"); }, - subSkill:{ - log:{charlotte:true}, + subSkill: { + log: { charlotte: true }, }, }, - botu:{ - audio:2, - trigger:{player:'phaseAfter'}, - frequent:true, - filter:function(event,player){ - var history=player.getHistory('useCard',function(evt){ + botu: { + audio: 2, + trigger: { player: "phaseAfter" }, + frequent: true, + filter: function (event, player) { + var history = player.getHistory("useCard", function (evt) { return evt.isPhaseUsing(); }); - var suits=[]; - for(var i=0;i1&&get.number(card)<10) return 5; + judgeCheck: function (card, bool) { + var suit = get.suit(card); + if (suit == "spade") { + if (bool && get.number(card) > 1 && get.number(card) < 10) return 5; return 4; } - if(suit=='club') return 2; + if (suit == "club") return 2; return 0; }, - content:function(){ - player.judge(lib.skill.xinleiji.judgeCheck).judge2=function(result){ - return result.bool?true:false; + content: function () { + player.judge(lib.skill.xinleiji.judgeCheck).judge2 = function (result) { + return result.bool ? true : false; }; }, - ai:{ - useShan:true, - effect:{ - target:function(card,player,target,current){ + ai: { + useShan: true, + effect: { + target: function (card, player, target, current) { let name; - if(typeof card=='object'){ - if(card.viewAs) name=card.viewAs; - else name=get.name(card); + 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 ( + 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(name==='sha'){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return; - } - else 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; + if (!target.isHealthy()) club += 2; + if (!club && !spade) return 1; + if (name === "sha") { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return; + } else 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 (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]; - } - } - } - }, - xinleiji_misa:{ - audio:'xinleiji', - trigger:{player:'judgeEnd'}, - direct:true, - disableReason:['暴虐','助祭','弘仪','孤影'], - filter:function(event,player){ - return !lib.skill.xinleiji_misa.disableReason.includes(event.judgestr)&&['spade','club'].includes(event.result.suit); - }, - content:function(){ - 'step 0' - event.num=1+['club','spade'].indexOf(trigger.result.suit); - event.logged=false; - if(event.num==1&&player.isDamaged()){ - event.logged=true; - player.logSkill('xinleiji'); - player.recover(); - } - player.chooseTarget('雷击:是否对一名角色造成'+event.num+'点雷电伤害?').ai=function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player,'thunder'); - }; - 'step 1' - if(result.bool&&result.targets&&result.targets.length){ - if(!event.logged) player.logSkill('xinleiji',result.targets); - else player.line(result.targets,'thunder'); - result.targets[0].damage(event.num,'thunder'); - } - }, - }, - 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; - }, - direct:true, - content:function(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('xinguidao'),'hes',function(card){ - if(get.color(card)!='black') return false; - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0){ - if(trigger.player!=player) return 0; - if(game.hasPlayer(function(current){ - return get.attitude(player,current)<0; - })){ - var checkx=lib.skill.xinleiji.judgeCheck(card,true)-lib.skill.xinleiji.judgeCheck(judging); - if(checkx>0) return checkx; - } - return 0; - } - if(attitude>0){ - return result; - } - else{ - return -result; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','xinguidao','noOrdering'); - } - else{ - event.finish(); - } - "step 2" - if(result.bool){ - player.$gain2(trigger.player.judging[0]); - player.gain(trigger.player.judging[0]); - var card=result.cards[0]; - if(get.suit(card)=='spade'&&get.number(card)>1&&get.number(card)<10) player.draw('nodelay'); - trigger.player.judging[0]=result.cards[0]; - trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); - } - "step 3" - game.delay(2); - }, - ai:{ - rejudge:true, - tag:{ - rejudge:1 - } - } - }, - reqingguo:{ - mod:{ - aiValue:function(player,card,num){ - if(get.name(card)!='shan'&&get.color(card)!='black') return; - var cards=player.getCards('hs',function(card){ - return get.name(card)=='shan'||get.color(card)=='black'; - }); - cards.sort(function(a,b){ - return (get.name(b)=='shan'?1:2)-(get.name(a)=='shan'?1:2); - }); - var geti=function(){ - if(cards.includes(card)){ - return cards.indexOf(card); - } - return cards.length; - }; - if(get.name(card)=='shan') return Math.min(num,[6,4,3][Math.min(geti(),2)])*0.6; - return Math.max(num,[6.5,4,3][Math.min(geti(),2)]); - }, - aiUseful:function(){ - return lib.skill.reqingguo.mod.aiValue.apply(this,arguments); - }, - }, - locked:false, - audio:2, - enable:['chooseToRespond','chooseToUse'], - filterCard:function(card){ - return get.color(card)=='black'; - }, - position:'hes', - viewAs:{name:'shan'}, - viewAsFilter:function(player){ - if(!player.countCards('hes',{color:'black'})) return false; - }, - prompt:'将一张黑色牌当闪打出', - check:function(){return 1}, - ai:{ - order:2, - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hes',{color:'black'})) return false; - }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.6 - } - } - } - }, - reqiangxi:{ - subSkill:{ - off:{ - sub:true, - }, - }, - audio:2, - enable:"phaseUse", - filterCard:function (card){ - return get.subtype(card)=='equip1'; - }, - selectCard:function (){ - return [0,1]; - }, - filterTarget:function (card,player,target){ - if(player==target) return false; - if(target.hasSkill('reqiangxi_off')) return false; - return player.inRange(target); - }, - content:function (){ - "step 0" - if(cards.length==0){ - player.loseHp(); - } - "step 1" - target.addTempSkill('reqiangxi_off'); - target.damage('nocard'); - }, - check:function (card){ - return 10-get.value(card); - }, - position:"he", - ai:{ - order:8.5, - result:{ - target:function (player,target){ - if(!ui.selected.cards.length){ - if(player.hp<2) return 0; - if(target.hp>=player.hp) return 0; - } - return get.damageEffect(target,player); + if (name == "lebu" || name == "bingliang") + return [ + target.hasSkillTag("rejudge") ? 0.4 : 1, + 2, + target.hasSkillTag("rejudge") ? 0.4 : 1, + 0, + ]; }, }, }, - threaten:1.5, }, - rehuoji:{ - position:"hes", - audio:2, - audioname:['ol_sp_zhugeliang','ol_pangtong'], - enable:"chooseToUse", - filterCard:function (card){ - return get.color(card)=='red'; + xinleiji_misa: { + audio: "xinleiji", + trigger: { player: "judgeEnd" }, + direct: true, + disableReason: ["暴虐", "助祭", "弘仪", "孤影"], + filter: function (event, player) { + return ( + !lib.skill.xinleiji_misa.disableReason.includes(event.judgestr) && + ["spade", "club"].includes(event.result.suit) + ); }, - viewAs:{ - name:"huogong", - }, - viewAsFilter:function (player){ - if(!player.countCards('hes',{color:'red'})) return false; - }, - prompt:"将一张红色牌当火攻使用", - check:function (card){ - var player=get.player(); - if(player.countCards('h')>player.hp){ - return 6-get.value(card); + content: function () { + "step 0"; + event.num = 1 + ["club", "spade"].indexOf(trigger.result.suit); + event.logged = false; + if (event.num == 1 && player.isDamaged()) { + event.logged = true; + player.logSkill("xinleiji"); + player.recover(); + } + player.chooseTarget("雷击:是否对一名角色造成" + event.num + "点雷电伤害?").ai = + function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player, "thunder"); + }; + "step 1"; + if (result.bool && result.targets && result.targets.length) { + if (!event.logged) player.logSkill("xinleiji", result.targets); + else player.line(result.targets, "thunder"); + result.targets[0].damage(event.num, "thunder"); } - return 4-get.value(card) - }, - ai:{ - fireAttack:true, }, }, - rekanpo:{ - mod:{ - aiValue:function(player,card,num){ - if(get.name(card)!='wuxie'&&get.color(card)!='black') return; - var cards=player.getCards('hs',function(card){ - return get.name(card)=='wuxie'||get.color(card)=='black'; + 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; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("xinguidao"), + "hes", + function (card) { + if (get.color(card) != "black") return false; + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) { + if (trigger.player != player) return 0; + if ( + game.hasPlayer(function (current) { + return get.attitude(player, current) < 0; + }) + ) { + var checkx = + lib.skill.xinleiji.judgeCheck(card, true) - + lib.skill.xinleiji.judgeCheck(judging); + if (checkx > 0) return checkx; + } + return 0; + } + if (attitude > 0) { + return result; + } else { + return -result; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "xinguidao", "noOrdering"); + } else { + event.finish(); + } + "step 2"; + if (result.bool) { + player.$gain2(trigger.player.judging[0]); + player.gain(trigger.player.judging[0]); + var card = result.cards[0]; + if (get.suit(card) == "spade" && get.number(card) > 1 && get.number(card) < 10) + player.draw("nodelay"); + trigger.player.judging[0] = result.cards[0]; + trigger.orderingCards.addArray(result.cards); + game.log(trigger.player, "的判定牌改为", result.cards[0]); + } + "step 3"; + game.delay(2); + }, + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, + }, + reqingguo: { + mod: { + aiValue: function (player, card, num) { + if (get.name(card) != "shan" && get.color(card) != "black") return; + var cards = player.getCards("hs", function (card) { + return get.name(card) == "shan" || get.color(card) == "black"; }); - cards.sort(function(a,b){ - return (get.name(b)=='wuxie'?1:2)-(get.name(a)=='wuxie'?1:2); + cards.sort(function (a, b) { + return (get.name(b) == "shan" ? 1 : 2) - (get.name(a) == "shan" ? 1 : 2); }); - var geti=function(){ - if(cards.includes(card)){ + var geti = function () { + if (cards.includes(card)) { return cards.indexOf(card); } return cards.length; }; - if(get.name(card)=='wuxie') return Math.min(num,[6,4,3][Math.min(geti(),2)])*0.6; - return Math.max(num,[6,4,3][Math.min(geti(),2)]); + if (get.name(card) == "shan") + return Math.min(num, [6, 4, 3][Math.min(geti(), 2)]) * 0.6; + return Math.max(num, [6.5, 4, 3][Math.min(geti(), 2)]); }, - aiUseful:function(){ - return lib.skill.rekanpo.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.reqingguo.mod.aiValue.apply(this, arguments); }, }, - locked:false, - audio:2, - audioname:['ol_sp_zhugeliang','ol_pangtong'], - position:"hes", - enable:"chooseToUse", - filterCard:function (card){ - return get.color(card)=='black'; + locked: false, + audio: 2, + enable: ["chooseToRespond", "chooseToUse"], + filterCard: function (card) { + return get.color(card) == "black"; }, - viewAsFilter:function (player){ - return player.countCards('hes',{color:'black'})>0; + position: "hes", + viewAs: { name: "shan" }, + viewAsFilter: function (player) { + if (!player.countCards("hes", { color: "black" })) return false; }, - viewAs:{ - name:"wuxie", + prompt: "将一张黑色牌当闪打出", + check: function () { + return 1; + }, + ai: { + order: 2, + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hes", { color: "black" })) return false; + }, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.6; + }, + }, }, - prompt:"将一张黑色牌当无懈可击使用", - check:function (card){return 8-get.value(card)}, }, - reshuangxiong:{ - audio:"shuangxiong", - audioname:['re_yanwen'], - group:['reshuangxiong1',"reshuangxiong2"], - }, - reshuangxiong1:{ - audio:"shuangxiong1", - audioname2:{ - re_yanwen:'shuangxiong_re_yanwen1', + reqiangxi: { + subSkill: { + off: { + sub: true, + }, }, - trigger:{player:"phaseDrawBegin1"}, - check:function (event,player){ - if(player.countCards('h')>player.hp) return true; - if(player.countCards('h')>3) return true; + audio: 2, + enable: "phaseUse", + filterCard: function (card) { + return get.subtype(card) == "equip1"; + }, + selectCard: function () { + return [0, 1]; + }, + filterTarget: function (card, player, target) { + if (player == target) return false; + if (target.hasSkill("reqiangxi_off")) return false; + return player.inRange(target); + }, + content: function () { + "step 0"; + if (cards.length == 0) { + player.loseHp(); + } + "step 1"; + target.addTempSkill("reqiangxi_off"); + target.damage("nocard"); + }, + check: function (card) { + return 10 - get.value(card); + }, + position: "he", + ai: { + order: 8.5, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) { + if (player.hp < 2) return 0; + if (target.hp >= player.hp) return 0; + } + return get.damageEffect(target, player); + }, + }, + }, + threaten: 1.5, + }, + rehuoji: { + position: "hes", + audio: 2, + audioname: ["ol_sp_zhugeliang", "ol_pangtong"], + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "red"; + }, + viewAs: { + name: "huogong", + }, + viewAsFilter: function (player) { + if (!player.countCards("hes", { color: "red" })) return false; + }, + prompt: "将一张红色牌当火攻使用", + check: function (card) { + var player = get.player(); + if (player.countCards("h") > player.hp) { + return 6 - get.value(card); + } + return 4 - get.value(card); + }, + ai: { + fireAttack: true, + }, + }, + rekanpo: { + mod: { + aiValue: function (player, card, num) { + if (get.name(card) != "wuxie" && get.color(card) != "black") return; + var cards = player.getCards("hs", function (card) { + return get.name(card) == "wuxie" || get.color(card) == "black"; + }); + cards.sort(function (a, b) { + return (get.name(b) == "wuxie" ? 1 : 2) - (get.name(a) == "wuxie" ? 1 : 2); + }); + var geti = function () { + if (cards.includes(card)) { + return cards.indexOf(card); + } + return cards.length; + }; + if (get.name(card) == "wuxie") + return Math.min(num, [6, 4, 3][Math.min(geti(), 2)]) * 0.6; + return Math.max(num, [6, 4, 3][Math.min(geti(), 2)]); + }, + aiUseful: function () { + return lib.skill.rekanpo.mod.aiValue.apply(this, arguments); + }, + }, + locked: false, + audio: 2, + audioname: ["ol_sp_zhugeliang", "ol_pangtong"], + position: "hes", + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "black"; + }, + viewAsFilter: function (player) { + return player.countCards("hes", { color: "black" }) > 0; + }, + viewAs: { + name: "wuxie", + }, + prompt: "将一张黑色牌当无懈可击使用", + check: function (card) { + return 8 - get.value(card); + }, + }, + reshuangxiong: { + audio: "shuangxiong", + audioname: ["re_yanwen"], + group: ["reshuangxiong1", "reshuangxiong2"], + }, + reshuangxiong1: { + audio: "shuangxiong1", + audioname2: { + re_yanwen: "shuangxiong_re_yanwen1", + }, + trigger: { player: "phaseDrawBegin1" }, + check: function (event, player) { + if (player.countCards("h") > player.hp) return true; + if (player.countCards("h") > 3) return true; return false; }, - filter:function(event,player){ + filter: function (event, player) { return !event.numFixed; }, - prompt2:function(){ - return '放弃摸牌,然后展示牌堆顶的两张牌并选择获得其中的一张。本回合内可以将与此牌颜色不同的一张手牌当做【决斗】使用'; + prompt2: function () { + return "放弃摸牌,然后亮出牌堆顶的两张牌并选择获得其中的一张。本回合内可以将与此牌颜色不同的一张手牌当做【决斗】使用"; }, - content:function(){ - "step 0" + content: function () { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(2); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str; - if(player==game.me&&!_status.auto){ - str='【双雄】选择获得其中一张牌'; - } - else{ - str='双雄'; - } - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - event.time=get.utc(); - game.addVideo('showCards',player,['双雄',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - "step 1" - var next=player.chooseButton([1,1],true); - next.set('dialog',event.videoId); - next.set('ai',function(button){ - var player=_status.event.player; - var color=get.color(button.link); - var value=get.value(button.link,player); - if(player.countCards('h',{color:color})>player.countCards('h',['red','black'].remove(color)[0])) value+=5; + event.cards = get.cards(2); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str; + if (player == game.me && !_status.auto) { + str = "【双雄】选择获得其中一张牌"; + } else { + str = "双雄"; + } + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + event.time = get.utc(); + game.addVideo("showCards", player, ["双雄", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + "step 1"; + var next = player.chooseButton([1, 1], true); + next.set("dialog", event.videoId); + next.set("ai", function (button) { + var player = _status.event.player; + var color = get.color(button.link); + var value = get.value(button.link, player); + if ( + player.countCards("h", { color: color }) > + player.countCards("h", ["red", "black"].remove(color)[0]) + ) + value += 5; return value; }); - "step 2" - if(result.bool&&result.links){ - var cards2=[]; - for(var i=0;i0){ - game.delay(0,time); + var time = 1000 - (get.utc() - event.time); + if (time > 0) { + game.delay(0, time); } - "step 3" - game.broadcastAll('closeDialog',event.videoId); - var card2=event.card2; - player.gain(card2,'gain2'); - player.addTempSkill('shuangxiong2'); - player.markAuto('shuangxiong2',[get.color(card2,false)]); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var card2 = event.card2; + player.gain(card2, "gain2"); + player.addTempSkill("shuangxiong2"); + player.markAuto("shuangxiong2", [get.color(card2, false)]); }, }, - reshuangxiong2:{ - trigger:{ - player:"damageEnd", + reshuangxiong2: { + trigger: { + player: "damageEnd", }, - direct:true, - filter:function (event,player){ - var evt=event.getParent(); - return (evt&&evt.name=='juedou'&&evt[player==evt.player?'targetCards':'playerCards'].length)>0; + direct: true, + filter: function (event, player) { + var evt = event.getParent(); + return ( + (evt && + evt.name == "juedou" && + evt[player == evt.player ? "targetCards" : "playerCards"].length) > 0 + ); }, - content:function (){ - "step 0" - var evt=trigger.getParent(); - var cards=evt[player==evt.player?'targetCards':'playerCards'].slice(0); - for(var i=0;i0&&['useCard','respond'].includes(event.getParent().name); + frequent: true, + filter: function (event, player) { + return ( + player != _status.currentPhase && + event.hs && + event.hs.length > 0 && + ["useCard", "respond"].includes(event.getParent().name) + ); }, - content:function (){ - "step 0" - event.card=get.cards(); + content: function () { + "step 0"; + event.card = get.cards(); player.showCards(event.card); - event.same=false; - if(get.type(event.card[0],'trick')==get.type(trigger.getParent().card,'trick')) event.same=true; - player.chooseTarget('选择获得此牌的角色',true).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.du){ - if(target.hasSkillTag('nodu')) return 0; - return -att; - } - if(!_status.event.same) att+=target==_status.event.player?1:0; - if(att>0){ - return att+Math.max(0,5-target.countCards('h')); - } - return att; - }).set('du',event.card.name=='du').set('same',event.same); - "step 1" - if(result.targets){ - player.line(result.targets,'green'); - result.targets[0].gain(event.card,'gain2'); - if(!event.same) player.chooseToDiscard(true,'he'); + event.same = false; + if (get.type(event.card[0], "trick") == get.type(trigger.getParent().card, "trick")) + event.same = true; + player + .chooseTarget("选择获得此牌的角色", true) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0; + return -att; + } + if (!_status.event.same) att += target == _status.event.player ? 1 : 0; + if (att > 0) { + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }) + .set("du", event.card.name == "du") + .set("same", event.same); + "step 1"; + if (result.targets) { + player.line(result.targets, "green"); + result.targets[0].gain(event.card, "gain2"); + if (!event.same) player.chooseToDiscard(true, "he"); } }, - ai:{ - effect:{ - target:function (card,player,target){ - if(get.tag(card,'respond')&&target.countCards('h')>1) return [1,0.2]; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "respond") && target.countCards("h") > 1) return [1, 0.2]; }, }, }, }, - "new_liyu":{ - audio:"liyu", - trigger:{ - source:"damageSource", + new_liyu: { + audio: "liyu", + trigger: { + source: "damageSource", }, - filter:function (event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player!=player&&event.player.isIn()&&event.player.countGainableCards(player,'hej')>0; + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.player != player && + event.player.isIn() && + event.player.countGainableCards(player, "hej") > 0 + ); }, - direct:true, - content:function (){ - 'step 0' - player.gainPlayerCard(get.prompt('new_liyu',trigger.player),trigger.player,'hej','visibleMove').set('ai',function(button){ - var player=_status.event.player,target=_status.event.target; - if(get.attitude(player,target)>0&&get.position(button.link)==='j') return 4+get.value(button.link); - if(get.type(button.link)==='equip') return _status.event.juedou; - return 3; - }).set('juedou',(()=>{ - if(get.attitude(player,trigger.player)>0&&game.hasPlayer(function(current){ - return (player.canUse({name:'juedou'},current)&¤t!=trigger.player&¤t!=player&&get.effect(current,{name:'juedou'},player,_status.event.player)>2); - })) return 5; - if(game.hasPlayer(function(current){ - return (player.canUse({name:'juedou'},current)&¤t!=trigger.player&¤t!=player&&get.effect(current,{name:'juedou'},player,_status.event.player)<0); - })) return 1; - return 4; - })()).set('logSkill',['new_liyu',trigger.player]); - 'step 1' - if(result.bool){ - if(get.type(result.cards[0])!='equip'){ + direct: true, + content: function () { + "step 0"; + player + .gainPlayerCard( + get.prompt("new_liyu", trigger.player), + trigger.player, + "hej", + "visibleMove" + ) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.target; + if (get.attitude(player, target) > 0 && get.position(button.link) === "j") + return 4 + get.value(button.link); + if (get.type(button.link) === "equip") return _status.event.juedou; + return 3; + }) + .set( + "juedou", + (() => { + if ( + get.attitude(player, trigger.player) > 0 && + game.hasPlayer(function (current) { + return ( + player.canUse({ name: "juedou" }, current) && + current != trigger.player && + current != player && + get.effect( + current, + { name: "juedou" }, + player, + _status.event.player + ) > 2 + ); + }) + ) + return 5; + if ( + game.hasPlayer(function (current) { + return ( + player.canUse({ name: "juedou" }, current) && + current != trigger.player && + current != player && + get.effect( + current, + { name: "juedou" }, + player, + _status.event.player + ) < 0 + ); + }) + ) + return 1; + return 4; + })() + ) + .set("logSkill", ["new_liyu", trigger.player]); + "step 1"; + if (result.bool) { + if (get.type(result.cards[0]) != "equip") { trigger.player.draw(); event.finish(); - } - else{ - if(!game.hasPlayer(function(current){ - return current!=player&¤t!=trigger.player&&player.canUse('juedou',current); - })){ + } else { + if ( + !game.hasPlayer(function (current) { + return ( + current != player && + current != trigger.player && + player.canUse("juedou", current) + ); + }) + ) { event.finish(); return; } - trigger.player.chooseTarget(true,function(card,player,target){ - var evt=_status.event.getParent(); - return evt.player.canUse({name:'juedou'},target)&&target!=_status.event.player; - },'请选择一名角色,视为'+get.translation(player)+'对其使用【决斗】').set('ai',function(target){ - var evt=_status.event.getParent(); - return get.effect(target,{name:'juedou'},evt.player,_status.event.player)-2; - }); + trigger.player + .chooseTarget( + true, + function (card, player, target) { + var evt = _status.event.getParent(); + return ( + evt.player.canUse({ name: "juedou" }, target) && + target != _status.event.player + ); + }, + "请选择一名角色,视为" + get.translation(player) + "对其使用【决斗】" + ) + .set("ai", function (target) { + var evt = _status.event.getParent(); + return ( + get.effect( + target, + { name: "juedou" }, + evt.player, + _status.event.player + ) - 2 + ); + }); } - } - else event.finish(); - 'step 2' - if(result.targets){ - player.useCard({name:'juedou',isCard:true},result.targets[0],'noai'); + } else event.finish(); + "step 2"; + if (result.targets) { + player.useCard({ name: "juedou", isCard: true }, result.targets[0], "noai"); } }, - ai:{ - halfneg:true, + ai: { + halfneg: true, }, }, - new_retuxi:{ - audio:"retuxi", - trigger:{ - player:"phaseDrawBegin2", + new_retuxi: { + audio: "retuxi", + trigger: { + player: "phaseDrawBegin2", }, - direct:true, - preHidden:true, - filter:function(event,player){ - return event.num>0&&!event.numFixed&&game.hasPlayer(function(target){ - return target.countCards('h')>0&&player!=target; - }); + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + event.num > 0 && + !event.numFixed && + game.hasPlayer(function (target) { + return target.countCards("h") > 0 && player != target; + }) + ); }, - content:function (){ - "step 0" - var num=get.copy(trigger.num); - if(get.mode()=='guozhan'&&num>2) num=2; - player.chooseTarget(get.prompt('new_retuxi'),'获得至多'+get.translation(num)+'名角色的各一张手牌,然后少摸等量的牌',[1,num],function(card,player,target){ - return target.countCards('h')>0&&player!=target; - },function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkill('tuntian')) return att/10; - return 1-att; - }).setHiddenSkill('new_retuxi'); - "step 1" - if(result.bool){ + content: function () { + "step 0"; + var num = get.copy(trigger.num); + if (get.mode() == "guozhan" && num > 2) num = 2; + player + .chooseTarget( + get.prompt("new_retuxi"), + "获得至多" + get.translation(num) + "名角色的各一张手牌,然后少摸等量的牌", + [1, num], + function (card, player, target) { + return target.countCards("h") > 0 && player != target; + }, + function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkill("tuntian")) return att / 10; + return 1 - att; + } + ) + .setHiddenSkill("new_retuxi"); + "step 1"; + if (result.bool) { result.targets.sortBySeat(); - player.logSkill('new_retuxi',result.targets); + player.logSkill("new_retuxi", result.targets); player.gainMultiple(result.targets); - trigger.num-=result.targets.length; - } - else{ + trigger.num -= result.targets.length; + } else { event.finish(); } - "step 2" - if(trigger.num<=0) game.delay(); + "step 2"; + if (trigger.num <= 0) game.delay(); }, - ai:{ - threaten:1.6, - expose:0.2, + ai: { + threaten: 1.6, + expose: 0.2, }, }, - "new_reyiji":{ - audio:"reyiji", - trigger:{ - player:"damageEnd", + new_reyiji: { + audio: "reyiji", + trigger: { + player: "damageEnd", }, - frequent:true, - filter:function (event){ - return (event.num>0) + frequent: true, + filter: function (event) { + return event.num > 0; }, - getIndex(event, player, triggername){ + getIndex(event, player, triggername) { return event.num; }, - content:function (){ - 'step 0' + content: function () { + "step 0"; player.draw(2); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - event.num=2; - 'step 1' + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + event.given_map = {}; + event.num = 2; + "step 1"; player.chooseCardTarget({ - filterCard:function(card){ - return get.itemtype(card)=='card'&&!card.hasGaintag('reyiji_tag'); + filterCard: function (card) { + return get.itemtype(card) == "card" && !card.hasGaintag("reyiji_tag"); }, - filterTarget:lib.filter.notMe, - selectCard:[1,event.num], - prompt:'请选择要分配的卡牌和目标', - ai1:function(card){ - if(!ui.selected.cards.length) return 1; + filterTarget: lib.filter.notMe, + selectCard: [1, event.num], + prompt: "请选择要分配的卡牌和目标", + ai1: function (card) { + if (!ui.selected.cards.length) return 1; return 0; }, - ai2:function(target){ - var player=_status.event.player,card=ui.selected.cards[0]; - var val=target.getUseValue(card); - if(val>0) return val*get.attitude(player,target)*2; - return get.value(card,target)*get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player, + card = ui.selected.cards[0]; + var val = target.getUseValue(card); + if (val > 0) return val * get.attitude(player, target) * 2; + return get.value(card, target) * get.attitude(player, target); }, }); - 'step 2' - if(result.bool){ - var res=result.cards,target=result.targets[0].playerid; - player.addGaintag(res,'reyiji_tag'); - event.num-=res.length - if(!event.given_map[target]) event.given_map[target]=[]; + "step 2"; + if (result.bool) { + var res = result.cards, + target = result.targets[0].playerid; + player.addGaintag(res, "reyiji_tag"); + event.num -= res.length; + if (!event.given_map[target]) event.given_map[target] = []; event.given_map[target].addArray(res); - if(event.num>0) event.goto(1); - } - else if(event.num==2){ - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (event.num > 0) event.goto(1); + } else if (event.num == 2) { + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } event.finish(); } - 'step 3' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + "step 3"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var map=[],cards=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - if(player!==source&&(get.mode()!=='identity'||player.identity!=='nei')) player.addExpose(0.18); - map.push([source,event.given_map[i]]); + var map = [], + cards = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + if (player !== source && (get.mode() !== "identity" || player.identity !== "nei")) + player.addExpose(0.18); + map.push([source, event.given_map[i]]); cards.addArray(event.given_map[i]); } game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); }, - ai:{ - maixie:true, - "maixie_hp":true, - result:{ - effect:function (card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + result: { + effect: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(player.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (player.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } }, }, - threaten:0.6, + threaten: 0.6, }, }, - "new_rejianxiong":{ - audio:"rejianxiong", - audioname:['shen_caopi'], - trigger:{ - player:"damageEnd", + new_rejianxiong: { + audio: "rejianxiong", + audioname: ["shen_caopi"], + trigger: { + player: "damageEnd", }, - content:function (){ - "step 0" - if(get.itemtype(trigger.cards)=='cards'&&get.position(trigger.cards[0],true)=='o'){ - player.gain(trigger.cards,"gain2"); + content: function () { + "step 0"; + if ( + get.itemtype(trigger.cards) == "cards" && + get.position(trigger.cards[0], true) == "o" + ) { + player.gain(trigger.cards, "gain2"); } - player.draw('nodelay'); + player.draw("nodelay"); }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function (card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target){ - var cards=card.cards,evt=_status.event; - if(evt.player==target&&card.name=='damage'&&evt.getParent().type=='card') cards=evt.getParent().cards.filterInD(); - if(target.hp<=1) return; - if(get.itemtype(cards)!='cards') return; - for(var i of cards){ - if(get.name(i,target)=='tao') return [1,5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage") && player != target) { + var cards = card.cards, + evt = _status.event; + if ( + evt.player == target && + card.name == "damage" && + evt.getParent().type == "card" + ) + cards = evt.getParent().cards.filterInD(); + if (target.hp <= 1) return; + if (get.itemtype(cards) != "cards") return; + for (var i of cards) { + if (get.name(i, target) == "tao") return [1, 5]; } - if(get.value(cards,target)>=(7+target.getDamagedHp())) return [1,3]; - return [1,0.6]; + if (get.value(cards, target) >= 7 + target.getDamagedHp()) return [1, 3]; + return [1, 0.6]; } }, }, }, }, - "new_reluoyi":{ - audio:"reluoyi", - trigger:{ - player:"phaseDrawBegin1", + new_reluoyi: { + audio: "reluoyi", + trigger: { + player: "phaseDrawBegin1", }, - forced:true, - locked:false, - filter:function(event,player){ + forced: true, + locked: false, + filter: function (event, player) { return !event.numFixed; }, - content:function (){ - "step 0" - var cards=get.cards(3); + content: function () { + "step 0"; + var cards = get.cards(3); game.cardsGotoOrdering(cards); - player.showCards(cards,'裸衣'); - var cardsx=[]; - for(var i=0;i=trigger.num; + event.cards = cardsx; + player.chooseBool( + "是否放弃摸牌" + (cardsx.length ? ",改为获得" + get.translation(cardsx) : "") + "?" + ).ai = function () { + var num = 3; + return cardsx.length >= trigger.num; }; - "step 1" - if(result.bool){ - if(cards.length) player.gain(cards,'gain2'); + "step 1"; + if (result.bool) { + if (cards.length) player.gain(cards, "gain2"); //game.cardsDiscard(cards2); - player.addTempSkill('reluoyi2',{player:'phaseBefore'}); + player.addTempSkill("reluoyi2", { player: "phaseBefore" }); trigger.changeToZero(); } //else game.cardsDiscard(cards); }, }, - "new_rewusheng":{ - mod:{ - targetInRange:function (card){ - if(get.suit(card)=='diamond'&&card.name=='sha') return true; + new_rewusheng: { + mod: { + targetInRange: function (card) { + if (get.suit(card) == "diamond" && card.name == "sha") return true; }, }, - locked:false, - audio:"wusheng", - audioname:['re_guanyu','guanzhang','jsp_guanyu','guansuo','re_guanzhang','dc_jsp_guanyu'], - audioname2:{ - dc_guansuo:'wusheng_guansuo', + locked: false, + audio: "wusheng", + audioname: [ + "re_guanyu", + "guanzhang", + "jsp_guanyu", + "guansuo", + "re_guanzhang", + "dc_jsp_guanyu", + ], + audioname2: { + dc_guansuo: "wusheng_guansuo", }, - enable:["chooseToRespond","chooseToUse"], - filterCard:function(card,player){ - if(get.zhu(player,'shouyue')) return true; - return get.color(card)=='red'; + enable: ["chooseToRespond", "chooseToUse"], + filterCard: function (card, player) { + if (get.zhu(player, "shouyue")) return true; + return get.color(card) == "red"; }, - position:"hes", - viewAs:{ - name:"sha", + position: "hes", + viewAs: { + name: "sha", }, - viewAsFilter:function(player){ - if(get.zhu(player,'shouyue')){ - if(!player.countCards('hes')) return false; - } - else{ - if(!player.countCards('hes',{color:'red'})) return false; + viewAsFilter: function (player) { + if (get.zhu(player, "shouyue")) { + if (!player.countCards("hes")) return false; + } else { + if (!player.countCards("hes", { color: "red" })) return false; } }, - prompt:"将一张红色牌当杀使用或打出", - check:function(card){ - var val=get.value(card); - if(_status.event.name=='chooseToRespond') return 1/Math.max(0.1,val); - return 5-val; + prompt: "将一张红色牌当杀使用或打出", + check: function (card) { + var val = get.value(card); + if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val); + return 5 - val; }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - if(get.zhu(player,'shouyue')){ - if(!player.countCards('hes')) return false; - } - else{ - if(!player.countCards('hes',{color:'red'})) return false; + ai: { + respondSha: true, + skillTagFilter: function (player) { + if (get.zhu(player, "shouyue")) { + if (!player.countCards("hes")) return false; + } else { + if (!player.countCards("hes", { color: "red" })) return false; } }, }, }, - wusheng_guansuo:{audio:2}, - "new_yijue":{ - audio:"yijue", - enable:"phaseUse", - usable:1, - position:"he", - filterTarget:function (card,player,target){ - return player!=target&&target.countCards('h'); + wusheng_guansuo: { audio: 2 }, + new_yijue: { + audio: "yijue", + enable: "phaseUse", + usable: 1, + position: "he", + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); }, - filterCard:true, - check:function (card){ - return 8-get.value(card); + filterCard: true, + check: function (card) { + return 8 - get.value(card); }, - content:function (){ - "step 0" - if(!target.countCards('h')){ + content: function () { + "step 0"; + if (!target.countCards("h")) { event.finish(); return; - } - else target.chooseCard(true,'h').set('ai',function(card){ - var player=_status.event.player; - if((player.hasShan()||player.hp<3)&&get.color(card)=='black') return 0.5; - return Math.max(1,20-get.value(card)); - }); - "step 1" + } else + target.chooseCard(true, "h").set("ai", function (card) { + var player = _status.event.player; + if ((player.hasShan() || player.hp < 3) && get.color(card) == "black") return 0.5; + return Math.max(1, 20 - get.value(card)); + }); + "step 1"; target.showCards(result.cards); - event.card2=result.cards[0]; - if(get.color(event.card2)=='black'){ - if(!target.hasSkill('fengyin')){ - target.addTempSkill('fengyin'); + event.card2 = result.cards[0]; + if (get.color(event.card2) == "black") { + if (!target.hasSkill("fengyin")) { + target.addTempSkill("fengyin"); } - target.addTempSkill('new_yijue2'); + target.addTempSkill("new_yijue2"); event.finish(); - } - else if(get.color(event.card2)=='red'){ - player.gain(event.card2,target,'give','bySelf'); - if(target.hp0; + } else if (get.color(event.card2) == "red") { + player.gain(event.card2, target, "give", "bySelf"); + if (target.hp < target.maxHp) { + player.chooseBool("是否让目标回复1点体力?").ai = function (event, player) { + return get.recoverEffect(target, player, player) > 0; }; } } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { target.recover(); } }, - ai:{ - result:{ - target:function(player,target){ - var hs=player.getCards('h'); - if(hs.length<3) return 0; - if(target.countCards('h')>target.hp+1&&get.recoverEffect(target)>0){ + ai: { + result: { + target: function (player, target) { + var hs = player.getCards("h"); + if (hs.length < 3) return 0; + if (target.countCards("h") > target.hp + 1 && get.recoverEffect(target) > 0) { return 1; } - if(player.canUse('sha',target)&&(player.countCards('h','sha')||player.countCards('he',{color:'red'}))){ + if ( + player.canUse("sha", target) && + (player.countCards("h", "sha") || player.countCards("he", { color: "red" })) + ) { return -2; } return -0.5; }, }, - order:9, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg.target.hasSkillTag('new_yijue2')) return false; + order: 9, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (!arg.target.hasSkillTag("new_yijue2")) return false; }, }, }, - new_yijue2:{ - trigger:{ - player:"damageBegin1", + new_yijue2: { + trigger: { + player: "damageBegin1", }, - filter:function(event){ - return event.source&&event.source==_status.currentPhase&&event.card&&event.card.name=='sha'&&get.suit(event.card)=='heart'&&event.notLink(); + filter: function (event) { + return ( + event.source && + event.source == _status.currentPhase && + event.card && + event.card.name == "sha" && + get.suit(event.card) == "heart" && + event.notLink() + ); }, - popup:false, - forced:true, - charlotte:true, - content:function(){ + popup: false, + forced: true, + charlotte: true, + content: function () { trigger.num++; }, - mark:true, - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + mark: true, + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, }, - intro:{ - content:"不能使用或打出手牌", + intro: { + content: "不能使用或打出手牌", }, }, - paoxiao_re_zhangfei:{audio:2}, - "new_repaoxiao":{ - audio:"paoxiao", - firstDo:true, - audioname2:{ - old_guanzhang:'old_fuhun', - xin_zhangfei:'paoxiao_re_zhangfei', - dc_xiahouba:'paoxiao_xiahouba', + paoxiao_re_zhangfei: { audio: 2 }, + new_repaoxiao: { + audio: "paoxiao", + firstDo: true, + audioname2: { + old_guanzhang: "old_fuhun", + xin_zhangfei: "paoxiao_re_zhangfei", + dc_xiahouba: "paoxiao_xiahouba", }, - audioname:['re_zhangfei','guanzhang','xiahouba','re_guanzhang'], - trigger:{player:'useCard1'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&(!event.audioed||!player.hasSkill('new_repaoxiao2')); + audioname: ["re_zhangfei", "guanzhang", "xiahouba", "re_guanzhang"], + trigger: { player: "useCard1" }, + forced: true, + filter: function (event, player) { + return event.card.name == "sha" && (!event.audioed || !player.hasSkill("new_repaoxiao2")); }, - content:function(){ - trigger.audioed=true; - player.addTempSkill('new_repaoxiao2'); + content: function () { + trigger.audioed = true; + player.addTempSkill("new_repaoxiao2"); }, - mod:{ - cardUsable:function (card,player,num){ - if(card.name=='sha') return Infinity; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return Infinity; }, }, - ai:{ - unequip:true, - skillTagFilter:function (player,tag,arg){ - if(!get.zhu(player,'shouyue')) return false; - if(arg&&arg.name=='sha') return true; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!get.zhu(player, "shouyue")) return false; + if (arg && arg.name == "sha") return true; return false; }, }, }, - new_repaoxiao2:{ - charlotte:true, - mod:{ - targetInRange:function (card,player){ - if(card.name=='sha') return true; + new_repaoxiao2: { + charlotte: true, + mod: { + targetInRange: function (card, player) { + if (card.name == "sha") return true; }, }, }, - "new_tishen":{ - trigger:{ - player:"phaseUseEnd", + new_tishen: { + trigger: { + player: "phaseUseEnd", }, - check:function (event,player){ - var num=0; - var he=player.getCards('he'); - for(var i=0;ievt.card==event.card)&&event.cards.filterInD('od').length; + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.targets && + event.targets.includes(player) && + !player.hasHistory("damage", (evt) => evt.card == event.card) && + event.cards.filterInD("od").length + ); }, - forced:true, - charlotte:true, - content:function (){ - player.gain(trigger.cards.filterInD('od'),'gain2'); + forced: true, + charlotte: true, + content: function () { + player.gain(trigger.cards.filterInD("od"), "gain2"); }, }, - new_qingjian:{ - audio:"qingjian", - trigger:{ - player:"gainAfter", - global:'loseAsyncAfter', + new_qingjian: { + audio: "qingjian", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - direct:true, - usable:1, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - if(evt&&evt.player==player) return false; - return event.getg(player).length>0; + direct: true, + usable: 1, + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + if (evt && evt.player == player) return false; + return event.getg(player).length > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseCardTarget({ - position:'he', - filterCard:true, - selectCard:[1,Infinity], - filterTarget:function(card,player,target){ - return player!=target; + position: "he", + filterCard: true, + selectCard: [1, Infinity], + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - if(card.name!='du'&&get.attitude(_status.event.player,_status.currentPhase)<0&&_status.currentPhase.needsToDiscard()) return -1; - for(var i=0;i_status.event.player.countCards('h')) return 0; - return att-4; + if (target.countCards("h") > _status.event.player.countCards("h")) return 0; + return att - 4; }, - prompt:get.prompt2('new_qingjian'), + prompt: get.prompt2("new_qingjian"), }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - var cards=result.cards; - var type=[]; - for(var i=0;i0&&get.attitude(player,current)>2); - })>1&&get.color(card)=='black'&&player.countCards('h',{color:'red'})>0) return 3-get.value(card); - return 9-get.value(card); + audio: 2, + enable: "phaseUse", + filterCard: true, + check: function (card) { + var player = _status.event.player; + if ( + game.countPlayer(function (current) { + return ( + get.recoverEffect(current, player, player) > 0 && + get.attitude(player, current) > 2 + ); + }) > 1 && + get.color(card) == "black" && + player.countCards("h", { color: "red" }) > 0 + ) + return 3 - get.value(card); + return 9 - get.value(card); }, - filter:function (event,player){ - return !player.hasSkill('new_reqingnang_off2'); + filter: function (event, player) { + return !player.hasSkill("new_reqingnang_off2"); }, - filterTarget:function (card,player,target){ - if(target.hp>=target.maxHp||target.hasSkill('new_reqingnang_off')) return false; + filterTarget: function (card, player, target) { + if (target.hp >= target.maxHp || target.hasSkill("new_reqingnang_off")) return false; return true; }, - content:function (){ - target.addTempSkill('new_reqingnang_off'); - if(get.color(cards[0])=='black') player.addTempSkill('new_reqingnang_off2'); + content: function () { + target.addTempSkill("new_reqingnang_off"); + if (get.color(cards[0]) == "black") player.addTempSkill("new_reqingnang_off2"); target.recover(); }, - ai:{ - order:9, - result:{ - target:function (player,target){ - if(target.hp==1) return 5; - if(player==target&&player.countCards('h')>player.hp) return 5; + ai: { + order: 9, + result: { + target: function (player, target) { + if (target.hp == 1) return 5; + if (player == target && player.countCards("h") > player.hp) return 5; return 2; }, }, - threaten:2, + threaten: 2, }, }, - reyaowu:{ - trigger:{player:'damageBegin3'}, - audio:'new_reyaowu', - forced:true, - filter:function(event){ - return event.card&&(get.color(event.card)!='red'||event.source&&event.source.isIn()); + reyaowu: { + trigger: { player: "damageBegin3" }, + audio: "new_reyaowu", + forced: true, + filter: function (event) { + return ( + event.card && + (get.color(event.card) != "red" || (event.source && event.source.isIn())) + ); }, - content:function(){ - trigger[get.color(trigger.card)!='red'?'player':'source'].draw(); + content: function () { + trigger[get.color(trigger.card) != "red" ? "player" : "source"].draw(); + }, + ai: { + effect: { + target: (card, player, target) => { + if ( + typeof card !== "object" || + !get.tag(card, "damage") || + target.hasSkill("gangzhi") + ) + return; + if (player.hasSkillTag("jueqing", null, true)) return; + if (get.color(card) === "red") return [1, 0, 1, 0.6]; + return [1, 0.6]; + }, + }, }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(typeof card!=='object'||!get.tag(card,'damage')||target.hasSkill('gangzhi')) return; - if(player.hasSkillTag('jueqing',null,true)) return; - if(get.color(card)==='red') return [1,0,1,0.6]; - return [1,0.6]; - } - } - } }, - "new_reyaowu":{ - trigger:{ - player:"damageBegin3", + new_reyaowu: { + trigger: { + player: "damageBegin3", }, //priority:1, - audio:2, - audioname:['sb_huaxiong'], - filter:function(event){ - return event.card&&event.card.name=='sha'&&(get.color(event.card)!='red'||event.source&&event.source.isIn()); + audio: 2, + audioname: ["sb_huaxiong"], + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + (get.color(event.card) != "red" || (event.source && event.source.isIn())) + ); }, - forced:true, - content:function(){ - if(get.color(trigger.card)!='red') player.draw(); + forced: true, + content: function () { + if (get.color(trigger.card) != "red") player.draw(); else trigger.source.chooseDrawRecover(true); }, - ai:{ - effect:{ - target:(card,player,target,current)=>{ - if(card.name=='sha'){ - if(get.color(card)=='red'){ - let num=player.isDamaged()?1.6:0.7; - if(get.attitude(player,target)>0&&player.hp<3) return [1,0,1,num]; - return [1,0,1,num/2]; + ai: { + effect: { + target: (card, player, target, current) => { + if (card.name == "sha") { + if (get.color(card) == "red") { + let num = player.isDamaged() ? 1.6 : 0.7; + if (get.attitude(player, target) > 0 && player.hp < 3) + return [1, 0, 1, num]; + return [1, 0, 1, num / 2]; } - return [1,0.6]; + return [1, 0.6]; } }, }, }, }, - reguanxing:{ - audio:'guanxing', - audioname:['jiangwei','re_jiangwei','re_zhugeliang','gexuan','ol_jiangwei'], - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - frequent:true, - filter:function(event,player,name){ - if(name=='phaseJieshuBegin'){ - return player.hasSkill('reguanxing_on'); + reguanxing: { + audio: "guanxing", + audioname: ["jiangwei", "re_jiangwei", "re_zhugeliang", "gexuan", "ol_jiangwei"], + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + frequent: true, + filter: function (event, player, name) { + if (name == "phaseJieshuBegin") { + return player.hasSkill("reguanxing_on"); } return true; }, - content:function(){ - "step 0" - var num=game.countPlayer()<4?3:5; - var cards=get.cards(num); + content: function () { + "step 0"; + var num = game.countPlayer() < 4 ? 3 : 5; + var cards = get.cards(num); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','观星:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var target=(_status.event.getTrigger().name=='phaseZhunbei')?player:player.next; - var att=get.sgn(get.attitude(player,target)); - var top=[]; - var judges=target.getCards('j'); - var stopped=false; - if(player!=target||!target.hasWuxie()){ - for(var i=0;i0)) break; + while (cards.length) { + if (get.value(cards[0], player) <= 5 == att > 0) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - "step 1" - var top=result.moved[0]; - var bottom=result.moved[1]; + bottom = cards; + return [top, bottom]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - game.cardsGotoPile( - top.concat(bottom), - ['top_cards',top], - function(event,card){ - if(event.top_cards.includes(card)) return ui.cardPile.firstChild; - return null; - } - ) - if(event.triggername=='phaseZhunbeiBegin'&&top.length==0){ - player.addTempSkill('reguanxing_on'); + game.cardsGotoPile(top.concat(bottom), ["top_cards", top], function (event, card) { + if (event.top_cards.includes(card)) return ui.cardPile.firstChild; + return null; + }); + if (event.triggername == "phaseZhunbeiBegin" && top.length == 0) { + player.addTempSkill("reguanxing_on"); } - player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); - game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶'); - "step 2" + player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下"); + game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶"); + "step 2"; game.delayx(); }, - subSkill:{ - on:{charlotte:true} - } + subSkill: { + on: { charlotte: true }, + }, }, - reluoshen:{ - audio:2, - locked:false, - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - content:function(){ - "step 0" - player.addTempSkill('reluoshen_add'); - event.cards=[]; - "step 1" - var next=player.judge(function(card){ - if(get.color(card)=='black') return 1.5; + reluoshen: { + audio: 2, + locked: false, + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + content: function () { + "step 0"; + player.addTempSkill("reluoshen_add"); + event.cards = []; + "step 1"; + var next = player.judge(function (card) { + if (get.color(card) == "black") return 1.5; return -1.5; }); - next.judge2=function(result){ + next.judge2 = function (result) { return result.bool; }; - if(get.mode()!='guozhan'&&!player.hasSkillTag('rejudge')) next.set('callback',function(){ - if(event.judgeResult.color=='black'&&get.position(card,true)=='o'){ - player.gain(card,'gain2').gaintag.add('reluoshen'); - } - }); - else next.set('callback',function(){ - if(event.judgeResult.color=='black') event.getParent().orderingCards.remove(card); - }); - "step 2" - if(result.bool){ + if (get.mode() != "guozhan" && !player.hasSkillTag("rejudge")) + next.set("callback", function () { + if (event.judgeResult.color == "black" && get.position(card, true) == "o") { + player.gain(card, "gain2").gaintag.add("reluoshen"); + } + }); + else + next.set("callback", function () { + if (event.judgeResult.color == "black") + event.getParent().orderingCards.remove(card); + }); + "step 2"; + if (result.bool) { event.cards.push(result.card); - player.chooseBool('是否再次发动【洛神】?').set('frequentSkill','reluoshen'); - } - else{ - for(var i=0;i0; + }, }, - check:function(card){ - var player=_status.event.player; - if(get.position(card)=='e'){ - var subtype=get.subtype(card); - if(!game.hasPlayer(function(current){ - return current!=player&¤t.hp!=player.hp&&get.attitude(player,current)>0&&!current.countCards('e',{subtype:subtype}); - })){ + }, + rejieyin: { + audio: 2, + enable: "phaseUse", + filterCard: true, + usable: 1, + position: "he", + filter: function (event, player) { + return player.countCards("he") > 0; + }, + check: function (card) { + var player = _status.event.player; + if (get.position(card) == "e") { + var subtype = get.subtype(card); + if ( + !game.hasPlayer(function (current) { + return ( + current != player && + current.hp != player.hp && + get.attitude(player, current) > 0 && + !current.countCards("e", { subtype: subtype }) + ); + }) + ) { return 0; } - if(player.countCards('h',{subtype:subtype})) return 20-get.value(card); - return 10-get.value(card); - } - else{ - if(player.countCards('e')) return 0; - if(player.countCards('h',{type:'equip'})) return 0; - return 8-get.value(card); + if (player.countCards("h", { subtype: subtype })) return 20 - get.value(card); + return 10 - get.value(card); + } else { + if (player.countCards("e")) return 0; + if (player.countCards("h", { type: "equip" })) return 0; + return 8 - get.value(card); } }, - filterTarget:function(card,player,target){ - if(!target.hasSex('male')) return false; - var card=ui.selected.cards[0]; - if(!card) return false; - if(get.position(card)=='e'&&!target.canEquip(card)) return false; + filterTarget: function (card, player, target) { + if (!target.hasSex("male")) return false; + var card = ui.selected.cards[0]; + if (!card) return false; + if (get.position(card) == "e" && !target.canEquip(card)) return false; return true; }, - discard:false, - delay:false, - lose:false, - content:function(){ - 'step 0' - if(get.position(cards[0])=='e') event._result={index:0}; - else if(get.type(cards[0])!='equip'||!target.canEquip(cards[0])) event._result={index:1}; - else player.chooseControl().set('choiceList',[ - '将'+get.translation(cards[0])+'置入'+get.translation(target)+'的装备区', - '弃置'+get.translation(cards[0]), - ]).ai=function(){return 1}; - 'step 1' - if(result.index==0){ - player.$give(cards,target,false); + discard: false, + delay: false, + lose: false, + content: function () { + "step 0"; + if (get.position(cards[0]) == "e") event._result = { index: 0 }; + else if (get.type(cards[0]) != "equip" || !target.canEquip(cards[0])) + event._result = { index: 1 }; + else + player + .chooseControl() + .set("choiceList", [ + "将" + + get.translation(cards[0]) + + "置入" + + get.translation(target) + + "的装备区", + "弃置" + get.translation(cards[0]), + ]).ai = function () { + return 1; + }; + "step 1"; + if (result.index == 0) { + player.$give(cards, target, false); target.equip(cards[0]); - } - else{ + } else { player.discard(cards); } - 'step 2' - if(player.hp>target.hp){ + "step 2"; + if (player.hp > target.hp) { player.draw(); - if(target.isDamaged()) target.recover(); - } - else if(player.hptarget.hp){ - if(target.isHealthy()){ - if(!player.needsToDiscard(1)||goon()) return 0.1; + if (player.hp > target.hp) { + if (target.isHealthy()) { + if (!player.needsToDiscard(1) || goon()) return 0.1; return 0; } return 1; } return 0; - } - } - } - }, - rejiuyuan:{ - audio:2, - zhuSkill:true, - trigger:{global:'recoverBefore'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.group=='wu'&&player.hp<=event.player.hp&& - event.getParent().name!='rejiuyuan'&&player.hasZhuSkill('rejiuyuan',event.player) + }, + }, }, - content:function(){ - 'step 0' - trigger.player.chooseBool('是否对'+get.translation(player)+'发动【救援】?','改为令其回复1点体力,然后你摸一张牌').set('ai',function(){ - var evt=_status.event; - return get.attitude(evt.player,evt.getParent().player)>0; - }); - 'step 1' - if(result.bool){ - player.logSkill('rejiuyuan'); - trigger.player.line(player,'green'); + }, + rejiuyuan: { + audio: 2, + zhuSkill: true, + trigger: { global: "recoverBefore" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.group == "wu" && + player.hp <= event.player.hp && + event.getParent().name != "rejiuyuan" && + player.hasZhuSkill("rejiuyuan", event.player) + ); + }, + content: function () { + "step 0"; + trigger.player + .chooseBool( + "是否对" + get.translation(player) + "发动【救援】?", + "改为令其回复1点体力,然后你摸一张牌" + ) + .set("ai", function () { + var evt = _status.event; + return get.attitude(evt.player, evt.getParent().player) > 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("rejiuyuan"); + trigger.player.line(player, "green"); trigger.cancel(); player.recover(); trigger.player.draw(); } }, }, - 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)2||!player.countCards('h',function(card){ - return get.value(card)>=8; - }))){ + locked: false, + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: lib.filter.cardDiscardable, + discard: false, + lose: false, + delay: false, + selectCard: [1, Infinity], + check: function (card) { + var player = _status.event.player; + if ( + get.position(card) == "h" && + !player.countCards("h", "du") && + (player.hp > 2 || + !player.countCards("h", function (card) { + return get.value(card) >= 8; + })) + ) { return 1; } - return 6-get.value(card) + return 6 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.discard(cards); - event.num=1; - var hs=player.getCards('h'); - if(!hs.length) event.num=0; - for(var i=0;iget.value(i)>Math.max(6,9-player.hp),'he')) return 1; + ai: { + order: function (item, player) { + if (player.hasCard((i) => get.value(i) > Math.max(6, 9 - player.hp), "he")) return 1; return 10; }, - result:{ - player:1 + 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'); + 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 + threaten: 1.55, }, }, - reqicai:{ - mod:{ - targetInRange:function(card,player,target,now){ - var type=get.type(card); - if(type=='trick'||type=='delay') return true; + reqicai: { + mod: { + targetInRange: function (card, player, target, now) { + var type = get.type(card); + if (type == "trick" || type == "delay") return true; }, - canBeDiscarded:function(card){ - if(get.position(card)=='e'&&['equip2','equip5'].includes(get.subtype(card))) return false; + canBeDiscarded: function (card) { + if (get.position(card) == "e" && ["equip2", "equip5"].includes(get.subtype(card))) + return false; }, }, }, - rejizhi:{ - audio:2, - audioname:['lukang'], - locked:false, - trigger:{player:'useCard'}, - frequent:true, - filter:function(event){ - return (get.type(event.card,'trick')=='trick'&&event.card.isCard); + rejizhi: { + audio: 2, + audioname: ["lukang"], + locked: false, + trigger: { player: "useCard" }, + frequent: true, + filter: function (event) { + return get.type(event.card, "trick") == "trick" && event.card.isCard; }, - init:function(player){ - player.storage.rejizhi=0; + init: function (player) { + player.storage.rejizhi = 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - event.card=result[0]; - if(get.type(event.card)=='basic'){ - player.chooseBool('是否弃置'+get.translation(event.card)+'并令本回合手牌上限+1?').set('ai',function(evt,player){ - return _status.currentPhase==player&&player.needsToDiscard(-3)&&_status.event.value<6; - }).set('value',get.value(event.card,player)); + "step 1"; + event.card = result[0]; + if (get.type(event.card) == "basic") { + player + .chooseBool("是否弃置" + get.translation(event.card) + "并令本回合手牌上限+1?") + .set("ai", function (evt, player) { + return ( + _status.currentPhase == player && + player.needsToDiscard(-3) && + _status.event.value < 6 + ); + }) + .set("value", get.value(event.card, player)); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.discard(event.card); player.storage.rejizhi++; - if(_status.currentPhase==player){ - player.markSkill('rejizhi'); + if (_status.currentPhase == player) { + player.markSkill("rejizhi"); } } }, - ai:{ - threaten:1.4, - noautowuxie:true, + ai: { + threaten: 1.4, + noautowuxie: true, }, - mod:{ - maxHandcard:function(player,num){ - return num+player.storage.rejizhi; - } + mod: { + maxHandcard: function (player, num) { + return num + player.storage.rejizhi; + }, }, - intro:{ - content:'本回合手牌上限+#' + intro: { + content: "本回合手牌上限+#", + }, + group: "rejizhi_clear", + subSkill: { + clear: { + trigger: { global: "phaseAfter" }, + silent: true, + content: function () { + player.storage.rejizhi = 0; + player.unmarkSkill("rejizhi"); + }, + }, }, - group:'rejizhi_clear', - subSkill:{ - clear:{ - trigger:{global:'phaseAfter'}, - silent:true, - content:function(){ - player.storage.rejizhi=0; - player.unmarkSkill('rejizhi'); - } - } - } }, - rebiyue:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - content:function(){ - var num=1; - if(!player.countCards('h')){ - num=2; + rebiyue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + content: function () { + var num = 1; + if (!player.countCards("h")) { + num = 2; } player.draw(num); }, }, - rerende:{ - audio:2, - audioname:['gz_jun_liubei','shen_caopi'], - enable:'phaseUse', - filterCard:true, - selectCard:[1,Infinity], - discard:false, - lose:false, - delay:false, - filterTarget:function(card,player,target){ - if(player.storage.rerende2&&player.storage.rerende2.includes(target)) return false; - return player!=target; + rerende: { + audio: 2, + audioname: ["gz_jun_liubei", "shen_caopi"], + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + discard: false, + lose: false, + delay: false, + filterTarget: function (card, player, target) { + if (player.storage.rerende2 && player.storage.rerende2.includes(target)) return false; + return player != target; }, - onremove:['rerende','rerende2'], - check:function(card){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(ui.selected.cards.length>=Math.max(2,player.countCards('h')-player.hp)) return 0; - if(player.hp==player.maxHp||player.storage.rerende<0||player.countCards('h')<=1){ - var players=game.filterPlayer(); - for(var i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + onremove: ["rerende", "rerende2"], + check: function (card) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + var player = get.owner(card); + if (ui.selected.cards.length >= Math.max(2, player.countCards("h") - player.hp)) return 0; + if ( + player.hp == player.maxHp || + player.storage.rerende < 0 || + player.countCards("h") <= 1 + ) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - content:function(){ - 'step 0' - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'&&!evt.rerende){ - var next=game.createEvent('rerende_clear'); + content: function () { + "step 0"; + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse" && !evt.rerende) { + var next = game.createEvent("rerende_clear"); _status.event.next.remove(next); evt.after.push(next); - evt.rerende=true; - next.player=player; + evt.rerende = true; + next.player = player; next.setContent(lib.skill.rerende1.content); } - if(!Array.isArray(player.storage.rerende2)){ - player.storage.rerende2=[]; + if (!Array.isArray(player.storage.rerende2)) { + player.storage.rerende2 = []; } player.storage.rerende2.push(target); - player.give(cards,target); - 'step 1' - if(typeof player.storage.rerende!='number'){ - player.storage.rerende=0; + player.give(cards, target); + "step 1"; + if (typeof player.storage.rerende != "number") { + player.storage.rerende = 0; } - if(player.storage.rerende>=0){ - player.storage.rerende+=cards.length; - if(player.storage.rerende>=2){ - var list=[]; - if(lib.filter.cardUsable({name:'sha'},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('sha',current); - })){ - list.push(['基本','','sha']); + if (player.storage.rerende >= 0) { + player.storage.rerende += cards.length; + if (player.storage.rerende >= 2) { + var list = []; + if ( + lib.filter.cardUsable( + { name: "sha" }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("sha", current); + }) + ) { + list.push(["基本", "", "sha"]); } - for(var i of lib.inpile_nature){ - if(lib.filter.cardUsable({name:'sha',nature:i},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse({name:'sha',nature:i},current); - })){ - list.push(['基本','','sha',i]); + for (var i of lib.inpile_nature) { + if ( + lib.filter.cardUsable( + { name: "sha", nature: i }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse({ name: "sha", nature: i }, current); + }) + ) { + list.push(["基本", "", "sha", i]); } } - if(lib.filter.cardUsable({name:'tao'},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('tao',current); - })){ - list.push(['基本','','tao']); + if ( + lib.filter.cardUsable( + { name: "tao" }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("tao", current); + }) + ) { + list.push(["基本", "", "tao"]); } - if(lib.filter.cardUsable({name:'jiu'},player,event.getParent('chooseToUse'))&&game.hasPlayer(function(current){ - return player.canUse('jiu',current); - })){ - list.push(['基本','','jiu']); + if ( + lib.filter.cardUsable( + { name: "jiu" }, + player, + event.getParent("chooseToUse") + ) && + game.hasPlayer(function (current) { + return player.canUse("jiu", current); + }) + ) { + list.push(["基本", "", "jiu"]); } - if(list.length){ - player.chooseButton(['是否视为使用一张基本牌?',[list,'vcard']]).set('ai',function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3],isCard:true}; - if(card.name=='tao'){ - if(player.hp==1||(player.hp==2&&!player.hasShan())||player.needsToDiscard()){ - return 5; + if (list.length) { + player + .chooseButton(["是否视为使用一张基本牌?", [list, "vcard"]]) + .set("ai", function (button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], + isCard: true, + }; + if (card.name == "tao") { + if ( + player.hp == 1 || + (player.hp == 2 && !player.hasShan()) || + player.needsToDiscard() + ) { + return 5; + } + return 1; } - return 1; - } - if(card.name=='sha'){ - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0 - })){ - if(card.nature=='fire') return 2.95; - if(card.nature=='thunder'||card.nature=='ice') return 2.92; - return 2.9; + if (card.name == "sha") { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + if (card.nature == "fire") return 2.95; + if (card.nature == "thunder" || card.nature == "ice") + return 2.92; + return 2.9; + } + return 0; + } + if (card.name == "jiu") { + return 0.5; } return 0; - } - if(card.name=='jiu'){ - return 0.5; - } - return 0; - }); - } - else{ + }); + } else { event.finish(); } - player.storage.rerende=-1; - } - else{ + player.storage.rerende = -1; + } else { event.finish(); } - } - else{ + } else { event.finish(); } - 'step 2' - if(result&&result.bool&&result.links[0]){ - var card={name:result.links[0][2],nature:result.links[0][3]}; - player.chooseUseTarget(card,true); + "step 2"; + if (result && result.bool && result.links[0]) { + var card = { name: result.links[0][2], nature: result.links[0][3] }; + player.chooseUseTarget(card, true); } }, - ai:{ - fireAttack:true, - order:function(skill,player){ - if(player.hp1){ + ai: { + fireAttack: true, + order: function (skill, player) { + if ( + player.hp < player.maxHp && + player.storage.rerende < 2 && + player.countCards("h") > 1 + ) { return 10; } return 4; }, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - var np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.rerende<0||player.countCards('h')<=1){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + var np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.rerende < 0 || + player.countCards("h") <= 1 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); - } + return Math.max(1, 5 - nh); + }, }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.type(card)=='equip'){ - if(player.countCards('e',{subtype:get.subtype(card)})){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })){ + effect: { + target: function (card, player, target) { + if (player == target && get.type(card) == "equip") { + if (player.countCards("e", { subtype: get.subtype(card) })) { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) { return 0; } } } - } + }, }, - threaten:0.8 - } - }, - rerende1:{ - trigger:{player:'phaseUseBegin'}, - silent:true, - content:function(){ - player.storage.rerende=0; - player.storage.rerende2=[]; - } - }, - liyu:{ - audio:2, - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.isIn()&&event.player.countGainableCards(player,'he')>0; + threaten: 0.8, }, - check:function(){ + }, + rerende1: { + trigger: { player: "phaseUseBegin" }, + silent: true, + content: function () { + player.storage.rerende = 0; + player.storage.rerende2 = []; + }, + }, + liyu: { + audio: 2, + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.player.isIn() && + event.player.countGainableCards(player, "he") > 0 + ); + }, + check: function () { return false; }, - content:function(){ - 'step 0' - trigger.player.chooseTarget(function(card,player,target){ - var evt=_status.event.getParent(); - return evt.player.canUse({name:'juedou'},target)&&target!=_status.event.player; - },get.prompt('liyu')).set('ai',function(target){ - var evt=_status.event.getParent(); - return get.effect(target,{name:'juedou'},evt.player,_status.event.player)-2; - }); - 'step 1' - if(result.bool){ - player.gainPlayerCard(trigger.player,'he',true); - event.target=result.targets[0]; - trigger.player.line(player,'green'); - } - else{ + content: function () { + "step 0"; + trigger.player + .chooseTarget(function (card, player, target) { + var evt = _status.event.getParent(); + return ( + evt.player.canUse({ name: "juedou" }, target) && + target != _status.event.player + ); + }, get.prompt("liyu")) + .set("ai", function (target) { + var evt = _status.event.getParent(); + return ( + get.effect(target, { name: "juedou" }, evt.player, _status.event.player) - 2 + ); + }); + "step 1"; + if (result.bool) { + player.gainPlayerCard(trigger.player, "he", true); + event.target = result.targets[0]; + trigger.player.line(player, "green"); + } else { event.finish(); } - 'step 2' - if(event.target){ - player.useCard({name:'juedou',isCard:true},event.target,'noai'); + "step 2"; + if (event.target) { + player.useCard({ name: "juedou", isCard: true }, event.target, "noai"); } }, - ai:{ - halfneg:true - } + ai: { + halfneg: true, + }, }, /*reqicai:{ trigger:{player:'equipEnd'}, @@ -12934,2671 +15731,3135 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, },*/ - retuxi:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - direct:true, - filter:function(event){ - return event.num>0; + retuxi: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + direct: true, + filter: function (event) { + return event.num > 0; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('retuxi'),[1,trigger.num],function(card,player,target){ - return target.countCards('h')>0&&player!=target&&target.countCards('h')>=player.countCards('h'); - },function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkill('tuntian')) return att/10; - return 1-att; - }); - "step 1" - if(result.bool){ - player.logSkill('retuxi',result.targets); + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("retuxi"), + [1, trigger.num], + function (card, player, target) { + return ( + target.countCards("h") > 0 && + player != target && + target.countCards("h") >= player.countCards("h") + ); + }, + function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkill("tuntian")) return att / 10; + return 1 - att; + } + ); + "step 1"; + if (result.bool) { + player.logSkill("retuxi", result.targets); player.gainMultiple(result.targets); - trigger.num-=result.targets.length; - } - else{ + trigger.num -= result.targets.length; + } else { event.finish(); } - "step 2" - if(trigger.num<=0) game.delay(); + "step 2"; + if (trigger.num <= 0) game.delay(); + }, + ai: { + threaten: 1.6, + expose: 0.2, }, - ai:{ - threaten:1.6, - expose:0.2 - } }, - reguicai:{ - audio:2, - trigger:{global:'judge'}, - direct:true, - filter:function(event,player){ - return player.countCards('hes')>0; + reguicai: { + audio: 2, + trigger: { global: "judge" }, + direct: true, + filter: function (event, player) { + return player.countCards("hes") > 0; }, - content:function(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('reguicai'),'hes',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result-get.value(card)/2; - } - else{ - return -result-get.value(card)/2; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'reguicai','highlight','noOrdering'); - } - else{ + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("reguicai"), + "hes", + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result - get.value(card) / 2; + } else { + return -result - get.value(card) / 2; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "reguicai", "highlight", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } - }, - refankui:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return (event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')&&event.num>0); + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, }, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" + }, + refankui: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return ( + event.source && + event.source.countGainableCards(player, event.source != player ? "he" : "e") && + event.num > 0 + ); + }, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - player.gainPlayerCard(get.prompt('refankui',trigger.source),trigger.source,get.buttonValue,trigger.source!=player?'he':'e').set('logSkill',[event.name,trigger.source]); - "step 2" - if(result.bool&&event.count>0&&trigger.source.countGainableCards(player,trigger.source!=player?'he':'e')>0&&player.hasSkill(event.name)) event.goto(1); + player + .gainPlayerCard( + get.prompt("refankui", trigger.source), + trigger.source, + get.buttonValue, + trigger.source != player ? "he" : "e" + ) + .set("logSkill", [event.name, trigger.source]); + "step 2"; + if ( + result.bool && + event.count > 0 && + trigger.source.countGainableCards(player, trigger.source != player ? "he" : "e") > + 0 && + player.hasSkill(event.name) + ) + event.goto(1); }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.countCards('he')>1&&get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - if(get.attitude(target,player)<0) return [1,1]; + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.countCards("he") > 1 && get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + if (get.attitude(target, player) < 0) return [1, 1]; } - } - } - } - }, - reluoyi:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - check:function(event,player){ - if(player.countCards('h','sha')) return true; - return Math.random()<0.5; + }, + }, }, - content:function(){ - "step 0" - player.addTempSkill('reluoyi2',{player:'phaseBefore'}); - trigger.cancel(null,null,'notrigger'); - "step 1" - event.cards=get.cards(3); - player.showCards(event.cards,'裸衣'); - "step 2" - for(var i=0;i0); + reganglie: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.source != undefined && event.num > 0; }, - check:function(event,player){ - return (get.attitude(player,event.source)<=0); + check: function (event, player) { + return get.attitude(player, event.source) <= 0; }, - logTarget:'source', - preHidden:true, - content:function(){ - "step 0" - event.num=trigger.num; - if(get.mode()=='guozhan') event.num=1; - "step 1" - player.judge(function(card){ - if(get.color(card)=='red') return 1; + logTarget: "source", + preHidden: true, + content: function () { + "step 0"; + event.num = trigger.num; + if (get.mode() == "guozhan") event.num = 1; + "step 1"; + player.judge(function (card) { + if (get.color(card) == "red") return 1; return 0; }); - "step 2" - if(result.color=='black'){ - if(trigger.source.countCards('he')){ - player.discardPlayerCard(trigger.source,'he',true); + "step 2"; + if (result.color == "black") { + if (trigger.source.countCards("he")) { + player.discardPlayerCard(trigger.source, "he", true); } - } - else if(trigger.source.isIn()){ + } else if (trigger.source.isIn()) { trigger.source.damage(); } event.num--; - if(event.num>0&&player.hasSkill('reganglie')){ - player.chooseBool(get.prompt2('reganglie')); - } - else{ + if (event.num > 0 && player.hasSkill("reganglie")) { + player.chooseBool(get.prompt2("reganglie")); + } else { event.finish(); } - "step 3" - if(result.bool){ - player.logSkill('reganglie',trigger.source); + "step 3"; + if (result.bool) { + player.logSkill("reganglie", trigger.source); event.goto(1); } }, - ai:{ - maixie_defend:true, - expose:0.4 - } + ai: { + maixie_defend: true, + expose: 0.4, + }, }, - qinxue:{ - skillAnimation:true, - animationColor:'wood', - audio:2, - unique:true, - juexingji:true, - derivation:'gongxin', - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - forced:true, - filter:function(event,player){ - if(player.countCards('h')>=player.hp+2) return true; + qinxue: { + skillAnimation: true, + animationColor: "wood", + audio: 2, + unique: true, + juexingji: true, + derivation: "gongxin", + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + forced: true, + filter: function (event, player) { + if (player.countCards("h") >= player.hp + 2) return true; return false; }, - content:function(){ - player.awakenSkill('qinxue'); + content: function () { + player.awakenSkill("qinxue"); player.loseMaxHp(); - player.chooseDrawRecover(2,true); - player.addSkills('gongxin'); - } - }, - qingjian:{ - audio:2, - unique:true, - trigger:{player:'gainAfter'}, - direct:true, - usable:4, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - if(evt&&evt.player==player) return false; - return event.getg(player).length>0; + player.chooseDrawRecover(2, true); + player.addSkills("gongxin"); }, - content:function(){ - "step 0" - event.cards=trigger.getg(player); - "step 1" + }, + qingjian: { + audio: 2, + unique: true, + trigger: { player: "gainAfter" }, + direct: true, + usable: 4, + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + if (evt && evt.player == player) return false; + return event.getg(player).length > 0; + }, + content: function () { + "step 0"; + event.cards = trigger.getg(player); + "step 1"; player.chooseCardTarget({ - filterCard:function(card){ + filterCard: function (card) { return _status.event.getParent().cards.includes(card); }, - selectCard:[1,event.cards.length], - filterTarget:function(card,player,target){ - return player!=target; + selectCard: [1, event.cards.length], + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - if(ui.selected.cards.length>0) return -1; - if(card.name=='du') return 20; - return (_status.event.player.countCards('h')-_status.event.player.hp); + ai1: function (card) { + if (ui.selected.cards.length > 0) return -1; + if (card.name == "du") return 20; + return _status.event.player.countCards("h") - _status.event.player.hp; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; - return 1-att; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; + return 1 - att; } - if(target.countCards('h')>_status.event.player.countCards('h')) return 0; - return att-4; + if (target.countCards("h") > _status.event.player.countCards("h")) return 0; + return att - 4; }, - prompt:'请选择要送人的卡牌' + prompt: "请选择要送人的卡牌", }); - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { player.storage.qingjian++; - player.logSkill('qingjian',result.targets); - result.targets[0].gain(result.cards,player,'give'); - for(var i=0;i0; + refanjian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - filterCard:true, - check:function(card){ - return 8-get.value(card); + filterCard: true, + check: function (card) { + return 8 - get.value(card); }, - discard:false, - lose:false, - delay:false, - content:function(){ - "step 0" - target.storage.refanjian=cards[0]; - player.give(cards[0],target); - "step 1" - var suit=get.suit(target.storage.refanjian); - if(!target.countCards('h')) event._result={control:'refanjian_hp'}; - else target.chooseControl('refanjian_card','refanjian_hp').ai=function(event,player){ - var cards=player.getCards('he',{suit:get.suit(player.storage.refanjian)}); - if(cards.length==1) return 0; - if(cards.length>=2){ - for(var i=0;i= 2) { + for (var i = 0; i < cards.length; i++) { + if (get.tag(cards[i], "save")) return 1; + } } - } - if(player.hp==1) return 0; - for(var i=0;i=8) return 1; - } - if(cards.length>2&&player.hp>2) return 1; - if(cards.length>3) return 1; - return 0; - } - "step 2" - if(result.control=='refanjian_card'){ + if (player.hp == 1) return 0; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) >= 8) return 1; + } + if (cards.length > 2 && player.hp > 2) return 1; + if (cards.length > 3) return 1; + return 0; + }; + "step 2"; + if (result.control == "refanjian_card") { target.showHandcards(); - } - else{ + } else { target.loseHp(); event.finish(); } - "step 3" - var suit=get.suit(target.storage.refanjian); - target.discard(target.getCards('he',function(i){ - return get.suit(i)==suit&&lib.filter.cardDiscardable(i,target,'refanjian'); - })); + "step 3"; + var suit = get.suit(target.storage.refanjian); + target.discard( + target.getCards("he", function (i) { + return get.suit(i) == suit && lib.filter.cardDiscardable(i, target, "refanjian"); + }) + ); delete target.storage.refanjian; }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return -target.countCards('he')-(player.countCards('h','du')?1:0); - } + ai: { + order: 9, + result: { + target: function (player, target) { + return -target.countCards("he") - (player.countCards("h", "du") ? 1 : 0); + }, }, - threaten:2, - } - }, - reqianxun:{ - audio:2, - trigger:{ - target:'useCardToBegin', - player:'judgeBefore', + threaten: 2, }, - filter:function(event,player){ - if(player.countCards('h')==0) return false; - if(event.getParent().name=='phaseJudge'){ + }, + reqianxun: { + audio: 2, + trigger: { + target: "useCardToBegin", + player: "judgeBefore", + }, + filter: function (event, player) { + if (player.countCards("h") == 0) return false; + if (event.getParent().name == "phaseJudge") { return true; } - if(event.name=='judge') return false; - if(event.targets&&event.targets.length>1) return false; - if(event.card&&get.type(event.card)=='trick'&&event.player!=player) return true; + if (event.name == "judge") return false; + if (event.targets && event.targets.length > 1) return false; + if (event.card && get.type(event.card) == "trick" && event.player != player) return true; }, - content:function(){ - var cards=player.getCards('h'); - player.addToExpansion(cards,'giveAuto',player).gaintag.add('reqianxun2'); - player.addSkill('reqianxun2'); + content: function () { + var cards = player.getCards("h"); + player.addToExpansion(cards, "giveAuto", player).gaintag.add("reqianxun2"); + player.addSkill("reqianxun2"); }, - ai:{ - effect:function(card,player,target){ - if(player==target||!target.hasFriend()) return; - var type=get.type(card); - var nh=Math.min(target.countCards(),game.countPlayer(i=>get.attitude(target,i)>0)); - if(type=='trick'){ - if(!get.tag(card,'multitarget')||get.info(card).singleCard){ - if(get.tag(card,'damage')) return [1.5,nh-1]; - return [1,nh]; + ai: { + effect: function (card, player, target) { + if (player == target || !target.hasFriend()) return; + var type = get.type(card); + var nh = Math.min( + target.countCards(), + game.countPlayer((i) => get.attitude(target, i) > 0) + ); + if (type == "trick") { + if (!get.tag(card, "multitarget") || get.info(card).singleCard) { + if (get.tag(card, "damage")) return [1.5, nh - 1]; + return [1, nh]; } - } - else if(type=='delay') return [0.5,0.5]; + } else if (type == "delay") return [0.5, 0.5]; }, - } - }, - reqianxun2:{ - trigger:{global:'phaseEnd'}, - forced:true, - audio:false, - content:function(){ - var cards=player.getExpansions('reqianxun2'); - if(cards.length) player.gain(cards,'draw'); - player.removeSkill('reqianxun2'); }, - intro:{ - mark:function(dialog,storage,player){ - var cards=player.getExpansions('reqianxun2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + }, + reqianxun2: { + trigger: { global: "phaseEnd" }, + forced: true, + audio: false, + content: function () { + var cards = player.getExpansions("reqianxun2"); + if (cards.length) player.gain(cards, "draw"); + player.removeSkill("reqianxun2"); + }, + intro: { + mark: function (dialog, storage, player) { + var cards = player.getExpansions("reqianxun2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, - markcount:'expansion', - } + markcount: "expansion", + }, }, - relianying:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + relianying: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length; + direct: true, + filter: function (event, player) { + if (player.countCards("h")) return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length; }, - content:function(){ - "step 0" - var num=trigger.getl(player).hs.length; - player.chooseTarget(get.prompt('relianying'),'令至多'+get.cnNumber(num)+'名角色各摸一张牌',[1,num]).ai=function(target){ - var player=_status.event.player; - if(player==target) return get.attitude(player,target)+10; - return get.attitude(player,target); - } - "step 1" - if(result.bool){ - player.logSkill('relianying',result.targets); + content: function () { + "step 0"; + var num = trigger.getl(player).hs.length; + player.chooseTarget( + get.prompt("relianying"), + "令至多" + get.cnNumber(num) + "名角色各摸一张牌", + [1, num] + ).ai = function (target) { + var player = _status.event.player; + if (player == target) return get.attitude(player, target) + 10; + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("relianying", result.targets); game.asyncDraw(result.targets); - } - else event.finish(); - "step 2" + } else event.finish(); + "step 2"; game.delay(); }, - ai:{ - threaten:0.8, - effect:{ - target:function(card){ - if(card.name=='guohe'||card.name=='liuxinghuoyu') return 0.5; - } + ai: { + threaten: 0.8, + effect: { + target: function (card) { + if (card.name == "guohe" || card.name == "liuxinghuoyu") return 0.5; + }, }, - noh:true, - } - }, - retishen:{ - audio:2, - unique:true, - mark:true, - skillAnimation:true, - animationColor:'soil', - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - init:function(player){ - player.storage.retishen=false; + noh: true, }, - filter:function(event,player){ - if(player.storage.retishen) return false; - if(typeof player.storage.retishen2=='number'){ - return player.hp0){ - return att+Math.max(0,5-target.countCards('h')); - } - return att; - }).set('du',event.card.name=='du'); - } - else{ - player.chooseBool('是否弃置'+get.translation(event.card)+'?'); - event.disbool=true; + content: function () { + "step 0"; + event.card = get.cards()[0]; + game.broadcast(function (card) { + ui.arena.classList.add("thrownhighlight"); + card.copy("thrown", "center", "thrownhighlight", ui.arena).addTempClass("start"); + }, event.card); + event.node = event.card + .copy("thrown", "center", "thrownhighlight", ui.arena) + .addTempClass("start"); + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + game.addVideo("centernode", null, get.cardInfo(event.card)); + if (get.type(event.card, "trick") == get.type(trigger.card, "trick")) { + player + .chooseTarget("选择获得此牌的角色") + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0; + return -att; + } + if (att > 0) { + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }) + .set("du", event.card.name == "du"); + } else { + player.chooseBool("是否弃置" + get.translation(event.card) + "?"); + event.disbool = true; } game.delay(2); - "step 1" - if(event.disbool){ - if(!result.bool){ - game.log(player,'展示了',event.card); - ui.cardPile.insertBefore(event.card,ui.cardPile.firstChild); - } - else{ - game.log(player,'展示并弃掉了',event.card); + "step 1"; + if (event.disbool) { + if (!result.bool) { + game.log(player, "展示了", event.card); + ui.cardPile.insertBefore(event.card, ui.cardPile.firstChild); + } else { + game.log(player, "展示并弃掉了", event.card); event.card.discard(); } - game.addVideo('deletenode',player,[get.cardInfo(event.node)]); + game.addVideo("deletenode", player, [get.cardInfo(event.node)]); event.node.delete(); - game.broadcast(function(card){ - ui.arena.classList.remove('thrownhighlight'); - if(card.clone){ + game.broadcast(function (card) { + ui.arena.classList.remove("thrownhighlight"); + if (card.clone) { card.clone.delete(); } - },event.card); - } - else if(result.targets){ - player.line(result.targets,'green'); - result.targets[0].gain(event.card,'log'); + }, event.card); + } else if (result.targets) { + player.line(result.targets, "green"); + result.targets[0].gain(event.card, "log"); event.node.moveDelete(result.targets[0]); - game.addVideo('gain2',result.targets[0],[get.cardInfo(event.node)]); - game.broadcast(function(card,target){ - ui.arena.classList.remove('thrownhighlight'); - if(card.clone){ - card.clone.moveDelete(target); - } - },event.card,result.targets[0]); - } - else{ - game.log(player,'展示并弃掉了',event.card); + game.addVideo("gain2", result.targets[0], [get.cardInfo(event.node)]); + game.broadcast( + function (card, target) { + ui.arena.classList.remove("thrownhighlight"); + if (card.clone) { + card.clone.moveDelete(target); + } + }, + event.card, + result.targets[0] + ); + } else { + game.log(player, "展示并弃掉了", event.card); event.card.discard(); - game.addVideo('deletenode',player,[get.cardInfo(event.node)]); + game.addVideo("deletenode", player, [get.cardInfo(event.node)]); event.node.delete(); - game.broadcast(function(card){ - ui.arena.classList.remove('thrownhighlight'); - if(card.clone){ + game.broadcast(function (card) { + ui.arena.classList.remove("thrownhighlight"); + if (card.clone) { card.clone.delete(); } - },event.card); + }, event.card); } - game.addVideo('thrownhighlight2'); - ui.arena.classList.remove('thrownhighlight'); + game.addVideo("thrownhighlight2"); + ui.arena.classList.remove("thrownhighlight"); + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "respond") && target.countCards("h") > 1) return [1, 0.2]; + }, + }, }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'respond')&&target.countCards('h')>1) return [1,0.2]; - } - } - } }, - rejianxiong:{ - audio:2, - audioname:['shen_caopi'], - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return get.itemtype(event.cards)=='cards'&&get.position(event.cards[0],true)=='o'; + rejianxiong: { + audio: 2, + audioname: ["shen_caopi"], + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return get.itemtype(event.cards) == "cards" && get.position(event.cards[0], true) == "o"; }, - content:function(){ + content: function () { player.gain(trigger.cards); player.$gain2(trigger.cards); player.draw(); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')) return [1,0.55]; - } - } - } - }, - rejianxiong_old:{ - audio:'rejianxiong', - audioname2:{ - gz_caocao:'jianxiong', - }, - trigger:{player:'damageEnd'}, - async cost(event,trigger,player){ - let list=['摸牌']; - if(get.itemtype(trigger.cards)=='cards'&&trigger.cards.filterInD().length){ - list.push('拿牌'); - } - list.push('cancel2'); - const {result:{control}}=await player.chooseControl(list).set('prompt',get.prompt2('rejianxiong_old')).set('ai',()=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - const cards=trigger.cards.filterInD(); - if(get.event().controls.includes('拿牌')){ - if(cards.reduce((sum,card)=>{ - return sum+(card.name=='du'?-1:1); - },0)>1||player.getUseValue(cards[0])>6) return '拿牌'; - } - return '摸牌'; - }); - event.result={bool:(control!='cancel2'),cost_data:control}; - }, - async content(event,trigger,player){ - if(event.cost_data=='摸牌') await player.draw(); - else await player.gain(trigger.cards.filterInD(),'gain2'); - }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target) return [1,0.6]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage")) return [1, 0.55]; }, }, }, }, - reyiji:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - filter:function(event){ - return (event.num>0) + rejianxiong_old: { + audio: "rejianxiong", + audioname2: { + gz_caocao: "jianxiong", }, - content:function(){ - "step 0" - event.num=1; - event.count=1; - "step 1" + trigger: { player: "damageEnd" }, + async cost(event, trigger, player) { + let list = ["摸牌"]; + if (get.itemtype(trigger.cards) == "cards" && trigger.cards.filterInD().length) { + list.push("拿牌"); + } + list.push("cancel2"); + const { + result: { control }, + } = await player + .chooseControl(list) + .set("prompt", get.prompt2("rejianxiong_old")) + .set("ai", () => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + const cards = trigger.cards.filterInD(); + if (get.event().controls.includes("拿牌")) { + if ( + cards.reduce((sum, card) => { + return sum + (card.name == "du" ? -1 : 1); + }, 0) > 1 || + player.getUseValue(cards[0]) > 6 + ) + return "拿牌"; + } + return "摸牌"; + }); + event.result = { bool: control != "cancel2", cost_data: control }; + }, + async content(event, trigger, player) { + if (event.cost_data == "摸牌") await player.draw(); + else await player.gain(trigger.cards.filterInD(), "gain2"); + }, + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage") && player != target) return [1, 0.6]; + }, + }, + }, + }, + reyiji: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + filter: function (event) { + return event.num > 0; + }, + content: function () { + "step 0"; + event.num = 1; + event.count = 1; + "step 1"; player.gain(get.cards(2)); player.$draw(2); - "step 2" + "step 2"; player.chooseCardTarget({ - filterCard:true, - selectCard:[1,2], - filterTarget:function(card,player,target){ - return player!=target&&target!=event.temp; + filterCard: true, + selectCard: [1, 2], + filterTarget: function (card, player, target) { + return player != target && target != event.temp; }, - ai1:function(card){ - if(ui.selected.cards.length>0) return -1; - if(card.name=='du') return 20; - return (_status.event.player.countCards('h')-_status.event.player.hp); + ai1: function (card) { + if (ui.selected.cards.length > 0) return -1; + if (card.name == "du") return 20; + return _status.event.player.countCards("h") - _status.event.player.hp; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; - return 1-att; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; + return 1 - att; } - return att-4; + return att - 4; }, - prompt:'请选择要送人的卡牌' + prompt: "请选择要送人的卡牌", }); - "step 3" - if(result.bool){ - player.lose(result.cards,ui.special,'toStorage'); - if(result.targets[0].hasSkill('reyiji2')){ - result.targets[0].storage.reyiji2=result.targets[0].storage.reyiji2.concat(result.cards); + "step 3"; + if (result.bool) { + player.lose(result.cards, ui.special, "toStorage"); + if (result.targets[0].hasSkill("reyiji2")) { + result.targets[0].storage.reyiji2 = result.targets[0].storage.reyiji2.concat( + result.cards + ); + } else { + result.targets[0].addSkill("reyiji2"); + result.targets[0].storage.reyiji2 = result.cards; } - else{ - result.targets[0].addSkill('reyiji2'); - result.targets[0].storage.reyiji2=result.cards; - } - player.$give(result.cards.length,result.targets[0],false); - player.line(result.targets,'green'); - game.addVideo('storage',result.targets[0],['reyiji2',get.cardsInfo(result.targets[0].storage.reyiji2),'cards']); - if(num==1){ - event.temp=result.targets[0]; + player.$give(result.cards.length, result.targets[0], false); + player.line(result.targets, "green"); + game.addVideo("storage", result.targets[0], [ + "reyiji2", + get.cardsInfo(result.targets[0].storage.reyiji2), + "cards", + ]); + if (num == 1) { + event.temp = result.targets[0]; event.num++; event.goto(2); - } - else if(event.count0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + result: { + effect: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(player.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (player.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } - } + }, }, - threaten:0.6 - } + threaten: 0.6, + }, }, - reyiji2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - mark:true, - popup:'遗计拿牌', - audio:false, - content:function(){ + reyiji2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + mark: true, + popup: "遗计拿牌", + audio: false, + content: function () { player.$draw(player.storage.reyiji2.length); - player.gain(player.storage.reyiji2,'fromStorage'); + player.gain(player.storage.reyiji2, "fromStorage"); delete player.storage.reyiji2; - player.removeSkill('reyiji2'); + player.removeSkill("reyiji2"); game.delay(); }, - intro:{ - content:'cardCount' - } + intro: { + content: "cardCount", + }, }, - yijue:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h'); + yijue: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" - player.chooseToCompare(target).set('small',true); - "step 1" - if(result.bool){ - if(!target.hasSkill('fengyin')){ - target.addTempSkill('fengyin'); + content: function () { + "step 0"; + player.chooseToCompare(target).set("small", true); + "step 1"; + if (result.bool) { + if (!target.hasSkill("fengyin")) { + target.addTempSkill("fengyin"); } - target.addTempSkill('yijue2'); + target.addTempSkill("yijue2"); event.finish(); - } - else if(target.hp0; + } else if (target.hp < target.maxHp) { + player.chooseBool("是否让目标回复1点体力?").ai = function (event, player) { + return get.recoverEffect(target, player, player) > 0; }; - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { target.recover(); } }, - ai:{ - result:{ - target:function(player,target){ - var hs=player.getCards('h'); - if(hs.length<3) return 0; - var bool=false; - for(var i=0;i=9&&get.value(hs[i])<7){ - bool=true; + ai: { + result: { + target: function (player, target) { + var hs = player.getCards("h"); + if (hs.length < 3) return 0; + var bool = false; + for (var i = 0; i < hs.length; i++) { + if (get.number(hs[i]) >= 9 && get.value(hs[i]) < 7) { + bool = true; break; } } - if(!bool) return 0; - if(target.countCards('h')>target.hp+1&&get.recoverEffect(target)>0){ + if (!bool) return 0; + if (target.countCards("h") > target.hp + 1 && get.recoverEffect(target) > 0) { return 1; } - if(player.canUse('sha',target)&&(player.countCards('h','sha')||player.countCards('he',{color:'red'}))){ + if ( + player.canUse("sha", target) && + (player.countCards("h", "sha") || player.countCards("he", { color: "red" })) + ) { return -2; } return -0.5; - } + }, }, - order:9, - } + order: 9, + }, }, - yijue2:{ - mark:true, - mod:{ - cardEnabled:function(){ + yijue2: { + mark: true, + mod: { + cardEnabled: function () { return false; }, - cardRespondable:function(){ + cardRespondable: function () { return false; }, - cardSavable:function(){ + cardSavable: function () { return false; - } + }, + }, + intro: { + content: "不能使用或打出卡牌", }, - intro:{ - content:'不能使用或打出卡牌' - } }, - retieji:{ - shaRelated:true, - audio:2, - audioname:['boss_lvbu3'], - trigger:{player:'useCardToPlayered'}, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + retieji: { + shaRelated: true, + audio: 2, + audioname: ["boss_lvbu3"], + trigger: { player: "useCardToPlayered" }, + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - filter:function(event,player){ - return event.card.name=='sha'; + filter: function (event, player) { + return event.card.name == "sha"; }, - logTarget:'target', - content:function(){ - "step 0" - player.judge(function(){return 0}); - if(!trigger.target.hasSkill('fengyin')){ - trigger.target.addTempSkill('fengyin'); + logTarget: "target", + content: function () { + "step 0"; + player.judge(function () { + return 0; + }); + if (!trigger.target.hasSkill("fengyin")) { + trigger.target.addTempSkill("fengyin"); } - "step 1" - var suit=result.suit; - var target=trigger.target; - var num=target.countCards('h','shan'); - target.chooseToDiscard('请弃置一张'+get.translation(suit)+'牌,否则不能使用闪抵消此杀','he',function(card){ - return get.suit(card)==_status.event.suit; - }).set('ai',function(card){ - var num=_status.event.num; - if(num==0) return 0; - if(card.name=='shan') return num>1?2:0; - return 8-get.value(card); - }).set('num',num).set('suit',suit); - "step 2" - if(!result.bool){ + "step 1"; + var suit = result.suit; + var target = trigger.target; + var num = target.countCards("h", "shan"); + target + .chooseToDiscard( + "请弃置一张" + get.translation(suit) + "牌,否则不能使用闪抵消此杀", + "he", + function (card) { + return get.suit(card) == _status.event.suit; + } + ) + .set("ai", function (card) { + var num = _status.event.num; + if (num == 0) return 0; + if (card.name == "shan") return num > 1 ? 2 : 0; + return 8 - get.value(card); + }) + .set("num", num) + .set("suit", suit); + "step 2"; + if (!result.bool) { trigger.getParent().directHit.add(trigger.target); } }, - ai:{ - ignoreSkill:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='directHit_ai'){ - return get.attitude(player,arg.target)<=0; + ai: { + ignoreSkill: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "directHit_ai") { + return get.attitude(player, arg.target) <= 0; } - if(!arg||arg.isLink||!arg.card||arg.card.name!='sha') return false; - if(!arg.target||get.attitude(player,arg.target)>=0) return false; - if(!arg.skill||!lib.skill[arg.skill]||lib.skill[arg.skill].charlotte||get.is.locked(arg.skill)||!arg.target.getSkills(true,false).includes(arg.skill)) return false; + if (!arg || arg.isLink || !arg.card || arg.card.name != "sha") return false; + if (!arg.target || get.attitude(player, arg.target) >= 0) return false; + if ( + !arg.skill || + !lib.skill[arg.skill] || + lib.skill[arg.skill].charlotte || + get.is.locked(arg.skill) || + !arg.target.getSkills(true, false).includes(arg.skill) + ) + return false; }, - directHit_ai:true, - } + directHit_ai: true, + }, }, - reyicong:{ - trigger:{ - player:["changeHp"], + reyicong: { + trigger: { + player: ["changeHp"], }, - audio:2, - audioname2:{gongsunzan:'yicong'}, - forced:true, - filter:function(event,player){ - return get.sgn(player.hp-2.5)!=get.sgn(player.hp-2.5-event.num); + audio: 2, + audioname2: { gongsunzan: "yicong" }, + forced: true, + filter: function (event, player) { + return get.sgn(player.hp - 2.5) != get.sgn(player.hp - 2.5 - event.num); }, - content:function (){}, - mod:{ - globalFrom:function(from,to,current){ - return current-1; + content: function () {}, + mod: { + globalFrom: function (from, to, current) { + return current - 1; }, - globalTo:function(from,to,current){ - if(to.hp<=2) return current+1; + globalTo: function (from, to, current) { + if (to.hp <= 2) return current + 1; }, }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, - reqiaomeng:{ - audio:'qiaomeng', - trigger:{source:'damageSource'}, - direct:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.countDiscardableCards(player,'hej'); + reqiaomeng: { + audio: "qiaomeng", + trigger: { source: "damageSource" }, + direct: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.player.countDiscardableCards(player, "hej") + ); }, - content:function(){ - "step 0" - player.discardPlayerCard(get.prompt('reqiaomeng',trigger.player),'hej',trigger.player).set('logSkill',['reqiaomeng',trigger.player]); - "step 1" - if(result.bool){ - var card=result.cards[0]; - if(get.position(card)=='d'){ - if(get.subtype(card)=='equip3'||get.subtype(card)=='equip4'||get.subtype(card)=='equip6'){ - player.gain(card,player,'gain2'); + content: function () { + "step 0"; + player + .discardPlayerCard(get.prompt("reqiaomeng", trigger.player), "hej", trigger.player) + .set("logSkill", ["reqiaomeng", trigger.player]); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + if (get.position(card) == "d") { + if ( + get.subtype(card) == "equip3" || + get.subtype(card) == "equip4" || + get.subtype(card) == "equip6" + ) { + player.gain(card, player, "gain2"); } } } - } - }, - qiaomeng:{ - audio:2, - trigger:{source:'damageSource'}, - direct:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.cards&& - get.color(event.cards)=='black'&&event.player.countDiscardableCards(player,'hej'); }, - content:function(){ - "step 0" - player.discardPlayerCard(get.prompt('qiaomeng',trigger.player),'e',trigger.player).set('logSkill',['qiaomeng',trigger.player]); - "step 1" - if(result.bool){ - var card=result.cards[0]; - if(get.position(card)=='d'){ - if(get.subtype(card)=='equip3'||get.subtype(card)=='equip4'||get.subtype(card)=='equip6'){ - player.gain(card,player,'gain2'); + }, + qiaomeng: { + audio: 2, + trigger: { source: "damageSource" }, + direct: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.cards && + get.color(event.cards) == "black" && + event.player.countDiscardableCards(player, "hej") + ); + }, + content: function () { + "step 0"; + player + .discardPlayerCard(get.prompt("qiaomeng", trigger.player), "e", trigger.player) + .set("logSkill", ["qiaomeng", trigger.player]); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + if (get.position(card) == "d") { + if ( + get.subtype(card) == "equip3" || + get.subtype(card) == "equip4" || + get.subtype(card) == "equip6" + ) { + player.gain(card, player, "gain2"); } } } - } - }, - rekurou:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:true, - check:function(card){ - return 8-get.value(card); }, - position:'he', - content:function(){ + }, + rekurou: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + check: function (card) { + return 8 - get.value(card); + }, + position: "he", + content: function () { player.loseHp(); }, - ai:{ - order:8, - result:{ - player:function(player){ - return get.effect(player,{name:'losehp'},player,player); - } + ai: { + order: 8, + result: { + player: function (player) { + return get.effect(player, { name: "losehp" }, player, player); + }, }, - } + neg: true, + }, }, - zhaxiang:{ - audio:2, - audioname:['ol_sb_jiangwei'], - trigger:{player:'loseHpEnd'}, - forced:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + zhaxiang: { + audio: 2, + audioname: ["ol_sb_jiangwei"], + trigger: { player: "loseHpEnd" }, + forced: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; player.draw(3); - if(player.isPhaseUsing()){ - player.addTempSkill('zhaxiang2'); - player.addMark('zhaxiang2',1,false); + if (player.isPhaseUsing()) { + player.addTempSkill("zhaxiang2"); + player.addMark("zhaxiang2", 1, false); } - 'step 2' - if(event.count>0&&player.hasSkill('zhaxiang')&&!get.is.blocked('zhaxiang',player)){ - player.logSkill('zhaxiang'); + "step 2"; + if ( + event.count > 0 && + player.hasSkill("zhaxiang") && + !get.is.blocked("zhaxiang", player) + ) { + player.logSkill("zhaxiang"); event.goto(1); } }, - ai:{ - maihp:true, - effect:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,1]; + ai: { + maihp: true, + effect: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, 1]; return 1.2; } - if(get.tag(card,'loseHp')){ - if(target.hp<=1) return; - var using=target.isPhaseUsing(); - if(target.hp<=2) return [1,player.countCards('h')<=1&&using?3:0]; - if(using&&target.countCards('h',{name:'sha',color:'red'})) return [1,3]; - return [1,(target.countCards('h')<=target.hp||using&&game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)<0&&player.inRange(current); - }))?3:2] + if (get.tag(card, "loseHp")) { + if (target.hp <= 1) return; + var using = target.isPhaseUsing(); + if (target.hp <= 2) return [1, player.countCards("h") <= 1 && using ? 3 : 0]; + if (using && target.countCards("h", { name: "sha", color: "red" })) return [1, 3]; + return [ + 1, + target.countCards("h") <= target.hp || + (using && + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) < 0 && + player.inRange(current) + ); + })) + ? 3 + : 2, + ]; } - } - } - }, - zhaxiang2:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(card.name=='sha'&&get.color(card)=='red') return true; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.storage.zhaxiang2; - } }, - charlotte:true, - onremove:true, - audio:'zhaxiang', - audioname:['ol_sb_jiangwei'], - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&get.color(event.card)=='red'; + }, + zhaxiang2: { + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "sha" && get.color(card) == "red") return true; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.storage.zhaxiang2; + }, }, - forced:true, - content:function(){ + charlotte: true, + onremove: true, + audio: "zhaxiang", + audioname: ["ol_sb_jiangwei"], + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card && event.card.name == "sha" && get.color(event.card) == "red"; + }, + forced: true, + content: function () { trigger.directHit.addArray(game.players); }, - intro:{content:'
            • 使用【杀】的次数上限+#
            • 使用红色【杀】无距离限制且不能被【闪】响应'}, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.card.name=='sha'&&get.color(arg.card)=='red'; + intro: { + content: "
            • 使用【杀】的次数上限+#
            • 使用红色【杀】无距离限制且不能被【闪】响应", + }, + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg.card.name == "sha" && get.color(arg.card) == "red"; }, }, }, - zhuhai:{ - audio:2, - audioname:['gz_re_xushu'], - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return event.player.isIn()&&event.player.getStat('damage')&& - lib.filter.targetEnabled({name:'sha'},player,event.player)&&(player.hasSha()||_status.connectMode&&player.countCards('h')>0); + zhuhai: { + audio: 2, + audioname: ["gz_re_xushu"], + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player.getStat("damage") && + lib.filter.targetEnabled({ name: "sha" }, player, event.player) && + (player.hasSha() || (_status.connectMode && player.countCards("h") > 0)) + ); + }, + content: function () { + player + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "诛害:是否对" + get.translation(trigger.player) + "使用一张杀?") + .set("logSkill", "zhuhai") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.player); }, - content:function(){ - player.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'诛害:是否对'+get.translation(trigger.player)+'使用一张杀?').set('logSkill','zhuhai').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.player); - } }, - qianxin:{ - skillAnimation:true, - animationColor:'orange', - audio:2, - unique:true, - juexingji:true, - trigger:{source:'damageSource'}, - forced:true, - derivation:'jianyan', - filter:function(event,player){ - return player.hp2) return 'trick'; - return 'red'; + content: function () { + "step 0"; + player.chooseControl(["red", "black", "basic", "trick", "equip"]).set("ai", function () { + var player = _status.event.player; + if (!player.hasShan()) return "basic"; + if (player.countCards("e") <= 1) return "equip"; + if (player.countCards("h") > 2) return "trick"; + return "red"; }); - "step 1" - event.card=get.cardPile(function(card){ - if(get.color(card)==result.control) return true; - if(get.type(card,'trick')==result.control) return true; + "step 1"; + event.card = get.cardPile(function (card) { + if (get.color(card) == result.control) return true; + if (get.type(card, "trick") == result.control) return true; return false; - },'cardPile'); - if(!event.card){ + }, "cardPile"); + if (!event.card) { event.finish(); return; } player.showCards([event.card]); - "step 2" - player.chooseTarget(true,'选择一名男性角色送出'+get.translation(event.card),function(card,player,target){ - return target.hasSex('male'); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.neg) return -att; - return att; - }).set('neg',get.value(event.card,player,'raw')<0); - "step 3" - player.line(result.targets,'green'); - result.targets[0].gain(event.card,'gain2'); + "step 2"; + player + .chooseTarget( + true, + "选择一名男性角色送出" + get.translation(event.card), + function (card, player, target) { + return target.hasSex("male"); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.neg) return -att; + return att; + }) + .set("neg", get.value(event.card, player, "raw") < 0); + "step 3"; + player.line(result.targets, "green"); + result.targets[0].gain(event.card, "gain2"); }, - ai:{ - order:9, - result:{ - player:function(player){ - if(game.hasPlayer(function(current){ - return current.hasSex('male')&&get.attitude(player,current)>0; - })) return 2; + ai: { + order: 9, + result: { + player: function (player) { + if ( + game.hasPlayer(function (current) { + return current.hasSex("male") && get.attitude(player, current) > 0; + }) + ) + return 2; return 0; }, }, - threaten:1.2 - } + threaten: 1.2, + }, }, - reguose:{ - audio:2, - enable:'phaseUse', - usable:1, - discard:false, - lose:false, - delay:false, - filter:function(event,player){ - return player.countCards('hes',{suit:'diamond'})>0; + reguose: { + audio: 2, + enable: "phaseUse", + usable: 1, + discard: false, + lose: false, + delay: false, + filter: function (event, player) { + return player.countCards("hes", { suit: "diamond" }) > 0; }, - position:'hes', - filterCard:{suit:'diamond'}, - filterTarget:function(card,player,target){ - if(get.position(ui.selected.cards[0])!='s'&&lib.filter.cardDiscardable(ui.selected.cards[0],player,'reguose')&&target.hasJudge('lebu')) return true; - if(player==target) return false; - if(!game.checkMod(ui.selected.cards[0],player,'unchanged','cardEnabled2',player)) return false; - return player.canUse({name:'lebu',cards:ui.selected.cards},target); + position: "hes", + filterCard: { suit: "diamond" }, + filterTarget: function (card, player, target) { + if ( + get.position(ui.selected.cards[0]) != "s" && + lib.filter.cardDiscardable(ui.selected.cards[0], player, "reguose") && + target.hasJudge("lebu") + ) + return true; + if (player == target) return false; + if (!game.checkMod(ui.selected.cards[0], player, "unchanged", "cardEnabled2", player)) + return false; + return player.canUse({ name: "lebu", cards: ui.selected.cards }, target); }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - if(target.hasJudge('lebu')){ + content: function () { + if (target.hasJudge("lebu")) { player.discard(cards); - target.discard(target.getJudge('lebu')); - } - else{ - player.useCard({name:'lebu'},target,cards).audio=false; + target.discard(target.getJudge("lebu")); + } else { + player.useCard({ name: "lebu" }, target, cards).audio = false; } player.draw(); }, - ai:{ - result:{ - target:function(player,target){ - if(target.hasJudge('lebu')) return -get.effect(target,{name:'lebu'},player,target); - return get.effect(target,{name:'lebu'},player,target); - } + ai: { + result: { + target: function (player, target) { + if (target.hasJudge("lebu")) + return -get.effect(target, { name: "lebu" }, player, target); + return get.effect(target, { name: "lebu" }, player, target); + }, }, - order:9, - } + order: 9, + }, }, - fenwei:{ - skillAnimation:true, - animationColor:'wood', - audio:2, - audioname:['heqi'], - unique:true, - mark:true, - limited:true, - trigger:{global:'useCardToPlayered'}, + fenwei: { + skillAnimation: true, + animationColor: "wood", + audio: 2, + audioname: ["heqi"], + unique: true, + mark: true, + limited: true, + trigger: { global: "useCardToPlayered" }, //priority:5, - filter:function(event,player){ - if(event.getParent().triggeredTargets3.length>1) return false; - if(get.type(event.card)!='trick') return false; - if(get.info(event.card).multitarget) return false; - if(event.targets.length<2) return false; - if(player.storage.fenwei) return false; + filter: function (event, player) { + if (event.getParent().triggeredTargets3.length > 1) return false; + if (get.type(event.card) != "trick") return false; + if (get.info(event.card).multitarget) return false; + if (event.targets.length < 2) return false; + if (player.storage.fenwei) return false; return true; }, - init:function(player){ - player.storage.fenwei=false; + init: function (player) { + player.storage.fenwei = false; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('fenwei'), - [1,trigger.targets.length],function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - if(game.phaseNumber>game.players.length*2&&trigger.targets.length>=game.players.length-1&&!trigger.excluded.includes(target)){ - return -get.effect(target,trigger.card,trigger.player,_status.event.player); - } - return -1; - }).set('targets',trigger.targets); - "step 1" - if(result.bool){ - player.awakenSkill('fenwei'); - player.logSkill('fenwei',result.targets); - player.storage.fenwei=true; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("fenwei"), + [1, trigger.targets.length], + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + if ( + game.phaseNumber > game.players.length * 2 && + trigger.targets.length >= game.players.length - 1 && + !trigger.excluded.includes(target) + ) { + return -get.effect( + target, + trigger.card, + trigger.player, + _status.event.player + ); + } + return -1; + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + player.awakenSkill("fenwei"); + player.logSkill("fenwei", result.targets); + player.storage.fenwei = true; trigger.getParent().excluded.addArray(result.targets); game.delay(); } }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - chulao:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(target.group=='unknown') return false; - for(var i=0;i0; + return target.countCards("he") > 0; }, - filter:function(event,player){ - return player.countCards('he')>0; + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - selectTarget:[1,Infinity], - check:function(card){ - if(get.suit(card)=='spade') return 8-get.value(card); - return 5-get.value(card); + filterCard: true, + position: "he", + selectTarget: [1, Infinity], + check: function (card) { + if (get.suit(card) == "spade") return 8 - get.value(card); + return 5 - get.value(card); }, - content:function(){ - "step 0" - if(num==0&&get.suit(cards[0])=='spade') player.draw(); - player.choosePlayerCard(targets[num],'he',true); - "step 1" - if(result.bool){ - if(result.links.length) targets[num].discard(result.links[0]); - if(get.suit(result.links[0])=='spade') targets[num].draw(); + content: function () { + "step 0"; + if (num == 0 && get.suit(cards[0]) == "spade") player.draw(); + player.choosePlayerCard(targets[num], "he", true); + "step 1"; + if (result.bool) { + if (result.links.length) targets[num].discard(result.links[0]); + if (get.suit(result.links[0]) == "spade") targets[num].draw(); } }, - ai:{ - result:{ - target:-1 + ai: { + result: { + target: -1, }, - threaten:1.2, - order:3 - } + threaten: 1.2, + order: 3, + }, }, - xunxun:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - preHidden:true, - content:function(){ - "step 0" - var cards=get.cards(4); + xunxun: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + preHidden: true, + content: function () { + "step 0"; + var cards = get.cards(4); game.cardsGotoOrdering(cards); - var next=player.chooseToMove('恂恂:将两张牌置于牌堆顶',true); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('filterMove',function(from,to,moved){ - if(to==1&&moved[1].length>=2) return false; + var next = player.chooseToMove("恂恂:将两张牌置于牌堆顶", true); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("filterMove", function (from, to, moved) { + if (to == 1 && moved[1].length >= 2) return false; return true; }); - next.set('filterOk',function(moved){ - return moved[1].length==2; + next.set("filterOk", function (moved) { + return moved[1].length == 2; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.value(a); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.value(a); }); - return [cards,cards.splice(2)]; - }) - 'step 1' - var top=result.moved[0]; - var bottom=result.moved[1]; + return [cards, cards.splice(2)]; + }); + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i-3; - return get.attitude(player,event.player)>-3; + check: function (event, player) { + if (player.isPhaseUsing()) return true; + if (event.player == player) return get.attitude(player, event.source) > -3; + return get.attitude(player, event.player) > -3; }, - logTarget:function(event,player){ - if(event.player==player) return event.source; + logTarget: function (event, player) { + if (event.player == player) return event.source; return event.player; }, - preHidden:true, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" - game.asyncDraw([trigger.player,trigger.source]); + preHidden: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + game.asyncDraw([trigger.player, trigger.source]); event.count--; - "step 2" + "step 2"; game.delay(); - "step 3" - if(event.count&&player.hasSkill('wangxi')){ - player.chooseBool(get.prompt2('wangxi',lib.skill.wangxi.logTarget(trigger,player))) - } - else event.finish(); - "step 4" - if(result.bool){ - player.logSkill('wangxi',lib.skill.wangxi.logTarget(trigger,player)); + "step 3"; + if (event.count && player.hasSkill("wangxi")) { + player.chooseBool(get.prompt2("wangxi", lib.skill.wangxi.logTarget(trigger, player))); + } else event.finish(); + "step 4"; + if (result.bool) { + player.logSkill("wangxi", lib.skill.wangxi.logTarget(trigger, player)); event.goto(1); } }, - ai:{ - maixie:true, - maixie_hp:true - } - }, - refangquan:{ - audio:2, - trigger:{player:'phaseUseBefore'}, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkill('fangquan3'); + ai: { + maixie: true, + maixie_hp: true, }, - direct:true, - content:function(){ - "step 0" - var fang=player.countMark('fangquan2')==0&&player.hp>=2&&player.countCards('h')<=player.maxHp+1; - player.chooseBool(get.prompt2('refangquan')).set('ai',function(){ - if(!_status.event.fang) return false; - return game.hasPlayer(function(target){ - if(target.hasJudge('lebu')||target==player) return false; - if(get.attitude(player,target)>4){ - return (get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1)>0); - } - return false; - }); - }).set('fang',fang); - "step 1" - if(result.bool){ - player.logSkill('refangquan'); + }, + refangquan: { + audio: 2, + trigger: { player: "phaseUseBefore" }, + filter: function (event, player) { + return player.countCards("h") > 0 && !player.hasSkill("fangquan3"); + }, + direct: true, + content: function () { + "step 0"; + var fang = + player.countMark("fangquan2") == 0 && + player.hp >= 2 && + player.countCards("h") <= player.maxHp + 1; + player + .chooseBool(get.prompt2("refangquan")) + .set("ai", function () { + if (!_status.event.fang) return false; + return game.hasPlayer(function (target) { + if (target.hasJudge("lebu") || target == player) return false; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) > + 0 + ); + } + return false; + }); + }) + .set("fang", fang); + "step 1"; + if (result.bool) { + player.logSkill("refangquan"); trigger.cancel(); - player.addTempSkill('fangquan2','phaseAfter'); - player.addMark('fangquan2',1,false); - player.addTempSkill('refangquan2'); + player.addTempSkill("fangquan2", "phaseAfter"); + player.addMark("fangquan2", 1, false); + player.addTempSkill("refangquan2"); //player.storage.fangquan=result.targets[0]; } - } + }, }, - refangquan2:{ - mod:{ - maxHandcardBase:function(player,num){ + refangquan2: { + mod: { + maxHandcardBase: function (player, num) { return player.maxHp; }, }, }, - rehunzi:{ - inherit:'hunzi', - filter:function(event,player){ - return player.hp<=2&&!player.storage.rehunzi; + rehunzi: { + inherit: "hunzi", + filter: function (event, player) { + return player.hp <= 2 && !player.storage.rehunzi; }, - ai:{ - threaten:function(player,target){ - if(target.hp<=2) return 2; + ai: { + threaten: function (player, target) { + if (target.hp <= 2) return 2; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(!target.hasFriend()) return; - if(target.hp===3&&get.tag(card,'damage')==1&&!target.isTurnedOver()&& - _status.currentPhase!=target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; - if(target.hp===1&&get.tag(card,'recover')&&!target.isTurnedOver()&& - _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [1,-3]; - } - } - } - }, - rezhijian:{ - inherit:'zhijian', - group:['rezhijian_use'], - subfrequent:['use'], - subSkill:{ - use:{ - audio:'rezhijian', - trigger:{player:'useCard'}, - frequent:true, - filter:function(event,player){ - return get.type(event.card)=='equip'; - }, - prompt:'是否发动【直谏】摸一张牌?', - content:function(){ - player.draw('nodelay'); + maixie: true, + effect: { + target: function (card, player, target) { + if (!target.hasFriend()) return; + if ( + target.hp === 3 && + get.tag(card, "damage") == 1 && + !target.isTurnedOver() && + _status.currentPhase != target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [0.5, 1]; + if ( + target.hp === 1 && + get.tag(card, "recover") && + !target.isTurnedOver() && + _status.currentPhase !== target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [1, -3]; }, }, }, }, - retuntian:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + rezhijian: { + inherit: "zhijian", + group: ["rezhijian_use"], + subfrequent: ["use"], + subSkill: { + use: { + audio: "rezhijian", + trigger: { player: "useCard" }, + frequent: true, + filter: function (event, player) { + return get.type(event.card) == "equip"; + }, + prompt: "是否发动【直谏】摸一张牌?", + content: function () { + player.draw("nodelay"); + }, + }, }, - frequent:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + }, + retuntian: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - content:function(){ - player.judge(function(card){ + frequent: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; + }, + content: function () { + player.judge(function (card) { return 1; - }).callback=lib.skill.retuntian.callback; + }).callback = lib.skill.retuntian.callback; }, - callback:function(){ - 'step 0' - if(event.judgeResult.suit=='heart'){ - player.gain(card,'gain2'); + callback: function () { + "step 0"; + if (event.judgeResult.suit == "heart") { + player.gain(card, "gain2"); event.finish(); - } - else if(get.mode()=='guozhan'){ - player.chooseBool('是否将'+get.translation(card)+'作为“田”置于武将牌上?').set('frequentSkill','retuntian').ai=function(){ + } else if (get.mode() == "guozhan") { + player + .chooseBool("是否将" + get.translation(card) + "作为“田”置于武将牌上?") + .set("frequentSkill", "retuntian").ai = function () { return true; }; - } - else event.directbool=true; - 'step 1' - if(!result.bool&&!event.directbool){ + } else event.directbool = true; + "step 1"; + if (!result.bool && !event.directbool) { //game.cardsDiscard(card); return; } - player.addToExpansion(card,'gain2').gaintag.add('tuntian'); + player.addToExpansion(card, "gain2").gaintag.add("tuntian"); }, - group:'tuntian_dist', - locked:false, - ai:{ - effect:{ - target:function(){ - return lib.skill.tuntian.ai.effect.target.apply(this,arguments); - } + group: "tuntian_dist", + locked: false, + ai: { + effect: { + target: function () { + return lib.skill.tuntian.ai.effect.target.apply(this, arguments); + }, }, - threaten:function(player,target){ - if(target.countCards('h')==0) return 2; + threaten: function (player, target) { + if (target.countCards("h") == 0) return 2; return 0.5; }, - nodiscard:true, - nolose:true - } + nodiscard: true, + nolose: true, + }, }, - rebeige:{ - audio:'beige', - audioname:['re_caiwenji'], - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return (event.card&&event.card.name=='sha'&&event.source&& - event.player.classList.contains('dead')==false&&player.countCards('he')); + rebeige: { + audio: "beige", + audioname: ["re_caiwenji"], + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.source && + event.player.classList.contains("dead") == false && + player.countCards("he") + ); }, - direct:true, - checkx:function(event,player){ - var att1=get.attitude(player,event.player); - var att2=get.attitude(player,event.source); - return att1>0&&att2<=0; + direct: true, + checkx: function (event, player) { + var att1 = get.attitude(player, event.player); + var att2 = get.attitude(player, event.source); + return att1 > 0 && att2 <= 0; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he',get.prompt2('rebeige',trigger.player)); - var check=lib.skill.beige.checkx(trigger,player); - next.set('ai',function(card){ - if(_status.event.goon) return 8-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard("he", get.prompt2("rebeige", trigger.player)); + var check = lib.skill.beige.checkx(trigger, player); + next.set("ai", function (card) { + if (_status.event.goon) return 8 - get.value(card); return 0; }); - next.set('logSkill','rebeige'); - next.set('goon',check); - "step 1" - if(result.bool){ + next.set("logSkill", "rebeige"); + next.set("goon", check); + "step 1"; + if (result.bool) { trigger.player.judge(); - } - else{ + } else { event.finish(); } - "step 2" - switch(result.suit){ - case 'heart':trigger.player.recover(trigger.num);break; - case 'diamond':trigger.player.draw(3);break; - case 'club':trigger.source.chooseToDiscard('he',2,true);break; - case 'spade':trigger.source.turnOver();break; + "step 2"; + switch (result.suit) { + case "heart": + trigger.player.recover(trigger.num); + break; + case "diamond": + trigger.player.draw(3); + break; + case "club": + trigger.source.chooseToDiscard("he", 2, true); + break; + case "spade": + trigger.source.turnOver(); + break; } }, - ai:{ - expose:0.3 - } - }, - rexingshang:{ - audio:2, - trigger:{global:'die'}, - filter:function(event,player){ - return player.isDamaged()||event.player.countCards('he')>0; + ai: { + expose: 0.3, }, - direct:true, - content:function(){ - "step 0" - var choice=[]; - if(player.isDamaged()) choice.push('回复体力'); - if(trigger.player.countCards('he')) choice.push('获得牌'); - choice.push('cancel2'); - player.chooseControl(choice).set('prompt',get.prompt2('rexingshang')).set('ai',function(){ - if(choice.length==2) return 0; - if(get.value(trigger.player.getCards('he'))>8) return 1; - return 0; - }); - "step 1" - if(result.control!='cancel2'){ - player.logSkill(event.name,trigger.player); - if(result.control=='获得牌'){ - event.togain=trigger.player.getCards('he'); - player.gain(event.togain,trigger.player,'giveAuto','bySelf'); - } - else player.recover(); + }, + rexingshang: { + audio: 2, + trigger: { global: "die" }, + filter: function (event, player) { + return player.isDamaged() || event.player.countCards("he") > 0; + }, + direct: true, + content: function () { + "step 0"; + var choice = []; + if (player.isDamaged()) choice.push("回复体力"); + if (trigger.player.countCards("he")) choice.push("获得牌"); + choice.push("cancel2"); + player + .chooseControl(choice) + .set("prompt", get.prompt2("rexingshang")) + .set("ai", function () { + if (choice.length == 2) return 0; + if (get.value(trigger.player.getCards("he")) > 8) return 1; + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill(event.name, trigger.player); + if (result.control == "获得牌") { + event.togain = trigger.player.getCards("he"); + player.gain(event.togain, trigger.player, "giveAuto", "bySelf"); + } else player.recover(); } }, }, - refangzhu:{ - audio:2, - trigger:{ - player:"damageEnd", + refangzhu: { + audio: 2, + trigger: { + player: "damageEnd", }, - direct:true, - content:function (){ - "step 0" - player.chooseTarget(get.prompt2('refangzhu'),function(card,player,target){ - return player!=target - }).ai=function(target){ - if(target.hasSkillTag('noturn')) return 0; - var player=_status.event.player; - if(get.attitude(_status.event.player,target)==0) return 0; - if(get.attitude(_status.event.player,target)>0){ - if(target.classList.contains('turnedover')) return 1000-target.countCards('h'); - if(player.getDamagedHp()<3) return -1; - return 100-target.countCards('h'); + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("refangzhu"), function (card, player, target) { + return player != target; + }).ai = function (target) { + if (target.hasSkillTag("noturn")) return 0; + var player = _status.event.player; + if (get.attitude(_status.event.player, target) == 0) return 0; + if (get.attitude(_status.event.player, target) > 0) { + if (target.classList.contains("turnedover")) return 1000 - target.countCards("h"); + if (player.getDamagedHp() < 3) return -1; + return 100 - target.countCards("h"); + } else { + if (target.classList.contains("turnedover")) return -1; + if (player.getDamagedHp() >= 3) return -1; + return 1 + target.countCards("h"); } - else{ - if(target.classList.contains('turnedover')) return -1; - if(player.getDamagedHp()>=3) return -1; - return 1+target.countCards('h'); - } - } - "step 1" - if(result.bool){ - player.logSkill('refangzhu',result.targets); - event.target=result.targets[0]; - if(player.isHealthy()) event._result={bool:false}; - else event.target.chooseToDiscard('he',player.getDamagedHp()).set('ai',function(card){ - var player=_status.event.player; - if(player.isTurnedOver()||_status.event.getTrigger().player.getDamagedHp()>2) return -1; - return (player.hp*player.hp)-get.value(card); - }).set('prompt','弃置'+get.cnNumber(player.getDamagedHp())+'张牌并失去1点体力;或选择不弃置,将武将牌翻面并摸'+get.cnNumber(player.getDamagedHp())+'张牌。'); - } - else event.finish(); - "step 2" - if(result.bool){ + }; + "step 1"; + if (result.bool) { + player.logSkill("refangzhu", result.targets); + event.target = result.targets[0]; + if (player.isHealthy()) event._result = { bool: false }; + else + event.target + .chooseToDiscard("he", player.getDamagedHp()) + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.isTurnedOver() || + _status.event.getTrigger().player.getDamagedHp() > 2 + ) + return -1; + return player.hp * player.hp - get.value(card); + }) + .set( + "prompt", + "弃置" + + get.cnNumber(player.getDamagedHp()) + + "张牌并失去1点体力;或选择不弃置,将武将牌翻面并摸" + + get.cnNumber(player.getDamagedHp()) + + "张牌。" + ); + } else event.finish(); + "step 2"; + if (result.bool) { event.target.loseHp(); - } - else{ - if(player.isDamaged()) event.target.draw(player.getDamagedHp()); + } else { + if (player.isDamaged()) event.target.draw(player.getDamagedHp()); event.target.turnOver(); } }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function (card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - if(target.hp<=1) return; - if(!target.hasFriend()) return; - var hastarget=false; - var turnfriend=false; - var players=game.filterPlayer(); - for(var i=0;i0&&players[i].isTurnedOver()){ - hastarget=true; - turnfriend=true; + if (get.attitude(target, players[i]) > 0 && players[i].isTurnedOver()) { + hastarget = true; + turnfriend = true; } } - if(get.attitude(player,target)>0&&!hastarget) return; - if(turnfriend||target.hp==target.maxHp) return [0.5,1]; - if(target.hp>1) return [1,0.5]; + if (get.attitude(player, target) > 0 && !hastarget) return; + if (turnfriend || target.hp == target.maxHp) return [0.5, 1]; + if (target.hp > 1) return [1, 0.5]; } }, }, }, }, - repolu:{ - audio:1, - trigger:{ - source:'dieAfter', - player:'die', + repolu: { + audio: 1, + trigger: { + source: "dieAfter", + player: "die", }, - forceDie:true, - filter:function(event,player,name){ - return name=='die'||player.isIn(); + forceDie: true, + filter: function (event, player, name) { + return name == "die" || player.isIn(); }, - direct:true, - content:function(){ - 'step 0' - if(!player.storage.repolu) player.storage.repolu=0; - event.num=player.storage.repolu+1; - player.chooseTarget([1,Infinity],get.prompt('repolu'),'令任意名角色摸'+get.cnNumber(event.num)+'张牌').set('forceDie',true).ai=function(target){ - return get.attitude(_status.event.player,target); + direct: true, + content: function () { + "step 0"; + if (!player.storage.repolu) player.storage.repolu = 0; + event.num = player.storage.repolu + 1; + player + .chooseTarget( + [1, Infinity], + get.prompt("repolu"), + "令任意名角色摸" + get.cnNumber(event.num) + "张牌" + ) + .set("forceDie", true).ai = function (target) { + return get.attitude(_status.event.player, target); }; - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { player.storage.repolu++; result.targets.sortBySeat(); - player.logSkill('repolu',result.targets); - game.asyncDraw(result.targets,num); - } - else event.finish(); - 'step 2' + player.logSkill("repolu", result.targets); + game.asyncDraw(result.targets, num); + } else event.finish(); + "step 2"; game.delay(); }, }, - oljiuchi:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='jiu') return Infinity; + oljiuchi: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "jiu") return Infinity; }, }, - audio:2, - enable:'chooseToUse', - filterCard:function(card){ - return get.suit(card)=='spade'; + audio: 2, + enable: "chooseToUse", + filterCard: function (card) { + return get.suit(card) == "spade"; }, - viewAs:{name:'jiu'}, - position:'hs', - viewAsFilter:function(player){ - return player.hasCard(card=>get.suit(card)=='spade','hs'); + viewAs: { name: "jiu" }, + position: "hs", + viewAsFilter: function (player) { + return player.hasCard((card) => get.suit(card) == "spade", "hs"); }, - prompt:'将一张黑桃手牌当酒使用', - check:function(cardx,player){ - if(player&&player==cardx.player) return true; - if(_status.event.type=='dying') return 1; - var player=_status.event.player; - var shas=player.getCards('hs',function(card){ - return card!=cardx&&get.name(card,player)=='sha'; + prompt: "将一张黑桃手牌当酒使用", + check: function (cardx, player) { + if (player && player == cardx.player) return true; + if (_status.event.type == "dying") return 1; + var player = _status.event.player; + var shas = player.getCards("hs", function (card) { + return card != cardx && get.name(card, player) == "sha"; }); - if(!shas.length) return -1; - if(shas.length>1&&(player.getCardUsable('sha')>1||player.countCards('hs','zhuge'))){ + if (!shas.length) return -1; + if ( + shas.length > 1 && + (player.getCardUsable("sha") > 1 || player.countCards("hs", "zhuge")) + ) { return 0; } - shas.sort(function(a,b){ - return get.order(b)-get.order(a); + shas.sort(function (a, b) { + return get.order(b) - get.order(a); }); - var card=false; - if(shas.length){ - for(var i=0;i1+(player.storage.jiu||0) - &&player.canUse(card,current,true,true)&& - !current.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - jiu:true, - })&& - get.effect(current,card,player)>0); - })){ - return 4-get.value(cardx); + if (card) { + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + !current.hasShan() && + current.hp + current.countCards("h", { name: ["tao", "jiu"] }) > + 1 + (player.storage.jiu || 0) && + player.canUse(card, current, true, true) && + !current.hasSkillTag("filterDamage", null, { + player: player, + card: card, + jiu: true, + }) && + get.effect(current, card, player) > 0 + ); + }) + ) { + return 4 - get.value(cardx); } } return -1; }, - ai:{ - threaten:1.5, + ai: { + threaten: 1.5, }, - trigger:{source:'damageEnd'}, - locked:false, - forced:true, - filter:function(event,player){ - if(event.name=='chooseToUse') return player.hasCard(card=>get.suit(card)=='spade','hs'); - return event.card&&event.card.name=='sha'&&event.getParent(2).jiu==true&&!player.hasSkill('oljiuchi_air'); + trigger: { source: "damageEnd" }, + locked: false, + forced: true, + filter: function (event, player) { + if (event.name == "chooseToUse") + return player.hasCard((card) => get.suit(card) == "spade", "hs"); + return ( + event.card && + event.card.name == "sha" && + event.getParent(2).jiu == true && + !player.hasSkill("oljiuchi_air") + ); }, - content:function(){ - player.logSkill('oljiuchi'); - player.addTempSkill('oljiuchi_air'); + content: function () { + player.logSkill("oljiuchi"); + player.addTempSkill("oljiuchi_air"); }, - subSkill:{ - air:{}, + subSkill: { + air: {}, }, }, - rezaiqi:{ - count:function(){ - var num=0; - game.countPlayer2(function(current){ - current.getHistory('lose',function(evt){ - if(evt.position==ui.discardPile){ - for(var i=0;i0; + audio: 2, + direct: true, + filter: function (event, player) { + return lib.skill.rezaiqi.count() > 0; }, - trigger:{ - player:'phaseJieshuBegin' + trigger: { + player: "phaseJieshuBegin", }, - content:function(){ - 'step 0' - player.chooseTarget([1,lib.skill.rezaiqi.count()],get.prompt2('rezaiqi')).ai=function(target){ - return get.attitude(_status.event.player,target); - }; - 'step 1' - if(result.bool){ - var targets=result.targets; + content: function () { + "step 0"; + player.chooseTarget([1, lib.skill.rezaiqi.count()], get.prompt2("rezaiqi")).ai = + function (target) { + return get.attitude(_status.event.player, target); + }; + "step 1"; + if (result.bool) { + var targets = result.targets; targets.sortBySeat(); - player.line(targets,'fire'); - player.logSkill('rezaiqi',targets); - event.targets=targets; - } - else event.finish(); - 'step 2' - event.current=targets.shift(); - if(player.isHealthy()) event._result={index:0}; - else event.current.chooseControl().set('choiceList',[ - '摸一张牌', - '令'+get.translation(player)+'回复1点体力', - ]).set('ai',function(){ - if(get.attitude(event.current,player)>0) return 1; - return 0; - }); - 'step 3' - if(result.index==1){ + player.line(targets, "fire"); + player.logSkill("rezaiqi", targets); + event.targets = targets; + } else event.finish(); + "step 2"; + event.current = targets.shift(); + if (player.isHealthy()) event._result = { index: 0 }; + else + event.current + .chooseControl() + .set("choiceList", ["摸一张牌", "令" + get.translation(player) + "回复1点体力"]) + .set("ai", function () { + if (get.attitude(event.current, player) > 0) return 1; + return 0; + }); + "step 3"; + if (result.index == 1) { event.current.line(player); player.recover(); - } - else event.current.draw(); + } else event.current.draw(); game.delay(); - if(targets.length) event.goto(2); + if (targets.length) event.goto(2); }, }, }, - dynamicTranslate:{ - rejiushi:function(player){ - if(player.storage.chengzhang) return '当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面。当你翻面时,你获得牌堆中的一张随机锦囊。'; - return '当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面并获得牌堆中的一张随机锦囊。'; + dynamicTranslate: { + rejiushi: function (player) { + if (player.storage.chengzhang) + return "当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面。当你翻面时,你获得牌堆中的一张随机锦囊。"; + return "当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面并获得牌堆中的一张随机锦囊。"; }, - rejiaozhao:function(player){ - return ['出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。','出牌阶段限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用(你不是此牌的合法目标)。','出牌阶段每种类型各限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用。'][player.countMark('redanxin')]; + rejiaozhao: function (player) { + return [ + "出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。", + "出牌阶段限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用(你不是此牌的合法目标)。", + "出牌阶段每种类型各限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用。", + ][player.countMark("redanxin")]; }, }, - translate:{ - re_zhangliao:'界张辽', - re_zhangliao_prefix:'界', - re_simayi:'界司马懿', - re_simayi_prefix:'界', - re_xuzhu:'界许褚', - re_xuzhu_prefix:'界', - re_xiahoudun:'界夏侯惇', - re_xiahoudun_prefix:'界', - re_lvmeng:'界吕蒙', - re_lvmeng_prefix:'界', - re_zhouyu:'界周瑜', - re_zhouyu_prefix:'界', - re_luxun:'界陆逊', - re_luxun_prefix:'界', - re_zhaoyun:'界赵云', - re_zhaoyun_prefix:'界', - re_guanyu:'界关羽', - re_guanyu_prefix:'界', - re_zhangfei:'界张飞', - re_zhangfei_prefix:'界', - re_machao:'界马超', - re_machao_prefix:'界', - re_caocao:'界曹操', - re_caocao_prefix:'界', - re_guojia:'界郭嘉', - re_guojia_prefix:'界', - re_lvbu:'界吕布', - re_lvbu_prefix:'界', - re_huanggai:'界黄盖', - re_huanggai_prefix:'界', - re_daqiao:'界大乔', - re_daqiao_prefix:'界', - re_ganning:'界甘宁', - re_ganning_prefix:'界', - re_huatuo:'界华佗', - re_huatuo_prefix:'界', - re_liubei:'界刘备', - re_liubei_prefix:'界', + translate: { + re_zhangliao: "界张辽", + re_zhangliao_prefix: "界", + re_simayi: "界司马懿", + re_simayi_prefix: "界", + re_xuzhu: "界许褚", + re_xuzhu_prefix: "界", + re_xiahoudun: "界夏侯惇", + re_xiahoudun_prefix: "界", + re_lvmeng: "界吕蒙", + re_lvmeng_prefix: "界", + re_zhouyu: "界周瑜", + re_zhouyu_prefix: "界", + re_luxun: "界陆逊", + re_luxun_prefix: "界", + re_zhaoyun: "界赵云", + re_zhaoyun_prefix: "界", + re_guanyu: "界关羽", + re_guanyu_prefix: "界", + re_zhangfei: "界张飞", + re_zhangfei_prefix: "界", + re_machao: "界马超", + re_machao_prefix: "界", + re_caocao: "界曹操", + re_caocao_prefix: "界", + re_guojia: "界郭嘉", + re_guojia_prefix: "界", + re_lvbu: "界吕布", + re_lvbu_prefix: "界", + re_huanggai: "界黄盖", + re_huanggai_prefix: "界", + re_daqiao: "界大乔", + re_daqiao_prefix: "界", + re_ganning: "界甘宁", + re_ganning_prefix: "界", + re_huatuo: "界华佗", + re_huatuo_prefix: "界", + re_liubei: "界刘备", + re_liubei_prefix: "界", - re_diaochan:'界貂蝉', - re_diaochan_prefix:'界', - re_huangyueying:'界黄月英', - re_huangyueying_prefix:'界', - re_sunquan:'界孙权', - re_sunquan_prefix:'界', - re_sunshangxiang:'界孙尚香', - re_sunshangxiang_prefix:'界', - re_zhugeliang:'界诸葛亮', - re_zhugeliang_prefix:'界', - re_zhenji:'界甄宓', - re_zhenji_prefix:'界', - re_huaxiong:"界华雄", - re_huaxiong_prefix:'界', + re_diaochan: "界貂蝉", + re_diaochan_prefix: "界", + re_huangyueying: "界黄月英", + re_huangyueying_prefix: "界", + re_sunquan: "界孙权", + re_sunquan_prefix: "界", + re_sunshangxiang: "界孙尚香", + re_sunshangxiang_prefix: "界", + re_zhugeliang: "界诸葛亮", + re_zhugeliang_prefix: "界", + re_zhenji: "界甄宓", + re_zhenji_prefix: "界", + re_huaxiong: "界华雄", + re_huaxiong_prefix: "界", - ol_sp_zhugeliang:"界卧龙", - ol_sp_zhugeliang_prefix:'界', - re_zhangjiao:'界张角', - re_zhangjiao_prefix:'界', - re_sunce:'界孙策', - re_sunce_prefix:'界', - ol_yuanshao:'界袁绍', - ol_yuanshao_prefix:'界', - ol_liushan:'界刘禅', - ol_liushan_prefix:'界', + ol_sp_zhugeliang: "界卧龙", + ol_sp_zhugeliang_prefix: "界", + re_zhangjiao: "界张角", + re_zhangjiao_prefix: "界", + re_sunce: "界孙策", + re_sunce_prefix: "界", + ol_yuanshao: "界袁绍", + ol_yuanshao_prefix: "界", + ol_liushan: "界刘禅", + ol_liushan_prefix: "界", - olfangquan:'放权', - olfangquan_info:'出牌阶段开始前,你可以跳过此阶段。若如此做,弃牌阶段开始时,你可以弃置一张手牌,令一名其他角色进行一个额外回合。', - olruoyu:'若愚', - olruoyu_info:'主公技,觉醒技,准备阶段,若你的体力值为全场最少,则你加1点体力上限,将体力回复至3点,然后获得技能〖思蜀〗和〖激将〗。', - sishu:'思蜀', - sishu_info:'出牌阶段开始时,你可以选择一名角色。该角色本局游戏内【乐不思蜀】的判定效果反转。', - olluanji:'乱击', - olluanji_info:'你可以将两张花色相同的手牌当做【万箭齐发】使用。当你使用【万箭齐发】选择目标后,你可以为此牌减少一个目标。', - olluanji_remove:'乱击', - olxueyi:'血裔', - olxueyi_info:'主公技,锁定技。①游戏开始时,你获得2X个“裔”标记(X为场上群势力角色的数目)。②出牌阶段开始时,你可以移去一个“裔”标记,然后摸一张牌。③你的手牌上限+Y(Y为“裔”标记数)。', - olxueyi_draw:'血裔', - olhunzi:'魂姿', - olhunzi_info:'觉醒技,准备阶段,若你的体力值为1,你减1点体力上限并获得技能〖英姿〗和〖英魂〗;本回合的结束阶段,你摸两张牌或回复1点体力。', - olzhiba:'制霸', - olzhiba_info:'主公技,其他吴势力的角色的出牌阶段限一次,其可以与你拼点(你可拒绝此拼点)。若其没赢,你可以获得两张拼点牌。你的出牌阶段限一次,你可以和一名吴势力角色拼点,若你赢,你获得两张拼点牌。', - olzhiba2:'制霸', - xinleiji:'雷击', - xinleiji_misa:'雷击', - xinguidao:'鬼道', - xinleiji_info:'①当你使用【闪】或【闪电】,或打出【闪】时,你可以进行判定。②当你的判定的判定牌生效后,若结果为:黑桃,你可对一名角色造成2点雷电伤害;梅花:你回复1点体力并可对一名角色造成1点雷电伤害。', - xinleiji_append:'不能触发〖雷击〗的判定:〖暴虐〗、〖助祭〗、
              〖弘仪〗、〖孤影〗。
              ', - xinleiji_faq:'不能触发〖雷击〗的判定', - xinleiji_faq_info:'
              董卓/界董卓〖暴虐〗
              黄巾雷使〖助祭〗
              羊徽瑜〖弘仪〗
              鸣濑白羽〖孤影〗', - xinguidao_info:'一名角色的判定牌生效前,你可以打出一张黑色牌作为判定牌并获得原判定牌。若你以此法打出的牌为黑桃2-9,则你摸一张牌。', - xinhuangtian:'黄天', - xinhuangtian2:'黄天', - xinhuangtian_info:'主公技。其他群势力角色的出牌阶段限一次,该角色可以交给你一张【闪】或黑桃手牌。', - reqiangxi:"强袭", - "reqiangxi_info":"出牌阶段对每名其他角色限一次,你可以选择一项:1. 失去1点体力并对你攻击范围内的一名其他角色造成1点伤害;2. 弃置一张武器牌并对你攻击范围内的一名其他角色造成1点伤害。", - rehuoji:"火计", - rehuoji_info:"你可一张红色牌当作【火攻】使用。", - rekanpo:"看破", - rekanpo_info:"你可以将一张黑色牌当作【无懈可击】使用。", - reshuangxiong:"双雄", - reshuangxiong1:"双雄", - reshuangxiong2:"双雄", - reshuangxiong_info:"摸牌阶段,你可以放弃摸牌。若如此做,你展示牌堆顶的两张牌并选择获得其中的一张。然后,你本回合内可以将与此牌颜色不同的一张手牌当做【决斗】使用。当你受到【决斗】造成的伤害时,你可以获得对方于此决斗中打出的所有【杀】。", + olfangquan: "放权", + olfangquan_info: + "出牌阶段开始前,你可以跳过此阶段。若如此做,弃牌阶段开始时,你可以弃置一张手牌,令一名其他角色进行一个额外回合。", + olruoyu: "若愚", + olruoyu_info: + "主公技,觉醒技,准备阶段,若你的体力值为全场最少,则你加1点体力上限,将体力回复至3点,然后获得技能〖思蜀〗和〖激将〗。", + sishu: "思蜀", + sishu_info: "出牌阶段开始时,你可以选择一名角色。该角色本局游戏内【乐不思蜀】的判定效果反转。", + olluanji: "乱击", + olluanji_info: + "你可以将两张花色相同的手牌当做【万箭齐发】使用。当你使用【万箭齐发】选择目标后,你可以为此牌减少一个目标。", + olluanji_remove: "乱击", + olxueyi: "血裔", + olxueyi_info: + "主公技,锁定技。①游戏开始时,你获得2X个“裔”标记(X为场上群势力角色的数目)。②出牌阶段开始时,你可以移去一个“裔”标记,然后摸一张牌。③你的手牌上限+Y(Y为“裔”标记数)。", + olxueyi_draw: "血裔", + olhunzi: "魂姿", + olhunzi_info: + "觉醒技,准备阶段,若你的体力值为1,你减1点体力上限并获得技能〖英姿〗和〖英魂〗;本回合的结束阶段,你摸两张牌或回复1点体力。", + olzhiba: "制霸", + olzhiba_info: + "主公技,其他吴势力的角色的出牌阶段限一次,其可以与你拼点(你可拒绝此拼点)。若其没赢,你可以获得两张拼点牌。你的出牌阶段限一次,你可以和一名吴势力角色拼点,若你赢,你获得两张拼点牌。", + olzhiba2: "制霸", + xinleiji: "雷击", + xinleiji_misa: "雷击", + xinguidao: "鬼道", + xinleiji_info: + "①当你使用【闪】或【闪电】,或打出【闪】时,你可以进行判定。②当你的判定的判定牌生效后,若结果为:黑桃,你可对一名角色造成2点雷电伤害;梅花:你回复1点体力并可对一名角色造成1点雷电伤害。", + xinleiji_append: + '不能触发〖雷击〗的判定:〖暴虐〗、〖助祭〗、
              〖弘仪〗、〖孤影〗。
              ', + xinleiji_faq: "不能触发〖雷击〗的判定", + xinleiji_faq_info: + "
              董卓/界董卓〖暴虐〗
              黄巾雷使〖助祭〗
              羊徽瑜〖弘仪〗
              鸣濑白羽〖孤影〗", + xinguidao_info: + "一名角色的判定牌生效前,你可以打出一张黑色牌作为判定牌并获得原判定牌。若你以此法打出的牌为黑桃2-9,则你摸一张牌。", + xinhuangtian: "黄天", + xinhuangtian2: "黄天", + xinhuangtian_info: + "主公技。其他群势力角色的出牌阶段限一次,该角色可以交给你一张【闪】或黑桃手牌。", + reqiangxi: "强袭", + reqiangxi_info: + "出牌阶段对每名其他角色限一次,你可以选择一项:1. 失去1点体力并对你攻击范围内的一名其他角色造成1点伤害;2. 弃置一张武器牌并对你攻击范围内的一名其他角色造成1点伤害。", + rehuoji: "火计", + rehuoji_info: "你可一张红色牌当作【火攻】使用。", + rekanpo: "看破", + rekanpo_info: "你可以将一张黑色牌当作【无懈可击】使用。", + reshuangxiong: "双雄", + reshuangxiong1: "双雄", + reshuangxiong2: "双雄", + reshuangxiong_info: + "摸牌阶段,你可以放弃摸牌。若如此做,你亮出牌堆顶的两张牌并选择获得其中的一张。然后,你本回合内可以将与此牌颜色不同的一张手牌当做【决斗】使用。当你受到【决斗】造成的伤害时,你可以获得对方于此决斗中打出的所有【杀】。", - reguanxing:'观星', - reguanxing_info:'准备阶段,你可以观看牌堆顶的五张牌(存活角色小于4时改为三张),并将其以任意顺序置于牌堆项或牌堆底,若你将〖观星〗的牌都放在了牌堆底,则你可以在结束阶段再次发动〖观星〗。', - reluoshen:'洛神', - reluoshen_info:'准备阶段,你可以进行判定,若结果为黑色则获得此判定牌,且可重复此流程直到出现红色的判定结果。你通过〖洛神〗得到的牌不计入当前回合的手牌上限。', - reluoshen_info_guozhan:'准备阶段,你可以进行判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。你通过〖洛神〗得到的牌不计入当前回合的手牌上限(结果为黑色的判定牌于此过程中不会进入弃牌堆)。', - rejieyin:'结姻', - rejieyin_info:'出牌阶段限一次,你可以选择一名男性角色并弃置一张手牌或将装备区内的一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。', - rebiyue:'闭月', - rebiyue_info:'结束阶段,你可以摸一张牌,若你没有手牌,则改为摸两张牌。', - rejizhi:'集智', - rejizhi_info:'当你使用锦囊牌时,你可以摸一张牌。若此牌为基本牌,则你可以弃置之,然后令本回合手牌上限+1。', - reqicai:'奇才', - reqicai_info:'锁定技,你使用锦囊牌无距离限制,你装备区内的防具牌和宝物牌不能被其他角色弃置。', - rezhiheng:'制衡', - rezhiheng_info:'出牌阶段限一次,你可以弃置任意张牌并摸等量的牌,若你在发动〖制衡〗时弃置了所有手牌,则你多摸一张牌。', - rejiuyuan:'救援', - rejiuyuan_info:'主公技,其他吴势力角色对自己使用【桃】时,若其体力值大于你,则其可以选择令你回复1点体力,然后其摸一张牌。', + reguanxing: "观星", + reguanxing_info: + "准备阶段,你可以观看牌堆顶的五张牌(存活角色小于4时改为三张),并将其以任意顺序置于牌堆项或牌堆底,若你将〖观星〗的牌都放在了牌堆底,则你可以在结束阶段再次发动〖观星〗。", + reluoshen: "洛神", + reluoshen_info: + "准备阶段,你可以进行判定,若结果为黑色则获得此判定牌,且可重复此流程直到出现红色的判定结果。你通过〖洛神〗得到的牌不计入当前回合的手牌上限。", + reluoshen_info_guozhan: + "准备阶段,你可以进行判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。你通过〖洛神〗得到的牌不计入当前回合的手牌上限(结果为黑色的判定牌于此过程中不会进入弃牌堆)。", + rejieyin: "结姻", + rejieyin_info: + "出牌阶段限一次,你可以选择一名男性角色并弃置一张手牌或将装备区内的一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。", + rebiyue: "闭月", + rebiyue_info: "结束阶段,你可以摸一张牌,若你没有手牌,则改为摸两张牌。", + rejizhi: "集智", + rejizhi_info: + "当你使用锦囊牌时,你可以摸一张牌。若此牌为基本牌,则你可以弃置之,然后令本回合手牌上限+1。", + reqicai: "奇才", + reqicai_info: "锁定技,你使用锦囊牌无距离限制,你装备区内的防具牌和宝物牌不能被其他角色弃置。", + rezhiheng: "制衡", + rezhiheng_info: + "出牌阶段限一次,你可以弃置任意张牌并摸等量的牌,若你在发动〖制衡〗时弃置了所有手牌,则你多摸一张牌。", + rejiuyuan: "救援", + rejiuyuan_info: + "主公技,其他吴势力角色对自己使用【桃】时,若其体力值大于你,则其可以选择令你回复1点体力,然后其摸一张牌。", - "new_yajiao":"涯角", - "new_yajiao_info":"每当你于回合外使用或打出牌时,你可以亮出牌堆顶的一张牌,并将其交给一名角色。若此牌与你此次使用或打出的牌类别不同,则你弃置一张牌。", - "new_liyu":"利驭", - "new_liyu_info":"当你使用【杀】对一名其他角色造成伤害后,你可以获得其区域内的一张牌。若此牌不为装备牌,则其摸一张牌。若此牌为装备牌,则视为你对其选择的另一名角色使用一张【决斗】。", - "new_retuxi":"突袭", - "new_retuxi_info":"摸牌阶段摸牌时,你可以少摸任意张牌,然后获得等量的角色的各一张手牌。", - "new_retuxi_info_guozhan":"摸牌阶段摸牌时,你可以少摸至多两张牌,然后获得等量的角色的各一张手牌。", - reyiji_tag:'已分配', - "new_reyiji":"遗计", - "new_reyiji_info":"当你受到1点伤害后,你可以摸两张牌,然后可以将至多两张手牌交给其他角色。", - "new_rejianxiong":"奸雄", - "new_rejianxiong_info":"当你受到伤害后,你可以获得对你造成伤害的牌并摸一张牌。", - "new_reluoyi":"裸衣", - "new_reluoyi_info":"摸牌阶段开始时,你展示牌堆顶的三张牌。然后,你可以放弃摸牌。若如此做,你获得其中的基本牌、武器牌和【决斗】,且直到你的下回合开始,你使用的【杀】或【决斗】造成伤害时,此伤害+1。否则,你将这些牌置入弃牌堆。", - "new_rewusheng":"武圣", - "new_rewusheng_info":"你可以将一张红色牌当做【杀】使用或打出。你使用的方片杀没有距离限制。", - "new_yijue":"义绝", - "new_yijue_info":"出牌阶段限一次,你可以弃置一张牌并令一名有手牌的其他角色展示一张手牌。若此牌为黑色,则该角色不能使用或打出牌,非锁定技失效且受到来自你的红桃【杀】的伤害+1直到回合结束。若此牌为红色,则你可以获得此牌,并可以令其回复1点体力。", - "new_yijue2":"义绝", - "new_yijue2_info":"", - "new_repaoxiao":"咆哮", - "new_repaoxiao_info":"锁定技,出牌阶段,你使用【杀】没有数量限制。若你于此出牌阶段内使用过【杀】,则你本回合内使用【杀】没有距离限制。", - "new_tishen":"替身", - "new_tishen_info":"出牌阶段结束时,你可以弃置你所有的锦囊牌与坐骑牌。若如此做,直到你的下个回合开始,当一张【杀】结算结束后,若你是此牌目标且你未受到此牌伤害,你获得此牌对应的所有实体牌。", - "new_tishen2":"替身", - "new_tishen2_info":"", - "new_qingjian":"清俭", - "new_qingjian_info":"当你于摸牌阶段外得到牌后,你可以展示任意张牌并交给一名其他角色。然后,当前回合角色本回合的手牌上限+X(X为你给出的牌中包含的类别数)。每回合限一次。", - "qingjian_add":"清俭", - "qingjian_add_info":"", - "new_reqingnang":"青囊", - "new_reqingnang_info":"出牌阶段,你可以弃置一张手牌,令一名本回合内未成为过〖青囊〗的目标的角色回复1点体力。若你弃置的是黑色牌,则你本回合内不能再发动〖青囊〗。", - "new_reyaowu":"耀武", - "new_reyaowu_info":"锁定技,当一名角色使用【杀】对你造成伤害时,若此杀为红色,该角色回复1点体力或摸一张牌。否则你摸一张牌。", - reyaowu:'耀武', - reyaowu_info:'锁定技,当你受到牌造成的伤害时,若此牌为红色,则伤害来源摸一张牌;否则你摸一张牌。', - reqingguo:'倾国', - reqingguo_info:'你可以将一张黑色牌当做【闪】使用或打出。', + new_yajiao: "涯角", + new_yajiao_info: + "每当你于回合外使用或打出牌时,你可以亮出牌堆顶的一张牌,并将其交给一名角色。若此牌与你此次使用或打出的牌类别不同,则你弃置一张牌。", + new_liyu: "利驭", + new_liyu_info: + "当你使用【杀】对一名其他角色造成伤害后,你可以获得其区域内的一张牌。若此牌不为装备牌,则其摸一张牌。若此牌为装备牌,则视为你对其选择的另一名角色使用一张【决斗】。", + new_retuxi: "突袭", + new_retuxi_info: "摸牌阶段摸牌时,你可以少摸任意张牌,然后获得等量的角色的各一张手牌。", + new_retuxi_info_guozhan: "摸牌阶段摸牌时,你可以少摸至多两张牌,然后获得等量的角色的各一张手牌。", + reyiji_tag: "已分配", + new_reyiji: "遗计", + new_reyiji_info: "当你受到1点伤害后,你可以摸两张牌,然后可以将至多两张手牌交给其他角色。", + new_rejianxiong: "奸雄", + new_rejianxiong_info: "当你受到伤害后,你可以获得对你造成伤害的牌并摸一张牌。", + new_reluoyi: "裸衣", + new_reluoyi_info: + "摸牌阶段开始时,你亮出牌堆顶的三张牌。然后,你可以放弃摸牌。若如此做,你获得其中的基本牌、武器牌和【决斗】,且直到你的下回合开始,你使用的【杀】或【决斗】造成伤害时,此伤害+1。否则,你将这些牌置入弃牌堆。", + new_rewusheng: "武圣", + new_rewusheng_info: "你可以将一张红色牌当做【杀】使用或打出。你使用的方片杀没有距离限制。", + new_yijue: "义绝", + new_yijue_info: + "出牌阶段限一次,你可以弃置一张牌并令一名有手牌的其他角色展示一张手牌。若此牌为黑色,则该角色不能使用或打出牌,非锁定技失效且受到来自你的红桃【杀】的伤害+1直到回合结束。若此牌为红色,则你可以获得此牌,并可以令其回复1点体力。", + new_yijue2: "义绝", + new_yijue2_info: "", + new_repaoxiao: "咆哮", + new_repaoxiao_info: + "锁定技,出牌阶段,你使用【杀】没有数量限制。若你于此出牌阶段内使用过【杀】,则你本回合内使用【杀】没有距离限制。", + new_tishen: "替身", + new_tishen_info: + "出牌阶段结束时,你可以弃置你所有的锦囊牌与坐骑牌。若如此做,直到你的下个回合开始,当一张【杀】结算结束后,若你是此牌目标且你未受到此牌伤害,你获得此牌对应的所有实体牌。", + new_tishen2: "替身", + new_tishen2_info: "", + new_qingjian: "清俭", + new_qingjian_info: + "当你于摸牌阶段外得到牌后,你可以展示任意张牌并交给一名其他角色。然后,当前回合角色本回合的手牌上限+X(X为你给出的牌中包含的类别数)。每回合限一次。", + qingjian_add: "清俭", + qingjian_add_info: "", + new_reqingnang: "青囊", + new_reqingnang_info: + "出牌阶段,你可以弃置一张手牌,令一名本回合内未成为过〖青囊〗的目标的角色回复1点体力。若你弃置的是黑色牌,则你本回合内不能再发动〖青囊〗。", + new_reyaowu: "耀武", + new_reyaowu_info: + "锁定技,当一名角色使用【杀】对你造成伤害时,若此杀为红色,该角色回复1点体力或摸一张牌。否则你摸一张牌。", + reyaowu: "耀武", + reyaowu_info: + "锁定技,当你受到牌造成的伤害时,若此牌为红色,则伤害来源摸一张牌;否则你摸一张牌。", + reqingguo: "倾国", + reqingguo_info: "你可以将一张黑色牌当做【闪】使用或打出。", - qinxue:'勤学', - retuxi:'突袭', - reluoyi:'裸衣', - reluoyi2:'裸衣', - reganglie:'刚烈', - qingjian:'清俭', - reyingzi:'英姿', - refanjian:'反间', - refanjian_card:'弃牌', - refanjian_hp:'失去体力', - reqianxun:'谦逊', - reqianxun2:'谦逊', - relianying:'连营', - retishen:'替身', - retishen2:'替身', - reyajiao:'涯角', - rejianxiong:'奸雄', - rejianxiong_mopai:'摸牌', - rejianxiong_napai:'拿牌', - reyiji:'遗计', - reyiji2:'遗计', - yijue:'义绝', - yijue2:'义绝', - retieji:'铁骑', - refankui:'反馈', - reyicong:'义从', - qiaomeng:'趫猛', - rekurou:'苦肉', - zhaxiang:'诈降', - zhaxiang2:'诈降', - zhuhai:'诛害', - qianxin:'潜心', - jianyan:'荐言', - reguicai:'鬼才', - xunxun:'恂恂', - wangxi:'忘隙', - reguose:'国色', - fenwei:'奋威', - chulao:'除疠', - liyu:'利驭', - rerende:'仁德', - rerende_info:'出牌阶段,你可以将至少一张手牌交给其他角色,然后你于此阶段内不能再以此法交给该角色牌;若你于此阶段内给出的牌首次达到两张,你可以视为使用一张基本牌。', - liyu_info:'当你使用【杀】对一名其他角色造成伤害后,该角色可令你获得其一张牌,若如此做,则视为你对其选择的另一名角色使用一张【决斗】。', - xunxun_info:'摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。', - wangxi_info:'每当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可与该角色各摸一张牌。', - reguose_info:'出牌阶段限一次,你可以选择一项:将一张方片花色牌当做【乐不思蜀】使用;或弃置一张方片花色牌并弃置场上的一张【乐不思蜀】。选择完成后,你摸一张牌。', - fenwei_info:'限定技,当一名角色使用的锦囊牌指定了至少两名角色为目标时,你可以令此牌对其中任意名角色无效。', - chulao_info:'出牌阶段限一次,若你有牌,你可以选择任意名势力各不相同的其他角色,你弃置你和这些角色的各一张牌。然后以此法弃置黑桃牌的角色各摸一张牌。', - reguicai_info:'在任意角色的判定牌生效前,你可以打出一张牌代替之。', - zhuhai_info:'一名其他角色的结束阶段开始时,若该角色本回合造成过伤害,你可以对其使用一张【杀】。', - qianxin_info:'觉醒技,当你造成一次伤害后,若你已受伤,你须减1点体力上限,并获得技能“荐言”。', - jianyan_info:'出牌阶段限一次,你可以声明一种牌的类别或颜色,并亮出牌库中第一张符合你声明的牌,然后你令一名男性角色获得此牌。', - rekurou_info:'出牌阶段限一次,你可以弃置一张牌,然后失去1点体力。', - zhaxiang_info:'锁定技。当你失去1点体力后,你摸三张牌。然后若此时是你的出牌阶段,则你本回合获得此下效果:使用【杀】的次数上限+1,使用红色【杀】无距离限制且不能被【闪】响应。', - qiaomeng_info:'当你使用黑色【杀】对一名角色造成伤害后,你可以弃置该角色装备区里的一张牌,若此牌是坐骑牌,你于此牌置入弃牌堆后获得之。', - reyicong_info:'锁定技,你计算与其他角色的距离时-1。若你的体力值不大于2,则其他角色计算与你的距离时+1。', - refankui_info:'每当你受到1点伤害后,你可以获得伤害来源的一张牌。', - retieji_info:'当你使用【杀】指定一名角色为目标后,你可以进行一次判定并令该角色的非锁定技失效直到回合结束,除非该角色弃置一张与判定结果花色相同的牌,否则不能使用【闪】抵消此【杀】。', - yijue_info:'出牌阶段限一次,你可以与一名其他角色拼点,若你赢,则直到回合结束,该角色不能使用或打出手牌且其非锁定技失效,若你没赢,你可令该角色回复1点体力。', - reyiji_info:'每当你受到1点伤害后,你可以摸两张牌。然后你可以在至多两名角色的武将牌旁边分别扣置至多两张手牌,这些角色的下个摸牌阶段开始时,该角色获得其武将牌旁的这些牌。', - rejianxiong_info:'每当你受到伤害后,你可以获得对你造成伤害的牌,然后摸一张牌。', - reyajiao_info:'每当你于回合外使用或打出一张手牌时,你可以亮出牌堆顶的一张牌,若此牌与你此次使用或打出的牌类别相同,你可以将之交给任意一名角色;若不同则你可以将之置入弃牌堆。', - retishen_info:'限定技,准备阶段开始时,你可以将体力回复至等同于你上回合结束时的体力值,然后你每以此法回复1点体力,便摸一张牌。', - reqianxun_info:'每当一张延时类锦囊牌或其他角色使用的普通锦囊牌生效时,若你是此牌的唯一目标,你可以将所有手牌置于你的武将牌上,若如此做,此回合结束时,你获得你武将牌上的所有牌。', - relianying_info:'当你失去最后的手牌时,你可以令至多X名角色各摸一张牌(X为你此次失去的手牌数)。', - reyingzi_info:'锁定技,摸牌阶段摸牌时,你额外摸一张牌;你的手牌上限为你的体力上限。', - refanjian_info:'出牌阶段限一次,你可以展示一张手牌并将此牌交给一名其他角色。然后该角色选择一项:展示其手牌并弃置所有与此牌花色相同的牌,或失去1点体力。', - qingjian_info:'每当你于摸牌阶段外得到牌时,你可以将其中任意牌以任意顺序交给其他角色,每回合最多发动四次。', - qinxue_info:'觉醒技。准备阶段或结束阶段开始时,若你的手牌数减体力值大于1,则你减1点体力上限,回复1点体力或摸两张牌,获得技能〖攻心〗。', - retuxi_info:'摸牌阶段摸牌时,你可以少摸任意张牌,然后选择等量的手牌数大于或等于你的其他角色,获得这些角色的各一张手牌。', - reluoyi_info:'你可以跳过摸牌阶段,然后展示牌堆顶的三张牌,获得其中的基本牌、武器牌和【决斗】,若如此做,直到你的下回合开始,你为伤害来源的【杀】或【决斗】造成的伤害+1。', - reganglie_info:'当你受到1点伤害后,你可进行判定,若结果为:红色,你对伤害来源造成1点伤害,;黑色,你弃置伤害来源一张牌。', - reganglie_info_guozhan:'当你受到伤害后,你可进行判定,若结果为:红色,你对伤害来源造成1点伤害,;黑色,你弃置伤害来源一张牌。', - botu:'博图', - botu_info:'回合结束时,若你本回合出牌阶段内使用的牌包含四种花色,则你可以进行一个额外回合。', - rebotu:'博图', - rebotu_info:'每轮限X次。回合结束时,若本回合内置入弃牌堆的牌中包含至少四种花色,则你可获得一个额外的回合。(X为存活角色数且至多为3)', + qinxue: "勤学", + retuxi: "突袭", + reluoyi: "裸衣", + reluoyi2: "裸衣", + reganglie: "刚烈", + qingjian: "清俭", + reyingzi: "英姿", + refanjian: "反间", + refanjian_card: "弃牌", + refanjian_hp: "失去体力", + reqianxun: "谦逊", + reqianxun2: "谦逊", + relianying: "连营", + retishen: "替身", + retishen2: "替身", + reyajiao: "涯角", + rejianxiong: "奸雄", + rejianxiong_mopai: "摸牌", + rejianxiong_napai: "拿牌", + reyiji: "遗计", + reyiji2: "遗计", + yijue: "义绝", + yijue2: "义绝", + retieji: "铁骑", + refankui: "反馈", + reyicong: "义从", + qiaomeng: "趫猛", + rekurou: "苦肉", + zhaxiang: "诈降", + zhaxiang2: "诈降", + zhuhai: "诛害", + qianxin: "潜心", + jianyan: "荐言", + reguicai: "鬼才", + xunxun: "恂恂", + wangxi: "忘隙", + reguose: "国色", + fenwei: "奋威", + chulao: "除疠", + liyu: "利驭", + rerende: "仁德", + rerende_info: + "出牌阶段,你可以将至少一张手牌交给其他角色,然后你于此阶段内不能再以此法交给该角色牌;若你于此阶段内给出的牌首次达到两张,你可以视为使用一张基本牌。", + liyu_info: + "当你使用【杀】对一名其他角色造成伤害后,该角色可令你获得其一张牌,若如此做,则视为你对其选择的另一名角色使用一张【决斗】。", + xunxun_info: + "摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。", + wangxi_info: + "每当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可与该角色各摸一张牌。", + reguose_info: + "出牌阶段限一次,你可以选择一项:将一张方片花色牌当做【乐不思蜀】使用;或弃置一张方片花色牌并弃置场上的一张【乐不思蜀】。选择完成后,你摸一张牌。", + fenwei_info: + "限定技,当一名角色使用的锦囊牌指定了至少两名角色为目标时,你可以令此牌对其中任意名角色无效。", + chulao_info: + "出牌阶段限一次,若你有牌,你可以选择任意名势力各不相同的其他角色,你弃置你和这些角色的各一张牌。然后以此法弃置黑桃牌的角色各摸一张牌。", + reguicai_info: "在任意角色的判定牌生效前,你可以打出一张牌代替之。", + zhuhai_info: "一名其他角色的结束阶段开始时,若该角色本回合造成过伤害,你可以对其使用一张【杀】。", + qianxin_info: "觉醒技,当你造成一次伤害后,若你已受伤,你须减1点体力上限,并获得技能“荐言”。", + jianyan_info: + "出牌阶段限一次,你可以声明一种牌的类别或颜色,并亮出牌库中第一张符合你声明的牌,然后你令一名男性角色获得此牌。", + rekurou_info: "出牌阶段限一次,你可以弃置一张牌,然后失去1点体力。", + zhaxiang_info: + "锁定技。当你失去1点体力后,你摸三张牌。然后若此时是你的出牌阶段,则你本回合获得此下效果:使用【杀】的次数上限+1,使用红色【杀】无距离限制且不能被【闪】响应。", + qiaomeng_info: + "当你使用黑色【杀】对一名角色造成伤害后,你可以弃置该角色装备区里的一张牌,若此牌是坐骑牌,你于此牌置入弃牌堆后获得之。", + reyicong_info: + "锁定技,你计算与其他角色的距离时-1。若你的体力值不大于2,则其他角色计算与你的距离时+1。", + refankui_info: "每当你受到1点伤害后,你可以获得伤害来源的一张牌。", + retieji_info: + "当你使用【杀】指定一名角色为目标后,你可以进行一次判定并令该角色的非锁定技失效直到回合结束,除非该角色弃置一张与判定结果花色相同的牌,否则不能使用【闪】抵消此【杀】。", + yijue_info: + "出牌阶段限一次,你可以与一名其他角色拼点,若你赢,则直到回合结束,该角色不能使用或打出手牌且其非锁定技失效,若你没赢,你可令该角色回复1点体力。", + reyiji_info: + "每当你受到1点伤害后,你可以摸两张牌。然后你可以在至多两名角色的武将牌旁边分别扣置至多两张手牌,这些角色的下个摸牌阶段开始时,该角色获得其武将牌旁的这些牌。", + rejianxiong_info: "每当你受到伤害后,你可以获得对你造成伤害的牌,然后摸一张牌。", + reyajiao_info: + "每当你于回合外使用或打出一张手牌时,你可以亮出牌堆顶的一张牌,若此牌与你此次使用或打出的牌类别相同,你可以将之交给任意一名角色;若不同则你可以将之置入弃牌堆。", + retishen_info: + "限定技,准备阶段开始时,你可以将体力回复至等同于你上回合结束时的体力值,然后你每以此法回复1点体力,便摸一张牌。", + reqianxun_info: + "每当一张延时类锦囊牌或其他角色使用的普通锦囊牌生效时,若你是此牌的唯一目标,你可以将所有手牌置于你的武将牌上,若如此做,此回合结束时,你获得你武将牌上的所有牌。", + relianying_info: "当你失去最后的手牌时,你可以令至多X名角色各摸一张牌(X为你此次失去的手牌数)。", + reyingzi_info: "锁定技,摸牌阶段摸牌时,你额外摸一张牌;你的手牌上限为你的体力上限。", + refanjian_info: + "出牌阶段限一次,你可以展示一张手牌并将此牌交给一名其他角色。然后该角色选择一项:展示其手牌并弃置所有与此牌花色相同的牌,或失去1点体力。", + qingjian_info: + "每当你于摸牌阶段外得到牌时,你可以将其中任意牌以任意顺序交给其他角色,每回合最多发动四次。", + qinxue_info: + "觉醒技。准备阶段或结束阶段开始时,若你的手牌数减体力值大于1,则你减1点体力上限,回复1点体力或摸两张牌,获得技能〖攻心〗。", + retuxi_info: + "摸牌阶段摸牌时,你可以少摸任意张牌,然后选择等量的手牌数大于或等于你的其他角色,获得这些角色的各一张手牌。", + reluoyi_info: + "你可以跳过摸牌阶段,然后亮出牌堆顶的三张牌,获得其中的基本牌、武器牌和【决斗】,若如此做,直到你的下回合开始,你为伤害来源的【杀】或【决斗】造成的伤害+1。", + reganglie_info: + "当你受到1点伤害后,你可进行判定,若结果为:红色,你对伤害来源造成1点伤害,;黑色,你弃置伤害来源一张牌。", + reganglie_info_guozhan: + "当你受到伤害后,你可进行判定,若结果为:红色,你对伤害来源造成1点伤害,;黑色,你弃置伤害来源一张牌。", + botu: "博图", + botu_info: "回合结束时,若你本回合出牌阶段内使用的牌包含四种花色,则你可以进行一个额外回合。", + rebotu: "博图", + rebotu_info: + "每轮限X次。回合结束时,若本回合内置入弃牌堆的牌中包含至少四种花色,则你可获得一个额外的回合。(X为存活角色数且至多为3)", - xin_yuji:'界于吉', - xin_yuji_prefix:'界', - re_zuoci:'界左慈', - re_zuoci_prefix:'界', - reguhuo:"蛊惑", - reguhuo_info:"每名角色的回合限一次,你可以扣置一张手牌当作一张基本牌或普通锦囊牌使用或打出。其他角色同时选择是否质疑。然后,你展示此牌。若有质疑的角色:若此牌为假,则此牌作废,且所有质疑者各摸一张牌;为真,则所有质疑角色于此牌结算完成后依次弃置一张牌或失去1点体力,并获得技能〖缠怨〗。", - reguhuo_guess:"蛊惑", - reguhuo_guess_info:"", - rechanyuan:"缠怨", - rechanyuan_info:"锁定技,你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值不大于1时,你的其他技能失效。", - reguhuo_ally:'信任', - reguhuo_betray:'质疑', - reguhuo_ally_bg:'真', - reguhuo_betray_bg:'假', - rehuashen:'化身', - rehuashen_info:'游戏开始时,你随机获得三张未加入游戏的武将牌,选一张置于你面前并声明该武将牌的一项技能,你拥有该技能且同时将性别和势力属性变成与该武将相同直到该化身被替换。回合开始时或回合结束时,你可以选择一项:①弃置至多两张未展示的化身牌并重新获得等量化身牌;②更换所展示的化身牌或技能。(你不可声明限定技、觉醒技、隐匿技、使命技、主公技等特殊技能)。', - rexinsheng:'新生', - rexinsheng_info:'当你受到1点伤害后,你可以获得一张新的化身牌。', - re_menghuo:'界孟获', - re_menghuo_prefix:'界', - re_caopi:'界曹丕', - re_caopi_prefix:'界', - oljiuchi:'酒池', - oljiuchi_info:'你可以将一张黑桃手牌当做【酒】使用。你使用【酒】无次数限制,且当你于回合内使用带有【酒】效果的【杀】造成伤害后,你令你的〖崩坏〗失效直到回合结束。', - repolu:'破虏', - repolu_info:'当你杀死一名角色/死亡时,你可以令任意名角色摸X+1张牌。(X为你此前发动过〖破虏〗的次数)', - rexingshang:'行殇', - rexingshang_info:'当其他角色死亡后,你可以选择一项:回复1点体力,或获得其所有牌。', - refangzhu:'放逐', - refangzhu_info:'当你受到伤害后,你可以令一名其他角色选择一项:摸X张牌并将武将牌翻面,或弃置X张牌并失去1点体力。(X为你已损失的体力值)', - rezaiqi:'再起', - rezaiqi_info:'结束阶段开始时,你可以令至多X名角色选择一项:1.摸一张牌,2.令你回复1点体力(X为本回合进入弃牌堆的红色牌数)。', - ol_caiwenji:'界蔡琰', - ol_caiwenji_prefix:'界', - retuntian:'屯田', - rebeige:'悲歌', - retuntian_info:'①当你于回合外失去牌后,你可以判定。若判定结果为♥,你获得此判定牌。否则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。', - rebeige_info:'当有角色受到【杀】造成的伤害后,你可以弃一张牌,并令其进行一次判定,若判定结果为:♥该角色回复X点体力(X为伤害点数);♦︎该角色摸三张牌;♣伤害来源弃两张牌;♠伤害来源将其武将牌翻面。', - rehunzi:'魂姿', - rehunzi_info:'觉醒技,准备阶段,若你的体力值不大于2,你减1点体力上限,并获得技能〖英姿〗和〖英魂〗。', - rezhijian:'直谏', - rezhijian_info:'出牌阶段,你可以将手牌中的一张装备牌置于一名其他角色装备区里(不得替换原装备),然后摸一张牌。当你使用装备牌时,你可以摸一张牌。', - refangquan:'放权', - refangquan_info:'你可跳过你的出牌阶段,若如此做,你本回合的手牌上限为你的体力上限,且回合结束时,你可以弃置一张手牌并令一名其他角色进行一个额外的回合。', - xin_gaoshun:'界高顺', - xin_gaoshun_prefix:'界', - repojun:'破军', - repojun2:'破军', - repojun3:'破军', - repojun_info:'当你使用【杀】指定目标后,你可以将其的至多X张牌置于其武将牌上(X为其体力值),然后其于当前回合结束时获得这些牌。当你使用【杀】对一名角色造成伤害时,若该角色的手牌数和装备区内的牌数均不大于你,则此伤害+1。', - rexianzhen:'陷阵', - rexianzhen_info:'出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你本回合内对其使用牌没有次数和距离限制且无视其防具。若你没赢,你本回合内不能使用【杀】。若你以此法失去的拼点牌为【杀】,则你的【杀】不计入本回合的手牌上限。', - rejinjiu:'禁酒', - rejinjiu_info:'锁定技,你的【酒】均视为【杀】。其他角色不能于你的回合内使用【酒】。当你受到酒【杀】的伤害时,你令此伤害-X(X为影响过此【杀】的伤害值的【酒】的数量)。', - rejinjiu2:'禁酒', - rejinjiu3:'禁酒', - ol_xiahouyuan:'界夏侯渊', - ol_xiahouyuan_prefix:'界', - shebian:'设变', - shebian_info:'当你的武将牌翻面后,你可以移动场上的一张装备牌。', - cangzhuo:'藏拙', - cangzhuo_info:'弃牌阶段开始时,若你本回合内没有使用过锦囊牌,则你的锦囊牌不计入手牌上限。', - re_zhangyi:'界张嶷', - re_zhangyi_prefix:'界', - rewurong:'怃戎', - rewurong_info:'出牌阶段限一次,你可以令一名其他角色与你同时展示一张手牌:若你展示的是【杀】且该角色展示的不是【闪】,则你对其造成1点伤害;若你展示的不是【杀】且该角色展示的是【闪】,则你获得其一张牌。', - ol_pangtong:'界庞统', - ol_pangtong_prefix:'界', - olniepan:'涅槃', - olniepan_info:'限定技,当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。然后你选择获得以下技能中的一个:〖八阵〗/〖火计〗/〖看破〗。', - ol_weiyan:'界魏延', - ol_weiyan_prefix:'界', - reqimou:'奇谋', - reqimou_info:'限定技,出牌阶段,你可以失去任意点体力并摸等量的牌,然后直到回合结束,你计算与其他角色的距离时-X,且你可以多使用X张【杀】(X为你失去的体力值)。', - ol_xiaoqiao:'界小乔', - ol_xiaoqiao_prefix:'界', - rehongyan:'红颜', - rehongyan_info:'锁定技,你区域内的黑桃牌和黑桃判定牌均视为红桃。当你于回合外正面朝上失去红桃牌后,若你的手牌数小于体力值,你摸一张牌。', - reluoying:'落英', - reluoying_discard:'落英', - reluoying_judge:'落英', - reluoying_info:'当其他角色的梅花牌因弃置或判定而进入弃牌堆后,你可以获得之。', - rejiushi:'酒诗', - rejiushi_info:'当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面并获得牌堆中的一张随机锦囊。', - rejiushi1:'酒诗', - rejiushi3:'酒诗', - rejiushi_mark:'酒诗·改', - rejiushi_mark_info:'当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面。当你翻面时,你获得牌堆中的一张随机锦囊。', - chengzhang:'成章', - chengzhang_info:'觉醒技,准备阶段开始时,若你造成伤害与受到伤害值之和累计7点或以上,则你回复1点体力并摸一张牌,然后改写〖酒诗〗。', - re_wuyi:'界吴懿', - re_wuyi_prefix:'界', - re_zhuran:'界朱然', - re_zhuran_prefix:'界', - re_quancong:'界全琮', - re_quancong_prefix:'界', - re_liaohua:'界廖化', - re_liaohua_prefix:'界', - re_guohuai:'界郭淮', - re_guohuai_prefix:'界', - re_chengpu:'界程普', - re_chengpu_prefix:'界', - rechunlao:'醇醪', - rechunlao2:'醇醪', - rechunlao_info:'出牌阶段结束时,若你没有“醇”,你可以将至少一张【杀】置于你的武将牌上,称为“醇”。当一名角色处于濒死状态时,你可以移去一张“醇”,视为该角色使用一张【酒】,然后若此“醇”的属性为:火,你回复1点体力、雷,你摸两张牌。', - re_caozhang:'界曹彰', - re_caozhang_prefix:'界', - yujin_yujin:'界于禁', - yujin_yujin_prefix:'界', - rexuanfeng:'旋风', - rexuanfeng_info:'当你失去装备区内的牌时,或于弃牌阶段弃置了两张或更多的手牌后,你可以依次弃置一至两名其他角色的共计两张牌,或将一名其他角色装备区内的一张牌移动到另一名其他角色的装备区内。', - olpaoxiao:'咆哮', - olpaoxiao2:'咆哮', - olpaoxiao_info:'①锁定技,你使用【杀】无次数限制。②锁定技,当你使用的【杀】被【闪】抵消时,你获得一枚“咆”(→)当你因【杀】造成伤害时,你弃置所有“咆”并令伤害值+X(X为“咆”数)。回合结束后,你弃置所有“咆”。', - oltishen:'替身', - oltishen_info:'限定技,准备阶段,你可以将体力回复至上限,然后摸X张牌(X为你回复的体力值)。', - ollongdan:'龙胆', - ollongdan_info:'你可以将一张【杀】当做【闪】、【闪】当做【杀】、【酒】当做【桃】、【桃】当做【酒】使用或打出。', - olyajiao:'涯角', - olyajiao_info:'当你于回合外因使用或打出而失去手牌后,你可以展示牌堆顶的一张牌。若这两张牌的类别相同,你可以将展示的牌交给一名角色;若类别不同,你可弃置攻击范围内包含你的角色区域里的一张牌。', - regongji:'弓骑', - regongji_info:'出牌阶段限一次,你可以弃置一张非基本牌,然后弃置一名其他角色的一张牌。锁定技,当你的装备区内有坐骑牌时,你的攻击范围无限。', - ol_sunjian:'界孙坚', - ol_sunjian_prefix:'界', - wulie:'武烈', - wulie2:'武烈', - wulie_info:'限定技,结束阶段,你可以失去任意点体力并指定等量的其他角色。这些角色各获得一枚「烈」。有「烈」的角色受到伤害时,其移去一枚「烈」,然后防止此伤害。', - re_sunluban:'界孙鲁班', - re_sunluban_prefix:'界', - re_masu:'界马谡', - re_masu_prefix:'界', - ol_pangde:'界庞德', - ol_pangde_prefix:'界', - rejianchu:'鞬出', - rejianchu_info:'当你使用【杀】指定一名角色为目标后,你可以弃置其一张牌,若以此法弃置的牌不为基本牌,此【杀】不可被【闪】响应且你本回合使用【杀】的次数上限+1,为基本牌,该角色获得此【杀】。', - re_taishici:'界太史慈', - re_taishici_prefix:'界', - hanzhan:'酣战', - hanzhan_gain:'酣战', - hanzhan_info:'①当你发起拼点时,或成为拼点的目标时,你可以令对方选择拼点牌的方式改为随机选择一张手牌。②当你拼点结束后,你可以获得本次拼点的拼点牌中点数最大的【杀】。', - re_jianyong:'界简雍', - re_jianyong_prefix:'界', - xin_xusheng:'界徐盛', - xin_xusheng_prefix:'界', - decadepojun:'破军', - decadepojun2:'破军', - decadepojun_info:'当你使用【杀】指定目标后,你可以将其的至多X张牌置于其武将牌上(X为其体力值)。若这些牌中:有装备牌,你将这些装备牌中的一张置于弃牌堆;有锦囊牌,你摸一张牌。其于回合结束时获得其武将牌上的这些牌。', - re_wangyi:'界王异', - re_wangyi_prefix:'界', - guanzhang:'关兴张苞', - rezishou:'自守', - rezishou2:'自守', - rezishou_info:'摸牌阶段,你可以多摸X张牌(X为存活势力数)。若如此做,本回合你对其他角色造成伤害时,防止此伤害。', - rezongshi:'宗室', - rezongshi_info:'锁定技,你的手牌上限+X(X为存活势力数)。准备阶段,若你的手牌数大于体力值,则你本回合内使用【杀】无次数限制。', - ol_dongzhuo:'界董卓', - ol_dongzhuo_prefix:'界', - olbaonue:'暴虐', - olbaonue_info:'主公技,其他群雄角色造成1点伤害后,你可进行判定,若为♠,你回复1点体力并获得判定牌。', - re_panzhangmazhong:'界潘璋马忠', - re_panzhangmazhong_prefix:'界', - re_hanhaoshihuan:'界韩浩史涣', - re_hanhaoshihuan_prefix:'界', - xinyicong:'义从', - xinyicong_info:'锁定技,你计算与其他角色的距离时-X,其他角色计算与你的距离时+Y。(X为你的体力值-1,Y为你的已损失体力值-1)', - oltianxiang:'天香', - oltianxiang_info:'当你受到伤害时,你可以弃置一张红桃牌,防止此伤害并选择一名其他角色,然后你选择一项:1.令其受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5);2.令其失去1点体力,然后获得你弃置的牌。', - olhongyan:'红颜', - olhongyan_info:'锁定技,你的黑桃牌的花色视为红桃。若你的装备区内有红桃牌,则你的手牌上限基数视为体力上限。', - piaoling:'飘零', - piaoling_info:'结束阶段,你可以进行判定。若判定结果为红桃,则你选择一项:1.将此牌交给一名角色。若你交给了自己,则你弃置一张牌。2.将此牌置于牌堆顶。', - decadelihuo:'疠火', - decadelihuo2:'疠火', - decadelihuo3:'疠火', - decadelihuo_info:'当你声明使用普【杀】后,你可以将此【杀】改为火【杀】。当你使用火【杀】选择目标时,可以选择一个额外目标。你使用的火【杀】结算完成后,若此【杀】的目标数大于1且你因此【杀】造成过伤害,则你失去1点体力。', - decadechunlao:'醇醪', - decadechunlao2:'醇醪', - decadechunlao_info:'你可以对其他角色使用【酒(使用方法②)】。当你需要使用【酒】时,若你的武将牌未横置,则你可以将武将牌横置,然后视为使用【酒】。当你受到或造成伤害后,若伤害值大于1且你的武将牌横置,则你可以重置武将牌。', - rejuece:'绝策', - rejuece_info:'结束阶段,你可以对一名本回合内失去过牌的角色造成1点伤害。', - remieji:'灭计', - remieji_info:'出牌阶段限一次,你可以将一张黑色锦囊牌置于牌堆顶,然后令一名有牌的其他角色选择一项:交给你一张锦囊牌,或依次弃置两张非锦囊牌。', - re_manchong:'界满宠', - re_manchong_prefix:'界', - rejunxing:'峻刑', - rejunxing_info:'出牌阶段限一次,你可以弃置任意张手牌并选择一名其他角色。该角色选择一项:1.弃置X张牌并失去1点体力。2.翻面并摸X张牌。(X为你弃置的牌数)', - re_gongsunzan:'界公孙瓒', - re_gongsunzan_prefix:'界', - reqiaomeng:'趫猛', - reqiaomeng_info:'当你使用【杀】对一名角色造成伤害后,你可以弃置该角色区域内的一张牌。若此牌为坐骑牌,则你于此弃置事件结算结束后获得此牌。', - ol_dengai:'界邓艾', - ol_dengai_prefix:'界', - oltuntian:'屯田', - olzaoxian:'凿险', - oltuntian_info:'①当你于回合外失去牌后,或于回合内因弃置而失去【杀】后,你可以判定。若判定结果不为♥,则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。', - olzaoxian_info:'觉醒技,准备阶段,若你武将牌上“田”的数量达到3张或更多,则你减1点体力上限,并获得技能〖急袭〗。你于当前回合结束后进行一个额外的回合。', - re_sunxiu:'界孙休', - re_sunxiu_prefix:'界', - re_caoxiu:'界曹休', - re_caoxiu_prefix:'界', - xin_lingtong:'界凌统', - xin_lingtong_prefix:'界', - decadexuanfeng:'旋风', - decadexuanfeng_info:'当你于弃牌阶段弃置过至少两张牌,或当你失去装备区里的牌后,若场上没有处于濒死状态的角色,则你可以弃置至多两名其他角色的共计两张牌。若此时处于你的回合内,你可以对其中一名目标角色造成1点伤害。', - yongjin:'勇进', - yongjin_info:'限定技,出牌阶段,你可以依次移动场上的至多三张不同的装备牌。', - xin_liubiao:'界刘表', - xin_liubiao_prefix:'界', - decadezishou:'自守', - decadezishou_zhiheng:'自守', - decadezishou_info:'摸牌阶段,你可以多摸X张牌(X为存活势力数);然后本回合你对其他角色造成伤害时,防止此伤害。结束阶段,若你本回合没有使用牌指定其他角色为目标,你可以弃置任意张花色不同的手牌,然后摸等量的牌。', - decadezongshi:'宗室', - decadezongshi_info:'锁定技,你的手牌上限+X(X为存活势力数)。你的回合外,若你的手牌数大于等于手牌上限,则当你成为延时类锦囊牌或无颜色的牌的目标后,你令此牌对你无效。', - re_fazheng:'界法正', - re_fazheng_prefix:'界', - reenyuan:'恩怨', - reenyuan1:'恩怨', - reenyuan2:'恩怨', - reenyuan_info:'当你获得一名其他角色的至少两张牌后,你可以令其摸一张牌。当你受到1点伤害后,你可令伤害来源选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。', - rexuanhuo:'眩惑', - rexuanhuo_info:'摸牌阶段结束时,你可以交给一名其他角色两张手牌,然后该角色选择一项:1. 视为对你选择的另一名角色使用任意一种【杀】或【决斗】,2. 交给你所有手牌。', - re_fuhuanghou:'界伏寿', - re_fuhuanghou_prefix:'界', - reqiuyuan:'求援', - reqiuyuan_info:'当你成为【杀】的目标时,你可选择另一名其他角色。除非该角色交给你一张除【杀】以外的基本牌,否则其也成为此【杀】的目标且该角色不能响应此【杀】。', - rezhuikong:'惴恐', - rezhuikong_info:'其他角色的回合开始时,若你已受伤,你可与其拼点:若你赢,本回合该角色只能对自己使用牌;若你没赢,你获得其拼点的牌,然后其视为对你使用一张【杀】。', - re_gongsunyuan:'界公孙渊', - re_gongsunyuan_prefix:'界', - rehuaiyi:'怀异', - rehuaiyi_info:'出牌阶段限一次,你可以展示所有手牌,若这些牌的颜色:全部相同,你摸一张牌,并将此技能于本阶段内改为“限两次”,然后终止此技能的结算流程;不全部相同,则你选择一种颜色并弃置该颜色的所有手牌,然后你可以获得至多X名角色的各一张牌(X为你以此法弃置的手牌数)。若你以此法得到的牌不少于两张,则你失去1点体力。', - re_caozhen:'界曹真', - re_caozhen_prefix:'界', - residi:'司敌', - residi_push:'司敌', - residi2:'司敌', - residi3:'司敌', - residi_info:'结束阶段,你可以将一张非基本牌置于武将牌上,称为“司”。其他角色的出牌阶段开始时,你可以移去一张“司”。若如此做,其本阶段内不能使用或打出与“司”颜色相同的牌。此阶段结束时,若其于此阶段内未使用过:【杀】,你视为对其使用一张【杀】。锦囊牌,你摸两张牌。', - gz_re_xushu:'徐庶', - re_zhangchunhua:'界张春华', - re_zhangchunhua_prefix:'界', - xin_handang:'界韩当', - xin_handang_prefix:'界', - xingongji:'弓骑', - xingongji2:'弓骑', - xingongji_info:'出牌阶段限一次,你可以弃置一张牌,然后你的攻击范围视为无限且使用与此牌花色相同的【杀】无次数限制直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。', - xinjiefan:'解烦', - xinjiefan_info:'限定技,出牌阶段,你可以选择一名角色,令攻击范围内含有该角色的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。然后若游戏轮数为1,则你于此回合结束时恢复此技能。', - gzquanji:'权计', - gzquanji_info:'每回合每项各限一次。当你受到伤害后或造成伤害后,你可以摸一张牌,然后你将一张牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。', - gzpaiyi:'排异', - gzpaiyi_backup:'排异', - gzpaiyi_info:'出牌阶段限一次。你可以移去一张“权”并选择一名角色。令其摸X张牌(X为你的“权”数且至多为7)。然后若其手牌数大于你,则你对其造成1点伤害。', - ol_zhurong:'界祝融', - ol_zhurong_prefix:'界', - changbiao:'长标', - changbiao_info:'出牌阶段限一次,你可以将任意张手牌当做【杀】使用(无距离限制)。若你因此【杀】对目标角色造成过伤害,则你于出牌阶段结束时摸X张牌(X为此【杀】对应的实体牌数量)。', - re_zhoucang:'界周仓', - re_zhoucang_prefix:'界', - rezhongyong:'忠勇', - rezhongyong_info:'当你使用【杀】后,你可以将此【杀】以及目标角色使用的【闪】交给一名其他角色,若其获得的牌中有红色,则其可以对你攻击范围内的角色使用一张【杀】。若其获得的牌中有黑色,其摸一张牌。', - ollihuo:'疠火', - ollihuo2:'疠火', - ollihuo3:'疠火', - ollihuo4:'疠火', - ollihuo_info:'你使用普通的【杀】可以改为火【杀】,若此【杀】造成过伤害,你失去1点体力;你使用火【杀】可以多选择一个目标。你每回合使用的第一张牌如果是【杀】,则此【杀】结算完毕后可置于你的武将牌上。', - xinjiangchi:'将驰', - xinjiangchi_info:'出牌阶段开始时,你可选择:①摸一张牌。②摸两张牌,然后本回合内不能使用或打出【杀】。③弃置一张牌,然后本回合内可以多使用一张【杀】,且使用【杀】无距离限制。', - redingpin:'定品', - redingpin_info:'出牌阶段,你可以弃置一张本回合未使用过/弃置过的类型的牌并选择一名角色。其进行判定,若结果为:黑色,其摸X张牌(X为其体力值且至多为3)且本回合内不能再成为〖定品〗的目标;红桃,你令此次弃置的牌不计入〖定品〗弃置牌合法性的检测;方片,你将武将牌翻面。', - refaen:'法恩', - refaen_info:'一名角色翻面或横置后,你可令其摸一张牌。', - dcfaen:'法恩', - dcfaen_info:'一名角色翻至正面或横置后,你可令其摸一张牌。', - reshizhi:'矢志', - reshizhi_info:'锁定技,若你的体力值为1,则你的【闪】视为【杀】,且当你使用对应的实体牌为一张【闪】的非转化普通杀造成伤害后,你回复1点体力。', - re_guotufengji:'界郭图逢纪', - re_guotufengji_prefix:'界', - rejigong:'急攻', - rejigong2:'急攻', - rejigong_info:'出牌阶段开始时,你可以摸至多三张牌。若如此做,你本回合的手牌上限基数改为X,且弃牌阶段结束时,若X不小于Y,则你回复1点体力。(X为你本回合内造成的伤害值之和,Y为你本回合内因〖急攻〗摸牌而得到的牌的数量总和)', - ol_jiangwei:'界姜维', - ol_jiangwei_prefix:'界', - oltiaoxin:'挑衅', - oltiaoxin_info:'出牌阶段限一次,你可以选择一名攻击范围内包含你的角色。然后除非该角色对你使用一张【杀】且此【杀】对你造成伤害,否则你弃置其一张牌,然后将此技能于此出牌阶段内修改为出牌阶段限两次。', - olzhiji:'志继', - olzhiji_info:'觉醒技,准备阶段或结束阶段,若你没有手牌,你回复1点体力或摸两张牌,然后减1点体力上限,获得〖观星〗。', - decadezhenjun:'镇军', - decadezhenjun_info:'准备阶段或结束阶段,你可以弃置一名角色X张牌(X为其手牌数减体力值且至少为1),若其中没有装备牌,你选择一项:1.你弃一张牌;2.该角色摸等量的牌。', - decadejingce:'精策', - decadejingce_info:'结束阶段,若你本回合使用过的牌数不小于你的体力值,则你可执行一个摸牌阶段或出牌阶段;若这些牌包含的花色数也不小于你的体力值,则你将“或”改为“并”。', - re_guanping:'界关平', - re_guanping_prefix:'界', - relongyin:'龙吟', - relongyin_info:'当一名角色于其出牌阶段内使用【杀】时,你可弃置一张牌令此【杀】不计入出牌阶段使用次数。若此【杀】为红色,则你摸一张牌;若你以此法弃置的牌与此【杀】点数相同,则你重置“竭忠”。', - jiezhong:'竭忠', - jiezhong_info:'限定技,出牌阶段开始时,你可以将手牌补至体力上限(至多摸五张)。', - re_caifuren:'界蔡夫人', - re_caifuren_prefix:'界', - reqieting:'窃听', - reqieting_info:'其他角色的回合结束时,若其本回合内未造成过伤害,则你可将其装备区内的一张牌置于你的装备区内;若其本回合内未对其他角色使用过牌,则你可摸一张牌。', - rexianzhou:'献州', - rexianzhou_info:'限定技。出牌阶段,你可将装备区内的所有牌交给一名其他角色。你回复X点体力,然后对其攻击范围内的至多X名角色各造成1点伤害(X为你以此法给出的牌数)。', - xin_zhonghui:'界钟会', - xin_zhonghui_prefix:'界', - xinquanji:'权计', - xinquanji_info:'①当你受到1点伤害后,或其他角色不因你的赠予或交给而得到你的牌后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”。②你的手牌上限+X(X为“权”的数量)。', - xinzili:'自立', - xinzili_info:'觉醒技。准备阶段,若你的“权”数大于2,则你回复1点体力并摸两张牌,减1点体力上限并获得〖排异〗。', - xinpaiyi:'排异', - xinpaiyi_backup:'排异', - xinpaiyi_info:'出牌阶段每项各限一次,你可移去一张“权”并选择一项:①令一名角色摸X张牌。②对至多X名角色各造成1点伤害。(X为“权”数)', - re_guyong:'界顾雍', - re_guyong_prefix:'界', - reshenxing:'慎行', - reshenxing_info:'出牌阶段,你可以弃置X张牌(X为你本阶段内发动过〖慎行〗的次数且至少为0,至多为2),然后摸一张牌。', - rebingyi:'秉壹', - rebingyi_info:'结束阶段,你可展示所有手牌。若这些牌:颜色均相同,则你可以令至多X名角色各摸一张牌(X为你的手牌数);点数均相同,则你摸一张牌。', - re_jiaxu:'界贾诩', - re_jiaxu_prefix:'界', - rewansha:'完杀', - rewansha_info:'锁定技。①你的回合内,不处于濒死状态的其他角色不能使用【桃】。②当有角色于你的回合内进入濒死状态时,你令其以外的所有其他角色的非锁定技失效直到此濒死状态结算结束。', - reluanwu:'乱武', - reluanwu_info:'限定技,出牌阶段,你可令所有其他角色依次选择一项:①对距离最近(或之一)的角色使用一张【杀】;②失去1点体力。结算完成后,你可视为使用一张【杀】(无距离限制)。', - reweimu:'帷幕', - reweimu_info:'锁定技。①你不能成为黑色锦囊牌的目标。②当你于回合内受到伤害时,你防止此伤害并摸2X张牌(X为伤害值)。', - ol_lusu:'界鲁肃', - ol_lusu_prefix:'界', - olhaoshi:'好施', - olhaoshi_info:'摸牌阶段开始时,你可以多摸两张牌。然后摸牌阶段结束时,若你的手牌数大于5,则你将手牌数的一半(向下取整)交给一名手牌最少其他角色并获得如下效果直到你下回合开始:当你成为【杀】或普通锦囊牌的目标后,其可以交给你一张手牌。', - oldimeng:'缔盟', - oldimeng_info:'出牌阶段限一次,你可令两名满足X≤Y的其他角色交换手牌并获得如下效果:出牌阶段结束时,你弃置X张牌(X为这两名角色手牌数之差的绝对值;Y为你的牌数)。', + xin_yuji: "界于吉", + xin_yuji_prefix: "界", + re_zuoci: "界左慈", + re_zuoci_prefix: "界", + reguhuo: "蛊惑", + reguhuo_info: + "每名角色的回合限一次,你可以扣置一张手牌当作一张基本牌或普通锦囊牌使用或打出。其他角色同时选择是否质疑。然后,你展示此牌。若有质疑的角色:若此牌为假,则此牌作废,且所有质疑者各摸一张牌;为真,则所有质疑角色于此牌结算完成后依次弃置一张牌或失去1点体力,并获得技能〖缠怨〗。", + reguhuo_guess: "蛊惑", + reguhuo_guess_info: "", + rechanyuan: "缠怨", + rechanyuan_info: + "锁定技,你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值不大于1时,你的其他技能失效。", + reguhuo_ally: "信任", + reguhuo_betray: "质疑", + reguhuo_ally_bg: "真", + reguhuo_betray_bg: "假", + rehuashen: "化身", + rehuashen_info: + "游戏开始时,你随机获得三张未加入游戏的武将牌,选一张置于你面前并声明该武将牌的一项技能,你拥有该技能且同时将性别和势力属性变成与该武将相同直到该化身被替换。回合开始时或回合结束时,你可以选择一项:①弃置至多两张未展示的化身牌并重新获得等量化身牌;②更换所展示的化身牌或技能。(你不可声明限定技、觉醒技、隐匿技、使命技、主公技等特殊技能)。", + rexinsheng: "新生", + rexinsheng_info: "当你受到1点伤害后,你可以获得一张新的化身牌。", + re_menghuo: "界孟获", + re_menghuo_prefix: "界", + re_caopi: "界曹丕", + re_caopi_prefix: "界", + oljiuchi: "酒池", + oljiuchi_info: + "你可以将一张黑桃手牌当做【酒】使用。你使用【酒】无次数限制,且当你于回合内使用带有【酒】效果的【杀】造成伤害后,你令你的〖崩坏〗失效直到回合结束。", + repolu: "破虏", + repolu_info: + "当你杀死一名角色/死亡时,你可以令任意名角色摸X+1张牌。(X为你此前发动过〖破虏〗的次数)", + rexingshang: "行殇", + rexingshang_info: "当其他角色死亡后,你可以选择一项:回复1点体力,或获得其所有牌。", + refangzhu: "放逐", + refangzhu_info: + "当你受到伤害后,你可以令一名其他角色选择一项:摸X张牌并将武将牌翻面,或弃置X张牌并失去1点体力。(X为你已损失的体力值)", + rezaiqi: "再起", + rezaiqi_info: + "结束阶段开始时,你可以令至多X名角色选择一项:1.摸一张牌,2.令你回复1点体力(X为本回合进入弃牌堆的红色牌数)。", + ol_caiwenji: "界蔡琰", + ol_caiwenji_prefix: "界", + retuntian: "屯田", + rebeige: "悲歌", + retuntian_info: + "①当你于回合外失去牌后,你可以判定。若判定结果为♥,你获得此判定牌。否则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。", + rebeige_info: + "当有角色受到【杀】造成的伤害后,你可以弃一张牌,并令其进行一次判定,若判定结果为:♥该角色回复X点体力(X为伤害点数);♦︎该角色摸三张牌;♣伤害来源弃两张牌;♠伤害来源将其武将牌翻面。", + rehunzi: "魂姿", + rehunzi_info: + "觉醒技,准备阶段,若你的体力值不大于2,你减1点体力上限,并获得技能〖英姿〗和〖英魂〗。", + rezhijian: "直谏", + rezhijian_info: + "出牌阶段,你可以将手牌中的一张装备牌置于一名其他角色装备区里(不得替换原装备),然后摸一张牌。当你使用装备牌时,你可以摸一张牌。", + refangquan: "放权", + refangquan_info: + "你可跳过你的出牌阶段,若如此做,你本回合的手牌上限为你的体力上限,且回合结束时,你可以弃置一张手牌并令一名其他角色进行一个额外的回合。", + xin_gaoshun: "界高顺", + xin_gaoshun_prefix: "界", + repojun: "破军", + repojun2: "破军", + repojun3: "破军", + repojun_info: + "当你使用【杀】指定目标后,你可以将其的至多X张牌置于其武将牌上(X为其体力值),然后其于当前回合结束时获得这些牌。当你使用【杀】对一名角色造成伤害时,若该角色的手牌数和装备区内的牌数均不大于你,则此伤害+1。", + rexianzhen: "陷阵", + rexianzhen_info: + "出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你本回合内对其使用牌没有次数和距离限制且无视其防具。若你没赢,你本回合内不能使用【杀】。若你以此法失去的拼点牌为【杀】,则你的【杀】不计入本回合的手牌上限。", + rejinjiu: "禁酒", + rejinjiu_info: + "锁定技,你的【酒】均视为【杀】。其他角色不能于你的回合内使用【酒】。当你受到酒【杀】的伤害时,你令此伤害-X(X为影响过此【杀】的伤害值的【酒】的数量)。", + rejinjiu2: "禁酒", + rejinjiu3: "禁酒", + ol_xiahouyuan: "界夏侯渊", + ol_xiahouyuan_prefix: "界", + shebian: "设变", + shebian_info: "当你的武将牌翻面后,你可以移动场上的一张装备牌。", + cangzhuo: "藏拙", + cangzhuo_info: "弃牌阶段开始时,若你本回合内没有使用过锦囊牌,则你的锦囊牌不计入手牌上限。", + re_zhangyi: "界张嶷", + re_zhangyi_prefix: "界", + rewurong: "怃戎", + rewurong_info: + "出牌阶段限一次,你可以令一名其他角色与你同时展示一张手牌:若你展示的是【杀】且该角色展示的不是【闪】,则你对其造成1点伤害;若你展示的不是【杀】且该角色展示的是【闪】,则你获得其一张牌。", + ol_pangtong: "界庞统", + ol_pangtong_prefix: "界", + olniepan: "涅槃", + olniepan_info: + "限定技,当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。然后你选择获得以下技能中的一个:〖八阵〗/〖火计〗/〖看破〗。", + ol_weiyan: "界魏延", + ol_weiyan_prefix: "界", + reqimou: "奇谋", + reqimou_info: + "限定技,出牌阶段,你可以失去任意点体力并摸等量的牌,然后直到回合结束,你计算与其他角色的距离时-X,且你可以多使用X张【杀】(X为你失去的体力值)。", + ol_xiaoqiao: "界小乔", + ol_xiaoqiao_prefix: "界", + rehongyan: "红颜", + rehongyan_info: + "锁定技,你区域内的黑桃牌和黑桃判定牌均视为红桃。当你于回合外正面朝上失去红桃牌后,若你的手牌数小于体力值,你摸一张牌。", + reluoying: "落英", + reluoying_discard: "落英", + reluoying_judge: "落英", + reluoying_info: "当其他角色的梅花牌因弃置或判定而进入弃牌堆后,你可以获得之。", + rejiushi: "酒诗", + rejiushi_info: + "当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面并获得牌堆中的一张随机锦囊。", + rejiushi1: "酒诗", + rejiushi3: "酒诗", + rejiushi_mark: "酒诗·改", + rejiushi_mark_info: + "当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。当你受到伤害后,若你的武将牌背面向上,你可以翻面。当你翻面时,你获得牌堆中的一张随机锦囊。", + chengzhang: "成章", + chengzhang_info: + "觉醒技,准备阶段开始时,若你造成伤害与受到伤害值之和累计7点或以上,则你回复1点体力并摸一张牌,然后改写〖酒诗〗。", + re_wuyi: "界吴懿", + re_wuyi_prefix: "界", + re_zhuran: "界朱然", + re_zhuran_prefix: "界", + re_quancong: "界全琮", + re_quancong_prefix: "界", + re_liaohua: "界廖化", + re_liaohua_prefix: "界", + re_guohuai: "界郭淮", + re_guohuai_prefix: "界", + re_chengpu: "界程普", + re_chengpu_prefix: "界", + rechunlao: "醇醪", + rechunlao2: "醇醪", + rechunlao_info: + "出牌阶段结束时,若你没有“醇”,你可以将至少一张【杀】置于你的武将牌上,称为“醇”。当一名角色处于濒死状态时,你可以移去一张“醇”,视为该角色使用一张【酒】,然后若此“醇”的属性为:火,你回复1点体力、雷,你摸两张牌。", + re_caozhang: "界曹彰", + re_caozhang_prefix: "界", + yujin_yujin: "界于禁", + yujin_yujin_prefix: "界", + rexuanfeng: "旋风", + rexuanfeng_info: + "当你失去装备区内的牌时,或于弃牌阶段弃置了两张或更多的手牌后,你可以依次弃置一至两名其他角色的共计两张牌,或将一名其他角色装备区内的一张牌移动到另一名其他角色的装备区内。", + olpaoxiao: "咆哮", + olpaoxiao2: "咆哮", + olpaoxiao_info: + "①锁定技,你使用【杀】无次数限制。②锁定技,当你使用的【杀】被【闪】抵消时,你获得一枚“咆”(→)当你因【杀】造成伤害时,你弃置所有“咆”并令伤害值+X(X为“咆”数)。回合结束后,你弃置所有“咆”。", + oltishen: "替身", + oltishen_info: "限定技,准备阶段,你可以将体力回复至上限,然后摸X张牌(X为你回复的体力值)。", + ollongdan: "龙胆", + ollongdan_info: + "你可以将一张【杀】当做【闪】、【闪】当做【杀】、【酒】当做【桃】、【桃】当做【酒】使用或打出。", + olyajiao: "涯角", + olyajiao_info: + "当你于回合外因使用或打出而失去手牌后,你可以亮出牌堆顶的一张牌。若这两张牌的类别相同,你可以将展示的牌交给一名角色;若类别不同,你可弃置攻击范围内包含你的角色区域里的一张牌。", + regongji: "弓骑", + regongji_info: + "出牌阶段限一次,你可以弃置一张非基本牌,然后弃置一名其他角色的一张牌。锁定技,当你的装备区内有坐骑牌时,你的攻击范围无限。", + ol_sunjian: "界孙坚", + ol_sunjian_prefix: "界", + wulie: "武烈", + wulie2: "武烈", + wulie_info: + "限定技,结束阶段,你可以失去任意点体力并指定等量的其他角色。这些角色各获得一枚「烈」。有「烈」的角色受到伤害时,其移去一枚「烈」,然后防止此伤害。", + re_sunluban: "界孙鲁班", + re_sunluban_prefix: "界", + re_masu: "界马谡", + re_masu_prefix: "界", + ol_pangde: "界庞德", + ol_pangde_prefix: "界", + rejianchu: "鞬出", + rejianchu_info: + "当你使用【杀】指定一名角色为目标后,你可以弃置其一张牌,若以此法弃置的牌不为基本牌,此【杀】不可被【闪】响应且你本回合使用【杀】的次数上限+1,为基本牌,该角色获得此【杀】。", + re_taishici: "界太史慈", + re_taishici_prefix: "界", + hanzhan: "酣战", + hanzhan_gain: "酣战", + hanzhan_info: + "①当你发起拼点时,或成为拼点的目标时,你可以令对方选择拼点牌的方式改为随机选择一张手牌。②当你拼点结束后,你可以获得本次拼点的拼点牌中点数最大的【杀】。", + re_jianyong: "界简雍", + re_jianyong_prefix: "界", + xin_xusheng: "界徐盛", + xin_xusheng_prefix: "界", + decadepojun: "破军", + decadepojun2: "破军", + decadepojun_info: + "当你使用【杀】指定目标后,你可以将其的至多X张牌置于其武将牌上(X为其体力值)。若这些牌中:有装备牌,你将这些装备牌中的一张置于弃牌堆;有锦囊牌,你摸一张牌。其于回合结束时获得其武将牌上的这些牌。", + re_wangyi: "界王异", + re_wangyi_prefix: "界", + guanzhang: "关兴张苞", + rezishou: "自守", + rezishou2: "自守", + rezishou_info: + "摸牌阶段,你可以多摸X张牌(X为存活势力数)。若如此做,本回合你对其他角色造成伤害时,防止此伤害。", + rezongshi: "宗室", + rezongshi_info: + "锁定技,你的手牌上限+X(X为存活势力数)。准备阶段,若你的手牌数大于体力值,则你本回合内使用【杀】无次数限制。", + ol_dongzhuo: "界董卓", + ol_dongzhuo_prefix: "界", + olbaonue: "暴虐", + olbaonue_info: + "主公技,其他群雄角色造成1点伤害后,你可进行判定,若为♠,你回复1点体力并获得判定牌。", + re_panzhangmazhong: "界潘璋马忠", + re_panzhangmazhong_prefix: "界", + re_hanhaoshihuan: "界韩浩史涣", + re_hanhaoshihuan_prefix: "界", + xinyicong: "义从", + xinyicong_info: + "锁定技,你计算与其他角色的距离时-X,其他角色计算与你的距离时+Y。(X为你的体力值-1,Y为你的已损失体力值-1)", + oltianxiang: "天香", + oltianxiang_info: + "当你受到伤害时,你可以弃置一张红桃牌,防止此伤害并选择一名其他角色,然后你选择一项:1.令其受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5);2.令其失去1点体力,然后获得你弃置的牌。", + olhongyan: "红颜", + olhongyan_info: + "锁定技,你的黑桃牌的花色视为红桃。若你的装备区内有红桃牌,则你的手牌上限基数视为体力上限。", + piaoling: "飘零", + piaoling_info: + "结束阶段,你可以进行判定。若判定结果为红桃,则你选择一项:1.将此牌交给一名角色。若你交给了自己,则你弃置一张牌。2.将此牌置于牌堆顶。", + decadelihuo: "疠火", + decadelihuo2: "疠火", + decadelihuo3: "疠火", + decadelihuo_info: + "当你声明使用普【杀】后,你可以将此【杀】改为火【杀】。当你使用火【杀】选择目标时,可以选择一个额外目标。你使用的火【杀】结算完成后,若此【杀】的目标数大于1且你因此【杀】造成过伤害,则你失去1点体力。", + decadechunlao: "醇醪", + decadechunlao2: "醇醪", + decadechunlao_info: + "你可以对其他角色使用【酒(使用方法②)】。当你需要使用【酒】时,若你的武将牌未横置,则你可以将武将牌横置,然后视为使用【酒】。当你受到或造成伤害后,若伤害值大于1且你的武将牌横置,则你可以重置武将牌。", + rejuece: "绝策", + rejuece_info: "结束阶段,你可以对一名本回合内失去过牌的角色造成1点伤害。", + remieji: "灭计", + remieji_info: + "出牌阶段限一次,你可以将一张黑色锦囊牌置于牌堆顶,然后令一名有牌的其他角色选择一项:交给你一张锦囊牌,或依次弃置两张非锦囊牌。", + re_manchong: "界满宠", + re_manchong_prefix: "界", + rejunxing: "峻刑", + rejunxing_info: + "出牌阶段限一次,你可以弃置任意张手牌并选择一名其他角色。该角色选择一项:1.弃置X张牌并失去1点体力。2.翻面并摸X张牌。(X为你弃置的牌数)", + re_gongsunzan: "界公孙瓒", + re_gongsunzan_prefix: "界", + reqiaomeng: "趫猛", + reqiaomeng_info: + "当你使用【杀】对一名角色造成伤害后,你可以弃置该角色区域内的一张牌。若此牌为坐骑牌,则你于此弃置事件结算结束后获得此牌。", + ol_dengai: "界邓艾", + ol_dengai_prefix: "界", + oltuntian: "屯田", + olzaoxian: "凿险", + oltuntian_info: + "①当你于回合外失去牌后,或于回合内因弃置而失去【杀】后,你可以判定。若判定结果不为♥,则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。", + olzaoxian_info: + "觉醒技,准备阶段,若你武将牌上“田”的数量达到3张或更多,则你减1点体力上限,并获得技能〖急袭〗。你于当前回合结束后进行一个额外的回合。", + re_sunxiu: "界孙休", + re_sunxiu_prefix: "界", + re_caoxiu: "界曹休", + re_caoxiu_prefix: "界", + xin_lingtong: "界凌统", + xin_lingtong_prefix: "界", + decadexuanfeng: "旋风", + decadexuanfeng_info: + "当你于弃牌阶段弃置过至少两张牌,或当你失去装备区里的牌后,若场上没有处于濒死状态的角色,则你可以弃置至多两名其他角色的共计两张牌。若此时处于你的回合内,你可以对其中一名目标角色造成1点伤害。", + yongjin: "勇进", + yongjin_info: "限定技,出牌阶段,你可以依次移动场上的至多三张不同的装备牌。", + xin_liubiao: "界刘表", + xin_liubiao_prefix: "界", + decadezishou: "自守", + decadezishou_zhiheng: "自守", + decadezishou_info: + "摸牌阶段,你可以多摸X张牌(X为存活势力数);然后本回合你对其他角色造成伤害时,防止此伤害。结束阶段,若你本回合没有使用牌指定其他角色为目标,你可以弃置任意张花色不同的手牌,然后摸等量的牌。", + decadezongshi: "宗室", + decadezongshi_info: + "锁定技,你的手牌上限+X(X为存活势力数)。你的回合外,若你的手牌数大于等于手牌上限,则当你成为延时类锦囊牌或无颜色的牌的目标后,你令此牌对你无效。", + re_fazheng: "界法正", + re_fazheng_prefix: "界", + reenyuan: "恩怨", + reenyuan1: "恩怨", + reenyuan2: "恩怨", + reenyuan_info: + "当你获得一名其他角色的至少两张牌后,你可以令其摸一张牌。当你受到1点伤害后,你可令伤害来源选择一项:①失去1点体力。②交给你一张手牌。若此牌不为♥,则你摸一张牌。", + rexuanhuo: "眩惑", + rexuanhuo_info: + "摸牌阶段结束时,你可以交给一名其他角色两张手牌,然后该角色选择一项:1. 视为对你选择的另一名角色使用任意一种【杀】或【决斗】,2. 交给你所有手牌。", + re_fuhuanghou: "界伏寿", + re_fuhuanghou_prefix: "界", + reqiuyuan: "求援", + reqiuyuan_info: + "当你成为【杀】的目标时,你可选择另一名其他角色。除非该角色交给你一张除【杀】以外的基本牌,否则其也成为此【杀】的目标且该角色不能响应此【杀】。", + rezhuikong: "惴恐", + rezhuikong_info: + "其他角色的回合开始时,若你已受伤,你可与其拼点:若你赢,本回合该角色只能对自己使用牌;若你没赢,你获得其拼点的牌,然后其视为对你使用一张【杀】。", + re_gongsunyuan: "界公孙渊", + re_gongsunyuan_prefix: "界", + rehuaiyi: "怀异", + rehuaiyi_info: + "出牌阶段限一次,你可以展示所有手牌,若这些牌的颜色:全部相同,你摸一张牌,并将此技能于本阶段内改为“限两次”,然后终止此技能的结算流程;不全部相同,则你选择一种颜色并弃置该颜色的所有手牌,然后你可以获得至多X名角色的各一张牌(X为你以此法弃置的手牌数)。若你以此法得到的牌不少于两张,则你失去1点体力。", + re_caozhen: "界曹真", + re_caozhen_prefix: "界", + residi: "司敌", + residi_push: "司敌", + residi2: "司敌", + residi3: "司敌", + residi_info: + "结束阶段,你可以将一张非基本牌置于武将牌上,称为“司”。其他角色的出牌阶段开始时,你可以移去一张“司”。若如此做,其本阶段内不能使用或打出与“司”颜色相同的牌。此阶段结束时,若其于此阶段内未使用过:【杀】,你视为对其使用一张【杀】。锦囊牌,你摸两张牌。", + gz_re_xushu: "徐庶", + re_zhangchunhua: "界张春华", + re_zhangchunhua_prefix: "界", + xin_handang: "界韩当", + xin_handang_prefix: "界", + xingongji: "弓骑", + xingongji2: "弓骑", + xingongji_info: + "出牌阶段限一次,你可以弃置一张牌,然后你的攻击范围视为无限且使用与此牌花色相同的【杀】无次数限制直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。", + xinjiefan: "解烦", + xinjiefan_info: + "限定技,出牌阶段,你可以选择一名角色,令攻击范围内含有该角色的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。然后若游戏轮数为1,则你于此回合结束时恢复此技能。", + gzquanji: "权计", + gzquanji_info: + "每回合每项各限一次。当你受到伤害后或造成伤害后,你可以摸一张牌,然后你将一张牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。", + gzpaiyi: "排异", + gzpaiyi_backup: "排异", + gzpaiyi_info: + "出牌阶段限一次。你可以移去一张“权”并选择一名角色。令其摸X张牌(X为你的“权”数且至多为7)。然后若其手牌数大于你,则你对其造成1点伤害。", + ol_zhurong: "界祝融", + ol_zhurong_prefix: "界", + changbiao: "长标", + changbiao_info: + "出牌阶段限一次,你可以将任意张手牌当做【杀】使用(无距离限制)。若你因此【杀】对目标角色造成过伤害,则你于出牌阶段结束时摸X张牌(X为此【杀】对应的实体牌数量)。", + re_zhoucang: "界周仓", + re_zhoucang_prefix: "界", + rezhongyong: "忠勇", + rezhongyong_info: + "当你使用【杀】后,你可以将此【杀】以及目标角色使用的【闪】交给一名其他角色,若其获得的牌中有红色,则其可以对你攻击范围内的角色使用一张【杀】。若其获得的牌中有黑色,其摸一张牌。", + ollihuo: "疠火", + ollihuo2: "疠火", + ollihuo3: "疠火", + ollihuo4: "疠火", + ollihuo_info: + "你使用普通的【杀】可以改为火【杀】,若此【杀】造成过伤害,你失去1点体力;你使用火【杀】可以多选择一个目标。你每回合使用的第一张牌如果是【杀】,则此【杀】结算完毕后可置于你的武将牌上。", + xinjiangchi: "将驰", + xinjiangchi_info: + "出牌阶段开始时,你可选择:①摸一张牌。②摸两张牌,然后本回合内不能使用或打出【杀】。③弃置一张牌,然后本回合内可以多使用一张【杀】,且使用【杀】无距离限制。", + redingpin: "定品", + redingpin_info: + "出牌阶段,你可以弃置一张本回合未使用过/弃置过的类型的牌并选择一名角色。其进行判定,若结果为:黑色,其摸X张牌(X为其体力值且至多为3)且本回合内不能再成为〖定品〗的目标;红桃,你令此次弃置的牌不计入〖定品〗弃置牌合法性的检测;方片,你将武将牌翻面。", + refaen: "法恩", + refaen_info: "一名角色翻面或横置后,你可令其摸一张牌。", + dcfaen: "法恩", + dcfaen_info: "一名角色翻至正面或横置后,你可令其摸一张牌。", + reshizhi: "矢志", + reshizhi_info: + "锁定技,若你的体力值为1,则你的【闪】视为【杀】,且当你使用对应的实体牌为一张【闪】的非转化普通杀造成伤害后,你回复1点体力。", + re_guotufengji: "界郭图逢纪", + re_guotufengji_prefix: "界", + rejigong: "急攻", + rejigong2: "急攻", + rejigong_info: + "出牌阶段开始时,你可以摸至多三张牌。若如此做,你本回合的手牌上限基数改为X,且弃牌阶段结束时,若X不小于Y,则你回复1点体力。(X为你本回合内造成的伤害值之和,Y为你本回合内因〖急攻〗摸牌而得到的牌的数量总和)", + ol_jiangwei: "界姜维", + ol_jiangwei_prefix: "界", + oltiaoxin: "挑衅", + oltiaoxin_info: + "出牌阶段限一次,你可以选择一名攻击范围内包含你的角色。然后除非该角色对你使用一张【杀】且此【杀】对你造成伤害,否则你弃置其一张牌,然后将此技能于此出牌阶段内修改为出牌阶段限两次。", + olzhiji: "志继", + olzhiji_info: + "觉醒技,准备阶段或结束阶段,若你没有手牌,你回复1点体力或摸两张牌,然后减1点体力上限,获得〖观星〗。", + decadezhenjun: "镇军", + decadezhenjun_info: + "准备阶段或结束阶段,你可以弃置一名角色X张牌(X为其手牌数减体力值且至少为1),若其中没有装备牌,你选择一项:1.你弃一张牌;2.该角色摸等量的牌。", + decadejingce: "精策", + decadejingce_info: + "结束阶段,若你本回合使用过的牌数不小于你的体力值,则你可执行一个摸牌阶段或出牌阶段;若这些牌包含的花色数也不小于你的体力值,则你将“或”改为“并”。", + re_guanping: "界关平", + re_guanping_prefix: "界", + relongyin: "龙吟", + relongyin_info: + "当一名角色于其出牌阶段内使用【杀】时,你可弃置一张牌令此【杀】不计入出牌阶段使用次数。若此【杀】为红色,则你摸一张牌;若你以此法弃置的牌与此【杀】点数相同,则你重置“竭忠”。", + jiezhong: "竭忠", + jiezhong_info: "限定技,出牌阶段开始时,你可以将手牌补至体力上限(至多摸五张)。", + re_caifuren: "界蔡夫人", + re_caifuren_prefix: "界", + reqieting: "窃听", + reqieting_info: + "其他角色的回合结束时,若其本回合内未造成过伤害,则你可将其装备区内的一张牌置于你的装备区内;若其本回合内未对其他角色使用过牌,则你可摸一张牌。", + rexianzhou: "献州", + rexianzhou_info: + "限定技。出牌阶段,你可将装备区内的所有牌交给一名其他角色。你回复X点体力,然后对其攻击范围内的至多X名角色各造成1点伤害(X为你以此法给出的牌数)。", + xin_zhonghui: "界钟会", + xin_zhonghui_prefix: "界", + xinquanji: "权计", + xinquanji_info: + "①当你受到1点伤害后,或其他角色不因你的赠予或交给而得到你的牌后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”。②你的手牌上限+X(X为“权”的数量)。", + xinzili: "自立", + xinzili_info: + "觉醒技。准备阶段,若你的“权”数大于2,则你回复1点体力并摸两张牌,减1点体力上限并获得〖排异〗。", + xinpaiyi: "排异", + xinpaiyi_backup: "排异", + xinpaiyi_info: + "出牌阶段每项各限一次,你可移去一张“权”并选择一项:①令一名角色摸X张牌。②对至多X名角色各造成1点伤害。(X为“权”数)", + re_guyong: "界顾雍", + re_guyong_prefix: "界", + reshenxing: "慎行", + reshenxing_info: + "出牌阶段,你可以弃置X张牌(X为你本阶段内发动过〖慎行〗的次数且至少为0,至多为2),然后摸一张牌。", + rebingyi: "秉壹", + rebingyi_info: + "结束阶段,你可展示所有手牌。若这些牌:颜色均相同,则你可以令至多X名角色各摸一张牌(X为你的手牌数);点数均相同,则你摸一张牌。", + re_jiaxu: "界贾诩", + re_jiaxu_prefix: "界", + rewansha: "完杀", + rewansha_info: + "锁定技。①你的回合内,不处于濒死状态的其他角色不能使用【桃】。②当有角色于你的回合内进入濒死状态时,你令其以外的所有其他角色的非锁定技失效直到此濒死状态结算结束。", + reluanwu: "乱武", + reluanwu_info: + "限定技,出牌阶段,你可令所有其他角色依次选择一项:①对距离最近(或之一)的角色使用一张【杀】;②失去1点体力。结算完成后,你可视为使用一张【杀】(无距离限制)。", + reweimu: "帷幕", + reweimu_info: + "锁定技。①你不能成为黑色锦囊牌的目标。②当你于回合内受到伤害时,你防止此伤害并摸2X张牌(X为伤害值)。", + ol_lusu: "界鲁肃", + ol_lusu_prefix: "界", + olhaoshi: "好施", + olhaoshi_info: + "摸牌阶段开始时,你可以多摸两张牌。然后摸牌阶段结束时,若你的手牌数大于5,则你将手牌数的一半(向下取整)交给一名手牌最少其他角色并获得如下效果直到你下回合开始:当你成为【杀】或普通锦囊牌的目标后,其可以交给你一张手牌。", + oldimeng: "缔盟", + oldimeng_info: + "出牌阶段限一次,你可令两名满足X≤Y的其他角色交换手牌并获得如下效果:出牌阶段结束时,你弃置X张牌(X为这两名角色手牌数之差的绝对值;Y为你的牌数)。", - rejijiang:'激将', - rejijiang1:'激将', - rejijiang2:'激将', - rejijiang_info:'主公技。①当你需要使用或打出【杀】时,你可以令其他蜀势力角色依次选择是否打出一张【杀】。若有角色响应,则你视为使用或打出了此【杀】。②每回合限一次。当有蜀势力角色于回合外使用或打出【杀】时,其可以令你摸一张牌。', - xin_yufan:'界虞翻', - xin_yufan_prefix:'界', - xinzongxuan:'纵玄', - xinzongxuan_info:'当你的牌因弃置而进入弃牌堆后,你可将其中的任意张牌置于牌堆顶。若剩余的牌中有锦囊牌,则你可以令一名其他角色获得其中的一张。', - xinzhiyan:'直言', - xinzhiyan_info:'结束阶段开始时,你可令一名角色摸一张牌(正面朝上移动)。若此牌为基本牌,则你摸一张牌。若此牌为装备牌,则其回复1点体力并使用此装备牌。', - re_xiahoushi:'界夏侯氏', - re_xiahoushi_prefix:'界', - reqiaoshi:'樵拾', - reqiaoshi_info:'其他角色的结束阶段开始时,若你的手牌数与其相等,则你可以与其各摸一张牌。若这两张牌花色相同,则你可以重复此步骤。', - reyanyu:'燕语', - reyanyu2:'燕语', - reyanyu_info:'①出牌阶段,你可以重铸【杀】。②出牌阶段结束时,你可以令一名其他男性角色摸X张牌(X为你本阶段内发动过〖燕语①〗的次数且至多为3)。', - rehujia:'护驾', - rehujia_info:'主公技。①当你需要使用或打出一张【闪】时,你可以令其他魏势力角色选择是否打出一张【闪】。若有角色响应,则你视为使用或打出了一张【闪】。②每回合限一次。当有魏势力角色于回合外使用或打出【闪】时,其可以令你摸一张牌。', - ol_xuhuang:'界徐晃', - ol_xuhuang_prefix:'界', - olduanliang:'断粮', - olduanliang_info:'你可以将一张黑色非锦囊牌当做【兵粮寸断】使用。若你于当前回合内未造成过伤害,则你使用【兵粮寸断】无距离限制。', - oljiezi:'截辎', - oljiezi_info:'①当有角色跳过摸牌阶段后,你可选择一名角色。若该角色:手牌数为全场最少且没有“辎”,则其获得一枚“辎”。否则其摸一张牌。②一名角色的摸牌阶段结束时,若其有“辎”,则你移去其“辎”,然后令其获得一个额外的摸牌阶段。', - re_madai:'界马岱', - re_madai_prefix:'界', - reqianxi:'潜袭', - reqianxi_info:'准备阶段开始时,你可摸一张牌,然后弃置一张牌并选择一名距离为1的其他角色。该角色于本回合内:{不能使用或打出与此牌颜色相同的牌,且其装备区内与此牌颜色相同的防具牌无效,且当其回复体力时,你摸两张牌。}', - re_guohuanghou:'界郭皇后', - re_guohuanghou_prefix:'界', - rejiaozhao:'矫诏', - rejiaozhao_info:'出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。', - rejiaozhao_lv2:'矫诏·升级 Lv.1', - rejiaozhao_lv2_info:'出牌阶段限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用(你不是此牌的合法目标)。', - rejiaozhao_lv3:'矫诏·升级 Lv.2', - rejiaozhao_lv3_info:'出牌阶段每种类型各限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用。', - redanxin:'殚心', - redanxin_info:'当你受到伤害后,你可以摸一张牌并升级〖矫诏〗。', - xin_wuguotai:'界吴国太', - xin_wuguotai_prefix:'界', - xinganlu:'甘露', - xinganlu_info:'出牌阶段限一次。你可以令两名角色交换装备区内的牌,然后若这两名角色装备区内牌数差的绝对值大于你已损失的体力值,则你弃置两张手牌。', - xinbuyi:'补益', - xinbuyi_info:'一名角色进入濒死状态时,你可展示其一张手牌。若此牌不为基本牌,则其弃置此牌并回复1点体力。若其以此法弃置的牌移动前为其的唯一一张手牌,则其摸一张牌。', - decadexianzhen:'陷阵', - decadexianzhen2:'陷阵', - decadexianzhen_info:'每回合限一次。出牌阶段,你可以和一名其他角色拼点。若你赢:本回合你无视该角色的防具,且对其使用牌没有次数和距离限制,且本回合对其使用牌造成伤害时,此伤害+1(每种牌名每回合限一次);若你没赢:你本回合内不能使用【杀】,且【杀】不计入手牌上限。', - decadejinjiu:'禁酒', - decadejinjiu_info:'锁定技。你的【酒】的牌名均视为【杀】且点数视为K;你的回合内,其他角色不能使用【酒】。', - dc_xushu:'新杀徐庶', - dc_xushu_prefix:'新杀', - rezhuhai:'诛害', - rezhuhai_info:'其他角色的回合结束时,若其本回合内造成过伤害,则你可以选择一项:⒈将一张手牌当做【杀】对其使用。⒉视为对其使用一张【过河拆桥】。', - xsqianxin:'潜心', - xsqianxin_info:'觉醒技。当你造成伤害后,若你已受伤,则你减1点体力上限并获得〖荐言〗。', - rejianyan:'荐言', - rejianyan_info:'出牌阶段每项各限一次。你可选择一种颜色或一种牌的类别,然后系统从牌堆中检索出一张满足该条件的牌并展示之。然后你将此牌交给一名男性角色或Key势力角色。', - re_zhanghe:'界张郃', - re_zhanghe_prefix:'界', - reqiaobian:'巧变', - reqiaobian_info:'①游戏开始时,你获得两枚“变”。②判定阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段。③摸牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段,然后可以获得至多两名其他角色的各一张手牌。④出牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段,然后你可以移动场上的一张牌。⑤弃牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段。⑥结束阶段,若你的〖巧变⑥〗记录中不包含你的手牌数,则你获得一枚“变”并记录你的手牌数。', - olbeige:'悲歌', - olbeige_info:'当有角色受到渠道为【杀】的伤害后,若你有牌,你可令其进行判定。然后你可弃置一张牌,根据判定结果执行以下的一个选项:♥,其回复1点体力;♦,其摸两张牌;♣,伤害来源弃置两张牌️;♠,伤害来源将武将牌翻面。若你弃置的牌与判定结果:点数相同,则你获得你弃置的牌;花色相同,则你获得判定牌。', - dc_bulianshi:'界步练师', - dc_bulianshi_prefix:'界', - dcanxu:'安恤', - dcanxu_info:'出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌少的角色获得手牌多的角色的一张手牌并展示之。然后若此牌不为黑桃,则你摸一张牌;若这两名角色手牌数相等,则你回复1点体力。', - dczhuiyi:'追忆', - dczhuiyi_info:'当你死亡时,你可以令一名不为击杀者的其他角色摸X张牌(X为存活角色数),然后其回复1点体力。', - re_jushou:'界沮授', - re_jushou_prefix:'界', - dcshibei:'矢北', - dcshibei_info:'锁定技,当你于一回合内第一次受到伤害后,你回复1点体力;当你于一回合内第二次受到伤害后,你失去1点体力。', - dcjianying:'渐营', - dcjianying_info:'当你使用与你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。', - re_duji:'界杜畿', - re_duji_prefix:'界', - reandong:'安东', - reandong_info:'当你受到其他角色造成的伤害时,你可以令伤害来源选择一项:⒈防止此伤害。然后其♥牌不计入本回合的手牌上限;⒉你观看其手牌并获得其中的所有♥牌,若其没有手牌,则你下次发动〖安东〗时改为自行选择。', - reyingshi:'应势', - reyingshi_info:'出牌阶段开始时,你可以展示一张手牌,选择一名角色A和一名其他角色B。A可以对B使用一张【杀】,然后获得你展示的牌。若A因此【杀】造成过伤害,则A获得牌堆中与展示牌花色点数相同的其他牌。', - dcqiaomeng:'趫猛', - dcqiaomeng_info:'当你使用黑色牌指定第一个目标后,你可以弃置目标角色中一名其他角色的一张牌。若你以此法弃置的牌为:装备牌,你获得此牌;锦囊牌,你令此牌不可被响应。', - dc_gongsunzan:'新杀公孙瓒', - dc_gongsunzan_prefix:'新杀', - re_liuchen:'界刘谌', - re_liuchen_prefix:'界', - rezhanjue:'战绝', - rezhanjue_effect:'战绝', - rezhanjue_info:'出牌阶段,若你本阶段内因〖战绝〗得到过的牌数小于3,则你可以将所有不具有“勤王”标记的手牌当做【决斗】使用。此【决斗】使用结算结束后,你摸一张牌。然后所有因此【决斗】受到过伤害的角色也各摸一张牌。', - reqinwang:'勤王', - reqinwang_info:'主公技。出牌阶段限一次,你可以令所有其他蜀势力角色依次选择是否交给你一张【杀】,然后你可以令选择是的角色摸一张牌。', - shizhan:'势斩', - shizhan_info:'出牌阶段限两次,你可以选择一名其他角色。该角色视为对你使用一张【决斗】。', - ol_xunyu:'界荀彧', - ol_xunyu_prefix:'界', - oljieming:'节命', - oljieming_info:'当你受到1点伤害后或死亡时,你可令一名角色摸X张牌。然后若其手牌数大于X,则其将手牌弃置至X张(X为其体力上限且至多为5)。', - re_liufeng:'界刘封', - re_liufeng_prefix:'界', - rexiansi:'陷嗣', - rexiansi2:'陷嗣', - rexiansi_info:'①准备阶段开始时,你可以将一至两名角色的各一张牌置于你的武将牌上,称为“逆”。②当一名角色需要对你使用【杀】时,其可以移去两张“逆”,然后视为对你使用一张【杀】。③若你的“逆”数大于体力值,则你可以移去一张“逆”并视为使用一张【杀】。', - re_sp_taishici:'界SP太史慈', - re_sp_taishici_prefix:'界SP', - rejixu:"击虚", - rejixu_info:"出牌阶段限一次。若你有手牌,则你可以选择至多X名角色,令这些角色猜测你的手牌区中是否有【杀】。若你:有【杀】,则你本阶段使用【杀】的次数上限+Y,且当你于本阶段内使用【杀】指定目标后,你可以令这Y名角色也成为此【杀】的目标;没有【杀】,则你弃置这Y名角色的各一张牌。然后你摸Y张牌(X为你的体力值,Y为这些角色中猜错的角色数)。", - ol_dianwei:'界典韦', - ol_dianwei_prefix:'界', - olqiangxi:'强袭', - olqiangxi_info:'出牌阶段限两次。你可以弃置一张武器牌或受到1点无来源伤害,然后对一名本回合内未成为过〖强袭〗目标的其他角色造成1点伤害。', - olningwu:'狞恶', - olningwu_info:'锁定技。当一名角色A于一回合内第二次受到伤害后,若A或伤害来源为你,则你摸一张牌,然后弃置其装备区或判定区内的一张牌。', - re_zhuhuan:'界朱桓', - re_zhuhuan_prefix:'界', - refenli:'奋励', - refenli_info:'若你的手牌数为全场最多,你可以跳过判定阶段和摸牌阶段;若你的体力值为全场最多,你可以跳过出牌阶段;若你的装备区里有牌且数量为全场最多,你可以跳过弃牌阶段。', + rejijiang: "激将", + rejijiang1: "激将", + rejijiang2: "激将", + rejijiang_info: + "主公技。①当你需要使用或打出【杀】时,你可以令其他蜀势力角色依次选择是否打出一张【杀】。若有角色响应,则你视为使用或打出了此【杀】。②每回合限一次。当有蜀势力角色于回合外使用或打出【杀】时,其可以令你摸一张牌。", + xin_yufan: "界虞翻", + xin_yufan_prefix: "界", + xinzongxuan: "纵玄", + xinzongxuan_info: + "当你的牌因弃置而进入弃牌堆后,你可将其中的任意张牌置于牌堆顶。若剩余的牌中有锦囊牌,则你可以令一名其他角色获得其中的一张。", + xinzhiyan: "直言", + xinzhiyan_info: + "结束阶段开始时,你可令一名角色摸一张牌(正面朝上移动)。若此牌为基本牌,则你摸一张牌。若此牌为装备牌,则其回复1点体力并使用此装备牌。", + re_xiahoushi: "界夏侯氏", + re_xiahoushi_prefix: "界", + reqiaoshi: "樵拾", + reqiaoshi_info: + "其他角色的结束阶段开始时,若你的手牌数与其相等,则你可以与其各摸一张牌。若这两张牌花色相同,则你可以重复此步骤。", + reyanyu: "燕语", + reyanyu2: "燕语", + reyanyu_info: + "①出牌阶段,你可以重铸【杀】。②出牌阶段结束时,你可以令一名其他男性角色摸X张牌(X为你本阶段内发动过〖燕语①〗的次数且至多为3)。", + rehujia: "护驾", + rehujia_info: + "主公技。①当你需要使用或打出一张【闪】时,你可以令其他魏势力角色选择是否打出一张【闪】。若有角色响应,则你视为使用或打出了一张【闪】。②每回合限一次。当有魏势力角色于回合外使用或打出【闪】时,其可以令你摸一张牌。", + ol_xuhuang: "界徐晃", + ol_xuhuang_prefix: "界", + olduanliang: "断粮", + olduanliang_info: + "你可以将一张黑色非锦囊牌当做【兵粮寸断】使用。若你于当前回合内未造成过伤害,则你使用【兵粮寸断】无距离限制。", + oljiezi: "截辎", + oljiezi_info: + "①当有角色跳过摸牌阶段后,你可选择一名角色。若该角色:手牌数为全场最少且没有“辎”,则其获得一枚“辎”。否则其摸一张牌。②一名角色的摸牌阶段结束时,若其有“辎”,则你移去其“辎”,然后令其获得一个额外的摸牌阶段。", + re_madai: "界马岱", + re_madai_prefix: "界", + reqianxi: "潜袭", + reqianxi_info: + "准备阶段开始时,你可摸一张牌,然后弃置一张牌并选择一名距离为1的其他角色。该角色于本回合内:{不能使用或打出与此牌颜色相同的牌,且其装备区内与此牌颜色相同的防具牌无效,且当其回复体力时,你摸两张牌。}", + re_guohuanghou: "界郭皇后", + re_guohuanghou_prefix: "界", + rejiaozhao: "矫诏", + rejiaozhao_info: + "出牌阶段限一次。你可以展示一张手牌,并令一名距离你最近的角色选择一种基本牌或普通锦囊牌的牌名。你可将此牌当做其声明的牌使用直到此阶段结束(你不是此牌的合法目标)。", + rejiaozhao_lv2: "矫诏·升级 Lv.1", + rejiaozhao_lv2_info: + "出牌阶段限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用(你不是此牌的合法目标)。", + rejiaozhao_lv3: "矫诏·升级 Lv.2", + rejiaozhao_lv3_info: "出牌阶段每种类型各限一次。你可以将一张手牌当做一张基本牌或普通锦囊牌使用。", + redanxin: "殚心", + redanxin_info: "当你受到伤害后,你可以摸一张牌并升级〖矫诏〗。", + xin_wuguotai: "界吴国太", + xin_wuguotai_prefix: "界", + xinganlu: "甘露", + xinganlu_info: + "出牌阶段限一次。你可以令两名角色交换装备区内的牌,然后若这两名角色装备区内牌数差的绝对值大于你已损失的体力值,则你弃置两张手牌。", + xinbuyi: "补益", + xinbuyi_info: + "一名角色进入濒死状态时,你可展示其一张手牌。若此牌不为基本牌,则其弃置此牌并回复1点体力。若其以此法弃置的牌移动前为其的唯一一张手牌,则其摸一张牌。", + decadexianzhen: "陷阵", + decadexianzhen2: "陷阵", + decadexianzhen_info: + "每回合限一次。出牌阶段,你可以和一名其他角色拼点。若你赢:本回合你无视该角色的防具,且对其使用牌没有次数和距离限制,且本回合对其使用牌造成伤害时,此伤害+1(每种牌名每回合限一次);若你没赢:你本回合内不能使用【杀】,且【杀】不计入手牌上限。", + decadejinjiu: "禁酒", + decadejinjiu_info: + "锁定技。你的【酒】的牌名均视为【杀】且点数视为K;你的回合内,其他角色不能使用【酒】。", + dc_xushu: "新杀徐庶", + dc_xushu_prefix: "新杀", + rezhuhai: "诛害", + rezhuhai_info: + "其他角色的回合结束时,若其本回合内造成过伤害,则你可以选择一项:⒈将一张手牌当做【杀】对其使用。⒉视为对其使用一张【过河拆桥】。", + xsqianxin: "潜心", + xsqianxin_info: "觉醒技。当你造成伤害后,若你已受伤,则你减1点体力上限并获得〖荐言〗。", + rejianyan: "荐言", + rejianyan_info: + "出牌阶段每项各限一次。你可选择一种颜色或一种牌的类别,然后系统从牌堆中检索出一张满足该条件的牌并展示之。然后你将此牌交给一名男性角色或Key势力角色。", + re_zhanghe: "界张郃", + re_zhanghe_prefix: "界", + reqiaobian: "巧变", + reqiaobian_info: + "①游戏开始时,你获得两枚“变”。②判定阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段。③摸牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段,然后可以获得至多两名其他角色的各一张手牌。④出牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段,然后你可以移动场上的一张牌。⑤弃牌阶段开始时,你可弃置一张牌或一枚“变”并跳过此阶段。⑥结束阶段,若你的〖巧变⑥〗记录中不包含你的手牌数,则你获得一枚“变”并记录你的手牌数。", + olbeige: "悲歌", + olbeige_info: + "当有角色受到渠道为【杀】的伤害后,若你有牌,你可令其进行判定。然后你可弃置一张牌,根据判定结果执行以下的一个选项:♥,其回复1点体力;♦,其摸两张牌;♣,伤害来源弃置两张牌️;♠,伤害来源将武将牌翻面。若你弃置的牌与判定结果:点数相同,则你获得你弃置的牌;花色相同,则你获得判定牌。", + dc_bulianshi: "界步练师", + dc_bulianshi_prefix: "界", + dcanxu: "安恤", + dcanxu_info: + "出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌少的角色获得手牌多的角色的一张手牌并展示之。然后若此牌不为黑桃,则你摸一张牌;若这两名角色手牌数相等,则你回复1点体力。", + dczhuiyi: "追忆", + dczhuiyi_info: + "当你死亡时,你可以令一名不为击杀者的其他角色摸X张牌(X为存活角色数),然后其回复1点体力。", + re_jushou: "界沮授", + re_jushou_prefix: "界", + dcshibei: "矢北", + dcshibei_info: + "锁定技,当你于一回合内第一次受到伤害后,你回复1点体力;当你于一回合内第二次受到伤害后,你失去1点体力。", + dcjianying: "渐营", + dcjianying_info: "当你使用与你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。", + re_duji: "界杜畿", + re_duji_prefix: "界", + reandong: "安东", + reandong_info: + "当你受到其他角色造成的伤害时,你可以令伤害来源选择一项:⒈防止此伤害。然后其♥牌不计入本回合的手牌上限;⒉你观看其手牌并获得其中的所有♥牌,若其没有手牌,则你下次发动〖安东〗时改为自行选择。", + reyingshi: "应势", + reyingshi_info: + "出牌阶段开始时,你可以展示一张手牌,选择一名角色A和一名其他角色B。A可以对B使用一张【杀】,然后获得你展示的牌。若A因此【杀】造成过伤害,则A获得牌堆中与展示牌花色点数相同的其他牌。", + dcqiaomeng: "趫猛", + dcqiaomeng_info: + "当你使用黑色牌指定第一个目标后,你可以弃置目标角色中一名其他角色的一张牌。若你以此法弃置的牌为:装备牌,你获得此牌;锦囊牌,你令此牌不可被响应。", + dc_gongsunzan: "新杀公孙瓒", + dc_gongsunzan_prefix: "新杀", + re_liuchen: "界刘谌", + re_liuchen_prefix: "界", + rezhanjue: "战绝", + rezhanjue_effect: "战绝", + rezhanjue_info: + "出牌阶段,若你本阶段内因〖战绝〗得到过的牌数小于3,则你可以将所有不具有“勤王”标记的手牌当做【决斗】使用。此【决斗】使用结算结束后,你摸一张牌。然后所有因此【决斗】受到过伤害的角色也各摸一张牌。", + reqinwang: "勤王", + reqinwang_info: + "主公技。出牌阶段限一次,你可以令所有其他蜀势力角色依次选择是否交给你一张【杀】,然后你可以令选择是的角色摸一张牌。", + shizhan: "势斩", + shizhan_info: "出牌阶段限两次,你可以选择一名其他角色。该角色视为对你使用一张【决斗】。", + ol_xunyu: "界荀彧", + ol_xunyu_prefix: "界", + oljieming: "节命", + oljieming_info: + "当你受到1点伤害后或死亡时,你可令一名角色摸X张牌。然后若其手牌数大于X,则其将手牌弃置至X张(X为其体力上限且至多为5)。", + re_liufeng: "界刘封", + re_liufeng_prefix: "界", + rexiansi: "陷嗣", + rexiansi2: "陷嗣", + rexiansi_info: + "①准备阶段开始时,你可以将一至两名角色的各一张牌置于你的武将牌上,称为“逆”。②当一名角色需要对你使用【杀】时,其可以移去两张“逆”,然后视为对你使用一张【杀】。③若你的“逆”数大于体力值,则你可以移去一张“逆”并视为使用一张【杀】。", + re_sp_taishici: "界SP太史慈", + re_sp_taishici_prefix: "界SP", + rejixu: "击虚", + rejixu_info: + "出牌阶段限一次。若你有手牌,则你可以选择至多X名角色,令这些角色猜测你的手牌区中是否有【杀】。若你:有【杀】,则你本阶段使用【杀】的次数上限+Y,且当你于本阶段内使用【杀】指定目标后,你可以令这Y名角色也成为此【杀】的目标;没有【杀】,则你弃置这Y名角色的各一张牌。然后你摸Y张牌(X为你的体力值,Y为这些角色中猜错的角色数)。", + ol_dianwei: "界典韦", + ol_dianwei_prefix: "界", + olqiangxi: "强袭", + olqiangxi_info: + "出牌阶段限两次。你可以弃置一张武器牌或受到1点无来源伤害,然后对一名本回合内未成为过〖强袭〗目标的其他角色造成1点伤害。", + olningwu: "狞恶", + olningwu_info: + "锁定技。当一名角色A于一回合内第二次受到伤害后,若A或伤害来源为你,则你摸一张牌,然后弃置其装备区或判定区内的一张牌。", + re_zhuhuan: "界朱桓", + re_zhuhuan_prefix: "界", + refenli: "奋励", + refenli_info: + "若你的手牌数为全场最多,你可以跳过判定阶段和摸牌阶段;若你的体力值为全场最多,你可以跳过出牌阶段;若你的装备区里有牌且数量为全场最多,你可以跳过弃牌阶段。", //破界石不值钱了 就逮着免费突破硬削是吧 - repingkou:'平寇', - repingkou_info:'回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。若你选择的角色数小于X,则你可以弃置其中一名角色装备区内的一张牌。', - dc_liru:'界李儒', - dc_liru_prefix:'界', - dcmieji:'灭计', - dcmieji_info:'出牌阶段限一次,你可以展示一张武器牌或黑色锦囊牌。你将此牌置于牌堆顶,然后令一名有手牌的其他角色选择一项:⒈弃置一张锦囊牌;⒉依次弃置两张非锦囊牌。', - dcfencheng:'焚城', - dcfencheng_info:'限定技。出牌阶段,你可以指定一名其他角色,令从其开始的其他角色依次选择一项:⒈弃置至少X张牌(X为上一名角色弃置的牌数+1)。⒉你对其造成2点火焰伤害。', - oljiang:'激昂', - oljiang_info:'①当你使用【决斗】或红色【杀】指定第一个目标后,或成为【决斗】或红色【杀】的目标后,你可以摸一张牌。②当有【决斗】或红色【杀】于每回合内首次因弃置而进入弃牌堆后,你可以失去1点体力并获得这些牌。', - re_xunyou:'界荀攸', - re_xunyou_prefix:'界', - reqice:'奇策', - reqice_info:'出牌阶段限X次(X为你的“奇策”数+1),你可以将所有手牌当做任意一张普通锦囊牌使用。', - rezhiyu:'智愚', - rezhiyu_info:'当你受到伤害后,你可以摸一张牌,然后展示所有手牌,令伤害来源弃置一张手牌。若你展示的牌颜色均相同,你获得1枚“奇策”直到下回合结束且获得来源弃置的牌。', - re_caiyong:'界蔡邕', - re_caiyong_prefix:'界', - rebizhuan:'辟撰', - rebizhuan_bg:'书', - rebizhuan_info:'①当你使用♠牌时,或成为其他角色使用♠牌的目标后,你可以将牌堆顶的一张牌置于武将牌上,称为“书”(你至多拥有四张“书”)。②你的手牌上限+X(X为“书”数)。', - retongbo:'通博', - retongbo_info:'摸牌阶段结束时,你可以用任意手牌交换等量“书”。然后若“书”数至少为4,你可以将四张“书”任意交给其他角色。若你交出的牌花色各不相同,你回复1点体力且“书”的上限+1(至多增加等同存活角色数的上限)。', - re_chengong:'界陈宫', - re_chengong_prefix:'界', - remingce:'明策', - remingce_info:'出牌阶段限一次。你可以将一张【杀】或装备牌交给一名其他角色,其选择一项:1.视为对你选择的另一名角色使用一张【杀】,且若此牌造成伤害,则执行选项2;2.你与其各摸一张牌。', - re_sundeng:'界孙登', - re_sundeng_prefix:'界', - rekuangbi:'匡弼', - rekuangbi_info:'出牌阶段开始时,你可以令一名其他角色将至多三张牌置于你的武将牌上直到此阶段结束。然后当你使用牌时,若你:有与此牌花色相同的“匡弼”牌,你移去其中一张并与其各摸一张牌;没有与此牌花色相同的“匡弼”牌,你随机移去一张“匡弼”牌并摸一张牌。', - dc_chenqun:'界陈群', - dc_chenqun_prefix:'界', - repindi:'品第', - repindi_info:'出牌阶段每名角色限一次。你可以弃置一张本阶段未以此法弃置过的类型的牌并选择一名角色,你选择一项:1.其摸X张牌;2.其弃置X张牌(X为你本回合发动〖品第〗的次数)。然后若其已受伤,你横置或重置。', - re_mazhong:'界马忠', - re_mazhong_prefix:'界', - refuman:'抚蛮', - refuman_info:'出牌阶段每名角色限一次。你可以弃置一张牌,令一名其他角色从弃牌堆中获得一张【杀】。然后其于其下个回合结束前使用或打出此牌时,你与其各摸一张牌。', - re_guanzhang:'界关兴张苞', - re_guanzhang_prefix:'界', - retongxin:'同心', - retongxin_info:'锁定技。你的攻击范围+2。', - re_wenpin:'界文聘', - re_wenpin_prefix:'界', - rezhenwei:'镇卫', - rezhenwei_info:'当一名其他角色成为【杀】或黑色锦囊牌的目标时,若该角色的体力值不大于你且此牌的目标角色数为1,你可以弃置一张牌并选择一项:1.摸一张牌,然后将此【杀】或黑色锦囊牌的目标转移给你;2.令此【杀】或黑色锦囊牌无效且将此【杀】或黑色锦囊牌置于使用者的武将牌上,然后当前回合结束后,使用者获得这些牌。', - ol_huangzhong:'界黄忠', - ol_huangzhong_prefix:'界', - remoshi:'没矢', - remoshi_info:'锁定技。①当你使用【杀】对目标角色造成伤害后,若其装备区里有防具牌或坐骑牌,你将此【杀】对应的实体牌置于其武将牌上。②当有“没矢”牌的角色失去防具牌或坐骑牌后,你获得其“没矢”牌。', - dc_caozhi:'界曹植', - dc_caozhi_prefix:'界', - dcjiushi:'酒诗', - dcjiushi_info:'①当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。②当你受到伤害后,若你的武将牌于受到伤害时背面向上,你可以翻面。③当你使用【酒】后,你使用【杀】的次数上限+1直到你的下个回合结束。', - olhuoji:'火计', - olhuoji_info:'①你可以将一张红色牌当【火攻】使用。②你使用【火攻】的作用效果改为“目标角色随机展示一张手牌A,然后你可以弃置一张与A颜色相同的牌,对目标造成1点火属性伤害”。', - olkanpo:'看破', - olkanpo_info:'①你可以将一张黑色牌当【无懈可击】使用。②你使用的【无懈可击】不可被响应。', - xinwangxi:'忘隙', - xinwangxi_info:'当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可以摸两张牌,然后交给其一张牌。', - ol_yanwen:'界颜良文丑', - ol_yanwen_prefix:'界', - olshuangxiong:'双雄', - olshuangxiong_info:'①摸牌阶段结束时,你可以弃置一张牌。若如此做,你本回合内可以将一张与此牌颜色不同的牌当做【决斗】使用。②结束阶段,你从弃牌堆中获得本回合内对你造成伤害的所有牌。', - re_zhuzhi:'界朱治', - re_zhuzhi_prefix:'界', - reanguo:'安国', - reanguo_info:'出牌阶段限一次。你可以选择一名其他角色,若其:手牌数为全场最少,其摸一张牌;体力值为全场最低,其回复1点体力;装备区内牌数为全场最少,其随机使用一张装备牌。然后若该角色有未执行的效果且你满足条件,你执行之。若你与其执行了全部分支,你可以重铸任意张牌。', - dcyicong:'义从', - dcyicong_info:'锁定技。①你至其他角色的距离-1。②若你已损失的体力值不小于2,则其他角色至你的距离+1。', - re_zhangsong:'界张松', - re_zhangsong_prefix:'界', - rexiantu:'献图', - rexiantu_info:'其他角色的出牌阶段开始时,你可以摸两张牌,然后将两张牌交给该角色。然后此阶段结束时,若其于此阶段没有造成过伤害,你失去1点体力。', - re_jsp_huangyueying:'界SP黄月英', - re_jsp_huangyueying_prefix:'界SP', - rejiqiao:'机巧', - rejiqiao_info:'出牌阶段开始时,你可以弃置任意张牌,然后亮出牌堆顶X张牌(X为你以此法弃置的牌数与其中装备牌数之和),你获得其中所有非装备牌。', - relinglong:'玲珑', - relinglong_info:'锁定技。若你的装备区:有空置的防具栏,你视为拥有〖八卦阵〗;有空置的两种坐骑栏,你的手牌上限+2;有空置的宝物栏,你视为拥有〖奇才〗;以上均满足:你使用的【杀】或普通锦囊牌不可被响应。', - ol_zhangzhang:'界张昭张纮', - ol_zhangzhang_prefix:'界', - olzhijian:'直谏', - olzhijian_info:'出牌阶段,你可以将一张装备牌置于其他角色的装备区(可替换原装备),然后摸一张牌。', - olguzheng:'固政', - olguzheng_info:'每阶段限一次。当其他角色的至少两张牌因弃置而进入弃牌堆后,你可以令其获得其中一张牌,然后你可以获得剩余的牌。', - re_caochong:'界曹冲', - re_caochong_prefix:'界', - rechengxiang:'称象', - rechengxiang_info:'当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于13的牌。若你得到的牌点数之和为13,你复原武将牌。', - re_caorui:'界曹叡', - re_caorui_prefix:'界', - remingjian:'明鉴', - remingjian_info:'出牌阶段限一次。你可以将所有手牌交给一名其他角色,然后该角色于其下个回合获得如下效果:1.手牌上限与使用【杀】的次数上限+1;2.当该角色首次造成伤害后,其可以令你发动一次〖恢拓〗。', - rexingshuai:'兴衰', - rexingshuai_info:'主公技,限定技。当你进入濒死状态时,你可令其他魏势力角色依次选择是否令你回复1点体力。然后这些角色依次受到1点伤害。有〖明鉴〗效果的角色于其回合内杀死角色后,你重置〖兴衰〗。', - xin_zhangliang:'界张梁', - xin_zhangliang_prefix:'界', - rejijun:'集军', - rejijun_info:'当你使用目标角色含有自己的牌结算完毕后,你可以进行一次判定并将判定牌置于武将牌上,称为“方”。', - refangtong:'方统', - refangtong_info:'结束阶段,你可以将一张手牌置于武将牌上,称为“方”。若如此做,你可以移去任意张“方”并对一名其他角色造成1点雷属性伤害(若你移去的“方”的点数和大于36,则改为造成3点雷属性伤害)。', - re_simalang:'界司马朗', - re_simalang_prefix:'界', - requji:'去疾', - requji_info:'出牌阶段限一次,你可以弃置至多X张牌并令等量名角色回复1点体力,然后仍处于受伤状态的目标角色摸一张牌,若你以此法弃置了黑色牌,你失去1点体力(X为你已损失的体力值)。', - rejunbing:'郡兵', - rejunbing_info:'一名角色的结束阶段,若其手牌数小于其体力值,其可以摸一张牌并将所有手牌交给你,然后你可以交给其等量的牌。', - re_zhugedan:'界诸葛诞', - re_zhugedan_prefix:'界', - regongao:'功獒', - regongao_info:'锁定技。一名其他角色首次进入濒死状态时,你增加1点体力上限,然后回复1点体力。', - rejuyi:'举义', - rejuyi_info:'觉醒技。准备阶段,若你已受伤,且你的体力上限大于场上的存活角色数,你将手牌数摸至体力上限,然后获得技能〖崩坏〗和〖威重〗。', - reweizhong:'威重', - reweizhong_info:'锁定技。当你的体力上限增加或减少时,你摸两张牌。', - re_zhongyao:'界钟繇', - re_zhongyao_prefix:'界', - rehuomo:'活墨', - rehuomo_info:'每种牌名每回合限一次。当你需要使用一张基本牌时,你可以将一张黑色非基本牌置于牌堆顶,视为使用此基本牌。', - zhoutai:'界周泰', - zhoutai_prefix:'界', - caoren:'界曹仁', - caoren_prefix:'界', - ollianhuan:'连环', - ollianhuan_info:'你可以将一张♣牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。', - re_lidian:'界李典', - gz_re_lidian:'李典', - re_lidian_prefix:'界', - re_xushu:'界徐庶', - re_xushu_prefix:'界', - rejianxiong_old:'奸雄', - rejianxiong_old_info:'当你受到伤害后,你可以摸一张牌或获得对你造成伤害的牌。', + repingkou: "平寇", + repingkou_info: + "回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。若你选择的角色数小于X,则你可以弃置其中一名角色装备区内的一张牌。", + dc_liru: "界李儒", + dc_liru_prefix: "界", + dcmieji: "灭计", + dcmieji_info: + "出牌阶段限一次,你可以展示一张武器牌或黑色锦囊牌。你将此牌置于牌堆顶,然后令一名有手牌的其他角色选择一项:⒈弃置一张锦囊牌;⒉依次弃置两张非锦囊牌。", + dcfencheng: "焚城", + dcfencheng_info: + "限定技。出牌阶段,你可以指定一名其他角色,令从其开始的其他角色依次选择一项:⒈弃置至少X张牌(X为上一名角色弃置的牌数+1)。⒉你对其造成2点火焰伤害。", + oljiang: "激昂", + oljiang_info: + "①当你使用【决斗】或红色【杀】指定第一个目标后,或成为【决斗】或红色【杀】的目标后,你可以摸一张牌。②当有【决斗】或红色【杀】于每回合内首次因弃置而进入弃牌堆后,你可以失去1点体力并获得这些牌。", + re_xunyou: "界荀攸", + re_xunyou_prefix: "界", + reqice: "奇策", + reqice_info: "出牌阶段限X次(X为你的“奇策”数+1),你可以将所有手牌当做任意一张普通锦囊牌使用。", + rezhiyu: "智愚", + rezhiyu_info: + "当你受到伤害后,你可以摸一张牌,然后展示所有手牌,令伤害来源弃置一张手牌。若你展示的牌颜色均相同,你获得1枚“奇策”直到下回合结束且获得来源弃置的牌。", + re_caiyong: "界蔡邕", + re_caiyong_prefix: "界", + rebizhuan: "辟撰", + rebizhuan_bg: "书", + rebizhuan_info: + "①当你使用♠牌时,或成为其他角色使用♠牌的目标后,你可以将牌堆顶的一张牌置于武将牌上,称为“书”(你至多拥有四张“书”)。②你的手牌上限+X(X为“书”数)。", + retongbo: "通博", + retongbo_info: + "摸牌阶段结束时,你可以用任意手牌交换等量“书”。然后若“书”数至少为4,你可以将四张“书”任意交给其他角色。若你交出的牌花色各不相同,你回复1点体力且“书”的上限+1(至多增加等同存活角色数的上限)。", + re_chengong: "界陈宫", + re_chengong_prefix: "界", + remingce: "明策", + remingce_info: + "出牌阶段限一次。你可以将一张【杀】或装备牌交给一名其他角色,其选择一项:1.视为对你选择的另一名角色使用一张【杀】,且若此牌造成伤害,则执行选项2;2.你与其各摸一张牌。", + re_sundeng: "界孙登", + re_sundeng_prefix: "界", + rekuangbi: "匡弼", + rekuangbi_info: + "出牌阶段开始时,你可以令一名其他角色将至多三张牌置于你的武将牌上直到此阶段结束。然后当你使用牌时,若你:有与此牌花色相同的“匡弼”牌,你移去其中一张并与其各摸一张牌;没有与此牌花色相同的“匡弼”牌,你随机移去一张“匡弼”牌并摸一张牌。", + dc_chenqun: "界陈群", + dc_chenqun_prefix: "界", + repindi: "品第", + repindi_info: + "出牌阶段每名角色限一次。你可以弃置一张本阶段未以此法弃置过的类型的牌并选择一名角色,你选择一项:1.其摸X张牌;2.其弃置X张牌(X为你本回合发动〖品第〗的次数)。然后若其已受伤,你横置或重置。", + re_mazhong: "界马忠", + re_mazhong_prefix: "界", + refuman: "抚蛮", + refuman_info: + "出牌阶段每名角色限一次。你可以弃置一张牌,令一名其他角色从弃牌堆中获得一张【杀】。然后其于其下个回合结束前使用或打出此牌时,你与其各摸一张牌。", + re_guanzhang: "界关兴张苞", + re_guanzhang_prefix: "界", + retongxin: "同心", + retongxin_info: "锁定技。你的攻击范围+2。", + re_wenpin: "界文聘", + re_wenpin_prefix: "界", + rezhenwei: "镇卫", + rezhenwei_info: + "当一名其他角色成为【杀】或黑色锦囊牌的目标时,若该角色的体力值不大于你且此牌的目标角色数为1,你可以弃置一张牌并选择一项:1.摸一张牌,然后将此【杀】或黑色锦囊牌的目标转移给你;2.令此【杀】或黑色锦囊牌无效且将此【杀】或黑色锦囊牌置于使用者的武将牌上,然后当前回合结束后,使用者获得这些牌。", + ol_huangzhong: "界黄忠", + ol_huangzhong_prefix: "界", + remoshi: "没矢", + remoshi_info: + "锁定技。①当你使用【杀】对目标角色造成伤害后,若其装备区里有防具牌或坐骑牌,你将此【杀】对应的实体牌置于其武将牌上。②当有“没矢”牌的角色失去防具牌或坐骑牌后,你获得其“没矢”牌。", + dc_caozhi: "界曹植", + dc_caozhi_prefix: "界", + dcjiushi: "酒诗", + dcjiushi_info: + "①当你需要使用【酒】时,若你的武将牌正面向上,你可以翻面,视为使用一张【酒】。②当你受到伤害后,若你的武将牌于受到伤害时背面向上,你可以翻面。③当你使用【酒】后,你使用【杀】的次数上限+1直到你的下个回合结束。", + olhuoji: "火计", + olhuoji_info: + "①你可以将一张红色牌当【火攻】使用。②你使用【火攻】的作用效果改为“目标角色随机展示一张手牌A,然后你可以弃置一张与A颜色相同的牌,对目标造成1点火属性伤害”。", + olkanpo: "看破", + olkanpo_info: "①你可以将一张黑色牌当【无懈可击】使用。②你使用的【无懈可击】不可被响应。", + xinwangxi: "忘隙", + xinwangxi_info: + "当你对其他角色造成1点伤害后,或受到其他角色造成的1点伤害后,你可以摸两张牌,然后交给其一张牌。", + ol_yanwen: "界颜良文丑", + ol_yanwen_prefix: "界", + olshuangxiong: "双雄", + olshuangxiong_info: + "①摸牌阶段结束时,你可以弃置一张牌。若如此做,你本回合内可以将一张与此牌颜色不同的牌当做【决斗】使用。②结束阶段,你从弃牌堆中获得本回合内对你造成伤害的所有牌。", + re_zhuzhi: "界朱治", + re_zhuzhi_prefix: "界", + reanguo: "安国", + reanguo_info: + "出牌阶段限一次。你可以选择一名其他角色,若其:手牌数为全场最少,其摸一张牌;体力值为全场最低,其回复1点体力;装备区内牌数为全场最少,其随机使用一张装备牌。然后若该角色有未执行的效果且你满足条件,你执行之。若你与其执行了全部分支,你可以重铸任意张牌。", + dcyicong: "义从", + dcyicong_info: + "锁定技。①你至其他角色的距离-1。②若你已损失的体力值不小于2,则其他角色至你的距离+1。", + re_zhangsong: "界张松", + re_zhangsong_prefix: "界", + rexiantu: "献图", + rexiantu_info: + "其他角色的出牌阶段开始时,你可以摸两张牌,然后将两张牌交给该角色。然后此阶段结束时,若其于此阶段没有造成过伤害,你失去1点体力。", + re_jsp_huangyueying: "界SP黄月英", + re_jsp_huangyueying_prefix: "界SP", + rejiqiao: "机巧", + rejiqiao_info: + "出牌阶段开始时,你可以弃置任意张牌,然后亮出牌堆顶X张牌(X为你以此法弃置的牌数与其中装备牌数之和),你获得其中所有非装备牌。", + relinglong: "玲珑", + relinglong_info: + "锁定技。若你的装备区:有空置的防具栏,你视为拥有〖八卦阵〗;有空置的两种坐骑栏,你的手牌上限+2;有空置的宝物栏,你视为拥有〖奇才〗;以上均满足:你使用的【杀】或普通锦囊牌不可被响应。", + ol_zhangzhang: "界张昭张纮", + ol_zhangzhang_prefix: "界", + olzhijian: "直谏", + olzhijian_info: + "出牌阶段,你可以将一张装备牌置于其他角色的装备区(可替换原装备),然后摸一张牌。", + olguzheng: "固政", + olguzheng_info: + "每阶段限一次。当其他角色的至少两张牌因弃置而进入弃牌堆后,你可以令其获得其中一张牌,然后你可以获得剩余的牌。", + re_caochong: "界曹冲", + re_caochong_prefix: "界", + rechengxiang: "称象", + rechengxiang_info: + "当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于13的牌。若你得到的牌点数之和为13,你复原武将牌。", + re_caorui: "界曹叡", + re_caorui_prefix: "界", + remingjian: "明鉴", + remingjian_info: + "出牌阶段限一次。你可以将所有手牌交给一名其他角色,然后该角色于其下个回合获得如下效果:1.手牌上限与使用【杀】的次数上限+1;2.当该角色首次造成伤害后,其可以令你发动一次〖恢拓〗。", + rexingshuai: "兴衰", + rexingshuai_info: + "主公技,限定技。当你进入濒死状态时,你可令其他魏势力角色依次选择是否令你回复1点体力。然后这些角色依次受到1点伤害。有〖明鉴〗效果的角色于其回合内杀死角色后,你重置〖兴衰〗。", + xin_zhangliang: "界张梁", + xin_zhangliang_prefix: "界", + rejijun: "集军", + rejijun_info: + "当你使用目标角色含有自己的牌结算完毕后,你可以进行一次判定并将判定牌置于武将牌上,称为“方”。", + refangtong: "方统", + refangtong_info: + "结束阶段,你可以将一张手牌置于武将牌上,称为“方”。若如此做,你可以移去任意张“方”并对一名其他角色造成1点雷属性伤害(若你移去的“方”的点数和大于36,则改为造成3点雷属性伤害)。", + re_simalang: "界司马朗", + re_simalang_prefix: "界", + requji: "去疾", + requji_info: + "出牌阶段限一次,你可以弃置至多X张牌并令等量名角色回复1点体力,然后仍处于受伤状态的目标角色摸一张牌,若你以此法弃置了黑色牌,你失去1点体力(X为你已损失的体力值)。", + rejunbing: "郡兵", + rejunbing_info: + "一名角色的结束阶段,若其手牌数小于其体力值,其可以摸一张牌并将所有手牌交给你,然后你可以交给其等量的牌。", + re_zhugedan: "界诸葛诞", + re_zhugedan_prefix: "界", + regongao: "功獒", + regongao_info: "锁定技。一名其他角色首次进入濒死状态时,你增加1点体力上限,然后回复1点体力。", + rejuyi: "举义", + rejuyi_info: + "觉醒技。准备阶段,若你已受伤,且你的体力上限大于场上的存活角色数,你将手牌数摸至体力上限,然后获得技能〖崩坏〗和〖威重〗。", + reweizhong: "威重", + reweizhong_info: "锁定技。当你的体力上限增加或减少时,你摸两张牌。", + re_zhongyao: "界钟繇", + re_zhongyao_prefix: "界", + rehuomo: "活墨", + rehuomo_info: + "每种牌名每回合限一次。当你需要使用一张基本牌时,你可以将一张黑色非基本牌置于牌堆顶,视为使用此基本牌。", + zhoutai: "界周泰", + zhoutai_prefix: "界", + caoren: "界曹仁", + caoren_prefix: "界", + ollianhuan: "连环", + ollianhuan_info: + "你可以将一张♣牌当【铁索连环】使用或重铸。你使用【铁索连环】选择目标后,可以给此牌增加一个目标。", + re_lidian: "界李典", + gz_re_lidian: "李典", + re_lidian_prefix: "界", + re_xushu: "界徐庶", + re_xushu_prefix: "界", + rejianxiong_old: "奸雄", + rejianxiong_old_info: "当你受到伤害后,你可以摸一张牌或获得对你造成伤害的牌。", - refresh_standard:'界限突破·标', - refresh_feng:'界限突破·风', - refresh_huo:'界限突破·火', - refresh_lin:'界限突破·林', - refresh_shan:'界限突破·山', - refresh_yijiang1:'界限突破·将1', - refresh_yijiang2:'界限突破·将2', - refresh_yijiang3:'界限突破·将3', - refresh_yijiang4:'界限突破·将4', - refresh_yijiang5:'界限突破·将5', - refresh_yijiang6:'界限突破·原6', - refresh_xinghuo:'界限突破·星火', + refresh_standard: "界限突破·标", + refresh_feng: "界限突破·风", + refresh_huo: "界限突破·火", + refresh_lin: "界限突破·林", + refresh_shan: "界限突破·山", + refresh_yijiang1: "界限突破·将1", + refresh_yijiang2: "界限突破·将2", + refresh_yijiang3: "界限突破·将3", + refresh_yijiang4: "界限突破·将4", + refresh_yijiang5: "界限突破·将5", + refresh_yijiang6: "界限突破·原6", + refresh_xinghuo: "界限突破·星火", }, }; }); diff --git a/character/sb.js b/character/sb.js index 2f684f6ea..519e02fdc 100644 --- a/character/sb.js +++ b/character/sb.js @@ -1,136 +1,196 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { //strategy and battle, "sb" in short - name:'sb', - connect:true, - character:{ - sb_gaoshun:['male','qun',4,['sbxianzhen','sbjinjiu']], - sb_xiahoudun:['male','wei',4,['sbganglie','sbqingjian']], - sb_xunyu:['male','wei',3,['sbquhu','sbjieming']], - sb_caopi:['male','wei',3,['sbxingshang','sbfangzhu','sbsongwei'],['zhu']], - sb_guanyu:['male','shu',4,['sbwusheng','sbyijue']], - sb_huangyueying:['female','shu',3,['sbjizhi','sbqicai']], - sb_sp_zhugeliang:['male','shu',3,['sbhuoji','sbkanpo']], - sb_zhanghe:['male','wei',4,['sbqiaobian']], - sb_yujin:['male','wei',4,['sbxiayuan','sbjieyue']], - sb_huaxiong:['male','qun','3/4/1',['new_reyaowu','sbyangwei']], - liucheng:['female','qun',3,['splveying','spyingwu']], - sp_yangwan:['female','qun',3,['spmingxuan','spxianchou']], - sb_huangzhong:['male','shu',4,['sbliegong']], - sb_lvmeng:['male','wu',4,['sbkeji','sbdujiang']], - sb_sunshangxiang:['female','shu',4,['sbjieyin','sbliangzhu','sbxiaoji'],['border:wu']], - sb_sunquan:['male','wu',4,['sbzhiheng','sbtongye','sbjiuyuan'],['zhu']], - sb_huanggai:['male','wu',4,['sbkurou','sbzhaxiang']], - sb_zhouyu:['male','wu',3,['sbyingzi','sbfanjian']], - sb_caoren:['male','wei','4/4/1',['sbjushou','sbjiewei']], - sb_xiahoushi:['female','shu',3,['sbqiaoshi','sbyanyu']], - sb_zhangjiao:['male','qun',3,['sbleiji','sbguidao','sbhuangtian'],['zhu']], - sb_caocao:['male','wei',4,['sbjianxiong','sbqingzheng','sbhujia'],['zhu']], - sb_zhenji:['female','wei',3,['sbluoshen','qingguo']], - sb_ganning:['male','wu',4,['sbqixi','sbfenwei']], - sb_machao:['male','shu',4,['mashu','sbtieji']], - sb_xuhuang:['male','wei',4,['sbduanliang','sbshipo']], - sb_zhangfei:['male','shu',4,['sbpaoxiao','sbxieji']], - sb_zhaoyun:['male','shu',4,['sblongdan','sbjizhu']], - sb_liubei:['male','shu',4,['sbrende','sbzhangwu','sbjijiang'],['zhu']], - sb_jiangwei:['male','shu','4/4/1',['sbtiaoxin','sbzhiji']], - sb_fazheng:['male','shu',3,['sbxuanhuo','sbenyuan']], - sb_chengong:['male','qun',3,['sbmingce','sbzhichi']], - sb_diaochan:['female','qun',3,['sblijian','sbbiyue']], - sb_yuanshao:['male','qun',4,['sbluanji','sbxueyi'],['zhu']], - sb_pangtong:['male','shu',3,['sblianhuan','sbniepan']], - sb_sunce:['male','wu',4,['sbjiang','sbhunzi','sbzhiba'],['zhu']], - sb_daqiao:['female','wu',3,['sbguose','sbliuli']], - 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']], + name: "sb", + connect: true, + character: { + sb_gaoshun: ["male", "qun", 4, ["sbxianzhen", "sbjinjiu"]], + sb_xiahoudun: ["male", "wei", 4, ["sbganglie", "sbqingjian"]], + sb_xunyu: ["male", "wei", 3, ["sbquhu", "sbjieming"]], + sb_caopi: ["male", "wei", 3, ["sbxingshang", "sbfangzhu", "sbsongwei"], ["zhu"]], + sb_guanyu: ["male", "shu", 4, ["sbwusheng", "sbyijue"]], + sb_huangyueying: ["female", "shu", 3, ["sbjizhi", "sbqicai"]], + sb_sp_zhugeliang: ["male", "shu", 3, ["sbhuoji", "sbkanpo"]], + sb_zhanghe: ["male", "wei", 4, ["sbqiaobian"]], + sb_yujin: ["male", "wei", 4, ["sbxiayuan", "sbjieyue"]], + sb_huaxiong: ["male", "qun", "3/4/1", ["new_reyaowu", "sbyangwei"]], + liucheng: ["female", "qun", 3, ["splveying", "spyingwu"]], + sp_yangwan: ["female", "qun", 3, ["spmingxuan", "spxianchou"]], + sb_huangzhong: ["male", "shu", 4, ["sbliegong"]], + sb_lvmeng: ["male", "wu", 4, ["sbkeji", "sbdujiang"]], + sb_sunshangxiang: ["female", "shu", 4, ["sbjieyin", "sbliangzhu", "sbxiaoji"], ["border:wu"]], + sb_sunquan: ["male", "wu", 4, ["sbzhiheng", "sbtongye", "sbjiuyuan"], ["zhu"]], + sb_huanggai: ["male", "wu", 4, ["sbkurou", "sbzhaxiang"]], + sb_zhouyu: ["male", "wu", 3, ["sbyingzi", "sbfanjian"]], + sb_caoren: ["male", "wei", "4/4/1", ["sbjushou", "sbjiewei"]], + sb_xiahoushi: ["female", "shu", 3, ["sbqiaoshi", "sbyanyu"]], + sb_zhangjiao: ["male", "qun", 3, ["sbleiji", "sbguidao", "sbhuangtian"], ["zhu"]], + sb_caocao: ["male", "wei", 4, ["sbjianxiong", "sbqingzheng", "sbhujia"], ["zhu"]], + sb_zhenji: ["female", "wei", 3, ["sbluoshen", "qingguo"]], + sb_ganning: ["male", "wu", 4, ["sbqixi", "sbfenwei"]], + sb_machao: ["male", "shu", 4, ["mashu", "sbtieji"]], + sb_xuhuang: ["male", "wei", 4, ["sbduanliang", "sbshipo"]], + sb_zhangfei: ["male", "shu", 4, ["sbpaoxiao", "sbxieji"]], + sb_zhaoyun: ["male", "shu", 4, ["sblongdan", "sbjizhu"]], + sb_liubei: ["male", "shu", 4, ["sbrende", "sbzhangwu", "sbjijiang"], ["zhu"]], + sb_jiangwei: ["male", "shu", "4/4/1", ["sbtiaoxin", "sbzhiji"]], + sb_fazheng: ["male", "shu", 3, ["sbxuanhuo", "sbenyuan"]], + sb_chengong: ["male", "qun", 3, ["sbmingce", "sbzhichi"]], + sb_diaochan: ["female", "qun", 3, ["sblijian", "sbbiyue"]], + sb_yuanshao: ["male", "qun", 4, ["sbluanji", "sbxueyi"], ["zhu"]], + sb_pangtong: ["male", "shu", 3, ["sblianhuan", "sbniepan"]], + sb_sunce: ["male", "wu", 4, ["sbjiang", "sbhunzi", "sbzhiba"], ["zhu"]], + sb_daqiao: ["female", "wu", 3, ["sbguose", "sbliuli"]], + 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:{ - sb_zhi:['sb_sunquan','sb_zhouyu','sb_zhangjiao','sb_caocao','sb_zhenji','sb_liubei','sb_daqiao','sb_liubiao','sb_sp_zhugeliang','sb_xunyu'], - sb_shi:['sb_xuhuang','sb_machao','sb_fazheng','sb_chengong','sb_diaochan','sb_pangtong','sb_zhanghe','sb_caopi'], - sb_tong:['liucheng','sp_yangwan','sb_xiahoushi','sb_zhangfei','sb_zhaoyun','sb_sunce','sb_zhurong','sb_xiaoqiao','sb_xiahoudun'], - sb_yu:['sb_yujin','sb_lvmeng','sb_huangzhong','sb_huanggai','sb_zhouyu','sb_caoren','sb_ganning','sb_yl_luzhi','sb_huangyueying'], - sb_neng:['sb_huaxiong','sb_sunshangxiang','sb_jiangwei','sb_yuanshao','sb_menghuo','sb_guanyu','sb_gaoshun'], + characterSort: { + sb: { + sb_zhi: [ + "sb_sunquan", + "sb_zhouyu", + "sb_zhangjiao", + "sb_caocao", + "sb_zhenji", + "sb_liubei", + "sb_daqiao", + "sb_liubiao", + "sb_sp_zhugeliang", + "sb_xunyu", + ], + sb_shi: [ + "sb_xuhuang", + "sb_machao", + "sb_fazheng", + "sb_chengong", + "sb_diaochan", + "sb_pangtong", + "sb_zhanghe", + "sb_caopi", + "sb_ganning", + ], + sb_tong: [ + "liucheng", + "sp_yangwan", + "sb_xiahoushi", + "sb_zhangfei", + "sb_zhaoyun", + "sb_sunce", + "sb_zhurong", + "sb_xiaoqiao", + "sb_xiahoudun", + ], + sb_yu: [ + "sb_yujin", + "sb_lvmeng", + "sb_huangzhong", + "sb_huanggai", + "sb_zhouyu", + "sb_caoren", + "sb_yl_luzhi", + "sb_huangyueying", + ], + sb_neng: [ + "sb_huaxiong", + "sb_sunshangxiang", + "sb_jiangwei", + "sb_yuanshao", + "sb_menghuo", + "sb_guanyu", + "sb_gaoshun", + ], // sb_waitforsort:[], - } + }, }, - characterSubstitute:{ - sb_sp_zhugeliang:[ - ], + characterSubstitute: { + sb_sp_zhugeliang: [], }, - skill:{ + skill: { //高顺 - sbxianzhen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget(card,player,target){ - return target!==player; + sbxianzhen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget(card, player, target) { + return target !== player; }, - async content(event,trigger,player){ + async content(event, trigger, player) { const target = event.targets[0]; - player.addTempSkill('sbxianzhen_attack', 'phaseUseAfter'); - player.markAuto('sbxianzhen_attack',target); + player.addTempSkill("sbxianzhen_attack", "phaseUseAfter"); + player.markAuto("sbxianzhen_attack", target); }, - ai:{ + ai: { expose: 0.2, - order(item,player){ - return get.order({ name: 'sha' }) + 1; + order(item, player) { + return get.order({ name: "sha" }) + 1; }, - result:{ - target(player,target){ - if (!player.countCards('hs', card => { - return get.name(card) === 'sha' && player.canUse(card, target, false); - })) return -0.1; - if (target.countCards('h') === 1 && player.canCompare(target)) return -2; + result: { + target(player, target) { + if ( + !player.countCards("hs", (card) => { + return get.name(card) === "sha" && player.canUse(card, target, false); + }) + ) + return -0.1; + if (target.countCards("h") === 1 && player.canCompare(target)) return -2; return -1.5; }, - } + }, }, - subSkill:{ - attack:{ - audio:'sbxianzhen', - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if (event.card.name !== 'sha') return false; - return player.getStorage('sbxianzhen_attack').includes(event.target) && event.target.isIn() && player.canCompare(event.target); + subSkill: { + attack: { + audio: "sbxianzhen", + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (event.card.name !== "sha") return false; + return ( + player.getStorage("sbxianzhen_attack").includes(event.target) && + event.target.isIn() && + player.canCompare(event.target) + ); }, - charlotte:true, - onremove:true, - logTarget:'target', - check(event,player){ + charlotte: true, + onremove: true, + logTarget: "target", + check(event, player) { return get.attitude(player, event.target) < 0; }, - prompt(event,player){ - return `陷阵:是否与${get.translation(event.target)}拼点?` + prompt(event, player) { + return `陷阵:是否与${get.translation(event.target)}拼点?`; }, - prompt2(event,player){ - const target = event.target, card = event.card; - return `若你赢,${get.translation(card)}无视防具且不计入次数,且若你本回合未以此法造成过伤害,你对其造成1点伤害;
              若其拼点牌为【杀】,则你获得之;
              若其拼点牌为其最后的手牌,则${get.translation(card)}对其造成伤害时,此伤害+1。` + prompt2(event, player) { + const target = event.target, + card = event.card; + return `若你赢,${get.translation( + card + )}无视防具且不计入次数,且若你本回合未以此法造成过伤害,你对其造成1点伤害;
              若其拼点牌为【杀】,则你获得之;
              若其拼点牌为其最后的手牌,则${get.translation( + card + )}对其造成伤害时,此伤害+1。`; }, - group:'sbxianzhen_record', - async content(event,trigger,player){ - const target = trigger.target, card = trigger.card; + group: "sbxianzhen_record", + async content(event, trigger, player) { + const target = trigger.target, + card = trigger.card; const next = player.chooseToCompare(target); let result = await next.forResult(); if (result.bool) { - target.addTempSkill('qinggang2'); + target.addTempSkill("qinggang2"); target.storage.qinggang2.add(card); if (trigger.addCount !== false) { trigger.addCount = false; - const stat = player.getStat('card'); + const stat = player.getStat("card"); if (stat[card.name] && stat[card.name] > 0) stat[card.name]--; } - game.log(card, '无视防具且不计入次数限制'); + game.log(card, "无视防具且不计入次数限制"); if (!player.storage.sbxianzhen_damaged) { player.storage.sbxianzhen_damaged = true; - player.when('phaseAfter').then(() => { + player.when("phaseAfter").then(() => { delete player.storage.sbxianzhen_damaged; - }) + }); await target.damage(); await game.asyncDelayx(); } @@ -141,227 +201,285 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if (!Array.isArray(cards)) cards = [cards]; if (comparer === player) continue; for (const card of cards) { - if (get.name(card, comparer) == 'sha' && get.position(card, true) == 'd') { + if ( + get.name(card, comparer) == "sha" && + get.position(card, true) == "d" + ) { toGain.push(card); } } } - if (toGain.length) await player.gain(toGain, 'gain2'); - if (player.getStorage('sbxianzhen_recorded').includes(target)) { + if (toGain.length) await player.gain(toGain, "gain2"); + if (player.getStorage("sbxianzhen_recorded").includes(target)) { const id = target.playerid; const map = trigger.getParent().customArgs; if (!map[id]) map[id] = {}; - if (typeof map[id].extraDamage != 'number') { + if (typeof map[id].extraDamage != "number") { map[id].extraDamage = 0; } map[id].extraDamage++; - game.log(card, '对', target, '造成的伤害+1'); + game.log(card, "对", target, "造成的伤害+1"); } }, - intro:{ - content:'本阶段对$使用牌无距离限制,且使用杀指定其为目标后可以与其拼点', + intro: { + content: "本阶段对$使用牌无距离限制,且使用杀指定其为目标后可以与其拼点", }, - mod:{ - targetInRange(card,player,target){ - if(player.getStorage('sbxianzhen_attack').includes(target)) return true; + mod: { + targetInRange(card, player, target) { + if (player.getStorage("sbxianzhen_attack").includes(target)) return true; }, - } - }, - record:{ - trigger:{ - global:'loseAsyncEnd', }, - charlotte:true, - silent:true, - filter(event,player){ - if(event.getParent(2).name !== 'sbxianzhen_attack') return false; - return game.hasPlayer(current => { - if (current.countCards('h')) return false; + }, + record: { + trigger: { + global: "loseAsyncEnd", + }, + charlotte: true, + silent: true, + filter(event, player) { + if (event.getParent(2).name !== "sbxianzhen_attack") return false; + return game.hasPlayer((current) => { + if (current.countCards("h")) return false; const evt = event.getl(current); return evt && evt.hs && evt.hs.length; }); }, - async content(event,trigger,player){ + async content(event, trigger, player) { const targets = []; - game.countPlayer(current => { - if (current.countCards('h')) return false; + game.countPlayer((current) => { + if (current.countCards("h")) return false; const evt = trigger.getl(current); - if(evt && evt.hs && evt.hs.length) targets.add(current); + if (evt && evt.hs && evt.hs.length) targets.add(current); }); if (!player.storage.sbxianzhen_recorded) { - player.when('sbxianzhen_attackAfter').then(() => { + player.when("sbxianzhen_attackAfter").then(() => { delete player.storage.sbxianzhen_recorded; - }) + }); } - player.markAuto('sbxianzhen_recorded', targets); + player.markAuto("sbxianzhen_recorded", targets); }, }, - } + }, }, - sbjinjiu:{ - audio:2, - inherit:'rejinjiu', - group:['sbjinjiu_decrease','sbjinjiu_compare'], - global:'sbjinjiu_global', - subSkill:{ - decrease:{ - audio:'sbjinjiu', - forced:true, - trigger:{player:'damageBegin4'}, - filter(event,player){ + sbjinjiu: { + audio: 2, + inherit: "rejinjiu", + group: ["sbjinjiu_decrease", "sbjinjiu_compare"], + global: "sbjinjiu_global", + subSkill: { + decrease: { + audio: "sbjinjiu", + forced: true, + trigger: { player: "damageBegin4" }, + filter(event, player) { return event.getParent(2).jiu; }, - async content(event,trigger){ + async content(event, trigger) { trigger.num = 1; }, - ai:{ - filterDamage:true, - skillTagFilter(player,tag,arg){ - return arg&&arg.jiu; + ai: { + filterDamage: true, + skillTagFilter(player, tag, arg) { + return arg && arg.jiu; }, }, }, - global:{ - mod:{ - cardEnabled(card,player){ - if(card.name=='jiu'&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('sbjinjiu')) return false; + global: { + mod: { + cardEnabled(card, player) { + if ( + card.name == "jiu" && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("sbjinjiu") + ) + return false; }, - cardSavable(card,player){ - if(card.name=='jiu'&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('sbjinjiu')) return false; + cardSavable(card, player) { + if ( + card.name == "jiu" && + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("sbjinjiu") + ) + return false; }, }, }, - compare:{ - trigger:{ - global:'compare', + compare: { + trigger: { + global: "compare", }, - filter(event,player){ + filter(event, player) { const participant = [event.player]; - if(event.targets) participant.addArray(event.targets); + if (event.targets) participant.addArray(event.targets); else participant.add(event.target); if (!participant.includes(player)) return false; - if (event.player !== player && event.card1 && event.card1.name === 'jiu') return true; - if (event.target !== player && event.card2 && event.card2.name === 'jiu') return true; + if (event.player !== player && event.card1 && event.card1.name === "jiu") + return true; + if (event.target !== player && event.card2 && event.card2.name === "jiu") + return true; return false; }, - forced:true, - direct:true, - async content(event,trigger,player){ - for (const [role, ind] of [['player',1], ['target',2]]){ - const current = trigger[role], card = trigger[`card${ind}`]; - if (current !== player && card && card.name === 'jiu') { - await player.logSkill('sbjinjiu_compare', current); - game.log(current, '拼点牌点数视为','#yA'); + forced: true, + direct: true, + async content(event, trigger, player) { + for (const [role, ind] of [ + ["player", 1], + ["target", 2], + ]) { + const current = trigger[role], + card = trigger[`card${ind}`]; + if (current !== player && card && card.name === "jiu") { + await player.logSkill("sbjinjiu_compare", current); + game.log(current, "拼点牌点数视为", "#yA"); trigger[`num${ind}`] = 1; } } - } + }, }, }, }, //夏侯惇 - sbganglie:{ - audio:2, - enable:'phaseUse', - filter(event,player){ + sbganglie: { + audio: 2, + enable: "phaseUse", + filter(event, player) { if (!event.sbganglie_enabledTargets) return false; - return game.hasPlayer(current=>{ - return lib.skill.sbganglie.filterTarget(null,player,current); + return game.hasPlayer((current) => { + return lib.skill.sbganglie.filterTarget(null, player, current); }); }, - onChooseToUse(event){ - if (game.online || event.type !== 'phase') return; + onChooseToUse(event) { + if (game.online || event.type !== "phase") return; const player = event.player; - const chosen = player.getAllHistory('useSkill', evt => evt.skill === 'sbganglie').map(evt => { - return evt.targets; - }).flat(); - const targets = player.getAllHistory('damage', evt => evt.source && evt.source.isIn()).map(evt => evt.source).unique(); + const chosen = player + .getAllHistory("useSkill", (evt) => evt.skill === "sbganglie") + .map((evt) => { + return evt.targets; + }) + .flat(); + const targets = player + .getAllHistory("damage", (evt) => evt.source && evt.source.isIn()) + .map((evt) => evt.source) + .unique(); targets.removeArray(chosen); - event.set('sbganglie_enabledTargets',targets); + event.set("sbganglie_enabledTargets", targets); }, - filterTarget(card,player,target){ - return get.event('sbganglie_enabledTargets').includes(target); + filterTarget(card, player, target) { + return get.event("sbganglie_enabledTargets").includes(target); }, - async content(event,trigger,player){ + async content(event, trigger, player) { event.targets[0].damage(2); }, - ai:{ - order:6, - result:{ - target:-2, - } + ai: { + order: 6, + result: { + target: -2, + }, }, }, - sbqingjian:{ - audio:2, - trigger:{ - global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter'], + sbqingjian: { + audio: 2, + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - forced:true, - locked:false, - filter(event,player){ - if (player.getExpansions('sbqingjian').length >= Math.max(1, player.getHp() - 1)) return false; - if (event.name !== 'cardsDiscard') { + forced: true, + locked: false, + filter(event, player) { + if (player.getExpansions("sbqingjian").length >= Math.max(1, player.getHp() - 1)) + return false; + if (event.name !== "cardsDiscard") { if (event.position !== ui.discardPile) return false; - if (!game.hasPlayer(current => { - const evt = event.getl(current); - return evt.cards && evt.cards.length > 0; - })) return false; - } - else{ + if ( + !game.hasPlayer((current) => { + const evt = event.getl(current); + return evt.cards && evt.cards.length > 0; + }) + ) + return false; + } else { const evt = event.getParent(); - if (evt.relatedEvent && evt.relatedEvent.name === 'useCard') return false; + if (evt.relatedEvent && evt.relatedEvent.name === "useCard") return false; } return true; }, - group:'sbqingjian_give', - async content(event,trigger,player){ + group: "sbqingjian_give", + async content(event, trigger, player) { let cards = trigger.cards.slice(); const maxNum = Math.max(1, player.getHp() - 1); - const myLen = player.getExpansions('sbqingjian').length, cardsLen = trigger.cards.length; + const myLen = player.getExpansions("sbqingjian").length, + cardsLen = trigger.cards.length; const overflow = myLen + cardsLen - maxNum; if (overflow > 0) cards.randomRemove(overflow); - const next = player.addToExpansion(cards, 'gain2'); - next.gaintag.add('sbqingjian'); + const next = player.addToExpansion(cards, "gain2"); + next.gaintag.add("sbqingjian"); await next; }, - marktext:'俭', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "俭", + intro: { + content: "expansion", + markcount: "expansion", }, - subSkill:{ - give:{ - audio:'sbqingjian', - trigger:{player:'phaseUseEnd'}, - filter(event,player){ - return player.getExpansions('sbqingjian').length > 0; + subSkill: { + give: { + audio: "sbqingjian", + trigger: { player: "phaseUseEnd" }, + filter(event, player) { + return player.getExpansions("sbqingjian").length > 0; }, - forced:true, - locked:false, - async content(event,trigger,player){ - if (_status.connectMode) game.broadcastAll(() => { _status.noclearcountdown = true }); + forced: true, + locked: false, + async content(event, trigger, player) { + if (_status.connectMode) + game.broadcastAll(() => { + _status.noclearcountdown = true; + }); const given_map = {}; event.given_map = given_map; - const expansions = player.getExpansions('sbqingjian'); + const expansions = player.getExpansions("sbqingjian"); let result; while (true) { if (expansions.length > 1) { - result = await player.chooseCardButton('清俭:请选择要分配的牌', true, expansions, [1, expansions.length]).set('ai', button => { - if (ui.selected.buttons.length) return 0; - return get.value(button.link, get.player()); - }).forResult(); - } - else if (expansions.length === 1) result = { bool: true, links: expansions.slice(0) }; + result = await player + .chooseCardButton("清俭:请选择要分配的牌", true, expansions, [ + 1, + expansions.length, + ]) + .set("ai", (button) => { + if (ui.selected.buttons.length) return 0; + return get.value(button.link, get.player()); + }) + .forResult(); + } else if (expansions.length === 1) + result = { bool: true, links: expansions.slice(0) }; else return; if (!result.bool) return; const toGive = result.links; - result = await player.chooseTarget(`选择一名角色获得${get.translation(toGive)}`, expansions.length === 1).set('ai', target => { - const att = get.attitude(get.player(), target); - if (get.event('toEnemy')) return Math.max(0.01, 100 - att); - else if (att > 0) return Math.max(0.1, att / Math.sqrt(1 + target.countCards('h') + (get.event().getParent().given_map[target.playerid] || 0))); - else return Math.max(0.01, (100 + att) / 200); - }).set('toEnemy', get.value(toGive[0], player, 'raw') < 0).forResult(); + result = await player + .chooseTarget( + `选择一名角色获得${get.translation(toGive)}`, + expansions.length === 1 + ) + .set("ai", (target) => { + const att = get.attitude(get.player(), target); + if (get.event("toEnemy")) return Math.max(0.01, 100 - att); + else if (att > 0) + return Math.max( + 0.1, + att / + Math.sqrt( + 1 + + target.countCards("h") + + (get.event().getParent().given_map[ + target.playerid + ] || 0) + ) + ); + else return Math.max(0.01, (100 + att) / 200); + }) + .set("toEnemy", get.value(toGive[0], player, "raw") < 0) + .forResult(); if (result.bool) { expansions.removeArray(toGive); if (result.targets.length) { @@ -372,166 +490,197 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if (!expansions.length) break; } } - if (_status.connectMode) game.broadcastAll(() => { delete _status.noclearcountdown; game.stopCountChoose() }); + if (_status.connectMode) + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); const gain_list = []; for (const i in given_map) { const source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - player.line(source, 'green'); + player.line(source, "green"); gain_list.push([source, given_map[i]]); - game.log(source, '获得了', given_map[i]); + game.log(source, "获得了", given_map[i]); } - await game.loseAsync({ - gain_list, - giver: player, - animate: 'gain2', - }).setContent('gaincardMultiple'); - } + await game + .loseAsync({ + gain_list, + giver: player, + animate: "gain2", + }) + .setContent("gaincardMultiple"); + }, }, }, }, //荀彧 - sbquhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - return game.countPlayer(current=>lib.skill.sbquhu.filterTarget(null,player,current))>1; + sbquhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return ( + game.countPlayer((current) => lib.skill.sbquhu.filterTarget(null, player, current)) > + 1 + ); }, - filterTarget(card,player,target){ - return player!=target&&target.countCards('he')>0; + filterTarget(card, player, target) { + return player != target && target.countCards("he") > 0; }, - selectTarget:2, - multitarget:true, - multiline:true, - async content(event,trigger,player){ - const targets=[player].addArray(event.targets); + selectTarget: 2, + multitarget: true, + multiline: true, + async content(event, trigger, player) { + const targets = [player].addArray(event.targets); targets.sortBySeat(); - const {result}=await player.chooseCardOL(targets,'he',[1,Infinity],true,'驱虎:请将任意张牌扣置于武将牌上').set('ai',card=>{ - const player=get.event().getParent(2).player; - let value=5; - if(get.player()==player) value-=0.5; - return value-get.useful(card); - }); - const lose_list=[]; - const map=new Map(); + const { result } = await player + .chooseCardOL(targets, "he", [1, Infinity], true, "驱虎:请将任意张牌扣置于武将牌上") + .set("ai", (card) => { + const player = get.event().getParent(2).player; + let value = 5; + if (get.player() == player) value -= 0.5; + return value - get.useful(card); + }); + const lose_list = []; + const map = new Map(); let myCards; - let minLength=Infinity; - for(let i=0;imyCards.length; - const sortedList=lose_list.filter(list=>list[0]!=player).sort((a,b)=>{ - return 1000*(b[1].length-a[1].length)+(get.distance(player,a[0],'absolute')-get.distance(player,b[0],'absolute')); - }); - const mostPlayer=sortedList[0][0],secondPlayer=sortedList[1][0]; - await new Promise(resolve=>{ - game.broadcastAll(lose_list=>{ - lose_list.forEach(list=>list[0].prompt(`${get.cnNumber(list[1].length)}张`,'wood')); - },lose_list); - setTimeout(()=>{ - game.broadcastAll(lose_list=>{ - lose_list.forEach(list=>list[0].unprompt()); - },lose_list); + const isMin = minLength > myCards.length; + const sortedList = lose_list + .filter((list) => list[0] != player) + .sort((a, b) => { + return ( + 1000 * (b[1].length - a[1].length) + + (get.distance(player, a[0], "absolute") - + get.distance(player, b[0], "absolute")) + ); + }); + const mostPlayer = sortedList[0][0], + secondPlayer = sortedList[1][0]; + await new Promise((resolve) => { + game.broadcastAll((lose_list) => { + lose_list.forEach((list) => + list[0].prompt(`${get.cnNumber(list[1].length)}张`, "wood") + ); + }, lose_list); + setTimeout(() => { + game.broadcastAll((lose_list) => { + lose_list.forEach((list) => list[0].unprompt()); + }, lose_list); resolve(); - },2000/(lib.config.speed=='vvfast'?3:1)); + }, 2000 / (lib.config.speed == "vvfast" ? 3 : 1)); }); - if(isMin){ - await mostPlayer.gain(myCards,'give',player); + if (isMin) { + await mostPlayer.gain(myCards, "give", player); await game.asyncDelay(); - const gain_list=lose_list.filter(list=>list[0]!=player); + const gain_list = lose_list.filter((list) => list[0] != player); game.loseAsync({ gain_list, - animate:'draw', - }).setContent('gaincardMultiple'); - } - else{ - mostPlayer.line(secondPlayer,'thunder'); + animate: "draw", + }).setContent("gaincardMultiple"); + } else { + mostPlayer.line(secondPlayer, "thunder"); await secondPlayer.damage(mostPlayer); await game.asyncDelay(); - await mostPlayer.gain(myCards,'give',player); + await mostPlayer.gain(myCards, "give", player); await game.asyncDelay(); - await game.loseAsync({ - lose_list:sortedList, - }).setContent(()=>{ - for(var i=0;i { + for (var i = 0; i < event.lose_list.length; i++) { + var current = event.lose_list[i][0], + cards = event.lose_list[i][1]; + var next = current.lose(cards, ui.discardPile); + current.$throw(cards); + game.log(current, "将", cards, "置入了弃牌堆"); + next.set("relatedEvent", event.getParent()); + next.set("getlx", false); + } + }); await game.asyncDelayx(); } }, - addToExpansionMultiple(){ - "step 0" - if(event.animate=='give') event.visible=true; - event.type='addToExpansion'; - if(!event.gaintag) event.gaintag=[]; - if(event.lose_list){ - var map={},map2={}; - for(var list of event.lose_list){ - var player=list[0],cards=list[1]; - var myId=player.playerid; - if(!map2[myId]) map2[myId]=[]; - for(var i of cards){ - var owner=get.owner(i,'judge'); - if(owner&&(owner!=player||get.position(i)!='x')){ - var id=owner.playerid; - if(!map[id]) map[id]=[[],[],[]]; + addToExpansionMultiple() { + "step 0"; + if (event.animate == "give") event.visible = true; + event.type = "addToExpansion"; + if (!event.gaintag) event.gaintag = []; + if (event.lose_list) { + var map = {}, + map2 = {}; + for (var list of event.lose_list) { + var player = list[0], + cards = list[1]; + var myId = player.playerid; + if (!map2[myId]) map2[myId] = []; + for (var i of cards) { + var owner = get.owner(i, "judge"); + if (owner && (owner != player || get.position(i) != "x")) { + var id = owner.playerid; + if (!map[id]) map[id] = [[], [], []]; map[id][0].push(i); map2[myId].push(i); - var position=get.position(i); - if(position=='h') map[id][1].push(i); + var position = get.position(i); + if (position == "h") map[id][1].push(i); else map[id][2].push(i); - } - else if(!event.updatePile&&get.position(i)=='c') event.updatePile=true; + } else if (!event.updatePile && get.position(i) == "c") + event.updatePile = true; } } - event.losing_map=map; - event.gaining_map=map2; - for(var i in map){ - var owner=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - var next=owner.lose(map[i][0],ui.special).set('forceDie',true).set('getlx',false); - next.set('relatedEvent',event.getParent()); - next.set('forceDie',true); - next.set('getlx',false); - if(event.visible==true) next.set('visible',true); + event.losing_map = map; + event.gaining_map = map2; + for (var i in map) { + var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + var next = owner + .lose(map[i][0], ui.special) + .set("forceDie", true) + .set("getlx", false); + next.set("relatedEvent", event.getParent()); + next.set("forceDie", true); + next.set("getlx", false); + if (event.visible == true) next.set("visible", true); } - } - else { + } else { event.finish(); } "step 1"; - if(event.lose_list){ - var map={}; - for(var list of event.lose_list){ - var player=list[0],cards=list[1]; - for(var i=0;i{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); - game.resume(); - },get.delayx(500,500),player,cards); - } - else if(event.animate=='gain'){ - player.$gain(cards,false); + setTimeout( + (player, cards, resume) => { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + if (resume) game.resume(); + }, + get.delayx(500, 500), + player, + cards, + loopedCount === mapLength + ); + } else if (event.animate == "gain") { + player.$gain(cards, false); game.pause(); - setTimeout((player,cards)=>{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); - game.resume(); - },get.delayx(700,700),player,cards); - } - else if(event.animate=='gain2'||event.animate=='draw2'){ - var gain2t=300; - if(player.$gain2(cards)&&player==game.me){ - gain2t=500; + setTimeout( + (player, cards, resume) => { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + if (resume) game.resume(); + }, + get.delayx(700, 700), + player, + cards, + loopedCount === mapLength + ); + } else if (event.animate == "gain2" || event.animate == "draw2") { + var gain2t = 300; + if (player.$gain2(cards) && player == game.me) { + gain2t = 500; } game.pause(); - setTimeout((player,cards)=>{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); - game.resume(); - },get.delayx(gain2t,gain2t),player,cards); - } - else if(event.animate=='give'||event.animate=='giveAuto'){ - var evtmap=event.losing_map; - var entries=Object.entries(evtmap).map(entry=>[entry[0],entry[1][0]]); - var getOwner=(card)=>{ - var entry=entries.find(entry=>entry[1].includes(card)); - if(entry) return (_status.connectMode?lib.playerOL:game.playerMap)[entry[0]]; + setTimeout( + (player, cards, resume) => { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + if (resume) game.resume(); + }, + get.delayx(gain2t, gain2t), + player, + cards, + loopedCount === mapLength + ); + } else if (event.animate == "give" || event.animate == "giveAuto") { + var evtmap = event.losing_map; + var entries = Object.entries(evtmap).map((entry) => [entry[0], entry[1][0]]); + var getOwner = (card) => { + var entry = entries.find((entry) => entry[1].includes(card)); + if (entry) + return (_status.connectMode ? lib.playerOL : game.playerMap)[entry[0]]; return null; }; - var gainmap={}; - for(var cardx of cards){ - var owner=getOwner(cardx); - if(owner){ - var id=owner.playerid; - if(!gainmap[id]) gainmap[id]=[]; + var gainmap = {}; + for (var cardx of cards) { + var owner = getOwner(cardx); + if (owner) { + var id = owner.playerid; + if (!gainmap[id]) gainmap[id] = []; gainmap[id].push(cardx); } } - if(event.animate=='give'){ - for(var i in gainmap){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - source.$give(evtmap[i][0],player,false); - if(event.log) game.log(player,'将',evtmap[i][0],'置于了武将牌上'); + if (event.animate == "give") { + for (var i in gainmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + source.$give(evtmap[i][0], player, false); + if (event.log) game.log(player, "将", evtmap[i][0], "置于了武将牌上"); } - } - else{ - for(var i in gainmap){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - if(evtmap[i][1].length){ - source.$giveAuto(evtmap[i][1],player,false); - if(event.log) game.log(player,'将',get.cnNumber(evtmap[i][1].length),'张牌置于了武将牌上'); + } else { + for (var i in gainmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (evtmap[i][1].length) { + source.$giveAuto(evtmap[i][1], player, false); + if (event.log) + game.log( + player, + "将", + get.cnNumber(evtmap[i][1].length), + "张牌置于了武将牌上" + ); } - if(evtmap[i][2].length){ - source.$give(evtmap[i][2],player,false); - if(event.log) game.log(player,'将',evtmap[i][2],'置于了武将牌上'); + if (evtmap[i][2].length) { + source.$give(evtmap[i][2], player, false); + if (event.log) game.log(player, "将", evtmap[i][2], "置于了武将牌上"); } } } game.pause(); - setTimeout((player,cards)=>{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); - game.resume(); - },get.delayx(500,500),player,cards); - } - else if(typeof event.animate=='function'){ - var time=event.animate(event); + setTimeout( + (player, cards, resume) => { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + if (resume) game.resume(); + }, + get.delayx(500, 500), + player, + cards, + loopedCount === mapLength + ); + } else if (typeof event.animate == "function") { + var time = event.animate(event); game.pause(); - setTimeout((player,cards)=>{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); - game.resume(); - },get.delayx(time,time),player,cards); - } - else{ - player.$addToExpansion(cards,null,event.gaintag); - for(var i of event.gaintag) player.markSkill(i); + setTimeout( + (player, cards, resume) => { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + if (resume) game.resume(); + }, + get.delayx(time, time), + player, + cards, + loopedCount === mapLength + ); + } else { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); event.finish(); } } "step 3"; game.delayx(); - if(event.updatePile) game.updateRoundNumber(); + if (event.updatePile) game.updateRoundNumber(); }, - intro:{ - markcount:'expansion', - mark(dialog,storage,player){ - const cards=player.getExpansions('sbquhu'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + intro: { + markcount: "expansion", + mark(dialog, storage, player) { + const cards = player.getExpansions("sbquhu"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, - ai:{ - order:3.5, - result:{ - target(player,target){ - let sgn=1,preAtt=0; - if(ui.selected.targets.length){ - const selected=ui.selected.targets[0]; - preAtt=get.attitude(player,selected); - if(preAtt>0) sgn=-1; + ai: { + order: 3.5, + result: { + target(player, target) { + let sgn = 1, + preAtt = 0; + if (ui.selected.targets.length) { + const selected = ui.selected.targets[0]; + preAtt = get.attitude(player, selected); + if (preAtt > 0) sgn = -1; } - let eff=0.4*target.countCards('h',card=>{ - return 5-get.useful(card); - })-1; - if(get.attitude(player,target)>0&&sgn<0||get.attitude(player,target)<0&&preAtt<0) eff=-Math.abs(eff); + let eff = + 0.4 * + target.countCards("h", (card) => { + return 5 - get.useful(card); + }) - + 1; + if ( + (get.attitude(player, target) > 0 && sgn < 0) || + (get.attitude(player, target) < 0 && preAtt < 0) + ) + eff = -Math.abs(eff); return eff; }, - } - } + }, + }, }, - sbjieming:{ - audio:2, - trigger:{ - player:'damageEnd', + sbjieming: { + audio: 2, + trigger: { + player: "damageEnd", }, - direct:true, - async content(event,trigger,player){ - let num=Math.max(1,player.getDamagedHp()); - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('sbjieming'),`令一名角色摸三张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于${get.cnNumber(num)}张,你失去1点体力。`).set('ai',target=>{ - if(get.event('nope')) return 0; - const player=get.player(),att=get.attitude(player,target); - if(att>2){ - const num=Math.sqrt(Math.min(5,Math.max(1,target.countCards('he',card=>get.value(card)<5.5)))); - return num*att; - } - return att/3; - }).set('nope',(player.getHp()+player.countCards('hs',card=>player.canSaveCard(card,player))<=1)&&num>2); - if(!bool) return; - const target=targets[0]; - player.logSkill('sbjieming',target); - await target.draw(3); - num=Math.max(1,player.getDamagedHp()); - const {result:{bool:bool2,cards}}=await target.chooseToDiscard('节命:是否弃置任意张牌?',`若你本次弃置的牌数不大于${get.cnNumber(num)}张,${get.translation(player)}失去1点体力。`,[1,Infinity],'he').set('ai',card=>{ - if(get.event('nope')) return 0; - if(ui.selected.cards.length>get.event('num')) return 0; - return 6-get.value(card); - }).set('nope',get.attitude(target,player)*get.effect(player,{name:'losehp'},player,target)>=0).set('num',num); - if(!bool2||cards.length<=num) player.loseHp(); + direct: true, + async content(event, trigger, player) { + let num = Math.max(1, player.getDamagedHp()); + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("sbjieming"), + `令一名角色摸四张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于${get.cnNumber( + num + )}张,你失去1点体力。` + ) + .set("ai", (target) => { + if (get.event("nope")) return 0; + const player = get.player(), + att = get.attitude(player, target); + if (att > 2) { + const num = Math.sqrt( + Math.min( + 5, + Math.max( + 1, + target.countCards("he", (card) => get.value(card) < 5.5) + ) + ) + ); + return num * att; + } + return att / 3; + }) + .set( + "nope", + player.getHp() + + player.countCards("hs", (card) => player.canSaveCard(card, player)) <= + 1 && num > 2 + ); + if (!bool) return; + const target = targets[0]; + player.logSkill("sbjieming", target); + await target.draw(4); + num = Math.max(1, player.getDamagedHp()); + const { + result: { bool: bool2, cards }, + } = await target + .chooseToDiscard( + "节命:是否弃置任意张牌?", + `若你本次弃置的牌数不大于${get.cnNumber(num)}张,${get.translation( + player + )}失去1点体力。`, + [1, Infinity], + "he" + ) + .set("ai", (card) => { + if (get.event("nope")) return 0; + if (ui.selected.cards.length > get.event("num")) return 0; + return 6 - get.value(card); + }) + .set( + "nope", + get.attitude(target, player) * + get.effect(player, { name: "losehp" }, player, target) >= + 0 + ) + .set("num", num); + if (!bool2 || cards.length <= num) player.loseHp(); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - let max=0; - const num=Math.max(1,player.getDamagedHp()); - if(num>2) return [1,-2]; - const players=game.filterPlayer(); - for(const current of players){ - if(get.attitude(target,current)>0){ - max=Math.max(current.countCards('he'),max); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + let max = 0; + const num = Math.max(1, player.getDamagedHp()); + if (num > 2) return [1, -2]; + const players = game.filterPlayer(); + for (const current of players) { + if (get.attitude(target, current) > 0) { + max = Math.max(current.countCards("he"), max); } } - return [1,Math.max(1,1+Math.min(2,max/3))]; + return [1, Math.max(1, 1 + Math.min(2, max / 3))]; } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; }, }, }, }, //曹丕 - sbxingshang:{ - audio:2, - trigger:{global:['die','damageEnd']}, - filter(event,player){ - if(player.countMark('sbxingshang')>=get.info('sbxingshang').getLimit) return false; - return event.name=='die'||!player.getHistory('custom',evt=>evt.sbxingshang).length; + sbxingshang: { + audio: 2, + trigger: { global: ["die", "damageEnd"] }, + filter(event, player) { + if (player.countMark("sbxingshang") >= get.info("sbxingshang").getLimit) return false; + return ( + event.name == "die" || !player.getHistory("custom", (evt) => evt.sbxingshang).length + ); }, - forced:true, - locked:false, - async content(event,trigger,player){ - player.addMark('sbxingshang',Math.min(2,get.info('sbxingshang').getLimit-player.countMark('sbxingshang'))); - if(trigger.name=='damage') player.getHistory('custom').push({sbxingshang:true}); + forced: true, + locked: false, + async content(event, trigger, player) { + player.addMark( + "sbxingshang", + Math.min(2, get.info("sbxingshang").getLimit - player.countMark("sbxingshang")) + ); + if (trigger.name == "damage") player.getHistory("custom").push({ sbxingshang: true }); }, - marktext:'颂', - intro:{ - name:'颂', - content:'mark', + marktext: "颂", + intro: { + name: "颂", + content: "mark", }, - ai:{threaten:2.5}, - getLimit:9, - getNum(num){ - const list=[2,2,5,5,1,2,2,3,3,2]; - if(typeof num!='number'||!Array.from({length:list.length}).map((_,i)=>i+1).includes(num)) return 0; - return list[num-1]; + ai: { threaten: 2.5 }, + getLimit: 9, + getNum(num) { + const list = [2, 2, 5, 5, 1, 2, 2, 3, 3, 2]; + if ( + typeof num != "number" || + !Array.from({ length: list.length }) + .map((_, i) => i + 1) + .includes(num) + ) + return 0; + return list[num - 1]; }, - getEffect(player,num){ - if(!player||typeof num!='number') return 0; - switch(num){ + getEffect(player, num) { + if (!player || typeof num != "number") return 0; + switch (num) { //行殇选项 - case 1://-2,重置武将牌 - if(game.hasPlayer(target=>{ - return get.attitude(player,target)>0&&target.isTurnedOver(); - })) return 10; + case 1: //-2,重置武将牌 + if ( + game.hasPlayer((target) => { + return get.attitude(player, target) > 0 && target.isTurnedOver(); + }) + ) + return 10; return 0; - case 2://-2,摸min(5,max(2,阵亡角色数))的牌 - return Math.min(5,(Math.max(2,game.dead.length))); - case 3://-5,加上限加血+复原装备栏 - if(!game.hasPlayer(target=>{ - return get.attitude(player,target)>0&&target.maxHp<10; - })) return 0; - return 5+(game.hasPlayer(target=>{ - return get.attitude(player,target)>0&&target.hasDisabledSlot(); - })?1:0); - case 4://-5,劝封/化萍 + case 2: //-2,摸min(5,max(2,阵亡角色数))的牌 + return Math.min(5, Math.max(2, game.dead.length)); + case 3: //-5,加上限加血+复原装备栏 + if ( + !game.hasPlayer((target) => { + return get.attitude(player, target) > 0 && target.maxHp < 10; + }) + ) + return 0; + return ( + 5 + + (game.hasPlayer((target) => { + return get.attitude(player, target) > 0 && target.hasDisabledSlot(); + }) + ? 1 + : 0) + ); + case 4: //-5,劝封/化萍 return 0; //放逐选项 - case 5://-1,封印基本牌外的手牌 - if(game.hasPlayer(target=>{ - return get.attitude(player,target)<0; - })) return 1; + case 5: //-1,封印基本牌外的手牌 + if ( + game.hasPlayer((target) => { + return get.attitude(player, target) < 0; + }) + ) + return 1; return 0; - case 6://-2,白板到结束 - if(game.hasPlayer(target=>{ - if(target.hasSkill('sbfangzhu_ban')||target.hasSkill('fengyin')||target.hasSkill('baiban')) return false; - return get.attitude(player,target)<0&&['name','name1','name2'].reduce((sum,name)=>{ - if(target[name]&&(name!='name1'||target.name!=target.name1)){ - if(get.character(target[name])) sum+get.rank(target[name],true); - } - return sum; - },0)>5; - })) return 6; + case 6: //-2,白板到结束 + if ( + game.hasPlayer((target) => { + if ( + target.hasSkill("sbfangzhu_ban") || + target.hasSkill("fengyin") || + target.hasSkill("baiban") + ) + return false; + return ( + get.attitude(player, target) < 0 && + ["name", "name1", "name2"].reduce((sum, name) => { + if ( + target[name] && + (name != "name1" || target.name != target.name1) + ) { + if (get.character(target[name])) + sum + get.rank(target[name], true); + } + return sum; + }, 0) > 5 + ); + }) + ) + return 6; return 0; - case 7://-2,强命到结束 + case 7: //-2,强命到结束 return 0; - case 8://-3,翻面 - if(game.hasPlayer(target=>{ - return get.attitude(player,target)<0&&!target.isTurnedOver(); - })) return 8; + case 8: //-3,翻面 + if ( + game.hasPlayer((target) => { + return get.attitude(player, target) < 0 && !target.isTurnedOver(); + }) + ) + return 8; return 0; - case 9://-3,封印装备牌外的手牌 - if(game.hasPlayer(target=>{ - return get.attitude(player,target)<0; - })) return 2.5; + case 9: //-3,封印装备牌外的手牌 + if ( + game.hasPlayer((target) => { + return get.attitude(player, target) < 0; + }) + ) + return 2.5; return 0; - case 10://-2,封印锦囊牌外的手牌 - if(game.hasPlayer(target=>{ - return get.attitude(player,target)<0; - })) return 1.5; + case 10: //-2,封印锦囊牌外的手牌 + if ( + game.hasPlayer((target) => { + return get.attitude(player, target) < 0; + }) + ) + return 1.5; return 0; - default://其他 + default: //其他 return 0; } }, - group:'sbxingshang_use', - subSkill:{ - use:{ - audio:'sbxingshang', - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>{ - if(player.countMark('sbxingshang')>1) return true; - return player.countMark('sbxingshang')&&(target.isLinked()||target.isTurnedOver()); + group: "sbxingshang_use", + subSkill: { + use: { + audio: "sbxingshang", + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => { + if (player.countMark("sbxingshang") > 1) return true; + return ( + player.countMark("sbxingshang") && + (target.isLinked() || target.isTurnedOver()) + ); }); }, - usable:2, - chooseButton:{ - dialog(){ - var dialog=ui.create.dialog('行殇:请选择你要执行的一项','hidden'); - dialog.add([[ - [1,'移去2个“颂”标记,复原一名角色的武将牌'], - [2,'移去2个“颂”标记,令一名角色摸'+get.cnNumber(Math.min(5,Math.max(2,game.dead.length)))+'张牌'], - [3,'移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏'], - [4,'移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去〖行殇〗〖放逐〗〖颂威〗'], - ],'textbutton']); + usable: 2, + chooseButton: { + dialog() { + var dialog = ui.create.dialog("行殇:请选择你要执行的一项", "hidden"); + dialog.add([ + [ + [1, "移去2个“颂”标记,复原一名角色的武将牌"], + [ + 2, + "移去2个“颂”标记,令一名角色摸" + + get.cnNumber(Math.min(5, Math.max(2, game.dead.length))) + + "张牌", + ], + [ + 3, + "移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏", + ], + [ + 4, + "移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去〖行殇〗〖放逐〗〖颂威〗", + ], + ], + "textbutton", + ]); return dialog; }, - filter(button,player){ - if(player.countMark('sbxingshang')target.isLinked()||target.isTurnedOver()); + return game.hasPlayer( + (target) => target.isLinked() || target.isTurnedOver() + ); case 2: return true; case 3: - return game.hasPlayer(target=>target.maxHp<10); + return game.hasPlayer((target) => target.maxHp < 10); case 4: return game.dead.length; } }, - check(button){ - const player=get.event('player'),info=get.info('sbxingshang'); - let list=Array.from({length:4}).map((_,i)=>i+1); - list=list.filter(num=>player.countMark('sbxingshang')>=info.getNum(num)); - const num=list.sort((a,b)=>info.getEffect(player,b)-info.getEffect(player,a))[0]; - return (button.link==num)?10:0; + check(button) { + const player = get.event("player"), + info = get.info("sbxingshang"); + let list = Array.from({ length: 4 }).map((_, i) => i + 1); + list = list.filter( + (num) => player.countMark("sbxingshang") >= info.getNum(num) + ); + const num = list.sort( + (a, b) => info.getEffect(player, b) - info.getEffect(player, a) + )[0]; + return button.link == num ? 10 : 0; }, - backup(links,player){ + backup(links, player) { return { - num:links[0], - audio:'sbxingshang', - filterCard:()=>false, - selectCard:-1, - filterTarget(card,player,target){ - switch(lib.skill.sbxingshang_use_backup.num){ + num: links[0], + audio: "sbxingshang", + filterCard: () => false, + selectCard: -1, + filterTarget(card, player, target) { + switch (lib.skill.sbxingshang_use_backup.num) { case 1: - return target=>target.isLinked()||target.isTurnedOver(); + return (target) => target.isLinked() || target.isTurnedOver(); case 2: return true; case 3: - return target.maxHp<10; + return target.maxHp < 10; case 4: - return target==player; + return target == player; } }, - selectTarget:()=>lib.skill.sbxingshang_use_backup.num==4?-1:1, - async content(event,trigger,player){ - const target=event.targets[0]; - const num=lib.skill.sbxingshang_use_backup.num; - player.removeMark('sbxingshang',get.info('sbxingshang').getNum(num)); - switch(num){ + selectTarget: () => (lib.skill.sbxingshang_use_backup.num == 4 ? -1 : 1), + async content(event, trigger, player) { + const target = event.targets[0]; + const num = lib.skill.sbxingshang_use_backup.num; + player.removeMark("sbxingshang", get.info("sbxingshang").getNum(num)); + switch (num) { case 1: - if(target.isLinked()) target.link(false); - if(target.isTurnedOver()) target.turnOver(); + if (target.isLinked()) target.link(false); + if (target.isTurnedOver()) target.turnOver(); break; case 2: - target.draw(Math.min(5,Math.max(2,game.dead.length))); + target.draw(Math.min(5, Math.max(2, game.dead.length))); break; case 3: target.gainMaxHp(); target.recover(); - let list=[]; - for (let i=1;i<=5;i++){ - if(target.hasDisabledSlot(i)) list.push('equip'+i); + let list = []; + for (let i = 1; i <= 5; i++) { + if (target.hasDisabledSlot(i)) list.push("equip" + i); } - if(list.length) target.enableEquip(list.randomGet()); + if (list.length) target.enableEquip(list.randomGet()); break; case 4: - let map={}; - game.dead.forEach(target=>map[target.playerid]=get.translation(target)); - const {result:{control}}=await player.chooseControl(Object.values(map)).set('ai',()=>{ - const getNum=(target)=>{ - let num=0; - if(target.name&&lib.character[target.name]) num+=get.rank(target.name,true); - if(target.name2&&lib.character[target.name2]) num+=get.rank(target.name2,true); - return num; - }; - let controls=_status.event.controls.slice(); - controls=controls.map(name=>[name,game.dead.find(target=>_status.event.map[target.playerid]==name)]); - controls.sort((a,b)=>getNum(b[1])-getNum(a[1])); - return controls[0][0]; - }).set('prompt','获得一名已阵亡角色的所有技能').set('map',map); - if(control){ - const target2=game.dead.find(targetx=>map[targetx.playerid]==control); + let map = {}; + game.dead.forEach( + (target) => + (map[target.playerid] = get.translation(target)) + ); + const { + result: { control }, + } = await player + .chooseControl(Object.values(map)) + .set("ai", () => { + const getNum = (target) => { + let num = 0; + if (target.name && lib.character[target.name]) + num += get.rank(target.name, true); + if (target.name2 && lib.character[target.name2]) + num += get.rank(target.name2, true); + return num; + }; + let controls = _status.event.controls.slice(); + controls = controls.map((name) => [ + name, + game.dead.find( + (target) => + _status.event.map[target.playerid] == name + ), + ]); + controls.sort((a, b) => getNum(b[1]) - getNum(a[1])); + return controls[0][0]; + }) + .set("prompt", "获得一名已阵亡角色的所有技能") + .set("map", map); + if (control) { + const target2 = game.dead.find( + (targetx) => map[targetx.playerid] == control + ); player.line(target2); - game.log(player,'选择了',target2); - const skills=target2.getStockSkills(true,true); - const skills2=['sbxingshang','sbfangzhu','sbsongwei']; - player.changeSkills(skills,skills2); + game.log(player, "选择了", target2); + const skills = target2.getStockSkills(true, true); + const skills2 = ["sbxingshang", "sbfangzhu", "sbsongwei"]; + player.changeSkills(skills, skills2); } } }, - ai:{ - result:{ - target(player,target){ - switch(lib.skill.sbxingshang_use_backup.num){ + ai: { + result: { + target(player, target) { + switch (lib.skill.sbxingshang_use_backup.num) { case 1: - let num=0; - if(target.isLinked()&&!target.hasSkill('nzry_jieying')) num+=0.5; - if(target.isTurnedOver()) num+=10; + let num = 0; + if ( + target.isLinked() && + !target.hasSkill("nzry_jieying") + ) + num += 0.5; + if (target.isTurnedOver()) num += 10; return num; case 2: - return get.effect(target,{name:'draw'},player,player); + return get.effect( + target, + { name: "draw" }, + player, + player + ); case 3: - return Math.max(0,get.recoverEffect(target,player,player))+get.attitude(player,target); + return ( + Math.max( + 0, + get.recoverEffect(target, player, player) + ) + get.attitude(player, target) + ); case 4: return 1; } }, }, }, - } + }; }, - prompt(links,player){ - const str='###行殇###'; - switch(links[0]){ + prompt(links, player) { + const str = "###行殇###"; + switch (links[0]) { case 1: - return str+'移去2个“颂”标记,复原一名角色的武将牌'; + return str + "移去2个“颂”标记,复原一名角色的武将牌"; case 2: - return str+'移去2个“颂”标记,令一名角色摸'+get.cnNumber(Math.min(5,Math.max(2,game.dead.length)))+'张牌'; + return ( + str + + "移去2个“颂”标记,令一名角色摸" + + get.cnNumber(Math.min(5, Math.max(2, game.dead.length))) + + "张牌" + ); case 3: - return str+'移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏'; + return ( + str + + "移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏" + ); case 4: - return str+'移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去武将牌上的所有技能'; + return ( + str + + "移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去武将牌上的所有技能" + ); } - } - }, - ai:{ - order(_,player){ - const info=get.info('sbxingshang'); - const goon=(player.hasSkill('sbfangzhu')&&(player.getStat('skill').sbfangzhu||0)<(get.info('sbfangzhu').usable||Infinity)); - let list=Array.from({length:goon?10:4}).map((_,i)=>i+1); - list=list.filter(num=>player.countMark('sbxingshang')>=info.getNum(num)); - list.sort((a,b)=>info.getEffect(player,b)-info.getEffect(player,a)); - return (Array.from({length:4}).map((_,i)=>i+1).includes(list[0])&&info.getEffect(player,list[0])>0)?1:0; }, - result:{player:1}, + }, + ai: { + order(_, player) { + const info = get.info("sbxingshang"); + const goon = + player.hasSkill("sbfangzhu") && + (player.getStat("skill").sbfangzhu || 0) < + (get.info("sbfangzhu").usable || Infinity); + let list = Array.from({ length: goon ? 10 : 4 }).map((_, i) => i + 1); + list = list.filter( + (num) => player.countMark("sbxingshang") >= info.getNum(num) + ); + list.sort((a, b) => info.getEffect(player, b) - info.getEffect(player, a)); + return Array.from({ length: 4 }) + .map((_, i) => i + 1) + .includes(list[0]) && info.getEffect(player, list[0]) > 0 + ? 1 + : 0; + }, + result: { player: 1 }, }, }, - use_backup:{}, + use_backup: {}, }, }, - sbfangzhu:{ - audio:2, - audioname:['mb_caomao'], - enable:'phaseUse', - filter(event,player){ - return player.hasMark('sbxingshang'); + sbfangzhu: { + audio: 2, + audioname: ["mb_caomao"], + enable: "phaseUse", + filter(event, player) { + return player.hasMark("sbxingshang"); }, - usable:1, - chooseButton:{ - dialog(){ - var dialog=ui.create.dialog('放逐:请选择你要执行的一项','hidden'); - dialog.add([[ - [1,'移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束'], - [2,'移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束'], - [3,'移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束'], - [4,'移去3个“颂”标记,令一名其他角色将武将牌翻面'], - [5,'移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束'], - [6,'移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束'], - ],'textbutton']); + usable: 1, + chooseButton: { + dialog() { + var dialog = ui.create.dialog("放逐:请选择你要执行的一项", "hidden"); + dialog.add([ + [ + [1, "移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束"], + [2, "移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束"], + [ + 3, + "移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束", + ], + [4, "移去3个“颂”标记,令一名其他角色将武将牌翻面"], + [5, "移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束"], + [6, "移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束"], + ], + "textbutton", + ]); return dialog; }, - filter(button,player){ - if(player.countMark('sbxingshang'){ - if(target==player) return false; - const num=button.link,storage=target.getStorage('sbfangzhu_ban'); - return !((num==1&&storage.includes('basic'))||(num==5&&storage.includes('equip'))||(num==6&&storage.includes('trick'))); + filter(button, player) { + if (player.countMark("sbxingshang") < get.info("sbxingshang").getNum(button.link + 4)) + return false; + return game.hasPlayer((target) => { + if (target == player) return false; + const num = button.link, + storage = target.getStorage("sbfangzhu_ban"); + return !( + (num == 1 && storage.includes("basic")) || + (num == 5 && storage.includes("equip")) || + (num == 6 && storage.includes("trick")) + ); }); }, - check(button){ - const player=get.event('player'),info=get.info('sbxingshang'); - let list=Array.from({length:6}).map((_,i)=>i+1); - list=list.filter(num=>player.countMark('sbxingshang')>=info.getNum(num+4)); - const num=list.sort((a,b)=>info.getEffect(player,b+4)-info.getEffect(player,a+4))[0]-4; - return (button.link==num)?10:0; + check(button) { + const player = get.event("player"), + info = get.info("sbxingshang"); + let list = Array.from({ length: 6 }).map((_, i) => i + 1); + list = list.filter((num) => player.countMark("sbxingshang") >= info.getNum(num + 4)); + const num = + list.sort( + (a, b) => info.getEffect(player, b + 4) - info.getEffect(player, a + 4) + )[0] - 4; + return button.link == num ? 10 : 0; }, - backup(links,player){ + backup(links, player) { return { - num:links[0], - audio:'sbfangzhu', - audioname:['mb_caomao'], - filterCard:()=>false, - selectCard:-1, - filterTarget(card,player,target){ - if(target==player) return false; - const num=lib.skill.sbfangzhu_backup.num,storage=target.getStorage('sbfangzhu_ban'); - return !((num==1&&storage.includes('basic'))||(num==5&&storage.includes('equip'))||(num==6&&storage.includes('trick'))); + num: links[0], + audio: "sbfangzhu", + audioname: ["mb_caomao"], + filterCard: () => false, + selectCard: -1, + filterTarget(card, player, target) { + if (target == player) return false; + const num = lib.skill.sbfangzhu_backup.num, + storage = target.getStorage("sbfangzhu_ban"); + return !( + (num == 1 && storage.includes("basic")) || + (num == 5 && storage.includes("equip")) || + (num == 6 && storage.includes("trick")) + ); }, - async content(event,trigger,player){ - const target=event.target; - const num=lib.skill.sbfangzhu_backup.num; - player.removeMark('sbxingshang',get.info('sbxingshang').getNum(num+4)); - switch(num){ - case 1: case 2: case 6: - const type=['basic','equip','trick'][[1,2,6].indexOf(num)]; - target.addTempSkill('sbfangzhu_ban',{player:'phaseEnd'}); - target.markAuto('sbfangzhu_ban',[type]); + async content(event, trigger, player) { + const target = event.target; + const num = lib.skill.sbfangzhu_backup.num; + player.removeMark("sbxingshang", get.info("sbxingshang").getNum(num + 4)); + switch (num) { + case 1: + case 2: + case 6: + const type = ["basic", "equip", "trick"][[1, 2, 6].indexOf(num)]; + target.addTempSkill("sbfangzhu_ban", { player: "phaseEnd" }); + target.markAuto("sbfangzhu_ban", [type]); break; case 3: - target.addTempSkill('sbfangzhu_kill',{player:'phaseEnd'}); + target.addTempSkill("sbfangzhu_kill", { player: "phaseEnd" }); break; case 4: target.turnOver(); break; case 5: - target.addTempSkill('sbfangzhu_ban',{player:'phaseEnd'}); - target.markAuto('sbfangzhu_ban',['equip']); + target.addTempSkill("sbfangzhu_ban", { player: "phaseEnd" }); + target.markAuto("sbfangzhu_ban", ["equip"]); break; } }, - ai:{ - result:{ - target(player,target){ - switch(lib.skill.sbfangzhu_backup.num){ + ai: { + result: { + target(player, target) { + switch (lib.skill.sbfangzhu_backup.num) { case 1: - return -target.countCards('h',card=>get.type(card)!='basic')-1; + return ( + -target.countCards( + "h", + (card) => get.type(card) != "basic" + ) - 1 + ); case 2: - return -target.getSkills(null,null,false).reduce((sum,skill)=>{ - return sum+Math.max(get.skillRank(skill,'out'),get.skillRank(skill,'in')); - },0); + return -target + .getSkills(null, null, false) + .reduce((sum, skill) => { + return ( + sum + + Math.max( + get.skillRank(skill, "out"), + get.skillRank(skill, "in") + ) + ); + }, 0); case 3: return 0; case 4: - if(get.attitude(player,target)>0&&target.isTurnedOver()) return 10*target.countCards('hs')+1; - if(get.attitude(player,target)<0&&!target.isTurnedOver()) return -5*target.countCards('hs')+1; + if (get.attitude(player, target) > 0 && target.isTurnedOver()) + return 10 * target.countCards("hs") + 1; + if ( + get.attitude(player, target) < 0 && + !target.isTurnedOver() + ) + return -5 * target.countCards("hs") + 1; return 0; case 5: - return -target.countCards('h',card=>get.type(card)!='equip')-3; + return ( + -target.countCards( + "h", + (card) => get.type(card) != "equip" + ) - 3 + ); case 6: - return -target.countCards('h',card=>get.type2(card)!='trick')-2; + return ( + -target.countCards( + "h", + (card) => get.type2(card) != "trick" + ) - 2 + ); } }, }, }, - } + }; }, - prompt(links,player){ - const str='###放逐###'; - switch(links[0]){ + prompt(links, player) { + const str = "###放逐###"; + switch (links[0]) { case 1: - return str+'移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束'; + return ( + str + + "移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束" + ); case 2: - return str+'移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束'; + return ( + str + "移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束" + ); case 3: - return str+'移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束'; + return ( + str + + "移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束" + ); case 4: - return str+'移去3个“颂”标记,令一名其他角色将武将牌翻面'; + return str + "移去3个“颂”标记,令一名其他角色将武将牌翻面"; case 5: - return str+'移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束'; + return ( + str + + "移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束" + ); case 6: - return str+'移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束'; + return ( + str + + "移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束" + ); } - } - }, - ai:{ - order(_,player){ - const info=get.info('sbxingshang'); - const goon=(player.hasSkill('sbxingshang')&&(player.getStat('skill').sbxingshang_use||0)<(info.subSkill.use.usable||Infinity)); - let list=Array.from({length:goon?10:6}).map((_,i)=>i+(goon?1:5)); - list=list.filter(num=>player.countMark('sbxingshang')>=info.getNum(num)); - list.sort((a,b)=>info.getEffect(player,b)-info.getEffect(player,a)); - return (Array.from({length:6}).map((_,i)=>i+5).includes(list[0])&&info.getEffect(player,list[0])>0)?1:0; }, - result:{player:1}, }, - subSkill:{ - backup:{}, - kill:{ - charlotte:true, - mark:true, - marktext:'禁', - intro:{content:'不能响应其他角色使用的牌'}, - trigger:{global:'useCard1'}, - filter(event,player){ - return event.player!=player; + ai: { + order(_, player) { + const info = get.info("sbxingshang"); + const goon = + player.hasSkill("sbxingshang") && + (player.getStat("skill").sbxingshang_use || 0) < + (info.subSkill.use.usable || Infinity); + let list = Array.from({ length: goon ? 10 : 6 }).map((_, i) => i + (goon ? 1 : 5)); + list = list.filter((num) => player.countMark("sbxingshang") >= info.getNum(num)); + list.sort((a, b) => info.getEffect(player, b) - info.getEffect(player, a)); + return Array.from({ length: 6 }) + .map((_, i) => i + 5) + .includes(list[0]) && info.getEffect(player, list[0]) > 0 + ? 1 + : 0; + }, + result: { player: 1 }, + combo: "sbxingshang", + }, + subSkill: { + backup: {}, + kill: { + charlotte: true, + mark: true, + marktext: "禁", + intro: { content: "不能响应其他角色使用的牌" }, + trigger: { global: "useCard1" }, + filter(event, player) { + return event.player != player; }, - forced:true, - popup:false, - async content(event,trigger,player){ + forced: true, + popup: false, + async content(event, trigger, player) { trigger.directHit.add(player); }, }, - ban:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'禁', - intro:{ - markcount:()=>0, - content(storage){ - if(storage.length>1) return '不能使用手牌'; - return '于手牌中只能使用'+get.translation(storage[0])+'牌'; + ban: { + charlotte: true, + onremove: true, + mark: true, + marktext: "禁", + intro: { + markcount: () => 0, + content(storage) { + if (storage.length > 1) return "不能使用手牌"; + return "于手牌中只能使用" + get.translation(storage[0]) + "牌"; }, }, - mod:{ - cardEnabled(card,player){ - const storage=player.getStorage('sbfangzhu_ban'); - if(get.itemtype(card)=='card'&&get.position(card)!='h') return; - if(storage.length>1||!storage.includes(get.type2(card))) return false; + mod: { + cardEnabled(card, player) { + const storage = player.getStorage("sbfangzhu_ban"); + if (get.itemtype(card) == "card" && get.position(card) != "h") return; + if (storage.length > 1 || !storage.includes(get.type2(card))) return false; }, - cardSavable(card,player){ - const storage=player.getStorage('sbfangzhu_ban'); - if(get.itemtype(card)=='card'&&get.position(card)!='h') return; - if(storage.length>1||!storage.includes(get.type2(card))) return false; + cardSavable(card, player) { + const storage = player.getStorage("sbfangzhu_ban"); + if (get.itemtype(card) == "card" && get.position(card) != "h") return; + if (storage.length > 1 || !storage.includes(get.type2(card))) return false; }, }, }, }, }, - sbsongwei:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - if(player.countMark('sbxingshang')>=get.info('sbxingshang').getLimit) return false; - return game.hasPlayer(target=>target.group=='wei'&&target!=player); + sbsongwei: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + if (player.countMark("sbxingshang") >= get.info("sbxingshang").getLimit) return false; + return game.hasPlayer((target) => target.group == "wei" && target != player); }, - zhuSkill:true, - forced:true, - locked:false, - async content(event,trigger,player){ - player.addMark('sbxingshang',Math.min(get.info('sbxingshang').getLimit-player.countMark('sbxingshang'),2*game.countPlayer(target=>target.group=='wei'&&target!=player))); + zhuSkill: true, + forced: true, + locked: false, + async content(event, trigger, player) { + player.addMark( + "sbxingshang", + Math.min( + get.info("sbxingshang").getLimit - player.countMark("sbxingshang"), + 2 * game.countPlayer((target) => target.group == "wei" && target != player) + ) + ); }, - group:'sbsongwei_delete', - subSkill:{ - delete:{ - audio:'sbsongwei', - enable:'phaseUse', - filter(event,player){ - if(player.storage.sbsongwei_delete) return false; - return game.hasPlayer(target=>lib.skill.sbsongwei.subSkill.delete.filterTarget(null,player,target)); + group: "sbsongwei_delete", + subSkill: { + delete: { + audio: "sbsongwei", + enable: "phaseUse", + filter(event, player) { + if (player.storage.sbsongwei_delete) return false; + return game.hasPlayer((target) => + lib.skill.sbsongwei.subSkill.delete.filterTarget(null, player, target) + ); }, - filterTarget(card,player,target){ - return target!=player&&target.group=='wei'&&target.getStockSkills(false,true).length; + filterTarget(card, player, target) { + return ( + target != player && + target.group == "wei" && + target.getStockSkills(false, true).length + ); }, - skillAnimation:true, - animationColor:'thunder', - async content(event,trigger,player){ - player.storage.sbsongwei_delete=true; - player.awakenSkill('sbsongwei_delete'); - event.target.removeSkills(event.target.getStockSkills(false,true)); + skillAnimation: true, + animationColor: "thunder", + async content(event, trigger, player) { + player.storage.sbsongwei_delete = true; + player.awakenSkill("sbsongwei_delete"); + event.target.removeSkills(event.target.getStockSkills(false, true)); }, - ai:{ - order:13, - result:{ - target(player,target){ - return -target.getStockSkills(false,true).length; + ai: { + order: 13, + result: { + target(player, target) { + return -target.getStockSkills(false, true).length; }, }, }, @@ -1194,886 +1648,1107 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //关羽 //矢 - sbwusheng:{ - audio:3, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return game.hasPlayer(target=>target!=player&&!target.isZhu2()); + sbwusheng: { + audio: 3, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return game.hasPlayer((target) => target != player && !target.isZhu2()); }, - direct:true, - content:function*(event,map){ - var player=map.player; - var result=yield player.chooseTarget(get.prompt('sbwusheng'),'选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸'+(get.mode()==='identity'?'两':'一')+'张牌,对其使用三张【杀】后不能对其使用【杀】',(card,player,target)=>{ - return target!=player&&!target.isZhu2(); - }).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }); - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbwusheng',target); - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.25); - player.addTempSkill('sbwusheng_effect',{player:'phaseUseAfter'}); - player.storage.sbwusheng_effect[target.playerid]=0; + direct: true, + content: function* (event, map) { + var player = map.player; + var result = yield player + .chooseTarget( + get.prompt("sbwusheng"), + "选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸" + + (get.mode() === "identity" ? "两" : "一") + + "张牌,对其使用三张【杀】后不能对其使用【杀】", + (card, player, target) => { + return target != player && !target.isZhu2(); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbwusheng", target); + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.25); + player.addTempSkill("sbwusheng_effect", { player: "phaseUseAfter" }); + player.storage.sbwusheng_effect[target.playerid] = 0; } }, - group:'sbwusheng_wusheng', - subSkill:{ - wusheng:{ - audio:'sbwusheng', - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - return name=='sha'&&player.countCards('hs'); + group: "sbwusheng_wusheng", + subSkill: { + wusheng: { + audio: "sbwusheng", + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + return name == "sha" && player.countCards("hs"); }, - filter:function(event,player){ - return event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)||lib.inpile_nature.some(nature=>event.filterCard(get.autoViewAs({name:'sha',nature},'unsure'),player,event)); + filter: function (event, player) { + return ( + event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) || + lib.inpile_nature.some((nature) => + event.filterCard( + get.autoViewAs({ name: "sha", nature }, "unsure"), + player, + event + ) + ) + ); }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - if(event.filterCard({name:'sha'},player,event)) list.push(['基本','','sha']); - for(var j of lib.inpile_nature){ - if(event.filterCard({name:'sha',nature:j},player,event)) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + if (event.filterCard({ name: "sha" }, player, event)) + list.push(["基本", "", "sha"]); + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: "sha", nature: j }, player, event)) + list.push(["基本", "", "sha", j]); } - var dialog=ui.create.dialog('武圣',[list,'vcard'],'hidden'); - dialog.direct=true; + var dialog = ui.create.dialog("武圣", [list, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(_status.event.getParent().type=='phase'&&game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch (button.link[2]){ - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder'||button.link[3]=='ice') return 2.92; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + _status.event.getParent().type == "phase" && + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder" || button.link[3] == "ice") + return 2.92; else return 2.9; } } - return 1+Math.random(); + return 1 + Math.random(); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'sbwusheng', - filterCard:true, - check:function(card){ - return 6-get.value(card); + audio: "sbwusheng", + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - viewAs:{name:links[0][2],nature:links[0][3]}, - position:'hs', - popname:true, - } + viewAs: { name: links[0][2], nature: links[0][3] }, + position: "hs", + popname: true, + }; }, - prompt:function(links,player){ - return '将一张手牌当作'+get.translation(links[0][3]||'')+'【'+get.translation(links[0][2])+'】'+(_status.event.name=='chooseToUse'?'使用':'打出'); + prompt: function (links, player) { + return ( + "将一张手牌当作" + + get.translation(links[0][3] || "") + + "【" + + get.translation(links[0][2]) + + "】" + + (_status.event.name == "chooseToUse" ? "使用" : "打出") + ); }, }, - ai:{ - respondSha:true, - fireAttack:true, - skillTagFilter:function(player,tag){ - if(!player.countCards('hs')) return false; + ai: { + respondSha: true, + fireAttack: true, + skillTagFilter: function (player, tag) { + if (!player.countCards("hs")) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - if(lib.inpile_nature.some(i=>player.getUseValue({name:'sha',nature:i})>0)){ - var temp=get.order({name:'sha'}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + if ( + lib.inpile_nature.some( + (i) => player.getUseValue({ name: "sha", nature: i }) > 0 + ) + ) { + var temp = get.order({ name: "sha" }); + if (temp > max) max = temp; } - if(max>0) max+=0.3; + if (max > 0) max += 0.3; return max; } return 4; }, - result:{player:1}, + result: { player: 1 }, }, }, - effect:{ - charlotte:true, - onremove:true, - init:function(player){ - if(!player.storage.sbwusheng_effect) player.storage.sbwusheng_effect={}; + effect: { + charlotte: true, + onremove: true, + init: function (player) { + if (!player.storage.sbwusheng_effect) player.storage.sbwusheng_effect = {}; }, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&typeof player.storage.sbwusheng_effect[target.playerid]=='number') return true; + mod: { + targetInRange: function (card, player, target) { + if ( + card.name == "sha" && + typeof player.storage.sbwusheng_effect[target.playerid] == "number" + ) + return true; }, - cardUsableTarget:function(card,player,target){ - if(card.name!=='sha'||typeof player.storage.sbwusheng_effect[target.playerid]!=='number') return; - return player.storage.sbwusheng_effect[target.playerid]<3; + cardUsableTarget: function (card, player, target) { + if ( + card.name !== "sha" || + typeof player.storage.sbwusheng_effect[target.playerid] !== "number" + ) + return; + return player.storage.sbwusheng_effect[target.playerid] < 3; }, - playerEnabled:function(card,player,target){ - if(card.name!='sha'||typeof player.storage.sbwusheng_effect[target.playerid]!='number') return; - if(player.storage.sbwusheng_effect[target.playerid]>=3) return false; + playerEnabled: function (card, player, target) { + if ( + card.name != "sha" || + typeof player.storage.sbwusheng_effect[target.playerid] != "number" + ) + return; + if (player.storage.sbwusheng_effect[target.playerid] >= 3) return false; }, }, - audio:'sbwusheng', - trigger:{player:['useCardToPlayered','useCardAfter']}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.name=='useCard') return event.targets.some(target=>typeof player.storage.sbwusheng_effect[target.playerid]=='number'); - return typeof player.storage.sbwusheng_effect[event.target.playerid]=='number'; + audio: "sbwusheng", + trigger: { player: ["useCardToPlayered", "useCardAfter"] }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.name == "useCard") + return event.targets.some( + (target) => + typeof player.storage.sbwusheng_effect[target.playerid] == "number" + ); + return typeof player.storage.sbwusheng_effect[event.target.playerid] == "number"; }, - direct:true, - content:function(){ - if(trigger.name=='useCard'){ - var targets=trigger.targets.filter(target=>typeof player.storage.sbwusheng_effect[target.playerid]=='number'); - targets.forEach(target=>player.storage.sbwusheng_effect[target.playerid]++); - } - else{ - player.logSkill('sbwusheng_effect',trigger.target); - player.draw(get.mode()==='identity'?2:1); + direct: true, + content: function () { + if (trigger.name == "useCard") { + var targets = trigger.targets.filter( + (target) => + typeof player.storage.sbwusheng_effect[target.playerid] == "number" + ); + targets.forEach( + (target) => player.storage.sbwusheng_effect[target.playerid]++ + ); + } else { + player.logSkill("sbwusheng_effect", trigger.target); + player.draw(get.mode() === "identity" ? 2 : 1); } }, }, }, - ai:{threaten:114514}, + ai: { threaten: 114514 }, }, - sbyijue:{ - audio:2, - trigger:{global:'damageBegin4'}, - filter:function(event,player){ - if(!event.source||event.source!=player||event.player==player) return false; - return event.num>=event.player.hp&&!player.getStorage('sbyijue').includes(event.player); + sbyijue: { + audio: 2, + trigger: { global: "damageBegin4" }, + filter: function (event, player) { + if (!event.source || event.source != player || event.player == player) return false; + return ( + event.num >= event.player.hp && !player.getStorage("sbyijue").includes(event.player) + ); }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { trigger.cancel(); - player.addTempSkill('sbyijue_effect'); - player.markAuto('sbyijue',[trigger.player]); - player.markAuto('sbyijue_effect',[trigger.player]); + player.addTempSkill("sbyijue_effect"); + player.markAuto("sbyijue", [trigger.player]); + player.markAuto("sbyijue_effect", [trigger.player]); }, - marktext:'绝', - intro:{content:'已放$一马'}, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - audio:'sbyijue', - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - return player.getStorage('sbyijue_effect').includes(event.target); + marktext: "绝", + intro: { content: "已放$一马" }, + subSkill: { + effect: { + charlotte: true, + onremove: true, + audio: "sbyijue", + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + return player.getStorage("sbyijue_effect").includes(event.target); }, - forced:true, - logTarget:'target', - content:function(){ + forced: true, + logTarget: "target", + content: function () { trigger.getParent().excluded.add(trigger.target); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(player.getStorage('sbyijue_effect').includes(target)) return 'zeroplayertarget'; + ai: { + effect: { + player: function (card, player, target) { + if (player.getStorage("sbyijue_effect").includes(target)) + return "zeroplayertarget"; }, }, }, - marktext:'义', - intro:{content:'本回合放$一马'}, + marktext: "义", + intro: { content: "本回合放$一马" }, }, }, }, //黄月英 - sbqicai:{ - mod:{ - targetInRange:function(card,player,target){ - if(get.type2(card)=='trick') return true; + sbqicai: { + mod: { + targetInRange: function (card, player, target) { + if (get.type2(card) == "trick") return true; }, }, - locked:false, - getLimit:3, - audio:2, - enable:'phaseUse', - onChooseToUse:function(event){ - if(!event.sbqicai&&!game.online){ - const player=get.player(); - const cards=Array.from(ui.discardPile.childNodes).filter(card=>lib.skill.sbqicai.filterCardx(card,player)); - event.set('sbqicai',cards); + locked: false, + getLimit: 3, + audio: 2, + enable: "phaseUse", + onChooseToUse: function (event) { + if (!event.sbqicai && !game.online) { + const player = get.player(); + const cards = Array.from(ui.discardPile.childNodes).filter((card) => + lib.skill.sbqicai.filterCardx(card, player) + ); + event.set("sbqicai", cards); } }, - filter:function(event,player){ - return player.countCards('h',card=>lib.skill.sbqicai.filterCardx(card,player))||event.sbqicai&&event.sbqicai.length; + filter: function (event, player) { + return ( + player.countCards("h", (card) => lib.skill.sbqicai.filterCardx(card, player)) || + (event.sbqicai && event.sbqicai.length) + ); }, - filterCardx:function(card,player){ - if(player.getStorage('sbqicai').includes(card.name)) return false; - return get.type(card)=='equip'&&game.hasPlayer(target=>target!=player&&target.hasEmptySlot(get.subtype(card))); + filterCardx: function (card, player) { + if (player.getStorage("sbqicai").includes(card.name)) return false; + return ( + get.type(card) == "equip" && + game.hasPlayer((target) => target != player && target.hasEmptySlot(get.subtype(card))) + ); }, - usable:1, - chooseButton:{ - dialog:function(event,player){ - const list1=player.getCards('h',card=>lib.skill.sbqicai.filterCardx(card,player)); - const list2=event.sbqicai; - var dialog=ui.create.dialog('###奇才###
              请选择一张装备牌置入一名其他角色的装备区
              '); - if(list1.length){ + usable: 1, + chooseButton: { + dialog: function (event, player) { + const list1 = player.getCards("h", (card) => + lib.skill.sbqicai.filterCardx(card, player) + ); + const list2 = event.sbqicai; + var dialog = ui.create.dialog( + '###奇才###
              请选择一张装备牌置入一名其他角色的装备区
              ' + ); + if (list1.length) { dialog.add('
              手牌区
              '); dialog.add(list1); } - if(list2.length){ + if (list2.length) { dialog.add('
              弃牌堆
              '); dialog.add(list2); - if(list1.length) dialog.classList.add('fullheight'); + if (list1.length) dialog.classList.add("fullheight"); } return dialog; }, - check:function(button){ - var player=_status.event.player; - var num=get.value(button.link); - if(!game.hasPlayer(target=>target!=player&&target.hasEmptySlot(get.subtype(button.link))&&get.attitude(player,target)>0)) num=1/(get.value(button.link)||0.5); - if(get.owner(button.link)) return num; - return num*5; + check: function (button) { + var player = _status.event.player; + var num = get.value(button.link); + if ( + !game.hasPlayer( + (target) => + target != player && + target.hasEmptySlot(get.subtype(button.link)) && + get.attitude(player, target) > 0 + ) + ) + num = 1 / (get.value(button.link) || 0.5); + if (get.owner(button.link)) return num; + return num * 5; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'sbqicai', - card:links[0], - filterCard:function(card,player){ - var cardx=lib.skill.sbqicai_backup.card; - if(get.owner(cardx)) return card==cardx; + audio: "sbqicai", + card: links[0], + filterCard: function (card, player) { + var cardx = lib.skill.sbqicai_backup.card; + if (get.owner(cardx)) return card == cardx; return false; }, - selectCard:-1, - filterTarget:function(card,player,target){ - return target!=player&&target.canEquip(lib.skill.sbqicai_backup.card); + selectCard: -1, + filterTarget: function (card, player, target) { + return target != player && target.canEquip(lib.skill.sbqicai_backup.card); }, - check:()=>1, - discard:false, - lose:false, - prepare:function(cards,player,targets){ - if(cards&&cards.length) player.$give(cards,targets[0],false); + check: () => 1, + discard: false, + lose: false, + prepare: function (cards, player, targets) { + if (cards && cards.length) player.$give(cards, targets[0], false); }, - content:function(){ - if(!cards||!cards.length){ - cards=[lib.skill.sbqicai_backup.card]; + content: function () { + if (!cards || !cards.length) { + cards = [lib.skill.sbqicai_backup.card]; target.$gain2(cards); game.delayx(); } - if(get.mode()=='doudizhu') player.markAuto('sbqicai',[cards[0].name]); + if (get.mode() == "doudizhu") player.markAuto("sbqicai", [cards[0].name]); target.equip(cards[0]); - player.addSkill('sbqicai_gain'); - lib.skill.sbqicai.updateCounter(player,target,0); + player.addSkill("sbqicai_gain"); + lib.skill.sbqicai.updateCounter(player, target, 0); }, - ai:{ - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - if(att>0) return 3; - if(att<0) return -1; + ai: { + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if (att > 0) return 3; + if (att < 0) return -1; return 0; }, }, }, - } + }; }, - prompt:function(links,player){ - return '请选择置入'+get.translation(links)+'的角色'; + prompt: function (links, player) { + return "请选择置入" + get.translation(links) + "的角色"; }, }, - updateCounter:function(player,target,num){ - const skill=`sbqicai_${player.playerid}`; - game.broadcastAll(lib.skill.sbqicai.initSkill,skill); - if(!target.hasSkill(skill)) target.addSkill(skill); - if(num==0) target.clearMark(skill,false); - else if(num>0) target.addMark(skill,num,false); - if(target.countMark(skill)>=lib.skill.sbqicai.getLimit) target.removeSkill(skill); - if(!_status.postReconnect.sbqicai){ - _status.postReconnect.sbqicai=[ - lib.skill.sbqicai.initSkill, - [] - ]; + updateCounter: function (player, target, num) { + const skill = `sbqicai_${player.playerid}`; + game.broadcastAll(lib.skill.sbqicai.initSkill, skill); + if (!target.hasSkill(skill)) target.addSkill(skill); + if (num == 0) target.clearMark(skill, false); + else if (num > 0) target.addMark(skill, num, false); + if (target.countMark(skill) >= lib.skill.sbqicai.getLimit) target.removeSkill(skill); + if (!_status.postReconnect.sbqicai) { + _status.postReconnect.sbqicai = [lib.skill.sbqicai.initSkill, []]; } _status.postReconnect.sbqicai[1].add(skill); }, - initSkill:skill=>{ - if(!lib.skill[skill]){ - lib.skill[skill]={ - onremove:true, - mark:true, - marktext:'奇', - intro:{ - markcount:function(storage){ - return (storage||0).toString(); + initSkill: (skill) => { + if (!lib.skill[skill]) { + lib.skill[skill] = { + onremove: true, + mark: true, + marktext: "奇", + intro: { + markcount: function (storage) { + return (storage || 0).toString(); }, - content:function(storage){ - return '已被掠夺'+get.cnNumber(storage||0)+'张普通锦囊牌'; + content: function (storage) { + return "已被掠夺" + get.cnNumber(storage || 0) + "张普通锦囊牌"; }, }, }; - lib.translate[skill]='奇才'; - lib.translate[skill+'_bg']='奇'; + lib.translate[skill] = "奇才"; + lib.translate[skill + "_bg"] = "奇"; } }, - ai:{ - order:7, - result:{ - player:function(player){ - if(!game.hasPlayer(target=>target!=player&&target.hasEmptySlot(2)&&get.attitude(player,target)!=0)) return 0; + ai: { + order: 7, + result: { + player: function (player) { + if ( + !game.hasPlayer( + (target) => + target != player && + target.hasEmptySlot(2) && + get.attitude(player, target) != 0 + ) + ) + return 0; return 1; }, }, }, - marktext:'才', - intro:{content:'已使用$发动过此技能'}, - subSkill:{ - gain:{ - audio:'sbqicai', - trigger:{global:['gainAfter','loseAsyncAfter']}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - if(!event.getg(current).length||!current.hasSkill('sbqicai_'+player.playerid)) return false; - if(current.countMark('sbqicai_'+player.playerid)>=lib.skill.sbqicai.getLimit) return false; - return event.getg(current).some(card=>get.type(card)=='trick'&&lib.filter.canBeGained(card,current,player)); + marktext: "才", + intro: { content: "已使用$发动过此技能" }, + subSkill: { + gain: { + audio: "sbqicai", + trigger: { global: ["gainAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + if ( + !event.getg(current).length || + !current.hasSkill("sbqicai_" + player.playerid) + ) + return false; + if ( + current.countMark("sbqicai_" + player.playerid) >= + lib.skill.sbqicai.getLimit + ) + return false; + return event + .getg(current) + .some( + (card) => + get.type(card) == "trick" && + lib.filter.canBeGained(card, current, player) + ); }); }, - forced:true, - direct:true, - charlotte:true, - content:function(){ - 'step 0' - if(!event.checkedTargets) event.checkedTargets=[]; - var target=game.findPlayer(function(current){ - if(!trigger.getg(current).length||!current.hasSkill('sbqicai_'+player.playerid)) return false; - if(event.checkedTargets.includes(current)) return false; - if(current.countMark('sbqicai_'+player.playerid)>=lib.skill.sbqicai.getLimit) return false; - return trigger.getg(current).some(card=>get.type(card)=='trick'&&lib.filter.canBeGained(card,current,player)); + forced: true, + direct: true, + charlotte: true, + content: function () { + "step 0"; + if (!event.checkedTargets) event.checkedTargets = []; + var target = game.findPlayer(function (current) { + if ( + !trigger.getg(current).length || + !current.hasSkill("sbqicai_" + player.playerid) + ) + return false; + if (event.checkedTargets.includes(current)) return false; + if ( + current.countMark("sbqicai_" + player.playerid) >= + lib.skill.sbqicai.getLimit + ) + return false; + return trigger + .getg(current) + .some( + (card) => + get.type(card) == "trick" && + lib.filter.canBeGained(card, current, player) + ); }); - if(!target){ + if (!target) { event.finish(); return; } - event.target=target; - player.logSkill('sbqicai_gain',target); + event.target = target; + player.logSkill("sbqicai_gain", target); event.checkedTargets.add(target); - var cards=trigger.getg(target).filter(card=>get.type(card)=='trick'&&lib.filter.canBeGained(card,target,player)); - if(cards.length<=lib.skill.sbqicai.getLimit-target.countMark('sbqicai_'+player.playerid)) event._result={bool:true,links:cards}; - else{ - var num=(lib.skill.sbqicai.getLimit-target.countMark('sbqicai_'+player.playerid)); - target.chooseButton(['奇才:将其中'+get.cnNumber(num)+'张牌交给'+get.translation(player),cards],num,true).set('ai',function(button){ - return get.value(button.link)*get.sgn(_status.event.att); - }).set('att',get.attitude(target,player)); + var cards = trigger + .getg(target) + .filter( + (card) => + get.type(card) == "trick" && + lib.filter.canBeGained(card, target, player) + ); + if ( + cards.length <= + lib.skill.sbqicai.getLimit - target.countMark("sbqicai_" + player.playerid) + ) + event._result = { bool: true, links: cards }; + else { + var num = + lib.skill.sbqicai.getLimit - + target.countMark("sbqicai_" + player.playerid); + target + .chooseButton( + [ + "奇才:将其中" + + get.cnNumber(num) + + "张牌交给" + + get.translation(player), + cards, + ], + num, + true + ) + .set("ai", function (button) { + return get.value(button.link) * get.sgn(_status.event.att); + }) + .set("att", get.attitude(target, player)); } - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { game.delaye(0.5); - target.give(result.links,player); - lib.skill.sbqicai.updateCounter(player,target,result.links.length); + target.give(result.links, player); + lib.skill.sbqicai.updateCounter(player, target, result.links.length); } event.goto(0); }, }, }, }, - sbjizhi:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - return get.type(event.card)=='trick'; + sbjizhi: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + return get.type(event.card) == "trick"; }, - forced:true, - content:function(){ - player.draw().gaintag=['sbjizhi']; - player.addTempSkill('sbjizhi_mark') + forced: true, + content: function () { + player.draw().gaintag = ["sbjizhi"]; + player.addTempSkill("sbjizhi_mark"); }, - subSkill:{ - mark:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('sbjizhi'); + subSkill: { + mark: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("sbjizhi"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('sbjizhi')) return true; + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("sbjizhi")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('sbjizhi')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("sbjizhi")) return false; }, }, }, }, }, //诸葛亮 - sbhuoji:{ - audio:3, - dutySkill:true, - derivation:['sbguanxing','sbkongcheng'], - group:['sbhuoji_fire','sbhuoji_achieve','sbhuoji_fail','sbhuoji_mark'], - subSkill:{ - fire:{ - audio:'sbhuoji1.mp3', - enable:'phaseUse', - filterTarget:lib.filter.notMe, - prompt:'选择一名其他角色,对其与其势力相同的所有其他角色各造成1点火属性伤害', - usable:1, - line:'fire', - content:function(){ - 'step 0' - target.damage('fire'); - 'step 1' - var targets=game.filterPlayer(current=>{ - if(current==player||current==target) return false; - return current.group==target.group; + sbhuoji: { + audio: 3, + dutySkill: true, + derivation: ["sbguanxing", "sbkongcheng"], + group: ["sbhuoji_fire", "sbhuoji_achieve", "sbhuoji_fail", "sbhuoji_mark"], + subSkill: { + fire: { + audio: "sbhuoji1.mp3", + enable: "phaseUse", + filterTarget: lib.filter.notMe, + prompt: "选择一名其他角色,对其与其势力相同的所有其他角色各造成1点火属性伤害", + usable: 1, + line: "fire", + content: function () { + "step 0"; + target.damage("fire"); + "step 1"; + var targets = game.filterPlayer((current) => { + if (current == player || current == target) return false; + return current.group == target.group; }); - if(targets.length){ + if (targets.length) { game.delayx(); - player.line(targets,'fire'); - targets.forEach(i=>i.damage('fire')); + player.line(targets, "fire"); + targets.forEach((i) => i.damage("fire")); } }, - ai:{ - order:7, - fireAttack:true, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - return get.sgn(att)*game.filterPlayer(current=>{ - if(current==player) return false; - return current.group==target.group; - }).reduce((num,current)=>num+get.damageEffect(current,player,player,'fire'),0); + ai: { + order: 7, + fireAttack: true, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + return ( + get.sgn(att) * + game + .filterPlayer((current) => { + if (current == player) return false; + return current.group == target.group; + }) + .reduce( + (num, current) => + num + get.damageEffect(current, player, player, "fire"), + 0 + ) + ); }, }, }, }, - achieve:{ - audio:'sbhuoji2.mp3', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getAllHistory('sourceDamage',evt=>evt.hasNature('fire')).reduce((num,evt)=>num+evt.num,0)>=game.players.length+game.dead.length; + achieve: { + audio: "sbhuoji2.mp3", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return ( + player + .getAllHistory("sourceDamage", (evt) => evt.hasNature("fire")) + .reduce((num, evt) => num + evt.num, 0) >= + game.players.length + game.dead.length + ); }, - forced:true, - locked:false, - skillAnimation:true, - animationColor:'fire', - async content(event,trigger,player){ - player.awakenSkill('sbhuoji'); - game.log(player,'成功完成使命'); - player.changeSkin('sbhuoji','sb_zhugeliang'); - player.changeSkills(['sbguanxing','sbkongcheng'],['sbhuoji','sbkanpo']); + forced: true, + locked: false, + skillAnimation: true, + animationColor: "fire", + async content(event, trigger, player) { + player.awakenSkill("sbhuoji"); + game.log(player, "成功完成使命"); + player.changeSkin("sbhuoji", "sb_zhugeliang"); + player.changeSkills(["sbguanxing", "sbkongcheng"], ["sbhuoji", "sbkanpo"]); }, }, - fail:{ - audio:'sbhuoji3.mp3', - trigger:{player:'dying'}, - forced:true, - locked:false, - content:function(){ - player.awakenSkill('sbhuoji'); - game.log(player,'使命失败'); + fail: { + audio: "sbhuoji3.mp3", + trigger: { player: "dying" }, + forced: true, + locked: false, + content: function () { + player.awakenSkill("sbhuoji"); + game.log(player, "使命失败"); }, }, - mark:{ - charlotte:true, - trigger:{source:'damage'}, - filter:function(event,player){ - return event.hasNature('fire'); + mark: { + charlotte: true, + trigger: { source: "damage" }, + filter: function (event, player) { + return event.hasNature("fire"); }, - firstDo:true, - forced:true, - popup:false, - content:function(){ - player.addTempSkill('sbhuoji_count',{player:['sbhuoji_achieveBegin','sbhuoji_failBegin']}); - player.storage.sbhuoji_count=player.getAllHistory('sourceDamage',evt=>evt.hasNature('fire')).reduce((num,evt)=>num+evt.num,0); - player.markSkill('sbhuoji_count'); + firstDo: true, + forced: true, + popup: false, + content: function () { + player.addTempSkill("sbhuoji_count", { + player: ["sbhuoji_achieveBegin", "sbhuoji_failBegin"], + }); + player.storage.sbhuoji_count = player + .getAllHistory("sourceDamage", (evt) => evt.hasNature("fire")) + .reduce((num, evt) => num + evt.num, 0); + player.markSkill("sbhuoji_count"); }, }, - count:{ - charlotte:true, - intro:{content:'本局游戏已造成过#点火属性伤害'}, + count: { + charlotte: true, + intro: { content: "本局游戏已造成过#点火属性伤害" }, }, }, }, - sbkanpo:{ - init:function(player){ - if(!player.storage.sbkanpo){ - player.storage.sbkanpo=[(get.mode()=='doudizhu'||(get.mode()=='versus'&&_status.mode=='two'))?2:4,[],[]]; - player.markSkill('sbkanpo'); + sbkanpo: { + init: function (player) { + if (!player.storage.sbkanpo) { + player.storage.sbkanpo = [ + get.mode() == "doudizhu" || (get.mode() == "versus" && _status.mode == "two") + ? 2 + : 4, + [], + [], + ]; + player.markSkill("sbkanpo"); } }, - audio:2, - trigger:{global:'roundStart'}, - filter:function(event,player){ - var storage=player.storage.sbkanpo; - return storage[0]||storage[1].length; + audio: 2, + trigger: { global: "roundStart" }, + filter: function (event, player) { + var storage = player.storage.sbkanpo; + return storage[0] || storage[1].length; }, - forced:true, - locked:false, - content:function*(event,map){ - var player=map.player,storage=player.storage.sbkanpo; - var sum=storage[0]; - storage[1]=[]; - player.markSkill('sbkanpo'); - if(!sum) return; - const list=get.inpileVCardList(info=>{ - if(info[2]=='sha'&&info[3]) return false; - return info[0]!='equip'; + forced: true, + locked: false, + content: function* (event, map) { + var player = map.player, + storage = player.storage.sbkanpo; + var sum = storage[0]; + storage[1] = []; + player.markSkill("sbkanpo"); + if (!sum) return; + const list = get.inpileVCardList((info) => { + if (info[2] == "sha" && info[3]) return false; + return info[0] != "equip"; }); - const func=()=>{ - const event=get.event(); - const controls=[link=>{ - const evt=get.event(); - if(evt.dialog&&evt.dialog.buttons){ - for(let i=0;i=Math.max(3,game.countPlayer()/2)) return 0; - switch(button.link[2]){ - case 'wuxie':return 5+Math.random(); - case 'sha':return 5+Math.random(); - case 'tao':return 4+Math.random(); - case 'jiu':return 3+Math.random(); - case 'lebu':return 3+Math.random(); - case 'shan':return 4.5+Math.random(); - case 'wuzhong':return 4+Math.random(); - case 'shunshou':return 2.7+Math.random(); - case 'nanman':return 2+Math.random(); - case 'wanjian':return 1.6+Math.random(); - default:return 1.5+Math.random(); - } - }).set('filterButton',button=>{ - return !_status.event.names.includes(button.link[2]); - }).set('names',storage[2]).set('custom',{ - add:{ - confirm:function(bool){ - if(bool!=true) return; - const event=get.event().parent; - if(event.controls) event.controls.forEach(i=>i.close()); - if(ui.confirm) ui.confirm.close(); - game.uncheck(); - }, - button:function(){ - if(ui.selected.buttons.length) return; - const event=get.event(); - if(event.dialog&&event.dialog.buttons){ - for(let i=0;i { + const event = get.event(); + const controls = [ + (link) => { + const evt = get.event(); + if (evt.dialog && evt.dialog.buttons) { + for (let i = 0; i < evt.dialog.buttons.length; i++) { + const button = evt.dialog.buttons[i]; + button.classList.remove("selectable"); + button.classList.remove("selected"); + const counterNode = button.querySelector(".caption"); + if (counterNode) { + counterNode.childNodes[0].innerHTML = ``; } } + ui.selected.buttons.length = 0; + game.check(); } - if(!ui.selected.buttons.length){ - const evt=event.parent; - if(evt.controls) evt.controls[0].classList.add('disabled'); - } + return; }, - }, - replace:{ - button:function(button){ - const event=get.event(),sum=event.sum; - if(!event.isMine()) return; - if(button.classList.contains('selectable')==false) return; - if(ui.selected.buttons.length>=sum) return false; - button.classList.add('selected'); - ui.selected.buttons.push(button); - let counterNode=button.querySelector('.caption'); - const count=ui.selected.buttons.filter(i=>i==button).length; - if(counterNode){ - counterNode=counterNode.childNodes[0]; - counterNode.innerHTML=`×${count}`; - } - else{ - counterNode=ui.create.caption(`×${count}`,button); - counterNode.style.right='5px'; - counterNode.style.bottom='2px'; - } - const evt=event.parent; - if(evt.controls) evt.controls[0].classList.remove('disabled'); - game.check(); + ]; + event.controls = [ui.create.control(controls.concat(["清除选择", "stayleft"]))]; + }; + if (event.isMine()) func(); + else if (event.isOnline()) event.player.send(func); + var result = yield player + .chooseButton( + ["看破:是否记录至多" + get.cnNumber(sum) + "个牌名?", [list, "vcard"]], + [1, sum], + false + ) + .set("ai", function (button) { + if (ui.selected.buttons.length >= Math.max(3, game.countPlayer() / 2)) return 0; + switch (button.link[2]) { + case "wuxie": + return 5 + Math.random(); + case "sha": + return 5 + Math.random(); + case "tao": + return 4 + Math.random(); + case "jiu": + return 3 + Math.random(); + case "lebu": + return 3 + Math.random(); + case "shan": + return 4.5 + Math.random(); + case "wuzhong": + return 4 + Math.random(); + case "shunshou": + return 2.7 + Math.random(); + case "nanman": + return 2 + Math.random(); + case "wanjian": + return 1.6 + Math.random(); + default: + return 1.5 + Math.random(); + } + }) + .set("filterButton", (button) => { + return !_status.event.names.includes(button.link[2]); + }) + .set("names", storage[2]) + .set("custom", { + add: { + confirm: function (bool) { + if (bool != true) return; + const event = get.event().parent; + if (event.controls) event.controls.forEach((i) => i.close()); + if (ui.confirm) ui.confirm.close(); + game.uncheck(); + }, + button: function () { + if (ui.selected.buttons.length) return; + const event = get.event(); + if (event.dialog && event.dialog.buttons) { + for (let i = 0; i < event.dialog.buttons.length; i++) { + const button = event.dialog.buttons[i]; + const counterNode = button.querySelector(".caption"); + if (counterNode) { + counterNode.childNodes[0].innerHTML = ``; + } + } + } + if (!ui.selected.buttons.length) { + const evt = event.parent; + if (evt.controls) evt.controls[0].classList.add("disabled"); + } + }, }, - } - }).set('sum',sum) - if(result.bool){ - var names=result.links.map(link=>link[2]); - storage[0]-=names.length; - storage[1]=names; - storage[2]=names; - } - else storage[2]=[]; - player.markSkill('sbkanpo'); + replace: { + button: function (button) { + const event = get.event(), + sum = event.sum; + if (!event.isMine()) return; + if (button.classList.contains("selectable") == false) return; + if (ui.selected.buttons.length >= sum) return false; + button.classList.add("selected"); + ui.selected.buttons.push(button); + let counterNode = button.querySelector(".caption"); + const count = ui.selected.buttons.filter((i) => i == button).length; + if (counterNode) { + counterNode = counterNode.childNodes[0]; + counterNode.innerHTML = `×${count}`; + } else { + counterNode = ui.create.caption( + `×${count}`, + button + ); + counterNode.style.right = "5px"; + counterNode.style.bottom = "2px"; + } + const evt = event.parent; + if (evt.controls) evt.controls[0].classList.remove("disabled"); + game.check(); + }, + }, + }) + .set("sum", sum); + if (result.bool) { + var names = result.links.map((link) => link[2]); + storage[0] -= names.length; + storage[1] = names; + storage[2] = names; + } else storage[2] = []; + player.markSkill("sbkanpo"); }, - marktext:'破', - intro:{ - markcount:function(storage){ + marktext: "破", + intro: { + markcount: function (storage) { return storage[1].length; }, - mark:function(dialog,content,player){ - const storage=player.getStorage('sbkanpo'); - const sum=storage[0]; - const names=storage[1]; - dialog.addText('剩余可记录'+sum+'次牌名'); - if(player.isUnderControl(true)&&names.length){ - dialog.addText('当前记录牌名:'); - dialog.addSmall([names,'vcard']); + mark: function (dialog, content, player) { + const storage = player.getStorage("sbkanpo"); + const sum = storage[0]; + const names = storage[1]; + dialog.addText("剩余可记录" + sum + "次牌名"); + if (player.isUnderControl(true) && names.length) { + dialog.addText("当前记录牌名:"); + dialog.addSmall([names, "vcard"]); } }, }, - group:'sbkanpo_kanpo', - subSkill:{ - kanpo:{ - audio:'sbkanpo', - trigger:{global:'useCard'}, - filter:function(event,player){ - return event.player!=player&&player.storage.sbkanpo[1].includes(event.card.name); + group: "sbkanpo_kanpo", + subSkill: { + kanpo: { + audio: "sbkanpo", + trigger: { global: "useCard" }, + filter: function (event, player) { + return ( + event.player != player && player.storage.sbkanpo[1].includes(event.card.name) + ); }, - prompt2:function(event,player){ - return '移除'+get.translation(event.card.name)+'的记录,令'+get.translation(event.card)+'无效'; + prompt2: function (event, player) { + return ( + "移除" + + get.translation(event.card.name) + + "的记录,令" + + get.translation(event.card) + + "无效" + ); }, - check:function(event,player){ - var effect=0; - if(event.card.name=='wuxie'||event.card.name=='shan'){ - if(get.attitude(player,event.player)<-1) effect=-1; - } - else if(event.targets&&event.targets.length){ - for(var i=0;icard.hasGaintag('sbguanxing'),'s'); - if(event.name=='phaseZhunbei'){ - return bool||7-lib.skill.sbguanxing.getNum*player.countMark('sbguanxingx')>0; + sbguanxing: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + filter: function (event, player) { + var bool = player.hasCard((card) => card.hasGaintag("sbguanxing"), "s"); + if (event.name == "phaseZhunbei") { + return bool || 7 - lib.skill.sbguanxing.getNum * player.countMark("sbguanxingx") > 0; } - return bool&&player.hasSkill('sbguanxing_on'); + return bool && player.hasSkill("sbguanxing_on"); }, - forced:true, - locked:false, - content:function(){ - 'step 0' - if(trigger.name=='phaseJieshu'){ + forced: true, + locked: false, + content: function () { + "step 0"; + if (trigger.name == "phaseJieshu") { event.goto(2); return; } - player.addMark('sbguanxingx',1,false); - var cards=player.getCards('s',card=>card.hasGaintag('sbguanxing')); - if(cards.length) player.loseToDiscardpile(cards); - var num=player.countMark('sbguanxingx')-1; - event.num=Math.max(0,7-lib.skill.sbguanxing.getNum*num); - 'step 1' - if(num){ - var cards2=get.cards(num); - player.$gain2(cards2,false); - game.log(player,'将',cards2,'置于了武将牌上'); - player.loseToSpecial(cards2,'sbguanxing').visible=true; - player.markSkill('sbguanxing'); + player.addMark("sbguanxingx", 1, false); + var cards = player.getCards("s", (card) => card.hasGaintag("sbguanxing")); + if (cards.length) player.loseToDiscardpile(cards); + var num = player.countMark("sbguanxingx") - 1; + event.num = Math.max(0, 7 - lib.skill.sbguanxing.getNum * num); + "step 1"; + if (num) { + var cards2 = get.cards(num); + player.$gain2(cards2, false); + game.log(player, "将", cards2, "置于了武将牌上"); + player.loseToSpecial(cards2, "sbguanxing").visible = true; + player.markSkill("sbguanxing"); } - 'step 2' - var cards=player.getCards('s',card=>card.hasGaintag('sbguanxing')); - if(cards.length){ - player.chooseToMove().set('list',[ - ['你的“星”',cards], - ['牌堆顶'], - ]).set('prompt','观星:点击将牌移动到牌堆顶').set('processAI',function(list){ - var cards=list[0][1].slice(),player=_status.event.player; - var name=_status.event.getTrigger().name; - var target=(name=='phaseZhunbei'?player:player.getNext()); - var judges=target.getCards('j'); - var top=[],att=get.sgn(get.attitude(player,target)); - if(judges.length&&att!=0&&(target!=player||!player.hasWuxie())){ - for(var i=0;iget.judge(card)*num; - cards.sort((a,b)=>judge(b,att)-judge(a,att)); - if(judge(cards[0],att)<0) break; - else top.unshift(cards.shift()); + "step 2"; + var cards = player.getCards("s", (card) => card.hasGaintag("sbguanxing")); + if (cards.length) { + player + .chooseToMove() + .set("list", [["你的“星”", cards], ["牌堆顶"]]) + .set("prompt", "观星:点击将牌移动到牌堆顶") + .set("processAI", function (list) { + var cards = list[0][1].slice(), + player = _status.event.player; + var name = _status.event.getTrigger().name; + var target = name == "phaseZhunbei" ? player : player.getNext(); + var judges = target.getCards("j"); + var top = [], + att = get.sgn(get.attitude(player, target)); + if (judges.length && att != 0 && (target != player || !player.hasWuxie())) { + for (var i = 0; i < judges.length; i++) { + var judge = (card, num) => get.judge(card) * num; + cards.sort((a, b) => judge(b, att) - judge(a, att)); + if (judge(cards[0], att) < 0) break; + else top.unshift(cards.shift()); + } } - } - return [cards,top]; - }).set('filterOk',function(moved){ - return moved[1].length; - }); - } - else event._result={bool:false}; - 'step 3' - if(result.bool){ - var cards=result.moved[1]; - player.loseToDiscardpile(cards,ui.cardPile,'insert').log=false; - game.log(player,'将',cards,'置于了牌堆顶'); - } - else if(trigger.name=='phaseZhunbei') player.addTempSkill('sbguanxing_on'); + return [cards, top]; + }) + .set("filterOk", function (moved) { + return moved[1].length; + }); + } else event._result = { bool: false }; + "step 3"; + if (result.bool) { + var cards = result.moved[1]; + player.loseToDiscardpile(cards, ui.cardPile, "insert").log = false; + game.log(player, "将", cards, "置于了牌堆顶"); + } else if (trigger.name == "phaseZhunbei") player.addTempSkill("sbguanxing_on"); }, - getNum:3, - group:'sbguanxing_unmark', - subSkill:{ - on:{charlotte:true}, - unmark:{ - trigger:{player:'loseAfter'}, - filter:function(event,player){ - if(!event.ss||!event.ss.length) return false; - return !player.countCards('s',card=>card.hasGaintag('sbguanxing')); + getNum: 3, + group: "sbguanxing_unmark", + subSkill: { + on: { charlotte: true }, + unmark: { + trigger: { player: "loseAfter" }, + filter: function (event, player) { + if (!event.ss || !event.ss.length) return false; + return !player.countCards("s", (card) => card.hasGaintag("sbguanxing")); }, - charlotte:true, - forced:true, - silent:true, - content:function(){ - player.unmarkSkill('sbguanxing'); + charlotte: true, + forced: true, + silent: true, + content: function () { + player.unmarkSkill("sbguanxing"); }, }, }, - marktext:'星', - intro:{ - mark:function(dialog,storage,player){ - var cards=player.getCards('s',card=>card.hasGaintag('sbguanxing')); - if(!cards||!cards.length) return; + marktext: "星", + intro: { + mark: function (dialog, storage, player) { + var cards = player.getCards("s", (card) => card.hasGaintag("sbguanxing")); + if (!cards || !cards.length) return; dialog.addAuto(cards); }, - markcount:function(storage,player){ - return player.countCards('s',card=>card.hasGaintag('sbguanxing')); + markcount: function (storage, player) { + return player.countCards("s", (card) => card.hasGaintag("sbguanxing")); }, - onunmark:function(storage,player){ - var cards=player.getCards('s',card=>card.hasGaintag('sbguanxing')); - if(cards.length) player.loseToDiscardpile(cards); + onunmark: function (storage, player) { + var cards = player.getCards("s", (card) => card.hasGaintag("sbguanxing")); + if (cards.length) player.loseToDiscardpile(cards); }, }, - mod:{ - aiOrder:function(player,card,num){ - var cards=player.getCards('s',card=>card.hasGaintag('sbguanxing')); - if(get.itemtype(card)=='card'&&card.hasGaintag('sbguanxing')) return num+(cards.length>1?0.5:-0.0001); + mod: { + aiOrder: function (player, card, num) { + var cards = player.getCards("s", (card) => card.hasGaintag("sbguanxing")); + if (get.itemtype(card) == "card" && card.hasGaintag("sbguanxing")) + return num + (cards.length > 1 ? 0.5 : -0.0001); }, }, }, - sbkongcheng:{ - audio:2, - trigger:{player:['damageBegin3','damageBegin4']}, - filter:function(event,player,name){ - if(!player.hasSkill('sbguanxing')) return false; - const num=player.countCards('s',card=>card.hasGaintag('sbguanxing')); - if(name=='damageBegin3'&&!num) return true; - if(name=='damageBegin4'&&num) return true; + sbkongcheng: { + audio: 2, + trigger: { player: ["damageBegin3", "damageBegin4"] }, + filter: function (event, player, name) { + if (!player.hasSkill("sbguanxing")) return false; + const num = player.countCards("s", (card) => card.hasGaintag("sbguanxing")); + if (name == "damageBegin3" && !num) return true; + if (name == "damageBegin4" && num) return true; return false; }, - forced:true, - content:function(){ - 'step 0' - var num=player.countCards('s',card=>card.hasGaintag('sbguanxing')); - if(!num&&event.triggername=='damageBegin3'){ - trigger.increase('num'); - } - else if(num&&event.triggername=='damageBegin4'){ - player.judge(function(result){ - if(get.number(result)<=get.player().countCards('s',card=>card.hasGaintag('sbguanxing'))) return 2; - return -1; - }).set('judge2',result=>result.bool).set('callback',function(){ - if(event.judgeResult.number<=player.countCards('s',card=>card.hasGaintag('sbguanxing'))){ - event.getParent('sbkongcheng').getTrigger().decrease('num'); - } - }); + forced: true, + content: function () { + "step 0"; + var num = player.countCards("s", (card) => card.hasGaintag("sbguanxing")); + if (!num && event.triggername == "damageBegin3") { + trigger.increase("num"); + } else if (num && event.triggername == "damageBegin4") { + player + .judge(function (result) { + if ( + get.number(result) <= + get.player().countCards("s", (card) => card.hasGaintag("sbguanxing")) + ) + return 2; + return -1; + }) + .set("judge2", (result) => result.bool) + .set("callback", function () { + if ( + event.judgeResult.number <= + player.countCards("s", (card) => card.hasGaintag("sbguanxing")) + ) { + event.getParent("sbkongcheng").getTrigger().decrease("num"); + } + }); } }, + ai: { + combo: "sbguanxing", + }, }, //卢植 - sbzhenliang:{ - mark:true, - locked:false, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - if(storage) return '你的回合外,一名角色使用或打出牌结算完成后,若此牌与“任”类别相同,则你可以令一名角色摸两张牌。'; - return '出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。'; + 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())); + 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]); + 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())); + 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); + check: function (card) { + return 6.5 - get.value(card); }, - prompt:'弃置与攻击范围内的一名角色体力值之差(至少为1)张与“任”颜色相同的牌,对其造成1点伤害', - content:function(){ - player.changeZhuanhuanji('sbzhenliang'); - target.damage('nocard'); + 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); + ai: { + order: 5, + result: { + player: function (player, target) { + return get.damageEffect(target, player, player); }, }, - combo:'nzry_mingren', + combo: "nzry_mingren", }, - 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); + 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); + 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(2); } }, @@ -2081,194 +2756,279 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //小乔 - 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)); + 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'; + 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); + 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); + 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}, + ai: { + order: 5, + result: { target: -1 }, }, - group:['sbtianxiang_draw','sbtianxiang_effect'], - subSkill:{ - heart:{ - charlotte:true, - mark:true, - marktext:'♥︎', - intro:{content:'伤害转移术'}, + group: ["sbtianxiang_draw", "sbtianxiang_effect"], + subSkill: { + heart: { + charlotte: true, + mark: true, + marktext: "♥︎", + intro: { content: "伤害转移术" }, }, - diamond:{ - 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)); + 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); + 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; + num += skills.length; }); - if(get.mode()!='identity') num+=2; + if (get.mode() != "identity") num += 2; player.draw(num); }, }, - effect:{ - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - return game.hasPlayer(target=>target.getSkills().some(skill=>skill.indexOf('sbtianxiang_')==0)); + 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); + 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.includes('sbtianxiang_heart')){ - target.damage(trigger.source?trigger.source:'nosource'); + if (skills.includes("sbtianxiang_heart")) { + target.damage(trigger.source ? trigger.source : "nosource"); trigger.cancel(); } - if(skills.includes('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'); + if (skills.includes("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, - trigger:{player:['phaseJudgeBefore','phaseDrawBefore','phaseUseBefore']}, - usable:1, - direct:true, - content:function(){ - 'step 0' - switch(trigger.name){ - case 'phaseJudge': - player.chooseTarget(get.prompt('sbqiaobian'),'失去1点体力并跳过判定阶段,将判定区里的牌移动给一名其他角色',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player.hp+player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,player); - return savable; - })<=1) return 0; - var eff=0; - for(var card of player.getCards('j')){ - var cardx; - if(card.viewAs) cardx=get.autoViewAs({name:card.viewAs},[card]); - else cardx=card; - if(target.canAddJudge(cardx)) eff+=get.effect(target,cardx,player,player); - else eff-=get.attitude(player,target)/114514; - } - return eff; - }).setHiddenSkill('sbqiaobian'); - break; - case 'phaseDraw': - player.chooseBool(get.prompt('sbqiaobian'),'跳过摸牌阶段,于下个准备阶段摸五张牌并回复1点体力').setHiddenSkill('sbqiaobian'); - break; - case 'phaseUse': - var num=(player.countCards('h')-6); - if(num<=0) player.chooseBool(get.prompt('sbqiaobian'),'跳过出牌阶段和弃牌阶段,然后移动场上的一张牌').set('choice',player.canMoveCard(true)).setHiddenSkill('sbqiaobian'); - else player.chooseToDiscard(get.prompt('sbqiaobian'),num,'弃置'+get.cnNumber(num)+'张手牌并跳过出牌阶段和弃牌阶段,然后移动场上的一张牌').set('ai',function(card){ - var player=_status.event.player; - if(!player.canMoveCard(true)||player.countCards('hs',card=>player.hasValueTarget(card))>=9) return 0; - return 7-get.value(card); - }).setHiddenSkill('sbqiaobian').logSkill='sbqiaobian'; - break; + sbqiaobian: { + audio: 2, + trigger: { player: ["phaseJudgeBefore", "phaseDrawBefore", "phaseUseBefore"] }, + usable: 1, + direct: true, + content: function () { + "step 0"; + switch (trigger.name) { + case "phaseJudge": + player + .chooseTarget( + get.prompt("sbqiaobian"), + "失去1点体力并跳过判定阶段,将判定区里的牌移动给一名其他角色", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + if ( + player.hp + + player.countCards("h", function (card) { + var mod2 = game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") + savable = savable(card, player, player); + return savable; + }) <= + 1 + ) + return 0; + var eff = 0; + for (var card of player.getCards("j")) { + var cardx; + if (card.viewAs) + cardx = get.autoViewAs({ name: card.viewAs }, [card]); + else cardx = card; + if (target.canAddJudge(cardx)) + eff += get.effect(target, cardx, player, player); + else eff -= get.attitude(player, target) / 114514; + } + return eff; + }) + .setHiddenSkill("sbqiaobian"); + break; + case "phaseDraw": + player + .chooseBool( + get.prompt("sbqiaobian"), + "跳过摸牌阶段,于下个准备阶段摸五张牌并回复1点体力" + ) + .setHiddenSkill("sbqiaobian"); + break; + case "phaseUse": + var num = player.countCards("h") - 6; + if (num <= 0) + player + .chooseBool( + get.prompt("sbqiaobian"), + "跳过出牌阶段和弃牌阶段,然后移动场上的一张牌" + ) + .set("choice", player.canMoveCard(true)) + .setHiddenSkill("sbqiaobian"); + else + player + .chooseToDiscard( + get.prompt("sbqiaobian"), + num, + "弃置" + + get.cnNumber(num) + + "张手牌并跳过出牌阶段和弃牌阶段,然后移动场上的一张牌" + ) + .set("ai", function (card) { + var player = _status.event.player; + if ( + !player.canMoveCard(true) || + player.countCards("hs", (card) => player.hasValueTarget(card)) >= + 9 + ) + return 0; + return 7 - get.value(card); + }) + .setHiddenSkill("sbqiaobian").logSkill = "sbqiaobian"; + break; } - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.cancel(); - switch(trigger.name){ - case 'phaseJudge': - var target=result.targets[0]; - player.logSkill('sbqiaobian',target); - player.loseHp(); - game.log(player,'跳过了判定阶段'); - for(var card of player.getCards('j')){ - if(target.canAddJudge(card)){ - player.$give(card,target,false); - if(card.viewAs) target.addJudge({name:card.viewAs},[card]); - else target.addJudge(card); + switch (trigger.name) { + case "phaseJudge": + var target = result.targets[0]; + player.logSkill("sbqiaobian", target); + player.loseHp(); + game.log(player, "跳过了判定阶段"); + for (var card of player.getCards("j")) { + if (target.canAddJudge(card)) { + player.$give(card, target, false); + if (card.viewAs) target.addJudge({ name: card.viewAs }, [card]); + else target.addJudge(card); + } else player.discard(card); } - else player.discard(card); - } - break; - case 'phaseDraw': - player.logSkill('sbqiaobian'); - game.log(player,'跳过了摸牌阶段'); - player.addSkill('sbqiaobian_draw'); - break; - case 'phaseUse': - if(!result.cards||!result.cards.length) player.logSkill('sbqiaobian',target); - player.skip('phaseDiscard'); - game.log(player,'跳过了出牌阶段'); - game.log(player,'跳过了弃牌阶段'); - player.moveCard(); - break; + break; + case "phaseDraw": + player.logSkill("sbqiaobian"); + game.log(player, "跳过了摸牌阶段"); + player.addSkill("sbqiaobian_draw"); + break; + case "phaseUse": + if (!result.cards || !result.cards.length) + player.logSkill("sbqiaobian", target); + player.skip("phaseDiscard"); + game.log(player, "跳过了出牌阶段"); + game.log(player, "跳过了弃牌阶段"); + player.moveCard(); + break; } - } - else player.storage.counttrigger.sbqiaobian--; + } else player.storage.counttrigger.sbqiaobian--; }, - subSkill:{ - draw:{ - charlotte:true, - mark:true, - intro:{content:'准备阶段摸五张牌并回复1点体力'}, - audio:'sbqiaobian', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ - player.removeSkill('sbqiaobian_draw'); + subSkill: { + draw: { + charlotte: true, + mark: true, + intro: { content: "准备阶段摸五张牌并回复1点体力" }, + audio: "sbqiaobian", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { + player.removeSkill("sbqiaobian_draw"); player.draw(5); player.recover(); }, @@ -2276,4840 +3036,5978 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //萌货 - sbhuoshou:{ - audio:2, - trigger:{ - player:'phaseUseBegin', + sbhuoshou: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - filter:function(event,player){ + filter: function (event, player) { return true; }, - forced:true, - onremove:true, - group:['sbhuoshou_cancel','sbhuoshou_source','sbhuoshou_nanmaned'], - content:function(){ - 'step 0' - var card=get.discardPile(card=>{ - return card.name=='nanman'; + forced: true, + onremove: true, + group: ["sbhuoshou_cancel", "sbhuoshou_source", "sbhuoshou_nanmaned"], + content: function () { + "step 0"; + var card = get.discardPile((card) => { + return card.name == "nanman"; }); - if(card){ - player.gain(card,'gain2'); - } - else{ - game.log('但是弃牌堆里并没有','#y南蛮入侵','!'); - player.addMark('sbhuoshou',1,false); - if(player.countMark('sbhuoshou')>=5&&Math.random()<0.25) player.chat('我南蛮呢'); + if (card) { + player.gain(card, "gain2"); + } else { + game.log("但是弃牌堆里并没有", "#y南蛮入侵", "!"); + player.addMark("sbhuoshou", 1, false); + if (player.countMark("sbhuoshou") >= 5 && Math.random() < 0.25) + player.chat("我南蛮呢"); } }, - subSkill:{ - cancel:{ - audio:'sbhuoshou', - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - filter:function(event,player){ - return (event.card.name=='nanman'); + subSkill: { + cancel: { + audio: "sbhuoshou", + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + filter: function (event, player) { + return event.card.name == "nanman"; }, - content:function(){ + content: function () { trigger.cancel(); }, }, - source:{ - audio:'sbhuoshou', - trigger:{global:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - return event.isFirstTarget&&event.card&&event.card.name=='nanman'&&event.player!=player; + source: { + audio: "sbhuoshou", + trigger: { global: "useCardToPlayered" }, + forced: true, + filter: function (event, player) { + return ( + event.isFirstTarget && + event.card && + event.card.name == "nanman" && + event.player != player + ); + }, + content: function () { + trigger.getParent().customArgs.default.customSource = player; }, - content:function(){ - trigger.getParent().customArgs.default.customSource=player; - } }, - nanmaned:{ - trigger:{ - player:'useCard1', + nanmaned: { + trigger: { + player: "useCard1", }, - filter:function(event,player){ - return event.card.name=='nanman'; + filter: function (event, player) { + return event.card.name == "nanman"; + }, + forced: true, + popup: false, + charlotte: true, + content: function () { + "step 0"; + player.addTempSkill("sbhuoshou_ban", "phaseUseAfter"); }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - 'step 0' - player.addTempSkill('sbhuoshou_ban','phaseUseAfter'); - } }, - ban:{ - charlotte:true, - intro:{ - content:'此阶段不能再使用【南蛮入侵】', - } + ban: { + charlotte: true, + intro: { + content: "此阶段不能再使用【南蛮入侵】", + }, }, }, - mod:{ - cardEnabled:function(card,player){ - if(player.hasSkill('sbhuoshou_ban')&&card.name=='nanman') return false; + mod: { + cardEnabled: function (card, player) { + if (player.hasSkill("sbhuoshou_ban") && card.name == "nanman") return false; }, }, - ai:{ - threaten:1.9, - } + ai: { + threaten: 1.9, + }, }, - sbzaiqi:{ - audio:2, - trigger:{ - player:'phaseDiscardEnd', + sbzaiqi: { + audio: 2, + trigger: { + player: "phaseDiscardEnd", }, - chargeSkill:true, - filter:function(event,player){ - return player.hasMark('charge'); + chargeSkill: true, + filter: function (event, player) { + return player.hasMark("charge"); }, - group:'sbzaiqi_backflow', - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('sbzaiqi'),'选择任意名角色并消耗等量蓄力值,令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力',[1,player.countMark('charge')]).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - return 3-get.sgn(att)+Math.abs(att/1000); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; + group: "sbzaiqi_backflow", + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("sbzaiqi"), + "选择任意名角色并消耗等量蓄力值,令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力", + [1, player.countMark("charge")] + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + return 3 - get.sgn(att) + Math.abs(att / 1000); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.sortBySeat(); - event.targets=targets; - player.logSkill('sbzaiqi',targets); - player.removeMark('charge',targets.length); - } - else event.finish(); - 'step 2' - var target=targets.shift(); - event.target=target; - if(!target.countCards('he')) event._result={bool:false}; - else target.chooseToDiscard(get.translation(player)+'对你发动了【再起】','是否弃置一张牌令其回复1点体力?或者点击“取消”,令该角色摸一张牌。','he').set('ai',card=>{ - var eff=_status.event.eff,att=_status.event.att; - if(eff>0&&att>0||eff<=0&&att<0) return 5.5-get.value(card); - return 0; - }).set('eff',get.recoverEffect(player,player,target)).set('att',get.attitude(target,player)); - 'step 3' + event.targets = targets; + player.logSkill("sbzaiqi", targets); + player.removeMark("charge", targets.length); + } else event.finish(); + "step 2"; + var target = targets.shift(); + event.target = target; + if (!target.countCards("he")) event._result = { bool: false }; + else + target + .chooseToDiscard( + get.translation(player) + "对你发动了【再起】", + "是否弃置一张牌令其回复1点体力?或者点击“取消”,令该角色摸一张牌。", + "he" + ) + .set("ai", (card) => { + var eff = _status.event.eff, + att = _status.event.att; + if ((eff > 0 && att > 0) || (eff <= 0 && att < 0)) + return 5.5 - get.value(card); + return 0; + }) + .set("eff", get.recoverEffect(player, player, target)) + .set("att", get.attitude(target, player)); + "step 3"; target.line(player); - if(result.bool){ + if (result.bool) { player.recover(); - } - else{ + } else { player.draw(); } game.delayex(); - if(targets.length) event.goto(2); + if (targets.length) event.goto(2); }, - subSkill:{ - backflow:{ - audio:'sbzaiqi', - trigger:{ + subSkill: { + backflow: { + audio: "sbzaiqi", + trigger: { //player:'enterGame', - source:'damageSource', + source: "damageSource", //global:'phaseBefore', }, - usable:1, - filter:function(event,player){ - if(event.name=='damage') return true; - return (event.name!='phase'||game.phaseNumber==0); + usable: 1, + 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',trigger.name=='damage'?1:3); - } - } - } + forced: true, + locked: false, + content: function () { + player.addMark("charge", trigger.name == "damage" ? 1 : 3); + }, + }, + }, }, //祝融 - sblieren:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.targets.length==1&&event.card.name=='sha'&&player.canCompare(event.target,true); + sblieren: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return ( + event.targets.length == 1 && + event.card.name == "sha" && + player.canCompare(event.target, true) + ); }, - check:function(event,player){ - return get.attitude(player,event.target)<=0||game.hasPlayer(current=>get.damageEffect(current,player,player)>0); + check: function (event, player) { + return ( + get.attitude(player, event.target) <= 0 || + game.hasPlayer((current) => get.damageEffect(current, player, player) > 0) + ); }, - shaRelated:true, - logTarget:'target', - content:function(){ - 'step 0' + shaRelated: true, + logTarget: "target", + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.canCompare(trigger.target)) player.chooseToCompare(trigger.target); + "step 1"; + if (player.canCompare(trigger.target)) player.chooseToCompare(trigger.target); else event.finish(); - 'step 2' - if(result.bool){ - player.addTempSkill('sblieren_damage'); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.sblieren=[player,trigger.target]; + "step 2"; + if (result.bool) { + player.addTempSkill("sblieren_damage"); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.sblieren = [player, trigger.target]; } }, - subSkill:{ - damage:{ - audio:'sblieren', - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.card.storage&&event.card.storage.sblieren&&event.card.storage.sblieren[0]==player&&game.hasPlayer(current=>{ - return !event.card.storage.sblieren.includes(current); - }); + subSkill: { + damage: { + audio: "sblieren", + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.card.storage && + event.card.storage.sblieren && + event.card.storage.sblieren[0] == player && + game.hasPlayer((current) => { + return !event.card.storage.sblieren.includes(current); + }) + ); }, - direct:true, - charlotte:true, - content:function(){ - 'step 0' - 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('ai',targetx=>get.damageEffect(targetx,_status.event.player,_status.event.player)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sblieren_damage',target); + direct: true, + charlotte: true, + content: function () { + "step 0"; + 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("ai", (targetx) => + get.damageEffect(targetx, _status.event.player, _status.event.player) + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sblieren_damage", target); target.damage(); } - } - } - } + }, + }, + }, }, - sbjuxiang:{ - audio:2, - trigger:{ - player:'phaseJieshuBegin', + sbjuxiang: { + audio: 2, + trigger: { + player: "phaseJieshuBegin", }, - forced:true, - direct:true, - filter:function(event,player){ - return !player.hasHistory('useCard',evt=>evt.card.name=='nanman')&&(!_status.sbjuxiang_nanman||_status.sbjuxiang_nanman.length); + forced: true, + direct: true, + filter: function (event, player) { + return ( + !player.hasHistory("useCard", (evt) => evt.card.name == "nanman") && + (!_status.sbjuxiang_nanman || _status.sbjuxiang_nanman.length) + ); }, - group:['sbjuxiang_cancel','sbjuxiang_gain'], - content:function(){ - 'step 0' - if(!_status.sbjuxiang_nanman){ - _status.sbjuxiang_nanman=[ - {name:'nanman',number:7,suit:'spade'}, - {name:'nanman',number:7,suit:'club'}, + group: ["sbjuxiang_cancel", "sbjuxiang_gain"], + content: function () { + "step 0"; + if (!_status.sbjuxiang_nanman) { + _status.sbjuxiang_nanman = [ + { name: "nanman", number: 7, suit: "spade" }, + { name: "nanman", number: 7, suit: "club" }, ]; - game.broadcastAll(function(){ - if(!lib.inpile.includes('nanman')) lib.inpile.add('nanman'); + game.broadcastAll(function () { + if (!lib.inpile.includes("nanman")) lib.inpile.add("nanman"); }); } - player.chooseTarget(get.prompt('sbjuxiang'),'将游戏外的随机一张【南蛮入侵】交给一名角色(剩余'+get.cnNumber(_status.sbjuxiang_nanman.length)+'张)').set('ai',target=>{ - var player=_status.event.player; - return Math.max(0,target.getUseValue({name:'nanman'}))*get.attitude(player,target)*(target==player?0.5:1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbjuxiang',target); - if(!_status.sbjuxiang_nanman.length) return; - var info=_status.sbjuxiang_nanman.randomRemove(); - var card=game.createCard2(info); - target.gain(card,'gain2').giver=player; + player + .chooseTarget( + get.prompt("sbjuxiang"), + "将游戏外的随机一张【南蛮入侵】交给一名角色(剩余" + + get.cnNumber(_status.sbjuxiang_nanman.length) + + "张)" + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + Math.max(0, target.getUseValue({ name: "nanman" })) * + get.attitude(player, target) * + (target == player ? 0.5 : 1) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbjuxiang", target); + if (!_status.sbjuxiang_nanman.length) return; + var info = _status.sbjuxiang_nanman.randomRemove(); + var card = game.createCard2(info); + target.gain(card, "gain2").giver = player; } }, - ai:{ - expose:0.05, - effect:{ - target:function(card){ - if(card.name=='nanman') return [0,1]; - } - } - }, - subSkill:{ - cancel:{ - audio:'sbjuxiang', - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - filter:function(event,player){ - return event.card.name=='nanman'; + ai: { + expose: 0.05, + effect: { + target: function (card) { + if (card.name == "nanman") return [0, 1]; }, - content:function(){ - trigger.cancel(); - } }, - gain:{ - audio:'sbjuxiang', - trigger:{global:'useCardAfter'}, - forced:true, - filter:function(event,player){ - return event.card.name=='nanman'&&event.player!=player&&event.cards.filterInD().length; + }, + subSkill: { + cancel: { + audio: "sbjuxiang", + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + filter: function (event, player) { + return event.card.name == "nanman"; }, - content:function(){ - player.gain(trigger.cards.filterInD(),'gain2'); - } - } - } + content: function () { + trigger.cancel(); + }, + }, + gain: { + audio: "sbjuxiang", + trigger: { global: "useCardAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "nanman" && + event.player != player && + event.cards.filterInD().length + ); + }, + content: function () { + player.gain(trigger.cards.filterInD(), "gain2"); + }, + }, + }, }, //阿笨 - sbjiang:{ - audio:2, - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + sbjiang: { + audio: 2, + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - shaRelated:true, - filter:function(event,player){ - if(!(event.card.name=='juedou'||(event.card.name=='sha'&&get.color(event.card)=='red'))) return false; + shaRelated: true, + filter: function (event, player) { + if ( + !( + event.card.name == "juedou" || + (event.card.name == "sha" && get.color(event.card) == "red") + ) + ) + return false; return true; }, - frequent:true, - onremove:true, - group:['sbjiang_add','sbjiang_qiben'], - content:function(){ + frequent: true, + onremove: true, + group: ["sbjiang_add", "sbjiang_qiben"], + content: function () { player.draw(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,0.6]; + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 0.6]; }, - player:function(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,1]; - } - } + player: function (card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 1]; + }, + }, }, - subSkill:{ - add:{ - audio:'sbjiang', - trigger:{player:'useCard2'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='juedou') return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + subSkill: { + add: { + audio: "sbjiang", + trigger: { player: "useCard2" }, + direct: true, + filter: function (event, player) { + if (event.card.name != "juedou") return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'额外指定一个目标,然后失去1点体力'; - player.chooseTarget(get.prompt('sbjiang_add'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var eff=get.effect(target,trigger.card,player,player); - if(player.hasZhuSkill('sbzhiba')&&!player.hasMark('sbjiang')) return eff; - if(eff+get.effect(player,{name:'losehp'},player)/8>0) return eff; - return 0; - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = + "为" + get.translation(trigger.card) + "额外指定一个目标,然后失去1点体力"; + player + .chooseTarget(get.prompt("sbjiang_add"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return lib.filter.targetEnabled2(_status.event.card, player, target); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var eff = get.effect(target, trigger.card, player, player); + if (player.hasZhuSkill("sbzhiba") && !player.hasMark("sbjiang")) + return eff; + if (eff + get.effect(player, { name: "losehp" }, player) / 8 > 0) + return eff; + return 0; + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('sbjiang_add',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("sbjiang_add", event.targets); trigger.targets.addArray(event.targets); player.loseHp(); } - } + }, }, - qiben:{ - audio:'sbjiang', - enable:'phaseUse', - viewAs:{name:'juedou'}, - filterCard:true, - position:'h', - selectCard:-1, - prompt:function(){ - var player=_status.event.player; - var limit=(player.hasMark('sbjiang')?(game.countPlayer(current=>{ - return current.group=='wu'&¤t!=player; - })+1):1); - return '出牌阶段限'+get.cnNumber(limit)+'次。你可以将所有手牌当【决斗】使用'; + qiben: { + audio: "sbjiang", + enable: "phaseUse", + viewAs: { name: "juedou" }, + filterCard: true, + position: "h", + selectCard: -1, + prompt: function () { + var player = _status.event.player; + var limit = player.hasMark("sbjiang") + ? game.countPlayer((current) => { + return current.group == "wu" && current != player; + }) + 1 + : 1; + return "出牌阶段限" + get.cnNumber(limit) + "次。你可以将所有手牌当【决斗】使用"; }, - filter:function(event,player){ - var limit=player.hasMark('sbjiang')?(game.countPlayer(current=>{ - return current.group=='wu'&¤t!=player; - })+1):1; - if((player.getStat('skill').sbjiang_qiben||0)>=limit) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i=0;i { + return current.group == "wu" && current != player; + }) + 1 + : 1; + if ((player.getStat("skill").sbjiang_qiben || 0) >= limit) return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i = 0; i < hs.length; i++) { + var mod2 = game.checkMod(hs[i], player, "unchanged", "cardEnabled2", player); + if (mod2 === false) return false; } - return event.filterCard(get.autoViewAs({name:'juedou'},hs)); + return event.filterCard(get.autoViewAs({ name: "juedou" }, hs)); }, - 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'); + 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" && current != player; + }) + 1 + : 1; + return ( + player.isPhaseUsing() && + (player.getStat("skill").sbjiang_qiben || 0) < limit && + player.hasCard((card) => get.name(card) != "tao", "h") + ); } - } + }, }, - } + }, }, }, - sbhunzi:{ - audio:2, - trigger:{player:'dyingAfter'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'wood', - derivation:['sbyingzi','gzyinghun'], - content:function(){ - 'step 0' - player.awakenSkill('sbhunzi'); + sbhunzi: { + audio: 2, + trigger: { player: "dyingAfter" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "wood", + derivation: ["sbyingzi", "gzyinghun"], + content: function () { + "step 0"; + player.awakenSkill("sbhunzi"); player.loseMaxHp(); - 'step 1' - player.changeHujia(1,null,true); - 'step 2' + "step 1"; + player.changeHujia(1, null, true); + "step 2"; player.draw(3); - 'step 3' - player.addSkills(['sbyingzi','gzyinghun']); + "step 3"; + player.addSkills(["sbyingzi", "gzyinghun"]); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 2; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 2; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(!target.hasFriend()||target.hp>1) return; - if(get.tag(card,'damage')==1&&((target.hasZhuSkill('sbzhiba')&&game.countPlayer(current=>current!=target&¤t.group=='wu'))||player.countCards('hs',card=>player.canSaveCard(card,target))+target.countCards('hs',card=>target.canSaveCard(card,target))>0)&&!target.isTurnedOver()&&_status.currentPhase!=target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; - } - } - } - }, - sbzhiba:{ - audio:2, - trigger:{player:'dying'}, - filter:function(event,player){ - if(!player.hasZhuSkill('sbzhiba')) return false; - return player.hp<=0; - }, - zhuSkill:true, - limited:true, - mark:true, - skillAnimation:true, - animationColor:'wood', - content:function(){ - 'step 0' - player.awakenSkill('sbzhiba'); - event.targets=game.filterPlayer(current=>{ - return current.group=='wu'&¤t!=player; - }).sortBySeat(_status.currentPhase); - var num=event.targets.length; - if(num>0) player.recover(num); - player.addMark('sbjiang',1,false); - player.addTempSkill('sbzhiba_draw'); - if(!event.targets.length) event.finish(); - 'step 1' - var target=targets.shift(); - target.damage('nosource'); - if(targets.length) event.redo(); - }, - subSkill:{ - draw:{ - trigger:{global:'dieAfter'}, - filter:function(event,player){ - return event.getParent(3).name=='sbzhiba'; + maixie: true, + effect: { + target: function (card, player, target) { + if (!target.hasFriend() || target.hp > 1) return; + if ( + get.tag(card, "damage") == 1 && + ((target.hasZhuSkill("sbzhiba") && + game.countPlayer( + (current) => current != target && current.group == "wu" + )) || + player.countCards("hs", (card) => player.canSaveCard(card, target)) + + target.countCards("hs", (card) => target.canSaveCard(card, target)) > + 0) && + !target.isTurnedOver() && + _status.currentPhase != target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [0.5, 1]; }, - forced:true, - charlotte:true, - content:function(){ + }, + }, + }, + sbzhiba: { + audio: 2, + trigger: { player: "dying" }, + filter: function (event, player) { + if (!player.hasZhuSkill("sbzhiba")) return false; + return player.hp <= 0; + }, + zhuSkill: true, + limited: true, + mark: true, + skillAnimation: true, + animationColor: "wood", + content: function () { + "step 0"; + player.awakenSkill("sbzhiba"); + event.targets = game + .filterPlayer((current) => { + return current.group == "wu" && current != player; + }) + .sortBySeat(_status.currentPhase); + var num = event.targets.length; + if (num > 0) player.recover(num); + player.addMark("sbjiang", 1, false); + player.addTempSkill("sbzhiba_draw"); + if (!event.targets.length) event.finish(); + "step 1"; + var target = targets.shift(); + target.damage("nosource"); + if (targets.length) event.redo(); + }, + subSkill: { + draw: { + trigger: { global: "dieAfter" }, + filter: function (event, player) { + return event.getParent(3).name == "sbzhiba"; + }, + forced: true, + charlotte: true, + content: function () { player.draw(3); - } - } - } + }, + }, + }, }, //大乔 - sbguose:{ - audio:2, - enable:'phaseUse', - get usable(){ - return get.mode()=='identity'?4:2; + sbguose: { + audio: 2, + enable: "phaseUse", + get usable() { + return get.mode() == "identity" ? 4 : 2; }, - discard:false, - lose:false, - delay:false, - filter:function(event,player){ - return player.hasCard(card=>get.suit(card)=='diamond','hes')||game.hasPlayer(current=>current.hasJudge('lebu')); + discard: false, + lose: false, + delay: false, + filter: function (event, player) { + return ( + player.hasCard((card) => get.suit(card) == "diamond", "hes") || + game.hasPlayer((current) => current.hasJudge("lebu")) + ); }, - position:'hes', - filterCard:function(card,player){ - if(get.suit(card)!='diamond') return false; - var mod=game.checkMod(ui.selected.cards[0],player,'unchanged','cardEnabled2',player); - if(!mod) return false; + position: "hes", + filterCard: function (card, player) { + if (get.suit(card) != "diamond") return false; + var mod = game.checkMod( + ui.selected.cards[0], + player, + "unchanged", + "cardEnabled2", + player + ); + if (!mod) return false; return true; }, - selectCard:[0,1], - filterTarget:function(card,player,target){ - if(!ui.selected.cards.length){ - if(target.hasJudge('lebu')) return true; + selectCard: [0, 1], + filterTarget: function (card, player, target) { + if (!ui.selected.cards.length) { + if (target.hasJudge("lebu")) return true; return false; } - if(player==target) return false; - return player.canUse(get.autoViewAs({name:'lebu'},ui.selected.cards),target); + if (player == target) return false; + return player.canUse(get.autoViewAs({ name: "lebu" }, ui.selected.cards), target); }, - complexSelect:true, - check:function(card){ - return 7-get.value(card); + complexSelect: true, + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' - if(target.hasJudge('lebu')){ - target.discard(target.getJudge('lebu')); + content: function () { + "step 0"; + if (target.hasJudge("lebu")) { + target.discard(target.getJudge("lebu")); + } else { + player.useCard({ name: "lebu" }, target, cards).audio = false; } - else{ - player.useCard({name:'lebu'},target,cards).audio=false; - } - 'step 1' + "step 1"; player.draw(); }, - ai:{ - result:{ - target:function(player,target){ - if(target.hasJudge('lebu')) return -get.effect(target,{name:'lebu'},player,target); - return get.effect(target,{name:'lebu'},player,target); - } + ai: { + result: { + target: function (player, target) { + if (target.hasJudge("lebu")) + return -get.effect(target, { name: "lebu" }, player, target); + return get.effect(target, { name: "lebu" }, player, target); + }, }, - order:9, - } + order: 9, + }, }, - sbliuli:{ - audio:2, - inherit:'liuli', - group:'sbliuli_heart', - subSkill:{ - heart:{ - trigger:{player:'logSkill'}, - filter:function(event,player){ - if(event.skill!='sbliuli') return false; - if(player.hasSkill('sbliuli_used')) return false; - var evt=event.log_event; - return player.hasHistory('lose',evtx=>{ - return evtx.getParent(2)==evt&&get.suit(evtx.cards[0])=='heart'; + sbliuli: { + audio: 2, + inherit: "liuli", + group: "sbliuli_heart", + subSkill: { + heart: { + trigger: { player: "logSkill" }, + filter: function (event, player) { + if (event.skill != "sbliuli") return false; + if (player.hasSkill("sbliuli_used")) return false; + var evt = event.log_event; + return player.hasHistory("lose", (evtx) => { + return evtx.getParent(2) == evt && get.suit(evtx.cards[0]) == "heart"; }); }, - direct:true, - content:function(){ - 'step 0' - var sourcex=trigger.log_event.getTrigger().player; - player.chooseTarget('流离:是否令一名不为'+get.translation(sourcex)+'的其他角色获得“流离”标记?',(card,player,target)=>{ - return target!=player&&target!=_status.event.sourcex; - }).set('ai',target=>{ - return get.attitude(_status.event.player,target); - }).set('sourcex',sourcex); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.countPlayer(i=>i.removeSkill('sbliuli_dangxian')); - target.addSkill('sbliuli_dangxian'); - player.addTempSkill('sbliuli_used'); + direct: true, + content: function () { + "step 0"; + var sourcex = trigger.log_event.getTrigger().player; + player + .chooseTarget( + "流离:是否令一名不为" + + get.translation(sourcex) + + "的其他角色获得“流离”标记?", + (card, player, target) => { + return target != player && target != _status.event.sourcex; + } + ) + .set("ai", (target) => { + return get.attitude(_status.event.player, target); + }) + .set("sourcex", sourcex); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.countPlayer((i) => i.removeSkill("sbliuli_dangxian")); + target.addSkill("sbliuli_dangxian"); + player.addTempSkill("sbliuli_used"); } - } + }, }, - used:{charlotte:true}, - dangxian:{ - trigger:{player:'phaseBegin'}, - forced:true, - charlotte:true, - mark:true, - marktext:'流', - intro:{content:'回合开始时,执行一个额外的出牌阶段'}, - content:function(){ - var next=player.phaseUse(); + used: { charlotte: true }, + dangxian: { + trigger: { player: "phaseBegin" }, + forced: true, + charlotte: true, + mark: true, + marktext: "流", + intro: { content: "回合开始时,执行一个额外的出牌阶段" }, + content: function () { + var next = player.phaseUse(); event.next.remove(next); trigger.next.push(next); - player.removeSkill('sbliuli_dangxian'); - } - } - } + player.removeSkill("sbliuli_dangxian"); + }, + }, + }, }, //刘表 - sbzishou:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - if(player==event.player) return false; - if(!event.player.countCards('he')) return false; - return !event.player.hasAllHistory('sourceDamage',evt=>{ - return evt.player==player; - })&&!event.player.hasAllHistory('damage',evt=>{ - return evt.source==player; - }); + sbzishou: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + if (player == event.player) return false; + if (!event.player.countCards("he")) return false; + return ( + !event.player.hasAllHistory("sourceDamage", (evt) => { + return evt.player == player; + }) && + !event.player.hasAllHistory("damage", (evt) => { + return evt.source == player; + }) + ); }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' - trigger.player.chooseCard(true,get.translation(player)+'对你发动了【自守】','交给其一张牌','he'); - 'step 1' - if(result.bool){ - trigger.player.give(result.cards,player); + forced: true, + logTarget: "player", + content: function () { + "step 0"; + trigger.player.chooseCard( + true, + get.translation(player) + "对你发动了【自守】", + "交给其一张牌", + "he" + ); + "step 1"; + if (result.bool) { + trigger.player.give(result.cards, player); } }, - ai:{ - threaten:3, - } + ai: { + threaten: 3, + }, }, - sbzongshi:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - return !player.getStorage('sbzongshi').includes(event.source); + sbzongshi: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + return !player.getStorage("sbzongshi").includes(event.source); }, - forced:true, - onremove:true, - logTarget:'source', - content:function(){ - trigger.source.chooseToDiscard(true,trigger.source.countCards('h')); - player.markAuto('sbzongshi',[trigger.source]); + forced: true, + onremove: true, + logTarget: "source", + content: function () { + trigger.source.chooseToDiscard(true, trigger.source.countCards("h")); + player.markAuto("sbzongshi", [trigger.source]); }, - intro:{ - content:'已扒过目标:$' + intro: { + content: "已扒过目标:$", }, - ai:{ - threaten:0.5, - effect:{ - target:function(card,player,target,current){ - if(player._sbzongshi_aiChecking) return; - if(!get.tag(card,'damage')) return; - var cards=player.getCards('h'); - if(!target.hasFriend()) return; - player._sbzongshi_aiChecking=true; - var value=cards.reduce((p,c)=>{ - return p+get.value(c); - },0); + ai: { + threaten: 0.5, + effect: { + target: function (card, player, target, current) { + if (player._sbzongshi_aiChecking) return; + if (!get.tag(card, "damage")) return; + var cards = player.getCards("h"); + if (!target.hasFriend()) return; + player._sbzongshi_aiChecking = true; + var value = cards.reduce((p, c) => { + return p + get.value(c); + }, 0); delete player._sbzongshi_aiChecking; - if(cards.length>5||value>5*cards.length) return [1,0,0,-cards.length/2]; - return [1,0,0,-0.5]; - } - } - } + if (cards.length > 5 || value > 5 * cards.length) + return [1, 0, 0, -cards.length / 2]; + return [1, 0, 0, -0.5]; + }, + }, + }, }, //貂蝉 - sblijian:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return !player.getStat('skill').sblijian&&game.countPlayer(current=>{ - return current!=player; - })>1; + sblijian: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + !player.getStat("skill").sblijian && + game.countPlayer((current) => { + return current != player; + }) > 1 + ); }, - filterCard:true, - selectCard:[1,Infinity], - position:'he', - filterTarget:lib.filter.notMe, - selectTarget:function(){ - return ui.selected.cards.length+1; + filterCard: true, + selectCard: [1, Infinity], + position: "he", + filterTarget: lib.filter.notMe, + selectTarget: function () { + return ui.selected.cards.length + 1; }, - filterOk:function(){ - return ui.selected.targets.length==ui.selected.cards.length+1; + filterOk: function () { + return ui.selected.targets.length == ui.selected.cards.length + 1; }, - check:function(card){ - let player=get.owner(card),targets=lib.skill.sblijian.selectTargetAi(_status.event,player); - if(ui.selected.cards.length{ - let cache=_status.event.getTempCache('sblijian','targets'); - if(Array.isArray(cache)) return cache.length; - let targets=[],cards=[0],sbbiyue=player.hasSkill('sbbiyue')?Math.max(0,3-game.countPlayer2(current=>{ - return current.getHistory('damage').length>0; - })):0,alter=[null,1,1],temp; - for(let i of game.players){ - if(player===i) continue; - let vplayer=ui.create.player(i); - temp=get.effect(i,new lib.element.VCard({name:'juedou',isCard:true}),vplayer,i); + selectTargetAi: (event, player) => { + let cache = _status.event.getTempCache("sblijian", "targets"); + if (Array.isArray(cache)) return cache.length; + let targets = [], + cards = [0], + sbbiyue = player.hasSkill("sbbiyue") + ? Math.max( + 0, + 3 - + game.countPlayer2((current) => { + return current.getHistory("damage").length > 0; + }) + ) + : 0, + alter = [null, 1, 1], + temp; + for (let i of game.players) { + if (player === i) continue; + let vplayer = ui.create.player(i); + temp = get.effect( + i, + new lib.element.VCard({ name: "juedou", isCard: true }), + vplayer, + i + ); vplayer.remove(); - if(temp){ - let att=get.attitude(event.player,i); - if(!att&&sbbiyue||att*temp>0) targets.push([i,temp,att]); - else if(!alter[2]) continue; - else if(!att||att>0&&temp>-15&&i.hp>2||att<0&&temp<15) alter=[i,temp,att]; + if (temp) { + let att = get.attitude(event.player, i); + if ((!att && sbbiyue) || att * temp > 0) targets.push([i, temp, att]); + else if (!alter[2]) continue; + else if (!att || (att > 0 && temp > -15 && i.hp > 2) || (att < 0 && temp < 15)) + alter = [i, temp, att]; } } - targets.sort((a,b)=>{ - if(Boolean(a[2])!==Boolean(b[2])) return Math.abs(b[2])-Math.abs(a[2]); - return Math.abs(b[1])-Math.abs(a[1]); + targets.sort((a, b) => { + if (Boolean(a[2]) !== Boolean(b[2])) return Math.abs(b[2]) - Math.abs(a[2]); + return Math.abs(b[1]) - Math.abs(a[1]); }); - if(targets.length<2&&alter[0]) targets.push(alter); - targets=targets.slice(0,1+player.countCards('he',card=>{ - if(lib.filter.cardDiscardable(card,player,'sblijian')){ - cards.push(get.value(card)); - return true; - } - return false; - })); - cards.sort((a,b)=>a-b); - for(let i=0;i { + if (lib.filter.cardDiscardable(card, player, "sblijian")) { + cards.push(get.value(card)); + return true; + } + return false; + }) + ); + cards.sort((a, b) => a - b); + for (let i = 0; i < targets.length; i++) { + if (Math.abs(targets[i][1]) < cards[i] / (1 + sbbiyue)) { + targets.splice(i, targets.length - i); break; } } - if(targets.length<2){ - event.putTempCache('sblijian','targets',[]); + if (targets.length < 2) { + event.putTempCache("sblijian", "targets", []); return 0; } - event.putTempCache('sblijian','targets',targets); + event.putTempCache("sblijian", "targets", targets); return targets.length; }, - multiline:true, - content:function(){ - var targetx=targets.slice().sortBySeat(target)[1]; - var card={name:'juedou',isCard:true}; - if(target.canUse(card,targetx)) target.useCard(card,targetx); + multiline: true, + content: function () { + var targetx = targets.slice().sortBySeat(target)[1]; + var card = { name: "juedou", isCard: true }; + if (target.canUse(card, targetx)) target.useCard(card, targetx); }, - ai:{ - threaten:3, - order:7, - result:{ - player:function(player,target){ - let targets=_status.event.getTempCache('sblijian','targets'); - if(Array.isArray(targets)) for(let arr of targets){ - if(target===arr[0]&&!arr[2]) return 1; - } + ai: { + threaten: 3, + order: 7, + result: { + player: function (player, target) { + let targets = _status.event.getTempCache("sblijian", "targets"); + if (Array.isArray(targets)) + for (let arr of targets) { + if (target === arr[0] && !arr[2]) return 1; + } return 0; }, - target:function(player,target){ - let targets=_status.event.getTempCache('sblijian','targets'); - if(Array.isArray(targets)) for(let arr of targets){ - if(target===arr[0]){ - if(arr[1]*arr[2]<0) return get.sgn(arr[2]); - return arr[1]; + target: function (player, target) { + let targets = _status.event.getTempCache("sblijian", "targets"); + if (Array.isArray(targets)) + for (let arr of targets) { + if (target === arr[0]) { + if (arr[1] * arr[2] < 0) return get.sgn(arr[2]); + return arr[1]; + } } - } return 0; - } - } - } + }, + }, + }, }, - sbbiyue:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content:function(){ - player.draw(Math.min(4,game.countPlayer2(current=>{ - return current.getHistory('damage').length>0; - })+1)); - } + sbbiyue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content: function () { + player.draw( + Math.min( + 4, + game.countPlayer2((current) => { + return current.getHistory("damage").length > 0; + }) + 1 + ) + ); + }, }, //陈宫 - sbmingce:{ - audio:2, - enable:'phaseUse', - usable:1, - position:'he', - filter:function(event,player){ - return player.countCards('he')>0; + sbmingce: { + audio: 2, + enable: "phaseUse", + usable: 1, + position: "he", + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - check:function(card){ - return 8-get.value(card) + filterCard: true, + check: function (card) { + return 8 - get.value(card); }, - filterTarget:lib.filter.notMe, - selectTarget:1, - discard:false, - lose:false, - delay:false, - onremove:true, - group:'sbmingce_hit', - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' - var choices=['选项二']; - var choiceList=[ - '失去1点体力,令'+get.translation(player)+'摸两张牌并获得1枚“策”', - '摸一张牌' + filterTarget: lib.filter.notMe, + selectTarget: 1, + discard: false, + lose: false, + delay: false, + onremove: true, + group: "sbmingce_hit", + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + var choices = ["选项二"]; + var choiceList = [ + "失去1点体力,令" + get.translation(player) + "摸两张牌并获得1枚“策”", + "摸一张牌", ]; - if(target.hp>0) choices.unshift('选项一'); - else choiceList[0]=''+choiceList[0]+''; - target.chooseControl(choices).set('choiceList', choiceList).set('prompt',get.translation(player)+'对你发动了【明策】,请选择一项').set('ai',()=>{ - return _status.event.choice; - }).set('choice',target.hp<=0||((target.hp+target.countCards('hs','tao')>2&&get.attitude(target,player)>0)||get.effect(target,{name:'losehp'},target,target)>0)&&target.hp>0?0:1); - 'step 2' - if(result.control=='选项一'){ + if (target.hp > 0) choices.unshift("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + target + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", get.translation(player) + "对你发动了【明策】,请选择一项") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + target.hp <= 0 || + (((target.hp + target.countCards("hs", "tao") > 2 && + get.attitude(target, player) > 0) || + get.effect(target, { name: "losehp" }, target, target) > 0) && + target.hp > 0) + ? 0 + : 1 + ); + "step 2"; + if (result.control == "选项一") { target.loseHp(); player.draw(2); - } - else{ + } else { target.draw(); event.finish(); } - 'step 3' - player.addMark('sbmingce',1); + "step 3"; + player.addMark("sbmingce", 1); }, - marktext:'笨', - intro:{ - name:'策(明策)', - name2:'策', - content:'mark' + marktext: "笨", + intro: { + name: "策(明策)", + name2: "策", + content: "mark", }, - ai:{ - result:{ - player:0.5, - target:1, + ai: { + result: { + player: 0.5, + target: 1, }, - order:8.5, - expose:0.2 + order: 8.5, + expose: 0.2, }, - subSkill:{ - hit:{ - audio:'sbmingce', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.hasMark('sbmingce'); + subSkill: { + hit: { + audio: "sbmingce", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.hasMark("sbmingce"); }, - direct:true, - content:function(){ - 'step 0' - var num=player.countMark('sbmingce'); - event.num=num; - player.chooseTarget(get.prompt('sbmingce'),'移去所有“策”,对一名其他角色造成'+num+'点伤害',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - var eff=get.damageEffect(target,player,player); - var num=player.countMark('sbmingce'); - if(target.hasSkillTag('filterDamage',null,{player:player})) num=1; - return eff*num; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbmingce_hit',target); - player.removeMark('sbmingce',num); + direct: true, + content: function () { + "step 0"; + var num = player.countMark("sbmingce"); + event.num = num; + player + .chooseTarget( + get.prompt("sbmingce"), + "移去所有“策”,对一名其他角色造成" + num + "点伤害", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player; + var eff = get.damageEffect(target, player, player); + var num = player.countMark("sbmingce"); + if (target.hasSkillTag("filterDamage", null, { player: player })) num = 1; + return eff * num; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbmingce_hit", target); + player.removeMark("sbmingce", num); target.damage(num); } - } - } - } - }, - sbzhichi:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - content:function(){ - player.addTempSkill('sbzhichi_muteki'); + }, + }, }, - subSkill:{ - muteki:{ - audio:'sbzhichi', - trigger:{player:'damageBegin4'}, - charlotte:true, - forced:true, - group:'sbzhichi_egg', - content:function(){ + }, + sbzhichi: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + content: function () { + player.addTempSkill("sbzhichi_muteki"); + }, + subSkill: { + muteki: { + audio: "sbzhichi", + trigger: { player: "damageBegin4" }, + charlotte: true, + forced: true, + group: "sbzhichi_egg", + content: function () { trigger.cancel(); }, - mark:true, - intro:{content:'我无敌啦!'}, - ai:{ - maixie:true, - maixie_hp:true, - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')) return 'zeroplayertarget'; - } + mark: true, + intro: { content: "我无敌啦!" }, + ai: { + maixie: true, + maixie_hp: true, + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) return "zeroplayertarget"; + }, }, - } - }, - egg:{ - trigger:{player:'die'}, - charlotte:true, - forced:true, - silent:true, - forceDie:true, - content:function(){ - player.chat('你是真滴牛批'); - } - } - } - }, - //袁绍 - sbluanji:{ - audio:2, - enable:'phaseUse', - trigger:{global:'respond'}, - viewAs:{name:'wanjian'}, - forced:true, - locked:false, - filter:function(event,player){ - if(event.name=='chooseToUse') return player.countCards('hs')>1&&!player.hasSkill('sbluanji_used'); - var evt=event.getParent(2); - return evt.name=='wanjian'&&evt.getParent().player==player&&event.player!=player&&player.getHistory('gain',function(evt){ - return evt.getParent(2).name=='sbluanji'; - }).length<3; - }, - filterCard:true, - selectCard:2, - position:'hs', - prompt:'将两张手牌当【万箭齐发】使用', - check:function(card){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return player.canUse('wanjian',current); - }); - var num=0; - for(var i=0;i=7){ - if(num<1) return 0; - } - else if(targets.length>=5){ - if(num<0.5) return 0; - } - } - return 6-get.value(card); - }, - content:function(){ - player.draw(); - }, - precontent:function(){ - player.addTempSkill('sbluanji_used','phaseUseAfter'); - }, - ai:{ - threaten:1.6, - }, - subSkill:{used:{charlotte:true}} - }, - sbxueyi:{ - audio:2, - trigger:{player:'useCardToTargeted'}, - filter:function(event,player){ - return player.hasZhuSkill('sbxueyi')&&event.target!=player&&event.target.group=='qun'; - }, - zhuSkill:true, - forced:true, - usable:2, - logTarget:'target', - content:function(){ - player.draw(); - }, - mod:{ - maxHandcard:function(player,num){ - if(player.hasZhuSkill('sbxueyi')){ - return num+2*game.countPlayer(current=>player!=current&¤t.group=='qun'); - } - } - }, - ai:{ - effect:{ - player:function(card,player,target){ - if(player!=target&&target&&target.group=='qun'&&card.name!='tao') return [1,0.1]; }, }, - } + egg: { + trigger: { player: "die" }, + charlotte: true, + forced: true, + silent: true, + forceDie: true, + content: function () { + player.chat("你是真滴牛批"); + }, + }, + }, + }, + //袁绍 + sbluanji: { + audio: 2, + enable: "phaseUse", + trigger: { global: "respond" }, + viewAs: { name: "wanjian" }, + forced: true, + locked: false, + filter: function (event, player) { + if (event.name == "chooseToUse") + return player.countCards("hs") > 1 && !player.hasSkill("sbluanji_used"); + var evt = event.getParent(2); + return ( + evt.name == "wanjian" && + evt.getParent().player == player && + event.player != player && + player.getHistory("gain", function (evt) { + return evt.getParent(2).name == "sbluanji"; + }).length < 3 + ); + }, + filterCard: true, + selectCard: 2, + position: "hs", + prompt: "将两张手牌当【万箭齐发】使用", + check: function (card) { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return player.canUse("wanjian", current); + }); + var num = 0; + for (var i = 0; i < targets.length; i++) { + var eff = get.sgn(get.effect(targets[i], { name: "wanjian" }, player, player)); + if (targets[i].hp == 1) { + eff *= 1.5; + } + if (get.attitude(player, targets[i]) == 0 || targets[i].group == "qun") { + eff += 0.5; + } + num += eff; + } + if (!player.needsToDiscard(-1)) { + if (targets.length >= 7) { + if (num < 1) return 0; + } else if (targets.length >= 5) { + if (num < 0.5) return 0; + } + } + return 6 - get.value(card); + }, + content: function () { + player.draw(); + }, + precontent: function () { + player.addTempSkill("sbluanji_used", "phaseUseAfter"); + }, + ai: { + threaten: 1.6, + }, + subSkill: { used: { charlotte: true } }, + }, + sbxueyi: { + audio: 2, + trigger: { player: "useCardToTargeted" }, + filter: function (event, player) { + return ( + player.hasZhuSkill("sbxueyi") && event.target != player && event.target.group == "qun" + ); + }, + zhuSkill: true, + forced: true, + usable: 2, + logTarget: "target", + content: function () { + player.draw(); + }, + mod: { + maxHandcard: function (player, num) { + if (player.hasZhuSkill("sbxueyi")) { + return ( + num + + 2 * game.countPlayer((current) => player != current && current.group == "qun") + ); + } + }, + }, + ai: { + effect: { + player: function (card, player, target) { + if (player != target && target && target.group == "qun" && card.name != "tao") + return [1, 0.1]; + }, + }, + }, }, //庞统 - sblianhuan:{ - audio:2, - enable:'phaseUse', - filter:(event,player)=>player.hasCard(card=>lib.skill.sblianhuan.filterCard(card,player),lib.skill.sblianhuan.position), - filterTarget:function(card,player,target){ - if(player.hasSkill('sblianhuan_blocker')) return false; - if(!ui.selected.cards.length) return false; - card=get.autoViewAs({name:'tiesuo'},[ui.selected.cards[0]]); - return player.canUse(card,target); + sblianhuan: { + audio: 2, + enable: "phaseUse", + filter: (event, player) => + player.hasCard( + (card) => lib.skill.sblianhuan.filterCard(card, player), + lib.skill.sblianhuan.position + ), + filterTarget: function (card, player, target) { + if (player.hasSkill("sblianhuan_blocker")) return false; + if (!ui.selected.cards.length) return false; + card = get.autoViewAs({ name: "tiesuo" }, [ui.selected.cards[0]]); + return player.canUse(card, target); }, - filterCard:(card,player)=>get.suit(card)=='club'&&(!player.hasSkill('sblianhuan_blocker')||player.canRecast(card)), - selectCard:1, - position:'hs', - derivation:'sblianhuan_lv2', - selectTarget:function(){ - var card=get.card(),player=get.player(); - if(player.hasSkill('sblianhuan_blocker')) return 0; - if(card==undefined) return; - var range=[0,2]; - game.checkMod(card,player,range,'selectTarget',player); + filterCard: (card, player) => + get.suit(card) == "club" && + (!player.hasSkill("sblianhuan_blocker") || player.canRecast(card)), + selectCard: 1, + position: "hs", + derivation: "sblianhuan_lv2", + selectTarget: function () { + var card = get.card(), + player = get.player(); + if (player.hasSkill("sblianhuan_blocker")) return 0; + if (card == undefined) return; + var range = [0, 2]; + game.checkMod(card, player, range, "selectTarget", player); return range; }, - filterOk:function(){ - var card=ui.selected.cards[0]; - if(!card) return false; - if(get.position(card)=='s'&&!ui.selected.targets.length) return false; + filterOk: function () { + var card = ui.selected.cards[0]; + if (!card) return false; + if (get.position(card) == "s" && !ui.selected.targets.length) return false; return true; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - prompt:function(){ - var player=_status.event.player,use=!player.hasSkill('sblianhuan_blocker'); - return '重铸一张♣手牌'+(use?';或将一张♣手牌当【铁索连环】使用':''); + prompt: function () { + var player = _status.event.player, + use = !player.hasSkill("sblianhuan_blocker"); + return "重铸一张♣手牌" + (use ? ";或将一张♣手牌当【铁索连环】使用" : ""); }, - group:['sblianhuan_use','sblianhuan_add','sblianhuan_discard2'], - multitarget:true, - multiline:true, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - if(targets.length){ - player.addTempSkill('sblianhuan_blocker','phaseUseAfter'); - var card=get.autoViewAs({name:'tiesuo'},cards); - player.useCard(card,cards,targets); - } - else{ + group: ["sblianhuan_use", "sblianhuan_add", "sblianhuan_discard2"], + multitarget: true, + multiline: true, + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + if (targets.length) { + player.addTempSkill("sblianhuan_blocker", "phaseUseAfter"); + var card = get.autoViewAs({ name: "tiesuo" }, cards); + player.useCard(card, cards, targets); + } else { player.loseToDiscardpile(cards); player.draw(cards.length); } }, - subSkill:{ - blocker:{charlotte:true}, - use:{ - audio:'sblianhuan', - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='tiesuo'&&!player.storage.sblianhuan; + subSkill: { + blocker: { charlotte: true }, + use: { + audio: "sblianhuan", + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "tiesuo" && !player.storage.sblianhuan; }, - check:function(event,player){ - var eff=0,targets=event.targets.filter(i=>!i.isLinked()); - for(var target of targets){ - eff+=get.attitude(player,target); + check: function (event, player) { + var eff = 0, + targets = event.targets.filter((i) => !i.isLinked()); + for (var target of targets) { + eff += get.attitude(player, target); } - return eff<-1; + return eff < -1; }, - prompt2:'失去1点体力,然后当此牌指定第一个目标后,你随机弃置所有不处于连环状态的目标角色各一张手牌', - content:function(){ - 'step 0' + prompt2: + "失去1点体力,然后当此牌指定第一个目标后,你随机弃置所有不处于连环状态的目标角色各一张手牌", + content: function () { + "step 0"; player.loseHp(); - 'step 1' - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.sblianhuan=true; - trigger._sblianhuan=true; - player.addTempSkill('sblianhuan_discard','phaseUseAfter'); - } - }, - discard:{ - trigger:{global:'useCardToPlayered'}, - forced:true, - locked:false, - popup:false, - charlotte:true, - filter:function(event,player){ - return event.isFirstTarget&&event.card.storage&&event.card.storage.sblianhuan; + "step 1"; + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.sblianhuan = true; + trigger._sblianhuan = true; + player.addTempSkill("sblianhuan_discard", "phaseUseAfter"); }, - content:function(){ - 'step 0' - event.targets=trigger.targets.filter(i=>!i.isLinked()); - if(!event.targets.length) event.finish(); - else player.logSkill('sblianhuan_discard',event.targets); - 'step 1' - var target=targets.shift(); - var cards=target.getCards('h',card=>{ - return lib.filter.cardDiscardable(card,player,'sblianhuan'); + }, + discard: { + trigger: { global: "useCardToPlayered" }, + forced: true, + locked: false, + popup: false, + charlotte: true, + filter: function (event, player) { + return event.isFirstTarget && event.card.storage && event.card.storage.sblianhuan; + }, + content: function () { + "step 0"; + event.targets = trigger.targets.filter((i) => !i.isLinked()); + if (!event.targets.length) event.finish(); + else player.logSkill("sblianhuan_discard", event.targets); + "step 1"; + var target = targets.shift(); + var cards = target.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, player, "sblianhuan"); }); - if(cards.length>0){ + if (cards.length > 0) { player.line(target); target.discard(cards.randomGet()); } - if(targets.length) event.redo(); - } - }, - add:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - return event.card.name=='tiesuo'&&player.storage.sblianhuan&&game.hasPlayer(current=>{ - return !event.targets.includes(current)&&player.canUse(event.card,current); - }); + if (targets.length) event.redo(); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('sblianhuan_add'),'为'+get.translation(trigger.card)+'额外指定任意个目标',[1,Infinity],function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,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.delayx(); - event.targets=result.targets; - } - else{ + }, + add: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + return ( + event.card.name == "tiesuo" && + player.storage.sblianhuan && + game.hasPlayer((current) => { + return ( + !event.targets.includes(current) && player.canUse(event.card, current) + ); + }) + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("sblianhuan_add"), + "为" + get.translation(trigger.card) + "额外指定任意个目标", + [1, Infinity], + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, 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.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - player.logSkill('sblianhuan_add',event.targets); + "step 2"; + player.logSkill("sblianhuan_add", event.targets); trigger.targets.addArray(event.targets); - } - }, - discard2:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - locked:false, - popup:false, - filter:function(event,player){ - return event.isFirstTarget&&event.card.name=='tiesuo'&&player.storage.sblianhuan&&!event.getParent()._sblianhuan; }, - content:function(){ - 'step 0' - event.targets=trigger.targets.filter(i=>!i.isLinked()); - if(!event.targets.length) event.finish(); - else player.logSkill('sblianhuan_discard2',event.targets); - 'step 1' - var target=targets.shift(); - var cards=target.getCards('h',card=>{ - return lib.filter.cardDiscardable(card,player,'sblianhuan'); + }, + discard2: { + trigger: { player: "useCardToPlayered" }, + forced: true, + locked: false, + popup: false, + filter: function (event, player) { + return ( + event.isFirstTarget && + event.card.name == "tiesuo" && + player.storage.sblianhuan && + !event.getParent()._sblianhuan + ); + }, + content: function () { + "step 0"; + event.targets = trigger.targets.filter((i) => !i.isLinked()); + if (!event.targets.length) event.finish(); + else player.logSkill("sblianhuan_discard2", event.targets); + "step 1"; + var target = targets.shift(); + var cards = target.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, player, "sblianhuan"); }); - if(cards.length>0){ + if (cards.length > 0) { player.line(target); target.discard(cards.randomGet()); } - if(targets.length) event.redo(); - } + if (targets.length) event.redo(); + }, }, - } + }, }, - sbniepan:{ - audio:2, - enable:'chooseToUse', - mark:true, - skillAnimation:true, - limited:true, - animationColor:'orange', - filter:function(event,player){ - return event.type=='dying'&&player==event.dying; + sbniepan: { + audio: 2, + enable: "chooseToUse", + mark: true, + skillAnimation: true, + limited: true, + animationColor: "orange", + filter: function (event, player) { + return event.type == "dying" && player == event.dying; }, - content:function(){ - 'step 0' - player.awakenSkill('sbniepan'); - player.discard(player.getCards('hej')); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("sbniepan"); + player.discard(player.getCards("hej")); + "step 1"; player.draw(2); - 'step 2' - if(player.hp<2) player.recover(2-player.hp); - 'step 3' + "step 2"; + if (player.hp < 2) player.recover(2 - player.hp); + "step 3"; player.turnOver(false); - 'step 4' + "step 4"; player.link(false); - 'step 5' - player.storage.sblianhuan=true; - game.log(player,'修改了','#g【连环】'); + "step 5"; + player.storage.sblianhuan = true; + game.log(player, "修改了", "#g【连环】"); }, - ai:{ - order:1, - skillTagFilter:function(player,arg,target){ - if(player!=target||player.storage.sbniepan) return false; + ai: { + order: 1, + skillTagFilter: function (player, arg, target) { + if (player != target || player.storage.sbniepan) return false; }, - save:true, - result:{ - player:function(player){ - if(player.hp<=0) return 10; + save: true, + result: { + player: function (player) { + if (player.hp <= 0) return 10; return 0; - } + }, }, - threaten:function(player,target){ - if(!target.storage.sbniepan) return 0.6; - } - } + threaten: function (player, target) { + if (!target.storage.sbniepan) return 0.6; + }, + }, }, //法正 - sbxuanhuo:{ - audio:2, - enable:'phaseUse', - usable:1, - group:'sbxuanhuo_rob', - filterTarget:function(card,player,target){ - return !target.hasMark('sbxuanhuo_mark')&&player!=target; + sbxuanhuo: { + audio: 2, + enable: "phaseUse", + usable: 1, + group: "sbxuanhuo_rob", + filterTarget: function (card, player, target) { + return !target.hasMark("sbxuanhuo_mark") && player != target; }, - filterCard:true, - position:'he', - discard:false, - lose:false, - delay:false, - onremove:function(player){ + filterCard: true, + position: "he", + discard: false, + lose: false, + delay: false, + onremove: function (player) { delete player.storage.sbxuanhuo; - player.unmarkSkill('sbxuanhuo'); + player.unmarkSkill("sbxuanhuo"); }, - check:function(card){ - return 6.5-get.value(card); + check: function (card) { + return 6.5 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target); - if(player.storage.sbxuanhuo&&player.storage.sbxuanhuo[target.playerid]) delete player.storage.sbxuanhuo[target.playerid]; - 'step 1' - target.addMark('sbxuanhuo_mark'); - var history=target.getAllHistory('lose'); - if(history.length){ - history[history.length-1].sbxuanhuo_mark=true; + content: function () { + "step 0"; + player.give(cards, target); + if (player.storage.sbxuanhuo && player.storage.sbxuanhuo[target.playerid]) + delete player.storage.sbxuanhuo[target.playerid]; + "step 1"; + target.addMark("sbxuanhuo_mark"); + var history = target.getAllHistory("lose"); + if (history.length) { + history[history.length - 1].sbxuanhuo_mark = true; } }, - getNum:function(current,skill){ - var num=0; - var history=current.getAllHistory('lose'); - if(history.length){ - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - if(evt.sbxuanhuo_mark) break; - if(typeof skill=='string'){ - if(evt.getParent(2).name==skill) num+=evt.cards2.length; - } - else{ - var evtx=evt.getParent(),player=skill; - if(evtx.name=='gain'){ - var cards=evtx.cards; - if(evtx.player==player&&cards.length>0) num+=cards.length; - } - else if(evtx.name=='loseAsync'){ - if(evtx.type!='gain'||evtx.giver) return false; - var cards=evtx.getl(current).cards2; - var cardsx=evtx.getg(player); - if(cardsx.length>0) num+=cardsx.length; + getNum: function (current, skill) { + var num = 0; + var history = current.getAllHistory("lose"); + if (history.length) { + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + if (evt.sbxuanhuo_mark) break; + if (typeof skill == "string") { + if (evt.getParent(2).name == skill) num += evt.cards2.length; + } else { + var evtx = evt.getParent(), + player = skill; + if (evtx.name == "gain") { + var cards = evtx.cards; + if (evtx.player == player && cards.length > 0) num += cards.length; + } else if (evtx.name == "loseAsync") { + if (evtx.type != "gain" || evtx.giver) return false; + var cards = evtx.getl(current).cards2; + var cardsx = evtx.getg(player); + if (cardsx.length > 0) num += cardsx.length; } } } } return num; }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return -Math.sqrt(Math.max(target.hp,1)); - } - } - }, - marktext:'惑', - intro:{ - content:function(storage,player){ - if(!storage||get.is.empty(storage)) return '未得到过牌'; - var map=(_status.connectMode?lib.playerOL:game.playerMap); - var str='已得到'; - for(var i in storage){ - str+=get.translation(map[i])+'的'+get.cnNumber(storage[i])+'张牌、'; - } - return str.slice(0,-1); - } - }, - subSkill:{ - mark:{ - marktext:'眩', - intro:{ - name:'眩惑', - name2:'眩', - markcount:()=>0, - content:'已获得“眩”标记', - } + ai: { + order: 9, + result: { + target: function (player, target) { + return -Math.sqrt(Math.max(target.hp, 1)); + }, }, - rob:{ - audio:'sbxuanhuo', - trigger:{ - global:['gainAfter','loseAsyncAfter'], - }, - forced:true, - locked:false, - direct:true, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - if(evt&&evt.name=='phaseDraw') return false; - return game.hasPlayer(current=>{ - if(!event.getg(current).length||!current.hasMark('sbxuanhuo_mark')) return false; - if(evt&&evt.player==current) return false; - if(lib.skill.sbxuanhuo.getNum(current,'sbxuanhuo_rob')>=5) return false; - return current.hasCard(card=>lib.filter.canBeGained(card,current,player),'he'); - }); - }, - content:function(){ - 'step 0' - var evt=trigger.getParent('phaseDraw'); - var targets=game.filterPlayer(current=>{ - if(!trigger.getg(current).length||!current.hasMark('sbxuanhuo_mark')) return false; - if(evt&&evt.player==current) return false; - if(lib.skill.sbxuanhuo.getNum(current,'sbxuanhuo_rob')>=5) return false; - return current.hasCard(card=>lib.filter.canBeGained(card,current,player),'he'); - }); - event.targets=targets; - 'step 1' - var target=targets.shift(); - player.logSkill('sbxuanhuo',target); - var hs=target.getCards('h',card=>lib.filter.canBeGained(card,target,player)); - if(hs.length){ - player.gain(hs.randomGet(),target,'giveAuto'); - if(!player.storage.sbxuanhuo) player.storage.sbxuanhuo={}; - player.storage.sbxuanhuo[target.playerid]=lib.skill.sbxuanhuo.getNum(target,'sbxuanhuo_rob')+1; - player.markSkill('sbxuanhuo'); - } - if(targets.length>0) event.redo(); - }, - } - } - }, - sbenyuan:{ - audio:2, - forced:true, - direct:true, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(current=>current.hasMark('sbxuanhuo_mark')); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>current.hasMark('sbxuanhuo_mark')); - event.targets=targets; - 'step 1' - var target=targets.shift(); - event.target=target; - player.logSkill('sbenyuan',target); - target.removeMark('sbxuanhuo_mark',target.countMark('sbxuanhuo_mark')); - game.players.forEach(current=>{ - var storage=current.storage.sbxuanhuo; - if(storage&&storage[target.playerid]) delete storage[target.playerid]; - if(storage&&get.is.empty(storage)){ + marktext: "惑", + intro: { + content: function (storage, player) { + if (!storage || get.is.empty(storage)) return "未得到过牌"; + var map = _status.connectMode ? lib.playerOL : game.playerMap; + var str = "已得到"; + for (var i in storage) { + str += get.translation(map[i]) + "的" + get.cnNumber(storage[i]) + "张牌、"; + } + return str.slice(0, -1); + }, + }, + subSkill: { + mark: { + marktext: "眩", + intro: { + name: "眩惑", + name2: "眩", + markcount: () => 0, + content: "已获得“眩”标记", + }, + }, + rob: { + audio: "sbxuanhuo", + trigger: { + global: ["gainAfter", "loseAsyncAfter"], + }, + forced: true, + locked: false, + direct: true, + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + if (evt && evt.name == "phaseDraw") return false; + return game.hasPlayer((current) => { + if (!event.getg(current).length || !current.hasMark("sbxuanhuo_mark")) + return false; + if (evt && evt.player == current) return false; + if (lib.skill.sbxuanhuo.getNum(current, "sbxuanhuo_rob") >= 5) return false; + return current.hasCard( + (card) => lib.filter.canBeGained(card, current, player), + "he" + ); + }); + }, + content: function () { + "step 0"; + var evt = trigger.getParent("phaseDraw"); + var targets = game.filterPlayer((current) => { + if (!trigger.getg(current).length || !current.hasMark("sbxuanhuo_mark")) + return false; + if (evt && evt.player == current) return false; + if (lib.skill.sbxuanhuo.getNum(current, "sbxuanhuo_rob") >= 5) return false; + return current.hasCard( + (card) => lib.filter.canBeGained(card, current, player), + "he" + ); + }); + event.targets = targets; + "step 1"; + var target = targets.shift(); + player.logSkill("sbxuanhuo", target); + var hs = target.getCards("h", (card) => + lib.filter.canBeGained(card, target, player) + ); + if (hs.length) { + player.gain(hs.randomGet(), target, "giveAuto"); + if (!player.storage.sbxuanhuo) player.storage.sbxuanhuo = {}; + player.storage.sbxuanhuo[target.playerid] = + lib.skill.sbxuanhuo.getNum(target, "sbxuanhuo_rob") + 1; + player.markSkill("sbxuanhuo"); + } + if (targets.length > 0) event.redo(); + }, + }, + }, + }, + sbenyuan: { + audio: 2, + forced: true, + direct: true, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer((current) => current.hasMark("sbxuanhuo_mark")); + }, + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => current.hasMark("sbxuanhuo_mark")); + event.targets = targets; + "step 1"; + var target = targets.shift(); + event.target = target; + player.logSkill("sbenyuan", target); + target.removeMark("sbxuanhuo_mark", target.countMark("sbxuanhuo_mark")); + game.players.forEach((current) => { + var storage = current.storage.sbxuanhuo; + if (storage && storage[target.playerid]) delete storage[target.playerid]; + if (storage && get.is.empty(storage)) { delete current.storage.sbxuanhuo; - current.unmarkSkill('sbxuanhuo'); + current.unmarkSkill("sbxuanhuo"); } }); - var num=lib.skill.sbxuanhuo.getNum(target,player); - if(num>=3){ - var cards=player.getCards('he'); - if(!cards.length) event._result={bool:false}; - else if(cards.length<=3) event._result={bool:true,cards:cards}; - else player.chooseCard('恩怨:交给'+get.translation(target)+'三张牌',true,3,'he'); - } - else{ + var num = lib.skill.sbxuanhuo.getNum(target, player); + if (num >= 3) { + var cards = player.getCards("he"); + if (!cards.length) event._result = { bool: false }; + else if (cards.length <= 3) event._result = { bool: true, cards: cards }; + else + player.chooseCard( + "恩怨:交给" + get.translation(target) + "三张牌", + true, + 3, + "he" + ); + } else { target.loseHp(); player.recover(); event.goto(3); } - 'step 2' - if(result.bool) player.give(result.cards,target); - 'step 3' - if(targets.length) event.goto(1); - } + "step 2"; + if (result.bool) player.give(result.cards, target); + "step 3"; + if (targets.length) event.goto(1); + }, + ai: { + combo: "sbxuanhuo", + }, }, //姜维 - sbtiaoxin:{ - audio:2, - enable:'phaseUse', - usable:1, - chargeSkill:true, - filter:function(event,player){ - return player.hasMark('charge'); + sbtiaoxin: { + audio: 2, + enable: "phaseUse", + usable: 1, + chargeSkill: true, + filter: function (event, player) { + return player.hasMark("charge"); }, - filterTarget:lib.filter.notMe, - selectTarget:function(){ - return [1,_status.event.player.countMark('charge')]; + filterTarget: lib.filter.notMe, + selectTarget: function () { + return [1, _status.event.player.countMark("charge")]; }, - multiline:true, - group:'sbtiaoxin_backflow', - content:function(){ - 'step 0' - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'挑衅:对'+get.translation(player)+'使用一张杀,或交给其一张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',player); - 'step 1' - if(!result.bool&&target.countCards('he')>0){ - target.chooseCard('he','交给'+get.translation(player)+'一张牌',true); - } - else event.finish(); - 'step 2' - if(result.bool){ - target.give(result.cards,player); + multiline: true, + group: "sbtiaoxin_backflow", + content: function () { + "step 0"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "挑衅:对" + get.translation(player) + "使用一张杀,或交给其一张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + if (!result.bool && target.countCards("he") > 0) { + target.chooseCard("he", "交给" + get.translation(player) + "一张牌", true); + } else event.finish(); + "step 2"; + if (result.bool) { + target.give(result.cards, player); } }, - contentAfter:function(){ - player.removeMark('charge',targets.length); + contentAfter: function () { + player.removeMark("charge", targets.length); }, - ai:{ - threaten:1.2, - order:4, - expose:0.2, - result:{ - target:function(player,target){ - if(target.countGainableCards(player,'he')==0) return 0; + ai: { + threaten: 1.2, + order: 4, + expose: 0.2, + result: { + target: function (player, target) { + if (target.countGainableCards(player, "he") == 0) return 0; return -1; }, - player:function(player,target){ - if(!target.canUse('sha',player)) return 0; - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.hp<=2) return -2; - if(player.countCards('h','shan')==0) return -1; + player: function (player, target) { + if (!target.canUse("sha", player)) return 0; + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.hp <= 2) return -2; + if (player.countCards("h", "shan") == 0) return -1; return -0.5; - } + }, }, }, - subSkill:{ - backflow:{ - audio:'sbtiaoxin', - trigger:{ - player:['loseAfter','enterGame'], - global:['loseAsyncAfter','phaseBefore'] + subSkill: { + backflow: { + audio: "sbtiaoxin", + trigger: { + player: ["loseAfter", "enterGame"], + global: ["loseAsyncAfter", "phaseBefore"], }, - forced:true, - filter:function(event,player){ - if(player.countMark('charge')>=4) return false; - if(event.name.indexOf('lose')==0){ - if(event.type!='discard') return false; - var evt=event.getParent('phaseDiscard'); - return evt&&evt.player==player&&event.getl(player).cards2.length>0; - } - else{ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + if (player.countMark("charge") >= 4) return false; + if (event.name.indexOf("lose") == 0) { + if (event.type != "discard") return false; + var evt = event.getParent("phaseDiscard"); + return evt && evt.player == player && event.getl(player).cards2.length > 0; + } else { + return event.name != "phase" || game.phaseNumber == 0; } }, - content:function(){ - var num=Math.min(4-player.countMark('charge'),trigger.name.indexOf('lose')==0?trigger.getl(player).cards2.length:4); - if(num>0) player.addMark('charge',num); - } - } - } + content: function () { + var num = Math.min( + 4 - player.countMark("charge"), + trigger.name.indexOf("lose") == 0 ? trigger.getl(player).cards2.length : 4 + ); + if (num > 0) player.addMark("charge", num); + }, + }, + }, }, - sbzhiji:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - var len=0; - player.getAllHistory('useSkill',evt=>{ - if(evt.skill!='sbtiaoxin') return false; - len+=evt.targets.length; + sbzhiji: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + var len = 0; + player.getAllHistory("useSkill", (evt) => { + if (evt.skill != "sbtiaoxin") return false; + len += evt.targets.length; }); - return len>=4; + return len >= 4; }, - content:function(){ - 'step 0' - player.awakenSkill('sbzhiji'); + content: function () { + "step 0"; + player.awakenSkill("sbzhiji"); player.loseMaxHp(); - 'step 1' - player.chooseTarget('志继:令至少一名角色获得“北伐”标记',true,[1,Infinity]).set('ai',target=>-get.attitude(player,target)); - 'step 2' - if(result.bool){ - player.line(result.targets,'fire'); - result.targets.forEach(target=>{ - target.addAdditionalSkill('sbzhiji_'+player.playerid,'sbzhiji_beifa'); - target.markAuto('sbzhiji_beifa',[player]); + "step 1"; + player + .chooseTarget("志继:令至少一名角色获得“北伐”标记", true, [1, Infinity]) + .set("ai", (target) => -get.attitude(player, target)); + "step 2"; + if (result.bool) { + player.line(result.targets, "fire"); + result.targets.forEach((target) => { + target.addAdditionalSkill("sbzhiji_" + player.playerid, "sbzhiji_beifa"); + target.markAuto("sbzhiji_beifa", [player]); }); - player.addTempSkill('sbzhiji_clear',{player:'phaseBegin'}); - if(!event.isMine()&&!event.isOnline()) game.delayx(); + player.addTempSkill("sbzhiji_clear", { player: "phaseBegin" }); + if (!event.isMine() && !event.isOnline()) game.delayx(); } }, - subSkill:{ - beifa:{ - charlotte:true, - mark:true, - marktext:'伐', - intro:{ - name:'北伐', - name2:'北伐', - content:'使用牌只能指定$和自己为目标', + subSkill: { + beifa: { + charlotte: true, + mark: true, + marktext: "伐", + intro: { + name: "北伐", + name2: "北伐", + content: "使用牌只能指定$和自己为目标", + }, + mod: { + playerEnabled: function (card, player, target) { + if (player != target && !player.getStorage("sbzhiji_beifa").includes(target)) + return false; + }, }, - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target&&!player.getStorage('sbzhiji_beifa').includes(target)) return false; - } - } }, - clear:{ - charlotte:true, - onremove:function(player){ - game.countPlayer(function(current){ - current.removeAdditionalSkill('sbzhiji_'+player.playerid); + clear: { + charlotte: true, + onremove: function (player) { + game.countPlayer(function (current) { + current.removeAdditionalSkill("sbzhiji_" + player.playerid); }); - } - } - } + }, + }, + }, + ai: { + combo: "sbtiaoxin" + }, }, //刘备 - sbrende:{ - audio:3, - enable:['chooseToUse','chooseToRespond'], - maxNum:8, - filter:function(event,player){ - if(event.type=='wuxie'||player.hasSkill('sbrende_used')) return false; - if(player.countMark('sbrende')<2) return false; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) return true; + sbrende: { + audio: 3, + enable: ["chooseToUse", "chooseToRespond"], + maxNum: 8, + filter: function (event, player) { + if (event.type == "wuxie" || player.hasSkill("sbrende_used")) return false; + if (player.countMark("sbrende") < 2) return false; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return true; } } } return false; }, - group:['sbrende_give','sbrende_gain'], - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('仁德'); - if(event.type=='phase'){ - dialog._chosenOpt=[]; - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var list=['视为使用基本牌','交给其他角色牌']; - for(var i of list){ - var td=ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode'); - td.innerHTML=''+i+''; - td.link=i; - if(i==list[0]){ - td.classList.add('bluebg'); + group: ["sbrende_give", "sbrende_gain"], + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("仁德"); + if (event.type == "phase") { + dialog._chosenOpt = []; + var table = document.createElement("div"); + table.classList.add("add-setting"); + table.style.margin = "0"; + table.style.width = "100%"; + table.style.position = "relative"; + var list = ["视为使用基本牌", "交给其他角色牌"]; + for (var i of list) { + var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); + td.innerHTML = "" + i + ""; + td.link = i; + if (i == list[0]) { + td.classList.add("bluebg"); dialog._chosenOpt.add(td); } - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.clicked) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - _status.clicked=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(link=='交给其他角色牌') game.uncheck(); - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); - dialog._chosenOpt.remove(current); + td.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function () { + if (_status.dragged) return; + if (_status.clicked) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + _status.clicked = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (link == "交给其他角色牌") game.uncheck(); + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); + dialog._chosenOpt.remove(current); + } + dialog._chosenOpt.add(this); + this.classList.add("bluebg"); + game.check(); } - dialog._chosenOpt.add(this); - this.classList.add('bluebg'); - game.check(); - }); + ); table.appendChild(td); dialog.buttons.add(td); } dialog.content.appendChild(table); } - var cards=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) cards.push(['基本','',name]); - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) cards.push(['基本','',name,nature]); + var cards = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) cards.push(["基本", "", name]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) + cards.push(["基本", "", name, nature]); } } } - dialog.add([cards,'vcard']) + dialog.add([cards, "vcard"]); return dialog; }, - check:function(button,player){ - if(typeof button.link=='string') return -1; - if(_status.event.getParent().type!='phase') return 1; - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); + check: function (button, player) { + if (typeof button.link == "string") return -1; + if (_status.event.getParent().type != "phase") return 1; + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); }, - select:function(){ - var opts=_status.event.dialog._chosenOpt; - return opts&&opts.length&&opts[0].link=='交给其他角色牌'?0:1; + select: function () { + var opts = _status.event.dialog._chosenOpt; + return opts && opts.length && opts[0].link == "交给其他角色牌" ? 0 : 1; }, - backup:function(links,player){ - var isUse=links.length==1; - var backup=get.copy(lib.skill['sbrende_'+(isUse?'use':'give')]); - if(isUse) backup.viewAs={name:links[0][2],nature:links[0][3],isCard:true}; + backup: function (links, player) { + var isUse = links.length == 1; + var backup = get.copy(lib.skill["sbrende_" + (isUse ? "use" : "give")]); + if (isUse) backup.viewAs = { name: links[0][2], nature: links[0][3], isCard: true }; return backup; }, - prompt:function(links,player){ - var isUse=links.length==1; - return (isUse?('移去2枚“仁望”,视为使用或打出'+(get.translation(links[0][3])||'')+get.translation(links[0][2])) - :'###仁德###出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为'+lib.skill.sbrende.maxNum+')'); - } - }, - hiddenCard:function(player,name){ - return get.type(name)=='basic'&&player.countMark('sbrende')>1&&player.hasSkill('sbrende_used'); - }, - marktext:'仁', - intro:{ - name:'仁望', - name2:'仁望', - content:'mark', - }, - ai:{ - respondSha:true, - respondShan:true, - save:true, - skillTagFilter:function(player){ - return player.countMark('sbrende')>1&&!player.hasSkill('sbrende_used'); + prompt: function (links, player) { + var isUse = links.length == 1; + return isUse + ? "移去2枚“仁望”,视为使用或打出" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + : "###仁德###出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为" + + lib.skill.sbrende.maxNum + + ")"; }, - order:function(item,player){ - if(_status.event.type=='phase'&&lib.skill.sbzhangwu.ai.result.player(player)>0) return 9.1; + }, + hiddenCard: function (player, name) { + return ( + get.type(name) == "basic" && + player.countMark("sbrende") > 1 && + player.hasSkill("sbrende_used") + ); + }, + marktext: "仁", + intro: { + name: "仁望", + name2: "仁望", + content: "mark", + }, + ai: { + respondSha: true, + respondShan: true, + save: true, + skillTagFilter: function (player) { + return player.countMark("sbrende") > 1 && !player.hasSkill("sbrende_used"); + }, + order: function (item, player) { + if (_status.event.type == "phase" && lib.skill.sbzhangwu.ai.result.player(player) > 0) + return 9.1; return 0.5; }, - result:{ - player:function(player){ - if(_status.event.dying){ - return get.attitude(player,_status.event.dying); + result: { + player: function (player) { + if (_status.event.dying) { + return get.attitude(player, _status.event.dying); } - return _status.event.type=='phase'&&player.countMark('sbrende')<=2?0:1; + return _status.event.type == "phase" && player.countMark("sbrende") <= 2 ? 0 : 1; }, }, }, - subSkill:{ - backup:{}, - used:{charlotte:true}, - given:{onremove:true}, - use:{ - audio:'sbrende', - filterCard:()=>false, - selectCard:-1, - popname:true, - precontent:function(){ - player.logSkill('sbrende_use'); + subSkill: { + backup: {}, + used: { charlotte: true }, + given: { onremove: true }, + use: { + audio: "sbrende", + filterCard: () => false, + selectCard: -1, + popname: true, + precontent: function () { + player.logSkill("sbrende_use"); delete event.result.skill; - player.removeMark('sbrende',2); - player.addTempSkill('sbrende_used'); - } + player.removeMark("sbrende", 2); + player.addTempSkill("sbrende_used"); + }, }, - give:{ - audio:'sbrende', - enable:'phaseUse', - filterCard:true, - selectCard:[1,Infinity], - position:'he', - discard:false, - lose:false, - delay:false, - filter:function(event,player){ - if(player.countMark('sbrende')<2||player.hasSkill('sbrende_used')) return true; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) return false; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) return false; + give: { + audio: "sbrende", + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + position: "he", + discard: false, + lose: false, + delay: false, + filter: function (event, player) { + if (player.countMark("sbrende") < 2 || player.hasSkill("sbrende_used")) + return true; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) return false; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return false; } } } return true; }, - filterTarget:function(card,player,target){ - if(player.getStorage('sbrende_given').includes(target)) return false; - return player!=target; + filterTarget: function (card, player, target) { + if (player.getStorage("sbrende_given").includes(target)) return false; + return player != target; }, - prompt:function(event){ - return '出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为'+lib.skill.sbrende.maxNum+')'; + prompt: function (event) { + return ( + "出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为" + + lib.skill.sbrende.maxNum + + ")" + ); }, - check:function(card){ - var player=get.owner(card); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(ui.selected.cards.length+player.countMark('sbrende')>lib.skill.sbrende.maxNum) return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - if(ui.selected.cards.length>=Math.max(2,player.countCards('he')-player.hp)) return 0; - if(player.countCards('he')<=1){ - var players=game.filterPlayer(); - for(var i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + check: function (card) { + var player = get.owner(card); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if ( + ui.selected.cards.length + player.countMark("sbrende") > + lib.skill.sbrende.maxNum + ) + return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + if (ui.selected.cards.length >= Math.max(2, player.countCards("he") - player.hp)) + return 0; + if (player.countCards("he") <= 1) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('he')>player.hp) return 10-get.value(card); - if(player.countCards('he')>2) return 6-get.value(card); + if (player.countCards("he") > player.hp) return 10 - get.value(card); + if (player.countCards("he") > 2) return 6 - get.value(card); return -1; } - return 18-(ui.selected.cards.length+player.countMark('sbrende'))-get.value(card); + return ( + 18 - + (ui.selected.cards.length + player.countMark("sbrende")) - + get.value(card) + ); }, - content:function(){ - player.addTempSkill('sbrende_given','phaseUseAfter'); - player.markAuto('sbrende_given',[target]); - player.markAuto('sbrende_givenx',[target]); - player.give(cards,target); - var num=Math.min(lib.skill.sbrende.maxNum-player.countMark('sbrende'),cards.length); - if(num>0) player.addMark('sbrende',num); + content: function () { + player.addTempSkill("sbrende_given", "phaseUseAfter"); + player.markAuto("sbrende_given", [target]); + player.markAuto("sbrende_givenx", [target]); + player.give(cards, target); + var num = Math.min( + lib.skill.sbrende.maxNum - player.countMark("sbrende"), + cards.length + ); + if (num > 0) player.addMark("sbrende", num); }, - ai:{ - order:function(skill,player){ - return player.countMark('sbrende')<2?6.8:5.8; + ai: { + order: function (skill, player) { + return player.countMark("sbrende") < 2 ? 6.8 : 5.8; }, - result:{ - target:function(player,target){ - if(!player.hasFriend()&&player.hasSkill('sbzhangwu')&&ui.selected.cards.length&& - get.value(ui.selected.cards[0])>(lib.skill.sbzhangwu.filterTarget(null,player,target)?3:5)) return -0.1; - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; + result: { + target: function (player, target) { + if ( + !player.hasFriend() && + player.hasSkill("sbzhangwu") && + ui.selected.cards.length && + get.value(ui.selected.cards[0]) > + (lib.skill.sbzhangwu.filterTarget(null, player, target) ? 3 : 5) + ) + return -0.1; + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - return Math.max(1,5-nh); - } + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + return Math.max(1, 5 - nh); + }, }, - threaten:1.1 + threaten: 1.1, }, }, - gain:{ - audio:'sbrende', - trigger:{player:'phaseUseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.countMark('sbrende') 0) player.addMark("sbrende", num); }, - content:function(){ - var num=Math.min(lib.skill.sbrende.maxNum-player.countMark('sbrende'),2); - if(num>0) player.addMark('sbrende',num); - } }, }, }, - sbzhangwu:{ - audio:2, - enable:'phaseUse', - skillAnimation:'epic', - animationColor:'orange', - limited:true, - filter:function(event,player){ - if(game.roundNumber<=1) return false; - if(!game.hasPlayer(current=>lib.skill.sbzhangwu.filterTarget(null,player,current))) return false; + sbzhangwu: { + audio: 2, + enable: "phaseUse", + skillAnimation: "epic", + animationColor: "orange", + limited: true, + filter: function (event, player) { + if (game.roundNumber <= 1) return false; + if (!game.hasPlayer((current) => lib.skill.sbzhangwu.filterTarget(null, player, current))) + return false; return true; }, - filterTarget:function(card,player,target){ - if(target==player) return false; - return player.getStorage('sbrende_givenx').includes(target); + filterTarget: function (card, player, target) { + if (target == player) return false; + return player.getStorage("sbrende_givenx").includes(target); }, - selectTarget:[-1,-2], - multiline:true, - content:function(){ - 'step 0' - player.awakenSkill('sbzhangwu'); - var num=Math.min(game.roundNumber-1,3); - var cards=target.getCards('he'),count=cards.length; - if(count==0) event.finish(); - else if(count<=num) event._result={bool:true,cards:cards}; - else target.chooseCard('章武:交给'+get.translation(player)+get.cnNumber(num)+'张牌',true,'he',num); - 'step 1' - if(result.bool){ - target.give(result.cards,player); + selectTarget: [-1, -2], + multiline: true, + content: function () { + "step 0"; + player.awakenSkill("sbzhangwu"); + var num = Math.min(game.roundNumber - 1, 3); + var cards = target.getCards("he"), + count = cards.length; + if (count == 0) event.finish(); + else if (count <= num) event._result = { bool: true, cards: cards }; + else + target.chooseCard( + "章武:交给" + get.translation(player) + get.cnNumber(num) + "张牌", + true, + "he", + num + ); + "step 1"; + if (result.bool) { + target.give(result.cards, player); } }, - contentAfter:function(){ - 'step 0' + contentAfter: function () { + "step 0"; player.recover(3); - 'step 1' - player.removeSkills('sbrende'); + "step 1"; + player.removeSkills("sbrende"); game.delayx(); }, - ai:{ - order:9, - combo:'sbrende', - result:{ - player:function(player,target){ - var targets=game.filterPlayer(current=>lib.skill.sbzhangwu.filterTarget(null,player,current)); - if(!targets.length) return 0; - var eff=0; - for(var target of targets){ - eff+=get.effect(target,{name:'shunshou_copy2'},player,player); + ai: { + order: 9, + combo: "sbrende", + result: { + player: function (player, target) { + var targets = game.filterPlayer((current) => + lib.skill.sbzhangwu.filterTarget(null, player, current) + ); + if (!targets.length) return 0; + var eff = 0; + for (var target of targets) { + eff += get.effect(target, { name: "shunshou_copy2" }, player, player); } - eff+=15-5*Math.max(0,3-player.getDamagedHp()); - return eff>15?1:0; + eff += 15 - 5 * Math.max(0, 3 - player.getDamagedHp()); + return eff > 15 ? 1 : 0; }, - } - } + }, + }, }, - sbjijiang:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - zhuSkill:true, - unique:true, - popup:false, - filter:function(event,player){ - if(!player.hasZhuSkill('sbjijiang')) return false; - return game.hasPlayer(current=>{ - if(current.group!='shu'||player==current||current.hpcurrent.inRange(currentx)); + sbjijiang: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + zhuSkill: true, + unique: true, + popup: false, + filter: function (event, player) { + if (!player.hasZhuSkill("sbjijiang")) return false; + return game.hasPlayer((current) => { + if (current.group != "shu" || player == current || current.hp < player.hp) + return false; + return game.hasPlayer((currentx) => current.inRange(currentx)); }); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt2('sbjijiang'),2).set('filterTarget',(card,player,target)=>{ - if(!ui.selected.targets.length) return target.group=='shu'&&target.hp>=player.hp&&target!=player; - var current=ui.selected.targets[0]; - return current.inRange(target); - }).set('targetprompt',['进行选择','出杀对象']).set('multitarget',true).set('ai',target=>{ - var player=_status.event.player; - if(ui.selected.targets.length){ - var current=ui.selected.targets[0]; - return get.effect(target,new lib.element.VCard({name:'sha'}),current,player); - } - let curs=game.filterPlayer(current=>{ - return target!==current&&target.inRange(current)&&target.canUse({name:'sha',isCard:true},current,false); - }); - if(!curs.length){ - let att=get.attitude(player,target); - if(att>=0) return 0; - return -att*get.threaten(target,player); - } - return curs.reduce((max,i)=>Math.max(max,get.effect(i,new lib.element.VCard({name:'sha'}),target,player)),-1); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("sbjijiang"), 2) + .set("filterTarget", (card, player, target) => { + if (!ui.selected.targets.length) + return target.group == "shu" && target.hp >= player.hp && target != player; + var current = ui.selected.targets[0]; + return current.inRange(target); + }) + .set("targetprompt", ["进行选择", "出杀对象"]) + .set("multitarget", true) + .set("ai", (target) => { + var player = _status.event.player; + if (ui.selected.targets.length) { + var current = ui.selected.targets[0]; + return get.effect( + target, + new lib.element.VCard({ name: "sha" }), + current, + player + ); + } + let curs = game.filterPlayer((current) => { + return ( + target !== current && + target.inRange(current) && + target.canUse({ name: "sha", isCard: true }, current, false) + ); + }); + if (!curs.length) { + let att = get.attitude(player, target); + if (att >= 0) return 0; + return -att * get.threaten(target, player); + } + return curs.reduce( + (max, i) => + Math.max( + max, + get.effect(i, new lib.element.VCard({ name: "sha" }), target, player) + ), + -1 + ); + }) + .forResult(); }, - async content(event,trigger,player){ - let targets=event.targets; - player.logSkill('sbjijiang',targets,false); + async content(event, trigger, player) { + let targets = event.targets; + player.logSkill("sbjijiang", targets, false); player.line2(targets); - var choiceList=[ - '视为对'+get.translation(targets[1])+'使用一张【杀】', - '你的下一个出牌阶段开始前,跳过此阶段' - ],result; - if(!targets[0].canUse({name:'sha',isCard:true},targets[1],false)) result={index:1}; - else result=await targets[0].chooseControl().set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',get.effect(targets[1],{name:'sha'},targets[0],targets[0])>get.effect(targets[0],{name:'lebu'},targets[0],targets[0])?0:1).forResult(); - if(result.index==0){ - targets[0].useCard({name:'sha',isCard:true},targets[1],false); - } - else{ - targets[0].addSkill('sbjijiang_skip'); + var choiceList = [ + "视为对" + get.translation(targets[1]) + "使用一张【杀】", + "你的下一个出牌阶段开始前,跳过此阶段", + ], + result; + if (!targets[0].canUse({ name: "sha", isCard: true }, targets[1], false)) + result = { index: 1 }; + else + result = await targets[0] + .chooseControl() + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + get.effect(targets[1], { name: "sha" }, targets[0], targets[0]) > + get.effect(targets[0], { name: "lebu" }, targets[0], targets[0]) + ? 0 + : 1 + ) + .forResult(); + if (result.index == 0) { + targets[0].useCard({ name: "sha", isCard: true }, targets[1], false); + } else { + targets[0].addSkill("sbjijiang_skip"); } }, - subSkill:{ - skip:{ - trigger:{player:'phaseUseBefore'}, - charlotte:true, - forced:true, - content:function(){ + subSkill: { + skip: { + trigger: { player: "phaseUseBefore" }, + charlotte: true, + forced: true, + content: function () { trigger.cancel(); - player.removeSkill('sbjijiang_skip'); - } + player.removeSkill("sbjijiang_skip"); + }, }, - } + }, }, //赵云 - sblongdan:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - chargeSkill:true, - filter:function(event,player){ - if(event.type=='wuxie'||!player.hasMark('charge')) return false; - var marked=player.hasSkill('sblongdan_mark',null,null,false); - for(var name of lib.inpile){ - if(!marked&&name!='sha'&&name!='shan') continue; - if(get.type(name)!='basic') continue; - if(player.hasCard(lib.skill.sblongdan.getFilter(name,player),'hs')){ - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) return true; - if(marked&&name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name,nature},'unsure'),player,event)) return true; + sblongdan: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + chargeSkill: true, + filter: function (event, player) { + if (event.type == "wuxie" || !player.hasMark("charge")) return false; + var marked = player.hasSkill("sblongdan_mark", null, null, false); + for (var name of lib.inpile) { + if (!marked && name != "sha" && name != "shan") continue; + if (get.type(name) != "basic") continue; + if (player.hasCard(lib.skill.sblongdan.getFilter(name, player), "hs")) { + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) + return true; + if (marked && name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name, nature }, "unsure"), + player, + event + ) + ) + return true; } } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - var marked=player.hasSkill('sblongdan_mark',null,null,false); - for(var name of lib.inpile){ - if(!marked&&name!='sha'&&name!='shan') continue; - if(get.type(name)!='basic') continue; - if(player.hasCard(lib.skill.sblongdan.getFilter(name,player),'hs')){ - if(event.filterCard(get.autoViewAs({name},'unsure'),player,event)) list.push(['基本','',name]); - if(marked&&name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name,nature},'unsure'),player,event)) list.push(['基本','',name,nature]) + chooseButton: { + dialog: function (event, player) { + var list = []; + var marked = player.hasSkill("sblongdan_mark", null, null, false); + for (var name of lib.inpile) { + if (!marked && name != "sha" && name != "shan") continue; + if (get.type(name) != "basic") continue; + if (player.hasCard(lib.skill.sblongdan.getFilter(name, player), "hs")) { + if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) + list.push(["基本", "", name]); + if (marked && name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name, nature }, "unsure"), + player, + event + ) + ) + list.push(["基本", "", name, nature]); } } } } - return ui.create.dialog('龙胆',[list,'vcard'],'hidden'); + return ui.create.dialog("龙胆", [list, "vcard"], "hidden"); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player,card={name:button.link[2],nature:button.link[3]}; - if(card.name=='jiu'&&Math.min(player.countMark('charge'),player.countCards('h',{type:'basic'}))<2) return 0; - return player.getUseValue(card,null,true); + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player, + card = { name: button.link[2], nature: button.link[3] }; + if ( + card.name == "jiu" && + Math.min(player.countMark("charge"), player.countCards("h", { type: "basic" })) < + 2 + ) + return 0; + return player.getUseValue(card, null, true); }, - backup:function(links,player){ + backup: function (links, player) { return { - viewAs:{ - name:links[0][2], - nature:links[0][3], + viewAs: { + name: links[0][2], + nature: links[0][3], }, - filterCard:lib.skill.sblongdan.getFilter(links[0][2],player), - position:'he', - popname:true, - check:function(card){ - return 6/Math.max(1,get.value(card)); + filterCard: lib.skill.sblongdan.getFilter(links[0][2], player), + position: "he", + popname: true, + check: function (card) { + return 6 / Math.max(1, get.value(card)); }, - precontent:function(){ - player.removeMark('charge',1); - player.addTempSkill('sblongdan_draw'); + precontent: function () { + player.removeMark("charge", 1); + player.addTempSkill("sblongdan_draw"); }, - } - }, - prompt:function(links,player){ - var marked=player.hasSkill('sblongdan_mark',null,null,false); - var card={ - name:links[0][2], - nature:links[0][3], - isCard:true, }; - if(marked) return '将一张基本牌当做'+get.translation(card)+'使用'; - return '将一张'+(card.name=='sha'?'闪':'杀')+'当做'+get.translation(card)+'使用'; + }, + prompt: function (links, player) { + var marked = player.hasSkill("sblongdan_mark", null, null, false); + var card = { + name: links[0][2], + nature: links[0][3], + isCard: true, + }; + if (marked) return "将一张基本牌当做" + get.translation(card) + "使用"; + return ( + "将一张" + + (card.name == "sha" ? "闪" : "杀") + + "当做" + + get.translation(card) + + "使用" + ); }, }, - hiddenCard:function(player,name){ - if(get.type(name)!='basic'||!player.hasMark('charge')) return false; - var marked=player.hasSkill('sblongdan_mark',null,null,false); - if(!marked&&name!='sha'&&name!='shan') return false; - return player.hasCard(lib.skill.sblongdan.getFilter(name,player),'hs'); + hiddenCard: function (player, name) { + if (get.type(name) != "basic" || !player.hasMark("charge")) return false; + var marked = player.hasSkill("sblongdan_mark", null, null, false); + if (!marked && name != "sha" && name != "shan") return false; + return player.hasCard(lib.skill.sblongdan.getFilter(name, player), "hs"); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ - return lib.skill.sblongdan.hiddenCard(player,tag=='respondSha'?'sha':'shan') + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { + return lib.skill.sblongdan.hiddenCard(player, tag == "respondSha" ? "sha" : "shan"); }, - order:9, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + order: 9, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - getFilter:function(name,player){ - if(!player.hasSkill('sblongdan_mark',null,null,false)){ - if(name=='sha') return {name:'shan'}; - if(name=='shan') return {name:'sha'}; - return (()=>false); + getFilter: function (name, player) { + if (!player.hasSkill("sblongdan_mark", null, null, false)) { + if (name == "sha") return { name: "shan" }; + if (name == "shan") return { name: "sha" }; + return () => false; } - return {type:'basic'}; + return { type: "basic" }; }, - group:'sblongdan_charge', - onremove:function(player){ - player.removeSkill('sblongdan_mark'); + group: "sblongdan_charge", + onremove: function (player) { + player.removeSkill("sblongdan_mark"); }, - subSkill:{ - backup:{audio:'sblongdan'}, - mark:{charlotte:true}, - draw:{ - charlotte:true, - trigger:{player:['useCardAfter']}, - forced:true, - popup:false, - filter:function(event,player){ - return event.skill=='sblongdan_backup'; + subSkill: { + backup: { audio: "sblongdan" }, + mark: { charlotte: true }, + draw: { + charlotte: true, + trigger: { player: ["useCardAfter"] }, + forced: true, + popup: false, + filter: function (event, player) { + return event.skill == "sblongdan_backup"; }, - content:function(){ + content: function () { player.draw(); }, }, - charge:{ - audio:'sblongdan', - trigger:{ - global:['phaseBefore','phaseEnd'], - player:'enterGame', + charge: { + audio: "sblongdan", + trigger: { + global: ["phaseBefore", "phaseEnd"], + player: "enterGame", }, - forced:true, - filter:function(event,player,name){ - if(player.countMark('charge')>2) return false; - return (name!='phaseBefore'||game.phaseNumber==0); + forced: true, + filter: function (event, player, name) { + if (player.countMark("charge") > 2) return false; + return name != "phaseBefore" || game.phaseNumber == 0; }, - content:function(){ - player.addMark('charge',1); + content: function () { + player.addMark("charge", 1); }, }, }, }, - sbjizhu:{ - audio:3, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('sbjizhu'),'和一名其他角色进行“协力”').set('ai',function(target){ - return get.threaten(target)*Math.sqrt(1+target.countCards('h'))*((target.isTurnedOver()||target.hasJudge('lebu'))?0.1:1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbjizhu',target); - player.chooseCooperationFor(target,'sbjizhu').set('ai',function(button){ - var base=0; - switch(button.link){ - case 'cooperation_damage':base=0.1;break; - case 'cooperation_draw':base=0.6;break; - case 'cooperation_discard':base=0.1;break; - case 'cooperation_use':base=0.6;break; - } - return base+Math.random(); + sbjizhu: { + audio: 3, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, get.prompt("sbjizhu"), "和一名其他角色进行“协力”") + .set("ai", function (target) { + return ( + get.threaten(target) * + Math.sqrt(1 + target.countCards("h")) * + (target.isTurnedOver() || target.hasJudge("lebu") ? 0.1 : 1) + ); }); - player.addAdditionalSkill('cooperation','sbjizhu_effect'); - } - else event.finish(); - 'step 2' + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbjizhu", target); + player.chooseCooperationFor(target, "sbjizhu").set("ai", function (button) { + var base = 0; + switch (button.link) { + case "cooperation_damage": + base = 0.1; + break; + case "cooperation_draw": + base = 0.6; + break; + case "cooperation_discard": + base = 0.1; + break; + case "cooperation_use": + base = 0.6; + break; + } + return base + Math.random(); + }); + player.addAdditionalSkill("cooperation", "sbjizhu_effect"); + } else event.finish(); + "step 2"; game.delayx(); }, - subSkill:{ - effect:{ - audio:'sbjizhu', - charlotte:true, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return player.checkCooperationStatus(event.player,'sbjizhu')&&player.hasSkill('sblongdan',null,null,false); + subSkill: { + effect: { + audio: "sbjizhu", + charlotte: true, + trigger: { global: "phaseJieshuBegin" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return ( + player.checkCooperationStatus(event.player, "sbjizhu") && + player.hasSkill("sblongdan", null, null, false) + ); }, - content:function(){ - game.log(player,'和',trigger.player,'的协力成功'); - player.addTempSkill('sblongdan_mark',{player:'phaseJieshuBegin'}); + content: function () { + game.log(player, "和", trigger.player, "的协力成功"); + player.addTempSkill("sblongdan_mark", { player: "phaseJieshuBegin" }); game.delayx(); }, }, }, - derivation:'sblongdan_shabi', + derivation: "sblongdan_shabi", + ai: { + combo: "sblongdan", + }, }, //张飞 - sbpaoxiao:{ - audio:2, - mod:{ - cardUsable:function(card){ - if(card.name=='sha') return Infinity; + sbpaoxiao: { + audio: 2, + mod: { + cardUsable: function (card) { + if (card.name == "sha") return Infinity; }, - targetInRange:function(card,player,target){ - if(card.name=='sha'&&player.getEquips(1).length>0) return true; + targetInRange: function (card, player, target) { + if (card.name == "sha" && player.getEquips(1).length > 0) return true; }, }, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - return player.hasHistory('useCard',function(evtx){ - return evtx!=event&&evtx.card.name=='sha'&&evtx.getParent('phaseUse')==evt; - },event); + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + return player.hasHistory( + "useCard", + function (evtx) { + return ( + evtx != event && evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt + ); + }, + event + ); }, - content:function(){ - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.sbpaoxiao=true; + content: function () { + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.sbpaoxiao = true; trigger.baseDamage++; trigger.directHit.addArray(game.players); - player.addTempSkill('sbpaoxiao_effect','phaseUseAfter'); + player.addTempSkill("sbpaoxiao_effect", "phaseUseAfter"); }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{player:'useCardToPlayered'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.storage&&event.card.storage.sbpaoxiao&&event.target.isIn(); + subSkill: { + effect: { + charlotte: true, + trigger: { player: "useCardToPlayered" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card.storage && event.card.storage.sbpaoxiao && event.target.isIn(); }, - content:function(){ - trigger.target.addTempSkill('fengyin'); + content: function () { + trigger.target.addTempSkill("fengyin"); }, - group:'sbpaoxiao_recoil', + group: "sbpaoxiao_recoil", }, - recoil:{ - charlotte:true, - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.storage&&event.card.storage.sbpaoxiao&&event.player.isIn(); + recoil: { + charlotte: true, + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.card.storage && + event.card.storage.sbpaoxiao && + event.player.isIn() + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - 'step 1' - var hs=player.getCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'sbpaoxiao_recoil'); + "step 1"; + var hs = player.getCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "sbpaoxiao_recoil"); }); - if(hs.length>0) player.discard(hs.randomGet()); + if (hs.length > 0) player.discard(hs.randomGet()); }, }, }, }, - sbxieji:{ - audio:3, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('sbxieji'),'和一名其他角色进行“协力”').set('ai',function(target){ - return get.threaten(target)*Math.sqrt(1+target.countCards('h'))*((target.isTurnedOver()||target.hasJudge('lebu'))?0.1:1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbxieji',target); + sbxieji: { + audio: 3, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, get.prompt("sbxieji"), "和一名其他角色进行“协力”") + .set("ai", function (target) { + return ( + get.threaten(target) * + Math.sqrt(1 + target.countCards("h")) * + (target.isTurnedOver() || target.hasJudge("lebu") ? 0.1 : 1) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbxieji", target); //选择对方的协击条件 - player.chooseCooperationFor(target,'sbxieji').set('ai',function(button){ - var base=0; - switch(button.link){ - case 'cooperation_damage':base=0.8;break; - case 'cooperation_draw':base=0.1;break; - case 'cooperation_discard':base=0.1;break; - case 'cooperation_use':base=0.1;break; + player.chooseCooperationFor(target, "sbxieji").set("ai", function (button) { + var base = 0; + switch (button.link) { + case "cooperation_damage": + base = 0.8; + break; + case "cooperation_draw": + base = 0.1; + break; + case "cooperation_discard": + base = 0.1; + break; + case "cooperation_use": + base = 0.1; + break; } - return base+Math.random(); + return base + Math.random(); }); //保证技能cooperation被移除之后 失去该技能 - player.addAdditionalSkill('cooperation','sbxieji_effect'); - } - else event.finish(); - 'step 2' + player.addAdditionalSkill("cooperation", "sbxieji_effect"); + } else event.finish(); + "step 2"; game.delayx(); }, - subSkill:{ - effect:{ - audio:'sbxieji', - charlotte:true, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ + subSkill: { + effect: { + audio: "sbxieji", + charlotte: true, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { //判断自己是否有目标为该角色 且已经完成的协力记录 - return player.checkCooperationStatus(event.player,'sbxieji'); + return player.checkCooperationStatus(event.player, "sbxieji"); }, - content:function(){ - 'step 0' - game.log(player,'和',trigger.player,'的协力成功'); - player.chooseTarget('协击:请选择【杀】的目标','你和'+get.translation(trigger.player)+'协力成功,可以视为对至多三名其他角色使用一张【杀】,且此【杀】造成伤害时,你摸等同于伤害值的牌',[1,3],true,function(card,player,target){ - return player.canUse('sha',target,false); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }); - 'step 1' - if(result.bool){ - player.addTempSkill('sbxieji_reward','sbxieji_effectAfter'); - player.useCard({ - name:'sha', - isCard:true, - storage:{sbxieji:true}, - },'sbxieji_effect',result.targets); + content: function () { + "step 0"; + game.log(player, "和", trigger.player, "的协力成功"); + player + .chooseTarget( + "协击:请选择【杀】的目标", + "你和" + + get.translation(trigger.player) + + "协力成功,可以视为对至多三名其他角色使用一张【杀】,且此【杀】造成伤害时,你摸等同于伤害值的牌", + [1, 3], + true, + function (card, player, target) { + return player.canUse("sha", target, false); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }); + "step 1"; + if (result.bool) { + player.addTempSkill("sbxieji_reward", "sbxieji_effectAfter"); + player.useCard( + { + name: "sha", + isCard: true, + storage: { sbxieji: true }, + }, + "sbxieji_effect", + result.targets + ); } }, }, - reward:{ - charlotte:true, - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.storage&&event.card.storage.sbxieji&&event.getParent().type=='card'; + reward: { + charlotte: true, + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.storage && + event.card.storage.sbxieji && + event.getParent().type == "card" + ); }, - content:function(){ + content: function () { player.draw(trigger.num); }, }, }, }, //徐晃 - sbduanliang:{ - audio:1, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - player.chooseToDuiben(target).set('title','谋弈').set('namelist',[ - '固守城池','突出重围','围城断粮','擂鼓进军' - ]).set('ai',button=>{ - var source=_status.event.getParent().player,target=_status.event.getParent().target; - if(get.effect(target,{name:'juedou'},source,source)>=10&&button.link[2]=='db_def2'&&Math.random()<0.5) return 10; - return 1+Math.random(); - }); - 'step 1' - if(result.bool){ - if(result.player=='db_def1'){ - if(target.hasJudge('bingliang')) player.gainPlayerCard(target,'he',true); - else{ - if(ui.cardPile.childNodes.length>0) { - if(player.canUse(get.autoViewAs({name:'bingliang'},[ui.cardPile.firstChild]),target,false)){ - player.useCard({name:'bingliang'},target,get.cards()); + sbduanliang: { + audio: 1, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + player + .chooseToDuiben(target) + .set("title", "谋弈") + .set("namelist", ["固守城池", "突出重围", "围城断粮", "擂鼓进军"]) + .set("ai", (button) => { + var source = _status.event.getParent().player, + target = _status.event.getParent().target; + if ( + get.effect(target, { name: "juedou" }, source, source) >= 10 && + button.link[2] == "db_def2" && + Math.random() < 0.5 + ) + return 10; + return 1 + Math.random(); + }); + "step 1"; + if (result.bool) { + if (result.player == "db_def1") { + if (target.hasJudge("bingliang")) player.gainPlayerCard(target, "he", true); + else { + if (ui.cardPile.childNodes.length > 0) { + if ( + player.canUse( + get.autoViewAs({ name: "bingliang" }, [ui.cardPile.firstChild]), + target, + false + ) + ) { + player.useCard({ name: "bingliang" }, target, get.cards()); } } } - } - else{ - var card={name:'juedou',isCard:true}; - if(player.canUse(card,target)) player.useCard(card,target); + } else { + var card = { name: "juedou", isCard: true }; + if (player.canUse(card, target)) player.useCard(card, target); } } }, - ai:{ - threaten:1.2, - order:5.5, - result:{ - player:1, - target:-1 - } + ai: { + threaten: 1.2, + order: 5.5, + result: { + player: 1, + target: -1, + }, + }, + subSkill: { + true1: { audio: true }, + true2: { audio: true }, + false: { audio: true }, }, - subSkill:{ - true1:{audio:true}, - true2:{audio:true}, - false:{audio:true}, - } }, - sbshipo:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current.hp { + return current.hp < player.hp || current.hasJudge("bingliang"); }); }, - content:function(){ - 'step 0' - var list=[]; - var choiceList=['选择一名体力少于你的角色','选择所有判定区有兵粮寸断的其他角色']; - var bool=false,bool2=false; - game.filterPlayer(current=>{ - if(current.hp { + if (current.hp < player.hp) bool = true; + if (current.hasJudge("bingliang")) bool2 = true; }); - if(bool) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(bool2) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseControl(list,'cancel2').set('prompt',get.prompt2('sbshipo')).set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',(function(){ - var eff=0,eff2=0; - if(!list.includes('选项一')) eff=Infinity; - if(!list.includes('选项二')) eff2=Infinity; - game.countPlayer(current=>{ - if(current.hp"; + if (bool2) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - if(eff>0&&eff2>0) return 'cancel2'; - return eff { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var eff = 0, + eff2 = 0; + if (!list.includes("选项一")) eff = Infinity; + if (!list.includes("选项二")) eff2 = Infinity; + game.countPlayer((current) => { + if (current.hp < player.hp) { + var effx = + get.attitude(player, current) / + Math.sqrt( + Math.max(0.1, 2 * current.hp + current.countCards("h")) + ); + if (effx < eff) eff = effx; + } + if (current.hasJudge("bingliang")) + eff2 += + get.attitude(player, current) / + Math.sqrt( + Math.max(0.1, 2 * current.hp + current.countCards("h")) + ); + }); + if (eff > 0 && eff2 > 0) return "cancel2"; + return eff < eff2 ? "选项一" : "选项二"; + })() + ); + "step 1"; + if (result.control == "cancel2") { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + event.finish(); + return; } - if(result.control=='选项一'){ - player.chooseTarget('选择一名体力少于你的角色',(card,player,target)=>target.hp-get.attitude(player,target)/Math.sqrt(Math.max(0.1,2*target.hp+target.countCards('h')))); + if (result.control == "选项一") { + player + .chooseTarget( + "选择一名体力少于你的角色", + (card, player, target) => target.hp < player.hp, + true + ) + .set( + "ai", + (target) => + -get.attitude(player, target) / + Math.sqrt(Math.max(0.1, 2 * target.hp + target.countCards("h"))) + ); + } else { + event._result = { + bool: true, + targets: game.filterPlayer((current) => current.hasJudge("bingliang")), + }; } - else{ - event._result={bool:true,targets:game.filterPlayer(current=>current.hasJudge('bingliang'))}; - } - 'step 2' - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - if(result.bool){ - var targets=result.targets; - player.logSkill('sbshipo',targets); - event.targets=targets.sortBySeat(); - event.cards=[]; - } - else event.finish(); - 'step 3' - var target=event.targets.shift(); - event.target=target; - target.chooseCard('交给'+get.translation(player)+'一张手牌,或受到1点伤害').set('ai',card=>{ - var player=_status.event.player,source=_status.event.getParent().player; - if(get.damageEffect(player,source,player)>0) return 0; - if(get.attitude(player,source)>0) return 1; - if(get.tag(card,'recover')>0) return 0; - return (player.hp<2?7:5.5)-get.value(card); + "step 2"; + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); }); - 'step 4' - if(result.bool){ + if (result.bool) { + var targets = result.targets; + player.logSkill("sbshipo", targets); + event.targets = targets.sortBySeat(); + event.cards = []; + } else event.finish(); + "step 3"; + var target = event.targets.shift(); + event.target = target; + target + .chooseCard("交给" + get.translation(player) + "一张手牌,或受到1点伤害") + .set("ai", (card) => { + var player = _status.event.player, + source = _status.event.getParent().player; + if (get.damageEffect(player, source, player) > 0) return 0; + if (get.attitude(player, source) > 0) return 1; + if (get.tag(card, "recover") > 0) return 0; + return (player.hp < 2 ? 7 : 5.5) - get.value(card); + }); + "step 4"; + if (result.bool) { event.cards.addArray(result.cards); - target.give(result.cards,player); - } - else{ + target.give(result.cards, player); + } else { target.damage(); } - 'step 5' - if(event.targets.length) event.goto(3); - else{ - var cards=event.cards.filter(card=>get.owner(card)==player&&get.position(card)=='h'); - if(!cards.length) event.finish(); - else event.cards=cards; + "step 5"; + if (event.targets.length) event.goto(3); + else { + var cards = event.cards.filter( + (card) => get.owner(card) == player && get.position(card) == "h" + ); + if (!cards.length) event.finish(); + else event.cards = cards; } - 'step 6' + "step 6"; player.chooseCardTarget({ - filterCard:function(card,player,target){ + filterCard: function (card, player, target) { return _status.event.getParent().cards.includes(card); }, - filterTarget:lib.filter.notMe, - selectCard:[1,event.cards.length], - prompt:'是否将任意张得到的牌交给一名其他角色?', - ai1:function(card){ - var player=_status.event.player; - var val=player.getUseValue(card); - if(val>0) return 2; - if(player.hp<=2&&val==0&&get.value(card)>5) return 0; - return Math.random()>0.5?1:0; + filterTarget: lib.filter.notMe, + selectCard: [1, event.cards.length], + prompt: "是否将任意张得到的牌交给一名其他角色?", + ai1: function (card) { + var player = _status.event.player; + var val = player.getUseValue(card); + if (val > 0) return 2; + if (player.hp <= 2 && val == 0 && get.value(card) > 5) return 0; + return Math.random() > 0.5 ? 1 : 0; }, - ai2:function(target){ - var player=_status.event.player,cards=ui.selected.cards; - var val=0; - for(var card of cards){ - val+=target.getUseValue(card); + ai2: function (target) { + var player = _status.event.player, + cards = ui.selected.cards; + var val = 0; + for (var card of cards) { + val += target.getUseValue(card); } - if(val>0) return val*get.attitude(player,target)*2; - return get.value(card,target)*get.attitude(player,target); + if (val > 0) return val * get.attitude(player, target) * 2; + return get.value(card, target) * get.attitude(player, target); }, }); - 'step 7' - if(result.bool){ - var cards=result.cards,target=result.targets[0]; - player.give(cards,target); + "step 7"; + if (result.bool) { + var cards = result.cards, + target = result.targets[0]; + player.give(cards, target); } - } + }, }, //马超 - sbtieji:{ - audio:1, - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - filter:function(event,player){ - return player!=event.target&&event.card.name=='sha'&&event.target.isIn(); + sbtieji: { + audio: 1, + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + filter: function (event, player) { + return player != event.target && event.card.name == "sha" && event.target.isIn(); }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - target.addTempSkill('fengyin'); + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + target.addTempSkill("fengyin"); trigger.directHit.add(target); - player.chooseToDuiben(target).set('title','谋弈').set('namelist',[ - '出阵迎战','拱卫中军','直取敌营','扰阵疲敌' - ]).set('ai',button=>{ - var source=get.event().getParent().player,target=get.event().getParent().target; - if(!target.countCards('he')&&button.link[2]=='db_def2') return 10; - if(!target.countCards('he')&&get.attitude(target,source)<=0&&button.link[2]=='db_atk1') return 10; - return 1+Math.random(); - }); - 'step 1' - if(result.bool){ - if(result.player=='db_def1') player.gainPlayerCard(target,'he',true); + player + .chooseToDuiben(target) + .set("title", "谋弈") + .set("namelist", ["出阵迎战", "拱卫中军", "直取敌营", "扰阵疲敌"]) + .set("ai", (button) => { + var source = get.event().getParent().player, + target = get.event().getParent().target; + if (!target.countCards("he") && button.link[2] == "db_def2") return 10; + if ( + !target.countCards("he") && + get.attitude(target, source) <= 0 && + button.link[2] == "db_atk1" + ) + return 10; + return 1 + Math.random(); + }); + "step 1"; + if (result.bool) { + if (result.player == "db_def1") player.gainPlayerCard(target, "he", true); else player.draw(2); } }, - shaRelated:true, - ai:{ - ignoreSkill:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='directHit_ai'){ - return get.attitude(player,arg.target)<=0; + shaRelated: true, + ai: { + ignoreSkill: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "directHit_ai") { + return get.attitude(player, arg.target) <= 0; } - if(!arg||arg.isLink||!arg.card||arg.card.name!='sha') return false; - if(!arg.target||get.attitude(player,arg.target)>=0) return false; - if(!arg.skill||!lib.skill[arg.skill]||lib.skill[arg.skill].charlotte||get.is.locked(arg.skill)||!arg.target.getSkills(true,false).includes(arg.skill)) return false; + if (!arg || arg.isLink || !arg.card || arg.card.name != "sha") return false; + if (!arg.target || get.attitude(player, arg.target) >= 0) return false; + if ( + !arg.skill || + !lib.skill[arg.skill] || + lib.skill[arg.skill].charlotte || + get.is.locked(arg.skill) || + !arg.target.getSkills(true, false).includes(arg.skill) + ) + return false; }, - directHit_ai:true, + directHit_ai: true, + }, + subSkill: { + true1: { audio: true }, + true2: { audio: true }, + false: { audio: true }, }, - subSkill:{ - true1:{audio:true}, - true2:{audio:true}, - false:{audio:true}, - } }, //甘宁 - sbqixi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + sbqixi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - event.list=lib.suit.slice(); - event.suits=[]; - event.num=0; - var cards=player.getCards('h'),map={},max=-Infinity; - for(var card of cards){ - var suit=get.suit(card,player); - if(!map[suit]) map[suit]=0; + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + event.list = lib.suit.slice(); + event.suits = []; + event.num = 0; + var cards = player.getCards("h"), + map = {}, + max = -Infinity; + for (var card of cards) { + var suit = get.suit(card, player); + if (!map[suit]) map[suit] = 0; map[suit]++; - if(map[suit]>max) max=map[suit]; + if (map[suit] > max) max = map[suit]; } - for(var i in map){ - if(map[i]==max) event.suits.push(i); + for (var i in map) { + if (map[i] == max) event.suits.push(i); } - 'step 1' - target.chooseControl(event.list).set('prompt','奇袭:猜测'+get.translation(player)+'手牌中最多的花色').set('ai',()=>{ - var player=_status.event.getParent().player,controls=_status.event.controls; - if(player.countCards('h')<=3&&controls.includes('diamond')&&Math.random()<0.3) return 'diamond'; - return controls.randomGet(); - }); - 'step 2' - var control=result.control; - target.chat('我猜是'+get.translation(control)+'!'); - game.log(target,'猜测为','#y'+control); - if(!event.isMine()&&!event.isOnline()) game.delayx(); - 'step 3' - var control=result.control; - if(!event.suits.includes(control)){ - player.chat('猜错了!'); - game.log(target,'猜测','#y错误'); + "step 1"; + target + .chooseControl(event.list) + .set("prompt", "奇袭:猜测" + get.translation(player) + "手牌中最多的花色") + .set("ai", () => { + var player = _status.event.getParent().player, + controls = _status.event.controls; + if ( + player.countCards("h") <= 3 && + controls.includes("diamond") && + Math.random() < 0.3 + ) + return "diamond"; + return controls.randomGet(); + }); + "step 2"; + var control = result.control; + target.chat("我猜是" + get.translation(control) + "!"); + game.log(target, "猜测为", "#y" + control); + if (!event.isMine() && !event.isOnline()) game.delayx(); + "step 3"; + var control = result.control; + if (!event.suits.includes(control)) { + player.chat("猜错了!"); + game.log(target, "猜测", "#y错误"); event.num++; event.list.remove(control); - player.chooseBool('是否令其重新选择一个花色继续猜测?').set('ai',()=>1); - } - else { - player.chat(event.num==0?'这么准?':'猜对了!'); - game.log(target,'猜测','#g正确'); + player.chooseBool("是否令其重新选择一个花色继续猜测?").set("ai", () => 1); + } else { + player.chat(event.num == 0 ? "这么准?" : "猜对了!"); + game.log(target, "猜测", "#g正确"); player.showHandcards(); event.goto(4); } - 'step 4' - if(result.bool){ + "step 4"; + if (result.bool) { event.goto(1); } - 'step 5' - if(event.num>0&&target.countDiscardableCards(player,'hej')){ + "step 5"; + if (event.num > 0 && target.countDiscardableCards(player, "hej")) { player.line(target); - player.discardPlayerCard(target,event.num,true,'hej'); + player.discardPlayerCard(target, event.num, true, "hej"); } }, - ai:{ - order:10, - result:{ - player:1, - target:function(player,target){ - return get.effect(target,{name:'guohe'},player,target)*(5-get.attitude(player,target)/2); - } - } - } + ai: { + order: 10, + result: { + player: 1, + target: function (player, target) { + return ( + get.effect(target, { name: "guohe" }, player, target) * + (5 - get.attitude(player, target) / 2) + ); + }, + }, + }, }, - sbfenwei:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he')>0; + sbfenwei: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") > 0; }, - skillAnimation:true, - animationColor:'wood', - limited:true, - position:'he', - filterCard:true, - selectCard:[1,3], - filterTarget:true, - selectTarget:function(){ + skillAnimation: true, + animationColor: "wood", + limited: true, + position: "he", + filterCard: true, + selectCard: [1, 3], + filterTarget: true, + selectTarget: function () { return ui.selected.cards.length; }, - delay:false, - discard:false, - lose:false, - complexSelect:true, - filterOk:function(){ - return ui.selected.targets.length==ui.selected.cards.length; + delay: false, + discard: false, + lose: false, + complexSelect: true, + filterOk: function () { + return ui.selected.targets.length == ui.selected.cards.length; }, - multitarget:true, - multiline:true, - check:function(card){ - return 7-get.value(card); + multitarget: true, + multiline: true, + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' - player.awakenSkill('sbfenwei'); - for(var i=0; i{ - return get.rawAttitude(player,current)>0&¤t!=player&&get.attitude(player,current)<=0; - })&&game.countPlayer(current=>{ - return get.attitude(player,current)>0; - })<=2) return 0; + ai: { + order: 6.9, + result: { + target: function (player, target) { + if ( + game.hasPlayer((current) => { + return ( + get.rawAttitude(player, current) > 0 && + current != player && + get.attitude(player, current) <= 0 + ); + }) && + game.countPlayer((current) => { + return get.attitude(player, current) > 0; + }) <= 2 + ) + return 0; return 1; }, - } + }, }, - subSkill:{ - effect:{ - audio:'sbfenwei', - trigger:{ - global:'useCardToTarget', + subSkill: { + effect: { + audio: "sbfenwei", + trigger: { + global: "useCardToTarget", }, - charlotte:true, - forced:true, - filter:function(event,player){ - return event.target.getExpansions('sbfenwei_effect').length>0&&get.type2(event.card)=='trick'; + charlotte: true, + forced: true, + filter: function (event, player) { + return ( + event.target.getExpansions("sbfenwei_effect").length > 0 && + get.type2(event.card) == "trick" + ); }, - content:function(){ - 'step 0' - var choiceList=['令'+get.translation(trigger.target)+'获得其“威”','移去'+ get.translation(trigger.target) +'的“威”,取消'+get.translation(trigger.card)+'对其的目标']; - player.chooseControl().set('choiceList',choiceList).set('prompt','奋威:请选择一项').set('ai',()=>{ - var player=_status.event.player,evt=_status.event.getTrigger(); - if(get.effect(evt.target,evt.card,evt.player,player)<-10) return 1; - return 0; - }); - 'step 1' - var cards=trigger.target.getExpansions('sbfenwei_effect'); - if(result.index==0){ - trigger.target.gain(cards,'gain2','fromStorage'); - } - else { + content: function () { + "step 0"; + var choiceList = [ + "令" + get.translation(trigger.target) + "获得其“威”", + "移去" + + get.translation(trigger.target) + + "的“威”,取消" + + get.translation(trigger.card) + + "对其的目标", + ]; + player + .chooseControl() + .set("choiceList", choiceList) + .set("prompt", "奋威:请选择一项") + .set("ai", () => { + var player = _status.event.player, + evt = _status.event.getTrigger(); + if (get.effect(evt.target, evt.card, evt.player, player) < -10) return 1; + return 0; + }); + "step 1"; + var cards = trigger.target.getExpansions("sbfenwei_effect"); + if (result.index == 0) { + trigger.target.gain(cards, "gain2", "fromStorage"); + } else { trigger.target.loseToDiscardpile(cards); trigger.targets.remove(trigger.target); trigger.getParent().triggeredTargets2.remove(trigger.target); trigger.untrigger(); } }, - marktext:'威', - intro:{ - name:'威', - markcount:'expansion', - content:'expansion', + marktext: "威", + intro: { + name: "威", + markcount: "expansion", + content: "expansion", }, - } - } + }, + }, }, //甄宓 - sbluoshen:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('sbluoshen')).set('ai',target=>{ - var eff=0; - var num=Math.ceil(game.countPlayer()/2),players=game.filterPlayer(current=>current!=player).sortBySeat(target).slice(0,num); - for(var targetx of players){ - eff+=get.attitude(player,targetx)*Math.sqrt(targetx.countCards('h')); + sbluoshen: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("sbluoshen")).set("ai", (target) => { + var eff = 0; + var num = Math.ceil(game.countPlayer() / 2), + players = game + .filterPlayer((current) => current != player) + .sortBySeat(target) + .slice(0, num); + for (var targetx of players) { + eff += get.attitude(player, targetx) * Math.sqrt(targetx.countCards("h")); } - return 1-eff; + return 1 - eff; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbluoshen',target); - player.addTempSkill('sbluoshen_add'); - event.targets=game.filterPlayer(current=>current!=player).sortBySeat(target).slice(0,Math.ceil(game.countPlayer()/2)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbluoshen", target); + player.addTempSkill("sbluoshen_add"); + event.targets = game + .filterPlayer((current) => current != player) + .sortBySeat(target) + .slice(0, Math.ceil(game.countPlayer() / 2)); } else event.finish(); - 'step 2' - var target=event.targets.shift(); - event.target=target; + "step 2"; + var target = event.targets.shift(); + event.target = target; player.line(target); - if(!target.countCards('h')) event._result={bool:false}; - else target.chooseCard('展示一张手牌',true).set('ai',card=>{ - var val=_status.event.goon?15:5; - if(get.color(card)=='black') return val-get.value(card); - return 7-get.value(card); - }).set('goon',get.attitude(target,player)>0); - 'step 3' - if(result.bool){ - var card=result.cards[0]; - target.showCards(card,get.translation(target)+'【洛神】展示'); - if(get.color(card)=='black'){ - player.gain(card,target,'give','bySelf').gaintag.add('sbluoshen'); - } - else if(get.color(card)=='red'){ + if (!target.countCards("h")) event._result = { bool: false }; + else + target + .chooseCard("展示一张手牌", true) + .set("ai", (card) => { + var val = _status.event.goon ? 15 : 5; + if (get.color(card) == "black") return val - get.value(card); + return 7 - get.value(card); + }) + .set("goon", get.attitude(target, player) > 0); + "step 3"; + if (result.bool) { + var card = result.cards[0]; + target.showCards(card, get.translation(target) + "【洛神】展示"); + if (get.color(card) == "black") { + player.gain(card, target, "give", "bySelf").gaintag.add("sbluoshen"); + } else if (get.color(card) == "red") { target.discard(card); } } - 'step 4' - if(targets.length) event.goto(2); + "step 4"; + if (targets.length) event.goto(2); }, - subSkill:{ - add:{ - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('sbluoshen')){ + subSkill: { + add: { + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("sbluoshen")) { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('sbluoshen')){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("sbluoshen")) { return false; } }, }, - onremove:function(player){ - player.removeGaintag('sbluoshen'); + onremove: function (player) { + player.removeGaintag("sbluoshen"); }, - } - } + }, + }, }, //曹操 - sbjianxiong:{ - audio:2, - trigger:{player:'damageEnd'}, - group:'sbjianxiong_mark', - filter:function(event,player){ - return get.itemtype(event.cards)=='cards'&&event.cards.some(i=>get.position(i,true)=='o')||1-player.countMark('sbjianxiong')>0; + sbjianxiong: { + audio: 2, + trigger: { player: "damageEnd" }, + group: "sbjianxiong_mark", + filter: function (event, player) { + return ( + (get.itemtype(event.cards) == "cards" && + event.cards.some((i) => get.position(i, true) == "o")) || + 1 - player.countMark("sbjianxiong") > 0 + ); }, - prompt2:function(event,player){ - var gain=get.itemtype(event.cards)=='cards'&&event.cards.some(i=>get.position(i,true)=='o'),draw=1-player.countMark('sbjianxiong'); - var str=''; - if(gain) str+='获得'+get.translation(event.cards); - if(gain&&draw>0) str+='并'; - if(draw>0) str+='摸'+get.cnNumber(1-player.countMark('sbjianxiong'))+'张牌'; - if(player.countMark('sbjianxiong')) str+=',然后可以弃1枚“治世”'; + prompt2: function (event, player) { + var gain = + get.itemtype(event.cards) == "cards" && + event.cards.some((i) => get.position(i, true) == "o"), + draw = 1 - player.countMark("sbjianxiong"); + var str = ""; + if (gain) str += "获得" + get.translation(event.cards); + if (gain && draw > 0) str += "并"; + if (draw > 0) str += "摸" + get.cnNumber(1 - player.countMark("sbjianxiong")) + "张牌"; + if (player.countMark("sbjianxiong")) str += ",然后可以弃1枚“治世”"; return str; }, - content:function(){ - 'step 0' - if(get.itemtype(trigger.cards)=='cards'&&trigger.cards.some(i=>get.position(i,true)=='o')){ - player.gain(trigger.cards,'gain2'); + content: function () { + "step 0"; + if ( + get.itemtype(trigger.cards) == "cards" && + trigger.cards.some((i) => get.position(i, true) == "o") + ) { + player.gain(trigger.cards, "gain2"); } - var num=player.countMark('sbjianxiong'); - if(1-num>0){ - player.draw(1-num,'nodelay'); + var num = player.countMark("sbjianxiong"); + if (1 - num > 0) { + player.draw(1 - num, "nodelay"); } - if(!num) event.finish(); - 'step 1' - player.chooseBool('是否弃1枚“治世”?').set('ai',()=>{ - var player=_status.event.player,current=_status.currentPhase; - if(get.distance(current,player,'absolute')>3&&player.hp<=2) return true; + if (!num) event.finish(); + "step 1"; + player.chooseBool("是否弃1枚“治世”?").set("ai", () => { + var player = _status.event.player, + current = _status.currentPhase; + if (get.distance(current, player, "absolute") > 3 && player.hp <= 2) return true; return false; }); - 'step 2' - if(result.bool){ - player.removeMark('sbjianxiong',1); + "step 2"; + if (result.bool) { + player.removeMark("sbjianxiong", 1); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target){ - var cards=card.cards,evt=_status.event; - if(evt.player==target&&card.name=='damage'&&evt.getParent().type=='card') cards=evt.getParent().cards.filterInD(); - if(target.hp<=1) return; - if(get.itemtype(cards)!='cards') return; - for(var i of cards){ - if(get.name(i,target)=='tao') return [1,5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage") && player != target) { + var cards = card.cards, + evt = _status.event; + if ( + evt.player == target && + card.name == "damage" && + evt.getParent().type == "card" + ) + cards = evt.getParent().cards.filterInD(); + if (target.hp <= 1) return; + if (get.itemtype(cards) != "cards") return; + for (var i of cards) { + if (get.name(i, target) == "tao") return [1, 5]; } - if(get.value(cards,target)>=(7+target.getDamagedHp())) return [1,3]; - return [1,0.55+0.05*Math.max(0,1-target.countMark('sbjianxiong'))]; + if (get.value(cards, target) >= 7 + target.getDamagedHp()) return [1, 3]; + return [1, 0.55 + 0.05 * Math.max(0, 1 - target.countMark("sbjianxiong"))]; } - } - } - }, - marktext:'治', - intro:{ - name:'治世', - name2:'治世', - content:'mark', - }, - subSkill:{ - mark:{ - audio:'sbjianxiong', - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); }, - content:function(){ - 'step 0' - var map={}; - var list=[]; - for(var i=1; i<=2; i++){ - var cn=get.cnNumber(i,true); - map[cn]=i; + }, + }, + marktext: "治", + intro: { + name: "治世", + name2: "治世", + content: "mark", + }, + subSkill: { + mark: { + audio: "sbjianxiong", + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; + }, + content: function () { + "step 0"; + var map = {}; + var list = []; + for (var i = 1; i <= 2; i++) { + var cn = get.cnNumber(i, true); + map[cn] = i; list.push(cn); } - event.map=map; - list.push('cancel2'); - player.chooseControl(list,function(){ - return get.cnNumber(2,true); - }).set('prompt','奸雄:获得任意枚“治世”标记'); - 'step 1' - if(result.control!='cancel2') player.addMark('sbjianxiong',event.map[result.control]); - } - } + event.map = map; + list.push("cancel2"); + player + .chooseControl(list, function () { + return get.cnNumber(2, true); + }) + .set("prompt", "奸雄:获得任意枚“治世”标记"); + "step 1"; + if (result.control != "cancel2") + player.addMark("sbjianxiong", event.map[result.control]); + }, + }, }, }, - sbqingzheng:{ - audio:2, - audioname:['mb_caomao'], - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + sbqingzheng: { + audio: 2, + audioname: ["mb_caomao"], + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - direct:true, - content:function(){ - 'step 0' - var num=3-player.countMark('sbjianxiong'); - var prompt='###'+get.prompt('sbqingzheng')+'###弃置'+get.cnNumber(num)+'种花色的所有牌'; - var next=player.chooseButton([prompt,[lib.suit.map(i=>['','','lukai_'+i]),'vcard']],num); - next.set('filterButton',button=>{ - var player=_status.event.player; - var cards=player.getCards('h',{suit:button.link[2].slice(6)}); - return cards.length>0&&cards.filter(card=>lib.filter.cardDiscardable(card,player,'sbqingzheng')).length==cards.length; + direct: true, + content: function () { + "step 0"; + var num = 3 - player.countMark("sbjianxiong"); + var prompt = + "###" + get.prompt("sbqingzheng") + "###弃置" + get.cnNumber(num) + "种花色的所有牌"; + var next = player.chooseButton( + [prompt, [lib.suit.map((i) => ["", "", "lukai_" + i]), "vcard"]], + num + ); + next.set("filterButton", (button) => { + var player = _status.event.player; + var cards = player.getCards("h", { suit: button.link[2].slice(6) }); + return ( + cards.length > 0 && + cards.filter((card) => lib.filter.cardDiscardable(card, player, "sbqingzheng")) + .length == cards.length + ); }); - next.set('ai',button=>{ - var player=_status.event.player; - return player.countMark('sbjianxiong')*15-player.getCards('h',{suit:button.link[2].slice(6)}).map(i=>get.value(i)).reduce((p,c)=>p+c,0); + next.set("ai", (button) => { + var player = _status.event.player; + return ( + player.countMark("sbjianxiong") * 15 - + player + .getCards("h", { suit: button.link[2].slice(6) }) + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0) + ); }); - next.set('custom',{ - replace:{ - button:function(button){ - if(!_status.event.isMine()) return; - if(button.classList.contains('selectable')==false) return; - var cards=_status.event.player.getCards('h',{suit:button.link[2].slice(6)}); - if(cards.length){ - var chosen=cards.filter(i=>ui.selected.cards.includes(i)).length==cards.length; - if(chosen){ + next.set("custom", { + replace: { + button: function (button) { + if (!_status.event.isMine()) return; + if (button.classList.contains("selectable") == false) return; + var cards = _status.event.player.getCards("h", { + suit: button.link[2].slice(6), + }); + if (cards.length) { + var chosen = + cards.filter((i) => ui.selected.cards.includes(i)).length == + cards.length; + if (chosen) { ui.selected.cards.removeArray(cards); - cards.forEach(card=>{ - card.classList.remove('selected'); + cards.forEach((card) => { + card.classList.remove("selected"); card.updateTransform(false); }); - }else{ + } else { ui.selected.cards.addArray(cards); - cards.forEach(card=>{ - card.classList.add('selected'); + cards.forEach((card) => { + card.classList.add("selected"); card.updateTransform(true); }); } } - if(button.classList.contains('selected')){ + if (button.classList.contains("selected")) { ui.selected.buttons.remove(button); - button.classList.remove('selected'); - if(_status.multitarget||_status.event.complexSelect){ + button.classList.remove("selected"); + if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); } - } - else{ - button.classList.add('selected'); + } else { + button.classList.add("selected"); ui.selected.buttons.add(button); } - var custom=_status.event.custom; - if(custom&&custom.add&&custom.add.button){ + var custom = _status.event.custom; + if (custom && custom.add && custom.add.button) { custom.add.button(); } game.check(); - } + }, }, - add:next.custom.add + add: next.custom.add, }); - 'step 1' - if(result.bool){ - var cards=result.cards; - if(!cards.length){ - var suits=result.links.map(i=>i[2].slice(6)); - cards=player.getCards('h',card=>suits.includes(get.suit(card,player))); + "step 1"; + if (result.bool) { + var cards = result.cards; + if (!cards.length) { + var suits = result.links.map((i) => i[2].slice(6)); + cards = player.getCards("h", (card) => suits.includes(get.suit(card, player))); } - event.cards=cards; - if(!cards.length) event.finish(); - else player.chooseTarget('清正:观看一名其他角色的手牌并弃置其中一种花色的所有牌',(card,player,target)=>{ - return target!=player&&target.countCards('h'); - }).set('ai',target=>{ - var player=_status.event.player,att=get.attitude(player,target); - if(att>=0) return 0; - return 1-att/2+Math.sqrt(target.countCards('h')); - }); + event.cards = cards; + if (!cards.length) event.finish(); + else + player + .chooseTarget( + "清正:观看一名其他角色的手牌并弃置其中一种花色的所有牌", + (card, player, target) => { + return target != player && target.countCards("h"); + } + ) + .set("ai", (target) => { + var player = _status.event.player, + att = get.attitude(player, target); + if (att >= 0) return 0; + return 1 - att / 2 + Math.sqrt(target.countCards("h")); + }); } else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('sbqingzheng',target); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("sbqingzheng", target); player.discard(cards); - var list=[]; - var dialog=['清正:弃置'+get.translation(target)+'一种花色的所有牌']; - for(var suit of lib.suit.concat('none')){ - if(target.countCards('h',{suit:suit})){ - dialog.push('
              '+get.translation(suit+'2')+'牌
              '); - dialog.push(target.getCards('h',{suit:suit})); + var list = []; + var dialog = ["清正:弃置" + get.translation(target) + "一种花色的所有牌"]; + for (var suit of lib.suit.concat("none")) { + if (target.countCards("h", { suit: suit })) { + dialog.push( + '
              ' + get.translation(suit + "2") + "牌
              " + ); + dialog.push(target.getCards("h", { suit: suit })); list.push(suit); } } - if(list.length){ - player.chooseControl(list).set('dialog',dialog).set('ai',()=>{ - return _status.event.control; - }).set('control',(()=>{ - var getv=(cards)=>cards.map(i=>get.value(i)).reduce((p,c)=>p+c,0); - return list.sort((a,b)=>{ - return getv(target.getCards('h',{suit:b}))-getv(target.getCards('h',{suit:a})); - })[0]; - })()); + if (list.length) { + player + .chooseControl(list) + .set("dialog", dialog) + .set("ai", () => { + return _status.event.control; + }) + .set( + "control", + (() => { + var getv = (cards) => + cards.map((i) => get.value(i)).reduce((p, c) => p + c, 0); + return list.sort((a, b) => { + return ( + getv(target.getCards("h", { suit: b })) - + getv(target.getCards("h", { suit: a })) + ); + })[0]; + })() + ); } } else event.finish(); - 'step 3' - var cards2=target.getCards('h',{suit:result.control}); - event.cards2=cards2; - target.discard(cards2,'notBySelf').set('discarder',player); - 'step 4' - if(event.cards2.lengthMath.random()<0.5?0:1); + "step 3"; + var cards2 = target.getCards("h", { suit: result.control }); + event.cards2 = cards2; + target.discard(cards2, "notBySelf").set("discarder", player); + "step 4"; + if (event.cards2.length < cards.length) target.damage(); + "step 5"; + if (player.countMark("sbjianxiong") < 2 && player.hasSkill("sbjianxiong")) { + player + .chooseBool("是否获得1枚“治世”?") + .set("ai", () => (Math.random() < 0.5 ? 0 : 1)); } else event.finish(); - 'step 6' - if(result.bool){ - player.addMark('sbjianxiong',1); + "step 6"; + if (result.bool) { + player.addMark("sbjianxiong", 1); } }, - ai:{combo:'sbjianxiong'} + ai: { combo: "sbjianxiong" }, }, - sbhujia:{ - audio:2, - trigger:{player:'damageBegin4'}, - zhuSkill:true, - direct:true, - filter:function(event,player){ - return !player.hasSkill('sbhujia_used')&&game.hasPlayer(current=>{ - return current!=player&¤t.group=='wei'&&player.hasZhuSkill('sbhujia',current); - }); + sbhujia: { + audio: 2, + trigger: { player: "damageBegin4" }, + zhuSkill: true, + direct: true, + filter: function (event, player) { + return ( + !player.hasSkill("sbhujia_used") && + game.hasPlayer((current) => { + return ( + current != player && + current.group == "wei" && + player.hasZhuSkill("sbhujia", current) + ); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('sbhujia'),'将'+get.translation(trigger.source)+'即将对你造成的'+trigger.num+'点伤害转移给一名其他魏势力角色',(card,player,target)=>{ - return target!=player&&target.group=='wei'&&player.hasZhuSkill('sbhujia',target); - }).set('ai',target=>{ - var player=_status.event.player,evt=_status.event.getTrigger(); - return get.damageEffect(target,evt.source,player,evt.nature)-_status.event.eff; - }).set('eff',get.damageEffect(player,trigger.source,player,trigger.nature)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbhujia',target); - player.addTempSkill('sbhujia_used','roundStart'); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("sbhujia"), + "将" + + get.translation(trigger.source) + + "即将对你造成的" + + trigger.num + + "点伤害转移给一名其他魏势力角色", + (card, player, target) => { + return ( + target != player && + target.group == "wei" && + player.hasZhuSkill("sbhujia", target) + ); + } + ) + .set("ai", (target) => { + var player = _status.event.player, + evt = _status.event.getTrigger(); + return ( + get.damageEffect(target, evt.source, player, evt.nature) - _status.event.eff + ); + }) + .set("eff", get.damageEffect(player, trigger.source, player, trigger.nature)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbhujia", target); + player.addTempSkill("sbhujia_used", "roundStart"); trigger.cancel(); - if(trigger.source) target.damage(trigger.source,trigger.nature,trigger.num).set('card',trigger.card).set('cards',trigger.cards); - else target.damage('nosource',trigger.nature,trigger.num).set('card',trigger.card).set('cards',trigger.cards); + if (trigger.source) + target + .damage(trigger.source, trigger.nature, trigger.num) + .set("card", trigger.card) + .set("cards", trigger.cards); + else + target + .damage("nosource", trigger.nature, trigger.num) + .set("card", trigger.card) + .set("cards", trigger.cards); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&!target.hasSkill('sbhujia_used')&&game.hasPlayer(current=>{ - return current!=target&¤t.group=='wei'&&target.hasZhuSkill('sbhujia',current); - })) return 0.8; - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if ( + get.tag(card, "damage") && + !target.hasSkill("sbhujia_used") && + game.hasPlayer((current) => { + return ( + current != target && + current.group == "wei" && + target.hasZhuSkill("sbhujia", current) + ); + }) + ) + return 0.8; + }, + }, + threaten: function (player, target) { + if (target.countCards("h") == 0) return 2; }, - threaten:function(player,target){ - if(target.countCards('h')==0) return 2; - } }, - subSkill:{ - used:{charlotte:true}, + subSkill: { + used: { charlotte: true }, }, }, //张角 - sbleiji:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countMark('sbguidao')>=4; + sbleiji: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countMark("sbguidao") >= 4; }, - filterTarget:lib.filter.notMe, - content:function(){ - player.removeMark('sbguidao',4); - target.damage('thunder'); + filterTarget: lib.filter.notMe, + content: function () { + player.removeMark("sbguidao", 4); + target.damage("thunder"); + }, + ai: { + combo: "sbguidao", + order: 9, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "thunder"); + }, + }, }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'thunder'); - } - } - } }, - sbguidao:{ - audio:2, - trigger:{ - global:['phaseBefore','damageEnd'], - player:'enterGame', + sbguidao: { + audio: 2, + trigger: { + global: ["phaseBefore", "damageEnd"], + player: "enterGame", }, - forced:true, - locked:false, - group:'sbguidao_defend', - filter:function(event,player){ - if(player.countMark('sbguidao')>=8) return false; - if(event.name=='damage') return event.hasNature()&&!player.hasSkill('sbguidao_forbid'); - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + group: "sbguidao_defend", + filter: function (event, player) { + if (player.countMark("sbguidao") >= 8) return false; + if (event.name == "damage") + return event.hasNature() && !player.hasSkill("sbguidao_forbid"); + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - var num=2; - if(trigger.name!='damage') num+=2; - num=Math.min(8-player.countMark('sbguidao'),num); - player.addMark('sbguidao',num); + content: function () { + var num = 2; + if (trigger.name != "damage") num += 2; + num = Math.min(8 - player.countMark("sbguidao"), num); + player.addMark("sbguidao", num); }, - marktext:'兵', - intro:{ - name:'道兵', - name2:'道兵', - content:'共有$枚“道兵”', + marktext: "兵", + intro: { + name: "道兵", + name2: "道兵", + content: "共有$枚“道兵”", }, - subSkill:{ - defend:{ - audio:'sbguidao', - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return player.countMark('sbguidao')>=2; + subSkill: { + defend: { + audio: "sbguidao", + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return player.countMark("sbguidao") >= 2; }, - prompt2:'弃2枚“道兵”,防止伤害', - check:function(event,player){ - return event.num>=2||player.hp<=event.num; + prompt2: "弃2枚“道兵”,防止伤害", + check: function (event, player) { + return event.num >= 2 || player.hp <= event.num; }, - content:function(){ + content: function () { trigger.cancel(); - player.removeMark('sbguidao',2); - if(player!=_status.currentPhase){ - player.addTempSkill('sbguidao_forbid',{player:'phaseBegin'}); + player.removeMark("sbguidao", 2); + if (player != _status.currentPhase) { + player.addTempSkill("sbguidao_forbid", { player: "phaseBegin" }); } }, }, - forbid:{charlotte:true}, - } + forbid: { charlotte: true }, + }, }, - sbhuangtian:{ - audio:2, - trigger:{ - player:'phaseBegin', + sbhuangtian: { + audio: 2, + trigger: { + player: "phaseBegin", }, - forced:true, - zhuSkill:true, - group:'sbhuangtian_mark', - filter:function(event,player){ - if(player.phaseNumber>1||game.phaseNumber>1) return false; - if(!player.hasZhuSkill('sbhuangtian')) return false; - return !game.hasPlayer(function(current){ - return current.countCards('hej','taipingyaoshu'); - })&&!Array.from(ui.cardPile.childNodes).concat(Array.from(ui.discardPile.childNodes)).concat(Array.from(ui.ordering.childNodes)).map(i=>i.name).includes('taipingyaoshu'); + forced: true, + zhuSkill: true, + group: "sbhuangtian_mark", + filter: function (event, player) { + if (player.phaseNumber > 1 || game.phaseNumber > 1) return false; + if (!player.hasZhuSkill("sbhuangtian")) return false; + return ( + !game.hasPlayer(function (current) { + return current.countCards("hej", "taipingyaoshu"); + }) && + !Array.from(ui.cardPile.childNodes) + .concat(Array.from(ui.discardPile.childNodes)) + .concat(Array.from(ui.ordering.childNodes)) + .map((i) => i.name) + .includes("taipingyaoshu") + ); }, - content:function(){ - 'step 0' - if(!lib.inpile.contains('taipingyaoshu')){ - lib.inpile.push('taipingyaoshu'); + content: function () { + "step 0"; + if (!lib.inpile.contains("taipingyaoshu")) { + lib.inpile.push("taipingyaoshu"); } - event.card=game.createCard2('taipingyaoshu','heart',3); - 'step 1' - if(card) player.equip(card); + event.card = game.createCard2("taipingyaoshu", "heart", 3); + "step 1"; + if (card) player.equip(card); }, - subSkill:{ - mark:{ - audio:'sbhuangtiang', - trigger:{global:'damageSource'}, - forced:true, - zhuSkill:true, - filter:function(event,player){ - if(!player.hasZhuSkill('sbhuangtian')||!player.hasSkill('sbguidao',null,false,false)) return false; - if(!event.source||player==event.source||event.source.group!='qun') return false; - if(player.hasSkill('sbguidao')&&player.countMark('sbguidao')>=8) return false; - if(player.countMark('sbhuangtian_count')>=4) return false; + subSkill: { + mark: { + audio: "sbhuangtiang", + trigger: { global: "damageSource" }, + forced: true, + zhuSkill: true, + filter: function (event, player) { + if ( + !player.hasZhuSkill("sbhuangtian") || + !player.hasSkill("sbguidao", null, false, false) + ) + return false; + if (!event.source || player == event.source || event.source.group != "qun") + return false; + if (player.hasSkill("sbguidao") && player.countMark("sbguidao") >= 8) + return false; + if (player.countMark("sbhuangtian_count") >= 4) return false; return true; }, - content:function(){ - var num=Math.min(8-player.countMark('sbhuangtian_count'),2); - player.addMark('sbguidao',num); - player.addTempSkill('sbhuangtian_count','roundStart'); - player.addMark('sbhuangtian_count',num,false); - } + content: function () { + var num = Math.min(8 - player.countMark("sbhuangtian_count"), 2); + player.addMark("sbguidao", num); + player.addTempSkill("sbhuangtian_count", "roundStart"); + player.addMark("sbhuangtian_count", num, false); + }, }, - count:{onremove:true} - } + count: { onremove: true }, + }, }, //夏侯氏 - sbqiaoshi:{ - audio:2, - trigger:{player:'damageEnd'}, - usable:1, - direct:true, - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.isIn(); + sbqiaoshi: { + audio: 2, + trigger: { player: "damageEnd" }, + usable: 1, + direct: true, + filter: function (event, player) { + return event.source && event.source != player && event.source.isIn(); }, - content:function(){ - 'step 0' - trigger.source.chooseBool('樵拾:是否令'+get.translation(player)+'回复'+trigger.num+'点体力,然后你摸两张牌?').set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.recoverEffect(player,trigger.source,trigger.source)+2*get.effect(trigger.source,{name:'draw'},trigger.source)>5); - 'step 1' - if(result.bool){ - player.logSkill('sbqiaoshi'); - trigger.source.line(player,'green'); + content: function () { + "step 0"; + trigger.source + .chooseBool( + "樵拾:是否令" + + get.translation(player) + + "回复" + + trigger.num + + "点体力,然后你摸两张牌?" + ) + .set("ai", () => { + return _status.event.bool; + }) + .set( + "bool", + get.recoverEffect(player, trigger.source, trigger.source) + + 2 * get.effect(trigger.source, { name: "draw" }, trigger.source) > + 5 + ); + "step 1"; + if (result.bool) { + player.logSkill("sbqiaoshi"); + trigger.source.line(player, "green"); player.recover(trigger.num); trigger.source.draw(2); - } - else player.storage.counttrigger.sbqiaoshi--; + } else player.storage.counttrigger.sbqiaoshi--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(get.attitude(target,player)<=0||target==player) return; - if(target.storage.counttrigger&&target.storage.counttrigger.sbqiaoshi) return; - if(target.hp<=1&&!player.canSave(target)) return; - return [0,0.5,0,0.5]; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (get.attitude(target, player) <= 0 || target == player) return; + if (target.storage.counttrigger && target.storage.counttrigger.sbqiaoshi) + return; + if (target.hp <= 1 && !player.canSave(target)) return; + return [0, 0.5, 0, 0.5]; } }, }, - } + }, }, - sbyanyu:{ - enable:'phaseUse', - usable:2, - filterCard:{name:'sha'}, - selectCard:1, - group:'sbyanyu_draw', - check:()=>1, - content:function(){ + sbyanyu: { + enable: "phaseUse", + usable: 2, + filterCard: { name: "sha" }, + selectCard: 1, + group: "sbyanyu_draw", + check: () => 1, + content: function () { player.draw(); }, - subSkill:{ - draw:{ - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getHistory('useSkill',evt=>{ - if(evt.skill!='sbyanyu') return false; - var evtx=evt.event.getParent('phaseUse'); - if(!evtx||evtx!=_status.event.getParent('phaseUse')) return; + subSkill: { + draw: { + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return player.getHistory("useSkill", (evt) => { + if (evt.skill != "sbyanyu") return false; + var evtx = evt.event.getParent("phaseUse"); + if (!evtx || evtx != _status.event.getParent("phaseUse")) return; return true; }).length; }, - direct:true, - content:function(){ - 'step 0' - event.num=3*player.getHistory('useSkill',evt=>{ - if(evt.skill!='sbyanyu') return false; - var evtx=evt.event.getParent('phaseUse'); - if(!evtx||evtx!=_status.event.getParent('phaseUse')) return; - return true; - }).length; - player.chooseTarget(get.prompt('sbyanyu'),'令一名其他角色摸'+get.cnNumber(event.num)+'张牌',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'draw'},player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbyanyu_draw',target); + direct: true, + content: function () { + "step 0"; + event.num = + 3 * + player.getHistory("useSkill", (evt) => { + if (evt.skill != "sbyanyu") return false; + var evtx = evt.event.getParent("phaseUse"); + if (!evtx || evtx != _status.event.getParent("phaseUse")) return; + return true; + }).length; + player + .chooseTarget( + get.prompt("sbyanyu"), + "令一名其他角色摸" + get.cnNumber(event.num) + "张牌", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "draw" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbyanyu_draw", target); target.draw(num); } - } - } + }, + }, }, - ai:{ - order:function(obj,player){ - if(game.hasPlayer(current=>current!=player&&get.attitude(player,current)>0)&&player.getHistory('useSkill',evt=>{ - if(evt.skill!='sbyanyu') return false; - var evtx=evt.event.getParent('phaseUse'); - if(!evtx||evtx!=_status.event.getParent('phaseUse')) return; - return true; - }).length<2) return 9; + ai: { + order: function (obj, player) { + if ( + game.hasPlayer( + (current) => current != player && get.attitude(player, current) > 0 + ) && + player.getHistory("useSkill", (evt) => { + if (evt.skill != "sbyanyu") return false; + var evtx = evt.event.getParent("phaseUse"); + if (!evtx || evtx != _status.event.getParent("phaseUse")) return; + return true; + }).length < 2 + ) + return 9; return 2; }, - result:{ - player:1 + result: { + player: 1, }, - } + }, }, //曹仁 - sbjushou:{ - audio:3, - enable:'phaseUse', - usable:1, - filter:function(event,player){ + sbjushou: { + audio: 3, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { return !player.isTurnedOver(); }, - filterCard:true, - selectCard:[1,2], - check:function(card){ - if(ui.selected.cards.length+_status.event.player.hujia>=5) return 0; - return 6.5-get.value(card); + filterCard: true, + selectCard: [1, 2], + check: function (card) { + if (ui.selected.cards.length + _status.event.player.hujia >= 5) return 0; + return 6.5 - get.value(card); }, - position:'he', - group:['sbjushou_damage','sbjushou_draw'], - content:function(){ + position: "he", + group: ["sbjushou_damage", "sbjushou_draw"], + content: function () { player.turnOver(); - player.changeHujia(cards.length,null,true); + player.changeHujia(cards.length, null, true); }, - ai:{ - order:5, - result:{ - player:1, - } + ai: { + order: 5, + result: { + player: 1, + }, }, - subSkill:{ - damage:{ - audio:'sbjushou', - trigger:{ - player:'damageEnd', + subSkill: { + damage: { + audio: "sbjushou", + trigger: { + player: "damageEnd", }, - filter:function(event,player){ + filter: function (event, player) { return player.isTurnedOver(); }, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('翻面','获得1点护甲','cancel2').set('ai',()=>{ - if(_status.event.player.hujia>=3) return 0; - return 1; - }).set('prompt',get.prompt('sbjushou')).set('prompt2','选择一项'); - 'step 1' - if(result.control=='cancel2'){ + direct: true, + content: function () { + "step 0"; + player + .chooseControl("翻面", "获得1点护甲", "cancel2") + .set("ai", () => { + if (_status.event.player.hujia >= 3) return 0; + return 1; + }) + .set("prompt", get.prompt("sbjushou")) + .set("prompt2", "选择一项"); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - player.logSkill('sbjushou'); - if(result.control=='翻面'){ + player.logSkill("sbjushou"); + if (result.control == "翻面") { player.turnOver(); - } - else { - player.changeHujia(1,null,true); + } else { + player.changeHujia(1, null, true); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(!target.isTurnedOver()) return; - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if((card.name=='sha'&&!player.hasSkill('jiu'))||target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - })) return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target) { + if (!target.isTurnedOver()) return; + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if ( + (card.name == "sha" && !player.hasSkill("jiu")) || + target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + return "zerotarget"; } }, }, }, }, - draw:{ - audio:'sbjushou', - trigger:{player:'turnOverAfter'}, - forced:true, - locked:false, - filter:function(event,player){ - return !player.isTurnedOver()&&player.hujia>0; + draw: { + audio: "sbjushou", + trigger: { player: "turnOverAfter" }, + forced: true, + locked: false, + filter: function (event, player) { + return !player.isTurnedOver() && player.hujia > 0; }, - content:function(){ + content: function () { player.draw(player.hujia); }, - } - } + }, + }, }, - sbjiewei:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hujia>0; + sbjiewei: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hujia > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); }, - content:function(){ + content: function () { player.changeHujia(-1); - player.gainPlayerCard(target,'visible',true,'h').set('ai',function(button){ - return get.value(button.link,_status.event.target); + player.gainPlayerCard(target, "visible", true, "h").set("ai", function (button) { + return get.value(button.link, _status.event.target); }); }, - ai:{ - order:8, - result:{ - target:-1, - } - } + ai: { + order: 8, + result: { + target: -1, + }, + }, }, //周瑜 - sbyingzi:{ - audio:2, - audioname:['sb_sunce'], - trigger:{player:'phaseDrawBegin2'}, - forced:true, - getNum:function(player){ - return (player.countCards('h')>=2)+(player.hp>=2)+(player.countCards('e')>=1); + sbyingzi: { + audio: 2, + audioname: ["sb_sunce"], + trigger: { player: "phaseDrawBegin2" }, + forced: true, + getNum: function (player) { + return (player.countCards("h") >= 2) + (player.hp >= 2) + (player.countCards("e") >= 1); }, - filter:function(event,player){ - return !event.numFixed&&lib.skill.sbyingzi.getNum(player)>0; + filter: function (event, player) { + return !event.numFixed && lib.skill.sbyingzi.getNum(player) > 0; }, - content:function(){ - var num=lib.skill.sbyingzi.getNum(player); - trigger.num+=num; - player.addTempSkill('sbyingzi_limit'); - player.addMark('sbyingzi_limit',num,false); + content: function () { + var num = lib.skill.sbyingzi.getNum(player); + trigger.num += num; + player.addTempSkill("sbyingzi_limit"); + player.addMark("sbyingzi_limit", num, false); }, - ai:{ - threaten:2 + ai: { + threaten: 2, }, - subSkill:{ - limit:{ - charlotte:true, - forced:true, - onremove:true, - marktext:'英', - intro:{ - content:'本回合手牌上限+#', + subSkill: { + limit: { + charlotte: true, + forced: true, + onremove: true, + marktext: "英", + intro: { + content: "本回合手牌上限+#", }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('sbyingzi_limit'); - } + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("sbyingzi_limit"); + }, }, - } - } - }, - sbfanjian:{ - audio:2, - enable:'phaseUse', - usable:5, - filter:function(event,player){ - return !player.hasSkill('sbfanjian_ban'); - }, - chooseButton:{ - dialog:function(){ - return ui.create.dialog('###反间###'+get.translation('sbfanjian_info')); }, - chooseControl:function(event,player){ - var suits=lib.suit.slice(); - suits.push('cancel2'); + }, + }, + sbfanjian: { + audio: 2, + enable: "phaseUse", + usable: 5, + filter: function (event, player) { + return !player.hasSkill("sbfanjian_ban"); + }, + chooseButton: { + dialog: function () { + return ui.create.dialog("###反间###" + get.translation("sbfanjian_info")); + }, + chooseControl: function (event, player) { + var suits = lib.suit.slice(); + suits.push("cancel2"); return suits; }, - check:function(event,player){ - var suits=lib.suit.slice(); - suits=suits.filter(suit=>!player.getStorage('sbfanjian_guessed').includes(suit)); + check: function (event, player) { + var suits = lib.suit.slice(); + suits = suits.filter( + (suit) => !player.getStorage("sbfanjian_guessed").includes(suit) + ); return suits.randomGet(); }, - backup:function(result,player){ + backup: function (result, player) { return { - audio:'sbfanjian', - filterCard:function(card,player){ - return !player.getStorage('sbfanjian_guessed').includes(get.suit(card,player)); + audio: "sbfanjian", + filterCard: function (card, player) { + return !player + .getStorage("sbfanjian_guessed") + .includes(get.suit(card, player)); }, - suit:result.control, - position:'h', - filterTarget:lib.filter.notMe, - check:function(card){ - return 6-get.value(card); + suit: result.control, + position: "h", + filterTarget: lib.filter.notMe, + check: function (card) { + return 6 - get.value(card); }, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - var suit=get.suit(cards,player); - event.claimSuit=lib.skill.sbfanjian_backup.suit; - event.cardSuit=suit; - player.addTempSkill('sbfanjian_guessed'); - var claim=get.translation(event.claimSuit+'2'); - player.chat('我声明'+claim); - game.log(player,'声明了','#y'+claim); - var choiceList=['猜测此牌花色为'+claim,'猜测此牌花色不为'+claim,'不猜测,你翻面并令其〖反间〗失效']; - target.chooseControl().set('choiceList',choiceList).set('prompt',get.translation(player)+'对你发动了【反间】并选择了一张牌,请选择一项').set('ai',()=>{ - var player=_status.event.player,user=_status.event.getParent().player,claim=_status.event.getParent().claimSuit,suit=_status.event.getParent().cardSuit; - if(player.isTurnedOver()) return 2; - var lose=get.effect(player,{name:'losehp'},user,player); - if(user.getStorage('sbfanjian_guessed').includes(claim)&&claim==suit) return lose<=0?0:1; - if(get.attitude(player,user)>0) return 0; - var list=[0,1]; - if(player.hp<=1&&player.getFriends().length>0) list.push(2); - return list.randomGet(); - }); - 'step 1' - player.markAuto('sbfanjian_guessed',[event.cardSuit]); - if(result.index==2){ - game.log(target,'选择','#y不猜测'); - target.chat('不猜!'); + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + var suit = get.suit(cards, player); + event.claimSuit = lib.skill.sbfanjian_backup.suit; + event.cardSuit = suit; + player.addTempSkill("sbfanjian_guessed"); + var claim = get.translation(event.claimSuit + "2"); + player.chat("我声明" + claim); + game.log(player, "声明了", "#y" + claim); + var choiceList = [ + "猜测此牌花色为" + claim, + "猜测此牌花色不为" + claim, + "不猜测,你翻面并令其〖反间〗失效", + ]; + target + .chooseControl() + .set("choiceList", choiceList) + .set( + "prompt", + get.translation(player) + + "对你发动了【反间】并选择了一张牌,请选择一项" + ) + .set("ai", () => { + var player = _status.event.player, + user = _status.event.getParent().player, + claim = _status.event.getParent().claimSuit, + suit = _status.event.getParent().cardSuit; + if (player.isTurnedOver()) return 2; + var lose = get.effect(player, { name: "losehp" }, user, player); + if ( + user.getStorage("sbfanjian_guessed").includes(claim) && + claim == suit + ) + return lose <= 0 ? 0 : 1; + if (get.attitude(player, user) > 0) return 0; + var list = [0, 1]; + if (player.hp <= 1 && player.getFriends().length > 0) list.push(2); + return list.randomGet(); + }); + "step 1"; + player.markAuto("sbfanjian_guessed", [event.cardSuit]); + if (result.index == 2) { + game.log(target, "选择", "#y不猜测"); + target.chat("不猜!"); target.turnOver(); + } else { + var claim = get.translation(event.claimSuit + "2"); + target.chat("我猜花色" + (result.index == 1 ? "不" : "") + "为" + claim); + game.log( + target, + "猜测花色", + "#g" + (result.index == 1 ? "不" : "") + "为" + claim + ); } - else { - var claim=get.translation(event.claimSuit+'2'); - target.chat('我猜花色'+(result.index==1?'不':'')+'为'+claim); - game.log(target,'猜测花色','#g'+(result.index==1?'不':'')+'为'+claim); - } - if(event.isMine()&&!event.isOnline()) game.delayx(); - 'step 2' - target.gain(cards,player,'giveAuto','bySelf'); - 'step 3' - if(result.index==0&&event.claimSuit!=event.cardSuit||result.index==1&&event.claimSuit==event.cardSuit){ - game.log(target,'猜测','#y错误'); + if (event.isMine() && !event.isOnline()) game.delayx(); + "step 2"; + target.gain(cards, player, "giveAuto", "bySelf"); + "step 3"; + if ( + (result.index == 0 && event.claimSuit != event.cardSuit) || + (result.index == 1 && event.claimSuit == event.cardSuit) + ) { + game.log(target, "猜测", "#y错误"); target.loseHp(); - } - else { - if(result.index!=2) game.log(target,'猜测','#g正确'); - player.addTempSkill('sbfanjian_ban'); + } else { + if (result.index != 2) game.log(target, "猜测", "#g正确"); + player.addTempSkill("sbfanjian_ban"); } }, - ai:{ - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - var val=get.value(ui.selected.cards,target); - if(val<0) return val+get.effect(target,{name:'losehp'},player,target); - if(val>5||get.value(ui.selected.cards,player)>5) return target.isTurnedOver()?5:0; - if(target.isTurnedOver()) return 1; - return get.effect(target,{name:'losehp'},player,target); + ai: { + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + var val = get.value(ui.selected.cards, target); + if (val < 0) + return ( + val + get.effect(target, { name: "losehp" }, player, target) + ); + if (val > 5 || get.value(ui.selected.cards, player) > 5) + return target.isTurnedOver() ? 5 : 0; + if (target.isTurnedOver()) return 1; + return get.effect(target, { name: "losehp" }, player, target); }, }, }, - } + }; }, - prompt:function(result){ - return '你选择了'+get.translation(result.control)+',请选择一张手牌和【反间】的目标'; + prompt: function (result) { + return ( + "你选择了" + get.translation(result.control) + ",请选择一张手牌和【反间】的目标" + ); }, }, - subSkill:{ - guessed:{onremove:true,charlotte:true}, - ban:{charlotte:true}, - backup:{}, + subSkill: { + guessed: { onremove: true, charlotte: true }, + ban: { charlotte: true }, + backup: {}, + }, + ai: { + order: 4, + result: { player: 1 }, }, - ai:{ - order:4, - result:{player:1} - } }, //黄盖 - sbkurou:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - group:'sbkurou_gain', - content:function(){ - 'step 0' + sbkurou: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + group: "sbkurou_gain", + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('sbkurou'), - prompt2:'交给其他角色一张牌,若此牌为【桃】或【酒】,你失去2点体力,否则你失去1点体力', - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - ai1:function(card){ - if(player.hp<=1&&!player.canSave(player)||player.hujia>=5) return 0; - if(get.value(card,player)>6&&!game.hasPlayer(current=>{ - return current!=player&&get.attitude(current,player)>0&&!current.hasSkillTag('nogain'); - })) return 0; - if(player.hp>=2&&(card.name=='tao'||(card.name=='jiu'&&player.countCards('hs',cardx=>{ - return cardx!=card&&get.tag(cardx,'save'); - })))&&player.hujia<=1) return 10; - if(player.hp<=1&&!player.canSave(player)) return 0; - return 1/Math.max(0.1,get.value(card)); + prompt: get.prompt("sbkurou"), + prompt2: + "交给其他角色一张牌,若此牌为【桃】或【酒】,你失去2点体力,否则你失去1点体力", + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + ai1: function (card) { + if ((player.hp <= 1 && !player.canSave(player)) || player.hujia >= 5) return 0; + if ( + get.value(card, player) > 6 && + !game.hasPlayer((current) => { + return ( + current != player && + get.attitude(current, player) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return 0; + if ( + player.hp >= 2 && + (card.name == "tao" || + (card.name == "jiu" && + player.countCards("hs", (cardx) => { + return cardx != card && get.tag(cardx, "save"); + }))) && + player.hujia <= 1 + ) + return 10; + if (player.hp <= 1 && !player.canSave(player)) return 0; + return 1 / Math.max(0.1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(ui.selected.cards.length){ - var val=get.value(ui.selected.cards[0]); - att*=val>=0?1:-1; + ai2: function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (ui.selected.cards.length) { + var val = get.value(ui.selected.cards[0]); + att *= val >= 0 ? 1 : -1; } - if(target.hasSkillTag('nogain')) att/=9; - return 15+att; + if (target.hasSkillTag("nogain")) att /= 9; + return 15 + att; }, }); - 'step 1' - 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'].includes(get.name(card,target))?2:1); + "step 1"; + 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"].includes(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(); - } + 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', - trigger:{player:'loseHpEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.isIn()&&player.hujia<5; + subSkill: { + gain: { + audio: "sbkurou", + trigger: { player: "loseHpEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + return player.isIn() && player.hujia < 5; }, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' - player.changeHujia(2,null,true); - 'step 2' - if(--event.count>0){ - player.logSkill('sbkurou_gain'); + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + player.changeHujia(2, null, true); + "step 2"; + if (--event.count > 0) { + player.logSkill("sbkurou_gain"); event.goto(1); } }, - ai:{ - maihp:true, - effect:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,1]; + ai: { + maihp: true, + effect: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, 1]; return 1.2; } - if(get.tag(card,'loseHp')){ - if(target.hp<=1||target.hujia>=5) return; - return [1,1]; + if (get.tag(card, "loseHp")) { + if (target.hp <= 1 || target.hujia >= 5) return; + return [1, 1]; } - } - } + }, + }, }, - } - }, - sbzhaxiang:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - group:'sbzhaxiang_draw', - filter:function(event,player){ - return player.getHistory('useCard').length<=player.getDamagedHp(); }, - content:function(){ + }, + sbzhaxiang: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + group: "sbzhaxiang_draw", + filter: function (event, player) { + return player.getHistory("useCard").length <= player.getDamagedHp(); + }, + content: function () { trigger.directHit.addArray(game.filterPlayer()); }, - ai:{ - threaten:1.5, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return player.countUsed()=player.getDamagedHp()) return; - var numx=get.info(card).usable; - if(typeof numx=='function') numx=num(card,player); - if(typeof numx=='number') return num+10; + aiOrder: function (player, card, num) { + if (player.countUsed() >= player.getDamagedHp()) return; + var numx = get.info(card).usable; + if (typeof numx == "function") numx = num(card, player); + if (typeof numx == "number") return num + 10; }, }, - 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; - } + 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){ - return !event.numFixed&&player.getDamagedHp()>0; + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { + return !event.numFixed && player.getDamagedHp() > 0; }, - content:function(){ - trigger.num+=player.getDamagedHp(); + content: function () { + trigger.num += player.getDamagedHp(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'recover')&&target.hp>0&&target.needsToDiscard()<1) return [0,0]; - } - } - } - } - } + ai: { + effect: { + target: function (card, player, target) { + if ( + get.tag(card, "recover") && + target.hp > 0 && + target.needsToDiscard() < 1 + ) + return [0, 0]; + }, + }, + }, + }, + }, }, //孙权 - sbzhiheng:{ - audio:2, - audioname:['shen_caopi'], - locked:false, - 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)0) str+=',并弃1枚“业”'; - str+='。'; + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: lib.filter.cardDiscardable, + discard: false, + lose: false, + delay: false, + selectCard: [1, Infinity], + prompt: function (event) { + var count = _status.event.player.countMark("sbtongye"); + var str = + "出牌阶段限一次。你可以弃置任意张牌并摸等量的牌,若你以此法弃置的牌包括你所有手牌,则你多摸" + + get.cnNumber(count + 1) + + "张牌"; + if (count > 0) str += ",并弃1枚“业”"; + str += "。"; return str; }, - check:function(card){ - var player=_status.event.player; - if(get.position(card)=='h'&&!player.countCards('h','du')&&(player.hp>2||!player.countCards('h',function(card){ - return get.value(card)>=8; - }))){ + check: function (card) { + var player = _status.event.player; + if ( + get.position(card) == "h" && + !player.countCards("h", "du") && + (player.hp > 2 || + !player.countCards("h", function (card) { + return get.value(card) >= 8; + })) + ) { return 1; } - return 6-get.value(card); + return 6 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.discard(cards); - event.num=1; - var hs=player.getCards('h'); - if(!hs.length) event.num=0; - for(var i=0; iget.value(i)>Math.max(6,9-player.hp),'he')) return 1; + ai: { + order: function (item, player) { + if (player.hasCard((i) => get.value(i) > Math.max(6, 9 - player.hp), "he")) return 1; return 10; }, - result:{ - player:1 + 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'); + 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 + threaten: 1.56, }, }, - sbtongye:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - onremove:true, - content:function(){ - 'step 0' - 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); - player.chat('变!'); - }else{ - player.addSkill('sbtongye_nochange',1); - player.chat('不变!'); + sbtongye: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + onremove: true, + content: function () { + "step 0"; + 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); + player.chat("变!"); + } else { + player.addSkill("sbtongye_nochange", 1); + player.chat("不变!"); } - var num=game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0); - player.removeMark('sbtongye_count',player.countMark('sbtongye_count'),false); - if(num>0) player.addMark('sbtongye_count',num,false); - player.addSkill('sbtongye_settle'); + var num = game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0); + player.removeMark("sbtongye_count", player.countMark("sbtongye_count"), false); + if (num > 0) player.addMark("sbtongye_count", num, false); + player.addSkill("sbtongye_settle"); }, - marktext:'业', - intro:{ - name:'统业', - name2:'业', - content:'mark', + marktext: "业", + intro: { + name: "统业", + name2: "业", + content: "mark", }, - subSkill:{ - broadcast:{ - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + ai: { + combo: "sbzhiheng", + }, + subSkill: { + broadcast: { + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - charlotte:true, - silent:true, - filter:function(event,player){ - var num=0; - game.countPlayer(function(current){ - var evt=event.getl(current); - if(evt&&evt.es) num+=evt.es.length; + charlotte: true, + silent: true, + filter: function (event, player) { + var num = 0; + game.countPlayer(function (current) { + var evt = event.getl(current); + if (evt && evt.es) num += evt.es.length; }); - if(event.name=='equip') num--; - return num!=0; + if (event.name == "equip") num--; + return num != 0; }, - content:function(){ - if(player.hasSkill('sbtongye_change')) player.markSkill('sbtongye_change'); - if(player.hasSkill('sbtongye_nochange')) player.markSkill('sbtongye_nochange'); + content: function () { + if (player.hasSkill("sbtongye_change")) player.markSkill("sbtongye_change"); + if (player.hasSkill("sbtongye_nochange")) player.markSkill("sbtongye_nochange"); }, }, - settle:{ - audio:'sbtongye', - init:function(player){ - player.addSkill('sbtongye_broadcast'); + settle: { + audio: "sbtongye", + init: function (player) { + player.addSkill("sbtongye_broadcast"); }, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.hasSkill('sbtongye_change')||player.hasSkill('sbtongye_nochange'); + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return player.hasSkill("sbtongye_change") || player.hasSkill("sbtongye_nochange"); }, - content:function(){ - var delta=game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0)-player.countMark('sbtongye_count'); - if(player.hasSkill('sbtongye_change')&&delta!=0||player.hasSkill('sbtongye_nochange')&&delta==0){ - game.log(player,'猜测','#g正确'); - if(player.countMark('sbtongye')<2) player.addMark('sbtongye',1); - }else{ - game.log(player,'猜测','#y错误'); - player.removeMark('sbtongye',1); + content: function () { + var delta = + game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0) - player.countMark("sbtongye_count"); + if ( + (player.hasSkill("sbtongye_change") && delta != 0) || + (player.hasSkill("sbtongye_nochange") && delta == 0) + ) { + game.log(player, "猜测", "#g正确"); + if (player.countMark("sbtongye") < 2) player.addMark("sbtongye", 1); + } else { + game.log(player, "猜测", "#y错误"); + player.removeMark("sbtongye", 1); } - player.removeSkill('sbtongye_change'); - player.removeSkill('sbtongye_nochange'); - player.removeSkill('sbtongye_settle'); - player.removeSkill('sbtongye_broadcast'); - } + player.removeSkill("sbtongye_change"); + player.removeSkill("sbtongye_nochange"); + player.removeSkill("sbtongye_settle"); + player.removeSkill("sbtongye_broadcast"); + }, }, - change:{ - charlotte:true, - mark:true, - marktext:'变', - intro:{ - markcount:function(storage,player){ - return game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0)-player.countMark('sbtongye_count'); + change: { + charlotte: true, + mark: true, + marktext: "变", + intro: { + markcount: function (storage, player) { + return ( + game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0) - player.countMark("sbtongye_count") + ); }, - mark:function(dialog,storage,player){ - dialog.addText(get.translation(player)+'猜测场上装备数发生变化'); - var delta=game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0)-player.countMark('sbtongye_count'); - if(delta==0) dialog.addText('(当前未发生变化)'); - else dialog.addText('(当前已'+(delta>0?'增加':'减少')+get.cnNumber(Math.abs(delta))+'张装备牌)'); - } - } - }, - nochange:{ - charlotte:true, - mark:true, - marktext:'', - intro:{ - markcount:function(storage,player){ - return game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0)-player.countMark('sbtongye_count'); + mark: function (dialog, storage, player) { + dialog.addText(get.translation(player) + "猜测场上装备数发生变化"); + var delta = + game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0) - player.countMark("sbtongye_count"); + if (delta == 0) dialog.addText("(当前未发生变化)"); + else + dialog.addText( + "(当前已" + + (delta > 0 ? "增加" : "减少") + + get.cnNumber(Math.abs(delta)) + + "张装备牌)" + ); }, - mark:function(dialog,storage,player){ - dialog.addText(get.translation(player)+'猜测场上装备数不发生变化'); - var delta=game.filterPlayer().map(i=>i.countCards('e')).reduce((p,c)=>p+c,0)-player.countMark('sbtongye_count'); - if(delta==0) dialog.addText('(当前未发生变化)'); - else dialog.addText('(当前已'+(delta>0?'增加':'减少')+get.cnNumber(Math.abs(delta))+'张装备牌)'); - } - } + }, + }, + nochange: { + charlotte: true, + mark: true, + marktext: '', + intro: { + markcount: function (storage, player) { + return ( + game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0) - player.countMark("sbtongye_count") + ); + }, + mark: function (dialog, storage, player) { + dialog.addText(get.translation(player) + "猜测场上装备数不发生变化"); + var delta = + game + .filterPlayer() + .map((i) => i.countCards("e")) + .reduce((p, c) => p + c, 0) - player.countMark("sbtongye_count"); + if (delta == 0) dialog.addText("(当前未发生变化)"); + else + dialog.addText( + "(当前已" + + (delta > 0 ? "增加" : "减少") + + get.cnNumber(Math.abs(delta)) + + "张装备牌)" + ); + }, + }, }, - } - }, - sbjiuyuan:{ - audio:2, - trigger:{global:'useCard'}, - forced:true, - zhuSkill:true, - group:'sbjiuyuan_recover', - filter:function(event,player){ - return event.card.name=='tao'&&player!=event.player&&event.player.group=='wu'&& - event.player.isIn()&&player.hasZhuSkill('sbjiuyuan',event.player); }, - content:function(){ + }, + sbjiuyuan: { + audio: 2, + trigger: { global: "useCard" }, + forced: true, + zhuSkill: true, + group: "sbjiuyuan_recover", + filter: function (event, player) { + return ( + event.card.name == "tao" && + player != event.player && + event.player.group == "wu" && + event.player.isIn() && + player.hasZhuSkill("sbjiuyuan", event.player) + ); + }, + content: function () { player.draw(); }, - subSkill:{ - recover:{ - audio:'sbjiuyuan', - trigger:{target:'taoBegin'}, - zhuSkill:true, - forced:true, - filter:function(event,player){ - if(event.player==player) return false; - if(!player.hasZhuSkill('sbjiuyuan',event.player)) return false; - if(event.player.group!='wu') return false; + subSkill: { + recover: { + audio: "sbjiuyuan", + trigger: { target: "taoBegin" }, + zhuSkill: true, + forced: true, + filter: function (event, player) { + if (event.player == player) return false; + if (!player.hasZhuSkill("sbjiuyuan", event.player)) return false; + if (event.player.group != "wu") return false; return true; }, - content:function(){ + content: function () { trigger.baseDamage++; - } - } + }, + }, }, }, //孙尚香 - sbjieyin:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - locked:false, - dutySkill:true, - group:['sbjieyin_init','sbjieyin_fail'], - filter:function(event,player){ - return game.hasPlayer(current=>current.hasMark('sbjieyin_mark')); + sbjieyin: { + trigger: { player: "phaseUseBegin" }, + forced: true, + locked: false, + dutySkill: true, + group: ["sbjieyin_init", "sbjieyin_fail"], + filter: function (event, player) { + return game.hasPlayer((current) => current.hasMark("sbjieyin_mark")); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>current.hasMark('sbjieyin_mark')); - event.targets=targets; - 'step 1' - var target=targets.shift(); - event.target=target; - var str=target.hasSkill('sbjieyin_marked')?'移去':'移动或移去'; - var num=Math.min(2,Math.max(1,target.countCards('h'))); - target.chooseCard('交给'+get.translation(player)+get.cnNumber(num)+'张手牌,然后获得1点护甲;或令其'+str+'你的所有“助”标记',num).set('ai',card=>{ - if(_status.event.goon) return 100-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)>1); - 'step 2' - if(result.bool){ - target.give(result.cards,player); - target.changeHujia(1,null,true); + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => current.hasMark("sbjieyin_mark")); + event.targets = targets; + "step 1"; + var target = targets.shift(); + event.target = target; + var str = target.hasSkill("sbjieyin_marked") ? "移去" : "移动或移去"; + var num = Math.min(2, Math.max(1, target.countCards("h"))); + target + .chooseCard( + "交给" + + get.translation(player) + + get.cnNumber(num) + + "张手牌,然后获得1点护甲;或令其" + + str + + "你的所有“助”标记", + num + ) + .set("ai", (card) => { + if (_status.event.goon) return 100 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) > 1); + "step 2"; + if (result.bool) { + target.give(result.cards, player); + target.changeHujia(1, null, true); event.goto(4); - }else{ - if(!game.hasPlayer(current=>current!=player&¤t!=target)||target.hasSkill('sbjieyin_marked')) event._result={bool:false}; - else player.chooseTarget('结姻:是否移动'+get.translation(target)+'的“助”?',(card,player,target)=>{ - return target!=player&&target!=_status.event.getParent().target; - }).set('ai',target=>get.attitude(_status.event.player,target)-1); - target.addSkill('sbjieyin_marked'); + } else { + if ( + !game.hasPlayer((current) => current != player && current != target) || + target.hasSkill("sbjieyin_marked") + ) + event._result = { bool: false }; + else + player + .chooseTarget( + "结姻:是否移动" + get.translation(target) + "的“助”?", + (card, player, target) => { + return target != player && target != _status.event.getParent().target; + } + ) + .set("ai", (target) => get.attitude(_status.event.player, target) - 1); + target.addSkill("sbjieyin_marked"); } - 'step 3' - if(result.bool){ - var targetx=result.targets[0]; - var num=target.countMark('sbjieyin_mark'); - target.removeSkill('sbjieyin_mark'); - targetx.addSkill('sbjieyin_mark'); - targetx.addMark('sbjieyin_mark',num,false); - player.line2([target,targetx],'green'); - game.log(player,'将',target,'的'+get.cnNumber(num)+'枚“助”移动至',targetx); - }else{ - target.removeSkill('sbjieyin_mark'); - game.log(player,'移去了',target,'的'+get.cnNumber(num)+'枚“助”'); - game.createEvent('sbjieyin_fail').setContent(lib.skill.sbjieyin_fail.content).player=player; + "step 3"; + if (result.bool) { + var targetx = result.targets[0]; + var num = target.countMark("sbjieyin_mark"); + target.removeSkill("sbjieyin_mark"); + targetx.addSkill("sbjieyin_mark"); + targetx.addMark("sbjieyin_mark", num, false); + player.line2([target, targetx], "green"); + game.log(player, "将", target, "的" + get.cnNumber(num) + "枚“助”移动至", targetx); + } else { + target.removeSkill("sbjieyin_mark"); + game.log(player, "移去了", target, "的" + get.cnNumber(num) + "枚“助”"); + game.createEvent("sbjieyin_fail").setContent(lib.skill.sbjieyin_fail.content).player = + player; } - 'step 4' - if(targets.length) event.goto(1); + "step 4"; + if (targets.length) event.goto(1); }, - subSkill:{ - fail:{ - audio:'sbjieyin', - trigger:{global:'dieAfter'}, - dutySkill:true, - forced:true, - locked:false, - direct:true, - filter:function(event,player){ - return event.player.hasMark('sbjieyin_mark'); + subSkill: { + fail: { + audio: "sbjieyin", + trigger: { global: "dieAfter" }, + dutySkill: true, + forced: true, + locked: false, + direct: true, + filter: function (event, player) { + return event.player.hasMark("sbjieyin_mark"); }, - content:function(){ - player.logSkill('sbjieyin_fail'); - player.awakenSkill('sbjieyin'); - game.log(player,'使命失败'); - player.changeGroup('wu'); + content: function () { + player.logSkill("sbjieyin_fail"); + player.awakenSkill("sbjieyin"); + game.log(player, "使命失败"); + player.changeGroup("wu"); player.recover(); - player.gain(player.getExpansions('sbliangzhu'),'gain2'); + player.gain(player.getExpansions("sbliangzhu"), "gain2"); player.loseMaxHp(); - } - }, - mark:{ - charlotte:true, - mark:true, - marktext:'助', - onremove:true, - intro:{ - name:'结姻(助)', - name2:'助', - content:'mark' - } - }, - marked:{charlotte:true}, - init:{ - audio:'sbjieyin', - trigger:{ - global:'phaseBefore', - player:'enterGame', }, - forced:true, - locked:false, - direct:true, - dutySkill:true, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); + }, + mark: { + charlotte: true, + mark: true, + marktext: "助", + onremove: true, + intro: { + name: "结姻(助)", + name2: "助", + content: "mark", }, - content:function(){ - 'step 0' - player.chooseTarget('结姻:令一名其他角色获得1枚“助”',lib.filter.notMe,true).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sbjieyin_init',target); - target.addSkill('sbjieyin_mark'); - target.addMark('sbjieyin_mark',1); + }, + marked: { charlotte: true }, + init: { + audio: "sbjieyin", + trigger: { + global: "phaseBefore", + player: "enterGame", + }, + forced: true, + locked: false, + direct: true, + dutySkill: true, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); + }, + content: function () { + "step 0"; + player + .chooseTarget("结姻:令一名其他角色获得1枚“助”", lib.filter.notMe, true) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sbjieyin_init", target); + target.addSkill("sbjieyin_mark"); + target.addMark("sbjieyin_mark", 1); } - 'step 2' + "step 2"; game.delayx(); - } + }, }, - } + }, }, - sbliangzhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.group=='shu'&&game.hasPlayer(current=>current!=player&¤t.countCards('e')); + sbliangzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.group == "shu" && + game.hasPlayer((current) => current != player && current.countCards("e")) + ); }, - groupSkill:true, - filterTarget:function(card,player,target){ - return target.countCards('e')&&target!=player; + groupSkill: true, + filterTarget: function (card, player, target) { + return target.countCards("e") && target != player; }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'e',true); - 'step 1' - if(result.bool){ - player.addToExpansion(result.cards,target,'give').gaintag.add('sbliangzhu'); + content: function () { + "step 0"; + player.choosePlayerCard(target, "e", true); + "step 1"; + if (result.bool) { + player.addToExpansion(result.cards, target, "give").gaintag.add("sbliangzhu"); } else event.finish(); - 'step 2' - for(var target of game.filterPlayer(current=>current.hasMark('sbjieyin_mark'))){ - target.chooseDrawRecover(2,true); + "step 2"; + for (var target of game.filterPlayer((current) => current.hasMark("sbjieyin_mark"))) { + target.chooseDrawRecover(2, true); } }, - marktext:'妆', - intro:{ - name:'良助(妆)', - name2:'妆', - content:'expansion', - markcount:'expansion', + marktext: "妆", + intro: { + name: "良助(妆)", + name2: "妆", + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - order:9, - result:{ - player:function(player){ - var num=0,targets=game.filterPlayer(current=>current.hasMark('sbjieyin_mark')); - for(var current of targets){ - num+=2*get.effect(current,{name:'draw'},player,player); + ai: { + order: 9, + result: { + player: function (player) { + var num = 0, + targets = game.filterPlayer((current) => current.hasMark("sbjieyin_mark")); + for (var current of targets) { + num += 2 * get.effect(current, { name: "draw" }, player, player); } - if(num>0) return 3; + if (num > 0) return 3; return 1; }, - target:-1, - } - } + target: -1, + }, + }, }, - sbxiaoji:{ - audio:2, - audioname:['sp_sunshangxiang','re_sunshangxiang','db_sunshangxiang'], - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + sbxiaoji: { + audio: 2, + audioname: ["sp_sunshangxiang", "re_sunshangxiang", "db_sunshangxiang"], + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - locked:false, - groupSkill:true, - filter:function(event,player){ - if(player.group!='wu') return false; - var evt=event.getl(player); - return evt&&evt.player==player&&evt.es&&evt.es.length>0; + forced: true, + locked: false, + groupSkill: true, + filter: function (event, player) { + if (player.group != "wu") return false; + var evt = event.getl(player); + return evt && evt.player == player && evt.es && evt.es.length > 0; }, - content:function(){ - 'step 0' - event.count=trigger.getl(player).es.length; - 'step 1' + content: function () { + "step 0"; + event.count = trigger.getl(player).es.length; + "step 1"; event.count--; player.draw(2); - player.chooseTarget('是否弃置场上的一张牌?',(card,player,target)=>{ - return target.countDiscardableCards(player,'ej'); - }).set('ai',target=>{ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0&&(target.countCards('j')>0||target.countCards('e',function(card){ - return get.value(card,target)<0; - }))) return 2; - if(att<0&&target.countCards('e')>0&&!target.hasSkillTag('noe')) return -1; - return 0; - }); - 'step 2' - if(result.bool){ - player.discardPlayerCard(result.targets[0],'ej',true); + player + .chooseTarget("是否弃置场上的一张牌?", (card, player, target) => { + return target.countDiscardableCards(player, "ej"); + }) + .set("ai", (target) => { + var player = _status.event.player; + var att = get.attitude(player, target); + if ( + att > 0 && + (target.countCards("j") > 0 || + target.countCards("e", function (card) { + return get.value(card, target) < 0; + })) + ) + return 2; + if (att < 0 && target.countCards("e") > 0 && !target.hasSkillTag("noe")) + return -1; + return 0; + }); + "step 2"; + if (result.bool) { + player.discardPlayerCard(result.targets[0], "ej", true); } - 'step 3' - if(event.count>0){ - player.logSkill('sbxiaoji'); + "step 3"; + if (event.count > 0) { + player.logSkill("sbxiaoji"); event.goto(1); } }, - ai:{ - noe:true, - reverseEquip:true, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } - } + ai: { + noe: true, + reverseEquip: true, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; + }, + }, }, }, //吕蒙 - sbkeji:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - if(player.hasSkill('sbkeji_discard')) return [0,0]; - if(player.hasSkill('sbkeji_losehp')) return [1,1]; - return [0,1]; + sbkeji: { + audio: 2, + enable: "phaseUse", + filterCard: true, + selectCard: function () { + var player = _status.event.player; + if (player.hasSkill("sbkeji_discard")) return [0, 0]; + if (player.hasSkill("sbkeji_losehp")) return [1, 1]; + return [0, 1]; }, - locked:false, - usable:2, - prompt:function(event){ - var player=_status.event.player,str='出牌阶段'+(player.storage.sbkeji?'':'各')+'限一次。你可以'; - var discard=player.hasSkill('sbkeji_discard'),losehp=player.hasSkill('sbkeji_losehp'); - if(!discard) str+='弃置一张手牌并获得1点护甲'; - if(!losehp) str+=(!discard?',或':'')+'点击“确定”失去1点体力并获得2点护甲'; + locked: false, + usable: 2, + prompt: function (event) { + var player = _status.event.player, + str = "出牌阶段" + (player.storage.sbkeji ? "" : "各") + "限一次。你可以"; + var discard = player.hasSkill("sbkeji_discard"), + losehp = player.hasSkill("sbkeji_losehp"); + if (!discard) str += "弃置一张手牌并获得1点护甲"; + if (!losehp) str += (!discard ? ",或" : "") + "点击“确定”失去1点体力并获得2点护甲"; return str; }, - filter:function(event,player){ - return (player.getStat('skill').sbkeji||0)<(player.storage.sbkeji?1:2); + filter: function (event, player) { + return (player.getStat("skill").sbkeji || 0) < (player.storage.sbkeji ? 1 : 2); }, - check:function(card){ - var player=_status.event.player; - if(_status.event.player.hp==1&&player.canSave(player)&&player.hujia<=3) return 0; - return 6-get.value(card); + check: function (card) { + var player = _status.event.player; + if (_status.event.player.hp == 1 && player.canSave(player) && player.hujia <= 3) return 0; + return 6 - get.value(card); }, - content:function(){ - 'step 0' - if(cards.length){ - player.changeHujia(1,null,true); - player.addTempSkill('sbkeji_discard','phaseUseAfter'); + content: function () { + "step 0"; + if (cards.length) { + player.changeHujia(1, null, true); + player.addTempSkill("sbkeji_discard", "phaseUseAfter"); event.finish(); - } - else{ + } else { player.loseHp(); } - 'step 1' - player.changeHujia(2,null,true); - player.addTempSkill('sbkeji_losehp','phaseUseAfter'); + "step 1"; + player.changeHujia(2, null, true); + player.addTempSkill("sbkeji_losehp", "phaseUseAfter"); }, - mod:{ - maxHandcard:function(player,num){ - return num+player.hujia; + mod: { + maxHandcard: function (player, num) { + return num + player.hujia; }, - cardEnabled:function(card,player){ - if(player!=_status.event.dying&&card.name=='tao') return false; + cardEnabled: function (card, player) { + if (player != _status.event.dying && card.name == "tao") return false; }, - cardSavable:function(card,player){ - if(player!=_status.event.dying&&card.name=='tao') return false; + cardSavable: function (card, player) { + if (player != _status.event.dying && card.name == "tao") return false; }, }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.hujia>=5) return 0; - if(player.hp==1&&!player.canSave(player)&&!player.hasCard(card=>{ - return lib.filter.cardDiscardable(card,player,'sbkeji')&&get.value(card)<6; - },'h')){ + ai: { + order: 1, + result: { + player: function (player, target) { + if (player.hujia >= 5) return 0; + if ( + player.hp == 1 && + !player.canSave(player) && + !player.hasCard((card) => { + return ( + lib.filter.cardDiscardable(card, player, "sbkeji") && + get.value(card) < 6 + ); + }, "h") + ) { return 0; } return 1; - } + }, }, }, - subSkill:{ - discard:{charlotte:true}, - losehp:{charlotte:true}, - } + subSkill: { + discard: { charlotte: true }, + losehp: { charlotte: true }, + }, }, - sbdujiang:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - derivation:'sbduojing', - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - return player.hujia>=3; + sbdujiang: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + derivation: "sbduojing", + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + return player.hujia >= 3; + }, + content: function () { + player.awakenSkill("sbdujiang"); + player.addSkills("sbduojing"); + player.storage.sbkeji = true; }, - content:function(){ - player.awakenSkill('sbdujiang'); - player.addSkills('sbduojing'); - player.storage.sbkeji=true; - } }, - sbduojing:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - return player.hujia>0&&event.card.name=='sha'; + sbduojing: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + return player.hujia > 0 && event.card.name == "sha"; }, - check:function(event,player){ - return event.target.countGainableCards(player,'he')>0||player.countCards('hs',{name:'sha'})>0; + check: function (event, player) { + return ( + event.target.countGainableCards(player, "he") > 0 || + player.countCards("hs", { name: "sha" }) > 0 + ); }, - logTarget:'target', - content:function(){ - 'step 0' + logTarget: "target", + content: function () { + "step 0"; player.changeHujia(-1); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.sbduojing=true; - 'step 1' - var target=trigger.target; - if(target.countGainableCards(player,'he')>0) player.gainPlayerCard(target,'he',true); - player.addTempSkill('sbduojing_add','phaseUseAfter'); - player.addMark('sbduojing_add',1,false); - player.markSkill('sbduojing_add'); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.sbduojing = true; + "step 1"; + var target = trigger.target; + if (target.countGainableCards(player, "he") > 0) + player.gainPlayerCard(target, "he", true); + player.addTempSkill("sbduojing_add", "phaseUseAfter"); + player.addMark("sbduojing_add", 1, false); + player.markSkill("sbduojing_add"); }, - subSkill:{ - add:{ - charlotte:true, - marktext:'夺', - onremove:true, - intro:{ - content:'本阶段使用杀次数上限+$' + subSkill: { + add: { + charlotte: true, + marktext: "夺", + onremove: true, + intro: { + content: "本阶段使用杀次数上限+$", }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('sbduojing_add'); + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("sbduojing_add"); }, }, }, }, - ai:{ - unequip:true, - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(player.hujia<=0) return; - if(tag=='unequip'&&(!arg||!arg.card||!arg.card.storage||!arg.card.storage.sbduojing)) return false; - if(tag=='unequip_ai'&&(!arg||arg.name!='sha')) return false; + ai: { + unequip: true, + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (player.hujia <= 0) return; + if ( + tag == "unequip" && + (!arg || !arg.card || !arg.card.storage || !arg.card.storage.sbduojing) + ) + return false; + if (tag == "unequip_ai" && (!arg || arg.name != "sha")) return false; }, }, }, //于禁 - sbxiayuan:{ - audio:2, - trigger:{global:'damageEnd'}, - direct:true, - filter:function(event,player){ - return event.hujia&&!event.player.hujia&&event.player.isIn()&&player.countCards('h')>1&&!player.hasSkill('sbxiayuan_round',null,false,false); + sbxiayuan: { + audio: 2, + trigger: { global: "damageEnd" }, + direct: true, + filter: function (event, player) { + return ( + event.hujia && + !event.player.hujia && + event.player.isIn() && + player.countCards("h") > 1 && + !player.hasSkill("sbxiayuan_round", null, false, false) + ); }, - content:function(){ - 'step 0' - player.addTempSkill('sbxiayuan_round','roundStart'); - player.chooseToDiscard(2,'h',get.prompt('sbxiayuan',trigger.player),'弃置两张手牌,令其获得'+get.cnNumber(trigger.hujia)+'点护甲').set('goon',get.attitude(player,trigger.player)>0).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 5-get.value(card); - }).logSkill=['sbxiayuan',trigger.player]; - 'step 1' - if(result.bool){ - var target=trigger.player; - target.changeHujia(trigger.hujia,null,true); + content: function () { + "step 0"; + player.addTempSkill("sbxiayuan_round", "roundStart"); + player + .chooseToDiscard( + 2, + "h", + get.prompt("sbxiayuan", trigger.player), + "弃置两张手牌,令其获得" + get.cnNumber(trigger.hujia) + "点护甲" + ) + .set("goon", get.attitude(player, trigger.player) > 0) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 5 - get.value(card); + }).logSkill = ["sbxiayuan", trigger.player]; + "step 1"; + if (result.bool) { + var target = trigger.player; + target.changeHujia(trigger.hujia, null, true); game.delayx(); - } - else player.removeSkill('sbxiayuan_round'); + } else player.removeSkill("sbxiayuan_round"); }, - subSkill:{round:{charlotte:true}}, - ai:{expose:0.2}, + subSkill: { round: { charlotte: true } }, + ai: { expose: 0.2 }, }, - sbjieyue:{ - audio:4, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('sbjieyue'),'令一名其他角色获得1点护甲,然后该角色可以交给你一张牌。').set('ai',function(target){ - return get.attitude(_status.event.player,target)/Math.sqrt(Math.min(1,target.hp+target.hujia)); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('sbjieyue',target); - target.changeHujia(1,null,true); - target.chooseCard('he','是否交给'+get.translation(player)+'一张牌?').set('ai',(card)=>0.1-get.value(card)); - } - else event.finish(); - 'step 2' - if(result.bool){ - target.give(result.cards,player); + sbjieyue: { + audio: 4, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + lib.filter.notMe, + get.prompt("sbjieyue"), + "令一名其他角色获得1点护甲,然后该角色可以交给你一张牌。" + ) + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) / + Math.sqrt(Math.min(1, target.hp + target.hujia)) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("sbjieyue", target); + target.changeHujia(1, null, true); + target + .chooseCard("he", "是否交给" + get.translation(player) + "一张牌?") + .set("ai", (card) => 0.1 - get.value(card)); + } else event.finish(); + "step 2"; + if (result.bool) { + target.give(result.cards, player); } }, - ai:{ - threaten:2.7, - expose:0.2, + ai: { + threaten: 2.7, + expose: 0.2, }, }, //华雄 - sbyangwei:{ - audio:3, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('sbyangwei_counter',null,null,false); + sbyangwei: { + audio: 3, + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("sbyangwei_counter", null, null, false); }, - content:function(){ + content: function () { player.draw(2); - player.addTempSkill('sbyangwei_effect'); - player.addSkill('sbyangwei_counter'); + player.addTempSkill("sbyangwei_effect"); + player.addSkill("sbyangwei_counter"); }, - ai:{ - order:9, - result:{player:1}, + ai: { + order: 9, + result: { player: 1 }, }, - subSkill:{ - effect:{ - audio:'sbyangwei', - equipSkill:false, - inherit:'qinggang_skill', - charlotte:true, - nopop:true, - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; + subSkill: { + effect: { + audio: "sbyangwei", + equipSkill: false, + inherit: "qinggang_skill", + charlotte: true, + nopop: true, + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, - mark:true, - marktext:'威', - intro:{content:'使用【杀】的次数上限+1且无距离限制且无视防具'}, + mark: true, + marktext: "威", + intro: { content: "使用【杀】的次数上限+1且无距离限制且无视防具" }, }, - counter:{ - trigger:{player:'phaseJieshu'}, - silent:true, - popup:false, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - if(!player.storage.sbyangwei_counter) player.storage.sbyangwei_counter=true; - else player.removeSkill('sbyangwei_counter'); + counter: { + trigger: { player: "phaseJieshu" }, + silent: true, + popup: false, + forced: true, + charlotte: true, + onremove: true, + content: function () { + if (!player.storage.sbyangwei_counter) player.storage.sbyangwei_counter = true; + else player.removeSkill("sbyangwei_counter"); }, }, }, }, //黄忠 - sbliegong:{ - audio:2, - mod:{ - cardnature:function(card,player){ - if(player.hasEmptySlot(1)&&get.name(card,player)=='sha') return false; + sbliegong: { + audio: 2, + mod: { + cardnature: function (card, player) { + if (player.hasEmptySlot(1) && get.name(card, player) == "sha") return false; }, }, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return !event.getParent()._sbliegong_player&&event.targets.length==1&&event.card.name=='sha'&&player.getStorage('sbliegong').length>0; + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return ( + !event.getParent()._sbliegong_player && + event.targets.length == 1 && + event.card.name == "sha" && + player.getStorage("sbliegong").length > 0 + ); }, - prompt2:function(event,player){ - var str='',storage=player.getStorage('sbliegong'); - if(storage.length>1){ - str+=('展示牌堆顶的'+get.cnNumber(storage.length-1)+'张牌并增加伤害;且'); + prompt2: function (event, player) { + var str = "", + storage = player.getStorage("sbliegong"); + if (storage.length > 1) { + str += "亮出牌堆顶的" + get.cnNumber(storage.length - 1) + "张牌并增加伤害;且"; } - str+=('令'+get.translation(event.target)+'不能使用花色为'); - for(var i=0;i0) return false; - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:event.card, - })) return false; - var storage=player.getStorage('sbliegong'); - if(storage.length>=4) return true; - if(storage.length<3) return false; - if(target.hasShan()) return storage.includes('heart')&&storage.includes('diamond'); + logTarget: "target", + locked: false, + check: function (event, player) { + var target = event.target; + if (get.attitude(player, target) > 0) return false; + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: event.card, + }) + ) + return false; + var storage = player.getStorage("sbliegong"); + if (storage.length >= 4) return true; + if (storage.length < 3) return false; + if (target.hasShan()) return storage.includes("heart") && storage.includes("diamond"); return true; }, - content:function(){ - var storage=player.getStorage('sbliegong').slice(0); - var num=storage.length-1; - var evt=trigger.getParent(); - if(num>0){ - if(typeof evt.baseDamage!='number') evt.baseDamage=1; - var cards=get.cards(num); - player.showCards(cards.slice(0),get.translation(player)+'发动了【烈弓】'); - while(cards.length>0){ - var card=cards.pop(); - if(storage.includes(get.suit(card,false))) evt.baseDamage++; - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + content: function () { + var storage = player.getStorage("sbliegong").slice(0); + var num = storage.length - 1; + var evt = trigger.getParent(); + if (num > 0) { + if (typeof evt.baseDamage != "number") evt.baseDamage = 1; + var cards = get.cards(num); + player.showCards(cards.slice(0), get.translation(player) + "发动了【烈弓】"); + while (cards.length > 0) { + var card = cards.pop(); + if (storage.includes(get.suit(card, false))) evt.baseDamage++; + //ui.cardPile.insertBefore(card,ui.cardPile.firstChild); } - game.updateRoundNumber(); + //game.updateRoundNumber(); } - evt._sbliegong_player=player; - player.addTempSkill('sbliegong_clear'); - var target=trigger.target; - target.addTempSkill('sbliegong_block'); - if(!target.storage.sbliegong_block) target.storage.sbliegong_block=[]; - target.storage.sbliegong_block.push([evt.card,storage]); + evt._sbliegong_player = player; + player.addTempSkill("sbliegong_clear"); + var target = trigger.target; + target.addTempSkill("sbliegong_block"); + if (!target.storage.sbliegong_block) target.storage.sbliegong_block = []; + target.storage.sbliegong_block.push([evt.card, storage]); lib.skill.sbliegong.updateBlocker(target); }, - updateBlocker:function(player){ - var list=[],storage=player.storage.sbliegong_block; - if(storage&&storage.length){ - for(var i of storage) list.addArray(i[1]); + updateBlocker: function (player) { + var list = [], + storage = player.storage.sbliegong_block; + if (storage && storage.length) { + for (var i of storage) list.addArray(i[1]); } - player.storage.sbliegong_blocker=list; + player.storage.sbliegong_blocker = list; }, - ai:{ - threaten:3.5, - directHit_ai:true, - halfneg:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha'){ - var storage=player.getStorage('sbliegong'); - if(storage.length<3||!storage.includes('heart')||!storage.includes('diamond')) return false; - var target=arg.target; - if(target.hasSkill('bagua_skill')||target.hasSkill('bazhen')||target.hasSkill('rw_bagua_skill')) return false; + ai: { + threaten: 3.5, + directHit_ai: true, + halfneg: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha") { + var storage = player.getStorage("sbliegong"); + if ( + storage.length < 3 || + !storage.includes("heart") || + !storage.includes("diamond") + ) + return false; + var target = arg.target; + if ( + target.hasSkill("bagua_skill") || + target.hasSkill("bazhen") || + target.hasSkill("rw_bagua_skill") + ) + return false; return true; } return false; }, }, - intro:{ - content:'已记录花色:$', - onunmark:true, + intro: { + content: "已记录花色:$", + onunmark: true, }, - group:'sbliegong_count', - subSkill:{ - clear:{ - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return event._sbliegong_player==player; + group: "sbliegong_count", + subSkill: { + clear: { + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return event._sbliegong_player == player; }, - content:function(){ - player.unmarkSkill('sbliegong'); + content: function () { + player.unmarkSkill("sbliegong"); }, }, - block:{ - mod:{ - cardEnabled:function(card,player){ - if(!player.storage.sbliegong_blocker) return; - var suit=get.suit(card); - if(suit=='none') return; - var evt=_status.event; - if(evt.name!='chooseToUse') evt=evt.getParent('chooseToUse'); - if(!evt||!evt.respondTo||evt.respondTo[1].name!='sha') return; - if(player.storage.sbliegong_blocker.includes(suit)) return false; + block: { + mod: { + cardEnabled: function (card, player) { + if (!player.storage.sbliegong_blocker) return; + var suit = get.suit(card); + if (suit == "none") return; + var evt = _status.event; + if (evt.name != "chooseToUse") evt = evt.getParent("chooseToUse"); + if (!evt || !evt.respondTo || evt.respondTo[1].name != "sha") return; + if (player.storage.sbliegong_blocker.includes(suit)) return false; }, }, - trigger:{ - player:['damageBefore','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded','useCardToEnd'], - global:['useCardEnd'], + trigger: { + player: ["damageBefore", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded", "useCardToEnd"], + global: ["useCardEnd"], }, - forced:true, - firstDo:true, - charlotte:true, - onremove:function(player){ + forced: true, + firstDo: true, + charlotte: true, + onremove: function (player) { delete player.storage.sbliegong_block; delete player.storage.sbliegong_blocker; }, - filter:function(event,player){ - if(!event.card||!player.storage.sbliegong_block) return false; - for(var i of player.storage.sbliegong_block){ - if(i[0]==event.card) return true; + filter: function (event, player) { + if (!event.card || !player.storage.sbliegong_block) return false; + for (var i of player.storage.sbliegong_block) { + if (i[0] == event.card) return true; } return false; }, - content:function(){ - var storage=player.storage.sbliegong_block; - for(var i=0;i1; + splveying: { + audio: 2, + trigger: { player: "useCardAfter" }, + forced: true, + filter: function (event, player) { + return event.card.name == "sha" && player.countMark("splveying") > 1; }, - content:function(){ - 'step 0' - player.removeMark('splveying',2); + content: function () { + "step 0"; + player.removeMark("splveying", 2); player.draw(); - 'step 1' - player.chooseUseTarget('guohe'); + "step 1"; + player.chooseUseTarget("guohe"); }, - marktext:'椎', - intro:{ - name:'椎(掠影/莺舞)', - name2:'椎', - content:'mark', + marktext: "椎", + intro: { + name: "椎(掠影/莺舞)", + name2: "椎", + content: "mark", }, - group:'splveying_add', - subSkill:{ - add:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - usable:2, - filter:function(event,player){ - return event.card.name=='sha'&&player.isPhaseUsing(); + group: "splveying_add", + subSkill: { + add: { + trigger: { player: "useCardToPlayered" }, + forced: true, + usable: 2, + filter: function (event, player) { + return event.card.name == "sha" && player.isPhaseUsing(); }, - content:function(){ - player.addMark('splveying',1); + content: function () { + player.addMark("splveying", 1); }, }, }, }, - spyingwu:{ - group:'spyingwu_add', - audio:2, - trigger:{player:'useCardAfter'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.hasSkill('splveying',null,null,false)&&(get.type(event.card)=='trick'&&!get.tag(event.card,'damage'))&&player.countMark('splveying')>1; + spyingwu: { + group: "spyingwu_add", + audio: 2, + trigger: { player: "useCardAfter" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player.hasSkill("splveying", null, null, false) && + get.type(event.card) == "trick" && + !get.tag(event.card, "damage") && + player.countMark("splveying") > 1 + ); }, - content:function(){ - player.removeMark('splveying',2); + content: function () { + player.removeMark("splveying", 2); player.draw(); - player.chooseUseTarget('sha',false); + player.chooseUseTarget("sha", false); }, - ai:{combo:'splveying'}, - subSkill:{ - add:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - locked:false, - usable:2, - filter:function(event,player){ - return player.hasSkill('splveying')&&(get.type(event.card)=='trick'&&!get.tag(event.card,'damage'))&&player.isPhaseUsing(); + ai: { combo: "splveying" }, + subSkill: { + add: { + trigger: { player: "useCardToPlayered" }, + forced: true, + locked: false, + usable: 2, + filter: function (event, player) { + return ( + player.hasSkill("splveying") && + get.type(event.card) == "trick" && + !get.tag(event.card, "damage") && + player.isPhaseUsing() + ); }, - content:function(){ - player.addMark('splveying',1); + content: function () { + player.addMark("splveying", 1); }, }, }, }, //手杀杨婉 - spmingxuan:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - var list=player.getStorage('spmingxuan'); - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&&!list.includes(current); - }); + spmingxuan: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + filter: function (event, player) { + var list = player.getStorage("spmingxuan"); + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && !list.includes(current); + }) + ); }, - content:function(){ - 'step 0' - var suits=[],hs=player.getCards('h'); - for(var i of hs) suits.add(get.suit(i,player)); - var list=player.getStorage('spmingxuan'),num=Math.min(suits.length,game.countPlayer(function(current){ - return current!=player&&!list.includes(current); - })); - player.chooseCard('h',true,[1,num],'瞑昡:请选择至多'+get.cnNumber(num)+'张花色各不相同的手牌',function(card,player){ - if(!ui.selected.cards.length) return true; - var suit=get.suit(card); - for(var i of ui.selected.cards){ - if(get.suit(i,player)==suit) return false; - } - return true; - }).set('complexCard',true).set('ai',(card)=>6-get.value(card)); - 'step 1' - if(result.bool){ - var list=player.getStorage('spmingxuan'),cards=result.cards.randomSort(); - var targets=game.filterPlayer((current)=>(current!=player&&!list.includes(current))).randomGets(cards.length).sortBySeat(); - player.line(targets,'green'); - var map=[]; - for(var i=0;i 6 - get.value(card)); + "step 1"; + if (result.bool) { + var list = player.getStorage("spmingxuan"), + cards = result.cards.randomSort(); + var targets = game + .filterPlayer((current) => current != player && !list.includes(current)) + .randomGets(cards.length) + .sortBySeat(); + player.line(targets, "green"); + var map = []; + for (var i = 0; i < targets.length; i++) { + map.push([targets[i], cards[i]]); } game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); - event.targets=targets; - event.num=0; - } - else event.finish(); - 'step 2' + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); + event.targets = targets; + event.num = 0; + } else event.finish(); + "step 2"; game.delayx(); - 'step 3' - if(num0); - } - else event.finish(); - 'step 2' - if(result.bool){ - if(target.canUse('sha',trigger.source,false)) target.useCard({name:'sha',isCard:true},trigger.source,false); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("spxianchou"), function (card, player, target) { + return target != player && target != _status.event.getTrigger().source; + }) + .set("ai", function (target) { + return ( + get.attitude(target, _status.event.player) * + Math.sqrt(target.countCards("he")) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("spxianchou", target); + player.line2([target, trigger.source]); + target + .chooseToDiscard( + "he", + "是否弃置一张牌,视为对" + + get.translation(trigger.source) + + "使用一张【杀】?" + ) + .set("ai", function (card) { + if (_status.event.goon) return 8 - get.value(card); + return 0; + }) + .set( + "goon", + (target.canUse("sha", trigger.source, false) + ? get.effect( + trigger.source, + { name: "sha", isCard: true }, + target, + target + ) + : 0) + + get.recoverEffect(player, target, target) > + 0 + ); + } else event.finish(); + "step 2"; + if (result.bool) { + if (target.canUse("sha", trigger.source, false)) + target.useCard({ name: "sha", isCard: true }, trigger.source, false); else event.finish(); - } - else event.finish(); - 'step 3' - if(target.hasHistory('sourceDamage',function(evt){ - var card=evt.card; - if(!card||card.name!='sha') return false; - var evtx=evt.getParent('useCard'); - return evtx.card==card&&evtx.getParent()==event; - })){ + } else event.finish(); + "step 3"; + if ( + target.hasHistory("sourceDamage", function (evt) { + var card = evt.card; + if (!card || card.name != "sha") return false; + var evtx = evt.getParent("useCard"); + return evtx.card == card && evtx.getParent() == event; + }) + ) { target.draw(); player.recover(); } }, }, }, - dynamicTranslate:{ - sbkeji:function(player){ - return '①出牌阶段' + (player.storage.sbkeji ? '' :'各') + '限一次。你可以选择一项:1.弃置一张手牌,然后获得1点护甲;2.失去1点体力,然后获得2点护甲。②你的手牌上限+X(X为你的护甲数)。③若你不为正在结算濒死流程的角色,你不能使用【桃】。'; + dynamicTranslate: { + sbkeji: function (player) { + return ( + "①出牌阶段" + + (player.storage.sbkeji ? "" : "各") + + "限一次。你可以选择一项:1.弃置一张手牌,然后获得1点护甲;2.失去1点体力,然后获得2点护甲。②你的手牌上限+X(X为你的护甲数)。③若你不为正在结算濒死流程的角色,你不能使用【桃】。" + ); }, - sblongdan:function(player){ - if(player.hasSkill('sblongdan_mark',null,null,false)) return '蓄力技(1/3)。①你可以消耗1点蓄力值,将一张基本牌当做任意基本牌使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。'; - return '蓄力技(1/3)。①你可以消耗1点蓄力值,将【杀】当做【闪】或将【闪】当做【杀】使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。'; + sblongdan: function (player) { + if (player.hasSkill("sblongdan_mark", null, null, false)) + return "蓄力技(1/3)。①你可以消耗1点蓄力值,将一张基本牌当做任意基本牌使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。"; + return "蓄力技(1/3)。①你可以消耗1点蓄力值,将【杀】当做【闪】或将【闪】当做【杀】使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。"; }, - sblianhuan:function(player){ - var str='①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。'; - if(!player.storage.sblianhuan) str+='③当你使用【铁索连环】时,你可以失去1点体力,然后当此牌指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。'; - else str+='③当你使用【铁索连环】时,你可以额外指定任意名角色为目标。④当你使用【铁索连环】指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。'; + sblianhuan: function (player) { + var str = + "①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。"; + if (!player.storage.sblianhuan) + str += + "③当你使用【铁索连环】时,你可以失去1点体力,然后当此牌指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。"; + else + str += + "③当你使用【铁索连环】时,你可以额外指定任意名角色为目标。④当你使用【铁索连环】指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。"; return str; }, - sbjiang:function(player){ - var str='①当你使用【决斗】或红色【杀】指定目标后,或当你成为【决斗】或红色【杀】的目标后,你摸一张牌。②当你使用【决斗】时,你可以额外指定一名目标,然后你失去1点体力。③出牌阶段限'; - if(player.countMark('sbjiang')) str+='X次。你可以将所有手牌当【决斗】使用(X为场上其他吴势力角色数+1)。'; - else str+='一次。你可以将所有手牌当【决斗】使用。'; + sbjiang: function (player) { + var str = + "①当你使用【决斗】或红色【杀】指定目标后,或当你成为【决斗】或红色【杀】的目标后,你摸一张牌。②当你使用【决斗】时,你可以额外指定一名目标,然后你失去1点体力。③出牌阶段限"; + if (player.countMark("sbjiang")) + str += "X次。你可以将所有手牌当【决斗】使用(X为场上其他吴势力角色数+1)。"; + else str += "一次。你可以将所有手牌当【决斗】使用。"; return str; }, - sbzhenliang:function(player){ - var storage=player.storage.sbzhenliang; - var str='转换技。'; - if(!storage) str+=''; - str+='阴:出牌阶段限一次,你可以弃置X张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害(X为你与其体力值值差且X至少为1)。'; - if(!storage) str+=''; - if(storage) str+=''; - str+='阳:你的回合外,一名角色使用或打出牌结算完成后,若此牌与“任”类别相同,则你可以令一名角色摸两张牌。'; - if(storage) str+=''; + sbzhenliang: function (player) { + var storage = player.storage.sbzhenliang; + var str = "转换技。"; + if (!storage) str += ''; + str += + "阴:出牌阶段限一次,你可以弃置X张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害(X为你与其体力值值差且X至少为1)。"; + if (!storage) str += ""; + if (storage) str += ''; + str += + "阳:你的回合外,一名角色使用或打出牌结算完成后,若此牌与“任”类别相同,则你可以令一名角色摸两张牌。"; + if (storage) str += ""; return str; }, }, - translate:{ - sb_zhanghe_prefix:'谋', - sb_yujin_prefix:'谋', - sb_huaxiong_prefix:'谋', - liucheng_prefix:'谋', - sp_yangwan_prefix:'谋', - sb_huangzhong_prefix:'谋', - sb_lvmeng_prefix:'谋', - sb_sunshangxiang_prefix:'谋', - sb_sunquan_prefix:'谋', - sb_huanggai_prefix:'谋', - sb_zhouyu_prefix:'谋', - sb_caoren_prefix:'谋', - sb_xiahoushi_prefix:'谋', - sb_zhangjiao_prefix:'谋', - sb_caocao_prefix:'谋', - sb_zhenji_prefix:'谋', - sb_ganning_prefix:'谋', - sb_machao_prefix:'谋', - sb_xuhuang_prefix:'谋', - sb_zhangfei_prefix:'谋', - sb_zhaoyun_prefix:'谋', - sb_liubei_prefix:'谋', - sb_jiangwei_prefix:'谋', - sb_fazheng_prefix:'谋', - sb_chengong_prefix:'谋', - sb_diaochan_prefix:'谋', - sb_yuanshao_prefix:'谋', - sb_pangtong_prefix:'谋', - sb_sunce_prefix:'谋', - sb_daqiao_prefix:'谋', - sb_liubiao_prefix:'谋', - sb_zhurong_prefix:'谋', - sb_menghuo_prefix:'谋', - sp_yangwan:'谋杨婉', - spmingxuan:'瞑昡', - spmingxuan_info:'锁定技。出牌阶段开始时,你须选择至多X张花色各不相同的手牌(X为未选择过选项一的角色),将这些牌随机交给这些角色中的等量角色。然后这些角色依次选择一项:⒈对你使用一张【杀】。⒉交给你一张牌,然后你摸一张牌。', - spxianchou:'陷仇', - spxianchou_info:'当你受到有来源的伤害后,你可选择一名不为伤害来源的其他角色。该角色可以弃置一张牌,然后视为对伤害来源使用一张【杀】(无距离限制)。若其因此【杀】造成了伤害,则其摸一张牌,你回复1点体力。', - liucheng:'谋刘赪', - splveying:'掠影', - splveying_info:'锁定技。①每回合限两次,当你使用【杀】指定目标后,你获得一个“椎”。②当你使用的【杀】结算结束后,若你的“椎”数大于1,则你弃置两个“椎”并摸一张牌,然后可以视为使用一张【过河拆桥】。', - spyingwu:'莺舞', - spyingwu_info:'若你拥有〖掠影〗,则:①每回合限两次,当你使用非伤害类普通锦囊牌指定目标后,你获得一个“椎”。②当你使用的非伤害类普通锦囊牌结算结束后,若你的“椎”数大于1,则你弃置两个“椎”并摸一张牌,然后可以视为使用一张【杀】。', - sb_huangzhong:'谋黄忠', - sbliegong:'烈弓', - sbliegong_info:'①若你的装备区内没有武器牌,则你手牌区内所有【杀】的属性视为无属性。②当你使用牌时,或成为其他角色使用牌的目标后,你记录此牌的花色。③当你使用【杀】指定唯一目标后,若你〖烈弓②〗的记录不为空,则你可亮出牌堆顶的X张牌(X为你〖烈弓②〗记录过的花色数-1),令此【杀】的伤害值基数+Y(Y为亮出牌中被〖烈弓②〗记录过花色的牌的数量),且目标角色不能使用〖烈弓②〗记录过花色的牌响应此【杀】。此【杀】使用结算结束后,你清除〖烈弓②〗的记录。', - sb_huaxiong:'谋华雄', - sbyangwei:'扬威', - sbyangwei_info:'出牌阶段,你可以摸两张牌,令此技能于你的下下个结束阶段前失效,且你获得如下效果直到回合结束:使用【杀】无距离限制,次数上限+1且无视防具。', - sb_yujin:'谋于禁', - sbxiayuan:'狭援', - sbxiayuan_info:'每轮限一次。其他角色受到伤害后,若其因此伤害触发过护甲效果且其没有护甲,则你可弃置两张手牌,令其获得X点护甲(X为其因此伤害触发护甲效果而失去的护甲数量)。', - sbjieyue:'节钺', - sbjieyue_info:'结束阶段,你可以令一名其他角色获得1点护甲。然后其可以交给你一张牌。', - sb_lvmeng:'谋吕蒙', - sbkeji:'克己', - sbkeji_info:'①出牌阶段各限一次。你可以选择一项:1.弃置一张手牌,然后获得1点护甲;2.失去1点体力,然后获得2点护甲。②你的手牌上限+X(X为你的护甲数)。③若你不为正在结算濒死流程的角色,你不能使用【桃】。', - sbdujiang:'渡江', - sbdujiang_info:'觉醒技。准备阶段,若你的护甲数不少于3,你获得〖夺荆〗,修改〖克己①〗为“出牌阶段限一次”。', - sbduojing:'夺荆', - sbduojing_info:'当你使用【杀】指定目标时,你可以失去1点护甲。然后令此【杀】无视防具,你获得目标角色一张牌,本回合使用【杀】的次数上限+1。', - sb_sunshangxiang:'谋孙尚香', - sbjieyin:'结姻', - sbjieyin_info:'使命技。①游戏开始时,你令一名其他角色获得1枚“助”。②出牌阶段开始时,有“助”的角色选择一项:1.交给你X张手牌(X=min(2,其手牌数)且至少为1),然后获得1点护甲;2.令你将“助”移动给另一名其他角色,或移去其“助”(若其此前获得过“助”,则只能移去)。③失败:当一名角色死亡后,若其于死亡时有“助”,或当你因〖结姻②〗移去“助”后,你将势力改为吴,回复1点体力,获得所有“妆”并减1点体力上限。', - sbliangzhu:'良助', - sbliangzhu_info:'蜀势力技。出牌阶段限一次,你可以将一名其他角色装备区里的一张牌置于武将牌上,称为“妆”,然后有“助”的角色须选择回复1点体力或摸两张牌。', - sbxiaoji:'枭姬', - sbxiaoji_info:'吴势力技。当你失去装备区里的一张牌后,你摸两张牌,然后可以弃置场上的一张牌。', - sb_sunquan:'谋孙权', - sbzhiheng:'制衡', - sbzhiheng_info:'出牌阶段限一次。你可以弃置任意张牌并摸等量的牌,若你以此法弃置的牌包括你所有手牌,则你多摸X张牌(X为你的“业”数+1),并弃1枚“业”。', - sbtongye:'统业', - sbtongye_info:'锁定技。结束阶段,你猜测场上装备牌数与你下一个准备阶段的场上装备牌数是否相等,并获得以下效果:你下一个准备阶段,若你猜对且“业”数小于2,你获得1枚“业”;若你猜错,你弃1枚“业”。', - sbjiuyuan:'救援', - sbjiuyuan_info:'主公技,锁定技。①其他吴势力角色使用【桃】时,你摸一张牌。②其他吴势力角色对你使用的【桃】的回复量+1。', - sb_huanggai:'谋黄盖', - sbkurou:'苦肉', - sbkurou_info:'①出牌阶段开始时,你可以交给其他角色一张牌,若此牌于对方手牌区内为【桃】或【酒】,你失去2点体力,否则你失去1点体力。②当你失去1点体力后,你获得2点护甲。', - sbzhaxiang:'诈降', - sbzhaxiang_info:'锁定技。①摸牌阶段,你多摸X张牌。②你每回合使用的前X张牌无距离与次数限制且不能被响应(X为你已损失的体力值)。', - sb_zhouyu:'谋周瑜', - sbyingzi:'英姿', - sbyingzi_info:'锁定技。摸牌阶段,你多摸X张牌,且令你本回合手牌上限+X(X为以下条件中你满足的项数:手牌数不小于2、体力值不小于2、装备区里的牌数不小于1)。', - sbfanjian:'反间', - sbfanjian_info:'出牌阶段,你可以声明一个花色并选择一张牌和一名其他角色(每种花色的牌每回合限一次)。其须选择一项:1.猜测此牌花色与你所声明花色是否相同;2.翻面。然后其正面向上获得此牌。若其选择猜测且猜测错误,其失去1点体力,否则其令你〖反间〗于本回合失效。', - sb_caoren:'谋曹仁', - sbjushou:'据守', - sbjushou_info:'①出牌阶段限一次。若你的武将牌正面朝上,你可以弃置至多两张牌,然后你翻面并获得等量护甲。②当你受到伤害后,若你的武将牌背面朝上,你选择一项:1.翻面;2.获得1点护甲。③当你翻面后,若你的武将牌正面朝上,你摸X张牌(X为你的护甲数)。', - sbjiewei:'解围', - sbjiewei_info:'出牌阶段限一次。你可以失去1点护甲并选择一名其他角色。你观看其手牌并获得其中一张。', - sb_xiahoushi:'谋夏侯氏', - sbqiaoshi:'樵拾', - sbqiaoshi_info:'每回合限一次。当你受到其他角色造成的伤害后,其可以令你回复等同于此次伤害值的体力,然后其摸两张牌。', - sbyanyu:'燕语', - sbyanyu_info:'①出牌阶段限两次。你可以弃置一张【杀】,然后摸一张牌。②出牌阶段结束时,你可以令一名其他角色摸3X张牌(X为你于此阶段发动〖燕语①〗的次数)。', - sb_zhangjiao:'谋张角', - sbleiji:'雷击', - sbleiji_info:'出牌阶段,你可以选择一名其他角色并弃4枚“道兵”,对其造成1点雷电伤害。', - sbguidao:'鬼道', - sbguidao_info:'①游戏开始时/一名角色受到属性伤害后,你获得4/2枚“道兵”。②当你受到伤害时,你可以弃2枚“道兵”并防止此伤害。然后若当前回合角色不为你,〖鬼道①〗于你下回合开始前无效。③“道兵”上限为8。', - sbhuangtian:'黄天', - sbhuangtian_info:'主公技,锁定技。①回合开始时,若本回合为你的第一个回合且游戏轮数为1,且游戏内没有【太平要术】,你装备【太平要术】。②其他群势力角色造成伤害后,若你拥有〖鬼道〗,你获得2枚“道兵”(每轮你至多以此法获得4枚“道兵”)。', - sb_caocao:'谋曹操', - sbjianxiong:'奸雄', - sbjianxiong_info:'①游戏开始时,你可获得至多2枚“治世”标记。②当你受到伤害后,你可获得伤害牌,摸1-X张牌(X为“治世”数),然后你可弃1枚“治世”。', - sbqingzheng:'清正', - sbqingzheng_info:'出牌阶段开始时,你可以弃置3-X种花色的所有手牌(X为“治世”数),并观看一名有手牌的其他角色的手牌,你弃置其中一种花色的所有牌。若其被弃置的牌数小于你以此法弃置的牌数,你对其造成1点伤害。然后若X小于2且你拥有技能〖奸雄〗,你可以获得1枚“治世”。', - sbhujia:'护驾', - sbhujia_info:'主公技,每轮限一次。当你受到伤害时,你可以将此伤害转移给一名其他魏势力角色。', - sb_zhenji:'谋甄宓', - sbluoshen:'洛神', - sbluoshen_info:'准备阶段,你可以选择一名角色。从其开始按逆时针方向的X名其他角色依次执行(X为角色数的一半,向上取整):展示一张手牌,若此牌为黑色,你获得之且此牌不计入本回合手牌上限;若此牌为红色,其弃置之。', - sb_ganning:'谋甘宁', - sbqixi:'奇袭', - sbqixi_info:'出牌阶段限一次。若你有手牌,你可以令一名其他角色猜测你手牌中最多的花色。若其猜对,你展示所有手牌;若其猜错,你可令其从其未选择过的花色中再次猜测,重复此流程。然后你弃置其区域内的X张牌(X为其于本次〖奇袭〗中猜错的次数)。', - sbfenwei:'奋威', - sbfenwei_info:'限定技。①出牌阶段,你可以将至多三张牌分别置于等量名角色的武将牌上,称为“威”,然后你摸等量牌。②当一名角色成为锦囊牌的目标时,若其有“威”,你须选择:1.令其获得其“威”;2.令其移去“威”,并取消此目标。', - sb_machao:'谋马超', - sbtieji:'铁骑', - sbtieji_info:'当你使用【杀】指定其他角色为目标后,你可以令目标角色不能响应此【杀】,且其所有非锁定技失效直到回合结束。然后你与其进行谋弈。若你赢,且你选择的选项为:“直取敌营”,则你获得其一张牌;“扰阵疲敌”,你摸两张牌。', - sb_xuhuang:'谋徐晃', - sbduanliang:'断粮', - sbduanliang_info:'出牌阶段限一次。你可以与一名其他角色进行谋弈。若你赢,且你选择的选项为:“围城断粮”,若其判定区没有【兵粮寸断】,你将牌堆顶牌当【兵粮寸断】对其使用,否则你获得其一张牌;“擂鼓进军”,你视为对其使用一张【决斗】。', - sbshipo:'势迫', - sbshipo_info:'结束阶段,你可以令一名体力少于你的角色或所有判定区有【兵粮寸断】的其他角色选择一项:1.交给你一张手牌;2.受到1点伤害。所有目标角色选择完成后,你可以将任意张你以此法得到的牌交给一名其他角色。', - sb_zhangfei:'谋张飞', - sbpaoxiao:'咆哮', - sbpaoxiao_info:'锁定技。①你使用【杀】无次数限制。②若你的装备区内有武器牌,则你使用【杀】无距离限制。③当你于出牌阶段内使用第二张及以后【杀】时,你获得如下效果:{此【杀】不可被响应且伤害值基数+1;此【杀】指定目标后,目标角色的非锁定技于本回合内失效;此【杀】造成伤害后,若目标角色存活,则你失去1点体力并随机弃置一张手牌。}', - sbxieji:'协击', - sbxieji_info:'准备阶段开始时,你可以和一名其他角色进行协力。其的下个结束阶段开始时,若你与其协力成功,则你可以选择至多三名其他角色。你对这些角色视为使用一张【杀】,且当此【杀】因执行牌面效果造成伤害后,你摸X张牌(X为伤害值)。', - sb_zhaoyun:'谋赵云', - sblongdan:'龙胆', - sblongdan_info:'蓄力技(1/3)。①你可以消耗1点蓄力值,将【杀】当做【闪】或将【闪】当做【杀】使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。', - sbjizhu:'积著', - sbjizhu_info:'准备阶段开始时,你可以和一名其他角色进行协力。其的下个结束阶段开始时,若你与其协力成功,则你修改〖龙胆〗直到你的下个结束阶段开始。', - sblongdan_shabi:'龙胆', - sblongdan_shabi_info:'蓄力技(1/3)。①你可以消耗1点蓄力值,将一张基本牌当做任意基本牌使用或打出,然后摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。', - sb_liubei:'谋刘备', - sbrende:'仁德', - sbrende_info:'①出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为8)。②每回合限一次。你可以移去2枚“仁望”,视为使用或打出一张基本牌。③出牌阶段开始时,你获得2枚“仁望”。', - sbzhangwu:'章武', - sbzhangwu_info:'限定技。出牌阶段,你可以令所有于本局游戏成为过〖仁德①〗目标的其他角色依次交给你X张牌,然后你回复3点体力并失去〖仁德〗(X为游戏轮数-1,且至多为3)。', - sbjijiang:'激将', - sbjijiang_info:'主公技。出牌阶段结束时,你可以选择一名体力值不小于你的其他蜀势力角色A和一名在A攻击范围内的角色B。A选择一项:1.视为对B使用一张【杀】;2.下一个出牌阶段开始前,跳过此阶段。', - sb_jiangwei:'谋姜维', - sbtiaoxin:'挑衅', - sbtiaoxin_info:'蓄力技(4/4)。①出牌阶段限一次。你可以选择至多X名角色(X为你的蓄力值),令这些角色选择一项:1.对你使用一张【杀】(无距离限制);2.交给你一张牌。然后你消耗等同于你选择的目标数的蓄力值。②当你于弃牌阶段弃置牌后,你获得等量蓄力值。', - sbzhiji:'志继', - sbzhiji_info:'觉醒技。准备阶段,若你因〖挑衅①〗消耗过至少4点蓄力值,你减1点体力上限,令至少一名角色获得“北伐”标记并获得如下效果直到你的下回合开始:其使用牌只能指定你或其为目标。', - sb_fazheng:'谋法正', - sbxuanhuo:'眩惑', - sbxuanhuo_info:'①出牌阶段限一次。你可以将一张牌交给一名没有“眩”标记的其他角色,然后令其获得“眩”标记。②当有“眩”的其他角色于摸牌阶段外得到牌后,若你以此法于其本次获得“眩”的期间内得到其的牌数小于5,你随机获得其一张手牌。', - sbenyuan:'恩怨', - sbenyuan_info:'锁定技。准备阶段,若场上存在有“眩”的角色,你移去该角色的“眩”,且你于其本次获得“眩”的期间内得到其的牌数:不小于3,你交给其三张牌;小于3,其失去1点体力,你回复1点体力。', - sb_chengong:'谋陈宫', - sbmingce:'明策', - sbmingce_info:'①出牌阶段限一次。你可以将一张牌交给一名其他角色,其选择一项:1.失去1点体力,令你摸两张牌并获得1枚“策”;2.摸一张牌。②出牌阶段开始时,你可以移去所有“策”并对一名其他角色造成等量伤害。', - sbzhichi:'智迟', - sbzhichi_info:'锁定技。当你受到伤害后,防止你本回合受到的伤害。', - sb_yuanshao:'谋袁绍', - sbluanji:'乱击', - sbluanji_info:'①出牌阶段限一次。你可以将两张手牌当【万箭齐发】使用。②每回合限三次,当其他角色因响应你使用的【万箭齐发】而打出【闪】时,你摸一张牌。', - sbxueyi:'血裔', - sbxueyi_info:'主公技,锁定技。①你的手牌上限+2X(X为场上其他群势力角色数)。②每回合限两次,当你使用牌指定其他群势力角色为目标后,你摸一张牌。', - sb_diaochan:'谋貂蝉', - sblijian:'离间', - sblijian_info:'出牌阶段限一次。你可以选择至少两名其他角色并弃置X张牌(X为你选择的角色数-1)。然后每名你选择的角色依次视为对这些角色中与其逆时针座次最近的另一名角色使用一张【决斗】。', - sbbiyue:'闭月', - sbbiyue_info:'锁定技。结束阶段,你摸Y张牌(Y为本回合包括已死亡角色在内受到过伤害的角色数+1且至多为4)。', - sb_pangtong:'谋庞统', - sblianhuan:'连环', - sblianhuan_info:'①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。③当你使用【铁索连环】时,你可以失去1点体力,然后当此牌指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。', - sblianhuan_lv2:'连环·改', - sblianhuan_lv2_info:'①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。③当你使用【铁索连环】时,你可以额外指定任意名角色为目标。④当你使用【铁索连环】指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。', - sbniepan:'涅槃', - sbniepan_info:'限定技。当你处于濒死状态时,你可以弃置区域里的所有牌,摸两张牌,将体力回复至2点,复原武将牌,然后修改〖连环〗。', - sb_sunce:'谋孙策', - sbjiang:'激昂', - sbjiang_info:'①当你使用【决斗】或红色【杀】指定目标后,或当你成为【决斗】或红色【杀】的目标后,你摸一张牌。②当你使用【决斗】时,你可以额外指定一名目标,然后你失去1点体力。③出牌阶段限一次。你可以将所有手牌当【决斗】使用。', - sbhunzi:'魂姿', - sbhunzi_info:'觉醒技。当你脱离濒死状态后,你减1点体力上限,获得1点护甲,摸三张牌。然后你获得〖英姿〗和〖英魂〗。', - sbzhiba:'制霸', - sbzhiba_info:'主公技,限定技。当你进入濒死状态时,你可以回复X-1点体力并修改〖激昂③〗为“出牌阶段限X次”(X为场上其他吴势力角色数+1)。然后其他吴势力角色依次受到1点无来源伤害,且当有角色因此死亡后,你摸三张牌。', - sb_daqiao:'谋大乔', - sbguose:'国色', - sbguose_info:'出牌阶段限两次,你可以将一张♦牌当【乐不思蜀】使用或弃置场上一张【乐不思蜀】,然后你摸一张牌。', - sbguose_info_identity:'出牌阶段限四次,你可以将一张♦牌当【乐不思蜀】使用或弃置场上一张【乐不思蜀】,然后你摸一张牌。', - sbliuli:'流离', - sbliuli_info:'当你成为【杀】的目标时,你可以弃置一张牌并选择你攻击范围内的一名不为此【杀】使用者的角色,将此【杀】转移给该角色。若你以此法弃置了♥牌,则你可以令一名不为此【杀】使用者的其他角色获得“流离”标记,且移去场上所有其他的“流离”(每回合限一次)。有“流离”的角色回合开始时,其移去其“流离”并执行一个额外的出牌阶段。', - sb_liubiao:'谋刘表', - sbzishou:'自守', - sbzishou_info:'锁定技。其他角色的结束阶段,若其与你于本局游戏内均未对对方造成过伤害,其须交给你一张牌。', - sbzongshi:'宗室', - sbzongshi_info:'锁定技。每名角色限一次。当你受到伤害后,你令伤害来源弃置所有手牌。', - sb_zhurong:'谋祝融', - sblieren:'烈刃', - sblieren_info:'当你使用【杀】指定唯一目标后,你可以摸一张牌,然后与其拼点。若你赢,此【杀】结算结束后,你可以对另一名其他角色造成1点伤害。', - sbjuxiang:'巨象', - sbjuxiang_info:'锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】结算结束后,你获得此牌对应的所有实体牌。③结束阶段,若你未于本回合使用过【南蛮入侵】,你可以将一张游戏外的随机【南蛮入侵】(共2张)交给一名角色。', - sb_menghuo:'谋孟获', - sbhuoshou:'祸首', - sbhuoshou_info:'锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】指定第一个目标后,你代替其成为此牌的伤害来源。③出牌阶段开始时,你随机获得弃牌堆中的一张【南蛮入侵】。④出牌阶段,若你于此阶段使用过【南蛮入侵】,你不能使用【南蛮入侵】。', - sbzaiqi:'再起', - 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_identity:'①出牌阶段限三次,你可以交给一名没有“天香”标记的其他角色一张红色牌,然后令其获得此牌花色的“天香”标记。②当你受到伤害时,你可以移去一名角色的“天香”标记,若此“天香”标记为:红桃,你防止此伤害,其受到伤害来源对其造成的1点伤害(若没有伤害来源则改为无来源伤害);方片,其交给你两张牌。③准备阶段,你移去场上所有的“天香”标记,然后摸等量的牌。', - sbtianxiang_info:'①出牌阶段限三次,你可以交给一名没有“天香”标记的其他角色一张红色牌,然后令其获得此牌花色的“天香”标记。②当你受到伤害时,你可以移去一名角色的“天香”标记,若此“天香”标记为:红桃,你防止此伤害,其受到伤害来源对其造成的1点伤害(若没有伤害来源则改为无来源伤害);方片,其交给你两张牌。③准备阶段,你移去场上所有的“天香”标记,然后摸X张牌(X为移去的“天香”标记数+2)。', - sb_sp_zhugeliang:'谋诸葛亮', - sb_sp_zhugeliang_prefix:'谋', - sbhuoji:'火计', - sbhuoji_info:'使命技。①使命:出牌阶段限一次。你可以对一名其他角色造成1点火焰伤害,然后你对所有与其势力相同的不为其的其他角色各造成1点火焰伤害。②成功:准备阶段,若你本局游戏已造成的火焰伤害不小于本局游戏总角色数,则你失去〖火计〗和〖看破〗,然后获得〖观星〗和〖空城〗。③失败:使命成功前进入濒死状态。', - sbkanpo:'看破', - sbkanpo_info:'①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录4个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。', - sbkanpo_info_doudizhu:'①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录2个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。', - sbkanpo_info_versus_two:'①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录2个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。', - sbguanxing:'观星', - sbguanxing_info:'①准备阶段,你将所有“星”置入弃牌堆,将牌堆顶的X张牌置于你的武将牌上,称为“星”(X为7-此前发动〖观星①〗次数的三倍,且X至少为0)。然后你可以将任意张“星”置于牌堆顶。②结束阶段,若你未于本回合的准备阶段将“星”置于过牌堆顶,你可以将任意张“星”置于牌堆顶。③你可以如手牌般使用或打出“星”。', - sbkongcheng:'空城', - sbkongcheng_info:'锁定技。当你受到伤害时,若你拥有技能〖观星〗,且若你:有“星”,你判定,若结果点数不大于你的“星”数,此伤害-1;没有“星”,此伤害+1。', - sb_huangyueying:'谋黄月英', - sb_huangyueying_prefix:'谋', - sbqicai:'奇才', - sbqicai_backup:'奇才', - sbqicai_info:'①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张装备牌置于一名其他角色的对应装备栏,然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。', - sbqicai_info_doudizhu:'①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张装备牌置于一名其他角色的对应装备栏(每种牌名的装备牌每局游戏限选择一次),然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。', - sbjizhi:'集智', - sbjizhi_info:'锁定技,当你使用一张普通锦囊牌时,你摸一张牌,且此牌本回合不计入你的手牌上限。', - sb_guanyu:'谋关羽', - sb_guanyu_prefix:'谋', - sbwusheng:'武圣', - sbwusheng_wusheng_backup:'武圣', - sbwusheng_info:'你可以将一张手牌当作任意【杀】使用或打出。出牌阶段开始时,你可以选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸一张牌,对其使用三张【杀】后不能对其使用【杀】。', - sbwusheng_info_identity:'你可以将一张手牌当作任意【杀】使用或打出。出牌阶段开始时,你可以选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸两张牌,对其使用三张【杀】后不能对其使用【杀】。', - sbyijue:'义绝', - sbyijue_info:'锁定技,每名角色每局游戏限一次,一名其他角色受到你对其造成的大于等于其体力值的伤害时,你防止此伤害,且本回合你使用牌指定其为目标时,此牌对其无效。', - sb_caopi:'谋曹丕', - sb_caopi_prefix:'谋', - sbxingshang:'行殇', - sbxingshang_info:'①当一名角色受到伤害后(每回合限一次)或死亡时,你获得2个“颂”标记(你至多拥有9个“颂”标记)。②出牌阶段限两次,你可以:1.移去2个“颂”标记,令一名角色复原武将牌;2.移去2个“颂”标记,令一名角色摸X张牌(X为场上阵亡角色数,且X至少为2,至多为5);3.移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限,回复1点体力,随机恢复一个已废除的装备栏;4.移去5个“颂”标记,获得一名阵亡角色武将牌上的所有技能,然后你失去〖行殇〗〖放逐〗〖颂威〗。', - sbfangzhu:'放逐', - sbfangzhu_info:'出牌阶段限一次,你可以:1.移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束;2.移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束;3.移去2个“颂”标记,令一名其他角色不能响应除其以外的角色使用的牌直到其回合结束;4.移去3个“颂”标记,令一名其他角色将武将牌翻面;5.移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束;6.移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束。', - sbsongwei:'颂威', - sbsongwei_info:'主公技。①出牌阶段开始时,你获得Y个“颂”标记(Y为场上其他魏势力角色数的两倍)。②每局游戏限一次,出牌阶段,你可以令一名其他魏势力角色失去所有武将牌的技能。', - sb_xunyu:'谋荀彧', - sb_xunyu_prefix:'谋', - sbquhu:'驱虎', - sbquhu_info:'出牌阶段限一次。你可以选择两名有牌的其他角色,你与这些角色同时将任意张牌扣置于武将牌上。若你以此法扣置的牌唯一最少,则扣置牌最多的其他角色获得你扣置的牌,且这些角色获得各自扣置的牌;否则这两名角色中扣置牌较多的角色对较少的角色造成1点伤害,获得你扣置的牌,然后这些角色将各自扣置的牌置入弃牌堆(若这两名角色扣置的牌数相同,视为与你逆时针最近座次的角色扣置牌较多)。', - sbjieming:'节命', - sbjieming_info:'当你受到伤害后,你可以令一名角色摸三张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于X,你失去1点体力(X为你已损失的体力值,至少为1)。', - sb_xiahoudun:'谋夏侯惇', - sb_xiahoudun_prefix:'谋', - sbganglie:'刚烈', - sbganglie_info:'出牌阶段,你可以选择一名本局游戏对你造成过伤害且未以此法选择过的角色,你对其造成2点伤害。', - sbqingjian:'清俭', - sbqingjian_info:'①当有一张牌不因使用而进入弃牌堆后,若你的“清俭”数小于X,你将此牌置于你的武将牌上,称为“清俭”(X为你的体力值-1,且至少为1)。②出牌阶段结束时,你将所有“清俭”分配给任意角色。', - sb_gaoshun:'谋高顺', - sb_gaoshun_prefix:'谋', - sbxianzhen:'陷阵', - sbxianzhen_info:'出牌阶段限一次。你可以选择一名其他角色,你于本阶段获得如下效果:⒈你对其使用牌无距离限制;⒉当你使用【杀】指定其为目标后,你可以与其拼点:若你赢,此【杀】无视防具且不计入次数,且若你本回合未以此法造成过伤害,你对其造成1点伤害;若其拼点牌为【杀】,则你获得之;若其拼点牌为其最后的手牌,则此【杀】对其造成伤害时,此伤害+1。', - sbjinjiu:'禁酒', - sbjinjiu_info:'锁定技。①你的【酒】均视为【杀】。②当你受到酒【杀】的伤害时,你令此伤害减至1。③其他角色不能于你的回合内使用【酒】。④当一名其他角色的拼点牌亮出后,若你为发起者或参与者且此牌为【酒】,则此牌的点数视为A。', + translate: { + sb_zhanghe_prefix: "谋", + sb_yujin_prefix: "谋", + sb_huaxiong_prefix: "谋", + liucheng_prefix: "谋", + sp_yangwan_prefix: "谋", + sb_huangzhong_prefix: "谋", + sb_lvmeng_prefix: "谋", + sb_sunshangxiang_prefix: "谋", + sb_sunquan_prefix: "谋", + sb_huanggai_prefix: "谋", + sb_zhouyu_prefix: "谋", + sb_caoren_prefix: "谋", + sb_xiahoushi_prefix: "谋", + sb_zhangjiao_prefix: "谋", + sb_caocao_prefix: "谋", + sb_zhenji_prefix: "谋", + sb_ganning_prefix: "谋", + sb_machao_prefix: "谋", + sb_xuhuang_prefix: "谋", + sb_zhangfei_prefix: "谋", + sb_zhaoyun_prefix: "谋", + sb_liubei_prefix: "谋", + sb_jiangwei_prefix: "谋", + sb_fazheng_prefix: "谋", + sb_chengong_prefix: "谋", + sb_diaochan_prefix: "谋", + sb_yuanshao_prefix: "谋", + sb_pangtong_prefix: "谋", + sb_sunce_prefix: "谋", + sb_daqiao_prefix: "谋", + sb_liubiao_prefix: "谋", + sb_zhurong_prefix: "谋", + sb_menghuo_prefix: "谋", + sp_yangwan: "谋杨婉", + spmingxuan: "瞑昡", + spmingxuan_info: + "锁定技。出牌阶段开始时,你须选择至多X张花色各不相同的手牌(X为未选择过选项一的角色),将这些牌随机交给这些角色中的等量角色。然后这些角色依次选择一项:⒈对你使用一张【杀】。⒉交给你一张牌,然后你摸一张牌。", + spxianchou: "陷仇", + spxianchou_info: + "当你受到有来源的伤害后,你可选择一名不为伤害来源的其他角色。该角色可以弃置一张牌,然后视为对伤害来源使用一张【杀】(无距离限制)。若其因此【杀】造成了伤害,则其摸一张牌,你回复1点体力。", + liucheng: "谋刘赪", + splveying: "掠影", + splveying_info: + "锁定技。①每回合限两次,当你使用【杀】指定目标后,你获得一个“椎”。②当你使用的【杀】结算结束后,若你的“椎”数大于1,则你弃置两个“椎”并摸一张牌,然后可以视为使用一张【过河拆桥】。", + spyingwu: "莺舞", + spyingwu_info: + "若你拥有〖掠影〗,则:①每回合限两次,当你使用非伤害类普通锦囊牌指定目标后,你获得一个“椎”。②当你使用的非伤害类普通锦囊牌结算结束后,若你的“椎”数大于1,则你弃置两个“椎”并摸一张牌,然后可以视为使用一张【杀】。", + sb_huangzhong: "谋黄忠", + sbliegong: "烈弓", + sbliegong_info: + "①若你的装备区内没有武器牌,则你手牌区内所有【杀】的属性视为无属性。②当你使用牌时,或成为其他角色使用牌的目标后,你记录此牌的花色。③当你使用【杀】指定唯一目标后,若你〖烈弓②〗的记录不为空,则你可亮出牌堆顶的X张牌(X为你〖烈弓②〗记录过的花色数-1),令此【杀】的伤害值基数+Y(Y为亮出牌中被〖烈弓②〗记录过花色的牌的数量),且目标角色不能使用〖烈弓②〗记录过花色的牌响应此【杀】。此【杀】使用结算结束后,你清除〖烈弓②〗的记录。", + sb_huaxiong: "谋华雄", + sbyangwei: "扬威", + sbyangwei_info: + "出牌阶段,你可以摸两张牌,令此技能于你的下下个结束阶段前失效,且你获得如下效果直到回合结束:使用【杀】无距离限制,次数上限+1且无视防具。", + sb_yujin: "谋于禁", + sbxiayuan: "狭援", + sbxiayuan_info: + "每轮限一次。其他角色受到伤害后,若其因此伤害触发过护甲效果且其没有护甲,则你可弃置两张手牌,令其获得X点护甲(X为其因此伤害触发护甲效果而失去的护甲数量)。", + sbjieyue: "节钺", + sbjieyue_info: "结束阶段,你可以令一名其他角色获得1点护甲。然后其可以交给你一张牌。", + sb_lvmeng: "谋吕蒙", + sbkeji: "克己", + sbkeji_info: + "①出牌阶段各限一次。你可以选择一项:1.弃置一张手牌,然后获得1点护甲;2.失去1点体力,然后获得2点护甲。②你的手牌上限+X(X为你的护甲数)。③若你不为正在结算濒死流程的角色,你不能使用【桃】。", + sbdujiang: "渡江", + sbdujiang_info: + "觉醒技。准备阶段,若你的护甲数不少于3,你获得〖夺荆〗,修改〖克己①〗为“出牌阶段限一次”。", + sbduojing: "夺荆", + sbduojing_info: + "当你使用【杀】指定目标时,你可以失去1点护甲。然后令此【杀】无视防具,你获得目标角色一张牌,本回合使用【杀】的次数上限+1。", + sb_sunshangxiang: "谋孙尚香", + sbjieyin: "结姻", + sbjieyin_info: + "使命技。①游戏开始时,你令一名其他角色获得1枚“助”。②出牌阶段开始时,有“助”的角色选择一项:1.交给你X张手牌(X=min(2,其手牌数)且至少为1),然后获得1点护甲;2.令你将“助”移动给另一名其他角色,或移去其“助”(若其此前获得过“助”,则只能移去)。③失败:当一名角色死亡后,若其于死亡时有“助”,或当你因〖结姻②〗移去“助”后,你将势力改为吴,回复1点体力,获得所有“妆”并减1点体力上限。", + sbliangzhu: "良助", + sbliangzhu_info: + "蜀势力技。出牌阶段限一次,你可以将一名其他角色装备区里的一张牌置于武将牌上,称为“妆”,然后有“助”的角色须选择回复1点体力或摸两张牌。", + sbxiaoji: "枭姬", + sbxiaoji_info: "吴势力技。当你失去装备区里的一张牌后,你摸两张牌,然后可以弃置场上的一张牌。", + sb_sunquan: "谋孙权", + sbzhiheng: "制衡", + sbzhiheng_info: + "出牌阶段限一次。你可以弃置任意张牌并摸等量的牌,若你以此法弃置的牌包括你所有手牌,则你多摸X张牌(X为你的“业”数+1),并弃1枚“业”。", + sbtongye: "统业", + sbtongye_info: + "锁定技。结束阶段,你猜测场上装备牌数与你下一个准备阶段的场上装备牌数是否相等,并获得以下效果:你下一个准备阶段,若你猜对且“业”数小于2,你获得1枚“业”;若你猜错,你弃1枚“业”。", + sbjiuyuan: "救援", + sbjiuyuan_info: + "主公技,锁定技。①其他吴势力角色使用【桃】时,你摸一张牌。②其他吴势力角色对你使用的【桃】的回复量+1。", + sb_huanggai: "谋黄盖", + sbkurou: "苦肉", + sbkurou_info: + "①出牌阶段开始时,你可以交给其他角色一张牌,若此牌于对方手牌区内为【桃】或【酒】,你失去2点体力,否则你失去1点体力。②当你失去1点体力后,你获得2点护甲。", + sbzhaxiang: "诈降", + sbzhaxiang_info: + "锁定技。①摸牌阶段,你多摸X张牌。②你每回合使用的前X张牌无距离与次数限制且不能被响应(X为你已损失的体力值)。", + sb_zhouyu: "谋周瑜", + sbyingzi: "英姿", + sbyingzi_info: + "锁定技。摸牌阶段,你多摸X张牌,且令你本回合手牌上限+X(X为以下条件中你满足的项数:手牌数不小于2、体力值不小于2、装备区里的牌数不小于1)。", + sbfanjian: "反间", + sbfanjian_info: + "出牌阶段,你可以声明一个花色并选择一张牌和一名其他角色(每种花色的牌每回合限一次)。其须选择一项:1.猜测此牌花色与你所声明花色是否相同;2.翻面。然后其正面向上获得此牌。若其选择猜测且猜测错误,其失去1点体力,否则其令你〖反间〗于本回合失效。", + sb_caoren: "谋曹仁", + sbjushou: "据守", + sbjushou_info: + "①出牌阶段限一次。若你的武将牌正面朝上,你可以弃置至多两张牌,然后你翻面并获得等量护甲。②当你受到伤害后,若你的武将牌背面朝上,你选择一项:1.翻面;2.获得1点护甲。③当你翻面后,若你的武将牌正面朝上,你摸X张牌(X为你的护甲数)。", + sbjiewei: "解围", + sbjiewei_info: + "出牌阶段限一次。你可以失去1点护甲并选择一名其他角色。你观看其手牌并获得其中一张。", + sb_xiahoushi: "谋夏侯氏", + sbqiaoshi: "樵拾", + sbqiaoshi_info: + "每回合限一次。当你受到其他角色造成的伤害后,其可以令你回复等同于此次伤害值的体力,然后其摸两张牌。", + sbyanyu: "燕语", + sbyanyu_info: + "①出牌阶段限两次。你可以弃置一张【杀】,然后摸一张牌。②出牌阶段结束时,你可以令一名其他角色摸3X张牌(X为你于此阶段发动〖燕语①〗的次数)。", + sb_zhangjiao: "谋张角", + sbleiji: "雷击", + sbleiji_info: "出牌阶段,你可以选择一名其他角色并弃4枚“道兵”,对其造成1点雷电伤害。", + sbguidao: "鬼道", + sbguidao_info: + "①游戏开始时/一名角色受到属性伤害后,你获得4/2枚“道兵”。②当你受到伤害时,你可以弃2枚“道兵”并防止此伤害。然后若当前回合角色不为你,〖鬼道①〗于你下回合开始前无效。③“道兵”上限为8。", + sbhuangtian: "黄天", + sbhuangtian_info: + "主公技,锁定技。①回合开始时,若本回合为你的第一个回合且游戏轮数为1,且游戏内没有【太平要术】,你装备【太平要术】。②其他群势力角色造成伤害后,若你拥有〖鬼道〗,你获得2枚“道兵”(每轮你至多以此法获得4枚“道兵”)。", + sb_caocao: "谋曹操", + sbjianxiong: "奸雄", + sbjianxiong_info: + "①游戏开始时,你可获得至多2枚“治世”标记。②当你受到伤害后,你可获得伤害牌,摸1-X张牌(X为“治世”数),然后你可弃1枚“治世”。", + sbqingzheng: "清正", + sbqingzheng_info: + "出牌阶段开始时,你可以弃置3-X种花色的所有手牌(X为“治世”数),并观看一名有手牌的其他角色的手牌,你弃置其中一种花色的所有牌。若其被弃置的牌数小于你以此法弃置的牌数,你对其造成1点伤害。然后若X小于2且你拥有技能〖奸雄〗,你可以获得1枚“治世”。", + sbhujia: "护驾", + sbhujia_info: "主公技,每轮限一次。当你受到伤害时,你可以将此伤害转移给一名其他魏势力角色。", + sb_zhenji: "谋甄宓", + sbluoshen: "洛神", + sbluoshen_info: + "准备阶段,你可以选择一名角色。从其开始按逆时针方向的X名其他角色依次执行(X为角色数的一半,向上取整):展示一张手牌,若此牌为黑色,你获得之且此牌不计入本回合手牌上限;若此牌为红色,其弃置之。", + sb_ganning: "谋甘宁", + sbqixi: "奇袭", + sbqixi_info: + "出牌阶段限一次。若你有手牌,你可以令一名其他角色猜测你手牌中最多的花色。若其猜对,你展示所有手牌;若其猜错,你可令其从其未选择过的花色中再次猜测,重复此流程。然后你弃置其区域内的X张牌(X为其于本次〖奇袭〗中猜错的次数)。", + sbfenwei: "奋威", + sbfenwei_info: + "限定技。①出牌阶段,你可以将至多三张牌分别置于等量名角色的武将牌上,称为“威”,然后你摸等量牌。②当一名角色成为锦囊牌的目标时,若其有“威”,你须选择:1.令其获得其“威”;2.令其移去“威”,并取消此目标。", + sb_machao: "谋马超", + sbtieji: "铁骑", + sbtieji_info: + "当你使用【杀】指定其他角色为目标后,你可以令目标角色不能响应此【杀】,且其所有非锁定技失效直到回合结束。然后你与其进行谋弈。若你赢,且你选择的选项为:“直取敌营”,则你获得其一张牌;“扰阵疲敌”,你摸两张牌。", + sb_xuhuang: "谋徐晃", + sbduanliang: "断粮", + sbduanliang_info: + "出牌阶段限一次。你可以与一名其他角色进行谋弈。若你赢,且你选择的选项为:“围城断粮”,若其判定区没有【兵粮寸断】,你将牌堆顶牌当【兵粮寸断】对其使用,否则你获得其一张牌;“擂鼓进军”,你视为对其使用一张【决斗】。", + sbshipo: "势迫", + sbshipo_info: + "结束阶段,你可以令一名体力少于你的角色或所有判定区有【兵粮寸断】的其他角色选择一项:1.交给你一张手牌;2.受到1点伤害。所有目标角色选择完成后,你可以将任意张你以此法得到的牌交给一名其他角色。", + sb_zhangfei: "谋张飞", + sbpaoxiao: "咆哮", + sbpaoxiao_info: + "锁定技。①你使用【杀】无次数限制。②若你的装备区内有武器牌,则你使用【杀】无距离限制。③当你于出牌阶段内使用第二张及以后【杀】时,你获得如下效果:{此【杀】不可被响应且伤害值基数+1;此【杀】指定目标后,目标角色的非锁定技于本回合内失效;此【杀】造成伤害后,若目标角色存活,则你失去1点体力并随机弃置一张手牌。}", + sbxieji: "协击", + sbxieji_info: + "准备阶段开始时,你可以和一名其他角色进行协力。其的下个结束阶段开始时,若你与其协力成功,则你可以选择至多三名其他角色。你对这些角色视为使用一张【杀】,且当此【杀】因执行牌面效果造成伤害后,你摸X张牌(X为伤害值)。", + sb_zhaoyun: "谋赵云", + sblongdan: "龙胆", + sblongdan_info: + "蓄力技(1/3)。①你可以消耗1点蓄力值,将【杀】当做【闪】或将【闪】当做【杀】使用或打出,然后若你以此法使用牌,你摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。", + sbjizhu: "积著", + sbjizhu_info: + "准备阶段开始时,你可以和一名其他角色进行协力。其的下个结束阶段开始时,若你与其协力成功,则你修改〖龙胆〗直到你的下个结束阶段开始。", + sblongdan_shabi: "龙胆", + sblongdan_shabi_info: + "蓄力技(1/3)。①你可以消耗1点蓄力值,将一张基本牌当做任意基本牌使用或打出,然后摸一张牌。②一名角色的回合结束时,你获得1点蓄力值。", + sb_liubei: "谋刘备", + sbrende: "仁德", + sbrende_info: + "①出牌阶段每名角色限一次。你可以将任意张牌交给一名其他角色,然后你获得等量“仁望”标记(至多为8)。②每回合限一次。你可以移去2枚“仁望”,视为使用或打出一张基本牌。③出牌阶段开始时,你获得2枚“仁望”。", + sbzhangwu: "章武", + sbzhangwu_info: + "限定技。出牌阶段,你可以令所有于本局游戏成为过〖仁德①〗目标的其他角色依次交给你X张牌,然后你回复3点体力并失去〖仁德〗(X为游戏轮数-1,且至多为3)。", + sbjijiang: "激将", + sbjijiang_info: + "主公技。出牌阶段结束时,你可以选择一名体力值不小于你的其他蜀势力角色A和一名在A攻击范围内的角色B。A选择一项:1.视为对B使用一张【杀】;2.下一个出牌阶段开始前,跳过此阶段。", + sb_jiangwei: "谋姜维", + sbtiaoxin: "挑衅", + sbtiaoxin_info: + "蓄力技(4/4)。①出牌阶段限一次。你可以选择至多X名角色(X为你的蓄力值),令这些角色选择一项:1.对你使用一张【杀】(无距离限制);2.交给你一张牌。然后你消耗等同于你选择的目标数的蓄力值。②当你于弃牌阶段弃置牌后,你获得等量蓄力值。", + sbzhiji: "志继", + sbzhiji_info: + "觉醒技。准备阶段,若你因〖挑衅①〗消耗过至少4点蓄力值,你减1点体力上限,令至少一名角色获得“北伐”标记并获得如下效果直到你的下回合开始:其使用牌只能指定你或其为目标。", + sb_fazheng: "谋法正", + sbxuanhuo: "眩惑", + sbxuanhuo_info: + "①出牌阶段限一次。你可以将一张牌交给一名没有“眩”标记的其他角色,然后令其获得“眩”标记。②当有“眩”的其他角色于摸牌阶段外得到牌后,若你以此法于其本次获得“眩”的期间内得到其的牌数小于5,你随机获得其一张手牌。", + sbenyuan: "恩怨", + sbenyuan_info: + "锁定技。准备阶段,若场上存在有“眩”的角色,你移去该角色的“眩”,且你于其本次获得“眩”的期间内得到其的牌数:不小于3,你交给其三张牌;小于3,其失去1点体力,你回复1点体力。", + sb_chengong: "谋陈宫", + sbmingce: "明策", + sbmingce_info: + "①出牌阶段限一次。你可以将一张牌交给一名其他角色,其选择一项:1.失去1点体力,令你摸两张牌并获得1枚“策”;2.摸一张牌。②出牌阶段开始时,你可以移去所有“策”并对一名其他角色造成等量伤害。", + sbzhichi: "智迟", + sbzhichi_info: "锁定技。当你受到伤害后,防止你本回合受到的伤害。", + sb_yuanshao: "谋袁绍", + sbluanji: "乱击", + sbluanji_info: + "①出牌阶段限一次。你可以将两张手牌当【万箭齐发】使用。②每回合限三次,当其他角色因响应你使用的【万箭齐发】而打出【闪】时,你摸一张牌。", + sbxueyi: "血裔", + sbxueyi_info: + "主公技,锁定技。①你的手牌上限+2X(X为场上其他群势力角色数)。②每回合限两次,当你使用牌指定其他群势力角色为目标后,你摸一张牌。", + sb_diaochan: "谋貂蝉", + sblijian: "离间", + sblijian_info: + "出牌阶段限一次。你可以选择至少两名其他角色并弃置X张牌(X为你选择的角色数-1)。然后每名你选择的角色依次视为对这些角色中与其逆时针座次最近的另一名角色使用一张【决斗】。", + sbbiyue: "闭月", + sbbiyue_info: + "锁定技。结束阶段,你摸Y张牌(Y为本回合包括已死亡角色在内受到过伤害的角色数+1且至多为4)。", + sb_pangtong: "谋庞统", + sblianhuan: "连环", + sblianhuan_info: + "①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。③当你使用【铁索连环】时,你可以失去1点体力,然后当此牌指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。", + sblianhuan_lv2: "连环·改", + sblianhuan_lv2_info: + "①出牌阶段,你可以重铸一张♣手牌。②出牌阶段限一次。你可以将一张♣手牌当【铁索连环】使用。③当你使用【铁索连环】时,你可以额外指定任意名角色为目标。④当你使用【铁索连环】指定第一个目标后,你随机弃置每名不处于连环状态的目标角色一张手牌。", + sbniepan: "涅槃", + sbniepan_info: + "限定技。当你处于濒死状态时,你可以弃置区域里的所有牌,摸两张牌,将体力回复至2点,复原武将牌,然后修改〖连环〗。", + sb_sunce: "谋孙策", + sbjiang: "激昂", + sbjiang_info: + "①当你使用【决斗】或红色【杀】指定目标后,或当你成为【决斗】或红色【杀】的目标后,你摸一张牌。②当你使用【决斗】时,你可以额外指定一名目标,然后你失去1点体力。③出牌阶段限一次。你可以将所有手牌当【决斗】使用。", + sbhunzi: "魂姿", + sbhunzi_info: + "觉醒技。当你脱离濒死状态后,你减1点体力上限,获得1点护甲,摸三张牌。然后你获得〖英姿〗和〖英魂〗。", + sbzhiba: "制霸", + sbzhiba_info: + "主公技,限定技。当你进入濒死状态时,你可以回复X-1点体力并修改〖激昂③〗为“出牌阶段限X次”(X为场上其他吴势力角色数+1)。然后其他吴势力角色依次受到1点无来源伤害,且当有角色因此死亡后,你摸三张牌。", + sb_daqiao: "谋大乔", + sbguose: "国色", + sbguose_info: + "出牌阶段限两次,你可以将一张♦牌当【乐不思蜀】使用或弃置场上一张【乐不思蜀】,然后你摸一张牌。", + sbguose_info_identity: + "出牌阶段限四次,你可以将一张♦牌当【乐不思蜀】使用或弃置场上一张【乐不思蜀】,然后你摸一张牌。", + sbliuli: "流离", + sbliuli_info: + "当你成为【杀】的目标时,你可以弃置一张牌并选择你攻击范围内的一名不为此【杀】使用者的角色,将此【杀】转移给该角色。若你以此法弃置了♥牌,则你可以令一名不为此【杀】使用者的其他角色获得“流离”标记,且移去场上所有其他的“流离”(每回合限一次)。有“流离”的角色回合开始时,其移去其“流离”并执行一个额外的出牌阶段。", + sb_liubiao: "谋刘表", + sbzishou: "自守", + sbzishou_info: + "锁定技。其他角色的结束阶段,若其与你于本局游戏内均未对对方造成过伤害,其须交给你一张牌。", + sbzongshi: "宗室", + sbzongshi_info: "锁定技。每名角色限一次。当你受到伤害后,你令伤害来源弃置所有手牌。", + sb_zhurong: "谋祝融", + sblieren: "烈刃", + sblieren_info: + "当你使用【杀】指定唯一目标后,你可以摸一张牌,然后与其拼点。若你赢,此【杀】结算结束后,你可以对另一名其他角色造成1点伤害。", + sbjuxiang: "巨象", + sbjuxiang_info: + "锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】结算结束后,你获得此牌对应的所有实体牌。③结束阶段,若你未于本回合使用过【南蛮入侵】,你可以将一张游戏外的随机【南蛮入侵】(共2张)交给一名角色。", + sb_menghuo: "谋孟获", + sbhuoshou: "祸首", + sbhuoshou_info: + "锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】指定第一个目标后,你代替其成为此牌的伤害来源。③出牌阶段开始时,你随机获得弃牌堆中的一张【南蛮入侵】。④出牌阶段,若你于此阶段使用过【南蛮入侵】,你不能使用【南蛮入侵】。", + sbzaiqi: "再起", + 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_identity: + "①出牌阶段限三次,你可以交给一名没有“天香”标记的其他角色一张红色牌,然后令其获得此牌花色的“天香”标记。②当你受到伤害时,你可以移去一名角色的“天香”标记,若此“天香”标记为:红桃,你防止此伤害,其受到伤害来源对其造成的1点伤害(若没有伤害来源则改为无来源伤害);方片,其交给你两张牌。③准备阶段,你移去场上所有的“天香”标记,然后摸等量的牌。", + sbtianxiang_info: + "①出牌阶段限三次,你可以交给一名没有“天香”标记的其他角色一张红色牌,然后令其获得此牌花色的“天香”标记。②当你受到伤害时,你可以移去一名角色的“天香”标记,若此“天香”标记为:红桃,你防止此伤害,其受到伤害来源对其造成的1点伤害(若没有伤害来源则改为无来源伤害);方片,其交给你两张牌。③准备阶段,你移去场上所有的“天香”标记,然后摸X张牌(X为移去的“天香”标记数+2)。", + sb_sp_zhugeliang: "谋诸葛亮", + sb_sp_zhugeliang_prefix: "谋", + sbhuoji: "火计", + sbhuoji_info: + "使命技。①使命:出牌阶段限一次。你可以对一名其他角色造成1点火焰伤害,然后你对所有与其势力相同的不为其的其他角色各造成1点火焰伤害。②成功:准备阶段,若你本局游戏已造成的火焰伤害不小于本局游戏总角色数,则你失去〖火计〗和〖看破〗,然后获得〖观星〗和〖空城〗。③失败:使命成功前进入濒死状态。", + sbkanpo: "看破", + sbkanpo_info: + "①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录4个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。", + sbkanpo_info_doudizhu: + "①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录2个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。", + sbkanpo_info_versus_two: + "①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录2个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。", + sbguanxing: "观星", + sbguanxing_info: + "①准备阶段,你将所有“星”置入弃牌堆,将牌堆顶的X张牌置于你的武将牌上,称为“星”(X为7-此前发动〖观星①〗次数的三倍,且X至少为0)。然后你可以将任意张“星”置于牌堆顶。②结束阶段,若你未于本回合的准备阶段将“星”置于过牌堆顶,你可以将任意张“星”置于牌堆顶。③你可以如手牌般使用或打出“星”。", + sbkongcheng: "空城", + sbkongcheng_info: + "锁定技。当你受到伤害时,若你拥有技能〖观星〗,且若你:有“星”,你判定,若结果点数不大于你的“星”数,此伤害-1;没有“星”,此伤害+1。", + sb_huangyueying: "谋黄月英", + sb_huangyueying_prefix: "谋", + sbqicai: "奇才", + sbqicai_backup: "奇才", + sbqicai_info: + "①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张装备牌置于一名其他角色的对应装备栏,然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。", + sbqicai_info_doudizhu: + "①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张装备牌置于一名其他角色的对应装备栏(每种牌名的装备牌每局游戏限选择一次),然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。", + sbjizhi: "集智", + sbjizhi_info: "锁定技,当你使用一张普通锦囊牌时,你摸一张牌,且此牌本回合不计入你的手牌上限。", + sb_guanyu: "谋关羽", + sb_guanyu_prefix: "谋", + sbwusheng: "武圣", + sbwusheng_wusheng_backup: "武圣", + sbwusheng_info: + "你可以将一张手牌当作任意【杀】使用或打出。出牌阶段开始时,你可以选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸一张牌,对其使用三张【杀】后不能对其使用【杀】。", + sbwusheng_info_identity: + "你可以将一张手牌当作任意【杀】使用或打出。出牌阶段开始时,你可以选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸两张牌,对其使用三张【杀】后不能对其使用【杀】。", + sbyijue: "义绝", + sbyijue_info: + "锁定技,每名角色每局游戏限一次,一名其他角色受到你对其造成的大于等于其体力值的伤害时,你防止此伤害,且本回合你使用牌指定其为目标时,此牌对其无效。", + sb_caopi: "谋曹丕", + sb_caopi_prefix: "谋", + sbxingshang: "行殇", + sbxingshang_info: + "①当一名角色受到伤害后(每回合限一次)或死亡时,你获得2个“颂”标记(你至多拥有9个“颂”标记)。②出牌阶段限两次,你可以:1.移去2个“颂”标记,令一名角色复原武将牌;2.移去2个“颂”标记,令一名角色摸X张牌(X为场上阵亡角色数,且X至少为2,至多为5);3.移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限,回复1点体力,随机恢复一个已废除的装备栏;4.移去5个“颂”标记,获得一名阵亡角色武将牌上的所有技能,然后你失去〖行殇〗〖放逐〗〖颂威〗。", + sbfangzhu: "放逐", + sbfangzhu_info: + "出牌阶段限一次,你可以:1.移去1个“颂”标记,令一名其他角色于手牌中只能使用基本牌直到其回合结束;2.移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束;3.移去2个“颂”标记,令一名其他角色不能响应除其以外的角色使用的牌直到其回合结束;4.移去3个“颂”标记,令一名其他角色将武将牌翻面;5.移去3个“颂”标记,令一名其他角色于手牌中只能使用装备牌直到其回合结束;6.移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束。", + sbsongwei: "颂威", + sbsongwei_info: + "主公技。①出牌阶段开始时,你获得Y个“颂”标记(Y为场上其他魏势力角色数的两倍)。②每局游戏限一次,出牌阶段,你可以令一名其他魏势力角色失去所有武将牌的技能。", + sb_xunyu: "谋荀彧", + sb_xunyu_prefix: "谋", + sbquhu: "驱虎", + sbquhu_info: + "出牌阶段限一次。你可以选择两名有牌的其他角色,你与这些角色同时将任意张牌扣置于武将牌上。若你以此法扣置的牌唯一最少,则扣置牌最多的其他角色获得你扣置的牌,且这些角色获得各自扣置的牌;否则这两名角色中扣置牌较多的角色对较少的角色造成1点伤害,获得你扣置的牌,然后这些角色将各自扣置的牌置入弃牌堆(若这两名角色扣置的牌数相同,视为与你逆时针最近座次的角色扣置牌较多)。", + sbjieming: "节命", + sbjieming_info: + "当你受到伤害后,你可以令一名角色摸四张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于X,你失去1点体力(X为你已损失的体力值,至少为1)。", + sb_xiahoudun: "谋夏侯惇", + sb_xiahoudun_prefix: "谋", + sbganglie: "刚烈", + sbganglie_info: + "出牌阶段,你可以选择一名本局游戏对你造成过伤害且未以此法选择过的角色,你对其造成2点伤害。", + sbqingjian: "清俭", + sbqingjian_info: + "①当有一张牌不因使用而进入弃牌堆后,若你的“清俭”数小于X,你将此牌置于你的武将牌上,称为“清俭”(X为你的体力值-1,且至少为1)。②出牌阶段结束时,你将所有“清俭”分配给任意角色。", + sb_gaoshun: "谋高顺", + sb_gaoshun_prefix: "谋", + sbxianzhen: "陷阵", + sbxianzhen_info: + "出牌阶段限一次。你可以选择一名其他角色,你于本阶段获得如下效果:⒈你对其使用牌无距离限制;⒉当你使用【杀】指定其为目标后,你可以与其拼点:若你赢,此【杀】无视防具且不计入次数,且若你本回合未以此法造成过伤害,你对其造成1点伤害;若其拼点牌为【杀】,则你获得之;若其拼点牌为其最后的手牌,则此【杀】对其造成伤害时,此伤害+1。", + sbjinjiu: "禁酒", + sbjinjiu_info: + "锁定技。①你的【酒】均视为【杀】。②当你受到酒【杀】的伤害时,你令此伤害减至1。③其他角色不能于你的回合内使用【酒】。④当一名其他角色的拼点牌亮出后,若你为发起者或参与者且此牌为【酒】,则此牌的点数视为A。", - sb_zhi:'谋攻篇·知', - sb_shi:'谋攻篇·识', - sb_tong:'谋攻篇·同', - sb_yu:'谋攻篇·虞', - sb_neng:'谋攻篇·能', - sb_waitforsort:'等待分包', + sb_zhi: "谋攻篇·知", + sb_shi: "谋攻篇·识", + sb_tong: "谋攻篇·同", + sb_yu: "谋攻篇·虞", + sb_neng: "谋攻篇·能", + sb_waitforsort: "等待分包", }, }; }); diff --git a/character/shenhua.js b/character/shenhua.js index e98103a99..9df90bd42 100755 --- a/character/shenhua.js +++ b/character/shenhua.js @@ -1,2075 +1,2550 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'shenhua', - connect:true, - characterSort:{ - shenhua:{ - shenhua_feng:["sp_zhangjiao","re_yuji","old_zhoutai","old_caoren","re_xiahouyuan","xiaoqiao","re_huangzhong","re_weiyan"], - shenhua_huo:['dianwei','xunyu','pangtong','sp_zhugeliang','taishici','yanwen','re_yuanshao','re_pangde'], - shenhua_lin:['caopi','re_xuhuang','menghuo','zhurong','re_lusu','sunjian','dongzhuo','jiaxu'], - shenhua_shan:['dengai','zhanghe','liushan','jiangwei','zhangzhang','sunce','caiwenji','zuoci'], - shenhua_yin:['wangji','kuailiangkuaiyue','yanyan','wangping','sunliang','luji','xuyou','yl_luzhi'], - shenhua_lei:['haozhao','guanqiujian','chendao','zhugezhan','lukang','zhoufei','zhangxiu','yl_yuanshu'], + name: "shenhua", + connect: true, + characterSort: { + shenhua: { + shenhua_feng: [ + "sp_zhangjiao", + "re_yuji", + "old_zhoutai", + "old_caoren", + "re_xiahouyuan", + "xiaoqiao", + "re_huangzhong", + "re_weiyan", + ], + shenhua_huo: [ + "dianwei", + "xunyu", + "pangtong", + "sp_zhugeliang", + "taishici", + "yanwen", + "re_yuanshao", + "re_pangde", + ], + shenhua_lin: [ + "caopi", + "re_xuhuang", + "menghuo", + "zhurong", + "re_lusu", + "sunjian", + "dongzhuo", + "jiaxu", + ], + shenhua_shan: [ + "dengai", + "zhanghe", + "liushan", + "jiangwei", + "zhangzhang", + "sunce", + "caiwenji", + "zuoci", + ], + shenhua_yin: [ + "wangji", + "kuailiangkuaiyue", + "yanyan", + "wangping", + "sunliang", + "luji", + "xuyou", + "yl_luzhi", + ], + shenhua_lei: [ + "haozhao", + "guanqiujian", + "chendao", + "zhugezhan", + "lukang", + "zhoufei", + "zhangxiu", + "yl_yuanshu", + ], }, }, - character:{ - re_huangzhong:['male','shu',4,['xinliegong']], - old_zhoutai:['male','wu',4,['gzbuqu']], - old_caoren:['male','wei',4,['jushou']], - re_xuhuang:['male','wei',4,['duanliang','jiezi']], - re_pangde:['male','qun',4,['mashu','jianchu']], - re_xiahouyuan:['male','wei',4,['xinshensu']], - re_weiyan:['male','shu',4,['xinkuanggu','qimou']], - xiaoqiao:['female','wu',3,['retianxiang','hongyan']], - sp_zhangjiao:['male','qun',3,['releiji','guidao','huangtian'],['zhu']], - re_yuji:["male","qun",3,["xinfu_guhuo"]], + character: { + re_huangzhong: ["male", "shu", 4, ["xinliegong"]], + old_zhoutai: ["male", "wu", 4, ["gzbuqu"]], + old_caoren: ["male", "wei", 4, ["jushou"]], + re_xuhuang: ["male", "wei", 4, ["duanliang", "jiezi"]], + re_pangde: ["male", "qun", 4, ["mashu", "jianchu"]], + re_xiahouyuan: ["male", "wei", 4, ["xinshensu"]], + re_weiyan: ["male", "shu", 4, ["xinkuanggu", "qimou"]], + xiaoqiao: ["female", "wu", 3, ["retianxiang", "hongyan"]], + sp_zhangjiao: ["male", "qun", 3, ["releiji", "guidao", "huangtian"], ["zhu"]], + re_yuji: ["male", "qun", 3, ["xinfu_guhuo"]], // yuji:['male','qun',3,['guhuo']], // xin_yuji:['male','qun',3,['guhuo']], - sp_zhugeliang:['male','shu',3,['bazhen','huoji','kanpo']], - pangtong:['male','shu',3,['lianhuan','oldniepan']], - xunyu:['male','wei',3,['quhu','jieming'],['clan:颍川荀氏']], - dianwei:['male','wei',4,['qiangxix']], - taishici:['male','wu',4,['tianyi']], - yanwen:['male','qun',4,['shuangxiong']], - re_yuanshao:['male','qun',4,['luanji','xueyi'],['zhu']], + sp_zhugeliang: ["male", "shu", 3, ["bazhen", "huoji", "kanpo"]], + pangtong: ["male", "shu", 3, ["lianhuan", "oldniepan"]], + xunyu: ["male", "wei", 3, ["quhu", "jieming"], ["clan:颍川荀氏"]], + dianwei: ["male", "wei", 4, ["qiangxix"]], + taishici: ["male", "wu", 4, ["tianyi"]], + yanwen: ["male", "qun", 4, ["shuangxiong"]], + re_yuanshao: ["male", "qun", 4, ["luanji", "xueyi"], ["zhu"]], - menghuo:['male','shu',4,['huoshou','zaiqixx']], - zhurong:['female','shu',4,['juxiang','lieren']], - caopi:['male','wei',3,['xingshang','fangzhu','songwei'],['zhu']], - re_lusu:['male','wu',3,['haoshi','dimeng']], - sunjian:['male','wu',4,['gzyinghun']], - dongzhuo:['male','qun',8,['jiuchi','roulin','benghuai','baonue'],['zhu']], - jiaxu:['male','qun',3,['luanwu','wansha','weimu']], + menghuo: ["male", "shu", 4, ["huoshou", "zaiqixx"]], + zhurong: ["female", "shu", 4, ["juxiang", "lieren"]], + caopi: ["male", "wei", 3, ["xingshang", "fangzhu", "songwei"], ["zhu"]], + re_lusu: ["male", "wu", 3, ["haoshi", "dimeng"]], + sunjian: ["male", "wu", 4, ["gzyinghun"]], + dongzhuo: ["male", "qun", 8, ["jiuchi", "roulin", "benghuai", "baonue"], ["zhu"]], + jiaxu: ["male", "qun", 3, ["luanwu", "wansha", "weimu"]], - jiangwei:['male','shu',4,['tiaoxin','zhiji']], - liushan:['male','shu',3,['xiangle','fangquan','ruoyu'],['zhu']], - zhanghe:['male','wei',4,['qiaobian']], - dengai:['male','wei',4,['tuntian','zaoxian']], - sunce:['male','wu',4,['jiang','hunzi','zhiba'],['zhu']], - zhangzhang:['male','wu',3,['zhijian','guzheng']], - caiwenji:['female','qun',3,['beige','duanchang']], - zuoci:['male','qun',3,['huashen','xinsheng']], + jiangwei: ["male", "shu", 4, ["tiaoxin", "zhiji"]], + liushan: ["male", "shu", 3, ["xiangle", "fangquan", "ruoyu"], ["zhu"]], + zhanghe: ["male", "wei", 4, ["qiaobian"]], + dengai: ["male", "wei", 4, ["tuntian", "zaoxian"]], + sunce: ["male", "wu", 4, ["jiang", "hunzi", "zhiba"], ["zhu"]], + zhangzhang: ["male", "wu", 3, ["zhijian", "guzheng"]], + caiwenji: ["female", "qun", 3, ["beige", "duanchang"]], + zuoci: ["male", "qun", 3, ["huashen", "xinsheng"]], - wangji:['male','wei',3,['qizhi','jinqu']], - "yanyan":["male","shu",4,["nzry_juzhan"],[]], - "wangping":["male","shu",4,["nzry_feijun","nzry_binglve"],[]], - "luji":["male","wu",3,["nzry_huaiju","nzry_yili","nzry_zhenglun"],[]], - "sunliang":["male","wu",3,["nzry_kuizhu","nzry_zhizheng","nzry_lijun"],['zhu']], - xuyou:["male","qun",3,["nzry_chenglve","nzry_shicai","nzry_cunmu"]], - "yl_luzhi":["male","qun",3,["nzry_mingren","nzry_zhenliang"],["die_audio"]], - "kuailiangkuaiyue":["male","wei",3,["nzry_jianxiang","nzry_shenshi"],[]], + wangji: ["male", "wei", 3, ["qizhi", "jinqu"]], + yanyan: ["male", "shu", 4, ["nzry_juzhan"], []], + wangping: ["male", "shu", 4, ["nzry_feijun", "nzry_binglve"], []], + luji: ["male", "wu", 3, ["nzry_huaiju", "nzry_yili", "nzry_zhenglun"], []], + sunliang: ["male", "wu", 3, ["nzry_kuizhu", "nzry_zhizheng", "nzry_lijun"], ["zhu"]], + xuyou: ["male", "qun", 3, ["nzry_chenglve", "nzry_shicai", "nzry_cunmu"]], + yl_luzhi: ["male", "qun", 3, ["nzry_mingren", "nzry_zhenliang"], ["die_audio"]], + kuailiangkuaiyue: ["male", "wei", 3, ["nzry_jianxiang", "nzry_shenshi"], []], - guanqiujian:['male','wei',4,['zhengrong','hongju']], - "haozhao":["male","wei",4,["drlt_zhenggu"],[]], - "zhugezhan":["male","shu",3,["xinfu_zuilun","xinfu_fuyin"],[]], - "lukang":["male","wu",4,["drlt_qianjie","drlt_jueyan","drlt_poshi"],[]], - "yl_yuanshu":["male","qun",4,["drlt_yongsi","drlt_weidi"],["zhu"]], - "zhangxiu":["male","qun",4,["drlt_xiongluan","drlt_congjian",'twjuxiang'],['zhu']], - "chendao":["male","shu",4,["dcwanglie"],[]], - zhoufei:["female","wu",3,["olliangyin","olkongsheng"]], + guanqiujian: ["male", "wei", 4, ["zhengrong", "hongju"]], + haozhao: ["male", "wei", 4, ["drlt_zhenggu"], []], + zhugezhan: ["male", "shu", 3, ["xinfu_zuilun", "xinfu_fuyin"], []], + lukang: ["male", "wu", 4, ["drlt_qianjie", "drlt_jueyan", "drlt_poshi"], []], + yl_yuanshu: ["male", "qun", 4, ["drlt_yongsi", "drlt_weidi"], ["zhu"]], + zhangxiu: ["male", "qun", 4, ["drlt_xiongluan", "drlt_congjian", "twjuxiang"], ["zhu"]], + chendao: ["male", "shu", 4, ["dcwanglie"], []], + zhoufei: ["female", "wu", 3, ["olliangyin", "olkongsheng"]], }, - perfectPair:{ - jiaxu:['liqueguosi'], - re_yuanshao:['yanwen','tianfeng'], - menghuo:['zhurong'], - sp_zhugeliang:['pangtong','huangyueying'], - sunce:['zhouyu','taishici','daqiao'], - zuoci:['yuji'], - xunyu:['xunyou'], - lukang:['luxun'], - yuanshu:['jiling'], - zhangxiu:['jiaxu'], - wangping:['jiangfei'], - jiangwei:['xiahouba'], - guanqiujian:['wenqin'], + perfectPair: { + jiaxu: ["liqueguosi"], + re_yuanshao: ["yanwen", "tianfeng"], + menghuo: ["zhurong"], + sp_zhugeliang: ["pangtong", "huangyueying"], + sunce: ["zhouyu", "taishici", "daqiao"], + zuoci: ["yuji"], + xunyu: ["xunyou"], + lukang: ["luxun"], + yuanshu: ["jiling"], + zhangxiu: ["jiaxu"], + wangping: ["jiangfei"], + jiangwei: ["xiahouba"], + guanqiujian: ["wenqin"], }, - characterFilter:{ - zuoci:function(mode){ - return mode!='guozhan'; - } + characterFilter: { + zuoci: function (mode) { + return mode != "guozhan"; + }, }, - characterIntro:{ - huangzhong:'字汉升,今河南南阳人。汉末三国时期蜀汉名将。本为刘表部下中郎将,后归刘备,并助刘备攻益州刘璋,在定军山一战中阵斩曹操部下名将夏侯渊。备称汉中王后改封后将军,赐关内侯。', - weiyan:'字文长,义阳人。三国时期蜀汉名将,诸葛亮死后,魏延因被陷害谋反而遭杨仪一党所杀。', - xiahouyuan:'字妙才,沛国谯人。东汉末年曹操部下名将,夏侯惇之族弟,八虎骑之一。群雄征讨董卓时随曹操一同起兵,后征战四方,屡立功勋。在平定马超叛乱后负责西北防线的镇守。公元219年刘备攻打汉中,被刘备部将黄忠所杀。', - caoren:'字子孝,沛国谯人,曹操的从弟。三国时期曹魏名将,官至大司马。谥曰忠侯。', - xiaoqiao:'庐江皖县人也。父桥国老德尊于时。小乔国色流离,资貌绝伦。建安三年,周瑜协策攻皖,拔之。娶小乔为妻。后人谓英雄美女,天作之合。', - zhoutai:'字幼平,九江下蔡人,三国时期吴国武将。早年与蒋钦随孙策左右,立过数次战功。孙策讨伐六县山贼时,周泰胆气绝伦,保卫孙权,勇战退敌,身受十二处伤。有诗云:三番救主出重围,忠勇如公世所稀。遍体疮痍犹痛饮,血痕残酒满征衣。', - yuji:'自号太平道人,琅琊人,在吴郡、会稽一带为百姓治病,甚得人心。孙策怒之,以惑人心为由斩之,后策常受吉咒而亡。', - zhangjiao:'乱世的开始,黄巾起义军首领,太平道创始人。张角早年信奉黄老学说,对在汉代十分流行的谶纬之学也深有研究,对民间医术 、巫术也很熟悉。', - dianwei:'己吾城村人。东汉末年曹魏猛将。擅使大双戟,为人壮猛任侠,曾为乡人刘氏报仇,杀人出市,人莫敢近。相貌魁梧,膂力过人。建安二年(197),张绣背叛曹操,典韦为保护曹操而独挡叛军,击杀多人,但最终因寡不敌众而战死。', - xunyu:'荀彧,字文若,颍川颍阴(今河南许昌)人。东汉末年曹操帐下首席谋臣,杰出的战略家。自小被世人称作“王佐之才”。', - pangtong:'庞统,字士元,襄阳(治今湖北襄阳)人。三国时刘备帐下谋士,官拜军师中郎将。才智与诸葛亮齐名,人称“凤雏”。在进围雒县时,统率众攻城,不幸被流矢击中去世,时年三十六岁。追赐统为关内侯,谥曰靖侯。庞统死后,葬于落凤庞统墓坡。', - sp_zhugeliang:'字孔明,号卧龙居士,琅琊阳都人。刘备曾“三顾茅庐”得见卧龙。卧龙以一篇《隆中对》分析天下形势,提出先取荆州,再取益州成鼎足之势的说法。《三国演义》中的诸葛亮善用“火攻”,曾用火攻战术赢得多场战役,如“火烧赤壁”、“火烧博望坡”、“火烧藤甲兵”等。', - taishici:'太史慈,字子义,东莱黄县(今山东龙口东黄城集)人。东汉末年武将,守言应诺,恪遵信义,始终如一,弭息诽论。官至建昌都尉。弓马熟练,箭法精良。原为刘繇部下,后被孙策收降,于赤壁之战前病逝,死时才四十一岁。', - pangde:'字令明,东汉末年雍州南安郡狟道县(今甘肃天水市武山县四门镇)人。曹操部下重要将领。官至立义将军,拜关门亭侯。谥曰壮侯。有一子庞会。', - yanwen:'东汉末年河北袁绍部下武将,素有威名。颜良与文丑一起作为袁绍军队的勇将而闻名。建安四年(199),袁绍以颜良、文丑为将,率精卒十万,准备攻许都;次年,兵进黎阳,遣颜良攻白马。终均亡于关羽刀下。', - yuanshao:'字本初,汉族,汝南汝阳人,出身名门望族,自曾祖父起四代有五人位居三公,自己也居三公之上,其家族也因此有“四世三公”之称。曾于初平元年被推举为反董卓联合军的盟主,联军瓦解后,在汉末群雄割据的过程中,袁绍先占据冀州,又先后夺青、并二州,并于建安四年击败了割据幽州的军阀公孙瓒,势力达到顶点;但在建安五年的官渡之战中败于曹操。在平定冀州叛乱之后,于建安七年病死。', - xuhuang:'字公明,河东杨人。三国时期曹魏名将,本为杨奉帐下骑都尉,杨奉被曹操击败后转投曹操,在曹操手下多立功勋,参与官渡、赤壁、关中征伐、汉中征伐等几次重大战役。', - caopi:'字子桓,三国时期著名的政治家、文学家,曹魏的开国皇帝,公元220-226年在位。沛国谯人,魏武帝曹操与武宣卞皇后的长子。去世后庙号高祖,谥为文皇帝,葬于首阳陵。', - sunjian:'字文台,汉族,吴郡富春人。东汉末期地方军阀,著名将领。史书说他“容貌不凡,性阔达,好奇节”,是大军事家孙武的后裔。汉末群雄之一,三国中吴国的奠基人。孙权建国后,追谥孙坚为武烈皇帝。', - dongzhuo:'字仲颖,陇西临洮人。东汉末年少帝、献帝时权臣,西凉军阀。官至太师、郿侯。其为人残忍嗜杀,倒行逆施,招致群雄联合讨伐,但联合军在董卓迁都长安不久后瓦解。后被其亲信吕布所杀。', - zhurong:'据传为火神祝融氏后裔,南蛮王孟获之妻。武艺超群,善使飞刀,是《三国演义》中写到的唯一真正上过战场的女性。曾与孟获一起抵抗蜀军,在诸葛亮七擒七纵孟获之后,随孟获投降蜀汉。', - menghuo:'中国三国时期南中少数族首领。系东汉末益州建宁郡( 今云南晋宁东 )大姓,身材肥硕。生卒年不详。官至御史中丞。曾被诸葛亮七擒七纵,传为佳话。', - jiaxu:'字文和,武威姑臧人。三国时期魏国著名谋士。曾先后担任三国军阀李傕、张绣、曹操的谋士。官至魏国太尉,谥曰肃侯。', - lusu:'字子敬,汉族,临淮东城人,中国东汉末年东吴的著名军事统帅。他曾为孙权提出鼎足江东的战略规划,因此得到孙权的赏识,于周瑜死后代替周瑜领兵,守陆口。曾单刀赴会关羽于荆州。', - zhanghe:'字儁乂,河间鄚人。三国时期魏国名将。官渡之战时,本为袁绍部将的张郃投降了曹操,并在曹操帐下多立功勋,于曹魏建立后加封为征西车骑将军。诸葛亮六出祁山之间,张郃多次抵御蜀军的进攻,于公元231年在木门道被诸葛亮设伏射死。后谥曰壮侯。为曹魏“五子良将”之一。', - dengai:'字士载,义阳棘阳人。三国时期魏国杰出的军事家、将领。公元263年他与钟会分别率军攻打蜀汉,最后他率先进入成都,使得蜀汉灭亡。后因遭到钟会的污蔑和陷害,被司马昭猜忌而被收押,最后与其子邓忠一起被卫瓘派遣的武将田续所杀害。', - jiangwei:'字伯约,天水冀人。三国时期蜀汉著名将领、军事统帅。原为曹魏天水郡的中郎将,后降蜀汉,官至凉州刺史、大将军。诸葛亮去世后继承诸葛亮的遗志,继续率领蜀汉军队北伐曹魏,与曹魏名将陈泰、郭淮、邓艾等多次交手。', - liushan:'蜀汉后主,字公嗣。小名阿斗。刘备之子,母亲是昭烈皇后甘氏。三国时期蜀汉第二位皇帝,公元223-263年在位。公元263年蜀汉被曹魏所灭,刘禅投降曹魏,被封为安乐公。', - sunce:'字伯符,吴郡富春人。孙坚长子,孙权长兄。东汉末年割据江东一带的军阀,汉末群雄之一,三国时期吴国的奠基者。三国演义中绰号“小霸王”,统一江东。在一次狩猎中为刺客所伤,不久后身亡,年仅二十六岁。其弟孙权接掌孙策势力,并于称帝后,追谥孙策为长沙桓王。', - zhangzhang:'张昭,字子布,彭城人,三国时期吴国重臣,善丹青。拜辅吴将军,班亚三司,改封娄侯。年八十一卒,谥曰文侯。张纮,字子纲,广陵人。东吴谋士,和张昭一起合称“二张”。孙策平定江东时亲自登门邀请,张纮遂出仕为官。张纮后来建议孙权迁都秣陵,孙权正在准备时张纮病逝,其年六十岁。孙权为之流涕。', - zuoci:'左慈,字元放,东汉末方士,汉族,庐江(今安徽庐江西南)人。在道教历史上,东汉时期的丹鼎派道术是从他一脉相传。', - caiwenji:'名琰,原字昭姬,晋时避司马昭讳,改字文姬,东汉末年陈留圉(今河南开封杞县)人,东汉大文学家蔡邕的女儿,是中国历史上著名的才女和文学家,精于天文数理,既博学能文,又善诗赋,兼长辩才与音律。代表作有《胡笳十八拍》、《悲愤诗》等 。', + characterIntro: { + huangzhong: + "字汉升,今河南南阳人。汉末三国时期蜀汉名将。本为刘表部下中郎将,后归刘备,并助刘备攻益州刘璋,在定军山一战中阵斩曹操部下名将夏侯渊。备称汉中王后改封后将军,赐关内侯。", + weiyan: "字文长,义阳人。三国时期蜀汉名将,诸葛亮死后,魏延因被陷害谋反而遭杨仪一党所杀。", + xiahouyuan: + "字妙才,沛国谯人。东汉末年曹操部下名将,夏侯惇之族弟,八虎骑之一。群雄征讨董卓时随曹操一同起兵,后征战四方,屡立功勋。在平定马超叛乱后负责西北防线的镇守。公元219年刘备攻打汉中,被刘备部将黄忠所杀。", + caoren: "字子孝,沛国谯人,曹操的从弟。三国时期曹魏名将,官至大司马。谥曰忠侯。", + xiaoqiao: + "庐江皖县人也。父桥国老德尊于时。小乔国色流离,资貌绝伦。建安三年,周瑜协策攻皖,拔之。娶小乔为妻。后人谓英雄美女,天作之合。", + zhoutai: + "字幼平,九江下蔡人,三国时期吴国武将。早年与蒋钦随孙策左右,立过数次战功。孙策讨伐六县山贼时,周泰胆气绝伦,保卫孙权,勇战退敌,身受十二处伤。有诗云:三番救主出重围,忠勇如公世所稀。遍体疮痍犹痛饮,血痕残酒满征衣。", + yuji: "自号太平道人,琅琊人,在吴郡、会稽一带为百姓治病,甚得人心。孙策怒之,以惑人心为由斩之,后策常受吉咒而亡。", + zhangjiao: + "乱世的开始,黄巾起义军首领,太平道创始人。张角早年信奉黄老学说,对在汉代十分流行的谶纬之学也深有研究,对民间医术 、巫术也很熟悉。", + dianwei: + "己吾城村人。东汉末年曹魏猛将。擅使大双戟,为人壮猛任侠,曾为乡人刘氏报仇,杀人出市,人莫敢近。相貌魁梧,膂力过人。建安二年(197),张绣背叛曹操,典韦为保护曹操而独挡叛军,击杀多人,但最终因寡不敌众而战死。", + xunyu: "荀彧,字文若,颍川颍阴(今河南许昌)人。东汉末年曹操帐下首席谋臣,杰出的战略家。自小被世人称作“王佐之才”。", + pangtong: + "庞统,字士元,襄阳(治今湖北襄阳)人。三国时刘备帐下谋士,官拜军师中郎将。才智与诸葛亮齐名,人称“凤雏”。在进围雒县时,统率众攻城,不幸被流矢击中去世,时年三十六岁。追赐统为关内侯,谥曰靖侯。庞统死后,葬于落凤庞统墓坡。", + sp_zhugeliang: + "字孔明,号卧龙居士,琅琊阳都人。刘备曾“三顾茅庐”得见卧龙。卧龙以一篇《隆中对》分析天下形势,提出先取荆州,再取益州成鼎足之势的说法。《三国演义》中的诸葛亮善用“火攻”,曾用火攻战术赢得多场战役,如“火烧赤壁”、“火烧博望坡”、“火烧藤甲兵”等。", + taishici: + "太史慈,字子义,东莱黄县(今山东龙口东黄城集)人。东汉末年武将,守言应诺,恪遵信义,始终如一,弭息诽论。官至建昌都尉。弓马熟练,箭法精良。原为刘繇部下,后被孙策收降,于赤壁之战前病逝,死时才四十一岁。", + pangde: "字令明,东汉末年雍州南安郡狟道县(今甘肃天水市武山县四门镇)人。曹操部下重要将领。官至立义将军,拜关门亭侯。谥曰壮侯。有一子庞会。", + yanwen: "东汉末年河北袁绍部下武将,素有威名。颜良与文丑一起作为袁绍军队的勇将而闻名。建安四年(199),袁绍以颜良、文丑为将,率精卒十万,准备攻许都;次年,兵进黎阳,遣颜良攻白马。终均亡于关羽刀下。", + yuanshao: + "字本初,汉族,汝南汝阳人,出身名门望族,自曾祖父起四代有五人位居三公,自己也居三公之上,其家族也因此有“四世三公”之称。曾于初平元年被推举为反董卓联合军的盟主,联军瓦解后,在汉末群雄割据的过程中,袁绍先占据冀州,又先后夺青、并二州,并于建安四年击败了割据幽州的军阀公孙瓒,势力达到顶点;但在建安五年的官渡之战中败于曹操。在平定冀州叛乱之后,于建安七年病死。", + xuhuang: + "字公明,河东杨人。三国时期曹魏名将,本为杨奉帐下骑都尉,杨奉被曹操击败后转投曹操,在曹操手下多立功勋,参与官渡、赤壁、关中征伐、汉中征伐等几次重大战役。", + caopi: "字子桓,三国时期著名的政治家、文学家,曹魏的开国皇帝,公元220-226年在位。沛国谯人,魏武帝曹操与武宣卞皇后的长子。去世后庙号高祖,谥为文皇帝,葬于首阳陵。", + sunjian: + "字文台,汉族,吴郡富春人。东汉末期地方军阀,著名将领。史书说他“容貌不凡,性阔达,好奇节”,是大军事家孙武的后裔。汉末群雄之一,三国中吴国的奠基人。孙权建国后,追谥孙坚为武烈皇帝。", + dongzhuo: + "字仲颖,陇西临洮人。东汉末年少帝、献帝时权臣,西凉军阀。官至太师、郿侯。其为人残忍嗜杀,倒行逆施,招致群雄联合讨伐,但联合军在董卓迁都长安不久后瓦解。后被其亲信吕布所杀。", + zhurong: + "据传为火神祝融氏后裔,南蛮王孟获之妻。武艺超群,善使飞刀,是《三国演义》中写到的唯一真正上过战场的女性。曾与孟获一起抵抗蜀军,在诸葛亮七擒七纵孟获之后,随孟获投降蜀汉。", + menghuo: + "中国三国时期南中少数族首领。系东汉末益州建宁郡( 今云南晋宁东 )大姓,身材肥硕。生卒年不详。官至御史中丞。曾被诸葛亮七擒七纵,传为佳话。", + jiaxu: "字文和,武威姑臧人。三国时期魏国著名谋士。曾先后担任三国军阀李傕、张绣、曹操的谋士。官至魏国太尉,谥曰肃侯。", + lusu: "字子敬,汉族,临淮东城人,中国东汉末年东吴的著名军事统帅。他曾为孙权提出鼎足江东的战略规划,因此得到孙权的赏识,于周瑜死后代替周瑜领兵,守陆口。曾单刀赴会关羽于荆州。", + zhanghe: + "字儁乂,河间鄚人。三国时期魏国名将。官渡之战时,本为袁绍部将的张郃投降了曹操,并在曹操帐下多立功勋,于曹魏建立后加封为征西车骑将军。诸葛亮六出祁山之间,张郃多次抵御蜀军的进攻,于公元231年在木门道被诸葛亮设伏射死。后谥曰壮侯。为曹魏“五子良将”之一。", + dengai: "字士载,义阳棘阳人。三国时期魏国杰出的军事家、将领。公元263年他与钟会分别率军攻打蜀汉,最后他率先进入成都,使得蜀汉灭亡。后因遭到钟会的污蔑和陷害,被司马昭猜忌而被收押,最后与其子邓忠一起被卫瓘派遣的武将田续所杀害。", + jiangwei: + "字伯约,天水冀人。三国时期蜀汉著名将领、军事统帅。原为曹魏天水郡的中郎将,后降蜀汉,官至凉州刺史、大将军。诸葛亮去世后继承诸葛亮的遗志,继续率领蜀汉军队北伐曹魏,与曹魏名将陈泰、郭淮、邓艾等多次交手。", + liushan: + "蜀汉后主,字公嗣。小名阿斗。刘备之子,母亲是昭烈皇后甘氏。三国时期蜀汉第二位皇帝,公元223-263年在位。公元263年蜀汉被曹魏所灭,刘禅投降曹魏,被封为安乐公。", + sunce: "字伯符,吴郡富春人。孙坚长子,孙权长兄。东汉末年割据江东一带的军阀,汉末群雄之一,三国时期吴国的奠基者。三国演义中绰号“小霸王”,统一江东。在一次狩猎中为刺客所伤,不久后身亡,年仅二十六岁。其弟孙权接掌孙策势力,并于称帝后,追谥孙策为长沙桓王。", + zhangzhang: + "张昭,字子布,彭城人,三国时期吴国重臣,善丹青。拜辅吴将军,班亚三司,改封娄侯。年八十一卒,谥曰文侯。张纮,字子纲,广陵人。东吴谋士,和张昭一起合称“二张”。孙策平定江东时亲自登门邀请,张纮遂出仕为官。张纮后来建议孙权迁都秣陵,孙权正在准备时张纮病逝,其年六十岁。孙权为之流涕。", + zuoci: "左慈,字元放,东汉末方士,汉族,庐江(今安徽庐江西南)人。在道教历史上,东汉时期的丹鼎派道术是从他一脉相传。", + caiwenji: + "名琰,原字昭姬,晋时避司马昭讳,改字文姬,东汉末年陈留圉(今河南开封杞县)人,东汉大文学家蔡邕的女儿,是中国历史上著名的才女和文学家,精于天文数理,既博学能文,又善诗赋,兼长辩才与音律。代表作有《胡笳十八拍》、《悲愤诗》等 。", - "yanyan":"严颜,东汉末年武将,初为刘璋部下,担任巴郡太守。建安十九年,刘备进攻江州,严颜战败被俘,张飞对严颜说:“大军至,何以不降而敢拒战?”,严颜回答说:“卿等无状,侵夺我州,我州但有断头将军,无降将军也!”,张飞生气,命左右将严颜牵去砍头,严颜表情不变地说:“砍头便砍头,何为怒邪!”张飞敬佩严颜的勇气,遂释放严颜并以严颜为宾客,之后的事迹不在正史中出现。", - "wangping":"王平,字子均,巴西宕渠(今四川省渠县东北)人,籍贯益州。三国时蜀汉后期大将。原属曹操,曹操与刘备争汉中,得以投降刘备。诸葛亮第一次北伐时与马谡一同守街亭,之后深受诸葛亮的器重,率领蜀汉的王牌军队无当飞军,多次随诸葛亮北伐。诸葛亮死后,拜前监军、镇北大将军,镇守汉中,曹爽率领十万大军攻汉中时,被王平所击退,累封安汉侯。延熙十一年,王平去世,其子王训继承了爵位。", - "luji":"陆绩(公元188年-公元219年),字公纪,吴郡吴县(今苏州)人,汉末庐江太守陆康之子。陆绩成年后,博学多识,通晓天文、历算,星历算数无不涉览。孙权征其为奏曹掾,常以直道见惮。后出为郁林太守,加偏将军。在军中不废著作,曾作《浑天图》,注《易经》,撰写《太玄经注》。", - "sunliang":"孙亮(243-260年),字子明,吴郡富春(今浙江杭州富阳区)人。三国时期吴国的第二位皇帝,公元252-258年在位。吴大帝孙权第七子,母潘皇后。史称吴少帝、吴废帝、会稽王。建兴元年(252年),十岁登基为帝,太平二年(257年),十五岁亲政,但一年后(258年)就被权臣孙綝废为会稽王。永安三年(260年),孙亮再被贬为候官侯,在前往封地途中自杀(一说被毒杀),终年18岁。西晋太康年间,原先任职吴国的官员戴显将孙亮的遗骨葬在赖乡。", - "xuyou":"许攸(?-204年),字子远,南阳(治今河南南阳)人。本为袁绍帐下谋士,官渡之战时其家人因犯法而被收捕,许攸因此背袁投曹,并为曹操设下偷袭袁绍军屯粮之所乌巢的计策,袁绍因此而大败于官渡。后许攸随曹操平定冀州,因自恃其功而屡屡口出狂言,终因触怒曹操而被杀。", - "yl_luzhi":"卢植(139年—192年),字子干。涿郡涿县(今河北涿州)人。东汉末年经学家、将领。卢植性格刚毅,师从太尉陈球、大儒马融等,为郑玄、管宁、华歆的同门师兄。曾先后担任九江、庐江太守,平定蛮族叛乱。后与马日磾、蔡邕等一起在东观校勘儒学经典书籍,并参与续写《汉记》。黄巾起义时为北中郎将,率军与张角交战,后被诬陷下狱,皇甫嵩平定黄巾后力救卢植,于是复任为尚书。后因上谏激怒董卓被免官,隐居在上谷军都山,被袁绍请为军师。初平三年(192年)去世。著有《尚书章句》、《三礼解诂》等,今皆失佚。唐代时配享孔子,北宋时被追封为良乡伯。白马将军公孙瓒以及后来的蜀汉昭烈帝刘备皆为卢植门下弟子。范阳卢氏后来也成为著名的家族。", - "kuailiangkuaiyue":"蒯良,字子柔,襄阳中庐人。归刘表。蒯良为刘表定下安抚荆楚的政治方向,佐其成业,被刘表誉为“雍季之论”。之后,蒯良就被刘表擢升为主簿(bù)。其后蒯良的生平,就不得而知了,《三国志》亦没有记载其卒年。与蒯越、以及同样活跃于襄阳的蒯祺(诸葛亮姐夫)或为同族兄弟。蒯越(?-214年),字异度,襄阳中庐(今湖北襄阳西南)人。东汉末期人物,演义中为蒯良之弟。原本是荆州牧刘表的部下,曾经在刘表初上任时帮助刘表铲除荆州一带的宗贼(以宗族、乡里关系组成的武装集团)。刘表病逝后与刘琮一同投降曹操,后来官至光禄勋。", + yanyan: "严颜,东汉末年武将,初为刘璋部下,担任巴郡太守。建安十九年,刘备进攻江州,严颜战败被俘,张飞对严颜说:“大军至,何以不降而敢拒战?”,严颜回答说:“卿等无状,侵夺我州,我州但有断头将军,无降将军也!”,张飞生气,命左右将严颜牵去砍头,严颜表情不变地说:“砍头便砍头,何为怒邪!”张飞敬佩严颜的勇气,遂释放严颜并以严颜为宾客,之后的事迹不在正史中出现。", + wangping: + "王平,字子均,巴西宕渠(今四川省渠县东北)人,籍贯益州。三国时蜀汉后期大将。原属曹操,曹操与刘备争汉中,得以投降刘备。诸葛亮第一次北伐时与马谡一同守街亭,之后深受诸葛亮的器重,率领蜀汉的王牌军队无当飞军,多次随诸葛亮北伐。诸葛亮死后,拜前监军、镇北大将军,镇守汉中,曹爽率领十万大军攻汉中时,被王平所击退,累封安汉侯。延熙十一年,王平去世,其子王训继承了爵位。", + luji: "陆绩(公元188年-公元219年),字公纪,吴郡吴县(今苏州)人,汉末庐江太守陆康之子。陆绩成年后,博学多识,通晓天文、历算,星历算数无不涉览。孙权征其为奏曹掾,常以直道见惮。后出为郁林太守,加偏将军。在军中不废著作,曾作《浑天图》,注《易经》,撰写《太玄经注》。", + sunliang: + "孙亮(243-260年),字子明,吴郡富春(今浙江杭州富阳区)人。三国时期吴国的第二位皇帝,公元252-258年在位。吴大帝孙权第七子,母潘皇后。史称吴少帝、吴废帝、会稽王。建兴元年(252年),十岁登基为帝,太平二年(257年),十五岁亲政,但一年后(258年)就被权臣孙綝废为会稽王。永安三年(260年),孙亮再被贬为候官侯,在前往封地途中自杀(一说被毒杀),终年18岁。西晋太康年间,原先任职吴国的官员戴显将孙亮的遗骨葬在赖乡。", + xuyou: "许攸(?-204年),字子远,南阳(治今河南南阳)人。本为袁绍帐下谋士,官渡之战时其家人因犯法而被收捕,许攸因此背袁投曹,并为曹操设下偷袭袁绍军屯粮之所乌巢的计策,袁绍因此而大败于官渡。后许攸随曹操平定冀州,因自恃其功而屡屡口出狂言,终因触怒曹操而被杀。", + yl_luzhi: + "卢植(139年—192年),字子干。涿郡涿县(今河北涿州)人。东汉末年经学家、将领。卢植性格刚毅,师从太尉陈球、大儒马融等,为郑玄、管宁、华歆的同门师兄。曾先后担任九江、庐江太守,平定蛮族叛乱。后与马日磾、蔡邕等一起在东观校勘儒学经典书籍,并参与续写《汉记》。黄巾起义时为北中郎将,率军与张角交战,后被诬陷下狱,皇甫嵩平定黄巾后力救卢植,于是复任为尚书。后因上谏激怒董卓被免官,隐居在上谷军都山,被袁绍请为军师。初平三年(192年)去世。著有《尚书章句》、《三礼解诂》等,今皆失佚。唐代时配享孔子,北宋时被追封为良乡伯。白马将军公孙瓒以及后来的蜀汉昭烈帝刘备皆为卢植门下弟子。范阳卢氏后来也成为著名的家族。", + kuailiangkuaiyue: + "蒯良,字子柔,襄阳中庐人。归刘表。蒯良为刘表定下安抚荆楚的政治方向,佐其成业,被刘表誉为“雍季之论”。之后,蒯良就被刘表擢升为主簿(bù)。其后蒯良的生平,就不得而知了,《三国志》亦没有记载其卒年。与蒯越、以及同样活跃于襄阳的蒯祺(诸葛亮姐夫)或为同族兄弟。蒯越(?-214年),字异度,襄阳中庐(今湖北襄阳西南)人。东汉末期人物,演义中为蒯良之弟。原本是荆州牧刘表的部下,曾经在刘表初上任时帮助刘表铲除荆州一带的宗贼(以宗族、乡里关系组成的武装集团)。刘表病逝后与刘琮一同投降曹操,后来官至光禄勋。", - "guanqiujian":"毌丘俭,字仲恭,河东闻喜(今山西闻喜县)人。三国时期曹魏后期的重要将领。继承父毌丘兴爵位高阳乡侯,任平原侯文学。魏明帝即位后,上疏劝魏明帝停止加建皇宫的工程,升为荆州刺史。景初二年(238年)从司马懿攻灭公孙渊;正始五年(244年)至正始六年(245年)两次率兵征讨高句丽,攻破丸都,几亡其国,刻石纪功而还;253年击退吴国诸葛恪的大举进犯,战功累累。司马师废帝,毌丘俭感昔日魏明帝之恩,为曹魏政权做拼死一搏,于正元二年(255年)发动兵变,即后人所谓“淮南三叛”(王淩、毌丘俭、诸葛诞)之一,惜准备不足,兵败身亡。", - "haozhao":"郝昭(生卒年不详),字伯道,太原人,中国东汉末年至曹魏初年著名将领。郝昭少年从军,屡立战功,逐渐晋升为杂号将军,后受曹真的推荐镇守陈仓(在小说三国演义中是司马懿推荐),防御蜀汉。太和二年(228年),诸葛亮率军北伐,为郝昭所阻,劝降不成,昼夜相攻二十余日后被迫退军。魏明帝因此封其为关内侯。不久因染疾而病死。", - "zhugezhan":"诸葛瞻,字思远,琅邪阳都(今山东沂南县)人。三国时期蜀汉大臣,蜀汉丞相诸葛亮之子。邓艾伐蜀时,他与长子诸葛尚及蜀将张遵、李球、黄崇等人防御绵竹(今四川德阳),因不听黄崇速占险要的建议而坐失良机,后来出城与邓艾决战,在交战时阵亡,绵竹也随后失守。", - "zhoufei":"周妃(210年?—?),一说本名周彻。周瑜独女,生母无载,疑为汉末美女小乔,因嫁孙登为太子妃,故称周妃。周瑜英年早逝,其遗孤都得到孙权厚遇,除却她本人在黄武四年(225年)嫁予太子外,兄长周循亦娶孙权长女孙鲁班为妻。", - "lukang":"陆抗,字幼节,吴郡吴县(今江苏苏州)人。三国时期吴国名将,丞相陆逊次子。陆抗袭父爵为江陵侯,为建武校尉,领其父众五千人。后迁立节中郎将、镇军将军等。孙皓为帝,任镇军大将军、都督西陵、信陵、夷道、乐乡、公安诸军事,驻乐乡(今湖北江陵西南)。凤凰元年(272年),击退晋将羊祜进攻,并攻杀叛将西陵督步阐。后拜大司马、荆州牧,卒于官,终年49岁。与陆逊皆是吴国的中流砥柱,并称“逊抗 ”,被誉为吴国最后的名将。", - "zhangxiu":"张绣,武威祖厉(今甘肃靖远)人。骠骑将军张济的从子。东汉末年割据宛城的军阀,汉末群雄之一。初随张济征伐,张济死后与刘表联合。后降曹操,因曹操调戏其嫂而突袭曹操,复与刘表连和。官渡之战前夕,听从贾诩的建议再次投降曹操,参加官渡之战,官至破羌将军,封宣威侯。在北征乌桓(207年)途中去世(一说为曹丕逼死),谥定侯。", - "chendao":"陈到,字叔至,生卒年不详,豫州汝南(今河南驻马店平舆县)人。三国时期蜀汉将领,刘备帐下白毦兵统领,名位常亚于赵云,以忠勇著称。蜀汉建兴年间,任征西将军、永安都督,封亭侯。在任期间去世。", + guanqiujian: + "毌丘俭,字仲恭,河东闻喜(今山西闻喜县)人。三国时期曹魏后期的重要将领。继承父毌丘兴爵位高阳乡侯,任平原侯文学。魏明帝即位后,上疏劝魏明帝停止加建皇宫的工程,升为荆州刺史。景初二年(238年)从司马懿攻灭公孙渊;正始五年(244年)至正始六年(245年)两次率兵征讨高句丽,攻破丸都,几亡其国,刻石纪功而还;253年击退吴国诸葛恪的大举进犯,战功累累。司马师废帝,毌丘俭感昔日魏明帝之恩,为曹魏政权做拼死一搏,于正元二年(255年)发动兵变,即后人所谓“淮南三叛”(王淩、毌丘俭、诸葛诞)之一,惜准备不足,兵败身亡。", + haozhao: + "郝昭(生卒年不详),字伯道,太原人,中国东汉末年至曹魏初年著名将领。郝昭少年从军,屡立战功,逐渐晋升为杂号将军,后受曹真的推荐镇守陈仓(在小说三国演义中是司马懿推荐),防御蜀汉。太和二年(228年),诸葛亮率军北伐,为郝昭所阻,劝降不成,昼夜相攻二十余日后被迫退军。魏明帝因此封其为关内侯。不久因染疾而病死。", + zhugezhan: + "诸葛瞻,字思远,琅邪阳都(今山东沂南县)人。三国时期蜀汉大臣,蜀汉丞相诸葛亮之子。邓艾伐蜀时,他与长子诸葛尚及蜀将张遵、李球、黄崇等人防御绵竹(今四川德阳),因不听黄崇速占险要的建议而坐失良机,后来出城与邓艾决战,在交战时阵亡,绵竹也随后失守。", + zhoufei: + "周妃(210年?—?),一说本名周彻。周瑜独女,生母无载,疑为汉末美女小乔,因嫁孙登为太子妃,故称周妃。周瑜英年早逝,其遗孤都得到孙权厚遇,除却她本人在黄武四年(225年)嫁予太子外,兄长周循亦娶孙权长女孙鲁班为妻。", + lukang: "陆抗,字幼节,吴郡吴县(今江苏苏州)人。三国时期吴国名将,丞相陆逊次子。陆抗袭父爵为江陵侯,为建武校尉,领其父众五千人。后迁立节中郎将、镇军将军等。孙皓为帝,任镇军大将军、都督西陵、信陵、夷道、乐乡、公安诸军事,驻乐乡(今湖北江陵西南)。凤凰元年(272年),击退晋将羊祜进攻,并攻杀叛将西陵督步阐。后拜大司马、荆州牧,卒于官,终年49岁。与陆逊皆是吴国的中流砥柱,并称“逊抗 ”,被誉为吴国最后的名将。", + zhangxiu: + "张绣,武威祖厉(今甘肃靖远)人。骠骑将军张济的从子。东汉末年割据宛城的军阀,汉末群雄之一。初随张济征伐,张济死后与刘表联合。后降曹操,因曹操调戏其嫂而突袭曹操,复与刘表连和。官渡之战前夕,听从贾诩的建议再次投降曹操,参加官渡之战,官至破羌将军,封宣威侯。在北征乌桓(207年)途中去世(一说为曹丕逼死),谥定侯。", + chendao: + "陈到,字叔至,生卒年不详,豫州汝南(今河南驻马店平舆县)人。三国时期蜀汉将领,刘备帐下白毦兵统领,名位常亚于赵云,以忠勇著称。蜀汉建兴年间,任征西将军、永安都督,封亭侯。在任期间去世。", }, - skill:{ + skill: { //庞统写法修改 - lianhuan:{ - audio:2, - hiddenCard:(player,name)=>{ - return name=='tiesuo'&&player.hasCard(card=>get.suit(card)=='club','sh'); + lianhuan: { + audio: 2, + 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(get.autoViewAs({name:'tiesuo'},'unsure'),player,event)); + enable: "chooseToUse", + filter: function (event, player) { + if (!player.hasCard((card) => get.suit(card) == "club", "sh")) return false; + return ( + event.type == "phase" || + event.filterCard(get.autoViewAs({ name: "tiesuo" }, "unsure"), 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)){ + 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,event); + } 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, event); } }, - 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)); + 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; + 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; + 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; + 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){ + 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]; + } 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); + 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(){ + content: function () { player.recast(cards); }, }, //新杀小加强 陈到 - dcwanglie:{ - audio:'drlt_wanglie', - locked:false, - mod:{ - targetInRange:function(card,player,target){ - if(player.hasSkill('dcwanglie_effect',null,null,false)) return true; + dcwanglie: { + audio: "drlt_wanglie", + locked: false, + mod: { + targetInRange: function (card, player, target) { + if (player.hasSkill("dcwanglie_effect", null, null, false)) return true; }, }, - trigger:{ - player:"useCard", + trigger: { + player: "useCard", }, - filter:function(event,player){ - return player.isPhaseUsing()&&(event.card.name=='sha'||get.type(event.card)=='trick'); + filter: function (event, player) { + return ( + player.isPhaseUsing() && (event.card.name == "sha" || get.type(event.card) == "trick") + ); }, - preHidden:true, - check:function(event,player){ - if(player.hasSkill('dcwanglie2',null,null,false)) return true; - if(['wuzhong','kaihua','dongzhuxianji'].includes(event.card.name)) return false; - player._wanglie_temp=true; - var eff=0; - for(var i of event.targets){ - eff+=get.effect(i,event.card,player,player); + preHidden: true, + check: function (event, player) { + if (player.hasSkill("dcwanglie2", null, null, false)) return true; + if (["wuzhong", "kaihua", "dongzhuxianji"].includes(event.card.name)) return false; + player._wanglie_temp = true; + var eff = 0; + for (var i of event.targets) { + eff += get.effect(i, event.card, player, player); } delete player._wanglie_temp; - if(eff<0) return true; - if(!player.countCards('h',function(card){ - return player.hasValueTarget(card,null,true); - })) return true; - if(get.tag(event.card,'damage')&&!player.needsToDiscard()&&!player.countCards('h',function(card){ - return get.tag(card,'damage')&&player.hasValueTarget(card,null,true); - })) return true; + if (eff < 0) return true; + if ( + !player.countCards("h", function (card) { + return player.hasValueTarget(card, null, true); + }) + ) + return true; + if ( + get.tag(event.card, "damage") && + !player.needsToDiscard() && + !player.countCards("h", function (card) { + return get.tag(card, "damage") && player.hasValueTarget(card, null, true); + }) + ) + return true; return false; }, - prompt2:function(event){ - return '令'+get.translation(event.card)+'不能被响应,然后本阶段你使用牌只能指定自己为目标' + prompt2: function (event) { + return ( + "令" + + get.translation(event.card) + + "不能被响应,然后本阶段你使用牌只能指定自己为目标" + ); }, - group:'dcwanglie_startup', - content:function(){ - trigger.nowuxie=true; + group: "dcwanglie_startup", + content: function () { + trigger.nowuxie = true; trigger.directHit.addArray(game.players); - player.addTempSkill('dcwanglie2','phaseUseAfter'); + player.addTempSkill("dcwanglie2", "phaseUseAfter"); }, - subSkill:{ - startup:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - popup:false, - content:function(){ - player.addTempSkill('dcwanglie_effect','phaseUseAfter'); + subSkill: { + startup: { + trigger: { player: "phaseUseBegin" }, + forced: true, + popup: false, + content: function () { + player.addTempSkill("dcwanglie_effect", "phaseUseAfter"); }, }, - effect:{ - forced:true, - charlotte:true, - firstDo:true, - popup:false, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return event.targets.some(target=>target!=player); + effect: { + forced: true, + charlotte: true, + firstDo: true, + popup: false, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return event.targets.some((target) => target != player); }, - content:function(){ - player.addMark('dcwanglie_effect',1,false); - if(player.countMark('dcwanglie_effect')>=2) player.removeSkill('dcwanglie_effect'); + content: function () { + player.addMark("dcwanglie_effect", 1, false); + if (player.countMark("dcwanglie_effect") >= 2) + player.removeSkill("dcwanglie_effect"); }, - onremove:true, + onremove: true, }, }, - ai:{ + ai: { //pretao:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { //if(tag=='pretao') return true; - if(player._wanglie_temp) return false; - player._wanglie_temp=true; - var bool=function(){ - if(['wuzhong','kaihua','dongzhuxianji'].includes(arg.card.name)) return false; - if(get.attitude(player,arg.target)>0||!player.isPhaseUsing()) return false; - var cards=player.getCards('h',function(card){ - return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card)); + if (player._wanglie_temp) return false; + player._wanglie_temp = true; + var bool = (function () { + if (["wuzhong", "kaihua", "dongzhuxianji"].includes(arg.card.name)) return false; + if (get.attitude(player, arg.target) > 0 || !player.isPhaseUsing()) return false; + var cards = player.getCards("h", function (card) { + return ( + card != arg.card && (!arg.card.cards || !arg.card.cards.includes(card)) + ); }); - var sha=player.getCardUsable('sha'); - if(arg.card.name=='sha') sha--; - cards=cards.filter(function(card){ - if(card.name=='sha'&&sha<=0) return false; - return player.hasValueTarget(card,null,true); + var sha = player.getCardUsable("sha"); + if (arg.card.name == "sha") sha--; + cards = cards.filter(function (card) { + if (card.name == "sha" && sha <= 0) return false; + return player.hasValueTarget(card, null, true); }); - if(!cards.length) return true; - if(!get.tag(arg.card,'damage')) return false; - if(!player.needsToDiscard()&&!cards.filter(function(card){ - return get.tag(card,'damage'); - }).length) return true; + if (!cards.length) return true; + if (!get.tag(arg.card, "damage")) return false; + if ( + !player.needsToDiscard() && + !cards.filter(function (card) { + return get.tag(card, "damage"); + }).length + ) + return true; return false; - }(); + })(); delete player._wanglie_temp; return bool; }, }, }, - dcwanglie2:{ - charlotte:true, - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; - } + dcwanglie2: { + charlotte: true, + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; + }, }, }, //周妃 - olliangyin:{ - audio:'liangyin', - trigger:{ - global:["loseAfter","addToExpansionAfter","cardsGotoSpecialAfter",'loseAsyncAfter'], + olliangyin: { + audio: "liangyin", + trigger: { + global: ["loseAfter", "addToExpansionAfter", "cardsGotoSpecialAfter", "loseAsyncAfter"], }, - filter:function(event,player,name){ - if(event.name=='lose'||event.name=='loseAsync') return event.getlx!==false&&event.toStorage==true; - if(event.name=='cardsGotoSpecial') return !event.notrigger; + filter: function (event, player, name) { + if (event.name == "lose" || event.name == "loseAsync") + return event.getlx !== false && event.toStorage == true; + if (event.name == "cardsGotoSpecial") return !event.notrigger; return true; }, - direct:true, - usable:1, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olliangyin'),'选择一名其他角色,你与其各摸一张牌',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,num=player.getExpansions('olkongsheng').length-1; - var att=get.attitude(player,target); - if(att<=0) return 0; - if(target.countCards('h')==num&&target.isDamaged()&&get.recoverEffect(target,player,player)>0) return 3*att; - return att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olliangyin',target); - game.asyncDraw([player,target].sortBySeat()); - } - else event.finish(); - 'step 2' - game.delayx(); - var num=player.getExpansions('olkongsheng').length; - var check=function(player){ - if(!player.isIn()||player.isHealthy()) return false; - return player.countCards('h')==num; - } - if(check(player)||check(target)){ - var choiceList=[ - '令自己回复1点体力', - '令'+get.translation(target)+'回复1点体力', - ]; - var choices=[]; - if(check(player)) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(check(target)) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('prompt','良姻:是否令一名角色回复体力?').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - var list=_status.event.controls.slice(0),eff1=0,eff2=0; - if(list.includes('选项一')) eff1=get.recoverEffect(player,player,player); - if(list.includes('选项二')) eff2=get.recoverEffect(target,player,player); - if(eff1>Math.max(0,eff2)) return '选项一'; - if(eff2>0) return '选项二'; - return 'cancel2'; + direct: true, + usable: 1, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olliangyin"), + "选择一名其他角色,你与其各摸一张牌", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player, + num = player.getExpansions("olkongsheng").length - 1; + var att = get.attitude(player, target); + if (att <= 0) return 0; + if ( + target.countCards("h") == num && + target.isDamaged() && + get.recoverEffect(target, player, player) > 0 + ) + return 3 * att; + return att; }); - } - else event.finish(); - 'step 3' - if(result.control=='选项一') player.recover(); - else if(result.control=='选项二') target.recover(); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olliangyin", target); + game.asyncDraw([player, target].sortBySeat()); + } else event.finish(); + "step 2"; + game.delayx(); + var num = player.getExpansions("olkongsheng").length; + var check = function (player) { + if (!player.isIn() || player.isHealthy()) return false; + return player.countCards("h") == num; + }; + if (check(player) || check(target)) { + var choiceList = [ + "令自己回复1点体力", + "令" + get.translation(target) + "回复1点体力", + ]; + var choices = []; + if (check(player)) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (check(target)) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", "良姻:是否令一名角色回复体力?") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + var list = _status.event.controls.slice(0), + eff1 = 0, + eff2 = 0; + if (list.includes("选项一")) eff1 = get.recoverEffect(player, player, player); + if (list.includes("选项二")) eff2 = get.recoverEffect(target, player, player); + if (eff1 > Math.max(0, eff2)) return "选项一"; + if (eff2 > 0) return "选项二"; + return "cancel2"; + }); + } else event.finish(); + "step 3"; + if (result.control == "选项一") player.recover(); + else if (result.control == "选项二") target.recover(); }, - group:'olliangyin_gain', - subSkill:{ - gain:{ - audio:'liangyin', - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + group: "olliangyin_gain", + subSkill: { + gain: { + audio: "liangyin", + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - var evt=event.getl(current); - return evt&&(evt.xs.length>0||evt.ss.length>0); + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + var evt = event.getl(current); + return evt && (evt.xs.length > 0 || evt.ss.length > 0); }); }, - usable:1, - content:function(){ - 'step 0' - if(!player.countCards('he')||!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - })) event.finish(); - else player.chooseCardTarget({ - prompt:get.prompt('olliangyin'), - prompt2:'弃置一张牌,并令一名其他角色也弃置一张牌', - position:'he', - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }, - ai1:function(card){ - let player=_status.event.player; - if(_status.event.me){ - if(get.position(card)===_status.event.me) return 12-player.hp-get.value(card); - return 0; - } - return 5-get.value(card); - }, - ai2:function(target){ - let player=_status.event.player,att=get.attitude(player,target); - if(att>0&&(_status.event.me||target.isHealthy())) return -att; - if(att>0&&(target.countCards('he')>target.hp||target.hasCard(function(card){ - return get.value(card,target)<=0; - },'e'))) return att; - return -att; - }, - me:function(){ - if(player.isHealthy()||get.recoverEffect(player,player,_status.event.player)<=0) return false; - let ph=player.countCards('h'),num=player.getExpansions('olkongsheng').length; - if(ph===num){ - if(player.hasSkillTag('noh')) return 'h'; - return 'e'; - } - if(ph-1===num) return 'h'; - return false; - }() - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olliangyin_gain',target); - player.discard(result.cards); - target.chooseToDiscard('he',true); - } - else event.finish(); - 'step 2' - game.delayx(); - var num=player.getExpansions('olkongsheng').length; - var check=function(player){ - if(!player.isIn()||player.isHealthy()) return false; - return player.countCards('h')==num; - } - if(check(player)||check(target)){ - var choiceList=[ - '令自己回复1点体力', - '令'+get.translation(target)+'回复1点体力', - ]; - var choices=[]; - if(check(player)) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(check(target)) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('prompt','良姻:是否令一名角色回复体力?').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - var list=_status.event.controls.slice(0),eff1=0,eff2=0; - if(list.includes('选项一')) eff1=get.recoverEffect(player,player,player); - if(list.includes('选项二')) eff2=get.recoverEffect(target,player,player); - if(eff1>Math.max(0,eff2)) return '选项一'; - if(eff2>0) return '选项二'; - return 'cancel2'; + usable: 1, + content: function () { + "step 0"; + if ( + !player.countCards("he") || + !game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; + }) + ) + event.finish(); + else + player.chooseCardTarget({ + prompt: get.prompt("olliangyin"), + prompt2: "弃置一张牌,并令一名其他角色也弃置一张牌", + position: "he", + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; + }, + ai1: function (card) { + let player = _status.event.player; + if (_status.event.me) { + if (get.position(card) === _status.event.me) + return 12 - player.hp - get.value(card); + return 0; + } + return 5 - get.value(card); + }, + ai2: function (target) { + let player = _status.event.player, + att = get.attitude(player, target); + if (att > 0 && (_status.event.me || target.isHealthy())) return -att; + if ( + att > 0 && + (target.countCards("he") > target.hp || + target.hasCard(function (card) { + return get.value(card, target) <= 0; + }, "e")) + ) + return att; + return -att; + }, + me: (function () { + if ( + player.isHealthy() || + get.recoverEffect(player, player, _status.event.player) <= 0 + ) + return false; + let ph = player.countCards("h"), + num = player.getExpansions("olkongsheng").length; + if (ph === num) { + if (player.hasSkillTag("noh")) return "h"; + return "e"; + } + if (ph - 1 === num) return "h"; + return false; + })(), }); - } - else event.finish(); - 'step 3' - if(result.control=='选项一') player.recover(); - else if(result.control=='选项二') target.recover(); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olliangyin_gain", target); + player.discard(result.cards); + target.chooseToDiscard("he", true); + } else event.finish(); + "step 2"; + game.delayx(); + var num = player.getExpansions("olkongsheng").length; + var check = function (player) { + if (!player.isIn() || player.isHealthy()) return false; + return player.countCards("h") == num; + }; + if (check(player) || check(target)) { + var choiceList = [ + "令自己回复1点体力", + "令" + get.translation(target) + "回复1点体力", + ]; + var choices = []; + if (check(player)) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (check(target)) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", "良姻:是否令一名角色回复体力?") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + var list = _status.event.controls.slice(0), + eff1 = 0, + eff2 = 0; + if (list.includes("选项一")) + eff1 = get.recoverEffect(player, player, player); + if (list.includes("选项二")) + eff2 = get.recoverEffect(target, player, player); + if (eff1 > Math.max(0, eff2)) return "选项一"; + if (eff2 > 0) return "选项二"; + return "cancel2"; + }); + } else event.finish(); + "step 3"; + if (result.control == "选项一") player.recover(); + else if (result.control == "选项二") target.recover(); }, }, }, }, - olkongsheng:{ - audio:'kongsheng', - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + olkongsheng: { + audio: "kongsheng", + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('he',[1,player.countCards('he')],get.prompt('olkongsheng'),'将任意张牌作为“箜”置于武将牌上').set('ai',function(card){ - var player=_status.event.player,num=player.getExpansions('olkongsheng')+ui.selected.cards.length; - if(ui.selected.cards.length>0&&game.hasPlayer(function(current){ - if(current.isHealthy()||get.recoverEffect(current,player,player)<=0) return false; - var num2=current.countCards('h',function(card){ - if(current!=player) return true; - return !ui.selected.cards.includes(card); - })+1; - return num==num2; - })) return 0; - if(get.type(card,null,false)=='equip'){ - for(var i of ui.selected.cards){ - if(get.type(i,null,false)=='equip') return 0; + content: function () { + "step 0"; + player + .chooseCard( + "he", + [1, player.countCards("he")], + get.prompt("olkongsheng"), + "将任意张牌作为“箜”置于武将牌上" + ) + .set("ai", function (card) { + var player = _status.event.player, + num = player.getExpansions("olkongsheng") + ui.selected.cards.length; + if ( + ui.selected.cards.length > 0 && + game.hasPlayer(function (current) { + if ( + current.isHealthy() || + get.recoverEffect(current, player, player) <= 0 + ) + return false; + var num2 = + current.countCards("h", function (card) { + if (current != player) return true; + return !ui.selected.cards.includes(card); + }) + 1; + return num == num2; + }) + ) + return 0; + if (get.type(card, null, false) == "equip") { + for (var i of ui.selected.cards) { + if (get.type(i, null, false) == "equip") return 0; + } + return 5 - get.value(card); } - return 5-get.value(card); - } - if(!player.hasValueTarget(card)) return 1; - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('olkongsheng'); - player.addToExpansion(result.cards,player,'give').gaintag.add('olkongsheng'); + if (!player.hasValueTarget(card)) return 1; + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("olkongsheng"); + player.addToExpansion(result.cards, player, "give").gaintag.add("olkongsheng"); } }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - group:'olkongsheng_kessoku', - subSkill:{ - kessoku:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.getExpansions('olkongsheng').filter(function(card){ - return get.type(card,false)!='equip'; - }).length>0; + group: "olkongsheng_kessoku", + subSkill: { + kessoku: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player.getExpansions("olkongsheng").filter(function (card) { + return get.type(card, false) != "equip"; + }).length > 0 + ); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('olkongsheng').filter(function(card){ - return get.type(card,false)!='equip'; + content: function () { + "step 0"; + var cards = player.getExpansions("olkongsheng").filter(function (card) { + return get.type(card, false) != "equip"; }); - if(cards.length) player.gain(cards,'gain2'); - 'step 1' - var cards=player.getExpansions('olkongsheng'); - if(cards.length>0){ - player.chooseTarget(true,'令一名角色使用以下装备牌',get.translation(cards)).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'losehp'},player,player); - }); - } - else event.finish(); - 'step 2' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - 'step 3' - var cards=player.getExpansions('olkongsheng').filter(function(i){ + if (cards.length) player.gain(cards, "gain2"); + "step 1"; + var cards = player.getExpansions("olkongsheng"); + if (cards.length > 0) { + player + .chooseTarget(true, "令一名角色使用以下装备牌", get.translation(cards)) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "losehp" }, player, player); + }); + } else event.finish(); + "step 2"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + "step 3"; + var cards = player.getExpansions("olkongsheng").filter(function (i) { return target.hasUseTarget(i); }); - if(cards.length==1){ - event._result={bool:true,links:cards} - } - else if(cards.length) target.chooseButton(true,['选择要使用的装备牌',cards]).set('ai',function(button){ - return get.order(button.link); - }); + if (cards.length == 1) { + event._result = { bool: true, links: cards }; + } else if (cards.length) + target + .chooseButton(true, ["选择要使用的装备牌", cards]) + .set("ai", function (button) { + return get.order(button.link); + }); else event.goto(5); - 'step 4' - if(result.bool){ - target.chooseUseTarget(result.links[0],true); + "step 4"; + if (result.bool) { + target.chooseUseTarget(result.links[0], true); event.goto(3); } - 'step 5' + "step 5"; target.loseHp(); }, }, }, }, //新毌丘俭 - zhengrong:{ - trigger:{player:'useCardToPlayered'}, - direct:true, - audio:'drlt_zhenrong', - filter:function(event,player){ - if(!event.isFirstTarget) return false; - if(!['basic','trick'].includes(get.type(event.card))) return false; - if(get.tag(event.card,'damage')) return game.hasPlayer(function(current){ - return event.targets.includes(current)&¤t.countCards('h')>=player.countCards('h')&¤t.countCards('he')>0; - }); + zhengrong: { + trigger: { player: "useCardToPlayered" }, + direct: true, + audio: "drlt_zhenrong", + filter: function (event, player) { + if (!event.isFirstTarget) return false; + if (!["basic", "trick"].includes(get.type(event.card))) return false; + if (get.tag(event.card, "damage")) + return game.hasPlayer(function (current) { + return ( + event.targets.includes(current) && + current.countCards("h") >= player.countCards("h") && + current.countCards("he") > 0 + ); + }); return false; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhengrong'),'将一名手牌数不小于你的目标角色的一张牌置于你的武将牌上,成为「荣」',function(card,player,target){ - return _status.event.targets.includes(target)&&target.countCards('h')>=player.countCards('h')&&target.countCards('he')>0; - }).set('ai',function(target){ - return (1-get.attitude(_status.event.player,target))/target.countCards('he'); - }).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=result.targets[0]; - player.logSkill('zhengrong',target); - player.choosePlayerCard(target,'he',true).ai=get.buttonValue; - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.links[0]; - player.addToExpansion(card,'give','log',target).gaintag.add('zhengrong'); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhengrong"), + "将一名手牌数不小于你的目标角色的一张牌置于你的武将牌上,成为「荣」", + function (card, player, target) { + return ( + _status.event.targets.includes(target) && + target.countCards("h") >= player.countCards("h") && + target.countCards("he") > 0 + ); + } + ) + .set("ai", function (target) { + return (1 - get.attitude(_status.event.player, target)) / target.countCards("he"); + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = result.targets[0]; + player.logSkill("zhengrong", target); + player.choosePlayerCard(target, "he", true).ai = get.buttonValue; + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.links[0]; + player.addToExpansion(card, "give", "log", target).gaintag.add("zhengrong"); } }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'荣', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "荣", + intro: { + content: "expansion", + markcount: "expansion", }, }, - hongju:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:'drlt_hongju', - forced:true, - unique:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - derivation:'qingce', - filter:function(event,player){ - return player.getExpansions('zhengrong').length>=3; + hongju: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: "drlt_hongju", + forced: true, + unique: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + derivation: "qingce", + filter: function (event, player) { + return player.getExpansions("zhengrong").length >= 3; }, - content:function(){ - 'step 0' - player.awakenSkill('hongju'); - var cards=player.getExpansions('zhengrong'); - if(!cards.length||!player.countCards('h')){ + content: function () { + "step 0"; + player.awakenSkill("hongju"); + var cards = player.getExpansions("zhengrong"); + if (!cards.length || !player.countCards("h")) { event.goto(2); return; } - var next=player.chooseToMove('征荣:是否交换“荣”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的“荣”',cards], - ['手牌区',player.getCards('h')], + var next = player.chooseToMove("征荣:是否交换“荣”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的“荣”", cards], + ["手牌区", player.getCards("h")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return get.value(a)-get.value(b); - }),cards2=cards.splice(0,player.getExpansions('zhengrong').length); - return [cards2,cards]; + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return get.value(a) - get.value(b); + }), + cards2 = cards.splice(0, player.getExpansions("zhengrong").length); + return [cards2, cards]; }); - 'step 1' - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('zhengrong')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.addToExpansion(pushs).gaintag.add('zhengrong'); - player.gain(gains,'gain2','log'); + "step 1"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("zhengrong")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.addToExpansion(pushs).gaintag.add("zhengrong"); + player.gain(gains, "gain2", "log"); } - 'step 2' - player.addSkills('qingce'); - game.log(player,'获得了技能','#g【清侧】'); + "step 2"; + player.addSkills("qingce"); + game.log(player, "获得了技能", "#g【清侧】"); player.loseMaxHp(); }, - }, - qingce:{ - enable:'phaseUse', - audio:'drlt_qingce', - filter:function(event,player){ - return player.getExpansions('zhengrong').length>0&&player.countCards('h')>0; + ai: { + combo: "zhengrong" }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('请选择要获得的「荣」',player.getExpansions('zhengrong'),'hidden'); + }, + qingce: { + enable: "phaseUse", + audio: "drlt_qingce", + filter: function (event, player) { + return player.getExpansions("zhengrong").length > 0 && player.countCards("h") > 0; + }, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "请选择要获得的「荣」", + player.getExpansions("zhengrong"), + "hidden" + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - card:links[0], - filterCard:true, - position:'h', - filterTarget:function(card,player,target){ - return target.countDiscardableCards(player,'ej')>0; + card: links[0], + filterCard: true, + position: "h", + filterTarget: function (card, player, target) { + return target.countDiscardableCards(player, "ej") > 0; }, - delay:false, - audio:'drlt_qingce', - content:lib.skill.qingce.contentx, - ai:{ - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - if(att>0&&(target.countCards('j')>0||target.countCards('e',function(card){ - return get.value(card,target)<0; - }))) return 2; - if(att<0&&target.countCards('e')>0&&!target.hasSkillTag('noe')) return -1; + delay: false, + audio: "drlt_qingce", + content: lib.skill.qingce.contentx, + ai: { + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if ( + att > 0 && + (target.countCards("j") > 0 || + target.countCards("e", function (card) { + return get.value(card, target) < 0; + })) + ) + return 2; + if ( + att < 0 && + target.countCards("e") > 0 && + !target.hasSkillTag("noe") + ) + return -1; return 0; }, }, }, - } + }; }, - prompt:function(links,player){ - return '选择弃置一张手牌,获得'+get.translation(links[0])+'并弃置一名角色装备区或判定区内的一张牌'; + prompt: function (links, player) { + return ( + "选择弃置一张手牌,获得" + + get.translation(links[0]) + + "并弃置一名角色装备区或判定区内的一张牌" + ); }, }, - contentx:function(){ - 'step 0' - var card=lib.skill.qingce_backup.card; - player.gain(card,'gain2','log'); - 'step 1' - if(target.countDiscardableCards(player,'ej')>0){ - player.discardPlayerCard('ej',true,target); + contentx: function () { + "step 0"; + var card = lib.skill.qingce_backup.card; + player.gain(card, "gain2", "log"); + "step 1"; + if (target.countDiscardableCards(player, "ej") > 0) { + player.discardPlayerCard("ej", true, target); } }, - ai:{ - order:8, - result:{ - player:function(player){ - if(game.hasPlayer(function(current){ - var att=get.attitude(player,current); - if((att>0&¤t.countCards('j')>0)||(att<0&¤t.countCards('e')>0)) return true; - return false; - })) return 1; + ai: { + order: 8, + result: { + player: function (player) { + if ( + game.hasPlayer(function (current) { + var att = get.attitude(player, current); + if ( + (att > 0 && current.countCards("j") > 0) || + (att < 0 && current.countCards("e") > 0) + ) + return true; + return false; + }) + ) + return 1; return 0; }, }, + combo: "qingce", }, }, //阴雷 - "drlt_zhenrong":{ - marktext:"荣", - intro:{ - content:'expansion', - markcount:'expansion', + drlt_zhenrong: { + marktext: "荣", + intro: { + content: "expansion", + markcount: "expansion", }, - audio:2, - trigger:{ - source:'damageSource', + audio: 2, + trigger: { + source: "damageSource", }, - filter:function(event,player){ - return event.player!=player&&event.player.countCards('h')>player.countCards('h'); + filter: function (event, player) { + return event.player != player && event.player.countCards("h") > player.countCards("h"); }, - direct:true, - content:function(){ - 'step 0' - player.choosePlayerCard('hej',get.prompt('drlt_zhenrong'),trigger.player).set('ai',function(button){ - return -get.attitude(player,trigger.player)+1; - }); - 'step 1' - if(result&&result.links&&result.links.length){ - player.line(player,trigger.player); - player.logSkill('drlt_zhenrong'); - player.addToExpansion(result.links,trigger.player,'give','log').gaintag.add('drlt_zhenrong'); + direct: true, + content: function () { + "step 0"; + player + .choosePlayerCard("hej", get.prompt("drlt_zhenrong"), trigger.player) + .set("ai", function (button) { + return -get.attitude(player, trigger.player) + 1; + }); + "step 1"; + if (result && result.links && result.links.length) { + player.line(player, trigger.player); + player.logSkill("drlt_zhenrong"); + player + .addToExpansion(result.links, trigger.player, "give", "log") + .gaintag.add("drlt_zhenrong"); } }, }, - "drlt_hongju":{ - skillAnimation:true, - animationColor:'thunder', - audio:2, - trigger:{ - player:'phaseZhunbeiBegin', + drlt_hongju: { + skillAnimation: true, + animationColor: "thunder", + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - unique:true, - juexingji:true, - derivation:['drlt_qingce'], - filter:function(event,player){ - return player.getExpansions('drlt_zhenrong').length>=3&&game.dead.length>0; + forced: true, + unique: true, + juexingji: true, + derivation: ["drlt_qingce"], + filter: function (event, player) { + return player.getExpansions("drlt_zhenrong").length >= 3 && game.dead.length > 0; }, - content:function(){ - 'step 0' - player.awakenSkill('drlt_hongju'); - var cards=player.getExpansions('drlt_zhenrong'); - if(!cards.length||!player.countCards('h')){ + content: function () { + "step 0"; + player.awakenSkill("drlt_hongju"); + var cards = player.getExpansions("drlt_zhenrong"); + if (!cards.length || !player.countCards("h")) { event.goto(2); return; } - var next=player.chooseToMove('征荣:是否交换“荣”和手牌?'); - next.set('list',[ - [get.translation(player)+'(你)的“荣”',cards], - ['手牌区',player.getCards('h')], + var next = player.chooseToMove("征荣:是否交换“荣”和手牌?"); + next.set("list", [ + [get.translation(player) + "(你)的“荣”", cards], + ["手牌区", player.getCards("h")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return get.value(a)-get.value(b); - }),cards2=cards.splice(0,player.getExpansions('drlt_zhenrong').length); - return [cards2,cards]; + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return get.value(a) - get.value(b); + }), + cards2 = cards.splice(0, player.getExpansions("drlt_zhenrong").length); + return [cards2, cards]; }); - 'step 1' - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('drlt_zhenrong')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.addToExpansion(pushs).gaintag.add('drlt_zhenrong'); - player.gain(gains,'gain2','log'); + "step 1"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("drlt_zhenrong")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.addToExpansion(pushs).gaintag.add("drlt_zhenrong"); + player.gain(gains, "gain2", "log"); } - 'step 2' - player.addSkills('drlt_qingce'); + "step 2"; + player.addSkills("drlt_qingce"); player.loseMaxHp(); }, + ai: { + combo: "drlt_zhengrong" + }, }, - 'drlt_qingce':{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.getExpansions('drlt_zhenrong').length>0; + drlt_qingce: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.getExpansions("drlt_zhenrong").length > 0; }, - filterTarget:function(card,player,target){ - return target.countDiscardableCards(player,'ej')>0; + filterTarget: function (card, player, target) { + return target.countDiscardableCards(player, "ej") > 0; }, - content:function(){ - 'step 0' - player.chooseCardButton(player.getExpansions('drlt_zhenrong'),1,'请选择需要弃置的“荣”',true).ai=function(button){ - return 6-get.value(button.link); + content: function () { + "step 0"; + player.chooseCardButton( + player.getExpansions("drlt_zhenrong"), + 1, + "请选择需要弃置的“荣”", + true + ).ai = function (button) { + return 6 - get.value(button.link); }; - 'step 1' - if(result.bool){ - var cards=result.links; + "step 1"; + if (result.bool) { + var cards = result.links; player.loseToDiscardpile(cards); - player.discardPlayerCard(target,'ej',1,true); + player.discardPlayerCard(target, "ej", 1, true); } }, - ai:{ - order:13, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0&&target.countCards('j')>0) return 1; + ai: { + order: 13, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0 && target.countCards("j") > 0) return 1; return -1; }, }, }, }, - "drlt_zhenggu":{ - audio:2, - trigger:{ - player:"phaseJieshuBegin", + drlt_zhenggu: { + audio: 2, + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('drlt_zhenggu'),function(card,player,target){ - //if(target.storage.drlt_zhenggu_mark&&target.storage.drlt_zhenggu_mark.includes(player)) return false; - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - //if(target.storage.drlt_zhenggu_mark&&target.storage.drlt_zhenggu_mark.includes(player)) return 0; - var num=(Math.min(5,player.countCards('h'))-target.countCards('h')); - var att=get.attitude(player,target); - return num*att; - }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('drlt_zhenggu',target); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("drlt_zhenggu"), function (card, player, target) { + //if(target.storage.drlt_zhenggu_mark&&target.storage.drlt_zhenggu_mark.includes(player)) return false; + return target != player; + }) + .set("ai", function (target) { + var player = _status.event.player; + //if(target.storage.drlt_zhenggu_mark&&target.storage.drlt_zhenggu_mark.includes(player)) return 0; + var num = Math.min(5, player.countCards("h")) - target.countCards("h"); + var att = get.attitude(player, target); + return num * att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("drlt_zhenggu", target); player.addSkill("drlt_zhenggu2"); target.addSkill("drlt_zhenggu_mark"); target.storage.drlt_zhenggu_mark.push(player); target.markSkill("drlt_zhenggu_mark"); - lib.skill.drlt_zhenggu.sync(player,target); + lib.skill.drlt_zhenggu.sync(player, target); } }, - sync:function(player,target){ - var num=player.countCards('h'); - var num2=target.countCards('h'); - if(num=2; + check: function (event, player) { + var num = 0; + if ( + player.hasHistory("lose", function (evt) { + return evt.type == "discard"; + }) + ) + num++; + if (!player.isMinHandcard()) num++; + if (!player.getStat("damage")) num++; + if (num == 3) return player.hp >= 2; return true; }, - prompt:function(event,player){ - var num=3; - if(player.hasHistory('lose',function(evt){ - return evt.type=='discard'; - })) num--; - if(!player.isMinHandcard()) num--; - if(!player.getStat('damage')) num--; - return get.prompt('xinfu_zuilun')+'(可获得'+get.cnNumber(num)+'张牌)' + prompt: function (event, player) { + var num = 3; + if ( + player.hasHistory("lose", function (evt) { + return evt.type == "discard"; + }) + ) + num--; + if (!player.isMinHandcard()) num--; + if (!player.getStat("damage")) num--; + return get.prompt("xinfu_zuilun") + "(可获得" + get.cnNumber(num) + "张牌)"; }, - content:function(){ - 'step 0' - event.num=0; - event.cards=get.cards(3); + content: function () { + "step 0"; + event.num = 0; + event.cards = get.cards(3); game.cardsGotoOrdering(cards); - if(player.hasHistory('lose',function(evt){ - return evt.type=='discard'; - })) event.num++; - if(!player.isMinHandcard()) event.num++; - if(!player.getStat('damage')) event.num++; - 'step 1' - if(event.num==0){ - player.gain(event.cards,'draw'); + if ( + player.hasHistory("lose", function (evt) { + return evt.type == "discard"; + }) + ) + event.num++; + if (!player.isMinHandcard()) event.num++; + if (!player.getStat("damage")) event.num++; + "step 1"; + if (event.num == 0) { + player.gain(event.cards, "draw"); event.finish(); - } - else{ - var prompt='罪论:将'+get.cnNumber(num)+'张牌置于牌堆顶'; - if(num<3) prompt+='并获得其余的牌'; - var next=player.chooseToMove(prompt,true); - if(num<3){ - next.set('list',[ - ['牌堆顶',cards], - ['获得'], - ]); - next.set('filterMove',function(from,to,moved){ - if(to==1&&moved[0].length<=_status.event.num) return false; + } else { + var prompt = "罪论:将" + get.cnNumber(num) + "张牌置于牌堆顶"; + if (num < 3) prompt += "并获得其余的牌"; + var next = player.chooseToMove(prompt, true); + if (num < 3) { + next.set("list", [["牌堆顶", cards], ["获得"]]); + next.set("filterMove", function (from, to, moved) { + if (to == 1 && moved[0].length <= _status.event.num) return false; return true; }); - next.set('filterOk',function(moved){ - return moved[0].length==_status.event.num; + next.set("filterOk", function (moved) { + return moved[0].length == _status.event.num; }); + } else { + next.set("list", [["牌堆顶", cards]]); } - else{ - next.set('list',[ - ['牌堆顶',cards], - ]); - } - next.set('num',num); - next.set('processAI',function(list){ - var check=function(card){ - var player=_status.event.player; - var next=player.next; - var att=get.attitude(player,next); - var judge=next.getCards('j')[tops.length]; - if(judge){ - return get.judge(judge)(card)*att; + next.set("num", num); + next.set("processAI", function (list) { + var check = function (card) { + var player = _status.event.player; + var next = player.next; + var att = get.attitude(player, next); + var judge = next.getCards("j")[tops.length]; + if (judge) { + return get.judge(judge)(card) * att; } - return next.getUseValue(card)*att; - } - var cards=list[0][1].slice(0),tops=[]; - while(tops.length<_status.event.num){ - list.sort(function(a,b){ - return check(b)-check(a); + return next.getUseValue(card) * att; + }; + var cards = list[0][1].slice(0), + tops = []; + while (tops.length < _status.event.num) { + list.sort(function (a, b) { + return check(b) - check(a); }); tops.push(cards.shift()); } - return [tops,cards]; + return [tops, cards]; }); } - 'step 2' - if(result.bool){ - var list=result.moved[0]; - var num=list.length-1; - for(var i=0;i0; + forced: true, + audio: 2, + filter: function (event, player) { + if (event.player.countCards("h") < player.countCards("h")) return false; + if (event.card.name != "sha" && event.card.name != "juedou") return false; + return !game.hasPlayer2(function (current) { + return ( + current.getHistory("useCard", function (evt) { + return ( + evt != event.getParent() && + evt.card && + ["sha", "juedou"].includes(evt.card.name) && + evt.targets.includes(player) + ); + }).length > 0 + ); }); }, - content:function(){ + content: function () { trigger.getParent().excluded.add(player); }, - ai:{ - effect:{ - target:function(card,player,target){ - let hs=player.getCards('h',i=>i!==card&&(!card.cards||!card.cards.includes(i))),num=player.getCardUsable('sha'); - if(card.name!=='sha'&&card.name!=='juedou'||hs.length0; - })) return 1; - if(card.name==='sha') num--; - hs=hs.filter(i=>{ - if(!player.canUse(i,target)) return false; - if(i.name==='juedou') return true; - if(num&&i.name==='sha'){ + ai: { + effect: { + target: function (card, player, target) { + let hs = player.getCards( + "h", + (i) => i !== card && (!card.cards || !card.cards.includes(i)) + ), + num = player.getCardUsable("sha"); + if ( + (card.name !== "sha" && card.name !== "juedou") || + hs.length < target.countCards("h") + ) + return 1; + if ( + game.hasPlayer2(function (current) { + return ( + current.getHistory("useCard", function (evt) { + return ( + evt.card && + ["sha", "juedou"].includes(evt.card.name) && + evt.targets.includes(player) + ); + }).length > 0 + ); + }) + ) + return 1; + if (card.name === "sha") num--; + hs = hs.filter((i) => { + if (!player.canUse(i, target)) return false; + if (i.name === "juedou") return true; + if (num && i.name === "sha") { num--; return true; } return false; }); - if(!hs.length) return 'zeroplayertarget'; - num=1-2/3/hs.length; - return [num,0,num,0]; - } - } - } - }, - "drlt_qianjie":{ - group:["drlt_qianjie_1","drlt_qianjie_2","drlt_qianjie_3"], - locked:true, - ai:{ - effect:{ - target:function(card){ - if(card.name=='tiesuo') return 'zeroplayertarget'; + if (!hs.length) return "zeroplayertarget"; + num = 1 - 2 / 3 / hs.length; + return [num, 0, num, 0]; }, }, }, - subSkill:{ - '1':{ - audio:'drlt_qianjie', - trigger:{ - player:'linkBegin' + }, + drlt_qianjie: { + group: ["drlt_qianjie_1", "drlt_qianjie_2", "drlt_qianjie_3"], + locked: true, + ai: { + effect: { + target: function (card) { + if (card.name == "tiesuo") return "zeroplayertarget"; }, - forced:true, - filter:function(event,player){ + }, + }, + subSkill: { + 1: { + audio: "drlt_qianjie", + trigger: { + player: "linkBegin", + }, + forced: true, + filter: function (event, player) { return !player.isLinked(); }, - content:function(){ + content: function () { trigger.cancel(); }, }, - '2':{ - mod:{ - targetEnabled:function(card,player,target){ - if(get.type(card)=='delay') return false; + 2: { + mod: { + targetEnabled: function (card, player, target) { + if (get.type(card) == "delay") return false; }, }, }, - '3':{ - ai:{noCompareTarget:true,}, + 3: { + ai: { noCompareTarget: true }, }, }, }, - 'drlt_jueyan':{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasEnabledSlot(1)||player.hasEnabledSlot(2)||player.hasEnabledSlot(5)||player.hasEnabledSlot('horse'); + drlt_jueyan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.hasEnabledSlot(1) || + player.hasEnabledSlot(2) || + player.hasEnabledSlot(5) || + player.hasEnabledSlot("horse") + ); }, - content:function(){ - 'step 0' - player.chooseToDisable(true).set('ai',function(event,player,list){ - if(list.includes('equip2')) return 'equip2'; - if(list.includes('equip1')&&(player.countCards('h',function(card){ - return get.name(card,player)=='sha'&&player.hasUseTarget(card); - })-player.getCardUsable('sha'))>1) return 'equip1'; - if(list.includes('equip5')&&player.countCards('h',function(card){ - return get.type2(card,player)=='trick'&&player.hasUseTarget(card); - })>1) return 'equip5'; + content: function () { + "step 0"; + player.chooseToDisable(true).set("ai", function (event, player, list) { + if (list.includes("equip2")) return "equip2"; + if ( + list.includes("equip1") && + player.countCards("h", function (card) { + return get.name(card, player) == "sha" && player.hasUseTarget(card); + }) - + player.getCardUsable("sha") > + 1 + ) + return "equip1"; + if ( + list.includes("equip5") && + player.countCards("h", function (card) { + return get.type2(card, player) == "trick" && player.hasUseTarget(card); + }) > 1 + ) + return "equip5"; }); - 'step 1' - switch(result.control){ - case 'equip1': - player.addTempSkill('drlt_jueyan1'); + "step 1"; + switch (result.control) { + case "equip1": + player.addTempSkill("drlt_jueyan1"); break; - case 'equip2': + case "equip2": player.draw(3); - player.addTempSkill('drlt_jueyan3'); + player.addTempSkill("drlt_jueyan3"); break; - case 'equip3_4': - player.addTempSkill('drlt_jueyan2'); + case "equip3_4": + player.addTempSkill("drlt_jueyan2"); break; - case 'equip5': - player.addTempSkills('rejizhi'); + case "equip5": + player.addTempSkills("rejizhi"); break; } }, - ai:{ - order:13, - result:{ - player:function(player){ - if(player.hasEnabledSlot('equip2')) return 1; - if(player.hasEnabledSlot('equip1')&&(player.countCards('h',function(card){ - return get.name(card,player)=='sha'&&player.hasValueTarget(card); - })-player.getCardUsable('sha'))>1) return 1; - if(player.hasEnabledSlot('equip5')&&player.countCards('h',function(card){ - return get.type2(card,player)=='trick'&&player.hasUseTarget(card); - })>1) return 1; + ai: { + order: 13, + result: { + player: function (player) { + if (player.hasEnabledSlot("equip2")) return 1; + if ( + player.hasEnabledSlot("equip1") && + player.countCards("h", function (card) { + return get.name(card, player) == "sha" && player.hasValueTarget(card); + }) - + player.getCardUsable("sha") > + 1 + ) + return 1; + if ( + player.hasEnabledSlot("equip5") && + player.countCards("h", function (card) { + return get.type2(card, player) == "trick" && player.hasUseTarget(card); + }) > 1 + ) + return 1; return -1; }, }, }, - derivation:'rejizhi', + derivation: "rejizhi", }, - 'drlt_jueyan1':{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+3; + drlt_jueyan1: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 3; }, }, - mark:true, - marktext:'决', - intro:{name:'决堰 - 武器',content:'本回合内可以多使用三张【杀】'}, + mark: true, + marktext: "决", + intro: { name: "决堰 - 武器", content: "本回合内可以多使用三张【杀】" }, }, - 'drlt_jueyan2':{ - mod:{ - targetInRange:function(card,player,target,now){ + drlt_jueyan2: { + mod: { + targetInRange: function (card, player, target, now) { return true; }, }, - mark:true, - marktext:'决', - intro:{name:'决堰 - 坐骑',content:'本回合内使用牌没有距离限制'}, + mark: true, + marktext: "决", + intro: { name: "决堰 - 坐骑", content: "本回合内使用牌没有距离限制" }, }, - 'drlt_jueyan3':{ - mod:{ - maxHandcard:function(player,num){ - return num+3; + drlt_jueyan3: { + mod: { + maxHandcard: function (player, num) { + return num + 3; }, }, - mark:true, - marktext:'决', - intro:{name:'决堰 - 防具',content:'本回合内手牌上限+3'}, + mark: true, + marktext: "决", + intro: { name: "决堰 - 防具", content: "本回合内手牌上限+3" }, }, - "drlt_poshi":{ - audio:2, - skillAnimation:true, - animationColor:'wood', - trigger:{ - player:'phaseZhunbeiBegin', + drlt_poshi: { + audio: 2, + skillAnimation: true, + animationColor: "wood", + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - unique:true, - juexingji:true, - derivation:['drlt_huairou'], - filter:function(event,player){ - return !player.hasEnabledSlot()||player.hp==1; + forced: true, + unique: true, + juexingji: true, + derivation: ["drlt_huairou"], + filter: function (event, player) { + return !player.hasEnabledSlot() || player.hp == 1; }, - content:function(){ - "step 0" - player.awakenSkill('drlt_poshi'); + content: function () { + "step 0"; + player.awakenSkill("drlt_poshi"); player.loseMaxHp(); - "step 1" - var num=player.maxHp-player.countCards('h'); - if(num>0) player.draw(num); - player.changeSkills(['drlt_huairou'],['drlt_jueyan']); + "step 1"; + var num = player.maxHp - player.countCards("h"); + if (num > 0) player.draw(num); + player.changeSkills(["drlt_huairou"], ["drlt_jueyan"]); }, }, - "drlt_huairou":{ - audio:2, - enable:"phaseUse", - position:'he', - filter:(event,player)=>player.hasCard(card=>lib.skill.drlt_huairou.filterCard(card,player),lib.skill.drlt_huairou.position), - filterCard:(card,player)=>get.type(card)=='equip'&&player.canRecast(card), - check:function(card){ - if(!_status.event.player.canEquip(card)) return 5; - return 3-get.value(card); + drlt_huairou: { + audio: 2, + enable: "phaseUse", + position: "he", + filter: (event, player) => + player.hasCard( + (card) => lib.skill.drlt_huairou.filterCard(card, player), + lib.skill.drlt_huairou.position + ), + filterCard: (card, player) => get.type(card) == "equip" && player.canRecast(card), + check: function (card) { + if (!_status.event.player.canEquip(card)) return 5; + return 3 - get.value(card); }, - content:function(){ + content: function () { player.recast(cards); }, - discard:false, - lose:false, - delay:false, - prompt:"将一张装备牌置入弃牌堆并摸一张牌", - ai:{ - order:10, - result:{ - player:1 - } - } + discard: false, + lose: false, + delay: false, + prompt: "将一张装备牌置入弃牌堆并摸一张牌", + ai: { + order: 10, + result: { + player: 1, + }, + }, }, - "drlt_yongsi":{ - audio:2, - group:["drlt_yongsi_1","drlt_yongsi_2"], - locked:true, - subSkill:{ - '1':{ - audio:"drlt_yongsi", - trigger:{ - player:'phaseDrawBegin2' + drlt_yongsi: { + audio: 2, + group: ["drlt_yongsi_1", "drlt_yongsi_2"], + locked: true, + subSkill: { + 1: { + audio: "drlt_yongsi", + trigger: { + player: "phaseDrawBegin2", }, - forced:true, - filter:function(event,player){ + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num=game.countGroup(); + content: function () { + trigger.num = game.countGroup(); }, }, - '2':{ - audio:"drlt_yongsi", - trigger:{ - player:'phaseUseEnd' + 2: { + audio: "drlt_yongsi", + trigger: { + player: "phaseUseEnd", }, - forced:true, - filter:function(event,player){ - var num=0; - player.getHistory('sourceDamage',function(evt){ - if(evt.getParent('phaseUse')==event) num+=evt.num; + forced: true, + filter: function (event, player) { + var num = 0; + player.getHistory("sourceDamage", function (evt) { + if (evt.getParent("phaseUse") == event) num += evt.num; }); - return !num||num>1; + return !num || num > 1; }, - content:function(){ - var numx=0; - player.getHistory('sourceDamage',function(evt){ - if(evt.getParent('phaseUse')==trigger) numx+=evt.num; + content: function () { + var numx = 0; + player.getHistory("sourceDamage", function (evt) { + if (evt.getParent("phaseUse") == trigger) numx += evt.num; }); - if(!numx){ - var num=player.hp-player.countCards('h'); - if(num>0) player.draw(num); - } - else{ - player.addTempSkill('drlt_yongsi1',{player:'phaseDiscardAfter'}); + if (!numx) { + var num = player.hp - player.countCards("h"); + if (num > 0) player.draw(num); + } else { + player.addTempSkill("drlt_yongsi1", { player: "phaseDiscardAfter" }); } }, }, }, }, - 'drlt_yongsi1':{ - mod:{ - maxHandcard:function(player,num){ - return num+player.maxHp-2*Math.max(0,player.hp); + drlt_yongsi1: { + mod: { + maxHandcard: function (player, num) { + return num + player.maxHp - 2 * Math.max(0, player.hp); }, }, }, - drlt_weidi:{ - audio:2, - forceaudio:true, - unique:true, - zhuSkill:true, - trigger:{ - player:"phaseDiscardBegin", + drlt_weidi: { + audio: 2, + forceaudio: true, + unique: true, + zhuSkill: true, + trigger: { + player: "phaseDiscardBegin", }, - direct:true, - filter:function(event,player){ - if(!player.hasZhuSkill('drlt_weidi')) return false; - return player.needsToDiscard()>0&&game.countPlayer(function(current){return current!=player&¤t.group=='qun'})>0; + direct: true, + filter: function (event, player) { + if (!player.hasZhuSkill("drlt_weidi")) return false; + return ( + player.needsToDiscard() > 0 && + game.countPlayer(function (current) { + return current != player && current.group == "qun"; + }) > 0 + ); }, - content:function(){ - 'step 0' - var num=Math.min(player.needsToDiscard(),game.countPlayer(function(target){ - return target!=player&&target.group=='qun'; - })); - if(num){ + content: function () { + "step 0"; + var num = Math.min( + player.needsToDiscard(), + game.countPlayer(function (target) { + return target != player && target.group == "qun"; + }) + ); + if (num) { player.chooseCardTarget({ - prompt:get.prompt('drlt_weidi'), - prompt2:'你可以将'+(num>1?'至多':'')+get.cnNumber(num)+'张手牌交给等量的其他群势力角色。先按顺序选中所有要给出的手牌,然后再按顺序选择等量的目标角色', - selectCard:[1,num], - selectTarget:function(){ + prompt: get.prompt("drlt_weidi"), + prompt2: + "你可以将" + + (num > 1 ? "至多" : "") + + get.cnNumber(num) + + "张手牌交给等量的其他群势力角色。先按顺序选中所有要给出的手牌,然后再按顺序选择等量的目标角色", + selectCard: [1, num], + selectTarget: function () { return ui.selected.cards.length; }, - filterTarget:function(card,player,target){ - return target!=player&&target.group=='qun'; + filterTarget: function (card, player, target) { + return target != player && target.group == "qun"; }, - complexSelect:true, - filterOk:function(){ - return ui.selected.cards.length==ui.selected.targets.length; + complexSelect: true, + filterOk: function () { + return ui.selected.cards.length == ui.selected.targets.length; }, - ai1:function(card){ - var player=_status.event.player; - var value=get.value(card,player,'raw'); - if(game.hasPlayer(function(target){ - return (target!=player&&target.group=='qun'&&!ui.selected.targets.includes(target))&&(get.sgn(value)==get.sgn(get.attitude(player,target))) - })) return 1/Math.max(1,get.useful(card)); + ai1: function (card) { + var player = _status.event.player; + var value = get.value(card, player, "raw"); + if ( + game.hasPlayer(function (target) { + return ( + target != player && + target.group == "qun" && + !ui.selected.targets.includes(target) && + get.sgn(value) == get.sgn(get.attitude(player, target)) + ); + }) + ) + return 1 / Math.max(1, get.useful(card)); return -1; }, - ai2:function(target){ - var player=_status.event.player; - var card=ui.selected.cards[ui.selected.targets.length]; - if(card&&get.value(card,player,'raw')<0) return -get.attitude(player,target); - return get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player; + var card = ui.selected.cards[ui.selected.targets.length]; + if (card && get.value(card, player, "raw") < 0) + return -get.attitude(player, target); + return get.attitude(player, target); }, }); - } - else event.finish(); - 'step 1' - if(result.bool&&result.cards.length>0){ - var list=[]; - for(var i=0;i 0) { + var list = []; + for (var i = 0; i < result.targets.length; i++) { + var target = result.targets[i]; + var card = result.cards[i]; + list.push([target, card]); } - player.logSkill('drlt_weidi',result.targets); + player.logSkill("drlt_weidi", result.targets); game.loseAsync({ - gain_list:list, - player:player, - cards:result.cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); - } - else event.finish(); + gain_list: list, + player: player, + cards: result.cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); + } else event.finish(); }, }, - "drlt_xiongluan":{ - audio:2, - unique:true, - enable:'phaseUse', - mark:true, - skillAnimation:true, - animationColor:'gray', - limited:true, - filter:function(event,player){ - return !player.isDisabledJudge()||player.hasEnabledSlot(); + drlt_xiongluan: { + audio: 2, + unique: true, + enable: "phaseUse", + mark: true, + skillAnimation: true, + animationColor: "gray", + limited: true, + filter: function (event, player) { + return !player.isDisabledJudge() || player.hasEnabledSlot(); }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - player.awakenSkill('drlt_xiongluan'); - var disables=[]; - for(var i=1;i<=5;i++){ - for(var j=0;j0) player.disableEquip(disables); + if (disables.length > 0) player.disableEquip(disables); player.disableJudge(); - player.addTempSkill('drlt_xiongluan1'); - player.storage.drlt_xiongluan1=target; - target.addSkill('drlt_xiongluan2'); - target.markSkillCharacter('drlt_xiongluan1',player,'雄乱','无法使用或打出任何手牌'); + player.addTempSkill("drlt_xiongluan1"); + player.storage.drlt_xiongluan1 = target; + target.addSkill("drlt_xiongluan2"); + target.markSkillCharacter("drlt_xiongluan1", player, "雄乱", "无法使用或打出任何手牌"); }, - ai:{ - order:13, - result:{ - target:(player,target)=>{ - let hs=player.countCards('h',card=>{ - if(!get.tag(card,'damage')||get.effect(target,card,player,player)<=0) return 0; - if(get.name(card,player)==='sha'){ - if(target.getEquip('bagua')) return 0.5; - if(target.getEquip('rewrite_bagua')) return 0.25; - } - return 1; - }),ts=target.hp+target.hujia+game.countPlayer(current=>{ - if(get.attitude(current,target)>0) return current.countCards('hs')/8; - return 0; - }); - if(hs>=ts) return -hs; + ai: { + order: 13, + result: { + target: (player, target) => { + let hs = player.countCards("h", (card) => { + if ( + !get.tag(card, "damage") || + get.effect(target, card, player, player) <= 0 + ) + return 0; + if (get.name(card, player) === "sha") { + if (target.getEquip("bagua")) return 0.5; + if (target.getEquip("rewrite_bagua")) return 0.25; + } + return 1; + }), + ts = + target.hp + + target.hujia + + game.countPlayer((current) => { + if (get.attitude(current, target) > 0) + return current.countCards("hs") / 8; + return 0; + }); + if (hs >= ts) return -hs; return 0; }, }, }, - intro:{ - content:'limited' + intro: { + content: "limited", }, }, - 'drlt_xiongluan1':{ - onremove:function(player){ - player.storage.drlt_xiongluan1.removeSkill('drlt_xiongluan2'); - player.storage.drlt_xiongluan1.unmarkSkill('drlt_xiongluan1'); + drlt_xiongluan1: { + onremove: function (player) { + player.storage.drlt_xiongluan1.removeSkill("drlt_xiongluan2"); + player.storage.drlt_xiongluan1.unmarkSkill("drlt_xiongluan1"); delete player.storage.drlt_xiongluan1; }, - mod:{ - targetInRange:function(card,player,target){ - if(target.hasSkill('drlt_xiongluan2')){ + mod: { + targetInRange: function (card, player, target) { + if (target.hasSkill("drlt_xiongluan2")) { return true; } }, - cardUsableTarget:function(card,player,target){ - if(target.hasSkill('drlt_xiongluan2')) return true; + cardUsableTarget: function (card, player, target) { + if (target.hasSkill("drlt_xiongluan2")) return true; }, }, - charlotte:true, + charlotte: true, }, - 'drlt_xiongluan2':{ - mod:{ - cardEnabled2:function(card,player){ - if(get.position(card)=='h') return false; + drlt_xiongluan2: { + mod: { + cardEnabled2: function (card, player) { + if (get.position(card) == "h") return false; }, }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return [0,-999999]; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) return [0, -999999]; }, }, }, - charlotte:true, + charlotte: true, }, - "drlt_congjian":{ - audio:2, - audioname2:{tongyuan:'ocongjian_tongyuan'}, - trigger:{ - target:"useCardToTargeted", + drlt_congjian: { + audio: 2, + audioname2: { tongyuan: "ocongjian_tongyuan" }, + trigger: { + target: "useCardToTargeted", }, - direct:true, - filter:function(event,player){ - return get.type(event.card)=='trick'&&event.targets.length>1&&player.countCards('he')>0; + direct: true, + filter: function (event, player) { + return ( + get.type(event.card) == "trick" && + event.targets.length > 1 && + player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:true, - selectCard:1, - position:'he', - filterTarget:function(card,player,target){ - return player!=target&&_status.event.targets.includes(target); + filterCard: true, + selectCard: 1, + position: "he", + filterTarget: function (card, player, target) { + return player != target && _status.event.targets.includes(target); }, - ai1:function(card){ - if(card.name=='du') return 20; - if(_status.event.player.storage.drlt_xiongluan&&get.type(card)=="equip") return 15; - return 6-get.value(card); + ai1: function (card) { + if (card.name == "du") return 20; + if (_status.event.player.storage.drlt_xiongluan && get.type(card) == "equip") + return 15; + return 6 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0.1; - return 1-att; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0.1; + return 1 - att; } - return att-3; + return att - 3; }, - prompt:get.prompt2('drlt_congjian'), - targets:trigger.targets, + prompt: get.prompt2("drlt_congjian"), + targets: trigger.targets, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('drlt_congjian',target); - player.give(result.cards,target,'give'); - var num=1; - if(get.type(result.cards[0])=='equip') num=2; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("drlt_congjian", target); + player.give(result.cards, target, "give"); + var num = 1; + if (get.type(result.cards[0]) == "equip") num = 2; player.draw(num); } }, }, - drlt_wanglie:{ - locked:false, - mod:{ - targetInRange:function(card,player,target,now){ - if(game.online){ - if(!player.countUsed()) return true; - } - else{ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'&&player.getHistory('useCard',function(evt2){ - return evt2.getParent('phaseUse')==evt - }).length==0) return true; + drlt_wanglie: { + locked: false, + mod: { + targetInRange: function (card, player, target, now) { + if (game.online) { + if (!player.countUsed()) return true; + } else { + var evt = _status.event.getParent("phaseUse"); + if ( + evt && + evt.name == "phaseUse" && + player.getHistory("useCard", function (evt2) { + return evt2.getParent("phaseUse") == evt; + }).length == 0 + ) + return true; } }, }, - audio:2, - trigger:{ - player:"useCard", + audio: 2, + trigger: { + player: "useCard", }, - filter:function(event,player){ - return player.isPhaseUsing()&&(event.card.name=='sha'||get.type(event.card)=='trick'); + filter: function (event, player) { + return ( + player.isPhaseUsing() && (event.card.name == "sha" || get.type(event.card) == "trick") + ); }, - preHidden:true, - check:function(event,player){ - if(['wuzhong','kaihua','dongzhuxianji'].includes(event.card.name)) return false; - player._wanglie_temp=true; - var eff=0; - for(var i of event.targets){ - eff+=get.effect(i,event.card,player,player); + preHidden: true, + check: function (event, player) { + if (["wuzhong", "kaihua", "dongzhuxianji"].includes(event.card.name)) return false; + player._wanglie_temp = true; + var eff = 0; + for (var i of event.targets) { + eff += get.effect(i, event.card, player, player); } delete player._wanglie_temp; - if(eff<0) return true; - if(!player.countCards('h',function(card){ - return player.hasValueTarget(card,null,true); - })) return true; - if(get.tag(event.card,'damage')&&!player.needsToDiscard()&&!player.countCards('h',function(card){ - return get.tag(card,'damage')&&player.hasValueTarget(card,null,true); - })) return true; + if (eff < 0) return true; + if ( + !player.countCards("h", function (card) { + return player.hasValueTarget(card, null, true); + }) + ) + return true; + if ( + get.tag(event.card, "damage") && + !player.needsToDiscard() && + !player.countCards("h", function (card) { + return get.tag(card, "damage") && player.hasValueTarget(card, null, true); + }) + ) + return true; return false; }, - prompt2:function(event){ - return '令'+get.translation(event.card)+'不能被响应,然后本阶段不能再使用牌' + prompt2: function (event) { + return "令" + get.translation(event.card) + "不能被响应,然后本阶段不能再使用牌"; }, - content:function(){ - trigger.nowuxie=true; + content: function () { + trigger.nowuxie = true; trigger.directHit.addArray(game.players); - player.addTempSkill('drlt_wanglie2','phaseUseAfter'); + player.addTempSkill("drlt_wanglie2", "phaseUseAfter"); }, - ai:{ - pretao:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='pretao') return true; - if(player._wanglie_temp) return false; - player._wanglie_temp=true; - var bool=function(){ - if(['wuzhong','kaihua','dongzhuxianji'].includes(arg.card.name)) return false; - if(get.attitude(player,arg.target)>0||!player.isPhaseUsing()) return false; - var cards=player.getCards('h',function(card){ - return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card)); + ai: { + pretao: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "pretao") return true; + if (player._wanglie_temp) return false; + player._wanglie_temp = true; + var bool = (function () { + if (["wuzhong", "kaihua", "dongzhuxianji"].includes(arg.card.name)) return false; + if (get.attitude(player, arg.target) > 0 || !player.isPhaseUsing()) return false; + var cards = player.getCards("h", function (card) { + return ( + card != arg.card && (!arg.card.cards || !arg.card.cards.includes(card)) + ); }); - var sha=player.getCardUsable('sha'); - if(arg.card.name=='sha') sha--; - cards=cards.filter(function(card){ - if(card.name=='sha'&&sha<=0) return false; - return player.hasValueTarget(card,null,true); + var sha = player.getCardUsable("sha"); + if (arg.card.name == "sha") sha--; + cards = cards.filter(function (card) { + if (card.name == "sha" && sha <= 0) return false; + return player.hasValueTarget(card, null, true); }); - if(!cards.length) return true; - if(!get.tag(arg.card,'damage')) return false; - if(!player.needsToDiscard()&&!cards.filter(function(card){ - return get.tag(card,'damage'); - }).length) return true; + if (!cards.length) return true; + if (!get.tag(arg.card, "damage")) return false; + if ( + !player.needsToDiscard() && + !cards.filter(function (card) { + return get.tag(card, "damage"); + }).length + ) + return true; return false; - }(); + })(); delete player._wanglie_temp; return bool; }, }, }, - "drlt_wanglie2":{ - mod:{ - cardEnabled:function(card,player){ + drlt_wanglie2: { + mod: { + cardEnabled: function (card, player) { return false; }, }, }, - liangyin:{ - audio:2, - group:["liangyin_1","liangyin_2"], - subSkill:{ - "1":{ - trigger:{ - global:["loseAfter","addToExpansionAfter","cardsGotoSpecialAfter",'loseAsyncAfter'], + liangyin: { + audio: 2, + group: ["liangyin_1", "liangyin_2"], + subSkill: { + 1: { + trigger: { + global: [ + "loseAfter", + "addToExpansionAfter", + "cardsGotoSpecialAfter", + "loseAsyncAfter", + ], }, - filter:function(event,player,name){ - if(event.name=='lose'||event.name=='loseAsync') return event.getlx!==false&&event.toStorage==true; - if(event.name=='cardsGotoSpecial') return !event.notrigger; + filter: function (event, player, name) { + if (event.name == "lose" || event.name == "loseAsync") + return event.getlx !== false && event.toStorage == true; + if (event.name == "cardsGotoSpecial") return !event.notrigger; return true; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget('是否发动【良姻】令手牌数大于你的一名角色摸一张牌?',function(card,player,target){ - return target!=player&&target.countCards('h')>player.countCards('h'); - }).ai=function(target){ - return get.attitude(player,target); + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + "是否发动【良姻】令手牌数大于你的一名角色摸一张牌?", + function (card, player, target) { + return ( + target != player && target.countCards("h") > player.countCards("h") + ); + } + ).ai = function (target) { + return get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('liangyin',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("liangyin", result.targets); result.targets[0].draw(); } }, - sub:true, + sub: true, }, - "2":{ - trigger:{ - global:"gainAfter", + 2: { + trigger: { + global: "gainAfter", }, - filter:function(event,player){ - return event.fromStorage==true||game.hasPlayer2(function(current){ - var evt=event.getl(current); - return evt&&evt.xs&&evt.xs.length>0; - }); + filter: function (event, player) { + return ( + event.fromStorage == true || + game.hasPlayer2(function (current) { + var evt = event.getl(current); + return evt && evt.xs && evt.xs.length > 0; + }) + ); }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget('是否发动【良姻】令手牌数小于你的一名角色弃置一张牌?',function(card,player,target){ - return target!=player&&target.countCards('h')0; - }).ai=function(target){ - return -get.attitude(player,target); + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + "是否发动【良姻】令手牌数小于你的一名角色弃置一张牌?", + function (card, player, target) { + return ( + target != player && + target.countCards("h") < player.countCards("h") && + target.countCards("he") > 0 + ); + } + ).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('liangyin',result.targets); - result.targets[0].chooseToDiscard('he',1,true); + "step 1"; + if (result.bool) { + player.logSkill("liangyin", result.targets); + result.targets[0].chooseToDiscard("he", 1, true); } }, - sub:true, + sub: true, }, }, }, - kongsheng:{ - audio:2, - trigger:{ - player:"phaseZhunbeiBegin", + kongsheng: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt('kongsheng'),'将任意张牌置于武将牌上','he',[1,player.countCards('he')]).set('ai',function(card){ - if(get.position(card)=='e') return 1-get.value(card); - if(card.name=='shan'||card.name=='du'||!player.hasValueTarget(card)) return 1; - return 4-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('kongsheng'); - player.addSkill('kongsheng2'); - player.addToExpansion(result.cards,'log','give',player).gaintag.add('kongsheng2'); + content: function () { + "step 0"; + player + .chooseCard(get.prompt("kongsheng"), "将任意张牌置于武将牌上", "he", [ + 1, + player.countCards("he"), + ]) + .set("ai", function (card) { + if (get.position(card) == "e") return 1 - get.value(card); + if (card.name == "shan" || card.name == "du" || !player.hasValueTarget(card)) + return 1; + return 4 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("kongsheng"); + player.addSkill("kongsheng2"); + player.addToExpansion(result.cards, "log", "give", player).gaintag.add("kongsheng2"); } }, }, - kongsheng_ai:{ai:{reverseOrder:true}}, - kongsheng2:{ - audio:'kongsheng', - marktext:"箜", - intro:{ - content:"expansion", - markcount:'expansion', + kongsheng_ai: { ai: { reverseOrder: true } }, + kongsheng2: { + audio: "kongsheng", + marktext: "箜", + intro: { + content: "expansion", + markcount: "expansion", }, - trigger:{ - player:"phaseJieshuBegin", + trigger: { + player: "phaseJieshuBegin", }, - filter:function(event,player){ - return player.getExpansions('kongsheng2').length>0; + filter: function (event, player) { + return player.getExpansions("kongsheng2").length > 0; }, - forced:true, - charlotte:true, - content:function(){ - 'step 0' - player.addTempSkill('kongsheng_ai','kongsheng2After'); - 'step 1' - var cards=player.getExpansions('kongsheng2').filter(function(i){ - return get.type(i,false)=='equip'&&player.hasUseTarget(i); - }); - if(cards.length==1){ - event._result={bool:true,links:cards} - } - else if(cards.length) player.chooseButton(true,['选择要使用的装备牌',cards]).set('ai',function(button){ - return get.order(button.link); + forced: true, + charlotte: true, + content: function () { + "step 0"; + player.addTempSkill("kongsheng_ai", "kongsheng2After"); + "step 1"; + var cards = player.getExpansions("kongsheng2").filter(function (i) { + return get.type(i, false) == "equip" && player.hasUseTarget(i); }); + if (cards.length == 1) { + event._result = { bool: true, links: cards }; + } else if (cards.length) + player.chooseButton(true, ["选择要使用的装备牌", cards]).set("ai", function (button) { + return get.order(button.link); + }); else event.goto(3); - 'step 2' - if(result.bool){ - player.chooseUseTarget(result.links[0],true); + "step 2"; + if (result.bool) { + player.chooseUseTarget(result.links[0], true); event.goto(1); } - 'step 3' - var cards=player.getExpansions('kongsheng2'); - if(cards.length) player.gain(cards,'gain2'); + "step 3"; + var cards = player.getExpansions("kongsheng2"); + if (cards.length) player.gain(cards, "gain2"); }, }, - nzry_juzhan:{ - audio:"nzry_juzhan_1", - mark:true, - locked:false, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player,skill){ - if(player.storage.nzry_juzhan==true) return '当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌'; - return '当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌'; + nzry_juzhan: { + audio: "nzry_juzhan_1", + mark: true, + locked: false, + zhuanhuanji: true, + marktext: "☯", + intro: { + content: function (storage, player, skill) { + if (player.storage.nzry_juzhan == true) + return "当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌"; + return "当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌"; }, }, - group:["nzry_juzhan_1","nzry_juzhan_2"], - subSkill:{ - '1':{ - audio:2, - trigger:{ - target:'useCardToTargeted' + group: ["nzry_juzhan_1", "nzry_juzhan_2"], + subSkill: { + 1: { + audio: 2, + trigger: { + target: "useCardToTargeted", }, - prompt2:'当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。', - filter:function(event,player){ - return event.card.name=='sha'&&!player.storage.nzry_juzhan; + prompt2: + "当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。", + filter: function (event, player) { + return event.card.name == "sha" && !player.storage.nzry_juzhan; }, - logTarget:'player', - content:function(){ - 'step 0' - game.asyncDraw([player,trigger.player]); - trigger.player.addTempSkill('nzry_juzhany'); - player.changeZhuanhuanji('nzry_juzhan'); - player.addTempSkill('nzry_juzhanx'); - 'step 1' + logTarget: "player", + content: function () { + "step 0"; + game.asyncDraw([player, trigger.player]); + trigger.player.addTempSkill("nzry_juzhany"); + player.changeZhuanhuanji("nzry_juzhan"); + player.addTempSkill("nzry_juzhanx"); + "step 1"; game.delayx(); }, }, - '2':{ - audio:"nzry_juzhan_1", - trigger:{ - player:'useCardToPlayered' + 2: { + audio: "nzry_juzhan_1", + trigger: { + player: "useCardToPlayered", }, - prompt2:'当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌', - filter:function(event,player){ - return event.card.name=='sha'&&player.storage.nzry_juzhan==true&&event.target.countGainableCards(player,'he')>0; + prompt2: + "当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌", + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.storage.nzry_juzhan == true && + event.target.countGainableCards(player, "he") > 0 + ); }, - check:function(event,player){ - return event.player.countCards('he')>0&&event.targets&&event.targets.length==1; + check: function (event, player) { + return ( + event.player.countCards("he") > 0 && + event.targets && + event.targets.length == 1 + ); }, - logTarget:'target', - content:function(){ - player.gainPlayerCard(trigger.targets[0],'he',true); - player.changeZhuanhuanji('nzry_juzhan'); - trigger.target.addTempSkill('nzry_juzhanx'); - player.addTempSkill('nzry_juzhany'); + logTarget: "target", + content: function () { + player.gainPlayerCard(trigger.targets[0], "he", true); + player.changeZhuanhuanji("nzry_juzhan"); + trigger.target.addTempSkill("nzry_juzhanx"); + player.addTempSkill("nzry_juzhany"); }, }, }, }, - nzry_juzhanx:{ - mod:{ - targetEnabled:function(card,player,target){ - if(player.hasSkill('nzry_juzhany')) return false; + nzry_juzhanx: { + mod: { + targetEnabled: function (card, player, target) { + if (player.hasSkill("nzry_juzhany")) return false; }, }, }, - nzry_juzhany:{}, - nzry_feijun:{ - init:(player)=>{ - if(!Array.isArray(player.storage.nzry_feijun)) player.storage.nzry_feijun=[]; + nzry_juzhany: {}, + nzry_feijun: { + init: (player) => { + if (!Array.isArray(player.storage.nzry_feijun)) player.storage.nzry_feijun = []; }, - intro:{ - content:function(storage){ - if(!storage||!storage.length) return '尚未发动'; - var str=get.translation(storage); - return '已对'+str+'发动过〖飞军〗'; + intro: { + content: function (storage) { + if (!storage || !storage.length) return "尚未发动"; + var str = get.translation(storage); + return "已对" + str + "发动过〖飞军〗"; }, }, - mark:true, - enable:"phaseUse", - usable:1, - position:"he", - audio:2, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>=player.countCards('h'); - })||game.hasPlayer(function(current){ - return current.countCards('e')>=player.countCards('e'); - })>0; + mark: true, + enable: "phaseUse", + usable: 1, + position: "he", + audio: 2, + filter: function (event, player) { + return ( + game.hasPlayer(function (current) { + return current.countCards("h") >= player.countCards("h"); + }) || + game.hasPlayer(function (current) { + return current.countCards("e") >= player.countCards("e"); + }) > 0 + ); }, - filterCard:true, - check:function(card){ - return 5-get.value(card); + filterCard: true, + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - 'step 0' - var list=[]; - if(game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h'); - })) list.push('令一名手牌数大于你的角色交给你一张牌'); - if(game.hasPlayer(function(current){ - return current.countCards('e')>player.countCards('e'); - })>0) list.push('令一名装备区内牌数大于你的角色弃置一张装备牌'); - if(list.length==0) event.finish(); - else if(list.length<2){ - if(game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h'); - })) event._result={index:0}; - else event._result={index:1}; + content: function () { + "step 0"; + var list = []; + if ( + game.hasPlayer(function (current) { + return current.countCards("h") > player.countCards("h"); + }) + ) + list.push("令一名手牌数大于你的角色交给你一张牌"); + if ( + game.hasPlayer(function (current) { + return current.countCards("e") > player.countCards("e"); + }) > 0 + ) + list.push("令一名装备区内牌数大于你的角色弃置一张装备牌"); + if (list.length == 0) event.finish(); + else if (list.length < 2) { + if ( + game.hasPlayer(function (current) { + return current.countCards("h") > player.countCards("h"); + }) + ) + event._result = { index: 0 }; + else event._result = { index: 1 }; + } else { + player + .chooseControl() + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + return ( + current.countCards("h") > player.countCards("h") && + get.attitude(player, current) < 0 + ); + }) + ) + return 0; + return 1; + }) + .set("choiceList", list); } - else{ - player.chooseControl().set('ai',function(){ - if(game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h')&&get.attitude(player,current)<0 - })) return 0; - return 1; - }).set('choiceList',list); - } - 'step 1' - event.index=result.index; - if(result.index==0){ - player.chooseTarget(function(card,player,target){ - return target!=player&&target.countCards('h')>player.countCards('h'); - },'选择一名手牌数大于你的角色').set('ai',function(target){ - return -get.attitude(player,target) - }); - } - else{ - player.chooseTarget(function(card,player,target){ - return target.countCards('e')>player.countCards('e')&&target!=player; - },'选择一名装备区里牌数大于你的角色').ai=function(target){ - return -get.attitude(player,target) + "step 1"; + event.index = result.index; + if (result.index == 0) { + player + .chooseTarget(function (card, player, target) { + return target != player && target.countCards("h") > player.countCards("h"); + }, "选择一名手牌数大于你的角色") + .set("ai", function (target) { + return -get.attitude(player, target); + }); + } else { + player.chooseTarget(function (card, player, target) { + return target.countCards("e") > player.countCards("e") && target != player; + }, "选择一名装备区里牌数大于你的角色").ai = function (target) { + return -get.attitude(player, target); }; } - 'step 2' - if(result.bool){ - event.target=result.targets[0]; - var list=player.getStorage('nzry_feijun'); - if(!list.includes(event.target)){ - event._nzry_binglve=true; - player.markAuto('nzry_feijun',[event.target]); + "step 2"; + if (result.bool) { + event.target = result.targets[0]; + var list = player.getStorage("nzry_feijun"); + if (!list.includes(event.target)) { + event._nzry_binglve = true; + player.markAuto("nzry_feijun", [event.target]); } - player.line(event.target,'green'); - if(event.index==0){ - event.target.chooseCard('he',true,'选择一张牌交给'+get.translation(player)).set('ai',function(card){ - return 6-get.value(card); - }); - } - else{ - event.target.chooseToDiscard('he',true,{type:'equip'},'请弃置一张装备牌'); + player.line(event.target, "green"); + if (event.index == 0) { + event.target + .chooseCard("he", true, "选择一张牌交给" + get.translation(player)) + .set("ai", function (card) { + return 6 - get.value(card); + }); + } else { + event.target.chooseToDiscard("he", true, { type: "equip" }, "请弃置一张装备牌"); event.finish(); } - } - else{ + } else { event.finish(); } - 'step 3' - if(result.bool){ - target.give(result.cards,player); + "step 3"; + if (result.bool) { + target.give(result.cards, player); } }, - ai:{ - order:11, - result:{ - player:function(player){ - if(game.hasPlayer(function(current){ - return (current.countCards('h')>player.countCards('h')||current.countCards('e')>player.countCards('e'))&&get.attitude(player,current)<0&&player.getStorage('nzry_feijun').includes(current); - })||game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h')&&get.attitude(player,current)<0; - })||(player.countCards('h')>=2&&game.hasPlayer(function(current){ - return current.countCards('e')>player.countCards('e')&&get.attitude(player,current)<0; - }))) return 1; + ai: { + order: 11, + result: { + player: function (player) { + if ( + game.hasPlayer(function (current) { + return ( + (current.countCards("h") > player.countCards("h") || + current.countCards("e") > player.countCards("e")) && + get.attitude(player, current) < 0 && + player.getStorage("nzry_feijun").includes(current) + ); + }) || + game.hasPlayer(function (current) { + return ( + current.countCards("h") > player.countCards("h") && + get.attitude(player, current) < 0 + ); + }) || + (player.countCards("h") >= 2 && + game.hasPlayer(function (current) { + return ( + current.countCards("e") > player.countCards("e") && + get.attitude(player, current) < 0 + ); + })) + ) + return 1; }, }, }, }, - nzry_binglve:{ - audio:2, - trigger:{player:'nzry_feijunAfter'}, - forced:true, - filter:function(event,player){ - return event._nzry_binglve==true; + nzry_binglve: { + audio: 2, + trigger: { player: "nzry_feijunAfter" }, + forced: true, + filter: function (event, player) { + return event._nzry_binglve == true; }, - content:function(){ - player.draw(2) + content: function () { + player.draw(2); }, - ai:{combo:'nzry_feijun'}, + ai: { combo: "nzry_feijun" }, }, - nzry_huaiju_ai:{ - charlotte:true, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(!player.hasMark('nzry_huaiju')) return false; - if(!game.hasPlayer(function(current){ - return current.hasSkill('tachibana_effect'); - })) return false; - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + nzry_huaiju_ai: { + charlotte: true, + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (!player.hasMark("nzry_huaiju")) return false; + if ( + !game.hasPlayer(function (current) { + return current.hasSkill("tachibana_effect"); + }) + ) + return false; + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, - "nzry_huaiju":{ - marktext:"橘", - intro:{ - name:'怀橘', - name2:'橘', - content:'当前有#个“橘”', + nzry_huaiju: { + marktext: "橘", + intro: { + name: "怀橘", + name2: "橘", + content: "当前有#个“橘”", }, - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - player.addMark('nzry_huaiju',3); - player.addSkill('nzry_huaiju_ai'); + content: function () { + player.addMark("nzry_huaiju", 3); + player.addSkill("nzry_huaiju_ai"); }, - group:['tachibana_effect'], + group: ["tachibana_effect"], }, //没错 这是个橘 - tachibana_effect:{ - audio:'nzry_huaiju', - trigger:{ - global:['damageBegin4','phaseDrawBegin2'], + tachibana_effect: { + audio: "nzry_huaiju", + trigger: { + global: ["damageBegin4", "phaseDrawBegin2"], }, - forced:true, - filter:function(event,player){ - return event.player.hasMark('nzry_huaiju')&&(event.name=='damage'||!event.numFixed); + forced: true, + filter: function (event, player) { + return event.player.hasMark("nzry_huaiju") && (event.name == "damage" || !event.numFixed); }, - content:function(){ - player.line(trigger.player,'green'); - if(trigger.name=='damage'){ + content: function () { + player.line(trigger.player, "green"); + if (trigger.name == "damage") { trigger.cancel(); - trigger.player.removeMark('nzry_huaiju',1); - } - else trigger.num++; + trigger.player.removeMark("nzry_huaiju", 1); + } else trigger.num++; }, }, - "nzry_yili":{ - audio:2, - trigger:{ - player:"phaseUseBegin", + nzry_yili: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('nzry_yili'),"移去一个【橘】或失去1点体力,然后令一名其他角色获得一个【橘】",function(card,player,target){ - return target!=player - }).ai=function(target){ - var player=_status.event.player; - if(player.storage.nzry_huaiju>2||player.hp>2) return get.attitude(player,target); + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("nzry_yili"), + "移去一个【橘】或失去1点体力,然后令一名其他角色获得一个【橘】", + function (card, player, target) { + return target != player; + } + ).ai = function (target) { + var player = _status.event.player; + if (player.storage.nzry_huaiju > 2 || player.hp > 2) + return get.attitude(player, target); return -1; }; - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - if(player.hasMark('nzry_huaiju')){ - player.chooseControl().set('choiceList',['失去1点体力','移去一个“橘”']).set('ai',function(){ - if(player.hp>2) return 0; - return 1; - }); - } - else event._result={index:0}; - }else{ + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + if (player.hasMark("nzry_huaiju")) { + player + .chooseControl() + .set("choiceList", ["失去1点体力", "移去一个“橘”"]) + .set("ai", function () { + if (player.hp > 2) return 0; + return 1; + }); + } else event._result = { index: 0 }; + } else { event.finish(); } - 'step 2' - player.logSkill('nzry_yili',target); - if(result.index==1){ - player.removeMark('nzry_huaiju',1); - }else{ + "step 2"; + player.logSkill("nzry_yili", target); + if (result.index == 1) { + player.removeMark("nzry_huaiju", 1); + } else { player.loseHp(); } - target.addMark('nzry_huaiju',1); - target.addSkill('nzry_huaiju_ai'); + target.addMark("nzry_huaiju", 1); + target.addSkill("nzry_huaiju_ai"); + }, + ai: { + combo: "nzry_huaiju", }, }, - "nzry_zhenglun":{ - audio:2, - trigger:{ - player:'phaseDrawBefore' + nzry_zhenglun: { + audio: 2, + trigger: { + player: "phaseDrawBefore", }, - filter:function(event,player){ - return !player.hasMark('nzry_huaiju'); + filter: function (event, player) { + return !player.hasMark("nzry_huaiju"); }, - check:function(event,player){ - return player.countCards('h')>=2||player.skipList.includes('phaseUse'); + check: function (event, player) { + return player.countCards("h") >= 2 || player.skipList.includes("phaseUse"); }, - content:function(){ + content: function () { trigger.cancel(); - player.addMark('nzry_huaiju',1); + player.addMark("nzry_huaiju", 1); + }, + ai: { + combo: "nzry_huaiju", }, }, - "nzry_kuizhu":{ - audio:2, - trigger:{ - player:"phaseDiscardAfter", + nzry_kuizhu: { + audio: 2, + trigger: { + player: "phaseDiscardAfter", }, - direct:true, - filter:function(event,player){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==event) cards.addArray(evt.cards2); + direct: true, + filter: function (event, player) { + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) + cards.addArray(evt.cards2); }); - return cards.length>0; + return cards.length > 0; }, - content:function(){ - 'step 0' - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) cards.addArray(evt.cards2); + content: function () { + "step 0"; + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + cards.addArray(evt.cards2); }); - event.num=cards.length; - event.str1='令至多'+event.num+'名角色摸一张牌'; - event.str2='对任意名体力值之和为'+event.num+'的角色造成1点伤害'; - player.chooseControl('cancel2').set('ai',function(){ - if(game.countPlayer(function(current){return get.attitude(player,current)<0&¤t.hp==event.num})>0&&event.num<=3) return 1; - return 0; - }).set('choiceList',[event.str1,event.str2]).set('prompt','是否发动【溃诛】?'); - 'step 1' - if(result.control=='cancel2') event.finish(); - event.control=[event.str1,event.str2][result.index]; - 'step 2' - var str='请选择〖溃诛〗的目标'; - if(event.bool==false) str='
              所选目标体力之和不足'+event.num+',请重选'; - if(event.control==event.str2){ - player.chooseTarget(str,function(card,player,target){ - var targets=ui.selected.targets; - var num=0; - for(var i=0;i 0 && + event.num <= 3 + ) + return 1; + return 0; + }) + .set("choiceList", [event.str1, event.str2]) + .set("prompt", "是否发动【溃诛】?"); + "step 1"; + if (result.control == "cancel2") event.finish(); + event.control = [event.str1, event.str2][result.index]; + "step 2"; + var str = "请选择〖溃诛〗的目标"; + if (event.bool == false) str = "
              所选目标体力之和不足" + event.num + ",请重选"; + if (event.control == event.str2) { + player + .chooseTarget(str, function (card, player, target) { + var targets = ui.selected.targets; + var num = 0; + for (var i = 0; i < targets.length; i++) { + num += targets[i].hp; + } + return num + target.hp <= _status.event.num; + }) + .set("ai", function (target) { + if (ui.selected.targets[0] != undefined) return -1; + return get.attitude(player, target) < 0; + }) + .set("promptbar", "none") + .set("num", event.num) + .set("selectTarget", function () { + var targets = ui.selected.targets; + var num = 0; + for (var i = 0; i < targets.length; i++) { + num += targets[i].hp; + } + if (num == _status.event.num) return ui.selected.targets.length; + return ui.selected.targets.length + 1; + }); + } else { + player.chooseTarget("请选择〖溃诛〗的目标", [1, event.num]).ai = function (target) { + return get.attitude(player, target); }; } - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - if(event.control==event.str1){ + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + if (event.control == event.str1) { //player.line(targets); - player.logSkill('nzry_kuizhu',targets); + player.logSkill("nzry_kuizhu", targets); game.asyncDraw(targets); - } - else{ - var num=0; - for(var i=0;i=2) player.loseHp(); @@ -2078,5221 +2553,5917 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, }, - rechezheng:{ - audio:'nzry_zhizheng', - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return player.isPhaseUsing()&&!player.inRangeOf(event.player); + rechezheng: { + audio: "nzry_zhizheng", + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return player.isPhaseUsing() && !player.inRangeOf(event.player); }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(get.tag(card,'damage')&&!player.inRangeOf(target)) return 'zerotarget'; + ai: { + effect: { + player: function (card, player, target) { + if (get.tag(card, "damage") && !player.inRangeOf(target)) return "zerotarget"; }, }, }, }, - nzry_zhizheng:{ - audio:2, + nzry_zhizheng: { + audio: 2, //mod:{ // playerEnabled:function(card,player,target){ // var info=get.info(card); // if(target!=player&&(!info||!info.singleCard||!ui.selected.targets.length)&&player.isPhaseUsing()&&!target.inRange(player)) return false; // }, //}, - trigger:{ - player:'phaseUseEnd' + trigger: { + player: "phaseUseEnd", }, - forced:true, - filter:function(event,player){ - return (player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; - }).length1?'中的一人':''),function(card,player,target){ - return player!=target&&target.hasZhuSkill('nzry_lijun',player); - }).ai=function(target){ - return get.attitude(_status.event.player,target); + player.chooseTarget( + get.prompt("nzry_lijun"), + "将" + + get.translation(trigger.cards) + + "交给" + + get.translation(list) + + (list.length > 1 ? "中的一人" : ""), + function (card, player, target) { + return player != target && target.hasZhuSkill("nzry_lijun", player); + } + ).ai = function (target) { + return get.attitude(_status.event.player, target); }; - 'step 1' - if(!result.bool) event.finish(); - else{ - player.addTempSkill('nzry_lijun2','phaseUseEnd'); - var zhu=result.targets[0]; - player.line(zhu,'green'); - zhu.logSkill('nzry_lijun'); - var list=[]; - for(var i=0;i0) return true; - return false; - }).set('prompt','是否令'+get.translation(player)+'摸一张牌?'); + zhu.gain(list, "gain2").giver = player; + zhu.chooseBool() + .set("ai", function () { + if (get.attitude(zhu, player) > 0) return true; + return false; + }) + .set("prompt", "是否令" + get.translation(player) + "摸一张牌?"); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.draw(); - player.addMark('nzry_lijun2',1,false); + player.addMark("nzry_lijun2", 1, false); } }, }, - nzry_chenglve:{ - mark:true, - locked:false, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player,skill){ - var str=player.storage.nzry_chenglve?'出牌阶段限一次,你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制':'出牌阶段限一次,你可以摸一张牌,然后弃置两张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制'; - if(player.storage.nzry_chenglve1){ - str+='
            • 当前花色:'; - str+=get.translation(player.storage.nzry_chenglve1); + nzry_chenglve: { + mark: true, + locked: false, + zhuanhuanji: true, + marktext: "☯", + intro: { + content: function (storage, player, skill) { + var str = player.storage.nzry_chenglve + ? "出牌阶段限一次,你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制" + : "出牌阶段限一次,你可以摸一张牌,然后弃置两张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制"; + if (player.storage.nzry_chenglve1) { + str += "
            • 当前花色:"; + str += get.translation(player.storage.nzry_chenglve1); } return str; }, }, - enable:"phaseUse", - usable:1, - audio:2, - content:function(){ - 'step 0' - if(player.storage.nzry_chenglve==true){ + enable: "phaseUse", + usable: 1, + audio: 2, + content: function () { + "step 0"; + if (player.storage.nzry_chenglve == true) { player.draw(2); - player.chooseToDiscard('h',true); - } - else{ + player.chooseToDiscard("h", true); + } else { player.draw(); - player.chooseToDiscard('h',2,true); + player.chooseToDiscard("h", 2, true); } - player.changeZhuanhuanji('nzry_chenglve') - 'step 1' - if(result.bool){ - player.storage.nzry_chenglve1=[]; - for(var i=0;i1?'以任意顺序':'')+'置于牌堆顶,然后摸一张牌'; + nzry_shicai: { + audio: "nzry_shicai_2", + trigger: { player: ["useCardAfter", "useCardToTargeted"] }, + prompt2: function (event, player) { + const cards = event.cards.filterInD("oe"); + return ( + "你可以将" + + get.translation(cards) + + (cards.length > 1 ? "以任意顺序" : "") + + "置于牌堆顶,然后摸一张牌" + ); }, - filter:function(event,player){ - if(!event.cards.someInD()) return false; - let evt=event,type=get.type2(evt.card,false); - if(event.name=='useCardToTargeted'){ - if(type!='equip'||player!=event.target) return false; - evt=evt.getParent(); + filter: function (event, player) { + if (!event.cards.someInD()) return false; + let evt = event, + type = get.type2(evt.card, false); + if (event.name == "useCardToTargeted") { + if (type != "equip" || player != event.target) return false; + evt = evt.getParent(); + } else { + if (type == "equip") return false; } - else{ - if(type=='equip') return false; - } - return !player.hasHistory('useCard',evtx=>{ - return evtx!=evt&&get.type2(evtx.card,false)==type; - },evt); + return !player.hasHistory( + "useCard", + (evtx) => { + return evtx != evt && get.type2(evtx.card, false) == type; + }, + evt + ); }, - check:function(event,player){ - if(get.type(event.card)=='equip'){ - if(get.subtype(event.card)=='equip6') return true; - if(get.equipResult(player,player,event.card.name)<=0) return true; - var eff1=player.getUseValue(event.card); - var subtype=get.subtype(event.card); - return player.countCards('h',function(card){ - return get.subtype(card)==subtype&&player.getUseValue(card)>=eff1; - })>0; + check: function (event, player) { + if (get.type(event.card) == "equip") { + if (get.subtype(event.card) == "equip6") return true; + if (get.equipResult(player, player, event.card.name) <= 0) return true; + var eff1 = player.getUseValue(event.card); + var subtype = get.subtype(event.card); + return ( + player.countCards("h", function (card) { + return get.subtype(card) == subtype && player.getUseValue(card) >= eff1; + }) > 0 + ); } return true; }, - content:function(){ - 'step 0' - var cards=trigger.cards.filterInD(); - if(cards.length==1){ - event._result={bool:true,moved:[cards]}; - } - else{ - var next=player.chooseToMove('恃才:将牌按顺序置于牌堆顶',true); - next.set('list',[['牌堆顶',cards]]); - next.set('reverse',((_status.currentPhase&&_status.currentPhase.next)?get.attitude(player,_status.currentPhase.next)>0:false)); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0); - cards.sort(function(a,b){ - return (_status.event.reverse?1:-1)*(get.value(b)-get.value(a)); + content: function () { + "step 0"; + var cards = trigger.cards.filterInD(); + if (cards.length == 1) { + event._result = { bool: true, moved: [cards] }; + } else { + var next = player.chooseToMove("恃才:将牌按顺序置于牌堆顶", true); + next.set("list", [["牌堆顶", cards]]); + next.set( + "reverse", + _status.currentPhase && _status.currentPhase.next + ? get.attitude(player, _status.currentPhase.next) > 0 + : false + ); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0); + cards.sort(function (a, b) { + return (_status.event.reverse ? 1 : -1) * (get.value(b) - get.value(a)); }); return [cards]; }); } - 'step 1' - if(result.bool){ - var cards=result.moved[0]; + "step 1"; + if (result.bool) { + var cards = result.moved[0]; cards.reverse(); - game.cardsGotoPile(cards,'insert'); - game.log(player,'将',cards,'置于了牌堆顶'); + game.cardsGotoPile(cards, "insert"); + game.log(player, "将", cards, "置于了牌堆顶"); } player.draw(); }, - subSkill:{'2':{audio:2}}, - ai:{ - reverseOrder:true, - skillTagFilter:function(player){ - if(player.getHistory('useCard',function(evt){ - return get.type(evt.card)=='equip'; - }).length>0) return false; + subSkill: { 2: { audio: 2 } }, + ai: { + reverseOrder: true, + skillTagFilter: function (player) { + if ( + player.getHistory("useCard", function (evt) { + return get.type(evt.card) == "equip"; + }).length > 0 + ) + return false; }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.type(card)=='equip'&&!player.getHistory('useCard',function(evt){ - return get.type(evt.card)=='equip'; - }).length) return [1,3]; + effect: { + target: function (card, player, target) { + if ( + player == target && + get.type(card) == "equip" && + !player.getHistory("useCard", function (evt) { + return get.type(evt.card) == "equip"; + }).length + ) + return [1, 3]; }, }, }, }, - "nzry_cunmu":{ - audio:2, - audioname:['ol_pengyang'], - trigger:{ - player:'drawBegin' + nzry_cunmu: { + audio: 2, + audioname: ["ol_pengyang"], + trigger: { + player: "drawBegin", }, - forced:true, - content:function(){ - trigger.bottom=true; + forced: true, + content: function () { + trigger.bottom = true; }, }, - nzry_mingren:{ - audio:"nzry_mingren_1", - audioname:['sb_yl_luzhi'], - marktext:"任", - intro:{ - content:'expansion', - markcount:'expansion', + nzry_mingren: { + audio: "nzry_mingren_1", + audioname: ["sb_yl_luzhi"], + marktext: "任", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:["nzry_mingren_1","nzry_mingren_2"], - subSkill:{ - 1:{ - audio:2, - audioname:['sb_yl_luzhi'], - trigger:{ - global:'phaseBefore', - player:'enterGame', + group: ["nzry_mingren_1", "nzry_mingren_2"], + subSkill: { + 1: { + audio: 2, + audioname: ["sb_yl_luzhi"], + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&!player.getExpansions('nzry_mingren').length; + forced: true, + locked: false, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + !player.getExpansions("nzry_mingren").length + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(2); - 'step 1' - if(!player.countCards('h')) event.finish(); - else player.chooseCard('h','将一张手牌置于武将牌上,称为“任”',true).set('ai',function(card){ - return 6-get.value(card); - }); - 'step 2' - if(result.bool){ - player.addToExpansion(result.cards[0],player,'give','log').gaintag.add('nzry_mingren'); + "step 1"; + if (!player.countCards("h")) event.finish(); + else + player + .chooseCard("h", "将一张手牌置于武将牌上,称为“任”", true) + .set("ai", function (card) { + return 6 - get.value(card); + }); + "step 2"; + if (result.bool) { + player + .addToExpansion(result.cards[0], player, "give", "log") + .gaintag.add("nzry_mingren"); } }, }, - 2:{ - trigger:{ - player:'phaseJieshuBegin', + 2: { + trigger: { + player: "phaseJieshuBegin", }, - filter:function(event,player){ - return player.countCards('h')>0&&player.getExpansions('nzry_mingren').length>0; + filter: function (event, player) { + return ( + player.countCards("h") > 0 && player.getExpansions("nzry_mingren").length > 0 + ); }, - direct:true, - content:function(){ - 'step 0' - 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; - var num=0; - var list=[]; - player.countCards('h',function(cardx){ - if(cardx!=card||get.color(cardx)!=color) return false; - if(list.includes(cardx.name)) return false; - list.push(cardx.name); - switch(cardx.name){ - case 'wuxie':num+=(game.countPlayer()/2.2);break; - case 'caochuan':num+=1.1;break; - case 'shan':num+=1;break; - } + direct: true, + content: function () { + "step 0"; + 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; + var num = 0; + var list = []; + player.countCards("h", function (cardx) { + if (cardx != card || get.color(cardx) != color) return false; + if (list.includes(cardx.name)) return false; + list.push(cardx.name); + switch (cardx.name) { + case "wuxie": + num += game.countPlayer() / 2.2; + break; + case "caochuan": + num += 1.1; + break; + case "shan": + num += 1; + break; + } + }); + return num * (30 - get.value(card)); }); - return num*(30-get.value(card)); - }); - 'step 1' - if(result.bool){ - player.logSkill('nzry_mingren'); - player.addToExpansion(result.cards[0],'log','give',player).gaintag.add('nzry_mingren'); - var card=player.getExpansions('nzry_mingren')[0]; - if(card) player.gain(card,'gain2'); + "step 1"; + if (result.bool) { + player.logSkill("nzry_mingren"); + player + .addToExpansion(result.cards[0], "log", "give", player) + .gaintag.add("nzry_mingren"); + var card = player.getExpansions("nzry_mingren")[0]; + if (card) player.gain(card, "gain2"); } }, }, }, - ai:{ - combo:'nzry_zhenliang', - }, }, - "nzry_zhenliang":{ - audio:"nzry_zhenliang_1", - mark:true, - locked:false, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player,skill){ - if(player.storage.nzry_zhenliang==true) return '当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。'; - return '出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。'; + nzry_zhenliang: { + audio: "nzry_zhenliang_1", + mark: true, + locked: false, + zhuanhuanji: true, + marktext: "☯", + intro: { + content: function (storage, player, skill) { + if (player.storage.nzry_zhenliang == true) + return "当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。"; + return "出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。"; }, }, - group:["nzry_zhenliang_1","nzry_zhenliang_2"], - subSkill:{ - 1:{ - prompt:'弃置一张与“任”颜色相同的牌,并对攻击范围内的一名角色造成1点伤害。', - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(player.storage.nzry_zhenliang) return false; - var storage=player.getExpansions('nzry_mingren'); - if(!storage.length) return false; - var color=get.color(storage[0]); - if(player.countCards('he',function(card){ - return get.color(card)==color; - })==0) return false; - return game.hasPlayer(function(current){ + group: ["nzry_zhenliang_1", "nzry_zhenliang_2"], + subSkill: { + 1: { + prompt: "弃置一张与“任”颜色相同的牌,并对攻击范围内的一名角色造成1点伤害。", + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (player.storage.nzry_zhenliang) return false; + var storage = player.getExpansions("nzry_mingren"); + if (!storage.length) return false; + var color = get.color(storage[0]); + if ( + player.countCards("he", function (card) { + return get.color(card) == color; + }) == 0 + ) + return false; + return game.hasPlayer(function (current) { return player.inRange(current); }); }, - position:'he', - filterCard:function(card,player){ - return get.color(card)==get.color(player.getExpansions('nzry_mingren')[0]); + position: "he", + filterCard: function (card, player) { + return get.color(card) == get.color(player.getExpansions("nzry_mingren")[0]); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.inRange(target); }, - check:function(card){ - return 6.5-get.value(card); + check: function (card) { + return 6.5 - get.value(card); }, - content:function(){ - player.changeZhuanhuanji('nzry_zhenliang'); - target.damage('nocard'); + content: function () { + player.changeZhuanhuanji("nzry_zhenliang"); + target.damage("nocard"); }, - ai:{ - order:5, - result:{ - player:function(player,target){ - return get.damageEffect(target,player,player); + ai: { + order: 5, + result: { + player: function (player, target) { + return get.damageEffect(target, player, player); }, }, }, }, - 2:{ - trigger:{ - player:['useCardAfter','respondAfter'], + 2: { + trigger: { + player: ["useCardAfter", "respondAfter"], }, - filter:function(event,player){ - if(_status.currentPhase==player||!player.storage.nzry_zhenliang) return false; - var card=player.getExpansions('nzry_mingren')[0]; - return card&&get.color(event.card)==get.color(card); + filter: function (event, player) { + if (_status.currentPhase == player || !player.storage.nzry_zhenliang) + return false; + var card = player.getExpansions("nzry_mingren")[0]; + return card && get.color(event.card) == get.color(card); }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('nzry_zhenliang'),'令一名角色摸一张牌').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){ - player.changeZhuanhuanji('nzry_zhenliang'); - player.logSkill('nzry_zhenliang',result.targets); + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("nzry_zhenliang"), "令一名角色摸一张牌").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) { + player.changeZhuanhuanji("nzry_zhenliang"); + player.logSkill("nzry_zhenliang", result.targets); result.targets[0].draw(); } }, }, }, - ai:{ - combo:'nzry_mingren', + ai: { + combo: "nzry_mingren", }, }, - 'nzry_jianxiang':{ - audio:2, - trigger:{ - target:'useCardToTargeted', + nzry_jianxiang: { + audio: 2, + trigger: { + target: "useCardToTargeted", }, - filter:function(event,player){ - return event.player!=player; + filter: function (event, player) { + return event.player != player; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('nzry_jianxiang'),'令场上手牌数最少的一名角色摸一张牌',function(card,player,target){ - return target.isMinHandcard(); - }).ai=function(target){ - return get.attitude(player,target) + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("nzry_jianxiang"), + "令场上手牌数最少的一名角色摸一张牌", + function (card, player, target) { + return target.isMinHandcard(); + } + ).ai = function (target) { + return get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('nzry_jianxiang',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("nzry_jianxiang", result.targets); result.targets[0].draw(); } }, }, - "nzry_shenshi":{ - mark:true, - audio:'nzry_shenshi_1', - locked:false, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player,skill){ - if(player.storage.nzry_shenshi==true) return '其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张'; - return '出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张'; + nzry_shenshi: { + mark: true, + audio: "nzry_shenshi_1", + locked: false, + zhuanhuanji: true, + marktext: "☯", + intro: { + content: function (storage, player, skill) { + if (player.storage.nzry_shenshi == true) + return "其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张"; + return "出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张"; }, }, - group:["nzry_shenshi_1","nzry_shenshi_2"], - subSkill:{ - '1':{ - audio:2, - prompt:'出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&player.storage.nzry_shenshi!=true; + group: ["nzry_shenshi_1", "nzry_shenshi_2"], + subSkill: { + 1: { + audio: 2, + prompt: "出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0 && player.storage.nzry_shenshi != true; }, - discard:false, - line:true, - lose:false, - delay:false, - position:'he', - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player&&!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>target.countCards('h'); - }); + discard: false, + line: true, + lose: false, + delay: false, + position: "he", + filterCard: true, + filterTarget: function (card, player, target) { + return ( + target != player && + !game.hasPlayer(function (current) { + return ( + current != player && current.countCards("h") > target.countCards("h") + ); + }) + ); }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - 'step 0' - player.changeZhuanhuanji('nzry_shenshi'); - player.give(cards,target); - target.damage('nocard'); - 'step 1' - if(!target.isIn()){ - player.chooseTarget('令一名角色将手牌摸至四张',function(card,player,target){ - return target.countCards('h')<4; - }).set('ai',function(target){ - return get.attitude(player,target) - }); - } - else{ + content: function () { + "step 0"; + player.changeZhuanhuanji("nzry_shenshi"); + player.give(cards, target); + target.damage("nocard"); + "step 1"; + if (!target.isIn()) { + player + .chooseTarget( + "令一名角色将手牌摸至四张", + function (card, player, target) { + return target.countCards("h") < 4; + } + ) + .set("ai", function (target) { + return get.attitude(player, target); + }); + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.line(result.targets); - result.targets[0].draw(4-result.targets[0].countCards('h')) + result.targets[0].draw(4 - result.targets[0].countCards("h")); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ + ai: { + order: 1, + result: { + target: function (player, target) { return -1; }, }, }, }, - '2':{ - audio:'nzry_shenshi_1', - trigger:{ - player:'damageEnd', + 2: { + audio: "nzry_shenshi_1", + trigger: { + player: "damageEnd", }, - filter:function(event,player){ - return player.countCards('he')>0&&event.source&&event.source!=player&&player.storage.nzry_shenshi==true; + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + event.source && + event.source != player && + player.storage.nzry_shenshi == true + ); }, - check:function(event,player){ - return event.source&&event.source.countCards('h')<=2&&player.countCards('h')<4; + check: function (event, player) { + return ( + event.source && + event.source.countCards("h") <= 2 && + player.countCards("h") < 4 + ); }, - logTarget:'source', - prompt2:'其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张', - content:function(){ - "step 0" - player.changeZhuanhuanji('nzry_shenshi'); + logTarget: "source", + prompt2: + "其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张", + content: function () { + "step 0"; + player.changeZhuanhuanji("nzry_shenshi"); player.viewHandcards(trigger.source); - player.chooseCard('he',true,'交给'+get.translation(trigger.source)+'一张牌').set('ai',function(card){ - return 5-get.value(card); - }); - "step 1" - if(result.bool){ - player.give(result.cards,trigger.source); - trigger.source.storage.nzry_shenshi1=result.cards[0]; - trigger.source.storage.nzry_shenshi2=player; - trigger.source.addSkill('nzry_shenshi1'); + player + .chooseCard("he", true, "交给" + get.translation(trigger.source) + "一张牌") + .set("ai", function (card) { + return 5 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.give(result.cards, trigger.source); + trigger.source.storage.nzry_shenshi1 = result.cards[0]; + trigger.source.storage.nzry_shenshi2 = player; + trigger.source.addSkill("nzry_shenshi1"); } }, }, }, }, - nzry_shenshi1:{ - audio:2, - trigger:{ - global:'phaseJieshuBegin', + nzry_shenshi1: { + audio: 2, + trigger: { + global: "phaseJieshuBegin", }, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.storage.nzry_shenshi1!=undefined&&player.storage.nzry_shenshi2!=undefined; + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return ( + player.storage.nzry_shenshi1 != undefined && player.storage.nzry_shenshi2 != undefined + ); }, - content:function(){ - var pl=player.storage.nzry_shenshi2; - var card=player.storage.nzry_shenshi1; - if(player.getCards('he').includes(card)&&4-pl.countCards('h')>0){ - pl.draw(4-pl.countCards('h')); - pl.logSkill('nzry_shenshi'); + content: function () { + var pl = player.storage.nzry_shenshi2; + var card = player.storage.nzry_shenshi1; + if (player.getCards("he").includes(card) && 4 - pl.countCards("h") > 0) { + pl.draw(4 - pl.countCards("h")); + pl.logSkill("nzry_shenshi"); } - player.removeSkill('nzry_shenshi1'); + player.removeSkill("nzry_shenshi1"); delete player.storage.nzry_shenshi1; delete player.storage.nzry_shenshi2; }, }, - xinjushou:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - content:function(){ - 'step 0' + xinjushou: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + content: function () { + "step 0"; player.draw(4); player.turnOver(); - 'step 1' - player.chooseCard('h',true,'弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之').set('ai',function(card){ - if(get.type(card)=='equip'){ - return 5-get.value(card); - } - return -get.value(card); - }).set('filterCard',lib.filter.cardDiscardable); - 'step 2' - if(result.bool&&result.cards.length){ - var card=result.cards[0]; - if(get.type(card)=='equip'&&player.hasUseTarget(card)){ - player.chooseUseTarget(card,true,'nopopup'); - } - else{ + "step 1"; + player + .chooseCard("h", true, "弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之") + .set("ai", function (card) { + if (get.type(card) == "equip") { + return 5 - get.value(card); + } + return -get.value(card); + }) + .set("filterCard", lib.filter.cardDiscardable); + "step 2"; + if (result.bool && result.cards.length) { + var card = result.cards[0]; + if (get.type(card) == "equip" && player.hasUseTarget(card)) { + player.chooseUseTarget(card, true, "nopopup"); + } else { player.discard(card); } } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,1]; - } - } + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 1]; + }, + }, }, }, - xinjiewei:{ - audio:2, - enable:'chooseToUse', - filterCard:true, - position:'e', - viewAs:{name:'wuxie'}, - filter:function(event,player){ - return player.countCards('e')>0; + xinjiewei: { + audio: 2, + enable: "chooseToUse", + filterCard: true, + position: "e", + viewAs: { name: "wuxie" }, + filter: function (event, player) { + return player.countCards("e") > 0; }, - viewAsFilter:function(player){ - return player.countCards('e')>0; + viewAsFilter: function (player) { + return player.countCards("e") > 0; }, - prompt:'将一张装备区内的牌当无懈可击使用', - check:function(card){return 8-get.equipValue(card)}, - threaten:1.2, - group:'xinjiewei_move', - subSkill:{ - move:{ - trigger:{player:'turnOverEnd'}, - direct:true, - audio:'jiewei', - filter:function(event,player){ - return !player.isTurnedOver()&&player.canMoveCard(); + prompt: "将一张装备区内的牌当无懈可击使用", + check: function (card) { + return 8 - get.equipValue(card); + }, + threaten: 1.2, + group: "xinjiewei_move", + subSkill: { + move: { + trigger: { player: "turnOverEnd" }, + direct: true, + audio: "jiewei", + filter: function (event, player) { + return !player.isTurnedOver() && player.canMoveCard(); }, - content:function(){ - "step 0" - player.chooseToDiscard('he',get.prompt('xinjiewei'),'弃置一张牌并移动场上的一张牌',lib.filter.cardDiscardable).set('ai',function(card){ - if(!_status.event.check) return 0; - return 7-get.value(card); - }).set('check',player.canMoveCard(true)).set('logSkill','xinjiewei'); - "step 1" - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("xinjiewei"), + "弃置一张牌并移动场上的一张牌", + lib.filter.cardDiscardable + ) + .set("ai", function (card) { + if (!_status.event.check) return 0; + return 7 - get.value(card); + }) + .set("check", player.canMoveCard(true)) + .set("logSkill", "xinjiewei"); + "step 1"; + if (result.bool) { player.moveCard(true); - } - else{ + } else { event.finish(); } - } - } - } + }, + }, + }, }, - jianchu:{ - shaRelated:true, - audio:2, - audioname:['re_pangde'], - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countDiscardableCards(player,'he')>0; + jianchu: { + shaRelated: true, + audio: 2, + audioname: ["re_pangde"], + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countDiscardableCards(player, "he") > 0; }, - preHidden:true, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + preHidden: true, + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - logTarget:'target', - content:function(){ - 'step 0' - player.discardPlayerCard(trigger.target,get.prompt('jianchu',trigger.target),true).set('ai',function(button){ - if(!_status.event.att) return 0; - if(get.position(button.link)=='e'){ - if(get.subtype(button.link)=='equip2') return 2*get.value(button.link); - return get.value(button.link); - } - return 1; - }).set('att',get.attitude(player,trigger.target)<=0); - 'step 1' - if(result.bool&&result.links&&result.links.length){ - if(get.type(result.links[0],null,result.links[0].original=='h'?player:false)=='equip'){ - trigger.getParent().directHit.add(trigger.target); - } - else if(trigger.cards){ - var list=[]; - for(var i=0;i1; - })>0; - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "directHit_ai") + return ( + arg.card.name == "sha" && + arg.target.countCards("e", function (card) { + return get.value(card) > 1; + }) > 0 + ); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } + }, }, }, - redimeng:{ - audio:'dimeng', - enable:'phaseUse', - usable:1, - position:'he', - filterCard:function(){ - if(ui.selected.targets.length==2) return false; + redimeng: { + audio: "dimeng", + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: function () { + if (ui.selected.targets.length == 2) return false; return true; }, - selectCard:[0,Infinity], - selectTarget:2, - complexCard:true, - complexSelect:true, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(ui.selected.targets.length==0) return true; - return (Math.abs(ui.selected.targets[0].countCards('h')-target.countCards('h'))== - ui.selected.cards.length); + selectCard: [0, Infinity], + selectTarget: 2, + complexCard: true, + complexSelect: true, + filterTarget: function (card, player, target) { + if (player == target) return false; + if (ui.selected.targets.length == 0) return true; + return ( + Math.abs(ui.selected.targets[0].countCards("h") - target.countCards("h")) == + ui.selected.cards.length + ); }, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - var cards=targets[0].getCards('h').concat(targets[1].getCards('h')); - var dialog=ui.create.dialog('缔盟',true); - if(player.isUnderControl(true)||targets[0].isUnderControl(true)||targets[1].isUnderControl(true)){ + multitarget: true, + multiline: true, + content: function () { + "step 0"; + var cards = targets[0].getCards("h").concat(targets[1].getCards("h")); + var dialog = ui.create.dialog("缔盟", true); + if ( + player.isUnderControl(true) || + targets[0].isUnderControl(true) || + targets[1].isUnderControl(true) + ) { dialog.add(cards); - dialog.seeing=true; - } - else{ - dialog.add([cards,'blank']); + dialog.seeing = true; + } else { + dialog.add([cards, "blank"]); } _status.dieClose.push(dialog); - dialog.videoId=lib.status.videoId++; - game.addVideo('cardDialog',null,['缔盟',get.cardsInfo(cards),dialog.videoId]); - game.broadcast(function(cards,id,player,targets){ - var dialog=ui.create.dialog('缔盟',true); - if(player.isUnderControl(true)||targets[0].isUnderControl(true)||targets[1].isUnderControl(true)){ - dialog.add(cards); - dialog.seeing=true; - } - else{ - dialog.add([cards,'blank']); - } - _status.dieClose.push(dialog); - dialog.videoId=id; - },cards,dialog.videoId,player,targets); + dialog.videoId = lib.status.videoId++; + game.addVideo("cardDialog", null, ["缔盟", get.cardsInfo(cards), dialog.videoId]); + game.broadcast( + function (cards, id, player, targets) { + var dialog = ui.create.dialog("缔盟", true); + if ( + player.isUnderControl(true) || + targets[0].isUnderControl(true) || + targets[1].isUnderControl(true) + ) { + dialog.add(cards); + dialog.seeing = true; + } else { + dialog.add([cards, "blank"]); + } + _status.dieClose.push(dialog); + dialog.videoId = id; + }, + cards, + dialog.videoId, + player, + targets + ); - event.current=targets[0]; - event.dialog=dialog; - event.num1=0; - event.num2=0; + event.current = targets[0]; + event.dialog = dialog; + event.num1 = 0; + event.num2 = 0; game.delay(); - 'step 1' - if(event.dialog.buttons.length>1){ - var next=event.current.chooseButton(true,function(button){ - return get.value(button.link,_status.event.player); + "step 1"; + if (event.dialog.buttons.length > 1) { + var next = event.current.chooseButton(true, function (button) { + return get.value(button.link, _status.event.player); }); - next.set('dialog',event.dialog.videoId); - next.set('closeDialog',false); - next.set('dialogdisplay',true); + next.set("dialog", event.dialog.videoId); + next.set("closeDialog", false); + next.set("dialogdisplay", true); + } else { + event.directButton = event.dialog.buttons[0]; } - else{ - event.directButton=event.dialog.buttons[0]; - } - 'step 2' - var dialog=event.dialog; + "step 2"; + var dialog = event.dialog; var card; - if(event.directButton){ - card=event.directButton.link; + if (event.directButton) { + card = event.directButton.link; + } else { + card = result.links[0]; } - else{ - card=result.links[0]; - } - for(var i=0;i3; + targetprompt: ["先拿牌", "后拿牌"], + find: function (type) { + var list = game.filterPlayer(function (current) { + return current != player && get.attitude(player, current) > 3; }); - var player=_status.event.player; - var num=player.countCards('he',function(card){ - return get.value(card)<7; + var player = _status.event.player; + var num = player.countCards("he", function (card) { + return get.value(card) < 7; }); - var count=null; - var from,nh; - if(list.length==0) return null; - list.sort(function(a,b){ - return a.countCards('h')-b.countCards('h'); + var count = null; + var from, nh; + if (list.length == 0) return null; + list.sort(function (a, b) { + return a.countCards("h") - b.countCards("h"); }); - if(type==1) return list[0]; - from=list[0]; - nh=from.countCards('h'); + if (type == 1) return list[0]; + from = list[0]; + nh = from.countCards("h"); - list=game.filterPlayer(function(current){ - return current!=player&&get.attitude(player,current)<1; + list = game.filterPlayer(function (current) { + return current != player && get.attitude(player, current) < 1; }); - if(list.length==0) return null; - list.sort(function(a,b){ - return b.countCards('h')-a.countCards('h'); + if (list.length == 0) return null; + list.sort(function (a, b) { + return b.countCards("h") - a.countCards("h"); }); - for(var i=0;i=7){ - if(num<2) return 0; - } - else if(targets.length>=5){ - if(num<1.5) return 0; + if (!player.needsToDiscard(-1)) { + if (targets.length >= 7) { + if (num < 2) return 0; + } else if (targets.length >= 5) { + if (num < 1.5) return 0; } } - return 6-get.value(card); + return 6 - get.value(card); }, - ai:{ - basic:{ - order:8.9 - } + ai: { + basic: { + order: 8.9, + }, }, - group:['reluanji_count','reluanji_reset','reluanji_respond','reluanji_damage','reluanji_draw'], - subSkill:{ - reset:{ - trigger:{player:'phaseAfter'}, - silent:true, - content:function(){ + group: [ + "reluanji_count", + "reluanji_reset", + "reluanji_respond", + "reluanji_damage", + "reluanji_draw", + ], + subSkill: { + reset: { + trigger: { player: "phaseAfter" }, + silent: true, + content: function () { delete player.storage.reluanji; delete player.storage.reluanji2; - } - }, - count:{ - trigger:{player:'useCard'}, - silent:true, - filter:function(event){ - return event.skill=='reluanji'; }, - content:function(){ - player.storage.reluanji2=trigger.card; - if(!player.storage.reluanji){ - player.storage.reluanji=[]; + }, + count: { + trigger: { player: "useCard" }, + silent: true, + filter: function (event) { + return event.skill == "reluanji"; + }, + content: function () { + player.storage.reluanji2 = trigger.card; + if (!player.storage.reluanji) { + player.storage.reluanji = []; } - for(var i=0;i=4&&shas.length>=3){ - num=3; + if (player.hp >= 4 && shas.length >= 3) { + num = 3; + } else if (player.hp >= 3 && shas.length >= 2) { + num = 2; + } else { + num = 1; } - else if(player.hp>=3&&shas.length>=2){ - num=2; - } - else{ - num=1 - } - var map={}; - var list=[]; - for(var i=1;i<=player.hp;i++){ - var cn=get.cnNumber(i,true); - map[cn]=i; + var map = {}; + var list = []; + for (var i = 1; i <= player.hp; i++) { + var cn = get.cnNumber(i, true); + map[cn] = i; list.push(cn); } - event.map=map; - player.awakenSkill('qimou'); - player.storage.qimou=true; - player.chooseControl(list,function(){ - return get.cnNumber(_status.event.goon,true); - }).set('prompt','失去任意点体力').set('goon',num); - 'step 1' - var num=event.map[result.control]||1; - player.storage.qimou2=num; + event.map = map; + player.awakenSkill("qimou"); + player.storage.qimou = true; + player + .chooseControl(list, function () { + return get.cnNumber(_status.event.goon, true); + }) + .set("prompt", "失去任意点体力") + .set("goon", num); + "step 1"; + var num = event.map[result.control] || 1; + player.storage.qimou2 = num; player.loseHp(num); - player.addTempSkill('qimou2'); + player.addTempSkill("qimou2"); }, - ai:{ - order:2, - result:{ - player:function(player){ - if(player.hp==1) return 0; - var shas=player.getCards('h','sha'); - if(!shas.length) return 0; - var card=shas[0]; - if(!lib.filter.cardEnabled(card,player)) return 0; - if(lib.filter.cardUsable(card,player)) return 0; + ai: { + order: 2, + result: { + player: function (player) { + if (player.hp == 1) return 0; + var shas = player.getCards("h", "sha"); + if (!shas.length) return 0; + var card = shas[0]; + if (!lib.filter.cardEnabled(card, player)) return 0; + if (lib.filter.cardUsable(card, player)) return 0; var mindist; - if(player.hp>=4&&shas.length>=3){ - mindist=4; + if (player.hp >= 4 && shas.length >= 3) { + mindist = 4; + } else if (player.hp >= 3 && shas.length >= 2) { + mindist = 3; + } else { + mindist = 2; } - else if(player.hp>=3&&shas.length>=2){ - mindist=3; - } - else{ - mindist=2; - } - if(game.hasPlayer(function(current){ - return (current.hp<=mindist-1&& - get.distance(player,current,'attack')<=mindist&& - player.canUse(card,current,false)&& - get.effect(current,card,player,player)>0); - })){ + if ( + game.hasPlayer(function (current) { + return ( + current.hp <= mindist - 1 && + get.distance(player, current, "attack") <= mindist && + player.canUse(card, current, false) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { return 1; } return 0; - } - } - } + }, + }, + }, }, - qimou2:{ - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(typeof player.storage.qimou2=='number'&&card.name=='sha'){ - return num+player.storage.qimou2; + qimou2: { + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (typeof player.storage.qimou2 == "number" && card.name == "sha") { + return num + player.storage.qimou2; } }, - globalFrom:function(from,to,distance){ - if(typeof from.storage.qimou2=='number'){ - return distance-from.storage.qimou2; + globalFrom: function (from, to, distance) { + if (typeof from.storage.qimou2 == "number") { + return distance - from.storage.qimou2; } - } - } - }, - xinkuanggu:{ - 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' - event.num=trigger.num; - 'step 1' + }, + xinkuanggu: { + 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"; + event.num = trigger.num; + "step 1"; var choice; - if(player.isDamaged()&&get.recoverEffect(player)>0&&(player.countCards('hs',function(card){ - return card.name=='sha'&&player.hasValueTarget(card); - })>=player.getCardUsable('sha'))){ - choice='recover_hp'; + if ( + player.isDamaged() && + get.recoverEffect(player) > 0 && + player.countCards("hs", function (card) { + return card.name == "sha" && player.hasValueTarget(card); + }) >= player.getCardUsable("sha") + ) { + choice = "recover_hp"; + } else { + choice = "draw_card"; } - else{ - choice='draw_card'; - } - var next=player.chooseDrawRecover('###'+get.prompt(event.name)+'###摸一张牌或回复1点体力').set('logSkill',event.name); - next.set('choice',choice); - next.set('ai',function(){ + 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; }); - next.setHiddenSkill('xinkuanggu'); - 'step 2' - if(result.control!='cancel2'){ + next.setHiddenSkill("xinkuanggu"); + "step 2"; + if (result.control != "cancel2") { event.num--; - if(event.num>0&&player.hasSkill('xinkuanggu')){ + if (event.num > 0 && player.hasSkill("xinkuanggu")) { event.goto(1); } } }, - group:'kuanggu_check', + group: "kuanggu_check", }, - xinliegong:{ - shaRelated:true, - mod:{ - aiOrder:function(player,card,num){ - if(num>0&&(card.name==='sha'||get.tag(card,'draw'))) return num+6; + xinliegong: { + shaRelated: true, + mod: { + aiOrder: function (player, card, num) { + if (num > 0 && (card.name === "sha" || get.tag(card, "draw"))) return num + 6; }, - targetInRange:function(card,player,target){ - if(card.name=='sha'&&typeof get.number(card)=='number'){ - if(get.distance(player,target)<=get.number(card)) return true; + targetInRange: function (card, player, target) { + if (card.name == "sha" && typeof get.number(card) == "number") { + if (get.distance(player, target) <= get.number(card)) return true; } - } + }, }, - audio:'liegong', - audioname:['re_huangzhong','ol_huangzhong'], - trigger:{player:'useCardToTargeted'}, - logTarget:'target', - locked:false, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + audio: "liegong", + audioname: ["re_huangzhong", "ol_huangzhong"], + trigger: { player: "useCardToTargeted" }, + logTarget: "target", + locked: false, + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.target.countCards('h')<=player.countCards('h')) return true; - if(event.target.hp>=player.hp) return true; + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.target.countCards("h") <= player.countCards("h")) return true; + if (event.target.hp >= player.hp) return true; return false; }, - content:function(){ - if(trigger.target.countCards('h')<=player.countCards('h')) trigger.getParent().directHit.push(trigger.target); - if(trigger.target.hp>=player.hp){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number'){ - map[id].extraDamage=0; + content: function () { + if (trigger.target.countCards("h") <= player.countCards("h")) + trigger.getParent().directHit.push(trigger.target); + if (trigger.target.hp >= player.hp) { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") { + map[id].extraDamage = 0; } map[id].extraDamage++; } }, - ai:{ - threaten:0.5, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)<=0&&arg.card.name=='sha'&&player.countCards('h',function(card){ - return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card)); - })>=arg.target.countCards('h')) return true; + ai: { + threaten: 0.5, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + get.attitude(player, arg.target) <= 0 && + arg.card.name == "sha" && + player.countCards("h", function (card) { + return ( + card != arg.card && (!arg.card.cards || !arg.card.cards.includes(card)) + ); + }) >= arg.target.countCards("h") + ) + return true; return false; }, - } + }, }, - tiaoxin:{ - audio:2, - audioname:['sp_jiangwei','xiahouba','re_jiangwei','gz_jiangwei','ol_jiangwei'], - audioname2:{ - dc_xiahouba:'tiaoxin_xiahouba', + tiaoxin: { + audio: 2, + audioname: ["sp_jiangwei", "xiahouba", "re_jiangwei", "gz_jiangwei", "ol_jiangwei"], + audioname2: { + dc_xiahouba: "tiaoxin_xiahouba", }, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.inRange(player)&&target.countCards('he')>0; + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.inRange(player) && target.countCards("he") > 0; }, - content:function(){ - "step 0" - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'挑衅:对'+get.translation(player)+'使用一张杀,或令其弃置你的一张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); - "step 1" - if(result.bool==false&&target.countCards('he')>0){ - player.discardPlayerCard(target,'he',true); - } - else{ + content: function () { + "step 0"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "挑衅:对" + get.translation(player) + "使用一张杀,或令其弃置你的一张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + if (result.bool == false && target.countCards("he") > 0) { + player.discardPlayerCard(target, "he", true); + } else { event.finish(); } }, - ai:{ - order:4, - expose:0.2, - result:{ - target:-1, - player:function(player,target){ - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.hp<=2) return -2; - if(player.countCards('h','shan')==0) return -1; + ai: { + order: 4, + expose: 0.2, + result: { + target: -1, + player: function (player, target) { + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.hp <= 2) return -2; + if (player.countCards("h", "shan") == 0) return -1; return -0.5; - } + }, }, - threaten:1.1 - } + threaten: 1.1, + }, }, - tiaoxin_xiahouba:{audio:2}, - zhiji:{ - skillAnimation:true, - animationColor:'fire', - audio:2, - audioname:['re_jiangwei'], - unique:true, - juexingji:true, + tiaoxin_xiahouba: { audio: 2 }, + zhiji: { + skillAnimation: true, + animationColor: "fire", + audio: 2, + audioname: ["re_jiangwei"], + unique: true, + juexingji: true, //priority:-10, - derivation:'reguanxing', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - if(player.storage.zhiji) return false; - return player.countCards('h')==0; + derivation: "reguanxing", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + if (player.storage.zhiji) return false; + return player.countCards("h") == 0; }, - content:function(){ - "step 0" - player.awakenSkill('zhiji'); - player.chooseDrawRecover(2,true); - "step 1" + content: function () { + "step 0"; + player.awakenSkill("zhiji"); + player.chooseDrawRecover(2, true); + "step 1"; player.loseMaxHp(); - player.addSkills('reguanxing'); - } - }, - xiangle:{ - audio:2, - audioname:['re_liushan','ol_liushan'], - trigger:{target:'useCardToTargeted'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return event.card.name=='sha'; + player.addSkills("reguanxing"); }, - content:function(){ - "step 0" - var eff=get.effect(player,trigger.card,trigger.player,trigger.player); - trigger.player.chooseToDiscard('享乐:弃置一张基本牌,否则杀对'+get.translation(player)+'无效',function(card){ - return get.type(card)=='basic'; - }).set('ai',function(card){ - if(_status.event.eff>0){ - return 10-get.value(card); - } - return 0; - }).set('eff',eff); - "step 1" - if(result.bool==false){ + }, + xiangle: { + audio: 2, + audioname: ["re_liushan", "ol_liushan"], + trigger: { target: "useCardToTargeted" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return event.card.name == "sha"; + }, + content: function () { + "step 0"; + var eff = get.effect(player, trigger.card, trigger.player, trigger.player); + trigger.player + .chooseToDiscard( + "享乐:弃置一张基本牌,否则杀对" + get.translation(player) + "无效", + function (card) { + return get.type(card) == "basic"; + } + ) + .set("ai", function (card) { + if (_status.event.eff > 0) { + return 10 - get.value(card); + } + return 0; + }) + .set("eff", eff); + "step 1"; + if (result.bool == false) { trigger.getParent().excluded.add(player); } }, - ai:{ - effect:{ - target_use:function(card,player,target,current){ - if(card.name=='sha'&&get.attitude(player,target)<0){ - if(_status.event.name=='xiangle') return; - if(get.attitude(player,target)>0&¤t<0) return 'zerotarget'; - var bs=player.getCards('h',{type:'basic'}); + ai: { + effect: { + target_use: function (card, player, target, current) { + if (card.name == "sha" && get.attitude(player, target) < 0) { + if (_status.event.name == "xiangle") return; + if (get.attitude(player, target) > 0 && current < 0) return "zerotarget"; + var bs = player.getCards("h", { type: "basic" }); bs.remove(card); - if(card.cards) bs.removeArray(card.cards); + if (card.cards) bs.removeArray(card.cards); else bs.removeArray(ui.selected.cards); - if(!bs.length) return 'zerotarget'; - if(player.hasSkill('jiu')||player.hasSkill('tianxianjiu')) return; - if(bs.length<=2){ - for(var i=0;i0&&!player.hasSkill('fangquan3'); + }, + }, }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - var fang=player.countMark('fangquan2')==0&&player.hp>=2&&player.countCards('h')<=player.hp+1; - player.chooseBool(get.prompt2('fangquan')).set('ai',function(){ - if(!_status.event.fang) return false; - return game.hasPlayer(function(target){ - if(target.hasJudge('lebu')||target==player) return false; - if(get.attitude(player,target)>4){ - return (get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1)>0); - } - return false; - }); - }).set('fang',fang).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - player.logSkill('fangquan'); + }, + fangquan: { + audio: 2, + trigger: { player: "phaseUseBefore" }, + filter: function (event, player) { + return player.countCards("h") > 0 && !player.hasSkill("fangquan3"); + }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + var fang = + player.countMark("fangquan2") == 0 && + player.hp >= 2 && + player.countCards("h") <= player.hp + 1; + player + .chooseBool(get.prompt2("fangquan")) + .set("ai", function () { + if (!_status.event.fang) return false; + return game.hasPlayer(function (target) { + if (target.hasJudge("lebu") || target == player) return false; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) > + 0 + ); + } + return false; + }); + }) + .set("fang", fang) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("fangquan"); trigger.cancel(); - player.addTempSkill('fangquan2'); - player.addMark('fangquan2',1,false); + player.addTempSkill("fangquan2"); + player.addMark("fangquan2", 1, false); //player.storage.fangquan=result.targets[0]; } - } + }, }, - fangquan2:{ - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - audio:false, + fangquan2: { + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + audio: false, //priority:-50, - onremove:true, - content:function(){ - "step 0" - event.count=player.countMark(event.name); - player.removeMark(event.name,event.count); - "step 1" + onremove: true, + content: function () { + "step 0"; + event.count = player.countMark(event.name); + player.removeMark(event.name, event.count); + "step 1"; event.count--; - player.chooseToDiscard('是否弃置一张牌并令一名其他角色进行一个额外回合?').set('logSkill',player.name=='re_liushan'?'refangquan':'fangquan').ai=function(card){ - return 20-get.value(card); - }; - "step 2" - if(result.bool){ - player.chooseTarget(true,'请选择进行额外回合的目标角色',lib.filter.notMe).ai=function(target){ - if(target.hasJudge('lebu')||get.attitude(player,target)<=0) return -1; - if(target.isTurnedOver()) return 0.18; - return get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1); + player + .chooseToDiscard("是否弃置一张牌并令一名其他角色进行一个额外回合?") + .set("logSkill", player.name == "re_liushan" ? "refangquan" : "fangquan").ai = + function (card) { + return 20 - get.value(card); }; - } - else event.finish(); - "step 3" - var target=result.targets[0]; - player.line(target,'fire'); - target.markSkillCharacter('fangquan',player,'放权','进行一个额外回合'); + "step 2"; + if (result.bool) { + player.chooseTarget(true, "请选择进行额外回合的目标角色", lib.filter.notMe).ai = + function (target) { + if (target.hasJudge("lebu") || get.attitude(player, target) <= 0) return -1; + if (target.isTurnedOver()) return 0.18; + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) + ); + }; + } else event.finish(); + "step 3"; + var target = result.targets[0]; + player.line(target, "fire"); + target.markSkillCharacter("fangquan", player, "放权", "进行一个额外回合"); target.insertPhase(); - target.addSkill('fangquan3'); - if(event.count>0) event.goto(1); - } + target.addSkill("fangquan3"); + if (event.count > 0) event.goto(1); + }, }, - fangquan3:{ - trigger:{player:['phaseAfter','phaseCancelled']}, - forced:true, - popup:false, - audio:false, - content:function(){ - player.unmarkSkill('fangquan'); - player.removeSkill('fangquan3'); - } + fangquan3: { + trigger: { player: ["phaseAfter", "phaseCancelled"] }, + forced: true, + popup: false, + audio: false, + content: function () { + player.unmarkSkill("fangquan"); + player.removeSkill("fangquan3"); + }, }, - ruoyu:{ - skillAnimation:true, - animationColor:'fire', - audio:2, - audioname:['re_liushan'], - unique:true, - juexingji:true, - zhuSkill:true, - keepSkill:true, - derivation:'rejijiang', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ + ruoyu: { + skillAnimation: true, + animationColor: "fire", + audio: 2, + audioname: ["re_liushan"], + unique: true, + juexingji: true, + zhuSkill: true, + keepSkill: true, + derivation: "rejijiang", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { return player.isMinHp(); }, - content:function(){ - 'step 0' - player.awakenSkill('ruoyu'); + content: function () { + "step 0"; + player.awakenSkill("ruoyu"); player.gainMaxHp(); player.recover(); - 'step 1' - player.addSkills('rejijiang'); - } - }, - qiaobian:{ - audio:2, - trigger:{player:['phaseJudgeBefore','phaseDrawBefore','phaseUseBefore','phaseDiscardBefore']}, - filter:function(event,player){ - return player.countCards('h')>0; + "step 1"; + player.addSkills("rejijiang"); }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - var check,str='弃置一张手牌并跳过'; - str+=['判定','摸牌','出牌','弃牌'][lib.skill.qiaobian.trigger.player.indexOf(event.triggername)]; - str+='阶段'; - if(trigger.name=='phaseDraw') str+=',然后可以获得至多两名角色各一张手牌'; - if(trigger.name=='phaseUse') str+=',然后可以移动场上的一张牌'; - switch(trigger.name){ - case 'phaseJudge': - check=player.countCards('j'); + }, + qiaobian: { + audio: 2, + trigger: { + player: ["phaseJudgeBefore", "phaseDrawBefore", "phaseUseBefore", "phaseDiscardBefore"], + }, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + var check, + str = "弃置一张手牌并跳过"; + str += ["判定", "摸牌", "出牌", "弃牌"][ + lib.skill.qiaobian.trigger.player.indexOf(event.triggername) + ]; + str += "阶段"; + if (trigger.name == "phaseDraw") str += ",然后可以获得至多两名角色各一张手牌"; + if (trigger.name == "phaseUse") str += ",然后可以移动场上的一张牌"; + switch (trigger.name) { + case "phaseJudge": + check = player.countCards("j"); break; - case 'phaseDraw': - var i,num=0,num2=0,players=game.filterPlayer(); - for(i=0;i=2&&num2>0); + check = num >= 2 && num2 > 0; break; - case 'phaseUse': - if(!player.canMoveCard(true)){ - check=false; - } - else{ - check=game.hasPlayer(function(current){ - return get.attitude(player,current)>0&¤t.countCards('j'); + case "phaseUse": + if (!player.canMoveCard(true)) { + check = false; + } else { + check = game.hasPlayer(function (current) { + return get.attitude(player, current) > 0 && current.countCards("j"); }); - if(!check){ - if(player.countCards('h')>player.hp+1){ - check=false; - } - else if(player.countCards('h',{name:'wuzhong'})){ - check=false; - } - else{ - check=true; + if (!check) { + if (player.countCards("h") > player.hp + 1) { + check = false; + } else if (player.countCards("h", { name: "wuzhong" })) { + check = false; + } else { + check = true; } } } break; - case 'phaseDiscard': - check=player.needsToDiscard(); + case "phaseDiscard": + check = player.needsToDiscard(); break; } - player.chooseToDiscard(get.prompt('qiaobian'),str,lib.filter.cardDiscardable).set('ai',card=>{ - if(!_status.event.check) return -1; - return 7-get.value(card); - }).set('check',check).set('logSkill','qiaobian').setHiddenSkill('qiaobian'); - 'step 1' - if(result.bool){ + player + .chooseToDiscard(get.prompt("qiaobian"), str, lib.filter.cardDiscardable) + .set("ai", (card) => { + if (!_status.event.check) return -1; + return 7 - get.value(card); + }) + .set("check", check) + .set("logSkill", "qiaobian") + .setHiddenSkill("qiaobian"); + "step 1"; + if (result.bool) { trigger.cancel(); - game.log(player,'跳过了','#y'+['判定','摸牌','出牌','弃牌'][lib.skill.qiaobian.trigger.player.indexOf(event.triggername)]+'阶段'); - if(trigger.name=='phaseUse'){ - if(player.canMoveCard()) player.moveCard(); + game.log( + player, + "跳过了", + "#y" + + ["判定", "摸牌", "出牌", "弃牌"][ + lib.skill.qiaobian.trigger.player.indexOf(event.triggername) + ] + + "阶段" + ); + if (trigger.name == "phaseUse") { + if (player.canMoveCard()) player.moveCard(); event.finish(); - } - else if(trigger.name=='phaseDraw'){ - player.chooseTarget([1,2],'获得至多两名角色各一张手牌',function(card,player,target){ - return target!=player&&target.countCards('h'); - }).set('ai',function(target){ - return 1-get.attitude(_status.event.player,target); - }); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ + } else if (trigger.name == "phaseDraw") { + player + .chooseTarget( + [1, 2], + "获得至多两名角色各一张手牌", + function (card, player, target) { + return target != player && target.countCards("h"); + } + ) + .set("ai", function (target) { + return 1 - get.attitude(_status.event.player, target); + }); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { result.targets.sortBySeat(); - player.line(result.targets,'green'); - event.targets=result.targets; - if(!event.targets.length) event.finish(); - } - else event.finish(); - 'step 3' + player.line(result.targets, "green"); + event.targets = result.targets; + if (!event.targets.length) event.finish(); + } else event.finish(); + "step 3"; player.gainMultiple(event.targets); - 'step 4' + "step 4"; game.delay(); }, - ai:{threaten:3}, + ai: { threaten: 3 }, }, - tuntian:{ - audio:2, - audioname:['gz_dengai'], - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + tuntian: { + audio: 2, + audioname: ["gz_dengai"], + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - frequent:true, - preHidden:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + frequent: true, + preHidden: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - content:function(){ - 'step 0' - var next=player.judge(function(card){ - if(get.suit(card)=='heart') return -1; + content: function () { + "step 0"; + var next = player.judge(function (card) { + if (get.suit(card) == "heart") return -1; return 1; }); - next.judge2=function(result){ + next.judge2 = function (result) { return result.bool; }; - if(get.mode()!='guozhan'){ - next.callback=lib.skill.tuntian.callback; + if (get.mode() != "guozhan") { + next.callback = lib.skill.tuntian.callback; event.finish(); } - 'step 1' - if(!result.bool||get.position(result.card)!='d'){ + "step 1"; + if (!result.bool || get.position(result.card) != "d") { //game.cardsDiscard(card); event.finish(); return; } - event.card=result.card; - player.chooseBool('是否将'+get.translation(event.card)+'作为“田”置于武将牌上?').ai=function(){ - return true; - }; - 'step 2' - if(!result.bool&&!event.directbool){ + event.card = result.card; + player.chooseBool("是否将" + get.translation(event.card) + "作为“田”置于武将牌上?").ai = + function () { + return true; + }; + "step 2"; + if (!result.bool && !event.directbool) { return; } - player.addToExpansion(event.card,'gain2').gaintag.add('tuntian'); + player.addToExpansion(event.card, "gain2").gaintag.add("tuntian"); }, - callback:function(){ - if(!event.judgeResult.bool){ + callback: function () { + if (!event.judgeResult.bool) { event.finish(); return; } - player.addToExpansion(event.judgeResult.card,'gain2').gaintag.add('tuntian'); + player.addToExpansion(event.judgeResult.card, "gain2").gaintag.add("tuntian"); }, - marktext:'田', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "田", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'tuntian_dist', - locked:false, - subSkill:{ - dist:{ - locked:false, - mod:{ - globalFrom:function(from,to,distance){ - var num=distance-from.getExpansions('tuntian').length; - if(_status.event.skill=='jixi_backup'||_status.event.skill=='gzjixi_backup') num++; + group: "tuntian_dist", + locked: false, + subSkill: { + dist: { + locked: false, + mod: { + globalFrom: function (from, to, distance) { + var num = distance - from.getExpansions("tuntian").length; + if ( + _status.event.skill == "jixi_backup" || + _status.event.skill == "gzjixi_backup" + ) + num++; return num; - } - } - } - }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(typeof card==='object'&&get.name(card)==='sha'&&target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return [0.6,0.75]; - if(!target.hasFriend()&&!player.hasUnknown()) return; - if(_status.currentPhase==target||get.type(card)==='delay') return; - if(card.name!='shuiyanqijunx'&&get.tag(card,'loseCard')&&target.countCards('he')){ - if(target.hasSkill('ziliang')) return 0.7; - return [0.5,Math.max(2,target.countCards('h'))]; - } - if(target.isUnderControl(true,player)){ - if((get.tag(card,'respondSha')&&target.countCards('h','sha'))|| - (get.tag(card,'respondShan')&&target.countCards('h','shan'))){ - if(target.hasSkill('ziliang')) return 0.7; - return [0.5,1]; - } - } - else if(get.tag(card,'respondSha')||get.tag(card,'respondShan')){ - if(get.attitude(player,target)>0&&card.name=='juedou') return; - if(get.tag(card,'damage')&&target.hasSkillTag('maixie')) return; - if(target.countCards('h')==0) return 2; - if(target.hasSkill('ziliang')) return 0.7; - if(get.mode()=='guozhan') return 0.5; - return [0.5,Math.max(target.countCards('h')/4,target.countCards('h','sha')+target.countCards('h','shan'))]; - } - } + }, + }, }, - threaten:function(player,target){ - if(target.countCards('h')==0) return 2; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if ( + typeof card === "object" && + get.name(card) === "sha" && + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return [0.6, 0.75]; + if (!target.hasFriend() && !player.hasUnknown()) return; + if (_status.currentPhase == target || get.type(card) === "delay") return; + if ( + card.name != "shuiyanqijunx" && + get.tag(card, "loseCard") && + target.countCards("he") + ) { + if (target.hasSkill("ziliang")) return 0.7; + return [0.5, Math.max(2, target.countCards("h"))]; + } + if (target.isUnderControl(true, player)) { + if ( + (get.tag(card, "respondSha") && target.countCards("h", "sha")) || + (get.tag(card, "respondShan") && target.countCards("h", "shan")) + ) { + if (target.hasSkill("ziliang")) return 0.7; + return [0.5, 1]; + } + } else if (get.tag(card, "respondSha") || get.tag(card, "respondShan")) { + if (get.attitude(player, target) > 0 && card.name == "juedou") return; + if (get.tag(card, "damage") && target.hasSkillTag("maixie")) return; + if (target.countCards("h") == 0) return 2; + if (target.hasSkill("ziliang")) return 0.7; + if (get.mode() == "guozhan") return 0.5; + return [ + 0.5, + Math.max( + target.countCards("h") / 4, + target.countCards("h", "sha") + target.countCards("h", "shan") + ), + ]; + } + }, + }, + threaten: function (player, target) { + if (target.countCards("h") == 0) return 2; return 0.5; }, - nodiscard:true, - nolose:true - } - }, - zaoxian:{ - skillAnimation:true, - animationColor:'thunder', - audio:2, - audioname:['re_dengai'], - unique:true, - juexingji:true, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('tuntian').length>=3; + nodiscard: true, + nolose: true, }, - derivation:'jixi', - content:function(){ - player.awakenSkill('zaoxian'); + }, + zaoxian: { + skillAnimation: true, + animationColor: "thunder", + audio: 2, + audioname: ["re_dengai"], + unique: true, + juexingji: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("tuntian").length >= 3; + }, + derivation: "jixi", + content: function () { + player.awakenSkill("zaoxian"); player.loseMaxHp(); - player.addSkills('jixi'); - } - }, - jixi:{ - audio:2, - audioname:['re_dengai','gz_dengai','ol_dengai'], - enable:'phaseUse', - filter:function(event,player){ - return player.getExpansions('tuntian').length>0&&event.filterCard({name:'shunshou'},player,event); + player.addSkills("jixi"); }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('急袭',player.getExpansions('tuntian'),'hidden'); + }, + jixi: { + audio: 2, + audioname: ["re_dengai", "gz_dengai", "ol_dengai"], + enable: "phaseUse", + filter: function (event, player) { + return ( + player.getExpansions("tuntian").length > 0 && + event.filterCard({ name: "shunshou" }, player, event) + ); + }, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("急袭", player.getExpansions("tuntian"), "hidden"); }, - filter:function(button,player){ - var card=button.link; - if(!game.checkMod(card,player,'unchanged','cardEnabled2',player)) return false; - var evt=_status.event.getParent(); - return evt.filterCard(get.autoViewAs({name:'shunshou'},[card]),player,evt) + filter: function (button, player) { + var card = button.link; + if (!game.checkMod(card, player, "unchanged", "cardEnabled2", player)) return false; + var evt = _status.event.getParent(); + return evt.filterCard(get.autoViewAs({ name: "shunshou" }, [card]), player, evt); }, - backup:function(links,player){ - var skill=_status.event.buttoned; + backup: function (links, player) { + var skill = _status.event.buttoned; return { - audio:'jixi', - audioname:['re_dengai','gz_dengai','ol_dengai'], - selectCard:-1, - position:'x', - filterCard:skill=='jixi'?(card)=>card==lib.skill.jixi_backup.card:(card)=>card==lib.skill.gzjixi_backup.card, - viewAs:{name:'shunshou'}, - card:links[0], - } + audio: "jixi", + audioname: ["re_dengai", "gz_dengai", "ol_dengai"], + selectCard: -1, + position: "x", + filterCard: + skill == "jixi" + ? (card) => card == lib.skill.jixi_backup.card + : (card) => card == lib.skill.gzjixi_backup.card, + viewAs: { name: "shunshou" }, + card: links[0], + }; + }, + prompt: function (links, player) { + return "选择 顺手牵羊(" + get.translation(links[0]) + ")的目标"; }, - prompt:function(links,player){ - return '选择 顺手牵羊('+get.translation(links[0])+')的目标'; - } }, - ai:{ - order:10, - result:{ - player:function(player){ - return player.getExpansions('tuntian').length-1; - } - } - } + ai: { + order: 10, + result: { + player: function (player) { + return player.getExpansions("tuntian").length - 1; + }, + }, + combo: "tuntian", + }, }, - jiang:{ - shaRelated:true, - 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; - } + jiang: { + shaRelated: true, + 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', + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter:function(event,player){ - 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; + filter: function (event, player) { + 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(){ + locked: false, + frequent: true, + content: function () { player.draw(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,0.6]; + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 0.6]; }, - player:function(card,player,target){ - if(card.name=='sha'&&get.color(card)=='red') return [1,1]; - } - } - } - }, - hunzi:{ - //audioname:['re_sunben'], - skillAnimation:true, - animationColor:'wood', - audio:2, - juexingji:true, - derivation:['reyingzi','gzyinghun'], - unique:true, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.hp<=1&&!player.storage.hunzi; + player: function (card, player, target) { + if (card.name == "sha" && get.color(card) == "red") return [1, 1]; + }, + }, }, - forced:true, + }, + hunzi: { + //audioname:['re_sunben'], + skillAnimation: true, + animationColor: "wood", + audio: 2, + juexingji: true, + derivation: ["reyingzi", "gzyinghun"], + unique: true, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.hp <= 1 && !player.storage.hunzi; + }, + forced: true, //priority:3, - content:function(){ + content: function () { player.awakenSkill(event.name); player.loseMaxHp(); - player.addSkills(['reyingzi','gzyinghun']); + player.addSkills(["reyingzi", "gzyinghun"]); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 2; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 2; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(!target.hasFriend()) return; - if(target.hp===2&&get.tag(card,'damage')==1&&!target.isTurnedOver()&& - _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; - if(target.hp===1&&get.tag(card,'recover')&&!target.isTurnedOver()&& - _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [1,-3]; - } - } - } + maixie: true, + effect: { + target: function (card, player, target) { + if (!target.hasFriend()) return; + if ( + target.hp === 2 && + get.tag(card, "damage") == 1 && + !target.isTurnedOver() && + _status.currentPhase !== target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [0.5, 1]; + if ( + target.hp === 1 && + get.tag(card, "recover") && + !target.isTurnedOver() && + _status.currentPhase !== target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [1, -3]; + }, + }, + }, }, - zhiba:{ - unique:true, - global:'zhiba2', - audioname:['re_sunben'], - audio:'zhiba2', - zhuSkill:true, + zhiba: { + unique: true, + global: "zhiba2", + audioname: ["re_sunben"], + audio: "zhiba2", + zhuSkill: true, }, - zhiba2:{ - audio:2, - audioname:['re_sunben'], + zhiba2: { + audio: 2, + audioname: ["re_sunben"], //forceaudio:true, - enable:'phaseUse', - prompt:function(){ - var player=_status.event.player; - var list=game.filterPlayer(function(target){ - return target.hasZhuSkill('zhiba',player)&&player.canCompare(target); + enable: "phaseUse", + prompt: function () { + var player = _status.event.player; + var list = game.filterPlayer(function (target) { + return target.hasZhuSkill("zhiba", player) && player.canCompare(target); }); - var str='和'+get.translation(list); - if(list.length>1) str+='中的一人'; - str+='进行拼点。若你没赢,其可以获得两张拼点牌。'; + var str = "和" + get.translation(list); + if (list.length > 1) str += "中的一人"; + str += "进行拼点。若你没赢,其可以获得两张拼点牌。"; return str; }, - filter:function(event,player){ - if(player.group!='wu'||player.countCards('h')==0) return false; - return game.hasPlayer(function(target){ - return target.hasZhuSkill('zhiba',player)&&player.canCompare(target); + filter: function (event, player) { + if (player.group != "wu" || player.countCards("h") == 0) return false; + return game.hasPlayer(function (target) { + return target.hasZhuSkill("zhiba", player) && player.canCompare(target); }); }, - filterTarget:function(card,player,target){ - return target.hasZhuSkill('zhiba',player)&&player.canCompare(target); + filterTarget: function (card, player, target) { + return target.hasZhuSkill("zhiba", player) && player.canCompare(target); }, - log:false, - prepare:function(cards,player,targets){ - targets[0].logSkill('zhiba'); + log: false, + prepare: function (cards, player, targets) { + targets[0].logSkill("zhiba"); }, - usable:1, - content:function(){ - "step 0" - if(target.storage.hunzi||target.storage.rehunzi){ - target.chooseControl('拒绝','不拒绝').set('prompt','是否拒绝制霸拼点?').set('choice',get.attitude(target,player)<=0); + usable: 1, + content: function () { + "step 0"; + if (target.storage.hunzi || target.storage.rehunzi) { + target + .chooseControl("拒绝", "不拒绝") + .set("prompt", "是否拒绝制霸拼点?") + .set("choice", get.attitude(target, player) <= 0); + } else { + event.forced = true; } - else{ - event.forced=true; - } - "step 1" - if(!event.forced&&result.control=='拒绝'){ - game.log(target,'拒绝了拼点'); - target.chat('拒绝'); + "step 1"; + if (!event.forced && result.control == "拒绝") { + game.log(target, "拒绝了拼点"); + target.chat("拒绝"); event.finish(); return; } - player.chooseToCompare(target,function(card){ - if(card.name=='du') return 20; - var player=get.owner(card); - var target=_status.event.getParent().target; - if(player!=target&&get.attitude(player,target)>0){ - return -get.number(card); - } - return get.number(card); - }).set('preserve','lose'); - "step 2" - if(result.bool==false){ - var list=[]; - if(get.position(result.player)=='d') list.push(result.player); - if(get.position(result.target)=='d') list.push(result.target); - if(!list.length) event.finish(); - else{ - event.list=list; - target.chooseBool('是否获得'+get.translation(list)+'?').ai=function(){ - return get.value(list)>0; + player + .chooseToCompare(target, function (card) { + if (card.name == "du") return 20; + var player = get.owner(card); + var target = _status.event.getParent().target; + if (player != target && get.attitude(player, target) > 0) { + return -get.number(card); + } + return get.number(card); + }) + .set("preserve", "lose"); + "step 2"; + if (result.bool == false) { + var list = []; + if (get.position(result.player) == "d") list.push(result.player); + if (get.position(result.target) == "d") list.push(result.target); + if (!list.length) event.finish(); + else { + event.list = list; + target.chooseBool("是否获得" + get.translation(list) + "?").ai = function () { + return get.value(list) > 0; }; } - } - else event.finish(); - "step 3" - if(result.bool) target.gain(event.list,'gain2'); + } else event.finish(); + "step 3"; + if (result.bool) target.gain(event.list, "gain2"); }, - ai:{ - basic:{ - order:1 + ai: { + basic: { + order: 1, }, - expose:0.2, - result:{ - target:function(player,target){ - if(player.countCards('h','du')&&get.attitude(player,target)<0) return -1; - if(player.countCards('h')<=player.hp) return 0; - var maxnum=0; - var cards2=target.getCards('h'); - for(var i=0;imaxnum){ - maxnum=get.number(cards2[i]); + expose: 0.2, + result: { + target: function (player, target) { + if (player.countCards("h", "du") && get.attitude(player, target) < 0) return -1; + if (player.countCards("h") <= player.hp) return 0; + var maxnum = 0; + var cards2 = target.getCards("h"); + for (var i = 0; i < cards2.length; i++) { + if (get.number(cards2[i]) > maxnum) { + maxnum = get.number(cards2[i]); } } - if(maxnum>10) maxnum=10; - if(maxnum<5&&cards2.length>1) maxnum=5; - var cards=player.getCards('h'); - for(var i=0;i 10) maxnum = 10; + if (maxnum < 5 && cards2.length > 1) maxnum = 5; + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + if (get.number(cards[i]) < maxnum) return 1; } return 0; - } - } - } + }, + }, + }, }, - zhijian:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h',{type:'equip'})>0; + zhijian: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", { type: "equip" }) > 0; }, - filterCard:function(card){ - return get.type(card)=='equip'; + filterCard: function (card) { + return get.type(card) == "equip"; }, - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - return player!=target&&target.canEquip(card); + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + return player != target && target.canEquip(card); }, - async content(event, trigger, player){ + async content(event, trigger, player) { event.target.equip(event.cards[0]); player.draw(); }, - discard:false, - lose:false, - prepare:function(cards,player,targets){ - player.$give(cards,targets[0],false); + discard: false, + lose: false, + prepare: function (cards, player, targets) { + player.$give(cards, targets[0], false); }, - ai:{ - basic:{ - order:10 + ai: { + basic: { + order: 10, }, - result:{ - target:function(player,target){ - var card=ui.selected.cards[0]; - if(card) return get.effect(target,card,target,target); + result: { + target: function (player, target) { + var card = ui.selected.cards[0]; + if (card) return get.effect(target, card, target, target); return 0; }, }, - threaten:1.3 - } + threaten: 1.3, + }, }, - guzheng:{ - audio:2, - audioname:['re_zhangzhang'], - trigger:{global:'phaseDiscardAfter'}, - filter:function(event,player){ - if(event.player!=player&&event.player.isIn()){ - return event.player.getHistory('lose',function(evt){ - return evt.type=='discard'&&evt.getParent('phaseDiscard')==event&&evt.hs.someInD('d'); - }).length>0; + guzheng: { + audio: 2, + audioname: ["re_zhangzhang"], + trigger: { global: "phaseDiscardAfter" }, + filter: function (event, player) { + if (event.player != player && event.player.isIn()) { + return ( + event.player.getHistory("lose", function (evt) { + return ( + evt.type == "discard" && + evt.getParent("phaseDiscard") == event && + evt.hs.someInD("d") + ); + }).length > 0 + ); } return false; }, - checkx:function(event,player,cards,cards2){ - if(cards.length>2||get.attitude(player,event.player)>0) return true; - for(var i=0;i 2 || get.attitude(player, event.player) > 0) return true; + for (var i = 0; i < cards2.length; i++) { + if (get.value(cards2[i], event.player, "raw") < 0) return true; } return false; }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - var cards=[],cards2=[]; - var target=trigger.player; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name=='cardsDiscard'){ - if(evt.getParent('phaseDiscard')==trigger){ - var moves=evt.cards.filterInD('d'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + var cards = [], + cards2 = []; + var target = trigger.player; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name == "cardsDiscard") { + if (evt.getParent("phaseDiscard") == trigger) { + var moves = evt.cards.filterInD("d"); cards.addArray(moves); cards2.removeArray(moves); } } - if(evt.name=='lose'){ - if(evt.type!='discard'||evt.position!=ui.discardPile||evt.getParent('phaseDiscard')!=trigger) return; - var moves=evt.cards.filterInD('d'); + if (evt.name == "lose") { + if ( + evt.type != "discard" || + evt.position != ui.discardPile || + evt.getParent("phaseDiscard") != trigger + ) + return; + var moves = evt.cards.filterInD("d"); cards.addArray(moves); - if(evt.player==target) cards2.addArray(moves); + if (evt.player == target) cards2.addArray(moves); else cards2.removeArray(moves); } }); - if(!cards2.length) event.finish(); - else if(cards.length==1){ - event.card=cards[0]; - player.chooseBool().set('createDialog',[ - get.prompt('guzheng',target), - '点击“确认”以令其收回此牌', - cards, - ]).set('choice',lib.skill.guzheng.checkx(trigger,player,cards,cards2)).set('ai',function(){ - return _status.event.choice; - }).setHiddenSkill('guzheng'); + if (!cards2.length) event.finish(); + else if (cards.length == 1) { + event.card = cards[0]; + player + .chooseBool() + .set("createDialog", [ + get.prompt("guzheng", target), + '点击“确认”以令其收回此牌', + cards, + ]) + .set("choice", lib.skill.guzheng.checkx(trigger, player, cards, cards2)) + .set("ai", function () { + return _status.event.choice; + }) + .setHiddenSkill("guzheng"); + } else { + player + .chooseButton(2, [ + get.prompt("guzheng", target), + '被选择的牌将成为对方收回的牌', + cards, + [["获得剩余的牌", "放弃剩余的牌"], "tdnodes"], + ]) + .set("filterButton", function (button) { + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + return type == "string" || _status.event.allowed.includes(button.link); + }) + .set("allowed", cards2) + .set("check", lib.skill.guzheng.checkx(trigger, player, cards, cards2)) + .set("ai", function (button) { + if (typeof button.link == "string") { + return button.link == "获得剩余的牌" ? 1 : 0; + } + if (_status.event.check) { + return 20 - get.value(button.link, _status.event.getTrigger().player); + } + return 0; + }) + .setHiddenSkill("guzheng"); } - else{ - player.chooseButton(2,[ - get.prompt('guzheng',target), - '被选择的牌将成为对方收回的牌', - cards, - [['获得剩余的牌','放弃剩余的牌'],'tdnodes'], - ]).set('filterButton',function(button){ - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - return type=='string'||_status.event.allowed.includes(button.link); - }).set('allowed',cards2).set('check',lib.skill.guzheng.checkx(trigger,player,cards,cards2)).set('ai',function(button){ - if(typeof button.link=='string'){ - return button.link=='获得剩余的牌'?1:0; - } - if(_status.event.check){ - return 20-get.value(button.link,_status.event.getTrigger().player); - } - return 0; - }).setHiddenSkill('guzheng'); - } - 'step 1' - if(result.bool){ - var target=trigger.player; - player.logSkill('guzheng',target); - if(!result.links||!result.links.length){ - target.gain(card,'gain2').giver=player; + "step 1"; + if (result.bool) { + var target = trigger.player; + player.logSkill("guzheng", target); + if (!result.links || !result.links.length) { + target.gain(card, "gain2").giver = player; + } else { + if (typeof result.links[0] != "string") result.links.reverse(); + var card = result.links[1]; + target.gain(card, "gain2").giver = player; + if (result.links[0] != "获得剩余的牌") event.finish(); } - else{ - if(typeof result.links[0]!='string') result.links.reverse(); - var card=result.links[1]; - target.gain(card,'gain2').giver=player; - if(result.links[0]!='获得剩余的牌') event.finish(); - } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; //避免插入结算改变弃牌堆 重新判断一次 - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name=='cardsDiscard'){ - if(evt.getParent('phaseDiscard')==trigger){ - var moves=evt.cards.filterInD('d'); + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name == "cardsDiscard") { + if (evt.getParent("phaseDiscard") == trigger) { + var moves = evt.cards.filterInD("d"); cards.addArray(moves); } } - if(evt.name=='lose'){ - if(evt.type!='discard'||evt.position!=ui.discardPile||evt.getParent('phaseDiscard')!=trigger) return; - var moves=evt.cards.filterInD('d'); + if (evt.name == "lose") { + if ( + evt.type != "discard" || + evt.position != ui.discardPile || + evt.getParent("phaseDiscard") != trigger + ) + return; + var moves = evt.cards.filterInD("d"); cards.addArray(moves); } }); - if(cards.length>0) player.gain(cards,'gain2'); + if (cards.length > 0) player.gain(cards, "gain2"); + }, + ai: { + threaten: 1.3, + expose: 0.2, }, - ai:{ - threaten:1.3, - expose:0.2 - } }, - beige:{ - audio:2, - audioname:['re_caiwenji','ol_caiwenji'], - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return (event.card&&event.card.name=='sha'&&event.source&& - event.player.isIn()&&player.countCards('he')); + beige: { + audio: 2, + audioname: ["re_caiwenji", "ol_caiwenji"], + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.source && + event.player.isIn() && + player.countCards("he") + ); }, - direct:true, - checkx:function(event,player){ - var att1=get.attitude(player,event.player); - var att2=get.attitude(player,event.source); - return att1>0&&att2<=0; + direct: true, + checkx: function (event, player) { + var att1 = get.attitude(player, event.player); + var att2 = get.attitude(player, event.source); + return att1 > 0 && att2 <= 0; }, - preHidden:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he',get.prompt2('beige',trigger.player)); - var check=lib.skill.beige.checkx(trigger,player); - next.set('ai',function(card){ - if(_status.event.goon) return 8-get.value(card); + preHidden: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard("he", get.prompt2("beige", trigger.player)); + var check = lib.skill.beige.checkx(trigger, player); + next.set("ai", function (card) { + if (_status.event.goon) return 8 - get.value(card); return 0; }); - next.set('logSkill','beige'); - next.set('goon',check); - next.setHiddenSkill('beige'); - "step 1" - if(result.bool){ + next.set("logSkill", "beige"); + next.set("goon", check); + next.setHiddenSkill("beige"); + "step 1"; + if (result.bool) { trigger.player.judge(); - } - else{ + } else { event.finish(); } - "step 2" - switch(result.suit){ - case 'heart':trigger.player.recover();break; - case 'diamond':trigger.player.draw(2);break; - case 'club':trigger.source.chooseToDiscard('he',2,true);break; - case 'spade':trigger.source.turnOver();break; + "step 2"; + switch (result.suit) { + case "heart": + trigger.player.recover(); + break; + case "diamond": + trigger.player.draw(2); + break; + case "club": + trigger.source.chooseToDiscard("he", 2, true); + break; + case "spade": + trigger.source.turnOver(); + break; } }, - ai:{ - expose:0.3 - } - }, - duanchang:{ - audio:2, - audioname:['re_caiwenji','ol_caiwenji'], - forbid:['boss'], - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event){ - return event.source&&event.source.isIn(); + ai: { + expose: 0.3, }, - content:function(){ + }, + duanchang: { + audio: 2, + audioname: ["re_caiwenji", "ol_caiwenji"], + forbid: ["boss"], + trigger: { player: "die" }, + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event) { + return event.source && event.source.isIn(); + }, + content: function () { trigger.source.clearSkills(); }, - logTarget:'source', - ai:{ - maixie_defend:true, - threaten:function(player,target){ - if(target.hp==1) return 0.2; + logTarget: "source", + ai: { + maixie_defend: true, + threaten: function (player, target) { + if (target.hp == 1) return 0.2; return 1.5; }, - effect:{ - target:function(card,player,target,current){ - if(!target.hasFriend()) return; - if(target.hp<=1&&get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return 3; - return [1,0,0,-3*get.threaten(player)]; + effect: { + target: function (card, player, target, current) { + if (!target.hasFriend()) return; + if (target.hp <= 1 && get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return 3; + return [1, 0, 0, -3 * get.threaten(player)]; } - } - } - } + }, + }, + }, }, - huashen:{ - audio:'huashen2', - unique:true, - init:function(player){ - if(!player.storage.huashen){ - player.storage.huashen={ - owned:{} + huashen: { + audio: "huashen2", + unique: true, + init: function (player) { + if (!player.storage.huashen) { + player.storage.huashen = { + owned: {}, }; } - player.when('dieBegin').then(()=>{ - const name=player.name?player.name:player.name1; - if(name){ - const sex=get.character(name,0); - const group=get.character(name,1); - if(player.sex!=sex){ - game.broadcastAll((player,sex)=>{ - player.sex=sex; - },player,sex); - game.log(player,'将性别变为了','#y'+get.translation(sex)+'性'); + player.when("dieBegin").then(() => { + const name = player.name ? player.name : player.name1; + if (name) { + const sex = get.character(name, 0); + const group = get.character(name, 1); + if (player.sex != sex) { + game.broadcastAll( + (player, sex) => { + player.sex = sex; + }, + player, + sex + ); + game.log(player, "将性别变为了", "#y" + get.translation(sex) + "性"); } - if(player.group!=group) player.changeGroup(group); + if (player.group != group) player.changeGroup(group); } }); }, - intro:{ - content:function(storage,player){ - var str=''; - var list=Object.keys(storage.owned); - if(list.length){ - str+=get.translation(list[0]); - for(var i=1;ilib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - dialog.add('
              【'+get.translation(lib.translate[skill+'_ab']||get.translation(skill).slice(0,2))+'】
              '+ - '
              '+get.skillInfoTranslation(skill,player)+'
              '); + mark: function (dialog, content, player) { + var list = Object.keys(content.owned); + if (list.length) { + var skill = player.storage.huashen.current2; + var character = player.storage.huashen.current; + if (skill && character) { + dialog.addSmall([ + [character], + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton( + item, + type, + position, + noclick, + node + ), + ]); + dialog.add( + '
              【' + + get.translation( + lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2) + ) + + "】
              " + + "
              " + + get.skillInfoTranslation(skill, player) + + "
              " + ); } - if(player.isUnderControl(true)){ - dialog.addSmall([list,(item,type,position,noclick,node)=>lib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - } - else{ - dialog.addText('共有'+get.cnNumber(list.length)+'张“化身”'); + if (player.isUnderControl(true)) { + dialog.addSmall([ + list, + (item, type, position, noclick, node) => + lib.skill.rehuashen.$createButton( + item, + type, + position, + noclick, + node + ), + ]); + } else { + dialog.addText("共有" + get.cnNumber(list.length) + "张“化身”"); } + } else { + return "没有化身"; } - else{ - return '没有化身'; - } - } + }, }, - addHuashen:function(player){ - if(!player.storage.huashen) return; - if(!_status.characterlist){ + addHuashen: function (player) { + if (!player.storage.huashen) return; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } _status.characterlist.randomSort(); - for(var i=0;i<_status.characterlist.length;i++){ - let name=_status.characterlist[i]; - if(name.indexOf('zuoci')!=-1||name.indexOf('key_')==0||name.indexOf('sp_key_')==0||lib.skill.rehuashen.banned.includes(name)||player.storage.huashen.owned[name]) continue; - let skills=lib.character[name][3].filter(skill=>{ - const categories=get.skillCategoriesOf(skill); - return !categories.some(type=>lib.skill.rehuashen.bannedType.includes(type)); - }) - if(skills.length){ - player.storage.huashen.owned[name]=skills; + for (var i = 0; i < _status.characterlist.length; i++) { + let name = _status.characterlist[i]; + if ( + name.indexOf("zuoci") != -1 || + name.indexOf("key_") == 0 || + name.indexOf("sp_key_") == 0 || + lib.skill.rehuashen.banned.includes(name) || + player.storage.huashen.owned[name] + ) + continue; + let skills = lib.character[name][3].filter((skill) => { + const categories = get.skillCategoriesOf(skill); + return !categories.some((type) => lib.skill.rehuashen.bannedType.includes(type)); + }); + if (skills.length) { + player.storage.huashen.owned[name] = skills; _status.characterlist.remove(name); return name; } } }, - addHuashens:function(player,num){ - var list=[]; - for(var i=0;ilib.skill.rehuashen.$createButton(item,type,position,noclick,node)]); - event.dialog=dialog; - event.forceMine=true; - event.button=null; - for(var i=0;i + lib.skill.rehuashen.$createButton(item, type, position, noclick, node), + ]); + event.dialog = dialog; + event.forceMine = true; + event.button = null; + for (var i = 0; i < event.dialog.buttons.length; i++) { + event.dialog.buttons[i].classList.add("pointerdiv"); + event.dialog.buttons[i].classList.add("selectable"); } event.dialog.open(); - event.custom.replace.button=function(button){ - if(!event.dialog.contains(button.parentNode)) return; - if(event.control) event.control.style.opacity=1; - if(button.classList.contains('selectedx')){ - event.button=null; - button.classList.remove('selectedx'); - if(event.control){ - event.control.replacex(['cancel2']); + event.custom.replace.button = function (button) { + if (!event.dialog.contains(button.parentNode)) return; + if (event.control) event.control.style.opacity = 1; + if (button.classList.contains("selectedx")) { + event.button = null; + button.classList.remove("selectedx"); + if (event.control) { + event.control.replacex(["cancel2"]); } - } - else{ - if(event.button){ - event.button.classList.remove('selectedx'); + } else { + if (event.button) { + event.button.classList.remove("selectedx"); } - button.classList.add('selectedx'); - event.button=button; - if(event.control&&button.link){ + button.classList.add("selectedx"); + event.button = button; + if (event.control && button.link) { event.control.replacex(player.storage.huashen.owned[button.link]); } } game.check(); - } - event.custom.replace.window=function(){ - if(event.button){ - event.button.classList.remove('selectedx'); - event.button=null; + }; + event.custom.replace.window = function () { + if (event.button) { + event.button.classList.remove("selectedx"); + event.button = null; } - event.control.replacex(['cancel2']); - } + event.control.replacex(["cancel2"]); + }; - event.switchToAuto=function(){ - var cards=[]; - var skills=[]; - for(var i in player.storage.huashen.owned){ + event.switchToAuto = function () { + var cards = []; + var skills = []; + for (var i in player.storage.huashen.owned) { cards.push(i); skills.addArray(player.storage.huashen.owned[i]); } - var cond=event.triggername=='phaseBegin'?'in':'out'; + var cond = event.triggername == "phaseBegin" ? "in" : "out"; skills.randomSort(); - skills.sort(function(a,b){ - return get.skillRank(b,cond)-get.skillRank(a,cond); + skills.sort(function (a, b) { + return get.skillRank(b, cond) - get.skillRank(a, cond); }); - _status.imchoosing=false; - var skill=skills[0],character; - for(var i in player.storage.huashen.owned){ - if(player.storage.huashen.owned[i].includes(skill)){ - character=i; break; + _status.imchoosing = false; + var skill = skills[0], + character; + for (var i in player.storage.huashen.owned) { + if (player.storage.huashen.owned[i].includes(skill)) { + character = i; + break; } } - event._result={ - bool:true, - skill:skill, - character:character + event._result = { + bool: true, + skill: skill, + character: character, }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); - } - var controls=[]; - event.control=ui.create.control(); - event.control.replacex=function(){ - var args=Array.from(arguments)[0]; - if(args.includes('cancel2')&&forced){ - args.remove('cancel2'); - this.style.opacity=''; + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); + }; + var controls = []; + event.control = ui.create.control(); + event.control.replacex = function () { + var args = Array.from(arguments)[0]; + if (args.includes("cancel2") && forced) { + args.remove("cancel2"); + this.style.opacity = ""; } - args.push(function(link){ - var result=event._result; - if(link=='cancel2') result.bool=false; - else{ - if(!event.button) return; - result.bool=true; - result.skill=link; - result.character=event.button.link; + args.push(function (link) { + var result = event._result; + if (link == "cancel2") result.bool = false; + else { + if (!event.button) return; + result.bool = true; + result.skill = link; + result.character = event.button.link; } event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - return this.replace.apply(this,args); - } - if(!forced){ - controls.push('cancel2'); - event.control.style.opacity=1; + return this.replace.apply(this, args); + }; + if (!forced) { + controls.push("cancel2"); + event.control.style.opacity = 1; } event.control.replacex(controls); game.pause(); game.countChoose(); }; - if(event.isMine()){ - chooseButton(player,cards,event.logged); - } - else if(event.isOnline()){ - event.player.send(chooseButton,event.player,cards,event.logged); + if (event.isMine()) { + chooseButton(player, cards, event.logged); + } else if (event.isOnline()) { + event.player.send(chooseButton, event.player, cards, event.logged); event.player.wait(); game.pause(); - } - else{ + } else { switchToAuto(); } - 'step 1' - var map=event.result||result; - if(map.bool){ - if(!event.logged) player.logSkill('huashen'); - var skill=map.skill,character=map.character; - if(character!=player.storage.huashen.current){ - const old=player.storage.huashen.current; - player.storage.huashen.current=character; - player.markSkill('huashen'); - game.broadcastAll(function(player,character,old){ - player.tempname.remove(old); - player.tempname.add(character); - player.sex=lib.character[character][0]; - //player.group=lib.character[character][1]; - //player.node.name.dataset.nature=get.groupnature(player.group); - var mark=player.marks.huashen; - if(mark){ - mark.style.transition='all 0.3s'; - setTimeout(function(){ - mark.style.transition='all 0s'; - ui.refresh(mark); - mark.setBackground(character,'character'); - if(mark.firstChild){ - mark.firstChild.remove(); - } - setTimeout(function(){ - mark.style.transition=''; - mark.show(); - },50); - },200); - } - },player,character,old); - game.log(player,'将性别变为了','#y'+get.translation(lib.character[character][0])+'性'); + "step 1"; + var map = event.result || result; + if (map.bool) { + if (!event.logged) player.logSkill("huashen"); + var skill = map.skill, + character = map.character; + if (character != player.storage.huashen.current) { + const old = player.storage.huashen.current; + player.storage.huashen.current = character; + player.markSkill("huashen"); + game.broadcastAll( + function (player, character, old) { + player.tempname.remove(old); + player.tempname.add(character); + player.sex = lib.character[character][0]; + //player.group=lib.character[character][1]; + //player.node.name.dataset.nature=get.groupnature(player.group); + var mark = player.marks.huashen; + if (mark) { + mark.style.transition = "all 0.3s"; + setTimeout(function () { + mark.style.transition = "all 0s"; + ui.refresh(mark); + mark.setBackground(character, "character"); + if (mark.firstChild) { + mark.firstChild.remove(); + } + setTimeout(function () { + mark.style.transition = ""; + mark.show(); + }, 50); + }, 200); + } + }, + player, + character, + old + ); + game.log( + player, + "将性别变为了", + "#y" + get.translation(lib.character[character][0]) + "性" + ); player.changeGroup(lib.character[character][1]); } - player.storage.huashen.current2=skill; - if(!player.additionalSkills.huashen||!player.additionalSkills.huashen.includes(skill)){ - player.addAdditionalSkills('huashen',skill); - player.flashAvatar('huashen',character); - player.syncStorage('huashen'); - player.updateMarks('huashen'); + player.storage.huashen.current2 = skill; + if ( + !player.additionalSkills.huashen || + !player.additionalSkills.huashen.includes(skill) + ) { + player.addAdditionalSkills("huashen", skill); + player.flashAvatar("huashen", character); + player.syncStorage("huashen"); + player.updateMarks("huashen"); // lib.skill.rehuashen.createAudio(character,skill,'zuoci'); } } - } + }, }, - huashen2:{audio:2}, - xinsheng:{ - audio:2, - unique:true, - trigger:{player:'damageEnd'}, - frequent:true, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - lib.skill.huashen.addHuashens(player,1); - 'step 2' - if(--event.num>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('xinsheng')).set('frequentSkill',event.name); - } - else event.finish(); - 'step 3' - if(result.bool&&player.hasSkill('xinsheng')){ - player.logSkill('xinsheng'); + huashen2: { audio: 2 }, + xinsheng: { + audio: 2, + unique: true, + trigger: { player: "damageEnd" }, + frequent: true, + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + lib.skill.huashen.addHuashens(player, 1); + "step 2"; + if ( + --event.num > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("xinsheng")).set("frequentSkill", event.name); + } else event.finish(); + "step 3"; + if (result.bool && player.hasSkill("xinsheng")) { + player.logSkill("xinsheng"); event.goto(1); } }, }, - huoshou:{ - audio:"huoshou1", - audioname:['re_menghuo'], - locked:true, - group:['huoshou1','huoshou2'], - preHidden:['huoshou1','huoshou2'], - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='nanman') return 0; - } - } - } - }, - huoshou1:{ - audio:2, - audioname:['re_menghuo'], - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - filter:function(event,player){ - return (event.card.name=='nanman'); + huoshou: { + audio: "huoshou1", + audioname: ["re_menghuo"], + locked: true, + group: ["huoshou1", "huoshou2"], + preHidden: ["huoshou1", "huoshou2"], + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "nanman") return 0; + }, + }, }, - content:function(){ + }, + huoshou1: { + audio: 2, + audioname: ["re_menghuo"], + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + filter: function (event, player) { + return event.card.name == "nanman"; + }, + content: function () { trigger.cancel(); }, }, - huoshou2:{ - audio:"huoshou1", - audioname:['re_menghuo'], - trigger:{global:'useCard'}, - forced:true, - filter:function(event,player){ - return (event.card&&event.card.name=='nanman'&&event.player!=player); + huoshou2: { + audio: "huoshou1", + audioname: ["re_menghuo"], + trigger: { global: "useCard" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "nanman" && event.player != player; }, - content:function(){ - trigger.customArgs.default.customSource=player; - } - }, - zaiqixx:{ - audio:'zaiqi', - inherit:'zaiqi', - }, - zaiqi:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ - return !event.numFixed&&player.hp=2; + } else if (player.getDamagedHp() == 2) { + return player.countCards("h") >= 2; } return true; }, - content:function(){ - "step 0" + content: function () { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(player.getDamagedHp()+(event.name=='zaiqi'?0:1)); + event.cards = get.cards(player.getDamagedHp() + (event.name == "zaiqi" ? 0 : 1)); game.cardsGotoOrdering(event.cards); player.showCards(event.cards); - "step 1" - var num=0; - for(var i=0;i1; + content: function () { + player.gain(trigger.cards.filterInD(), "gain2"); + }, + }, + lieren: { + shaRelated: true, + audio: 2, + audioname: ["boss_lvbu3", "ol_zhurong"], + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return ( + event.card && + event.card.name == "sha" && + event.getParent().name == "sha" && + event.player.isIn() && + player.canCompare(event.player) + ); + }, + check: function (event, player) { + return get.attitude(player, event.player) < 0 && player.countCards("h") > 1; }, //priority:5, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(trigger.player); - "step 1" - if(result.bool&&trigger.player.countGainableCards(player,'he')){ - player.gainPlayerCard(trigger.player,true,'he'); + "step 1"; + if (result.bool && trigger.player.countGainableCards(player, "he")) { + player.gainPlayerCard(trigger.player, true, "he"); } - } - }, - xingshang:{ - audio:2, - trigger:{global:'die'}, - preHidden:true, - filter:function(event){ - return event.player.countCards('he')>0; - }, - content:function(){ - "step 0" - event.togain=trigger.player.getCards('he'); - player.gain(event.togain,trigger.player,'giveAuto','bySelf'); }, }, - fangzhu:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - preHidden:true, - content:function(){ - "step 0" - var draw=player.getDamagedHp(); - player.chooseTarget(get.prompt('fangzhu'),'令一名其他角色翻面'+(draw>0?'并摸'+get.cnNumber(draw)+'张牌':''),function(card,player,target){ - return player!=target - }).setHiddenSkill('fangzhu').set('ai',target=>{ - if(target.hasSkillTag('noturn')) return 0; - var player=_status.event.player; - var current=_status.currentPhase; - var dis=current?get.distance(current,target,'absolute'):1; - var draw=player.getDamagedHp(); - var att=get.attitude(player,target); - if(att==0) return target.hasJudge('lebu')?Math.random()/3:Math.sqrt(get.threaten(target))/5+Math.random()/2; - if(att>0){ - if(target.isTurnedOver()) return att+draw; - if(draw<4) return -1; - if(current&&target.getSeatNum()>current.getSeatNum()) return att+draw/3; - return 10*Math.sqrt(Math.max(0.01,get.threaten(target)))/(3.5-draw)+dis/(2*game.countPlayer()); - } - else{ - if(target.isTurnedOver()) return att-draw; - if(draw>=5) return -1; - if(current&&target.getSeatNum()<=current.getSeatNum()) return -att+draw/3; - return (4.25-draw)*10*Math.sqrt(Math.max(0.01,get.threaten(target)))+2*game.countPlayer()/dis; - } - }); - "step 1" - if(result.bool){ - player.logSkill('fangzhu',result.targets); - var draw=player.getDamagedHp(); - if(draw>0) result.targets[0].draw(draw); + xingshang: { + audio: 2, + trigger: { global: "die" }, + preHidden: true, + filter: function (event) { + return event.player.countCards("he") > 0; + }, + content: function () { + "step 0"; + event.togain = trigger.player.getCards("he"); + player.gain(event.togain, trigger.player, "giveAuto", "bySelf"); + }, + }, + fangzhu: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + var draw = player.getDamagedHp(); + player + .chooseTarget( + get.prompt("fangzhu"), + "令一名其他角色翻面" + (draw > 0 ? "并摸" + get.cnNumber(draw) + "张牌" : ""), + function (card, player, target) { + return player != target; + } + ) + .setHiddenSkill("fangzhu") + .set("ai", (target) => { + if (target.hasSkillTag("noturn")) return 0; + var player = _status.event.player; + var current = _status.currentPhase; + var dis = current ? get.distance(current, target, "absolute") : 1; + var draw = player.getDamagedHp(); + var att = get.attitude(player, target); + if (att == 0) + return target.hasJudge("lebu") + ? Math.random() / 3 + : Math.sqrt(get.threaten(target)) / 5 + Math.random() / 2; + if (att > 0) { + if (target.isTurnedOver()) return att + draw; + if (draw < 4) return -1; + if (current && target.getSeatNum() > current.getSeatNum()) + return att + draw / 3; + return ( + (10 * Math.sqrt(Math.max(0.01, get.threaten(target)))) / (3.5 - draw) + + dis / (2 * game.countPlayer()) + ); + } else { + if (target.isTurnedOver()) return att - draw; + if (draw >= 5) return -1; + if (current && target.getSeatNum() <= current.getSeatNum()) + return -att + draw / 3; + return ( + (4.25 - draw) * 10 * Math.sqrt(Math.max(0.01, get.threaten(target))) + + (2 * game.countPlayer()) / dis + ); + } + }); + "step 1"; + if (result.bool) { + player.logSkill("fangzhu", result.targets); + var draw = player.getDamagedHp(); + if (draw > 0) result.targets[0].draw(draw); result.targets[0].turnOver(); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp<=1) return; - if(!target.hasFriend()) return; - var hastarget=false; - var turnfriend=false; - var players=game.filterPlayer(); - for(var i=0;i0&&players[i].isTurnedOver()){ - hastarget=true; - turnfriend=true; + if (get.attitude(target, players[i]) > 0 && players[i].isTurnedOver()) { + hastarget = true; + turnfriend = true; } } - if(get.attitude(player,target)>0&&!hastarget) return; - if(turnfriend||target.hp==target.maxHp) return [0.5,1]; - if(target.hp>1) return [1,0.5]; + if (get.attitude(player, target) > 0 && !hastarget) return; + if (turnfriend || target.hp == target.maxHp) return [0.5, 1]; + if (target.hp > 1) return [1, 0.5]; } - } - } - } - }, - songwei:{ - unique:true, - group:'songwei2', - audioname:['re_caopi'], - audio:"songwei2", - zhuSkill:true, - }, - songwei2:{ - audio:2, - audioname:['re_caopi'], - forceaudio:true, - trigger:{global:'judgeEnd'}, - filter:function(event,player){ - if(event.player==player||event.player.group!='wei') return false; - if(event.result.color!='black') return false; - return player.hasZhuSkill('songwei',event.player); + }, + }, }, - direct:true, - content:function(){ - 'step 0' - trigger.player.chooseBool('是否发动【颂威】,令'+get.translation(player)+'摸一张牌?').set('choice',get.attitude(trigger.player,player)>0); - 'step 1' - if(result.bool){ - player.logSkill('songwei2'); - trigger.player.line(player,'green'); + }, + songwei: { + unique: true, + group: "songwei2", + audioname: ["re_caopi"], + audio: "songwei2", + zhuSkill: true, + }, + songwei2: { + audio: 2, + audioname: ["re_caopi"], + forceaudio: true, + trigger: { global: "judgeEnd" }, + filter: function (event, player) { + if (event.player == player || event.player.group != "wei") return false; + if (event.result.color != "black") return false; + return player.hasZhuSkill("songwei", event.player); + }, + direct: true, + content: function () { + "step 0"; + trigger.player + .chooseBool("是否发动【颂威】,令" + get.translation(player) + "摸一张牌?") + .set("choice", get.attitude(trigger.player, player) > 0); + "step 1"; + if (result.bool) { + player.logSkill("songwei2"); + trigger.player.line(player, "green"); player.draw(); } - } - }, - jiezi:{ - trigger:{global:['phaseDrawSkipped','phaseDrawCancelled']}, - audio:2, - forced:true, - filter:function(event,player){ - return event.player!=player; }, - content:function(){ + }, + jiezi: { + trigger: { global: ["phaseDrawSkipped", "phaseDrawCancelled"] }, + audio: 2, + forced: true, + filter: function (event, player) { + return event.player != player; + }, + content: function () { player.draw(); - } - }, - gzduanliang:{ - audio:'duanliang1', - audioname:['re_xuhuang'], - group:['duanliang1','duanliang2'], - ai:{ - threaten:1.2 - } - }, - duanliang:{ - audio:'duanliang1', - audioname:['re_xuhuang'], - group:['duanliang1','duanliang3'], - ai:{ - threaten:1.2 - } - }, - duanliang1:{ - audio:2, - audioname:['re_xuhuang'], - enable:'chooseToUse', - filterCard:function(card){ - if(get.type(card)!='basic'&&get.type(card)!='equip') return false; - return get.color(card)=='black'; }, - filter:function(event,player){ - return player.countCards('hes',{type:['basic','equip'],color:'black'}) + }, + gzduanliang: { + audio: "duanliang1", + audioname: ["re_xuhuang"], + group: ["duanliang1", "duanliang2"], + ai: { + threaten: 1.2, }, - position:'hes', - viewAs:{name:'bingliang'}, - prompt:'将一黑色的基本牌或装备牌当兵粮寸断使用', - check:function(card){return 6-get.value(card)}, - ai:{ - order:9 - } }, - duanliang2:{ - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='bingliang'){ - if(get.distance(player,target)<=2) return true; + duanliang: { + audio: "duanliang1", + audioname: ["re_xuhuang"], + group: ["duanliang1", "duanliang3"], + ai: { + threaten: 1.2, + }, + }, + duanliang1: { + audio: 2, + audioname: ["re_xuhuang"], + enable: "chooseToUse", + filterCard: function (card) { + if (get.type(card) != "basic" && get.type(card) != "equip") return false; + return get.color(card) == "black"; + }, + filter: function (event, player) { + return player.countCards("hes", { type: ["basic", "equip"], color: "black" }); + }, + position: "hes", + viewAs: { name: "bingliang" }, + prompt: "将一黑色的基本牌或装备牌当兵粮寸断使用", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + order: 9, + }, + }, + duanliang2: { + mod: { + targetInRange: function (card, player, target) { + if (card.name == "bingliang") { + if (get.distance(player, target) <= 2) return true; } - } - } + }, + }, }, - duanliang3:{ - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='bingliang'){ - if(target.countCards('h')>=player.countCards('h')) return true; + duanliang3: { + mod: { + targetInRange: function (card, player, target) { + if (card.name == "bingliang") { + if (target.countCards("h") >= player.countCards("h")) return true; } - } - } + }, + }, }, - haoshi:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ + haoshi: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { return !event.numFixed; }, - preHidden:true, - check:function(event,player){ - 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; - }); + preHidden: true, + check: function (event, player) { + return ( + player.countCards("h") + 2 + event.num <= 5 || + game.hasPlayer(function (target) { + return ( + player !== target && + !game.hasPlayer(function (current) { + return ( + current !== player && + current !== target && + current.countCards("h") < target.countCards("h") + ); + }) && + get.attitude(player, target) > 0 + ); + }) + ); }, - content:function(){ - trigger.num+=2; - player.addSkill('haoshi2'); + content: function () { + trigger.num += 2; + player.addSkill("haoshi2"); }, - ai:{ - threaten:2, - noh:true, - skillTagFilter:function(player,tag){ - if(tag=='noh'){ - if(player.countCards('h')!=2) return false; + ai: { + threaten: 2, + noh: true, + skillTagFilter: function (player, tag) { + if (tag == "noh") { + if (player.countCards("h") != 2) return false; } - } - } + }, + }, }, - haoshi2:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - popup:false, - audio:false, - content:function(){ - "step 0" - player.removeSkill('haoshi2'); - if(player.countCards('h')<=5){ + haoshi2: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + popup: false, + audio: false, + content: function () { + "step 0"; + player.removeSkill("haoshi2"); + if (player.countCards("h") <= 5) { event.finish(); return; } player.chooseCardTarget({ - selectCard:Math.floor(player.countCards('h')/2), - filterTarget:function(card,player,target){ + selectCard: Math.floor(player.countCards("h") / 2), + filterTarget: function (card, player, target) { return target.isMinHandcard(); }, - prompt:'将一半的手牌交给场上手牌数最少的一名角色', - forced:true, - ai2:function(target){ - return get.attitude(_status.event.player,target); - } + prompt: "将一半的手牌交给场上手牌数最少的一名角色", + forced: true, + ai2: function (target) { + return get.attitude(_status.event.player, target); + }, }); - "step 1" - if(result.targets&&result.targets[0]){ - player.give(result.cards,result.targets[0]); + "step 1"; + if (result.targets && result.targets[0]) { + player.give(result.cards, result.targets[0]); } - } + }, }, - dimeng:{ - audio:2, - enable:'phaseUse', - usable:1, - position:'he', - filterCard:function(){ - var targets=ui.selected.targets; - if(targets.length==2){ - if(Math.abs(targets[0].countCards('h')-targets[1].countCards('h'))<=ui.selected.cards.length) return false; + dimeng: { + audio: 2, + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: function () { + var targets = ui.selected.targets; + if (targets.length == 2) { + if ( + Math.abs(targets[0].countCards("h") - targets[1].countCards("h")) <= + ui.selected.cards.length + ) + return false; } return true; }, - selectCard:[0,Infinity], - selectTarget:2, - complexCard:true, - filterTarget:function(card,player,target){ - if(player==target) return false; + selectCard: [0, Infinity], + selectTarget: 2, + complexCard: true, + filterTarget: function (card, player, target) { + if (player == target) return false; return true; }, - filterOk:function(){ - var targets=ui.selected.targets; - if(targets.length!=2) return false; - return (Math.abs(targets[0].countCards('h')-targets[1].countCards('h'))==ui.selected.cards.length); + filterOk: function () { + var targets = ui.selected.targets; + if (targets.length != 2) return false; + return ( + Math.abs(targets[0].countCards("h") - targets[1].countCards("h")) == + ui.selected.cards.length + ); }, - multitarget:true, - multiline:true, - content:function(){ + multitarget: true, + multiline: true, + content: function () { targets[0].swapHandcards(targets[1]); }, - check:function(card){ - var list=[],player=_status.event.player; - var num=player.countCards('he'); + check: function (card) { + var list = [], + player = _status.event.player; + var num = player.countCards("he"); var count; - var players=game.filterPlayer(); - for(var i=0;i3) list.push(players[i]); + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && get.attitude(player, players[i]) > 3) + list.push(players[i]); } - list.sort(function(a,b){ - return a.countCards('h')-b.countCards('h'); + list.sort(function (a, b) { + return a.countCards("h") - b.countCards("h"); }); - if(list.length==0) return -1; - var from=list[0]; - list.length=0; + if (list.length == 0) return -1; + var from = list[0]; + list.length = 0; - for(var i=0;i=list[0].countCards('h')) return -1; - for(var i=0;i= list[0].countCards("h")) return -1; + for (var i = 0; i < list.length && from.countCards("h") < list[i].countCards("h"); i++) { + if (list[i].countCards("h") - from.countCards("h") <= num) { + count = list[i].countCards("h") - from.countCards("h"); + break; } } - if(count<2&&from.countCards('h')>=2) return -1; - if(ui.selected.cards.length= 2) return -1; + if (ui.selected.cards.length < count) return 11 - get.value(card); return -1; }, - ai:{ - order:6, - threaten:3, - expose:0.9, - result:{ - target:function(player,target){ - var list=[]; - var num=player.countCards('he'); - var players=game.filterPlayer(); - if(ui.selected.targets.length==0){ - for(var i=0;i3) list.push(players[i]); + ai: { + order: 6, + threaten: 3, + expose: 0.9, + result: { + target: function (player, target) { + var list = []; + var num = player.countCards("he"); + var players = game.filterPlayer(); + if (ui.selected.targets.length == 0) { + for (var i = 0; i < players.length; i++) { + if (players[i] != player && get.attitude(player, players[i]) > 3) + list.push(players[i]); } - list.sort(function(a,b){ - return a.countCards('h')-b.countCards('h'); + list.sort(function (a, b) { + return a.countCards("h") - b.countCards("h"); }); - if(target==list[0]) return get.attitude(player,target); - return -get.attitude(player,target); - } - else{ - var from=ui.selected.targets[0]; - for(var i=0;i=list[0].countCards('h')) return -get.attitude(player,target); - for(var i=0;i=2) return -get.attitude(player,target); - if(target==list[i]) return get.attitude(player,target); - return -get.attitude(player,target); + if (from.countCards("h") >= list[0].countCards("h")) + return -get.attitude(player, target); + for ( + var i = 0; + i < list.length && from.countCards("h") < list[i].countCards("h"); + i++ + ) { + if (list[i].countCards("h") - from.countCards("h") <= num) { + var count = list[i].countCards("h") - from.countCards("h"); + if (count < 2 && from.countCards("h") >= 2) + return -get.attitude(player, target); + if (target == list[i]) return get.attitude(player, target); + return -get.attitude(player, target); } } } - } - } - } + }, + }, + }, }, - yinghun:{ - audio:2, - audioname:['re_sunjian','sunce','re_sunben','re_sunce','ol_sunjian'], - audioname2:{ - re_sunyi:'gzyinghun_re_sunyi', - tw_ol_sunjian:'yinghun_ol_sunjian', + yinghun: { + audio: 2, + audioname: ["re_sunjian", "sunce", "re_sunben", "re_sunce", "ol_sunjian"], + audioname2: { + 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; + 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, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('yinghun'),function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - var player=_status.event.player; - if(player.getDamagedHp()==1&&target.countCards('he')==0){ - return 0; + locked: false, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("yinghun"), function (card, player, target) { + return player != target; + }) + .set("ai", function (target) { + var player = _status.event.player; + if (player.getDamagedHp() == 1 && target.countCards("he") == 0) { + return 0; + } + if (get.attitude(_status.event.player, target) > 0) { + return 10 + get.attitude(_status.event.player, target); + } + if (player.getDamagedHp() == 1) { + return -1; + } + return 1; + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + event.num = player.getDamagedHp(); + player.logSkill(event.name, result.targets); + event.target = result.targets[0]; + if (event.num == 1) { + event.directcontrol = true; + } else { + var str1 = "摸" + get.cnNumber(event.num, true) + "弃一"; + var str2 = "摸一弃" + get.cnNumber(event.num, true); + player + .chooseControl(str1, str2, function (event, player) { + if (player.isHealthy()) return 1 - _status.event.choice; + return _status.event.choice; + }) + .set("choice", get.attitude(player, event.target) > 0 ? 0 : 1); + event.str = str1; } - if(get.attitude(_status.event.player,target)>0){ - return 10+get.attitude(_status.event.player,target); - } - if(player.getDamagedHp()==1){ - return -1; - } - return 1; - }).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - event.num=player.getDamagedHp(); - player.logSkill(event.name,result.targets); - event.target=result.targets[0]; - if(event.num==1){ - event.directcontrol=true; - } - else{ - var str1='摸'+get.cnNumber(event.num,true)+'弃一'; - var str2='摸一弃'+get.cnNumber(event.num,true); - player.chooseControl(str1,str2,function(event,player){ - if(player.isHealthy()) return 1-_status.event.choice; - return _status.event.choice; - }).set('choice',(get.attitude(player,event.target)>0)?0:1); - event.str=str1; - } - } - else{ + } else { event.finish(); } - "step 2" - if(event.directcontrol||result.control==event.str){ - if(event.num>0) event.target.draw(event.num); - event.target.chooseToDiscard(true,'he'); - } - else{ + "step 2"; + if (event.directcontrol || result.control == event.str) { + if (event.num > 0) event.target.draw(event.num); + event.target.chooseToDiscard(true, "he"); + } else { event.target.draw(); - if(event.num>0) event.target.chooseToDiscard(event.num,true,'he'); + 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]; - } + 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); + threaten: function (player, target) { + return Math.max(0.5, target.getDamagedHp() / 2); }, - maixie:true - } + maixie: true, + }, }, - gzyinghun:{ - audio:'yinghun', - audioname:['re_sunjian','sunce','re_sunben','re_sunce','ol_sunjian','sb_sunce'], - audioname2:{ - re_sunyi:'gzyinghun_re_sunyi', - tw_ol_sunjian:'yinghun_ol_sunjian', + gzyinghun: { + audio: "yinghun", + audioname: ["re_sunjian", "sunce", "re_sunben", "re_sunce", "ol_sunjian", "sb_sunce"], + audioname2: { + 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; + 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; + locked: false, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getDamagedHp() > 0; }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('gzyinghun'),function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - var player=_status.event.player; - if(player.getDamagedHp()==1&&target.countCards('he')==0){ - return 0; + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gzyinghun"), function (card, player, target) { + return player != target; + }) + .set("ai", function (target) { + var player = _status.event.player; + if (player.getDamagedHp() == 1 && target.countCards("he") == 0) { + return 0; + } + if (get.attitude(_status.event.player, target) > 0) { + return 10 + get.attitude(_status.event.player, target); + } + if (player.getDamagedHp() == 1) { + return -1; + } + return 1; + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + event.num = player.getDamagedHp(); + player.logSkill(event.name, result.targets); + event.target = result.targets[0]; + if (event.num == 1) { + event.directcontrol = true; + } else { + var str1 = "摸" + get.cnNumber(event.num, true) + "弃一"; + var str2 = "摸一弃" + get.cnNumber(event.num, true); + player + .chooseControl(str1, str2, function (event, player) { + return _status.event.choice; + }) + .set("choice", get.attitude(player, event.target) > 0 ? str1 : str2); + event.str = str1; } - if(get.attitude(_status.event.player,target)>0){ - return 10+get.attitude(_status.event.player,target); - } - if(player.getDamagedHp()==1){ - return -1; - } - return 1; - }).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - event.num=player.getDamagedHp(); - player.logSkill(event.name,result.targets); - event.target=result.targets[0]; - if(event.num==1){ - event.directcontrol=true; - } - else{ - var str1='摸'+get.cnNumber(event.num,true)+'弃一'; - var str2='摸一弃'+get.cnNumber(event.num,true); - player.chooseControl(str1,str2,function(event,player){ - return _status.event.choice; - }).set('choice',get.attitude(player,event.target)>0?str1:str2); - event.str=str1; - } - } - else{ + } else { event.finish(); } - "step 2" - if(event.directcontrol||result.control==event.str){ + "step 2"; + if (event.directcontrol || result.control == event.str) { event.target.draw(event.num); - event.target.chooseToDiscard(true,'he'); - } - else{ + event.target.chooseToDiscard(true, "he"); + } else { event.target.draw(); - event.target.chooseToDiscard(event.num,true,'he'); + 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]; - } + 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); + threaten: function (player, target) { + return Math.max(0.5, target.getDamagedHp() / 2); }, - maixie:true - } - }, - yinghun_ol_sunjian:{audio:2}, - jiuchi:{ - audio:2, - audioname:['re_dongzhuo'], - enable:'chooseToUse', - filterCard:function(card){ - return get.suit(card)=='spade'; + maixie: true, }, - viewAs:{name:'jiu'}, - viewAsFilter:function(player){ - if(!player.countCards('hs',{suit:'spade'})) return false; + }, + yinghun_ol_sunjian: { audio: 2 }, + jiuchi: { + audio: 2, + audioname: ["re_dongzhuo"], + enable: "chooseToUse", + filterCard: function (card) { + return get.suit(card) == "spade"; + }, + viewAs: { name: "jiu" }, + viewAsFilter: function (player) { + if (!player.countCards("hs", { suit: "spade" })) return false; return true; }, - prompt:'将一张黑桃手牌当酒使用', - check:function(card){ - if(_status.event.type=='dying') return 1/Math.max(0.1,get.value(card)); - return 4-get.value(card); + prompt: "将一张黑桃手牌当酒使用", + check: function (card) { + if (_status.event.type == "dying") return 1 / Math.max(0.1, get.value(card)); + return 4 - get.value(card); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5, - } }, - roulin:{ - audio:2, - audioname:['re_dongzhuo','ol_dongzhuo'], - trigger:{player:'useCardToPlayered',target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(player==event.player){ - return event.target.hasSex('female'); + roulin: { + audio: 2, + audioname: ["re_dongzhuo", "ol_dongzhuo"], + trigger: { player: "useCardToPlayered", target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (player == event.player) { + return event.target.hasSex("female"); } - return event.player.hasSex('female'); + return event.player.hasSex("female"); }, - check:function(event,player){ - return player==event.player; + check: function (event, player) { + return player == event.player; }, - content:function(){ - var id=(player==trigger.player?trigger.target:player).playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + content: function () { + var id = (player == trigger.player ? trigger.target : player).playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; - } - else{ - map[id].shanRequired=2; + } else { + map[id].shanRequired = 2; } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg.card.name!='sha'||!arg.target.hasSex('female')||arg.target.countCards('h','shan')>1) return false; + ai: { + halfneg: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag === "directHit_ai") return; + if ( + arg.card.name != "sha" || + !arg.target.hasSex("female") || + arg.target.countCards("h", "shan") > 1 + ) + return false; }, }, }, - benghuai:{ - audio:2, - audioname:['zhugedan','re_dongzhuo','ol_dongzhuo','re_zhugedan'], - trigger:{player:'phaseJieshuBegin'}, - forced:true, - check:function(){ + benghuai: { + audio: 2, + audioname: ["zhugedan", "re_dongzhuo", "ol_dongzhuo", "re_zhugedan"], + trigger: { player: "phaseJieshuBegin" }, + forced: true, + check: function () { return false; }, - filter:function(event,player){ - return !player.isMinHp()&&!player.hasSkill('rejiuchi_air')&&!player.hasSkill('oljiuchi_air'); + filter: function (event, player) { + return ( + !player.isMinHp() && + !player.hasSkill("rejiuchi_air") && + !player.hasSkill("oljiuchi_air") + ); }, - content:function(){ - "step 0" - player.chooseControl('baonue_hp','baonue_maxHp',function(event,player){ - if(player.hp==player.maxHp) return 'baonue_hp'; - if(player.hp0); - 'step 1' - if(result.bool){ - player.logSkill('baonue'); - trigger.source.line(player,'green') - trigger.source.judge(function(card){ - if(get.suit(card)=='spade') return 4; + }, + baonue: { + unique: true, + group: "baonue2", + audioname: ["re_dongzhuo"], + audio: "baonue2", + zhuSkill: true, + }, + baonue2: { + audio: 2, + audioname: ["re_dongzhuo"], + //forceaudio:true, + trigger: { global: "damageSource" }, + filter: function (event, player) { + if (player == event.source || !event.source || event.source.group != "qun") return false; + return player.hasZhuSkill("baonue", event.source); + }, + direct: true, + content: function () { + "step 0"; + trigger.source + .chooseBool("是否对" + get.translation(player) + "发动【暴虐】?") + .set("choice", get.attitude(trigger.source, player) > 0); + "step 1"; + if (result.bool) { + player.logSkill("baonue"); + trigger.source.line(player, "green"); + trigger.source.judge(function (card) { + if (get.suit(card) == "spade") return 4; return 0; - }).judge2=function(result){ - return result.bool?true:false; + }).judge2 = function (result) { + return result.bool ? true : false; }; - } - else{ + } else { event.finish(); } - 'step 2' - if(result.suit=='spade'){ + "step 2"; + if (result.suit == "spade") { player.recover(); } - } - }, - luanwu:{ - audio:2, - audioname:['re_jiaxu'], - unique:true, - enable:'phaseUse', - limited:true, - skillAnimation:'epic', - animationColor:'thunder', - filterTarget:function(card,player,target){ - return target!=player; }, - selectTarget:-1, - multitarget:true, - multiline:true, - content:function(){ - "step 0" - player.awakenSkill('luanwu'); - event.current=player.next; - event.currented=[]; - "step 1" + }, + luanwu: { + audio: 2, + audioname: ["re_jiaxu"], + unique: true, + enable: "phaseUse", + limited: true, + skillAnimation: "epic", + animationColor: "thunder", + filterTarget: function (card, player, target) { + return target != player; + }, + selectTarget: -1, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + player.awakenSkill("luanwu"); + event.current = player.next; + event.currented = []; + "step 1"; event.currented.push(event.current); - event.current.addTempClass('target'); - event.current.chooseToUse('乱武:使用一张杀或失去1点体力',function(card){ - if(get.name(card)!='sha') return false; - return lib.filter.cardEnabled.apply(this,arguments) - },function(card,player,target){ - if(player==target) return false; - var dist=get.distance(player,target); - if(dist>1){ - if(game.hasPlayer(function(current){ - return current!=player&&get.distance(player,current) 1) { + if ( + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) < dist; + }) + ) { + return false; + } + } + return lib.filter.filterTarget.apply(this, arguments); } - } - return lib.filter.filterTarget.apply(this,arguments); - }).set('ai2',function(){ - return get.effect_use.apply(this,arguments)+0.01; - }).set('addCount',false); - "step 2" - if(result.bool==false) event.current.loseHp(); - event.current=event.current.next; - if(event.current!=player&&!event.currented.includes(event.current)){ + ) + .set("ai2", function () { + return get.effect_use.apply(this, arguments) + 0.01; + }) + .set("addCount", false); + "step 2"; + if (result.bool == false) event.current.loseHp(); + event.current = event.current.next; + if (event.current != player && !event.currented.includes(event.current)) { game.delay(0.5); event.goto(1); } }, - ai:{ - order:1, - result:{ - player:function(player){ - if(lib.config.mode=='identity'&&game.zhu.isZhu&&player.identity=='fan'){ - if(game.zhu.hp==1&&game.zhu.countCards('h')<=2) return 1; + ai: { + order: 1, + result: { + player: function (player) { + if (lib.config.mode == "identity" && game.zhu.isZhu && player.identity == "fan") { + if (game.zhu.hp == 1 && game.zhu.countCards("h") <= 2) return 1; } - var num=0; - var players=game.filterPlayer(); - for(var i=0;i0) att=1; - if(att<0) att=-1; - if(players[i]!=player&&players[i].hp<=3){ - if(players[i].countCards('h')==0) num+=att/players[i].hp; - else if(players[i].countCards('h')==1) num+=att/2/players[i].hp; - else if(players[i].countCards('h')==2) num+=att/4/players[i].hp; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var att = get.attitude(player, players[i]); + if (att > 0) att = 1; + if (att < 0) att = -1; + if (players[i] != player && players[i].hp <= 3) { + if (players[i].countCards("h") == 0) num += att / players[i].hp; + else if (players[i].countCards("h") == 1) num += att / 2 / players[i].hp; + else if (players[i].countCards("h") == 2) num += att / 4 / players[i].hp; } - if(players[i].hp==1) num+=att*1.5; + if (players[i].hp == 1) num += att * 1.5; } - if(player.hp==1){ + if (player.hp == 1) { return -num; } - if(player.hp==2){ - return -game.players.length/4-num; + if (player.hp == 2) { + return -game.players.length / 4 - num; } - return -game.players.length/3-num; - } - } - } - }, - wansha:{ - locked:true, - audio:2, - audioname:['boss_lvbu3','shen_simayi'], - global:'wansha2', - trigger:{global:'dying'}, - priority:15, - forced:true, - preHidden:true, - filter:function(event,player,name){ - return _status.currentPhase==player&&event.player!=player; + return -game.players.length / 3 - num; + }, + }, }, - content:function(){} }, - wansha2:{ - mod:{ - cardSavable:function(card,player){ - if(card.name=='tao'&&_status.currentPhase&&_status.currentPhase.isIn()&&_status.currentPhase.hasSkill('wansha')&&_status.currentPhase!=player){ - if(!player.isDying()) return false; + wansha: { + locked: true, + audio: 2, + audioname: ["boss_lvbu3", "shen_simayi"], + global: "wansha2", + trigger: { global: "dying" }, + priority: 15, + forced: true, + preHidden: true, + filter: function (event, player, name) { + return _status.currentPhase == player && event.player != player; + }, + content: function () {}, + }, + wansha2: { + mod: { + cardSavable: function (card, player) { + if ( + card.name == "tao" && + _status.currentPhase && + _status.currentPhase.isIn() && + _status.currentPhase.hasSkill("wansha") && + _status.currentPhase != player + ) { + if (!player.isDying()) return false; } }, - cardEnabled:function(card,player){ - if(card.name=='tao'&&_status.currentPhase&&_status.currentPhase.isIn()&&_status.currentPhase.hasSkill('wansha')&&_status.currentPhase!=player){ - if(!player.isDying()) return false; + cardEnabled: function (card, player) { + if ( + card.name == "tao" && + _status.currentPhase && + _status.currentPhase.isIn() && + _status.currentPhase.hasSkill("wansha") && + _status.currentPhase != player + ) { + if (!player.isDying()) return false; } + }, + }, + }, + weimu: { + trigger: { global: "useCard1" }, + audio: 2, + forced: true, + firstDo: true, + filter: function (event, player, card) { + if (get.color(event.card) != "black") return false; + return ( + (event.card.name == "nanman" && player != event.player) || + (event.card.name == "wanjian" && player != event.player) || + (event.card.name == "taoyuan" && player.hp < player.maxHp) || + event.card.name == "wugu" + ); + }, + content: function () {}, + mod: { + targetEnabled: function (card) { + if ( + (get.type(card) == "trick" || get.type(card) == "delay") && + get.color(card) == "black" + ) + return false; + }, + }, + }, + huoji: { + audio: 2, + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "red"; + }, + viewAs: { name: "huogong" }, + viewAsFilter: function (player) { + if (!player.countCards("hs", { color: "red" })) return false; + }, + position: "hs", + prompt: "将一张红色牌当火攻使用", + check: function (card) { + var player = get.player(); + if (player.countCards("h") > player.hp) { + return 6 - get.value(card); } - } - }, - weimu:{ - trigger:{global:'useCard1'}, - audio:2, - forced:true, - firstDo:true, - filter:function(event,player,card){ - if(get.color(event.card)!='black') return false; - return event.card.name=='nanman'&&player!=event.player||event.card.name=='wanjian'&&player!=event.player||event.card.name=='taoyuan'&&player.hpplayer.hp){ - return 6-get.value(card); - } - return 3-get.value(card) - }, - ai:{ - fireAttack:true, + ai: { + fireAttack: true, }, }, - bazhen:{ - audio:2, - audioname:['re_sp_zhugeliang','ol_sp_zhugeliang','ol_pangtong'], - group:'bazhen_bagua', - locked:true, + bazhen: { + audio: 2, + audioname: ["re_sp_zhugeliang", "ol_sp_zhugeliang", "ol_pangtong"], + group: "bazhen_bagua", + locked: true, }, - bazhen_bagua:{ - audio:'bazhen', - audioname:['re_sp_zhugeliang','ol_sp_zhugeliang','ol_pangtong'], - equipSkill:true, - noHidden:true, - inherit:'bagua_skill', - filter:function(event,player){ - if(!lib.skill.bagua_skill.filter(event,player)) return false; - if(!player.hasEmptySlot(2)) return false; + bazhen_bagua: { + audio: "bazhen", + audioname: ["re_sp_zhugeliang", "ol_sp_zhugeliang", "ol_pangtong"], + equipSkill: true, + noHidden: true, + inherit: "bagua_skill", + filter: function (event, player) { + if (!lib.skill.bagua_skill.filter(event, player)) return false; + if (!player.hasEmptySlot(2)) return false; return true; }, - ai:{ - respondShan:true, - freeShan:true, - skillTagFilter(player,tag,arg){ - if(tag!=='respondShan'&&tag!=='freeShan') return; - if(!player.hasEmptySlot(2)||player.hasSkillTag('unequip2')) return false; - if(!arg||!arg.player) return true; - if(arg.player.hasSkillTag('unequip',false,{ - target:player - })) return false; + ai: { + respondShan: true, + freeShan: true, + skillTagFilter(player, tag, arg) { + if (tag !== "respondShan" && tag !== "freeShan") return; + if (!player.hasEmptySlot(2) || player.hasSkillTag("unequip2")) return false; + if (!arg || !arg.player) return true; + if ( + arg.player.hasSkillTag("unequip", false, { + target: player, + }) + ) + return false; return true; }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.subtype(card)=='equip2'){ - if(get.equipValue(card)<=7.5) return 0; + effect: { + target: function (card, player, target) { + if (player == target && get.subtype(card) == "equip2") { + if (get.equipValue(card) <= 7.5) return 0; } - if(!target.hasEmptySlot(2)) return; - return lib.skill.bagua_skill.ai.effect.target.apply(this,arguments); - } - } - } + if (!target.hasEmptySlot(2)) return; + return lib.skill.bagua_skill.ai.effect.target.apply(this, arguments); + }, + }, + }, }, - kanpo:{ - mod:{ - aiValue:function(player,card,num){ - if(get.name(card)!='wuxie'&&get.color(card)!='black') return; - var cards=player.getCards('hs',function(card){ - return get.name(card)=='wuxie'||get.color(card)=='black'; + kanpo: { + mod: { + aiValue: function (player, card, num) { + if (get.name(card) != "wuxie" && get.color(card) != "black") return; + var cards = player.getCards("hs", function (card) { + return get.name(card) == "wuxie" || get.color(card) == "black"; }); - cards.sort(function(a,b){ - return (get.name(b)=='wuxie'?1:2)-(get.name(a)=='wuxie'?1:2); + cards.sort(function (a, b) { + return (get.name(b) == "wuxie" ? 1 : 2) - (get.name(a) == "wuxie" ? 1 : 2); }); - var geti=function(){ - if(cards.includes(card)){ + var geti = function () { + if (cards.includes(card)) { return cards.indexOf(card); } return cards.length; }; - if(get.name(card)=='wuxie') return Math.min(num,[6,4,3][Math.min(geti(),2)])*0.6; - return Math.max(num,[6,4,3][Math.min(geti(),2)]); + if (get.name(card) == "wuxie") + return Math.min(num, [6, 4, 3][Math.min(geti(), 2)]) * 0.6; + return Math.max(num, [6, 4, 3][Math.min(geti(), 2)]); }, - aiUseful:function(){ - return lib.skill.kanpo.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.kanpo.mod.aiValue.apply(this, arguments); }, }, - locked:false, - audio:2, - enable:'chooseToUse', - filterCard:function(card){ - return get.color(card)=='black'; + locked: false, + audio: 2, + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "black"; }, - viewAsFilter:function(player){ - return player.countCards('hs',{color:'black'})>0; + viewAsFilter: function (player) { + return player.countCards("hs", { color: "black" }) > 0; }, - viewAs:{name:'wuxie'}, - position:'hs', - prompt:'将一张黑色手牌当无懈可击使用', - check:function(card){ - var tri=_status.event.getTrigger(); - if(tri&&tri.card&&tri.card.name=='chiling') return -1; - return 8-get.value(card) + viewAs: { name: "wuxie" }, + position: "hs", + prompt: "将一张黑色手牌当无懈可击使用", + check: function (card) { + var tri = _status.event.getTrigger(); + if (tri && tri.card && tri.card.name == "chiling") return -1; + return 8 - get.value(card); }, - threaten:1.2 + threaten: 1.2, }, - niepan:{ - audio:2, - audioname:['re_pangtong'], - unique:true, - enable:'chooseToUse', - mark:true, - limited:true, - skillAnimation:true, - animationColor:'fire', - init:function(player){ - player.storage.niepan=false; + niepan: { + audio: 2, + audioname: ["re_pangtong"], + unique: true, + enable: "chooseToUse", + mark: true, + limited: true, + skillAnimation: true, + animationColor: "fire", + init: function (player) { + player.storage.niepan = false; }, - filter:function(event,player){ - if(player.storage.niepan) return false; - if(event.type=='dying'){ - if(player!=event.dying) return false; + filter: function (event, player) { + if (player.storage.niepan) return false; + if (event.type == "dying") { + if (player != event.dying) return false; return true; - } - else if(event.parent.name=='phaseUse'){ + } else if (event.parent.name == "phaseUse") { return true; } return false; }, - content:function(){ - 'step 0' - player.awakenSkill('niepan'); - player.storage.niepan=true; - player.discard(player.getCards('hej')); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("niepan"); + player.storage.niepan = true; + player.discard(player.getCards("hej")); + "step 1"; player.link(false); - 'step 2' + "step 2"; player.turnOver(false); - 'step 3' + "step 3"; player.draw(3); - 'step 4' - if(player.hp<3){ - player.recover(3-player.hp); + "step 4"; + if (player.hp < 3) { + player.recover(3 - player.hp); } }, - ai:{ - order:0.5, - skillTagFilter:function(player,tag,target){ - if(player!=target||player.storage.niepan) return false; + ai: { + order: 0.5, + skillTagFilter: function (player, tag, target) { + if (player != target || player.storage.niepan) return false; }, - save:true, - result:{ - player:function(player){ - if(player.hp<=0) return 10; - if(player.hp<=1&&player.countCards('he')<=1) return 10; + save: true, + result: { + player: function (player) { + if (player.hp <= 0) return 10; + if (player.hp <= 1 && player.countCards("he") <= 1) return 10; return 0; - } + }, + }, + threaten: function (player, target) { + if (!target.storage.niepan) return 0.6; }, - threaten:function(player,target){ - if(!target.storage.niepan) return 0.6; - } }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - oldniepan:{ - audio:'niepan', - unique:true, - enable:'chooseToUse', - mark:true, - skillAnimation:true, - limited:true, - animationColor:'orange', - init:function(player){ - player.storage.oldniepan=false; + oldniepan: { + audio: "niepan", + unique: true, + enable: "chooseToUse", + mark: true, + skillAnimation: true, + limited: true, + animationColor: "orange", + init: function (player) { + player.storage.oldniepan = false; }, - filter:function(event,player){ - if(player.storage.oldniepan) return false; - if(event.type=='dying'){ - if(player!=event.dying) return false; + filter: function (event, player) { + if (player.storage.oldniepan) return false; + if (event.type == "dying") { + if (player != event.dying) return false; return true; } return false; }, - content:function(){ - 'step 0' - player.awakenSkill('oldniepan'); - player.storage.oldniepan=true; - player.discard(player.getCards('hej')); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("oldniepan"); + player.storage.oldniepan = true; + player.discard(player.getCards("hej")); + "step 1"; player.link(false); - 'step 2' + "step 2"; player.turnOver(false); - 'step 3' + "step 3"; player.draw(3); - 'step 4' - if(player.hp<3){ - player.recover(3-player.hp); + "step 4"; + if (player.hp < 3) { + player.recover(3 - player.hp); } }, - ai:{ - order:1, - skillTagFilter:function(player,arg,target){ - if(player!=target||player.storage.oldniepan) return false; + ai: { + order: 1, + skillTagFilter: function (player, arg, target) { + if (player != target || player.storage.oldniepan) return false; }, - save:true, - result:{ - player:function(player){ - if(player.hp<=0) return 10; - if(player.hp<=2&&player.countCards('he')<=1) return 10; + save: true, + result: { + player: function (player) { + if (player.hp <= 0) return 10; + if (player.hp <= 2 && player.countCards("he") <= 1) return 10; return 0; - } + }, + }, + threaten: function (player, target) { + if (!target.storage.oldniepan) return 0.6; }, - threaten:function(player,target){ - if(!target.storage.oldniepan) return 0.6; - } }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - quhu:{ - audio:2, - audioname:['re_xunyu','ol_xunyu'], - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.countCards('h')==0) return false; - return game.hasPlayer(function(current){ - return current.hp>player.hp&&player.canCompare(current); + quhu: { + audio: 2, + audioname: ["re_xunyu", "ol_xunyu"], + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.countCards("h") == 0) return false; + return game.hasPlayer(function (current) { + return current.hp > player.hp && player.canCompare(current); }); }, - filterTarget:function(card,player,target){ - return target.hp>player.hp&&player.canCompare(target); + filterTarget: function (card, player, target) { + return target.hp > player.hp && player.canCompare(target); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.bool){ - if(game.hasPlayer(function(player){ - return player!=target&&target.inRange(player); - })){ - player.chooseTarget(function(card,player,target){ - var source=_status.event.source; - return target!=source&&source.inRange(target); - },true).set('ai',function(target){ - return get.damageEffect(target,_status.event.source,player); - }).set('source',target); - } - else{ + "step 1"; + if (result.bool) { + if ( + game.hasPlayer(function (player) { + return player != target && target.inRange(player); + }) + ) { + player + .chooseTarget(function (card, player, target) { + var source = _status.event.source; + return target != source && source.inRange(target); + }, true) + .set("ai", function (target) { + return get.damageEffect(target, _status.event.source, player); + }) + .set("source", target); + } else { event.finish(); } - } - else{ + } else { player.damage(target); event.finish(); } - "step 2" - if(result.bool&&result.targets&&result.targets.length){ - target.line(result.targets[0],'green'); + "step 2"; + if (result.bool && result.targets && result.targets.length) { + target.line(result.targets[0], "green"); result.targets[0].damage(target); } }, - ai:{ - order:0.5, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var oc=(target.countCards('h')==1); - if(att>0&&oc) return 0; - var players=game.filterPlayer(); - for(var i=0;i0){ - return att>0?att/2:att-(oc?5:0); + ai: { + order: 0.5, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + var oc = target.countCards("h") == 1; + if (att > 0 && oc) return 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != target && + players[i] != player && + target.inRange(players[i]) + ) { + if (get.damageEffect(players[i], target, player) > 0) { + return att > 0 ? att / 2 : att - (oc ? 5 : 0); } } } return 0; }, - player:function(player,target){ - if(target.hasSkillTag('jueqing',false,target)) return -10; - var mn=1; - var hs=player.getCards('h'); - for(var i=0;i2){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + if (mn <= 11 && player.hp < 2) return -20; + var max = player.maxHp - hs.length; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 2) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return mn==13?0:-20; - case 1:return mn>=12?0:-15; - case 2:return 0; - case 3:return 1; - default:return max; + switch (max) { + case 0: + return mn == 13 ? 0 : -20; + case 1: + return mn >= 12 ? 0 : -15; + case 2: + return 0; + case 3: + return 1; + default: + return max; } - } + }, }, - expose:0.2 - } + expose: 0.2, + }, }, - jieming:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" + jieming: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - player.chooseTarget(get.prompt2('jieming'),function(card,player,target){ - return true;//target.countCards('h')2){ - return Math.max(0,Math.min(5,target.maxHp)-target.countCards('h')); + player + .chooseTarget(get.prompt2("jieming"), function (card, player, target) { + return true; //target.countCards('h') 2) { + return Math.max(0, Math.min(5, target.maxHp) - target.countCards("h")); + } + return att / 3; + }); + "step 2"; + if (result.bool) { + player.logSkill("jieming", result.targets); + for (var i = 0; i < result.targets.length; i++) { + result.targets[i].drawTo(Math.min(5, result.targets[i].maxHp)); } - return att/3; - }); - "step 2" - if(result.bool){ - player.logSkill('jieming',result.targets); - for(var i=0;i1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - var max=0; - var players=game.filterPlayer(); - for(var i=0;i0){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + var max = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(target, players[i]) > 0) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return 2; - case 1:return 1.5; - case 2:return [1,2]; - default:return [0,max]; + switch (max) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return [1, 2]; + default: + return [0, max]; } } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; - } + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; + }, }, - } + }, }, - qiangxix:{ - inherit:'reqiangxi', - audioname:['boss_lvbu3'], - audio:'qiangxi', - usable:2, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(target.hasSkill('reqiangxi_off')) return false; + qiangxix: { + inherit: "reqiangxi", + audioname: ["boss_lvbu3"], + audio: "qiangxi", + usable: 2, + filterTarget: function (card, player, target) { + if (player == target) return false; + if (target.hasSkill("reqiangxi_off")) return false; return true; }, }, - qiangxi:{ - audio:2, - enable:'phaseUse', - usable:1, - audioname:['boss_lvbu3'], - filterCard:function(card){ - return get.subtype(card)=='equip1'; + qiangxi: { + audio: 2, + enable: "phaseUse", + usable: 1, + audioname: ["boss_lvbu3"], + filterCard: function (card) { + return get.subtype(card) == "equip1"; }, - selectCard:[0,1], - filterTarget:function(card,player,target){ - if(player==target) return false; + selectCard: [0, 1], + filterTarget: function (card, player, target) { + if (player == target) return false; return player.inRange(target); }, - content:function(){ - "step 0" - if(cards.length==0){ + content: function () { + "step 0"; + if (cards.length == 0) { player.loseHp(); } - "step 1" - target.damage('nocard'); + "step 1"; + target.damage("nocard"); }, - check:function(card){ - return 10-get.value(card); + check: function (card) { + return 10 - get.value(card); }, - position:'he', - ai:{ - damage:true, - order:8, - result:{ - player:function(player,target){ - if(ui.selected.cards.length) return 0; - if(player.hp>=target.hp) return -0.9; - if(player.hp<=2) return -10; + position: "he", + ai: { + damage: true, + order: 8, + result: { + player: function (player, target) { + if (ui.selected.cards.length) return 0; + if (player.hp >= target.hp) return -0.9; + if (player.hp <= 2) return -10; return -2; }, - target:function(player,target){ - if(!ui.selected.cards.length){ - if(player.hp<2) return 0; - if(player.hp==2&&target.hp>=2) return 0; - if(target.hp>player.hp) return 0; + target: function (player, target) { + if (!ui.selected.cards.length) { + if (player.hp < 2) return 0; + if (player.hp == 2 && target.hp >= 2) return 0; + if (target.hp > player.hp) return 0; } - return get.damageEffect(target,player); - } + return get.damageEffect(target, player); + }, }, - threaten:1.3, + threaten: 1.3, }, }, - xinqiangxi:{ - audio:'qiangxi', - enable:'phaseUse', - filter:function(event,player){ - if(player.hasSkill('xinqiangxi2')){ - return !player.hasSkill('xinqiangxi3'); - } - else if(player.hasSkill('xinqiangxi3')){ - return !player.hasSkill('xinqiangxi2')&&player.countCards('he',{type:'equip'})>0; - } - else{ + xinqiangxi: { + audio: "qiangxi", + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("xinqiangxi2")) { + return !player.hasSkill("xinqiangxi3"); + } else if (player.hasSkill("xinqiangxi3")) { + return ( + !player.hasSkill("xinqiangxi2") && player.countCards("he", { type: "equip" }) > 0 + ); + } else { return true; } }, - filterCard:function(card){ - var player=_status.event.player; - if(player.hasSkill('xinqiangxi2')) return false; - return get.type(card)=='equip'; + filterCard: function (card) { + var player = _status.event.player; + if (player.hasSkill("xinqiangxi2")) return false; + return get.type(card) == "equip"; }, - selectCard:function(){ - var player=_status.event.player; - if(player.hasSkill('xinqiangxi2')) return -1; - if(player.hasSkill('xinqiangxi3')) return [1,1]; - return [0,1]; + selectCard: function () { + var player = _status.event.player; + if (player.hasSkill("xinqiangxi2")) return -1; + if (player.hasSkill("xinqiangxi3")) return [1, 1]; + return [0, 1]; }, - filterTarget:function(card,player,target){ - if(player==target) return false; + filterTarget: function (card, player, target) { + if (player == target) return false; return player.inRange(target); }, - content:function(){ - "step 0" - if(cards.length==0){ + content: function () { + "step 0"; + if (cards.length == 0) { player.loseHp(); - player.addTempSkill('xinqiangxi3'); + player.addTempSkill("xinqiangxi3"); + } else { + player.addTempSkill("xinqiangxi2"); } - else{ - player.addTempSkill('xinqiangxi2'); - } - "step 1" - target.damage('nocard'); + "step 1"; + target.damage("nocard"); }, - check:function(card){ - return 10-get.value(card); + check: function (card) { + return 10 - get.value(card); }, - position:'he', - ai:{ - order:8.5, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length){ - if(player.hp<2) return 0; - if(target.hp>=player.hp) return 0; + position: "he", + ai: { + order: 8.5, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) { + if (player.hp < 2) return 0; + if (target.hp >= player.hp) return 0; } - return get.damageEffect(target,player); - } - } + return get.damageEffect(target, player); + }, + }, }, - threaten:1.5 + threaten: 1.5, }, - xinqiangxi2:{}, - xinqiangxi3:{}, - tianyi:{ - audio:2, - audioname:['re_taishici'], - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + xinqiangxi2: {}, + xinqiangxi3: {}, + tianyi: { + audio: 2, + audioname: ["re_taishici"], + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.bool){ - player.addTempSkill('tianyi2'); - } - else{ - player.addTempSkill('tianyi3'); + "step 1"; + if (result.bool) { + player.addTempSkill("tianyi2"); + } else { + player.addTempSkill("tianyi3"); } }, - ai:{ - order:function(name,player){ - var cards=player.getCards('h'); - if(player.countCards('h','sha')==0){ + ai: { + order: function (name, player) { + var cards = player.getCards("h"); + if (player.countCards("h", "sha") == 0) { return 1; } - for(var i=0;i11&&get.value(cards[i])<7){ + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].name != "sha" && + get.number(cards[i]) > 11 && + get.value(cards[i]) < 7 + ) { return 9; } } - return get.order({name:'sha'})-1; + return get.order({ name: "sha" }) - 1; }, - result:{ - player:function(player){ - if(player.countCards('h','sha')>0) return 0.6; - var num=player.countCards('h'); - if(num>player.hp) return 0; - if(num==1) return -2; - if(num==2) return -1; + result: { + player: function (player) { + if (player.countCards("h", "sha") > 0) return 0.6; + var num = player.countCards("h"); + if (num > player.hp) return 0; + if (num == 1) return -2; + if (num == 2) return -1; return -0.7; }, - target:function(player,target){ - var num=target.countCards('h'); - if(num==1) return -1; - if(num==2) return -0.7; - return -0.5 + target: function (player, target) { + var num = target.countCards("h"); + if (num == 1) return -1; + if (num == 2) return -0.7; + return -0.5; }, }, - threaten:1.3 - } + threaten: 1.3, + }, }, - tianyi2:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(card.name=='sha') return true; + tianyi2: { + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "sha") return true; }, - selectTarget:function(card,player,range){ - if(card.name=='sha'&&range[1]!=-1) range[1]++; + selectTarget: function (card, player, range) { + if (card.name == "sha" && range[1] != -1) range[1]++; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } }, - charlotte:true, + charlotte: true, }, - tianyi3:{ - mod:{ - cardEnabled:function(card){if(card.name=='sha') return false} + tianyi3: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, }, - charlotte:true, + charlotte: true, }, - shuangxiong:{ - audio:2, - audioname:['re_yanwen'], - group:'shuangxiong1', - subSkill:{ - re_yanwen1:{audio:true}, - re_yanwen2:{audio:true}, + shuangxiong: { + audio: 2, + audioname: ["re_yanwen"], + group: "shuangxiong1", + subSkill: { + re_yanwen1: { audio: true }, + re_yanwen2: { audio: true }, }, }, - shuangxiong1:{ - audio:true, - trigger:{player:'phaseDrawBegin1'}, - check:function(event,player){ - if(player.countCards('h')>player.hp) return true; - if(player.countCards('h')>3) return true; + shuangxiong1: { + audio: true, + trigger: { player: "phaseDrawBegin1" }, + check: function (event, player) { + if (player.countCards("h") > player.hp) return true; + if (player.countCards("h") > 3) return true; return false; }, - filter:function(event,player){ + filter: function (event, player) { return !event.numFixed; }, - preHidden:true, - prompt2:()=>'进行一次判定,本回合可以将一张与此牌颜色不同的手牌当作【决斗】使用', - content:function(){ - player.judge().set('callback',lib.skill.shuangxiong1.callback); + preHidden: true, + prompt2: () => "进行一次判定,本回合可以将一张与此牌颜色不同的手牌当作【决斗】使用", + content: function () { + player.judge().set("callback", lib.skill.shuangxiong1.callback); trigger.changeToZero(); }, - callback:function(){ - player.gain(card,'gain2'); - player.addTempSkill('shuangxiong2'); - player.markAuto('shuangxiong2',[event.judgeResult.color]); + callback: function () { + player.gain(card, "gain2"); + player.addTempSkill("shuangxiong2"); + player.markAuto("shuangxiong2", [event.judgeResult.color]); }, }, - shuangxiong2:{ - charlotte:true, - onremove:true, - audio:true, - audioname2:{ - re_yanwen:'shuangxiong_re_yanwen2', + shuangxiong2: { + charlotte: true, + onremove: true, + audio: true, + audioname2: { + re_yanwen: "shuangxiong_re_yanwen2", }, - enable:'chooseToUse', - viewAs:{name:'juedou'}, - position:'hs', - viewAsFilter:function(player){ - return player.hasCard(card=>lib.skill.shuangxiong2.filterCard(card,player),'hs'); + enable: "chooseToUse", + viewAs: { name: "juedou" }, + position: "hs", + viewAsFilter: function (player) { + return player.hasCard((card) => lib.skill.shuangxiong2.filterCard(card, player), "hs"); }, - filterCard:function(card,player){ - var color=get.color(card),colors=player.getStorage('shuangxiong2'); - for(var i of colors){ - if(color!=i) return true; + filterCard: function (card, player) { + var color = get.color(card), + colors = player.getStorage("shuangxiong2"); + for (var i of colors) { + if (color != i) return true; } return false; }, - prompt:function(){ - var colors=_status.event.player.getStorage('shuangxiong2'); - var str='将一张颜色'; - for(var i=0;i0) str+='或'; - str+='不为'; - str+=get.translation(colors[i]); + prompt: function () { + var colors = _status.event.player.getStorage("shuangxiong2"); + var str = "将一张颜色"; + for (var i = 0; i < colors.length; i++) { + if (i > 0) str += "或"; + str += "不为"; + str += get.translation(colors[i]); } - str+='的牌当做【决斗】使用'; + str += "的牌当做【决斗】使用"; return str; }, - check:function(card){ - var player=_status.event.player; - var raw=player.getUseValue(card,null,true); - var eff=player.getUseValue(get.autoViewAs({name:'juedou'},[card])); - return eff-raw; + check: function (card) { + var player = _status.event.player; + var raw = player.getUseValue(card, null, true); + var eff = player.getUseValue(get.autoViewAs({ name: "juedou" }, [card])); + return eff - raw; }, - ai:{order:7}, + ai: { order: 7 }, }, - luanji:{ - audio:2, - enable:'phaseUse', - position:'hs', - viewAs:{name:'wanjian'}, - filterCard:function(card,player){ - if(ui.selected.cards.length){ - return get.suit(card)==get.suit(ui.selected.cards[0]); + luanji: { + audio: 2, + enable: "phaseUse", + position: "hs", + viewAs: { name: "wanjian" }, + filterCard: function (card, player) { + if (ui.selected.cards.length) { + return get.suit(card) == get.suit(ui.selected.cards[0]); } - var cards=player.getCards('hs'); - for(var i=0;i=7){ - if(num<2) return 0; - } - else if(targets.length>=5){ - if(num<1.5) return 0; + if (!player.needsToDiscard(-1)) { + if (targets.length >= 7) { + if (num < 2) return 0; + } else if (targets.length >= 5) { + if (num < 1.5) return 0; } } - return 6-get.value(card); + return 6 - get.value(card); + }, + ai: { + basic: { + order: 8.5, + }, }, - ai:{ - basic:{ - order:8.5 - } - } }, - xueyi:{ - trigger:{player:'phaseDiscardBefore'}, - audio:2, - audioname:['re_yuanshao'], - forced:true, - firstDo:true, - filter:function(event,player){ - return player.hasZhuSkill('xueyi')&&game.hasPlayer(function(current){ - return current!=player&¤t.group=='qun'; - })&&player.countCards('h')>player.hp; + xueyi: { + trigger: { player: "phaseDiscardBefore" }, + audio: 2, + audioname: ["re_yuanshao"], + forced: true, + firstDo: true, + filter: function (event, player) { + return ( + player.hasZhuSkill("xueyi") && + game.hasPlayer(function (current) { + return current != player && current.group == "qun"; + }) && + player.countCards("h") > player.hp + ); }, - content:function(){}, - mod:{ - maxHandcard:function(player,num){ - if(player.hasZhuSkill('xueyi')){ - return num+game.countPlayer(function(current){ - if(player!=current&¤t.group=='qun') return 2; - }); + content: function () {}, + mod: { + maxHandcard: function (player, num) { + if (player.hasZhuSkill("xueyi")) { + return ( + num + + game.countPlayer(function (current) { + if (player != current && current.group == "qun") return 2; + }) + ); } return num; - } + }, }, - zhuSkill:true, + zhuSkill: true, }, - mengjin:{ - shaRelated:true, - audio:2, - trigger:{player:'shaMiss'}, + mengjin: { + shaRelated: true, + audio: 2, + trigger: { player: "shaMiss" }, //priority:-1, - filter:function(event){ - return event.target.countCards('he')>0; + filter: function (event) { + return event.target.countCards("he") > 0; }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + logTarget: "target", + content: function () { + player.discardPlayerCard("he", trigger.target, true); }, - logTarget:'target', - content:function(){ - player.discardPlayerCard('he',trigger.target,true); - } }, - jiewei:{ - trigger:{player:'turnOverEnd'}, + jiewei: { + trigger: { player: "turnOverEnd" }, //direct:true, - frequent:true, - audio:'xinjiewei', - content:function(){ - 'step 0' + frequent: true, + audio: "xinjiewei", + content: function () { + "step 0"; player.draw(); - player.chooseToUse(function(card){ - if(!lib.filter.cardEnabled(card,_status.event.player,_status.event)){ + player.chooseToUse(function (card) { + if (!lib.filter.cardEnabled(card, _status.event.player, _status.event)) { return false; } - var type=get.type(card,'trick'); - return type=='trick'||type=='equip'; - },'是否使用一张锦囊牌或装备牌?'); - 'step 1' - if(result.bool){ - var type=get.type(result.card||result.cards[0]); - if(game.hasPlayer(function(current){ - if(type=='equip'){ - return current.countCards('e'); - } - else{ - return current.countCards('j'); - } - })){ - var next=player.chooseTarget('是否弃置场上的一张'+get.translation(type)+'牌?',function(card,player,target){ - if(_status.event.type=='equip'){ - return target.countCards('e')>0; + var type = get.type(card, "trick"); + return type == "trick" || type == "equip"; + }, "是否使用一张锦囊牌或装备牌?"); + "step 1"; + if (result.bool) { + var type = get.type(result.card || result.cards[0]); + if ( + game.hasPlayer(function (current) { + if (type == "equip") { + return current.countCards("e"); + } else { + return current.countCards("j"); } - else{ - return target.countCards('j')>0; + }) + ) { + var next = player.chooseTarget( + "是否弃置场上的一张" + get.translation(type) + "牌?", + function (card, player, target) { + if (_status.event.type == "equip") { + return target.countCards("e") > 0; + } else { + return target.countCards("j") > 0; + } + } + ); + next.set("ai", function (target) { + if (type == "equip") { + return -get.attitude(player, target); + } else { + return get.attitude(player, target); } }); - next.set('ai',function(target){ - if(type=='equip'){ - return -get.attitude(player,target); - } - else{ - return get.attitude(player,target); - } - }); - next.set('type',type); - event.type=type; - } - else{ + next.set("type", type); + event.type = type; + } else { event.finish(); } - } - else{ + } else { event.finish(); } - 'step 2' - if(event.type&&result.bool&&result.targets&&result.targets.length){ - player.line(result.targets,'green'); - if(event.type=='equip'){ - player.discardPlayerCard(result.targets[0],'e',true); - } - else{ - player.discardPlayerCard(result.targets[0],'j',true); + "step 2"; + if (event.type && result.bool && result.targets && result.targets.length) { + player.line(result.targets, "green"); + if (event.type == "equip") { + player.discardPlayerCard(result.targets[0], "e", true); + } else { + player.discardPlayerCard(result.targets[0], "j", true); } } - } + }, }, - releiji:{ - audio:2, - audioname:['boss_qinglong'], - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - return event.card.name=='shan'; + releiji: { + audio: 2, + audioname: ["boss_qinglong"], + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + return event.card.name == "shan"; }, - direct:true, - content:function(){ + direct: true, + content: function () { "step 0"; - player.chooseTarget(get.prompt2('releiji'),function(card,player,target){ - return target!=player; - }).ai=function(target){ - if(target.hasSkill('hongyan')) return 0; - return get.damageEffect(target,_status.event.player,_status.event.player,'thunder'); + player.chooseTarget(get.prompt2("releiji"), function (card, player, target) { + return target != player; + }).ai = function (target) { + if (target.hasSkill("hongyan")) return 0; + return get.damageEffect( + target, + _status.event.player, + _status.event.player, + "thunder" + ); }; - "step 1" - if(result.bool){ - player.logSkill('releiji',result.targets,'thunder'); - event.target=result.targets[0]; - event.target.judge(function(card){ - var suit=get.suit(card); - if(suit=='spade') return -4; - if(suit=='club') return -2; + "step 1"; + if (result.bool) { + player.logSkill("releiji", result.targets, "thunder"); + event.target = result.targets[0]; + event.target.judge(function (card) { + var suit = get.suit(card); + if (suit == "spade") return -4; + if (suit == "club") return -2; return 0; - }).judge2=function(result){ - return result.bool==false?true:false; + }).judge2 = function (result) { + return result.bool == false ? true : false; }; - } - else{ + } else { event.finish(); } - "step 2" - if(result.suit=='club'){ + "step 2"; + if (result.suit == "club") { player.recover(); - event.target.damage('thunder'); - } - else if(result.suit=='spade'){ - event.target.damage(2,'thunder'); + event.target.damage("thunder"); + } else if (result.suit == "spade") { + event.target.damage(2, "thunder"); } }, - ai:{ - useShan:true, - effect:{ - target:function(card,player,target,current){ - 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; + ai: { + useShan: true, + effect: { + target: function (card, player, target, current) { + 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.isHealthy()) club+=2; - if(!club&&!spade) return 1; - if(card.name==='sha'){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return; - } - else 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; + if (!target.isHealthy()) club += 2; + if (!club && !spade) return 1; + if (card.name === "sha") { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return; + } else 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]; + 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]; } - } - } - } - }, - shensu:{ - audio:'shensu1', - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - group:['shensu1','shensu2'], - preHidden:['shensu1','shensu2'], - }, - xinshensu:{ - audio:'shensu1', - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - audioname2:{ - dc_xiahouba:'shensu1_xiahouba', + }, + }, }, - group:['shensu1','shensu2','shensu4'] }, - shensu1_xiahouba:{audio:2}, - shensu1:{ - audio:2, - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - audioname2:{ - dc_xiahouba:'shensu1_xiahouba', + shensu: { + audio: "shensu1", + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + group: ["shensu1", "shensu2"], + preHidden: ["shensu1", "shensu2"], + }, + xinshensu: { + audio: "shensu1", + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + audioname2: { + dc_xiahouba: "shensu1_xiahouba", }, - trigger:{player:'phaseJudgeBefore'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt("shensu"),"跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',player.countCards('h')>2).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }).setHiddenSkill('shensu1'); - "step 1" - if(result.bool){ - player.logSkill('shensu1',result.targets); - player.useCard({name:'sha',isCard:true},result.targets[0],false); + group: ["shensu1", "shensu2", "shensu4"], + }, + shensu1_xiahouba: { audio: 2 }, + shensu1: { + audio: 2, + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + audioname2: { + dc_xiahouba: "shensu1_xiahouba", + }, + trigger: { player: "phaseJudgeBefore" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("shensu"), + "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", player.countCards("h") > 2) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }) + .setHiddenSkill("shensu1"); + "step 1"; + if (result.bool) { + player.logSkill("shensu1", result.targets); + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); trigger.cancel(); - player.skip('phaseDraw'); + player.skip("phaseDraw"); } - } + }, }, - shensu2:{ - audio:'shensu1', - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - audioname2:{ - dc_xiahouba:'shensu1_xiahouba', + shensu2: { + audio: "shensu1", + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + audioname2: { + dc_xiahouba: "shensu1_xiahouba", }, - trigger:{player:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',function(card){ - if(_status.connectMode) return true; - return get.type(card)=='equip'; - })>0; + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + if (_status.connectMode) return true; + return get.type(card) == "equip"; + }) > 0 + ); }, - content:function(){ - "step 0" - player.chooseCardTarget({ - prompt:get.prompt('shensu'), - prompt2:"弃置一张装备牌并跳过出牌阶段,视为对一名其他角色使用一张【杀】", - filterCard:function(card,player){ - return get.type(card)=='equip'&&lib.filter.cardDiscardable(card,player) - }, - position:'he', - filterTarget:function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }, - ai1:function(card){ - if(_status.event.check) return 0; - return 6-get.value(card); - }, - ai2:function(target){ - if(_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }, - check:player.countCards('hs',i=>{ - return player.hasValueTarget(i,null,true); - })>player.hp-1 - }).setHiddenSkill('shensu2'); - "step 1" - if(result.bool){ - player.logSkill('shensu2',result.targets); + content: function () { + "step 0"; + player + .chooseCardTarget({ + prompt: get.prompt("shensu"), + prompt2: "弃置一张装备牌并跳过出牌阶段,视为对一名其他角色使用一张【杀】", + filterCard: function (card, player) { + return get.type(card) == "equip" && lib.filter.cardDiscardable(card, player); + }, + position: "he", + filterTarget: function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + }, + ai1: function (card) { + if (_status.event.check) return 0; + return 6 - get.value(card); + }, + ai2: function (target) { + if (_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }, + check: + player.countCards("hs", (i) => { + return player.hasValueTarget(i, null, true); + }) > + player.hp - 1, + }) + .setHiddenSkill("shensu2"); + "step 1"; + if (result.bool) { + player.logSkill("shensu2", result.targets); player.discard(result.cards[0]); - player.useCard({name:'sha',isCard:true},result.targets[0],false); + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); trigger.cancel(); } - } - }, - shensu4:{ - audio:'shensu1', - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - audioname2:{ - dc_xiahouba:'shensu1_xiahouba', }, - trigger:{player:'phaseDiscardBefore'}, - direct:true, - content:function(){ - "step 0" - var check=player.needsToDiscard()||player.isTurnedOver()||(player.hasSkill('shebian')&&player.canMoveCard(true,true)); - player.chooseTarget(get.prompt('shensu'),"跳过弃牌阶段并将武将牌翻面,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',check).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player); - }); - "step 1" - if(result.bool){ - player.logSkill('shensu4',result.targets); + }, + shensu4: { + audio: "shensu1", + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + audioname2: { + dc_xiahouba: "shensu1_xiahouba", + }, + trigger: { player: "phaseDiscardBefore" }, + direct: true, + content: function () { + "step 0"; + var check = + player.needsToDiscard() || + player.isTurnedOver() || + (player.hasSkill("shebian") && player.canMoveCard(true, true)); + player + .chooseTarget( + get.prompt("shensu"), + "跳过弃牌阶段并将武将牌翻面,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", check) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect( + target, + { name: "sha" }, + _status.event.player, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + player.logSkill("shensu4", result.targets); player.turnOver(); - player.useCard({name:'sha',isCard:true},result.targets[0],false); + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); trigger.cancel(); } - } - }, - jushou:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - check:function(event,player){ - return event.player.hp+player.countCards('h')<4; }, - content:function(){ + }, + jushou: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + check: function (event, player) { + return event.player.hp + player.countCards("h") < 4; + }, + content: function () { player.draw(3); player.turnOver(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,1]; - } - } + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 1]; + }, + }, }, }, - moon_jushou:{ - audio:'xinjushou', - trigger:{player:'phaseJieshuBegin'}, - check:function(event,player){ - return event.player.hp+player.countCards('h')<4; + moon_jushou: { + audio: "xinjushou", + trigger: { player: "phaseJieshuBegin" }, + check: function (event, player) { + return event.player.hp + player.countCards("h") < 4; }, - content:function(){ + content: function () { player.draw(); player.turnOver(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,1]; - } - } + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 1]; + }, + }, }, }, - liegong:{ - shaRelated:true, - audio:2, - audioname:['re_huangzhong'], - trigger:{player:'useCardToPlayered'}, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + liegong: { + shaRelated: true, + audio: 2, + audioname: ["re_huangzhong"], + trigger: { player: "useCardToPlayered" }, + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - logTarget:'target', - filter:function(event,player){ - if(event.card.name!='sha') return false; - var length=event.target.countCards('h'); - return (length>=player.hp||length<=player.getAttackRange()); + logTarget: "target", + filter: function (event, player) { + if (event.card.name != "sha") return false; + var length = event.target.countCards("h"); + return length >= player.hp || length <= player.getAttackRange(); }, - preHidden:true, - content:function(){ + preHidden: true, + content: function () { trigger.getParent().directHit.push(trigger.target); }, - locked:false, - mod:{ - attackRange:function(player,distance){ - if(get.zhu(player,'shouyue')) return distance+1; - } + locked: false, + mod: { + attackRange: function (player, distance) { + if (get.zhu(player, "shouyue")) return distance + 1; + }, }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)>0||arg.card.name!='sha') return false; - var length=arg.target.countCards('h'); - return (length>=player.hp||length<=player.getAttackRange()); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (get.attitude(player, arg.target) > 0 || arg.card.name != "sha") return false; + var length = arg.target.countCards("h"); + return length >= player.hp || length <= player.getAttackRange(); }, }, }, - kuanggu:{ - audio:2, - audioname:['re_weiyan','ol_weiyan'], - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.kuangguCheck&&player.isDamaged(); + kuanggu: { + audio: 2, + audioname: ["re_weiyan", "ol_weiyan"], + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + return event.kuangguCheck && player.isDamaged(); }, - content:function(){ + 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; + 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; + firstDo: true, + silent: true, + content: function () { + trigger.kuangguCheck = true; }, }, }, }, - tianxiang:{ - audio:2, - audioname:['daxiaoqiao','re_xiaoqiao','ol_xiaoqiao'], - trigger:{player:'damageBegin3'}, - direct:true, - filter:function(event,player){ - return player.countCards('h',{suit:'heart'})>0&&event.num>0; + tianxiang: { + audio: 2, + audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"], + trigger: { player: "damageBegin3" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", { suit: "heart" }) > 0 && event.num > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:function(card,player){ - return get.suit(card)=='heart'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - return 10-get.value(card); + ai1: function (card) { + return 10 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var trigger=_status.event.getTrigger(); - var da=0; - if(_status.event.player.hp==1){ - da=10; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var trigger = _status.event.getTrigger(); + var da = 0; + if (_status.event.player.hp == 1) { + da = 10; } - if(trigger.num>1){ - if(target.maxHp>5&&target.hp>1) return -att/10+da; - return -att+da; + if (trigger.num > 1) { + if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da; + return -att + da; } - var eff=get.damageEffect(target,trigger.source,target,trigger.nature); - if(att==0) return 0.1+da; - if(eff>=0&&trigger.num==1){ - return att+da; + var eff = get.damageEffect(target, trigger.source, target, trigger.nature); + if (att == 0) return 0.1 + da; + if (eff >= 0 && trigger.num == 1) { + return att + da; } - if(target.hp==target.maxHp) return -att+da; - if(target.hp==1){ - if(target.maxHp<=4&&!target.hasSkillTag('maixie')){ - if(target.maxHp<=3){ - return -att+da; + if (target.hp == target.maxHp) return -att + da; + if (target.hp == 1) { + if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) { + if (target.maxHp <= 3) { + return -att + da; } - return -att/2+da; + return -att / 2 + da; } return da; } - if(target.hp==target.maxHp-1){ - if(target.hp>2||target.hasSkillTag('maixie')) return att/5+da; - if(att>0) return 0.02+da; - return 0.05+da; + if (target.hp == target.maxHp - 1) { + if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da; + if (att > 0) return 0.02 + da; + return 0.05 + da; } - return att/2+da; + return att / 2 + da; }, - prompt:get.prompt2('tianxiang') + prompt: get.prompt2("tianxiang"), }); - "step 1" - if(result.bool){ - player.logSkill(event.name,result.targets); - trigger.player=result.targets[0]; - trigger.player.addSkill('tianxiang2'); + "step 1"; + if (result.bool) { + player.logSkill(event.name, result.targets); + trigger.player = result.targets[0]; + trigger.player.addSkill("tianxiang2"); player.discard(result.cards[0]); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&target.countCards('h')>1) return 0.7; - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.tag(card, "damage") && target.countCards("h") > 1) return 0.7; + }, + }, + threaten: function (player, target) { + if (target.countCards("h") == 0) return 2; }, - threaten:function(player,target){ - if(target.countCards('h')==0) return 2; - } - } - }, - tianxiang2:{ - trigger:{player:['damageAfter','damageCancelled','damageZero']}, - forced:true, - popup:false, - audio:false, - vanish:true, - charlotte:true, - content:function(){ - if(player.getDamagedHp()) player.draw(player.getDamagedHp()); - player.removeSkill('tianxiang2'); - player.popup('tianxiang'); - } - }, - retianxiang:{ - audio:'tianxiang', - audioname:['daxiaoqiao','re_xiaoqiao','ol_xiaoqiao'], - trigger:{player:'damageBegin4'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('h',function(card){ - return _status.connectMode||get.suit(card,player)=='heart'; - })>0&&event.num>0; }, - content:function(){ - "step 0" - player.chooseCardTarget({ - filterCard:function(card,player){ - return get.suit(card)=='heart'&&lib.filter.cardDiscardable(card,player); - }, - filterTarget:function(card,player,target){ - return player!=target; - }, - ai1:function(card){ - return 10-get.value(card); - }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var trigger=_status.event.getTrigger(); - var da=0; - if(_status.event.player.hp==1){ - da=10; - } - var eff=get.damageEffect(target,trigger.source,target); - if(att==0) return 0.1+da; - if(eff>=0&&att>0){ - return att+da; - } - if(att>0&&target.hp>1){ - if(target.maxHp-target.hp>=3) return att*1.1+da; - if(target.maxHp-target.hp>=2) return att*0.9+da; - } - return -att+da; - }, - prompt:get.prompt('retianxiang'), - prompt2:lib.translate.retianxiang_info - }).setHiddenSkill(event.name); - "step 1" - if(result.bool){ + }, + tianxiang2: { + trigger: { player: ["damageAfter", "damageCancelled", "damageZero"] }, + forced: true, + popup: false, + audio: false, + vanish: true, + charlotte: true, + content: function () { + if (player.getDamagedHp()) player.draw(player.getDamagedHp()); + player.removeSkill("tianxiang2"); + player.popup("tianxiang"); + }, + }, + retianxiang: { + audio: "tianxiang", + audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"], + trigger: { player: "damageBegin4" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + player.countCards("h", function (card) { + return _status.connectMode || get.suit(card, player) == "heart"; + }) > 0 && event.num > 0 + ); + }, + content: function () { + "step 0"; + player + .chooseCardTarget({ + filterCard: function (card, player) { + return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player); + }, + filterTarget: function (card, player, target) { + return player != target; + }, + ai1: function (card) { + return 10 - get.value(card); + }, + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var trigger = _status.event.getTrigger(); + var da = 0; + if (_status.event.player.hp == 1) { + da = 10; + } + var eff = get.damageEffect(target, trigger.source, target); + if (att == 0) return 0.1 + da; + if (eff >= 0 && att > 0) { + return att + da; + } + if (att > 0 && target.hp > 1) { + if (target.maxHp - target.hp >= 3) return att * 1.1 + da; + if (target.maxHp - target.hp >= 2) return att * 0.9 + da; + } + return -att + da; + }, + prompt: get.prompt("retianxiang"), + prompt2: lib.translate.retianxiang_info, + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { player.discard(result.cards); - var target=result.targets[0]; - player.chooseControlList(true,function(event,player){ - var target=_status.event.target; - var att=get.attitude(player,target); - if(target.hasSkillTag('maihp')) att=-att; - if(att>0){ - return 0; - } - else{ - return 1; - } - }, - ['令'+get.translation(target)+'受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)', - '令'+get.translation(target)+'失去1点体力,然后获得'+get.translation(result.cards)]).set('target',target); - player.logSkill(event.name,target); + var target = result.targets[0]; + player + .chooseControlList( + true, + function (event, player) { + var target = _status.event.target; + var att = get.attitude(player, target); + if (target.hasSkillTag("maihp")) att = -att; + if (att > 0) { + return 0; + } else { + return 1; + } + }, + [ + "令" + + get.translation(target) + + "受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)", + "令" + + get.translation(target) + + "失去1点体力,然后获得" + + get.translation(result.cards), + ] + ) + .set("target", target); + player.logSkill(event.name, target); trigger.cancel(); - event.target=target; - event.card=result.cards[0]; - } - else{ + event.target = target; + event.card = result.cards[0]; + } else { event.finish(); } - "step 2" - if(typeof result.index=='number'){ - event.index=result.index; - if(result.index){ - event.related=event.target.loseHp(); + "step 2"; + if (typeof result.index == "number") { + event.index = result.index; + if (result.index) { + event.related = event.target.loseHp(); + } else { + event.related = event.target.damage(trigger.source || "nosource", "nocard"); } - else{ - event.related=event.target.damage(trigger.source||'nosource','nocard'); - } - } - else event.finish(); - "step 3" + } else event.finish(); + "step 3"; //if(event.related.cancelled||target.isDead()) return; - if(event.index&&card.isInPile()) target.gain(card,'gain2'); - else if(target.getDamagedHp()) target.draw(Math.min(5,target.getDamagedHp())); + if (event.index && card.isInPile()) target.gain(card, "gain2"); + else if (target.getDamagedHp()) target.draw(Math.min(5, target.getDamagedHp())); }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&target.countCards('he')>1) return 0.7; - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.tag(card, "damage") && target.countCards("he") > 1) return 0.7; + }, }, - } + }, }, - retianxiang3:{ - trigger:{player:'loseHpAfter'}, - forced:true, - popup:false, - filter:function(event){ - return event.type=='retianxiang'; + retianxiang3: { + trigger: { player: "loseHpAfter" }, + forced: true, + popup: false, + filter: function (event) { + return event.type == "retianxiang"; }, - vanish:true, - content:function(){ - 'step 0' - player.gain(player.storage.retianxiang3,'gain2'); - 'step 1' - player.removeSkill('retianxiang3'); + vanish: true, + content: function () { + "step 0"; + player.gain(player.storage.retianxiang3, "gain2"); + "step 1"; + player.removeSkill("retianxiang3"); }, - onremove:function(player){ - var card=player.storage.retianxiang3; - if(get.position(card)=='s'){ + onremove: function (player) { + var card = player.storage.retianxiang3; + if (get.position(card) == "s") { game.cardsDiscard(card); } delete player.storage.retianxiang3; - } - }, - retianxiang2:{ - trigger:{player:'damageAfter'}, - forced:true, - popup:false, - filter:function(event){ - return event.type=='retianxiang'; }, - vanish:true, - content:function(){ - if(player.isDamaged()){ + }, + retianxiang2: { + trigger: { player: "damageAfter" }, + forced: true, + popup: false, + filter: function (event) { + return event.type == "retianxiang"; + }, + vanish: true, + content: function () { + if (player.isDamaged()) { player.draw(player.getDamagedHp()); } - player.removeSkill('retianxiang2'); + player.removeSkill("retianxiang2"); }, }, - xintianxiang:{ - audio:'tianxiang', - trigger:{player:'damageBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{suit:'heart'})>0&&event.num>0&&!player.hasSkill('xintianxiang3'); + xintianxiang: { + audio: "tianxiang", + trigger: { player: "damageBefore" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("he", { suit: "heart" }) > 0 && + event.num > 0 && + !player.hasSkill("xintianxiang3") + ); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:function(card,player){ - return get.suit(card)=='heart'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - position:'he', - ai1:function(card){ - return 10-get.value(card); + position: "he", + ai1: function (card) { + return 10 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var trigger=_status.event.getTrigger(); - var da=0; - if(_status.event.player.hp==1){ - da=10; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var trigger = _status.event.getTrigger(); + var da = 0; + if (_status.event.player.hp == 1) { + da = 10; } - if(trigger.num>1){ - if(target.maxHp>5&&target.hp>1) return -att/10+da; - return -att+da; + if (trigger.num > 1) { + if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da; + return -att + da; } - var eff=get.damageEffect(target,trigger.source,target,trigger.nature); - if(att==0) return 0.1+da; - if(eff>=0&&trigger.num==1){ - return att+da; + var eff = get.damageEffect(target, trigger.source, target, trigger.nature); + if (att == 0) return 0.1 + da; + if (eff >= 0 && trigger.num == 1) { + return att + da; } - if(target.hp==target.maxHp) return -att+da; - if(target.hp==1){ - if(target.maxHp<=4&&!target.hasSkillTag('maixie')){ - if(target.maxHp<=3){ - return -att+da; + if (target.hp == target.maxHp) return -att + da; + if (target.hp == 1) { + if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) { + if (target.maxHp <= 3) { + return -att + da; } - return -att/2+da; + return -att / 2 + da; } return da; } - if(target.hp==target.maxHp-1){ - if(target.hp>2||target.hasSkillTag('maixie')) return att/5+da; - if(att>0) return 0.02+da; - return 0.05+da; + if (target.hp == target.maxHp - 1) { + if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da; + if (att > 0) return 0.02 + da; + return 0.05 + da; } - return att/2+da; + return att / 2 + da; }, - prompt:get.prompt2('xintianxiang') + prompt: get.prompt2("xintianxiang"), }); - "step 1" - if(result.bool){ - player.logSkill(event.name,result.targets); - trigger.player=result.targets[0]; - trigger.player.addSkill('xintianxiang2'); - trigger.player.storage.xintianxiang=player; + "step 1"; + if (result.bool) { + player.logSkill(event.name, result.targets); + trigger.player = result.targets[0]; + trigger.player.addSkill("xintianxiang2"); + trigger.player.storage.xintianxiang = player; player.discard(result.cards[0]); - } - else{ + } else { event.finish(); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&target.countCards('he')>1) return 0.7; - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.tag(card, "damage") && target.countCards("he") > 1) return 0.7; + }, }, - } + }, }, - xintianxiang2:{ - trigger:{player:['damageAfter','damageCancelled','damageZero']}, - forced:true, - popup:false, - audio:false, - vanish:true, - content:function(){ - 'step 0' - var source=player.storage.xintianxiang; - if(source.isDead()){ + xintianxiang2: { + trigger: { player: ["damageAfter", "damageCancelled", "damageZero"] }, + forced: true, + popup: false, + audio: false, + vanish: true, + content: function () { + "step 0"; + var source = player.storage.xintianxiang; + if (source.isDead()) { event.finish(); return; } - var num=player.maxHp-player.hp||0; - var str1='令'+get.translation(player)+'摸'+get.cnNumber(num)+'张牌'; - var str2='令'+get.translation(player)+'防止造成和受到的所有伤害且天香失效直到你下一回合开始'; - var att=get.attitude(source,player); - var choice='选项一'; - if(att<0){ - if(num>=2){ - choice='选项二'; + var num = player.maxHp - player.hp || 0; + var str1 = "令" + get.translation(player) + "摸" + get.cnNumber(num) + "张牌"; + var str2 = + "令" + + get.translation(player) + + "防止造成和受到的所有伤害且天香失效直到你下一回合开始"; + var att = get.attitude(source, player); + var choice = "选项一"; + if (att < 0) { + if (num >= 2) { + choice = "选项二"; + } + } else if (att > 0) { + if (num < 2 && !player.hasSkillTag("maixie")) { + choice = "选项二"; } } - else if(att>0){ - if(num<2&&!player.hasSkillTag('maixie')){ - choice='选项二'; + source + .chooseControl(function () { + return _status.event.choice; + }) + .set("choiceList", [str1, str2]) + .set("choice", choice); + "step 1"; + if (result.control == "选项一") { + if (player.isDamaged()) { + player.draw(player.maxHp - player.hp); } + } else { + player.storage.xintianxiang.addSkill("xintianxiang3"); + player.storage.xintianxiang.storage.xintianxiang3 = player; + player.addSkill("xintianxiang4"); } - source.chooseControl(function(){ - return _status.event.choice; - }).set('choiceList',[str1,str2]).set('choice',choice); - 'step 1' - if(result.control=='选项一'){ - if(player.isDamaged()){ - player.draw(player.maxHp-player.hp); - } - } - else{ - player.storage.xintianxiang.addSkill('xintianxiang3'); - player.storage.xintianxiang.storage.xintianxiang3=player; - player.addSkill('xintianxiang4'); - } - player.removeSkill('xintianxiang2'); + player.removeSkill("xintianxiang2"); delete player.storage.xintianxiang; - } + }, }, - xintianxiang3:{ - trigger:{player:['phaseZhunbeiBegin','dieBegin']}, - silent:true, - content:function(){ - if(player.storage.xintianxiang3){ - player.storage.xintianxiang3.removeSkill('xintianxiang4'); + xintianxiang3: { + trigger: { player: ["phaseZhunbeiBegin", "dieBegin"] }, + silent: true, + content: function () { + if (player.storage.xintianxiang3) { + player.storage.xintianxiang3.removeSkill("xintianxiang4"); delete player.storage.xintianxiang3; } - player.removeSkill('xintianxiang3'); - } - }, - xintianxiang4:{ - trigger:{source:'damageBefore',player:'damageBefore'}, - forced:true, - mark:true, - intro:{ - content:'防止造成和受到的一切伤害' + player.removeSkill("xintianxiang3"); }, - priority:15, - content:function(){ + }, + xintianxiang4: { + trigger: { source: "damageBefore", player: "damageBefore" }, + forced: true, + mark: true, + intro: { + content: "防止造成和受到的一切伤害", + }, + priority: 15, + content: function () { trigger.cancel(); }, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - notrick:true, - notricksource:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')){ - return 'zeroplayertarget'; + ai: { + nofire: true, + nothunder: true, + nodamage: true, + notrick: true, + notricksource: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) { + return "zeroplayertarget"; } }, - player:function(card,player,target,current){ - if(get.tag(card,'damage')){ - return 'zeroplayertarget'; + player: function (card, player, target, current) { + if (get.tag(card, "damage")) { + return "zeroplayertarget"; } - } - } - } - }, - hongyan:{ - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'heart'; - } - } - }, - xinhongyan:{ - audio:2, - audioname:['sb_xiaoqiao'], - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'heart'; - } + }, + }, }, - trigger:{global:'judge'}, - direct:true, - filter:function(event,player){ - if(event.fixedResult&&event.fixedResult.suit) return event.fixedResult.suit=='heart'; - return get.suit(event.player.judging[0],event.player)=='heart'; + }, + hongyan: { + mod: { + suit: function (card, suit) { + if (suit == "spade") return "heart"; + }, }, - content:function(){ - "step 0" - var str='红颜:'+get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+',请将其改为一种花色'; - player.chooseControl('spade','heart','diamond','club').set('prompt',str).set('ai',function(){ - var judging=_status.event.judging; - var trigger=_status.event.getTrigger(); - var res1=trigger.judge(judging); - var list=lib.suit.slice(0); - var attitude=get.attitude(player,trigger.player); - if(attitude==0) return 0; - var getj=function(suit){ - return trigger.judge({ - name:get.name(judging), - nature:get.nature(judging), - suit:suit, - number:get.number(judging), - }) - }; - list.sort(function(a,b){ - return (getj(b)-getj(a))*get.sgn(attitude); - }); - return list[0]; - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.control!='cancel2'){ + }, + xinhongyan: { + audio: 2, + audioname: ["sb_xiaoqiao"], + mod: { + suit: function (card, suit) { + if (suit == "spade") return "heart"; + }, + }, + trigger: { global: "judge" }, + direct: true, + filter: function (event, player) { + if (event.fixedResult && event.fixedResult.suit) return event.fixedResult.suit == "heart"; + return get.suit(event.player.judging[0], event.player) == "heart"; + }, + content: function () { + "step 0"; + var str = + "红颜:" + + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + ",请将其改为一种花色"; + player + .chooseControl("spade", "heart", "diamond", "club") + .set("prompt", str) + .set("ai", function () { + var judging = _status.event.judging; + var trigger = _status.event.getTrigger(); + var res1 = trigger.judge(judging); + var list = lib.suit.slice(0); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0) return 0; + var getj = function (suit) { + return trigger.judge({ + name: get.name(judging), + nature: get.nature(judging), + suit: suit, + number: get.number(judging), + }); + }; + list.sort(function (a, b) { + return (getj(b) - getj(a)) * get.sgn(attitude); + }); + return list[0]; + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.control != "cancel2") { player.addExpose(0.25); player.popup(result.control); - game.log(player,'将判定结果改为了','#y'+get.translation(result.control+2)); - if(!trigger.fixedResult) trigger.fixedResult={}; - trigger.fixedResult.suit=result.control; - trigger.fixedResult.color=get.color({suit:result.control}); + game.log(player, "将判定结果改为了", "#y" + get.translation(result.control + 2)); + if (!trigger.fixedResult) trigger.fixedResult = {}; + trigger.fixedResult.suit = result.control; + trigger.fixedResult.color = get.color({ suit: result.control }); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:0.4, + ai: { + rejudge: true, + tag: { + rejudge: 0.4, }, - expose:0.5, + expose: 0.5, }, }, - gzbuqu:{ - audio:2, - trigger:{player:'changeHp'}, - filter:function(event,player){ - return player.hp<=0&&event.num<0; + gzbuqu: { + audio: 2, + trigger: { player: "changeHp" }, + filter: function (event, player) { + return player.hp <= 0 && event.num < 0; }, - marktext:'创', - intro:{ - markcount:'expansion', - content:'expansion', + marktext: "创", + intro: { + markcount: "expansion", + content: "expansion", }, - group:'gzbuqu_recover', - frequent:true, - ondisable:true, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length){ + group: "gzbuqu_recover", + frequent: true, + ondisable: true, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) { //delete player.nodying; player.loseToDiscardpile(cards); - if(player.hp<=0) player.dying({}); + if (player.hp <= 0) player.dying({}); } }, - process:function(player){ + process: function (player) { //delete player.nodying; - var nums=[]; - var cards=player.getExpansions('gzbuqu'); - for(var i=0;i0&&event.num>0; + subSkill: { + recover: { + trigger: { player: "recoverAfter" }, + filter: function (event, player) { + return player.getExpansions("gzbuqu").length > 0 && event.num > 0; }, - forced:true, - popup:false, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + forced: true, + popup: false, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - var cards=player.getExpansions('gzbuqu'),count=cards.length; - if(count>0&&(player.hp+count)>1){ - if(count==1) event._result={links:cards}; - else player.chooseCardButton('不屈:移去一张“创”',true,cards).set('ai',function(button){ - var buttons=get.selectableButtons(); - for(var i=0;i 0 && player.hp + count > 1) { + if (count == 1) event._result = { links: cards }; + else + player + .chooseCardButton("不屈:移去一张“创”", true, cards) + .set("ai", function (button) { + var buttons = get.selectableButtons(); + for (var i = 0; i < buttons.length; i++) { + if ( + buttons[i] != button && + get.number(buttons[i].link) == get.number(button.link) && + !ui.selected.buttons.includes(buttons[i]) + ) { + return 1; + } + } + return 0; + }); + } else event.finish(); + "step 2"; + var cards = result.links; player.loseToDiscardpile(cards); - if(event.count) event.goto(1); - 'step 3' - if(lib.skill.gzbuqu.process(player)){ - if(player.isDying()){ - var evt=event,histories=[evt]; - while(true){ - evt=event.getParent('dying'); - if(!evt||evt.name!='dying'||histories.includes(evt)) break; + if (event.count) event.goto(1); + "step 3"; + if (lib.skill.gzbuqu.process(player)) { + if (player.isDying()) { + var evt = event, + histories = [evt]; + while (true) { + evt = event.getParent("dying"); + if (!evt || evt.name != "dying" || histories.includes(evt)) break; histories.push(evt); - if(evt.player==player) evt.nodying=true; + if (evt.player == player) evt.nodying = true; } } } - } + }, + }, + }, + content: function () { + "step 0"; + var num = -trigger.num - Math.max(player.hp - trigger.num, 1) + 1; + player.addToExpansion(get.cards(num), "gain2").gaintag.add("gzbuqu"); + "step 1"; + player.showCards(get.translation(player) + "的不屈牌", player.getExpansions("gzbuqu")); + "step 2"; + if (lib.skill.gzbuqu.process(player)) { + var evt = trigger.getParent(); + if (evt.name == "damage" || evt.name == "loseHp") evt.nodying = true; } }, - content:function(){ - 'step 0' - var num=(-trigger.num-Math.max(player.hp-trigger.num,1)+1); - player.addToExpansion(get.cards(num),'gain2').gaintag.add('gzbuqu'); - 'step 1' - player.showCards(get.translation(player)+'的不屈牌',player.getExpansions('gzbuqu')); - 'step 2' - if(lib.skill.gzbuqu.process(player)){ - var evt=trigger.getParent(); - if(evt.name=='damage'||evt.name=='loseHp') evt.nodying=true; - } + ai: { + mingzhi: true, }, - ai:{ - mingzhi:true - } }, - buqu:{ - audio:2, - audioname:['key_yuri'], - trigger:{player:'chooseToUseBefore'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return event.type=='dying'&&player.isDying()&&event.dying==player&&!event.getParent()._buqu; + buqu: { + audio: 2, + audioname: ["key_yuri"], + trigger: { player: "chooseToUseBefore" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return ( + event.type == "dying" && + player.isDying() && + event.dying == player && + !event.getParent()._buqu + ); }, - content:function(){ - "step 0" - trigger.getParent()._buqu=true; - var card=get.cards()[0]; - event.card=card; - player.addToExpansion(card,'gain2').gaintag.add('buqu'); - "step 1" - var cards=player.getExpansions('buqu'),num=get.number(card); - player.showCards(cards,'不屈') - for(var i=0;i0; + } else if (event.type == "discard") { + if (!event.discarder) return false; + return game.hasPlayer(function (current) { + return current != event.discarder && event.getl(current).hs.length > 0; }); } return false; }, - content:function(){ - 'step 0' - var targets=[]; - if(trigger.name=='gain'){ - var cards=trigger.getg(trigger.player); - targets.addArray(game.filterPlayer(function(current){ - if(current==trigger.player) return false; - var hs=trigger.getl(current).hs; - for(var i of hs){ - if(cards.includes(i)) return true; - } - return false; - })); - } - else if(trigger.name=='loseAsync'&&trigger.type=='discard'){ - targets.addArray(game.filterPlayer(function(current){ - return current!=trigger.discarder&&trigger.getl(current).hs.length>0; - })); - } - else targets.push(trigger.player); - event.targets=targets.sortBySeat(); - if(!event.targets.length) event.finish(); - 'step 1' - var target=targets.shift(); - event.target=target; - if(target.isIn()) player.chooseBool(get.prompt('fenji',target),'失去1点体力,令该角色摸两张牌').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>4; - }); - else{ - if(targets.length>0) event.goto(1); + content: function () { + "step 0"; + var targets = []; + if (trigger.name == "gain") { + var cards = trigger.getg(trigger.player); + targets.addArray( + game.filterPlayer(function (current) { + if (current == trigger.player) return false; + var hs = trigger.getl(current).hs; + for (var i of hs) { + if (cards.includes(i)) return true; + } + return false; + }) + ); + } else if (trigger.name == "loseAsync" && trigger.type == "discard") { + targets.addArray( + game.filterPlayer(function (current) { + return current != trigger.discarder && trigger.getl(current).hs.length > 0; + }) + ); + } else targets.push(trigger.player); + event.targets = targets.sortBySeat(); + if (!event.targets.length) event.finish(); + "step 1"; + var target = targets.shift(); + event.target = target; + if (target.isIn()) + player + .chooseBool(get.prompt("fenji", target), "失去1点体力,令该角色摸两张牌") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 4; + }); + else { + if (targets.length > 0) event.goto(1); else event.finish(); } - 'step 2' - if(result.bool){ - player.logSkill('fenji',target); + "step 2"; + if (result.bool) { + player.logSkill("fenji", target); player.loseHp(); - } - else{ - if(targets.length>0) event.goto(1); + } else { + if (targets.length > 0) event.goto(1); else event.finish(); } - 'step 3' + "step 3"; target.draw(2); - if(targets.length>0) event.goto(1); + if (targets.length > 0) event.goto(1); }, }, - new_fenji:{ - audio:"fenji", - trigger:{ - global:"phaseJieshuBegin", + new_fenji: { + audio: "fenji", + trigger: { + global: "phaseJieshuBegin", }, - filter:function(event,player){ - if(event.player.countCards('h')==0&&event.player.isIn()) return true; + filter: function (event, player) { + if (event.player.countCards("h") == 0 && event.player.isIn()) return true; return false; }, - preHidden:true, - check:function(event,player){ - return get.attitude(player,event.player)>2; + preHidden: true, + check: function (event, player) { + return get.attitude(player, event.player) > 2; }, - content:function(){ - player.line(trigger.player,'green'); + content: function () { + player.line(trigger.player, "green"); trigger.player.draw(2); player.loseHp(); }, }, - leiji:{ - audio:2, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - return event.card.name=='shan'; + leiji: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + return event.card.name == "shan"; }, - direct:true, - preHidden:true, - content:function(){ + direct: true, + preHidden: true, + content: function () { "step 0"; - player.chooseTarget(get.prompt2('leiji')).setHiddenSkill(event.name).ai=function(target){ - if(target.hasSkill('hongyan')) return 0; - return get.damageEffect(target,_status.event.player,_status.event.player,'thunder'); + player.chooseTarget(get.prompt2("leiji")).setHiddenSkill(event.name).ai = function ( + target + ) { + if (target.hasSkill("hongyan")) return 0; + return get.damageEffect( + target, + _status.event.player, + _status.event.player, + "thunder" + ); }; - "step 1" - if(result.bool){ - player.logSkill('leiji',result.targets,'thunder'); - event.target=result.targets[0]; - event.target.judge(function(card){ - if(get.suit(card)=='spade') return -4; + "step 1"; + if (result.bool) { + player.logSkill("leiji", result.targets, "thunder"); + event.target = result.targets[0]; + event.target.judge(function (card) { + if (get.suit(card) == "spade") return -4; return 0; - }).judge2=function(result){ - return result.bool==false?true:false; + }).judge2 = function (result) { + return result.bool == false ? true : false; }; - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool==false){ - event.target.damage(2,'thunder'); + "step 2"; + if (result.bool == false) { + event.target.damage(2, "thunder"); } }, - ai:{ - mingzhi:false, - useShan:true, - effect:{ - target:function(card,player,target,current){ - 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(card.name==='sha'){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return; - } - else 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]; + ai: { + mingzhi: false, + useShan: true, + effect: { + target: function (card, player, target, current) { + 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 (card.name === "sha") { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return; + } else 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]; } - } - } - } - }, - guidao:{ - audio:2, - audioname:['sp_zhangjiao'], - trigger:{global:'judge'}, - filter:function(event,player){ - return player.countCards('hes',{color:'black'})>0; + }, + }, }, - direct:true, - content:function(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('guidao'),'hes',function(card){ - if(get.color(card)!='black') return false; - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result; - } - else{ - return -result; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','guidao','noOrdering'); - } - else{ + }, + guidao: { + audio: 2, + audioname: ["sp_zhangjiao"], + trigger: { global: "judge" }, + filter: function (event, player) { + return player.countCards("hes", { color: "black" }) > 0; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("guidao"), + "hes", + function (card) { + if (get.color(card) != "black") return false; + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result; + } else { + return -result; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "guidao", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); } - "step 3" + "step 3"; game.delay(2); }, - ai:{ - rejudge:true, - tag:{ - rejudge:1 - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, // 蛊惑(guhuo)技能错误,请勿引用 /* @@ -7365,804 +8536,1022 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, */ - huangtian:{ - unique:true, - audio:'huangtian2', - audioname:['zhangjiao','re_zhangjiao'], - global:'huangtian2', - zhuSkill:true, + huangtian: { + unique: true, + audio: "huangtian2", + audioname: ["zhangjiao", "re_zhangjiao"], + global: "huangtian2", + zhuSkill: true, }, - huangtian2:{ - audio:2, - enable:'phaseUse', - discard:false, - lose:false, - delay:false, - line:true, - prepare:function(cards,player,targets){ - targets[0].logSkill('huangtian'); + huangtian2: { + audio: 2, + enable: "phaseUse", + discard: false, + lose: false, + delay: false, + line: true, + prepare: function (cards, player, targets) { + targets[0].logSkill("huangtian"); }, - prompt:function(){ - var player=_status.event.player; - var list=game.filterPlayer(function(target){ - return target!=player&&target.hasZhuSkill('huangtian',player); + prompt: function () { + var player = _status.event.player; + var list = game.filterPlayer(function (target) { + return target != player && target.hasZhuSkill("huangtian", player); }); - var str='将一张【闪】或【闪电】交给'+get.translation(list); - if(list.length>1) str+='中的一人'; + var str = "将一张【闪】或【闪电】交给" + get.translation(list); + if (list.length > 1) str += "中的一人"; return str; }, - filter:function(event,player){ - if(player.group!='qun') return false; - if(player.countCards('h','shan')+player.countCards('h','shandian')==0) return 0; - return game.hasPlayer(function(target){ - return target!=player&&target.hasZhuSkill('huangtian',player)&&!target.hasSkill('huangtian3'); + filter: function (event, player) { + if (player.group != "qun") return false; + if (player.countCards("h", "shan") + player.countCards("h", "shandian") == 0) return 0; + return game.hasPlayer(function (target) { + return ( + target != player && + target.hasZhuSkill("huangtian", player) && + !target.hasSkill("huangtian3") + ); }); }, - filterCard:function(card){ - return (card.name=='shan'||card.name=='shandian') + filterCard: function (card) { + return card.name == "shan" || card.name == "shandian"; }, - log:false, - visible:true, - filterTarget:function(card,player,target){ - return target!=player&&target.hasZhuSkill('huangtian',player)&&!target.hasSkill('huangtian3'); + log: false, + visible: true, + filterTarget: function (card, player, target) { + return ( + target != player && + target.hasZhuSkill("huangtian", player) && + !target.hasSkill("huangtian3") + ); }, //usable:1, //forceaudio:true, - content:function(){ - player.give(cards,target); - target.addTempSkill('huangtian3','phaseUseEnd'); + content: function () { + player.give(cards, target); + target.addTempSkill("huangtian3", "phaseUseEnd"); + }, + ai: { + expose: 0.3, + order: 10, + result: { + target: 5, + }, }, - ai:{ - expose:0.3, - order:10, - result:{ - target:5 - } - } }, - huangtian3:{}, - xinfu_guhuo:{ - audio:'guhuo_guess', - derivation:['chanyuan'], - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - return (lib.inpile.includes(name)&&player.countCards('hs')>0&&!player.hasSkill('guhuo_phase')); + huangtian3: {}, + xinfu_guhuo: { + audio: "guhuo_guess", + derivation: ["chanyuan"], + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + return ( + lib.inpile.includes(name) && + player.countCards("hs") > 0 && + !player.hasSkill("guhuo_phase") + ); }, - filter:function(event,player){ - if(player.hasSkill('guhuo_phase')) return false; - if(!player.countCards('hs')) return false; - for(var i of lib.inpile){ - var type=get.type(i); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) return true; + filter: function (event, player) { + if (player.hasSkill("guhuo_phase")) return false; + if (!player.countCards("hs")) return false; + for (var i of lib.inpile) { + var type = get.type(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if ( + event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of lib.inpile){ - if(event.type!='phase') if(!event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) continue; - var type=get.type(i); - if(type=='basic'||type=='trick') list.push([type,'',i]); - if(i=='sha'){ - if(event.type!='phase') if(!event.filterCard(get.autoViewAs({name:i,nature:j},'unsure'),player,event)) continue; - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of lib.inpile) { + if (event.type != "phase") + if (!event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event)) + continue; + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); + if (i == "sha") { + if (event.type != "phase") + if ( + !event.filterCard( + get.autoViewAs({ name: i, nature: j }, "unsure"), + player, + event + ) + ) + continue; + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } - return ui.create.dialog('蛊惑',[list,'vcard']); + return ui.create.dialog("蛊惑", [list, "vcard"]); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard({name:button.link[2],nature:button.link[3]},player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard({ name: button.link[2], nature: button.link[3] }, player, evt); }, - check:function(button){ - var player=_status.event.player; - var enemyNum=game.countPlayer(function(current){ - return current!=player&&!current.hasSkill('chanyuan')&&(get.realAttitude||get.attitude)(current,player)<0; + check: function (button) { + var player = _status.event.player; + var enemyNum = game.countPlayer(function (current) { + return ( + current != player && + !current.hasSkill("chanyuan") && + (get.realAttitude || get.attitude)(current, player) < 0 + ); }); - var card={name:button.link[2],nature:button.link[3]}; - var val=_status.event.getParent().type=='phase'?player.getUseValue(card):1; - if(val<=0) return 0; - if(enemyNum){ - if(!player.hasCard(function(cardx){ - if(card.name==cardx.name){ - if(card.name!='sha') return true; - return get.is.sameNature(card,cardx); - } - return false; - },'hs')){ - if(get.value(card,player,'raw')<6) return Math.sqrt(val)*(0.25+Math.random()/1.5); - if(enemyNum<=2) return Math.sqrt(val)/1.5; + var card = { name: button.link[2], nature: button.link[3] }; + var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; + if (val <= 0) return 0; + if (enemyNum) { + if ( + !player.hasCard(function (cardx) { + if (card.name == cardx.name) { + if (card.name != "sha") return true; + return get.is.sameNature(card, cardx); + } + return false; + }, "hs") + ) { + if (get.value(card, player, "raw") < 6) + return Math.sqrt(val) * (0.25 + Math.random() / 1.5); + if (enemyNum <= 2) return Math.sqrt(val) / 1.5; return 0; } - return 3*val; + return 3 * val; } return val; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:function(card,player,target){ - var result=true; - var suit=card.suit,number=card.number; - card.suit='none';card.number=null; - var mod=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod!='unchanged') result=mod; - card.suit=suit;card.number=number; + filterCard: function (card, player, target) { + var result = true; + var suit = card.suit, + number = card.number; + card.suit = "none"; + card.number = null; + var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod != "unchanged") result = mod; + card.suit = suit; + card.number = number; return result; }, - selectCard:1, - position:'hs', - ignoreMod:true, - aiUse:Math.random(), - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null + selectCard: 1, + position: "hs", + ignoreMod: true, + aiUse: Math.random(), + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, }, - ai1:function(card){ - var player=_status.event.player; - var enemyNum=game.countPlayer(function(current){ - return current!=player&&!current.hasSkill('chanyuan')&&(get.realAttitude||get.attitude)(current,player)<0; + ai1: function (card) { + var player = _status.event.player; + var enemyNum = game.countPlayer(function (current) { + return ( + current != player && + !current.hasSkill("chanyuan") && + (get.realAttitude || get.attitude)(current, player) < 0 + ); }); - var cardx=lib.skill.xinfu_guhuo_backup.viewAs; - if(enemyNum){ - if(card.name==cardx.name&&(card.name!='sha'||get.is.sameNature(card,cardx))) return 2+Math.random()*3; - else if(lib.skill.xinfu_guhuo_backup.aiUse<0.5&&!player.isDying()) return 0; + var cardx = lib.skill.xinfu_guhuo_backup.viewAs; + if (enemyNum) { + if ( + card.name == cardx.name && + (card.name != "sha" || get.is.sameNature(card, cardx)) + ) + return 2 + Math.random() * 3; + else if (lib.skill.xinfu_guhuo_backup.aiUse < 0.5 && !player.isDying()) + return 0; } - return 6-get.value(card); + return 6 - get.value(card); }, - precontent:function(){ - player.logSkill('xinfu_guhuo'); - player.addTempSkill('guhuo_guess'); - var card=event.result.cards[0]; - event.result.card.suit=get.suit(card); - event.result.card.number=get.number(card); + precontent: function () { + player.logSkill("xinfu_guhuo"); + player.addTempSkill("guhuo_guess"); + var card = event.result.cards[0]; + event.result.card.suit = get.suit(card); + event.result.card.number = get.number(card); }, - } + }; }, - prompt:function(links,player){ - return '将一张手牌当做'+get.translation(links[0][2])+(_status.event.name=='chooseToRespond'?'打出':'使用'); + prompt: function (links, player) { + return ( + "将一张手牌当做" + + get.translation(links[0][2]) + + (_status.event.name == "chooseToRespond" ? "打出" : "使用") + ); }, }, - ai:{ - save:true, - respondSha:true, - respondShan:true, - fireAttack:true, - skillTagFilter:function(player){ - if(!player.countCards('hs')||player.hasSkill('guhuo_phase')) return false; + ai: { + save: true, + respondSha: true, + respondShan: true, + fireAttack: true, + skillTagFilter: function (player) { + if (!player.countCards("hs") || player.hasSkill("guhuo_phase")) return false; }, - threaten:1.2, - order:8.1, - result:{player:1}, + threaten: 1.2, + order: 8.1, + result: { player: 1 }, }, }, - guhuo_guess:{ - audio:2, - trigger:{ - player:['useCardBefore','respondBefore'], + guhuo_guess: { + audio: 2, + trigger: { + player: ["useCardBefore", "respondBefore"], }, - forced:true, - silent:true, - popup:false, - firstDo:true, - charlotte:true, - filter:function(event,player){ - return event.skill&&(event.skill.indexOf('guhuo_')==0||event.skill.indexOf('xinfu_guhuo_')==0); + forced: true, + silent: true, + popup: false, + firstDo: true, + charlotte: true, + filter: function (event, player) { + return ( + event.skill && + (event.skill.indexOf("guhuo_") == 0 || event.skill.indexOf("xinfu_guhuo_") == 0) + ); }, - content:function(){ - 'step 0' - player.addTempSkill('guhuo_phase'); - event.fake=false; - event.betrayer=null; - var card=trigger.cards[0]; - if(card.name!=trigger.card.name||(card.name=='sha'&&!get.is.sameNature(trigger.card,card))) event.fake=true; - player.popup(trigger.card.name,'metal'); - player.lose(card,ui.ordering).relatedEvent=trigger; + content: function () { + "step 0"; + player.addTempSkill("guhuo_phase"); + event.fake = false; + event.betrayer = null; + var card = trigger.cards[0]; + if ( + card.name != trigger.card.name || + (card.name == "sha" && !get.is.sameNature(trigger.card, card)) + ) + event.fake = true; + player.popup(trigger.card.name, "metal"); + player.lose(card, ui.ordering).relatedEvent = trigger; // player.line(trigger.targets,trigger.card.nature); - trigger.throw=false; - trigger.skill='xinfu_guhuo_backup'; - game.log(player,'声明',trigger.targets&&trigger.targets.length?'对':'',trigger.targets||'',trigger.name=='useCard'?'使用':'打出',trigger.card); - event.prompt=get.translation(player)+'声明'+(trigger.targets&&trigger.targets.length?'对'+get.translation(trigger.targets):'')+ - (trigger.name=='useCard'?'使用':'打出')+(get.translation(trigger.card.nature)||'')+get.translation(trigger.card.name)+',是否质疑?'; - event.targets=game.filterPlayer(function(current){ - return current!=player&&!current.hasSkill('chanyuan'); - }).sortBySeat(_status.currentPhase); + trigger.throw = false; + trigger.skill = "xinfu_guhuo_backup"; + game.log( + player, + "声明", + trigger.targets && trigger.targets.length ? "对" : "", + trigger.targets || "", + trigger.name == "useCard" ? "使用" : "打出", + trigger.card + ); + event.prompt = + get.translation(player) + + "声明" + + (trigger.targets && trigger.targets.length + ? "对" + get.translation(trigger.targets) + : "") + + (trigger.name == "useCard" ? "使用" : "打出") + + (get.translation(trigger.card.nature) || "") + + get.translation(trigger.card.name) + + ",是否质疑?"; + event.targets = game + .filterPlayer(function (current) { + return current != player && !current.hasSkill("chanyuan"); + }) + .sortBySeat(_status.currentPhase); - game.broadcastAll(function(card,player){ - _status.guhuoNode=card.copy('thrown'); - if(lib.config.cardback_style!='default'){ - _status.guhuoNode.style.transitionProperty='none'; - ui.refresh(_status.guhuoNode); - _status.guhuoNode.classList.add('infohidden'); - ui.refresh(_status.guhuoNode); - _status.guhuoNode.style.transitionProperty=''; - } - else{ - _status.guhuoNode.classList.add('infohidden'); - } - _status.guhuoNode.style.transform='perspective(600px) rotateY(180deg) translateX(0)'; - player.$throwordered2(_status.guhuoNode); - },trigger.cards[0],player); - event.onEnd01=function(){ - _status.guhuoNode.removeEventListener('webkitTransitionEnd',_status.event.onEnd01); - setTimeout(function(){ - _status.guhuoNode.style.transition='all ease-in 0.3s'; - _status.guhuoNode.style.transform='perspective(600px) rotateY(270deg)'; - var onEnd=function(){ - _status.guhuoNode.classList.remove('infohidden'); - _status.guhuoNode.style.transition='all 0s'; + game.broadcastAll( + function (card, player) { + _status.guhuoNode = card.copy("thrown"); + if (lib.config.cardback_style != "default") { + _status.guhuoNode.style.transitionProperty = "none"; ui.refresh(_status.guhuoNode); - _status.guhuoNode.style.transform='perspective(600px) rotateY(-90deg)'; + _status.guhuoNode.classList.add("infohidden"); ui.refresh(_status.guhuoNode); - _status.guhuoNode.style.transition=''; - ui.refresh(_status.guhuoNode); - _status.guhuoNode.style.transform=''; - _status.guhuoNode.removeEventListener('webkitTransitionEnd',onEnd); + _status.guhuoNode.style.transitionProperty = ""; + } else { + _status.guhuoNode.classList.add("infohidden"); } + _status.guhuoNode.style.transform = + "perspective(600px) rotateY(180deg) translateX(0)"; + player.$throwordered2(_status.guhuoNode); + }, + trigger.cards[0], + player + ); + event.onEnd01 = function () { + _status.guhuoNode.removeEventListener("webkitTransitionEnd", _status.event.onEnd01); + setTimeout(function () { + _status.guhuoNode.style.transition = "all ease-in 0.3s"; + _status.guhuoNode.style.transform = "perspective(600px) rotateY(270deg)"; + var onEnd = function () { + _status.guhuoNode.classList.remove("infohidden"); + _status.guhuoNode.style.transition = "all 0s"; + ui.refresh(_status.guhuoNode); + _status.guhuoNode.style.transform = "perspective(600px) rotateY(-90deg)"; + ui.refresh(_status.guhuoNode); + _status.guhuoNode.style.transition = ""; + ui.refresh(_status.guhuoNode); + _status.guhuoNode.style.transform = ""; + _status.guhuoNode.removeEventListener("webkitTransitionEnd", onEnd); + }; _status.guhuoNode.listenTransition(onEnd); - },300); + }, 300); }; - if(!event.targets.length) event.goto(3); - 'step 1' - event.target=event.targets.shift(); - event.target.chooseButton([event.prompt,[['reguhuo_ally','reguhuo_betray'],'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - var evt=_status.event.getParent('guhuo_guess'),evtx=evt.getTrigger(); - if(!evt) return Math.random(); - var card={name:evtx.card.name,nature:evtx.card.nature,isCard:true}; - var ally=button.link[2]=='reguhuo_ally'; - if(ally&&(player.hp<=1||get.attitude(player,evt.player)>=0)) return 1.1; - if(!ally&&get.attitude(player,evt.player)<0&&evtx.name=='useCard'){ - var eff=0; - var targetsx=evtx.targets||[]; - for(var target of targetsx){ - var isMe=target==evt.player; - eff+=get.effect(target,card,evt.player,player)/(isMe?1.5:1); + if (!event.targets.length) event.goto(3); + "step 1"; + event.target = event.targets.shift(); + event.target + .chooseButton([event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], true) + .set("ai", function (button) { + var player = _status.event.player; + var evt = _status.event.getParent("guhuo_guess"), + evtx = evt.getTrigger(); + if (!evt) return Math.random(); + var card = { name: evtx.card.name, nature: evtx.card.nature, isCard: true }; + var ally = button.link[2] == "reguhuo_ally"; + if (ally && (player.hp <= 1 || get.attitude(player, evt.player) >= 0)) return 1.1; + if (!ally && get.attitude(player, evt.player) < 0 && evtx.name == "useCard") { + var eff = 0; + var targetsx = evtx.targets || []; + for (var target of targetsx) { + var isMe = target == evt.player; + eff += get.effect(target, card, evt.player, player) / (isMe ? 1.5 : 1); + } + eff /= 1.5 * targetsx.length || 1; + if (eff > 0) return 0; + if (eff < -7) return Math.random() + Math.pow(-(eff + 7) / 8, 2); + return Math.pow( + (get.value(card, evt.player, "raw") - 4) / (eff == 0 ? 5 : 10), + 2 + ); } - eff/=(1.5*targetsx.length)||1; - if(eff>0) return 0; - if(eff<-7) return Math.random()+Math.pow(-(eff+7)/8,2); - return Math.pow((get.value(card,evt.player,'raw')-4)/(eff==0?5:10),2); - } - return Math.random(); - }); - 'step 2' - if(result.links[0][2]=='reguhuo_betray'){ + return Math.random(); + }); + "step 2"; + if (result.links[0][2] == "reguhuo_betray") { target.addExpose(0.2); - game.log(target,'#y质疑'); - target.popup('质疑!','fire'); - event.betrayer=target; + game.log(target, "#y质疑"); + target.popup("质疑!", "fire"); + event.betrayer = target; + } else { + game.log(target, "#g不质疑"); + target.popup("不质疑", "wood"); + if (targets.length) event.goto(1); } - else{ - game.log(target,'#g不质疑'); - target.popup('不质疑','wood'); - if(targets.length) event.goto(1); - } - 'step 3' + "step 3"; game.delayx(); - game.broadcastAll(function(onEnd){ - _status.event.onEnd01=onEnd; - if(_status.guhuoNode) _status.guhuoNode.listenTransition(onEnd,300); - },event.onEnd01); - 'step 4' + game.broadcastAll(function (onEnd) { + _status.event.onEnd01 = onEnd; + if (_status.guhuoNode) _status.guhuoNode.listenTransition(onEnd, 300); + }, event.onEnd01); + "step 4"; game.delay(2); - 'step 5' - if(!event.betrayer) event.finish(); - 'step 6' - if(event.fake){ - event.betrayer.popup('质疑正确','wood'); - game.log(player,'声明的',trigger.card,'作废了'); + "step 5"; + if (!event.betrayer) event.finish(); + "step 6"; + if (event.fake) { + event.betrayer.popup("质疑正确", "wood"); + game.log(player, "声明的", trigger.card, "作废了"); trigger.cancel(); trigger.getParent().goto(0); - trigger.line=false; + trigger.line = false; + } else { + event.betrayer.popup("质疑错误", "fire"); + event.betrayer.addSkills("chanyuan"); } - else{ - event.betrayer.popup('质疑错误','fire'); - event.betrayer.addSkills('chanyuan'); - } - 'step 7' + "step 7"; game.delay(2); - 'step 8' - if(event.fake) game.broadcastAll(ui.clear); + "step 8"; + if (event.fake) game.broadcastAll(ui.clear); }, }, - chanyuan:{ - init:function(player,skill){ - if(player.hp==1) player.logSkill(skill); + chanyuan: { + init: function (player, skill) { + if (player.hp == 1) player.logSkill(skill); player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); }, - skillBlocker:function(skill,player){ - return skill!='chanyuan'&&skill!='rechanyuan'&&!lib.skill[skill].charlotte&&player.hp==1; + skillBlocker: function (skill, player) { + return ( + skill != "chanyuan" && + skill != "rechanyuan" && + !lib.skill[skill].charlotte && + player.hp == 1 + ); }, - mark:true, - intro:{ - content:function(storage,player,skill){ - var str='
            • 锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。'; - var list=player.getSkills(null,false,false).filter(function(i){ - return lib.skill.rechanyuan.skillBlocker(i,player); + mark: true, + intro: { + content: function (storage, player, skill) { + var str = + "
            • 锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。"; + var list = player.getSkills(null, false, false).filter(function (i) { + return lib.skill.rechanyuan.skillBlocker(i, player); }); - if(list.length) str+=('
            • 失效技能:'+get.translation(list)) + if (list.length) str += "
            • 失效技能:" + get.translation(list); return str; }, }, - audio:2, - trigger:{player:'changeHp'}, - filter:function(event,player){ - return player.hp==1; + audio: 2, + trigger: { player: "changeHp" }, + filter: function (event, player) { + return player.hp == 1; }, - forced:true, - content:function(){}, + forced: true, + content: function () {}, }, - guhuo_phase:{}, + guhuo_phase: {}, }, - card:{}, - dynamicTranslate:{ - nzry_juzhan:function(player){ - if(player.storage.nzry_juzhan==true) return '转换技,阴:当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。阳:当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌。'; + card: {}, + dynamicTranslate: { + nzry_juzhan: function (player) { + if (player.storage.nzry_juzhan == true) + return '转换技,阴:当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。阳:当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌。'; return '转换技,阴:当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。阳:当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌。'; }, - nzry_zhenliang:function(player){ - if(player.storage.nzry_zhenliang==true) return '转换技,阴:出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。阳:当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。'; + nzry_zhenliang: function (player) { + if (player.storage.nzry_zhenliang == true) + return '转换技,阴:出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。阳:当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。'; return '转换技,阴:出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。阳:当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。'; }, - nzry_chenglve:function(player){ - if(player.storage.nzry_chenglve==true) return '转换技,出牌阶段限一次,阴:你可以摸一张牌,然后弃置两张手牌。阳:你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制。'; + nzry_chenglve: function (player) { + if (player.storage.nzry_chenglve == true) + return '转换技,出牌阶段限一次,阴:你可以摸一张牌,然后弃置两张手牌。阳:你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制。'; return '转换技,出牌阶段限一次,阴:你可以摸一张牌,然后弃置两张手牌。阳:你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制。'; }, - nzry_shenshi:function(player){ - if(player.storage.nzry_shenshi==true) return '转换技,阴:出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张。阳:其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张。'; + nzry_shenshi: function (player) { + if (player.storage.nzry_shenshi == true) + return '转换技,阴:出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张。阳:其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张。'; return '转换技,阴:出牌阶段限一次,你可以将一张牌交给一名手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张。阳:其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张。'; }, }, - characterReplace:{ - caoren:['caoren','old_caoren','sb_caoren','new_caoren','star_caoren'], - sp_caoren:['sp_caoren','jsp_caoren'], - xiahouyuan:['re_xiahouyuan','ol_xiahouyuan','xiahouyuan'], - huangzhong:['re_huangzhong','ol_huangzhong','sb_huangzhong','huangzhong','jsrg_huangzhong'], - weiyan:['re_weiyan','ol_weiyan','weiyan'], - zhoutai:['zhoutai','xin_zhoutai','old_zhoutai'], - xiaoqiao:['xiaoqiao','ol_xiaoqiao','re_xiaoqiao','sb_xiaoqiao','old_xiaoqiao'], - yuji:['xin_yuji','re_yuji','yuji'], - zhangjiao:['sp_zhangjiao','re_zhangjiao','sb_zhangjiao','zhangjiao'], - dianwei:['dianwei','ol_dianwei','re_dianwei'], - xunyu:['xunyu','ol_xunyu','re_xunyu','sb_xunyu'], - sp_zhugeliang:['sp_zhugeliang','ol_sp_zhugeliang','re_sp_zhugeliang','sb_sp_zhugeliang'], - pangtong:['pangtong','ol_pangtong','re_pangtong','sb_pangtong'], - re_jsp_pangtong:['re_jsp_pangtong','jsrg_pangtong','sp_pangtong'], - taishici:['taishici','re_taishici','ol_sb_taishici'], - re_yuanshao:['re_yuanshao','ol_yuanshao','xin_yuanshao','ol_sb_yuanshao','star_yuanshao','sb_yuanshao'], - pangde:['re_pangde','ol_pangde','pangde'], - yanwen:['yanwen','ol_yanwen','re_yanwen'], - caopi:['caopi','re_caopi','ps_caopi','sb_caopi'], - xuhuang:['re_xuhuang','ol_xuhuang','sb_xuhuang','xuhuang'], - menghuo:['menghuo','re_menghuo','sb_menghuo','tw_menghuo'], - zhurong:['zhurong','ol_zhurong','re_zhurong','sb_zhurong'], - sunjian:['sunjian','ol_sunjian','re_sunjian','tw_ol_sunjian'], - jiaxu:['jiaxu','re_jiaxu','ns_jiaxu','ps_jiaxu'], - dongzhuo:['dongzhuo','ol_dongzhuo','re_dongzhuo','star_dongzhuo','sp_dongzhuo','yj_dongzhuo'], - dengai:['dengai','ol_dengai','re_dengai'], - sp_ol_zhanghe:['sp_ol_zhanghe','yj_zhanghe','sp_zhanghe','jsrg_zhanghe'], - jiangwei:['jiangwei','ol_jiangwei','re_jiangwei','ol_sb_jiangwei','sb_jiangwei','jsrg_jiangwei'], - liushan:['liushan','ol_liushan','re_liushan'], - sunce:['sunce','re_sunce','re_sunben','sb_sunce','dc_sunce'], - zhangzhang:['zhangzhang','ol_zhangzhang','re_zhangzhang'], - zuoci:['zuoci','re_zuoci'], - caiwenji:['caiwenji','ol_caiwenji','re_caiwenji'], - xuyou:['xuyou','sp_xuyou','jsrg_xuyou','yj_xuyou','junk_xuyou'], - guanqiujian:['guanqiujian','re_guanqiujian','tw_guanqiujian','mb_sp_guanqiujian','old_guanqiujian'], - chendao:['chendao','ns_chendao','old_chendao'], - zhugezhan:['zhugezhan','old_zhugezhan'], - ol_lusu:['re_lusu','ol_lusu','dc_sb_lusu'], - zhanghe:['zhanghe','re_zhanghe','sb_zhanghe'], - yl_luzhi:['yl_luzhi','sb_yl_luzhi','tw_yl_luzhi'], - sunliang:['sunliang','xin_sunliang'], + characterReplace: { + caoren: ["caoren", "old_caoren", "sb_caoren", "new_caoren", "star_caoren"], + sp_caoren: ["sp_caoren", "jsp_caoren"], + xiahouyuan: ["re_xiahouyuan", "ol_xiahouyuan", "xiahouyuan"], + huangzhong: ["re_huangzhong", "ol_huangzhong", "sb_huangzhong", "huangzhong", "jsrg_huangzhong"], + weiyan: ["re_weiyan", "ol_weiyan", "weiyan"], + zhoutai: ["zhoutai", "xin_zhoutai", "old_zhoutai"], + xiaoqiao: ["xiaoqiao", "ol_xiaoqiao", "re_xiaoqiao", "sb_xiaoqiao", "old_xiaoqiao"], + yuji: ["xin_yuji", "re_yuji", "yuji"], + zhangjiao: ["sp_zhangjiao", "re_zhangjiao", "sb_zhangjiao", "zhangjiao"], + dianwei: ["dianwei", "ol_dianwei", "re_dianwei"], + xunyu: ["xunyu", "ol_xunyu", "re_xunyu", "sb_xunyu"], + sp_zhugeliang: ["sp_zhugeliang", "ol_sp_zhugeliang", "re_sp_zhugeliang", "sb_sp_zhugeliang"], + pangtong: ["pangtong", "ol_pangtong", "re_pangtong", "sb_pangtong"], + re_jsp_pangtong: ["re_jsp_pangtong", "jsrg_pangtong", "sp_pangtong"], + taishici: ["taishici", "re_taishici", "ol_sb_taishici"], + re_yuanshao: [ + "re_yuanshao", + "ol_yuanshao", + "xin_yuanshao", + "ol_sb_yuanshao", + "star_yuanshao", + "sb_yuanshao", + ], + pangde: ["re_pangde", "ol_pangde", "pangde"], + yanwen: ["yanwen", "ol_yanwen", "re_yanwen"], + caopi: ["caopi", "re_caopi", "ps_caopi", "sb_caopi"], + xuhuang: ["re_xuhuang", "ol_xuhuang", "sb_xuhuang", "xuhuang"], + menghuo: ["menghuo", "re_menghuo", "sb_menghuo", "tw_menghuo"], + zhurong: ["zhurong", "ol_zhurong", "re_zhurong", "sb_zhurong"], + sunjian: ["sunjian", "ol_sunjian", "re_sunjian", "tw_ol_sunjian"], + jiaxu: ["jiaxu", "re_jiaxu", "ns_jiaxu", "ps_jiaxu"], + dongzhuo: [ + "dongzhuo", + "ol_dongzhuo", + "re_dongzhuo", + "star_dongzhuo", + "sp_dongzhuo", + "yj_dongzhuo", + ], + dengai: ["dengai", "ol_dengai", "re_dengai"], + sp_ol_zhanghe: ["sp_ol_zhanghe", "yj_zhanghe", "sp_zhanghe", "jsrg_zhanghe"], + jiangwei: [ + "jiangwei", + "ol_jiangwei", + "re_jiangwei", + "ol_sb_jiangwei", + "sb_jiangwei", + "jsrg_jiangwei", + ], + liushan: ["liushan", "ol_liushan", "re_liushan"], + sunce: ["sunce", "re_sunce", "re_sunben", "sb_sunce", "dc_sunce"], + zhangzhang: ["zhangzhang", "ol_zhangzhang", "re_zhangzhang"], + zuoci: ["zuoci", "re_zuoci"], + caiwenji: ["caiwenji", "ol_caiwenji", "re_caiwenji"], + xuyou: ["xuyou", "sp_xuyou", "jsrg_xuyou", "yj_xuyou", "junk_xuyou"], + guanqiujian: [ + "guanqiujian", + "re_guanqiujian", + "tw_guanqiujian", + "mb_sp_guanqiujian", + "old_guanqiujian", + ], + chendao: ["chendao", "ns_chendao", "old_chendao"], + zhugezhan: ["zhugezhan", "old_zhugezhan"], + ol_lusu: ["re_lusu", "ol_lusu", "dc_sb_lusu"], + zhanghe: ["zhanghe", "re_zhanghe", "sb_zhanghe"], + yl_luzhi: ["yl_luzhi", "sb_yl_luzhi", "tw_yl_luzhi"], + sunliang: ["sunliang", "xin_sunliang"], }, - translate:{ - re_yuanshao:'袁绍', - re_lusu:'鲁肃', - re_yuji:"于吉", - wangji:'王基', - "kuailiangkuaiyue":"蒯良蒯越", - "sunliang":"孙亮", - "yl_luzhi":"卢植", - "xuyou":"许攸", - "luji":"陆绩", - "wangping":"王平", - "yanyan":"严颜", + translate: { + re_yuanshao: "袁绍", + re_lusu: "鲁肃", + re_yuji: "于吉", + wangji: "王基", + kuailiangkuaiyue: "蒯良蒯越", + sunliang: "孙亮", + yl_luzhi: "卢植", + xuyou: "许攸", + luji: "陆绩", + wangping: "王平", + yanyan: "严颜", - "zhugezhan":"诸葛瞻", - "lukang":"陆抗", - "haozhao":"郝昭", - yl_yuanshu:"新杀袁术", - yl_yuanshu_prefix:"新杀", - "zhangxiu":"张绣", - "chendao":"陈到", - "guanqiujian":"毌丘俭", - zhoufei:"周妃", + zhugezhan: "诸葛瞻", + lukang: "陆抗", + haozhao: "郝昭", + yl_yuanshu: "新杀袁术", + yl_yuanshu_prefix: "新杀", + zhangxiu: "张绣", + chendao: "陈到", + guanqiujian: "毌丘俭", + zhoufei: "周妃", - "nzry_jianxiang":"荐降", - "nzry_jianxiang_info":"当你成为其他角色使用牌的目标时,你可令手牌数最少的一名角色摸一张牌。", - "nzry_shenshi1":"审时", - "nzry_shenshi":"审时", - "nzry_shenshi_info":"转换技,阴:出牌阶段限一次,你可以将一张牌交给一名除你外手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张。阳:其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张。", - "nzry_mingren":"明任", - "nzry_mingren_info":"游戏开始时,你摸两张牌,然后将一张手牌置于你的武将牌上,称为“任”。结束阶段,你可以用一张手牌替换“任”。", - "nzry_zhenliang":"贞良", - "nzry_zhenliang_info":"转换技,阴:出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。阳:当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。", - "nzry_chenglve1":"成略", - "nzry_chenglve":"成略", - "nzry_chenglve_info":"转换技,出牌阶段限一次,阴:你可以摸一张牌,然后弃置两张手牌。阳:你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制。", - "nzry_cunmu":"寸目", - "nzry_cunmu_info":"锁定技,当你摸牌时,改为从牌堆底摸牌。", - "nzry_kuizhu":"溃诛", - "nzry_kuizhu_info":"弃牌阶段结束后,你可以选择一项:①令至多X名角色各摸一张牌。②对任意名体力值之和为X的角色造成1点伤害。(X为你此阶段弃置的牌数)", - "nzry_zhizheng":"掣政", - rechezheng:'掣政', - "nzry_zhizheng_info":"锁定技,你的出牌阶段内,当你对攻击范围内不包含你的其他角色造成伤害时,防止此伤害。出牌阶段结束时,若你本阶段内使用的牌数小于这些角色的数量,则你弃置其中一名角色的一张牌。", - "nzry_lijun1":"立军", - "nzry_lijun":"立军", - "nzry_lijun_info":"主公技,其他吴势力角色的出牌阶段限一次,其使用【杀】结算后,可以将此【杀】对应的实体牌交给你,然后你可以令其摸一张牌且本阶段内使用【杀】的次数上限+1。", - "nzry_huaiju":"怀橘", - "nzry_huaiju_info":"锁定技,游戏开始时,你获得3个“橘”标记。(有“橘”的角色受到伤害时,防止此伤害,然后移去一个“橘”;有“橘”的角色摸牌阶段额外摸一张牌)", - "tachibana_effect":"怀橘", - "nzry_yili":"遗礼", - "nzry_yili_info":"出牌阶段开始时,你可以失去1点体力或移去一个“橘”,然后令一名其他角色获得一个“橘”。", - "nzry_zhenglun":"整论", - "nzry_zhenglun_info":"若你没有“橘”,你可以跳过摸牌阶段然后获得一个“橘”。", - "nzry_feijun":"飞军", - "nzry_feijun_info":"出牌阶段限一次。你可以弃置一张牌,然后选择一项:⒈令一名手牌数大于你的角色交给你一张牌;⒉令一名装备区里牌数大于你的角色弃置一张装备牌。", - "nzry_binglve":"兵略", - "nzry_binglve_info":"锁定技,当你发动“飞军”时,若目标与你之前指定的目标均不相同,则你摸两张牌。", - "nzry_juzhan1":"拒战", - "nzry_juzhan":"拒战", - "nzry_juzhan_info":"转换技,阴:当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。阳:当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌。", + nzry_jianxiang: "荐降", + nzry_jianxiang_info: "当你成为其他角色使用牌的目标时,你可令手牌数最少的一名角色摸一张牌。", + nzry_shenshi1: "审时", + nzry_shenshi: "审时", + nzry_shenshi_info: + "转换技,阴:出牌阶段限一次,你可以将一张牌交给一名除你外手牌数最多的角色,然后对其造成1点伤害,若该角色因此死亡,则你可以令一名角色将手牌摸至四张。阳:其他角色对你造成伤害后,你可以观看该角色的手牌,然后交给其一张牌,当前角色回合结束时,若此牌仍在该角色的区域内,你将手牌摸至四张。", + nzry_mingren: "明任", + nzry_mingren_info: + "游戏开始时,你摸两张牌,然后将一张手牌置于你的武将牌上,称为“任”。结束阶段,你可以用一张手牌替换“任”。", + nzry_zhenliang: "贞良", + nzry_zhenliang_info: + "转换技,阴:出牌阶段限一次,你可以弃置一张与“任”颜色相同的牌并对攻击范围内的一名角色造成1点伤害。阳:当你于回合外使用或打出的牌结算完成后,若此牌与“任”颜色相同,则你可以令一名角色摸一张牌。", + nzry_chenglve1: "成略", + nzry_chenglve: "成略", + nzry_chenglve_info: + "转换技,出牌阶段限一次,阴:你可以摸一张牌,然后弃置两张手牌。阳:你可以摸两张牌,然后弃置一张手牌。若如此做,直到本回合结束,你使用与弃置牌花色相同的牌无距离和次数限制。", + nzry_cunmu: "寸目", + nzry_cunmu_info: "锁定技,当你摸牌时,改为从牌堆底摸牌。", + nzry_kuizhu: "溃诛", + nzry_kuizhu_info: + "弃牌阶段结束后,你可以选择一项:①令至多X名角色各摸一张牌。②对任意名体力值之和为X的角色造成1点伤害。(X为你此阶段弃置的牌数)", + nzry_zhizheng: "掣政", + rechezheng: "掣政", + nzry_zhizheng_info: + "锁定技,你的出牌阶段内,当你对攻击范围内不包含你的其他角色造成伤害时,防止此伤害。出牌阶段结束时,若你本阶段内使用的牌数小于这些角色的数量,则你弃置其中一名角色的一张牌。", + nzry_lijun1: "立军", + nzry_lijun: "立军", + nzry_lijun_info: + "主公技,其他吴势力角色的出牌阶段限一次,其使用【杀】结算后,可以将此【杀】对应的实体牌交给你,然后你可以令其摸一张牌且本阶段内使用【杀】的次数上限+1。", + nzry_huaiju: "怀橘", + nzry_huaiju_info: + "锁定技,游戏开始时,你获得3个“橘”标记。(有“橘”的角色受到伤害时,防止此伤害,然后移去一个“橘”;有“橘”的角色摸牌阶段额外摸一张牌)", + tachibana_effect: "怀橘", + nzry_yili: "遗礼", + nzry_yili_info: + "出牌阶段开始时,你可以失去1点体力或移去一个“橘”,然后令一名其他角色获得一个“橘”。", + nzry_zhenglun: "整论", + nzry_zhenglun_info: "若你没有“橘”,你可以跳过摸牌阶段然后获得一个“橘”。", + nzry_feijun: "飞军", + nzry_feijun_info: + "出牌阶段限一次。你可以弃置一张牌,然后选择一项:⒈令一名手牌数大于你的角色交给你一张牌;⒉令一名装备区里牌数大于你的角色弃置一张装备牌。", + nzry_binglve: "兵略", + nzry_binglve_info: "锁定技,当你发动“飞军”时,若目标与你之前指定的目标均不相同,则你摸两张牌。", + nzry_juzhan1: "拒战", + nzry_juzhan: "拒战", + nzry_juzhan_info: + "转换技,阴:当你成为其他角色【杀】的目标后,你可以与其各摸一张牌,然后其本回合内不能再对你使用牌。阳:当你使用【杀】指定一名角色为目标后,你可以获得其一张牌,然后你本回合内不能再对其使用牌。", - liangyin:"良姻", - "liangyin_info":"当有牌移至游戏外时,你可以令手牌数大于你的一名角色摸一张牌;当有牌从游戏外加入任意角色的手牌时,你可以令手牌数小于你的一名角色弃置一张牌。", - kongsheng:"箜声", - "kongsheng_info":"准备阶段,你可以将任意张牌置于你的武将牌上;结束阶段,你使用武将牌上的装备牌,并获得武将牌上的其他牌。", - "kongsheng2":"箜声", - "kongsheng2_info":"", - "xinfu_zuilun":"罪论", - "xinfu_zuilun_info":"结束阶段,你可以观看牌堆顶三张牌,你每满足以下一项便保留一张,然后以任意顺序放回其余的牌:1.你于此回合内造成过伤害;2.你于此回合内未弃置过牌;3.手牌数为全场最少。若均不满足,你与一名其他角色失去1点体力。", - "xinfu_fuyin":"父荫", - "xinfu_fuyin_info":"锁定技,你每回合第一次成为【杀】或【决斗】的目标后,若你的手牌数小于等于该角色,此牌对你无效。", - drlt_wanglie:"往烈", - drlt_wanglie_info:"①出牌阶段,你使用的第一张牌无距离限制。②当你于出牌阶段内使用牌时,你可以令此牌不能被响应,然后你于本阶段内不能再使用牌。", - "drlt_xiongluan":"雄乱", - drlt_xiongluan1:'雄乱', - "drlt_xiongluan_info":"限定技,出牌阶段,你可以废除你的判定区和装备区,然后指定一名其他角色。直到回合结束,你对其使用牌无距离和次数限制,其不能使用和打出手牌。", - "drlt_congjian":"从谏", - "drlt_congjian_info":"当你成为锦囊牌的目标时,若此牌的目标数大于1,则你可以交给其中一名其他目标角色一张牌,然后摸一张牌,若你给出的是装备牌,改为摸两张牌。", - "drlt_yongsi":"庸肆", - "drlt_yongsi_info":"锁定技,摸牌阶段,你改为摸X张牌(X为存活势力数);出牌阶段结束时,若你本回合:1.没有造成伤害,将手牌摸至当前体力值;2.造成的伤害超过1点,本回合手牌上限改为已损失体力值。", - "drlt_weidi":"伪帝", - weidi_tag:'伪帝', - "drlt_weidi_info":"主公技,弃牌阶段开始时,若你的手牌数大于手牌上限,则你可以将至多X张手牌分别交给等量的其他群雄角色(X为你的手牌数与手牌上限之差)。", - "drlt_qianjie":"谦节", - "drlt_qianjie_info":"锁定技,当你横置时,取消之。你不能成为延时类锦囊的目标。你不能成为其他角色拼点的目标。", - "drlt_jueyan":"决堰", - "drlt_jueyan_info":"出牌阶段限一次,你可以废除一种装备栏,然后执行对应一项:武器栏,你本回合内使用【杀】的次数上限+3;防具栏,你摸三张牌,且本回合手牌上限+3;坐骑栏,你本回合内使用牌无距离限制;宝物栏,你获得〖集智〗直到回合结束。", - "drlt_poshi":"破势", - "drlt_poshi_info":"觉醒技,准备阶段开始时,若你的装备栏均已被废除或体力值为1,则你减1点体力上限,将手牌摸至体力上限,失去〖决堰〗并获得〖怀柔〗。", - "drlt_huairou":"怀柔", - "drlt_huairou_info":"出牌阶段,你可以重铸装备牌。", - "drlt_zhenggu":"镇骨", - drlt_zhenggu2:"镇骨", - "drlt_zhenggu_info":"结束阶段,你可以选择一名其他角色,你的回合结束后和该角色的下个回合结束时,其将手牌摸至或弃至X张。(X为你的手牌数且至多为5)", - "drlt_zhenrong":"征荣", - "drlt_zhenrong_info":"当你对其他角色造成伤害后,若其手牌比你多,你可以将其一张牌置于你的武将牌上,称为“荣”。", - "drlt_hongju":"鸿举", - "drlt_hongju_info":"觉醒技,准备阶段,若“荣”的数量大于或等于3且场上有角色死亡,则你可以用任意张手牌替换等量的“荣”,然后减1点体力上限并获得〖清侧〗。", - "drlt_qingce":"清侧", - "drlt_qingce_info":"出牌阶段,你可以移去一张“荣”,然后弃置一名角色装备区或判定区内的一张牌。", + liangyin: "良姻", + liangyin_info: + "当有牌移至游戏外时,你可以令手牌数大于你的一名角色摸一张牌;当有牌从游戏外加入任意角色的手牌时,你可以令手牌数小于你的一名角色弃置一张牌。", + kongsheng: "箜声", + kongsheng_info: + "准备阶段,你可以将任意张牌置于你的武将牌上;结束阶段,你使用武将牌上的装备牌,并获得武将牌上的其他牌。", + kongsheng2: "箜声", + kongsheng2_info: "", + xinfu_zuilun: "罪论", + xinfu_zuilun_info: + "结束阶段,你可以观看牌堆顶三张牌,你每满足以下一项便保留一张,然后以任意顺序放回其余的牌:1.你于此回合内造成过伤害;2.你于此回合内未弃置过牌;3.手牌数为全场最少。若均不满足,你与一名其他角色失去1点体力。", + xinfu_fuyin: "父荫", + xinfu_fuyin_info: + "锁定技,你每回合第一次成为【杀】或【决斗】的目标后,若你的手牌数小于等于该角色,此牌对你无效。", + drlt_wanglie: "往烈", + drlt_wanglie_info: + "①出牌阶段,你使用的第一张牌无距离限制。②当你于出牌阶段内使用牌时,你可以令此牌不能被响应,然后你于本阶段内不能再使用牌。", + drlt_xiongluan: "雄乱", + drlt_xiongluan1: "雄乱", + drlt_xiongluan_info: + "限定技,出牌阶段,你可以废除你的判定区和装备区,然后指定一名其他角色。直到回合结束,你对其使用牌无距离和次数限制,其不能使用和打出手牌。", + drlt_congjian: "从谏", + drlt_congjian_info: + "当你成为锦囊牌的目标时,若此牌的目标数大于1,则你可以交给其中一名其他目标角色一张牌,然后摸一张牌,若你给出的是装备牌,改为摸两张牌。", + drlt_yongsi: "庸肆", + drlt_yongsi_info: + "锁定技,摸牌阶段,你改为摸X张牌(X为存活势力数);出牌阶段结束时,若你本回合:1.没有造成伤害,将手牌摸至当前体力值;2.造成的伤害超过1点,本回合手牌上限改为已损失体力值。", + drlt_weidi: "伪帝", + weidi_tag: "伪帝", + drlt_weidi_info: + "主公技,弃牌阶段开始时,若你的手牌数大于手牌上限,则你可以将至多X张手牌分别交给等量的其他群雄角色(X为你的手牌数与手牌上限之差)。", + drlt_qianjie: "谦节", + drlt_qianjie_info: + "锁定技,当你横置时,取消之。你不能成为延时类锦囊的目标。你不能成为其他角色拼点的目标。", + drlt_jueyan: "决堰", + drlt_jueyan_info: + "出牌阶段限一次,你可以废除一种装备栏,然后执行对应一项:武器栏,你本回合内使用【杀】的次数上限+3;防具栏,你摸三张牌,且本回合手牌上限+3;坐骑栏,你本回合内使用牌无距离限制;宝物栏,你获得〖集智〗直到回合结束。", + drlt_poshi: "破势", + drlt_poshi_info: + "觉醒技,准备阶段开始时,若你的装备栏均已被废除或体力值为1,则你减1点体力上限,将手牌摸至体力上限,失去〖决堰〗并获得〖怀柔〗。", + drlt_huairou: "怀柔", + drlt_huairou_info: "出牌阶段,你可以重铸装备牌。", + drlt_zhenggu: "镇骨", + drlt_zhenggu2: "镇骨", + drlt_zhenggu_info: + "结束阶段,你可以选择一名其他角色,你的回合结束后和该角色的下个回合结束时,其将手牌摸至或弃至X张。(X为你的手牌数且至多为5)", + drlt_zhenrong: "征荣", + drlt_zhenrong_info: + "当你对其他角色造成伤害后,若其手牌比你多,你可以将其一张牌置于你的武将牌上,称为“荣”。", + drlt_hongju: "鸿举", + drlt_hongju_info: + "觉醒技,准备阶段,若“荣”的数量大于或等于3且场上有角色死亡,则你可以用任意张手牌替换等量的“荣”,然后减1点体力上限并获得〖清侧〗。", + drlt_qingce: "清侧", + drlt_qingce_info: "出牌阶段,你可以移去一张“荣”,然后弃置一名角色装备区或判定区内的一张牌。", - zhengrong:'征荣', - hongju:'鸿举', - qingce:'清侧', - qingce_backup:'清侧', - zhengrong_info:'当你使用带有「伤害」标签的基本牌或锦囊牌指定目标后,你可以将一名手牌数不小于你的目标角色的一张牌置于你的武将牌上,称为「荣」。', - hongju_info:'觉醒技,准备阶段,若你武将牌上「荣」的数量不小于3,则你触发此技能。你可以用任意数量的手牌交换等量的「荣」。你减1点体力上限并获得技能〖清侧〗。', - qingce_info:'出牌阶段,你可以获得一张「荣」并弃置一张手牌,然后弃置场上的一张牌。', + zhengrong: "征荣", + hongju: "鸿举", + qingce: "清侧", + qingce_backup: "清侧", + zhengrong_info: + "当你使用带有「伤害」标签的基本牌或锦囊牌指定目标后,你可以将一名手牌数不小于你的目标角色的一张牌置于你的武将牌上,称为「荣」。", + hongju_info: + "觉醒技,准备阶段,若你武将牌上「荣」的数量不小于3,则你触发此技能。你可以用任意数量的手牌交换等量的「荣」。你减1点体力上限并获得技能〖清侧〗。", + qingce_info: "出牌阶段,你可以获得一张「荣」并弃置一张手牌,然后弃置场上的一张牌。", - jianchu:'鞬出', - jianchu_info:'当你使用【杀】指定一名角色为目标后,你可以弃置其一张牌,若以此法弃置的牌为装备牌,此【杀】不可被【闪】响应,若不为装备牌,该角色获得此【杀】。', - redimeng:'缔盟', - redimeng_info:'出牌阶段限一次,你可以弃置X张牌选择两名其他角色(X为这两名角色的手牌差),你混合他们的手牌,然后令其中一名角色获得其中的一张牌,并令另一名角色获得其中的一张牌,然后重复此流程,直到这些牌均被获得为止。', - reluanji:'乱击', - reluanji_info:'你可以将两张与你本回合以此法转化的花色均不相同的手牌当【万箭齐发】使用,然后当一名角色因响应此牌而打出【闪】时,该角色摸一张牌。若你以此法使用的【万箭齐发】未造成伤害,则你可以在此牌结算完成后摸X张牌。(X为此牌的目标数)', - xintianxiang:'天香', - xintianxiang2:'天香', - xintianxiang3:'天香', - xintianxiang4:'天香', - xintianxiang_bg:'香', - xintianxiang_info:'当你受到伤害时,你可以弃置一张♥牌,将此伤害转移给一名其他角色,然后你选择一项:令该角色摸X张牌(X为其已损失的体力值);或防止其造成与受到的所有伤害,且此技能失效直到你的下回合开始。', - xinshensu:'神速', - xinshensu_info:'你可以选择一至三项:1. 跳过判定阶段和摸牌阶段;2. 跳过出牌阶段并弃置一张装备牌;3. 跳过弃牌阶段并将你的武将牌翻面。你每选择一项,视为你对一名其他角色使用一张没有距离限制的【杀】。', - yinghun:'英魂', - yinghun_info:'准备阶段开始时,你可令一名其他角色执行一项:摸X张牌,然后弃置一张牌;或摸一张牌,然后弃置X张牌(X为你已损失的体力值)。', - gzyinghun:'英魂', - gzyinghun_info:'准备阶段开始时,若你已受伤,你可令一名其他角色执行一项:摸X张牌,然后弃置一张牌;或摸一张牌,然后弃置X张牌(X为你已损失的体力值)。', + jianchu: "鞬出", + jianchu_info: + "当你使用【杀】指定一名角色为目标后,你可以弃置其一张牌,若以此法弃置的牌为装备牌,此【杀】不可被【闪】响应,若不为装备牌,该角色获得此【杀】。", + redimeng: "缔盟", + redimeng_info: + "出牌阶段限一次,你可以弃置X张牌选择两名其他角色(X为这两名角色的手牌差),你混合他们的手牌,然后令其中一名角色获得其中的一张牌,并令另一名角色获得其中的一张牌,然后重复此流程,直到这些牌均被获得为止。", + reluanji: "乱击", + reluanji_info: + "你可以将两张与你本回合以此法转化的花色均不相同的手牌当【万箭齐发】使用,然后当一名角色因响应此牌而打出【闪】时,该角色摸一张牌。若你以此法使用的【万箭齐发】未造成伤害,则你可以在此牌结算完成后摸X张牌。(X为此牌的目标数)", + xintianxiang: "天香", + xintianxiang2: "天香", + xintianxiang3: "天香", + xintianxiang4: "天香", + xintianxiang_bg: "香", + xintianxiang_info: + "当你受到伤害时,你可以弃置一张♥牌,将此伤害转移给一名其他角色,然后你选择一项:令该角色摸X张牌(X为其已损失的体力值);或防止其造成与受到的所有伤害,且此技能失效直到你的下回合开始。", + xinshensu: "神速", + xinshensu_info: + "你可以选择一至三项:1. 跳过判定阶段和摸牌阶段;2. 跳过出牌阶段并弃置一张装备牌;3. 跳过弃牌阶段并将你的武将牌翻面。你每选择一项,视为你对一名其他角色使用一张没有距离限制的【杀】。", + yinghun: "英魂", + yinghun_info: + "准备阶段开始时,你可令一名其他角色执行一项:摸X张牌,然后弃置一张牌;或摸一张牌,然后弃置X张牌(X为你已损失的体力值)。", + gzyinghun: "英魂", + gzyinghun_info: + "准备阶段开始时,若你已受伤,你可令一名其他角色执行一项:摸X张牌,然后弃置一张牌;或摸一张牌,然后弃置X张牌(X为你已损失的体力值)。", - tiaoxin:'挑衅', - zhiji:'志继', - zhiji_draw:'摸牌', - zhiji_recover:'回血', - xiangle:'享乐', - fangquan:'放权', - ruoyu:'若愚', - qiaobian:'巧变', - tuntian:'屯田', - tuntian_bg:'田', - zaoxian:'凿险', - jixi:'急袭', - jiang:'激昂', - hunzi:'魂姿', - zhiba:'制霸', - zhiba2:'制霸', - zhijian:'直谏', - guzheng:'固政', - beige:'悲歌', - duanchang:'断肠', + tiaoxin: "挑衅", + zhiji: "志继", + zhiji_draw: "摸牌", + zhiji_recover: "回血", + xiangle: "享乐", + fangquan: "放权", + ruoyu: "若愚", + qiaobian: "巧变", + tuntian: "屯田", + tuntian_bg: "田", + zaoxian: "凿险", + jixi: "急袭", + jiang: "激昂", + hunzi: "魂姿", + zhiba: "制霸", + zhiba2: "制霸", + zhijian: "直谏", + guzheng: "固政", + beige: "悲歌", + duanchang: "断肠", // fushen:'附身', - huashen:'化身', - xinsheng:'新生', - qimou:'奇谋', - xinqiangxi:'强袭', - xinjushou:'据守', - xinjiewei:'解围', - retianxiang:'天香', - retianxiang_info:'当你受到伤害时,你可以弃置一张红桃手牌,防止此次伤害并选择一名其他角色,然后你选择一项:1.令其受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5);2.令其失去1点体力,然后获得你弃置的牌。', - xinjiewei_info:'你可以将装备区里的牌当【无懈可击】使用;当你的武将牌从背面翻至正面时,你可以弃置一张牌,然后移动场上的一张牌。', - xinjushou_info:'结束阶段,你可以翻面并摸四张牌,然后弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之。', - jixi_info:'出牌阶段,你可以将任意一张“田”当作【顺手牵羊】使用。', - xinqiangxi_info:'出牌阶段各限一次,你可以选择一项:1. 失去1点体力并对你攻击范围内的一名其他角色造成1点伤害;2. 弃置一张装备牌并对你攻击范围内的一名其他角色造成1点伤害。', - qimou_info:'限定技,出牌阶段,你可以失去任意点体力,然后直到回合结束,你计算与其他角色的距离时-X,且你可以多使用X张【杀】(X为你失去的体力值)。', - tiaoxin_info:'出牌阶段限一次,你可以指定一名攻击范围内包含你的角色,该角色需对你使用一张【杀】,否则你弃置其一张牌。', - zhiji_info:'觉醒技,准备阶段,若你没有手牌,你须回复1点体力或摸两张牌,然后减1点体力上限,并获得技能〖观星〗。', - xiangle_info:'锁定技,当其他角色使用【杀】指定你为目标时,其需弃置一张基本牌,否则此【杀】对你无效。', - fangquan_info:'你可跳过你的出牌阶段,若如此做,回合结束时,你可以弃置一张手牌并令一名其他角色进行一个额外的回合。', - ruoyu_info:'主公技,觉醒技,准备阶段,若你的体力是全场最少的(或之一),你须增加1点体力上限并回复1点体力,然后获得技能〖激将〗。', - qiaobian_info:'你可以弃置一张手牌并跳过自己的一个阶段(准备阶段和结束阶段除外)。若你以此法跳过了摸牌阶段,则你可以获得至多两名其他角色的各一张手牌;若你以此法跳过了出牌阶段,则你可以移动场上的一张牌。', - tuntian_info:'①当你于回合外失去牌后,你可以判定。若判定结果不为♥,则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。', - zaoxian_info:'觉醒技,准备阶段,若你武将牌上“田”的数量达到3张或更多,则你减1点体力上限,并获得技能〖急袭〗。', - jiang_info:'每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。', - hunzi_info:'觉醒技,准备阶段,若你的体力值为1,你减1点体力上限,并获得技能〖英姿〗和〖英魂〗。', - zhiba_info:'主公技,其他吴势力角色的出牌阶段限一次,其可与你进行一次拼点。若该角色没赢,你可以获得双方拼点的牌。若你已发动过〖魂姿〗,你可以拒绝此拼点。', - zhijian_info:'出牌阶段,你可以将手牌中的一张装备牌置于一名其他角色装备区里(不得替换原装备),然后摸一张牌。', - guzheng_info:'其他角色的弃牌阶段结束时,你可以令其获得本阶段内进入弃牌堆的牌中的一张,然后你获得其余的牌。', - beige_info:'当有角色受到【杀】造成的伤害后,你可以弃一张牌,并令其进行一次判定,若判定结果为:♥该角色回复1点体力;♦︎该角色摸两张牌;♣伤害来源弃两张牌;♠伤害来源将其武将牌翻面。', - duanchang_info:'锁定技,杀死你的角色失去当前的所有技能。', + huashen: "化身", + xinsheng: "新生", + qimou: "奇谋", + xinqiangxi: "强袭", + xinjushou: "据守", + xinjiewei: "解围", + retianxiang: "天香", + retianxiang_info: + "当你受到伤害时,你可以弃置一张红桃手牌,防止此次伤害并选择一名其他角色,然后你选择一项:1.令其受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5);2.令其失去1点体力,然后获得你弃置的牌。", + xinjiewei_info: + "你可以将装备区里的牌当【无懈可击】使用;当你的武将牌从背面翻至正面时,你可以弃置一张牌,然后移动场上的一张牌。", + xinjushou_info: + "结束阶段,你可以翻面并摸四张牌,然后弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之。", + jixi_info: "出牌阶段,你可以将任意一张“田”当作【顺手牵羊】使用。", + xinqiangxi_info: + "出牌阶段各限一次,你可以选择一项:1. 失去1点体力并对你攻击范围内的一名其他角色造成1点伤害;2. 弃置一张装备牌并对你攻击范围内的一名其他角色造成1点伤害。", + qimou_info: + "限定技,出牌阶段,你可以失去任意点体力,然后直到回合结束,你计算与其他角色的距离时-X,且你可以多使用X张【杀】(X为你失去的体力值)。", + tiaoxin_info: + "出牌阶段限一次,你可以指定一名攻击范围内包含你的角色,该角色需对你使用一张【杀】,否则你弃置其一张牌。", + zhiji_info: + "觉醒技,准备阶段,若你没有手牌,你须回复1点体力或摸两张牌,然后减1点体力上限,并获得技能〖观星〗。", + xiangle_info: + "锁定技,当其他角色使用【杀】指定你为目标时,其需弃置一张基本牌,否则此【杀】对你无效。", + fangquan_info: + "你可跳过你的出牌阶段,若如此做,回合结束时,你可以弃置一张手牌并令一名其他角色进行一个额外的回合。", + ruoyu_info: + "主公技,觉醒技,准备阶段,若你的体力是全场最少的(或之一),你须增加1点体力上限并回复1点体力,然后获得技能〖激将〗。", + qiaobian_info: + "你可以弃置一张手牌并跳过自己的一个阶段(准备阶段和结束阶段除外)。若你以此法跳过了摸牌阶段,则你可以获得至多两名其他角色的各一张手牌;若你以此法跳过了出牌阶段,则你可以移动场上的一张牌。", + tuntian_info: + "①当你于回合外失去牌后,你可以判定。若判定结果不为♥,则你将此牌置于你的武将牌上,称为“田”。②你计算与其他角色的距离时-X(X为你武将牌上“田”的数目)。", + zaoxian_info: + "觉醒技,准备阶段,若你武将牌上“田”的数量达到3张或更多,则你减1点体力上限,并获得技能〖急袭〗。", + jiang_info: + "每当你使用(指定目标后)或被使用(成为目标后)一张【决斗】或红色的【杀】时,你可以摸一张牌。", + hunzi_info: "觉醒技,准备阶段,若你的体力值为1,你减1点体力上限,并获得技能〖英姿〗和〖英魂〗。", + zhiba_info: + "主公技,其他吴势力角色的出牌阶段限一次,其可与你进行一次拼点。若该角色没赢,你可以获得双方拼点的牌。若你已发动过〖魂姿〗,你可以拒绝此拼点。", + zhijian_info: + "出牌阶段,你可以将手牌中的一张装备牌置于一名其他角色装备区里(不得替换原装备),然后摸一张牌。", + guzheng_info: + "其他角色的弃牌阶段结束时,你可以令其获得本阶段内进入弃牌堆的牌中的一张,然后你获得其余的牌。", + beige_info: + "当有角色受到【杀】造成的伤害后,你可以弃一张牌,并令其进行一次判定,若判定结果为:♥该角色回复1点体力;♦︎该角色摸两张牌;♣伤害来源弃两张牌;♠伤害来源将其武将牌翻面。", + duanchang_info: "锁定技,杀死你的角色失去当前的所有技能。", // fushen_info:'回合开始前,你可以选择与任意一名角色交换控制权,该角色可选择在下一个回合开始前与你换回。', - huashen_info:'①游戏开始时,你随机将武将牌堆中的两张牌扣置于武将牌上(均称为“化身牌”),选择并亮出一张“化身牌”并声明该武将牌上的一个技能,你拥有该技能且同时将性别和势力属性变成与该武将相同直到该化身被替换(你不可声明限定技、觉醒技、隐匿技、使命技、主公技等特殊技能)。②回合开始时或回合结束时,你重新可以选择一张“化身牌”并声明该武将牌上的一个技能。', - xinsheng_info:'当你受到1点伤害后,你可以获得一张“化身牌”。', - jiangwei:'姜维', - liushan:'刘禅', - zhanghe:'张郃', - dengai:'邓艾', - sunce:'孙策', - zhangzhang:'张昭张纮', - caiwenji:'蔡琰', - zuoci:'左慈', + huashen_info: + "①游戏开始时,你随机将武将牌堆中的两张牌扣置于武将牌上(均称为“化身牌”),选择并亮出一张“化身牌”并声明该武将牌上的一个技能,你拥有该技能且同时将性别和势力属性变成与该武将相同直到该化身被替换(你不可声明限定技、觉醒技、隐匿技、使命技、主公技等特殊技能)。②回合开始时或回合结束时,你重新可以选择一张“化身牌”并声明该武将牌上的一个技能。", + xinsheng_info: "当你受到1点伤害后,你可以获得一张“化身牌”。", + jiangwei: "姜维", + liushan: "刘禅", + zhanghe: "张郃", + dengai: "邓艾", + sunce: "孙策", + zhangzhang: "张昭张纮", + caiwenji: "蔡琰", + zuoci: "左慈", - zhurong:'祝融', - menghuo:'孟获', - caopi:'曹丕', - re_xuhuang:'徐晃', - lusu:'旧鲁肃', - lusu_prefix:'旧', - sunjian:'孙坚', - dongzhuo:'董卓', - jiaxu:'贾诩', - huoshou:'祸首', - huoshou1:'祸首', - huoshou2:'祸首', - zaiqi:'再起', - zaiqixx:'再起', - juxiang:'巨象', - juxiang1:'巨象', - juxiang2:'巨象', - lieren:'烈刃', - xingshang:'行殇', - fangzhu:'放逐', - songwei:'颂威', - songwei2:'颂威', - duanliang:'断粮', - duanliang1:'断粮', - haoshi:'好施', - dimeng:'缔盟', - jiuchi:'酒池', - roulin:'肉林', - benghuai:'崩坏', - baonue:'暴虐', - baonue2:'暴虐', - baonue_hp:'体力', - baonue_maxHp:'体力上限', - luanwu:'乱武', - wansha:'完杀', - weimu:'帷幕', - jiezi:'截辎', - jiezi_info:'锁定技,其他角色跳过摸牌阶段后,你摸一张牌。', - huoshou_info:'锁定技,【南蛮入侵】对你无效;你视为所有【南蛮入侵】的伤害来源。', - zaiqi_info:'摸牌阶段,若你已受伤,则你可以改为展示牌堆顶的X张牌(X为你已损失的体力值),并回复X点体力(X为其中♥牌的数目)。然后你将这些♥牌置入弃牌堆,并获得其余的牌。', - zaiqixx_info:'摸牌阶段,若你已受伤,则你可以改为展示牌堆顶的X张牌(X为你已损失的体力值+1),并回复X点体力(X为其中♥牌的数目)。然后你将这些♥牌置入弃牌堆,并获得其余的牌。', - juxiang_info:'锁定技。①【南蛮入侵】对你无效。②其他角色使用的【南蛮入侵】结算结束后,你获得此牌对应的所有实体牌。', - lieren_info:'当你使用【杀】造成伤害后,可与受到该伤害的角色进行拼点;若你赢,你获得对方的一张牌。', - xingshang_info:'当有角色死亡后,你可以获得该角色的所有牌。', - fangzhu_info:'当你受到伤害后,你可令一名其他角色摸X张牌(X为你已损失的体力值),然后该角色将武将牌翻面。', - songwei_info:'主公技,其他魏势力的角色的判定牌结果为黑色且生效后,其可以令你摸一张牌。', - duanliang_info:'你可以将一张黑色基本牌或装备牌当做【兵粮寸断】使用;若一名角色的手牌数大于或等于你的手牌数,则你对其使用【兵粮寸断】没有距离限制。', - haoshi_info:'摸牌阶段,你可以额外摸两张牌。若此时你的手牌数多于五张,你须将一半(向下取整)的手牌交给场上除你外手牌数最少的一名角色。', - dimeng_info:'出牌阶段限一次,你可以选择其他两名角色,你弃置等同于这两名角色手牌数量之差的牌,然后交换他们的手牌。', - yinghun_old_info:'准备阶段,若你已受伤,则你可以令一名其他角色执行下列两项中的一项: 1.摸X张牌,然后弃一张牌。 2.摸一张牌,然后弃X张牌。 (X为你已损失的体力值)', - jiuchi_info:'你可以将一张♠手牌当作【酒】使用。', - roulin_info:'锁定技。你对女性角色、女性角色对你使用【杀】时,都需连续使用两张【闪】才能抵消。', - benghuai_info:'锁定技。结束阶段,若你的体力不为全场最少,你失去1点体力或减1点体力上限。', - baonue_info:'主公技,其他群雄角色造成伤害后,可进行一次判定,若为♠,你回复1点体力。', - luanwu_info:'限定技,出牌阶段,你可令除你外的所有角色依次对与其距离最近的另一名角色使用一张【杀】,否则失去1点体力。', - wansha_info:'锁定技,你的回合内,除你以外,不处于濒死状态的角色不能使用【桃】。', - weimu_info:'锁定技,你不能成为黑色锦囊牌的目标。', + zhurong: "祝融", + menghuo: "孟获", + caopi: "曹丕", + re_xuhuang: "徐晃", + lusu: "旧鲁肃", + lusu_prefix: "旧", + sunjian: "孙坚", + dongzhuo: "董卓", + jiaxu: "贾诩", + huoshou: "祸首", + huoshou1: "祸首", + huoshou2: "祸首", + zaiqi: "再起", + zaiqixx: "再起", + juxiang: "巨象", + juxiang1: "巨象", + juxiang2: "巨象", + lieren: "烈刃", + xingshang: "行殇", + fangzhu: "放逐", + songwei: "颂威", + songwei2: "颂威", + duanliang: "断粮", + duanliang1: "断粮", + haoshi: "好施", + dimeng: "缔盟", + jiuchi: "酒池", + roulin: "肉林", + benghuai: "崩坏", + baonue: "暴虐", + baonue2: "暴虐", + baonue_hp: "体力", + baonue_maxHp: "体力上限", + luanwu: "乱武", + wansha: "完杀", + weimu: "帷幕", + jiezi: "截辎", + jiezi_info: "锁定技,其他角色跳过摸牌阶段后,你摸一张牌。", + huoshou_info: "锁定技,【南蛮入侵】对你无效;你视为所有【南蛮入侵】的伤害来源。", + zaiqi_info: + "摸牌阶段,若你已受伤,则你可以改为亮出牌堆顶的X张牌(X为你已损失的体力值),并回复X点体力(X为其中♥牌的数目)。然后你将这些♥牌置入弃牌堆,并获得其余的牌。", + zaiqixx_info: + "摸牌阶段,若你已受伤,则你可以改为亮出牌堆顶的X张牌(X为你已损失的体力值+1),并回复X点体力(X为其中♥牌的数目)。然后你将这些♥牌置入弃牌堆,并获得其余的牌。", + juxiang_info: + "锁定技。①【南蛮入侵】对你无效。②其他角色使用的【南蛮入侵】结算结束后,你获得此牌对应的所有实体牌。", + lieren_info: + "当你使用【杀】造成伤害后,可与受到该伤害的角色进行拼点;若你赢,你获得对方的一张牌。", + xingshang_info: "当有角色死亡后,你可以获得该角色的所有牌。", + fangzhu_info: + "当你受到伤害后,你可令一名其他角色摸X张牌(X为你已损失的体力值),然后该角色将武将牌翻面。", + songwei_info: "主公技,其他魏势力的角色的判定牌结果为黑色且生效后,其可以令你摸一张牌。", + duanliang_info: + "你可以将一张黑色基本牌或装备牌当做【兵粮寸断】使用;若一名角色的手牌数大于或等于你的手牌数,则你对其使用【兵粮寸断】没有距离限制。", + haoshi_info: + "摸牌阶段,你可以额外摸两张牌。若此时你的手牌数多于五张,你须将一半(向下取整)的手牌交给场上除你外手牌数最少的一名角色。", + dimeng_info: + "出牌阶段限一次,你可以选择其他两名角色,你弃置等同于这两名角色手牌数量之差的牌,然后交换他们的手牌。", + yinghun_old_info: + "准备阶段,若你已受伤,则你可以令一名其他角色执行下列两项中的一项: 1.摸X张牌,然后弃一张牌。 2.摸一张牌,然后弃X张牌。 (X为你已损失的体力值)", + jiuchi_info: "你可以将一张♠手牌当作【酒】使用。", + roulin_info: "锁定技。你对女性角色、女性角色对你使用【杀】时,都需连续使用两张【闪】才能抵消。", + benghuai_info: "锁定技。结束阶段,若你的体力不为全场最少,你失去1点体力或减1点体力上限。", + baonue_info: "主公技,其他群雄角色造成伤害后,可进行一次判定,若为♠,你回复1点体力。", + luanwu_info: + "限定技,出牌阶段,你可令除你外的所有角色依次对与其距离最近的另一名角色使用一张【杀】,否则失去1点体力。", + wansha_info: "锁定技,你的回合内,除你以外,不处于濒死状态的角色不能使用【桃】。", + weimu_info: "锁定技,你不能成为黑色锦囊牌的目标。", - sp_zhugeliang:'卧龙', - pangtong:'庞统', - xunyu:'荀彧', - dianwei:'典韦', - taishici:'太史慈', - yanwen:'颜良文丑', - yuanshao:'旧袁绍', - yuanshao_prefix:'旧', - re_pangde:'庞德', - huoji:'火计', - bazhen:'八阵', - kanpo:'看破', - niepan:'涅槃', - oldniepan:'涅槃', - quhu:'驱虎', - jieming:'节命', - qiangxix:'强袭', - qiangxi:'强袭', - tianyi:'天义', - shuangxiong:'双雄', - shuangxiong1:'双雄', - shuangxiong2:'双雄', - luanji:'乱击', - xueyi:'血裔', - mengjin:'猛进', - huoji_info:'你可以将一张红色手牌当作【火攻】使用。', - bazhen_info:'锁定技,若你的防具栏内没有牌且没有被废除,则你视为装备着【八卦阵】。', - kanpo_info:'你可以将你的任意一张黑色手牌当做【无懈可击】使用。', - niepan_info:'限定技,出牌阶段或当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。', - oldniepan_info:'限定技,当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。', - quhu_info:'出牌阶段限一次,你可以与一名体力值大于你的角色拼点,若你赢,则该角色对其攻击范围内另一名由你指定的角色造成1点伤害。若你没赢,该角色对你造成1点伤害。', - jieming_info:'当你受到1点伤害后,你可令一名角色将手牌摸至X张(X为其体力上限且至多为5)。', - qiangxi_info:'出牌阶段限一次,你可以失去1点体力或弃置一张武器牌,然后对你攻击范围内的一名其他角色造成1点伤害。', - qiangxix_info:'出牌阶段限两次,你可以失去1点体力或弃置一张武器牌,然后对一名本阶段内未成为过〖强袭〗的目标的其他角色造成1点伤害。', - tianyi_info:'出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你获得以下技能效果直到回合结束:你使用【杀】没有距离限制;可额外使用一张【杀】;使用【杀】时可额外指定一个目标。若你没赢,你不能使用【杀】直到回合结束。', - shuangxiong_info:'摸牌阶段,你可以改为进行一次判定:你获得此判定牌,且你可以于此回合内将任意一张与此判定牌不同颜色的手牌当做【决斗】使用。', - luanji_info:'出牌阶段,你可以将任意两张相同花色的手牌当做【万箭齐发】使用。', - xueyi_info:'主公技,锁定技,场上每有一名其他群雄角色存活,你的手牌上限便+2。', - mengjin_info:'当你使用的【杀】被【闪】抵消时,你可以弃置目标角色的一张牌。', + sp_zhugeliang: "卧龙", + pangtong: "庞统", + xunyu: "荀彧", + dianwei: "典韦", + taishici: "太史慈", + yanwen: "颜良文丑", + yuanshao: "旧袁绍", + yuanshao_prefix: "旧", + re_pangde: "庞德", + huoji: "火计", + bazhen: "八阵", + kanpo: "看破", + niepan: "涅槃", + oldniepan: "涅槃", + quhu: "驱虎", + jieming: "节命", + qiangxix: "强袭", + qiangxi: "强袭", + tianyi: "天义", + shuangxiong: "双雄", + shuangxiong1: "双雄", + shuangxiong2: "双雄", + luanji: "乱击", + xueyi: "血裔", + mengjin: "猛进", + huoji_info: "你可以将一张红色手牌当作【火攻】使用。", + bazhen_info: "锁定技,若你的防具栏内没有牌且没有被废除,则你视为装备着【八卦阵】。", + kanpo_info: "你可以将你的任意一张黑色手牌当做【无懈可击】使用。", + niepan_info: + "限定技,出牌阶段或当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。", + oldniepan_info: + "限定技,当你处于濒死状态时,你可以弃置你区域内的所有牌并复原你的武将牌,然后摸三张牌并将体力回复至3点。", + quhu_info: + "出牌阶段限一次,你可以与一名体力值大于你的角色拼点,若你赢,则该角色对其攻击范围内另一名由你指定的角色造成1点伤害。若你没赢,该角色对你造成1点伤害。", + jieming_info: "当你受到1点伤害后,你可令一名角色将手牌摸至X张(X为其体力上限且至多为5)。", + qiangxi_info: + "出牌阶段限一次,你可以失去1点体力或弃置一张武器牌,然后对你攻击范围内的一名其他角色造成1点伤害。", + qiangxix_info: + "出牌阶段限两次,你可以失去1点体力或弃置一张武器牌,然后对一名本阶段内未成为过〖强袭〗的目标的其他角色造成1点伤害。", + tianyi_info: + "出牌阶段限一次,你可以和一名其他角色拼点。若你赢,你获得以下技能效果直到回合结束:你使用【杀】没有距离限制;可额外使用一张【杀】;使用【杀】时可额外指定一个目标。若你没赢,你不能使用【杀】直到回合结束。", + shuangxiong_info: + "摸牌阶段,你可以改为进行一次判定:你获得此判定牌,且你可以于此回合内将任意一张与此判定牌不同颜色的手牌当做【决斗】使用。", + luanji_info: "出牌阶段,你可以将任意两张相同花色的手牌当做【万箭齐发】使用。", + xueyi_info: "主公技,锁定技,场上每有一名其他群雄角色存活,你的手牌上限便+2。", + mengjin_info: "当你使用的【杀】被【闪】抵消时,你可以弃置目标角色的一张牌。", - re_xiahouyuan:'夏侯渊', - re_huangzhong:'黄忠', - re_weiyan:'魏延', + re_xiahouyuan: "夏侯渊", + re_huangzhong: "黄忠", + re_weiyan: "魏延", - gz_xiahouyuan:'夏侯渊', - gz_huangzhong:'黄忠', - gz_weiyan:'魏延', - gz_xuhuang:'徐晃', - gz_pangde:'庞德', - gz_caoren:'曹仁', - gz_zhoutai:'周泰', + gz_xiahouyuan: "夏侯渊", + gz_huangzhong: "黄忠", + gz_weiyan: "魏延", + gz_xuhuang: "徐晃", + gz_pangde: "庞德", + gz_caoren: "曹仁", + gz_zhoutai: "周泰", - old_zhoutai:'周泰', - old_caoren:'曹仁', - xuhuang:'旧徐晃', - xuhuang_prefix:'旧', - pangde:'旧庞德', - pangde_prefix:'旧', - xiahouyuan:'旧夏侯渊', - xiahouyuan_prefix:'旧', - huangzhong:'旧黄忠', - huangzhong_prefix:'旧', - sp_zhangjiao:'张角', - weiyan:'旧魏延', - weiyan_prefix:'旧', - xiaoqiao:'小乔', - zhangjiao:'旧张角', - zhangjiao_prefix:'旧', + old_zhoutai: "周泰", + old_caoren: "曹仁", + xuhuang: "旧徐晃", + xuhuang_prefix: "旧", + pangde: "旧庞德", + pangde_prefix: "旧", + xiahouyuan: "旧夏侯渊", + xiahouyuan_prefix: "旧", + huangzhong: "旧黄忠", + huangzhong_prefix: "旧", + sp_zhangjiao: "张角", + weiyan: "旧魏延", + weiyan_prefix: "旧", + xiaoqiao: "小乔", + zhangjiao: "旧张角", + zhangjiao_prefix: "旧", //yuji:'于吉', - shensu:'神速', - shensu1:'神速', - shensu2:'神速', - shensu4:'神速', - jushou:'据守', - moon_jushou:'据守', - liegong:'烈弓', - kuanggu:'狂骨', - tianxiang:'天香', - hongyan:'红颜', - buqu:'不屈', - buqu_bg:'创', - leiji:'雷击', - guidao:'鬼道', - huangtian:'黄天', - huangtian2:'黄天', - guhuo:'蛊惑', - fenji:'奋激', - releiji:'雷击', - jiewei:'解围', - tiangong:'天公', - tiangong2:'天公', - xinliegong:'烈弓', - xinkuanggu:'狂骨', - gzbuqu:'不屈', - gzbuqu_info:'①当你扣减1点体力时,若你的体力值小于1,你可以将牌堆顶的一张牌置于你的武将牌上,称为“创”。②当你回复1点体力时,你移去一张“创”。③若你有“创”且点数均不相同,则你不结算濒死流程。', - xinkuanggu_info:'当你造成1点伤害后,若受伤角色受到此伤害时你与其的距离不大于1,则你可以回复1点体力或摸一张牌。', - xinliegong_info:'①你使用【杀】可以选择你距离不大于此【杀】点数的角色为目标。②当你使用【杀】指定一个目标后,你可以根据下列条件执行相应的效果:1.其手牌数小于等于你的手牌数,此【杀】不可被响应,2.其体力值大于等于你的体力值,此【杀】伤害+1。', - jiewei_info:'当你的武将牌翻面后,你可以摸一张牌。然后你可以使用一张锦囊牌或装备牌,并可以在此牌结算后弃置场上一张同类型的牌。', - releiji_info:'当你使用或打出一张【闪】时,你可令一名其他角色进行一次判定:若结果为梅花,你回复1点体力,并对其造成1点雷电伤害;若结果为黑桃,你对其造成2点雷电伤害。', - tiangong_info:'锁定技,你防止即将受到的雷电伤害。每当你造成雷电伤害时,你摸一张牌。', - shensu_info:'你可以跳过判定阶段和摸牌阶段,或跳过出牌阶段并弃置一张装备牌。若如此做,则你可以视为对任意一名角色使用一张无距离限制的【杀】。', - jushou_info:'结束阶段,你可以摸三张牌并翻面。', - moon_jushou_info:'结束阶段,你可以摸一张牌并翻面。', - liegong_info:'当你使用【杀】时,若目标的手牌数大于等于你的体力值,或小于等于你的攻击范围,你可令此【杀】不能被响应。', - kuanggu_info:'锁定技,当你造成伤害后,若受伤角色受到此伤害时你与其的距离不大于1,你回复X点体力(X为伤害值)。', - tianxiang_info:'当你即将受到伤害时,你可以弃置一张♥手牌,将伤害转移给一名其他角色,然后该角色摸X张牌(X为其已损失的体力值)。', - hongyan_info:'锁定技,你区域内的黑桃牌和黑桃判定牌均视为红桃。', - buqu_info:'锁定技,当你处于濒死状态时,你亮出牌堆顶的一张牌并置于你的武将牌上,称之为“创”。若此牌的点数与你武将牌上已有的“创”点数均不同,则你回复至1体力。若点数相同,则将此牌置入弃牌堆。只要你的武将牌上有“创”,你的手牌上限便与“创”的数量相等。', - buqu_info_guozhan:'锁定技,当你处于濒死状态时,你亮出牌堆顶的一张牌并置于你的武将牌上,称之为“创”。若此牌的点数与你武将牌上已有的“创”点数均不同,则你回复至1体力。若点数相同,则将此牌置入弃牌堆。', - leiji_info:'当你使用或打出一张【闪】时,你可令任意一名角色进行一次判定。若结果为黑桃,其受到2点雷电伤害。', - guidao_info:'一名角色的判定牌生效前,你可以打出一张黑色牌替换之。', - huangtian_info:'主公技,其他群势力角色的出牌阶段限一次,其可以交给你一张【闪】或【闪电】。', - guhuo_info:'每名角色的回合限一次,你可以扣置一张手牌当一张基本牌或普通锦囊牌使用或打出。其他角色依次选择是否质疑。一旦有其他角色质疑则翻开此牌:若为假则此牌作废,若为真,则质疑角色获得技能“缠怨”(锁定技,你不能质疑于吉,只要你的体力值为1,你失去你的武将技能)。', - fenji_info:'当一名角色的手牌不因赠予或交给而被另一名角色得到后,或一名角色的手牌被另一名角色弃置后,你可以失去1点体力,令其摸两张牌。', + shensu: "神速", + shensu1: "神速", + shensu2: "神速", + shensu4: "神速", + jushou: "据守", + moon_jushou: "据守", + liegong: "烈弓", + kuanggu: "狂骨", + tianxiang: "天香", + hongyan: "红颜", + buqu: "不屈", + buqu_bg: "创", + leiji: "雷击", + guidao: "鬼道", + huangtian: "黄天", + huangtian2: "黄天", + guhuo: "蛊惑", + fenji: "奋激", + releiji: "雷击", + jiewei: "解围", + tiangong: "天公", + tiangong2: "天公", + xinliegong: "烈弓", + xinkuanggu: "狂骨", + gzbuqu: "不屈", + gzbuqu_info: + "①当你扣减1点体力时,若你的体力值小于1,你可以将牌堆顶的一张牌置于你的武将牌上,称为“创”。②当你回复1点体力时,你移去一张“创”。③若你有“创”且点数均不相同,则你不结算濒死流程。", + xinkuanggu_info: + "当你造成1点伤害后,若受伤角色受到此伤害时你与其的距离不大于1,则你可以回复1点体力或摸一张牌。", + xinliegong_info: + "①你使用【杀】可以选择你距离不大于此【杀】点数的角色为目标。②当你使用【杀】指定一个目标后,你可以根据下列条件执行相应的效果:1.其手牌数小于等于你的手牌数,此【杀】不可被响应,2.其体力值大于等于你的体力值,此【杀】伤害+1。", + jiewei_info: + "当你的武将牌翻面后,你可以摸一张牌。然后你可以使用一张锦囊牌或装备牌,并可以在此牌结算后弃置场上一张同类型的牌。", + releiji_info: + "当你使用或打出一张【闪】时,你可令一名其他角色进行一次判定:若结果为梅花,你回复1点体力,并对其造成1点雷电伤害;若结果为黑桃,你对其造成2点雷电伤害。", + tiangong_info: "锁定技,你防止即将受到的雷电伤害。每当你造成雷电伤害时,你摸一张牌。", + shensu_info: + "你可以跳过判定阶段和摸牌阶段,或跳过出牌阶段并弃置一张装备牌。若如此做,则你可以视为对任意一名角色使用一张无距离限制的【杀】。", + jushou_info: "结束阶段,你可以摸三张牌并翻面。", + moon_jushou_info: "结束阶段,你可以摸一张牌并翻面。", + liegong_info: + "当你使用【杀】时,若目标的手牌数大于等于你的体力值,或小于等于你的攻击范围,你可令此【杀】不能被响应。", + kuanggu_info: + "锁定技,当你造成伤害后,若受伤角色受到此伤害时你与其的距离不大于1,你回复X点体力(X为伤害值)。", + tianxiang_info: + "当你即将受到伤害时,你可以弃置一张♥手牌,将伤害转移给一名其他角色,然后该角色摸X张牌(X为其已损失的体力值)。", + hongyan_info: "锁定技,你区域内的黑桃牌和黑桃判定牌均视为红桃。", + buqu_info: + "锁定技,当你处于濒死状态时,你亮出牌堆顶的一张牌并置于你的武将牌上,称之为“创”。若此牌的点数与你武将牌上已有的“创”点数均不同,则你回复至1体力。若点数相同,则将此牌置入弃牌堆。只要你的武将牌上有“创”,你的手牌上限便与“创”的数量相等。", + buqu_info_guozhan: + "锁定技,当你处于濒死状态时,你亮出牌堆顶的一张牌并置于你的武将牌上,称之为“创”。若此牌的点数与你武将牌上已有的“创”点数均不同,则你回复至1体力。若点数相同,则将此牌置入弃牌堆。", + leiji_info: + "当你使用或打出一张【闪】时,你可令任意一名角色进行一次判定。若结果为黑桃,其受到2点雷电伤害。", + guidao_info: "一名角色的判定牌生效前,你可以打出一张黑色牌替换之。", + huangtian_info: "主公技,其他群势力角色的出牌阶段限一次,其可以交给你一张【闪】或【闪电】。", + guhuo_info: + "每名角色的回合限一次,你可以扣置一张手牌当一张基本牌或普通锦囊牌使用或打出。其他角色依次选择是否质疑。一旦有其他角色质疑则翻开此牌:若为假则此牌作废,若为真,则质疑角色获得技能“缠怨”(锁定技,你不能质疑于吉,只要你的体力值为1,你失去你的武将技能)。", + fenji_info: + "当一名角色的手牌不因赠予或交给而被另一名角色得到后,或一名角色的手牌被另一名角色弃置后,你可以失去1点体力,令其摸两张牌。", - new_fenji:"奋激", - new_fenji_info:"一名角色的结束阶段开始时,若其没有手牌,你可以令其摸两张牌,然后你失去1点体力。", - gzduanliang:'断粮', - gzduanliang_info:'你可以将一张黑色基本牌或黑色装备牌当【兵粮寸断】使用;你可以对距离为2的角色使用【兵粮寸断】。', - xinfu_guhuo:"蛊惑", - xinfu_guhuo_info:"每回合限一次。你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出,其他角色依次选择是否质疑。当有角色质疑时,你终止质疑流程并展示此牌:若为假,此牌作废;若为真,该角色获得〖缠怨〗。", - guhuo_guess:"蛊惑", - guhuo_guess_info:"", - chanyuan:"缠怨", - chanyuan_info:"锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。", - "guhuo_respond":"蛊惑", - "guhuo_respond_info":"", - "guhuo_wuxie":"蛊惑", - "guhuo_wuxie_info":"", - "guhuo_phase":"蛊惑", - "guhuo_phase_info":"", - xinhongyan:'红颜', - xinhongyan_info:'锁定技,你的♠牌和♠判定牌的花色视为♥。一名角色的判定结果生效前,若判定结果为♥,则你将其改为一种花色。', - olliangyin:'良姻', - olliangyin_info:'当有牌发生移动后,若此移动事件是本回合内你拥有〖良姻〗期间的首个有牌移出游戏/移入游戏的事件,则你可以选择一名其他角色。你与其各摸一张牌/弃置一张牌,然后你可以选择你或其中的一名手牌数为X的角色,该角色回复1点体力(X为你的“箜”数)。', - olkongsheng:'箜声', - olkongsheng_info:'①准备阶段开始时,你可以将任意张牌置于你的武将牌上,称为“箜”。②结束阶段开始时,若你有不为装备牌的“箜”,则你获得“箜”中的非装备牌,然后令一名角色依次使用“箜”中的装备牌并失去1点体力。', - dcwanglie:"往烈", - dcwanglie_info:"①出牌阶段,你对其他角色使用的前两张牌无距离限制。②当你于出牌阶段内使用牌时,你可以令此牌不能被响应,然后你于本阶段内不能使用牌指定其他角色为目标。", - nzry_shicai:"恃才", - nzry_shicai_info:"当你使用非装备牌结算结束后,或成为自己使用装备牌的目标后,若此牌与你本回合使用的牌类型均不同,则你可以将此牌置于牌堆顶,然后摸一张牌。", - lianhuan:'连环', - lianhuan_info:'你可以将♣手牌当作【铁索连环】使用或重铸。', + new_fenji: "奋激", + new_fenji_info: "一名角色的结束阶段开始时,若其没有手牌,你可以令其摸两张牌,然后你失去1点体力。", + gzduanliang: "断粮", + gzduanliang_info: + "你可以将一张黑色基本牌或黑色装备牌当【兵粮寸断】使用;你可以对距离为2的角色使用【兵粮寸断】。", + xinfu_guhuo: "蛊惑", + xinfu_guhuo_info: + "每回合限一次。你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出,其他角色依次选择是否质疑。当有角色质疑时,你终止质疑流程并展示此牌:若为假,此牌作废;若为真,该角色获得〖缠怨〗。", + guhuo_guess: "蛊惑", + guhuo_guess_info: "", + chanyuan: "缠怨", + chanyuan_info: + "锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。", + guhuo_respond: "蛊惑", + guhuo_respond_info: "", + guhuo_wuxie: "蛊惑", + guhuo_wuxie_info: "", + guhuo_phase: "蛊惑", + guhuo_phase_info: "", + xinhongyan: "红颜", + xinhongyan_info: + "锁定技,你的♠牌和♠判定牌的花色视为♥。一名角色的判定结果生效前,若判定结果为♥,则你将其改为一种花色。", + olliangyin: "良姻", + olliangyin_info: + "当有牌发生移动后,若此移动事件是本回合内你拥有〖良姻〗期间的首个有牌移出游戏/移入游戏的事件,则你可以选择一名其他角色。你与其各摸一张牌/弃置一张牌,然后你可以选择你或其中的一名手牌数为X的角色,该角色回复1点体力(X为你的“箜”数)。", + olkongsheng: "箜声", + olkongsheng_info: + "①准备阶段开始时,你可以将任意张牌置于你的武将牌上,称为“箜”。②结束阶段开始时,若你有不为装备牌的“箜”,则你获得“箜”中的非装备牌,然后令一名角色依次使用“箜”中的装备牌并失去1点体力。", + dcwanglie: "往烈", + dcwanglie_info: + "①出牌阶段,你对其他角色使用的前两张牌无距离限制。②当你于出牌阶段内使用牌时,你可以令此牌不能被响应,然后你于本阶段内不能使用牌指定其他角色为目标。", + nzry_shicai: "恃才", + nzry_shicai_info: + "当你使用非装备牌结算结束后,或成为自己使用装备牌的目标后,若此牌与你本回合使用的牌类型均不同,则你可以将此牌置于牌堆顶,然后摸一张牌。", + lianhuan: "连环", + lianhuan_info: "你可以将♣手牌当作【铁索连环】使用或重铸。", - shenhua_feng:'神话再临·风', - shenhua_huo:'神话再临·火', - shenhua_lin:'神话再临·林', - shenhua_shan:'神话再临·山', - shenhua_yin:'神话再临·阴', - shenhua_lei:'神话再临·雷', + shenhua_feng: "神话再临·风", + shenhua_huo: "神话再临·火", + shenhua_lin: "神话再临·林", + shenhua_shan: "神话再临·山", + shenhua_yin: "神话再临·阴", + shenhua_lei: "神话再临·雷", }, }; }); diff --git a/character/shiji.js b/character/shiji.js index 1a0f5c79f..88ed695d2 100644 --- a/character/shiji.js +++ b/character/shiji.js @@ -1,251 +1,357 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'shiji', - connect:true, - characterSort:{ - shiji:{ - mobile_shijizhi:["sp_wangcan","sp_chenzhen","sp_sunshao","sp_xunchen","luotong","sp_duyu","sp_bianfuren","feiyi"], - mobile_shijixin:['wujing','sp_mifuren','sp_xinpi','wangling','wangfuzhaolei','zhouchu','sp_kongrong','sp_yanghu'], - mobile_shijiren:['caizhenji','xiangchong','sp_huaxin','sp_xujing','zhangzhongjing','sp_zhangwen','liuzhang','qiaogong'], - mobile_shijiyong:['db_wenyang','sp_chendong','yuanhuan','sp_zongyu','sp_wangshuang','sunyi','sp_gaolan','sp_huaman'], - mobile_shijiyan:['sp_cuiyan','sp_zhangchangpu','sp_jiangwan','sp_jiangqing','sp_lvfan','sp_huangfusong','sp_zhujun','liuba'], + name: "shiji", + connect: true, + characterSort: { + shiji: { + mobile_shijizhi: [ + "sp_wangcan", + "sp_chenzhen", + "sp_sunshao", + "sp_xunchen", + "luotong", + "sp_duyu", + "sp_bianfuren", + "feiyi", + ], + mobile_shijixin: [ + "wujing", + "sp_mifuren", + "sp_xinpi", + "wangling", + "wangfuzhaolei", + "zhouchu", + "sp_kongrong", + "sp_yanghu", + ], + mobile_shijiren: [ + "caizhenji", + "xiangchong", + "sp_huaxin", + "sp_xujing", + "zhangzhongjing", + "sp_zhangwen", + "liuzhang", + "qiaogong", + ], + mobile_shijiyong: [ + "db_wenyang", + "sp_chendong", + "yuanhuan", + "sp_zongyu", + "sp_wangshuang", + "sunyi", + "sp_gaolan", + "sp_huaman", + ], + mobile_shijiyan: [ + "sp_cuiyan", + "sp_zhangchangpu", + "sp_jiangwan", + "sp_jiangqing", + "sp_lvfan", + "sp_huangfusong", + "sp_zhujun", + "liuba", + ], }, }, - character:{ - liuba:['male','shu',3,['duanbi','tongduo']], - sp_zhujun:['male','qun',4,['xinyangjie','xinjuxiang','houfeng']], - sp_huangfusong:['male','qun',4,['spzhengjun','spshiji','sptaoluan']], - sp_lvfan:['male','wu',3,['mbdiaodu','mbdiancai','spyanji']], - sp_jiangqing:['male','wu',4,['spjianyi','spshangyi']], - sp_jiangwan:['male','shu',3,['spzhenting','spjincui']], - sp_zhangchangpu:['female','wei',3,['spdifei','spyanjiao']], - sp_cuiyan:['male','wei',3,['spyajun','spzundi']], - sp_huaman:['female','shu',4,['spxiangzhen','spfangzong','spxizhan']], - sp_gaolan:['male','qun',4,['spjungong','spdengli']], - sunyi:['male','wu',4,['zaoli']], - sp_wangshuang:['male','wei',4,['yiyong','shanxie']], - sp_zongyu:['male','shu',3,['zhibian','yuyan']], - yuanhuan:['male','wei',3,['qingjue','fengjie']], - sp_chendong:['male','wu',4,['spyilie','spfenming']], - db_wenyang:['male','wei',4,['dbquedi','dbzhuifeng','dbchongjian','dbchoujue'],['doublegroup:wei:wu']], - sp_yanghu:['male','qun',3,['mingfa','rongbei']], - qiaogong:['male','wu',3,['yizhu','luanchou']], - liuzhang:['male','qun',3,['jutu','yaohu','rehuaibi'],['zhu']], - sp_zhangwen:['male','wu',3,['gebo','spsongshu']], - zhangzhongjing:['male','qun',3,['jishi','xinliaoyi','binglun']], - sp_xujing:['male','shu',3,['boming','ejian']], - sp_huaxin:['male','wei',3,['yuanqing','shuchen']], - xiangchong:['male','shu',4,['guying','muzhen']], - caizhenji:['female','wei',3,['sheyi','tianyin']], - sp_kongrong:['male','qun',3,['xinlirang','xinmingshi']], - zhouchu:['male','wu',4,['xianghai','rechuhai']], - wangfuzhaolei:['male','shu',4,['xunyi']], - wangling:['male','wei',4,['xingqi','xinzifu','mibei'],['clan:太原王氏']], - wujing:['male','wu',4,['heji','liubing']], - sp_mifuren:['female','shu',3,['xinguixiu','qingyu']], - sp_xinpi:['male','wei',3,['spyinju','spchijie']], - feiyi:['male','shu',3,['mjshengxi','fyjianyu']], - sp_bianfuren:['female','wei',3,['spwanwei','spyuejian']], - sp_duyu:['male','qun',4,['spwuku','spsanchen']], - luotong:['male','wu',4,['qinzheng']], - sp_wangcan:['male','wei',3,['spqiai','spshanxi']], - sp_chenzhen:['male','shu',3,['shameng']], - sp_sunshao:['male','wu',3,['mjdingyi','mjzuici','mjfubi']], - sp_xunchen:['male','qun',3,['mjweipo','mjchenshi','mjmouzhi'],['clan:颍川荀氏']], + character: { + liuba: ["male", "shu", 3, ["duanbi", "tongduo"]], + sp_zhujun: ["male", "qun", 4, ["xinyangjie", "xinjuxiang", "houfeng"]], + sp_huangfusong: ["male", "qun", 4, ["spzhengjun", "spshiji", "sptaoluan"]], + sp_lvfan: ["male", "wu", 3, ["mbdiaodu", "mbdiancai", "spyanji"]], + sp_jiangqing: ["male", "wu", 4, ["spjianyi", "spshangyi"]], + sp_jiangwan: ["male", "shu", 3, ["spzhenting", "spjincui"]], + sp_zhangchangpu: ["female", "wei", 3, ["spdifei", "spyanjiao"]], + sp_cuiyan: ["male", "wei", 3, ["spyajun", "spzundi"]], + sp_huaman: ["female", "shu", 4, ["spxiangzhen", "spfangzong", "spxizhan"]], + sp_gaolan: ["male", "qun", 4, ["spjungong", "spdengli"]], + sunyi: ["male", "wu", 4, ["zaoli"]], + sp_wangshuang: ["male", "wei", 4, ["yiyong", "shanxie"]], + sp_zongyu: ["male", "shu", 3, ["zhibian", "yuyan"]], + yuanhuan: ["male", "wei", 3, ["qingjue", "fengjie"]], + sp_chendong: ["male", "wu", 4, ["spyilie", "spfenming"]], + db_wenyang: [ + "male", + "wei", + 4, + ["dbquedi", "dbzhuifeng", "dbchongjian", "dbchoujue"], + ["doublegroup:wei:wu"], + ], + sp_yanghu: ["male", "qun", 3, ["mingfa", "rongbei"]], + qiaogong: ["male", "wu", 3, ["yizhu", "luanchou"]], + liuzhang: ["male", "qun", 3, ["jutu", "yaohu", "rehuaibi"], ["zhu"]], + sp_zhangwen: ["male", "wu", 3, ["gebo", "spsongshu"]], + zhangzhongjing: ["male", "qun", 3, ["jishi", "xinliaoyi", "binglun"]], + sp_xujing: ["male", "shu", 3, ["boming", "ejian"]], + sp_huaxin: ["male", "wei", 3, ["yuanqing", "shuchen"]], + xiangchong: ["male", "shu", 4, ["guying", "muzhen"]], + caizhenji: ["female", "wei", 3, ["sheyi", "tianyin"]], + sp_kongrong: ["male", "qun", 3, ["xinlirang", "xinmingshi"]], + zhouchu: ["male", "wu", 4, ["xianghai", "rechuhai"]], + wangfuzhaolei: ["male", "shu", 4, ["xunyi"]], + wangling: ["male", "wei", 4, ["xingqi", "xinzifu", "mibei"], ["clan:太原王氏"]], + wujing: ["male", "wu", 4, ["heji", "liubing"]], + sp_mifuren: ["female", "shu", 3, ["xinguixiu", "qingyu"]], + sp_xinpi: ["male", "wei", 3, ["spyinju", "spchijie"]], + feiyi: ["male", "shu", 3, ["mjshengxi", "fyjianyu"]], + sp_bianfuren: ["female", "wei", 3, ["spwanwei", "spyuejian"]], + sp_duyu: ["male", "qun", 4, ["spwuku", "spsanchen"]], + luotong: ["male", "wu", 4, ["qinzheng"]], + sp_wangcan: ["male", "wei", 3, ["spqiai", "spshanxi"]], + sp_chenzhen: ["male", "shu", 3, ["shameng"]], + sp_sunshao: ["male", "wu", 3, ["mjdingyi", "mjzuici", "mjfubi"]], + sp_xunchen: ["male", "qun", 3, ["mjweipo", "mjchenshi", "mjmouzhi"], ["clan:颍川荀氏"]], }, - skill:{ + skill: { //刘巴 - duanbi:{ - unique:true, - mark:true, - limited:true, - audio:2, - enable:'phaseUse', - filter:function(event,player){ - var num1=0,num2=0; - var count=game.countPlayer(function(current){ - num1+=current.countCards('h'); + duanbi: { + unique: true, + mark: true, + limited: true, + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + var num1 = 0, + num2 = 0; + var count = game.countPlayer(function (current) { + num1 += current.countCards("h"); num2++; - return current!=player; + return current != player; }); - return count>0&&num1>num2*2; + return count > 0 && num1 > num2 * 2; }, - filterTarget:true, - selectTarget:-1, - multitarget:true, - multiline:true, - skillAnimation:true, - animationColor:'orange', - content:function(){ - 'step 0' - player.awakenSkill('duanbi'); - event.num=0; - event.cards=[]; + filterTarget: true, + selectTarget: -1, + multitarget: true, + multiline: true, + skillAnimation: true, + animationColor: "orange", + content: function () { + "step 0"; + player.awakenSkill("duanbi"); + event.num = 0; + event.cards = []; event.targets.sortBySeat(); event.targets.remove(player); - 'step 1' - var target=targets[num]; - var num=Math.min(3,Math.floor(target.countCards('h')/2)); - if(num>0) target.chooseToDiscard('h',true,num); - else event._result={bool:false}; - 'step 2' - if(result.bool&&Array.isArray(result.cards)) event.cards.addArray(result.cards); + "step 1"; + var target = targets[num]; + var num = Math.min(3, Math.floor(target.countCards("h") / 2)); + if (num > 0) target.chooseToDiscard("h", true, num); + else event._result = { bool: false }; + "step 2"; + if (result.bool && Array.isArray(result.cards)) event.cards.addArray(result.cards); event.num++; - if(event.num3?'随机获得三':('获得'+get.cnNumber(event.cards.length)))+'张被弃置的牌?').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) att/=10; - if(target.hasJudge('lebu')) att/=4; - return att*Math.sqrt(Math.max(1,5-target.countCards('h'))); - }); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - target.gain(cards.randomGets(3),'gain2'); + if (!event.cards.length) event.finish(); + else + player + .chooseTarget( + "是否令一名角色" + + (event.cards.length > 3 + ? "随机获得三" + : "获得" + get.cnNumber(event.cards.length)) + + "张被弃置的牌?" + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) att /= 10; + if (target.hasJudge("lebu")) att /= 4; + return att * Math.sqrt(Math.max(1, 5 - target.countCards("h"))); + }); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + target.gain(cards.randomGets(3), "gain2"); } }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(player==target) return 3; - return -Math.min(3,Math.floor(target.countCards('h')/2)); + ai: { + order: 10, + result: { + target: function (player, target) { + if (player == target) return 3; + return -Math.min(3, Math.floor(target.countCards("h") / 2)); }, }, }, }, - tongduo:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - direct:true, - usable:1, - filter:function(event,player){ - return player!=event.player&&event.targets.length==1&&game.hasPlayer(function(current){ - return current.countCards('he')>0; - }); + tongduo: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + direct: true, + usable: 1, + filter: function (event, player) { + return ( + player != event.player && + event.targets.length == 1 && + game.hasPlayer(function (current) { + return current.countCards("he") > 0; + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('tongduo'),'令一名角色重铸一张牌',function(card,player,target){ - return target.hasCard(lib.filter.cardRecastable,'he'); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)*Math.min(3,Math.floor(target.countCards('h',lib.filter.cardRecastable)/2)); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('tongduo',target); - } - else event.finish(); - 'step 2' - if(!target.hasCard(lib.filter.cardRecastable,'he')) event.finish(); - else target.chooseCard('he',true,'请重铸一张牌',lib.filter.cardRecastable); - 'step 3' + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("tongduo"), + "令一名角色重铸一张牌", + function (card, player, target) { + return target.hasCard(lib.filter.cardRecastable, "he"); + } + ) + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) * + Math.min(3, Math.floor(target.countCards("h", lib.filter.cardRecastable) / 2)) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("tongduo", target); + } else event.finish(); + "step 2"; + if (!target.hasCard(lib.filter.cardRecastable, "he")) event.finish(); + else target.chooseCard("he", true, "请重铸一张牌", lib.filter.cardRecastable); + "step 3"; target.recast(result.cards); }, }, //朱儁 - yangjie:{ - audio:2, - group:['yangjie_add'], - enable:'phaseUse', - prompt:'摸一张牌并与一名其他角色进行拼点', - usable:1, - filter:function(event,player){ - return !player.hasSkillTag('noCompareSource'); + yangjie: { + audio: 2, + group: ["yangjie_add"], + enable: "phaseUse", + prompt: "摸一张牌并与一名其他角色进行拼点", + usable: 1, + filter: function (event, player) { + return !player.hasSkillTag("noCompareSource"); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0&& - !target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + return ( + target != player && + target.countCards("h") > 0 && + !target.hasSkillTag("noCompareTarget") + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.canCompare(target)) player.chooseToCompare(target).set('small',true); + "step 1"; + if (player.canCompare(target)) player.chooseToCompare(target).set("small", true); else event.finish(); - 'step 2' - if(!result.bool){ - var cards=[result.player,result.target].filterInD('d'); - if(!cards.length||!game.hasPlayer((current)=>current!=player&¤t!=target)) event.finish(); - else{ - event.cards=cards; - player.chooseTarget('请选择一名角色','令其获得'+get.translation(cards)+',且视为对'+get.translation(target)+'使用一张火【杀】',function(card,player,target){ - return target!=player&&target!=_status.event.getParent().target; - }).set('ai',function(target){ - var player=_status.event.player,cards=_status.event.getParent().cards,target2=_status.event.getParent().target; - var val=get.value(cards,target)*get.attitude(player,target); - if(val<=0) return 0; - return val+target.canUse({name:'sha',nature:'fire',isCard:true},target2,false)?get.effect(target2,{name:'sha',nature:'fire',isCard:true},target,player):0; - }); + "step 2"; + if (!result.bool) { + var cards = [result.player, result.target].filterInD("d"); + if ( + !cards.length || + !game.hasPlayer((current) => current != player && current != target) + ) + event.finish(); + else { + event.cards = cards; + player + .chooseTarget( + "请选择一名角色", + "令其获得" + + get.translation(cards) + + ",且视为对" + + get.translation(target) + + "使用一张火【杀】", + function (card, player, target) { + return target != player && target != _status.event.getParent().target; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + cards = _status.event.getParent().cards, + target2 = _status.event.getParent().target; + var val = get.value(cards, target) * get.attitude(player, target); + if (val <= 0) return 0; + return val + + target.canUse( + { name: "sha", nature: "fire", isCard: true }, + target2, + false + ) + ? get.effect( + target2, + { name: "sha", nature: "fire", isCard: true }, + target, + player + ) + : 0; + }); } - } - else event.finish(); - 'step 3' - if(result.bool){ - var source=result.targets[0]; - event.source=source; + } else event.finish(); + "step 3"; + if (result.bool) { + var source = result.targets[0]; + event.source = source; player.line(source); - source.gain(cards,'gain2'); - } - else event.finish(); - 'step 4' - var card={name:'sha',nature:'fire',isCard:true}; - if(target.isIn()&&source.isIn()&&source.canUse(card,target,false)) source.useCard(card,target,false); + source.gain(cards, "gain2"); + } else event.finish(); + "step 4"; + var card = { name: "sha", nature: "fire", isCard: true }; + if (target.isIn() && source.isIn() && source.canUse(card, target, false)) + source.useCard(card, target, false); }, - subSkill:{ - add:{ - trigger:{player:'compare'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.getParent().name=='yangjie'&&event.num1>1&&player.isDamaged(); + subSkill: { + add: { + trigger: { player: "compare" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.getParent().name == "yangjie" && event.num1 > 1 && player.isDamaged() + ); + }, + content: function () { + var num = player.getDamagedHp(); + game.log(player, "的拼点牌点数-", num); + trigger.num1 = Math.max(1, trigger.num1 - num); }, - content:function(){ - var num=player.getDamagedHp(); - game.log(player,'的拼点牌点数-',num); - trigger.num1=Math.max(1,trigger.num1-num); - } }, }, - ai:{ - order:3, - result:{target:-1.5}, + ai: { + order: 3, + result: { target: -1.5 }, }, }, - zjjuxiang:{ - audio:2, - trigger:{global:'dyingAfter'}, - logTarget:'player', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return event.player!=player&&event.player.isIn(); + zjjuxiang: { + audio: 2, + trigger: { global: "dyingAfter" }, + logTarget: "player", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return event.player != player && event.player.isIn(); }, - check:function(event,player){ - return get.damageEffect(event.player,player,player)>0; + check: function (event, player) { + return get.damageEffect(event.player, player, player) > 0; }, - content:function(){ - 'step 0' - player.awakenSkill('zjjuxiang'); + content: function () { + "step 0"; + player.awakenSkill("zjjuxiang"); trigger.player.damage(); - 'step 1' - if(trigger.player.maxHp>0) player.draw(trigger.player.maxHp); + "step 1"; + if (trigger.player.maxHp > 0) player.draw(trigger.player.maxHp); }, - ai:{expose:10}, + ai: { expose: 10 }, }, xinyangjie: { - audio: 'yangjie', - enable: 'phaseUse', + audio: "yangjie", + enable: "phaseUse", filter: function (event, player) { return game.hasPlayer(function (target) { return player.canCompare(target); @@ -256,399 +362,549 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, usable: 1, content: function () { - 'step 0' - player.chooseToCompare(target).set('small', true); - 'step 1' - if (!result.bool && game.hasPlayer(function (current) { - return current != player && current != target && current.canUse({ name: 'sha', nature: 'fire', isCard: true }, target, false); - })) { - player.chooseTarget('佯解:是否选择另一名其他角色?', '令其视为对' + get.translation(target) + '使用一张火【杀】', function (card, player, target) { - return target != player && target != _status.event.getParent().target; - }).set('ai', function (target) { - var player = _status.event.player, target2 = _status.event.getParent().target; - return get.effect(target2, { name: 'sha', nature: 'fire', isCard: true }, target, player); - }); - } - else event.finish(); - 'step 2' + "step 0"; + player.chooseToCompare(target).set("small", true); + "step 1"; + if ( + !result.bool && + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + current.canUse({ name: "sha", nature: "fire", isCard: true }, target, false) + ); + }) + ) { + player + .chooseTarget( + "佯解:是否选择另一名其他角色?", + "令其视为对" + get.translation(target) + "使用一张火【杀】", + function (card, player, target) { + return target != player && target != _status.event.getParent().target; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + target2 = _status.event.getParent().target; + return get.effect( + target2, + { name: "sha", nature: "fire", isCard: true }, + target, + player + ); + }); + } else event.finish(); + "step 2"; if (result.bool) { var source = result.targets[0]; player.line(source); - game.log(player, '选择了', source); - var card = { name: 'sha', nature: 'fire', isCard: true }; - if (target.isIn() && source.isIn() && source.canUse(card, target, false)) source.useCard(card, target, false, 'noai'); + game.log(player, "选择了", source); + var card = { name: "sha", nature: "fire", isCard: true }; + if (target.isIn() && source.isIn() && source.canUse(card, target, false)) + source.useCard(card, target, false, "noai"); } }, ai: { order: 3, result: { target: function (player, target) { - var hs = player.getCards('h').sort(function (a, b) { + var hs = player.getCards("h").sort(function (a, b) { return a.number - b.number; }); - var ts = target.getCards('h').sort(function (a, b) { + var ts = target.getCards("h").sort(function (a, b) { return a.number - b.number; }); if (!hs.length || !ts.length) return 0; if (hs[0].number <= ts[0].number) return -3; - if (player.countCards('h') >= target.countCards('h')) return -10; + if (player.countCards("h") >= target.countCards("h")) return -10; return -1; }, }, }, }, xinjuxiang: { - audio: 'zjjuxiang', - inherit: 'zjjuxiang', + audio: "zjjuxiang", + inherit: "zjjuxiang", content: function () { - player.awakenSkill('xinjuxiang'); + player.awakenSkill("xinjuxiang"); trigger.player.damage(); }, }, - houfeng:{ - audio:3, - group:'houfeng_zhengsu', - subSkill:{ - zhengsu:{ - audio:'houfeng1', - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - if(!['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].some(i=>!event.player.hasSkill(i))) return false; + houfeng: { + audio: 3, + group: "houfeng_zhengsu", + subSkill: { + zhengsu: { + audio: "houfeng1", + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + if ( + !["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].some( + (i) => !event.player.hasSkill(i) + ) + ) + return false; return player.inRange(event.player); }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - prompt2:()=>lib.translate.houfeng_info, - round:1, - logTarget:'player', - content:function(){ - 'step 0' - player.chooseButton(['选择'+get.translation(trigger.player)+'要进行的整肃类型',[['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].filter(i=>!trigger.player.hasSkill(i)),'vcard']],true).set('ai',()=>Math.random()); - 'step 1' - if(result.bool){ - var name=result.links[0][2],target=trigger.player; - target.addTempSkill('houfeng_share',{player:['phaseDiscardAfter','phaseAfter']}); - target.markAuto('houfeng_share',[player]); - target.addTempSkill(name,{player:['phaseDiscardAfter','phaseAfter']}); - target.popup(name,'thunder'); + prompt2: () => lib.translate.houfeng_info, + round: 1, + logTarget: "player", + content: function () { + "step 0"; + player + .chooseButton( + [ + "选择" + get.translation(trigger.player) + "要进行的整肃类型", + [ + ["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].filter( + (i) => !trigger.player.hasSkill(i) + ), + "vcard", + ], + ], + true + ) + .set("ai", () => Math.random()); + "step 1"; + if (result.bool) { + var name = result.links[0][2], + target = trigger.player; + target.addTempSkill("houfeng_share", { + player: ["phaseDiscardAfter", "phaseAfter"], + }); + target.markAuto("houfeng_share", [player]); + target.addTempSkill(name, { player: ["phaseDiscardAfter", "phaseAfter"] }); + target.popup(name, "thunder"); game.delayx(); } }, }, - share:{ - charlotte:true, - onremove:true, - trigger:{player:'phaseDiscardEnd'}, - forced:true, - popup:false, - content:function(){ - 'step 0' - if(!lib.skill.zhengsu.filter(trigger,player)){ - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','houfeng3'); + share: { + charlotte: true, + onremove: true, + trigger: { player: "phaseDiscardEnd" }, + forced: true, + popup: false, + content: function () { + "step 0"; + if (!lib.skill.zhengsu.filter(trigger, player)) { + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "houfeng3"); }); - player.popup('整肃失败','fire'); - game.log(player,'整肃失败'); + player.popup("整肃失败", "fire"); + game.log(player, "整肃失败"); event.finish(); return; } - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','houfeng2'); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "houfeng2"); }); - player.popup('整肃成功','wood'); - game.log(player,'整肃成功'); - var list=player.getStorage('houfeng_share').filter(i=>i.isIn()); + player.popup("整肃成功", "wood"); + game.log(player, "整肃成功"); + var list = player.getStorage("houfeng_share").filter((i) => i.isIn()); list.unshift(player); - event.list=list; - var num1=0,num2=0,num3=0; - for(var target of list){ - num1+=2*get.effect(target,{name:'draw'},player,player); - num2+=get.recoverEffect(target,player,player); + event.list = list; + var num1 = 0, + num2 = 0, + num3 = 0; + for (var target of list) { + num1 += 2 * get.effect(target, { name: "draw" }, player, player); + num2 += get.recoverEffect(target, player, player); } - trigger.player.chooseControl('摸两张牌','回复体力','cancel2').set('prompt','整肃奖励:请选择'+get.translation(list)+'的整肃奖励').set('ai',function(){ - return ['摸两张牌','回复体力','cancel2'][_status.event.goon.indexOf(Math.max.apply(Math,_status.event.goon))]; - }).set('goon',[num1,num2,num3]); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='摸两张牌') game.asyncDraw(event.list,2); - else{ - for(var i of event.list) i.recover(); + trigger.player + .chooseControl("摸两张牌", "回复体力", "cancel2") + .set("prompt", "整肃奖励:请选择" + get.translation(list) + "的整肃奖励") + .set("ai", function () { + return [ + "摸两张牌", + "回复体力", + "cancel2", + ][_status.event.goon.indexOf(Math.max.apply(Math, _status.event.goon))]; + }) + .set("goon", [num1, num2, num3]); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "摸两张牌") game.asyncDraw(event.list, 2); + else { + for (var i of event.list) i.recover(); } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; game.delayx(); }, }, }, }, - houfeng1:{audio:true}, + houfeng1: { audio: true }, //手杀皇甫嵩 - spzhengjun:{ - audio:3, - group:'spzhengjun_zhengsu', - subSkill:{ - zhengsu:{ - audio:'spzhengjun1', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return ['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].some(i=>!player.hasSkill(i)); + spzhengjun: { + audio: 3, + group: "spzhengjun_zhengsu", + subSkill: { + zhengsu: { + audio: "spzhengjun1", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].some( + (i) => !player.hasSkill(i) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('spzhengjun'),[['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].filter(i=>!player.hasSkill(i)),'vcard']]).set('ai',()=>Math.random()); - 'step 1' - if(result.bool){ - player.logSkill('spzhengjun_zhengsu',player); - var name=result.links[0][2]; - player.addTempSkill('spzhengjun_share',{player:['phaseDiscardAfter','phaseAfter']}); - player.addTempSkill(name,{player:['phaseDiscardAfter','phaseAfter']}); - player.popup(name,'thunder'); + direct: true, + content: function () { + "step 0"; + player + .chooseButton([ + get.prompt("spzhengjun"), + [ + ["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].filter( + (i) => !player.hasSkill(i) + ), + "vcard", + ], + ]) + .set("ai", () => Math.random()); + "step 1"; + if (result.bool) { + player.logSkill("spzhengjun_zhengsu", player); + var name = result.links[0][2]; + player.addTempSkill("spzhengjun_share", { + player: ["phaseDiscardAfter", "phaseAfter"], + }); + player.addTempSkill(name, { player: ["phaseDiscardAfter", "phaseAfter"] }); + player.popup(name, "thunder"); game.delayx(); } }, }, - share:{ - charlotte:true, - trigger:{player:'phaseDiscardEnd'}, - forced:true, - popup:false, - content:function(){ - 'step 0' - if(!lib.skill.zhengsu.filter(trigger,player)){ - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spzhengjun3'); + share: { + charlotte: true, + trigger: { player: "phaseDiscardEnd" }, + forced: true, + popup: false, + content: function () { + "step 0"; + if (!lib.skill.zhengsu.filter(trigger, player)) { + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spzhengjun3"); }); - player.popup('整肃失败','fire'); - game.log(player,'整肃失败'); + player.popup("整肃失败", "fire"); + game.log(player, "整肃失败"); event.finish(); return; } - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spzhengjun2'); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spzhengjun2"); }); - player.popup('整肃成功','wood'); - game.log(player,'整肃成功'); - player.chooseDrawRecover(2,'整肃奖励:摸两张牌或回复1点体力'); - 'step 1' - if(result.control=='cancel2'){event.finish();return;} - player.chooseTarget('整军:是否令一名其他角色也回复1点体力或摸两张牌?',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return Math.max(2*get.effect(target,{name:'draw'},target,player),get.recoverEffect(target,target,player)); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var num1=2*get.effect(target,{name:'draw'},target,player); - var num2=get.recoverEffect(target,target,player); - player.line(target); - if(target.isHealthy()) result.index=0; - else player.chooseControl('摸牌','回血').set('prompt','整肃奖励:令'+get.translation(target)+'摸两张牌或回复1点体力').set('ai',function(){ - return _status.event.goon?0:1; - }).set('goon',num1>=num2); + player.popup("整肃成功", "wood"); + game.log(player, "整肃成功"); + player.chooseDrawRecover(2, "整肃奖励:摸两张牌或回复1点体力"); + "step 1"; + if (result.control == "cancel2") { + event.finish(); + return; } - else event.finish(); - 'step 3' - if(result.index==0) target.draw(2); + player + .chooseTarget( + "整军:是否令一名其他角色也回复1点体力或摸两张牌?", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + return Math.max( + 2 * get.effect(target, { name: "draw" }, target, player), + get.recoverEffect(target, target, player) + ); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var num1 = 2 * get.effect(target, { name: "draw" }, target, player); + var num2 = get.recoverEffect(target, target, player); + player.line(target); + if (target.isHealthy()) result.index = 0; + else + player + .chooseControl("摸牌", "回血") + .set( + "prompt", + "整肃奖励:令" + get.translation(target) + "摸两张牌或回复1点体力" + ) + .set("ai", function () { + return _status.event.goon ? 0 : 1; + }) + .set("goon", num1 >= num2); + } else event.finish(); + "step 3"; + if (result.index == 0) target.draw(2); else target.recover(); }, }, }, }, - spzhengjun1:{audio:true}, - spshiji:{ - audio:2, - trigger:{source:'damageBegin2'}, - logTarget:'player', - filter:function(event,player){ - return player!=event.player&&event.hasNature('linked')&&event.player.countCards('h')>0&&!player.isMaxHandcard(true); + spzhengjun1: { audio: true }, + spshiji: { + audio: 2, + trigger: { source: "damageBegin2" }, + logTarget: "player", + filter: function (event, player) { + return ( + player != event.player && + event.hasNature("linked") && + event.player.countCards("h") > 0 && + !player.isMaxHandcard(true) + ); }, - check:function(event,player){ - return get.attitude(player,event.player)<=0; + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function(){ - var target=trigger.player; + content: function () { + var target = trigger.player; player.viewHandcards(target); - var hs=target.getCards('h',{color:'red'}); - if(hs.length){ + var hs = target.getCards("h", { color: "red" }); + if (hs.length) { target.discard(hs); player.draw(hs.length); } }, }, - sptaoluan:{ - audio:2, - trigger:{global:'judgeFixing'}, - usable:1, - filter:function(event,player){ - return event.result&&event.result.suit=='spade'; + sptaoluan: { + audio: 2, + trigger: { global: "judgeFixing" }, + usable: 1, + filter: function (event, player) { + return event.result && event.result.suit == "spade"; }, - check:function(event,player){ - return event.result.judge*get.attitude(player,event.player)<=0; + check: function (event, player) { + return event.result.judge * get.attitude(player, event.player) <= 0; }, - content:function(){ - 'step 0' - var evt=trigger.getParent(); - if(evt.name=='phaseJudge') evt.excluded=true; - else{ + content: function () { + "step 0"; + var evt = trigger.getParent(); + if (evt.name == "phaseJudge") evt.excluded = true; + else { evt.finish(); - evt._triggered=null; - if(evt.name.startsWith('pre_')){ - var evtx=evt.getParent(); + evt._triggered = null; + if (evt.name.startsWith("pre_")) { + var evtx = evt.getParent(); evtx.finish(); - evtx._triggered=null; + evtx._triggered = null; } - var nexts=trigger.next.slice(); - for(var next of nexts){ - if(next.name=='judgeCallback') trigger.next.remove(next); + var nexts = trigger.next.slice(); + for (var next of nexts) { + if (next.name == "judgeCallback") trigger.next.remove(next); } - var evts=game.getGlobalHistory('cardMove',function(evt){ - return evt.getParent(2)==trigger.getParent(); + var evts = game.getGlobalHistory("cardMove", function (evt) { + return evt.getParent(2) == trigger.getParent(); }); - var cards=[]; - for(var i=evts.length-1;i>=0;i--){ - var evt=evts[i]; - for(var card of evt.cards){ - if(get.position(card,true)=='o') cards.push(card); + var cards = []; + for (var i = evts.length - 1; i >= 0; i--) { + var evt = evts[i]; + for (var card of evt.cards) { + if (get.position(card, true) == "o") cards.push(card); } } trigger.orderingCards.addArray(cards); } - var list=[]; - if(get.position(trigger.result.card)=='d') list.push(0); - if(trigger.player.isIn()&&player.canUse({name:'sha',nature:'fire',isCard:true},trigger.player,false)) list.push(1); - if(list.length==2) player.chooseControl().set('choiceList',[ - '获得'+get.translation(trigger.result.card), - '视为对'+get.translation(trigger.player)+'使用一张火【杀】', - ]).set('choice',(get.effect(trigger.player,{name:'sha'},player,player)>0)?1:0); - else if(list.length==1) event._result={index:list[0]}; + var list = []; + if (get.position(trigger.result.card) == "d") list.push(0); + if ( + trigger.player.isIn() && + player.canUse({ name: "sha", nature: "fire", isCard: true }, trigger.player, false) + ) + list.push(1); + if (list.length == 2) + player + .chooseControl() + .set("choiceList", [ + "获得" + get.translation(trigger.result.card), + "视为对" + get.translation(trigger.player) + "使用一张火【杀】", + ]) + .set( + "choice", + get.effect(trigger.player, { name: "sha" }, player, player) > 0 ? 1 : 0 + ); + else if (list.length == 1) event._result = { index: list[0] }; else event.finish(); - 'step 1' - if(result.index==0) player.gain(trigger.result.card,'gain2'); - else player.useCard({name:'sha',nature:'fire',isCard:true},trigger.player,false) + "step 1"; + if (result.index == 0) player.gain(trigger.result.card, "gain2"); + else player.useCard({ name: "sha", nature: "fire", isCard: true }, trigger.player, false); }, }, //吕范 - spdiaodu:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('spdiaodu'),'令一名角色摸一张牌,然后移动其装备区内的一张牌').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att>0){ - if(target.hasCard(function(card){ - if(get.value(card,target)<=0&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card,false)&&get.effect(current,card,player,player)>0; - })) return true; - return false; - },'e')) return 2*att; - if(!target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card); - }) - },'e')) return 1; - } - else if(att<0){ - if(target.hasCard(function(card){ - if(get.value(card,target)>=4.5&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card)&&get.effect(current,card,player,player)>0; - })) return true; - return false; - },'e')) return -att; - } - return 0; - }) - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('spdiaodu',target); - target.draw(); - } - else event.finish(); - 'step 2' - var es=target.getCards('e',function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card); - }) - }); - if(es.length){ - if(es.length==1) event._result={bool:true,links:es}; - else player.chooseButton(['移动'+get.translation(target)+'的一张装备牌',es],true).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().target,card=button.link; - if(game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card)&&get.effect(current,card,player,player)>0; - })) return -get.value(card,target)*get.attitude(player,target); + spdiaodu: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("spdiaodu"), + "令一名角色摸一张牌,然后移动其装备区内的一张牌" + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att > 0) { + if ( + target.hasCard(function (card) { + if ( + get.value(card, target) <= 0 && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(card, false) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return true; + return false; + }, "e") + ) + return 2 * att; + if ( + !target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canEquip(card); + }); + }, "e") + ) + return 1; + } else if (att < 0) { + if ( + target.hasCard(function (card) { + if ( + get.value(card, target) >= 4.5 && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return true; + return false; + }, "e") + ) + return -att; + } return 0; }); - } - else event.finish(); - 'step 3' - if(result.bool){ - event.card=result.links[0]; - player.chooseTarget(true,'选择'+get.translation(event.card)+'的移动目标',function(card,player,target){ - return target.canEquip(_status.event.card); - }).set('card',event.card).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,evt.getParent().card,evt.player,evt.player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("spdiaodu", target); + target.draw(); + } else event.finish(); + "step 2"; + var es = target.getCards("e", function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canEquip(card); }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target2=result.targets[0]; + }); + if (es.length) { + if (es.length == 1) event._result = { bool: true, links: es }; + else + player + .chooseButton(["移动" + get.translation(target) + "的一张装备牌", es], true) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target, + card = button.link; + if ( + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return -get.value(card, target) * get.attitude(player, target); + return 0; + }); + } else event.finish(); + "step 3"; + if (result.bool) { + event.card = result.links[0]; + player + .chooseTarget( + true, + "选择" + get.translation(event.card) + "的移动目标", + function (card, player, target) { + return target.canEquip(_status.event.card); + } + ) + .set("card", event.card) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, evt.getParent().card, evt.player, evt.player); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var target2 = result.targets[0]; target.line(target2); - target.$give(card,target2); + target.$give(card, target2); game.delay(0.5); target2.equip(card); } }, }, - spdiancai:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&player.hasHistory('lose',function(evt){ - return evt.hs&&evt.hs.length>0; - }); + spdiancai: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + player.hasHistory("lose", function (evt) { + return evt.hs && evt.hs.length > 0; + }) + ); }, - content:function(){ - 'step 0' - var num=0; - player.getHistory('lose',function(evt){ - if(evt.hs) num+=evt.hs.length; + content: function () { + "step 0"; + var num = 0; + player.getHistory("lose", function (evt) { + if (evt.hs) num += evt.hs.length; }); - num=Math.min(num,game.countPlayer()); - player.chooseTarget(get.prompt('spdiancai'),[1,num],'令至多'+get.cnNumber(num)+'名角色各摸一张牌').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(trigger.player); - player.logSkill('spdiancai',targets); - if(targets.length==1){ + num = Math.min(num, game.countPlayer()); + player + .chooseTarget( + get.prompt("spdiancai"), + [1, num], + "令至多" + get.cnNumber(num) + "名角色各摸一张牌" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(trigger.player); + player.logSkill("spdiancai", targets); + if (targets.length == 1) { targets[0].draw(); event.finish(); - } - else game.asyncDraw(targets); - } - else event.finish(); - 'step 2' + } else game.asyncDraw(targets); + } else event.finish(); + "step 2"; game.delayx(); }, }, mbdiaodu: { - audio: 'spdiaodu', - trigger: { player: 'phaseZhunbeiBegin' }, + audio: "spdiaodu", + trigger: { player: "phaseZhunbeiBegin" }, filter: function (event, player) { return game.hasPlayer(function (target) { - return target.countCards('e', function (card) { + return target.countCards("e", function (card) { return game.hasPlayer(function (current) { return current != player && current != target && current.canEquip(card); }); @@ -657,1590 +913,1983 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, direct: true, content: function () { - 'step 0' - player.chooseTarget(get.prompt2('mbdiaodu'), function (card, player, target) { - return target.countCards('e', function (card) { - return game.hasPlayer(function (current) { - return current != player && current != target && current.canEquip(card); + "step 0"; + player + .chooseTarget(get.prompt2("mbdiaodu"), function (card, player, target) { + return target.countCards("e", function (card) { + return game.hasPlayer(function (current) { + return current != player && current != target && current.canEquip(card); + }); }); + }) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att > 0) { + if ( + target.hasCard(function (card) { + if ( + get.value(card, target) <= 0 && + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + current.canEquip(card, false) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return true; + return false; + }, "e") + ) + return 2 * att; + } else if (att < 0) { + if ( + target.hasCard(function (card) { + if ( + get.value(card, target) >= 4.5 && + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return true; + return false; + }, "e") + ) + return -att; + } + return 0; }); - }).set('ai', function (target) { - var player = _status.event.player, att = get.attitude(player, target); - if (att > 0) { - if (target.hasCard(function (card) { - if (get.value(card, target) <= 0 && game.hasPlayer(function (current) { - return current != player && current != target && current.canEquip(card, false) && get.effect(current, card, player, player) > 0; - })) return true; - return false; - }, 'e')) return 2 * att; - } - else if (att < 0) { - if (target.hasCard(function (card) { - if (get.value(card, target) >= 4.5 && game.hasPlayer(function (current) { - return current != player && current != target && current.canEquip(card) && get.effect(current, card, player, player) > 0; - })) return true; - return false; - }, 'e')) return -att; - } - return 0; - }) - 'step 1' + "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; - player.logSkill('mbdiaodu', target); - } - else event.finish(); - 'step 2' - var es = target.getCards('e', function (card) { + player.logSkill("mbdiaodu", target); + } else event.finish(); + "step 2"; + var es = target.getCards("e", function (card) { return game.hasPlayer(function (current) { return current != target && current.canEquip(card); - }) + }); }); if (es.length == 1) event._result = { bool: true, links: es }; - else player.chooseButton(['移动' + get.translation(target) + '的一张装备牌', es], true).set('ai', function (button) { - var player = _status.event.player, target = _status.event.getParent().target, card = button.link; - if (game.hasPlayer(function (current) { - return current != player && current != target && current.canEquip(card) && get.effect(current, card, player, player) > 0; - })) return -get.value(card, target) * get.attitude(player, target); - return 0; - }); - 'step 3' + else + player + .chooseButton(["移动" + get.translation(target) + "的一张装备牌", es], true) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target, + card = button.link; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return -get.value(card, target) * get.attitude(player, target); + return 0; + }); + "step 3"; if (result.bool) { event.card = result.links[0]; - player.chooseTarget('请选择' + get.translation(event.card) + '的移动目标', true, function (card, player, target) { - return target != player && target.canEquip(_status.event.card); - }).set('card', event.card).set('ai', function (target) { - var evt = _status.event; - return get.effect(target, evt.getParent().card, evt.player, evt.player); - }); - } - else event.finish(); - 'step 4' + player + .chooseTarget( + "请选择" + get.translation(event.card) + "的移动目标", + true, + function (card, player, target) { + return target != player && target.canEquip(_status.event.card); + } + ) + .set("card", event.card) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, evt.getParent().card, evt.player, evt.player); + }); + } else event.finish(); + "step 4"; if (result.bool) { var target2 = result.targets[0]; target.line(target2); target.$give(card, target2); game.delay(0.5); target2.equip(card); - } - else event.finish(); - 'step 5' + } else event.finish(); + "step 5"; target.draw(); }, }, mbdiancai: { - audio: 'spdiancai', - trigger: { global: 'phaseUseEnd' }, + audio: "spdiancai", + trigger: { global: "phaseUseEnd" }, filter: function (event, player) { if (_status.currentPhase == player) return false; var num = 0; - player.getHistory('lose', function (evt) { - if (evt.cards2 && evt.getParent('phaseUse') == event) num += evt.cards2.length; + player.getHistory("lose", function (evt) { + if (evt.cards2 && evt.getParent("phaseUse") == event) num += evt.cards2.length; }); - return num >= player.hp && player.countCards('h') < player.maxHp; + return num >= player.hp && player.countCards("h") < player.maxHp; }, frequent: true, content: function () { - var num = player.maxHp - player.countCards('h'); + var num = player.maxHp - player.countCards("h"); if (num > 0) player.draw(num); }, }, - spyanji:{ - audio:3, - group:'spyanji_zhengsu', - subSkill:{ - zhengsu:{ - audio:'spyanji', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return ['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].some(i=>!player.hasSkill(i)); + spyanji: { + audio: 3, + group: "spyanji_zhengsu", + subSkill: { + zhengsu: { + audio: "spyanji", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].some( + (i) => !player.hasSkill(i) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('spyanji'),[['zhengsu_leijin','zhengsu_bianzhen','zhengsu_mingzhi'].filter(i=>!player.hasSkill(i)),'vcard']]).set('ai',()=>Math.random()); - 'step 1' - if(result.bool){ - player.logSkill('spyanji_zhengsu',player); - var name=result.links[0][2]; - player.addTempSkill('spyanji_share',{player:['phaseDiscardAfter','phaseAfter']}); - player.addTempSkill(name,{player:['phaseDiscardAfter','phaseAfter']}); - player.popup(name,'thunder'); + direct: true, + content: function () { + "step 0"; + player + .chooseButton([ + get.prompt("spyanji"), + [ + ["zhengsu_leijin", "zhengsu_bianzhen", "zhengsu_mingzhi"].filter( + (i) => !player.hasSkill(i) + ), + "vcard", + ], + ]) + .set("ai", () => Math.random()); + "step 1"; + if (result.bool) { + player.logSkill("spyanji_zhengsu", player); + var name = result.links[0][2]; + player.addTempSkill("spyanji_share", { + player: ["phaseDiscardAfter", "phaseAfter"], + }); + player.addTempSkill(name, { player: ["phaseDiscardAfter", "phaseAfter"] }); + player.popup(name, "thunder"); game.delayx(); } }, }, - share:{ - charlotte:true, - trigger:{player:'phaseDiscardEnd'}, - forced:true, - popup:false, - content:function(){ - if(!lib.skill.zhengsu.filter(trigger,player)){ - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spyanji3'); + share: { + charlotte: true, + trigger: { player: "phaseDiscardEnd" }, + forced: true, + popup: false, + content: function () { + if (!lib.skill.zhengsu.filter(trigger, player)) { + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spyanji3"); }); - player.popup('整肃失败','fire'); - game.log(player,'整肃失败'); + player.popup("整肃失败", "fire"); + game.log(player, "整肃失败"); event.finish(); return; } - game.broadcastAll(function(){ - if(lib.config.background_speak) game.playAudio('skill','spyanji2'); + game.broadcastAll(function () { + if (lib.config.background_speak) game.playAudio("skill", "spyanji2"); }); - player.popup('整肃成功','wood'); - game.log(player,'整肃成功'); - player.chooseDrawRecover(2,'整肃奖励:摸两张牌或回复1点体力'); + player.popup("整肃成功", "wood"); + game.log(player, "整肃成功"); + player.chooseDrawRecover(2, "整肃奖励:摸两张牌或回复1点体力"); }, }, }, }, - spyanji1:{audio:true}, + spyanji1: { audio: true }, //蒋钦 - spjianyi:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='lose'||evt.type!='discard') return false; - for(var i of evt.cards){ - if(get.subtype(i,false)=='equip2'&&get.position(i,true)=='d') return true; - } - return false; - }).length>0; + spjianyi: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return ( + player != event.player && + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.type != "discard") return false; + for (var i of evt.cards) { + if (get.subtype(i, false) == "equip2" && get.position(i, true) == "d") + return true; + } + return false; + }).length > 0 + ); }, - content:function(){ - 'step 0' - var cards=[]; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='lose'||evt.type!='discard') return false; - for(var i of evt.cards){ - if(get.subtype(i,false)=='equip2'&&get.position(i,true)=='d') cards.push(i); + content: function () { + "step 0"; + var cards = []; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.type != "discard") return false; + for (var i of evt.cards) { + if (get.subtype(i, false) == "equip2" && get.position(i, true) == "d") + cards.push(i); } }); - player.chooseButton(['俭衣:获得一张防具牌',cards],true).set('ai',function(button){ - return get.value(button.link,_status.event.player); + player.chooseButton(["俭衣:获得一张防具牌", cards], true).set("ai", function (button) { + return get.value(button.link, _status.event.player); }); - 'step 1' - if(result.bool) player.gain(result.links,'gain2'); + "step 1"; + if (result.bool) player.gain(result.links, "gain2"); }, }, - spshangyi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer((current)=>lib.skill.spshangyi.filterTarget(null,player,current)); + spshangyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer((current) => lib.skill.spshangyi.filterTarget(null, player, current)) + ); }, - filterCard:true, - position:'he', - check:function(card){ - return 6-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ + content: function () { target.viewHandcards(player); - player.gainPlayerCard(target,'h',true,'visible'); + player.gainPlayerCard(target, "h", true, "visible"); }, - ai:{ - order:6, - result:{ - player:0.5, - target:function(player,target){ - if(target.hasSkillTag('noh')) return 0; + ai: { + order: 6, + result: { + player: 0.5, + target: function (player, target) { + if (target.hasSkillTag("noh")) return 0; return -1; }, }, }, }, //蒋琬 - spzhenting:{ - audio:2, - trigger:{global:'useCardToTarget'}, - usable:1, - filter:function(event,player){ - return (event.card.name=='sha'||get.type(event.card,false)=='delay')&& - event.player!=player&&!event.targets.includes(player)&&player.inRange(event.target); + spzhenting: { + audio: 2, + trigger: { global: "useCardToTarget" }, + usable: 1, + filter: function (event, player) { + return ( + (event.card.name == "sha" || get.type(event.card, false) == "delay") && + event.player != player && + !event.targets.includes(player) && + player.inRange(event.target) + ); }, - logTarget:'target', - check:function(event,player){ - var target=event.target,source=event.player; - var eff1=get.effect(target,event.card,source,player); - if(eff1>=0) return false; - var eff2=get.effect(player,event.card,source,player); - if(eff2>=0) return true; - if(eff1) - if(event.card.name=='sha'){ - if(player.hasShan()) return true; - if(eff1>eff2) return false; - if(player.hp>2) return true; - if(player.hp==2) return eff2>eff1/3; - return false; - } - if(event.card.name=='shandian'||event.card.name=='bingliang') return true; - if(event.card.name=='lebu') return !player.needsToDiscard()&&target.needsToDiscard(); + logTarget: "target", + check: function (event, player) { + var target = event.target, + source = event.player; + var eff1 = get.effect(target, event.card, source, player); + if (eff1 >= 0) return false; + var eff2 = get.effect(player, event.card, source, player); + if (eff2 >= 0) return true; + if (eff1) + if (event.card.name == "sha") { + if (player.hasShan()) return true; + if (eff1 > eff2) return false; + if (player.hp > 2) return true; + if (player.hp == 2) return eff2 > eff1 / 3; + return false; + } + if (event.card.name == "shandian" || event.card.name == "bingliang") return true; + if (event.card.name == "lebu") return !player.needsToDiscard() && target.needsToDiscard(); return false; }, - content:function(){ - 'step 0' - var target=trigger.target,evt=trigger.getParent(); + content: function () { + "step 0"; + var target = trigger.target, + evt = trigger.getParent(); evt.triggeredTargets2.remove(target); evt.targets.remove(target); evt.triggeredTargets2.add(player); evt.targets.add(player); - game.log(trigger.card,'的目标被改为了',player); + game.log(trigger.card, "的目标被改为了", player); trigger.untrigger(); - 'step 1' - if(!trigger.player.countDiscardableCards(player,'h')) event._result={index:0}; - else player.chooseControl().set('choiceList',[ - '摸一张牌', - '弃置'+get.translation(trigger.player)+'的一张手牌', - ]); - 'step 2' - if(result.index==0) player.draw(); - else{ - player.line(trigger.player,'fire'); - player.discardPlayerCard(trigger.player,true,'h'); + "step 1"; + if (!trigger.player.countDiscardableCards(player, "h")) event._result = { index: 0 }; + else + player + .chooseControl() + .set("choiceList", [ + "摸一张牌", + "弃置" + get.translation(trigger.player) + "的一张手牌", + ]); + "step 2"; + if (result.index == 0) player.draw(); + else { + player.line(trigger.player, "fire"); + player.discardPlayerCard(trigger.player, true, "h"); } }, - ai:{ - threaten:1.4, + ai: { + threaten: 1.4, }, }, - spjincui:{ - audio:2, - enable:'phaseUse', - usable:1, - limited:true, - skillAnimation:true, - animationColor:'orange', - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - player.awakenSkill('spjincui'); - game.broadcastAll(function(target1,target2){ - game.swapSeat(target1,target2); - },player,target); - 'step 1' - if(player.hp>0) player.loseHp(player.hp); + spjincui: { + audio: 2, + enable: "phaseUse", + usable: 1, + limited: true, + skillAnimation: true, + animationColor: "orange", + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + player.awakenSkill("spjincui"); + game.broadcastAll( + function (target1, target2) { + game.swapSeat(target1, target2); + }, + player, + target + ); + "step 1"; + if (player.hp > 0) player.loseHp(player.hp); }, - ai:{ - order:5, - result:{ - player:function(player,target){ - if(player.hasUnknown()) return 0; - if(!player.countCards('h',{name:['tao','jiu']})) return 0; - var num=0,current=player.next; - while(true){ - num-=get.sgn(get.attitude(player,current)); - if(current==target) break; - current=current.next; + ai: { + order: 5, + result: { + player: function (player, target) { + if (player.hasUnknown()) return 0; + if (!player.countCards("h", { name: ["tao", "jiu"] })) return 0; + var num = 0, + current = player.next; + while (true) { + num -= get.sgn(get.attitude(player, current)); + if (current == target) break; + current = current.next; } - while(true){ - if(current==player) break; - num+=get.sgn(get.attitude(player,current))*1.1; - current=current.next; + while (true) { + if (current == player) break; + num += get.sgn(get.attitude(player, current)) * 1.1; + current = current.next; } - if(nummap[i]); - list.push('cancel2'); + chooseControl: function (event, player) { + var map = {}, + hs = player.getCards("h"); + for (var i of hs) map[get.suit(i, player)] = true; + var list = lib.suit.filter((i) => map[i]); + list.push("cancel2"); return list; }, - check:function(event,player){ - var map={},hs=player.getCards('h'),min=Infinity,min_suit=null; - for(var i of hs){ - var suit=get.suit(i,player); - if(!map[suit]) map[suit]=0; - map[suit]+=get.value(i); + check: function (event, player) { + var map = {}, + hs = player.getCards("h"), + min = Infinity, + min_suit = null; + for (var i of hs) { + var suit = get.suit(i, player); + if (!map[suit]) map[suit] = 0; + map[suit] += get.value(i); } - for(var i in map){ - if(map[i]5||get.value(ui.selected.cards,player)>5) return 0; - return get.damageEffect(target,player,target); + ai: { + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + var val = get.value(ui.selected.cards, target); + if (val < 0) return val + get.damageEffect(target, player, target); + if (val > 5 || get.value(ui.selected.cards, player) > 5) return 0; + return get.damageEffect(target, player, target); }, }, }, - } + }; }, - prompt:()=>'请选择【严教】的目标', + prompt: () => "请选择【严教】的目标", }, - subSkill:{ - draw:{ - onremove:true, - trigger:{player:'phaseBegin'}, - forced:true, - charlotte:true, - content:function(){ - player.draw(player.countMark('spyanjiao_draw')); - player.removeSkill('spyanjiao_draw'); + subSkill: { + draw: { + onremove: true, + trigger: { player: "phaseBegin" }, + forced: true, + charlotte: true, + content: function () { + player.draw(player.countMark("spyanjiao_draw")); + player.removeSkill("spyanjiao_draw"); }, - mark:true, - intro:{content:'下回合开始时摸#张牌'}, + mark: true, + intro: { content: "下回合开始时摸#张牌" }, }, - backup:{audio:'spyanjiao'}, + backup: { audio: "spyanjiao" }, }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, }, //崔琰 - spyajun:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - var hs=player.getCards('h'); - return hs.length>0&&!player.hasSkillTag('noCompareSource')&&player.hasHistory('gain',function(evt){ - for(var i of evt.cards){ - if(hs.includes(i)) return true; - } - return false; - })&&game.hasPlayer(function(current){ - return current!=player&&player.canCompare(current); - }); + spyajun: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + var hs = player.getCards("h"); + return ( + hs.length > 0 && + !player.hasSkillTag("noCompareSource") && + player.hasHistory("gain", function (evt) { + for (var i of evt.cards) { + if (hs.includes(i)) return true; + } + return false; + }) && + game.hasPlayer(function (current) { + return current != player && player.canCompare(current); + }) + ); }, - content:function(){ - 'step 0' - var cards=[],hs=player.getCards('h'); - player.getHistory('gain',function(evt){ + content: function () { + "step 0"; + var cards = [], + hs = player.getCards("h"); + player.getHistory("gain", function (evt) { cards.addArray(evt.cards); }); - cards=cards.filter(function(i){ + cards = cards.filter(function (i) { return hs.includes(i); }); player.chooseCardTarget({ - prompt:get.prompt('spyajun'), - prompt2:'操作提示:选择一张本回合新得到的牌作为拼点牌,然后选择一名拼点目标', - cards:cards, - filterCard:function(card){ + prompt: get.prompt("spyajun"), + prompt2: "操作提示:选择一张本回合新得到的牌作为拼点牌,然后选择一名拼点目标", + cards: cards, + filterCard: function (card) { return _status.event.cards.includes(card); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.canCompare(target); }, - ai1:function(card){ - return get.number(card)-get.value(card); + ai1: function (card) { + return get.number(card) - get.value(card); }, - ai2:function(target){ - return -get.attitude(_status.event.player,target)*Math.sqrt(5-Math.min(4,target.countCards('h')))*(target.hasSkillTag('noh')?0.5:1); + ai2: function (target) { + return ( + -get.attitude(_status.event.player, target) * + Math.sqrt(5 - Math.min(4, target.countCards("h"))) * + (target.hasSkillTag("noh") ? 0.5 : 1) + ); }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('spyajun',target); - var next=player.chooseToCompare(target); - if(!next.fixedResult) next.fixedResult={}; - next.fixedResult[player.playerid]=result.cards[0]; - } - else event.finish(); - 'step 2' - if(result.bool){ - var cards=[result.player,result.target].filterInD('d'); - if(cards.length){ - player.chooseButton(['是否将一张牌置于牌堆顶?',cards]).set('ai',function(button){ - if(get.color(button.link)=='black') return 1; - return 0; - }); - } - else event.finish(); - } - else{ - player.addMark('spyajun_less',1,false); - player.addTempSkill('spyajun_less'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("spyajun", target); + var next = player.chooseToCompare(target); + if (!next.fixedResult) next.fixedResult = {}; + next.fixedResult[player.playerid] = result.cards[0]; + } else event.finish(); + "step 2"; + if (result.bool) { + var cards = [result.player, result.target].filterInD("d"); + if (cards.length) { + player + .chooseButton(["是否将一张牌置于牌堆顶?", cards]) + .set("ai", function (button) { + if (get.color(button.link) == "black") return 1; + return 0; + }); + } else event.finish(); + } else { + player.addMark("spyajun_less", 1, false); + player.addTempSkill("spyajun_less"); event.finish(); } - 'step 3' - if(result.bool){ - var card=result.links[0]; + "step 3"; + if (result.bool) { + var card = result.links[0]; card.fix(); - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); game.updateRoundNumber(); - game.log(player,'将',card,'置于牌堆顶'); + game.log(player, "将", card, "置于牌堆顶"); } }, - group:'spyajun_draw', - subSkill:{ - draw:{ - audio:'spyajun', - trigger:{player:'phaseDrawBegin2'}, - forced:true, - locked:false, - filter:function(event,player){ + group: "spyajun_draw", + subSkill: { + draw: { + audio: "spyajun", + trigger: { player: "phaseDrawBegin2" }, + forced: true, + locked: false, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ + content: function () { trigger.num++; }, }, - less:{ - onremove:true, - charlotte:true, - intro:{content:'手牌上限-#'}, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('spyajun_less'); - } + less: { + onremove: true, + charlotte: true, + intro: { content: "手牌上限-#" }, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("spyajun_less"); + }, }, }, }, }, - spzundi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + spzundi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - filterTarget:true, - check:function(card){ - return 7-get.value(card); + filterCard: true, + filterTarget: true, + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.judge(); - 'step 1' - if(result.color=='black') target.draw(3); + "step 1"; + if (result.color == "black") target.draw(3); else target.moveCard(); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(target.canMoveCard(true)) return 3; + ai: { + order: 8, + result: { + target: function (player, target) { + if (target.canMoveCard(true)) return 3; return 1; }, }, }, }, //花蔓 - spxiangzhen:{ - trigger:{target:'useCardToBefore'}, - forced:true, - audio:2, - filter:function(event,player){ - return event.card.name=='nanman'; + spxiangzhen: { + trigger: { target: "useCardToBefore" }, + forced: true, + audio: 2, + filter: function (event, player) { + return event.card.name == "nanman"; }, - content:function(){ + content: function () { trigger.cancel(); }, - group:'spxiangzhen_draw', - subSkill:{ - draw:{ - audio:'spxiangzhen', - trigger:{global:'useCardAfter'}, - forced:true, - filter:function(event,player){ - return event.card.name=='nanman'&&game.hasPlayer2(function(current){ - return current.hasHistory('damage',function(evt){ - return evt.card==event.card; - }); - }); + group: "spxiangzhen_draw", + subSkill: { + draw: { + audio: "spxiangzhen", + trigger: { global: "useCardAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "nanman" && + game.hasPlayer2(function (current) { + return current.hasHistory("damage", function (evt) { + return evt.card == event.card; + }); + }) + ); }, - content:function(){ - 'step 0' - if(player!=trigger.player&&trigger.player.isIn()) game.asyncDraw([player,trigger.player].sortBySeat()); - else{ + content: function () { + "step 0"; + if (player != trigger.player && trigger.player.isIn()) + game.asyncDraw([player, trigger.player].sortBySeat()); + else { player.draw(); event.finish(); } - 'step 1' + "step 1"; game.delayx(); }, }, }, }, - spfangzong:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return !player.hasSkill('spxizhan_spfangzong')&&player.countCards('h')0&&!player.hasSkill('spxizhan_spfangzong')&&player.inRange(target)) return false; + mod: { + playerEnabled: function (card, player, target) { + if ( + player == _status.currentPhase && + get.tag(card, "damage") > 0 && + !player.hasSkill("spxizhan_spfangzong") && + player.inRange(target) + ) + return false; }, - targetEnabled:function(card,player,target){ - if(get.tag(card,'damage')>0&&!target.hasSkill('spxizhan_spfangzong')&&player.inRange(target)) return false; + targetEnabled: function (card, player, target) { + if ( + get.tag(card, "damage") > 0 && + !target.hasSkill("spxizhan_spfangzong") && + player.inRange(target) + ) + return false; }, }, }, - spxizhan:{ - audio:4, - group:'spxizhan_effect', - locked:false, - subSkill:{ - spfangzong:{charlotte:true}, - effect:{ - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - return player!=event.player; + spxizhan: { + audio: 4, + group: "spxizhan_effect", + locked: false, + subSkill: { + spfangzong: { charlotte: true }, + effect: { + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + return player != event.player; }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' - player.chooseToDiscard('he','嬉战:弃置一张牌或失去1点体力','根据弃置的牌对'+get.translation(trigger.player)+'视为使用如下牌:
              ♠,其使用【酒】;♥,你使用【无中生有】
              ♣,对其使用【铁索连环】;♦:对其使用火【杀】').set('ai',function(card){ - var player=_status.event.player,target=_status.event.getTrigger().player; - var suit=get.suit(card,player),list; - switch(suit){ - case 'spade':list=[{name:'jiu'},target,target];break; - case 'heart':list=[{name:'wuzhong'},player,player];break; - case 'club':list=[{name:'tiesuo'},player,target];break; - case 'diamond':list=[{name:'sha',nature:'fire'},player,target];break; - } - list[0].isCard=true; - var eff=0; - if(list[1].canUse(list[0],list[2],false)) eff=get.effect(list[2],list[0],list[1],player); - if(eff>=0||suit=='club') eff=Math.max(eff,5); - return eff*1.5-get.value(card); - }); - 'step 1' - if(result.bool){ - player.addTempSkill('spxizhan_spfangzong'); - var target=trigger.player,card=result.cards[0],suit=get.suit(card,player); - if(!lib.suit.includes(suit)||(!target||!target.isIn())&&suit!='heart') return; - game.broadcastAll(function(suit){ - if(lib.config.background_speak) game.playAudio('skill','spxizhan'+(4-lib.suit.indexOf(suit))); - },suit); - switch(suit){ - case 'spade': - target.chooseUseTarget('jiu',true); + forced: true, + logTarget: "player", + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + "嬉战:弃置一张牌或失去1点体力", + "根据弃置的牌对" + + get.translation(trigger.player) + + "视为使用如下牌:
              ♠,其使用【酒】;♥,你使用【无中生有】
              ♣,对其使用【铁索连环】;♦:对其使用火【杀】" + ) + .set("ai", function (card) { + var player = _status.event.player, + target = _status.event.getTrigger().player; + var suit = get.suit(card, player), + list; + switch (suit) { + case "spade": + list = [{ name: "jiu" }, target, target]; + break; + case "heart": + list = [{ name: "wuzhong" }, player, player]; + break; + case "club": + list = [{ name: "tiesuo" }, player, target]; + break; + case "diamond": + list = [{ name: "sha", nature: "fire" }, player, target]; + break; + } + list[0].isCard = true; + var eff = 0; + if (list[1].canUse(list[0], list[2], false)) + eff = get.effect(list[2], list[0], list[1], player); + if (eff >= 0 || suit == "club") eff = Math.max(eff, 5); + return eff * 1.5 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.addTempSkill("spxizhan_spfangzong"); + var target = trigger.player, + card = result.cards[0], + suit = get.suit(card, player); + if ( + !lib.suit.includes(suit) || + ((!target || !target.isIn()) && suit != "heart") + ) + return; + game.broadcastAll(function (suit) { + if (lib.config.background_speak) + game.playAudio("skill", "spxizhan" + (4 - lib.suit.indexOf(suit))); + }, suit); + switch (suit) { + case "spade": + target.chooseUseTarget("jiu", true); break; - case 'heart': - player.chooseUseTarget('wuzhong',true); + case "heart": + player.chooseUseTarget("wuzhong", true); break; - case 'club': - if(player.canUse('tiesuo',target)) player.useCard({ - name:'tiesuo', - isCard:true, - },target); + case "club": + if (player.canUse("tiesuo", target)) + player.useCard( + { + name: "tiesuo", + isCard: true, + }, + target + ); break; - case 'diamond': - if(player.canUse({ - name:'sha', - isCard:true, - nature:'fire', - },target,false)) player.useCard({ - name:'sha', - isCard:true, - nature:'fire', - },target,false); + case "diamond": + if ( + player.canUse( + { + name: "sha", + isCard: true, + nature: "fire", + }, + target, + false + ) + ) + player.useCard( + { + name: "sha", + isCard: true, + nature: "fire", + }, + target, + false + ); break; } - } - else player.loseHp(); + } else player.loseHp(); }, }, }, }, //高览 - spjungong:{ - enable:'phaseUse', - filter:function(event,player){ - var num=(player.getStat('skill').spjungong||0); - return (numplayer.hp) return num; - return [0,num]; + filterCard: true, + position: "he", + selectCard: function () { + var player = _status.event.player, + num = (player.getStat("skill").spjungong || 0) + 1; + if (ui.selected.cards.length || num > player.hp) return num; + return [0, num]; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - prompt:function(){ - var player=_status.event.player,num=get.cnNumber((player.getStat('skill').spjungong||0)+1); - return '弃置'+num+'张牌或失去'+num+'点体力,视为使用杀'; + prompt: function () { + var player = _status.event.player, + num = get.cnNumber((player.getStat("skill").spjungong || 0) + 1); + return "弃置" + num + "张牌或失去" + num + "点体力,视为使用杀"; }, - content:function(){ - 'step 0' - if(!cards.length) player.loseHp(player.getStat('skill').spjungong||1); - player.useCard({name:'sha',isCard:true},target,false); - 'step 1' - if(player.hasHistory('sourceDamage',function(evt){ - var card=evt.card; - if(!card||card.name!='sha') return false; - var evtx=evt.getParent('useCard'); - return evtx.card==card&&evtx.getParent()==event; - })) player.addTempSkill('spjungong_block'); + content: function () { + "step 0"; + if (!cards.length) player.loseHp(player.getStat("skill").spjungong || 1); + player.useCard({ name: "sha", isCard: true }, target, false); + "step 1"; + if ( + player.hasHistory("sourceDamage", function (evt) { + var card = evt.card; + if (!card || card.name != "sha") return false; + var evtx = evt.getParent("useCard"); + return evtx.card == card && evtx.getParent() == event; + }) + ) + player.addTempSkill("spjungong_block"); }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'},player)+1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }, player) + 1; }, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - return get.effect(target,{name:'sha'},player,target); + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + return get.effect(target, { name: "sha" }, player, target); }, }, }, - subSkill:{block:{charlotte:true}}, + subSkill: { block: { charlotte: true } }, }, - spdengli:{ - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + spdengli: { + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - frequent:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.player.hp==event.target.hp; + frequent: true, + filter: function (event, player) { + return event.card.name == "sha" && event.player.hp == event.target.hp; }, - content:function(){ + content: function () { player.draw(); }, - ai:{ - effect:{ - player:function(card,player,target){ - var hp=player.hp,evt=_status.event; - if(evt.name=='chooseToUse'&&evt.player==player&&evt.skill=='spjungong'&&!ui.selected.cards.length) hp-=((player.getStat('skill').spjungong||0)+1); - if(card&&card.name=='sha'&&hp==target.hp) return [1,0.3]; + ai: { + effect: { + player: function (card, player, target) { + var hp = player.hp, + evt = _status.event; + if ( + evt.name == "chooseToUse" && + evt.player == player && + evt.skill == "spjungong" && + !ui.selected.cards.length + ) + hp -= (player.getStat("skill").spjungong || 0) + 1; + if (card && card.name == "sha" && hp == target.hp) return [1, 0.3]; }, - target:function(card,player,target){ - if(card&&card.name=='sha'&&player.hp==target.hp) return [1,0.3]; + target: function (card, player, target) { + if (card && card.name == "sha" && player.hp == target.hp) return [1, 0.3]; }, }, }, }, //孙翊 - zaoli:{ - trigger:{player:'phaseBegin'}, - audio:2, - forced:true, - filter:function(event,player){ - return player.countMark('zaoli')>0; + zaoli: { + trigger: { player: "phaseBegin" }, + audio: 2, + forced: true, + filter: function (event, player) { + return player.countMark("zaoli") > 0; }, - content:function(){ - 'step 0' - event.num=player.storage.zaoli; - player.removeMark('zaoli',event.num); - if(player.countCards('he')>0){ - player.chooseToDiscard(true,'he',[1,Infinity],'躁厉:弃置至少一张牌').set('ai',function(card){ - if(card.hasGaintag('zaoli')) return 1; - return 5-get.value(card); - }); + content: function () { + "step 0"; + event.num = player.storage.zaoli; + player.removeMark("zaoli", event.num); + if (player.countCards("he") > 0) { + player + .chooseToDiscard(true, "he", [1, Infinity], "躁厉:弃置至少一张牌") + .set("ai", function (card) { + if (card.hasGaintag("zaoli")) return 1; + return 5 - get.value(card); + }); } - 'step 1' - if(result.bool) num+=result.cards.length; - if(event.num>2) player.loseHp(); + "step 1"; + if (result.bool) num += result.cards.length; + if (event.num > 2) player.loseHp(); player.draw(num); }, - mod:{ - cardEnabled2:function(card,player){ - if(player==_status.currentPhase&&get.itemtype(card)=='card'&&card.hasGaintag('zaoli')) return false; + mod: { + cardEnabled2: function (card, player) { + if ( + player == _status.currentPhase && + get.itemtype(card) == "card" && + card.hasGaintag("zaoli") + ) + return false; }, }, - group:['zaoli_add','zaoli_count'], - init:function(player){ - if(player==_status.currentPhase){ - var hs=player.getCards('h'); - player.getHistory('gain',function(evt){ + group: ["zaoli_add", "zaoli_count"], + init: function (player) { + if (player == _status.currentPhase) { + var hs = player.getCards("h"); + player.getHistory("gain", function (evt) { hs.removeArray(evt.cards); }); - if(hs.length) player.addGaintag(hs,'zaoli'); + if (hs.length) player.addGaintag(hs, "zaoli"); } }, - onremove:function(player){ - player.removeGaintag('zaoli'); + onremove: function (player) { + player.removeGaintag("zaoli"); delete player.storage.zaoli; }, - intro:{content:'mark'}, - subSkill:{ - add:{ - audio:'zaoli', - trigger:{player:['useCard','respond']}, - forced:true, - filter:function(event,player){ - return player.countMark('zaoli')<4&&player.hasHistory('lose',function(evt){ - return evt.hs&&evt.hs.length>0&&evt.getParent()==event; - }); + intro: { content: "mark" }, + subSkill: { + add: { + audio: "zaoli", + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter: function (event, player) { + return ( + player.countMark("zaoli") < 4 && + player.hasHistory("lose", function (evt) { + return evt.hs && evt.hs.length > 0 && evt.getParent() == event; + }) + ); }, - content:function(){ - player.addMark('zaoli',1); + content: function () { + player.addMark("zaoli", 1); }, }, - count:{ - trigger:{global:'phaseBeginStart'}, - forced:true, - firstDo:true, - silent:true, - filter:function(event,player){ - if(player==event.player) return player.countCards('h')>0; - return player.hasCard(function(card){ - return card.hasGaintag('zaoli'); - },'h'); + count: { + trigger: { global: "phaseBeginStart" }, + forced: true, + firstDo: true, + silent: true, + filter: function (event, player) { + if (player == event.player) return player.countCards("h") > 0; + return player.hasCard(function (card) { + return card.hasGaintag("zaoli"); + }, "h"); }, - content:function(){ - if(player==trigger.player){ - player.addGaintag(player.getCards('h'),'zaoli'); - } - else player.removeGaintag('zaoli'); + content: function () { + if (player == trigger.player) { + player.addGaintag(player.getCards("h"), "zaoli"); + } else player.removeGaintag("zaoli"); }, }, }, }, //王双 - yiyong:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&& - event.source&&event.source.isIn()&&player!=event.source - &&event.cards.filterInD().length>0&&player.getEquips(1).length>0; + yiyong: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.source && + event.source.isIn() && + player != event.source && + event.cards.filterInD().length > 0 && + player.getEquips(1).length > 0 + ); }, - check:function(event,player){ - var card={ - name:'sha', - cards:event.cards.filterInD(), - },target=event.source; - return !player.canUse(card,target,false)||get.effect(target,card,player,player)>0; + check: function (event, player) { + var card = { + name: "sha", + cards: event.cards.filterInD(), + }, + target = event.source; + return ( + !player.canUse(card, target, false) || get.effect(target, card, player, player) > 0 + ); }, - content:function(){ - 'step 0' - event.cards=trigger.cards.filterInD(); - player.gain(event.cards,'gain2'); - 'step 1' - var target=trigger.source,hs=player.getCards('h'); - if(target&&target.isIn()&&hs.length>=cards.length&&cards.filter(function(i){ - return hs.includes(i); - }).length==cards.length&&player.canUse({name:'sha',cards:cards},target,false)){ - var next=player.useCard({name:'sha'},cards,target,false); - if(!target.getEquips(1).length) next.baseDamage=2; + content: function () { + "step 0"; + event.cards = trigger.cards.filterInD(); + player.gain(event.cards, "gain2"); + "step 1"; + var target = trigger.source, + hs = player.getCards("h"); + if ( + target && + target.isIn() && + hs.length >= cards.length && + cards.filter(function (i) { + return hs.includes(i); + }).length == cards.length && + player.canUse({ name: "sha", cards: cards }, target, false) + ) { + var next = player.useCard({ name: "sha" }, cards, target, false); + if (!target.getEquips(1).length) next.baseDamage = 2; } }, }, - shanxie:{ - audio:2, - enable:'phaseUse', - usable:1, + shanxie: { + audio: 2, + enable: "phaseUse", + usable: 1, //filterTarget:function(card,player,target){ // return target!=player&&target.getEquip(1); //}, //selectTarget:[0,1], - content:function(){ - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'; + content: function () { + var card = get.cardPile2(function (card) { + return get.subtype(card) == "equip1"; }); - if(card) player.gain(card,'gain2'); - else{ - var targets=game.filterPlayer(function(current){ - return current.getEquips(1).length>0; + if (card) player.gain(card, "gain2"); + else { + var targets = game.filterPlayer(function (current) { + return current.getEquips(1).length > 0; }); - if(targets.length){ - var target=targets.randomGet(); - player.gain(target.getEquips(1),target,'give','bySelf'); + if (targets.length) { + var target = targets.randomGet(); + player.gain(target.getEquips(1), target, "give", "bySelf"); } } }, - content_old:function(){ - 'step 0' - if(!target){ - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'; + content_old: function () { + "step 0"; + if (!target) { + var card = get.cardPile2(function (card) { + return get.subtype(card) == "equip1"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); event.finish(); + } else { + var card = target.getEquip(1); + if (card) { + event.card = card; + player.gain(card, target, "give"); + } else event.finish(); } - else{ - var card=target.getEquip(1); - if(card){ - event.card=card; - player.gain(card,target,'give'); - } - else event.finish(); - } - 'step 1' - if(player.getCards('h').includes(card)&&get.type(card,player)=='equip'&&player.hasUseTarget(card)) player.chooseUseTarget(card,true,'nopopup'); - 'step 2' - var hs=target.getCards('h',function(card){ - return target.canUse(get.autoViewAs({name:'sha'},[card]),player,false); + "step 1"; + if ( + player.getCards("h").includes(card) && + get.type(card, player) == "equip" && + player.hasUseTarget(card) + ) + player.chooseUseTarget(card, true, "nopopup"); + "step 2"; + var hs = target.getCards("h", function (card) { + return target.canUse(get.autoViewAs({ name: "sha" }, [card]), player, false); }); - if(hs.length){ - if(hs.length==1) event._result={bool:true,cards:hs}; - else target.chooseCard('h',true,'将一张牌当做【杀】对'+get.translation(player)+'使用',function(card){ - return _status.event.cards.includes(card); - }).set('cards',hs).set('ai',function(card){ - return get.effect(_status.event.getParent().player,get.autoViewAs({name:'sha',},[card]),_status.event.player) - }) - } - else event.finish(); - 'step 3' - if(result.bool) target.useCard({name:'sha'},result.cards,player,false); + if (hs.length) { + if (hs.length == 1) event._result = { bool: true, cards: hs }; + else + target + .chooseCard( + "h", + true, + "将一张牌当做【杀】对" + get.translation(player) + "使用", + function (card) { + return _status.event.cards.includes(card); + } + ) + .set("cards", hs) + .set("ai", function (card) { + return get.effect( + _status.event.getParent().player, + get.autoViewAs({ name: "sha" }, [card]), + _status.event.player + ); + }); + } else event.finish(); + "step 3"; + if (result.bool) target.useCard({ name: "sha" }, result.cards, player, false); }, - ai:{ - order:9, - result:{player:1}, + ai: { + order: 9, + result: { player: 1 }, }, - group:['shanxie_exclude','shanxie_shan'], - subSkill:{ - exclude:{ - trigger:{global:'useCard'}, - forced:true, - locked:false, - filter:function(event,player){ - if(event.card.name!='shan'||event.getParent(2).player!=player) return false; - var num=get.number(event.card); - return !num||num<=player.getAttackRange()*2; + group: ["shanxie_exclude", "shanxie_shan"], + subSkill: { + exclude: { + trigger: { global: "useCard" }, + forced: true, + locked: false, + filter: function (event, player) { + if (event.card.name != "shan" || event.getParent(2).player != player) + return false; + var num = get.number(event.card); + return !num || num <= player.getAttackRange() * 2; }, - logTarget:'player', - content:function(){ - trigger.all_excluded=true; + logTarget: "player", + content: function () { + trigger.all_excluded = true; }, - sub:true + sub: true, }, - shan:{ - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.target.isAlive()&&event.card.name=='sha'; + shan: { + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.target.isAlive() && event.card.name == "sha"; }, - silent:true, - content:function(){ - trigger.target.addTempSkill('shanxie_banned'); - trigger.target.storage.shanxie_banned={ - card:trigger.card, - num:player.getAttackRange()*2 + silent: true, + content: function () { + trigger.target.addTempSkill("shanxie_banned"); + trigger.target.storage.shanxie_banned = { + card: trigger.card, + num: player.getAttackRange() * 2, }; }, - sub:true + sub: true, }, - banned:{ - init:function(player){ - player.storage.shanxie_banned={}; + banned: { + init: function (player) { + player.storage.shanxie_banned = {}; }, - onremove:function(player){ + onremove: function (player) { delete player.storage.shanxie_banned; }, - trigger:{global:'useCardEnd'}, - filter:function(event,player){ - return event.card==player.storage.shanxie_banned.card; + trigger: { global: "useCardEnd" }, + filter: function (event, player) { + return event.card == player.storage.shanxie_banned.card; }, - silent:true, - content:function(){ - player.removeSkill('shanxie_banned'); + silent: true, + content: function () { + player.removeSkill("shanxie_banned"); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(get.name(card)=='shan'){ - let num=get.number(card); - if(!num||num<=player.storage.shanxie_banned.num) return 'zeroplayertarget'; + ai: { + effect: { + player: function (card, player, target) { + if (get.name(card) == "shan") { + let num = get.number(card); + if (!num || num <= player.storage.shanxie_banned.num) + return "zeroplayertarget"; } - } - } - } + }, + }, + }, }, }, }, //吴景流兵 - liubing:{ - trigger:{player:'useCard1'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha'||!event.cards||!event.cards.length) return false; - var evt=event.getParent('phaseUse'); - return evt&&evt.player==player&&player.getHistory('useCard',function(evt2){ - return evt2.card.name=='sha'&&evt2.cards&&evt2.cards.length&&evt2.getParent('phaseUse')==evt; - }).indexOf(event)==0; + liubing: { + trigger: { player: "useCard1" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha" || !event.cards || !event.cards.length) return false; + var evt = event.getParent("phaseUse"); + return ( + evt && + evt.player == player && + player + .getHistory("useCard", function (evt2) { + return ( + evt2.card.name == "sha" && + evt2.cards && + evt2.cards.length && + evt2.getParent("phaseUse") == evt + ); + }) + .indexOf(event) == 0 + ); }, - content:function(){ - game.log(player,'将',trigger.card,'的花色改为','#y♦'); - trigger.card.suit='diamond'; - trigger.card.color='red'; + content: function () { + game.log(player, "将", trigger.card, "的花色改为", "#y♦"); + trigger.card.suit = "diamond"; + trigger.card.color = "red"; }, - group:'liubing_gain', - subSkill:{ - gain:{ - trigger:{global:'useCardAfter'}, - forced:true, - audio:'liubing', - filter:function(event,player){ - return event.player!=player&&event.card.isCard&&event.card.name=='sha'&& - get.color(event.card)=='black'&&event.cards.filterInD().length>0&& - event.player.isPhaseUsing()&&!event.player.hasHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }); + group: "liubing_gain", + subSkill: { + gain: { + trigger: { global: "useCardAfter" }, + forced: true, + audio: "liubing", + filter: function (event, player) { + return ( + event.player != player && + event.card.isCard && + event.card.name == "sha" && + get.color(event.card) == "black" && + event.cards.filterInD().length > 0 && + event.player.isPhaseUsing() && + !event.player.hasHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }) + ); }, - logTarget:'player', - content:function(){ - player.gain(trigger.cards.filterInD(),'gain2'); + logTarget: "player", + content: function () { + player.gain(trigger.cards.filterInD(), "gain2"); }, }, }, }, //新刘璋 - jutu:{ - audio:'xiusheng', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.yaohu&&game.hasPlayer(function(current){ - return current.group==player.storage.yaohu; - }); + jutu: { + audio: "xiusheng", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.storage.yaohu && + game.hasPlayer(function (current) { + return current.group == player.storage.yaohu; + }) + ); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('jutu'); - if(cards.length>0){ - player.gain(cards,'gain2'); + content: function () { + "step 0"; + var cards = player.getExpansions("jutu"); + if (cards.length > 0) { + player.gain(cards, "gain2"); } - 'step 1' - event.num=game.countPlayer(function(current){ - return current.group==player.storage.yaohu; + "step 1"; + event.num = game.countPlayer(function (current) { + return current.group == player.storage.yaohu; }); - player.draw(event.num+1); - if(!event.num) event.finish(); - 'step 2' - var he=player.getCards('he'); - if(!he.length) event.finish(); - else if(he.length0) return 1; - return 1.3; - }); - } - list.sort(function(a,b){ - return getn(b)-getn(a); - }); - return list[0]; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('yaohu',game.filterPlayer(function(current){ - return current.group==result.control; - })); - game.log(player,'选择了','#y'+get.translation(result.control+2)) - player.storage.yaohu=result.control; - player.markSkill('yaohu'); + if (!player.hasSkill("yaohu")) list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", "邀虎:请选择一个势力") + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var getn = function (group) { + return game.countPlayer(function (current) { + if (current.group != group) return false; + if (player == current) return 2; + if (get.attitude(current, player) > 0) return 1; + return 1.3; + }); + }; + list.sort(function (a, b) { + return getn(b) - getn(a); + }); + return list[0]; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill( + "yaohu", + game.filterPlayer(function (current) { + return current.group == result.control; + }) + ); + game.log(player, "选择了", "#y" + get.translation(result.control + 2)); + player.storage.yaohu = result.control; + player.markSkill("yaohu"); } }, - ai:{combo:'jutu'}, - intro:{content:'已选择了$势力'}, - group:'yaohu_gain', - subSkill:{ - round:{}, - gain:{ - audio:'yinlang', - trigger:{global:'phaseUseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.player!=player&&event.player.group==player.storage.yaohu&&event.player.isIn()&&player.getExpansions('jutu').length>0; + ai: { combo: "jutu" }, + intro: { content: "已选择了$势力" }, + group: "yaohu_gain", + subSkill: { + round: {}, + gain: { + audio: "yinlang", + trigger: { global: "phaseUseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + event.player != player && + event.player.group == player.storage.yaohu && + event.player.isIn() && + player.getExpansions("jutu").length > 0 + ); }, - logTarget:'player', - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - target.chooseButton(['选择获得一张“生”',player.getExpansions('jutu')],true).set('ai',function(button){ - return get.value(button.link,player); - }); - 'step 1' - if(result.bool){ - target.gain(result.links,'give',player,'bySelf'); - } - 'step 2' - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target; - })){ - player.chooseTarget(true,'选择'+get.translation(target)+'使用【杀】的目标',function(card,player,target){ - return target!=player&&target!=_status.event.source; - }).set('source',target).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,{name:'sha'},evt.source,evt.player); + logTarget: "player", + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + target + .chooseButton(["选择获得一张“生”", player.getExpansions("jutu")], true) + .set("ai", function (button) { + return get.value(button.link, player); }); + "step 1"; + if (result.bool) { + target.gain(result.links, "give", player, "bySelf"); } - else{ - event._result={bool:false}; + "step 2"; + if ( + game.hasPlayer(function (current) { + return current != player && current != target; + }) + ) { + player + .chooseTarget( + true, + "选择" + get.translation(target) + "使用【杀】的目标", + function (card, player, target) { + return target != player && target != _status.event.source; + } + ) + .set("source", target) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, { name: "sha" }, evt.source, evt.player); + }); + } else { + event._result = { bool: false }; event.goto(4); } - 'step 3' - var target2=result.targets[0]; - player.line(target2,'green'); - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'对'+get.translation(target2)+'使用一张杀,否则交给其两张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',target2).set('addCount',false); - 'step 4' - if(!result.bool){ - var hs=target.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length<=2) event._result={bool:true,cards:hs}; - else target.chooseCard(2,true,'交给'+get.translation(player)+'两张牌','he'); - } - else event.finish(); - 'step 5' - if(result.bool) target.give(result.cards,player); + "step 3"; + var target2 = result.targets[0]; + player.line(target2, "green"); + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "对" + get.translation(target2) + "使用一张杀,否则交给其两张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", target2) + .set("addCount", false); + "step 4"; + if (!result.bool) { + var hs = target.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length <= 2) event._result = { bool: true, cards: hs }; + else + target.chooseCard( + 2, + true, + "交给" + get.translation(player) + "两张牌", + "he" + ); + } else event.finish(); + "step 5"; + if (result.bool) target.give(result.cards, player); }, }, }, }, - rehuaibi:{ - audio:'huaibi', - zhuSkill:true, - mod:{ - maxHandcard:function(player,num){ - if(player.storage.yaohu&&player.hasZhuSkill('rehuaibi')) return num+game.countPlayer(function(current){ - return current.group==player.storage.yaohu; - }); + rehuaibi: { + audio: "huaibi", + zhuSkill: true, + mod: { + maxHandcard: function (player, num) { + if (player.storage.yaohu && player.hasZhuSkill("rehuaibi")) + return ( + num + + game.countPlayer(function (current) { + return current.group == player.storage.yaohu; + }) + ); }, }, - ai:{combo:'yaohu'}, + ai: { combo: "yaohu" }, }, //宗预 - zhibian:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer((current)=>(current!=player&&player.canCompare(current))); + zhibian: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer((current) => current != player && player.canCompare(current)); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhibian'),'与一名其他角色进行拼点',function(card,player,target){ - return target!=player&&player.canCompare(target); - }).set('ai',function(target){ - if(!_status.event.goon) return false; - var att=get.attitude(player,target); - if(att<0&&target.countCards('e',function(card){ - return player.canEquip(card)&&get.effect(player,card,target,player)>0; - })) return -att/Math.sqrt(target.countCards('h')); - if(!player.isDamaged()) return false; - if(att<=0) return (1-att)/Math.sqrt(target.countCards('h')); - return Math.sqrt(2/att*Math.sqrt(target.countCards('h'))); - }).set('goon',function(){ - if(!player.hasCard(function(card){ - return (card.number>=14-player.hp&&get.value(card)<=5); - })) return false; - return true; - }()); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('zhibian',target); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhibian"), + "与一名其他角色进行拼点", + function (card, player, target) { + return target != player && player.canCompare(target); + } + ) + .set("ai", function (target) { + if (!_status.event.goon) return false; + var att = get.attitude(player, target); + if ( + att < 0 && + target.countCards("e", function (card) { + return ( + player.canEquip(card) && get.effect(player, card, target, player) > 0 + ); + }) + ) + return -att / Math.sqrt(target.countCards("h")); + if (!player.isDamaged()) return false; + if (att <= 0) return (1 - att) / Math.sqrt(target.countCards("h")); + return Math.sqrt((2 / att) * Math.sqrt(target.countCards("h"))); + }) + .set( + "goon", + (function () { + if ( + !player.hasCard(function (card) { + return card.number >= 14 - player.hp && get.value(card) <= 5; + }) + ) + return false; + return true; + })() + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("zhibian", target); player.chooseToCompare(target); - } - else event.finish(); - 'step 2' - if(result.bool){ - var list=[],list2=[ - '将'+get.translation(target)+'装备区/判定区中的一张牌移动到你的区域内', - '回复1点体力', - '背水!跳过摸牌阶段,并依次执行上述所有选项', - ]; - if(target.hasCard(function(card){ - return player.canEquip(card); - },'e')||target.hasCard(function(card){ - return player.canAddJudge(card); - },'j')){ - list.push('选项一'); + } else event.finish(); + "step 2"; + if (result.bool) { + var list = [], + list2 = [ + "将" + get.translation(target) + "装备区/判定区中的一张牌移动到你的区域内", + "回复1点体力", + "背水!跳过摸牌阶段,并依次执行上述所有选项", + ]; + if ( + target.hasCard(function (card) { + return player.canEquip(card); + }, "e") || + target.hasCard(function (card) { + return player.canAddJudge(card); + }, "j") + ) { + list.push("选项一"); } - if(player.isDamaged()){ - list.push('选项二'); + if (player.isDamaged()) { + list.push("选项二"); } - if(list.includes('选项一')) list.push('背水!') - list.push('cancel2'); - player.chooseControl(list).set('choiceList',list2).set('ai',function(target){ - if(player.isDamaged()&&(player.hp<=2||!target.countCards('e',function(card){ - return player.canEquip(card)&&get.value(card,target)>=4+player.getDamagedHp(); - }))) return 1; - return 0; - }); - } - else{ + if (list.includes("选项一")) list.push("背水!"); + list.push("cancel2"); + player + .chooseControl(list) + .set("choiceList", list2) + .set("ai", function (target) { + if ( + player.isDamaged() && + (player.hp <= 2 || + !target.countCards("e", function (card) { + return ( + player.canEquip(card) && + get.value(card, target) >= 4 + player.getDamagedHp() + ); + })) + ) + return 1; + return 0; + }); + } else { player.loseHp(); event.finish(); } - 'step 3' - if(result.control!='cancel2'){ - event.control=result.control; - if(result.control=='选项一'||result.control=='背水!'){ - player.choosePlayerCard(target,'ej',true).set('ai',get.buttonValue); - } - else event.goto(5); - } - else event.finish(); - 'step 4' - if(result.bool){ - var card=result.cards[0]; - target.$give(card,player,false); + "step 3"; + if (result.control != "cancel2") { + event.control = result.control; + if (result.control == "选项一" || result.control == "背水!") { + player.choosePlayerCard(target, "ej", true).set("ai", get.buttonValue); + } else event.goto(5); + } else event.finish(); + "step 4"; + if (result.bool) { + var card = result.cards[0]; + target.$give(card, player, false); game.delayx(); - if(get.position(card)=='e') player.equip(card); + if (get.position(card) == "e") player.equip(card); else player.addJudge(card); } - 'step 5' - if(event.control=='选项二'||event.control=='背水!'){ + "step 5"; + if (event.control == "选项二" || event.control == "背水!") { player.recover(); } - if(event.control=='背水!') player.skip('phaseDraw'); + if (event.control == "背水!") player.skip("phaseDraw"); }, }, - yuyan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.card.name=='sha'&&event.card.isCard&&typeof get.number(event.card)=='number'&&player.hp=13||!trigger.player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.number(card)>num; - },'he')) event._result={bool:false}; - else trigger.player.chooseCard('he',function(card){ - return get.number(card)>_status.event.number; - },'交给'+get.translation(player)+'一张点数大于'+get.cnNumber(num)+'的牌,或令'+get.translation(trigger.card)+'对其无效').set('number',num).set('',function(card){ - if(card.name=='shan'||card.name=='tao'||card.name=='jiu') return false; - return 6-get.value(card); - }); - 'step 1' - if(result.bool){ - trigger.player.give(result.cards,player); - } - else{ + content: function () { + "step 0"; + var num = get.number(trigger.card); + if ( + num >= 13 || + !trigger.player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.number(card) > num; + }, "he") + ) + event._result = { bool: false }; + else + trigger.player + .chooseCard( + "he", + function (card) { + return get.number(card) > _status.event.number; + }, + "交给" + + get.translation(player) + + "一张点数大于" + + get.cnNumber(num) + + "的牌,或令" + + get.translation(trigger.card) + + "对其无效" + ) + .set("number", num) + .set("", function (card) { + if (card.name == "shan" || card.name == "tao" || card.name == "jiu") + return false; + return 6 - get.value(card); + }); + "step 1"; + if (result.bool) { + trigger.player.give(result.cards, player); + } else { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&player.hp>target.hp&&get.attitude(player,target)<0){ - var num=get.number(card); - if(typeof num!='number') return false; - var bs=player.getCards('h',function(cardx){ - return (get.number(cardx)>num&&!['','',''].includes(cardx.name)); + ai: { + effect: { + target: function (card, player, target, current) { + if ( + card.name == "sha" && + player.hp > target.hp && + get.attitude(player, target) < 0 + ) { + var num = get.number(card); + if (typeof num != "number") return false; + var bs = player.getCards("h", function (cardx) { + return get.number(cardx) > num && !["", "", ""].includes(cardx.name); }); - if(bs.length<2) return 0; - if(player.hasSkill('jiu')||player.hasSkill('tianxianjiu')) return; - if(bs.length<=2){ - for(var i=0;ievent.target.hp&&event.targets.length==1&&event.player.countCards('h')>0&&!event.target.isDying()&& - !event.player.hasSkillTag('noCompareTarget')&&!player.hasSkillTag('noCompareSource')); + qingjue: { + audio: 2, + trigger: { global: "useCardToPlayer" }, + logTarget: "player", + round: 1, + filter: function (event, player) { + return ( + event.player != player && + event.target != player && + event.player != event.target && + event.player.hp > event.target.hp && + event.targets.length == 1 && + event.player.countCards("h") > 0 && + !event.target.isDying() && + !event.player.hasSkillTag("noCompareTarget") && + !player.hasSkillTag("noCompareSource") + ); }, - check:function(event,player){ - var target=event.target,source=event.player; - var eff1=get.effect(target,event.card,source,player); - if(eff1>=0) return false; - var eff2=get.effect(player,event.card,source,player); - if(eff2>=0) return true; - if(eff2>eff1/3) return player.hasCard(function(card){ - return (card.number>=9&&get.value(card)<=5)||get.value(card)<=3; - }); - if(eff2>eff1/2) return player.hasCard(function(card){ - return card.number>10&&get.value(card)<=5; - }); - return player.hasCard(function(card){ - return card.number>11&&get.value(card)<=5; + check: function (event, player) { + var target = event.target, + source = event.player; + var eff1 = get.effect(target, event.card, source, player); + if (eff1 >= 0) return false; + var eff2 = get.effect(player, event.card, source, player); + if (eff2 >= 0) return true; + if (eff2 > eff1 / 3) + return player.hasCard(function (card) { + return (card.number >= 9 && get.value(card) <= 5) || get.value(card) <= 3; + }); + if (eff2 > eff1 / 2) + return player.hasCard(function (card) { + return card.number > 10 && get.value(card) <= 5; + }); + return player.hasCard(function (card) { + return card.number > 11 && get.value(card) <= 5; }); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.canCompare(trigger.player)) player.chooseToCompare(trigger.player); + "step 1"; + if (player.canCompare(trigger.player)) player.chooseToCompare(trigger.player); else event.finish(); - 'step 2' + "step 2"; trigger.targets.remove(trigger.target); trigger.getParent().triggeredTargets1.remove(trigger.target); trigger.untrigger(); - if(!result.bool) trigger.targets.push(player); + if (!result.bool) trigger.targets.push(player); }, }, - fengjie:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return game.hasPlayer((current)=>(current!=player)); + fengjie: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return game.hasPlayer((current) => current != player); }, - content:function(){ - 'step 0' - player.chooseTarget('请选择【奉节】的目标','选择一名其他角色并获得如下效果直到你下回合开始:一名角色的结束阶段开始时,你将手牌摸至(至多摸至四张)或弃置至与其体力值相等。',lib.filter.notMe,true).set('ai',function(target){ - return (target.hp-player.countCards('h'))/get.threaten(target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'选择了',target); - player.storage.fengjie2=target; - player.addTempSkill('fengjie2',{player:'phaseBegin'}); + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【奉节】的目标", + "选择一名其他角色并获得如下效果直到你下回合开始:一名角色的结束阶段开始时,你将手牌摸至(至多摸至四张)或弃置至与其体力值相等。", + lib.filter.notMe, + true + ) + .set("ai", function (target) { + return (target.hp - player.countCards("h")) / get.threaten(target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "选择了", target); + player.storage.fengjie2 = target; + player.addTempSkill("fengjie2", { player: "phaseBegin" }); game.delayx(); } }, }, - fengjie2:{ - audio:'fengjie', - trigger:{global:'phaseJieshuBegin'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - if(!player.storage.fengjie2||!player.storage.fengjie2.isIn()) return false; - var num1=player.countCards('h'),num2=player.storage.fengjie2.hp; - return num1!=num2; + fengjie2: { + audio: "fengjie", + trigger: { global: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + if (!player.storage.fengjie2 || !player.storage.fengjie2.isIn()) return false; + var num1 = player.countCards("h"), + num2 = player.storage.fengjie2.hp; + return num1 != num2; }, - logTarget:(event,player)=>player.storage.fengjie2, - content:function(){ - var num1=player.countCards('h'),num2=player.storage.fengjie2.hp; - if(num1>num2) player.chooseToDiscard('h',true,num1-num2); - else player.drawTo(Math.min(num1+4,num2)); + logTarget: (event, player) => player.storage.fengjie2, + content: function () { + var num1 = player.countCards("h"), + num2 = player.storage.fengjie2.hp; + if (num1 > num2) player.chooseToDiscard("h", true, num1 - num2); + else player.drawTo(Math.min(num1 + 4, num2)); }, }, //陈武董袭 - spyilie:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('选项一','选项二','背水!','cancel2').set('choiceList',[ - '本阶段内使用【杀】的次数上限+1', - '本回合内使用【杀】被【闪】抵消时摸一张牌', - '背水!失去1点体力并依次执行上述所有选项', - ]).set('ai',function(){ - if(player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card); - })>player.getCardUsable({name:'sha'})) return 0; - return 1; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('spyilie'); - game.log(player,'选择了','#g【毅烈】','的','#y'+result.control); - if(result.index%2==0) player.addTempSkill('spyilie_add','phaseUseEnd'); - if(result.index>0) player.addTempSkill('spyilie_miss'); - if(result.index==2) player.loseHp(); + spyilie: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseControl("选项一", "选项二", "背水!", "cancel2") + .set("choiceList", [ + "本阶段内使用【杀】的次数上限+1", + "本回合内使用【杀】被【闪】抵消时摸一张牌", + "背水!失去1点体力并依次执行上述所有选项", + ]) + .set("ai", function () { + if ( + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) > player.getCardUsable({ name: "sha" }) + ) + return 0; + return 1; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("spyilie"); + game.log(player, "选择了", "#g【毅烈】", "的", "#y" + result.control); + if (result.index % 2 == 0) player.addTempSkill("spyilie_add", "phaseUseEnd"); + if (result.index > 0) player.addTempSkill("spyilie_miss"); + if (result.index == 2) player.loseHp(); } }, - subSkill:{ - add:{ - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + subSkill: { + add: { + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, - miss:{ - charlotte:true, - audio:'spyilie', - trigger:{player:'shaMiss'}, - forced:true, - content:function(){ + miss: { + charlotte: true, + audio: "spyilie", + trigger: { player: "shaMiss" }, + forced: true, + content: function () { player.draw(); }, }, }, }, - spfenming:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:(event,player)=>game.hasPlayer((current)=>lib.skill.spfenming.filterTarget(null,player,current)), - filterTarget:function(card,player,target){ - if(target.hp>player.hp) return false; - return !target.isLinked()||target.hasCard(function(card){ - return lib.filter.canBeGained(card,player,target); - },target==player?'e':'he'); + spfenming: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: (event, player) => + game.hasPlayer((current) => lib.skill.spfenming.filterTarget(null, player, current)), + filterTarget: function (card, player, target) { + if (target.hp > player.hp) return false; + return ( + !target.isLinked() || + target.hasCard( + function (card) { + return lib.filter.canBeGained(card, player, target); + }, + target == player ? "e" : "he" + ) + ); }, - content:function(){ - if(!target.isLinked()) target.link(); - else player.gainPlayerCard(target,target==player?'e':'he',true); + content: function () { + if (!target.isLinked()) target.link(); + else player.gainPlayerCard(target, target == player ? "e" : "he", true); }, - ai:{ - order:7, - result:{ - player:function(player,target){ - if(!target.isLinked()) return get.effect(target,{name:'tiesuo'},player,player); - return get.effect(target,{name:'shunshou_copy2'},player,player); + ai: { + order: 7, + result: { + player: function (player, target) { + if (!target.isLinked()) + return get.effect(target, { name: "tiesuo" }, player, player); + return get.effect(target, { name: "shunshou_copy2" }, player, player); }, }, }, }, //周处 - rechuhai:{ - audio:'chuhai', - dutySkill:true, - locked:false, - group:['rechuhai_add','rechuhai_achieve','rechuhai_fail','rechuhai_chuhai'], - derivation:'zhangming', - subSkill:{ - chuhai:{ - audio:['chuhai',2], - inherit:'chuhai', - prompt:'与一名其他角色进行拼点', + rechuhai: { + audio: "chuhai", + dutySkill: true, + locked: false, + group: ["rechuhai_add", "rechuhai_achieve", "rechuhai_fail", "rechuhai_chuhai"], + derivation: "zhangming", + subSkill: { + chuhai: { + audio: ["chuhai", 2], + inherit: "chuhai", + prompt: "与一名其他角色进行拼点", }, - add:{ - trigger:{player:'compare'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.getParent().name=='rechuhai_chuhai'&&event.num1<13&&player.countCards('e')<4; + add: { + trigger: { player: "compare" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.getParent().name == "rechuhai_chuhai" && + event.num1 < 13 && + player.countCards("e") < 4 + ); }, - content:function(){ - var num=4-player.countCards('e'); - game.log(player,'的拼点牌点数+',num); - trigger.num1=Math.min(13,trigger.num1+num); + content: function () { + var num = 4 - player.countCards("e"); + game.log(player, "的拼点牌点数+", num); + trigger.num1 = Math.min(13, trigger.num1 + num); }, }, - achieve:{ - audio:['chuhai',2], - trigger:{player:'equipAfter'}, - forced:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - return player.countCards('e')>2; + achieve: { + audio: ["chuhai", 2], + trigger: { player: "equipAfter" }, + forced: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + return player.countCards("e") > 2; }, - content:function(){ - player.awakenSkill('rechuhai'); - game.log(player,'成功完成使命'); - if(player.isDamaged()) player.recover(player.maxHp-player.hp); - player.changeSkills(['zhangming'],['xianghai']); + content: function () { + player.awakenSkill("rechuhai"); + game.log(player, "成功完成使命"); + if (player.isDamaged()) player.recover(player.maxHp - player.hp); + player.changeSkills(["zhangming"], ["xianghai"]); }, }, - fail:{ - audio:'chuhai3', - trigger:{player:'chooseToCompareAfter'}, - forced:true, - filter:function(event,player){ - return event.getParent().name=='rechuhai_chuhai'&&event.num1<7&&!event.result.bool; + fail: { + audio: "chuhai3", + trigger: { player: "chooseToCompareAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.getParent().name == "rechuhai_chuhai" && + event.num1 < 7 && + !event.result.bool + ); }, - content:function(){ - player.awakenSkill('rechuhai'); - game.log(player,'使命失败'); + content: function () { + player.awakenSkill("rechuhai"); + game.log(player, "使命失败"); }, }, }, }, - chuhai3:{audio:true}, - zhangming:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return get.suit(event.card)=='club'; + chuhai3: { audio: true }, + zhangming: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return get.suit(event.card) == "club"; }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player; - })); + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player; + }) + ); }, - group:'zhangming_damage', - subSkill:{ - damage:{ - audio:'zhangming', - trigger:{source:'damageEnd'}, - forced:true, - usable:1, - filter:function(event,player){ - return player!=event.player; + group: "zhangming_damage", + subSkill: { + damage: { + audio: "zhangming", + trigger: { source: "damageEnd" }, + forced: true, + usable: 1, + filter: function (event, player) { + return player != event.player; }, - logTarget:'player', - content:function(){ - var list=[],cards=[],target=trigger.player,hs=target.getCards('h'); - if(hs.length>0){ - var card=hs.randomGet(); - list.push(get.type2(card,target)); - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【彰名】'); + logTarget: "player", + content: function () { + var list = [], + cards = [], + target = trigger.player, + hs = target.getCards("h"); + if (hs.length > 0) { + var card = hs.randomGet(); + list.push(get.type2(card, target)); + player.showCards( + card, + get.translation(player) + + "对" + + get.translation(target) + + "发动了【彰名】" + ); } target.discard(card); - for(var i=0;iplayer.canCompare(target,true)); + chuhai: { + audio: 3, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((target) => player.canCompare(target, true)); }, - filterTarget:function(card,player,target){ - return player.canCompare(target,true); + filterTarget: function (card, player, target) { + return player.canCompare(target, true); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.canCompare(target)) player.chooseToCompare(target); + "step 1"; + if (player.canCompare(target)) player.chooseToCompare(target); else event.finish(); - 'step 2' - if(result.bool){ - player.storage.chuhai2=target; - player.addTempSkill('chuhai2','phaseUseEnd'); - if(target.countCards('h')>0){ + "step 2"; + if (result.bool) { + player.storage.chuhai2 = target; + player.addTempSkill("chuhai2", "phaseUseEnd"); + if (target.countCards("h") > 0) { player.viewHandcards(target); - var types=[],cards=[],hs=target.getCards('h'); - for(var i of hs){ - types.add(get.type2(i,target)); + var types = [], + cards = [], + hs = target.getCards("h"); + for (var i of hs) { + types.add(get.type2(i, target)); } - for(var i of types){ - var card=get.cardPile(function(card){ - return get.type2(card,false)==i; + for (var i of types) { + var card = get.cardPile(function (card) { + return get.type2(card, false) == i; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2','log'); + if (cards.length) player.gain(cards, "gain2", "log"); } } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(player.countCards('hs',function(card){ - return get.tag(card,'damage')>0&&player.canUse(card,target,null,true)&& - get.effect(target,card,player,player)>0&&player.hasValueTarget(card,null,true); - })>0) return -3; + ai: { + order: 9, + result: { + target: function (player, target) { + if ( + player.countCards("hs", function (card) { + return ( + get.tag(card, "damage") > 0 && + player.canUse(card, target, null, true) && + get.effect(target, card, player, player) > 0 && + player.hasValueTarget(card, null, true) + ); + }) > 0 + ) + return -3; return -1; }, }, }, }, - chuhai2:{ - trigger:{source:'damageSource'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - if(event.player!=player.storage.chuhai2) return false; - for(var i=1;i<6;i++){ - if(player.hasEmptySlot(i)) return true; + chuhai2: { + trigger: { source: "damageSource" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + if (event.player != player.storage.chuhai2) return false; + for (var i = 1; i < 6; i++) { + if (player.hasEmptySlot(i)) return true; } return false; }, - content:function(){ - for(var i=1;i<7;i++){ - if(player.hasEmptySlot(i)){ - var sub='equip'+i,card=get.cardPile(function(card){ - return get.subtype(card,false)==sub&&!get.cardtag(card,'gifts')&&player.canEquip(card); - }); - if(card){ + content: function () { + for (var i = 1; i < 7; i++) { + if (player.hasEmptySlot(i)) { + var sub = "equip" + i, + card = get.cardPile(function (card) { + return ( + get.subtype(card, false) == sub && + !get.cardtag(card, "gifts") && + player.canEquip(card) + ); + }); + if (card) { player.$gain2(card); game.delayx(); player.equip(card); @@ -2347,2951 +3013,3512 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //文鸯 - dbquedi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - direct:true, - usable:1, - filter:function(event,player){ - return (event.card.name=='sha'||event.card.name=='juedou')&&event.targets.length==1&& - (event.target.countGainableCards(player,'h')>0||player.hasCard(function(i){ - return _status.connectMode||get.type(i,player)=='basic'&&lib.filter.cardDiscardable(i,player,'dbquedi'); - },'h')); + dbquedi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + usable: 1, + filter: function (event, player) { + return ( + (event.card.name == "sha" || event.card.name == "juedou") && + event.targets.length == 1 && + (event.target.countGainableCards(player, "h") > 0 || + player.hasCard(function (i) { + return ( + _status.connectMode || + (get.type(i, player) == "basic" && + lib.filter.cardDiscardable(i, player, "dbquedi")) + ); + }, "h")) + ); }, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - var list=[]; - if(target.countGainableCards(player,'h')>0) list.push('选项一'); - if(player.hasCard(function(i){ - return get.type(i,player)=='basic'&&lib.filter.cardDiscardable(i,player,'dbquedi'); - },'h')) list.push('选项二'); - list.push('背水!'); - list.push('cancel2'); - player.chooseControl(list).set('choiceList',[ - '获得'+get.translation(target)+'的一张手牌', - '弃置一张基本牌并令'+get.translation(trigger.card)+'伤害+1', - '背水!减1点体力上限并执行所有选项', - ]).set('prompt',get.prompt('dbquedi',target)).set('ai',function(){ - var evt=_status.event.getTrigger(),player=evt.player,target=evt.target,card=evt.card; - if(get.attitude(player,target)>0) return 'cancel2'; - var bool1=target.countGainableCards(player,'h')>0; - var bool2=player.hasCard(function(i){ - return get.type(i,player)=='basic'&&lib.filter.cardDiscardable(i,player,'dbquedi')&&get.value(card,player)<5; - },'h')&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + var list = []; + if (target.countGainableCards(player, "h") > 0) list.push("选项一"); + if ( + player.hasCard(function (i) { + return ( + get.type(i, player) == "basic" && + lib.filter.cardDiscardable(i, player, "dbquedi") + ); + }, "h") + ) + list.push("选项二"); + list.push("背水!"); + list.push("cancel2"); + player + .chooseControl(list) + .set("choiceList", [ + "获得" + get.translation(target) + "的一张手牌", + "弃置一张基本牌并令" + get.translation(trigger.card) + "伤害+1", + "背水!减1点体力上限并执行所有选项", + ]) + .set("prompt", get.prompt("dbquedi", target)) + .set("ai", function () { + var evt = _status.event.getTrigger(), + player = evt.player, + target = evt.target, + card = evt.card; + if (get.attitude(player, target) > 0) return "cancel2"; + var bool1 = target.countGainableCards(player, "h") > 0; + var bool2 = + player.hasCard(function (i) { + return ( + get.type(i, player) == "basic" && + lib.filter.cardDiscardable(i, player, "dbquedi") && + get.value(card, player) < 5 + ); + }, "h") && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }); + if ( + bool1 && + bool2 && + (target.hp <= 2 || (player.isDamaged() && player.maxHp > 3)) + ) + return "背水!"; + if (bool1) return "选项一"; + if (bool2) return "选项二"; + return "cancel2"; }); - if(bool1&&bool2&&(target.hp<=2||(player.isDamaged()&&player.maxHp>3))) return '背水!'; - if(bool1) return '选项一'; - if(bool2) return '选项二'; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dbquedi',target); - event.control=result.control; - if(event.control=='背水!') player.loseMaxHp(); - } - else{ + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dbquedi", target); + event.control = result.control; + if (event.control == "背水!") player.loseMaxHp(); + } else { player.storage.counttrigger.dbquedi--; event.finish(); } - 'step 2' - if((event.control=='选项一'||event.control=='背水!')&&target.countGainableCards(player,'h')>0) player.gainPlayerCard(target,true,'h'); - 'step 3' - if((event.control=='选项二'||event.control=='背水!')&&player.hasCard(function(i){ - return get.type(i,player)=='basic'&&lib.filter.cardDiscardable(i,player,'dbquedi'); - },'h')){ - player.chooseToDiscard('h','弃置一张基本牌',{type:'basic'},true); - } - else event.finish(); - 'step 4' - if(result.bool) trigger.getParent().baseDamage++; + "step 2"; + if ( + (event.control == "选项一" || event.control == "背水!") && + target.countGainableCards(player, "h") > 0 + ) + player.gainPlayerCard(target, true, "h"); + "step 3"; + if ( + (event.control == "选项二" || event.control == "背水!") && + player.hasCard(function (i) { + return ( + get.type(i, player) == "basic" && + lib.filter.cardDiscardable(i, player, "dbquedi") + ); + }, "h") + ) { + player.chooseToDiscard("h", "弃置一张基本牌", { type: "basic" }, true); + } else event.finish(); + "step 4"; + if (result.bool) trigger.getParent().baseDamage++; }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(tag!=='directHit_ai'||!arg||!arg.card||!arg.target||(arg.card.name!='sha'&&arg.card.name!='juedou')) return false; - if(player.storage.counttrigger&&player.storage.counttrigger.dbquedi&&player.storage.counttrigger.dbquedi>0) return false; - if(arg.target.countCards('h')==1&&(arg.card.name!='sha'||!arg.target.hasSkillTag('freeShan',false,{ - player:player, - card:arg.card - })||player.hasSkillTag('unequip',false,{ - name:arg.card?arg.card.name:null, - target:arg.target, - card:arg.card - })||player.hasSkillTag('unequip_ai',false,{ - name:arg.card?arg.card.name:null, - target:arg.target, - card:arg.card - }))) return true; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + tag !== "directHit_ai" || + !arg || + !arg.card || + !arg.target || + (arg.card.name != "sha" && arg.card.name != "juedou") + ) + return false; + if ( + player.storage.counttrigger && + player.storage.counttrigger.dbquedi && + player.storage.counttrigger.dbquedi > 0 + ) + return false; + if ( + arg.target.countCards("h") == 1 && + (arg.card.name != "sha" || + !arg.target.hasSkillTag("freeShan", false, { + player: player, + card: arg.card, + }) || + player.hasSkillTag("unequip", false, { + name: arg.card ? arg.card.name : null, + target: arg.target, + card: arg.card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: arg.card ? arg.card.name : null, + target: arg.target, + card: arg.card, + })) + ) + return true; return false; }, }, }, - dbzhuifeng:{ - audio:2, - groupSkill:true, - enable:'chooseToUse', - usable:2, - viewAsFilter:function(player){ - return player.group=='wei'&&player.hp>0; + dbzhuifeng: { + audio: 2, + groupSkill: true, + enable: "chooseToUse", + usable: 2, + viewAsFilter: function (player) { + return player.group == "wei" && player.hp > 0; }, - viewAs:{name:'juedou',isCard:true}, - filterCard:()=>false, - selectCard:-1, - log:false, - precontent:function(){ - 'step 0' - player.logSkill('dbzhuifeng'); + viewAs: { name: "juedou", isCard: true }, + filterCard: () => false, + selectCard: -1, + log: false, + precontent: function () { + "step 0"; + player.logSkill("dbzhuifeng"); player.loseHp(); - event.forceDie=true; - 'step 1' + event.forceDie = true; + "step 1"; //特殊处理 - if(player.isDead()){ - player.useResult(event.result,event.getParent()).forceDie=true; + if (player.isDead()) { + player.useResult(event.result, event.getParent()).forceDie = true; } }, - ai:{ - order:function(){ - return get.order({name:'juedou'})-0.5; + ai: { + order: function () { + return get.order({ name: "juedou" }) - 0.5; }, }, - group:'dbzhuifeng_self', - subSkill:{ - self:{ - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - var evt=event.getParent(); - return evt.skill=='dbzhuifeng'&&evt.player==player; + group: "dbzhuifeng_self", + subSkill: { + self: { + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + var evt = event.getParent(); + return evt.skill == "dbzhuifeng" && evt.player == player; }, - content:function(){ + content: function () { trigger.cancel(); - player.getStat().skill.dbzhuifeng=2; + player.getStat().skill.dbzhuifeng = 2; }, }, }, }, - dbchongjian:{ - audio:2, - groupSkill:true, - hiddenCard:function(player,name){ - if(player.group=='wu'&&(name=='sha'||name=='jiu')&&player.hasCard(function(card){ - return get.type(card)=='equip'; - },'hes')) return true; + dbchongjian: { + audio: 2, + groupSkill: true, + hiddenCard: function (player, name) { + if ( + player.group == "wu" && + (name == "sha" || name == "jiu") && + player.hasCard(function (card) { + return get.type(card) == "equip"; + }, "hes") + ) + return true; return false; }, - enable:'chooseToUse', - filter:function(event,player){ - return player.group=='wu'&&player.hasCard(function(card){ - return get.type(card)=='equip'; - },'hes')&&(event.filterCard({name:'sha'},player,event)||event.filterCard({name:'jiu'},player,event)); + enable: "chooseToUse", + filter: function (event, player) { + return ( + player.group == "wu" && + player.hasCard(function (card) { + return get.type(card) == "equip"; + }, "hes") && + (event.filterCard({ name: "sha" }, player, event) || + event.filterCard({ name: "jiu" }, player, event)) + ); }, - locked:false, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.dbchongjian) return true; + locked: false, + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.dbchongjian) return true; }, }, - chooseButton:{ - dialog:function(){ - var list=[]; - list.push(['基本','','sha']); - for(var i of lib.inpile_nature) list.push(['基本','','sha',i]); - list.push(['基本','','jiu']); - return ui.create.dialog('冲坚',[list,'vcard']); + chooseButton: { + dialog: function () { + var list = []; + list.push(["基本", "", "sha"]); + for (var i of lib.inpile_nature) list.push(["基本", "", "sha", i]); + list.push(["基本", "", "jiu"]); + return ui.create.dialog("冲坚", [list, "vcard"]); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard({name:button.link[2],nature:button.link[3],isCard:true},player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard( + { name: button.link[2], nature: button.link[3], isCard: true }, + player, + evt + ); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; - if(button.link[2]=='jiu'&&(player.hasCard(function(card){ - return get.name(card)=='sha'; - },'hs')||player.countCards('hes',function(card){ - if(get.type(card)!='equip') return false; - if(get.position(card)=='e'){ - if(player.hasSkillTag('noe')) return (10-get.value(card))>0; - var sub=get.subtype(card); - if(player.hasCard(function(card){ - return get.subtype(card)==sub&&player.canUse(card,player)&&get.effect(player,card,player,player)>0; - },'hs')) return (10-get.value(card))>0; - } - return (5-get.value(card))>0; - })>1)) return player.getUseValue({name:'jiu'})*4; - return player.getUseValue({name:button.link[2],nature:button.link[3]},false); + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; + if ( + button.link[2] == "jiu" && + (player.hasCard(function (card) { + return get.name(card) == "sha"; + }, "hs") || + player.countCards("hes", function (card) { + if (get.type(card) != "equip") return false; + if (get.position(card) == "e") { + if (player.hasSkillTag("noe")) return 10 - get.value(card) > 0; + var sub = get.subtype(card); + if ( + player.hasCard(function (card) { + return ( + get.subtype(card) == sub && + player.canUse(card, player) && + get.effect(player, card, player, player) > 0 + ); + }, "hs") + ) + return 10 - get.value(card) > 0; + } + return 5 - get.value(card) > 0; + }) > 1) + ) + return player.getUseValue({ name: "jiu" }) * 4; + return player.getUseValue({ name: button.link[2], nature: button.link[3] }, false); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'dbchongjian', - viewAs:{ - name:links[0][2], - nature:links[0][3], + audio: "dbchongjian", + viewAs: { + name: links[0][2], + nature: links[0][3], //isCard:true, - storage:{dbchongjian:true}, + storage: { dbchongjian: true }, }, - filterCard:{type:'equip'}, - position:'hes', - popname:true, - precontent:function(){ - player.addTempSkill('dbchongjian_effect'); + filterCard: { type: "equip" }, + position: "hes", + popname: true, + precontent: function () { + player.addTempSkill("dbchongjian_effect"); }, - check:function(card){ - var player=_status.event.player; - if(get.position(card)=='e'){ - if(player.hasSkillTag('noe')) return 10-get.value(card); - var sub=get.subtype(card); - if(player.hasCard(function(card){ - return get.subtype(card)==sub&&player.canUse(card,player)&&get.effect(player,card,player,player)>0; - },'hs')) return 10-get.value(card); + check: function (card) { + var player = _status.event.player; + if (get.position(card) == "e") { + if (player.hasSkillTag("noe")) return 10 - get.value(card); + var sub = get.subtype(card); + if ( + player.hasCard(function (card) { + return ( + get.subtype(card) == sub && + player.canUse(card, player) && + get.effect(player, card, player, player) > 0 + ); + }, "hs") + ) + return 10 - get.value(card); } - return 5-get.value(card); + return 5 - get.value(card); }, - } + }; }, - prompt:function(links){ - return '将一张装备牌当做'+(links[0][3]?get.translation(links[0][3]):'')+'【'+get.translation(links[0][2])+'】使用'; + prompt: function (links) { + return ( + "将一张装备牌当做" + + (links[0][3] ? get.translation(links[0][3]) : "") + + "【" + + get.translation(links[0][2]) + + "】使用" + ); }, }, - ai:{ - unequip:true, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='unequip'){ - if(player.group!='wu'||!arg||!arg.card||!arg.card.storage||!arg.card.storage.dbchongjian) return false; - return true + ai: { + unequip: true, + respondSha: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "unequip") { + if ( + player.group != "wu" || + !arg || + !arg.card || + !arg.card.storage || + !arg.card.storage.dbchongjian + ) + return false; + return true; } - return player.group=='wu'&&arg=='use'&&player.hasCard(function(card){ - return get.type(card)=='equip'; - },'hes'); + return ( + player.group == "wu" && + arg == "use" && + player.hasCard(function (card) { + return get.type(card) == "equip"; + }, "hes") + ); }, - order:function(item,player){ - if(_status.event.type!='phase') return 1; - var player=_status.event.player; - if(player.hasCard(function(card){ - if(get.value(card,player)<0) return true; - var sub=get.subtype(card); - return player.hasCard(function(card){ - return get.subtype(card)==sub&&player.canUse(card,player)&&get.effect(player,card,player,player)>0; - },'hs')>0; - },'e')) return 10; - if(player.countCards('hs','sha')||player.countCards('he',function(card){ - return get.type(card)=='equip'&&get.value(card,player)<5; - })>1) return get.order({name:'jiu'})-0.1; - return get.order({name:'sha'})-0.1; + order: function (item, player) { + if (_status.event.type != "phase") return 1; + var player = _status.event.player; + if ( + player.hasCard(function (card) { + if (get.value(card, player) < 0) return true; + var sub = get.subtype(card); + return ( + player.hasCard(function (card) { + return ( + get.subtype(card) == sub && + player.canUse(card, player) && + get.effect(player, card, player, player) > 0 + ); + }, "hs") > 0 + ); + }, "e") + ) + return 10; + if ( + player.countCards("hs", "sha") || + player.countCards("he", function (card) { + return get.type(card) == "equip" && get.value(card, player) < 5; + }) > 1 + ) + return get.order({ name: "jiu" }) - 0.1; + return get.order({ name: "sha" }) - 0.1; }, - result:{player:1}, + result: { player: 1 }, }, - subSkill:{ - effect:{ - charlotte:true, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.dbchongjian) return true; + subSkill: { + effect: { + charlotte: true, + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.dbchongjian) return true; }, }, - trigger:{source:'damageSource'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.parent.skill=='dbchongjian_backup'&&event.card.name=='sha'&&event.getParent().name=='sha'&&event.player.countGainableCards(player,'e')>0; + trigger: { source: "damageSource" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return ( + event.parent.skill == "dbchongjian_backup" && + event.card.name == "sha" && + event.getParent().name == "sha" && + event.player.countGainableCards(player, "e") > 0 + ); }, - content:function(){ - player.gainPlayerCard(trigger.player,'e',true,trigger.num); + content: function () { + player.gainPlayerCard(trigger.player, "e", true, trigger.num); }, }, }, }, - dbchoujue:{ - audio:2, - trigger:{source:'dieAfter'}, - forced:true, - content:function(){ + dbchoujue: { + audio: 2, + trigger: { source: "dieAfter" }, + forced: true, + content: function () { player.gainMaxHp(); player.draw(2); - player.addSkill('counttrigger'); - if(!player.storage.counttrigger) player.storage.counttrigger={}; - if(!player.storage.counttrigger.dbquedi) player.storage.counttrigger.dbquedi=0; + player.addSkill("counttrigger"); + if (!player.storage.counttrigger) player.storage.counttrigger = {}; + if (!player.storage.counttrigger.dbquedi) player.storage.counttrigger.dbquedi = 0; player.storage.counttrigger.dbquedi--; }, }, //王淩 - xingqi:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - locked:false, - filter:function(event,player){ - return get.type(event.card,false)!='delay'&&!player.getStorage('xingqi').includes(event.card.name); + xingqi: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + get.type(event.card, false) != "delay" && + !player.getStorage("xingqi").includes(event.card.name) + ); }, - content:function(){ - player.markAuto('xingqi',[trigger.card.name]); - game.log(player,'获得了一个','#g【备('+get.translation(trigger.card.name)+')】'); + content: function () { + player.markAuto("xingqi", [trigger.card.name]); + game.log(player, "获得了一个", "#g【备(" + get.translation(trigger.card.name) + ")】"); }, - marktext:'备', - intro:{ - content:'$', - onunmark:function(storage,player){ + marktext: "备", + intro: { + content: "$", + onunmark: function (storage, player) { delete player.storage.xingqi; }, }, - group:'xingqi_gain', - subSkill:{ - gain:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getStorage('xingqi').length>0; + group: "xingqi_gain", + subSkill: { + gain: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.getStorage("xingqi").length > 0; }, - content:function(){ - 'step 0' - player.removeSkill('mibei_mark'); - player.chooseButton(['星启:是否获得一张牌?',[player.getStorage('xingqi'),'vcard']]).set('ai',function(button){ - var card={name:button.link[2]},player=_status.event.player; - if(!get.cardPile2(function(cardx){ - return cardx.name==card.name; - })) return 0; - return get.value(card,player)*player.getUseValue(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('xingqi'); - var name=result.links[0][2]; - game.log(player,'移去了一个','#g【备('+get.translation(name)+')】'); - player.unmarkAuto('xingqi',[name]); - var card=get.cardPile2(function(card){ - return card.name==name; + content: function () { + "step 0"; + player.removeSkill("mibei_mark"); + player + .chooseButton([ + "星启:是否获得一张牌?", + [player.getStorage("xingqi"), "vcard"], + ]) + .set("ai", function (button) { + var card = { name: button.link[2] }, + player = _status.event.player; + if ( + !get.cardPile2(function (cardx) { + return cardx.name == card.name; + }) + ) + return 0; + return get.value(card, player) * player.getUseValue(card); }); - if(card) player.gain(card,'gain2'); + "step 1"; + if (result.bool) { + player.logSkill("xingqi"); + var name = result.links[0][2]; + game.log(player, "移去了一个", "#g【备(" + get.translation(name) + ")】"); + player.unmarkAuto("xingqi", [name]); + var card = get.cardPile2(function (card) { + return card.name == name; + }); + if (card) player.gain(card, "gain2"); } }, }, }, }, - xinzifu:{ - audio:'zifu', - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - return player.getStorage('xingqi').length>0&&!player.hasHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; - }); + xinzifu: { + audio: "zifu", + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + return ( + player.getStorage("xingqi").length > 0 && + !player.hasHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == event; + }) + ); }, - content:function(){ - game.log(player,'移去了所有','#g【备】'); - player.unmarkSkill('xingqi'); - player.addTempSkill('xinzifu_limit'); - player.addMark('xinzifu_limit',1,false); + content: function () { + game.log(player, "移去了所有", "#g【备】"); + player.unmarkSkill("xingqi"); + player.addTempSkill("xinzifu_limit"); + player.addMark("xinzifu_limit", 1, false); }, - ai:{ - neg:true, - combo:'xingqi', + ai: { + neg: true, + combo: "xingqi", }, - subSkill:{ - limit:{ - charlotte:true, - markimage:'image/card/handcard.png', - intro:{ - content:function(storage,player){ - var num=-player.countMark('xinzifu_limit'); - return '手牌上限'+num; - } + subSkill: { + limit: { + charlotte: true, + markimage: "image/card/handcard.png", + intro: { + content: function (storage, player) { + var num = -player.countMark("xinzifu_limit"); + return "手牌上限" + num; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('xinzifu_limit'); - } + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("xinzifu_limit"); + }, }, - } - } + }, + }, }, - mibei:{ - audio:2, - trigger:{player:'useCardAfter'}, - dutySkill:true, - forced:true, - locked:false, - direct:true, - filter:function(event,player){ - if(!player.storage.xingqi||!player.storage.xingqi.length) return false; - var map={basic:0,trick:0,equip:0}; - for(var i of player.storage.xingqi){ - var type=get.type(i); - if(typeof map[type]=='number') map[type]++; + mibei: { + audio: 2, + trigger: { player: "useCardAfter" }, + dutySkill: true, + forced: true, + locked: false, + direct: true, + filter: function (event, player) { + if (!player.storage.xingqi || !player.storage.xingqi.length) return false; + var map = { basic: 0, trick: 0, equip: 0 }; + for (var i of player.storage.xingqi) { + var type = get.type(i); + if (typeof map[type] == "number") map[type]++; } - for(var i in map){ - if(map[i]<2) return false; + for (var i in map) { + if (map[i] < 2) return false; } return true; }, - content:function(){ - 'step 0' - player.logSkill('twmibei_achieve'); - game.log(player,'成功完成使命'); - player.awakenSkill('mibei'); - var list=['basic','equip','trick'],cards=[]; - for(var i of list){ - var card=get.cardPile2(function(card){ - return get.type(card)==i; + content: function () { + "step 0"; + player.logSkill("twmibei_achieve"); + game.log(player, "成功完成使命"); + player.awakenSkill("mibei"); + var list = ["basic", "equip", "trick"], + cards = []; + for (var i of list) { + var card = get.cardPile2(function (card) { + return get.type(card) == i; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); - 'step 1' - player.addSkills('xinmouli'); + if (cards.length) player.gain(cards, "gain2"); + "step 1"; + player.addSkills("xinmouli"); }, - group:['mibei_fail','mibei_silent'], - derivation:'xinmouli', - subSkill:{ - silent:{ - charlotte:true, - trigger:{player:'phaseZhunbeiBegin'}, - silent:true, - lastDo:true, - filter:function(event,player){ - return !player.getStorage('xingqi').length; + ai: { + combo: "xingqi" + }, + group: ["mibei_fail", "mibei_silent"], + derivation: "xinmouli", + subSkill: { + silent: { + charlotte: true, + trigger: { player: "phaseZhunbeiBegin" }, + silent: true, + lastDo: true, + filter: function (event, player) { + return !player.getStorage("xingqi").length; }, - content:function(){ - player.addTempSkill('mibei_mark'); + content: function () { + player.addTempSkill("mibei_mark"); }, }, - mark:{charlotte:true}, - fail:{ - audio:'mibei2', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return !player.getStorage('xingqi').length&&player.hasSkill('mibei_mark'); + mark: { charlotte: true }, + fail: { + audio: "mibei2", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return !player.getStorage("xingqi").length && player.hasSkill("mibei_mark"); }, - forced:true, - content:function(){ - game.log(player,'使命失败'); - player.awakenSkill('mibei'); + forced: true, + content: function () { + game.log(player, "使命失败"); + player.awakenSkill("mibei"); player.loseMaxHp(); }, }, }, }, - mibei1:{audio:true}, - mibei2:{audio:true}, - xinmouli:{ - audio:'mouli', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.getStorage('xingqi').length>0; + mibei1: { audio: true }, + mibei2: { audio: true }, + xinmouli: { + audio: "mouli", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.getStorage("xingqi").length > 0; }, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - target.chooseButton(['谋立:是否获得一张牌?',[player.getStorage('xingqi'),'vcard']],true).set('ai',function(button){ - var card={name:button.link[2]},player=_status.event.player; - return get.value(card,player); - }); - 'step 1' - if(result.bool){ - var name=result.links[0][2]; - game.log(player,'移去了一个','#g【备('+get.translation(name)+')】'); - player.unmarkAuto('xingqi',[name]); - var card=get.cardPile2(function(card){ - return card.name==name; + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + target + .chooseButton( + ["谋立:是否获得一张牌?", [player.getStorage("xingqi"), "vcard"]], + true + ) + .set("ai", function (button) { + var card = { name: button.link[2] }, + player = _status.event.player; + return get.value(card, player); }); - if(card) target.gain(card,'gain2'); + "step 1"; + if (result.bool) { + var name = result.links[0][2]; + game.log(player, "移去了一个", "#g【备(" + get.translation(name) + ")】"); + player.unmarkAuto("xingqi", [name]); + var card = get.cardPile2(function (card) { + return card.name == name; + }); + if (card) target.gain(card, "gain2"); } }, - ai:{ - combo:'xingqi', - order:1, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; + ai: { + combo: "xingqi", + order: 1, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; return 1; }, }, }, }, - mouli:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + mouli: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - position:'h', - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - check:function(card){ - return 8-get.value(card); + filterCard: true, + position: "h", + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - player.give(cards,target); - if(!target.storage.mouli2) target.storage.mouli2=[]; - if(!target.storage.mouli3) target.storage.mouli3=[]; + content: function () { + player.give(cards, target); + if (!target.storage.mouli2) target.storage.mouli2 = []; + if (!target.storage.mouli3) target.storage.mouli3 = []; target.storage.mouli2.add(player); target.storage.mouli3.push(player); - target.addSkill('mouli_effect'); + target.addSkill("mouli_effect"); }, - ai:{ - threaten:1.2, - order:4, - result:{ - target:1, + ai: { + threaten: 1.2, + order: 4, + result: { + target: 1, }, }, - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(event.card.name!='sha'&&event.card.name!='shan') return false; - for(var i of player.storage.mouli3){ - if(i.isIn()) return true; + subSkill: { + effect: { + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if (event.card.name != "sha" && event.card.name != "shan") return false; + for (var i of player.storage.mouli3) { + if (i.isIn()) return true; } return false; }, - logTarget:function(event,player){ + logTarget: function (event, player) { return player.storage.mouli3; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; game.delayx(); player.storage.mouli3.sortBySeat(); - if(player.storage.mouli3.length==1){ + if (player.storage.mouli3.length == 1) { player.storage.mouli3[0].draw(3); - player.storage.mouli3.length=0; + player.storage.mouli3.length = 0; event.finish(); - } - else game.asyncDraw(player.storage.mouli3,3); - 'step 1' - player.storage.mouli3.length=0; + } else game.asyncDraw(player.storage.mouli3, 3); + "step 1"; + player.storage.mouli3.length = 0; game.delayx(); }, - group:['mouli_sha','mouli_shan','mouli_clear'], - mark:true, - intro:{ - content:'已因$获得“谋立”效果', + group: ["mouli_sha", "mouli_shan", "mouli_clear"], + mark: true, + intro: { + content: "已因$获得“谋立”效果", }, }, - sha:{ - enable:'chooseToUse', - viewAs:{name:'sha'}, - filterCard:{color:'black'}, - position:'he', - prompt:'将一张黑色牌当做杀使用', - check:function(card){ - return 6-get.value(card); + sha: { + enable: "chooseToUse", + viewAs: { name: "sha" }, + filterCard: { color: "black" }, + position: "he", + prompt: "将一张黑色牌当做杀使用", + check: function (card) { + return 6 - get.value(card); }, - viewAsFilter:function(player){ - return player.countCards('he',{color:'black'})>0; + viewAsFilter: function (player) { + return player.countCards("he", { color: "black" }) > 0; }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - return player.countCards('he',{color:'black'})>0; + ai: { + respondSha: true, + skillTagFilter: function (player) { + return player.countCards("he", { color: "black" }) > 0; }, }, }, - shan:{ - enable:'chooseToUse', - viewAs:{name:'shan'}, - filterCard:{color:'red'}, - position:'he', - prompt:'将一张红色牌当做闪使用', - check:function(card){ - return 7-get.value(card); + shan: { + enable: "chooseToUse", + viewAs: { name: "shan" }, + filterCard: { color: "red" }, + position: "he", + prompt: "将一张红色牌当做闪使用", + check: function (card) { + return 7 - get.value(card); }, - viewAsFilter:function(player){ - return player.countCards('he',{color:'red'})>0; + viewAsFilter: function (player) { + return player.countCards("he", { color: "red" }) > 0; }, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - return player.countCards('he',{color:'red'})>0; + ai: { + respondShan: true, + skillTagFilter: function (player) { + return player.countCards("he", { color: "red" }) > 0; }, }, }, - clear:{ - trigger:{global:['phaseBegin','dieAfter']}, - forced:true, - silent:true, - popup:false, - lastDo:true, - forceDie:true, - filter:function(event,player){ - if(event.name=='die'&&player==event.player) return true; + clear: { + trigger: { global: ["phaseBegin", "dieAfter"] }, + forced: true, + silent: true, + popup: false, + lastDo: true, + forceDie: true, + filter: function (event, player) { + if (event.name == "die" && player == event.player) return true; return player.storage.mouli2.includes(event.player); }, - content:function(){ - if(trigger.name=='die'&&player==trigger.player){ - player.removeSkill('mouli_effect'); + content: function () { + if (trigger.name == "die" && player == trigger.player) { + player.removeSkill("mouli_effect"); delete player.storage.mouli2; delete player.storage.mouli3; return; } player.storage.mouli2.remove(trigger.player); - while(player.storage.mouli3.includes(trigger.player)) player.storage.mouli3.remove(trigger.player); - if(!player.storage.mouli2.length) player.removeSkill('mouli_effect'); + while (player.storage.mouli3.includes(trigger.player)) + player.storage.mouli3.remove(trigger.player); + if (!player.storage.mouli2.length) player.removeSkill("mouli_effect"); }, }, }, }, - zifu:{ - audio:2, - trigger:{global:'dieAfter'}, - forced:true, - filter:function(event,player){ - return event.player.storage.mouli2&&event.player.storage.mouli2.includes(player); + zifu: { + audio: 2, + trigger: { global: "dieAfter" }, + forced: true, + filter: function (event, player) { + return event.player.storage.mouli2 && event.player.storage.mouli2.includes(player); }, - content:function(){ + content: function () { player.loseMaxHp(2); }, - ai:{ - combo:'mouli', - neg:true, + ai: { + combo: "mouli", + neg: true, }, }, //孔融 - xinlirang:{ - audio:'splirang', - trigger:{global:'phaseDrawBegin2'}, - logTarget:'player', - filter:function(event,player){ - return !event.numFixed&&event.player!=player&&player.countMark('xinlirang')==0; + xinlirang: { + audio: "splirang", + trigger: { global: "phaseDrawBegin2" }, + logTarget: "player", + filter: function (event, player) { + return !event.numFixed && event.player != player && player.countMark("xinlirang") == 0; }, - prompt2:'获得一枚“谦”并令其多摸两张牌', - check:function(event,player){ - return get.attitude(player,event.player)>0; + prompt2: "获得一枚“谦”并令其多摸两张牌", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - trigger.num+=2; - player.addMark('xinlirang',1); - player.addTempSkill('xinlirang_gain'); + content: function () { + trigger.num += 2; + player.addMark("xinlirang", 1); + player.addTempSkill("xinlirang_gain"); }, - marktext:'谦', - intro:{ - name:'谦', - content:'mark', + marktext: "谦", + intro: { + name: "谦", + content: "mark", }, - group:'xinlirang_skip', - subSkill:{ - gain:{ - audio:'splirang', - trigger:{global:'phaseDiscardEnd'}, - direct:true, - filter:function(event,player){ - return event.player.hasHistory('lose',function(evt){ - return evt.type=='discard'&&evt.cards2.filterInD('d').length>0&&evt.getParent('phaseDiscard')==event; + group: "xinlirang_skip", + subSkill: { + gain: { + audio: "splirang", + trigger: { global: "phaseDiscardEnd" }, + direct: true, + filter: function (event, player) { + return event.player.hasHistory("lose", function (evt) { + return ( + evt.type == "discard" && + evt.cards2.filterInD("d").length > 0 && + evt.getParent("phaseDiscard") == event + ); }); }, - content:function(){ - 'step 0' - var cards=[]; - trigger.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) cards.addArray(evt.cards2.filterInD('d')); + content: function () { + "step 0"; + var cards = []; + trigger.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + cards.addArray(evt.cards2.filterInD("d")); }); - player.chooseButton(['礼让:是否获得其中至多两张牌?',cards],[1,2]); - 'step 1' - if(result.bool){ - player.logSkill('xinlirang_gain',trigger.player); - player.gain(result.links,'gain2'); + player.chooseButton(["礼让:是否获得其中至多两张牌?", cards], [1, 2]); + "step 1"; + if (result.bool) { + player.logSkill("xinlirang_gain", trigger.player); + player.gain(result.links, "gain2"); } }, }, - skip:{ - audio:'splirang', - trigger:{player:'phaseDrawBefore'}, - forced:true, - filter:function(event,player){ - return player.hasMark('xinlirang'); + skip: { + audio: "splirang", + trigger: { player: "phaseDrawBefore" }, + forced: true, + filter: function (event, player) { + return player.hasMark("xinlirang"); }, - content:function(){ + content: function () { trigger.cancel(); - player.removeMark('xinlirang',player.countMark('xinlirang')); + player.removeMark("xinlirang", player.countMark("xinlirang")); }, }, }, }, - xinmingshi:{ - audio:'spmingshi', - trigger:{player:'damageEnd'}, - forced:true, - logTarget:'source', - filter:function(event,player){ - return event.source&&event.source.isIn()&&player.hasMark('xinlirang')&&event.source.countCards('he')>0; + xinmingshi: { + audio: "spmingshi", + trigger: { player: "damageEnd" }, + forced: true, + logTarget: "source", + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + player.hasMark("xinlirang") && + event.source.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - trigger.source.chooseToDiscard('he',true).set('color',get.attitude(trigger.source,player)>0?'red':'black').set('ai',function(card){ - return (get.color(card)==_status.event.color?4:0)-get.value(card); - }); - 'step 1' - if(result.bool&&result.cards&&result.cards.length){ - var card=result.cards[0]; - if(get.color(card,trigger.source)=='red') player.recover(); - else if(get.position(card,true)=='d') player.gain(card,'gain2'); + content: function () { + "step 0"; + trigger.source + .chooseToDiscard("he", true) + .set("color", get.attitude(trigger.source, player) > 0 ? "red" : "black") + .set("ai", function (card) { + return (get.color(card) == _status.event.color ? 4 : 0) - get.value(card); + }); + "step 1"; + if (result.bool && result.cards && result.cards.length) { + var card = result.cards[0]; + if (get.color(card, trigger.source) == "red") player.recover(); + else if (get.position(card, true) == "d") player.gain(card, "gain2"); } }, - ai:{ - combo:'xinmingshi', - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&target.hasMark('xinlirang')){ - var cards=[card]; - if(card.cards&&card.cards.length) cards.addArray(card.cards); - if(ui.selected.cards.length) cards.addArray(ui.selected.cards); - if(!player.countCards('he',function(card){ - return !cards.includes(card); - })) return; - if(!player.countCards('h',function(card){ - return !cards.includes(card)&&get.color(card)=='black'&&get.value(card,player)<6; - })) return 'zerotarget'; + ai: { + combo: "xinlirang", + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage") && target.hasMark("xinlirang")) { + var cards = [card]; + if (card.cards && card.cards.length) cards.addArray(card.cards); + if (ui.selected.cards.length) cards.addArray(ui.selected.cards); + if ( + !player.countCards("he", function (card) { + return !cards.includes(card); + }) + ) + return; + if ( + !player.countCards("h", function (card) { + return ( + !cards.includes(card) && + get.color(card) == "black" && + get.value(card, player) < 6 + ); + }) + ) + return "zerotarget"; return 0.5; } }, }, }, }, - spmingshi:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - logTarget:'source', - filter:function(event,player){ - return event.source&&player!=event.source&&event.source.countCards('he')>0; + spmingshi: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + logTarget: "source", + filter: function (event, player) { + return event.source && player != event.source && event.source.countCards("he") > 0; }, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - trigger.source.chooseToDiscard('he',true); - 'step 2' - if(event.count>0&&result.bool&&lib.skill.spmingshi.filter(trigger,player)&&player.hasSkill('spmingshi')) event.goto(1); + trigger.source.chooseToDiscard("he", true); + "step 2"; + if ( + event.count > 0 && + result.bool && + lib.skill.spmingshi.filter(trigger, player) && + player.hasSkill("spmingshi") + ) + event.goto(1); }, - ai:{ - threaten:0.8, - maixie:true, - maixie_defend:true, + ai: { + threaten: 0.8, + maixie: true, + maixie_defend: true, }, }, - splirang:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of hs){ - if(!lib.filter.cardDiscardable(i,player,'splirang')) return false; + splirang: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of hs) { + if (!lib.filter.cardDiscardable(i, player, "splirang")) return false; } return true; }, - filterCard:true, - selectCard:-1, - content:function(){ - 'step 0' - cards=cards.filterInD('d'); - if(!cards.length||player.hp<1) event.goto(3); - else player.chooseButton(['将任意张牌交给一名其他角色',cards],[1,Math.min(cards.length,player.hp)]).set('ai',function(button){ - return get.value(button.link); - }); - 'step 1' - if(result.bool){ - event.cards=result.links; - player.chooseTarget(true,'令一名角色获得'+get.translation(event.cards),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkillTag('nogain')) att/=10; - if(target.hasJudge('lebu')) att/=5; - return att; - }); + filterCard: true, + selectCard: -1, + content: function () { + "step 0"; + cards = cards.filterInD("d"); + if (!cards.length || player.hp < 1) event.goto(3); + else + player + .chooseButton( + ["将任意张牌交给一名其他角色", cards], + [1, Math.min(cards.length, player.hp)] + ) + .set("ai", function (button) { + return get.value(button.link); + }); + "step 1"; + if (result.bool) { + event.cards = result.links; + player + .chooseTarget( + true, + "令一名角色获得" + get.translation(event.cards), + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkillTag("nogain")) att /= 10; + if (target.hasJudge("lebu")) att /= 5; + return att; + }); + } else event.goto(3); + "step 2"; + if (result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + target.gain(cards, "gain2"); } - else event.goto(3); - 'step 2' - if(result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - target.gain(cards,'gain2'); - } - 'step 3' + "step 3"; player.draw(); }, - ai:{ - order:0.1, - result:{ - player:function(player){ - var hs=player.getCards('h'); - if(hs.length<=player.hp&&game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&&!current.hasJudge('lebu')&&!current.hasSkillTag('nogain'); - })) return 1; - if(get.value(hs,player)<6) return 1; + ai: { + order: 0.1, + result: { + player: function (player) { + var hs = player.getCards("h"); + if ( + hs.length <= player.hp && + game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) > 0 && + !current.hasJudge("lebu") && + !current.hasSkillTag("nogain") + ); + }) + ) + return 1; + if (get.value(hs, player) < 6) return 1; return 0; }, }, }, }, //糜夫人 - xinguixiu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.hp%2==1||player.isDamaged(); + xinguixiu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.hp % 2 == 1 || player.isDamaged(); }, - content:function(){ - if(player.hp%2==1) player.draw(); + content: function () { + if (player.hp % 2 == 1) player.draw(); else player.recover(); }, }, - qingyu:{ - audio:3, - dutySkill:true, - locked:false, - group:['qingyu_achieve','qingyu_fail','qingyu_defend'], - subSkill:{ - defend:{ - audio:'qingyu1', - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - return player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'qingyu_defend'); - })>1; + qingyu: { + audio: 3, + dutySkill: true, + locked: false, + group: ["qingyu_achieve", "qingyu_fail", "qingyu_defend"], + subSkill: { + defend: { + audio: "qingyu1", + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "qingyu_defend"); + }) > 1 + ); }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); - player.chooseToDiscard(2,'he',true); + player.chooseToDiscard(2, "he", true); }, }, - achieve:{ - audio:'qingyu3', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - return player.isHealthy()&&player.countCards('h')==0; + achieve: { + audio: "qingyu3", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + return player.isHealthy() && player.countCards("h") == 0; }, - content:function(){ - game.log(player,'成功完成使命'); - player.awakenSkill('qingyu'); - player.addSkills('xuancun'); + content: function () { + game.log(player, "成功完成使命"); + player.awakenSkill("qingyu"); + player.addSkills("xuancun"); }, }, - fail:{ - audio:'qingyu2', - trigger:{player:'dying'}, - forced:true, - content:function(){ - game.log(player,'使命失败'); - player.awakenSkill('qingyu'); + fail: { + audio: "qingyu2", + trigger: { player: "dying" }, + forced: true, + content: function () { + game.log(player, "使命失败"); + player.awakenSkill("qingyu"); player.loseMaxHp(); }, }, }, - derivation:'xuancun', + derivation: "xuancun", }, - qingyu1:{audio:true}, - qingyu2:{audio:true}, - qingyu3:{audio:true}, - xuancun:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return player!=event.player&&player.countCards('h')0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - prompt2:function(event,player){ - return '令其摸'+get.cnNumber(Math.min(2,player.hp-player.countCards('h')))+'张牌'; + prompt2: function (event, player) { + return "令其摸" + get.cnNumber(Math.min(2, player.hp - player.countCards("h"))) + "张牌"; }, - content:function(){ - trigger.player.draw(Math.min(2,player.hp-player.countCards('h'))); + content: function () { + trigger.player.draw(Math.min(2, player.hp - player.countCards("h"))); }, }, //羊祜 - mingfa:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.storage.mingfa&&player.countCards('h')>0&&player.getCards('he').includes(player.storage.mingfa) - &&!player.hasSkillTag('noCompareSource')&&game.hasPlayer(function(current){ - return current!=player&&player.canCompare(current); - }); + mingfa: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.storage.mingfa && + player.countCards("h") > 0 && + player.getCards("he").includes(player.storage.mingfa) && + !player.hasSkillTag("noCompareSource") && + game.hasPlayer(function (current) { + return current != player && player.canCompare(current); + }) + ); }, - content:function(){ - 'step 0' - event.card=player.storage.mingfa; + content: function () { + "step 0"; + event.card = player.storage.mingfa; delete player.storage.mingfa; - player.chooseTarget(get.prompt('mingfa'),'用'+get.translation(event.card)+'和一名其他角色拼点',function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player,card=_status.event.getParent().card; - if(card.number>9||!target.countCards('h',function(cardx){ - return cardx.number>=card.number+2; - })) return -get.attitude(player,target)/Math.sqrt(target.countCards('h')); - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('mingfa',target); - var next=player.chooseToCompare(target); - if(!next.fixedResult) next.fixedResult={}; - next.fixedResult[player.playerid]=event.card; - } - else{ - player.removeGaintag('mingfa'); + player + .chooseTarget( + get.prompt("mingfa"), + "用" + get.translation(event.card) + "和一名其他角色拼点", + function (card, player, target) { + return player.canCompare(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + card = _status.event.getParent().card; + if ( + card.number > 9 || + !target.countCards("h", function (cardx) { + return cardx.number >= card.number + 2; + }) + ) + return -get.attitude(player, target) / Math.sqrt(target.countCards("h")); + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("mingfa", target); + var next = player.chooseToCompare(target); + if (!next.fixedResult) next.fixedResult = {}; + next.fixedResult[player.playerid] = event.card; + } else { + player.removeGaintag("mingfa"); event.finish(); } - 'step 2' - if(result.bool){ - player.gainPlayerCard(target,true,'he'); - if(event.card.number==1) event.finish(); - } - else{ - player.addTempSkill('mingfa_block'); + "step 2"; + if (result.bool) { + player.gainPlayerCard(target, true, "he"); + if (event.card.number == 1) event.finish(); + } else { + player.addTempSkill("mingfa_block"); event.finish(); } - 'step 3' - var card=get.cardPile2(function(card){ - return card.number==event.card.number-1; + "step 3"; + var card = get.cardPile2(function (card) { + return card.number == event.card.number - 1; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, - group:['mingfa_choose','mingfa_add','mingfa_mark'], - subSkill:{ - block:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; + group: ["mingfa_choose", "mingfa_add", "mingfa_mark"], + subSkill: { + block: { + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; }, }, }, - choose:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + choose: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('mingfa'),'选择展示自己的一张牌').set('ai',function(card){ - return Math.min(13,get.number(card)+2)/Math.pow(Math.min(2,get.value(card)),0.25); - }); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - player.logSkill('mingfa'); - player.removeGaintag('mingfa'); - player.addGaintag(card,'mingfa'); - player.storage.mingfa=card; - player.showCards(card,get.translation(player)+'发动了【明伐】'); + content: function () { + "step 0"; + player + .chooseCard("he", get.prompt("mingfa"), "选择展示自己的一张牌") + .set("ai", function (card) { + return ( + Math.min(13, get.number(card) + 2) / + Math.pow(Math.min(2, get.value(card)), 0.25) + ); + }); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + player.logSkill("mingfa"); + player.removeGaintag("mingfa"); + player.addGaintag(card, "mingfa"); + player.storage.mingfa = card; + player.showCards(card, get.translation(player) + "发动了【明伐】"); } }, }, - add:{ - trigger:{player:'compare',target:'compare'}, - filter:function(event,player){ - if(event.player==player) return !event.iwhile; + add: { + trigger: { player: "compare", target: "compare" }, + filter: function (event, player) { + if (event.player == player) return !event.iwhile; return true; }, - forced:true, - locked:false, - content:function(){ - if(player==trigger.player){ - trigger.num1+=2; - if(trigger.num1>13) trigger.num1=13; + forced: true, + locked: false, + content: function () { + if (player == trigger.player) { + trigger.num1 += 2; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += 2; + if (trigger.num2 > 13) trigger.num2 = 13; } - else{ - trigger.num2+=2; - if(trigger.num2>13) trigger.num2=13; - } - game.log(player,'的拼点牌点数+2') + game.log(player, "的拼点牌点数+2"); }, }, - mark:{ - trigger:{player:'gainEnd'}, - silent:true, - firstDo:true, - filter:function(event,player){ - return player.storage.mingfa&&event.cards.includes(player.storage.mingfa)&&player.getCards('h').includes(player.storage.mingfa); + mark: { + trigger: { player: "gainEnd" }, + silent: true, + firstDo: true, + filter: function (event, player) { + return ( + player.storage.mingfa && + event.cards.includes(player.storage.mingfa) && + player.getCards("h").includes(player.storage.mingfa) + ); }, - content:function(){ - player.addGaintag(player.storage.mingfa,'mingfa'); + content: function () { + player.addGaintag(player.storage.mingfa, "mingfa"); }, }, }, }, - rongbei:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.rongbei.filterTarget(null,player,current)); + rongbei: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return game.hasPlayer((current) => lib.skill.rongbei.filterTarget(null, player, current)); }, - filterTarget:function(card,player,target){ - for(var i=1;i<6;i++){ - if(target.hasEmptySlot(i)) return true; + filterTarget: function (card, player, target) { + for (var i = 1; i < 6; i++) { + if (target.hasEmptySlot(i)) return true; } return false; }, - content:function(){ - 'step 0' - event.num=1; - player.awakenSkill('rongbei'); - 'step 1' - while(!target.hasEmptySlot(event.num)){ + content: function () { + "step 0"; + event.num = 1; + player.awakenSkill("rongbei"); + "step 1"; + while (!target.hasEmptySlot(event.num)) { event.num++; - if(event.num>5){ + if (event.num > 5) { event.finish(); return; } } - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip'+event.num&&target.canUse(card,target); + var card = get.cardPile2(function (card) { + return get.subtype(card) == "equip" + event.num && target.canUse(card, target); }); - if(card){ - target.chooseUseTarget(card,true,'nopopup'); + if (card) { + target.chooseUseTarget(card, true, "nopopup"); } event.num++; - if(event.num<=5) event.redo(); + if (event.num <= 5) event.redo(); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - return (target.hasSkillTag('noe')?2:1)*(5-target.countCards('e')-target.countDisabled()); + ai: { + order: 5, + result: { + target: function (player, target) { + return ( + (target.hasSkillTag("noe") ? 2 : 1) * + (5 - target.countCards("e") - target.countDisabled()) + ); }, }, }, }, //桥公 - yizhu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - content:function(){ - 'step 0' + yizhu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + content: function () { + "step 0"; player.draw(2); - 'step 1' - var hs=player.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length<=2) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,2,'选择两张牌洗入牌堆'); - 'step 2' - if(result.bool){ - player.$throw(result.cards.length,1000); - player.lose(result.cards,ui.cardPile).insert_index=function(){ - return ui.cardPile.childNodes[get.rand(0,game.players.length*2-2)]; - } - player.markAuto('yizhu',result.cards); - } - else event.finish(); - 'step 3' + "step 1"; + var hs = player.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length <= 2) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", true, 2, "选择两张牌洗入牌堆"); + "step 2"; + if (result.bool) { + player.$throw(result.cards.length, 1000); + player.lose(result.cards, ui.cardPile).insert_index = function () { + return ui.cardPile.childNodes[get.rand(0, game.players.length * 2 - 2)]; + }; + player.markAuto("yizhu", result.cards); + } else event.finish(); + "step 3"; game.updateRoundNumber(); game.delayx(); }, - intro:{ - mark:function(dialog,content,player){ - if(player==game.me||player.isUnderControl()) dialog.addAuto(content); - else{ - var names=[]; - for(var i of content) names.add(i.name); + intro: { + mark: function (dialog, content, player) { + if (player == game.me || player.isUnderControl()) dialog.addAuto(content); + else { + var names = []; + for (var i of content) names.add(i.name); return get.translation(names); } }, }, - group:'yizhu_use', - subSkill:{ - use:{ - audio:'yizhu', - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - return player.storage.yizhu&&player.storage.yizhu.length&& - event.player!=player&&event.targets.length==1&& - event.cards.filter(function(i){ - return player.storage.yizhu.includes(i); - }).length>0; + group: "yizhu_use", + subSkill: { + use: { + audio: "yizhu", + trigger: { global: "useCardToPlayer" }, + filter: function (event, player) { + return ( + player.storage.yizhu && + player.storage.yizhu.length && + event.player != player && + event.targets.length == 1 && + event.cards.filter(function (i) { + return player.storage.yizhu.includes(i); + }).length > 0 + ); }, - logTarget:'player', - check:function(event,player){ - return get.effect(event.targets[0],event.card,event.player,player)<0; + logTarget: "player", + check: function (event, player) { + return get.effect(event.targets[0], event.card, event.player, player) < 0; }, - prompt2:function(event,player){ - return '令'+get.translation(event.card)+'无效'; + prompt2: function (event, player) { + return "令" + get.translation(event.card) + "无效"; }, - content:function(){ + content: function () { trigger.cancel(); - trigger.targets.length=0; - trigger.getParent().triggeredTargets1.length=0; - var list=trigger.cards.filter(function(i){ + trigger.targets.length = 0; + trigger.getParent().triggeredTargets1.length = 0; + var list = trigger.cards.filter(function (i) { return player.storage.yizhu.includes(i); }); - player.unmarkAuto('yizhu',list); + player.unmarkAuto("yizhu", list); game.delayx(); }, }, }, }, - luanchou:{ - audio:2, - enable:'phaseUse', - usable:1, - selectTarget:2, - filterTarget:true, - multitarget:true, - multiline:true, - content:function(){ - game.countPlayer(function(current){ - var num=current.countMark('luanchou'); - if(num) current.removeMark('luanchou',num); + luanchou: { + audio: 2, + enable: "phaseUse", + usable: 1, + selectTarget: 2, + filterTarget: true, + multitarget: true, + multiline: true, + content: function () { + game.countPlayer(function (current) { + var num = current.countMark("luanchou"); + if (num) current.removeMark("luanchou", num); }); targets.sortBySeat(); - for(var i of targets) i.addMark('luanchou',1); + for (var i of targets) i.addMark("luanchou", 1); }, - global:['gonghuan','gonghuan_clear'], - derivation:'gonghuan', - marktext:'姻', - intro:{ - name:'共患', - content:()=>lib.translate.gonghuan_info, - onunmark:true, + global: ["gonghuan", "gonghuan_clear"], + derivation: "gonghuan", + marktext: "姻", + intro: { + name: "共患", + content: () => lib.translate.gonghuan_info, + onunmark: true, }, - ai:{ - order:10, - expose:0.2, - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return -Math.pow(target.hp,3); - if(target.hp>=ui.selected.targets[0].hp) return 0; - return Math.pow(ui.selected.targets[0].hp-target.hp,3); + ai: { + order: 10, + expose: 0.2, + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return -Math.pow(target.hp, 3); + if (target.hp >= ui.selected.targets[0].hp) return 0; + return Math.pow(ui.selected.targets[0].hp - target.hp, 3); }, }, }, }, - gonghuan:{ - audio:2, - forceaudio:true, - trigger:{global:'damageBegin4'}, - usable:1, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.player.hptarget.hp&&(!current.storage.counttrigger||!current.storage.counttrigger.gonghuan); + ai: { + effect: { + target: function (card, player, target) { + if (_status.luanchou_judging) return; + if (get.tag(card, "damage") && target.hasMark("luanchou")) { + var other = game.findPlayer(function (current) { + return ( + current != target && + current.hasMark("luanchou") && + current.hp > target.hp && + (!current.storage.counttrigger || + !current.storage.counttrigger.gonghuan) + ); }); - if(!other) return; - _status.luanchou_judging=true; - var eff=[0,0,0,get.damageEffect(other,player,player,get.nature(card))/get.attitude(player,player)]; + if (!other) return; + _status.luanchou_judging = true; + var eff = [ + 0, + 0, + 0, + get.damageEffect(other, player, player, get.nature(card)) / + get.attitude(player, player), + ]; delete _status.luanchou_judging; return eff; } }, }, }, - subSkill:{ - clear:{ - trigger:{player:'damageEnd'}, - forced:true, - popup:false, - filter:function(event,player){ + subSkill: { + clear: { + trigger: { player: "damageEnd" }, + forced: true, + popup: false, + filter: function (event, player) { return event._gonghuan_player; }, - content:function(){ - player.removeMark('luanchou',player.countMark('luanchou')); - trigger._gonghuan_player.removeMark('luanchou',trigger._gonghuan_player.countMark('luanchou')); + content: function () { + player.removeMark("luanchou", player.countMark("luanchou")); + trigger._gonghuan_player.removeMark( + "luanchou", + trigger._gonghuan_player.countMark("luanchou") + ); }, }, }, }, //刘璋 - xiusheng:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.yinlang&&game.hasPlayer(function(current){ - return current.group==player.storage.yinlang; - }); + xiusheng: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.storage.yinlang && + game.hasPlayer(function (current) { + return current.group == player.storage.yinlang; + }) + ); }, - content:function(){ - 'step 0' - if(player.storage.xiusheng&&player.storage.xiusheng.length>0) player.unmarkSkill('xiusheng'); - 'step 1' - event.num=game.countPlayer(function(current){ - return current.group==player.storage.yinlang; + content: function () { + "step 0"; + if (player.storage.xiusheng && player.storage.xiusheng.length > 0) + player.unmarkSkill("xiusheng"); + "step 1"; + event.num = game.countPlayer(function (current) { + return current.group == player.storage.yinlang; }); - if(event.num>0) player.draw(event.num); + if (event.num > 0) player.draw(event.num); else event.finish(); - 'step 2' - var he=player.getCards('he'); - if(!he.length) event.finish(); - else if(he.length0) return 1.5; - if(!current.inRange(player)) return 1; - return 0.6; - }); - } - list.sort(function(a,b){ - return getn(b)-getn(a); - }); - return list[0]; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('yinlang',game.filterPlayer(function(current){ - return current.group==result.control; - })); - game.log(player,'选择了','#y'+get.translation(result.control+2)) - player.storage.yinlang=result.control; - player.markSkill('yinlang'); + if (!player.hasSkill("yinlang")) list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", "引狼:请选择一个势力") + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var getn = function (group) { + return game.countPlayer(function (current) { + if (current.group != group) return false; + if (get.attitude(current, player) > 0) return 1.5; + if (!current.inRange(player)) return 1; + return 0.6; + }); + }; + list.sort(function (a, b) { + return getn(b) - getn(a); + }); + return list[0]; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill( + "yinlang", + game.filterPlayer(function (current) { + return current.group == result.control; + }) + ); + game.log(player, "选择了", "#y" + get.translation(result.control + 2)); + player.storage.yinlang = result.control; + player.markSkill("yinlang"); } }, - ai:{combo:'xiusheng'}, - intro:{content:'已选择了$势力'}, - group:'yinlang_gain', - subSkill:{ - round:{}, - gain:{ - audio:'yinlang', - trigger:{global:'phaseUseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.player.group==player.storage.yinlang&&event.player.isIn()&&player.getStorage('xiusheng').length>0; + ai: { combo: "xiusheng" }, + intro: { content: "已选择了$势力" }, + group: "yinlang_gain", + subSkill: { + round: {}, + gain: { + audio: "yinlang", + trigger: { global: "phaseUseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + event.player.group == player.storage.yinlang && + event.player.isIn() && + player.getStorage("xiusheng").length > 0 + ); }, - logTarget:'player', - content:function(){ - 'step 0' - var str=get.translation(player); - event.target=trigger.player; - event.target.chooseControl().set('choiceList',[ - '获得'+str+'的一张“生”,然后本阶段使用牌时只能指定其为目标', - '令'+str+'获得一张“生”', - ]).set('ai',function(){ - var evt=_status.event.getParent(),player=evt.target,target=evt.player; - if(get.attitude(player,target)>0) return 1; - if(!player.countCards('hs',function(card){ - return player.hasValueTarget(card,null,true)&&(!player.canUse(card,target,null,true)||get.effect(target,card,player,player)<0) - })) return 0; - return 1; - }); - 'step 1' - event.gainner=(result.index==0)?target:player; - if(result.index==0) event.block=true; - event.gainner.chooseButton(['选择获得一张“生”',player.storage.xiusheng],true); - 'step 2' - player.unmarkAuto('xiusheng',result.links); - event.gainner.gain(result.links,'gain2'); - if(event.block){ - target.markAuto('yinlang_block',[player]); - target.addTempSkill('yinlang_block','phaseUseAfter'); + logTarget: "player", + content: function () { + "step 0"; + var str = get.translation(player); + event.target = trigger.player; + event.target + .chooseControl() + .set("choiceList", [ + "获得" + str + "的一张“生”,然后本阶段使用牌时只能指定其为目标", + "令" + str + "获得一张“生”", + ]) + .set("ai", function () { + var evt = _status.event.getParent(), + player = evt.target, + target = evt.player; + if (get.attitude(player, target) > 0) return 1; + if ( + !player.countCards("hs", function (card) { + return ( + player.hasValueTarget(card, null, true) && + (!player.canUse(card, target, null, true) || + get.effect(target, card, player, player) < 0) + ); + }) + ) + return 0; + return 1; + }); + "step 1"; + event.gainner = result.index == 0 ? target : player; + if (result.index == 0) event.block = true; + event.gainner.chooseButton(["选择获得一张“生”", player.storage.xiusheng], true); + "step 2"; + player.unmarkAuto("xiusheng", result.links); + event.gainner.gain(result.links, "gain2"); + if (event.block) { + target.markAuto("yinlang_block", [player]); + target.addTempSkill("yinlang_block", "phaseUseAfter"); } }, }, - block:{ - mod:{ - playerEnabled:function(card,player,target){ - var info=get.info(card); - if(info&&info.singleCard&&ui.selected.cards.length) return; - if(!player.getStorage('yinlang_block').includes(target)) return false; + block: { + mod: { + playerEnabled: function (card, player, target) { + var info = get.info(card); + if (info && info.singleCard && ui.selected.cards.length) return; + if (!player.getStorage("yinlang_block").includes(target)) return false; }, }, - onremove:true, + onremove: true, }, }, }, - huaibi:{ - audio:2, - zhuSkill:true, - mod:{ - maxHandcard:function(player,num){ - if(player.storage.yinlang&&player.hasZhuSkill('huaibi')) return num+game.countPlayer(function(current){ - return current.group==player.storage.yinlang; - }); + huaibi: { + audio: 2, + zhuSkill: true, + mod: { + maxHandcard: function (player, num) { + if (player.storage.yinlang && player.hasZhuSkill("huaibi")) + return ( + num + + game.countPlayer(function (current) { + return current.group == player.storage.yinlang; + }) + ); }, }, - ai:{combo:'yinlang'}, + ai: { combo: "yinlang" }, }, //张温 - gebo:{ - audio:2, - trigger:{global:'recoverAfter'}, - forced:true, - content:function(){ - game.cardsGotoSpecial(get.cards(),'toRenku'); + gebo: { + audio: 2, + trigger: { global: "recoverAfter" }, + forced: true, + content: function () { + game.cardsGotoSpecial(get.cards(), "toRenku"); }, }, - spsongshu:{ - audio:2, - trigger:{global:'phaseDrawBegin1'}, - logTarget:'player', - filter:function(event,player){ - return event.player.hp>player.hp&&player.hp>0&&!event.numFixed&&_status.renku.length>0; + spsongshu: { + audio: 2, + trigger: { global: "phaseDrawBegin1" }, + logTarget: "player", + filter: function (event, player) { + return ( + event.player.hp > player.hp && + player.hp > 0 && + !event.numFixed && + _status.renku.length > 0 + ); }, - check:function(event,player){ - var num=Math.min(5,player.hp,_status.renku.length); - if(num<=event.num) return get.attitude(player,event.player)<0; + check: function (event, player) { + var num = Math.min(5, player.hp, _status.renku.length); + if (num <= event.num) return get.attitude(player, event.player) < 0; return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - var num=Math.min(5,player.hp,_status.renku.length); - trigger.player.chooseButton(['选择获得'+get.cnNumber(num)+'张牌',_status.renku],true,num); - 'step 1' - if(result.bool){ - var cards=result.links; + var num = Math.min(5, player.hp, _status.renku.length); + trigger.player.chooseButton( + ["选择获得" + get.cnNumber(num) + "张牌", _status.renku], + true, + num + ); + "step 1"; + if (result.bool) { + var cards = result.links; _status.renku.removeArray(cards); game.updateRenku(); - trigger.player.gain(cards,'gain2','fromRenku'); - trigger.player.addTempSkill('spsongshu_block'); + trigger.player.gain(cards, "gain2", "fromRenku"); + trigger.player.addTempSkill("spsongshu_block"); } }, - init:function(player){ - player.storage.renku=true; + init: function (player) { + player.storage.renku = true; }, - subSkill:{ - block:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; + subSkill: { + block: { + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; }, }, - mark:true, - intro:{content:'不能对其他角色使用牌'}, + mark: true, + intro: { content: "不能对其他角色使用牌" }, }, }, }, //张机 - jishi:{ - audio:2, - trigger:{player:'useCardAfter'}, - forced:true, - filter:function(event,player){ - return event.cards.filterInD().length>0&&!player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length; + jishi: { + audio: 2, + trigger: { player: "useCardAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.cards.filterInD().length > 0 && + !player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length + ); }, - content:function(){ - var cards=trigger.cards.filterInD(); - game.log(player,'将',cards,'置于了仁库'); - game.cardsGotoSpecial(cards,'toRenku'); + content: function () { + var cards = trigger.cards.filterInD(); + game.log(player, "将", cards, "置于了仁库"); + game.cardsGotoSpecial(cards, "toRenku"); }, - init:function(player){ - player.storage.renku=true; + init: function (player) { + player.storage.renku = true; }, - group:'jishi_draw', - subSkill:{ - draw:{ - trigger:{ - global:['gainAfter','cardsDiscardAfter'], + group: "jishi_draw", + subSkill: { + draw: { + trigger: { + global: ["gainAfter", "cardsDiscardAfter"], }, - forced:true, - filter:function(event,player){ - return event.fromRenku==true&&!event.outRange; + forced: true, + filter: function (event, player) { + return event.fromRenku == true && !event.outRange; }, - content:function(){ + content: function () { player.draw(); }, }, }, }, - xinliaoyi:{ - audio:'liaoyi', - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - if(player==event.player) return false; - if(_status.renku.length) return true; - return event.player.countCards('h')>event.player.hp; + xinliaoyi: { + audio: "liaoyi", + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + if (player == event.player) return false; + if (_status.renku.length) return true; + return event.player.countCards("h") > event.player.hp; }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - var num=Math.max(0,target.countCards('h')-target.hp); - var choiceList=['令其从仁库中获得一张牌','令其将'+get.cnNumber(num)+'张手牌置入仁库']; - var choices=[]; - if(_status.renku.length) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(target.countCards('h')>target.hp){ - event.num=num; - choices.push('选项二'); - } - else choiceList[1]=''+choiceList[1]+''; - if(!choices.length) event.finish(); - else player.chooseControl(choices,'cancel2').set('prompt',get.prompt('xinliaoyi',target)).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().player; - var att=get.attitude(player,target); - if(att>0){ - if(_status.renku.length>0) return '选项一'; - return 0; - } - if(target.countCards('h')>target.hp) return '选项二'; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xinliaoyi',target); - if(result.control=='选项一'){ - target.chooseButton(true,['选择获得一张牌',_status.renku]).set('ai',function(button){ - return get.value(button.link,_status.event.player); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + var num = Math.max(0, target.countCards("h") - target.hp); + var choiceList = [ + "令其从仁库中获得一张牌", + "令其将" + get.cnNumber(num) + "张手牌置入仁库", + ]; + var choices = []; + if (_status.renku.length) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (target.countCards("h") > target.hp) { + event.num = num; + choices.push("选项二"); + } else choiceList[1] = '' + choiceList[1] + ""; + if (!choices.length) event.finish(); + else + player + .chooseControl(choices, "cancel2") + .set("prompt", get.prompt("xinliaoyi", target)) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player; + var att = get.attitude(player, target); + if (att > 0) { + if (_status.renku.length > 0) return "选项一"; + return 0; + } + if (target.countCards("h") > target.hp) return "选项二"; + return "cancel2"; }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xinliaoyi", target); + if (result.control == "选项一") { + target + .chooseButton(true, ["选择获得一张牌", _status.renku]) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); event.goto(4); + } else { + var hs = target.getCards("h"); + if (hs.length <= num) event._result = { bool: true, cards: hs }; + else + target.chooseCard( + "h", + true, + "将" + get.cnNumber(num) + "张手牌置于仁库中", + num + ); } - else{ - var hs=target.getCards('h'); - if(hs.length<=num) event._result={bool:true,cards:hs}; - else target.chooseCard('h',true,'将'+get.cnNumber(num)+'张手牌置于仁库中',num); - } - } - else event.finish(); - 'step 2' - if(result.bool){ - target.$throw(result.cards,1000); - game.log(target,'将',result.cards,'置入了仁库'); - target.lose(result.cards,ui.special,'toRenku'); - } - else event.finish(); - 'step 3' + } else event.finish(); + "step 2"; + if (result.bool) { + target.$throw(result.cards, 1000); + game.log(target, "将", result.cards, "置入了仁库"); + target.lose(result.cards, ui.special, "toRenku"); + } else event.finish(); + "step 3"; game.delayx(); event.finish(); - 'step 4' - var cards=result.links; + "step 4"; + var cards = result.links; _status.renku.removeArray(cards); game.updateRenku(); - target.gain(cards,'gain2','fromRenku'); + target.gain(cards, "gain2", "fromRenku"); }, - init:function(player){ - player.storage.renku=true; + init: function (player) { + player.storage.renku = true; }, - ai:{threaten:3.4}, + ai: { threaten: 3.4 }, }, - liaoyi:{ - audio:2, - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - if(player==event.player) return false; - var num=event.player.hp-event.player.countCards('h'); - if(num<0) return true; - return num>0&&_status.renku.length>=Math.min(4,num); + liaoyi: { + audio: 2, + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + if (player == event.player) return false; + var num = event.player.hp - event.player.countCards("h"); + if (num < 0) return true; + return num > 0 && _status.renku.length >= Math.min(4, num); }, - logTarget:'player', - prompt2:function(event,player){ - var target=event.player,num=target.hp-target.countCards('h'); - if(num<0) return '令'+get.translation(target)+'将'+get.cnNumber(Math.min(4,-num))+'张牌置入仁库'; - return '令'+get.translation(target)+'从仁库中获得'+get.cnNumber(Math.min(4,num))+'张牌'; + logTarget: "player", + prompt2: function (event, player) { + var target = event.player, + num = target.hp - target.countCards("h"); + if (num < 0) + return ( + "令" + + get.translation(target) + + "将" + + get.cnNumber(Math.min(4, -num)) + + "张牌置入仁库" + ); + return ( + "令" + + get.translation(target) + + "从仁库中获得" + + get.cnNumber(Math.min(4, num)) + + "张牌" + ); }, - check:function(event,player){ - var target=event.player,num=target.hp-target.countCards('h'),att=get.attitude(player,target); - if(num<0){ - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })>=(-num/2)) return att>0; - return att<=0; + check: function (event, player) { + var target = event.player, + num = target.hp - target.countCards("h"), + att = get.attitude(player, target); + if (num < 0) { + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) >= + -num / 2 + ) + return att > 0; + return att <= 0; } - return att>0; + return att > 0; }, - content:function(){ - 'step 0' - var target=trigger.player,num=target.hp-target.countCards('h'); - event.target=target; - if(num<0){ - num=Math.min(4,-num); - target.chooseCard('he',true,'将'+get.cnNumber(num)+'张牌置于仁库中',num); - } - else{ - num=Math.min(4,num); - target.chooseButton(['选择获得'+get.cnNumber(num)+'张牌',_status.renku],num,true).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); + content: function () { + "step 0"; + var target = trigger.player, + num = target.hp - target.countCards("h"); + event.target = target; + if (num < 0) { + num = Math.min(4, -num); + target.chooseCard("he", true, "将" + get.cnNumber(num) + "张牌置于仁库中", num); + } else { + num = Math.min(4, num); + target + .chooseButton(["选择获得" + get.cnNumber(num) + "张牌", _status.renku], num, true) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); event.goto(3); } - 'step 1' - if(result.bool){ - target.$throw(result.cards,1000); - game.log(target,'将',result.cards,'置入了仁库'); - target.lose(result.cards,ui.special,'toRenku'); - } - else event.finish(); - 'step 2' + "step 1"; + if (result.bool) { + target.$throw(result.cards, 1000); + game.log(target, "将", result.cards, "置入了仁库"); + target.lose(result.cards, ui.special, "toRenku"); + } else event.finish(); + "step 2"; game.delayx(); event.finish(); - 'step 3' - var cards=result.links; + "step 3"; + var cards = result.links; _status.renku.removeArray(cards); game.updateRenku(); - target.gain(cards,'gain2','fromRenku'); + target.gain(cards, "gain2", "fromRenku"); }, }, - binglun:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return _status.renku.length>0; + binglun: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return _status.renku.length > 0; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('病论',_status.renku); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("病论", _status.renku); }, - backup:function(links,player){ - var obj=lib.skill.binglun_backup; - obj.card=links[0]; + backup: function (links, player) { + var obj = lib.skill.binglun_backup; + obj.card = links[0]; return obj; }, - prompt:()=>'请选择【病论】的目标', + prompt: () => "请选择【病论】的目标", }, - subSkill:{ - backup:{ - audio:'binglun', - filterCard:()=>false, - selectCard:-1, - filterTarget:true, - delay:false, - content:function(){ - 'step 0' - var card=lib.skill.binglun_backup.card; - game.log(card,'从仁库进入了弃牌堆'); - player.$throw(card,1000); + subSkill: { + backup: { + audio: "binglun", + filterCard: () => false, + selectCard: -1, + filterTarget: true, + delay: false, + content: function () { + "step 0"; + var card = lib.skill.binglun_backup.card; + game.log(card, "从仁库进入了弃牌堆"); + player.$throw(card, 1000); game.delayx(); - game.cardsDiscard(card).fromRenku=true; + game.cardsDiscard(card).fromRenku = true; _status.renku.remove(card); game.updateRenku(); - 'step 1' - target.chooseControl().set('choiceList',[ - '摸一张牌', - '于自己的下回合结束后回复1点体力', - ]).set('ai',function(){ - if(_status.event.player.isHealthy()) return 0; - return 1; - }); - 'step 2' - if(result.index==0) target.draw(); - else{ - target.addSkill('binglun_recover'); - target.addMark('binglun_recover',1,false); + "step 1"; + target + .chooseControl() + .set("choiceList", ["摸一张牌", "于自己的下回合结束后回复1点体力"]) + .set("ai", function () { + if (_status.event.player.isHealthy()) return 0; + return 1; + }); + "step 2"; + if (result.index == 0) target.draw(); + else { + target.addSkill("binglun_recover"); + target.addMark("binglun_recover", 1, false); } }, - ai:{ - result:{ - target:function(player,target){ - if(target.isDamaged()) return 1.5; + ai: { + result: { + target: function (player, target) { + if (target.isDamaged()) return 1.5; return 1; }, }, }, }, - recover:{ - trigger:{player:'phaseEnd'}, - forced:true, - popup:false, - onremove:true, - charlotte:true, - content:function(){ - if(player.isDamaged()){ - player.logSkill('binglun_recover'); - player.recover(player.countMark('binglun_recover')); + recover: { + trigger: { player: "phaseEnd" }, + forced: true, + popup: false, + onremove: true, + charlotte: true, + content: function () { + if (player.isDamaged()) { + player.logSkill("binglun_recover"); + player.recover(player.countMark("binglun_recover")); } - player.removeSkill('binglun_recover'); + player.removeSkill("binglun_recover"); }, - intro:{ - content:'下回合结束时回复#点体力', + intro: { + content: "下回合结束时回复#点体力", }, - ai:{threaten:1.7}, + ai: { threaten: 1.7 }, }, }, - ai:{ - order:2, - result:{ - player:1, + ai: { + order: 2, + result: { + player: 1, }, }, }, - mjweipo:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return !current.hasSkill('mjweipo_effect'); + mjweipo: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return !current.hasSkill("mjweipo_effect"); }); }, - filterTarget:function(card,player,target){ - return !target.hasSkill('mjweipo_effect'); + filterTarget: function (card, player, target) { + return !target.hasSkill("mjweipo_effect"); }, - content:function(){ - 'step 0' - var list=['binglinchengxiax']; + content: function () { + "step 0"; + var list = ["binglinchengxiax"]; list.addArray(get.zhinangs()); - player.chooseButton(['危迫:选择一个智囊',[list,'vcard']],true).set('ai',function(button){ - return _status.event.getParent().target.getUseValue({name:button.link[2]}); - }); - 'step 1' - if(result.bool){ - var name=result.links[0][2]; - game.log(player,'选择了','#y'+get.translation(name)); - target.storage.mjweipo_effect=name; - target.storage.mjweipo_source=player; - target.addSkill('mjweipo_effect'); + player + .chooseButton(["危迫:选择一个智囊", [list, "vcard"]], true) + .set("ai", function (button) { + return _status.event.getParent().target.getUseValue({ name: button.link[2] }); + }); + "step 1"; + if (result.bool) { + var name = result.links[0][2]; + game.log(player, "选择了", "#y" + get.translation(name)); + target.storage.mjweipo_effect = name; + target.storage.mjweipo_source = player; + target.addSkill("mjweipo_effect"); game.delayx(); } }, - ai:{ - order:7.1, - result:{ - target:function(player,target){ - if(target==player) return player.countCards('hs','sha')>0?10:0.01; - return (target.countCards('hs','sha')+0.5)*Math.sqrt(Math.max(1,target.hp)); + ai: { + order: 7.1, + result: { + target: function (player, target) { + if (target == player) return player.countCards("hs", "sha") > 0 ? 10 : 0.01; + return (target.countCards("hs", "sha") + 0.5) * Math.sqrt(Math.max(1, target.hp)); }, }, }, }, - mjweipo_effect:{ - audio:'mjweipo', - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h','sha')>0; + mjweipo_effect: { + audio: "mjweipo", + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - prompt:function(){ - return '弃置一张【杀】并获得一张'+get.translation(_status.event.player.storage.mjweipo_effect); + prompt: function () { + return ( + "弃置一张【杀】并获得一张" + + get.translation(_status.event.player.storage.mjweipo_effect) + ); }, - filterCard:{name:'sha'}, - check:function(card){ - return 6-get.value(card); + filterCard: { name: "sha" }, + check: function (card) { + return 6 - get.value(card); }, - position:'h', - popname:true, - content:function(){ - var name=player.storage.mjweipo_effect,card=false; - if(name=='binglinchengxiax'){ - if(!_status.binglinchengxiax){ - _status.binglinchengxiax=[ - ['spade',7], - ['club',7], - ['club',13], + position: "h", + popname: true, + content: function () { + var name = player.storage.mjweipo_effect, + card = false; + if (name == "binglinchengxiax") { + if (!_status.binglinchengxiax) { + _status.binglinchengxiax = [ + ["spade", 7], + ["club", 7], + ["club", 13], ]; - game.broadcastAll(function(){lib.inpile.add('binglinchengxiax')}); + game.broadcastAll(function () { + lib.inpile.add("binglinchengxiax"); + }); } - if(_status.binglinchengxiax.length){ - var info=_status.binglinchengxiax.randomRemove(); - card=game.createCard2('binglinchengxiax',info[0],info[1]); + if (_status.binglinchengxiax.length) { + var info = _status.binglinchengxiax.randomRemove(); + card = game.createCard2("binglinchengxiax", info[0], info[1]); } } - if(!card) card=get.cardPile2(name); - if(card) player.gain(card,'gain2'); - player.removeSkill('mjweipo_effect'); + if (!card) card = get.cardPile2(name); + if (card) player.gain(card, "gain2"); + player.removeSkill("mjweipo_effect"); }, - ai:{ - order:7, - result:{player:1}, + ai: { + order: 7, + result: { player: 1 }, }, - mark:true, - marktext:'迫', - intro:{content:'可弃置一张【杀】并获得【$】'}, - group:'mjweipo_remove', + mark: true, + marktext: "迫", + intro: { content: "可弃置一张【杀】并获得【$】" }, + group: "mjweipo_remove", }, - mjweipo_remove:{ - trigger:{global:['phaseBegin','die']}, - forced:true, - firstDo:true, - popup:false, - filter:function(event,player){ - return event.player==player.storage.mjweipo_source; + mjweipo_remove: { + trigger: { global: ["phaseBegin", "die"] }, + forced: true, + firstDo: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.mjweipo_source; }, - content:function(){ - player.removeSkill('mjweipo_effect'); + content: function () { + player.removeSkill("mjweipo_effect"); }, }, - mjchenshi:{ - audio:2, - global:['mjchenshi_player','mjchenshi_target'], - ai:{combo:'mjweipo'}, + mjchenshi: { + audio: 2, + global: ["mjchenshi_player", "mjchenshi_target"], + ai: { combo: "mjweipo" }, }, - mjchenshi_player:{ - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - if(!event.card||event.card.name!='binglinchengxiax'||!event.isFirstTarget) return false; - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('mjchenshi'); - }); + mjchenshi_player: { + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + if (!event.card || event.card.name != "binglinchengxiax" || !event.isFirstTarget) + return false; + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.hasSkill("mjchenshi"); + }) + ); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('mjchenshi'); + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current != player && current.hasSkill("mjchenshi"); }); player.chooseCardTarget({ - prompt:'是否交给'+get.translation(list)+'一张牌,将牌堆顶三张牌中不为【杀】的牌置于弃牌堆?', - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ + prompt: + "是否交给" + + get.translation(list) + + "一张牌,将牌堆顶三张牌中不为【杀】的牌置于弃牌堆?", + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { return _status.event.list.includes(target); }, - list:list, - selectTarget:list.length>1?1:-1, - goon:function(){ - for(var i of list){ - if(get.attitude(player,i)>0) return 1; + list: list, + selectTarget: list.length > 1 ? 1 : -1, + goon: (function () { + for (var i of list) { + if (get.attitude(player, i) > 0) return 1; return -1; } - }(), - ai1:function(card){ - if(_status.event.goon>0) return 7-get.value(card); - return 0.01-get.value(card); + })(), + ai1: function (card) { + if (_status.event.goon > 0) return 7 - get.value(card); + return 0.01 - get.value(card); }, - ai2:function(target){ - var card=ui.selected.cards[0]; - return get.value(card,target)*get.attitude(_status.event.player,target); + ai2: function (target) { + var card = ui.selected.cards[0]; + return get.value(card, target) * get.attitude(_status.event.player, target); }, }); - 'step 1' - if(result.bool&&result.cards.length&&result.targets.length){ - var target=result.targets[0]; - target.logSkill('mjchenshi'); - player.line(target,'green'); - player.give(result.cards,target); - trigger.getParent().mjchenshi_ai=true; - } - else event.finish(); - 'step 2' - var cards=get.cards(3); - for(var i=cards.length-1;i>=0;i--){ - if(cards[i].name=='sha'){ + "step 1"; + if (result.bool && result.cards.length && result.targets.length) { + var target = result.targets[0]; + target.logSkill("mjchenshi"); + player.line(target, "green"); + player.give(result.cards, target); + trigger.getParent().mjchenshi_ai = true; + } else event.finish(); + "step 2"; + var cards = get.cards(3); + for (var i = cards.length - 1; i >= 0; i--) { + if (cards[i].name == "sha") { cards[i].fix(); - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); - cards.splice(i,1); + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); + cards.splice(i, 1); } } - if(cards.length){ - player.$throw(cards,1000); + if (cards.length) { + player.$throw(cards, 1000); game.delayx(); game.cardsDiscard(cards); - game.log(cards,'进入了弃牌堆'); + game.log(cards, "进入了弃牌堆"); } }, }, - mjchenshi_target:{ - trigger:{target:'useCardToTargeted'}, - direct:true, - filter:function(event,player){ - if(!event.card||event.card.name!='binglinchengxiax') return false; - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('mjchenshi'); - }); + mjchenshi_target: { + trigger: { target: "useCardToTargeted" }, + direct: true, + filter: function (event, player) { + if (!event.card || event.card.name != "binglinchengxiax") return false; + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.hasSkill("mjchenshi"); + }) + ); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('mjchenshi'); + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current != player && current.hasSkill("mjchenshi"); }); player.chooseCardTarget({ - prompt:'是否交给'+get.translation(list)+'一张牌,将牌堆顶三张牌中的【杀】置于弃牌堆?', - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ + prompt: + "是否交给" + + get.translation(list) + + "一张牌,将牌堆顶三张牌中的【杀】置于弃牌堆?", + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { return _status.event.list.includes(target); }, - list:list, - selectTarget:list.length>1?1:-1, - goon:function(){ - if(trigger.getParent().chenshi_ai) return 1; - for(var i of list){ - if(get.attitude(player,i)>0) return 1; + list: list, + selectTarget: list.length > 1 ? 1 : -1, + goon: (function () { + if (trigger.getParent().chenshi_ai) return 1; + for (var i of list) { + if (get.attitude(player, i) > 0) return 1; return -1; } - }(), - ai1:function(card){ - if(_status.event.goon>0) return 7-get.value(card); - return 3-get.value(card); + })(), + ai1: function (card) { + if (_status.event.goon > 0) return 7 - get.value(card); + return 3 - get.value(card); }, - ai2:function(target){ - var card=ui.selected.cards[0]; - return Math.max(0.1,get.value(card,target)*get.attitude(_status.event.player,target)); + ai2: function (target) { + var card = ui.selected.cards[0]; + return Math.max( + 0.1, + get.value(card, target) * get.attitude(_status.event.player, target) + ); }, }); - 'step 1' - if(result.bool&&result.cards.length&&result.targets.length){ - var target=result.targets[0]; - target.logSkill('mjchenshi'); - player.line(target,'green'); - player.give(result.cards,target); - } - else event.finish(); - 'step 2' - var cards=get.cards(3); - for(var i=cards.length-1;i>=0;i--){ - if(cards[i].name!='sha'){ + "step 1"; + if (result.bool && result.cards.length && result.targets.length) { + var target = result.targets[0]; + target.logSkill("mjchenshi"); + player.line(target, "green"); + player.give(result.cards, target); + } else event.finish(); + "step 2"; + var cards = get.cards(3); + for (var i = cards.length - 1; i >= 0; i--) { + if (cards[i].name != "sha") { cards[i].fix(); - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); - cards.splice(i,1); + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); + cards.splice(i, 1); } } - if(cards.length){ - player.$throw(cards,1000); + if (cards.length) { + player.$throw(cards, 1000); game.delayx(); game.cardsDiscard(cards); - game.log(cards,'进入了弃牌堆'); + game.log(cards, "进入了弃牌堆"); } }, }, - mjmouzhi:{ - audio:2, - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - if(!event.card||get.suit(event.card)=='none') return false; - var all=player.getAllHistory('damage'); - if(!all.length) return false; - return all[all.length-1].card&&get.suit(all[all.length-1].card)==get.suit(event.card); + mjmouzhi: { + audio: 2, + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + if (!event.card || get.suit(event.card) == "none") return false; + var all = player.getAllHistory("damage"); + if (!all.length) return false; + return ( + all[all.length - 1].card && get.suit(all[all.length - 1].card) == get.suit(event.card) + ); }, - content:function(){ + content: function () { trigger.cancel(); }, - group:'mjmouzhi_mark', - intro:{content:'上次受到伤害的花色:$'}, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(typeof card==='object'&&get.tag(card,'damage')){ - let suit=get.suit(card); - if(suit==='none') return; - let all=target.getAllHistory('damage'); - if(!all.length||!all[all.length-1].card) return; - if(get.suit(all[all.length-1].card)===suit) return 'zeroplayertarget'; + group: "mjmouzhi_mark", + intro: { content: "上次受到伤害的花色:$" }, + ai: { + effect: { + target: (card, player, target) => { + if (typeof card === "object" && get.tag(card, "damage")) { + let suit = get.suit(card); + if (suit === "none") return; + let all = target.getAllHistory("damage"); + if (!all.length || !all[all.length - 1].card) return; + if (get.suit(all[all.length - 1].card) === suit) return "zeroplayertarget"; } }, }, }, - subSkill:{ - mark:{ - trigger:{player:'damage'}, - silent:true, - firstDo:true, - content:function(){ - if(!trigger.card||get.suit(trigger.card)=='none') player.unmarkSkill('mjmouzhi'); - else{ - player.markSkill('mjmouzhi'); - game.broadcastAll(function(player,suit){ - if(player.marks.mjmouzhi) player.marks.mjmouzhi.firstChild.innerHTML=get.translation(suit); - player.storage.mjmouzhi=suit; - },player,get.suit(trigger.card)) + subSkill: { + mark: { + trigger: { player: "damage" }, + silent: true, + firstDo: true, + content: function () { + if (!trigger.card || get.suit(trigger.card) == "none") + player.unmarkSkill("mjmouzhi"); + else { + player.markSkill("mjmouzhi"); + game.broadcastAll( + function (player, suit) { + if (player.marks.mjmouzhi) + player.marks.mjmouzhi.firstChild.innerHTML = + get.translation(suit); + player.storage.mjmouzhi = suit; + }, + player, + get.suit(trigger.card) + ); } }, }, }, }, - mjshengxi:{ - audio:'shengxi', - audioname:['feiyi'], - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getHistory('useCard').length>0&&player.getHistory('sourceDamage').length==0; + mjshengxi: { + audio: "shengxi", + audioname: ["feiyi"], + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getHistory("useCard").length > 0 && + player.getHistory("sourceDamage").length == 0 + ); }, - content:function(){ - 'step 0' - var list=get.zhinangs(); - player.chooseButton([ - '###'+get.prompt('mjshengxi')+'###获得一张智囊或摸一张牌', - [list,'vcard'], - [['摸一张牌','取消'],'tdnodes'], - ],true).set('ai',function(card){ - if(card.link[2]){ - if(!get.cardPile2(function(cardx){ - return cardx.name==card.link[2]; - })) return 0; - return (Math.random()+1.5)*get.value({name:card.link[2]},_status.event.player); - } - if(card.link=='摸一张牌') return 1; - return 0; - }); - 'step 1' - if(result.bool&&result.links[0]!='取消'){ - player.logSkill('mjshengxi'); - if(result.links[0]=='摸一张牌') player.draw(); - else{ - var card=get.cardPile2(function(card){ - return card.name==result.links[0][2]; - }); - if(card) player.gain(card,'gain2'); - } - } - }, - group:'mjshengxi_zhunbei', - subfrequent:['zhunbei'], - subSkill:{ - zhunbei:{ - audio:'shengxi', - audioname:['feiyi'], - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - prompt2:'从游戏外或牌堆中获得一张【调剂盐梅】', - content:function(){ - if(!_status.tiaojiyanmei_suits||_status.tiaojiyanmei_suits.length>0){ - if(!lib.inpile.includes('tiaojiyanmei')) lib.inpile.add('tiaojiyanmei'); - if(!_status.tiaojiyanmei_suits) _status.tiaojiyanmei_suits=lib.suit.slice(0); - player.gain(game.createCard2('tiaojiyanmei',_status.tiaojiyanmei_suits.randomRemove(),6),'gain2'); + content: function () { + "step 0"; + var list = get.zhinangs(); + player + .chooseButton( + [ + "###" + get.prompt("mjshengxi") + "###获得一张智囊或摸一张牌", + [list, "vcard"], + [["摸一张牌", "取消"], "tdnodes"], + ], + true + ) + .set("ai", function (card) { + if (card.link[2]) { + if ( + !get.cardPile2(function (cardx) { + return cardx.name == card.link[2]; + }) + ) + return 0; + return ( + (Math.random() + 1.5) * + get.value({ name: card.link[2] }, _status.event.player) + ); } - else{ - var card=get.cardPile2(function(card){ - return card.name=='tiaojiyanmei'; - }); - if(card) player.gain(card,'gain2'); - } - }, - } - }, - }, - mjkuanji:{ - audio:'fyjianyu', - usable:1, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', - }, - direct:true, - filter:function(event,player){ - if(event.type!='discard') return false; - var evt=event.getl(player); - return evt.cards2.filterInD('d').length>0; - }, - content:function(){ - 'step 0' - var cards=trigger.getl(player).cards2; - player.chooseButton(['宽济:是否将一张牌交给一名其他角色?',cards.filterInD('d')]).set('ai',function(button){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })) return Math.abs(get.value(button.link,'raw'))+1; - return -get.value(button.link,'raw'); - }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('将'+get.translation(card)+'交给一名其他角色并摸一张牌',lib.filter.notMe,true).set('ai',function(target){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,target)*get.value(evt.card,target)*(target.hasSkillTag('nogain')?0.1:1); + if (card.link == "摸一张牌") return 1; + return 0; }); + "step 1"; + if (result.bool && result.links[0] != "取消") { + player.logSkill("mjshengxi"); + if (result.links[0] == "摸一张牌") player.draw(); + else { + var card = get.cardPile2(function (card) { + return card.name == result.links[0][2]; + }); + if (card) player.gain(card, "gain2"); + } } - else{ + }, + group: "mjshengxi_zhunbei", + subfrequent: ["zhunbei"], + subSkill: { + zhunbei: { + audio: "shengxi", + audioname: ["feiyi"], + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + prompt2: "从游戏外或牌堆中获得一张【调剂盐梅】", + content: function () { + if (!_status.tiaojiyanmei_suits || _status.tiaojiyanmei_suits.length > 0) { + if (!lib.inpile.includes("tiaojiyanmei")) lib.inpile.add("tiaojiyanmei"); + if (!_status.tiaojiyanmei_suits) + _status.tiaojiyanmei_suits = lib.suit.slice(0); + player.gain( + game.createCard2( + "tiaojiyanmei", + _status.tiaojiyanmei_suits.randomRemove(), + 6 + ), + "gain2" + ); + } else { + var card = get.cardPile2(function (card) { + return card.name == "tiaojiyanmei"; + }); + if (card) player.gain(card, "gain2"); + } + }, + }, + }, + }, + mjkuanji: { + audio: "fyjianyu", + usable: 1, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", + }, + direct: true, + filter: function (event, player) { + if (event.type != "discard") return false; + var evt = event.getl(player); + return evt.cards2.filterInD("d").length > 0; + }, + content: function () { + "step 0"; + var cards = trigger.getl(player).cards2; + player + .chooseButton(["宽济:是否将一张牌交给一名其他角色?", cards.filterInD("d")]) + .set("ai", function (button) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) + return Math.abs(get.value(button.link, "raw")) + 1; + return -get.value(button.link, "raw"); + }); + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + "将" + get.translation(card) + "交给一名其他角色并摸一张牌", + lib.filter.notMe, + true + ) + .set("ai", function (target) { + var evt = _status.event.getParent(); + return ( + get.attitude(evt.player, target) * + get.value(evt.card, target) * + (target.hasSkillTag("nogain") ? 0.1 : 1) + ); + }); + } else { player.storage.counttrigger.mjkuanji--; event.finish(); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('mjkuanji',target); - target.gain(card,'gain2'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("mjkuanji", target); + target.gain(card, "gain2"); player.draw(); } }, }, - mjdingyi:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + mjdingyi: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - logTarget:function(){ + logTarget: function () { return game.players; }, - content:function(){ - 'step 0' - var list=[]; - for(var i=0;i<4;i++) list.push(lib.skill['mjdingyi_'+i].title); - player.chooseControl().set('choiceList',list).set('prompt','定仪:请选择一个全局效果').set('ai',function(target){ - var list1=player.getEnemies().length; - var list2=game.players.length-list1; - if(list2-list1>1) return 0; - if(game.players.length<6) return 2; - return 3; - }); - 'step 1' - if(typeof result.index=='number'){ - var skill='mjdingyi_'+result.index; - game.log(player,'选择了','#g'+lib.skill[skill].title); - for(var i of game.players) i.addSkill(skill); + content: function () { + "step 0"; + var list = []; + for (var i = 0; i < 4; i++) list.push(lib.skill["mjdingyi_" + i].title); + player + .chooseControl() + .set("choiceList", list) + .set("prompt", "定仪:请选择一个全局效果") + .set("ai", function (target) { + var list1 = player.getEnemies().length; + var list2 = game.players.length - list1; + if (list2 - list1 > 1) return 0; + if (game.players.length < 6) return 2; + return 3; + }); + "step 1"; + if (typeof result.index == "number") { + var skill = "mjdingyi_" + result.index; + game.log(player, "选择了", "#g" + lib.skill[skill].title); + for (var i of game.players) i.addSkill(skill); game.delayx(); } }, - subSkill:{ - 0:{ - title:'摸牌阶段的额定摸牌数+1', - charlotte:true, - mark:true, - marktext:'仪', - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ + subSkill: { + 0: { + title: "摸牌阶段的额定摸牌数+1", + charlotte: true, + mark: true, + marktext: "仪", + trigger: { player: "phaseDrawBegin" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=((player.storage.mjdingyi_plus||0)+1); + content: function () { + trigger.num += (player.storage.mjdingyi_plus || 0) + 1; }, - intro:{ - content:function(storage,player){ - return '摸牌阶段的额定摸牌数+'+(1*((player.storage.mjdingyi_plus||0)+1)); + intro: { + content: function (storage, player) { + return ( + "摸牌阶段的额定摸牌数+" + 1 * ((player.storage.mjdingyi_plus || 0) + 1) + ); }, }, }, - 1:{ - title:'手牌上限+2', - charlotte:true, - mark:true, - marktext:'仪', - mod:{ - maxHandcard:function(player,num){ - return num+2*((player.storage.mjdingyi_plus||0)+1); + 1: { + title: "手牌上限+2", + charlotte: true, + mark: true, + marktext: "仪", + mod: { + maxHandcard: function (player, num) { + return num + 2 * ((player.storage.mjdingyi_plus || 0) + 1); }, }, - intro:{ - content:function(storage,player){ - return '手牌上限+'+(2*((player.storage.mjdingyi_plus||0)+1)); + intro: { + content: function (storage, player) { + return "手牌上限+" + 2 * ((player.storage.mjdingyi_plus || 0) + 1); }, }, }, - 2:{ - title:'攻击范围+1', - charlotte:true, - mark:true, - marktext:'仪', - mod:{ - attackRange:function(player,num){ - return num+((player.storage.mjdingyi_plus||0)+1); + 2: { + title: "攻击范围+1", + charlotte: true, + mark: true, + marktext: "仪", + mod: { + attackRange: function (player, num) { + return num + ((player.storage.mjdingyi_plus || 0) + 1); }, }, - intro:{ - content:function(storage,player){ - return '攻击范围+'+((player.storage.mjdingyi_plus||0)+1); + intro: { + content: function (storage, player) { + return "攻击范围+" + ((player.storage.mjdingyi_plus || 0) + 1); }, }, }, - 3:{ - title:'脱离濒死状态后回复1点体力', - charlotte:true, - mark:true, - marktext:'仪', - trigger:{player:'dyingAfter'}, - forced:true, - filter:function(event,player){ + 3: { + title: "脱离濒死状态后回复1点体力", + charlotte: true, + mark: true, + marktext: "仪", + trigger: { player: "dyingAfter" }, + forced: true, + filter: function (event, player) { return player.isDamaged(); }, - content:function(){ - player.recover((player.storage.mjdingyi_plus||0)+1); + content: function () { + player.recover((player.storage.mjdingyi_plus || 0) + 1); }, - intro:{ - content:function(storage,player){ - return '脱离濒死状态后回复'+((player.storage.mjdingyi_plus||0)+1)+'点体力'; + intro: { + content: function (storage, player) { + return ( + "脱离濒死状态后回复" + + ((player.storage.mjdingyi_plus || 0) + 1) + + "点体力" + ); }, }, }, }, }, - mjzuici:{ - audio:'zuici', - trigger:{player:'damageEnd'}, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - for(var i=0;i<4;i++){ - if(event.source.hasSkill('mjdingyi_'+i)) return true; + mjzuici: { + audio: "zuici", + trigger: { player: "damageEnd" }, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + for (var i = 0; i < 4; i++) { + if (event.source.hasSkill("mjdingyi_" + i)) return true; } return false; }, - logTarget:'source', - check:()=>false, - content:function(){ - 'step 0' - var target=trigger.source; - event.target=target; - for(var i=0;i<4;i++){ - if(target.hasSkill('mjdingyi_'+i)) target.removeSkill('mjdingyi_'+i); + logTarget: "source", + check: () => false, + content: function () { + "step 0"; + var target = trigger.source; + event.target = target; + for (var i = 0; i < 4; i++) { + if (target.hasSkill("mjdingyi_" + i)) target.removeSkill("mjdingyi_" + i); } - 'step 1' - var list=get.zhinangs(); - if(list.length){ - player.chooseButton(['选择要令'+get.translation(target)+'获得的智囊',[list,'vcard']],true); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=get.cardPile2(function(card){ - return card.name==result.links[0][2]; - }) - if(card) target.gain(card,'gain2'); + "step 1"; + var list = get.zhinangs(); + if (list.length) { + player.chooseButton( + ["选择要令" + get.translation(target) + "获得的智囊", [list, "vcard"]], + true + ); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = get.cardPile2(function (card) { + return card.name == result.links[0][2]; + }); + if (card) target.gain(card, "gain2"); } }, + ai: { + combo: "mjdingyi", + }, }, - mjfubi:{ - audio:'fubi', - enable:'phaseUse', - filter:function(event,player){ - if(player.hasSkill('mjfubi_round')) return false; - return game.hasPlayer(function(current){ - for(var i=0;i<4;i++){ - if(current.hasSkill('mjdingyi_'+i)) return true; + mjfubi: { + audio: "fubi", + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("mjfubi_round")) return false; + return game.hasPlayer(function (current) { + for (var i = 0; i < 4; i++) { + if (current.hasSkill("mjdingyi_" + i)) return true; } }); }, - filterCard:true, - selectCard:[0,1], - filterTarget:function(card,player,target){ - if(ui.selected.cards.length){ - for(var i=0;i<4;i++){ - if(target.hasSkill('mjdingyi_'+i)) return true; + filterCard: true, + selectCard: [0, 1], + filterTarget: function (card, player, target) { + if (ui.selected.cards.length) { + for (var i = 0; i < 4; i++) { + if (target.hasSkill("mjdingyi_" + i)) return true; } } - var num=0; - for(var i=0;i<4;i++){ - if(target.hasSkill('mjdingyi_'+i)) return true; + var num = 0; + for (var i = 0; i < 4; i++) { + if (target.hasSkill("mjdingyi_" + i)) return true; } - return num>1&&num<4; + return num > 1 && num < 4; }, - check:()=>false, - position:'he', - content:function(){ - 'step 0' - player.addTempSkill('mjfubi_round','roundStart'); - if(cards.length){ - player.addSkill('mjfubi_clear'); - player.markAuto('mjfubi_clear',[target]); - target.addMark('mjdingyi_plus',1,false); - game.log(target,'的','#g【定仪】','效果增加一倍'); + check: () => false, + position: "he", + content: function () { + "step 0"; + player.addTempSkill("mjfubi_round", "roundStart"); + if (cards.length) { + player.addSkill("mjfubi_clear"); + player.markAuto("mjfubi_clear", [target]); + target.addMark("mjdingyi_plus", 1, false); + game.log(target, "的", "#g【定仪】", "效果增加一倍"); event.finish(); return; } - var list=[],nums=[]; - for(var i=0;i<4;i++){ - if(!target.hasSkill('mjdingyi_'+i)){ - list.push(lib.skill['mjdingyi_'+i].title); + var list = [], + nums = []; + for (var i = 0; i < 4; i++) { + if (!target.hasSkill("mjdingyi_" + i)) { + list.push(lib.skill["mjdingyi_" + i].title); nums.push(i); } } - if(list.length){ - event.nums=nums; - player.chooseControl().set('choiceList',list).set('prompt','辅弼:请选择为'+get.translation(target)+'更换的〖定仪〗效果').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - if(get.attitude(player,target)>0&&!target.hasSkill('mjdingyi_0')) return 0; - return _status.event.getParent().nums.length-1; - }); + if (list.length) { + event.nums = nums; + player + .chooseControl() + .set("choiceList", list) + .set("prompt", "辅弼:请选择为" + get.translation(target) + "更换的〖定仪〗效果") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + if (get.attitude(player, target) > 0 && !target.hasSkill("mjdingyi_0")) + return 0; + return _status.event.getParent().nums.length - 1; + }); + } else event.finish(); + "step 1"; + for (var i = 0; i < 4; i++) { + if (target.hasSkill("mjdingyi_" + i)) target.removeSkill("mjdingyi_" + i); } - else event.finish(); - 'step 1' - for(var i=0;i<4;i++){ - if(target.hasSkill('mjdingyi_'+i)) target.removeSkill('mjdingyi_'+i); - } - target.addSkill('mjdingyi_'+event.nums[result.index]); - game.log(target,'的效果被改为','#g'+lib.skill['mjdingyi_'+event.nums[result.index]].title); + target.addSkill("mjdingyi_" + event.nums[result.index]); + game.log( + target, + "的效果被改为", + "#g" + lib.skill["mjdingyi_" + event.nums[result.index]].title + ); }, - ai:{ - order:10, - expose:0, - result:{ - target:function(player,target){ - if(target.hasSkill('mjdingyi_0')) return -1; + ai: { + order: 10, + expose: 0, + result: { + target: function (player, target) { + if (target.hasSkill("mjdingyi_0")) return -1; return 2; }, }, + combo: "mjdingyi", }, - subSkill:{ - round:{}, - clear:{ - trigger:{player:['phaseBegin','dieBegin']}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - while(player.storage.mjfubi_clear&&player.storage.mjfubi_clear.length){ - var target=player.storage.mjfubi_clear.shift(); - if(target.hasMark('mjdingyi_plus')) target.removeMark('mjdingyi_plus',1,false); + subSkill: { + round: {}, + clear: { + trigger: { player: ["phaseBegin", "dieBegin"] }, + forced: true, + popup: false, + charlotte: true, + content: function () { + while (player.storage.mjfubi_clear && player.storage.mjfubi_clear.length) { + var target = player.storage.mjfubi_clear.shift(); + if (target.hasMark("mjdingyi_plus")) + target.removeMark("mjdingyi_plus", 1, false); } delete player.storage.mjfubi_clear; - player.removeSkill('mjfubi_clear'); + player.removeSkill("mjfubi_clear"); }, }, }, }, - boming:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return player.countCards('he')>0; + boming: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - content:function(){ - player.give(cards,target); + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + content: function () { + player.give(cards, target); }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - var card=ui.selected.cards[0]; - if(player.hasSkill('ejian')&&!player.getStorage('ejian').includes(target)){ - var dam=get.damageEffect(target,player,target); - if(dam>0) return dam; - var type=get.type(card,target),ts=target.getCards('he',function(card){ - return get.type(card)==type; - }); - if(ts.length){ - var val=get.value(ts,target); - if(val>get.value(card)) return -Math.max(1,val); + ai: { + order: 10, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + var card = ui.selected.cards[0]; + if (player.hasSkill("ejian") && !player.getStorage("ejian").includes(target)) { + var dam = get.damageEffect(target, player, target); + if (dam > 0) return dam; + var type = get.type(card, target), + ts = target.getCards("he", function (card) { + return get.type(card) == type; + }); + if (ts.length) { + var val = get.value(ts, target); + if (val > get.value(card)) return -Math.max(1, val); return 0; } } - return get.value(card,target)/1.5; + return get.value(card, target) / 1.5; }, }, }, - group:'boming_draw', - subSkill:{ - draw:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - return evt.getParent(2).name=='boming'; - }).length>1; + group: "boming_draw", + subSkill: { + draw: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player.getHistory("lose", function (evt) { + return evt.getParent(2).name == "boming"; + }).length > 1 + ); }, - content:function(){ + content: function () { player.draw(); }, }, }, }, - ejian:{ - audio:2, - trigger:{global:'gainAfter'}, - forced:true, - filter:function(event,player){ - var evt=event.getParent(),target=event.player; - if(evt.name!='boming'||evt.player!=player||player.getStorage('ejian').includes(target)||!target.isIn()) return false; - var he=target.getCards('he'),card=event.cards[0]; - if(!he.includes(card)) return false; - var type=get.type2(card); - for(var i of he){ - if(i!=card&&get.type2(i)==type) return true; + ejian: { + audio: 2, + trigger: { global: "gainAfter" }, + forced: true, + filter: function (event, player) { + var evt = event.getParent(), + target = event.player; + if ( + evt.name != "boming" || + evt.player != player || + player.getStorage("ejian").includes(target) || + !target.isIn() + ) + return false; + var he = target.getCards("he"), + card = event.cards[0]; + if (!he.includes(card)) return false; + var type = get.type2(card); + for (var i of he) { + if (i != card && get.type2(i) == type) return true; } return false; }, - logTarget:'player', - content:function(){ - 'step 0' - event.cardType=get.type2(trigger.cards[0]); - event.target=trigger.player; - player.markAuto('ejian',[event.target]); - event.target.chooseControl().set('choiceList',[ - '受到1点伤害', - '展示手牌并弃置所有'+get.translation(event.cardType)+'牌', - ]).set('ai',function(event,player){ - if(get.damageEffect(player,_status.event.getParent().player,player)>=0) return 0; - var type=_status.event.cardType,cards=player.getCards('he',function(card){ - return get.type2(card)==type; - }); - if(cards.length==1) return 1; - if(cards.length>=2){ - for(var i=0;i= 0) + return 0; + var type = _status.event.cardType, + cards = player.getCards("he", function (card) { + return get.type2(card) == type; + }); + if (cards.length == 1) return 1; + if (cards.length >= 2) { + for (var i = 0; i < cards.length; i++) { + if (get.tag(cards[i], "save")) return 0; + } } - } - if(player.hp==1) return 1; - for(var i=0;i=8) return 0; - } - if(cards.length>2&&player.hp>2) return 0; - if(cards.length>3) return 0; - return 1; - }).set('cardType',event.cardType); - 'step 1' - if(result.index==1){ - if(target.countCards('h')>0) target.showHandcards(); - } - else{ + if (player.hp == 1) return 1; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) >= 8) return 0; + } + if (cards.length > 2 && player.hp > 2) return 0; + if (cards.length > 3) return 0; + return 1; + }) + .set("cardType", event.cardType); + "step 1"; + if (result.index == 1) { + if (target.countCards("h") > 0) target.showHandcards(); + } else { target.damage(); event.finish(); } - 'step 2' - target.discard(target.getCards('he',function(card){ - return get.type2(card)==event.cardType; - })); + "step 2"; + target.discard( + target.getCards("he", function (card) { + return get.type2(card) == event.cardType; + }) + ); }, - ai:{combo:'boming',halfneg:true}, - onremove:true, - intro:{content:'已对$发动过此技能'}, + ai: { combo: "boming", halfneg: true }, + onremove: true, + intro: { content: "已对$发动过此技能" }, }, - hxrenshi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0&&(!player.storage.hxrenshi2||game.hasPlayer(function(current){ - return !player.storage.hxrenshi2.includes(current); - })) + hxrenshi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + (!player.storage.hxrenshi2 || + game.hasPlayer(function (current) { + return !player.storage.hxrenshi2.includes(current); + })) + ); }, - filterCard:true, - filterTarget:function(card,player,target){ - return !player.storage.hxrenshi2||!player.storage.hxrenshi2.includes(target); + filterCard: true, + filterTarget: function (card, player, target) { + return !player.storage.hxrenshi2 || !player.storage.hxrenshi2.includes(target); }, - position:'h', - discard:false, - lose:false, - delay:false, - check:function(cardx){ - var player=_status.event.player; - if(player.getStorage('debao').length==1&&(!game.hasPlayer(function(current){ - return get.attitude(player,current)>0&¤t.hp*1.5+current.countCards('h')<4; - })||game.hasPlayer(function(current){ - return get.attitude(player,current)<=0&¤t.hp*1.5+current.countCards('h')<4; - }))) return 0; - return 5-get.value(cardx); + position: "h", + discard: false, + lose: false, + delay: false, + check: function (cardx) { + var player = _status.event.player; + if ( + player.getStorage("debao").length == 1 && + (!game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + current.hp * 1.5 + current.countCards("h") < 4 + ); + }) || + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) <= 0 && + current.hp * 1.5 + current.countCards("h") < 4 + ); + })) + ) + return 0; + return 5 - get.value(cardx); }, - content:function(){ - player.addTempSkill('hxrenshi2','phaseUseEnd'); - player.markAuto('hxrenshi2',targets); - player.give(cards,target); + content: function () { + player.addTempSkill("hxrenshi2", "phaseUseEnd"); + player.markAuto("hxrenshi2", targets); + player.give(cards, target); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(ui.selected.cards.length) return get.value(ui.selected.cards[0],target)+0.1; + ai: { + order: 1, + result: { + target: function (player, target) { + if (ui.selected.cards.length) + return get.value(ui.selected.cards[0], target) + 0.1; return 0; }, }, }, }, - hxrenshi2:{ - onremove:true, + hxrenshi2: { + onremove: true, }, - debao:{ - audio:2, - trigger:{global:'gainAfter'}, - forced:true, - filter:function(event,player){ - if(player==event.player||player.getStorage('debao').length>=player.maxHp) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + debao: { + audio: 2, + trigger: { global: "gainAfter" }, + forced: true, + filter: function (event, player) { + if (player == event.player || player.getStorage("debao").length >= player.maxHp) + return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - content:function(){ - var cards=get.cards(); - player.markAuto('debao',cards); - player.$gain2(cards[0],false); + content: function () { + var cards = get.cards(); + player.markAuto("debao", cards); + player.$gain2(cards[0], false); game.cardsGotoSpecial(cards); - game.log(player,'将',cards[0],'放在了武将牌上'); + game.log(player, "将", cards[0], "放在了武将牌上"); game.delayx(); }, - marktext:'仁', - intro:{content:'cards',onunmark:'throw'}, - group:'debao_gain', - subSkill:{ - gain:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getStorage('debao').length>0; + marktext: "仁", + intro: { content: "cards", onunmark: "throw" }, + group: "debao_gain", + subSkill: { + gain: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.getStorage("debao").length > 0; }, - content:function(){ - var cards=player.storage.debao; - player.gain(cards,'gain2','fromStorage'); - cards.length=0; - player.unmarkSkill('debao'); + content: function () { + var cards = player.storage.debao; + player.gain(cards, "gain2", "fromStorage"); + cards.length = 0; + player.unmarkSkill("debao"); }, }, }, }, - buqi:{ - audio:2, - trigger:{global:'dying'}, - forced:true, - filter:function(event,player){ - return player.getStorage('debao').length>1; + buqi: { + audio: 2, + trigger: { global: "dying" }, + forced: true, + filter: function (event, player) { + return player.getStorage("debao").length > 1; }, - logTarget:'player', - content:function(){ - 'step 0' - var cards=player.getStorage('debao'); - if(cards.length==2) event._result={bool:true,links:cards.slice(0)}; - else player.chooseButton(['不弃:请选择移去两张“仁”',cards],2,true); - 'step 1' - if(result.bool){ - var cards=result.links; - player.unmarkAuto('debao',cards); - player.$throw(cards,1000); - game.log(player,'将',cards,'置入了弃牌堆'); + logTarget: "player", + content: function () { + "step 0"; + var cards = player.getStorage("debao"); + if (cards.length == 2) event._result = { bool: true, links: cards.slice(0) }; + else player.chooseButton(["不弃:请选择移去两张“仁”", cards], 2, true); + "step 1"; + if (result.bool) { + var cards = result.links; + player.unmarkAuto("debao", cards); + player.$throw(cards, 1000); + game.log(player, "将", cards, "置入了弃牌堆"); game.delayx(); game.cardsDiscard(cards); - } - else event.finish(); - 'step 2' - if(trigger.player.isIn()&&trigger.player.isDamaged()) trigger.player.recover(); + } else event.finish(); + "step 2"; + if (trigger.player.isIn() && trigger.player.isDamaged()) trigger.player.recover(); }, - group:'buqi_die', - subSkill:{ - die:{ - trigger:{global:'dieAfter'}, - forced:true, - filter:function(event,player){ - return player.getStorage('debao').length>0; + group: "buqi_die", + subSkill: { + die: { + trigger: { global: "dieAfter" }, + forced: true, + filter: function (event, player) { + return player.getStorage("debao").length > 0; }, - content:function(){ - player.unmarkSkill('debao'); + content: function () { + player.unmarkSkill("debao"); }, }, }, - ai:{ - neg:true, - combo:'debao', + ai: { + neg: true, + combo: "debao", }, }, - guying:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + guying: { + audio: 2, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - forced:true, - usable:1, - filter:function(event,player){ - if(event.type!='discard'){ - var evt=event.getParent(); - if(evt.name!='useCard'&&evt.name!='respond') return false; + forced: true, + usable: 1, + filter: function (event, player) { + if (event.type != "discard") { + var evt = event.getParent(); + if (evt.name != "useCard" && evt.name != "respond") return false; } - var target=_status.currentPhase,evt=event.getl(player); - if(!evt.cards2||evt.cards2.length!=1||!target||target==player||!target.isIn()) return false; - return get.position(evt.cards2[0])=='d'||target.countCards('he')<0; + var target = _status.currentPhase, + evt = event.getl(player); + if ( + !evt.cards2 || + evt.cards2.length != 1 || + !target || + target == player || + !target.isIn() + ) + return false; + return get.position(evt.cards2[0]) == "d" || target.countCards("he") < 0; }, - logTarget:function(){ + logTarget: function () { return _status.currentPhase; }, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - event.target=_status.currentPhase; - event.card=trigger.getl(player).cards2[0]; - 'step 1' - player.addMark('guying',1,false); - event.addIndex=0; - var choiceList=[],str=get.translation(player); - if(target.countCards('he')>0) choiceList.push('随机交给'+str+'一张牌'); + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + event.target = _status.currentPhase; + event.card = trigger.getl(player).cards2[0]; + "step 1"; + player.addMark("guying", 1, false); + event.addIndex = 0; + var choiceList = [], + str = get.translation(player); + if (target.countCards("he") > 0) choiceList.push("随机交给" + str + "一张牌"); else event.addIndex++; - if(get.position(card)=='d') choiceList.push('令'+str+'收回'+get.translation(card)); - if(choiceList.length==1) event._result={index:0}; - target.chooseControl().set('choiceList',choiceList).set('ai',function(){ - 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; - }); - 'step 2' - if(result.index+event.addIndex==0){ - target.give(target.getCards('he').randomGet(),player); + if (get.position(card) == "d") + choiceList.push("令" + str + "收回" + get.translation(card)); + if (choiceList.length == 1) event._result = { index: 0 }; + target + .chooseControl() + .set("choiceList", choiceList) + .set("ai", function () { + 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; + }); + "step 2"; + if (result.index + event.addIndex == 0) { + target.give(target.getCards("he").randomGet(), player); event.finish(); - } - else player.gain(card,'gain2'); - 'step 3' - if(player.isIn()&&player.getCards('h').includes(card)&&get.type(card,player)=='equip') player.chooseUseTarget(card,true,'nopopup'); + } else player.gain(card, "gain2"); + "step 3"; + if ( + player.isIn() && + player.getCards("h").includes(card) && + get.type(card, player) == "equip" + ) + player.chooseUseTarget(card, true, "nopopup"); }, - onremove:true, - intro:{content:'已发动过#次'}, - group:'guying_discard', - subSkill:{ - discard:{ - audio:'guying', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('guying')>0; + onremove: true, + intro: { content: "已发动过#次" }, + group: "guying_discard", + subSkill: { + discard: { + audio: "guying", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("guying") > 0; }, - content:function(){ - var num=player.countMark('guying'); - player.removeMark('guying',num,false); - player.chooseToDiscard('he',num,true); + content: function () { + var num = player.countMark("guying"); + player.removeMark("guying", num, false); + player.chooseToDiscard("he", num, true); }, }, }, }, - muzhen:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - if(!player.hasSkill('muzhen1')&&player.countCards('e')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - })) return true; - if(!player.hasSkill('muzhen2')&&player.countCards('he')>1&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e')>0; - })) return true; + muzhen: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + if ( + !player.hasSkill("muzhen1") && + player.countCards("e") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ) + return true; + if ( + !player.hasSkill("muzhen2") && + player.countCards("he") > 1 && + game.hasPlayer(function (current) { + return current != player && current.countCards("e") > 0; + }) + ) + return true; return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[ - '将一张装备牌置于其他角色的装备区内并获得其一张手牌', - '将两张牌交给一名其他角色并获得其装备区内的一张牌', + chooseButton: { + dialog: function (event, player) { + var list = [ + "将一张装备牌置于其他角色的装备区内并获得其一张手牌", + "将两张牌交给一名其他角色并获得其装备区内的一张牌", ]; - var choiceList=ui.create.dialog('睦阵:请选择一项','hidden'); - choiceList.add([list.map((item,i)=>{ - return [i,item]; - }),'textbutton']); + var choiceList = ui.create.dialog("睦阵:请选择一项", "hidden"); + choiceList.add([ + list.map((item, i) => { + return [i, item]; + }), + "textbutton", + ]); return choiceList; }, - filter:function(button,player){ - if(button.link==0) return !player.hasSkill('muzhen1')&&player.countCards('e')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }) - return !player.hasSkill('muzhen2')&&player.countCards('he')>1&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e')>0; - }); + filter: function (button, player) { + if (button.link == 0) + return ( + !player.hasSkill("muzhen1") && + player.countCards("e") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); + return ( + !player.hasSkill("muzhen2") && + player.countCards("he") > 1 && + game.hasPlayer(function (current) { + return current != player && current.countCards("e") > 0; + }) + ); }, - backup:function(links){ + backup: function (links) { return { - audio:'muzhen', - filterTarget:[ - function(card,player,target){ - return target.countCards('h')>0&&target.canEquip(ui.selected.cards[0]); + audio: "muzhen", + filterTarget: [ + function (card, player, target) { + return ( + target.countCards("h") > 0 && target.canEquip(ui.selected.cards[0]) + ); + }, + function (card, player, target) { + return target.countCards("e") > 0; }, - function(card,player,target){ - return target.countCards('e')>0; - } ][links[0]], - filterCard:[ - function(card,player){ - if(ui.selected.targets.length) return ui.selected.targets[0].canEquip(card); - return game.hasPlayer(function(current){ - return current.countCards('h')>0&¤t.canEquip(card); - }) + filterCard: [ + function (card, player) { + if (ui.selected.targets.length) + return ui.selected.targets[0].canEquip(card); + return game.hasPlayer(function (current) { + return current.countCards("h") > 0 && current.canEquip(card); + }); }, true, ], - selectCard:1+links[0], - position:('eh')[links[0]], - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.addTempSkill('muzhen'+cards.length,'phaseUseEnd'); - if(cards.length==1){ - player.$giveAuto(cards[0],target); + selectCard: 1 + links[0], + position: "eh"[links[0]], + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.addTempSkill("muzhen" + cards.length, "phaseUseEnd"); + if (cards.length == 1) { + player.$giveAuto(cards[0], target); game.delayx(); target.equip(cards[0]); + } else { + player.give(cards, target); } - else{ - player.give(cards,target); - } - player.gainPlayerCard(target,cards.length==2?'e':'h',true); + player.gainPlayerCard(target, cards.length == 2 ? "e" : "h", true); }, - } + }; }, - prompt:function(){ - return '请选择【睦阵】的牌和目标' + prompt: function () { + return "请选择【睦阵】的牌和目标"; }, }, }, - muzhen1:{}, - muzhen2:{}, - sheyi2:{charlotte:true}, - sheyi:{ - audio:2, - trigger:{global:'damageBegin4'}, - direct:true, - filter:function(event,player){ - return !player.hasSkill('sheyi2')&&player!=event.player&&event.player.hp=Math.max(1,player.hp); + muzhen1: {}, + muzhen2: {}, + sheyi2: { charlotte: true }, + sheyi: { + audio: 2, + trigger: { global: "damageBegin4" }, + direct: true, + filter: function (event, player) { + return ( + !player.hasSkill("sheyi2") && + player != event.player && + event.player.hp < player.hp && + player.countCards("he") >= Math.max(1, player.hp) + ); }, - content:function(){ - 'step 0' - var num=Math.max(1,player.hp),target=trigger.player; - player.chooseCard('he',get.prompt('sheyi',target),'交给其至少'+get.cnNumber(num)+'张牌,防止即将受到的伤害('+trigger.num+'点)',[num,player.countCards('he')]).set('goon',function(){ - if(get.attitude(player,target)<0) return false; - if(trigger.num=0) return false; - if(trigger.num<2&&target.hp>trigger.num) return 6/Math.sqrt(num); - if(target==get.zhu(player)) return 9; - return 8/Math.sqrt(num); - }()).set('ai',function(card){ - if(ui.selected.cards.length>=Math.max(1,_status.event.player.hp)) return 0; - if(typeof _status.event.goon=='number') return _status.event.goon-get.value(card); - return 0; - }); - 'step 1' - if(result.bool){ - var target=trigger.player; - player.logSkill('sheyi',target); - player.addTempSkill('sheyi2','roundStart'); - player.give(result.cards,target); + content: function () { + "step 0"; + var num = Math.max(1, player.hp), + target = trigger.player; + player + .chooseCard( + "he", + get.prompt("sheyi", target), + "交给其至少" + + get.cnNumber(num) + + "张牌,防止即将受到的伤害(" + + trigger.num + + "点)", + [num, player.countCards("he")] + ) + .set( + "goon", + (function () { + if (get.attitude(player, target) < 0) return false; + if ( + trigger.num < target.hp && + get.damageEffect(target, trigger.source, player, trigger.nature) >= 0 + ) + return false; + if (trigger.num < 2 && target.hp > trigger.num) return 6 / Math.sqrt(num); + if (target == get.zhu(player)) return 9; + return 8 / Math.sqrt(num); + })() + ) + .set("ai", function (card) { + if (ui.selected.cards.length >= Math.max(1, _status.event.player.hp)) return 0; + if (typeof _status.event.goon == "number") + return _status.event.goon - get.value(card); + return 0; + }); + "step 1"; + if (result.bool) { + var target = trigger.player; + player.logSkill("sheyi", target); + player.addTempSkill("sheyi2", "roundStart"); + player.give(result.cards, target); trigger.cancel(); } }, }, - tianyin:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - var list=[]; - player.getHistory('useCard',function(evt){ - list.add(get.type2(evt.card,false)); + tianyin: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + var list = []; + player.getHistory("useCard", function (evt) { + list.add(get.type2(evt.card, false)); }); - for(var i=0;i0; + xunyi3: { + audio: "xunyi", + trigger: { global: "damageEnd" }, + forced: true, + charlotte: true, + filter: function (event, player) { + var list = [player, player.storage.xunyi2]; + return ( + list.includes(event.player) && + !list.includes(event.source) && + (player == event.player ? player.storage.xunyi2 : player).countCards("he") > 0 + ); }, - logTarget:function(event,player){ + logTarget: function (event, player) { return player.storage.xunyi2; }, - content:function(){ - (player==trigger.player?player.storage.xunyi2:player).chooseToDiscard('he',true); + content: function () { + (player == trigger.player ? player.storage.xunyi2 : player).chooseToDiscard("he", true); }, }, //狗剩 - reduoji:{ - audio:'duoji', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + reduoji: { + audio: "duoji", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - discard:false, - toStorage:true, - delay:false, - check:function(card){ - return 3-get.value(card); + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + discard: false, + toStorage: true, + delay: false, + check: function (card) { + return 3 - get.value(card); }, - content:function(){ - 'step 0' - player.$give(cards[0],target,false); - target.markAuto('reduoji',cards); - game.log(player,'将',cards[0],'放在了',target,'的武将牌上'); - 'step 1' + content: function () { + "step 0"; + player.$give(cards[0], target, false); + target.markAuto("reduoji", cards); + game.log(player, "将", cards[0], "放在了", target, "的武将牌上"); + "step 1"; game.delay(); }, - group:['reduoji_equip','reduoji_gain'], - intro:{ - content:'cards', - onunmark:'throw', + group: ["reduoji_equip", "reduoji_gain"], + intro: { + content: "cards", + onunmark: "throw", }, - ai:{ - order:1, - result:{target:-1}, + ai: { + order: 1, + result: { target: -1 }, }, - subSkill:{ - equip:{ - audio:'duoji', - trigger:{global:'equipAfter'}, - forced:true, - filter:function(event,player){ - if(player==event.player||!event.player.getStorage('reduoji').length||!event.player.getCards('e').includes(event.card)) return false; - var evt=event.getParent(2); - return evt.name=='useCard'&&evt.player==event.player; + subSkill: { + equip: { + audio: "duoji", + trigger: { global: "equipAfter" }, + forced: true, + filter: function (event, player) { + if ( + player == event.player || + !event.player.getStorage("reduoji").length || + !event.player.getCards("e").includes(event.card) + ) + return false; + var evt = event.getParent(2); + return evt.name == "useCard" && evt.player == event.player; }, - logTarget:'player', - content:function(){ - 'step 0' - player.gain(trigger.card,trigger.player,'give','bySelf'); - 'step 1' - var target=trigger.player,storage=target.getStorage('reduoji'); - if(storage.length){ - var card=storage[0]; - target.$throw(card,1000); - target.unmarkAuto('reduoji',[card]); - game.log(target,'移去了',card); + logTarget: "player", + content: function () { + "step 0"; + player.gain(trigger.card, trigger.player, "give", "bySelf"); + "step 1"; + var target = trigger.player, + storage = target.getStorage("reduoji"); + if (storage.length) { + var card = storage[0]; + target.$throw(card, 1000); + target.unmarkAuto("reduoji", [card]); + game.log(target, "移去了", card); game.cardsDiscard(card); target.draw(); } }, }, - gain:{ - audio:'duoji', - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return event.player.getStorage('reduoji').length>0; + gain: { + audio: "duoji", + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return event.player.getStorage("reduoji").length > 0; }, - logTarget:'player', - content:function(){ - var target=trigger.player,cards=target.storage.reduoji; - target.$give(cards,player); - player.gain(cards,'fromStorage'); - cards.length=0; - target.unmarkSkill('reduoji'); + logTarget: "player", + content: function () { + var target = trigger.player, + cards = target.storage.reduoji; + target.$give(cards, player); + player.gain(cards, "fromStorage"); + cards.length = 0; + target.unmarkSkill("reduoji"); game.delay(); }, }, }, }, //SP辛毗 - spyinju:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - "step 0" - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'引裾:对'+get.translation(player)+'使用一张杀,或跳过下回合的出牌阶段和弃牌阶段').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',player); - "step 1" - if(!result.bool) target.addSkill('spyinju2'); + spyinju: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "引裾:对" + + get.translation(player) + + "使用一张杀,或跳过下回合的出牌阶段和弃牌阶段") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + if (!result.bool) target.addSkill("spyinju2"); }, - ai:{ - order:1, - expose:0.2, - result:{ - target:-1.5, - player:function(player,target){ - if(!target.canUse('sha',player)) return 0; - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.countCards('h','shan')==0) return -1; - if(player.hp<2) return -2; + ai: { + order: 1, + expose: 0.2, + result: { + target: -1.5, + player: function (player, target) { + if (!target.canUse("sha", player)) return 0; + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.countCards("h", "shan") == 0) return -1; + if (player.hp < 2) return -2; return -0.5; - } + }, }, - threaten:1.1 - } + threaten: 1.1, + }, }, - spyinju2:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - charlotte:true, - content:function(){ - player.skip('phaseUse'); - player.skip('phaseDiscard'); - player.removeSkill('spyinju2'); - game.log(player,'跳过了出牌阶段'); - game.log(player,'跳过了弃牌阶段'); + spyinju2: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + charlotte: true, + content: function () { + player.skip("phaseUse"); + player.skip("phaseDiscard"); + player.removeSkill("spyinju2"); + game.log(player, "跳过了出牌阶段"); + game.log(player, "跳过了弃牌阶段"); }, - mark:true, - intro:{content:'衣襟被拽住了,下个准备阶段开始时跳过出牌阶段和弃牌阶段'}, + mark: true, + intro: { content: "衣襟被拽住了,下个准备阶段开始时跳过出牌阶段和弃牌阶段" }, }, - spchijie:{ - audio:2, - trigger:{target:'useCardToTarget'}, - usable:1, - filter:function(event,player){ - return event.player!=player&&event.targets.length==1; + spchijie: { + audio: 2, + trigger: { target: "useCardToTarget" }, + usable: 1, + filter: function (event, player) { + return event.player != player && event.targets.length == 1; }, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)<0; + check: function (event, player) { + return get.effect(player, event.card, event.player, player) < 0; }, - content:function(){ - 'step 0' - player.judge(function(card){ - if(get.number(card)>6) return 2; + content: function () { + "step 0"; + player.judge(function (card) { + if (get.number(card) > 6) return 2; return 0; - }).judge2=function(result){ - return result.bool?true:false; + }).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 1' - if(result.bool){ - trigger.targets.length=0; - trigger.getParent().triggeredTargets2.length=0; + "step 1"; + if (result.bool) { + trigger.targets.length = 0; + trigger.getParent().triggeredTargets2.length = 0; trigger.cancel(); } }, }, //糜夫人 - spcunsi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ + spcunsi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { return !player.isTurnedOver(); }, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; player.turnOver(); - 'step 1' - var card=get.cardPile(function(card){ - return card.name=='sha'; + "step 1"; + var card = get.cardPile(function (card) { + return card.name == "sha"; }); - if(card) target.gain(card,'gain2'); - 'step 2' - target.addSkill('spcunsi2'); - target.addMark('spcunsi2',1,false); + if (card) target.gain(card, "gain2"); + "step 2"; + target.addSkill("spcunsi2"); + target.addMark("spcunsi2", 1, false); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var card={name:'sha',isCard:true}; - if(!target.hasSkillTag('nogain')&&game.hasPlayer(function(current){ - return (get.attitude(target,current)<0&& - !current.hasShan() - &&target.canUse(card,current)&& - !current.hasSkillTag('filterDamage',null,{ - player:target, - card:card, - jiu:true, - })&& - get.effect(current,card,target)>0); - })){ + ai: { + order: 1, + result: { + target: function (player, target) { + var card = { name: "sha", isCard: true }; + if ( + !target.hasSkillTag("nogain") && + game.hasPlayer(function (current) { + return ( + get.attitude(target, current) < 0 && + !current.hasShan() && + target.canUse(card, current) && + !current.hasSkillTag("filterDamage", null, { + player: target, + card: card, + jiu: true, + }) && + get.effect(current, card, target) > 0 + ); + }) + ) { return 4; } return 0; @@ -5299,686 +6526,815 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - spcunsi2:{ - charlotte:true, - trigger:{player:'useCard1'}, - firstDo:true, - forced:true, - popup:false, - onremove:true, - filter:function(event,player){ - return event.card.name=='sha'; + spcunsi2: { + charlotte: true, + trigger: { player: "useCard1" }, + firstDo: true, + forced: true, + popup: false, + onremove: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - content:function(){ - trigger.baseDamage+=player.countMark('spcunsi2'); - player.removeSkill('spcunsi2'); + content: function () { + trigger.baseDamage += player.countMark("spcunsi2"); + player.removeSkill("spcunsi2"); }, - marktext:'嗣', - intro:{ - content:'下一张【杀】的伤害+#', + marktext: "嗣", + intro: { + content: "下一张【杀】的伤害+#", }, }, - spguixiu:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - if(typeof event.spguixiu=='boolean'&&!event.spguixiu) return false; + spguixiu: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + if (typeof event.spguixiu == "boolean" && !event.spguixiu) return false; return player.isTurnedOver(); }, - content:function(){ + content: function () { player.turnOver(); }, - group:['spguixiu_draw','spguixiu_count'], - subSkill:{ - count:{ - trigger:{player:'damageBegin2'}, - lastDo:true, - silent:true, - content:function(){ - event.spguixiu=player.isTurnedOver(); + group: ["spguixiu_draw", "spguixiu_count"], + subSkill: { + count: { + trigger: { player: "damageBegin2" }, + lastDo: true, + silent: true, + content: function () { + event.spguixiu = player.isTurnedOver(); }, }, - draw:{ - trigger:{player:'turnOverAfter'}, - forced:true, - filter:function(event,player){ + draw: { + trigger: { player: "turnOverAfter" }, + forced: true, + filter: function (event, player) { return !player.isTurnedOver(); }, - content:function(){ + content: function () { player.draw(); }, }, }, }, //那个男人的舅舅 - heji:{ - audio:2, - trigger:{global:'useCardAfter'}, - direct:true, - locked:false, - filter:function(event,player){ - if(event.targets.length!=1||event.targets[0]==player||event.targets[0].isDead()) return false; - if(event.card.name!='juedou'&&(event.card.name!='sha'||get.color(event.card)!='red')) return false; - if(_status.connectMode&&player.countCards('h')>0) return true; - return player.hasSha()||player.hasUsableCard('juedou'); + heji: { + audio: 2, + trigger: { global: "useCardAfter" }, + direct: true, + locked: false, + filter: function (event, player) { + if (event.targets.length != 1 || event.targets[0] == player || event.targets[0].isDead()) + return false; + if ( + event.card.name != "juedou" && + (event.card.name != "sha" || get.color(event.card) != "red") + ) + return false; + if (_status.connectMode && player.countCards("h") > 0) return true; + return player.hasSha() || player.hasUsableCard("juedou"); }, - content:function(){ - player.chooseToUse(function(card,player,event){ - var name=get.name(card); - if(name!='sha'&&name!='juedou') return false; - return lib.filter.cardEnabled.apply(this,arguments); - },'合击:是否对'+get.translation(trigger.targets[0])+'使用一张【杀】或【决斗】?').set('logSkill','heji').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.targets[0]).set('addCount',false); + content: function () { + player + .chooseToUse(function (card, player, event) { + var name = get.name(card); + if (name != "sha" && name != "juedou") return false; + return lib.filter.cardEnabled.apply(this, arguments); + }, "合击:是否对" + + get.translation(trigger.targets[0]) + + "使用一张【杀】或【决斗】?") + .set("logSkill", "heji") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.targets[0]) + .set("addCount", false); }, - group:'heji_gain', - subSkill:{ - gain:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.isCard&&event.getParent(2).name=='heji'; + group: "heji_gain", + subSkill: { + gain: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card.isCard && event.getParent(2).name == "heji"; }, - content:function(){ - var card=get.cardPile2(function(card){ - return get.color(card,false)=='red'; + content: function () { + var card = get.cardPile2(function (card) { + return get.color(card, false) == "red"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.name(card,player)=='sha'&&get.color(card,player)=='red') return num+0.6*(_status.event.name=='chooseToUse'&&player.hasHistory('useCard',function(evt){ - return evt.card.name=='sha'&&evt.cards.length==1; - })?1:-1); + mod: { + aiOrder: function (player, card, num) { + if (get.name(card, player) == "sha" && get.color(card, player) == "red") + return ( + num + + 0.6 * + (_status.event.name == "chooseToUse" && + player.hasHistory("useCard", function (evt) { + return evt.card.name == "sha" && evt.cards.length == 1; + }) + ? 1 + : -1) + ); }, }, }, //始计篇·智 - refubi:{ - audio:'fubi', - trigger:{ - global:'phaseBefore', - player:'enterGame', + refubi: { + audio: "fubi", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - direct:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + direct: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('refubi'),lib.filter.notMe).set('ai',function(target){ - return 1+get.attitude(_status.event.player,target); + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("refubi"), lib.filter.notMe).set("ai", function (target) { + return 1 + get.attitude(_status.event.player, target); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('refubi',target); - target.addMark('refubi',1); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("refubi", target); + target.addMark("refubi", 1); } }, - intro:{ - content:function(info,player){ - var str='已获得“辅弼”标记' - if(player.storage.refubi_effect0){ - str+=';本回合使用【杀】的次数上限+'; - str+=player.storage.refubi_effect0; + intro: { + content: function (info, player) { + var str = "已获得“辅弼”标记"; + if (player.storage.refubi_effect0) { + str += ";本回合使用【杀】的次数上限+"; + str += player.storage.refubi_effect0; } - if(player.storage.refubi_effect1){ - str+=';本回合的手牌上限+'; - str+=(player.storage.refubi_effect1*3); + if (player.storage.refubi_effect1) { + str += ";本回合的手牌上限+"; + str += player.storage.refubi_effect1 * 3; } return str; }, }, - marktext:'弼', - group:'refubi_buff', - subSkill:{ - buff:{ - trigger:{global:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&event.player.hasMark('refubi'); + marktext: "弼", + group: "refubi_buff", + subSkill: { + buff: { + trigger: { global: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return event.player != player && event.player.hasMark("refubi"); }, - content:function(){ - 'step 0' - var str=get.translation(trigger.player); - player.chooseControl('cancel2').set('choiceList',[ - '令'+str+'本回合使用【杀】的次数上限+1', - '令'+str+'本回合的手牌上限+3', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().player; - if(get.attitude(player,target)<=0) return 'cancel2'; - if(!target.hasJudge('lebu')&&target.countCards('h',function(card){ - return get.name(card,target)=='sha'&&target.hasValueTarget(card); - })>target.getCardUsable('sha')) return 0; - return 1; - }); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.player; - player.logSkill('refubi',target); - var str='refubi_effect'+result.index; + content: function () { + "step 0"; + var str = get.translation(trigger.player); + player + .chooseControl("cancel2") + .set("choiceList", [ + "令" + str + "本回合使用【杀】的次数上限+1", + "令" + str + "本回合的手牌上限+3", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player; + if (get.attitude(player, target) <= 0) return "cancel2"; + if ( + !target.hasJudge("lebu") && + target.countCards("h", function (card) { + return ( + get.name(card, target) == "sha" && target.hasValueTarget(card) + ); + }) > target.getCardUsable("sha") + ) + return 0; + return 1; + }); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.player; + player.logSkill("refubi", target); + var str = "refubi_effect" + result.index; target.addTempSkill(str); - target.addMark(str,1,false); - game.log(target,[ - '本回合使用【杀】的次数上限+1', - '本回合的手牌上限+3', - ][result.index]); + target.addMark(str, 1, false); + game.log( + target, + ["本回合使用【杀】的次数上限+1", "本回合的手牌上限+3"][result.index] + ); } }, }, - effect0:{ - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('refubi_effect0'); + effect0: { + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("refubi_effect0"); }, }, }, - effect1:{ - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+3*player.countMark('refubi_effect1'); + effect1: { + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + 3 * player.countMark("refubi_effect1"); }, }, }, }, }, - rezuici:{ - audio:'zuici', - enable:'chooseToUse', - filter:function(event,player){ - if(event.type=='phase'||event.type=='dying'&&player==event.dying) return (player.isDamaged()&&player.countCards('e')>0); + rezuici: { + audio: "zuici", + enable: "chooseToUse", + filter: function (event, player) { + if (event.type == "phase" || (event.type == "dying" && player == event.dying)) + return player.isDamaged() && player.countCards("e") > 0; return false; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('###罪辞###选择废除一个有牌的装备栏,然后回复2点体力,并可移动“辅弼”标记。'); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "###罪辞###选择废除一个有牌的装备栏,然后回复2点体力,并可移动“辅弼”标记。" + ); }, - chooseControl:function(event,player){ - var list=[]; - for(var i=1;i<6;i++){ - if(player.getEquips(i).length>0) list.push('equip'+i); + chooseControl: function (event, player) { + var list = []; + for (var i = 1; i < 6; i++) { + if (player.getEquips(i).length > 0) list.push("equip" + i); } - list.push('cancel2'); + list.push("cancel2"); return list; }, - check:function(event,player){ - if(player.hp>1&&player.getDamagedHp()<2) return 'cancel2'; - var cards=player.getCards('e').sort(function(a,b){ - return get.value(a)-get.value(b); + check: function (event, player) { + if (player.hp > 1 && player.getDamagedHp() < 2) return "cancel2"; + var cards = player.getCards("e").sort(function (a, b) { + return get.value(a) - get.value(b); }); - var sub=get.subtype(cards[0],false); - if(player.hp<1) return sub; - var val=get.value(cards[0]); - if(val<0) return sub; - return val<4?sub:'cancel2'; + var sub = get.subtype(cards[0], false); + if (player.hp < 1) return sub; + var val = get.value(cards[0]); + if (val < 0) return sub; + return val < 4 ? sub : "cancel2"; }, - backup:function(result){ - var next=get.copy(lib.skill.rezuicix); - next.position=result.control; + backup: function (result) { + var next = get.copy(lib.skill.rezuicix); + next.position = result.control; return next; }, }, - ai:{ - order:2.7, - result:{ - player:1, + ai: { + order: 2.7, + result: { + player: 1, }, - save:true, - skillTagFilter:function(player,tag,arg){ - return player==arg; + save: true, + skillTagFilter: function (player, tag, arg) { + return player == arg; }, }, }, - rezuicix:{ - audio:'zuici', - content:function(){ - 'step 0' + rezuicix: { + audio: "zuici", + content: function () { + "step 0"; player.disableEquip(lib.skill.rezuici_backup.position); player.recover(2); - 'step 1' - var b1=false,b2=false; - for(var i of game.players){ - if(i.hasMark('refubi')) b1=true; - else if(i!=player) b2=true; - if(b1&&b2) break; + "step 1"; + var b1 = false, + b2 = false; + for (var i of game.players) { + if (i.hasMark("refubi")) b1 = true; + else if (i != player) b2 = true; + if (b1 && b2) break; } - if(b1&&b2){ - player.chooseTarget('是否转移“辅弼”标记?',function(card,player,target){ - return target!=player&&!target.hasMark('refubi'); - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - return Math.min(att,att-_status.event.preatt); - }).set('preatt',get.attitude(player,game.findPlayer(function(current){ - return current.hasMark('refubi'); - }))); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'group'); - game.countPlayer(function(current){ - var num=current.countMark('refubi'); - if(num) current.removeMark('refubi',1,false); + if (b1 && b2) { + player + .chooseTarget("是否转移“辅弼”标记?", function (card, player, target) { + return target != player && !target.hasMark("refubi"); + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + return Math.min(att, att - _status.event.preatt); + }) + .set( + "preatt", + get.attitude( + player, + game.findPlayer(function (current) { + return current.hasMark("refubi"); + }) + ) + ); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "group"); + game.countPlayer(function (current) { + var num = current.countMark("refubi"); + if (num) current.removeMark("refubi", 1, false); }); - target.addMark('refubi',1); + target.addMark("refubi", 1); } }, - ai:{ - result:{ - player:1, + ai: { + result: { + player: 1, }, }, }, - reshengxi:{ - audio:'shengxi', - audioname:['feiyi'], - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - preHidden:true, - filter:function(event,player){ - return !player.getHistory('sourceDamage').length; + reshengxi: { + audio: "shengxi", + audioname: ["feiyi"], + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + preHidden: true, + filter: function (event, player) { + return !player.getHistory("sourceDamage").length; }, - content:function(){ + content: function () { player.draw(2); }, }, - fyjianyu:{ - initSkill:function(skill){ - if(!lib.skill[skill]){ - lib.skill[skill]={ - marktext:'喻', - intro:{ - markcount:()=>1, - content:'指定另一名有“喻”的角色为目标时,其摸一张牌', + fyjianyu: { + initSkill: function (skill) { + if (!lib.skill[skill]) { + lib.skill[skill] = { + marktext: "喻", + intro: { + markcount: () => 1, + content: "指定另一名有“喻”的角色为目标时,其摸一张牌", }, }; - lib.translate[skill]='谏喻'; - lib.translate[skill+'_bg']='喻'; + lib.translate[skill] = "谏喻"; + lib.translate[skill + "_bg"] = "喻"; } }, - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return game.countPlayer(function(current){ - return !current.hasMark('fyjianyu_'+player.playerid); - })>1; + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + game.countPlayer(function (current) { + return !current.hasMark("fyjianyu_" + player.playerid); + }) > 1 + ); }, - round:1, - filterTarget:function(card,player,target){ - return !target.hasMark('fyjianyu_'+player.playerid); + round: 1, + filterTarget: function (card, player, target) { + return !target.hasMark("fyjianyu_" + player.playerid); }, - selectTarget:2, - content:function(){ - var skill='fyjianyu_'+player.playerid; - game.broadcastAll(lib.skill.fyjianyu.initSkill,skill); - player.addTempSkill('fyjianyu_draw',{player:'phaseBegin'}); - target.addMark(skill,1); + selectTarget: 2, + content: function () { + var skill = "fyjianyu_" + player.playerid; + game.broadcastAll(lib.skill.fyjianyu.initSkill, skill); + player.addTempSkill("fyjianyu_draw", { player: "phaseBegin" }); + target.addMark(skill, 1); }, - ai:{ - order:0.1, - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return target==player?1:0; - if(get.attitude(player,target)<0) return -1.6*(1+(target.countCards('h',function(card){ - return target.hasValueTarget(card)&&get.effect(player,card,target,target)>0; - }))*Math.sqrt(target.countCards('h'))); - return 0.3*(1+(target.countCards('h',function(card){ - return target.hasValueTarget(card)&&get.effect(player,card,target,target)>0; - }))*Math.sqrt(target.countCards('h'))); + ai: { + order: 0.1, + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return target == player ? 1 : 0; + if (get.attitude(player, target) < 0) + return ( + -1.6 * + (1 + + target.countCards("h", function (card) { + return ( + target.hasValueTarget(card) && + get.effect(player, card, target, target) > 0 + ); + }) * + Math.sqrt(target.countCards("h"))) + ); + return ( + 0.3 * + (1 + + target.countCards("h", function (card) { + return ( + target.hasValueTarget(card) && + get.effect(player, card, target, target) > 0 + ); + }) * + Math.sqrt(target.countCards("h"))) + ); }, }, }, - subSkill:{ - draw:{ - charlotte:true, - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - return event.player!=event.target&&event.player.hasMark('fyjianyu_'+player.playerid)&&event.target.hasMark('fyjianyu_'+player.playerid)&&event.target.isIn(); + subSkill: { + draw: { + charlotte: true, + trigger: { global: "useCardToPlayer" }, + filter: function (event, player) { + return ( + event.player != event.target && + event.player.hasMark("fyjianyu_" + player.playerid) && + event.target.hasMark("fyjianyu_" + player.playerid) && + event.target.isIn() + ); }, - forced:true, - logTarget:'target', - content:function(){ + forced: true, + logTarget: "target", + content: function () { trigger.target.draw(); }, - onremove:function(player){ - game.countPlayer(function(current){ - var num=current.countMark('fyjianyu_'+player.playerid); - if(num) current.removeMark('fyjianyu_'+player.playerid); + onremove: function (player) { + game.countPlayer(function (current) { + var num = current.countMark("fyjianyu_" + player.playerid); + if (num) current.removeMark("fyjianyu_" + player.playerid); }); }, }, }, }, - spwanwei:{ - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - if(player.hasSkill('spwanwei2')||player.hp<1) return false; - if(event.type=='dying') return event.dying!=player; - if(event.type!='phase') return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged(); + spwanwei: { + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + if (player.hasSkill("spwanwei2") || player.hp < 1) return false; + if (event.type == "dying") return event.dying != player; + if (event.type != "phase") return false; + return game.hasPlayer(function (current) { + return current != player && current.isDamaged(); }); }, - filterTarget:function(card,player,target){ - if(_status.event.type=='dying') return target==_status.event.dying; - return player!=target&&target.isDamaged(); + filterTarget: function (card, player, target) { + if (_status.event.type == "dying") return target == _status.event.dying; + return player != target && target.isDamaged(); }, - selectTarget:function(){ - if(_status.event.type=='dying') return -1; + selectTarget: function () { + if (_status.event.type == "dying") return -1; return 1; }, - content:function(){ - player.addTempSkill('spwanwei2','roundStart'); - var num=player.hp; - target.recover(Math.max(num+1,1-target.hp)); + content: function () { + player.addTempSkill("spwanwei2", "roundStart"); + var num = player.hp; + target.recover(Math.max(num + 1, 1 - target.hp)); player.loseHp(num); }, - ai:{ - save:true, - skillTagFilter:function(player,tag,target){ - return player!=target; + ai: { + save: true, + skillTagFilter: function (player, tag, target) { + return player != target; }, - expose:0.5, - order:6, - result:{ - target:function(player,target){ - if(_status.event.type!='dying') return 0; - if(get.attitude(player,target)<4) return 0; - if(player.countCards('he')<2&&target!=get.zhu(player)) return 0; + expose: 0.5, + order: 6, + result: { + target: function (player, target) { + if (_status.event.type != "dying") return 0; + if (get.attitude(player, target) < 4) return 0; + if (player.countCards("he") < 2 && target != get.zhu(player)) return 0; return 1; }, }, }, }, - spwanwei2:{}, - spyuejian:{ - mod:{ - maxHandcardBase:function(player){ + spwanwei2: {}, + spyuejian: { + mod: { + maxHandcardBase: function (player) { return player.maxHp; }, }, - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - return event.type=='dying'&&player==event.dying&&player.countCards('he')>1; + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + return event.type == "dying" && player == event.dying && player.countCards("he") > 1; }, - selectCard:2, - filterCard:true, - position:'he', - check:function(card){ - return 1/Math.max(0.1,get.value(card)); + selectCard: 2, + filterCard: true, + position: "he", + check: function (card) { + return 1 / Math.max(0.1, get.value(card)); }, - content:function(){ + content: function () { player.recover(); }, - ai:{ - save:true, - skillTagFilter:function(player,tag,target){ - return player==target; + ai: { + save: true, + skillTagFilter: function (player, tag, target) { + return player == target; }, - order:1.4, - result:{ - player:1, + order: 1.4, + result: { + player: 1, }, }, }, - spwuku:{ - audio:2, - trigger:{global:'useCard'}, - forced:true, - 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('spwuku')<(gz?2:3); + spwuku: { + audio: 2, + trigger: { global: "useCard" }, + forced: true, + 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("spwuku") < (gz ? 2 : 3); }, - content:function(){ - player.addMark('spwuku',1); + content: function () { + player.addMark("spwuku", 1); }, - marktext:'库', - intro:{ - content:'mark', + marktext: "库", + intro: { + content: "mark", }, - ai:{ - combo:'spsanchen', - threaten:3.6, + ai: { + combo: "spsanchen", + threaten: 3.6, }, }, - spsanchen:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.countMark('spwuku')>2; + spsanchen: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.countMark("spwuku") > 2; }, - content:function(){ - player.awakenSkill('spsanchen'); + content: function () { + player.awakenSkill("spsanchen"); player.gainMaxHp(); player.recover(); - player.addSkills('spmiewu'); + player.addSkills("spmiewu"); }, - ai:{ - combo:'wuku', + ai: { + combo: "wuku", }, - derivation:'spmiewu', + derivation: "spmiewu", }, - spmiewu:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - if(!player.countMark('spwuku')||!player.countCards('hse')||player.hasSkill('spmiewu2')) return false; - for(var i of lib.inpile){ - var type=get.type2(i); - if((type=='basic'||type=='trick')&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; + spmiewu: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filter: function (event, player) { + if ( + !player.countMark("spwuku") || + !player.countCards("hse") || + player.hasSkill("spmiewu2") + ) + return false; + for (var i of lib.inpile) { + var type = get.type2(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i=0;i0&&player.countCards('she')>0&&!player.hasSkill('spmiewu2'); - }, - ai:{ - combo:'spwuku', - fireAttack:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - if(!player.countMark('spwuku')||!player.countCards('hse')||player.hasSkill('spmiewu2')) return false; + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + }, + hiddenCard: function (player, name) { + if (!lib.inpile.includes(name)) return false; + var type = get.type2(name); + return ( + (type == "basic" || type == "trick") && + player.countMark("spwuku") > 0 && + player.countCards("she") > 0 && + !player.hasSkill("spmiewu2") + ); + }, + ai: { + combo: "spwuku", + fireAttack: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + if ( + !player.countMark("spwuku") || + !player.countCards("hse") || + player.hasSkill("spmiewu2") + ) + return false; + }, + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, }, - spmiewu2:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return event.skill=='spmiewu_backup'; + spmiewu2: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return event.skill == "spmiewu_backup"; }, - content:function(){ + content: function () { player.draw(); }, }, - spmiewu_backup:{audio:'spmiewu'}, - qinzheng:{ - audio:2, - trigger:{player:['useCard','respond']}, - forced:true, - filter:function(event,player){ - var num=player.getAllHistory('useCard').length+player.getAllHistory('respond').length; - return num%3==0||num%5==0||num%8==0; + spmiewu_backup: { audio: "spmiewu" }, + qinzheng: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter: function (event, player) { + var num = player.getAllHistory("useCard").length + player.getAllHistory("respond").length; + return num % 3 == 0 || num % 5 == 0 || num % 8 == 0; }, - content:function(){ - var num=player.getAllHistory('useCard').length+player.getAllHistory('respond').length; - var cards=[]; - if(num%3==0){ - var card=get.cardPile2(function(card){ - return card.name=='sha'||card.name=='shan'; + content: function () { + var num = player.getAllHistory("useCard").length + player.getAllHistory("respond").length; + var cards = []; + if (num % 3 == 0) { + var card = get.cardPile2(function (card) { + return card.name == "sha" || card.name == "shan"; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(num%5==0){ - var card=get.cardPile2(function(card){ - return ['tao','jiu','zong','xionghuangjiu'].includes(card.name); + if (num % 5 == 0) { + var card = get.cardPile2(function (card) { + return ["tao", "jiu", "zong", "xionghuangjiu"].includes(card.name); }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(num%8==0){ - var card=get.cardPile2(function(card){ - return ['juedou','wuzhong','zengbin','sadouchengbing','dongzhuxianji','tongzhougongji'].includes(card.name); + if (num % 8 == 0) { + var card = get.cardPile2(function (card) { + return [ + "juedou", + "wuzhong", + "zengbin", + "sadouchengbing", + "dongzhuxianji", + "tongzhougongji", + ].includes(card.name); }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, - group:'qinzheng_count', - intro:{ - content:function(num){ - var str='
            • 总次数:'; - str+=num; - str+='
            • 杀/闪:'; - str+=num%3; - str+='/3
            • 桃/酒:'; - str+=num%5; - str+='/5
            • 决斗/无中生有:'; - str+=num%8; - str+='/8'; + group: "qinzheng_count", + intro: { + content: function (num) { + var str = "
            • 总次数:"; + str += num; + str += "
            • 杀/闪:"; + str += num % 3; + str += "/3
            • 桃/酒:"; + str += num % 5; + str += "/5
            • 决斗/无中生有:"; + str += num % 8; + str += "/8"; return str; }, }, }, - qinzheng_count:{ - trigger:{player:['useCard1','respond']}, - silent:true, - firstDo:true, - noHidden:true, - content:function(){ - player.storage.qinzheng=player.getAllHistory('useCard').length+player.getAllHistory('respond').length; - player.markSkill('qinzheng'); + qinzheng_count: { + trigger: { player: ["useCard1", "respond"] }, + silent: true, + firstDo: true, + noHidden: true, + content: function () { + player.storage.qinzheng = + player.getAllHistory("useCard").length + player.getAllHistory("respond").length; + player.markSkill("qinzheng"); }, }, - spqiai:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',function(card){ - return get.type(card)!='basic'; - })>0; + spqiai: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he", function (card) { + return get.type(card) != "basic"; + }) > 0 + ); }, - filterCard:function(card){ - return get.type(card)!='basic'; + filterCard: function (card) { + return get.type(card) != "basic"; }, - position:'he', - filterTarget:lib.filter.notMe, - delay:false, - discard:false, - lose:false, - check:function(card){ - var player=_status.event.player; - if(get.position(card)=='e'&&card.name=='jinhe') return 10; - if(player.isHealthy()) return 7-get.value(card); - return 9-get.value(card); + position: "he", + filterTarget: lib.filter.notMe, + delay: false, + discard: false, + lose: false, + check: function (card) { + var player = _status.event.player; + if (get.position(card) == "e" && card.name == "jinhe") return 10; + if (player.isHealthy()) return 7 - get.value(card); + return 9 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target,true); - 'step 1' - if(!target.isIn()){ + content: function () { + "step 0"; + player.give(cards, target, true); + "step 1"; + if (!target.isIn()) { event.finish(); return; } - if(player.isHealthy()) event._result={index:1}; - else{ - var str=get.translation(player); - target.chooseControl().set('choiceList',[ - '令'+str+'回复1点体力', - '令'+str+'摸两张牌', - ]); + if (player.isHealthy()) event._result = { index: 1 }; + else { + var str = get.translation(player); + target + .chooseControl() + .set("choiceList", ["令" + str + "回复1点体力", "令" + str + "摸两张牌"]); } - 'step 2' - if(result.index==0) player.recover(); + "step 2"; + if (result.index == 0) player.recover(); else player.draw(2); }, - ai:{ - order:8, - result:{ - player:1, - target:function(player,target){ - if(ui.selected.cards.length){ - var card=ui.selected.cards[0]; - var val=get.value(card,target); - if(val<0) return -1; - if(target.hasSkillTag('nogain')) return 0; - var useval=target.getUseValue(card); - if(val<1||useval<=0) return 0.1; + ai: { + order: 8, + result: { + player: 1, + target: function (player, target) { + if (ui.selected.cards.length) { + var card = ui.selected.cards[0]; + var val = get.value(card, target); + if (val < 0) return -1; + if (target.hasSkillTag("nogain")) return 0; + var useval = target.getUseValue(card); + if (val < 1 || useval <= 0) return 0.1; return Math.sqrt(useval); } return 0; @@ -5986,515 +7342,613 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - spshanxi:{ - audio:2, - init:function(player){ - game.addGlobalSkill('spshanxi_bj'); + spshanxi: { + audio: 2, + init: function (player) { + game.addGlobalSkill("spshanxi_bj"); }, - onremove:function(player){ - if(!game.hasPlayer(current=>current.hasSkill('spshanxi'),true)) game.removeGlobalSkill('spshanxi_bj'); + onremove: function (player) { + if (!game.hasPlayer((current) => current.hasSkill("spshanxi"), true)) + game.removeGlobalSkill("spshanxi_bj"); }, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&!current.hasMark('spshanxi'); + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && !current.hasMark("spshanxi"); }); }, - content:function(){ - 'step 0' - var eff=0; - var target=game.findPlayer(function(current){ - return current!=player&¤t.hasMark('spshanxi'); + content: function () { + "step 0"; + var eff = 0; + var target = game.findPlayer(function (current) { + return current != player && current.hasMark("spshanxi"); }); - if(target) eff=(-get.attitude(player,target)/Math.sqrt(Math.max(1,target.hp))); - player.chooseTarget(get.prompt('spshanxi'),'令一名其他角色获得“檄”',function(card,player,target){ - return target!=player&&!target.hasMark('spshanxi'); - }).set('ai',function(target){ - return (-get.attitude(_status.event.player,target)/Math.sqrt(Math.max(1,target.hp)))-_status.event.eff; - }).set('eff',eff); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('spshanxi',target); - game.countPlayer(function(current){ - if(current==target) current.addMark('spshanxi',1); - else{ - var num=current.countMark('spshanxi'); - if(num>0) current.removeMark('spshanxi',num); + if (target) eff = -get.attitude(player, target) / Math.sqrt(Math.max(1, target.hp)); + player + .chooseTarget( + get.prompt("spshanxi"), + "令一名其他角色获得“檄”", + function (card, player, target) { + return target != player && !target.hasMark("spshanxi"); + } + ) + .set("ai", function (target) { + return ( + -get.attitude(_status.event.player, target) / + Math.sqrt(Math.max(1, target.hp)) - + _status.event.eff + ); + }) + .set("eff", eff); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("spshanxi", target); + game.countPlayer(function (current) { + if (current == target) current.addMark("spshanxi", 1); + else { + var num = current.countMark("spshanxi"); + if (num > 0) current.removeMark("spshanxi", num); } }); } }, - marktext:'檄', - intro:{ - name2:'檄', - content:'已被设下索命檄文', + marktext: "檄", + intro: { + name2: "檄", + content: "已被设下索命檄文", }, - group:'spshanxi_suoming', - ai:{threaten:3.3}, + group: "spshanxi_suoming", + ai: { threaten: 3.3 }, }, - spshanxi_suoming:{ - audio:'spshanxi', - trigger:{global:'recoverAfter'}, - forced:true, - filter:function(event,player){ - return event.player.hasMark('spshanxi')&&event.player.hp>0; + spshanxi_suoming: { + audio: "spshanxi", + trigger: { global: "recoverAfter" }, + forced: true, + filter: function (event, player) { + return event.player.hasMark("spshanxi") && event.player.hp > 0; }, - logTarget:'player', - content:function(){ - 'step 0' - if(trigger.player.countCards('he')<2) event._result={bool:false}; - else trigger.player.chooseCard('he',2,'交给'+get.translation(player)+'两张牌,或失去1点体力').set('ai',function(card){ - return 9-get.value(card); - }); - 'step 1' - if(!result.bool) trigger.player.loseHp(); - else trigger.player.give(result.cards,player); + logTarget: "player", + content: function () { + "step 0"; + if (trigger.player.countCards("he") < 2) event._result = { bool: false }; + else + trigger.player + .chooseCard("he", 2, "交给" + get.translation(player) + "两张牌,或失去1点体力") + .set("ai", function (card) { + return 9 - get.value(card); + }); + "step 1"; + if (!result.bool) trigger.player.loseHp(); + else trigger.player.give(result.cards, player); }, }, - spshanxi_bj:{ - trigger:{player:'dieAfter'}, - filter:function(event,player){ - for(let i of game.players){ - if(i.hasSkill('spshanxi_suoming')) return false; + spshanxi_bj: { + trigger: { player: "dieAfter" }, + filter: function (event, player) { + for (let i of game.players) { + if (i.hasSkill("spshanxi_suoming")) return false; } return true; }, - silent:true, - forceDie:true, - charlotte:true, - content:function(){ - game.removeGlobalSkill('spshanxi_bj'); + silent: true, + forceDie: true, + charlotte: true, + content: function () { + game.removeGlobalSkill("spshanxi_bj"); }, - ai:{ - effect:{ - target:function(card,player,target){ - let suoming=game.findPlayer(current=>current.hasSkill('spshanxi_suoming')); - if(suoming&&_status.event&&target===_status.event.dying&&target.hasMark('spshanxi')){ - if(target.countCards('he')<2) return 'zerotarget'; - return [1,get.attitude(target,suoming)>0?0:-1.2]; + ai: { + effect: { + target: function (card, player, target) { + let suoming = game.findPlayer((current) => current.hasSkill("spshanxi_suoming")); + if ( + suoming && + _status.event && + target === _status.event.dying && + target.hasMark("spshanxi") + ) { + if (target.countCards("he") < 2) return "zerotarget"; + return [1, get.attitude(target, suoming) > 0 ? 0 : -1.2]; } - } - } - } + }, + }, + }, }, - shameng:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var hs=player.getCards('h'); - if(hs.length<2) return false; - var red=0,black=0; - for(var i of hs){ - if(get.color(i,player)=='red') red++; + shameng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var hs = player.getCards("h"); + if (hs.length < 2) return false; + var red = 0, + black = 0; + for (var i of hs) { + if (get.color(i, player) == "red") red++; else black++; - if(red>1||black>1) return true; + if (red > 1 || black > 1) return true; } return false; }, - complexCard:true, - selectCard:2, - filterCard:function(card,player){ - if(ui.selected.cards.length) return get.color(card,player)==get.color(ui.selected.cards[0],player); - var color=get.color(card,player); - return player.countCards('h',function(cardx){ - return cardx!=card&&color==get.color(cardx,player); - })>0; + complexCard: true, + selectCard: 2, + filterCard: function (card, player) { + if (ui.selected.cards.length) + return get.color(card, player) == get.color(ui.selected.cards[0], player); + var color = get.color(card, player); + return ( + player.countCards("h", function (cardx) { + return cardx != card && color == get.color(cardx, player); + }) > 0 + ); }, - filterTarget:lib.filter.notMe, - check:function(card){return 7-get.value(card)}, - position:'h', - content:function(){ + filterTarget: lib.filter.notMe, + check: function (card) { + return 7 - get.value(card); + }, + position: "h", + content: function () { target.draw(2); player.draw(3); }, - ai:{ - order:6, - result:{target:2}, + ai: { + order: 6, + result: { target: 2 }, }, }, - fubi:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + fubi: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - direct:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + direct: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('fubi'),lib.filter.notMe).set('ai',function(target){ - return get.attitude(_status.event.player,target); + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("fubi"), lib.filter.notMe).set("ai", function (target) { + return get.attitude(_status.event.player, target); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('fubi',target); - target.addSkill('fubi2'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("fubi", target); + target.addSkill("fubi2"); target.storage.fubi2.push(player); } }, }, - fubi2:{ - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + fubi2: { + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - mod:{ - maxHandcard:function(player,num){ - var list=player.getStorage('fubi2'); - for(var i of list){ - if(i.isIn()) num+=3; + mod: { + maxHandcard: function (player, num) { + var list = player.getStorage("fubi2"); + for (var i of list) { + if (i.isIn()) num += 3; } return num; }, }, - mark:true, - intro:{content:'若$存活,则手牌上限+3'}, + mark: true, + intro: { content: "若$存活,则手牌上限+3" }, }, - zuici:{ - trigger:{player:'dying'}, - direct:true, - filter:function(event,player){ - return player.countCards('e')>0; + zuici: { + trigger: { player: "dying" }, + direct: true, + filter: function (event, player) { + return player.countCards("e") > 0; }, - content:function(){ - 'step 0' - var list=[]; - var cards=player.getCards('e'); - for(var i of cards) list.push(get.subtype(i)); - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt2('zuici')); - 'step 1' - if(result.control!='cancel2'){ + content: function () { + "step 0"; + var list = []; + var cards = player.getCards("e"); + for (var i of cards) list.push(get.subtype(i)); + list.push("cancel2"); + player.chooseControl(list).set("prompt", get.prompt2("zuici")); + "step 1"; + if (result.control != "cancel2") { player.disableEquip(result.control); - } - else event.finish(); - 'step 2' - if(player.hp<1) player.recover(1-player.hp); + } else event.finish(); + "step 2"; + if (player.hp < 1) player.recover(1 - player.hp); }, }, - jianzhan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.jianzhan.filterTarget(null,player,current); + jianzhan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return lib.skill.jianzhan.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(ui.selected.targets.length){ - var targetx=ui.selected.targets[0]; - return targetx!=target&&targetx.countCards('h')>target.countCards('h')&&targetx.inRange(target); + filterTarget: function (card, player, target) { + if (target == player) return false; + if (ui.selected.targets.length) { + var targetx = ui.selected.targets[0]; + return ( + targetx != target && + targetx.countCards("h") > target.countCards("h") && + targetx.inRange(target) + ); } - var num=target.countCards('h'); - return game.hasPlayer(function(current){ - return current!=target&¤t!=player&¤t.countCards('h')0) return 0; - if(eff<0||get.attitude(evt.targets[0],evt.player)>1) return 1; - return 0; - }); - 'step 1' - if(result.index==0) targets[0].useCard({name:'sha',isCard:true},targets[1],false); + selectTarget: 2, + complexTarget: true, + targetprompt: ["出杀", "被出杀"], + multitarget: true, + content: function () { + "step 0"; + if (!targets[0].canUse("sha", targets[1])) event._result = { index: 1 }; + else + targets[0] + .chooseControl() + .set("choiceList", [ + "视为对" + get.translation(targets[1]) + "使用一张【杀】", + "令" + get.translation(player) + "摸一张牌", + ]) + .set("ai", function () { + var evt = _status.event.getParent(); + var eff = get.effect( + evt.targets[1], + { name: "sha", isCard: true }, + evt.targets[0], + evt.targets[0] + ); + if (eff > 0) return 0; + if (eff < 0 || get.attitude(evt.targets[0], evt.player) > 1) return 1; + return 0; + }); + "step 1"; + if (result.index == 0) + targets[0].useCard({ name: "sha", isCard: true }, targets[1], false); else player.draw(); }, - ai:{ - result:{ - target:function(player,target){ - if(ui.selected.targets.length){ - var from=ui.selected.targets[0]; - return get.effect(target,{name:'sha'},from,target); + ai: { + result: { + target: function (player, target) { + if (ui.selected.targets.length) { + var from = ui.selected.targets[0]; + return get.effect(target, { name: "sha" }, from, target); } - var effs=[0,0]; - game.countPlayer(function(current){ - if(current!=target&&target.canUse('sha',current)){ - var eff=get.effect(current,{name:'sha'},target,target); - if(eff>effs[0]) effs[0]=eff; - if(eff effs[0]) effs[0] = eff; + if (eff < effs[1]) effs[1] = eff; } }); - return effs[get.attitude(player,target)>0?0:1]; - } + return effs[get.attitude(player, target) > 0 ? 0 : 1]; + }, }, - order:8.5, - expose:0.2 + order: 8.5, + expose: 0.2, }, }, - duoji:{ - audio:2, - enable:'phaseUse', - limited:true, - filter:function(event,player){ - return player.countCards('h')>1&&game.hasPlayer(function(current){ - return current!=player&¤t.countGainableCards(player,'e')>0; - }); + duoji: { + audio: 2, + enable: "phaseUse", + limited: true, + filter: function (event, player) { + return ( + player.countCards("h") > 1 && + game.hasPlayer(function (current) { + return current != player && current.countGainableCards(player, "e") > 0; + }) + ); }, - filterCard:true, - selectCard:2, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'e')>0; + filterCard: true, + selectCard: 2, + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "e") > 0; }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - position:'h', - skillAnimation:true, - animationColor:'metal', - content:function(){ - player.awakenSkill('duoji'); - var cards=target.getGainableCards(player,'e'); - player.gain(cards,target,'give','bySelf'); + position: "h", + skillAnimation: true, + animationColor: "metal", + content: function () { + player.awakenSkill("duoji"); + var cards = target.getGainableCards(player, "e"); + player.gain(cards, target, "give", "bySelf"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var num=0,es=target.getCards('e'),val=0; - for(var i of es){ - num+=get.value(i,target); + ai: { + order: 1, + result: { + target: function (player, target) { + var num = 0, + es = target.getCards("e"), + val = 0; + for (var i of es) { + num += get.value(i, target); } - for(var i of ui.selected.cards){ - val+=get.value(i,player); + for (var i of ui.selected.cards) { + val += get.value(i, player); } - if(Math.abs(num)>val) return -num; + if (Math.abs(num) > val) return -num; return 0; }, }, }, }, }, - characterIntro:{ - yuanhuan:'袁涣,字曜卿,陈郡扶乐(今河南省周口市太康县)人。东汉末年官员,出身陈郡袁氏,为东汉司徒袁滂之子。袁涣早年曾任郡功曹,后被公府征辟,相继被举为高第、秀才。汉末战乱时,袁涣流寓江淮一带,初为袁术所用,后投吕布。建安三年(198年),曹操率兵剿灭了吕布,袁涣又转投曹操,拜沛南部都尉,后又任谏议大夫、郎中令等职,在任上尽心尽责,以敢谏直言称名。袁涣恕思而后行,外表温柔而内心能断,处危难则勇气极大。汉末三国时期,唯有程昱、曹仁、袁涣三人被评价为勇冠贲育。', - qiaogong:'桥公,亦作“乔公”,名字不详,是中国汉末三国时期的长者,江东二乔的父亲,三国时期庐江郡皖县(今安徽潜山)人,中国长篇古典名著《三国演义》中称之为“乔国老”。', - liuzhang:'刘璋(生卒年不详),字季玉,江夏竟陵(今湖北省天门市)人。东汉末年宗室、军阀,益州牧刘焉幼子,在父亲刘焉死后继任益州牧。刘璋为人懦弱多疑。汉中张鲁骄纵,不听刘璋号令,于是刘璋杀张鲁母弟,双方成为仇敌,刘璋派庞羲攻击张鲁,战败。后益州内乱,平定后,又有曹操将前来袭击的消息。在内外交逼之下,刘璋听信手下张松、法正之言,迎接刘备入益州,想借刘备之力,抵抗曹操。不料此举乃引狼入室,刘备反手攻击刘璋,又有法正为内应,进至成都。成都吏民都想抵抗刘备,但刘璋为百姓计而开城出降,群下莫不流涕。刘备占据成都后,刘璋以振威将军的身份被迁往荆州居住,关羽失荆州后,刘璋归属东吴,被孙权任命为益州牧,不久后去世,卒年不详。', - zhangzhongjing:'张仲景(约公元150~154年—约公元215~219年),名机,字仲景,南阳涅阳县(今河南省邓州市穰东镇张寨村)人。东汉末年著名医学家,被后人尊称为“医圣”。张仲景广泛收集医方,写出了传世巨著《伤寒杂病论》。它确立的“辨证论治”原则,是中医临床的基本原则,是中医的灵魂所在。在方剂学方面,《伤寒杂病论》也做出了巨大贡献,创造了很多剂型,记载了大量有效的方剂。其所确立的六经辨证的治疗原则,受到历代医学家的推崇。这是中国第一部从理论到实践、确立辨证论治法则的医学专著,是中国医学史上影响最大的著作之一,是后学者研习中医必备的经典著作,广泛受到医学生和临床大夫的重视。', - xiangchong:'向宠(?~240年),左将军向朗之侄,蜀汉重要将领。具有谦和公允的性格品行,对军事通晓畅达,被汉昭烈帝刘备称赞。刘备时,历任牙门将(类似于主将帐下的偏将),诸葛亮北伐时,以向宠为中领军,封都亭侯。诸葛亮北行汉中前,特意在《出师表》中向刘禅推荐向宠。延熙三年(公元240年),南征汉嘉(今四川省雅安市)蛮夷时,遇害,尸体被其部下夺回,送回成都安葬。', - caizhenji:'蔡贞姬,生卒年不详,汉末大儒蔡邕之女。其父蔡邕精于天文数理,妙解音律,是曹操的挚友和老师。生在书香门第的家庭的蔡贞姬,自小耳濡目染,精通书法与音律。后来,其父为避宦竖迫害,便随父亲来泰山依付羊衜一族,在羊衜的元配孔氏死后,便在父亲的做主下与之成亲。夫妻二人婚后生有两子一女:羊承、羊徽瑜、羊祜。在与羊衜成亲之前,羊衜和孔氏生有一子羊发。后来羊发、羊承同时生病,蔡贞姬知道不能两全,就专心照顾羊发,最后羊发痊愈,羊承病死。', - zhouchu:'周处(236—297年),字子隐,吴郡阳羡(今江苏宜兴)人。西晋大臣、将领,东吴鄱阳太守周鲂之子。少时纵情肆欲,为祸乡里。后来改过自新,拜访名人陆机和陆云,浪子回头,发奋读书,留下“周处除三害”的传说,拜东观左丞,迁无难都督,功业胜过父亲。吴国灭亡后,出仕西晋,拜新平太守,转广汉太守,治境有方。入为散骑常侍,迁御史中丞,刚正不阿。得罪梁孝王司马肜。元康七年,出任建威将军,前往关中,讨伐氐羌齐万年叛乱,遇害于沙场。追赠平西将军,谥号为孝。', - wangfuzhaolei:'王甫(?—222年),字国山,广汉郪(今四川三台县)人,三国时期蜀汉重臣。刘璋时,为益州书佐,之后归降刘备,先后担任绵竹令、荆州议曹从事,并在夷陵之战中阵亡。其子王祐,官至尚书右选郎。赵累,蜀汉大将关羽部下都督。后来吴将吕蒙袭取荆州,赵累被吴将潘璋等在临沮擒获。', - wangling:'王淩(172年~251年6月15日),字彦云,太原郡祁县(今山西省祁县)人,三国时期曹魏将领,东汉司徒王允之侄。王淩出身太原王氏祁县房。举孝廉出身,授发干县令,迁中山太守。颇有政绩,迁司空(曹操)掾属。魏文帝曹丕即位,拜散骑常侍、兖州刺史。参加洞口之战,跟从张辽击败吴将吕范,加号建武将军,封宜城亭侯。太和二年(228年),王淩参与石亭之战,跟从曹休征伐东吴,力挽狂澜,历任扬豫二州刺史,治境有方。齐王曹芳继位,拜征东将军,联合孙礼击败吴将全琮,进封南乡侯,授车骑将军、仪同三司,正始九年(248年),代高柔为司空。嘉平元年(249年),代蒋济为太尉。嘉平三年(251年),不满太傅司马懿专擅朝政,联合兖州刺史令狐愚谋立楚王曹彪为帝,事泄自尽,时年八十岁,夷灭三族。', - wujing:'吴景,本吴郡吴县(今江苏苏州)人,后迁居吴郡钱塘(今浙江杭州),孙坚妻子吴夫人(武烈皇后)之弟,孙策和孙权的舅舅,东汉末年将领。吴景因追随孙坚征伐有功,被任命为骑都尉。袁术上表举荐吴景兼任丹杨太守,讨伐前任太守周昕,占据丹杨。后遭扬州刺史刘繇逼迫,再度依附袁术,袁术任用他为督军中郎将,与孙贲共同进击樊能等人。又在秣陵攻打笮融、薛礼。袁术与刘备争夺徐州时,任吴景为广陵太守。建安二年(197年),吴景放弃广陵东归孙策,孙策任他为丹杨太守。朝廷使者吴景为扬武将军,郡守之职照旧。建安八年(203年),吴景死于任上。', - feiyi:'费祎(?~253年2月),字文伟,江夏鄳县(今河南省罗山县)人,三国时期蜀汉名臣,与诸葛亮、蒋琬、董允并称为蜀汉四相。深得诸葛亮器重,屡次出使东吴,孙权、诸葛恪、羊茞等人以辞锋刁难,而费祎据理以答,辞义兼备,始终不为所屈。孙权非常惊异于他的才能,加以礼遇。北伐时为中护军,又转为司马。当时魏延与杨仪不和,经常争论,费祎常为二人谏喻,两相匡护,以尽其用。诸葛亮死后,初为后军师,再为尚书令,官至大将军,封成乡侯。费祎主政时,与姜维北伐的主张相左,执行休养生息的政策,为蜀汉的发展尽心竭力。费祎性格谦恭真诚,颇为廉洁,家无余财。后为魏降将郭循(一作郭脩)行刺身死。葬于今广元市昭化古城城西。', - luotong:'骆统(193年-228年),字公绪。会稽郡乌伤县(今浙江义乌)人。东汉末年至三国时期吴国将领、学者,陈国相骆俊之子。骆统二十岁时已任乌程国相,任内有政绩,使得国中民户过万。又迁为功曹,行骑都尉。曾劝孙权尊贤纳士,省役息民。后出任为建忠中郎将。将军凌统逝世后,统领其部曲。因战功迁偏将军,封新阳亭侯,任濡须督。黄武七年(228年),骆统去世,年仅三十六岁。有集十卷,今已佚。', + characterIntro: { + yuanhuan: + "袁涣,字曜卿,陈郡扶乐(今河南省周口市太康县)人。东汉末年官员,出身陈郡袁氏,为东汉司徒袁滂之子。袁涣早年曾任郡功曹,后被公府征辟,相继被举为高第、秀才。汉末战乱时,袁涣流寓江淮一带,初为袁术所用,后投吕布。建安三年(198年),曹操率兵剿灭了吕布,袁涣又转投曹操,拜沛南部都尉,后又任谏议大夫、郎中令等职,在任上尽心尽责,以敢谏直言称名。袁涣恕思而后行,外表温柔而内心能断,处危难则勇气极大。汉末三国时期,唯有程昱、曹仁、袁涣三人被评价为勇冠贲育。", + qiaogong: + "桥公,亦作“乔公”,名字不详,是中国汉末三国时期的长者,江东二乔的父亲,三国时期庐江郡皖县(今安徽潜山)人,中国长篇古典名著《三国演义》中称之为“乔国老”。", + liuzhang: + "刘璋(生卒年不详),字季玉,江夏竟陵(今湖北省天门市)人。东汉末年宗室、军阀,益州牧刘焉幼子,在父亲刘焉死后继任益州牧。刘璋为人懦弱多疑。汉中张鲁骄纵,不听刘璋号令,于是刘璋杀张鲁母弟,双方成为仇敌,刘璋派庞羲攻击张鲁,战败。后益州内乱,平定后,又有曹操将前来袭击的消息。在内外交逼之下,刘璋听信手下张松、法正之言,迎接刘备入益州,想借刘备之力,抵抗曹操。不料此举乃引狼入室,刘备反手攻击刘璋,又有法正为内应,进至成都。成都吏民都想抵抗刘备,但刘璋为百姓计而开城出降,群下莫不流涕。刘备占据成都后,刘璋以振威将军的身份被迁往荆州居住,关羽失荆州后,刘璋归属东吴,被孙权任命为益州牧,不久后去世,卒年不详。", + zhangzhongjing: + "张仲景(约公元150~154年—约公元215~219年),名机,字仲景,南阳涅阳县(今河南省邓州市穰东镇张寨村)人。东汉末年著名医学家,被后人尊称为“医圣”。张仲景广泛收集医方,写出了传世巨著《伤寒杂病论》。它确立的“辨证论治”原则,是中医临床的基本原则,是中医的灵魂所在。在方剂学方面,《伤寒杂病论》也做出了巨大贡献,创造了很多剂型,记载了大量有效的方剂。其所确立的六经辨证的治疗原则,受到历代医学家的推崇。这是中国第一部从理论到实践、确立辨证论治法则的医学专著,是中国医学史上影响最大的著作之一,是后学者研习中医必备的经典著作,广泛受到医学生和临床大夫的重视。", + xiangchong: + "向宠(?~240年),左将军向朗之侄,蜀汉重要将领。具有谦和公允的性格品行,对军事通晓畅达,被汉昭烈帝刘备称赞。刘备时,历任牙门将(类似于主将帐下的偏将),诸葛亮北伐时,以向宠为中领军,封都亭侯。诸葛亮北行汉中前,特意在《出师表》中向刘禅推荐向宠。延熙三年(公元240年),南征汉嘉(今四川省雅安市)蛮夷时,遇害,尸体被其部下夺回,送回成都安葬。", + caizhenji: + "蔡贞姬,生卒年不详,汉末大儒蔡邕之女。其父蔡邕精于天文数理,妙解音律,是曹操的挚友和老师。生在书香门第的家庭的蔡贞姬,自小耳濡目染,精通书法与音律。后来,其父为避宦竖迫害,便随父亲来泰山依付羊衜一族,在羊衜的元配孔氏死后,便在父亲的做主下与之成亲。夫妻二人婚后生有两子一女:羊承、羊徽瑜、羊祜。在与羊衜成亲之前,羊衜和孔氏生有一子羊发。后来羊发、羊承同时生病,蔡贞姬知道不能两全,就专心照顾羊发,最后羊发痊愈,羊承病死。", + zhouchu: + "周处(236—297年),字子隐,吴郡阳羡(今江苏宜兴)人。西晋大臣、将领,东吴鄱阳太守周鲂之子。少时纵情肆欲,为祸乡里。后来改过自新,拜访名人陆机和陆云,浪子回头,发奋读书,留下“周处除三害”的传说,拜东观左丞,迁无难都督,功业胜过父亲。吴国灭亡后,出仕西晋,拜新平太守,转广汉太守,治境有方。入为散骑常侍,迁御史中丞,刚正不阿。得罪梁孝王司马肜。元康七年,出任建威将军,前往关中,讨伐氐羌齐万年叛乱,遇害于沙场。追赠平西将军,谥号为孝。", + wangfuzhaolei: + "王甫(?—222年),字国山,广汉郪(今四川三台县)人,三国时期蜀汉重臣。刘璋时,为益州书佐,之后归降刘备,先后担任绵竹令、荆州议曹从事,并在夷陵之战中阵亡。其子王祐,官至尚书右选郎。赵累,蜀汉大将关羽部下都督。后来吴将吕蒙袭取荆州,赵累被吴将潘璋等在临沮擒获。", + wangling: + "王淩(172年~251年6月15日),字彦云,太原郡祁县(今山西省祁县)人,三国时期曹魏将领,东汉司徒王允之侄。王淩出身太原王氏祁县房。举孝廉出身,授发干县令,迁中山太守。颇有政绩,迁司空(曹操)掾属。魏文帝曹丕即位,拜散骑常侍、兖州刺史。参加洞口之战,跟从张辽击败吴将吕范,加号建武将军,封宜城亭侯。太和二年(228年),王淩参与石亭之战,跟从曹休征伐东吴,力挽狂澜,历任扬豫二州刺史,治境有方。齐王曹芳继位,拜征东将军,联合孙礼击败吴将全琮,进封南乡侯,授车骑将军、仪同三司,正始九年(248年),代高柔为司空。嘉平元年(249年),代蒋济为太尉。嘉平三年(251年),不满太傅司马懿专擅朝政,联合兖州刺史令狐愚谋立楚王曹彪为帝,事泄自尽,时年八十岁,夷灭三族。", + wujing: "吴景,本吴郡吴县(今江苏苏州)人,后迁居吴郡钱塘(今浙江杭州),孙坚妻子吴夫人(武烈皇后)之弟,孙策和孙权的舅舅,东汉末年将领。吴景因追随孙坚征伐有功,被任命为骑都尉。袁术上表举荐吴景兼任丹杨太守,讨伐前任太守周昕,占据丹杨。后遭扬州刺史刘繇逼迫,再度依附袁术,袁术任用他为督军中郎将,与孙贲共同进击樊能等人。又在秣陵攻打笮融、薛礼。袁术与刘备争夺徐州时,任吴景为广陵太守。建安二年(197年),吴景放弃广陵东归孙策,孙策任他为丹杨太守。朝廷使者吴景为扬武将军,郡守之职照旧。建安八年(203年),吴景死于任上。", + feiyi: "费祎(?~253年2月),字文伟,江夏鄳县(今河南省罗山县)人,三国时期蜀汉名臣,与诸葛亮、蒋琬、董允并称为蜀汉四相。深得诸葛亮器重,屡次出使东吴,孙权、诸葛恪、羊茞等人以辞锋刁难,而费祎据理以答,辞义兼备,始终不为所屈。孙权非常惊异于他的才能,加以礼遇。北伐时为中护军,又转为司马。当时魏延与杨仪不和,经常争论,费祎常为二人谏喻,两相匡护,以尽其用。诸葛亮死后,初为后军师,再为尚书令,官至大将军,封成乡侯。费祎主政时,与姜维北伐的主张相左,执行休养生息的政策,为蜀汉的发展尽心竭力。费祎性格谦恭真诚,颇为廉洁,家无余财。后为魏降将郭循(一作郭脩)行刺身死。葬于今广元市昭化古城城西。", + luotong: + "骆统(193年-228年),字公绪。会稽郡乌伤县(今浙江义乌)人。东汉末年至三国时期吴国将领、学者,陈国相骆俊之子。骆统二十岁时已任乌程国相,任内有政绩,使得国中民户过万。又迁为功曹,行骑都尉。曾劝孙权尊贤纳士,省役息民。后出任为建忠中郎将。将军凌统逝世后,统领其部曲。因战功迁偏将军,封新阳亭侯,任濡须督。黄武七年(228年),骆统去世,年仅三十六岁。有集十卷,今已佚。", }, - characterTitle:{ - }, - card:{ - binglinchengxiax:{ - enable:true, - type:'trick', - derivation:'sp_xunchen', - fullskin:true, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - if(!player.isIn()||!target.isIn()){ + characterTitle: {}, + card: { + binglinchengxiax: { + enable: true, + type: "trick", + derivation: "sp_xunchen", + fullskin: true, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + if (!player.isIn() || !target.isIn()) { event.finish(); return; } - event.showCards=get.cards(4); + event.showCards = get.cards(4); game.cardsGotoOrdering(event.showCards); player.showCards(event.showCards); - 'step 1' - if(player.isIn()&&target.isIn()&&event.showCards.length){ - for(var i of event.showCards){ - if(i.name=='sha'&&player.canUse(i,target,false)){ - player.useCard(i,target,false); + "step 1"; + if (player.isIn() && target.isIn() && event.showCards.length) { + for (var i of event.showCards) { + if (i.name == "sha" && player.canUse(i, target, false)) { + player.useCard(i, target, false); event.showCards.remove(i); event.redo(); break; } } } - 'step 2' - if(event.showCards.length){ - while(event.showCards.length) ui.cardPile.insertBefore(event.showCards.pop().fix(),ui.cardPile.firstChild); + "step 2"; + if (event.showCards.length) { + while (event.showCards.length) + ui.cardPile.insertBefore(event.showCards.pop().fix(), ui.cardPile.firstChild); game.updateRoundNumber(); } }, - ai:{ - basic:{ - useful:4, - value:3, + ai: { + basic: { + useful: 4, + value: 3, }, - order:4, - result:{ - target:function(player,target,card,isLink){ - if(get.effect(target,{name:'sha'},player,target)==0) return 0; + order: 4, + result: { + target: function (player, target, card, isLink) { + if (get.effect(target, { name: "sha" }, player, target) == 0) return 0; return -2.5; }, }, - tag:{ - respond:1, - respondShan:1, - damage:1, - } - } + tag: { + respond: 1, + respondShan: 1, + damage: 1, + }, + }, }, - tiaojiyanmei:{ - enable:true, - type:'trick', - derivation:'feiyi', - fullskin:true, - filterTarget:function(card,player,target){ - var targets=[]; - if(ui.selected.targets.length) targets.addArray(ui.selected.targets); - var evt=_status.event.getParent('useCard'); - if(evt&&evt.card==card) targets.addArray(evt.targets); - if(targets.length){ - var hs=target.countCards('h'); - for(var i of targets){ - if(i.countCards('h')!=hs) return true; + tiaojiyanmei: { + enable: true, + type: "trick", + derivation: "feiyi", + fullskin: true, + filterTarget: function (card, player, target) { + var targets = []; + if (ui.selected.targets.length) targets.addArray(ui.selected.targets); + var evt = _status.event.getParent("useCard"); + if (evt && evt.card == card) targets.addArray(evt.targets); + if (targets.length) { + var hs = target.countCards("h"); + for (var i of targets) { + if (i.countCards("h") != hs) return true; } return false; } return true; }, - recastable:true, - selectTarget:2, - postAi:()=>true, - contentBefore:function(){ - if(!targets.length) return; - var map={}; - event.getParent().customArgs.default.tiaojiyanmei_map=map; - var average=0; - for(var target of targets){ - var hs=target.countCards('h'); - map[target.playerid]=hs; - average+=hs; + recastable: true, + selectTarget: 2, + postAi: () => true, + contentBefore: function () { + if (!targets.length) return; + var map = {}; + event.getParent().customArgs.default.tiaojiyanmei_map = map; + var average = 0; + for (var target of targets) { + var hs = target.countCards("h"); + map[target.playerid] = hs; + average += hs; } - map.average=(average/targets.length); + map.average = average / targets.length; }, - content:function(){ - var map=event.tiaojiyanmei_map,num1=map.average,num2=map[target.playerid]; - if(typeof num2!='number') num2=target.countCards('h'); - if(num2>num1) target.chooseToDiscard('he',true); - else if(num2 num1) target.chooseToDiscard("he", true); + else if (num2 < num1) target.draw(); }, - contentAfter:function(){ - 'step 0' - if(!player.isIn()||targets.length<2){ + contentAfter: function () { + "step 0"; + if (!player.isIn() || targets.length < 2) { event.finish(); return; } - var num=targets[0].countCards('h'); - for(var i=1;inum1){ - if(target.countCards('e',function(card){ - return get.value(card)<=0; - })) return 1; + result: { + target: function (player, target, card, isLink) { + var targets = []; + if (ui.selected.targets.length) targets.addArray(ui.selected.targets); + var evt = _status.event.getParent("useCard"); + if (evt && evt.card == card) targets.addArray(evt.targets); + if ( + evt && + evt.card == card && + evt.customArgs && + evt.customArgs.tiaojiyanmei_map + ) { + var map = evt.customArgs.tiaojiyanmei_map, + num1 = map.average, + num2 = map[target.playerid]; + if (typeof num2 != "number") num2 = target.countCards("h"); + if (num2 > num1) { + if ( + target.countCards("e", function (card) { + return get.value(card) <= 0; + }) + ) + return 1; return -1; } - if(num2average){ - if(target.countCards('e',function(card){ - return get.value(card)<=0; - })) return 1; + var average = 0; + for (var i of targets) average += i.countCards("h", fh); + if (!targets.includes(target)) { + var th = target.countCards("h", fh); + average += th; + average /= targets.length + 1; + if (th == average) return 0; + if (th < average) return th == average - 1 ? 2 : 1; + if (th > average) { + if ( + target.countCards("e", function (card) { + return get.value(card) <= 0; + }) + ) + return 1; return -0.5; } return 0; } - average/=targets.length; - if(thaverage){ - if(target.countCards('e',function(card){ - return get.value(card)<=0; - })) return 1; + average /= targets.length; + if (th < average) return 1; + if (th > average) { + if ( + target.countCards("e", function (card) { + return get.value(card) <= 0; + }) + ) + return 1; return -1; } return 0; @@ -6503,372 +7957,475 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - characterFilter:{ + characterFilter: {}, + dynamicTranslate: {}, + perfectPair: { + wujing: ["sunce", "sunben", "wuguotai"], }, - dynamicTranslate:{ + characterReplace: { + wangcan: ["wangcan", "sp_wangcan", "tw_wangcan"], + sunshao: ["sunshao", "sp_sunshao"], + xunchen: ["xunchen", "re_xunchen", "sp_xunchen", "tw_xunchen", "clan_xunchen"], + xinpi: ["xinpi", "sp_xinpi"], + duyu: ["duyu", "dc_duyu", "sp_duyu", "pk_sp_duyu"], + zhangwen: ["zhangwen", "sp_zhangwen"], + ol_bianfuren: ["ol_bianfuren", "sp_bianfuren", "tw_bianfuren"], + wangshuang: ["wangshuang", "sp_wangshuang"], + huaman: ["huaman", "sp_huaman"], + gaolan: ["gaolan", "dc_gaolan", "sp_gaolan"], + cuiyan: ["cuiyan", "sp_cuiyan"], + wujing: ["wujing", "tw_wujing"], + zhouchu: ["jin_zhouchu", "zhouchu", "tw_zhouchu"], + liuzhang: ["liuzhang", "tw_liuzhang"], + chenzhen: ["sp_chenzhen", "tw_chenzhen"], + feiyi: ["ol_feiyi", "feiyi", "tw_feiyi"], + wangling: ["dc_wangling", "wangling", "tw_wangling", "clan_wangling"], + qiaogong: ["qiaogong", "tw_qiaogong"], + sp_chendong: ["sp_chendong", "tw_chendong", "chendong"], + sp_jiangqing: ["sp_jiangqing", "tw_jiangqing", "jiangqing"], + kongrong: ["dc_kongrong", "sp_kongrong", "jsrg_kongrong", "kongrong"], + dc_mifuren: ["dc_mifuren", "sp_mifuren"], }, - perfectPair:{ - wujing:['sunce','sunben','wuguotai'], - }, - characterReplace:{ - wangcan:['wangcan','sp_wangcan','tw_wangcan'], - sunshao:['sunshao','sp_sunshao'], - xunchen:['xunchen','re_xunchen','sp_xunchen','tw_xunchen','clan_xunchen'], - xinpi:['xinpi','sp_xinpi'], - duyu:['duyu','dc_duyu','sp_duyu','pk_sp_duyu'], - zhangwen:['zhangwen','sp_zhangwen'], - ol_bianfuren:['ol_bianfuren','sp_bianfuren','tw_bianfuren'], - wangshuang:['wangshuang','sp_wangshuang'], - huaman:['huaman','sp_huaman'], - gaolan:['gaolan','dc_gaolan','sp_gaolan'], - cuiyan:['cuiyan','sp_cuiyan'], - wujing:['wujing','tw_wujing'], - zhouchu:['jin_zhouchu','zhouchu','tw_zhouchu'], - liuzhang:['liuzhang','tw_liuzhang'], - chenzhen:['sp_chenzhen','tw_chenzhen'], - feiyi:['ol_feiyi','feiyi','tw_feiyi'], - wangling:['dc_wangling','wangling','tw_wangling','clan_wangling'], - qiaogong:['qiaogong','tw_qiaogong'], - sp_chendong:['sp_chendong','tw_chendong','chendong'], - sp_jiangqing:['sp_jiangqing','tw_jiangqing','jiangqing'], - kongrong:['dc_kongrong','sp_kongrong','jsrg_kongrong','kongrong'], - dc_mifuren:['dc_mifuren','sp_mifuren'], - }, - translate:{ - liuba_prefix:'手杀', - sp_zhujun_prefix:'手杀', - sp_huangfusong_prefix:'手杀', - sp_zhangchangpu_prefix:'手杀', - sp_cuiyan_prefix:'手杀', - sp_huaman_prefix:'手杀', - sp_gaolan_prefix:'手杀', - sunyi_prefix:'手杀', - sp_wangshuang_prefix:'手杀', - sp_zongyu_prefix:'手杀', - db_wenyang_prefix:'手杀', - sp_yanghu_prefix:'手杀', - sp_zhangwen_prefix:'手杀', - sp_xujing_prefix:'手杀', - sp_huaxin_prefix:'手杀', - zhouchu_prefix:'手杀', - sp_mifuren_prefix:'手杀', - sp_xinpi_prefix:'手杀', - sp_bianfuren_prefix:'手杀', - sp_duyu_prefix:'手杀', - luotong_prefix:'手杀', - sp_wangcan_prefix:'手杀', - sp_sunshao_prefix:'手杀', - sp_xunchen_prefix:'手杀', - sp_kongrong_prefix:'手杀', + translate: { + liuba_prefix: "手杀", + sp_zhujun_prefix: "手杀", + sp_huangfusong_prefix: "手杀", + sp_zhangchangpu_prefix: "手杀", + sp_cuiyan_prefix: "手杀", + sp_huaman_prefix: "手杀", + sp_gaolan_prefix: "手杀", + sunyi_prefix: "手杀", + sp_wangshuang_prefix: "手杀", + sp_zongyu_prefix: "手杀", + db_wenyang_prefix: "手杀", + sp_yanghu_prefix: "手杀", + sp_zhangwen_prefix: "手杀", + sp_xujing_prefix: "手杀", + sp_huaxin_prefix: "手杀", + zhouchu_prefix: "手杀", + sp_mifuren_prefix: "手杀", + sp_xinpi_prefix: "手杀", + sp_bianfuren_prefix: "手杀", + sp_duyu_prefix: "手杀", + luotong_prefix: "手杀", + sp_wangcan_prefix: "手杀", + sp_sunshao_prefix: "手杀", + sp_xunchen_prefix: "手杀", + sp_kongrong_prefix: "手杀", - sp_wangcan:'手杀王粲', - spqiai:'七哀', - spqiai_info:'出牌阶段限一次,你可以将一张非基本牌交给一名其他角色。然后其选择一项:①你回复1点体力。②你摸两张牌。', - spshanxi:'善檄', - spshanxi_suoming:'善檄', - spshanxi_info:'出牌阶段开始时,你可令一名其他角色获得“檄”标记并清除场上已有的其他“檄”标记(若有)。有“檄”标记的角色回复体力时,若其体力值大于0,则其需选择一项:①交给你两张牌。②失去1点体力。', - sp_chenzhen:'陈震', - shameng:'歃盟', - shameng_info:'出牌阶段限一次,你可弃置两张颜色相同的手牌并选择一名其他角色。其摸两张牌,然后你摸三张牌。', - sp_sunshao:'手杀孙邵', - fubi:'辅弼', - fubi2:'辅弼', - fubi_info:'游戏开始时,你可选择一名其他角色。该角色的手牌上限于你死亡前+3。', - zuici:'罪辞', - zuici_info:'当你进入濒死状态时,你可废除你的一个不为空的装备栏,然后将体力值回复至1点。', - sp_xunchen:'手杀荀谌', - jianzhan:'谏战', - jianzhan_info:'出牌阶段限一次,你可选择一名其他角色A和其攻击范围内的另一名手牌数小于其的角色B。A选择一项:①视为对B使用一张【杀】。②令你摸一张牌。', - duoji:'夺冀', - duoji_info:'限定技,出牌阶段,你可弃置两张手牌并选择一名装备区有牌的其他角色。你获得其装备区里的所有牌。', - binglinchengxiax:'兵临城下', - binglinchengxiax_info:'出牌阶段,对一名其他角色使用。你展示牌堆顶的四张牌,依次对其使用其中所有的【杀】,然后将剩余的牌置于牌堆顶。', - mjweipo:'危迫', - mjweipo_effect:'危迫', - mjweipo_remove:'危迫', - mjweipo_info:'出牌阶段限一次。你可以选择一个智囊或【兵临城下】,令一名没有〖危迫〗效果的角色获得如下一次性效果直到你下回合开始:其可于出牌阶段弃置一张【杀】,并获得一张你选择的牌。', - mjchenshi:'陈势', - mjchenshi_player:'陈势', - mjchenshi_target:'陈势', - mjchenshi_info:'当有角色使用【兵临城下】指定第一个目标后,其可交给你一张牌,并将牌堆的顶三张牌中所有不为【杀】的牌置入弃牌堆;当有角色成为【兵临城下】的目标后,其可交给你一张牌,然后将牌堆顶三张牌中所有的【杀】置入弃牌堆。', - mjmouzhi:'谋识', - mjmouzhi_info:'锁定技,当你受到伤害时,若伤害渠道对应的牌和你上次受到的伤害花色相同,则你防止此伤害。', - luotong:'手杀骆统', - qinzheng:'勤政', - qinzheng_info:'锁定技,当你使用或打出牌时,若你本局游戏内使用或打出过的牌数和:为3的倍数,你从牌堆中获得一张【杀】或【闪】;为5的倍数,你从牌堆中获得一张【桃】或【酒】;为8的倍数,你从牌堆中获得一张【决斗】或【无中生有】(可获得对应的衍生替换牌)。', - sp_duyu:'手杀杜预', - spwuku:'武库', - spwuku_info:'锁定技,当有角色使用装备牌时,若你的“武库”数小于3,则你获得一个“武库”。', - spwuku_info_guozhan:'锁定技,当有其他势力的角色使用装备牌时,若你的“武库”数小于2,则你获得一个“武库”。', - spsanchen:'三陈', - spsanchen_info:'觉醒技,结束阶段,若你的“武库”数大于2,则你加1点体力上限并回复1点体力,然后获得〖灭吴〗。', - spmiewu:'灭吴', - spmiewu2:'灭吴', - spmiewu_backup:'灭吴', - spmiewu_info:'每回合限一次。你可弃置一枚“武库”并将一张牌当做任意基本牌或锦囊牌使用,然后摸一张牌。', - sp_bianfuren:'手杀卞夫人', - spwanwei:'挽危', - spwanwei_info:'每轮累计限一次。①出牌阶段,你可选择一名其他角色。②当有其他角色处于濒死状态时。你可令该角色回复X+1点体力(至少回复至1),然后你失去X点体力。(X为你的体力值)', - spyuejian:'约俭', - spyuejian_info:'锁定技,你的手牌上限基数等于你的体力上限。当你处于濒死状态时,你可弃置两张牌,然后回复1点体力。', - feiyi:'手杀费祎', - feiyi_prefix:'手杀', - reshengxi:'生息', - reshengxi_info:'结束阶段,若你于本回合内未造成过伤害,则你可摸两张牌。', - fyjianyu:'谏喻', - fyjianyu_info:'每轮限一次。出牌阶段,你可选择两名角色,令这些角色获得“喻”直到你的下回合开始。当一名有“喻”的角色A使用牌指定另一名有“喻”的角色B为目标时,你令B摸一张牌。', - mjshengxi:'生息', - mjshengxi_info:'准备阶段,你可以获得一张【调剂盐梅】;结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊或摸一张牌。', - mjkuanji:'宽济', - mjkuanji_info:'每回合限一次。当你因弃置而失去牌后,你可令一名其他角色获得其中的一张牌,然后你摸一张牌。', - tiaojiyanmei:'调剂盐梅', - tiaojiyanmei_info:'出牌阶段,对两名手牌数不均相同的其他角色使用。若目标角色于此牌使用准备工作结束时的手牌数大于此时所有目标的平均手牌数,其弃置一张牌。若小于则其摸一张牌。此牌使用结束后,若所有目标角色的手牌数均相等,则你可令一名角色获得所有因执行此牌效果而弃置的牌。', - refubi:'辅弼', - refubi_info:'游戏开始时,你可令一名其他角色获得“辅弼”标记。有“辅弼”标记的角色的准备阶段开始时,你可选择一项:①令其本回合使用【杀】的次数上限+1。②令其本回合的手牌上限+3。', - rezuici:'罪辞', - rezuici_backup:'罪辞', - rezuici_info:'出牌阶段,或当你处于濒死状态时,你可以废除一个有牌的装备栏并回复2点体力,然后可以移动“辅弼”标记。', - mjdingyi:'定仪', - mjdingyi_info:'游戏开始时,你选择一个效果(相同效果不可叠加)并令全场角色获得之:①摸牌阶段额定摸牌数+1。②手牌上限+2。③攻击范围+1。④脱离濒死状态时回复1点体力。', - mjzuici:'罪辞', - mjzuici_info:'当你受到伤害后,你可令伤害来源失去〖定仪〗效果,然后令其从牌堆中获得一张由你选择的智囊。', - mjfubi:'辅弼', - mjfubi_info:'每轮限一次。出牌阶段,你可选择一项:①更换一名角色的〖定仪〗效果。②弃置一张牌并令一名角色的〖定仪〗效果翻倍直到你的下回合开始。', - wujing:'吴景', - heji:'合击', - heji_info:'当有角色使用的【决斗】或红色【杀】结算完成后,若此牌对应的目标数为1,则你可以对相同的目标使用一张【杀】或【决斗】(无距离和次数限制)。若你以此法使用的牌不为转化牌,则你从牌堆中随机获得一张红色牌。', - liubing:'流兵', - liubing_info:'锁定技。①你于出牌阶段使用的第一张非虚拟【杀】的花色视为♦。②其他角色于其出牌阶段内使用的非转化黑色杀结算结束后,若此【杀】未造成伤害,则你获得之。', - sp_mifuren:'手杀糜夫人', - spcunsi:'存嗣', - spcunsi2:'存嗣', - spcunsi_info:'出牌阶段限一次,你可将武将牌翻至背面并选择一名其他角色。其从牌堆或弃牌堆中获得一张【杀】,且下一张杀的伤害值基数+1。', - spguixiu:'闺秀', - spguixiu_info:'锁定技,当你受到伤害后,若你的武将牌背面朝上,则你将武将牌翻至正面。当你的武将牌从背面翻至正面时,你摸一张牌。', - qingyu:'清玉', - qingyu_info:'使命技。①当你受到伤害时,你弃置两张牌,然后防止此伤害。②使命:准备阶段,若你的体力值等于体力上限且你没有手牌,则你获得〖悬存〗。③失败:当你进入濒死状态时,你减1点体力上限。', - xuancun:'悬存', - xuancun_info:'其他角色的回合结束时,若你的手牌数小于体力值,则你可以令其摸X张牌(X为你的体力值与手牌数之差且至多为2)。', - xinlirang:'礼让', - xinlirang_info:'①其他角色的摸牌阶段开始时,若你没有“谦”标记,则你可以获得一枚“谦”标记。若如此做,其额定摸牌数+2,且本回合的弃牌阶段开始时,你可以获得其弃置的至多两张牌。②摸牌阶段开始时,若你有“谦”标记,则你跳过此摸牌阶段并移除“谦”标记。', - xinmingshi:'名仕', - xinmingshi_info:'锁定技,当你受到伤害后,若你有“谦”标记,则伤害来源弃置一张牌。若此牌为:黑色:你获得之。红色,你回复1点体力。', - sp_xinpi:'手杀辛毗', - spyinju:'引裾', - spyinju2:'引裾', - spyinju_info:'出牌阶段限一次,你可令一名其他角色选择一项:①对你使用一张【杀】(无距离限制)。②其下个回合的准备阶段开始时,跳过出牌阶段和弃牌阶段。', - spchijie:'持节', - spchijie_info:'每回合限一次。当你成为其他角色使用牌的唯一目标时,你可判定。若结果大于6,则你取消此牌的所有目标。', - reduoji:'夺冀', - reduoji_info:'出牌阶段限一次,你可将一张牌置于其他角色的武将牌上,称为“冀”。当有装备牌因使用而进入一名角色的装备区后,若该角色有“冀”且其为使用者,则你获得此装备牌,其移去一个“冀”并摸一张牌。一名其他角色的回合结束后,若其有“冀”,则你获得其的所有“冀”。', - wangling:'手杀王淩', - wangling_prefix:'手杀', - mouli:'谋立', - mouli_info:'出牌阶段限一次,你可以将一张手牌交给一名其他角色,其获得如下效果直到你的下回合开始:其可以将黑色牌当做【杀】,红色牌当做【闪】使用。其第一次触发“使用【杀】/【闪】结算完成后”的时机时,你摸三张牌。', - zifu:'自缚', - zifu_info:'锁定技,当有角色死亡时,若其因你获得的“谋立”效果未过期,则你减2点体力上限。', - xingqi:'星启', - xingqi_info:'①当你使用牌时,若此牌不为延时锦囊牌且你没有同名的“备”,则你获得一枚与此牌名称相同的“备”。②结束阶段,你可移去一枚“备”,然后从牌堆中获得一张与此“备”名称相同的牌。', - xinzifu:'自缚', - xinzifu_info:'锁定技。出牌阶段结束时,若你本阶段内未使用牌,则你移去所有“备”且本回合的手牌上限-1。', - mibei:'秘备', - mibei_info:'使命技。①使命:当你使用的牌结算完成后,若你的“备”中包含的基本牌,锦囊牌,装备牌数量均大于1,则你从牌堆中获得这三种类型的牌各一张并获得技能“谋立”。②失败:结束阶段开始时,若你没有“备”,且你于本回合的准备阶段开始时也没有“备”,则你减1点体力上限。', - xinmouli:'谋立', - xinmouli_info:'出牌阶段限一次,你可以指定一名其他角色。其移去你的一个“备”,然后从牌堆中获得一张与此“备”名称相同的牌。', - wangfuzhaolei:'王甫赵累', - xunyi:'殉义', - xunyi2:'殉义', - xunyi3:'殉义', - xunyi_info:'游戏开始时,或当上一个拥有“殉义”效果的角色死亡后,你可以选择一名角色获得如下效果:当其/你对二者之外的角色造成伤害后,你/其摸一张牌;当其/你受到二者之外的角色造成的伤害后,你/其弃置一张牌。', - zhouchu:'手杀周处', - xianghai:'乡害', - xianghai_info:'锁定技,其他角色的手牌上限-1。你手牌区的装备牌均视为【酒】。', - chuhai:'除害', - chuhai_info:'出牌阶段限一次,你可以摸一张牌,然后和一名其他角色拼点。若你赢,则你观看其手牌,并从牌堆/弃牌堆中获得其手牌中包含的类型的牌各一张,且当你于此阶段内对其造成伤害后,你将牌堆/弃牌堆中的一张装备牌置于你的一个空置装备栏内。', - rechuhai:'除害', - rechuhai_info:'使命技。①出牌阶段限一次,你可以摸一张牌,然后和一名其他角色拼点。若你赢,则你观看其手牌,并从牌堆/弃牌堆中获得其手牌中包含的类型的牌各一张,且当你于此阶段内对其造成伤害后,你将牌堆/弃牌堆中的一张装备牌置于你的一个空置装备栏内。②当你因发动〖除害①〗而展示拼点牌时,你令此牌的点数+X(X=(4-你装备区的牌数))。③使命:当有装备牌进入你的装备区后,若你的装备区内有至少三张牌,则你将体力值回复至上限,失去〖乡害〗并获得〖彰名〗。④失败:当你因发动〖除害①〗发起的拼点没赢时,若你的最终点数不大于6,则你触发使命失败分支。', - zhangming:'彰名', - zhangming_info:'锁定技。①你使用的♣牌不能被其他角色响应。②每回合限一次,当你对其他角色造成伤害后,你随机弃置其一张手牌,然后你从牌堆或弃牌堆中获得与其展示牌类型不同类型的牌各一张(若其没有手牌,则你改为从牌堆或弃牌堆中获得所有类型牌各一张),且以此法得到的牌不计入本回合的手牌上限。', - sp_kongrong:'手杀孔融', - spmingshi:'名士', - spmingshi_info:'锁定技,当你受到1点伤害后,伤害来源弃置一张牌。', - splirang:'礼让', - splirang_info:'出牌阶段限一次,你可以弃置所有手牌,然后将其中的至多X张牌交给一名其他角色(X为你的体力值),之后摸一张牌。', - caizhenji:'蔡贞姬', - sheyi:'舍裔', - sheyi_info:'每轮限一次。当有体力值小于你的其他角色受到伤害时,你可以交给其至少X张牌并防止此伤害(X为你的体力值)。', - tianyin:'天音', - tianyin_info:'锁定技,结束阶段开始时,你从牌堆中获得每种本回合未使用过的类型的牌各一张。', - xiangchong:'向宠', - guying:'固营', - guying_info:'锁定技。每回合限一次,当你于回合外因使用/打出/弃置而失去牌后,若牌数为1,则你获得一枚“固”并令当前回合角色选择一项:①随机交给你一张牌。②令你获得本次失去的牌,若为装备牌,则你使用之。准备阶段开始时,你移去所有“固”并弃置等量的牌。', - muzhen:'睦阵', - muzhen_backup:'睦阵', - muzhen_info:'出牌阶段各限一次。①你可以将两张牌交给一名装备区内有牌的其他角色,然后获得其装备区内的一张牌。②你可以将装备区内的一张牌置于其他角色的装备区内,然后获得其一张手牌。', - sp_huaxin:'手杀华歆', - hxrenshi:'仁仕', - hxrenshi_info:'出牌阶段每名角色限一次。你可以将一张手牌交给一名其他角色。', - debao:'德保', - debao_info:'锁定技,当其他角色获得你的牌后,若你的“仁”数小于你的体力上限,则你将牌堆顶的一张牌置于你的武将牌上,称为“仁”。准备阶段,你获得所有“仁”。', - buqi:'不弃', - buqi_info:'锁定技,当有角色进入濒死状态时,若你的“仁”数大于1,则你移去两张“仁”并令其回复1点体力。一名角色死亡后,你将所有“仁”置入弃牌堆。', - yuanqing:'渊清', - yuanqing_info:'锁定技,出牌阶段结束时,你随机将弃牌堆中你本阶段使用过的牌类型的各一张牌置于仁库中。', - shuchen:'疏陈', - shuchen_info:'锁定技,当有角色进入濒死状态时,若仁库中的牌数大于三,则你获得仁库中的所有牌,然后其回复1点体力。', - sp_xujing:'手杀许靖', - boming:'博名', - boming_info:'出牌阶段限两次,你可以将一张牌交给一名其他角色。结束阶段,若你本回合以此法失去了两张以上的牌,则你摸一张牌。', - ejian:'恶荐', - ejian_info:'锁定技,每名角色限一次。当有其他角色因〖博名〗而得到了你的牌后,若其拥有与此牌类型相同的其他牌,则你令其选择一项:①受到1点伤害。②展示所有手牌,并弃置所有与此牌类别相同的牌。', - zhangzhongjing:'张机', - jishi:'济世', - jishi_info:'锁定技。①当你使用的牌结算完成后,若你未因此牌造成过伤害,则你将此牌对应的所有实体牌置于仁库中。②当有牌不因溢出而离开仁库时,你摸一张牌。', - liaoyi:'疗疫', - liaoyi_info:'其他角色的回合开始时,若其:①手牌数小于体力值且仁库内牌数大于等于X,则你可令其从仁库中获得X张牌;②手牌数大于体力值,则你可以令其将X张牌置于仁库中(X为其手牌数与体力值之差且至多为4)。', - xinliaoyi:'疗疫', - xinliaoyi_info:'其他角色的回合开始时,你可选择一项:①令其从仁库中获得一张牌。②若其手牌数大于体力值,则令其将X张手牌置入仁库(X为其手牌数与体力值之差)。', - binglun:'病论', - binglun_info:'出牌阶段限一次,你可以将仁库中的一张牌置于弃牌堆并选择一名角色。该角色选择一项:①摸一张牌。②于其下回合结束时回复1点体力。', - sp_zhangwen:'手杀张温', - gebo:'戈帛', - gebo_info:'锁定技,当有角色回复体力后,你将牌堆顶的一张牌置入仁库。', - spsongshu:'颂蜀', - spsongshu_info:'其他角色的摸牌阶段开始时,若其体力值大于你且仁库内有牌,则你可以令其放弃摸牌。其改为获得X张仁(X为你的体力值且至多为5),且本回合内不能使用牌指定其他角色为目标。', - liuzhang:'刘璋', - xiusheng:'休生', - xiusheng_info:'锁定技。准备阶段,你将所有“生”置入弃牌堆,然后摸X张牌,并将等量的牌置于武将牌上,称为“生”(X为你因〖引狼〗而选择的势力的存活角色数)。', - yinlang:'引狼', - yinlang_info:'①每轮限一次。回合开始时,你选择场上的一个势力。②一名角色的出牌阶段开始时,若其势力与你选择的势力相同,则其选择一项:1.获得你的一张“生”,然后其本回合使用牌时不能指定你以外的角色为目标。2.你获得一张“生”。', - huaibi:'怀璧', - huaibi_info:'主公技,锁定技。你的手牌上限+X(X为你因〖引狼〗而选择的势力的存活角色数)。', - jutu:'据土', - jutu_info:'锁定技,准备阶段,你获得所有你武将牌上的“生”,然后摸X+1张牌,然后将X张牌置于你的武将牌上,称为“生”(X为你因〖邀虎〗选择势力的角色数量)。', - yaohu:'邀虎', - yaohu_info:'每轮限一次,你的回合开始时,你须选择场上一个势力。该势力其他角色的出牌阶段开始时,其获得你的一张“生”,然后其须选择一项:①对你指定的另一名的其他角色使用一张【杀】(无距离和次数限制);②交给你两张牌。', - rehuaibi:'怀璧', - rehuaibi_info:'主公技,锁定技,你的手牌上限+X(X为你因〖邀虎〗选择势力的角色数量)。', - qiaogong:'桥公', - yizhu:'遗珠', - yizhu_info:'①结束阶段,你摸两张牌,然后将两张牌随机插入牌堆前2X张牌的位置中(X为角色数,选择牌的牌名对其他角色可见)。②其他角色使用“遗珠”牌指定唯一目标时,你可以取消此目标,然后你清除对应的“遗珠”标记。', - luanchou:'鸾俦', - luanchou_info:'出牌阶段限一次,你可令两名角色获得“姻”标记并清除原有标记。拥有“姻”标记的角色视为拥有技能〖共患〗。', - gonghuan:'共患', - gonghuan_info:'锁定技。每回合限一次,一名其他角色受到伤害时,若其拥有“姻”标记且其体力值小于你,则你将伤害转移给自己。此伤害结算结束后,你与其移去“姻”标记。', - sp_yanghu:'手杀羊祜', - mingfa:'明伐', - mingfa_info:'①结束阶段,你可展示一张牌并记录为“明伐”。②出牌阶段开始时,若“明伐”牌在你的手牌区或装备区,则你可以使用“明伐”牌与一名其他角色拼点。若你赢:你获得对方一张牌并从牌堆中获得一张点数等于“明伐”牌牌面点数-1的牌。若你没赢:你本回合不能使用牌指定其他角色为目标。③你的拼点牌亮出后,你令此牌的点数+2。', - rongbei:'戎备', - rongbei_info:'限定技。出牌阶段,你可选择一名有空装备栏的角色。系统为该角色的每个空装备栏选择一张装备牌,然后该角色使用之。', - db_wenyang:'手杀文鸯', - dbquedi:'却敌', - dbquedi_info:'每回合限一次。当你使用【杀】或【决斗】指定唯一目标后,你可选择:①获得目标角色的一张手牌。②弃置一张基本牌,并令此牌的伤害值基数+1。③背水:减1点体力上限,然后依次执行上述所有选项。', - dbzhuifeng:'椎锋', - dbzhuifeng_info:'魏势力技。每回合限两次,你可以失去1点体力并视为使用一张【决斗】(你死亡后仍然结算)。当你因此【决斗】而受到伤害时,你防止此伤害并令此技能失效直到出牌阶段结束。', - dbchongjian:'冲坚', - dbchongjian_backup:'冲坚', - dbchongjian_info:'吴势力技。你可以将一张装备牌当做一种【杀】(无距离限制且无视防具)或【酒】使用。当你以此法使用【杀】造成伤害后,你获得目标角色装备区内的X张牌(X为伤害值)。', - dbchoujue:'仇决', - dbchoujue_info:'锁定技。当你杀死其他角色后,你加1点体力上限并摸两张牌,然后本回合发动【却敌】的次数上限+1。', - sp_chendong:'手杀陈武董袭', - sp_chendong_prefix:'手杀', - spyilie:'毅烈', - spyilie_info:'出牌阶段开始时,你可选择:①本阶段内使用【杀】的次数上限+1。②本回合内使用【杀】被【闪】抵消时,摸一张牌。③背水:失去1点体力,然后依次执行上述所有选项。', - spfenming:'奋命', - spfenming_info:'出牌阶段限一次,你可以选择一名体力值不大于你的角色。若其:未横置,其横置;已横置,你获得其一张牌。', - yuanhuan:'袁涣', - qingjue:'请决', - qingjue_info:'每轮限一次。当有其他角色A使用牌指定另一名体力值小于A且不处于濒死状态的其他角色B为目标时,你可以摸一张牌,然后与A拼点。若你赢,你取消此目标。若你没赢,你将此牌的目标改为自己。', - fengjie:'奉节', - fengjie2:'奉节', - fengjie_info:'锁定技,准备阶段开始时,你选择一名其他角色并获得如下效果直到你下回合开始:一名角色的结束阶段开始时,你将手牌摸至(至多摸四张)或弃置至与其体力值相等。', - sp_zongyu:'手杀宗预', - zhibian:'直辩', - zhibian_info:'准备阶段,你可以和一名其他角色拼点。若你赢,你可选择:①将其装备区/判定区内的一张牌移动到你的对应区域。②回复1点体力。③背水:跳过下个摸牌阶段,然后依次执行上述所有选项;若你没赢,你失去1点体力。', - yuyan:'御严', - yuyan_info:'锁定技。当你成为非转换的【杀】的目标时,若使用者的体力值大于你且此【杀】有点数,则你令使用者选择一项:①交给你一张点数大于此【杀】的牌。②取消此目标。', - sp_wangshuang:'手杀王双', - yiyong:'异勇', - yiyong_info:'当你受到其他角色造成的渠道为【杀】的伤害后,若你的装备区内有武器牌,则你可以获得此【杀】对应的所有实体牌,然后将这些牌当做【杀】对伤害来源使用(无距离限制)。若其装备区内没有武器牌,则此伤害+1。', - shanxie:'擅械', - shanxie_info:'①出牌阶段限一次,你可从牌堆中获得一张武器牌。若牌堆中没有武器牌,则你改为随机获得一名角色装备区内的一张武器牌。②当其他角色使用【闪】响应你使用的【杀】时,若此【闪】没有点数或点数不大于你攻击范围的二倍,则你令此【闪】无效。', - shanxie_info_old:'①出牌阶段限一次,你可选择一项:⒈从牌堆中获得一张武器牌。⒉获得一名其他角色装备区内的一张武器牌并使用,然后其将一张手牌当做【杀】对你使用。②当其他角色使用【闪】响应你使用的【杀】时,若此【闪】没有点数或点数不大于你攻击范围的二倍,则你令此【闪】无效。', - sunyi:'手杀孙翊', - zaoli:'躁厉', - zaoli_info:'锁定技。①你不能于回合内使用你手牌中不为本回合得到的牌。②当你使用或打出手牌时,你获得一个“厉”(至多4个)。③回合开始时,若你有“厉”,则你移去所有“厉”并弃置任意张牌,然后摸X+Y张牌。若X大于2,你失去1点体力(X为你移去的标记数,Y为你弃置的牌数)。', - sp_gaolan:'手杀高览', - spjungong:'峻攻', - spjungong_info:'出牌阶段,你可失去X+1点体力或弃置X+1张牌,视为对一名其他角色使用【杀】(不计入次数和距离限制,X为你本回合内发动过〖峻攻〗的次数)。若你因此【杀】造成了伤害,则你令此技能失效直到回合结束。', - spdengli:'等力', - spdengli_info:'当你使用【杀】指定目标后,或成为【杀】的目标后,若使用者和目标的体力值相等,则你摸一张牌。', - sp_huaman:'手杀花鬘', - spxiangzhen:'象阵', - spxiangzhen_info:'锁定技。①【南蛮入侵】对你无效。②当有角色使用的【南蛮入侵】结算结束后,若有角色因此牌受到过伤害,则你和使用者各摸一张牌。', - spfangzong:'芳踪', - spfangzong_info:'锁定技。①你不能于回合内使用具有伤害标签的牌指定攻击范围内的角色为目标。②攻击范围内包含你的角色不能使用具有伤害标签的牌指定你为目标。③结束阶段,你将手牌摸至X张(X为场上存活人数且至多为8)。', - spxizhan:'嬉战', - spxizhan_info:'其他角色的回合开始时,你须选择一项:①失去1点体力。②弃置一张牌并令〖芳踪〗于本回合失效,然后若此牌的花色为:♠,其视为使用一张【酒】;♥,你视为使用一张【无中生有】;♣,你视为对其使用【铁索连环】;♦:你视为对其使用火【杀】(无距离限制)。', - sp_cuiyan:'手杀崔琰', - spyajun:'雅俊', - spyajun_info:'①摸牌阶段,你令额定摸牌数+1。②出牌阶段开始时,你可以用一张本回合得到的牌与其他角色拼点。若你赢,则你可将其中一张拼点牌置于牌堆顶。若你没赢,你本回合的手牌上限-1。', - spzundi:'尊嫡', - spzundi_info:'出牌阶段限一次,你可以弃置一张手牌并选择一名角色,然后你进行判定。若结果为:黑色,其摸三张牌;红色,其可以移动场上的一张牌。', - sp_zhangchangpu:'手杀张昌蒲', - spdifei:'抵诽', - spdifei_info:'锁定技。每回合限一次,当你受到伤害后,你摸一张牌或弃置一张手牌,然后展示所有手牌。若此伤害的渠道为没有花色的牌或你的手牌中没有与此牌花色相同的牌,则你回复1点体力。', - spyanjiao:'严教', - spyanjiao_info:'出牌阶段限一次。你可以将手牌中一种花色的所有牌交给一名其他角色,对其造成1点伤害。然后你于自己的下回合开始时摸等量的牌。', - sp_jiangwan:'蒋琬', - spzhenting:'镇庭', - spzhenting_info:'每回合限一次。当你攻击范围内的角色成为【杀】或延时锦囊的目标时,若你不是此牌的使用者且不是此牌的目标,则你可以将此目标改为自己。然后你选择一项:①弃置使用者的一张手牌。②摸一张牌。', - spjincui:'尽瘁', - spjincui_info:'限定技。出牌阶段,你可以和一名其他角色交换位置,然后失去X点体力(X为你的体力值)。', - sp_jiangqing:'蒋钦', - spjianyi:'俭衣', - spjianyi_info:'锁定技。其他角色的回合结束时,若弃牌堆中有于本回合内因弃置而进入弃牌堆的防具牌,则你获得其中一张。', - spshangyi:'尚义', - spshangyi_info:'出牌阶段限一次。你可以弃置一张牌并选择一名其他角色。其观看你的手牌,然后你观看其手牌并获得其中的一张。', - sp_lvfan:'手杀吕范', - sp_lvfan_prefix:'手杀', - spdiaodu:'调度', - spdiaodu_info:'准备阶段,你可令一名角色摸一张牌,然后移动其装备区内的一张牌。', - spdiancai:'典财', - spdiancai_info:'其他角色的结束阶段开始时,你可以令至多X名角色各摸一张牌(X为你本回合失去的手牌数)。', - mbdiaodu:'调度', - mbdiaodu_info:'准备阶段,你可以移动一名角色装备区内的一张牌(不能移动给自己),然后其摸一张牌。', - mbdiancai:'典财', - mbdiancai_info:'其他角色的出牌阶段阶段结束后,若你本阶段失去的牌数不小于你的体力值,则你可将手牌数补至体力上限。', - spyanji:'严纪', - spyanji_info:'出牌阶段开始时,你可以进行“整肃”。', - sp_huangfusong:'手杀皇甫嵩', - spzhengjun:'整军', - spzhengjun_info:'①出牌阶段开始时,你可进行“整肃”。②当你因整肃而摸牌或回复体力后,你可令一名其他角色摸两张牌或回复1点体力。', - spshiji:'势击', - spshiji_info:'当你对其他角色造成属性伤害时,若你的手牌数不为全场唯一最多,则你可以观看其手牌。你令其弃置其中的所有红色牌,然后摸等量的牌。', - sptaoluan:'讨乱', - sptaoluan_info:'每回合限一次。一名角色的判定结果确定时,若结果的花色为♠,则你可以终止导致此判定发生的上级事件。然后选择一项:①获得判定牌对应的实体牌。②视为对判定角色使用一张火【杀】(无距离和次数限制)。', - sp_zhujun:'手杀朱儁', - yangjie:'佯解', - yangjie_info:'出牌阶段限一次,你可以摸一张牌并和一名其他角色A拼点。当你以此法展示你的拼点牌时,你令此牌点数-X(X为你已损失的体力值)。若你没赢,则你可以令另一名其他角色B获得两张拼点牌,然后其视为对A使用一张火【杀】。', - zjjuxiang:'拒降', - zjjuxiang_info:'限定技。一名其他角色脱离濒死状态时,你可以对其造成1点伤害,然后摸X张牌(X为其体力上限且至多为5)。', - xinyangjie:'佯解', - xinyangjie_info:'出牌阶段限一次,你可以与一名其他角色A拼点。若你没赢,则你可以令另一名其他角色B视为对A使用一张火【杀】。', - xinjuxiang:'拒降', - xinjuxiang_info:'限定技,一名其他角色脱离濒死状态时,你可以对其造成1点伤害。', - houfeng:'厚俸', - houfeng_info:'每轮限一次。一名其他角色的出牌阶段开始时,若其在你的攻击范围内,则你可以令其进行“整肃”。然后当其于本回合内因整肃而摸牌或回复体力后,你获得相同的整肃奖励。', - liuba:'手杀刘巴', - duanbi:'锻币', - duanbi_info:'限定技。出牌阶段,若场上所有角色的手牌数之和大于角色数之和的二倍,则你可以令所有其他角色各弃置X张手牌(X为该角色手牌数的一半且向下取整且至多为3)。然后你可选择一名角色,令其随机获得三张以此法被弃置的牌。', - tongduo:'统度', - tongduo_info:'每回合限一次。当你成为其他角色使用牌的唯一目标后,你可令一名角色重铸一张牌。', + sp_wangcan: "手杀王粲", + spqiai: "七哀", + spqiai_info: + "出牌阶段限一次,你可以将一张非基本牌交给一名其他角色。然后其选择一项:①你回复1点体力。②你摸两张牌。", + spshanxi: "善檄", + spshanxi_suoming: "善檄", + spshanxi_info: + "出牌阶段开始时,你可令一名其他角色获得“檄”标记并清除场上已有的其他“檄”标记(若有)。有“檄”标记的角色回复体力时,若其体力值大于0,则其需选择一项:①交给你两张牌。②失去1点体力。", + sp_chenzhen: "陈震", + shameng: "歃盟", + shameng_info: + "出牌阶段限一次,你可弃置两张颜色相同的手牌并选择一名其他角色。其摸两张牌,然后你摸三张牌。", + sp_sunshao: "手杀孙邵", + fubi: "辅弼", + fubi2: "辅弼", + fubi_info: "游戏开始时,你可选择一名其他角色。该角色的手牌上限于你死亡前+3。", + zuici: "罪辞", + zuici_info: "当你进入濒死状态时,你可废除你的一个不为空的装备栏,然后将体力值回复至1点。", + sp_xunchen: "手杀荀谌", + jianzhan: "谏战", + jianzhan_info: + "出牌阶段限一次,你可选择一名其他角色A和其攻击范围内的另一名手牌数小于其的角色B。A选择一项:①视为对B使用一张【杀】。②令你摸一张牌。", + duoji: "夺冀", + duoji_info: + "限定技,出牌阶段,你可弃置两张手牌并选择一名装备区有牌的其他角色。你获得其装备区里的所有牌。", + binglinchengxiax: "兵临城下", + binglinchengxiax_info: + "出牌阶段,对一名其他角色使用。你亮出牌堆顶的四张牌,依次对其使用其中所有的【杀】,然后将剩余的牌置于牌堆顶。", + mjweipo: "危迫", + mjweipo_effect: "危迫", + mjweipo_remove: "危迫", + mjweipo_info: + "出牌阶段限一次。你可以选择一个智囊或【兵临城下】,令一名没有〖危迫〗效果的角色获得如下一次性效果直到你下回合开始:其可于出牌阶段弃置一张【杀】,并获得一张你选择的牌。", + mjchenshi: "陈势", + mjchenshi_player: "陈势", + mjchenshi_target: "陈势", + mjchenshi_info: + "当有角色使用【兵临城下】指定第一个目标后,其可交给你一张牌,并将牌堆的顶三张牌中所有不为【杀】的牌置入弃牌堆;当有角色成为【兵临城下】的目标后,其可交给你一张牌,然后将牌堆顶三张牌中所有的【杀】置入弃牌堆。", + mjmouzhi: "谋识", + mjmouzhi_info: + "锁定技,当你受到伤害时,若伤害渠道对应的牌和你上次受到的伤害花色相同,则你防止此伤害。", + luotong: "手杀骆统", + qinzheng: "勤政", + qinzheng_info: + "锁定技,当你使用或打出牌时,若你本局游戏内使用或打出过的牌数和:为3的倍数,你从牌堆中获得一张【杀】或【闪】;为5的倍数,你从牌堆中获得一张【桃】或【酒】;为8的倍数,你从牌堆中获得一张【决斗】或【无中生有】(可获得对应的衍生替换牌)。", + sp_duyu: "手杀杜预", + spwuku: "武库", + spwuku_info: "锁定技,当有角色使用装备牌时,若你的“武库”数小于3,则你获得一个“武库”。", + spwuku_info_guozhan: + "锁定技,当有其他势力的角色使用装备牌时,若你的“武库”数小于2,则你获得一个“武库”。", + spsanchen: "三陈", + spsanchen_info: + "觉醒技,结束阶段,若你的“武库”数大于2,则你加1点体力上限并回复1点体力,然后获得〖灭吴〗。", + spmiewu: "灭吴", + spmiewu2: "灭吴", + spmiewu_backup: "灭吴", + spmiewu_info: + "每回合限一次。你可弃置一枚“武库”并将一张牌当做任意基本牌或锦囊牌使用,然后摸一张牌。", + sp_bianfuren: "手杀卞夫人", + spwanwei: "挽危", + spwanwei_info: + "每轮累计限一次。①出牌阶段,你可选择一名其他角色。②当有其他角色处于濒死状态时。你可令该角色回复X+1点体力(至少回复至1),然后你失去X点体力。(X为你的体力值)", + spyuejian: "约俭", + spyuejian_info: + "锁定技,你的手牌上限基数等于你的体力上限。当你处于濒死状态时,你可弃置两张牌,然后回复1点体力。", + feiyi: "手杀费祎", + feiyi_prefix: "手杀", + reshengxi: "生息", + reshengxi_info: "结束阶段,若你于本回合内未造成过伤害,则你可摸两张牌。", + fyjianyu: "谏喻", + fyjianyu_info: + "每轮限一次。出牌阶段,你可选择两名角色,令这些角色获得“喻”直到你的下回合开始。当一名有“喻”的角色A使用牌指定另一名有“喻”的角色B为目标时,你令B摸一张牌。", + mjshengxi: "生息", + mjshengxi_info: + "准备阶段,你可以获得一张【调剂盐梅】;结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊或摸一张牌。", + mjkuanji: "宽济", + mjkuanji_info: + "每回合限一次。当你因弃置而失去牌后,你可令一名其他角色获得其中的一张牌,然后你摸一张牌。", + tiaojiyanmei: "调剂盐梅", + tiaojiyanmei_info: + "出牌阶段,对两名手牌数不均相同的其他角色使用。若目标角色于此牌使用准备工作结束时的手牌数大于此时所有目标的平均手牌数,其弃置一张牌。若小于则其摸一张牌。此牌使用结束后,若所有目标角色的手牌数均相等,则你可令一名角色获得所有因执行此牌效果而弃置的牌。", + refubi: "辅弼", + refubi_info: + "游戏开始时,你可令一名其他角色获得“辅弼”标记。有“辅弼”标记的角色的准备阶段开始时,你可选择一项:①令其本回合使用【杀】的次数上限+1。②令其本回合的手牌上限+3。", + rezuici: "罪辞", + rezuici_backup: "罪辞", + rezuici_info: + "出牌阶段,或当你处于濒死状态时,你可以废除一个有牌的装备栏并回复2点体力,然后可以移动“辅弼”标记。", + mjdingyi: "定仪", + mjdingyi_info: + "游戏开始时,你选择一个效果(相同效果不可叠加)并令全场角色获得之:①摸牌阶段额定摸牌数+1。②手牌上限+2。③攻击范围+1。④脱离濒死状态时回复1点体力。", + mjzuici: "罪辞", + mjzuici_info: + "当你受到伤害后,你可令伤害来源失去〖定仪〗效果,然后令其从牌堆中获得一张由你选择的智囊。", + mjfubi: "辅弼", + mjfubi_info: + "每轮限一次。出牌阶段,你可选择一项:①更换一名角色的〖定仪〗效果。②弃置一张牌并令一名角色的〖定仪〗效果翻倍直到你的下回合开始。", + wujing: "吴景", + heji: "合击", + heji_info: + "当有角色使用的【决斗】或红色【杀】结算完成后,若此牌对应的目标数为1,则你可以对相同的目标使用一张【杀】或【决斗】(无距离和次数限制)。若你以此法使用的牌不为转化牌,则你从牌堆中随机获得一张红色牌。", + liubing: "流兵", + liubing_info: + "锁定技。①你于出牌阶段使用的第一张非虚拟【杀】的花色视为♦。②其他角色于其出牌阶段内使用的非转化黑色杀结算结束后,若此【杀】未造成伤害,则你获得之。", + sp_mifuren: "手杀糜夫人", + spcunsi: "存嗣", + spcunsi2: "存嗣", + spcunsi_info: + "出牌阶段限一次,你可将武将牌翻至背面并选择一名其他角色。其从牌堆或弃牌堆中获得一张【杀】,且下一张杀的伤害值基数+1。", + spguixiu: "闺秀", + spguixiu_info: + "锁定技,当你受到伤害后,若你的武将牌背面朝上,则你将武将牌翻至正面。当你的武将牌从背面翻至正面时,你摸一张牌。", + qingyu: "清玉", + qingyu_info: + "使命技。①当你受到伤害时,你弃置两张牌,然后防止此伤害。②使命:准备阶段,若你的体力值等于体力上限且你没有手牌,则你获得〖悬存〗。③失败:当你进入濒死状态时,你减1点体力上限。", + xuancun: "悬存", + xuancun_info: + "其他角色的回合结束时,若你的手牌数小于体力值,则你可以令其摸X张牌(X为你的体力值与手牌数之差且至多为2)。", + xinlirang: "礼让", + xinlirang_info: + "①其他角色的摸牌阶段开始时,若你没有“谦”标记,则你可以获得一枚“谦”标记。若如此做,其额定摸牌数+2,且本回合的弃牌阶段开始时,你可以获得其弃置的至多两张牌。②摸牌阶段开始时,若你有“谦”标记,则你跳过此摸牌阶段并移除“谦”标记。", + xinmingshi: "名仕", + xinmingshi_info: + "锁定技,当你受到伤害后,若你有“谦”标记,则伤害来源弃置一张牌。若此牌为:黑色:你获得之。红色,你回复1点体力。", + sp_xinpi: "手杀辛毗", + spyinju: "引裾", + spyinju2: "引裾", + spyinju_info: + "出牌阶段限一次,你可令一名其他角色选择一项:①对你使用一张【杀】(无距离限制)。②其下个回合的准备阶段开始时,跳过出牌阶段和弃牌阶段。", + spchijie: "持节", + spchijie_info: + "每回合限一次。当你成为其他角色使用牌的唯一目标时,你可判定。若结果大于6,则你取消此牌的所有目标。", + reduoji: "夺冀", + reduoji_info: + "出牌阶段限一次,你可将一张牌置于其他角色的武将牌上,称为“冀”。当有装备牌因使用而进入一名角色的装备区后,若该角色有“冀”且其为使用者,则你获得此装备牌,其移去一个“冀”并摸一张牌。一名其他角色的回合结束后,若其有“冀”,则你获得其的所有“冀”。", + wangling: "手杀王淩", + wangling_prefix: "手杀", + mouli: "谋立", + mouli_info: + "出牌阶段限一次,你可以将一张手牌交给一名其他角色,其获得如下效果直到你的下回合开始:其可以将黑色牌当做【杀】,红色牌当做【闪】使用。其第一次触发“使用【杀】/【闪】结算完成后”的时机时,你摸三张牌。", + zifu: "自缚", + zifu_info: "锁定技,当有角色死亡时,若其因你获得的“谋立”效果未过期,则你减2点体力上限。", + xingqi: "星启", + xingqi_info: + "①当你使用牌时,若此牌不为延时锦囊牌且你没有同名的“备”,则你获得一枚与此牌名称相同的“备”。②结束阶段,你可移去一枚“备”,然后从牌堆中获得一张与此“备”名称相同的牌。", + xinzifu: "自缚", + xinzifu_info: + "锁定技。出牌阶段结束时,若你本阶段内未使用牌,则你移去所有“备”且本回合的手牌上限-1。", + mibei: "秘备", + mibei_info: + "使命技。①使命:当你使用的牌结算完成后,若你的“备”中包含的基本牌,锦囊牌,装备牌数量均大于1,则你从牌堆中获得这三种类型的牌各一张并获得技能“谋立”。②失败:结束阶段开始时,若你没有“备”,且你于本回合的准备阶段开始时也没有“备”,则你减1点体力上限。", + xinmouli: "谋立", + xinmouli_info: + "出牌阶段限一次,你可以指定一名其他角色。其移去你的一个“备”,然后从牌堆中获得一张与此“备”名称相同的牌。", + wangfuzhaolei: "王甫赵累", + xunyi: "殉义", + xunyi2: "殉义", + xunyi3: "殉义", + xunyi_info: + "游戏开始时,或当上一个拥有“殉义”效果的角色死亡后,你可以选择一名角色获得如下效果:当其/你对二者之外的角色造成伤害后,你/其摸一张牌;当其/你受到二者之外的角色造成的伤害后,你/其弃置一张牌。", + zhouchu: "手杀周处", + xianghai: "乡害", + xianghai_info: "锁定技,其他角色的手牌上限-1。你手牌区的装备牌均视为【酒】。", + chuhai: "除害", + chuhai_info: + "出牌阶段限一次,你可以摸一张牌,然后和一名其他角色拼点。若你赢,则你观看其手牌,并从牌堆/弃牌堆中获得其手牌中包含的类型的牌各一张,且当你于此阶段内对其造成伤害后,你将牌堆/弃牌堆中的一张装备牌置于你的一个空置装备栏内。", + rechuhai: "除害", + rechuhai_info: + "使命技。①出牌阶段限一次,你可以摸一张牌,然后和一名其他角色拼点。若你赢,则你观看其手牌,并从牌堆/弃牌堆中获得其手牌中包含的类型的牌各一张,且当你于此阶段内对其造成伤害后,你将牌堆/弃牌堆中的一张装备牌置于你的一个空置装备栏内。②当你因发动〖除害①〗而展示拼点牌时,你令此牌的点数+X(X=(4-你装备区的牌数))。③使命:当有装备牌进入你的装备区后,若你的装备区内有至少三张牌,则你将体力值回复至上限,失去〖乡害〗并获得〖彰名〗。④失败:当你因发动〖除害①〗发起的拼点没赢时,若你的最终点数不大于6,则你触发使命失败分支。", + zhangming: "彰名", + zhangming_info: + "锁定技。①你使用的♣牌不能被其他角色响应。②每回合限一次,当你对其他角色造成伤害后,你随机弃置其一张手牌,然后你从牌堆或弃牌堆中获得与其展示牌类型不同类型的牌各一张(若其没有手牌,则你改为从牌堆或弃牌堆中获得所有类型牌各一张),且以此法得到的牌不计入本回合的手牌上限。", + sp_kongrong: "手杀孔融", + spmingshi: "名士", + spmingshi_info: "锁定技,当你受到1点伤害后,伤害来源弃置一张牌。", + splirang: "礼让", + splirang_info: + "出牌阶段限一次,你可以弃置所有手牌,然后将其中的至多X张牌交给一名其他角色(X为你的体力值),之后摸一张牌。", + caizhenji: "蔡贞姬", + sheyi: "舍裔", + sheyi_info: + "每轮限一次。当有体力值小于你的其他角色受到伤害时,你可以交给其至少X张牌并防止此伤害(X为你的体力值)。", + tianyin: "天音", + tianyin_info: "锁定技,结束阶段开始时,你从牌堆中获得每种本回合未使用过的类型的牌各一张。", + xiangchong: "向宠", + guying: "固营", + guying_info: + "锁定技。每回合限一次,当你于回合外因使用/打出/弃置而失去牌后,若牌数为1,则你获得一枚“固”并令当前回合角色选择一项:①随机交给你一张牌。②令你获得本次失去的牌,若为装备牌,则你使用之。准备阶段开始时,你移去所有“固”并弃置等量的牌。", + muzhen: "睦阵", + muzhen_backup: "睦阵", + muzhen_info: + "出牌阶段各限一次。①你可以将两张牌交给一名装备区内有牌的其他角色,然后获得其装备区内的一张牌。②你可以将装备区内的一张牌置于其他角色的装备区内,然后获得其一张手牌。", + sp_huaxin: "手杀华歆", + hxrenshi: "仁仕", + hxrenshi_info: "出牌阶段每名角色限一次。你可以将一张手牌交给一名其他角色。", + debao: "德保", + debao_info: + "锁定技,当其他角色获得你的牌后,若你的“仁”数小于你的体力上限,则你将牌堆顶的一张牌置于你的武将牌上,称为“仁”。准备阶段,你获得所有“仁”。", + buqi: "不弃", + buqi_info: + "锁定技,当有角色进入濒死状态时,若你的“仁”数大于1,则你移去两张“仁”并令其回复1点体力。一名角色死亡后,你将所有“仁”置入弃牌堆。", + yuanqing: "渊清", + yuanqing_info: + "锁定技,出牌阶段结束时,你随机将弃牌堆中你本阶段使用过的牌类型的各一张牌置于仁库中。", + shuchen: "疏陈", + shuchen_info: + "锁定技,当有角色进入濒死状态时,若仁库中的牌数大于三,则你获得仁库中的所有牌,然后其回复1点体力。", + sp_xujing: "手杀许靖", + boming: "博名", + boming_info: + "出牌阶段限两次,你可以将一张牌交给一名其他角色。结束阶段,若你本回合以此法失去了两张以上的牌,则你摸一张牌。", + ejian: "恶荐", + ejian_info: + "锁定技,每名角色限一次。当有其他角色因〖博名〗而得到了你的牌后,若其拥有与此牌类型相同的其他牌,则你令其选择一项:①受到1点伤害。②展示所有手牌,并弃置所有与此牌类别相同的牌。", + zhangzhongjing: "张机", + jishi: "济世", + jishi_info: + "锁定技。①当你使用的牌结算完成后,若你未因此牌造成过伤害,则你将此牌对应的所有实体牌置于仁库中。②当有牌不因溢出而离开仁库时,你摸一张牌。", + liaoyi: "疗疫", + liaoyi_info: + "其他角色的回合开始时,若其:①手牌数小于体力值且仁库内牌数大于等于X,则你可令其从仁库中获得X张牌;②手牌数大于体力值,则你可以令其将X张牌置于仁库中(X为其手牌数与体力值之差且至多为4)。", + xinliaoyi: "疗疫", + xinliaoyi_info: + "其他角色的回合开始时,你可选择一项:①令其从仁库中获得一张牌。②若其手牌数大于体力值,则令其将X张手牌置入仁库(X为其手牌数与体力值之差)。", + binglun: "病论", + binglun_info: + "出牌阶段限一次,你可以将仁库中的一张牌置于弃牌堆并选择一名角色。该角色选择一项:①摸一张牌。②于其下回合结束时回复1点体力。", + sp_zhangwen: "手杀张温", + gebo: "戈帛", + gebo_info: "锁定技,当有角色回复体力后,你将牌堆顶的一张牌置入仁库。", + spsongshu: "颂蜀", + spsongshu_info: + "其他角色的摸牌阶段开始时,若其体力值大于你且仁库内有牌,则你可以令其放弃摸牌。其改为获得X张仁(X为你的体力值且至多为5),且本回合内不能使用牌指定其他角色为目标。", + liuzhang: "刘璋", + xiusheng: "休生", + xiusheng_info: + "锁定技。准备阶段,你将所有“生”置入弃牌堆,然后摸X张牌,并将等量的牌置于武将牌上,称为“生”(X为你因〖引狼〗而选择的势力的存活角色数)。", + yinlang: "引狼", + yinlang_info: + "①每轮限一次。回合开始时,你选择场上的一个势力。②一名角色的出牌阶段开始时,若其势力与你选择的势力相同,则其选择一项:1.获得你的一张“生”,然后其本回合使用牌时不能指定你以外的角色为目标。2.你获得一张“生”。", + huaibi: "怀璧", + huaibi_info: "主公技,锁定技。你的手牌上限+X(X为你因〖引狼〗而选择的势力的存活角色数)。", + jutu: "据土", + jutu_info: + "锁定技,准备阶段,你获得所有你武将牌上的“生”,然后摸X+1张牌,然后将X张牌置于你的武将牌上,称为“生”(X为你因〖邀虎〗选择势力的角色数量)。", + yaohu: "邀虎", + yaohu_info: + "每轮限一次,你的回合开始时,你须选择场上一个势力。该势力其他角色的出牌阶段开始时,其获得你的一张“生”,然后其须选择一项:①对你指定的另一名的其他角色使用一张【杀】(无距离和次数限制);②交给你两张牌。", + rehuaibi: "怀璧", + rehuaibi_info: "主公技,锁定技,你的手牌上限+X(X为你因〖邀虎〗选择势力的角色数量)。", + qiaogong: "桥公", + yizhu: "遗珠", + yizhu_info: + "①结束阶段,你摸两张牌,然后将两张牌随机插入牌堆前2X张牌的位置中(X为角色数,选择牌的牌名对其他角色可见)。②其他角色使用“遗珠”牌指定唯一目标时,你可以取消此目标,然后你清除对应的“遗珠”标记。", + luanchou: "鸾俦", + luanchou_info: + "出牌阶段限一次,你可令两名角色获得“姻”标记并清除原有标记。拥有“姻”标记的角色视为拥有技能〖共患〗。", + gonghuan: "共患", + gonghuan_info: + "锁定技。每回合限一次,一名其他角色受到伤害时,若其拥有“姻”标记且其体力值小于你,则你将伤害转移给自己。此伤害结算结束后,你与其移去“姻”标记。", + sp_yanghu: "手杀羊祜", + mingfa: "明伐", + mingfa_info: + "①结束阶段,你可展示一张牌并记录为“明伐”。②出牌阶段开始时,若“明伐”牌在你的手牌区或装备区,则你可以使用“明伐”牌与一名其他角色拼点。若你赢:你获得对方一张牌并从牌堆中获得一张点数等于“明伐”牌牌面点数-1的牌。若你没赢:你本回合不能使用牌指定其他角色为目标。③你的拼点牌亮出后,你令此牌的点数+2。", + rongbei: "戎备", + rongbei_info: + "限定技。出牌阶段,你可选择一名有空装备栏的角色。系统为该角色的每个空装备栏选择一张装备牌,然后该角色使用之。", + db_wenyang: "手杀文鸯", + dbquedi: "却敌", + dbquedi_info: + "每回合限一次。当你使用【杀】或【决斗】指定唯一目标后,你可选择:①获得目标角色的一张手牌。②弃置一张基本牌,并令此牌的伤害值基数+1。③背水:减1点体力上限,然后依次执行上述所有选项。", + dbzhuifeng: "椎锋", + dbzhuifeng_info: + "魏势力技。每回合限两次,你可以失去1点体力并视为使用一张【决斗】(你死亡后仍然结算)。当你因此【决斗】而受到伤害时,你防止此伤害并令此技能失效直到出牌阶段结束。", + dbchongjian: "冲坚", + dbchongjian_backup: "冲坚", + dbchongjian_info: + "吴势力技。你可以将一张装备牌当做一种【杀】(无距离限制且无视防具)或【酒】使用。当你以此法使用【杀】造成伤害后,你获得目标角色装备区内的X张牌(X为伤害值)。", + dbchoujue: "仇决", + dbchoujue_info: + "锁定技。当你杀死其他角色后,你加1点体力上限并摸两张牌,然后本回合发动【却敌】的次数上限+1。", + sp_chendong: "手杀陈武董袭", + sp_chendong_prefix: "手杀", + spyilie: "毅烈", + spyilie_info: + "出牌阶段开始时,你可选择:①本阶段内使用【杀】的次数上限+1。②本回合内使用【杀】被【闪】抵消时,摸一张牌。③背水:失去1点体力,然后依次执行上述所有选项。", + spfenming: "奋命", + spfenming_info: + "出牌阶段限一次,你可以选择一名体力值不大于你的角色。若其:未横置,其横置;已横置,你获得其一张牌。", + yuanhuan: "袁涣", + qingjue: "请决", + qingjue_info: + "每轮限一次。当有其他角色A使用牌指定另一名体力值小于A且不处于濒死状态的其他角色B为目标时,你可以摸一张牌,然后与A拼点。若你赢,你取消此目标。若你没赢,你将此牌的目标改为自己。", + fengjie: "奉节", + fengjie2: "奉节", + fengjie_info: + "锁定技,准备阶段开始时,你选择一名其他角色并获得如下效果直到你下回合开始:一名角色的结束阶段开始时,你将手牌摸至(至多摸四张)或弃置至与其体力值相等。", + sp_zongyu: "手杀宗预", + zhibian: "直辩", + zhibian_info: + "准备阶段,你可以和一名其他角色拼点。若你赢,你可选择:①将其装备区/判定区内的一张牌移动到你的对应区域。②回复1点体力。③背水:跳过下个摸牌阶段,然后依次执行上述所有选项;若你没赢,你失去1点体力。", + yuyan: "御严", + yuyan_info: + "锁定技。当你成为非转换的【杀】的目标时,若使用者的体力值大于你且此【杀】有点数,则你令使用者选择一项:①交给你一张点数大于此【杀】的牌。②取消此目标。", + sp_wangshuang: "手杀王双", + yiyong: "异勇", + yiyong_info: + "当你受到其他角色造成的渠道为【杀】的伤害后,若你的装备区内有武器牌,则你可以获得此【杀】对应的所有实体牌,然后将这些牌当做【杀】对伤害来源使用(无距离限制)。若其装备区内没有武器牌,则此伤害+1。", + shanxie: "擅械", + shanxie_info: + "①出牌阶段限一次,你可从牌堆中获得一张武器牌。若牌堆中没有武器牌,则你改为随机获得一名角色装备区内的一张武器牌。②当其他角色使用【闪】响应你使用的【杀】时,若此【闪】没有点数或点数不大于你攻击范围的二倍,则你令此【闪】无效。", + shanxie_info_old: + "①出牌阶段限一次,你可选择一项:⒈从牌堆中获得一张武器牌。⒉获得一名其他角色装备区内的一张武器牌并使用,然后其将一张手牌当做【杀】对你使用。②当其他角色使用【闪】响应你使用的【杀】时,若此【闪】没有点数或点数不大于你攻击范围的二倍,则你令此【闪】无效。", + sunyi: "手杀孙翊", + zaoli: "躁厉", + zaoli_info: + "锁定技。①你不能于回合内使用或打出你手牌中不为本回合得到的牌。②当你使用或打出手牌时,你获得一个“厉”(至多4个)。③回合开始时,若你有“厉”,则你移去所有“厉”并弃置任意张牌,然后摸X+Y张牌。若X大于2,你失去1点体力(X为你移去的标记数,Y为你弃置的牌数)。", + sp_gaolan: "手杀高览", + spjungong: "峻攻", + spjungong_info: + "出牌阶段,你可失去X+1点体力或弃置X+1张牌,视为对一名其他角色使用【杀】(不计入次数和距离限制,X为你本回合内发动过〖峻攻〗的次数)。若你因此【杀】造成了伤害,则你令此技能失效直到回合结束。", + spdengli: "等力", + spdengli_info: + "当你使用【杀】指定目标后,或成为【杀】的目标后,若使用者和目标的体力值相等,则你摸一张牌。", + sp_huaman: "手杀花鬘", + spxiangzhen: "象阵", + spxiangzhen_info: + "锁定技。①【南蛮入侵】对你无效。②当有角色使用的【南蛮入侵】结算结束后,若有角色因此牌受到过伤害,则你和使用者各摸一张牌。", + spfangzong: "芳踪", + spfangzong_info: + "锁定技。①你不能于回合内使用具有伤害标签的牌指定攻击范围内的角色为目标。②攻击范围内包含你的角色不能使用具有伤害标签的牌指定你为目标。③结束阶段,你将手牌摸至X张(X为场上存活人数且至多为8)。", + spxizhan: "嬉战", + spxizhan_info: + "其他角色的回合开始时,你须选择一项:①失去1点体力。②弃置一张牌并令〖芳踪〗于本回合失效,然后若此牌的花色为:♠,其视为使用一张【酒】;♥,你视为使用一张【无中生有】;♣,你视为对其使用【铁索连环】;♦:你视为对其使用火【杀】(无距离限制)。", + sp_cuiyan: "手杀崔琰", + spyajun: "雅俊", + spyajun_info: + "①摸牌阶段,你令额定摸牌数+1。②出牌阶段开始时,你可以用一张本回合得到的牌与其他角色拼点。若你赢,则你可将其中一张拼点牌置于牌堆顶。若你没赢,你本回合的手牌上限-1。", + spzundi: "尊嫡", + spzundi_info: + "出牌阶段限一次,你可以弃置一张手牌并选择一名角色,然后你进行判定。若结果为:黑色,其摸三张牌;红色,其可以移动场上的一张牌。", + sp_zhangchangpu: "手杀张昌蒲", + spdifei: "抵诽", + spdifei_info: + "锁定技。每回合限一次,当你受到伤害后,你摸一张牌或弃置一张手牌,然后展示所有手牌。若此伤害的渠道为没有花色的牌或你的手牌中没有与此牌花色相同的牌,则你回复1点体力。", + spyanjiao: "严教", + spyanjiao_info: + "出牌阶段限一次。你可以将手牌中一种花色的所有牌交给一名其他角色,对其造成1点伤害。然后你于自己的下回合开始时摸等量的牌。", + sp_jiangwan: "蒋琬", + spzhenting: "镇庭", + spzhenting_info: + "每回合限一次。当你攻击范围内的角色成为【杀】或延时锦囊的目标时,若你不是此牌的使用者且不是此牌的目标,则你可以将此目标改为自己。然后你选择一项:①弃置使用者的一张手牌。②摸一张牌。", + spjincui: "尽瘁", + spjincui_info: + "限定技。出牌阶段,你可以和一名其他角色交换位置,然后失去X点体力(X为你的体力值)。", + sp_jiangqing: "蒋钦", + spjianyi: "俭衣", + spjianyi_info: + "锁定技。其他角色的回合结束时,若弃牌堆中有于本回合内因弃置而进入弃牌堆的防具牌,则你获得其中一张。", + spshangyi: "尚义", + spshangyi_info: + "出牌阶段限一次。你可以弃置一张牌并选择一名其他角色。其观看你的手牌,然后你观看其手牌并获得其中的一张。", + sp_lvfan: "手杀吕范", + sp_lvfan_prefix: "手杀", + spdiaodu: "调度", + spdiaodu_info: "准备阶段,你可令一名角色摸一张牌,然后移动其装备区内的一张牌。", + spdiancai: "典财", + spdiancai_info: + "其他角色的结束阶段开始时,你可以令至多X名角色各摸一张牌(X为你本回合失去的手牌数)。", + mbdiaodu: "调度", + mbdiaodu_info: "准备阶段,你可以移动一名角色装备区内的一张牌(不能移动给自己),然后其摸一张牌。", + mbdiancai: "典财", + mbdiancai_info: + "其他角色的出牌阶段阶段结束后,若你本阶段失去的牌数不小于你的体力值,则你可将手牌数补至体力上限。", + spyanji: "严纪", + spyanji_info: "出牌阶段开始时,你可以进行“整肃”。", + sp_huangfusong: "手杀皇甫嵩", + spzhengjun: "整军", + spzhengjun_info: + "①出牌阶段开始时,你可进行“整肃”。②当你因整肃而摸牌或回复体力后,你可令一名其他角色摸两张牌或回复1点体力。", + spshiji: "势击", + spshiji_info: + "当你对其他角色造成属性伤害时,若你的手牌数不为全场唯一最多,则你可以观看其手牌。你令其弃置其中的所有红色牌,然后摸等量的牌。", + sptaoluan: "讨乱", + sptaoluan_info: + "每回合限一次。一名角色的判定结果确定时,若结果的花色为♠,则你可以终止导致此判定发生的上级事件。然后选择一项:①获得判定牌对应的实体牌。②视为对判定角色使用一张火【杀】(无距离和次数限制)。", + sp_zhujun: "手杀朱儁", + yangjie: "佯解", + yangjie_info: + "出牌阶段限一次,你可以摸一张牌并和一名其他角色A拼点。当你以此法展示你的拼点牌时,你令此牌点数-X(X为你已损失的体力值)。若你没赢,则你可以令另一名其他角色B获得两张拼点牌,然后其视为对A使用一张火【杀】。", + zjjuxiang: "拒降", + zjjuxiang_info: + "限定技。一名其他角色脱离濒死状态时,你可以对其造成1点伤害,然后摸X张牌(X为其体力上限且至多为5)。", + xinyangjie: "佯解", + xinyangjie_info: + "出牌阶段限一次,你可以与一名其他角色A拼点。若你没赢,则你可以令另一名其他角色B视为对A使用一张火【杀】。", + xinjuxiang: "拒降", + xinjuxiang_info: "限定技,一名其他角色脱离濒死状态时,你可以对其造成1点伤害。", + houfeng: "厚俸", + houfeng_info: + "每轮限一次。一名其他角色的出牌阶段开始时,若其在你的攻击范围内,则你可以令其进行“整肃”。然后当其于本回合内因整肃而摸牌或回复体力后,你获得相同的整肃奖励。", + liuba: "手杀刘巴", + duanbi: "锻币", + duanbi_info: + "限定技。出牌阶段,若场上所有角色的手牌数之和大于角色数之和的二倍,则你可以令所有其他角色各弃置X张手牌(X为该角色手牌数的一半且向下取整且至多为3)。然后你可选择一名角色,令其随机获得三张以此法被弃置的牌。", + tongduo: "统度", + tongduo_info: "每回合限一次。当你成为其他角色使用牌的唯一目标后,你可令一名角色重铸一张牌。", - mobile_shijiren:'始计篇·仁', - mobile_shijizhi:'始计篇·智', - mobile_shijixin:'始计篇·信', - mobile_shijiyong:'始计篇·勇', - mobile_shijiyan:'始计篇·严', - } + mobile_shijiren: "始计篇·仁", + mobile_shijizhi: "始计篇·智", + mobile_shijixin: "始计篇·信", + mobile_shijiyong: "始计篇·勇", + mobile_shijiyan: "始计篇·严", + }, }; }); diff --git a/character/sp.js b/character/sp.js index 7e2d0ef3a..8b9ace269 100755 --- a/character/sp.js +++ b/character/sp.js @@ -1,1367 +1,2141 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'sp', - connect:true, - characterSort:{ - sp:{ - sp_tianji:["sunhao","liuxie","caoang","hetaihou","sunluyu",'ol_wangrong',"zuofen","ol_bianfuren","qinghegongzhu","tengfanglan","ruiji",'caoxiancaohua'], - sp_sibi:['ol_lukai',"yangxiu",'guotu',"chenlin","chengyu","shixie","fuwan","wangyun","zhugejin","simalang","maliang","buzhi","dongyun","kanze","sunqian","xizhicai","sunshao",'duxi',"jianggan",'ol_dengzhi','ol_yangyi','ol_dongzhao','ol_chendeng','jin_yanghu','wangyan','xiahouxuan','quhuang','zhanghua','wangguan','sunhong','caoxi','tianchou'], - sp_tianzhu:['liyi','zhangyan','niujin','hejin','hansui',"wutugu","yanbaihu","shamoke","zhugedan",'huangzu','gaogan',"tadun","fanjiangzhangda","ahuinan","dongtuna",'ol_wenqin'], - sp_nvshi:['ol_dingshangwan',"lingju","guanyinping","zhangxingcai","mayunlu","dongbai","zhaoxiang",'ol_zhangchangpu',"daxiaoqiao","jin_guohuai",'ol_hujinding'], - sp_shaowei:["simahui","zhangbao","zhanglu","zhugeguo","xujing","zhangling",'huangchengyan','zhangzhi','lushi'], - sp_huben:['duanjiong','ol_mengda',"caohong","xiahouba","zhugeke","zumao","wenpin","litong","mazhong","heqi","quyi","luzhi","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:['lvboshe','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_qifu:['ol_feiyi',"caoying",'panshu',"caochun","yuantanyuanshang",'caoshuang','wolongfengchu','guansuo','baosanniang','fengfangnv','jin_zhouchu'], - sp_wanglang:['ol_wanglang','ol_puyuan','ol_zhouqun'], - sp_zhongdan:["cuiyan","huangfusong"], - sp_guozhan2:["sp_dongzhuo","liqueguosi","zhangren"], - sp_others:["hanba","caiyang"], - sp_waitforsort:['ol_luyusheng','ol_pengyang','ol_tw_zhangji','ol_liwan','ol_liuyan','caoyu','liupan','ol_liupi'], + name: "sp", + connect: true, + characterSort: { + sp: { + sp_tianji: [ + "sunhao", + "liuxie", + "caoang", + "hetaihou", + "sunluyu", + "ol_wangrong", + "zuofen", + "ol_bianfuren", + "qinghegongzhu", + "tengfanglan", + "ruiji", + "caoxiancaohua", + "caoyu", + ], + sp_sibi: [ + "ol_lukai", + "yangxiu", + "guotu", + "chenlin", + "chengyu", + "shixie", + "fuwan", + "wangyun", + "zhugejin", + "simalang", + "maliang", + "buzhi", + "dongyun", + "kanze", + "sunqian", + "xizhicai", + "sunshao", + "duxi", + "jianggan", + "ol_dengzhi", + "ol_yangyi", + "ol_dongzhao", + "ol_chendeng", + "jin_yanghu", + "wangyan", + "xiahouxuan", + "quhuang", + "zhanghua", + "wangguan", + "sunhong", + "caoxi", + "tianchou", + ], + sp_tianzhu: [ + "liyi", + "zhangyan", + "niujin", + "hejin", + "hansui", + "wutugu", + "yanbaihu", + "shamoke", + "zhugedan", + "huangzu", + "gaogan", + "tadun", + "fanjiangzhangda", + "ahuinan", + "dongtuna", + "ol_wenqin", + ], + sp_nvshi: [ + "ol_dingshangwan", + "lingju", + "guanyinping", + "zhangxingcai", + "mayunlu", + "dongbai", + "zhaoxiang", + "ol_zhangchangpu", + "daxiaoqiao", + "jin_guohuai", + "ol_hujinding", + ], + sp_shaowei: [ + "simahui", + "zhangbao", + "zhanglu", + "zhugeguo", + "xujing", + "zhangling", + "huangchengyan", + "zhangzhi", + "lushi", + ], + sp_huben: [ + "duanjiong", + "ol_mengda", + "caohong", + "xiahouba", + "zhugeke", + "zumao", + "wenpin", + "litong", + "mazhong", + "heqi", + "quyi", + "luzhi", + "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: ["lvboshe", "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_sunce", + ], + sp_qifu: [ + "ol_feiyi", + "caoying", + "panshu", + "caochun", + "yuantanyuanshang", + "caoshuang", + "wolongfengchu", + "guansuo", + "baosanniang", + "fengfangnv", + "jin_zhouchu", + ], + sp_wanglang: ["ol_wanglang", "ol_puyuan", "ol_zhouqun"], + sp_zhongdan: ["cuiyan", "huangfusong"], + sp_guozhan2: ["sp_dongzhuo", "liqueguosi", "zhangren"], + sp_others: ["hanba", "caiyang"], + sp_waitforsort: [ + "ol_luyusheng", + "ol_pengyang", + "ol_tw_zhangji", + "ol_liwan", + "ol_liuyan", + "liupan", + "ol_liupi", + ], }, }, - characterFilter:{ - tianyu:function(mode){ - return mode!='chess'&&mode!='tafang'&&mode!='stone'; + characterFilter: { + tianyu: function (mode) { + return mode != "chess" && mode != "tafang" && mode != "stone"; }, - ol_dongzhao:function(mode){ - return mode=='identity'&&['normal','zhong'].includes(_status.mode); + ol_dongzhao: function (mode) { + return mode == "identity" && ["normal", "zhong"].includes(_status.mode); + }, + ol_mengda(mode) { + return mode !== "guozhan"; + }, + ol_mengda(mode) { + return mode !== "guozhan"; }, }, - character:{ - ol_liupi:['male','qun',4,['olyicheng']], - ol_lukai:['male','wu',3,['olxuanzhu','oljiane']], - liupan:['male','qun',4,['olpijing']], - guotu:['male','qun',3,['olqushi','olweijie']], - ol_hujinding:['female','shu',3,['olqingyuan','olchongshen']], - tianchou:['male','qun',4,['olshandao']], - liyi:['male','wu',4,['olchanshuang','olzhanjin']], - caoyu:['male','wei',3,['olgongjie','olxiangxv','olxiangzuo']], - ol_liwan:['female','wei',3,['ollianju','olsilv']], - 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,['yanru','hezhong']], - lvboshe:['male','qun',4,['olfushi','oldongdao']], - ol_luyusheng:['female','wu',3,['olcangxin','olrunwei']], - caoxi:['male','wei',3,['olgangshu','oljianxuan']], - ol_pengyang:['male','shu',3,['olxiaofan','oltuishi','nzry_cunmu']], - ol_qianzhao:['male','wei',4,['olweifu','olkuansai']], - niujin:['male','wei',4,['olcuorui','liewei']], - hejin:['male','qun',4,['mouzhu','olyanhuo']], - hansui:['male','qun',4,['olniluan','olxiaoxi']], - duanjiong:['male','qun',4,['olsaogu']], - ol_zhouqun:['male','shu',4,['oltianhou','olchenshuo']], - ol_wenqin:['male','wei',4,['olguangao','olhuiqi']], - haopu:['male','shu',4,['olzhenying']], - ol_mengda:['male','shu',4,['olgoude']], - ol_wanglang:['male','wei',3,['gushe','oljici']], - ol_liuyan:['male','qun','4/6',['olpianan','olyinji','olkuisi']], - lushi:['female','qun',3,['olzhuyan','olleijie']], - zhangshiping:['male','shu',3,['olhongji','olxinggu']], - sunhong:['male','wu',3,['olxianbi','olzenrun']], - luoxian:['male','shu',4,['oldaili']], - ol_huban:['male','wei',4,['olhuiyun']], - wangguan:['male','wei',3,['olmiuyan','olshilu']], - ol_zhangyì:['male','shu',4,['oldianjun','olkangrui']], - ol_zhujun:['male','qun',4,['olcuipo']], - maxiumatie:['male','qun',4,['mashu','rekenshang']], - dongtuna:['male','qun',4,['oljianman']], - zhanghua:['male','jin',3,['olbihun','oljianhe','olchuanwu']], - quhuang:['male','wu',3,['olqiejian','olnishou']], - macheng:['male','shu',4,['mashu','olchenglie']], - zhangzhi:['male','qun',3,['olbixin','olximo']], - ol_liuba:['male','shu',3,['oltongduo','olzhubi']], - ol_furong:['male','shu',4,['olxiaosi']], - ahuinan:['male','qun',4,['jueman']], - jin_guohuai:['female','jin',3,['zhefu','yidu']], - xiahouxuan:['male','wei',3,['olhuanfu','olqingyi','olzeyue']], - dengzhong:['male','wei',4,['dzkanpo','dzgengzhan']], - wangyan:['male','jin',3,['yangkuang','cihuang','sanku']], - huojun:['male','shu',4,['qiongshou','fenrui']], - caoxiancaohua:['female','qun',3,['huamu','qianmeng','liangyuan','jisi']], - jin_zhouchu:['male','jin',4,['shanduan','yilie']], - zhaoyǎn:['male','wei',4,['tongxie']], - ol_puyuan:['male','shu',4,['olshengong','olqisi']], - ruiji:['female','wu',3,['qiaoli','qingliang']], - weizi:['male','qun',3,['yuanzi','liejie']], - tengfanglan:['female','wu',3,['luochong','aichen']], - sp_menghuo:['male','qun',4,['spmanwang']], - jin_yanghu:['male','jin',4,['huaiyuan','chongxin','dezhang']], - qinghegongzhu:['female','wei',3,['zengou','qhzhangji']], - fanjiangzhangda:['male','wu',4,['yuanchou','juesheng']], - tianyu:['male','wei',4,['saodi','zhuitao']], - ol_chendeng:['male','qun',4,['olfengji']], - ol_zhuling:['male','wei',4,['jixian']], - wuyan:['male','wu',4,['lanjiang']], - sp_ol_zhanghe:['male','qun',4,['spolzhouxuan']], - ol_dongzhao:['male','wei',3,['olxianlve','olzaowang']], - fengfangnv:['female','qun',3,['zhuangshu','chuiti']], - ol_yangyi:['male','shu',3,['oljuanxia','oldingcuo']], - zuofen:['female','jin',3,['zhaosong','lisi']], - ol_wangrong:['female','qun',3,['olfengzi','oljizhan','olfusong']], - ol_dengzhi:['male','shu',3,['olxiuhao','olsujian']], - ol_bianfuren:['female','wei',3,['fuwei','yuejian']], - duxi:['male','wei',3,['quxi','bixiong']], - gaogan:['male','qun',4,['juguan']], - huangchengyan:['male','qun',3,['guanxu','yashi']], - huangzu:['male','qun',4,['wangong']], - panshu:['female','wu',3,['weiyi','jinzhi']], - wolongfengchu:['male','shu',4,['youlong','luanfeng']], - sp_zhangliao:['male','qun',4,['mubing','ziqu','diaoling']], - caoshuang:['male','wei',4,['retuogu','shanzhuan']], - ol_zhangchangpu:['female','wei',3,['yanjiao','olxingshen']], - zhangling:['male','qun',3,['zlhuji','zlshoufu']], - caiyang:['male','qun',1,['yinka','zhuixi'],['forbidai','unseen']], - sunshao:['male','wu',3,['bizheng','yidian']], + character: { + sp_sunce: ["male", "qun", 4, ["olliantao"]], + ol_liupi: ["male", "qun", 4, ["olyicheng"]], + ol_lukai: ["male", "wu", 3, ["olxuanzhu", "oljiane"]], + liupan: ["male", "qun", 4, ["olpijing"]], + guotu: ["male", "qun", 3, ["olqushi", "olweijie"]], + ol_hujinding: ["female", "shu", 3, ["olqingyuan", "olchongshen"]], + tianchou: ["male", "qun", 4, ["olshandao"]], + liyi: ["male", "wu", 4, ["olchanshuang", "olzhanjin"]], + caoyu: ["male", "wei", 3, ["olgongjie", "olxiangxv", "olxiangzuo"]], + ol_liwan: ["female", "wei", 3, ["ollianju", "olsilv"]], + 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, ["yanru", "hezhong"]], + lvboshe: ["male", "qun", 4, ["olfushi", "oldongdao"]], + ol_luyusheng: ["female", "wu", 3, ["olcangxin", "olrunwei"]], + caoxi: ["male", "wei", 3, ["olgangshu", "oljianxuan"]], + ol_pengyang: ["male", "shu", 3, ["olxiaofan", "oltuishi", "nzry_cunmu"]], + ol_qianzhao: ["male", "wei", 4, ["olweifu", "olkuansai"]], + niujin: ["male", "wei", 4, ["olcuorui", "liewei"]], + hejin: ["male", "qun", 4, ["mouzhu", "olyanhuo"]], + hansui: ["male", "qun", 4, ["olniluan", "olxiaoxi"]], + duanjiong: ["male", "qun", 4, ["olsaogu"]], + ol_zhouqun: ["male", "shu", 4, ["oltianhou", "olchenshuo"]], + ol_wenqin: ["male", "wei", 4, ["olguangao", "olhuiqi"]], + haopu: ["male", "shu", 4, ["olzhenying"]], + ol_mengda: ["male", "shu", 4, ["olgoude"]], + ol_wanglang: ["male", "wei", 3, ["gushe", "oljici"]], + ol_liuyan: ["male", "qun", "4/6", ["olpianan", "olyinji", "olkuisi"]], + lushi: ["female", "qun", 3, ["olzhuyan", "releijie"]], + zhangshiping: ["male", "shu", 3, ["olhongji", "olxinggu"]], + sunhong: ["male", "wu", 3, ["olxianbi", "olzenrun"]], + luoxian: ["male", "shu", 4, ["oldaili"]], + ol_huban: ["male", "wei", 4, ["olhuiyun"]], + wangguan: ["male", "wei", 3, ["olmiuyan", "olshilu"]], + ol_zhangyì: ["male", "shu", 4, ["oldianjun", "olkangrui"]], + ol_zhujun: ["male", "qun", 4, ["olcuipo"]], + maxiumatie: ["male", "qun", 4, ["mashu", "rekenshang"]], + dongtuna: ["male", "qun", 4, ["oljianman"]], + zhanghua: ["male", "jin", 3, ["olbihun", "oljianhe", "olchuanwu"]], + quhuang: ["male", "wu", 3, ["olqiejian", "olnishou"]], + macheng: ["male", "shu", 4, ["mashu", "olchenglie"]], + zhangzhi: ["male", "qun", 3, ["olbixin", "olximo"]], + ol_liuba: ["male", "shu", 3, ["oltongduo", "olzhubi"]], + ol_furong: ["male", "shu", 4, ["olxiaosi"]], + ahuinan: ["male", "qun", 4, ["jueman"]], + jin_guohuai: ["female", "jin", 3, ["zhefu", "yidu"]], + xiahouxuan: ["male", "wei", 3, ["olhuanfu", "olqingyi", "olzeyue"]], + dengzhong: ["male", "wei", 4, ["dzkanpo", "dzgengzhan"]], + wangyan: ["male", "jin", 3, ["yangkuang", "cihuang", "sanku"]], + huojun: ["male", "shu", 4, ["qiongshou", "fenrui"]], + caoxiancaohua: ["female", "qun", 3, ["huamu", "qianmeng", "liangyuan", "jisi"]], + jin_zhouchu: ["male", "jin", 4, ["shanduan", "yilie"]], + zhaoyǎn: ["male", "wei", 4, ["tongxie"]], + ol_puyuan: ["male", "shu", 4, ["olshengong", "olqisi"]], + ruiji: ["female", "wu", 3, ["qiaoli", "qingliang"]], + weizi: ["male", "qun", 3, ["yuanzi", "liejie"]], + tengfanglan: ["female", "wu", 3, ["luochong", "aichen"]], + sp_menghuo: ["male", "qun", 4, ["spmanwang"]], + jin_yanghu: ["male", "jin", 4, ["huaiyuan", "chongxin", "dezhang"]], + qinghegongzhu: ["female", "wei", 3, ["zengou", "qhzhangji"]], + fanjiangzhangda: ["male", "wu", 4, ["yuanchou", "juesheng"]], + tianyu: ["male", "wei", 4, ["saodi", "zhuitao"]], + ol_chendeng: ["male", "qun", 4, ["olfengji"]], + ol_zhuling: ["male", "wei", 4, ["jixian"]], + wuyan: ["male", "wu", 4, ["lanjiang"]], + sp_ol_zhanghe: ["male", "qun", 4, ["spolzhouxuan"]], + ol_dongzhao: ["male", "wei", 3, ["olxianlve", "olzaowang"]], + fengfangnv: ["female", "qun", 3, ["zhuangshu", "chuiti"]], + ol_yangyi: ["male", "shu", 3, ["oljuanxia", "oldingcuo"]], + zuofen: ["female", "jin", 3, ["zhaosong", "lisi"]], + ol_wangrong: ["female", "qun", 3, ["olfengzi", "oljizhan", "olfusong"]], + ol_dengzhi: ["male", "shu", 3, ["olxiuhao", "olsujian"]], + ol_bianfuren: ["female", "wei", 3, ["fuwei", "yuejian"]], + duxi: ["male", "wei", 3, ["quxi", "bixiong"]], + gaogan: ["male", "qun", 4, ["juguan"]], + huangchengyan: ["male", "qun", 3, ["guanxu", "yashi"]], + huangzu: ["male", "qun", 4, ["wangong"]], + panshu: ["female", "wu", 3, ["weiyi", "jinzhi"]], + wolongfengchu: ["male", "shu", 4, ["youlong", "luanfeng"]], + sp_zhangliao: ["male", "qun", 4, ["mubing", "ziqu", "diaoling"]], + caoshuang: ["male", "wei", 4, ["retuogu", "shanzhuan"]], + ol_zhangchangpu: ["female", "wei", 3, ["yanjiao", "olxingshen"]], + zhangling: ["male", "qun", 3, ["zlhuji", "zlshoufu"]], + caiyang: ["male", "qun", 1, ["yinka", "zhuixi"], ["forbidai", "unseen"]], + sunshao: ["male", "wu", 3, ["bizheng", "yidian"]], - huangfusong:['male','qun',4,['fenyue']], - yuantanyuanshang:['male','qun',4,['neifa']], - xujing:['male','shu',3,['yuxu','xjshijian']], + huangfusong: ["male", "qun", 4, ["fenyue"]], + yuantanyuanshang: ["male", "qun", 4, ["neifa"]], + xujing: ["male", "shu", 3, ["yuxu", "xjshijian"]], - jianggan:["male","wei",3,["weicheng","daoshu"]], + jianggan: ["male", "wei", 3, ["weicheng", "daoshu"]], - caoying:["female","wei",4,["xinfu_lingren","fujian"],[]], - simahui:["male","qun",3,["jianjie","xinfu_chenghao","xinfu_yinshi"],[]], - baosanniang:["female","shu",4,["olwuniang","olxushen"],[]], + caoying: ["female", "wei", 4, ["xinfu_lingren", "fujian"], []], + simahui: ["male", "qun", 3, ["jianjie", "xinfu_chenghao", "xinfu_yinshi"], []], + baosanniang: ["female", "shu", 4, ["olwuniang", "olxushen"], []], - yangxiu:['male','wei',3,['jilei','danlao']], - chenlin:['male','wei',3,['bifa','songci']], - caohong:['male','wei',4,['yuanhu']], - xiahouba:['male','shu',4,['baobian']], - yuanshu:['male','qun',4,['yongsi','weidi']], - sp_diaochan:['female','qun',3,['lihun','rebiyue']], - sp_zhaoyun:['male','qun',3,['ollongdan','chongzhen']], - liuxie:['male','qun',3,['tianming','mizhao','twzhuiting'],['zhu']], - zhugejin:['male','wu',3,['olhuanshi','olhongyuan','olmingzhe']], - zhugeke:['male','wu',3,['aocai','duwu']], - guanyinping:['female','shu',3,['huxiao','xueji','wuji']], - simalang:['male','wei',3,['junbing','quji']], - zhangxingcai:['female','shu',3,['shenxian','qiangwu']], - fuwan:['male','qun',4,['dcmoukui']], - sp_sunshangxiang:['female','shu',3,['liangzhu','fanxiang']], - caoang:['male','wei',4,['kaikang']], - sp_caoren:['male','wei',4,['weikui','lizhan']], - zhangbao:['male','qun',3,['rezhoufu','reyingbing']], - maliang:['male','shu',3,['zishu','yingyuan']], - zhugedan:['male','wei',4,['gongao','juyi']], - sp_jiangwei:['male','wei',4,['kunfen','fengliang']], - sp_machao:['male','qun',4,['olzhuiji','ol_shichou']], - sunhao:['male','wu',5,['recanshi','rechouhai','guiming'],['zhu']], - shixie:['male','qun',3,['olbiluan','relixia']], - mayunlu:['female','shu',4,['fengpo','mashu']], - zhanglu:['male','qun',3,['yishe','bushi','midao','twshijun'],['zhu']], - wutugu:['male','qun',15,['ranshang','hanyong']], - sp_caiwenji:['female','wei',3,['chenqing','mozhi']], - zhugeguo:['female','shu',3,['qirang','yuhua']], + yangxiu: ["male", "wei", 3, ["jilei", "danlao"]], + chenlin: ["male", "wei", 3, ["bifa", "songci"]], + caohong: ["male", "wei", 4, ["yuanhu"]], + xiahouba: ["male", "shu", 4, ["baobian"]], + yuanshu: ["male", "qun", 4, ["yongsi", "weidi"]], + sp_diaochan: ["female", "qun", 3, ["lihun", "rebiyue"]], + sp_zhaoyun: ["male", "qun", 3, ["ollongdan", "chongzhen"]], + liuxie: ["male", "qun", 3, ["tianming", "mizhao", "twzhuiting"], ["zhu"]], + zhugejin: ["male", "wu", 3, ["olhuanshi", "olhongyuan", "olmingzhe"]], + zhugeke: ["male", "wu", 3, ["aocai", "duwu"]], + guanyinping: ["female", "shu", 3, ["huxiao", "xueji", "wuji"]], + simalang: ["male", "wei", 3, ["junbing", "quji"]], + zhangxingcai: ["female", "shu", 3, ["shenxian", "qiangwu"]], + fuwan: ["male", "qun", 4, ["dcmoukui"]], + sp_sunshangxiang: ["female", "shu", 3, ["liangzhu", "fanxiang"]], + caoang: ["male", "wei", 4, ["kaikang"]], + sp_caoren: ["male", "wei", 4, ["weikui", "lizhan"]], + zhangbao: ["male", "qun", 3, ["rezhoufu", "reyingbing"]], + maliang: ["male", "shu", 3, ["zishu", "yingyuan"]], + zhugedan: ["male", "wei", 4, ["gongao", "juyi"]], + sp_jiangwei: ["male", "wei", 4, ["kunfen", "fengliang"]], + sp_machao: ["male", "qun", 4, ["olzhuiji", "ol_shichou"]], + sunhao: ["male", "wu", 5, ["recanshi", "rechouhai", "guiming"], ["zhu"]], + shixie: ["male", "qun", 3, ["olbiluan", "relixia"]], + mayunlu: ["female", "shu", 4, ["fengpo", "mashu"]], + zhanglu: ["male", "qun", 3, ["yishe", "bushi", "midao", "twshijun"], ["zhu"]], + wutugu: ["male", "qun", 15, ["ranshang", "hanyong"]], + sp_caiwenji: ["female", "wei", 3, ["chenqing", "mozhi"]], + zhugeguo: ["female", "shu", 3, ["qirang", "yuhua"]], - lingju:['female','qun',3,['jieyuan','fenxin']], + lingju: ["female", "qun", 3, ["jieyuan", "fenxin"]], - cuiyan:['male','wei',3,['yawang','xunzhi']], - jsp_guanyu:['male','wei',4,['new_rewusheng','danji']], - jsp_huangyueying:['female','qun',3,['jiqiao','linglong']], - sunluyu:['female','wu',3,['new_meibu','new_mumu']], - hanba:['female','qun',4,['fentian','zhiri']], - zumao:['male','wu',4,['yinbing','juedi']], - wenpin:['male','wei',4,['zhenwei']], - daxiaoqiao:['female','wu',3,['new_xingwu','new_luoyan']], + cuiyan: ["male", "wei", 3, ["yawang", "xunzhi"]], + jsp_guanyu: ["male", "wei", 4, ["new_rewusheng", "danji"]], + jsp_huangyueying: ["female", "qun", 3, ["jiqiao", "linglong"]], + sunluyu: ["female", "wu", 3, ["new_meibu", "new_mumu"]], + hanba: ["female", "qun", 4, ["fentian", "zhiri"]], + zumao: ["male", "wu", 4, ["yinbing", "juedi"]], + wenpin: ["male", "wei", 4, ["zhenwei"]], + daxiaoqiao: ["female", "wu", 3, ["new_xingwu", "new_luoyan"]], - guansuo:['male','shu',4,['zhengnan','xiefang']], - tadun:['male','qun',4,['reluanzhan']], - yanbaihu:['male','qun',4,['zhidao','jili']], - chengyu:['male','wei',3,['shefu','benyu']], + guansuo: ["male", "shu", 4, ["zhengnan", "xiefang"]], + tadun: ["male", "qun", 4, ["reluanzhan"]], + yanbaihu: ["male", "qun", 4, ["zhidao", "jili"]], + chengyu: ["male", "wei", 3, ["shefu", "benyu"]], - sp_pangde:['male','wei',4,['mashu','juesi']], - sp_jiaxu:['male','wei',3,['zhenlue','jianshu','yongdi']], + sp_pangde: ["male", "wei", 4, ["mashu", "juesi"]], + sp_jiaxu: ["male", "wei", 3, ["zhenlue", "jianshu", "yongdi"]], - litong:['male','wei',4,['tuifeng']], - mizhu:['male','shu',3,['ziyuan','jugu']], - buzhi:['male','wu',3,['hongde','dingpan']], + litong: ["male", "wei", 4, ["tuifeng"]], + mizhu: ["male", "shu", 3, ["ziyuan", "jugu"]], + buzhi: ["male", "wu", 3, ["hongde", "dingpan"]], - caochun:['male','wei',4,['xinshanjia']], + caochun: ["male", "wei", 4, ["xinshanjia"]], - dongbai:['female','qun',3,['lianzhu','xiehui']], + dongbai: ["female", "qun", 3, ["lianzhu", "xiehui"]], - zhaoxiang:['female','shu',4,['fanghun','fuhan']], - mazhong:['male','shu',4,['fuman']], - dongyun:['male','shu',3,['bingzheng','sheyan']], - kanze:['male','wu',3,['xiashu','kuanshi']], - heqi:['male','wu',4,['olqizhou','olshanxi']], + zhaoxiang: ["female", "shu", 4, ["fanghun", "fuhan"]], + mazhong: ["male", "shu", 4, ["fuman"]], + dongyun: ["male", "shu", 3, ["bingzheng", "sheyan"]], + kanze: ["male", "wu", 3, ["xiashu", "kuanshi"]], + heqi: ["male", "wu", 4, ["olqizhou", "olshanxi"]], - yuejin:['male','wei',4,['xiaoguo']], - sp_dongzhuo:['male','qun',5,['hengzheng']], - hetaihou:['female','qun',3,['zhendu','qiluan']], - dingfeng:['male','wu',4,['reduanbing','refenxun']], - shamoke:['male','shu',4,['gzjili']], + yuejin: ["male", "wei", 4, ["xiaoguo"]], + sp_dongzhuo: ["male", "qun", 5, ["hengzheng"]], + hetaihou: ["female", "qun", 3, ["zhendu", "qiluan"]], + dingfeng: ["male", "wu", 4, ["reduanbing", "refenxun"]], + shamoke: ["male", "shu", 4, ["gzjili"]], - zhangren:['male','qun',4,['chuanxin','zfengshi']], + zhangren: ["male", "qun", 4, ["chuanxin", "zfengshi"]], - wangyun:['male','qun',4,['xinlianji','xinmoucheng'],['clan:太原王氏']], - sunqian:['male','shu',3,['qianya','shuimeng']], - xizhicai:['male','wei',3,['tiandu','xianfu','chouce']], - quyi:['male','qun',4,['fuqi','jiaozi']], + wangyun: ["male", "qun", 4, ["xinlianji", "xinmoucheng"], ["clan:太原王氏"]], + sunqian: ["male", "shu", 3, ["qianya", "shuimeng"]], + xizhicai: ["male", "wei", 3, ["tiandu", "xianfu", "chouce"]], + quyi: ["male", "qun", 4, ["fuqi", "jiaozi"]], - luzhi:['male','wei',3,['qingzhong','weijing']] + luzhi: ["male", "wei", 3, ["qingzhong", "weijing"]], }, - characterIntro:{ - liupan:'刘磐(生卒年不详),山阳高平人,荆州牧刘表从子。与南阳人黄忠共守长沙攸县。为人骁勇,数次为寇于艾、西安诸县。江东孙策于是分海昏、建昌为左右六县,以东莱太史慈为建昌都尉,治海昏,并督诸将共拒刘磐。于是刘磐绝迹不复为寇。', - guotu:'郭图(?-205年),字公则,颍川(治今河南省禹州市)人。东汉末年袁绍帐下谋士。韩馥统冀州时,郭图与荀谌等人奉袁绍之命,说服韩馥让位。袁绍统一河北后,郭图与审配等人力劝袁绍统率大军攻打曹操。袁绍死后,袁尚继位。郭图与辛评为袁谭效力,挑唆袁谭攻击袁尚。建安十年(205年),郭图和袁谭一同被曹操所杀。', - tianchou:'田畴(169年或170年-214年或216年),字子泰,东汉右北平郡无终人,东汉末年隐士。田畴好文习武。汉初平年间,其受刘虞派遣去长安,呈送指控公孙赞奏章,献帝大悦,封为骑都尉,田畴不受。携诏返回时,刘虞已被公孙所杀,田畴到刘墓祭拜,被公孙所提,不久释放。田畴回故乡后率家族及随从数百人隐居徐无山,致力农桑,数年间增至5000家。制定法条,兴建学校,一时民风良好,乌桓、鲜卑纷纷与其结交。汉建安二十年(207年),曹操北征乌桓,田畴请为向导。上徐无山、出卢龙、过平冈、登白狼堆、至柳城,曹军大胜,封田畴为亭侯,坚辞不受。曹念田功,四次封赏,终不受,乃拜为议郎。建安二十一年(216年),田畴去世。', - liyi:'李异(生卒年不详),三国时期东吴将领。建安末,与谢旌率水陆三千,击破刘备军将领詹晏、陈凤。刘备领兵攻孙权时,李异与陆逊等人屯巫、秭归,为蜀将所破。黄武元年(222年),陆逊破刘备于猇亭,李异追踪蜀军,屯驻南山。清代学者赵一清认为此李异与刘璋部将李异为同一人。', - caoyu:'曹宇(?-278年),字彭祖,沛国谯县(今安徽亳州)人。三国时期魏国宗室,魏武帝曹操与环夫人之子,邓哀王曹冲同母兄弟。太和六年,封为燕王。魏明帝病危,欲以大将军辅政,不果。其子常道乡公曹奂,是魏国末代皇帝,史称魏元帝。晋朝建立后,降封燕公。咸宁四年(278年),曹宇去世。', - zhangyan:'张燕,本姓褚,生卒年不详,常山真定(今河北正定南)人,东汉末年黑山军首领。张燕剽捍,敏捷过人,军中称为“飞燕”。官渡之战时投降曹操,被任命为平北将军,封安国亭侯。死后其子张方袭爵。', - lushi:'卢氏,五斗米教主张衡妻,张鲁母,擅长驻颜之术,常年令自己保持少女的容颜。常拜访刘焉,与其交好。', - lvboshe:'吕伯奢,东汉成皋(今河南荥阳)人,曹操父亲曹嵩的故友。曹操与陈宫在逃离董卓避祸,返回乡里的途中借宿于吕伯奢家,未伤其人,有贼八人欲捉曹操,曹操杀之,明罗贯中在历史小说《三国演义》中将这段历史进行了丑化加工,也成为小说中曹操名言“宁教我负天下人,休教天下人负我”的出处。', - caoxi:'曹羲(?-249年),字昭叔。曹真之子,曹爽之弟。为人有学识,明律法。司马懿曾组织朝议改革九品中正制废除九品而留中正,曹羲认为此举并无区别,最终都是决定于人的人治。曹爽掌权后,受封中领军,掌握禁兵,封安乡侯。曹爽及诸兄弟轻视司马懿,恣意妄为,经常外出狩猎,曹羲屡次劝谏,不被采纳。249年,司马懿发动高平陵政变,被夷三族。', - duanjiong:'段颎(?-179年),字纪明,武威姑臧(今甘肃省武威市)人。东汉名将,西域都护段会宗从曾孙,与皇甫规(字威明)、张奂(字然明)并称“凉州三明”。段颎少时学习骑射,有文武智略,最初被举为孝廉,为宪陵园丞、阳陵令,有治理之才。汉桓帝时入军旅,先破鲜卑,后讨平东郭窦、公孙举起事,以功封列侯。延熹二年(159年)起戍边征战十余年,百战羌人,至永康元年(167年)平定西羌,建宁二年(169年)平定东羌,前后斩东西羌六万余级。累功封新丰县侯。建宁三年(170年),段颎被征入朝,历任侍中、执金吾、河南尹、司隶校尉等职,他党附宦官、捕杀太学生,因而得保富贵,两度出任太尉。光和二年(179年),权宦王甫罪行被揭发,段颎受牵连下狱,其后在狱中饮鸩而死。', - haopu:'郝普,字子太,义阳(治所在今湖北枣阳东南)人。刘备入川后,郝普为零陵太守。建安二十年(215年),吴将吕蒙进攻荆州三郡,唯有郝普坚守待援。但援兵久久不至,其挚友邓玄之又被吕蒙所骗,郝普也因此上当,投降吴国。湘水划界后,郝普回归刘备。建安二十四年(219年),吕蒙再次袭击荆州,击败关羽,郝普再次投降,最终归顺吴国并官至廷尉。郝普与隐蕃亲善,隐蕃蓄谋叛变事情败露,他受到牵连,因此自杀。在刘备集团的5个荆州郡守中,郝普是唯一一个抵抗过东吴的荆州郡守。', - ol_zhanghe:'字儁乂,河间鄚人。三国时期魏国名将。官渡之战时,本为袁绍部将的张郃投降了曹操,并在曹操帐下多立功勋,于曹魏建立后加封为征西车骑将军。诸葛亮六出祁山之间,张郃多次抵御蜀军的进攻,于公元231年在木门道被诸葛亮设伏射死。后谥曰壮侯。为曹魏“五子良将”之一。', - zhangshiping:'张世平是东汉末期的中山商人,曾与苏双同路,资助刘备组织武装、建立政权。于《三国演义》第一回出场,刘关张桃园三结义时资助刘备良马五十匹,金银五百两,镔铁一千斤。刘备所使用的“双股剑”、关羽所使用的“青龙偃月刀(又名‘冷艳锯’)”、张飞所使用的“丈八点钢矛(又名‘丈八蛇矛’)”皆由这一千斤上好镔铁打造而成。', - luoxian:'罗宪(218年—270年),字令则,荆州襄阳(今湖北襄阳)人。西晋开国将领,巴东太守(郡府在永安白帝城)。于蜀汉灭亡后降魏,成功抵御孙吴的入侵,守住入魏国的要冲永安。后仕晋官至冠军将军、假节,封西鄂县侯。泰始六年(270年)去世,谥烈侯。', - sunhong:'孙弘(?—252年),三国时期吴国大臣,扬州会稽(今浙江省绍兴市)人。官至吴国中书令、少傅。鲁王孙霸与太子孙和各植党羽,孙弘即依附孙霸。孙权病笃,而太子年少,于是以孙弘领少傅。孙权临终,召他与诸葛恪、孙峻等嘱以后事,孙弘与诸葛恪同为顾命大臣。孙权死后,孙弘因素来与诸葛恪不和,怕为所治,故而隐瞒了孙权的死讯,欲矫诏除掉诸葛恪,被孙峻告发。后诸葛恪请孙弘议事,于座中将其诛杀。', - wangguan:'《三国演义》中虚构人物,历史上不曾记载。在114回出场,曾为邓艾手下参谋,献反间计与邓艾,被姜维识破,兵败自投江而死。', - maxiumatie:'马休(?-212年),马铁(?-212年)。两人均为扶风茂陵(今陕西兴平)人,马腾之子,马超之弟。马腾遭韩遂进攻,乃携马休、马铁等入京受职。马休被封为奉车都尉,马铁被封为骑都尉。后在邺城居住。因兄马超反,两人被曹操夷灭。', - dongtuna:'董荼那,小说《三国演义》及其衍生作品中的角色,南蛮王孟获属下大将,第二洞元帅;与阿会喃等人一起担任孟获的援军出征,但是被俘虏,又被诸葛亮释放,再次出战时,被唾骂不知羞耻,面红耳赤的退军。后同阿会喃共同绑架孟获献于蜀军,却被诸葛亮在其二人与孟获的重要性间权衡后出卖了他们,放走了孟获,使其为孟获所杀。', - zhanghua:'张华(232年-300年),字茂先。范阳郡方城县(今河北固安)人。西晋时期政治家、文学家、藏书家,西汉留侯张良的十六世孙。张华出身范阳张氏,自少贫苦,因才学过人而受同乡名臣卢钦、刘放、阮籍等人的赞赏。在曹魏时,他历任太常博士、河南尹丞、佐著作郎、中书郎等职。西晋建立后,拜黄门侍郎,封关内侯,逐渐受到晋武帝的重用。后拜中书令,加散骑常侍,与大将杜预坚决支持武帝伐吴,于战时任度支尚书。吴国灭亡后,以功进封广武县侯。其后遭到排挤,出镇幽州,政绩卓然。之后返朝任太常,终武帝之世未得参与政事。晋惠帝继位后,累官至司空,封壮武郡公,被皇后贾南风委以朝政。张华尽忠辅佐,使天下仍然保持相对安宁。永康元年(300年),♯♯司马伦发动政变,张华惨遭杀害,年六十九。太安二年(303年),获得♯♯,追复官爵。张华工于诗赋,词藻华丽,又雅爱书籍,精于目录学,编纂有中国第一部博物学著作《博物志》;还曾与荀勖等人依照刘向《别录》整理典籍。《宣和书谱》载有其草书《得书帖》及行书《闻时帖》。《隋书·经籍志》有《张华集》十卷,今已佚。明人张溥辑有《张茂先集》。', - quhuang:'屈晃(?—251),祖籍汝南(今河南省汝南县),汉末避乱南下,三国吴时居章安(今属椒江区)。初为郡吏,在职清廉,颇有政声。赤乌初年,擢为尚书仆射。', - macheng:'马承,蜀汉骠骑将军马超之子。仕蜀汉,马超死后继承其斄乡侯爵位。', - zhangzhi:'张芝(?—192年),字伯英,敦煌郡渊泉县(今甘肃省瓜州县)人。东汉书法家、“草书之祖”,大司农张奂的儿子。出身名门,拒绝朝廷征召,潜心研习书法。擅长草书中的章草,将古代当时字字区别、笔画分离的草法,改为上下牵连富于变化的新写法,富有独创性,在当时影响很大。李志敏评价:“张芝创造了草书问世以来的第一座高峰,精熟神妙,兼善章今”。 没有真迹传世,仅存《八月帖》等刻帖。汉献帝初平三年,去世于家中,著有《笔心论》,与钟繇、王羲之和王献之并称“书中四贤”。', - ahuinan:'阿会喃,小说《三国演义》及其衍生作品中的角色,南蛮王孟获属下大将,第三洞元帅;与董荼那等人一起担任孟获的援军出征,但是被俘虏,又被诸葛亮释放,再次出战时,被唾骂不知羞耻,面红耳赤的退军。后同董荼那共同绑架孟获献于蜀军,却被诸葛亮在其二人与孟获的重要性间权衡后出卖了他们,放走了孟获,使其为孟获所杀。', - xiahouxuan:'夏侯玄(209年~254年),字泰初(《三国志》等作太初),沛国谯县(今安徽省亳州市)人。三国时期曹魏大臣、思想家、文学家,征南大将军夏侯尚之子,大将军曹爽的表弟。夏侯玄少年有名望,仪表出众,时人称为“朗朗如日月之入怀”。魏文帝黄初六年(225年),袭封昌陵乡侯。魏明帝时,历任散骑黄门侍郎、羽林监。少帝曹芳继位后,拜散骑常侍、中护军,保卫皇宫。后任征西将军,任内与曹爽策划骆谷之役,大失人心。高平陵政变后,被夺去兵权,改任大鸿胪、太常卿。嘉平六年(254年),中书令李丰与外戚张缉密谋杀死大将军司马师,改以夏侯玄执政。事泄被杀,夷灭三族,夏侯玄死时年仅四十六岁。著有文集三卷,如今已佚。政治上,提出了“审官择人”、“除重官”、“改服制”等制度,被太傅司马懿评价“皆大善”。博学多识,才华出众,精通玄学,成为“四聪”之一,与何晏等人开创了魏晋玄学的先河,是早期的玄学领袖人物。', - dengzhong:'邓忠(不详-264年),三国时期曹魏名将邓艾之子。景元五年(264年),钟会谋反事败,士兵哗变,钟会被杀,邓艾部将想追还邓艾父子,但卫瓘却派田续追邓艾,于绵竹西相遇,将邓艾和邓忠等人杀死。直至泰始九年(273年)才恢复名节。', - wangyan:'王衍(256年~311年),字夷甫,琅邪郡临沂县(今山东省临沂市)人。西晋末年重臣,玄学清谈领袖,曹魏幽州刺史王雄之孙、平北将军王乂之子、司徒王戎堂弟。王衍出身琅琊王氏。外表清明俊秀,风姿安详文雅,笃好老庄学说,颇有时名。步入仕途后,历任黄门侍郎、中领军、尚书令、尚书仆射等职。光熙元年(307年),升任司空。次年,又任司徒。王衍位高权重,却不思为国,为保全自己,还让弟弟王澄、族弟王敦分任荆州、青州刺史,遭时人鄙夷。王弥进攻洛阳时,王衍率军抵抗。其后转任太尉兼尚书令,又兼领太傅军司。永嘉五年(311年),东海王司马越去世,王衍奉其灵柩返回东海,途中为羯人石勒所俘获。王衍在与石勒交谈时,仍推脱责任,并劝其称帝,石勒大怒,将其与西晋旧臣一同活埋,时年五十六岁。王衍工书法,尤擅行书,《宣和书谱》有其作品《尊夫人帖》。', - caoxiancaohua:'请分别查看「曹宪」和「曹华」的武将介绍。', - zhaoyǎn:'赵俨(171~245年),字伯然,颍川阳翟(今河南禹州市)。东汉末年颍川“四大名士”之一,三国时期魏国名臣。熟读经史,精明强干。建安二年,投靠大将军曹操之后,起家朗陵县令,历任司空府掾、司空主薄、都督护军、扶风太守等职。魏文帝曹丕继位后,历任魏国侍中、驸马都尉、河东太守、典农中郎将、度支尚书,封宜土亭侯。魏明帝曹睿时期,历任大司农、骠骑将军、大司空等职。正始六年,去世,时年七十五,谥号为穆。', - ruiji:'芮姬,芮玄之女,太子孙登妃,黄武五年卒。', - weizi:'卫兹(?-190年),字子许,(《三国演义》中其名为卫弘,当为误记),陈留襄邑(今河南睢县)人。曾举孝廉,先后被车骑将军何苗、司徒杨赐等召辟。中平六年(189年)十二月,曹操在陈留己吾募兵,而卫兹以家财资助曹操,使曹操顺利募得五千士兵。此后,卫兹与曹操共同讨伐董卓。初平元年(190年),卫兹在跟随曹操讨伐董卓途中,于荥阳汴水遭遇董卓军徐荣,力战终日,失利身亡。', - tengfanglan:'滕芳兰,生卒年不详,北海剧县(今山东省寿光市)人,太常滕胤的族女,滕牧的女儿,吴末帝孙皓的皇后。永安元年(258年),孙皓为乌程侯时被聘为妃。元兴元年(264年),孙皓登基后被立为皇后。孙吴灭亡后,随孙皓迁居洛阳。', - qinghegongzhu:'清河长公主,沛国谯县人,曹操长女(按其与曹操长子曹昂同出于刘夫人,而刘夫人又早死,故其年龄应长于曹丕等其他曹操诸子女,又按长公主亦有年最长之意,故应为曹操之长女)。母刘夫人,得到曹操喜爱。清河公主后来下嫁夏侯楙。曹操初欲嫁丁仪,曹丕劝其嫁与夏侯楙。后与小叔子设计欲谋害丈夫,未果。', - fanjiangzhangda:'范强,在明朝小说《三国演义》里叫做范疆。二人均为张飞手下部将。蜀汉章武元年,刘备伐吴,张飞率军从阆中前往江州,出发前,范强和张达杀死张飞,带着张飞的首级投奔了东吴。', - tianyu:'田豫(171年~252年),字国让,渔阳雍奴(今天津市武清区)人。三国时期曹魏将领。初从刘备,因母亲年老回乡,后跟随公孙瓒,公孙瓒败亡,劝说鲜于辅加入曹操。曹操攻略河北时,田豫正式得到曹操任用,历任颖阴、郎陵令、弋阳太守等。后来田豫常年镇守曹魏北疆,从征代郡乌桓、斩骨进、破轲比能,多有功勋;也曾参与对孙吴的作战,在成山斩杀周贺,于新城击败孙权。官至太中大夫,封长乐亭侯。有一子田彭祖。', - wuyan:'吴国及西晋初年将领。初任通江县吏,后得到大司马陆抗的提拔重用,逐渐升至建平太守。', - fengfangnv:'冯方之女,司隶人,袁术妻妾。在史书中被记载为天姿国色的美人。钱大昭在《三国志辨疑》中认为冯方当为冯芳误字,冯方女实为是西园八校尉之一的冯芳的女儿。然而,在曹丕《典论》、《九州春秋》等书籍都有提及她,皆作冯方女字样,并无一书写作冯芳女或是明提是冯芳之女。最关键的一点是,冯芳是荆州西陵县人,她女儿不可能是司隶籍,冯芳也没担任过任何与司隶有关的官职。同时期名字为“○女”的并不少见,如施绩女儿施淑女,曹植女儿曹行女,夏侯令女等。', - zuofen:'左芬(约253年-300年4月23日),出土墓志作左棻,字兰芝,齐国临淄(今山东临淄)人,西晋诗人。少好学,善属文。为晋武帝贵人。今存诗、赋、颂、赞、诔等20余篇,大都为应诏而作,《离思赋》最著名。原有集,已失传。', - duxi:'杜袭(生卒年不详),字子绪,颍川郡定陵县(今河南省襄城县)人。三国时期魏国重臣,东汉末年颍川“四大名士”之一,济阴太守杜根的孙子。建安初年,投奔司空曹操,历任西鄂县令、议郎、丞相军咨祭酒、魏王侍中、丞相长史、驸马都尉。魏文帝时期,出任督军粮御史、尚书,累封武平亭侯。魏明帝时期,担任大将军曹真和司马懿的军师,抵御蜀国进攻,拜太中大夫,受封平阳乡侯。卒于任上,获赠少府,谥号为定。', - gaogan:'高干(?~206年),字元才,陈留郡圉县(今河南杞县圉镇)人。东汉末年并州割据将领,蜀郡太守高躬之子、大将军袁绍外甥。出身陈留高氏,才志弘邈,文武秀出。早年联合荀谌游说韩馥让出冀州牧。袁绍平定河北后,以为并州牧。官渡之战时,在西线配合作战。因曹操早有准备,没有实质进展。袁绍死后,袁谭、袁尚与曹操大战于黎阳郡时,联合郭援攻打平阳郡,为马腾为首关中将领所败,郭援为庞德所斩。袁尚败走中山郡后,出降于曹操,仍为并州刺史。建安十年,兴兵反曹,固守壶关,成功抵挡乐进进攻。得知曹操亲征后,留下别将守城,亲往匈奴呼厨泉求救,没有成功。引兵攻略河东郡,屡为钟繇、张既所败。建安十一年,投奔荆州刘表。途经上洛时,为上洛都尉捕斩之。', - huangchengyan:'黄承彦,生卒年不详,汉末三国时期沔阳名士,诸葛亮岳父,黄月英之父。南郡大士蔡讽的女婿,与襄阳名士上层社会圈子:庞统(凤雏)、庞德公、司马徽、徐庶等人交好。《襄阳记》:黄承彦者,高爽开列,为沔阳名士,谓诸葛孔明曰:“闻君择妇,身有丑女,黄头黑色,而才堪配。”孔明许,即载送之。时人以为笑乐,乡里为之谚曰:“莫作孔明择妇,正得阿承丑女。”', - panshu:'潘淑(?-252年),会稽句章(今浙江省宁波市)人,是吴大帝孙权的皇后,吴少帝孙亮的母亲。和孙权是中国历代帝后中年龄差距较大的一对。潘淑少时与姐姐俱没入织室,容媚有宠,拜为夫人,生有一子孙亮。赤乌十三年(250年),孙权立孙亮为皇太子,翌年(251年)立潘淑为皇后。神凤元年(252年)暴崩,合葬蒋陵。世称潘淑为江东绝色,有神女之称。', - zongyu:'宗预(?-264年),字德艳 ,荆州南阳郡安众县(今河南省南阳市)人。三国时期蜀汉官员、将领。曾随张飞入蜀助平益州,又受辟为丞相诸葛亮手下主簿,升任参军、右中郎将。诸葛亮逝世后,宗预受命出使孙吴,得到孙权的赞赏。迁后将军,出督永安,又升任征西大将军,并受封关内侯。公元258年(景耀元年),因病回成都,受任镇军大将军。蜀汉灭亡后,宗预随后主刘禅徙往洛阳,在中途病逝。宗预为人坦率耿直,多次出使孙吴并深得孙权的敬重,为吴、汉两国同盟的巩固作出了一定的贡献。', - mengda:'孟达(?-228),字子度,本字子敬,因刘备的叔父名叫刘子敬,为避讳而改字。扶风郡郿人,三国时期人物。本为刘璋属下,后降刘备。关羽围樊城、襄阳时因不发兵救关羽而触怒刘备,于是投奔曹魏。此后,劝降刘封,未果。在魏官至散骑常侍、建武将军,封平阳亭侯。此后又欲反曹魏而归蜀汉,事败而死。', - wolongfengchu:'沙比武将,懒得复制粘贴,自己去看「诸葛亮」和「庞统」的介绍吧。', - caoshuang:'曹爽(?-249年2月9日),字昭伯,沛国谯县(今安徽亳州市)人。三国时期魏国权臣,大司马曹真长子。曹爽体态肥胖,凭借宗室身份,出入宫廷,交好太子曹叡。魏明帝即位,起家员外散骑侍郎,累迁城门校尉、散骑常侍,转武卫将军。太和五年(231年),袭封邵陵侯。景初三年(239年),魏明帝曹叡病危,拜大将军、假黄钺,与司马懿并为托孤大臣。少帝曹芳即位,加侍中,改封武安侯。势倾四海,声震天下。任用私人,专权乱政,侵吞公产。伐蜀失败,虚耗国力。起居逾制,软禁郭太后。正始十年,太傅司马懿发动高平陵政变,掌握魏国大权。曹爽失去大将军职务,以谋反之罪处死,夷灭三族。', - zhangling:'张道陵(34年2月22日—156年),字辅汉,原名陵,道教正一道实际创立者,汉朝东汉时期丰邑(今江苏徐州丰县)人。太上老君降临蜀地,“授以三天正法,命为天师”,张道陵整合当时的:黄老派、方仙道、文始派等先秦修道团体,创立道教称正一盟威之道。后世尊称为“老祖天师”、“正一真人”、“三天扶教大法师”、高明上帝、张天师。著作《老子想尔注》,弟子有3000多人,设立24治,奠基天师道。张道陵、葛玄、许逊、萨守坚合称四大天师。张道陵创建道教的背景:当时在巴蜀一带,原有巴人信奉原始巫教,大规模的淫祀而害民。而这些祀奉鬼妖(学名为:妖邪)的法教巫师聚众敛财,无恶不作。张天师携王长、赵升二位弟子和黄帝九鼎丹经,来到北邙山修行,平定了那些祸害百姓的巫妖之教。川渝一带流传的张天师以太上老君剑印符箓大破鬼兵的故事就是以此为原型的。', - caiyang:'蔡阳(?-201年),又作蔡扬,东汉丞相曹操部下武将,汝南太守。于建安六年(201)奉曹操之命攻击与刘备联合的汝南贼龚都等人,兵败被刘备所杀。明代小说《三国演义》改编为“云长擂鼓斩蔡阳”。', - pujing:'湖北省当阳境内有一座山,名叫玉泉山。东汉建安末年,山上住着一个老和尚,法名普净,普净原来是沂水关镇国寺方丈,后因云游天下,来到此处,风这地方山明水秀,就于山中结草为庵,每天坐禅参道,身边只有一个小和尚,外出化一些斋饭,供养师父。在《三国演义》中,当关羽通过汜水关时,正是由于普净提醒,关羽才揭穿了卞喜的阴谋,并杀死了卞喜。关羽死后,其怨魂亦在普净的指点下醒悟,放下了心中的仇恨,专心致力于造福一方百姓。', - huban:'为《三国演义》所杜撰的人物,正史无记载,荥阳太守王植麾下从事、桓帝时议郎胡华之子。关羽过五关斩六将时其中一关就是王植所镇守,胡班奉命放火夜袭关公,因敬服公之气概,并得其父托公所带家书,班看毕,叹曰:“险些误杀忠良!”故将之放走。胡班到荆州来投降关公,公念其旧日相救之情,甚爱之;令随费诗入川,见汉中王受爵。费诗辞别关公,带了胡班,自回蜀中去了。', - chunyuqiong:'淳于琼(?-200年),字仲简,颍川(治今河南禹州)人。东汉时期官吏,于汉灵帝中平五年(188)被任命为西园八校尉之一的右校尉,与蹇硕、袁绍、鲍鸿、曹操、赵融、冯芳、夏牟同列。为袁绍大将,与张郃、高览等人齐名。在官渡之战时镇守乌巢,遭到曹操的偷袭而惨败,自己也被曹操处斩。', - lvkuanglvxiang:'吕旷(生卒年不详),与吕翔同是袁绍属下,袁绍去世后,为袁尚守东平,后来投降曹操,并被封为列侯。在《三国演义》中,在曹操准备往南准备攻击前,两人跟著大将曹仁和将军李典准备要攻击刘备。但吕旷被赵云刺下马身亡,而吕翔也死于张飞矛下,可以算是出师未捷身先死', - caobuxing:'曹不兴,亦名弗兴,三国时著名画家。孙吴吴兴(今浙江湖州)人,生卒年不详。他在黄武年间(222—229年)享有很大的声誉。被称为“佛画之祖”。与东晋顾恺之、南朝宋陆探微、南朝梁张僧繇并称“六朝四大家”。又与赵达的算术、严武的弈棋、皇象的草书等号称“吴中八绝”。曹不兴善画龙、虎、马及人物,有“落墨为蝇”等传奇故事,其佛画成就对后世影响很大,相传其所画龙头令谢赫叹服不已。画迹今已不存,据《贞观公私画史》载,作品有《青溪龙》、《赤盘龙》、《南海监牧进十种马图》、《夷事夷兽样》、《桃源图》等,惜早已散佚。但之后的著名画家卫协直接师承其法。', - gaolan:'高览,生卒年不详,一名高奂,本属袁绍部将,后官渡之战淳于琼被曹操击破,与张郃一同投降曹操,被封为偏将军,东莱侯。《三国演义》里,曾与许褚、徐晃大战不分胜负。201年刘备败走荆州时,高览奉命追杀,三合斩刘辟,而后被冲阵而来的赵云刺死。', - xunchen:'荀谌,字友若,荀彧之兄(一说荀彧之弟),荀绲之子,颍川人。曾任军阀袁绍的幕僚。帮助袁绍游说韩馥,夺取了冀州。', - sunshao:'孙邵(163年-225年),字长绪,青州北海国人(今山东潍坊市昌乐县西)。原为北海相孔融的功曹,被孔融称赞为可任朝廷要职的人才,后随刘繇到达江东,继而辅佐孙权。孙权称吴王后,孙邵成为吴国首任丞相,数年后病逝。由于孙邵和当时吴国史官的关系并不是很好,因此在史书中并没有详细的记载。', - yuantanyuanshang:'袁谭、袁尚分别是袁绍的长子和第三子。袁绍坐拥青州、冀州、幽州、并州,本是北方最强诸侯,却于官渡大败,惭恨而终。虽然袁绍生前偏爱小儿子袁尚,却并未在继承人上有明确表态,这也导致本应以嫡长子身份继承的袁谭因郭图、审配伪立遗令未能如愿。曹操击败袁绍后,进而渡过黄河追击袁家残余势力,袁谭告急,但袁尚仅给他少量兵力。曹操得郭嘉之计退兵坐观其变,恰使两人此前的种种矛盾彻底爆发,袁谭不敌便引狼入室,派辛毗作为使者向曹操求援,让袁尚不得不北逃投奔乌桓。但袁谭也在之后背叛曹操兵败被杀。没多久,乌桓也被平定,袁熙、袁尚二人投奔公孙康后被斩首送还曹操。', - xujing:'许靖(?—222年),字文休。汝南郡平舆县(今河南省平舆县)人。汉末至三国蜀汉时期重臣、名士、评论家。许靖因与从弟许邵俱以品评人物而闻名于世。后被刘翊推举为孝廉,任尚书郎。曾先后投奔孔伷、陈祎、许贡、王朗等人,于孙策攻王朗前与家属俱避难交州,受到交趾太守士燮礼待。其后受益州牧刘璋邀请,相继为巴郡、广汉、蜀郡太守。于刘备包围成都时欲越墙叛逃,为刘璋所获。刘备定蜀后欲将其弃用,在法正的建议下方以其为左将军长史。建安二十三年(218年),刘备称汉中王,任命许靖为汉中王傅。章武元年(221年),刘备称帝,任命许靖为司徒,位列三公。章武二年(222年),去世。有文集二卷。', - hejin:'何进(?~189年),字遂高,南阳郡宛县(今河南南阳市宛城区)人。东汉时期外戚大臣,灵思皇后之兄。初以妹妹有宠,拜为郎中,出任虎贲中郎将、颍川太守,迁侍中、将作大匠、河南尹。黄巾起义时,拜为大将军,总镇京师,发现并镇压马元义的密谋,封为慎侯。为张大威望,在京师讲武结营,置西园八校尉。汉灵帝驾崩后,粉碎了中常侍蹇硕拥立皇子刘协的图谋,听从袁绍之言,博征智谋之士,内借元舅之资,外据辅政之权,独揽朝中大权。中平六年(189),不纳陈琳和曹操劝谏,阴结军阀董卓,联合袁绍谋诛宦竖。事情败露后,为中常侍张让等人损害,其后代是魏晋高门士族南阳何氏。', - hansui:'韩遂(?-215年),字文约。凉州金城郡人。东汉末年军阀、将领,汉末群雄之一。原名韩约,后改名遂。韩遂最初闻名于西州,被羌胡叛军劫持并推举为首领,以诛宦官为名举兵造反,聚众十万,先后败皇甫嵩、张温、董卓、孙坚等名将,使得天下骚动。后受朝廷招安,拥兵割据一方长达三十余年。韩遂曾与马腾结为异姓兄弟,后二人关系破裂。袁绍、曹操相争之际,马腾、韩遂被钟繇说服,依附于曹操。马腾入京后,留其子马超统领部队。马超推举韩遂为都督起兵反叛曹操,为曹操所败,韩遂逃奔凉州,后又为夏侯渊所败,病死(一说被杀),享年七十余岁。', - niujin:'牛金(生卒年不详),初为曹仁部曲将,周瑜军数万人来攻,前锋数千人始至,曹仁登城望,乃募得三百人,遣牛金迎战。但对方兵力较多,牛金遂被围困。曹仁亲自杀入阵中救出牛金。司马懿使牛金轻骑饵诱蜀军,刚交战诸葛亮就退兵,追至祁山。蜀将马岱入寇,司马懿遣将军牛金击退,斩千余级。公孙渊反,司马懿帅牛金、胡遵等步骑四万发自洛阳,后平定辽东。牛金官至后将军。', - jianggan:"蒋干,字子翼,汉末三国时期的人物,九江(治今安徽寿县)人。历史上的蒋干是当时的名士、辩论家。而罗贯中在历史小说《三国演义》中则将蒋干刻画成了被周瑜所愚弄的小丑形象。", + characterIntro: { + liupan: "刘磐(生卒年不详),山阳高平人,荆州牧刘表从子。与南阳人黄忠共守长沙攸县。为人骁勇,数次为寇于艾、西安诸县。江东孙策于是分海昏、建昌为左右六县,以东莱太史慈为建昌都尉,治海昏,并督诸将共拒刘磐。于是刘磐绝迹不复为寇。", + guotu: "郭图(?-205年),字公则,颍川(治今河南省禹州市)人。东汉末年袁绍帐下谋士。韩馥统冀州时,郭图与荀谌等人奉袁绍之命,说服韩馥让位。袁绍统一河北后,郭图与审配等人力劝袁绍统率大军攻打曹操。袁绍死后,袁尚继位。郭图与辛评为袁谭效力,挑唆袁谭攻击袁尚。建安十年(205年),郭图和袁谭一同被曹操所杀。", + tianchou: + "田畴(169年或170年-214年或216年),字子泰,东汉右北平郡无终人,东汉末年隐士。田畴好文习武。汉初平年间,其受刘虞派遣去长安,呈送指控公孙赞奏章,献帝大悦,封为骑都尉,田畴不受。携诏返回时,刘虞已被公孙所杀,田畴到刘墓祭拜,被公孙所提,不久释放。田畴回故乡后率家族及随从数百人隐居徐无山,致力农桑,数年间增至5000家。制定法条,兴建学校,一时民风良好,乌桓、鲜卑纷纷与其结交。汉建安二十年(207年),曹操北征乌桓,田畴请为向导。上徐无山、出卢龙、过平冈、登白狼堆、至柳城,曹军大胜,封田畴为亭侯,坚辞不受。曹念田功,四次封赏,终不受,乃拜为议郎。建安二十一年(216年),田畴去世。", + liyi: "李异(生卒年不详),三国时期东吴将领。建安末,与谢旌率水陆三千,击破刘备军将领詹晏、陈凤。刘备领兵攻孙权时,李异与陆逊等人屯巫、秭归,为蜀将所破。黄武元年(222年),陆逊破刘备于猇亭,李异追踪蜀军,屯驻南山。清代学者赵一清认为此李异与刘璋部将李异为同一人。", + caoyu: "曹宇(?-278年),字彭祖,沛国谯县(今安徽亳州)人。三国时期魏国宗室,魏武帝曹操与环夫人之子,邓哀王曹冲同母兄弟。太和六年,封为燕王。魏明帝病危,欲以大将军辅政,不果。其子常道乡公曹奂,是魏国末代皇帝,史称魏元帝。晋朝建立后,降封燕公。咸宁四年(278年),曹宇去世。", + zhangyan: + "张燕,本姓褚,生卒年不详,常山真定(今河北正定南)人,东汉末年黑山军首领。张燕剽捍,敏捷过人,军中称为“飞燕”。官渡之战时投降曹操,被任命为平北将军,封安国亭侯。死后其子张方袭爵。", + lushi: "卢氏,五斗米教主张衡妻,张鲁母,擅长驻颜之术,常年令自己保持少女的容颜。常拜访刘焉,与其交好。", + lvboshe: + "吕伯奢,东汉成皋(今河南荥阳)人,曹操父亲曹嵩的故友。曹操与陈宫在逃离董卓避祸,返回乡里的途中借宿于吕伯奢家,未伤其人,有贼八人欲捉曹操,曹操杀之,明罗贯中在历史小说《三国演义》中将这段历史进行了丑化加工,也成为小说中曹操名言“宁教我负天下人,休教天下人负我”的出处。", + caoxi: "曹羲(?-249年),字昭叔。曹真之子,曹爽之弟。为人有学识,明律法。司马懿曾组织朝议改革九品中正制废除九品而留中正,曹羲认为此举并无区别,最终都是决定于人的人治。曹爽掌权后,受封中领军,掌握禁兵,封安乡侯。曹爽及诸兄弟轻视司马懿,恣意妄为,经常外出狩猎,曹羲屡次劝谏,不被采纳。249年,司马懿发动高平陵政变,被夷三族。", + duanjiong: + "段颎(?-179年),字纪明,武威姑臧(今甘肃省武威市)人。东汉名将,西域都护段会宗从曾孙,与皇甫规(字威明)、张奂(字然明)并称“凉州三明”。段颎少时学习骑射,有文武智略,最初被举为孝廉,为宪陵园丞、阳陵令,有治理之才。汉桓帝时入军旅,先破鲜卑,后讨平东郭窦、公孙举起事,以功封列侯。延熹二年(159年)起戍边征战十余年,百战羌人,至永康元年(167年)平定西羌,建宁二年(169年)平定东羌,前后斩东西羌六万余级。累功封新丰县侯。建宁三年(170年),段颎被征入朝,历任侍中、执金吾、河南尹、司隶校尉等职,他党附宦官、捕杀太学生,因而得保富贵,两度出任太尉。光和二年(179年),权宦王甫罪行被揭发,段颎受牵连下狱,其后在狱中饮鸩而死。", + haopu: "郝普,字子太,义阳(治所在今湖北枣阳东南)人。刘备入川后,郝普为零陵太守。建安二十年(215年),吴将吕蒙进攻荆州三郡,唯有郝普坚守待援。但援兵久久不至,其挚友邓玄之又被吕蒙所骗,郝普也因此上当,投降吴国。湘水划界后,郝普回归刘备。建安二十四年(219年),吕蒙再次袭击荆州,击败关羽,郝普再次投降,最终归顺吴国并官至廷尉。郝普与隐蕃亲善,隐蕃蓄谋叛变事情败露,他受到牵连,因此自杀。在刘备集团的5个荆州郡守中,郝普是唯一一个抵抗过东吴的荆州郡守。", + ol_zhanghe: + "字儁乂,河间鄚人。三国时期魏国名将。官渡之战时,本为袁绍部将的张郃投降了曹操,并在曹操帐下多立功勋,于曹魏建立后加封为征西车骑将军。诸葛亮六出祁山之间,张郃多次抵御蜀军的进攻,于公元231年在木门道被诸葛亮设伏射死。后谥曰壮侯。为曹魏“五子良将”之一。", + zhangshiping: + "张世平是东汉末期的中山商人,曾与苏双同路,资助刘备组织武装、建立政权。于《三国演义》第一回出场,刘关张桃园三结义时资助刘备良马五十匹,金银五百两,镔铁一千斤。刘备所使用的“双股剑”、关羽所使用的“青龙偃月刀(又名‘冷艳锯’)”、张飞所使用的“丈八点钢矛(又名‘丈八蛇矛’)”皆由这一千斤上好镔铁打造而成。", + luoxian: + "罗宪(218年—270年),字令则,荆州襄阳(今湖北襄阳)人。西晋开国将领,巴东太守(郡府在永安白帝城)。于蜀汉灭亡后降魏,成功抵御孙吴的入侵,守住入魏国的要冲永安。后仕晋官至冠军将军、假节,封西鄂县侯。泰始六年(270年)去世,谥烈侯。", + sunhong: + "孙弘(?—252年),三国时期吴国大臣,扬州会稽(今浙江省绍兴市)人。官至吴国中书令、少傅。鲁王孙霸与太子孙和各植党羽,孙弘即依附孙霸。孙权病笃,而太子年少,于是以孙弘领少傅。孙权临终,召他与诸葛恪、孙峻等嘱以后事,孙弘与诸葛恪同为顾命大臣。孙权死后,孙弘因素来与诸葛恪不和,怕为所治,故而隐瞒了孙权的死讯,欲矫诏除掉诸葛恪,被孙峻告发。后诸葛恪请孙弘议事,于座中将其诛杀。", + wangguan: + "《三国演义》中虚构人物,历史上不曾记载。在114回出场,曾为邓艾手下参谋,献反间计与邓艾,被姜维识破,兵败自投江而死。", + maxiumatie: + "马休(?-212年),马铁(?-212年)。两人均为扶风茂陵(今陕西兴平)人,马腾之子,马超之弟。马腾遭韩遂进攻,乃携马休、马铁等入京受职。马休被封为奉车都尉,马铁被封为骑都尉。后在邺城居住。因兄马超反,两人被曹操夷灭。", + dongtuna: + "董荼那,小说《三国演义》及其衍生作品中的角色,南蛮王孟获属下大将,第二洞元帅;与阿会喃等人一起担任孟获的援军出征,但是被俘虏,又被诸葛亮释放,再次出战时,被唾骂不知羞耻,面红耳赤的退军。后同阿会喃共同绑架孟获献于蜀军,却被诸葛亮在其二人与孟获的重要性间权衡后出卖了他们,放走了孟获,使其为孟获所杀。", + zhanghua: + "张华(232年-300年),字茂先。范阳郡方城县(今河北固安)人。西晋时期政治家、文学家、藏书家,西汉留侯张良的十六世孙。张华出身范阳张氏,自少贫苦,因才学过人而受同乡名臣卢钦、刘放、阮籍等人的赞赏。在曹魏时,他历任太常博士、河南尹丞、佐著作郎、中书郎等职。西晋建立后,拜黄门侍郎,封关内侯,逐渐受到晋武帝的重用。后拜中书令,加散骑常侍,与大将杜预坚决支持武帝伐吴,于战时任度支尚书。吴国灭亡后,以功进封广武县侯。其后遭到排挤,出镇幽州,政绩卓然。之后返朝任太常,终武帝之世未得参与政事。晋惠帝继位后,累官至司空,封壮武郡公,被皇后贾南风委以朝政。张华尽忠辅佐,使天下仍然保持相对安宁。永康元年(300年),♯♯司马伦发动政变,张华惨遭杀害,年六十九。太安二年(303年),获得♯♯,追复官爵。张华工于诗赋,词藻华丽,又雅爱书籍,精于目录学,编纂有中国第一部博物学著作《博物志》;还曾与荀勖等人依照刘向《别录》整理典籍。《宣和书谱》载有其草书《得书帖》及行书《闻时帖》。《隋书·经籍志》有《张华集》十卷,今已佚。明人张溥辑有《张茂先集》。", + quhuang: + "屈晃(?—251),祖籍汝南(今河南省汝南县),汉末避乱南下,三国吴时居章安(今属椒江区)。初为郡吏,在职清廉,颇有政声。赤乌初年,擢为尚书仆射。", + macheng: "马承,蜀汉骠骑将军马超之子。仕蜀汉,马超死后继承其斄乡侯爵位。", + zhangzhi: + "张芝(?—192年),字伯英,敦煌郡渊泉县(今甘肃省瓜州县)人。东汉书法家、“草书之祖”,大司农张奂的儿子。出身名门,拒绝朝廷征召,潜心研习书法。擅长草书中的章草,将古代当时字字区别、笔画分离的草法,改为上下牵连富于变化的新写法,富有独创性,在当时影响很大。李志敏评价:“张芝创造了草书问世以来的第一座高峰,精熟神妙,兼善章今”。 没有真迹传世,仅存《八月帖》等刻帖。汉献帝初平三年,去世于家中,著有《笔心论》,与钟繇、王羲之和王献之并称“书中四贤”。", + ahuinan: + "阿会喃,小说《三国演义》及其衍生作品中的角色,南蛮王孟获属下大将,第三洞元帅;与董荼那等人一起担任孟获的援军出征,但是被俘虏,又被诸葛亮释放,再次出战时,被唾骂不知羞耻,面红耳赤的退军。后同董荼那共同绑架孟获献于蜀军,却被诸葛亮在其二人与孟获的重要性间权衡后出卖了他们,放走了孟获,使其为孟获所杀。", + xiahouxuan: + "夏侯玄(209年~254年),字泰初(《三国志》等作太初),沛国谯县(今安徽省亳州市)人。三国时期曹魏大臣、思想家、文学家,征南大将军夏侯尚之子,大将军曹爽的表弟。夏侯玄少年有名望,仪表出众,时人称为“朗朗如日月之入怀”。魏文帝黄初六年(225年),袭封昌陵乡侯。魏明帝时,历任散骑黄门侍郎、羽林监。少帝曹芳继位后,拜散骑常侍、中护军,保卫皇宫。后任征西将军,任内与曹爽策划骆谷之役,大失人心。高平陵政变后,被夺去兵权,改任大鸿胪、太常卿。嘉平六年(254年),中书令李丰与外戚张缉密谋杀死大将军司马师,改以夏侯玄执政。事泄被杀,夷灭三族,夏侯玄死时年仅四十六岁。著有文集三卷,如今已佚。政治上,提出了“审官择人”、“除重官”、“改服制”等制度,被太傅司马懿评价“皆大善”。博学多识,才华出众,精通玄学,成为“四聪”之一,与何晏等人开创了魏晋玄学的先河,是早期的玄学领袖人物。", + dengzhong: + "邓忠(不详-264年),三国时期曹魏名将邓艾之子。景元五年(264年),钟会谋反事败,士兵哗变,钟会被杀,邓艾部将想追还邓艾父子,但卫瓘却派田续追邓艾,于绵竹西相遇,将邓艾和邓忠等人杀死。直至泰始九年(273年)才恢复名节。", + wangyan: + "王衍(256年~311年),字夷甫,琅邪郡临沂县(今山东省临沂市)人。西晋末年重臣,玄学清谈领袖,曹魏幽州刺史王雄之孙、平北将军王乂之子、司徒王戎堂弟。王衍出身琅琊王氏。外表清明俊秀,风姿安详文雅,笃好老庄学说,颇有时名。步入仕途后,历任黄门侍郎、中领军、尚书令、尚书仆射等职。光熙元年(307年),升任司空。次年,又任司徒。王衍位高权重,却不思为国,为保全自己,还让弟弟王澄、族弟王敦分任荆州、青州刺史,遭时人鄙夷。王弥进攻洛阳时,王衍率军抵抗。其后转任太尉兼尚书令,又兼领太傅军司。永嘉五年(311年),东海王司马越去世,王衍奉其灵柩返回东海,途中为羯人石勒所俘获。王衍在与石勒交谈时,仍推脱责任,并劝其称帝,石勒大怒,将其与西晋旧臣一同活埋,时年五十六岁。王衍工书法,尤擅行书,《宣和书谱》有其作品《尊夫人帖》。", + caoxiancaohua: "请分别查看「曹宪」和「曹华」的武将介绍。", + zhaoyǎn: + "赵俨(171~245年),字伯然,颍川阳翟(今河南禹州市)。东汉末年颍川“四大名士”之一,三国时期魏国名臣。熟读经史,精明强干。建安二年,投靠大将军曹操之后,起家朗陵县令,历任司空府掾、司空主薄、都督护军、扶风太守等职。魏文帝曹丕继位后,历任魏国侍中、驸马都尉、河东太守、典农中郎将、度支尚书,封宜土亭侯。魏明帝曹睿时期,历任大司农、骠骑将军、大司空等职。正始六年,去世,时年七十五,谥号为穆。", + ruiji: "芮姬,芮玄之女,太子孙登妃,黄武五年卒。", + weizi: "卫兹(?-190年),字子许,(《三国演义》中其名为卫弘,当为误记),陈留襄邑(今河南睢县)人。曾举孝廉,先后被车骑将军何苗、司徒杨赐等召辟。中平六年(189年)十二月,曹操在陈留己吾募兵,而卫兹以家财资助曹操,使曹操顺利募得五千士兵。此后,卫兹与曹操共同讨伐董卓。初平元年(190年),卫兹在跟随曹操讨伐董卓途中,于荥阳汴水遭遇董卓军徐荣,力战终日,失利身亡。", + tengfanglan: + "滕芳兰,生卒年不详,北海剧县(今山东省寿光市)人,太常滕胤的族女,滕牧的女儿,吴末帝孙皓的皇后。永安元年(258年),孙皓为乌程侯时被聘为妃。元兴元年(264年),孙皓登基后被立为皇后。孙吴灭亡后,随孙皓迁居洛阳。", + qinghegongzhu: + "清河长公主,沛国谯县人,曹操长女(按其与曹操长子曹昂同出于刘夫人,而刘夫人又早死,故其年龄应长于曹丕等其他曹操诸子女,又按长公主亦有年最长之意,故应为曹操之长女)。母刘夫人,得到曹操喜爱。清河公主后来下嫁夏侯楙。曹操初欲嫁丁仪,曹丕劝其嫁与夏侯楙。后与小叔子设计欲谋害丈夫,未果。", + fanjiangzhangda: + "范强,在明朝小说《三国演义》里叫做范疆。二人均为张飞手下部将。蜀汉章武元年,刘备伐吴,张飞率军从阆中前往江州,出发前,范强和张达杀死张飞,带着张飞的首级投奔了东吴。", + tianyu: "田豫(171年~252年),字国让,渔阳雍奴(今天津市武清区)人。三国时期曹魏将领。初从刘备,因母亲年老回乡,后跟随公孙瓒,公孙瓒败亡,劝说鲜于辅加入曹操。曹操攻略河北时,田豫正式得到曹操任用,历任颖阴、郎陵令、弋阳太守等。后来田豫常年镇守曹魏北疆,从征代郡乌桓、斩骨进、破轲比能,多有功勋;也曾参与对孙吴的作战,在成山斩杀周贺,于新城击败孙权。官至太中大夫,封长乐亭侯。有一子田彭祖。", + wuyan: "吴国及西晋初年将领。初任通江县吏,后得到大司马陆抗的提拔重用,逐渐升至建平太守。", + fengfangnv: + "冯方之女,司隶人,袁术妻妾。在史书中被记载为天姿国色的美人。钱大昭在《三国志辨疑》中认为冯方当为冯芳误字,冯方女实为是西园八校尉之一的冯芳的女儿。然而,在曹丕《典论》、《九州春秋》等书籍都有提及她,皆作冯方女字样,并无一书写作冯芳女或是明提是冯芳之女。最关键的一点是,冯芳是荆州西陵县人,她女儿不可能是司隶籍,冯芳也没担任过任何与司隶有关的官职。同时期名字为“○女”的并不少见,如施绩女儿施淑女,曹植女儿曹行女,夏侯令女等。", + zuofen: "左芬(约253年-300年4月23日),出土墓志作左棻,字兰芝,齐国临淄(今山东临淄)人,西晋诗人。少好学,善属文。为晋武帝贵人。今存诗、赋、颂、赞、诔等20余篇,大都为应诏而作,《离思赋》最著名。原有集,已失传。", + duxi: "杜袭(生卒年不详),字子绪,颍川郡定陵县(今河南省襄城县)人。三国时期魏国重臣,东汉末年颍川“四大名士”之一,济阴太守杜根的孙子。建安初年,投奔司空曹操,历任西鄂县令、议郎、丞相军咨祭酒、魏王侍中、丞相长史、驸马都尉。魏文帝时期,出任督军粮御史、尚书,累封武平亭侯。魏明帝时期,担任大将军曹真和司马懿的军师,抵御蜀国进攻,拜太中大夫,受封平阳乡侯。卒于任上,获赠少府,谥号为定。", + gaogan: "高干(?~206年),字元才,陈留郡圉县(今河南杞县圉镇)人。东汉末年并州割据将领,蜀郡太守高躬之子、大将军袁绍外甥。出身陈留高氏,才志弘邈,文武秀出。早年联合荀谌游说韩馥让出冀州牧。袁绍平定河北后,以为并州牧。官渡之战时,在西线配合作战。因曹操早有准备,没有实质进展。袁绍死后,袁谭、袁尚与曹操大战于黎阳郡时,联合郭援攻打平阳郡,为马腾为首关中将领所败,郭援为庞德所斩。袁尚败走中山郡后,出降于曹操,仍为并州刺史。建安十年,兴兵反曹,固守壶关,成功抵挡乐进进攻。得知曹操亲征后,留下别将守城,亲往匈奴呼厨泉求救,没有成功。引兵攻略河东郡,屡为钟繇、张既所败。建安十一年,投奔荆州刘表。途经上洛时,为上洛都尉捕斩之。", + huangchengyan: + "黄承彦,生卒年不详,汉末三国时期沔阳名士,诸葛亮岳父,黄月英之父。南郡大士蔡讽的女婿,与襄阳名士上层社会圈子:庞统(凤雏)、庞德公、司马徽、徐庶等人交好。《襄阳记》:黄承彦者,高爽开列,为沔阳名士,谓诸葛孔明曰:“闻君择妇,身有丑女,黄头黑色,而才堪配。”孔明许,即载送之。时人以为笑乐,乡里为之谚曰:“莫作孔明择妇,正得阿承丑女。”", + panshu: "潘淑(?-252年),会稽句章(今浙江省宁波市)人,是吴大帝孙权的皇后,吴少帝孙亮的母亲。和孙权是中国历代帝后中年龄差距较大的一对。潘淑少时与姐姐俱没入织室,容媚有宠,拜为夫人,生有一子孙亮。赤乌十三年(250年),孙权立孙亮为皇太子,翌年(251年)立潘淑为皇后。神凤元年(252年)暴崩,合葬蒋陵。世称潘淑为江东绝色,有神女之称。", + zongyu: "宗预(?-264年),字德艳 ,荆州南阳郡安众县(今河南省南阳市)人。三国时期蜀汉官员、将领。曾随张飞入蜀助平益州,又受辟为丞相诸葛亮手下主簿,升任参军、右中郎将。诸葛亮逝世后,宗预受命出使孙吴,得到孙权的赞赏。迁后将军,出督永安,又升任征西大将军,并受封关内侯。公元258年(景耀元年),因病回成都,受任镇军大将军。蜀汉灭亡后,宗预随后主刘禅徙往洛阳,在中途病逝。宗预为人坦率耿直,多次出使孙吴并深得孙权的敬重,为吴、汉两国同盟的巩固作出了一定的贡献。", + mengda: "孟达(?-228),字子度,本字子敬,因刘备的叔父名叫刘子敬,为避讳而改字。扶风郡郿人,三国时期人物。本为刘璋属下,后降刘备。关羽围樊城、襄阳时因不发兵救关羽而触怒刘备,于是投奔曹魏。此后,劝降刘封,未果。在魏官至散骑常侍、建武将军,封平阳亭侯。此后又欲反曹魏而归蜀汉,事败而死。", + wolongfengchu: "沙比武将,懒得复制粘贴,自己去看「诸葛亮」和「庞统」的介绍吧。", + caoshuang: + "曹爽(?-249年2月9日),字昭伯,沛国谯县(今安徽亳州市)人。三国时期魏国权臣,大司马曹真长子。曹爽体态肥胖,凭借宗室身份,出入宫廷,交好太子曹叡。魏明帝即位,起家员外散骑侍郎,累迁城门校尉、散骑常侍,转武卫将军。太和五年(231年),袭封邵陵侯。景初三年(239年),魏明帝曹叡病危,拜大将军、假黄钺,与司马懿并为托孤大臣。少帝曹芳即位,加侍中,改封武安侯。势倾四海,声震天下。任用私人,专权乱政,侵吞公产。伐蜀失败,虚耗国力。起居逾制,软禁郭太后。正始十年,太傅司马懿发动高平陵政变,掌握魏国大权。曹爽失去大将军职务,以谋反之罪处死,夷灭三族。", + zhangling: + "张道陵(34年2月22日—156年),字辅汉,原名陵,道教正一道实际创立者,汉朝东汉时期丰邑(今江苏徐州丰县)人。太上老君降临蜀地,“授以三天正法,命为天师”,张道陵整合当时的:黄老派、方仙道、文始派等先秦修道团体,创立道教称正一盟威之道。后世尊称为“老祖天师”、“正一真人”、“三天扶教大法师”、高明上帝、张天师。著作《老子想尔注》,弟子有3000多人,设立24治,奠基天师道。张道陵、葛玄、许逊、萨守坚合称四大天师。张道陵创建道教的背景:当时在巴蜀一带,原有巴人信奉原始巫教,大规模的淫祀而害民。而这些祀奉鬼妖(学名为:妖邪)的法教巫师聚众敛财,无恶不作。张天师携王长、赵升二位弟子和黄帝九鼎丹经,来到北邙山修行,平定了那些祸害百姓的巫妖之教。川渝一带流传的张天师以太上老君剑印符箓大破鬼兵的故事就是以此为原型的。", + caiyang: + "蔡阳(?-201年),又作蔡扬,东汉丞相曹操部下武将,汝南太守。于建安六年(201)奉曹操之命攻击与刘备联合的汝南贼龚都等人,兵败被刘备所杀。明代小说《三国演义》改编为“云长擂鼓斩蔡阳”。", + pujing: "湖北省当阳境内有一座山,名叫玉泉山。东汉建安末年,山上住着一个老和尚,法名普净,普净原来是沂水关镇国寺方丈,后因云游天下,来到此处,风这地方山明水秀,就于山中结草为庵,每天坐禅参道,身边只有一个小和尚,外出化一些斋饭,供养师父。在《三国演义》中,当关羽通过汜水关时,正是由于普净提醒,关羽才揭穿了卞喜的阴谋,并杀死了卞喜。关羽死后,其怨魂亦在普净的指点下醒悟,放下了心中的仇恨,专心致力于造福一方百姓。", + huban: "为《三国演义》所杜撰的人物,正史无记载,荥阳太守王植麾下从事、桓帝时议郎胡华之子。关羽过五关斩六将时其中一关就是王植所镇守,胡班奉命放火夜袭关公,因敬服公之气概,并得其父托公所带家书,班看毕,叹曰:“险些误杀忠良!”故将之放走。胡班到荆州来投降关公,公念其旧日相救之情,甚爱之;令随费诗入川,见汉中王受爵。费诗辞别关公,带了胡班,自回蜀中去了。", + chunyuqiong: + "淳于琼(?-200年),字仲简,颍川(治今河南禹州)人。东汉时期官吏,于汉灵帝中平五年(188)被任命为西园八校尉之一的右校尉,与蹇硕、袁绍、鲍鸿、曹操、赵融、冯芳、夏牟同列。为袁绍大将,与张郃、高览等人齐名。在官渡之战时镇守乌巢,遭到曹操的偷袭而惨败,自己也被曹操处斩。", + lvkuanglvxiang: + "吕旷(生卒年不详),与吕翔同是袁绍属下,袁绍去世后,为袁尚守东平,后来投降曹操,并被封为列侯。在《三国演义》中,在曹操准备往南准备攻击前,两人跟著大将曹仁和将军李典准备要攻击刘备。但吕旷被赵云刺下马身亡,而吕翔也死于张飞矛下,可以算是出师未捷身先死", + caobuxing: + "曹不兴,亦名弗兴,三国时著名画家。孙吴吴兴(今浙江湖州)人,生卒年不详。他在黄武年间(222—229年)享有很大的声誉。被称为“佛画之祖”。与东晋顾恺之、南朝宋陆探微、南朝梁张僧繇并称“六朝四大家”。又与赵达的算术、严武的弈棋、皇象的草书等号称“吴中八绝”。曹不兴善画龙、虎、马及人物,有“落墨为蝇”等传奇故事,其佛画成就对后世影响很大,相传其所画龙头令谢赫叹服不已。画迹今已不存,据《贞观公私画史》载,作品有《青溪龙》、《赤盘龙》、《南海监牧进十种马图》、《夷事夷兽样》、《桃源图》等,惜早已散佚。但之后的著名画家卫协直接师承其法。", + gaolan: "高览,生卒年不详,一名高奂,本属袁绍部将,后官渡之战淳于琼被曹操击破,与张郃一同投降曹操,被封为偏将军,东莱侯。《三国演义》里,曾与许褚、徐晃大战不分胜负。201年刘备败走荆州时,高览奉命追杀,三合斩刘辟,而后被冲阵而来的赵云刺死。", + xunchen: + "荀谌,字友若,荀彧之兄(一说荀彧之弟),荀绲之子,颍川人。曾任军阀袁绍的幕僚。帮助袁绍游说韩馥,夺取了冀州。", + sunshao: + "孙邵(163年-225年),字长绪,青州北海国人(今山东潍坊市昌乐县西)。原为北海相孔融的功曹,被孔融称赞为可任朝廷要职的人才,后随刘繇到达江东,继而辅佐孙权。孙权称吴王后,孙邵成为吴国首任丞相,数年后病逝。由于孙邵和当时吴国史官的关系并不是很好,因此在史书中并没有详细的记载。", + yuantanyuanshang: + "袁谭、袁尚分别是袁绍的长子和第三子。袁绍坐拥青州、冀州、幽州、并州,本是北方最强诸侯,却于官渡大败,惭恨而终。虽然袁绍生前偏爱小儿子袁尚,却并未在继承人上有明确表态,这也导致本应以嫡长子身份继承的袁谭因郭图、审配伪立遗令未能如愿。曹操击败袁绍后,进而渡过黄河追击袁家残余势力,袁谭告急,但袁尚仅给他少量兵力。曹操得郭嘉之计退兵坐观其变,恰使两人此前的种种矛盾彻底爆发,袁谭不敌便引狼入室,派辛毗作为使者向曹操求援,让袁尚不得不北逃投奔乌桓。但袁谭也在之后背叛曹操兵败被杀。没多久,乌桓也被平定,袁熙、袁尚二人投奔公孙康后被斩首送还曹操。", + xujing: "许靖(?—222年),字文休。汝南郡平舆县(今河南省平舆县)人。汉末至三国蜀汉时期重臣、名士、评论家。许靖因与从弟许邵俱以品评人物而闻名于世。后被刘翊推举为孝廉,任尚书郎。曾先后投奔孔伷、陈祎、许贡、王朗等人,于孙策攻王朗前与家属俱避难交州,受到交趾太守士燮礼待。其后受益州牧刘璋邀请,相继为巴郡、广汉、蜀郡太守。于刘备包围成都时欲越墙叛逃,为刘璋所获。刘备定蜀后欲将其弃用,在法正的建议下方以其为左将军长史。建安二十三年(218年),刘备称汉中王,任命许靖为汉中王傅。章武元年(221年),刘备称帝,任命许靖为司徒,位列三公。章武二年(222年),去世。有文集二卷。", + hejin: "何进(?~189年),字遂高,南阳郡宛县(今河南南阳市宛城区)人。东汉时期外戚大臣,灵思皇后之兄。初以妹妹有宠,拜为郎中,出任虎贲中郎将、颍川太守,迁侍中、将作大匠、河南尹。黄巾起义时,拜为大将军,总镇京师,发现并镇压马元义的密谋,封为慎侯。为张大威望,在京师讲武结营,置西园八校尉。汉灵帝驾崩后,粉碎了中常侍蹇硕拥立皇子刘协的图谋,听从袁绍之言,博征智谋之士,内借元舅之资,外据辅政之权,独揽朝中大权。中平六年(189),不纳陈琳和曹操劝谏,阴结军阀董卓,联合袁绍谋诛宦竖。事情败露后,为中常侍张让等人损害,其后代是魏晋高门士族南阳何氏。", + hansui: "韩遂(?-215年),字文约。凉州金城郡人。东汉末年军阀、将领,汉末群雄之一。原名韩约,后改名遂。韩遂最初闻名于西州,被羌胡叛军劫持并推举为首领,以诛宦官为名举兵造反,聚众十万,先后败皇甫嵩、张温、董卓、孙坚等名将,使得天下骚动。后受朝廷招安,拥兵割据一方长达三十余年。韩遂曾与马腾结为异姓兄弟,后二人关系破裂。袁绍、曹操相争之际,马腾、韩遂被钟繇说服,依附于曹操。马腾入京后,留其子马超统领部队。马超推举韩遂为都督起兵反叛曹操,为曹操所败,韩遂逃奔凉州,后又为夏侯渊所败,病死(一说被杀),享年七十余岁。", + niujin: "牛金(生卒年不详),初为曹仁部曲将,周瑜军数万人来攻,前锋数千人始至,曹仁登城望,乃募得三百人,遣牛金迎战。但对方兵力较多,牛金遂被围困。曹仁亲自杀入阵中救出牛金。司马懿使牛金轻骑饵诱蜀军,刚交战诸葛亮就退兵,追至祁山。蜀将马岱入寇,司马懿遣将军牛金击退,斩千余级。公孙渊反,司马懿帅牛金、胡遵等步骑四万发自洛阳,后平定辽东。牛金官至后将军。", + jianggan: + "蒋干,字子翼,汉末三国时期的人物,九江(治今安徽寿县)人。历史上的蒋干是当时的名士、辩论家。而罗贯中在历史小说《三国演义》中则将蒋干刻画成了被周瑜所愚弄的小丑形象。", - caoying:"曹婴是在电影《三国志之见龙卸甲》中登场的虚拟人物,由李美琪饰演。曹婴是曹操的孙女,弓马娴熟,文武双全,深得曹操的用兵之道及心术。于凤鸣山一战中担任魏军大都督阻止诸葛亮北伐并因罗平安的告密而全歼关兴、张苞、赵云率领的蜀军部队。", - simahui:"司马徽(约145—208年),字德操,颍川阳翟(今河南禹州)人。东汉末年名士,精通道学、奇门、兵法、经学。有“水镜先生”之称。 司马徽为人清雅,学识广博,有知人之明,并向刘备推荐了诸葛亮、庞统等人,受到世人的敬重。", - baosanniang:"鲍三娘是中国民间传说中的人物,事迹多见于《花关索传》。相传她是鲍家庄鲍员外的小女儿。后来与关索成亲,关羽自传授其武艺,因此也造就了鲍三娘的文武双全。荆州失守之后鲍三娘就跟随关索一同投奔蜀汉,并随诸葛亮征讨南蛮。平定了南蛮之后,夫妻二人就此一直替诸葛亮镇守着南中,他们也的确留下了许多脍炙人口的行侠仗义故事,在民间广为流传。", + caoying: + "曹婴是在电影《三国志之见龙卸甲》中登场的虚拟人物,由李美琪饰演。曹婴是曹操的孙女,弓马娴熟,文武双全,深得曹操的用兵之道及心术。于凤鸣山一战中担任魏军大都督阻止诸葛亮北伐并因罗平安的告密而全歼关兴、张苞、赵云率领的蜀军部队。", + simahui: + "司马徽(约145—208年),字德操,颍川阳翟(今河南禹州)人。东汉末年名士,精通道学、奇门、兵法、经学。有“水镜先生”之称。 司马徽为人清雅,学识广博,有知人之明,并向刘备推荐了诸葛亮、庞统等人,受到世人的敬重。", + baosanniang: + "鲍三娘是中国民间传说中的人物,事迹多见于《花关索传》。相传她是鲍家庄鲍员外的小女儿。后来与关索成亲,关羽自传授其武艺,因此也造就了鲍三娘的文武双全。荆州失守之后鲍三娘就跟随关索一同投奔蜀汉,并随诸葛亮征讨南蛮。平定了南蛮之后,夫妻二人就此一直替诸葛亮镇守着南中,他们也的确留下了许多脍炙人口的行侠仗义故事,在民间广为流传。", - pangdegong:"庞德公,字尚长,荆州襄阳人,东汉末年名士、隐士。 庞德公与当时徐庶、司马徽、诸葛亮、庞统等人交往密切。庞德公曾称诸葛亮为\"卧龙\",庞统为\"凤雏\",司马徽为\"水镜\",被誉为知人。对诸葛亮、庞统等人早年影响较大,并得到诸葛亮的敬重。庞德公最后隐居于鹿门山,采药而终。", - zhaotongzhaoguang:"赵统,赵云长子,生卒年不详。常山真定(今为河北正定)人,陈寿在正史《三国志》中记载赵云去世后,赵统袭爵永昌亭侯,官至蜀汉虎贲中郎督,加行领军。赵广(?—263年),三国时期蜀汉牙门将,赵云的次子,赵统之弟。随姜维前往沓中,官拜牙门将。曹魏司马氏派五路大军伐蜀时,随大将军姜维与魏兵战于疆川口,姜维败绩还守剑阁,赵广于沓中战死。", - majun:"马钧,字德衡,扶风(今陕西扶风)人,生活在汉朝末期,是中国古代科技史上最负盛名的机械发明家之一。马钧年幼时家境贫寒,自己又有口吃的毛病,所以不擅言谈却精于巧思,后来在魏国担任给事中的官职。马钧最突出的表现有还原指南车;改进当时操作笨重的织绫机;发明一种由低处向高地引水的龙骨水车;制作出一种轮转式发石机,能连续发射石块,远至数百步;把木制原动轮装于木偶下面,叫做“水转百戏”。此后,马钧还改制了诸葛连弩,对科学发展和技术进步做出了贡献。", - simazhao:"司马昭(211年—265年9月6日),字子上(小说《三国演义》为子尚),河内温县(今属河南)人。三国时期曹魏权臣,西晋王朝的奠基人之一。为晋宣帝司马懿与宣穆皇后张春华次子、晋景帝司马师之弟、晋武帝司马炎之父。 司马昭早年随父抗击蜀汉,多有战功。累官洛阳典农中郎将,封新城乡侯。正元二年(255年),继兄司马师为大将军,专揽国政。甘露五年(260年),魏帝曹髦被弑杀,司马昭立曹奂为帝。景元四年(263年),分兵遣钟会、邓艾、诸葛绪三路灭亡蜀汉,受封晋公。次年,进爵晋王。 咸熙二年(265年),司马昭病逝,年五十四,葬于崇阳陵。数月后,其子司马炎代魏称帝,建立晋朝,追尊司马昭为文帝,庙号太祖。", - wangyuanji:"王元姬(217年—268年4月20日),东海郯县(今山东郯城西北)人。三国时期曹魏经学家王朗之孙女、王肃之女,晋文帝司马昭妻子,晋武帝司马炎与齐王司马攸的生母。 王元姬幼时便通《诗经》、《论语》,嫁司马昭后竭尽妇道、谦虚谨慎。其人颇有远见,曾预言钟会谋反之事。泰始元年(265年),司马炎建立西晋,尊王元姬为皇太后,宫号曰崇化宫。王元姬身处太后之位,提倡节俭,身体力行,作为众妃子的表率。在其治理之下,后宫井井有条,众人和睦相处。 泰始四年(268年),王元姬崩逝,终年五十二岁。谥号文明皇后,与司马昭合葬于崇阳陵。", + pangdegong: + '庞德公,字尚长,荆州襄阳人,东汉末年名士、隐士。 庞德公与当时徐庶、司马徽、诸葛亮、庞统等人交往密切。庞德公曾称诸葛亮为"卧龙",庞统为"凤雏",司马徽为"水镜",被誉为知人。对诸葛亮、庞统等人早年影响较大,并得到诸葛亮的敬重。庞德公最后隐居于鹿门山,采药而终。', + zhaotongzhaoguang: + "赵统,赵云长子,生卒年不详。常山真定(今为河北正定)人,陈寿在正史《三国志》中记载赵云去世后,赵统袭爵永昌亭侯,官至蜀汉虎贲中郎督,加行领军。赵广(?—263年),三国时期蜀汉牙门将,赵云的次子,赵统之弟。随姜维前往沓中,官拜牙门将。曹魏司马氏派五路大军伐蜀时,随大将军姜维与魏兵战于疆川口,姜维败绩还守剑阁,赵广于沓中战死。", + majun: "马钧,字德衡,扶风(今陕西扶风)人,生活在汉朝末期,是中国古代科技史上最负盛名的机械发明家之一。马钧年幼时家境贫寒,自己又有口吃的毛病,所以不擅言谈却精于巧思,后来在魏国担任给事中的官职。马钧最突出的表现有还原指南车;改进当时操作笨重的织绫机;发明一种由低处向高地引水的龙骨水车;制作出一种轮转式发石机,能连续发射石块,远至数百步;把木制原动轮装于木偶下面,叫做“水转百戏”。此后,马钧还改制了诸葛连弩,对科学发展和技术进步做出了贡献。", + simazhao: + "司马昭(211年—265年9月6日),字子上(小说《三国演义》为子尚),河内温县(今属河南)人。三国时期曹魏权臣,西晋王朝的奠基人之一。为晋宣帝司马懿与宣穆皇后张春华次子、晋景帝司马师之弟、晋武帝司马炎之父。 司马昭早年随父抗击蜀汉,多有战功。累官洛阳典农中郎将,封新城乡侯。正元二年(255年),继兄司马师为大将军,专揽国政。甘露五年(260年),魏帝曹髦被弑杀,司马昭立曹奂为帝。景元四年(263年),分兵遣钟会、邓艾、诸葛绪三路灭亡蜀汉,受封晋公。次年,进爵晋王。 咸熙二年(265年),司马昭病逝,年五十四,葬于崇阳陵。数月后,其子司马炎代魏称帝,建立晋朝,追尊司马昭为文帝,庙号太祖。", + wangyuanji: + "王元姬(217年—268年4月20日),东海郯县(今山东郯城西北)人。三国时期曹魏经学家王朗之孙女、王肃之女,晋文帝司马昭妻子,晋武帝司马炎与齐王司马攸的生母。 王元姬幼时便通《诗经》、《论语》,嫁司马昭后竭尽妇道、谦虚谨慎。其人颇有远见,曾预言钟会谋反之事。泰始元年(265年),司马炎建立西晋,尊王元姬为皇太后,宫号曰崇化宫。王元姬身处太后之位,提倡节俭,身体力行,作为众妃子的表率。在其治理之下,后宫井井有条,众人和睦相处。 泰始四年(268年),王元姬崩逝,终年五十二岁。谥号文明皇后,与司马昭合葬于崇阳陵。", - liuye:'刘晔(?-234年),字子扬,淮南成德人,是光武帝刘秀之子阜陵王刘延的后代,三国时期魏国著名的战略家。刘晔年少知名,人称有佐世之才,是曹操手下举足轻重的谋士,他屡献妙计,对天下形势的发展往往一语中的。刘晔历仕数朝,是曹魏的三朝元老。', - luzhi:'鲁芝(190年—273年),字世英。扶风郡郿县(今陕西眉县)人。魏晋时期名臣。官至光禄大夫,位特进,封阴平侯。泰始九年(273年)卒,时年八十四。谥号“贞”。', - xizhicai:'戏志才(生卒年不详),或志才为字,名不详(一说名忠),东汉颍川郡(今河南禹州)人。经张邈推荐,成为曹操手下谋士。为人多谋略,曹操十分器重,不幸早卒。三国演义中并无此人,三国志中只有寥寥数语。由荀彧推荐给曹操,被称为有“负俗之讥”。死后,荀彧又举荐了郭嘉。
              陈寿《三国志》记载:太祖与荀彧书曰:自志才亡后,莫可与计事者。汝、颍固多奇士,谁可以继之?彧荐嘉。', - sunqian:'孙乾(?—约215年),字公祐。北海郡(治今山东昌乐西)人。东汉末年刘备的幕僚。最初被大儒郑玄推荐于州里。刘备领徐州,以孙乾为从事。自徐州跟随刘备,多次作为刘备的使臣。刘备定益州后,拜孙乾为秉忠将军,其待遇仅次于麋竺,与简雍相同。不久后便病逝。', - miheng:'祢衡(173年-198年),字正平,平原郡(今山东德州临邑德平镇)人。个性恃才傲物.和孔融交好。孔融著有《荐祢衡表》,向曹操推荐祢衡,但是祢衡称病不肯去,曹操封他为鼓手,想要羞辱祢衡,却反而被祢衡裸身击鼓而羞辱。后来祢衡骂曹操,曹操就把他遣送给刘表,祢衡对刘表也很轻慢,刘表又把他送去给江夏太守黄祖,最后因为和黄祖言语冲突而被杀,时年二十六岁。黄祖对杀害祢衡一事感到十分后悔,便将其加以厚葬。', - quyi:'麴义(又作曲义、鞠义),生卒年不详,是东汉末年军阀袁绍部下的将领,能征善战,屡建战功,早年在凉州,精通羌人战法,率领着袁绍的精锐部队。后来由于自恃功高而骄纵不轨,被袁绍所杀。', - taoqian:'陶谦(132年-194年),字恭祖。丹阳郡(治今安徽宣城)人。汉末群雄之一。陶谦最初为诸生,在州郡任职,被举茂才,历任舒、卢二县令、幽州刺史、议郎,性格刚直,有大志。后随左车骑将军皇甫嵩对抗北宫伯玉,任扬武校尉,之后又随张温征韩遂、边章。中平五年(188年),徐州黄巾起,陶谦被朝廷任为徐州刺史,击破徐州黄巾,并推行屯田,恢复生产。尔后听从王朗、赵昱建议遣使进京朝贡,获拜安东将军、徐州牧,封溧阳侯。晚年因战事上为曹操大败,徐州大半几乎遭兵祸所害,以致过度忧劳而逝,终年六十三岁。', - wangyun:'王允(137~192年),字子师,太原郡祁县(今山西祁县)人。东汉末年时期大臣。出身太原王氏,世代官宦。举孝廉出身,司徒高第征为侍御史。出任豫州刺史,勤政爱民。斗争中常侍张让失败后,去官隐居。中平六年,大将军何进掌权之后,辟为从事中郎,迁河南尹。董卓拥立汉献帝即位后,代替杨彪,拜太仆、尚书令、司徒,密谋刺死董卓,联合吕布共同执政,日益骄傲自满。初平三年(192年),董卓余党李傕、郭汜、樊稠等攻破长安。王允兵败处死,时年五十六岁。', - bianfuren:'武宣皇后卞氏(159年12月30日-230年7月9日),琅邪开阳(今山东临沂)人,魏武帝曹操的正妻(继室),魏文帝曹丕、任城威王曹彰、陈思王曹植、萧怀王曹熊的母亲。原本是倡家,即汉代专门从事音乐歌舞的乐人家庭,后来与曹操成婚,建安初年,原配丁夫人被废,卞夫人成为曹操的正妻。曹丕继位后尊其为皇太后,曹叡继位后尊其为太皇太后。卞后在太和四年去世,与魏武帝曹操合葬高陵。', - shamoke:'沙摩柯(?-222年),东汉末三国时期五溪蛮首领。汉章武元年(221年)初,为报关羽被东吴杀害之仇,刘备亲自领兵攻孙权,以金锦爵赏诱沙摩柯助战。章武二年(222年),吴大都督陆逊以火攻破刘备,率诸军齐击,汉军四十多个营寨被攻破,沙摩柯在大乱中匹马奔逃,被乱军杀死。', - lvfan:'吕范(?-228年),字子衡。汝南郡细阳县(今安徽太和)人。汉末至三国时期吴国重臣。吕范年轻为汝南县吏,后避难寿春,结识孙策。此后随孙策、孙权征伐四方,对稳固孙氏在江东的统治做出了杰出的贡献,孙权将其比之于东汉开国元勋吴汉。吴国建立后,吕范累官至前将军、假节、扬州牧,封南昌侯。黄武七年(228年),吕范被拜为大司马,未得授官,便已病逝。孙权悲痛不已,遣使赠其大司马印绶。孙权还都建业后,以太牢礼祭祀吕范。', - liqueguosi:"请分别查看「李傕」和「郭汜」的武将介绍。", - maojie:"毛玠(?—216年),字孝先,陈留平丘(今河南封丘)人。东汉末年大臣。年少时为县吏,以清廉公正著称。因战乱而打算到荆州避乱,但中途知道刘表政令不严明,因而改往鲁阳。后来投靠曹操,提出“奉天子以令不臣,脩耕植,畜军资”的战略规划,得到曹操的欣赏。
              毛玠与崔琰主持选举,所举用的都是清廉正直之士。而毛玠为人廉洁,激起天下廉洁之风,一改朝中奢华风气。曹操大为赞赏,曹丕也亲自去拜访他。
              曹操获封魏公后,毛玠改任尚书仆射,再典选举。又密谏曹操应该立嫡长子曹丕为魏国太子。崔琰被杀后,毛玠十分不快。后来有人诬告毛玠,曹操大怒,将毛玠收于狱中。及后在桓阶、和洽营救下,只被免职,不久逝世于家中。曹操在他死后赐他棺材和钱帛。", + liuye: "刘晔(?-234年),字子扬,淮南成德人,是光武帝刘秀之子阜陵王刘延的后代,三国时期魏国著名的战略家。刘晔年少知名,人称有佐世之才,是曹操手下举足轻重的谋士,他屡献妙计,对天下形势的发展往往一语中的。刘晔历仕数朝,是曹魏的三朝元老。", + luzhi: "鲁芝(190年—273年),字世英。扶风郡郿县(今陕西眉县)人。魏晋时期名臣。官至光禄大夫,位特进,封阴平侯。泰始九年(273年)卒,时年八十四。谥号“贞”。", + xizhicai: + "戏志才(生卒年不详),或志才为字,名不详(一说名忠),东汉颍川郡(今河南禹州)人。经张邈推荐,成为曹操手下谋士。为人多谋略,曹操十分器重,不幸早卒。三国演义中并无此人,三国志中只有寥寥数语。由荀彧推荐给曹操,被称为有“负俗之讥”。死后,荀彧又举荐了郭嘉。
              陈寿《三国志》记载:太祖与荀彧书曰:自志才亡后,莫可与计事者。汝、颍固多奇士,谁可以继之?彧荐嘉。", + sunqian: + "孙乾(?—约215年),字公祐。北海郡(治今山东昌乐西)人。东汉末年刘备的幕僚。最初被大儒郑玄推荐于州里。刘备领徐州,以孙乾为从事。自徐州跟随刘备,多次作为刘备的使臣。刘备定益州后,拜孙乾为秉忠将军,其待遇仅次于麋竺,与简雍相同。不久后便病逝。", + miheng: "祢衡(173年-198年),字正平,平原郡(今山东德州临邑德平镇)人。个性恃才傲物.和孔融交好。孔融著有《荐祢衡表》,向曹操推荐祢衡,但是祢衡称病不肯去,曹操封他为鼓手,想要羞辱祢衡,却反而被祢衡裸身击鼓而羞辱。后来祢衡骂曹操,曹操就把他遣送给刘表,祢衡对刘表也很轻慢,刘表又把他送去给江夏太守黄祖,最后因为和黄祖言语冲突而被杀,时年二十六岁。黄祖对杀害祢衡一事感到十分后悔,便将其加以厚葬。", + quyi: "麴义(又作曲义、鞠义),生卒年不详,是东汉末年军阀袁绍部下的将领,能征善战,屡建战功,早年在凉州,精通羌人战法,率领着袁绍的精锐部队。后来由于自恃功高而骄纵不轨,被袁绍所杀。", + taoqian: + "陶谦(132年-194年),字恭祖。丹阳郡(治今安徽宣城)人。汉末群雄之一。陶谦最初为诸生,在州郡任职,被举茂才,历任舒、卢二县令、幽州刺史、议郎,性格刚直,有大志。后随左车骑将军皇甫嵩对抗北宫伯玉,任扬武校尉,之后又随张温征韩遂、边章。中平五年(188年),徐州黄巾起,陶谦被朝廷任为徐州刺史,击破徐州黄巾,并推行屯田,恢复生产。尔后听从王朗、赵昱建议遣使进京朝贡,获拜安东将军、徐州牧,封溧阳侯。晚年因战事上为曹操大败,徐州大半几乎遭兵祸所害,以致过度忧劳而逝,终年六十三岁。", + wangyun: + "王允(137~192年),字子师,太原郡祁县(今山西祁县)人。东汉末年时期大臣。出身太原王氏,世代官宦。举孝廉出身,司徒高第征为侍御史。出任豫州刺史,勤政爱民。斗争中常侍张让失败后,去官隐居。中平六年,大将军何进掌权之后,辟为从事中郎,迁河南尹。董卓拥立汉献帝即位后,代替杨彪,拜太仆、尚书令、司徒,密谋刺死董卓,联合吕布共同执政,日益骄傲自满。初平三年(192年),董卓余党李傕、郭汜、樊稠等攻破长安。王允兵败处死,时年五十六岁。", + bianfuren: + "武宣皇后卞氏(159年12月30日-230年7月9日),琅邪开阳(今山东临沂)人,魏武帝曹操的正妻(继室),魏文帝曹丕、任城威王曹彰、陈思王曹植、萧怀王曹熊的母亲。原本是倡家,即汉代专门从事音乐歌舞的乐人家庭,后来与曹操成婚,建安初年,原配丁夫人被废,卞夫人成为曹操的正妻。曹丕继位后尊其为皇太后,曹叡继位后尊其为太皇太后。卞后在太和四年去世,与魏武帝曹操合葬高陵。", + shamoke: + "沙摩柯(?-222年),东汉末三国时期五溪蛮首领。汉章武元年(221年)初,为报关羽被东吴杀害之仇,刘备亲自领兵攻孙权,以金锦爵赏诱沙摩柯助战。章武二年(222年),吴大都督陆逊以火攻破刘备,率诸军齐击,汉军四十多个营寨被攻破,沙摩柯在大乱中匹马奔逃,被乱军杀死。", + lvfan: "吕范(?-228年),字子衡。汝南郡细阳县(今安徽太和)人。汉末至三国时期吴国重臣。吕范年轻为汝南县吏,后避难寿春,结识孙策。此后随孙策、孙权征伐四方,对稳固孙氏在江东的统治做出了杰出的贡献,孙权将其比之于东汉开国元勋吴汉。吴国建立后,吕范累官至前将军、假节、扬州牧,封南昌侯。黄武七年(228年),吕范被拜为大司马,未得授官,便已病逝。孙权悲痛不已,遣使赠其大司马印绶。孙权还都建业后,以太牢礼祭祀吕范。", + liqueguosi: "请分别查看「李傕」和「郭汜」的武将介绍。", + maojie: "毛玠(?—216年),字孝先,陈留平丘(今河南封丘)人。东汉末年大臣。年少时为县吏,以清廉公正著称。因战乱而打算到荆州避乱,但中途知道刘表政令不严明,因而改往鲁阳。后来投靠曹操,提出“奉天子以令不臣,脩耕植,畜军资”的战略规划,得到曹操的欣赏。
              毛玠与崔琰主持选举,所举用的都是清廉正直之士。而毛玠为人廉洁,激起天下廉洁之风,一改朝中奢华风气。曹操大为赞赏,曹丕也亲自去拜访他。
              曹操获封魏公后,毛玠改任尚书仆射,再典选举。又密谏曹操应该立嫡长子曹丕为魏国太子。崔琰被杀后,毛玠十分不快。后来有人诬告毛玠,曹操大怒,将毛玠收于狱中。及后在桓阶、和洽营救下,只被免职,不久逝世于家中。曹操在他死后赐他棺材和钱帛。", - huangfusong:'字义真。安定郡朝那县(今宁夏彭阳)人。于黄巾起义时,以中郎将身份讨伐黄巾,用火攻大破张梁、张宝。后接替董卓进攻张梁,连胜七阵。掘张角墓,拜左车骑将军、冀州牧,因拒绝贿赂宦官而被免职。 董卓死,王允命其与吕布等共至郿坞抄籍董卓家产、人口,皇甫嵩将坞中所藏良家子女,尽行释放。', - zangba:'其父臧戒,有二子臧艾与臧舜。年少时曾召集数人将获罪的父亲救出,此后四处流亡。后来成为陶谦麾下的骑都尉,负责募兵抵抗黄巾军。与孙观、尹礼等人拥兵驻屯于开阳,自成一股独立势力,后跟随吕布。吕布战败后,投降了曹操。后与袁绍、孙权等的战役里战功赫赫,官至镇东将军。', - zhangren:'刘璋的属下,以忠勇著称。刘备入蜀时,张任曾劝刘璋提防刘备,但刘璋没有听从。魏延舞剑想趁机除掉刘璋时,张任出面对舞,解救刘璋。后在刘备进攻时于落凤坡射死了庞统。', - jiling:'东汉末年袁术帐下将领,勇猛非常,曾奉命率军攻打小沛的刘备,在吕布辕门射戟的调停下撤兵。', - zoushi:'军阀张济之妻,张绣之婶。张绣降曹后,邹氏遂被曹操霸占。贾诩献计趁机诛杀曹操,险些得手。曹操在损失爱将典韦、侄子曹安民和长子曹昂后方才逃出生天。', - ganfuren:'刘备起兵后,于沛城娶甘氏为妾。后来,甘夫人随刘备到荆州,生了阿斗(也就是后主刘禅)。223年四月,刘备病死于白帝城,追谥甘夫人为“昭烈皇后”。', - jiangfei:'请分别查看「蒋琬」和「费袆」的武将介绍。', - mifuren:'刘备夫人。徐州别驾糜竺之妹。长坂兵败,她怀抱年仅两岁的刘禅在乱军中走散,被赵云发现;但麋夫人因为赵云只有一匹马,不肯上马,在将阿斗托付给赵云后投井而亡。', - chendong:'陈武,东吴将领,孙策攻打刘繇,陈武前来相助,孙策非常喜爱陈武,拜为校尉,使作先锋。陈武以十数骑兵力杀敌五十余人。后于赤壁等战役屡立功勋。董袭献上严虎的人头来降孙策。赤壁之战,董袭受周瑜命,分兵去汉阳,合肥会战时接应太史慈,逍遥津支援孙权。濡须口之战时,董袭在船上督战,船覆董袭坚守殉职。', - jiangqing:'擅长弓术。与周泰原为活跃于长江一带的江贼,孙策脱离袁术下江东自立门户时,和周泰一起率众投靠。 孙策攻刘繇,并引出城中麾下的陈横、薛礼、张英三名将领,陈横后被蒋钦一箭射杀,后与韩当等将乘舟过江,乱箭射杀敌军。曾在赤壁之战与周泰,还有擅使长枪的韩当率领水军在三江口踏江破敌。', - kongrong:'字文举,鲁国人,东汉文学家,“建安七子”之首。献帝即位后任北军中侯、虎贲中郎将、北海相,时称孔北海后因触怒曹操,为曹操所杀。能诗善文。', - mateng:'字寿成,扶风茂陵人,东汉末年征西将军,割据西凉一带的军阀,伏波将军马援的后代,官至卫尉,封爵槐里乡侯。因其子马超谋反,而被杀,夷灭三族。', - tianfeng:'字元皓。东汉末年大军阀袁绍部下重要谋士。为人刚直不阿,曾多次向袁绍进言而不被采纳。后因谏阻袁绍征伐曹操而被袁绍下令监禁,并于官渡之战后,被袁绍杀害。', - caochun:'字子和,沛国谯(今安徽亳州)人。东汉末年曹操麾下将领,曹仁之弟。曹纯是曹操部下精锐部队“虎豹骑”的统领者之一,因在平定北方的战役中颇有功绩,被加封为高陵亭侯。死后谥曰威侯。曹纯擅战,甚得人心,为人重纲纪,不失理智,好学问,敬爱学士,闻名天下。', - hanba:'中国古代神话传说中引起旱灾的怪物。《诗·大雅·云汉》:“旱魃为虐,如惔如焚。”', - cuiyan:'字季珪,清河东武城(今河北省清河县)人。东汉末年名士,司空崔林的从兄,曹操帐下谋士。崔琰相貌俊美,很有威望,曹操对他也很敬畏。建安二十一年(216年),崔琰在给杨训的书信中写道“时乎时乎,会当有变时”,曹操认为此句有不逊之意,因而将崔琰下狱,不久崔琰即被曹操赐死。', - lifeng:'南阳(治今河南南阳)人,三国时期蜀汉大臣李严之子。230年,李严迁为骠骑将军,率军前往汉中,诸葛亮上表推举李丰为江州都督督军,以代替李严管理后方事务。李严去世后,李丰在蜀汉官至朱提太守。', - sunru:'孙茹,孙坚之妹,其名载于《江浙通志》中。儿子徐琨亦为孙吴早期名将,当初母子二人随军跟从孙策渡长江时,因为暂时没足够的船,孙策感到苦恼打算暂时驻军江边。孙茹夫人献计以芦苇为筏,孙策大喜。吴军遂以神不知鬼不觉的速度过长江击破刘繇部将张英,立下平江东第一功。', - lingcao:'东汉末年将领,吴郡余杭(今浙江余杭)人,凌统之父。早年跟随孙策转战江东。孙权统军后,凌操随其征伐黄祖,被甘宁射杀。《吴书》载:甘宁以善射,将兵在后,射杀校尉凌操', - zhugeguo:'诸葛果,为《历代神仙通鉴》中诸葛亮女儿的名字,《历代神仙通鉴》记录从上古到明代的神仙历史,因此诸葛果不见于任何史书。成都西南有朝真观,即乘烟观。相传,诸葛果在这里修行后成仙升天。', - zhuling:'朱灵(生卒年不详),字文博,冀州清河国人,三国时期曹魏名将。官至后将军,封为高唐侯,谥号威侯。初为袁绍部将,后归顺曹操,随曹操征伐四方,屡建战功。', - re_yuanshu:'字公路,汝南汝阳人,袁绍之弟。初为虎贲中郎将。董卓进京后以袁术为后将军,袁术因畏祸而出奔南阳。初平元年与袁绍、曹操等同时起兵,共讨董卓。后与袁绍对立,被袁绍、曹操击败,率馀众奔九江,割据扬州。建安二年称帝,建号仲氏。', - fuwan:'伏完(?-209),琅邪东武(今属山东)人,东汉末大臣,汉献帝伏皇后之父。历官辅国将军、中散大夫、屯骑校尉。', - liuxie:'字伯和,又字合。汉族,祖籍沛县,生于洛阳。汉灵帝第三子,被董卓迎立为帝。董卓被王允和吕布诛杀后,董卓部将李傕等攻入长安,再次挟持了他,后来逃出长安。公元196年,曹操控制了刘协,并迁都许昌,“挟天子以令诸侯”。公元220年,曹操病死,刘协被曹丕控制,随后被迫禅让于曹丕。', - yuanshu:'字公路,汝南汝阳人,袁绍之弟。初为虎贲中郎将。董卓进京后以袁术为后将军,袁术因畏祸而出奔南阳。初平元年与袁绍、曹操等同时起兵,共讨董卓。后与袁绍对立,被袁绍、曹操击败,率馀众奔九江,割据扬州。建安二年称帝,建号仲氏。', - gongsunzan:'字伯珪,汉族,号“白马义从”。辽西令支人。东汉末年献帝年间占据幽州一带的军阀,汉末群雄之一。出身贵族,因母地位卑贱,只当了郡中小吏。他貌美,声音洪亮,机智善辩。后随卢植于缑氏山中读书,粗通经传。', - caohong:'字子廉,沛国谯(今安徽亳县)人,曹操从弟,曾献马并救护曹操。后多随军征伐,平兖州、征刘表、讨祝臂。曹丕即位时封曹洪为骠骑将军。曹叡即位,拜曹洪为后将军,更封乐城侯,后复拜为骠骑将军。曹洪逝世,追谥曰恭侯。', - guanyinping:'河东解县(今山西运城)人,美髯公关羽之女。因在关羽的四个子女中排行第三,故又被称作“关三小姐”、“关氏三姐”或“关羽三小姐”。传说她是赵云的弟子、并随同诸葛亮平定南蛮。', - xiahouba:'夏侯渊次子。本为曹魏武将,后因司马懿诛曹爽一族,夏侯霸身为曹氏宗室而心怀不安,遂投降蜀汉。后随蜀将姜维北伐,官至车骑将军。', - daxiaoqiao:'大乔,庐江皖县人,为乔公长女,孙策之妻,容貌国色流离。小乔为大乔之妹,周瑜之妻,资貌绝伦。两人合称“二乔”。', - yuejin:'字文谦,魏“五子良将”之一。容貌短小,以胆烈跟从曹操,南征北讨,战功无数。从击袁绍于官渡,奋勇力战,斩袁绍部将淳于琼。又从击袁绍子谭、尚于黎阳,斩其大将严敬。从平荆州,留屯襄阳,进击关羽、苏非等人,击退其众,南郡诸郡的山谷蛮夷都前往乐进处投降。后来从曹操征孙权,假进节。曹操回师后,留乐进与张辽、李典屯于合肥。又以乐进数有军功,迁右将军。建安二十三年逝世,谥曰威侯。', - caoang:'字子修,曹操的长子,由于性情谦和且聪慧所以深得曹操喜爱。曹操征讨张绣时,羞辱张绣之婶邹氏,被张绣突然袭击。曹昂为保护曹操撤退,与典韦一起战死在宛城。', - zhugejin:'字子瑜,吴国大臣,诸葛亮之兄,诸葛恪之父。经鲁肃推荐,为东吴效力。胸怀宽广,温厚诚信,得到孙权的深深信赖,努力缓和蜀汉与东吴的关系。建安二十五年(220年)吕蒙病逝,诸葛瑾代吕蒙领南郡太守,驻守公安。孙权称帝后,诸葛瑾官至大将军,领豫州牧。', - zhangxingcai:'蜀名将张飞与夏侯氏所生之女,刘禅的妻子,史上称为“敬哀皇后”。', - zumao:'字大荣,吴郡富春人,使用双刀。孙坚在汜水关被华雄击败,祖茂为保护主公而主动提出与孙坚交换头盔,孙坚因此得脱。祖茂将孙坚的赤帻挂在柱子上,准备以此引诱华雄,趁机偷袭,却反被华雄所杀。', - dingfeng:'吴国将领。年少时以骁勇为小将,经常奋勇杀敌,屡立功勋,此后又于东兴之战中“雪中奋短兵”,大破侵犯东吴的魏军。吴景帝孙休在位时,丁奉设计除掉了东吴的权臣孙綝,被拜为大将军,后为右大司马、左军师。', - panfeng:'冀州牧韩馥部下的上将。当十八路诸侯讨伐董卓之时,他奉韩馥之命前往汜水关前挑战董卓部下大将华雄,不敌被斩。', - maliang:'字季常,因眉毛中有白毛,人称白眉马良,马谡的兄长。马良在兄弟五人中名声最佳,因此有“马氏五常,白眉最良”的说法。', - zhugedan:'字公休,曹魏后期的重要将领,诸葛亮的族弟。曾与司马师一同平定毌丘俭、文钦的叛乱。之后因与被诛的夏侯玄、邓飏交厚,且见到王淩、毌丘俭等人的覆灭而心不自安,于甘露二年起兵,并得到东吴的支援,但于次年被镇压,被大将军司马胡奋所斩。', - hetaihou:'大将军何进的妹妹,汉灵帝刘宏第二任皇后,汉少帝刘辩的生母。何氏出身于屠户家庭,后选入掖庭,得到汉灵帝临幸,生下皇子刘辩,并受封贵人。光和三年(180年),立为皇后。中平六年(189年),汉灵帝去世,刘辩继位,尊何氏为皇太后。董卓进京,废黜刘辩,不久毒杀刘辩及何氏。', - sunluyu:'又名小虎,孙权与步练师之女。吴后期,孙鲁班诬陷孙鲁育参与谋反,于是孙峻杀害了孙鲁育。', - wenpin:'本为刘表大将,刘表死后,跟随刘琮投降曹操。后曹操令其镇守江夏,多次阻止了关羽和孙权的进攻,为曹操倚为屏障的大将之一。', - zhanglu:'汉宁太守,继父祖之后传播五斗米教。刘璋杀张鲁之母,二人因此结仇,多次交战。刘备攻益州时,刘璋向张鲁求援。张鲁派马超前往,但马超投降刘备。张鲁后见曹操自封魏王,想要自立为汉宁王,为谋士阎圃劝免。后曹操讨汉中,张鲁败,众人劝其烧粮仓,张鲁认为这是国家之物,未听从,为曹操所称赞。后投降曹操,任镇南将军。', - mayunlu:'马腾之女,马超之妹,赵云之妻。父亲令其自幼习武,枪术非凡,寻常男子也是难以匹敌。', - tadun:'东汉末年辽西乌桓(亦称乌丸)的首领,乌桓大人丘力居的从子,总摄三王部。曾出兵协助袁绍,击破公孙瓒。此后受袁绍假传朝廷诏命,与三王难楼、苏仆延、乌延等人同受单于称号及印绶。后难楼、苏仆延率其部众奉立楼班为单于,蹋顿于是退位为王。袁绍死后,收到被曹操击败的袁尚的求助,纠集逃亡至乌桓的幽州、冀州官吏百姓,企图夺回河北。东汉建安十二年,曹操亲征乌桓。八月,乌桓、袁氏部队于柳城白狼山为曹军所败,蹋顿在此战中被曹操的先锋张辽所斩杀。 ', - yanbaihu:'吴郡乌程县人,原名“严虎”,别号“白虎”,东汉末年盘据吴郡一带山贼出身的地方豪帅。献帝初拥兵万人自固。孙策受袁术使渡江,攻破白虎等。白虎奔余杭,投靠许昭。建安二年,再度被孙策击败,至此不知亡佚何处。', - simalang:'字伯达,“司马八达”之一。曹操任司空后,司马朗被辟为司空属官,又历任成皋令、堂阳长、元城令、丞相主簿、兖州刺史等职,所在皆有政绩,深受百姓爱戴。后司马朗与夏侯惇、臧霸等征讨吴国,到达居巢。军队中流行瘟疫,司马朗亲自去视察,派送医药,因此染病去世。', - wangji:'字伯舆,东莱曲城人。三国时期魏国将领。王基文武兼备,才高于世,德溥于时,深得司马懿、司马师、司马昭的器重,尤其在南征毋丘俭,文钦之乱,东征诸葛诞之叛大规模军事活动中,王基与司马师、司马昭结下了深厚的军友情谊。魏景元二年王基去世,追赠司空,谥号为景侯。', - buzhi:'吴重臣,最初避难江东,于孙权统事后,被召为主记。后游历吴地,又任海盐县长,还任东曹掾,出领鄱阳太守。建安十五年,转交州刺史、立武中郎将,率军接管往交州,追拜使持节、征南中郎将。次年,以平定交州功,加平戎将军,封广信侯。后迁右将军、左护军,改封临湘侯。孙权称帝后,拜骠骑将军,领冀州牧,后因冀州分与蜀汉而解牧职。又都督西陵。赤乌九年,代陆逊为丞相。', - litong:'字文达,小字万亿。江夏平春(今河南信阳)人,汝南太守。早年以游侠闻名于江汝,在率众补充曹操兵源有功拜为阳安都尉,其间不因私而忘公,不因其妻子的求请而过问执法者。后来在曹操讨伐马超时出阵挑战,死于马超枪下。', - mizhu:'原为徐州富商,后被徐州牧陶谦辟为别驾从事。陶谦病死后,奉其遗命迎接刘备。与其弟麋芳拒绝曹操的任命而跟随刘备,在刘备最潦倒之时给予刘备很大的帮助,使他重新振作。214年(建安十九年),刘备入主益州后,拜麋竺为安汉将军,地位在诸葛亮之上,为刘备手下众臣之最。吕蒙袭取荆州,麋芳举城投降,导致关羽兵败身亡,麋竺面缚请罪,刘备劝慰麋竺,对他待遇如初。', - dongbai:'东汉末年县君,陇西临洮(今甘肃省岷县)人,董卓之孙女。董卓当权时,遍封其宗族,其中孙女董白尚未及笄,被封为渭阳君。', - zhaoxiang:'赵云与马云騄之女,赵统赵广之妹,关平之妻。', - heqi:'早年在平定山越的战争中立有大功,又讨平叛乱无数,身经百战,所向披靡,深受孙权器重。后来在与魏国的多次边境争斗中也屡立战功,官至后将军,并领徐州牧。', - dongyun:'大汉重臣,掌军中郎将董和之子。东汉末年,其父董和事刘璋为益州太守,刘备立太子时,允被选为洗马,后为黄门侍郎,延熙六年(公元243年)加辅国将军,延熙七年(公元244年)以侍中守尚书令,任大将军费祎的副手。', - mazhong:'本名狐笃,字德信,巴西阆中人,初次出场时随丞相诸葛亮南征孟获,诸葛亮遣马忠与赵云两路夹攻,大败蛮将阿会喃。孟获派弟孟优赴汉军处假投降,欲内应外合,诸葛亮将计就计,埋伏擒获孟获和诸洞酋长,马忠亦于此战立下战功。后诸葛亮北伐时亦数次出阵,立下汗马功劳。', - kanze:'孙权谋士,在孙权广纳贤才之时与严畯等来到江东,甚为孙权礼遇。第一个识破周瑜打黄盖是苦肉计,后欣然向曹操献诈降书,被曹操识破后面不改色,哈哈大笑,一番妙言让曹操相信了诈降书,是苦肉计中的关键人物。后劝孙权不要设局请关羽。在刘备御驾亲征东吴时,向孙权举荐陆逊为都督,间接上挽救了东吴的命运。', - lingju:'相传为吕布与貂蝉的女儿,被汉献帝掳走并训练为死士,被秘密送入宫中接近曹操,成为其“忘年红颜知己”。外表是柔弱的女子,实际上身怀致命的杀人绝技,等待时机给予曹操致命一击。', - yangxiu:'字德祖,今陕西华阴人,是东汉末年的文学家。杨修学问渊博,极聪慧,任丞相府主簿。史载,“是时,军国多事,修总知外内,事皆称意”。', - chenlin:'陈琳(?-217年),字孔璋,广陵射阳(今江苏宝应)人。东汉末年著名文学家,“建安七子”之一。', - zhugeke:'字元逊,琅邪阳都(今山东沂南)人。三国时期吴臣,蜀丞相诸葛亮之侄,吴大将军诸葛瑾长子,从小就以神童著称,深受孙权赏识。', - zhangbao:'东汉末年黄巾起义的首领之一,张角之弟,张梁之兄。中平元年(184)随兄张角起义,号称“地公将军”。', - chengyu:'字仲德,本名程立,因梦中於泰山捧日,更名程昱。荀彧投曹操时向其举荐程昱。他参与了攻打吕布、袁绍、刘备、孙权的大部份战事,一直出谋献策,表现出众。', - sunhao:'孙权之孙,孙和之子,东吴的末代君主。在位初期虽施行过明政,但不久即沉溺酒色,专于杀戮,变得昏庸暴虐,嗜用挖眼、剥皮等酷刑。280年,吴国被西晋所灭,孙皓投降西晋,被封为归命侯。', - wutugu:'南蛮乌戈国主,身长丈二(约合现在2.77米),不食五谷,以生蛇恶兽为饭。身有鳞甲,刀箭不能侵。兀突骨乘骑巨象,头戴日月狼须帽,身披金珠缨络,两肋下露出生鳞甲,眼目中微有光芒。', - shixie:'割据交州(今越南)一带的军阀,年少时师事刘陶,经逐渐升迁任交趾太守。后被朝廷加职绥南中郎将,迁安远将军,封龙度亭侯。在步骘接管交州时积极配合,归附孙权,被孙权加为左将军;此后又因诱降益州豪族雍闿而迁任卫将军,进封龙编侯。任交趾太守四十年。', - guansuo:'关羽的三子。自荆州失陷后,逃难在鲍家庄养病,伤势痊愈之后入蜀,逢丞相诸葛亮南征,拜之为前部先锋,一同南征。', - wanglang:'字景兴,汉末三国经学家,曹魏初期重臣。曾任会稽太守举兵抵抗孙策,后为曹操所征,被拜为谏议大夫等职。曹丕建立魏国后任命为司空。小说《三国演义》中他在阵前与诸葛亮饶舌比拼,最终被诸葛亮言词所驳倒,一时气愤坠马身亡。', - zhangliang:'东汉末年黄巾起义首领之一,张角的三弟。中平元年(184)随兄起义,号称“人公将军”。遭到朝廷所派左中郎将皇甫嵩进攻时,他率军在广宗(今河北威县)进行反击。后因警戒疏忽,遭到汉军夜袭,兵败身亡。', + huangfusong: + "字义真。安定郡朝那县(今宁夏彭阳)人。于黄巾起义时,以中郎将身份讨伐黄巾,用火攻大破张梁、张宝。后接替董卓进攻张梁,连胜七阵。掘张角墓,拜左车骑将军、冀州牧,因拒绝贿赂宦官而被免职。 董卓死,王允命其与吕布等共至郿坞抄籍董卓家产、人口,皇甫嵩将坞中所藏良家子女,尽行释放。", + zangba: "其父臧戒,有二子臧艾与臧舜。年少时曾召集数人将获罪的父亲救出,此后四处流亡。后来成为陶谦麾下的骑都尉,负责募兵抵抗黄巾军。与孙观、尹礼等人拥兵驻屯于开阳,自成一股独立势力,后跟随吕布。吕布战败后,投降了曹操。后与袁绍、孙权等的战役里战功赫赫,官至镇东将军。", + zhangren: + "刘璋的属下,以忠勇著称。刘备入蜀时,张任曾劝刘璋提防刘备,但刘璋没有听从。魏延舞剑想趁机除掉刘璋时,张任出面对舞,解救刘璋。后在刘备进攻时于落凤坡射死了庞统。", + jiling: "东汉末年袁术帐下将领,勇猛非常,曾奉命率军攻打小沛的刘备,在吕布辕门射戟的调停下撤兵。", + zoushi: "军阀张济之妻,张绣之婶。张绣降曹后,邹氏遂被曹操霸占。贾诩献计趁机诛杀曹操,险些得手。曹操在损失爱将典韦、侄子曹安民和长子曹昂后方才逃出生天。", + ganfuren: + "刘备起兵后,于沛城娶甘氏为妾。后来,甘夫人随刘备到荆州,生了阿斗(也就是后主刘禅)。223年四月,刘备病死于白帝城,追谥甘夫人为“昭烈皇后”。", + jiangfei: "请分别查看「蒋琬」和「费袆」的武将介绍。", + mifuren: + "刘备夫人。徐州别驾糜竺之妹。长坂兵败,她怀抱年仅两岁的刘禅在乱军中走散,被赵云发现;但麋夫人因为赵云只有一匹马,不肯上马,在将阿斗托付给赵云后投井而亡。", + chendong: + "陈武,东吴将领,孙策攻打刘繇,陈武前来相助,孙策非常喜爱陈武,拜为校尉,使作先锋。陈武以十数骑兵力杀敌五十余人。后于赤壁等战役屡立功勋。董袭献上严虎的人头来降孙策。赤壁之战,董袭受周瑜命,分兵去汉阳,合肥会战时接应太史慈,逍遥津支援孙权。濡须口之战时,董袭在船上督战,船覆董袭坚守殉职。", + jiangqing: + "擅长弓术。与周泰原为活跃于长江一带的江贼,孙策脱离袁术下江东自立门户时,和周泰一起率众投靠。 孙策攻刘繇,并引出城中麾下的陈横、薛礼、张英三名将领,陈横后被蒋钦一箭射杀,后与韩当等将乘舟过江,乱箭射杀敌军。曾在赤壁之战与周泰,还有擅使长枪的韩当率领水军在三江口踏江破敌。", + kongrong: + "字文举,鲁国人,东汉文学家,“建安七子”之首。献帝即位后任北军中侯、虎贲中郎将、北海相,时称孔北海后因触怒曹操,为曹操所杀。能诗善文。", + mateng: "字寿成,扶风茂陵人,东汉末年征西将军,割据西凉一带的军阀,伏波将军马援的后代,官至卫尉,封爵槐里乡侯。因其子马超谋反,而被杀,夷灭三族。", + tianfeng: + "字元皓。东汉末年大军阀袁绍部下重要谋士。为人刚直不阿,曾多次向袁绍进言而不被采纳。后因谏阻袁绍征伐曹操而被袁绍下令监禁,并于官渡之战后,被袁绍杀害。", + caochun: + "字子和,沛国谯(今安徽亳州)人。东汉末年曹操麾下将领,曹仁之弟。曹纯是曹操部下精锐部队“虎豹骑”的统领者之一,因在平定北方的战役中颇有功绩,被加封为高陵亭侯。死后谥曰威侯。曹纯擅战,甚得人心,为人重纲纪,不失理智,好学问,敬爱学士,闻名天下。", + hanba: "中国古代神话传说中引起旱灾的怪物。《诗·大雅·云汉》:“旱魃为虐,如惔如焚。”", + cuiyan: "字季珪,清河东武城(今河北省清河县)人。东汉末年名士,司空崔林的从兄,曹操帐下谋士。崔琰相貌俊美,很有威望,曹操对他也很敬畏。建安二十一年(216年),崔琰在给杨训的书信中写道“时乎时乎,会当有变时”,曹操认为此句有不逊之意,因而将崔琰下狱,不久崔琰即被曹操赐死。", + lifeng: "南阳(治今河南南阳)人,三国时期蜀汉大臣李严之子。230年,李严迁为骠骑将军,率军前往汉中,诸葛亮上表推举李丰为江州都督督军,以代替李严管理后方事务。李严去世后,李丰在蜀汉官至朱提太守。", + sunru: "孙茹,孙坚之妹,其名载于《江浙通志》中。儿子徐琨亦为孙吴早期名将,当初母子二人随军跟从孙策渡长江时,因为暂时没足够的船,孙策感到苦恼打算暂时驻军江边。孙茹夫人献计以芦苇为筏,孙策大喜。吴军遂以神不知鬼不觉的速度过长江击破刘繇部将张英,立下平江东第一功。", + lingcao: + "东汉末年将领,吴郡余杭(今浙江余杭)人,凌统之父。早年跟随孙策转战江东。孙权统军后,凌操随其征伐黄祖,被甘宁射杀。《吴书》载:甘宁以善射,将兵在后,射杀校尉凌操", + zhugeguo: + "诸葛果,为《历代神仙通鉴》中诸葛亮女儿的名字,《历代神仙通鉴》记录从上古到明代的神仙历史,因此诸葛果不见于任何史书。成都西南有朝真观,即乘烟观。相传,诸葛果在这里修行后成仙升天。", + zhuling: + "朱灵(生卒年不详),字文博,冀州清河国人,三国时期曹魏名将。官至后将军,封为高唐侯,谥号威侯。初为袁绍部将,后归顺曹操,随曹操征伐四方,屡建战功。", + re_yuanshu: + "字公路,汝南汝阳人,袁绍之弟。初为虎贲中郎将。董卓进京后以袁术为后将军,袁术因畏祸而出奔南阳。初平元年与袁绍、曹操等同时起兵,共讨董卓。后与袁绍对立,被袁绍、曹操击败,率馀众奔九江,割据扬州。建安二年称帝,建号仲氏。", + fuwan: "伏完(?-209),琅邪东武(今属山东)人,东汉末大臣,汉献帝伏皇后之父。历官辅国将军、中散大夫、屯骑校尉。", + liuxie: "字伯和,又字合。汉族,祖籍沛县,生于洛阳。汉灵帝第三子,被董卓迎立为帝。董卓被王允和吕布诛杀后,董卓部将李傕等攻入长安,再次挟持了他,后来逃出长安。公元196年,曹操控制了刘协,并迁都许昌,“挟天子以令诸侯”。公元220年,曹操病死,刘协被曹丕控制,随后被迫禅让于曹丕。", + yuanshu: + "字公路,汝南汝阳人,袁绍之弟。初为虎贲中郎将。董卓进京后以袁术为后将军,袁术因畏祸而出奔南阳。初平元年与袁绍、曹操等同时起兵,共讨董卓。后与袁绍对立,被袁绍、曹操击败,率馀众奔九江,割据扬州。建安二年称帝,建号仲氏。", + gongsunzan: + "字伯珪,汉族,号“白马义从”。辽西令支人。东汉末年献帝年间占据幽州一带的军阀,汉末群雄之一。出身贵族,因母地位卑贱,只当了郡中小吏。他貌美,声音洪亮,机智善辩。后随卢植于缑氏山中读书,粗通经传。", + caohong: + "字子廉,沛国谯(今安徽亳县)人,曹操从弟,曾献马并救护曹操。后多随军征伐,平兖州、征刘表、讨祝臂。曹丕即位时封曹洪为骠骑将军。曹叡即位,拜曹洪为后将军,更封乐城侯,后复拜为骠骑将军。曹洪逝世,追谥曰恭侯。", + guanyinping: + "河东解县(今山西运城)人,美髯公关羽之女。因在关羽的四个子女中排行第三,故又被称作“关三小姐”、“关氏三姐”或“关羽三小姐”。传说她是赵云的弟子、并随同诸葛亮平定南蛮。", + xiahouba: + "夏侯渊次子。本为曹魏武将,后因司马懿诛曹爽一族,夏侯霸身为曹氏宗室而心怀不安,遂投降蜀汉。后随蜀将姜维北伐,官至车骑将军。", + daxiaoqiao: + "大乔,庐江皖县人,为乔公长女,孙策之妻,容貌国色流离。小乔为大乔之妹,周瑜之妻,资貌绝伦。两人合称“二乔”。", + yuejin: "字文谦,魏“五子良将”之一。容貌短小,以胆烈跟从曹操,南征北讨,战功无数。从击袁绍于官渡,奋勇力战,斩袁绍部将淳于琼。又从击袁绍子谭、尚于黎阳,斩其大将严敬。从平荆州,留屯襄阳,进击关羽、苏非等人,击退其众,南郡诸郡的山谷蛮夷都前往乐进处投降。后来从曹操征孙权,假进节。曹操回师后,留乐进与张辽、李典屯于合肥。又以乐进数有军功,迁右将军。建安二十三年逝世,谥曰威侯。", + caoang: "字子修,曹操的长子,由于性情谦和且聪慧所以深得曹操喜爱。曹操征讨张绣时,羞辱张绣之婶邹氏,被张绣突然袭击。曹昂为保护曹操撤退,与典韦一起战死在宛城。", + zhugejin: + "字子瑜,吴国大臣,诸葛亮之兄,诸葛恪之父。经鲁肃推荐,为东吴效力。胸怀宽广,温厚诚信,得到孙权的深深信赖,努力缓和蜀汉与东吴的关系。建安二十五年(220年)吕蒙病逝,诸葛瑾代吕蒙领南郡太守,驻守公安。孙权称帝后,诸葛瑾官至大将军,领豫州牧。", + zhangxingcai: "蜀名将张飞与夏侯氏所生之女,刘禅的妻子,史上称为“敬哀皇后”。", + zumao: "字大荣,吴郡富春人,使用双刀。孙坚在汜水关被华雄击败,祖茂为保护主公而主动提出与孙坚交换头盔,孙坚因此得脱。祖茂将孙坚的赤帻挂在柱子上,准备以此引诱华雄,趁机偷袭,却反被华雄所杀。", + dingfeng: + "吴国将领。年少时以骁勇为小将,经常奋勇杀敌,屡立功勋,此后又于东兴之战中“雪中奋短兵”,大破侵犯东吴的魏军。吴景帝孙休在位时,丁奉设计除掉了东吴的权臣孙綝,被拜为大将军,后为右大司马、左军师。", + panfeng: + "冀州牧韩馥部下的上将。当十八路诸侯讨伐董卓之时,他奉韩馥之命前往汜水关前挑战董卓部下大将华雄,不敌被斩。", + maliang: + "字季常,因眉毛中有白毛,人称白眉马良,马谡的兄长。马良在兄弟五人中名声最佳,因此有“马氏五常,白眉最良”的说法。", + zhugedan: + "字公休,曹魏后期的重要将领,诸葛亮的族弟。曾与司马师一同平定毌丘俭、文钦的叛乱。之后因与被诛的夏侯玄、邓飏交厚,且见到王淩、毌丘俭等人的覆灭而心不自安,于甘露二年起兵,并得到东吴的支援,但于次年被镇压,被大将军司马胡奋所斩。", + hetaihou: + "大将军何进的妹妹,汉灵帝刘宏第二任皇后,汉少帝刘辩的生母。何氏出身于屠户家庭,后选入掖庭,得到汉灵帝临幸,生下皇子刘辩,并受封贵人。光和三年(180年),立为皇后。中平六年(189年),汉灵帝去世,刘辩继位,尊何氏为皇太后。董卓进京,废黜刘辩,不久毒杀刘辩及何氏。", + sunluyu: "又名小虎,孙权与步练师之女。吴后期,孙鲁班诬陷孙鲁育参与谋反,于是孙峻杀害了孙鲁育。", + wenpin: "本为刘表大将,刘表死后,跟随刘琮投降曹操。后曹操令其镇守江夏,多次阻止了关羽和孙权的进攻,为曹操倚为屏障的大将之一。", + zhanglu: + "汉宁太守,继父祖之后传播五斗米教。刘璋杀张鲁之母,二人因此结仇,多次交战。刘备攻益州时,刘璋向张鲁求援。张鲁派马超前往,但马超投降刘备。张鲁后见曹操自封魏王,想要自立为汉宁王,为谋士阎圃劝免。后曹操讨汉中,张鲁败,众人劝其烧粮仓,张鲁认为这是国家之物,未听从,为曹操所称赞。后投降曹操,任镇南将军。", + mayunlu: "马腾之女,马超之妹,赵云之妻。父亲令其自幼习武,枪术非凡,寻常男子也是难以匹敌。", + tadun: "东汉末年辽西乌桓(亦称乌丸)的首领,乌桓大人丘力居的从子,总摄三王部。曾出兵协助袁绍,击破公孙瓒。此后受袁绍假传朝廷诏命,与三王难楼、苏仆延、乌延等人同受单于称号及印绶。后难楼、苏仆延率其部众奉立楼班为单于,蹋顿于是退位为王。袁绍死后,收到被曹操击败的袁尚的求助,纠集逃亡至乌桓的幽州、冀州官吏百姓,企图夺回河北。东汉建安十二年,曹操亲征乌桓。八月,乌桓、袁氏部队于柳城白狼山为曹军所败,蹋顿在此战中被曹操的先锋张辽所斩杀。 ", + yanbaihu: + "吴郡乌程县人,原名“严虎”,别号“白虎”,东汉末年盘据吴郡一带山贼出身的地方豪帅。献帝初拥兵万人自固。孙策受袁术使渡江,攻破白虎等。白虎奔余杭,投靠许昭。建安二年,再度被孙策击败,至此不知亡佚何处。", + simalang: + "字伯达,“司马八达”之一。曹操任司空后,司马朗被辟为司空属官,又历任成皋令、堂阳长、元城令、丞相主簿、兖州刺史等职,所在皆有政绩,深受百姓爱戴。后司马朗与夏侯惇、臧霸等征讨吴国,到达居巢。军队中流行瘟疫,司马朗亲自去视察,派送医药,因此染病去世。", + wangji: "字伯舆,东莱曲城人。三国时期魏国将领。王基文武兼备,才高于世,德溥于时,深得司马懿、司马师、司马昭的器重,尤其在南征毋丘俭,文钦之乱,东征诸葛诞之叛大规模军事活动中,王基与司马师、司马昭结下了深厚的军友情谊。魏景元二年王基去世,追赠司空,谥号为景侯。", + buzhi: "吴重臣,最初避难江东,于孙权统事后,被召为主记。后游历吴地,又任海盐县长,还任东曹掾,出领鄱阳太守。建安十五年,转交州刺史、立武中郎将,率军接管往交州,追拜使持节、征南中郎将。次年,以平定交州功,加平戎将军,封广信侯。后迁右将军、左护军,改封临湘侯。孙权称帝后,拜骠骑将军,领冀州牧,后因冀州分与蜀汉而解牧职。又都督西陵。赤乌九年,代陆逊为丞相。", + litong: "字文达,小字万亿。江夏平春(今河南信阳)人,汝南太守。早年以游侠闻名于江汝,在率众补充曹操兵源有功拜为阳安都尉,其间不因私而忘公,不因其妻子的求请而过问执法者。后来在曹操讨伐马超时出阵挑战,死于马超枪下。", + mizhu: "原为徐州富商,后被徐州牧陶谦辟为别驾从事。陶谦病死后,奉其遗命迎接刘备。与其弟麋芳拒绝曹操的任命而跟随刘备,在刘备最潦倒之时给予刘备很大的帮助,使他重新振作。214年(建安十九年),刘备入主益州后,拜麋竺为安汉将军,地位在诸葛亮之上,为刘备手下众臣之最。吕蒙袭取荆州,麋芳举城投降,导致关羽兵败身亡,麋竺面缚请罪,刘备劝慰麋竺,对他待遇如初。", + dongbai: + "东汉末年县君,陇西临洮(今甘肃省岷县)人,董卓之孙女。董卓当权时,遍封其宗族,其中孙女董白尚未及笄,被封为渭阳君。", + zhaoxiang: "赵云与马云騄之女,赵统赵广之妹,关平之妻。", + heqi: "早年在平定山越的战争中立有大功,又讨平叛乱无数,身经百战,所向披靡,深受孙权器重。后来在与魏国的多次边境争斗中也屡立战功,官至后将军,并领徐州牧。", + dongyun: + "大汉重臣,掌军中郎将董和之子。东汉末年,其父董和事刘璋为益州太守,刘备立太子时,允被选为洗马,后为黄门侍郎,延熙六年(公元243年)加辅国将军,延熙七年(公元244年)以侍中守尚书令,任大将军费祎的副手。", + mazhong: + "本名狐笃,字德信,巴西阆中人,初次出场时随丞相诸葛亮南征孟获,诸葛亮遣马忠与赵云两路夹攻,大败蛮将阿会喃。孟获派弟孟优赴汉军处假投降,欲内应外合,诸葛亮将计就计,埋伏擒获孟获和诸洞酋长,马忠亦于此战立下战功。后诸葛亮北伐时亦数次出阵,立下汗马功劳。", + kanze: "孙权谋士,在孙权广纳贤才之时与严畯等来到江东,甚为孙权礼遇。第一个识破周瑜打黄盖是苦肉计,后欣然向曹操献诈降书,被曹操识破后面不改色,哈哈大笑,一番妙言让曹操相信了诈降书,是苦肉计中的关键人物。后劝孙权不要设局请关羽。在刘备御驾亲征东吴时,向孙权举荐陆逊为都督,间接上挽救了东吴的命运。", + lingju: "相传为吕布与貂蝉的女儿,被汉献帝掳走并训练为死士,被秘密送入宫中接近曹操,成为其“忘年红颜知己”。外表是柔弱的女子,实际上身怀致命的杀人绝技,等待时机给予曹操致命一击。", + yangxiu: + "字德祖,今陕西华阴人,是东汉末年的文学家。杨修学问渊博,极聪慧,任丞相府主簿。史载,“是时,军国多事,修总知外内,事皆称意”。", + chenlin: + "陈琳(?-217年),字孔璋,广陵射阳(今江苏宝应)人。东汉末年著名文学家,“建安七子”之一。", + zhugeke: + "字元逊,琅邪阳都(今山东沂南)人。三国时期吴臣,蜀丞相诸葛亮之侄,吴大将军诸葛瑾长子,从小就以神童著称,深受孙权赏识。", + zhangbao: + "东汉末年黄巾起义的首领之一,张角之弟,张梁之兄。中平元年(184)随兄张角起义,号称“地公将军”。", + chengyu: + "字仲德,本名程立,因梦中於泰山捧日,更名程昱。荀彧投曹操时向其举荐程昱。他参与了攻打吕布、袁绍、刘备、孙权的大部份战事,一直出谋献策,表现出众。", + sunhao: "孙权之孙,孙和之子,东吴的末代君主。在位初期虽施行过明政,但不久即沉溺酒色,专于杀戮,变得昏庸暴虐,嗜用挖眼、剥皮等酷刑。280年,吴国被西晋所灭,孙皓投降西晋,被封为归命侯。", + wutugu: "南蛮乌戈国主,身长丈二(约合现在2.77米),不食五谷,以生蛇恶兽为饭。身有鳞甲,刀箭不能侵。兀突骨乘骑巨象,头戴日月狼须帽,身披金珠缨络,两肋下露出生鳞甲,眼目中微有光芒。", + shixie: "割据交州(今越南)一带的军阀,年少时师事刘陶,经逐渐升迁任交趾太守。后被朝廷加职绥南中郎将,迁安远将军,封龙度亭侯。在步骘接管交州时积极配合,归附孙权,被孙权加为左将军;此后又因诱降益州豪族雍闿而迁任卫将军,进封龙编侯。任交趾太守四十年。", + guansuo: + "关羽的三子。自荆州失陷后,逃难在鲍家庄养病,伤势痊愈之后入蜀,逢丞相诸葛亮南征,拜之为前部先锋,一同南征。", + wanglang: + "字景兴,汉末三国经学家,曹魏初期重臣。曾任会稽太守举兵抵抗孙策,后为曹操所征,被拜为谏议大夫等职。曹丕建立魏国后任命为司空。小说《三国演义》中他在阵前与诸葛亮饶舌比拼,最终被诸葛亮言词所驳倒,一时气愤坠马身亡。", + zhangliang: + "东汉末年黄巾起义首领之一,张角的三弟。中平元年(184)随兄起义,号称“人公将军”。遭到朝廷所派左中郎将皇甫嵩进攻时,他率军在广宗(今河北威县)进行反击。后因警戒疏忽,遭到汉军夜袭,兵败身亡。", }, - characterTitle:{}, - perfectPair:{ - yuejin:['re_lidian'], - zhugejin:['zhugeke','sunquan'], - guanyinping:['guanyu'], - zhangxingcai:['liushan'], - fuwan:['fuhuanghou'], - sunshangxiang:['liubei'], - caoang:['caocao'], - zhangbao:['zhangliang','zhangjiao'], - zhangliang:['zhangjiao'], - maliang:['masu'], - lingcao:['lingtong'], - lingju:['diaochan','lvbu'], - jiangqing:['zhoutai'], - dingfeng:['xusheng','zhugeke'], - caohong:['caoren'], - daxiaoqiao:['zhouyu','sunce'], - cuiyan:['caocao'], - guansuo:['guanyu'], - mateng:['machao','madai','mayunlu'], - chengpu:['zhouyu'], - hanba:['swd_muyun'], - dongbai:['dongzhuo'], - cuimao:['caopi'], - simazhao:['wangyuanji'], + characterTitle: {}, + perfectPair: { + yuejin: ["re_lidian"], + zhugejin: ["zhugeke", "sunquan"], + guanyinping: ["guanyu"], + zhangxingcai: ["liushan"], + fuwan: ["fuhuanghou"], + sunshangxiang: ["liubei"], + caoang: ["caocao"], + zhangbao: ["zhangliang", "zhangjiao"], + zhangliang: ["zhangjiao"], + maliang: ["masu"], + lingcao: ["lingtong"], + lingju: ["diaochan", "lvbu"], + jiangqing: ["zhoutai"], + dingfeng: ["xusheng", "zhugeke"], + caohong: ["caoren"], + daxiaoqiao: ["zhouyu", "sunce"], + cuiyan: ["caocao"], + guansuo: ["guanyu"], + mateng: ["machao", "madai", "mayunlu"], + chengpu: ["zhouyu"], + hanba: ["swd_muyun"], + dongbai: ["dongzhuo"], + cuimao: ["caopi"], + simazhao: ["wangyuanji"], }, - card:{ + card: { //蒲元衍生 - sanlve:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip5", - ai:{ - basic:{ - equipValue:5, + sanlve: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip5", + ai: { + basic: { + equipValue: 5, }, }, - skills:["sanlve_skill"], - fullskin:true, + skills: ["sanlve_skill"], + fullskin: true, }, - zhaogujing:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip5", - ai:{ - basic:{ - equipValue:6.5, + zhaogujing: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip5", + ai: { + basic: { + equipValue: 6.5, }, }, - skills:["zhaogujing_skill"], - fullskin:true, + skills: ["zhaogujing_skill"], + fullskin: true, }, - shufazijinguan:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip5", - modeimage:'boss', - ai:{ - basic:{ - equipValue:8, + shufazijinguan: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip5", + modeimage: "boss", + ai: { + basic: { + equipValue: 8, }, }, - skills:["shufazijinguan_skill"], - fullskin:true, + skills: ["shufazijinguan_skill"], + fullskin: true, }, - xuwangzhimian:{ - derivation:'ol_puyuan', - type:'equip', - fullskin:true, - subtype:'equip5', - modeimage:'boss', - skills:['xuwangzhimian'], - ai:{ - equipValue:7, - } + xuwangzhimian: { + derivation: "ol_puyuan", + type: "equip", + fullskin: true, + subtype: "equip5", + modeimage: "boss", + skills: ["xuwangzhimian"], + ai: { + equipValue: 7, + }, }, - hongmianbaihuapao:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip2", - modeimage:'boss', - ai:{ - basic:{ - equipValue:4, + hongmianbaihuapao: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip2", + modeimage: "boss", + ai: { + basic: { + equipValue: 4, }, }, - skills:["hongmianbaihuapao_skill"], - fullskin:true, + skills: ["hongmianbaihuapao_skill"], + fullskin: true, }, - guofengyupao:{ - derivation:'ol_puyuan', - type:'equip', - fullskin:true, - modeimage:'boss', - subtype:'equip2', - skills:['guofengyupao'], - ai:{ - equipValue:7 - } + guofengyupao: { + derivation: "ol_puyuan", + type: "equip", + fullskin: true, + modeimage: "boss", + subtype: "equip2", + skills: ["guofengyupao"], + ai: { + equipValue: 7, + }, }, - qimenbagua:{ - derivation:'ol_puyuan', - type:'equip', - fullskin:true, - modeimage:'boss', - subtype:'equip2', - skills:['qimenbagua'], - ai:{ - equipValue:7.5 - } + qimenbagua: { + derivation: "ol_puyuan", + type: "equip", + fullskin: true, + modeimage: "boss", + subtype: "equip2", + skills: ["qimenbagua"], + ai: { + equipValue: 7.5, + }, }, - linglongshimandai:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip2", - modeimage:'boss', - ai:{ - basic:{ - equipValue:5, + linglongshimandai: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip2", + modeimage: "boss", + ai: { + basic: { + equipValue: 5, }, }, - skills:["linglongshimandai_skill"], - fullskin:true, + skills: ["linglongshimandai_skill"], + fullskin: true, }, - chixueqingfeng:{ - derivation:'ol_puyuan', - type:'equip', - fullskin:true, - modeimage:'boss', - subtype:'equip1', - distance:{attackFrom:-1}, - skills:['chixueqingfeng'], - ai:{ - equipValue:6.7 - } - }, - guilongzhanyuedao:{ - derivation:'ol_puyuan', - type:'equip', - fullskin:true, - modeimage:'boss', - subtype:'equip1', - distance:{attackFrom:-2}, - skills:['guilongzhanyuedao'], - nomod:true, - nopower:true, - unique:true, - ai:{ - equipValue:4 - } - }, - wushuangfangtianji:{ - derivation:'ol_puyuan', - type:"equip", - modeimage:'boss', - subtype:"equip1", - distance:{ - attackFrom:-3, + chixueqingfeng: { + derivation: "ol_puyuan", + type: "equip", + fullskin: true, + modeimage: "boss", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["chixueqingfeng"], + ai: { + equipValue: 6.7, }, - ai:{ - basic:{ - equipValue:3, + }, + guilongzhanyuedao: { + derivation: "ol_puyuan", + type: "equip", + fullskin: true, + modeimage: "boss", + subtype: "equip1", + distance: { attackFrom: -2 }, + skills: ["guilongzhanyuedao"], + nomod: true, + nopower: true, + unique: true, + ai: { + equipValue: 4, + }, + }, + wushuangfangtianji: { + derivation: "ol_puyuan", + type: "equip", + modeimage: "boss", + subtype: "equip1", + distance: { + attackFrom: -3, + }, + ai: { + basic: { + equipValue: 3, }, }, - skills:["wushuangfangtianji_skill"], - fullskin:true, + skills: ["wushuangfangtianji_skill"], + fullskin: true, }, - bintieshuangji:{ - derivation:'ol_puyuan', - type:"equip", - subtype:"equip1", - distance:{ - attackFrom:-2, + bintieshuangji: { + derivation: "ol_puyuan", + type: "equip", + subtype: "equip1", + distance: { + attackFrom: -2, }, - ai:{ - basic:{ - equipValue:4.5, + ai: { + basic: { + equipValue: 4.5, }, }, - skills:["bintieshuangji_skill"], - fullskin:true, + skills: ["bintieshuangji_skill"], + fullskin: true, }, //王允 - wy_meirenji:{ - fullskin:true, - vanish:true, - derivation:'wangyun', - type:'trick', - enable:true, - filterTarget:function(card,player,target){ - return target.countCards('h')&&target!=player&&target.hasSex('male'); + wy_meirenji: { + fullskin: true, + vanish: true, + derivation: "wangyun", + type: "trick", + enable: true, + filterTarget: function (card, player, target) { + return target.countCards("h") && target != player && target.hasSex("male"); }, - content:function(){ - 'step 0' - event.list=game.filterPlayer(function(current){ - return current!=player&¤t!=target&¤t.hasSex('female'); - }).sortBySeat(); - 'step 1' - if(target.countCards('h')&&event.list.length){ - event.current=event.list.shift(); - event.current.gainPlayerCard(target,true,'h'); - target.line2([event.current,player]); - } - else{ + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + return current != player && current != target && current.hasSex("female"); + }) + .sortBySeat(); + "step 1"; + if (target.countCards("h") && event.list.length) { + event.current = event.list.shift(); + event.current.gainPlayerCard(target, true, "h"); + target.line2([event.current, player]); + } else { event.goto(4); } - 'step 2' - event.current.chooseCard('h',true,'将一张手牌交给'+get.translation(player)); - 'step 3' - if(result.bool){ - event.current.give(result.cards,player); + "step 2"; + event.current.chooseCard("h", true, "将一张手牌交给" + get.translation(player)); + "step 3"; + if (result.bool) { + event.current.give(result.cards, player); } event.goto(1); - 'step 4' - var n1=target.countCards('h'); - var n2=player.countCards('h'); - if(n1>n2){ + "step 4"; + var n1 = target.countCards("h"); + var n2 = player.countCards("h"); + if (n1 > n2) { target.damage(player); player.line(target); - } - else if(n1=3) return 0; - if(!target.hasSkillTag('maixie_hp')){ + result: { + target: function (player, target) { + var num = Math.min(5, target.maxHp - target.hp); + if (target.hp == 1) { + if (num >= 3) return 0; + if (!target.hasSkillTag("maixie_hp")) { return -3; } return -1; } - if(num==2) return 0; - return -2+num+(Math.pow(target.hp,0.2)-1); - } - } - } + if (num == 2) return 0; + return -2 + num + (Math.pow(target.hp, 0.2) - 1); + }, + }, + }, }, - zhuangshu_basic:{ - fullskin:true, - vanish:true, - derivation:'fengfangnv', - type:'equip', - suit:'spade', - subtype:'equip5', - skills:['zhuangshu_basic'], - forceDie:true, - onLose:function(){ - if((!event.getParent(2)||event.getParent(2).name!='swapEquip')&&(event.getParent().type!='equip'||event.getParent().swapEquip)){ + zhuangshu_basic: { + fullskin: true, + vanish: true, + derivation: "fengfangnv", + type: "equip", + suit: "spade", + subtype: "equip5", + skills: ["zhuangshu_basic"], + forceDie: true, + onLose: function () { + if ( + (!event.getParent(2) || event.getParent(2).name != "swapEquip") && + (event.getParent().type != "equip" || event.getParent().swapEquip) + ) { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); + card.destroyed = true; + game.log(card, "被销毁了"); } }, - equipDelay:false, - loseDelay:false, - ai:{ - equipValue:5, - basic:{ - equipValue:5 - } - } + equipDelay: false, + loseDelay: false, + ai: { + equipValue: 5, + basic: { + equipValue: 5, + }, + }, }, - zhuangshu_trick:{ - fullskin:true, - vanish:true, - derivation:'fengfangnv', - type:'equip', - suit:'club', - subtype:'equip5', - forceDie:true, - skills:['zhuangshu_trick'], - onLose:function(){ - if((!event.getParent(2)||event.getParent(2).name!='swapEquip')&&(event.getParent().type!='equip'||event.getParent().swapEquip)){ + zhuangshu_trick: { + fullskin: true, + vanish: true, + derivation: "fengfangnv", + type: "equip", + suit: "club", + subtype: "equip5", + forceDie: true, + skills: ["zhuangshu_trick"], + onLose: function () { + if ( + (!event.getParent(2) || event.getParent(2).name != "swapEquip") && + (event.getParent().type != "equip" || event.getParent().swapEquip) + ) { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); + card.destroyed = true; + game.log(card, "被销毁了"); } }, - equipDelay:false, - loseDelay:false, + equipDelay: false, + loseDelay: false, }, - zhuangshu_equip:{ - fullskin:true, - vanish:true, - derivation:'fengfangnv', - type:'equip', - suit:'heart', - subtype:'equip5', - skills:['zhuangshu_equip'], - forceDie:true, - inherit:'zhuangshu_basic', - onLose:function(){ - if((!event.getParent(2)||event.getParent(2).name!='swapEquip')&&(event.getParent().type!='equip'||event.getParent().swapEquip)){ + zhuangshu_equip: { + fullskin: true, + vanish: true, + derivation: "fengfangnv", + type: "equip", + suit: "heart", + subtype: "equip5", + skills: ["zhuangshu_equip"], + forceDie: true, + inherit: "zhuangshu_basic", + onLose: function () { + if ( + (!event.getParent(2) || event.getParent(2).name != "swapEquip") && + (event.getParent().type != "equip" || event.getParent().swapEquip) + ) { card.fix(); card.remove(); - card.destroyed=true; - game.log(card,'被销毁了'); + card.destroyed = true; + game.log(card, "被销毁了"); } }, - equipDelay:false, - loseDelay:false, + equipDelay: false, + loseDelay: false, }, }, - skill:{ - //刘辟 - olyicheng:{ - audio:2, - enable:'phaseUse', - usable:1, - async content(event,trigger,player){ - let cards=get.cards(3); - await game.cardsGotoOrdering(cards); - await player.showCards(cards,get.translation(player)+'发动了【易城】'); - if(player.countCards('h')){ - const sum=cards.reduce((num,card)=>num+get.number(card),0); - const {result:{bool,moved}}=await player.chooseToMove('易城:请选择你要交换的牌').set('list',[ - ['牌堆顶',cards,list=>{ - const sum2=list.reduce((num,card)=>num+get.number(card,false),0); - return '牌堆顶(现'+sum2+{'0':'=','-1':'<','1':'>'}[get.sgn(sum2-sum).toString()]+'原'+sum+')'; - }], - ['手牌',player.getCards('h')], - ]).set('filterOk',moved=>moved[1].some(i=>!get.owner(i))).set('processAI',list=>{ - const player=get.event('player'),limit=Math.min(3,player.countCards('h')); - let cards=list[0][1].slice(),hs=player.getCards('h'); - if(cards.reduce((num,card)=>num+get.value(card),0)>player.getCards('h').reduce((num,card)=>num+get.value(card),0)){ - cards.sort((a,b)=>get.number(a)-get.number(b)); - hs.sort((a,b)=>get.number(b)-get.number(a)); - let cards2=cards.slice(0,limit),hs2=hs.slice(0,limit); - if(hs2.reduce((num,card)=>num+get.number(card),0)>cards2.reduce((num,card)=>num+get.number(card),0)){ - cards.removeArray(cards2);hs.removeArray(hs2); - return [cards.concat(hs2),hs.concat(cards2)]; - } - return [cards,hs]; - } - else{ - cards.sort((a,b)=>get.value(b)-get.value(a)); - hs.sort((a,b)=>get.value(a)-get.value(b)); - let cards2=cards.slice(0,limit),hs2=hs.slice(0,limit),list=[cards,hs]; - for(let i=0;iget.value(hs2[i])){ - const change=[cards2[i],hs2[i]]; - cards[i]=change[1];hs[i]=change[0]; - } - else break; + skill: { + //SP孙策 + olliantao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((target) => target != player); + }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("olliantao"), lib.filter.notMe) + .set("ai", (target) => { + const player = get.event("player"), + att = get.attitude(player, target); + const colors = Object.keys(lib.color).filter((i) => i != "none"); + if ( + !colors.some((color) => + player.hasCard((card) => { + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return player.canUse(juedou, target, false); + }, "h") + ) + ) + return 20 + (3 - get.sgn(att)) + Math.random(); + const effs = colors.reduce((list, color) => { + const cards = player.getCards("h", (card) => { + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return player.canUse(juedou, target, false); + }); + if (cards.length) { + list.push( + cards.reduce((sum, card) => { + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return sum + get.effect(target, juedou, player, player); + }, 0) + ); } return list; - } - }); - if(bool){ - const puts=player.getCards('h',i=>moved[0].includes(i)); - const gains=cards.filter(i=>moved[1].includes(i)); - if(puts.length&&gains.length){ - player.$throw(puts,1000); - await player.lose(puts,ui.special); - await player.gain(gains,'gain2'); - cards=moved[0].slice(); - await player.showCards(cards,get.translation(player)+'【易城】第一次交换后'); - if(cards.reduce((num,card)=>num+get.number(card),0)>sum&&player.countCards('h')){ - const {result:{bool}}=await player.chooseBool('易城:是否使用全部手牌交换'+get.translation(cards)+'?').set('choice',(()=>{ - return cards.reduce((num,card)=>num+get.value(card),0)>player.getCards('h').reduce((num,card)=>num+get.value(card),0); - })()); - if(bool){ - const hs=player.getCards('h'); - player.$throw(hs,1000); - await player.lose(hs,ui.special); - await player.gain(cards,'gain2'); - cards=hs.slice(); - await player.showCards(cards,get.translation(player)+'【易城】第二次交换后'); + }, []); + return Math[att > 0 ? "max" : "min"].apply(Math, effs); + }) + .forResult(); + }, + async content(event, trigger, player) { + const target = event.targets[0]; + const colors = Object.keys(lib.color).filter((i) => i != "none"); + if (colors.length && player.countCards("h")) { + const result = await target + .chooseControl(colors) + .set("prompt", "连讨:请选择一个颜色") + .set("ai", () => { + const player = get.event("player"), + source = get.event().getParent().player; + let controls = get.event("controls").slice(); + if (controls.length == 1) return controls[0]; + const getSum = function (color, player, source) { + return source + .getCards("h", (card) => { + if (get.color(card) != color) return false; + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return source.canUse(juedou, player, false); + }) + .reduce((num, card) => { + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return num + get.effect(player, juedou, source, player); + }, 0); + }; + return controls.sort( + (a, b) => getSum(b, player, source) - getSum(a, player, source) + )[0]; + }) + .set( + "prompt2", + get.translation(player) + + "将对你依次使用由其手牌中所有此颜色的牌转化的【决斗】" + ) + .forResult(); + const color = result.control; + game.broadcastAll( + (color, target) => { + lib.skill.olliantao_backup.filterCardx = [color, target]; + lib.skill.olliantao_backup.filterCard = function (card, player) { + const list = lib.skill.olliantao_backup.filterCardx; + if (get.color(card) != list[0]) return false; + const juedou = get.autoViewAs({ name: "juedou" }, [card]); + return player.canUse(juedou, list[1], false); + }; + }, + color, + target + ); + while ( + target.isIn() && + player.hasCard((card) => lib.skill.olliantao_backup.filterCard(card, player)) && + !game.getGlobalHistory("everything", (evt) => { + return ( + evt.name == "dying" && + [player, target].includes(evt.player) && + evt.getParent("olliantao") == event + ); + }).length + ) { + await player + .chooseToUse() + .set("forced", true) + .set( + "openskilldialog", + "连讨:将一张" + + get.translation(color) + + "手牌当作【决斗】对" + + get.translation(target) + + "使用" + ) + .set("norestore", true) + .set("_backupevent", "olliantao_backup") + .set("custom", { + add: {}, + replace: { window: function () {} }, + }) + .backup("olliantao_backup") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", target) + .set("addCount", false); + } + } + const num = player + .getHistory("sourceDamage", (evt) => { + return evt.getParent(4) == event; + }) + .reduce((sum, evt) => sum + evt.num, 0); + if (num) await player.draw(num); + if ( + !game.hasPlayer2((current) => { + return current.getHistory("damage", (evt) => { + return evt.getParent(4) == event; + }).length; + }) + ) { + await player.draw(3); + player.addTempSkill("olliantao_buff"); + player.addMark("olliantao_buff", 3, false); + } + }, + subSkill: { + backup: { + viewAs: { name: "juedou" }, + position: "h", + check: () => 1 + Math.random(), + precontent() { + delete event.result.skill; + }, + }, + buff: { + charlotte: true, + onremove: true, + mod: { + maxHandcard(player, num) { + return num + player.countMark("olliantao_buff"); + }, + cardEnabled(card) { + if (card.name == "sha") return false; + }, + }, + intro: { content: "手牌上限+#,不能使用【杀】" }, + }, + }, + }, + //刘辟 + olyicheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + async content(event, trigger, player) { + let num = player.maxHp, cards = get.cards(num); + await game.cardsGotoOrdering(cards); + await player.showCards(cards, get.translation(player) + "发动了【易城】"); + if (player.countCards("h")) { + const sum = cards.reduce((num, card) => num + get.number(card), 0); + const { + result: { bool, moved }, + } = await player + .chooseToMove("易城:请选择你要交换的牌") + .set("list", [ + [ + "牌堆顶", + cards, + (list) => { + const sum2 = list.reduce( + (num, card) => num + get.number(card, false), + 0 + ); + return ( + "牌堆顶(现" + + sum2 + + { 0: "=", "-1": "<", 1: ">" }[get.sgn(sum2 - sum).toString()] + + "原" + + sum + + ")" + ); + }, + ], + ["手牌", player.getCards("h")], + ]) + .set("filterOk", (moved) => moved[1].some((i) => !get.owner(i))) + .set("processAI", (list) => { + const player = get.event("player"), + limit = Math.min(get.event("num"), player.countCards("h")); + let cards = list[0][1].slice(), + hs = player.getCards("h"); + if ( + cards.reduce((num, card) => num + get.value(card), 0) > + player.getCards("h").reduce((num, card) => num + get.value(card), 0) + ) { + cards.sort((a, b) => get.number(a) - get.number(b)); + hs.sort((a, b) => get.number(b) - get.number(a)); + let cards2 = cards.slice(0, limit), + hs2 = hs.slice(0, limit); + if ( + hs2.reduce((num, card) => num + get.number(card), 0) > + cards2.reduce((num, card) => num + get.number(card), 0) + ) { + cards.removeArray(cards2); + hs.removeArray(hs2); + return [cards.concat(hs2), hs.concat(cards2)]; + } + return [cards, hs]; + } else { + cards.sort((a, b) => get.value(b) - get.value(a)); + hs.sort((a, b) => get.value(a) - get.value(b)); + let cards2 = cards.slice(0, limit), + hs2 = hs.slice(0, limit), + list = [cards, hs]; + for (let i = 0; i < limit; i++) { + if (get.value(cards2[i]) > get.value(hs2[i])) { + const change = [cards2[i], hs2[i]]; + cards[i] = change[1]; + hs[i] = change[0]; + } else break; + } + return list; + } + }) + .set("num", num); + if (bool) { + const puts = player.getCards("h", (i) => moved[0].includes(i)); + const gains = cards.filter((i) => moved[1].includes(i)); + if (puts.length && gains.length) { + player.$throw(puts, 1000); + await player.lose(puts, ui.special); + await player.gain(gains, "gain2"); + cards = moved[0].slice(); + await player.showCards( + cards, + get.translation(player) + "【易城】第一次交换后" + ); + if ( + cards.reduce((num, card) => num + get.number(card), 0) > sum && + player.countCards("h") + ) { + const { + result: { bool }, + } = await player + .chooseBool( + "易城:是否使用全部手牌交换" + get.translation(cards) + "?" + ) + .set( + "choice", + (() => { + return ( + cards.reduce((num, card) => num + get.value(card), 0) > + player + .getCards("h") + .reduce((num, card) => num + get.value(card), 0) + ); + })() + ); + if (bool) { + const hs = player.getCards("h"); + player.$throw(hs, 1000); + await player.lose(hs, ui.special); + await player.gain(cards, "gain2"); + cards = hs.slice(); + await player.showCards( + cards, + get.translation(player) + "【易城】第二次交换后" + ); } } } } - if(cards.length){ - await game.cardsDiscard(cards); - //game.log(cards,'被置入了弃牌堆'); + if (cards.length) { + for (let i = cards.length - 1; i--; i >= 0) { + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); + } + game.log(cards, "被放回了牌堆顶"); + game.updateRoundNumber(); } } }, - ai:{ - order:9, - result:{player:1}, + ai: { + order: 9, + result: { player: 1 }, }, }, //陆凯 - olxuanzhu:{ - mark:true, - marktext:'☯', - zhuanhuanji:true, - audio:2, - enable:'chooseToUse', - filter(event,player){ - if(!player.countCards('he')||event.type=='wuxie') return false; - return get.inpileVCardList(info=>{ - const name=info[2],type=get.type(name),infox=get.info({name:name}); - if(type!='basic'&&type!='trick') return false; - if(type=='trick'&&(!infox||!infox.filterTarget)) return false; - return (type!='basic')==(player.storage.olxuanzhu||false); - }).some(card=>event.filterCard({name:card[2],nature:card[3]},player,event)); + olxuanzhu: { + mark: true, + marktext: "☯", + zhuanhuanji: true, + audio: 2, + enable: "chooseToUse", + filter(event, player) { + if (!player.countCards("he") || event.type == "wuxie") return false; + return get + .inpileVCardList((info) => { + const name = info[2], + type = get.type(name), + infox = get.info({ name: name }); + if (type != "basic" && type != "trick") return false; + if (type == "trick" && (!infox || !infox.filterTarget)) return false; + return (type != "basic") == (player.storage.olxuanzhu || false); + }) + .some((card) => event.filterCard({ name: card[2], nature: card[3] }, player, event)); }, - usable:1, - chooseButton:{ - dialog(event,player){ - const list=get.inpileVCardList(info=>{ - const name=info[2],type=get.type(name),infox=get.info({name:name}); - if(type!='basic'&&type!='trick') return false; - if(type=='trick'&&(!infox||!infox.filterTarget)) return false; - return (type!='basic')==(player.storage.olxuanzhu||false); - }).filter(card=>event.filterCard({name:card[2],nature:card[3]},player,event)); - return ui.create.dialog('玄注',[list,'vcard']); + usable: 1, + chooseButton: { + dialog(event, player) { + const list = get + .inpileVCardList((info) => { + const name = info[2], + type = get.type(name), + infox = get.info({ name: name }); + if (type != "basic" && type != "trick") return false; + if (type == "trick" && (!infox || !infox.filterTarget)) return false; + return (type != "basic") == (player.storage.olxuanzhu || false); + }) + .filter((card) => + event.filterCard({ name: card[2], nature: card[3] }, player, event) + ); + return ui.create.dialog("玄注", [list, "vcard"]); }, - check(button){ - if(get.event().getParent().type!='phase') return 1; - return get.event('player').getUseValue({name:button.link[2],nature:button.link[3]}); + check(button) { + if (get.event().getParent().type != "phase") return 1; + return get + .event("player") + .getUseValue({ name: button.link[2], nature: button.link[3] }); }, - backup(links,player){ - let next={ - audio:'olxuanzhu', - filterCard:true, - popname:true, - check(card){ - return 1/(get.value(card)||0.5); + backup(links, player) { + let next = { + audio: "olxuanzhu", + filterCard: true, + popname: true, + check(card) { + return 1 / (get.value(card) || 0.5); }, - position:'he', - ignoreMod:true, - precontent(){ - const cards=event.result.cards.slice(); - player.addToExpansion(cards,player,'give').gaintag.add('olxuanzhu'); - const viewAs={name:event.result.card.name,nature:event.result.card.nature}; - event.result.card=viewAs;event.result.cards=[]; - player.when('useCardAfter').filter(evt=>evt.skill=='olxuanzhu_backup').then(()=>{ - const card=cards[0]; - if(get.type(card)!='equip') player.chooseToDiscard('he',true); - else{ - const cardx=player.getExpansions('olxuanzhu'); - if(cardx.length){ - player.loseToDiscardpile(cardx); - player.draw(cardx.length); + position: "he", + ignoreMod: true, + precontent() { + const cards = event.result.cards.slice(); + player.addToExpansion(cards, player, "give").gaintag.add("olxuanzhu"); + const viewAs = { + name: event.result.card.name, + nature: event.result.card.nature, + }; + event.result.card = viewAs; + event.result.cards = []; + player + .when("useCardAfter") + .filter((evt) => evt.skill == "olxuanzhu_backup") + .then(() => { + const card = cards[0]; + if (get.type(card) != "equip") player.chooseToDiscard("he", true); + else { + const cardx = player.getExpansions("olxuanzhu"); + if (cardx.length) { + player.loseToDiscardpile(cardx); + player.draw(cardx.length); + } } - } - }).vars({cards:cards}); + }) + .vars({ cards: cards }); }, - onuse(result,player){ - player.changeZhuanhuanji('olxuanzhu'); + onuse(result, player) { + player.changeZhuanhuanji("olxuanzhu"); }, }; - const viewAs={ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + const viewAs = { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }; - next.viewAs=viewAs; - if(get.info('xunshi').isXunshi(viewAs)){ - next.filterTarget=function(card,player,target){ - const info=get.info(card); - if(info.changeTarget){ - let targets=[target]; - info.changeTarget(player,targets); - if(targets.length>1) return false; + next.viewAs = viewAs; + if (get.info("xunshi").isXunshi(viewAs)) { + next.filterTarget = function (card, player, target) { + const info = get.info(card); + if (info.changeTarget) { + let targets = [target]; + info.changeTarget(player, targets); + if (targets.length > 1) return false; } - return lib.filter.filterTarget(card,player,target); + return lib.filter.filterTarget(card, player, target); }; - next.selectTarget=1; + next.selectTarget = 1; } return next; }, - prompt(links,player){ - const viewAs={ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + prompt(links, player) { + const viewAs = { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }; - const str='将一张牌称为“玄”置于武将牌上,然后视为使用'+(get.translation(links[0][3])||'')+'【'+get.translation(links[0][2])+'】'; - return str+(get.info('xunshi').isXunshi(viewAs)?'(仅能指定一个目标)':''); + const str = + "将一张牌称为“玄”置于武将牌上,然后视为使用" + + (get.translation(links[0][3]) || "") + + "【" + + get.translation(links[0][2]) + + "】"; + return str + (get.info("xunshi").isXunshi(viewAs) ? "(仅能指定一个目标)" : ""); }, }, - hiddenCard(player,name){ - if(!lib.inpile.includes(name)||player.getStat('skill').olxuanzhu||!player.countCards('he')) return false; - return get.inpileVCardList(info=>{ - const name=info[2],type=get.type(name),infox=get.info({name:name}); - if(type!='basic'&&type!='trick') return false; - if(type=='trick'&&(!infox||!infox.filterTarget)) return false; - return (type!='basic')==(player.storage.olxuanzhu||false); - }).map(card=>card[2]).includes(name); + hiddenCard(player, name) { + if ( + !lib.inpile.includes(name) || + player.getStat("skill").olxuanzhu || + !player.countCards("he") + ) + return false; + return get + .inpileVCardList((info) => { + const name = info[2], + type = get.type(name), + infox = get.info({ name: name }); + if (type != "basic" && type != "trick") return false; + if (type == "trick" && (!infox || !infox.filterTarget)) return false; + return (type != "basic") == (player.storage.olxuanzhu || false); + }) + .map((card) => card[2]) + .includes(name); }, - ai:{ - order(item,player){ - if(player&&get.event().type=='phase'){ - let list=get.inpileVCardList(info=>{ - const name=info[2],type=get.type(name),infox=get.info({name:name}); - if(type!='basic'&&type!='trick') return false; - if(type=='trick'&&(!infox||!infox.filterTarget)) return false; - return (type!='basic')==(player.storage.olxuanzhu||false); - }).map(card=>{return {name:card[2],nature:card[3]}}).filter(card=>player.getUseValue(card,true,true)>0); - if(!list.length) return 0; - list.sort((a,b)=>{ - const getNum=function(card){ - if(get.info('xunshi').isXunshi(card)) return get.effect(game.filterPlayer(target=>{ - return player.canUse(card,target,true,true); - }).sort((a,b)=>get.effect(b,card,player,player)-get.effect(a,card,player,player))[0],card,player,player); - return player.getUseValue(card,true,true); + ai: { + order(item, player) { + if (player && get.event().type == "phase") { + let list = get + .inpileVCardList((info) => { + const name = info[2], + type = get.type(name), + infox = get.info({ name: name }); + if (type != "basic" && type != "trick") return false; + if (type == "trick" && (!infox || !infox.filterTarget)) return false; + return (type != "basic") == (player.storage.olxuanzhu || false); + }) + .map((card) => { + return { name: card[2], nature: card[3] }; + }) + .filter((card) => player.getUseValue(card, true, true) > 0); + if (!list.length) return 0; + list.sort((a, b) => { + const getNum = function (card) { + if (get.info("xunshi").isXunshi(card)) + return get.effect( + game + .filterPlayer((target) => { + return player.canUse(card, target, true, true); + }) + .sort( + (a, b) => + get.effect(b, card, player, player) - + get.effect(a, card, player, player) + )[0], + card, + player, + player + ); + return player.getUseValue(card, true, true); }; - return (getNum(b)||0)-(getNum(a)||0); + return (getNum(b) || 0) - (getNum(a) || 0); }); - return get.order(list[0],player)*0.99; + return get.order(list[0], player) * 0.99; } return 0.001; }, - respondSha:true, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(arg=='respond') return false; - const name=(tag=='respondSha'?'sha':'shan'); - return get.info('olxuanzhu').hiddenCard(player,name); + respondSha: true, + respondShan: true, + skillTagFilter(player, tag, arg) { + if (arg == "respond") return false; + const name = tag == "respondSha" ? "sha" : "shan"; + return get.info("olxuanzhu").hiddenCard(player, name); }, - result:{player:1}, + result: { player: 1 }, }, - intro:{ - markcount:'expansion', - mark(dialog,storage,player){ - const cards=player.getExpansions('olxuanzhu'); - if(cards.length) dialog.addSmall(player.getExpansions('olxuanzhu')); - dialog.addText((()=>{ - if(storage) return '每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。'; - return '每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用任意基本牌。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。'; - })(storage)); + intro: { + markcount: "expansion", + mark(dialog, storage, player) { + const cards = player.getExpansions("olxuanzhu"); + if (cards.length) dialog.addSmall(player.getExpansions("olxuanzhu")); + dialog.addText( + (() => { + if (storage) + return "每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。"; + return "每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用任意基本牌。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。"; + })(storage) + ); }, }, - onremove(player,skill){ - const cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove(player, skill) { + const cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - subSkill:{backup:{}}, + subSkill: { backup: {} }, }, - oljiane:{ - audio:2, - trigger:{player:['shaDamage','useCardToEnd']}, - filter(event,player,name){ - if(event.type!='card'||!event.target||!event.target.isIn()||event.target==player) return false; - if(name=='shaDamage') return true; - return event.card.name!='sha'&&!event.getParent()._neutralized; + oljiane: { + audio: 2, + trigger: { player: ["shaDamage", "useCardToEnd"] }, + filter(event, player, name) { + if ( + event.type != "card" || + !event.target || + !event.target.isIn() || + event.target == player + ) + return false; + if (name == "shaDamage") return true; + return event.card.name != "sha" && !event.getParent()._neutralized; }, - logTarget:'target', - forced:true, - async content(event,trigger,player){ - trigger.target.addTempSkill('oljiane_neutralized'); + logTarget: "target", + forced: true, + async content(event, trigger, player) { + trigger.target.addTempSkill("oljiane_neutralized"); }, - group:'oljiane_neutralize', - global:'oljiane_ai', - subSkill:{ - neutralize:{ - audio:'oljiane', - trigger:{ - target:'shaMiss', - global:'eventNeutralized', + group: "oljiane_neutralize", + global: "oljiane_ai", + subSkill: { + neutralize: { + audio: "oljiane", + trigger: { + target: "shaMiss", + global: "eventNeutralized", }, - filter(event,player,name){ - if(event.type!='card') return false; - return name=='shaMiss'||event._neutralize_event.player==player; + filter(event, player, name) { + if (event.type != "card") return false; + return name == "shaMiss" || event._neutralize_event.player == player; }, - forced:true, - async content(event,trigger,player){ - player.addTempSkill('oljiane_nouse'); + forced: true, + async content(event, trigger, player) { + player.addTempSkill("oljiane_nouse"); }, }, - ai:{ - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(!arg||!arg.target||!arg.target.hasSkill('oljiane_neutralized')) return false; + ai: { + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if (!arg || !arg.target || !arg.target.hasSkill("oljiane_neutralized")) + return false; }, }, }, - neutralized:{ - charlotte:true, - mark:true, - marktext:'牌', - intro:{content:'本回合无法抵消牌'}, - trigger:{global:'useCard'}, - forced:true, - popup:false, - async content(event,trigger,player){ - const id=player.playerid; - const map=trigger.customArgs; - if(!map[id]) map[id]={}; - map[id].directHit2=true; + neutralized: { + charlotte: true, + mark: true, + marktext: "牌", + intro: { content: "本回合无法抵消牌" }, + trigger: { global: "useCard" }, + forced: true, + popup: false, + async content(event, trigger, player) { + const id = player.playerid; + const map = trigger.customArgs; + if (!map[id]) map[id] = {}; + map[id].directHit2 = true; }, - mod:{ - wuxieJudgeEnabled:()=>false, - wuxieEnabled:()=>false, + mod: { + wuxieJudgeEnabled: () => false, + wuxieEnabled: () => false, }, }, - nouse:{ - charlotte:true, - mark:true, - marktext:'', - intro:{content:'本回合无法成为牌的目标'}, - mod:{targetEnabled:()=>false}, + nouse: { + charlotte: true, + mark: true, + marktext: '', + intro: { content: "本回合无法成为牌的目标" }, + mod: { targetEnabled: () => false }, }, }, }, //刘磐 - olpijing:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!game.hasPlayer(target=>target!=player&&!event.targets.includes(target)&&lib.filter.targetEnabled2(event.card,player,target)&&lib.filter.targetInRange(event.card,player,target))) return false; - return get.color(event.card)=='black'&&(event.card.name=='sha'||get.type(event.card)=='trick')&&event.targets.length==1; + olpijing: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if ( + !game.hasPlayer( + (target) => + target != player && + !event.targets.includes(target) && + lib.filter.targetEnabled2(event.card, player, target) && + lib.filter.targetInRange(event.card, player, target) + ) + ) + return false; + return ( + get.color(event.card) == "black" && + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.targets.length == 1 + ); }, - usable:1, - direct:true, - locked:false, - async content(event,trigger,player){ - const num=Math.max(1,player.getDamagedHp()); - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('olpijing'),[1,num],(card,player,target)=>{ - const trigger=get.event().getTrigger(); - return target!=player&&!trigger.targets.includes(target)&&lib.filter.targetEnabled2(trigger.card,player,target)&&lib.filter.targetInRange(trigger.card,player,target); - }).set('ai',target=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - return get.effect(target,trigger.card,player,player)*(target.getStorage('olpijing_effect').includes(player)?2:1)+get.effect(target,{name:'shunshou_copy2'},player,player); - }).set('prompt2','令至多'+get.cnNumber(num)+'名角色成为'+get.translation(trigger.card)+'的目标并交给你一张牌'); - if(bool){ - player.logSkill('olpijing',targets); + usable: 1, + direct: true, + locked: false, + async content(event, trigger, player) { + const num = Math.max(1, player.getDamagedHp()); + const { + result: { bool, targets }, + } = await player + .chooseTarget(get.prompt("olpijing"), [1, num], (card, player, target) => { + const trigger = get.event().getTrigger(); + return ( + target != player && + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(trigger.card, player, target) && + lib.filter.targetInRange(trigger.card, player, target) + ); + }) + .set("ai", (target) => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + return ( + get.effect(target, trigger.card, player, player) * + (target.getStorage("olpijing_effect").includes(player) ? 2 : 1) + + get.effect(target, { name: "shunshou_copy2" }, player, player) + ); + }) + .set( + "prompt2", + "令至多" + + get.cnNumber(num) + + "名角色成为" + + get.translation(trigger.card) + + "的目标并交给你一张牌" + ); + if (bool) { + player.logSkill("olpijing", targets); trigger.targets.addArray(targets); - for(const target of targets){ - target.addSkill('olpijing_effect'); - target.markAuto('olpijing_effect',[player]); - await target.chooseToGive(player,'he',true,'披荆:交给'+get.translation(player)+'一张牌'); + for (const target of targets) { + target.addSkill("olpijing_effect"); + target.markAuto("olpijing_effect", [player]); + await target.chooseToGive( + player, + "he", + true, + "披荆:交给" + get.translation(player) + "一张牌" + ); } - } - else player.storage.counttrigger.olpijing--; + } else player.storage.counttrigger.olpijing--; }, - mod:{ - aiOrder(player,card,num){ - if(!(card.name=='sha'||get.type(card)=='trick')||get.color(card)!='black') return; - const info=get.info(card); - if(info&&!info.notarget&&(info.toself||info.singleCard||!info.selectTarget||info.selectTarget==1)&&game.countPlayer(target=>{ - if(get.effect(target,card,player,player)<=0) return false; - return lib.filter.targetEnabled2(card,player,target)&&lib.filter.targetInRange(card,player,target); - })>1) return num+0.01; + mod: { + aiOrder(player, card, num) { + if (!(card.name == "sha" || get.type(card) == "trick") || get.color(card) != "black") + return; + const info = get.info(card); + if ( + info && + !info.notarget && + (info.toself || + info.singleCard || + !info.selectTarget || + info.selectTarget == 1) && + game.countPlayer((target) => { + if (get.effect(target, card, player, player) <= 0) return false; + return ( + lib.filter.targetEnabled2(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); + }) > 1 + ) + return num + 0.01; }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - intro:{content:'使用的下一张基本牌或普通锦囊牌指定唯一目标时,可指定$为额外目标或摸一张牌'}, - trigger:{player:'useCardToPlayer'}, - filter(event,player){ - return (get.type(event.card)=='basic'||get.type(event.card)=='trick')&&event.targets.length==1; + subSkill: { + effect: { + charlotte: true, + onremove: true, + intro: { + content: + "使用的下一张基本牌或普通锦囊牌指定唯一目标时,可指定$为额外目标或摸一张牌", }, - forced:true, - popup:false, - async content(event,trigger,player){ - const storage=player.getStorage('olpijing_effect'); - player.removeSkill('olpijing_effect'); - const {result:{bool,targets}}=await player.chooseTarget('披荆:请选择此牌的额外目标',[1,storage.length],(card,player,target)=>{ - const trigger=get.event().getTrigger(); - return !trigger.targets.includes(target)&&get.event('storage').includes(target)&&lib.filter.targetEnabled2(trigger.card,player,target)&&lib.filter.targetInRange(trigger.card,player,target); - }).set('prompt2','不选择的角色视为你选择摸牌项').set('ai',target=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - return get.effect(target,trigger.card,player,player)-get.effect(player,{name:'draw'},player,player); - }).set('storage',storage); - if(bool){ + trigger: { player: "useCardToPlayer" }, + filter(event, player) { + return ( + (get.type(event.card) == "basic" || get.type(event.card) == "trick") && + event.targets.length == 1 + ); + }, + forced: true, + popup: false, + async content(event, trigger, player) { + const storage = player.getStorage("olpijing_effect"); + player.removeSkill("olpijing_effect"); + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "披荆:请选择此牌的额外目标", + [1, storage.length], + (card, player, target) => { + const trigger = get.event().getTrigger(); + return ( + !trigger.targets.includes(target) && + get.event("storage").includes(target) && + lib.filter.targetEnabled2(trigger.card, player, target) && + lib.filter.targetInRange(trigger.card, player, target) + ); + } + ) + .set("prompt2", "不选择的角色视为你选择摸牌项") + .set("ai", (target) => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + return ( + get.effect(target, trigger.card, player, player) - + get.effect(player, { name: "draw" }, player, player) + ); + }) + .set("storage", storage); + if (bool) { player.line(targets); trigger.targets.addArray(targets); - if(storage.length-targets.length>0){ - player.draw(storage.length-targets.length); + if (storage.length - targets.length > 0) { + player.draw(storage.length - targets.length); } - } - else player.draw(storage.length); + } else player.draw(storage.length); }, }, }, }, //郭图 - olqushi:{ - audio:2, - enable:'phaseUse', - usable:1, - delay:false, - async content(event,trigger,player){ + olqushi: { + audio: 2, + enable: "phaseUse", + usable: 1, + delay: false, + async content(event, trigger, player) { await player.draw(); - if(player.countCards('h')&&game.hasPlayer(target=>target!=player)){ - const {result:{bool,targets,cards}}=await player.chooseCardTarget({ - forced:true, - prompt:'将一张手牌作为“趋”扣置于其他角色的武将牌上', - filterTarget:lib.filter.notMe, - filterCard:true, - position:'h', - ai1(card){ - if(get.type(card,false)=='equip') return 1-get.value(card); - return 7-get.value(card); + if (player.countCards("h") && game.hasPlayer((target) => target != player)) { + const { + result: { bool, targets, cards }, + } = await player.chooseCardTarget({ + forced: true, + prompt: "将一张手牌作为“趋”扣置于其他角色的武将牌上", + filterTarget: lib.filter.notMe, + filterCard: true, + position: "h", + ai1(card) { + if (get.type(card, false) == "equip") return 1 - get.value(card); + return 7 - get.value(card); }, - ai2(target){ - const att=get.sgn(get.sgn(get.attitude(get.event('player'),target))+0.5); - return (target.countCards('h')+1)*att; + ai2(target) { + const att = get.sgn(get.sgn(get.attitude(get.event("player"), target)) + 0.5); + return (target.countCards("h") + 1) * att; }, }); - if(bool){ - const target=targets[0]; - target.addSkill('olqushi_effect'); - target.markAuto('olqushi_effect',[player]); - game.log(player,'将一张牌扣置于',target,'的武将牌上'); - target.addToExpansion(cards,player,'giveAuto').gaintag.add('olqushi_effect'); + if (bool) { + const target = targets[0]; + target.addSkill("olqushi_effect"); + target.markAuto("olqushi_effect", [player]); + game.log(player, "将一张牌扣置于", target, "的武将牌上"); + target.addToExpansion(cards, player, "giveAuto").gaintag.add("olqushi_effect"); } } }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove(player,skill){ + subSkill: { + effect: { + charlotte: true, + onremove(player, skill) { delete player.storage[skill]; - const cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + const cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'趋', - intro:{ - content:'expansion', - markcount:'expansion', - mark(dialog,storage,player){ - return '共扣置'+get.cnNumber(player.getExpansions('olqushi_effect').length)+'张“趋”'; + marktext: "趋", + intro: { + content: "expansion", + markcount: "expansion", + mark(dialog, storage, player) { + return ( + "共扣置" + + get.cnNumber(player.getExpansions("olqushi_effect").length) + + "张“趋”" + ); }, }, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - popup:false, - async content(event,trigger,player){ - const cards=player.getExpansions('olqushi_effect'); - if(cards.length){ + trigger: { player: "phaseJieshuBegin" }, + forced: true, + popup: false, + async content(event, trigger, player) { + const cards = player.getExpansions("olqushi_effect"); + if (cards.length) { await player.loseToDiscardpile(cards); - const targets=player.getStorage('olqushi_effect').filter(i=>{ - return i.isIn(); - }).sortBySeat(); - const num=Math.min(player.getHistory('useCard',evt=>{ - return evt.targets&&evt.targets.length; - }).reduce((sum,evt)=>{ - return sum+evt.targets.length - },0),5); - if(targets.length&&player.getHistory('useCard',evt=>{ - return cards.some(card=>get.type2(card)==get.type2(evt.card)); - }).length&&num){ - for(const target of targets) await target.draw(num); + const targets = player + .getStorage("olqushi_effect") + .filter((i) => { + return i.isIn(); + }) + .sortBySeat(); + const num = Math.min( + player + .getHistory("useCard", (evt) => { + return evt.targets && evt.targets.length; + }) + .reduce((sum, evt) => { + return sum + evt.targets.length; + }, 0), + 5 + ); + if ( + targets.length && + player.getHistory("useCard", (evt) => { + return cards.some((card) => get.type2(card) == get.type2(evt.card)); + }).length && + num + ) { + for (const target of targets) await target.draw(num); } } - player.removeSkill('olqushi_effect'); + player.removeSkill("olqushi_effect"); }, }, }, }, - olweijie:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter(event,player){ - if(!game.hasPlayer(target=>{ - return get.distance(player,target)==1&&target.countCards('h'); - })||_status.currentPhase===player||event.olweijie) return false; - return get.inpileVCardList(info=>{ - const name=info[2]; - return get.type(name)=='basic'; - }).some(card=>event.filterCard({name:card[2],nature:card[3],isCard:true},player,event)); + olweijie: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filter(event, player) { + if ( + !game.hasPlayer((target) => { + return get.distance(player, target) == 1 && target.countCards("h"); + }) || + _status.currentPhase === player || + event.olweijie + ) + return false; + return get + .inpileVCardList((info) => { + const name = info[2]; + return get.type(name) == "basic"; + }) + .some((card) => + event.filterCard({ name: card[2], nature: card[3], isCard: true }, player, event) + ); }, - chooseButton:{ - dialog(event,player){ - const list=get.inpileVCardList(info=>{ - const name=info[2]; - return get.type(name)=='basic'; - }).filter(card=>event.filterCard({name:card[2],nature:card[3],isCard:true},player,event)); - return ui.create.dialog('诿解',[list,'vcard']); + chooseButton: { + dialog(event, player) { + const list = get + .inpileVCardList((info) => { + const name = info[2]; + return get.type(name) == "basic"; + }) + .filter((card) => + event.filterCard( + { name: card[2], nature: card[3], isCard: true }, + player, + event + ) + ); + return ui.create.dialog("诿解", [list, "vcard"]); }, - filter(button,player){ - return get.event().getParent().filterCard({name:button.link[2],nature:button.link[3],isCard:true},player,_status.event.getParent()); + filter(button, player) { + return get + .event() + .getParent() + .filterCard( + { name: button.link[2], nature: button.link[3], isCard: true }, + player, + _status.event.getParent() + ); }, - check(button){ - if(get.event().getParent().type!='phase') return 1; - return get.event('player').getUseValue({name:button.link[2],nature:button.link[3],isCard:true}); + check(button) { + if (get.event().getParent().type != "phase") return 1; + return get + .event("player") + .getUseValue({ name: button.link[2], nature: button.link[3], isCard: true }); }, - backup(links,player){ + backup(links, player) { return { - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, }, - filterCard:()=>false, - selectCard:-1, - *precontent(event,map){ + filterCard: () => false, + selectCard: -1, + *precontent(event, map) { delete event.result.skill; - const player=map.player; - let stop=false; - const result=yield player.chooseTarget('请选择一名距离为1的角色','弃置其一张手牌,若此牌牌名为【'+get.translation(event.result.card.name)+'】,则视为你使用/打出之',(card,player,target)=>{ - return get.distance(player,target)==1&&target.countCards('h'); - }).set('ai',target=>1-get.sgn(get.attitude(get.event('player'),target))); - if(result.bool){ - const target=result.targets[0]; - player.logSkill('olweijie',target); - player.tempBanSkill('olweijie',null,false); - const result2=yield player.discardPlayerCard(target,'h',true).set('prompt2','若弃置的牌名为【'+get.translation(event.result.card.name)+'】,则视为你使用/打出之').set('ai',button=>{ - if(button.link.isKnownBy(get.event('player'))&&button.link.name==get.event('namex')) return 114514; - return 1+Math.random(); - }).set('namex',event.result.card.name); - if(result2.bool){ - const card=result2.cards[0]; - if(get.name(card,target)==event.result.card.name){ - player.popup('洗具'); - stop=true; + const player = map.player; + let stop = false; + const result = yield player + .chooseTarget( + "请选择一名距离为1的角色", + "弃置其一张手牌,若此牌牌名为【" + + get.translation(event.result.card.name) + + "】,则视为你使用/打出之", + (card, player, target) => { + return ( + get.distance(player, target) == 1 && target.countCards("h") + ); } - else player.popup('杯具'); + ) + .set( + "ai", + (target) => 1 - get.sgn(get.attitude(get.event("player"), target)) + ); + if (result.bool) { + const target = result.targets[0]; + player.logSkill("olweijie", target); + player.tempBanSkill("olweijie", null, false); + const result2 = yield player + .discardPlayerCard(target, "h", true) + .set( + "prompt2", + "若弃置的牌名为【" + + get.translation(event.result.card.name) + + "】,则视为你使用/打出之" + ) + .set("ai", (button) => { + if ( + button.link.isKnownBy(get.event("player")) && + button.link.name == get.event("namex") + ) + return 114514; + return 1 + Math.random(); + }) + .set("namex", event.result.card.name); + if (result2.bool) { + const card = result2.cards[0]; + if (get.name(card, target) == event.result.card.name) { + player.popup("洗具"); + stop = true; + } else player.popup("杯具"); } } - if(!stop){ - const evt=event.getParent(); - evt.set('olweijie',true); + if (!stop) { + const evt = event.getParent(); + evt.set("olweijie", true); evt.goto(0); delete evt.openskilldialog; return; } }, - } + }; }, - prompt(links,player){ - const nature=(get.translation(links[0][3])||''); - const name='【'+get.translation(links[0][2])+'】'; - return '弃置距离为1的一名角色的一张手牌,若此牌牌名为'+name+',则你视为使用'+nature+name; + prompt(links, player) { + const nature = get.translation(links[0][3]) || ""; + const name = "【" + get.translation(links[0][2]) + "】"; + return ( + "弃置距离为1的一名角色的一张手牌,若此牌牌名为" + + name + + ",则你视为使用" + + nature + + name + ); }, }, - ai:{ - order:10, - respondSha:true, - respondShan:true, - skillTagFilter(player,tag){ - const name=(tag=='respondSha'?'sha':'shan'); - return lib.skill.olweijie.hiddenCard(player,name); + ai: { + order: 10, + respondSha: true, + respondShan: true, + skillTagFilter(player, tag) { + const name = tag == "respondSha" ? "sha" : "shan"; + return lib.skill.olweijie.hiddenCard(player, name); }, - result:{ - player(player){ - if(_status.event.dying&&get.attitude(player,_status.event.dying)<=0) return 0; - return game.hasPlayer(target=>{ - if(get.attitude(player,target)>0) return false; - return get.distance(player,target)==1&&target.countCards('h'); - })?1:0; + result: { + player(player) { + if (_status.event.dying && get.attitude(player, _status.event.dying) <= 0) + return 0; + return game.hasPlayer((target) => { + if (get.attitude(player, target) > 0) return false; + return get.distance(player, target) == 1 && target.countCards("h"); + }) + ? 1 + : 0; }, }, }, - hiddenCard(player,name){ - if(!lib.inpile.includes(name)||_status.currentPhase===player||player.isTempBanned('olweijie')) return false; - return get.type(name)=='basic'&&game.hasPlayer(target=>{ - return get.distance(player,target)==1&&target.countCards('h'); - }); + hiddenCard(player, name) { + if ( + !lib.inpile.includes(name) || + _status.currentPhase === player || + player.isTempBanned("olweijie") + ) + return false; + return ( + get.type(name) == "basic" && + game.hasPlayer((target) => { + return get.distance(player, target) == 1 && target.countCards("h"); + }) + ); }, }, //胡金定 - olqingyuan:{ - audio:2, - trigger:{ - global:['phaseBefore','gainAfter','loseAsyncAfter'], - player:['enterGame','damageEnd'], + olqingyuan: { + audio: 2, + trigger: { + global: ["phaseBefore", "gainAfter", "loseAsyncAfter"], + player: ["enterGame", "damageEnd"], }, - filter(event,player){ - const storage=player.getStorage('olqingyuan'); - if(event.name=='gain'||event.name=='loseAsync'){ - if(player.hasSkill('olqingyuan_used')) return false; - return storage.some(target=>event.getg(target).length)&&storage.some(target=>target.hasCard(card=>lib.filter.canBeGained(card,target,player),'h')); + filter(event, player) { + const storage = player.getStorage("olqingyuan"); + if (event.name == "gain" || event.name == "loseAsync") { + if (player.hasSkill("olqingyuan_used")) return false; + return ( + storage.some((target) => event.getg(target).length) && + storage.some((target) => + target.hasCard((card) => lib.filter.canBeGained(card, target, player), "h") + ) + ); } - if(!game.hasPlayer(target=>!storage.includes(target)&&target!=player)) return false; - if(event.name=='damage'&&player.getAllHistory('damage').indexOf(event)!=0) return false; - return event.name!='phase'||game.phaseNumber==0; + if (!game.hasPlayer((target) => !storage.includes(target) && target != player)) + return false; + if (event.name == "damage" && player.getAllHistory("damage").indexOf(event) != 0) + return false; + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - async content(event,trigger,player){ - if(trigger.name=='gain'||trigger.name=='loseAsync'){ - const target=player.getStorage('olqingyuan').filter(target=>target.hasCard(card=>lib.filter.canBeGained(card,target,player),'h')).randomGet(); + forced: true, + async content(event, trigger, player) { + if (trigger.name == "gain" || trigger.name == "loseAsync") { + const target = player + .getStorage("olqingyuan") + .filter((target) => + target.hasCard((card) => lib.filter.canBeGained(card, target, player), "h") + ) + .randomGet(); player.line(target); - player.addTempSkill('olqingyuan_used'); - player.gain(target.getCards('h',card=>{ - return lib.filter.canBeGained(card,target,player); - }).randomGet(),target,'giveAuto'); - } - else{ - const filterTarget=(card,player,target)=>{ - return target!=player&&!player.getStorage('olqingyuan').includes(target); - },targetsx=game.filterPlayer(current=>filterTarget(null,player,current)); + player.addTempSkill("olqingyuan_used"); + player.gain( + target + .getCards("h", (card) => { + return lib.filter.canBeGained(card, target, player); + }) + .randomGet(), + target, + "giveAuto" + ); + } else { + const filterTarget = (card, player, target) => { + return target != player && !player.getStorage("olqingyuan").includes(target); + }, + targetsx = game.filterPlayer((current) => filterTarget(null, player, current)); let result; - if(targetsx.length==1) result={bool:true,targets:targetsx}; - else result=await player.chooseTarget(filterTarget,true).set('prompt2','每回合限一次,当你以此法选择的角色获得牌后,你随机获得其中一名角色的一张手牌') - .set('prompt','请选择【轻缘】的目标').set('ai',target=>{ - const player=get.event('player'); - return get.effect(target,new lib.element.VCard({name:'shunshou_copy2'}),player,player); - }) - .forResult(); - if(result.bool){ - const target=result.targets[0]; + if (targetsx.length == 1) result = { bool: true, targets: targetsx }; + else + result = await player + .chooseTarget(filterTarget, true) + .set( + "prompt2", + "每回合限一次,当你以此法选择的角色获得牌后,你随机获得其中一名角色的一张手牌" + ) + .set("prompt", "请选择【轻缘】的目标") + .set("ai", (target) => { + const player = get.event("player"); + return get.effect( + target, + new lib.element.VCard({ name: "shunshou_copy2" }), + player, + player + ); + }) + .forResult(); + if (result.bool) { + const target = result.targets[0]; player.line(target); - game.log(player,'选择了',target); - player.markAuto('olqingyuan',[target]); + game.log(player, "选择了", target); + player.markAuto("olqingyuan", [target]); } } }, - subSkill:{used:{charlotte:true}}, - intro:{content:'已选择$为目标'}, - ai:{ - expose:0.3, + subSkill: { used: { charlotte: true } }, + intro: { content: "已选择$为目标" }, + ai: { + expose: 0.3, }, }, - olchongshen:{ - audio:2, - locked:false, - enable:'chooseToUse', - filterCard(card){ - return get.itemtype(card)=='card'&&card.hasGaintag('olchongshen')&&get.color(card)=='red'; + olchongshen: { + audio: 2, + locked: false, + enable: "chooseToUse", + filterCard(card) { + return ( + get.itemtype(card) == "card" && + card.hasGaintag("olchongshen") && + get.color(card) == "red" + ); }, - position:'h', - viewAs:{name:'shan'}, - viewAsFilter(player){ - if(!player.countCards('h',card=>card.hasGaintag('olchongshen')&&get.color(card)=='red')) return false; + position: "h", + viewAs: { name: "shan" }, + viewAsFilter(player) { + if ( + !player.countCards( + "h", + (card) => card.hasGaintag("olchongshen") && get.color(card) == "red" + ) + ) + return false; }, - prompt:'将本轮得到的红色牌当作【闪】使用', - check(card){ - return 7-get.value(card); + prompt: "将本轮得到的红色牌当作【闪】使用", + check(card) { + return 7 - get.value(card); }, - ai:{ - order:2, - respondShan:true, - skillTagFilter(player,tag,arg){ - if(arg=='respond'||!player.countCards('h',card=>_status.connectMode||card.hasGaintag('olchongshen')&&get.color(card)=='red')) return false; + ai: { + order: 2, + respondShan: true, + skillTagFilter(player, tag, arg) { + if ( + arg == "respond" || + !player.countCards( + "h", + (card) => + _status.connectMode || + (card.hasGaintag("olchongshen") && get.color(card) == "red") + ) + ) + return false; }, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.6; + effect: { + target(card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.6; }, }, }, - group:'olchongshen_mark', - mod:{ - aiValue(player,card,num){ - if(get.name(card)!='shan'&&(get.itemtype(card)=='card'&&(!card.hasGaintag('olchongshen')||get.color(card)!='red'))) return; - let cards=player.getCards('hs',card=>get.name(card)=='shan'||card.hasGaintag('olchongshen')); - cards.sort((a,b)=>(get.name(b)=='shan'?1:2)-(get.name(a)=='shan'?1:2)); - const geti=()=>{ - if(cards.includes(card)) return cards.indexOf(card); + group: "olchongshen_mark", + mod: { + aiValue(player, card, num) { + if ( + get.name(card) != "shan" && + get.itemtype(card) == "card" && + (!card.hasGaintag("olchongshen") || get.color(card) != "red") + ) + return; + let cards = player.getCards( + "hs", + (card) => get.name(card) == "shan" || card.hasGaintag("olchongshen") + ); + cards.sort( + (a, b) => (get.name(b) == "shan" ? 1 : 2) - (get.name(a) == "shan" ? 1 : 2) + ); + const geti = () => { + if (cards.includes(card)) return cards.indexOf(card); return cards.length; }; - if(get.name(card)=='shan') return Math.min(num,[6,4,3][Math.min(geti(),2)])*0.6; - return Math.max(num,[6.5,4,3][Math.min(geti(),2)]); + if (get.name(card) == "shan") + return Math.min(num, [6, 4, 3][Math.min(geti(), 2)]) * 0.6; + return Math.max(num, [6.5, 4, 3][Math.min(geti(), 2)]); }, - aiUseful(){ - return lib.skill.olchongshen.mod.aiValue.apply(this,arguments); + aiUseful() { + return lib.skill.olchongshen.mod.aiValue.apply(this, arguments); }, // ignoredHandcard(card,player){ // if(card.hasGaintag('olchongshen')) return true; @@ -1370,285 +2144,397 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // if(name=='phaseDiscard'&&card.hasGaintag('olchongshen')) return false; // }, }, - init(player){ - if(game.phaseNumber>0){ - const hs=player.getCards('h'),history=player.getAllHistory(); - let cards=[]; - for(let i=history.length-1;i>=0;i--){ - for(const evt of history[i].gain){ + init(player) { + if (game.phaseNumber > 0) { + const hs = player.getCards("h"), + history = player.getAllHistory(); + let cards = []; + for (let i = history.length - 1; i >= 0; i--) { + for (const evt of history[i].gain) { cards.addArray(evt.cards); } - if(history[i].isRound) break; + if (history[i].isRound) break; } - cards=cards.filter(i=>hs.includes(i)); - if(cards.length) player.addGaintag(cards,'olchongshen'); + cards = cards.filter((i) => hs.includes(i)); + if (cards.length) player.addGaintag(cards, "olchongshen"); } }, - onremove(player){ - player.removeGaintag('olchongshen'); + onremove(player) { + player.removeGaintag("olchongshen"); }, - subSkill:{ - mark:{ - charlotte:true, - trigger:{player:'gainBegin',global:'roundStart'}, - filter(event,player){ - return event.name=='gain'||game.roundNumber>1; + subSkill: { + mark: { + charlotte: true, + trigger: { player: "gainBegin", global: "roundStart" }, + filter(event, player) { + return event.name == "gain" || game.roundNumber > 1; }, - forced:true, - popup:false, - content(){ - if(trigger.name=='gain') trigger.gaintag.add('olchongshen'); - else player.removeGaintag('olchongshen'); + forced: true, + popup: false, + content() { + if (trigger.name == "gain") trigger.gaintag.add("olchongshen"); + else player.removeGaintag("olchongshen"); }, }, }, }, //田畴 - olshandao:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>lib.skill.olshandao.filterTarget(null,player,target)); + olshandao: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => lib.skill.olshandao.filterTarget(null, player, target)); }, - filterTarget(card,player,target){ - return target.countCards('he'); + filterTarget(card, player, target) { + return target.countCards("he"); }, - usable:1, - selectTarget:[1,Infinity], - multitarget:true, - multiline:true, - async content(event,trigger,player){ - const wugu=new lib.element.VCard({name:'wugu'}); - const wanjian=new lib.element.VCard({name:'wanjian'}); - const targets=game.filterPlayer(target=>{ - if(target==player) return false; - return !event.targets.includes(target)&&player.canUse(wanjian,target,false); - }),targetx=event.targets.sortBySeat(); - let dialog=['将这些角色的各一张牌置于牌堆顶,然后视为对这些角色使用【五谷丰登】']; - for(const target of targetx){ - const name=(target==player?'你':get.translation(target)); - if(target.countCards('h')){ - dialog.add('
              '+name+'的手牌区
              '); - if(player.hasSkillTag('viewHandcard',null,target,true)||player==target) dialog.push(target.getCards('h')); - else dialog.push([target.getCards('h'),'blank']); + usable: 1, + selectTarget: [1, Infinity], + multitarget: true, + multiline: true, + async content(event, trigger, player) { + const wugu = new lib.element.VCard({ name: "wugu" }); + const wanjian = new lib.element.VCard({ name: "wanjian" }); + const targets = game.filterPlayer((target) => { + if (target == player) return false; + return !event.targets.includes(target) && player.canUse(wanjian, target, false); + }), + targetx = event.targets.sortBySeat(); + let dialog = ["将这些角色的各一张牌置于牌堆顶,然后视为对这些角色使用【五谷丰登】"]; + for (const target of targetx) { + const name = target == player ? "你" : get.translation(target); + if (target.countCards("h")) { + dialog.add('
              ' + name + "的手牌区
              "); + if (player.hasSkillTag("viewHandcard", null, target, true) || player == target) + dialog.push(target.getCards("h")); + else dialog.push([target.getCards("h"), "blank"]); } - if(target.countCards('e')) dialog.addArray(['
              '+name+'的装备区
              ',target.getCards('e')]); + if (target.countCards("e")) + dialog.addArray([ + '
              ' + name + "的装备区
              ", + target.getCards("e"), + ]); } - const {result:{bool,links}}=await player.chooseButton(dialog,event.targets.length,true).set('filterButton',button=>{ - return !ui.selected.buttons.some(but=>get.owner(but.link)==get.owner(button.link)); - }).set('ai',button=>1/(get.value(button.link,get.owner(button.link))||0.5)); - if(bool){ - const cards=links.sort((a,b)=>targetx.indexOf(get.owner(a))-targetx.indexOf(get.owner(b))); - for(const card of cards){ - const target=get.owner(card); - target.$throw(1,1000); - await target.lose([card],ui.cardPile,'insert'); + const { + result: { bool, links }, + } = await player + .chooseButton(dialog, event.targets.length, true) + .set("filterButton", (button) => { + return !ui.selected.buttons.some( + (but) => get.owner(but.link) == get.owner(button.link) + ); + }) + .set("ai", (button) => 1 / (get.value(button.link, get.owner(button.link)) || 0.5)); + if (bool) { + const cards = links.sort( + (a, b) => targetx.indexOf(get.owner(a)) - targetx.indexOf(get.owner(b)) + ); + for (const card of cards) { + const target = get.owner(card); + target.$throw(1, 1000); + await target.lose([card], ui.cardPile, "insert"); } - const targety=targetx.filter(target=>player.canUse(wugu,target,false)); - if(targety.length) await player.useCard(wugu,targety,false); - if(targets.length) await player.useCard(wanjian,targets,false); + const targety = targetx.filter((target) => player.canUse(wugu, target, false)); + if (targety.length) await player.useCard(wugu, targety, false); + if (targets.length) await player.useCard(wanjian, targets, false); } }, - ai:{ - order:9, - result:{target:1}, + ai: { + order: 9, + result: { target: 1 }, }, }, //李异 - olchanshuang:{ - audio:2, - enable:'phaseUse', - filterTarget:lib.filter.notMe, - usable:1, - content:function*(event,map){ - const player=map.player,target=event.target; - const choiceList=[ - '重铸一张牌', - '使用一张【杀】', - '弃置两张牌', - ],list=['重铸','出杀','弃牌','无法选择']; - let result=[]; - for(let current of [player,target]){ - let list1=list.slice(),choiceList1=choiceList.slice(); - list1=list1.filter(control=>{ - if(control=='无法选择') return false; - if(control=='重铸') return current.countCards('he',card=>current.canRecast(card)); - if(control=='出杀') return current.countCards('he',card=>card.name=='sha'&¤t.hasUseTarget(card)); - if(control=='弃牌') return current.countCards('he',card=>lib.filter.cardDiscardable(card,current))>1; + olchanshuang: { + audio: 2, + enable: "phaseUse", + filterTarget: lib.filter.notMe, + usable: 1, + content: function* (event, map) { + const player = map.player, + target = event.target; + const choiceList = ["重铸一张牌", "使用一张【杀】", "弃置两张牌"], + list = ["重铸", "出杀", "弃牌", "无法选择"]; + let result = []; + for (let current of [player, target]) { + let list1 = list.slice(), + choiceList1 = choiceList.slice(); + list1 = list1.filter((control) => { + if (control == "无法选择") return false; + if (control == "重铸") + return current.countCards("he", (card) => current.canRecast(card)); + if (control == "出杀") + return current.countCards( + "he", + (card) => card.name == "sha" && current.hasUseTarget(card) + ); + if (control == "弃牌") + return ( + current.countCards("he", (card) => + lib.filter.cardDiscardable(card, current) + ) > 1 + ); }); - choiceList1=choiceList.filter(control=>{ - if(choiceList.indexOf(control)==0) return current.countCards('he',card=>current.canRecast(card)); - if(choiceList.indexOf(control)==1) return current.countCards('he',card=>card.name=='sha'&¤t.hasUseTarget(card)); - if(choiceList.indexOf(control)==2) return current.countCards('he',card=>lib.filter.cardDiscardable(card,current))>1; + choiceList1 = choiceList.filter((control) => { + if (choiceList.indexOf(control) == 0) + return current.countCards("he", (card) => current.canRecast(card)); + if (choiceList.indexOf(control) == 1) + return current.countCards( + "he", + (card) => card.name == "sha" && current.hasUseTarget(card) + ); + if (choiceList.indexOf(control) == 2) + return ( + current.countCards("he", (card) => + lib.filter.cardDiscardable(card, current) + ) > 1 + ); }); - if(list1.length){ - if(list1.length==1) result.push(list.indexOf(list1[0])); - else{ - let result1=yield current.chooseControl(list1).set('ai',()=>{ - const current=_status.event.player; - const controls=_status.event.controls.slice(); - if(controls.includes('出杀')&¤t.countCards('hs',card=>card.name=='sha'&¤t.hasValueTarget(card))) return '出杀'; - if(controls.includes('重铸')) return '重铸'; - return '弃牌'; - }).set('choiceList',choiceList1); - if(result1.control) result.push(list.indexOf(result1.control)); + if (list1.length) { + if (list1.length == 1) result.push(list.indexOf(list1[0])); + else { + let result1 = yield current + .chooseControl(list1) + .set("ai", () => { + const current = _status.event.player; + const controls = _status.event.controls.slice(); + if ( + controls.includes("出杀") && + current.countCards( + "hs", + (card) => card.name == "sha" && current.hasValueTarget(card) + ) + ) + return "出杀"; + if (controls.includes("重铸")) return "重铸"; + return "弃牌"; + }) + .set("choiceList", choiceList1); + if (result1.control) result.push(list.indexOf(result1.control)); } - } - else result.push(3); + } else result.push(3); } player.popup(list[result[0]]); target.popup(list[result[1]]); - for(let current of [player,target]){ - switch(list[result[current==player?0:1]]){ - case '重铸': - let result2=yield current.chooseCard('he','请重铸一张牌',(card,player)=>player.canRecast(card),true); - if(result2.bool) current.recast(result2.cards); + for (let current of [player, target]) { + switch (list[result[current == player ? 0 : 1]]) { + case "重铸": + let result2 = yield current.chooseCard( + "he", + "请重铸一张牌", + (card, player) => player.canRecast(card), + true + ); + if (result2.bool) current.recast(result2.cards); break; - case '出杀': + case "出杀": current.chooseToUse({ - prompt:'请使用一张【杀】', - filterCard:function(card,player){ - if(card.name!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); + prompt: "请使用一张【杀】", + filterCard: function (card, player) { + if (card.name != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); }, - forced:true, - ai1:function(card){ + forced: true, + ai1: function (card) { return _status.event.player.getUseValue(card); }, }); break; - case '弃牌': - current.chooseToDiscard('he',2,true); + case "弃牌": + current.chooseToDiscard("he", 2, true); break; } } }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'},player)-0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }, player) - 0.1; }, - result:{ - target:function(player,target){ - const att=get.attitude(player,target); - if(target.countCards('hs',card=>{ - return card.name=='sha'&&game.hasPlayer(current=>{ - return target.canUse(card,current)&&get.effect(current,card,target,target)>0&&get.effect(current,card,target,player)>0; - }); - })) return 3; - if(att>0) return 2; - if(!target.countCards('h')) return get.sgn(att)+(att==0?1:0); + result: { + target: function (player, target) { + const att = get.attitude(player, target); + if ( + target.countCards("hs", (card) => { + return ( + card.name == "sha" && + game.hasPlayer((current) => { + return ( + target.canUse(card, current) && + get.effect(current, card, target, target) > 0 && + get.effect(current, card, target, player) > 0 + ); + }) + ); + }) + ) + return 3; + if (att > 0) return 2; + if (!target.countCards("h")) return get.sgn(att) + (att == 0 ? 1 : 0); return 0; }, }, }, - group:'olchanshuang_end', - subSkill:{ - end:{ - audio:'olchanshuang', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getHistory('lose',evt=>{ - if(evt.type=='discard'){ - var evtx=evt.getl(player); - return evtx&&evtx.cards2.length==2; - } - return evt.getParent(2).name=='recast'; - }).length||player.getHistory('useCard',evt=>evt.card.name=='sha').length; + group: "olchanshuang_end", + subSkill: { + end: { + audio: "olchanshuang", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.getHistory("lose", (evt) => { + if (evt.type == "discard") { + var evtx = evt.getl(player); + return evtx && evtx.cards2.length == 2; + } + return evt.getParent(2).name == "recast"; + }).length || + player.getHistory("useCard", (evt) => evt.card.name == "sha").length + ); }, - forced:true, - locked:false, - content:function*(event,map){ - let num=0,player=map.player; - if(player.getHistory('lose',evt=>evt.getParent(2).name=='recast').length) num++; - if(player.getHistory('useCard',evt=>evt.card.name=='sha').length) num++; - if(player.getHistory('lose',evt=>{ - if(evt.type=='discard'){ - var evtx=evt.getl(player); - return evtx&&evtx.cards2.length==2; - } - }).length) num++; - if(num&&player.countCards('he',card=>player.canRecast(card))){ - let result=yield player.chooseCard('he','请重铸一张牌',(card,player)=>player.canRecast(card),true); - if(result.bool) yield player.recast(result.cards); + forced: true, + locked: false, + content: function* (event, map) { + let num = 0, + player = map.player; + if (player.getHistory("lose", (evt) => evt.getParent(2).name == "recast").length) + num++; + if (player.getHistory("useCard", (evt) => evt.card.name == "sha").length) num++; + if ( + player.getHistory("lose", (evt) => { + if (evt.type == "discard") { + var evtx = evt.getl(player); + return evtx && evtx.cards2.length == 2; + } + }).length + ) + num++; + if (num && player.countCards("he", (card) => player.canRecast(card))) { + let result = yield player.chooseCard( + "he", + "请重铸一张牌", + (card, player) => player.canRecast(card), + true + ); + if (result.bool) yield player.recast(result.cards); } - if(num>1&&player.countCards('he',card=>card.name=='sha'&&player.hasUseTarget(card))){ + if ( + num > 1 && + player.countCards( + "he", + (card) => card.name == "sha" && player.hasUseTarget(card) + ) + ) { yield player.chooseToUse({ - prompt:'请使用一张【杀】', - filterCard:function(card,player){ - if(card.name!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); + prompt: "请使用一张【杀】", + filterCard: function (card, player) { + if (card.name != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); }, - forced:true, - ai1:function(card){ + forced: true, + ai1: function (card) { return _status.event.player.getUseValue(card); }, }); } - if(num>2&&player.countCards('he',card=>lib.filter.cardDiscardable(card,player))) yield player.chooseToDiscard('he',2,true); + if ( + num > 2 && + player.countCards("he", (card) => lib.filter.cardDiscardable(card, player)) + ) + yield player.chooseToDiscard("he", 2, true); }, }, }, }, - olzhanjin:{ - audio:2, - locked:true, - group:'olzhanjin_guanshi', - subSkill:{ - guanshi:{ - audio:'olzhanjin', - nobracket:true, - equipSkill:true, - trigger:{player:['shaMiss','eventNeutralized']}, - filter:function(event,player){ - if(!player.hasEmptySlot(1)||!lib.card.guanshi||player.hasSkillTag('unequip_equip1')) return false; - if(event.type!='card'||event.card.name!='sha'||!event.target.isIn()) return false; - return player.countCards('he')>=2; + olzhanjin: { + audio: 2, + locked: true, + group: "olzhanjin_guanshi", + subSkill: { + guanshi: { + audio: "olzhanjin", + nobracket: true, + equipSkill: true, + trigger: { player: ["shaMiss", "eventNeutralized"] }, + filter: function (event, player) { + if ( + !player.hasEmptySlot(1) || + !lib.card.guanshi || + player.hasSkillTag("unequip_equip1") + ) + return false; + if (event.type != "card" || event.card.name != "sha" || !event.target.isIn()) + return false; + return player.countCards("he") >= 2; }, - direct:true, - locked:false, - content:function(){ - "step 0" - player.chooseToDiscard(get.prompt('olzhanjin_guanshi'),'弃置两张牌,令'+get.translation(trigger.card)+'强制命中',2,'he').set('ai',function(card){ - var evt=_status.event.getTrigger(); - if(get.attitude(evt.player,evt.target)<0){ - if(player.needsToDiscard()) return 15-get.value(card); - if(evt.baseDamage+evt.extraDamage>=Math.min(2,evt.target.hp)) return 8-get.value(card); - return 5-get.value(card); - } - return -1; - }).set('complexCard',true).logSkill='olzhanjin_guanshi'; - 'step 1' - if(result.bool){ - if(event.triggername=='shaMiss'){ + direct: true, + locked: false, + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("olzhanjin_guanshi"), + "弃置两张牌,令" + get.translation(trigger.card) + "强制命中", + 2, + "he" + ) + .set("ai", function (card) { + var evt = _status.event.getTrigger(); + if (get.attitude(evt.player, evt.target) < 0) { + if (player.needsToDiscard()) return 15 - get.value(card); + if (evt.baseDamage + evt.extraDamage >= Math.min(2, evt.target.hp)) + return 8 - get.value(card); + return 5 - get.value(card); + } + return -1; + }) + .set("complexCard", true).logSkill = "olzhanjin_guanshi"; + "step 1"; + if (result.bool) { + if (event.triggername == "shaMiss") { trigger.untrigger(); - trigger.trigger('shaHit'); - trigger._result.bool=false; - trigger._result.result=null; - } - else trigger.unneutralize(); + trigger.trigger("shaHit"); + trigger._result.bool = false; + trigger._result.result = null; + } else trigger.unneutralize(); } }, - mod:{ - attackRange:function(player,num){ - if(lib.card.guanshi&&player.hasEmptySlot(1)) return num-lib.card.guanshi.distance.attackFrom; + mod: { + attackRange: function (player, num) { + if (lib.card.guanshi && player.hasEmptySlot(1)) + return num - lib.card.guanshi.distance.attackFrom; }, }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(player._olzhanjin_guanshi_temp||!player.hasEmptySlot(1)||!lib.card.guanshi||player.hasSkillTag('unequip_equip1')) return; - player._olzhanjin_guanshi_temp=true; - var bool=(get.attitude(player,arg.target)<0&&arg.card&&arg.card.name=='sha'&&player.countCards('he',card=>{ - return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card))&&get.value(card)<5; - })>1); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + player._olzhanjin_guanshi_temp || + !player.hasEmptySlot(1) || + !lib.card.guanshi || + player.hasSkillTag("unequip_equip1") + ) + return; + player._olzhanjin_guanshi_temp = true; + var bool = + get.attitude(player, arg.target) < 0 && + arg.card && + arg.card.name == "sha" && + player.countCards("he", (card) => { + return ( + card != arg.card && + (!arg.card.cards || !arg.card.cards.includes(card)) && + get.value(card) < 5 + ); + }) > 1; delete player._olzhanjin_guanshi_temp; return bool; }, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('unequip_equip1')) return; - if(player==target&&get.subtype(card)=='equip1'){ - if(get.equipValue(card)<=get.equipValue({name:'guanshi'})) return 0; + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("unequip_equip1")) return; + if (player == target && get.subtype(card) == "equip1") { + if (get.equipValue(card) <= get.equipValue({ name: "guanshi" })) + return 0; } }, }, @@ -1657,1050 +2543,1449 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //曹宇 - olgongjie:{ - audio:2, - trigger:{global:'phaseBegin'}, - filter(event,player){ - if(!player.countCards('he')) return false; - return !game.hasPlayer(current=>{ - var history=current.actionHistory; - for(var num=history.length-1;num>=0;num--){ - if(history[num].isRound) break; - if(history[num].isSkipped) continue; + olgongjie: { + audio: 2, + trigger: { global: "phaseBegin" }, + filter(event, player) { + if (!player.countCards("he")) return false; + return !game.hasPlayer((current) => { + var history = current.actionHistory; + for (var num = history.length - 1; num >= 0; num--) { + if (history[num].isRound) break; + if (history[num].isSkipped) continue; return true; } return false; }); }, - direct:true, - async content(event,trigger,player){ - var num=player.countCards('he'),draws=[]; - var {result:{bool,targets}}=await player.chooseTarget(get.prompt2('olgongjie'),[1,num],lib.filter.notMe).set('ai',target=>get.attitude(_status.event.player,target)); - if(!bool) return; - targets=targets.sortBySeat(); - player.logSkill('olgongjie',targets); - for(var target of targets){ - var {result:{bool,cards}}=await target.gainPlayerCard(player,true,'he'); - if(bool) draws.add(get.suit(cards[0],player)); + direct: true, + async content(event, trigger, player) { + var num = player.countCards("he"), + draws = []; + var { + result: { bool, targets }, + } = await player + .chooseTarget(get.prompt2("olgongjie"), [1, num], lib.filter.notMe) + .set("ai", (target) => get.attitude(_status.event.player, target)); + if (!bool) return; + targets = targets.sortBySeat(); + player.logSkill("olgongjie", targets); + for (var target of targets) { + var { + result: { bool, cards }, + } = await target.gainPlayerCard(player, true, "he"); + if (bool) draws.add(get.suit(cards[0], player)); } player.draw(draws.length); }, }, - olxiangxv:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'], + olxiangxv: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "gainAfter", + "equipAfter", + "addJudgeAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter(event,player){ - if(!_status.currentPhase||!_status.currentPhase.isIn()) return false; - if(!player.isMinHandcard()) return false; - var evt=event.getl(player); - if(evt&&evt.player==player&&evt.hs&&evt.hs.length>0) return true; - if(event.getg) return game.hasPlayer(current=>{ - var cards=event.getg(current); - if(!cards.length) return false; - return current.countCards('h')>=player.countCards('h')&¤t.countCards('h')-cards.length 0) return true; + if (event.getg) + return game.hasPlayer((current) => { + var cards = event.getg(current); + if (!cards.length) return false; + return ( + current.countCards("h") >= player.countCards("h") && + current.countCards("h") - cards.length < player.countCards("h") + ); + }); return false; }, - check(event,player){ - var target=_status.currentPhase; - var cards=target.getCards('h'); - if(target.isPhaseUsing()){ - var cardx=cards.filter(card=>get.name(card)=='sha'); - cardx.sort((a,b)=>target.getUseValue(b)-target.getUseValue(a)); - cardx=cardx.slice(Math.min(cardx.length,target.getCardUsable('sha')),cardx.length); + check(event, player) { + var target = _status.currentPhase; + var cards = target.getCards("h"); + if (target.isPhaseUsing()) { + var cardx = cards.filter((card) => get.name(card) == "sha"); + cardx.sort((a, b) => target.getUseValue(b) - target.getUseValue(a)); + cardx = cardx.slice( + Math.min(cardx.length, target.getCardUsable("sha")), + cardx.length + ); cards.removeArray(cardx); } - return cards.length-player.countCards('h')>0; + return cards.length - player.countCards("h") > 0; }, - usable:1, - logTarget:()=>_status.currentPhase, - async content(event,trigger,player){ - player.when({global:'phaseEnd'}).then(()=>{ - if(target&&target.isIn()){ - var num=target.countCards('h')-player.countCards('h'); - if(num){ - if(num>0){ - if(player.countCards('h')<5) player.draw(Math.min(5-player.countCards('h'),num)); - } - else player.chooseToDiscard(-num,'h',true); + usable: 1, + logTarget: () => _status.currentPhase, + async content(event, trigger, player) { + player + .when({ global: "phaseEnd" }) + .then(() => { + if (target && target.isIn()) { + var num = target.countCards("h") - player.countCards("h"); + if (num) { + if (num > 0) { + if (player.countCards("h") < 5) + player.draw(Math.min(5 - player.countCards("h"), num)); + event.finish(); + } else player.chooseToDiscard(-num, "h", true); + } else event.finish(); + } else event.finish(); + }) + .then(() => { + if (result.bool && result.cards.length > 1) { + if (player.isDamaged()) player.recover(); } - } - }).vars({target:_status.currentPhase}); + }) + .vars({ target: _status.currentPhase }); }, }, - olxiangzuo:{ - audio:2, - trigger:{player:'dying'}, - filter(event,player){ - if(!_status.currentPhase||!_status.currentPhase.isIn()) return false; - return player.countCards('he'); + olxiangzuo: { + audio: 2, + trigger: { player: "dying" }, + filter(event, player) { + return player.countCards("he") && game.hasPlayer((target) => target != player); }, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'water', - async content(event,trigger,player){ - var target=_status.currentPhase,num=player.countCards('he'); - var {result:{bool,cards}}=await player.chooseToGive(get.prompt2('olxiangzuo',target),[1,num],'he').set('ai',card=>{ - var player=_status.event.player,target=_status.event.target; - if(player.getHistory('useSkill',evt=>{ - return evt.skill=='olgongjie'&&evt.targets.includes(target); - }).length&&player.getHistory('useSkill',evt=>{ - return evt.skill=='olxiangxv'&&evt.targets.includes(target); - }).length){ - if(get.attitude(player,target)>0) return 1; - if(player.canSaveCard(card,player)) return 0; - if(ui.selected.cards.length+player.hp>=player.maxHp) return 0; - return 20-get.value(card); - } - else{ - if(get.attitude(player,target)>0&&!player.countCards('he',cardx=>player.canSaveCard(cardx,player))) return 1; - return 0; - } - }).set('target',target).set('complexCard',true).set('logSkill',['olxiangzuo',target]); - if(!bool) return; - player.awakenSkill('olxiangzuo'); - if(player.getHistory('useSkill',evt=>{ - return evt.skill=='olgongjie'&&evt.targets.includes(target); - }).length&&player.getHistory('useSkill',evt=>{ - return evt.skill=='olxiangxv'&&evt.targets.includes(target); - }).length) player.recover(cards.length); + async cost(event, trigger, player) { + event.result = await player + .chooseCardTarget({ + prompt: get.prompt2("olxiangzuo"), + filterCard: true, + selectCard: [1, Infinity], + filterTarget: lib.filter.notMe, + complexCard: true, + complexTarget: true, + complexSelect: true, + ai1(card) { + const player = get.event("player"); + if (!ui.selected.targets.length) return 0; + const target = ui.selected.targets[0]; + if ( + player.hasAllHistory("useSkill", (evt) => { + return ( + evt.skill == "olgongjie" && + (evt.targets || [evt.target]).includes(target) + ); + }) && + player.hasAllHistory("useSkill", (evt) => { + return ( + evt.skill == "olxiangxv" && + (evt.targets || [evt.target]).includes(target) + ); + }) + ) { + if (get.attitude(player, target) > 0) return 1; + if (player.canSaveCard(card, player)) return 0; + if (ui.selected.cards.length + player.hp >= player.maxHp) return 0; + return 20 - get.value(card); + } + if ( + get.attitude(player, target) > 0 && + !player.countCards("he", (cardx) => player.canSaveCard(cardx, player)) + ) + return 1; + return 0; + }, + ai2(target) { + const player = get.event("player"); + const goon = + player.hasAllHistory("useSkill", (evt) => { + return ( + evt.skill == "olgongjie" && + (evt.targets || [evt.target]).includes(target) + ); + }) && + player.hasAllHistory("useSkill", (evt) => { + return ( + evt.skill == "olxiangxv" && + (evt.targets || [evt.target]).includes(target) + ); + }), + att = get.attitude(player, target); + if (goon) return 5 * att; + if (!!player.countCards("he", (cardx) => player.canSaveCard(cardx, player))) + return att; + return 0; + }, + }) + .forResult(); + }, + limited: true, + skillAnimation: true, + animationColor: "water", + async content(event, trigger, player) { + const target = event.targets[0], + cards = event.cards; + player.awakenSkill("olxiangzuo"); + await player.give(cards, target); + if ( + player.hasAllHistory("useSkill", (evt) => { + return evt.skill == "olgongjie" && evt.targets.includes(target); + }) && + player.hasAllHistory("useSkill", (evt) => { + return evt.skill == "olxiangxv" && evt.targets.includes(target); + }) + ) + await player.recover(cards.length); }, }, //OL飞扬 - olfeiyang:{ - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.countCards('he',card=>{ - if(_status.connectMode&&get.position(card)=='h') return true; - return lib.filter.cardDiscardable(card,player); - })>=3&&player.countCards('j'); + olfeiyang: { + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return ( + player.countCards("he", (card) => { + if (_status.connectMode && get.position(card) == "h") return true; + return lib.filter.cardDiscardable(card, player); + }) >= 3 && player.countCards("j") + ); }, - direct:true, + direct: true, //limited:true, //skillAnimation:true, //animationColor:'orange', - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('olfeiyang'),'he',3).set('ai',function(card){ - var player=_status.event.player; - if(player.hasCard(function(card){ - return get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)<0; - },'j')) return 6-get.value(card); - return 0; - }).set('logSkill','olfeiyang'); - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt2("olfeiyang"), "he", 3) + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.hasCard(function (card) { + return ( + get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) < 0 + ); + }, "j") + ) + return 6 - get.value(card); + return 0; + }) + .set("logSkill", "olfeiyang"); + "step 1"; + if (result.bool) { //player.awakenSkill('olfeiyang'); - player.discardPlayerCard(player,'j',true); + player.discardPlayerCard(player, "j", true); } }, }, //李婉 - ollianju:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - var history=player.getHistory('useCard'); - if(!history.length) return false; - var evt=history[history.length-1]; - return evt.cards&&evt.cards.filterInD('d').length; + ollianju: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + var history = player.getHistory("useCard"); + if (!history.length) return false; + var evt = history[history.length - 1]; + return evt.cards && evt.cards.filterInD("d").length; }, - direct:true, - content:function(){ - 'step 0' - var history=player.getHistory('useCard'); - var evt=history[history.length-1]; - event.evt=evt; - player.chooseTarget(get.prompt('ollianju'),'令一名角色获得'+get.translation(evt.cards.filterInD('d'))+'并记录'+get.translation(evt.card.name),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player,att=get.attitude(player,target); - var cards=_status.event.cards; - if(cards.filter(card=>get.name(card,false)=='du').length>=Math.ceil(cards.length/2)) att*=-1; - if(target.skipList.includes('phaseUse')||target.hasJudge('lebu')) return att/20; - return att; - }).set('cards',evt.cards.filterInD('d')); - 'step 1' - if(result.bool){ - var evt=event.evt; - var target=result.targets[0]; - player.logSkill('oliandui',target); - target.gain(evt.cards.filterInD('d'),'gain2'); - player.addSkill('ollianju_effect'); - player.storage.ollianju=evt.card.name; - player.markSkill('ollianju'); - if(!player.storage.ollianju_effect[target.playerid]) player.storage.ollianju_effect[target.playerid]=[]; + direct: true, + content: function () { + "step 0"; + var history = player.getHistory("useCard"); + var evt = history[history.length - 1]; + event.evt = evt; + player + .chooseTarget( + get.prompt("ollianju"), + "令一名角色获得" + + get.translation(evt.cards.filterInD("d")) + + "并记录" + + get.translation(evt.card.name), + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player, + att = get.attitude(player, target); + var cards = _status.event.cards; + if ( + cards.filter((card) => get.name(card, false) == "du").length >= + Math.ceil(cards.length / 2) + ) + att *= -1; + if (target.skipList.includes("phaseUse") || target.hasJudge("lebu")) + return att / 20; + return att; + }) + .set("cards", evt.cards.filterInD("d")); + "step 1"; + if (result.bool) { + var evt = event.evt; + var target = result.targets[0]; + player.logSkill("oliandui", target); + target.gain(evt.cards.filterInD("d"), "gain2"); + player.addSkill("ollianju_effect"); + player.storage.ollianju = evt.card.name; + player.markSkill("ollianju"); + if (!player.storage.ollianju_effect[target.playerid]) + player.storage.ollianju_effect[target.playerid] = []; player.storage.ollianju_effect[target.playerid].add(evt.card.name); } }, - onunmark:true, - intro:{ - content:function(storage,player){ - var str='当前最后一次记录牌名:'+get.translation(storage); - if(player.storage.ollianju_effect){ - for(var i in player.storage.ollianju_effect){ - var target=game.findPlayer(target=>target.playerid==i); - if(!i) continue; - str+='
              '; - str+=get.translation(target)+'的下个结束阶段,其可令你获得其本回合使用的最后一张牌对应的所有位于弃牌堆的实体牌'; - str+=',然后若此牌名为'+get.translation(player.storage.ollianju_effect[i])+',则你失去1点体力,否则你可以视为使用'+get.translation(player.storage.ollianju_effect[i]); + onunmark: true, + intro: { + content: function (storage, player) { + var str = "当前最后一次记录牌名:" + get.translation(storage); + if (player.storage.ollianju_effect) { + for (var i in player.storage.ollianju_effect) { + var target = game.findPlayer((target) => target.playerid == i); + if (!i) continue; + str += "
              "; + str += + get.translation(target) + + "的下个结束阶段,其可令你获得其本回合使用的最后一张牌对应的所有位于弃牌堆的实体牌"; + str += + ",然后若此牌名为" + + get.translation(player.storage.ollianju_effect[i]) + + ",则你失去1点体力,否则你可以视为使用" + + get.translation(player.storage.ollianju_effect[i]); } } return str; }, }, - subSkill:{ - effect:{ - init:function(player){ - if(!player.storage.ollianju_effect) player.storage.ollianju_effect={}; + subSkill: { + effect: { + init: function (player) { + if (!player.storage.ollianju_effect) player.storage.ollianju_effect = {}; }, - charlotte:true, - trigger:{global:['phaseJieshuBegin','die']}, - filter:function(event,player){ + charlotte: true, + trigger: { global: ["phaseJieshuBegin", "die"] }, + filter: function (event, player) { return player.storage.ollianju_effect[event.player.playerid]; }, - direct:true, - content:function(){ - 'step 0' - if(trigger.name=='phaseJieshu') event.list=player.storage.ollianju_effect[trigger.player.playerid]; + direct: true, + content: function () { + "step 0"; + if (trigger.name == "phaseJieshu") + event.list = player.storage.ollianju_effect[trigger.player.playerid]; delete player.storage.ollianju_effect[trigger.player.playerid]; - var history=trigger.player.getHistory('useCard'); - var evt=history[history.length-1]; - event.evt=evt; - if(trigger.name=='die'||!history.length||!evt.cards||!evt.cards.filterInD('d').length) event.finish(); - 'step 1' - var evt=event.evt; - trigger.player.chooseBool(get.prompt('ollianju',player),'令'+get.translation(player)+'获得'+get.translation(evt.cards.filterInD('d'))+(event.list.includes(evt.card.name)?',然后'+get.translation(player)+'失去1点体力':'')).set('choice',get.attitude(trigger.player,player)>0&&(!event.list.includes(evt.card.name)||player.getHp()>1)); - 'step 2' - if(result.bool){ - var evt=event.evt,cards=evt.cards.filterInD('d'); + var history = trigger.player.getHistory("useCard"); + var evt = history[history.length - 1]; + event.evt = evt; + if ( + trigger.name == "die" || + !history.length || + !evt.cards || + !evt.cards.filterInD("d").length + ) + event.finish(); + "step 1"; + var evt = event.evt; + trigger.player + .chooseBool( + get.prompt("ollianju", player), + "令" + + get.translation(player) + + "获得" + + get.translation(evt.cards.filterInD("d")) + + (event.list.includes(evt.card.name) + ? ",然后" + get.translation(player) + "失去1点体力" + : "") + ) + .set( + "choice", + get.attitude(trigger.player, player) > 0 && + (!event.list.includes(evt.card.name) || player.getHp() > 1) + ); + "step 2"; + if (result.bool) { + var evt = event.evt, + cards = evt.cards.filterInD("d"); trigger.player.line(player); - player.gain(cards,'gain2'); - if(event.list.includes(evt.card.name)) player.loseHp(); - else{ - var card={ - name:evt.card.name, - isCard:true, + player.gain(cards, "gain2"); + if (event.list.includes(evt.card.name)) player.loseHp(); + else { + var card = { + name: evt.card.name, + isCard: true, }; - if(player.hasUseTarget(card)) player.chooseUseTarget(card,false); + if (player.hasUseTarget(card)) player.chooseUseTarget(card, false); } } }, }, }, }, - olsilv:{ - audio:2, - trigger:{ - player:['loseAfter','gainAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + olsilv: { + audio: 2, + trigger: { + player: ["loseAfter", "gainAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var name=player.storage.ollianju; - if(!name) return false; - if(event.getg) return event.getg(player).some(card=>card.name==name)&&!player.hasSkill('olsilv_gain'); - return event.getl(player).cards2.some(card=>card.name==name)&&!player.hasSkill('olsilv_lose'); + filter: function (event, player) { + var name = player.storage.ollianju; + if (!name) return false; + if (event.getg) + return ( + event.getg(player).some((card) => card.name == name) && + !player.hasSkill("olsilv_gain") + ); + return ( + event.getl(player).cards2.some((card) => card.name == name) && + !player.hasSkill("olsilv_lose") + ); }, - forced:true, - content:function(){ - 'step 0' - player.addTempSkill('olsilv_'+(trigger.getg?'gain':'lose')); - if(!trigger.visible){ - var cards,name=player.storage.ollianju; - if(trigger.getg) cards=trigger.getg(player).filter(card=>card.name==name); - else cards=trigger.getl(player).cards2.filter(card=>card.name==name); - if(cards.length) player.showCards(cards,get.translation(player)+'发动了【思闾】'); + forced: true, + content: function () { + "step 0"; + player.addTempSkill("olsilv_" + (trigger.getg ? "gain" : "lose")); + if (!trigger.visible) { + var cards, + name = player.storage.ollianju; + if (trigger.getg) cards = trigger.getg(player).filter((card) => card.name == name); + else cards = trigger.getl(player).cards2.filter((card) => card.name == name); + if (cards.length) player.showCards(cards, get.translation(player) + "发动了【思闾】"); } - 'step 1' + "step 1"; player.draw(); }, - ai:{combo:'ollianju'}, - subSkill:{ - gain:{charlotte:true}, - lose:{charlotte:true}, + ai: { combo: "ollianju" }, + subSkill: { + gain: { charlotte: true }, + lose: { charlotte: true }, }, }, //丁尚涴 - olfudao:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + olfudao: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - content:function(){ - 'step 0' + forced: true, + locked: false, + content: function () { + "step 0"; player.draw(3); - 'step 1' - var num=player.countCards('h'); - if(num>0){ + "step 1"; + var num = player.countCards("h"); + if (num > 0) { player.chooseCardTarget({ - prompt:'抚悼:将至多三张手张牌交给一名其他角色', - selectCard:[1,3], - filterCard:true, - filterTarget:lib.filter.notMe, - position:'h', - ai1:function(card){ - if(card.name=='du') return 10; - else if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - var player=_status.event.player; - if(ui.selected.cards.length>4||!game.hasPlayer(function(current){ - return get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })) return 0; - return 1/Math.max(0.1,get.value(card)); + prompt: "抚悼:将至多三张手张牌交给一名其他角色", + selectCard: [1, 3], + filterCard: true, + filterTarget: lib.filter.notMe, + position: "h", + ai1: function (card) { + if (card.name == "du") return 10; + else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") + return 0; + var player = _status.event.player; + if ( + ui.selected.cards.length > 4 || + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return 0; + return 1 / Math.max(0.1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(ui.selected.cards[0].name=='du') return -att; - if(target.hasSkillTag('nogain')) att/=6; + ai2: function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (ui.selected.cards[0].name == "du") return -att; + if (target.hasSkillTag("nogain")) att /= 6; return att; }, }); + } else event.goto(3); + "step 2"; + if (result.bool) { + player.give(result.cards, result.targets[0]); } - else event.goto(3); - 'step 2' - if(result.bool){ - player.give(result.cards,result.targets[0]); - } - 'step 3' - var num=player.countCards('h'); - if(num>0) player.chooseToDiscard('h',[1,num],'抚悼:弃置任意张手牌,然后记录手牌数'); - 'step 4' - player.storage.olfudao=player.countCards('h'); - player.markSkill('olfudao'); + "step 3"; + var num = player.countCards("h"); + if (num > 0) + player.chooseToDiscard("h", [1, num], "抚悼:弃置任意张手牌,然后记录手牌数"); + "step 4"; + player.storage.olfudao = player.countCards("h"); + player.markSkill("olfudao"); }, - intro:{ - content:'一名角色的回合结束时,若其手牌数等于#,你可以与其各摸一张牌。', + 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(); + 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; + check: function (event, player) { + return get.attitude(player, event.player) >= 0; }, - logTarget:'player', - prompt2:function(event,player){ - return '与'+get.translation(event.player)+'各摸一张牌'; + logTarget: "player", + prompt2: function (event, player) { + return "与" + get.translation(event.player) + "各摸一张牌"; }, - content:function(){ - game.asyncDraw([trigger.player,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; + 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; + 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); - var str=get.translation(target);event.target=target; - player.chooseControl().set('choiceList',[ - '摸一张牌,然后交给'+str+'一张牌', - '令'+str+'摸一张牌,然后'+str+'弃置两张牌', - ]).set('ai',()=>_status.event.att>0?0:1).set('att',get.attitude(player,target)); - 'step 1' - if(result.index==0){ + forced: true, + content: function () { + "step 0"; + var target = lib.skill.olfengyan.logTarget(trigger, player); + var str = get.translation(target); + event.target = target; + player + .chooseControl() + .set("choiceList", [ + "摸一张牌,然后交给" + str + "一张牌", + "令" + str + "摸一张牌,然后" + str + "弃置两张牌", + ]) + .set("ai", () => (_status.event.att > 0 ? 0 : 1)) + .set("att", get.attitude(player, target)); + "step 1"; + if (result.index == 0) { player.draw(); - player.chooseToGive(target,'he',true); - } - else{ + player.chooseToGive(target, "he", true); + } else { target.draw(); - target.chooseToDiscard(2,'he',true); + target.chooseToDiscard(2, "he", true); } }, }, //张燕 - 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'); + 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(){}} + 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'); + 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); + (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'; + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card" && get.color(card) == "black"; }, - viewAs:{ - name:'sha', - storage:{olsuji:true}, + viewAs: { + name: "sha", + storage: { olsuji: true }, }, - selectCard:1, - position:'hes', - ai1:function(card){ - return 5-get.value(card); + selectCard: 1, + position: "hes", + ai1: function (card) { + return 5 - get.value(card); }, - precontent:function(){ + 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; + 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; + 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'); + 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); + 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); + 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)); + 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]); + 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); + if (ai_targets.length) { + for (var i = 0; i < ai_targets.length; i++) { + if (players.includes(ai_targets[i])) { + var target = ai_targets[i]; + 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); } - 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 (list.length) index = list.randomGet(); + sendback({ index: index }, target); + ai_targets.splice(i--, 1); } } - if(ai_targets.length){ + 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); + 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)); + 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]); + results.push([player, result]); } } - if(withol&&!event.resultOL){ + if (withol && !event.resultOL) { game.pause(); yield null; } - if(ai_targets.length>0){ - withai=true; + if (ai_targets.length > 0) { + withai = true; game.pause(); yield null; } - if(_status.connectMode){ - for(var i of [player,target]) i.hideTimer(); + 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') + var chosenCount = [0, 0, 0]; + results.sort((a, b) => lib.sort.seat(a[0], b[0])); + player + .when("useCardAfter") .assign({ - card:trigger.card + 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('、')); + .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; + result = yield player + .chooseTarget( + `狼蹈:为${get.translation(trigger.card)}额外指定至多${get.cnNumber( + extraTargetNum + )}个目标`, + (card, player, target) => { + 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,'的目标'); + 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)}`); + 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)}; + 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('、')}`, + intro: { + content: (storage, player) => + `已移除选项${storage.map((i) => get.cnNumber(i + 1, true)).join("、")}`, }, }, //张既 - skill_zhangji_A:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(player.countMark('skill_zhangji_A_count')>=player.hp) return false; - return event.target!=player&&event.target.countCards('h')&&player.isPhaseUsing(); + skill_zhangji_A: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (player.countMark("skill_zhangji_A_count") >= player.hp) return false; + return event.target != player && event.target.countCards("h") && player.isPhaseUsing(); }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - logTarget:'target', - content:function(){ - 'step 0' - player.addTempSkill('skill_zhangji_A_count','phaseUseAfter'); - player.addMark('skill_zhangji_A_count',1,false); + logTarget: "target", + content: function () { + "step 0"; + player.addTempSkill("skill_zhangji_A_count", "phaseUseAfter"); + player.addMark("skill_zhangji_A_count", 1, false); player.viewHandcards(trigger.target); - var list=[],choiceList=[ - '弃置'+get.translation(trigger.target)+'的一张牌,然后若弃置的牌的是能造成火焰伤害的牌,你摸一张牌', - '重铸'+get.translation(trigger.target)+'手牌中的所有【杀】和【决斗】', - '你与'+get.translation(trigger.target)+'互相对对方造成1点伤害', - ]; - list.push('选项一'); - if(trigger.target.countCards('h',{name:['sha','juedou']})) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(!trigger.target.countCards('h',{name:'shan'})) list.push('选项三'); - else choiceList[2]=''+choiceList[2]+''; - player.chooseControl(list).set('prompt',get.prompt('tspowei',target)).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,target=_status.event.target; - if(list.includes('选项三')&&player.hp+player.countCards('hs',{name:'tao'})>2) return '选项三'; - if(list.includes('选项二')&&target.countCards('h',{name:['sha','juedou']})>1) return'选项二'; - return '选项一'; - }).set('target',trigger.target); - 'step 1' - game.log(player,'选择了','#y'+result.control); - switch(result.control){ - case '选项一': - player.discardPlayerCard('he',trigger.target,'visible',true); + var list = [], + choiceList = [ + "弃置" + + get.translation(trigger.target) + + "的一张牌,然后若弃置的牌的是能造成火焰伤害的牌,你摸一张牌", + "重铸" + get.translation(trigger.target) + "手牌中的所有【杀】和【决斗】", + "你与" + get.translation(trigger.target) + "互相对对方造成1点伤害", + ]; + list.push("选项一"); + if (trigger.target.countCards("h", { name: ["sha", "juedou"] })) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (!trigger.target.countCards("h", { name: "shan" })) list.push("选项三"); + else choiceList[2] = '' + choiceList[2] + ""; + player + .chooseControl(list) + .set("prompt", get.prompt("tspowei", target)) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.target; + if ( + list.includes("选项三") && + player.hp + player.countCards("hs", { name: "tao" }) > 2 + ) + return "选项三"; + if ( + list.includes("选项二") && + target.countCards("h", { name: ["sha", "juedou"] }) > 1 + ) + return "选项二"; + return "选项一"; + }) + .set("target", trigger.target); + "step 1"; + game.log(player, "选择了", "#y" + result.control); + switch (result.control) { + case "选项一": + player.discardPlayerCard("he", trigger.target, "visible", true); break; - case '选项二': - var cards=trigger.target.getCards('h',{name:['sha','juedou']}).filter(card=>trigger.target.canRecast(card)); + case "选项二": + var cards = trigger.target + .getCards("h", { name: ["sha", "juedou"] }) + .filter((card) => trigger.target.canRecast(card)); trigger.target.recast(cards); event.finish(); break; - case '选项三': + case "选项三": trigger.target.damage(player); player.damage(trigger.target); event.finish(); break; } - 'step 2' - if(result.bool&&get.tag(result.cards[0],'fireDamage')) player.draw(); + "step 2"; + if (result.bool && get.tag(result.cards[0], "fireDamage")) player.draw(); }, - subSkill:{ - count:{ - charlotte:true, - onremove:true, + subSkill: { + count: { + charlotte: true, + onremove: true, }, }, }, - skill_zhangji_B:{ - getNum:function(name){ - var num=0; - if(name=='litong') num=1; - else switch(game.getRarity(name)){ - case 'junk':num=1;break; - case 'rare':num=2;break; - case 'epic':num=3;break; - case 'legend':num=4;break; - } + skill_zhangji_B: { + getNum: function (name) { + var num = 0; + if (name == "litong") num = 1; + else + switch (game.getRarity(name)) { + case "junk": + num = 1; + break; + case "rare": + num = 2; + break; + case "epic": + num = 3; + break; + case "legend": + num = 4; + break; + } return num; }, - getCharacter:function(list){ - var listx=[],num=0; - for(var name of list){ - var numx=lib.skill.skill_zhangji_B.getNum(name); - if(numx>num){ - num=numx; - listx=[name]; - } - else if(numx==num) listx.push(name); + getCharacter: function (list) { + var listx = [], + num = 0; + for (var name of list) { + var numx = lib.skill.skill_zhangji_B.getNum(name); + if (numx > num) { + num = numx; + listx = [name]; + } else if (numx == num) listx.push(name); } return listx; }, - group:'skill_zhangji_B_jieming', - audio:2, - trigger:{player:'dying'}, - skillAnimation:true, - animationColor:'water', - direct:true, - content:function(){ - 'step 0' - if(!_status.characterlist) lib.skill.pingjian.initList(); - player.chooseTarget(get.prompt('skill_zhangji_B'),'令一名其他角色选择是否更换武将牌',lib.filter.notMe).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - var num=lib.skill.skill_zhangji_B.getNum(target.name); - if(target.name2!=undefined) num=Math.min(num,lib.skill.skill_zhangji_B.getNum(target.name2)); - return att*(4-num); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('skill_zhangji_B',target); - var list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - if(lib.character[_status.characterlist[i]][1]=='wei') list.push(_status.characterlist[i]); + group: "skill_zhangji_B_jieming", + audio: 2, + trigger: { player: "dying" }, + skillAnimation: true, + animationColor: "water", + direct: true, + content: function () { + "step 0"; + if (!_status.characterlist) lib.skill.pingjian.initList(); + player + .chooseTarget( + get.prompt("skill_zhangji_B"), + "令一名其他角色选择是否更换武将牌", + lib.filter.notMe + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + var num = lib.skill.skill_zhangji_B.getNum(target.name); + if (target.name2 != undefined) + num = Math.min(num, lib.skill.skill_zhangji_B.getNum(target.name2)); + return att * (4 - num); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("skill_zhangji_B", target); + var list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + if (lib.character[_status.characterlist[i]][1] == "wei") + list.push(_status.characterlist[i]); } - list=list.randomGets(5); - var bolDialog=['请选择替换的武将',[list,'character']]; - target.chooseButton(bolDialog).set('ai',function(button){ - var target=_status.event.player; - var num=lib.skill.skill_zhangji_B.getNum(target.name); - if(target.name2!=undefined) num=Math.min(num,lib.skill.skill_zhangji_B.getNum(target.name2)); - return lib.skill.skill_zhangji_B.getNum(button.link)-num; + list = list.randomGets(5); + var bolDialog = ["请选择替换的武将", [list, "character"]]; + target.chooseButton(bolDialog).set("ai", function (button) { + var target = _status.event.player; + var num = lib.skill.skill_zhangji_B.getNum(target.name); + if (target.name2 != undefined) + num = Math.min(num, lib.skill.skill_zhangji_B.getNum(target.name2)); + return lib.skill.skill_zhangji_B.getNum(button.link) - num; }); - } - else event.finish(); - 'step 2' - if(result.bool){ - event.character=result.links[0]; - if(target.name2!=undefined) target.chooseControl(target.name1,target.name2).set('prompt','请选择要更换的武将牌').set('ai',function(){ - return lib.skill.skill_zhangji_B.getNum(target.name)2) return Math.min(5,target.maxHp)-target.countCards('h'); - return att/3; - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('skill_zhangji_B_jieming',target); + player + .chooseTarget( + get.prompt("skill_zhangji_B"), + "令一名手牌数小于其体力上限的角色摸三张牌,然后其将手牌数调整至其体力上限值", + function (card, player, target) { + return target.countCards("h") < target.maxHp; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 6; + if (att > 2) return Math.min(5, target.maxHp) - target.countCards("h"); + return att / 3; + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("skill_zhangji_B_jieming", target); target.draw(3); - } - else event.finish(); - 'step 3' - if(target.countCards('h')>target.maxHp) target.chooseToDiscard('h',target.countCards('h')-target.maxHp,true); - if(event.count>0&&game.hasPlayer(function(current){ - return current.countCards('h') target.maxHp) + target.chooseToDiscard("h", target.countCards("h") - target.maxHp, true); + if ( + event.count > 0 && + game.hasPlayer(function (current) { + return current.countCards("h") < current.maxHp; + }) && + player.hasSkill("skill_zhangji_B") + ) + event.goto(1); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - var max=0; - var players=game.filterPlayer(); - for(var i=0;i0){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + var max = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(target, players[i]) > 0) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return 2; - case 1:return 1.5; - case 2:return [1,2]; - default:return [0,max]; + switch (max) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return [1, 2]; + default: + return [0, max]; } } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; - } + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; + }, }, }, }, }, }, //费祎 - yanru:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(!player.countCards('h')) return false; - var num=player.countCards('h')%2; - return !player.hasSkill('yanru_'+num); + yanru: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (!player.countCards("h")) return false; + var num = player.countCards("h") % 2; + return !player.hasSkill("yanru_" + num); }, - filterCard:function(card,player){ - if(player.countCards('h')&&player.countCards('h')%2==0) return lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + if (player.countCards("h") && player.countCards("h") % 2 == 0) + return lib.filter.cardDiscardable(card, player); return false; }, - selectCard:function(){ - var player=_status.event.player; - if(player.countCards('h')&&player.countCards('h')%2==0) return [player.countCards('h')/2,Infinity]; + selectCard: function () { + var player = _status.event.player; + if (player.countCards("h") && player.countCards("h") % 2 == 0) + return [player.countCards("h") / 2, Infinity]; return -1; }, - prompt:function(){ - var player=_status.event.player; + prompt: function () { + var player = _status.event.player; return [ - (player.countCards('h')?'弃置至少一半的手牌,然后':'')+'摸三张牌', - '摸三张牌,然后弃置至少一半的手牌', - ][player.countCards('h')%2]; + (player.countCards("h") ? "弃置至少一半的手牌,然后" : "") + "摸三张牌", + "摸三张牌,然后弃置至少一半的手牌", + ][player.countCards("h") % 2]; }, - check:function(card){ - var player=_status.event.player; - if(player.hasSkill('hezhong')&&(!(player.hasSkill('hezhong_0')&&player.hasSkill('hezhong_1')))){ - if(player.countCards('h')-ui.selected.cards.length>2) return 1/(get.value(card)||0.5); + check: function (card) { + var player = _status.event.player; + if ( + player.hasSkill("hezhong") && + !(player.hasSkill("hezhong_0") && player.hasSkill("hezhong_1")) + ) { + if (player.countCards("h") - ui.selected.cards.length > 2) + return 1 / (get.value(card) || 0.5); return 0; } - if(ui.selected.cards.length{ - var player=_status.event.player; - if(player.hasSkill('hezhong')&&(!(player.hasSkill('hezhong_0')&&player.hasSkill('hezhong_1')))&&player.countCards('h')-ui.selected.cards.length>2) return 1/(get.value(card)||0.5); - if(!player.hasSkill('hezhong')&&ui.selected.cards.length { + var player = _status.event.player; + if ( + player.hasSkill("hezhong") && + !(player.hasSkill("hezhong_0") && player.hasSkill("hezhong_1")) && + player.countCards("h") - ui.selected.cards.length > 2 + ) + return 1 / (get.value(card) || 0.5); + if ( + !player.hasSkill("hezhong") && + ui.selected.cards.length < Math.floor(player.countCards("h") / 2) + ) + return 1 / (get.value(card) || 0.5); + return 0; + }); }, - subSkill:{ - '0':{charlotte:true}, - '1':{charlotte:true}, + subSkill: { + 0: { charlotte: true }, + 1: { charlotte: true }, }, - ai:{ - order:3, - result:{player:1}, + ai: { + order: 3, + result: { player: 1 }, }, }, - hezhong:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + hezhong: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - if(player.countCards('h')!=1||typeof get.number(player.getCards('h')[0],player)!='number') return false; - if(player.hasSkill('hezhong_0')&&player.hasSkill('hezhong_1')) return false; - let gain=0,lose=0; - if(event.getg) gain=event.getg(player).length; - if(event.getl) lose=event.getl(player).hs.length; - return gain!=lose; + filter: function (event, player) { + if ( + player.countCards("h") != 1 || + typeof get.number(player.getCards("h")[0], player) != "number" + ) + return false; + if (player.hasSkill("hezhong_0") && player.hasSkill("hezhong_1")) return false; + let gain = 0, + lose = 0; + if (event.getg) gain = event.getg(player).length; + if (event.getl) lose = event.getl(player).hs.length; + return gain != lose; }, - prompt2:function(event,player){ - var str='展示最后一张手牌并摸一张牌'; - if(!player.hasSkill('hezhong_0')||!player.hasSkill('hezhong_0')){ - str+=',然后令本回合使用点数'; - if(!player.hasSkill('hezhong_0')) str+='大于'; - if(!player.hasSkill('hezhong_0')&&!player.hasSkill('hezhong_0')) str+='或'; - if(!player.hasSkill('hezhong_1')) str+='小于'; - str+=get.number(player.getCards('h')[0],player); - str+='的普通锦囊牌额外结算一次'; + prompt2: function (event, player) { + var str = "展示最后一张手牌并摸一张牌"; + if (!player.hasSkill("hezhong_0") || !player.hasSkill("hezhong_0")) { + str += ",然后令本回合使用点数"; + if (!player.hasSkill("hezhong_0")) str += "大于"; + if (!player.hasSkill("hezhong_0") && !player.hasSkill("hezhong_0")) str += "或"; + if (!player.hasSkill("hezhong_1")) str += "小于"; + str += get.number(player.getCards("h")[0], player); + str += "的普通锦囊牌额外结算一次"; } return str; }, - frequent:true, - content:function(){ - 'step 0' - player.showHandcards(get.translation(player)+'发动了【技能】'); - event.num=get.number(player.getCards('h')[0],player); - 'step 1' + frequent: true, + content: function () { + "step 0"; + player.showHandcards(get.translation(player) + "发动了【技能】"); + event.num = get.number(player.getCards("h")[0], player); + "step 1"; player.draw(); - 'step 2' - if(player.hasSkill('hezhong_0')) event._result={index:1}; - else if(player.hasSkill('hezhong_1')) event._result={index:0}; - else{ - player.chooseControl().set('choiceList',[ - '本回合使用点数大于'+num+'的普通锦囊牌额外结算一次', - '本回合使用点数小于'+num+'的普通锦囊牌额外结算一次', - ]).set('ai',()=>{ - var player=_status.event.player; - var num=_status.event.player; - if(player.getCards('h').reduce(function(num,card){ - return num+(get.number(card,player)||0); - },0)>num*2) return 0; - return 1; - }).set('num',num); + "step 2"; + if (player.hasSkill("hezhong_0")) event._result = { index: 1 }; + else if (player.hasSkill("hezhong_1")) event._result = { index: 0 }; + else { + player + .chooseControl() + .set("choiceList", [ + "本回合使用点数大于" + num + "的普通锦囊牌额外结算一次", + "本回合使用点数小于" + num + "的普通锦囊牌额外结算一次", + ]) + .set("ai", () => { + var player = _status.event.player; + var num = _status.event.player; + if ( + player.getCards("h").reduce(function (num, card) { + return num + (get.number(card, player) || 0); + }, 0) > + num * 2 + ) + return 0; + return 1; + }) + .set("num", num); } - 'step 3' - var skill='hezhong_'+result.index; + "step 3"; + var skill = "hezhong_" + result.index; player.addTempSkill(skill); - player.markAuto(skill,[num]); + player.markAuto(skill, [num]); }, - subSkill:{ - '0':{ - charlotte:true, - onremove:true, - marktext:'>', - intro:{ - markcount:(list)=>{ - var list2=[1,11,12,13]; - return list.reduce((str,num)=>{ - if(list2.includes(num)) return str+['A','J','Q','K'][list2.indexOf(num)]; - return str+parseFloat(num); - },''); + subSkill: { + 0: { + charlotte: true, + onremove: true, + marktext: ">", + intro: { + markcount: (list) => { + var list2 = [1, 11, 12, 13]; + return list.reduce((str, num) => { + if (list2.includes(num)) + return str + ["A", "J", "Q", "K"][list2.indexOf(num)]; + return str + parseFloat(num); + }, ""); }, - content:'使用的下一张点数大于$的普通锦囊牌额外结算一次', + content: "使用的下一张点数大于$的普通锦囊牌额外结算一次", }, - audio:'hezhong', - trigger:{player:'useCard'}, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(!event.targets.length) return false; - var num=get.number(event.card,player); - return typeof num=='number'&&player.getStorage('hezhong_0').some(numx=>num>numx); + audio: "hezhong", + trigger: { player: "useCard" }, + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + if (!event.targets.length) return false; + var num = get.number(event.card, player); + return ( + typeof num == "number" && + player.getStorage("hezhong_0").some((numx) => num > numx) + ); }, - forced:true, - usable:1, - content:function(){ - player.unmarkSkill('hezhong_0'); + forced: true, + usable: 1, + content: function () { + player.unmarkSkill("hezhong_0"); trigger.effectCount++; - game.log(trigger.card,'额外结算一次'); + game.log(trigger.card, "额外结算一次"); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name=='tiesuo'&&(!player.storage.counttrigger||!player.storage.counttrigger.hezhong_0)) return 'zerotarget'; + ai: { + effect: { + player: function (card, player, target) { + if ( + card.name == "tiesuo" && + (!player.storage.counttrigger || + !player.storage.counttrigger.hezhong_0) + ) + return "zerotarget"; }, }, }, }, - '1':{ - charlotte:true, - onremove:true, - marktext:'<', - intro:{ - markcount:(list)=>{ - var list2=[1,11,12,13]; - return list.reduce((str,num)=>{ - if(list2.includes(num)) return str+['A','J','Q','K'][list2.indexOf(num)]; - return str+parseFloat(num); - },''); + 1: { + charlotte: true, + onremove: true, + marktext: "<", + intro: { + markcount: (list) => { + var list2 = [1, 11, 12, 13]; + return list.reduce((str, num) => { + if (list2.includes(num)) + return str + ["A", "J", "Q", "K"][list2.indexOf(num)]; + return str + parseFloat(num); + }, ""); }, - content:'使用的下一张点数小于$的普通锦囊牌额外结算一次', + content: "使用的下一张点数小于$的普通锦囊牌额外结算一次", }, - audio:'hezhong', - trigger:{player:'useCard'}, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(!event.targets.length) return false; - var num=get.number(event.card,player); - return typeof num=='number'&&player.getStorage('hezhong_1').some(numx=>num num < numx) + ); }, - forced:true, - usable:1, - content:function(){ - player.unmarkSkill('hezhong_1'); + forced: true, + usable: 1, + content: function () { + player.unmarkSkill("hezhong_1"); trigger.effectCount++; - game.log(trigger.card,'额外结算一次'); + game.log(trigger.card, "额外结算一次"); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name=='tiesuo'&&(!player.storage.counttrigger||!player.storage.counttrigger.hezhong_1)) return 'zerotarget'; + ai: { + effect: { + player: function (card, player, target) { + if ( + card.name == "tiesuo" && + (!player.storage.counttrigger || + !player.storage.counttrigger.hezhong_1) + ) + return "zerotarget"; }, }, }, @@ -2708,3475 +3993,4533 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //吕伯奢 - olfushi:{ - audio:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.player.isIn()&&event.card.name=='sha'&&event.cards&&event.cards.filterInD().length&&get.distance(player,event.player)<=1; + olfushi: { + audio: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + event.player.isIn() && + event.card.name == "sha" && + event.cards && + event.cards.filterInD().length && + get.distance(player, event.player) <= 1 + ); }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ - player.addToExpansion(trigger.cards.filterInD(),'gain2').gaintag.add('olfushi'); + forced: true, + locked: false, + logTarget: "player", + content: function () { + player.addToExpansion(trigger.cards.filterInD(), "gain2").gaintag.add("olfushi"); }, - marktext:'豕', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "豕", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'olfushi_wusheng', - subSkill:{ - wusheng:{ - enable:'chooseToUse', - filter:function(event,player){ - return player.getExpansions('olfushi').length&&event.filterCard({name:'sha',isCard:true},player,event); + group: "olfushi_wusheng", + subSkill: { + wusheng: { + enable: "chooseToUse", + filter: function (event, player) { + return ( + player.getExpansions("olfushi").length && + event.filterCard({ name: "sha", isCard: true }, player, event) + ); }, - chooseButton:{ - dialog:function(event,player){ + chooseButton: { + dialog: function (event, player) { return ui.create.dialog( '###缚豕###
              将任意“缚豕”牌置入弃牌堆并摸等量的牌,视为使用一张【杀】并执行等量项
              ', - player.getExpansions('olfushi'), - [['额外目标','伤害-1','伤害+1'],'tdnodes'], - 'hidden' + player.getExpansions("olfushi"), + [["额外目标", "伤害-1", "伤害+1"], "tdnodes"], + "hidden" ); }, - filter:function(button){ - const cards=ui.selected.buttons.filter(button=>typeof button.link=='object'); - if(cards.length>=3&&typeof button.link=='string') return false; + filter: function (button) { + const cards = ui.selected.buttons.filter( + (button) => typeof button.link == "object" + ); + if (cards.length >= 3 && typeof button.link == "string") return false; return true; }, - select:[2,Infinity], - filterOk:()=>{ - if(!ui.selected.buttons.length) return false; - const controls=ui.selected.buttons.filter(button=>typeof button.link=='string'); - const cards=ui.selected.buttons.filter(button=>typeof button.link=='object'); - if(cards.length>=3){ - const dialog=get.event().dialog; - if(dialog&&dialog.buttons){ - dialog.buttons.forEach(button=>{ - if(typeof button.link!='string') return; - button.classList.remove('selectable'); - button.classList.remove('selected'); + select: [2, Infinity], + filterOk: () => { + if (!ui.selected.buttons.length) return false; + const controls = ui.selected.buttons.filter( + (button) => typeof button.link == "string" + ); + const cards = ui.selected.buttons.filter( + (button) => typeof button.link == "object" + ); + if (cards.length >= 3) { + const dialog = get.event().dialog; + if (dialog && dialog.buttons) { + dialog.buttons.forEach((button) => { + if (typeof button.link != "string") return; + button.classList.remove("selectable"); + button.classList.remove("selected"); ui.selected.buttons.remove(button); }); } return true; } - return cards.length==controls.length; + return cards.length == controls.length; }, - check:function(button){ - const player=get.player(); - const card=new lib.element.VCard({name:'sha',isCard:true}); - const targets=game.filterPlayer(target=>{ - return player.canUse(card,target); + check: function (button) { + const player = get.player(); + const card = new lib.element.VCard({ name: "sha", isCard: true }); + const targets = game.filterPlayer((target) => { + return player.canUse(card, target); }); - const num0=targets.filter(target=>get.effect(target,card,player,player)>0).length; - if(num0<=0) return 0; - const num1=Math.max(0,num0-1); - const num2=targets.length-num1; - const num3=player.getExpansions('olfushi').length; + const num0 = targets.filter( + (target) => get.effect(target, card, player, player) > 0 + ).length; + if (num0 <= 0) return 0; + const num1 = Math.max(0, num0 - 1); + const num2 = targets.length - num1; + const num3 = player.getExpansions("olfushi").length; let list; - if((num1>0&&num2>0)||(num1==0&&num2==0)){ - switch(num3){ + if ((num1 > 0 && num2 > 0) || (num1 == 0 && num2 == 0)) { + switch (num3) { case 1: - list=[['额外目标','伤害+1'].randomGet()]; + list = [["额外目标", "伤害+1"].randomGet()]; break; case 2: - list=[['额外目标','伤害+1'].randomGet(),'伤害-1']; + list = [["额外目标", "伤害+1"].randomGet(), "伤害-1"]; break; default: - list=['额外目标','伤害-1','伤害+1']; + list = ["额外目标", "伤害-1", "伤害+1"]; break; } - } - else if(num2==0){ - switch(num3){ + } else if (num2 == 0) { + switch (num3) { case 1: - list=['伤害+1']; + list = ["伤害+1"]; break; case 2: - list=['额外目标','伤害+1']; + list = ["额外目标", "伤害+1"]; break; default: - list=['额外目标','伤害-1','伤害+1']; + list = ["额外目标", "伤害-1", "伤害+1"]; break; } - } - else if(num1==0){ - switch(num3){ + } else if (num1 == 0) { + switch (num3) { case 1: - list=['伤害+1']; + list = ["伤害+1"]; break; default: - list=['伤害-1','伤害+1']; + list = ["伤害-1", "伤害+1"]; break; } } - if(typeof button.link=='string'){ - if(list.includes(button.link)) return 114514; + if (typeof button.link == "string") { + if (list.includes(button.link)) return 114514; return -1; - } - else{ - const cards=ui.selected.buttons.filter(button=>typeof button.link=='object'); - if(list.length==3&&(player.getHp()<=2||cards.length typeof button.link == "object" + ); + if ( + (list.length == 3 && + (player.getHp() <= 2 || cards.length < num3 - 1)) || + cards.length < list.length + ) + return 1 / (get.value(button.link) || 0.5); return -1; } }, - backup:function(links,player){ - var cards=links.filter(button=>typeof button=='object'); - var controls=links.filter(button=>typeof button=='string'); - if(!controls.length) controls=['额外目标','伤害-1','伤害+1']; + backup: function (links, player) { + var cards = links.filter((button) => typeof button == "object"); + var controls = links.filter((button) => typeof button == "string"); + if (!controls.length) controls = ["额外目标", "伤害-1", "伤害+1"]; return { - audio:'olfushi', - selectCard:-1, - position:'x', - cards:cards, - controls:controls, - filterCard:function(card){ + audio: "olfushi", + selectCard: -1, + position: "x", + cards: cards, + controls: controls, + filterCard: function (card) { return lib.skill.olfushi_wusheng_backup.cards.includes(card); }, - viewAs:{ - name:'sha', - isCard:true, + viewAs: { + name: "sha", + isCard: true, }, - precontent:function(){ - var cards=lib.skill.olfushi_wusheng_backup.cards.slice(); - var controls=lib.skill.olfushi_wusheng_backup.controls.slice(); - player.logSkill('olfushi'); + precontent: function () { + var cards = lib.skill.olfushi_wusheng_backup.cards.slice(); + var controls = lib.skill.olfushi_wusheng_backup.controls.slice(); + player.logSkill("olfushi"); delete event.result.skill; - event.result.card=new lib.element.VCard(lib.skill.olfushi_wusheng_backup.viewAs); - event.result.cards=[]; + event.result.card = new lib.element.VCard( + lib.skill.olfushi_wusheng_backup.viewAs + ); + event.result.cards = []; player.loseToDiscardpile(cards); player.draw(cards.length); - event.result.card.storage.olfushi_buff=controls; - player.addTempSkill('olfushi_buff'); - } - } + event.result.card.storage.olfushi_buff = controls; + player.addTempSkill("olfushi_buff"); + }, + }; + }, + prompt: function (links, player) { + let controls = links.filter((button) => typeof button == "string"); + if (!controls.length) controls = ["额外目标", "伤害-1", "伤害+1"]; + return `请选择【杀】的目标(${controls.join("、")})`; }, - prompt:function(links,player){ - let controls=links.filter(button=>typeof button=='string'); - if(!controls.length) controls=['额外目标','伤害-1','伤害+1']; - return `请选择【杀】的目标(${controls.join('、')})`; - } }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'})+0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }) + 0.1; }, - result:{player:1}, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - if(!player.getExpansions('olfushi').length) return false; + result: { player: 1 }, + respondSha: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "respond") return false; + if (!player.getExpansions("olfushi").length) return false; }, }, }, - buff:{ - charlotte:true, - trigger:{player:['useCard2','useCardToPlayered']}, - filter:function(event,player,name){ - if(!event.card.storage||!event.card.storage.olfushi_buff) return false; - if(name=='useCard2') return true; - return event.getParent().triggeredTargets3.length==event.targets.length&&event.card.storage.olfushi_buff.length>1&&event.card.storage.olfushi_buff.includes('伤害-1')&&!event.targets.some(target=>!event.targets.includes(target.getPrevious())&&!event.targets.includes(target.getNext())); + buff: { + charlotte: true, + trigger: { player: ["useCard2", "useCardToPlayered"] }, + filter: function (event, player, name) { + if (!event.card.storage || !event.card.storage.olfushi_buff) return false; + if (name == "useCard2") return true; + return ( + event.getParent().triggeredTargets3.length == event.targets.length && + event.card.storage.olfushi_buff.length > 1 && + event.card.storage.olfushi_buff.includes("伤害-1") && + !event.targets.some( + (target) => + !event.targets.includes(target.getPrevious()) && + !event.targets.includes(target.getNext()) + ) + ); }, - forced:true, - popup:false, - content:function(){ - 'step 0' - if(event.triggername=='useCardToPlayered'){ - if(trigger.getParent().addCount!==false){ - trigger.getParent().addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + forced: true, + popup: false, + content: function () { + "step 0"; + if (event.triggername == "useCardToPlayered") { + if (trigger.getParent().addCount !== false) { + trigger.getParent().addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } } - game.log(trigger.card,'不计入次数'); + game.log(trigger.card, "不计入次数"); event.finish(); return; } - var list=trigger.card.storage.olfushi_buff; - event.list=list; - var canBeAddedTargets=game.filterPlayer(target=>{ - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); + var list = trigger.card.storage.olfushi_buff; + event.list = list; + var canBeAddedTargets = game.filterPlayer((target) => { + return ( + !trigger.targets.includes(target) && player.canUse(trigger.card, target) + ); }); - if(!list.includes('额外目标')||!canBeAddedTargets.length) event._result={bool:false}; - else if(canBeAddedTargets.length==1) event._result={bool:true,targets:canBeAddedTargets}; - else player.chooseTarget('请选择'+get.translation(trigger.card)+'的额外目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); - },true).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); + if (!list.includes("额外目标") || !canBeAddedTargets.length) + event._result = { bool: false }; + else if (canBeAddedTargets.length == 1) + event._result = { bool: true, targets: canBeAddedTargets }; + else + player + .chooseTarget( + "请选择" + get.translation(trigger.card) + "的额外目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return ( + !trigger.targets.includes(target) && + player.canUse(trigger.card, target) + ); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); player.line(targets); trigger.targets.addArray(targets); - game.log(targets,'成为了',trigger.card,'的额外目标'); + game.log(targets, "成为了", trigger.card, "的额外目标"); } - 'step 2' - if(!event.list.includes('伤害-1')) event._result={bool:false}; - else if(trigger.targets.length==1) event._result={bool:true,targets:trigger.targets.slice()}; - else player.chooseTarget('请选择'+get.translation(trigger.card)+'伤害-1的目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return trigger.targets.includes(target); - },true).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target); - }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + if (!event.list.includes("伤害-1")) event._result = { bool: false }; + else if (trigger.targets.length == 1) + event._result = { bool: true, targets: trigger.targets.slice() }; + else + player + .chooseTarget( + "请选择" + get.translation(trigger.card) + "伤害-1的目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return trigger.targets.includes(target); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }); + "step 3"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - game.log(trigger.card,'对',target,'的伤害-1'); - player.addTempSkill('olfushi_buff2'); - player.initStorage('olfushi_buff2',[]); - player.getStorage('olfushi_buff2').push([target,trigger.card]); + game.log(trigger.card, "对", target, "的伤害-1"); + player.addTempSkill("olfushi_buff2"); + player.initStorage("olfushi_buff2", []); + player.getStorage("olfushi_buff2").push([target, trigger.card]); } - 'step 4' - if(!event.list.includes('伤害+1')) event.finish(); - else if(trigger.targets.length==1) event._result={bool:true,targets:trigger.targets.slice()}; - else player.chooseTarget('请选择'+get.translation(trigger.card)+'伤害+1的目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return trigger.targets.includes(target); - },true).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 5' - if(result.bool){ - var target=result.targets[0]; + "step 4"; + if (!event.list.includes("伤害+1")) event.finish(); + else if (trigger.targets.length == 1) + event._result = { bool: true, targets: trigger.targets.slice() }; + else + player + .chooseTarget( + "请选择" + get.translation(trigger.card) + "伤害+1的目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return trigger.targets.includes(target); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 5"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - game.log(trigger.card,'对',target,'的伤害+1'); - player.addTempSkill('olfushi_buff3'); - player.initStorage('olfushi_buff3',[]); - player.getStorage('olfushi_buff3').push([target,trigger.card]); + game.log(trigger.card, "对", target, "的伤害+1"); + player.addTempSkill("olfushi_buff3"); + player.initStorage("olfushi_buff3", []); + player.getStorage("olfushi_buff3").push([target, trigger.card]); } }, }, - buff2:{ - charlotte:true, - onremove:true, - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return event.card&&player.getStorage('olfushi_buff2').some(info=>info[0]==event.player&&info[1]==event.card); + buff2: { + charlotte: true, + onremove: true, + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return ( + event.card && + player + .getStorage("olfushi_buff2") + .some((info) => info[0] == event.player && info[1] == event.card) + ); }, - forced:true, - popup:false, - content:function(){ + forced: true, + popup: false, + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(!card||!player.getStorage('olfushi_buff2').includes(card)) return; - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (!card || !player.getStorage("olfushi_buff2").includes(card)) return; + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } }, }, }, }, - buff3:{ - charlotte:true, - onremove:true, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return event.card&&player.getStorage('olfushi_buff3').some(info=>info[0]==event.player&&info[1]==event.card); + buff3: { + charlotte: true, + onremove: true, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + event.card && + player + .getStorage("olfushi_buff3") + .some((info) => info[0] == event.player && info[1] == event.card) + ); }, - forced:true, - popup:false, - content:function(){ + forced: true, + popup: false, + content: function () { trigger.num++; }, }, - wusheng_backup:{}, + wusheng_backup: {}, }, }, - oldongdao:{ - mode:['doudizhu'], - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content:function(storage){ - if(storage) return '农民的回合结束时,其可以进行一个额外回合'; - return '农民的回合结束时,你可以令地主进行一个额外回合'; + oldongdao: { + mode: ["doudizhu"], + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content: function (storage) { + if (storage) return "农民的回合结束时,其可以进行一个额外回合"; + return "农民的回合结束时,你可以令地主进行一个额外回合"; }, }, - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return event.player.identity=='fan'; + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return event.player.identity == "fan"; }, - direct:true, - content:function(){ - 'step 0' - var target=(player.storage.oldongdao?trigger.player:game.zhu); - event.target=target; - var target2=(player.storage.oldongdao?trigger.player:player); - event.target2=target2; - target2.chooseBool(get.prompt('oldongdao'),'令'+get.translation(target)+'进行一个额外回合').set('ai',()=>{ - var event=_status.event.getParent(); - return get.attitude(event.target2,event.target)>0; - }) - 'step 1' - if(result.bool){ - player.logSkill('oldongdao'); + direct: true, + content: function () { + "step 0"; + var target = player.storage.oldongdao ? trigger.player : game.zhu; + event.target = target; + var target2 = player.storage.oldongdao ? trigger.player : player; + event.target2 = target2; + target2 + .chooseBool( + get.prompt("oldongdao"), + "令" + get.translation(target) + "进行一个额外回合" + ) + .set("ai", () => { + var event = _status.event.getParent(); + return get.attitude(event.target2, event.target) > 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("oldongdao"); event.target2.line(target); - player.changeZhuanhuanji('oldongdao'); + player.changeZhuanhuanji("oldongdao"); target.insertPhase(); } }, }, //OL陆郁生 - olcangxin:{ - audio:2, - trigger:{player:'damageBegin4'}, - filter(event,player){ - return game.getGlobalHistory('everything',evt=>{ - return evt.name=='damage'&&evt.player==player; - },event).indexOf(event)==0; + olcangxin: { + audio: 2, + trigger: { player: "damageBegin4" }, + filter(event, player) { + return ( + game + .getGlobalHistory( + "everything", + (evt) => { + return evt.name == "damage" && evt.player == player; + }, + event + ) + .indexOf(event) == 0 + ); }, - checkx:function(event,player){ - var target=event.source; - return get.damageEffect(player,target,target)<=0; + checkx: function (event, player) { + var target = event.source; + return get.damageEffect(player, target, target) <= 0; }, - forced:true, - content:function(){ - 'step 0' - var cards=get.bottomCards(3,true); - player.chooseButton(['###藏心:请选择要弃置的牌###若以此法弃置了红桃牌,则减少弃置红桃牌数的伤害',cards],[1,cards.length],true).set('ai',function(button){ - if(!_status.event.bool&&get.suit(button.link,false)=='heart') return 0; - if(get.suit(button.link,false)!='heart') return 1; - const num=get.event().getTrigger().num; - if(num>ui.selected.buttons.filter(but=>get.suit(but.link,false)=='heart').length) return 1; - return 0; - }).set('bool',lib.skill.olcangxin.checkx(trigger,player)); - 'step 1' - if(result.bool){ - player.$throw(result.links,1000); + forced: true, + content: function () { + "step 0"; + var cards = get.bottomCards(3, true); + player + .chooseButton( + [ + "###藏心:请选择要弃置的牌###若以此法弃置了红桃牌,则减少弃置红桃牌数的伤害", + cards, + ], + [1, cards.length], + true + ) + .set("ai", function (button) { + if (!_status.event.bool && get.suit(button.link, false) == "heart") return 0; + if (get.suit(button.link, false) != "heart") return 1; + const num = get.event().getTrigger().num; + if ( + num > + ui.selected.buttons.filter((but) => get.suit(but.link, false) == "heart") + .length + ) + return 1; + return 0; + }) + .set("bool", lib.skill.olcangxin.checkx(trigger, player)); + "step 1"; + if (result.bool) { + player.$throw(result.links, 1000); game.cardsDiscard(result.links); - const num=result.links.filter(card=>get.suit(card,false)=='heart').length; - if(num) trigger.num-=Math.min(trigger.num,num); - } - else event.finish(); - 'step 2' + const num = result.links.filter((card) => get.suit(card, false) == "heart").length; + if (num) trigger.num -= Math.min(trigger.num, num); + } else event.finish(); + "step 2"; game.delayx(); }, - group:'olcangxin_yingzi', - subSkill:{ - yingzi:{ - audio:'olcangxin', - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ - var cards=get.bottomCards(3,true); - player.showCards(cards,get.translation(player)+'发动了【藏心】'); - var num=cards.filter(card=>get.suit(card,false)=='heart').length; - if(num) player.draw(num); + group: "olcangxin_yingzi", + subSkill: { + yingzi: { + audio: "olcangxin", + trigger: { player: "phaseDrawBegin" }, + forced: true, + content: function () { + var cards = get.bottomCards(3, true); + player.showCards(cards, get.translation(player) + "发动了【藏心】"); + var num = cards.filter((card) => get.suit(card, false) == "heart").length; + if (num) player.draw(num); }, }, }, }, - olrunwei:{ - audio:2, - trigger:{global:'phaseDiscardBegin'}, - filter:function(event,player){ - if(event.player==player) return false; + olrunwei: { + audio: 2, + trigger: { global: "phaseDiscardBegin" }, + filter: function (event, player) { + if (event.player == player) return false; return event.player.isDamaged(); }, - direct:true, - content:function(){ - 'step 0' - var str=get.translation(trigger.player); - player.chooseControl('弃牌,+1','摸牌,-1','cancel2').set('choiceList',[ - '令'+str+'弃置一张牌,且其本回合手牌上限+1', - '令'+str+'摸一张牌,且其本回合手牌上限-1', - ]).set('ai',function(){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - var target=trigger.player; - var num1=target.countCards('h'),num2=target.getHandcardLimit(); - switch(get.sgn(get.attitude(player,target))){ - case 0: - return 2; - case 1: - if(num1-1>=num2) return 0; - if(num1+1<=num2) return 1; - return 2; - case -1: - if(num1-2<=num2) return 0; - if(num1+3>=num2) return 1; - return 2; - } - }).set('prompt',get.prompt('olrunwei',trigger.player)); - 'step 1' - if(result.index!=2){ - player.logSkill('olrunwei',trigger.player); - if(result.index==0){ - trigger.player.chooseToDiscard('he',true).set('ai',card=>{ - if(get.position(card)=='e') return -get.value(card); - return 1/(get.value(card)||0.5); + direct: true, + content: function () { + "step 0"; + var str = get.translation(trigger.player); + player + .chooseControl("弃牌,+1", "摸牌,-1", "cancel2") + .set("choiceList", [ + "令" + str + "弃置一张牌,且其本回合手牌上限+1", + "令" + str + "摸一张牌,且其本回合手牌上限-1", + ]) + .set("ai", function () { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + var target = trigger.player; + var num1 = target.countCards("h"), + num2 = target.getHandcardLimit(); + switch (get.sgn(get.attitude(player, target))) { + case 0: + return 2; + case 1: + if (num1 - 1 >= num2) return 0; + if (num1 + 1 <= num2) return 1; + return 2; + case -1: + if (num1 - 2 <= num2) return 0; + if (num1 + 3 >= num2) return 1; + return 2; + } + }) + .set("prompt", get.prompt("olrunwei", trigger.player)); + "step 1"; + if (result.index != 2) { + player.logSkill("olrunwei", trigger.player); + if (result.index == 0) { + trigger.player.chooseToDiscard("he", true).set("ai", (card) => { + if (get.position(card) == "e") return -get.value(card); + return 1 / (get.value(card) || 0.5); }); - trigger.player.addTempSkill('olrunwei_+'); - trigger.player.addMark('olrunwei_+',1,false); + trigger.player.addTempSkill("olrunwei_+"); + trigger.player.addMark("olrunwei_+", 1, false); } - if(result.index==1){ + if (result.index == 1) { trigger.player.draw(); - trigger.player.addTempSkill('olrunwei_-'); - trigger.player.addMark('olrunwei_-',1,false); + trigger.player.addTempSkill("olrunwei_-"); + trigger.player.addMark("olrunwei_-", 1, false); } } }, - subSkill:{ - '+':{ - charlotte:true, - onremove:true, - marktext:'+', - intro:{content:'手牌上限+#'}, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('olrunwei_+'); + subSkill: { + "+": { + charlotte: true, + onremove: true, + marktext: "+", + intro: { content: "手牌上限+#" }, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("olrunwei_+"); }, }, }, - '-':{ - charlotte:true, - onremove:true, - marktext:'-', - intro:{content:'手牌上限-#'}, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('olrunwei_-'); + "-": { + charlotte: true, + onremove: true, + marktext: "-", + intro: { content: "手牌上限-#" }, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("olrunwei_-"); }, }, }, }, }, //曹羲 - olgangshu:{ - audio:2, - trigger:{ - player:'useCardAfter', + olgangshu: { + audio: 2, + trigger: { + player: "useCardAfter", }, - filter:function(event,player){ - return get.type2(event.card,false)!='basic'; + filter: function (event, player) { + return get.type2(event.card, false) != "basic"; }, - getInfo:(player)=>{ - if(!player.storage.olgangshu_buff) player.storage.olgangshu_buff=[0,0,0]; + getInfo: (player) => { + if (!player.storage.olgangshu_buff) player.storage.olgangshu_buff = [0, 0, 0]; return player.storage.olgangshu_buff; }, - direct:true, - group:'olgangshu_reset', - 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',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var info=lib.skill.olgangshu.getInfo(player); - if(info[1]==0) return 1; - if(info[2]<5&&player.hasCard(card=>{ - return get.name(card)=='sha'&&player.hasValueTarget(card); - },'hs')&&!player.getCardUsable('sha')) return 2; - if(info[0]<5&&!game.hasPlayer(current=>{ - return player.inRange(current)&&get.effect(current,{name:'sha'},player,player)>0; - })) return 0; - var rand=Math.random(); - var list=[0,1,2].filter(i=>info[i]<5); - if(!list.length) return 'cancel2'; - if(rand<0.2&&list.includes(0)) return 0; - if(rand<0.7&&list.includes(1)) return 1; - if(rand<1.0&&list.includes(2)) return 2; - return list.randomGet(); - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('olgangshu'); - player.addSkill('olgangshu_buff'); - var info=lib.skill.olgangshu.getInfo(player); - info[result.index]=Math.min(5,info[result.index]+1); - game.log(player,'的',result.control.slice(0,result.control.indexOf('(')),'#y+1'); - player.markSkill('olgangshu_buff'); + direct: true, + group: "olgangshu_reset", + 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", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var info = lib.skill.olgangshu.getInfo(player); + if (info[1] == 0) return 1; + if ( + info[2] < 5 && + player.hasCard((card) => { + return get.name(card) == "sha" && player.hasValueTarget(card); + }, "hs") && + !player.getCardUsable("sha") + ) + return 2; + if ( + info[0] < 5 && + !game.hasPlayer((current) => { + return ( + player.inRange(current) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) + return 0; + var rand = Math.random(); + var list = [0, 1, 2].filter((i) => info[i] < 5); + if (!list.length) return "cancel2"; + if (rand < 0.2 && list.includes(0)) return 0; + if (rand < 0.7 && list.includes(1)) return 1; + if (rand < 1.0 && list.includes(2)) return 2; + return list.randomGet(); + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("olgangshu"); + player.addSkill("olgangshu_buff"); + var info = lib.skill.olgangshu.getInfo(player); + info[result.index] = Math.min(5, info[result.index] + 1); + game.log(player, "的", result.control.slice(0, result.control.indexOf("(")), "#y+1"); + player.markSkill("olgangshu_buff"); } }, - ai:{ - threaten:3, + ai: { + threaten: 3, }, - subSkill:{ - buff:{ - trigger:{player:'phaseDrawBegin2'}, - charlotte:true, - onremove:true, - forced:true, - filter:function(event,player){ - var info=lib.skill.olgangshu.getInfo(player); - if(!info[1]) return false; + subSkill: { + buff: { + trigger: { player: "phaseDrawBegin2" }, + charlotte: true, + onremove: true, + forced: true, + filter: function (event, player) { + var info = lib.skill.olgangshu.getInfo(player); + if (!info[1]) return false; return !event.numFixed; }, - content:function(){ - var info=lib.skill.olgangshu.getInfo(player); - trigger.num+=info[1]; - info[1]=0; - player.markSkill('olgangshu_buff'); + content: function () { + var info = lib.skill.olgangshu.getInfo(player); + trigger.num += info[1]; + info[1] = 0; + player.markSkill("olgangshu_buff"); }, - mod:{ - attackRange:function(player,range){ - var info=lib.skill.olgangshu.getInfo(player); - if(info) return range+info[0]; + mod: { + attackRange: function (player, range) { + var info = lib.skill.olgangshu.getInfo(player); + if (info) return range + info[0]; }, - cardUsable:function(card,player,num){ - if(card.name!='sha') return; - var info=lib.skill.olgangshu.getInfo(player); - if(info) return num+info[2]; + cardUsable: function (card, player, num) { + if (card.name != "sha") return; + var info = lib.skill.olgangshu.getInfo(player); + if (info) return num + info[2]; }, }, - mark:true, - intro:{ - markcount:function(storage,player){ - var info=lib.skill.olgangshu.getInfo(player); - var str=''; - info.forEach(num=>str+=parseFloat(num)); + mark: true, + intro: { + markcount: function (storage, player) { + var info = lib.skill.olgangshu.getInfo(player); + var str = ""; + info.forEach((num) => (str += parseFloat(num))); return str; }, - content:function(storage,player){ - var info=lib.skill.olgangshu.getInfo(player); - var str=''; - if(info[0]>0) str+='
            • 攻击范围+'+info[0]; - if(info[1]>0) str+='
            • 下个摸牌阶段摸牌数+'+info[1]; - if(info[2]>0) str+='
            • 使用【杀】的次数上限+'+info[2]; + content: function (storage, player) { + var info = lib.skill.olgangshu.getInfo(player); + var str = ""; + if (info[0] > 0) str += "
            • 攻击范围+" + info[0]; + if (info[1] > 0) str += "
            • 下个摸牌阶段摸牌数+" + info[1]; + if (info[2] > 0) str += "
            • 使用【杀】的次数上限+" + info[2]; return str; }, }, }, - reset:{ - audio:'olgangshu', - trigger:{ - global:['shaMiss','eventNeutralized'], + reset: { + audio: "olgangshu", + trigger: { + global: ["shaMiss", "eventNeutralized"], }, - filter:function(event,player){ - if(event.type!='card') return false; + filter: function (event, player) { + if (event.type != "card") return false; var responder; - if(event.name=='sha'){ - responder=event.target; + if (event.name == "sha") { + responder = event.target; + } else { + responder = event._neutralize_event.player; } - else{ - responder=event._neutralize_event.player; - } - return player==responder; + return player == responder; }, - forced:true, - locked:false, - content:function(){ - player.removeSkill('olgangshu_buff'); - game.log(player,'重置了','#g【刚述】','的数值'); - } - } - } + forced: true, + locked: false, + content: function () { + player.removeSkill("olgangshu_buff"); + game.log(player, "重置了", "#g【刚述】", "的数值"); + }, + }, + }, }, - oljianxuan:{ - audio:2, - trigger:{ - player:'damageEnd', + oljianxuan: { + audio: 2, + trigger: { + player: "damageEnd", }, - direct:true, - content:function(){ - 'step 0' - var info=lib.skill.olgangshu.getInfo(player); - var list=[]; + direct: true, + content: function () { + "step 0"; + var info = lib.skill.olgangshu.getInfo(player); + var list = []; list.add(player.getAttackRange()); - list.add(2+info[1]); - list.add(player.getCardUsable('sha',true)); + list.add(2 + info[1]); + list.add(player.getCardUsable("sha", true)); list.sort(); - var str=list.join('、').replace(/(.*)、/, '$1或'); - event.list=list; - player.chooseTarget(get.prompt('oljianxuan'),'令一名角色摸一张牌,然后若其手牌数为'+str+',其重复此流程').set('ai',target=>{ - var list=_status.event.list; - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<=0) return 0; - var num=target.countCards('h')+1; - var value=1; - while(true){ - if(list.includes(num)){ - value++; - num++; + var str = list.join("、").replace(/(.*)、/, "$1或"); + event.list = list; + player + .chooseTarget( + get.prompt("oljianxuan"), + "令一名角色摸一张牌,然后若其手牌数为" + str + ",其重复此流程" + ) + .set("ai", (target) => { + var list = _status.event.list; + var player = _status.event.player; + var att = get.attitude(player, target); + if (att <= 0) return 0; + var num = target.countCards("h") + 1; + var value = 1; + while (true) { + if (list.includes(num)) { + value++; + num++; + } else break; } - else break; - } - return value+att/10; - }).set('list',list); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('oljianxuan',target); - if(player!=target) player.addExpose(0.15); - } - else event.finish(); - 'step 2' + return value + att / 10; + }) + .set("list", list); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("oljianxuan", target); + if (player != target) player.addExpose(0.15); + } else event.finish(); + "step 2"; target.draw(); - 'step 3' - if(event.list.includes(target.countCards('h'))) event.goto(2); + "step 3"; + if (event.list.includes(target.countCards("h"))) event.goto(2); }, - ai:{ - combo:'olgangshu', - maixie:true, + ai: { + combo: "olgangshu", + maixie: true, }, }, //OL彭羕 - olxiaofan:{ - audio:2, - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(name!='wuxie'&&lib.inpile.includes(name)) return true; + olxiaofan: { + audio: 2, + enable: "chooseToUse", + hiddenCard: function (player, name) { + if (name != "wuxie" && lib.inpile.includes(name)) return true; }, - getNum:(player)=>player.getHistory('useCard').reduce((list,evt)=>list.add(get.type2(evt.card)),[]).length, - filter:function(event,player){ - if(event.responded||event.type=='wuxie'||event.olxiaofan) return false; - for(var i of lib.inpile){ - if(i!='wuxie'&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; + getNum: (player) => + player.getHistory("useCard").reduce((list, evt) => list.add(get.type2(evt.card)), []) + .length, + filter: function (event, player) { + if (event.responded || event.type == "wuxie" || event.olxiaofan) return false; + for (var i of lib.inpile) { + if ( + i != "wuxie" && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; } return false; }, - delay:false, - content:function(){ - 'step 0' - var evt=event.getParent(2); - evt.set('olxiaofan',true); - var cards=get.bottomCards(lib.skill.olxiaofan.getNum(player)+1,true); - var aozhan=player.hasSkill('aozhan'); - player.chooseButton(['嚣翻:选择要使用的牌',cards]).set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards.filter(function(card){ - if(aozhan&&card.name=='tao'){ - return evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)||evt.filterCard({ - name:'shan',isCard:true,cards:[card], - },evt.player,evt); + delay: false, + content: function () { + "step 0"; + var evt = event.getParent(2); + evt.set("olxiaofan", true); + var cards = get.bottomCards(lib.skill.olxiaofan.getNum(player) + 1, true); + var aozhan = player.hasSkill("aozhan"); + player + .chooseButton(["嚣翻:选择要使用的牌", cards]) + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set( + "cards", + cards.filter(function (card) { + if (aozhan && card.name == "tao") { + return ( + evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) || + evt.filterCard( + { + name: "shan", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ); + } + return evt.filterCard(card, evt.player, evt); + }) + ) + .set("ai", function (button) { + if (get.type(button.link) == "equip") return 0; + var evt = _status.event.getParent(3), + player = _status.event.player; + if (evt.type == "phase" && !player.hasValueTarget(button.link, null, true)) + return 0; + if (evt && evt.ai) { + var tmp = _status.event; + _status.event = evt; + var result = (evt.ai || event.ai1)(button.link, _status.event.player, evt); + _status.event = tmp; + return result; + } + return 1; + }); + "step 1"; + var evt = event.getParent(2); + if (result.bool && result.links && result.links.length) { + var card = result.links[0]; + var name = card.name, + aozhan = player.hasSkill("aozhan") && name == "tao"; + if (aozhan) { + name = evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ? "sha" + : "shan"; } - return evt.filterCard(card,evt.player,evt); - })).set('ai',function(button){ - if(get.type(button.link)=='equip') return 0; - var evt=_status.event.getParent(3),player=_status.event.player; - if(evt.type=='phase'&&!player.hasValueTarget(button.link,null,true)) return 0; - if(evt&&evt.ai){ - var tmp=_status.event; - _status.event=evt; - var result=(evt.ai||event.ai1)(button.link,_status.event.player,evt); - _status.event=tmp; - return result; - } - return 1; - }); - 'step 1' - var evt=event.getParent(2); - if(result.bool&&result.links&&result.links.length){ - var card=result.links[0]; - var name=card.name,aozhan=(player.hasSkill('aozhan')&&name=='tao'); - if(aozhan){ - name=evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)?'sha':'shan'; - } - game.broadcastAll(function(result,name){ - lib.skill.olxiaofan_backup.viewAs={name:name,cards:[result],isCard:true}; - },card,name); - evt.set('_backupevent','olxiaofan_backup'); - evt.set('openskilldialog',('请选择'+get.translation(card)+'的目标')) - evt.backup('olxiaofan_backup'); + game.broadcastAll( + function (result, name) { + lib.skill.olxiaofan_backup.viewAs = { + name: name, + cards: [result], + isCard: true, + }; + }, + card, + name + ); + evt.set("_backupevent", "olxiaofan_backup"); + evt.set("openskilldialog", "请选择" + get.translation(card) + "的目标"); + evt.backup("olxiaofan_backup"); } evt.goto(0); }, - ai:{ - effect:{ - target:function(card,player,target,effect){ - if(get.tag(card,'respondShan')) return 0.7; - if(get.tag(card,'respondSha')) return 0.7; - } + ai: { + effect: { + target: function (card, player, target, effect) { + if (get.tag(card, "respondShan")) return 0.7; + if (get.tag(card, "respondSha")) return 0.7; + }, }, - order:12, - respondShan:true, - respondSha:true, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + order: 12, + respondShan: true, + respondSha: true, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; - } - } + }, + }, }, }, - olxiaofan_backup:{ - sourceSkill:'olxiaofan', - precontent:function(){ + olxiaofan_backup: { + sourceSkill: "olxiaofan", + precontent: function () { delete event.result.skill; - var name=event.result.card.name,cards=event.result.card.cards.slice(0); - event.result.cards=cards; - var rcard=cards[0],card; - if(rcard.name==name) card=get.autoViewAs(rcard); - else card=get.autoViewAs({name,isCard:true}); - event.result.card=card; - var id=get.id(); - player.when('chooseToUseAfter').filter((evt)=>evt==event.getParent()).then(()=>{ - var num=lib.skill.olxiaofan.getNum(player),pos=('jeh').slice(0,num); - if(num>0&&player.countCards(pos)>0){ - event.maxNum=Math.min(3,num); - event.num=0; - } - else event.finish(); - }).then(()=>{ - var pos=('jeh')[event.num],hs=player.countCards(pos); - if(hs>0) player.chooseToDiscard(hs,pos,true); - event.num++; - if(event.num evt == event.getParent()) + .then(() => { + var num = lib.skill.olxiaofan.getNum(player), + pos = "jeh".slice(0, num); + if (num > 0 && player.countCards(pos) > 0) { + event.maxNum = Math.min(3, num); + event.num = 0; + } else event.finish(); + }) + .then(() => { + var pos = "jeh"[event.num], + hs = player.countCards(pos); + if (hs > 0) player.chooseToDiscard(hs, pos, true); + event.num++; + if (event.num < event.maxNum) event.redo(); + }) + .translation("嚣翻"); }, - filterCard:function(){return false}, - selectCard:-1, + filterCard: function () { + return false; + }, + selectCard: -1, }, - oltuishi:{ - audio:2, - mod:{ - wuxieJudgeEnabled:()=>false, - wuxieEnabled:()=>false, - cardEnabled:(card)=>{ - if(card.name=='wuxie') return false; + oltuishi: { + audio: 2, + mod: { + wuxieJudgeEnabled: () => false, + wuxieEnabled: () => false, + cardEnabled: (card) => { + if (card.name == "wuxie") return false; }, - targetInRange:(card)=>{ - if(card.storage&&card.storage.oltuishi) return true; + targetInRange: (card) => { + if (card.storage && card.storage.oltuishi) return true; }, - aiValue:(player,card,val)=>{ - if(card.name=='wuxie') return 0; - var num=get.number(card); - if([1,11,12,13].includes(num)) return val*1.1; + aiValue: (player, card, val) => { + if (card.name == "wuxie") return 0; + var num = get.number(card); + if ([1, 11, 12, 13].includes(num)) return val * 1.1; }, - aiUseful:(player,card,val)=>{ - if(card.name=='wuxie') return 0; - var num=get.number(card); - if([1,11,12,13].includes(num)) return val*1.1; + aiUseful: (player, card, val) => { + if (card.name == "wuxie") return 0; + var num = get.number(card); + if ([1, 11, 12, 13].includes(num)) return val * 1.1; }, - aiOrder:(player,card,order)=>{ - if(get.name(card)=='sha'&&player.hasSkill('oltuishi_unlimit')) order+=9; - var num=get.number(card); - if([1,11,12,13].includes(num)) order+=3; + aiOrder: (player, card, order) => { + if (get.name(card) == "sha" && player.hasSkill("oltuishi_unlimit")) order += 9; + var num = get.number(card); + if ([1, 11, 12, 13].includes(num)) order += 3; return order; }, }, - trigger:{player:['useCard','useCardAfter']}, - filter:function(event,player,name){ - if(name=='useCardAfter'){ - if(player.isTempBanned('olxiaofan')) return false; - return player.getHistory('useCard',evt=>{ - return !player.getHistory('sourceDamage',evt2=>{ - return evt2.card&&evt2.card==evt.card; - }).length&&get.tag(evt.card,'damage'); - }).indexOf(event)>=2; + trigger: { player: ["useCard", "useCardAfter"] }, + filter: function (event, player, name) { + if (name == "useCardAfter") { + if (player.isTempBanned("olxiaofan")) return false; + return ( + player + .getHistory("useCard", (evt) => { + return ( + !player.getHistory("sourceDamage", (evt2) => { + return evt2.card && evt2.card == evt.card; + }).length && get.tag(evt.card, "damage") + ); + }) + .indexOf(event) >= 2 + ); } - return [1,11,12,13].includes(get.number(event.card)); + return [1, 11, 12, 13].includes(get.number(event.card)); }, - forced:true, - content:function(){ - 'step 0' - if(event.triggername=='useCardAfter'){ - player.tempBanSkill('olxiaofan'); + forced: true, + content: function () { + "step 0"; + if (event.triggername == "useCardAfter") { + player.tempBanSkill("olxiaofan"); event.finish(); return; } - trigger.targets.length=0; - trigger.all_excluded=true; - game.log(trigger.card,'被无效了'); - 'step 1' + trigger.targets.length = 0; + trigger.all_excluded = true; + game.log(trigger.card, "被无效了"); + "step 1"; player.draw(); - player.addSkill('oltuishi_unlimit'); + player.addSkill("oltuishi_unlimit"); }, - subSkill:{ - unlimit:{ - charlotte:true, - mod:{ - cardUsableTarget:(card,player,target)=>{ - if(target.countCards('h') { + if (target.countCards("h") < player.countCards("h")) return true; }, - targetInRange:(card,player,target)=>{ - if(target.countCards('h') { + if (target.countCards("h") < player.countCards("h")) return true; }, }, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(!event.targets||!event.targets.length) return false; - let num=0; - if(event.cards&&event.cards.length){ - const history=player.getHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - return event.cards.some(card=>evt.hs.includes(card)); + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (!event.targets || !event.targets.length) return false; + let num = 0; + if (event.cards && event.cards.length) { + const history = player.getHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + return event.cards.some((card) => evt.hs.includes(card)); }); - if(history.length) num+=event.cards.filter(card=>history[0].hs.includes(card)).length; + if (history.length) + num += event.cards.filter((card) => history[0].hs.includes(card)).length; } - return event.targets.some(target=>player.countCards('h')+num>target.countCards('h')+(target==player?num:0)); + return event.targets.some( + (target) => + player.countCards("h") + num > + target.countCards("h") + (target == player ? num : 0) + ); }, - forced:true, - popup:false, - silent:true, - firstDo:true, - content:function(){ - player.removeSkill('oltuishi_unlimit') - var card=trigger.card; - if(!card.storage) card.storage={}; - card.storage.oltuishi=true; - if(trigger.addCount!==false){ - trigger.addCount=false; - player.getStat('card')[card.name]--; + forced: true, + popup: false, + silent: true, + firstDo: true, + content: function () { + player.removeSkill("oltuishi_unlimit"); + var card = trigger.card; + if (!card.storage) card.storage = {}; + card.storage.oltuishi = true; + if (trigger.addCount !== false) { + trigger.addCount = false; + player.getStat("card")[card.name]--; } }, - mark:true, - intro:{content:'对手牌数小于你的角色使用的下一张牌无距离次数限制'}, + mark: true, + intro: { content: "对手牌数小于你的角色使用的下一张牌无距离次数限制" }, }, }, }, //OL牵招 - olweifu:{ - audio:2, - enable:'phaseUse', - filterCard:lib.filter.cardDiscardable, - position:'he', - filter:function(event,player){ - return player.hasCard(card=>lib.filter.cardDiscardable(card,player),'he'); + olweifu: { + audio: 2, + enable: "phaseUse", + filterCard: lib.filter.cardDiscardable, + position: "he", + filter: function (event, player) { + return player.hasCard((card) => lib.filter.cardDiscardable(card, player), "he"); }, - check:function(card){ - var player=_status.event.player; - return (5-get.value(card))/Math.pow(Math.max(0.1,player.getUseValue(card)),0.33); + check: function (card) { + var player = _status.event.player; + return (5 - get.value(card)) / Math.pow(Math.max(0.1, player.getUseValue(card)), 0.33); }, - content:function(){ - 'step 0' - player.judge(card=>{ - var evt=_status.event.getParent(); - var cardx=evt.cards[0]; - if(get.type2(card)==get.type2(cardx)) return 0.5; - return 0.1; - }).set('callback',function(){ - var card=event.judgeResult.card; - player.addTempSkill('olweifu_clear'); - player.addTempSkill('olweifu_add'); - if(!get.is.object(player.storage.olweifu_add)) player.storage.olweifu_add={}; - var type=get.type2(card,player); - if(typeof player.storage.olweifu_add[type]!='number') player.storage.olweifu_add[type]=0; - player.storage.olweifu_add[type]++; - player.markSkill('olweifu_add'); - if(type==get.type2(event.getParent(2).cards[0],player)) player.draw(); - }).set('judge2',result=>result.bool); + content: function () { + "step 0"; + player + .judge((card) => { + var evt = _status.event.getParent(); + var cardx = evt.cards[0]; + if (get.type2(card) == get.type2(cardx)) return 0.5; + return 0.1; + }) + .set("callback", function () { + var card = event.judgeResult.card; + player.addTempSkill("olweifu_clear"); + player.addTempSkill("olweifu_add"); + if (!get.is.object(player.storage.olweifu_add)) player.storage.olweifu_add = {}; + var type = get.type2(card, player); + if (typeof player.storage.olweifu_add[type] != "number") + player.storage.olweifu_add[type] = 0; + player.storage.olweifu_add[type]++; + player.markSkill("olweifu_add"); + if (type == get.type2(event.getParent(2).cards[0], player)) player.draw(); + }) + .set("judge2", (result) => result.bool); }, - ai:{ - order:7, - result:{ - player:function(player){ - return player.hasCard(card=>{ - var type=get.type2(card); - if(type=='equip') return false; - return player.hasUseTarget(card)&&player.getUseValue(card)>5&&game.countPlayer(current=>{ - return lib.filter.targetEnabled2(card,player,current)&&get.effect(current,card,player,player)>0; - })+1>(get.is.object(player.storage.olweifu_add)?(player.storage.olweifu_add[type]||0):0); - },'hs')?1:0; + ai: { + order: 7, + result: { + player: function (player) { + return player.hasCard((card) => { + var type = get.type2(card); + if (type == "equip") return false; + return ( + player.hasUseTarget(card) && + player.getUseValue(card) > 5 && + game.countPlayer((current) => { + return ( + lib.filter.targetEnabled2(card, player, current) && + get.effect(current, card, player, player) > 0 + ); + }) + + 1 > + (get.is.object(player.storage.olweifu_add) + ? player.storage.olweifu_add[type] || 0 + : 0) + ); + }, "hs") + ? 1 + : 0; }, }, }, - subSkill:{ - clear:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - var type=get.type2(event.card); - if(get.is.object(player.storage.olweifu_add)&&typeof player.storage.olweifu_add[type]=='number') return true; + subSkill: { + clear: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + var type = get.type2(event.card); + if ( + get.is.object(player.storage.olweifu_add) && + typeof player.storage.olweifu_add[type] == "number" + ) + return true; return false; }, - silent:true, - firstDo:true, - charlotte:true, - content:function(){ - var type=get.type2(trigger.card); - var num=player.storage.olweifu_add[type]; + silent: true, + firstDo: true, + charlotte: true, + content: function () { + var type = get.type2(trigger.card); + var num = player.storage.olweifu_add[type]; delete player.storage.olweifu_add[type]; - if(get.is.empty(player.storage.olweifu_add)){ + if (get.is.empty(player.storage.olweifu_add)) { delete player.storage.olweifu_add; - player.unmarkSkill('olweifu_add'); + player.unmarkSkill("olweifu_add"); } - trigger._olweifu_clear=num; - } + trigger._olweifu_clear = num; + }, }, - add:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(!event._olweifu_clear) 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.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })) return true; + add: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (!event._olweifu_clear) 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.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) + ); + }) + ) + return true; } return false; }, - onremove:true, - charlotte:true, - direct:true, - content:function(){ - 'step 0' - var num=trigger._olweifu_clear; - player.chooseTarget(get.prompt('olweifu'),'为'+get.translation(trigger.card)+'额外指定'+get.cnNumber(num)+'个目标。',[1,num],(card,player,target)=>{ - return !_status.event.sourcex.includes(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){ - var targets=result.targets; - player.logSkill('olweifu_add',targets); + onremove: true, + charlotte: true, + direct: true, + content: function () { + "step 0"; + var num = trigger._olweifu_clear; + player + .chooseTarget( + get.prompt("olweifu"), + "为" + + get.translation(trigger.card) + + "额外指定" + + get.cnNumber(num) + + "个目标。", + [1, num], + (card, player, target) => { + return ( + !_status.event.sourcex.includes(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) { + var targets = result.targets; + player.logSkill("olweifu_add", targets); trigger.targets.addArray(targets); - game.log(targets,'也成为了',trigger.card,'的目标'); - if(!event.isMine()&&!event.isOnline()) game.delayex(); + game.log(targets, "也成为了", trigger.card, "的目标"); + if (!event.isMine() && !event.isOnline()) game.delayex(); } }, - intro:{ - markcount:()=>0, - content:(storage,player)=>{ - if(!get.is.object(storage)) return; - var str='使用下一张以下类型的牌无距离限制,且可以额外指定对应数量个目标:'; - for(var type in storage){ - str+='
            • '+get.translation(type)+'牌:+'+storage[type]; + intro: { + markcount: () => 0, + content: (storage, player) => { + if (!get.is.object(storage)) return; + var str = "使用下一张以下类型的牌无距离限制,且可以额外指定对应数量个目标:"; + for (var type in storage) { + str += "
            • " + get.translation(type) + "牌:+" + storage[type]; } return str; - } - }, - mod:{ - targetInRange:(card,player)=>{ - var type=get.type2(card); - if(get.is.object(player.storage.olweifu_add)&&typeof player.storage.olweifu_add[type]=='number') return true; }, - } - } + }, + mod: { + targetInRange: (card, player) => { + var type = get.type2(card); + if ( + get.is.object(player.storage.olweifu_add) && + typeof player.storage.olweifu_add[type] == "number" + ) + return true; + }, + }, + }, }, }, - olkuansai:{ - audio:2, - trigger:{ - global:'useCardToPlayered', + olkuansai: { + audio: 2, + trigger: { + global: "useCardToPlayered", }, - filter:function(event,player){ - return event.isFirstTarget&&event.targets.length>=player.getHp(); + filter: function (event, player) { + return event.isFirstTarget && event.targets.length >= player.getHp(); }, - direct:true, - usable:1, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olkuansai'),'令其中一个目标选择一项:1.交给你一张牌;2.令你回复1点体力。',(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',trigger.targets).set('ai',target=>{ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0) return 1; - return (1-att)/Math.sqrt(1+target.countCards('he')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olkuansai',target); - var position='e'; - if(player!=target) position+='h'; - var forced=player.isHealthy(); - var str='请交给其一张牌'+(forced?'':'或点击“取消”令其回复1点体力')+'。'; - if(!target.countCards(position)) event._result={bool:false}; - else target.chooseCard(get.translation(player)+'对你发动了【款塞】',str,position,forced).set('ai',card=>{ - if(_status.event.recover) return 0; - var target=_status.event.player,player=_status.event.getParent().player; - if(get.attitude(target,player)>0){ - return get.value(card,target)-get.value(card,player); + direct: true, + usable: 1, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olkuansai"), + "令其中一个目标选择一项:1.交给你一张牌;2.令你回复1点体力。", + (card, player, target) => { + return _status.event.targets.includes(target); } - if(get.tag(card,'recover')) return -1; - return 6.5-get.value(card); - }).set('recover',function(){ - if(forced) return false; - var recoverEff=get.recoverEffect(player,target,target); - var att=get.attitude(target,player); - if(att<0){ - if(recoverEff>=0) return true; - if(target.hasCard(card=>{ - return get.value(card)<6.5&&!get.tag(card,'recover')||get.value(card)<=0.05; - },position)) return false; - } - else{ - if(recoverEff>0) return true; - if(target.hasCard(card=>{ - return get.value(card,target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) return 1; + return (1 - att) / Math.sqrt(1 + target.countCards("he")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olkuansai", target); + var position = "e"; + if (player != target) position += "h"; + var forced = player.isHealthy(); + var str = "请交给其一张牌" + (forced ? "" : "或点击“取消”令其回复1点体力") + "。"; + if (!target.countCards(position)) event._result = { bool: false }; + else + target + .chooseCard( + get.translation(player) + "对你发动了【款塞】", + str, + position, + forced + ) + .set("ai", (card) => { + if (_status.event.recover) return 0; + var target = _status.event.player, + player = _status.event.getParent().player; + if (get.attitude(target, player) > 0) { + return get.value(card, target) - get.value(card, player); + } + if (get.tag(card, "recover")) return -1; + return 6.5 - get.value(card); + }) + .set( + "recover", + (function () { + if (forced) return false; + var recoverEff = get.recoverEffect(player, target, target); + var att = get.attitude(target, player); + if (att < 0) { + if (recoverEff >= 0) return true; + if ( + target.hasCard((card) => { + return ( + (get.value(card) < 6.5 && + !get.tag(card, "recover")) || + get.value(card) <= 0.05 + ); + }, position) + ) + return false; + } else { + if (recoverEff > 0) return true; + if ( + target.hasCard((card) => { + return get.value(card, target) < get.value(card, player); + }, position) + ) + return false; + } + return true; + })() + ); + } else { player.storage.counttrigger.olkuansai--; event.finish(); } - 'step 2' - if(result.bool){ - target.give(result.cards,player); - } - else player.recover(target); + "step 2"; + if (result.bool) { + target.give(result.cards, player); + } else player.recover(target); }, }, //牛金 - olcuorui:{ - audio:'cuorui', - trigger:{ - global:'phaseBefore', - player:'enterGame', - target:'useCardToTargeted', + olcuorui: { + audio: "cuorui", + trigger: { + global: "phaseBefore", + player: "enterGame", + target: "useCardToTargeted", }, - filter:function(event,player){ - if(event.name=='useCardToTargeted') return get.type(event.card)=='delay'&&!player.hasSkill('olcuorui_skip'); - return (event.name!='phase'||game.phaseNumber==0)&&player.countCards('h')player.getUseValue({name:'juedou'})?'sha':'juedou'; - }); - 'step 3' - if(result.control) target.chooseUseTarget({name:result.control},true); + var list = []; + if (target.hasUseTarget({ name: "sha" })) list.push("sha"); + if (target.hasUseTarget({ name: "sha" })) list.push("juedou"); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { control: list[0] }; + else + target + .chooseControl(list) + .set("prompt", "谋诛:视为使用一张【杀】或【决斗】") + .set("ai", function () { + var player = _status.event.player; + return player.getUseValue({ name: "sha" }) > + player.getUseValue({ name: "juedou" }) + ? "sha" + : "juedou"; + }); + "step 3"; + if (result.control) target.chooseUseTarget({ name: result.control }, true); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(get.attitude(target,player)>0&&game.hasPlayer(function(current){ - if(current==target) return false; - for(var card of [{name:'sha'},{name:'juedou'}]){ - if(target.canUse(card,current)&&get.effect(current,card,target,player)>0&&get.effect(current,card,target,target)>0) return true; - } - return false; - })&&target.countCards('h')player.countCards('h')) return -2; - var canSave=function(player,target){ - return target.hp+player.countCards('hs',card=>player.canSaveCard(card,target))>1+((get.mode()=='identity'&&target.identity=='zhu')||(get.mode()=='guozhan'&&get.is.jun(target))); + ai: { + order: 7, + result: { + target: function (player, target) { + if ( + get.attitude(target, player) > 0 && + game.hasPlayer(function (current) { + if (current == target) return false; + for (var card of [{ name: "sha" }, { name: "juedou" }]) { + if ( + target.canUse(card, current) && + get.effect(current, card, target, player) > 0 && + get.effect(current, card, target, target) > 0 + ) + return true; + } + return false; + }) && + target.countCards("h") < player.countCards("h") + 2 + ) + return 3; + if ( + !target.hasValueTarget({ name: "sha" }) && + !target.hasValueTarget({ name: "juedou" }) + ) + return -2; + if (target.countCards("h") + 1 > player.countCards("h")) return -2; + var canSave = function (player, target) { + return ( + target.hp + + player.countCards("hs", (card) => player.canSaveCard(card, target)) > + 1 + + ((get.mode() == "identity" && target.identity == "zhu") || + (get.mode() == "guozhan" && get.is.jun(target))) + ); }; - if(target.hasValueTarget({name:'sha'})){ - var aimx=game.filterPlayer(current=>{ - return target.canUse({name:'sha'},current)&&get.effect(current,{name:'sha'},target,target)>0; - }).sort((a,b)=>get.effect(b,{name:'sha'},target,target)-get.effect(a,{name:'sha'},target,target))[0]; - if(aimx&&get.effect(aimx,{name:'sha'},target,player)<0&&get.effect(aimx,{name:'sha'},target,aimx)<0&&!canSave(player,aimx)) return 0; + if (target.hasValueTarget({ name: "sha" })) { + var aimx = game + .filterPlayer((current) => { + return ( + target.canUse({ name: "sha" }, current) && + get.effect(current, { name: "sha" }, target, target) > 0 + ); + }) + .sort( + (a, b) => + get.effect(b, { name: "sha" }, target, target) - + get.effect(a, { name: "sha" }, target, target) + )[0]; + if ( + aimx && + get.effect(aimx, { name: "sha" }, target, player) < 0 && + get.effect(aimx, { name: "sha" }, target, aimx) < 0 && + !canSave(player, aimx) + ) + return 0; } - if(target.hasValueTarget({name:'juedou'})){ - var aimy=game.filterPlayer(current=>{ - return target.canUse({name:'juedou'},current)&&get.effect(current,{name:'juedou'},target,target)>0; - }).sort((a,b)=>get.effect(b,{name:'juedou'},target,target)-get.effect(a,{name:'juedou'},target,target))[0]; - if(aimy&&get.effect(aimy,{name:'juedou'},target,player)<0&&get.effect(aimy,{name:'sha'},target,aimy)<0&&!canSave(player,aimy)) return 0; + if (target.hasValueTarget({ name: "juedou" })) { + var aimy = game + .filterPlayer((current) => { + return ( + target.canUse({ name: "juedou" }, current) && + get.effect(current, { name: "juedou" }, target, target) > 0 + ); + }) + .sort( + (a, b) => + get.effect(b, { name: "juedou" }, target, target) - + get.effect(a, { name: "juedou" }, target, target) + )[0]; + if ( + aimy && + get.effect(aimy, { name: "juedou" }, target, player) < 0 && + get.effect(aimy, { name: "sha" }, target, aimy) < 0 && + !canSave(player, aimy) + ) + return 0; } return -1; }, }, }, }, - olyanhuo:{ - audio:'yanhuo', - trigger:{player:'die'}, - forceDie:true, - filter:function(event,player){ - if(!event.source||!event.source.isIn()||!event.source.countCards('he')) return false; - return player.countCards('he')>0; + olyanhuo: { + audio: "yanhuo", + trigger: { player: "die" }, + forceDie: true, + filter: function (event, player) { + if (!event.source || !event.source.isIn() || !event.source.countCards("he")) return false; + return player.countCards("he") > 0; }, - check:function(event,player){ - return get.effect(event.source,{name:'guohe_copy2'},player,player)>0; + check: function (event, player) { + return get.effect(event.source, { name: "guohe_copy2" }, player, player) > 0; }, - logTarget:'source', - skillAnimation:true, - animationColor:'thunder', - content:function(){ - player.discardPlayerCard(trigger.source,'he',[1,player.countCards('he')],true).set('forceDie',true); + logTarget: "source", + skillAnimation: true, + animationColor: "thunder", + content: function () { + player + .discardPlayerCard(trigger.source, "he", [1, player.countCards("he")], true) + .set("forceDie", true); }, }, //韩遂 - olniluan:{ - audio:'niluan', - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player.getHp()>player.getHp()&&event.player.getHistory('useCard',function(card){ - return card.card.name=='sha'; - }).length&&player.countCards('hes',card=>get.color(card,player)=='black'&&player.canUse(get.autoViewAs({name:'sha'},[card]),event.player,false)); + olniluan: { + audio: "niluan", + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player.getHp() > player.getHp() && + event.player.getHistory("useCard", function (card) { + return card.card.name == "sha"; + }).length && + player.countCards( + "hes", + (card) => + get.color(card, player) == "black" && + player.canUse(get.autoViewAs({ name: "sha" }, [card]), event.player, false) + ) + ); }, - direct:true, - content:function(){ - var next=player.chooseToUse(); - next.set('openskilldialog','逆乱:是否将一张黑色牌当作【杀】对'+get.translation(trigger.player)+'使用?'); - next.set('norestore',true); - next.set('_backupevent','niluanx'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + direct: true, + content: function () { + var next = player.chooseToUse(); + next.set( + "openskilldialog", + "逆乱:是否将一张黑色牌当作【杀】对" + get.translation(trigger.player) + "使用?" + ); + next.set("norestore", true); + next.set("_backupevent", "niluanx"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('niluanx'); - next.set('targetRequired',true); - next.set('complexSelect',true); - next.set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); + next.backup("niluanx"); + next.set("targetRequired", true); + next.set("complexSelect", true); + next.set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); }); - next.set('sourcex',trigger.player); - next.set('addCount',false); - next.logSkill='olniluan'; + next.set("sourcex", trigger.player); + next.set("addCount", false); + next.logSkill = "olniluan"; }, }, - olxiaoxi:{ - audio:'xiaoxi', - audioname:['machao','hansui','pangde'], - trigger:{global:'roundStart'}, - filter:function(event,player){ - return player.hasUseTarget({name:'sha'},false); + olxiaoxi: { + audio: "xiaoxi", + audioname: ["machao", "hansui", "pangde"], + trigger: { global: "roundStart" }, + filter: function (event, player) { + return player.hasUseTarget({ name: "sha" }, false); }, - direct:true, - content:function(){ - player.chooseUseTarget({name:'sha'},get.prompt('olxiaoxi'),'视为使用一张无距离限制的【杀】',false,'nodistance').logSkill='olxiaoxi'; + direct: true, + content: function () { + player.chooseUseTarget( + { name: "sha" }, + get.prompt("olxiaoxi"), + "视为使用一张无距离限制的【杀】", + false, + "nodistance" + ).logSkill = "olxiaoxi"; }, }, //段颎 - olsaogu:{ - audio:2, - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content:function(storage){ - if(storage) return '转换技。①出牌阶段,你可以摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色摸一张牌。'; - return '转换技。①出牌阶段,你可以弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】。②结束阶段,你可以弃置一张牌,令一名其他角色弃置两张牌,然后其使用弃置的【杀】。'; + olsaogu: { + audio: 2, + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content: function (storage) { + if (storage) + return "转换技。①出牌阶段,你可以摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色摸一张牌。"; + return "转换技。①出牌阶段,你可以弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】。②结束阶段,你可以弃置一张牌,令一名其他角色弃置两张牌,然后其使用弃置的【杀】。"; }, }, - onChooseToUse:function(event){ - if(!game.online&&!event.olsaogu){ - var list=[],player=event.player; - var evtx=event.getParent('phaseUse'); - player.getHistory('lose',evt=>{ - if(evt.type=='discard'&&evt.getParent('phaseUse')==evtx) list.addArray(evt.cards2); + onChooseToUse: function (event) { + if (!game.online && !event.olsaogu) { + var list = [], + player = event.player; + var evtx = event.getParent("phaseUse"); + player.getHistory("lose", (evt) => { + if (evt.type == "discard" && evt.getParent("phaseUse") == evtx) + list.addArray(evt.cards2); }); - event.set('olsaogu',list); + event.set("olsaogu", list); } }, - enable:'phaseUse', - filter:function(event,player){ - var storage=player.storage.olsaogu; - if(storage) return true; - return player.getDiscardableCards(player,'he').filter(card=>{ - if(event.olsaogu&&event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; - return true; - }).length>1; + enable: "phaseUse", + filter: function (event, player) { + var storage = player.storage.olsaogu; + if (storage) return true; + return ( + player.getDiscardableCards(player, "he").filter((card) => { + if ( + event.olsaogu && + event.olsaogu.some( + (cardx) => get.suit(cardx, false) == get.suit(card, player) + ) + ) + return false; + return true; + }).length > 1 + ); }, - filterCard:function(card,player){ - if(player.storage.olsaogu) return false; - if(_status.event.olsaogu&&_status.event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; + filterCard: function (card, player) { + if (player.storage.olsaogu) return false; + if ( + _status.event.olsaogu && + _status.event.olsaogu.some( + (cardx) => get.suit(cardx, false) == get.suit(card, player) + ) + ) + return false; return true; }, - selectCard:function(){ - var player=_status.event.player; - return player.storage.olsaogu?-1:2; + selectCard: function () { + var player = _status.event.player; + return player.storage.olsaogu ? -1 : 2; }, - position:'he', - check:function(card){ - var player=_status.event.player; - if(card.name=='sha') return player.hasValueTarget(card)?10:0.001; - return 6-get.value(card); + position: "he", + check: function (card) { + var player = _status.event.player; + if (card.name == "sha") return player.hasValueTarget(card) ? 10 : 0.001; + return 6 - get.value(card); }, - prompt:function(){ - var player=_status.event.player; - var storage=player.storage.olsaogu; - if(storage) return '摸一张牌'; - var list=_status.event.olsaogu,str=''; - if(list&&list.length){ - var text='',suits=list.reduce(function(list,card){ - return list.add(get.suit(card,false)),list; - },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); - for(var i=0;i lib.suit.indexOf(b) - lib.suit.indexOf(a)); + for (var i = 0; i < suits.length; i++) text += get.translation(suits[i]); + str += "(不能弃置" + text + "花色的牌)"; } - return '弃置两张牌'+str+',然后使用其中的【杀】'; + return "弃置两张牌" + str + ",然后使用其中的【杀】"; }, - content:function(){ - player.changeZhuanhuanji('olsaogu'); - if(!cards.length) player.draw(); - else{ - var cardx=cards.filter(card=>card.name=='sha'); - if(cardx.length){ - var next=game.createEvent('olsaogu_chooseToUseSha'); - next.player=player; - next.cards=cardx; + content: function () { + player.changeZhuanhuanji("olsaogu"); + if (!cards.length) player.draw(); + else { + var cardx = cards.filter((card) => card.name == "sha"); + if (cardx.length) { + var next = game.createEvent("olsaogu_chooseToUseSha"); + next.player = player; + next.cards = cardx; next.setContent(lib.skill.olsaogu.chooseToUseSha); } } }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'},player)-0.2; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }, player) - 0.2; }, - result:{ - player:function(player){ - var storage=player.storage.olsaogu; - if(storage) return 1; - if(player.getDiscardableCards(player,'he').filter(card=>{ - if(card.name!='sha') return false; - if(_status.event.olsaogu&&_status.event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; - return true; - }).length) return 1; + result: { + player: function (player) { + var storage = player.storage.olsaogu; + if (storage) return 1; + if ( + player.getDiscardableCards(player, "he").filter((card) => { + if (card.name != "sha") return false; + if ( + _status.event.olsaogu && + _status.event.olsaogu.some( + (cardx) => get.suit(cardx, false) == get.suit(card, player) + ) + ) + return false; + return true; + }).length + ) + return 1; return 0; }, }, }, - group:'olsaogu_effect', - subSkill:{ - effect:{ - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - if(_status.connectMode) return player.countCards('he'); - return player.countDiscardableCards(player,'he'); + group: "olsaogu_effect", + subSkill: { + effect: { + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + if (_status.connectMode) return player.countCards("he"); + return player.countDiscardableCards(player, "he"); }, - direct:true, - content:function(){ - 'step 0' - var list=[]; - player.getHistory('lose',evt=>{ - if(evt.type=='discard'&&evt.getParent('phaseJieshu').name=='phaseJieshu') list.addArray(evt.cards2); + direct: true, + content: function () { + "step 0"; + var list = []; + player.getHistory("lose", (evt) => { + if ( + evt.type == "discard" && + evt.getParent("phaseJieshu").name == "phaseJieshu" + ) + list.addArray(evt.cards2); }); - event.list=list; - var str,storage=player.storage.olsaogu; - if(storage) str='弃置一张牌,令一名其他角色摸一张牌。'; - else{ - str='弃置一张牌,令一名其他角色弃置两张牌(不能包含你本阶段弃置过的花色),然后其使用弃置的【杀】。'; - if(list.length){ - var text='',suits=list.reduce(function(list,card){ - return list.add(get.suit(card,false)),list; - },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); - for(var i=0;i lib.suit.indexOf(b) - lib.suit.indexOf(a)); + for (var i = 0; i < suits.length; i++) text += get.translation(suits[i]); + str += "
              本阶段已弃置过" + text + "花色的牌。"; } } - player.chooseCardTarget({ - prompt:get.prompt('olsaogu'), - prompt2:str, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('he')>1; - }, - filterCard:lib.filter.cardDiscardable, - position:'he', - complexCard:true, - complexSelect:true, - ai1:function(card){ - var player=_status.event.player; - if(!player.storage.olsaogu&&_status.event.list.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return 7-get.value(card); - return 5-get.value(card); - }, - ai2:function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(player.storage.olsaogu) return att; - var list=_status.event.list.slice(); - if(ui.selected.cards.length) list.addArray(ui.selected.cards); - var cards=target.getCards('he',card=>{ - if(card.name!='sha'||list.some(cardx=>get.suit(cardx,false)==get.suit(card,target))) return false; - return lib.filter.cardDiscardable(card,target)&&game.hasPlayer(function(current){ - if(!current.canUse(card,target,false)) return false; - return get.effect(current,card,target,target)>0&&get.effect(current,card,target,player)>0; + player + .chooseCardTarget({ + prompt: get.prompt("olsaogu"), + prompt2: str, + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 1; + }, + filterCard: lib.filter.cardDiscardable, + position: "he", + complexCard: true, + complexSelect: true, + ai1: function (card) { + var player = _status.event.player; + if ( + !player.storage.olsaogu && + _status.event.list.some( + (cardx) => get.suit(cardx, false) == get.suit(card, player) + ) + ) + return 7 - get.value(card); + return 5 - get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (player.storage.olsaogu) return att; + var list = _status.event.list.slice(); + if (ui.selected.cards.length) list.addArray(ui.selected.cards); + var cards = target.getCards("he", (card) => { + if ( + card.name != "sha" || + list.some( + (cardx) => + get.suit(cardx, false) == get.suit(card, target) + ) + ) + return false; + return ( + lib.filter.cardDiscardable(card, target) && + game.hasPlayer(function (current) { + if (!current.canUse(card, target, false)) return false; + return ( + get.effect(current, card, target, target) > 0 && + get.effect(current, card, target, player) > 0 + ); + }) + ); }); - }); - if(cards.length&&att>0) return Math.sqrt(Math.min(2,cards.length))*cards.reduce(function(num,card){ - var players=game.filterPlayer(current=>target.canUse(card,current,false)); - players.sort((a,b)=>get.effect(b,card,target,target)*get.effect(b,card,target,player)-get.effect(a,card,target,target)*get.effect(a,card,target,player)); - return num=(get.effect(players[0],card,target,target)*get.effect(players[0],card,target,player)); - },0); - return get.effect(target,{name:'guohe_copy2'},player,player)*Math.sqrt(Math.min(2,target.getDiscardableCards(player,'he').filter(card=>{ - return !list.some(cardx=>get.suit(cardx,false)==get.suit(card,target)); - }).length)); - }, - }).set('list',list); - 'step 1' - if(result.bool){ - var cards=result.cards,target=result.targets[0]; - player.logSkill('olsaogu',target); + if (cards.length && att > 0) + return ( + Math.sqrt(Math.min(2, cards.length)) * + cards.reduce(function (num, card) { + var players = game.filterPlayer((current) => + target.canUse(card, current, false) + ); + players.sort( + (a, b) => + get.effect(b, card, target, target) * + get.effect(b, card, target, player) - + get.effect(a, card, target, target) * + get.effect(a, card, target, player) + ); + return (num = + get.effect(players[0], card, target, target) * + get.effect(players[0], card, target, player)); + }, 0) + ); + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) * + Math.sqrt( + Math.min( + 2, + target + .getDiscardableCards(player, "he") + .filter((card) => { + return !list.some( + (cardx) => + get.suit(cardx, false) == + get.suit(card, target) + ); + }).length + ) + ) + ); + }, + }) + .set("list", list); + "step 1"; + if (result.bool) { + var cards = result.cards, + target = result.targets[0]; + player.logSkill("olsaogu", target); player.discard(cards); - if(player.storage.olsaogu){ + if (player.storage.olsaogu) { target.draw(); event.finish(); - } - else{ - event.target=target; - var list=result.cards.slice(); - player.getHistory('lose',evt=>{ - if(evt.type=='discard'&&evt.getParent('phaseJieshu').name=='phaseJieshu') list.addArray(evt.cards2); + } else { + event.target = target; + var list = result.cards.slice(); + player.getHistory("lose", (evt) => { + if ( + evt.type == "discard" && + evt.getParent("phaseJieshu").name == "phaseJieshu" + ) + list.addArray(evt.cards2); }); - var cards=target.getCards('he',card=>{ - return lib.filter.cardDiscardable(card,target)&&!list.some(cardx=>get.suit(cardx,false)==get.suit(card,target)); + var cards = target.getCards("he", (card) => { + return ( + lib.filter.cardDiscardable(card, target) && + !list.some( + (cardx) => get.suit(cardx, false) == get.suit(card, target) + ) + ); }); - if(cards.length){ - var text='',suits=list.reduce(function(list,card){ - return list.add(get.suit(card,false)),list; - },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); - for(var i=0;iget.suit(cardx,false)==get.suit(card,player)); - },Math.min(cards.length,2),true).set('ai',function(card){ - var player=_status.event.player; - if(card.name=='sha'&&player.hasValueTarget(card)) return 10; - return -get.value(card); - }).set('list',list); - } - else event.finish(); + if (cards.length) { + var text = "", + suits = list + .reduce(function (list, card) { + return list.add(get.suit(card, false)), list; + }, []) + .sort((a, b) => lib.suit.indexOf(b) - lib.suit.indexOf(a)); + for (var i = 0; i < suits.length; i++) + text += get.translation(suits[i]); + target + .chooseToDiscard( + "he", + "扫谷:弃置两张牌(不能弃置" + + text + + "花色的牌),然后使用其中的【杀】", + function (card, player) { + var list = _status.event.list; + return !list.some( + (cardx) => + get.suit(cardx, false) == get.suit(card, player) + ); + }, + Math.min(cards.length, 2), + true + ) + .set("ai", function (card) { + var player = _status.event.player; + if (card.name == "sha" && player.hasValueTarget(card)) + return 10; + return -get.value(card); + }) + .set("list", list); + } else event.finish(); } - } - else event.finish(); - 'step 2' - if(result.bool){ - var cards=result.cards.filter(card=>card.name=='sha'); - if(cards.length){ - var next=game.createEvent('olsaogu_chooseToUseSha'); - next.player=target; - next.cards=cards; + } else event.finish(); + "step 2"; + if (result.bool) { + var cards = result.cards.filter((card) => card.name == "sha"); + if (cards.length) { + var next = game.createEvent("olsaogu_chooseToUseSha"); + next.player = target; + next.cards = cards; next.setContent(lib.skill.olsaogu.chooseToUseSha); } } }, }, }, - chooseToUseSha:function(){ - 'step 0' - event.cards2=cards.filter(i=>get.position(i,true)=='d'&&player.hasUseTarget(i)); - if(!event.cards2.length) event.finish(); - 'step 1' - if(event.cards2.length==1) event._result={bool:true,links:event.cards2}; - else player.chooseButton(['扫谷:请使用其中的【杀】',event.cards2],true).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link,false); - }).set('ai',button=>{ - return _status.event.player.getUseValue(button.link); - }); - 'step 2' - if(result.bool){ - var card=result.links[0]; + chooseToUseSha: function () { + "step 0"; + event.cards2 = cards.filter( + (i) => get.position(i, true) == "d" && player.hasUseTarget(i) + ); + if (!event.cards2.length) event.finish(); + "step 1"; + if (event.cards2.length == 1) event._result = { bool: true, links: event.cards2 }; + else + player + .chooseButton(["扫谷:请使用其中的【杀】", event.cards2], true) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link, false); + }) + .set("ai", (button) => { + return _status.event.player.getUseValue(button.link); + }); + "step 2"; + if (result.bool) { + var card = result.links[0]; event.cards2.remove(card); - player.$gain2(card,false); + player.$gain2(card, false); game.delayx(); - player.chooseUseTarget(true,card,false); - } - else event.finish(); - 'step 3' - if(event.cards2.length) event.goto(1); + player.chooseUseTarget(true, card, false); + } else event.finish(); + "step 3"; + if (event.cards2.length) event.goto(1); }, }, //OL周群 - oltianhou:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ - 'step 0' - var card=get.cards()[0]; - event.card=card; + oltianhou: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { + "step 0"; + var card = get.cards()[0]; + event.card = card; game.cardsGotoOrdering(card); - 'step 1' - if(player.countCards('he')>0){ - 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; + "step 1"; + if (player.countCards("he") > 0) { + 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; }); - 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; + } else { + event._result = { bool: false }; + } + "step 2"; + if (result.bool) { + player.lose(result.cards, ui.cardPile, "insert"); + player.gain(event.card, "draw"); + } else { + ui.cardPile.insertBefore(event.card, ui.cardPile.firstChild); + } + "step 3"; + var card = get.cards()[0]; + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); + player.showCards(card, get.translation(player) + "发动了【天候】"); + var suit = get.suit(card, false), + skill = "oltianhou_" + suit; + if (!lib.skill.oltianhou.derivation.includes(skill)) event.finish(); + else { + event.weather_skill = skill; + player + .chooseTarget( + true, + "令一名角色获得技能【" + get.translation(skill) + "】", + get.translation(skill + "_info") + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); }); - return val+0.1; - }); } - else{ - event._result={bool:false}; - } - 'step 2' - if(result.bool){ - player.lose(result.cards,ui.cardPile,'insert'); - player.gain(event.card,'draw'); - } - else{ - ui.cardPile.insertBefore(event.card,ui.cardPile.firstChild); - } - 'step 3' - var card=get.cards()[0]; - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); - player.showCards(card,get.translation(player)+'发动了【天候】'); - var suit=get.suit(card,false),skill='oltianhou_'+suit; - if(!lib.skill.oltianhou.derivation.includes(skill)) event.finish(); - else{ - event.weather_skill=skill; - player.chooseTarget(true,'令一名角色获得技能【'+get.translation(skill)+'】',get.translation(skill+'_info')).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - } - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.addAdditionalSkill('oltianhou_'+player.playerid,event.weather_skill); - player.addTempSkill('oltianhou_expire',{player:'phaseZhunbeiBegin'}); - game.log(target,'获得了天气技能','#g【'+get.translation(event.weather_skill)+'】'); - game.broadcastAll(function(bg){ - _status.tempBackground=bg; + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.addAdditionalSkill("oltianhou_" + player.playerid, event.weather_skill); + player.addTempSkill("oltianhou_expire", { player: "phaseZhunbeiBegin" }); + game.log( + target, + "获得了天气技能", + "#g【" + get.translation(event.weather_skill) + "】" + ); + game.broadcastAll(function (bg) { + _status.tempBackground = bg; game.updateBackground(); - },event.weather_skill+'_bg'); - game.addVideo('skill',player,['oltianhou',[true,event.weather_skill+'_bg']]) + }, event.weather_skill + "_bg"); + game.addVideo("skill", player, ["oltianhou", [true, event.weather_skill + "_bg"]]); } }, - video:function(player,info){ - if(info[0]){ - _status.tempBackground=info[1]; - } - else{ + video: function (player, info) { + if (info[0]) { + _status.tempBackground = info[1]; + } else { delete _status.tempBackground; } game.updateBackground(); }, - derivation:['oltianhou_spade','oltianhou_heart','oltianhou_club','oltianhou_diamond'], - subSkill:{ - expire:{ - charlotte:true, - onremove:function(player){ - var key='oltianhou_'+player.playerid,players=game.players.concat(game.dead); - for(var current of players){ + derivation: ["oltianhou_spade", "oltianhou_heart", "oltianhou_club", "oltianhou_diamond"], + subSkill: { + expire: { + charlotte: true, + onremove: function (player) { + var key = "oltianhou_" + player.playerid, + players = game.players.concat(game.dead); + for (var current of players) { current.removeAdditionalSkill(key); } - game.removeGlobalSkill('oltianhou_'+player.playerid+'_ai'); - game.broadcastAll(function(){ + game.removeGlobalSkill("oltianhou_" + player.playerid + "_ai"); + game.broadcastAll(function () { delete _status.tempBackground; game.updateBackground(); }); - game.addVideo('skill',player,['oltianhou',[false]]) + game.addVideo("skill", player, ["oltianhou", [false]]); }, }, - spade:{ - audio:true, - mark:true, - marktext:'雨', - intro:{ - content:'锁定技。其他角色造成火属性伤害时,取消之;一名角色受到雷属性伤害后,所有与其座次相邻的角色失去1点体力。', + spade: { + audio: true, + mark: true, + marktext: "雨", + intro: { + content: + "锁定技。其他角色造成火属性伤害时,取消之;一名角色受到雷属性伤害后,所有与其座次相邻的角色失去1点体力。", }, - trigger:{global:'damageEnd'}, - forced:true, - filter:function(event){ - return event.hasNature('thunder')&&lib.skill.oltianhou_spade.logTarget(event).length>0; + trigger: { global: "damageEnd" }, + forced: true, + filter: function (event) { + return ( + event.hasNature("thunder") && + lib.skill.oltianhou_spade.logTarget(event).length > 0 + ); }, - logTarget:function(event){ - var list=[]; - if(!event.player.isIn()) return []; - if(event.player.getNext().isIn()) list.push(event.player.getNext()); - if(event.player.getPrevious().isIn()) list.push(event.player.getPrevious()); + logTarget: function (event) { + var list = []; + if (!event.player.isIn()) return []; + if (event.player.getNext().isIn()) list.push(event.player.getNext()); + if (event.player.getPrevious().isIn()) list.push(event.player.getPrevious()); return list.sortBySeat(_status.currentPhase); }, - content:function(){ - var targets=lib.skill.oltianhou_spade.logTarget(trigger); - for(var i of targets) i.loseHp(); + content: function () { + var targets = lib.skill.oltianhou_spade.logTarget(trigger); + for (var i of targets) i.loseHp(); game.delayex(); }, - group:'oltianhou_miehuo', - global:'oltianhou_spade_ai', + group: "oltianhou_miehuo", + global: "oltianhou_spade_ai", }, - spade_ai:{ - 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]; + spade_ai: { + 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]; } - } - } - } - }, - miehuo:{ - audio:'oltianhou_spade', - trigger:{global:'damageBegin2'}, - forced:true, - logTarget:'source', - filter:function(event,player){ - return event.hasNature('fire')&&event.source&&event.source.isIn()&&event.source!=player; + }, + }, }, - content:function(){ + }, + miehuo: { + audio: "oltianhou_spade", + trigger: { global: "damageBegin2" }, + forced: true, + logTarget: "source", + filter: function (event, player) { + return ( + event.hasNature("fire") && + event.source && + event.source.isIn() && + event.source != player + ); + }, + content: function () { trigger.cancel(); - } + }, }, - heart:{ - audio:true, - mark:true, - marktext:'暑', - intro:{ - content:'锁定技。其他角色的结束阶段开始时,若其体力值为全场最大,则其失去1点体力。', + heart: { + audio: true, + mark: true, + marktext: "暑", + intro: { + content: + "锁定技。其他角色的结束阶段开始时,若其体力值为全场最大,则其失去1点体力。", }, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&event.player.isMaxHp(); + trigger: { global: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player != event.player && event.player.isIn() && event.player.isMaxHp(); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.loseHp(); }, - global:'oltianhou_heart_ai' + 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; - } - } + 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, - mark:true, - marktext:'霜', - intro:{ - content:'锁定技。其他角色的结束阶段开始时,若其体力值为全场最小,则其失去1点体力。', + club: { + audio: true, + mark: true, + marktext: "霜", + intro: { + content: + "锁定技。其他角色的结束阶段开始时,若其体力值为全场最小,则其失去1点体力。", }, - trigger:{global:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&event.player.isMinHp(); + trigger: { global: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player != event.player && event.player.isIn() && event.player.isMinHp(); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.loseHp(); }, - global:'oltianhou_club_ai' + 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; - } - } + 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, - mark:true, - marktext:'雾', - intro:{ - content:'锁定技。其他角色使用【杀】指定与其座次不相邻唯一目标时,则其判定。若判定结果的点数大于此【杀】,则此【杀】对其无效。', + diamond: { + audio: true, + mark: true, + marktext: "雾", + intro: { + content: + "锁定技。其他角色使用【杀】指定与其座次不相邻唯一目标时,则其判定。若判定结果的点数大于此【杀】,则此【杀】对其无效。", }, - trigger:{global:'useCardToPlayer'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha'||event.player==player||event.targets.length!=1||!event.player.isIn()) return false; - return event.target!=event.player.getNext()&&event.target!=event.player.getPrevious(); - }, - logTarget:'player', - content:function(){ - 'step 0' - var num=get.number(trigger.card); - event.num=num; - trigger.player.judge(card=>{ - var num=get.number(card),num2=_status.event.getParent('oltianhou_diamond').num; - return num>num2?-4:4; - }).set('judge2',result=>{ - if(result.bool==false) return true; + trigger: { global: "useCardToPlayer" }, + forced: true, + filter: function (event, player) { + if ( + event.card.name != "sha" || + event.player == player || + event.targets.length != 1 || + !event.player.isIn() + ) return false; - }) - 'step 1' - if(!result.bool){ - trigger.getParent().all_excluded=true; + return ( + event.target != event.player.getNext() && + event.target != event.player.getPrevious() + ); + }, + logTarget: "player", + content: function () { + "step 0"; + var num = get.number(trigger.card); + event.num = num; + trigger.player + .judge((card) => { + var num = get.number(card), + num2 = _status.event.getParent("oltianhou_diamond").num; + return num > num2 ? -4 : 4; + }) + .set("judge2", (result) => { + if (result.bool == false) return true; + return false; + }); + "step 1"; + if (!result.bool) { + trigger.getParent().all_excluded = true; trigger.untrigger(); } }, - global:'oltianhou_diamond_ai', + global: "oltianhou_diamond_ai", }, - diamond_ai:{ - 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]; + diamond_ai: { + 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]; } - } - } - } + }, + }, + }, }, - } + }, }, - olchenshuo:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + olchenshuo: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - hasSame:function(info,card){ - if(info.type==get.type2(card,false)) return true; - if(info.suit!='none'&&info.suit==get.suit(card,false)) return true; - if(typeof info.number=='number'&&info.number>0&&info.number==get.number(card,false)) return true; - return info.length==get.cardNameLength(card) + hasSame: function (info, card) { + if (info.type == get.type2(card, false)) return true; + if (info.suit != "none" && info.suit == get.suit(card, false)) return true; + if ( + typeof info.number == "number" && + info.number > 0 && + info.number == get.number(card, false) + ) + return true; + return info.length == get.cardNameLength(card); }, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('olchenshuo'),'展示一张手牌,然后展示并获得牌堆顶的牌').set('ai',function(card){ - if(get.type(card)=='basic') return 1+Math.random(); - return Math.random(); - }) - 'step 1' - if(result.bool){ - player.logSkill('olchenshuo'); - player.showCards(result.cards,get.translation(player)+'发动了【谶说】'); - var card=result.cards[0]; - event.cardInfo={ - type:get.type2(card,player), - suit:get.suit(card,player), - number:get.number(card,player), - length:get.cardNameLength(card), - } - event.cards=[]; - event.forceDie=true; - event.includeOut=true; - } - else event.finish(); - 'step 2' - var judgestr=get.translation(player)+'展示的第'+get.cnNumber(cards.length+1,true)+'张【谶说】牌'; - event.videoId=lib.status.videoId++; - var card=get.cards()[0]; - event.card=card; + content: function () { + "step 0"; + player + .chooseCard("h", get.prompt("olchenshuo"), "展示一张手牌,然后展示并获得牌堆顶的牌") + .set("ai", function (card) { + if (get.type(card) == "basic") return 1 + Math.random(); + return Math.random(); + }); + "step 1"; + if (result.bool) { + player.logSkill("olchenshuo"); + player.showCards(result.cards, get.translation(player) + "发动了【谶说】"); + var card = result.cards[0]; + event.cardInfo = { + type: get.type2(card, player), + suit: get.suit(card, player), + number: get.number(card, player), + length: get.cardNameLength(card), + }; + event.cards = []; + event.forceDie = true; + event.includeOut = true; + } else event.finish(); + "step 2"; + var judgestr = + get.translation(player) + + "展示的第" + + get.cnNumber(cards.length + 1, true) + + "张【谶说】牌"; + event.videoId = lib.status.videoId++; + var card = get.cards()[0]; + event.card = card; cards.add(card); game.cardsGotoOrdering(card); - game.addVideo('judge1',player,[get.cardInfo(card),judgestr,event.videoId]); - game.broadcastAll(function(player,card,str,id,cardid){ - var event; - if(game.online){ - event={}; - } - else{ - event=_status.event; - } - if(game.chess){ - event.node=card.copy('thrown','center',ui.arena).addTempClass('start'); - } - else{ - event.node=player.$throwordered(card.copy(),true); - } - if(lib.cardOL) lib.cardOL[cardid]=event.node; - event.node.cardid=cardid; - event.node.classList.add('thrownhighlight'); - ui.arena.classList.add('thrownhighlight'); - event.dialog=ui.create.dialog(str); - event.dialog.classList.add('center'); - event.dialog.videoId=id; - },player,card,judgestr,event.videoId,get.id()); - game.log(player,'展示了牌堆顶的',card); + game.addVideo("judge1", player, [get.cardInfo(card), judgestr, event.videoId]); + game.broadcastAll( + function (player, card, str, id, cardid) { + var event; + if (game.online) { + event = {}; + } else { + event = _status.event; + } + if (game.chess) { + event.node = card.copy("thrown", "center", ui.arena).addTempClass("start"); + } else { + event.node = player.$throwordered(card.copy(), true); + } + if (lib.cardOL) lib.cardOL[cardid] = event.node; + event.node.cardid = cardid; + event.node.classList.add("thrownhighlight"); + ui.arena.classList.add("thrownhighlight"); + event.dialog = ui.create.dialog(str); + event.dialog.classList.add("center"); + event.dialog.videoId = id; + }, + player, + card, + judgestr, + event.videoId, + get.id() + ); + game.log(player, "展示了牌堆顶的", card); game.delay(2); - 'step 3' - game.broadcastAll(function(id){ - var dialog=get.idDialog(id); - if(dialog){ + "step 3"; + game.broadcastAll(function (id) { + var dialog = get.idDialog(id); + if (dialog) { dialog.close(); } - ui.arena.classList.remove('thrownhighlight'); - },event.videoId); - game.addVideo('judge2',null,event.videoId); - if(cards.length<3&&player.isIn()&&lib.skill.olchenshuo.hasSame(event.cardInfo,card)) event.goto(2); - else{ - game.broadcastAll(function(){ui.clear()}); - player.gain(cards,'gain2'); + ui.arena.classList.remove("thrownhighlight"); + }, event.videoId); + game.addVideo("judge2", null, event.videoId); + if ( + cards.length < 3 && + player.isIn() && + lib.skill.olchenshuo.hasSame(event.cardInfo, card) + ) + event.goto(2); + else { + game.broadcastAll(function () { + ui.clear(); + }); + player.gain(cards, "gain2"); } }, }, //OL文钦 - olguangao:{ - audio:2, - trigger:{ - global:'useCard2', + olguangao: { + audio: 2, + trigger: { + global: "useCard2", }, - filter:function(event,player){ - var card=event.card; - if(card.name!='sha') return false; - if(event.player==player){ - return game.hasPlayer(current=>{ - return current.isIn()&&!event.targets.includes(current)&&player.canUse(card,current); + filter: function (event, player) { + var card = event.card; + if (card.name != "sha") return false; + if (event.player == player) { + return game.hasPlayer((current) => { + return ( + current.isIn() && + !event.targets.includes(current) && + player.canUse(card, current) + ); }); } - return event.player.isIn()&&!event.targets.includes(player)&&event.player.canUse(card,player); + return ( + event.player.isIn() && + !event.targets.includes(player) && + event.player.canUse(card, player) + ); }, - direct:true, - content:function(){ - 'step 0' - if(trigger.player==player){ - player.chooseTarget(get.prompt('olguangao'),'为'+get.translation(trigger.card)+'额外指定一个目标。然后若你手牌数为偶数,你摸一张牌并令此牌对任意目标无效。',(card,player,target)=>{ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target); - }).set('sourcex',trigger.targets).set('ai',function(target){ - var player=_status.event.player; - if(player.countCards('h')%2==0) return true; - var eff=get.effect(target,_status.event.card,player,player); - if(player.hasSkill('olxieju')&&player.isPhaseUsing()&&!player.getStat().skill.olxieju&&get.attitude(player,target)>0&&!game.hasGlobalHistory('useCard',evt=>{ - return evt.targets&&evt.targets.includes(target); - })) return 6+eff; - return eff; - }).set('card',trigger.card); + direct: true, + content: function () { + "step 0"; + if (trigger.player == player) { + player + .chooseTarget( + get.prompt("olguangao"), + "为" + + get.translation(trigger.card) + + "额外指定一个目标。然后若你手牌数为偶数,你摸一张牌并令此牌对任意目标无效。", + (card, player, target) => { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("ai", function (target) { + var player = _status.event.player; + if (player.countCards("h") % 2 == 0) return true; + var eff = get.effect(target, _status.event.card, player, player); + if ( + player.hasSkill("olxieju") && + player.isPhaseUsing() && + !player.getStat().skill.olxieju && + get.attitude(player, target) > 0 && + !game.hasGlobalHistory("useCard", (evt) => { + return evt.targets && evt.targets.includes(target); + }) + ) + return 6 + eff; + return eff; + }) + .set("card", trigger.card); + } else { + trigger.player + .chooseBool( + "是否发动" + get.translation(player) + "的【犷骜】?", + "令其成为" + + get.translation(trigger.card) + + "的额外目标。然后若其手牌数为偶数,其摸一张牌并令此牌对任意目标无效。" + ) + .set("ai", () => { + return _status.event.bool; + }) + .set( + "bool", + (function () { + var att = get.attitude(trigger.player, player); + if (player.countCards("h") % 2 == 0) { + if (att > 0) return true; + return false; + } + if (get.effect(player, trigger.card, trigger.player, trigger.player) > 0) + return true; + return false; + })() + ); } - else{ - trigger.player.chooseBool('是否发动'+get.translation(player)+'的【犷骜】?','令其成为'+get.translation(trigger.card)+'的额外目标。然后若其手牌数为偶数,其摸一张牌并令此牌对任意目标无效。').set('ai',()=>{ - return _status.event.bool; - }).set('bool',function(){ - var att=get.attitude(trigger.player,player); - if(player.countCards('h')%2==0){ - if(att>0) return true; - return false; - } - if(get.effect(player,trigger.card,trigger.player,trigger.player)>0) return true; - return false; - }()); - } - 'step 1' - if(result.bool){ - var target=result.targets&&result.targets[0]; - if(!target){ - target=player; - trigger.player.logSkill('olguangao',player); - } - else{ - player.logSkill('olguangao',target); + "step 1"; + if (result.bool) { + var target = result.targets && result.targets[0]; + if (!target) { + target = player; + trigger.player.logSkill("olguangao", player); + } else { + player.logSkill("olguangao", target); } trigger.targets.add(target); game.delayex(); - } - else event.finish(); - 'step 2' - if(player.countCards('h')%2==0){ + } else event.finish(); + "step 2"; + if (player.countCards("h") % 2 == 0) { player.draw(); - player.chooseTarget('犷骜:令此杀对其任意个目标无效',[1,Infinity],(card,player,target)=>{ - return _status.event.targetsx.includes(target); - }).set('ai',target=>{ - return 1-get.effect(target,_status.event.getTrigger().card,_status.event.player,_status.event.player); - }).set('targetsx',trigger.targets); - } - else event.finish(); - 'step 3' - if(result.bool){ + player + .chooseTarget( + "犷骜:令此杀对其任意个目标无效", + [1, Infinity], + (card, player, target) => { + return _status.event.targetsx.includes(target); + } + ) + .set("ai", (target) => { + return ( + 1 - + get.effect( + target, + _status.event.getTrigger().card, + _status.event.player, + _status.event.player + ) + ); + }) + .set("targetsx", trigger.targets); + } else event.finish(); + "step 3"; + if (result.bool) { player.line(result.targets); trigger.excluded.addArray(result.targets); } - } - }, - olhuiqi:{ - audio:2, - trigger:{ - global:'phaseEnd', }, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'thunder', - derivation:'olxieju', - filter:function(event,player){ - var targets=[]; - game.getGlobalHistory('useCard',evt=>{ - if(evt.targets&&evt.targets.length){ + }, + olhuiqi: { + audio: 2, + trigger: { + global: "phaseEnd", + }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "thunder", + derivation: "olxieju", + filter: function (event, player) { + var targets = []; + game.getGlobalHistory("useCard", (evt) => { + if (evt.targets && evt.targets.length) { targets.addArray(evt.targets); } }); - return targets.length==3&&targets.includes(player); + return targets.length == 3 && targets.includes(player); }, - content:function(){ - 'step 0' - player.awakenSkill('olhuiqi'); - player.addSkills('olxieju'); + content: function () { + "step 0"; + player.awakenSkill("olhuiqi"); + player.addSkills("olxieju"); player.insertPhase(); - } - }, - olxieju:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return event.olxieju&&event.olxieju.length; }, - onChooseToUse:function(event){ - if(!event.olxieju&&!game.online){ - var targets=[]; - game.getGlobalHistory('useCard',evt=>{ - if(evt.targets&&evt.targets.length){ + }, + olxieju: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return event.olxieju && event.olxieju.length; + }, + onChooseToUse: function (event) { + if (!event.olxieju && !game.online) { + var targets = []; + game.getGlobalHistory("useCard", (evt) => { + if (evt.targets && evt.targets.length) { targets.addArray(evt.targets); } - }) - event.set('olxieju',targets); + }); + event.set("olxieju", targets); } }, - filterTarget:function(card,player,target){ - var event=_status.event; - if(event.olxieju.includes(target)) return true; + filterTarget: function (card, player, target) { + var event = _status.event; + if (event.olxieju.includes(target)) return true; return false; }, - selectTarget:[1,Infinity], - content:function(){ - var card={ - name:'sha', - isCard:true, + selectTarget: [1, Infinity], + content: function () { + var card = { + name: "sha", + isCard: true, }; - if(target.hasUseTarget(card,true)){ - target.chooseUseTarget(card,true,false); + if (target.hasUseTarget(card, true)) { + target.chooseUseTarget(card, true, false); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var val=target.getUseValue({name:'sha'},true); + ai: { + order: 1, + result: { + target: function (player, target) { + var val = target.getUseValue({ name: "sha" }, true); return Math.sign(val); - } - } - } + }, + }, + }, }, //郝普 - olzhenying:{ - audio:2, - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return lib.skill.olzhenying.filterTarget(null,player,current); + olzhenying: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return game.hasPlayer((current) => { + return lib.skill.olzhenying.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h')<=player.countCards('h'); + filterTarget: function (card, player, target) { + return player != target && target.countCards("h") <= player.countCards("h"); }, - content:function(){ - 'step 0' - var send=function(){ - var next=game.createEvent('olzhenying_adjust',false); + content: function () { + "step 0"; + var send = function () { + var next = game.createEvent("olzhenying_adjust", false); next.setContent(lib.skill.olzhenying.contentx); game.resume(); }; - var sendback=function(result,player){ - if(!result&&typeof result!=='number'){ - result=player.getCards('h'); - if(!result.length) result=0; + var sendback = function (result, player) { + if (!result && typeof result !== "number") { + result = player.getCards("h"); + if (!result.length) result = 0; } - event.results.push([player,result]); + event.results.push([player, result]); }; - event.ai_targets=[]; - event.results=[]; - var players=[player,target]; - for(var i=0;i{ - return get.value(b)-get.value(a); + if (event.ai_targets.length) { + for (var i = 0; i < event.ai_targets.length; i++) { + if (players.includes(event.ai_targets[i])) { + var target = event.ai_targets[i]; + var cards = target.getCards("h"); + cards = cards.sort((a, b) => { + return get.value(b) - get.value(a); }); - var beginInd=1; - var endInd=2; - var eff=get.effect(player,{name:'juedou'},target,target),eff2=get.effect(target,{name:'juedou'},player,target); - var att=get.attitude(player,target); - if(att>0||eff2>0){ - if(cards.length<=2){ - cards=2-cards.length; + var beginInd = 1; + var endInd = 2; + var eff = get.effect(player, { name: "juedou" }, target, target), + eff2 = get.effect(target, { name: "juedou" }, player, target); + var att = get.attitude(player, target); + if (att > 0 || eff2 > 0) { + if (cards.length <= 2) { + cards = 2 - cards.length; + } else { + beginInd = 2; + endInd = 2; } - else{ - beginInd=2; endInd=2; - } - } - else{ - if(get.value(cards,target)<=5&&!target.isZhu){ - if(eff>0&&Math.random()<0.65){ - beginInd=0; endInd=1; + } else { + if (get.value(cards, target) <= 5 && !target.isZhu) { + if (eff > 0 && Math.random() < 0.65) { + beginInd = 0; + endInd = 1; } } } - if(typeof cards!='number'){ - cards=cards.slice([beginInd,endInd].randomGet(),cards.length); + if (typeof cards != "number") { + cards = cards.slice([beginInd, endInd].randomGet(), cards.length); } - sendback(cards,target); - event.ai_targets.splice(i--,1); + sendback(cards, target); + event.ai_targets.splice(i--, 1); } } - if(event.ai_targets.length){ + if (event.ai_targets.length) { event.ai_targets.randomSort(); - setTimeout(function(){ - event.interval=setInterval(function(){ - var target=event.ai_targets.shift(); - var cards=target.getCards('h'); - cards=cards.sort((a,b)=>{ - return get.value(b)-get.value(a); - }); - var beginInd=1; - var endInd=2; - var eff=get.effect(player,{name:'juedou'},target,target),eff2=get.effect(target,{name:'juedou'},player,target); - var att=get.attitude(player,target); - if(att>0||eff2>0){ - if(cards.length<=2){ - cards=2-cards.length; - } - else{ - beginInd=2; endInd=2; - } - } - else{ - if(get.value(cards,target)<=5&&!target.isZhu){ - if(eff>0&&Math.random()<0.65){ - beginInd=0; endInd=1; + setTimeout(function () { + event.interval = setInterval( + function () { + var target = event.ai_targets.shift(); + var cards = target.getCards("h"); + cards = cards.sort((a, b) => { + return get.value(b) - get.value(a); + }); + var beginInd = 1; + var endInd = 2; + var eff = get.effect(player, { name: "juedou" }, target, target), + eff2 = get.effect(target, { name: "juedou" }, player, target); + var att = get.attitude(player, target); + if (att > 0 || eff2 > 0) { + if (cards.length <= 2) { + cards = 2 - cards.length; + } else { + beginInd = 2; + endInd = 2; + } + } else { + if (get.value(cards, target) <= 5 && !target.isZhu) { + if (eff > 0 && Math.random() < 0.65) { + beginInd = 0; + endInd = 1; + } } } - } - if(typeof cards!='number'){ - cards=cards.slice([beginInd,endInd].randomGet(),cards.length); - } - sendback(cards,target); - if(!event.ai_targets.length){ - clearInterval(event.interval); - if(event.withai) game.resume(); - } - },_status.connectMode?750:75); - },500); + if (typeof cards != "number") { + cards = cards.slice([beginInd, endInd].randomGet(), cards.length); + } + sendback(cards, target); + if (!event.ai_targets.length) { + clearInterval(event.interval); + if (event.withai) game.resume(); + } + }, + _status.connectMode ? 750 : 75 + ); + }, 500); } } - 'step 1' - if(event.withme){ - if(_status.connectMode) game.me.unwait(result,game.me); - else{ - if(!result&&typeof result!=='number'){ - result=game.me.getCards('h'); - if(!result.length) result=0; + "step 1"; + if (event.withme) { + if (_status.connectMode) game.me.unwait(result, game.me); + else { + if (!result && typeof result !== "number") { + result = game.me.getCards("h"); + if (!result.length) result = 0; } - event.results.push([game.me,result]); + event.results.push([game.me, result]); } } - 'step 2' - if(event.withol&&!event.resultOL){ + "step 2"; + if (event.withol && !event.resultOL) { game.pause(); } - 'step 3' - if(event.ai_targets.length>0){ - event.withai=true; + "step 3"; + if (event.ai_targets.length > 0) { + event.withai = true; game.pause(); } - 'step 4' - if(_status.connectMode){ - for(var i of [player,target]) i.hideTimer(); + "step 4"; + if (_status.connectMode) { + for (var i of [player, target]) i.hideTimer(); } - var lose_list=[]; - var draw_list=[]; - event.results.sort((a,b)=>lib.sort.seat(a[0],b[0])); - for(var res of event.results){ - var target=res[0],cardsx=res[1]; - if(!target||!cardsx) continue; - if(typeof cardsx==='number') draw_list.push([target,cardsx]); - else if(cardsx.length) lose_list.push([target,cardsx]); + var lose_list = []; + var draw_list = []; + event.results.sort((a, b) => lib.sort.seat(a[0], b[0])); + for (var res of event.results) { + var target = res[0], + cardsx = res[1]; + if (!target || !cardsx) continue; + if (typeof cardsx === "number") draw_list.push([target, cardsx]); + else if (cardsx.length) lose_list.push([target, cardsx]); } - if(lose_list.length){ + if (lose_list.length) { game.loseAsync({ - lose_list:lose_list, - }).setContent('discardMultiple'); + lose_list: lose_list, + }).setContent("discardMultiple"); } - if(draw_list.length){ - for(var list of draw_list){ - var target=list[0],num=list[1]; - target.draw(num,'nodelay'); + if (draw_list.length) { + for (var list of draw_list) { + var target = list[0], + num = list[1]; + target.draw(num, "nodelay"); } } - 'step 5' + "step 5"; game.delay(); - var num1=player.countCards('h'),num2=target.countCards('h'); - if(num1==num2){ + var num1 = player.countCards("h"), + num2 = target.countCards("h"); + if (num1 == num2) { event.finish(); return; } - var players=[player,target]; - if(num2=2){ - var cards=player.getCards('h',card=>{ - return lib.filter.cardDiscardable(card,player,'olzhenying'); - }); - if(cards.length{ - return lib.filter.cardDiscardable(card,player,'olzhenying'); + contentx: function () { + "step 0"; + var player = game.me; + event.player = player; + var num = player.countCards("h"); + if (num >= 2) { + var cards = player.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, player, "olzhenying"); }); + if (cards.length < num - 2) event._result = { cards: cards }; + else + player.chooseCard( + "镇荧:请将手牌弃置至至多两张", + [num - 2, num], + true, + (card, player, target) => { + return lib.filter.cardDiscardable(card, player, "olzhenying"); + } + ); event.goto(2); + } else { + var choices = ["零", "一", "二"]; + player + .chooseControl(choices) + .set("prompt", "镇荧:请选择要将手牌调整至的张数") + .set("ai", () => { + return [0, 1, 2].randomGet(); + }); } - else{ - var choices=['零','一','二']; - player.chooseControl(choices).set('prompt','镇荧:请选择要将手牌调整至的张数').set('ai',()=>{ - return [0,1,2].randomGet(); + "step 1"; + var num = result.index; + var len = player.countCards("h"); + if (len > num) { + var cards = player.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, player, "olzhenying"); }); + if (num == 0 || cards.length < len - num) { + event._result = { cards: cards }; + } else + player.chooseCard( + "镇荧:请将手牌弃置至" + get.cnNumber(num) + "张", + len - num, + true, + (card, player, target) => { + return lib.filter.cardDiscardable(card, player, "olzhenying"); + } + ); + } else event._result = { cards: num - len }; + "step 2"; + if (result && result.cards) { + var cards = result.cards; } - 'step 1' - var num=result.index; - var len=player.countCards('h'); - if(len>num){ - var cards=player.getCards('h',card=>{ - return lib.filter.cardDiscardable(card,player,'olzhenying'); - }); - if(num==0||cards.length{ - return lib.filter.cardDiscardable(card,player,'olzhenying'); - }); - } - else event._result={cards:num-len}; - 'step 2' - if(result&&result.cards){ - var cards=result.cards; - } - event.result=cards; + event.result = cards; }, - ai:{ - order:function(item,player){ - if(game.hasPlayer(current=>{ - return current.countCards('h') { + return current.countCards("h") < player.countCards("h"); + }) + ) + return 3; return 7; }, - result:{ - player:function(player,target){ - var delt=2-player.countCards('h'); - return Math.sqrt(Math.abs(delt))*Math.sign(delt)+0.1; + result: { + player: function (player, target) { + var delt = 2 - player.countCards("h"); + return Math.sqrt(Math.abs(delt)) * Math.sign(delt) + 0.1; }, - target:function(player,target){ - if(get.attitude(player,target)>0&&target.countCards('h')+player.countCards('h')<=3) return 1; - return get.sgn(get.effect(target,{name:'juedou'},player,target))*1.2; - } - } + target: function (player, target) { + if ( + get.attitude(player, target) > 0 && + target.countCards("h") + player.countCards("h") <= 3 + ) + return 1; + return get.sgn(get.effect(target, { name: "juedou" }, player, target)) * 1.2; + }, + }, }, }, //OL孟达 - olgoude:{ - audio:2, - trigger:{ - global:'phaseEnd', + olgoude: { + audio: 2, + trigger: { + global: "phaseEnd", }, - filter:function(event,player){ - var list=[]; - game.countPlayer(current=>{ - if(current.group!=player.group) return false; - var listx=lib.skill.olgoude.getActed(current); + filter: function (event, player) { + var list = []; + game.countPlayer((current) => { + if (current.group != player.group) return false; + var listx = lib.skill.olgoude.getActed(current); list.addArray(listx); }); - return list.length&&list.length<4; + return list.length && list.length < 4; }, - getActed:function(target){ - var list=[]; - if(target.hasHistory('gain',evt=>{ - return evt.getParent().name=='draw'&&evt.cards.length==1; - })){ + getActed: function (target) { + var list = []; + if ( + target.hasHistory("gain", (evt) => { + return evt.getParent().name == "draw" && evt.cards.length == 1; + }) + ) { list.push(1); } - if(game.hasPlayer2(current=>{ - return current.hasHistory('lose',evt=>{ - if(evt.type!='discard') return false; - if((evt.discarder||evt.getParent(2).player)!=target) return false; - var evtx=evt.getl(current); - if(!evtx||evtx.hs.length!=1) return false; - return true; - }); - })){ + if ( + game.hasPlayer2((current) => { + return current.hasHistory("lose", (evt) => { + if (evt.type != "discard") return false; + if ((evt.discarder || evt.getParent(2).player) != target) return false; + var evtx = evt.getl(current); + if (!evtx || evtx.hs.length != 1) return false; + return true; + }); + }) + ) { list.push(2); } - if(target.hasHistory('useCard',evt=>{ - if(evt.card.name=='sha'&&evt.cards&&!evt.cards.length) return true; - return false; - })){ + if ( + target.hasHistory("useCard", (evt) => { + if (evt.card.name == "sha" && evt.cards && !evt.cards.length) return true; + return false; + }) + ) { list.push(3); } - if(target.hasHistory('custom',evt=>{ - return evt.name=='changeGroup'; - })){ + if ( + target.hasHistory("custom", (evt) => { + return evt.name == "changeGroup"; + }) + ) { list.push(4); } return list; }, - direct:true, - content:function(){ - 'step 0' - var list=[1,2,3,4]; - game.countPlayer(current=>{ - if(current.group!=player.group) return false; - var listx=lib.skill.olgoude.getActed(current); + direct: true, + content: function () { + "step 0"; + var list = [1, 2, 3, 4]; + game.countPlayer((current) => { + if (current.group != player.group) return false; + var listx = lib.skill.olgoude.getActed(current); list.removeArray(listx); }); - var list2=list.slice(); - var nochai=false,nosha=false; - if(!game.hasPlayer(current=>{ - return current.countDiscardableCards(player,'h'); - })){ - nochai=true; + var list2 = list.slice(); + var nochai = false, + nosha = false; + if ( + !game.hasPlayer((current) => { + return current.countDiscardableCards(player, "h"); + }) + ) { + nochai = true; list2.remove(2); } - if(!game.hasPlayer(current=>{ - return player.canUse({name:'sha',isCard:true},current,true,false); - })){ - nosha=true; + if ( + !game.hasPlayer((current) => { + return player.canUse({ name: "sha", isCard: true }, current, true, false); + }) + ) { + nosha = true; list2.remove(3); } - var choices=list2.map(i=>{ - return '选项'+get.cnNumber(i,true); + var choices = list2.map((i) => { + return "选项" + get.cnNumber(i, true); }); - var choiceList=[ - '摸一张牌', - '弃置一名角色的一张手牌', - '视为使用一张【杀】', - '将势力改为任意一个势力' - ].map((text,ind)=>{ - var hint=''; - if(list2.includes(ind+1)){ + var choiceList = [ + "摸一张牌", + "弃置一名角色的一张手牌", + "视为使用一张【杀】", + "将势力改为任意一个势力", + ].map((text, ind) => { + var hint = ""; + if (list2.includes(ind + 1)) { return text; + } else if (!list.includes(ind + 1)) { + hint += "已被执行过且"; } - else if(!list.includes(ind+1)){ - hint+='已被执行过且'; - } - if(ind==1&&nochai&&!list2.includes(ind+1)) hint+='无有手牌角色且'; - if(ind==2&&nosha&&!list2.includes(ind+1)) hint+='无可选目标且'; - hint=hint.slice(0,-1); - return ''+text+'('+hint+')'; + if (ind == 1 && nochai && !list2.includes(ind + 1)) hint += "无有手牌角色且"; + if (ind == 2 && nosha && !list2.includes(ind + 1)) hint += "无可选目标且"; + hint = hint.slice(0, -1); + return '' + text + "(" + hint + ")"; }); - choices.push('cancel2'); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseControl(choices).set('choiceList',choiceList).set('prompt',get.prompt('olgoude')).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var fn=function(control){ - switch(control){ - case '选项一': - return player.getUseValue({name:'draw'}); - case '选项二': - return Math.max.apply(Math,game.filterPlayer().map(current=>{ - if(current.hasSkillTag('noh')) return -1; - return -1.5*get.attitude(player,current)-Math.max(0,current.countCards('h')-2)/3; - })); - case '选项三': - return player.getUseValue({name:'sha'}); - case '选项四': - var myPopulation=game.countPlayer(current=>{ - return current.group==player.group; - })-1; - var value=Math.max.apply(Math,lib.group.map(group=>{ - return game.countPlayer(current=>{ - return current.group==group&¤t!=player; - })-myPopulation; - })); - return 10*value+0.1*(Math.random()-0.5); - case 'cancel2': - return 0; - } - } - var choicesx=choices.map(choice=>{ - return [choice,fn(choice)]; + choices.push("cancel2"); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - choicesx=choicesx.sort((a,b)=>{ - return b[1]-a[1]; - }); - var choice=choicesx[0]; - if(choice[1]<0) return 'cancel2'; - return choice[0]; - }()); - 'step 1' - if(result.control=='cancel2'){ + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", get.prompt("olgoude")) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var fn = function (control) { + switch (control) { + case "选项一": + return player.getUseValue({ name: "draw" }); + case "选项二": + return Math.max.apply( + Math, + game.filterPlayer().map((current) => { + if (current.hasSkillTag("noh")) return -1; + return ( + -1.5 * get.attitude(player, current) - + Math.max(0, current.countCards("h") - 2) / 3 + ); + }) + ); + case "选项三": + return player.getUseValue({ name: "sha" }); + case "选项四": + var myPopulation = + game.countPlayer((current) => { + return current.group == player.group; + }) - 1; + var value = Math.max.apply( + Math, + lib.group.map((group) => { + return ( + game.countPlayer((current) => { + return ( + current.group == group && current != player + ); + }) - myPopulation + ); + }) + ); + return 10 * value + 0.1 * (Math.random() - 0.5); + case "cancel2": + return 0; + } + }; + var choicesx = choices.map((choice) => { + return [choice, fn(choice)]; + }); + choicesx = choicesx.sort((a, b) => { + return b[1] - a[1]; + }); + var choice = choicesx[0]; + if (choice[1] < 0) return "cancel2"; + return choice[0]; + })() + ); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - var contents={ - 选项一:function(){ - player.logSkill('olgoude'); + var contents = { + 选项一: function () { + player.logSkill("olgoude"); player.draw(); }, - 选项二:function(){ - 'step 0' - player.chooseTarget('苟得:弃置一名角色的一张手牌',true,(card,player,target)=>{ - return target.countDiscardableCards(player,'h'); - }).set('ai',target=>{ - if(target.hasSkillTag('noh')) return 0; - return -get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - player.logSkill('olgoude',target); - player.discardPlayerCard(target,true,'h'); + 选项二: function () { + "step 0"; + player + .chooseTarget( + "苟得:弃置一名角色的一张手牌", + true, + (card, player, target) => { + return target.countDiscardableCards(player, "h"); + } + ) + .set("ai", (target) => { + if (target.hasSkillTag("noh")) return 0; + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + player.logSkill("olgoude", target); + player.discardPlayerCard(target, true, "h"); } }, - 选项三:function(){ - player.chooseUseTarget('sha',true,false).set('logSkill','olgoude').set('prompt','苟得:选择【杀】的目标'); + 选项三: function () { + player + .chooseUseTarget("sha", true, false) + .set("logSkill", "olgoude") + .set("prompt", "苟得:选择【杀】的目标"); }, - 选项四:function(){ - 'step 0' - var list=lib.group.slice(); - var maxGroup=list.slice().sort((a,b)=>{ - return game.countPlayer(current=>{ - return current.group==b&¤t!=player; - })-game.countPlayer(current=>{ - return current.group==a&¤t!=player; - }); + 选项四: function () { + "step 0"; + var list = lib.group.slice(); + var maxGroup = list.slice().sort((a, b) => { + return ( + game.countPlayer((current) => { + return current.group == b && current != player; + }) - + game.countPlayer((current) => { + return current.group == a && current != player; + }) + ); })[0]; - player.chooseControl(list).set('prompt','苟得:请选择要变更为的势力').set('ai',()=>{ - return _status.event.choice; - }).set('choice',maxGroup); - 'step 1' - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - var group=result.control; - player.logSkill('olgoude'); + player + .chooseControl(list) + .set("prompt", "苟得:请选择要变更为的势力") + .set("ai", () => { + return _status.event.choice; + }) + .set("choice", maxGroup); + "step 1"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + var group = result.control; + player.logSkill("olgoude"); player.changeGroup(group); - player.popup(group+'2',get.groupnature(group,'raw')); + player.popup(group + "2", get.groupnature(group, "raw")); }, - } - var next=game.createEvent('olgoude_'+result.control); - next.player=player; + }; + var next = game.createEvent("olgoude_" + result.control); + next.player = player; next.setContent(contents[result.control]); }, - ai:{ - threaten:3, - effect:{ - player_use:function(card,player,target){ - if(typeof card=='object'&&card.cards&&card.cards.some(card=>{ - return get.position(card)=='h'; - })&&!get.tag(card,'draw')&&!get.tag(card,'gain')&&!get.tag(card,'discard')&& - player==_status.currentPhase&&player.needsToDiscard()==1&&game.countPlayer(current=>{ - return current.group==player.group&¤t!=player; - })<=1&&lib.group.some(group=>{ - return game.countPlayer(current=>{ - return current.group==group&¤t!=player; - })>2; - })) return 'zeroplayertarget'; + ai: { + threaten: 3, + effect: { + player_use: function (card, player, target) { + if ( + typeof card == "object" && + card.cards && + card.cards.some((card) => { + return get.position(card) == "h"; + }) && + !get.tag(card, "draw") && + !get.tag(card, "gain") && + !get.tag(card, "discard") && + player == _status.currentPhase && + player.needsToDiscard() == 1 && + game.countPlayer((current) => { + return current.group == player.group && current != player; + }) <= 1 && + lib.group.some((group) => { + return ( + game.countPlayer((current) => { + return current.group == group && current != player; + }) > 2 + ); + }) + ) + return "zeroplayertarget"; }, }, }, }, //OL新改王朗 - oljici:{ - audio:'jici', - trigger:{ - player:'compare', - target:'compare', + oljici: { + audio: "jici", + trigger: { + player: "compare", + target: "compare", }, - filter:function(event,player){ - if(event.player==player){ - if(event.iwhile) return false; - return event.num1<=player.countMark('gushe'); + filter: function (event, player) { + if (event.player == player) { + if (event.iwhile) return false; + return event.num1 <= player.countMark("gushe"); } - return event.num2<=player.countMark('gushe'); + return event.num2 <= player.countMark("gushe"); }, - content:function(){ - var num=player.countMark('gushe'); - if(player==trigger.player){ - trigger.num1+=num; - if(trigger.num1>13) trigger.num1=13; + content: function () { + var num = player.countMark("gushe"); + if (player == trigger.player) { + trigger.num1 += num; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += num; + if (trigger.num2 > 13) trigger.num2 = 13; } - else{ - trigger.num2+=num; - if(trigger.num2>13) trigger.num2=13; - } - game.log(player,'的拼点牌点数+'+num); - var stat=player.getStat().skill; + game.log(player, "的拼点牌点数+" + num); + var stat = player.getStat().skill; delete stat.gushe; - } + }, + ai: { + combo: "gushe", + }, }, //OL刘老板 - olpianan:{ - audio:2, - trigger:{ - player:['enterGame','phaseDiscardEnd'], - global:'phaseBefore', + olpianan: { + audio: 2, + trigger: { + player: ["enterGame", "phaseDiscardEnd"], + global: "phaseBefore", }, - forced:true, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var hs=player.getCards('h',card=>{ - return get.name(card)!='shan'&&lib.filter.cardDiscardable(card,player,'olpianan'); + content: function () { + "step 0"; + var hs = player.getCards("h", (card) => { + return ( + get.name(card) != "shan" && lib.filter.cardDiscardable(card, player, "olpianan") + ); }); - if(hs.length) player.discard(hs); - 'step 1' - var num=player.hp-player.countCards('h'); - if(num>0){ - var cards=[]; - for(var i=0;i 0) { + var cards = []; + for (var i = 0; i < ui.cardPile.childNodes.length; i++) { + var card = ui.cardPile.childNodes[i]; + if (card.name == "shan") { cards.add(card); num--; } - if(num==0) break; + if (num == 0) break; } - if(num>0){ - for(var i=0;i 0) { + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var card = ui.discardPile.childNodes[i]; + if (card.name == "shan") { cards.add(card); num--; } - if(num==0) break; + if (num == 0) break; } } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); } }, - mod:{ - aiValue:function(player,card,num){ - if(card.name!='shan') return; - if(player==_status.currentPhase) return 0; + mod: { + aiValue: function (player, card, num) { + if (card.name != "shan") return; + if (player == _status.currentPhase) return 0; }, - aiUseful:function(){ - return lib.skill.olpianan.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.olpianan.mod.aiValue.apply(this, arguments); }, }, }, - olyinji:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ + olyinji: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { return !player.isMaxHp(true); }, - content:function(){ - 'step 0' - player.chooseControl('体力','体力上限').set('prompt','殷积:回复1点体力或加1点体力上限').set('ai',()=>{ - var player=_status.event.player; - if(!player.isDamaged()||player.hp>3&&player.getDamagedHp()==1||player.maxHp<3) return 1; - return 0; - }); - 'step 1' - player[result.index==0?'recover':'gainMaxHp'](); - } + content: function () { + "step 0"; + player + .chooseControl("体力", "体力上限") + .set("prompt", "殷积:回复1点体力或加1点体力上限") + .set("ai", () => { + var player = _status.event.player; + if ( + !player.isDamaged() || + (player.hp > 3 && player.getDamagedHp() == 1) || + player.maxHp < 3 + ) + return 1; + return 0; + }); + "step 1"; + player[result.index == 0 ? "recover" : "gainMaxHp"](); + }, }, - olkuisi:{ - audio:2, - trigger:{player:'phaseDrawBefore'}, - forced:true, - content:function(){ - 'step 0' + olkuisi: { + audio: 2, + trigger: { player: "phaseDrawBefore" }, + forced: true, + content: function () { + "step 0"; trigger.cancel(); - var cards=game.cardsGotoOrdering(get.cards(4)).cards; - event.cards=cards.slice(); - 'step 1' - player.chooseButton(['窥伺:是否使用其中的一张牌?',cards]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link); - }).set('ai',button=>{ - var player=_status.event.player,card=button.link,cards=_status.event.getParent().cards; - var val=player.getUseValue(card)+0.01; - if(val>0&&cards.length>1||val>4&&cards.length==1&&(player.maxHp>3||player.isDamaged())) return get.order(card)+val/5; - return 0; - }); - 'step 2' - if(result.bool){ - var card=result.links[0]; + var cards = game.cardsGotoOrdering(get.cards(4)).cards; + event.cards = cards.slice(); + "step 1"; + player + .chooseButton(["窥伺:是否使用其中的一张牌?", cards]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link); + }) + .set("ai", (button) => { + var player = _status.event.player, + card = button.link, + cards = _status.event.getParent().cards; + var val = player.getUseValue(card) + 0.01; + if ( + (val > 0 && cards.length > 1) || + (val > 4 && cards.length == 1 && (player.maxHp > 3 || player.isDamaged())) + ) + return get.order(card) + val / 5; + return 0; + }); + "step 2"; + if (result.bool) { + var card = result.links[0]; event.cards.remove(card); - player.$gain2(card,false); + player.$gain2(card, false); game.delayx(); - player.chooseUseTarget(true,card,false); - } - else event.goto(4); - 'step 3' - if(cards.some(i=>get.position(i,true)=='o'&&player.hasUseTarget(i))) event.goto(1); - 'step 4' - if(cards.length!=1&&cards.length!=2){ + player.chooseUseTarget(true, card, false); + } else event.goto(4); + "step 3"; + if (cards.some((i) => get.position(i, true) == "o" && player.hasUseTarget(i))) + event.goto(1); + "step 4"; + if (cards.length != 1 && cards.length != 2) { player.loseMaxHp(); } - } + }, }, //卢氏 - olzhuyan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - init:function(player){ - player.addSkill('olzhuyan_record'); + olzhuyan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + init: function (player) { + player.addSkill("olzhuyan_record"); }, - onremove:['olzhuyan_true','olzhuyan_false'], - direct:true, - filter:function(event,player){ - for(var bool of [true,false]){ - var targeted=player.getStorage('olzhuyan_'+bool); - if(game.hasPlayer(current=>{ - return !targeted.includes(current)&&lib.skill.olzhuyan.getNum(current,bool); - })) return true; + onremove: ["olzhuyan_true", "olzhuyan_false"], + direct: true, + filter: function (event, player) { + for (var bool of [true, false]) { + var targeted = player.getStorage("olzhuyan_" + bool); + if ( + game.hasPlayer((current) => { + return ( + !targeted.includes(current) && lib.skill.olzhuyan.getNum(current, bool) + ); + }) + ) + return true; } return false; }, - getNum:function(player,status){ - if(!_status.olzhuyan||!_status.olzhuyan[player.playerid]) return 0; - var num=_status.olzhuyan[player.playerid][status?1:0]; - if(status){ - num-=player.countCards('h'); - if(num+player.countCards('h')>5) num=5-player.countCards('h'); - } - else{ - num-=player.hp; - if(num+player.hp<1) num=1-player.hp; + getNum: function (player, status) { + if (!_status.olzhuyan || !_status.olzhuyan[player.playerid]) return 0; + var num = _status.olzhuyan[player.playerid][status ? 1 : 0]; + if (status) { + num -= player.countCards("h"); + if (num + player.countCards("h") > 5) num = 5 - player.countCards("h"); + } else { + num -= player.hp; + if (num + player.hp < 1) num = 1 - player.hp; } return num; }, - content:function(){ - 'step 0' - var map={}; - for(var bool of [true,false]){ - var targeted=player.getStorage('olzhuyan_'+bool); - game.countPlayer(current=>{ - if(targeted.includes(current)) return false; - if(!map[current.playerid]) map[current.playerid]=[]; - map[current.playerid][bool?1:0]=lib.skill.olzhuyan.getNum(current,bool); + content: function () { + "step 0"; + var map = {}; + for (var bool of [true, false]) { + var targeted = player.getStorage("olzhuyan_" + bool); + game.countPlayer((current) => { + if (targeted.includes(current)) return false; + if (!map[current.playerid]) map[current.playerid] = []; + map[current.playerid][bool ? 1 : 0] = lib.skill.olzhuyan.getNum(current, bool); }); } - event.map=map; - player.chooseTarget(get.prompt('olzhuyan'),'令一名角色将{体力值/手牌数}调整至与其上个准备阶段相同(“--”表示已对其发动过该分支)',(card,player,target)=>{ - var list=_status.event.map[target.playerid]; - return list&&(list[0]||list[1]); - }).set('map',map).set('targetprompt',target=>{ - var list=_status.event.map[target.playerid]; - var str=''; - for(var i=0;i<2;i++){ - if(list[i]===undefined) str+='--'; - else{ - str+=(list[i]>0?'+':'')+list[i]; + event.map = map; + player + .chooseTarget( + get.prompt("olzhuyan"), + "令一名角色将{体力值/手牌数}调整至与其上个准备阶段相同(“--”表示已对其发动过该分支)", + (card, player, target) => { + var list = _status.event.map[target.playerid]; + return list && (list[0] || list[1]); } - str+='/'; - } - return str.slice(0,-1); - }).set('ai',target=>{ - var list=_status.event.map[target.playerid]; - var att=get.attitude(_status.event.player,target); - var v1=list[0],v2=get.sgn(list[1])*Math.sqrt(Math.abs(list[1])); - return Math[att>0?'max':'min'](v1,v2)*att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('olzhuyan',target); - event.target=target; - var list=event.map[target.playerid]; - var choices=['体力值','手牌数']; - if(list[0]&&list[1]){ - player.chooseControl(choices).set('choiceList',[ - '令'+get.translation(target)+(list[0]>0?'回复':'失去')+Math.abs(list[0])+'点体力'+(list[0]<0?'(至多失去至1)':''), - '令'+get.translation(target)+(list[1]>0?'摸':'弃置')+get.cnNumber(Math.abs(list[1]))+'张'+(list[1]>0?'':'手')+'牌'+(list[1]>0?'(至多摸至5)':''), - ]).set('prompt','驻颜:请选择一项').set('ai',()=>_status.event.choice).set('choice',function(){ - var v1=list[0],v2=get.sgn(list[1])*Math.sqrt(Math.abs(list[1])); - if(get.attitude(player,target)>0){ - return v1>v2?0:1; + ) + .set("map", map) + .set("targetprompt", (target) => { + var list = _status.event.map[target.playerid]; + var str = ""; + for (var i = 0; i < 2; i++) { + if (list[i] === undefined) str += "--"; + else { + str += (list[i] > 0 ? "+" : "") + list[i]; } - return v1>v2?1:0; - }()); + str += "/"; + } + return str.slice(0, -1); + }) + .set("ai", (target) => { + var list = _status.event.map[target.playerid]; + var att = get.attitude(_status.event.player, target); + var v1 = list[0], + v2 = get.sgn(list[1]) * Math.sqrt(Math.abs(list[1])); + return Math[att > 0 ? "max" : "min"](v1, v2) * att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("olzhuyan", target); + event.target = target; + var list = event.map[target.playerid]; + var choices = ["体力值", "手牌数"]; + if (list[0] && list[1]) { + player + .chooseControl(choices) + .set("choiceList", [ + "令" + + get.translation(target) + + (list[0] > 0 ? "回复" : "失去") + + Math.abs(list[0]) + + "点体力" + + (list[0] < 0 ? "(至多失去至1)" : ""), + "令" + + get.translation(target) + + (list[1] > 0 ? "摸" : "弃置") + + get.cnNumber(Math.abs(list[1])) + + "张" + + (list[1] > 0 ? "" : "手") + + "牌" + + (list[1] > 0 ? "(至多摸至5)" : ""), + ]) + .set("prompt", "驻颜:请选择一项") + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + var v1 = list[0], + v2 = get.sgn(list[1]) * Math.sqrt(Math.abs(list[1])); + if (get.attitude(player, target) > 0) { + return v1 > v2 ? 0 : 1; + } + return v1 > v2 ? 1 : 0; + })() + ); + } else { + event._result = { index: list[0] ? 0 : 1 }; } - else{ - event._result={index:list[0]?0:1}; - } - } - else event.finish(); - 'step 2' - var ind=result.index; - player.markAuto('olzhuyan_'+Boolean(ind),[target]); - var num=event.map[target.playerid][ind]; - if(ind==0){ - if(num>0){ + } else event.finish(); + "step 2"; + var ind = result.index; + player.markAuto("olzhuyan_" + Boolean(ind), [target]); + var num = event.map[target.playerid][ind]; + if (ind == 0) { + if (num > 0) { target.recover(num); - } - else{ - num=Math.min(target.hp-1,-num); + } else { + num = Math.min(target.hp - 1, -num); target.loseHp(num); } - } - else{ - if(num>0){ - num=Math.min(5-target.countCards('h'),num); - if(num>0) target.draw(num); - } - else{ - num=-num; - target.chooseToDiscard(num,true).set('prompt','驻颜:请弃置'+get.cnNumber(Math.abs(num))+'张手牌'); + } else { + if (num > 0) { + num = Math.min(5 - target.countCards("h"), num); + if (num > 0) target.draw(num); + } else { + num = -num; + target + .chooseToDiscard(num, true) + .set("prompt", "驻颜:请弃置" + get.cnNumber(Math.abs(num)) + "张手牌"); } } }, - subSkill:{ - record:{ - trigger:{ - global:['phaseZhunbeiAfter','phaseBefore','enterGame'], + subSkill: { + record: { + trigger: { + global: ["phaseJieshuAfter", "phaseBefore", "enterGame"], }, - lastDo:true, - charlotte:true, - forced:true, - popup:false, - forceDie:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + lastDo: true, + charlotte: true, + forced: true, + popup: false, + forceDie: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - if(!_status.olzhuyan) _status.olzhuyan={}; - if(event.triggername=='phaseBefore'){ - game.countPlayer(current=>{ - _status.olzhuyan[current.playerid]=[current.hp,current.countCards('h')]; - }) - } - else{ - _status.olzhuyan[trigger.player.playerid]=[trigger.player.hp,trigger.player.countCards('h')]; + content: function () { + if (!_status.olzhuyan) _status.olzhuyan = {}; + if (event.triggername == "phaseBefore") { + game.countPlayer((current) => { + _status.olzhuyan[current.playerid] = [ + current.hp, + current.countCards("h"), + ]; + }); + } else { + _status.olzhuyan[trigger.player.playerid] = [ + trigger.player.hp, + trigger.player.countCards("h"), + ]; } }, - } - } + }, + }, }, - olleijie:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olleijie'),'令一名角色判定。若结果为♠2~9,其受到2点雷电伤害,否则其摸两张牌。').set('ai',target=>{ - var player=_status.event.player,sgn=_status.event.sgn; - if(sgn>0){ - return get.damageEffect(target,target,player,'thunder'); - } - else if(sgn==0){ - return get.attitude(player,target); - } - return 0; - }).set('sgn',function(){ - var sgn=0; - game.countPlayer(current=>{ - if(!current.hasSkillTag('rejudge')) return; - sgn=get.sgnAttitude(player,current); - }); - return sgn; - }()) - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olleijie',target); - target.judge(card=>{ - var number=get.number(card); - if(get.suit(card)=='spade'&&number>=2&&number<=9) return -4; - return 2; - }).set('judge2',result=>{ - return result.bool===false?true:false; - }); - } - else event.finish(); - 'step 2' - if(result.bool){ + olleijie: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olleijie"), + "令一名角色判定。若结果为♠2~9,其受到2点雷电伤害,否则其摸两张牌。" + ) + .set("ai", (target) => { + var player = _status.event.player, + sgn = _status.event.sgn; + if (sgn > 0) { + return get.damageEffect(target, target, player, "thunder"); + } else if (sgn == 0) { + return get.attitude(player, target); + } + return 0; + }) + .set( + "sgn", + (function () { + var sgn = 0; + game.countPlayer((current) => { + if (!current.hasSkillTag("rejudge")) return; + sgn = get.sgnAttitude(player, current); + }); + return sgn; + })() + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olleijie", target); + target + .judge((card) => { + var number = get.number(card); + if (get.suit(card) == "spade" && number >= 2 && number <= 9) return -4; + return 2; + }) + .set("judge2", (result) => { + return result.bool === false ? true : false; + }); + } else event.finish(); + "step 2"; + if (result.bool) { target.draw(2); + } else { + target.damage(2, "thunder"); } - else{ - target.damage(2,'thunder'); + }, + }, + releijie: { + audio: "olleijie", + enable: "phaseUse", + filterTarget: true, + usable: 1, + async content(event, trigger, player) { + const target = event.target, + result = await target + .judge((card) => { + var number = get.number(card); + if (get.suit(card) == "spade" && number >= 2 && number <= 9) return -4; + return 2; + }) + .set("judge2", (result) => { + return result.bool === false ? true : false; + }) + .forResult(); + if (result.bool) await target.draw(2); + else { + const card = new lib.element.VCard({ name: "sha", nature: "thunder" }); + if (player.canUse(card, target, false)) { + for (let i = 1; i <= 2; i++) { + await player.useCard(card, target, false); + } + } } - } + }, + ai: { + order: 1, + result: { + target(player, target) { + let sgn = 0, + eff = 0, + num = get.attitude(player, target); + const card = new lib.element.VCard({ name: "sha", nature: "thunder" }); + game.countPlayer((current) => { + if (!current.hasSkillTag("rejudge")) return; + sgn = get.sgnAttitude(player, current); + }); + if (sgn > 0 && player.canUse(card, target, false)) { + eff += get.effect(target, card, player, player) * 2; + return eff * get.sgn(num); + } else if (sgn == 0) return num * get.sgn(num); + return 0; + }, + }, + }, }, //张世平 - olhongji:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(event.player.isMinHandcard()&&!player.hasSkill('olhongji_min')) return true; - if(event.player.isMaxHandcard()&&!player.hasSkill('olhongji_max')) return true; + olhongji: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (event.player.isMinHandcard() && !player.hasSkill("olhongji_min")) return true; + if (event.player.isMaxHandcard() && !player.hasSkill("olhongji_max")) return true; return false; }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - var bool1=target.isMinHandcard()&&!player.hasSkill('olhongji_min'),str1='其手牌数为全场最少。你可以令其于本回合摸牌阶段结束后执行一个额外的摸牌阶段,然后本轮你不能再发动该分支。'; - var bool2=target.isMaxHandcard()&&!player.hasSkill('olhongji_max'),str2='其手牌数为全场最多。你可以令其于本回合出牌阶段结束后执行一个额外的出牌阶段,然后本轮你不能再发动该分支。'; - if(bool1&&!bool2){ - event.branch=0; - player.chooseBool(get.prompt('olhongji',target),str1).set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.attitude(player,trigger.player)>1); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + var bool1 = target.isMinHandcard() && !player.hasSkill("olhongji_min"), + str1 = + "其手牌数为全场最少。你可以令其于本回合摸牌阶段结束后执行一个额外的摸牌阶段,然后本轮你不能再发动该分支。"; + var bool2 = target.isMaxHandcard() && !player.hasSkill("olhongji_max"), + str2 = + "其手牌数为全场最多。你可以令其于本回合出牌阶段结束后执行一个额外的出牌阶段,然后本轮你不能再发动该分支。"; + if (bool1 && !bool2) { + event.branch = 0; + player + .chooseBool(get.prompt("olhongji", target), str1) + .set("ai", () => { + return _status.event.bool; + }) + .set("bool", get.attitude(player, trigger.player) > 1); + } else if (!bool1 && bool2) { + event.branch = 1; + player + .chooseBool(get.prompt("olhongji", target), str2) + .set("ai", () => { + return _status.event.bool; + }) + .set("bool", get.attitude(player, trigger.player) > 1); + } else if (bool1 && bool2) { + player + .chooseControl("摸牌阶段", "出牌阶段", "cancel2") + .set("prompt", get.prompt("olhongji", target)) + .set("choiceList", [str1.slice(13), str2.slice(13)]) + .set("ai", () => _status.event.bool) + .set("bool", () => + get.attitude(player, trigger.player) > 1 ? [0, 1].randomGet() : "cancel2" + ); } - else if(!bool1&&bool2){ - event.branch=1; - player.chooseBool(get.prompt('olhongji',target),str2).set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.attitude(player,trigger.player)>1); - } - else if(bool1&&bool2){ - player.chooseControl('摸牌阶段','出牌阶段','cancel2').set('prompt',get.prompt('olhongji',target)).set('choiceList',[ - str1.slice(13), - str2.slice(13) - ]).set('ai',()=>_status.event.bool).set('bool',()=>get.attitude(player,trigger.player)>1?[0,1].randomGet():'cancel2'); - } - 'step 1' - var choice=-1; - if(event.branch==0&&result.bool||result.control=='摸牌阶段') choice=0; - if(event.branch==1&&result.bool||result.control=='出牌阶段') choice=1; - if(choice==0){ - player.logSkill('olhongji',target); - player.addTempSkill('olhongji_min','roundStart'); - target.addTempSkill('olhongji_draw'); - } - else if(choice==1){ - player.logSkill('olhongji',target); - player.addTempSkill('olhongji_max','roundStart'); - target.addTempSkill('olhongji_use'); + "step 1"; + var choice = -1; + if ((event.branch == 0 && result.bool) || result.control == "摸牌阶段") choice = 0; + if ((event.branch == 1 && result.bool) || result.control == "出牌阶段") choice = 1; + if (choice == 0) { + player.logSkill("olhongji", target); + player.addTempSkill("olhongji_min", "roundStart"); + target.addTempSkill("olhongji_draw"); + } else if (choice == 1) { + player.logSkill("olhongji", target); + player.addTempSkill("olhongji_max", "roundStart"); + target.addTempSkill("olhongji_use"); } }, - ai:{expose:0.25}, - subSkill:{ - min:{charlotte:true}, - max:{charlotte:true}, - draw:{ - trigger:{player:'phaseDrawAfter'}, - charlotte:true, - forced:true, - popup:false, - content:function(){ - var next=trigger.player.phaseDraw(); + ai: { expose: 0.25 }, + subSkill: { + min: { charlotte: true }, + max: { charlotte: true }, + draw: { + trigger: { player: "phaseDrawAfter" }, + charlotte: true, + forced: true, + popup: false, + content: function () { + var next = trigger.player.phaseDraw(); event.next.remove(next); - trigger.getParent('phase').next.push(next); - player.removeSkill('olhongji_draw'); - } + trigger.getParent("phase").next.push(next); + player.removeSkill("olhongji_draw"); + }, }, - use:{ - trigger:{player:'phaseUseAfter'}, - charlotte:true, - forced:true, - popup:false, - content:function(){ - var next=trigger.player.phaseUse(); + use: { + trigger: { player: "phaseUseAfter" }, + charlotte: true, + forced: true, + popup: false, + content: function () { + var next = trigger.player.phaseUse(); event.next.remove(next); - trigger.getParent('phase').next.push(next); - player.removeSkill('olhongji_use'); - } - } - } + trigger.getParent("phase").next.push(next); + player.removeSkill("olhongji_use"); + }, + }, + }, }, - olxinggu:{ - audio:2, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + olxinggu: { + audio: 2, + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'olxinggu_trade', - content:function(){ - 'step 0' - var cards=[]; - for(var i=0;i<3;i++){ - var card=get.cardPile2(function(card){ - if(cards.includes(card)) return false; - var type=get.subtype(card); - return type=='equip3'||type=='equip4'||type=='equip6'; + group: "olxinggu_trade", + content: function () { + "step 0"; + var cards = []; + for (var i = 0; i < 3; i++) { + var card = get.cardPile2(function (card) { + if (cards.includes(card)) return false; + var type = get.subtype(card); + return type == "equip3" || type == "equip4" || type == "equip6"; }); - if(card) cards.add(card); + if (card) cards.add(card); else break; } - if(cards.length) player.addToExpansion(cards,'draw').gaintag.add('olxinggu'); + if (cards.length) player.addToExpansion(cards, "draw").gaintag.add("olxinggu"); }, - marktext:'贾', - intro:{ - markcount:'expansion', - mark:function(dialog,content,player){ - var content=player.getExpansions('olxinggu'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + marktext: "贾", + intro: { + markcount: "expansion", + mark: function (dialog, content, player) { + var content = player.getExpansions("olxinggu"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { dialog.addAuto(content); - } - else{ - return '剩余'+get.cnNumber(content.length)+'匹马'; + } else { + return "剩余" + get.cnNumber(content.length) + "匹马"; } } - } + }, }, - subSkill:{ - trade:{ - audio:'olxinggu', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getExpansions('olxinggu').length; + subSkill: { + trade: { + audio: "olxinggu", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.getExpansions("olxinggu").length; }, - direct:true, - content:function(){ - 'step 0' - var cards=player.getExpansions('olxinggu'); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseButton([get.prompt('olxinggu'),cards]).set('ai',button=>{ - if(_status.event.toChoose==button.link) return 1; - return 0; - }).set('toChoose',!event.aiCancel&&cards.find(card=>{ - return game.hasPlayer(current=>{ - if(!lib.skill.zhijian.filterTarget(card,player,current)) return false; - return get.effect(current,card,player,player)>0; + direct: true, + content: function () { + "step 0"; + var cards = player.getExpansions("olxinggu"); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - })); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('将'+get.translation(card)+'置入一名其他角色的装备区',lib.skill.zhijian.filterTarget).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }).set('card',card); - } - else{ - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} + player + .chooseButton([get.prompt("olxinggu"), cards]) + .set("ai", (button) => { + if (_status.event.toChoose == button.link) return 1; + return 0; + }) + .set( + "toChoose", + !event.aiCancel && + cards.find((card) => { + return game.hasPlayer((current) => { + if (!lib.skill.zhijian.filterTarget(card, player, current)) + return false; + return get.effect(current, card, player, player) > 0; + }); + }) + ); + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + "将" + get.translation(card) + "置入一名其他角色的装备区", + lib.skill.zhijian.filterTarget + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }) + .set("card", card); + } else { + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } event.finish(); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - player.logSkill('olxinggu',target); - player.$give(card,target,false); - } - else{ - if(!event.isMine()&&!event.isOnline()) event.aiCancel=true; + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + player.logSkill("olxinggu", target); + player.$give(card, target, false); + } else { + if (!event.isMine() && !event.isOnline()) event.aiCancel = true; event.goto(0); } - 'step 3' + "step 3"; target.equip(card); - 'step 4' - var card=get.cardPile2(cardx=>{ - return get.suit(cardx)=='diamond'; + "step 4"; + var card = get.cardPile2((cardx) => { + return get.suit(cardx) == "diamond"; }); - if(card) player.gain(card,'gain2'); - else{ - game.log('但是牌堆中并没有♦牌了!'); - player.chat('做了个亏本买卖…'); + if (card) player.gain(card, "gain2"); + else { + game.log("但是牌堆中并没有♦牌了!"); + player.chat("做了个亏本买卖…"); } - } - } - } + }, + }, + }, }, //孙弘 - olxianbi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return !player.getStorage('olzenrun').includes(target)&&target.countCards('e')!=player.countCards('h'); + olxianbi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return ( + !player.getStorage("olzenrun").includes(target) && + target.countCards("e") != player.countCards("h") + ); }, - content:function(){ - 'step 0' - var del=target.countCards('e')-player.countCards('h'); - if(del==0) event.finish(); - else if(del>0){ - player.draw(Math.min(5,del)); - } - else{ - player.chooseToDiscard('险诐:弃置'+get.cnNumber(-del)+'张手牌',-del,'h',true); - player.addTempSkill('olxianbi_gain'); + content: function () { + "step 0"; + var del = target.countCards("e") - player.countCards("h"); + if (del == 0) event.finish(); + else if (del > 0) { + player.draw(Math.min(5, del)); + } else { + player.chooseToDiscard("险诐:弃置" + get.cnNumber(-del) + "张手牌", -del, "h", true); + player.addTempSkill("olxianbi_gain"); } }, - ai:{ - order:5, - result:{ - player:function(player,target){ - return player.countCards('h',card=>{ - return get.value(card)>6; - })>=target.countCards('e')?0:1; - } - } - }, - subSkill:{ - gain:{ - trigger:{ - player:'loseAfter', + ai: { + order: 5, + result: { + player: function (player, target) { + return player.countCards("h", (card) => { + return get.value(card) > 6; + }) >= target.countCards("e") + ? 0 + : 1; }, - filter:function(event,player){ - return event.getParent(3).name=='olxianbi'; + }, + }, + subSkill: { + gain: { + trigger: { + player: "loseAfter", }, - forced:true, - charlotte:true, - popup:false, - content:function(){ - var cards=[],cards2=trigger.cards; - for(var cardx of cards2){ - var type=get.type2(cardx,player); - var card=get.discardPile(function(card){ - return get.type(card,false)==type&&!cards2.includes(card)&&!cards.includes(card); + filter: function (event, player) { + return event.getParent(3).name == "olxianbi"; + }, + forced: true, + charlotte: true, + popup: false, + content: function () { + var cards = [], + cards2 = trigger.cards; + for (var cardx of cards2) { + var type = get.type2(cardx, player); + var card = get.discardPile(function (card) { + return ( + get.type(card, false) == type && + !cards2.includes(card) && + !cards.includes(card) + ); }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); - } - } - } - }, - olzenrun:{ - audio:2, - trigger:{player:'drawBefore'}, - filter:function(event,player){ - return !player.hasSkill('olzenrun_used')&&game.hasPlayer(current=>{ - return !player.getStorage('olzenrun').includes(current)&¤t!=player&¤t.hasCard(function(card){ - return lib.filter.canBeGained(card,player,current); - },'he') - }); + if (cards.length) player.gain(cards, "gain2"); + }, + }, }, - direct:true, - check:function(event,player){ + }, + olzenrun: { + audio: 2, + trigger: { player: "drawBefore" }, + filter: function (event, player) { + return ( + !player.hasSkill("olzenrun_used") && + game.hasPlayer((current) => { + return ( + !player.getStorage("olzenrun").includes(current) && + current != player && + current.hasCard(function (card) { + return lib.filter.canBeGained(card, player, current); + }, "he") + ); + }) + ); + }, + direct: true, + check: function (event, player) { return true; }, - content:function(){ - 'step 0' - var num=trigger.num; - player.chooseTarget(get.prompt('olzenrun'),'改为获得一名其他角色'+get.cnNumber(num)+'张牌',(card,player,target)=>{ - return !player.getStorage('olzenrun').includes(target)&&target!=player&&target.hasCard(function(card){ - return lib.filter.canBeGained(card,player,target); - },'he') - }).set('ai',target=>{ - return get.attitude(_status.event.player,target)/5+Math.random()+2.5; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olzenrun',target); - player.addTempSkill('olzenrun_used',['phaseZhunbeiAfter','phaseJudgeAfter','phaseDrawAfter','phaseUseAfter','phaseDiscardAfter','phaseJieshuAfter']); + content: function () { + "step 0"; + var num = trigger.num; + player + .chooseTarget( + get.prompt("olzenrun"), + "改为获得一名其他角色" + get.cnNumber(num) + "张牌", + (card, player, target) => { + return ( + !player.getStorage("olzenrun").includes(target) && + target != player && + target.hasCard(function (card) { + return lib.filter.canBeGained(card, player, target); + }, "he") + ); + } + ) + .set("ai", (target) => { + return get.attitude(_status.event.player, target) / 5 + Math.random() + 2.5; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olzenrun", target); + player.addTempSkill("olzenrun_used", [ + "phaseZhunbeiAfter", + "phaseJudgeAfter", + "phaseDrawAfter", + "phaseUseAfter", + "phaseDiscardAfter", + "phaseJieshuAfter", + ]); trigger.cancel(); - player.gainPlayerCard(target,trigger.num,'he',true); + player.gainPlayerCard(target, trigger.num, "he", true); } - 'step 2' - if(result.bool){ - var cards=result.cards; - var num=cards.length; - event.num=num; - target.chooseControl().set('choiceList',[ - '摸'+get.cnNumber(num)+'张牌', - '令其不能再对你发动〖险诐〗和〖谮润〗' - ]).set('prompt',get.translation(player)+'对你发动了【谮润】,请选择一项').set('ai',()=>{ - if(_status.event.bool) return 0; - return 1; - }).set('bool',get.attitude(target,player)>0||num==1&&Math.random()<0.5||num>=2); - } - else event.finish(); - 'step 3' - game.log(target,'选择了','#y'+result.control); - if(result.index==0){ + "step 2"; + if (result.bool) { + var cards = result.cards; + var num = cards.length; + event.num = num; + target + .chooseControl() + .set("choiceList", [ + "摸" + get.cnNumber(num) + "张牌", + "令其不能再对你发动〖险诐〗和〖谮润〗", + ]) + .set("prompt", get.translation(player) + "对你发动了【谮润】,请选择一项") + .set("ai", () => { + if (_status.event.bool) return 0; + return 1; + }) + .set( + "bool", + get.attitude(target, player) > 0 || + (num == 1 && Math.random() < 0.5) || + num >= 2 + ); + } else event.finish(); + "step 3"; + game.log(target, "选择了", "#y" + result.control); + if (result.index == 0) { target.draw(num); - } - else{ - player.markAuto('olzenrun',[target]); + } else { + player.markAuto("olzenrun", [target]); } }, - subSkill:{ - used:{ - charlotte:true, - } - } + subSkill: { + used: { + charlotte: true, + }, + }, }, //罗宪 - oldaili:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return player.countCards('h',card=>{ - return card.hasGaintag('oldaili_tag'); - })%2==0; + oldaili: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return ( + player.countCards("h", (card) => { + return card.hasGaintag("oldaili_tag"); + }) % + 2 == + 0 + ); }, - group:'oldaili_record', - locked:false, - check:function(event,player){ - if(get.distance(event.player,player,'absolute')==1&&!player.isTurnedOver()) return false; + group: "oldaili_record", + locked: false, + check: function (event, player) { + if (get.distance(event.player, player, "absolute") == 1 && !player.isTurnedOver()) + return false; return true; }, - content:function(){ + content: function () { player.turnOver(); - player.draw(3,'visible').gaintag=['oldaili_tag']; + player.draw(3, "visible").gaintag = ["oldaili_tag"]; }, - mod:{ - aiValue:function(player,card,num){ - 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'); + mod: { + aiValue: function (player, card, num) { + 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"); }); - if(ui.selected.cards && ui.selected.cards.length) dai += ui.selected.cards.filter((card) => { - return card.hasGaintag('oldaili_tag'); - }).length; - if(dai % 2) return Math.sqrt(num); + if (ui.selected.cards && ui.selected.cards.length) + dai += ui.selected.cards.filter((card) => { + return card.hasGaintag("oldaili_tag"); + }).length; + if (dai % 2) return Math.sqrt(num); return num + 6; }, - aiUseful:function(){ - return lib.skill.oldaili.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.oldaili.mod.aiValue.apply(this, arguments); }, }, - mark:true, - marktext:'砺', - intro:{ - markcount:function(storage,player){ - return player.countCards('h',card=>card.hasGaintag('oldaili_tag')); + mark: true, + marktext: "砺", + intro: { + markcount: function (storage, player) { + return player.countCards("h", (card) => card.hasGaintag("oldaili_tag")); }, - mark:function(dialog,content,player){ - var cards=player.getCards('h',card=>card.hasGaintag('oldaili_tag')); - if(cards.length){ + mark: function (dialog, content, player) { + var cards = player.getCards("h", (card) => card.hasGaintag("oldaili_tag")); + if (cards.length) { dialog.addAuto(cards); - } - else return '无展示牌'; + } else return "无展示牌"; }, }, - subSkill:{ - record:{ - trigger:{global:'showCardsEnd'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.cards.some(i=>get.owner(i)==player); + subSkill: { + record: { + trigger: { global: "showCardsEnd" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return event.cards.some((i) => get.owner(i) == player); + }, + content: function () { + game.broadcastAll( + function (cards) { + cards.forEach((card) => card.addGaintag("oldaili_tag")); + }, + trigger.cards.filter((i) => get.owner(i) == player) + ); + player.markSkill("oldaili"); }, - content:function(){ - game.broadcastAll(function(cards){ - cards.forEach(card=>card.addGaintag('oldaili_tag')); - },trigger.cards.filter(i=>get.owner(i)==player)); - player.markSkill('oldaili'); - } }, - } + }, }, //胡班 - olhuiyun:{ - audio:2, - enable:'phaseUse', - viewAs:{ - name:'huogong', - storage:{olhuiyun:true}, + olhuiyun: { + audio: 2, + enable: "phaseUse", + viewAs: { + name: "huogong", + storage: { olhuiyun: true }, }, - filterCard:true, - position:'hes', - onuse:function(links,player){ - player.addTempSkill('olhuiyun_after'); - player.addTempSkill('olhuiyun_record'); + filterCard: true, + position: "hes", + onuse: function (links, player) { + player.addTempSkill("olhuiyun_after"); + player.addTempSkill("olhuiyun_record"); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(get.attitude(player,target)>0&&card&&card.name=='huogong'&&card.storage&&card.storage.olhuiyun&&!player.hasSkill('olhuiyun_3')) return [0,0.5,0,0.5]; - } - } - }, - subSkill:{ - after:{ - audio:'olhuiyun', - trigger:{global:'useCardAfter'}, - charlotte:true, - forced:true, - direct:true, - filter:function(event,player){ - return event.card.name=='huogong'&&event.card.storage&&event.card.storage.olhuiyun&&event.targets.some(i=>i.isIn()); + ai: { + effect: { + player: function (card, player, target) { + if ( + get.attitude(player, target) > 0 && + card && + card.name == "huogong" && + card.storage && + card.storage.olhuiyun && + !player.hasSkill("olhuiyun_3") + ) + return [0, 0.5, 0, 0.5]; }, - content:function(){ - 'step 0' - var choices=[]; - var choiceList=[ - '使用展示牌,然后重铸所有手牌', - '使用一张手牌,然后重铸展示牌', - '摸一张牌' + }, + }, + subSkill: { + after: { + audio: "olhuiyun", + trigger: { global: "useCardAfter" }, + charlotte: true, + forced: true, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "huogong" && + event.card.storage && + event.card.storage.olhuiyun && + event.targets.some((i) => i.isIn()) + ); + }, + content: function () { + "step 0"; + var choices = []; + var choiceList = [ + "使用展示牌,然后重铸所有手牌", + "使用一张手牌,然后重铸展示牌", + "摸一张牌", ]; - for(var i=1;i<=3;i++){ - if(!player.hasSkill('olhuiyun_'+i)) choices.push('选项'+get.cnNumber(i,true)); - else choiceList[i-1]=''+choiceList[i-1]+''; + for (var i = 1; i <= 3; i++) { + if (!player.hasSkill("olhuiyun_" + i)) + choices.push("选项" + get.cnNumber(i, true)); + else + choiceList[i - 1] = + '' + choiceList[i - 1] + ""; } - if(!choices.length) event.finish(); - else{ - player.logSkill('olhuiyun_after'); - player.chooseControl(choices).set('choiceList',choiceList).set('prompt','晖云:选择一项,令'+get.translation(trigger.targets)+'可以选择执行').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(choices.length==1) return choices[0]; - var choicesx=choices.slice(); - if(get.attitude(player,trigger.targets[0])>0&&choices.includes('选项三')) return '选项三'; - choicesx.remove('选项三'); - return choicesx.randomGet(); - }()); + if (!choices.length) event.finish(); + else { + player.logSkill("olhuiyun_after"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set( + "prompt", + "晖云:选择一项,令" + + get.translation(trigger.targets) + + "可以选择执行" + ) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (choices.length == 1) return choices[0]; + var choicesx = choices.slice(); + if ( + get.attitude(player, trigger.targets[0]) > 0 && + choices.includes("选项三") + ) + return "选项三"; + choicesx.remove("选项三"); + return choicesx.randomGet(); + })() + ); } - 'step 1' - if(result.control!='cancel2'){ - var index=['选项一','选项二','选项三'].indexOf(result.control)+1; - event.index=index; - game.log(player,'选择了','#y'+result.control); - player.addTempSkill('olhuiyun_'+index,'roundStart'); - event.targets=trigger.targets.slice(0); - } - else event.finish(); - 'step 2' - var target=targets.shift(); - event.target=target; - if(target.isIn()){ - var cards=target.getCards('h',card=>card.hasGaintag('olhuiyun_tag')); - if(event.index==3){ - target.chooseBool('是否摸一张牌?').set('ai',()=>true); + "step 1"; + if (result.control != "cancel2") { + var index = ["选项一", "选项二", "选项三"].indexOf(result.control) + 1; + event.index = index; + game.log(player, "选择了", "#y" + result.control); + player.addTempSkill("olhuiyun_" + index, "roundStart"); + event.targets = trigger.targets.slice(0); + } else event.finish(); + "step 2"; + var target = targets.shift(); + event.target = target; + if (target.isIn()) { + var cards = target.getCards("h", (card) => card.hasGaintag("olhuiyun_tag")); + if (event.index == 3) { + target.chooseBool("是否摸一张牌?").set("ai", () => true); event.goto(5); - } - else if(event.index==1&&cards.length){ + } else if (event.index == 1 && cards.length) { target.chooseToUse({ - filterCard:function(card){ - if(get.itemtype(card)!='card'||!card.hasGaintag('olhuiyun_tag')) return false; - return lib.filter.filterCard.apply(this,arguments); + filterCard: function (card) { + if ( + get.itemtype(card) != "card" || + !card.hasGaintag("olhuiyun_tag") + ) + return false; + return lib.filter.filterCard.apply(this, arguments); }, - prompt:'是否使用一张展示牌,然后重铸所有手牌?' + prompt: "是否使用一张展示牌,然后重铸所有手牌?", }); - } - else if(event.index==2){ + } else if (event.index == 2) { target.chooseToUse({ - filterCard:function(card){ - if(get.itemtype(card)!='card'||get.position(card)!='h'&&get.position(card)!='s') return false; - return lib.filter.filterCard.apply(this,arguments); + filterCard: function (card) { + if ( + get.itemtype(card) != "card" || + (get.position(card) != "h" && get.position(card) != "s") + ) + return false; + return lib.filter.filterCard.apply(this, arguments); }, - prompt:'是否使用一张手牌,然后重铸展示牌?' + prompt: "是否使用一张手牌,然后重铸展示牌?", }); event.goto(4); - } - else event.goto(6); - } - else event.goto(6); - 'step 3' - if(result.bool){ - var hs=target.getCards('h',lib.filter.cardRecastable); - if(hs.length){ + } else event.goto(6); + } else event.goto(6); + "step 3"; + if (result.bool) { + var hs = target.getCards("h", lib.filter.cardRecastable); + if (hs.length) { target.recast(hs); } } event.goto(6); - 'step 4' - if(result.bool){ - var hs=target.getCards('h',card=>{ - if(!card.hasGaintag('olhuiyun_tag')) return false; + "step 4"; + if (result.bool) { + var hs = target.getCards("h", (card) => { + if (!card.hasGaintag("olhuiyun_tag")) return false; return target.canRecast(card); }); - if(hs.length){ + if (hs.length) { target.recast(hs); } } event.goto(6); - 'step 5' - if(result.bool){ + "step 5"; + if (result.bool) { target.draw(); } - 'step 6' - if(targets.length) event.goto(2); - } + "step 6"; + if (targets.length) event.goto(2); + }, }, - record:{ - trigger:{global:'showCardsEnd'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(event.getParent().name!='huogong') return false; - var card=event.getParent(2).card; - if(card&&card.storage&&card.storage.olhuiyun) return true; + record: { + trigger: { global: "showCardsEnd" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if (event.getParent().name != "huogong") return false; + var card = event.getParent(2).card; + if (card && card.storage && card.storage.olhuiyun) return true; return false; }, - content:function(){ - game.broadcastAll(function(cards){ - cards.forEach(card=>card.addGaintag('olhuiyun_tag')); - },trigger.cards); - } + content: function () { + game.broadcastAll(function (cards) { + cards.forEach((card) => card.addGaintag("olhuiyun_tag")); + }, trigger.cards); + }, }, - 1:{charlotte:true}, - 2:{charlotte:true}, - 3:{charlotte:true}, - } + 1: { charlotte: true }, + 2: { charlotte: true }, + 3: { charlotte: true }, + }, }, //王瓘 - olmiuyan:{ - audio:2, - enable:'chooseToUse', - viewAsFilter:function(player){ - return !player.hasSkill('olmiuyan_blocker')&&player.hasCard(card=>get.color(card)=='black','hes') + olmiuyan: { + audio: 2, + enable: "chooseToUse", + viewAsFilter: function (player) { + return ( + !player.hasSkill("olmiuyan_blocker") && + player.hasCard((card) => get.color(card) == "black", "hes") + ); }, - viewAs:{name:'huogong'}, - filterCard:{color:'black'}, - position:'hes', - check:function(card){ - var player=_status.event.player,suits=lib.suit.slice(0); - if(player.countCards('h')>4&&player.hasCard(function(card){ - suits.remove(get.suit(card)); - return suits.length==0; - },'h')) return 8-get.value(card); - return 4-get.value(card); + viewAs: { name: "huogong" }, + filterCard: { color: "black" }, + position: "hes", + check: function (card) { + var player = _status.event.player, + suits = lib.suit.slice(0); + if ( + player.countCards("h") > 4 && + player.hasCard(function (card) { + suits.remove(get.suit(card)); + return suits.length == 0; + }, "h") + ) + return 8 - get.value(card); + return 4 - get.value(card); }, - promptfunc:function(){ - if(_status.event.player.storage.olmiuyan) return '转换技。你可以将一张黑色牌当做【火攻】使用。若此牌未造成伤害,则你令此技能失效直到本轮结束。'; - return '转换技。你可以将一张黑色牌当做【火攻】使用。若此牌造成了伤害,则你获得此阶段内所有被展示过的牌。'; + promptfunc: function () { + if (_status.event.player.storage.olmiuyan) + return "转换技。你可以将一张黑色牌当做【火攻】使用。若此牌未造成伤害,则你令此技能失效直到本轮结束。"; + return "转换技。你可以将一张黑色牌当做【火攻】使用。若此牌造成了伤害,则你获得此阶段内所有被展示过的牌。"; }, - precontent:function(){ - player.changeZhuanhuanji('olmiuyan'); - var card=event.result.card; - if(!card.storage) card.storage={}; - if(player.storage.olmiuyan){ - card.storage.olmiuyan_gain=true; - player.addTempSkill('olmiuyan_gain'); - } - else{ - card.storage.olmiuyan_remove=true; - player.addTempSkill('olmiuyan_remove'); + precontent: function () { + player.changeZhuanhuanji("olmiuyan"); + var card = event.result.card; + if (!card.storage) card.storage = {}; + if (player.storage.olmiuyan) { + card.storage.olmiuyan_gain = true; + player.addTempSkill("olmiuyan_gain"); + } else { + card.storage.olmiuyan_remove = true; + player.addTempSkill("olmiuyan_remove"); } }, - init:function(player){ - player.addSkill('olmiuyan_counter'); + init: function (player) { + player.addSkill("olmiuyan_counter"); }, - onremove:function(player){ - player.removeSkill('olmiuyan_counter'); + onremove: function (player) { + player.removeSkill("olmiuyan_counter"); }, - zhuanhuanji:true, - mark:true, - marktext:'☯', - ai:{ - order:function(item,player){ - if(player.storage.olmiuyan) return 1; + zhuanhuanji: true, + mark: true, + marktext: "☯", + ai: { + order: function (item, player) { + if (player.storage.olmiuyan) return 1; return 8; }, }, - intro:{ - content:function(storage){ - if(storage) return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此牌未造成伤害,则你令此技能失效直到本轮结束。'; - return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此牌造成了伤害,则你获得此阶段内所有被展示过的牌。'; + intro: { + content: function (storage) { + if (storage) + return "转换技。你可以将一张黑色牌当做【火攻】使用。然后若此牌未造成伤害,则你令此技能失效直到本轮结束。"; + return "转换技。你可以将一张黑色牌当做【火攻】使用。然后若此牌造成了伤害,则你获得此阶段内所有被展示过的牌。"; }, }, - subSkill:{ - counter:{ - trigger:{global:['showCardsEnd','phaseZhunbeiBefore','phaseJudgeBefore','phaseDrawBefore','phaseUseBefore','phaseDiscardBefore','phaseJieshuBefore']}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(event.name=='showCards') return get.itemtype(event.cards)=='cards'; + subSkill: { + counter: { + trigger: { + global: [ + "showCardsEnd", + "phaseZhunbeiBefore", + "phaseJudgeBefore", + "phaseDrawBefore", + "phaseUseBefore", + "phaseDiscardBefore", + "phaseJieshuBefore", + ], + }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if (event.name == "showCards") return get.itemtype(event.cards) == "cards"; return true; }, - content:function(){ - if(trigger.name=='showCards'){ - game.broadcastAll(function(cards){ - cards.forEach(card=>card.addGaintag('olmiuyan_tag')); - },trigger.cards); - } - else game.players.forEach(current=>current.removeGaintag('olmiuyan_tag')); + content: function () { + if (trigger.name == "showCards") { + game.broadcastAll(function (cards) { + cards.forEach((card) => card.addGaintag("olmiuyan_tag")); + }, trigger.cards); + } else game.players.forEach((current) => current.removeGaintag("olmiuyan_tag")); }, }, - gain:{ - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.card.storage&&event.card.storage.olmiuyan_gain&&player.hasHistory('sourceDamage',function(evt){ - return evt.card==event.card; - })&&game.hasPlayer(function(current){ - return current!=player&¤t.hasCard(card=>card.hasGaintag('olmiuyan_tag')) + gain: { + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.olmiuyan_gain && + player.hasHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }) && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasCard((card) => card.hasGaintag("olmiuyan_tag")) + ); + }) + ); + }, + logTarget: function (event, player) { + return game.filterPlayer(function (current) { + return ( + current != player && + current.hasCard((card) => card.hasGaintag("olmiuyan_tag")) + ); }); }, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return current!=player&¤t.hasCard(card=>card.hasGaintag('olmiuyan_tag')) - }); - }, - content:function(){ - var cards=[],players=game.filterPlayer(current=>current!=player).sortBySeat(); - players.forEach(current=>{ - var cardsx=current.getCards('h',function(card){ - return card.hasGaintag('olmiuyan_tag'); + content: function () { + var cards = [], + players = game.filterPlayer((current) => current != player).sortBySeat(); + players.forEach((current) => { + var cardsx = current.getCards("h", function (card) { + return card.hasGaintag("olmiuyan_tag"); }); - if(cardsx.length) cards.addArray(cardsx); + if (cardsx.length) cards.addArray(cardsx); }); - player.gain(cards,'give'); + player.gain(cards, "give"); }, }, - remove:{ - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.card.storage&&event.card.storage.olmiuyan_remove&&!player.hasHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }); + remove: { + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.olmiuyan_remove && + !player.hasHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }) + ); }, - content:function(){ - player.addTempSkill('olmiuyan_blocker','roundStart'); - game.log(player,'的','#g【谬焰】','失效了'); + content: function () { + player.addTempSkill("olmiuyan_blocker", "roundStart"); + game.log(player, "的", "#g【谬焰】", "失效了"); }, }, - blocker:{charlotte:true}, + blocker: { charlotte: true }, }, }, - olshilu:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player.hp>0; + olshilu: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player.hp > 0; }, - content:function(){ - 'step 0' - player.draw(Math.min(5,player.hp)); - 'step 1' - var targets=game.filterPlayer(current=>current!=player&¤t.countCards('h')>0&&player.inRange(current)); - if(targets.length>0){ - if(targets.length==1) event._result={bool:true,targets:targets} - else player.chooseTarget(true,'请选择一名攻击范围内的角色','然后你选择该角色的一张手牌,令此牌视为【杀】',function(card,player,target){ - return target!=player&&target.countCards('h')>0&&player.inRange(target); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); + content: function () { + "step 0"; + player.draw(Math.min(5, player.hp)); + "step 1"; + var targets = game.filterPlayer( + (current) => + current != player && current.countCards("h") > 0 && player.inRange(current) + ); + if (targets.length > 0) { + if (targets.length == 1) event._result = { bool: true, targets: targets }; + else + player + .chooseTarget( + true, + "请选择一名攻击范围内的角色", + "然后你选择该角色的一张手牌,令此牌视为【杀】", + function (card, player, target) { + return ( + target != player && + target.countCards("h") > 0 && + player.inRange(target) + ); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + player.choosePlayerCard(target, true, "h"); } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - player.choosePlayerCard(target,true,'h'); - } - 'step 3' - if(result.bool){ - target.addSkill('olshilu_viewas'); + "step 3"; + if (result.bool) { + target.addSkill("olshilu_viewas"); target.showCards(result.cards); - target.addGaintag(result.cards,'olshilu'); + target.addGaintag(result.cards, "olshilu"); } }, - ai:{ - maixie:true, + ai: { + maixie: true, }, - subSkill:{ - viewas:{ - mod:{ - cardname:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('olshilu')) return 'sha'; + subSkill: { + viewas: { + mod: { + cardname: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("olshilu")) return "sha"; }, }, - charlotte:true, + charlotte: true, }, }, }, //张翼 - oldianjun:{ - audio:2, - trigger:{player:'phaseEnd'}, - forced:true, - content:function(){ - 'step 0' - player.damage('nosource'); - 'step 1' - trigger.phaseList.splice(trigger.num,0,'phaseUse|oldianjun'); + oldianjun: { + audio: 2, + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { + "step 0"; + player.damage("nosource"); + "step 1"; + trigger.phaseList.splice(trigger.num, 0, "phaseUse|oldianjun"); }, }, - olkangrui:{ - audio:2, - init:()=>{ - game.addGlobalSkill('olkangrui_ai'); + olkangrui: { + audio: 2, + init: () => { + game.addGlobalSkill("olkangrui_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('olkangrui'),true)) game.removeGlobalSkill('olkangrui_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("olkangrui"), true)) + game.removeGlobalSkill("olkangrui_ai"); }, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return event.player==_status.currentPhase&&event.player.getHistory('damage').indexOf(event)==0; + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return ( + event.player == _status.currentPhase && + event.player.getHistory("damage").indexOf(event) == 0 + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('cancel2').set('choiceList',[ - '令'+get.translation(trigger.player)+'回复1点体力,且造成伤害时本回合手牌上限为0', - '令'+get.translation(trigger.player)+'于本回合下次造成的伤害+1,且造成伤害时本回合手牌上限为0', - ]).set('prompt',get.prompt('olkangrui',trigger.player)).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(get.attitude(player,trigger.player)<=0) return 'cancel2'; - if(!trigger.player.isDamaged()) return '选项二'; - var list=[]; - if(trigger.player.hp+trigger.player.countCards('hs','tao')<=2) list.push('选项一'); - if(trigger.player.hasCard(card=>{ - if(!get.tag(card,'damage')) return false; - if(game.hasPlayer(current=>{ - return get.effect(current,card,trigger.player,player)>0&&trigger.player.canUse(card,current)&& - !current.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:card - }); - },'hs')){ - return true; - } - })) list.push('选项二'); - if(list.length) return list.randomGet(); - return '选项一'; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('olkangrui',trigger.player); + direct: true, + content: function () { + "step 0"; + player + .chooseControl("cancel2") + .set("choiceList", [ + "令" + + get.translation(trigger.player) + + "回复1点体力,且造成伤害时本回合手牌上限为0", + "令" + + get.translation(trigger.player) + + "于本回合下次造成的伤害+1,且造成伤害时本回合手牌上限为0", + ]) + .set("prompt", get.prompt("olkangrui", trigger.player)) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (get.attitude(player, trigger.player) <= 0) return "cancel2"; + if (!trigger.player.isDamaged()) return "选项二"; + var list = []; + if (trigger.player.hp + trigger.player.countCards("hs", "tao") <= 2) + list.push("选项一"); + if ( + trigger.player.hasCard((card) => { + if (!get.tag(card, "damage")) return false; + if ( + game.hasPlayer((current) => { + return ( + get.effect(current, card, trigger.player, player) > 0 && + trigger.player.canUse(card, current) && + !current.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: card, + }) + ); + }, "hs") + ) { + return true; + } + }) + ) + list.push("选项二"); + if (list.length) return list.randomGet(); + return "选项一"; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("olkangrui", trigger.player); player.draw(); - if(result.index==0){ + if (result.index == 0) { trigger.player.recover(); - trigger.player.addTempSkill('olkangrui_nil'); - } - else{ - trigger.player.addTempSkill('olkangrui_add'); - trigger.player.addMark('olkangrui_add',1,false); + trigger.player.addTempSkill("olkangrui_nil"); + } else { + trigger.player.addTempSkill("olkangrui_add"); + trigger.player.addMark("olkangrui_add", 1, false); } } }, - ai:{ - expose:0.2, - threaten:1.5, + ai: { + expose: 0.2, + threaten: 1.5, }, - subSkill:{ - add:{ - trigger:{source:'damageBegin1'}, - charlotte:true, - forced:true, - onremove:['olkangrui_add','olkangrui_nil'], - filter:function(event,player){ - return player.hasMark('olkangrui_add'); + subSkill: { + add: { + trigger: { source: "damageBegin1" }, + charlotte: true, + forced: true, + onremove: ["olkangrui_add", "olkangrui_nil"], + filter: function (event, player) { + return player.hasMark("olkangrui_add"); }, - content:function(){ - trigger.num+=player.countMark('olkangrui_add'); - player.removeMark('olkangrui_add',player.countMark('olkangrui_add'),false); - player.storage.olkangrui_nil=true; - game.log(player,'本回合手牌上限基数为','#g0'); + content: function () { + trigger.num += player.countMark("olkangrui_add"); + player.removeMark("olkangrui_add", player.countMark("olkangrui_add"), false); + player.storage.olkangrui_nil = true; + game.log(player, "本回合手牌上限基数为", "#g0"); }, - mod:{ - maxHandcardBase:function(player,num){ - if(player.storage.olkangrui_nil) return 0; + mod: { + maxHandcardBase: function (player, num) { + if (player.storage.olkangrui_nil) return 0; }, - } + }, }, - nil:{ - trigger:{source:'damageBegin1'}, - charlotte:true, - forced:true, - onremove:true, - filter:function(event,player){ + nil: { + trigger: { source: "damageBegin1" }, + charlotte: true, + forced: true, + onremove: true, + filter: function (event, player) { return !player.storage.olkangrui_nil; }, - content:function(){ - player.storage.olkangrui_nil=true; - game.log(player,'本回合手牌上限基数为','#g0'); + content: function () { + player.storage.olkangrui_nil = true; + game.log(player, "本回合手牌上限基数为", "#g0"); }, - mod:{ - maxHandcardBase:function(player,num){ - if(player.storage.olkangrui_nil) return 0; + mod: { + maxHandcardBase: function (player, num) { + if (player.storage.olkangrui_nil) return 0; }, - } + }, }, - ai:{ - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('olkangrui'),true); + ai: { + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("olkangrui"), true); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('olkangrui_ai'); + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("olkangrui_ai"); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target!=player||!get.tag(card,'damage')) return; - var list=game.filterPlayer(current=>current.hasSkill('olkangrui')&&get.attitude(current,player)>0); - var history=player.getHistory('damage'); - if(!list.length||history.length!=0) return; - return [1,2]; - } - } - } - } - } + ai: { + effect: { + target: function (card, player, target) { + if (target != player || !get.tag(card, "damage")) return; + var list = game.filterPlayer( + (current) => + current.hasSkill("olkangrui") && get.attitude(current, player) > 0 + ); + var history = player.getHistory("damage"); + if (!list.length || history.length != 0) return; + return [1, 2]; + }, + }, + }, + }, + }, }, //朱儁 - olcuipo:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return get.cardNameLength(event.card)==player.getHistory('useCard').indexOf(event)+1; + olcuipo: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return get.cardNameLength(event.card) == player.getHistory("useCard").indexOf(event) + 1; }, - content:function(){ - var card=trigger.card; - if(card.name=='sha'||get.type(card)=='trick'&&get.tag(card,'damage')>0) trigger.baseDamage++; + content: function () { + var card = trigger.card; + if (card.name == "sha" || (get.type(card) == "trick" && get.tag(card, "damage") > 0)) + trigger.baseDamage++; else player.draw(); }, /* @@ -6190,386 +8533,533 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ trigger.num++; },*/ - mod:{ - aiOrder:function(player,card,num){ - if(typeof card=='object'&&get.cardNameLength(card)==player.getHistory('useCard').length+1) return num+10; + mod: { + aiOrder: function (player, card, num) { + if ( + typeof card == "object" && + get.cardNameLength(card) == player.getHistory("useCard").length + 1 + ) + return num + 10; }, - } + }, }, //马休马铁 - rekenshang:{ - audio:'olkenshang', - enable:'chooseToUse', - filterCard:true, - selectCard:[2,Infinity], - viewAsFilter:function(player){ - return player.countCards('hes')>1; + rekenshang: { + audio: "olkenshang", + enable: "chooseToUse", + filterCard: true, + selectCard: [2, Infinity], + viewAsFilter: function (player) { + return player.countCards("hes") > 1; }, - check:function(card){ + check: function (card) { var player = _status.event.player; - if(game.countPlayer(function (current) { - return current != player && player.canUse('sha', current) && get.effect(current, {name: 'sha'}, player, player) > 0; - }) <= ui.selected.cards.length) return 0; - if(_status.event.player.countCards('hes') >= 3) return 8 - ui.selected.cards.length - get.value(card); + if ( + game.countPlayer(function (current) { + return ( + current != player && + player.canUse("sha", current) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) <= ui.selected.cards.length + ) + return 0; + if (_status.event.player.countCards("hes") >= 3) + return 8 - ui.selected.cards.length - get.value(card); return 6 - ui.selected.cards.length - get.value(card); }, - position:'hes', - viewAs:{ - name:'sha', - storage:{olkenshang:true} + position: "hes", + viewAs: { + name: "sha", + storage: { olkenshang: true }, }, - onuse:function(links,player){ - player.addTempSkill('rekenshang_effect'); + onuse: function (links, player) { + player.addTempSkill("rekenshang_effect"); }, - ai:{ - order:function(item,player){ - if(player.countCards('hes') >= 3) return 6; + ai: { + order: function (item, player) { + if (player.countCards("hes") >= 3) return 6; return 4; }, - result:{ - target:function(player,target,card,isLink){ - let eff=-1.5,odds=1.35,num=1; - if(isLink){ - let cache=_status.event.getTempCache('sha_result','eff'); - if(typeof cache!=='object'||cache.card!==get.translation(card)) return eff; - if(cache.odds<1.35&&cache.bool) return 1.35*cache.eff; - return cache.odds*cache.eff; + result: { + target: function (player, target, card, isLink) { + let eff = -1.5, + odds = 1.35, + num = 1; + if (isLink) { + let cache = _status.event.getTempCache("sha_result", "eff"); + if (typeof cache !== "object" || cache.card !== get.translation(card)) + return eff; + if (cache.odds < 1.35 && cache.bool) return 1.35 * cache.eff; + return cache.odds * cache.eff; } - if(player.hasSkill('jiu')||player.hasSkillTag('damageBonus',true,{ - target:target, - card:card - })){ - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - jiu:true, - })) eff=-0.5; - else{ - num=2; - if(get.attitude(player,target)>0) eff=-7; - else eff=-4; + if ( + player.hasSkill("jiu") || + player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }) + ) { + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + jiu: true, + }) + ) + eff = -0.5; + else { + num = 2; + if (get.attitude(player, target) > 0) eff = -7; + else eff = -4; } } - if(!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)) odds-=0.7*target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }),'odds'); - _status.event.putTempCache('sha_result','eff',{ - bool:target.hp>num&&get.attitude(player,target)>0, - card:get.translation(card), - eff:eff, - odds:odds + if ( + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) + odds -= + 0.7 * + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }), + "odds" + ); + _status.event.putTempCache("sha_result", "eff", { + bool: target.hp > num && get.attitude(player, target) > 0, + card: get.translation(card), + eff: eff, + odds: odds, }); - return odds*eff; - } + return odds * eff; + }, }, - respondSha:true, - skillTagFilter:player=>player.countCards('hes')>1, + respondSha: true, + skillTagFilter: (player) => player.countCards("hes") > 1, }, - subSkill:{ - effect:{ - audio:'olkenshang', - trigger:{player:'useCard2'}, - charlotte:true, - group:'rekenshang_after', - direct:true, - filter:function(event,player){ - return event.card.storage&&event.card.storage.olkenshang&&game.countPlayer(function(current){ - return current!=player&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })>=event.cards.length; + subSkill: { + effect: { + audio: "olkenshang", + trigger: { player: "useCard2" }, + charlotte: true, + group: "rekenshang_after", + direct: true, + filter: function (event, player) { + return ( + event.card.storage && + event.card.storage.olkenshang && + game.countPlayer(function (current) { + return ( + current != player && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) >= event.cards.length + ); }, - content:function(){ - 'step 0' - player.chooseTarget( - trigger.cards.length, - '是否更改'+get.translation(trigger.card)+'的目标?', - '选择'+get.cnNumber(trigger.cards.length)+'名角色作为'+get.translation(trigger.card)+'的目标,覆盖原先存在的目标', - function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&lib.filter.targetEnabled2(evt.card,player,target)&&lib.filter.targetInRange(evt.card,player,target); - }).set('ai',function(target){ - var evt=_status.event.getTrigger(); - return get.effect(target,evt.card,evt.player,evt.player); - }); - 'step 1' - if(result.bool){ - if(player!=event.player&&!player.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - var targets=result.targets; - player.logSkill('rekenshang_effect',targets); - trigger.targets.length=0; + content: function () { + "step 0"; + player + .chooseTarget( + trigger.cards.length, + "是否更改" + get.translation(trigger.card) + "的目标?", + "选择" + + get.cnNumber(trigger.cards.length) + + "名角色作为" + + get.translation(trigger.card) + + "的目标,覆盖原先存在的目标", + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); + } + ) + .set("ai", function (target) { + var evt = _status.event.getTrigger(); + return get.effect(target, evt.card, evt.player, evt.player); + }); + "step 1"; + if (result.bool) { + if (player != event.player && !player.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + var targets = result.targets; + player.logSkill("rekenshang_effect", targets); + trigger.targets.length = 0; trigger.targets.addArray(targets); - game.log(targets,'成为了',trigger.card,'的新目标'); + game.log(targets, "成为了", trigger.card, "的新目标"); }, }, - after:{ - audio:'olkenshang', - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(event.card.name!='sha'||!event.card.storage||!event.card.storage.olkenshang) return false; - var num=0; - game.countPlayer2(current=>{ - current.getHistory('damage',evt=>{ - if(evt.card==event.card) num+=evt.num; - }) + after: { + audio: "olkenshang", + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if ( + event.card.name != "sha" || + !event.card.storage || + !event.card.storage.olkenshang + ) + return false; + var num = 0; + game.countPlayer2((current) => { + current.getHistory("damage", (evt) => { + if (evt.card == event.card) num += evt.num; + }); }); - return numcurrent!=player&&player.canUse(card,current,false)&&!player.inRange(current)); - for(var target of targets){ - eff+=get.effect(target,card,player,player); + ai: { + order: 1, + threaten: 1.1, + effect: { + player_use: function (card, player, target) { + if (_status._olkenshang_aiChecking || ui.selected.targets.length) return; + if (typeof card != "object" || !card.storage || !card.storage.olkenshang) + return false; + _status._olkenshang_aiChecking = true; + var eff = 0; + var targets = game.filterPlayer( + (current) => + current != player && + player.canUse(card, current, false) && + !player.inRange(current) + ); + for (var target of targets) { + eff += get.effect(target, card, player, player); } delete _status._olkenshang_aiChecking; - if(eff>0) return [0,eff/Math.max(0.01,get.attitude(player,player))]; + if (eff > 0) return [0, eff / Math.max(0.01, get.attitude(player, player))]; }, }, }, - subSkill:{ - effect:{ - audio:'olkenshang', - trigger:{player:'useCard2'}, - charlotte:true, - logTarget:function(event,player){ - return game.filterPlayer(current=>current!=player&&player.canUse(event.card,current,false)&&!player.inRange(current)); + subSkill: { + effect: { + audio: "olkenshang", + trigger: { player: "useCard2" }, + charlotte: true, + logTarget: function (event, player) { + return game.filterPlayer( + (current) => + current != player && + player.canUse(event.card, current, false) && + !player.inRange(current) + ); }, - prompt2:'将此牌目标改为攻击范围外的所有其他角色', - group:'olkenshang_after', - check:function(event,player){ - var eff1=0,eff2=0; - for(var target of event.targets){ - eff1+=get.effect(target,event.card,event.player,player); + prompt2: "将此牌目标改为攻击范围外的所有其他角色", + group: "olkenshang_after", + check: function (event, player) { + var eff1 = 0, + eff2 = 0; + for (var target of event.targets) { + eff1 += get.effect(target, event.card, event.player, player); } - var targets=game.filterPlayer(current=>current!=player&&player.canUse(event.card,current,false)&&!player.inRange(current)); - for(var target of targets){ - eff2+=get.effect(target,event.card,event.player,player); + var targets = game.filterPlayer( + (current) => + current != player && + player.canUse(event.card, current, false) && + !player.inRange(current) + ); + for (var target of targets) { + eff2 += get.effect(target, event.card, event.player, player); } - return eff2>eff1; + return eff2 > eff1; }, - filter:function(event,player){ - return event.card.name=='sha'&&event.card.storage&&event.card.storage.olkenshang&&event.targets.length&&game.filterPlayer(current=>current!=player&&player.canUse(event.card,current,false)&&!player.inRange(current)).length; + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.card.storage && + event.card.storage.olkenshang && + event.targets.length && + game.filterPlayer( + (current) => + current != player && + player.canUse(event.card, current, false) && + !player.inRange(current) + ).length + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.targets.removeArray(trigger.targets); - var targets=game.filterPlayer(current=>current!=player&&player.canUse(trigger.card,current,false)&&!player.inRange(current)); - if(targets.length) trigger.targets.addArray(targets); - } - }, - after:{ - audio:'olkenshang', - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(event.card.name!='sha'||!event.card.storage||!event.card.storage.olkenshang) return false; - var num=0; - game.countPlayer2(current=>{ - current.getHistory('damage',evt=>{ - if(evt.card==event.card) num+=evt.num; - }) - }); - return num>0; + var targets = game.filterPlayer( + (current) => + current != player && + player.canUse(trigger.card, current, false) && + !player.inRange(current) + ); + if (targets.length) trigger.targets.addArray(targets); }, - content:function(){ - 'step 0' - var num=0,len=trigger.cards.length; - game.countPlayer2(current=>{ - current.getHistory('damage',evt=>{ - if(evt.card==trigger.card) num+=evt.num; - }) + }, + after: { + audio: "olkenshang", + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if ( + event.card.name != "sha" || + !event.card.storage || + !event.card.storage.olkenshang + ) + return false; + var num = 0; + game.countPlayer2((current) => { + current.getHistory("damage", (evt) => { + if (evt.card == event.card) num += evt.num; + }); }); - if(len>num){ + return num > 0; + }, + content: function () { + "step 0"; + var num = 0, + len = trigger.cards.length; + game.countPlayer2((current) => { + current.getHistory("damage", (evt) => { + if (evt.card == trigger.card) num += evt.num; + }); + }); + if (len > num) { player.draw(num); event.finish(); - } - else{ - var skills=player.getSkills(null,false,false).filter(skill=>{ - var info=get.info(skill); - if(!info||info.charlotte||get.skillInfoTranslation(skill,player).length==0) return false; + } else { + var skills = player.getSkills(null, false, false).filter((skill) => { + var info = get.info(skill); + if ( + !info || + info.charlotte || + get.skillInfoTranslation(skill, player).length == 0 + ) + return false; return true; }); - if(skills.length==1) event._result={control:skills[0]}; - else player.chooseControl(skills).set('choiceList',skills.map(i=>{ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','垦伤:选择失去一个技能').set('ai',()=>{ - var choices=_status.event.controls.slice(); - var negs=choices.filter(i=>{ - var info=get.info(i); - if(!info||!info.ai) return false; - return info.ai.neg||info.ai.halfneg; - }); - if(negs.length) return negs.randomGet(); - if(choices.includes('mashu')) return 'mashu'; - return choices.randomGet(); - }); + if (skills.length == 1) event._result = { control: skills[0] }; + else + player + .chooseControl(skills) + .set( + "choiceList", + skills.map((i) => { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || + get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "垦伤:选择失去一个技能") + .set("ai", () => { + var choices = _status.event.controls.slice(); + var negs = choices.filter((i) => { + var info = get.info(i); + if (!info || !info.ai) return false; + return info.ai.neg || info.ai.halfneg; + }); + if (negs.length) return negs.randomGet(); + if (choices.includes("mashu")) return "mashu"; + return choices.randomGet(); + }); } - 'step 1' + "step 1"; player.removeSkills(result.control); - } - } + }, + }, }, }, //董荼那 - oljianman:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - direct:true, - filter:function(event,player){ - var history=game.getGlobalHistory('useCard',evt=>{ - return get.type(evt.card)=='basic'; + oljianman: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + direct: true, + filter: function (event, player) { + var history = game.getGlobalHistory("useCard", (evt) => { + return get.type(evt.card) == "basic"; }); - if(history.length<2) return false; - var users=history.slice(0,2).map(i=>i.player); - var list=users.filter(user=>user==player); - if(list.length==1){ - var target=users.filter(user=>user!=player)[0]; - return target&&target.isIn()&&target.countDiscardableCards(player,'he'); + if (history.length < 2) return false; + var users = history.slice(0, 2).map((i) => i.player); + var list = users.filter((user) => user == player); + if (list.length == 1) { + var target = users.filter((user) => user != player)[0]; + return target && target.isIn() && target.countDiscardableCards(player, "he"); } - if(list.length==2){ - return history.slice(0,2).some(evt=>{ - var card=evt.card; - return player.hasUseTarget({name:card.name,nature:card.nature,isCard:true}); + if (list.length == 2) { + return history.slice(0, 2).some((evt) => { + var card = evt.card; + return player.hasUseTarget({ + name: card.name, + nature: card.nature, + isCard: true, + }); }); } return false; }, - content:function(){ - 'step 0' - var history=game.getGlobalHistory('useCard',evt=>{ - return get.type(evt.card)=='basic'; + content: function () { + "step 0"; + var history = game.getGlobalHistory("useCard", (evt) => { + return get.type(evt.card) == "basic"; }); - var list=history.slice(0,2).map(i=>i.player).filter(user=>user==player); - if(list.length==1) { - var users=history.slice(0,2).map(i=>i.player); - var target=users.filter(user=>user!=player)[0]; - player.logSkill('oljianman',target); - player.discardPlayerCard(target,'he',true); + var list = history + .slice(0, 2) + .map((i) => i.player) + .filter((user) => user == player); + if (list.length == 1) { + var users = history.slice(0, 2).map((i) => i.player); + var target = users.filter((user) => user != player)[0]; + player.logSkill("oljianman", target); + player.discardPlayerCard(target, "he", true); event.finish(); - } - else if(list.length==2){ - var evts=history.slice(0,2); - var vcard=[]; - for(var evt of evts){ - var card=evt.card; - if(vcard.length&&vcard[0][2]==card.name&&vcard[0][3]==card.nature) continue; - if(player.hasUseTarget({name:card.name,nature:card.nature,isCard:true})){ - vcard.push(['基本','',card.name,card.nature]); + } else if (list.length == 2) { + var evts = history.slice(0, 2); + var vcard = []; + for (var evt of evts) { + var card = evt.card; + if (vcard.length && vcard[0][2] == card.name && vcard[0][3] == card.nature) + continue; + if (player.hasUseTarget({ name: card.name, nature: card.nature, isCard: true })) { + vcard.push(["基本", "", card.name, card.nature]); } } - if(vcard.length==1) event._result={bool:true,links:[vcard[0]]}; - else{ - player.chooseButton(['鹣蛮:视为使用其中一张牌',[vcard,'vcard']]).set('ai',function(button){ - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); - }); + if (vcard.length == 1) event._result = { bool: true, links: [vcard[0]] }; + else { + player + .chooseButton(["鹣蛮:视为使用其中一张牌", [vcard, "vcard"]]) + .set("ai", function (button) { + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }); } + } else event.finish(); + "step 1"; + if (result.bool) { + var card = { name: result.links[0][2], nature: result.links[0][3], isCard: true }; + player + .chooseUseTarget(card, true) + .set("logSkill", "oljianman") + .set("prompt", "鹣蛮:选择" + get.translation(card) + "的目标"); } - else event.finish(); - 'step 1' - if(result.bool){ - var card={name:result.links[0][2],nature:result.links[0][3],isCard:true}; - player.chooseUseTarget(card,true).set('logSkill','oljianman').set('prompt','鹣蛮:选择'+get.translation(card)+'的目标'); - } - } + }, }, //张华 - olbihun:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - forced:true, - filter:function(event,player){ - return event.isFirstTarget&&player.countCards('h')>player.getHandcardLimit()&&event.targets.some(target=>target!=player); + olbihun: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + forced: true, + filter: function (event, player) { + return ( + event.isFirstTarget && + player.countCards("h") > player.getHandcardLimit() && + event.targets.some((target) => target != player) + ); }, //group:'olbihun_give', - content:function(){ - if(trigger.targets.length==1){ - var cards=trigger.cards.filterInD(); - if(cards.length){ + content: function () { + if (trigger.targets.length == 1) { + var cards = trigger.cards.filterInD(); + if (cards.length) { game.delayx(); - trigger.targets[0].gain(cards,'gain2'); + trigger.targets[0].gain(cards, "gain2"); } } - var targets=trigger.targets.filter(target=>target!=player); + var targets = trigger.targets.filter((target) => target != player); trigger.targets.removeArray(targets); trigger.getParent().triggeredTargets1.removeArray(targets); }, - ai:{ - threaten:0.8, - halfneg:true, - effect:{ - player:function(card,player,target){ - if((!card.isCard||!card.cards)&&get.itemtype(card)!='card') return; - let cs=0; - if(target&&player!=target&&player.countCards('h',i=>{ - if(card===i||card.cards&&card.cards.includes(i)){ - cs++; - return false; - } - return true; - })>player.getHandcardLimit()){ - let targets=[],evt=_status.event.getParent('useCard'); + ai: { + threaten: 0.8, + halfneg: true, + effect: { + player: function (card, player, target) { + if ((!card.isCard || !card.cards) && get.itemtype(card) != "card") return; + let cs = 0; + if ( + target && + player != target && + player.countCards("h", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) { + cs++; + return false; + } + return true; + }) > player.getHandcardLimit() + ) { + let targets = [], + evt = _status.event.getParent("useCard"); targets.addArray(ui.selected.targets); - if(evt&&evt.card==card) targets.addArray(evt.targets); - if(targets.length){ - if(targets.length>1||!targets.includes(target)) return 'zeroplayertarget'; + if (evt && evt.card == card) targets.addArray(evt.targets); + if (targets.length) { + if (targets.length > 1 || !targets.includes(target)) + return "zeroplayertarget"; return; } - let info=get.info(card); - if(!info||info.notarget||!info.filterTarget) return; - let range,select=get.copy(info.selectTarget),filter; - if(select===undefined) range=[1,1]; - else if(typeof select==='number') range=[select,select]; - else if(get.itemtype(select)==='select') range=select; - else if(typeof select==='function') range=select(card,player); - if(info.singleCard) range=[1,1]; - game.checkMod(card,player,range,'selectTarget',player); - if(range[1]<-1) range=[1, 1]; - else if(range[0]<0){ - if(info.filterTarget===true) filter=game.players.length; - else filter=game.countPlayer(current=>{ - return info.filterTarget(card,player,current); - }); - range=[filter,filter]; + let info = get.info(card); + if (!info || info.notarget || !info.filterTarget) return; + let range, + select = get.copy(info.selectTarget), + filter; + if (select === undefined) range = [1, 1]; + else if (typeof select === "number") range = [select, select]; + else if (get.itemtype(select) === "select") range = select; + else if (typeof select === "function") range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); + if (range[1] < -1) range = [1, 1]; + else if (range[0] < 0) { + if (info.filterTarget === true) filter = game.players.length; + else + filter = game.countPlayer((current) => { + return info.filterTarget(card, player, current); + }); + range = [filter, filter]; } - if(range&&range[0]>1&&range[1]>1) return 'zeroplayertarget'; - return [0,0,0,1]; + if (range && range[0] > 1 && range[1] > 1) return "zeroplayertarget"; + return [0, 0, 0, 1]; } }, }, @@ -6588,1763 +9078,2274 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }*/ }, - olchuanwu:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + olchuanwu: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - filter:function(event,player){ - return player.getAttackRange()>0; + forced: true, + filter: function (event, player) { + return player.getAttackRange() > 0; }, - content:function(){ - var skills=game.filterSkills(player.getStockSkills(true,true),player); - var num=Math.min(player.getAttackRange(),skills.length); - skills=skills.slice(0,num); - player.disableSkill('olchuanwu',skills); - player.addTempSkill('olchuanwu_restore'); - var str=''; - for(var i of skills){ - str+='【'+get.translation(i)+'】、'; + content: function () { + var skills = game.filterSkills(player.getStockSkills(true, true), player); + var num = Math.min(player.getAttackRange(), skills.length); + skills = skills.slice(0, num); + player.disableSkill("olchuanwu", skills); + player.addTempSkill("olchuanwu_restore"); + var str = ""; + for (var i of skills) { + str += "【" + get.translation(i) + "】、"; player.popup(i); } - str=str.slice(0,-1); - game.log(player,'的技能','#g'+str,'失效了'); + str = str.slice(0, -1); + game.log(player, "的技能", "#g" + str, "失效了"); player.draw(num); }, - subSkill:{ - restore:{ - charlotte:true, - forced:true, - popup:false, - onremove:function(player){ - player.enableSkill('olchuanwu'); - game.log(player,'恢复了技能'); - } - } - } - }, - oljianhe:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - return !player.getStorage('oljianhe_chosen').includes(target); + subSkill: { + restore: { + charlotte: true, + forced: true, + popup: false, + onremove: function (player) { + player.enableSkill("olchuanwu"); + game.log(player, "恢复了技能"); + }, + }, }, - filterCard:function(card,player){ - if(ui.selected.cards.length){ - var cardx=ui.selected.cards[0]; - if(get.type(cardx)=='equip') return get.type(card)=='equip'; - return get.name(card)==get.name(cardx); + }, + oljianhe: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + return !player.getStorage("oljianhe_chosen").includes(target); + }, + filterCard: function (card, player) { + if (ui.selected.cards.length) { + var cardx = ui.selected.cards[0]; + if (get.type(cardx) == "equip") return get.type(card) == "equip"; + return get.name(card) == get.name(cardx); } - var cards=player.getCards('he'); - for(var cardx of cards){ - if(card!=cardx){ - if(get.type(cardx)=='equip'&&get.type(card)=='equip') return true; - if(get.name(card)==get.name(cardx)) return true; + var cards = player.getCards("he"); + for (var cardx of cards) { + if (card != cardx) { + if (get.type(cardx) == "equip" && get.type(card) == "equip") return true; + if (get.name(card) == get.name(cardx)) return true; } } return false; }, - selectCard:[2,Infinity], - position:'he', - complexCard:true, - discard:false, - visible:true, - prepare:'throw', - loseTo:'discardPile', - delay:0.5, - check:function(card){ - if(get.type(card)=='equip') return 15-get.value(card); - return 7-get.value(card); + selectCard: [2, Infinity], + position: "he", + complexCard: true, + discard: false, + visible: true, + prepare: "throw", + loseTo: "discardPile", + delay: 0.5, + check: function (card) { + if (get.type(card) == "equip") return 15 - get.value(card); + return 7 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(cards.length); - player.addTempSkill('oljianhe_chosen','phaseUseAfter'); - player.markAuto('oljianhe_chosen',[target]); - 'step 1' - var type=get.type2(cards[0]); - target.chooseCard(get.translation(player)+'对你发动了【剑合】','请重铸'+get.cnNumber(cards.length)+'张'+get.translation(type)+'牌,或点“取消”受到1点雷电伤害',cards.length,'he',(card,player)=>{ - return get.type2(card)==_status.event.type&&player.canRecast(card); - }).set('ai',card=>{ - if(_status.event.goon) return (get.type(card)=='equip'?15:7)-get.value(card); - return 0; - }).set('type',type).set('goon',get.damageEffect(target,player,target,'thunder')<0); - 'step 2' - if(result.bool){ + player.addTempSkill("oljianhe_chosen", "phaseUseAfter"); + player.markAuto("oljianhe_chosen", [target]); + "step 1"; + var type = get.type2(cards[0]); + target + .chooseCard( + get.translation(player) + "对你发动了【剑合】", + "请重铸" + + get.cnNumber(cards.length) + + "张" + + get.translation(type) + + "牌,或点“取消”受到1点雷电伤害", + cards.length, + "he", + (card, player) => { + return get.type2(card) == _status.event.type && player.canRecast(card); + } + ) + .set("ai", (card) => { + if (_status.event.goon) + return (get.type(card) == "equip" ? 15 : 7) - get.value(card); + return 0; + }) + .set("type", type) + .set("goon", get.damageEffect(target, player, target, "thunder") < 0); + "step 2"; + if (result.bool) { target.recast(result.cards); + } else { + target.damage(player, "thunder"); } - else{ - target.damage(player,'thunder'); - } - 'step 3' + "step 3"; game.delayx(); }, - ai:{ - order:function(item,player){ - if(player.hasSkill('olbihun')&&player.countCards('h')>player.getHandcardLimit()) return 11; + ai: { + order: function (item, player) { + if (player.hasSkill("olbihun") && player.countCards("h") > player.getHandcardLimit()) + return 11; return 4; }, - threaten:2.4, - expose:0.1, - result:{ - target:function(player,target){ - var cards=ui.selected.cards,type=get.type2(cards[0]); - if(target.countCards('he',card=>{ - return get.type(card)==type&&get.value(card)<=5; - })>=cards.length) return 1; + threaten: 2.4, + expose: 0.1, + result: { + target: function (player, target) { + var cards = ui.selected.cards, + type = get.type2(cards[0]); + if ( + target.countCards("he", (card) => { + return get.type(card) == type && get.value(card) <= 5; + }) >= cards.length + ) + return 1; return -1; - } - } + }, + }, + }, + subSkill: { + chosen: { + charlotte: true, + onremove: true, + intro: { content: "本阶段已对$发动过技能" }, + }, }, - subSkill:{ - chosen:{ - charlotte:true, - onremove:true, - intro:{content:'本阶段已对$发动过技能'}, - } - } }, //屈晃 - olqiejian:{ - audio:2, - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + olqiejian: { + audio: 2, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - if(current.countCards('h')) return false; - var evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length&&!player.getStorage('olqiejian_ban').includes(current); + direct: true, + filter: function (event, player) { + return game.hasPlayer((current) => { + if (current.countCards("h")) return false; + var evt = event.getl(current); + return ( + evt && + evt.hs && + evt.hs.length && + !player.getStorage("olqiejian_ban").includes(current) + ); }); }, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(current=>{ - if(current.countCards('h')) return false; - var evt=trigger.getl(current); - return evt&&evt.hs&&evt.hs.length&&!player.getStorage('olqiejian_ban').includes(current); - }).sortBySeat(_status.currentPhase); - 'step 1' - var target=targets.shift(); - event.target=target; - if(target.isIn()){ - player.chooseBool(get.prompt2('olqiejian',target)).set('ai',()=>{ - return _status.event.bool; - }).set('bool',get.attitude(player,target)>0||target.hasCard(card=>{ - return get.value(card,target)*get.sgnAttitude(player,target)<-6; - },'ej')); - } - else event.goto(5); - 'step 2' - if(result.bool){ - player.logSkill('olqiejian',target); - player.draw('nodelay'); + content: function () { + "step 0"; + event.targets = game + .filterPlayer((current) => { + if (current.countCards("h")) return false; + var evt = trigger.getl(current); + return ( + evt && + evt.hs && + evt.hs.length && + !player.getStorage("olqiejian_ban").includes(current) + ); + }) + .sortBySeat(_status.currentPhase); + "step 1"; + var target = targets.shift(); + event.target = target; + if (target.isIn()) { + player + .chooseBool(get.prompt2("olqiejian", target)) + .set("ai", () => { + return _status.event.bool; + }) + .set( + "bool", + get.attitude(player, target) > 0 || + target.hasCard((card) => { + return get.value(card, target) * get.sgnAttitude(player, target) < -6; + }, "ej") + ); + } else event.goto(5); + "step 2"; + if (result.bool) { + player.logSkill("olqiejian", target); + player.draw("nodelay"); target.draw(); - } - else event.goto(5); - 'step 3' - player.chooseTarget('切谏:选择一名角色','弃置你或其场上的一张牌;或点击“取消”令你于本轮不能再对其发动此技能',(card,player,target)=>{ - return (target==player||target==_status.event.getParent().target)&&target.countDiscardableCards(player,'ej')>0; - }).set('ai',target=>{ - var sign=get.sgnAttitude(_status.event.player,target); - return 6-target.getCards('ej').map(i=>{ - var val=0; - if(get.position(i)=='e') val=get.value(i,target); - else{ - val=get.effect(player,{ - name:i.viewAs||i.name, - cards:[i], - },target,target); + } else event.goto(5); + "step 3"; + player + .chooseTarget( + "切谏:选择一名角色", + "弃置你或其场上的一张牌;或点击“取消”令你于本轮不能再对其发动此技能", + (card, player, target) => { + return ( + (target == player || target == _status.event.getParent().target) && + target.countDiscardableCards(player, "ej") > 0 + ); } - return sign*val; - }).sort((a,b)=>a-b)[0]; - }); - 'step 4' - if(result.bool){ - var targetx=result.targets[0]; - player.discardPlayerCard(targetx,'ej',true); + ) + .set("ai", (target) => { + var sign = get.sgnAttitude(_status.event.player, target); + return ( + 6 - + target + .getCards("ej") + .map((i) => { + var val = 0; + if (get.position(i) == "e") val = get.value(i, target); + else { + val = get.effect( + player, + { + name: i.viewAs || i.name, + cards: [i], + }, + target, + target + ); + } + return sign * val; + }) + .sort((a, b) => a - b)[0] + ); + }); + "step 4"; + if (result.bool) { + var targetx = result.targets[0]; + player.discardPlayerCard(targetx, "ej", true); + } else { + player.addTempSkill("olqiejian_ban", "roundStart"); + player.markAuto("olqiejian_ban", [target]); } - else{ - player.addTempSkill('olqiejian_ban','roundStart'); - player.markAuto('olqiejian_ban',[target]); - } - 'step 5' - if(targets.length) event.goto(1); + "step 5"; + if (targets.length) event.goto(1); + }, + subSkill: { + ban: { + onremove: true, + charlotte: true, + intro: { + content: "本轮不能再对$发动〖切谏〗", + }, + }, }, - subSkill:{ - ban:{ - onremove:true, - charlotte:true, - intro:{ - content:'本轮不能再对$发动〖切谏〗' - } - } - } }, - olnishou:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['loseAsyncAfter','equipAfter'], + olnishou: { + audio: 2, + trigger: { + player: "loseAfter", + global: ["loseAsyncAfter", "equipAfter"], }, - forced:true, - filter:function(event,player){ + forced: true, + filter: function (event, player) { var phaseName; - for(var name of lib.phaseName){ - var evt=event.getParent(name); - if(!evt||evt.name!=name) continue; - phaseName=name; + for (var name of lib.phaseName) { + var evt = event.getParent(name); + if (!evt || evt.name != name) continue; + phaseName = name; } - var cards=event.getd(player,'es'); - return cards.length&&(cards.some(card=>{ - if(get.position(card,true)!='d') return false; - return player.hasUseTarget(get.autoViewAs({name:'shandian'},[card])); - })||phaseName&&!player.hasSkill('olnishou_swap')); + var cards = event.getd(player, "es"); + return ( + cards.length && + (cards.some((card) => { + if (get.position(card, true) != "d") return false; + return player.hasUseTarget(get.autoViewAs({ name: "shandian" }, [card])); + }) || + (phaseName && !player.hasSkill("olnishou_swap"))) + ); }, - direct:true, - content:function(){ - 'step 0' - var cards=trigger.getd(player,'es'); - var choices=[]; - var choiceList=[ - '将'+(cards.length?get.translation(cards[0]):'这些牌中第一张能当【闪电】对你使用的牌')+'当【闪电】使用', - '本阶段结束时,你与一名手牌数最少的角色交换手牌' + direct: true, + content: function () { + "step 0"; + var cards = trigger.getd(player, "es"); + var choices = []; + var choiceList = [ + "将" + + (cards.length + ? get.translation(cards[0]) + : "这些牌中第一张能当【闪电】对你使用的牌") + + "当【闪电】使用", + "本阶段结束时,你与一名手牌数最少的角色交换手牌", ]; - cards=cards.filter(card=>{ - if(get.position(card,true)!='d') return false; - return player.hasUseTarget(get.autoViewAs({name:'shandian'},[card])); + cards = cards.filter((card) => { + if (get.position(card, true) != "d") return false; + return player.hasUseTarget(get.autoViewAs({ name: "shandian" }, [card])); }); - event.cards=cards; + event.cards = cards; var phaseName; - for(var name of lib.phaseName){ - var evt=trigger.getParent(name); - if(!evt||evt.name!=name) continue; - phaseName=name; + for (var name of lib.phaseName) { + var evt = trigger.getParent(name); + if (!evt || evt.name != name) continue; + phaseName = name; } - if(cards.length) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(phaseName&&!player.hasSkill('olnishou_swap')) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - event.phaseName=phaseName; - if(!choices.length) event.finish(); - else player.chooseControl(choices).set('choiceList',choiceList).set('prompt','泥首:选择一项').set('ai',()=>0); - 'step 1' - player.logSkill('olnishou'); - game.log(player,'选择了','#y'+result.control); - if(result.control=='选项一'){ - var card=cards[0]; - player.chooseUseTarget({name:'shandian'},[card],true); - } - else{ - var name=event.phaseName; - player.storage.olnishou_swap=name; - player.addTempSkill('olnishou_swap',name+'After'); + if (cards.length) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (phaseName && !player.hasSkill("olnishou_swap")) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + event.phaseName = phaseName; + if (!choices.length) event.finish(); + else + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", "泥首:选择一项") + .set("ai", () => 0); + "step 1"; + player.logSkill("olnishou"); + game.log(player, "选择了", "#y" + result.control); + if (result.control == "选项一") { + var card = cards[0]; + player.chooseUseTarget({ name: "shandian" }, [card], true); + } else { + var name = event.phaseName; + player.storage.olnishou_swap = name; + player.addTempSkill("olnishou_swap", name + "After"); } }, - subSkill:{ - swap:{ - audio:'olnishou', - charlotte:true, - forced:true, - direct:true, - onremove:true, - trigger:{global:['phaseZhunbeiEnd','phaseJudgeEnd','phaseDrawEnd','phaseUseEnd','phaseDiscardEnd','phaseJieshuEnd']}, - content:function(){ - 'step 0' - if(trigger.name!=player.storage.olnishou_swap||!event.player.isIn()){ - player.removeSkill('olnishou_swap'); - event.finish(); return; + subSkill: { + swap: { + audio: "olnishou", + charlotte: true, + forced: true, + direct: true, + onremove: true, + trigger: { + global: [ + "phaseZhunbeiEnd", + "phaseJudgeEnd", + "phaseDrawEnd", + "phaseUseEnd", + "phaseDiscardEnd", + "phaseJieshuEnd", + ], + }, + content: function () { + "step 0"; + if (trigger.name != player.storage.olnishou_swap || !event.player.isIn()) { + player.removeSkill("olnishou_swap"); + event.finish(); + return; } - player.chooseTarget('泥首:与一名手牌数最少的角色交换手牌',true,(card,player,target)=>{ - return target.isMinHandcard(); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('olnishou_swap',target); - if(target!=player){ + player.chooseTarget( + "泥首:与一名手牌数最少的角色交换手牌", + true, + (card, player, target) => { + return target.isMinHandcard(); + } + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("olnishou_swap", target); + if (target != player) { player.swapHandcards(target); } } - 'step 2' - player.removeSkill('olnishou_swap'); - } - } - } + "step 2"; + player.removeSkill("olnishou_swap"); + }, + }, + }, }, //马承 - olchenglie:{ - audio:2, - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current); + olchenglie: { + audio: 2, + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current); }); }, - direct:true, - shaRelated:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olchenglie'),'为'+get.translation(trigger.card)+'多指定至多两个目标,并发动后续效果',[1,2],(card,player,target)=>{ - var evt=_status.event.getTrigger(); - return !evt.targets.includes(target)&&player.canUse(evt.card,target); - }).set('ai',function(target){ - var player=_status.event.player,evt=_status.event.getTrigger(); - return get.effect(target,evt.card,player,player); - }); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else event.finish(); - 'step 2' - player.logSkill('olchenglie',targets); + direct: true, + shaRelated: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olchenglie"), + "为" + get.translation(trigger.card) + "多指定至多两个目标,并发动后续效果", + [1, 2], + (card, player, target) => { + var evt = _status.event.getTrigger(); + return !evt.targets.includes(target) && player.canUse(evt.card, target); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + evt = _status.event.getTrigger(); + return get.effect(target, evt.card, player, player); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else event.finish(); + "step 2"; + player.logSkill("olchenglie", targets); trigger.targets.addArray(targets); - var targets=trigger.targets; - event.targets=targets; - event.given=[]; - var cards=get.cards(targets.length); - event.cards=cards.slice(); - player.showCards(event.cards,get.translation(player)+'发动了【骋烈】'); - while(cards.length) ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); - 'step 3' + var targets = trigger.targets; + event.targets = targets; + event.given = []; + var cards = get.cards(targets.length); + event.cards = cards.slice(); + player.showCards(event.cards, get.translation(player) + "发动了【骋烈】"); + while (cards.length) ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); + "step 3"; game.updateRoundNumber(); - var hs=player.getCards('h'); - var next=player.chooseToMove('骋烈:是否交换一张牌?'); - next.set('list',[ - ['〖骋烈〗展示',event.cards,'olchenglie'], - ['你的手牌',hs], + var hs = player.getCards("h"); + var next = player.chooseToMove("骋烈:是否交换一张牌?"); + next.set("list", [ + ["〖骋烈〗展示", event.cards, "olchenglie"], + ["你的手牌", hs], ]); - next.set('filterMove',function(from,to,moved){ - if(typeof to=='number') return false; - var player=_status.event.player; - var hs=player.getCards('h'); - var changed=hs.filter(function(card){ + next.set("filterMove", function (from, to, moved) { + if (typeof to == "number") return false; + var player = _status.event.player; + var hs = player.getCards("h"); + var changed = hs.filter(function (card) { return !moved[1].includes(card); }); - var changed2=moved[1].filter(function(card){ + var changed2 = moved[1].filter(function (card) { return !hs.includes(card); }); - if(changed.length<1) return true; - var pos1=(moved[0].includes(from.link)?0:1),pos2=(moved[0].includes(to.link)?0:1); - if(pos1==pos2) return true; - if(pos1==0){ - if(changed.includes(from.link)) return true; + if (changed.length < 1) return true; + var pos1 = moved[0].includes(from.link) ? 0 : 1, + pos2 = moved[0].includes(to.link) ? 0 : 1; + if (pos1 == pos2) return true; + if (pos1 == 0) { + if (changed.includes(from.link)) return true; return changed2.includes(to.link); } - if(changed2.includes(from.link)) return true; + if (changed2.includes(from.link)) return true; return changed.includes(to.link); }); - next.set('processAI',function(list){ - var cards1=list[0][1].slice(),cards2=list[1][1].slice(); - var card1=cards1.sort((a,b)=>get.value(b)-get.value(a))[0]; - var card2=cards2.sort((a,b)=>get.value(a)-get.value(b))[0]; - if(card1&&card2&&get.value(card1)>get.value(card2)){ + next.set("processAI", function (list) { + var cards1 = list[0][1].slice(), + cards2 = list[1][1].slice(); + var card1 = cards1.sort((a, b) => get.value(b) - get.value(a))[0]; + var card2 = cards2.sort((a, b) => get.value(a) - get.value(b))[0]; + if (card1 && card2 && get.value(card1) > get.value(card2)) { cards1.remove(card1); cards2.remove(card2); cards1.push(card2); cards2.push(card1); } - return [cards1,cards2]; + return [cards1, cards2]; }); - 'step 4' - var moved=result.moved; - var hs=player.getCards('h'),ts=event.cards; - var card1,card2; - for(var i of moved[0]){ - if(!ts.includes(i)) card1=i; + "step 4"; + var moved = result.moved; + var hs = player.getCards("h"), + ts = event.cards; + var card1, card2; + for (var i of moved[0]) { + if (!ts.includes(i)) card1 = i; } - for(var i of moved[1]){ - if(!hs.includes(i)) card2=i; + for (var i of moved[1]) { + if (!hs.includes(i)) card2 = i; } - if(card1&&card2){ - player.$throw(1,1000); - event.cards.forEach((i,ind,arr)=>{ - if(i==card2) arr[ind]=card1; - }) - player.lose(card1,ui.cardPile).set('insert_index',event=>event.cardx).set('cardx',card2); - player.gain(card2,'draw'); - game.log(player,'交换了一张牌'); + if (card1 && card2) { + player.$throw(1, 1000); + event.cards.forEach((i, ind, arr) => { + if (i == card2) arr[ind] = card1; + }); + player + .lose(card1, ui.cardPile) + .set("insert_index", (event) => event.cardx) + .set("cardx", card2); + player.gain(card2, "draw"); + game.log(player, "交换了一张牌"); } - 'step 5' + "step 5"; game.cardsGotoOrdering(event.cards); - 'step 6' - if(event.cards.length==1) event._result={bool:true,links:event.cards}; - else player.chooseButton(['骋烈:将这些牌置于目标角色的武将牌上',event.cards],true); + "step 6"; + if (event.cards.length == 1) event._result = { bool: true, links: event.cards }; + else player.chooseButton(["骋烈:将这些牌置于目标角色的武将牌上", event.cards], true); game.updateRoundNumber(); - 'step 7' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('将'+get.translation(card)+'置于一名目标角色的武将牌上',true,(card,player,target)=>{ - return _status.event.getTrigger().targets.includes(target)&&!_status.event.getParent().given.includes(target); - }).set('ai',target=>{ - var color=_status.event.color,player=_status.event.player; - var evt=_status.event.getTrigger(); - if(color=='red'){ - var eff=get.effect(target,evt.card,player,target),att=get.attitude(player,target); - if(eff>=0&&att<0) return -1; - if(eff<0&&att<0&&target.hasCard(card=>['shan','caochuan'].includes(get.name(card)),'hs')) return 10; - } - return 1; - }).set('color',get.color(card)); - } - else event.finish(); - 'step 8' - if(result.bool){ - var target=result.targets[0]; + "step 7"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + "将" + get.translation(card) + "置于一名目标角色的武将牌上", + true, + (card, player, target) => { + return ( + _status.event.getTrigger().targets.includes(target) && + !_status.event.getParent().given.includes(target) + ); + } + ) + .set("ai", (target) => { + var color = _status.event.color, + player = _status.event.player; + var evt = _status.event.getTrigger(); + if (color == "red") { + var eff = get.effect(target, evt.card, player, target), + att = get.attitude(player, target); + if (eff >= 0 && att < 0) return -1; + if ( + eff < 0 && + att < 0 && + target.hasCard( + (card) => ["shan", "caochuan"].includes(get.name(card)), + "hs" + ) + ) + return 10; + } + return 1; + }) + .set("color", get.color(card)); + } else event.finish(); + "step 8"; + if (result.bool) { + var target = result.targets[0]; player.line(target); event.given.push(target); - target.addToExpansion(card).gaintag.add('olchenglie'); - player.addTempSkill('olchenglie_effect','phaseUseAfter'); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.olchenglie=player; - target.storage.olchenglie_viewer=player; + target.addToExpansion(card).gaintag.add("olchenglie"); + player.addTempSkill("olchenglie_effect", "phaseUseAfter"); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.olchenglie = player; + target.storage.olchenglie_viewer = player; event.cards.remove(card); - var cardx=player==game.me||player.isUnderControl()?card:1; - player.$give(cardx,target,false); - } - else event.finish(); - 'step 9' - if(event.cards.length) event.goto(6); - else if(!event.isMine()&&!event.isOnline()) game.delayx(); + var cardx = player == game.me || player.isUnderControl() ? card : 1; + player.$give(cardx, target, false); + } else event.finish(); + "step 9"; + if (event.cards.length) event.goto(6); + else if (!event.isMine() && !event.isOnline()) game.delayx(); }, - marktext:'骋', - intro:{ - markcount:'expansion', - mark:function(dialog,content,player){ - var content=player.getExpansions('olchenglie'); - if(content&&content.length){ - if(game.me==player.storage.olchenglie_viewer){ + marktext: "骋", + intro: { + markcount: "expansion", + mark: function (dialog, content, player) { + var content = player.getExpansions("olchenglie"); + if (content && content.length) { + if (game.me == player.storage.olchenglie_viewer) { dialog.addAuto(content); - } - else{ - return '有'+get.cnNumber(content.length)+'张扣置的“骋烈”牌'; + } else { + return "有" + get.cnNumber(content.length) + "张扣置的“骋烈”牌"; } } }, - content:function(content,player){ - var content=player.getExpansions('olchenglie'); - if(content&&content.length){ - if(game.me==player.storage.olchenglie_viewer){ + content: function (content, player) { + var content = player.getExpansions("olchenglie"); + if (content && content.length) { + if (game.me == player.storage.olchenglie_viewer) { return get.translation(content); } - return '有'+get.cnNumber(content.length)+'张扣置的“骋烈”牌'; + return "有" + get.cnNumber(content.length) + "张扣置的“骋烈”牌"; } - } + }, }, - subSkill:{ - effect:{ - trigger:{global:'useCardAfter'}, - forced:true, - charlotte:true, - forceDie:true, - popup:false, - filter:function(event,player){ - return event.card.storage&&event.card.storage.olchenglie; + subSkill: { + effect: { + trigger: { global: "useCardAfter" }, + forced: true, + charlotte: true, + forceDie: true, + popup: false, + filter: function (event, player) { + return event.card.storage && event.card.storage.olchenglie; }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - var cards=current.getExpansions('olchenglie'); - return cards.some(i=>get.color(i,false)=='red'); - }).sortBySeat(); - event.targets=targets; - var togive=trigger.card.storage.olchenglie; - event.togive=togive; - if(!targets.length||!togive.isIn()) event.goto(3); - 'step 1' - var target=event.targets.shift(); - event.target=target; + content: function () { + "step 0"; + var targets = game + .filterPlayer((current) => { + var cards = current.getExpansions("olchenglie"); + return cards.some((i) => get.color(i, false) == "red"); + }) + .sortBySeat(); + event.targets = targets; + var togive = trigger.card.storage.olchenglie; + event.togive = togive; + if (!targets.length || !togive.isIn()) event.goto(3); + "step 1"; + var target = event.targets.shift(); + event.target = target; player.line(target); - if(target.hasHistory('useCard',evt=>{ - return evt.respondTo&&evt.respondTo[1]==trigger.card; - })){ - if(target.countCards('he')) target.chooseCard('骋烈:交给'+get.translation(event.togive)+'一张牌',true,'he'); - } - else{ + if ( + target.hasHistory("useCard", (evt) => { + return evt.respondTo && evt.respondTo[1] == trigger.card; + }) + ) { + if (target.countCards("he")) + target.chooseCard( + "骋烈:交给" + get.translation(event.togive) + "一张牌", + true, + "he" + ); + } else { target.recover(); } - 'step 2' - if(result.bool){ - target.give(result.cards,event.togive); + "step 2"; + if (result.bool) { + target.give(result.cards, event.togive); } - if(targets.length) event.goto(1); - 'step 3' - game.filterPlayer(current=>{ - var cards=current.getExpansions('olchenglie'); + if (targets.length) event.goto(1); + "step 3"; + game.filterPlayer((current) => { + var cards = current.getExpansions("olchenglie"); return cards.length; - }).forEach(i=>{ - i.loseToDiscardpile(i.getExpansions('olchenglie')); + }).forEach((i) => { + i.loseToDiscardpile(i.getExpansions("olchenglie")); delete i.storage.olchenglie_viewer; }); - } - } + }, + }, }, }, //新贺齐 - olqizhou:{ - audio:'qizhou', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter','phaseBefore'], + olqizhou: { + audio: "qizhou", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + "phaseBefore", + ], }, - forced:true, - onremove:true, - filter:function(event,player){ - if(event.name!='phase'&&(event.name!='equip'||event.player!=player)){ - var evt=event.getl(player); - if(!evt||!evt.es||!evt.es.length) return false; + forced: true, + onremove: true, + filter: function (event, player) { + if (event.name != "phase" && (event.name != "equip" || event.player != player)) { + var evt = event.getl(player); + if (!evt || !evt.es || !evt.es.length) return false; } - var num=player.countMark('olqizhou'); - return lib.skill.olqizhou.getSuitNum(player)!=num; + var num = player.countMark("olqizhou"); + return lib.skill.olqizhou.getSuitNum(player) != num; }, - content:function(){ + content: function () { lib.skill.olqizhou.applyChange(player); }, - getSuitNum:function(player){ - var suits=[],es=player.getCards('e'); - for(var i of es) suits.add(get.suit(i,player)); - return Math.min(4,suits.length); + getSuitNum: function (player) { + var suits = [], + es = player.getCards("e"); + for (var i of es) suits.add(get.suit(i, player)); + return Math.min(4, suits.length); }, - applyChange:function(player){ - player.removeAdditionalSkill('olqizhou'); - var num=lib.skill.olqizhou.getSuitNum(player); - player.storage.olqizhou=num; - if(num>0) player.addAdditionalSkill('olqizhou',lib.skill.olqizhou.derivation.slice(0,num)); + applyChange: function (player) { + player.removeAdditionalSkill("olqizhou"); + var num = lib.skill.olqizhou.getSuitNum(player); + player.storage.olqizhou = num; + if (num > 0) + player.addAdditionalSkill("olqizhou", lib.skill.olqizhou.derivation.slice(0, num)); }, - derivation:['reduanbing','reyingzi','fenwei','lanjiang'], + derivation: ["reduanbing", "reyingzi", "fenwei", "lanjiang"], }, - olshanxi:{ - audio:'shanxi', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('e')<5&&game.hasPlayer((current)=>lib.skill.olshanxi.filterTarget(null,player,current)); + olshanxi: { + audio: "shanxi", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("e") < 5 && + game.hasPlayer((current) => lib.skill.olshanxi.filterTarget(null, player, current)) + ); }, - filterTarget:function(card,player,target){ - return (target!=player&&player.countCards('h')+target.countCards('h')>0&&!player.inRangeOf(target)); + filterTarget: function (card, player, target) { + return ( + target != player && + player.countCards("h") + target.countCards("h") > 0 && + !player.inRangeOf(target) + ); }, - content:function(){ - 'step 0' - var cards1=player.getCards('h'),cards2=target.getCards('h'); - var num=5-player.countCards('e'); - var dialog=['闪袭:选择展示至多'+get.cnNumber(num)+'张牌']; - if(cards1.length>0){ + content: function () { + "step 0"; + var cards1 = player.getCards("h"), + cards2 = target.getCards("h"); + var num = 5 - player.countCards("e"); + var dialog = ["闪袭:选择展示至多" + get.cnNumber(num) + "张牌"]; + if (cards1.length > 0) { dialog.push('
              你的手牌
              '); dialog.push(cards1); } - if(cards2.length>0){ - dialog.push('
              '+get.translation(target)+'的手牌
              '); - if(player.hasSkillTag('viewHandcard',null,target,true)) dialog.push(cards2); - else dialog.push([cards2.randomSort(),'blank']); + if (cards2.length > 0) { + dialog.push('
              ' + get.translation(target) + "的手牌
              "); + if (player.hasSkillTag("viewHandcard", null, target, true)) dialog.push(cards2); + else dialog.push([cards2.randomSort(), "blank"]); } - player.chooseButton(dialog,[1,num],true).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getParent().target; - var card=button.link,cards=ui.selected.buttons.map(button=>button.link); - var hs=player.getCards('h'),discard=false; - for(var i of cards){ - if(hs.includes(i)){ - discard=true; + player.chooseButton(dialog, [1, num], true).set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getParent().target; + var card = button.link, + cards = ui.selected.buttons.map((button) => button.link); + var hs = player.getCards("h"), + discard = false; + for (var i of cards) { + if (hs.includes(i)) { + discard = true; break; } } - if(hs.includes(card)){ - if(discard||get.name(card)!='shan') return 0; - if(target.hasCard(card=>get.value(card,target)>5,'e')) return 2; + if (hs.includes(card)) { + if (discard || get.name(card) != "shan") return 0; + if (target.hasCard((card) => get.value(card, target) > 5, "e")) return 2; return 0; } - if(discard&&!target.hasCard(function(cardx){ - return cardx!=card&&!cards.includes(cardx)&&get.value(cardx,target)>0; - },'he')) return 0; - return 1+Math.random(); + if ( + discard && + !target.hasCard(function (cardx) { + return ( + cardx != card && !cards.includes(cardx) && get.value(cardx, target) > 0 + ); + }, "he") + ) + return 0; + return 1 + Math.random(); }); - 'step 1' - if(result.bool){ - event.cards=result.links; - var list1=[],list2=[]; - var hs=player.getCards('h'); - for(var card of result.links){ - if(hs.includes(card)){ + "step 1"; + if (result.bool) { + event.cards = result.links; + var list1 = [], + list2 = []; + var hs = player.getCards("h"); + for (var card of result.links) { + if (hs.includes(card)) { list1.push(card); - } - else{ + } else { list2.push(card); } } - event.list1=list1; - event.list2=list2; - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,target,list1,list2,id){ - var dialog=ui.create.dialog(player+'对'+target+'发动了【闪袭】'); - dialog.videoId=id; - if(list1.length>0){ - dialog.add('
              '+player+'展示的牌
              '); - dialog.add(list1); - } - if(list2.length>0){ - dialog.add('
              '+target+'被展示的牌
              '); - dialog.add(list2); - } - },get.translation(player),get.translation(target),list1,list2,event.videoId) + event.list1 = list1; + event.list2 = list2; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, target, list1, list2, id) { + var dialog = ui.create.dialog(player + "对" + target + "发动了【闪袭】"); + dialog.videoId = id; + if (list1.length > 0) { + dialog.add('
              ' + player + "展示的牌
              "); + dialog.add(list1); + } + if (list2.length > 0) { + dialog.add('
              ' + target + "被展示的牌
              "); + dialog.add(list2); + } + }, + get.translation(player), + get.translation(target), + list1, + list2, + event.videoId + ); game.delay(4); - } - else event.finish(); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - var list1=event.list1.filter((card)=>get.name(card,player)=='shan'); - var list2=event.list2.filter((card)=>get.name(card,target)=='shan'); - if(list1.length&&list2.length){ + } else event.finish(); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + var list1 = event.list1.filter((card) => get.name(card, player) == "shan"); + var list2 = event.list2.filter((card) => get.name(card, target) == "shan"); + if (list1.length && list2.length) { game.loseAsync({ - lose_list:[ - [player,list1], - [target,list2] + lose_list: [ + [player, list1], + [target, list2], ], - discarder:player, - }).setContent('discardMultiple'); - } - else if(list2.length){ + discarder: player, + }).setContent("discardMultiple"); + } else if (list2.length) { target.discard(list2); - } - else if(list1.length) player.discard(list1); + } else if (list1.length) player.discard(list1); else event.finish(); - 'step 3' - if(target.hasCard(function(card){ - return !cards.includes(card)&&lib.filter.canBeGained(card,player,target); - },'he')) player.gainPlayerCard(target,true,'he').set('filterButton',function(button){ - return !_status.event.cards.includes(button.link); - }).set('cards',cards); + "step 3"; + if ( + target.hasCard(function (card) { + return !cards.includes(card) && lib.filter.canBeGained(card, player, target); + }, "he") + ) + player + .gainPlayerCard(target, true, "he") + .set("filterButton", function (button) { + return !_status.event.cards.includes(button.link); + }) + .set("cards", cards); }, - ai:{ - order:14, - result:{ - target:function(player,target){ - return -target.countCards('h'); + ai: { + order: 14, + result: { + target: function (player, target) { + return -target.countCards("h"); }, }, }, }, //刘巴 - oltongduo:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('oltongduo'),function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return Math.sqrt(att)/10; - return 5-att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('oltongduo',target); - target.chooseCard('h',true,'统度:将一张手牌交给'+get.translation(player)+',然后其于此阶段结束时将此牌置于牌堆顶'); - } - else{ + oltongduo: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("oltongduo"), function (card, player, target) { + return target != player && target.countCards("h") > 0; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return Math.sqrt(att) / 10; + return 5 - att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("oltongduo", target); + target.chooseCard( + "h", + true, + "统度:将一张手牌交给" + + get.translation(player) + + ",然后其于此阶段结束时将此牌置于牌堆顶" + ); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.addTempSkill('oltongduo_put'); - event.target.give(result.cards,player,true).gaintag.add('oltongduo'); + "step 2"; + if (result.bool) { + player.addTempSkill("oltongduo_put"); + event.target.give(result.cards, player, true).gaintag.add("oltongduo"); } }, - subSkill:{ - put:{ - trigger:{player:'phaseUseEnd'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player.hasCard(card=>card.hasGaintag('oltongduo'),'h'); + subSkill: { + put: { + trigger: { player: "phaseUseEnd" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return player.hasCard((card) => card.hasGaintag("oltongduo"), "h"); }, - content:function(){ - var cards=player.getCards('h',card=>card.hasGaintag('oltongduo')); - player.lose(cards,ui.cardPile,'insert'); - game.log(player,'将',get.cnNumber(cards.length)+'张牌','置于牌堆顶'); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },player); + content: function () { + var cards = player.getCards("h", (card) => card.hasGaintag("oltongduo")); + player.lose(cards, ui.cardPile, "insert"); + game.log(player, "将", get.cnNumber(cards.length) + "张牌", "置于牌堆顶"); + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, player); }, - onremove:function(player){ - player.removeGaintag('oltongduo'); + onremove: function (player) { + player.removeGaintag("oltongduo"); }, - } - } + }, + }, }, - olzhubi:{ - audio:2, - enable:'phaseUse', - group:'olzhubi_replace', - filter:function(event,player){ - return (player.getStat('skill').olzhubi||0)0; + filterTarget: function (card, player, target) { + return target.countCards("he") > 0; }, - content:function(){ - 'step 0' - target.chooseCard('he',true,'铸币:请重铸一张牌',lib.filter.cardRecastable); - 'step 1' - if(result.bool){ - target.recast(result.cards,null,player=>player.draw().set('log',false).gaintag=['olzhubi_tag']); + content: function () { + "step 0"; + target.chooseCard("he", true, "铸币:请重铸一张牌", lib.filter.cardRecastable); + "step 1"; + if (result.bool) { + target.recast( + result.cards, + null, + (player) => (player.draw().set("log", false).gaintag = ["olzhubi_tag"]) + ); } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - if(target.hasCard(card=>card.hasGaintag('olzhubi_tag'),'h')) return 0.5; + ai: { + order: 6, + result: { + target: function (player, target) { + if (target.hasCard((card) => card.hasGaintag("olzhubi_tag"), "h")) return 0.5; return 1; - } - } - }, - subSkill:{ - replace:{ - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player.hasCard(card=>card.hasGaintag('olzhubi_tag'),'h'); }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ - 'step 0' - var cards=get.bottomCards(5); - event.cards2=cards; + }, + }, + subSkill: { + replace: { + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return event.player.hasCard((card) => card.hasGaintag("olzhubi_tag"), "h"); + }, + forced: true, + locked: false, + logTarget: "player", + content: function () { + "step 0"; + var cards = get.bottomCards(5); + event.cards2 = cards; game.cardsGotoOrdering(cards); - var player=trigger.player; - var next=player.chooseToMove('铸币:用任意“币”交换牌堆底等量张牌'); - var hs=player.getCards('h',card=>card.hasGaintag('olzhubi_tag')); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + var player = trigger.player; + var next = player.chooseToMove("铸币:用任意“币”交换牌堆底等量张牌"); + var hs = player.getCards("h", (card) => card.hasGaintag("olzhubi_tag")); + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('list',[ - ['牌堆底',cards], - ['你的手牌',hs,'olzhubi_tag'] + next.set("list", [ + ["牌堆底", cards], + ["你的手牌", hs, "olzhubi_tag"], ]); - next.set('processAI',function(list){ - var all=list[0][1].concat(list[1][1]),cards=all.slice(0); - var num=_status.event.num; - cards.sort(function(a,b){ - return get.value(b)-get.value(a); + next.set("processAI", function (list) { + var all = list[0][1].concat(list[1][1]), + cards = all.slice(0); + var num = _status.event.num; + cards.sort(function (a, b) { + return get.value(b) - get.value(a); }); - return [cards.slice(num),cards.slice(0,num)]; + return [cards.slice(num), cards.slice(0, num)]; }); - next.set('num',hs.length); - 'step 1' - if(result.bool){ - event.forceDie=true; - var cards=result.moved[0]; - event.cards=cards; - var player=trigger.player; - var hs=player.getCards('h'); - var lose=[],gain=event.cards2; - for(var i of cards){ - if(hs.includes(i)) lose.push(i); + next.set("num", hs.length); + "step 1"; + if (result.bool) { + event.forceDie = true; + var cards = result.moved[0]; + event.cards = cards; + var player = trigger.player; + var hs = player.getCards("h"); + var lose = [], + gain = event.cards2; + for (var i of cards) { + if (hs.includes(i)) lose.push(i); else gain.remove(i); } - if(lose.length) player.lose(lose,ui.cardPile); - if(gain.length) player.gain(gain,'draw'); - } - else event.finish(); - 'step 2' - for(var i of cards){ - if(!(('hejsdx').includes(get.position(i,true)))){ + if (lose.length) player.lose(lose, ui.cardPile); + if (gain.length) player.gain(gain, "draw"); + } else event.finish(); + "step 2"; + for (var i of cards) { + if (!"hejsdx".includes(get.position(i, true))) { i.fix(); ui.cardPile.appendChild(i); } } game.updateRoundNumber(); - } + }, }, - } + }, }, //傅肜 - olxiaosi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('h')>0&&player!=target; + olxiaosi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0 && player != target; }, - filterCard:function(card,player,target){ - return get.type(card)=='basic'; + filterCard: function (card, player, target) { + return get.type(card) == "basic"; }, - check:function(card){ - var player=_status.event.player; - if(player.hasValueTarget(card)) return 10-get.value(card); + check: function (card) { + var player = _status.event.player; + if (player.hasValueTarget(card)) return 10 - get.value(card); return 0.1; }, - content:function(){ - 'step 0' - if(target.countCards('h',card=>{ - return get.type(card)=='basic'&&lib.filter.cardDiscardable(card,target,'olxiaosi'); - })==0) event.draw=true; - else{ - target.chooseToDiscard('h',true,'效死:弃置一张基本牌',{type:'basic'}); + content: function () { + "step 0"; + if ( + target.countCards("h", (card) => { + return ( + get.type(card) == "basic" && + lib.filter.cardDiscardable(card, target, "olxiaosi") + ); + }) == 0 + ) + event.draw = true; + else { + target.chooseToDiscard("h", true, "效死:弃置一张基本牌", { type: "basic" }); } - 'step 1' - var cards2=cards.slice(0); - if(result.bool){ - cards2=cards2.addArray(result.cards); + "step 1"; + var cards2 = cards.slice(0); + if (result.bool) { + cards2 = cards2.addArray(result.cards); } - event.cards2=cards2; - 'step 2' - var cardsx=event.cards2.filter(i=>get.position(i,true)=='d'&&player.hasUseTarget(i,false)); - if(!cardsx.length) event.goto(5); - else player.chooseButton(['效死:是否使用其中的一张牌?',cardsx]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link,false); - }).set('ai',button=>{ - if(button.link.name=='jiu') return 10; - return _status.event.player.getUseValue(button.link); - }); - 'step 3' - if(result.bool){ - var card=result.links[0]; + event.cards2 = cards2; + "step 2"; + var cardsx = event.cards2.filter( + (i) => get.position(i, true) == "d" && player.hasUseTarget(i, false) + ); + if (!cardsx.length) event.goto(5); + else + player + .chooseButton(["效死:是否使用其中的一张牌?", cardsx]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link, false); + }) + .set("ai", (button) => { + if (button.link.name == "jiu") return 10; + return _status.event.player.getUseValue(button.link); + }); + "step 3"; + if (result.bool) { + var card = result.links[0]; event.cards2.remove(card); - player.$gain2(card,false); + player.$gain2(card, false); game.delayx(); - player.chooseUseTarget(true,card,false,'nodistance'); - } - else event.goto(5); - 'step 4' - if(event.cards2.filter(i=>get.position(i,true)=='d'&&player.hasUseTarget(i,false)).length) event.goto(2); - 'step 5' - if(event.draw) player.draw(); + player.chooseUseTarget(true, card, false, "nodistance"); + } else event.goto(5); + "step 4"; + if ( + event.cards2.filter( + (i) => get.position(i, true) == "d" && player.hasUseTarget(i, false) + ).length + ) + event.goto(2); + "step 5"; + if (event.draw) player.draw(); + }, + ai: { + order: 4.5, + result: { + player: 1, + target: -1, + }, }, - ai:{ - order:4.5, - result:{ - player:1, - target:-1 - } - } }, //阿会喃 - jueman:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - direct:true, - filter:function(event,player){ - var history=game.getGlobalHistory('useCard',evt=>{ - return get.type(evt.card)=='basic'; + jueman: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + direct: true, + filter: function (event, player) { + var history = game.getGlobalHistory("useCard", (evt) => { + return get.type(evt.card) == "basic"; }); - if(history.length<2) return false; - var users=history.slice(0,2).map(i=>i.player); - var list=users.filter(user=>user==player); - if(list.length==1) return true; - if(list.length==0){ - var evtx=history[2]; - if(evtx){ - var name=evtx.card.name,nature=evtx.card.nature; - if(evtx&&player.hasUseTarget({name:name,nature:nature,isCard:true})) return true; + if (history.length < 2) return false; + var users = history.slice(0, 2).map((i) => i.player); + var list = users.filter((user) => user == player); + if (list.length == 1) return true; + if (list.length == 0) { + var evtx = history[2]; + if (evtx) { + var name = evtx.card.name, + nature = evtx.card.nature; + if (evtx && player.hasUseTarget({ name: name, nature: nature, isCard: true })) + return true; } } return false; }, - content:function(){ - 'step 0' - var history=game.getGlobalHistory('useCard',evt=>{ - return get.type(evt.card)=='basic'; + content: function () { + "step 0"; + var history = game.getGlobalHistory("useCard", (evt) => { + return get.type(evt.card) == "basic"; }); - var list=history.slice(0,2).map(i=>i.player).filter(user=>user==player); - if(list.length==1) { - player.logSkill('jueman'); + var list = history + .slice(0, 2) + .map((i) => i.player) + .filter((user) => user == player); + if (list.length == 1) { + player.logSkill("jueman"); player.draw(); + } else if (list.length == 0) { + var evtx = history[2], + name = evtx.card.name, + nature = evtx.card.nature; + player + .chooseUseTarget({ name: name, nature: nature, isCard: true }, true) + .set("logSkill", "jueman"); } - else if(list.length==0){ - var evtx=history[2],name=evtx.card.name,nature=evtx.card.nature; - player.chooseUseTarget({name:name,nature:nature,isCard:true},true).set('logSkill','jueman'); - } - } + }, }, //张芝 - olbixin:{ - audio:2, - trigger:{ - global:['phaseZhunbeiBegin','phaseJieshuBegin'], + olbixin: { + audio: 2, + trigger: { + global: ["phaseZhunbeiBegin", "phaseJieshuBegin"], }, - direct:true, - onremove:['olbixin','olbixin_basic','olbixin_trick','olbixin_equip'], - group:'olbixin_full', - map:{基本:'basic',锦囊:'trick',装备:'equip'}, - filter:function(event,player){ - var count=player.countMark('olbixin'); - if(count>0&&event.player!=player) return false; - if(count>1&&event.name=='phaseZhunbei') return false; - if(count>2) return false; - var num=count>=3?3:1; - var types=['basic','trick','equip'].filter(type=>{ - return player.countMark('olbixin_'+type) 0 && event.player != player) return false; + if (count > 1 && event.name == "phaseZhunbei") return false; + if (count > 2) return false; + var num = count >= 3 ? 3 : 1; + var types = ["basic", "trick", "equip"].filter((type) => { + return player.countMark("olbixin_" + type) < num; }); - if(!types.length) return false; - return lib.skill.olbixin.getList(player).length>0; + if (!types.length) return false; + return lib.skill.olbixin.getList(player).length > 0; }, - getList:function(player,event){ - var natures=lib.inpile_nature.slice(0),used=[]; - var history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - var info=history[i]; - for(var evt of info.useCard){ - var name=evt.card.name; - if(get.type(name)!='basic') continue; - if(name=='sha'){ - if(evt.card.nature) natures.remove(evt.card.nature); + getList: function (player, event) { + var natures = lib.inpile_nature.slice(0), + used = []; + var history = player.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + var info = history[i]; + for (var evt of info.useCard) { + var name = evt.card.name; + if (get.type(name) != "basic") continue; + if (name == "sha") { + if (evt.card.nature) natures.remove(evt.card.nature); else used.push(name); - } - else used.push(name); + } else used.push(name); } - if(info.isRound) break; + if (info.isRound) break; } - var vcards=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(!event){ - if(name=='sha'){ - if(!used.includes('sha')&&player.hasUseTarget({name:'sha'})) vcards.push(['基本','','sha']); - for(var nature of natures) { - if(player.hasUseTarget({name:'sha',nature:nature})) vcards.push(['基本','','sha',nature]); + var vcards = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (!event) { + if (name == "sha") { + if (!used.includes("sha") && player.hasUseTarget({ name: "sha" })) + vcards.push(["基本", "", "sha"]); + for (var nature of natures) { + if (player.hasUseTarget({ name: "sha", nature: nature })) + vcards.push(["基本", "", "sha", nature]); } - } - else if(!used.includes(name)&&player.hasUseTarget({name:name})) vcards.push(['基本','',name]); - } - else{ - if(name=='sha'){ - if(!used.includes('sha')&&event.filterCard({name:'sha'},player,event)) vcards.push(['基本','','sha']); - for(var nature of natures) { - if(event.filterCard({name:'sha',nature:nature},player,event)) vcards.push(['基本','','sha',nature]); + } else if (!used.includes(name) && player.hasUseTarget({ name: name })) + vcards.push(["基本", "", name]); + } else { + if (name == "sha") { + if (!used.includes("sha") && event.filterCard({ name: "sha" }, player, event)) + vcards.push(["基本", "", "sha"]); + for (var nature of natures) { + if (event.filterCard({ name: "sha", nature: nature }, player, event)) + vcards.push(["基本", "", "sha", nature]); } - } - else if(!used.includes(name)&&event.filterCard({name:name},player,event)) vcards.push(['基本','',name]); + } else if ( + !used.includes(name) && + event.filterCard({ name: name }, player, event) + ) + vcards.push(["基本", "", name]); } } return vcards; }, - content:function(){ - 'step 0' - var types=['basic','trick','equip']; - var list=lib.skill.olbixin.getList(player); - if(list.length){ - var dialog=['###'+get.prompt('olbixin')+'###
              摸'+get.cnNumber(player.countMark('olbixin')>=3?1:3)+'张牌,然后将所有指定类型的手牌当一张基本牌使用
              ']; - dialog.push([types.map(i=>get.translation(i)),'tdnodes']); - dialog.push([list,'vcard']); - player.chooseButton(dialog,2).set('filterButton',button=>{ - var player=_status.event.player,count=player.countMark('olbixin'),num=count>=3?3:1; - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - if(type=='string'&&player.countMark('olbixin_'+lib.skill.olbixin.map[button.link])>=num) return false; - if(type!='string'&&!player.hasUseTarget({name:button.link[2],nature:button.link[3]})) return false; - return true; - }).set('ai',button=>{ - var list=_status.event.list; - var type=typeof button.link; - if(type=='string') return (1.2-list.indexOf(lib.skill.olbixin.map[button.link]))*10; - return _status.event.player.getUseValue({name:button.link[2],nature:button.link[3]}); - }).set('list',types.map(i=>[i,player.getCards('h',{type:i}).map(i=>get.value(i)).reduce((p,c)=>p+c,0)]).sort((a,b)=>a[1]-b[1]).map(i=>i[0])); - }else event.finish(); - 'step 1' - if(result.bool){ - if(typeof result.links[0]!='string') result.links.reverse(); - var type=result.links[0],name=result.links[1][2],nature=result.links[1][3]; - player.logSkill('olbixin'); - game.log(player,'声明了',type+'牌'); - type=lib.skill.olbixin.map[type]; - event.type=type; - event.card={name:name,nature:nature}; - player.addMark('olbixin_'+type,1,false); - player.draw(player.countMark('olbixin')>=3?1:3); + content: function () { + "step 0"; + var types = ["basic", "trick", "equip"]; + var list = lib.skill.olbixin.getList(player); + if (list.length) { + var dialog = [ + "###" + + get.prompt("olbixin") + + '###
              摸' + + get.cnNumber(player.countMark("olbixin") >= 3 ? 1 : 3) + + "张牌,然后将所有指定类型的手牌当一张基本牌使用
              ", + ]; + dialog.push([types.map((i) => get.translation(i)), "tdnodes"]); + dialog.push([list, "vcard"]); + player + .chooseButton(dialog, 2) + .set("filterButton", (button) => { + var player = _status.event.player, + count = player.countMark("olbixin"), + num = count >= 3 ? 3 : 1; + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + if ( + type == "string" && + player.countMark("olbixin_" + lib.skill.olbixin.map[button.link]) >= num + ) + return false; + if ( + type != "string" && + !player.hasUseTarget({ name: button.link[2], nature: button.link[3] }) + ) + return false; + return true; + }) + .set("ai", (button) => { + var list = _status.event.list; + var type = typeof button.link; + if (type == "string") + return (1.2 - list.indexOf(lib.skill.olbixin.map[button.link])) * 10; + return _status.event.player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }) + .set( + "list", + types + .map((i) => [ + i, + player + .getCards("h", { type: i }) + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0), + ]) + .sort((a, b) => a[1] - b[1]) + .map((i) => i[0]) + ); + } else event.finish(); + "step 1"; + if (result.bool) { + if (typeof result.links[0] != "string") result.links.reverse(); + var type = result.links[0], + name = result.links[1][2], + nature = result.links[1][3]; + player.logSkill("olbixin"); + game.log(player, "声明了", type + "牌"); + type = lib.skill.olbixin.map[type]; + event.type = type; + event.card = { name: name, nature: nature }; + player.addMark("olbixin_" + type, 1, false); + player.draw(player.countMark("olbixin") >= 3 ? 1 : 3); game.delayx(); - }else event.finish(); - 'step 2' - if(player.hasCard(card=>get.type2(card)==event.type,'h')){ - var cards=player.getCards('h',card=>get.type2(card)==event.type); - var cardx=get.autoViewAs(card,cards); - if(player.hasUseTarget(cardx,true,false)){ - player.chooseUseTarget(cardx,cards,true,false).set('prompt','选择'+get.translation(cardx)+'('+get.translation(cards)+')的目标'); + } else event.finish(); + "step 2"; + if (player.hasCard((card) => get.type2(card) == event.type, "h")) { + var cards = player.getCards("h", (card) => get.type2(card) == event.type); + var cardx = get.autoViewAs(card, cards); + if (player.hasUseTarget(cardx, true, false)) { + player + .chooseUseTarget(cardx, cards, true, false) + .set( + "prompt", + "选择" + + get.translation(cardx) + + "(" + + get.translation(cards) + + ")的目标" + ); } } }, - subSkill:{ - full:{ - enable:'chooseToUse', - filter:function(event,player){ - if(event.olbixin) return false; - var count=player.countMark('olbixin'); - if(count<=2) return false; - var num=count>=3?3:1; - var types=['basic','trick','equip'].filter(type=>{ - return player.countMark('olbixin_'+type)= 3 ? 3 : 1; + var types = ["basic", "trick", "equip"].filter((type) => { + return player.countMark("olbixin_" + type) < num; }); - if(!types.length) return false; - return lib.skill.olbixin.getList(player,event).length>0; + if (!types.length) return false; + return lib.skill.olbixin.getList(player, event).length > 0; }, - prompt:'你可以声明一种牌的类型(每种类型限三次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸一张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。', - chooseButton:{ - dialog:function(event,player){ - var list=lib.skill.olbixin.getList(player,event); - var types=['basic','trick','equip']; + prompt: "你可以声明一种牌的类型(每种类型限三次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸一张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。", + chooseButton: { + dialog: function (event, player) { + var list = lib.skill.olbixin.getList(player, event); + var types = ["basic", "trick", "equip"]; return ui.create.dialog( '###笔心###
              摸一张牌,然后将所有指定类型的手牌当一张基本牌使用
              ', - [types.map(i=>get.translation(i)),'tdnodes'], - [list,'vcard'] + [types.map((i) => get.translation(i)), "tdnodes"], + [list, "vcard"] ); }, - filter:function(button,player){ - var player=_status.event.player,count=player.countMark('olbixin'),num=count>=3?3:1; - var type=typeof button.link; - if(ui.selected.buttons.length&&type==typeof ui.selected.buttons[0].link) return false; - if(type=='string'&&player.countMark('olbixin_'+lib.skill.olbixin.map[button.link])>=num) return false; - if(type!='string'&&!_status.event.getParent().filterCard({name:button.link[2],nature:button.link[3]},player,_status.event.getParent())) return false; + filter: function (button, player) { + var player = _status.event.player, + count = player.countMark("olbixin"), + num = count >= 3 ? 3 : 1; + var type = typeof button.link; + if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) + return false; + if ( + type == "string" && + player.countMark("olbixin_" + lib.skill.olbixin.map[button.link]) >= num + ) + return false; + if ( + type != "string" && + !_status.event + .getParent() + .filterCard( + { name: button.link[2], nature: button.link[3] }, + player, + _status.event.getParent() + ) + ) + return false; return true; }, - select:2, - check:function(button){ - var types=['basic','trick','equip']; - var type=typeof button.link; - var player=_status.event.player; - var list=types.map(i=>[i,player.getCards('h',{type:i}).map(i=>get.value(i)).reduce((p,c)=>p+c,0)]).sort((a,b)=>a[1]-b[1]).map(i=>i[0]); - if(type=='string') return (1.2-list.indexOf(button.link)+Math.sqrt(3-player.countMark('olbixin_'+lib.skill.olbixin.map[button.link])))*10; - if(_status.event.getParent().type!='phase') return 1; - return player.getUseValue({name:button.link[2],nature:button.link[3]}); + select: 2, + check: function (button) { + var types = ["basic", "trick", "equip"]; + var type = typeof button.link; + var player = _status.event.player; + var list = types + .map((i) => [ + i, + player + .getCards("h", { type: i }) + .map((i) => get.value(i)) + .reduce((p, c) => p + c, 0), + ]) + .sort((a, b) => a[1] - b[1]) + .map((i) => i[0]); + if (type == "string") + return ( + (1.2 - + list.indexOf(button.link) + + Math.sqrt( + 3 - + player.countMark( + "olbixin_" + lib.skill.olbixin.map[button.link] + ) + )) * + 10 + ); + if (_status.event.getParent().type != "phase") return 1; + return player.getUseValue({ name: button.link[2], nature: button.link[3] }); }, - backup:function(links,player){ - if(typeof links[0]!='string') links.reverse(); + backup: function (links, player) { + if (typeof links[0] != "string") links.reverse(); return { - popname:true, - position:'h', - filterCard:()=>false, - selectCard:-1, - type:lib.skill.olbixin.map[links[0]], - viewAs:{name:links[1][2],nature:links[1][3]}, - precontent:function(){ - 'step 0' - player.logSkill('olbixin'); - var type=lib.skill.olbixin_full_backup.type; - game.log(player,'声明了',type,'牌'); + popname: true, + position: "h", + filterCard: () => false, + selectCard: -1, + type: lib.skill.olbixin.map[links[0]], + viewAs: { name: links[1][2], nature: links[1][3] }, + precontent: function () { + "step 0"; + player.logSkill("olbixin"); + var type = lib.skill.olbixin_full_backup.type; + game.log(player, "声明了", type, "牌"); delete event.result.skill; - player.addMark('olbixin_'+type,1,false); - player.draw(player.countMark('olbixin')>=3?1:3); - 'step 1' - var cards=player.getCards('h',card=>get.type2(card)==lib.skill.olbixin_full_backup.type); - var cardsx=cards.filter(i=>game.checkMod(i,player,'unchanged','cardEnabled2',player)!==false); - if(cardsx.length&&cardsx.length==cards.length){ - event.result.cards=cards; + player.addMark("olbixin_" + type, 1, false); + player.draw(player.countMark("olbixin") >= 3 ? 1 : 3); + "step 1"; + var cards = player.getCards( + "h", + (card) => get.type2(card) == lib.skill.olbixin_full_backup.type + ); + var cardsx = cards.filter( + (i) => + game.checkMod( + i, + player, + "unchanged", + "cardEnabled2", + player + ) !== false + ); + if (cardsx.length && cardsx.length == cards.length) { + event.result.cards = cards; game.delayx(); - } - else{ + } else { event.cancel(); // event.getParent().set('olbixin',true); event.getParent().goto(0); delete event.getParent().openskilldialog; } }, - } + }; + }, + prompt: function (links, player) { + return ( + "摸一张牌,然后将所有" + + get.translation(links[0]) + + "牌当做" + + (get.translation(links[1][3]) || "") + + get.translation(links[1][2]) + + "使用" + ); }, - prompt:function(links,player){ - return '摸一张牌,然后将所有'+get.translation(links[0])+'牌当做'+(get.translation(links[1][3])||'')+get.translation(links[1][2])+'使用'; - } }, - hiddenCard:function(player,name){ - var count=player.countMark('olbixin'); - if(!lib.inpile.includes(name)||get.type(name)!='basic'||count<3) return false; - var types=['basic','trick','equip'].filter(type=>{ - return player.countMark('olbixin_'+type)<3; + hiddenCard: function (player, name) { + var count = player.countMark("olbixin"); + if (!lib.inpile.includes(name) || get.type(name) != "basic" || count < 3) + return false; + var types = ["basic", "trick", "equip"].filter((type) => { + return player.countMark("olbixin_" + type) < 3; }); return types.length; }, - ai:{ - fireAttack:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player){ - var count=player.countMark('olbixin'); - if(count<3) return; - var types=['basic','trick','equip'].filter(type=>{ - return player.countMark('olbixin_'+type)<3; + ai: { + fireAttack: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player) { + var count = player.countMark("olbixin"); + if (count < 3) return; + var types = ["basic", "trick", "equip"].filter((type) => { + return player.countMark("olbixin_" + type) < 3; }); - if(types.length) return true; + if (types.length) return true; }, - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, }, - full_backup:{}, - } - }, - olximo:{ - audio:3, - trigger:{player:'logSkill'}, - derivation:'olfeibai', - filter:function(event,player){ - return event.skill=='olbixin'&&player.countMark('olbixin')<3; + full_backup: {}, }, - forced:true, - content:function(){ - player.addMark('olbixin',1,false); - game.log(player,'删除了','#g【笔心】','描述的前五个字符'); - if(player.countMark('olbixin')==3){ - game.log(player,'交换了','#g【笔心】','方括号中的两个数字'); + }, + olximo: { + audio: 3, + trigger: { player: "logSkill" }, + derivation: "olfeibai", + filter: function (event, player) { + return event.skill == "olbixin" && player.countMark("olbixin") < 3; + }, + forced: true, + content: function () { + player.addMark("olbixin", 1, false); + game.log(player, "删除了", "#g【笔心】", "描述的前五个字符"); + if (player.countMark("olbixin") == 3) { + game.log(player, "交换了", "#g【笔心】", "方括号中的两个数字"); //player.removeSkill('olximo'); //game.log(player,'失去了技能','#g【洗墨】'); - player.changeSkills(['olfeibai'],['olximo']); + player.changeSkills(["olfeibai"], ["olximo"]); } }, - ai:{ - combo:'olbixin', - } + ai: { + combo: "olbixin", + }, }, - olfeibai:{ - audio:2, - trigger:{ - source:'damageBegin1', - player:'recoverBegin', + olfeibai: { + audio: 2, + trigger: { + source: "damageBegin1", + player: "recoverBegin", }, - filter:function(event,player){ - var storage=player.storage.olfeibai; - var evt=event.getParent(),card=event.card; - if(evt.player!=player||!card) return false; - if(storage&&event.name=='recover'){ - return get.color(card)!='red'; + filter: function (event, player) { + var storage = player.storage.olfeibai; + var evt = event.getParent(), + card = event.card; + if (evt.player != player || !card) return false; + if (storage && event.name == "recover") { + return get.color(card) != "red"; } - if(!storage&&event.name=='damage'){ - return get.color(card)!='black'; + if (!storage && event.name == "damage") { + return get.color(card) != "black"; } return false; }, - content:function(){ - player.changeZhuanhuanji('olfeibai'); + content: function () { + player.changeZhuanhuanji("olfeibai"); trigger.num++; }, - zhuanhuanji:true, - forced:true, - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - if(storage) return '转换技。当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。'; - return '转换技。当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1。'; + zhuanhuanji: true, + forced: true, + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + if (storage) + return "转换技。当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。"; + return "转换技。当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1。"; }, }, }, //新诸葛瑾 - olhuanshi:{ - audio:'huanshi', - trigger:{global:'judge'}, - filter:function(event,player){ - return player.countCards('h')>0; + olhuanshi: { + audio: "huanshi", + trigger: { global: "judge" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - logTarget:'player', - prompt2:function(event,player){ - var str=(get.translation(event.player)+'的'+event.judgestr+'判定为'+get.translation(event.player.judging[0])+'。你可以令其观看你的牌,其选择一张牌进行改判。'); - if(!player.hasSkill('olhuanshi_mark',null,null,false)) str+='然后你可以重铸任意张牌。'; + logTarget: "player", + prompt2: function (event, player) { + var str = + get.translation(event.player) + + "的" + + event.judgestr + + "判定为" + + get.translation(event.player.judging[0]) + + "。你可以令其观看你的牌,其选择一张牌进行改判。"; + if (!player.hasSkill("olhuanshi_mark", null, null, false)) + str += "然后你可以重铸任意张牌。"; return str; }, - check:function(event,player){ - if(get.attitude(player,event.player)<=0) return false; - var cards=player.getCards('he'); - var judge=event.judge(event.player.judging[0]); - for(var i=0;ijudge) return true; - if(_status.currentPhase!=player&&judge2==judge&&get.color(cards[i])=='red'&&get.useful(cards[i])<5) return true; + check: function (event, player) { + if (get.attitude(player, event.player) <= 0) return false; + var cards = player.getCards("he"); + var judge = event.judge(event.player.judging[0]); + for (var i = 0; i < cards.length; i++) { + var judge2 = event.judge(cards[i]); + if (judge2 > judge) return true; + if ( + _status.currentPhase != player && + judge2 == judge && + get.color(cards[i]) == "red" && + get.useful(cards[i]) < 5 + ) + return true; } return false; }, - content:function(){ - 'step 0' - var target=trigger.player; - var judge=trigger.judge(target.judging[0]); - var attitude=get.attitude(target,player); - target.choosePlayerCard('请选择代替判定的牌','he','visible',true,player).set('ai',function(button){ - var card=button.link; - var judge=_status.event.judge; - var attitude=_status.event.attitude; - var result=trigger.judge(card)-judge; - var player=_status.event.player; - if(result>0){ - return 20+result; - } - if(result==0){ - if(_status.currentPhase==player) return 0; - if(attitude>=0){ - return get.color(card)=='red'?7:0-get.value(card); + content: function () { + "step 0"; + var target = trigger.player; + var judge = trigger.judge(target.judging[0]); + var attitude = get.attitude(target, player); + target + .choosePlayerCard("请选择代替判定的牌", "he", "visible", true, player) + .set("ai", function (button) { + var card = button.link; + var judge = _status.event.judge; + var attitude = _status.event.attitude; + var result = trigger.judge(card) - judge; + var player = _status.event.player; + if (result > 0) { + return 20 + result; } - else{ - return get.color(card)=='black'?10:0+get.value(card); + if (result == 0) { + if (_status.currentPhase == player) return 0; + if (attitude >= 0) { + return get.color(card) == "red" ? 7 : 0 - get.value(card); + } else { + return get.color(card) == "black" ? 10 : 0 + get.value(card); + } } - } - if(attitude>=0){ - return get.color(card)=='red'?0:-10+result; - } - else{ - return get.color(card)=='black'?0:-10+result; - } - }).set('filterButton',function(button){ - var player=_status.event.target; - var card=button.link; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('judge',judge).set('attitude',attitude); - 'step 1' - if(result.bool){ - event.card=result.links[0]; - player.respond(event.card,'highlight','noOrdering').nopopup=true; - } - else{ + if (attitude >= 0) { + return get.color(card) == "red" ? 0 : -10 + result; + } else { + return get.color(card) == "black" ? 0 : -10 + result; + } + }) + .set("filterButton", function (button) { + var player = _status.event.target; + var card = button.link; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + }) + .set("judge", judge) + .set("attitude", attitude); + "step 1"; + if (result.bool) { + event.card = result.links[0]; + player.respond(event.card, "highlight", "noOrdering").nopopup = true; + } else { event.finish(); } - 'step 2' - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=event.card; + trigger.player.judging[0] = event.card; trigger.orderingCards.add(event.card); - game.log(trigger.player,'的判定牌改为',event.card); + game.log(trigger.player, "的判定牌改为", event.card); game.delay(2); } - if(!player.countCards('h')||player.hasSkill('olhuanshi_mark',null,null,false)) event.finish(); - 'step 3' - player.chooseCard('是否重铸任意张手牌?','操作提示:选择要重铸的牌并点击“确定”',[1,player.countCards('h')],lib.filter.cardRecastable).set('ai',function(card){ - var player=_status.event.player,cards=ui.selected.cards; - if(!player.hasSkill('olmingzhe')) return 5-get.value(card); - for(var i of cards){ - if(get.color(i,player)=='red') return 5-get.value(card); - } - return 7.5-get.value(card); - }); - 'step 4' - if(result.bool){ - player.addTempSkill('olhuanshi_mark'); + if (!player.countCards("h") || player.hasSkill("olhuanshi_mark", null, null, false)) + event.finish(); + "step 3"; + player + .chooseCard( + "是否重铸任意张手牌?", + "操作提示:选择要重铸的牌并点击“确定”", + [1, player.countCards("h")], + lib.filter.cardRecastable + ) + .set("ai", function (card) { + var player = _status.event.player, + cards = ui.selected.cards; + if (!player.hasSkill("olmingzhe")) return 5 - get.value(card); + for (var i of cards) { + if (get.color(i, player) == "red") return 5 - get.value(card); + } + return 7.5 - get.value(card); + }); + "step 4"; + if (result.bool) { + player.addTempSkill("olhuanshi_mark"); player.recast(result.cards); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, }, - subSkill:{mark:{charlotte:true}}, + subSkill: { mark: { charlotte: true } }, }, - olhongyuan:{ - audio:'hongyuan', - trigger:{player:'gainAfter',global:'loseAsyncAfter'}, - filter(event,player){ - if(!player.countCards('he')||player.hasSkill('olhongyuan_blocker',null,null,false)) return false; - return event.getg(player).length>=2; + olhongyuan: { + audio: "hongyuan", + trigger: { player: "gainAfter", global: "loseAsyncAfter" }, + filter(event, player) { + if (!player.countCards("he") || player.hasSkill("olhongyuan_blocker", null, null, false)) + return false; + return event.getg(player).length >= 2; }, - async content(event,trigger,player){ - player.addTempSkill('olhongyuan_blocker',['phaseZhunbeiBefore','phaseJudgeBefore','phaseDrawBefore','phaseUseBefore','phaseDiscardBefore','phaseJieshuBefore','phaseBefore']); - let selectedTargets=[]; - while(selectedTargets.length<2&&player.countCards('he')&&game.hasPlayer(target=>{ - return target!=player&&!selectedTargets.includes(target); - })){ - const {result:{bool,targets,cards}}=await player.chooseCardTarget({ - prompt:'弘援:将一张牌交给一名其他角色', - filterCard:true, - position:'he', - filterTarget(card,player,target){ - return target!=player&&!get.event('selectedTargets').includes(target); - }, - complexCard:true, - complexTarget:true, - complexSelect:true, - ai1(card){ - const player=get.event('player'); - if(!game.hasPlayer(current=>{ - if(get.event('selectedTargets').includes(current)) return false; - return current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })) return -get.value(card); - return 4+((player.hasSkill('olmingzhe')&&get.color(card)=='red')?2:0)-Math.max(player.getUseValue(card),get.value(card,player)); - }, - ai2(target){ - const player=_status.event.player,att=get.attitude(player,target); - if(!ui.selected.cards.length) return att; - const card=ui.selected.cards[0],val=get.value(card,target); - if(val<0) return -att*Math.sqrt(-val); - return att*Math.sqrt(val+2); - }, - }).set('selectedTargets',selectedTargets); - if(bool){ - const target=targets[0]; + async content(event, trigger, player) { + player.addTempSkill("olhongyuan_blocker", [ + "phaseZhunbeiBefore", + "phaseJudgeBefore", + "phaseDrawBefore", + "phaseUseBefore", + "phaseDiscardBefore", + "phaseJieshuBefore", + "phaseBefore", + ]); + let selectedTargets = []; + while ( + selectedTargets.length < 2 && + player.countCards("he") && + game.hasPlayer((target) => { + return target != player && !selectedTargets.includes(target); + }) + ) { + const { + result: { bool, targets, cards }, + } = await player + .chooseCardTarget({ + prompt: "弘援:将一张牌交给一名其他角色", + filterCard: true, + position: "he", + filterTarget(card, player, target) { + return target != player && !get.event("selectedTargets").includes(target); + }, + complexCard: true, + complexTarget: true, + complexSelect: true, + ai1(card) { + const player = get.event("player"); + if ( + !game.hasPlayer((current) => { + if (get.event("selectedTargets").includes(current)) return false; + return ( + current != player && + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return -get.value(card); + return ( + 4 + + (player.hasSkill("olmingzhe") && get.color(card) == "red" ? 2 : 0) - + Math.max(player.getUseValue(card), get.value(card, player)) + ); + }, + ai2(target) { + const player = _status.event.player, + att = get.attitude(player, target); + if (!ui.selected.cards.length) return att; + const card = ui.selected.cards[0], + val = get.value(card, target); + if (val < 0) return -att * Math.sqrt(-val); + return att * Math.sqrt(val + 2); + }, + }) + .set("selectedTargets", selectedTargets); + if (bool) { + const target = targets[0]; selectedTargets.push(target); player.line(target); - await player.give(cards,target); - } - else break; + await player.give(cards, target); + } else break; } }, - ai:{threaten:0.8}, - subSkill:{blocker:{charlotte:true}}, + ai: { threaten: 0.8 }, + subSkill: { blocker: { charlotte: true } }, }, - olmingzhe:{ - audio:'mingzhe', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + olmingzhe: { + audio: "mingzhe", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - if(player.isPhaseUsing()) return false; - var evt=event.getl(player); - for(var i of evt.cards2){ - if(get.color(i,player)=='red') return true; + forced: true, + filter: function (event, player) { + if (player.isPhaseUsing()) return false; + var evt = event.getl(player); + for (var i of evt.cards2) { + if (get.color(i, player) == "red") return true; } return false; }, - content:function(){ - if(!trigger.visible){ - var cards=trigger.getl(player).hs.filter(function(i){ - return get.color(i,player)=='red'; + content: function () { + if (!trigger.visible) { + var cards = trigger.getl(player).hs.filter(function (i) { + return get.color(i, player) == "red"; }); - if(cards.length>0) player.showCards(cards,get.translation(player)+'发动了【明哲】'); + if (cards.length > 0) + player.showCards(cards, get.translation(player) + "发动了【明哲】"); } player.draw(); }, }, //吕范 - xindiaodu:{ - audio:"diaodu", - group:'xindiaodu_use', - frequent:true, - preHidden:true, - isFriendOf:function(player,target){ - if(get.mode()=='guozhan') return player.isFriendOf(target); - return player.group==target.group; + xindiaodu: { + audio: "diaodu", + group: "xindiaodu_use", + frequent: true, + preHidden: true, + isFriendOf: function (player, target) { + if (get.mode() == "guozhan") return player.isFriendOf(target); + return player.group == target.group; }, - subSkill:{ - temp:{charlotte:true}, - use:{ - trigger:{ - global:"useCard", + subSkill: { + temp: { charlotte: true }, + use: { + trigger: { + global: "useCard", }, - filter:function(event,player){ - return get.type(event.card)=='equip'&&event.player.isIn()&& - lib.skill.xindiaodu.isFriendOf(player,event.player)&&(player==event.player||player.hasSkill('xindiaodu'))&&!event.player.hasSkill('xindiaodu_temp'); + filter: function (event, player) { + return ( + get.type(event.card) == "equip" && + event.player.isIn() && + lib.skill.xindiaodu.isFriendOf(player, event.player) && + (player == event.player || player.hasSkill("xindiaodu")) && + !event.player.hasSkill("xindiaodu_temp") + ); }, - direct:true, - content:function(){ - 'step 0' - var next=trigger.player.chooseBool('是否发动【调度】摸一张牌?'); - if(player.hasSkill('xindiaodu')) next.set('frequentSkill','xindiaodu'); - if(player==trigger.player) next.setHiddenSkill('xindiaodu'); - 'step 1' - if(result.bool){ - player.logSkill('xindiaodu',trigger.player); - trigger.player.draw('nodelay'); - trigger.player.addTempSkill('xindiaodu_temp'); + direct: true, + content: function () { + "step 0"; + var next = trigger.player.chooseBool("是否发动【调度】摸一张牌?"); + if (player.hasSkill("xindiaodu")) next.set("frequentSkill", "xindiaodu"); + if (player == trigger.player) next.setHiddenSkill("xindiaodu"); + "step 1"; + if (result.bool) { + player.logSkill("xindiaodu", trigger.player); + trigger.player.draw("nodelay"); + trigger.player.addTempSkill("xindiaodu_temp"); } }, }, }, - trigger:{ - player:"phaseUseBegin", + trigger: { + player: "phaseUseBegin", }, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.xindiaodu.isFriendOf(current,player)&¤t.countGainableCards(player,'e')>0; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + lib.skill.xindiaodu.isFriendOf(current, player) && + current.countGainableCards(player, "e") > 0 + ); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('xindiaodu'),function(card,player,current){ - return lib.skill.xindiaodu.isFriendOf(current,player)&¤t.countGainableCards(player,'e')>0; - }).setHiddenSkill(event.name).ai=function(target){ - var num=1; - if(target.hasSkill('gzxiaoji')) num+=2.5; - if(target.isDamaged()&&target.getEquip('baiyin')) num+=2.5; - if(target.hasSkill('xuanlve')) num+=2; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("xindiaodu"), function (card, player, current) { + return ( + lib.skill.xindiaodu.isFriendOf(current, player) && + current.countGainableCards(player, "e") > 0 + ); + }) + .setHiddenSkill(event.name).ai = function (target) { + var num = 1; + if (target.hasSkill("gzxiaoji")) num += 2.5; + if (target.isDamaged() && target.getEquip("baiyin")) num += 2.5; + if (target.hasSkill("xuanlve")) num += 2; return num; }; - 'step 1' - if(result.bool){ - event.target1=result.targets[0]; - player.logSkill('xindiaodu',event.target1); - player.line(event.target1,'xindiaodu'); - player.gainPlayerCard(event.target1,'e',true); - } - else event.finish(); - 'step 2' - if(result.bool&&player.getCards('h').includes(result.cards[0])){ - event.card=result.cards[0]; - player.chooseTarget('是否将'+get.translation(event.card)+'交给一名其他角色?',function(card,player,current){ - return current!=player&¤t!=_status.event.target1&&lib.skill.xindiaodu.isFriendOf(current,player) - }).set('target1',event.target1); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.give(card,target); + "step 1"; + if (result.bool) { + event.target1 = result.targets[0]; + player.logSkill("xindiaodu", event.target1); + player.line(event.target1, "xindiaodu"); + player.gainPlayerCard(event.target1, "e", true); + } else event.finish(); + "step 2"; + if (result.bool && player.getCards("h").includes(result.cards[0])) { + event.card = result.cards[0]; + player + .chooseTarget( + "是否将" + get.translation(event.card) + "交给一名其他角色?", + function (card, player, current) { + return ( + current != player && + current != _status.event.target1 && + lib.skill.xindiaodu.isFriendOf(current, player) + ); + } + ) + .set("target1", event.target1); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.give(card, target); } }, }, //夏侯玄 - olhuanfu:{ - audio:2, - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + olhuanfu: { + audio: 2, + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(player==event.player&&!event.isFirstTarget) return false; - if(event.olhuanfu_map&&event.olhuanfu_map[player.playerid]) return false; - return player.maxHp>0&&player.countCards('he')>0; + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (player == event.player && !event.isFirstTarget) return false; + if (event.olhuanfu_map && event.olhuanfu_map[player.playerid]) return false; + return player.maxHp > 0 && player.countCards("he") > 0; }, - shaRelated:true, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard('he',[1,player.maxHp],get.prompt('olhuanfu'),'通过弃牌,预测'+(player==trigger.player?'你':get.translation(trigger.player))+'使用的'+get.translation(trigger.card)+'能造成多少伤害。如果弃置的牌数等于总伤害,则你摸两倍的牌。').set('predict',function(){ - var target=trigger.target; - if(player==target){ - if(trigger.targets.length>1||player.hasShan()||get.effect(player,trigger.card,trigger.player,player)==0) return 0; - } - else{ - var target=trigger.target; - if(trigger.targets.length>1||target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return 0; - } - var num=trigger.getParent().baseDamage; - var map=trigger.getParent().customArgs,id=target.playerid; - if(map[id]){ - if(typeof map[id].baseDamage=='number') num=map[id].baseDamage; - if(typeof map[id].extraDamage=='number') num+=map[id].extraDamage; - } - if(target.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:trigger.card, - })) num=1; - return num; - }()).set('ai',function(card){ - var num=_status.event.predict,player=_status.event.player; - if(ui.selected.cards.length>=num) return 0; - if(player.countCards('he',function(card){ - return get.value(card)<6+num; - }) 1 || + player.hasShan() || + get.effect(player, trigger.card, trigger.player, player) == 0 + ) + return 0; + } else { + var target = trigger.target; + if ( + trigger.targets.length > 1 || + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return 0; + } + var num = trigger.getParent().baseDamage; + var map = trigger.getParent().customArgs, + id = target.playerid; + if (map[id]) { + if (typeof map[id].baseDamage == "number") num = map[id].baseDamage; + if (typeof map[id].extraDamage == "number") num += map[id].extraDamage; + } + if ( + target.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: trigger.card, + }) + ) + num = 1; + return num; + })() + ) + .set("ai", function (card) { + var num = _status.event.predict, + player = _status.event.player; + if (ui.selected.cards.length >= num) return 0; + if ( + player.countCards("he", function (card) { + return get.value(card) < 6 + num; + }) < num + ) + return 0; + return 6 + num - get.value(card); + }).logSkill = "olhuanfu"; + "step 1"; + if (result.bool) { + player.addTempSkill("olhuanfu_lottery"); + var evt = trigger.getParent(); + if (!evt.olhuanfu_map) evt.olhuanfu_map = {}; + evt.olhuanfu_map[player.playerid] = result.cards.length; } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&target.hp>0&¤t<0&&target.countCards('he')>0) return 0.7; + ai: { + effect: { + target: function (card, player, target, current) { + if ( + card.name == "sha" && + target.hp > 0 && + current < 0 && + target.countCards("he") > 0 + ) + return 0.7; }, }, }, - subSkill:{ - lottery:{ - trigger:{global:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - var map=event.olhuanfu_map; - if(!map||!map[player.playerid]) return false; - var num=0; - event.player.getHistory('sourceDamage',function(evt){ - if(evt.card==event.card&&evt.getParent().type=='card') num+=evt.num; + subSkill: { + lottery: { + trigger: { global: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + var map = event.olhuanfu_map; + if (!map || !map[player.playerid]) return false; + var num = 0; + event.player.getHistory("sourceDamage", function (evt) { + if (evt.card == event.card && evt.getParent().type == "card") num += evt.num; }); - return num==map[player.playerid]; + return num == map[player.playerid]; }, - content:function(){ - player.draw(2*trigger.olhuanfu_map[player.playerid]); + content: function () { + player.draw(2 * trigger.olhuanfu_map[player.playerid]); }, }, }, }, - olqingyi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'olqingyi'); - },'he')&&game.hasPlayer(current=>lib.skill.olqingyi.filterTarget(null,player,current)); + olqingyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "olqingyi"); + }, "he") && + game.hasPlayer((current) => lib.skill.olqingyi.filterTarget(null, player, current)) + ); }, - selectTarget:[1,2], - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + selectTarget: [1, 2], + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - var list=[player]; + multitarget: true, + multiline: true, + content: function () { + "step 0"; + var list = [player]; list.addArray(targets); list.sortBySeat(); - event.list=list; - for(var target of event.list){ - if(!target.hasCard(function(card){ - return lib.filter.cardDiscardable(card,target,'olqingyi'); - },'he')){ + event.list = list; + for (var target of event.list) { + if ( + !target.hasCard(function (card) { + return lib.filter.cardDiscardable(card, target, "olqingyi"); + }, "he") + ) { event.finish(); break; } } - 'step 1' - player.chooseCardOL(event.list,'he',true,'清议:选择弃置一张牌',function(card,player){ - return lib.filter.cardDiscardable(card,player,'olqingyi'); - }).set('ai',get.unuseful); - 'step 2' - var lose_list=[],cards=[]; - for(var i=0;ievt.skill=='olqingyi'); - if(!history.length) return false; - var color=false; - for(var evt of history){ - var list=[player]; + group: "olqingyi_gain", + subSkill: { + gain: { + audio: "olqingyi", + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + var history = player.getHistory("useSkill", (evt) => evt.skill == "olqingyi"); + if (!history.length) return false; + var color = false; + for (var evt of history) { + var list = [player]; list.addArray(evt.targets); - for(var target of list){ - target.getHistory('lose',function(evtx){ - if(color===true||evtx.getParent(2).name!='olqingyi') return false; - for(var card of evtx.cards){ - if(color===true||get.position(card,true)!='d') continue; - var color2=get.color(card,false); - if(!color) color=color2; - else if(color!=color2) color=true; + for (var target of list) { + target.getHistory("lose", function (evtx) { + if (color === true || evtx.getParent(2).name != "olqingyi") + return false; + for (var card of evtx.cards) { + if (color === true || get.position(card, true) != "d") continue; + var color2 = get.color(card, false); + if (!color) color = color2; + else if (color != color2) color = true; } }); - if(color===true) return true; + if (color === true) return true; } } return false; }, - content:function(){ - 'step 0' - var history=player.getHistory('useSkill',(evt)=>evt.skill=='olqingyi'),cards=[]; - for(var evt of history){ - var list=[player]; + content: function () { + "step 0"; + var history = player.getHistory("useSkill", (evt) => evt.skill == "olqingyi"), + cards = []; + for (var evt of history) { + var list = [player]; list.addArray(evt.targets); - for(var target of list){ - target.getHistory('lose',function(evtx){ - if(evtx.getParent(2).name!='olqingyi') return false; - for(var card of evtx.cards){ - if(get.position(card,true)=='d') cards.add(card); + for (var target of list) { + target.getHistory("lose", function (evtx) { + if (evtx.getParent(2).name != "olqingyi") return false; + for (var card of evtx.cards) { + if (get.position(card, true) == "d") cards.add(card); } }); } } - player.chooseButton(['清议:选择获得两张异色牌',cards],2).set('filterButton',function(button){ - if(!ui.selected.buttons.length) return true; - return get.color(button.link,false)!=get.color(ui.selected.buttons[0].link,false); - }).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); - 'step 1' - if(result.bool){ - player.logSkill('olqingyi_gain'); - player.gain(result.links,'gain2'); + player + .chooseButton(["清议:选择获得两张异色牌", cards], 2) + .set("filterButton", function (button) { + if (!ui.selected.buttons.length) return true; + return ( + get.color(button.link, false) != + get.color(ui.selected.buttons[0].link, false) + ); + }) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); + "step 1"; + if (result.bool) { + player.logSkill("olqingyi_gain"); + player.gain(result.links, "gain2"); } }, }, }, }, - olzeyue:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - limited:true, - skillAnimation:true, - animationColor:'water', - direct:true, - filter:function(event,player){ - var sources=[],history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - if(i= 0; i--) { + if (i < history.length - 1 && history[i].isMe) break; + for (var evt of history[i].damage) { + if (evt.source && evt.source != player && evt.source.isIn()) + sources.add(evt.source); } } - for(var source of sources){ - var skills=source.getStockSkills('一!','五!'); - for(var skill of skills){ - var info=get.info(skill); - if(info&&!info.charlotte&&!get.is.locked(skill,source)&&source.hasSkill(skill,null,null,false)) return true; + for (var source of sources) { + var skills = source.getStockSkills("一!", "五!"); + for (var skill of skills) { + var info = get.info(skill); + if ( + info && + !info.charlotte && + !get.is.locked(skill, source) && + source.hasSkill(skill, null, null, false) + ) + return true; } } return false; }, - content:function(){ - 'step 0' - var sources=[],history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - if(i= 0; i--) { + if (i < history.length - 1 && history[i].isMe) break; + for (var evt of history[i].damage) { + if (evt.source && evt.source != player && evt.source.isIn()) + sources.add(evt.source); } } - sources=sources.filter(function(source){ - var skills=source.getStockSkills('一!','五!'); - for(var skill of skills){ - var info=get.info(skill); - if(info&&!info.charlotte&&!get.is.locked(skill,source)&&source.hasSkill(skill,null,null,false)) return true; + sources = sources.filter(function (source) { + var skills = source.getStockSkills("一!", "五!"); + for (var skill of skills) { + var info = get.info(skill); + if ( + info && + !info.charlotte && + !get.is.locked(skill, source) && + source.hasSkill(skill, null, null, false) + ) + return true; } return false; }); - player.chooseTarget(get.prompt('olzeyue'),'令一名可选角色的一个非锁定技失效',function(card,player,target){ - return _status.event.sources.includes(target); - }).set('sources',sources).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att>=0) return 0; - return get.threaten(target,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('olzeyue',target); - player.awakenSkill('olzeyue'); - event.target=target; - var skills=target.getStockSkills('一!','五!'); - skills=skills.filter(function(skill){ - var info=get.info(skill); - if(info&&!info.charlotte&&!get.is.locked(skill,target)&&target.hasSkill(skill,null,null,false)) return true; + player + .chooseTarget( + get.prompt("olzeyue"), + "令一名可选角色的一个非锁定技失效", + function (card, player, target) { + return _status.event.sources.includes(target); + } + ) + .set("sources", sources) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att >= 0) return 0; + return get.threaten(target, player); }); - if(skills.length==1) event._result={control:skills[0]}; - else player.chooseControl(skills).set('prompt','令'+get.translation(target)+'的一个技能失效'); - } - else event.finish(); - 'step 2' - var skill=result.control; - target.disableSkill('olzeyue_'+player.playerid,skill); - target.storage['olzeyue_'+player.playerid]=true; - player.addSkill('olzeyue_round'); - player.markAuto('olzeyue_round',[target]); - if(!player.storage.olzeyue_map) player.storage.olzeyue_map={}; - player.storage.olzeyue_map[target.playerid]=0; - game.log(target,'的技能','#g【'+get.translation(skill)+'】','被失效了'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("olzeyue", target); + player.awakenSkill("olzeyue"); + event.target = target; + var skills = target.getStockSkills("一!", "五!"); + skills = skills.filter(function (skill) { + var info = get.info(skill); + if ( + info && + !info.charlotte && + !get.is.locked(skill, target) && + target.hasSkill(skill, null, null, false) + ) + return true; + }); + if (skills.length == 1) event._result = { control: skills[0] }; + else + player + .chooseControl(skills) + .set("prompt", "令" + get.translation(target) + "的一个技能失效"); + } else event.finish(); + "step 2"; + var skill = result.control; + target.disableSkill("olzeyue_" + player.playerid, skill); + target.storage["olzeyue_" + player.playerid] = true; + player.addSkill("olzeyue_round"); + player.markAuto("olzeyue_round", [target]); + if (!player.storage.olzeyue_map) player.storage.olzeyue_map = {}; + player.storage.olzeyue_map[target.playerid] = 0; + game.log(target, "的技能", "#g【" + get.translation(skill) + "】", "被失效了"); }, - ai:{threaten:3}, - subSkill:{ - round:{ - trigger:{global:'roundStart'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - var storage=player.getStorage('olzeyue_round'); - for(var source of storage){ - if(source.isIn()&&source.canUse('sha',player,false)) return true; + ai: { threaten: 3 }, + subSkill: { + round: { + trigger: { global: "roundStart" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + var storage = player.getStorage("olzeyue_round"); + for (var source of storage) { + if (source.isIn() && source.canUse("sha", player, false)) return true; } return false; }, - content:function(){ - 'step 0' - event.targets=player.storage.olzeyue_round.slice(0).sortBySeat(); - event.target=event.targets.shift(); - event.forceDie=true; - 'step 1' - var map=player.storage.olzeyue_map; - if(target.storage['olzeyue_'+player.playerid]) map[target.playerid]++; - event.num=map[target.playerid]-1; - if(event.num<=0) event.finish(); - 'step 2' + content: function () { + "step 0"; + event.targets = player.storage.olzeyue_round.slice(0).sortBySeat(); + event.target = event.targets.shift(); + event.forceDie = true; + "step 1"; + var map = player.storage.olzeyue_map; + if (target.storage["olzeyue_" + player.playerid]) map[target.playerid]++; + event.num = map[target.playerid] - 1; + if (event.num <= 0) event.finish(); + "step 2"; event.num--; - target.useCard(player,{name:'sha',isCard:true},false,'olzeyue_round'); - 'step 3' - var key='olzeyue_'+player.playerid; - if(target.storage[key]&&player.hasHistory('damage',function(evt){ - return evt.card.name=='sha'&&evt.getParent().type=='card'&&evt.getParent(3)==event; - })){ - for(var skill in target.disabledSkills){ - if(target.disabledSkills[skill].includes(key)) game.log(target,'恢复了技能','#g【'+get.translation(skill)+'】'); + target.useCard(player, { name: "sha", isCard: true }, false, "olzeyue_round"); + "step 3"; + var key = "olzeyue_" + player.playerid; + if ( + target.storage[key] && + player.hasHistory("damage", function (evt) { + return ( + evt.card.name == "sha" && + evt.getParent().type == "card" && + evt.getParent(3) == event + ); + }) + ) { + for (var skill in target.disabledSkills) { + if (target.disabledSkills[skill].includes(key)) + game.log( + target, + "恢复了技能", + "#g【" + get.translation(skill) + "】" + ); } delete target.storage[key]; target.enableSkill(key); } - if(event.num>0&&player.isIn()&&target.isIn()&&target.canUse('sha',player,false)){ + if ( + event.num > 0 && + player.isIn() && + target.isIn() && + target.canUse("sha", player, false) + ) { event.goto(2); - } - else if(event.targets.length>0){ - event.target=event.targets.shift(); + } else if (event.targets.length > 0) { + event.target = event.targets.shift(); event.goto(1); } }, @@ -8352,2447 +11353,3064 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //邓忠 - dzkanpo:{ - audio:2, - trigger:{source:'damageSource'}, - filter:function(event,player){ - return event.getParent().type=='card'&&event.card&&event.card.name=='sha'&&event.player.countCards('he')>0; + dzkanpo: { + audio: 2, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return ( + event.getParent().type == "card" && + event.card && + event.card.name == "sha" && + event.player.countCards("he") > 0 + ); }, - logTarget:'player', - content:function(){ - var suit=get.suit(trigger.card); - var next=player.gainPlayerCard(trigger.player,'h','visible'); - next.set('suit',suit); - next.set('filterButton',function(button){ - var evt=_status.event; - return get.suit(button.link,evt.target)==evt.suit; + logTarget: "player", + content: function () { + var suit = get.suit(trigger.card); + var next = player.gainPlayerCard(trigger.player, "h", "visible"); + next.set("suit", suit); + next.set("filterButton", function (button) { + var evt = _status.event; + return get.suit(button.link, evt.target) == evt.suit; }); }, - group:'dzkanpo_sha', - subSkill:{ - sha:{ - enable:'chooseToUse', - usable:1, - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - return player.countCards('hs')>0; + group: "dzkanpo_sha", + subSkill: { + sha: { + enable: "chooseToUse", + usable: 1, + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + return player.countCards("hs") > 0; }, - filterCard:true, - position:'hs', - prompt:'将一张手牌当做【杀】使用', - check:function(card){ - return 6-get.value(card); + filterCard: true, + position: "hs", + prompt: "将一张手牌当做【杀】使用", + check: function (card) { + return 6 - get.value(card); }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - if(player.getStat('skill').dzkanpo_sha) return false; - if(!player.countCards('hs')) return false; + ai: { + respondSha: true, + skillTagFilter: function (player) { + if (player.getStat("skill").dzkanpo_sha) return false; + if (!player.countCards("hs")) return false; }, }, }, }, }, - dzgengzhan:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + dzgengzhan: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - usable:1, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false||player==_status.currentPhase||!event.isPhaseUsing()) return false; - for(var card of event.cards){ - if(get.position(card,true)=='d'&&get.name(card,event.hs&&event.hs.includes(card)?event.player:false)=='sha') return true; + usable: 1, + filter: function (event, player) { + if ( + event.type != "discard" || + event.getlx === false || + player == _status.currentPhase || + !event.isPhaseUsing() + ) + return false; + for (var card of event.cards) { + if ( + get.position(card, true) == "d" && + get.name(card, event.hs && event.hs.includes(card) ? event.player : false) == + "sha" + ) + return true; } }, - direct:true, - content:function(){ - 'step 0' - var cards=trigger.cards.filter(function(card){ - return (get.position(card,true)=='d'&&get.name(card,trigger.hs&&trigger.hs.includes(card)?trigger.player:false)=='sha') + direct: true, + content: function () { + "step 0"; + var cards = trigger.cards.filter(function (card) { + return ( + get.position(card, true) == "d" && + get.name( + card, + trigger.hs && trigger.hs.includes(card) ? trigger.player : false + ) == "sha" + ); }); - player.chooseButton(['是否发动【更战】获得一张杀?',cards]).set('ai',function(button){ - return get.value(button.link,_status.event.player); + player.chooseButton(["是否发动【更战】获得一张杀?", cards]).set("ai", function (button) { + return get.value(button.link, _status.event.player); }); - 'step 1' - if(result.bool){ - player.logSkill('dzgengzhan'); - player.gain(result.links,'gain2'); - } - else player.storage.counttrigger.dzgengzhan--; + "step 1"; + if (result.bool) { + player.logSkill("dzgengzhan"); + player.gain(result.links, "gain2"); + } else player.storage.counttrigger.dzgengzhan--; }, - group:'dzgengzhan_add', - subSkill:{ - add:{ - audio:'dzgengzhan', - trigger:{global:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player!=event.player&&!event.player.hasHistory('useCard',function(evt){ - return evt.card.name=='sha'; - }); + group: "dzgengzhan_add", + subSkill: { + add: { + audio: "dzgengzhan", + trigger: { global: "phaseJieshuBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player != event.player && + !event.player.hasHistory("useCard", function (evt) { + return evt.card.name == "sha"; + }) + ); }, - logTarget:'player', - content:function(){ - player.addTempSkill('dzgengzhan_effect',{player:'phaseUseAfter'}); - player.addMark('dzgengzhan_effect',1,false); + logTarget: "player", + content: function () { + player.addTempSkill("dzgengzhan_effect", { player: "phaseUseAfter" }); + player.addMark("dzgengzhan_effect", 1, false); game.delayx(); }, }, - effect:{ - onremove:true, - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('dzgengzhan_effect'); + effect: { + onremove: true, + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("dzgengzhan_effect"); }, }, - intro:{content:'使用杀的次数上限+#'}, + intro: { content: "使用杀的次数上限+#" }, }, }, }, //王衍 - yangkuang:{ - audio:2, - trigger:{player:'recoverEnd'}, - filter:function(event,player){ + yangkuang: { + audio: 2, + trigger: { player: "recoverEnd" }, + filter: function (event, player) { return player.isHealthy(); }, - logTarget:function(event,player){ - return _status.currentPhase||player; + logTarget: function (event, player) { + return _status.currentPhase || player; }, - check:function(event,player){ - var target=(_status.currentPhase||player); - if(get.attitude(player,target)>0) return true; - if(player.countCards('h')>target.countCards('h')) return true; - if(!target.getCardUsable('sha')) return true; + check: function (event, player) { + var target = _status.currentPhase || player; + if (get.attitude(player, target) > 0) return true; + if (player.countCards("h") > target.countCards("h")) return true; + if (!target.getCardUsable("sha")) return true; return false; }, - content:function(){ - 'step 0' - player.chooseUseTarget('jiu',true); - 'step 1' - var target=_status.currentPhase; - if(target) target.draw('nodelay'); + content: function () { + "step 0"; + player.chooseUseTarget("jiu", true); + "step 1"; + var target = _status.currentPhase; + if (target) target.draw("nodelay"); player.draw(); }, }, - cihuang:{ - audio:2, - trigger:{ - global:['eventNeutralized','shaMiss'], + cihuang: { + audio: 2, + trigger: { + global: ["eventNeutralized", "shaMiss"], }, - direct:true, - filter:function(event,player){ - if(event.player!=_status.currentPhase||!event.targets||event.targets.length!=1||event.type!='card'||!player.countCards('he')) return false; - return lib.skill.cihuang.getList(player,event.player,true); + direct: true, + filter: function (event, player) { + if ( + event.player != _status.currentPhase || + !event.targets || + event.targets.length != 1 || + event.type != "card" || + !player.countCards("he") + ) + return false; + return lib.skill.cihuang.getList(player, event.player, true); }, - getList:function(player,target,bool){ - var natures=lib.inpile_nature.slice(0); - var tricks=[]; - for(var name of lib.inpile){ - var info=lib.card[name]; - if(!info||info.type!='trick'||info.notarget||((info.selectTarget&&info.selectTarget!=1)&&(info.selectTarget!=-1||!info.toself))) continue; + getList: function (player, target, bool) { + var natures = lib.inpile_nature.slice(0); + var tricks = []; + for (var name of lib.inpile) { + var info = lib.card[name]; + if ( + !info || + info.type != "trick" || + info.notarget || + (info.selectTarget && + info.selectTarget != 1 && + (info.selectTarget != -1 || !info.toself)) + ) + continue; tricks.push(name); } - var history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - var info=history[i]; - for(var evt of info.useCard){ - var name=evt.card.name; - if(name=='sha'){ - if(evt.card.nature) natures.remove(evt.card.nature); - } - else tricks.remove(name); + var history = player.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + var info = history[i]; + for (var evt of info.useCard) { + var name = evt.card.name; + if (name == "sha") { + if (evt.card.nature) natures.remove(evt.card.nature); + } else tricks.remove(name); } - if(info.isRound) break; + if (info.isRound) break; } - var vcards=[]; - for(var i of natures){ - if(player.canUse({ - name:'sha', - nature:i, - isCard:true, - },target)){ - if(bool) return true; - else vcards.push(['基本','','sha',i]); + var vcards = []; + for (var i of natures) { + if ( + player.canUse( + { + name: "sha", + nature: i, + isCard: true, + }, + target + ) + ) { + if (bool) return true; + else vcards.push(["基本", "", "sha", i]); } } - for(var i of tricks){ - if(player.canUse({ - name:i, - isCard:true, - },target)){ - if(bool) return true; - else vcards.push(['锦囊','',i]); + for (var i of tricks) { + if ( + player.canUse( + { + name: i, + isCard: true, + }, + target + ) + ) { + if (bool) return true; + else vcards.push(["锦囊", "", i]); } } - if(bool) return false; + if (bool) return false; return vcards; }, - content:function(){ - 'step 0' - var target=trigger.player; - var list=lib.skill.cihuang.getList(player,target); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - player.chooseButton([get.prompt('cihuang',target),'
              将一张牌当以下的一张牌对'+get.translation(target)+'使用
              ',[list,'vcard']]).set('ai',function(button){ - var card={ - name:button.link[2], - nature:button.link[3], - storage:{cihuang:true}, - },player=_status.event.player,target=_status.event.getTrigger().player; - return get.effect(target,card,player,player); - }); - 'step 1' - if(result.bool){ - var card={ - name:result.links[0][2], - nature:result.links[0][3], - storage:{cihuang:true}, + content: function () { + "step 0"; + var target = trigger.player; + var list = lib.skill.cihuang.getList(player, target); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + player + .chooseButton([ + get.prompt("cihuang", target), + '
              将一张牌当以下的一张牌对' + + get.translation(target) + + "使用
              ", + [list, "vcard"], + ]) + .set("ai", function (button) { + var card = { + name: button.link[2], + nature: button.link[3], + storage: { cihuang: true }, + }, + player = _status.event.player, + target = _status.event.getTrigger().player; + return get.effect(target, card, player, player); + }); + "step 1"; + if (result.bool) { + var card = { + name: result.links[0][2], + nature: result.links[0][3], + storage: { cihuang: true }, }; - event.card=card; - player.chooseCard('hes','雌黄:将一张牌当'+get.translation(card)+'对'+get.translation(trigger.player)+'使用',function(card,player){ - return player.canUse(get.autoViewAs(_status.event.getParent().card,[card]),_status.event.target,false); - }).set('target',trigger.player).set('ai',function(card){ - if(get.effect(_status.event.target,get.autoViewAs(_status.event.getParent().card,[card]),player)<=0) return false; - return 6-get.value(card); + event.card = card; + player + .chooseCard( + "hes", + "雌黄:将一张牌当" + + get.translation(card) + + "对" + + get.translation(trigger.player) + + "使用", + function (card, player) { + return player.canUse( + get.autoViewAs(_status.event.getParent().card, [card]), + _status.event.target, + false + ); + } + ) + .set("target", trigger.player) + .set("ai", function (card) { + if ( + get.effect( + _status.event.target, + get.autoViewAs(_status.event.getParent().card, [card]), + player + ) <= 0 + ) + return false; + return 6 - get.value(card); + }); + } else event._result = { bool: false }; + "step 2"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); }); } - else event._result={bool:false}; - 'step 2' - if(_status.connectMode){game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()});} - if(result.bool){ - player.useCard(get.autoViewAs(event.card,result.cards),result.cards,false,trigger.player,'cihuang').oncard=function(card,player){ + if (result.bool) { + player.useCard( + get.autoViewAs(event.card, result.cards), + result.cards, + false, + trigger.player, + "cihuang" + ).oncard = function (card, player) { _status.event.directHit.addArray(game.filterPlayer()); }; } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg&&arg.card&&arg.card.storage&&arg.card.storage.cihuang; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg && arg.card && arg.card.storage && arg.card.storage.cihuang; }, }, }, - sanku:{ - audio:2, - trigger:{player:'dying'}, - forced:true, - group:'sanku_nogain', - content:function(){ - 'step 0' + sanku: { + audio: 2, + trigger: { player: "dying" }, + forced: true, + group: "sanku_nogain", + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' - var num=player.maxHp-player.hp; - if(num>0) player.recover(num); + "step 1"; + var num = player.maxHp - player.hp; + if (num > 0) player.recover(num); }, - ai:{halfneg:true}, - subSkill:{ - nogain:{ - audio:'sanku', - trigger:{player:'gainMaxHpBegin'}, - forced:true, - content:function(){ + ai: { halfneg: true }, + subSkill: { + nogain: { + audio: "sanku", + trigger: { player: "gainMaxHpBegin" }, + forced: true, + content: function () { trigger.cancel(); - } - } - } + }, + }, + }, }, //霍峻 - qiongshou:{ - audio:2, - trigger:{ - player:'enterGame', - global:'phaseBefore', + qiongshou: { + audio: 2, + trigger: { + player: "enterGame", + global: "phaseBefore", }, - forced:true, - filter:function(event,player){ - if(event.name=='phase'&&game.phaseNumber!=0) return false; + forced: true, + filter: function (event, player) { + if (event.name == "phase" && game.phaseNumber != 0) return false; return player.hasEnabledSlot(); }, - content:function(){ - var list=[]; - for(var i=1;i<6;i++){ - for(var j=0;j0)||(!player.storage.fenrui&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e') 0) || + (!player.storage.fenrui && + game.hasPlayer(function (current) { + return current != player && current.countCards("e") < es; + })) + ); }, - content:function(){ - 'step 0' - if(player.hasDisabledSlot()&&player.countCards('he')>0){ - var str='弃置一张牌,恢复一个装备栏并使用一张对应装备牌'; - player.chooseToDiscard('he',get.prompt('fenrui'),str).set('ai',function(card){ - return 7-get.value(card); - }).logSkill='fenrui'; - } - else event.goto(3); - 'step 1' - if(result.bool){ - player.chooseToEnable().set('ai',function(){ - var player=_status.event.player; - var list=[2,5,1,3,4]; - for(var i of list){ - if(player.hasDisabledSlot(i)) return 'equip'+i; + content: function () { + "step 0"; + if (player.hasDisabledSlot() && player.countCards("he") > 0) { + var str = "弃置一张牌,恢复一个装备栏并使用一张对应装备牌"; + player.chooseToDiscard("he", get.prompt("fenrui"), str).set("ai", function (card) { + return 7 - get.value(card); + }).logSkill = "fenrui"; + } else event.goto(3); + "step 1"; + if (result.bool) { + player.chooseToEnable().set("ai", function () { + var player = _status.event.player; + var list = [2, 5, 1, 3, 4]; + for (var i of list) { + if (player.hasDisabledSlot(i)) return "equip" + i; } }); - } - else{ - var es=player.countCards('e'); - if(player.storage.fenrui||!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e')0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('e')target.countCards('e'); - }).set('ai',function(target){ - var player=_status.event.player; - var num=player.countCards('e')-target.countCards('e'); - if(get.attitude(player,target)>=0) return 0; - if(num>=Math.min(2,player.hp,target.hp)) return get.damageEffect(target,player,player); - return 0; - }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('fenrui_animate',target); - player.storage.fenrui=true; - player.unmarkSkill('fenrui'); + if (player.storage.fenrui) event.finish(); + "step 3"; + var es = player.countCards("e"); + if ( + es > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("e") < es; + }) + ) { + player + .chooseTarget( + "是否对一名装备数小于你的角色造成伤害?", + "你可以选择一名装备区内牌数小于你的角色,并对其造成X点伤害(X为你与其装备区牌数之差),但此效果每局游戏内仅限一次。", + function (card, player, target) { + return ( + player != target && player.countCards("e") > target.countCards("e") + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var num = player.countCards("e") - target.countCards("e"); + if (get.attitude(player, target) >= 0) return 0; + if (num >= Math.min(2, player.hp, target.hp)) + return get.damageEffect(target, player, player); + return 0; + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("fenrui_animate", target); + player.storage.fenrui = true; + player.unmarkSkill("fenrui"); game.delayx(); - target.damage(player.countCards('e')-target.countCards('e')); + target.damage(player.countCards("e") - target.countCards("e")); } }, - group:'fenrui_animate', - mark:true, - intro:{content:'王炸尚未使用'}, - subSkill:{ - animate:{ - skillAnimation:true, - animationColor:'fire', + group: "fenrui_animate", + mark: true, + intro: { content: "王炸尚未使用" }, + subSkill: { + animate: { + skillAnimation: true, + animationColor: "fire", }, }, }, //曹宪曹华 - huamu:{ - audio:6, - trigger:{player:'useCardAfter'}, - locked:false, - filter:function(event,player){ - var color=get.color(event.card); - if(color=='none') return false; - if(!player.hasHistory('lose',function(evt){ - return evt.hs.length>0&&evt.getParent()==event; - })||!event.cards.filterInD('oe').length) return false; - var history=game.getGlobalHistory('useCard'); - var index=history.indexOf(event); - if(index<1) return false; - var evt=history[index-1],color2=get.color(evt.card); - return color!=color2&&color2!='none'; + huamu: { + audio: 6, + trigger: { player: "useCardAfter" }, + locked: false, + filter: function (event, player) { + var color = get.color(event.card); + if (color == "none") return false; + if ( + !player.hasHistory("lose", function (evt) { + return evt.hs.length > 0 && evt.getParent() == event; + }) || + !event.cards.filterInD("oe").length + ) + return false; + var history = game.getGlobalHistory("useCard"); + var index = history.indexOf(event); + if (index < 1) return false; + var evt = history[index - 1], + color2 = get.color(evt.card); + return color != color2 && color2 != "none"; }, - prompt2:(event)=>'将'+get.translation(event.cards.filterInD('oe'))+'置于武将牌上', - check:function(event,player){ - if(!game.hasPlayer(function(current){ - return current.hasSkill('qianmeng',null,null,false)&&get.attitude(player,current)>0; - })) return false; - var cards=event.cards.filterInD('e'); - if(!cards.length) return true; - var card=cards[0]; - if(get.owner(card)==player){ - if(get.value(card,player)<=0) return true; - var subtype=get.subtype(card); - if(player.hasCard('hs',function(card){ - return get.subtype(card)==subtype&&player.canUse(card,player)&&get.effect(player,card,player,player)>0; - })) return true; + prompt2: (event) => "将" + get.translation(event.cards.filterInD("oe")) + "置于武将牌上", + check: function (event, player) { + if ( + !game.hasPlayer(function (current) { + return ( + current.hasSkill("qianmeng", null, null, false) && + get.attitude(player, current) > 0 + ); + }) + ) + return false; + var cards = event.cards.filterInD("e"); + if (!cards.length) return true; + var card = cards[0]; + if (get.owner(card) == player) { + if (get.value(card, player) <= 0) return true; + var subtype = get.subtype(card); + if ( + player.hasCard("hs", function (card) { + return ( + get.subtype(card) == subtype && + player.canUse(card, player) && + get.effect(player, card, player, player) > 0 + ); + }) + ) + return true; } return false; }, - content:function(){ - var cards=trigger.cards.filterInD('oe'); - player.addToExpansion(cards,'gain2').gaintag.add('huamu'); + content: function () { + var cards = trigger.cards.filterInD("oe"); + player.addToExpansion(cards, "gain2").gaintag.add("huamu"); }, - ai:{ - reverseOrder:true, - combo:'qianmeng', + ai: { + reverseOrder: true, + combo: "qianmeng", }, - mod:{ - aiOrder:function(player,card,num){ - if(typeof card=='object'){ - var history=game.getGlobalHistory('useCard'); - if(!history.length) return; - var evt=history[history.length-1]; - if(evt&&evt.card&&get.color(evt.card)!='none'&&get.color(card)!='none'&&get.color(evt.card)!=get.color(card)){ - return num+4; + mod: { + aiOrder: function (player, card, num) { + if (typeof card == "object") { + var history = game.getGlobalHistory("useCard"); + if (!history.length) return; + var evt = history[history.length - 1]; + if ( + evt && + evt.card && + get.color(evt.card) != "none" && + get.color(card) != "none" && + get.color(evt.card) != get.color(card) + ) { + return num + 4; } } }, }, - marktext:'木', - intro:{ - name:'灵杉&玉树', - markcount:function(storage,player){ - var red=[],black=[]; - var cards=player.getExpansions('huamu'); - for(var i of cards){ - var color=get.color(i,false); - (color=='red'?red:black).push(i); + marktext: "木", + intro: { + name: "灵杉&玉树", + markcount: function (storage, player) { + var red = [], + black = []; + var cards = player.getExpansions("huamu"); + for (var i of cards) { + var color = get.color(i, false); + (color == "red" ? red : black).push(i); } - return (''+black.length+'/'+red.length); + return "" + black.length + "/" + red.length; }, - content:'expansion', - mark:function(dialog,storage,player){ - var red=[],black=[]; - var cards=player.getExpansions('huamu'); - for(var i of cards){ - var color=get.color(i,false); - (color=='red'?red:black).push(i); + content: "expansion", + mark: function (dialog, storage, player) { + var red = [], + black = []; + var cards = player.getExpansions("huamu"); + for (var i of cards) { + var color = get.color(i, false); + (color == "red" ? red : black).push(i); } - if(black.length){ - dialog.addText('灵杉'); + if (black.length) { + dialog.addText("灵杉"); dialog.addSmall(black); } - if(red.length){ - dialog.addText('玉树'); + if (red.length) { + dialog.addText("玉树"); dialog.addSmall(red); } }, }, }, - qianmeng:{ - audio:2, - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + qianmeng: { + audio: 2, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - if(event.name=='addToExpansion'){ - if(event.gaintag.includes('huamu')){ - var cards=event.player.getExpansions('huamu'),red=cards.filter(function(i){ - return get.color(i,false)=='red'; - }); - if(cards.length==red.length||red.length==0||cards.length==red.length*2) return true; + filter: function (event, player) { + if (event.name == "addToExpansion") { + if (event.gaintag.includes("huamu")) { + var cards = event.player.getExpansions("huamu"), + red = cards.filter(function (i) { + return get.color(i, false) == "red"; + }); + if ( + cards.length == red.length || + red.length == 0 || + cards.length == red.length * 2 + ) + return true; } } - if(event.name=='lose'&&event.getlx!==false){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('huamu')){ - var cards=event.player.getExpansions('huamu'),red=cards.filter(function(i){ - return get.color(i,false)=='red'; - }); - return (cards.length==red.length||red.length==0||cards.length==red.length/2); + if (event.name == "lose" && event.getlx !== false) { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("huamu")) { + var cards = event.player.getExpansions("huamu"), + red = cards.filter(function (i) { + return get.color(i, false) == "red"; + }); + return ( + cards.length == red.length || + red.length == 0 || + cards.length == red.length / 2 + ); } } return false; } - return game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='lose'||event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('huamu')){ - var cards=evt.player.getExpansions('huamu'),red=cards.filter(function(i){ - return get.color(i,false)=='red'; - }); - return (cards.length==red.length||red.length==0||cards.length==red.length/2); + return ( + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("huamu")) { + var cards = evt.player.getExpansions("huamu"), + red = cards.filter(function (i) { + return get.color(i, false) == "red"; + }); + return ( + cards.length == red.length || + red.length == 0 || + cards.length == red.length / 2 + ); + } } - } - return false; - }).length>0; + return false; + }).length > 0 + ); }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, - ai:{combo:'huamu'}, + ai: { combo: "huamu" }, }, - liangyuan:{ - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(name=='tao'){ - return !player.hasSkill('liangyuan_tao',null,null,false)&&game.hasPlayer(function(current){ - var storage=current.getExpansions('huamu'); - return storage.length>0&&storage.filter(function(i){ - return get.color(i,false)=='red'; - }).length>0; - }); + liangyuan: { + enable: "chooseToUse", + hiddenCard: function (player, name) { + if (name == "tao") { + return ( + !player.hasSkill("liangyuan_tao", null, null, false) && + game.hasPlayer(function (current) { + var storage = current.getExpansions("huamu"); + return ( + storage.length > 0 && + storage.filter(function (i) { + return get.color(i, false) == "red"; + }).length > 0 + ); + }) + ); + } else if (name == "jiu") { + return ( + !player.hasSkill("liangyuan_jiu", null, null, false) && + game.hasPlayer(function (current) { + var storage = current.getExpansions("huamu"); + return ( + storage.length > 0 && + storage.filter(function (i) { + return get.color(i, false) == "black"; + }).length > 0 + ); + }) + ); } - else if(name=='jiu'){ - return !player.hasSkill('liangyuan_jiu',null,null,false)&&game.hasPlayer(function(current){ - var storage=current.getExpansions('huamu'); - return storage.length>0&&storage.filter(function(i){ - return get.color(i,false)=='black'; - }).length>0; + return false; + }, + filter: function (event, player) { + if (event.type == "wuxie") return false; + if ( + !player.hasSkill("liangyuan_tao", null, null, false) && + event.filterCard(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && + game.hasPlayer(function (current) { + var storage = current.getExpansions("huamu"); + return ( + storage.length > 0 && + storage.filter(function (i) { + return get.color(i, false) == "red"; + }).length > 0 + ); }) - } + ) + return true; + if ( + !player.hasSkill("liangyuan_jiu", null, null, false) && + event.filterCard(get.autoViewAs({ name: "jiu" }, "unsure"), player, event) && + game.hasPlayer(function (current) { + var storage = current.getExpansions("huamu"); + return ( + storage.length > 0 && + storage.filter(function (i) { + return get.color(i, false) == "black"; + }).length > 0 + ); + }) + ) + return true; return false; }, - filter:function(event,player){ - if(event.type=='wuxie') return false; - if(!player.hasSkill('liangyuan_tao',null,null,false)&&event.filterCard(get.autoViewAs({name:'tao'},'unsure'),player,event)&&game.hasPlayer(function(current){ - var storage=current.getExpansions('huamu'); - return storage.length>0&&storage.filter(function(i){ - return get.color(i,false)=='red'; - }).length>0; - })) return true; - if(!player.hasSkill('liangyuan_jiu',null,null,false)&&event.filterCard(get.autoViewAs({name:'jiu'},'unsure'),player,event)&&game.hasPlayer(function(current){ - var storage=current.getExpansions('huamu'); - return storage.length>0&&storage.filter(function(i){ - return get.color(i,false)=='black'; - }).length>0; - })) return true; - return false; - }, - chooseButton:{ - dialog:function(){ - return ui.create.dialog('良缘',[['tao','jiu'],'vcard'],'hidden'); + chooseButton: { + dialog: function () { + return ui.create.dialog("良缘", [["tao", "jiu"], "vcard"], "hidden"); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - var name=button.link[2],color=(name=='tao')?'red':'black'; - if(player.hasSkill('liangyuan_'+name,null,null,false)) return false; - var cards=[]; - game.countPlayer(function(current){ - cards.addArray(current.getExpansions('huamu').filter(function(i){ - return get.color(i,false)==color; - })); + filter: function (button, player) { + var evt = _status.event.getParent(); + var name = button.link[2], + color = name == "tao" ? "red" : "black"; + if (player.hasSkill("liangyuan_" + name, null, null, false)) return false; + var cards = []; + game.countPlayer(function (current) { + cards.addArray( + current.getExpansions("huamu").filter(function (i) { + return get.color(i, false) == color; + }) + ); }); - if(!cards.length) return false; - var card=get.autoViewAs({name:name},cards); - return evt.filterCard(card,player,evt); + if (!cards.length) return false; + var card = get.autoViewAs({ name: name }, cards); + return evt.filterCard(card, player, evt); }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; - var name=button.link[2],color=(name=='tao')?'red':'black'; - var cards=[]; - game.countPlayer(function(current){ - cards.addArray(current.getExpansions('huamu').filter(function(i){ - return get.color(i,false)==color; - })); + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; + var name = button.link[2], + color = name == "tao" ? "red" : "black"; + var cards = []; + game.countPlayer(function (current) { + cards.addArray( + current.getExpansions("huamu").filter(function (i) { + return get.color(i, false) == color; + }) + ); }); - var card=get.autoViewAs({name:name},cards); - return player.getUseValue(card,null,true); + var card = get.autoViewAs({ name: name }, cards); + return player.getUseValue(card, null, true); }, - backup:function(links,player){ - var name=links[0][2],color=(name=='tao')?'red':'black'; - var cards=[]; - game.countPlayer(function(current){ - cards.addArray(current.getExpansions('huamu').filter(function(i){ - return get.color(i,false)==color; - })); + backup: function (links, player) { + var name = links[0][2], + color = name == "tao" ? "red" : "black"; + var cards = []; + game.countPlayer(function (current) { + cards.addArray( + current.getExpansions("huamu").filter(function (i) { + return get.color(i, false) == color; + }) + ); }); - if(!cards.length) return false; - var card=get.autoViewAs({name:name},cards); + if (!cards.length) return false; + var card = get.autoViewAs({ name: name }, cards); return { - viewAs:card, - color:color, - selectCard:-1, - filterCard:()=>false, - precontent:function(){ - player.addTempSkill('liangyuan_'+event.result.card.name,'roundStart'); - player.logSkill('liangyuan'); - var list=[],color=lib.skill.liangyuan_backup.color; - var cards=[]; - game.countPlayer(function(current){ - var cardsx=current.getExpansions('huamu').filter(function(i){ - return get.color(i,false)==color; + viewAs: card, + color: color, + selectCard: -1, + filterCard: () => false, + precontent: function () { + player.addTempSkill("liangyuan_" + event.result.card.name, "roundStart"); + player.logSkill("liangyuan"); + var list = [], + color = lib.skill.liangyuan_backup.color; + var cards = []; + game.countPlayer(function (current) { + var cardsx = current.getExpansions("huamu").filter(function (i) { + return get.color(i, false) == color; }); - if(cardsx.length){ + if (cardsx.length) { cards.addArray(cardsx); - list.push([current,cardsx]); + list.push([current, cardsx]); current.$throw(cardsx); - game.log(current,'将',cardsx,'化作“'+(color=='black'?'灵杉':'玉树')+'”良缘') + game.log( + current, + "将", + cardsx, + "化作“" + (color == "black" ? "灵杉" : "玉树") + "”良缘" + ); } }); - event.result.cards=cards; + event.result.cards = cards; delete event.result.skill; - event.result._apply_args={'throw':false}; + event.result._apply_args = { throw: false }; game.loseAsync({ - lose_list:list, - }).setContent('chooseToCompareLose'); + lose_list: list, + }).setContent("chooseToCompareLose"); }, - } + }; }, - prompt:function(links,player){ - var name=links[0][2],color=(name=='tao')?'玉树':'灵杉'; - return '将场上所有的“'+color+'”当做【'+get.translation(name)+'】使用'; + prompt: function (links, player) { + var name = links[0][2], + color = name == "tao" ? "玉树" : "灵杉"; + return "将场上所有的“" + color + "”当做【" + get.translation(name) + "】使用"; }, }, - subSkill:{ - tao:{charlotte:true}, - jiu:{charlotte:true}, + subSkill: { + tao: { charlotte: true }, + jiu: { charlotte: true }, }, - ai:{ - order:function(item,player){ - if(!player) player=_status.event.player; - return get.order({name:lib.skill.liangyuan.hiddenCard(player,'jiu')?'jiu':'tao'})+4; + ai: { + order: function (item, player) { + if (!player) player = _status.event.player; + return ( + get.order({ + name: lib.skill.liangyuan.hiddenCard(player, "jiu") ? "jiu" : "tao", + }) + 4 + ); }, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, - combo:'huamu', - threaten:3, + combo: "huamu", + threaten: 3, }, }, - jisi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'metal', - filter:function(event,player){ - var skills=player.getStockSkills('一!','五!').filter(function(skill){ - if(skill=='jisi') return false; - var info=get.info(skill); - return info&&!info.charlotte; + jisi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + limited: true, + skillAnimation: true, + animationColor: "metal", + filter: function (event, player) { + var skills = player.getStockSkills("一!", "五!").filter(function (skill) { + if (skill == "jisi") return false; + var info = get.info(skill); + return info && !info.charlotte; }); - var history=player.getAllHistory('useSkill'); - for(var i of history){ - if(skills.includes(i.sourceSkill)||skills.includes(i.skill)) return true; + var history = player.getAllHistory("useSkill"); + for (var i of history) { + if (skills.includes(i.sourceSkill) || skills.includes(i.skill)) return true; } return false; }, - content:function(){ - 'step 0' - var skills2=[]; - var skills=player.getStockSkills('只!','因!').filter(function(skill){ - if(skill=='jisi') return false; - var info=get.info(skill); - return info&&!info.charlotte; + content: function () { + "step 0"; + var skills2 = []; + var skills = player.getStockSkills("只!", "因!").filter(function (skill) { + if (skill == "jisi") return false; + var info = get.info(skill); + return info && !info.charlotte; }); - var history=player.getAllHistory('useSkill'); - for(var i of history){ - if(skills.includes(i.sourceSkill)) skills2.add(i.sourceSkill); - if(skills.includes(i.skill)) skills2.add(i.skill); - if(skills.length==skills2.length) break; + var history = player.getAllHistory("useSkill"); + for (var i of history) { + if (skills.includes(i.sourceSkill)) skills2.add(i.sourceSkill); + if (skills.includes(i.skill)) skills2.add(i.skill); + if (skills.length == skills2.length) break; } - event.skills2=skills2; - var str='令一名其他角色获得'; - for(var i=0;i1) str+='中的一个技能'; - str+='然后你'; - if(player.countCards('h')>0) str+='弃置所有手牌,并'; - str+='视为对其使用一张【杀】'; - player.chooseTarget(get.prompt('jisi'),str,lib.filter.notMe).set('ai',function(target){ - if(!_status.event.goon) return false; - var att=get.attitude(player,target); - if(att<4) return false; - var eff=get.effect(target,{name:'sha',isCard:true},player,player); - if(eff>=0) return att+eff; - if(target.hp<=2) return false; - return att/Math.max(1,-eff); - }).set('goon',function(){ - if(player.hasUnknown()||player.identity=='nei') return false; - var hs=player.getCards('h'); - if(!hs.length||get.value(hs,player)<=9-player.hp) return true; - return false; - }()); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jisi',target); - player.awakenSkill('jisi'); - var list=event.skills2; - if(list.length==0) event._result={control:list[0]}; - player.chooseControl(list).set('prompt','令'+get.translation(target)+'获得一个技能').set( - 'ai',()=>_status.event.choice - ).set('choice',list.includes('qianmeng')?'qianmeng':list.randomGet()); - } - else event.finish(); - 'step 2' + if (skills2.length > 1) str += "中的一个技能"; + str += "然后你"; + if (player.countCards("h") > 0) str += "弃置所有手牌,并"; + str += "视为对其使用一张【杀】"; + player + .chooseTarget(get.prompt("jisi"), str, lib.filter.notMe) + .set("ai", function (target) { + if (!_status.event.goon) return false; + var att = get.attitude(player, target); + if (att < 4) return false; + var eff = get.effect(target, { name: "sha", isCard: true }, player, player); + if (eff >= 0) return att + eff; + if (target.hp <= 2) return false; + return att / Math.max(1, -eff); + }) + .set( + "goon", + (function () { + if (player.hasUnknown() || player.identity == "nei") return false; + var hs = player.getCards("h"); + if (!hs.length || get.value(hs, player) <= 9 - player.hp) return true; + return false; + })() + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jisi", target); + player.awakenSkill("jisi"); + var list = event.skills2; + if (list.length == 0) event._result = { control: list[0] }; + player + .chooseControl(list) + .set("prompt", "令" + get.translation(target) + "获得一个技能") + .set("ai", () => _status.event.choice) + .set("choice", list.includes("qianmeng") ? "qianmeng" : list.randomGet()); + } else event.finish(); + "step 2"; target.addSkills(result.control); - 'step 3' - var num=player.countCards('h'); - if(num>0) player.chooseToDiscard('h',num,true); - 'step 4' - if(player.canUse('sha',target,false)) player.useCard(false,target,{ - name:'sha', - isCard:true, - },'noai') + "step 3"; + var num = player.countCards("h"); + if (num > 0) player.chooseToDiscard("h", num, true); + "step 4"; + if (player.canUse("sha", target, false)) + player.useCard( + false, + target, + { + name: "sha", + isCard: true, + }, + "noai" + ); }, }, //周处 - shanduan:{ - audio:2, - init:function(player,name){ - player.storage[name]=[1,2,3,4]; + shanduan: { + audio: 2, + init: function (player, name) { + player.storage[name] = [1, 2, 3, 4]; }, - trigger:{player:'damageEnd'}, - filter:(event,player)=>player!=_status.currentPhase, - forced:true, - locked:false, - content:function(){ - if(!player.storage.shanduan) player.storage.shanduan=[1,2,3,4]; - var list=player.storage.shanduan; - for(var i=0;i player != _status.currentPhase, + forced: true, + locked: false, + content: function () { + if (!player.storage.shanduan) player.storage.shanduan = [1, 2, 3, 4]; + var list = player.storage.shanduan; + for (var i = 0; i < list.length; i++) { + var num = list[i], + add = true; + for (var j = 0; j < list.length; j++) { + if (list[j] < num) { + add = false; break; } } - if(add){ + if (add) { list[i]++; break; } } game.delayx(); }, - group:['shanduan_draw','shanduan_use','shanduan_discard'], - ai:{ - notemp:true, - threaten:3.6, + group: ["shanduan_draw", "shanduan_use", "shanduan_discard"], + ai: { + notemp: true, + threaten: 3.6, }, - subSkill:{ - draw:{ - audio:'shanduan', - trigger:{player:'phaseDrawBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - var list=event.getParent()._shanduan; - return !list||list.length>0; + subSkill: { + draw: { + audio: "shanduan", + trigger: { player: "phaseDrawBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + var list = event.getParent()._shanduan; + return !list || list.length > 0; }, - content:function(){ - 'step 0' - var list=trigger.getParent()._shanduan; - if(!list){ - trigger.getParent()._shanduan=(player.storage.shanduan||[1,2,3,4]).slice(0); - player.storage.shanduan=[1,2,3,4]; + content: function () { + "step 0"; + var list = trigger.getParent()._shanduan; + if (!list) { + trigger.getParent()._shanduan = ( + player.storage.shanduan || [1, 2, 3, 4] + ).slice(0); + player.storage.shanduan = [1, 2, 3, 4]; } - 'step 1' - var list=trigger.getParent()._shanduan; - if(list.length==1) event._result={index:0}; - else player.chooseControl(list).set('prompt','善断:为摸牌阶段的摸牌数分配一个数值').set('choice',list.indexOf(Math.max.apply(Math,list))).set('ai',()=>_status.event.choice); - 'step 2' - var list=trigger.getParent()._shanduan; - var num=list[result.index]; - trigger.num=num; + "step 1"; + var list = trigger.getParent()._shanduan; + if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl(list) + .set("prompt", "善断:为摸牌阶段的摸牌数分配一个数值") + .set("choice", list.indexOf(Math.max.apply(Math, list))) + .set("ai", () => _status.event.choice); + "step 2"; + var list = trigger.getParent()._shanduan; + var num = list[result.index]; + trigger.num = num; list.remove(num); - game.log(player,'给','#g摸牌阶段的摸牌数','分配的数值是','#y'+num); + game.log(player, "给", "#g摸牌阶段的摸牌数", "分配的数值是", "#y" + num); }, }, - use:{ - audio:'shanduan', - trigger:{player:'phaseUseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - var list=event.getParent()._shanduan; - return !list||list.length>0; + use: { + audio: "shanduan", + trigger: { player: "phaseUseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + var list = event.getParent()._shanduan; + return !list || list.length > 0; }, - content:function(){ - 'step 0' - var list=trigger.getParent()._shanduan; - if(!list){ - trigger.getParent()._shanduan=(player.storage.shanduan||[1,2,3,4]).slice(0); - player.storage.shanduan=[1,2,3,4]; + content: function () { + "step 0"; + var list = trigger.getParent()._shanduan; + if (!list) { + trigger.getParent()._shanduan = ( + player.storage.shanduan || [1, 2, 3, 4] + ).slice(0); + player.storage.shanduan = [1, 2, 3, 4]; } - 'step 1' - var list=trigger.getParent()._shanduan; - if(list.length==1) event._result={index:0}; - else player.chooseControl(list).set('prompt','善断:为攻击范围基数分配一个数值').set('list',list).set('ai',function(){ - var player=_status.event.player,list=_status.event.list,card={name:'sha'}; - if(player.hasSha()&&(player.hasValueTarget(card,false,true)&&!player.hasValueTarget(card,null,true))){ - var range=1; - var equips=player.getCards('e'); - for(var i=0;i 1 && distance <= i - range) + return true; + return false; + }) + ) + return list.indexOf(i); + } } - } - var listx=list.slice(0).sort(); - for(var i of listx){ - if(i<=range) continue; - if(game.hasPlayer(function(current){ - var distance=get.distance(player,current,'attack'); - if(distance>1&&distance<=(i-range)) return true; - return false; - })) return list.indexOf(i); - } - } - return list.indexOf(Math.min.apply(Math,list)); - }); - 'step 2' - var list=trigger.getParent()._shanduan; - var num=list[result.index]; - if(!player.storage.shanduan_effect) player.storage.shanduan_effect={}; - player.storage.shanduan_effect.range=num; - player.addTempSkill('shanduan_effect'); + return list.indexOf(Math.min.apply(Math, list)); + }); + "step 2"; + var list = trigger.getParent()._shanduan; + var num = list[result.index]; + if (!player.storage.shanduan_effect) player.storage.shanduan_effect = {}; + player.storage.shanduan_effect.range = num; + player.addTempSkill("shanduan_effect"); list.remove(num); - game.log(player,'给','#g攻击范围的基数','分配的数值是','#y'+num); - if(list.length==0) event.finish(); - else if(list.length==1) event._result={index:0}; - else player.chooseControl(list).set('prompt','为使用【杀】的次数上限分配一个数值').set('list',list).set('ai',function(){ - var player=_status.event.player,list=_status.event.list; - var sha=player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card,null,true); - }); - var max=player.getCardUsable('sha'); - if(sha<=max){ - var listx=list.slice(0).sort(); - for(var i of listx){ - if(max+i>=sha) return list.indexOf(i); - } - return list.indexOf(Math.max.apply(Math,list)) - } - return list.indexOf(Math.min.apply(Math,list)); - }); - 'step 3' - var list=trigger.getParent()._shanduan; - var num=list[result.index]; - if(!player.storage.shanduan_effect) player.storage.shanduan_effect={}; - player.storage.shanduan_effect.sha=num; - game.log(player,'给','#g使用【杀】的次数上限','分配的数值是','#y'+num); + game.log(player, "给", "#g攻击范围的基数", "分配的数值是", "#y" + num); + if (list.length == 0) event.finish(); + else if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl(list) + .set("prompt", "为使用【杀】的次数上限分配一个数值") + .set("list", list) + .set("ai", function () { + var player = _status.event.player, + list = _status.event.list; + var sha = player.countCards("hs", function (card) { + return ( + get.name(card) == "sha" && + player.hasValueTarget(card, null, true) + ); + }); + var max = player.getCardUsable("sha"); + if (sha <= max) { + var listx = list.slice(0).sort(); + for (var i of listx) { + if (max + i >= sha) return list.indexOf(i); + } + return list.indexOf(Math.max.apply(Math, list)); + } + return list.indexOf(Math.min.apply(Math, list)); + }); + "step 3"; + var list = trigger.getParent()._shanduan; + var num = list[result.index]; + if (!player.storage.shanduan_effect) player.storage.shanduan_effect = {}; + player.storage.shanduan_effect.sha = num; + game.log(player, "给", "#g使用【杀】的次数上限", "分配的数值是", "#y" + num); list.remove(num); }, }, - discard:{ - audio:'shanduan', - trigger:{player:'phaseDiscardBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - var list=event.getParent()._shanduan; - return !list||list.length>0; + discard: { + audio: "shanduan", + trigger: { player: "phaseDiscardBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + var list = event.getParent()._shanduan; + return !list || list.length > 0; }, - content:function(){ - 'step 0' - var list=trigger.getParent()._shanduan; - if(!list){ - trigger.getParent()._shanduan=(player.storage.shanduan||[1,2,3,4]).slice(0); - player.storage.shanduan=[1,2,3,4]; + content: function () { + "step 0"; + var list = trigger.getParent()._shanduan; + if (!list) { + trigger.getParent()._shanduan = ( + player.storage.shanduan || [1, 2, 3, 4] + ).slice(0); + player.storage.shanduan = [1, 2, 3, 4]; } - 'step 1' - var list=trigger.getParent()._shanduan; - if(list.length==1) event._result={index:0}; - else player.chooseControl(list).set('prompt','善断:为手牌上限基数分配一个数值').set('choice',list.indexOf(Math.max.apply(Math,list))).set('ai',()=>_status.event.choice); - 'step 2' - var list=trigger.getParent()._shanduan; - var num=list[result.index]; - if(!player.storage.shanduan_effect) player.storage.shanduan_effect={}; - player.storage.shanduan_effect.limit=num; - player.addTempSkill('shanduan_effect'); + "step 1"; + var list = trigger.getParent()._shanduan; + if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl(list) + .set("prompt", "善断:为手牌上限基数分配一个数值") + .set("choice", list.indexOf(Math.max.apply(Math, list))) + .set("ai", () => _status.event.choice); + "step 2"; + var list = trigger.getParent()._shanduan; + var num = list[result.index]; + if (!player.storage.shanduan_effect) player.storage.shanduan_effect = {}; + player.storage.shanduan_effect.limit = num; + player.addTempSkill("shanduan_effect"); list.remove(num); - game.log(player,'给','#g手牌上限的基数','分配的数值是','#y'+num); + game.log(player, "给", "#g手牌上限的基数", "分配的数值是", "#y" + num); }, }, - effect:{ - charlotte:true, - onremove:true, - mod:{ - attackRangeBase:function(player){ - var map=player.storage.shanduan_effect; - if(typeof map.range!='number') return; - var range=1; - var equips=player.getCards('e',function(card){ - return !ui.selected.cards||!ui.selected.cards.includes(card); + effect: { + charlotte: true, + onremove: true, + mod: { + attackRangeBase: function (player) { + var map = player.storage.shanduan_effect; + if (typeof map.range != "number") return; + var range = 1; + var equips = player.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); }); - for(var i=0;iget.value(cardx)<8); - cards.sort((a,b)=>get.value(a)-get.value(b)); - if(cards.some(cardx=>get.name(cardx)=='sha'&&!cards.slice(0,2).includes(cardx))) return player.getUseValue({name:'jiu'}); + if (evt.type == "phase") { + if (button.link[2] == "jiu") { + if (player.getUseValue({ name: "jiu" }) <= 0) return 0; + var cards = player.getCards("hs", (cardx) => get.value(cardx) < 8); + cards.sort((a, b) => get.value(a) - get.value(b)); + if ( + cards.some( + (cardx) => + get.name(cardx) == "sha" && !cards.slice(0, 2).includes(cardx) + ) + ) + return player.getUseValue({ name: "jiu" }); return 0; } - return player.getUseValue(card)/4; + return player.getUseValue(card) / 4; } return 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'yilie', - selectCard:2, - filterCard:function(card,player){ - var color=get.color(card); - if(ui.selected.cards.length) return color==get.color(ui.selected.cards[0]); - return player.hasCard(function(cardx){ - return card!=cardx&&get.color(cardx)==color; - },'hs') + audio: "yilie", + selectCard: 2, + filterCard: function (card, player) { + var color = get.color(card); + if (ui.selected.cards.length) return color == get.color(ui.selected.cards[0]); + return player.hasCard(function (cardx) { + return card != cardx && get.color(cardx) == color; + }, "hs"); }, - position:'hs', - complexCard:true, - check:(card)=>8-get.value(card), - popname:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], + position: "hs", + complexCard: true, + check: (card) => 8 - get.value(card), + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], }, - precontent:function(){ - var name=event.result.card.name; - player.addTempSkill('yilie_count','roundStart'); - player.markAuto('yilie_count',[name]); + precontent: function () { + var name = event.result.card.name; + player.addTempSkill("yilie_count", "roundStart"); + player.markAuto("yilie_count", [name]); }, - } + }; }, - prompt:function(links,player){ - var name=links[0][2]; - var nature=links[0][3]; - return '将两张颜色相同的手牌当做'+(get.translation(nature)||'')+get.translation(name)+'使用'; + prompt: function (links, player) { + var name = links[0][2]; + var nature = links[0][3]; + return ( + "将两张颜色相同的手牌当做" + + (get.translation(nature) || "") + + get.translation(name) + + "使用" + ); }, }, - ai:{ - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var add=false,max=0; - var names=lib.inpile.filter(name=>get.type(name)=='basic'&&!player.getStorage('yilie_count').includes(name)); - if(names.includes('sha')) add=true; - names=names.map(namex=>{return {name:namex}}); - if(add) lib.inpile_nature.forEach(nature=>names.push({name:'sha',nature:nature})); - names.forEach(card=>{ - if(player.getUseValue(card)>0){ - var temp=get.order(card); - if(card.name=='jiu'){ - var cards=player.getCards('hs',cardx=>get.value(cardx)<8); - cards.sort((a,b)=>get.value(a)-get.value(b)); - if(!cards.some(cardx=>get.name(cardx)=='sha'&&!cards.slice(0,2).includes(cardx))) temp=0; + ai: { + order: function (item, player) { + if (player && _status.event.type == "phase") { + var add = false, + max = 0; + var names = lib.inpile.filter( + (name) => + get.type(name) == "basic" && + !player.getStorage("yilie_count").includes(name) + ); + if (names.includes("sha")) add = true; + names = names.map((namex) => { + return { name: namex }; + }); + if (add) + lib.inpile_nature.forEach((nature) => + names.push({ name: "sha", nature: nature }) + ); + names.forEach((card) => { + if (player.getUseValue(card) > 0) { + var temp = get.order(card); + if (card.name == "jiu") { + var cards = player.getCards("hs", (cardx) => get.value(cardx) < 8); + cards.sort((a, b) => get.value(a) - get.value(b)); + if ( + !cards.some( + (cardx) => + get.name(cardx) == "sha" && + !cards.slice(0, 2).includes(cardx) + ) + ) + temp = 0; } - if(temp>max) max=temp; + if (temp > max) max = temp; } }); - if(max>0) max-=0.001; + if (max > 0) max -= 0.001; return max; } return 0.5; }, - respondShan:true, - respondSha:true, - fireAttack:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - var hs=player.getCards('hs'); - if(hs.length<2) return false; - var bool=false,map={}; - for(var card of hs){ - var color=get.color(card); - if(!map[color]) map[color]=true; - else{ - bool=true; + respondShan: true, + respondSha: true, + fireAttack: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "respond") return false; + var hs = player.getCards("hs"); + if (hs.length < 2) return false; + var bool = false, + map = {}; + for (var card of hs) { + var color = get.color(card); + if (!map[color]) map[color] = true; + else { + bool = true; break; } } - if(!bool) return false; - var storage=player.storage.yilie_count; + if (!bool) return false; + var storage = player.storage.yilie_count; var name; - switch(tag){ - case 'respondShan':name='shan';break; - default:name='sha';break; + switch (tag) { + case "respondShan": + name = "shan"; + break; + default: + name = "sha"; + break; } - if(storage&&storage.includes(name)) return false; + if (storage && storage.includes(name)) return false; }, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; - } - } + }, + }, }, - subSkill:{ - count:{charlotte:true,onremove:true}, - backup:{audio:'yilie'}, + subSkill: { + count: { charlotte: true, onremove: true }, + backup: { audio: "yilie" }, }, }, //赵俨 - tongxie:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('tongxie'),'选择至多两名其他角色作为“同协角色”',lib.filter.notMe,[0,2]).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; + tongxie: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("tongxie"), + "选择至多两名其他角色作为“同协角色”", + lib.filter.notMe, + [0, 2] + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.add(player); - player.logSkill('tongxie',targets); - player.addTempSkill('tongxie_effect',{player:'phaseBegin'}); - player.markAuto('tongxie_effect',targets); - var min=player.countCards('h'),min_player=player; - for(var i of targets){ - if(i==player) continue; - var num=i.countCards('h'); - if(num0) return true; - if(i.hasSha()) return true; + subSkill: { + effect: { + audio: "tongxie", + charlotte: true, + trigger: { global: "useCardAfter" }, + onremove: true, + forced: true, + popup: false, + filter: function (event, player) { + if ( + event.card.name != "sha" || + event.targets.length != 1 || + !event.targets[0].isIn() + ) + return false; + if (event.getParent(2).name == "tongxie_effect") return false; + var list = player.getStorage("tongxie_effect"), + target = event.targets[0]; + if (!list.includes(event.player)) return false; + for (var i of list) { + if (i == event.player || !i.isIn()) continue; + if (!i.canUse("sha", target, false)) continue; + if (_status.connectMode && i.countCards("hs") > 0) return true; + if (i.hasSha()) return true; } return false; }, - content:function(){ - 'step 0' - event.targets=player.getStorage('tongxie_effect').filter(function(i){ - return i!==trigger.player; - }).sortBySeat(); - event.target=trigger.targets[0]; - 'step 1' - var current=targets.shift(); - if(current.isIn()&&target.isIn()&¤t.canUse('sha',target,false)&&(_status.connectMode||current.hasSha())){ - current.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'同协:是否对'+get.translation(target)+'使用一张杀?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',target).set('logSkill','tongxie_effect').set('addCount',false); - if(targets.length>0) event.redo(); + content: function () { + "step 0"; + event.targets = player + .getStorage("tongxie_effect") + .filter(function (i) { + return i !== trigger.player; + }) + .sortBySeat(); + event.target = trigger.targets[0]; + "step 1"; + var current = targets.shift(); + if ( + current.isIn() && + target.isIn() && + current.canUse("sha", target, false) && + (_status.connectMode || current.hasSha()) + ) { + current + .chooseToUse( + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + "同协:是否对" + get.translation(target) + "使用一张杀?" + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", target) + .set("logSkill", "tongxie_effect") + .set("addCount", false); + if (targets.length > 0) event.redo(); } }, - group:['tongxie_damage','tongxie_count'], + group: ["tongxie_damage", "tongxie_count"], }, - damage:{ - audio:'tongxie', - charlotte:true, - trigger:{global:'damageBegin4'}, - filter:function(event,player){ - var list=player.getStorage('tongxie_effect'); - if(!list.includes(event.player)) return false; - for(var i of list){ - if(i!=event.player&&i.isIn()&&!i.hasSkill('tongxie_count2',null,null,false)) return true; + damage: { + audio: "tongxie", + charlotte: true, + trigger: { global: "damageBegin4" }, + filter: function (event, player) { + var list = player.getStorage("tongxie_effect"); + if (!list.includes(event.player)) return false; + for (var i of list) { + if ( + i != event.player && + i.isIn() && + !i.hasSkill("tongxie_count2", null, null, false) + ) + return true; } return false; }, - forced:true, - popup:false, - content:function(){ - 'step 0' - event.targets=player.getStorage('tongxie_effect').filter(function(i){ - return i!=trigger.player&&i.isIn()&&!i.hasSkill('tongxie_count2',null,null,false); - }).sortBySeat(); - event.num=0; - 'step 1' - var target=targets[num]; + forced: true, + popup: false, + content: function () { + "step 0"; + event.targets = player + .getStorage("tongxie_effect") + .filter(function (i) { + return ( + i != trigger.player && + i.isIn() && + !i.hasSkill("tongxie_count2", null, null, false) + ); + }) + .sortBySeat(); + event.num = 0; + "step 1"; + var target = targets[num]; event.num++; - event.target=target; - target.chooseBool('同协:是否为'+get.translation(trigger.player)+'阻挡伤害?','失去1点体力,防止'+get.translation(trigger.player)+'即将受到的'+get.cnNumber(trigger.num)+'点伤害').set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().player; - var trigger=_status.event.getTrigger(); - var eff1=get.damageEffect(target,trigger.source,player,trigger.nature); - if(trigger.num>1) eff1=Math.min(-1,eff1)*trigger.num; - var eff2=get.effect(player,{name:'losehp'},player,player); - return eff2>eff1; - }); - 'step 2' - if(result.bool){ - target.logSkill('tongxie_damage',trigger.player); + event.target = target; + target + .chooseBool( + "同协:是否为" + get.translation(trigger.player) + "阻挡伤害?", + "失去1点体力,防止" + + get.translation(trigger.player) + + "即将受到的" + + get.cnNumber(trigger.num) + + "点伤害" + ) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player; + var trigger = _status.event.getTrigger(); + var eff1 = get.damageEffect( + target, + trigger.source, + player, + trigger.nature + ); + if (trigger.num > 1) eff1 = Math.min(-1, eff1) * trigger.num; + var eff2 = get.effect(player, { name: "losehp" }, player, player); + return eff2 > eff1; + }); + "step 2"; + if (result.bool) { + target.logSkill("tongxie_damage", trigger.player); trigger.cancel(); target.loseHp(); - } - else if(num=to.hp) return -Infinity; + olzhuiji: { + mod: { + globalFrom: function (from, to) { + if (from.hp >= to.hp) return -Infinity; }, }, - trigger:{player:'useCardToPlayered'}, - shaRelated:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('he')>0&&get.distance(player,event.target)==1; + trigger: { player: "useCardToPlayered" }, + shaRelated: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.target.countCards("he") > 0 && + get.distance(player, event.target) == 1 + ); }, - forced:true, - logTarget:'target', - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - if(target.countCards('e')==0) event._result={index:0}; - else target.chooseControl().set('choiceList',[ - '弃置一张牌', - '重铸装备区的所有牌', - ]).set('ai',function(card){ - var min=Infinity,equ=0,es=player.getCards('e'),hs=player.getCards('he'); - for(var i of hs){ - var val=get.value(i); - min=Math.min(min,val); - if(es.includes(i)) equ+=val; - } - equ/=es.length; - if(min1) return; - var card=get.cards()[0]; - if(!card) return; - game.log(player,'展示了',card); + var sendback = function (result, player) { + if (result) { + var index = result.index; + game.log(player, "选择了", ["#b助力锻造", "#g妨碍锻造", "#b什么都不做"][index]); + if (index > 1) return; + var card = get.cards()[0]; + if (!card) return; + game.log(player, "展示了", card); event.cardsx.push(card); event.cards2[index].push(card); - game.broadcastAll(function(id,card,name,index){ - var dialog=get.idDialog(id); - if(!dialog) return; - var button=ui.create.button(card,'card',dialog.buttonss[index]); - button.querySelector('.info').innerHTML=(name+'|'+get.strNumber(card.number)); - },event.videoId,card,function(target){ - if(target._tempTranslate) return target._tempTranslate; - var name=target.name; - if(lib.translate[name+'_ab']) return lib.translate[name+'_ab']; - return get.translation(name); - }(player),index); + game.broadcastAll( + function (id, card, name, index) { + var dialog = get.idDialog(id); + if (!dialog) return; + var button = ui.create.button(card, "card", dialog.buttonss[index]); + button.querySelector(".info").innerHTML = + name + "|" + get.strNumber(card.number); + }, + event.videoId, + card, + (function (target) { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; + return get.translation(name); + })(player), + index + ); } }; - event.players=game.filterPlayer(); - event.cardsx=[]; - event.cards2=[[],[]]; - event.videoId=lib.status.videoId++; - event.ai_targets=[]; - game.broadcastAll(function(name,id){ - var dialog=ui.create.dialog(name+'发起了“锻造”','hidden','forcebutton'); - dialog.videoId=id; - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - ui.arena.classList.add('choose-to-move'); - dialog.buttonss=[]; + event.players = game.filterPlayer(); + event.cardsx = []; + event.cards2 = [[], []]; + event.videoId = lib.status.videoId++; + event.ai_targets = []; + game.broadcastAll( + function (name, id) { + var dialog = ui.create.dialog(name + "发起了“锻造”", "hidden", "forcebutton"); + dialog.videoId = id; + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + ui.arena.classList.add("choose-to-move"); + dialog.buttonss = []; - var list=['协力锻造的玩家','妨碍锻造的玩家'] - for(var i=0;i'+list[i]+''); - var buttons=ui.create.div('.buttons',dialog.content); - dialog.buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - } - dialog.open(); - },get.translation(player),event.videoId) - for(var i=0;i' + list[i] + ""); + var buttons = ui.create.div(".buttons", dialog.content); + dialog.buttonss.push(buttons); + buttons.classList.add("popup"); + buttons.classList.add("guanxing"); + } + dialog.open(); + }, + get.translation(player), + event.videoId + ); + for (var i = 0; i < event.players.length; i++) { + if (event.players[i] == player) { + sendback({ index: 0 }, player); + } else if (event.players[i].isOnline()) { + event.withol = true; event.players[i].send(send); event.players[i].wait(sendback); - } - else if(event.players[i]==game.me){ - event.withme=true; - game.me.chooseControl('助力锻造!','妨碍锻造!','什么都不做'); - if(_status.connectMode) game.me.wait(sendback); - } - else{ + } else if (event.players[i] == game.me) { + event.withme = true; + game.me.chooseControl("助力锻造!", "妨碍锻造!", "什么都不做"); + if (_status.connectMode) game.me.wait(sendback); + } else { event.ai_targets.push(event.players[i]); - if(_status.connectMode) event.players[i].showTimer(); + if (_status.connectMode) event.players[i].showTimer(); } } - if(event.ai_targets.length){ + if (event.ai_targets.length) { event.ai_targets.randomSort(); - setTimeout(function(){ - event.interval=setInterval(function(){ - var target=event.ai_targets.shift(); - var att=get.attitude(target,player); - var num=2; - if(att>0) num=0; - else if(att<0) num=1; - sendback({index:num},target); - if(_status.connectMode) target.hideTimer(); - if(!event.ai_targets.length){ + setTimeout(function () { + event.interval = setInterval(function () { + var target = event.ai_targets.shift(); + var att = get.attitude(target, player); + var num = 2; + if (att > 0) num = 0; + else if (att < 0) num = 1; + sendback({ index: num }, target); + if (_status.connectMode) target.hideTimer(); + if (!event.ai_targets.length) { clearInterval(event.interval); - if(event.withai) game.resume(); + if (event.withai) game.resume(); } - },750); - },500) + }, 750); + }, 500); } - 'step 1' - if(event.withme){ - if(_status.connectMode) game.me.unwait(result); - else{ - var index=result.index; - game.log(game.me,'选择了',['#b助力锻造','#g妨碍锻造','#b什么都不做'][index]) - if(index>1) return; - var card=get.cards()[0]; - if(!card) return; - game.log(game.me,'展示了',card); + "step 1"; + if (event.withme) { + if (_status.connectMode) game.me.unwait(result); + else { + var index = result.index; + game.log(game.me, "选择了", ["#b助力锻造", "#g妨碍锻造", "#b什么都不做"][index]); + if (index > 1) return; + var card = get.cards()[0]; + if (!card) return; + game.log(game.me, "展示了", card); event.cardsx.push(card); event.cards2[index].push(card); - game.broadcastAll(function(id,card,name,index){ - var dialog=get.idDialog(id); - if(!dialog) return; - var button=ui.create.button(card,'card',dialog.buttonss[index]); - button.querySelector('.info').innerHTML=(name+'|'+get.strNumber(card.number)); - },event.videoId,card,function(target){ - if(target._tempTranslate) return target._tempTranslate; - var name=target.name; - if(lib.translate[name+'_ab']) return lib.translate[name+'_ab']; - return get.translation(name); - }(game.me),index); + game.broadcastAll( + function (id, card, name, index) { + var dialog = get.idDialog(id); + if (!dialog) return; + var button = ui.create.button(card, "card", dialog.buttonss[index]); + button.querySelector(".info").innerHTML = + name + "|" + get.strNumber(card.number); + }, + event.videoId, + card, + (function (target) { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; + return get.translation(name); + })(game.me), + index + ); } } - 'step 2' - if(event.withol&&!event.resultOL){ + "step 2"; + if (event.withol && !event.resultOL) { game.pause(); } - 'step 3' - if(event.ai_targets.length>0){ - event.withai=true; + "step 3"; + if (event.ai_targets.length > 0) { + event.withai = true; game.pause(); } - 'step 4' - game.broadcastAll(function(){ - setTimeout(function(){ - ui.arena.classList.remove('choose-to-move'); - },500); - }) + "step 4"; + game.broadcastAll(function () { + setTimeout(function () { + ui.arena.classList.remove("choose-to-move"); + }, 500); + }); game.delay(2); - var num1=0,num2=0; - for(var i of event.cards2[0]) num1+=get.number(i,false); - for(var i of event.cards2[1]) num2+=get.number(i,false); - var result=2; - if(num10) result=1; - event.duanzao_result=result; - game.broadcastAll(function(id,result){ - var dialog=get.idDialog(id); - if(dialog) dialog.content.firstChild.innerHTML=['锻造失败…','锻造成功','完美锻造!'][result]; - },event.videoId,result) - 'step 5' + var num1 = 0, + num2 = 0; + for (var i of event.cards2[0]) num1 += get.number(i, false); + for (var i of event.cards2[1]) num2 += get.number(i, false); + var result = 2; + if (num1 < num2) result = 0; + else if (num2 > 0) result = 1; + event.duanzao_result = result; + game.broadcastAll( + function (id, result) { + var dialog = get.idDialog(id); + if (dialog) + dialog.content.firstChild.innerHTML = ["锻造失败…", "锻造成功", "完美锻造!"][ + result + ]; + }, + event.videoId, + result + ); + "step 5"; game.cardsGotoOrdering(event.cardsx); - game.broadcastAll('closeDialog',event.videoId); - 'step 6' - var subtype=get.subtype(cards[0]); - if(subtype!='equip1'&&subtype!='equip2') subtype='others'; - var card_map={ - equip1:[ - ['diamond',13,'bintieshuangji'], - ['diamond',1,'wuxinghelingshan'], - ['spade',13,'wutiesuolian'], - ['diamond',12,'wushuangfangtianji'], - ['spade',6,'chixueqingfeng'], - ['spade',5,'guilongzhanyuedao'], + game.broadcastAll("closeDialog", event.videoId); + "step 6"; + var subtype = get.subtype(cards[0]); + if (subtype != "equip1" && subtype != "equip2") subtype = "others"; + var card_map = { + equip1: [ + ["diamond", 13, "bintieshuangji"], + ["diamond", 1, "wuxinghelingshan"], + ["spade", 13, "wutiesuolian"], + ["diamond", 12, "wushuangfangtianji"], + ["spade", 6, "chixueqingfeng"], + ["spade", 5, "guilongzhanyuedao"], ], - equip2:[ - ['club',1,'huxinjing'], - ['club',2,'heiguangkai'], - ['spade',2,'linglongshimandai'], - ['club',1,'hongmianbaihuapao'], - ['spade',2,'qimenbagua'], - ['spade',9,'guofengyupao'], + equip2: [ + ["club", 1, "huxinjing"], + ["club", 2, "heiguangkai"], + ["spade", 2, "linglongshimandai"], + ["club", 1, "hongmianbaihuapao"], + ["spade", 2, "qimenbagua"], + ["spade", 9, "guofengyupao"], ], - others:[ - ['diamond',1,'zhaogujing'], - ['spade',5,'sanlve'], - ['club',12,'tianjitu'], - ['spade',2,'taigongyinfu'], - ['diamond',1,'shufazijinguan'], - ['club',4,'xuwangzhimian'], + others: [ + ["diamond", 1, "zhaogujing"], + ["spade", 5, "sanlve"], + ["club", 12, "tianjitu"], + ["spade", 2, "taigongyinfu"], + ["diamond", 1, "shufazijinguan"], + ["club", 4, "xuwangzhimian"], ], }; - if(!_status.olshengong_map) _status.olshengong_map={}; - if(!_status.olshengong_maken) _status.olshengong_maken={}; - var list=card_map[subtype]; - for(var i=0;i0; + draw: { + audio: "olshengong", + trigger: { global: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return player.countMark("olshengong_draw") > 0; }, - content:function(){ - player.draw(player.countMark('olshengong_draw')); + content: function () { + player.draw(player.countMark("olshengong_draw")); }, }, }, }, - olqisi:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ - return !event.numFixed&&event.num>0; + olqisi: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { + return !event.numFixed && event.num > 0; }, - check:function(event,player){ - if(player.hasEmptySlot(2)||player.hasEmptySlot(5)||player.hasEmptySlot(1)) return true; + check: function (event, player) { + if (player.hasEmptySlot(2) || player.hasEmptySlot(5) || player.hasEmptySlot(1)) + return true; return false; }, - prompt2:'摸牌阶段开始时,你可以少摸一张牌并声明一种装备牌的副类别,然后从牌堆或弃牌堆中获得一张该副类别的牌。', - content:function(){ - 'step 0' - player.chooseControl('equip1','equip2','equip6','equip5').set('prompt','选择获得一种副类别的装备牌').set('ai',function(card){ - if(player.hasEmptySlot(2)) return 'equip2'; - if(player.hasEmptySlot(5)) return 'equip5'; - if(player.hasEmptySlot(1)) return 'equip1'; - return 'equip6'; + prompt2: + "摸牌阶段开始时,你可以少摸一张牌并声明一种装备牌的副类别,然后从牌堆或弃牌堆中获得一张该副类别的牌。", + content: function () { + "step 0"; + player + .chooseControl("equip1", "equip2", "equip6", "equip5") + .set("prompt", "选择获得一种副类别的装备牌") + .set("ai", function (card) { + if (player.hasEmptySlot(2)) return "equip2"; + if (player.hasEmptySlot(5)) return "equip5"; + if (player.hasEmptySlot(1)) return "equip1"; + return "equip6"; + }); + "step 1"; + var card = get.cardPile(function (card) { + var type = get.subtype(card); + if (result.control == "equip6") return type == "equip3" || type == "equip4"; + return type == result.control; }); - 'step 1' - var card=get.cardPile(function(card){ - var type=get.subtype(card); - if(result.control=='equip6') return (type=='equip3'||type=='equip4'); - return type==result.control; - }); - if(card){ + if (card) { trigger.num--; - player.gain(card,'gain2'); + player.gain(card, "gain2"); } }, - group:'olqisi_init', - subSkill:{ - init:{ - audio:'olqisi', - trigger:{ - global:'phaseBefore', - player:'enterGame', + group: "olqisi_init", + subSkill: { + init: { + audio: "olqisi", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var i=0; - var list=[]; - while(i++<2){ - var card=get.cardPile(function(card){ - if(get.type(card)!='equip') return false; - return list.length==0||get.subtype(card)!=get.subtype(list[0]); + content: function () { + "step 0"; + var i = 0; + var list = []; + while (i++ < 2) { + var card = get.cardPile(function (card) { + if (get.type(card) != "equip") return false; + return list.length == 0 || get.subtype(card) != get.subtype(list[0]); }); - if(card) list.push(card); + if (card) list.push(card); } - if(!list.length){event.finish();return;} - event.list=list; - player.gain(event.list,'gain2'); - 'step 1' + if (!list.length) { + event.finish(); + return; + } + event.list = list; + player.gain(event.list, "gain2"); + "step 1"; game.delay(1); - var card=event.list.shift(); - if(player.getCards('h').includes(card)){ - player.$give(card,player,false) + var card = event.list.shift(); + if (player.getCards("h").includes(card)) { + player.$give(card, player, false); player.equip(card); } - if(event.list.length) event.redo(); + if (event.list.length) event.redo(); }, }, }, }, //蒲元衍生 - zhaogujing_skill:{ - equipSkill:true, - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.hasCard(function(card){ - if(_status.connectMode) return true; - var type=get.type(card,player); - return type=='basic'||type=='trick'; - },'h'); + zhaogujing_skill: { + equipSkill: true, + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.hasCard(function (card) { + if (_status.connectMode) return true; + var type = get.type(card, player); + return type == "basic" || type == "trick"; + }, "h"); }, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('zhaogujing_skill'),'展示并视为使用一张基本牌或普通锦囊牌',function(card,player){ - var type=get.type(card,player); - return type=='basic'||type=='trick'; - }).set('ai',function(card){ - var player=_status.event.player,name=get.name(card,player); - if(name=='jiu') return 0; - return player.getUseValue({ - name:name, - nature:get.nature(card,player), - isCard:true, - }) - }); - 'step 1' - if(result.bool){ - player.logSkill('zhaogujing_skill'); - player.showCards(result.cards,get.translation(player)+'发动了【照骨镜】'); - var card={ - name:get.name(result.cards[0],player), - nature:get.nature(result.cards[0],player), - isCard:true, - } - player.chooseUseTarget(card,true,false); + content: function () { + "step 0"; + player + .chooseCard( + "h", + get.prompt("zhaogujing_skill"), + "展示并视为使用一张基本牌或普通锦囊牌", + function (card, player) { + var type = get.type(card, player); + return type == "basic" || type == "trick"; + } + ) + .set("ai", function (card) { + var player = _status.event.player, + name = get.name(card, player); + if (name == "jiu") return 0; + return player.getUseValue({ + name: name, + nature: get.nature(card, player), + isCard: true, + }); + }); + "step 1"; + if (result.bool) { + player.logSkill("zhaogujing_skill"); + player.showCards(result.cards, get.translation(player) + "发动了【照骨镜】"); + var card = { + name: get.name(result.cards[0], player), + nature: get.nature(result.cards[0], player), + isCard: true, + }; + player.chooseUseTarget(card, true, false); } }, }, - sanlve_skill:{ - equipSkill:true, - mod:{ - maxHandcard:function(player,num){ - return num+1; + sanlve_skill: { + equipSkill: true, + mod: { + maxHandcard: function (player, num) { + return num + 1; }, - attackRange:function(player,num){ - return num+1; + attackRange: function (player, num) { + return num + 1; }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, - xuwangzhimian:{ - equipSkill:true, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ + xuwangzhimian: { + equipSkill: true, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=2; + content: function () { + trigger.num += 2; + }, + mod: { + maxHandcard: function (player, num) { + return num - 1; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num-1; - } - } }, - shufazijinguan_skill:{ - equipSkill:true, - trigger:{ - player:"phaseZhunbeiBegin", + shufazijinguan_skill: { + equipSkill: true, + trigger: { + player: "phaseZhunbeiBegin", }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('shufazijinguan'),'对一名其他角色造成1点伤害',function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - return get.damageEffect(target,player,player); - }); - "step 1" - if(result.bool){ - player.logSkill('shufazijinguan_skill',result.targets[0]); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("shufazijinguan"), + "对一名其他角色造成1点伤害", + function (card, player, target) { + return player != target; + } + ) + .set("ai", function (target) { + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("shufazijinguan_skill", result.targets[0]); result.targets[0].damage(); } }, }, - qimenbagua:{ - equipSkill:true, - trigger:{target:'useCardToBefore'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.player.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; - return true; - }, - content:function(){ - trigger.cancel(); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name!='sha') return; - if(target.hasSkillTag('unequip2')||player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:player, - card:card - })) return; - return 'zerotarget'; - } - } - } - }, - guofengyupao:{ - equipSkill:true, - mod:{ - targetEnabled:function(card,player,target){ - if(player==target||get.type(card)!='trick') return; - if(target.hasSkillTag('unequip2')) return; - if(player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })) return; + qimenbagua: { + equipSkill: true, + trigger: { target: "useCardToBefore" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.player.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) return false; - } - } - }, - hongmianbaihuapao_skill:{ - equipSkill:true, - trigger:{ - player:"damageBegin4", - }, - filter:function(event,player){ - if(!event.hasNature('linked')) return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source&&event.source.hasSkillTag('unequip',false,{ - name:event.card?event.card.name:null, - target:player, - card:event.card - })) return false; return true; }, - forced:true, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - nofire:true, - nothunder:true, - effect:{ - target:function(card,player,target,current){ - if(!get.tag(card,'natureDamage')) return; - if(!target.hasSkillTag('unequip2')&&!player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })&&!player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:player, - card:card - })) return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target) { + if (card.name != "sha") return; + if ( + target.hasSkillTag("unequip2") || + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return; + return "zerotarget"; }, }, }, }, - linglongshimandai_skill:{ - equipSkill:true, - trigger:{ - target:"useCardToTargeted", + guofengyupao: { + equipSkill: true, + mod: { + targetEnabled: function (card, player, target) { + if (player == target || get.type(card) != "trick") return; + if (target.hasSkillTag("unequip2")) return; + if ( + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return; + return false; + }, }, - filter:function(event,player){ - if(event.targets&&event.targets.length>1||event.player==player) return false; - if(player.hasSkillTag('unequip2')) return false; - var evt=event.getParent(); - if(evt.player&&evt.player.hasSkillTag('unequip',false,{ - name:evt.card?evt.card.name:null, - target:player, - card:evt.card - })) return false; + }, + hongmianbaihuapao_skill: { + equipSkill: true, + trigger: { + player: "damageBegin4", + }, + filter: function (event, player) { + if (!event.hasNature("linked")) return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source && + event.source.hasSkillTag("unequip", false, { + name: event.card ? event.card.name : null, + target: player, + card: event.card, + }) + ) + return false; return true; }, - audio:true, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)<=0; + forced: true, + content: function () { + trigger.cancel(); }, - prompt2:(event)=>('进行一次判定。若结果为♥,则'+get.translation(event.card)+'对你无效'), - content:function(){ - "step 0" - player.judge('linglongshimandai',function(card){return (get.suit(card)=='heart')?1.5:-0.5}).judge2=function(result){ - return result.bool?true:false; + ai: { + nofire: true, + nothunder: true, + effect: { + target: function (card, player, target, current) { + if (!get.tag(card, "natureDamage")) return; + if ( + !target.hasSkillTag("unequip2") && + !player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) && + !player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return "zerotarget"; + }, + }, + }, + }, + linglongshimandai_skill: { + equipSkill: true, + trigger: { + target: "useCardToTargeted", + }, + filter: function (event, player) { + if ((event.targets && event.targets.length > 1) || event.player == player) return false; + if (player.hasSkillTag("unequip2")) return false; + var evt = event.getParent(); + if ( + evt.player && + evt.player.hasSkillTag("unequip", false, { + name: evt.card ? evt.card.name : null, + target: player, + card: evt.card, + }) + ) + return false; + return true; + }, + audio: true, + check: function (event, player) { + return get.effect(player, event.card, event.player, player) <= 0; + }, + prompt2: (event) => "进行一次判定。若结果为♥,则" + get.translation(event.card) + "对你无效", + content: function () { + "step 0"; + player.judge("linglongshimandai", function (card) { + return get.suit(card) == "heart" ? 1.5 : -0.5; + }).judge2 = function (result) { + return result.bool ? true : false; }; - "step 1" - if(result.judge>0){ + "step 1"; + if (result.judge > 0) { trigger.getParent().excluded.add(player); } }, - ai:{ - effect:{ - target:function(card,player,target,effect){ - if(effect>0||player.hasSkillTag('unequip',false,{ - name:card?card.name:null, - target:player, - card:card - })||player.hasSkillTag('unequip_ai',false,{ - name:card?card.name:null, - target:player, - card:card - })) return; + ai: { + effect: { + target: function (card, player, target, effect) { + if ( + effect > 0 || + player.hasSkillTag("unequip", false, { + name: card ? card.name : null, + target: player, + card: card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: card ? card.name : null, + target: player, + card: card, + }) + ) + return; return 0.75; }, }, }, }, - bintieshuangji_skill:{ - trigger:{player:'shaMiss'}, - filter:function(event,player){ - return player.hp>0; + bintieshuangji_skill: { + trigger: { player: "shaMiss" }, + filter: function (event, player) { + return player.hp > 0; }, - prompt2:function(event,player){ - var prompt='失去1点体力,然后'; - var cards=event.cards.filterInD(); - if(cards.length) prompt+=('获得'+get.translation(cards)+'、'); - prompt+='摸一张牌、本回合使用【杀】的次数上限+1'; + prompt2: function (event, player) { + var prompt = "失去1点体力,然后"; + var cards = event.cards.filterInD(); + if (cards.length) prompt += "获得" + get.translation(cards) + "、"; + prompt += "摸一张牌、本回合使用【杀】的次数上限+1"; return prompt; }, - check:function(event,player){ - if(get.effect(player,{name:'losehp'},player,player)>0) return true; - return player.hp>event.target.hp&&event.cards.filterInD().length>0; + check: function (event, player) { + if (get.effect(player, { name: "losehp" }, player, player) > 0) return true; + return player.hp > event.target.hp && event.cards.filterInD().length > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - 'step 1' - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2'); + "step 1"; + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2"); player.draw(); - 'step 2' - player.addTempSkill('bintieshuangji_skill_effect'); - player.addMark('bintieshuangji_skill_effect',1,false); + "step 2"; + player.addTempSkill("bintieshuangji_skill_effect"); + player.addMark("bintieshuangji_skill_effect", 1, false); }, - subSkill:{ - effect:{ - charlotte:true, - intro:{content:'使用【杀】的次数上限+#'}, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('bintieshuangji_skill_effect'); + subSkill: { + effect: { + charlotte: true, + intro: { content: "使用【杀】的次数上限+#" }, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") + return num + player.countMark("bintieshuangji_skill_effect"); }, }, }, }, }, - chixueqingfeng:{ - equipSkill:true, - trigger:{player:'useCardToPlayered'}, - filter:function(event){ - return event.card.name=='sha'; + chixueqingfeng: { + equipSkill: true, + trigger: { player: "useCardToPlayered" }, + filter: function (event) { + return event.card.name == "sha"; }, - logTarget:'target', - forced:true, - content:function(){ - var target=trigger.target; - target.addTempSkill('chixueqingfeng2'); - target.markAuto('chixueqingfeng2',[trigger.card]) + logTarget: "target", + forced: true, + content: function () { + var target = trigger.target; + target.addTempSkill("chixueqingfeng2"); + target.markAuto("chixueqingfeng2", [trigger.card]); }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha') return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha") return true; return false; - } - } - }, - chixueqingfeng2:{ - equipSkill:true, - trigger:{global:'useCardAfter'}, - forced:true, - charlotte:true, - popup:false, - firstDo:true, - onremove:true, - filter:function(event,player){ - return player.storage.chixueqingfeng2&&player.storage.chixueqingfeng2.includes(event.card); - }, - content:function(){ - player.storage.chixueqingfeng2.remove(trigger.card); - if(!player.storage.chixueqingfeng2.length) player.removeSkill('chixueqingfeng2'); - }, - mark:true, - marktext:'※', - intro:{ - content:'防具技能无效,且不能使用或打出手牌', - }, - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; }, }, - ai:{ - unequip2:true, + }, + chixueqingfeng2: { + equipSkill: true, + trigger: { global: "useCardAfter" }, + forced: true, + charlotte: true, + popup: false, + firstDo: true, + onremove: true, + filter: function (event, player) { + return ( + player.storage.chixueqingfeng2 && player.storage.chixueqingfeng2.includes(event.card) + ); + }, + content: function () { + player.storage.chixueqingfeng2.remove(trigger.card); + if (!player.storage.chixueqingfeng2.length) player.removeSkill("chixueqingfeng2"); + }, + mark: true, + marktext: "※", + intro: { + content: "防具技能无效,且不能使用或打出手牌", + }, + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; + }, + }, + ai: { + unequip2: true, }, }, - guilongzhanyuedao:{ - equipSkill:true, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&get.color(event.card)=='red'; + guilongzhanyuedao: { + equipSkill: true, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && get.color(event.card) == "red"; }, - content:function(){ + content: function () { trigger.directHit.addArray(game.players); }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha'&&get.color(arg.card)=='red') return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha" && get.color(arg.card) == "red") + return true; return false; - } - } + }, + }, }, - wushuangfangtianji_skill:{ - equipSkill:true, - trigger:{ - source:"damageSource", + wushuangfangtianji_skill: { + equipSkill: true, + trigger: { + source: "damageSource", }, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent().type=='card'; + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.getParent().type == "card"; }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.player; - var choices=['摸一张牌']; - if(target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he')) choices.push('弃置'+get.translation(target)+'的一张牌'); - player.chooseControl('cancel2').set('choiceList',choices).set('prompt',get.prompt('wushuangfangtianji_skill')).set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().player; - if(target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he')&&get.effect(target,{name:'guohe_copy2'},player,player)>get.effect(player,{name:'draw'},player,player)) return 1; - return 0; - }); - 'step 1' - if(result.control=='cancel2') return; - if(result.index==0){ - player.logSkill('wushuangfangtianji_skill'); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + var choices = ["摸一张牌"]; + if ( + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ) + choices.push("弃置" + get.translation(target) + "的一张牌"); + player + .chooseControl("cancel2") + .set("choiceList", choices) + .set("prompt", get.prompt("wushuangfangtianji_skill")) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player; + if ( + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") && + get.effect(target, { name: "guohe_copy2" }, player, player) > + get.effect(player, { name: "draw" }, player, player) + ) + return 1; + return 0; + }); + "step 1"; + if (result.control == "cancel2") return; + if (result.index == 0) { + player.logSkill("wushuangfangtianji_skill"); player.draw(); - } - else{ - var target=trigger.player; - player.logSkill('wushuangfangtianji_skill',target); - player.discardPlayerCard(target,'he',true); + } else { + var target = trigger.player; + player.logSkill("wushuangfangtianji_skill", target); + player.discardPlayerCard(target, "he", true); } }, }, //芮姬 - qiaoli:{ - onChooseToUse:function(event){ - if(event.type=='phase'&&!game.online&&!(event.qiaoli_equip1&&event.qiaoli_noequip1)){ - var player=event.player; - var evt=event.getParent('phaseUse'); - if(player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt&&evtx.skill=='qiaoli'&&get.subtype(evtx.cards[0])=='equip1'; - }).length) event.set('qiaoli_equip1',true); - if(player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt&&evtx.skill=='qiaoli'&&get.subtype(evtx.cards[0])!='equip1'; - }).length) event.set('qiaoli_noequip1',true); + qiaoli: { + onChooseToUse: function (event) { + if ( + event.type == "phase" && + !game.online && + !(event.qiaoli_equip1 && event.qiaoli_noequip1) + ) { + var player = event.player; + var evt = event.getParent("phaseUse"); + if ( + player.getHistory("useCard", function (evtx) { + return ( + evtx.getParent("phaseUse") == evt && + evtx.skill == "qiaoli" && + get.subtype(evtx.cards[0]) == "equip1" + ); + }).length + ) + event.set("qiaoli_equip1", true); + if ( + player.getHistory("useCard", function (evtx) { + return ( + evtx.getParent("phaseUse") == evt && + evtx.skill == "qiaoli" && + get.subtype(evtx.cards[0]) != "equip1" + ); + }).length + ) + event.set("qiaoli_noequip1", true); } }, - audio:2, - enable:'phaseUse', - viewAs:{ - name:'juedou', - qiaoli:true, + audio: 2, + enable: "phaseUse", + viewAs: { + name: "juedou", + qiaoli: true, }, - filterCard:function(card,player){ - if(get.type(card)!='equip') return false; - var event=_status.event; - if(get.subtype(card)=='equip1'&&event.qiaoli_equip1) return false; - if(get.subtype(card)!='equip1'&&event.qiaoli_noequip1) return false; + filterCard: function (card, player) { + if (get.type(card) != "equip") return false; + var event = _status.event; + if (get.subtype(card) == "equip1" && event.qiaoli_equip1) return false; + if (get.subtype(card) != "equip1" && event.qiaoli_noequip1) return false; return true; }, - viewAsFilter:function(player){ - return player.isPhaseUsing()&&player.hasCard(function(card){ - return lib.skill.qiaoli.filterCard(card,player); - },'hes'); + viewAsFilter: function (player) { + return ( + player.isPhaseUsing() && + player.hasCard(function (card) { + return lib.skill.qiaoli.filterCard(card, player); + }, "hes") + ); }, - check:function(card){ - if(get.position(card)=='e') return 7.5-get.value(card); - return 12-_status.event.player.getUseValue(card); + check: function (card) { + if (get.position(card) == "e") return 7.5 - get.value(card); + return 12 - _status.event.player.getUseValue(card); }, - position:'hes', - precontent:function(){ - player.addTempSkill('qiaoli_norespond'); - player.addTempSkill('qiaoli_effect'); + position: "hes", + precontent: function () { + player.addTempSkill("qiaoli_norespond"); + player.addTempSkill("qiaoli_effect"); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg&&arg.card&&arg.card.name=='juedou'&&_status.event.skill=='qiaoli'; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return ( + arg && arg.card && arg.card.name == "juedou" && _status.event.skill == "qiaoli" + ); }, }, - subSkill:{ - norespond:{ - charlotte:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return event.card.qiaoli&&get.subtype(event.cards[0])!='equip1'; + subSkill: { + norespond: { + charlotte: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return event.card.qiaoli && get.subtype(event.cards[0]) != "equip1"; }, - forced:true, - popup:false, - content:function(){ - player.addTempSkill('qiaoli_gain'); + forced: true, + popup: false, + content: function () { + player.addTempSkill("qiaoli_gain"); trigger.directHit.addArray(game.players); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, }, - effect:{ - charlotte:true, - trigger:{source:'damageSource'}, - filter:function(event,player){ - return event.card&&event.cards&&event.card.qiaoli&&get.subtype(event.cards[0])=='equip1'; + effect: { + charlotte: true, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return ( + event.card && + event.cards && + event.card.qiaoli && + get.subtype(event.cards[0]) == "equip1" + ); }, - forced:true, - popup:false, - content:function(){ - 'step 0' - var card=trigger.cards[0]; - var num=1; - var info=get.info(card,false); - if(info&&info.distance&&typeof info.distance.attackFrom=='number') num-=info.distance.attackFrom; + forced: true, + popup: false, + content: function () { + "step 0"; + var card = trigger.cards[0]; + var num = 1; + var info = get.info(card, false); + if (info && info.distance && typeof info.distance.attackFrom == "number") + num -= info.distance.attackFrom; player.draw(num); - 'step 1' - var cards=result; - if(get.itemtype(cards)!='cards'){ + "step 1"; + var cards = result; + if (get.itemtype(cards) != "cards") { event.finish(5); return; } - var hs=player.getCards('h'); - cards=cards.filter(function(card){ + var hs = player.getCards("h"); + cards = cards.filter(function (card) { return hs.includes(card); }); - if(!cards.length){ + if (!cards.length) { event.finish(5); return; } - event.cards=cards; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 2' + event.cards = cards; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + event.given_map = {}; + "step 2"; player.chooseCardTarget({ - filterCard:function(card){ - return _status.event.cards.includes(card)&&!card.hasGaintag('qiaoli_given'); + filterCard: function (card) { + return ( + _status.event.cards.includes(card) && !card.hasGaintag("qiaoli_given") + ); }, - cards:cards, - filterTarget:lib.filter.notMe, - selectCard:[1,cards.length], - prompt:'是否将获得的牌分配给其他角色?', - ai1:function(card){ + cards: cards, + filterTarget: lib.filter.notMe, + selectCard: [1, cards.length], + prompt: "是否将获得的牌分配给其他角色?", + ai1: function (card) { return -1; }, - ai2:function(target){ + ai2: function (target) { return -1; }, }); - 'step 3' - if(result.bool){ - var res=result.cards,target=result.targets[0].playerid; - player.addGaintag(res,'qiaoli_given'); + "step 3"; + if (result.bool) { + var res = result.cards, + target = result.targets[0].playerid; + player.addGaintag(res, "qiaoli_given"); cards.removeArray(res); - if(!event.given_map[target]) event.given_map[target]=[]; + if (!event.given_map[target]) event.given_map[target] = []; event.given_map[target].addArray(res); - if(cards.length) event.goto(2); + if (cards.length) event.goto(2); } - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown}); + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + }); game.stopCountChoose(); } - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - source.gain(event.given_map[i],player,'giveAuto'); + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + source.gain(event.given_map[i], player, "giveAuto"); } - event.next.sort(function(a,b){ - return lib.sort.seat(a.player,b.player); + event.next.sort(function (a, b) { + return lib.sort.seat(a.player, b.player); }); }, }, - gain:{ - charlotte:true, - audio:'qiaoli', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - content:function(){ - var card=get.cardPile2(function(card){ - return get.type(card)=='equip'; + gain: { + charlotte: true, + audio: "qiaoli", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + content: function () { + var card = get.cardPile2(function (card) { + return get.type(card) == "equip"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, }, }, }, - qingliang:{ - audio:2, - trigger:{target:'useCardToTarget'}, - filter:function(event,player){ - if(event.targets.length!=1) return false; - var bool1=(event.card.name=='sha'); - var bool2=(get.type2(event.card)=='trick'&&get.tag(event.card,'damage')); - if(!bool1&&!bool2) return false; - return player!=event.player&&player.countCards('h')>0; + qingliang: { + audio: 2, + trigger: { target: "useCardToTarget" }, + filter: function (event, player) { + if (event.targets.length != 1) return false; + var bool1 = event.card.name == "sha"; + var bool2 = get.type2(event.card) == "trick" && get.tag(event.card, "damage"); + if (!bool1 && !bool2) return false; + return player != event.player && player.countCards("h") > 0; }, - usable:1, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)>0||event.player.hasSkillTag('nogain')) return true; - var eff=get.effect(player,event.card,event.player,player); - if(eff>=0) return false; - var suits=[],banned=[],hs=player.getCards('h'); - for(var i of hs){ - var suit=get.suit(i,player); + usable: 1, + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) > 0 || event.player.hasSkillTag("nogain")) + return true; + var eff = get.effect(player, event.card, event.player, player); + if (eff >= 0) return false; + var suits = [], + banned = [], + hs = player.getCards("h"); + for (var i of hs) { + var suit = get.suit(i, player); suits.add(suit); - if(!lib.filter.cardDiscardable(i,player,'qingliang')) banned.add(suit); + if (!lib.filter.cardDiscardable(i, player, "qingliang")) banned.add(suit); } suits.removeArray(banned); - for(var i of suits){ - var cards=player.getCards('h',function(card){ - return get.suit(card,player)==i; + for (var i of suits) { + var cards = player.getCards("h", function (card) { + return get.suit(card, player) == i; }); - if((-eff/2-get.value(cards,player))>0) return true; + if (-eff / 2 - get.value(cards, player) > 0) return true; } return false; }, - content:function(){ - 'step 0' - player.showHandcards(get.translation(player)+'发动了【清靓】'); - 'step 1' - var suits=[],banned=[],hs=player.getCards('h'); - for(var i of hs){ - var suit=get.suit(i,player); + content: function () { + "step 0"; + player.showHandcards(get.translation(player) + "发动了【清靓】"); + "step 1"; + var suits = [], + banned = [], + hs = player.getCards("h"); + for (var i of hs) { + var suit = get.suit(i, player); suits.add(suit); - if(!lib.filter.cardDiscardable(i,player,'qingliang')) banned.add(suit); + if (!lib.filter.cardDiscardable(i, player, "qingliang")) banned.add(suit); } - if(suits.length>banned.length){ - player.chooseControl().set('choiceList',[ - '和'+get.translation(trigger.player)+'各摸一张牌', - '弃置一种花色的所有手牌,令'+get.translation(trigger.card)+'对自己无效', - ]).set('ai',function(){ - var player=_status.event.player,event=_status.event.getTrigger(); - if(get.attitude(player,event.player)>0||event.player.hasSkillTag('nogain')) return 0; - return 1; - }); - event.suits=suits; + if (suits.length > banned.length) { + player + .chooseControl() + .set("choiceList", [ + "和" + get.translation(trigger.player) + "各摸一张牌", + "弃置一种花色的所有手牌,令" + get.translation(trigger.card) + "对自己无效", + ]) + .set("ai", function () { + var player = _status.event.player, + event = _status.event.getTrigger(); + if ( + get.attitude(player, event.player) > 0 || + event.player.hasSkillTag("nogain") + ) + return 0; + return 1; + }); + event.suits = suits; suits.removeArray(banned); suits.sort(); + } else { + event._result = { index: 0 }; } - else{ - event._result={index:0}; - } - 'step 2' - if(result.index==0){ - var list=[player,trigger.player].sortBySeat(); - list[0].draw('nodelay'); + "step 2"; + if (result.index == 0) { + var list = [player, trigger.player].sortBySeat(); + list[0].draw("nodelay"); list[1].draw(); event.finish(); - } - else{ - if(event.suits.length==1) event._result={control:event.suits[0]}; - else player.chooseControl(event.suits).set('prompt','选择弃置一种花色的所有牌').set('ai',function(){ - var player=_status.event.player,list=_status.event.controls.slice(0); - var gett=function(suit){ - var cards=player.getCards('h',function(card){ - return get.suit(card,player)==suit; + } else { + if (event.suits.length == 1) event._result = { control: event.suits[0] }; + else + player + .chooseControl(event.suits) + .set("prompt", "选择弃置一种花色的所有牌") + .set("ai", function () { + var player = _status.event.player, + list = _status.event.controls.slice(0); + var gett = function (suit) { + var cards = player.getCards("h", function (card) { + return get.suit(card, player) == suit; + }); + return get.value(cards); + }; + return list.sort(function (b, a) { + return gett(b) - gett(a); + })[0]; }); - return get.value(cards); - } - return list.sort(function(b,a){ - return gett(b)-gett(a); - })[0]; - }); } - 'step 3' - var cards=player.getCards('h',function(card){ - return get.suit(card)==result.control; + "step 3"; + var cards = player.getCards("h", function (card) { + return get.suit(card) == result.control; }); - if(cards.length) player.discard(cards); + if (cards.length) player.discard(cards); trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); }, }, //卫兹 - yuanzi:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - logTarget:'player', - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&player.countCards('h')>0&&!player.hasSkill('yuanzi_round',null,null,false); + yuanzi: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + logTarget: "player", + filter: function (event, player) { + return ( + player != event.player && + event.player.isIn() && + player.countCards("h") > 0 && + !player.hasSkill("yuanzi_round", null, null, false) + ); }, - check:function(event,player){ - if(event.player.hasJudge('lebu')||get.attitude(player,event.player)<2) return false; - return game.hasPlayer(function(current){ - return current!==player&¤t!==event.player&&event.player.inRange(current)&&get.attitude(event.player,current)<0; + check: function (event, player) { + if (event.player.hasJudge("lebu") || get.attitude(player, event.player) < 2) return false; + return game.hasPlayer(function (current) { + return ( + current !== player && + current !== event.player && + event.player.inRange(current) && + get.attitude(event.player, current) < 0 + ); }); }, - content:function(){ - var cards=player.getCards('h'); - player.give(cards,trigger.player); - player.addTempSkill('yuanzi_effect'); - player.addTempSkill('yuanzi_round','roundStart'); + content: function () { + var cards = player.getCards("h"); + player.give(cards, trigger.player); + player.addTempSkill("yuanzi_effect"); + player.addTempSkill("yuanzi_round", "roundStart"); }, - subSkill:{ - effect:{ - charlotte:true, - audio:'yuanzi', - trigger:{global:'damageSource'}, - forced:true, - filter:function(event,player){ - var source=event.source; - return source&&source==_status.currentPhase&&player.countCards('h')<=source.countCards('h'); + subSkill: { + effect: { + charlotte: true, + audio: "yuanzi", + trigger: { global: "damageSource" }, + forced: true, + filter: function (event, player) { + var source = event.source; + return ( + source && + source == _status.currentPhase && + player.countCards("h") <= source.countCards("h") + ); }, - content:function(){ + content: function () { player.draw(2); }, }, - round:{charlotte:true}, + round: { charlotte: true }, }, }, - liejie:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + liejie: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var source=trigger.source; - var prompt2='弃置至多三张牌并摸等量的牌'; - if(source) prompt2+=(',若弃置的牌中有红色牌,则弃置'+get.translation(source)+'至多等量的牌'); - var next=player.chooseToDiscard('he',[1,3],get.prompt('liejie'),prompt2); - next.set('ai',function(card){ - return 6-get.value(card); - }) - if(source) next.logSkill=['liejie',source]; - else next.logSkill='liejie'; - 'step 1' - if(result.bool){ - var cards=result.cards; + content: function () { + "step 0"; + var source = trigger.source; + var prompt2 = "弃置至多三张牌并摸等量的牌"; + if (source) + prompt2 += + ",若弃置的牌中有红色牌,则弃置" + get.translation(source) + "至多等量的牌"; + var next = player.chooseToDiscard("he", [1, 3], get.prompt("liejie"), prompt2); + next.set("ai", function (card) { + return 6 - get.value(card); + }); + if (source) next.logSkill = ["liejie", source]; + else next.logSkill = "liejie"; + "step 1"; + if (result.bool) { + var cards = result.cards; player.draw(cards.length); - if(trigger.source){ - var num=cards.filter(function(i){ - return get.color(i,player)=='red'; + if (trigger.source) { + var num = cards.filter(function (i) { + return get.color(i, player) == "red"; }).length; - if(num>0) player.discardPlayerCard(trigger.source,'he',[1,num]).set('forceAuto',true); + if (num > 0) + player + .discardPlayerCard(trigger.source, "he", [1, num]) + .set("forceAuto", true); } } }, }, //滕芳兰 - luochong:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','damageEnd']}, - direct:true, - filter:function(event,player){ - if(event.name=='damage'){ - var history=player.getHistory('damage'); - if(history.indexOf(event)!=0) return false; + luochong: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "damageEnd"] }, + direct: true, + filter: function (event, player) { + if (event.name == "damage") { + var history = player.getHistory("damage"); + if (history.indexOf(event) != 0) return false; } - var storage1=player.storage.luochong_round,storage2=player.getStorage('luochong'); - if(!storage1) storage1=[[],[]]; - for(var i=0;i<4;i++){ - if(!storage1[0].includes(i)&&!storage2.includes(i)&&game.hasPlayer(function(current){ - return !storage1[1].includes(current)&&lib.skill.luochong.filterx[i](current); - })) return true; + var storage1 = player.storage.luochong_round, + storage2 = player.getStorage("luochong"); + if (!storage1) storage1 = [[], []]; + for (var i = 0; i < 4; i++) { + if ( + !storage1[0].includes(i) && + !storage2.includes(i) && + game.hasPlayer(function (current) { + return ( + !storage1[1].includes(current) && lib.skill.luochong.filterx[i](current) + ); + }) + ) + return true; } return false; }, - filterx:[ - (target)=>target.isDamaged(), - ()=>true, - (target)=>target.countCards('he')>0, - ()=>true, + filterx: [ + (target) => target.isDamaged(), + () => true, + (target) => target.countCards("he") > 0, + () => true, ], - onremove:true, - content:function(){ - 'step 0' - var list=[]; - var choiceList=[ - '令一名角色回复1点体力。', - '令一名角色失去1点体力。', - '令一名角色弃置两张牌。', - '令一名角色摸两张牌。', + onremove: true, + content: function () { + "step 0"; + var list = []; + var choiceList = [ + "令一名角色回复1点体力。", + "令一名角色失去1点体力。", + "令一名角色弃置两张牌。", + "令一名角色摸两张牌。", ]; - var storage1=player.storage.luochong_round,storage2=player.getStorage('luochong'); - if(!storage1) storage1=[[],[]]; - for(var i=0;i<4;i++){ - if(storage2.includes(i)){ - choiceList[i]=(''+choiceList[i]+''); - } - else if(storage1[0].includes(i)||!game.hasPlayer(function(current){ - return !storage1[1].includes(current)&&lib.skill.luochong.filterx[i](current); - })){ - choiceList[i]=(''+choiceList[i]+''); - } - else list.push('选项'+get.cnNumber(i+1,true)) + var storage1 = player.storage.luochong_round, + storage2 = player.getStorage("luochong"); + if (!storage1) storage1 = [[], []]; + for (var i = 0; i < 4; i++) { + if (storage2.includes(i)) { + choiceList[i] = + '' + + choiceList[i] + + ""; + } else if ( + storage1[0].includes(i) || + !game.hasPlayer(function (current) { + return ( + !storage1[1].includes(current) && lib.skill.luochong.filterx[i](current) + ); + }) + ) { + choiceList[i] = '' + choiceList[i] + ""; + } else list.push("选项" + get.cnNumber(i + 1, true)); } - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('luochong')).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player; - var list=_status.event.controls.slice(0); - var listx=(player.storage.luochong_round||[[],[]])[1]; - var gett=function(choice){ - if(choice=='cancel2') return 0.1; - var max=0,func={ - 选项一:function(current){ - if(current.isDamaged()) max=Math.max(max,get.recoverEffect(current,player,player)); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("luochong")) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player; + var list = _status.event.controls.slice(0); + var listx = (player.storage.luochong_round || [[], []])[1]; + var gett = function (choice) { + if (choice == "cancel2") return 0.1; + var max = 0, + func = { + 选项一: function (current) { + if (current.isDamaged()) + max = Math.max( + max, + get.recoverEffect(current, player, player) + ); + }, + 选项二: function (target) { + max = Math.max( + max, + get.effect(target, { name: "losehp" }, player, player) + ); + }, + 选项三: function (target) { + var num = target.countDiscardableCards(player, "he"); + if (num > 0) + max = Math.max( + max, + Math.sqrt(Math.min(2, num)) * + get.effect( + target, + { name: "guohe_copy2" }, + player, + player + ) + ); + }, + 选项四: function (target) { + max = Math.max( + max, + 2 * get.effect(target, { name: "draw" }, player, player) + ); + }, + }[choice]; + game.countPlayer(function (current) { + if (!listx.includes(current)) func(current); + }); + return max; + }; + return list.sort(function (a, b) { + return gett(b) - gett(a); + })[0]; + }); + "step 1"; + if (result.control != "cancel2") { + var index = ["选项一", "选项二", "选项三", "选项四"].indexOf(result.control); + event.index = index; + var listx = (player.storage.luochong_round || [[], []])[1]; + var list = [ + [ + "选择一名角色,令其回复1点体力", + function (target) { + var player = _status.event.player; + return get.recoverEffect(target, player, player); }, - 选项二:function(target){ - max=Math.max(max,get.effect(target,{name:'losehp'},player,player)); + ], + [ + "选择一名角色,令其失去1点体力", + function (target) { + return get.effect(target, { name: "losehp" }, player, player); }, - 选项三:function(target){ - var num=target.countDiscardableCards(player,'he'); - if(num>0) max=Math.max(max,Math.sqrt(Math.min(2,num))*get.effect(target,{name:'guohe_copy2'},player,player)); + ], + [ + "选择一名角色,令其弃置两张牌", + function (target) { + var player = _status.event.player; + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) * + Math.sqrt(Math.min(2, target.countCards("he"))) + ); }, - 选项四:function(target){ - max=Math.max(max,2*get.effect(target,{name:'draw'},player,player)); + ], + [ + "选择一名角色,令其摸两张牌", + function (target) { + var player = _status.event.player; + return 2 * get.effect(target, { name: "draw" }, player, player); }, - }[choice]; - game.countPlayer(function(current){ - if(!listx.includes(current)) func(current); - }); - return max; - }; - return list.sort(function(a,b){ - return gett(b)-gett(a); - })[0]; - }); - 'step 1' - if(result.control!='cancel2'){ - var index=['选项一','选项二','选项三','选项四'].indexOf(result.control); - event.index=index; - var listx=(player.storage.luochong_round||[[],[]])[1]; - var list=[ - ['选择一名角色,令其回复1点体力',function(target){ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - }], - ['选择一名角色,令其失去1点体力',function(target){ - return get.effect(target,{name:'losehp'},player,player); - }], - ['选择一名角色,令其弃置两张牌',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player)*Math.sqrt(Math.min(2,target.countCards('he'))); - }], - ['选择一名角色,令其摸两张牌',function(target){ - var player=_status.event.player; - return 2*get.effect(target,{name:'draw'},player,player); - }] + ], ][index]; - var targets=game.filterPlayer(function(current){ - return !listx.includes(current)&&lib.skill.luochong.filterx[event.index](current); - }) - var next=player.chooseTarget(list[0],true,function(card,player,target){ + var targets = game.filterPlayer(function (current) { + return ( + !listx.includes(current) && lib.skill.luochong.filterx[event.index](current) + ); + }); + var next = player.chooseTarget(list[0], true, function (card, player, target) { return _status.event.targets.includes(target); }); - next.set('targets',targets); - next.set('ai',list[1]); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('luochong',target); - if(player!=target) player.addExpose(0.2); - player.addTempSkill('luochong_round','roundStart'); - if(!player.storage.luochong_round) player.storage.luochong_round=[[],[]]; + next.set("targets", targets); + next.set("ai", list[1]); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("luochong", target); + if (player != target) player.addExpose(0.2); + player.addTempSkill("luochong_round", "roundStart"); + if (!player.storage.luochong_round) player.storage.luochong_round = [[], []]; player.storage.luochong_round[0].push(event.index); player.storage.luochong_round[1].push(target); - switch(event.index){ + switch (event.index) { case 0: target.recover(); break; @@ -10800,7 +14418,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.loseHp(); break; case 2: - target.chooseToDiscard(true,'he',2); + target.chooseToDiscard(true, "he", 2); break; case 3: target.draw(2); @@ -10808,169 +14426,208 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } }, - subSkill:{ - round:{ - charlotte:true, - onremove:true, + subSkill: { + round: { + charlotte: true, + onremove: true, }, }, }, - aichen:{ - audio:2, - trigger:{player:'dying'}, - forced:true, - filter:function(event,player){ - return player.hasSkill('luochong',null,null,false)&&player.getStorage('luochong').length<3; + aichen: { + audio: 2, + trigger: { player: "dying" }, + forced: true, + filter: function (event, player) { + return ( + player.hasSkill("luochong", null, null, false) && + player.getStorage("luochong").length < 3 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; //var num=1-player.hp; //if(num>0) player.recover(num); - var list=[]; - var choiceList=[ - '令一名角色回复1点体力。', - '令一名角色失去1点体力。', - '令一名角色弃置两张牌。', - '令一名角色摸两张牌。', + var list = []; + var choiceList = [ + "令一名角色回复1点体力。", + "令一名角色失去1点体力。", + "令一名角色弃置两张牌。", + "令一名角色摸两张牌。", ]; - var storage2=player.getStorage('luochong'); - for(var i=0;i<4;i++){ - if(storage2.includes(i)){ - choiceList[i]=(''+choiceList[i]+''); - } - else list.push('选项'+get.cnNumber(i+1,true)) + var storage2 = player.getStorage("luochong"); + for (var i = 0; i < 4; i++) { + if (storage2.includes(i)) { + choiceList[i] = + '' + + choiceList[i] + + ""; + } else list.push("选项" + get.cnNumber(i + 1, true)); } - player.chooseControl(list).set('prompt','哀尘:选择移去一个〖落宠〗的选项').set('choiceList',choiceList).set('ai',function(){ - var controls=_status.event.controls.slice(0); - var list=['选项三','选项四','选项二','选项一']; - for(var i of list){ - if(controls.includes(i)) return i; - } - return 0; - }); - 'step 1' - var index=['选项一','选项二','选项三','选项四'].indexOf(result.control); - player.markAuto('luochong',[index]); - game.log(player,'移去了','#g【落宠】','的','#y'+[ - '令一名角色回复1点体力', - '令一名角色失去1点体力', - '令一名角色弃置两张牌', - '令一名角色摸两张牌', - ][index],'的选项'); + player + .chooseControl(list) + .set("prompt", "哀尘:选择移去一个〖落宠〗的选项") + .set("choiceList", choiceList) + .set("ai", function () { + var controls = _status.event.controls.slice(0); + var list = ["选项三", "选项四", "选项二", "选项一"]; + for (var i of list) { + if (controls.includes(i)) return i; + } + return 0; + }); + "step 1"; + var index = ["选项一", "选项二", "选项三", "选项四"].indexOf(result.control); + player.markAuto("luochong", [index]); + game.log( + player, + "移去了", + "#g【落宠】", + "的", + "#y" + + [ + "令一名角色回复1点体力", + "令一名角色失去1点体力", + "令一名角色弃置两张牌", + "令一名角色摸两张牌", + ][index], + "的选项" + ); + }, + ai: { + combo: "luochong", + neg: true }, }, //SP孟获 - spmanwang:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he')>0; + spmanwang: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - selectCard:[1,Infinity], - check:function(card){ - var player=_status.event.player; - var max=Math.min(player.isDamaged()?3:2,4-player.countMark('spmanwang')); - if(!max&&!player.hasSkill('sppanqin')) return 0; - if(max==0&&ui.selected.length>0) return 0; - return 7-ui.selected.cards.length-get.value(card); + filterCard: true, + position: "he", + selectCard: [1, Infinity], + check: function (card) { + var player = _status.event.player; + var max = Math.min(player.isDamaged() ? 3 : 2, 4 - player.countMark("spmanwang")); + if (!max && !player.hasSkill("sppanqin")) return 0; + if (max == 0 && ui.selected.length > 0) return 0; + return 7 - ui.selected.cards.length - get.value(card); }, - content:function(){ - var num=Math.min(cards.length,4-player.countMark('spmanwang')); - if(num>=1) player.addSkills('sppanqin'); - if(num>=2) player.draw(); - if(num>=3) player.recover(); - if(num>=4){ + content: function () { + var num = Math.min(cards.length, 4 - player.countMark("spmanwang")); + if (num >= 1) player.addSkills("sppanqin"); + if (num >= 2) player.draw(); + if (num >= 3) player.recover(); + if (num >= 4) { player.draw(2); - player.removeSkills('sppanqin'); + player.removeSkills("sppanqin"); } }, - intro:{content:'已经移去过#个选项'}, - ai:{ - order:2, - result:{ - player:function(player,target){ - if(player.getUseValue({name:'nanman'})<=0) return 0; - if(player.getStat('skill').spmanwang&&player.hasSkill('sppanqin')) return 0; + intro: { content: "已经移去过#个选项" }, + ai: { + order: 2, + result: { + player: function (player, target) { + if (player.getUseValue({ name: "nanman" }) <= 0) return 0; + if (player.getStat("skill").spmanwang && player.hasSkill("sppanqin")) return 0; return 1; }, }, }, - derivation:'sppanqin', + derivation: "sppanqin", }, - sppanqin:{ - audio:2, - trigger:{player:['phaseUseEnd','phaseDiscardEnd']}, - filter:function(event,player){ - var cards=[],bool=true; - player.getHistory('lose',function(evt){ - if(!bool||evt.type!='discard'||evt.getParent(event.name)!=event) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'){ + sppanqin: { + audio: 2, + trigger: { player: ["phaseUseEnd", "phaseDiscardEnd"] }, + filter: function (event, player) { + var cards = [], + bool = true; + player.getHistory("lose", function (evt) { + if (!bool || evt.type != "discard" || evt.getParent(event.name) != event) + return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d") { cards.add(i); - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) bool=false; + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) + bool = false; } } }); - if(!bool||!cards.length) return false; - return player.hasUseTarget(get.autoViewAs({name:'nanman'},cards)); + if (!bool || !cards.length) return false; + return player.hasUseTarget(get.autoViewAs({ name: "nanman" }, cards)); }, - prompt2:function(event,player){ - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent(event.name)!=event) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'){ + prompt2: function (event, player) { + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent(event.name) != event) return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d") { cards.add(i); } } }); - return '将'+get.translation(cards)+'(共计'+get.cnNumber(cards.length)+'张牌)当做【南蛮入侵】使用' + return ( + "将" + + get.translation(cards) + + "(共计" + + get.cnNumber(cards.length) + + "张牌)当做【南蛮入侵】使用" + ); }, - check:function(event,player){ - var cards=[],bool=true; - player.getHistory('lose',function(evt){ - if(!bool||evt.type!='discard'||evt.getParent(event.name)!=event) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'){ + check: function (event, player) { + var cards = [], + bool = true; + player.getHistory("lose", function (evt) { + if (!bool || evt.type != "discard" || evt.getParent(event.name) != event) + return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d") { cards.add(i); - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) bool=false; + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) + bool = false; } } }); - if(!bool||!cards.length) return false; - return player.hasValueTarget(get.autoViewAs({name:'nanman'},cards)); + if (!bool || !cards.length) return false; + return player.hasValueTarget(get.autoViewAs({ name: "nanman" }, cards)); }, - content:function(){ - 'step 0' - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.type!='discard'||evt.getParent(trigger.name)!=trigger) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'){ + content: function () { + "step 0"; + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.type != "discard" || evt.getParent(trigger.name) != trigger) return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d") { cards.add(i); } } }); - player.chooseUseTarget(true,{name:'nanman'},cards); - player.addTempSkill('sppanqin_eff'); + player.chooseUseTarget(true, { name: "nanman" }, cards); + player.addTempSkill("sppanqin_eff"); }, - subSkill:{ - eff:{ - trigger:{player:'useCard'}, - charlotte:true, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.name=='nanman'&&event.getParent(2).name=='sppanqin'&&player.countMark('spmanwang')<4&&player.hasSkill('spmanwang',null,null,false)&&event.cards.length<=event.targets.length; + subSkill: { + eff: { + trigger: { player: "useCard" }, + charlotte: true, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card.name == "nanman" && + event.getParent(2).name == "sppanqin" && + player.countMark("spmanwang") < 4 && + player.hasSkill("spmanwang", null, null, false) && + event.cards.length <= event.targets.length + ); }, - content:function(){ - player.addMark('spmanwang',1,false); - switch(player.countMark('spmanwang')){ + content: function () { + player.addMark("spmanwang", 1, false); + switch (player.countMark("spmanwang")) { case 1: player.draw(2); - player.removeSkills('sppanqin'); + player.removeSkills("sppanqin"); break; case 2: player.recover(); @@ -10979,961 +14636,1218 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.draw(); break; case 4: - player.addSkills('sppanqin'); + player.addSkills("sppanqin"); break; } }, - } - } + }, + }, }, //清河公主 - zengou:{ - audio:2, - trigger:{global:'useCard'}, - filter:function(event,player){ - return event.card.name=='shan'&&player.inRange(event.player)&&(player.hp>0||player.hasCard(function(card){ - return get.type(card)!='basic'&&lib.filter.cardDiscardable(card,player,'zengou'); - },'eh')) + zengou: { + audio: 2, + trigger: { global: "useCard" }, + filter: function (event, player) { + return ( + event.card.name == "shan" && + player.inRange(event.player) && + (player.hp > 0 || + player.hasCard(function (card) { + return ( + get.type(card) != "basic" && + lib.filter.cardDiscardable(card, player, "zengou") + ); + }, "eh")) + ); }, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(get.damageEffect(event.player,event.getParent(3).player,player,get.nature(event.card))<=0) return false; - if(player.hasCard(function(card){ - return get.type(card)!='basic'&&get.value(card)<7&&lib.filter.cardDiscardable(card,player,'zengou'); - },'eh')) return true; - return player.hp>Math.max(1,event.player.hp); + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + if ( + get.damageEffect( + event.player, + event.getParent(3).player, + player, + get.nature(event.card) + ) <= 0 + ) + return false; + if ( + player.hasCard(function (card) { + return ( + get.type(card) != "basic" && + get.value(card) < 7 && + lib.filter.cardDiscardable(card, player, "zengou") + ); + }, "eh") + ) + return true; + return player.hp > Math.max(1, event.player.hp); }, - content:function(){ - 'step 0' - trigger.all_excluded=true; - var str='弃置一张非基本牌'; - if(player.hp>0) str+=',或点「取消」失去1点体力'; - var next=player.chooseToDiscard(str,function(card){ - return get.type(card)!='basic'; - },'he').set('ai',function(card){ - return 7-get.value(card); - }); - if(player.hp<=0) next.set('forced',true); - 'step 1' - if(!result.bool) player.loseHp(); - 'step 2' - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2'); + content: function () { + "step 0"; + trigger.all_excluded = true; + var str = "弃置一张非基本牌"; + if (player.hp > 0) str += ",或点「取消」失去1点体力"; + var next = player + .chooseToDiscard( + str, + function (card) { + return get.type(card) != "basic"; + }, + "he" + ) + .set("ai", function (card) { + return 7 - get.value(card); + }); + if (player.hp <= 0) next.set("forced", true); + "step 1"; + if (!result.bool) player.loseHp(); + "step 2"; + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2"); }, }, - qhzhangji:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - if(!event.player.isIn()) return false; - if(player.getHistory('sourceDamage').length>0) return true; - if(player.getHistory('damage').length>0) return event.player.countCards('he')>0; + qhzhangji: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + if (!event.player.isIn()) return false; + if (player.getHistory("sourceDamage").length > 0) return true; + if (player.getHistory("damage").length > 0) return event.player.countCards("he") > 0; return false; }, - content:function(){ - 'step 0' - event.target=trigger.player; - if(player.getHistory('sourceDamage').length) player.chooseBool(get.prompt('qhzhangji',event.target),'令'+get.translation(event.target)+'摸两张牌').set('choice',get.attitude(player,event.target)>0).set('ai',()=>_status.event.choice); + content: function () { + "step 0"; + event.target = trigger.player; + if (player.getHistory("sourceDamage").length) + player + .chooseBool( + get.prompt("qhzhangji", event.target), + "令" + get.translation(event.target) + "摸两张牌" + ) + .set("choice", get.attitude(player, event.target) > 0) + .set("ai", () => _status.event.choice); else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('qhzhangji',target); - event.logged=true; + "step 1"; + if (result.bool) { + player.logSkill("qhzhangji", target); + event.logged = true; target.draw(2); } - 'step 2' - if(target.isIn()&&target.countCards('he')>0&&player.getHistory('damage').length>0) player.chooseBool(get.prompt('qhzhangji',event.target),'令'+get.translation(event.target)+'弃置两张牌').set('choice',get.attitude(player,event.target)<0).set('ai',()=>_status.event.choice); + "step 2"; + if ( + target.isIn() && + target.countCards("he") > 0 && + player.getHistory("damage").length > 0 + ) + player + .chooseBool( + get.prompt("qhzhangji", event.target), + "令" + get.translation(event.target) + "弃置两张牌" + ) + .set("choice", get.attitude(player, event.target) < 0) + .set("ai", () => _status.event.choice); else event.finish(); - 'step 3' - if(result.bool){ - if(!event.logged) player.logSkill('qhzhangji',target); - target.chooseToDiscard('he',true,2); + "step 3"; + if (result.bool) { + if (!event.logged) player.logSkill("qhzhangji", target); + target.chooseToDiscard("he", true, 2); } }, }, //十周年夏侯霸 - rebaobian:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - for(var i of lib.skill.rebaobian.derivation){ - if(!player.hasSkill(i,null,null,false)) return true; + rebaobian: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + for (var i of lib.skill.rebaobian.derivation) { + if (!player.hasSkill(i, null, null, false)) return true; } return false; }, - forced:true, - content:function(){ - for(var i of lib.skill.rebaobian.derivation){ - if(!player.hasSkill(i,null,null,false)){ + forced: true, + content: function () { + for (var i of lib.skill.rebaobian.derivation) { + if (!player.hasSkill(i, null, null, false)) { player.addSkills(i); break; } } }, - ai:{ - maixie:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&!target.hasSkill('oltiaoxin',null,null,false)){ - if(!target.hasFriend()) return; - if(target.hp>=4) return [0,1]; + ai: { + maixie: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage") && !target.hasSkill("oltiaoxin", null, null, false)) { + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0, 1]; } - } - } + }, + }, }, - derivation:['tiaoxin','new_repaoxiao','xinshensu'], + derivation: ["tiaoxin", "new_repaoxiao", "xinshensu"], }, //范强张达 - yuanchou:{ - audio:2, - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + yuanchou: { + audio: 2, + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter:function(event){ - return event.card.name=='sha'&&get.color(event.card)=='black'; + filter: function (event) { + return event.card.name == "sha" && get.color(event.card) == "black"; }, - forced:true, - logTarget:'target', - content:function(){ - trigger.target.addTempSkill('qinggang2'); + forced: true, + logTarget: "target", + content: function () { + trigger.target.addTempSkill("qinggang2"); trigger.target.storage.qinggang2.add(trigger.card); }, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.name=='sha'&&get.color(arg.card)=='black') return true; + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.name == "sha" && get.color(arg.card) == "black") return true; return false; - } + }, }, - global:'yuanchou_ai', - subSkill:{ - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.name=='sha'&&get.color(arg.card)=='black'&&arg.target&&arg.target.hasSkill('yuanchou')) return true; + global: "yuanchou_ai", + subSkill: { + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + arg && + arg.name == "sha" && + get.color(arg.card) == "black" && + arg.target && + arg.target.hasSkill("yuanchou") + ) + return true; return false; - } + }, }, }, }, - juesheng:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - viewAs:{name:'juedou',isCard:true}, - filterCard:()=>false, - selectCard:-1, - precontent:function(){ - player.awakenSkill('juesheng'); - player.addTempSkill('juesheng_counter'); + juesheng: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + viewAs: { name: "juedou", isCard: true }, + filterCard: () => false, + selectCard: -1, + precontent: function () { + player.awakenSkill("juesheng"); + player.addTempSkill("juesheng_counter"); }, - ai:{ - result:{ - player:function(player,target){ - return target.getAllHistory('useCard',(evt)=>evt.card.name=='sha').length*lib.card.juedou.ai.result.player.apply(this,arguments); + ai: { + result: { + player: function (player, target) { + return ( + target.getAllHistory("useCard", (evt) => evt.card.name == "sha").length * + lib.card.juedou.ai.result.player.apply(this, arguments) + ); }, - target:function(player,target){ - var num=target.getAllHistory('useCard',(evt)=>evt.card.name=='sha').length; - if(num evt.card.name == "sha").length; + if (num < target.hp) return 0; + return num * lib.card.juedou.ai.result.target; }, }, }, - subSkill:{ - counter:{ - trigger:{global:'damageBegin1'}, - forced:true, - charlotte:true, - filter:function(event,player){ - var evt=event.getParent(); - return evt.skill=='juesheng'&&evt.player==player; + subSkill: { + counter: { + trigger: { global: "damageBegin1" }, + forced: true, + charlotte: true, + filter: function (event, player) { + var evt = event.getParent(); + return evt.skill == "juesheng" && evt.player == player; }, - content:function(){ - var target=trigger.getParent().target; - trigger.num=Math.max(1,target.getAllHistory('useCard',(evt)=>evt.card.name=='sha').length); - target.addTempSkills('juesheng',{player:'phaseAfter'}); + content: function () { + var target = trigger.getParent().target; + trigger.num = Math.max( + 1, + target.getAllHistory("useCard", (evt) => evt.card.name == "sha").length + ); + target.addTempSkills("juesheng", { player: "phaseAfter" }); }, }, }, }, //田之间 - saodi:{ - audio:2, - trigger:{ - player:'useCardToPlayer', + saodi: { + audio: 2, + trigger: { + player: "useCardToPlayer", }, - direct:true, - filter:function(event,player){ - if(event.targets.length!=1||event.target==player||event.target.hasSkill('nodis')) return false; - if(event.card.name!='sha'&&get.type(event.card)!='trick') return false; - var target=event.target; - var left=[],right=[],left2=player,right2=player; - while(left2!=target&&right2!=target){ - left2=left2.getPrevious(); - right2=right2.getNext(); - if(left2!=target) left.push(left2); - if(right2!=target) right.push(right2); + direct: true, + filter: function (event, player) { + if (event.targets.length != 1 || event.target == player || event.target.hasSkill("nodis")) + return false; + if (event.card.name != "sha" && get.type(event.card) != "trick") return false; + var target = event.target; + var left = [], + right = [], + left2 = player, + right2 = player; + while (left2 != target && right2 != target) { + left2 = left2.getPrevious(); + right2 = right2.getNext(); + if (left2 != target) left.push(left2); + if (right2 != target) right.push(right2); } - if(target==left2){ - for(var i of left){ - if(lib.filter.targetEnabled2(event.card,player,i)) return true; + if (target == left2) { + for (var i of left) { + if (lib.filter.targetEnabled2(event.card, player, i)) return true; } } - if(target==right2){ - for(var i of right){ - if(lib.filter.targetEnabled2(event.card,player,i)) return true; + if (target == right2) { + for (var i of right) { + if (lib.filter.targetEnabled2(event.card, player, i)) return true; } } return false; }, - aiJudge:function(card,player,target,bool){ - var left=[],right=[],left2=player,right2=player,left3=false,right3=false; - var eff_left=0,eff_right=0; - while(left2!=target&&right2!=target){ - left2=left2.getPrevious(); - right2=right2.getNext(); - if(left2!=target) left.push(left2); - if(right2!=target) right.push(right2); + aiJudge: function (card, player, target, bool) { + var left = [], + right = [], + left2 = player, + right2 = player, + left3 = false, + right3 = false; + var eff_left = 0, + eff_right = 0; + while (left2 != target && right2 != target) { + left2 = left2.getPrevious(); + right2 = right2.getNext(); + if (left2 != target) left.push(left2); + if (right2 != target) right.push(right2); } - if(target==left2){ - for(var i of left){ - if(lib.filter.targetEnabled2(card,player,i)){ - left3=true; - eff_left+=get.effect(i,card,player,player); + if (target == left2) { + for (var i of left) { + if (lib.filter.targetEnabled2(card, player, i)) { + left3 = true; + eff_left += get.effect(i, card, player, player); } } } - if(target==right2){ - for(var i of right){ - if(lib.filter.targetEnabled2(card,player,i)){ - right3=true; - eff_right+=get.effect(i,card,player,player); + if (target == right2) { + for (var i of right) { + if (lib.filter.targetEnabled2(card, player, i)) { + right3 = true; + eff_right += get.effect(i, card, player, player); } } } - if(left3&&right3){ - if(!bool) return Math.max(eff_left,eff_right); - if(eff_left>Math.max(0,eff_right)) return '↖顺时针'; - if(eff_right>Math.max(0,eff_left)) return '逆时针↗'; - return 'cancel2'; - } - else if(left3){ - if(bool) return eff_left>0?'↖顺时针':'cancel2'; + if (left3 && right3) { + if (!bool) return Math.max(eff_left, eff_right); + if (eff_left > Math.max(0, eff_right)) return "↖顺时针"; + if (eff_right > Math.max(0, eff_left)) return "逆时针↗"; + return "cancel2"; + } else if (left3) { + if (bool) return eff_left > 0 ? "↖顺时针" : "cancel2"; return eff_left; - } - else if(right3){ - if(bool) return eff_right>0?'逆时针↗':'cancel2'; + } else if (right3) { + if (bool) return eff_right > 0 ? "逆时针↗" : "cancel2"; return eff_right; - } - else return bool?'cancel2':0; + } else return bool ? "cancel2" : 0; }, - content:function(){ - 'step 0' - var choices=[]; - var target=trigger.target; - var left=[],right=[],left2=player,right2=player; - while(left2!=target&&right2!=target){ - left2=left2.getPrevious(); - right2=right2.getNext(); - if(left2!=target) left.push(left2); - if(right2!=target) right.push(right2); + content: function () { + "step 0"; + var choices = []; + var target = trigger.target; + var left = [], + right = [], + left2 = player, + right2 = player; + while (left2 != target && right2 != target) { + left2 = left2.getPrevious(); + right2 = right2.getNext(); + if (left2 != target) left.push(left2); + if (right2 != target) right.push(right2); } - if(target==left2){ - for(var i of left){ - if(lib.filter.targetEnabled2(trigger.card,player,i)){ - choices.push('↖顺时针'); + if (target == left2) { + for (var i of left) { + if (lib.filter.targetEnabled2(trigger.card, player, i)) { + choices.push("↖顺时针"); break; } } } - if(target==right2){ - for(var i of right){ - if(lib.filter.targetEnabled2(trigger.card,player,i)){ - choices.push('逆时针↗'); + if (target == right2) { + for (var i of right) { + if (lib.filter.targetEnabled2(trigger.card, player, i)) { + choices.push("逆时针↗"); break; } } } - choices.push('cancel2'); - player.chooseControl(choices).set('prompt',get.prompt('saodi')).set('prompt2','令自己和'+get.translation(trigger.target)+'某个方向之间的所有角色均成为'+get.translation(trigger.card)+'的目标').set('choices',choices).set('ai',function(){ - var evt=_status.event.getTrigger(); - return lib.skill.saodi.aiJudge(evt.card,evt.player,evt.target,true); - }); - 'step 1' - if(result.control!='cancel2'){ - var targets=[]; - if(result.control=='↖顺时针'){ - var current=player.getPrevious(); - while(current!=trigger.target){ - if(lib.filter.targetEnabled2(trigger.card,player,current)) targets.push(current); - current=current.getPrevious(); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", get.prompt("saodi")) + .set( + "prompt2", + "令自己和" + + get.translation(trigger.target) + + "某个方向之间的所有角色均成为" + + get.translation(trigger.card) + + "的目标" + ) + .set("choices", choices) + .set("ai", function () { + var evt = _status.event.getTrigger(); + return lib.skill.saodi.aiJudge(evt.card, evt.player, evt.target, true); + }); + "step 1"; + if (result.control != "cancel2") { + var targets = []; + if (result.control == "↖顺时针") { + var current = player.getPrevious(); + while (current != trigger.target) { + if (lib.filter.targetEnabled2(trigger.card, player, current)) + targets.push(current); + current = current.getPrevious(); + } + } else { + var current = player.getNext(); + while (current != trigger.target) { + if (lib.filter.targetEnabled2(trigger.card, player, current)) + targets.push(current); + current = current.getNext(); } } - else{ - var current=player.getNext(); - while(current!=trigger.target){ - if(lib.filter.targetEnabled2(trigger.card,player,current)) targets.push(current); - current=current.getNext(); - } - } - event.targets=targets; - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - player.logSkill('saodi',targets); + event.targets = targets; + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + player.logSkill("saodi", targets); trigger.targets.addArray(targets); }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(!target||player._saodi_judging||ui.selected.targets.length||player==target||target.hasSkill('nodis')) return; - if(typeof card!='object'||card.name!='sha'&&get.type(card)!='trick') return false; - player._saodi_judging=true; - var effect=lib.skill.saodi.aiJudge(card,player,target); + ai: { + effect: { + player_use: function (card, player, target) { + if ( + !target || + player._saodi_judging || + ui.selected.targets.length || + player == target || + target.hasSkill("nodis") + ) + return; + if (typeof card != "object" || (card.name != "sha" && get.type(card) != "trick")) + return false; + player._saodi_judging = true; + var effect = lib.skill.saodi.aiJudge(card, player, target); delete player._saodi_judging; - if(effect>0) return [1,effect/Math.max(0.01,get.attitude(player,player))]; + if (effect > 0) return [1, effect / Math.max(0.01, get.attitude(player, player))]; }, }, }, }, - zhuitao:{ - audio:2, - direct:true, - locked:false, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - var storage=player.getStorage('zhuitao'); - return game.hasPlayer(function(current){ - return current!=player&&!storage.includes(current); + zhuitao: { + audio: 2, + direct: true, + locked: false, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + var storage = player.getStorage("zhuitao"); + return game.hasPlayer(function (current) { + return current != player && !storage.includes(current); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhuitao'),'令自己至一名其他角色的距离-1',function(card,player,target){ - return target!=player&&!player.getStorage('zhuitao').includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<0&&get.distance(player,target)==2) return 100; - return get.distance(player,target)*(1-get.sgn(att)/3); - }); - 'step 1' - if(result.bool){ - player.logSkill('zhuitao',result.targets[0]); - player.markAuto('zhuitao',result.targets); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhuitao"), + "令自己至一名其他角色的距离-1", + function (card, player, target) { + return target != player && !player.getStorage("zhuitao").includes(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att < 0 && get.distance(player, target) == 2) return 100; + return get.distance(player, target) * (1 - get.sgn(att) / 3); + }); + "step 1"; + if (result.bool) { + player.logSkill("zhuitao", result.targets[0]); + player.markAuto("zhuitao", result.targets); game.delayx(); } }, - intro:{ - content:'至$的距离-1', - onunmark:true, + intro: { + content: "至$的距离-1", + onunmark: true, }, - onremove:true, - mod:{ - globalFrom:function(player,target,distance){ - if(player.getStorage('zhuitao').includes(target)) return distance-1; + onremove: true, + mod: { + globalFrom: function (player, target, distance) { + if (player.getStorage("zhuitao").includes(target)) return distance - 1; }, }, - group:'zhuitao_remove', - subSkill:{ - remove:{ - audio:'zhuitao', - trigger:{ - source:'damageSource', + group: "zhuitao_remove", + subSkill: { + remove: { + audio: "zhuitao", + trigger: { + source: "damageSource", }, - forced:true, - filter:function(event,player){ - return player.getStorage('zhuitao').includes(event.player); + forced: true, + filter: function (event, player) { + return player.getStorage("zhuitao").includes(event.player); }, - logTarget:'player', - content:function(){ - player.unmarkAuto('zhuitao',[trigger.player]); + logTarget: "player", + content: function () { + player.unmarkAuto("zhuitao", [trigger.player]); }, }, }, }, //生鱼片 - olfengji:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - locked:false, - filter:function(event,player){ + olfengji: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + locked: false, + filter: function (event, player) { return !player.numFixed; }, - content:function(){ - 'step 0' - player.chooseTarget('丰积:请选择增加摸牌的目标','令自己本回合的额定摸牌数-1,且目标下回合的额定摸牌数+2。或者点击「取消」,令自己的额定摸牌数+1',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(target.hasJudge('lebu')||target.hasJudge('bingliang')) return 0; - var att=get.attitude(player,target),dist=get.distance(player,target,'absolute'); - if(_status.event.goon){ - return att/dist; - } - if(game.countPlayer(function(current){ - return current!=player&¤t!=target&&get.attitude(player,current)<0&&get.distance(player,current,'absolute')=target.hp) return 0; - return att/dist; - }).set('goon',player.skipList.includes('lebu')); - 'step 1' - if(!player.storage.olfengji_draw) player.storage.olfengji_draw=0; - if(result.bool){ - var target=result.targets[0]; - player.line(target,'thunder'); + content: function () { + "step 0"; + player + .chooseTarget( + "丰积:请选择增加摸牌的目标", + "令自己本回合的额定摸牌数-1,且目标下回合的额定摸牌数+2。或者点击「取消」,令自己的额定摸牌数+1", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + if (target.hasJudge("lebu") || target.hasJudge("bingliang")) return 0; + var att = get.attitude(player, target), + dist = get.distance(player, target, "absolute"); + if (_status.event.goon) { + return att / dist; + } + if ( + game.countPlayer(function (current) { + return ( + current != player && + current != target && + get.attitude(player, current) < 0 && + get.distance(player, current, "absolute") < dist + ); + }) >= target.hp + ) + return 0; + return att / dist; + }) + .set("goon", player.skipList.includes("lebu")); + "step 1"; + if (!player.storage.olfengji_draw) player.storage.olfengji_draw = 0; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "thunder"); player.storage.olfengji_draw--; - if(!target.storage.olfengji_draw) target.storage.olfengji_draw=0; - target.storage.olfengji_draw+=2; - target.addTempSkill('olfengji_draw',{player:'phaseAfter'}); - target.markSkill('olfengji_draw'); - } - else{ + if (!target.storage.olfengji_draw) target.storage.olfengji_draw = 0; + target.storage.olfengji_draw += 2; + target.addTempSkill("olfengji_draw", { player: "phaseAfter" }); + target.markSkill("olfengji_draw"); + } else { player.storage.olfengji_draw++; } - player.addTempSkill('olfengji_draw'); - player.markSkill('olfengji_draw'); - 'step 2' - player.chooseTarget('丰积:请选择增加使用杀次数的目标','令自己本回合使用杀的次数上限-1,且目标下回合使用杀的次数上限+2。或者点击「取消」,令自己使用杀的次数上限+1',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(target.countMark('olfengji_draw')>0&&target.getCardUsable('sha')<2) return get.attitude(player,target); - return 0; - }); - 'step 3' - if(!player.storage.olfengji_sha) player.storage.olfengji_sha=0; - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); + player.addTempSkill("olfengji_draw"); + player.markSkill("olfengji_draw"); + "step 2"; + player + .chooseTarget( + "丰积:请选择增加使用杀次数的目标", + "令自己本回合使用杀的次数上限-1,且目标下回合使用杀的次数上限+2。或者点击「取消」,令自己使用杀的次数上限+1", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + if (target.countMark("olfengji_draw") > 0 && target.getCardUsable("sha") < 2) + return get.attitude(player, target); + return 0; + }); + "step 3"; + if (!player.storage.olfengji_sha) player.storage.olfengji_sha = 0; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); player.storage.olfengji_sha--; - if(!target.storage.olfengji_sha) target.storage.olfengji_sha=0; - target.storage.olfengji_sha+=2; - target.addTempSkill('olfengji_sha',{player:'phaseAfter'}); - target.markSkill('olfengji_sha'); - } - else{ + if (!target.storage.olfengji_sha) target.storage.olfengji_sha = 0; + target.storage.olfengji_sha += 2; + target.addTempSkill("olfengji_sha", { player: "phaseAfter" }); + target.markSkill("olfengji_sha"); + } else { player.storage.olfengji_sha++; } - player.addTempSkill('olfengji_sha'); - player.markSkill('olfengji_sha'); + player.addTempSkill("olfengji_sha"); + player.markSkill("olfengji_sha"); }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - intro:{ - content:function(storage){ - return '使用【杀】的次数上限'+(storage>=0?'+':'')+storage; + subSkill: { + sha: { + charlotte: true, + onremove: true, + intro: { + content: function (storage) { + return "使用【杀】的次数上限" + (storage >= 0 ? "+" : "") + storage; }, }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.storage.olfengji_sha; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.storage.olfengji_sha; }, }, }, - draw:{ - charlotte:true, - onremove:true, - intro:{ - content:function(storage){ - return '额定摸牌数'+(storage>=0?'+':'')+storage; + draw: { + charlotte: true, + onremove: true, + intro: { + content: function (storage) { + return "额定摸牌数" + (storage >= 0 ? "+" : "") + storage; }, }, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=player.storage.olfengji_draw; + content: function () { + trigger.num += player.storage.olfengji_draw; }, }, }, }, //朱灵 - jixian:{ - audio:2, - trigger:{player:'phaseDrawAfter'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&lib.skill.jixian.getNum(player,current)>0&&player.canUse('sha',current,false); - }) - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('jixian'),'视为对一名满足条件的角色使用一张【杀】',function(card,player,target){ - return target!=player&&lib.skill.jixian.getNum(player,target)>0&&player.canUse('sha',target,false); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player)*Math.sqrt(lib.skill.jixian.getNum(player,target)); + jixian: { + audio: 2, + trigger: { player: "phaseDrawAfter" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current != player && + lib.skill.jixian.getNum(player, current) > 0 && + player.canUse("sha", current, false) + ); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('jixian',target); - var num=lib.skill.jixian.getNum(player,target); - player.useCard({name:'sha',isCard:true},target,false); - if(num>0) player.draw(num); - } - else event.finish(); - 'step 2' - if(!player.hasHistory('sourceDamage',function(evt){ - var card=evt.card; - if(!card||card.name!='sha') return false; - var evtx=evt.getParent('useCard'); - return evtx.card==card&&evtx.getParent()==event; - })) player.loseHp(); }, - getNum:function(player,target){ - var num=0; - if(target.isHealthy()) num++; - if(target.getEquips(2).length) num++; - var countSkill=function(player){ - return player.getSkills(null,false,false).filter(function(skill){ - var info=get.info(skill); - if(!info||info.charlotte) return false; - if(info.zhuSkill) return player.hasZhuSkill(skill); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("jixian"), + "视为对一名满足条件的角色使用一张【杀】", + function (card, player, target) { + return ( + target != player && + lib.skill.jixian.getNum(player, target) > 0 && + player.canUse("sha", target, false) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.effect(target, { name: "sha" }, player, player) * + Math.sqrt(lib.skill.jixian.getNum(player, target)) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("jixian", target); + var num = lib.skill.jixian.getNum(player, target); + player.useCard({ name: "sha", isCard: true }, target, false); + if (num > 0) player.draw(num); + } else event.finish(); + "step 2"; + if ( + !player.hasHistory("sourceDamage", function (evt) { + var card = evt.card; + if (!card || card.name != "sha") return false; + var evtx = evt.getParent("useCard"); + return evtx.card == card && evtx.getParent() == event; + }) + ) + player.loseHp(); + }, + getNum: function (player, target) { + var num = 0; + if (target.isHealthy()) num++; + if (target.getEquips(2).length) num++; + var countSkill = function (player) { + return player.getSkills(null, false, false).filter(function (skill) { + var info = get.info(skill); + if (!info || info.charlotte) return false; + if (info.zhuSkill) return player.hasZhuSkill(skill); return true; }).length; - } - if(countSkill(player)(current==player||current.countCards('h')>=ph)).sortBySeat(); - player.line(targets,'green'); - event.targets=targets; - event.num=0; - 'step 1' - var target=targets[num]; + lanjiang: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + audioname: ["heqi"], + content: function () { + "step 0"; + var ph = player.countCards("h"); + var targets = game + .filterPlayer((current) => current == player || current.countCards("h") >= ph) + .sortBySeat(); + player.line(targets, "green"); + event.targets = targets; + event.num = 0; + "step 1"; + var target = targets[num]; event.num++; - if(target.isIn()){ - event.target=target; - target.chooseBool('是否令'+(player==target?'自己':get.translation(player))+'摸一张牌?').set('ai',()=>get.attitude(_status.event.player,_status.event.getParent().player)>0); + if (target.isIn()) { + event.target = target; + target + .chooseBool( + "是否令" + + (player == target ? "自己" : get.translation(player)) + + "摸一张牌?" + ) + .set( + "ai", + () => get.attitude(_status.event.player, _status.event.getParent().player) > 0 + ); + } else { + event.goto(event.num < targets.length ? 1 : 3); } - else{ - event.goto(event.num0&&targets.some(target=>target.isIn()&&target.countCards('h') 0 && targets.some((target) => target.isIn() && target.countCards("h") < ph)) { + player + .chooseTarget( + "请选择一名手牌数小于自己的目标角色,令其摸一张牌", + function (card, player, target) { + return ( + _status.event.getParent().targets.includes(target) && + target.countCards("h") < player.countCards("h") + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }); } - 'step 6' - if(result.bool){ - var target=result.targets[0]; + "step 6"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - if(player!==target&&(get.mode()!=='identity'||player.identity!=='nei')) player.addExpose(0.1); + if (player !== target && (get.mode() !== "identity" || player.identity !== "nei")) + player.addExpose(0.1); target.draw(); } }, }, //新SP张郃 - spolzhouxuan:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - filter:function(event,player){ - return player.countCards('h')>0&&player.getExpansions('spolzhouxuan').length<5; + spolzhouxuan: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0 && player.getExpansions("spolzhouxuan").length < 5; }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('spolzhouxuan'),[1,5-player.getExpansions('spolzhouxuan').length],'将至多'+get.cnNumber(5-player.getExpansions('spolzhouxuan').length)+'张手牌置于武将牌上').set('ai',function(card){ - if(ui.selected.cards.length>=player.needsToDiscard()) return 6-get.value(card); - return 100-get.useful(card); - }); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.logSkill('spolzhouxuan'); - player.addToExpansion(cards,player,'give').gaintag.add('spolzhouxuan'); + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + "h", + get.prompt("spolzhouxuan"), + [1, 5 - player.getExpansions("spolzhouxuan").length], + "将至多" + + get.cnNumber(5 - player.getExpansions("spolzhouxuan").length) + + "张手牌置于武将牌上" + ) + .set("ai", function (card) { + if (ui.selected.cards.length >= player.needsToDiscard()) + return 6 - get.value(card); + return 100 - get.useful(card); + }); + "step 1"; + if (result.bool) { + var cards = result.cards; + player.logSkill("spolzhouxuan"); + player.addToExpansion(cards, player, "give").gaintag.add("spolzhouxuan"); } }, - marktext:'旋', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "旋", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:['spolzhouxuan_use','spolzhouxuan_discard'], - subSkill:{ - use:{ - audio:'spolzhouxuan', - trigger:{player:'useCard'}, - filter:function(event,player){ - return player.getExpansions('spolzhouxuan').length>0; + group: ["spolzhouxuan_use", "spolzhouxuan_discard"], + subSkill: { + use: { + audio: "spolzhouxuan", + trigger: { player: "useCard" }, + filter: function (event, player) { + return player.getExpansions("spolzhouxuan").length > 0; }, - forced:true, - locked:false, - content:function(){ - 'step 0' - player.loseToDiscardpile(player.getExpansions('spolzhouxuan').randomGet()); - 'step 1' - var num=1; - if(!player.isMaxHandcard(true)) num+=player.getExpansions('spolzhouxuan').length; + forced: true, + locked: false, + content: function () { + "step 0"; + player.loseToDiscardpile(player.getExpansions("spolzhouxuan").randomGet()); + "step 1"; + var num = 1; + if (!player.isMaxHandcard(true)) + num += player.getExpansions("spolzhouxuan").length; player.draw(num); }, }, - discard:{ - audio:'spolzhouxuan', - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getExpansions('spolzhouxuan').length>0; + discard: { + audio: "spolzhouxuan", + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return player.getExpansions("spolzhouxuan").length > 0; }, - forced:true, - locked:false, - content:function(){ - player.loseToDiscardpile(player.getExpansions('spolzhouxuan')); + forced: true, + locked: false, + content: function () { + player.loseToDiscardpile(player.getExpansions("spolzhouxuan")); }, }, }, }, //董昭 - olxianlve:{ - audio:2, - mode:['identity'], - trigger:{ - global:'phaseZhunbeiBegin', + olxianlve: { + audio: 2, + mode: ["identity"], + trigger: { + global: "phaseZhunbeiBegin", }, - direct:true, - filter:function(event,player){ - return event.player==game.zhu&&event.player.isZhu; + direct: true, + filter: function (event, player) { + return event.player == game.zhu && event.player.isZhu; }, - content:function(){ - 'step 0' - var list=lib.inpile.filter(function(i){ - return get.type2(i)=='trick'; - }).map(function(i){ - return ['锦囊','',i]; - }); - if(!list.length) event.finish(); - else player.chooseButton([get.prompt('olxianlve'),[list,'vcard']]).set('ai',function(button){ - switch(button.link[2]){ - case 'wuxie': return 0.6+Math.random(); - case 'wuzhong': case 'dongzhuxianji':return 0.5+Math.random(); - case 'guohe': case 'zhujinqiyuan': return 0.4+Math.random(); - default: return Math.random(); - } - }); - 'step 1' - if(result.bool){ - var name=result.links[0][2]; - player.logSkill('olxianlve'); - player.storage.olxianlve=name; - player.markSkill('olxianlve'); - } - }, - intro:{ - content:function(name,player){ - return '已声明'+(player.isUnderControl(true)?'【'+get.translation(name)+'】':'一个牌名'); - }, - }, - group:['olxianlve_use','olxianlve_count'], - subSkill:{ - count:{ - trigger:{global:'useCard1'}, - silent:true, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.player!=player&&event.card.name==player.storage.olxianlve; - }, - content:function(){ - if(!trigger.olxianlve_map) trigger.olxianlve_map={}; - trigger.olxianlve_map[player.playerid]=true; - }, - }, - use:{ - audio:'olxianlve', - trigger:{global:'useCardAfter'}, - forced:true, - locked:false, - usable:1, - filter:function(event,player){ - return event.player!=player&&event.olxianlve_map&&event.olxianlve_map[player.playerid]&&event.card.name==player.storage.olxianlve; - }, - content:function(){ - 'step 0' - player.draw(2); - 'step 1' - var cards=result; - if(get.itemtype(cards)!='cards'){ - event.goto(5); - return; - } - var hs=player.getCards('h'); - cards=cards.filter(function(card){ - return hs.includes(card); - }); - if(!cards.length){ - event.goto(5); - return; - } - event.cards=cards; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - event.ai_list=[]; - 'step 2' - player.chooseCardTarget({ - filterCard:function(card){ - return _status.event.cards.includes(card)&&!card.hasGaintag('olxianlve'); - }, - cards:cards, - filterTarget:lib.filter.notMe, - selectCard:[1,cards.length], - prompt:'是否将得到的牌分配给其他角色?', - ai1:function(card){ - if(!ui.selected.cards.length) return 1; - return 0; - }, - ai2:function(target){ - var player=_status.event.player,card=ui.selected.cards[0]; - var val=target.getUseValue(card); - if(target.isPhaseUsing()&&get.type2(card)=='trick') val*=3; - if(val>0) return val*get.attitude(player,target)*2; - return get.value(card,target)*get.attitude(player,target); - }, - }); - 'step 3' - if(result.bool){ - var res=result.cards,target=result.targets[0].playerid; - player.addGaintag(res,'olxianlve'); - cards.removeArray(res); - if(!event.given_map[target]) event.given_map[target]=[]; - event.given_map[target].addArray(res); - if(result.targets[0].isPhaseUsing()&&get.type2(res[0])=='trick') event.ai_list.push(res[0].name); - if(cards.length) event.goto(2); - } - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - } - var map=[],cards=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - map.push([source,event.given_map[i]]); - cards.addArray(event.given_map[i]); - } - if(map.length) game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple') - 'step 5' - var list=lib.inpile.filter(function(i){ - return get.type2(i)=='trick'; - }).map(function(i){ - return ['锦囊','',i]; - }); - if(!list.length) event.finish(); - else player.chooseButton([get.prompt('olxianlve'),[list,'vcard']]).set('list',event.ai_list).set('ai',function(button){ - if(_status.event.list.includes(button.link[2])) return 2+Math.random(); - switch(button.link[2]){ - case 'wuxie': return 0.6+Math.random(); - case 'wuzhong': case 'dongzhuxianji':return 0.5+Math.random(); - case 'guohe': case 'zhujinqiyuan': return 0.4+Math.random(); - default: return Math.random(); + content: function () { + "step 0"; + var list = lib.inpile + .filter(function (i) { + return get.type2(i) == "trick"; + }) + .map(function (i) { + return ["锦囊", "", i]; + }); + if (!list.length) event.finish(); + else + player + .chooseButton([get.prompt("olxianlve"), [list, "vcard"]]) + .set("ai", function (button) { + switch (button.link[2]) { + case "wuxie": + return 0.6 + Math.random(); + case "wuzhong": + case "dongzhuxianji": + return 0.5 + Math.random(); + case "guohe": + case "zhujinqiyuan": + return 0.4 + Math.random(); + default: + return Math.random(); } }); - 'step 6' - if(result.bool){ - var name=result.links[0][2]; - player.storage.olxianlve=name; - player.markSkill('olxianlve'); + "step 1"; + if (result.bool) { + var name = result.links[0][2]; + player.logSkill("olxianlve"); + player.storage.olxianlve = name; + player.markSkill("olxianlve"); + } + }, + intro: { + content: function (name, player) { + return ( + "已声明" + + (player.isUnderControl(true) ? "【" + get.translation(name) + "】" : "一个牌名") + ); + }, + }, + group: ["olxianlve_use", "olxianlve_count"], + subSkill: { + count: { + trigger: { global: "useCard1" }, + silent: true, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return event.player != player && event.card.name == player.storage.olxianlve; + }, + content: function () { + if (!trigger.olxianlve_map) trigger.olxianlve_map = {}; + trigger.olxianlve_map[player.playerid] = true; + }, + }, + use: { + audio: "olxianlve", + trigger: { global: "useCardAfter" }, + forced: true, + locked: false, + usable: 1, + filter: function (event, player) { + return ( + event.player != player && + event.olxianlve_map && + event.olxianlve_map[player.playerid] && + event.card.name == player.storage.olxianlve + ); + }, + content: function () { + "step 0"; + player.draw(2); + "step 1"; + var cards = result; + if (get.itemtype(cards) != "cards") { + event.goto(5); + return; + } + var hs = player.getCards("h"); + cards = cards.filter(function (card) { + return hs.includes(card); + }); + if (!cards.length) { + event.goto(5); + return; + } + event.cards = cards; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + event.given_map = {}; + event.ai_list = []; + "step 2"; + player.chooseCardTarget({ + filterCard: function (card) { + return ( + _status.event.cards.includes(card) && !card.hasGaintag("olxianlve") + ); + }, + cards: cards, + filterTarget: lib.filter.notMe, + selectCard: [1, cards.length], + prompt: "是否将得到的牌分配给其他角色?", + ai1: function (card) { + if (!ui.selected.cards.length) return 1; + return 0; + }, + ai2: function (target) { + var player = _status.event.player, + card = ui.selected.cards[0]; + var val = target.getUseValue(card); + if (target.isPhaseUsing() && get.type2(card) == "trick") val *= 3; + if (val > 0) return val * get.attitude(player, target) * 2; + return get.value(card, target) * get.attitude(player, target); + }, + }); + "step 3"; + if (result.bool) { + var res = result.cards, + target = result.targets[0].playerid; + player.addGaintag(res, "olxianlve"); + cards.removeArray(res); + if (!event.given_map[target]) event.given_map[target] = []; + event.given_map[target].addArray(res); + if (result.targets[0].isPhaseUsing() && get.type2(res[0]) == "trick") + event.ai_list.push(res[0].name); + if (cards.length) event.goto(2); + } + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + var map = [], + cards = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + map.push([source, event.given_map[i]]); + cards.addArray(event.given_map[i]); + } + if (map.length) + game.loseAsync({ + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); + "step 5"; + var list = lib.inpile + .filter(function (i) { + return get.type2(i) == "trick"; + }) + .map(function (i) { + return ["锦囊", "", i]; + }); + if (!list.length) event.finish(); + else + player + .chooseButton([get.prompt("olxianlve"), [list, "vcard"]]) + .set("list", event.ai_list) + .set("ai", function (button) { + if (_status.event.list.includes(button.link[2])) + return 2 + Math.random(); + switch (button.link[2]) { + case "wuxie": + return 0.6 + Math.random(); + case "wuzhong": + case "dongzhuxianji": + return 0.5 + Math.random(); + case "guohe": + case "zhujinqiyuan": + return 0.4 + Math.random(); + default: + return Math.random(); + } + }); + "step 6"; + if (result.bool) { + var name = result.links[0][2]; + player.storage.olxianlve = name; + player.markSkill("olxianlve"); } }, }, }, }, - olzaowang:{ - mode:['identity'], - available:function(mode){ - if(mode=='identity'&&_status.mode=='purple') return false; + olzaowang: { + mode: ["identity"], + available: function (mode) { + if (mode == "identity" && _status.mode == "purple") return false; }, - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'water', - filterTarget:true, - content:function(){ - player.awakenSkill('olzaowang'); + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "water", + filterTarget: true, + content: function () { + player.awakenSkill("olzaowang"); target.gainMaxHp(); target.recover(); target.draw(3); - target.addSkills('olzaowang2'); + target.addSkills("olzaowang2"); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(player.hasUnknown(2)) return 0; - if(target.identity=='zhong') return 20; - if(target.identity=='zhu') return 10; - if(target.identity=='nei') return 5; - if(!target.hasFriend()) return 5; + ai: { + order: 2, + result: { + target: function (player, target) { + if (player.hasUnknown(2)) return 0; + if (target.identity == "zhong") return 20; + if (target.identity == "zhu") return 10; + if (target.identity == "nei") return 5; + if (!target.hasFriend()) return 5; return 0; }, }, }, }, - olzaowang2:{ - charlotte:true, - trigger:{global:'dieBegin'}, - forced:true, - filter:function(event,player){ - return event.player.identity=='zhu'&&(player.identity=='zhong'||player.identity=='mingzhong'); + olzaowang2: { + charlotte: true, + trigger: { global: "dieBegin" }, + forced: true, + filter: function (event, player) { + return ( + event.player.identity == "zhu" && + (player.identity == "zhong" || player.identity == "mingzhong") + ); }, - logTarget:'player', - skillAnimation:true, - animationColor:'orange', - content:function(){ - game.broadcastAll(function(player,target){ - target.identity=player.identity; - if(player.identity=='mingzhong') game.zhong=target; - delete target.isZhu; - player.identity='zhu'; - game.zhu=player; - player.showIdentity(); - target.showIdentity(); - },player,trigger.player); - event.trigger('zhuUpdate'); - }, - mark:true, - marktext:'王', - intro:{content:'造了个王'}, - group:'olzaowang2_kill', - subSkill:{ - kill:{ - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - return player.identity=='fan'&&event.source&&(event.source.identity=='zhu'||event.source.identity=='zhong'||event.source.identity=='mingzhong'); + logTarget: "player", + skillAnimation: true, + animationColor: "orange", + content: function () { + game.broadcastAll( + function (player, target) { + target.identity = player.identity; + if (player.identity == "mingzhong") game.zhong = target; + delete target.isZhu; + player.identity = "zhu"; + game.zhu = player; + player.showIdentity(); + target.showIdentity(); }, - content:function(){ - game.over((game.me.identity=='zhu'||game.me.identity=='zhong'||game.me.identity=='mingzhong')); + player, + trigger.player + ); + event.trigger("zhuUpdate"); + }, + mark: true, + marktext: "王", + intro: { content: "造了个王" }, + group: "olzaowang2_kill", + subSkill: { + kill: { + trigger: { player: "die" }, + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + return ( + player.identity == "fan" && + event.source && + (event.source.identity == "zhu" || + event.source.identity == "zhong" || + event.source.identity == "mingzhong") + ); + }, + content: function () { + game.over( + game.me.identity == "zhu" || + game.me.identity == "zhong" || + game.me.identity == "mingzhong" + ); }, }, }, }, //冯方女 - zhuangshu:{ - audio:2, - trigger:{global:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return event.player.isIn()&&event.player.hasEmptySlot(5)&&player.hasCard(lib.skill.zhuangshu.filterCard,'he'); + zhuangshu: { + audio: 2, + trigger: { global: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player.hasEmptySlot(5) && + player.hasCard(lib.skill.zhuangshu.filterCard, "he") + ); }, - filterCard:function(card){ - if(_status.connectMode) return true; - var type=get.type2(card); - return type=='basic'||type=='trick'||type=='equip'; + filterCard: function (card) { + if (_status.connectMode) return true; + var type = get.type2(card); + return type == "basic" || type == "trick" || type == "equip"; }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('zhuangshu',trigger.player),'弃置一张牌,并根据此牌的类型,按如下关系将一张宝物牌置入该角色的装备区:{<基本牌,【琼梳】>,<锦囊牌,【犀梳】>,<装备牌,【金梳】>}。',function(card){ - var type=get.type2(card); - return type=='basic'||type=='trick'||type=='equip'; - }).set('ai',function(card){ - var player=_status.event.player; - if(get.attitude(player,_status.event.getTrigger().player)<4) return 0; - var name='zhuangshu_'+get.type2(card,player); - if(game.hasPlayer(function(current){ - return current.getEquip(name)&&get.attitude(player,current)>0; - })) return 0; - return 7-get.value(card); - }).logSkill=['zhuangshu',trigger.player]; - 'step 1' - if(result.bool){ - var name='zhuangshu_'+get.type2(result.cards[0],result.cards[0].original=='h'?player:false); - if(lib.card[name]&&trigger.player.isIn&&trigger.player.hasEmptySlot(5)){ - var target=game.findPlayer(function(current){ - var equip=current.getEquip(name); - return equip&&equip.name==name; - }); - if(target){ - var card=target.getEquip(name); - target.$give(card,trigger.player,false); + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("zhuangshu", trigger.player), + "弃置一张牌,并根据此牌的类型,按如下关系将一张宝物牌置入该角色的装备区:{<基本牌,【琼梳】>,<锦囊牌,【犀梳】>,<装备牌,【金梳】>}。", + function (card) { + var type = get.type2(card); + return type == "basic" || type == "trick" || type == "equip"; } - else{ - var card=game.createCard(name,lib.card[name].suit,12); - trigger.player.$gain2(card,false); + ) + .set("ai", function (card) { + var player = _status.event.player; + if (get.attitude(player, _status.event.getTrigger().player) < 4) return 0; + var name = "zhuangshu_" + get.type2(card, player); + if ( + game.hasPlayer(function (current) { + return current.getEquip(name) && get.attitude(player, current) > 0; + }) + ) + return 0; + return 7 - get.value(card); + }).logSkill = ["zhuangshu", trigger.player]; + "step 1"; + if (result.bool) { + var name = + "zhuangshu_" + + get.type2(result.cards[0], result.cards[0].original == "h" ? player : false); + if (lib.card[name] && trigger.player.isIn && trigger.player.hasEmptySlot(5)) { + var target = game.findPlayer(function (current) { + var equip = current.getEquip(name); + return equip && equip.name == name; + }); + if (target) { + var card = target.getEquip(name); + target.$give(card, trigger.player, false); + } else { + var card = game.createCard(name, lib.card[name].suit, 12); + trigger.player.$gain2(card, false); } game.delayx(); trigger.player.equip(card); } } }, - group:'zhuangshu_gameStart', - subSkill:{ - gameStart:{ - trigger:{global:'phaseBefore'}, - direct:true, - filter:function(event,player){ - return game.phaseNumber==0; + group: "zhuangshu_gameStart", + subSkill: { + gameStart: { + trigger: { global: "phaseBefore" }, + direct: true, + filter: function (event, player) { + return game.phaseNumber == 0; }, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('zhuangshu'),[['zhuangshu_basic','zhuangshu_trick','zhuangshu_equip'],'vcard']]).set('filterButton',function(button){ - return !game.hasPlayer(function(current){ - return current.getEquip(button.link[2]); - }) - }); - 'step 1' - if(result.bool){ - player.logSkill('zhuangshu'); - var name=result.links[0][2],card=game.createCard(name,lib.card[name].suit,12); - player.$gain2(card,false); + content: function () { + "step 0"; + player + .chooseButton([ + get.prompt("zhuangshu"), + [["zhuangshu_basic", "zhuangshu_trick", "zhuangshu_equip"], "vcard"], + ]) + .set("filterButton", function (button) { + return !game.hasPlayer(function (current) { + return current.getEquip(button.link[2]); + }); + }); + "step 1"; + if (result.bool) { + player.logSkill("zhuangshu"); + var name = result.links[0][2], + card = game.createCard(name, lib.card[name].suit, 12); + player.$gain2(card, false); game.delayx(); player.equip(card); } @@ -11941,74 +15855,84 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - chuiti:{ - audio:2, - usable:1, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + chuiti: { + audio: 2, + usable: 1, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - direct:true, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - return game.hasPlayer(function(current){ - if(player!=current){ - var cards=current.getEquips(5); - if(!cards.some(card=>card.name.indexOf('zhuangshu_')==0)) return false; + direct: true, + filter: function (event, player) { + if (event.type != "discard" || event.getlx === false) return false; + return game.hasPlayer(function (current) { + if (player != current) { + var cards = current.getEquips(5); + if (!cards.some((card) => card.name.indexOf("zhuangshu_") == 0)) return false; } - var evt=event.getl(current); - if(!evt||!evt.cards2) return false; - for(var i of evt.cards2){ - if(get.position(i,true)=='d'&&player.hasUseTarget(i)) return true; + var evt = event.getl(current); + if (!evt || !evt.cards2) return false; + for (var i of evt.cards2) { + if (get.position(i, true) == "d" && player.hasUseTarget(i)) return true; } return false; }); }, - content:function(){ - 'step 0' - var cards=[]; - game.countPlayer(function(current){ - if(player!=current){ - var cards2=current.getEquips(5); - if(!cards2.some(card=>card.name.indexOf('zhuangshu_')==0)) return false; + content: function () { + "step 0"; + var cards = []; + game.countPlayer(function (current) { + if (player != current) { + var cards2 = current.getEquips(5); + if (!cards2.some((card) => card.name.indexOf("zhuangshu_") == 0)) return false; } - var evt=trigger.getl(current); - for(var i of evt.cards2){ - if(get.position(i,true)=='d'&&player.hasUseTarget(i)) cards.push(i); + var evt = trigger.getl(current); + for (var i of evt.cards2) { + if (get.position(i, true) == "d" && player.hasUseTarget(i)) cards.push(i); } return false; }); - player.chooseButton(['垂涕:是否使用其中的一张牌?',cards]).set('ai',function(button){ + player.chooseButton(["垂涕:是否使用其中的一张牌?", cards]).set("ai", function (button) { return _status.event.player.getUseValue(button.link); }); - 'step 1' - if(result.bool){ - player.$gain2(result.links[0],false); + "step 1"; + if (result.bool) { + player.$gain2(result.links[0], false); game.delayx(); - player.chooseUseTarget(true,result.links[0],false).logSkill='chuiti'; - } - else player.storage.counttrigger.chuiti--; + player.chooseUseTarget(true, result.links[0], false).logSkill = "chuiti"; + } else player.storage.counttrigger.chuiti--; }, }, - zhuangshu_basic:{ - equipSkill:true, - trigger:{player:'damageBegin2'}, - direct:true, - filter:function(event,player){ - var equip=player.getEquip('zhuangshu_basic'); - return event.num<=player.countCards('he',function(card){ - return card!=equip; - }) + zhuangshu_basic: { + equipSkill: true, + trigger: { player: "damageBegin2" }, + direct: true, + filter: function (event, player) { + var equip = player.getEquip("zhuangshu_basic"); + return ( + event.num <= + player.countCards("he", function (card) { + return card != equip; + }) + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',trigger.num,get.prompt('zhuangshu_basic'),'弃置'+get.cnNumber(trigger.num)+'张牌并防止伤害',function(card,player){ - return card!=player.getEquip('zhuangshu_basic'); - }).set('ai',function(card){ - var player=_status.event.player; - return 4+player.getUseValue(card)-get.value(card,player); - }); - 'step 1' - if(result.bool) trigger.cancel(); + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + trigger.num, + get.prompt("zhuangshu_basic"), + "弃置" + get.cnNumber(trigger.num) + "张牌并防止伤害", + function (card, player) { + return card != player.getEquip("zhuangshu_basic"); + } + ) + .set("ai", function (card) { + var player = _status.event.player; + return 4 + player.getUseValue(card) - get.value(card, player); + }); + "step 1"; + if (result.bool) trigger.cancel(); }, /*usable:1, trigger:{player:'useCard2'}, @@ -12050,186 +15974,237 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.directHit.addArray(targets); },*/ }, - zhuangshu_trick:{ - trigger:{player:['phaseJudgeBefore']}, - equipSkill:true, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('判定阶段','弃牌阶段','cancel2').set('prompt',get.prompt('zhuangshu_trick')).set('prompt2','跳过本回合的判定阶段或弃牌阶段').set('ai',function(){ - var player=_status.event.player; - if(player.hasCard(function(card){ - return get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)<0; - },'j')) return '判定阶段'; - return '弃牌阶段'; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('zhuangshu_trick'); - if(result.control=='判定阶段'){ + zhuangshu_trick: { + trigger: { player: ["phaseJudgeBefore"] }, + equipSkill: true, + direct: true, + content: function () { + "step 0"; + player + .chooseControl("判定阶段", "弃牌阶段", "cancel2") + .set("prompt", get.prompt("zhuangshu_trick")) + .set("prompt2", "跳过本回合的判定阶段或弃牌阶段") + .set("ai", function () { + var player = _status.event.player; + if ( + player.hasCard(function (card) { + return ( + get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) < 0 + ); + }, "j") + ) + return "判定阶段"; + return "弃牌阶段"; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("zhuangshu_trick"); + if (result.control == "判定阶段") { trigger.cancel(); - game.log(player,'跳过了','#y判定阶段'); - } - else{ - player.skip('phaseDiscard'); - game.log(player,'跳过了','#g弃牌阶段'); + game.log(player, "跳过了", "#y判定阶段"); + } else { + player.skip("phaseDiscard"); + game.log(player, "跳过了", "#g弃牌阶段"); } } }, }, - zhuangshu_equip:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - return player.countCards('h')0) list.push(eff); - } - list.sort().reverse(); - if(!list.length) return 0; - return list[0]+(list[1]||0)+(list[2]||0); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('oljuanxia',target); - } - else event.finish(); - 'step 2' - var list=[]; - for(var name of lib.inpile){ - var info=lib.card[name]; - if(!info||info.type!='trick'||info.notarget||(info.selectTarget&&info.selectTarget!=1)) continue; + oljuanxia: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("oljuanxia"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player, + list = []; + for (var name of lib.inpile) { + var info = lib.card[name]; + if ( + !info || + info.type != "trick" || + info.notarget || + (info.selectTarget && info.selectTarget != 1) + ) + continue; + if (!player.canUse(name, target, false)) continue; + var eff = get.effect(target, { name: name }, player, player); + if (eff > 0) list.push(eff); + } + list.sort().reverse(); + if (!list.length) return 0; + return list[0] + (list[1] || 0) + (list[2] || 0); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("oljuanxia", target); + } else event.finish(); + "step 2"; + var list = []; + for (var name of lib.inpile) { + var info = lib.card[name]; + if ( + !info || + info.type != "trick" || + info.notarget || + (info.selectTarget && info.selectTarget != 1) + ) + continue; list.push(name); } - if(!list.length) event.finish(); - else{ - event.list=list; - event.count=0; + if (!list.length) event.finish(); + else { + event.list = list; + event.count = 0; } - 'step 3' - var list=event.list.filter(function(name){ - return player.canUse(name,target,false); + "step 3"; + var list = event.list.filter(function (name) { + return player.canUse(name, target, false); }); - if(list.length){ - var next=player.chooseButton(['视为对'+get.translation(target)+'使用一张牌',[list,'vcard']]).set('ai',function(button){ - var evt=_status.event.getParent(); - return get.effect(evt.target,{name:button.link[2]},evt.player,evt.player); - }); - if(event.count==0) next.set('forced',true); - } - else{ - event.stopped=true; + if (list.length) { + var next = player + .chooseButton([ + "视为对" + get.translation(target) + "使用一张牌", + [list, "vcard"], + ]) + .set("ai", function (button) { + var evt = _status.event.getParent(); + return get.effect( + evt.target, + { name: button.link[2] }, + evt.player, + evt.player + ); + }); + if (event.count == 0) next.set("forced", true); + } else { + event.stopped = true; event.goto(5); } - 'step 4' - if(result.bool){ + "step 4"; + if (result.bool) { event.count++; - var name=result.links[0][2]; + var name = result.links[0][2]; event.list.remove(name); - player.useCard({name:name,isCard:true},target,false); - } - else event.stopped=true; - 'step 5' - if(target.isIn()&&event.count>0){ - if(event.count<3&&!event.stopped&&event.list.length>0) event.goto(3); - else{ - target.addTempSkill('oljuanxia_counter',{player:'phaseAfter'}); - if(!target.storage.oljuanxia_counter) target.storage.oljuanxia_counter={}; - if(!target.storage.oljuanxia_counter[player.playerid]) target.storage.oljuanxia_counter[player.playerid]=0; - target.storage.oljuanxia_counter[player.playerid]+=event.count; + player.useCard({ name: name, isCard: true }, target, false); + } else event.stopped = true; + "step 5"; + if (target.isIn() && event.count > 0) { + if (event.count < 3 && !event.stopped && event.list.length > 0) event.goto(3); + else { + target.addTempSkill("oljuanxia_counter", { player: "phaseAfter" }); + if (!target.storage.oljuanxia_counter) target.storage.oljuanxia_counter = {}; + if (!target.storage.oljuanxia_counter[player.playerid]) + target.storage.oljuanxia_counter[player.playerid] = 0; + target.storage.oljuanxia_counter[player.playerid] += event.count; } } }, - subSkill:{ - counter:{ - trigger:{player:'phaseEnd'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - var map1=(_status.connectMode?lib.playerOL:game.playerMap),map2=player.storage.oljuanxia_counter; - if(!map2) return false; - for(var i in map2){ - if(map1[i]&&map1[i].isIn()&&player.canUse('sha',map1[i],false)) return true; + subSkill: { + counter: { + trigger: { player: "phaseEnd" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + var map1 = _status.connectMode ? lib.playerOL : game.playerMap, + map2 = player.storage.oljuanxia_counter; + if (!map2) return false; + for (var i in map2) { + if (map1[i] && map1[i].isIn() && player.canUse("sha", map1[i], false)) + return true; } return false; }, - logTarget:function(event,player){ - var list=[]; - var map1=(_status.connectMode?lib.playerOL:game.playerMap),map2=player.storage.oljuanxia_counter; - if(!map2) return false; - for(var i in map2){ - if(map1[i]&&map1[i].isIn()) list.push(map1[i]); + logTarget: function (event, player) { + var list = []; + var map1 = _status.connectMode ? lib.playerOL : game.playerMap, + map2 = player.storage.oljuanxia_counter; + if (!map2) return false; + for (var i in map2) { + if (map1[i] && map1[i].isIn()) list.push(map1[i]); } return list; }, - content:function(){ - 'step 0' - var list=[]; - var map1=(_status.connectMode?lib.playerOL:game.playerMap),map2=player.storage.oljuanxia_counter; - if(!map2) return false; - for(var i in map2){ - if(map1[i]&&map1[i].isIn()) list.push(map1[i]); + content: function () { + "step 0"; + var list = []; + var map1 = _status.connectMode ? lib.playerOL : game.playerMap, + map2 = player.storage.oljuanxia_counter; + if (!map2) return false; + for (var i in map2) { + if (map1[i] && map1[i].isIn()) list.push(map1[i]); } list.sortBySeat(); - event.num=0; - event.targets=list; - 'step 1' - var target=targets[num]; - event.target=target; - if(target.isIn()&&player.canUse('sha',target,false)) player.chooseBool('狷狭:是否视为对'+get.translation(target)+'依次使用'+get.cnNumber(player.storage.oljuanxia_counter[target.playerid])+'张【杀】?').set('goon',get.effect(target,{name:'sha'},player,player)>0).set('ai',()=>_status.event.goon); - 'step 2' + event.num = 0; + event.targets = list; + "step 1"; + var target = targets[num]; + event.target = target; + if (target.isIn() && player.canUse("sha", target, false)) + player + .chooseBool( + "狷狭:是否视为对" + + get.translation(target) + + "依次使用" + + get.cnNumber(player.storage.oljuanxia_counter[target.playerid]) + + "张【杀】?" + ) + .set("goon", get.effect(target, { name: "sha" }, player, player) > 0) + .set("ai", () => _status.event.goon); + "step 2"; event.num++; - if(result.bool) event.count=player.storage.oljuanxia_counter[target.playerid]; - else if(event.num0) event.redo(); - else if(event.num 0) event.redo(); + else if (event.num < targets.length) event.goto(1); }, }, }, }, - oldingcuo:{ - trigger:{ - player:'damageEnd', - source:'damageSource', + oldingcuo: { + trigger: { + player: "damageEnd", + source: "damageSource", }, - usable:1, - content:function(){ - 'step 0' + usable: 1, + content: function () { + "step 0"; player.draw(2); - 'step 1' - if(Array.isArray(result)&&result.length>1){ - var color=get.color(result[0],player); - for(var i=1;i 1) { + var color = get.color(result[0], player); + for (var i = 1; i < result.length; i++) { + if (get.color(result[i], player) != color) { + if (player.countCards("h")) player.chooseToDiscard("h", true); break; } } @@ -12237,78 +16212,101 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //左棻 - zhaosong:{ - trigger:{global:'phaseDrawAfter'}, - logTarget:'player', - filter:function(event,player){ - if(player==event.player||!event.player.countCards('h')) return false; - var types=['basic','trick','equip']; - for(var i of types){ - if(event.player.hasMark('zhaosong_'+i)) return false; + zhaosong: { + trigger: { global: "phaseDrawAfter" }, + logTarget: "player", + filter: function (event, player) { + if (player == event.player || !event.player.countCards("h")) return false; + var types = ["basic", "trick", "equip"]; + for (var i of types) { + if (event.player.hasMark("zhaosong_" + i)) return false; } return true; }, - prompt2:'令其交给你一张手牌,并根据类型获得对应的标记', - check:function(event,player){ - return get.attitude(_status.event.player,event.player)>0; + prompt2: "令其交给你一张手牌,并根据类型获得对应的标记", + check: function (event, player) { + return get.attitude(_status.event.player, event.player) > 0; }, - content:function(){ - 'step 0' - event.target=trigger.player; - event.target.chooseCard('h',true,get.translation(player)+'发动了【诏颂】;请交给其一张手牌'); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - target.give(card,player,'give'); - var type=get.type2(card,target); - if(lib.skill['zhaosong_'+type]){ - target.addSkill('zhaosong_'+type); - target.addMark('zhaosong_'+type); + content: function () { + "step 0"; + event.target = trigger.player; + event.target.chooseCard( + "h", + true, + get.translation(player) + "发动了【诏颂】;请交给其一张手牌" + ); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + target.give(card, player, "give"); + var type = get.type2(card, target); + if (lib.skill["zhaosong_" + type]) { + target.addSkill("zhaosong_" + type); + target.addMark("zhaosong_" + type); } } }, - subSkill:{ - basic:{ - marktext:'颂', - intro:{ - name:'诏颂(颂)', - name2:'颂', - content:'当你使用【杀】选择唯一目标时,你可移去“颂”,并为此【杀】增加至多两个目标。', + subSkill: { + basic: { + marktext: "颂", + intro: { + name: "诏颂(颂)", + name2: "颂", + content: + "当你使用【杀】选择唯一目标时,你可移去“颂”,并为此【杀】增加至多两个目标。", }, - trigger:{player:'useCard2'}, - direct:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.hasMark('zhaosong_basic')&&event.card.name=='sha'&& - event.targets.length==1&&game.hasPlayer(function(current){ - return current!=player&¤t!=event.targets[0]&&lib.filter.targetEnabled2(event.card,player,current); - }); + trigger: { player: "useCard2" }, + direct: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + player.hasMark("zhaosong_basic") && + event.card.name == "sha" && + event.targets.length == 1 && + game.hasPlayer(function (current) { + return ( + current != player && + current != event.targets[0] && + lib.filter.targetEnabled2(event.card, player, current) + ); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget([1,2],'是否弃置“颂”标记?','为'+get.translation(trigger.card)+'增加至多两个目标',function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&target!=evt.targets[0]&&lib.filter.targetEnabled2(evt.card,player,target); - }).set('ai',function(target){ - var evt=_status.event.getTrigger(); - return get.effect(target,evt.card,evt.player,evt.player); - }); - 'step 1' - if(result.bool){ - if(player!=event.player&&!player.isOnline()) game.delayx(); + content: function () { + "step 0"; + player + .chooseTarget( + [1, 2], + "是否弃置“颂”标记?", + "为" + get.translation(trigger.card) + "增加至多两个目标", + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + target != evt.targets[0] && + lib.filter.targetEnabled2(evt.card, player, target) + ); + } + ) + .set("ai", function (target) { + var evt = _status.event.getTrigger(); + return get.effect(target, evt.card, evt.player, evt.player); + }); + "step 1"; + if (result.bool) { + if (player != event.player && !player.isOnline()) game.delayx(); //player.addTempSkill('zhaosong_shaloss'); - } - else event.finish(); - 'step 2' - var targets=result.targets; - player.logSkill('zhaosong_basic',targets); - player.removeMark('zhaosong_basic',1); - player.removeSkill('zhaosong_basic'); + } else event.finish(); + "step 2"; + var targets = result.targets; + player.logSkill("zhaosong_basic", targets); + player.removeMark("zhaosong_basic", 1); + player.removeSkill("zhaosong_basic"); trigger.targets.addArray(targets); - trigger.zhaosong_basic=true; + trigger.zhaosong_basic = true; }, - },/* + } /* shaloss:{ trigger:{player:'useCardAfter'}, forced:true, @@ -12324,142 +16322,194 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.loseHp(); }, - },*/ - trick:{ - marktext:'诔', - intro:{ - name:'诏颂(诔)', - name2:'诔', - content:'当你进入濒死状态时,你可移去“诔”,然后将体力回复至1点并摸一张牌。', + },*/, + trick: { + marktext: "诔", + intro: { + name: "诏颂(诔)", + name2: "诔", + content: "当你进入濒死状态时,你可移去“诔”,然后将体力回复至1点并摸一张牌。", }, - trigger:{player:'dying'}, - prompt:'是否弃置“诔”标记?', - prompt2:'回复体力至1点并摸一张牌。', - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.hasMark('zhaosong_trick')&&player.hp<1; + trigger: { player: "dying" }, + prompt: "是否弃置“诔”标记?", + prompt2: "回复体力至1点并摸一张牌。", + charlotte: true, + onremove: true, + filter: function (event, player) { + return player.hasMark("zhaosong_trick") && player.hp < 1; }, - check:function(event,player){ - if(player.maxHp<2||player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,event.player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,event.player); - return savable; - })>=1+event.num-event.player.hp) return false; + check: function (event, player) { + if ( + player.maxHp < 2 || + player.countCards("h", function (card) { + var mod2 = game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + event.player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") + savable = savable(card, player, event.player); + return savable; + }) >= + 1 + event.num - event.player.hp + ) + return false; return true; }, - content:function(){ - player.removeMark('zhaosong_trick',1); - player.removeSkill('zhaosong_trick'); + content: function () { + player.removeMark("zhaosong_trick", 1); + player.removeSkill("zhaosong_trick"); //player.loseMaxHp(); - if(player.hp<1) player.recover(1-player.hp); + if (player.hp < 1) player.recover(1 - player.hp); player.draw(); }, }, - equip:{ - marktext:'赋', - intro:{ - name:'诏颂(赋)', - name2:'赋', - content:'出牌阶段开始时,你可移去“赋”并弃置一名角色区域内的至多两张牌。', + equip: { + marktext: "赋", + intro: { + name: "诏颂(赋)", + name2: "赋", + content: "出牌阶段开始时,你可移去“赋”并弃置一名角色区域内的至多两张牌。", }, - trigger:{player:'phaseUseBegin'}, - direct:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.hasMark('zhaosong_equip')&&game.hasPlayer(function(current){ - return current.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,current); - },'hej'); - }); + trigger: { player: "phaseUseBegin" }, + direct: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + player.hasMark("zhaosong_equip") && + game.hasPlayer(function (current) { + return current.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, current); + }, "hej"); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget('是否弃置“赋”标记?','弃置一名角色区域内的至多两张牌',function(card,player,current){ - return current.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,current); - },'hej'); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target)>0?2:1; - return get.effect(target,{name:'guohe_copy'},player,player)*att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('zhaosong_equip',target); - player.removeMark('zhaosong_equip',1); - player.removeSkill('zhaosong_equip'); - player.discardPlayerCard(target,true,'hej',[1,2]); + content: function () { + "step 0"; + player + .chooseTarget( + "是否弃置“赋”标记?", + "弃置一名角色区域内的至多两张牌", + function (card, player, current) { + return current.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, current); + }, "hej"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target) > 0 ? 2 : 1; + return get.effect(target, { name: "guohe_copy" }, player, player) * att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("zhaosong_equip", target); + player.removeMark("zhaosong_equip", 1); + player.removeSkill("zhaosong_equip"); + player.discardPlayerCard(target, true, "hej", [1, 2]); } }, }, }, }, - lisi:{ - audio:2, - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - if(player==_status.currentPhase||!event.cards.filterInD().length) return false; - var hs=player.countCards('h'); - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')<=hs; + lisi: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + if (player == _status.currentPhase || !event.cards.filterInD().length) return false; + var hs = player.countCards("h"); + return game.hasPlayer(function (current) { + return current != player && current.countCards("h") <= hs; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('lisi'),'将'+get.translation(trigger.cards.filterInD())+'交给一名手牌数不大于你的其他角色',function(card,player,target){ - return target!=player&&target.countCards('h')<=player.countCards('h'); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('lisi',target); - target.gain(trigger.cards.filterInD(),'gain2'); + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("lisi"), + "将" + + get.translation(trigger.cards.filterInD()) + + "交给一名手牌数不大于你的其他角色", + function (card, player, target) { + return target != player && target.countCards("h") <= player.countCards("h"); + } + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("lisi", target); + target.gain(trigger.cards.filterInD(), "gain2"); } }, }, //王荣 - olfengzi:{ - audio:2, - trigger:{player:'useCard'}, - direct:true, - usable:1, - filter:function(event,player){ - if(event.olfengzi_buff||!event.targets.length||!player.isPhaseUsing()||player.hasSkill('olfengzi_buff')) return false; - var type=get.type(event.card,false); - if(type!='basic'&&type!='trick') return false; - return player.hasCard(function(i){ - if(_status.connectMode) return true; - return get.type2(i,player)==type; - },'h'); + olfengzi: { + audio: 2, + trigger: { player: "useCard" }, + direct: true, + usable: 1, + filter: function (event, player) { + if ( + event.olfengzi_buff || + !event.targets.length || + !player.isPhaseUsing() || + player.hasSkill("olfengzi_buff") + ) + return false; + var type = get.type(event.card, false); + if (type != "basic" && type != "trick") return false; + return player.hasCard(function (i) { + if (_status.connectMode) return true; + return get.type2(i, player) == type; + }, "h"); }, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isUnderControl()&&!player.isOnline()) game.delayx(); - var type=get.type(trigger.card,false); - player.chooseToDiscard('h',get.prompt('olfengzi'),'弃置一张'+get.translation(type)+'牌,令'+get.translation(trigger.card)+'结算两次',function(card,player){ - return get.type2(card,player)==_status.event.type; - }).set('type',type).set('ai',function(card){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - if(trigger.card.name=='tiesuo') return 0; - var num=0; - for(var i of trigger.targets) num+=get.effect(i,trigger.card,player,player); - if(num<=0) return 0; - return 7-get.value(card); - }).logSkill='olfengzi'; - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + if (player != game.me && !player.isUnderControl() && !player.isOnline()) game.delayx(); + var type = get.type(trigger.card, false); + player + .chooseToDiscard( + "h", + get.prompt("olfengzi"), + "弃置一张" + + get.translation(type) + + "牌,令" + + get.translation(trigger.card) + + "结算两次", + function (card, player) { + return get.type2(card, player) == _status.event.type; + } + ) + .set("type", type) + .set("ai", function (card) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + if (trigger.card.name == "tiesuo") return 0; + var num = 0; + for (var i of trigger.targets) num += get.effect(i, trigger.card, player, player); + if (num <= 0) return 0; + return 7 - get.value(card); + }).logSkill = "olfengzi"; + "step 1"; + if (result.bool) { trigger.effectCount++; - } - else player.storage.counttrigger.olfengzi--; + } else player.storage.counttrigger.olfengzi--; }, /*subSkill:{ buff:{ @@ -12481,3682 +16531,4689 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, },*/ }, - oljizhan:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ + oljizhan: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - var card=get.cards()[0]; + var card = get.cards()[0]; game.cardsGotoOrdering(card); - event.cards=[card]; - event.num=get.number(card,false); - player.showCards(card,get.translation(player)+'发动了【吉占】'); - 'step 1' - var str=get.strNumber(num); - player.chooseControl('大于'+str,'小于'+str,'cancel2').set('prompt','吉占:猜测下一张牌的点数').set('choice',num<7?0:1).set('ai',()=>_status.event.choice); - 'step 2' - var card=get.cards()[0]; + event.cards = [card]; + event.num = get.number(card, false); + player.showCards(card, get.translation(player) + "发动了【吉占】"); + "step 1"; + var str = get.strNumber(num); + player + .chooseControl("大于" + str, "小于" + str, "cancel2") + .set("prompt", "吉占:猜测下一张牌的点数") + .set("choice", num < 7 ? 0 : 1) + .set("ai", () => _status.event.choice); + "step 2"; + var card = get.cards()[0]; game.cardsGotoOrdering(card); event.cards.push(card); - var num=get.number(card,false); - if(num>event.num&&result.index==0||num event.num && result.index == 0) || (num < event.num && result.index == 1)) { + event.num = num; event.goto(1); } player.showCards(card); - 'step 3' - player.gain(cards,'gain2'); + "step 3"; + player.gain(cards, "gain2"); }, }, - olfusong:{ - audio:2, - forceDie:true, - trigger:{player:'die'}, - skillAnimation:true, - animationColor:'gray', - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.maxHp>player.maxHp; + olfusong: { + audio: 2, + forceDie: true, + trigger: { player: "die" }, + skillAnimation: true, + animationColor: "gray", + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.maxHp > player.maxHp; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('olfusong'),'令一名体力上限大于你的其他角色获得〖丰姿〗或〖吉占〗',function(card,player,target){ - return target.maxHp>player.maxHp; - }).set('forceDie',true).set('ai',(target)=>get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('olfusong',target); - target.chooseControl('olfengzi','oljizhan').set('prompt','令'+get.translation(target)+'获得其中一个技能').set('ai',()=>(Math.random()>0.5?0:1)); - } - else event.finish(); - 'step 2' + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("olfusong"), + "令一名体力上限大于你的其他角色获得〖丰姿〗或〖吉占〗", + function (card, player, target) { + return target.maxHp > player.maxHp; + } + ) + .set("forceDie", true) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("olfusong", target); + target + .chooseControl("olfengzi", "oljizhan") + .set("prompt", "令" + get.translation(target) + "获得其中一个技能") + .set("ai", () => (Math.random() > 0.5 ? 0 : 1)); + } else event.finish(); + "step 2"; target.addSkills(result.control); }, }, //邓芝 - olxiuhao:{ - audio:2, - trigger:{global:'damageBegin4'}, - usable:1, - filter:function(event,player){ - return event.source&&event.source.isIn()&&[event.source,event.player].includes(player)&&event.source!=event.player; + olxiuhao: { + audio: 2, + trigger: { global: "damageBegin4" }, + usable: 1, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + [event.source, event.player].includes(player) && + event.source != event.player + ); }, - logTarget:function(event,player){ - return player==event.player?event.source:event.player; + logTarget: function (event, player) { + return player == event.player ? event.source : event.player; }, - check:function(event,player){ - _status.olxiuhao_judging=true; - var bool=false; - if(get.attitude(player,event.player)>0) bool=true; - else if(2*get.effect(event.source,{name:'draw'},player,_status.event.player)+event.num*get.damageEffect(player,event.source,_status.event.player,event.nature)>0) bool=true; - else if(event.source.hasSkillTag('nogain')) bool=true; + check: function (event, player) { + _status.olxiuhao_judging = true; + var bool = false; + if (get.attitude(player, event.player) > 0) bool = true; + else if ( + 2 * get.effect(event.source, { name: "draw" }, player, _status.event.player) + + event.num * + get.damageEffect(player, event.source, _status.event.player, event.nature) > + 0 + ) + bool = true; + else if (event.source.hasSkillTag("nogain")) bool = true; delete _status.olxiuhao_judging; return bool; }, - content:function(){ + content: function () { trigger.cancel(); trigger.source.draw(2); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(!_status.olxiuhao_judging&&get.tag(card,'damage')&&get.attitude(target,player)>0&&player!=target&&(!target.storage.counttrigger||!target.storage.counttrigger.olxiuhao)) return [0,0.5,0,0.5]; + ai: { + effect: { + target: function (card, player, target) { + if ( + !_status.olxiuhao_judging && + get.tag(card, "damage") && + get.attitude(target, player) > 0 && + player != target && + (!target.storage.counttrigger || !target.storage.counttrigger.olxiuhao) + ) + return [0, 0.5, 0, 0.5]; }, - player:function(card,player,target){ - if(!_status.olxiuhao_judging&&get.tag(card,'damage')&&get.attitude(player,target)>0&&player!=target&&(!player.storage.counttrigger||!player.storage.counttrigger.olxiuhao)) return [0,0.5,0,0.5]; + player: function (card, player, target) { + if ( + !_status.olxiuhao_judging && + get.tag(card, "damage") && + get.attitude(player, target) > 0 && + player != target && + (!player.storage.counttrigger || !player.storage.counttrigger.olxiuhao) + ) + return [0, 0.5, 0, 0.5]; }, }, }, }, - olsujian:{ - trigger:{player:'phaseDiscardBefore'}, - forced:true, - content:function(){ + olsujian: { + trigger: { player: "phaseDiscardBefore" }, + forced: true, + content: function () { trigger.setContent(lib.skill.olsujian.phaseDiscard); }, - phaseDiscard:function(){ - 'step 0' - game.log(player,'进入了弃牌阶段'); - game.broadcastAll(function(player){ - if(lib.config.show_phase_prompt){ - player.popup('弃牌阶段',null,false); + phaseDiscard: function () { + "step 0"; + game.log(player, "进入了弃牌阶段"); + game.broadcastAll(function (player) { + if (lib.config.show_phase_prompt) { + player.popup("弃牌阶段", null, false); } - },player); - event.trigger('phaseDiscard'); - 'step 1' - var cards=lib.skill.olsujian.update(player); - if(!cards.length) event.finish(); - else{ - event.cards=cards; - var str=get.translation(cards); - player.chooseControl().set('choiceList',[ - '将'+str+'分配给任意名其他角色', - '弃置'+str+'并弃置一名其他角色至多等量的牌', - ]).set('ai',function(){ - var cards=_status.event.getParent().cards,player=_status.event.player; - if(!game.hasPlayer(function(current){ - return player!==current&&get.attitude(player,current)>0; - })) return 1; - if(game.hasPlayer(function(current){ - var att=get.attitude(player,current); - return att&¤t.countDiscardableCards(player,'he',function(i){ - if(att>0) return get.value(i,current)<0; - return get.value(i,current)>=4; - })>=cards.length&&get.effect(current,{name:'guohe_copy2'},player,player)>0; - })) return 1; - return 0; - }); + }, player); + event.trigger("phaseDiscard"); + "step 1"; + var cards = lib.skill.olsujian.update(player); + if (!cards.length) event.finish(); + else { + event.cards = cards; + var str = get.translation(cards); + player + .chooseControl() + .set("choiceList", [ + "将" + str + "分配给任意名其他角色", + "弃置" + str + "并弃置一名其他角色至多等量的牌", + ]) + .set("ai", function () { + var cards = _status.event.getParent().cards, + player = _status.event.player; + if ( + !game.hasPlayer(function (current) { + return player !== current && get.attitude(player, current) > 0; + }) + ) + return 1; + if ( + game.hasPlayer(function (current) { + var att = get.attitude(player, current); + return ( + att && + current.countDiscardableCards(player, "he", function (i) { + if (att > 0) return get.value(i, current) < 0; + return get.value(i, current) >= 4; + }) >= cards.length && + get.effect(current, { name: "guohe_copy2" }, player, player) > 0 + ); + }) + ) + return 1; + return 0; + }); } - 'step 2' - if(result.index==1){ - cards=event.cards.filter(function(i){ - return lib.filter.cardDiscardable(i,player,'olsujian'); + "step 2"; + if (result.index == 1) { + cards = event.cards.filter(function (i) { + return lib.filter.cardDiscardable(i, player, "olsujian"); }); - if(cards.length){ - event.num=cards.length; + if (cards.length) { + event.num = cards.length; player.discard(cards); - event.cards=cards; - } - else event.finish(); - } - else event.goto(5); - 'step 3' - if(game.hasPlayer(function(current){ - return current!=player&¤t.countDiscardableCards(player,'he')>0; - })){ - player.chooseTarget(true,'弃置一名其他角色的至多'+get.cnNumber(num)+'张牌',function(card,player,current){ - return current!=player&¤t.countDiscardableCards(player,'he')>0; - }).set('ai',function(current){ - var att=get.attitude(player,current); - if(current.countDiscardableCards(player,'he',function(i){ - if(att>0) return get.value(i,current)>=4; - return get.value(i,current)<=0; - })>=num) return 4*get.effect(current,{name:'guohe_copy2'},player,player); - return get.effect(current,{name:'guohe_copy2'},player,player); - }); - } - else event.finish(); - 'step 4' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,true,[1,num]); + event.cards = cards; + } else event.finish(); + } else event.goto(5); + "step 3"; + if ( + game.hasPlayer(function (current) { + return current != player && current.countDiscardableCards(player, "he") > 0; + }) + ) { + player + .chooseTarget( + true, + "弃置一名其他角色的至多" + get.cnNumber(num) + "张牌", + function (card, player, current) { + return ( + current != player && current.countDiscardableCards(player, "he") > 0 + ); + } + ) + .set("ai", function (current) { + var att = get.attitude(player, current); + if ( + current.countDiscardableCards(player, "he", function (i) { + if (att > 0) return get.value(i, current) >= 4; + return get.value(i, current) <= 0; + }) >= num + ) + return 4 * get.effect(current, { name: "guohe_copy2" }, player, player); + return get.effect(current, { name: "guohe_copy2" }, player, player); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, true, [1, num]); } event.finish(); - 'step 5' - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 6' + "step 5"; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + event.given_map = {}; + "step 6"; player.chooseCardTarget({ - filterCard:function(card){ - return card.hasGaintag('olsujian'); + filterCard: function (card) { + return card.hasGaintag("olsujian"); }, - filterTarget:lib.filter.notMe, - selectCard:[1,cards.length], - forced:true, - prompt:'请选择要分配的卡牌和目标', - ai1:function(card){ - if(!ui.selected.cards.length) return 1; + filterTarget: lib.filter.notMe, + selectCard: [1, cards.length], + forced: true, + prompt: "请选择要分配的卡牌和目标", + ai1: function (card) { + if (!ui.selected.cards.length) return 1; return 0; }, - ai2:function(target){ - var player=_status.event.player,card=ui.selected.cards[0]; - var val=target.getUseValue(card); - if(val>0) return val*get.attitude(player,target)*2; - return get.value(card,target)*get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player, + card = ui.selected.cards[0]; + var val = target.getUseValue(card); + if (val > 0) return val * get.attitude(player, target) * 2; + return get.value(card, target) * get.attitude(player, target); }, }); - 'step 7' - if(result.bool){ - var res=result.cards,target=result.targets[0].playerid; - player.removeGaintag('olsujian',res); - player.addGaintag(res,'olsujian_given'); + "step 7"; + if (result.bool) { + var res = result.cards, + target = result.targets[0].playerid; + player.removeGaintag("olsujian", res); + player.addGaintag(res, "olsujian_given"); cards.removeArray(res); - if(!event.given_map[target]) event.given_map[target]=[]; + if (!event.given_map[target]) event.given_map[target] = []; event.given_map[target].addArray(res); - if(cards.length) event.goto(6); + if (cards.length) event.goto(6); + } else event.finish(); + "step 8"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - else event.finish(); - 'step 8' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - } - var map=[],cards=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - map.push([source,event.given_map[i]]); + var map = [], + cards = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + map.push([source, event.given_map[i]]); cards.addArray(event.given_map[i]); } - if(map.length) game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); - 'step 9' - event.cards=[]; + if (map.length) + game.loseAsync({ + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); + "step 9"; + event.cards = []; }, - update:function(player){ - player.removeGaintag('olsujian'); - var hs=player.getCards('h'); - player.getHistory('gain',function(evt){ + update: function (player) { + player.removeGaintag("olsujian"); + var hs = player.getCards("h"); + player.getHistory("gain", function (evt) { hs.removeArray(evt.cards); }); - if(hs.length) player.addGaintag(hs,'olsujian'); + if (hs.length) player.addGaintag(hs, "olsujian"); return hs; }, - group:'olsujian_sync', - subSkill:{ - sync:{ - trigger:{player:['phaseBeginStart','gainBegin']}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(event.name=='gain') return (player==_status.currentPhase)&&(event.getParent('olsujian').player!=player); + group: "olsujian_sync", + subSkill: { + sync: { + trigger: { player: ["phaseBeginStart", "gainBegin"] }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if (event.name == "gain") + return ( + player == _status.currentPhase && + event.getParent("olsujian").player != player + ); return true; }, - content:function(){ + content: function () { lib.skill.olsujian.update(player); }, }, }, }, //卞夫人 - fuwei:{ - audio:'wanwei', - trigger:{ - player:'loseAfter', - global:'gainAfter', + fuwei: { + audio: "wanwei", + trigger: { + player: "loseAfter", + global: "gainAfter", }, - filter:function(event,player){ - var evt=event; - if(event.name=='lose'){ - if(event.type!='discard') return false; - evt=event.getParent(); + filter: function (event, player) { + var evt = event; + if (event.name == "lose") { + if (event.type != "discard") return false; + evt = event.getParent(); } - if(evt[event.name=='gain'?'bySelf':'notBySelf']!=true) return false; - var evtx=event.getl(player); - return evtx&&evtx.cards2&&evtx.cards2.length>0; + if (evt[event.name == "gain" ? "bySelf" : "notBySelf"] != true) return false; + var evtx = event.getl(player); + return evtx && evtx.cards2 && evtx.cards2.length > 0; }, - prompt2:function(event,player){ - var evt=event.getl(player),origins=evt.cards2.map(function(i){ - return get.name(i,evt.hs.includes(i)?player:false); - }); - return '从牌堆中获得'+get.translation(origins)+';若没有则改为摸一张牌'; - }, - usable:1, - content:function(){ - var num=0,cards=[],evt=trigger.getl(player),origins=evt.cards2.map(function(i){ - return get.name(i,evt.hs.includes(i)?player:false); - }); - for(var i of origins){ - var card=get.cardPile2(function(card){ - return card.name==i&&!cards.includes(card); + prompt2: function (event, player) { + var evt = event.getl(player), + origins = evt.cards2.map(function (i) { + return get.name(i, evt.hs.includes(i) ? player : false); }); - if(card) cards.push(card); + return "从牌堆中获得" + get.translation(origins) + ";若没有则改为摸一张牌"; + }, + usable: 1, + content: function () { + var num = 0, + cards = [], + evt = trigger.getl(player), + origins = evt.cards2.map(function (i) { + return get.name(i, evt.hs.includes(i) ? player : false); + }); + for (var i of origins) { + var card = get.cardPile2(function (card) { + return card.name == i && !cards.includes(card); + }); + if (card) cards.push(card); else num++; } - if(cards.length) player.gain(cards,'gain2'); - if(num) player.draw(num); + if (cards.length) player.gain(cards, "gain2"); + if (num) player.draw(num); }, }, - yuejian:{ - audio:2, - usable:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return player!=event.player&&event.targets&&event.targets.includes(player)&&player.countCards('h')>0; + yuejian: { + audio: 2, + usable: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + player != event.player && + event.targets && + event.targets.includes(player) && + player.countCards("h") > 0 + ); }, - prompt2:function(event,player){ - var suit=get.suit(event.card),hs=player.getCards('h'),cards=event.cards.filterInD(); - if(!lib.suit.includes(suit)||!cards.length){ - return '展示所有手牌,然后无事发生'; + prompt2: function (event, player) { + var suit = get.suit(event.card), + hs = player.getCards("h"), + cards = event.cards.filterInD(); + if (!lib.suit.includes(suit) || !cards.length) { + return "展示所有手牌,然后无事发生"; } - for(var i of hs){ - if(get.suit(i)==suit){ - return '展示所有手牌,然后无事发生'; + for (var i of hs) { + if (get.suit(i) == suit) { + return "展示所有手牌,然后无事发生"; } } - return '展示所有手牌,然后获得'+get.translation(cards)+''; + return ( + '展示所有手牌,然后获得' + get.translation(cards) + "" + ); }, - check:function(event,player){ - var suit=get.suit(event.card),hs=player.getCards('h'),cards=event.cards.filterInD(); - if(!lib.suit.includes(suit)||!cards.length){ + check: function (event, player) { + var suit = get.suit(event.card), + hs = player.getCards("h"), + cards = event.cards.filterInD(); + if (!lib.suit.includes(suit) || !cards.length) { return false; } - for(var i of hs){ - if(get.suit(i)==suit){ + for (var i of hs) { + if (get.suit(i) == suit) { return false; } } return true; }, - content:function(){ - 'step 0' - player.showHandcards(get.translation(player)+'发动了【约俭】'); - var suit=get.suit(trigger.card),hs=player.getCards('h'); - if(!lib.suit.includes(suit)){event.finish();return;} - for(var i of hs){ - if(get.suit(i)==suit){ + content: function () { + "step 0"; + player.showHandcards(get.translation(player) + "发动了【约俭】"); + var suit = get.suit(trigger.card), + hs = player.getCards("h"); + if (!lib.suit.includes(suit)) { + event.finish(); + return; + } + for (var i of hs) { + if (get.suit(i) == suit) { event.finish(); return; } } - 'step 1' - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2'); + "step 1"; + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2"); }, }, //杜袭 - quxi:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'water', - filter:function(event,player){ - if(player.isTurnedOver()) return false; - var list=game.filterPlayer((target)=>target!=player&&!target.hasMark('quxi_gain')&&!target.hasMark('quxi_lose')); - if(list.length<2) return false; - var nf=list[0].countCards('h'); - for(var i=1;i + target != player && !target.hasMark("quxi_gain") && !target.hasMark("quxi_lose") + ); + if (list.length < 2) return false; + var nf = list[0].countCards("h"); + for (var i = 1; i < list.length; i++) { + if (list[i].countCards("h") != nf) return true; } return false; }, - content:function(){ - 'step 0' - player.chooseTarget(2,get.prompt('quxi'),'选择两名手牌数不同的其他角色。你将翻至背面,令这两名角色中手牌数较少的角色获得另一名角色的一张牌并获得一枚“丰”,另一名角色获得一枚“歉”。',function(card,player,target){ - if(player==target||target.hasMark('quxi_gain')||target.hasMark('quxi_lose')) return false; - if(!ui.selected.targets.length) return true; - return target.countCards('h')!=ui.selected.targets[0].countCards('h'); - }).set('complexTarget',true).set('ai',function(target){ - if(!ui.selected.targets.length){ - var player=_status.event.player,hs=target.countCards('h'); - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target&¤t.countCards('h')>hs&&!current.hasMark('quxi_gain')&&!current.hasMark('quxi_lose'); - })) return get.attitude(player,target)/(Math.sqrt(1+target.countCards('h'))); + content: function () { + "step 0"; + player + .chooseTarget( + 2, + get.prompt("quxi"), + "选择两名手牌数不同的其他角色。你将翻至背面,令这两名角色中手牌数较少的角色获得另一名角色的一张牌并获得一枚“丰”,另一名角色获得一枚“歉”。", + function (card, player, target) { + if ( + player == target || + target.hasMark("quxi_gain") || + target.hasMark("quxi_lose") + ) + return false; + if (!ui.selected.targets.length) return true; + return target.countCards("h") != ui.selected.targets[0].countCards("h"); + } + ) + .set("complexTarget", true) + .set("ai", function (target) { + if (!ui.selected.targets.length) { + var player = _status.event.player, + hs = target.countCards("h"); + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + current.countCards("h") > hs && + !current.hasMark("quxi_gain") && + !current.hasMark("quxi_lose") + ); + }) + ) + return ( + get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")) + ); + return 0; + } + if (target.countCards("h") > ui.selected.targets[0].countCards("h")) + return -get.attitude(_status.event.player, target); return 0; - } - if(target.countCards('h')>ui.selected.targets[0].countCards('h')) return -get.attitude(_status.event.player,target); - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('quxi',result.targets); - player.awakenSkill('quxi'); - player.skip('phaseDiscard'); - if(result.targets[0].countCards('h')>result.targets[1].countCards('h')) result.targets.reverse(); - event.gainner=result.targets[0]; - event.giver=result.targets[1]; + }); + "step 1"; + if (result.bool) { + player.logSkill("quxi", result.targets); + player.awakenSkill("quxi"); + player.skip("phaseDiscard"); + if (result.targets[0].countCards("h") > result.targets[1].countCards("h")) + result.targets.reverse(); + event.gainner = result.targets[0]; + event.giver = result.targets[1]; player.turnOver(); - } - else event.finish(); - 'step 2' - event.gainner.gainPlayerCard(event.giver,true,'he'); - 'step 3' - player.addSkill('quxi_effect'); - event.gainner.addMark('quxi_gain',1); - event.giver.addMark('quxi_lose',1); + } else event.finish(); + "step 2"; + event.gainner.gainPlayerCard(event.giver, true, "he"); + "step 3"; + player.addSkill("quxi_effect"); + event.gainner.addMark("quxi_gain", 1); + event.giver.addMark("quxi_lose", 1); }, - subSkill:{ - effect:{ - global:'quxi_gainlose', - trigger:{global:['roundStart','die']}, - charlotte:true, - direct:true, - filter:function(event,player){ - if(event.name=='die') return event.player.countMark('quxi_gain')>0||event.player.countMark('quxi_lose')>0; - return game.hasPlayer(function(target){ - return target!=player&&(target.countMark('quxi_gain')>0||target.countMark('quxi_lose')>0) + subSkill: { + effect: { + global: "quxi_gainlose", + trigger: { global: ["roundStart", "die"] }, + charlotte: true, + direct: true, + filter: function (event, player) { + if (event.name == "die") + return ( + event.player.countMark("quxi_gain") > 0 || + event.player.countMark("quxi_lose") > 0 + ); + return game.hasPlayer(function (target) { + return ( + target != player && + (target.countMark("quxi_gain") > 0 || target.countMark("quxi_lose") > 0) + ); }); }, - content:function(){ - 'step 0' - if(trigger.name=='die'){ - var gain=trigger.player.countMark('quxi_gain'),lose=trigger.player.countMark('quxi_lose'); - player.chooseTarget('是否令一名角色获得'+get.translation(trigger.player)+'的“'+(gain&&lose?'丰”和“歉':(gain?'丰':'歉'))+'”标记?',function(card,player,target){ - return !target.hasMark('quxi_gain')&&!target.hasMark('quxi_lose'); - }).set('goon',gain-lose).set('ai',function(target){ - var evt=_status.event; - return evt.goon*get.attitude(evt.player,target); - }); - } - else event.goto(2); - 'step 1' - if(result.bool){ - var targets=result.targets; - if(targets.length<2) targets.unshift(trigger.player); - player.logSkill('quxi_effect',targets,false); + content: function () { + "step 0"; + if (trigger.name == "die") { + var gain = trigger.player.countMark("quxi_gain"), + lose = trigger.player.countMark("quxi_lose"); + player + .chooseTarget( + "是否令一名角色获得" + + get.translation(trigger.player) + + "的“" + + (gain && lose ? "丰”和“歉" : gain ? "丰" : "歉") + + "”标记?", + function (card, player, target) { + return ( + !target.hasMark("quxi_gain") && !target.hasMark("quxi_lose") + ); + } + ) + .set("goon", gain - lose) + .set("ai", function (target) { + var evt = _status.event; + return evt.goon * get.attitude(evt.player, target); + }); + } else event.goto(2); + "step 1"; + if (result.bool) { + var targets = result.targets; + if (targets.length < 2) targets.unshift(trigger.player); + player.logSkill("quxi_effect", targets, false); player.line2(targets); - var gain=targets[0].countMark('quxi_gain'),lose=targets[0].countMark('quxi_lose'); - if(gain){ - targets[0].removeMark('quxi_gain',gain); - targets[1].addMark('quxi_gain',gain); + var gain = targets[0].countMark("quxi_gain"), + lose = targets[0].countMark("quxi_lose"); + if (gain) { + targets[0].removeMark("quxi_gain", gain); + targets[1].addMark("quxi_gain", gain); } - if(lose){ - targets[0].removeMark('quxi_lose',lose); - targets[1].addMark('quxi_lose',lose); + if (lose) { + targets[0].removeMark("quxi_lose", lose); + targets[1].addMark("quxi_lose", lose); } game.delayx(); event.finish(); } - 'step 2' - if(game.hasPlayer(function(target){ - return target.countMark('quxi_gain')>0; - })) player.chooseTarget(2,'是否转移“丰”标记?',function(card,player,target){ - if(ui.selected.targets.length) return (!target.hasMark('quxi_gain')&&!target.hasMark('quxi_lose')); - return target.countMark('quxi_gain')>0; - }).set('complexTarget',true).set('complexSelect',true).set('targetprompt',['移走标记','获得标记']).set('ai',function(target){ - var player=_status.event.player; - if(!ui.selected.targets.length){ - return -get.attitude(player,target); - } - return get.attitude(player,target); - }); + "step 2"; + if ( + game.hasPlayer(function (target) { + return target.countMark("quxi_gain") > 0; + }) + ) + player + .chooseTarget(2, "是否转移“丰”标记?", function (card, player, target) { + if (ui.selected.targets.length) + return ( + !target.hasMark("quxi_gain") && !target.hasMark("quxi_lose") + ); + return target.countMark("quxi_gain") > 0; + }) + .set("complexTarget", true) + .set("complexSelect", true) + .set("targetprompt", ["移走标记", "获得标记"]) + .set("ai", function (target) { + var player = _status.event.player; + if (!ui.selected.targets.length) { + return -get.attitude(player, target); + } + return get.attitude(player, target); + }); else event.goto(4); - 'step 3' - if(result.bool){ - var targets=result.targets; - player.logSkill('quxi_effect',targets,false); + "step 3"; + if (result.bool) { + var targets = result.targets; + player.logSkill("quxi_effect", targets, false); player.line2(targets); - var gain=targets[0].countMark('quxi_gain'); - if(gain){ - targets[0].removeMark('quxi_gain',gain); - targets[1].addMark('quxi_gain',gain); + var gain = targets[0].countMark("quxi_gain"); + if (gain) { + targets[0].removeMark("quxi_gain", gain); + targets[1].addMark("quxi_gain", gain); } game.delayx(); } - 'step 4' - if(game.hasPlayer(function(target){ - return target.countMark('quxi_lose')>0; - })) player.chooseTarget(2,'是否转移“歉”标记?',function(card,player,target){ - if(ui.selected.targets.length) return (!target.hasMark('quxi_gain')&&!target.hasMark('quxi_lose')); - return target.countMark('quxi_lose')>0; - }).set('complexTarget',true).set('complexSelect',true).set('targetprompt',['移走标记','获得标记']).set('ai',function(target){ - var player=_status.event.player; - if(!ui.selected.targets.length){ - return get.attitude(player,target); - } - return -get.attitude(player,target); - }); + "step 4"; + if ( + game.hasPlayer(function (target) { + return target.countMark("quxi_lose") > 0; + }) + ) + player + .chooseTarget(2, "是否转移“歉”标记?", function (card, player, target) { + if (ui.selected.targets.length) + return ( + !target.hasMark("quxi_gain") && !target.hasMark("quxi_lose") + ); + return target.countMark("quxi_lose") > 0; + }) + .set("complexTarget", true) + .set("complexSelect", true) + .set("targetprompt", ["移走标记", "获得标记"]) + .set("ai", function (target) { + var player = _status.event.player; + if (!ui.selected.targets.length) { + return get.attitude(player, target); + } + return -get.attitude(player, target); + }); else event.finish(); - 'step 5' - if(result.bool){ - var targets=result.targets; - player.logSkill('quxi_effect',targets,false); + "step 5"; + if (result.bool) { + var targets = result.targets; + player.logSkill("quxi_effect", targets, false); player.line2(targets); - var gain=targets[0].countMark('quxi_lose'); - if(gain){ - targets[0].removeMark('quxi_lose',gain); - targets[1].addMark('quxi_lose',gain); + var gain = targets[0].countMark("quxi_lose"); + if (gain) { + targets[0].removeMark("quxi_lose", gain); + targets[1].addMark("quxi_lose", gain); } game.delayx(); } }, }, - gainlose:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ - if(event.numFixed) return false; - return player.countMark('quxi_gain')-player.countMark('quxi_lose')!=0; + gainlose: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + filter: function (event, player) { + if (event.numFixed) return false; + return player.countMark("quxi_gain") - player.countMark("quxi_lose") != 0; }, - content:function(){ - trigger.num+=(player.countMark('quxi_gain')-player.countMark('quxi_lose')); + content: function () { + trigger.num += player.countMark("quxi_gain") - player.countMark("quxi_lose"); }, }, - gain:{ - marktext:'丰', - intro:{ - name:'驱徙(丰)', - name2:'丰', - content:'mark', + gain: { + marktext: "丰", + intro: { + name: "驱徙(丰)", + name2: "丰", + content: "mark", }, }, - lose:{ - marktext:'歉', - intro:{ - name:'驱徙(歉)', - name2:'歉', - content:'mark', + lose: { + marktext: "歉", + intro: { + name: "驱徙(歉)", + name2: "歉", + content: "mark", }, }, }, }, - bixiong:{ - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + bixiong: { + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false||event.getParent('phaseDiscard').player!=player) return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length>0; + forced: true, + filter: function (event, player) { + if ( + event.type != "discard" || + event.getlx === false || + event.getParent("phaseDiscard").player != player + ) + return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length > 0; }, - content:function(){ - var cards=[],hs=trigger.getl(player).hs; - for(var i of hs) cards.add(get.suit(i,player)); - player.addTempSkill('bixiong2',{player:'phaseBegin'}); - player.markAuto('bixiong2',cards); + content: function () { + var cards = [], + hs = trigger.getl(player).hs; + for (var i of hs) cards.add(get.suit(i, player)); + player.addTempSkill("bixiong2", { player: "phaseBegin" }); + player.markAuto("bixiong2", cards); }, }, - bixiong2:{ - onremove:true, - mod:{ - targetEnabled:function(card,player,target){ - if(player!==target&&target.getStorage('bixiong2').includes(get.suit(card))) return false; + bixiong2: { + onremove: true, + mod: { + targetEnabled: function (card, player, target) { + if (player !== target && target.getStorage("bixiong2").includes(get.suit(card))) + return false; }, }, - intro:{content:'不能成为其他角色$牌的目标'}, + intro: { content: "不能成为其他角色$牌的目标" }, }, //高干 - juguan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return event.filterCard({ - name:'sha', - },player,event)||event.filterCard({ - name:'juedou', - },player,event); + juguan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + event.filterCard( + { + name: "sha", + }, + player, + event + ) || + event.filterCard( + { + name: "juedou", + }, + player, + event + ) + ); }, - chooseButton:{ - dialog:function(){ - return ui.create.dialog('拒关',[['sha','juedou'],'vcard']); + chooseButton: { + dialog: function () { + return ui.create.dialog("拒关", [["sha", "juedou"], "vcard"]); }, - filter:function(button,player){ - var evt=_status.event.getParent(); - return evt.filterCard({ - name:button.link[2], - },player,evt); + filter: function (button, player) { + var evt = _status.event.getParent(); + return evt.filterCard( + { + name: button.link[2], + }, + player, + evt + ); }, - check:function(button){ - return _status.event.player.getUseValue({ - name:button.link[2], - })*(button.link[2]=='juedou'?3:1); + check: function (button) { + return ( + _status.event.player.getUseValue({ + name: button.link[2], + }) * (button.link[2] == "juedou" ? 3 : 1) + ); }, - backup:function(links){ + backup: function (links) { return { - audio:'juguan', - viewAs:{name:links[0][2]}, - filterCard:true, - check:function(card){ - return 6-get.value(card); + audio: "juguan", + viewAs: { name: links[0][2] }, + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - position:'hs', - onuse:function(result,player){ - player.addTempSkill('juguan_effect'); + position: "hs", + onuse: function (result, player) { + player.addTempSkill("juguan_effect"); }, - } + }; }, - prompt:function(links){ - return '将一张手牌当做'+get.translation(links[0][2])+'使用'; + prompt: function (links) { + return "将一张手牌当做" + get.translation(links[0][2]) + "使用"; }, }, - ai:{ - order:function(item,player){ - return Math.max(get.order({name:'sha'}),get.order({name:'juedou'}))+0.2; + ai: { + order: function (item, player) { + return Math.max(get.order({ name: "sha" }), get.order({ name: "juedou" })) + 0.2; }, - result:{player:1}, + result: { player: 1 }, }, - subSkill:{ - effect:{ - trigger:{global:'damage'}, - forced:true, - charlotte:true, - firstDo:true, - silent:true, - popup:false, - filter:function(event,player){ - var evt=event.getParent('useCard'); - return event.card&&evt&&event.card==evt.card&&evt.skill=='juguan_backup'&&evt.player==player; + subSkill: { + effect: { + trigger: { global: "damage" }, + forced: true, + charlotte: true, + firstDo: true, + silent: true, + popup: false, + filter: function (event, player) { + var evt = event.getParent("useCard"); + return ( + event.card && + evt && + event.card == evt.card && + evt.skill == "juguan_backup" && + evt.player == player + ); }, - content:function(){ - player.addSkill('juguan_draw'); - player.markAuto('juguan_draw',[trigger.player]); + content: function () { + player.addSkill("juguan_draw"); + player.markAuto("juguan_draw", [trigger.player]); }, }, - draw:{ - audio:'juguan', - trigger:{player:'phaseDrawBegin'}, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - player.removeSkill('juguan_draw'); - if(!trigger.numFixed) trigger.num+=2; + draw: { + audio: "juguan", + trigger: { player: "phaseDrawBegin" }, + forced: true, + charlotte: true, + onremove: true, + content: function () { + player.removeSkill("juguan_draw"); + if (!trigger.numFixed) trigger.num += 2; }, - group:'juguan_clear', - intro:{ - content:'若没有受到$的伤害,则下个摸牌阶段多摸两张牌', + group: "juguan_clear", + intro: { + content: "若没有受到$的伤害,则下个摸牌阶段多摸两张牌", }, }, - clear:{ - trigger:{player:'damage'}, - forced:true, - charlotte:true, - firstDo:true, - silent:true, - popup:false, - filter:function(event,player){ - return player.storage.juguan_draw&&player.storage.juguan_draw.includes(event.source); + clear: { + trigger: { player: "damage" }, + forced: true, + charlotte: true, + firstDo: true, + silent: true, + popup: false, + filter: function (event, player) { + return ( + player.storage.juguan_draw && + player.storage.juguan_draw.includes(event.source) + ); }, - content:function(){ - player.unmarkAuto('juguan_draw',[trigger.source]); - if(!player.storage.juguan_draw||!player.storage.juguan_draw.length) player.removeSkill('juguan_draw'); + content: function () { + player.unmarkAuto("juguan_draw", [trigger.source]); + if (!player.storage.juguan_draw || !player.storage.juguan_draw.length) + player.removeSkill("juguan_draw"); }, }, }, }, //OL鲍三娘 - olwuniang:{ - audio:'xinfu_wuniang', - trigger:{player:'useCardAfter'}, - usable:1, - filter:function(event,player){ - return event.card.name=='sha'&&event.targets.length==1&&event.targets[0].isIn(); + olwuniang: { + audio: "xinfu_wuniang", + trigger: { player: "useCardAfter" }, + usable: 1, + filter: function (event, player) { + return event.card.name == "sha" && event.targets.length == 1 && event.targets[0].isIn(); }, - logTarget:'targets', - content:function(){ - 'step 0' - var target=trigger.targets[0]; - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'武娘:是否对'+get.translation(player)+'使用一张杀?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); - 'step 1' - player.addTempSkill('olwuniang2'); - player.addMark('olwuniang2',1,false); + logTarget: "targets", + content: function () { + "step 0"; + var target = trigger.targets[0]; + target + .chooseToUse( + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + "武娘:是否对" + get.translation(player) + "使用一张杀?" + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); + "step 1"; + player.addTempSkill("olwuniang2"); + player.addMark("olwuniang2", 1, false); player.draw(); }, }, - olwuniang2:{ - onremove:true, - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('olwuniang2'); + olwuniang2: { + onremove: true, + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("olwuniang2"); }, }, }, - olxushen:{ - derivation:'olzhennan', - audio:'xinfu_xushen', - trigger:{player:'dying'}, - limited:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - return player.hp<1; + olxushen: { + derivation: "olzhennan", + audio: "xinfu_xushen", + trigger: { player: "dying" }, + limited: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + return player.hp < 1; }, - content:function(){ - 'step 0' - player.awakenSkill('olxushen'); - player.addSkills('olzhennan'); - player.recover(1-player.hp); - 'step 1' - if(!player.isDying()&&!game.hasPlayer(function(current){ - return current.name1=='guansuo'||current.name2=='guansuo'; - })){ - player.chooseTarget(function(card,player,current){ - return current!=player&¤t.hasSex('male'); - },'许身:是否令一名其他男性角色选择是否将其武将牌替换为“关索”?').set('ai',function(target){ - return get.attitude(_status.event.player,target)-4; - }); - } - else event.finish(); - 'step 2' - if(!result.bool){ + content: function () { + "step 0"; + player.awakenSkill("olxushen"); + player.addSkills("olzhennan"); + player.recover(1 - player.hp); + "step 1"; + if ( + !player.isDying() && + !game.hasPlayer(function (current) { + return current.name1 == "guansuo" || current.name2 == "guansuo"; + }) + ) { + player + .chooseTarget(function (card, player, current) { + return current != player && current.hasSex("male"); + }, "许身:是否令一名其他男性角色选择是否将其武将牌替换为“关索”?") + .set("ai", function (target) { + return get.attitude(_status.event.player, target) - 4; + }); + } else event.finish(); + "step 2"; + if (!result.bool) { event.finish(); return; } - var target=result.targets[0]; - event.target=target; - player.line(target,'fire'); - target.chooseBool('许身:是否将自己的一张武将牌替换为“关索”?'); - 'step 3' - if(result.bool){ - if(target.name2!=undefined){ - target.chooseControl(target.name1,target.name2).set('prompt','请选择要更换的武将牌'); - } - else event._result={control:target.name1}; - } - else event.finish(); - 'step 4' - target.reinitCharacter(result.control,'guansuo'); + var target = result.targets[0]; + event.target = target; + player.line(target, "fire"); + target.chooseBool("许身:是否将自己的一张武将牌替换为“关索”?"); + "step 3"; + if (result.bool) { + if (target.name2 != undefined) { + target + .chooseControl(target.name1, target.name2) + .set("prompt", "请选择要更换的武将牌"); + } else event._result = { control: target.name1 }; + } else event.finish(); + "step 4"; + target.reinitCharacter(result.control, "guansuo"); }, }, - olzhennan:{ - audio:'xinfu_zhennan', - enable:'phaseUse', - usable:1, - viewAs:{name:'nanman'}, - filterCard:true, - selectCard:function(){ - if(ui.selected.targets.length) return [ui.selected.targets.length,Math.min(ui.selected.targets.length+1,game.players.length-1)]; - return [1,Infinity]; + olzhennan: { + audio: "xinfu_zhennan", + enable: "phaseUse", + usable: 1, + viewAs: { name: "nanman" }, + filterCard: true, + selectCard: function () { + if (ui.selected.targets.length) + return [ + ui.selected.targets.length, + Math.min(ui.selected.targets.length + 1, game.players.length - 1), + ]; + return [1, Infinity]; }, - check:function(card){ - var player=_status.event.player; - if(game.countPlayer(function(current){ - return current!=player&&player.canUse('nanman',current)&&get.effect(current,{name:'nanman'},player,player)>0; - })<=ui.selected.cards.length) return 0; - return 6-get.value(card); + check: function (card) { + var player = _status.event.player; + if ( + game.countPlayer(function (current) { + return ( + current != player && + player.canUse("nanman", current) && + get.effect(current, { name: "nanman" }, player, player) > 0 + ); + }) <= ui.selected.cards.length + ) + return 0; + return 6 - get.value(card); }, - selectTarget:function(){ + selectTarget: function () { return ui.selected.cards.length; }, - ai:{ - order:2, + ai: { + order: 2, }, - group:'olzhennan2', + group: "olzhennan2", }, - olzhennan2:{ - trigger:{target:'useCardToBefore'}, - forced:true, - locked:false, - audio:'olzhennan', - filter:function(event,player){ - return event.card.name=='nanman'; + olzhennan2: { + trigger: { target: "useCardToBefore" }, + forced: true, + locked: false, + audio: "olzhennan", + filter: function (event, player) { + return event.card.name == "nanman"; }, - content:function(){ + content: function () { trigger.cancel(); }, }, //黄承彦 - guanxu:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.guanxu.filterTarget(null,player,current)); + guanxu: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => lib.skill.guanxu.filterTarget(null, player, current)); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - var cards=get.cards(5); - for(var i=cards.length-1;i>=0;i--){ - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); + content: function () { + "step 0"; + var cards = get.cards(5); + for (var i = cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); } game.updateRoundNumber(); - var hs=target.getCards('h'); - var dialog=['观虚:选择要操作的牌','
              '+get.translation(target)+'的手牌
              ',hs,'
              牌堆顶
              ',cards]; - player.chooseButton(dialog,2).set('filterButton',function(button){ - if(ui.selected.buttons.length) return get.position(button.link)!=get.position(ui.selected.buttons[0].link); - return true; - }).set('cards1',hs).set('cards2',cards).set('ai',function(button){ - var card=button.link,cards1=_status.event.cards1.slice(0); - var cards2=_status.event.cards2.slice(0),target=_status.event.getParent().target; - if(!ui.selected.buttons.length){ - if(!cards1.includes(card)) return 0; - cards1.remove(card); - var suits=cards2.map(function(i){ - return get.suit(i,target); - }); - for(var i of lib.suit){ - var num=cards1.filter(function(c){ - return get.suit(c,target)==i; - }).length; - if(num>2||(num>1&&suits.includes(i))) return 20+get.value(card); + var hs = target.getCards("h"); + var dialog = [ + "观虚:选择要操作的牌", + '
              ' + get.translation(target) + "的手牌
              ", + hs, + '
              牌堆顶
              ', + cards, + ]; + player + .chooseButton(dialog, 2) + .set("filterButton", function (button) { + if (ui.selected.buttons.length) + return get.position(button.link) != get.position(ui.selected.buttons[0].link); + return true; + }) + .set("cards1", hs) + .set("cards2", cards) + .set("ai", function (button) { + var card = button.link, + cards1 = _status.event.cards1.slice(0); + var cards2 = _status.event.cards2.slice(0), + target = _status.event.getParent().target; + if (!ui.selected.buttons.length) { + if (!cards1.includes(card)) return 0; + cards1.remove(card); + var suits = cards2.map(function (i) { + return get.suit(i, target); + }); + for (var i of lib.suit) { + var num = cards1.filter(function (c) { + return get.suit(c, target) == i; + }).length; + if (num > 2 || (num > 1 && suits.includes(i))) + return 20 + get.value(card); + } + return get.value(card); + } + cards1.remove(ui.selected.buttons[0].link); + cards1.push(card); + for (var i of lib.suit) { + if ( + cards1.filter(function (c) { + return get.suit(c, target) == i; + }).length > 2 + ) + return 20 - get.value(card); + return get.value(ui.selected.buttons[0].link) - get.value(card); } - return get.value(card); - } - cards1.remove(ui.selected.buttons[0].link); - cards1.push(card); - for(var i of lib.suit){ - if(cards1.filter(function(c){ - return get.suit(c,target)==i; - }).length>2) return 20-get.value(card); - return get.value(ui.selected.buttons[0].link)-get.value(card); - } - }); - 'step 1' - if(result.bool){ - var cards=result.links; - if(get.position(cards[0])!='h') cards.reverse(); - var next=target.lose(cards[0],ui.cardPile); - next.insert_index_card=cards[1]; - next.insert_index=function(event){ - return event.insert_index_card; - } - target.gain(cards[1],'draw'); - } - else event.finish(); - 'step 2' - game.updateRoundNumber(); - var suits=[],map={},hs=target.getCards('h'); - if(hs.length){ - for(var i of hs){ - if(!lib.filter.canBeDiscarded(i,player,target,'guanxu')) continue; - var suit=get.suit(i,target); - if(!map[suit]) map[suit]=1; - else map[suit]++; - if(map[suit]>2) suits.add(suit); - } - var next=player.discardPlayerCard(target,3,'visible','h'); - next.set('suits',suits); - next.set('filterButton',function(button){ - var suit=get.suit(button.link); - if(!ui.selected.buttons.length) return _status.event.suits.includes(suit); - return suit==get.suit(ui.selected.buttons[0].link) }); - if(suits.length) next.set('forced',true); + "step 1"; + if (result.bool) { + var cards = result.links; + if (get.position(cards[0]) != "h") cards.reverse(); + var next = target.lose(cards[0], ui.cardPile); + next.insert_index_card = cards[1]; + next.insert_index = function (event) { + return event.insert_index_card; + }; + target.gain(cards[1], "draw"); + } else event.finish(); + "step 2"; + game.updateRoundNumber(); + var suits = [], + map = {}, + hs = target.getCards("h"); + if (hs.length) { + for (var i of hs) { + if (!lib.filter.canBeDiscarded(i, player, target, "guanxu")) continue; + var suit = get.suit(i, target); + if (!map[suit]) map[suit] = 1; + else map[suit]++; + if (map[suit] > 2) suits.add(suit); + } + var next = player.discardPlayerCard(target, 3, "visible", "h"); + next.set("suits", suits); + next.set("filterButton", function (button) { + var suit = get.suit(button.link); + if (!ui.selected.buttons.length) return _status.event.suits.includes(suit); + return suit == get.suit(ui.selected.buttons[0].link); + }); + if (suits.length) next.set("forced", true); } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(target.countCards('h')>3) return -5; - if(target.countCards('h')==3) return -3; + ai: { + order: 9, + result: { + target: function (player, target) { + if (target.countCards("h") > 3) return -5; + if (target.countCards("h") == 3) return -3; return -0.5; }, }, }, }, - yashi:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - if(event.source&&event.source.isIn()) return true; - return game.hasPlayer((current)=>lib.skill.guanxu.filterTarget(null,player,current)); + yashi: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + if (event.source && event.source.isIn()) return true; + return game.hasPlayer((current) => lib.skill.guanxu.filterTarget(null, player, current)); }, - content:function(){ - 'step 0' - event.addIndex=0; - var choiceList=[]; - if(trigger.source&&trigger.source.isIn()){ - choiceList.push('令'+get.translation(trigger.source)+'的所有非锁定技失效'); - } - else event.addIndex++; - if(game.hasPlayer((current)=>lib.skill.guanxu.filterTarget(null,player,current))) choiceList.push('发动一次〖观虚〗'); - player.chooseControl('cancel2').set('prompt',get.prompt('yashi')).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,source=_status.event.getTrigger().source,index=_status.event.getParent().addIndex; - if(game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>3&&get.attitude(player,current)<0; - })) return 1-index; - if(source&&source.isIn()&&get.attitude(player,source)<0&&!source.hasSkill('fengyin')) return 0; - if(game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0&&get.attitude(player,current)<0; - })) return 1-index; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.index+event.addIndex==0){ - var target=trigger.source; - player.logSkill('yashi',target); - //target.removeSkill('fengyin'); - target.addTempSkill('fengyin',{player:'phaseBegin'}); - event.finish(); - } - else player.chooseTarget(true,'请选择〖观虚〗的目标',lib.skill.guanxu.filterTarget).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,'guanxu',player,player); + content: function () { + "step 0"; + event.addIndex = 0; + var choiceList = []; + if (trigger.source && trigger.source.isIn()) { + choiceList.push("令" + get.translation(trigger.source) + "的所有非锁定技失效"); + } else event.addIndex++; + if (game.hasPlayer((current) => lib.skill.guanxu.filterTarget(null, player, current))) + choiceList.push("发动一次〖观虚〗"); + player + .chooseControl("cancel2") + .set("prompt", get.prompt("yashi")) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + source = _status.event.getTrigger().source, + index = _status.event.getParent().addIndex; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("h") > 3 && + get.attitude(player, current) < 0 + ); + }) + ) + return 1 - index; + if ( + source && + source.isIn() && + get.attitude(player, source) < 0 && + !source.hasSkill("fengyin") + ) + return 0; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("h") > 0 && + get.attitude(player, current) < 0 + ); + }) + ) + return 1 - index; + return "cancel2"; }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('yashi',target); - var next=game.createEvent('yashi_guanxu'); - next.player=player; - next.target=target; + "step 1"; + if (result.control != "cancel2") { + if (result.index + event.addIndex == 0) { + var target = trigger.source; + player.logSkill("yashi", target); + //target.removeSkill('fengyin'); + target.addTempSkill("fengyin", { player: "phaseBegin" }); + event.finish(); + } else + player + .chooseTarget(true, "请选择〖观虚〗的目标", lib.skill.guanxu.filterTarget) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, "guanxu", player, player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("yashi", target); + var next = game.createEvent("yashi_guanxu"); + next.player = player; + next.target = target; next.setContent(lib.skill.guanxu.content); } }, }, //黄祖 - wangong:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return get.type(event.card,false)=='basic'; + wangong: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return get.type(event.card, false) == "basic"; }, - content:function(){ - player.addSkill('wangong2'); + content: function () { + player.addSkill("wangong2"); }, }, - wangong2:{ - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - charlotte:true, - content:function(){ - player.removeSkill('wangong2'); - if(trigger.card.name=='sha') trigger.baseDamage++; + wangong2: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + charlotte: true, + content: function () { + player.removeSkill("wangong2"); + if (trigger.card.name == "sha") trigger.baseDamage++; }, - mod:{ - cardUsable:function(card){ - if(card.name=='sha') return Infinity; + mod: { + cardUsable: function (card) { + if (card.name == "sha") return Infinity; }, - targetInRange:function(card){ - if(card.name=='sha') return true; + targetInRange: function (card) { + if (card.name == "sha") return true; }, }, - mark:true, - intro:{ - content:'使用【杀】无距离和次数限制且伤害+1', + mark: true, + intro: { + content: "使用【杀】无距离和次数限制且伤害+1", }, }, //潘淑 - weiyi:{ - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(player.getStorage('weiyi').includes(event.player)||!event.player.isIn()) return false; - return event.player.hp>=player.hp||event.player.isDamaged(); + weiyi: { + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (player.getStorage("weiyi").includes(event.player) || !event.player.isIn()) + return false; + return event.player.hp >= player.hp || event.player.isDamaged(); }, - direct:true, - content:function(){ - 'step 0' - var list=[]; - if(trigger.player.hp>=player.hp) list.push('失去体力'); - if(trigger.player.hp<=player.hp&&trigger.player.isDamaged()) list.push('回复体力'); - list.push('cancel2') - player.chooseControl(list).set('prompt',get.prompt2('weiyi',trigger.player)).set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().player; - var att=get.attitude(player,target),eff=get.recoverEffect(target,player,player); - if(target.hp<=player.hp&&target.isDamaged()&&att>2&&eff>0){ - if(player==target){ - var storage=player.getStorage('weiyi'); - if(player.hp>=2&&game.hasPlayer(function(current){ - return current.hp==player.hp+1&&!storage.includes(current)&&get.attitude(player,current)<0; - })) return 'cancel2'; + direct: true, + content: function () { + "step 0"; + var list = []; + if (trigger.player.hp >= player.hp) list.push("失去体力"); + if (trigger.player.hp <= player.hp && trigger.player.isDamaged()) list.push("回复体力"); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt2("weiyi", trigger.player)) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().player; + var att = get.attitude(player, target), + eff = get.recoverEffect(target, player, player); + if (target.hp <= player.hp && target.isDamaged() && att > 2 && eff > 0) { + if (player == target) { + var storage = player.getStorage("weiyi"); + if ( + player.hp >= 2 && + game.hasPlayer(function (current) { + return ( + current.hp == player.hp + 1 && + !storage.includes(current) && + get.attitude(player, current) < 0 + ); + }) + ) + return "cancel2"; + } + return "回复体力"; } - return '回复体力'; - } - if(target.hp>=player.hp&&att<-2&&eff<0) return '失去体力'; - return 'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.player; - player.logSkill('weiyi',target); - player.markAuto('weiyi',[target]); - target[result.control=='失去体力'?'loseHp':'recover'](); + if (target.hp >= player.hp && att < -2 && eff < 0) return "失去体力"; + return "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.player; + player.logSkill("weiyi", target); + player.markAuto("weiyi", [target]); + target[result.control == "失去体力" ? "loseHp" : "recover"](); } }, - onremove:true, - intro:{ - content:'已令$对汝威服', + onremove: true, + intro: { + content: "已令$对汝威服", }, }, - jinzhi:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - if(get.type(name)=='basic'&&lib.inpile.includes(name)&&player.countMark('jinzhi2')=player.countCards('he')) return false; - for(var i of lib.inpile){ - if(get.type(i)=='basic'&&event.filterCard({name:i,isCard:true},player,event)) return true; + filter: function (event, player) { + if ( + event.responded || + event.jinzhi || + player.countMark("jinzhi2") >= player.countCards("he") + ) + return false; + for (var i of lib.inpile) { + if ( + get.type(i) == "basic" && + event.filterCard({ name: i, isCard: true }, player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of lib.inpile){ - if(get.type(i)=='basic'&&event.filterCard({name:i,isCard:true},player,event)){ - list.push(['基本','',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of lib.inpile) { + if ( + get.type(i) == "basic" && + event.filterCard({ name: i, isCard: true }, player, event) + ) { + list.push(["基本", "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } } - return ui.create.dialog('锦织',[list,'vcard'],'hidden') + return ui.create.dialog("锦织", [list, "vcard"], "hidden"); }, - check:function(button){ - if(button.link[2]=='shan') return 3; - var player=_status.event.player; - if(button.link[2]=='jiu'){ - if(player.getUseValue({name:'jiu'})<=0) return 0; - if(player.countCards('h','sha')) return player.getUseValue({name:'jiu'}); + check: function (button) { + if (button.link[2] == "shan") return 3; + var player = _status.event.player; + if (button.link[2] == "jiu") { + if (player.getUseValue({ name: "jiu" }) <= 0) return 0; + if (player.countCards("h", "sha")) return player.getUseValue({ name: "jiu" }); } - return player.getUseValue({name:button.link[2],nature:button.link[3]})/4; + return player.getUseValue({ name: button.link[2], nature: button.link[3] }) / 4; }, - backup:function(links,player){ + backup: function (links, player) { return { - selectCard:player.countMark('jinzhi2')+1, - filterCard:function(card,player){ - if(ui.selected.cards.length){ - if(get.color(card)!=get.color(ui.selected.cards[0])) return false; + selectCard: player.countMark("jinzhi2") + 1, + filterCard: function (card, player) { + if (ui.selected.cards.length) { + if (get.color(card) != get.color(ui.selected.cards[0])) return false; } - return lib.filter.cardDiscardable.apply(this,arguments); + return lib.filter.cardDiscardable.apply(this, arguments); }, - complexCard:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + complexCard: true, + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }, - position:'he', - ignoreMod:true, - check:function(card){ - var player=_status.event.player,color=get.color(card,player); - if(player.countCards('he',{color:color})<=player.countMark('jinzhi2')||(ui.selected.cards.length&&get.color(ui.selected.cards[0],player)!=color)) return -1; - if(lib.skill.jinzhi_backup.viewAs.name=='jiu'&&!player.countCards('h',function(cardx){ - return card!=cardx&&!ui.selected.cards.includes(cardx)&&get.name(cardx,player)=='sha'; - })) return 0; - return Math.min(0.01,6-get.value(card)); + position: "he", + ignoreMod: true, + check: function (card) { + var player = _status.event.player, + color = get.color(card, player); + if ( + player.countCards("he", { color: color }) <= + player.countMark("jinzhi2") || + (ui.selected.cards.length && + get.color(ui.selected.cards[0], player) != color) + ) + return -1; + if ( + lib.skill.jinzhi_backup.viewAs.name == "jiu" && + !player.countCards("h", function (cardx) { + return ( + card != cardx && + !ui.selected.cards.includes(cardx) && + get.name(cardx, player) == "sha" + ); + }) + ) + return 0; + return Math.min(0.01, 6 - get.value(card)); }, - precontent:function(){ - player.logSkill('jinzhi'); - player.addTempSkill('jinzhi2','roundStart'); - player.addMark('jinzhi2',1,false); - var cards=event.result.cards; + precontent: function () { + player.logSkill("jinzhi"); + player.addTempSkill("jinzhi2", "roundStart"); + player.addMark("jinzhi2", 1, false); + var cards = event.result.cards; player.discard(cards); player.draw(); - event.result.card={ - name:event.result.card.name, - nature:event.result.card.nature, - isCard:true, + event.result.card = { + name: event.result.card.name, + nature: event.result.card.nature, + isCard: true, }; - event.result.cards=[]; + event.result.cards = []; delete event.result.skill; - if(cards.length>1){ - var color=get.color(cards[0],player); - for(var i=1;i 1) { + var color = get.color(cards[0], player); + for (var i = 1; i < cards.length; i++) { + if (get.color(cards[i], player) != color) { + var evt = event.getParent(); + evt.set("jinzhi", true); evt.goto(0); return; } } } }, - } + }; }, - prompt:function(links,player){ - var name=links[0][2]; - var nature=links[0][3]; - return '弃置'+get.cnNumber(player.countMark('jinzhi2')+1)+'张颜色相同的牌并摸一张牌,然后视为使用'+(get.translation(nature)||'')+get.translation(name); + prompt: function (links, player) { + var name = links[0][2]; + var nature = links[0][3]; + return ( + "弃置" + + get.cnNumber(player.countMark("jinzhi2") + 1) + + "张颜色相同的牌并摸一张牌,然后视为使用" + + (get.translation(nature) || "") + + get.translation(name) + ); }, }, - ai:{ - order:function(item,player){ - if(_status.event.type=='phase'&&!player.countMark('jinzhi2')&&player.getUseValue({name:'jiu'},null,true)>0&&player.countCards('h','sha')) return get.order({name:'jiu'})+1; + ai: { + order: function (item, player) { + if ( + _status.event.type == "phase" && + !player.countMark("jinzhi2") && + player.getUseValue({ name: "jiu" }, null, true) > 0 && + player.countCards("h", "sha") + ) + return get.order({ name: "jiu" }) + 1; return 1; }, - respondShan:true, - respondSha:true, - skillTagFilter:function(player){ - if(player.countMark('jinzhi2')>=player.countCards('he')) return false; + respondShan: true, + respondSha: true, + skillTagFilter: function (player) { + if (player.countMark("jinzhi2") >= player.countCards("he")) return false; }, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; - } - } - } + }, + }, + }, }, - jinzhi2:{ - onremove:true, - intro:{ - content:'本轮已发动过#次', + jinzhi2: { + onremove: true, + intro: { + content: "本轮已发动过#次", }, }, //宗预 - zyqiao:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - logTarget:'player', - usable:2, - preHidden:true, - filter:function(event,player){ - var source=event.player; - if(source==player) return false; - if(get.mode()=='guozhan'&&source.isFriendOf(player)) return false; - return source.countDiscardableCards(player,'he')>0; + zyqiao: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + logTarget: "player", + usable: 2, + preHidden: true, + filter: function (event, player) { + var source = event.player; + if (source == player) return false; + if (get.mode() == "guozhan" && source.isFriendOf(player)) return false; + return source.countDiscardableCards(player, "he") > 0; }, - check:function(event,player){ - var target=event.player; - if(get.attitude(player,target)>=0) return false; - if(!player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'zyqiao'); - })) return true; - if(player.countCards('he',(card)=>get.value(card,player)<5)) return true; - if(target.countCards('he',(card)=>get.value(card,target)>6)&&player.countCards('he',(card)=>get.value(card,player)<7)) return true; + check: function (event, player) { + var target = event.player; + if (get.attitude(player, target) >= 0) return false; + if ( + !player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "zyqiao"); + }) + ) + return true; + if (player.countCards("he", (card) => get.value(card, player) < 5)) return true; + if ( + target.countCards("he", (card) => get.value(card, target) > 6) && + player.countCards("he", (card) => get.value(card, player) < 7) + ) + return true; return false; }, - content:function(){ - 'step 0' - player.discardPlayerCard(trigger.player,true,'he'); - 'step 1' - if(player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'zyqiao'); - })) player.chooseToDiscard('he',true); + content: function () { + "step 0"; + player.discardPlayerCard(trigger.player, true, "he"); + "step 1"; + if ( + player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "zyqiao"); + }) + ) + player.chooseToDiscard("he", true); }, }, - chengshang:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(!lib.suit.includes(get.suit(event.card,false))||typeof get.number(event.card)!='number') return false; - if(player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length) return false; - var phsu=event.getParent('phaseUse'); - if(!phsu||phsu.player!=player) return false; - if(player.getHistory('gain',function(evt){ - return evt.getParent().name=='chengshang'; - }).length) return false; - for(var i of event.targets){ - if(i!=player&&(get.mode()!='guozhan'||i.isEnemyOf(player))) return true; + chengshang: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if ( + !lib.suit.includes(get.suit(event.card, false)) || + typeof get.number(event.card) != "number" + ) + return false; + if ( + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length + ) + return false; + var phsu = event.getParent("phaseUse"); + if (!phsu || phsu.player != player) return false; + if ( + player.getHistory("gain", function (evt) { + return evt.getParent().name == "chengshang"; + }).length + ) + return false; + for (var i of event.targets) { + if (i != player && (get.mode() != "guozhan" || i.isEnemyOf(player))) return true; } return false; }, - preHidden:true, - content:function(){ - var suit=get.suit(trigger.card); - var number=get.number(trigger.card); - var cards=[]; - for(var i=0;i0; - })){ + if ( + game.hasPlayer(function (current) { + return ( + current != target && + get.distance(player, current) <= 1 && + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { delete player._reduanbingtmp; - return [1,1]; + return [1, 1]; } delete player._reduanbingtmp; } - } - } + }, + }, }, - group:'reduanbing_sha', - subSkill:{ - sha:{ - audio:'duanbing', - audioname:['heqi'], - trigger:{player:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.getParent().directHit.includes(event.target)&&get.distance(player,event.target)<=1; + group: "reduanbing_sha", + subSkill: { + sha: { + audio: "duanbing", + audioname: ["heqi"], + trigger: { player: "useCardToPlayered" }, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !event.getParent().directHit.includes(event.target) && + get.distance(player, event.target) <= 1 + ); }, - logTarget:'target', - content:function(){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + logTarget: "target", + content: function () { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; - } - else{ - map[id].shanRequired=2; + } else { + map[id].shanRequired = 2; } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg.card.name!='sha'||arg.target.countCards('h','shan')>1||get.distance(player,arg.target)>1) return false; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + arg.card.name != "sha" || + arg.target.countCards("h", "shan") > 1 || + get.distance(player, arg.target) > 1 + ) + return false; }, }, }, }, }, - refenxun:{ - audio:'fenxun', - enable:'phaseUse', - usable:1, - position:'he', - filterTarget:function(card,player,target){ - return target!=player; + refenxun: { + audio: "fenxun", + enable: "phaseUse", + usable: 1, + position: "he", + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - player.markAuto('refenxun2',targets); - player.addTempSkill('refenxun2'); + content: function () { + player.markAuto("refenxun2", targets); + player.addTempSkill("refenxun2"); }, - ai:{ - order:6.5, - result:{ - player:function(player,target){ - if(get.distance(player,target)<=1) return 0; - var hs=player.getCards('h','shunshou'); - if(hs.length&&player.canUse(hs[0],target,false)){ + ai: { + order: 6.5, + result: { + player: function (player, target) { + if (get.distance(player, target) <= 1) return 0; + var hs = player.getCards("h", "shunshou"); + if (hs.length && player.canUse(hs[0], target, false)) { return 1; } - var geteff=function(current){ - return player.canUse('sha',current,false,true)&&get.effect(current,{name:'sha'},player,player)>0; - } - if(player.hasSha()&&geteff(target)){ - var num=game.countPlayer(function(current){ - return current!=player&&get.distance(player,current)<=1&&geteff(current); + var geteff = function (current) { + return ( + player.canUse("sha", current, false, true) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }; + if (player.hasSha() && geteff(target)) { + var num = game.countPlayer(function (current) { + return ( + current != player && + get.distance(player, current) <= 1 && + geteff(current) + ); }); - if(num==0){ - if(game.hasPlayer(function(current){ - return player.canUse('sha',current)&&geteff(current)&¤t!=target; - })){ + if (num == 0) { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + geteff(current) && + current != target + ); + }) + ) { return 1; } - } - else if(num==1){ + } else if (num == 1) { return 1; } } return 0; - } - } - } + }, + }, + }, }, - refenxun2:{ - audio:'fenxun', - trigger:{ - player:'phaseJieshuBegin', + refenxun2: { + audio: "fenxun", + trigger: { + player: "phaseJieshuBegin", }, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getHistory('sourceDamage',function(evt){ - return player.storage.refenxun2.includes(evt.player); - }).length==0&&player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'refenxun2'); - })>0; + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + player.getHistory("sourceDamage", function (evt) { + return player.storage.refenxun2.includes(evt.player); + }).length == 0 && + player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "refenxun2"); + }) > 0 + ); }, - content:function(){ - player.chooseToDiscard('he',true); + content: function () { + player.chooseToDiscard("he", true); }, - onremove:true, - intro:{ - content:'到$的距离视为1' + onremove: true, + intro: { + content: "到$的距离视为1", }, - mod:{ - globalFrom:function(from,to){ - if(from.storage.refenxun2.includes(to)){ + mod: { + globalFrom: function (from, to) { + if (from.storage.refenxun2.includes(to)) { return -Infinity; } - } + }, }, }, //蔡阳新技能 - zhuixi:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + zhuixi: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, //新塌顿 - reluanzhan:{ - audio:'luanzhan', - trigger:{ - player:'damageEnd', - source:'damageSource', + reluanzhan: { + audio: "luanzhan", + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - locked:false, - content:function(){ - player.addMark('reluanzhan',1,false); + forced: true, + locked: false, + content: function () { + player.addMark("reluanzhan", 1, false); }, - intro:{content:'mark'}, - ai:{notemp:true}, - group:['reluanzhan_add','reluanzhan_remove'], + intro: { content: "mark" }, + ai: { notemp: true }, + group: ["reluanzhan_add", "reluanzhan_remove"], }, - reluanzhan_add:{ - trigger:{player:'useCard2'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='sha'&&(get.color(event.card)!='black'||get.type(event.card)!='trick')||!player.countMark('reluanzhan')) return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + reluanzhan_add: { + trigger: { player: "useCard2" }, + direct: true, + filter: function (event, player) { + if ( + (event.card.name != "sha" && + (get.color(event.card) != "black" || get.type(event.card) != "trick")) || + !player.countMark("reluanzhan") + ) + return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var num=player.countMark('reluanzhan'); - var prompt2='为'+get.translation(trigger.card)+'增加至多'+get.cnNumber(num)+'个目标' - player.chooseTarget(get.prompt('reluanzhan'),function(card,player,target){ - if(_status.event.targets.includes(target)) return false; - var player=_status.event.player; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - },[1,num]).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var num = player.countMark("reluanzhan"); + var prompt2 = + "为" + get.translation(trigger.card) + "增加至多" + get.cnNumber(num) + "个目标"; + player + .chooseTarget( + get.prompt("reluanzhan"), + function (card, player, target) { + if (_status.event.targets.includes(target)) return false; + var player = _status.event.player; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }, + [1, num] + ) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('reluanzhan',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("reluanzhan", event.targets); trigger.targets.addArray(event.targets); } }, }, - reluanzhan_remove:{ - audio:'luanzhan', - trigger:{player:'useCardToPlayered'}, - forced:true, - locked:false, - filter:function(event,player){ - if(!event.isFirstTarget||(event.card.name!='sha'&&(get.color(event.card)!='black'||get.type(event.card)!='trick'))||!player.countMark('reluanzhan')) return false; - var info=get.info(event.card); - if(info.allowMultiple==false||info.multitarget) return false; - return event.targets.length0) dialog.add([equips,'tdnodes']) - var type=player.storage.youlong?'basic':'trick'; - var list=[]; - for(var name of lib.inpile){ - if(player.storage.youlong2.includes(name)) continue; - if(get.type(name)!=type) continue; - if(event.filterCard({name:name,isCard:true},player,event)){ - list.push([type,'',name]); - if(name=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + if (equips.length > 0) dialog.add([equips, "tdnodes"]); + var type = player.storage.youlong ? "basic" : "trick"; + var list = []; + for (var name of lib.inpile) { + if (player.storage.youlong2.includes(name)) continue; + if (get.type(name) != type) continue; + if (event.filterCard({ name: name, isCard: true }, player, event)) { + list.push([type, "", name]); + if (name == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } } - dialog.add([list,'vcard']); + dialog.add([list, "vcard"]); return dialog; }, - filter:function(button){ - if(ui.selected.buttons.length&&typeof button.link==typeof ui.selected.buttons[0].link) return false; + filter: function (button) { + if ( + ui.selected.buttons.length && + typeof button.link == typeof ui.selected.buttons[0].link + ) + return false; return true; }, - select:2, - check:function(button){ - var player=_status.event.player; - if(typeof button.link=='number'){ - var card=player.getEquip(button.link); - if(card){ - var val=get.value(card); - if(val>0) return 0; - return 5-val; + select: 2, + check: function (button) { + var player = _status.event.player; + if (typeof button.link == "number") { + var card = player.getEquip(button.link); + if (card) { + var val = get.value(card); + if (val > 0) return 0; + return 5 - val; } - switch(button.link){ - case 3:return 4.5; - case 4:return 4.4; - case 5:return 4.3; - case 2:return (3-player.hp)*1.5; - case 1:{ - if(game.hasPlayer(function(current){ - return (get.realAttitude||get.attitude)(player,current)<0&&get.distance(player,current)>1; - })) return 0; + switch (button.link) { + case 3: + return 4.5; + case 4: + return 4.4; + case 5: + return 4.3; + case 2: + return (3 - player.hp) * 1.5; + case 1: { + if ( + game.hasPlayer(function (current) { + return ( + (get.realAttitude || get.attitude)(player, current) < 0 && + get.distance(player, current) > 1 + ); + }) + ) + return 0; return 3.2; } } } - var name=button.link[2]; - var evt=_status.event.getParent(); - if(evt.type=='phase'){ - var card={name:name,nature:button.link[3],isCard:true}; - if(name=='shan') return 2; - if(evt.type=='dying'){ - if(get.attitude(player,evt.dying)<2) return false; - if(name=='jiu') return 2.1; + var name = button.link[2]; + var evt = _status.event.getParent(); + if (evt.type == "phase") { + var card = { name: name, nature: button.link[3], isCard: true }; + if (name == "shan") return 2; + if (evt.type == "dying") { + if (get.attitude(player, evt.dying) < 2) return false; + if (name == "jiu") return 2.1; return 1.9; } return player.getUseValue(card); } return 1; }, - backup:function(links,player){ - if(typeof links[1]=='number') links.reverse(); - var equip=links[0]; - var name=links[1][2]; - var nature=links[1][3]; + backup: function (links, player) { + if (typeof links[1] == "number") links.reverse(); + var equip = links[0]; + var name = links[1][2]; + var nature = links[1][3]; return { - filterCard:function(){return false}, - selectCard:-1, - equip:equip, - viewAs:{ - name:name, - nature:nature, - isCard:true, + filterCard: function () { + return false; }, - popname:true, - precontent:function(){ - player.logSkill('youlong'); + selectCard: -1, + equip: equip, + viewAs: { + name: name, + nature: nature, + isCard: true, + }, + popname: true, + precontent: function () { + player.logSkill("youlong"); player.disableEquip(lib.skill.youlong_backup.equip); delete event.result.skill; - player.addTempSkill('youlong_'+(player.storage.youlong||false),'roundStart'); - player.changeZhuanhuanji('youlong'); + player.addTempSkill( + "youlong_" + (player.storage.youlong || false), + "roundStart" + ); + player.changeZhuanhuanji("youlong"); player.storage.youlong2.add(event.result.card.name); }, - } + }; }, - prompt:function(links,player){ - if(typeof links[1]=='number') links.reverse(); - var equip='equip'+links[0]; - var name=links[1][2]; - var nature=links[1][3]; - return '废除自己的'+get.translation(equip)+'栏,视为使用'+(get.translation(nature)||'')+get.translation(name); + prompt: function (links, player) { + if (typeof links[1] == "number") links.reverse(); + var equip = "equip" + links[0]; + var name = links[1][2]; + var nature = links[1][3]; + return ( + "废除自己的" + + get.translation(equip) + + "栏,视为使用" + + (get.translation(nature) || "") + + get.translation(name) + ); }, }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - if(!player.storage.youlong||player.hasSkill('youlong_true')) return false; - var name=(tag=='respondSha'?'sha':'shan'); + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "respond") return false; + if (!player.storage.youlong || player.hasSkill("youlong_true")) return false; + var name = tag == "respondSha" ? "sha" : "shan"; return !player.storage.youlong2.includes(name); }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0,add=false; - var type=player.storage.youlong?'basic':'trick'; - var list=lib.inpile.filter(name=>get.type(name)==type&&!player.storage.youlong2.includes(name)); - if(list.includes('sha')) add=true; - list=list.map(namex=>{return {name:namex,isCard:true}}); - if(add) lib.inpile_nature.forEach(naturex=>list.push({name:'sha',nature:naturex,isCard:true})); - for(var card of list){ - if(player.getUseValue(card)>0){ - var temp=get.order(card); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0, + add = false; + var type = player.storage.youlong ? "basic" : "trick"; + var list = lib.inpile.filter( + (name) => get.type(name) == type && !player.storage.youlong2.includes(name) + ); + if (list.includes("sha")) add = true; + list = list.map((namex) => { + return { name: namex, isCard: true }; + }); + if (add) + lib.inpile_nature.forEach((naturex) => + list.push({ name: "sha", nature: naturex, isCard: true }) + ); + for (var card of list) { + if (player.getUseValue(card) > 0) { + var temp = get.order(card); + if (temp > max) max = temp; } } - if(max>0) max+=0.3; + if (max > 0) max += 0.3; return max; } return 1; }, - result:{player:1}, + result: { player: 1 }, }, }, - youlong_true:{charlotte:true}, - youlong_false:{charlotte:true}, - luanfeng:{ - audio:2, - audioname:['key_sakuya'], - trigger:{global:'dying'}, - filter:function(event,player){ - return event.player.maxHp>=player.maxHp&&event.player.hp<1; + youlong_true: { charlotte: true }, + youlong_false: { charlotte: true }, + luanfeng: { + audio: 2, + audioname: ["key_sakuya"], + trigger: { global: "dying" }, + filter: function (event, player) { + return event.player.maxHp >= player.maxHp && event.player.hp < 1; }, - limited:true, - skillAnimation:true, - animationColor:'soil', - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)<4) return false; - if(player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,event.player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,event.player); - return savable; - })>=1-event.player.hp) return false; - if(event.player==player||event.player==get.zhu(player)) return true; + limited: true, + skillAnimation: true, + animationColor: "soil", + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) < 4) return false; + if ( + player.countCards("h", function (card) { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + event.player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") savable = savable(card, player, event.player); + return savable; + }) >= + 1 - event.player.hp + ) + return false; + if (event.player == player || event.player == get.zhu(player)) return true; return !player.hasUnknown(); }, - content:function(){ - 'step 0' - player.awakenSkill('luanfeng'); - trigger.player.recover(3-trigger.player.hp); - 'step 1' - var list=[],target=trigger.player; - for(var i=1;i<6;i++){ - for(var j=0;j0) target.enableEquip(list); - if(list.length<6) target.drawTo(6-list.length); - if(target.storage.kotarou_rewrite) target.storage.kotarou_rewrite=[]; - if(player==target) player.storage.youlong2=[]; + if (list.length > 0) target.enableEquip(list); + if (list.length < 6) target.drawTo(6 - list.length); + if (target.storage.kotarou_rewrite) target.storage.kotarou_rewrite = []; + if (player == target) player.storage.youlong2 = []; }, }, //曹爽,韩遂,何进 - xiaoxi:{ - audio:2, - audioname:['machao','hansui','pangde'], - trigger:{ - player:'enterGame', - global:'phaseBefore', + xiaoxi: { + audio: 2, + audioname: ["machao", "hansui", "pangde"], + trigger: { + player: "enterGame", + global: "phaseBefore", }, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - direct:true, - content:function(){ - player.chooseUseTarget('sha',get.prompt('xiaoxi'),'视为使用一张【杀】').logSkill='xiaoxi'; + direct: true, + content: function () { + player.chooseUseTarget("sha", get.prompt("xiaoxi"), "视为使用一张【杀】").logSkill = + "xiaoxi"; }, }, - spmouzhu:{ - enable:'phaseUse', - audio:'mouzhu', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.spmouzhu.filterTarget(null,player,current)); + spmouzhu: { + enable: "phaseUse", + audio: "mouzhu", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => + lib.skill.spmouzhu.filterTarget(null, player, current) + ); }, - filterTarget:function(card,player,target){ - if(!target.countCards('h')) return false; - return player!=target&&(target.hp==player.hp||get.distance(player,target)==1); + filterTarget: function (card, player, target) { + if (!target.countCards("h")) return false; + return player != target && (target.hp == player.hp || get.distance(player, target) == 1); }, - selectTarget:[1,Infinity], - content:function(){ - 'step 0' - target.chooseCard('h','交给'+get.translation(player)+'一张牌',true); - 'step 1' - if(result.bool) target.give(result.cards,player); - 'step 2' - if(player.countCards('h')<=target.countCards('h')){ + selectTarget: [1, Infinity], + content: function () { + "step 0"; + target.chooseCard("h", "交给" + get.translation(player) + "一张牌", true); + "step 1"; + if (result.bool) target.give(result.cards, player); + "step 2"; + if (player.countCards("h") <= target.countCards("h")) { event.finish(); return; } - var list=[]; - if(target.canUse('sha',player,false)) list.push('sha'); - if(target.canUse('juedou',player,false)) list.push('juedou'); - if(!list.length) event.finish(); - else if(list.length==1) event._result={control:list[0]}; - else target.chooseControl(list).set('prompt','对'+get.translation(player)+'使用一张【杀】或【决斗】。').ai=function(){ - return get.effect(player,{name:'sha'},target,target)>=get.effect(player,{name:'juedou'},target,target)?'sha':'juedou'; - }; - 'step 3' - target.useCard({name:result.control,isCard:true},player,'noai'); + var list = []; + if (target.canUse("sha", player, false)) list.push("sha"); + if (target.canUse("juedou", player, false)) list.push("juedou"); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { control: list[0] }; + else + target + .chooseControl(list) + .set("prompt", "对" + get.translation(player) + "使用一张【杀】或【决斗】。").ai = + function () { + return get.effect(player, { name: "sha" }, target, target) >= + get.effect(player, { name: "juedou" }, target, target) + ? "sha" + : "juedou"; + }; + "step 3"; + target.useCard({ name: result.control, isCard: true }, player, "noai"); }, - ai:{ - order:7, - result:{ - target:-1.2, - player:function(player,target){ - if(ui.selected.targets.length) return 0; - if(target.countCards('h')-player.countCards('h')>1) return 1; - if(get.damageEffect(target,player,player,player)>0) return 1; - if(player.hp>3||player.countCards('h','sha')&&player.countCards('h','shan')) return 0; - if(player.hp>2) return -1.1; + ai: { + order: 7, + result: { + target: -1.2, + player: function (player, target) { + if (ui.selected.targets.length) return 0; + if (target.countCards("h") - player.countCards("h") > 1) return 1; + if (get.damageEffect(target, player, player, player) > 0) return 1; + if ( + player.hp > 3 || + (player.countCards("h", "sha") && player.countCards("h", "shan")) + ) + return 0; + if (player.hp > 2) return -1.1; return -2; }, }, }, }, - spyanhuo:{ - audio:'yanhuo', - trigger:{player:'die'}, - forceDie:true, - skillAnimation:true, - animationColor:'soil', - content:function(){ - player.line(game.players,'green'); - game.addGlobalSkill('spyanhuo_damage'); - if(!_status.yanhuo) _status.yanhuo=0; + spyanhuo: { + audio: "yanhuo", + trigger: { player: "die" }, + forceDie: true, + skillAnimation: true, + animationColor: "soil", + content: function () { + player.line(game.players, "green"); + game.addGlobalSkill("spyanhuo_damage"); + if (!_status.yanhuo) _status.yanhuo = 0; _status.yanhuo++; }, - subSkill:{ - damage:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'; + subSkill: { + damage: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - content:function(){ - trigger.baseDamage+=(_status.yanhuo||0); + content: function () { + trigger.baseDamage += _status.yanhuo || 0; }, }, }, }, - spniluan:{ - enable:'phaseUse', - audio:'niluan', - viewAs:{name:'sha'}, - check:function(card){ - return 5.1-get.value(card); + spniluan: { + enable: "phaseUse", + audio: "niluan", + viewAs: { name: "sha" }, + check: function (card) { + return 5.1 - get.value(card); }, - filterCard:{color:'black'}, - position:'hes', - viewAsFilter:function(player){ - return player.countCards('hes',lib.skill.spniluan.filterCard)>0; + filterCard: { color: "black" }, + position: "hes", + viewAsFilter: function (player) { + return player.countCards("hes", lib.skill.spniluan.filterCard) > 0; }, - group:'spniluan_clear', + group: "spniluan_clear", }, - spniluan_clear:{ - trigger:{player:'useCardAfter'}, - forced:true, - silent:true, - charlotte:true, - filter:function(event,player){ - return event.skill=='spniluan'&&event.addCount!==false&&player.getHistory('sourceDamage',function(card){ - return card.card==event.card; - }).length==0; + spniluan_clear: { + trigger: { player: "useCardAfter" }, + forced: true, + silent: true, + charlotte: true, + filter: function (event, player) { + return ( + event.skill == "spniluan" && + event.addCount !== false && + player.getHistory("sourceDamage", function (card) { + return card.card == event.card; + }).length == 0 + ); }, - content:function(){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + content: function () { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, }, - spweiwu:{ - audio:2, - locked:false, - enable:'phaseUse', - usable:1, - viewAs:{ - name:'shunshou', - storage:{spweiwu:true}, + spweiwu: { + audio: 2, + locked: false, + enable: "phaseUse", + usable: 1, + viewAs: { + name: "shunshou", + storage: { spweiwu: true }, }, - filterCard:{color:'red'}, - position:'hes', - check:function(card){ - return 7-get.value(card); + filterCard: { color: "red" }, + position: "hes", + check: function (card) { + return 7 - get.value(card); }, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.spweiwu) return true; + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.spweiwu) return true; }, }, }, - tuogu:{ - audio:2, - trigger:{global:'die'}, - filter:function(event,player){ - return event.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; - }).length>0; + tuogu: { + audio: 2, + trigger: { global: "die" }, + filter: function (event, player) { + return ( + event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); + }).length > 0 + ); }, - logTarget:'player', - skillAnimation:true, - limited:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.awakenSkill('tuogu'); - var list=trigger.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; + logTarget: "player", + skillAnimation: true, + limited: true, + animationColor: "thunder", + content: function () { + "step 0"; + player.awakenSkill("tuogu"); + var list = trigger.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); }); - if(list.length==1) event._result={control:list[0]}; - else trigger.player.chooseControl(list).set('prompt','选择令'+get.translation(player)+'获得一个技能').set('forceDie',true).set('ai',function(){ - return list.randomGet(); - }); - 'step 1' + if (list.length == 1) event._result = { control: list[0] }; + else + trigger.player + .chooseControl(list) + .set("prompt", "选择令" + get.translation(player) + "获得一个技能") + .set("forceDie", true) + .set("ai", function () { + return list.randomGet(); + }); + "step 1"; player.addSkills(result.control); - game.broadcastAll(function(skill){ - var list=[skill];game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.caoshuang='tuogu'; + game.broadcastAll(function (skill) { + var list = [skill]; + game.expandSkills(list); + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.caoshuang = "tuogu"; } - },result.control); + }, result.control); }, }, - retuogu:{ - audio:'tuogu', - trigger:{global:'die'}, - filter:function(event,player){ - return event.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; - }).length>0; + retuogu: { + audio: "tuogu", + trigger: { global: "die" }, + filter: function (event, player) { + return ( + event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); + }).length > 0 + ); }, - logTarget:'player', - check:function(event,player){ - var list=event.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; + logTarget: "player", + check: function (event, player) { + var list = event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); }); - var negSkill=list.some(function(skill){ - return get.skillRank(skill,'inout')<=0; + var negSkill = list.some(function (skill) { + return get.skillRank(skill, "inout") <= 0; }); - var att=get.sgnAttitude(event.player,player); - if(!player.storage.retuogu){ - if(negSkill&&att<0) return false; + var att = get.sgnAttitude(event.player, player); + if (!player.storage.retuogu) { + if (negSkill && att < 0) return false; return true; } - list.sort(function(a,b){ - return att*(get.skillRank(b,'inout')-get.skillRank(a,'inout')); + list.sort(function (a, b) { + return att * (get.skillRank(b, "inout") - get.skillRank(a, "inout")); })[0]; - return get.skillRank(list[0],'inout')>=get.skillRank(player.storage.retuogu,'inout'); + return get.skillRank(list[0], "inout") >= get.skillRank(player.storage.retuogu, "inout"); }, - content:function(){ - 'step 0' - var list=trigger.player.getStockSkills('仲村由理','天下第一').filter(function(skill){ - var info=get.info(skill); - return info&&!info.juexingji&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte&&!info.limited&&!info.dutySkill; + content: function () { + "step 0"; + var list = trigger.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { + var info = get.info(skill); + return ( + info && + !info.juexingji && + !info.hiddenSkill && + !info.zhuSkill && + !info.charlotte && + !info.limited && + !info.dutySkill + ); }); - if(list.length==1) event._result={control:list[0]}; - else trigger.player.chooseControl(list).set('prompt','选择令'+get.translation(player)+'获得一个技能').set('forceDie',true).set('ai',function(){ - var att=get.sgnAttitude(_status.event.getTrigger().player,player); - if(att==0) return list.randomGet(); - var listx=list.map(function(skill){ - return [skill,get.skillRank(skill,'inout')]; - }).sort(function(a,b){ - return att*(b[1]-a[1]); - }).slice(0,2); - var listx2=[0]; - if(Math.abs(listx[0][1]-listx[1][1])<=0.5&&Math.sign(listx[0][1])==Math.sign(listx[1][1])) listx2.push(1); - return listx[listx2.randomGet()][0]; - }); - 'step 1' - if(player.storage.retuogu) player.removeSkill(player.storage.retuogu); - player.storage.retuogu=result.control; - player.markSkill('retuogu'); + if (list.length == 1) event._result = { control: list[0] }; + else + trigger.player + .chooseControl(list) + .set("prompt", "选择令" + get.translation(player) + "获得一个技能") + .set("forceDie", true) + .set("ai", function () { + var att = get.sgnAttitude(_status.event.getTrigger().player, player); + if (att == 0) return list.randomGet(); + var listx = list + .map(function (skill) { + return [skill, get.skillRank(skill, "inout")]; + }) + .sort(function (a, b) { + return att * (b[1] - a[1]); + }) + .slice(0, 2); + var listx2 = [0]; + if ( + Math.abs(listx[0][1] - listx[1][1]) <= 0.5 && + Math.sign(listx[0][1]) == Math.sign(listx[1][1]) + ) + listx2.push(1); + return listx[listx2.randomGet()][0]; + }); + "step 1"; + if (player.storage.retuogu) player.removeSkill(player.storage.retuogu); + player.storage.retuogu = result.control; + player.markSkill("retuogu"); player.addSkills(result.control); - game.broadcastAll(function(skill){ - var list=[skill]; + game.broadcastAll(function (skill) { + var list = [skill]; game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.caoshuang='tuogu'; + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.caoshuang = "tuogu"; } - },result.control); + }, result.control); }, - mark:true, - intro:{content:'当前托孤技能:$'}, + mark: true, + intro: { content: "当前托孤技能:$" }, }, - shanzhuan:{ - trigger:{source:'damageSource'}, - audio:2, - direct:true, - filter:function(event,player){ - return player!=event.player&&!event.player.isDisabledJudge()&&event.player.countCards('he')&&!event.player.countCards('j',card=>get.type(card.viewAs||card.name)=='delay'); + shanzhuan: { + trigger: { source: "damageSource" }, + audio: 2, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + !event.player.isDisabledJudge() && + event.player.countCards("he") && + !event.player.countCards("j", (card) => get.type(card.viewAs || card.name) == "delay") + ); }, - content:function(){ - 'step 0' - player.choosePlayerCard(trigger.player,'he',get.prompt('shanzhuan',trigger.player)).set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.target)>=0) return 0; - return get.buttonValue(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('shanzhuan',trigger.player); - var card=result.cards[0]; + content: function () { + "step 0"; + player + .choosePlayerCard(trigger.player, "he", get.prompt("shanzhuan", trigger.player)) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.target) >= 0) return 0; + return get.buttonValue(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("shanzhuan", trigger.player); + var card = result.cards[0]; trigger.player.$throw(card); game.delayx(); - if(get.type(card,false)=='delay') trigger.player.addJudge(card); - else trigger.player.addJudge({name:get.color(card,false)=='red'?'lebu':'bingliang'},result.cards); + if (get.type(card, false) == "delay") trigger.player.addJudge(card); + else + trigger.player.addJudge( + { name: get.color(card, false) == "red" ? "lebu" : "bingliang" }, + result.cards + ); } }, - group:'shanzhuan_draw', - subfrequent:['draw'], - subSkill:{ - draw:{ - audio:'shanzhuan', - trigger:{player:'phaseEnd'}, - frequent:true, - prompt:'是否发动【擅专】摸一张牌?', - filter:function(event,player){ - return !player.getHistory('sourceDamage').length; + group: "shanzhuan_draw", + subfrequent: ["draw"], + subSkill: { + draw: { + audio: "shanzhuan", + trigger: { player: "phaseEnd" }, + frequent: true, + prompt: "是否发动【擅专】摸一张牌?", + filter: function (event, player) { + return !player.getHistory("sourceDamage").length; }, - content:function(){ + content: function () { player.draw(); }, }, }, }, - olxingshen:{ - trigger:{player:'damageEnd'}, - frequent:true, - audio:'xingshen', - content:function(){ - 'step 0' - var next=player.draw(); - if(get.isLuckyStar(player)||Math.random()<0.5) next.num=2; - var num=player.countMark('olxingshen'); - if(num<6) player.addMark('olxingshen',Math.min(6-num,player.getDamagedHp()),false) + olxingshen: { + trigger: { player: "damageEnd" }, + frequent: true, + audio: "xingshen", + content: function () { + "step 0"; + var next = player.draw(); + if (get.isLuckyStar(player) || Math.random() < 0.5) next.num = 2; + var num = player.countMark("olxingshen"); + if (num < 6) + player.addMark("olxingshen", Math.min(6 - num, player.getDamagedHp()), false); }, - intro:{ - content:'下一次发动〖严教〗时多展示X张牌', + intro: { + content: "下一次发动〖严教〗时多展示X张牌", }, }, //张道陵 - zlhuji:{ - mod:{ - globalFrom:function(player,target,distance){ - return distance-1; + zlhuji: { + mod: { + globalFrom: function (player, target, distance) { + return distance - 1; }, }, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player!=_status.currentPhase; + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player != _status.currentPhase; }, - content:function(){ - 'step 0' - var func=function(result){ - if(get.color(result)=='red') return 1; + content: function () { + "step 0"; + var func = function (result) { + if (get.color(result) == "red") return 1; return 0; }; - if(get.itemtype(trigger.source)!='player'||!player.canUse('sha',trigger.source,false)) func=function(result){ - return 0; + if ( + get.itemtype(trigger.source) != "player" || + !player.canUse("sha", trigger.source, false) + ) + func = function (result) { + return 0; + }; + else if (get.effect(trigger.source, { name: "sha" }, player, player) < 0) + func = function (result) { + if (get.color(result) == "red") return -1; + return 0; + }; + player.judge(func).judge2 = function (result) { + return result.color == "red" ? true : false; }; - else if(get.effect(trigger.source,{name:'sha'},player,player)<0) func=function(result){ - if(get.color(result)=='red') return -1; - return 0; - }; - player.judge(func).judge2=function(result){ - return result.color=='red'?true:false; - }; - 'step 1' - if(result.color=='red'&&get.itemtype(trigger.source)=='player'&&player.canUse('sha',trigger.source,false)){ - player.useCard({name:'sha',isCard:true},trigger.source,false,'noai'); + "step 1"; + if ( + result.color == "red" && + get.itemtype(trigger.source) == "player" && + player.canUse("sha", trigger.source, false) + ) { + player.useCard({ name: "sha", isCard: true }, trigger.source, false, "noai"); } }, }, - zlshoufu:{ - enable:'phaseUse', - usable:1, - delay:false, - content:function(){ - 'step 0' + zlshoufu: { + enable: "phaseUse", + usable: 1, + delay: false, + content: function () { + "step 0"; player.draw(); - 'step 1' - var filterTarget=function(card,player,target){ - return target!=player&&!target.hasSkill('zlshoufu2'); + "step 1"; + var filterTarget = function (card, player, target) { + return target != player && !target.hasSkill("zlshoufu2"); }; - if(!player.countCards('h')||!game.hasPlayer(function(current){ - return filterTarget(null,player,current); - })) event.finish(); - else player.chooseCardTarget({ - forced:true, - prompt:'将一张手牌作为“箓”置于其他角色的武将牌上', - filterTarget:filterTarget, - filterCard:true, - position:'h', - ai1:function(card){ - if(get.type(card,false)=='equip') return 1-get.value(card); - return 7-get.value(card); - }, - ai2:function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0) return -att; - return -att/get.distance(player,target,'absolute'); - }, - }); - 'step 2' - var target=result.targets[0]; - var cards=result.cards; - target.addToExpansion(cards,player,'give').gaintag.add('zlshoufu2'); - player.line(target,'green'); - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.12); - target.addSkill('zlshoufu2'); - 'step 3' + if ( + !player.countCards("h") || + !game.hasPlayer(function (current) { + return filterTarget(null, player, current); + }) + ) + event.finish(); + else + player.chooseCardTarget({ + forced: true, + prompt: "将一张手牌作为“箓”置于其他角色的武将牌上", + filterTarget: filterTarget, + filterCard: true, + position: "h", + ai1: function (card) { + if (get.type(card, false) == "equip") return 1 - get.value(card); + return 7 - get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) return -att; + return -att / get.distance(player, target, "absolute"); + }, + }); + "step 2"; + var target = result.targets[0]; + var cards = result.cards; + target.addToExpansion(cards, player, "give").gaintag.add("zlshoufu2"); + player.line(target, "green"); + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.12); + target.addSkill("zlshoufu2"); + "step 3"; game.delayx(); }, - ai:{ - notemp:true, - order:1, - result:{ - player:function(player){ - if(game.hasPlayer(function(target){ - return target!=player&&!target.hasSkill('zlshoufu2')&&get.attitude(player,target)<0; - })||!game.hasPlayer(function(target){ - return target!=player&&!target.hasSkill('zlshoufu2')&&get.attitude(player,target)>0; - })) return 1; + ai: { + notemp: true, + order: 1, + result: { + player: function (player) { + if ( + game.hasPlayer(function (target) { + return ( + target != player && + !target.hasSkill("zlshoufu2") && + get.attitude(player, target) < 0 + ); + }) || + !game.hasPlayer(function (target) { + return ( + target != player && + !target.hasSkill("zlshoufu2") && + get.attitude(player, target) > 0 + ); + }) + ) + return 1; return 0; }, }, }, }, - zlshoufu2:{ - marktext:'箓', - intro:{ - content:'expansion', - markcount:'expansion', + zlshoufu2: { + marktext: "箓", + intro: { + content: "expansion", + markcount: "expansion", }, - charlotte:true, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + charlotte: true, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - mod:{ - cardEnabled:function(card,player){ - if(player.getExpansions('zlshoufu2').filter(function(magic){ - return get.type2(magic)==get.type2(card); - }).length) return false; + mod: { + cardEnabled: function (card, player) { + if ( + player.getExpansions("zlshoufu2").filter(function (magic) { + return get.type2(magic) == get.type2(card); + }).length + ) + return false; }, - cardRespondable:function(card,player){ - if(player.getExpansions('zlshoufu2').filter(function(magic){ - return get.type2(magic)==get.type2(card); - }).length) return false; + cardRespondable: function (card, player) { + if ( + player.getExpansions("zlshoufu2").filter(function (magic) { + return get.type2(magic) == get.type2(card); + }).length + ) + return false; }, - cardSavable:function(card,player){ - if(player.getExpansions('zlshoufu2').filter(function(magic){ - return get.type2(magic)==get.type2(card); - }).length) return false; + cardSavable: function (card, player) { + if ( + player.getExpansions("zlshoufu2").filter(function (magic) { + return get.type2(magic) == get.type2(card); + }).length + ) + return false; }, }, - trigger:{ - player:['damageEnd','loseAfter'], - global:'loseAsyncAfter', + trigger: { + player: ["damageEnd", "loseAfter"], + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - var storage=player.getExpansions('zlshoufu2'); - if(!storage.length) return false; - if(event.name=='damage') return true; - if(event.type!='discard'||event.getlx===false||event.getParent('phaseDiscard').player!=player) return false; - var num=0,evt=event.getl(player); - if(!evt||!evt.cards2) return false; - for(var i of evt.cards2){ - if(storage.filter(function(magic){ - return get.type2(magic)==get.type2(i,event.hs.includes(i)?player:false); - }).length) num++; + forced: true, + filter: function (event, player) { + var storage = player.getExpansions("zlshoufu2"); + if (!storage.length) return false; + if (event.name == "damage") return true; + if ( + event.type != "discard" || + event.getlx === false || + event.getParent("phaseDiscard").player != player + ) + return false; + var num = 0, + evt = event.getl(player); + if (!evt || !evt.cards2) return false; + for (var i of evt.cards2) { + if ( + storage.filter(function (magic) { + return ( + get.type2(magic) == get.type2(i, event.hs.includes(i) ? player : false) + ); + }).length + ) + num++; } - return num>1; + return num > 1; }, - content:function(){ - player.removeSkill('zlshoufu2'); + content: function () { + player.removeSkill("zlshoufu2"); }, }, //蔡阳 - yinka:{ - trigger:{player:['drawBegin','judgeBegin']}, - direct:true, - filter:function(){ - return ui.cardPile.childNodes.length>0; + yinka: { + trigger: { player: ["drawBegin", "judgeBegin"] }, + direct: true, + filter: function () { + return ui.cardPile.childNodes.length > 0; }, - content:function(){ - 'step 0' - player.chooseButton(['印卡:请选择要置于牌堆'+(trigger.bottom?'底':'顶')+'的牌(先选择的在上)',Array.from(ui.cardPile.childNodes)],[1,trigger.num||1]); - 'step 1' - if(result.bool){ - while(result.links.length){ - if(trigger.bottom){ - var card=result.links.shift(); + content: function () { + "step 0"; + player.chooseButton( + [ + "印卡:请选择要置于牌堆" + + (trigger.bottom ? "底" : "顶") + + "的牌(先选择的在上)", + Array.from(ui.cardPile.childNodes), + ], + [1, trigger.num || 1] + ); + "step 1"; + if (result.bool) { + while (result.links.length) { + if (trigger.bottom) { + var card = result.links.shift(); ui.cardPile.removeChild(card); ui.cardPile.appendChild(card); - } - else{ - var card=result.links.pop(); + } else { + var card = result.links.pop(); ui.cardPile.removeChild(card); - ui.cardPile.insertBefore(card,ui.cardPile.firstChild) + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); } } } }, - ai:{isLuckyStar:true}, + ai: { isLuckyStar: true }, }, //新王允 - xinlianji:{ - enable:'phaseUse', - audio:'wylianji', - usable:1, - check:function(card){ - return 5-get.value(card); + xinlianji: { + enable: "phaseUse", + audio: "wylianji", + usable: 1, + check: function (card) { + return 5 - get.value(card); }, - filterTarget:function(card,player,target){ - if(ui.selected.targets.length) return true; - return target!=player; + filterTarget: function (card, player, target) { + if (ui.selected.targets.length) return true; + return target != player; }, - filterCard:true, - selectTarget:2, - multitarget:true, - targetprompt:['打人','被打'], - content:function(){ - 'step 0' + filterCard: true, + selectTarget: 2, + multitarget: true, + targetprompt: ["打人", "被打"], + content: function () { + "step 0"; //player.addMark('xinlianji',1,false); - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'&&targets[0].hasUseTarget(card); + var card = get.cardPile2(function (card) { + return get.subtype(card) == "equip1" && targets[0].hasUseTarget(card); }); - if(card){ - if(card.name=='qinggang'&&!lib.inpile.includes('qibaodao')){ + if (card) { + if (card.name == "qinggang" && !lib.inpile.includes("qibaodao")) { card.remove(); - card=game.createCard('qibaodao',card.suit,card.number); + card = game.createCard("qibaodao", card.suit, card.number); } - targets[0].chooseUseTarget(card,true,'nopopup','nothrow'); + targets[0].chooseUseTarget(card, true, "nopopup", "nothrow"); + } else { + player.chat("没有装备牌了吗"); + game.log("但是牌堆里已经没有装备牌了!"); } - else{ - player.chat('没有装备牌了吗'); - game.log('但是牌堆里已经没有装备牌了!'); - } - 'step 1' + "step 1"; game.updateRoundNumber(); - targets[0].chooseToUse('对'+get.translation(targets[1])+'使用一张杀,或将装备区里的武器牌交给一名其他角色', - {name:'sha'}).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',targets[1]).set('addCount',false); - 'step 2' - var cards=targets[0].getEquips(1); - if(!result.bool&&cards.length){ - event.cards=cards; - player.chooseTarget(true,'将'+get.translation(cards)+'交给一名其他角色').set('ai',function(target){ - var card=_status.event.getParent().cards; - return (target.hasSkillTag('nogain')?0:get.attitude(_status.event.player,target))*Math.max(0.1,target.getUseValue(cards[0])); - }); - } - else event.finish(); - 'step 3' - result.targets[0].gain(cards,result.targets[0],'give').giver=player; + targets[0] + .chooseToUse( + "对" + + get.translation(targets[1]) + + "使用一张杀,或将装备区里的武器牌交给一名其他角色", + { name: "sha" } + ) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", targets[1]) + .set("addCount", false); + "step 2"; + var cards = targets[0].getEquips(1); + if (!result.bool && cards.length) { + event.cards = cards; + player + .chooseTarget(true, "将" + get.translation(cards) + "交给一名其他角色") + .set("ai", function (target) { + var card = _status.event.getParent().cards; + return ( + (target.hasSkillTag("nogain") + ? 0 + : get.attitude(_status.event.player, target)) * + Math.max(0.1, target.getUseValue(cards[0])) + ); + }); + } else event.finish(); + "step 3"; + result.targets[0].gain(cards, result.targets[0], "give").giver = player; }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(ui.selected.targets.length){ - var pretarget=ui.selected.targets[0]; - if(pretarget.hasSha()&&pretarget.canUse({name:'sha'},target)) return get.effect(target,{name:'sha'},pretarget,target); + ai: { + order: 4, + result: { + target: function (player, target) { + if (ui.selected.targets.length) { + var pretarget = ui.selected.targets[0]; + if (pretarget.hasSha() && pretarget.canUse({ name: "sha" }, target)) + return get.effect(target, { name: "sha" }, pretarget, target); return Math.random(); } - if(!target.getEquip(1)){ - if(game.hasPlayer(function(current){ - return current!=target&&!current.hasSkillTag('nogain')&&get.attitude(current,target)>0; - })) return 3; + if (!target.getEquip(1)) { + if ( + game.hasPlayer(function (current) { + return ( + current != target && + !current.hasSkillTag("nogain") && + get.attitude(current, target) > 0 + ); + }) + ) + return 3; return -3; } - if(!game.hasPlayer(function(current){ - return current!=target&&!current.hasSkillTag('nogain')&&get.attitude(current,target)>0; - })) return -6; - return 4-get.value(target.getEquip(1)); + if ( + !game.hasPlayer(function (current) { + return ( + current != target && + !current.hasSkillTag("nogain") && + get.attitude(current, target) > 0 + ); + }) + ) + return -6; + return 4 - get.value(target.getEquip(1)); }, }, }, }, - xinmoucheng:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:'moucheng', - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - derivation:'xinjingong', - unique:true, - filter:function(event,player){ - return game.hasPlayer2(function(current){ - return current.getAllHistory('sourceDamage',function(evt){ - if(!evt.card||evt.card.name!='sha'||evt.getParent().type!='card') return false; - var evt2=evt.getParent(4); - return evt2&&evt2.name=='xinlianji'&&evt2.player==player; - }).length>0; + xinmoucheng: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: "moucheng", + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + derivation: "xinjingong", + unique: true, + filter: function (event, player) { + return game.hasPlayer2(function (current) { + return ( + current.getAllHistory("sourceDamage", function (evt) { + if (!evt.card || evt.card.name != "sha" || evt.getParent().type != "card") + return false; + var evt2 = evt.getParent(4); + return evt2 && evt2.name == "xinlianji" && evt2.player == player; + }).length > 0 + ); }); }, - content:function(){ - player.awakenSkill('xinmoucheng'); - player.changeSkills(['xinjingong'],['xinlianji']); + content: function () { + player.awakenSkill("xinmoucheng"); + player.changeSkills(["xinjingong"], ["xinlianji"]); }, }, - xinjingong:{ - audio:'jingong', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return event.xinjingong_list&&player.countCards('hes',function(card){ - return card.name=='sha'||get.type(card)=='equip'; - }); + xinjingong: { + audio: "jingong", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + event.xinjingong_list && + player.countCards("hes", function (card) { + return card.name == "sha" || get.type(card) == "equip"; + }) + ); }, - onChooseToUse:function(event){ - if(!game.online){ - var evt=event.getParent(); - if(evt.name!='phaseUse') return; - if(!evt.xinjingong_list){ - var list=get.inpile('trick').randomGets(2); - if(Math.random()<0.5){ - list.push('wy_meirenji'); + onChooseToUse: function (event) { + if (!game.online) { + var evt = event.getParent(); + if (evt.name != "phaseUse") return; + if (!evt.xinjingong_list) { + var list = get.inpile("trick").randomGets(2); + if (Math.random() < 0.5) { + list.push("wy_meirenji"); + } else { + list.push("wy_xiaolicangdao"); } - else{ - list.push('wy_xiaolicangdao'); - } - evt.xinjingong_list=list; + evt.xinjingong_list = list; } - if(!event.xinjingong_list) event.set('xinjingong_list',evt.xinjingong_list); + if (!event.xinjingong_list) event.set("xinjingong_list", evt.xinjingong_list); } }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of event.xinjingong_list) list.push(['锦囊','',i]); - return ui.create.dialog('矜功',[list,'vcard']); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of event.xinjingong_list) list.push(["锦囊", "", i]); + return ui.create.dialog("矜功", [list, "vcard"]); }, - filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2]}); + check: function (button) { + return _status.event.player.getUseValue({ name: button.link[2] }); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jingong', - popname:true, - position:'hes', - viewAs:{name:links[0][2]}, - check:function(card){ - return 6-get.value(card); + audio: "jingong", + popname: true, + position: "hes", + viewAs: { name: links[0][2] }, + check: function (card) { + return 6 - get.value(card); }, - filterCard:function(card){ - return card.name=='sha'||get.type(card)=='equip'; + filterCard: function (card) { + return card.name == "sha" || get.type(card) == "equip"; }, }; }, - prompt:function(links,player){ - return '将一张【杀】或装备牌当做'+get.translation(links[0][2])+'使用'; - } + prompt: function (links, player) { + return "将一张【杀】或装备牌当做" + get.translation(links[0][2]) + "使用"; + }, + }, + ai: { + order: 2, + result: { + player: 1, + }, }, - ai:{ - order:2, - result:{ - player:1 - } - } }, //孙邵 - bizheng:{ - trigger:{player:'phaseDrawEnd'}, - direct:true, - audio:2, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('bizheng'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player.countCards('h')>player.maxHp) return 0; - var att=get.attitude(player,target); - if(att<=0||target.hasSkillTag('nogain')) return 0; - if(target.maxHp-target.countCards('h')>=2) return att; - return att/2; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('bizheng',target); + bizheng: { + trigger: { player: "phaseDrawEnd" }, + direct: true, + audio: 2, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("bizheng"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + if (player.countCards("h") > player.maxHp) return 0; + var att = get.attitude(player, target); + if (att <= 0 || target.hasSkillTag("nogain")) return 0; + if (target.maxHp - target.countCards("h") >= 2) return att; + return att / 2; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("bizheng", target); target.draw(2); - } - else event.finish(); - 'step 2' - if(player.countCards('h')>player.maxHp) player.chooseToDiscard(2,'he',true); - 'step 3' - if(target.countCards('h')>target.maxHp) target.chooseToDiscard(2,'he',true); + } else event.finish(); + "step 2"; + if (player.countCards("h") > player.maxHp) player.chooseToDiscard(2, "he", true); + "step 3"; + if (target.countCards("h") > target.maxHp) target.chooseToDiscard(2, "he", true); }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - yidian:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - for(var i=0;i0; - })){ - player.chooseControl('cancel2').set('choiceList',[ - '摸两张牌,然后弃置一张牌', - '获得场上的一张牌,然后弃置一张牌', - ]).set('prompt',get.prompt('neifa')).set('ai',function(){ - if(game.hasPlayer(function(current){ - var att=get.attitude(player,current); - if(att==0) return false; - if(att<0) return current.countCards('e',function(card){ - return get.value(card,current)>5; - })>0; - return current.countCards('ej',function(card){ - return get.position(card)=='j'||get.value(card,current)<=0; - })>0; - })) return 1; - return 0; - }); + neifa: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + _status.noclearcountdown = true; + if ( + game.hasPlayer(function (current) { + return current.countGainableCards(player, "ej") > 0; + }) + ) { + player + .chooseControl("cancel2") + .set("choiceList", [ + "摸两张牌,然后弃置一张牌", + "获得场上的一张牌,然后弃置一张牌", + ]) + .set("prompt", get.prompt("neifa")) + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + var att = get.attitude(player, current); + if (att == 0) return false; + if (att < 0) + return ( + current.countCards("e", function (card) { + return get.value(card, current) > 5; + }) > 0 + ); + return ( + current.countCards("ej", function (card) { + return ( + get.position(card) == "j" || get.value(card, current) <= 0 + ); + }) > 0 + ); + }) + ) + return 1; + return 0; + }); + } else { + player.chooseControl("ok", "cancel2").set("prompt", get.prompt2("neifa")); } - else{ - player.chooseControl('ok','cancel2').set('prompt',get.prompt2('neifa')); - } - 'step 1' - if(result.control=='cancel2'){ + "step 1"; + if (result.control == "cancel2") { delete _status.noclearcountdown; - if(!_status.noclearcountdown){ + if (!_status.noclearcountdown) { game.stopCountChoose(); } event.finish(); return; - } - else if(result.index==1){ - player.chooseTarget('请选择一名角色,获得其装备区或判定区内的一张牌',true,function(card,player,target){ - return target.countGainableCards(player,'ej')>0; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0&&target.countCards('ej',function(card){ - return get.position(card)=='j'||get.value(card,target)<=0; - })) return 2*att; - else if(att<0&&target.countCards('e',function(card){ - return get.value(card,target)>5; - })) return -att; - return -1; - }); - } - else{ + } else if (result.index == 1) { + player + .chooseTarget( + "请选择一名角色,获得其装备区或判定区内的一张牌", + true, + function (card, player, target) { + return target.countGainableCards(player, "ej") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if ( + att > 0 && + target.countCards("ej", function (card) { + return get.position(card) == "j" || get.value(card, target) <= 0; + }) + ) + return 2 * att; + else if ( + att < 0 && + target.countCards("e", function (card) { + return get.value(card, target) > 5; + }) + ) + return -att; + return -1; + }); + } else { delete _status.noclearcountdown; - if(!_status.noclearcountdown){ + if (!_status.noclearcountdown) { game.stopCountChoose(); } - player.logSkill('neifa'); + player.logSkill("neifa"); player.draw(2); - event.goto(3) + event.goto(3); } - 'step 2' + "step 2"; delete _status.noclearcountdown; - if(!_status.noclearcountdown){ + if (!_status.noclearcountdown) { game.stopCountChoose(); } - if(result.bool){ - var target=result.targets[0]; - player.logSkill('neifa',target); - player.gainPlayerCard(target,'ej',true); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("neifa", target); + player.gainPlayerCard(target, "ej", true); } - 'step 3' - player.chooseToDiscard(true,'he').set('ai',function(cardx){ - var player=_status.event.player; - var num=0; - var hs=player.getCards('h'); - var muniu=player.getEquip('muniu'); - var subs=[]; - if(muniu&&muniu.cards) hs=hs.concat(muniu.cards); - if(get.type(cardx)=='basic'){ - var shas=hs.filter(function(card){ - return card!=cardx&&get.name(card,player)=='sha'&&player.hasValueTarget(card); + "step 3"; + player.chooseToDiscard(true, "he").set("ai", function (cardx) { + var player = _status.event.player; + var num = 0; + var hs = player.getCards("h"); + var muniu = player.getEquip("muniu"); + var subs = []; + if (muniu && muniu.cards) hs = hs.concat(muniu.cards); + if (get.type(cardx) == "basic") { + var shas = hs.filter(function (card) { + return ( + card != cardx && + get.name(card, player) == "sha" && + player.hasValueTarget(card) + ); }); - var numx=player.countCards('h',function(card){ - return get.type(card,player)!='basic'; + var numx = player.countCards("h", function (card) { + return get.type(card, player) != "basic"; }); - num+=Math.min(numx,Math.max(0,shas.length-player.getCardUsable('sha')))*0.7; - num+=Math.min(player.getCardUsable('sha')+numx,shas.filter(function(card){ - return game.countPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })>1; - }).length)*1.1; - var taos=Math.min(player.maxHp-player.hp,hs.filter(function(card){ - return cardx!=card&&get.name(card,player)=='tao'; - }).length); - num+=taos*player.getDamagedHp()*1.2; + num += + Math.min(numx, Math.max(0, shas.length - player.getCardUsable("sha"))) * 0.7; + num += + Math.min( + player.getCardUsable("sha") + numx, + shas.filter(function (card) { + return ( + game.countPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) > 1 + ); + }).length + ) * 1.1; + var taos = Math.min( + player.maxHp - player.hp, + hs.filter(function (card) { + return cardx != card && get.name(card, player) == "tao"; + }).length + ); + num += taos * player.getDamagedHp() * 1.2; + } else { + var numx = Math.sqrt( + Math.min( + 5, + player.countCards("h", function (card) { + return get.type(card, player) == "basic"; + }) + ) + ); + if (numx) + num += + (numx * + Math.min( + 2, + hs.filter(function (card) { + if ( + card == cardx || + get.type(card) != "equip" || + !player.hasUseTarget(card) + ) + return false; + subs.add(get.subtype(card)); + return true; + }).length + ) * + (2.5 + player.countCards("e"))) / + 2.5; + num += + hs.filter(function (card) { + return ( + card != cardx && + get.type2(card) == "trick" && + player.hasValueTarget(card) + ); + }).length * 0.65; } - else{ - var numx=Math.sqrt(Math.min(5,player.countCards('h',function(card){ - return get.type(card,player)=='basic'; - }))); - if(numx) num+=numx*Math.min(2,hs.filter(function(card){ - if(card==cardx||get.type(card)!='equip'||!player.hasUseTarget(card)) return false; - subs.add(get.subtype(card)); - return true; - }).length)*(2.5+player.countCards('e'))/2.5; - num+=hs.filter(function(card){ - return card!=cardx&&get.type2(card)=='trick'&&player.hasValueTarget(card); - }).length*0.65; - } - if(get.position(cardx)=='e'&&cardx.name!='muniu'&&subs.includes(get.subtype(card))) num+=3; - return num*1.5-get.value(cardx); + if ( + get.position(cardx) == "e" && + cardx.name != "muniu" && + subs.includes(get.subtype(card)) + ) + num += 3; + return num * 1.5 - get.value(cardx); }); - 'step 4' - if(result.bool&&result.cards&&result.cards.length){ - var name=get.type(result.cards[0])=='basic'?'neifa_basic':'neifa_nobasic'; + "step 4"; + if (result.bool && result.cards && result.cards.length) { + var name = get.type(result.cards[0]) == "basic" ? "neifa_basic" : "neifa_nobasic"; player.addTempSkill(name); - var num=Math.min(5,player.countCards('h',function(cardx){ - return (name=='neifa_basic')!=(get.type(cardx,player)=='basic') - })); - if(num>0) player.addMark(name,num,false); - else player.storage[name]=0; + var num = Math.min( + 5, + player.countCards("h", function (cardx) { + return (name == "neifa_basic") != (get.type(cardx, player) == "basic"); + }) + ); + if (num > 0) player.addMark(name, num, false); + else player.storage[name] = 0; } }, - ai:{ - threaten:3, + ai: { + threaten: 3, }, }, - neifa_basic:{ - mark:true, - marktext:'伐', - onremove:true, - intro:{ - name:'内伐 - 基本牌', - content:'本回合内不能使用锦囊牌和装备牌,使用【杀】选择目标时可以额外指定一个目标且使用【杀】的目标次数上限+#。', + neifa_basic: { + mark: true, + marktext: "伐", + onremove: true, + intro: { + name: "内伐 - 基本牌", + content: + "本回合内不能使用锦囊牌和装备牌,使用【杀】选择目标时可以额外指定一个目标且使用【杀】的目标次数上限+#。", }, - mod:{ - cardEnabled:function(card,player){ - if(['trick','equip'].includes(get.type(card,'trick'))) return false; + mod: { + cardEnabled: function (card, player) { + if (["trick", "equip"].includes(get.type(card, "trick"))) return false; }, - cardSavable:function(card,player){ - if(['trick','equip'].includes(get.type(card,'trick'))) return false; + cardSavable: function (card, player) { + if (["trick", "equip"].includes(get.type(card, "trick"))) return false; }, - cardUsable:function(card,player,num){ - if(card.name=='sha'){ - return num+player.countMark('neifa_basic'); + cardUsable: function (card, player, num) { + if (card.name == "sha") { + return num + player.countMark("neifa_basic"); } }, }, - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current); + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('neifa'),'为'+get.translation(trigger.card)+'额外指定一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,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.delayx(); - event.targets=result.targets; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("neifa"), + "为" + get.translation(trigger.card) + "额外指定一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, 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.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - player.logSkill('neifa',event.targets); + "step 2"; + player.logSkill("neifa", event.targets); trigger.targets.addArray(event.targets); }, }, - neifa_nobasic:{ - trigger:{player:'useCard2'}, - direct:true, - mark:true, - marktext:'伐', - onremove:true, - mod:{ - cardEnabled:function(card,player){ - if(get.type(card)=='basic') return false; + neifa_nobasic: { + trigger: { player: "useCard2" }, + direct: true, + mark: true, + marktext: "伐", + onremove: true, + mod: { + cardEnabled: function (card, player) { + if (get.type(card) == "basic") return false; }, - cardSavable:function(card,player){ - if(get.type(card)=='basic') return false; + cardSavable: function (card, player) { + if (get.type(card) == "basic") return false; }, }, - intro:{ - name:'内伐 - 非基本牌', - content:'本回合内不能使用基本牌,使用普通锦囊牌选择目标时可以增加或减少一个目标,且本回合的出牌阶段内前两次使用装备牌时摸#张牌。' + intro: { + name: "内伐 - 非基本牌", + content: + "本回合内不能使用基本牌,使用普通锦囊牌选择目标时可以增加或减少一个目标,且本回合的出牌阶段内前两次使用装备牌时摸#张牌。", }, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(event.targets&&event.targets.length>0) return true; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + if (event.targets && event.targets.length > 0) return true; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加或减少一个目标' - player.chooseTarget(get.prompt('neifa'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return true; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加或减少一个目标"; + player + .chooseTarget(get.prompt("neifa"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return true; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('neifa',event.targets); - if(trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets); + "step 2"; + if (event.targets) { + player.logSkill("neifa", event.targets); + if (trigger.targets.includes(event.targets[0])) + trigger.targets.removeArray(event.targets); else trigger.targets.addArray(event.targets); } }, - group:'neifa_use', - ai:{ - reverseOrder:true, - skillTagFilter:function(player){ - if(player.storage.counttrigger&&player.storage.counttrigger.neifa_use>=2) return false; + group: "neifa_use", + ai: { + reverseOrder: true, + skillTagFilter: function (player) { + if (player.storage.counttrigger && player.storage.counttrigger.neifa_use >= 2) + return false; }, - effect:{ - target:function(card,player,target){ - if((!player.storage.counttrigger||!player.storage.counttrigger.neifa_use||player.storage.counttrigger.neifa_use<2)&&player==target&&get.type(card)=='equip') return [1,3]; + effect: { + target: function (card, player, target) { + if ( + (!player.storage.counttrigger || + !player.storage.counttrigger.neifa_use || + player.storage.counttrigger.neifa_use < 2) && + player == target && + get.type(card) == "equip" + ) + return [1, 3]; }, }, }, }, - neifa_use:{ - audio:'neifa', - usable:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return get.type(event.card)=='equip'&&player.countMark('neifa_nobasic')>0; + neifa_use: { + audio: "neifa", + usable: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return get.type(event.card) == "equip" && player.countMark("neifa_nobasic") > 0; }, - content:function(){ - player.draw(player.countMark('neifa_nobasic')); + content: function () { + player.draw(player.countMark("neifa_nobasic")); }, }, //许靖 - yuxu:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; + yuxu: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; return true; }, - direct:true, - content:function(){ - 'step 0' - var draw=!player.hasMark('yuxu_used'); - if(draw) player.chooseBool(get.prompt2('yuxu')).set('ai',()=>1); + direct: true, + content: function () { + "step 0"; + var draw = !player.hasMark("yuxu_used"); + if (draw) player.chooseBool(get.prompt2("yuxu")).set("ai", () => 1); else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('yuxu'); + "step 1"; + if (result.bool) { + player.logSkill("yuxu"); player.draw(); - player.addMark('yuxu_used',1,false); - player.addTempSkill('yuxu_used','phaseUseAfter'); + player.addMark("yuxu_used", 1, false); + player.addTempSkill("yuxu_used", "phaseUseAfter"); } event.finish(); - 'step 2' - player.logSkill('yuxu'); - player.removeMark('yuxu_used',player.countMark('yuxu_used'),false); - player.chooseToDiscard('he',true); + "step 2"; + player.logSkill("yuxu"); + player.removeMark("yuxu_used", player.countMark("yuxu_used"), false); + player.chooseToDiscard("he", true); + }, + subSkill: { + used: { + charlotte: true, + onremove: true, + }, }, - subSkill:{ - used:{ - charlotte:true, - onremove:true - } - } }, - xjshijian:{ - audio:2, - trigger:{global:'useCardAfter'}, - direct:true, - filter:function(event,player){ - if(event.player==player) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - return event.player.getHistory('useCard',function(evtt){ - return evtt.getParent('phaseUse')==evt; - }).indexOf(event)==1&&player.countCards('he')>0; + xjshijian: { + audio: 2, + trigger: { global: "useCardAfter" }, + direct: true, + filter: function (event, player) { + if (event.player == player) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + return ( + event.player + .getHistory("useCard", function (evtt) { + return evtt.getParent("phaseUse") == evt; + }) + .indexOf(event) == 1 && player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - var next=player.chooseToDiscard('he',get.prompt('xjshijian',trigger.player),'弃置一张牌并令其获得技能〖誉虚〗至回合结束'); - next.set('logSkill',['xjshijian',trigger.player]); - next.set('check',get.attitude(player,trigger.player)>0&&trigger.player.countCards('h')>2); - next.ai=function(card){ - if(_status.event.check) return 5-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + get.prompt("xjshijian", trigger.player), + "弃置一张牌并令其获得技能〖誉虚〗至回合结束" + ); + next.set("logSkill", ["xjshijian", trigger.player]); + next.set( + "check", + get.attitude(player, trigger.player) > 0 && trigger.player.countCards("h") > 2 + ); + next.ai = function (card) { + if (_status.event.check) return 5 - get.value(card); return -1; }; - 'step 1' - if(result.bool) trigger.player.addTempSkills('yuxu'); + "step 1"; + if (result.bool) trigger.player.addTempSkills("yuxu"); }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, //新1v1 - yanhuo:{ - audio:2, - trigger:{player:'die'}, - forceDie:true, - filter:function(event,player){ - return player.countCards('he')>0; + yanhuo: { + audio: 2, + trigger: { player: "die" }, + forceDie: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - direct:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('yanhuo'),function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0 - }).set('forceDie',true).ai=function(target){ - return -target.countCards('he')*get.attitude(player,target); + direct: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("yanhuo"), function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; + }) + .set("forceDie", true).ai = function (target) { + return -target.countCards("he") * get.attitude(player, target); }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('yanhuo',target); - event.count=player.countCards('he'); - } - else event.finish() - 'step 2' - if(target.countDiscardableCards(player,'he')){ + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("yanhuo", target); + event.count = player.countCards("he"); + } else event.finish(); + "step 2"; + if (target.countDiscardableCards(player, "he")) { player.line(target); - player.discardPlayerCard(target,'he',true).set('forceDie',true); + player.discardPlayerCard(target, "he", true).set("forceDie", true); event.count--; - if(event.count) event.redo(); + if (event.count) event.redo(); } }, }, - mouzhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + mouzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - target.chooseCard('h','交给'+get.translation(player)+'一张手牌',true); - 'step 1' - if(result.bool) target.give(result.cards,player); - 'step 2' - if(player.countCards('h')<=target.countCards('h')){ + content: function () { + "step 0"; + target.chooseCard("h", "交给" + get.translation(player) + "一张手牌", true); + "step 1"; + if (result.bool) target.give(result.cards, player); + "step 2"; + if (player.countCards("h") <= target.countCards("h")) { event.finish(); return; } - var list=[]; - if(target.canUse('sha',player,false)) list.push('sha'); - if(target.canUse('juedou',player,false)) list.push('juedou'); - if(!list.length) event.finish(); - else if(list.length==1) event._result={control:list[0]}; - else target.chooseControl(list).set('prompt','对'+get.translation(player)+'使用一张【杀】或【决斗】。').ai=function(){ - return get.effect(player,{name:'sha'},target,target)>=get.effect(player,{name:'juedou'},target,target)?'sha':'juedou'; - }; - 'step 3' - target.useCard({name:result.control,isCard:true},player,'noai'); + var list = []; + if (target.canUse("sha", player, false)) list.push("sha"); + if (target.canUse("juedou", player, false)) list.push("juedou"); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { control: list[0] }; + else + target + .chooseControl(list) + .set("prompt", "对" + get.translation(player) + "使用一张【杀】或【决斗】。").ai = + function () { + return get.effect(player, { name: "sha" }, target, target) >= + get.effect(player, { name: "juedou" }, target, target) + ? "sha" + : "juedou"; + }; + "step 3"; + target.useCard({ name: result.control, isCard: true }, player, "noai"); }, - ai:{ - order:7, - result:{ - target:-1.2, - player:function(player,target){ - if(target.countCards('h')-player.countCards('h')>1) return 1; - if(get.damageEffect(target,player,player,player)>0) return 1; - if(player.hp>3||player.countCards('h','sha')&&player.countCards('h','shan')) return 0; - if(player.hp>2) return -1.1; + ai: { + order: 7, + result: { + target: -1.2, + player: function (player, target) { + if (target.countCards("h") - player.countCards("h") > 1) return 1; + if (get.damageEffect(target, player, player, player) > 0) return 1; + if ( + player.hp > 3 || + (player.countCards("h", "sha") && player.countCards("h", "shan")) + ) + return 0; + if (player.hp > 2) return -1.1; return -2; }, }, }, }, - niluan:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player!=player&&(event.player.hp>player.hp||event.player.getHistory('useCard',function(card){ - return card.card.name=='sha'; - }).length>0); + niluan: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player != player && + (event.player.hp > player.hp || + event.player.getHistory("useCard", function (card) { + return card.card.name == "sha"; + }).length > 0) + ); }, - direct:true, - content:function(){ - var next=player.chooseToUse(); - next.logSkill='niluan'; - next.set('openskilldialog',get.prompt2('niluan')); - next.set('norestore',true); - next.set('_backupevent','niluanx'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + direct: true, + content: function () { + var next = player.chooseToUse(); + next.logSkill = "niluan"; + next.set("openskilldialog", get.prompt2("niluan")); + next.set("norestore", true); + next.set("_backupevent", "niluanx"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('niluanx'); + next.backup("niluanx"); }, }, - niluanx:{ - viewAs:{name:'sha'}, - filterCard:{color:'black'}, - position:'hes', - selectCard:1, - check:function(card){return 5-get.value(card)}, + niluanx: { + viewAs: { name: "sha" }, + filterCard: { color: "black" }, + position: "hes", + selectCard: 1, + check: function (card) { + return 5 - get.value(card); + }, }, - cuorui:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + cuorui: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return player.maxHp>0&&!get.is.single()&&(event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return ( + player.maxHp > 0 && + !get.is.single() && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - content:function(){ - player.draw(Math.min(5,player.maxHp),false); + content: function () { + player.draw(Math.min(5, player.maxHp), false); }, - group:'cuorui_nojudge', - subSkill:{ - nojudge:{ - trigger:{ - player:'phaseJudgeBefore', + group: "cuorui_nojudge", + subSkill: { + nojudge: { + trigger: { + player: "phaseJudgeBefore", }, - forced:true, - audio:'cuorui', - filter:function(event,player){ - return !player.storage.cuorui&&(get.is.single()||player.countCards('j')); + forced: true, + audio: "cuorui", + filter: function (event, player) { + return !player.storage.cuorui && (get.is.single() || player.countCards("j")); }, - content:function(){ - player.storage.cuorui=true; + content: function () { + player.storage.cuorui = true; trigger.cancel(); - game.log(player,'跳过了','#g判定阶段'); + game.log(player, "跳过了", "#g判定阶段"); }, }, }, }, - liewei:{ - audio:2, - trigger:{source:'dieAfter'}, - frequent:true, - content:function(){ + liewei: { + audio: 2, + trigger: { source: "dieAfter" }, + frequent: true, + content: function () { player.draw(3); }, }, //蒋干 - weicheng:{ - audio:2, - trigger:{ - global:'gainAfter', - player:'loseAsyncAfter', + weicheng: { + audio: 2, + trigger: { + global: "gainAfter", + player: "loseAsyncAfter", }, //forced:true, - frequent:true, - filter:function(event,player){ - if(player.getHp()<=player.countCards('h')) return false; - if(event.name=='loseAsync'){ - if(event.type!='gain') return false; - var cards=event.getl(player).hs; - return game.hasPlayer(function(current){ - if(current==player) return false; - var cardsx=event.getg(current); - for(var i of cardsx){ - if(cards.includes(i)) return true; + frequent: true, + filter: function (event, player) { + if (player.getHp() <= player.countCards("h")) return false; + if (event.name == "loseAsync") { + if (event.type != "gain") return false; + var cards = event.getl(player).hs; + return game.hasPlayer(function (current) { + if (current == player) return false; + var cardsx = event.getg(current); + for (var i of cardsx) { + if (cards.includes(i)) return true; } return false; }); } - if(event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length>0; + if (event.player == player) return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length > 0; }, - preHidden:true, - content:function(){ + preHidden: true, + content: function () { player.draw(); }, }, - daoshu:{ - audio:2, - enable:'phaseUse', - filterTarget:function(c,p,t){ - return t!=p&&t.countGainableCards(p,'h')>0; + daoshu: { + audio: 2, + enable: "phaseUse", + filterTarget: function (c, p, t) { + return t != p && t.countGainableCards(p, "h") > 0; }, - filter:function(e,p){ - return !p.hasSkill('daoshu_used') + filter: function (e, p) { + return !p.hasSkill("daoshu_used"); }, - content:function(){ - 'step 0' - player.chooseControl(lib.suit).set('prompt','请选择一个花色').ai=function(){return lib.suit.randomGet()}; - 'step 1' - event.suit=result.control; - player.popup(event.suit+2); - game.log(player,'选择了',event.suit+2); - player.gainPlayerCard(target,true,'h','visibleMove'); - 'step 2' - if(result.bool){ - var suit2=get.suit(result.cards[0]); - if(suit2==event.suit){ + content: function () { + "step 0"; + player.chooseControl(lib.suit).set("prompt", "请选择一个花色").ai = function () { + return lib.suit.randomGet(); + }; + "step 1"; + event.suit = result.control; + player.popup(event.suit + 2); + game.log(player, "选择了", event.suit + 2); + player.gainPlayerCard(target, true, "h", "visibleMove"); + "step 2"; + if (result.bool) { + var suit2 = get.suit(result.cards[0]); + if (suit2 == event.suit) { target.damage(); event.finish(); - } - else{ - player.addTempSkill('daoshu_used','phaseUseEnd'); - if(player.countCards('h',function(card){return get.suit(card)!=suit2})==0){ + } else { + player.addTempSkill("daoshu_used", "phaseUseEnd"); + if ( + player.countCards("h", function (card) { + return get.suit(card) != suit2; + }) == 0 + ) { player.showHandcards(); event.finish(); - } - else player.chooseCard('h',true,function(card){ - return get.suit(card)!=_status.event.suit2 - },'交给'+get.translation(target)+'一张不为'+get.translation(suit2)+'花色的牌').set('suit2',suit2); + } else + player + .chooseCard( + "h", + true, + function (card) { + return get.suit(card) != _status.event.suit2; + }, + "交给" + + get.translation(target) + + "一张不为" + + get.translation(suit2) + + "花色的牌" + ) + .set("suit2", suit2); } - } - else event.finish(); - 'step 3' - player.give(result.cards,target,true); + } else event.finish(); + "step 3"; + player.give(result.cards, target, true); }, - ai:{ - order:1, - result:{ - target:-1, + ai: { + order: 1, + result: { + target: -1, }, }, - subSkill:{ - used:{sub:true}, + subSkill: { + used: { sub: true }, }, }, //统率三军诸葛瑾和文聘 - "zhenwei_three":{ - global:"zhenwei_three_others", - subSkill:{ - others:{ - mod:{ - globalTo:function (from,to,distance){ - if(from.side!=to.side&&game.hasPlayer(function(current){ - return current!=to&¤t.side==to.side&¤t.hasSkill('zhenwei_three'); - }))return distance+1; + zhenwei_three: { + global: "zhenwei_three_others", + subSkill: { + others: { + mod: { + globalTo: function (from, to, distance) { + if ( + from.side != to.side && + game.hasPlayer(function (current) { + return ( + current != to && + current.side == to.side && + current.hasSkill("zhenwei_three") + ); + }) + ) + return distance + 1; }, }, - sub:true, + sub: true, }, }, }, - "huanshi_three":{ - audio:"huanshi", - trigger:{ - global:"judge", + huanshi_three: { + audio: "huanshi", + trigger: { + global: "judge", }, - filter:function (event,player){ - return player.countCards('hes')>0&&player.side==event.player.side; + filter: function (event, player) { + return player.countCards("hes") > 0 && player.side == event.player.side; }, - direct:true, - content:function (){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('huanshi_three'),'hes',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result-get.value(card)/2; - } - else{ - return -result-get.value(card)/2; - } - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','huanshi_three','noOrdering'); - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("huanshi_three"), + "hes", + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result - get.value(card) / 2; + } else { + return -result - get.value(card) / 2; + } + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "huanshi_three", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, + ai: { + rejudge: true, + tag: { + rejudge: 1, }, }, }, //变权移植 - wanwei:{ - trigger:{target:['rewriteGainResult','rewriteDiscardResult']}, - direct:true, - preHidden:true, - filter:function(event,player){ - return event.player!=player; + wanwei: { + trigger: { target: ["rewriteGainResult", "rewriteDiscardResult"] }, + direct: true, + preHidden: true, + filter: function (event, player) { + return event.player != player; }, - audio:2, - content:function(){ - 'step 0' - var prompt='即将失去'+get.translation(trigger.result.cards)+',是否发动【挽危】?'; - var next=player.choosePlayerCard(player,prompt,trigger.position); - next.set('ai',function(button){ - return 20-get.value(button.link); + audio: 2, + content: function () { + "step 0"; + var prompt = "即将失去" + get.translation(trigger.result.cards) + ",是否发动【挽危】?"; + var next = player.choosePlayerCard(player, prompt, trigger.position); + next.set("ai", function (button) { + return 20 - get.value(button.link); }); - next.filterButton=trigger.filterButton; - next.selectButton=trigger.result.cards.length; - next.setHiddenSkill('wanwei'); - 'step 1' - if(result.bool){ - player.logSkill('wanwei'); - trigger.result.cards=result.links.slice(0); - trigger.result.links=result.links.slice(0); - trigger.cards=result.links.slice(0); + next.filterButton = trigger.filterButton; + next.selectButton = trigger.result.cards.length; + next.setHiddenSkill("wanwei"); + "step 1"; + if (result.bool) { + player.logSkill("wanwei"); + trigger.result.cards = result.links.slice(0); + trigger.result.links = result.links.slice(0); + trigger.cards = result.links.slice(0); trigger.untrigger(); } - } + }, }, - gzjili:{ - mod:{ - aiOrder:function(player,card,num){ - if(player.isPhaseUsing()&&get.subtype(card)=='equip1'&&!get.cardtag(card,'gifts')){ - var range0=player.getAttackRange(); - var range=0; - var info=get.info(card); - if(info&&info.distance&&info.distance.attackFrom){ - range-=info.distance.attackFrom; + gzjili: { + mod: { + aiOrder: function (player, card, num) { + if ( + player.isPhaseUsing() && + get.subtype(card) == "equip1" && + !get.cardtag(card, "gifts") + ) { + var range0 = player.getAttackRange(); + var range = 0; + var info = get.info(card); + if (info && info.distance && info.distance.attackFrom) { + range -= info.distance.attackFrom; } - if(player.getEquip(1)){ - var num=0; - var info=get.info(player.getEquip(1)); - if(info&&info.distance&&info.distance.attackFrom){ - num-=info.distance.attackFrom; + if (player.getEquip(1)) { + var num = 0; + var info = get.info(player.getEquip(1)); + if (info && info.distance && info.distance.attackFrom) { + num -= info.distance.attackFrom; } - range0-=num; + range0 -= num; } - range0+=range; - if(range0==(player.getHistory('useCard').length+player.getHistory('respond').length+2)&&player.countCards('h',function(cardx){ - return get.subtype(cardx)!='equip1'&&player.getUseValue(cardx)>0; - })) return num+10; + range0 += range; + if ( + range0 == + player.getHistory("useCard").length + + player.getHistory("respond").length + + 2 && + player.countCards("h", function (cardx) { + return get.subtype(cardx) != "equip1" && player.getUseValue(cardx) > 0; + }) + ) + return num + 10; } }, }, - trigger:{player:['useCard','respond']}, - frequent:true, - locked:false, - preHidden:true, - filter:function(event,player){ - return player.getHistory('useCard').length+player.getHistory('respond').length==player.getAttackRange(); + trigger: { player: ["useCard", "respond"] }, + frequent: true, + locked: false, + preHidden: true, + filter: function (event, player) { + return ( + player.getHistory("useCard").length + player.getHistory("respond").length == + player.getAttackRange() + ); }, - audio:2, - content:function(){ - player.draw(player.getHistory('useCard').length+player.getHistory('respond').length); + audio: 2, + content: function () { + player.draw(player.getHistory("useCard").length + player.getHistory("respond").length); }, - ai:{ - threaten:1.8, - effect:{ - target:function(card,player,target,current){ - let used=(target.getHistory('useCard').length+target.getHistory('respond').length); - if(get.subtype(card)=='equip1'&&!get.cardtag(card,'gifts')){ - if(player!=target||!player.isPhaseUsing()) return; - let range0=player.getAttackRange(); - let range=0; - let info=get.info(card); - if(info&&info.distance&&info.distance.attackFrom){ - range-=info.distance.attackFrom; + ai: { + threaten: 1.8, + effect: { + target: function (card, player, target, current) { + let used = + target.getHistory("useCard").length + target.getHistory("respond").length; + if (get.subtype(card) == "equip1" && !get.cardtag(card, "gifts")) { + if (player != target || !player.isPhaseUsing()) return; + let range0 = player.getAttackRange(); + let range = 0; + let info = get.info(card); + if (info && info.distance && info.distance.attackFrom) { + range -= info.distance.attackFrom; } - if(player.getEquip(1)){ - let num=0; - let info=get.info(player.getEquip(1)); - if(info&&info.distance&&info.distance.attackFrom){ - num-=info.distance.attackFrom; + if (player.getEquip(1)) { + let num = 0; + let info = get.info(player.getEquip(1)); + if (info && info.distance && info.distance.attackFrom) { + num -= info.distance.attackFrom; } - range0-=num; + range0 -= num; } - range0+=range; - let delta=range0-used; - if(delta<0) return; - let num=player.countCards('h',function(card){ - return (get.cardtag(card,'gifts')||get.subtype(card)!='equip1')&&player.getUseValue(card)>0; + range0 += range; + let delta = range0 - used; + if (delta < 0) return; + let num = player.countCards("h", function (card) { + return ( + (get.cardtag(card, "gifts") || get.subtype(card) != "equip1") && + player.getUseValue(card) > 0 + ); }); - if(delta==2&&num>0) return [1,3]; - if(num>=delta) return 'zeroplayertarget'; - } - else if(get.tag(card,'respondShan')>0){ - if(current<0&&used==target.getAttackRange()-1){ - if(card.name==='sha'){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))) return; - } - else if(!target.mayHaveShan(player)) return 0.9; - return [1,(used+1)/2]; + if (delta == 2 && num > 0) return [1, 3]; + if (num >= delta) return "zeroplayertarget"; + } else if (get.tag(card, "respondShan") > 0) { + if (current < 0 && used == target.getAttackRange() - 1) { + if (card.name === "sha") { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ) + return; + } else if (!target.mayHaveShan(player)) return 0.9; + return [1, (used + 1) / 2]; } - } - else if(get.tag(card,'respondSha')>0){ - if(current<0&&used==target.getAttackRange()-1&&target.mayHaveSha(player)) return [1,(used+1)/2]; + } else if (get.tag(card, "respondSha") > 0) { + if ( + current < 0 && + used == target.getAttackRange() - 1 && + target.mayHaveSha(player) + ) + return [1, (used + 1) / 2]; } }, }, - } + }, }, //新服曹笨 - xinshanjia:{ - group:["xinshanjia_count"], - locked:false, - mod:{ - aiValue:function(player,card,num){ - if((player.storage.xinshanjia||0)<3&&get.type(card)=='equip'&&!get.cardtag(card,'gifts')){ - return num/player.hp; + xinshanjia: { + group: ["xinshanjia_count"], + locked: false, + mod: { + aiValue: function (player, card, num) { + if ( + (player.storage.xinshanjia || 0) < 3 && + get.type(card) == "equip" && + !get.cardtag(card, "gifts") + ) { + return num / player.hp; } }, }, - audio:"shanjia", - trigger:{ - player:"phaseUseBegin", + audio: "shanjia", + trigger: { + player: "phaseUseBegin", }, - intro:{ - content:"本局游戏内已失去过#张装备牌", + intro: { + content: "本局游戏内已失去过#张装备牌", }, - frequent:true, - sync:function(player){ - var history=player.actionHistory; - var num=0; - for(var i=0;i0) player.markSkill('xinshanjia'); + player.storage.xinshanjia = num; + if (num > 0) player.markSkill("xinshanjia"); }, - content:function (){ - 'step 0' + content: function () { + "step 0"; player.draw(3); - 'step 1' + "step 1"; lib.skill.xinshanjia.sync(player); - var num=3-player.storage.xinshanjia; - if(num>0){ - player.chooseToDiscard('he',true,num).ai=get.disvalue; + var num = 3 - player.storage.xinshanjia; + if (num > 0) { + player.chooseToDiscard("he", true, num).ai = get.disvalue; } - 'step 2' - var bool1=true,bool2=true; - if(result.cards){ - var cards=result.cards; - for(var i=0;i2) return false; + ai: { + threaten: 3, + noe: true, + reverseOrder: true, + skillTagFilter: function (player) { + if (player.storage.xinshanjia > 2) return false; }, - effect:{ - target:function(card,player,target){ - if(player.storage.xinshanjia<3&&get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; + effect: { + target: function (card, player, target) { + if ( + player.storage.xinshanjia < 3 && + get.type(card) == "equip" && + !get.cardtag(card, "gifts") + ) + return [1, 3]; }, }, }, - subSkill:{ - count:{ - forced:true, - silent:true, - popup:false, - trigger:{ - player:"loseEnd", + subSkill: { + count: { + forced: true, + silent: true, + popup: false, + trigger: { + player: "loseEnd", }, - filter:function(event,player){ - return event.cards2&&event.cards2.length>0; + filter: function (event, player) { + return event.cards2 && event.cards2.length > 0; }, - content:function (){ + content: function () { lib.skill.xinshanjia.sync(player); }, }, - sha:{ - mark:true, - charlotte:true, - intro:{content:'使用【杀】的次数上限+1'}, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } - } + sha: { + mark: true, + charlotte: true, + intro: { content: "使用【杀】的次数上限+1" }, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, }, - nodis:{ - mark:true, - charlotte:true, - intro:{content:'使用牌无距离限制'}, - mod:{ - targetInRange:()=>true - } - } - } + nodis: { + mark: true, + charlotte: true, + intro: { content: "使用牌无距离限制" }, + mod: { + targetInRange: () => true, + }, + }, + }, }, //OL马超 - ol_shichou:{ - audio:2, - trigger:{player:'useCard2'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; + ol_shichou: { + audio: 2, + trigger: { player: "useCard2" }, + filter: function (event, player) { + return event.card && event.card.name == "sha"; }, - direct:true, - content:function(){ - 'step 0' - var num=player.getDamagedHp()+1; - player.chooseTarget('是否发动【誓仇】?','为'+get.translation(trigger.card)+'添加至多'+get.cnNumber(num)+'个目标',[1,num],function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&!evt.targets.includes(target)&&lib.filter.targetEnabled2(evt.card,player,target)&&lib.filter.targetInRange(evt.card,player,target); - }).set('ai',function(target){ - return get.effect(target,_status.event.getTrigger().card,_status.event.player); - }); - 'step 1' - if(result.bool&&result.targets&&result.targets.length){ - var targets=result.targets; - player.logSkill('ol_shichou',targets); - player.line(targets,trigger.card.nature); + direct: true, + content: function () { + "step 0"; + var num = player.getDamagedHp() + 1; + player + .chooseTarget( + "是否发动【誓仇】?", + "为" + get.translation(trigger.card) + "添加至多" + get.cnNumber(num) + "个目标", + [1, num], + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); + } + ) + .set("ai", function (target) { + return get.effect(target, _status.event.getTrigger().card, _status.event.player); + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + var targets = result.targets; + player.logSkill("ol_shichou", targets); + player.line(targets, trigger.card.nature); trigger.targets.addArray(targets); } }, }, dc_olshichou: { - audio: 'ol_shichou', - trigger: { player: 'useCard2' }, + audio: "ol_shichou", + trigger: { player: "useCard2" }, filter: function (event, player) { - return event.card && event.card.name == 'sha' && player.isDamaged() && game.hasPlayer(function (current) { - return !event.targets.includes(current) && lib.filter.filterTarget(event.card, player, current); - }); + return ( + event.card && + event.card.name == "sha" && + player.isDamaged() && + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.filterTarget(event.card, player, current) + ); + }) + ); }, direct: true, content: function () { - 'step 0' - var num = Math.min(player.getDamagedHp(), game.countPlayer(function (current) { - return !trigger.targets.includes(current) && lib.filter.filterTarget(trigger.card, player, current); - })); - player.chooseTarget('是否发动【誓仇】,令至多' + get.cnNumber(num) + '名其他角色也成为此【杀】的目标?', [1, num], function (card, player, target) { - var evt = _status.event.getTrigger(); - return target != player && !evt.targets.includes(target) && lib.filter.targetEnabled2(evt.card, player, target) && lib.filter.targetInRange(evt.card, player, target); - }).ai = function (target) { - return get.effect(target, { name: 'sha' }, _status.event.player); + "step 0"; + var num = Math.min( + player.getDamagedHp(), + game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.filterTarget(trigger.card, player, current) + ); + }) + ); + player.chooseTarget( + "是否发动【誓仇】,令至多" + get.cnNumber(num) + "名其他角色也成为此【杀】的目标?", + [1, num], + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); + } + ).ai = function (target) { + return get.effect(target, { name: "sha" }, _status.event.player); }; - 'step 1' + "step 1"; if (result.bool && result.targets && result.targets.length) { var targets = result.targets; - player.logSkill('dc_olshichou', targets); + player.logSkill("dc_olshichou", targets); player.line(targets, trigger.card.nature); trigger.targets.addArray(targets); trigger.ol_shichou = true; - player.addTempSkill('ol_shichou2'); + player.addTempSkill("ol_shichou2"); } }, }, - ol_shichou2:{ - charlotte:true, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.ol_shichou&&!player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length&&event.cards.filterInD().length>0; + ol_shichou2: { + charlotte: true, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + event.ol_shichou && + !player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length && + event.cards.filterInD().length > 0 + ); }, - forced:true, - popup:false, - content:function(){ - player.gain(trigger.cards.filterInD(),'gain2'); + forced: true, + popup: false, + content: function () { + player.gain(trigger.cards.filterInD(), "gain2"); }, }, //新大小乔 - new_xingwu:{ - audio:"xingwu", - trigger:{ - player:"phaseDiscardBegin", + new_xingwu: { + audio: "xingwu", + trigger: { + player: "phaseDiscardBegin", }, - direct:true, - intro:{ - content:"expansion", - markcount:'expansion', - onunmark:function(storage,player){ - player.removeAdditionalSkill('new_luoyan'); + direct: true, + intro: { + content: "expansion", + markcount: "expansion", + onunmark: function (storage, player) { + player.removeAdditionalSkill("new_luoyan"); }, }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - filter:function(event,player){ - return player.countCards('he')>0; + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('new_xingwu'),'将一张牌置于武将牌上作为“舞”').set('ai',function(card){ - if(_status.event.goon) return 20-get.value(card); - return 7-get.value(card); - }).set('goon',player.needsToDiscard()||player.getExpansions('new_xingwu').length>1); - 'step 1' - if(result.bool){ - player.logSkill('new_xingwu'); - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('new_xingwu'); - if(player.hasSkill('new_luoyan')) player.addAdditionalSkill('new_luoyan',['oltianxiang','liuli']); - } - else event.finish(); - 'step 2' + content: function () { + "step 0"; + player + .chooseCard("he", get.prompt("new_xingwu"), "将一张牌置于武将牌上作为“舞”") + .set("ai", function (card) { + if (_status.event.goon) return 20 - get.value(card); + return 7 - get.value(card); + }) + .set( + "goon", + player.needsToDiscard() || player.getExpansions("new_xingwu").length > 1 + ); + "step 1"; + if (result.bool) { + player.logSkill("new_xingwu"); + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("new_xingwu"); + if (player.hasSkill("new_luoyan")) + player.addAdditionalSkill("new_luoyan", ["oltianxiang", "liuli"]); + } else event.finish(); + "step 2"; game.delayx(); - var choices=[]; - event.addIndex=0; - if(player.getExpansions('new_xingwu').length>2){ - choices.push('将三张“星舞”牌置入弃牌堆'); - } - else event.addIndex++; - if(player.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'new_xingwu'); - })>1) choices.push('弃置两张手牌并将武将牌翻面'); - if(choices.length){ - player.chooseControl('cancel2').set('prompt','星舞:是否发射核弹?').set('choiceList',choices).set('ai',function(){ - var player=_status.event.player; - if(player.getExpansions('new_xingwu').length>2) return 0; - if(player.isTurnedOver()||player.identity=='fan'||player.getEnemies().length==1) return 0; - return 'cancel2'; - }); - } - else event.finish(); - 'step 3' - if(result.control!='cancel2'){ - var num=result.index+event.addIndex; - if(num==1){ + var choices = []; + event.addIndex = 0; + if (player.getExpansions("new_xingwu").length > 2) { + choices.push("将三张“星舞”牌置入弃牌堆"); + } else event.addIndex++; + if ( + player.countCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "new_xingwu"); + }) > 1 + ) + choices.push("弃置两张手牌并将武将牌翻面"); + if (choices.length) { + player + .chooseControl("cancel2") + .set("prompt", "星舞:是否发射核弹?") + .set("choiceList", choices) + .set("ai", function () { + var player = _status.event.player; + if (player.getExpansions("new_xingwu").length > 2) return 0; + if ( + player.isTurnedOver() || + player.identity == "fan" || + player.getEnemies().length == 1 + ) + return 0; + return "cancel2"; + }); + } else event.finish(); + "step 3"; + if (result.control != "cancel2") { + var num = result.index + event.addIndex; + if (num == 1) { event.goto(5); return; } - if(player.getExpansions('new_xingwu').length>3) player.chooseButton(['请选择要移去的“星舞”牌',player.getExpansions('new_xingwu')],3,true); - else event._result={ - bool:true, - links:player.getExpansions('new_xingwu').slice(0), - } - } - else event.finish(); - 'step 4' - if(result.bool&&result.links&&result.links.length==3){ - var cards=result.links; + if (player.getExpansions("new_xingwu").length > 3) + player.chooseButton( + ["请选择要移去的“星舞”牌", player.getExpansions("new_xingwu")], + 3, + true + ); + else + event._result = { + bool: true, + links: player.getExpansions("new_xingwu").slice(0), + }; + } else event.finish(); + "step 4"; + if (result.bool && result.links && result.links.length == 3) { + var cards = result.links; player.loseToDiscardpile(cards); event.goto(6); - } - else event.finish(); - 'step 5' - player.chooseToDiscard(true,'h',2); + } else event.finish(); + "step 5"; + player.chooseToDiscard(true, "h", 2); player.turnOver(); - 'step 6' - player.chooseTarget('请选择【星舞】的目标','弃置其装备区内的所有牌。然后对其造成2点伤害(目标为女性角色则改为1点)',true,lib.filter.notMe).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*Math.sqrt(4+target.countCards('e',function(card){ - return get.value(card,target)>0; - }))*(target.hasSex('female')?1:2); - }); - 'step 7' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - var num=target.countCards('e'); - if(num) player.discardPlayerCard(target,'e',num,true); - target.damage(target.hasSex('female')?1:2); + "step 6"; + player + .chooseTarget( + "请选择【星舞】的目标", + "弃置其装备区内的所有牌。然后对其造成2点伤害(目标为女性角色则改为1点)", + true, + lib.filter.notMe + ) + .set("ai", function (target) { + return ( + -get.attitude(_status.event.player, target) * + Math.sqrt( + 4 + + target.countCards("e", function (card) { + return get.value(card, target) > 0; + }) + ) * + (target.hasSex("female") ? 1 : 2) + ); + }); + "step 7"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + var num = target.countCards("e"); + if (num) player.discardPlayerCard(target, "e", num, true); + target.damage(target.hasSex("female") ? 1 : 2); } }, - ai:{ - threaten:1.5, + ai: { + threaten: 1.5, }, }, - new_luoyan:{ - init:function(player){ - if(player.getExpansions('new_xingwu').length) player.addAdditionalSkill('new_luoyan',['oltianxiang','liuli']); + new_luoyan: { + init: function (player) { + if (player.getExpansions("new_xingwu").length) + player.addAdditionalSkill("new_luoyan", ["oltianxiang", "liuli"]); }, - onremove:function(player){ - player.removeAdditionalSkill('new_luoyan'); + onremove: function (player) { + player.removeAdditionalSkill("new_luoyan"); + }, + derivation: ["oltianxiang", "liuli"], + locked: true, + ai: { + combo: "new_xingwu", }, - derivation:['oltianxiang','liuli'], - locked:true, }, //新孙鲁育 - "new_meibu":{ - audio:"meibu", - trigger:{ - global:"phaseUseBegin", + new_meibu: { + audio: "meibu", + trigger: { + global: "phaseUseBegin", }, - filter:function (event,player){ - return event.player!=player&&event.player.isIn()&&player.countCards('he')>0&&event.player.inRange(player); + filter: function (event, player) { + return ( + event.player != player && + event.player.isIn() && + player.countCards("he") > 0 && + event.player.inRange(player) + ); }, - direct:true, - derivation:["new_zhixi"], - checkx:function (event,player){ - if(get.attitude(player,event.player)>=0) return false; - var e2=player.getEquip(2); - if(e2){ - if(e2.name=='tengjia'||e2.name=='rewrite_tengjia') return true; - if(e2.name=='bagua'||e2.name=='rewrite_bagua') return true; + direct: true, + derivation: ["new_zhixi"], + checkx: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + var e2 = player.getEquip(2); + if (e2) { + if (e2.name == "tengjia" || e2.name == "rewrite_tengjia") return true; + if (e2.name == "bagua" || e2.name == "rewrite_bagua") return true; } - return event.player.countCards('h')>event.player.hp; + return event.player.countCards("h") > event.player.hp; }, - content:function (){ - "step 0" - var check=lib.skill.new_meibu.checkx(trigger,player); - player.chooseToDiscard(get.prompt2('new_meibu',trigger.player),'he').set('ai',function(card){ - if(_status.event.check) return 6-get.value(card); - return 0; - }).set('check',check).set('logSkill',['new_meibu',trigger.player]); - "step 1" - if(result.bool){ - var target=trigger.player; - var card=result.cards[0]; - player.line(target,'green'); - target.addTempSkills('new_zhixi','phaseUseAfter'); - if(card.name!='sha'&&get.type(card)!='trick'&&get.color(card)!='black'){ - target.addTempSkill('new_meibu_range','phaseUseAfter'); - target.markAuto('new_meibu_range',player); + content: function () { + "step 0"; + var check = lib.skill.new_meibu.checkx(trigger, player); + player + .chooseToDiscard(get.prompt2("new_meibu", trigger.player), "he") + .set("ai", function (card) { + if (_status.event.check) return 6 - get.value(card); + return 0; + }) + .set("check", check) + .set("logSkill", ["new_meibu", trigger.player]); + "step 1"; + if (result.bool) { + var target = trigger.player; + var card = result.cards[0]; + player.line(target, "green"); + target.addTempSkills("new_zhixi", "phaseUseAfter"); + if (card.name != "sha" && get.type(card) != "trick" && get.color(card) != "black") { + target.addTempSkill("new_meibu_range", "phaseUseAfter"); + target.markAuto("new_meibu_range", player); } - target.markSkillCharacter('new_meibu',player,'魅步','锁定技,出牌阶段,你至多可使用X张牌,你使用了锦囊牌后不能再使用牌(X为你的体力值)。'); + target.markSkillCharacter( + "new_meibu", + player, + "魅步", + "锁定技,出牌阶段,你至多可使用X张牌,你使用了锦囊牌后不能再使用牌(X为你的体力值)。" + ); } }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, - subSkill:{ - range:{ - onremove:true, - charlotte:true, - mod:{ - globalFrom:function (from,to,num){ - if(from.getStorage('new_meibu_range').includes(to)){ + subSkill: { + range: { + onremove: true, + charlotte: true, + mod: { + globalFrom: function (from, to, num) { + if (from.getStorage("new_meibu_range").includes(to)) { return -Infinity; } }, }, - sub:true, + sub: true, }, }, }, - "new_mumu":{ - audio:"mumu", - trigger:{ - player:"phaseUseBegin", + new_mumu: { + audio: "mumu", + trigger: { + player: "phaseUseBegin", }, - filter:function(event,player){ - return game.hasPlayer(current=>{ - if(current==player) return current.getEquips(2).length>0; - return current.countCards('e')>0; + filter: function (event, player) { + return game.hasPlayer((current) => { + if (current == player) return current.getEquips(2).length > 0; + return current.countCards("e") > 0; }); }, - direct:true, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt('new_mumu'),'弃置一名其他角色装备区内的一张牌,或者获得一名角色装备区内的防具牌',function(card,player,target){ - if(target==player) return target.getEquips(2).length>0; - return target.countCards('e')>0; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target) - if(target.getEquip(2)&&player.hasEmptySlot(2)){ - return -2*att; - } - return -att; - }); - 'step 1' - if(result.bool&&result.targets&&result.targets.length){ - event.target=result.targets[0]; - player.logSkill('new_mumu',event.target); - player.line(event.target,'green'); - var e=event.target.getEquips(2); - event.e=e; - if(target==player) event.choice='获得一张防具牌'; - else if(e.length>0){ - player.chooseControl('弃置一张装备牌','获得一张防具牌').set('ai',function(){ - if(_status.event.player.getEquips(2).length>0){ - return '弃置一张装备牌'; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("new_mumu"), + "弃置一名其他角色装备区内的一张牌,或者获得一名角色装备区内的防具牌", + function (card, player, target) { + if (target == player) return target.getEquips(2).length > 0; + return target.countCards("e") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (target.getEquip(2) && player.hasEmptySlot(2)) { + return -2 * att; + } + return -att; + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + event.target = result.targets[0]; + player.logSkill("new_mumu", event.target); + player.line(event.target, "green"); + var e = event.target.getEquips(2); + event.e = e; + if (target == player) event.choice = "获得一张防具牌"; + else if (e.length > 0) { + player.chooseControl("弃置一张装备牌", "获得一张防具牌").set("ai", function () { + if (_status.event.player.getEquips(2).length > 0) { + return "弃置一张装备牌"; } - return '获得一张防具牌'; + return "获得一张防具牌"; }); + } else { + event.choice = "弃置一张装备牌"; } - else{ - event.choice='弃置一张装备牌'; - } - } - else event.finish(); - 'step 2' - var choice=event.choice||result.control; - if(choice=='弃置一张装备牌'){ - player.discardPlayerCard(event.target,'e',true); - } - else{ - if(event.e){ - player.gain(event.e,event.target,'give','bySelf'); - player.addTempSkill('new_mumu2') + } else event.finish(); + "step 2"; + var choice = event.choice || result.control; + if (choice == "弃置一张装备牌") { + player.discardPlayerCard(event.target, "e", true); + } else { + if (event.e) { + player.gain(event.e, event.target, "give", "bySelf"); + player.addTempSkill("new_mumu2"); } } }, }, - "new_zhixi":{ - mod:{ - cardEnabled:function(card,player){ - if(player.storage.new_zhixi2||player.countMark('new_zhixi')>=player.hp) return false; + new_zhixi: { + mod: { + cardEnabled: function (card, player) { + if (player.storage.new_zhixi2 || player.countMark("new_zhixi") >= player.hp) + return false; }, - cardUsable:function(card,player){ - if(player.storage.new_zhixi2||player.countMark('new_zhixi')>=player.hp) return false; + cardUsable: function (card, player) { + if (player.storage.new_zhixi2 || player.countMark("new_zhixi") >= player.hp) + return false; }, - cardRespondable:function(card,player){ - if(player.storage.new_zhixi2||player.countMark('new_zhixi')>=player.hp) return false; + cardRespondable: function (card, player) { + if (player.storage.new_zhixi2 || player.countMark("new_zhixi") >= player.hp) + return false; }, - cardSavable:function(card,player){ - if(player.storage.new_zhixi2||player.countMark('new_zhixi')>=player.hp) return false; + cardSavable: function (card, player) { + if (player.storage.new_zhixi2 || player.countMark("new_zhixi") >= player.hp) + return false; }, }, - trigger:{ - player:"useCard1", + trigger: { + player: "useCard1", }, - forced:true, - popup:false, - firstDo:true, - init:function(player,skill){ - player.storage[skill]=0; - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.player==player){ - player.getHistory('useCard',function(evtx){ - if(evtx.getParent('phaseUse')==evt){ + forced: true, + popup: false, + firstDo: true, + init: function (player, skill) { + player.storage[skill] = 0; + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.player == player) { + player.getHistory("useCard", function (evtx) { + if (evtx.getParent("phaseUse") == evt) { player.storage[skill]++; - if(get.type2(evtx.card)=='trick') player.storage.new_zhixi2=true; + if (get.type2(evtx.card) == "trick") player.storage.new_zhixi2 = true; } }); } }, - onremove:function(player){ - player.unmarkSkill('new_meibu'); + onremove: function (player) { + player.unmarkSkill("new_meibu"); delete player.storage.new_zhixi; delete player.storage.new_zhixi2; }, - content:function(){ - player.addMark('new_zhixi',1,false); - if(get.type2(trigger.card)=='trick') player.storage.new_zhixi2=true; + content: function () { + player.addMark("new_zhixi", 1, false); + if (get.type2(trigger.card) == "trick") player.storage.new_zhixi2 = true; }, - ai:{presha:true,pretao:true,nokeep:true}, + ai: { presha: true, pretao: true, nokeep: true }, }, - "new_mumu2":{ - charlotte:true, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + new_mumu2: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, }, }, - qingzhong:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - check:function(event,player){ - if(game.hasPlayer(function(current){ - return current!=player&¤t.isMinHandcard()&&get.attitude(player,current)>0; - })){ + qingzhong: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + check: function (event, player) { + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.isMinHandcard() && + get.attitude(player, current) > 0 + ); + }) + ) { return true; } - if(player.countCards('h')<=2) return true; + if (player.countCards("h") <= 2) return true; // if(player.countCards('h')<=3&&!player.countCards('h','shan')) return true; //if(player.countCards('h',{type:'basic'})<=1) return true; return false; }, - content:function(){ + content: function () { player.draw(2); - player.addTempSkill('qingzhong_give'); + player.addTempSkill("qingzhong_give"); }, - subSkill:{ - give:{ - audio:'qingzhong', - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ + subSkill: { + give: { + audio: "qingzhong", + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { return !player.isMinHandcard(true); }, - forced:true, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ + forced: true, + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { return current.isMinHandcard(); }); - if(list.length==1){ - if(list[0]!=player){ - player.line(list[0],'green'); + if (list.length == 1) { + if (list[0] != player) { + player.line(list[0], "green"); player.swapHandcards(list[0]); } event.finish(); + } else { + player + .chooseTarget( + true, + "清忠:选择一名手牌最少的角色与其交换手牌", + function (card, player, target) { + return target.isMinHandcard(); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); } - else{ - player.chooseTarget(true,'清忠:选择一名手牌最少的角色与其交换手牌',function(card,player,target){ - return target.isMinHandcard(); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(target!=player){ - player.line(target,'green'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (target != player) { + player.line(target, "green"); player.swapHandcards(target); } } - } - } - } + }, + }, + }, }, - weijing:{ - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - if(event.type=='wuxie'||player.hasSkill('weijing_used')) return false; - for(var name of ['sha','shan']){ - if(event.filterCard({name:name,isCard:true},player,event)) return true; + weijing: { + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + if (event.type == "wuxie" || player.hasSkill("weijing_used")) return false; + for (var name of ["sha", "shan"]) { + if (event.filterCard({ name: name, isCard: true }, player, event)) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var vcards=[]; - for(var name of ['sha','shan']){ - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); + chooseButton: { + dialog: function (event, player) { + var vcards = []; + for (var name of ["sha", "shan"]) { + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); } - var dialog=ui.create.dialog('卫境',[vcards,'vcard'],'hidden'); - dialog.direct=true; + var dialog = ui.create.dialog("卫境", [vcards, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:()=>false, - selectCard:-1, - viewAs:{ - name:links[0][2], - isCard:true, + filterCard: () => false, + selectCard: -1, + viewAs: { + name: links[0][2], + isCard: true, }, - popname:true, - precontent:function(){ - player.logSkill('weijing'); - player.addTempSkill('weijing_used','roundStart'); + popname: true, + precontent: function () { + player.logSkill("weijing"); + player.addTempSkill("weijing_used", "roundStart"); }, - } + }; + }, + prompt: function (links, player) { + return "卫境:视为使用一张【" + get.translation(links[0][2]) + "】"; }, - prompt:function(links,player){ - return '卫境:视为使用一张【'+get.translation(links[0][2])+'】'; - } }, - ai:{ - order:function(item,player){ - var player=_status.event.player; - var event=_status.event; - if(event.filterCard({name:'sha'},player,event)){ - if(!player.hasShan()&&!game.hasPlayer(function(current){ - return player.canUse('sha',current)&¤t.hp==1&&get.effect(current,{name:'sha'},player,player)>0; - })){ + ai: { + order: function (item, player) { + var player = _status.event.player; + var event = _status.event; + if (event.filterCard({ name: "sha" }, player, event)) { + if ( + !player.hasShan() && + !game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + current.hp == 1 && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { return 0; } return 2.95; - } - else{ - var player=_status.event.player; - if(player.hasSkill('qingzhong_give')) return 2.95; + } else { + var player = _status.event.player; + if (player.hasSkill("qingzhong_give")) return 2.95; return 3.15; } }, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(player.hasSkill('weijing_used')) return false; - if(arg!='use') return false; + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (player.hasSkill("weijing_used")) return false; + if (arg != "use") return false; + }, + result: { + player: 1, + }, + }, + subSkill: { + used: { + mark: true, + intro: { + content: "本轮已发动", + }, }, - result:{ - player:1 - } }, - subSkill:{ - used:{ - mark:true, - intro:{ - content:'本轮已发动' - } - } - } }, - zishu:{ - audio:2, - locked:true, - subSkill:{ - discard:{ - trigger:{global:'phaseEnd'}, - audio:"zishu", - forced:true, - filter:function(event,player){ - if(_status.currentPhase!=player){ - var he=player.getCards('h'); - var bool=false; - player.getHistory('gain',function(evt){ - if(!bool&&evt&&evt.cards){ - for(var i=0;i0) return false; - return event.cards.filterInD().length>0 - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yingyuan'),'将'+get.translation(trigger.cards)+'交给一名其他角色',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - if(target.hasJudge('lebu')) return 0; - let att=get.attitude(_status.event.player,target),name=_status.event.cards[0].name; - if(att<3) return 0; - if(target.hasSkillTag('nogain')) att/=10; - if(name==='sha'&&target.hasSha()) att/=5; - if(name==='wuxie'&&target.needsToDiscard(_status.event.cards)) att/=5; - return att/(1+get.distance(player,target,'absolute')); - }).set('cards',trigger.cards); - 'step 1' - if(result.bool){ - player.logSkill('yingyuan',result.targets[0]); - result.targets[0].gain(trigger.cards.filterInD(),'gain2'); - player.getHistory('custom').push({yingyuan_name:trigger.card.name}); - } - }, - }, - shuimeng:{ - audio:2, - trigger:{player:'phaseUseAfter'}, - direct:true, - filter:function(event,player){ - return player.countCards('h'); - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('shuimeng'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - return -get.attitude(_status.event.player,target); - }).set('goon',player.needsToDiscard()||player.hasCard(function(card){ - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=11; - } - if(val<=6){ - return card.number>=12; - } + yingyuan: { + audio: 2, + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + if (_status.currentPhase != player) return false; + if ( + player.getHistory("custom", function (evt) { + return evt.yingyuan_name == event.card.name; + }).length > 0 + ) return false; - })); - 'step 1' - if(result.bool){ - player.logSkill('shuimeng',result.targets); - event.target=result.targets[0]; - player.chooseToCompare(event.target); + return event.cards.filterInD().length > 0; + }, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("yingyuan"), + "将" + get.translation(trigger.cards) + "交给一名其他角色", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + if (target.hasJudge("lebu")) return 0; + let att = get.attitude(_status.event.player, target), + name = _status.event.cards[0].name; + if (att < 3) return 0; + if (target.hasSkillTag("nogain")) att /= 10; + if (name === "sha" && target.hasSha()) att /= 5; + if (name === "wuxie" && target.needsToDiscard(_status.event.cards)) att /= 5; + return att / (1 + get.distance(player, target, "absolute")); + }) + .set("cards", trigger.cards); + "step 1"; + if (result.bool) { + player.logSkill("yingyuan", result.targets[0]); + result.targets[0].gain(trigger.cards.filterInD(), "gain2"); + player.getHistory("custom").push({ yingyuan_name: trigger.card.name }); } - else{ + }, + }, + shuimeng: { + audio: 2, + trigger: { player: "phaseUseAfter" }, + direct: true, + filter: function (event, player) { + return player.countCards("h"); + }, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("shuimeng"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + return -get.attitude(_status.event.player, target); + }) + .set( + "goon", + player.needsToDiscard() || + player.hasCard(function (card) { + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 11; + } + if (val <= 6) { + return card.number >= 12; + } + return false; + }) + ); + "step 1"; + if (result.bool) { + player.logSkill("shuimeng", result.targets); + event.target = result.targets[0]; + player.chooseToCompare(event.target); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.chooseUseTarget({name:'wuzhong',isCard:true},true); + "step 2"; + if (result.bool) { + player.chooseUseTarget({ name: "wuzhong", isCard: true }, true); + } else { + event.target.useCard({ name: "guohe", isCard: true }, player); } - else{ - event.target.useCard({name:'guohe',isCard:true},player); - } - } - }, - qianya:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - direct:true, - filter:function(event,player){ - return get.type(event.card,'trick')=='trick'&&player.countCards('h'); }, - content:function(){ - 'step 0' - var nh=player.countCards('h'); + }, + qianya: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + direct: true, + filter: function (event, player) { + return get.type(event.card, "trick") == "trick" && player.countCards("h"); + }, + content: function () { + "step 0"; + var nh = player.countCards("h"); player.chooseCardTarget({ - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player; + filterCard: true, + filterTarget: function (card, player, target) { + return target != player; }, - selectCard:[1,nh], - ai1:function(card){ - var player=_status.event.player; - var cardname=_status.event.cardname; - if(_status.event.du) return -get.value(card,player,'raw'); - else if(_status.event.shuimeng){ - if(cardname=='wuzhong'){ - if(player.needsToDiscard(2,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 10-get.value(card,player,'raw'); - } - else if(cardname=='guohe'){ - if(player.needsToDiscard(-1,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 10-get.value(card,player,'raw'); + selectCard: [1, nh], + ai1: function (card) { + var player = _status.event.player; + var cardname = _status.event.cardname; + if (_status.event.du) return -get.value(card, player, "raw"); + else if (_status.event.shuimeng) { + if (cardname == "wuzhong") { + if ( + player.needsToDiscard(2, (i, player) => { + return ( + !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i) + ); + }) + ) + return 10 - get.value(card, player, "raw"); + } else if (cardname == "guohe") { + if ( + player.needsToDiscard(-1, (i, player) => { + return ( + !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i) + ); + }) + ) + return 10 - get.value(card, player, "raw"); } return 0; - } - else if(cardname=='lebu'){ - if(player.needsToDiscard(1,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })){ - return 8-get.value(card,player,'raw'); - } - else{ - if(!ui.selected.cards.length){ - return 6-get.value(card,player,'raw'); + } else if (cardname == "lebu") { + if ( + player.needsToDiscard(1, (i, player) => { + return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); + }) + ) { + return 8 - get.value(card, player, "raw"); + } else { + if (!ui.selected.cards.length) { + return 6 - get.value(card, player, "raw"); } return 0; } + } else if (cardname == "shunshou") { + if (_status.event.nh <= 2) return get.value(card, player, "raw"); + } else if (cardname == "huogong") { + if (player.hp == 1) return get.value(card, player, "raw"); } - else if(cardname=='shunshou'){ - if(_status.event.nh<=2) return get.value(card,player,'raw'); - } - else if(cardname=='huogong'){ - if(player.hp==1) return get.value(card,player,'raw'); - } - if(ui.selected.cards.length) return 0; - return 7-get.value(card,player,'raw'); + if (ui.selected.cards.length) return 0; + return 7 - get.value(card, player, "raw"); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var nh2=target.countCards('h'); - var num=Math.sqrt(1+nh2); - var cardname=_status.event.cardname; - if(_status.event.du) return 0.5-att; - else if(_status.event.shuimeng){ - return att/num; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var nh2 = target.countCards("h"); + var num = Math.sqrt(1 + nh2); + var cardname = _status.event.cardname; + if (_status.event.du) return 0.5 - att; + else if (_status.event.shuimeng) { + return att / num; + } else if (cardname == "lebu") { + return att / num; + } else if (cardname == "shunshou") { + if (_status.event.nh <= 2) return att / num; + } else if (cardname == "huogong") { + if (_status.event.player.hp == 1) return att / num; } - else if(cardname=='lebu'){ - return att/num; - } - else if(cardname=='shunshou'){ - if(_status.event.nh<=2) return att/num; - } - else if(cardname=='huogong'){ - if(_status.event.player.hp==1) return att/num; - } - if(_status.event.nh>nh2+1){ - return att/num; + if (_status.event.nh > nh2 + 1) { + return att / num; } return 0; }, - du:player.hasCard(function(card){ - return get.value(card,player,'raw')<0; + du: player.hasCard(function (card) { + return get.value(card, player, "raw") < 0; }), - shuimeng:trigger.getParent(2).name=='shuimeng', - nh:nh, - cardname:trigger.card.name, - prompt:get.prompt2('qianya') + shuimeng: trigger.getParent(2).name == "shuimeng", + nh: nh, + cardname: trigger.card.name, + prompt: get.prompt2("qianya"), }); - 'step 1' - if(result.bool){ - player.logSkill('qianya',result.targets); - player.give(result.cards,result.targets[0]); + "step 1"; + if (result.bool) { + player.logSkill("qianya", result.targets); + player.give(result.cards, result.targets[0]); } - } + }, }, - xianfu:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + xianfu: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - audio:6, - content:function(){ - 'step 0' - player.chooseTarget('请选择【先辅】的目标',lib.translate.xianfu_info,true,function(card,player,target){ - return target!=player&&(!player.storage.xianfu2||!player.storage.xianfu2.includes(target)); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return att+1; - if(att==0) return Math.random(); - return att; - }).animate=false; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - if(!player.storage.xianfu2) player.storage.xianfu2=[]; + audio: 6, + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【先辅】的目标", + lib.translate.xianfu_info, + true, + function (card, player, target) { + return ( + target != player && + (!player.storage.xianfu2 || !player.storage.xianfu2.includes(target)) + ); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return att + 1; + if (att == 0) return Math.random(); + return att; + }).animate = false; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (!player.storage.xianfu2) player.storage.xianfu2 = []; player.storage.xianfu2.push(target); - player.addSkill('xianfu2'); + player.addSkill("xianfu2"); } - } - }, - xianfu_mark:{ - marktext:'辅', - intro:{ - name:'先辅', - content:'当你受到伤害后,$受到等量的伤害,当你回复体力后,$回复等量的体力' }, }, - xianfu2:{ - audio:'xianfu', - charlotte:true, - trigger:{global:['damageEnd','recoverEnd']}, - forced:true, - filter:function(event,player){ - if(event.player.isDead()||!player.storage.xianfu2||!player.storage.xianfu2.includes(event.player)||event.num<=0) return false; - if(event.name=='damage') return true; + xianfu_mark: { + marktext: "辅", + intro: { + name: "先辅", + content: "当你受到伤害后,$受到等量的伤害,当你回复体力后,$回复等量的体力", + }, + }, + xianfu2: { + audio: "xianfu", + charlotte: true, + trigger: { global: ["damageEnd", "recoverEnd"] }, + forced: true, + filter: function (event, player) { + if ( + event.player.isDead() || + !player.storage.xianfu2 || + !player.storage.xianfu2.includes(event.player) || + event.num <= 0 + ) + return false; + if (event.name == "damage") return true; return player.isDamaged(); }, - logTarget:'player', - content:function(){ - 'step 0' - var target=trigger.player; - if(!target.storage.xianfu_mark) target.storage.xianfu_mark=[]; + logTarget: "player", + content: function () { + "step 0"; + var target = trigger.player; + if (!target.storage.xianfu_mark) target.storage.xianfu_mark = []; target.storage.xianfu_mark.add(player); target.storage.xianfu_mark.sortBySeat(); - target.markSkill('xianfu_mark'); + target.markSkill("xianfu_mark"); game.delayx(); - 'step 1' - player[trigger.name](trigger.num,'nosource'); + "step 1"; + player[trigger.name](trigger.num, "nosource"); }, - onremove:function(player){ - if(!player.storage.xianfu2) return; - game.countPlayer(function(current){ - if(player.storage.xianfu2.includes(current)&¤t.storage.xianfu_mark){ + onremove: function (player) { + if (!player.storage.xianfu2) return; + game.countPlayer(function (current) { + if (player.storage.xianfu2.includes(current) && current.storage.xianfu_mark) { current.storage.xianfu_mark.remove(player); - if(!current.storage.xianfu_mark.length) current.unmarkSkill('xianfu_mark'); - else current.markSkill('xianfu_mark'); + if (!current.storage.xianfu_mark.length) current.unmarkSkill("xianfu_mark"); + else current.markSkill("xianfu_mark"); } }); delete player.storage.xianfu2; }, - group:'xianfu3', + group: "xianfu3", }, - xianfu3:{ - trigger:{global:'dieBegin'}, - silent:true, - filter:function(event,player){ - return event.player==player||player.storage.xianfu2&&player.storage.xianfu2.includes(player); + xianfu3: { + trigger: { global: "dieBegin" }, + silent: true, + filter: function (event, player) { + return ( + event.player == player || + (player.storage.xianfu2 && player.storage.xianfu2.includes(player)) + ); }, - content:function(){ - if(player==trigger.player) lib.skill.xianfu2.onremove(player); + content: function () { + if (player == trigger.player) lib.skill.xianfu2.onremove(player); else player.storage.xianfu2.remove(event.player); - } + }, }, - chouce:{ - trigger:{player:'damageEnd'}, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' + chouce: { + trigger: { player: "damageEnd" }, + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; player.judge(); - 'step 2' - event.color=result.color; - if(event.color=='black'){ - if(game.hasPlayer(function(current){ - return current.countDiscardableCards(player,'hej')>0; - })) player.chooseTarget('弃置一名角色区域内的一张牌',function(card,player,target){ - return target.countDiscardableCards(player,'hej'); - },true).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<0){ - att=-Math.sqrt(-att); - } - else{ - att=Math.sqrt(att); - } - return att*lib.card.guohe.ai.result.target(player,target); - }); + "step 2"; + event.color = result.color; + if (event.color == "black") { + if ( + game.hasPlayer(function (current) { + return current.countDiscardableCards(player, "hej") > 0; + }) + ) + player + .chooseTarget( + "弃置一名角色区域内的一张牌", + function (card, player, target) { + return target.countDiscardableCards(player, "hej"); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att < 0) { + att = -Math.sqrt(-att); + } else { + att = Math.sqrt(att); + } + return att * lib.card.guohe.ai.result.target(player, target); + }); else event.finish(); - } - else{ - var next=player.chooseTarget('令一名角色摸一张牌'); - if(player.storage.xianfu2&&player.storage.xianfu2.length){ - next.set('prompt2','(若目标为'+get.translation(player.storage.xianfu2)+'则改为摸两张牌)'); + } else { + var next = player.chooseTarget("令一名角色摸一张牌"); + if (player.storage.xianfu2 && player.storage.xianfu2.length) { + next.set( + "prompt2", + "(若目标为" + get.translation(player.storage.xianfu2) + "则改为摸两张牌)" + ); } - next.set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - if(target.hasSkillTag('nogain')) att/=10; - if(player.storage.xianfu2&&player.storage.xianfu2.includes(target)) return att*2; + next.set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + if (target.hasSkillTag("nogain")) att /= 10; + if (player.storage.xianfu2 && player.storage.xianfu2.includes(target)) + return att * 2; return att; - }) + }); } - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - if(event.color=='black'){ - player.discardPlayerCard(target,'hej',true); - } - else{ - if(player.storage.xianfu2&&player.storage.xianfu2.includes(target)){ - if(!target.storage.xianfu_mark) target.storage.xianfu_mark=[]; + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + if (event.color == "black") { + player.discardPlayerCard(target, "hej", true); + } else { + if (player.storage.xianfu2 && player.storage.xianfu2.includes(target)) { + if (!target.storage.xianfu_mark) target.storage.xianfu_mark = []; target.storage.xianfu_mark.add(player); target.storage.xianfu_mark.sortBySeat(); - target.markSkill('xianfu_mark'); + target.markSkill("xianfu_mark"); target.draw(2); - } - else{ + } else { target.draw(); } } } - 'step 4' - if(--event.num>0&&player.hasSkill('chouce')){ - player.chooseBool(get.prompt2('chouce')); - } - else{ + "step 4"; + if (--event.num > 0 && player.hasSkill("chouce")) { + player.chooseBool(get.prompt2("chouce")); + } else { event.finish(); } - 'step 5' - if(result.bool){ - player.logSkill('chouce'); + "step 5"; + if (result.bool) { + player.logSkill("chouce"); event.goto(1); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [1,get.tag(card,'damage')*1.5]; - if(target.hp==3) return [1,get.tag(card,'damage')*1]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [1, get.tag(card, "damage") * 1.5]; + if (target.hp == 3) return [1, get.tag(card, "damage") * 1]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } - } - } - } - }, - fuqi:{ - audio:2, - forced:true, - trigger:{ - player:"useCard", - }, - filter:function(event,player){ - return event.card&&(get.type(event.card)=='trick'||get.type(event.card)=='basic'&&!['shan','tao','jiu','du'].includes(event.card.name))&&game.hasPlayer(function(current){ - return current!=player&&get.distance(current,player)<=1; - }); - }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player&&get.distance(current,player)<=1; - })); - }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return get.distance(arg.target,player)<=1; + }, }, }, }, - wylianji:{ - enable:'phaseUse', - audio:2, - usable:1, - filter:function(event,player){ + fuqi: { + audio: 2, + forced: true, + trigger: { + player: "useCard", + }, + filter: function (event, player) { + return ( + event.card && + (get.type(event.card) == "trick" || + (get.type(event.card) == "basic" && + !["shan", "tao", "jiu", "du"].includes(event.card.name))) && + game.hasPlayer(function (current) { + return current != player && get.distance(current, player) <= 1; + }) + ); + }, + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player && get.distance(current, player) <= 1; + }) + ); + }, + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return get.distance(arg.target, player) <= 1; + }, + }, + }, + wylianji: { + enable: "phaseUse", + audio: 2, + usable: 1, + filter: function (event, player) { return player.hasCard(lib.skill.wylianji.filterCard); }, - check:function(card){ - if(card.name=='sha') return 1; - else{ - if(get.tag(card,'damage')){ - if(get.tag(card,'multineg')) return 5; + check: function (card) { + if (card.name == "sha") return 1; + else { + if (get.tag(card, "damage")) { + if (get.tag(card, "multineg")) return 5; return 2; } } return 0; }, - filterCard:function(card){ - return get.name(card)=='sha'||(get.type(card,'trick')=='trick'&&get.color(card)=='black'&&!get.info(card).multitarget)&&get.info(card).enable; + filterCard: function (card) { + return ( + get.name(card) == "sha" || + (get.type(card, "trick") == "trick" && + get.color(card) == "black" && + !get.info(card).multitarget && + get.info(card).enable) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&!target.isMin()&& - (player.canUse(card,target,false)||game.hasPlayer(function(current){ - return current!=player&&target.canUse(card,current); - })); + filterTarget: function (card, player, target) { + return ( + target != player && + !target.isMin() && + (player.canUse(card, target, false) || + game.hasPlayer(function (current) { + return current != player && target.canUse(card, current); + })) + ); }, - discard:false, - lose:true, - delay:false, - content:function(){ - 'step 0' - player.showCards(get.translation(player)+'对'+get.translation(target)+'发动了【连计】',cards); - 'step 1' - var equip1=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'; + discard: false, + lose: true, + delay: false, + content: function () { + "step 0"; + player.showCards( + get.translation(player) + "对" + get.translation(target) + "发动了【连计】", + cards + ); + "step 1"; + var equip1 = get.cardPile2(function (card) { + return get.subtype(card) == "equip1"; }); - if(!equip1){ - player.popup('杯具'); - game.log('牌堆中无装备'); + if (!equip1) { + player.popup("杯具"); + game.log("牌堆中无装备"); event.finish(); return; } - if(equip1.name=='qinggang'&&!lib.inpile.includes('qibaodao')){ + if (equip1.name == "qinggang" && !lib.inpile.includes("qibaodao")) { equip1.remove(); - equip1=game.createCard2('qibaodao',equip1.suit,equip1.number); + equip1 = game.createCard2("qibaodao", equip1.suit, equip1.number); } target.$draw(equip1); - target.chooseUseTarget(true,equip1,'nothrow','nopopup'); + target.chooseUseTarget(true, equip1, "nothrow", "nopopup"); game.delay(); - 'step 2' + "step 2"; game.updateRoundNumber(); - var card=cards[0]; - var bool1=game.hasPlayer(function(current){ - return current!=player&&target.canUse(card,current); + var card = cards[0]; + var bool1 = game.hasPlayer(function (current) { + return current != player && target.canUse(card, current); }); - var bool2=player.canUse(card,target,false); - if(bool1&&bool2){ - target.chooseControl(function(){ - return 0; - }).set('choiceList',[ - '对除'+get.translation(player)+'以外的角色使用'+get.translation(cards)+',并将装备区里的武器牌交给该牌的一个目标角色', - '视为'+get.translation(player)+'对你使用'+get.translation(cards)+',并将装备区内的武器牌交给'+get.translation(player) - ]); - } - else if(bool1){ - event.directindex=0; - } - else if(bool2){ - event.directindex=1; - } - else{ + var bool2 = player.canUse(card, target, false); + if (bool1 && bool2) { + target + .chooseControl(function () { + return 0; + }) + .set("choiceList", [ + "对除" + + get.translation(player) + + "以外的角色使用" + + get.translation(cards) + + ",并将装备区里的武器牌交给该牌的一个目标角色", + "视为" + + get.translation(player) + + "对你使用" + + get.translation(cards) + + ",并将装备区内的武器牌交给" + + get.translation(player), + ]); + } else if (bool1) { + event.directindex = 0; + } else if (bool2) { + event.directindex = 1; + } else { event.finish(); } - 'step 3' - var card=cards[0]; - if(result&&typeof event.directindex!='number'){ - event.directindex=result.index; + "step 3"; + var card = cards[0]; + if (result && typeof event.directindex != "number") { + event.directindex = result.index; } - if(event.directindex==1){ - event.insert(lib.skill.wylianji.content_use,{ - player:player, - target:target, - card:card - }) - } - else{ - event.insert(lib.skill.wylianji.content_give,{ - player:target, - card:card, - targets:game.filterPlayer(function(current){ - return current!=player; - }) + if (event.directindex == 1) { + event.insert(lib.skill.wylianji.content_use, { + player: player, + target: target, + card: card, + }); + } else { + event.insert(lib.skill.wylianji.content_give, { + player: target, + card: card, + targets: game.filterPlayer(function (current) { + return current != player; + }), }); } }, - content_use:function(){ - 'step 0' - player.useCard(card,target); - 'step 1' - if(!get.owner(card)){ - target.gain(card,'gain2'); + content_use: function () { + "step 0"; + player.useCard(card, target); + "step 1"; + if (!get.owner(card)) { + target.gain(card, "gain2"); } - 'step 2' - var equip1=target.getEquips(1); - if(equip1.length){ + "step 2"; + var equip1 = target.getEquips(1); + if (equip1.length) { game.delay(); - target.give(equip1,player); + target.give(equip1, player); target.line(player); } }, - content_give:function(){ - 'step 0' - var select=get.select(get.info(card).selectTarget); - if(select[1]==-1){ - for(var i=0;i1){ - player.chooseTarget(true,'将'+get.translation(equip1)+'交给一名角色',function(card,player,target){ - return _status.event.list.includes(target); - }).set('ai',function(target){ - return get.attitude(player,target); - }).set('list',_status.event.list); - event.equip1=equip1; - } - else{ - if(event.list.length==1){ - player.give(equip1,event.list[0]); + if (event.list.length > 1) { + player + .chooseTarget( + true, + "将" + get.translation(equip1) + "交给一名角色", + function (card, player, target) { + return _status.event.list.includes(target); + } + ) + .set("ai", function (target) { + return get.attitude(player, target); + }) + .set("list", _status.event.list); + event.equip1 = equip1; + } else { + if (event.list.length == 1) { + player.give(equip1, event.list[0]); player.line(event.list); } event.finish(); } - } - else{ + } else { event.finish(); } - 'step 3' - if(result.bool&&result.targets.length&&event.equip1){ - player.give(event.equip1,result.targets[0]); + "step 3"; + if (result.bool && result.targets.length && event.equip1) { + player.give(event.equip1, result.targets[0]); player.line(result.targets); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(ui.selected.cards.length){ - var card=ui.selected.cards[0]; - var bool=(card.name!='sha'); - if(game.hasPlayer(function(current){ - return target.canUse(card,current,bool)&&get.effect(current,card,target,player)>0; - })){ - var num=1; - if(target.getEquip(1)){ - num=0.6; + ai: { + order: 7, + result: { + target: function (player, target) { + if (ui.selected.cards.length) { + var card = ui.selected.cards[0]; + var bool = card.name != "sha"; + if ( + game.hasPlayer(function (current) { + return ( + target.canUse(card, current, bool) && + get.effect(current, card, target, player) > 0 + ); + }) + ) { + var num = 1; + if (target.getEquip(1)) { + num = 0.6; } - if(target.hasSkillTag('noe')) 2*num; + if (target.hasSkillTag("noe")) 2 * num; return num; } } return 0; - } - } - } + }, + }, + }, }, - moucheng:{ - audio:2, - derivation:['jingong','wy_meirenji','wy_xiaolicangdao'], - trigger:{global:'damageEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.source!=player&&event.getParent(2).name=='useCard'&&event.getParent(3).name=='wylianjiInserted'; + moucheng: { + audio: 2, + derivation: ["jingong", "wy_meirenji", "wy_xiaolicangdao"], + trigger: { global: "damageEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.source != player && + event.getParent(2).name == "useCard" && + event.getParent(3).name == "wylianjiInserted" + ); }, - init:function(player){ - player.storage.moucheng=0; + init: function (player) { + player.storage.moucheng = 0; }, - intro:{ - content:'已造成#点伤害' + intro: { + content: "已造成#点伤害", }, - unique:true, - juexingji:true, - content:function(){ - player.storage.moucheng+=trigger.num; - if(player.hasSkill('moucheng')){ - player.markSkill('moucheng'); - player.syncStorage('moucheng'); + unique: true, + juexingji: true, + content: function () { + player.storage.moucheng += trigger.num; + if (player.hasSkill("moucheng")) { + player.markSkill("moucheng"); + player.syncStorage("moucheng"); } - if(player.storage.moucheng>=3){ - event.trigger('mouchengAwaken'); + if (player.storage.moucheng >= 3) { + event.trigger("mouchengAwaken"); } }, - group:'moucheng_awaken', - subSkill:{ - awaken:{ - trigger:{player:'mouchengAwaken'}, - forced:true, - skillAnimation:true, - animationColor:'gray', - content:function(){ - player.awakenSkill('moucheng'); - game.log(player,'失去了技能','#g【连计】'); - player.changeSkills(['jingong'],['wylianji']); - } - } - } + group: "moucheng_awaken", + subSkill: { + awaken: { + trigger: { player: "mouchengAwaken" }, + forced: true, + skillAnimation: true, + animationColor: "gray", + content: function () { + player.awakenSkill("moucheng"); + game.log(player, "失去了技能", "#g【连计】"); + player.changeSkills(["jingong"], ["wylianji"]); + }, + }, + }, + ai: { + combo: "wylianji", + }, }, - jingong:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return event.xinjingong_list&&player.countCards('hes',function(card){ - return card.name=='sha'||get.type(card)=='equip'; - }); + jingong: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + event.xinjingong_list && + player.countCards("hes", function (card) { + return card.name == "sha" || get.type(card) == "equip"; + }) + ); }, - onChooseToUse:function(event){ - if(!game.online){ - var evt=event.getParent(); - if(evt.name!='phaseUse') return; - if(!evt.xinjingong_list){ - var list=get.inpile('trick').randomGets(2); - if(Math.random()<0.5){ - list.push('wy_meirenji'); + onChooseToUse: function (event) { + if (!game.online) { + var evt = event.getParent(); + if (evt.name != "phaseUse") return; + if (!evt.xinjingong_list) { + var list = get.inpile("trick").randomGets(2); + if (Math.random() < 0.5) { + list.push("wy_meirenji"); + } else { + list.push("wy_xiaolicangdao"); } - else{ - list.push('wy_xiaolicangdao'); - } - evt.xinjingong_list=list; + evt.xinjingong_list = list; } - if(!event.xinjingong_list) event.set('xinjingong_list',evt.xinjingong_list); + if (!event.xinjingong_list) event.set("xinjingong_list", evt.xinjingong_list); } }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of event.xinjingong_list) list.push(['锦囊','',i]); - return ui.create.dialog('矜功',[list,'vcard']); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of event.xinjingong_list) list.push(["锦囊", "", i]); + return ui.create.dialog("矜功", [list, "vcard"]); }, - filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2]}); + check: function (button) { + return _status.event.player.getUseValue({ name: button.link[2] }); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jingong', - popname:true, - position:'hes', - viewAs:{name:links[0][2]}, - check:function(card){ - return 6-get.value(card); + audio: "jingong", + popname: true, + position: "hes", + viewAs: { name: links[0][2] }, + check: function (card) { + return 6 - get.value(card); }, - filterCard:function(card){ - return card.name=='sha'||get.type(card)=='equip'; + filterCard: function (card) { + return card.name == "sha" || get.type(card) == "equip"; }, - precontent:function(){ - player.addTempSkill('jingong2'); + precontent: function () { + player.addTempSkill("jingong2"); }, }; }, - prompt:function(links,player){ - return '将一张【杀】或装备牌当做'+get.translation(links[0][2])+'使用'; - } + prompt: function (links, player) { + return "将一张【杀】或装备牌当做" + get.translation(links[0][2]) + "使用"; + }, }, - ai:{ - order:2, - result:{ - player:function(player){ - if((player.hp<=2||player.needsToDiscard())&&!player.getStat('damage')) return 0; + ai: { + order: 2, + result: { + player: function (player) { + if ((player.hp <= 2 || player.needsToDiscard()) && !player.getStat("damage")) + return 0; return 1; - } - } - } - }, - jingong2:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return !player.getStat('damage'); + }, + }, }, - content:function(){ - player.loseHp(); - } }, - jingong3:{charlotte:true}, - weikui:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); + jingong2: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return !player.getStat("damage"); }, - content:function(){ - 'step 0' + content: function () { player.loseHp(); - 'step 1' - if(target.countCards('h','shan')){ + }, + }, + jingong3: { charlotte: true }, + weikui: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); + }, + content: function () { + "step 0"; + player.loseHp(); + "step 1"; + if (target.countCards("h", "shan")) { player.viewHandcards(target); - if(player.canUse({name:'sha',isCard:true},target,false)) player.useCard({name:'sha',isCard:true},target,false); - player.storage.weikui2=target; - player.addTempSkill('weikui2'); - } - else{ - player.discardPlayerCard(target,'visible',true,'h').set('ai',function(button){ - return get.value(button.link,_status.event.target); + if (player.canUse({ name: "sha", isCard: true }, target, false)) + player.useCard({ name: "sha", isCard: true }, target, false); + player.storage.weikui2 = target; + player.addTempSkill("weikui2"); + } else { + player.discardPlayerCard(target, "visible", true, "h").set("ai", function (button) { + return get.value(button.link, _status.event.target); }); } }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(player.hp<=2) return 0; - if(player.hp==3) return target.hp<=2?-1:0; + ai: { + order: 8, + result: { + target: function (player, target) { + if (player.hp <= 2) return 0; + if (player.hp == 3) return target.hp <= 2 ? -1 : 0; return -1; - } - } - } - }, - weikui2:{ - onremove:true, - mod:{ - globalFrom:function(from,to){ - if(to==from.storage.weikui2) return -Infinity; - } - }, - mark:'character', - intro:{ - content:'与$的距离视为1直到回合结束' + }, + }, }, }, - lizhan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - for(var i=0;i=num) return false; - return player.countCards('h')>0; + ai: { + expose: 0.3, + threaten: 1.3, }, - filterTarget:function(event,player,target){ + }, + xinfenyue: { + enable: "phaseUse", + audio: "fenyue", + filter: function (event, player) { + var num = game.players.length - player.getFriends(true).length; + if ((player.getStat().skill.xinfenyue || 0) >= num) return false; + return player.countCards("h") > 0; + }, + filterTarget: function (event, player, target) { return player.canCompare(target); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(!result.bool) event.finish(); - event.num=result.num1; - 'step 2' - if(num<=5&&target.countGainableCards(player,'he')>0) player.gainPlayerCard(target,'he',true); - 'step 3' - if(num<=9){ - var card=get.cardPile2(function(x){ - return x.name=='sha'; + "step 1"; + if (!result.bool) event.finish(); + event.num = result.num1; + "step 2"; + if (num <= 5 && target.countGainableCards(player, "he") > 0) + player.gainPlayerCard(target, "he", true); + "step 3"; + if (num <= 9) { + var card = get.cardPile2(function (x) { + return x.name == "sha"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } - 'step 4' - if(num<=13){ - var card={name:'sha',nature:'thunder'}; - if(player.canUse(card,target,false)) player.useCard(card,target,false); + "step 4"; + if (num <= 13) { + var card = { name: "sha", nature: "thunder" }; + if (player.canUse(card, target, false)) player.useCard(card, target, false); } }, - ai:{ - order:4, - result:{ - target:function(player,target){ - var sort=function(a,b){ - return b.number-a.number; + ai: { + order: 4, + result: { + target: function (player, target) { + var sort = function (a, b) { + return b.number - a.number; }; - var ps=player.getCards('h').sort(sort); - var ts=target.getCards('h').sort(sort); - if(ps[0].number>ts[0].number){ - var effect=get.effect(target,{name:'sha',nature:'thunder'},player,player) - if(ps[0].number<6&&target.countCards('he')>1) effect-=2; - if(ps[0].number<10) effect-=1; + var ps = player.getCards("h").sort(sort); + var ts = target.getCards("h").sort(sort); + if (ps[0].number > ts[0].number) { + var effect = get.effect( + target, + { name: "sha", nature: "thunder" }, + player, + player + ); + if (ps[0].number < 6 && target.countCards("he") > 1) effect -= 2; + if (ps[0].number < 10) effect -= 1; return effect; } - return ps.length>=ts.length?-0.5:0; + return ps.length >= ts.length ? -0.5 : 0; }, }, }, }, - fenyue:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(!player.countCards('h')) return false; + fenyue: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (!player.countCards("h")) return false; var num; - if(get.mode()=='identity'){ - num=game.countPlayer(function(current){ - return current.identity=='zhong'||current.identity=='mingzhong'; + if (get.mode() == "identity") { + num = game.countPlayer(function (current) { + return current.identity == "zhong" || current.identity == "mingzhong"; }); + } else { + num = 1; } - else{ - num=1; - } - if(player.getStat().skill.fenyue>=num) return false; + if (player.getStat().skill.fenyue >= num) return false; return true; }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.canCompare(target); }, - ai:{ - order:2.8, - result:{ - target:function(player,target){ - if(get.attitude(player,target)<0&&player.hasCard(function(card){ - return (card.number>=9&&get.value(card)<=5)||get.value(card)<=3; - })){ - return get.effect(target,{name:'sha'},player,target); - } - else{ + ai: { + order: 2.8, + result: { + target: function (player, target) { + if ( + get.attitude(player, target) < 0 && + player.hasCard(function (card) { + return (card.number >= 9 && get.value(card) <= 5) || get.value(card) <= 3; + }) + ) { + return get.effect(target, { name: "sha" }, player, target); + } else { return 0; } - } - } + }, + }, }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - player.chooseControl(function(){ - return 1; - }).set('choiceList',[ - '令'+get.translation(target)+'不能使用或打出手牌直到回合结束', - '视为对'+get.translation(target)+'使用一张杀(不计入次数限制)' - ]); - } - else{ - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.name=='phaseUse'){ - evt.skipped=true; + "step 1"; + if (result.bool) { + player + .chooseControl(function () { + return 1; + }) + .set("choiceList", [ + "令" + get.translation(target) + "不能使用或打出手牌直到回合结束", + "视为对" + get.translation(target) + "使用一张杀(不计入次数限制)", + ]); + } else { + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.name == "phaseUse") { + evt.skipped = true; } event.finish(); } - 'step 2' - if(result.control=='选项一'){ - target.addTempSkill('fenyue2'); + "step 2"; + if (result.control == "选项一") { + target.addTempSkill("fenyue2"); + } else { + player.useCard({ name: "sha", isCard: true }, target, false); } - else{ - player.useCard({name:'sha',isCard:true},target,false); - } - } + }, }, - fenyue2:{ - mark:true, - mod:{ - cardEnabled2:function (card){ - if(get.position(card)=='h') return false; + fenyue2: { + mark: true, + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, }, - intro:{ - content:'不能使用或打出手牌' - } + intro: { + content: "不能使用或打出手牌", + }, }, - zfengshi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('e'); + zfengshi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countCards("e"); }, - logTarget:'target', - check:function(event,player){ - if(event.target.hasSkillTag('noe')) return false; - return get.attitude(player,event.target)<0; + logTarget: "target", + check: function (event, player) { + if (event.target.hasSkillTag("noe")) return false; + return get.attitude(player, event.target) < 0; + }, + content: function () { + trigger.target.chooseToDiscard("e", true); }, - content:function(){ - trigger.target.chooseToDiscard('e',true); - } }, - chuanxin:{ - audio:2, - trigger:{source:'damageBegin2'}, - preHidden:true, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - if(!_status.event.getParent('phaseUse')) return false; - if(event.card&&(event.card.name=='sha'||event.card.name=='juedou')&&event.getParent().name==event.card.name){ - if(get.mode()=='guozhan'){ - return (event.player.identity!='qun'||player.identity=='ye')&& - !event.player.isUnseen()&&event.player.hasViceCharacter(); - } - else{ - var info=lib.character[event.player.name]; - if(!info) return false; - var skills=event.player.getSkills(); - for(var i=0;i=2) return 1; - return 0; - }).set('choiceList',['弃置装备区内的所有牌并失去1点体力',get.mode()=='guozhan'?'移除副将牌':'随机移除武将牌上的一个技能']); + if (trigger.player.countCards("e")) { + trigger.player + .chooseControl(function (event, player) { + if (get.mode() == "guozhan" && get.guozhanRank(player.name2, player) < 4) + return 1; + if (player.hp == 1) return 1; + if (player.hp == 2 && player.countCards("e") >= 2) return 1; + return 0; + }) + .set("choiceList", [ + "弃置装备区内的所有牌并失去1点体力", + get.mode() == "guozhan" ? "移除副将牌" : "随机移除武将牌上的一个技能", + ]); + } else { + event._result = { index: 1 }; } - else{ - event._result={index:1}; - } - 'step 1' - if(result.index==1){ - if(get.mode()!='guozhan'){ - var info=lib.character[trigger.player.name]; - var skills=trigger.player.getSkills(); - var list=[]; - for(var i=0;i0; + filter: function (event) { + return _status.currentPhase && _status.currentPhase.isIn() && event.num > 0; }, - logTarget:function(){ + logTarget: function () { return _status.currentPhase; }, - content:function(){ - var source=_status.currentPhase; - if(source.hasSkill('hengjiang2')){ - source.storage.hengjiang2+=trigger.num; + content: function () { + var source = _status.currentPhase; + if (source.hasSkill("hengjiang2")) { + source.storage.hengjiang2 += trigger.num; source.storage.hengjiang3.add(player); source.updateMarks(); - } - else{ - source.storage.hengjiang3=[player]; - source.storage.hengjiang2=trigger.num; - source.addTempSkill('hengjiang2'); + } else { + source.storage.hengjiang3 = [player]; + source.storage.hengjiang2 = trigger.num; + source.addTempSkill("hengjiang2"); } }, - ai:{ - maixie_defend:true, - } + ai: { + maixie_defend: true, + }, }, - hengjiang2:{ - mark:true, - charlotte:true, - intro:{ - content:'手牌上限-#' + hengjiang2: { + mark: true, + charlotte: true, + intro: { + content: "手牌上限-#", }, - mod:{ - maxHandcard:function(player,num){ - return num-player.storage.hengjiang2; - } + mod: { + maxHandcard: function (player, num) { + return num - player.storage.hengjiang2; + }, }, - onremove:function(player){ + onremove: function (player) { delete player.storage.hengjiang2; delete player.storage.hengjiang3; }, - trigger:{player:'phaseDiscardEnd'}, - filter:function(event,player){ - if(event.cards&&event.cards.length) return false; - var players=player.storage.hengjiang3; - for(var i=0;i0; + filter: function (event) { + return _status.currentPhase && _status.currentPhase.isIn() && event.num > 0; }, - logTarget:function(){ + logTarget: function () { return _status.currentPhase; }, - preHidden:true, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" + preHidden: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - var source=_status.currentPhase; - source.addTempSkill('rehengjiang2'); - source.addMark('rehengjiang2',1,false); - player.addTempSkill('rehengjiang3'); - "step 2" - if(event.count&&player.hasSkill('rehengjiang')){ - player.chooseBool(get.prompt2('rehengjiang',_status.currentPhase)).set('ai',function(){ - return lib.skill.rehengjiang.check(_status.event.getTrigger(),_status.event.player); - }) - } - else event.finish(); - "step 3" - if(result.bool){ - player.logSkill('rehengjiang',_status.currentPhase); + var source = _status.currentPhase; + source.addTempSkill("rehengjiang2"); + source.addMark("rehengjiang2", 1, false); + player.addTempSkill("rehengjiang3"); + "step 2"; + if (event.count && player.hasSkill("rehengjiang")) { + player + .chooseBool(get.prompt2("rehengjiang", _status.currentPhase)) + .set("ai", function () { + return lib.skill.rehengjiang.check( + _status.event.getTrigger(), + _status.event.player + ); + }); + } else event.finish(); + "step 3"; + if (result.bool) { + player.logSkill("rehengjiang", _status.currentPhase); event.goto(1); } }, - ai:{ - maixie_defend:true, - notemp:true, - } - }, - rehengjiang2:{ - mark:true, - charlotte:true, - onremove:true, - intro:{ - content:'手牌上限-#' - }, - mod:{ - maxHandcard:function(player,num){ - return num-player.storage.rehengjiang2; - } + ai: { + maixie_defend: true, + notemp: true, }, }, - rehengjiang3:{ - audio:'hengjiang', - trigger:{global:'phaseEnd'}, - forced:true, - charlotte:true, - filterx:function(event,player){ - if(!event.player.countMark('rehengjiang2')) return false; - if(event.player.hasHistory('lose',function(evt){ - return evt.type=='discard'&&evt.cards2.length>0&&evt.getParent('phaseDiscard').player==event.player; - })) return false; + rehengjiang2: { + mark: true, + charlotte: true, + onremove: true, + intro: { + content: "手牌上限-#", + }, + mod: { + maxHandcard: function (player, num) { + return num - player.storage.rehengjiang2; + }, + }, + }, + rehengjiang3: { + audio: "hengjiang", + trigger: { global: "phaseEnd" }, + forced: true, + charlotte: true, + filterx: function (event, player) { + if (!event.player.countMark("rehengjiang2")) return false; + if ( + event.player.hasHistory("lose", function (evt) { + return ( + evt.type == "discard" && + evt.cards2.length > 0 && + evt.getParent("phaseDiscard").player == event.player + ); + }) + ) + return false; return true; }, - logTarget:'player', - content:function(){ - if(lib.skill.rehengjiang3.filterx(trigger,player)){ - var num=player.getHistory('useSkill',function(evt){ - return evt.skill=='rehengjiang'&&evt.targets.includes(trigger.player); + logTarget: "player", + content: function () { + if (lib.skill.rehengjiang3.filterx(trigger, player)) { + var num = player.getHistory("useSkill", function (evt) { + return evt.skill == "rehengjiang" && evt.targets.includes(trigger.player); }).length; - if(num>0) player.draw(num); - } - else player.draw(); + if (num > 0) player.draw(num); + } else player.draw(); }, }, - shuangren:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&&player.canCompare(current); - }) + shuangren: { + trigger: { player: "phaseUseBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && player.canCompare(current); + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var goon; - if(player.needsToDiscard()>1){ - goon=player.hasCard(function(card){ - return card.number>10&&get.value(card)<=5; + if (player.needsToDiscard() > 1) { + goon = player.hasCard(function (card) { + return card.number > 10 && get.value(card) <= 5; + }); + } else { + goon = player.hasCard(function (card) { + return (card.number >= 9 && get.value(card) <= 5) || get.value(card) <= 3; }); } - else{ - goon=player.hasCard(function(card){ - return (card.number>=9&&get.value(card)<=5)||get.value(card)<=3; - }); - } - player.chooseTarget(get.prompt2('shuangren'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player; - if(_status.event.goon&&get.attitude(player,target)<0){ - return get.effect(target,{name:'sha'},player,player); - } - return 0; - }).set('goon',goon).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('shuangren',target); + player + .chooseTarget(get.prompt2("shuangren"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + if (_status.event.goon && get.attitude(player, target) < 0) { + return get.effect(target, { name: "sha" }, player, player); + } + return 0; + }) + .set("goon", goon) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("shuangren", target); player.chooseToCompare(target); - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - var target=event.target; - if(game.hasPlayer(function(current){ - if(target==current) return false; - if(!player.canUse('sha',current,false)) return false; - return target.isFriendOf(current); - })){ - var str='对一名与'+get.translation(target)+'势力相同的'; - player.chooseTarget(str+'角色使用一张杀',true,function(card,player,target){ - if(!player.canUse('sha',target,false)) return false; - if(get.mode()=='guozhan'){ - return target.isFriendOf(_status.event.identity); - } - return true; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }).set('identity',target); - } - else{ - player.useCard({name:'sha',isCard:true},target,false); + "step 2"; + if (result.bool) { + var target = event.target; + if ( + game.hasPlayer(function (current) { + if (target == current) return false; + if (!player.canUse("sha", current, false)) return false; + return target.isFriendOf(current); + }) + ) { + var str = "对一名与" + get.translation(target) + "势力相同的"; + player + .chooseTarget(str + "角色使用一张杀", true, function (card, player, target) { + if (!player.canUse("sha", target, false)) return false; + if (get.mode() == "guozhan") { + return target.isFriendOf(_status.event.identity); + } + return true; + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }) + .set("identity", target); + } else { + player.useCard({ name: "sha", isCard: true }, target, false); event.finish(); } - } - else{ - player.addTempSkill('zishou2'); + } else { + player.addTempSkill("zishou2"); event.finish(); } - 'step 3' - if(result.bool&&result.targets&&result.targets.length){ - player.useCard({name:'sha',isCard:true},result.targets[0],false); + "step 3"; + if (result.bool && result.targets && result.targets.length) { + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); } - } + }, }, - kuanshi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('kuanshi')).set('ai',function(target){ - if(get.attitude(_status.event.player,target)>0){ - return 1/Math.sqrt(target.hp+1); + kuanshi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("kuanshi")).set("ai", function (target) { + if (get.attitude(_status.event.player, target) > 0) { + return 1 / Math.sqrt(target.hp + 1); } return 0; - }).animate=false; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('kuanshi'); - target.storage.kuanshi2=player; - target.addSkill('kuanshi2'); + }).animate = false; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("kuanshi"); + target.storage.kuanshi2 = player; + target.addSkill("kuanshi2"); } - } + }, }, - kuanshi2:{ + kuanshi2: { /*mark:'character', intro:{ content:'下一次受到超过1点的伤害时,防止此伤害,然后$跳过下个回合的摸牌阶段' },*/ - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return event.num>1; + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return event.num > 1; }, //priority:-11, - content:function(){ + content: function () { trigger.cancel(); - player.storage.kuanshi2.skip('phaseDraw'); - player.removeSkill('kuanshi2'); + player.storage.kuanshi2.skip("phaseDraw"); + player.removeSkill("kuanshi2"); }, - group:'kuanshi2_remove', - onremove:true, - subSkill:{ - remove:{ - trigger:{global:['phaseZhunbeiBegin','dieAfter']}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player==player.storage.kuanshi2; + group: "kuanshi2_remove", + onremove: true, + subSkill: { + remove: { + trigger: { global: ["phaseZhunbeiBegin", "dieAfter"] }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.kuanshi2; }, - content:function(){ - player.removeSkill('kuanshi2'); - } - } - } - }, - xiashu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + content: function () { + player.removeSkill("kuanshi2"); + }, + }, }, - content:function(){ - 'step 0' - var maxval=0; - var hs=player.getCards('h'); - for(var i=0;i 0; + }, + content: function () { + "step 0"; + var maxval = 0; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { + maxval = Math.max(maxval, get.value(hs[i])); } - player.chooseTarget(get.prompt2('xiashu'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - var maxval=_status.event.maxval; - var dh=target.countCards('h')-player.countCards('h'); - var att=get.attitude(player,target); - if(target.hasSkill('qingjian')) return false; - if(dh<=0) return 0; - if(att>0) return 0.1; - if(maxval>=8) return 0; - if(att==0) return 0.2; - if(dh>=3) return dh; - if(dh==2){ - if(maxval<=7) return dh; - } - if(maxval<=6) return dh; - return 0; - }).set('maxval',maxval); - 'step 1' - if(result.bool){ - player.logSkill('xiashu',result.targets); - event.target=result.targets[0]; - var hs=player.getCards('h'); - player.give(hs,event.target); - } - else{ + player + .chooseTarget(get.prompt2("xiashu"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + var maxval = _status.event.maxval; + var dh = target.countCards("h") - player.countCards("h"); + var att = get.attitude(player, target); + if (target.hasSkill("qingjian")) return false; + if (dh <= 0) return 0; + if (att > 0) return 0.1; + if (maxval >= 8) return 0; + if (att == 0) return 0.2; + if (dh >= 3) return dh; + if (dh == 2) { + if (maxval <= 7) return dh; + } + if (maxval <= 6) return dh; + return 0; + }) + .set("maxval", maxval); + "step 1"; + if (result.bool) { + player.logSkill("xiashu", result.targets); + event.target = result.targets[0]; + var hs = player.getCards("h"); + player.give(hs, event.target); + } else { event.finish(); } - 'step 2' - var hs=event.target.getCards('h'); - if(!hs.length){ + "step 2"; + var hs = event.target.getCards("h"); + if (!hs.length) { event.finish(); return; } - hs.sort(function(a,b){ - return get.value(b,player,'raw')-get.value(a,player,'raw'); + hs.sort(function (a, b) { + return get.value(b, player, "raw") - get.value(a, player, "raw"); }); - event.target.chooseCard([1,hs.length],'展示至少一张手牌',true).set('ai',function(card){ - var rand=_status.event.rand; - var list=_status.event.list; - if(_status.event.att){ - if(ui.selected.cards.length>=Math.ceil(list.length/2)) return 0; - var value=get.value(card); - if(_status.event.getParent().player.isHealthy()){ - value+=(get.tag(card,'damage')?1.5:0)+(get.tag(card,'draw')?2:0); + event.target + .chooseCard([1, hs.length], "展示至少一张手牌", true) + .set("ai", function (card) { + var rand = _status.event.rand; + var list = _status.event.list; + if (_status.event.att) { + if (ui.selected.cards.length >= Math.ceil(list.length / 2)) return 0; + var value = get.value(card); + if (_status.event.getParent().player.isHealthy()) { + value += + (get.tag(card, "damage") ? 1.5 : 0) + (get.tag(card, "draw") ? 2 : 0); + } + return value; } - return value; - } - if(ui.selected.cards.length>=Math.floor(list.length/2)) return 0; - return (list.indexOf(card)%2==rand)?1:0; - }).set('rand',(Math.random()<0.6)?1:0).set('list',hs).set('att',get.attitude(event.target,player)>0); - 'step 3' + if (ui.selected.cards.length >= Math.floor(list.length / 2)) return 0; + return list.indexOf(card) % 2 == rand ? 1 : 0; + }) + .set("rand", Math.random() < 0.6 ? 1 : 0) + .set("list", hs) + .set("att", get.attitude(event.target, player) > 0); + "step 3"; event.target.showCards(result.cards); - event.cards1=result.cards; - event.cards2=event.target.getCards('h',function(card){ + event.cards1 = result.cards; + event.cards2 = event.target.getCards("h", function (card) { return !event.cards1.includes(card); }); - 'step 4' + "step 4"; var choice; - var num1=event.cards1.length; - var num2=event.cards2.length; - if(get.attitude(event.target,player)>0&&num1>=num2){ - choice=0; - } - else if(num1==num2){ - choice=(Math.random()<0.45)?0:1; - } - else if(num1>num2){ - if(num1-num2==1){ - choice=(Math.random()<0.6)?0:1; + var num1 = event.cards1.length; + var num2 = event.cards2.length; + if (get.attitude(event.target, player) > 0 && num1 >= num2) { + choice = 0; + } else if (num1 == num2) { + choice = Math.random() < 0.45 ? 0 : 1; + } else if (num1 > num2) { + if (num1 - num2 == 1) { + choice = Math.random() < 0.6 ? 0 : 1; + } else { + choice = 0; } - else{ - choice=0; + } else { + if (num2 - num1 == 1) { + choice = Math.random() < 0.6 ? 1 : 0; + } else { + choice = 1; } } - else{ - if(num2-num1==1){ - choice=(Math.random()<0.6)?1:0; - } - else{ - choice=1; - } - } - player.chooseControl(function(event,player){ - return _status.event.choice; - }).set('choiceList',['获得'+get.translation(event.target)+'展示的牌', - '获得'+get.translation(event.target)+'未展示的牌']).set('choice',choice); - 'step 5' - if(result.index==0){ - player.gain(event.cards1,target,'give','bySelf'); - } - else{ - player.gain(event.cards2,target,'giveAuto','bySelf'); + player + .chooseControl(function (event, player) { + return _status.event.choice; + }) + .set("choiceList", [ + "获得" + get.translation(event.target) + "展示的牌", + "获得" + get.translation(event.target) + "未展示的牌", + ]) + .set("choice", choice); + "step 5"; + if (result.index == 0) { + player.gain(event.cards1, target, "give", "bySelf"); + } else { + player.gain(event.cards2, target, "giveAuto", "bySelf"); } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - sheyan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - filter:function(event,player){ - if(!event.targets||!event.targets.includes(player)) return false; - var info=get.info(event.card); - if(info.type!='trick') return false; - if(info.multitarget) return false; - if(event.targets.length>1) return true; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,event.player,current); + sheyan: { + audio: 2, + trigger: { target: "useCardToTarget" }, + filter: function (event, player) { + if (!event.targets || !event.targets.includes(player)) return false; + var info = get.info(event.card); + if (info.type != "trick") return false; + if (info.multitarget) return false; + if (event.targets.length > 1) return true; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, event.player, current) + ); }); }, - direct:true, - content:function(){ - 'step 0' - var bool1=(trigger.targets.length>1); - var bool2=game.hasPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,trigger.player,current); + direct: true, + content: function () { + "step 0"; + var bool1 = trigger.targets.length > 1; + var bool2 = game.hasPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ); }); - if(bool1&&bool2){ - player.chooseControlList(get.prompt('sheyan'),['为'+get.translation(trigger.card)+'增加一个目标','为'+get.translation(trigger.card)+'减少一个目标'],function(event,player){ - if(_status.event.add) return 0; - return 1; - }).set('add',get.effect(player,trigger.card,trigger.player,player)>=0); - } - else if(bool2){ - event.type='add'; + if (bool1 && bool2) { + player + .chooseControlList( + get.prompt("sheyan"), + [ + "为" + get.translation(trigger.card) + "增加一个目标", + "为" + get.translation(trigger.card) + "减少一个目标", + ], + function (event, player) { + if (_status.event.add) return 0; + return 1; + } + ) + .set("add", get.effect(player, trigger.card, trigger.player, player) >= 0); + } else if (bool2) { + event.type = "add"; event.goto(2); - event.unchosen=true; - } - else{ - event.type='remove'; + event.unchosen = true; + } else { + event.type = "remove"; event.goto(2); - event.unchosen=true; + event.unchosen = true; } - 'step 1' - if(result.control=='cancel2'){ + "step 1"; + if (result.control == "cancel2") { + event.finish(); + } else if (result.index == 1) { + event.type = "remove"; + } else { + event.type = "add"; + } + "step 2"; + if (event.type == "add") { + player + .chooseTarget( + event.unchosen ? get.prompt("sheyan") : null, + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return ( + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(trigger.card, trigger.player, target) + ); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, trigger.player, _status.event.player); + }); + } else { + player + .chooseTarget( + event.unchosen ? get.prompt("sheyan") : null, + "为" + get.translation(trigger.card) + "减少一个目标", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + return -get.effect( + target, + trigger.card, + trigger.player, + _status.event.player + ); + }) + .set("targets", trigger.targets); + } + "step 3"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - else if(result.index==1){ - event.type='remove'; - } - else{ - event.type='add'; - } - 'step 2' - if(event.type=='add'){ - player.chooseTarget(event.unchosen?get.prompt('sheyan'):null,'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return !trigger.targets.includes(target)&&lib.filter.targetEnabled2(trigger.card,trigger.player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,trigger.player,_status.event.player); - }); - } - else{ - player.chooseTarget(event.unchosen?get.prompt('sheyan'):null,'为'+get.translation(trigger.card)+'减少一个目标',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - return -get.effect(target,trigger.card,trigger.player,_status.event.player); - }).set('targets',trigger.targets); - } - 'step 3' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.target=result.targets[0]; - } - else{ - event.finish(); - } - 'step 4' - player.logSkill('sheyan',event.target); - if(event.type=='add'){ + "step 4"; + player.logSkill("sheyan", event.target); + if (event.type == "add") { trigger.targets.push(event.target); - } - else{ + } else { trigger.getParent().excluded.add(event.target); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - bingzheng:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('bingzheng'),function(card,player,target){ - return target.countCards('h')!=target.hp; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - var nh=target.countCards('h'); - if(att>0){ - if(nh==target.hp-1){ - if(player==target) return att+1; - return att+2; + bingzheng: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("bingzheng"), function (card, player, target) { + return target.countCards("h") != target.hp; + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var nh = target.countCards("h"); + if (att > 0) { + if (nh == target.hp - 1) { + if (player == target) return att + 1; + return att + 2; + } + if (player == target && player.needsToDiscard()) return att / 3; + return att; + } else { + if (nh == target.hp + 1) return -att; + if (nh == 0) return 0; + return -att / 2; } - if(player==target&&player.needsToDiscard()) return att/3; - return att; + }); + "step 1"; + if (result.bool) { + player.logSkill("bingzheng", result.targets); + event.target = result.targets[0]; + if (event.target.countCards("h")) { + player + .chooseControl(function (event, player) { + var target = event.target; + if (get.attitude(player, target) < 0) return 1; + return 0; + }) + .set("choiceList", [ + "令" + get.translation(event.target) + "摸一张牌", + "令" + get.translation(event.target) + "弃置一张手牌", + ]); + } else { + event.directfalse = true; } - else{ - if(nh==target.hp+1) return -att; - if(nh==0) return 0; - return -att/2; - } - }); - 'step 1' - if(result.bool){ - player.logSkill('bingzheng',result.targets); - event.target=result.targets[0]; - if(event.target.countCards('h')){ - player.chooseControl(function(event,player){ - var target=event.target; - if(get.attitude(player,target)<0) return 1; - return 0; - }).set('choiceList',['令'+get.translation(event.target)+'摸一张牌', - '令'+get.translation(event.target)+'弃置一张手牌']); - } - else{ - event.directfalse=true; - } - } - else{ + } else { event.finish(); } - 'step 2' - if(event.directfalse||result.index==0){ + "step 2"; + if (event.directfalse || result.index == 0) { event.target.draw(); + } else { + event.target.chooseToDiscard("h", true); } - else{ - event.target.chooseToDiscard('h',true); - } - 'step 3' - if(event.target.countCards('h')==event.target.hp){ + "step 3"; + if (event.target.countCards("h") == event.target.hp) { player.draw(); - if(event.target==player){ + if (event.target == player) { event.finish(); return; } - var next=player.chooseCard('是否交给'+get.translation(event.target)+'一张牌?','he'); - next.set('ai',function(card){ - if(get.position(card)!='h') return 0; - if(_status.event.shan&&card.name=='shan'){ + var next = player.chooseCard( + "是否交给" + get.translation(event.target) + "一张牌?", + "he" + ); + next.set("ai", function (card) { + if (get.position(card) != "h") return 0; + if (_status.event.shan && card.name == "shan") { return 11; } - if(_status.event.goon){ - return 10-get.value(card); + if (_status.event.goon) { + return 10 - get.value(card); } - return -get.value(card,_status.event.player,'raw'); + return -get.value(card, _status.event.player, "raw"); }); - if(get.attitude(player,event.target)>1&& - player.countCards('h','shan')>1&&player.countCards('h')>event.target.countCards('h')){ - next.set('shan',true); + if ( + get.attitude(player, event.target) > 1 && + player.countCards("h", "shan") > 1 && + player.countCards("h") > event.target.countCards("h") + ) { + next.set("shan", true); } - if(get.attitude(player,event.target)>0&&player.needsToDiscard()){ - next.set('goon',true); + if (get.attitude(player, event.target) > 0 && player.needsToDiscard()) { + next.set("goon", true); } - } - else{ + } else { event.finish(); } - 'step 4' - if(result.bool){ - player.give(result.cards,target); + "step 4"; + if (result.bool) { + player.give(result.cards, target); } }, - ai:{ - expose:0.2, - threaten:1.4 - } + ai: { + expose: 0.2, + threaten: 1.4, + }, }, - fuman:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - if(target==player) return false; - var stat=player.getStat('skill').fuman_targets; - return !stat||!stat.includes(target); + fuman: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + if (target == player) return false; + var stat = player.getStat("skill").fuman_targets; + return !stat || !stat.includes(target); }, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer((current)=>lib.skill.fuman.filterTarget(null,player,current)); + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer((current) => lib.skill.fuman.filterTarget(null, player, current)) + ); }, - discard:false, - lose:false, - delay:false, - filterCard:true, - content:function(){ - player.give(cards,target).gaintag.add('fuman'); - target.addSkill('fuman2'); - player.addSkill('fuman_draw'); - var stat=player.getStat('skill'); - if(!stat.fuman_targets) stat.fuman_targets=[]; + discard: false, + lose: false, + delay: false, + filterCard: true, + content: function () { + player.give(cards, target).gaintag.add("fuman"); + target.addSkill("fuman2"); + player.addSkill("fuman_draw"); + var stat = player.getStat("skill"); + if (!stat.fuman_targets) stat.fuman_targets = []; stat.fuman_targets.push(target); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(!target.hasSha()) return 1.2; + ai: { + order: 2, + result: { + target: function (player, target) { + if (!target.hasSha()) return 1.2; return 1; - } - } + }, + }, }, - subSkill:{ - draw:{ - trigger:{global:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('fuman')) return true; + subSkill: { + draw: { + trigger: { global: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("fuman")) return true; } return false; }); }, - logTarget:'player', - content:function(){ - player.draw(trigger.player.hasHistory('sourceDamage',function(evt){ - return evt.card==trigger.card; - })?2:1); + logTarget: "player", + content: function () { + player.draw( + trigger.player.hasHistory("sourceDamage", function (evt) { + return evt.card == trigger.card; + }) + ? 2 + : 1 + ); }, }, }, }, - fuman2:{ - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('fuman')) return num+1; + fuman2: { + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("fuman")) return num + 1; }, - cardname:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('fuman')) return 'sha'; + cardname: function (card, player) { + if (get.itemtype(card) == "card" && card.hasGaintag("fuman")) return "sha"; }, }, }, - qizhou:{ - trigger:{player:['phaseBefore','equipEnd','loseEnd']}, - forced:true, - popup:false, - derivation:['mashu','reyingzi','reduanbing','fenwei'], - filter:function(event,player){ - if(player.equiping) return false; - var suits=[]; - var es=player.getCards('e'); - for(var i=0;i0; + if (player.additionalSkills.qizhou) { + return player.additionalSkills.qizhou.length != suits.length; + } else { + return suits.length > 0; } }, - content:function(){ - var suits=[]; - var es=player.getCards('e'); - for(var i=0;i0; - } - if(player.hasSha()&&geteff(target)){ - var num=game.countPlayer(function(current){ - return current!=player&&get.distance(player,current)<=1&&geteff(current); + var geteff = function (current) { + return ( + player.canUse("sha", current, false, true) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }; + if (player.hasSha() && geteff(target)) { + var num = game.countPlayer(function (current) { + return ( + current != player && + get.distance(player, current) <= 1 && + geteff(current) + ); }); - if(num==0){ - if(game.hasPlayer(function(current){ - return player.canUse('sha',current)&&geteff(current)&¤t!=target; - })){ + if (num == 0) { + if ( + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + geteff(current) && + current != target + ); + }) + ) { return 1; } - } - else if(num==1){ + } else if (num == 1) { return 1; } } return 0; - } - } - } - }, - fenxun2:{ - mark:'character', - onremove:true, - intro:{ - content:'到$的距离视为1' + }, + }, }, - mod:{ - globalFrom:function(from,to){ - if(from.getStorage('fenxun2').includes(to)){ + }, + fenxun2: { + mark: "character", + onremove: true, + intro: { + content: "到$的距离视为1", + }, + mod: { + globalFrom: function (from, to) { + if (from.getStorage("fenxun2").includes(to)) { return -Infinity; } - } - } + }, + }, }, - duanbing:{ - audio:2, - audioname:['heqi'], - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&get.distance(player,current)<=1&&player.canUse(event.card,current); + duanbing: { + audio: 2, + audioname: ["heqi"], + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + get.distance(player, current) <= 1 && + player.canUse(event.card, current) + ); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('duanbing'),'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&get.distance(player,target)<=1&&player.canUse(_status.event.card,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.delayx(); - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("duanbing"), + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + get.distance(player, target) <= 1 && + player.canUse(_status.event.card, 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.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - player.logSkill('duanbing',event.target); + "step 2"; + player.logSkill("duanbing", event.target); trigger.targets.push(event.target); }, - ai:{ - effect:{ - player:function(card,player,target,current,isLink){ - if(!isLink&&card.name=='sha'){ - if(player._duanbingtmp) return; - player._duanbingtmp=true; - if(get.effect(target,card,player,player)<=0){ + ai: { + effect: { + player: function (card, player, target, current, isLink) { + if (!isLink && card.name == "sha") { + if (player._duanbingtmp) return; + player._duanbingtmp = true; + if (get.effect(target, card, player, player) <= 0) { delete player._duanbingtmp; return; } - if(game.hasPlayer(function(current){ - return current!=target&&get.distance(player,current)<=1&& - player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ + if ( + game.hasPlayer(function (current) { + return ( + current != target && + get.distance(player, current) <= 1 && + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { delete player._duanbingtmp; - return [1,1]; + return [1, 1]; } delete player._duanbingtmp; } - } - } - } + }, + }, + }, }, - fuhan:{ - audio:2, - trigger:{player:'phaseBegin'}, - unique:true, - limited:true, - skillAnimation:true, - animationColor:'orange', - forceunique:true, - filter:function(event,player){ - return player.storage.fanghun2>0; + fuhan: { + audio: 2, + trigger: { player: "phaseBegin" }, + unique: true, + limited: true, + skillAnimation: true, + animationColor: "orange", + forceunique: true, + filter: function (event, player) { + return player.storage.fanghun2 > 0; }, - prompt:function(event,player){ - var num=Math.max(2,player.storage.fanghun2||0); - num=Math.min(num,8); - return get.prompt('fuhan')+'(体力上限:'+num+')'; + prompt: function (event, player) { + var num = Math.max(2, player.storage.fanghun2 || 0); + num = Math.min(num, 8); + return get.prompt("fuhan") + "(体力上限:" + num + ")"; }, - check:function(event,player){ - var num=Math.max(2,player.storage.fanghun2||0); - if(num==1) return false; - if(player.hp<=1) return true; - if(num==2) return false; - if(num==3) return player.hp<3&&player.isMinHp(); + check: function (event, player) { + var num = Math.max(2, player.storage.fanghun2 || 0); + if (num == 1) return false; + if (player.hp <= 1) return true; + if (num == 2) return false; + if (num == 3) return player.hp < 3 && player.isMinHp(); return true; }, - content:function(){ - 'step 0' - if(player.storage.fanghun) player.draw(player.storage.fanghun); - player.removeMark('fanghun',player.storage.fanghun); - event.num=Math.max(2,player.storage.fanghun2||0); + content: function () { + "step 0"; + if (player.storage.fanghun) player.draw(player.storage.fanghun); + player.removeMark("fanghun", player.storage.fanghun); + event.num = Math.max(2, player.storage.fanghun2 || 0); var list; - if(_status.characterlist){ - list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - var name=_status.characterlist[i]; - if(lib.character[name][1]=='shu') list.push(name); + if (_status.characterlist) { + list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + var name = _status.characterlist[i]; + if (lib.character[name][1] == "shu") list.push(name); } - } - else if(_status.connectMode){ - list=get.charactersOL(function(i){ - return lib.character[i][1]!='shu'; + } else if (_status.connectMode) { + list = get.charactersOL(function (i) { + return lib.character[i][1] != "shu"; + }); + } else { + list = get.gainableCharacters(function (info) { + return info[1] == "shu"; }); } - else{ - list=get.gainableCharacters(function(info){ - return info[1]=='shu'; - }); - } - var players=game.players.concat(game.dead); - for(var i=0;i0) player.gainMaxHp(num); + player + .chooseButton(true) + .set("ai", function (button) { + return get.rank(button.link, true) - lib.character[button.link][2]; + }) + .set("createDialog", ["将武将牌替换为一名角色", [list.randomGets(5), "character"]]); + player.awakenSkill("fuhan"); + "step 1"; + event.num = Math.min(event.num, 8); + player.reinitCharacter("zhaoxiang", result.links[0]); + "step 2"; + var num = event.num - player.maxHp; + if (num > 0) player.gainMaxHp(num); else player.loseMaxHp(-num); player.recover(); - } - }, - refuhan:{ - audio:'fuhan', - trigger:{player:'phaseZhunbeiBegin'}, - unique:true, - limited:true, - skillAnimation:true, - animationColor:'orange', - forceunique:true, - filter:function(event,player){ - return player.countMark('fanghun')>0; }, - content:function(){ - 'step 0' - if(player.storage.fanghun) player.draw(player.storage.fanghun); - player.removeMark('fanghun',player.storage.fanghun); - player.awakenSkill('refuhan'); - 'step 1' + ai: { + combo: "fanghun", + }, + }, + refuhan: { + audio: "fuhan", + trigger: { player: "phaseZhunbeiBegin" }, + unique: true, + limited: true, + skillAnimation: true, + animationColor: "orange", + forceunique: true, + filter: function (event, player) { + return player.countMark("fanghun") > 0; + }, + content: function () { + "step 0"; + if (player.storage.fanghun) player.draw(player.storage.fanghun); + player.removeMark("fanghun", player.storage.fanghun); + player.awakenSkill("refuhan"); + "step 1"; var list; - if(_status.characterlist){ - list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - var name=_status.characterlist[i]; - if(lib.character[name][1]=='shu') list.push(name); + if (_status.characterlist) { + list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + var name = _status.characterlist[i]; + if (lib.character[name][1] == "shu") list.push(name); } - } - else if(_status.connectMode){ - list=get.charactersOL(function(i){ - return lib.character[i][1]!='shu'; + } else if (_status.connectMode) { + list = get.charactersOL(function (i) { + return lib.character[i][1] != "shu"; + }); + } else { + list = get.gainableCharacters(function (info) { + return info[1] == "shu"; }); } - else{ - list=get.gainableCharacters(function(info){ - return info[1]=='shu'; - }); - } - var players=game.players.concat(game.dead); - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(!this.classList.contains('bluebg')){ - if(rSkill.length>=2) return; + td.innerHTML = "" + get.translation(skills[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (!this.classList.contains("bluebg")) { + if (rSkill.length >= 2) return; rSkill.add(link); - this.classList.add('bluebg'); - } - else{ - this.classList.remove('bluebg'); + this.classList.add("bluebg"); + } else { + this.classList.remove("bluebg"); rSkill.remove(link); } }); } dialog.content.appendChild(table); - dialog.add('  '); + dialog.add("  "); dialog.open(); - event.switchToAuto=function(){ + event.switchToAuto = function () { event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok',function(link){ + event.control = ui.create.control("ok", function (link) { event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;i0; - if(name=='jiu') return player.countCards('hs','tao')>0; + fanghun: { + hiddenCard: function (player, name) { + if (!player.storage.fanghun || player.storage.fanghun <= 0) return false; + if (name == "tao") return player.countCards("hs", "jiu") > 0; + if (name == "jiu") return player.countCards("hs", "tao") > 0; return false; }, - audio:2, - marktext:'影', - intro:{ - content:'mark', - name:'梅影', + audio: 2, + marktext: "影", + intro: { + content: "mark", + name: "梅影", }, - trigger:{ - source:'damageSource', - player:'damageEnd', + trigger: { + source: "damageSource", + player: "damageEnd", }, - forced:true, - locked:false, - filter:function(event){ - return event.card&&event.card.name=='sha'; + forced: true, + locked: false, + filter: function (event) { + return event.card && event.card.name == "sha"; }, - content:function(){ - player.addMark('fanghun',trigger.num||1); - player.addMark('fanghun2',trigger.num||1,false); + content: function () { + player.addMark("fanghun", trigger.num || 1); + player.addMark("fanghun2", trigger.num || 1, false); }, - group:['fanghun_sha','fanghun_draw'], - subSkill:{ - draw:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - popup:false, - filter:function(event){ - return event.skill=='fanghun_sha'||event.skill=='fanghun_shan'; + group: ["fanghun_sha", "fanghun_draw"], + subSkill: { + draw: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + popup: false, + filter: function (event) { + return event.skill == "fanghun_sha" || event.skill == "fanghun_shan"; }, - content:function(){ + content: function () { player.draw(); - } + }, }, - sha:{ - audio:'fanghun', - inherit:'ollongdan', - enable:['chooseToUse','chooseToRespond'], - prompt:'弃置一枚【梅影】标记,将杀当做闪,或将闪当做杀,或将桃当做酒,或将酒当做桃使用或打出', - filter:function(event,player){ - return player.hasMark('fanghun')&&get.info('ollongdan').filter(event,player); + sha: { + audio: "fanghun", + inherit: "ollongdan", + enable: ["chooseToUse", "chooseToRespond"], + prompt: "弃置一枚【梅影】标记,将杀当做闪,或将闪当做杀,或将桃当做酒,或将酒当做桃使用或打出", + filter: function (event, player) { + return player.hasMark("fanghun") && get.info("ollongdan").filter(event, player); }, - onrespond:function(){return this.onuse.apply(this,arguments)}, - onuse:function(result,player){ - player.removeMark('fanghun',1); + onrespond: function () { + return this.onuse.apply(this, arguments); }, - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ - if(!player.hasMark('fanghun')) return false; - return get.info('ollongdan').ai.skillTagFilter(player,tag); + onuse: function (result, player) { + player.removeMark("fanghun", 1); + }, + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { + if (!player.hasMark("fanghun")) return false; + return get.info("ollongdan").ai.skillTagFilter(player, tag); }, - order:function(item,player){ - if(!player||!player.storage){ - player=_status.event.player; - if(!player||!player.storage) return 0; - if(Object.keys(player.storage).some(i=>{ - return typeof i=='string'&&i.indexOf('fuhan')!=-1; - })) return 4; + order: function (item, player) { + if (!player || !player.storage) { + player = _status.event.player; + if (!player || !player.storage) return 0; + if ( + Object.keys(player.storage).some((i) => { + return typeof i == "string" && i.indexOf("fuhan") != -1; + }) + ) + return 4; return 1; } - const awakened=Object.keys(player.storage).some(i=>typeof i=='string'&&i.indexOf('fuhan')!=-1); - if(_status.event.type=='phase'){ - var max=0; - var list=['sha','tao','jiu']; - var map={sha:'shan',tao:'jiu',jiu:'tao'} - for(var i=0;i(name=='jiu'?1:0)&&player.getUseValue({name:name})>0){ - var temp=get.order({name:name}); - if(temp>max) max=temp; + const awakened = Object.keys(player.storage).some( + (i) => typeof i == "string" && i.indexOf("fuhan") != -1 + ); + if (_status.event.type == "phase") { + var max = 0; + var list = ["sha", "tao", "jiu"]; + var map = { sha: "shan", tao: "jiu", jiu: "tao" }; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + if ( + player.countCards("hs", map[name]) > (name == "jiu" ? 1 : 0) && + player.getUseValue({ name: name }) > 0 + ) { + var temp = get.order({ name: name }); + if (temp > max) max = temp; } } - if(max>0) max+=(awakened?0.3:-0.3); + if (max > 0) max += awakened ? 0.3 : -0.3; return max; } - return awakened?4:1; + return awakened ? 4 : 1; }, }, }, - } + }, }, - yjixi:{ - derivation:'rewangzun', - audio:'weidi', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - 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{ + yjixi: { + derivation: "rewangzun", + audio: "weidi", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + 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; + if (num >= 3) break; } } return true; }, - skillAnimation:true, - animationColor:'gray', - unique:true, - juexingji:true, - content:function(){ - 'step 0' - player.awakenSkill('yjixi'); + skillAnimation: true, + animationColor: "gray", + unique: true, + juexingji: true, + content: function () { + "step 0"; + player.awakenSkill("yjixi"); player.gainMaxHp(); player.recover(); - 'step 1' - var str='摸两张牌'; - var mode=get.mode(); - var choice='选项一'; - if(mode=='identity'||(mode=='versus'&&_status.mode=='four')){ - var list=[]; - var zhu=get.zhu(player); - if(zhu&&zhu!=player&&zhu.skills){ - for(var i=0;i=6) return 0; - return 20-num; - } - else{ - if(_status.event.player.needsToDiscard()) return 7-num; + check: function (card) { + var num = get.value(card); + if (get.color(card) == "black") { + if (num >= 6) return 0; + return 20 - num; + } else { + if (_status.event.player.needsToDiscard()) return 7 - num; } return 0; }, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.give(cards,target); - if(get.color(cards[0])=='black'){ - target.chooseToDiscard(2,'he','弃置两张牌,或令'+get.translation(player)+'摸两张牌').set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)<0); - } - else{ + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.give(cards, target); + if (get.color(cards[0]) == "black") { + target + .chooseToDiscard( + 2, + "he", + "弃置两张牌,或令" + get.translation(player) + "摸两张牌" + ) + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) < 0); + } else { event.finish(); } - 'step 1' - if(!result.bool){ + "step 1"; + if (!result.bool) { player.draw(2); } }, - ai:{ - order:8, - expose:0.2, - result:{ - target:function(player,target){ - if(ui.selected.cards.length&&get.color(ui.selected.cards[0])=='red'){ - if(target.countCards('h')0; + if (event.player != player) { + var hs = event.player.getCards("h"); + var evt = event.getl(player); + return ( + evt && + evt.cards2 && + evt.cards2.filter(function (card) { + return hs.includes(card) && get.color(card, player) == "black"; + }).length > 0 + ); } return false; }, - content:function(){ - var cards=trigger.getl(player).cards2; - game.countPlayer(function(current){ - if(current==player) return; - var hs=current.getCards('h'),cardsx=trigger.getg(current).filter(function(card){ - return hs.includes(card)&&cards.includes(card)&&get.color(card,player)=='black'; - }); - if(cardsx.length>0){ - current.addSkill('xiehui2'); - current.addGaintag(cards,'xiehui'); + content: function () { + var cards = trigger.getl(player).cards2; + game.countPlayer(function (current) { + if (current == player) return; + var hs = current.getCards("h"), + cardsx = trigger.getg(current).filter(function (card) { + return ( + hs.includes(card) && + cards.includes(card) && + get.color(card, player) == "black" + ); + }); + if (cardsx.length > 0) { + current.addSkill("xiehui2"); + current.addGaintag(cards, "xiehui"); } }); - } - }, - xiehui2:{ - mark:true, - intro:{ - content:'不能使用、打出或弃置得到的黑色牌', - }, - mod:{ - cardDiscardable:function(card,player){ - if(card.hasGaintag('xiehui')) return false; - }, - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('xiehui')) return false; - }, - }, - trigger:{player:'changeHp'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event){ - return event.num<0; - }, - content:function(){ - player.removeSkill('xiehui2'); - }, - onremove:function(player){ - player.removeGaintag('xiehui'); }, }, - shanjia:{ - sync:function(player){ - if(game.online) return; - var history=player.actionHistory; - var num=0; - for(var i=0;i0) player.markSkill('shanjia'); + player.storage.shanjia = num; + if (num > 0) player.markSkill("shanjia"); }, - audio:2, - intro:{ - content:function(storage){ - if(storage==0) return '未使用过装备牌'; - return '已使用过'+storage+'张装备牌'; - } + audio: 2, + intro: { + content: function (storage) { + if (storage == 0) return "未使用过装备牌"; + return "已使用过" + storage + "张装备牌"; + }, }, - group:'shanjia2', - trigger:{player:'phaseUseBegin'}, - frequent:true, - filter:function(event,player){ + group: "shanjia2", + trigger: { player: "phaseUseBegin" }, + frequent: true, + filter: function (event, player) { lib.skill.shanjia.sync(player); - return player.storage.shanjia>0; + return player.storage.shanjia > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; lib.skill.shanjia.sync(player); - player.draw(Math.min(7,player.storage.shanjia)); - 'step 1' - player.chooseToDiscard('he',Math.min(7,player.storage.shanjia),true); - 'step 2' - var useCard=false; - if(result.bool&&result.cards){ - for(var i=0;i0) - })){ - return 6-get.value(card); + shanjia2: { + trigger: { player: "useCard" }, + silent: true, + filter: function (event, player) { + return get.type(event.card) == "equip"; + }, + content: function () { + lib.skill.shanjia.sync(player); + }, + }, + zhanyi: { + enable: "phaseUse", + usable: 1, + audio: 2, + filterCard: true, + position: "he", + check: function (card) { + var player = _status.event.player; + if (player.hp < 3) return 0; + var type = get.type(card, "trick"); + if (type == "trick") { + return 6 - get.value(card); + } else if (type == "equip") { + if ( + player.hasSha() && + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current) && + get.attitude(player, current) < 0 && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { + return 6 - get.value(card); } } return 0; }, - content:function(){ + content: function () { player.loseHp(); - switch(get.type(cards[0],'trick')){ - case 'basic':player.addTempSkill('zhanyi_basic');break; - case 'equip':player.addTempSkill('zhanyi_equip');break; - case 'trick':player.addTempSkill('zhanyi_trick');player.draw(2);break; + switch (get.type(cards[0], "trick")) { + case "basic": + player.addTempSkill("zhanyi_basic"); + break; + case "equip": + player.addTempSkill("zhanyi_equip"); + break; + case "trick": + player.addTempSkill("zhanyi_trick"); + player.draw(2); + break; } }, - ai:{ - order:9.1, - result:{ - player:1 - } - } - }, - zhanyi_basic:{ - group:['zhanyi_basic_sha','zhanyi_basic_jiu','zhanyi_basic_tao'] - }, - zhanyi_basic_tao:{ - enable:'chooseToUse', - filterCard:{type:'basic'}, - viewAs:{name:'tao'}, - viewAsFilter:function(player){ - if(!player.countCards('h',{type:'basic'})) return false; - }, - prompt:'将一张基本牌当桃使用', - check:function(card){ - return 8-get.value(card); - }, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('h',{type:'basic'})) return false; + ai: { + order: 9.1, + result: { + player: 1, }, - save:true, - } - }, - zhanyi_basic_sha:{ - enable:'chooseToUse', - filterCard:{type:'basic'}, - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(!player.countCards('h',{type:'basic'})) return false; }, - prompt:'将一张基本牌当杀使用', - check:function(card){return 4-get.value(card)}, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('h',{type:'basic'})) return false; + }, + zhanyi_basic: { + group: ["zhanyi_basic_sha", "zhanyi_basic_jiu", "zhanyi_basic_tao"], + }, + zhanyi_basic_tao: { + enable: "chooseToUse", + filterCard: { type: "basic" }, + viewAs: { name: "tao" }, + viewAsFilter: function (player) { + if (!player.countCards("h", { type: "basic" })) return false; + }, + prompt: "将一张基本牌当桃使用", + check: function (card) { + return 8 - get.value(card); + }, + ai: { + skillTagFilter: function (player) { + if (!player.countCards("h", { type: "basic" })) return false; }, - respondSha:true, - } + save: true, + }, }, - zhanyi_basic_jiu:{ - enable:'chooseToUse', - filterCard:{type:'basic'}, - viewAs:{name:'jiu'}, - viewAsFilter:function(player){ - if(!player.countCards('h',{type:'basic'})) return false; + zhanyi_basic_sha: { + enable: "chooseToUse", + filterCard: { type: "basic" }, + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (!player.countCards("h", { type: "basic" })) return false; }, - prompt:'将一张基本牌当酒使用', - check:function(card){ - if(_status.event.type=='dying') return 1; - return 4-get.value(card); + prompt: "将一张基本牌当杀使用", + check: function (card) { + return 4 - get.value(card); }, - ai:{ - skillTagFilter:function(player){ - return player.countCards('h',{type:'basic'})>0&&player.hp<=0; + ai: { + skillTagFilter: function (player) { + if (!player.countCards("h", { type: "basic" })) return false; }, - save:true, - } - }, - zhanyi_equip:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return event.target.countCards('he')>0; + respondSha: true, }, - check:function(event,player){ - return get.attitude(player,event.target)<0; - }, - content:function(){ - trigger.target.chooseToDiscard('he',true,2); - } }, - zhanyi_trick:{ - mod:{ - targetInRange:function(){ + zhanyi_basic_jiu: { + enable: "chooseToUse", + filterCard: { type: "basic" }, + viewAs: { name: "jiu" }, + viewAsFilter: function (player) { + if (!player.countCards("h", { type: "basic" })) return false; + }, + prompt: "将一张基本牌当酒使用", + check: function (card) { + if (_status.event.type == "dying") return 1; + return 4 - get.value(card); + }, + ai: { + skillTagFilter: function (player) { + return player.countCards("h", { type: "basic" }) > 0 && player.hp <= 0; + }, + save: true, + }, + }, + zhanyi_equip: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return event.target.countCards("he") > 0; + }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + content: function () { + trigger.target.chooseToDiscard("he", true, 2); + }, + }, + zhanyi_trick: { + mod: { + targetInRange: function () { return true; - } - } + }, + }, }, - dingpan:{ - enable:'phaseUse', - filter:function(event,player){ + dingpan: { + enable: "phaseUse", + filter: function (event, player) { var num; - var mode=get.mode(); - if(mode=='identity'||mode=='doudizhu'){ - if(mode=='identity'&&_status.mode=='purple') num=player.getEnemies().length; - else num=get.population('fan'); - } - else if(mode=='versus'){ - if(!_status.mode||_status.mode!='two') num=player.getEnemies().length; - else{ - var target=game.findPlayer(x=>{ - var num=x.getFriends().length; - return !game.hasPlayer(y=>{ - return x!=y&&y.getFriends().length>num; + var mode = get.mode(); + if (mode == "identity" || mode == "doudizhu") { + if (mode == "identity" && _status.mode == "purple") num = player.getEnemies().length; + else num = get.population("fan"); + } else if (mode == "versus") { + if (!_status.mode || _status.mode != "two") num = player.getEnemies().length; + else { + var target = game.findPlayer((x) => { + var num = x.getFriends().length; + return !game.hasPlayer((y) => { + return x != y && y.getFriends().length > num; }); }); - num=(target?target.getFriends(true).length:1); + num = target ? target.getFriends(true).length : 1; } + } else { + num = 1; } - else{ - num=1; - } - if((player.getStat().skill.dingpan||0)>=num) return false; + if ((player.getStat().skill.dingpan || 0) >= num) return false; return true; }, - filterTarget:function(card,player,target){ - return target.countCards('e')>0; + filterTarget: function (card, player, target) { + return target.countCards("e") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.draw(); - 'step 1' - var goon=get.damageEffect(target,player,target)>=0; - if(!goon&&target.hp>=4&&get.attitude(player,target)<0){ - var es=target.getCards('e'); - for(var i=0;i=8){ - goon=true;break; + "step 1"; + var goon = get.damageEffect(target, player, target) >= 0; + if (!goon && target.hp >= 4 && get.attitude(player, target) < 0) { + var es = target.getCards("e"); + for (var i = 0; i < es.length; i++) { + if (get.equipValue(es[i], target) >= 8) { + goon = true; + break; } } } - target.chooseControl(function(){ - if(_status.event.goon) return '选项二'; - return '选项一'; - }).set('goon',goon).set('prompt','定叛').set('choiceList',['令'+get.translation(player)+'弃置你装备区里的一张牌','获得你装备区内的所有牌并受到1点伤害']); - 'step 2' - if(result.control=='选项一'){ - player.discardPlayerCard(target,true,'e'); + target + .chooseControl(function () { + if (_status.event.goon) return "选项二"; + return "选项一"; + }) + .set("goon", goon) + .set("prompt", "定叛") + .set("choiceList", [ + "令" + get.translation(player) + "弃置你装备区里的一张牌", + "获得你装备区内的所有牌并受到1点伤害", + ]); + "step 2"; + if (result.control == "选项一") { + player.discardPlayerCard(target, true, "e"); event.finish(); + } else { + target.gain(target.getCards("e"), "gain2"); } - else{ - target.gain(target.getCards('e'),'gain2'); - } - 'step 3' + "step 3"; game.delay(0.5); target.damage(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(get.damageEffect(target,player,target)>=0) return 2; - var att=get.attitude(player,target); - if(att==0) return 0; - var es=target.getCards('e'); - if(att>0&&(target.countCards('h')>2||target.needsToDiscard(1))) return 0; - if(es.length==1&&att>0) return 0; - for(var i=0;i0){ + ai: { + order: 7, + result: { + target: function (player, target) { + if (get.damageEffect(target, player, target) >= 0) return 2; + var att = get.attitude(player, target); + if (att == 0) return 0; + var es = target.getCards("e"); + if (att > 0 && (target.countCards("h") > 2 || target.needsToDiscard(1))) return 0; + if (es.length == 1 && att > 0) return 0; + for (var i = 0; i < es.length; i++) { + var val = get.equipValue(es[i], target); + if (val <= 4) { + if (att > 0) { return 1; } - } - else if(val>=7){ - if(att<0){ + } else if (val >= 7) { + if (att < 0) { return -1; } } } return 0; - } - } - } + }, + }, + }, }, - hongde:{ - audio:2, - trigger:{ - player:['loseAfter','gainAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + hongde: { + audio: 2, + trigger: { + player: ["loseAfter", "gainAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - filter:function(event,player){ - var num=event.getl(player).cards2.length; - if(event.getg) num=Math.max(num,event.getg(player).length) - return num>1; + direct: true, + filter: function (event, player) { + var num = event.getl(player).cards2.length; + if (event.getg) num = Math.max(num, event.getg(player).length); + return num > 1; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('hongde'),'令一名其他角色摸一张牌',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - player.logSkill('hongde',result.targets); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("hongde"), + "令一名其他角色摸一张牌", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + return get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("hongde", result.targets); result.targets[0].draw(); } - } + }, }, - ziyuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:function(card){ - var num=0; - for(var i=0;i0); - })){ + ai: { + order: function (skill, player) { + if ( + game.hasPlayer(function (current) { + return ( + current.hp < current.maxHp && + current != player && + get.recoverEffect(current, player, player) > 0 + ); + }) + ) { return 10; } return 1; }, - result:{ - player:function(player,target){ - if(get.attitude(player,target)<0) return -1; - var eff=get.recoverEffect(target,player,player); - if(eff<0) return 0; - if(eff>0){ - if(target.hp==1) return 3; + result: { + player: function (player, target) { + if (get.attitude(player, target) < 0) return -1; + var eff = get.recoverEffect(target, player, player); + if (eff < 0) return 0; + if (eff > 0) { + if (target.hp == 1) return 3; return 2; } - if(player.needsToDiscard()) return 1; + if (player.needsToDiscard()) return 1; return 0; - } + }, }, - threaten:1.3 - } + threaten: 1.3, + }, }, - jugu:{ - audio:2, - mod:{ - maxHandcard:function(player,num){ - return num+player.maxHp; - } + jugu: { + audio: 2, + mod: { + maxHandcard: function (player, num) { + return num + player.maxHp; + }, }, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ + content: function () { player.draw(player.maxHp); - } - }, - tuifeng:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - notemp:true, - filter:function(event,player){ - return player.countCards('he')>0; }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('tuifeng'),'he',[1,trigger.num]).set('ai',function(card){ - if(card.name=='du') return 20; - return 7-get.useful(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('tuifeng'); - player.addToExpansion(result.cards,player,'give').gaintag.add('tuifeng'); + }, + tuifeng: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + notemp: true, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + content: function () { + "step 0"; + player + .chooseCard(get.prompt2("tuifeng"), "he", [1, trigger.num]) + .set("ai", function (card) { + if (card.name == "du") return 20; + return 7 - get.useful(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("tuifeng"); + player.addToExpansion(result.cards, player, "give").gaintag.add("tuifeng"); } }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - marktext:'锋', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "锋", + intro: { + content: "expansion", + markcount: "expansion", + }, + group: "tuifeng2", + ai: { + threaten: 0.8, + maixie: true, + maixie_hp: true, }, - group:'tuifeng2', - ai:{ - threaten:0.8, - maixie:true, - maixie_hp:true - } }, - tuifeng2:{ - audio:'tuifeng', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('tuifeng').length>0; + tuifeng2: { + audio: "tuifeng", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("tuifeng").length > 0; }, - content:function(){ - var cards=player.getExpansions('tuifeng'); - player.draw(2*cards.length); - player.addTempSkill('tuifeng3'); - player.addMark('tuifeng3',cards.length,false); + content: function () { + var cards = player.getExpansions("tuifeng"); + player.draw(2 * cards.length); + player.addTempSkill("tuifeng3"); + player.addMark("tuifeng3", cards.length, false); player.loseToDiscardpile(cards); - } - }, - tuifeng3:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('tuifeng3'); - } }, - onremove:true, - charlotte:true, }, - weidi:{ - init(player){ - const list=[]; - const zhu=get.zhu(player); - if(zhu&&zhu!=player&&zhu.skills){ - for(var i=0;i { - return lib.skill[skill] && lib.skill[skill].zhuSkill; - }) || event.addSkill.some(skill => { - return lib.skill[skill] && lib.skill[skill].zhuSkill; - })); + if (event.name == "gameStart") return true; + return ( + event.player == zhu && + (event.addSkill.some((skill) => { + return lib.skill[skill] && lib.skill[skill].zhuSkill; + }) || + event.addSkill.some((skill) => { + return lib.skill[skill] && lib.skill[skill].zhuSkill; + })) + ); }, - async content (event, trigger, player) { + async content(event, trigger, player) { lib.skill.weidi.init(player); }, }, - zhenlue:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event){ - return get.type(event.card)=='trick'; + zhenlue: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event) { + return get.type(event.card) == "trick"; }, - content:function(){ - trigger.nowuxie=true; + content: function () { + trigger.nowuxie = true; }, - mod:{ - targetEnabled:function(card,player,target){ - if(get.type(card)=='delay'){ + mod: { + targetEnabled: function (card, player, target) { + if (get.type(card) == "delay") { return false; } }, - } + }, }, - jianshu:{ - audio:2, - unique:true, - limited:true, - enable:'phaseUse', - animationColor:'thunder', - skillAnimation:'epic', - filter:function(event,player){ - return !player.storage.jianshu&&player.countCards('h',{color:'black'})>0; + jianshu: { + audio: 2, + unique: true, + limited: true, + enable: "phaseUse", + animationColor: "thunder", + skillAnimation: "epic", + filter: function (event, player) { + return !player.storage.jianshu && player.countCards("h", { color: "black" }) > 0; }, - init:function(player){ - player.storage.jianshu=false; + init: function (player) { + player.storage.jianshu = false; }, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(ui.selected.targets.length){ - return ui.selected.targets[0]!=target&&!ui.selected.targets[0].hasSkillTag('noCompareSource')&&target.countCards('h') - &&!target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + if (target == player) return false; + if (ui.selected.targets.length) { + return ( + ui.selected.targets[0] != target && + !ui.selected.targets[0].hasSkillTag("noCompareSource") && + target.countCards("h") && + !target.hasSkillTag("noCompareTarget") + ); } return true; }, - filterCard:{color:'black'}, - mark:true, - discard:false, - lose:false, - delay:false, - check:function(card){ - if(_status.event.player.hp==1) return 8-get.value(card); - return 6-get.value(card); + filterCard: { color: "black" }, + mark: true, + discard: false, + lose: false, + delay: false, + check: function (card) { + if (_status.event.player.hp == 1) return 8 - get.value(card); + return 6 - get.value(card); }, - selectTarget:2, - multitarget:true, - content:function(){ - 'step 0' - player.awakenSkill('jianshu'); - player.storage.jianshu=true; - player.give(cards,targets[0],'give'); - 'step 1' + selectTarget: 2, + multitarget: true, + content: function () { + "step 0"; + player.awakenSkill("jianshu"); + player.storage.jianshu = true; + player.give(cards, targets[0], "give"); + "step 1"; targets[0].chooseToCompare(targets[1]); - 'step 2' - if(result.bool){ - targets[0].chooseToDiscard('he',2,true); + "step 2"; + if (result.bool) { + targets[0].chooseToDiscard("he", 2, true); targets[1].loseHp(); - } - else if(result.tie){ - targets[0].loseHp() - targets[1].loseHp() - } - else{ - targets[1].chooseToDiscard('he',2,true); + } else if (result.tie) { + targets[0].loseHp(); + targets[1].loseHp(); + } else { + targets[1].chooseToDiscard("he", 2, true); targets[0].loseHp(); } }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - ai:{ - expose:0.4, - order:4, - result:{ - target:function(player,target){ - if(player.hasUnknown()) return 0; - if(ui.selected.targets.length) return -1; + ai: { + expose: 0.4, + order: 4, + result: { + target: function (player, target) { + if (player.hasUnknown()) return 0; + if (ui.selected.targets.length) return -1; return -0.5; - } - } - } + }, + }, + }, }, - yongdi:{ - audio:2, - audioname:['xinping'], - unique:true, - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - animationColor:'thunder', - skillAnimation:'legend', - mark:true, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('yongdi'),function(card,player,target){ - return (target.hasSex('male')||target.name=='key_yuri')&&target!=player; - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<=1) return 0; - var mode=get.mode(); - if(mode=='identity'||(mode=='versus'&&(_status.mode=='four'||_status.mode=='guandu'))){ - if(target.name&&lib.character[target.name]){ - for(var i=0;i{ - if(target.hasSkill(skill)) return false; - var info=get.info(skill); - return info&&info.zhuSkill; + var skills = target.getStockSkills(true, true).filter((skill) => { + if (target.hasSkill(skill)) return false; + var info = get.info(skill); + return info && info.zhuSkill; }); - if(skills.length){ + if (skills.length) { target.addSkills(skills); } } }, - ai:{expose:0.2}, + ai: { expose: 0.2 }, }, - regushe:{ - audio:'gushe', - enable:'phaseUse', - filterTarget:function(card,player,target){ + regushe: { + audio: "gushe", + enable: "phaseUse", + filterTarget: function (card, player, target) { return player.canCompare(target); }, - selectTarget:[1,3], - filter:function(event,player){ - return (player.countMark('regushe')+player.countMark('regushe2')<7)&&player.countCards('h')>0; + selectTarget: [1, 3], + filter: function (event, player) { + return ( + player.countMark("regushe") + player.countMark("regushe2") < 7 && + player.countCards("h") > 0 + ); }, - multitarget:true, - multiline:true, - content:function(){ - player.addTempSkill('regushe2'); - player.chooseToCompare(targets).callback=lib.skill.regushe.callback; + multitarget: true, + multiline: true, + content: function () { + player.addTempSkill("regushe2"); + player.chooseToCompare(targets).callback = lib.skill.regushe.callback; }, - intro:{ - name:'饶舌', - content:'mark' + intro: { + name: "饶舌", + content: "mark", }, - callback:function(){ - 'step 0' - if(event.num1<=event.num2){ - target.chat(lib.skill.gushe.chat[player.countMark('regushe')]); + callback: function () { + "step 0"; + if (event.num1 <= event.num2) { + target.chat(lib.skill.gushe.chat[player.countMark("regushe")]); game.delay(); - player.addMark('regushe',1); - if(player.countMark('regushe')>=7){ + player.addMark("regushe", 1); + if (player.countMark("regushe") >= 7) { player.die(); } - } - else player.addMark('regushe2',1,false); - 'step 1' - if(event.num1<=event.num2){ - player.chooseToDiscard('he','弃置一张牌,或摸一张牌').set('ai',function(){return -1;}); - } - else event.goto(3); - 'step 2' - if(!result.bool){ + } else player.addMark("regushe2", 1, false); + "step 1"; + if (event.num1 <= event.num2) { + player.chooseToDiscard("he", "弃置一张牌,或摸一张牌").set("ai", function () { + return -1; + }); + } else event.goto(3); + "step 2"; + if (!result.bool) { player.draw(); } - 'step 3' - if(event.num1>=event.num2){ - target.chooseToDiscard('he','弃置一张牌,或令'+get.translation(player)+'摸一张牌').set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)<0); - } - else event.finish(); - 'step 4' - if(!result.bool) player.draw(); + "step 3"; + if (event.num1 >= event.num2) { + target + .chooseToDiscard("he", "弃置一张牌,或令" + get.translation(player) + "摸一张牌") + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) < 0); + } else event.finish(); + "step 4"; + if (!result.bool) player.draw(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - var num=ui.selected.targets.length+1; - if(num+player.countMark('regushe')<=6) return -1; - var hs=player.getCards('h'); - for(var i=0;i5&&player.countMark('regushe')+num<=6) return -1; + ai: { + order: 7, + result: { + target: function (player, target) { + var num = ui.selected.targets.length + 1; + if (num + player.countMark("regushe") <= 6) return -1; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { + if (get.value(hs[i]) <= 6) { + switch (hs[i].number) { + case 13: + return -1; + case 12: + if (player.countMark("regushe") + num <= 8) return -1; + break; + case 11: + if (player.countMark("regushe") + num <= 7) return -1; + break; + default: + if (hs[i].number > 5 && player.countMark("regushe") + num <= 6) + return -1; } } } return 0; }, - } + }, }, - marktext:'饶', + marktext: "饶", }, - regushe2:{ - charlotte:true, - onremove:true, + regushe2: { + charlotte: true, + onremove: true, }, - rejici:{ - audio:'jici', - trigger:{ - player:'compare', - target:'compare', + rejici: { + audio: "jici", + trigger: { + player: "compare", + target: "compare", }, - forced:true, - filter:function(event,player){ + forced: true, + filter: function (event, player) { // if(player!=event.target&&event.iwhile) return false; - return (player==event.player?event.num1:event.num2)<=player.countMark('regushe'); + return (player == event.player ? event.num1 : event.num2) <= player.countMark("regushe"); }, - content:function(){ - if(player==trigger.target||!trigger.iwhile){ - trigger[player==trigger.player?'num1':'num2']+=player.countMark('regushe'); - game.log(player,'的拼点牌点数+'+player.countMark('regushe')); + content: function () { + if (player == trigger.target || !trigger.iwhile) { + trigger[player == trigger.player ? "num1" : "num2"] += player.countMark("regushe"); + game.log(player, "的拼点牌点数+" + player.countMark("regushe")); } game.delayx(); // var cards=[trigger.card1]; @@ -19340,896 +24791,1015 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // } // cards=cards.filterInD(); - var cards=[]; - if(trigger.num1>trigger.num2) cards.push(trigger.card1); - if(trigger.num1 trigger.num2) cards.push(trigger.card1); + if (trigger.num1 < trigger.num2) cards.push(trigger.card2); + cards = cards.filterInD(); + if (cards.length) player.gain(cards, "gain2"); + }, + group: "rejici2", + ai: { + combo: "regushe", }, - group:'rejici2', }, - rejici2:{ - audio:'jici', - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'water', - filter:function(event,player){ - return event.source&&event.source.isIn(); + rejici2: { + audio: "jici", + trigger: { player: "die" }, + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "water", + filter: function (event, player) { + return event.source && event.source.isIn(); }, - logTarget:'source', - content:function(){ - var num=7-player.countMark('regushe'); - if(num>0) trigger.source.chooseToDiscard(num,true,'he'); + logTarget: "source", + content: function () { + var num = 7 - player.countMark("regushe"); + if (num > 0) trigger.source.chooseToDiscard(num, true, "he"); trigger.source.loseHp(); }, }, - gushe:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + gushe: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - selectTarget:[1,3], - filter:function(event,player){ - return player.countCards('h')>0; + selectTarget: [1, 3], + filter: function (event, player) { + return player.countCards("h") > 0; }, - multitarget:true, - multiline:true, - content:function(){ - player.chooseToCompare(targets).callback=lib.skill.gushe.callback; + multitarget: true, + multiline: true, + content: function () { + player.chooseToCompare(targets).callback = lib.skill.gushe.callback; }, - intro:{ - name:'饶舌', - content:'mark' + intro: { + name: "饶舌", + content: "mark", }, - chat:['粗鄙之语','天地不容','谄谀之臣','皓首匹夫,苍髯老贼','二臣贼子','断脊之犬','我从未见过有如此厚颜无耻之人!'], - callback:function(){ - 'step 0' - if(event.num1<=event.num2){ - target.chat(lib.skill.gushe.chat[player.countMark('gushe')]); + chat: [ + "粗鄙之语", + "天地不容", + "谄谀之臣", + "皓首匹夫,苍髯老贼", + "二臣贼子", + "断脊之犬", + "我从未见过有如此厚颜无耻之人!", + ], + callback: function () { + "step 0"; + if (event.num1 <= event.num2) { + target.chat(lib.skill.gushe.chat[player.countMark("gushe")]); game.delay(); - player.addMark('gushe',1); - if(player.countMark('gushe')>=7){ + player.addMark("gushe", 1); + if (player.countMark("gushe") >= 7) { player.die(); } } - 'step 1' - if(event.num1<=event.num2){ - player.chooseToDiscard('he','弃置一张牌,或摸一张牌').set('ai',function(){return -1;}); - } - else event.goto(3); - 'step 2' - if(!result.bool){ + "step 1"; + if (event.num1 <= event.num2) { + player.chooseToDiscard("he", "弃置一张牌,或摸一张牌").set("ai", function () { + return -1; + }); + } else event.goto(3); + "step 2"; + if (!result.bool) { player.draw(); } - 'step 3' - if(event.num1>=event.num2){ - target.chooseToDiscard('he','弃置一张牌,或令'+get.translation(player)+'摸一张牌').set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)<0); - } - else event.finish(); - 'step 4' - if(!result.bool) player.draw(); + "step 3"; + if (event.num1 >= event.num2) { + target + .chooseToDiscard("he", "弃置一张牌,或令" + get.translation(player) + "摸一张牌") + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) < 0); + } else event.finish(); + "step 4"; + if (!result.bool) player.draw(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - var num=ui.selected.targets.length+1; - if(num>3) num=3; - var hs=player.getCards('h'); - for(var i=0;i5&&player.countMark('gushe')+num<=6) return -1; + ai: { + order: 7, + result: { + target: function (player, target) { + var num = ui.selected.targets.length + 1; + if (num > 3) num = 3; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { + if (get.value(hs[i]) <= 6) { + switch (hs[i].number) { + case 13: + return -1; + case 12: + if (player.countMark("gushe") + num <= 8) return -1; + break; + case 11: + if (player.countMark("gushe") + num <= 7) return -1; + break; + default: + if (hs[i].number > 5 && player.countMark("gushe") + num <= 6) + return -1; } } } return 0; }, - } - } - }, - jici:{ - audio:2, - trigger:{player:'compare'}, - filter:function(event,player){ - return event.getParent().name=='gushe'&&!event.iwhile&&event.num1<=player.countMark('gushe'); + }, }, - content:function(){ - if(trigger.num10; + juesi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0&&player.inRange(target); + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0 && player.inRange(target); }, - filterCard:{name:'sha'}, - content:function(){ - 'step 0' - target.chooseToDiscard('he',true); - 'step 1' - if(target.hp>=player.hp&&result.bool&&result.cards[0].name!='sha'){ - player.useCard({name:'juedou',isCard:true},target); + filterCard: { name: "sha" }, + content: function () { + "step 0"; + target.chooseToDiscard("he", true); + "step 1"; + if (target.hp >= player.hp && result.bool && result.cards[0].name != "sha") { + player.useCard({ name: "juedou", isCard: true }, target); } }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(get.effect(target,{name:'juedou'},player,player)<=0){ + ai: { + order: 2, + result: { + target: function (player, target) { + if (get.effect(target, { name: "juedou" }, player, player) <= 0) { return 0; } - if(target.hpplayer.hp) return -0.1; + if (target.hp < player.hp) { + if (player.countCards("h") > player.hp) return -0.1; return 0; } - var hs1=target.getCards('h','sha'); - var hs2=player.getCards('h','sha'); - if(hs1.length>hs2.length){ + var hs1 = target.getCards("h", "sha"); + var hs2 = player.getCards("h", "sha"); + if (hs1.length > hs2.length) { return 0; } - var hsx=target.getCards('h'); - if(hsx.length>2&&hs2.length<=1&&hsx[0].number<6){ + var hsx = target.getCards("h"); + if (hsx.length > 2 && hs2.length <= 1 && hsx[0].number < 6) { return 0; } - if(hsx.length>3&&hs2.length<=1){ + if (hsx.length > 3 && hs2.length <= 1) { return 0; } - if(hs1.length>hs2.length-1&&hs1.length>0&&(hs2.length<=1||hs1[0].number>hs2[0].number)){ + if ( + hs1.length > hs2.length - 1 && + hs1.length > 0 && + (hs2.length <= 1 || hs1[0].number > hs2[0].number) + ) { return 0; } return -1; - } - } - } - }, - shefu:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - init:function(player){ - if(!player.storage.shefu) player.storage.shefu=[]; - if(!player.storage.shefu2) player.storage.shefu2=[]; - }, - filter:function(event,player){ - return player.countCards('he')>0; - }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - }, - intro:{ - content:'cards', - onunmark:function(storage,player){ - player.storage.shefu=[]; - player.storage.shefu2=[]; + }, }, - mark:function(dialog,content,player){ - if(content&&content.length){ + }, + }, + shefu: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + init: function (player) { + if (!player.storage.shefu) player.storage.shefu = []; + if (!player.storage.shefu2) player.storage.shefu2 = []; + }, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + intro: { + content: "cards", + onunmark: function (storage, player) { + player.storage.shefu = []; + player.storage.shefu2 = []; + }, + mark: function (dialog, content, player) { + if (content && content.length) { dialog.addAuto(content); - if(player.isUnderControl(true)){ - var str=''; - for(var i=0;i'+str+'') + dialog.add('
              ' + str + "
              "); } } }, }, - content:function(){ - 'step 0' - var list1=[],list2=[],list3=[]; - for(var i=0;inh2&&event.source.isIn()) return true; - if(nh1 nh2 && event.source.isIn()) return true; + if (nh1 < Math.min(5, nh2)) return true; }, - direct:true, - content:function(){ - "step 0" - var num1=player.countCards('h'); - var num2=trigger.source.countCards('h'); - var eh=player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'benyu'); + direct: true, + content: function () { + "step 0"; + var num1 = player.countCards("h"); + var num2 = trigger.source.countCards("h"); + var eh = player.countCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "benyu"); }); - var bool1=false,bool2=false; - if(num1num2&&trigger.source.isIn()) bool2=true; - if(bool1&&bool2){ - event.chosen=true; - player.chooseControl('cancel2').set('prompt',get.prompt('benyu',trigger.source)).set('choiceList',[ - '将手牌摸至'+get.cnNumber(Math.min(num2,5))+'张', - '弃置至少'+get.cnNumber(num2+1)+'张牌并对其造成1点伤害', - ]) - } - else if(bool2) event.goto(3); - "step 1" - if(event.chosen){ - if(result.control=='cancel2') event.finish(); - else if(result.index==1) event.goto(3); - else event._result={bool:true}; - } - else player.chooseBool(get.prompt('benyu',trigger.source),'将手牌摸至'+get.cnNumber(Math.min(trigger.source.countCards('h'),5))+'张'); - "step 2" - if(result.bool){ - player.logSkill('benyu',trigger.source); - player.drawTo(Math.min(trigger.source.countCards('h'),5)); + var bool1 = false, + bool2 = false; + if (num1 < Math.min(num2, 5)) bool1 = true; + if (eh > num2 && trigger.source.isIn()) bool2 = true; + if (bool1 && bool2) { + event.chosen = true; + player + .chooseControl("cancel2") + .set("prompt", get.prompt("benyu", trigger.source)) + .set("choiceList", [ + "将手牌摸至" + get.cnNumber(Math.min(num2, 5)) + "张", + "弃置至少" + get.cnNumber(num2 + 1) + "张牌并对其造成1点伤害", + ]); + } else if (bool2) event.goto(3); + "step 1"; + if (event.chosen) { + if (result.control == "cancel2") event.finish(); + else if (result.index == 1) event.goto(3); + else event._result = { bool: true }; + } else + player.chooseBool( + get.prompt("benyu", trigger.source), + "将手牌摸至" + get.cnNumber(Math.min(trigger.source.countCards("h"), 5)) + "张" + ); + "step 2"; + if (result.bool) { + player.logSkill("benyu", trigger.source); + player.drawTo(Math.min(trigger.source.countCards("h"), 5)); } event.finish(); - "step 3" - var num=trigger.source.countCards('h')+1; - var args=[[num,player.countCards('he')],'he']; - if(event.chosen){ - player.logSkill('benyu',trigger.source); + "step 3"; + var num = trigger.source.countCards("h") + 1; + var args = [[num, player.countCards("he")], "he"]; + if (event.chosen) { + player.logSkill("benyu", trigger.source); args.push(true); + } else { + args.push(get.prompt("benyu", trigger.source)); + args.push("弃置" + get.cnNumber(num) + "张牌并对其造成1点伤害"); } - else{ - args.push(get.prompt('benyu',trigger.source)); - args.push('弃置'+get.cnNumber(num)+'张牌并对其造成1点伤害'); - } - var next=player.chooseToDiscard.apply(player,args); - if(!event.chosen) next.logSkill=['benyu',trigger.source]; - next.set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - if(ui.selected.cards.length>=_status.event.num){ + var next = player.chooseToDiscard.apply(player, args); + if (!event.chosen) next.logSkill = ["benyu", trigger.source]; + next.set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + if (ui.selected.cards.length >= _status.event.num) { return -1; } - if(get.damageEffect(trigger.source,player,player)>0&&(get.value(card,player)<0||_status.event.num<=2)){ - return 8-get.value(card); + if ( + get.damageEffect(trigger.source, player, player) > 0 && + (get.value(card, player) < 0 || _status.event.num <= 2) + ) { + return 8 - get.value(card); } return -1; }); - next.set('num',num); - "step 4" - if(result.bool) trigger.source.damage(); + next.set("num", num); + "step 4"; + if (result.bool) trigger.source.damage(); }, }, - jili:{ - audio:2, - trigger:{ - global:'useCardToTarget' + jili: { + audio: 2, + trigger: { + global: "useCardToTarget", }, - forced:true, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)>0; + forced: true, + check: function (event, player) { + return get.effect(player, event.card, event.player, player) > 0; }, - filter:function(event,player){ - if(get.color(event.card)!='red') return false; - if(!event.targets) return false; - if(event.player==player) return false; - if(event.targets.includes(player)) return false; - if(get.info(event.card).multitarget) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - if(lib.filter.targetEnabled2(event.card,event.player,player)){ - for(var i=0;i0&&!player.hasSkill('zhidao2')&&!get.tag(card,'damage')&&(!lib.filter.targetEnabled(card,player,player)||get.effect(player,card,player)<=0)) return num+10; - } + trigger.player.line(player, "green"); }, - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return _status.currentPhase==player&&event.player.isIn()&& - event.player.countCards('hej')>0&&event.player!=player&&!player.hasSkill('zhidao2'); + }, + 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; + }, }, - forced:true, - content:function(){ - var num=0; - if(trigger.player.countCards('h')) num++; - if(trigger.player.countCards('e')) num++; - if(trigger.player.countCards('j')) num++; - if(num){ - player.gainPlayerCard(trigger.player,num,'hej',true).set('filterButton',function(button){ - for(var i=0;i 0 && + event.player != player && + !player.hasSkill("zhidao2") + ); + }, + forced: true, + content: function () { + var num = 0; + if (trigger.player.countCards("h")) num++; + if (trigger.player.countCards("e")) num++; + if (trigger.player.countCards("j")) num++; + if (num) { + player + .gainPlayerCard(trigger.player, num, "hej", true) + .set("filterButton", function (button) { + for (var i = 0; i < ui.selected.buttons.length; i++) { + if ( + get.position(button.link) == get.position(ui.selected.buttons[i].link) + ) + return false; + } + return true; + }); } - player.addTempSkill('zhidao2'); - } + player.addTempSkill("zhidao2"); + }, }, - zhidao2:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; - } - } + zhidao2: { + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; + }, + }, }, - luanzhan:{ - mod:{ - selectTarget:function(card,player,range){ - if(!player.storage.luanzhan) return; - if(range[1]==-1) return; - if(card.name=='sha') range[1]+=player.storage.luanzhan; - if(get.color(card)=='black'&&get.type(card)=='trick'){ - var info=get.info(card); - if(info.multitarget) return false; - range[1]+=player.storage.luanzhan; + luanzhan: { + mod: { + selectTarget: function (card, player, range) { + if (!player.storage.luanzhan) return; + if (range[1] == -1) return; + if (card.name == "sha") range[1] += player.storage.luanzhan; + if (get.color(card) == "black" && get.type(card) == "trick") { + var info = get.info(card); + if (info.multitarget) return false; + range[1] += player.storage.luanzhan; } }, }, - trigger:{source:'damageSource'}, - audio:2, - forced:true, - mark:true, - intro:{ - content:function(storage){ - return '可以额外指定'+storage+'个目标'; + trigger: { source: "damageSource" }, + audio: 2, + forced: true, + mark: true, + intro: { + content: function (storage) { + return "可以额外指定" + storage + "个目标"; + }, + }, + init: function (player) { + player.storage.luanzhan = 0; + }, + init2: function (player) { + player.markSkill("luanzhan"); + }, + content: function () { + if (typeof player.storage.luanzhan == "number") { + player.storage.luanzhan += trigger.num; + } else { + player.storage.luanzhan = trigger.num; + } + if (player.hasSkill("luanzhan")) { + player.markSkill("luanzhan"); } }, - init:function(player){ - player.storage.luanzhan=0; - }, - init2:function(player){ - player.markSkill('luanzhan'); - }, - content:function(){ - if(typeof player.storage.luanzhan=='number'){ - player.storage.luanzhan+=trigger.num; - } - else{ - player.storage.luanzhan=trigger.num; - } - if(player.hasSkill('luanzhan')){ - player.markSkill('luanzhan'); - } - }, - group:'luanzhan_cancel', - subSkill:{ - cancel:{ - audio:'luanzhan', - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(!player.storage.luanzhan) return false; - var check=false; - var card=event.card; - if(card.name=='sha'){ - check=true; - } - else if(get.color(card)=='black'&&get.type(card)=='trick'){ - var info=get.info(card); - if(!info.multitarget){ - check=true; - if(info.selectTarget==-1){ - check=false; - } - else if(Array.isArray(info.selectTarget)&&info.selectTarget[1]==-1){ - check=false; + group: "luanzhan_cancel", + subSkill: { + cancel: { + audio: "luanzhan", + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (!player.storage.luanzhan) return false; + var check = false; + var card = event.card; + if (card.name == "sha") { + check = true; + } else if (get.color(card) == "black" && get.type(card) == "trick") { + var info = get.info(card); + if (!info.multitarget) { + check = true; + if (info.selectTarget == -1) { + check = false; + } else if ( + Array.isArray(info.selectTarget) && + info.selectTarget[1] == -1 + ) { + check = false; } } } - if(check&&event.targets&&event.targets.length!player.hasSkill(skill)); - if(list.length==1) event._result={control:list[0]}; - else if(list.length>0){ - player.chooseControl(list).set('prompt','选择获得一项技能').set('ai',function(){ - if(_status.event.controls.includes('dangxian')) return 'dangxian'; - return _status.event.controls[0]; - }); - } - else event.finish(); - 'step 2' - if(result.control){ + "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 > 0) { + player + .chooseControl(list) + .set("prompt", "选择获得一项技能") + .set("ai", function () { + if (_status.event.controls.includes("dangxian")) return "dangxian"; + return _status.event.controls[0]; + }); + } else event.finish(); + "step 2"; + if (result.control) { player.addSkills(result.control); } }, - ai:{threaten:2}, + ai: { threaten: 2 }, }, - xiefang:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance-game.countPlayer(function(current){ - return current.hasSex('female'); - }); - } - } - }, - qizhi:{ - audio:2, - trigger:{ - player:'useCardToPlayered' + xiefang: { + mod: { + globalFrom: function (from, to, distance) { + return ( + distance - + game.countPlayer(function (current) { + return current.hasSex("female"); + }) + ); + }, }, - direct:true, - filter:function(event,player){ - if(!event.targets) return false; - if(!event.isFirstTarget) return false; - if(_status.currentPhase!=player) return false; - var type=get.type(event.card,'trick'); - if(type!='basic'&&type!='trick') return false; - if(event.noai) return false; - return game.hasPlayer(function(target){ - return !event.targets.includes(target)&&target.countCards('he')>0; + }, + qizhi: { + audio: 2, + trigger: { + player: "useCardToPlayered", + }, + direct: true, + filter: function (event, player) { + if (!event.targets) return false; + if (!event.isFirstTarget) return false; + if (_status.currentPhase != player) return false; + var type = get.type(event.card, "trick"); + if (type != "basic" && type != "trick") return false; + if (event.noai) return false; + return game.hasPlayer(function (target) { + return !event.targets.includes(target) && target.countCards("he") > 0; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('qizhi'),'弃置一名角色的一张牌,然后其摸一张牌',function(card,player,target){ - return !_status.event.targets.includes(target)&&target.countCards('he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - if(target==player) return 2; - if(get.attitude(player,target)<=0){ - return 1 - } - return 0.5; - }).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - player.getHistory('custom').push({qizhi:true}); - player.logSkill('qizhi',result.targets); - player.discardPlayerCard(result.targets[0],true,'he'); - event.target=result.targets[0]; - } - else{ + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("qizhi"), + "弃置一名角色的一张牌,然后其摸一张牌", + function (card, player, target) { + return !_status.event.targets.includes(target) && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (target == player) return 2; + if (get.attitude(player, target) <= 0) { + return 1; + } + return 0.5; + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + player.getHistory("custom").push({ qizhi: true }); + player.logSkill("qizhi", result.targets); + player.discardPlayerCard(result.targets[0], true, "he"); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' + "step 2"; event.target.draw(); }, }, - jinqu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - check:function(event,player){ - return player.getHistory('custom',function(evt){ - return evt.qizhi==true; - }).length>=player.countCards('h'); + jinqu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + check: function (event, player) { + return ( + player.getHistory("custom", function (evt) { + return evt.qizhi == true; + }).length >= player.countCards("h") + ); }, - prompt:function(event,player){ - var num=player.getHistory('custom',function(evt){ - return evt.qizhi==true; + prompt: function (event, player) { + var num = player.getHistory("custom", function (evt) { + return evt.qizhi == true; }).length; - return '进趋:是否摸两张牌并将手牌弃置至'+get.cnNumber(num)+'张?'; + return "进趋:是否摸两张牌并将手牌弃置至" + get.cnNumber(num) + "张?"; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(2); - 'step 1' - var dh=player.countCards('h')-player.getHistory('custom',function(evt){ - return evt.qizhi==true; - }).length; - if(dh>0){ - player.chooseToDiscard(dh,true); + "step 1"; + var dh = + player.countCards("h") - + player.getHistory("custom", function (evt) { + return evt.qizhi == true; + }).length; + if (dh > 0) { + player.chooseToDiscard(dh, true); } }, - ai:{combo:'qizhi'}, + ai: { combo: "qizhi" }, }, - jiaozi:{ - audio:2, - trigger:{player:'damageBegin3',source:'damageBegin1'}, - forced:true, - filter:function(event,player){ + jiaozi: { + audio: 2, + trigger: { player: "damageBegin3", source: "damageBegin1" }, + forced: true, + filter: function (event, player) { return player.isMaxHandcard(true); }, - content:function(){ + content: function () { trigger.num++; }, - ai:{presha:true}, + ai: { presha: true }, }, - jiqiao:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0; + jiqiao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; }, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt2('jiqiao'),[1,player.countCards('he',{type:'equip'})],'he',function(card){ - return get.type(card)=='equip'; - }).set('ai',function(card){ - if(card.name=='bagua') return 10; - return 7-get.value(card); - }).logSkill='jiqiao'; - 'step 1' - if(result.bool){ - event.cards=get.cards(2*result.cards.length); + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt2("jiqiao"), + [1, player.countCards("he", { type: "equip" })], + "he", + function (card) { + return get.type(card) == "equip"; + } + ) + .set("ai", function (card) { + if (card.name == "bagua") return 10; + return 7 - get.value(card); + }).logSkill = "jiqiao"; + "step 1"; + if (result.bool) { + event.cards = get.cards(2 * result.cards.length); player.showCards(event.cards); - } - else{ + } else { event.finish(); } - 'step 2' - var gained=[]; - var tothrow=[]; - for(var i=0;islot=='equip2'||slot=='equip5')) return false; + canBeDiscarded: function (card, source, player) { + if (!player.hasEmptySlot(5)) return; + if ( + get.position(card) == "e" && + get.subtypes(card).some((slot) => slot == "equip2" || slot == "equip5") + ) + return false; }, /*cardDiscardable:function (card,player){ if(player.getEquip(5)) return; if(get.position(card)=='e') return false; },*/ - } + }, }, - linglong_bagua:{ - audio:'linglong', - audioname2:{re_jsp_huangyueying:'relinglong'}, - inherit:'bagua_skill', - filter:function(event,player){ - if(!lib.skill.bagua_skill.filter(event,player)) return false; - if(!player.hasEmptySlot(2)) return false; + linglong_bagua: { + audio: "linglong", + audioname2: { re_jsp_huangyueying: "relinglong" }, + inherit: "bagua_skill", + filter: function (event, player) { + if (!lib.skill.bagua_skill.filter(event, player)) return false; + if (!player.hasEmptySlot(2)) return false; return true; }, - ai:{ - respondShan:true, - freeShan:true, - skillTagFilter(player,tag,arg){ - if(tag!=='respondShan'&&tag!=='freeShan') return; - if(!player.hasEmptySlot(2)||player.hasSkillTag('unequip2')) return false; - if(!arg||!arg.player) return true; - if(arg.player.hasSkillTag('unequip',false,{ - target:player - })) return false; + ai: { + respondShan: true, + freeShan: true, + skillTagFilter(player, tag, arg) { + if (tag !== "respondShan" && tag !== "freeShan") return; + if (!player.hasEmptySlot(2) || player.hasSkillTag("unequip2")) return false; + if (!arg || !arg.player) return true; + if ( + arg.player.hasSkillTag("unequip", false, { + target: player, + }) + ) + return false; return true; }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.subtype(card)=='equip2'){ - if(get.equipValue(card)<=7.5) return 0; + effect: { + target: function (card, player, target) { + if (player == target && get.subtype(card) == "equip2") { + if (get.equipValue(card) <= 7.5) return 0; } - if(target.getEquip(2)) return; - return lib.skill.bagua_skill.ai.effect.target.apply(this,arguments); - } - } + if (target.getEquip(2)) return; + return lib.skill.bagua_skill.ai.effect.target.apply(this, arguments); + }, + }, }, }, - zhenwei:{ - audio:2, - audioname:['re_wenpin'], - trigger:{ - global:'useCardToTarget' + zhenwei: { + audio: 2, + audioname: ["re_wenpin"], + trigger: { + global: "useCardToTarget", }, - direct:true, - filter:function(event,player){ - if(player==event.target||player==event.player) return false; - if(!player.countCards('he')) return false; - if(event.targets.length>1) return false; - if(!event.target) return false; - if(event.target.hp>=player.hp) return false; + direct: true, + filter: function (event, player) { + if (player == event.target || player == event.player) return false; + if (!player.countCards("he")) return false; + if (event.targets.length > 1) return false; + if (!event.target) return false; + if (event.target.hp >= player.hp) return false; - var card=event.card; - if(card.name=='sha') return true; - if(get.color(card)=='black'&&get.type(card,'trick')=='trick') return true; + var card = event.card; + if (card.name == "sha") return true; + if (get.color(card) == "black" && get.type(card, "trick") == "trick") return true; return false; }, - content:function(){ - "step 0" - var save=false; - if(get.attitude(player,trigger.target)>2){ - if(trigger.card.name=='sha'){ - if(player.countCards('h','shan')||player.getEquip(2)|| - trigger.target.hp==1||player.hp>trigger.target.hp+1){ - if(!trigger.target.countCards('h','shan')||trigger.target.countCards('h') 2) { + if (trigger.card.name == "sha") { + if ( + player.countCards("h", "shan") || + player.getEquip(2) || + trigger.target.hp == 1 || + player.hp > trigger.target.hp + 1 + ) { + if ( + !trigger.target.countCards("h", "shan") || + trigger.target.countCards("h") < player.countCards("h") + ) { + save = true; } } - } - else if(trigger.card.name=='juedou'&&trigger.target.hp==1){ - save=true; - } - else if(trigger.card.name=='shunshou'&& - get.attitude(player,trigger.player)<0&& - get.attitude(trigger.player,trigger.target)<0){ - save=true; + } else if (trigger.card.name == "juedou" && trigger.target.hp == 1) { + save = true; + } else if ( + trigger.card.name == "shunshou" && + get.attitude(player, trigger.player) < 0 && + get.attitude(trigger.player, trigger.target) < 0 + ) { + save = true; } } - var next=player.chooseToDiscard('he',get.prompt(event.name,trigger.target),'弃置一张牌,将'+get.translation(trigger.card)+'转移给自己,或令此牌对其无效'); - next.logSkill=[event.name,trigger.target]; - next.set('ai',function(card){ - if(_status.event.aisave){ - return 7-get.value(card); + var next = player.chooseToDiscard( + "he", + get.prompt(event.name, trigger.target), + "弃置一张牌,将" + get.translation(trigger.card) + "转移给自己,或令此牌对其无效" + ); + next.logSkill = [event.name, trigger.target]; + next.set("ai", function (card) { + if (_status.event.aisave) { + return 7 - get.value(card); } return 0; }); - next.set('aisave',save); - "step 1" - if(result.bool){ - player.chooseControl('转移','失效',function(){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - if(trigger.card.name=='sha'){ - if(player.countCards('h','shan')) return '转移'; - } - else if(trigger.card.name=='juedou'){ - if(player.countCards('h','sha')) return '转移'; - } - return '失效'; - }).set('prompt','将'+get.translation(trigger.card)+'转移给你,或令其失效'); - } - else{ + next.set("aisave", save); + "step 1"; + if (result.bool) { + player + .chooseControl("转移", "失效", function () { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + if (trigger.card.name == "sha") { + if (player.countCards("h", "shan")) return "转移"; + } else if (trigger.card.name == "juedou") { + if (player.countCards("h", "sha")) return "转移"; + } + return "失效"; + }) + .set("prompt", "将" + get.translation(trigger.card) + "转移给你,或令其失效"); + } else { event.finish(); } - "step 2" - if(result.control=='转移'){ + "step 2"; + if (result.control == "转移") { player.draw(); trigger.getParent().targets.remove(trigger.target); trigger.getParent().triggeredTargets2.remove(trigger.target); @@ -20237,1565 +25807,1792 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger.untrigger(); trigger.player.line(player); game.delayx(); - } - else{ - var cards=trigger.cards.filterInD(); - if(cards.length>0){ - trigger.player.addSkill('zhenwei2'); - trigger.player.addToExpansion(cards,'gain2').gaintag.add('zhenwei2'); + } else { + var cards = trigger.cards.filterInD(); + if (cards.length > 0) { + trigger.player.addSkill("zhenwei2"); + trigger.player.addToExpansion(cards, "gain2").gaintag.add("zhenwei2"); } - trigger.targets.length=0; - trigger.getParent().triggeredTargets2.length=0; + trigger.targets.length = 0; + trigger.getParent().triggeredTargets2.length = 0; } }, - ai:{ - threaten:1.1 - } + ai: { + threaten: 1.1, + }, }, - zhenwei2:{ - audio:false, - intro:{ - content:'expansion', - markcount:'expansion', + zhenwei2: { + audio: false, + intro: { + content: "expansion", + markcount: "expansion", }, - trigger:{global:'phaseEnd'}, - forced:true, - charlotte:true, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + trigger: { global: "phaseEnd" }, + forced: true, + charlotte: true, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + content: function () { + "step 0"; + var cards = player.getExpansions("zhenwei2"); + if (cards.length) player.gain(cards, "gain2"); + "step 1"; + player.removeSkill("zhenwei2"); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('zhenwei2'); - if(cards.length) player.gain(cards,'gain2'); - 'step 1' - player.removeSkill('zhenwei2'); - } }, - xunzhi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - locked:false, - init:function(player){ - player.storage.xunzhi=0; + xunzhi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + locked: false, + init: function (player) { + player.storage.xunzhi = 0; }, - filter:function(event,player){ - var previous=player.getPrevious(); - var next=player.getNext(); - if(previous&&next){ - return player.hp!=previous.hp&&player.hp!=next.hp; + filter: function (event, player) { + var previous = player.getPrevious(); + var next = player.getNext(); + if (previous && next) { + return player.hp != previous.hp && player.hp != next.hp; } return false; }, - check:function(event,player){ - return player.hp>=3&&player.countCards('h')>player.hp+1+player.storage.xunzhi; + check: function (event, player) { + return player.hp >= 3 && player.countCards("h") > player.hp + 1 + player.storage.xunzhi; }, - content:function(){ + content: function () { player.loseHp(); - player.storage.xunzhi+=2; + player.storage.xunzhi += 2; }, - mark:true, - intro:{ - content:function(storage,player){ - return '手牌上限+'+player.storage.xunzhi; - } + mark: true, + intro: { + content: function (storage, player) { + return "手牌上限+" + player.storage.xunzhi; + }, }, - mod:{ - maxHandcard:function(player,num){ - if(typeof player.storage.xunzhi=='number'){ - return num+player.storage.xunzhi; + mod: { + maxHandcard: function (player, num) { + if (typeof player.storage.xunzhi == "number") { + return num + player.storage.xunzhi; } - } - } + }, + }, }, - yawang:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - forced:true, - filter:function(event,player){ + yawang: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - check:function(event,player){ - var num=game.countPlayer(function(target){ - return target.hp==player.hp; + check: function (event, player) { + var num = game.countPlayer(function (target) { + return target.hp == player.hp; }); - if(!player.hasSkill('xunzhi2')){ - var nh=player.countCards('h'); - if(nh>5) return false; - if(num==3&&nh>3) return false; + if (!player.hasSkill("xunzhi2")) { + var nh = player.countCards("h"); + if (nh > 5) return false; + if (num == 3 && nh > 3) return false; } - return num>=3; + return num >= 3; }, - content:function(){ + content: function () { trigger.changeToZero(); - var num=game.countPlayer(function(target){ - return target.hp==player.hp; + var num = game.countPlayer(function (target) { + return target.hp == player.hp; }); - if(num){ + if (num) { player.draw(num); } - player.storage.yawang=num; - player.addTempSkill('yawang2'); - } - }, - yawang2:{ - mod:{ - cardEnabled:function(card,player){ - if(_status.currentPhase!=player) return; - if(player.countUsed()>=player.storage.yawang) return false; - }, - cardSavable:function(card,player){ - if(_status.currentPhase!=player) return; - if(player.countUsed()>=player.storage.yawang) return false; - } - } - }, - luoyan_tianxiang:{ - inherit:'tianxiang', - filter:function(event,player){ - if(!player.storage.xingwu||!player.storage.xingwu.length) return false; - if(player.hasSkill('tianxiang')) return false; - return lib.skill.tianxiang.filter(event,player); + player.storage.yawang = num; + player.addTempSkill("yawang2"); }, }, - luoyan_liuli:{ - inherit:'liuli', - filter:function(event,player){ - if(!player.storage.xingwu||!player.storage.xingwu.length) return false; - if(player.hasSkill('liuli')) return false; - return lib.skill.liuli.filter(event,player); + yawang2: { + mod: { + cardEnabled: function (card, player) { + if (_status.currentPhase != player) return; + if (player.countUsed() >= player.storage.yawang) return false; + }, + cardSavable: function (card, player) { + if (_status.currentPhase != player) return; + if (player.countUsed() >= player.storage.yawang) return false; + }, }, }, - luoyan:{ - group:['luoyan_tianxiang','luoyan_liuli'], + luoyan_tianxiang: { + inherit: "tianxiang", + filter: function (event, player) { + if (!player.storage.xingwu || !player.storage.xingwu.length) return false; + if (player.hasSkill("tianxiang")) return false; + return lib.skill.tianxiang.filter(event, player); + }, }, - xingwu:{ - audio:2, - group:['xingwu_color','xingwu_color2'], - subSkill:{ - color:{ - trigger:{player:'phaseZhunbeiBegin'}, - silent:true, - content:function(){ - player.storage.xingwu_color=['black','red']; - } - }, - color2:{ - trigger:{player:'useCard'}, - silent:true, - filter:function(event,player){ - return Array.isArray(player.storage.xingwu_color)&&_status.currentPhase==player; + luoyan_liuli: { + inherit: "liuli", + filter: function (event, player) { + if (!player.storage.xingwu || !player.storage.xingwu.length) return false; + if (player.hasSkill("liuli")) return false; + return lib.skill.liuli.filter(event, player); + }, + }, + luoyan: { + group: ["luoyan_tianxiang", "luoyan_liuli"], + ai: { + combo: "xingwu", + }, + }, + xingwu: { + audio: 2, + group: ["xingwu_color", "xingwu_color2"], + subSkill: { + color: { + trigger: { player: "phaseZhunbeiBegin" }, + silent: true, + content: function () { + player.storage.xingwu_color = ["black", "red"]; }, - content:function(){ + }, + color2: { + trigger: { player: "useCard" }, + silent: true, + filter: function (event, player) { + return ( + Array.isArray(player.storage.xingwu_color) && _status.currentPhase == player + ); + }, + content: function () { player.storage.xingwu_color.remove(get.color(trigger.card)); - } - } + }, + }, }, - trigger:{player:'phaseDiscardBegin'}, - direct:true, - filter:function(event,player){ - if(!player.storage.xingwu_color) return false; - var length=player.storage.xingwu_color.length; - if(length==0) return false; - var hs=player.getCards('h'); - if(hs.length==0) return false; - if(length==2) return true; - var color=player.storage.xingwu_color[0]; - for(var i=0;i0&& - get.attitude(player,current)<0) - })) return 0; + content: function () { + "step 0"; + player + .chooseCard(get.prompt("xingwu"), function (card) { + return _status.event.player.storage.xingwu_color.includes(get.color(card)); + }) + .set("ai", function (card) { + var player = _status.event.player; + if (player.storage.xingwu.length == 2) { + if ( + !game.hasPlayer(function (current) { + return ( + current != player && + current.hasSex("male") && + get.damageEffect(current, player, player) > 0 && + get.attitude(player, current) < 0 + ); + }) + ) + return 0; + } + return 7 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("xingwu"); + if (player.storage.xingwu.length < 2) { + player.$give(result.cards, player); } - return 7-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('xingwu'); - if(player.storage.xingwu.length<2){ - player.$give(result.cards,player); - } - player.lose(result.cards,ui.special); - player.storage.xingwu=player.storage.xingwu.concat(result.cards); - player.markSkill('xingwu'); - player.syncStorage('xingwu'); - } - else{ + player.lose(result.cards, ui.special); + player.storage.xingwu = player.storage.xingwu.concat(result.cards); + player.markSkill("xingwu"); + player.syncStorage("xingwu"); + } else { event.finish(); } - 'step 2' - if(player.storage.xingwu.length==3){ + "step 2"; + if (player.storage.xingwu.length == 3) { player.$throw(player.storage.xingwu); - while(player.storage.xingwu.length){ + while (player.storage.xingwu.length) { player.storage.xingwu.shift().discard(); } - player.unmarkSkill('xingwu'); - player.chooseTarget(function(card,player,target){ - return target!=player&&target.hasSex('male'); - },'对一名男性角色造成2点伤害并弃置其装备区内的牌').set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0) return -1; - return get.damageEffect(target,player,player)+target.countCards('e')/2; - }); - } - else{ + player.unmarkSkill("xingwu"); + player + .chooseTarget(function (card, player, target) { + return target != player && target.hasSex("male"); + }, "对一名男性角色造成2点伤害并弃置其装备区内的牌") + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) return -1; + return get.damageEffect(target, player, player) + target.countCards("e") / 2; + }); + } else { event.finish(); } - 'step 3' - if(result.bool){ - var target=result.targets[0]; + "step 3"; + if (result.bool) { + var target = result.targets[0]; target.damage(2); - event.target=target; - player.line(target,'green'); - } - else{ + event.target = target; + player.line(target, "green"); + } else { event.finish(); } - 'step 4' - if(event.target&&event.target.isIn()){ - var es=event.target.getCards('e'); - if(es.length){ + "step 4"; + if (event.target && event.target.isIn()) { + var es = event.target.getCards("e"); + if (es.length) { event.target.discard(es); } } }, - ai:{ - threaten:1.5 - } + ai: { + threaten: 1.5, + }, }, - yinbing:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - preHidden:true, - filter:function(event,player){ - return player.countCards('he',{type:'basic'})0&& - (event.card.name=='sha'||event.card.name=='juedou'); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + intro: { + content: "expansion", + markcount: "expansion", + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (card.name == "sha" || card.name == "juedou") { + if (current < 0) return 1.2; + } }, - content:function(){ - 'step 0' - player.chooseCardButton('移去一张引兵牌',true,player.getExpansions('yinbing')); - 'step 1' - if(result.bool) player.loseToDiscardpile(result.links); - } - } + }, + threaten: function (player, target) { + if (target.getExpansions("yinbing").length) return 2; + return 1; + }, + combo: "juedi", }, - group:'yinbing_discard' + subSkill: { + discard: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + player.getExpansions("yinbing").length > 0 && + (event.card.name == "sha" || event.card.name == "juedou") + ); + }, + content: function () { + "step 0"; + player.chooseCardButton("移去一张引兵牌", true, player.getExpansions("yinbing")); + "step 1"; + if (result.bool) player.loseToDiscardpile(result.links); + }, + }, + }, + group: "yinbing_discard", }, - juedi:{ - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getExpansions('yinbing').length>0; + juedi: { + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getExpansions("yinbing").length > 0; }, - forced:true, - audio:2, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('juedi'),true,function(card,player,target){ - return player.hp>=target.hp; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att<2) return att-10; - var num=att/10; - if(target==player){ - num+=player.maxHp-player.countCards('h')+0.5; - } - else{ - num+=_status.event.n2*2; - if(target.isDamaged()){ - if(target.hp==1){ - num+=3; - } - else if(target.hp==2){ - num+=2; - } - else{ - num+=0.5; + forced: true, + audio: 2, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("juedi"), true, function (card, player, target) { + return player.hp >= target.hp; + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att < 2) return att - 10; + var num = att / 10; + if (target == player) { + num += player.maxHp - player.countCards("h") + 0.5; + } else { + num += _status.event.n2 * 2; + if (target.isDamaged()) { + if (target.hp == 1) { + num += 3; + } else if (target.hp == 2) { + num += 2; + } else { + num += 0.5; + } } } - } - if(target.hasJudge('lebu')){ - num/=2; - } - return num; - }).set('n2',player.getExpansions('yinbing').length); - 'step 1' - if(result.bool){ - player.line(result.targets[0],'green'); - var cards=player.getExpansions('yinbing'); - if(result.targets[0]==player){ + if (target.hasJudge("lebu")) { + num /= 2; + } + return num; + }) + .set("n2", player.getExpansions("yinbing").length); + "step 1"; + if (result.bool) { + player.line(result.targets[0], "green"); + var cards = player.getExpansions("yinbing"); + if (result.targets[0] == player) { player.loseToDiscardpile(cards); - var num=player.maxHp-player.countCards('h'); - if(num>0) player.draw(num); - } - else{ - var target=result.targets[0]; + var num = player.maxHp - player.countCards("h"); + if (num > 0) player.draw(num); + } else { + var target = result.targets[0]; target.recover(); - player.give(cards,target,'give'); + player.give(cards, target, "give"); target.draw(cards.length); } } - } + }, + ai: { + combo: "yinbing", + }, }, - meibu:{ - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player!=player&&get.distance(event.player,player,'attack')>1; + meibu: { + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return event.player != player && get.distance(event.player, player, "attack") > 1; }, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)>=0) return false; - var e2=player.getEquip(2); - if(e2){ - if(e2.name=='tengjia'||e2.name=='rewrite_tengjia') return true; - if(e2.name=='bagua'||e2.name=='rewrite_bagua') return true; + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + var e2 = player.getEquip(2); + if (e2) { + if (e2.name == "tengjia" || e2.name == "rewrite_tengjia") return true; + if (e2.name == "bagua" || e2.name == "rewrite_bagua") return true; } - return player.countCards('h','shan')>0; + return player.countCards("h", "shan") > 0; }, - content:function(){ - var target=trigger.player; - target.addTempSkill('meibu_viewas'); - target.addTempSkill('meibu_range'); - target.storage.meibu=player; - target.markSkillCharacter('meibu',player,'魅步','锦囊牌均视为杀且'+get.translation(player)+'视为在攻击范围内'); + content: function () { + var target = trigger.player; + target.addTempSkill("meibu_viewas"); + target.addTempSkill("meibu_range"); + target.storage.meibu = player; + target.markSkillCharacter( + "meibu", + player, + "魅步", + "锦囊牌均视为杀且" + get.translation(player) + "视为在攻击范围内" + ); }, - ai:{ - expose:0.2 + ai: { + expose: 0.2, }, - subSkill:{ - range:{ - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&target==player.storage.meibu){ + subSkill: { + range: { + mod: { + targetInRange: function (card, player, target) { + if (card.name == "sha" && target == player.storage.meibu) { return true; } - } + }, }, - onremove:function(player){ - game.broadcast(function(player){ - if(player.marks.meibu){ + onremove: function (player) { + game.broadcast(function (player) { + if (player.marks.meibu) { player.marks.meibu.delete(); delete player.marks.meibu; } - },player); - if(player.marks.meibu){ + }, player); + if (player.marks.meibu) { player.marks.meibu.delete(); delete player.marks.meibu; - game.addVideo('unmark',player,'meibu'); + game.addVideo("unmark", player, "meibu"); } }, - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.skill=='meibu_viewas' + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.skill == "meibu_viewas"; }, - content:function(){ - player.removeSkill('meibu_viewas'); - game.broadcastAll(function(player){ - if(player.marks.meibu&&player.marks.meibu.info){ - player.marks.meibu.info.content=player.marks.meibu.info.content.slice(8); + content: function () { + player.removeSkill("meibu_viewas"); + game.broadcastAll(function (player) { + if (player.marks.meibu && player.marks.meibu.info) { + player.marks.meibu.info.content = + player.marks.meibu.info.content.slice(8); } - },player); - } + }, player); + }, }, - viewas:{ - mod:{ - cardEnabled:function(card,player){ - if(card.name!='sha'&&get.type(card,'trick')=='trick') return false; + viewas: { + mod: { + cardEnabled: function (card, player) { + if (card.name != "sha" && get.type(card, "trick") == "trick") return false; }, - cardUsable:function(card,player){ - if(card.name!='sha'&&get.type(card,'trick')=='trick') return false; + cardUsable: function (card, player) { + if (card.name != "sha" && get.type(card, "trick") == "trick") return false; }, - cardRespondable:function(card,player){ - if(card.name!='sha'&&get.type(card,'trick')=='trick') return false; + cardRespondable: function (card, player) { + if (card.name != "sha" && get.type(card, "trick") == "trick") return false; }, - cardSavable:function(card,player){ - if(card.name!='sha'&&get.type(card,'trick')=='trick') return false; + cardSavable: function (card, player) { + if (card.name != "sha" && get.type(card, "trick") == "trick") return false; }, }, - enable:['chooseToUse','chooseToRespond'], - filterCard:function(card){ - return get.type(card,'trick')=='trick'; + enable: ["chooseToUse", "chooseToRespond"], + filterCard: function (card) { + return get.type(card, "trick") == "trick"; }, - viewAs:{name:'sha'}, - check:function(){return 1}, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.8 - } + viewAs: { name: "sha" }, + check: function () { + return 1; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.8; + }, }, - respondSha:true, - order:4, - useful:-1, - value:-1 - } - } - } + respondSha: true, + order: 4, + useful: -1, + value: -1, + }, + }, + }, }, - mumu:{ - enable:'phaseUse', - usable:1, - filterCard:function(card,player,target){ - return card.name=='sha'||(get.type(card,'trick')=='trick'&&get.color(card)=='black'); + mumu: { + enable: "phaseUse", + usable: 1, + filterCard: function (card, player, target) { + return ( + card.name == "sha" || + (get.type(card, "trick") == "trick" && get.color(card) == "black") + ); }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - filterTarget:function(card,player,target){ - if(target==player) return false; - return target.getEquips(1).length>0||target.getEquips(2).length>0; + filterTarget: function (card, player, target) { + if (target == player) return false; + return target.getEquips(1).length > 0 || target.getEquips(2).length > 0; }, - content:function(){ - 'step 0' - var e1=target.getEquips(1); - var e2=target.getEquips(2); - event.e1=e1; - event.e2=e2; - if(e1.length&&e2.length){ - player.chooseControl('武器牌','防具牌').set('ai',function(){ - if(_status.event.player.getEquip(2)){ - return '武器牌'; + content: function () { + "step 0"; + var e1 = target.getEquips(1); + var e2 = target.getEquips(2); + event.e1 = e1; + event.e2 = e2; + if (e1.length && e2.length) { + player.chooseControl("武器牌", "防具牌").set("ai", function () { + if (_status.event.player.getEquip(2)) { + return "武器牌"; } - return '防具牌'; + return "防具牌"; }); + } else if (e1.length) { + event.choice = "武器牌"; + } else { + event.choice = "防具牌"; } - else if(e1.length){ - event.choice='武器牌'; - } - else{ - event.choice='防具牌'; - } - 'step 1' - var choice=event.choice||result.control; - if(choice=='武器牌'){ - if(event.e1){ + "step 1"; + var choice = event.choice || result.control; + if (choice == "武器牌") { + if (event.e1) { target.discard(event.e1); } player.draw(); - } - else{ - if(event.e2){ + } else { + if (event.e2) { player.equip(event.e2); - target.$give(event.e2,player); + target.$give(event.e2, player); } } }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(target.getEquip(2)&&!player.getEquip(2)){ + ai: { + order: 8, + result: { + target: function (player, target) { + if (target.getEquip(2) && !player.getEquip(2)) { return -2; } return -1; - } - } - } + }, + }, + }, }, - fentian:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - if(player.countCards('h')>=player.hp) return false; - return game.hasPlayer(function(current){ - return player!=current&&player.inRange(current)&¤t.countCards('he'); + fentian: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + if (player.countCards("h") >= player.hp) return false; + return game.hasPlayer(function (current) { + return player != current && player.inRange(current) && current.countCards("he"); }); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - 'step 0' - player.chooseTarget('焚天:选择一名攻击范围内的角色,将其一张牌置于你的武将牌上',true,function(card,player,target){ - return player!=target&&player.inRange(target)&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target) - }); - 'step 1' - if(result.bool){ - player.logSkill('fentian',result.targets); - event.target=result.targets[0]; - player.choosePlayerCard(result.targets[0],'he',true); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget( + "焚天:选择一名攻击范围内的角色,将其一张牌置于你的武将牌上", + true, + function (card, player, target) { + return ( + player != target && player.inRange(target) && target.countCards("he") > 0 + ); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("fentian", result.targets); + event.target = result.targets[0]; + player.choosePlayerCard(result.targets[0], "he", true); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.addToExpansion(result.links,target,'give').gaintag.add('fentian'); + "step 2"; + if (result.bool) { + player.addToExpansion(result.links, target, "give").gaintag.add("fentian"); } }, - mod:{ - attackRange:function(from,distance){ - return distance+from.getExpansions('fentian').length; - } - } + mod: { + attackRange: function (from, distance) { + return distance + from.getExpansions("fentian").length; + }, + }, }, - zhiri:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - juexingji:true, - audio:2, - skillAnimation:true, - animationColor:'fire', - derivation:'xintan', - filter:function(event,player){ - return player.getExpansions('fentian').length>=3; + zhiri: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + juexingji: true, + audio: 2, + skillAnimation: true, + animationColor: "fire", + derivation: "xintan", + filter: function (event, player) { + return player.getExpansions("fentian").length >= 3; }, - content:function(){ - player.awakenSkill('zhiri'); + content: function () { + player.awakenSkill("zhiri"); player.loseMaxHp(); - player.storage.zhiri=true; - } - }, - xintan:{ - enable:'phaseUse', - usable:1, - audio:2, - unique:true, - filter:function(event,player){ - return player.getExpansions('fentian').length>=2; + player.storage.zhiri = true; }, - filterTarget:true, - prompt:'移去两张“焚”并令一名角色失去1点体力', - content:function(){ - 'step 0' - player.chooseCardButton(2,'移去两张“焚”并令'+get.translation(target)+'失去1点体力',player.getExpansions('fentian'),true); - 'step 1' - if(result.bool){ + ai: { + combo: "fentian", + }, + }, + xintan: { + enable: "phaseUse", + usable: 1, + audio: 2, + unique: true, + filter: function (event, player) { + return player.getExpansions("fentian").length >= 2; + }, + filterTarget: true, + prompt: "移去两张“焚”并令一名角色失去1点体力", + content: function () { + "step 0"; + player.chooseCardButton( + 2, + "移去两张“焚”并令" + get.translation(target) + "失去1点体力", + player.getExpansions("fentian"), + true + ); + "step 1"; + if (result.bool) { player.loseToDiscardpile(result.links); target.loseHp(); } }, - ai:{ - order:8, - result:{ - target:-1 - } - } + ai: { + order: 8, + result: { + target: -1, + }, + combo: "fentian", + }, }, - danji:{ - skillAnimation:true, - animationColor:'water', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - juexingji:true, - derivation:['mashu','nuzhan'], - filter:function(event,player){ - var zhu=get.zhu(player); - if(zhu&&zhu.isZhu){ - var name=zhu.name - while(name.indexOf('_')!=-1){ - name=name.slice(name.indexOf('_')+1); + danji: { + skillAnimation: true, + animationColor: "water", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + juexingji: true, + derivation: ["mashu", "nuzhan"], + filter: function (event, player) { + var zhu = get.zhu(player); + if (zhu && zhu.isZhu) { + var name = zhu.name; + while (name.indexOf("_") != -1) { + name = name.slice(name.indexOf("_") + 1); } - if(name.indexOf('liubei')==0) return false; + if (name.indexOf("liubei") == 0) return false; } - return !player.storage.danji&&player.countCards('h')>player.hp; + return !player.storage.danji && player.countCards("h") > player.hp; }, - content:function(){ - player.awakenSkill('danji'); + content: function () { + player.awakenSkill("danji"); player.loseMaxHp(); - player.addSkills(['mashu','nuzhan']); + player.addSkills(["mashu", "nuzhan"]); }, - ai:{ - maixie:true, - skillTagFilter:(player,tag,arg)=>{ - if(tag==='maixie'){ - if(player.hp<2||player.storage.danji||player.hasSkill('nuzhan')||player.countCards('h')!==player.hp) return false; - let zhu=get.zhu(player); - if(zhu&&zhu.isZhu){ - let name=zhu.name; - while(name.indexOf('_')!==-1){ - name=name.slice(name.indexOf('_')+1); + ai: { + maixie: true, + skillTagFilter: (player, tag, arg) => { + if (tag === "maixie") { + if ( + player.hp < 2 || + player.storage.danji || + player.hasSkill("nuzhan") || + player.countCards("h") !== player.hp + ) + return false; + let zhu = get.zhu(player); + if (zhu && zhu.isZhu) { + let name = zhu.name; + while (name.indexOf("_") !== -1) { + name = name.slice(name.indexOf("_") + 1); } - if(name.indexOf('liubei')==0) return false; + if (name.indexOf("liubei") == 0) return false; } return true; } }, - effect:{ - target:(card,player,target)=>{ - let hs=target.countCards('h'); - if(target.hp<3||target.storage.danji||target.hasSkill('nuzhan')||hs>target.hp+1) return; - let zhu=get.zhu(target); - if(zhu&&zhu.isZhu){ - let name=zhu.name; - while(name.indexOf('_')!==-1){ - name=name.slice(name.indexOf('_')+1); + effect: { + target: (card, player, target) => { + let hs = target.countCards("h"); + if ( + target.hp < 3 || + target.storage.danji || + target.hasSkill("nuzhan") || + hs > target.hp + 1 + ) + return; + let zhu = get.zhu(target); + if (zhu && zhu.isZhu) { + let name = zhu.name; + while (name.indexOf("_") !== -1) { + name = name.slice(name.indexOf("_") + 1); } - if(name.indexOf('liubei')==0) return; + if (name.indexOf("liubei") == 0) return; } - if(get.tag(card,'draw')) return 1.6; - if(get.tag(card,'lose')||get.tag(card,'discard')) return [1,-0.8]; - if(hs===target.hp&&get.tag(card,'damage')) return [1,target.hp/3]; - if(hs>target.hp&&target.hp>3&&(card.name==='shan'||card.name==='wuxie')) return 'zeroplayertarget'; - } - } - } - }, - nuzhan:{ - audio:2, - popup:false, - silent:true, - firstDo:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.addCount!==false&&event.cards&& - event.cards.length==1&&get.type(event.cards[0],'trick')=='trick'; - }, - forced:true, - content:function(){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; - } - }, - group:'nuzhan2' - }, - nuzhan2:{ - audio:'nuzhan', - trigger:{player:'useCard1'}, - forced:true, - popup:false, - silent:true, - firstDo:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.cards&& - event.cards.length==1&&get.type(event.cards[0])=='equip'; - }, - content:function(){ - trigger.baseDamage++; - } - }, - jieyuan:{ - group:['jieyuan_more','jieyuan_less'], - subSkill:{ - more:{ - audio:true, - trigger:{source:'damageBegin1'}, - direct:true, - filter:function(event,player){ - if(!player.countCards(player.hasSkill('fenxin_nei')?'he':'h',function(card){ - if(player.hasSkill('fenxin_nei')||(_status.connectMode&&get.position(card)=='h')) return true; - return get.color(card)=='black'; - })) return false; - return (event.player.hp>=player.hp||player.hasSkill('fenxin_fan'))&&player!=event.player; + if (get.tag(card, "draw")) return 1.6; + if (get.tag(card, "lose") || get.tag(card, "discard")) return [1, -0.8]; + if (hs === target.hp && get.tag(card, "damage")) return [1, target.hp / 3]; + if ( + hs > target.hp && + target.hp > 3 && + (card.name === "shan" || card.name === "wuxie") + ) + return "zeroplayertarget"; }, - content:function(){ - 'step 0' - var goon=(get.attitude(player,trigger.player)<0); - var next=player.chooseToDiscard(get.prompt('jieyuan',trigger.player),player.hasSkill('fenxin_nei')?'he':'h'); - if(!player.hasSkill('fenxin_nei')){ - next.set('filterCard',function(card){ - return get.color(card)=='black'; + }, + }, + }, + nuzhan: { + audio: 2, + popup: false, + silent: true, + firstDo: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.addCount !== false && + event.cards && + event.cards.length == 1 && + get.type(event.cards[0], "trick") == "trick" + ); + }, + forced: true, + content: function () { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; + } + }, + group: "nuzhan2", + }, + nuzhan2: { + audio: "nuzhan", + trigger: { player: "useCard1" }, + forced: true, + popup: false, + silent: true, + firstDo: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.cards && + event.cards.length == 1 && + get.type(event.cards[0]) == "equip" + ); + }, + content: function () { + trigger.baseDamage++; + }, + }, + jieyuan: { + group: ["jieyuan_more", "jieyuan_less"], + subSkill: { + more: { + audio: true, + trigger: { source: "damageBegin1" }, + direct: true, + filter: function (event, player) { + if ( + !player.countCards( + player.hasSkill("fenxin_nei") ? "he" : "h", + function (card) { + if ( + player.hasSkill("fenxin_nei") || + (_status.connectMode && get.position(card) == "h") + ) + return true; + return get.color(card) == "black"; + } + ) + ) + return false; + return ( + (event.player.hp >= player.hp || player.hasSkill("fenxin_fan")) && + player != event.player + ); + }, + content: function () { + "step 0"; + var goon = get.attitude(player, trigger.player) < 0; + var next = player.chooseToDiscard( + get.prompt("jieyuan", trigger.player), + player.hasSkill("fenxin_nei") ? "he" : "h" + ); + if (!player.hasSkill("fenxin_nei")) { + next.set("filterCard", function (card) { + return get.color(card) == "black"; }); - next.set('prompt2','弃置一张黑色手牌令伤害+1'); + next.set("prompt2", "弃置一张黑色手牌令伤害+1"); + } else { + next.set("prompt2", "弃置一张手牌令伤害+1"); } - else{ - next.set('prompt2','弃置一张手牌令伤害+1'); - } - next.set('ai',function(card){ - if(_status.event.goon){ - return 8-get.value(card); + next.set("ai", function (card) { + if (_status.event.goon) { + return 8 - get.value(card); } return 0; }); - next.set('goon',goon); - next.logSkill=['jieyuan_more',trigger.player]; - 'step 1' - if(result.bool){ + next.set("goon", goon); + next.logSkill = ["jieyuan_more", trigger.player]; + "step 1"; + if (result.bool) { trigger.num++; } - } - }, - less:{ - audio:true, - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - if(!player.countCards(player.hasSkill('fenxin_nei')?'he':'h',function(card){ - if(player.hasSkill('fenxin_nei')||(_status.connectMode&&get.position(card)=='h')) return true; - return get.color(card)=='red'; - })) return false; - return event.source&&(event.source.hp>=player.hp||player.hasSkill('fenxin_zhong'))&&player!=event.source; }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('jieyuan'),player.hasSkill('fenxin_nei')?'he':'h'); - if(!player.hasSkill('fenxin_nei')){ - next.set('filterCard',function(card){ - return get.color(card)=='red'; + }, + less: { + audio: true, + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + if ( + !player.countCards( + player.hasSkill("fenxin_nei") ? "he" : "h", + function (card) { + if ( + player.hasSkill("fenxin_nei") || + (_status.connectMode && get.position(card) == "h") + ) + return true; + return get.color(card) == "red"; + } + ) + ) + return false; + return ( + event.source && + (event.source.hp >= player.hp || player.hasSkill("fenxin_zhong")) && + player != event.source + ); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + get.prompt("jieyuan"), + player.hasSkill("fenxin_nei") ? "he" : "h" + ); + if (!player.hasSkill("fenxin_nei")) { + next.set("filterCard", function (card) { + return get.color(card) == "red"; }); - next.set('prompt2','弃置一张红色手牌令伤害-1'); + next.set("prompt2", "弃置一张红色手牌令伤害-1"); + } else { + next.set("prompt2", "弃置一张手牌令伤害-1"); } - else{ - next.set('prompt2','弃置一张手牌令伤害-1'); - } - next.set('ai',function(card){ - var player=_status.event.player; - if(player.hp==1||_status.event.getTrigger().num>1){ - return 9-get.value(card); + next.set("ai", function (card) { + var player = _status.event.player; + if (player.hp == 1 || _status.event.getTrigger().num > 1) { + return 9 - get.value(card); } - if(player.hp==2){ - return 8-get.value(card); + if (player.hp == 2) { + return 8 - get.value(card); } - return 7-get.value(card); + return 7 - get.value(card); }); - next.logSkill='jieyuan_less'; - "step 1" - if(result.bool){ + next.logSkill = "jieyuan_less"; + "step 1"; + if (result.bool) { trigger.num--; } - } - } + }, + }, + }, + ai: { + expose: 0.2, + threaten: 1.5, }, - ai:{ - expose:0.2, - threaten:1.5 - } }, - fenxin:{ - mode:['identity','versus'], - available:function(mode){ - if(mode=='identity'&&_status.mode=='purple') return false; - if(mode=='versus'&&_status.mode!='two') return false; + fenxin: { + mode: ["identity", "versus"], + available: function (mode) { + if (mode == "identity" && _status.mode == "purple") return false; + if (mode == "versus" && _status.mode != "two") return false; }, - trigger:{global:['dieAfter','damageEnd']}, - filter:function(event,player){ - var list=['fan','zhong','nei']; - if(get.mode()=='identity') return event.name=='die'&&list.includes(event.player.identity)&&!player.hasSkill('fenxin_'+event.player.identity); - return event.name=='damage'&&event.player!=player&&list.some(identity=>!player.hasSkill('fenxin_'+identity))&&event.player.getHistory('damage').indexOf(event)==0; + trigger: { global: ["dieAfter", "damageEnd"] }, + filter: function (event, player) { + var list = ["fan", "zhong", "nei"]; + if (get.mode() == "identity") + return ( + event.name == "die" && + list.includes(event.player.identity) && + !player.hasSkill("fenxin_" + event.player.identity) + ); + return ( + event.name == "damage" && + event.player != player && + list.some((identity) => !player.hasSkill("fenxin_" + identity)) && + event.player.getHistory("damage").indexOf(event) == 0 + ); }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' - if(get.mode()=='identity'){ - event._result={ - bool:true, - links:['fenxin_'+trigger.player.identity], + forced: true, + logTarget: "player", + content: function () { + "step 0"; + if (get.mode() == "identity") { + event._result = { + bool: true, + links: ["fenxin_" + trigger.player.identity], }; + } else { + player + .chooseButton( + [ + "焚心:请选择〖竭缘〗的升级方式", + [ + [ + ["fenxin_fan", "发动〖竭缘〗增加伤害无体力值限制"], + ["fenxin_zhong", "发动〖竭缘〗减少伤害无体力值限制"], + ["fenxin_nei", "将〖竭缘〗中的黑色手牌和红色手牌改为一张牌"], + ].filter((list) => !player.hasSkill(list[0])), + "textbutton", + ], + ], + true + ) + .set("ai", function (button) { + return ["fenxin_fan", "fenxin_zhong", "fenxin_nei"].indexOf(button.link) + 1; + }); } - else{ - player.chooseButton([ - '焚心:请选择〖竭缘〗的升级方式', - [[ - ['fenxin_fan','发动〖竭缘〗增加伤害无体力值限制'], - ['fenxin_zhong','发动〖竭缘〗减少伤害无体力值限制'], - ['fenxin_nei','将〖竭缘〗中的黑色手牌和红色手牌改为一张牌'], - ].filter(list=>!player.hasSkill(list[0])),'textbutton'] - ],true).set('ai',function(button){ - return ['fenxin_fan','fenxin_zhong','fenxin_nei'].indexOf(button.link)+1; - }); - } - 'step 1' - if(result.bool){ - var identity=result.links[0]; + "step 1"; + if (result.bool) { + var identity = result.links[0]; player.addSkill(identity); - player.markSkill('fenxin'); + player.markSkill("fenxin"); } }, - intro:{ - mark:function(dialog,content,player){ - if(player.hasSkill('fenxin_zhong')){ - dialog.addText('你发动“竭缘”减少伤害无体力值限制'); + intro: { + mark: function (dialog, content, player) { + if (player.hasSkill("fenxin_zhong")) { + dialog.addText("你发动“竭缘”减少伤害无体力值限制"); } - if(player.hasSkill('fenxin_fan')){ - dialog.addText('你发动“竭缘”增加伤害无体力值限制'); + if (player.hasSkill("fenxin_fan")) { + dialog.addText("你发动“竭缘”增加伤害无体力值限制"); } - if(player.hasSkill('fenxin_nei')){ - dialog.addText('将“竭缘”中的黑色手牌和红色手牌改为一张牌'); + if (player.hasSkill("fenxin_nei")) { + dialog.addText("将“竭缘”中的黑色手牌和红色手牌改为一张牌"); } - } - }, - subSkill:{ - fan:{charlotte:true}, - zhong:{charlotte:true}, - nei:{charlotte:true} - }, - ai:{combo:'jieyuan'}, - }, - xisheng:{ - enable:'chooseToUse', - usable:1, - viewAs:{name:'tao'}, - viewAsFilter:function(player){ - return player!=_status.currentPhase&&player.countCards('hes')>1; - }, - selectCard:2, - filterCard:true, - position:'hes', - }, - shulv:{ - inherit:'zhiheng', - prompt:'弃置一张牌并摸一张牌', - selectCard:1, - filter:function(event,player){ - return player.countCards('hs')>player.hp; - }, - }, - xiandeng:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; }, - targetInRange:function(card,player){ - if(card.name=='sha'&&player.countUsed('sha',true)==0) return true; + }, + subSkill: { + fan: { charlotte: true }, + zhong: { charlotte: true }, + nei: { charlotte: true }, + }, + ai: { combo: "jieyuan" }, + }, + xisheng: { + enable: "chooseToUse", + usable: 1, + viewAs: { name: "tao" }, + viewAsFilter: function (player) { + return player != _status.currentPhase && player.countCards("hes") > 1; + }, + selectCard: 2, + filterCard: true, + position: "hes", + }, + shulv: { + inherit: "zhiheng", + prompt: "弃置一张牌并摸一张牌", + selectCard: 1, + filter: function (event, player) { + return player.countCards("hs") > player.hp; + }, + }, + xiandeng: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + targetInRange: function (card, player) { + if (card.name == "sha" && player.countUsed("sha", true) == 0) return true; }, }, }, - qingyi:{ - audio:2, - trigger:{player:'phaseJudgeBefore'}, - direct:true, - content:function(){ - "step 0" - var check= player.countCards('h')>2; - player.chooseTarget(get.prompt("qingyi"),"跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】",function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); - }).set('check',check).set('ai',function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); - }); - "step 1" - if(result.bool){ - player.logSkill('qingyi',result.targets); - player.useCard({name:'sha',isCard:true},result.targets[0],false); + qingyi: { + audio: 2, + trigger: { player: "phaseJudgeBefore" }, + direct: true, + content: function () { + "step 0"; + var check = player.countCards("h") > 2; + player + .chooseTarget( + get.prompt("qingyi"), + "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", + function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); + } + ) + .set("check", check) + .set("ai", function (target) { + if (!_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }); + "step 1"; + if (result.bool) { + player.logSkill("qingyi", result.targets); + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); trigger.cancel(); - player.skip('phaseDraw'); + player.skip("phaseDraw"); } }, }, - qingyi1:{ - audio:true, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - "step 0" - player.addSkill('qingyi3'); - var check= player.countCards('h')>2; - player.chooseTarget(get.prompt2('qingyi'),function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target); - }).ai=function(target){ - if(!check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); + qingyi1: { + audio: true, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player.addSkill("qingyi3"); + var check = player.countCards("h") > 2; + player.chooseTarget(get.prompt2("qingyi"), function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target); + }).ai = function (target) { + if (!check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); + }; + "step 1"; + if (result.bool) { + player.logSkill("qingyi1", result.targets); + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); + player.skip("phaseJudge"); + player.skip("phaseDraw"); } - "step 1" - if(result.bool){ - player.logSkill('qingyi1',result.targets); - player.useCard({name:'sha',isCard:true},result.targets[0],false); - player.skip('phaseJudge'); - player.skip('phaseDraw'); - } - player.removeSkill('qingyi3'); - } - }, - qingyi2:{ - audio:true, - trigger:{player:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0; + player.removeSkill("qingyi3"); }, - content:function(){ - "step 0" - player.addSkill('qingyi3'); - var check=player.countCards('h')<=player.hp; + }, + qingyi2: { + audio: true, + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + content: function () { + "step 0"; + player.addSkill("qingyi3"); + var check = player.countCards("h") <= player.hp; player.chooseCardTarget({ - prompt:get.prompt2('qingyi'), - filterCard:function(card,player){ - return get.type(card)=='equip'&&lib.filter.cardDiscardable(card,player); + prompt: get.prompt2("qingyi"), + filterCard: function (card, player) { + return get.type(card) == "equip" && lib.filter.cardDiscardable(card, player); }, - position:'he', - filterTarget:function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target); + position: "he", + filterTarget: function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target); }, - ai1:function(card){ - if(!_status.event.check) return 0; - return 6-get.value(card); + ai1: function (card) { + if (!_status.event.check) return 0; + return 6 - get.value(card); }, - ai2:function(target){ - if(!_status.event.check) return 0; - return get.effect(target,{name:'sha'},_status.event.player); + ai2: function (target) { + if (!_status.event.check) return 0; + return get.effect(target, { name: "sha" }, _status.event.player); }, - check:check + check: check, }); - "step 1" - if(result.bool){ - player.logSkill('qingyi2',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("qingyi2", result.targets); player.discard(result.cards[0]); - player.useCard({name:'sha',isCard:true},result.targets[0]); + player.useCard({ name: "sha", isCard: true }, result.targets[0]); trigger.cancel(); } - player.removeSkill('qingyi3'); - } + player.removeSkill("qingyi3"); + }, }, - qingyi3:{ - mod:{ - targetInRange:function(card,player,target,now){ + qingyi3: { + mod: { + targetInRange: function (card, player, target, now) { return true; - } + }, }, }, - qirang:{ - audio:2, - trigger:{player:'equipEnd'}, - frequent:true, - content:function(){ - var card=get.cardPile(function(card){ - return get.type(card,'trick')=='trick'; + qirang: { + audio: 2, + trigger: { player: "equipEnd" }, + frequent: true, + content: function () { + var card = get.cardPile(function (card) { + return get.type(card, "trick") == "trick"; }); - if(card){ - var next=player.gain(card,'gain2'); - if(get.type(card)=='trick') next.gaintag.add('qirang'); - else{ - player.addMark('qirang_mark',1,false); - player.addTempSkill('qirang_mark',{player:'phaseBegin'}); + if (card) { + var next = player.gain(card, "gain2"); + if (get.type(card) == "trick") next.gaintag.add("qirang"); + else { + player.addMark("qirang_mark", 1, false); + player.addTempSkill("qirang_mark", { player: "phaseBegin" }); } } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; + }, }, - threaten:1.3 + threaten: 1.3, }, - group:'qirang_use', - subSkill:{ - mark:{ - charlotte:true, - onremove:function(player){ - var evt=_status.event; - if(evt.name!='phase') evt=evt.getParent('phase'); - if(evt&&evt.player==player){ - if(!evt.qirang_num) evt.qirang_num=0; - evt.qirang_num+=player.storage.qirang_mark; + group: "qirang_use", + subSkill: { + mark: { + charlotte: true, + onremove: function (player) { + var evt = _status.event; + if (evt.name != "phase") evt = evt.getParent("phase"); + if (evt && evt.player == player) { + if (!evt.qirang_num) evt.qirang_num = 0; + evt.qirang_num += player.storage.qirang_mark; } delete player.storage.qirang_mark; }, - intro:{ - content:'下回合发动〖羽化〗时卜算量+#', + intro: { + content: "下回合发动〖羽化〗时卜算量+#", }, }, - use:{ - audio:'qirang', - trigger:{player:'useCard2'}, - direct:true, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - if(!event.targets||event.targets.length!=1) return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(!player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('qirang')) return true; - } + use: { + audio: "qirang", + trigger: { player: "useCard2" }, + direct: true, + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + if (!event.targets || event.targets.length != 1) return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if ( + !player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("qirang")) return true; + } + return false; + }) + ) return false; - })) return false; - if(!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + if (!info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('qirang'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget(get.prompt("qirang"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('qirang_use',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("qirang_use", event.targets); trigger.targets.addArray(event.targets); } }, }, }, }, - yuhua:{ - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - forced:true, - audio:2, - content:function(){ - "step 0" - var num=1,evt=trigger.getParent(); - if(evt.qirang_num) num+=evt.qirang_num; - var cards=get.cards(Math.min(5,num)); + yuhua: { + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + forced: true, + audio: 2, + content: function () { + "step 0"; + var num = 1, + evt = trigger.getParent(); + if (evt.qirang_num) num += evt.qirang_num; + var cards = get.cards(Math.min(5, num)); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','羽化:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var target=(_status.event.getTrigger().name=='phaseZhunbei')?player:player.next; - var att=get.sgn(get.attitude(player,target)); - var top=[]; - var judges=target.getCards('j'); - var stopped=false; - if(player!=target||!target.hasWuxie()){ - for(var i=0;i0)) break; + while (cards.length) { + if (get.value(cards[0], player) <= 5 == att > 0) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - "step 1" - var top=result.moved[0]; - var bottom=result.moved[1]; + bottom = cards; + return [top, bottom]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i0){ - var att1=get.attitude(target,player); - var att2=get.attitude(target,trigger.player); - var att3=get.attitude(player,target); - if(att3<0) return 0; - return att1/2+att2+att3; - } - else{ - return 0; - // return get.attitude(player,target); - } - }); - 'step 1' - if(result.bool){ - player.addTempSkill('chenqing2','roundStart'); - event.target=result.targets[0]; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("chenqing"), function (card, player, target) { + return target != player && target != _status.event.getTrigger().player; + }) + .set("ai", function (target) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + if (get.attitude(player, trigger.player) > 0) { + var att1 = get.attitude(target, player); + var att2 = get.attitude(target, trigger.player); + var att3 = get.attitude(player, target); + if (att3 < 0) return 0; + return att1 / 2 + att2 + att3; + } else { + return 0; + // return get.attitude(player,target); + } + }); + "step 1"; + if (result.bool) { + player.addTempSkill("chenqing2", "roundStart"); + event.target = result.targets[0]; event.target.draw(4); - player.logSkill('chenqing',event.target); - } - else{ + player.logSkill("chenqing", event.target); + } else { event.finish(); } - 'step 2' - var target=event.target; - var tosave=trigger.player; - var att=get.attitude(target,tosave); - var hastao=target.countCards('h','tao'); - target.chooseToDiscard(4,true,'he').set('ai',function(card){ - var hastao=_status.event.hastao; - var att=_status.event.att; - if(!hastao&&att>0){ - var suit=get.suit(card); - for(var i=0;i 0) { + var suit = get.suit(card); + for (var i = 0; i < ui.selected.cards.length; i++) { + if (get.suit(ui.selected.cards[i]) == suit) { + return -4 - get.value(card); + } } } - } - if(att<0&&ui.selected.cards.length==3){ - var suit=get.suit(card); - for(var i=0;i0&&player.countCards('hs')>0; + ai: { + expose: 0.2, + threaten: 1.5, }, - content:function(){ - "step 0" - event.count=2; - event.history=player.getHistory('useCard',function(evt){ - return evt.isPhaseUsing()&&['basic','trick'].includes(get.type(evt.card)); - }) - "step 1" - event._result={}; - if(event.count&&event.history.length&&player.countCards('hs')){ + }, + mozhi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getHistory("useCard", function (evt) { + return evt.isPhaseUsing() && ["basic", "trick"].includes(get.type(evt.card)); + }).length > 0 && player.countCards("hs") > 0 + ); + }, + content: function () { + "step 0"; + event.count = 2; + event.history = player.getHistory("useCard", function (evt) { + return evt.isPhaseUsing() && ["basic", "trick"].includes(get.type(evt.card)); + }); + "step 1"; + event._result = {}; + if (event.count && event.history.length && player.countCards("hs")) { event.count--; - var card=event.history.shift().card; - card={name:card.name,nature:card.nature}; - if(card.name!='jiu'&&lib.filter.cardEnabled(card)){ - if(game.hasPlayer(function(current){ - return player.canUse(card,current); - })){ - lib.skill.mozhix.viewAs=card; - var next=player.chooseToUse(); - if(next.isOnline()){ - player.send(function(card){ - lib.skill.mozhix.viewAs=card; - },card) + var card = event.history.shift().card; + card = { name: card.name, nature: card.nature }; + if (card.name != "jiu" && lib.filter.cardEnabled(card)) { + if ( + game.hasPlayer(function (current) { + return player.canUse(card, current); + }) + ) { + lib.skill.mozhix.viewAs = card; + var next = player.chooseToUse(); + if (next.isOnline()) { + player.send(function (card) { + lib.skill.mozhix.viewAs = card; + }, card); } - next.logSkill='mozhi'; - next.set('openskilldialog','默识:将一张手牌当'+get.translation(card)+'使用'); - next.set('norestore',true); - next.set('_backupevent','mozhix'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + next.logSkill = "mozhi"; + next.set( + "openskilldialog", + "默识:将一张手牌当" + get.translation(card) + "使用" + ); + next.set("norestore", true); + next.set("_backupevent", "mozhix"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('mozhix'); + next.backup("mozhix"); } } } - "step 2" - if(result&&result.bool) event.goto(1); + "step 2"; + if (result && result.bool) event.goto(1); }, }, - mozhix:{ - filterCard:function(card){ - return get.itemtype(card)=='card'; + mozhix: { + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - selectCard:1, - position:'hs', - popname:true, + selectCard: 1, + position: "hs", + popname: true, }, - chenqing2:{charlotte:true}, - ranshang:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.hasNature('fire'); + chenqing2: { charlotte: true }, + ranshang: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.hasNature("fire"); }, - forced:true, - check:function(){ + forced: true, + check: function () { return false; }, - content:function(){ - player.addMark('ranshang',trigger.num); + content: function () { + player.addMark("ranshang", trigger.num); }, - intro:{ - name2:'燃', - content:'mark' + intro: { + name2: "燃", + content: "mark", }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'){ - if(game.hasNature(card,'fire')||player.hasSkill('zhuque_skill')) return 2; + ai: { + neg: true, + effect: { + target: function (card, player, target, current) { + if (card.name == "sha") { + if (game.hasNature(card, "fire") || player.hasSkill("zhuque_skill")) return 2; } - if(get.tag(card,'fireDamage')&¤t<0) return 2; - } - } + if (get.tag(card, "fireDamage") && current < 0) return 2; + }, + }, }, - group:'ranshang2' + group: "ranshang2", }, - ranshang2:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('ranshang')>0; + ranshang2: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("ranshang") > 0; }, - content:function(){ - player.loseHp(player.countMark('ranshang')); - if(player.countMark('ranshang')>2){ + content: function () { + player.loseHp(player.countMark("ranshang")); + if (player.countMark("ranshang") > 2) { player.loseMaxHp(2); player.draw(2); } - } - }, - hanyong:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card&&(event.card.name=='nanman'||event.card.name=='wanjian'||(event.card.name=='sha'&&!game.hasNature(event.card)&&get.suit(event.card)=='spade'))&&player.isDamaged(); }, - content:function(){ + }, + hanyong: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + event.card && + (event.card.name == "nanman" || + event.card.name == "wanjian" || + (event.card.name == "sha" && + !game.hasNature(event.card) && + get.suit(event.card) == "spade")) && + player.isDamaged() + ); + }, + content: function () { trigger.baseDamage++; - if(game.roundNumber<=player.hp) player.addMark('ranshang',1); + if (game.roundNumber <= player.hp) player.addMark("ranshang", 1); }, }, - hanyong3:{ - audio:false, - trigger:{source:'damageBegin1'}, - forced:true, - onremove:true, - filter:function(event,player){ - return event.card==player.storage.hanyong3; + hanyong3: { + audio: false, + trigger: { source: "damageBegin1" }, + forced: true, + onremove: true, + filter: function (event, player) { + return event.card == player.storage.hanyong3; }, - content:function(){ + content: function () { trigger.num++; - } + }, }, - yishe:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return !player.getExpansions('yishe').length; + yishe: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return !player.getExpansions("yishe").length; }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(2); - 'step 1' - var cards=player.getCards('he'); - if(!cards.length) event.finish(); - else if(cards.length<=2) event._result={bool:true,cards:cards}; - else player.chooseCard(2,'he',true,'选择两张牌作为“米”'); - 'step 2' - if(result.bool) player.addToExpansion(result.cards,player,'give').gaintag.add('yishe'); + "step 1"; + var cards = player.getCards("he"); + if (!cards.length) event.finish(); + else if (cards.length <= 2) event._result = { bool: true, cards: cards }; + else player.chooseCard(2, "he", true, "选择两张牌作为“米”"); + "step 2"; + if (result.bool) player.addToExpansion(result.cards, player, "give").gaintag.add("yishe"); }, - group:'yishe_recover', - ai:{combo:'bushi'}, - subSkill:{ - recover:{ - audio:'yishe', - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + group: "yishe_recover", + ai: { combo: "bushi" }, + subSkill: { + recover: { + audio: "yishe", + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - if(player.isHealthy()) return false; - var evt=event.getl(player); - if(!evt||!evt.xs||!evt.xs.length||player.getExpansions('yishe').length>0) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('yishe')) return true; + filter: function (event, player) { + if (player.isHealthy()) return false; + var evt = event.getl(player); + if (!evt || !evt.xs || !evt.xs.length || player.getExpansions("yishe").length > 0) + return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("yishe")) return true; } return false; } - return player.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('yishe')) return true; + return player.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("yishe")) return true; } return false; }); }, - forced:true, - content:function(){ + forced: true, + content: function () { player.recover(); }, }, }, }, - bushi:{ - audio:2, - trigger:{player:'damageEnd',source:'damageEnd'}, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player.isIn()&&player.getExpansions('yishe').length>0; + bushi: { + audio: 2, + trigger: { player: "damageEnd", source: "damageEnd" }, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player.isIn() && player.getExpansions("yishe").length > 0; }, - direct:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' - trigger.player.chooseCardButton('选择获得一张“米”',player.getExpansions('yishe')); - 'step 2' - if(result.bool){ + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + trigger.player.chooseCardButton("选择获得一张“米”", player.getExpansions("yishe")); + "step 2"; + if (result.bool) { event.count--; - player.logSkill('bushi',trigger.player); - trigger.player.gain(result.links[0],'give',player,'bySelf'); - } - else event.finish(); - 'step 3' - if(event.count>0&&player.getExpansions('yishe').length&&player.hasSkill('bushi')){ + player.logSkill("bushi", trigger.player); + trigger.player.gain(result.links[0], "give", player, "bySelf"); + } else event.finish(); + "step 3"; + if (event.count > 0 && player.getExpansions("yishe").length && player.hasSkill("bushi")) { event.goto(1); } }, - ai:{combo:'yishe'}, + ai: { combo: "yishe" }, }, - midao:{ - audio:2, - trigger:{global:'judge'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('yishe').length&&event.player.isIn(); + midao: { + audio: 2, + trigger: { global: "judge" }, + direct: true, + filter: function (event, player) { + return player.getExpansions("yishe").length && event.player.isIn(); }, - content:function(){ - "step 0" - var list=player.getExpansions('yishe'); - player.chooseButton([get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+get.translation(trigger.player.judging[0])+ - ','+get.prompt('midao'),list,'hidden'],function(button){ - var card=button.link; - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - return result*attitude; - }).set('judging',trigger.player.judging[0]).set('filterButton',function(button){ - var player=_status.event.player; - var card=button.link; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }); - "step 1" - if(result.bool){ - event.forceDie=true; - player.respond(result.links,'midao','highlight','noOrdering'); - result.cards=result.links; - var card=result.cards[0]; - event.card=card; - } - else{ + content: function () { + "step 0"; + var list = player.getExpansions("yishe"); + player + .chooseButton( + [ + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("midao"), + list, + "hidden", + ], + function (button) { + var card = button.link; + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + return result * attitude; + } + ) + .set("judging", trigger.player.judging[0]) + .set("filterButton", function (button) { + var player = _status.event.player; + var card = button.link; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + }); + "step 1"; + if (result.bool) { + event.forceDie = true; + player.respond(result.links, "midao", "highlight", "noOrdering"); + result.cards = result.links; + var card = result.cards[0]; + event.card = card; + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',card); + game.log(trigger.player, "的判定牌改为", card); game.delay(2); } }, - ai:{ - combo:'yishe', - rejudge:true, - tag:{ - rejudge:0.6 - } - } + ai: { + combo: "yishe", + rejudge: true, + tag: { + rejudge: 0.6, + }, + }, }, - fengpo:{ - shaRelated:true, - audio:2, - trigger:{ - player:'useCardToPlayered', + fengpo: { + shaRelated: true, + audio: 2, + trigger: { + player: "useCardToPlayered", }, - filter:function(event,player){ - if(event.targets.length!=1||!['sha','juedou'].includes(event.card.name)) return false; - var evtx=event.getParent(); - return !player.hasHistory('useCard',function(evt){ - return evt!=evtx&&evt.card.name==event.card.name; - },evtx) + filter: function (event, player) { + if (event.targets.length != 1 || !["sha", "juedou"].includes(event.card.name)) + return false; + var evtx = event.getParent(); + return !player.hasHistory( + "useCard", + function (evt) { + return evt != evtx && evt.card.name == event.card.name; + }, + evtx + ); }, - direct:true, - content:function(){ - 'step 0' - var str1=get.translation(trigger.card),str2=get.translation(trigger.target); - player.chooseControl('摸X加1伤','摸1加X伤','cancel2').set('prompt',get.prompt('fengpo',trigger.target)).set('prompt2','你可以选择一项:1.摸X张牌,令'+str1+'的伤害+1;2.摸一张牌,令'+str1+'的伤害+X(X为'+str2+'的♦牌的数量)。'); - 'step 1' - if(result.control&&result.control!='cancel2'){ - player.logSkill('fengpo',trigger.target); - var nd=trigger.target.countCards('he',{suit:'diamond'}); - var draw=1,damage=1; - if(result.control=='摸X加1伤') draw=nd; - else damage=nd; + direct: true, + content: function () { + "step 0"; + var str1 = get.translation(trigger.card), + str2 = get.translation(trigger.target); + player + .chooseControl("摸X加1伤", "摸1加X伤", "cancel2") + .set("prompt", get.prompt("fengpo", trigger.target)) + .set( + "prompt2", + "你可以选择一项:1.摸X张牌,令" + + str1 + + "的伤害+1;2.摸一张牌,令" + + str1 + + "的伤害+X(X为" + + str2 + + "的♦牌的数量)。" + ); + "step 1"; + if (result.control && result.control != "cancel2") { + player.logSkill("fengpo", trigger.target); + var nd = trigger.target.countCards("he", { suit: "diamond" }); + var draw = 1, + damage = 1; + if (result.control == "摸X加1伤") draw = nd; + else damage = nd; player.draw(draw); - var trigger2=trigger.getParent(); - if(typeof trigger2.baseDamage!='number'){ - trigger2.baseDamage=1; + var trigger2 = trigger.getParent(); + if (typeof trigger2.baseDamage != "number") { + trigger2.baseDamage = 1; } - trigger2.baseDamage+=damage; + trigger2.baseDamage += damage; } - } - }, - fengpo2:{ - trigger:{source:'damageBegin1'}, - filter:function(event){ - return event.card&&(event.card.name=='sha'||event.card.name=='juedou')&&event.notLink(); }, - forced:true, - audio:false, - content:function(){ - if(typeof player.storage.fengpo=='number'){ - trigger.num+=player.storage.fengpo; - } - } }, - fengpo3:{charlotte:true}, + fengpo2: { + trigger: { source: "damageBegin1" }, + filter: function (event) { + return ( + event.card && + (event.card.name == "sha" || event.card.name == "juedou") && + event.notLink() + ); + }, + forced: true, + audio: false, + content: function () { + if (typeof player.storage.fengpo == "number") { + trigger.num += player.storage.fengpo; + } + }, + }, + fengpo3: { charlotte: true }, //士燮 biluan: { audio: 2, - trigger: { player: 'phaseDrawBegin1' }, + trigger: { player: "phaseDrawBegin1" }, check: function (event, player) { - if (player.countCards('h') > player.hp) return true; - if (player.hasJudge('lebu')) return true; + if (player.countCards("h") > player.hp) return true; + if (player.hasJudge("lebu")) return true; var ng = []; var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { - if (players[i].group != 'unknown') { + if (players[i].group != "unknown") { ng.add(players[i].group); } } @@ -21804,7 +27601,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var nai = 0; for (var i = 0; i < players.length; i++) { if (players[i] != player) { - var dist = get.distance(players[i], player, 'attack'); + var dist = get.distance(players[i], player, "attack"); if (dist <= 1 && dist + ng > 1) { nai++; } @@ -21813,3739 +27610,4210 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return nai >= 2; }, filter: function (event, player) { - return !event.numFixed && game.hasPlayer(function (current) { - return current != player && get.distance(current, player) <= 1; - }); + return ( + !event.numFixed && + game.hasPlayer(function (current) { + return current != player && get.distance(current, player) <= 1; + }) + ); }, content: function () { - if (!player.hasSkill('rebiluan2')) player.addSkill('rebiluan2'); + if (!player.hasSkill("rebiluan2")) player.addSkill("rebiluan2"); var ng = []; var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { - if (players[i].group != 'unknown') { + if (players[i].group != "unknown") { ng.add(players[i].group); } } - player.$damagepop(ng.length, 'unknownx'); + player.$damagepop(ng.length, "unknownx"); player.storage.rebiluan2 += ng.length; - player.markSkill('rebiluan2'); - game.addVideo('storage', player, ['biluan', player.storage.rebiluan2]); + player.markSkill("rebiluan2"); + game.addVideo("storage", player, ["biluan", player.storage.rebiluan2]); trigger.changeToZero(); }, }, lixia: { audio: 2, - trigger: { global: 'phaseJieshuBegin' }, + trigger: { global: "phaseJieshuBegin" }, filter: function (event, player) { - return event.player.isIn() && event.player != player && get.distance(event.player, player, 'attack') > 1; + return ( + event.player.isIn() && + event.player != player && + get.distance(event.player, player, "attack") > 1 + ); }, forced: true, content: function () { - 'step 0' - player.chooseTarget(function (card, player, target) { - return target == player || target == _status.event.source; - }, true, '礼下:选择一个目标摸一张牌').set('ai', function (target) { - if (get.attitude(player, trigger.player) > 2) return 114514 - target.countCards(); - return player == target ? 1 : 0; - }).set('source', trigger.player); - 'step 1' + "step 0"; + player + .chooseTarget( + function (card, player, target) { + return target == player || target == _status.event.source; + }, + true, + "礼下:选择一个目标摸一张牌" + ) + .set("ai", function (target) { + if (get.attitude(player, trigger.player) > 2) return 114514 - target.countCards(); + return player == target ? 1 : 0; + }) + .set("source", trigger.player); + "step 1"; if (result.targets.length) { result.targets[0].draw(); - player.line(result.targets[0], 'green'); + player.line(result.targets[0], "green"); } - if (!player.hasSkill('rebiluan2')) player.addSkill('rebiluan2'); + if (!player.hasSkill("rebiluan2")) player.addSkill("rebiluan2"); player.storage.rebiluan2--; - player.markSkill('rebiluan2'); - game.addVideo('storage', player, ['biluan', player.storage.rebiluan2]); - } + player.markSkill("rebiluan2"); + game.addVideo("storage", player, ["biluan", player.storage.rebiluan2]); + }, }, olbiluan: { - audio: 'biluan', - trigger: { player: 'phaseJieshuBegin' }, + audio: "biluan", + trigger: { player: "phaseJieshuBegin" }, checkx: function (player) { var ng = Math.min(4, game.countPlayer()); var nai = 0; for (var i = 0; i < game.players.length; i++) { if (game.players[i] != player) { - var dist = get.distance(game.players[i], player, 'attack'); + var dist = get.distance(game.players[i], player, "attack"); if (dist <= 1 && dist + ng > 1) nai++; } } return nai >= 2; }, filter: function (event, player) { - return player.countCards('he') && game.hasPlayer(function (current) { - return current != player && get.distance(current, player) <= 1; - }); + return ( + player.countCards("he") && + game.hasPlayer(function (current) { + return current != player && get.distance(current, player) <= 1; + }) + ); }, direct: true, content: function () { - 'step 0' - player.chooseToDiscard('he', get.prompt2('olbiluan')).set('logSkill', 'olbiluan').set('ai', function (card) { - if (_status.event.check) return 6 - get.value(card); - return 0; - }).set('check', lib.skill.olbiluan.checkx(player)); - 'step 1' + "step 0"; + player + .chooseToDiscard("he", get.prompt2("olbiluan")) + .set("logSkill", "olbiluan") + .set("ai", function (card) { + if (_status.event.check) return 6 - get.value(card); + return 0; + }) + .set("check", lib.skill.olbiluan.checkx(player)); + "step 1"; if (result.bool) { - player.addSkill('rebiluan2'); + player.addSkill("rebiluan2"); var num = game.countGroup(); - player.$damagepop(num, 'unknownx'); + player.$damagepop(num, "unknownx"); player.storage.rebiluan2 += num; - player.markSkill('rebiluan2'); - game.addVideo('storage', player, ['rebiluan2', player.storage.rebiluan2]); + player.markSkill("rebiluan2"); + game.addVideo("storage", player, ["rebiluan2", player.storage.rebiluan2]); } }, }, ollixia: { - audio: 'lixia', - trigger: { global: 'phaseJieshuBegin' }, + audio: "lixia", + trigger: { global: "phaseJieshuBegin" }, filter: function (event, player) { - return event.player.isIn() && event.player != player && get.distance(event.player, player, 'attack') > 1; + return ( + event.player.isIn() && + event.player != player && + get.distance(event.player, player, "attack") > 1 + ); }, forced: true, content: function () { - 'step 0' - player.chooseTarget(function (card, player, target) { - return target == player || target == _status.event.source; - }, true, '礼下:请选择一个目标令其摸牌并减少你与其他角色的距离').set('ai', function (target) { - return player == target ? 1 : 0; - }).set('source', trigger.player); - 'step 1' + "step 0"; + player + .chooseTarget( + function (card, player, target) { + return target == player || target == _status.event.source; + }, + true, + "礼下:请选择一个目标令其摸牌并减少你与其他角色的距离" + ) + .set("ai", function (target) { + return player == target ? 1 : 0; + }) + .set("source", trigger.player); + "step 1"; if (result.targets.length) { - var num = (result.targets[0] == player ? 1 : 2); + var num = result.targets[0] == player ? 1 : 2; result.targets[0].draw(num); - player.line(result.targets[0], 'green'); + player.line(result.targets[0], "green"); } - if (!player.hasSkill('rebiluan2')) player.addSkill('rebiluan2'); + if (!player.hasSkill("rebiluan2")) player.addSkill("rebiluan2"); player.storage.rebiluan2--; - player.markSkill('rebiluan2'); - game.addVideo('storage', player, ['rebiluan2', player.storage.rebiluan]); + player.markSkill("rebiluan2"); + game.addVideo("storage", player, ["rebiluan2", player.storage.rebiluan]); }, }, - rebiluan2:{ - mark:true, - charlotte:true, - intro:{ - content:function(storage){ - if(storage>0){ - return '其他角色计算与你的距离时+'+storage; + rebiluan2: { + mark: true, + charlotte: true, + intro: { + content: function (storage) { + if (storage > 0) { + return "其他角色计算与你的距离时+" + storage; + } else if (storage < 0) { + return "其他角色计算与你的距离时" + storage; + } else { + return "无距离变化"; } - else if(storage<0){ - return '其他角色计算与你的距离时'+storage; - } - else{ - return '无距离变化'; - } - } + }, }, - init:function(player){ - if(typeof player.storage.rebiluan2!='number') player.storage.rebiluan2=0; + init: function (player) { + if (typeof player.storage.rebiluan2 != "number") player.storage.rebiluan2 = 0; }, - mod:{ - globalTo:function(from,to,distance){ - if(typeof to.storage.rebiluan2=='number'){ - return distance+to.storage.rebiluan2; + mod: { + globalTo: function (from, to, distance) { + if (typeof to.storage.rebiluan2 == "number") { + return distance + to.storage.rebiluan2; } - } - } + }, + }, }, - rebiluan:{ - audio:'biluan', - trigger:{player:'phaseJieshuBegin'}, - checkx:function(player){ - var ng=Math.min(4,game.countPlayer()); - var nai=0; - for(var i=0;i1){ + rebiluan: { + audio: "biluan", + trigger: { player: "phaseJieshuBegin" }, + checkx: function (player) { + var ng = Math.min(4, game.countPlayer()); + var nai = 0; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player) { + var dist = get.distance(game.players[i], player, "attack"); + if (dist <= 1 && dist + ng > 1) { nai++; } } } - return nai>=2; + return nai >= 2; }, - filter:function(event,player){ - return player.countCards('he')&&game.hasPlayer(function(current){ - return current!=player&&get.distance(current,player)<=1; - }); + filter: function (event, player) { + return ( + player.countCards("he") && + game.hasPlayer(function (current) { + return current != player && get.distance(current, player) <= 1; + }) + ); }, - direct:true, - content:function(){ - "step 0" - player.chooseToDiscard('he',get.prompt2('rebiluan')).set('logSkill','rebiluan').set('check',lib.skill.rebiluan.checkx(player)).set('ai',function(card){ - if(_status.event.check) return 6-get.value(card); - return 0; - }); - "step 1" - if(result.bool){ - player.addSkill('rebiluan2'); - var ng=Math.min(4,game.countPlayer()); - player.$damagepop(ng,'unknownx'); - player.storage.rebiluan2+=ng; - player.markSkill('rebiluan2'); - game.addVideo('storage',player,['rebiluan2',player.storage.rebiluan2]); + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard("he", get.prompt2("rebiluan")) + .set("logSkill", "rebiluan") + .set("check", lib.skill.rebiluan.checkx(player)) + .set("ai", function (card) { + if (_status.event.check) return 6 - get.value(card); + return 0; + }); + "step 1"; + if (result.bool) { + player.addSkill("rebiluan2"); + var ng = Math.min(4, game.countPlayer()); + player.$damagepop(ng, "unknownx"); + player.storage.rebiluan2 += ng; + player.markSkill("rebiluan2"); + game.addVideo("storage", player, ["rebiluan2", player.storage.rebiluan2]); } }, }, - relixia:{ - audio:'lixia', - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player.isIn()&&event.player!=player&&!player.inRangeOf(event.player); + relixia: { + audio: "lixia", + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return event.player.isIn() && event.player != player && !player.inRangeOf(event.player); }, - forced:true, - content:function(){ - 'step 0' - if(trigger.player.isDead()){ - event._result={bool:true,links:[0]}; + forced: true, + content: function () { + "step 0"; + if (trigger.player.isDead()) { + event._result = { bool: true, links: [0] }; return; } - var list=[ - '令自己摸一张牌', - '令XXX摸两张牌', - '令XXX回复1点体力', - ]; - var card=get.translation(trigger.player); - var next=player.chooseButton([ - '【礼下】:请选择一至两项', - [list.map((item,index)=>{ - return [index,item.replace(/XXX/g,card)] - }),'textbutton'] - ],true,[1,2]); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - if(button.link==2){ + var list = ["令自己摸一张牌", "令XXX摸两张牌", "令XXX回复1点体力"]; + var card = get.translation(trigger.player); + var next = player.chooseButton( + [ + "【礼下】:请选择一至两项", + [ + list.map((item, index) => { + return [index, item.replace(/XXX/g, card)]; + }), + "textbutton", + ], + ], + true, + [1, 2] + ); + next.set("dialog", event.videoId); + next.set("filterButton", function (button) { + if (button.link == 2) { return _status.event.bool1; } return true; }); - next.set('bool1',trigger.player.isDamaged()); - next.set('ai',function(button){ - var player=_status.event.player; - var event=_status.event.getTrigger(); - if(button.link&&get.attitude(player,event.player)<=0) return 0; - return button.link*Math.random(); + next.set("bool1", trigger.player.isDamaged()); + next.set("ai", function (button) { + var player = _status.event.player; + var event = _status.event.getTrigger(); + if (button.link && get.attitude(player, event.player) <= 0) return 0; + return button.link * Math.random(); }); - "step 1" - var map=[ - function(trigger,player,event){ + "step 1"; + var map = [ + function (trigger, player, event) { player.draw(); }, - function(trigger,player,event){ - if(!result.links.includes(2)) player.line(trigger.player); + function (trigger, player, event) { + if (!result.links.includes(2)) player.line(trigger.player); trigger.player.draw(2); }, - function(trigger,player,event){ + function (trigger, player, event) { player.line(trigger.player); trigger.player.recover(); - } + }, ]; result.links.sort(); - for(var i=0;i3; + return num > 3; }, - prompt:function(event,player){ - var num=game.countPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu'&¤t!=player) return true; + prompt: function (event, player) { + var num = game.countPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu" && current != player) + return true; return current.isDamaged(); }); - return '残蚀:是否改为摸'+get.cnNumber(num)+'张牌?'; + return "残蚀:是否改为摸" + get.cnNumber(num) + "张牌?"; }, - filter:function(event,player){ + filter: function (event, player) { return !event.numFixed; }, - content:function(){ + content: function () { trigger.changeToZero(); - var num=game.countPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu'&¤t!=player) return true; + var num = game.countPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu" && current != player) + return true; return current.isDamaged(); }); - if(num>0){ + if (num > 0) { player.draw(num); } - player.addTempSkill('canshi2'); - } - }, - canshi2:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - var type=get.type(event.card,'trick'); - return type=='basic'||type=='trick'; + player.addTempSkill("canshi2"); }, - autodelay:true, - content:function(){ - player.chooseToDiscard(true,'he'); - } }, - chouhai:{ - audio:2, - trigger:{player:'damageBegin3'}, - forced:true, - check:function(){ + canshi2: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + var type = get.type(event.card, "trick"); + return type == "basic" || type == "trick"; + }, + autodelay: true, + content: function () { + player.chooseToDiscard(true, "he"); + }, + }, + chouhai: { + audio: 2, + trigger: { player: "damageBegin3" }, + forced: true, + check: function () { return false; }, - filter:function(event,player){ - return player.countCards('h')==0; + filter: function (event, player) { + return player.countCards("h") == 0; }, - content:function(){ + content: function () { trigger.num++; }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&target.countCards('h')==0) return [1,-2]; - } + ai: { + neg: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.countCards("h") == 0) return [1, -2]; + }, + }, + }, + }, + recanshi: { + audio: "canshi", + trigger: { player: "phaseDrawBegin2" }, + check: function (event, player) { + if ( + player.skipList.includes("phaseUse") || + !player.countCards("h", function (card) { + return get.type(card, "trick") == "trick" && player.hasUseTarget(card); + }) + ) + return true; + var num = game.countPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu") return true; + return current.isDamaged(); + }); + return num > 1; + }, + prompt: function (event, player) { + var num = game.countPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu" && current != player) + return true; + return current.isDamaged(); + }); + return "残蚀:是否多摸" + get.cnNumber(num) + "张牌?"; + }, + filter: function (event, player) { + return ( + !event.numFixed && + game.hasPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu" && current != player) + return true; + return current.isDamaged(); + }) + ); + }, + content: function () { + var num = game.countPlayer(function (current) { + if (player.hasZhuSkill("guiming") && current.group == "wu" && current != player) + return true; + return current.isDamaged(); + }); + if (num > 0) { + trigger.num += num; } - } + player.addTempSkill("recanshi2"); + }, }, - recanshi:{ - audio:'canshi', - trigger:{player:'phaseDrawBegin2'}, - check:function(event,player){ - if(player.skipList.includes('phaseUse')||!player.countCards('h',function(card){ - return get.type(card,'trick')=='trick'&&player.hasUseTarget(card); - })) return true; - var num=game.countPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu') return true; - return current.isDamaged(); - }); - return num>1; + recanshi2: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + if (event.card.name == "sha") return true; + return get.type(event.card) == "trick"; }, - prompt:function(event,player){ - var num=game.countPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu'&¤t!=player) return true; - return current.isDamaged(); - }); - return '残蚀:是否多摸'+get.cnNumber(num)+'张牌?'; + autodelay: true, + content: function () { + player.chooseToDiscard(true, "he"); }, - filter:function(event,player){ - return !event.numFixed&&game.hasPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu'&¤t!=player) return true; - return current.isDamaged(); - }); - }, - content:function(){ - var num=game.countPlayer(function(current){ - if(player.hasZhuSkill('guiming')&¤t.group=='wu'&¤t!=player) return true; - return current.isDamaged(); - }); - if(num>0){ - trigger.num+=num; - } - player.addTempSkill('recanshi2'); - } }, - recanshi2:{ - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - if(event.card.name=='sha') return true; - return get.type(event.card)=='trick'; - }, - autodelay:true, - content:function(){ - player.chooseToDiscard(true,'he'); - } - }, - rechouhai:{ - audio:'chouhai', - trigger:{player:'damageBegin3'}, - forced:true, - check:function(){ + rechouhai: { + audio: "chouhai", + trigger: { player: "damageBegin3" }, + forced: true, + check: function () { return false; }, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.countCards('h')==0; + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.countCards("h") == 0; }, - content:function(){ + content: function () { trigger.num++; }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&target.countCards('h')==0) return [1,-2]; - } - } - } + ai: { + neg: true, + effect: { + target: function (card, player, target, current) { + if (card.name == "sha" && target.countCards("h") == 0) return [1, -2]; + }, + }, + }, }, - kunfen:{ - audio:2, - audioname:['ol_sb_jiangwei'], - trigger:{player:'phaseJieshuBegin'}, - locked:function(skill,player){ - if(!player||!player.storage.kunfen) return true; + kunfen: { + audio: 2, + audioname: ["ol_sb_jiangwei"], + trigger: { player: "phaseJieshuBegin" }, + locked: function (skill, player) { + if (!player || !player.storage.kunfen) return true; return false; }, - direct:true, - content:function(){ - 'step 0' - if(player.storage.kunfen||(get.mode()=='guozhan'&&player.hiddenSkills.includes('kunfen'))){ - if(!player.storage.kunfen) event.skillHidden=true; - player.chooseBool(get.prompt('kunfen'),'失去1点体力,然后摸两张牌').set('ai',function(){ - var player=_status.event.player; - if(player.hp>3) return true; - if(player.hp==3&&player.countCards('h')<3) return true; - if(player.hp==2&&player.countCards('h')==0) return true; - return false; - }); - } - else event._result={bool:true}; - 'step 1' - if(result.bool){ - player.logSkill('kunfen'); + direct: true, + content: function () { + "step 0"; + if ( + player.storage.kunfen || + (get.mode() == "guozhan" && player.hiddenSkills.includes("kunfen")) + ) { + if (!player.storage.kunfen) event.skillHidden = true; + player + .chooseBool(get.prompt("kunfen"), "失去1点体力,然后摸两张牌") + .set("ai", function () { + var player = _status.event.player; + if (player.hp > 3) return true; + if (player.hp == 3 && player.countCards("h") < 3) return true; + if (player.hp == 2 && player.countCards("h") == 0) return true; + return false; + }); + } else event._result = { bool: true }; + "step 1"; + if (result.bool) { + player.logSkill("kunfen"); player.loseHp(); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; player.draw(2); }, - ai:{threaten:1.5}, + ai: { threaten: 1.5 }, }, - fengliang:{ - skillAnimation:true, - animationColor:'thunder', - unique:true, - juexingji:true, - audio:2, - derivation:'oltiaoxin', - trigger:{player:'dying'}, + fengliang: { + skillAnimation: true, + animationColor: "thunder", + unique: true, + juexingji: true, + audio: 2, + derivation: "oltiaoxin", + trigger: { player: "dying" }, //priority:10, - forced:true, - filter:function(event,player){ + forced: true, + filter: function (event, player) { return !player.storage.kunfen; }, - content:function(){ - "step 0" - player.awakenSkill('fengliang'); + content: function () { + "step 0"; + player.awakenSkill("fengliang"); player.loseMaxHp(); - "step 1" - if(player.hp<2){ - player.recover(2-player.hp); + "step 1"; + if (player.hp < 2) { + player.recover(2 - player.hp); } - "step 2" - player.storage.kunfen=true; - player.addSkills('oltiaoxin'); + "step 2"; + player.storage.kunfen = true; + player.addSkills("oltiaoxin"); }, }, - zhuiji:{ - mod:{ - globalFrom:function(from,to){ - if(from.hp>=to.hp) return -Infinity; - } - } + zhuiji: { + mod: { + globalFrom: function (from, to) { + if (from.hp >= to.hp) return -Infinity; + }, + }, }, - oldcihuai:{ - audio:'cihuai', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + oldcihuai: { + audio: "cihuai", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - check:function(event,player){ - return !player.countCards('h','sha'); + check: function (event, player) { + return !player.countCards("h", "sha"); }, - content:function(){ + content: function () { player.showHandcards(); - if(!player.countCards('h','sha')) player.addTempSkill('oldcihuai2'); + if (!player.countCards("h", "sha")) player.addTempSkill("oldcihuai2"); }, }, - oldcihuai2:{ - group:'oldcihuai3', - prompt:'视为使用一张杀', - enable:'chooseToUse', - viewAs:{name:'sha',isCard:true}, - filterCard:function(){return false}, - selectCard:-1, - ai:{ - presha:true, - respondSha:true, + oldcihuai2: { + group: "oldcihuai3", + prompt: "视为使用一张杀", + enable: "chooseToUse", + viewAs: { name: "sha", isCard: true }, + filterCard: function () { + return false; + }, + selectCard: -1, + ai: { + presha: true, + respondSha: true, }, }, - oldcihuai3:{ - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter','die'], + oldcihuai3: { + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + "die", + ], }, - silent:true, - firstDo:true, - filter:function(event,player){ - if(event.name=='die') return true; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length>0; + silent: true, + firstDo: true, + filter: function (event, player) { + if (event.name == "die") return true; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length > 0; }, - content:function(){ - player.removeSkill('oldcihuai2'); + content: function () { + player.removeSkill("oldcihuai2"); }, }, - cihuai:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h','sha')==0; + cihuai: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", "sha") == 0; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('cihuai'),function(card,player,target){ - return player.canUse({name:'sha',isCard:true},target); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha',isCard:true},player,player); - }); - "step 1" - if(result.bool){ - player.logSkill('cihuai'); - player.showHandcards(); - player.useCard({name:'sha',isCard:true},result.targets); - } - }, - ai:{ - expose:0.2, - } - }, - jilei:{ - trigger:{player:'damageEnd'}, - audio:2, - direct:true, - filter:function(event){ - return event.source&&event.source.isIn(); - }, - content:function(){ - 'step 0' - player.chooseControl('basic','trick','equip','cancel2',function(){ - var source=_status.event.source; - if(get.attitude(_status.event.player,source)>0) return 'cancel2'; - var list=['basic','trick','equip'].filter(function(name){ - return (!source.storage.jilei2||!source.storage.jilei2.includes(name)); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("cihuai"), function (card, player, target) { + return player.canUse({ name: "sha", isCard: true }, target); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha", isCard: true }, player, player); }); - if(!list.length) return 'cancel2'; - if(list.includes('trick')&&source.countCards('h',function(card){ - return get.type(card,source)=='trick'&&source.hasValueTarget(card); - })>1) return 'trick'; - return list[0]; - }).set('prompt',get.prompt2('jilei',trigger.source)).set('source',trigger.source); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('jilei',trigger.source); - player.popup(get.translation(result.control)+'牌'); - trigger.source.addTempSkill('jilei2',{player:'phaseBegin'}); + "step 1"; + if (result.bool) { + player.logSkill("cihuai"); + player.showHandcards(); + player.useCard({ name: "sha", isCard: true }, result.targets); + } + }, + ai: { + expose: 0.2, + }, + }, + jilei: { + trigger: { player: "damageEnd" }, + audio: 2, + direct: true, + filter: function (event) { + return event.source && event.source.isIn(); + }, + content: function () { + "step 0"; + player + .chooseControl("basic", "trick", "equip", "cancel2", function () { + var source = _status.event.source; + if (get.attitude(_status.event.player, source) > 0) return "cancel2"; + var list = ["basic", "trick", "equip"].filter(function (name) { + return !source.storage.jilei2 || !source.storage.jilei2.includes(name); + }); + if (!list.length) return "cancel2"; + if ( + list.includes("trick") && + source.countCards("h", function (card) { + return get.type(card, source) == "trick" && source.hasValueTarget(card); + }) > 1 + ) + return "trick"; + return list[0]; + }) + .set("prompt", get.prompt2("jilei", trigger.source)) + .set("source", trigger.source); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("jilei", trigger.source); + player.popup(get.translation(result.control) + "牌"); + trigger.source.addTempSkill("jilei2", { player: "phaseBegin" }); trigger.source.storage.jilei2.add(result.control); - trigger.source.updateMarks('jilei2'); + trigger.source.updateMarks("jilei2"); } }, - ai:{ - maixie_defend:true, - threaten:0.7 - } + ai: { + maixie_defend: true, + threaten: 0.7, + }, }, - jilei2:{ - unique:true, - charlotte:true, - intro:{ - content:function(storage){ - return '不能使用、打出或弃置'+get.translation(storage)+'牌'; - } - }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; - }, - mark:true, - onremove:true, - mod:{ - cardDiscardable:function(card,player){ - if(player.storage.jilei2.includes(get.type(card,'trick'))) return false; + jilei2: { + unique: true, + charlotte: true, + intro: { + content: function (storage) { + return "不能使用、打出或弃置" + get.translation(storage) + "牌"; }, - cardEnabled:function(card,player){ - if(player.storage.jilei2.includes(get.type(card,'trick'))){ - var hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - for(var i of cards){ - if(hs.includes(i)) return false; + }, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; + }, + mark: true, + onremove: true, + mod: { + cardDiscardable: function (card, player) { + if (player.storage.jilei2.includes(get.type(card, "trick"))) return false; + }, + cardEnabled: function (card, player) { + if (player.storage.jilei2.includes(get.type(card, "trick"))) { + var hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + for (var i of cards) { + if (hs.includes(i)) return false; } } }, - cardRespondable:function(card,player){ - if(player.storage.jilei2.includes(get.type(card,'trick'))){ - var hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - for(var i of cards){ - if(hs.includes(i)) return false; + cardRespondable: function (card, player) { + if (player.storage.jilei2.includes(get.type(card, "trick"))) { + var hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + for (var i of cards) { + if (hs.includes(i)) return false; } } }, - cardSavable:function(card,player){ - if(player.storage.jilei2.includes(get.type(card,'trick'))){ - var hs=player.getCards('h'),cards=[card]; - if(Array.isArray(card.cards)) cards.addArray(card.cards); - for(var i of cards){ - if(hs.includes(i)) return false; + cardSavable: function (card, player) { + if (player.storage.jilei2.includes(get.type(card, "trick"))) { + var hs = player.getCards("h"), + cards = [card]; + if (Array.isArray(card.cards)) cards.addArray(card.cards); + for (var i of cards) { + if (hs.includes(i)) return false; } } }, }, }, - danlao:{ - audio:2, - filter:function(event,player){ - return (event.card.name=='sha'||get.type(event.card)=='trick')&&event.targets&&event.targets.length>1; + danlao: { + audio: 2, + filter: function (event, player) { + return ( + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.targets && + event.targets.length > 1 + ); }, - check:function(event,player){ - return event.getParent().excluded.includes(player)||get.tag(event.card,'multineg')||get.effect(player,event.card,event.player,player)<=0; + check: function (event, player) { + return ( + event.getParent().excluded.includes(player) || + get.tag(event.card, "multineg") || + get.effect(player, event.card, event.player, player) <= 0 + ); }, - trigger:{target:'useCardToTargeted'}, - content:function(){ + trigger: { target: "useCardToTargeted" }, + content: function () { trigger.getParent().excluded.add(player); player.draw(); }, - ai:{ - effect:{ - target:function(card){ - if(get.type(card)!='trick') return; - if(card.name=='tiesuo') return [0,0]; - if(card.name=='yihuajiemu') return [0,1]; - if(get.tag(card,'multineg')) return [0,2]; - } - } - } + ai: { + effect: { + target: function (card) { + if (get.type(card) != "trick") return; + if (card.name == "tiesuo") return [0, 0]; + if (card.name == "yihuajiemu") return [0, 1]; + if (get.tag(card, "multineg")) return [0, 2]; + }, + }, + }, }, - taichen:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player.canUse('sha',target); + taichen: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player.canUse("sha", target); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.loseHp(); - "step 1" - player.useCard({name:'sha',isCard:true},target,false); + "step 1"; + player.useCard({ name: "sha", isCard: true }, target, false); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(player.hp>2&&player.hp>target.hp&&target.countCards('he')<4){ - return get.effect(target,{name:'sha'},player,target); + ai: { + order: 1, + result: { + target: function (player, target) { + if (player.hp > 2 && player.hp > target.hp && target.countCards("he") < 4) { + return get.effect(target, { name: "sha" }, player, target); } return 0; - } - } - } + }, + }, + }, }, - naman:{ - audio:2, - trigger:{global:'respondAfter'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.player==player) return false; - if(event.cards){ - for(var i=0;i0; + xiemu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - filterCard:{name:'sha'}, - check:function(card){return 6-get.value(card)}, - content:function(){ - 'step 0' - var list=lib.group.filter(function(group){ - return ['wei','shu','wu','qun'].includes(group)||game.hasPlayer(function(current){ - return current.group==group; + filterCard: { name: "sha" }, + check: function (card) { + return 6 - get.value(card); + }, + content: function () { + "step 0"; + var list = lib.group.filter(function (group) { + return ( + ["wei", "shu", "wu", "qun"].includes(group) || + game.hasPlayer(function (current) { + return current.group == group; + }) + ); + }); + if (player.storage.xiemu2) list.removeArray(player.storage.xiemu2); + var list2 = list.slice(0); + list2.sort(function (a, b) { + return lib.skill.xiemu.count(b) - lib.skill.xiemu.count(a); + }); + player + .chooseControl(list) + .set("prompt", "请选择一个势力") + .set("ai", function () { + return _status.event.group; }) - }); - if(player.storage.xiemu2) list.removeArray(player.storage.xiemu2); - var list2=list.slice(0); - list2.sort(function(a,b){ - return lib.skill.xiemu.count(b)-lib.skill.xiemu.count(a); - }); - player.chooseControl(list).set('prompt','请选择一个势力').set('ai',function(){return _status.event.group}).set('group',list2[0]); - 'step 1' - player.popup(result.control+2,get.groupnature(result.control)); - game.log(player,'选择了','#g'+get.translation(result.control+2)); - player.addTempSkill('xiemu2',{player:'phaseBegin'}); + .set("group", list2[0]); + "step 1"; + player.popup(result.control + 2, get.groupnature(result.control)); + game.log(player, "选择了", "#g" + get.translation(result.control + 2)); + player.addTempSkill("xiemu2", { player: "phaseBegin" }); player.storage.xiemu2.add(result.control); - player.updateMarks('xiemu2'); + player.updateMarks("xiemu2"); }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, }, - count:function(group){ - var player=_status.event.player; - return game.countPlayer(function(current){ - return current!=player&¤t.group==group&&get.attitude(current,player)<0; + count: function (group) { + var player = _status.event.player; + return game.countPlayer(function (current) { + return ( + current != player && current.group == group && get.attitude(current, player) < 0 + ); }); }, }, - xiemu2:{ - onremove:true, - mark:true, - forced:true, - audio:'xiemu', - intro:{ - content:function(storage){ - return '已指定'+get.translation(storage)+'势力'; + xiemu2: { + onremove: true, + mark: true, + forced: true, + audio: "xiemu", + intro: { + content: function (storage) { + return "已指定" + get.translation(storage) + "势力"; }, }, - trigger:{ - target:'useCardToTargeted' + trigger: { + target: "useCardToTargeted", }, - init:function(player){ - if(!player.storage.xiemu2) player.storage.xiemu2=[]; + init: function (player) { + if (!player.storage.xiemu2) player.storage.xiemu2 = []; }, - filter:function(event,player){ - if(!player.storage.xiemu2) return false; - if(get.color(event.card)!='black') return false; - if(!event.player) return false; - if(event.player==player||!player.storage.xiemu2.includes(event.player.group)) return false; + filter: function (event, player) { + if (!player.storage.xiemu2) return false; + if (get.color(event.card) != "black") return false; + if (!event.player) return false; + if (event.player == player || !player.storage.xiemu2.includes(event.player.group)) + return false; return true; }, - content:function(){ + content: function () { player.draw(2); }, }, - oldxiemu:{ - audio:'xiemu', - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - if(get.color(event.card)!='black') return false; - if(!event.player) return false; - if(event.player==player) return false; - if(get.mode()!='guozhan') return false; - return player.countCards('h','sha')>0; + oldxiemu: { + audio: "xiemu", + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + if (get.color(event.card) != "black") return false; + if (!event.player) return false; + if (event.player == player) return false; + if (get.mode() != "guozhan") return false; + return player.countCards("h", "sha") > 0; }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('协穆:是否弃置一张杀并摸两张牌?',{name:'sha'}); - next.set('ai',function(card){ - return 9-get.value(card); + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard("协穆:是否弃置一张杀并摸两张牌?", { name: "sha" }); + next.set("ai", function (card) { + return 9 - get.value(card); }); - next.logSkill='xiemu'; - "step 1" - if(result.bool){ + next.logSkill = "xiemu"; + "step 1"; + if (result.bool) { player.draw(2); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.color(card)=='black'&&target.countCards('h')>0){ - return [1,0.5]; + ai: { + effect: { + target: function (card, player, target) { + if (get.color(card) == "black" && target.countCards("h") > 0) { + return [1, 0.5]; } - } - } - } - }, - spmengjin:{ - trigger:{player:'shaBegin'}, - filter:function(event,player){ - return event.target.countCards('he')>0; + }, + }, }, - direct:true, - content:function(){ - "step 0" - var att=get.attitude(player,trigger.target); - player.choosePlayerCard(get.prompt('spmengjin',trigger.target),'he',trigger.target).ai=function(button){ - var val=get.buttonValue(button); - if(att>0) return -val; + }, + spmengjin: { + trigger: { player: "shaBegin" }, + filter: function (event, player) { + return event.target.countCards("he") > 0; + }, + direct: true, + content: function () { + "step 0"; + var att = get.attitude(player, trigger.target); + player.choosePlayerCard( + get.prompt("spmengjin", trigger.target), + "he", + trigger.target + ).ai = function (button) { + var val = get.buttonValue(button); + if (att > 0) return -val; return val; }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { trigger.target.discard(result.links); - player.logSkill('spmengjin',trigger.target); - trigger.target.addTempSkill('mengjin2','shaAfter'); + player.logSkill("spmengjin", trigger.target); + trigger.target.addTempSkill("mengjin2", "shaAfter"); } }, - ai:{ - expose:0.2 - } - }, - fenxun_old:{ - audio:2, - trigger:{player:'shaBefore'}, - direct:true, - filter:function(event,player){ - return event.targets.length==1; + ai: { + expose: 0.2, }, - position:'he', - content:function(){ - "step 0" + }, + fenxun_old: { + audio: 2, + trigger: { player: "shaBefore" }, + direct: true, + filter: function (event, player) { + return event.targets.length == 1; + }, + position: "he", + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - var trigger=_status.event.getTrigger(); - return lib.filter.targetEnabled(trigger.card,player,target)&&target!=trigger.targets[0]; + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + var trigger = _status.event.getTrigger(); + return ( + lib.filter.targetEnabled(trigger.card, player, target) && + target != trigger.targets[0] + ); }, - ai1:function(card){ - return 6-get.value(card); + ai1: function (card) { + return 6 - get.value(card); }, - ai2:function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); + ai2: function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); }, - prompt:get.prompt2('fenxun') + prompt: get.prompt2("fenxun"), }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); trigger.targets.push(result.targets[0]); - player.logSkill('fenxun',result.targets); + player.logSkill("fenxun", result.targets); } - } + }, }, - rezhoufu:{ - audio:'zhoufu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + rezhoufu: { + audio: "zhoufu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player&&!target.getExpansions('rezhoufu2').length; + filterCard: true, + filterTarget: function (card, player, target) { + return target != player && !target.getExpansions("rezhoufu2").length; }, - check:function(card){ - return 6-get.value(card) + check: function (card) { + return 6 - get.value(card); }, - position:'he', - discard:false, - lose:false, - delay:false, - content:function(){ - if(!target.storage.rezhoufu2_markcount) target.storage.rezhoufu2_markcount=0; - target.addToExpansion(cards,player,'give').gaintag.add('rezhoufu2'); - target.addSkill('rezhoufu_judge'); + position: "he", + discard: false, + lose: false, + delay: false, + content: function () { + if (!target.storage.rezhoufu2_markcount) target.storage.rezhoufu2_markcount = 0; + target.addToExpansion(cards, player, "give").gaintag.add("rezhoufu2"); + target.addSkill("rezhoufu_judge"); }, - ai:{ - order:1, - result:{ - target:-1, + ai: { + order: 1, + result: { + target: -1, }, }, - group:['rezhoufu_losehp'], - subSkill:{ - judge:{ - audio:'zhoufu', - trigger:{player:'judgeBefore'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return !event.directresult&&player.getExpansions('rezhoufu2').length; + group: ["rezhoufu_losehp"], + subSkill: { + judge: { + audio: "zhoufu", + trigger: { player: "judgeBefore" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return !event.directresult && player.getExpansions("rezhoufu2").length; }, - content:function(){ - var cards=[player.getExpansions('rezhoufu2')[0]]; - trigger.directresult=cards[0]; + content: function () { + var cards = [player.getExpansions("rezhoufu2")[0]]; + trigger.directresult = cards[0]; }, }, - losehp:{ - audio:'zhoufu', - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hasHistory('lose',function(evt){ - if(!evt||!evt.xs||!evt.xs.length) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('rezhoufu2')) return true; + losehp: { + audio: "zhoufu", + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.hasHistory("lose", function (evt) { + if (!evt || !evt.xs || !evt.xs.length) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("rezhoufu2")) return true; } return false; }); }); }, - logTarget:function(current){ - return game.filterPlayer(function(current){ - return current.hasHistory('lose',function(evt){ - if(!evt||!evt.xs||!evt.xs.length) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('rezhoufu2')) return true; - } - return false; - }); - }).sortBySeat(); + logTarget: function (current) { + return game + .filterPlayer(function (current) { + return current.hasHistory("lose", function (evt) { + if (!evt || !evt.xs || !evt.xs.length) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("rezhoufu2")) return true; + } + return false; + }); + }) + .sortBySeat(); }, - content:function(){ - var targets=game.filterPlayer(function(current){ - return current.hasHistory('lose',function(evt){ - if(!evt||!evt.xs||!evt.xs.length) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('rezhoufu2')) return true; - } - return false; - }); - }).sortBySeat(); - while(targets.length){ + content: function () { + var targets = game + .filterPlayer(function (current) { + return current.hasHistory("lose", function (evt) { + if (!evt || !evt.xs || !evt.xs.length) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("rezhoufu2")) return true; + } + return false; + }); + }) + .sortBySeat(); + while (targets.length) { targets.shift().loseHp(); } }, }, }, }, - rezhoufu2:{ - intro:{ - content:'expansion', + rezhoufu2: { + intro: { + content: "expansion", }, }, - rezhoufu3:{}, - reyingbing:{ - audio:'yingbin', - trigger:{global:'useCard'}, - forced:true, - filter:function(event,player){ - var cards=event.player.getExpansions('rezhoufu2'); - return cards.length&&get.color(cards[0])==get.color(event.card); + rezhoufu3: {}, + reyingbing: { + audio: "yingbin", + trigger: { global: "useCard" }, + forced: true, + filter: function (event, player) { + var cards = event.player.getExpansions("rezhoufu2"); + return cards.length && get.color(cards[0]) == get.color(event.card); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; player.draw(); - 'step 1' + "step 1"; trigger.player.storage.rezhoufu2_markcount++; - if(trigger.player.storage.rezhoufu2_markcount>=2){ + if (trigger.player.storage.rezhoufu2_markcount >= 2) { delete trigger.player.storage.rezhoufu2_markcount; - var cards=trigger.player.getExpansions('rezhoufu2'); - player.gain(cards,trigger.player,'give','bySelf'); - } - else trigger.player.markSkill('rezhoufu2'); + var cards = trigger.player.getExpansions("rezhoufu2"); + player.gain(cards, trigger.player, "give", "bySelf"); + } else trigger.player.markSkill("rezhoufu2"); + }, + ai: { + combo: "rezhoufu", }, }, - zhoufu:{ - audio:2, + zhoufu: { + audio: 2, }, - yingbin:{ - audio:2, + yingbin: { + audio: 2, }, - kuiwei:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - check:function(event,player){ - if(player.isTurnedOver()) return true; - var num=game.countPlayer(function(current){ + kuiwei: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + check: function (event, player) { + if (player.isTurnedOver()) return true; + var num = game.countPlayer(function (current) { return current.getEquip(1); }); - return num>1; + return num > 1; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.turnOver(); - "step 1" - var num=game.countPlayer(function(current){ + "step 1"; + var num = game.countPlayer(function (current) { return current.getEquips(1).length; }); - player.draw(2+num); - player.addSkill('kuiwei2'); + player.draw(2 + num); + player.addSkill("kuiwei2"); + }, + ai: { + effect: { + target: function (card) { + if (card.name == "guiyoujie") return [0, 2]; + }, + }, }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='guiyoujie') return [0,2]; - } - } - } }, - kuiwei2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - audio:false, - content:function(){ - var num=game.countPlayer(function(current){ + kuiwei2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + audio: false, + content: function () { + var num = game.countPlayer(function (current) { return current.getEquips(1).length; }); - if(num>=player.countCards('he')){ - player.discard(player.getCards('he')); + if (num >= player.countCards("he")) { + player.discard(player.getCards("he")); + } else if (num) { + player.chooseToDiscard("he", num, true); } - else if(num){ - player.chooseToDiscard('he',num,true); - } - player.removeSkill('kuiwei2'); - } + player.removeSkill("kuiwei2"); + }, }, - yanzheng:{ - enable:'chooseToUse', - audio:2, - filter:function(event,player){ - return player.hp0; + yanzheng: { + enable: "chooseToUse", + audio: 2, + filter: function (event, player) { + return player.hp < player.countCards("h") && player.countCards("e") > 0; }, - viewAsFilter:function(player){ - return player.hp0; + viewAsFilter: function (player) { + return player.hp < player.countCards("h") && player.countCards("e") > 0; }, - filterCard:true, - position:'e', - viewAs:{name:'wuxie'}, - prompt:'将一张装备区内的牌当无懈可击使用', - check:function(card){return 8-get.equipValue(card)}, - threaten:1.2 + filterCard: true, + position: "e", + viewAs: { name: "wuxie" }, + prompt: "将一张装备区内的牌当无懈可击使用", + check: function (card) { + return 8 - get.equipValue(card); + }, + threaten: 1.2, }, - tongji:{ - global:'tongji_disable', - audio:2, - trigger:{global:"useCard1"}, - forced:true, - filter:function (event,player){ - return event.targets.includes(player)&&player!=event.player&&event.card.name=='sha'&&player.hp=0; + }, + wangzun3: { + mod: { + maxHandcard: function (player, num) { + return num - 1; + }, }, - logTarget:'target', - content:function(){ - "step 0" + }, + kaikang: { + audio: 2, + trigger: { global: "useCardToTargeted" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + get.distance(player, event.target) <= 1 && + event.target.isIn() + ); + }, + check: function (event, player) { + return get.attitude(player, event.target) >= 0; + }, + logTarget: "target", + content: function () { + "step 0"; player.draw(); - if(trigger.target!=player){ - player.chooseCard(true,'he','交给'+get.translation(trigger.target)+'一张牌').set('ai',function(card){ - if(get.position(card)=='e') return -1; - if(card.name=='shan') return 1; - if(get.type(card)=='equip') return 0.5; - return 0; - }); - } - else{ + if (trigger.target != player) { + player + .chooseCard(true, "he", "交给" + get.translation(trigger.target) + "一张牌") + .set("ai", function (card) { + if (get.position(card) == "e") return -1; + if (card.name == "shan") return 1; + if (get.type(card) == "equip") return 0.5; + return 0; + }); + } else { event.finish(); } - "step 1" - player.give(result.cards,trigger.target,'give'); + "step 1"; + player.give(result.cards, trigger.target, "give"); game.delay(); - event.card=result.cards[0]; - "step 2" - if(trigger.target.getCards('h').includes(card)&&get.type(card)=='equip'){ + event.card = result.cards[0]; + "step 2"; + if (trigger.target.getCards("h").includes(card) && get.type(card) == "equip") { trigger.target.chooseUseTarget(card); } }, - ai:{ - threaten:1.1 - } + ai: { + threaten: 1.1, + }, }, - liangzhu:{ - audio:2, - trigger:{global:'recoverAfter'}, - direct:true, - filter:function(event,player){ + liangzhu: { + audio: 2, + trigger: { global: "recoverAfter" }, + direct: true, + filter: function (event, player) { return event.player.isPhaseUsing(); }, - content:function(){ - 'step 0' - if(player==trigger.player){ - player.chooseControl('摸一张','摸两张','cancel2',function(){ - return '摸两张'; - }).set('prompt',get.prompt2('liangzhu')); - event.single=true; + content: function () { + "step 0"; + if (player == trigger.player) { + player + .chooseControl("摸一张", "摸两张", "cancel2", function () { + return "摸两张"; + }) + .set("prompt", get.prompt2("liangzhu")); + event.single = true; + } else { + player + .chooseTarget(get.prompt2("liangzhu"), function (card, player, target) { + return target == _status.event.player || target == _status.event.target; + }) + .set("target", trigger.player) + .set("ai", function (target) { + var player = _status.event.player; + if (player == target) return 1; + return get.attitude(player, target) - 1.5; + }); } - else{ - player.chooseTarget(get.prompt2('liangzhu'),function(card,player,target){ - return target==_status.event.player||target==_status.event.target; - }).set('target',trigger.player).set('ai',function(target){ - var player=_status.event.player; - if(player==target) return 1; - return get.attitude(player,target)-1.5; - }); - } - 'step 1' - if(event.single){ - if(result.control!='cancel2'){ - player.logSkill('liangzhu',player); - if(result.control=='摸一张'){ + "step 1"; + if (event.single) { + if (result.control != "cancel2") { + player.logSkill("liangzhu", player); + if (result.control == "摸一张") { player.draw(); - } - else{ + } else { player.draw(2); - if(!player.storage.liangzhu) player.storage.liangzhu=[]; + if (!player.storage.liangzhu) player.storage.liangzhu = []; player.storage.liangzhu.add(player); } } - } - else if(result.bool){ - var target=result.targets[0]; - player.logSkill('liangzhu',target); - if(target==player){ + } else if (result.bool) { + var target = result.targets[0]; + player.logSkill("liangzhu", target); + if (target == player) { target.draw(); - } - else{ + } else { target.draw(2); - if(target.storage.liangzhu){ + if (target.storage.liangzhu) { target.storage.liangzhu.add(player); - } - else{ - target.storage.liangzhu=[player]; + } else { + target.storage.liangzhu = [player]; } } } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - fanxiang:{ - skillAnimation:true, - animationColor:'fire', - audio:2, - unique:true, - juexingji:true, - forceunique:true, - derivation:'xiaoji', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(player.storage.fanxiang) return false; - return game.hasPlayer(function(current){ - return current.storage.liangzhu&¤t.storage.liangzhu.includes(player)&¤t.isDamaged(); + fanxiang: { + skillAnimation: true, + animationColor: "fire", + audio: 2, + unique: true, + juexingji: true, + forceunique: true, + derivation: "xiaoji", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (player.storage.fanxiang) return false; + return game.hasPlayer(function (current) { + return ( + current.storage.liangzhu && + current.storage.liangzhu.includes(player) && + current.isDamaged() + ); }); }, - forced:true, - content:function(){ - player.awakenSkill('fanxiang'); + forced: true, + content: function () { + player.awakenSkill("fanxiang"); player.gainMaxHp(); player.recover(); - player.changeSkills(['xiaoji'],['liangzhu']); + player.changeSkills(["xiaoji"], ["liangzhu"]); + }, + ai: { + combo: "liangzhu", }, }, - mingshi:{ - audio:2, - trigger:{player:'damageBegin3'}, - direct:true, - filter:function(event,player){ - return event.source&&event.source.hp>player.hp; + mingshi: { + audio: 2, + trigger: { player: "damageBegin3" }, + direct: true, + filter: function (event, player) { + return event.source && event.source.hp > player.hp; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt2('mingshi'),{color:'black'}); - next.set('ai',function(card){ - return 9-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt2("mingshi"), { color: "black" }); + next.set("ai", function (card) { + return 9 - get.value(card); }); - next.set('logSkill','mingshi'); - "step 1" - if(result.bool){ + next.set("logSkill", "mingshi"); + "step 1"; + if (result.bool) { trigger.num--; } }, - ai:{ - threaten:0.8 - } - }, - lirang:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + ai: { + threaten: 0.8, }, - filter:function(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; - if(event.type!='discard'||event.getlx===false) return false; - var evt=event.getl(player); - if(!evt||!evt.cards2) return false; - for(var i=0;i current != player)) return false; + if (event.type != "discard" || event.getlx === false) return false; + var evt = event.getl(player); + if (!evt || !evt.cards2) return false; + for (var i = 0; i < evt.cards2.length; i++) { + if (get.position(evt.cards2[i]) == "d") { return true; } } return false; }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - if(trigger.delay==false) game.delay(); - event.cards=[]; - var cards2=trigger.getl(player).cards2; - for(var i=0;i1; + if (!goon) { + goon = game.hasPlayer(function (current) { + return player != current && get.attitude(player, current) > 1; }); } - player.chooseButton(['礼让:是否分配本次弃置的牌?',event.cards], - [1,event.cards.length]).set('ai',function(button){ - if(_status.event.goon&&ui.selected.buttons.length==0) return 1+Math.abs(get.value(button.link)); - return 0; - }).set('goon',goon).setHiddenSkill('lirang'); - 'step 2' - if(result.bool){ + player + .chooseButton(["礼让:是否分配本次弃置的牌?", event.cards], [1, event.cards.length]) + .set("ai", function (button) { + if (_status.event.goon && ui.selected.buttons.length == 0) + return 1 + Math.abs(get.value(button.link)); + return 0; + }) + .set("goon", goon) + .setHiddenSkill("lirang"); + "step 2"; + if (result.bool) { event.cards.removeArray(result.links); - event.togive=result.links.slice(0); - player.chooseTarget('选择一名其他角色获得'+get.translation(result.links),true,lib.filter.notMe).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.enemy){ - return -att; - } - else if(att>0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); - } - else event.goto(4); - 'step 3' - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + event.togive = result.links.slice(0); + player + .chooseTarget( + "选择一名其他角色获得" + get.translation(result.links), + true, + lib.filter.notMe + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); + } else event.goto(4); + "step 3"; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(cards.length>0) event.goto(1); - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length > 0) event.goto(1); + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var list=[],targets=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - list.push([source,event.given_map[i]]); + var list = [], + targets = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + list.push([source, event.given_map[i]]); targets.push(source); } - if(targets.length){ - player.logSkill('lirang',targets); + if (targets.length) { + player.logSkill("lirang", targets); game.loseAsync({ - gain_list:list, - giver:player, - animate:'gain2', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "gain2", + }).setContent("gaincardMultiple"); } }, - ai:{ - expose:0.1, - effect:{ - target:function(card,player,target,current){ - if(target.hasFriend()&&get.tag(card,'discard')){ - if(current<0) return 0; - return [1,1]; + ai: { + expose: 0.1, + effect: { + target: function (card, player, target, current) { + if (target.hasFriend() && get.tag(card, "discard")) { + if (current < 0) return 0; + return [1, 1]; } - } - } - } - }, - moukui:{ - audio:2, - audioname:['sp_mushun'], - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'; + }, + }, }, - content:function(){ - "step 0" - var controls=['draw_card']; - if(trigger.target.countCards('he')){ - controls.push('discard_card'); + }, + moukui: { + audio: 2, + audioname: ["sp_mushun"], + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return event.card.name == "sha"; + }, + content: function () { + "step 0"; + var controls = ["draw_card"]; + if (trigger.target.countCards("he")) { + controls.push("discard_card"); } - controls.push('cancel'); - player.chooseControl(controls).set('ai',function(){ - var trigger=_status.event.getTrigger(); - if(trigger.target.countCards('he')&&get.attitude(_status.event.player,trigger.target)<0){ - return 'discard_card'; - } - else{ - return 'draw_card'; - } - }).set('prompt',get.prompt2('moukui')); - "step 1" - if(result.control=='draw_card'){ + controls.push("cancel"); + player + .chooseControl(controls) + .set("ai", function () { + var trigger = _status.event.getTrigger(); + if ( + trigger.target.countCards("he") && + get.attitude(_status.event.player, trigger.target) < 0 + ) { + return "discard_card"; + } else { + return "draw_card"; + } + }) + .set("prompt", get.prompt2("moukui")); + "step 1"; + if (result.control == "draw_card") { player.draw(); - player.logSkill('moukui'); - } - else if(result.control=='discard_card'&&trigger.target.countCards('he')){ - player.discardPlayerCard(trigger.target,'he',true).logSkill=['moukui',trigger.target]; - } - else event.finish(); - "step 2" - player.addTempSkill('moukui2','shaEnd'); + player.logSkill("moukui"); + } else if (result.control == "discard_card" && trigger.target.countCards("he")) { + player.discardPlayerCard(trigger.target, "he", true).logSkill = [ + "moukui", + trigger.target, + ]; + } else event.finish(); + "step 2"; + player.addTempSkill("moukui2", "shaEnd"); }, - ai:{ - expose:0.1 - } - }, - moukui2:{ - audio:false, - trigger:{player:'shaMiss'}, - forced:true, - filter:function(event,player){ - return player.countCards('he')>0; + ai: { + expose: 0.1, }, - content:function(){ - trigger.target.discardPlayerCard(player,true); - } }, - shenxian:{ - audio:2, - trigger:{global:['loseAfter','loseAsyncAfter']}, - filter:function(event,player){ - if(event.type!='discard'||_status.currentPhase==player||event.getlx===false) return false; - if(event.name=='lose'&&event.player==player) return false; - if(player.hasSkill('shenxian2')) return false; - var cards=event.cards.slice(0); - var evt=event.getl(player); - if(evt&&evt.cards) cards.removeArray(evt.cards); - for(var i=0;i 0; + }, + content: function () { + trigger.target.discardPlayerCard(player, true); + }, + }, + shenxian: { + audio: 2, + trigger: { global: ["loseAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + if (event.type != "discard" || _status.currentPhase == player || event.getlx === false) + return false; + if (event.name == "lose" && event.player == player) return false; + if (player.hasSkill("shenxian2")) return false; + var cards = event.cards.slice(0); + var evt = event.getl(player); + if (evt && evt.cards) cards.removeArray(evt.cards); + for (var i = 0; i < cards.length; i++) { + if ( + get.type( + cards[i], + null, + event.hs && event.hs.includes(cards[i]) ? event.player : false + ) == "basic" && + cards[i].original != "j" + ) { return true; } } return false; }, - frequent:true, - content:function(){ - "step 0" - if(trigger.delay==false) game.delay(); - "step 1" + frequent: true, + content: function () { + "step 0"; + if (trigger.delay == false) game.delay(); + "step 1"; player.draw(); - if(event.name=='shenxian') player.addTempSkill('shenxian2'); + if (event.name == "shenxian") player.addTempSkill("shenxian2"); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - shenxian2:{charlotte:true}, - qiangwu:{ - audio:2, - enable:'phaseUse', - usable:1, - content:function(){ - "step 0" + shenxian2: { charlotte: true }, + qiangwu: { + audio: 2, + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; player.judge(); - "step 1" - player.storage.qiangwu=result.number; - player.addTempSkill('qiangwu3','phaseUseEnd'); + "step 1"; + player.storage.qiangwu = result.number; + player.addTempSkill("qiangwu3", "phaseUseEnd"); }, - ai:{ - result:{ - player:1 + ai: { + result: { + player: 1, }, - order:11 + order: 11, }, }, - qiangwu3:{ - mod:{ - targetInRange:function(card,player){ - if (card.name == 'sha') { + qiangwu3: { + mod: { + targetInRange: function (card, player) { + if (card.name == "sha") { const num = get.number(card); - if (num == 'unsure' || num < player.storage.qiangwu) return true; + if (num == "unsure" || num < player.storage.qiangwu) return true; } }, - cardUsable:function(card,player){ - if (card.name == 'sha') { + cardUsable: function (card, player) { + if (card.name == "sha") { const num = get.number(card); - if (num == 'unsure' || num > player.storage.qiangwu) return true; + if (num == "unsure" || num > player.storage.qiangwu) return true; } - } + }, }, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(_status.currentPhase==player&&event.card.name=='sha'&& - get.number(event.card)>player.storage.qiangwu&&event.addCount!==false) return true; + trigger: { player: "useCard1" }, + filter: function (event, player) { + if ( + _status.currentPhase == player && + event.card.name == "sha" && + get.number(event.card) > player.storage.qiangwu && + event.addCount !== false + ) + return true; return false; }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + forced: true, + popup: false, + firstDo: true, + content: function () { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, }, - zhendu:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return /*(get.mode()!='guozhan'||event.player!=player)&&*/event.player.isIn()&&player.countCards('h')>0&&event.player.hasUseTarget({name:'jiu'},null,true); + zhendu: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return ( + /*(get.mode()!='guozhan'||event.player!=player)&&*/ event.player.isIn() && + player.countCards("h") > 0 && + event.player.hasUseTarget({ name: "jiu" }, null, true) + ); }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - var nono=(Math.abs(get.attitude(player,trigger.player))<3); - if(player==trigger.player||get.damageEffect(trigger.player,player,player)<=0||!trigger.player.hasUseTarget({name:'jiu'},null,true)){ - nono=true + direct: true, + preHidden: true, + content: function () { + "step 0"; + var nono = Math.abs(get.attitude(player, trigger.player)) < 3; + if ( + player == trigger.player || + get.damageEffect(trigger.player, player, player) <= 0 || + !trigger.player.hasUseTarget({ name: "jiu" }, null, true) + ) { + nono = true; + } else if (trigger.player.hp > 2) { + nono = true; + } else if ( + trigger.player.hp > 1 && + player.countCards("h") < 3 && + trigger.player.canUse("sha", player) && + !player.countCards("h", "shan") && + trigger.player.countCards("h") >= 3 + ) { + nono = true; } - else if(trigger.player.hp>2){ - nono=true; - } - else if(trigger.player.hp>1&&player.countCards('h')<3&&(trigger.player.canUse('sha',player)&&!player.countCards('h','shan')&&trigger.player.countCards('h')>=3)){ - nono=true; - } - var next=player.chooseToDiscard(get.prompt2('zhendu',trigger.player)); - next.set('ai',function(card){ - if(_status.event.nono) return -1; - return 7-get.useful(card); + var next = player.chooseToDiscard(get.prompt2("zhendu", trigger.player)); + next.set("ai", function (card) { + if (_status.event.nono) return -1; + return 7 - get.useful(card); }); - next.set('logSkill',['zhendu',trigger.player]); - next.set('nono',nono); - next.setHiddenSkill('zhendu'); - "step 1" - if(result.bool){ - trigger.player.chooseUseTarget({name:'jiu'},true,'noTargetDelay','nodelayx'); - } - else{ + next.set("logSkill", ["zhendu", trigger.player]); + next.set("nono", nono); + next.setHiddenSkill("zhendu"); + "step 1"; + if (result.bool) { + trigger.player.chooseUseTarget({ name: "jiu" }, true, "noTargetDelay", "nodelayx"); + } else { event.finish(); } - "step 2" - if(result.bool&&trigger.player!=player) trigger.player.damage(); + "step 2"; + if (result.bool && trigger.player != player) trigger.player.damage(); + }, + ai: { + threaten: 2, + expose: 0.3, }, - ai:{ - threaten:2, - expose:0.3 - } }, - qiluan:{ - audio:'qiluan2', - preHidden:true, - trigger:{global:'phaseEnd'}, - frequent:true, - filter:function(event,player){ - return game.hasPlayer2(function(current){ - return current.getStat('kill')>0 + qiluan: { + audio: "qiluan2", + preHidden: true, + trigger: { global: "phaseEnd" }, + frequent: true, + filter: function (event, player) { + return game.hasPlayer2(function (current) { + return current.getStat("kill") > 0; }); }, - prompt:function(event,player){ - var num=game.countPlayer2(function(current){ - return (current.getStat('kill')||0)*(current==player?3:1); + prompt: function (event, player) { + var num = game.countPlayer2(function (current) { + return (current.getStat("kill") || 0) * (current == player ? 3 : 1); }); - return get.prompt('qiluan')+'(可摸'+get.cnNumber(num)+'张牌)'; + return get.prompt("qiluan") + "(可摸" + get.cnNumber(num) + "张牌)"; }, - content:function(){ + content: function () { //if(get.mode()=='guozhan'){ // player.draw(3); //} //else{ - player.draw(game.countPlayer2(function(current){ - return (current.getStat('kill')||0)*(current==player?3:1); - })); + player.draw( + game.countPlayer2(function (current) { + return (current.getStat("kill") || 0) * (current == player ? 3 : 1); + }) + ); //} }, - subSkill:{ - draw:{ - trigger:{global:'dieAfter'}, - frequent:true, - filter:function(event,player){ - return /*get.mode()!='guozhan'&&*/player!=event.source; + subSkill: { + draw: { + trigger: { global: "dieAfter" }, + frequent: true, + filter: function (event, player) { + return /*get.mode()!='guozhan'&&*/ player != event.source; + }, + content: function () { + player.draw(); }, - content:function(){player.draw()}, }, }, }, - qiluan2:{ - audio:2, + qiluan2: { + audio: 2, }, - zniaoxiang:{ - shaRelated:true, - audio:2, - trigger:{player:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.getParent().directHit.includes(event.target); + zniaoxiang: { + shaRelated: true, + audio: 2, + trigger: { player: "useCardToPlayered" }, + forced: true, + filter: function (event, player) { + return event.card.name == "sha" && !event.getParent().directHit.includes(event.target); }, //priority:-1, - logTarget:'target', - content:function(){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + logTarget: "target", + content: function () { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; + } else { + map[id].shanRequired = 2; } - else{ - map[id].shanRequired=2; - } - } - }, - shangyi:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h'); }, - content:function(){ - "step 0" - player.chooseCardButton(target,target.getCards('h')).set('filterButton',function(button){ - return get.color(button.link)=='black'; - }); - "step 1" - if(result.bool){ + }, + shangyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); + }, + content: function () { + "step 0"; + player + .chooseCardButton(target, target.getCards("h")) + .set("filterButton", function (button) { + return get.color(button.link) == "black"; + }); + "step 1"; + if (result.bool) { target.discard(result.links[0]); } }, - ai:{ - order:11, - result:{ - target:function(player,target){ - return -target.countCards('h'); - } + ai: { + order: 11, + result: { + target: function (player, target) { + return -target.countCards("h"); + }, }, - threaten:1.1 + threaten: 1.1, }, }, - shengxi:{ - trigger:{player:'phaseDiscardBegin'}, - frequent:true, - filter:function(event,player){ - return !player.getStat('damage'); + shengxi: { + trigger: { player: "phaseDiscardBegin" }, + frequent: true, + filter: function (event, player) { + return !player.getStat("damage"); }, - content:function(){ + content: function () { player.draw(2); }, - audio:2, - audioname:['liushan'] + audio: 2, + audioname: ["liushan"], }, - shoucheng:{ - init(player){ - game.addGlobalSkill('shoucheng_draw',player); + shoucheng: { + init(player) { + game.addGlobalSkill("shoucheng_draw", player); }, - trigger:{ - global:['equipAfter','addJudgeAfter','loseAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "loseAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - audio:2, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - if(current==_status.currentPhase) return false; - var evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length&¤t.countCards('h')==0; + audio: 2, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + if (current == _status.currentPhase) return false; + var evt = event.getl(current); + return evt && evt.hs && evt.hs.length && current.countCards("h") == 0; }); }, - content:function(){ - "step 0" - event.list=game.filterPlayer(function(current){ - if(current==_status.currentPhase) return false; - var evt=trigger.getl(current); - return evt&&evt.hs&&evt.hs.length; - }).sortBySeat(_status.currentPhase); - "step 1" - var target=event.list.shift(); - event.target=target; - if(target.isIn()&&target.countCards('h')==0){ - player.chooseBool(get.prompt2('shoucheng',target)).set('ai',function(){ - return get.attitude(_status.event.player,_status.event.getParent().target)>0; + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + if (current == _status.currentPhase) return false; + var evt = trigger.getl(current); + return evt && evt.hs && evt.hs.length; + }) + .sortBySeat(_status.currentPhase); + "step 1"; + var target = event.list.shift(); + event.target = target; + if (target.isIn() && target.countCards("h") == 0) { + player.chooseBool(get.prompt2("shoucheng", target)).set("ai", function () { + return get.attitude(_status.event.player, _status.event.getParent().target) > 0; }); - } - else event.goto(3); - "step 2" - if(result.bool){ - player.logSkill(event.name,target); - if(player!==target&&(get.mode()!=='identity'||player.identity!=='nei')) player.addExpose(0.15); + } else event.goto(3); + "step 2"; + if (result.bool) { + player.logSkill(event.name, target); + if (player !== target && (get.mode() !== "identity" || player.identity !== "nei")) + player.addExpose(0.15); target.draw(); } - "step 3" - if(event.list.length) event.goto(1); + "step 3"; + if (event.list.length) event.goto(1); }, - ai:{ - threaten:1.3, + ai: { + threaten: 1.3, }, - subSkill:{ - draw:{ - trigger:{player:'dieAfter'}, - filter(event,player){ - return !game.hasPlayer(current=>{ - return current.hasSkill('shoucheng'); - },true); + subSkill: { + draw: { + trigger: { player: "dieAfter" }, + filter(event, player) { + return !game.hasPlayer((current) => { + return current.hasSkill("shoucheng"); + }, true); }, - content(){ - game.removeGlobalSkill('shoucheng_draw'); + content() { + game.removeGlobalSkill("shoucheng_draw"); }, - ai:{ - noh:true, - skillTagFilter(player,tag,arg){ - if(player===_status.currentPhase||player.countCards('h')!==1) return false; - return game.hasPlayer(current=>{ - return current.hasSkill('shoucheng')&&player.isFriendOf(current); + ai: { + noh: true, + skillTagFilter(player, tag, arg) { + if (player === _status.currentPhase || player.countCards("h") !== 1) + return false; + return game.hasPlayer((current) => { + return current.hasSkill("shoucheng") && player.isFriendOf(current); }); - } - } - } - } - }, - hengzheng:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - preHidden:true, - filter:function(event,player){ - return !event.numFixed&&(player.hp==1||player.countCards('h')==0); + }, + }, + }, }, - check:function(event,player){ - var num=game.countPlayer(function(current){ - if(current.countCards('he')&¤t!=player&&get.attitude(player,current)<=0){ + }, + hengzheng: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + preHidden: true, + filter: function (event, player) { + return !event.numFixed && (player.hp == 1 || player.countCards("h") == 0); + }, + check: function (event, player) { + var num = game.countPlayer(function (current) { + if ( + current.countCards("he") && + current != player && + get.attitude(player, current) <= 0 + ) { return true; } - if(current.countCards('j')&¤t!=player&&get.attitude(player,current)>0){ + if ( + current.countCards("j") && + current != player && + get.attitude(player, current) > 0 + ) { return true; } }); - return num>=2; + return num >= 2; }, - content:function(){ - "step 0" - var targets=game.filterPlayer(); + content: function () { + "step 0"; + var targets = game.filterPlayer(); targets.remove(player); targets.sort(lib.sort.seat); - event.targets=targets; - event.num=0; + event.targets = targets; + event.num = 0; trigger.changeToZero(); - player.line(targets,'green'); - "step 1" - if(num【勇决】
              每当其他角色于回合内使用一张杀,若目标不是你,你可以获得之,每回合限一次
              '); + content: function () { + "step 0"; + player.awakenSkill("cunsi"); + var cards = player.getCards("h"); + player.give(cards, target); + "step 1"; + target.addSkills("yongjue"); + "step 2"; + target.markSkillCharacter( + "yongjue", + player, + "存嗣", + '
              【勇决】
              每当其他角色于回合内使用一张杀,若目标不是你,你可以获得之,每回合限一次
              ' + ); player.turnOver(); }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(target.isMin()) return 0; - if(player.hp>1){ - if(game.phaseNumber2) return 0; - if(get.attitude(player,target)<5) return 0; + ai: { + order: 4, + result: { + target: function (player, target) { + if (target.isMin()) return 0; + if (player.hp > 1) { + if (game.phaseNumber < game.players.length) return 0; + if (target.hp == 1 && target.maxHp > 2) return 0; + if (get.attitude(player, target) < 5) return 0; } - if(get.attitude(player,target)<5) return 0; - if(target.hp==1&&target.maxHp>2) return 0.2; - if(target==game.me) return 1.2; + if (get.attitude(player, target) < 5) return 0; + if (target.hp == 1 && target.maxHp > 2) return 0.2; + if (target == game.me) return 1.2; return 1; - } + }, }, - expose:0.5, - threaten:1.5 - } + expose: 0.5, + threaten: 1.5, + }, }, - fenming:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - check:function(event,player){ - var num=game.countPlayer(function(current){ - if(current.isLinked()&¤t.countCards('he')){ - return get.effect(current,{name:'guohe_copy2'},player,player); + fenming: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + check: function (event, player) { + var num = game.countPlayer(function (current) { + if (current.isLinked() && current.countCards("he")) { + return get.effect(current, { name: "guohe_copy2" }, player, player); } }); - return num<0; + return num < 0; }, - filter:function(event,player){ + filter: function (event, player) { return player.isLinked(); }, - preHidden:true, - prompt:'是否发动【奋命】?', - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - if(current.isLinked()&¤t.countCards('he')){ + preHidden: true, + prompt: "是否发动【奋命】?", + logTarget: function (event, player) { + return game.filterPlayer(function (current) { + if (current.isLinked() && current.countCards("he")) { return true; } }); }, - content:function(){ - "step 0" - event.targets=game.filterPlayer(function(current){ - if(current.isLinked()&¤t.countCards('he')){ + content: function () { + "step 0"; + event.targets = game.filterPlayer(function (current) { + if (current.isLinked() && current.countCards("he")) { return true; } }); - event.num=0; + event.num = 0; event.targets.sort(lib.sort.seat); - "step 1" - if(event.num0) return 0; - if(_status.event.noe) return 12-get.value(card); - return 2*_status.event.damage-get.value(card); - }).set('damage',get.damageEffect(trigger.player,player,trigger.player)).set('noe',trigger.player.hasSkillTag('noe')); - } - else{ + next.set("logSkill", ["xiaoguo", trigger.player]); + next.set( + "eff", + (function () { + if (trigger.player.hasSkillTag("noe")) + return get.attitude(_status.event.player, trigger.player); + return get.damageEffect(trigger.player, player, _status.event.player); + })() + ); + "step 1"; + if (result.bool) { + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.15); + trigger.player + .chooseToDiscard( + "he", + "弃置一张装备牌并令" + get.translation(player) + "摸一张牌,或受到1点伤害", + { type: "equip" } + ) + .set("ai", function (card) { + if (_status.event.damage > 0) return 0; + if (_status.event.noe) return 12 - get.value(card); + return 2 * _status.event.damage - get.value(card); + }) + .set("damage", get.damageEffect(trigger.player, player, trigger.player)) + .set("noe", trigger.player.hasSkillTag("noe")); + } else { event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { player.draw(); - } - else{ + } else { trigger.player.damage(); } - } + }, }, - suishi:{ - audio:2, - trigger:{global:'dying'}, - forced:true, - popup:false, + suishi: { + audio: 2, + trigger: { global: "dying" }, + forced: true, + popup: false, //priority:12, - check:function(){ + check: function () { return false; }, - filter:function(event,player){ - return event.player!=player&&event.parent.name=='damage'&&event.parent.source&&event.parent.source!=event.player; + filter: function (event, player) { + return ( + event.player != player && + event.parent.name == "damage" && + event.parent.source && + event.parent.source != event.player + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var str; - if(trigger.parent.source==player){ - str='随势:是否摸一张牌?'; + if (trigger.parent.source == player) { + str = "随势:是否摸一张牌?"; + } else { + str = "随势:是否令" + get.translation(player) + "摸一张牌?"; } - else{ - str='随势:是否令'+get.translation(player)+'摸一张牌?' - } - trigger.parent.source.chooseBool(str).set('ai',function(){ - return get.attitude(_status.event.player,_status.event.target)>0; - }).set('target',player); - 'step 1' - if(result.bool){ - player.logSkill('suishi'); - trigger.parent.source.line(player,'green'); + trigger.parent.source + .chooseBool(str) + .set("ai", function () { + return get.attitude(_status.event.player, _status.event.target) > 0; + }) + .set("target", player); + "step 1"; + if (result.bool) { + player.logSkill("suishi"); + trigger.parent.source.line(player, "green"); player.draw(); } }, - group:'suishi2' + group: "suishi2", }, - suishi2:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - check:function(){ + suishi2: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + check: function () { return false; }, - filter:function(event,player){ - return event.player!=player&&event.source&&event.source!=player&&event.source!=event.player; + filter: function (event, player) { + return ( + event.player != player && + event.source && + event.source != player && + event.source != event.player + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var str; - if(trigger.source==player){ - str='随势:是否失去1点体力?'; + if (trigger.source == player) { + str = "随势:是否失去1点体力?"; + } else { + str = "随势:是否令" + get.translation(player) + "失去1点体力?"; } - else{ - str='随势:是否令'+get.translation(player)+'失去1点体力?' - } - trigger.source.chooseBool(str).set('ai',function(){ - return get.attitude(_status.event.player,_status.event.target)<0; - }).set('target',player); - 'step 1' - if(result.bool){ - player.logSkill('suishi'); - trigger.source.line(player,'green'); + trigger.source + .chooseBool(str) + .set("ai", function () { + return get.attitude(_status.event.player, _status.event.target) < 0; + }) + .set("target", player); + "step 1"; + if (result.bool) { + player.logSkill("suishi"); + trigger.source.line(player, "green"); player.loseHp(); } }, }, - sijian:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + sijian: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - audio:2, - preHidden:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length>0; + direct: true, + audio: 2, + preHidden: true, + filter: function (event, player) { + if (player.countCards("h")) return false; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length > 0; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('sijian'),'弃置一名其他角色的一张牌',function(card,player,target){ - return player!=target&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - player.logSkill('sijian',result.targets); - event.target=result.targets[0]; - player.discardPlayerCard(event.target,true); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("sijian"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + return player != target && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("sijian", result.targets); + event.target = result.targets[0]; + player.discardPlayerCard(event.target, true); + } else { event.finish(); } }, - ai:{ - expose:0.2, - } + ai: { + expose: 0.2, + }, }, - quji:{ - audio:2, - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - selectCard:function(){ - var player=_status.event.player; + quji: { + audio: 2, + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + selectCard: function () { + var player = _status.event.player; return player.getDamagedHp(); }, - filterTarget:function(card,player,target){ - return target.hp-1; - if(num==2) return att>0; - return att>1; + }, + junbing: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player.countCards("h") <= 1 && + (player == event.player || player.hasSkill("junbing")) + ); + }, + direct: true, + checkx: function (target, player) { + if (target) { + var num = target.countCards("h"); + var att = get.attitude(player, target); + if (num == 0) return true; + if (num == 1) return att > -1; + if (num == 2) return att > 0; + return att > 1; } return false; }, - content:function(){ - "step 0" - event.target=player; - event.player=trigger.player; + content: function () { + "step 0"; + event.target = player; + event.player = trigger.player; var prompt; - if(player==event.player) prompt='是否发动【郡兵】摸一张牌?'; - else prompt=('###是否对'+get.translation(event.target)+'发动【郡兵】?###'+(event.player==event.target?'摸一张牌':'摸一张牌,将所有手牌交给该角色,然后该角色交给你等量的手牌')); - event.player.chooseBool(prompt).set('choice',lib.skill.junbing.checkx(event.target,event.player)); - "step 1" - if(!result.bool){event.finish();return} - target.logSkill('junbing',player); - if(player==target) event.finish(); + if (player == event.player) prompt = "是否发动【郡兵】摸一张牌?"; + else + prompt = + "###是否对" + + get.translation(event.target) + + "发动【郡兵】?###" + + (event.player == event.target + ? "摸一张牌" + : "摸一张牌,将所有手牌交给该角色,然后该角色交给你等量的手牌"); + event.player + .chooseBool(prompt) + .set("choice", lib.skill.junbing.checkx(event.target, event.player)); + "step 1"; + if (!result.bool) { + event.finish(); + return; + } + target.logSkill("junbing", player); + if (player == target) event.finish(); player.draw(); - "step 2" - var cards=player.getCards('h'); - player.give(cards,target); - event.num=cards.length; - "step 3" - var he=target.getCards('he'); - if(!he.length) event.finish(); - else if(he.length<=num) event._result={cards:he}; - else target.chooseCard('选择还给'+get.translation(player)+'的牌',true,event.num,'he'); - "step 4" - target.give(result.cards,player); + "step 2"; + var cards = player.getCards("h"); + player.give(cards, target); + event.num = cards.length; + "step 3"; + var he = target.getCards("he"); + if (!he.length) event.finish(); + else if (he.length <= num) event._result = { cards: he }; + else + target.chooseCard( + "选择还给" + get.translation(player) + "的牌", + true, + event.num, + "he" + ); + "step 4"; + target.give(result.cards, player); }, }, - xiongyi:{ - skillAnimation:true, - animationColor:'gray', - unique:true, - enable:'phaseUse', - audio:2, - limited:true, - filterTarget:function(card,player,target){ - if(get.mode()=='guozhan'){ - if(player==target) return true; - if(player.identity=='unknown'){ - if(!player.wontYe('qun')) return false; - return target.identity=='qun'; + xiongyi: { + skillAnimation: true, + animationColor: "gray", + unique: true, + enable: "phaseUse", + audio: 2, + limited: true, + filterTarget: function (card, player, target) { + if (get.mode() == "guozhan") { + if (player == target) return true; + if (player.identity == "unknown") { + if (!player.wontYe("qun")) return false; + return target.identity == "qun"; } return target.isFriendOf(player); - } - else{ + } else { return true; } }, - multitarget:true, - multiline:true, - selectTarget:function(){ - if(get.mode()=='guozhan') return -1; - return [1,Infinity]; + multitarget: true, + multiline: true, + selectTarget: function () { + if (get.mode() == "guozhan") return -1; + return [1, Infinity]; }, - content:function(){ - "step 0" - player.awakenSkill('xiongyi'); - game.asyncDraw(targets,3); - "step 1" - if(player.isDamaged()){ - if(get.mode()=='guozhan'){ - if(player.isMinor(true)){ + content: function () { + "step 0"; + player.awakenSkill("xiongyi"); + game.asyncDraw(targets, 3); + "step 1"; + if (player.isDamaged()) { + if (get.mode() == "guozhan") { + if (player.isMinor(true)) { player.recover(); } - } - else if(player.isMinHp()){ + } else if (player.isMinHp()) { player.recover(); } } }, - ai:{ - order:1, - result:{ - target:function(player){ - var num=player.countCards('h'); - if(player.hp==1) return 1; - if(player.hp==2&&num<=2) return 1; - if(player.hp==3&&num<=1) return 1; - if(game.phaseNumber1){ + if (event.num > 1) { event.num--; event.goto(1); } } }, - ai:{ - threaten:0.8, - expose:0.1 - } + ai: { + threaten: 0.8, + expose: 0.1, + }, }, - shushen:{ - audio:2, - trigger:{player:'recoverAfter'}, - direct:true, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" - player.chooseTarget(get.prompt('shushen'),'令一名其他角色选择摸两张牌或回复1点体力',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - "step 2" - if(result.bool){ + shushen: { + audio: 2, + trigger: { player: "recoverAfter" }, + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + player + .chooseTarget( + get.prompt("shushen"), + "令一名其他角色选择摸两张牌或回复1点体力", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 2"; + if (result.bool) { event.count--; - player.logSkill('shushen',result.targets); - result.targets[0].chooseDrawRecover(2,true); - if(event.count) event.goto(1); + player.logSkill("shushen", result.targets); + result.targets[0].chooseDrawRecover(2, true); + if (event.count) event.goto(1); } }, - ai:{ - threaten:0.8, - expose:0.1 - } + ai: { + threaten: 0.8, + expose: 0.1, + }, }, - shenzhi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - check:function(event,player){ - if(player.hp>2) return false; - var cards=player.getCards('h'); - if(cards.length3) return false; - for(var i=0;i7||get.tag(cards[i],'recover')>=1) return false; + shenzhi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + check: function (event, player) { + if (player.hp > 2) return false; + var cards = player.getCards("h"); + if (cards.length < player.hp) return false; + if (cards.length > 3) return false; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) > 7 || get.tag(cards[i], "recover") >= 1) return false; } return true; }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - preHidden:true, - content:function(){ - "step 0" - var cards=player.getCards('h'); - event.bool=cards.length>=player.hp; + preHidden: true, + content: function () { + "step 0"; + var cards = player.getCards("h"); + event.bool = cards.length >= player.hp; player.discard(cards); - "step 1" - if(event.bool){ + "step 1"; + if (event.bool) { player.recover(); } - } - }, - wuji:{ - skillAnimation:true, - animationColor:'orange', - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - unique:true, - juexingji:true, - filter:function(event,player){ - return player.getStat('damage')>=3&&!player.storage.wuji; }, - content:function(){ - "step 0" - player.removeSkills('huxiao'); + }, + wuji: { + skillAnimation: true, + animationColor: "orange", + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + unique: true, + juexingji: true, + filter: function (event, player) { + return player.getStat("damage") >= 3 && !player.storage.wuji; + }, + content: function () { + "step 0"; + player.removeSkills("huxiao"); player.gainMaxHp(); - "step 1" + "step 1"; player.recover(); - player.awakenSkill('wuji'); - player.storage.wuji=true; + player.awakenSkill("wuji"); + player.storage.wuji = true; - var card=get.cardPile('qinglong','field'); - if(card){ - player.gain(card,'gain2','log'); + var card = get.cardPile("qinglong", "field"); + if (card) { + player.gain(card, "gain2", "log"); } - } + }, }, - xueji_old:{ - audio:'xueji', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hp0; + xueji_old: { + audio: "xueji", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hp < player.maxHp && player.countCards("he", { color: "red" }) > 0; }, - filterTarget:function(card,player,target){ - return player!=target&&get.distance(player,target,'attack')<=1; + filterTarget: function (card, player, target) { + return player != target && get.distance(player, target, "attack") <= 1; }, - selectTarget:function(){ - return [1,_status.event.player.maxHp-_status.event.player.hp]; + selectTarget: function () { + return [1, _status.event.player.maxHp - _status.event.player.hp]; }, - position:'he', - filterCard:function(card){ - return get.color(card)=='red'; + position: "he", + filterCard: function (card) { + return get.color(card) == "red"; }, - check:function(card){ - return 8-get.useful(card); + check: function (card) { + return 8 - get.useful(card); }, - content:function(){ - "step 0" + content: function () { + "step 0"; target.damage(); - "step 1" + "step 1"; target.draw(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - return get.damageEffect(target,player); - } + ai: { + order: 7, + result: { + target: function (player, target) { + return get.damageEffect(target, player); + }, }, - threaten:function(player,target){ - if(target.hp==1) return 2; - if(target.hp==2) return 1.5; + threaten: function (player, target) { + if (target.hp == 1) return 2; + if (target.hp == 2) return 1.5; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(target.hp==target.maxHp&&target.hasFriend()) return [0,1]; + maixie: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (target.hp == target.maxHp && target.hasFriend()) return [0, 1]; } - if(get.tag(card,'recover')&&player.hp>=player.maxHp-1) return [0,0]; - } - } - } + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, + }, + }, }, //FW关银屏 - oldhuxiao:{ - shaRelated:true, - audio:'huxiao', - trigger:{player:'shaMiss'}, - forced:true, - content:function(){ - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + oldhuxiao: { + shaRelated: true, + audio: "huxiao", + trigger: { player: "shaMiss" }, + forced: true, + content: function () { + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, }, - oldwuji:{ - unique:true, - audio:'wuji', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getStat('damage')>=3&&!player.storage.oldwuji; + oldwuji: { + unique: true, + audio: "wuji", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.getStat("damage") >= 3 && !player.storage.oldwuji; }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'orange', - content:function(){ - 'step 0' - player.removeSkills('oldhuxiao'); + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "orange", + content: function () { + "step 0"; + player.removeSkills("oldhuxiao"); player.gainMaxHp(); - 'step 1' + "step 1"; player.recover(); - player.awakenSkill('oldwuji'); + player.awakenSkill("oldwuji"); }, }, - xueji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',{color:'red'})>0; + xueji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { color: "red" }) > 0; }, - filterTarget:true, - selectTarget:function(){ - var player=_status.event.player - return [1,Math.max(1,player.getDamagedHp())]; + filterTarget: true, + selectTarget: function () { + var player = _status.event.player; + return [1, Math.max(1, player.getDamagedHp())]; }, - position:'he', - filterCard:{color:'red'}, - check:function(card){ - return 8-get.value(card); + position: "he", + filterCard: { color: "red" }, + check: function (card) { + return 8 - get.value(card); }, - multitarget:true, - multiline:true, - line:'fire', - content:function(){ - 'step 0' - event.delay=false; - for(var i=0;i=0;i--){ - ui.cardPile.insertBefore(cards[i].fix(),ui.cardPile.firstChild); + delay: false, + content: function () { + "step 0"; + var evt = event.getParent(2); + evt.set("aocai", true); + var cards = get.cards(get.mode() != "guozhan" && player.countCards("h") == 0 ? 4 : 2); + for (var i = cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(cards[i].fix(), ui.cardPile.firstChild); } - var aozhan=player.hasSkill('aozhan'); - player.chooseButton(['傲才:选择要'+(evt.name=='chooseToUse'?'使用':'打出')+'的牌',cards]).set('filterButton',function(button){ - return _status.event.cards.includes(button.link); - }).set('cards',cards.filter(function(card){ - if(aozhan&&card.name=='tao'){ - return evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)||evt.filterCard({ - name:'shan',isCard:true,cards:[card], - },evt.player,evt); + var aozhan = player.hasSkill("aozhan"); + player + .chooseButton([ + "傲才:选择要" + (evt.name == "chooseToUse" ? "使用" : "打出") + "的牌", + cards, + ]) + .set("filterButton", function (button) { + return _status.event.cards.includes(button.link); + }) + .set( + "cards", + cards.filter(function (card) { + if (aozhan && card.name == "tao") { + return ( + evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) || + evt.filterCard( + { + name: "shan", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ); + } + return evt.filterCard(card, evt.player, evt); + }) + ) + .set("ai", function (button) { + var evt = _status.event.getParent(3); + if (evt && evt.ai) { + var tmp = _status.event; + _status.event = evt; + var result = (evt.ai || event.ai1)(button.link, _status.event.player, evt); + _status.event = tmp; + return result; + } + return 1; + }); + "step 1"; + var evt = event.getParent(2); + if (result.bool && result.links && result.links.length) { + var card = result.links[0]; + var name = card.name, + aozhan = player.hasSkill("aozhan") && name == "tao"; + if (aozhan) { + name = evt.filterCard( + { + name: "sha", + isCard: true, + cards: [card], + }, + evt.player, + evt + ) + ? "sha" + : "shan"; } - return evt.filterCard(card,evt.player,evt); - })).set('ai',function(button){ - var evt=_status.event.getParent(3); - if(evt&&evt.ai){ - var tmp=_status.event; - _status.event=evt; - var result=(evt.ai||event.ai1)(button.link,_status.event.player,evt); - _status.event=tmp; - return result; - } - return 1; - }); - 'step 1' - var evt=event.getParent(2); - if(result.bool&&result.links&&result.links.length){ - var card=result.links[0]; - var name=card.name,aozhan=(player.hasSkill('aozhan')&&name=='tao'); - if(aozhan){ - name=evt.filterCard({ - name:'sha',isCard:true,cards:[card], - },evt.player,evt)?'sha':'shan'; - } - if(evt.name=='chooseToUse'){ - game.broadcastAll(function(result,name){ - lib.skill.aocai_backup.viewAs={name:name,cards:[result],isCard:true}; - },card,name); - evt.set('_backupevent','aocai_backup'); - evt.set('openskilldialog',('请选择'+get.translation(card)+'的目标')) - evt.backup('aocai_backup'); - } - else{ + if (evt.name == "chooseToUse") { + game.broadcastAll( + function (result, name) { + lib.skill.aocai_backup.viewAs = { + name: name, + cards: [result], + isCard: true, + }; + }, + card, + name + ); + evt.set("_backupevent", "aocai_backup"); + evt.set("openskilldialog", "请选择" + get.translation(card) + "的目标"); + evt.backup("aocai_backup"); + } else { delete evt.result.skill; delete evt.result.used; - evt.result.card=get.autoViewAs(result.links[0]); - if(aozhan) evt.result.card.name=name; - evt.result.cards=[result.links[0]]; + evt.result.card = get.autoViewAs(result.links[0]); + if (aozhan) evt.result.card.name = name; + evt.result.cards = [result.links[0]]; evt.redo(); return; } } evt.goto(0); }, - ai:{ - effect:{ - target:function(card,player,target,effect){ - if(get.tag(card,'respondShan')) return 0.7; - if(get.tag(card,'respondSha')) return 0.7; - } + ai: { + effect: { + target: function (card, player, target, effect) { + if (get.tag(card, "respondShan")) return 0.7; + if (get.tag(card, "respondSha")) return 0.7; + }, }, - order:11, - respondShan:true, - respondSha:true, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + order: 11, + respondShan: true, + respondSha: true, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; - } - } - } + }, + }, + }, }, - aocai_backup:{ - sourceSkill:'aocai', - precontent:function(){ + aocai_backup: { + sourceSkill: "aocai", + precontent: function () { delete event.result.skill; - var name=event.result.card.name,cards=event.result.card.cards.slice(0); - event.result.cards=cards; - var rcard=cards[0],card; - if(rcard.name==name) card=get.autoViewAs(rcard); - else card=get.autoViewAs({name,isCard:true}); - event.result.card=card; + var name = event.result.card.name, + cards = event.result.card.cards.slice(0); + event.result.cards = cards; + var rcard = cards[0], + card; + if (rcard.name == name) card = get.autoViewAs(rcard); + else card = get.autoViewAs({ name, isCard: true }); + event.result.card = card; }, - filterCard:function(){return false}, - selectCard:-1, + filterCard: function () { + return false; + }, + selectCard: -1, }, - hongyuan:{ - trigger:{player:'phaseDrawBegin2'}, - direct:true, - audio:2, - filter:function(event,player){ - return !event.numFixed&&event.num>0; + hongyuan: { + trigger: { player: "phaseDrawBegin2" }, + direct: true, + audio: 2, + filter: function (event, player) { + return !event.numFixed && event.num > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; var check; - if(player.countCards('h')==0){ - check=false; + if (player.countCards("h") == 0) { + check = false; + } else { + check = + game.countPlayer(function (current) { + return player != current && get.attitude(player, current) > 1; + }) >= 2; } - else{ - check=(game.countPlayer(function(current){ - return player!=current&&get.attitude(player,current)>1; - })>=2); - } - if(get.is.versus()){ - event.versus=true; - player.chooseBool(get.prompt2('hongyuan')).ai=function(){ - return game.countPlayer(function(current){ - return player.side==current.side; - })>2; + if (get.is.versus()) { + event.versus = true; + player.chooseBool(get.prompt2("hongyuan")).ai = function () { + return ( + game.countPlayer(function (current) { + return player.side == current.side; + }) > 2 + ); }; + } else { + player + .chooseTarget( + get.prompt2("hongyuan"), + [1, 2], + function (card, player, target) { + return player != target; + }, + function (target) { + if (!_status.event.check) return 0; + return get.attitude(_status.event.player, target); + } + ) + .set("check", check); } - else{ - player.chooseTarget(get.prompt2('hongyuan'),[1,2],function(card,player,target){ - return player!=target; - },function(target){ - if(!_status.event.check) return 0; - return get.attitude(_status.event.player,target); - }).set('check',check); - } - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { var targets; - if(event.versus){ - targets=game.filterPlayer(function(current){ - return current!=player&¤t.side==player.side; + if (event.versus) { + targets = game.filterPlayer(function (current) { + return current != player && current.side == player.side; }); + } else { + targets = result.targets; } - else{ - targets=result.targets; - } - player.logSkill('hongyuan',targets); + player.logSkill("hongyuan", targets); game.asyncDraw(targets); trigger.num--; } }, }, - huanshi:{ - audio:2, - trigger:{global:'judge'}, - filter:function(event,player){ - return player.countCards('he')>0; + huanshi: { + audio: 2, + trigger: { global: "judge" }, + filter: function (event, player) { + return player.countCards("he") > 0; }, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)<=0) return false; - var cards=player.getCards('he'); - var judge=event.judge(event.player.judging[0]); - for(var i=0;ijudge) return true; - if(_status.currentPhase!=player&&judge2==judge&&get.color(cards[i])=='red'&&get.useful(cards[i])<5) return true; + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) <= 0) return false; + var cards = player.getCards("he"); + var judge = event.judge(event.player.judging[0]); + for (var i = 0; i < cards.length; i++) { + var judge2 = event.judge(cards[i]); + if (judge2 > judge) return true; + if ( + _status.currentPhase != player && + judge2 == judge && + get.color(cards[i]) == "red" && + get.useful(cards[i]) < 5 + ) + return true; } return false; }, - content:function(){ - "step 0" - var target=trigger.player; - var judge=trigger.judge(target.judging[0]); - var attitude=get.attitude(target,player); - target.choosePlayerCard('请选择代替判定的牌','he','visible',true,player).set('ai',function(button){ - var card=button.link; - var judge=_status.event.judge; - var attitude=_status.event.attitude; - var result=trigger.judge(card)-judge; - var player=_status.event.player; - if(result>0){ - return 20+result; - } - if(result==0){ - if(_status.currentPhase==player) return 0; - if(attitude>=0){ - return get.color(card)=='red'?7:0-get.value(card); + content: function () { + "step 0"; + var target = trigger.player; + var judge = trigger.judge(target.judging[0]); + var attitude = get.attitude(target, player); + target + .choosePlayerCard("请选择代替判定的牌", "he", "visible", true, player) + .set("ai", function (button) { + var card = button.link; + var judge = _status.event.judge; + var attitude = _status.event.attitude; + var result = trigger.judge(card) - judge; + var player = _status.event.player; + if (result > 0) { + return 20 + result; } - else{ - return get.color(card)=='black'?10:0+get.value(card); + if (result == 0) { + if (_status.currentPhase == player) return 0; + if (attitude >= 0) { + return get.color(card) == "red" ? 7 : 0 - get.value(card); + } else { + return get.color(card) == "black" ? 10 : 0 + get.value(card); + } } - } - if(attitude>=0){ - return get.color(card)=='red'?0:-10+result; - } - else{ - return get.color(card)=='black'?0:-10+result; - } - }).set('filterButton',function(button){ - var player=_status.event.target; - var card=button.link; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('judge',judge).set('attitude',attitude); - "step 1" - if(result.bool){ - event.card=result.links[0]; - player.respond(event.card,'highlight','noOrdering').nopopup=true; - } - else{ + if (attitude >= 0) { + return get.color(card) == "red" ? 0 : -10 + result; + } else { + return get.color(card) == "black" ? 0 : -10 + result; + } + }) + .set("filterButton", function (button) { + var player = _status.event.target; + var card = button.link; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + }) + .set("judge", judge) + .set("attitude", attitude); + "step 1"; + if (result.bool) { + event.card = result.links[0]; + player.respond(event.card, "highlight", "noOrdering").nopopup = true; + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=event.card; + trigger.player.judging[0] = event.card; trigger.orderingCards.add(event.card); - game.log(trigger.player,'的判定牌改为',event.card); + game.log(trigger.player, "的判定牌改为", event.card); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } - }, - mingzhe:{ - audio:2, - trigger:{ - player:['useCard','respond','loseAfter'], - global:'loseAsyncAfter', + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, }, - frequent:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.name.indexOf('lose')!=0) return get.color(event.card)=='red'; - if(event.type!='discard') return false; - var evt=event.getl(player); - if(evt&&evt.cards2){ - for(var i=0;i0&¤t.hp<=player.countCards('he')&&player.inRange(current); - }); + duwu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.hasSkill("duwu2") == false && + game.hasPlayer(function (current) { + return ( + current.hp > 0 && + current.hp <= player.countCards("he") && + player.inRange(current) + ); + }) + ); }, - filterCard:function(){ - if(ui.selected.targets.length) return false; + filterCard: function () { + if (ui.selected.targets.length) return false; return true; }, - position:'he', - selectCard:[1,Infinity], - complexSelect:true, - complexCard:true, - filterTarget:function(card,player,target){ - return target!=player&&target.hp>0&&player.inRange(target)&&ui.selected.cards.length==target.hp; + position: "he", + selectCard: [1, Infinity], + complexSelect: true, + complexCard: true, + filterTarget: function (card, player, target) { + return ( + target != player && + target.hp > 0 && + player.inRange(target) && + ui.selected.cards.length == target.hp + ); }, - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&¤t.hp>0&&player.inRange(current)&&ui.selected.cards.length==current.hp&&get.damageEffect(current,player,player)>0; - })) return 0; - switch(ui.selected.cards.length){ - case 0:return 8-get.value(card); - case 1:return 6-get.value(card); - case 2:return 3-get.value(card); - default:return 0; + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current.hp > 0 && + player.inRange(current) && + ui.selected.cards.length == current.hp && + get.damageEffect(current, player, player) > 0 + ); + }) + ) + return 0; + switch (ui.selected.cards.length) { + case 0: + return 8 - get.value(card); + case 1: + return 6 - get.value(card); + case 2: + return 3 - get.value(card); + default: + return 0; } }, - content:function(){ - player.addTempSkill('duwu3'); - target.damage('nocard'); + content: function () { + player.addTempSkill("duwu3"); + target.damage("nocard"); }, - ai:{ - damage:true, - order:2, - result:{ - target:function(player,target){ - return get.damageEffect(target,player); - } + ai: { + damage: true, + order: 2, + result: { + target: function (player, target) { + return get.damageEffect(target, player); + }, }, - threaten:1.5, - expose:0.3 - } - }, - duwu2:{charlotte:true}, - duwu3:{ - trigger:{global:'dyingAfter'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return event.player.isIn()&&event.reason&&event.reason.getParent().name=='duwu'; + threaten: 1.5, + expose: 0.3, }, - content:function(){ + }, + duwu2: { charlotte: true }, + duwu3: { + trigger: { global: "dyingAfter" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return event.player.isIn() && event.reason && event.reason.getParent().name == "duwu"; + }, + content: function () { player.loseHp(); - player.addTempSkill('duwu2'); - } + player.addTempSkill("duwu2"); + }, }, - yicong:{ - trigger:{ - player:["changeHp"], + yicong: { + trigger: { + player: ["changeHp"], }, - audio:2, - audioname:['re_gongsunzan'], - forced:true, - filter:function(event,player){ - return get.sgn(player.hp-2.5)!=get.sgn(player.hp-2.5-event.num); + audio: 2, + audioname: ["re_gongsunzan"], + forced: true, + filter: function (event, player) { + return get.sgn(player.hp - 2.5) != get.sgn(player.hp - 2.5 - event.num); }, - content:function (){}, - mod:{ - globalFrom:function(from,to,current){ - if(from.hp>2) return current-1; + content: function () {}, + mod: { + globalFrom: function (from, to, current) { + if (from.hp > 2) return current - 1; }, - globalTo:function(from,to,current){ - if(to.hp<=2) return current+1; + globalTo: function (from, to, current) { + if (to.hp <= 2) return current + 1; }, }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, - yongsi:{ - audio:2, - group:['yongsi1','yongsi2'], - locked:true, - ai:{ - threaten:3.2 - } + yongsi: { + audio: 2, + group: ["yongsi1", "yongsi2"], + locked: true, + ai: { + threaten: 3.2, + }, }, - yongsi1:{ - audio:true, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ + yongsi1: { + audio: true, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=game.countGroup(); - } - }, - yongsi2:{ - audio:true, - trigger:{player:'phaseDiscardBegin'}, - forced:true, - content:function(){ - player.chooseToDiscard(game.countGroup(),'he',true); - } - }, - bifa:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - filter:function(event,player){ - return player.countCards('h')>0; + content: function () { + trigger.num += game.countGroup(); }, - content:function(){ - "step 0" + }, + yongsi2: { + audio: true, + trigger: { player: "phaseDiscardBegin" }, + forced: true, + content: function () { + player.chooseToDiscard(game.countGroup(), "he", true); + }, + }, + bifa: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:true, - filterTarget:function(card,player,target){ - return player!=target&&!target.getExpansions('bifa2').length; + filterCard: true, + filterTarget: function (card, player, target) { + return player != target && !target.getExpansions("bifa2").length; }, - ai1:function(card){ - return 7-get.value(card); + ai1: function (card) { + return 7 - get.value(card); }, - ai2:function(target){ - var num=target.hasSkillTag('maixie')?2:0; - return -get.attitude(_status.event.player,target)-num; + ai2: function (target) { + var num = target.hasSkillTag("maixie") ? 2 : 0; + return -get.attitude(_status.event.player, target) - num; }, - prompt:get.prompt2('bifa'), + prompt: get.prompt2("bifa"), }); - "step 1" - if(result.bool){ - event.forceDie=true; - var target=result.targets[0]; - event.target=target; - player.logSkill('bifa',result.targets[0]); - event.card=result.cards[0]; - target.storage.bifa2=[result.cards[0],player]; - if(!_status.connectMode&&player.isUnderControl(true)) player.$giveAuto(result.cards[0],target,false); - else player.$give(1,target,false); - target.addToExpansion(result.cards[0]).gaintag.add('bifa2'); - } - else event.finish(); - "step 2" - if(target.getExpansions('bifa2').includes(card)){ - target.addSkill('bifa2'); - } - else delete target.storage.bifa2; + "step 1"; + if (result.bool) { + event.forceDie = true; + var target = result.targets[0]; + event.target = target; + player.logSkill("bifa", result.targets[0]); + event.card = result.cards[0]; + target.storage.bifa2 = [result.cards[0], player]; + if (!_status.connectMode && player.isUnderControl(true)) + player.$giveAuto(result.cards[0], target, false); + else player.$give(1, target, false); + target.addToExpansion(result.cards[0]).gaintag.add("bifa2"); + } else event.finish(); + "step 2"; + if (target.getExpansions("bifa2").includes(card)) { + target.addSkill("bifa2"); + } else delete target.storage.bifa2; + }, + ai: { + threaten: 1.7, + expose: 0.3, }, - ai:{ - threaten:1.7, - expose:0.3 - } }, - bifa2:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - charlotte:true, - audio:false, - filter:function(event,player){ - return player.storage.bifa2&&player.getExpansions('bifa2').includes(player.storage.bifa2[0]); + bifa2: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + charlotte: true, + audio: false, + filter: function (event, player) { + return ( + player.storage.bifa2 && + player.getExpansions("bifa2").includes(player.storage.bifa2[0]) + ); }, - content:function(){ - "step 0" - if(player.storage.bifa2[1].isIn()&&player.countCards('h')){ - player.chooseCard(get.translation(player.storage.bifa2[1])+'的笔伐牌为:',function(card){ - return get.type(card,'trick')==_status.event.type; - }).set('ai',function(card){ - return 8-get.value(card); - }).set('type',get.type(player.storage.bifa2[0],'trick')).set('promptx',[[player.storage.bifa2[0]],'请交给其一张与此牌类别相同的手牌,否则失去1点体力' ]); + content: function () { + "step 0"; + if (player.storage.bifa2[1].isIn() && player.countCards("h")) { + player + .chooseCard( + get.translation(player.storage.bifa2[1]) + "的笔伐牌为:", + function (card) { + return get.type(card, "trick") == _status.event.type; + } + ) + .set("ai", function (card) { + return 8 - get.value(card); + }) + .set("type", get.type(player.storage.bifa2[0], "trick")) + .set("promptx", [ + [player.storage.bifa2[0]], + "请交给其一张与此牌类别相同的手牌,否则失去1点体力", + ]); + } else { + event.directfalse = true; } - else{ - event.directfalse=true; - } - "step 1" - if(result.bool&&!event.directfalse){ - player.give(result.cards,player.storage.bifa2[1]); - player.gain(player.storage.bifa2[0],'draw'); - } - else{ + "step 1"; + if (result.bool && !event.directfalse) { + player.give(result.cards, player.storage.bifa2[1]); + player.gain(player.storage.bifa2[0], "draw"); + } else { player.loseHp(); } - "step 2" - player.removeSkill('bifa2'); + "step 2"; + player.removeSkill("bifa2"); }, - marktext:'檄', - intro:{ - markcount:()=>1, - name:'笔伐', - content:'已成为〖笔伐〗的目标', + marktext: "檄", + intro: { + markcount: () => 1, + name: "笔伐", + content: "已成为〖笔伐〗的目标", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage[skill]; }, }, - songci:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(!player.storage.songci) return true; - return game.hasPlayer(function(current){ + songci: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (!player.storage.songci) return true; + return game.hasPlayer(function (current) { return !player.storage.songci.includes(current); }); }, - init:function(player){ - if(!player.storage.songci) player.storage.songci=[]; + init: function (player) { + if (!player.storage.songci) player.storage.songci = []; }, - filterTarget:function(card,player,target){ - return (!player.storage.songci||!player.storage.songci.includes(target)); + filterTarget: function (card, player, target) { + return !player.storage.songci || !player.storage.songci.includes(target); }, - content:function(){ - if(target.countCards('h')>target.hp){ - target.chooseToDiscard(2,'he',true); - } - else{ + content: function () { + if (target.countCards("h") > target.hp) { + target.chooseToDiscard(2, "he", true); + } else { target.draw(2); } - if(!player.storage.songci) player.storage.songci=[]; + if (!player.storage.songci) player.storage.songci = []; player.storage.songci.push(target); player.storage.songci.sortBySeat(); - player.markSkill('songci'); + player.markSkill("songci"); }, - intro:{ - content:'已对$发动过〖颂词〗' + intro: { + content: "已对$发动过〖颂词〗", }, - ai:{ - order:7, - threaten:1.6, - expose:0.2, - result:{ - target:function(player,target){ - if(target.countCards('h')<=target.hp){ + ai: { + order: 7, + threaten: 1.6, + expose: 0.2, + result: { + target: function (player, target) { + if (target.countCards("h") <= target.hp) { return 1; - } - else if(target.countCards('h')>target.hp){ + } else if (target.countCards("h") > target.hp) { return -1; } - } - } + }, + }, }, - group:'songci_draw', + group: "songci_draw", }, - songci_draw:{ - audio:'songci', - trigger:{player:'phaseDiscardEnd'}, - forced:true, - filter:function(event,player){ - if(!player.storage.songci) return false; - return !game.hasPlayer(function(current){ + songci_draw: { + audio: "songci", + trigger: { player: "phaseDiscardEnd" }, + forced: true, + filter: function (event, player) { + if (!player.storage.songci) return false; + return !game.hasPlayer(function (current) { return !player.storage.songci.includes(current); }); }, - content:function(){ + content: function () { player.draw(); }, }, - baobian:{ - audio:2, - trigger:{player:['phaseBefore','changeHp']}, - forced:true, - popup:false, - init:function(player){ - if(game.online) return; - player.removeAdditionalSkill('baobian'); - var list=[]; - if(player.hp<=3){ + baobian: { + audio: 2, + trigger: { player: ["phaseBefore", "changeHp"] }, + forced: true, + popup: false, + init: function (player) { + if (game.online) return; + player.removeAdditionalSkill("baobian"); + var list = []; + if (player.hp <= 3) { //if(trigger.num!=undefined&&trigger.num<0&&player.hp-trigger.num>1) player.logSkill('baobian'); - list.push('oltiaoxin'); + list.push("oltiaoxin"); } - if(player.hp<=2){ - list.push('olpaoxiao'); + if (player.hp <= 2) { + list.push("olpaoxiao"); } - if(player.hp<=1){ - list.push('xinshensu'); + if (player.hp <= 1) { + list.push("xinshensu"); } - if(list.length){ - player.addAdditionalSkill('baobian',list); + if (list.length) { + player.addAdditionalSkill("baobian", list); } }, - derivation:['oltiaoxin','olpaoxiao','xinshensu'], - content:function(){ - player.removeAdditionalSkill('baobian'); - var list=[]; - if(player.hp<=3){ - if(trigger.num!=undefined&&trigger.num<0&&player.hp-trigger.num>1) player.logSkill('baobian'); - list.push('oltiaoxin'); + derivation: ["oltiaoxin", "olpaoxiao", "xinshensu"], + content: function () { + player.removeAdditionalSkill("baobian"); + var list = []; + if (player.hp <= 3) { + if (trigger.num != undefined && trigger.num < 0 && player.hp - trigger.num > 1) + player.logSkill("baobian"); + list.push("oltiaoxin"); } - if(player.hp<=2){ - list.push('olpaoxiao'); + if (player.hp <= 2) { + list.push("olpaoxiao"); } - if(player.hp<=1){ - list.push('xinshensu'); + if (player.hp <= 1) { + list.push("xinshensu"); } - if(list.length){ - player.addAdditionalSkill('baobian',list); + if (list.length) { + player.addAdditionalSkill("baobian", list); } }, - ai:{ - maixie:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(!target.hasFriend()) return; - if(target.hp>=4) return [0,1]; + ai: { + maixie: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0, 1]; } - if(get.tag(card,'recover')&&player.hp>=player.maxHp-1) return [0,0]; - } - } - } - }, - chongzhen:{ - audio:2, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - if(event.card.name!='sha'&&event.card.name!='shan') return false; - if(!event.skill||event.skill.indexOf('fanghun')+event.skill.indexOf('longdan')==-2) return false; - var target=lib.skill.chongzhen.logTarget(event,player); - return target&&target.countGainableCards(player,'h')>0; + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, + }, }, - logTarget:function(event,player){ - if(event.name=='respond') return event.source; - if(event.card.name=='sha') return event.targets[0]; + }, + chongzhen: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + if (event.card.name != "sha" && event.card.name != "shan") return false; + if (!event.skill || event.skill.indexOf("fanghun") + event.skill.indexOf("longdan") == -2) + return false; + var target = lib.skill.chongzhen.logTarget(event, player); + return target && target.countGainableCards(player, "h") > 0; + }, + logTarget: function (event, player) { + if (event.name == "respond") return event.source; + if (event.card.name == "sha") return event.targets[0]; return event.respondTo[0]; }, - prompt2:function(event,player){ - var target=lib.skill.chongzhen.logTarget(event,player); - return '获得'+get.translation(target)+'的一张手牌'; + prompt2: function (event, player) { + var target = lib.skill.chongzhen.logTarget(event, player); + return "获得" + get.translation(target) + "的一张手牌"; }, - content:function(){ - var target=lib.skill.chongzhen.logTarget(trigger,player); - player.gainPlayerCard(target,'h',true); + content: function () { + var target = lib.skill.chongzhen.logTarget(trigger, player); + player.gainPlayerCard(target, "h", true); }, - ai:{ - combo:'ollongdan', - mingzhi:false, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')||get.tag(card,'respondSha')){ - if(get.attitude(target,player)<=0){ - if(current>0) return; - if(target.countCards('h')==0) return 1.6; - if(target.countCards('h')==1) return 1.2; - if(target.countCards('h')==2) return [0.8,0.2,0,-0.2]; - return [0.4,0.7,0,-0.7]; + ai: { + combo: "ollongdan", + mingzhi: false, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") || get.tag(card, "respondSha")) { + if (get.attitude(target, player) <= 0) { + if (current > 0) return; + if (target.countCards("h") == 0) return 1.6; + if (target.countCards("h") == 1) return 1.2; + if (target.countCards("h") == 2) return [0.8, 0.2, 0, -0.2]; + return [0.4, 0.7, 0, -0.7]; } } }, }, }, }, - lihun:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.hasSex('male'); + lihun: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.hasSex("male"); }, - filterCard:true, - position:'he', - content:function(){ - player.gainPlayerCard(target,true,'h',target.countCards('h')); + filterCard: true, + position: "he", + content: function () { + player.gainPlayerCard(target, true, "h", target.countCards("h")); player.turnOver(); - player.addSkill('lihun2'); - player.storage.lihun=target; + player.addSkill("lihun2"); + player.storage.lihun = target; }, - check:function(card){return 8-get.value(card)}, - ai:{ - order:10, - result:{ - player:function(player){ - if(player.classList.contains('turnedover')) return 10; + check: function (card) { + return 8 - get.value(card); + }, + ai: { + order: 10, + result: { + player: function (player) { + if (player.classList.contains("turnedover")) return 10; return 0; }, - target:function(player,target){ - if(target.countCards('h')>target.hp) return target.hp-target.countCards('h'); + target: function (player, target) { + if (target.countCards("h") > target.hp) return target.hp - target.countCards("h"); return 0; - } + }, }, - threaten:1.5, - effect:{ - target:function(card){ - if(card.name=='guiyoujie') return [0,2]; - } - } - }, - }, - lihun2:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - audio:false, - content:function(){ - "step 0" - var cards=player.getCards('he'); - player.removeSkill('lihun2'); - if(player.storage.lihun.classList.contains('dead')||player.storage.lihun.hp<=0||cards.length==0){ - event.finish(); - } - else{ - if(cards.length0; - }, - content:function(){ - "step 0" - player.chooseCardTarget({ - filterCard:function(card){ - return get.type(card)=='equip'; + threaten: 1.5, + effect: { + target: function (card) { + if (card.name == "guiyoujie") return [0, 2]; }, - position:'he', - filterTarget:function(card,player,target){ + }, + }, + }, + lihun2: { + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + audio: false, + content: function () { + "step 0"; + var cards = player.getCards("he"); + player.removeSkill("lihun2"); + if ( + player.storage.lihun.classList.contains("dead") || + player.storage.lihun.hp <= 0 || + cards.length == 0 + ) { + event.finish(); + } else { + if (cards.length < player.storage.lihun.hp) + event._result = { bool: true, cards: cards }; + else + player.chooseCard( + "he", + true, + player.storage.lihun.hp, + "离魂:选择要交给" + get.translation(player.storage.lihun) + "的牌" + ); + } + "step 1"; + player.give(result.cards, player.storage.lihun); + }, + }, + yuanhu: { + audio: 3, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + content: function () { + "step 0"; + player.chooseCardTarget({ + filterCard: function (card) { + return get.type(card) == "equip"; + }, + position: "he", + filterTarget: function (card, player, target) { return target.canEquip(card); }, - ai1:function(card){ - return 6-get.value(card); + ai1: function (card) { + return 6 - get.value(card); }, - ai2:function(target){ - return get.attitude(_status.event.player,target)-3; + ai2: function (target) { + return get.attitude(_status.event.player, target) - 3; }, - prompt:get.prompt2('yuanhu') + prompt: get.prompt2("yuanhu"), }); - "step 1" - if(result.bool){ - player.logSkill('yuanhu',result.targets); - var thisTarget=result.targets[0]; - var thisCard=result.cards[0]; + "step 1"; + if (result.bool) { + player.logSkill("yuanhu", result.targets); + var thisTarget = result.targets[0]; + var thisCard = result.cards[0]; thisTarget.equip(thisCard); - event.target=thisTarget; - if(thisTarget!=player){ - player.$give(thisCard,thisTarget,false); + event.target = thisTarget; + if (thisTarget != player) { + player.$give(thisCard, thisTarget, false); } - switch(get.subtype(thisCard)){ - case 'equip1':{ - if(!game.hasPlayer(function(current){ - return get.distance(thisTarget,current)<=1; - })){ + switch (get.subtype(thisCard)) { + case "equip1": { + if ( + !game.hasPlayer(function (current) { + return get.distance(thisTarget, current) <= 1; + }) + ) { event.finish(); return; } game.delay(); - player.chooseTarget(true,function(card,player,target){ - return get.distance(_status.event.thisTarget,target)<=1&&target.countCards('hej'); - }).set('ai',function(target){ - var attitude=get.attitude(_status.event.player,target); - if(attitude>0&&target.countCards('j')){ - return attitude*1.5; - } - return -attitude; - }).set('thisTarget',thisTarget); + player + .chooseTarget(true, function (card, player, target) { + return ( + get.distance(_status.event.thisTarget, target) <= 1 && + target.countCards("hej") + ); + }) + .set("ai", function (target) { + var attitude = get.attitude(_status.event.player, target); + if (attitude > 0 && target.countCards("j")) { + return attitude * 1.5; + } + return -attitude; + }) + .set("thisTarget", thisTarget); return; } - case 'equip2':{ - thisTarget.draw();event.finish(); - return; - } - case 'equip5':{ + case "equip2": { + thisTarget.draw(); event.finish(); return; } - default:{ + case "equip5": { + event.finish(); + return; + } + default: { thisTarget.recover(); event.finish(); return; } } - } - else{ + } else { event.finish(); } - "step 2" - if(result.targets.length){ - player.discardPlayerCard(true,result.targets[0],'hej'); + "step 2"; + if (result.targets.length) { + player.discardPlayerCard(true, result.targets[0], "hej"); } }, }, - tianming:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - check:function(event,player){ - var cards=player.getCards('h'); - if(cards.length<=2){ - for(var i=0;iplayers[1].hp&&players[0]!=player){ - players[0].chooseBool(get.prompt2('tianming')); - event.player=players[0]; - } - else{ + if (players[0].hp > players[1].hp && players[0] != player) { + players[0].chooseBool(get.prompt2("tianming")); + event.player = players[0]; + } else { event.finish(); } - "step 1" - if(result.bool){ - player.chooseToDiscard(2,true,'he'); + "step 1"; + if (result.bool) { + player.chooseToDiscard(2, true, "he"); player.draw(2); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha') return [1,0.5]; - } - } - } - }, - mizhao:{ - enable:'phaseUse', - usable:1, - audio:2, - filter:function(event,player){ - return player.countCards('h')>0; - }, - filterCard:true, - selectCard:-1, - filterTarget:function(card,player,target){ - return player!=target; - }, - discard:false, - lose:false, - delay:false, - ai:{ - order:1, - result:{ - player:0, - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(player.countCards('h')>1){ - return 1; - } - var players=game.filterPlayer(); - for(var i=0;i0){ - return eff-10; - } - return eff; - }).set('target1',event.target1).set('forceDie',true); - "step 3" - if(result.targets.length){ - event.target2=result.targets[0]; - event.target1.line(event.target2); - event.target1.chooseToCompare(event.target2); - } - else{ - event.finish(); - } - "step 4" - if(!result.tie){ - if(result.bool){ - if(event.target1.canUse({name:'sha',isCard:true},event.target2,false)) event.target1.useCard({name:'sha',isCard:true},event.target2); - } - else if(event.target2.canUse({name:'sha',isCard:true},event.target1,false)){ - event.target2.useCard({name:'sha',isCard:true},event.target1); - } - } - } - }, - gongao:{ - audio:2, - trigger:{global:'dieAfter'}, - forced:true, - content:function(){ - player.gainMaxHp(); - player.recover(); - }, - ai:{ - threaten:1.5 - }, - }, - juyi:{ - skillAnimation:true, - animationColor:'thunder', - audio:2, - derivation:['benghuai','weizhong'], - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.maxHp>game.countPlayer()&&!player.storage.juyi; - }, - forced:true, - unique:true, - juexingji:true, - content:function(){ - player.awakenSkill('juyi'); - player.draw(player.maxHp); - player.addSkills(['benghuai','weizhong']); - } - }, - weizhong:{ - audio:2, - trigger:{player:['gainMaxHpEnd','loseMaxHpEnd']}, - forced:true, - content:function(){ - player.draw(player.isMinHandcard()?2:1); - }, - }, - kuangfu:{ - trigger:{source:'damageSource'}, - audio:2, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.countCards('e'); - }, - logTarget:'player', - preHidden:true, - check:function(event,player){ - return get.attitude(player,event.player)<=0; - }, - content:function(){ - "step 0" - var neg=get.attitude(player,trigger.player)<=0; - player.choosePlayerCard('e',trigger.player).set('ai',function(button){ - if(_status.event.neg){ - return get.buttonValue(button); - } - return 0; - }).set('neg',neg); - "step 1" - if(result.bool){ - event.card=result.links[0]; - if(player.canEquip(event.card)){ - player.chooseBool('是否将'+get.translation(event.card)+'置入自己的装备区?').ai=function(){ - return true; - }; - } - else event._result={bool:false}; - } - else event.finish(); - "step 2" - if(result.bool){ - trigger.player.$give(event.card,player,false); - player.equip(event.card); - } - else trigger.player.discard(event.card); - } - }, - xinfu_lingren:{ - audio:2, - trigger:{ - player:"useCardToPlayered", - }, - filter:function(event,player){ - if(event.getParent().triggeredTargets3.length>1) return false; - if(!['basic','trick'].includes(get.type(event.card))) return false; - if(get.tag(event.card,'damage')) return true; - return false; - }, - usable:1, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('xinfu_lingren'),'选择一名目标角色并猜测其手牌构成',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return 2-get.attitude(_status.event.player,target); - }).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - player.logSkill('xinfu_lingren',result.targets); - var target=result.targets[0]; - event.target=target; - event.choice={ - basic:false, - trick:false, - equip:false, - } - player.chooseButton(['凌人:猜测其有哪些类别的手牌',[['basic','trick','equip'],'vcard']],[0,3],true).set('ai',function(button){ - switch(button.link[2]){ - case 'basic': - var rand=0.95; - if(!target.countCards('h',{type:['basic']})) rand=0.05; - if(!target.countCards('h')) rand=0; - return Math.random()i[2]); - if(!event.isMine()&&!event.isOnline()) game.delayx(); - var list=[]; - event.num=0; - ['basic','trick','equip'].forEach(type=>{ - if(choices.includes(type)==target.hasCard({type:type},'h')) event.num++; - }) - } - 'step 3' - player.popup('猜对'+get.cnNumber(event.num)+'项'); - game.log(player,'猜对了'+get.cnNumber(event.num)+'项'); - if(event.num>0){ - target.addTempSkill('lingren_adddamage'); - target.storage.lingren={ - card:trigger.card, - //player:event.targett, - } - } - if(event.num>1) player.draw(2); - if(event.num>2){ - player.addTempSkills(['lingren_jianxiong','lingren_xingshang'],{player:'phaseBegin'}); - } - }, - ai:{ - threaten:2.4, - }, - }, - "lingren_adddamage":{ - onremove:function (player){ - delete player.storage.lingren; - }, - trigger:{ - player:"damageBegin3", - }, - filter:function (event,player){ - var info=player.storage.lingren; - return event.card&&event.card==info.card; - }, - silent:true, - popup:false, - forced:true, - charlotte:true, - content:function (){ - trigger.num++; - }, - }, - "lingren_jianxiong":{ - audio:1, - trigger:{ - player:"damageEnd", - }, - content:function (){ - "step 0" - if(get.itemtype(trigger.cards)=='cards'&&get.position(trigger.cards[0],true)=='o'){ - player.gain(trigger.cards,"gain2"); - } - player.draw("nodelay"); - }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function (card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')&&player!=target) return [1,0.6]; + ai: { + effect: { + target: function (card, player, target, current) { + if (card.name == "sha") return [1, 0.5]; }, }, }, }, - "lingren_xingshang":{ - audio:1, - inherit:'rexingshang', - }, - "xinfu_fujian":{ - audio:2, - trigger:{ - player:"phaseJieshuBegin", + mizhao: { + enable: "phaseUse", + usable: 1, + audio: 2, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filter:function (event,player){ - return !game.hasPlayer(function(current){ - return current.countCards('h')==0; - }); + filterCard: true, + selectCard: -1, + filterTarget: function (card, player, target) { + return player != target; }, - forced:true, - content:function (){ - event.num=0; - var list=game.filterPlayer(function(target){ - if(target.isMinHandcard()) event.num=target.countCards('h'); - return player!=target; - }); - if(event.num<1){ + discard: false, + lose: false, + delay: false, + ai: { + order: 1, + result: { + player: 0, + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (player.countCards("h") > 1) { + return 1; + } + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].countCards("h") && + players[i] != target && + players[i] != player && + get.attitude(player, players[i]) < 0 + ) { + break; + } + } + if (i == players.length) { + return 1; + } + return -2 / (target.countCards("h") + 1); + }, + }, + }, + content: function () { + "step 0"; + event.target1 = targets[0]; + player.give(cards, targets[0], "giveAuto"); + "step 1"; + if (!targets[0].countCards("h")) { + event.finish(); + return; + } + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != event.target1 && + players[i] != player && + event.target1.canCompare(players[i]) + ) { + break; + } + } + if (i == players.length) { event.finish(); } - else{ - var target=list.randomGet(); - var cards=target.getCards('h').randomGets(event.num); - player.line(target); - var content=[get.translation(target)+'的部分手牌',cards]; - game.log(player,'观看了',target,'的部分手牌'); - player.chooseControl('ok').set('dialog',content); + "step 2"; + player + .chooseTarget(true, "选择拼点目标", function (card, player, target) { + return _status.event.target1.canCompare(target) && target != player; + }) + .set("ai", function (target) { + var player = _status.event.player; + var eff = get.effect(target, { name: "sha" }, _status.event.target1, player); + var att = get.attitude(player, target); + if (att > 0) { + return eff - 10; + } + return eff; + }) + .set("target1", event.target1) + .set("forceDie", true); + "step 3"; + if (result.targets.length) { + event.target2 = result.targets[0]; + event.target1.line(event.target2); + event.target1.chooseToCompare(event.target2); + } else { + event.finish(); + } + "step 4"; + if (!result.tie) { + if (result.bool) { + if (event.target1.canUse({ name: "sha", isCard: true }, event.target2, false)) + event.target1.useCard({ name: "sha", isCard: true }, event.target2); + } else if ( + event.target2.canUse({ name: "sha", isCard: true }, event.target1, false) + ) { + event.target2.useCard({ name: "sha", isCard: true }, event.target1); + } } }, }, - fujian:{ - audio:'xinfu_fujian', - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - filter(event,player){ - return game.hasPlayer(target=>target!=player&&target.countCards('h')&&!target.isMaxHandcard()); + gongao: { + audio: 2, + trigger: { global: "dieAfter" }, + forced: true, + content: function () { + player.gainMaxHp(); + player.recover(); }, - forced:true, - async content(event,trigger,player){ - const target=game.filterPlayer(target=>{ - return target!=player&&target.countCards('h')&&!target.isMaxHandcard(); - }).randomGet(); + ai: { + threaten: 1.5, + }, + }, + juyi: { + skillAnimation: true, + animationColor: "thunder", + audio: 2, + derivation: ["benghuai", "weizhong"], + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.maxHp > game.countPlayer() && !player.storage.juyi; + }, + forced: true, + unique: true, + juexingji: true, + content: function () { + player.awakenSkill("juyi"); + player.draw(player.maxHp); + player.addSkills(["benghuai", "weizhong"]); + }, + }, + weizhong: { + audio: 2, + trigger: { player: ["gainMaxHpEnd", "loseMaxHpEnd"] }, + forced: true, + content: function () { + player.draw(player.isMinHandcard() ? 2 : 1); + }, + }, + kuangfu: { + trigger: { source: "damageSource" }, + audio: 2, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.card && event.card.name == "sha" && event.player.countCards("e"); + }, + logTarget: "player", + preHidden: true, + check: function (event, player) { + return get.attitude(player, event.player) <= 0; + }, + content: function () { + "step 0"; + var neg = get.attitude(player, trigger.player) <= 0; + player + .choosePlayerCard("e", trigger.player) + .set("ai", function (button) { + if (_status.event.neg) { + return get.buttonValue(button); + } + return 0; + }) + .set("neg", neg); + "step 1"; + if (result.bool) { + event.card = result.links[0]; + if (player.canEquip(event.card)) { + player.chooseBool( + "是否将" + get.translation(event.card) + "置入自己的装备区?" + ).ai = function () { + return true; + }; + } else event._result = { bool: false }; + } else event.finish(); + "step 2"; + if (result.bool) { + trigger.player.$give(event.card, player, false); + player.equip(event.card); + } else trigger.player.discard(event.card); + }, + }, + xinfu_lingren: { + audio: 2, + trigger: { + player: "useCardToPlayered", + }, + filter: function (event, player) { + if (event.getParent().triggeredTargets3.length > 1) return false; + if (!["basic", "trick"].includes(get.type(event.card))) return false; + if (get.tag(event.card, "damage")) return true; + return false; + }, + usable: 1, + direct: true, + derivation: ["lingren_jianxiong", "lingren_xingshang"], + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xinfu_lingren"), + "选择一名目标角色并猜测其手牌构成", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + return 2 - get.attitude(_status.event.player, target); + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + player.logSkill("xinfu_lingren", result.targets); + var target = result.targets[0]; + event.target = target; + event.choice = { + basic: false, + trick: false, + equip: false, + }; + player + .chooseButton( + ["凌人:猜测其有哪些类别的手牌", [["basic", "trick", "equip"], "vcard"]], + [0, 3], + true + ) + .set("ai", function (button) { + switch (button.link[2]) { + case "basic": + var rand = 0.95; + if (!target.countCards("h", { type: ["basic"] })) rand = 0.05; + if (!target.countCards("h")) rand = 0; + return Math.random() < rand ? true : false; + case "trick": + var rand = 0.9; + if (!target.countCards("h", { type: ["trick", "delay"] })) rand = 0.1; + if (!target.countCards("h")) rand = 0; + return Math.random() < rand ? true : false; + case "equip": + var rand = 0.75; + if (!target.countCards("h", { type: ["equip"] })) rand = 0.25; + if (!target.countCards("h")) rand = 0; + return Math.random() < rand ? true : false; + } + }); + } else { + player.storage.counttrigger.xinfu_lingren--; + event.finish(); + } + "step 2"; + if (result.bool) { + var choices = result.links.map((i) => i[2]); + if (!event.isMine() && !event.isOnline()) game.delayx(); + var list = []; + event.num = 0; + ["basic", "trick", "equip"].forEach((type) => { + if (choices.includes(type) == target.hasCard({ type: type }, "h")) event.num++; + }); + } + "step 3"; + player.popup("猜对" + get.cnNumber(event.num) + "项"); + game.log(player, "猜对了" + get.cnNumber(event.num) + "项"); + if (event.num > 0) { + target.addTempSkill("lingren_adddamage"); + target.storage.lingren = { + card: trigger.card, + //player:event.targett, + }; + } + if (event.num > 1) player.draw(2); + if (event.num > 2) { + player.addTempSkills(["lingren_jianxiong", "lingren_xingshang"], { + player: "phaseBegin", + }); + } + }, + ai: { + threaten: 2.4, + }, + }, + lingren_adddamage: { + onremove: function (player) { + delete player.storage.lingren; + }, + trigger: { + player: "damageBegin3", + }, + filter: function (event, player) { + var info = player.storage.lingren; + return event.card && event.card == info.card; + }, + silent: true, + popup: false, + forced: true, + charlotte: true, + content: function () { + trigger.num++; + }, + }, + lingren_jianxiong: { + audio: 1, + trigger: { + player: "damageEnd", + }, + content: function () { + "step 0"; + if ( + get.itemtype(trigger.cards) == "cards" && + get.position(trigger.cards[0], true) == "o" + ) { + player.gain(trigger.cards, "gain2"); + } + player.draw("nodelay"); + }, + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage") && player != target) return [1, 0.6]; + }, + }, + }, + }, + lingren_xingshang: { + audio: 1, + inherit: "rexingshang", + }, + xinfu_fujian: { + audio: 2, + trigger: { + player: "phaseJieshuBegin", + }, + filter: function (event, player) { + return !game.hasPlayer(function (current) { + return current.countCards("h") == 0; + }); + }, + forced: true, + content: function () { + event.num = 0; + var list = game.filterPlayer(function (target) { + if (target.isMinHandcard()) event.num = target.countCards("h"); + return player != target; + }); + if (event.num < 1) { + event.finish(); + } else { + var target = list.randomGet(); + var cards = target.getCards("h").randomGets(event.num); + player.line(target); + var content = [get.translation(target) + "的部分手牌", cards]; + game.log(player, "观看了", target, "的部分手牌"); + player.chooseControl("ok").set("dialog", content); + } + }, + }, + fujian: { + audio: "xinfu_fujian", + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + filter(event, player) { + return game.hasPlayer( + (target) => target != player && target.countCards("h") && !target.isMaxHandcard() + ); + }, + forced: true, + async content(event, trigger, player) { + const target = game + .filterPlayer((target) => { + return target != player && target.countCards("h") && !target.isMaxHandcard(); + }) + .randomGet(); player.line(target); - game.log(player,'观看了',target,'的手牌'); + game.log(player, "观看了", target, "的手牌"); player.viewHandcards(target); }, }, - xinfu_xionghuo:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countMark('xinfu_xionghuo')>0; + xinfu_xionghuo: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countMark("xinfu_xionghuo") > 0; }, - filterTarget:function(card,player,target){ - return player!=target&&!target.hasMark('xinfu_xionghuo'); + filterTarget: function (card, player, target) { + return player != target && !target.hasMark("xinfu_xionghuo"); }, - content:function(){ - player.removeMark('xinfu_xionghuo',1); - target.addMark('xinfu_xionghuo',1); + content: function () { + player.removeMark("xinfu_xionghuo", 1); + target.addMark("xinfu_xionghuo", 1); }, - ai:{ - order:11, - result:{ - target:function(player,target){ - if((player.countMark('xinfu_xionghuo')>=2||!game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)<0&¤t.hasMark('xinfu_xionghuo'); - }))&&player.countCards('h',function(card){ - return get.tag(card,'damage')&&player.canUse(card,target,null,true) - &&player.getUseValue(card)>0&&get.effect_use(target,card,player)>0 - &&target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - }); - })) return 3/Math.max(1,target.hp); - if((!player.hasUnknown()&&game.countPlayer(function(current){ - return get.attitude(player,current)<0; - })<=1)||player.countMark('xinfu_xionghuo')>=2){ + ai: { + order: 11, + result: { + target: function (player, target) { + if ( + (player.countMark("xinfu_xionghuo") >= 2 || + !game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) < 0 && + current.hasMark("xinfu_xionghuo") + ); + })) && + player.countCards("h", function (card) { + return ( + get.tag(card, "damage") && + player.canUse(card, target, null, true) && + player.getUseValue(card) > 0 && + get.effect_use(target, card, player) > 0 && + target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ); + }) + ) + return 3 / Math.max(1, target.hp); + if ( + (!player.hasUnknown() && + game.countPlayer(function (current) { + return get.attitude(player, current) < 0; + }) <= 1) || + player.countMark("xinfu_xionghuo") >= 2 + ) { return -1; } return 0; }, }, - effect:{ - player:function(card,player,target){ - if(player!=target&&get.tag(card,'damage')&&target&&target.hasMark('xinfu_xionghuo')&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card, - })) return [1,0,1,-2]; + effect: { + player: function (card, player, target) { + if ( + player != target && + get.tag(card, "damage") && + target && + target.hasMark("xinfu_xionghuo") && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + return [1, 0, 1, -2]; }, }, - threaten:1.6, + threaten: 1.6, }, - marktext:'戾', - intro:{ - name:'暴戾', - content:'mark', + marktext: "戾", + intro: { + name: "暴戾", + content: "mark", }, - group:['xinfu_xionghuo_init','xinfu_xionghuo_damage','xinfu_xionghuo_effect'], - subSkill:{ - init:{ - audio:'xinfu_xionghuo', - trigger:{ - global:"phaseBefore", - player:'enterGame', + group: ["xinfu_xionghuo_init", "xinfu_xionghuo_damage", "xinfu_xionghuo_effect"], + subSkill: { + init: { + audio: "xinfu_xionghuo", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - if(player.countMark('xinfu_xionghuo')>=3) return false; - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + if (player.countMark("xinfu_xionghuo") >= 3) return false; + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - content:function(){ - player.addMark('xinfu_xionghuo',3-player.countMark('xinfu_xionghuo')); + forced: true, + locked: false, + content: function () { + player.addMark("xinfu_xionghuo", 3 - player.countMark("xinfu_xionghuo")); }, }, - damage:{ - audio:"xinfu_xionghuo", - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return event.player.countMark('xinfu_xionghuo')>0&&event.player!=player; + damage: { + audio: "xinfu_xionghuo", + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return event.player.countMark("xinfu_xionghuo") > 0 && event.player != player; }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ + forced: true, + locked: false, + logTarget: "player", + content: function () { trigger.num++; }, }, - effect:{ - audio:'xinfu_xionghuo', - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player.countMark('xinfu_xionghuo')>0&&event.player!=player; + effect: { + audio: "xinfu_xionghuo", + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return event.player.countMark("xinfu_xionghuo") > 0 && event.player != player; }, - line:false, - forced:true, - locked:false, - logTarget:'player', - content:function(){ - 'step 0' - trigger.player.removeMark('xinfu_xionghuo',trigger.player.countMark('xinfu_xionghuo')); - 'step 1' - var num=get.rand(0,2); - switch(num){ + line: false, + forced: true, + locked: false, + logTarget: "player", + content: function () { + "step 0"; + trigger.player.removeMark( + "xinfu_xionghuo", + trigger.player.countMark("xinfu_xionghuo") + ); + "step 1"; + var num = get.rand(0, 2); + switch (num) { case 0: - player.line(trigger.player,'fire'); - trigger.player.damage('fire'); - trigger.player.addTempSkill('xinfu_xionghuo_disable'); - trigger.player.markAuto('xinfu_xionghuo_disable',[player]); + player.line(trigger.player, "fire"); + trigger.player.damage("fire"); + trigger.player.addTempSkill("xinfu_xionghuo_disable"); + trigger.player.markAuto("xinfu_xionghuo_disable", [player]); break; case 1: - player.line(trigger.player,'water'); + player.line(trigger.player, "water"); trigger.player.loseHp(); - trigger.player.addMark('xinfu_xionghuo_low',1,false); - trigger.player.addTempSkill('xinfu_xionghuo_low'); + trigger.player.addMark("xinfu_xionghuo_low", 1, false); + trigger.player.addTempSkill("xinfu_xionghuo_low"); break; case 2: - player.line(trigger.player,'green'); + player.line(trigger.player, "green"); /* var card1=trigger.player.getCards('h').randomGet(); var card2=trigger.player.getCards('e').randomGet(); @@ -25554,2260 +31822,2784 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(card2) list.push(card2); if(list.length) player.gain(list,trigger.player,'giveAuto','bySelf'); */ - const cards=trigger.player.getGainableCards(player,'he'); - if(cards.length) player.gain(cards.randomGets(2),trigger.player,'giveAuto','bySelf'); + const cards = trigger.player.getGainableCards(player, "he"); + if (cards.length) + player.gain( + cards.randomGets(2), + trigger.player, + "giveAuto", + "bySelf" + ); break; } - 'step 2' + "step 2"; game.delay(); }, }, - disable:{ - mod:{ - playerEnabled:function (card,player,target){ - if(card.name=='sha'&&player.getStorage('xinfu_xionghuo_disable').includes(target)) return false; + disable: { + mod: { + playerEnabled: function (card, player, target) { + if ( + card.name == "sha" && + player.getStorage("xinfu_xionghuo_disable").includes(target) + ) + return false; }, }, - charlotte:true, - onremove:true, - mark:true, - marktext:'禁', - intro:{content:'不能对$使用【杀】'}, + charlotte: true, + onremove: true, + mark: true, + marktext: "禁", + intro: { content: "不能对$使用【杀】" }, }, - low:{ - mod:{ - maxHandcard:function (player,num){ - return num-player.countMark('xinfu_xionghuo_low'); + low: { + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("xinfu_xionghuo_low"); }, }, - charlotte:true, - onremove:true, - mark:true, - marktext:'减', - intro:{content:'手牌上限-#'}, + charlotte: true, + onremove: true, + mark: true, + marktext: "减", + intro: { content: "手牌上限-#" }, }, }, }, - xinfu_shajue:{ - audio:2, - trigger:{global:'dying'}, - filter:function(event,player){ - if(event.player==player) return false; - const bool1=(!player.hasSkill('xinfu_xionghuo')||player.countMark('xinfu_xionghuo')<3); - const bool2=(event.player.hp<0&&get.itemtype(event.parent.cards)=='cards'&&event.parent.cards.some(card=>get.position(card,true)=='o')); - return bool1||bool2; + xinfu_shajue: { + audio: 2, + trigger: { global: "dying" }, + filter: function (event, player) { + if (event.player == player) return false; + const bool1 = + !player.hasSkill("xinfu_xionghuo") || player.countMark("xinfu_xionghuo") < 3; + const bool2 = + event.player.hp < 0 && + get.itemtype(event.parent.cards) == "cards" && + event.parent.cards.some((card) => get.position(card, true) == "o"); + return bool1 || bool2; }, - forced:true, - content:function(){ - if(!player.hasSkill('xinfu_xionghuo')||player.countMark('xinfu_xionghuo')<3) player.addMark('xinfu_xionghuo',1); - if(trigger.player.hp<0&&get.itemtype(trigger.parent.cards)=='cards'&&trigger.parent.cards.some(card=>get.position(card,true)=='o')){ - player.gain(trigger.parent.cards.filter(card=>get.position(card,true)=='o'),'gain2'); + forced: true, + content: function () { + if (!player.hasSkill("xinfu_xionghuo") || player.countMark("xinfu_xionghuo") < 3) + player.addMark("xinfu_xionghuo", 1); + if ( + trigger.player.hp < 0 && + get.itemtype(trigger.parent.cards) == "cards" && + trigger.parent.cards.some((card) => get.position(card, true) == "o") + ) { + player.gain( + trigger.parent.cards.filter((card) => get.position(card, true) == "o"), + "gain2" + ); } }, }, - xinfu_jianjie:{audio:3}, - jianjie:{ - group:["jianjie_use","jianjie_die"], - derivation:['jianjie_huoji','jianjie_lianhuan','jianjie_yeyan'], - audio:'xinfu_jianjie', - trigger:{ - player:"phaseZhunbeiBegin", + xinfu_jianjie: { audio: 3 }, + jianjie: { + group: ["jianjie_use", "jianjie_die"], + derivation: ["jianjie_huoji", "jianjie_lianhuan", "jianjie_yeyan"], + audio: "xinfu_jianjie", + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - locked:false, - filter:function(event,player){ - return player.phaseNumber<=1&&game.hasPlayer(current=>current!=player); + forced: true, + locked: false, + filter: function (event, player) { + return player.phaseNumber <= 1 && game.hasPlayer((current) => current != player); }, - content:function(){ - 'step 0' - player.chooseTarget('荐杰:选择一名其他角色获得“龙印”',lib.filter.notMe,true).set('ai',(target)=>{ - return get.attitude(get.player(),target); - }); - '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(game.hasPlayer((current)=>{ - return current!=player&¤t!=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); + content: function () { + "step 0"; + player + .chooseTarget("荐杰:选择一名其他角色获得“龙印”", lib.filter.notMe, 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); + "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 ( + game.hasPlayer((current) => { + return current != player && current != 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 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "thunder"); + lib.skill.jianjie.addMark("lianhuan", player, target); game.delayx(); } }, - ai:{ - threaten:3, + ai: { + threaten: 3, }, - hasMark:(mark,player,target)=>{ - if(!target) return player.getStorage('jianjie_'+mark).length>0; - return target.getStorage('jianjie_'+mark).includes(player); + hasMark: (mark, player, target) => { + if (!target) return player.getStorage("jianjie_" + mark).length > 0; + return target.getStorage("jianjie_" + mark).includes(player); }, - 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'?'龙印':'凤印'}”`); + 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; + 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'?'龙印':'凤印'}”`); + target.unmarkAuto(mark, [player]); + if (log) + game.log( + target, + "移去了", + player, + "给予的", + `#g“${mark == "jianjie_huoji" ? "龙印" : "凤印"}”` + ); + else + game.log( + player, + "移去了", + target, + "的", + `#g“${mark == "jianjie_huoji" ? "龙印" : "凤印"}”` + ); } }, - 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); + 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){ - const skill=lib.skill.jianjie; - return skill.hasMark('huoji',player,target)||skill.hasMark('lianhuan',player,target); + filterTarget: function (card, player, target) { + if (ui.selected.targets.length == 0) { + 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','选择要移动的“印”'); + 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 { + event._result = { control: bool1 ? "龙印" : "凤印" }; } - else{ - 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]); + "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; + 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, + expose: 0.4, }, }, - die:{ - audio:'xinfu_jianjie', - trigger:{global:'die'}, - filter:function(event,player){ - const skill=lib.skill.jianjie; - return skill.hasMark('huoji',player,event.player)||skill.hasMark('lianhuan',player,event.player); + die: { + audio: "xinfu_jianjie", + trigger: { global: "die" }, + filter: function (event, player) { + const skill = lib.skill.jianjie; + return ( + skill.hasMark("huoji", player, event.player) || + skill.hasMark("lianhuan", player, event.player) + ); }, - forced:true, - logTarget:'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(2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - lib.skill.jianjie.addMark('huoji',player,target); - event.target=target; + forced: true, + logTarget: "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(2); + "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); + } 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(); } }, }, - huoji:{ - marktext:'龙', - intro:{ - name:"龙印", - content:"
            • 出牌阶段限三次。你可以将一张红色牌当作【火攻】使用,且你以此法使用【火攻】的作用效果改为“目标角色随机展示一张手牌A,然后你可以弃置一张与A颜色相同的牌,对目标造成1点火属性伤害”。
            • 若你同时拥有“凤印”,则你视为拥有技能〖业炎〗。(发动〖业炎〗时,弃置所有“龙印”和“凤印”)", + 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'); + 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'], + 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' + huoji_effect: { + trigger: { player: "huogongBegin" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return event.skill == "jianjie_huoji"; }, - content:function(){ + content: function () { trigger.setContent(lib.skill.olhuoji.huogongContent); }, }, - lianhuan:{ - marktext:'凤', - intro:{ - name:"凤印", - content:"
            • 出牌阶段限三次。你可以将一张♣牌当作【铁索连环】使用或重铸,且你以此法使用【铁索连环】的目标数上限+1。
            • 若你同时拥有“龙印”,则你视为拥有技能〖业炎〗。(发动〖业炎〗时,弃置所有“龙印”和“凤印”)", + 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)); + 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'], + 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.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })) return true; + 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.includes(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.includes(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'); + charlotte: true, + forced: true, + popup: false, + content: function () { + "step 0"; + player + .chooseTarget( + "是否为" + get.translation(trigger.card) + "额外指定一个目标?", + (card, player, target) => { + return ( + !_status.event.sourcex.includes(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,'的目标'); + game.log(targets, "也成为了", trigger.card, "的目标"); } }, }, - yeyan:{ - inherit:'yeyan', - filter:function(event,player){ - const huoji=player.getStorage('jianjie_huoji'),lianhuan=player.getStorage('jianjie_lianhuan'); - return huoji.length>0&&lianhuan.some(source=>{ - return huoji.includes(source)&&source.isIn()&&source.hasSkill('jianjie'); - }) + yeyan: { + inherit: "yeyan", + filter: function (event, player) { + const huoji = player.getStorage("jianjie_huoji"), + lianhuan = player.getStorage("jianjie_lianhuan"); + return ( + huoji.length > 0 && + 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); + 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); + lianhuan.forEach((source) => { + skill.removeMark("lianhuan", source, player, true); }); }, }, }, }, - xinfu_yinshi:{ - audio:2, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function (event,player){ - 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'; + xinfu_yinshi: { + audio: 2, + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + 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"; }, - content:function (){ + content: function () { trigger.cancel(); }, - ai:{ - notrick:true, - nofire:true, - nothunder:true, - effect:{ - target:function (card,player,target,current){ - 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; + ai: { + notrick: true, + nofire: true, + nothunder: true, + effect: { + target: function (card, player, target, current) { + 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; } - if(!target.hasEmptySlot(2)) return; - if(get.tag(card,'natureDamage')) return 'zerotarget'; - if(get.type(card)=='trick'&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + if (!target.hasEmptySlot(2)) return; + if (get.tag(card, "natureDamage")) return "zerotarget"; + if (get.type(card) == "trick" && get.tag(card, "damage")) { + return "zeroplayertarget"; } }, }, }, }, - "xinfu_chenghao":{ - audio:2, - trigger:{ - global:"damageEnd", + xinfu_chenghao: { + audio: 2, + trigger: { + global: "damageEnd", }, - filter:function (event,player){ - return event.lianhuanable==true&&event.player.isIn(); + filter: function (event, player) { + return event.lianhuanable == true && event.player.isIn(); }, - frequent:true, - content:function(){ - 'step 0' - event.cards=game.cardsGotoOrdering(get.cards(game.countPlayer(function(current){ - return current.isLinked(); - })+1)).cards; - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 1' - if(event.cards.length>1){ - player.chooseCardButton('称好:请选择要分配的牌',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return 1; - return 0; + frequent: true, + content: function () { + "step 0"; + event.cards = game.cardsGotoOrdering( + get.cards( + game.countPlayer(function (current) { + return current.isLinked(); + }) + 1 + ) + ).cards; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cards.length==1){ - event._result={links:event.cards.slice(0),bool:true}; - } - else{ + event.given_map = {}; + "step 1"; + if (event.cards.length > 1) { + player + .chooseCardButton("称好:请选择要分配的牌", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + } else if (event.cards.length == 1) { + event._result = { links: event.cards.slice(0), bool: true }; + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.cards.removeArray(result.links); - event.togive=result.links.slice(0); - player.chooseTarget('选择一名角色获得'+get.translation(result.links),true).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.enemy){ - return -att; - } - else if(att>0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); + event.togive = result.links.slice(0); + player + .chooseTarget("选择一名角色获得" + get.translation(result.links), true) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); } - 'step 3' - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + "step 3"; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(cards.length>0) event.goto(1); - 'step 4' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length > 0) event.goto(1); + "step 4"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - list.push([source,event.given_map[i]]); + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + list.push([source, event.given_map[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'draw', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "draw", + }).setContent("gaincardMultiple"); }, }, - "xinfu_wuniang":{ - trigger:{ - player:["useCard","respond"], + xinfu_wuniang: { + trigger: { + player: ["useCard", "respond"], }, - audio:2, - direct:true, - filter:function (event,player){ - return event.card.name=='sha'; + audio: 2, + direct: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt('xinfu_wuniang'),'获得一名其他角色的一张牌,然后其和场上所有的“关索”摸一张牌。',function(card,player,target){ - if(player==target) return false; - return target.countGainableCards(player,'he')>0; - }).set('ai',function(target){ - return 10-get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('xinfu_wuniang',target); - player.line(target,'fire'); - event.draws=game.filterPlayer(function(current){ - if(current==target) return true; - return current.name=='guansuo'||current.name2=='guansuo'; + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xinfu_wuniang"), + "获得一名其他角色的一张牌,然后其和场上所有的“关索”摸一张牌。", + function (card, player, target) { + if (player == target) return false; + return target.countGainableCards(player, "he") > 0; + } + ) + .set("ai", function (target) { + return 10 - get.attitude(_status.event.player, target); }); - player.gainPlayerCard(target,'he',true); - } - else event.finish(); - 'step 2' - game.asyncDraw(event.draws,1); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("xinfu_wuniang", target); + player.line(target, "fire"); + event.draws = game.filterPlayer(function (current) { + if (current == target) return true; + return current.name == "guansuo" || current.name2 == "guansuo"; + }); + player.gainPlayerCard(target, "he", true); + } else event.finish(); + "step 2"; + game.asyncDraw(event.draws, 1); game.delay(); }, }, - "xinfu_xushen":{ - derivation:["xinfu_zhennan"], - audio:2, - subSkill:{ - count:{ - trigger:{ - player:"recoverBegin", + xinfu_xushen: { + derivation: ["xinfu_zhennan"], + audio: 2, + subSkill: { + count: { + trigger: { + player: "recoverBegin", }, - forced:true, - silent:true, - popup:false, - filter:function (event,player){ - if(!event.card||event.card.name!='tao') return false; - if(!event.source||!event.source.hasSex('male')) return false; - if(!player.isDying()) return false; - if(game.hasPlayer(function(current){ - return current.name=='guansuo'||current.name2=='guansuo'; - })) return false; + forced: true, + silent: true, + popup: false, + filter: function (event, player) { + if (!event.card || event.card.name != "tao") return false; + if (!event.source || !event.source.hasSex("male")) return false; + if (!player.isDying()) return false; + if ( + game.hasPlayer(function (current) { + return current.name == "guansuo" || current.name2 == "guansuo"; + }) + ) + return false; return true; }, - content:function (){ - trigger.xinfu_xushen=true; + content: function () { + trigger.xinfu_xushen = true; }, - sub:true, + sub: true, }, }, - group:["xinfu_xushen_count"], - trigger:{ - player:"recoverAfter", + group: ["xinfu_xushen_count"], + trigger: { + player: "recoverAfter", }, - limited:true, - init:function (player){ - player.storage.xinfu_xushen=false; + limited: true, + init: function (player) { + player.storage.xinfu_xushen = false; }, - filter:function (event,player){ - if(player.storage.xinfu_xushen) return false; - if(player.isDying()) return false; - return event.xinfu_xushen==true; + filter: function (event, player) { + if (player.storage.xinfu_xushen) return false; + if (player.isDying()) return false; + return event.xinfu_xushen == true; }, - direct:true, - skillAnimation:true, - animationColor:'fire', - content:function (){ - "step 0" - trigger.source.chooseBool('【许身】:是否将自己的一张武将牌替换为“关索”?').set('ai',function(){ - return false; - }); - "step 1" - if(result.bool){ - player.awakenSkill('xinfu_xushen'); - player.logSkill('xinfu_xushen',trigger.source); - if(trigger.source.name2!=undefined){ - trigger.source.chooseControl(trigger.source.name1,trigger.source.name2).set('prompt','请选择要更换的武将牌'); - }else event._result={control:trigger.source.name1}; - } - else event.finish(); - "step 2" - trigger.source.reinitCharacter(result.control,'guansuo'); + direct: true, + skillAnimation: true, + animationColor: "fire", + content: function () { + "step 0"; + trigger.source + .chooseBool("【许身】:是否将自己的一张武将牌替换为“关索”?") + .set("ai", function () { + return false; + }); + "step 1"; + if (result.bool) { + player.awakenSkill("xinfu_xushen"); + player.logSkill("xinfu_xushen", trigger.source); + if (trigger.source.name2 != undefined) { + trigger.source + .chooseControl(trigger.source.name1, trigger.source.name2) + .set("prompt", "请选择要更换的武将牌"); + } else event._result = { control: trigger.source.name1 }; + } else event.finish(); + "step 2"; + trigger.source.reinitCharacter(result.control, "guansuo"); player.recover(); - player.addSkills('xinfu_zhennan'); + player.addSkills("xinfu_zhennan"); }, - mark:true, - intro:{ - content:"limited", + mark: true, + intro: { + content: "limited", }, }, - "xinfu_falu":{ - subSkill:{ - spade:{ - marktext:'♠︎️', - intro:{ - name:'紫薇', - content:'mark', + xinfu_falu: { + subSkill: { + spade: { + marktext: "♠︎️", + intro: { + name: "紫薇", + content: "mark", }, }, - heart:{ - marktext:'♥︎️', - intro:{ - name:'玉清', - content:'mark', + heart: { + marktext: "♥︎️", + intro: { + name: "玉清", + content: "mark", }, }, - club:{ - marktext:'♣︎️', - intro:{ - name:'后土', - content:'mark', + club: { + marktext: "♣︎️", + intro: { + name: "后土", + content: "mark", }, }, - diamond:{ - marktext:'♦︎', - intro:{ - name:'勾陈', - content:'mark', + diamond: { + marktext: "♦︎", + intro: { + name: "勾陈", + content: "mark", }, }, }, - forced:true, - audio:2, - trigger:{ - player:["loseAfter","enterGame"], - global:['loseAsyncAfter',"phaseBefore"], + forced: true, + audio: 2, + trigger: { + player: ["loseAfter", "enterGame"], + global: ["loseAsyncAfter", "phaseBefore"], }, - filter:function (event,player){ - if(event.name.indexOf('lose')!=0) return (event.name!='phase'||game.phaseNumber==0); - if(event.type!='discard'||event.getlx===false) return false; - var evt=event.getl(player); - for(var i=0;i0)) break; + while (cards.length) { + if (get.value(cards[0], player) <= 5 == att > 0) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - "step 1" - var top=result.moved[0]; - var bottom=result.moved[1]; + bottom = cards; + return [top, bottom]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i0) return list[0]; - return 'cancel2'; - }).set('judging',trigger.player.judging[0]); - "step 1" - if(result.control!='cancel2'){ + content: function () { + "step 0"; + var str = + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + ",是否发动【真仪】,弃置「紫薇♠」标记并修改判定结果?"; + player + .chooseControl("spade", "heart", "diamond", "club", "cancel2") + .set("prompt", str) + .set("ai", function () { + //return '取消'; + var judging = _status.event.judging; + var trigger = _status.event.getTrigger(); + var res1 = trigger.judge(judging); + var list = lib.suit.slice(0); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0) return 0; + var getj = function (suit) { + return trigger.judge({ + name: get.name(judging), + nature: get.nature(judging), + suit: suit, + number: 5, + }); + }; + list.sort(function (a, b) { + return (getj(b) - getj(a)) * get.sgn(attitude); + }); + if ((getj(list[0]) - res1) * attitude > 0) return list[0]; + return "cancel2"; + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.control != "cancel2") { player.addExpose(0.25); - player.removeMark('xinfu_falu_spade'); - player.logSkill('xinfu_zhenyi',trigger.player); + player.removeMark("xinfu_falu_spade"); + player.logSkill("xinfu_zhenyi", trigger.player); //player.line(trigger.player); player.popup(result.control); - game.log(player,'将判定结果改为了','#y'+get.translation(result.control+2)+5); - trigger.fixedResult={ - suit:result.control, - color:get.color({suit:result.control}), - number:5, + game.log(player, "将判定结果改为了", "#y" + get.translation(result.control + 2) + 5); + trigger.fixedResult = { + suit: result.control, + color: get.color({ suit: result.control }), + number: 5, }; } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, + ai: { + rejudge: true, + tag: { + rejudge: 1, }, - expose:0.5, + expose: 0.5, }, }, - "zhenyi_club":{ - audio:'xinfu_zhenyi', - enable:"chooseToUse", - viewAsFilter:function(player){ - if(player==_status.currentPhase) return false; - return player.hasMark('xinfu_falu_club')&&player.countCards('hs')>0; + zhenyi_club: { + audio: "xinfu_zhenyi", + enable: "chooseToUse", + viewAsFilter: function (player) { + if (player == _status.currentPhase) return false; + return player.hasMark("xinfu_falu_club") && player.countCards("hs") > 0; }, - filterCard:true, - position:"hs", - viewAs:{ - name:"tao", + filterCard: true, + position: "hs", + viewAs: { + name: "tao", }, - prompt:"弃置「后土♣」标记,将一张手牌当桃使用", - check:function(card){return 15-get.value(card)}, - precontent:function(){ - player.removeMark('xinfu_falu_club'); + prompt: "弃置「后土♣」标记,将一张手牌当桃使用", + check: function (card) { + return 15 - get.value(card); + }, + precontent: function () { + player.removeMark("xinfu_falu_club"); }, }, - zhenyi_heart:{ - trigger:{ - source:"damageBegin1", + zhenyi_heart: { + trigger: { + source: "damageBegin1", }, - audio:'xinfu_zhenyi', - filter:function (event,player){ - return player.hasMark('xinfu_falu_heart'); + audio: "xinfu_zhenyi", + filter: function (event, player) { + return player.hasMark("xinfu_falu_heart"); }, - check:function (event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(event.player.hasSkillTag('filterDamage',null,{ - player:player, - card:event.card, - })) return false; + check: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + if ( + event.player.hasSkillTag("filterDamage", null, { + player: player, + card: event.card, + }) + ) + return false; return true; //return player.hasMark('xinfu_falu_spade')||get.color(ui.cardPile.firstChild)=='black'; }, - prompt2:function(event){ - return '弃置「玉清♥」标记,令对'+get.translation(event.player)+'即将造成的伤害+1。'; + prompt2: function (event) { + return "弃置「玉清♥」标记,令对" + get.translation(event.player) + "即将造成的伤害+1。"; }, - logTarget:"player", - content:function(){ - player.removeMark('xinfu_falu_heart'); + logTarget: "player", + content: function () { + player.removeMark("xinfu_falu_heart"); trigger.num++; }, }, - "xinfu_zhennan":{ - audio:2, - trigger:{ - target:"useCardToTargeted", + xinfu_zhennan: { + audio: 2, + trigger: { + target: "useCardToTargeted", }, - filter:function (event,player){ - return event.card.name=='nanman'; + filter: function (event, player) { + return event.card.name == "nanman"; }, - direct:true, - content:function (){ - "step 0" - player.chooseTarget(get.prompt('xinfu_zhennan'),'对一名其他角色造成1-3点随机伤害',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xinfu_zhennan"), + "对一名其他角色造成1-3点随机伤害", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { game.delay(); - player.logSkill('xinfu_zhennan',result.targets); - var num=[1,2,3,1,1,2].randomGet(); - if(get.isLuckyStar(player)) num=3; + player.logSkill("xinfu_zhennan", result.targets); + var num = [1, 2, 3, 1, 1, 2].randomGet(); + if (get.isLuckyStar(player)) num = 3; //player.line(result.targets[0],'fire'); result.targets[0].damage(num); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, }, - dynamicTranslate:{ - shanduan:function(player){ - if(player.storage.shanduan) return '锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=['+get.translation(player.storage.shanduan)+']中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。'; - return '锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=[1,2,3,4]中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。'; + dynamicTranslate: { + shanduan: function (player) { + if (player.storage.shanduan) + return ( + "锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=[" + + get.translation(player.storage.shanduan) + + "]中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。" + ); + return "锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=[1,2,3,4]中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。"; }, - kunfen:function(player){ - if(player.storage.kunfen) return '结束阶段开始时,你可以失去1点体力,然后摸两张牌。'; - return '锁定技,结束阶段开始时,你失去1点体力,然后摸两张牌。'; + kunfen: function (player) { + if (player.storage.kunfen) return "结束阶段开始时,你可以失去1点体力,然后摸两张牌。"; + return "锁定技,结束阶段开始时,你失去1点体力,然后摸两张牌。"; }, - jieyuan:function(player){ - var str='当你对一名其他角色造成伤害时,' - if(!player.hasSkill('fenxin_fan')) str+='若其体力值大于或等于你的体力值,'; - str+='你可弃置一张'; - if(!player.hasSkill('fenxin_nei')) str+='黑色手'; - str+='牌,令此伤害+1;当你受到一名其他角色造成的伤害时,'; - if(!player.hasSkill('fenxin_zhong')) str+='若其体力值大于或等于你的体力值,'; - str+='你可弃置一张' - if(!player.hasSkill('fenxin_nei')) str+='红色手'; - str+='牌,令此伤害-1。'; + jieyuan: function (player) { + var str = "当你对一名其他角色造成伤害时,"; + if (!player.hasSkill("fenxin_fan")) str += "若其体力值大于或等于你的体力值,"; + str += "你可弃置一张"; + if (!player.hasSkill("fenxin_nei")) str += "黑色手"; + str += "牌,令此伤害+1;当你受到一名其他角色造成的伤害时,"; + if (!player.hasSkill("fenxin_zhong")) str += "若其体力值大于或等于你的体力值,"; + str += "你可弃置一张"; + if (!player.hasSkill("fenxin_nei")) str += "红色手"; + str += "牌,令此伤害-1。"; return str; }, - youlong:function(player){ - if(player.storage.youlong) return '转换技,阴,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的基本牌。'; + youlong: function (player) { + if (player.storage.youlong) + return '转换技,阴,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的基本牌。'; return '转换技,阴,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的基本牌。'; }, - luochong:function(player){ - var storage=player.getStorage('luochong'); - var str='准备阶段开始时/当你于一回合首次受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):' - var choiceList=[ - '⒈令一名角色回复1点体力。', - '⒉令一名角色失去1点体力。', - '⒊令一名角色弃置两张牌。', - '⒋令一名角色摸两张牌。' + luochong: function (player) { + var storage = player.getStorage("luochong"); + var str = + "准备阶段开始时/当你于一回合首次受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):"; + var choiceList = [ + "⒈令一名角色回复1点体力。", + "⒉令一名角色失去1点体力。", + "⒊令一名角色弃置两张牌。", + "⒋令一名角色摸两张牌。", ]; - for(var i=0;i<4;i++){ - if(storage.includes(i)){ - choiceList[i]=(''+choiceList[i]+''); + for (var i = 0; i < 4; i++) { + if (storage.includes(i)) { + choiceList[i] = + '' + choiceList[i] + ""; } - str+=choiceList[i]; + str += choiceList[i]; } return str; }, - spmanwang:function(player){ - var num=4-player.countMark('spmanwang'); - var str='出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:'; - var list=[ - '⒈获得〖叛侵〗。', - '⒉摸一张牌。', - '⒊回复1点体力。', - '⒋摸两张牌并失去〖叛侵〗。', - ]; - for(var i=0;i<4;i++){ - if(i==num){ - str+=''; + spmanwang: function (player) { + var num = 4 - player.countMark("spmanwang"); + var str = "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前等量项:"; + var list = ["⒈获得〖叛侵〗。", "⒉摸一张牌。", "⒊回复1点体力。", "⒋摸两张牌并失去〖叛侵〗。"]; + for (var i = 0; i < 4; i++) { + if (i == num) { + str += ''; } - str+=list[i]; + str += list[i]; } - if(num<4) str+=''; + if (num < 4) str += ""; return str; }, - olbixin:function(player){ - var count=player.countMark('olbixin'); - if(count<3) return lib.translate.olbixin_info.slice(count*5); - return '你可以声明一种牌的类型(每种类型限[3]次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸[1]张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。'; + olbixin: function (player) { + var count = player.countMark("olbixin"); + if (count < 3) return lib.translate.olbixin_info.slice(count * 5); + return "你可以声明一种牌的类型(每种类型限[3]次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸[1]张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。"; }, - olfeibai:function(player){ - if(player.storage.olfeibai) return '转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。'; - return '转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。' + olfeibai: function (player) { + if (player.storage.olfeibai) + return '转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。'; + return '转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。'; }, - olmiuyan:function(player){ - if(player.storage.olmiuyan) return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。'; + olmiuyan: function (player) { + if (player.storage.olmiuyan) + return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。'; return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。'; }, - olsaogu:function(player){ - if(player.storage.olsaogu) return '转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。'; + olsaogu: function (player) { + if (player.storage.olsaogu) + return '转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。'; return '转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。'; }, - oldongdao:function(player){ - if(player.storage.oldongdao) return '农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,其可以进行一个额外回合。'; + oldongdao: function (player) { + if (player.storage.oldongdao) + return '农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,其可以进行一个额外回合。'; return '农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,其可以进行一个额外回合。'; }, - ollangdao:function(player){ - var str='当你使用【杀】指定唯一目标时,你可以与该目标角色同时选择一项:'; - var list=[ - '1.令此【杀】伤害基数+1;', - '2.令你可以为此【杀】多选择一个目标;', - '3.令此【杀】不可被响应。' + 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+='然后若没有角色因此【杀】死亡,你移除本次被选择的项。'; + var storage = player.getStorage("ollangdao"); + list.forEach((item, index) => { + if (storage.includes(index)) { + str += `${item}`; + } else str += item; + }); + str += "然后若没有角色因此【杀】死亡,你移除本次被选择的项。"; return str; }, - olxuanzhu(player){ - if(player.storage.olxuanzhu) return '转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。'; + olxuanzhu(player) { + if (player.storage.olxuanzhu) + return '转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。'; return '转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。'; }, }, - characterReplace:{ - guanyinping:['guanyinping','old_guanyinping'], - shixie:['shixie','dc_shixie','old_shixie'], - caoshuang:['caoshuang','dc_caoshuang','ns_caoshuang'], - caoang:['caoang','yj_caoang','tw_caoang'], - caohong:['caohong','tw_re_caohong','tw_caohong','yj_caohong'], - xiahouba:['xiahouba','dc_xiahouba','tw_xiahouba'], - maliang:['maliang','re_maliang','tw_maliang','ol_maliang','old_maliang'], - dingfeng:['dingfeng','tw_dingfeng','old_dingfeng'], - zumao:['zumao','tw_zumao'], - tw_beimihu:['beimihu','tw_beimihu'], - panfeng:['panfeng','re_panfeng','std_panfeng'], - sunluyu:['sunluyu','re_sunluyu','mb_sunluyu'], - jin_simazhao:['jin_simazhao','simazhao','sp_simazhao'], - jin_wangyuanji:['jin_wangyuanji','wangyuanji','sp_wangyuanji'], - wangyun:['clan_wangyun','wangyun','dc_wangyun','re_wangyun','jsrg_wangyun','old_wangyun','pe_wangyun'], - zhangliang:['xin_zhangliang','re_zhangliang','zhangliang'], - lingju:['lingju','old_lingju'], - guansuo:['guansuo','dc_guansuo'], - zhangxingcai:['zhangxingcai','old_zhangxingcai'], - lisu:['ol_lisu','lisu'], - fuwan:['fuwan','tw_fuwan','sp_fuwan'], - huaxin:['ol_huaxin','huaxin','sp_huaxin'], - xujing:['xujing','dc_xujing','sp_xujing','tw_xujing'], - zhaoxiang:['zhaoxiang','dc_zhaoxiang','tw_zhaoxiang'], - dengzhi:['ol_dengzhi','re_dengzhi','dengzhi','tw_dengzhi'], - wangrong:['ol_wangrong','wangrong'], - zongyu:['zongyu','sp_zongyu','tw_zongyu'], - ol_dongzhao:['ol_dongzhao','dc_dongzhao','tw_dongzhao'], - mayunlu:['mayunlu','tw_mayunlu'], - zhuling:['ol_zhuling','dc_zhuling','zhuling'], - zangba:['zangba','tw_zangba'], - zhangbao:['zhangbao','re_zhangbao'], - jianggan:['jianggan','sp_jianggan'], - dc_jiben:['dc_jiben','sp_jiben'], - yangyi:['ol_yangyi','yangyi','tw_yangyi'], - tianyu:['tianyu','tw_tianyu'], - huangchengyan:['huangchengyan','dc_huangchengyan'], - puyuan:['ol_puyuan','puyuan'], - huangzu:['huangzu','dc_huangzu'], - huojun:['huojun','dc_huojun','xin_huojun','tw_huojun'], - zhaoyǎn:['zhaoyǎn','dc_zhaoyǎn'], - furong:['ol_furong','furong','tw_furong'], - daxiaoqiao:['daxiaoqiao','dc_daxiaoqiao','tw_daxiaoqiao'], - zhugeguo:['zhugeguo','tw_zhugeguo'], - wanglang:['ol_wanglang','wanglang','old_wanglang'], - tengfanglan:['tengfanglan','dc_tengfanglan'], - zhangyì:['ol_zhangyì','zhangyì'], - yuantanyuanshang:['yuantanyuanshang','yuantanyuanxiyuanshang'], - ruiji:['ruiji','dc_ruiji'], - jsp_huangyueying:['jsp_huangyueying','re_jsp_huangyueying'], - ganfuren:['ganfuren','dc_ganfuren','jsp_ganfuren'], - wenqin:['wenqin','pe_wenqin'], - zhouqun:['ol_zhouqun','zhouqun'], - qianzhao:['ol_qianzhao','qianzhao'], - ol_pengyang:['ol_pengyang','sp_pengyang'], - ol_luyusheng:['ol_luyusheng','luyusheng'], - fanjiangzhangda:['fanjiangzhangda','jsrg_fanjiangzhangda'], - simalang:['re_simalang','simalang'], - zhugedan:['re_zhugedan','zhugedan'], - zhangren:['jsrg_zhangren','zhangren'], - wenqin:['ol_wenqin','pe_wenqin'], - lukai:['ol_lukai','lukai'], - liupi:['ol_liupi','liupi'], + characterReplace: { + guanyinping: ["guanyinping", "old_guanyinping"], + shixie: ["shixie", "dc_shixie", "old_shixie"], + caoshuang: ["caoshuang", "dc_caoshuang", "ns_caoshuang"], + caoang: ["caoang", "yj_caoang", "tw_caoang"], + caohong: ["caohong", "tw_re_caohong", "tw_caohong", "yj_caohong"], + xiahouba: ["xiahouba", "dc_xiahouba", "tw_xiahouba"], + maliang: ["maliang", "re_maliang", "tw_maliang", "ol_maliang", "old_maliang"], + dingfeng: ["dingfeng", "tw_dingfeng", "old_dingfeng"], + zumao: ["zumao", "tw_zumao"], + tw_beimihu: ["beimihu", "tw_beimihu"], + panfeng: ["panfeng", "re_panfeng", "std_panfeng"], + sunluyu: ["sunluyu", "re_sunluyu", "mb_sunluyu"], + jin_simazhao: ["jin_simazhao", "simazhao", "sp_simazhao"], + jin_wangyuanji: ["jin_wangyuanji", "wangyuanji", "sp_wangyuanji"], + wangyun: [ + "clan_wangyun", + "wangyun", + "dc_wangyun", + "re_wangyun", + "jsrg_wangyun", + "old_wangyun", + "pe_wangyun", + ], + zhangliang: ["xin_zhangliang", "re_zhangliang", "zhangliang"], + lingju: ["lingju", "old_lingju"], + guansuo: ["guansuo", "dc_guansuo"], + zhangxingcai: ["zhangxingcai", "old_zhangxingcai"], + lisu: ["ol_lisu", "lisu"], + fuwan: ["fuwan", "tw_fuwan", "sp_fuwan"], + huaxin: ["ol_huaxin", "huaxin", "sp_huaxin"], + xujing: ["xujing", "dc_xujing", "sp_xujing", "tw_xujing"], + zhaoxiang: ["zhaoxiang", "dc_zhaoxiang", "tw_zhaoxiang"], + dengzhi: ["ol_dengzhi", "re_dengzhi", "dengzhi", "tw_dengzhi"], + wangrong: ["ol_wangrong", "wangrong"], + zongyu: ["zongyu", "sp_zongyu", "tw_zongyu"], + ol_dongzhao: ["ol_dongzhao", "dc_dongzhao", "tw_dongzhao"], + mayunlu: ["mayunlu", "tw_mayunlu"], + zhuling: ["ol_zhuling", "dc_zhuling", "zhuling"], + zangba: ["zangba", "tw_zangba"], + zhangbao: ["zhangbao", "re_zhangbao"], + jianggan: ["jianggan", "sp_jianggan"], + dc_jiben: ["dc_jiben", "sp_jiben"], + yangyi: ["ol_yangyi", "yangyi", "tw_yangyi"], + tianyu: ["tianyu", "tw_tianyu"], + huangchengyan: ["huangchengyan", "dc_huangchengyan"], + puyuan: ["ol_puyuan", "puyuan"], + huangzu: ["huangzu", "dc_huangzu"], + huojun: ["huojun", "dc_huojun", "xin_huojun", "tw_huojun"], + zhaoyǎn: ["zhaoyǎn", "dc_zhaoyǎn"], + furong: ["ol_furong", "furong", "tw_furong"], + daxiaoqiao: ["daxiaoqiao", "dc_daxiaoqiao", "tw_daxiaoqiao"], + zhugeguo: ["zhugeguo", "tw_zhugeguo"], + wanglang: ["ol_wanglang", "wanglang", "old_wanglang"], + tengfanglan: ["tengfanglan", "dc_tengfanglan"], + zhangyì: ["ol_zhangyì", "zhangyì"], + yuantanyuanshang: ["yuantanyuanshang", "yuantanyuanxiyuanshang"], + ruiji: ["ruiji", "dc_ruiji"], + jsp_huangyueying: ["jsp_huangyueying", "re_jsp_huangyueying"], + ganfuren: ["ganfuren", "dc_ganfuren", "jsp_ganfuren"], + wenqin: ["wenqin", "pe_wenqin"], + zhouqun: ["ol_zhouqun", "zhouqun"], + qianzhao: ["ol_qianzhao", "qianzhao"], + ol_pengyang: ["ol_pengyang", "sp_pengyang"], + ol_luyusheng: ["ol_luyusheng", "luyusheng"], + fanjiangzhangda: ["fanjiangzhangda", "jsrg_fanjiangzhangda"], + simalang: ["re_simalang", "simalang"], + zhugedan: ["re_zhugedan", "zhugedan"], + zhangren: ["jsrg_zhangren", "zhangren"], + wenqin: ["ol_wenqin", "pe_wenqin"], + lukai: ["ol_lukai", "lukai"], + liupi: ["ol_liupi", "liupi"], }, - translate:{ - "xinfu_lingren":"凌人", - "xinfu_lingren_info":"每回合限一次。当你使用带有「伤害」标签的基本牌或普通锦囊牌指定目标后,你可以猜测其中的一个目标的手牌中是否有基本牌,锦囊牌或装备牌。若你猜中的项目数:≥1,此牌对该角色的伤害+1;≥2,你摸两张牌;≥3,你获得技能〖奸雄〗和〖行殇〗直到你的下回合开始。", - "lingren_adddamage":"凌人", - "lingren_adddamage_info":"", - "lingren_jianxiong":"奸雄", - "lingren_jianxiong_info":"当你受到伤害后,你可以获得对你造成伤害的牌并摸一张牌。", - "lingren_xingshang":"行殇", - "lingren_xingshang_info":"当有角色死亡后,你可以选择一项:1.回复1点体力。2.获得该角色的所有牌。", - "xinfu_fujian":"伏间", - "xinfu_fujian_info":"锁定技,结束阶段,你观看一名随机的其他角色的随机X张手牌。(X为场上手牌最少的角色的手牌数)", - fujian:'伏间', - fujian_info:'锁定技,准备阶段和结束阶段,你随机观看一名手牌数不为全场最多的其他角色的手牌。', - xinfu_xionghuo:'凶镬', - xinfu_xionghuo_info:'游戏开始时,你获得3个“暴戾”标记(标记上限为3)。出牌阶段,你可以交给一名其他角色一个“暴戾”标记。当你对有“暴戾”标记的其他角色造成伤害时,此伤害+1。有“暴戾”标记的其他角色的出牌阶段开始时,其移去所有“暴戾”标记并随机执行一项:1.受到1点火焰伤害且本回合不能对你使用【杀】;2.失去1点体力且本回合手牌上限-1;3.你随机获得其两张牌。', - xinfu_shajue:'杀绝', - xinfu_shajue_info:'锁定技,其他角色进入濒死状态时,你获得一个“暴戾”标记。然后若其体力值小于0,你获得使其进入濒死状态的牌。', - 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":"武娘", - "xinfu_wuniang_info":"当你使用或打出【杀】时,你可以获得一名其他角色的一张牌。若如此做,该角色和场上所有的“关索”各摸一张牌。", - "xinfu_xushen":"许身", - "xinfu_xushen_info":"限定技,当一名男性角色使用【桃】令你脱离濒死状态时,若场上没有“关索”,则其可以将自己的一张武将牌变更为“关索”。然后你回复1点体力,并获得技能〖镇南〗。", - "xinfu_zhennan":"镇南", - "xinfu_zhennan_info":"当你成为【南蛮入侵】的目标时,你可以对一名其他角色造成1-3点随机伤害。", - "xinfu_falu":"法箓", - "xinfu_falu_info":"锁定技,游戏开始时,你获得「紫薇」「后土」「玉清」「勾陈」标记各一个。当你的牌因弃置而进入弃牌堆后,根据这些牌的花色,你获得对应的标记:黑桃,你获得1枚「紫薇」;梅花,你获得1枚「后土」;红桃,你获得1枚「玉清」;方块,你获得1枚「勾陈」。(每种标记限拥有1个)", - "xinfu_dianhua":"点化", - "xinfu_dianhua_info":"准备阶段或结束阶段,你可以观看牌堆顶的X张牌(X为你的「紫薇」「后土」「玉清」「勾陈」标记数的总和)。若如此做,你将这些牌以任意顺序放回牌堆顶或牌堆底。", - "xinfu_zhenyi":"真仪", - "xinfu_zhenyi_info":"你可以在以下时机弃置相应的标记来发动以下效果:一名角色的判定牌生效前,你可以弃置一枚「紫薇」,然后将判定结果改为任意花色且点数为5;你的回合外,你可以弃置一枚「后土」,然后将你的一张手牌当【桃】使用;当你造成伤害时,你可以弃置一枚「玉清」,然后令此伤害+1;当你受到伤害后,你可以弃置一张「勾陈」,然后你从牌堆中随机获得三种类型的牌各一张。", - "zhenyi_spade":"真仪", - "zhenyi_spade_info":"", - "zhenyi_club":"真仪", - "zhenyi_club_info":"", - "zhenyi_heart":"真仪", - "zhenyi_heart_info":"", - zhangren:'张任', - zoushi:'邹氏', - zangba:'臧霸', - gz_jiling:'纪灵', - gz_sp_dongzhuo:'董卓', - gz_zhangjiao:'张角', - litong:'李通', - mizhu:'糜竺', - buzhi:'步骘', - chenlin:'陈琳', - yuanshu:'SP袁术', - yuanshu_prefix:'SP', - gongsunzan:'公孙瓒', - sp_diaochan:'SP貂蝉', - sp_diaochan_prefix:'SP', - yangxiu:'杨修', - sp_zhaoyun:'SP赵云', - sp_zhaoyun_prefix:'SP', - caohong:'曹洪', - liuxie:'刘协', - xiahouba:'夏侯霸', - zhugejin:'诸葛瑾', - zhugeke:'诸葛恪', - guanyinping:'关银屏', - sunhao:'孙皓', - chengyu:'程昱', - simalang:'司马朗', - gz_tianfeng:'田丰', - sp_jiaxu:'SP贾诩', - sp_jiaxu_prefix:'SP', - maliang:'马良', - sp_caoren:'SP曹仁', - sp_caoren_prefix:'SP', - yuejin:'乐进', - mifuren:'糜夫人', - sp_dongzhuo:'SP董卓', - sp_dongzhuo_prefix:'SP', - gz_jiangfei:'蒋琬费祎', - gz_jiangqing:'蒋钦', - hetaihou:'何太后', - dingfeng:'丁奉', - zhangxingcai:'张星彩', - caoang:'曹昂', - gz_kongrong:'孔融', - fuwan:'伏完', - sp_pangde:'SP庞德', - sp_pangde_prefix:'SP', - sp_sunshangxiang:'SP孙尚香', - sp_sunshangxiang_prefix:'SP', - zhugedan:'诸葛诞', - sp_machao:'SP马超', - sp_machao_prefix:'SP', - sp_jiangwei:'SP姜维', - sp_jiangwei_prefix:'SP', - zhangbao:'张宝', - yangxiou:'杨修', - shixie:'士燮', - mayunlu:'马云騄', - zhanglu:'张鲁', - wutugu:'兀突骨', - gz_mateng:'马腾', - sp_caiwenji:'SP蔡琰', - sp_caiwenji_prefix:'SP', - zhugeguo:'诸葛果', - lingcao:'凌操', - lingju:'灵雎', - lifeng:'李丰', - jsp_guanyu:'SP关羽', - jsp_guanyu_prefix:'SP', - zhuling:'朱灵', - sunluyu:'OL孙鲁育', - sunluyu_prefix:'OL', - hanba:'旱魃', - gz_panfeng:'潘凤', - zumao:'祖茂', - daxiaoqiao:'大乔小乔', - cuiyan:'崔琰', - wenpin:'文聘', - jsp_huangyueying:'SP黄月英', - jsp_huangyueying_prefix:'SP', - guansuo:'关索', - tadun:'蹋顿', - yanbaihu:'严虎', - wanglang:'王朗', - caochun:'曹纯', - dongbai:'OL董白', - dongbai_prefix:'OL', - zhaoxiang:'赵襄', - heqi:'贺齐', - kanze:'OL阚泽', - kanze_prefix:'OL', - dongyun:'董允', - mazhong:'马忠', - huangfusong:'皇甫嵩', - wangyun:'王允', - sunqian:'孙乾', - xizhicai:'戏志才', - beimihu:'卑弥呼', - luzhi:'鲁芝', - bianfuren:'卞夫人', - ol_bianfuren:'卞夫人', - shamoke:'沙摩柯', + translate: { + xinfu_lingren: "凌人", + xinfu_lingren_info: + "每回合限一次。当你使用带有「伤害」标签的基本牌或普通锦囊牌指定目标后,你可以猜测其中的一个目标的手牌中是否有基本牌,锦囊牌或装备牌。若你猜中的项目数:≥1,此牌对该角色的伤害+1;≥2,你摸两张牌;≥3,你获得技能〖奸雄〗和〖行殇〗直到你的下回合开始。", + lingren_adddamage: "凌人", + lingren_adddamage_info: "", + lingren_jianxiong: "奸雄", + lingren_jianxiong_info: "当你受到伤害后,你可以获得对你造成伤害的牌并摸一张牌。", + lingren_xingshang: "行殇", + lingren_xingshang_info: "当有角色死亡后,你可以选择一项:1.回复1点体力。2.获得该角色的所有牌。", + xinfu_fujian: "伏间", + xinfu_fujian_info: + "锁定技,结束阶段,你观看一名随机的其他角色的随机X张手牌。(X为场上手牌最少的角色的手牌数)", + fujian: "伏间", + fujian_info: "锁定技,准备阶段和结束阶段,你随机观看一名手牌数不为全场最多的其他角色的手牌。", + xinfu_xionghuo: "凶镬", + xinfu_xionghuo_info: + "游戏开始时,你获得3个“暴戾”标记(标记上限为3)。出牌阶段,你可以交给一名其他角色一个“暴戾”标记。当你对有“暴戾”标记的其他角色造成伤害时,此伤害+1。有“暴戾”标记的其他角色的出牌阶段开始时,其移去所有“暴戾”标记并随机执行一项:1.受到1点火焰伤害且本回合不能对你使用【杀】;2.失去1点体力且本回合手牌上限-1;3.你随机获得其两张牌。", + xinfu_shajue: "杀绝", + xinfu_shajue_info: + "锁定技,其他角色进入濒死状态时,你获得一个“暴戾”标记。然后若其体力值小于0,你获得使其进入濒死状态的牌。", + 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: "武娘", + xinfu_wuniang_info: + "当你使用或打出【杀】时,你可以获得一名其他角色的一张牌。若如此做,该角色和场上所有的“关索”各摸一张牌。", + xinfu_xushen: "许身", + xinfu_xushen_info: + "限定技,当一名男性角色使用【桃】令你脱离濒死状态时,若场上没有“关索”,则其可以将自己的一张武将牌变更为“关索”。然后你回复1点体力,并获得技能〖镇南〗。", + xinfu_zhennan: "镇南", + xinfu_zhennan_info: "当你成为【南蛮入侵】的目标时,你可以对一名其他角色造成1-3点随机伤害。", + xinfu_falu: "法箓", + xinfu_falu_info: + "锁定技,游戏开始时,你获得「紫薇」「后土」「玉清」「勾陈」标记各一个。当你的牌因弃置而进入弃牌堆后,根据这些牌的花色,你获得对应的标记:黑桃,你获得1枚「紫薇」;梅花,你获得1枚「后土」;红桃,你获得1枚「玉清」;方块,你获得1枚「勾陈」。(每种标记限拥有1个)", + xinfu_dianhua: "点化", + xinfu_dianhua_info: + "准备阶段或结束阶段,你可以观看牌堆顶的X张牌(X为你的「紫薇」「后土」「玉清」「勾陈」标记数的总和)。若如此做,你将这些牌以任意顺序放回牌堆顶或牌堆底。", + xinfu_zhenyi: "真仪", + xinfu_zhenyi_info: + "你可以在以下时机弃置相应的标记来发动以下效果:一名角色的判定牌生效前,你可以弃置一枚「紫薇」,然后将判定结果改为任意花色且点数为5;你的回合外,你可以弃置一枚「后土」,然后将你的一张手牌当【桃】使用;当你造成伤害时,你可以弃置一枚「玉清」,然后令此伤害+1;当你受到伤害后,你可以弃置一张「勾陈」,然后你从牌堆中随机获得三种类型的牌各一张。", + zhenyi_spade: "真仪", + zhenyi_spade_info: "", + zhenyi_club: "真仪", + zhenyi_club_info: "", + zhenyi_heart: "真仪", + zhenyi_heart_info: "", + zhangren: "张任", + zoushi: "邹氏", + zangba: "臧霸", + gz_jiling: "纪灵", + gz_sp_dongzhuo: "董卓", + gz_zhangjiao: "张角", + litong: "李通", + mizhu: "糜竺", + buzhi: "步骘", + chenlin: "陈琳", + yuanshu: "SP袁术", + yuanshu_prefix: "SP", + gongsunzan: "公孙瓒", + sp_diaochan: "SP貂蝉", + sp_diaochan_prefix: "SP", + yangxiu: "杨修", + sp_zhaoyun: "SP赵云", + sp_zhaoyun_prefix: "SP", + caohong: "曹洪", + liuxie: "刘协", + xiahouba: "夏侯霸", + zhugejin: "诸葛瑾", + zhugeke: "诸葛恪", + guanyinping: "关银屏", + sunhao: "孙皓", + chengyu: "程昱", + simalang: "司马朗", + gz_tianfeng: "田丰", + sp_jiaxu: "SP贾诩", + sp_jiaxu_prefix: "SP", + maliang: "马良", + sp_caoren: "SP曹仁", + sp_caoren_prefix: "SP", + yuejin: "乐进", + mifuren: "糜夫人", + sp_dongzhuo: "SP董卓", + sp_dongzhuo_prefix: "SP", + gz_jiangfei: "蒋琬费祎", + gz_jiangqing: "蒋钦", + hetaihou: "何太后", + dingfeng: "丁奉", + zhangxingcai: "张星彩", + caoang: "曹昂", + gz_kongrong: "孔融", + fuwan: "伏完", + sp_pangde: "SP庞德", + sp_pangde_prefix: "SP", + sp_sunshangxiang: "SP孙尚香", + sp_sunshangxiang_prefix: "SP", + zhugedan: "诸葛诞", + sp_machao: "SP马超", + sp_machao_prefix: "SP", + sp_jiangwei: "SP姜维", + sp_jiangwei_prefix: "SP", + zhangbao: "张宝", + yangxiou: "杨修", + shixie: "士燮", + mayunlu: "马云騄", + zhanglu: "张鲁", + wutugu: "兀突骨", + gz_mateng: "马腾", + sp_caiwenji: "SP蔡琰", + sp_caiwenji_prefix: "SP", + zhugeguo: "诸葛果", + lingcao: "凌操", + lingju: "灵雎", + lifeng: "李丰", + jsp_guanyu: "SP关羽", + jsp_guanyu_prefix: "SP", + zhuling: "朱灵", + sunluyu: "OL孙鲁育", + sunluyu_prefix: "OL", + hanba: "旱魃", + gz_panfeng: "潘凤", + zumao: "祖茂", + daxiaoqiao: "大乔小乔", + cuiyan: "崔琰", + wenpin: "文聘", + jsp_huangyueying: "SP黄月英", + jsp_huangyueying_prefix: "SP", + guansuo: "关索", + tadun: "蹋顿", + yanbaihu: "严虎", + wanglang: "王朗", + caochun: "曹纯", + dongbai: "OL董白", + dongbai_prefix: "OL", + zhaoxiang: "赵襄", + heqi: "贺齐", + kanze: "OL阚泽", + kanze_prefix: "OL", + dongyun: "董允", + mazhong: "马忠", + huangfusong: "皇甫嵩", + wangyun: "王允", + sunqian: "孙乾", + xizhicai: "戏志才", + beimihu: "卑弥呼", + luzhi: "鲁芝", + bianfuren: "卞夫人", + ol_bianfuren: "卞夫人", + shamoke: "沙摩柯", - caoying:"曹婴", - simahui:"司马徽", - baosanniang:"鲍三娘", - majun:"马钧", - simazhao:"司马昭", - wangyuanji:"王元姬", + caoying: "曹婴", + simahui: "司马徽", + baosanniang: "鲍三娘", + majun: "马钧", + simazhao: "司马昭", + wangyuanji: "王元姬", - jianggan:"蒋干", - hejin:'何进', - hansui:'韩遂', - niujin:'牛金', - xujing:'OL许靖', - xujing_prefix:'OL', - yuantanyuanshang:'袁谭袁尚', + jianggan: "蒋干", + hejin: "何进", + hansui: "韩遂", + niujin: "牛金", + xujing: "OL许靖", + xujing_prefix: "OL", + yuantanyuanshang: "袁谭袁尚", - xinfenyue:'奋钺', - xinfenyue_info:'出牌阶段限X次(X为与你不同阵营的存活角色数),你可以与一名其他角色拼点,若你赢,根据你拼点牌的点数依次执行以下效果:不大于5,你获得其一张牌;不大于9,你获得牌堆里的一张【杀】; 不大于K,视为你对其使用一张雷【杀】。', - neifa:'内伐', - neifa_info:'出牌阶段开始时,你可以摸两张牌或获得场上的一张牌,然后弃置一张牌。若弃置的牌是基本牌,本回合你不能使用锦囊和装备牌,且【杀】的使用次数+X且目标+1;若弃置的不是基本牌,本回合你不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标,前两次使用装备牌时摸X张牌(X为你发动〖内伐〗弃牌后手牌中因〖内伐〗而不能使用的牌的数量且最多为5)。', - neifa_use:'内伐', - yuxu:'誉虚', - yuxu_info:'当你于出牌阶段内使用的牌结算结束后,若你此前于此阶段发动过〖誉虚〗的次数为:偶数,你可以摸一张牌;奇数,你弃置一张牌。', - yuxu2:'誉虚(弃牌)', - xjshijian:'实荐', - xjshijian_info:'一名其他角色于其回合内使用的第二张牌结算完成后,你可弃置一张牌并令其获得技能〖誉虚〗直到回合结束。', - mouzhu:'谋诛', - mouzhu_info:'出牌阶段限一次,你可以令一名有手牌的其他角色交给你一张手牌。然后若你的手牌数大于其,其选择视为对你使用一张【杀】或【决斗】。', - yanhuo:'延祸', - yanhuo_info:'当你死亡时,你可以依次弃置一名其他角色的X张牌。(X为你的牌数)', - niluan:'逆乱', - niluan_info:'其他角色的结束阶段开始时,若其本回合内使用过【杀】或其体力值大于你,则你可以将一张黑色牌当做【杀】使用。', - cuorui:'挫锐', - cuorui_info:'锁定技,游戏开始时,你摸X张牌(X为你的体力上限)。锁定技,限定技,判定阶段开始前,若你的判定区有牌,你跳过此阶段。', - cuorui_info_single:'锁定技,你的起始手牌数改为X+2(X为你剩余的备选武将数)。你跳过登场后的第一个判定阶段。', - liewei:'裂围', - liewei_info:'当你杀死一名角色后,你可以摸三张牌。', + xinfenyue: "奋钺", + xinfenyue_info: + "出牌阶段限X次(X为与你不同阵营的存活角色数),你可以与一名其他角色拼点,若你赢,根据你拼点牌的点数依次执行以下效果:不大于5,你获得其一张牌;不大于9,你获得牌堆里的一张【杀】; 不大于K,视为你对其使用一张雷【杀】。", + neifa: "内伐", + neifa_info: + "出牌阶段开始时,你可以摸两张牌或获得场上的一张牌,然后弃置一张牌。若弃置的牌是基本牌,本回合你不能使用锦囊和装备牌,且【杀】的使用次数+X且目标+1;若弃置的不是基本牌,本回合你不能使用基本牌,且使用普通锦囊牌选择目标时可以增加或减少一个目标,前两次使用装备牌时摸X张牌(X为你发动〖内伐〗弃牌后手牌中因〖内伐〗而不能使用的牌的数量且最多为5)。", + neifa_use: "内伐", + yuxu: "誉虚", + yuxu_info: + "当你于出牌阶段内使用的牌结算结束后,若你此前于此阶段发动过〖誉虚〗的次数为:偶数,你可以摸一张牌;奇数,你弃置一张牌。", + yuxu2: "誉虚(弃牌)", + xjshijian: "实荐", + xjshijian_info: + "一名其他角色于其回合内使用的第二张牌结算完成后,你可弃置一张牌并令其获得技能〖誉虚〗直到回合结束。", + mouzhu: "谋诛", + mouzhu_info: + "出牌阶段限一次,你可以令一名有手牌的其他角色交给你一张手牌。然后若你的手牌数大于其,其选择视为对你使用一张【杀】或【决斗】。", + yanhuo: "延祸", + yanhuo_info: "当你死亡时,你可以依次弃置一名其他角色的X张牌。(X为你的牌数)", + niluan: "逆乱", + niluan_info: + "其他角色的结束阶段开始时,若其本回合内使用过【杀】或其体力值大于你,则你可以将一张黑色牌当做【杀】使用。", + cuorui: "挫锐", + cuorui_info: + "锁定技,游戏开始时,你摸X张牌(X为你的体力上限)。锁定技,限定技,判定阶段开始前,若你的判定区有牌,你跳过此阶段。", + cuorui_info_single: + "锁定技,你的起始手牌数改为X+2(X为你剩余的备选武将数)。你跳过登场后的第一个判定阶段。", + liewei: "裂围", + liewei_info: "当你杀死一名角色后,你可以摸三张牌。", - weicheng:'伪诚', - weicheng_info:'当牌从你的手牌区移动至其他角色的手牌区后,若你的手牌数小于体力值,你可以摸一张牌。', - daoshu:'盗书', - daoshu_info:'出牌阶段限一次。你可以选择一个花色并获得一名其他角色的一张手牌。若此牌花色与你选择的相同,则你对其造成1点伤害且你〖盗书〗于此阶段内可使用的次数上限+1。否则你须交给其一张与此牌花色不同的手牌(没有则展示手牌)。', + weicheng: "伪诚", + weicheng_info: + "当牌从你的手牌区移动至其他角色的手牌区后,若你的手牌数小于体力值,你可以摸一张牌。", + daoshu: "盗书", + daoshu_info: + "出牌阶段限一次。你可以选择一个花色并获得一名其他角色的一张手牌。若此牌花色与你选择的相同,则你对其造成1点伤害且你〖盗书〗于此阶段内可使用的次数上限+1。否则你须交给其一张与此牌花色不同的手牌(没有则展示手牌)。", - xinshanjia:"缮甲", - xinshanjia_info:"出牌阶段开始时,你可以摸三张牌,然后弃置3-X张牌(X为你本局游戏内不因使用而失去过的装备牌的数目且至多为3)。若你没有以此法弃置:基本牌,此阶段你使用【杀】的次数上限+1;锦囊牌,此阶段你使用牌无距离限制;基本牌或锦囊牌,你可以视为使用一张【杀】。", - "new_meibu":"魅步", - "new_meibu_info":"其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌,令该角色于本回合内获得技能〖止息〗。若你以此法弃置的牌不是【杀】或黑色锦囊牌,则本回合其与你的距离视为1。", - "new_mumu":"穆穆", - "new_mumu_info":"出牌阶段开始时,你可以选择一项:1.弃置一名其他角色装备区里的一张牌;2.获得一名角色装备区里的一张防具牌,若如此做,你本回合不能使用【杀】。", - new_zhixi:"止息", - new_zhixi_info:"锁定技。出牌阶段内,若你使用过锦囊牌或使用过的牌数不小于X,则你不能使用牌(X为你的体力值)。", - "new_mumu2":"穆穆", - "new_mumu2_info":"锁定技,你不能使用【杀】。", - new_xingwu:"星舞", - new_xingwu_info:"弃牌阶段开始时,你可以将一张牌置于武将牌上,称为“舞”。然后你可以选择一项:①将三张“舞”置入弃牌堆;②弃置两张手牌并将武将牌翻面。若如此做,你选择一名角色,该角色弃置其装备区的所有牌并受到2点伤害(若为女性,则改为1点)。", - "new_luoyan":"落雁", - "new_luoyan_info":"锁定技。若你的武将牌上有“舞”,则你视为拥有技能〖天香〗和〖流离〗。", - "new_luoyan_tianxiang":"天香", - "new_luoyan_tianxiang_info":"", - "new_luoyan_liuli":"流离", - "new_luoyan_liuli_info":"", - ol_shichou:"誓仇", - ol_shichou_info:"当你使用【杀】时,你可以令至多X+1名角色也成为此【杀】的目标(X为你已损失的体力值)。", - dc_olshichou: '誓仇', - dc_olshichou_info: '当你使用【杀】时,你可以令至多X名角色也成为此【杀】的目标。此牌结算结束后,若你未因【杀】造成过伤害,则你获得此【杀】(X为你已损失的体力值)。', - "zhenwei_three":"镇卫", - "zhenwei_three_info":"锁定技,敌方角色至己方其他角色的距离+1。", - "huanshi_three":"缓释", - "huanshi_three_info":"一名友方角色的判定牌生效前,你可打出一张牌代替之。", + xinshanjia: "缮甲", + xinshanjia_info: + "出牌阶段开始时,你可以摸三张牌,然后弃置3-X张牌(X为你本局游戏内不因使用而失去过的装备牌的数目且至多为3)。若你没有以此法弃置:基本牌,此阶段你使用【杀】的次数上限+1;锦囊牌,此阶段你使用牌无距离限制;基本牌或锦囊牌,你可以视为使用一张【杀】。", + new_meibu: "魅步", + new_meibu_info: + "其他角色的出牌阶段开始时,若你在其攻击范围内,你可以弃置一张牌,令该角色于本回合内获得技能〖止息〗。若你以此法弃置的牌不是【杀】或黑色锦囊牌,则本回合其与你的距离视为1。", + new_mumu: "穆穆", + new_mumu_info: + "出牌阶段开始时,你可以选择一项:1.弃置一名其他角色装备区里的一张牌;2.获得一名角色装备区里的一张防具牌,若如此做,你本回合不能使用【杀】。", + new_zhixi: "止息", + new_zhixi_info: + "锁定技。出牌阶段内,若你使用过锦囊牌或使用过的牌数不小于X,则你不能使用牌(X为你的体力值)。", + new_mumu2: "穆穆", + new_mumu2_info: "锁定技,你不能使用【杀】。", + new_xingwu: "星舞", + new_xingwu_info: + "弃牌阶段开始时,你可以将一张牌置于武将牌上,称为“舞”。然后你可以选择一项:①将三张“舞”置入弃牌堆;②弃置两张手牌并将武将牌翻面。若如此做,你选择一名角色,该角色弃置其装备区的所有牌并受到2点伤害(若为女性,则改为1点)。", + new_luoyan: "落雁", + new_luoyan_info: "锁定技。若你的武将牌上有“舞”,则你视为拥有技能〖天香〗和〖流离〗。", + new_luoyan_tianxiang: "天香", + new_luoyan_tianxiang_info: "", + new_luoyan_liuli: "流离", + new_luoyan_liuli_info: "", + ol_shichou: "誓仇", + ol_shichou_info: + "当你使用【杀】时,你可以令至多X+1名角色也成为此【杀】的目标(X为你已损失的体力值)。", + dc_olshichou: "誓仇", + dc_olshichou_info: + "当你使用【杀】时,你可以令至多X名角色也成为此【杀】的目标。此牌结算结束后,若你未因【杀】造成过伤害,则你获得此【杀】(X为你已损失的体力值)。", + zhenwei_three: "镇卫", + zhenwei_three_info: "锁定技,敌方角色至己方其他角色的距离+1。", + huanshi_three: "缓释", + huanshi_three_info: "一名友方角色的判定牌生效前,你可打出一张牌代替之。", - yizan:"翊赞", - yizan_info:"你可以将两张牌(其中至少一张是基本牌)当任意基本牌牌使用。", - yizan0:"翊赞", - yizan0_info:"你可以将两张牌(其中至少一张是基本牌)当任意基本牌牌使用。", - yizan1:"翊赞", - yizan1_info:"你可以将两张牌(其中至少一张是基本牌)当【闪】打出。", - yizan2:"翊赞", - yizan2_info:"你可以将一张基本牌当任意基本牌牌使用。", - yizan3:"翊赞", - yizan3_info:"你可以将一张基本牌当【闪】打出。", - yizan5:"翊赞", - yizan5_info:"你可以将两张牌(其中至少一张是基本牌)当【杀】打出。", - yizan6:"翊赞", - yizan6_info:"你可以将一张基本牌当【杀】打出。", - longyuan:"龙渊", - longyuan_info:"觉醒技 当你使用或打出基本牌时,若你已经已累计发动过3次〖翊赞〗,你将〖翊赞〗改为“你可以将一张基本牌当任意基本牌牌使用或打出”。", - wuniang:"武娘", - wuniang_info:"你使用或打出【杀】时,你可以获得一名其他角色的一张牌,然后该角色摸一张牌;若“关索”在场,你可令“关索”也摸一张牌。", - zhennan:"镇南", - zhennan_info:"当你成为【南蛮入侵】的目标时,你可令一名其他角色随机受到1至3点伤害。", - xushen:"许身", - xushen_info:"当其他男性角色令你脱离濒死状态时,若“关索”不在场,其可以选择是否用“关索”替换其武将牌,然后你回复1点体力并获得技能〖镇南〗。", + yizan: "翊赞", + yizan_info: "你可以将两张牌(其中至少一张是基本牌)当任意基本牌牌使用。", + yizan0: "翊赞", + yizan0_info: "你可以将两张牌(其中至少一张是基本牌)当任意基本牌牌使用。", + yizan1: "翊赞", + yizan1_info: "你可以将两张牌(其中至少一张是基本牌)当【闪】打出。", + yizan2: "翊赞", + yizan2_info: "你可以将一张基本牌当任意基本牌牌使用。", + yizan3: "翊赞", + yizan3_info: "你可以将一张基本牌当【闪】打出。", + yizan5: "翊赞", + yizan5_info: "你可以将两张牌(其中至少一张是基本牌)当【杀】打出。", + yizan6: "翊赞", + yizan6_info: "你可以将一张基本牌当【杀】打出。", + longyuan: "龙渊", + longyuan_info: + "觉醒技 当你使用或打出基本牌时,若你已经已累计发动过3次〖翊赞〗,你将〖翊赞〗改为“你可以将一张基本牌当任意基本牌牌使用或打出”。", + wuniang: "武娘", + wuniang_info: + "你使用或打出【杀】时,你可以获得一名其他角色的一张牌,然后该角色摸一张牌;若“关索”在场,你可令“关索”也摸一张牌。", + zhennan: "镇南", + zhennan_info: "当你成为【南蛮入侵】的目标时,你可令一名其他角色随机受到1至3点伤害。", + xushen: "许身", + xushen_info: + "当其他男性角色令你脱离濒死状态时,若“关索”不在场,其可以选择是否用“关索”替换其武将牌,然后你回复1点体力并获得技能〖镇南〗。", - wanwei:'挽危', - wanwei_info:'当你因被其他角色获得或弃置而失去牌时,你可以改为自己选择失去的牌。', - gzjili:'蒺藜', - gzjili_info:'当你于一回合内使用或打出第X张牌时,你可以摸X张牌(X为你的攻击范围)。', + wanwei: "挽危", + wanwei_info: "当你因被其他角色获得或弃置而失去牌时,你可以改为自己选择失去的牌。", + gzjili: "蒺藜", + gzjili_info: "当你于一回合内使用或打出第X张牌时,你可以摸X张牌(X为你的攻击范围)。", - qingzhong:'清忠', - qingzhong_info:'出牌阶段开始时,你可以摸两张牌,若如此做,此阶段结束时,你与手牌数最少的角色交换手牌。', - weijing:'卫境', - weijing_info:'每轮限一次,当你需要使用【杀】或【闪】时,你可以视为使用一张【杀】或【闪】。', - zishu:'自书', - zishu_info:'锁定技。①其他角色的回合结束时,你将手牌区里所有你于此回合得到过的牌置入弃牌堆。②当你于回合内不因〖自书②〗而得到牌后,你摸一张牌。', - yingyuan:'应援', - yingyuan_info:'当你于回合内使用的牌结算完成后,你可以将其交给一名其他角色(相同牌名的牌每回合限一次)。', - xinyingyuan:'应援', - xinyingyuan_info:'当你于回合内使用一张牌后,你可以令一名其他角色从牌堆获得一张与该牌类型相同的牌(每种类型的牌每回合限一次)。', - qianya:'谦雅', - qianya_info:'当你成为锦囊牌的目标后,你可以将任意张手牌交给一名其他角色。', - shuimeng:'说盟', - shuimeng_info:'出牌阶段结束时,你可以与一名角色拼点,若你赢,视为你使用【无中生有】;若你没赢,视为其对你使用【过河拆桥】。', - xianfu:'先辅', - xianfu2:'先辅', - xianfu2_bg:'辅', - xianfu_info:'锁定技,游戏开始时,你选择一名其他角色,当其受到伤害后,你受到等量的伤害,当其回复体力后,你回复等量的体力。', - chouce:'筹策', - chouce_info:'当你受到1点伤害后,你可以判定,若结果为:黑色,你弃置一名角色区域里的一张牌;红色,你选择一名角色,其摸一张牌,若其是〖先辅〗选择的角色,改为其摸两张牌。', - fuqi:'伏骑', - fuqi_info:'锁定技,当你使用牌时,你令所有与你距离为1的其他角色不能使用或打出牌响应此牌。', - jiaozi:'骄恣', - jiaozi_info:'锁定技,若你的手牌数为全场唯一最多,则当你造成或受到伤害时,此伤害+1。', - wy_meirenji:'美人计', - wy_meirenji_info:'出牌阶段,对一名有手牌的其他男性角色使用。每名女性角色各获得其一张手牌并将一张手牌交给你,然后比较你与其的手牌数,手牌少的角色对手牌多的角色造成1点伤害。', - wy_xiaolicangdao:'笑里藏刀', - wy_xiaolicangdao_info:'出牌阶段,对一名其他角色使用。该角色摸X张牌(X为其已损失的体力值且至多为5),然后你对其造成1点伤害。', - weikui:'伪溃', - weikui2:'伪溃', - weikui_info:'出牌阶段限一次,你可以失去1点体力并选择一名有手牌的其他角色,你观看其手牌:若其手牌中有【闪】,则视为你对其使用【杀】,且本回合你计算与其的距离视为1;若其手牌中没有【闪】,你弃置其中一张牌。', - lizhan:'励战', - lizhan_info:'结束阶段,你可以令任意名已受伤的角色摸一张牌。', - wylianji:'连计', - wylianji_info:'出牌阶段限一次,你可以展示一张【杀】或黑色锦囊牌,并令一名其他角色将牌堆中的随机一张武器牌置入装备区(可替换原装备)。然后该角色选择一项:1.对除你以外的角色使用该牌,并将装备区里的武器牌交给该牌的一个目标角色;2.令你对其使用此牌,然后获得此牌,并将装备区内的武器牌交给你。', + qingzhong: "清忠", + qingzhong_info: + "出牌阶段开始时,你可以摸两张牌,若如此做,此阶段结束时,你与手牌数最少的角色交换手牌。", + weijing: "卫境", + weijing_info: "每轮限一次,当你需要使用【杀】或【闪】时,你可以视为使用一张【杀】或【闪】。", + zishu: "自书", + zishu_info: + "锁定技。①其他角色的回合结束时,你将手牌区里所有你于此回合得到过的牌置入弃牌堆。②当你于回合内不因〖自书②〗而得到牌后,你摸一张牌。", + yingyuan: "应援", + yingyuan_info: + "当你于回合内使用的牌结算完成后,你可以将其交给一名其他角色(相同牌名的牌每回合限一次)。", + xinyingyuan: "应援", + xinyingyuan_info: + "当你于回合内使用一张牌后,你可以令一名其他角色从牌堆获得一张与该牌类型相同的牌(每种类型的牌每回合限一次)。", + qianya: "谦雅", + qianya_info: "当你成为锦囊牌的目标后,你可以将任意张手牌交给一名其他角色。", + shuimeng: "说盟", + shuimeng_info: + "出牌阶段结束时,你可以与一名角色拼点,若你赢,视为你使用【无中生有】;若你没赢,视为其对你使用【过河拆桥】。", + xianfu: "先辅", + xianfu2: "先辅", + xianfu2_bg: "辅", + xianfu_info: + "锁定技,游戏开始时,你选择一名其他角色,当其受到伤害后,你受到等量的伤害,当其回复体力后,你回复等量的体力。", + chouce: "筹策", + chouce_info: + "当你受到1点伤害后,你可以判定,若结果为:黑色,你弃置一名角色区域里的一张牌;红色,你选择一名角色,其摸一张牌,若其是〖先辅〗选择的角色,改为其摸两张牌。", + fuqi: "伏骑", + fuqi_info: "锁定技,当你使用牌时,你令所有与你距离为1的其他角色不能使用或打出牌响应此牌。", + jiaozi: "骄恣", + jiaozi_info: "锁定技,若你的手牌数为全场唯一最多,则当你造成或受到伤害时,此伤害+1。", + wy_meirenji: "美人计", + wy_meirenji_info: + "出牌阶段,对一名有手牌的其他男性角色使用。每名女性角色各获得其一张手牌并将一张手牌交给你,然后比较你与其的手牌数,手牌少的角色对手牌多的角色造成1点伤害。", + wy_xiaolicangdao: "笑里藏刀", + wy_xiaolicangdao_info: + "出牌阶段,对一名其他角色使用。该角色摸X张牌(X为其已损失的体力值且至多为5),然后你对其造成1点伤害。", + weikui: "伪溃", + weikui2: "伪溃", + weikui_info: + "出牌阶段限一次,你可以失去1点体力并选择一名有手牌的其他角色,你观看其手牌:若其手牌中有【闪】,则视为你对其使用【杀】,且本回合你计算与其的距离视为1;若其手牌中没有【闪】,你弃置其中一张牌。", + lizhan: "励战", + lizhan_info: "结束阶段,你可以令任意名已受伤的角色摸一张牌。", + wylianji: "连计", + wylianji_info: + "出牌阶段限一次,你可以展示一张【杀】或黑色锦囊牌,并令一名其他角色将牌堆中的随机一张武器牌置入装备区(可替换原装备)。然后该角色选择一项:1.对除你以外的角色使用该牌,并将装备区里的武器牌交给该牌的一个目标角色;2.令你对其使用此牌,然后获得此牌,并将装备区内的武器牌交给你。", // from here - moucheng:'谋逞', - moucheng_info:'觉醒技,当其他角色使用因〖连计〗交给其的牌累计造成伤害达到3点后,你失去技能〖连计〗,然后获得技能〖矜功〗。', - jingong:'矜功', - jingong2:'矜功', - jingong_backup:'矜功', - jingong_info:'出牌阶段限一次,你可以将一张装备牌或【杀】当做一张随机锦囊牌使用(三选一,其中一张为【美人计】或【笑里藏刀】),然后本回合的结束阶段,若你于本回合内未造成过伤害,你失去1点体力。', - fenyue:'奋钺', - fenyue2:'奋钺', - fenyue2_bg:'钺', - fenyue_info:'出牌阶段限X次,你可以与一名角色拼点,若你赢,你选择一项:1.令其不能使用或打出手牌直到回合结束;2.视为对其使用一张【杀】(不计入次数)。若你没赢,你结束出牌阶段。(X为存活的忠臣数)', + moucheng: "谋逞", + moucheng_info: + "觉醒技,当其他角色使用因〖连计〗交给其的牌累计造成伤害达到3点后,你失去技能〖连计〗,然后获得技能〖矜功〗。", + jingong: "矜功", + jingong2: "矜功", + jingong_backup: "矜功", + jingong_info: + "出牌阶段限一次,你可以将一张装备牌或【杀】当做一张随机锦囊牌使用(三选一,其中一张为【美人计】或【笑里藏刀】),然后本回合的结束阶段,若你于本回合内未造成过伤害,你失去1点体力。", + fenyue: "奋钺", + fenyue2: "奋钺", + fenyue2_bg: "钺", + fenyue_info: + "出牌阶段限X次,你可以与一名角色拼点,若你赢,你选择一项:1.令其不能使用或打出手牌直到回合结束;2.视为对其使用一张【杀】(不计入次数)。若你没赢,你结束出牌阶段。(X为存活的忠臣数)", - zfengshi:'锋矢', - zfengshi_info:'当你使用【杀】指定目标后,你可以令目标弃置装备区内的一张牌。', - chuanxin:'穿心', - chuanxin_info:'当你于出牌阶段内使用【杀】或【决斗】对目标角色造成伤害时,你可以防止此伤害。若如此做,该角色选择一项:1.弃置装备区里的所有牌,若如此做,其失去1点体力;2.随机移除主武将牌上的一个技能。', - chuanxin_info_guozhan:'当你于出牌阶段内使用【杀】或【决斗】对目标角色造成伤害时,若其与你势力不同且有副将,你可以防止此伤害。若如此做,该角色选择一项:1.弃置装备区里的所有牌,若如此做,其失去1点体力;2.移除副将。', - hengjiang:'横江', - hengjiang2:'横江', - hengjiang_info:'当你受到1点伤害后,你可以令当前回合角色本回合的手牌上限-1。然后若其弃牌阶段内没有弃牌,则你摸一张牌。', - rehengjiang:'横江', - rehengjiang2:'横江', - rehengjiang3:'横江', - rehengjiang_info:'当你受到1点伤害后,你可以令当前回合角色本回合的手牌上限-1。然后若其弃牌阶段内有/没有弃牌,则你摸一/X张牌(X为你本回合内对其发动过〖横江〗的次数)。', - shuangren:'双刃', - shuangren_info:'出牌阶段开始时,你可以与一名角色拼点。若你赢,你视为对其或与其势力相同的另一名角色使用一张【杀】(不计入出牌阶段的次数限制);若你没赢,你本回合内不能对其他角色使用牌。', - xiashu:'下书', - xiashu_info:'出牌阶段开始时,你可以将所有手牌交给一名其他角色,然后该角色亮出任意数量的手牌(至少一张)。你选择一项:1.获得其亮出的手牌;2.获得其未亮出的手牌。', - kuanshi:'宽释', - kuanshi2:'宽释', - kuanshi_info:'结束阶段,你可以选择一名角色。直到你的下回合开始,该角色第一次受到大于1的伤害时,防止此伤害,然后你跳过下个回合的摸牌阶段。', - bingzheng:'秉正', - bingzheng_info:'出牌阶段结束时,你可以令手牌数不等于体力值的一名角色弃置一张手牌或摸一张牌。然后若其手牌数等于体力值,你摸一张牌,且可以交给该角色一张牌。', - sheyan:'舍宴', - sheyan_info:'当你成为普通锦囊牌的目标时(【借刀杀人】等带有指向目标的锦囊除外),你可以为此牌增加一个目标或令其对其中一个目标无效。(有效目标数至少为一)', - fuman:'抚蛮', - fuman2:'抚蛮', - fuman_info:'出牌阶段每名角色限一次,你可以将一张手牌交给一名其他角色并标记为“抚蛮”且“抚蛮”牌的牌名视为【杀】。然后当一名角色使用“抚蛮”牌结算结束后,你摸一张牌。若此牌造成过伤害,则改为摸两张牌。', - qizhou:'绮胄', - qizhou_info:'锁定技,你根据装备区里牌的花色数获得以下技能:1种或以上:〖马术〗;2种或以上:〖英姿〗;3种或以上:〖短兵〗;4种:〖奋威〗。', - shanxi:'闪袭', - shanxi_info:'出牌阶段限一次,你可以弃置一张红色基本牌,然后弃置攻击范围内的一名其他角色的一张牌。若弃置的牌是【闪】,你观看其手牌,若弃置的不是【闪】,其观看你的手牌。', - duanbing:'短兵', - duanbing_info:'当你使用【杀】选择目标后,你可以令一名距离为1的其他角色也成为此牌的目标。', - fanghun:'芳魂', - fanghun_info:'当你使用【杀】造成伤害或受到【杀】的伤害后,你获得X个“梅影”标记(X为伤害点数);你可以移去1个“梅影”标记来发动〖龙胆〗并摸一张牌。', - refanghun:'芳魂', - refanghun_info:'当你使用【杀】或成为【杀】的目标后,你获得1个“梅影”标记;你可以移去1个“梅影”标记来发动〖龙胆〗并摸一张牌。', - fanghun_sha:'龙胆', - fuhan:'扶汉', - fuhan_info:'限定技,回合开始时,你可以移去所有“梅影”标记并摸等量的牌,随机观看五名未登场的蜀势力角色,将武将牌替换为其中一名角色,并将体力上限数调整为本局游戏中移去“梅影”标记的数量(至少为2,至多为8),然后回复1点体力。', - refuhan:'扶汉', - refuhan_info:'限定技,回合开始时,你可以移去所有"梅影"标记并摸等量的牌,然后从X张蜀势力武将牌中选择并获得至多两个技能(限定技、觉醒技、隐匿技、使命技、主公技除外)。若此时你是体力值最低的角色,你回复1点体力(X为场上角色数,且X∈[4,+∞))。', - yjixi:'觊玺', - yjixi_info:'觉醒技,结束阶段,若你已连续三个自己回合未失去过体力,则你增加1点体力上限并回复1点体力,然后选择一项:获得技能〖妄尊〗;摸两张牌并获得当前主公的主公技。', - xinyongsi:'庸肆', - xinyongsi1:'庸肆', - xinyongsi2:'庸肆', - xinyongsi_info:'锁定技,摸牌阶段,你令额定摸牌数改为X(X为势力数);弃牌阶段开始时,你选择一项:1.弃置一张牌;2.失去1点体力。', - xiehui:'黠慧', - xiehui2:'黠慧', - xiehui_info:'锁定技,你的黑色牌不计入手牌上限;其他角色获得你的黑色牌时,其不能使用、打出、弃置这些牌直到其体力值扣减为止。', - lianzhu:'连诛', - lianzhu_info:'出牌阶段限一次,你可以展示并交给一名其他角色一张牌,若此牌为黑色,其选择一项:1.你摸两张牌;2.弃置两张牌。', - shanjia:'缮甲', - shanjia_info:'出牌阶段开始时,你可以摸X张牌,然后弃置等量的牌。若你以此法弃置了装备区内的牌,则你可以视为使用一张【杀】。(X为你于本局游戏内使用过的装备牌数且最大为7)', - tuifeng:'推锋', - tuifeng2:'推锋', - tuifeng_info:'1.当你受到伤害后,你可以将至多X张牌置于武将牌上(X为伤害值),称为“锋”。2.准备阶段开始时,若你的武将牌上有“锋”,你移去所有“锋”,摸2X张牌,然后你于此回合的出牌阶段内使用【杀】的次数上限+X。(X为你此次移去的“锋”数)', - ziyuan:'资援', - ziyuan_info:'出牌阶段限一次,你可以将任意张点数之和为13的手牌交给一名其他角色,然后该角色回复1点体力。', - jugu:'巨贾', - jugu_info:'锁定技,1.你的手牌上限+X。2.游戏开始时,你摸X张牌(X为你的体力上限)。', - hongde:'弘德', - hongde_info:'当你一次获得或失去至少两张牌后,你可以令一名其他角色摸一张牌。', - dingpan:'定叛', - dingpan_info_identity:'出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的反贼数)', - dingpan_info_doudizhu:'出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的农民数)', - dingpan_info_versus_two:'出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的最大阵营角色数)', - dingpan_info_versus:'出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的敌方角色数)', - dingpan_info:'出牌阶段限一次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。', - weidi:'伪帝', - weidi_info:'锁定技,你视为拥有当前主公的主公技。', - juesi:'决死', - juesi_info:'出牌阶段,你可以弃置一张【杀】并选择攻击范围内的一名有牌的其他角色,该角色弃置一张牌,然后若弃置的牌不是【杀】且你的体力值不大于该角色,你视为对其使用【决斗】。', - zhenlue:'缜略', - zhenlue_info:'锁定技,你使用的普通锦囊牌不能被【无懈可击】响应;你不能成为延时锦囊牌的目标。', - jianshu:'间书', - jianshu_info:'限定技,出牌阶段,你可以将一张黑色手牌交给一名其他角色,并选择另一名其他角色,然后令这两名角色拼点。赢的角色弃置两张牌,没赢的角色失去1点体力。', - yongdi:'拥嫡', - yongdi_info:'限定技,准备阶段开始时,你可令一名其他男性角色增加1点体力上限并回复1点体力,然后若该角色的武将牌上有主公技且其不为主公,其获得此主公技。', - regushe:'鼓舌', - regushe_info:'出牌阶段,若X小于7,则你可以用一张手牌与至多三名角色同时拼点,然后依次结算拼点结果,没赢的角色选择一项:1.弃置一张牌;2.令你摸一张牌。若你没赢,你获得一个“饶舌”标记。当你获得第7个“饶舌”标记时,你死亡。(X为你的“饶舌”标记数与本回合因“鼓舌”拼点而胜利的次数之和)', - rejici:'激词', - rejici2:'激词', - rejici_info:'锁定技。①当你的拼点牌亮出后,若此牌的点数不大于X,则你令此牌点数+X,并获得此次拼点中点数最大的拼点牌。②当你死亡时,你令杀死你的角色弃置7-X张牌并失去1点体力(X为你的“饶舌”标记数)。', - gushe:'鼓舌', - gushe_bg:'舌', - gushe_info:'出牌阶段限一次,你可以用一张手牌与至多三名角色同时拼点,然后依次结算拼点结果,没赢的角色选择一项:1.弃置一张牌;2.令你摸一张牌。若你没赢,你获得一个“饶舌”标记。当你获得第7个“饶舌”标记时,你死亡。', - jici:'激词', - jici_info:'当你因发动〖鼓舌〗而扣置的拼点牌亮出后,若点数小于X,你可令点数+X;若点数等于X,你可令你本回合发动〖鼓舌〗的次数上限+1。(X为你“饶舌”标记的数量)', - shefu:'设伏', - shefu2:'设伏', - shefu_bg:'伏', - shefu_info:'结束阶段开始时,你可以将一张牌移出游戏,称为「伏兵」。并为「伏兵」记录一个基本牌或锦囊牌的名称(须与其他「伏兵」记录的名称均不同)。你的回合外,当有其他角色使用与你记录的「伏兵」牌名相同的手牌时,你可以取消此牌的所有目标,然后移去该「伏兵」。若此时处于使用者的回合内,则你令使用者当前的所有非Charlotte技失效直至回合结束。', - benyu:'贲育', - benyu2:'贲育', - benyu_info:'当你受到伤害后,你可选择:①将手牌摸至与伤害来源手牌数相同(至多摸至5张);②弃置大于伤害来源手牌数的牌,然后对其造成1点伤害。', - zhidao:'雉盗', - zhidao_info:'锁定技,当你于你的回合内第一次对区域里有牌的其他角色造成伤害后,你获得其手牌、装备区和判定区里的各一张牌,然后直到回合结束,其他角色不能被选择为你使用牌的目标。', - jili:'寄篱', - jili_info:'锁定技,当一名其他角色成为红色基本牌或红色普通锦囊牌的目标时,若其与你的距离为1且你既不是此牌的使用者也不是目标,你也成为此牌的目标。', - luanzhan:'乱战', - luanzhan_info:'你使用【杀】或黑色普通锦囊牌可以额外选择X名角色为目标;当你使用【杀】或黑色普通锦囊牌指定目标后,若此牌的目标角色数小于X,则X减至0。(X为你于本局游戏内造成过伤害的次数)', - zhengnan:'征南', - zhengnan_info:'其他角色死亡后,你可以摸三张牌并获得下列技能中的任意一个:〖武圣〗、〖当先〗和〖制蛮〗。', - xinzhengnan:'征南', - xinzhengnan_info:'当一名角色进入濒死状态时,若你未因其发动过〖征南〗,则你回复1点体力并摸一张牌并获得下列技能中的任意一个:〖武圣〗、〖当先〗和〖制蛮〗(若技能全部拥有则改为摸三张牌。你以此法获得的〖当先〗结算时视为已发动过〖伏枥〗)。', - xiefang:'撷芳', - xiefang_info:'锁定技,你计算与其他角色的距离时-X。(X为女性角色数)', - qizhi:'奇制', - qizhi_info:'当你于回合内使用基本牌或锦囊牌指定目标后,你可以弃置不是此牌目标的一名角色的一张牌。若如此做,其摸一张牌。', - jinqu:'进趋', - jinqu_info:'结束阶段开始时,你可以摸两张牌,若如此做,你将手牌弃置至X张。(X为你于此回合发动过〖奇制〗的次数)', - jiqiao:'机巧', - jiqiao_info:'出牌阶段开始时,你可以弃置任意张装备牌,然后亮出牌堆顶两倍数量的牌并获得其中的非装备牌。', - linglong:'玲珑', - linglong_info:'锁定技,若你的装备区没有武器牌,则你使用【杀】的次数上限+1;若你的装备区没有防具牌,视为你装备着【八卦阵】;若你的装备区没有坐骑牌,你的手牌上限+1;若你的装备区没有宝物牌,则你视为拥有技能〖奇才〗。', - zhenwei:'镇卫', - zhenwei2:'镇卫', - zhenwei_info:'当一名其他角色成为【杀】或黑色锦囊牌的目标时(使用者不是你),若该角色的体力值小于你且此牌的目标角色数为1,你可以弃置一张牌。若如此做,你选择一项:1、摸一张牌,然后将此【杀】或黑色锦囊牌转移给你;2、令此【杀】或黑色锦囊牌无效,然后将此【杀】或黑色锦囊牌置于使用者的武将牌旁,若如此做,当前回合结束后,使用者获得使用者武将牌旁的这些牌。', - xingwu:'星舞', - xingwu_info:'弃牌阶段开始时,你可以将一张与你本回合使用的牌颜色均不同的手牌置于武将牌上:若你有至少三张“星舞”牌,你移去“星舞”牌并选择一名男性角色,该角色受到2点伤害并弃置其装备区的所有牌。', - luoyan:'落雁', - luoyan_info:'锁定技。若你的武将牌上有“星舞牌”,你拥有“天香”和“流离”。', - yinbing:'引兵', - yinbing_info:'结束阶段开始时,你可以将至少一张非基本牌置于武将牌上。每当你受到【杀】或【决斗】的伤害后,你移去一张「引兵」牌。', - juedi:'绝地', - juedi_info:'锁定技,准备阶段,若你的武将牌上有「引兵」牌,你选择一项:1.移去「引兵」牌,将手牌补至体力上限数;2.将「引兵」牌交给一名体力值不大于你的其他角色,其回复1点体力并摸等量的牌。', - kuangfu:'狂斧', - kuangfu_info:'当你使用【杀】造成伤害后,你可以选择一项:弃置其装备区内的一张牌,或将其装备区内的一张牌移动到你的装备区内。', - xintan:'心惔', - xintan_info:'出牌阶段限一次,你可以移去两张「焚」并选择一名角色,该角色失去1点体力。', - fentian:'焚天', - fentian_info:'锁定技,结束阶段开始时,若你的手牌数少于体力值,你须选择一名攻击范围内的角色,将其一张牌置于你的武将牌上,称为「焚」。锁定技,你的攻击范围+X(X为「焚」的数量)。', - zhiri:'炙日', - zhiri_info:'觉醒技,准备阶段开始时,若你的「焚」的数量不小于3,你减1点体力上限,然后获得技能〖心惔〗。', - meibu:'魅步', - meibu_info:'其他角色的出牌阶段开始时,若你不在其攻击范围内,你可以令该角色的锦囊牌均视为【杀】,直到该角色以此法使用了一张【杀】或回合结束。若如此做,则直到回合结束,视为你在其攻击范围内。', - mumu:'穆穆', - mumu_info:'出牌阶段限一次,你可以弃置一张【杀】或黑色锦囊牌,然后选择一项:弃置场上的一张武器牌,然后摸一张牌;或将场上的一张防具牌移动到你的装备区里(可替换原防具)。', - zhanyi:'战意', - zhanyi_basic_sha:'战杀', - zhanyi_basic_jiu:'战酒', - zhanyi_basic_tao:'战桃', - zhanyi_info:'出牌阶段限一次,你可以弃置一张牌并失去1点体力,然后根据你弃置的牌获得以下效果直到回合结束:基本牌,你可以将一张基本牌当作【杀】、【酒】或【桃】使用;锦囊牌,摸两张牌且你使用的牌无距离限制;装备牌,你使用【杀】指定目标角色后,其弃置两张牌。', - nuzhan:'怒斩', - nuzhan2:'怒斩', - nuzhan_info:'锁定技,你使用的由一张锦囊牌转化的【杀】不计入出牌阶段的次数限制;锁定技,你使用的由一张装备牌转化的【杀】的伤害值基数+1。', - danji:'单骑', - danji_info:'觉醒技,准备阶段开始时,若你的手牌数大于你的体力值且本局游戏的主公不为刘备,你减1点体力上限,然后获得〖马术〗和〖怒斩〗。', - jieyuan:'竭缘', - jieyuan_more:'竭缘', - jieyuan_less:'竭缘', - jieyuan_info:'当你对一名其他角色造成伤害时,若其体力值大于或等于你的体力值,你可弃置一张黑色手牌,令此伤害+1;当你受到一名其他角色造成的伤害时,若其体力值大于或等于你的体力值,你可弃置一张红色手牌,令此伤害-1。', - fenxin:'焚心', - fenxin_info:'锁定技,一名其他角色死亡后,若其身份为:忠臣,你本局内发动〖竭缘〗减少伤害时无视体力值限制;反贼,你本局内发动〖竭缘〗增加伤害时无视体力值限制;内奸,你本局内选择发动〖竭缘〗的牌时无颜色和区域限制。', - fenxin_info_versus:'锁定技,一名其他角色首次受到伤害后,你选择本局游戏未选择过的一项:1.发动〖竭缘〗减少伤害时无视体力值限制;2.发动〖竭缘〗增加伤害时无视体力值限制;3.发动〖竭缘〗选择的牌时无颜色和区域限制。', - qingyi:'轻逸', - qingyi1:'轻逸', - qingyi2:'轻逸', - qingyi_info:'你可以跳过判定阶段和摸牌阶段。若如此做,视为对一名角色使用了一张无距离限制的【杀】。', - xiandeng:'先登', - xiandeng_info:'锁定技,出牌阶段,你使用的第一张【杀】不计入次数且无距离限制。', - shulv:'熟虑', - shulv_info:'出牌阶段限一次,若你的手牌数大于体力值,则你可以弃置一张牌并摸一张牌。', - xisheng:'牺牲', - xisheng_info:'每名其他角色的回合限一次,你可以将两张牌当做【桃】使用。', - yuhua:'羽化', - yuhua_info:'锁定技。①你的非基本牌不计入手牌上限。②准备阶段和结束阶段开始时,你卜算1。', - qirang:'祈禳', - qirang_info:'当有装备牌进入你的装备区时,你可获得牌堆中的一张锦囊牌。若此牌为:普通锦囊牌,则当你使用此“祈禳”牌选择唯一目标后,可为此牌增加一个目标;延时锦囊牌,则你下回合发动〖羽化〗时的卜算量+1(至多为5)。', - biluan:'避乱', - biluan_info:'摸牌阶段开始时,若有与你距离不大于1的其他角色,你可以放弃摸牌。若如此做,本局内其他角色计算与你的距离时+X。(X为势力数)', - lixia:'礼下', - lixia_info:'锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你摸一张牌或令其摸一张牌。本局内其他角色计算与你的距离时-1。', - olbiluan: '避乱', - olbiluan_info: '结束阶段开始时,若有与你距离不大于1的其他角色,你可以弃置一张牌。若如此做,本局内其他角色计算与你的距离时+X。(X为场上的势力数)', - relixia:'礼下', - relixia_info:'锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你选择一至两项:1.摸一张牌;2.其摸两张牌;3.其回复1点体力。本局内其他角色计算与你的距离时-X(X为你选择的选项数)。', - rebiluan:'避乱', - rebiluan2:'避乱', - rebiluan_info:'结束阶段开始时,若有与你距离不大于1的其他角色,你可以弃置一张牌。若如此做,本局内其他角色计算与你的距离时+X。(X为场上角色数且至多为4)', - ollixia: '礼下', - ollixia_info: '锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你摸一张牌或令其摸两张牌。本局内其他角色计算与你的距离时-1。', - yishe:'义舍', - yishe_bg:'米', - yishe_info:'结束阶段开始时,若你的武将牌上没有「米」,则你可以摸两张牌。若如此做,你将两张牌置于武将牌上,称为「米」;当有「米」移至其他区域后,若你的武将牌上没有「米」,则你回复1点体力。', - bushi:'布施', - midao:'米道', - bushi_info:'当你受到1点伤害后,或其他角色受到你造成的1点伤害后,受到伤害的角色可以获得你的一张「米」。', - midao_info:'一名角色的判定牌生效前,你可以打出一张「米」代替之。', - fengpo:'凤魄', - fengpo_info:'每种牌名各限一次。当你每回合使用的第一张【杀】或【决斗】指定目标后,若目标角色数为1,你可以选择一项:1.摸X张牌,令此牌的伤害值基数+1;2.摸一张牌,令此牌的伤害值基数+X(X为其♦牌的数量)。', - chenqing:'陈情', - chenqing_info:'每轮限一次,当一名角色处于濒死状态时,你可以令另一名其他角色摸四张牌,然后其弃置四张牌。若其以此法弃置的四张牌花色各不相同,则视为该角色对濒死的角色使用一张【桃】。', - mozhi:'默识', - mozhi_info:'结束阶段开始时,你可以将一张手牌当作你本回合出牌阶段内使用的第一张基本或普通锦囊牌使用。然后,你可以将一张手牌当做你本回合出牌阶段内使用的第二张基本或普通锦囊牌使用。(你不能通过此技能使用【酒】)', - ranshang:'燃殇', - ranshang2:'燃殇', - ranshang_info:'锁定技,当你受到1点火焰伤害后,你获得1枚“燃”标记;结束阶段开始时,你失去X点体力。若X大于2,则你减2点体力上限并摸两张牌。(X为“燃”标记的数量)', - hanyong:'悍勇', - hanyong_info:'当你使用【南蛮入侵】或【万箭齐发】或黑桃普通【杀】时,若你已受伤,则你可以令此牌的伤害值基数+1。然后若你的体力值不小于游戏轮数,则你获得一枚“燃”标记。', + zfengshi: "锋矢", + zfengshi_info: "当你使用【杀】指定目标后,你可以令目标弃置装备区内的一张牌。", + chuanxin: "穿心", + chuanxin_info: + "当你于出牌阶段内使用【杀】或【决斗】对目标角色造成伤害时,你可以防止此伤害。若如此做,该角色选择一项:1.弃置装备区里的所有牌,若如此做,其失去1点体力;2.随机移除主武将牌上的一个技能。", + chuanxin_info_guozhan: + "当你于出牌阶段内使用【杀】或【决斗】对目标角色造成伤害时,若其与你势力不同且有副将,你可以防止此伤害。若如此做,该角色选择一项:1.弃置装备区里的所有牌,若如此做,其失去1点体力;2.移除副将。", + hengjiang: "横江", + hengjiang2: "横江", + hengjiang_info: + "当你受到1点伤害后,你可以令当前回合角色本回合的手牌上限-1。然后若其弃牌阶段内没有弃牌,则你摸一张牌。", + rehengjiang: "横江", + rehengjiang2: "横江", + rehengjiang3: "横江", + rehengjiang_info: + "当你受到1点伤害后,你可以令当前回合角色本回合的手牌上限-1。然后若其弃牌阶段内有/没有弃牌,则你摸一/X张牌(X为你本回合内对其发动过〖横江〗的次数)。", + shuangren: "双刃", + shuangren_info: + "出牌阶段开始时,你可以与一名角色拼点。若你赢,你视为对其或与其势力相同的另一名角色使用一张【杀】(不计入出牌阶段的次数限制);若你没赢,你本回合内不能对其他角色使用牌。", + xiashu: "下书", + xiashu_info: + "出牌阶段开始时,你可以将所有手牌交给一名其他角色,然后该角色亮出任意数量的手牌(至少一张)。你选择一项:1.获得其亮出的手牌;2.获得其未亮出的手牌。", + kuanshi: "宽释", + kuanshi2: "宽释", + kuanshi_info: + "结束阶段,你可以选择一名角色。直到你的下回合开始,该角色第一次受到大于1的伤害时,防止此伤害,然后你跳过下个回合的摸牌阶段。", + bingzheng: "秉正", + bingzheng_info: + "出牌阶段结束时,你可以令手牌数不等于体力值的一名角色弃置一张手牌或摸一张牌。然后若其手牌数等于体力值,你摸一张牌,且可以交给该角色一张牌。", + sheyan: "舍宴", + sheyan_info: + "当你成为普通锦囊牌的目标时(【借刀杀人】等带有指向目标的锦囊除外),你可以为此牌增加一个目标或令其对其中一个目标无效。(有效目标数至少为一)", + fuman: "抚蛮", + fuman2: "抚蛮", + fuman_info: + "出牌阶段每名角色限一次,你可以将一张手牌交给一名其他角色并标记为“抚蛮”且“抚蛮”牌的牌名视为【杀】。然后当一名角色使用“抚蛮”牌结算结束后,你摸一张牌。若此牌造成过伤害,则改为摸两张牌。", + qizhou: "绮胄", + qizhou_info: + "锁定技,你根据装备区里牌的花色数获得以下技能:1种或以上:〖马术〗;2种或以上:〖英姿〗;3种或以上:〖短兵〗;4种:〖奋威〗。", + shanxi: "闪袭", + shanxi_info: + "出牌阶段限一次,你可以弃置一张红色基本牌,然后弃置攻击范围内的一名其他角色的一张牌。若弃置的牌是【闪】,你观看其手牌,若弃置的不是【闪】,其观看你的手牌。", + duanbing: "短兵", + duanbing_info: "当你使用【杀】选择目标后,你可以令一名距离为1的其他角色也成为此牌的目标。", + fanghun: "芳魂", + fanghun_info: + "当你使用【杀】造成伤害或受到【杀】的伤害后,你获得X个“梅影”标记(X为伤害点数);你可以移去1个“梅影”标记来发动〖龙胆〗并摸一张牌。", + refanghun: "芳魂", + refanghun_info: + "当你使用【杀】或成为【杀】的目标后,你获得1个“梅影”标记;你可以移去1个“梅影”标记来发动〖龙胆〗并摸一张牌。", + fanghun_sha: "龙胆", + fuhan: "扶汉", + fuhan_info: + "限定技,回合开始时,你可以移去所有“梅影”标记并摸等量的牌,随机观看五名未登场的蜀势力角色,将武将牌替换为其中一名角色,并将体力上限数调整为本局游戏中移去“梅影”标记的数量(至少为2,至多为8),然后回复1点体力。", + refuhan: "扶汉", + refuhan_info: + '限定技,回合开始时,你可以移去所有"梅影"标记并摸等量的牌,然后从X张蜀势力武将牌中选择并获得至多两个技能(限定技、觉醒技、隐匿技、使命技、主公技除外)。若此时你是体力值最低的角色,你回复1点体力(X为场上角色数,且X∈[4,+∞))。', + yjixi: "觊玺", + yjixi_info: + "觉醒技,结束阶段,若你已连续三个自己回合未失去过体力,则你增加1点体力上限并回复1点体力,然后选择一项:获得技能〖妄尊〗;摸两张牌并获得当前主公的主公技。", + xinyongsi: "庸肆", + xinyongsi1: "庸肆", + xinyongsi2: "庸肆", + xinyongsi_info: + "锁定技,摸牌阶段,你令额定摸牌数改为X(X为势力数);弃牌阶段开始时,你选择一项:1.弃置一张牌;2.失去1点体力。", + xiehui: "黠慧", + xiehui2: "黠慧", + xiehui_info: + "锁定技,你的黑色牌不计入手牌上限;其他角色获得你的黑色牌时,其不能使用、打出、弃置这些牌直到其体力值扣减为止。", + lianzhu: "连诛", + lianzhu_info: + "出牌阶段限一次,你可以展示并交给一名其他角色一张牌,若此牌为黑色,其选择一项:1.你摸两张牌;2.弃置两张牌。", + shanjia: "缮甲", + shanjia_info: + "出牌阶段开始时,你可以摸X张牌,然后弃置等量的牌。若你以此法弃置了装备区内的牌,则你可以视为使用一张【杀】。(X为你于本局游戏内使用过的装备牌数且最大为7)", + tuifeng: "推锋", + tuifeng2: "推锋", + tuifeng_info: + "1.当你受到伤害后,你可以将至多X张牌置于武将牌上(X为伤害值),称为“锋”。2.准备阶段开始时,若你的武将牌上有“锋”,你移去所有“锋”,摸2X张牌,然后你于此回合的出牌阶段内使用【杀】的次数上限+X。(X为你此次移去的“锋”数)", + ziyuan: "资援", + ziyuan_info: + "出牌阶段限一次,你可以将任意张点数之和为13的手牌交给一名其他角色,然后该角色回复1点体力。", + jugu: "巨贾", + jugu_info: "锁定技,1.你的手牌上限+X。2.游戏开始时,你摸X张牌(X为你的体力上限)。", + hongde: "弘德", + hongde_info: "当你一次获得或失去至少两张牌后,你可以令一名其他角色摸一张牌。", + dingpan: "定叛", + dingpan_info_identity: + "出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的反贼数)", + dingpan_info_doudizhu: + "出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的农民数)", + dingpan_info_versus_two: + "出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的最大阵营角色数)", + dingpan_info_versus: + "出牌阶段限X次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。(X为场上存活的敌方角色数)", + dingpan_info: + "出牌阶段限一次,你可以令一名装备区里有牌的角色摸一张牌,然后其选择一项:1.令你弃置其装备区里的一张牌;2.获得其装备区里的所有牌,若如此做,你对其造成1点伤害。", + weidi: "伪帝", + weidi_info: "锁定技,你视为拥有当前主公的主公技。", + juesi: "决死", + juesi_info: + "出牌阶段,你可以弃置一张【杀】并选择攻击范围内的一名有牌的其他角色,该角色弃置一张牌,然后若弃置的牌不是【杀】且你的体力值不大于该角色,你视为对其使用【决斗】。", + zhenlue: "缜略", + zhenlue_info: "锁定技,你使用的普通锦囊牌不能被【无懈可击】响应;你不能成为延时锦囊牌的目标。", + jianshu: "间书", + jianshu_info: + "限定技,出牌阶段,你可以将一张黑色手牌交给一名其他角色,并选择另一名其他角色,然后令这两名角色拼点。赢的角色弃置两张牌,没赢的角色失去1点体力。", + yongdi: "拥嫡", + yongdi_info: + "限定技,准备阶段开始时,你可令一名其他男性角色增加1点体力上限并回复1点体力,然后若该角色的武将牌上有主公技且其不为主公,其获得此主公技。", + regushe: "鼓舌", + regushe_info: + "出牌阶段,若X小于7,则你可以用一张手牌与至多三名角色同时拼点,然后依次结算拼点结果,没赢的角色选择一项:1.弃置一张牌;2.令你摸一张牌。若你没赢,你获得一个“饶舌”标记。当你获得第7个“饶舌”标记时,你死亡。(X为你的“饶舌”标记数与本回合因“鼓舌”拼点而胜利的次数之和)", + rejici: "激词", + rejici2: "激词", + rejici_info: + "锁定技。①当你的拼点牌亮出后,若此牌的点数不大于X,则你令此牌点数+X,并获得此次拼点中点数最大的拼点牌。②当你死亡时,你令杀死你的角色弃置7-X张牌并失去1点体力(X为你的“饶舌”标记数)。", + gushe: "鼓舌", + gushe_bg: "舌", + gushe_info: + "出牌阶段限一次,你可以用一张手牌与至多三名角色同时拼点,然后依次结算拼点结果,没赢的角色选择一项:1.弃置一张牌;2.令你摸一张牌。若你没赢,你获得一个“饶舌”标记。当你获得第7个“饶舌”标记时,你死亡。", + jici: "激词", + jici_info: + "当你因发动〖鼓舌〗而扣置的拼点牌亮出后,若点数小于X,你可令点数+X;若点数等于X,你可令你本回合发动〖鼓舌〗的次数上限+1。(X为你“饶舌”标记的数量)", + shefu: "设伏", + shefu2: "设伏", + shefu_bg: "伏", + shefu_info: + "结束阶段开始时,你可以将一张牌移出游戏,称为「伏兵」。并为「伏兵」记录一个基本牌或锦囊牌的名称(须与其他「伏兵」记录的名称均不同)。你的回合外,当有其他角色使用与你记录的「伏兵」牌名相同的手牌时,你可以取消此牌的所有目标,然后移去该「伏兵」。若此时处于使用者的回合内,则你令使用者当前的所有非Charlotte技失效直至回合结束。", + benyu: "贲育", + benyu2: "贲育", + benyu_info: + "当你受到伤害后,你可选择:①将手牌摸至与伤害来源手牌数相同(至多摸至5张);②弃置大于伤害来源手牌数的牌,然后对其造成1点伤害。", + zhidao: "雉盗", + zhidao_info: + "锁定技,当你于你的回合内第一次对区域里有牌的其他角色造成伤害后,你获得其手牌、装备区和判定区里的各一张牌,然后直到回合结束,其他角色不能被选择为你使用牌的目标。", + jili: "寄篱", + jili_info: + "锁定技,当一名其他角色成为红色基本牌或红色普通锦囊牌的目标时,若其与你的距离为1且你既不是此牌的使用者也不是目标,你也成为此牌的目标。", + luanzhan: "乱战", + luanzhan_info: + "你使用【杀】或黑色普通锦囊牌可以额外选择X名角色为目标;当你使用【杀】或黑色普通锦囊牌指定目标后,若此牌的目标角色数小于X,则X减至0。(X为你于本局游戏内造成过伤害的次数)", + zhengnan: "征南", + zhengnan_info: + "其他角色死亡后,你可以摸三张牌并获得下列技能中的任意一个:〖武圣〗、〖当先〗和〖制蛮〗。", + xinzhengnan: "征南", + xinzhengnan_info: + "当一名角色进入濒死状态时,若你未因其发动过〖征南〗,则你回复1点体力并摸一张牌并获得下列技能中的任意一个:〖武圣〗、〖当先〗和〖制蛮〗(若技能全部拥有则改为摸三张牌。你以此法获得的〖当先〗结算时视为已发动过〖伏枥〗)。", + xiefang: "撷芳", + xiefang_info: "锁定技,你计算与其他角色的距离时-X。(X为女性角色数)", + qizhi: "奇制", + qizhi_info: + "当你于回合内使用基本牌或锦囊牌指定目标后,你可以弃置不是此牌目标的一名角色的一张牌。若如此做,其摸一张牌。", + jinqu: "进趋", + jinqu_info: + "结束阶段开始时,你可以摸两张牌,若如此做,你将手牌弃置至X张。(X为你于此回合发动过〖奇制〗的次数)", + jiqiao: "机巧", + jiqiao_info: + "出牌阶段开始时,你可以弃置任意张装备牌,然后亮出牌堆顶两倍数量的牌并获得其中的非装备牌。", + linglong: "玲珑", + linglong_info: + "锁定技,若你的装备区没有武器牌,则你使用【杀】的次数上限+1;若你的装备区没有防具牌,视为你装备着【八卦阵】;若你的装备区没有坐骑牌,你的手牌上限+1;若你的装备区没有宝物牌,则你视为拥有技能〖奇才〗。", + zhenwei: "镇卫", + zhenwei2: "镇卫", + zhenwei_info: + "当一名其他角色成为【杀】或黑色锦囊牌的目标时(使用者不是你),若该角色的体力值小于你且此牌的目标角色数为1,你可以弃置一张牌。若如此做,你选择一项:1、摸一张牌,然后将此【杀】或黑色锦囊牌转移给你;2、令此【杀】或黑色锦囊牌无效,然后将此【杀】或黑色锦囊牌置于使用者的武将牌旁,若如此做,当前回合结束后,使用者获得使用者武将牌旁的这些牌。", + xingwu: "星舞", + xingwu_info: + "弃牌阶段开始时,你可以将一张与你本回合使用的牌颜色均不同的手牌置于武将牌上:若你有至少三张“星舞”牌,你移去“星舞”牌并选择一名男性角色,该角色受到2点伤害并弃置其装备区的所有牌。", + luoyan: "落雁", + luoyan_info: "锁定技。若你的武将牌上有“星舞牌”,你拥有“天香”和“流离”。", + yinbing: "引兵", + yinbing_info: + "结束阶段开始时,你可以将至少一张非基本牌置于武将牌上。每当你受到【杀】或【决斗】的伤害后,你移去一张「引兵」牌。", + juedi: "绝地", + juedi_info: + "锁定技,准备阶段,若你的武将牌上有「引兵」牌,你选择一项:1.移去「引兵」牌,将手牌补至体力上限数;2.将「引兵」牌交给一名体力值不大于你的其他角色,其回复1点体力并摸等量的牌。", + kuangfu: "狂斧", + kuangfu_info: + "当你使用【杀】造成伤害后,你可以选择一项:弃置其装备区内的一张牌,或将其装备区内的一张牌移动到你的装备区内。", + xintan: "心惔", + xintan_info: "出牌阶段限一次,你可以移去两张「焚」并选择一名角色,该角色失去1点体力。", + fentian: "焚天", + fentian_info: + "锁定技,结束阶段开始时,若你的手牌数少于体力值,你须选择一名攻击范围内的角色,将其一张牌置于你的武将牌上,称为「焚」。锁定技,你的攻击范围+X(X为「焚」的数量)。", + zhiri: "炙日", + zhiri_info: + "觉醒技,准备阶段开始时,若你的「焚」的数量不小于3,你减1点体力上限,然后获得技能〖心惔〗。", + meibu: "魅步", + meibu_info: + "其他角色的出牌阶段开始时,若你不在其攻击范围内,你可以令该角色的锦囊牌均视为【杀】,直到该角色以此法使用了一张【杀】或回合结束。若如此做,则直到回合结束,视为你在其攻击范围内。", + mumu: "穆穆", + mumu_info: + "出牌阶段限一次,你可以弃置一张【杀】或黑色锦囊牌,然后选择一项:弃置场上的一张武器牌,然后摸一张牌;或将场上的一张防具牌移动到你的装备区里(可替换原防具)。", + zhanyi: "战意", + zhanyi_basic_sha: "战杀", + zhanyi_basic_jiu: "战酒", + zhanyi_basic_tao: "战桃", + zhanyi_info: + "出牌阶段限一次,你可以弃置一张牌并失去1点体力,然后根据你弃置的牌获得以下效果直到回合结束:基本牌,你可以将一张基本牌当作【杀】、【酒】或【桃】使用;锦囊牌,摸两张牌且你使用的牌无距离限制;装备牌,你使用【杀】指定目标角色后,其弃置两张牌。", + nuzhan: "怒斩", + nuzhan2: "怒斩", + nuzhan_info: + "锁定技,你使用的由一张锦囊牌转化的【杀】不计入出牌阶段的次数限制;锁定技,你使用的由一张装备牌转化的【杀】的伤害值基数+1。", + danji: "单骑", + danji_info: + "觉醒技,准备阶段开始时,若你的手牌数大于你的体力值且本局游戏的主公不为刘备,你减1点体力上限,然后获得〖马术〗和〖怒斩〗。", + jieyuan: "竭缘", + jieyuan_more: "竭缘", + jieyuan_less: "竭缘", + jieyuan_info: + "当你对一名其他角色造成伤害时,若其体力值大于或等于你的体力值,你可弃置一张黑色手牌,令此伤害+1;当你受到一名其他角色造成的伤害时,若其体力值大于或等于你的体力值,你可弃置一张红色手牌,令此伤害-1。", + fenxin: "焚心", + fenxin_info: + "锁定技,一名其他角色死亡后,若其身份为:忠臣,你本局内发动〖竭缘〗减少伤害时无视体力值限制;反贼,你本局内发动〖竭缘〗增加伤害时无视体力值限制;内奸,你本局内选择发动〖竭缘〗的牌时无颜色和区域限制。", + fenxin_info_versus: + "锁定技,一名其他角色首次受到伤害后,你选择本局游戏未选择过的一项:1.发动〖竭缘〗减少伤害时无视体力值限制;2.发动〖竭缘〗增加伤害时无视体力值限制;3.发动〖竭缘〗选择的牌时无颜色和区域限制。", + qingyi: "轻逸", + qingyi1: "轻逸", + qingyi2: "轻逸", + qingyi_info: + "你可以跳过判定阶段和摸牌阶段。若如此做,视为对一名角色使用了一张无距离限制的【杀】。", + xiandeng: "先登", + xiandeng_info: "锁定技,出牌阶段,你使用的第一张【杀】不计入次数且无距离限制。", + shulv: "熟虑", + shulv_info: "出牌阶段限一次,若你的手牌数大于体力值,则你可以弃置一张牌并摸一张牌。", + xisheng: "牺牲", + xisheng_info: "每名其他角色的回合限一次,你可以将两张牌当做【桃】使用。", + yuhua: "羽化", + yuhua_info: "锁定技。①你的非基本牌不计入手牌上限。②准备阶段和结束阶段开始时,你卜算1。", + qirang: "祈禳", + qirang_info: + "当有装备牌进入你的装备区时,你可获得牌堆中的一张锦囊牌。若此牌为:普通锦囊牌,则当你使用此“祈禳”牌选择唯一目标后,可为此牌增加一个目标;延时锦囊牌,则你下回合发动〖羽化〗时的卜算量+1(至多为5)。", + biluan: "避乱", + biluan_info: + "摸牌阶段开始时,若有与你距离不大于1的其他角色,你可以放弃摸牌。若如此做,本局内其他角色计算与你的距离时+X。(X为势力数)", + lixia: "礼下", + lixia_info: + "锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你摸一张牌或令其摸一张牌。本局内其他角色计算与你的距离时-1。", + olbiluan: "避乱", + olbiluan_info: + "结束阶段开始时,若有与你距离不大于1的其他角色,你可以弃置一张牌。若如此做,本局内其他角色计算与你的距离时+X。(X为场上的势力数)", + relixia: "礼下", + relixia_info: + "锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你选择一至两项:1.摸一张牌;2.其摸两张牌;3.其回复1点体力。本局内其他角色计算与你的距离时-X(X为你选择的选项数)。", + rebiluan: "避乱", + rebiluan2: "避乱", + rebiluan_info: + "结束阶段开始时,若有与你距离不大于1的其他角色,你可以弃置一张牌。若如此做,本局内其他角色计算与你的距离时+X。(X为场上角色数且至多为4)", + ollixia: "礼下", + ollixia_info: + "锁定技,其他角色的结束阶段开始时,若你不在其攻击范围内,你摸一张牌或令其摸两张牌。本局内其他角色计算与你的距离时-1。", + yishe: "义舍", + yishe_bg: "米", + yishe_info: + "结束阶段开始时,若你的武将牌上没有「米」,则你可以摸两张牌。若如此做,你将两张牌置于武将牌上,称为「米」;当有「米」移至其他区域后,若你的武将牌上没有「米」,则你回复1点体力。", + bushi: "布施", + midao: "米道", + bushi_info: + "当你受到1点伤害后,或其他角色受到你造成的1点伤害后,受到伤害的角色可以获得你的一张「米」。", + midao_info: "一名角色的判定牌生效前,你可以打出一张「米」代替之。", + fengpo: "凤魄", + fengpo_info: + "每种牌名各限一次。当你每回合使用的第一张【杀】或【决斗】指定目标后,若目标角色数为1,你可以选择一项:1.摸X张牌,令此牌的伤害值基数+1;2.摸一张牌,令此牌的伤害值基数+X(X为其♦牌的数量)。", + chenqing: "陈情", + chenqing_info: + "每轮限一次,当一名角色处于濒死状态时,你可以令另一名其他角色摸四张牌,然后其弃置四张牌。若其以此法弃置的四张牌花色各不相同,则视为该角色对濒死的角色使用一张【桃】。", + mozhi: "默识", + mozhi_info: + "结束阶段开始时,你可以将一张手牌当作你本回合出牌阶段内使用的第一张基本或普通锦囊牌使用。然后,你可以将一张手牌当做你本回合出牌阶段内使用的第二张基本或普通锦囊牌使用。(你不能通过此技能使用【酒】)", + ranshang: "燃殇", + ranshang2: "燃殇", + ranshang_info: + "锁定技,当你受到1点火焰伤害后,你获得1枚“燃”标记;结束阶段开始时,你失去X点体力。若X大于2,则你减2点体力上限并摸两张牌。(X为“燃”标记的数量)", + hanyong: "悍勇", + hanyong_info: + "当你使用【南蛮入侵】或【万箭齐发】或黑桃普通【杀】时,若你已受伤,则你可以令此牌的伤害值基数+1。然后若你的体力值不小于游戏轮数,则你获得一枚“燃”标记。", - yicong:'义从', - yongsi:'庸肆', - yongsi1:'庸肆', - yongsi2:'庸肆', - bifa:'笔伐', - bifa2:'笔伐', - songci:'颂词', - songci_draw:'颂词', - baobian:'豹变', - lihun:'离魂', - chongzhen:'冲阵', - yuanhu:'援护', - tianming:'天命', - mizhao:'密诏', - duwu:'黩武', - duwu3:'黩武', - mingzhe:'明哲', - huanshi:'缓释', - hongyuan:'弘援', - aocai:'傲才', - aocai2:'傲才', - aocai2_backup:'傲才', - aocai3:'傲才', - huxiao:'虎啸', - huxiao3:'虎啸', - xueji:'雪恨', - wuji:'武继', - shushen:'淑慎', - shenzhi:'神智', - xiongyi:'雄异', - junbing:'郡兵', - junbing2:'郡兵', - quji:'去疾', - sijian:'死谏', - suishi:'随势', - suishi2:'随势', - xiaoguo:'骁果', - duanxie:'断绁', - fenming:'奋命', - guixiu:'闺秀', - cunsi:'存嗣', - yongjue:'勇决', - hengzheng:'横征', - shengxi:'生息', - shoucheng:'守成', - shangyi:'尚义', - zniaoxiang:'鸟翔', - zhendu:'鸩毒', - qiluan:'戚乱', - qiluan2:'戚乱', - qiluan3:'戚乱', - shenxian:'甚贤', - oldshenxian:'甚贤', - qiangwu:'枪舞', - moukui:'谋溃', - moukui2:'谋溃', - lirang:'礼让', - mingshi:'名士', - liangzhu:'良助', - kaikang:'慷忾', - wangzun:'妄尊', - tongji:'同疾', - kuiwei:'溃围', - kuiwei2:'溃围', - yanzheng:'严整', - zhoufu:'咒缚', - zhoufu2:'咒缚', - zhoufu3:'咒缚', - yingbin:'影兵', - reyingbing:'影兵', - rezhoufu:'咒缚', - rezhoufu2:'咒缚', - fenxun:'奋迅', - fenxun2:'奋迅', - spmengjin:'猛进', - xiemu:'协穆', - xiemu2:'协穆', - oldxiemu:'协穆', - naman:'纳蛮', - taichen:'抬榇', - jilei:'鸡肋', - jilei2:'鸡肋', - jilei2_bg:'肋', - yawang:'雅望', - xunzhi:'殉志', - fanxiang:'返乡', - fanxiang_info:'觉醒技,准备阶段开始时,若场上有已受伤且你发动过〖良助〗的选项二的角色,则你加1点体力上限并回复1点体力,失去技能〖良助〗并获得技能〖枭姬〗。', - xunzhi_info:'准备阶段开始时,若你的上家和下家与你的体力值均不相等,你可以失去1点体力。若如此做,你本局内手牌上限+2。', - yawang_info:'锁定技,摸牌阶段开始时,你改为摸X张牌,然后你于本回合的出牌阶段内至多使用X张牌(X为与你体力值相等的角色数)。', - jilei_info:'当你受到有来源的伤害后,你可以声明一种牌的类别。若如此做,你令伤害来源不能使用、打出或弃置此类别的手牌直到其下个回合开始。', - danlao:'啖酪', - danlao_info:'当你成为【杀】或普通锦囊牌的目标后,若此牌的目标数大于1,则你可以摸一张牌,令此牌对你无效。', - gongao:'功獒', - zhuiji:'追击', - chouhai:'仇海', - chouhai_info:'锁定技,当你受到伤害时,若你没有手牌,此伤害+1。', - rechouhai:'仇海', - rechouhai_info:'锁定技,当你受到渠道为【杀】的伤害时,若你没有手牌,此伤害+1。', - guiming:'归命', - guiming_info:'主公技,锁定技,你将残蚀描述中的“已受伤角色”改为“已受伤角色或其他吴势力角色”。', - canshi:'残蚀', - canshi2:'残蚀', - canshi_info:'摸牌阶段开始时,你可以改为摸X张牌(X为已受伤的角色数),若如此做,当你于此回合内使用基本牌或锦囊牌时,你弃置一张牌。', - recanshi:'残蚀', - recanshi2:'残蚀', - recanshi_info:'摸牌阶段开始时,你可以多摸X张牌(X为已受伤的角色数),若如此做,当你于此回合内使用【杀】或普通锦囊牌时,你弃置一张牌。', - zhuiji_info:'锁定技,你与体力值不大于你的角色的距离视为1。', - kunfen:'困奋', - kunfen_info:'锁定技,结束阶段开始时,你失去1点体力,然后摸两张牌。', - fengliang:'逢亮', - fengliang_info:'觉醒技,当你进入濒死状态时,你减1点体力上限,将体力值回复至2点,获得技能〖挑衅〗并将〖困奋〗改为非锁定技。', - oldcihuai:'刺槐', - oldcihuai2:'刺槐', - oldcihuai_info:'出牌阶段开始时,你可以展示手牌。若其中没有【杀】,则当你于此阶段内手牌数变化之前/有角色死亡之前需要使用【杀】时,你可以使用无对应实体牌的【杀】。', - cihuai:'刺槐', - cihuai_info:'出牌阶段开始时,若你的手牌中没有【杀】,则你可以展示你的手牌,视为对一名角色使用一张【杀】。', - gongao_info:'锁定技,当一名角色死亡后,你增加1点体力上限,回复1点体力。', - juyi:'举义', - juyi_info:'觉醒技,准备阶段开始时,若你的体力上限大于存活角色数,你摸等同于体力上限张数的牌,然后获得技能〖崩坏〗和〖威重〗。', - weizhong:'威重', - weizhong_info:'锁定技,当你的体力上限增加或减少时,你摸一张牌。若你的手牌数为全场最少,则你改为摸两张牌。', - taichen_info:'出牌阶段限一次,你可以失去1点体力,视为对一名角色使用一张【杀】。(不计入出牌阶段的使用次数限制)', - naman_info:'当其他角色打出的【杀】结算结束后,你可以获得此牌对应的所有实体牌。', - xiemu_info:'出牌阶段限一次,你可以弃置一张【杀】并选择一个势力。若如此做,直到你的下回合开始时,当你成为该势力的其他角色使用的黑色牌的目标后,你摸两张牌。', - oldxiemu_info:'当你成为其他角色使用的黑色牌的目标后,你可以弃置一张【杀】,然后摸两张牌。', - spmengjin_info:'当你使用【杀】指定目标后,你可以弃置目标角色的一张牌。', - fenxun_info:'出牌阶段限一次,你可以弃置一张牌并选择一名其他角色,你于本回合内至其的距离视为1。', - rezhoufu_info:'①出牌阶段限一次。你可以用一张牌对一名其他角色施“咒”,且当其判定时,将“咒”作为判定牌。②一名角色的回合结束时,你令本回合移除过“咒”的角色各失去1点体力。', - reyingbing_info:'锁定技,有“咒”的角色使用与“咒”颜色相同的牌时,你摸一张牌;若这是你第二次因该“咒”摸牌,则你获得该"咒"。', - yingbin_info:'锁定技,有“咒”的角色使用与“咒”花色相同的牌时,你摸一张牌;当你因同一名角色的同一张“咒”的效果摸第二张牌时,移去该“咒”。', - zhoufu_info:'出牌阶段限一次,你可以将一张手牌置于一名没有“咒”的其他角色的武将牌旁,称为“咒”。当有“咒”的角色判定时,其改为将“咒”作为判定牌;一名角色的回合结束时,若有角色于此回合因判定而移除过“咒”,则你令这些角色各失去1点体力。', - yanzheng_info:'若你的手牌数大于你的体力值,则你可以将你装备区内的牌当做【无懈可击】使用。', - kuiwei_info:'结束阶段开始时,你可以摸2+X张牌并翻面。你的下个摸牌阶段开始时,你弃置X张牌(X为当前时机场上所有角色装备区内武器牌数之和)。', - tongji_info:'锁定技。若你的手牌数大于你的体力值,则攻击范围包含你的其他角色使用【杀】时不能指定你以外的角色为目标。', - wangzun_info:'其他角色的准备阶段开始时,你可以摸一张牌。若如此做,该角色此回合的手牌上限-1。然后你不能再发动〖妄尊〗直到回合开始。', - kaikang_info:'当一名角色成为【杀】的目标后,若你至该角色的距离为1,你可以摸一张牌。若如此做,你交给其一张牌并展示之。若为装备牌,该角色可以使用此牌。', - liangzhu_info:'当一名角色于其出牌阶段内回复体力时,你可以选择一项:1、摸一张牌;2、令该角色摸两张牌。', - mingshi_info:'当你受到伤害时,若伤害来源的体力值大于你,你可以弃置一张黑色手牌,令伤害值-1。', - lirang_info:'当你的牌因弃置而置入弃牌堆后,你可以将其中的任意张牌交给其他角色。', - moukui_info:'当你使用【杀】指定目标后,你可以选择一项:摸一张牌,或弃置其一张牌。若如此做,当此【杀】被【闪】抵消时,目标角色弃置你的一张牌。', - qiangwu_info:'出牌阶段,你可以进行判定。若如此做,直到回合结束,你使用点数小于判定结果的【杀】时不受距离限制,且你使用点数大于判定结果的【杀】时无使用次数限制。', - shenxian_info:'每名角色的回合限一次,你的回合外,当有其他角色因弃置而失去基本牌时,你可以摸一张牌。', - oldshenxian_info:'你的回合外,每当有其他角色因弃置而失去基本牌时,你可以摸一张牌。', - qiluan_info:'一名角色的回合结束时,你可以摸3X+Y张牌。(X为你本回合内杀死过的角色数,Y为本回合内其他角色杀死过的角色数)', + yicong: "义从", + yongsi: "庸肆", + yongsi1: "庸肆", + yongsi2: "庸肆", + bifa: "笔伐", + bifa2: "笔伐", + songci: "颂词", + songci_draw: "颂词", + baobian: "豹变", + lihun: "离魂", + chongzhen: "冲阵", + yuanhu: "援护", + tianming: "天命", + mizhao: "密诏", + duwu: "黩武", + duwu3: "黩武", + mingzhe: "明哲", + huanshi: "缓释", + hongyuan: "弘援", + aocai: "傲才", + aocai2: "傲才", + aocai2_backup: "傲才", + aocai3: "傲才", + huxiao: "虎啸", + huxiao3: "虎啸", + xueji: "雪恨", + wuji: "武继", + shushen: "淑慎", + shenzhi: "神智", + xiongyi: "雄异", + junbing: "郡兵", + junbing2: "郡兵", + quji: "去疾", + sijian: "死谏", + suishi: "随势", + suishi2: "随势", + xiaoguo: "骁果", + duanxie: "断绁", + fenming: "奋命", + guixiu: "闺秀", + cunsi: "存嗣", + yongjue: "勇决", + hengzheng: "横征", + shengxi: "生息", + shoucheng: "守成", + shangyi: "尚义", + zniaoxiang: "鸟翔", + zhendu: "鸩毒", + qiluan: "戚乱", + qiluan2: "戚乱", + qiluan3: "戚乱", + shenxian: "甚贤", + oldshenxian: "甚贤", + qiangwu: "枪舞", + moukui: "谋溃", + moukui2: "谋溃", + lirang: "礼让", + mingshi: "名士", + liangzhu: "良助", + kaikang: "慷忾", + wangzun: "妄尊", + tongji: "同疾", + kuiwei: "溃围", + kuiwei2: "溃围", + yanzheng: "严整", + zhoufu: "咒缚", + zhoufu2: "咒缚", + zhoufu3: "咒缚", + yingbin: "影兵", + reyingbing: "影兵", + rezhoufu: "咒缚", + rezhoufu2: "咒缚", + fenxun: "奋迅", + fenxun2: "奋迅", + spmengjin: "猛进", + xiemu: "协穆", + xiemu2: "协穆", + oldxiemu: "协穆", + naman: "纳蛮", + taichen: "抬榇", + jilei: "鸡肋", + jilei2: "鸡肋", + jilei2_bg: "肋", + yawang: "雅望", + xunzhi: "殉志", + fanxiang: "返乡", + fanxiang_info: + "觉醒技,准备阶段开始时,若场上有已受伤且你发动过〖良助〗的选项二的角色,则你加1点体力上限并回复1点体力,失去技能〖良助〗并获得技能〖枭姬〗。", + xunzhi_info: + "准备阶段开始时,若你的上家和下家与你的体力值均不相等,你可以失去1点体力。若如此做,你本局内手牌上限+2。", + yawang_info: + "锁定技,摸牌阶段开始时,你改为摸X张牌,然后你于本回合的出牌阶段内至多使用X张牌(X为与你体力值相等的角色数)。", + jilei_info: + "当你受到有来源的伤害后,你可以声明一种牌的类别。若如此做,你令伤害来源不能使用、打出或弃置此类别的手牌直到其下个回合开始。", + danlao: "啖酪", + danlao_info: + "当你成为【杀】或普通锦囊牌的目标后,若此牌的目标数大于1,则你可以摸一张牌,令此牌对你无效。", + gongao: "功獒", + zhuiji: "追击", + chouhai: "仇海", + chouhai_info: "锁定技,当你受到伤害时,若你没有手牌,此伤害+1。", + rechouhai: "仇海", + rechouhai_info: "锁定技,当你受到渠道为【杀】的伤害时,若你没有手牌,此伤害+1。", + guiming: "归命", + guiming_info: "主公技,锁定技,你将残蚀描述中的“已受伤角色”改为“已受伤角色或其他吴势力角色”。", + canshi: "残蚀", + canshi2: "残蚀", + canshi_info: + "摸牌阶段开始时,你可以改为摸X张牌(X为已受伤的角色数),若如此做,当你于此回合内使用基本牌或锦囊牌时,你弃置一张牌。", + recanshi: "残蚀", + recanshi2: "残蚀", + recanshi_info: + "摸牌阶段开始时,你可以多摸X张牌(X为已受伤的角色数),若如此做,当你于此回合内使用【杀】或普通锦囊牌时,你弃置一张牌。", + zhuiji_info: "锁定技,你与体力值不大于你的角色的距离视为1。", + kunfen: "困奋", + kunfen_info: "锁定技,结束阶段开始时,你失去1点体力,然后摸两张牌。", + fengliang: "逢亮", + fengliang_info: + "觉醒技,当你进入濒死状态时,你减1点体力上限,将体力值回复至2点,获得技能〖挑衅〗并将〖困奋〗改为非锁定技。", + oldcihuai: "刺槐", + oldcihuai2: "刺槐", + oldcihuai_info: + "出牌阶段开始时,你可以展示手牌。若其中没有【杀】,则当你于此阶段内手牌数变化之前/有角色死亡之前需要使用【杀】时,你可以使用无对应实体牌的【杀】。", + cihuai: "刺槐", + cihuai_info: + "出牌阶段开始时,若你的手牌中没有【杀】,则你可以展示你的手牌,视为对一名角色使用一张【杀】。", + gongao_info: "锁定技,当一名角色死亡后,你增加1点体力上限,回复1点体力。", + juyi: "举义", + juyi_info: + "觉醒技,准备阶段开始时,若你的体力上限大于存活角色数,你摸等同于体力上限张数的牌,然后获得技能〖崩坏〗和〖威重〗。", + weizhong: "威重", + weizhong_info: + "锁定技,当你的体力上限增加或减少时,你摸一张牌。若你的手牌数为全场最少,则你改为摸两张牌。", + taichen_info: + "出牌阶段限一次,你可以失去1点体力,视为对一名角色使用一张【杀】。(不计入出牌阶段的使用次数限制)", + naman_info: "当其他角色打出的【杀】结算结束后,你可以获得此牌对应的所有实体牌。", + xiemu_info: + "出牌阶段限一次,你可以弃置一张【杀】并选择一个势力。若如此做,直到你的下回合开始时,当你成为该势力的其他角色使用的黑色牌的目标后,你摸两张牌。", + oldxiemu_info: "当你成为其他角色使用的黑色牌的目标后,你可以弃置一张【杀】,然后摸两张牌。", + spmengjin_info: "当你使用【杀】指定目标后,你可以弃置目标角色的一张牌。", + fenxun_info: "出牌阶段限一次,你可以弃置一张牌并选择一名其他角色,你于本回合内至其的距离视为1。", + rezhoufu_info: + "①出牌阶段限一次。你可以用一张牌对一名其他角色施“咒”,且当其判定时,将“咒”作为判定牌。②一名角色的回合结束时,你令本回合移除过“咒”的角色各失去1点体力。", + reyingbing_info: + '锁定技,有“咒”的角色使用与“咒”颜色相同的牌时,你摸一张牌;若这是你第二次因该“咒”摸牌,则你获得该"咒"。', + yingbin_info: + "锁定技,有“咒”的角色使用与“咒”花色相同的牌时,你摸一张牌;当你因同一名角色的同一张“咒”的效果摸第二张牌时,移去该“咒”。", + zhoufu_info: + "出牌阶段限一次,你可以将一张手牌置于一名没有“咒”的其他角色的武将牌旁,称为“咒”。当有“咒”的角色判定时,其改为将“咒”作为判定牌;一名角色的回合结束时,若有角色于此回合因判定而移除过“咒”,则你令这些角色各失去1点体力。", + yanzheng_info: "若你的手牌数大于你的体力值,则你可以将你装备区内的牌当做【无懈可击】使用。", + kuiwei_info: + "结束阶段开始时,你可以摸2+X张牌并翻面。你的下个摸牌阶段开始时,你弃置X张牌(X为当前时机场上所有角色装备区内武器牌数之和)。", + tongji_info: + "锁定技。若你的手牌数大于你的体力值,则攻击范围包含你的其他角色使用【杀】时不能指定你以外的角色为目标。", + wangzun_info: + "其他角色的准备阶段开始时,你可以摸一张牌。若如此做,该角色此回合的手牌上限-1。然后你不能再发动〖妄尊〗直到回合开始。", + kaikang_info: + "当一名角色成为【杀】的目标后,若你至该角色的距离为1,你可以摸一张牌。若如此做,你交给其一张牌并展示之。若为装备牌,该角色可以使用此牌。", + liangzhu_info: + "当一名角色于其出牌阶段内回复体力时,你可以选择一项:1、摸一张牌;2、令该角色摸两张牌。", + mingshi_info: "当你受到伤害时,若伤害来源的体力值大于你,你可以弃置一张黑色手牌,令伤害值-1。", + lirang_info: "当你的牌因弃置而置入弃牌堆后,你可以将其中的任意张牌交给其他角色。", + moukui_info: + "当你使用【杀】指定目标后,你可以选择一项:摸一张牌,或弃置其一张牌。若如此做,当此【杀】被【闪】抵消时,目标角色弃置你的一张牌。", + qiangwu_info: + "出牌阶段,你可以进行判定。若如此做,直到回合结束,你使用点数小于判定结果的【杀】时不受距离限制,且你使用点数大于判定结果的【杀】时无使用次数限制。", + shenxian_info: + "每名角色的回合限一次,你的回合外,当有其他角色因弃置而失去基本牌时,你可以摸一张牌。", + oldshenxian_info: "你的回合外,每当有其他角色因弃置而失去基本牌时,你可以摸一张牌。", + qiluan_info: + "一名角色的回合结束时,你可以摸3X+Y张牌。(X为你本回合内杀死过的角色数,Y为本回合内其他角色杀死过的角色数)", //qiluan_info_guozhan:'一名角色的回合结束时,若你于回合内杀死过角色,则你可以摸三张牌。', - zhendu_info:'一名角色的出牌阶段开始时,你可以弃置一张手牌,视为该角色使用了一张【酒】。若该角色不是你,你对其造成1点伤害。', + zhendu_info: + "一名角色的出牌阶段开始时,你可以弃置一张手牌,视为该角色使用了一张【酒】。若该角色不是你,你对其造成1点伤害。", //zhendu_info_guozhan:'其他角色的出牌阶段开始时,你可以弃置一张手牌,视为该角色使用了一张【酒】。若如此做,你对其造成1点伤害。', - shangyi_info:'出牌阶段限一次,你可以观看一名其他角色的手牌,然后弃置其中的一张黑色牌。', - zniaoxiang_info:'锁定技,当你使用【杀】指定目标后,你令目标角色响应此【杀】所需要使用的【闪】的数目+1。', - shoucheng_info:'当一名角色于其回合外失去手牌时,若其没有手牌,则你可令该角色摸一张牌。', - shengxi_info:'弃牌阶段开始时,若你本回合内未造成过伤害,则你可以摸两张牌。', - hengzheng_info:'摸牌阶段开始时,若你的体力值为1或你没有手牌,则你可以放弃摸牌,改为获得每名其他角色区域内的一张牌。', - cunsi_info:'限定技,出牌阶段,你可以将所有手牌交给一名男性角色。该角色获得技能〖勇决〗,然后你将武将牌翻面。', - yongjue_info:'每回合限一次。当其他角色于回合内使用的【杀】结算完成后,若你不是此【杀】的目标角色,则你可以获得之。', - guixiu_info:'当你成为【杀】的目标后,若你的手牌数小于体力值,则你可以摸一张牌。', - fenming_info:'结束阶段开始时,若你处于横置状态,你可以弃置所有处于横置状态的角色的各一张牌。', - duanxie_info:'出牌阶段限一次,你可以令至多X名其他角色横置(X为你已损失的体力值且至少为1),然后你横置。', - xiaoguo_info:'其他角色的结束阶段开始时,你可以弃置一张手牌,令该角色选择一项:1.弃置一张装备牌,然后你摸一张牌;2.受到你对其造成的1点伤害。', - sijian_info:'当你失去最后的手牌时,你可以弃置一名其他角色的一张牌。', - suishi_info:'当其他角色进入濒死状态时,伤害来源可以令你摸一张牌;当其他角色死亡时,伤害来源可以令你失去1点体力。', - quji_info:'出牌阶段限一次,你可以弃置X张牌(X为你已损失的体力值),然后令至多X名已受伤的角色各回复1点体力。若你以此法弃置的牌中有黑色牌,你失去1点体力。', - junbing_info:'一名角色的结束阶段开始时,若其手牌数不大于1,该角色可以摸一张牌。若如此做,该角色将所有手牌交给你,然后你交给其等量的牌。', - xiongyi_info:'限定技,出牌阶段,你可以选择任意名角色,这些角色各摸三张牌。然后若你的体力值最小,你回复1点体力。', - xiongyi_info_guozhan:'限定技,出牌阶段,你可以令与你势力相同的所有角色各摸三张牌,然后若你的势力是角色最少的势力(或之一),则你回复1点体力。', - shenzhi_info:'准备阶段开始时,你可以弃置所有手牌。若你以此法弃置的牌数不小于X,你回复1点体力(X为你的体力值)。', - shushen_info:'当你回复1点体力时,你可以令一名其他角色选择回复1点体力或摸两张牌。', - wuji_info:'觉醒技,结束阶段开始时,若你于此回合内造成过3点或更多伤害,你加1点体力上限并回复1点体力,失去〖虎啸〗,然后从场上、牌堆或弃牌堆中获得【青龙偃月刀】。', - xueji_info:'出牌阶段限一次,你可以弃置一张红色牌,然后选择至多X名角色,横置这些角色并对其中一名角色造成1点火焰伤害。(X为你已损失的体力值且至少为1)', - huxiao_info:'锁定技,当你造成火焰伤害后,你令受伤角色摸一张牌,然后你于此回合内对其使用牌没有次数限制。', - aocai_info:'当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌(若你没有手牌则改为四张)。若你观看的牌中有此牌,你可以使用打出之。', - aocai_info_guozhan:'当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌。若你观看的牌中有此牌,你可以使用打出之。', - hongyuan_info:'摸牌阶段,你可以少摸一张牌并指定至多两名其他角色。若如此做,这些角色各摸一张牌。', - hongyuan_info_combat:'摸牌阶段,你可以少摸一张牌。若如此做,其他友方角色各摸一张牌。', - huanshi_info:'一名角色的判定牌生效前,你可令其观看你的手牌。若如此做,该角色选择你的一张牌,你打出此牌代替之。', - mingzhe_info:'当你于回合外使用或打出红色牌,或因弃置失去一张红色牌后,你可以摸一张牌。', - duwu_info:'出牌阶段,你可以弃置X张牌对你攻击范围内的一名其他角色造成1点伤害(X为该角色的体力值)。若该角色因此法进入濒死状态且存活,则你于濒死状态结算后失去1点体力,且本回合不能再发动〖黩武〗。', - tianming_info:'当你成为【杀】的目标时,你可以弃置两张牌(不足则全弃,无牌则不弃),然后摸两张牌;若此时全场体力值最多的角色仅有一名且不是你,该角色也可以如此做。', - mizhao_info:'出牌阶段限一次,你可以将所有手牌交给一名其他角色。若如此做,你令该角色与你指定的另一名有手牌的角色拼点,视为拼点赢的角色对没赢的角色使用一张【杀】。', - yuanhu_info:'结束阶段开始时,你可以将一张装备牌置于一名角色的装备区里,然后根据此装备牌的类型执行以下对应效果。武器牌:弃置该角色距离1以内的一名角色区域中的一张牌;防具牌:该角色摸一张牌;坐骑牌:该角色回复1点体力。', - lihun_info:'出牌阶段限一次,你可以弃置一张牌并选择一名其他男性角色。若如此做,你将武将牌翻面并获得其所有手牌。出牌阶段结束时,你交给其X张牌。(X为该角色的体力值)', - chongzhen_info:'当你因发动〖龙胆〗而使用或打出【杀】或【闪】时,你可以获得对方的一张手牌。', - bifa_info:'结束阶段开始时,你可以将一张手牌移出游戏并指定一名其他角色。该角色的准备阶段开始时,其观看你移出游戏的牌并选择一项:交给你一张与此牌类型相同的手牌并获得此牌;或将此牌置入弃牌堆,然后失去1点体力。', - songci_info:'①出牌阶段,你可以选择一名未以此法选择过的角色。若其手牌数:大于其体力值,其弃置两张牌;不大于其体力值,其摸两张牌。②弃牌阶段结束时,若你已对场上所有存活角色发动过〖颂词①〗,则你摸一张牌。', - yongsi_info:'锁定技。①摸牌阶段,你多摸X张牌。②弃牌阶段开始时,你弃置X张牌。(X为场上势力数)', - yicong_info:'锁定技,当你的体力值大于2时,你计算与其他角色的距离时-1;当你的体力值不大于2时,其他角色计算与你的距离时+1。', - baobian_info:'锁定技,若你的体力值为3或更少,你视为拥有技能〖挑衅〗;若你的体力值为2或更少;你视为拥有技能〖咆哮〗;若你的体力值为1,你视为拥有技能〖神速〗。', - rebaobian:'豹变', - rebaobian_info:'锁定技。当你受到伤害后,你获得以下技能中第一个未拥有的技能:〖挑衅〗/〖咆哮〗/〖神速〗。', - bingzhao:'秉诏', - bingzhao_info:'主公技,游戏开始时,你选择一个其他势力。当你对该势力的角色发动〖骨疽〗时,其可令你额外摸一张牌。', - sunshao:'孙邵', - bizheng:'弼政', - bizheng_info:'摸牌阶段结束时,你可以令一名其他角色摸两张牌。然后,若你的手牌数大于体力上限,你弃置两张牌。若其的手牌数大于体力上限,其弃置两张牌。', - yidian:'佚典', - yidian_info:'当你使用牌选择目标时,若弃牌堆中没有与此牌名称相同的牌,则你可以为此牌增加一个目标(无距离限制)。', - xinlianji:'连计', - xinlianji_info:'出牌阶段限一次,你可以弃置一张手牌,令一名角色使用牌堆中的一张随机武器牌。然后其选择一项:对你指定的一名角色使用一张【杀】,或令你将其装备区里的武器牌交给任意角色。', - xinmoucheng:'谋逞', - xinmoucheng_info:'觉醒技,准备阶段,若有角色因你发动〖连计〗使用【杀】而造成过伤害,则你失去〖连计〗并获得〖矜功〗。', - xinjingong:'矜功', - xinjingong_backup:'矜功', - xinjingong_info:'出牌阶段限一次,你可以将一张【杀】或装备牌当做三张随机锦囊牌中的一张使用。', - caiyang:'蔡阳', - yinka:'印卡', - zhangling:'张陵', - zlhuji:'虎骑', - zlhuji_info:'锁定技,你与其他角色的距离-1,当你于回合外受到伤害后,你可进行判定,若结果为红色,视为你对伤害来源使用一张【杀】(无距离限制)。', - zlshoufu:'授符', - zlshoufu2:'授符', - zlshoufu_info:'出牌阶段限一次,你可摸一张牌,然后将一张手牌置于一名没有【箓】的角色的武将牌上,称为【箓】;其不能使用和打出与【箓】同类型的牌。该角色受到伤害后,或于弃牌阶段弃置至少两张与【箓】同类型的牌后,将【箓】置入弃牌堆。', - ol_zhangchangpu:'OL张昌蒲', - ol_zhangchangpu_prefix:'OL', - olxingshen:'省身', - olxingshen_info:'当你受到伤害后,你可以随机摸至多两张牌。若如此做,你获得X个“省”,且下一次发动〖严教〗展示牌时移去所有“省”并多展示等量的牌。(X为你已损失的体力值,且你至多拥有6个“省”)', - caoshuang:'曹爽', - tuogu:'托孤', - tuogu_info:'限定技,一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能。', - retuogu:'托孤', - retuogu_info:'一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能并失去上次因〖托孤〗获得的技能。', - shanzhuan:'擅专', - shanzhuan_info:'①当你对其他角色造成伤害后,若其判定区没有延时类锦囊牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。②回合结束时,若你本回合内未造成伤害,你可摸一张牌。', - spniluan:'逆乱', - spniluan_info:'出牌阶段,你可以将一张黑色牌当做【杀】使用。此【杀】使用结算完成后,若你未因此【杀】造成过伤害,则你令此【杀】不计入使用次数。', - spweiwu:'违忤', - spweiwu_info:'出牌阶段限一次,你可以将一张红色牌当无距离限制的【顺手牵羊】使用。', - spmouzhu:'谋诛', - spmouzhu_backup:'谋诛', - spmouzhu_info:'出牌阶段限一次,你可以选择任意名“距离为1”或“体力值等于你”的其他角色,这些角色依次进行以下结算:交给你一张手牌,然后若其手牌数小于你,则其视为对你使用一张【杀】或【决斗】。', - spyanhuo:'延祸', - spyanhuo_info:'当你死亡时,你可增加如下全局技能:当有角色使用【杀】时,此【杀】的伤害值基数+1。', - xiaoxi:'骁袭', - xiaoxi_info:'当你登场时,你可以视为使用一张【杀】。', - quyi:'麴义', - wolongfengchu:'卧龙凤雏', - youlong:'游龙', - youlong_info:'转换技,阴,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的基本牌。', - luanfeng:'鸾凤', + shangyi_info: "出牌阶段限一次,你可以观看一名其他角色的手牌,然后弃置其中的一张黑色牌。", + zniaoxiang_info: + "锁定技,当你使用【杀】指定目标后,你令目标角色响应此【杀】所需要使用的【闪】的数目+1。", + shoucheng_info: "当一名角色于其回合外失去手牌时,若其没有手牌,则你可令该角色摸一张牌。", + shengxi_info: "弃牌阶段开始时,若你本回合内未造成过伤害,则你可以摸两张牌。", + hengzheng_info: + "摸牌阶段开始时,若你的体力值为1或你没有手牌,则你可以放弃摸牌,改为获得每名其他角色区域内的一张牌。", + cunsi_info: + "限定技,出牌阶段,你可以将所有手牌交给一名男性角色。该角色获得技能〖勇决〗,然后你将武将牌翻面。", + yongjue_info: + "每回合限一次。当其他角色于回合内使用的【杀】结算完成后,若你不是此【杀】的目标角色,则你可以获得之。", + guixiu_info: "当你成为【杀】的目标后,若你的手牌数小于体力值,则你可以摸一张牌。", + fenming_info: "结束阶段开始时,若你处于横置状态,你可以弃置所有处于横置状态的角色的各一张牌。", + duanxie_info: + "出牌阶段限一次,你可以令至多X名其他角色横置(X为你已损失的体力值且至少为1),然后你横置。", + xiaoguo_info: + "其他角色的结束阶段开始时,你可以弃置一张手牌,令该角色选择一项:1.弃置一张装备牌,然后你摸一张牌;2.受到你对其造成的1点伤害。", + sijian_info: "当你失去最后的手牌时,你可以弃置一名其他角色的一张牌。", + suishi_info: + "当其他角色进入濒死状态时,伤害来源可以令你摸一张牌;当其他角色死亡时,伤害来源可以令你失去1点体力。", + quji_info: + "出牌阶段限一次,你可以弃置X张牌(X为你已损失的体力值),然后令至多X名已受伤的角色各回复1点体力。若你以此法弃置的牌中有黑色牌,你失去1点体力。", + junbing_info: + "一名角色的结束阶段开始时,若其手牌数不大于1,该角色可以摸一张牌。若如此做,该角色将所有手牌交给你,然后你交给其等量的牌。", + xiongyi_info: + "限定技,出牌阶段,你可以选择任意名角色,这些角色各摸三张牌。然后若你的体力值最小,你回复1点体力。", + xiongyi_info_guozhan: + "限定技,出牌阶段,你可以令与你势力相同的所有角色各摸三张牌,然后若你的势力是角色最少的势力(或之一),则你回复1点体力。", + shenzhi_info: + "准备阶段开始时,你可以弃置所有手牌。若你以此法弃置的牌数不小于X,你回复1点体力(X为你的体力值)。", + shushen_info: "当你回复1点体力时,你可以令一名其他角色选择回复1点体力或摸两张牌。", + wuji_info: + "觉醒技,结束阶段开始时,若你于此回合内造成过3点或更多伤害,你加1点体力上限并回复1点体力,失去〖虎啸〗,然后从场上、牌堆或弃牌堆中获得【青龙偃月刀】。", + xueji_info: + "出牌阶段限一次,你可以弃置一张红色牌,然后选择至多X名角色,横置这些角色并对其中一名角色造成1点火焰伤害。(X为你已损失的体力值且至少为1)", + huxiao_info: + "锁定技,当你造成火焰伤害后,你令受伤角色摸一张牌,然后你于此回合内对其使用牌没有次数限制。", + aocai_info: + "当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌(若你没有手牌则改为四张)。若你观看的牌中有此牌,你可以使用打出之。", + aocai_info_guozhan: + "当你于回合外需要使用或打出一张基本牌时,你可以观看牌堆顶的两张牌。若你观看的牌中有此牌,你可以使用打出之。", + hongyuan_info: "摸牌阶段,你可以少摸一张牌并指定至多两名其他角色。若如此做,这些角色各摸一张牌。", + hongyuan_info_combat: "摸牌阶段,你可以少摸一张牌。若如此做,其他友方角色各摸一张牌。", + huanshi_info: + "一名角色的判定牌生效前,你可令其观看你的手牌。若如此做,该角色选择你的一张牌,你打出此牌代替之。", + mingzhe_info: "当你于回合外使用或打出红色牌,或因弃置失去一张红色牌后,你可以摸一张牌。", + duwu_info: + "出牌阶段,你可以弃置X张牌对你攻击范围内的一名其他角色造成1点伤害(X为该角色的体力值)。若该角色因此法进入濒死状态且存活,则你于濒死状态结算后失去1点体力,且本回合不能再发动〖黩武〗。", + tianming_info: + "当你成为【杀】的目标时,你可以弃置两张牌(不足则全弃,无牌则不弃),然后摸两张牌;若此时全场体力值最多的角色仅有一名且不是你,该角色也可以如此做。", + mizhao_info: + "出牌阶段限一次,你可以将所有手牌交给一名其他角色。若如此做,你令该角色与你指定的另一名有手牌的角色拼点,视为拼点赢的角色对没赢的角色使用一张【杀】。", + yuanhu_info: + "结束阶段开始时,你可以将一张装备牌置于一名角色的装备区里,然后根据此装备牌的类型执行以下对应效果。武器牌:弃置该角色距离1以内的一名角色区域中的一张牌;防具牌:该角色摸一张牌;坐骑牌:该角色回复1点体力。", + lihun_info: + "出牌阶段限一次,你可以弃置一张牌并选择一名其他男性角色。若如此做,你将武将牌翻面并获得其所有手牌。出牌阶段结束时,你交给其X张牌。(X为该角色的体力值)", + chongzhen_info: "当你因发动〖龙胆〗而使用或打出【杀】或【闪】时,你可以获得对方的一张手牌。", + bifa_info: + "结束阶段开始时,你可以将一张手牌移出游戏并指定一名其他角色。该角色的准备阶段开始时,其观看你移出游戏的牌并选择一项:交给你一张与此牌类型相同的手牌并获得此牌;或将此牌置入弃牌堆,然后失去1点体力。", + songci_info: + "①出牌阶段,你可以选择一名未以此法选择过的角色。若其手牌数:大于其体力值,其弃置两张牌;不大于其体力值,其摸两张牌。②弃牌阶段结束时,若你已对场上所有存活角色发动过〖颂词①〗,则你摸一张牌。", + yongsi_info: "锁定技。①摸牌阶段,你多摸X张牌。②弃牌阶段开始时,你弃置X张牌。(X为场上势力数)", + yicong_info: + "锁定技,当你的体力值大于2时,你计算与其他角色的距离时-1;当你的体力值不大于2时,其他角色计算与你的距离时+1。", + baobian_info: + "锁定技,若你的体力值为3或更少,你视为拥有技能〖挑衅〗;若你的体力值为2或更少;你视为拥有技能〖咆哮〗;若你的体力值为1,你视为拥有技能〖神速〗。", + rebaobian: "豹变", + rebaobian_info: + "锁定技。当你受到伤害后,你获得以下技能中第一个未拥有的技能:〖挑衅〗/〖咆哮〗/〖神速〗。", + bingzhao: "秉诏", + bingzhao_info: + "主公技,游戏开始时,你选择一个其他势力。当你对该势力的角色发动〖骨疽〗时,其可令你额外摸一张牌。", + sunshao: "孙邵", + bizheng: "弼政", + bizheng_info: + "摸牌阶段结束时,你可以令一名其他角色摸两张牌。然后,若你的手牌数大于体力上限,你弃置两张牌。若其的手牌数大于体力上限,其弃置两张牌。", + yidian: "佚典", + yidian_info: + "当你使用牌选择目标时,若弃牌堆中没有与此牌名称相同的牌,则你可以为此牌增加一个目标(无距离限制)。", + xinlianji: "连计", + xinlianji_info: + "出牌阶段限一次,你可以弃置一张手牌,令一名角色使用牌堆中的一张随机武器牌。然后其选择一项:对你指定的一名角色使用一张【杀】,或令你将其装备区里的武器牌交给任意角色。", + xinmoucheng: "谋逞", + xinmoucheng_info: + "觉醒技,准备阶段,若有角色因你发动〖连计〗使用【杀】而造成过伤害,则你失去〖连计〗并获得〖矜功〗。", + xinjingong: "矜功", + xinjingong_backup: "矜功", + xinjingong_info: "出牌阶段限一次,你可以将一张【杀】或装备牌当做三张随机锦囊牌中的一张使用。", + caiyang: "蔡阳", + yinka: "印卡", + zhangling: "张陵", + zlhuji: "虎骑", + zlhuji_info: + "锁定技,你与其他角色的距离-1,当你于回合外受到伤害后,你可进行判定,若结果为红色,视为你对伤害来源使用一张【杀】(无距离限制)。", + zlshoufu: "授符", + zlshoufu2: "授符", + zlshoufu_info: + "出牌阶段限一次,你可摸一张牌,然后将一张手牌置于一名没有【箓】的角色的武将牌上,称为【箓】;其不能使用和打出与【箓】同类型的牌。该角色受到伤害后,或于弃牌阶段弃置至少两张与【箓】同类型的牌后,将【箓】置入弃牌堆。", + ol_zhangchangpu: "OL张昌蒲", + ol_zhangchangpu_prefix: "OL", + olxingshen: "省身", + olxingshen_info: + "当你受到伤害后,你可以随机摸至多两张牌。若如此做,你获得X个“省”,且下一次发动〖严教〗展示牌时移去所有“省”并多展示等量的牌。(X为你已损失的体力值,且你至多拥有6个“省”)", + caoshuang: "曹爽", + tuogu: "托孤", + tuogu_info: + "限定技,一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能。", + retuogu: "托孤", + retuogu_info: + "一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能并失去上次因〖托孤〗获得的技能。", + shanzhuan: "擅专", + shanzhuan_info: + "①当你对其他角色造成伤害后,若其判定区没有延时类锦囊牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。②回合结束时,若你本回合内未造成伤害,你可摸一张牌。", + spniluan: "逆乱", + spniluan_info: + "出牌阶段,你可以将一张黑色牌当做【杀】使用。此【杀】使用结算完成后,若你未因此【杀】造成过伤害,则你令此【杀】不计入使用次数。", + spweiwu: "违忤", + spweiwu_info: "出牌阶段限一次,你可以将一张红色牌当无距离限制的【顺手牵羊】使用。", + spmouzhu: "谋诛", + spmouzhu_backup: "谋诛", + spmouzhu_info: + "出牌阶段限一次,你可以选择任意名“距离为1”或“体力值等于你”的其他角色,这些角色依次进行以下结算:交给你一张手牌,然后若其手牌数小于你,则其视为对你使用一张【杀】或【决斗】。", + spyanhuo: "延祸", + spyanhuo_info: "当你死亡时,你可增加如下全局技能:当有角色使用【杀】时,此【杀】的伤害值基数+1。", + xiaoxi: "骁袭", + xiaoxi_info: "当你登场时,你可以视为使用一张【杀】。", + quyi: "麴义", + wolongfengchu: "卧龙凤雏", + youlong: "游龙", + youlong_info: + "转换技,阴,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的普通锦囊牌;阳,每轮限一次,你可以废除你的一个装备栏,视为使用一张未以此法使用过的基本牌。", + luanfeng: "鸾凤", //luanfeng_info_fullinfo:'限定技,一名角色进入濒死状态时,若其体力上限不小于你,你可令其回复至3点体力,恢复其被废除的装备栏,令其手牌补至6-X张(X为以此法恢复的装备栏数量),重置其因“改写”使用过的牌名。若该角色是你,重置你因“游龙”使用过的牌名。', - luanfeng_info:'限定技,一名角色进入濒死状态时,若其体力上限不小于你,你可令其回复至3点体力,恢复其被废除的装备栏,令其手牌补至6-X张(X为以此法恢复的装备栏数量)。若该角色是你,重置你因“游龙”使用过的牌名。', - reluanzhan:'乱战', - reluanzhan_add:'乱战', - reluanzhan_remove:'乱战', - reluanzhan_info:'当你受到或造成伤害后,你获得一个“乱”。当你使用【杀】或黑色普通锦囊牌选择目标后,你可为此牌增加至多X个目标。当你使用这些牌指定第一个目标后,若此牌目标数小于X,则你移去X/2(向上取整)个“乱”。(X为“乱”数)', - zhuixi:'追摄', - zhuixi_info:'锁定技,你使用【杀】的次数上限+1。', - reduanbing:'短兵', - reduanbing_info:'你使用【杀】选择目标后,可以为此【杀】增加一名距离为1的额外目标。你对距离为1的角色使用的【杀】需两张【闪】才能抵消。', - refenxun:'奋迅', - refenxun2:'奋迅', - refenxun_info:'出牌阶段限一次,你可以选择一名其他角色,然后本回合你计算与其的距离视为1;结束阶段开始时,若你未对其造成过伤害,你弃一张牌。', - zongyu:'宗预', - zyqiao:'气傲', - zyqiao_info:'每回合限两次。当你成为其他角色使用牌的目标后,你可以弃置其一张牌,然后你弃置一张牌。', - zyqiao_info_guozhan:'每回合限两次。当你成为其他势力的角色使用牌的目标后,你可以弃置其一张牌,然后你弃置一张牌。', - chengshang:'承赏', - chengshang_info:'当你于出牌阶段内使用的牌结算完成后,若此牌未造成过伤害且此牌的目标包含其他角色且你本阶段内未因〖承赏〗得到过牌,则你可以从牌堆中获得所有与此牌花色点数相同的牌。', - chengshang_info_guozhan:'当你于出牌阶段内使用的牌结算完成后,若此牌未造成过伤害且此牌的目标包含其他角色且你本阶段内未因〖承赏〗得到过牌,则你可以从牌堆中获得所有与此牌花色点数相同的牌。', - panshu:'OL潘淑', - panshu_prefix:'OL', - weiyi:'威仪', - weiyi_info:'每名角色限一次。当有角色受到伤害后,你可选择:①若其体力值不小于你,则其失去1点体力。②若其体力值不大于你且其已受伤,则其回复1点体力。', - jinzhi:'锦织', - jinzhi2:'锦织', - jinzhi_info:'当你需要使用或打出一张基本牌时,你可弃置X+1张颜色相同的牌并摸一张牌,然后视为你使用或打出了此牌。(X为你于本轮内发动此技能的次数)', - yanxiao_card:'言笑', - yanxiao_global:'言笑', - yanxiao_card_info:'判定阶段开始时,你获得判定区内的所有牌。', - gz_huangzu:'黄祖', - huangzu:'OL黄祖', - huangzu_prefix:'OL', - wangong:'挽弓', - wangong2:'挽弓', - wangong_info:'锁定技,当你使用基本牌时,你获得如下效果:当你使用下一张牌时,若此牌为【杀】,则此牌无次数和距离限制且伤害+1。', - huangchengyan:'OL黄承彦', - huangchengyan_prefix:'OL', - guanxu:'观虚', - guanxu_info:'出牌阶段限一次,你可以观看一名其他角色的手牌,然后你可将其中一张手牌与牌堆顶五张牌中的一张交换。若如此做,你弃置其手牌中三张花色相同的牌。', - yashi:'雅士', - yashi_info:'当你受到一次伤害后,你可选择一项:1. 令伤害来源的非锁定技无效直到其下个回合开始;2. 对一名其他角色发动〖观虚〗。', - olwuniang:'武娘', - olwuniang_info:'每回合限一次,当你于回合内使用的【杀】结算完成后,若此【杀】对应的目标数为1,则你可以令目标角色选择是否对你使用使用【杀】。你于其选择结算完成后摸一张牌,且本回合内使用【杀】的次数上限+1。', - olxushen:'许身', - olxushen_info:'限定技,当你进入濒死状态时,你可将体力回复至1点并获得技能〖镇南〗。然后若场上没有存活的“关索”,则你可以令一名其他男性角色选择是否将一张武将牌替换为“关索”。', - olzhennan:'镇南', - olzhennan2:'镇南', - olzhennan_info:'【南蛮入侵】对你无效。出牌阶段限一次,你可以将任意张手牌当做【南蛮入侵】对等量的角色使用。', - gaogan:'高干', - juguan:'拒关', - juguan_backup:'拒关', - juguan_info:'出牌阶段限一次,你可将一张手牌当【杀】或【决斗】使用。若受到此牌伤害的角色未在你的下回合开始前对你造成过伤害,你的下个摸牌阶段摸牌数+2。', - duxi:'杜袭', - quxi:'驱徙', - quxi_info:'限定技。出牌阶段结束时,你可跳过下个弃牌阶段并选择两名手牌数不同的其他角色。你将武将牌翻至背面,令这两名角色中手牌数较少的角色获得另一名角色的一张牌并获得一枚“丰”,另一名角色获得一枚“歉”。拥有“丰”/“歉”的角色的摸牌阶段额定摸牌数+1/-1。拥有“丰”/“歉”的角色死亡时,或一轮游戏开始时,你可转移“丰”/“歉”。', - bixiong:'避凶', - bixiong2:'避凶', - bixiong_info:'锁定技,当你于弃牌阶段弃置手牌后,其他角色不能使用与这些牌花色相同的牌指定你为目标直到你的下回合开始。', - fuwei:'扶危', - fuwei_info:'每回合限一次。当你的牌被其他角色弃置或获得后,你可从牌堆中获得一张与此牌名称相同的牌(若没有则改为摸一张牌)。', - yuejian:'约俭', - yuejian_info:'每回合限两次。当其他角色对你使用的牌A结算结束后,你可展示所有手牌。若牌A有花色且你的手牌中没有同花色的牌,则你获得牌A对应的所有实体牌。', - ol_dengzhi:'OL邓芝', - ol_dengzhi_prefix:'OL', - olxiuhao:'修好', - olxiuhao_info:'每回合限一次。当你受到其他角色造成的伤害时,或其他角色受到你造成的伤害时,你可防止此伤害,然后令伤害来源摸两张牌。', - olsujian:'素俭', - olsujian_given:'已分配', - olsujian_info:'锁定技。弃牌阶段开始前,你将此阶段的规则改为:{你选择一项:①将所有不为本回合得到的手牌分配给其他角色。②弃置这些手牌,然后弃置一名其他角色等量的牌}。', - ol_wangrong:'OL王荣', - ol_wangrong_prefix:'OL', - olfengzi:'丰姿', - olfengzi_info:'出牌阶段限一次。当你使用有目标的基本牌或普通锦囊牌时,你可弃置一张与此牌类型相同的牌,然后令此牌结算两次。', - oljizhan:'吉占', - oljizhan_info:'摸牌阶段开始时,你可以放弃摸牌。你展示牌堆顶的一张牌,并猜测牌堆顶的下一张牌点数大于或小于此牌。若你猜对,你可继续重复此流程。然后你获得以此法展示的所有牌。', - olfusong:'赋颂', - olfusong_info:'当你死亡时,你可以选择一名体力上限大于你的其他角色。其选择获得〖吉占〗或〖丰姿〗。', - zuofen:'左棻', - zhaosong:'诏颂', - zhaosong_info:'一名其他角色的摸牌阶段结束时,若其没有因〖诏颂〗而获得的标记,则你可令其正面向上交给你一张手牌。根据此牌的类型,该角色获得对应的标记和效果:
              锦囊牌:“诔”标记。当拥有者进入濒死状态时,其可弃置所有“诔”,将体力回复至1点并摸一张牌。
              装备牌:“赋”标记。拥有者的出牌阶段开始时,其可弃置所有“赋”,弃置一名角色区域内的至多两张牌。
              基本牌:“颂”标记。当使用者使用仅指定一个目标的【杀】时,其可弃置“颂”,为此【杀】增加至多两个目标。', - lisi:'离思', - lisi_info:'当你于回合外使用的牌结算结束后,你可将其交给一名手牌数不大于你的其他角色。', - ol_yangyi:'杨仪', - oljuanxia:'狷狭', - oljuanxia_info:'结束阶段,你可以选择一名其他角色。你依次视为对其使用至多三种单目标普通锦囊牌。然后其下回合结束时,可视为对你使用等量的【杀】。', - oldingcuo:'定措', - oldingcuo_info:'每回合限一次。当你受到或造成伤害后,你可摸两张牌。若这两张牌颜色不同,则你弃置一张手牌。', - fengfangnv:'OL冯妤', - fengfangnv_prefix:'OL', - zhuangshu:'妆梳', - zhuangshu_info:'①游戏开始时,你可将{【琼梳】,【犀梳】,【金梳】}中的一张牌置于装备区。②一名角色的回合开始时,若其宝物区为空,则你可以弃置一张牌,并根据此牌的类型,按如下关系将一张宝物牌置入该角色的装备区:{<基本牌,【琼梳】>,<锦囊牌,【犀梳】>,<装备牌,【金梳】>}。', - chuiti:'垂涕', - chuiti_info:'每回合限一次。当你或拥有〖妆梳〗牌角色的牌因弃置而进入弃牌堆后,你可使用其中的一张牌。', - zhuangshu_basic:'琼梳', - zhuangshu_basic_bg:'琼', - zhuangshu_basic_info:'当你受到伤害时,你可以弃置X张牌并防止此伤害(X为伤害值)。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。', - zhuangshu_trick:'犀梳', - zhuangshu_trick_bg:'犀', - zhuangshu_trick_info:'判定阶段开始前,你可选择:①跳过此阶段。②跳过本回合的弃牌阶段。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。', - zhuangshu_equip:'金梳', - zhuangshu_equip_bg:'金', - zhuangshu_equip_info:'锁定技。出牌阶段结束时,你将手牌摸至手牌上限(至多摸五张)。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。', - ol_dongzhao:'OL董昭', - ol_dongzhao_prefix:'OL', - olxianlve:'先略', - olxianlve_info:'①主公的回合开始时,你可声明并记录一个锦囊牌的名称并移除先前的记录。②每回合限一次,其他角色使用〖先略〗记录过的锦囊牌后,你可摸两张牌并可以分配给任意其他角色,然后你可声明并记录一个锦囊牌的名称并移除先前的记录。', - olzaowang:'造王', - olzaowang2:'造王', - olzaowang_info:'限定技。出牌阶段,你可以令一名角色加1点体力上限,回复1点体力并摸三张牌,且获得如下效果:主公死亡时,若其身份为忠臣,则其和主公交换身份牌;其死亡时,若其身份为反贼且伤害来源的身份为主公或忠臣,则以主忠胜利结束本局游戏。', - sp_ol_zhanghe:'SP张郃', - sp_ol_zhanghe_prefix:'SP', - spolzhouxuan:'周旋', - spolzhouxuan_info:'①弃牌阶段开始时,你可将任意张置于武将牌上,称为“旋”(你至多拥有五张“旋”)。②当你使用牌时,你随机将一张“旋”置入弃牌堆,然后摸一张牌(若你的手牌数不为全场唯一最多则额外摸X张牌,X为“旋”数)。③出牌阶段结束时,你将所有“旋”置入弃牌堆。', - wuyan:'吾彦', - lanjiang:'澜疆', - lanjiang_info:'结束阶段,你可以选择所有手牌数不小于你的角色。这些角色依次选择是否令你摸一张牌。然后你可以对其中一名手牌数等于你的角色造成1点伤害,随后令其中一名手牌数小于你的角色摸一张牌。', - ol_zhuling:'OL朱灵', - ol_zhuling_prefix:'OL', - jixian:'急陷', - jixian_info:'摸牌阶段结束时,你可以选择一名满足以下至少一项条件的角色:⒈装备区内有防具牌;⒉拥有的普通技能数大于你;⒊体力值等于体力上限。你视为对其使用一张【杀】,然后摸X张牌(X为其于此【杀】结算前满足的条件数);若此【杀】未造成伤害,则你失去1点体力。', - ol_chendeng:'OL陈登', - ol_chendeng_prefix:'OL', - olfengji:'丰积', - olfengji_info:'摸牌阶段开始时,你选择:⒈本回合摸牌阶段的额定摸牌数-1,且令一名其他角色下回合摸牌阶段的额定摸牌数+2;⒉本回合摸牌阶段的额定摸牌数+1。然后你选择:⒈本回合使用【杀】的次数上限-1,且令一名其他角色下回合使用【杀】的次数上限+2;⒉本回合使用【杀】的次数上限+1。', - tianyu:'田豫', - saodi:'扫狄', - saodi_info:'当你使用【杀】或普通锦囊牌指定唯一其他角色为目标时,你可从逆时针方向和顺时针方向中选择一个你与其之间角色最少的方向。你令该方向下你与其之间的所有能成为此牌额外目标的角色均成为此牌的目标。', - zhuitao:'追讨', - zhuitao_info:'①准备阶段,你可选择一名未被〖追讨〗记录过的其他角色。②你至所有〖追讨〗记录过的角色的距离-1。③当你对一名被〖追讨〗记录过的角色造成伤害时,你从〖追讨〗记录里移除该角色。', - fanjiangzhangda_ab:'范疆张达', - fanjiangzhangda:'范强张达', - yuanchou:'怨仇', - yuanchou_info:'锁定技。当你使用黑色【杀】指定目标角色后或成为黑色【杀】的目标角色后,你令目标角色的防具技能无效直到此【杀】被抵消或造成伤害。', - juesheng:'决生', - juesheng_info:'限定技。出牌阶段,你可视为使用一张【决斗】。当你因此【决斗】造成伤害时,你将伤害值改为X(X为目标角色本局游戏内使用过【杀】的数量且至少为1)且令目标角色获得此技能直到其下回合结束。', - qinghegongzhu:'清河公主', - zengou:'谮构', - zengou_info:'当有角色使用【闪】时,若其在你的攻击范围内,则你可以弃置一张非基本牌或失去1点体力,然后取消此【闪】的目标并获得其对应的实体牌。', - qhzhangji:'长姬', - qhzhangji_info:'一名角色的回合结束时,若你本回合内:造成过伤害,则你可以令其摸两张牌;受到过伤害,则你可以令其弃置两张牌。', - sp_menghuo:'SP孟获', - sp_menghuo_prefix:'SP', - spmanwang:'蛮王', - spmanwang_info:'出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前等量项:⒈获得〖叛侵〗。⒉摸一张牌。⒊回复1点体力。⒋摸两张牌并失去〖叛侵〗。', - sppanqin:'叛侵', - sppanqin_info:'出牌阶段或弃牌阶段结束时,你可将你于本阶段内弃置且位于弃牌堆的所有牌当做【南蛮入侵】使用。然后若此牌被使用时对应的实体牌数不大于此牌的目标数,则你执行并移除〖蛮王〗中的最后一个选项。', - tengfanglan:'OL滕芳兰', - tengfanglan_prefix:'OL', - luochong:'落宠', - luochong_info:'准备阶段开始时/当你于一回合内首次受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):⒈令一名角色回复1点体力。⒉令一名角色失去1点体力。⒊令一名角色弃置两张牌。⒋令一名角色摸两张牌。', - aichen:'哀尘', - aichen_info:'锁定技。当你进入濒死状态时,若〖落宠〗中的剩余选项数大于1,则你选择移去〖落宠〗中的一个选项。', - weizi:'卫兹', - yuanzi:'援资', - yuanzi_info:'每轮限一次。其他角色的准备阶段开始时,你可将所有手牌交给该角色。若如此做,当该角色于本回合内造成伤害后,若其手牌数不小于你,则你摸两张牌。', - liejie:'烈节', - liejie_info:'当你受到伤害后,你可以弃置至多三张牌,摸等量的牌,然后可弃置伤害来源的至多X张牌(X为你以此法弃置的红色牌的数量)。', - ruiji:'OL芮姬', - ruiji_prefix:'OL', - qiaoli:'巧力', - qiaoli_info:'出牌阶段各限一次,你可以将一张武器牌/非武器装备牌当作【决斗】使用。若此【决斗】对应的实体牌为武器牌,当你以此【决斗】对目标角色造成伤害后,你摸X张牌(X为此牌的攻击范围),且可以将其中任意张牌分配给其他角色;若此【决斗】对应的实体牌不为武器牌,此牌不可被响应,且你于结束阶段从牌堆中获得一张装备牌。', - qiaoli_given:'已分配', - qingliang:'清靓', - qingliang_info:'每回合限一次,当你成为其他角色使用【杀】或伤害类锦囊牌的唯一目标时,你可展示所有手牌,然后选择一项:⒈你与其各摸一张牌,⒉取消此目标,然后弃置你手牌中一种花色的所有牌。', - chixueqingfeng:'赤血青锋', - chixueqingfeng2:'赤血青锋', - chixueqingfeng_info:'锁定技,当你使用【杀】指定目标后,你令目标角色不能使用或打出手牌且防具技能无效直到此【杀】结算结束。', - wushuangfangtianji:'无双方天戟', - wushuangfangtianji_skill:"无双方天戟", - wushuangfangtianji_info:"当你因执行【杀】的效果而造成伤害后,你可选择一项:⒈摸一张牌;⒉弃置目标角色的一张牌。", - guilongzhanyuedao:'鬼龙斩月刀', - guilongzhanyuedao_info:'锁定技,你使用的红色【杀】不可被响应。', - bintieshuangji:'镔铁双戟', - bintieshuangji_skill:'镔铁双戟', - bintieshuangji_info:'当你使用的【杀】被抵消后,你可失去1点体力。获得此【杀】对应的所有实体牌,摸一张牌,且本回合使用【杀】的次数上限+1。', - linglongshimandai:"玲珑狮蛮带", - linglongshimandai_info:"当你成为其他角色使用的牌的唯一目标后,你可以进行判定。若判定结果为♥,则此牌对你无效。", - linglongshimandai_skill:"玲珑狮蛮带", - hongmianbaihuapao_skill:"红棉百花袍", - hongmianbaihuapao:"红棉百花袍", - hongmianbaihuapao_info:"锁定技,当你受到属性伤害时,防止此伤害。", - qimenbagua:'奇门八卦', - qimenbagua_info:'锁定技,【杀】对你无效。', - guofengyupao:'国风玉袍', - guofengyupao_info:'锁定技,你不是其他角色使用普通锦囊牌的合法目标。', - shufazijinguan:'束发紫金冠', - shufazijinguan_skill:"束发紫金冠", - shufazijinguan_info:"准备阶段,你可以对一名其他角色造成1点伤害。", - sanlve:'三略', - sanlve_skill:'三略', - sanlve_info:'锁定技。你的攻击范围+1。你的手牌上限+1。你使用【杀】的次数上限+1。', - zhaogujing:'照骨镜', - zhaogujing_skill:'照骨镜', - zhaogujing_info:'出牌阶段结束时,你可展示手牌中的一张基本牌或普通锦囊牌,然后你视为使用一张牌名和属性与此牌相同的牌。', - xuwangzhimian:'虚妄之冕', - xuwangzhimian_info:'锁定技,摸牌阶段,你令额定摸牌数+2;你的手牌上限-1。', - ol_puyuan:'OL蒲元', - ol_puyuan_prefix:'OL', - olshengong:'神工', - olshengong_info:'出牌阶段每项限一次。你可以弃置一张武器牌/防具牌/其他装备牌,并发起一次“锻造”。然后你从锻造结果中选择一张牌,置于一名角色的装备区内(可替换原装备)。当有因你发动〖神工〗而加入游戏的牌进入弃牌堆后,你将此牌移出游戏,然后你于当前回合结束后摸一张牌。', - olqisi:'奇思', - olqisi_info:'①游戏开始时,你获得两张副类别不同的牌,并将这些牌置入你的装备区。②摸牌阶段开始时,你可以少摸一张牌并声明一种装备牌的副类别,然后从牌堆或弃牌堆中获得一张该副类别的牌。', - olzhuiji:'追击', - olzhuiji_info:'锁定技。①你至体力值不大于你的角色的距离为1。②当你使用【杀】指定距离为1的角色为目标后,你令其选择一项:⒈弃置一张牌。⒉重铸装备区内的所有牌。', - zhaoyǎn:'OL赵俨', - zhaoyǎn_prefix:'OL', - tongxie:'同协', - tongxie_info:'出牌阶段开始时,你可以选择包括你在内的至多三名角色(你与这些角色均称为“同协角色”)。这些角色中手牌数唯一最少的角色摸一张牌,且你获得如下效果直到你下回合开始:①当有“同协角色”对唯一目标角色使用的【杀】结算结束后,其他“同协角色”可以依次对目标角色使用一张【杀】(无距离和次数限制,且不能再触发此效果)。②当有“同协角色”受到伤害时,其他“同协角色”(本回合内失去过体力的角色除外)可以防止此伤害,失去1点体力。', - jin_zhouchu:'周处', - shanduan:'善断', - shanduan_info:'锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=[1,2,3,4]中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。', - yilie:'义烈', - yilie_info:'每轮每种牌名限一次。你可以将两张颜色相同的手牌当做任意一种基本牌使用。', - caoxiancaohua:'曹宪曹华', - huamu:'化木', - huamu_info:'当你使用手牌后,若此牌和本回合内上一张被使用的牌颜色不同,则你可以将此牌对应的所有{位于处理区或装备区}的实体牌置于你的武将牌上。这些牌中的黑色牌称为“灵杉”,红色牌称为“玉树”。', - qianmeng:'前盟', - qianmeng_info:'锁定技。当有牌移动事件结算结束后,若有角色的“灵杉”和“玉树”数量发生了变化,且二者数量相等或有一项为0,则你摸一张牌。', - liangyuan:'良缘', - liangyuan_info:'每轮每项各限一次。你可以将场上所有的“灵杉”/“玉树”置于处理区,然后将这些牌当做【酒】/【桃】使用。', - jisi:'羁肆', - jisi_info:'限定技。准备阶段,你可以令一名其他角色获得你武将牌上的一个已发动过的其他技能。然后你弃置所有手牌,并视为对其使用一张【杀】(无距离关系的限制)。', - huojun:'OL霍峻', - huojun_prefix:'OL', - qiongshou:'穷守', - qiongshou_info:'锁定技。①游戏开始时,你废除所有装备栏并摸四张牌。②你的手牌上限+4。', - fenrui:'奋锐', - fenrui_info:'结束阶段,你可以弃置一张牌并恢复一个装备栏。系统检索一张对应的装备牌,你使用之。然后你可以选择一名装备区内牌数小于你的其他角色,对其造成X点伤害(X为你与其装备区内的牌数之差,且每局限一次)。', - wangyan:'王衍', - yangkuang:'阳狂', - yangkuang_info:'当你回复体力后,若你的体力值等于体力上限,则你可以视为使用一张【酒】,然后当前回合角色摸一张牌,你摸一张牌。', - cihuang:'雌黄', - cihuang_info:'当有牌被抵消后,若此牌的目标数为1且此牌的使用者A为当前回合角色,则你可以将一张牌当做一张你本轮内未使用过的属性【杀】或单目标锦囊牌对A使用(不可被响应)。', - sanku:'三窟', - sanku_info:'锁定技。①当你进入濒死状态时,你减1点体力上限,然后将体力回复至体力上限。②当你加体力上限前,取消之。', - dengzhong:'邓忠', - dzkanpo:'勘破', - dzkanpo_info:'①当你因执行【杀】的效果而造成伤害后,你可以观看目标角色的手牌,然后获得其中一张与此【杀】花色相同的牌。②每回合限一次,你可以将一张手牌当做【杀】使用。', - dzgengzhan:'更战', - dzgengzhan_info:'①其他角色的出牌阶段限一次,当有【杀】因弃置而进入弃牌堆后,你可以获得这些【杀】。②其他角色的结束阶段,若其本回合内未使用过【杀】,则你下个出牌阶段使用【杀】的次数上限+1。', - xiahouxuan:'夏侯玄', - olhuanfu:'宦浮', - olhuanfu_info:'当你使用【杀】指定第一个目标后,或成为【杀】的目标后,你可以弃置X张牌(X∈[1, 你的体力上限])。此【杀】结算结束后,若此【杀】累计因执行效果而造成的伤害值等于X,则你摸2X张牌。', - olqingyi:'清议', - olqingyi_info:'①出牌阶段限一次,你可以选择至多两名有牌的其他角色。你和这些角色同时弃置一张牌,然后若这些牌类型均相同,则你重复此流程。②结束阶段开始时,若你本回合内发动〖清议①〗弃置的牌包含两种颜色,则你获得每种颜色的牌各一张。', - olzeyue:'迮阅', - olzeyue_info:'限定技。准备阶段,你可以选择一名于你的上个回合结束后对你造成过伤害的角色A及其武将牌上的一个非锁定技B,令A的B失效。然后每轮游戏开始时,A依次视为对你使用X张【杀】(X为B失效状态下经过的完整轮数)。当你因这些【杀】受到伤害后,你令A恢复技能B。', - xindiaodu:"调度", - xindiaodu_info:"①每回合限一次,与你势力相同的角色使用装备牌时,其可以摸一张牌。②出牌阶段开始时,你可以获得与你势力相同的一名角色装备区内的一张牌,然后你可以将此牌交给另一名与你势力相同的其他角色。", - olhuanshi:'缓释', - olhuanshi_info:'一名角色的判定牌生效前,你可以令其观看你的手牌并选择你的一张牌,你打出此牌代替判定牌。然后你可以重铸任意张牌(每回合限重铸一次)。', - olhongyuan:'弘援', - olhongyuan_info:'每阶段限一次。当你一次性获得至少两张牌以后,你可以将至多两张牌交给等量名角色。', - olmingzhe:'明哲', - olmingzhe_info:'锁定技。当你于出牌阶段外失去红色牌后,你展示这些牌中所有背面朝上移动的牌(没有则不展示),然后摸一张牌。', - ahuinan:'阿会喃', - jueman:'蟨蛮', - jueman_info:'锁定技。一名角色的回合结束时,若本回合被使用过的基本牌数不小于2,且前两张基本牌的使用者:均不为你,你视为使用本回合被使用的第三张基本牌;有且仅有其中之一为你,你摸一张牌。', - ol_liuba:'OL刘巴', - ol_liuba_prefix:'OL', - oltongduo:'统度', - oltongduo_info:'准备阶段,你可以令一名角色交给你一张手牌,然后出牌阶段结束时,你将此牌置于牌堆顶。', - olzhubi:'铸币', - olzhubi_tag:'币', - olzhubi_info:'①出牌阶段限X次(X为你的体力上限)。你可以令一名角色重铸一张牌,以此法获得的牌称为“币”。②一名角色的结束阶段,若其有“币”,其观看牌堆底的五张牌,然后可以用任意“币”交换其中等量张牌。', - ol_furong:'傅肜', - olxiaosi:'效死', - olxiaosi_info:'出牌阶段限一次。你可以选择一名有手牌的其他角色并弃置一张基本牌。若其有可被弃置的基本牌,其弃置一张基本牌。然后你可以以任意顺序使用你与其以此法弃置的牌(无距离和次数限制)。最后若其未以此法弃置牌,你摸一张牌。', - zhangzhi:'张芝', - olbixin:'笔心', - olbixin_info:'一名角色的准备阶段或结束阶段,你可以声明一种牌的类型(每种类型限[1]次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸[3]张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。', - olximo:'洗墨', - olximo_info:'锁定技。当你发动〖笔心〗后,你移除其描述的前五个字符。若你已发动三次〖笔心〗,交换中括号中的两个数字,失去〖洗墨〗并获得〖飞白〗。', - olfeibai:'飞白', - olfeibai_info:'转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。', - olqizhou:'绮冑', - olqizhou_info:'锁定技。每个回合开始前,或当你装备区内的牌发生变化后,你失去所有因此技能获得过的额外技能,然后根据你装备区内的花色数获得对应的技能。至少一种:〖短兵〗、至少两种:〖英姿〗、至少三种:〖奋威〗、至少四种:〖澜江〗。', - olshanxi:'闪袭', - olshanxi_info:'出牌阶段限一次。你可以选择一名攻击范围内不包含你的其他角色,展示你与其的至多X张手牌(X为你的空装备栏数)。若这些牌中有【闪】,则你弃置这些【闪】,然后获得对方的一张未展示的牌。', - macheng:'马承', - olchenglie:'骋烈', - olchenglie_info:'当你使用【杀】选择目标后,你可以令至多两名角色也成为此牌目标,并展示牌堆顶的等同于目标数张牌,然后你可以将一张手牌与其中一张牌交换,将这些牌扣置于每名目标角色武将牌上,称为“骋烈”牌。此牌结算结束后:1.若有红色“骋烈”牌的角色:响应过此【杀】,其交给你一张牌;未响应此【杀】,其回复1点体力;2.有“骋烈”牌的角色将其“骋烈”牌置入弃牌堆。', - quhuang:'屈晃', - olqiejian:'切谏', - olqiejian_info:'当一名角色失去最后的手牌后,你可以摸一张牌,然后令其摸一张牌,你选择一项:1.弃置你或其场上的一张牌;2.你于本轮不能再对其发动此技能。', - olnishou:'泥首', - olnishou_info:'锁定技。当你装备区里的牌进入弃牌堆后,你选择一项:1.将这些牌中第一张能当【闪电】对你使用的牌当【闪电】使用;2.本阶段结束时,你与一名手牌数最少的角色交换手牌。', - zhanghua:'张华', - olbihun:'弼昏', - olbihun_info:'锁定技。当你使用牌指定其他角色为目标时,若你的手牌数大于手牌上限且若此牌的目标数:大于1,取消此目标;为1,其获得此牌。', - olchuanwu:'穿屋', - olchuanwu_info:'锁定技。当你造成或受到伤害后,你令武将牌上的前X个未失效的技能失效直到回合结束。然后你摸等同于你此次失效的技能数张牌(X为你的攻击范围)。', - oljianhe:'剑合', - oljianhe_info:'出牌阶段每名角色限一次。你可以重铸至少两张同名牌或至少两张装备牌,然后令一名角色选择一项:1.重铸等量张与你以此法重铸的牌类型相同的牌;2.受到你造成的1点雷电伤害。', - dongtuna:'董荼那', - oljianman:'鹣蛮', - oljianman_info:'锁定技。一名角色的回合结束时,若本回合被使用过的基本牌数不小于2,且前两张基本牌的使用者:均为你,你视为使用其中的一张牌;有且仅有其中之一为你,你弃置另一名使用者一张牌。', - maxiumatie:'马休马铁', - olkenshang:'垦伤', - olkenshang_info:'你可以将任意张牌当【杀】使用,然后你可以将此牌目标改为所有你攻击范围外的角色。此牌结算结束后,若此牌对应的实体牌数大于X,你摸X张牌(X为此牌造成过的伤害值),否则你失去一个技能。', - rekenshang:'垦伤', - rekenshang_info:'你可以将至少两张牌当【杀】使用,然后你可以将此牌目标改为等量名角色。此牌结算结束后,若此牌对应的实体牌数大于此牌造成过的伤害值,你摸一张牌。', - ol_zhujun:'OL朱儁', - ol_zhujun_prefix:'OL', - olcuipo:'摧破', - olcuipo_info:'锁定技。当你使用牌时,若此牌是你本回合使用的第X张牌(X为此牌牌名的字数),则:{若此牌为【杀】或伤害类锦囊牌,则此牌的伤害值基数+1,否则你摸一张牌}。', - ol_zhangyì:'OL张翼', - ol_zhangyì_prefix:'OL', - oldianjun:'殿军', - oldianjun_info:'锁定技。回合结束时,你受到1点无来源伤害,然后执行一个额外的出牌阶段。', - olkangrui:'亢锐', - olkangrui_info:'当一名角色于其回合内首次受到伤害后,你可以摸一张牌并选择一项:1.令其回复1点体力;2.令其于本回合下次造成的伤害+1。然后当其于本回合造成伤害时,其本回合手牌上限基数为0。', - wangguan:'王瓘', - olmiuyan:'谬焰', - olmiuyan_tag:'invisible', - olmiuyan_info:'转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的手牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。', - olshilu:'失路', - olshilu_info:'锁定技。当你受到伤害后,你摸X张牌(X为你的体力值且至多为5)。然后你展示攻击范围内一名角色的一张手牌,令此牌的牌名视为【杀】。', - ol_huban:'OL胡班', - ol_huban_prefix:'OL', - olhuiyun:'晖云', - olhuiyun_tag:'invisible', - olhuiyun_info:'每轮每项各限一次。你可以将一张牌当【火攻】使用。此牌结算结束后,你选择一项,令目标角色选择是否执行:1.使用展示的牌,然后重铸所有手牌;2.使用一张手牌,然后重铸展示牌;3.摸一张牌。', - sunhong:'孙弘', - olxianbi:'险诐', - olxianbi_info:'出牌阶段限一次。你可以选择一名角色,然后将手牌摸至或弃置至等同于其装备区里的牌数(至多摸五张),且当你因此弃置一张牌后,你随机获得弃牌堆中的另一张类型相同的牌。', - olzenrun:'谮润', - olzenrun_info:'每阶段限一次。当你摸牌时,你可以改为获得一名其他角色等量的牌,然后其选择一项:1.摸等量的牌;2.令你本局游戏不能再对其发动〖险诐〗和〖谮润〗。', - luoxian:'罗宪', - oldaili:'带砺', - oldaili_tag:'带砺', - oldaili_info:'一名角色的回合结束时,若你被展示过的手牌数为偶数,则你可以翻面,摸三张牌并展示之。', - zhangshiping:'张世平', - olhongji:'鸿济', - olhongji_info:'每轮每项各限一次。一名角色的准备阶段,若其手牌数最少/最多,你可以令其于本回合第一个摸牌阶段/出牌阶段后执行一个额外的摸牌阶段/出牌阶段(若其条件同时满足则只能选择一项)。', - olxinggu:'行贾', - olxinggu_info:'①游戏开始时,你将牌堆中的三张坐骑牌扣置于武将牌上。②结束阶段,你可以将一张〖行贾①〗牌置于一名其他角色的装备区,然后你从牌堆获得一张♦牌。', - lushi:'卢氏', - olzhuyan:'驻颜', - olzhuyan_info:'每名角色每项各限一次。结束阶段,你可以令一名角色将以下一项调整至与其上一个准备阶段结束后相同:1.体力值;2.手牌数(体力值至多失去至1,手牌数至多摸至5;若其未执行过准备阶段则改为游戏开始时)。', - olleijie:'雷劫', - olleijie_info:'准备阶段,你可以令一名角色判定,若结果为♠2~9,其受到2点雷电伤害,否则其摸两张牌。', - ol_liuyan:'OL刘焉', - ol_liuyan_prefix:'OL', - olpianan:'偏安', - olpianan_info:'锁定技。游戏开始或弃牌阶段结束时,你弃置所有不为【闪】的手牌(没有则不弃)。若你的手牌数小于体力值,你获得牌堆或弃牌堆中的前X张【闪】(X为你的体力值与手牌数的差)。', - olyinji:'殷积', - olyinji_info:'锁定技。结束阶段,若你的体力值不为唯一最大,你选择回复1点体力或加1点体力上限。', - olkuisi:'窥伺', - olkuisi_info:'锁定技。摸牌阶段开始时,你跳过此阶段,然后观看牌堆顶的四张牌并可以使用其中任意张。若你以此法使用的牌数不为2或3,你减1点体力上限。', - ol_wanglang:'OL王朗', - ol_wanglang_prefix:'OL', - oljici:'激词', - oljici_info:'当你的拼点牌亮出后,若点数不大于X,你可令点数+X并令〖鼓舌〗视为未发动过(X为你的“饶舌”标记数)。', - ol_mengda:'OL孟达', - ol_mengda_prefix:'OL', - olgoude:'苟得', - olgoude_info:'一名角色的回合结束时,若有与你势力相同的角色执行过以下项,则你可以执行这些角色未执行过的一项:1.摸一张牌;2.弃置一名角色的一张手牌;3.使用一张无对应实体牌的【杀】;4.变更势力。', - haopu:'郝普', - olzhenying:'镇荧', - olzhenying_info:'出牌阶段限两次。你可以选择一名手牌数不大于你的其他角色,你与其同时将手牌摸或弃置至至多两张。然后你与其中手牌数较少的角色视为对另一名角色使用一张【决斗】。', - ol_wenqin:'文钦', - olguangao:'犷骜', - olguangao_info:'当你/其他角色使用【杀】时,你/该角色可以额外指定一个目标/你为目标(有距离限制)。然后若你的手牌数为偶数,你摸一张牌并令此牌对任意目标无效(可不选)。', - olhuiqi:'彗企', - olhuiqi_info:'觉醒技。一名角色回合结束后,若你与其他两名角色于此回合成为过牌的目标,你获得〖偕举〗并获得一个额外的回合。', - olxieju:'偕举', - olxieju_info:'出牌阶段限一次。你可以令任意名本回合成为过牌的目标的角色依次视为使用一张【杀】。', - ol_zhouqun:'周群', - oltianhou:'天候', - oltianhou_info:'锁定技。准备阶段,你观看牌堆顶的一张牌,且可以用你的一张牌交换此牌。然后你展示牌堆顶的牌,令一名角色根据此牌的花色获得对应的技能直到你下个准备阶段开始:♠〖骤雨〗;♥〖烈暑〗;♣〖严霜〗;♦〖凝雾〗。', - olchenshuo:'谶说', - olchenshuo_info:'结束阶段,你可以展示一张手牌,然后展示牌堆顶的一张牌。若这两张牌类型/花色/点数/牌名字数中任一项相同且已展示的牌数小于3,则你重复此流程,然后获得所有所有展示牌。', - oltianhou_spade:'骤雨', - oltianhou_spade_miehuo:'骤雨', - oltianhou_spade_info:'锁定技。其他角色造成火属性伤害时,取消之;一名角色受到雷属性伤害后,所有与其座次相邻的角色失去1点体力。', - oltianhou_heart:'烈暑', - oltianhou_heart_info:'锁定技。其他角色的结束阶段开始时,若其体力值为全场最大,则其失去1点体力。', - oltianhou_club:'严霜', - oltianhou_club_info:'锁定技。其他角色的结束阶段开始时,若其体力值为全场最小,则其失去1点体力。', - oltianhou_diamond:'凝雾', - oltianhou_diamond_info:'锁定技。其他角色使用【杀】指定与其座次不相邻唯一目标时,则其判定。若判定结果的点数大于此【杀】,则此【杀】对其无效。', - duanjiong:'段颎', - olsaogu:'扫谷', - olsaogu_info:'转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。', - olcuorui:'挫锐', - olcuorui_info:'锁定技。①游戏开始时,你将手牌摸至场上存活人数张(至多摸至8张)。②当你成为延时锦囊牌的目标后,你跳过下个判定阶段。', - olmouzhu:'谋诛', - olmouzhu_info:'出牌阶段限一次,你可以令一名有手牌的其他角色交给你一张手牌。然后若其手牌数小于你,其视为使用一张【杀】或【决斗】。', - olyanhuo:'延祸', - olyanhuo_info:'当你死亡时,你可以弃置杀死你的角色至多X张牌(X为你的牌数)。', - olniluan:'逆乱', - olniluan_info:'体力值大于你的其他角色的结束阶段,若其本回合内使用过【杀】,则你可以将一张黑色牌当作【杀】对其使用(无距离限制)。', - olxiaoxi:'骁袭', - olxiaoxi_info:'一轮游戏开始时,你可以视为使用一张无距离限制的【杀】。', - ol_qianzhao:'牵招', - olweifu:'威抚', - olweifu_info:'出牌阶段,你可以弃置一张牌并判定。你本回合下次使用与结果类型相同的牌无距离限制,且可以额外指定一个目标。若你弃置的牌与判定牌类型相同,你摸一张牌。', - olkuansai:'款塞', - olkuansai_info:'每回合限一次,当一张牌指定第一个目标后,若目标数不小于你的体力值,你可以令其中一个目标选择一项:1.交给你一张牌;2.令你回复1点体力。', - ol_luyusheng:'OL陆郁生', - ol_luyusheng_prefix:'OL', - olcangxin:'藏心', - olcangxin_info:'锁定技。①当你每回合第一次受到伤害时,你观看牌堆底的三张牌并弃置其中任意张牌,然后此伤害-X。②摸牌阶段开始时,你展示牌堆底的三张牌,然后摸X张牌(X为其中红桃牌的数量)。', - olrunwei:'润微', - olrunwei_info:'其他角色的弃牌阶段开始时,若其已受伤,则你可以选择一项:①令其弃置一张牌,其本回合手牌上限+1;②令其摸一张牌,其本回合手牌上限-1。', - caoxi:'曹羲', - olgangshu:'刚述', - olgangshu_info:'①当你使用非基本牌结算结束后,你可以令以下一项数值+1(每项至多加至5):1.攻击范围;2.受〖刚述〗影响的下个摸牌阶段摸牌数;3.使用【杀】的次数上限。②当有牌被你抵消后,重置你〖刚述①〗增加的所有数值。', - oljianxuan:'谏旋', - oljianxuan_info:'当你受到伤害后,你可以令一名角色摸一张牌,然后若其手牌数等于你〖刚述①〗中的任意一项对应的数值,其重复此流程。', - ol_pengyang:'彭羕', - olxiaofan:'嚣翻', - olxiaofan_info:'当你需要使用不为【无懈可击】的牌时,你可以观看牌堆底的X+1张牌并使用其中的一张。此牌结算结束时,你依次弃置以下前X个区域中的所有牌:⒈判定区、⒉装备区、⒊手牌区(X为本回合你使用过的牌中包含的类型数)。', - oltuishi:'侻失', - oltuishi_info:'锁定技。①你不能使用【无懈可击】。②当你使用点数为字母的牌时,你令此牌无效并摸一张牌,且你对手牌数小于你的角色使用的下一张牌无距离和次数限制。③当你使用伤害类卡牌结算完毕后,若此牌为你本回合使用的第三张或以上未造成伤害的卡牌,则你令本回合〖器翻〗失效。', - ol_tw_zhangji:'张既', - skill_zhangji_A:'技能', - skill_zhangji_A_info:'出牌阶段限X次(X为你的体力值),当你使用牌指定一名其他角色为目标后,你可以观看其手牌,然后你选择一项:
              1.弃置其一张牌,然后若弃置的牌是能造成火焰伤害的牌,你摸一张牌。
              2.重铸其手牌中的所有【杀】和【决斗】。
              3.若其没有【闪】,你与其互相对对方造成1点伤害。', - skill_zhangji_B:'技能', - skill_zhangji_B_info:'当你受到1点伤害后,你可令一名手牌数小于体力上限的角色摸三张牌,然后其将手牌数弃置至其体力上限数;当你进入濒死状态时,你可令一名其他角色观看五张魏势力武将牌,其可以选择其中一张代替自己的武将牌(体力和体力上限不变)。', - ol_feiyi:'费祎', - yanru:'宴如', - yanru_info:'出牌阶段各限一次,若你的手牌数为:①奇数,你可以摸三张牌,然后弃置至少一半手牌(向下取整);②偶数,你可以弃置至少一半手牌,然后摸三张牌。', - hezhong:'和衷', - hezhong_info:'每回合每项限一次,当你的手牌数变为1后,你可以展示唯一手牌并摸一张牌,然后你选择一项:①本回合使用的下一张点数大于此牌的点数的普通锦囊牌额外结算一次;②本回合使用的下一张点数小于此牌的点数的普通锦囊牌额外结算一次。', - lvboshe:'吕伯奢', - olfushi:'缚豕', - olfushi_info:'①一名角色使用【杀】结算结束后,若你至其的距离不大于1,你将此【杀】对应的所有实体牌置于武将牌上。②当你需要使用一张【杀】时,你可以将任意张“缚豕”牌置入弃牌堆并摸等量的牌,视为使用一张【杀】并选择X项(X为你以此法重铸的牌数且至多为3):1.你为此【杀】额外指定一个目标;2.你选择此【杀】的一个目标角色,此牌对其造成的伤害-1;3.你选择此【杀】的一个目标角色,此【杀】对其造成的伤害+1。当此【杀】指定最后一个目标后,若此牌被选择的效果选项相邻且此牌的目标角色座位连续,则此【杀】不计入次数限制。', - oldongdao:'东道', - oldongdao_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:'锁定技。当你受到其他角色造成的伤害后或响应其他角色使用的牌时,你选择一项:①摸一张牌,然后交给其一张牌。②令其摸一张牌,然后其弃置两张牌。', - ol_liwan:'OL李婉', - ol_liwan_prefix:'OL', - ollianju:'联句', - ollianju_info:'结束阶段,你可以令一名其他角色获得你本回合使用的最后一张牌A对应的所有位于弃牌堆的实体牌并记录A的牌名,然后其下个结束阶段可以令你获得其本回合使用的最后一张牌B对应的所有位于弃牌堆的实体牌,然后若A与B的牌名相同,则你失去1点体力;若A与B的牌名不同,则你可以视为使用A。', - olsilv:'思闾', - olsilv_info:'锁定技,每回合每项限一次,当你获得或失去你发动〖联句〗记录的最后一次牌名的同名牌后,你展示这些牌,然后摸一张牌。', - xueji_old:'血祭', - xueji_old_info:'出牌阶段限一次,你可以弃置一张红色牌并对攻击范围内的至多X名角色各造成1点伤害(X为你已损失的体力值),然后这些角色各摸一张牌。', - oldhuxiao:'虎啸', - oldhuxiao_info:'锁定技,当你使用的【杀】被【闪】抵消后,你令此【杀】不计入使用次数。', - oldwuji:'武继', - oldwuji_info:'觉醒技,结束阶段,若你本回合造成了3点或更多伤害,你加1点体力上限并回复1点体力,并失去技能〖虎啸〗。', - olfeiyang:'飞扬', + luanfeng_info: + "限定技,一名角色进入濒死状态时,若其体力上限不小于你,你可令其回复至3点体力,恢复其被废除的装备栏,令其手牌补至6-X张(X为以此法恢复的装备栏数量)。若该角色是你,重置你因“游龙”使用过的牌名。", + reluanzhan: "乱战", + reluanzhan_add: "乱战", + reluanzhan_remove: "乱战", + reluanzhan_info: + "当你受到或造成伤害后,你获得一个“乱”。当你使用【杀】或黑色普通锦囊牌选择目标后,你可为此牌增加至多X个目标。当你使用这些牌指定第一个目标后,若此牌目标数小于X,则你移去X/2(向上取整)个“乱”。(X为“乱”数)", + zhuixi: "追摄", + zhuixi_info: "锁定技,你使用【杀】的次数上限+1。", + reduanbing: "短兵", + reduanbing_info: + "你使用【杀】选择目标后,可以为此【杀】增加一名距离为1的额外目标。你对距离为1的角色使用的【杀】需两张【闪】才能抵消。", + refenxun: "奋迅", + refenxun2: "奋迅", + refenxun_info: + "出牌阶段限一次,你可以选择一名其他角色,然后本回合你计算与其的距离视为1;结束阶段开始时,若你未对其造成过伤害,你弃一张牌。", + zongyu: "宗预", + zyqiao: "气傲", + zyqiao_info: + "每回合限两次。当你成为其他角色使用牌的目标后,你可以弃置其一张牌,然后你弃置一张牌。", + zyqiao_info_guozhan: + "每回合限两次。当你成为其他势力的角色使用牌的目标后,你可以弃置其一张牌,然后你弃置一张牌。", + chengshang: "承赏", + chengshang_info: + "当你于出牌阶段内使用的牌结算完成后,若此牌未造成过伤害且此牌的目标包含其他角色且你本阶段内未因〖承赏〗得到过牌,则你可以从牌堆中获得所有与此牌花色点数相同的牌。", + chengshang_info_guozhan: + "当你于出牌阶段内使用的牌结算完成后,若此牌未造成过伤害且此牌的目标包含其他角色且你本阶段内未因〖承赏〗得到过牌,则你可以从牌堆中获得所有与此牌花色点数相同的牌。", + panshu: "OL潘淑", + panshu_prefix: "OL", + weiyi: "威仪", + weiyi_info: + "每名角色限一次。当有角色受到伤害后,你可选择:①若其体力值不小于你,则其失去1点体力。②若其体力值不大于你且其已受伤,则其回复1点体力。", + jinzhi: "锦织", + jinzhi2: "锦织", + jinzhi_info: + "当你需要使用或打出一张基本牌时,你可弃置X+1张颜色相同的牌并摸一张牌,然后视为你使用或打出了此牌。(X为你于本轮内发动此技能的次数)", + yanxiao_card: "言笑", + yanxiao_global: "言笑", + yanxiao_card_info: "判定阶段开始时,你获得判定区内的所有牌。", + gz_huangzu: "黄祖", + huangzu: "OL黄祖", + huangzu_prefix: "OL", + wangong: "挽弓", + wangong2: "挽弓", + wangong_info: + "锁定技,当你使用基本牌时,你获得如下效果:当你使用下一张牌时,若此牌为【杀】,则此牌无次数和距离限制且伤害+1。", + huangchengyan: "OL黄承彦", + huangchengyan_prefix: "OL", + guanxu: "观虚", + guanxu_info: + "出牌阶段限一次,你可以观看一名其他角色的手牌,然后你可将其中一张手牌与牌堆顶五张牌中的一张交换。若如此做,你弃置其手牌中三张花色相同的牌。", + yashi: "雅士", + yashi_info: + "当你受到一次伤害后,你可选择一项:1. 令伤害来源的非锁定技无效直到其下个回合开始;2. 对一名其他角色发动〖观虚〗。", + olwuniang: "武娘", + olwuniang_info: + "每回合限一次,当你于回合内使用的【杀】结算完成后,若此【杀】对应的目标数为1,则你可以令目标角色选择是否对你使用使用【杀】。你于其选择结算完成后摸一张牌,且本回合内使用【杀】的次数上限+1。", + olxushen: "许身", + olxushen_info: + "限定技,当你进入濒死状态时,你可将体力回复至1点并获得技能〖镇南〗。然后若场上没有存活的“关索”,则你可以令一名其他男性角色选择是否将一张武将牌替换为“关索”。", + olzhennan: "镇南", + olzhennan2: "镇南", + olzhennan_info: + "【南蛮入侵】对你无效。出牌阶段限一次,你可以将任意张手牌当做【南蛮入侵】对等量的角色使用。", + gaogan: "高干", + juguan: "拒关", + juguan_backup: "拒关", + juguan_info: + "出牌阶段限一次,你可将一张手牌当【杀】或【决斗】使用。若受到此牌伤害的角色未在你的下回合开始前对你造成过伤害,你的下个摸牌阶段摸牌数+2。", + duxi: "杜袭", + quxi: "驱徙", + quxi_info: + "限定技。出牌阶段结束时,你可跳过下个弃牌阶段并选择两名手牌数不同的其他角色。你将武将牌翻至背面,令这两名角色中手牌数较少的角色获得另一名角色的一张牌并获得一枚“丰”,另一名角色获得一枚“歉”。拥有“丰”/“歉”的角色的摸牌阶段额定摸牌数+1/-1。拥有“丰”/“歉”的角色死亡时,或一轮游戏开始时,你可转移“丰”/“歉”。", + bixiong: "避凶", + bixiong2: "避凶", + bixiong_info: + "锁定技,当你于弃牌阶段弃置手牌后,其他角色不能使用与这些牌花色相同的牌指定你为目标直到你的下回合开始。", + fuwei: "扶危", + fuwei_info: + "每回合限一次。当你的牌被其他角色弃置或获得后,你可从牌堆中获得一张与此牌名称相同的牌(若没有则改为摸一张牌)。", + yuejian: "约俭", + yuejian_info: + "每回合限两次。当其他角色对你使用的牌A结算结束后,你可展示所有手牌。若牌A有花色且你的手牌中没有同花色的牌,则你获得牌A对应的所有实体牌。", + ol_dengzhi: "OL邓芝", + ol_dengzhi_prefix: "OL", + olxiuhao: "修好", + olxiuhao_info: + "每回合限一次。当你受到其他角色造成的伤害时,或其他角色受到你造成的伤害时,你可防止此伤害,然后令伤害来源摸两张牌。", + olsujian: "素俭", + olsujian_given: "已分配", + olsujian_info: + "锁定技。弃牌阶段开始前,你将此阶段的规则改为:{你选择一项:①将所有不为本回合得到的手牌分配给其他角色。②弃置这些手牌,然后弃置一名其他角色等量的牌}。", + ol_wangrong: "OL王荣", + ol_wangrong_prefix: "OL", + olfengzi: "丰姿", + olfengzi_info: + "出牌阶段限一次。当你使用有目标的基本牌或普通锦囊牌时,你可弃置一张与此牌类型相同的牌,然后令此牌结算两次。", + oljizhan: "吉占", + oljizhan_info: + "摸牌阶段开始时,你可以放弃摸牌。你亮出牌堆顶的一张牌,并猜测牌堆顶的下一张牌点数大于或小于此牌。若你猜对,你可继续重复此流程。然后你获得以此法展示的所有牌。", + olfusong: "赋颂", + olfusong_info: + "当你死亡时,你可以选择一名体力上限大于你的其他角色。其选择获得〖吉占〗或〖丰姿〗。", + zuofen: "左棻", + zhaosong: "诏颂", + zhaosong_info: + "一名其他角色的摸牌阶段结束时,若其没有因〖诏颂〗而获得的标记,则你可令其正面向上交给你一张手牌。根据此牌的类型,该角色获得对应的标记和效果:
              锦囊牌:“诔”标记。当拥有者进入濒死状态时,其可弃置所有“诔”,将体力回复至1点并摸一张牌。
              装备牌:“赋”标记。拥有者的出牌阶段开始时,其可弃置所有“赋”,弃置一名角色区域内的至多两张牌。
              基本牌:“颂”标记。当使用者使用仅指定一个目标的【杀】时,其可弃置“颂”,为此【杀】增加至多两个目标。", + lisi: "离思", + lisi_info: "当你于回合外使用的牌结算结束后,你可将其交给一名手牌数不大于你的其他角色。", + ol_yangyi: "杨仪", + oljuanxia: "狷狭", + oljuanxia_info: + "结束阶段,你可以选择一名其他角色。你依次视为对其使用至多三种单目标普通锦囊牌。然后其下回合结束时,可视为对你使用等量的【杀】。", + oldingcuo: "定措", + oldingcuo_info: + "每回合限一次。当你受到或造成伤害后,你可摸两张牌。若这两张牌颜色不同,则你弃置一张手牌。", + fengfangnv: "OL冯妤", + fengfangnv_prefix: "OL", + zhuangshu: "妆梳", + zhuangshu_info: + "①游戏开始时,你可将{【琼梳】,【犀梳】,【金梳】}中的一张牌置于装备区。②一名角色的回合开始时,若其宝物区为空,则你可以弃置一张牌,并根据此牌的类型,按如下关系将一张宝物牌置入该角色的装备区:{<基本牌,【琼梳】>,<锦囊牌,【犀梳】>,<装备牌,【金梳】>}。", + chuiti: "垂涕", + chuiti_info: + "每回合限一次。当你或拥有〖妆梳〗牌角色的牌因弃置而进入弃牌堆后,你可使用其中的一张牌。", + zhuangshu_basic: "琼梳", + zhuangshu_basic_bg: "琼", + zhuangshu_basic_info: + "当你受到伤害时,你可以弃置X张牌并防止此伤害(X为伤害值)。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。", + zhuangshu_trick: "犀梳", + zhuangshu_trick_bg: "犀", + zhuangshu_trick_info: + "判定阶段开始前,你可选择:①跳过此阶段。②跳过本回合的弃牌阶段。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。", + zhuangshu_equip: "金梳", + zhuangshu_equip_bg: "金", + zhuangshu_equip_info: + "锁定技。出牌阶段结束时,你将手牌摸至手牌上限(至多摸五张)。当此牌不因交换装备或移动至其他装备区而离开你的装备区后,销毁之。", + ol_dongzhao: "OL董昭", + ol_dongzhao_prefix: "OL", + olxianlve: "先略", + olxianlve_info: + "①主公的回合开始时,你可声明并记录一个锦囊牌的名称并移除先前的记录。②每回合限一次,其他角色使用〖先略〗记录过的锦囊牌后,你可摸两张牌并可以分配给任意其他角色,然后你可声明并记录一个锦囊牌的名称并移除先前的记录。", + olzaowang: "造王", + olzaowang2: "造王", + olzaowang_info: + "限定技。出牌阶段,你可以令一名角色加1点体力上限,回复1点体力并摸三张牌,且获得如下效果:主公死亡时,若其身份为忠臣,则其和主公交换身份牌;其死亡时,若其身份为反贼且伤害来源的身份为主公或忠臣,则以主忠胜利结束本局游戏。", + sp_ol_zhanghe: "SP张郃", + sp_ol_zhanghe_prefix: "SP", + spolzhouxuan: "周旋", + spolzhouxuan_info: + "①弃牌阶段开始时,你可将任意张置于武将牌上,称为“旋”(你至多拥有五张“旋”)。②当你使用牌时,你随机将一张“旋”置入弃牌堆,然后摸一张牌(若你的手牌数不为全场唯一最多则额外摸X张牌,X为“旋”数)。③出牌阶段结束时,你将所有“旋”置入弃牌堆。", + wuyan: "吾彦", + lanjiang: "澜疆", + lanjiang_info: + "结束阶段,你可以选择所有手牌数不小于你的角色。这些角色依次选择是否令你摸一张牌。然后你可以对其中一名手牌数等于你的角色造成1点伤害,随后令其中一名手牌数小于你的角色摸一张牌。", + ol_zhuling: "OL朱灵", + ol_zhuling_prefix: "OL", + jixian: "急陷", + jixian_info: + "摸牌阶段结束时,你可以选择一名满足以下至少一项条件的角色:⒈装备区内有防具牌;⒉拥有的普通技能数大于你;⒊体力值等于体力上限。你视为对其使用一张【杀】,然后摸X张牌(X为其于此【杀】结算前满足的条件数);若此【杀】未造成伤害,则你失去1点体力。", + ol_chendeng: "OL陈登", + ol_chendeng_prefix: "OL", + olfengji: "丰积", + olfengji_info: + "摸牌阶段开始时,你选择:⒈本回合摸牌阶段的额定摸牌数-1,且令一名其他角色下回合摸牌阶段的额定摸牌数+2;⒉本回合摸牌阶段的额定摸牌数+1。然后你选择:⒈本回合使用【杀】的次数上限-1,且令一名其他角色下回合使用【杀】的次数上限+2;⒉本回合使用【杀】的次数上限+1。", + tianyu: "田豫", + saodi: "扫狄", + saodi_info: + "当你使用【杀】或普通锦囊牌指定唯一其他角色为目标时,你可从逆时针方向和顺时针方向中选择一个你与其之间角色最少的方向。你令该方向下你与其之间的所有能成为此牌额外目标的角色均成为此牌的目标。", + zhuitao: "追讨", + zhuitao_info: + "①准备阶段,你可选择一名未被〖追讨〗记录过的其他角色。②你至所有〖追讨〗记录过的角色的距离-1。③当你对一名被〖追讨〗记录过的角色造成伤害时,你从〖追讨〗记录里移除该角色。", + fanjiangzhangda_ab: "范疆张达", + fanjiangzhangda: "范强张达", + yuanchou: "怨仇", + yuanchou_info: + "锁定技。当你使用黑色【杀】指定目标角色后或成为黑色【杀】的目标角色后,你令目标角色的防具技能无效直到此【杀】被抵消或造成伤害。", + juesheng: "决生", + juesheng_info: + "限定技。出牌阶段,你可视为使用一张【决斗】。当你因此【决斗】造成伤害时,你将伤害值改为X(X为目标角色本局游戏内使用过【杀】的数量且至少为1)且令目标角色获得此技能直到其下回合结束。", + qinghegongzhu: "清河公主", + zengou: "谮构", + zengou_info: + "当有角色使用【闪】时,若其在你的攻击范围内,则你可以弃置一张非基本牌或失去1点体力,然后取消此【闪】的目标并获得其对应的实体牌。", + qhzhangji: "长姬", + qhzhangji_info: + "一名角色的回合结束时,若你本回合内:造成过伤害,则你可以令其摸两张牌;受到过伤害,则你可以令其弃置两张牌。", + sp_menghuo: "SP孟获", + sp_menghuo_prefix: "SP", + spmanwang: "蛮王", + spmanwang_info: + "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前等量项:⒈获得〖叛侵〗。⒉摸一张牌。⒊回复1点体力。⒋摸两张牌并失去〖叛侵〗。", + sppanqin: "叛侵", + sppanqin_info: + "出牌阶段或弃牌阶段结束时,你可将你于本阶段内弃置且位于弃牌堆的所有牌当做【南蛮入侵】使用。然后若此牌被使用时对应的实体牌数不大于此牌的目标数,则你执行并移除〖蛮王〗中的最后一个选项。", + tengfanglan: "OL滕芳兰", + tengfanglan_prefix: "OL", + luochong: "落宠", + luochong_info: + "准备阶段开始时/当你于一回合内首次受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):⒈令一名角色回复1点体力。⒉令一名角色失去1点体力。⒊令一名角色弃置两张牌。⒋令一名角色摸两张牌。", + aichen: "哀尘", + aichen_info: + "锁定技。当你进入濒死状态时,若〖落宠〗中的剩余选项数大于1,则你选择移去〖落宠〗中的一个选项。", + weizi: "卫兹", + yuanzi: "援资", + yuanzi_info: + "每轮限一次。其他角色的准备阶段开始时,你可将所有手牌交给该角色。若如此做,当该角色于本回合内造成伤害后,若其手牌数不小于你,则你摸两张牌。", + liejie: "烈节", + liejie_info: + "当你受到伤害后,你可以弃置至多三张牌,摸等量的牌,然后可弃置伤害来源的至多X张牌(X为你以此法弃置的红色牌的数量)。", + ruiji: "OL芮姬", + ruiji_prefix: "OL", + qiaoli: "巧力", + qiaoli_info: + "出牌阶段各限一次,你可以将一张武器牌/非武器装备牌当作【决斗】使用。若此【决斗】对应的实体牌为武器牌,当你以此【决斗】对目标角色造成伤害后,你摸X张牌(X为此牌的攻击范围),且可以将其中任意张牌分配给其他角色;若此【决斗】对应的实体牌不为武器牌,此牌不可被响应,且你于结束阶段从牌堆中获得一张装备牌。", + qiaoli_given: "已分配", + qingliang: "清靓", + qingliang_info: + "每回合限一次,当你成为其他角色使用【杀】或伤害类锦囊牌的唯一目标时,你可展示所有手牌,然后选择一项:⒈你与其各摸一张牌,⒉取消此目标,然后弃置你手牌中一种花色的所有牌。", + chixueqingfeng: "赤血青锋", + chixueqingfeng2: "赤血青锋", + chixueqingfeng_info: + "锁定技,当你使用【杀】指定目标后,你令目标角色不能使用或打出手牌且防具技能无效直到此【杀】结算结束。", + wushuangfangtianji: "无双方天戟", + wushuangfangtianji_skill: "无双方天戟", + wushuangfangtianji_info: + "当你因执行【杀】的效果而造成伤害后,你可选择一项:⒈摸一张牌;⒉弃置目标角色的一张牌。", + guilongzhanyuedao: "鬼龙斩月刀", + guilongzhanyuedao_info: "锁定技,你使用的红色【杀】不可被响应。", + bintieshuangji: "镔铁双戟", + bintieshuangji_skill: "镔铁双戟", + bintieshuangji_info: + "当你使用的【杀】被抵消后,你可失去1点体力。获得此【杀】对应的所有实体牌,摸一张牌,且本回合使用【杀】的次数上限+1。", + linglongshimandai: "玲珑狮蛮带", + linglongshimandai_info: + "当你成为其他角色使用的牌的唯一目标后,你可以进行判定。若判定结果为♥,则此牌对你无效。", + linglongshimandai_skill: "玲珑狮蛮带", + hongmianbaihuapao_skill: "红棉百花袍", + hongmianbaihuapao: "红棉百花袍", + hongmianbaihuapao_info: "锁定技,当你受到属性伤害时,防止此伤害。", + qimenbagua: "奇门八卦", + qimenbagua_info: "锁定技,【杀】对你无效。", + guofengyupao: "国风玉袍", + guofengyupao_info: "锁定技,你不是其他角色使用普通锦囊牌的合法目标。", + shufazijinguan: "束发紫金冠", + shufazijinguan_skill: "束发紫金冠", + shufazijinguan_info: "准备阶段,你可以对一名其他角色造成1点伤害。", + sanlve: "三略", + sanlve_skill: "三略", + sanlve_info: "锁定技。你的攻击范围+1。你的手牌上限+1。你使用【杀】的次数上限+1。", + zhaogujing: "照骨镜", + zhaogujing_skill: "照骨镜", + zhaogujing_info: + "出牌阶段结束时,你可展示手牌中的一张基本牌或普通锦囊牌,然后你视为使用一张牌名和属性与此牌相同的牌。", + xuwangzhimian: "虚妄之冕", + xuwangzhimian_info: "锁定技,摸牌阶段,你令额定摸牌数+2;你的手牌上限-1。", + ol_puyuan: "OL蒲元", + ol_puyuan_prefix: "OL", + olshengong: "神工", + olshengong_info: + "出牌阶段每项限一次。你可以弃置一张武器牌/防具牌/其他装备牌,并发起一次“锻造”。然后你从锻造结果中选择一张牌,置于一名角色的装备区内(可替换原装备)。当有因你发动〖神工〗而加入游戏的牌进入弃牌堆后,你将此牌移出游戏,然后你于当前回合结束后摸一张牌。", + olqisi: "奇思", + olqisi_info: + "①游戏开始时,你获得两张副类别不同的牌,并将这些牌置入你的装备区。②摸牌阶段开始时,你可以少摸一张牌并声明一种装备牌的副类别,然后从牌堆或弃牌堆中获得一张该副类别的牌。", + olzhuiji: "追击", + olzhuiji_info: + "锁定技。①你至体力值不大于你的角色的距离为1。②当你使用【杀】指定距离为1的角色为目标后,你令其选择一项:⒈弃置一张牌。⒉重铸装备区内的所有牌。", + zhaoyǎn: "OL赵俨", + zhaoyǎn_prefix: "OL", + tongxie: "同协", + tongxie_info: + "出牌阶段开始时,你可以选择包括你在内的至多三名角色(你与这些角色均称为“同协角色”)。这些角色中手牌数唯一最少的角色摸一张牌,且你获得如下效果直到你下回合开始:①当有“同协角色”对唯一目标角色使用的【杀】结算结束后,其他“同协角色”可以依次对目标角色使用一张【杀】(无距离和次数限制,且不能再触发此效果)。②当有“同协角色”受到伤害时,其他“同协角色”(本回合内失去过体力的角色除外)可以防止此伤害,失去1点体力。", + jin_zhouchu: "周处", + shanduan: "善断", + shanduan_info: + "锁定技。①摸牌/出牌/弃牌阶段开始时,你为本回合摸牌阶段摸牌数/攻击范围和使用【杀】的限制次数/手牌上限的默认值从数组R=[1,2,3,4]中分配数值。②当你于回合外受到伤害后,你令下回合〖善断①〗以此法分配的数值集合R中的最小值+1。", + yilie: "义烈", + yilie_info: "每轮每种牌名限一次。你可以将两张颜色相同的手牌当做任意一种基本牌使用。", + caoxiancaohua: "曹宪曹华", + huamu: "化木", + huamu_info: + "当你使用手牌后,若此牌和本回合内上一张被使用的牌颜色不同,则你可以将此牌对应的所有{位于处理区或装备区}的实体牌置于你的武将牌上。这些牌中的黑色牌称为“灵杉”,红色牌称为“玉树”。", + qianmeng: "前盟", + qianmeng_info: + "锁定技。当有牌移动事件结算结束后,若有角色的“灵杉”和“玉树”数量发生了变化,且二者数量相等或有一项为0,则你摸一张牌。", + liangyuan: "良缘", + liangyuan_info: + "每轮每项各限一次。你可以将场上所有的“灵杉”/“玉树”置于处理区,然后将这些牌当做【酒】/【桃】使用。", + jisi: "羁肆", + jisi_info: + "限定技。准备阶段,你可以令一名其他角色获得你武将牌上的一个已发动过的其他技能。然后你弃置所有手牌,并视为对其使用一张【杀】(无距离关系的限制)。", + huojun: "OL霍峻", + huojun_prefix: "OL", + qiongshou: "穷守", + qiongshou_info: "锁定技。①游戏开始时,你废除所有装备栏并摸四张牌。②你的手牌上限+4。", + fenrui: "奋锐", + fenrui_info: + "结束阶段,你可以弃置一张牌并恢复一个装备栏。系统检索一张对应的装备牌,你使用之。然后你可以选择一名装备区内牌数小于你的其他角色,对其造成X点伤害(X为你与其装备区内的牌数之差,且每局限一次)。", + wangyan: "王衍", + yangkuang: "阳狂", + yangkuang_info: + "当你回复体力后,若你的体力值等于体力上限,则你可以视为使用一张【酒】,然后当前回合角色摸一张牌,你摸一张牌。", + cihuang: "雌黄", + cihuang_info: + "当有牌被抵消后,若此牌的目标数为1且此牌的使用者A为当前回合角色,则你可以将一张牌当做一张你本轮内未使用过的属性【杀】或单目标锦囊牌对A使用(不可被响应)。", + sanku: "三窟", + sanku_info: + "锁定技。①当你进入濒死状态时,你减1点体力上限,然后将体力回复至体力上限。②当你加体力上限前,取消之。", + dengzhong: "邓忠", + dzkanpo: "勘破", + dzkanpo_info: + "①当你因执行【杀】的效果而造成伤害后,你可以观看目标角色的手牌,然后获得其中一张与此【杀】花色相同的牌。②每回合限一次,你可以将一张手牌当做【杀】使用。", + dzgengzhan: "更战", + dzgengzhan_info: + "①其他角色的出牌阶段限一次,当有【杀】因弃置而进入弃牌堆后,你可以获得这些【杀】。②其他角色的结束阶段,若其本回合内未使用过【杀】,则你下个出牌阶段使用【杀】的次数上限+1。", + xiahouxuan: "夏侯玄", + olhuanfu: "宦浮", + olhuanfu_info: + "当你使用【杀】指定第一个目标后,或成为【杀】的目标后,你可以弃置X张牌(X∈[1, 你的体力上限])。此【杀】结算结束后,若此【杀】累计因执行效果而造成的伤害值等于X,则你摸2X张牌。", + olqingyi: "清议", + olqingyi_info: + "①出牌阶段限一次,你可以选择至多两名有牌的其他角色。你和这些角色同时弃置一张牌,然后若这些牌类型均相同,则你重复此流程。②结束阶段开始时,若你本回合内发动〖清议①〗弃置的牌包含两种颜色,则你获得每种颜色的牌各一张。", + olzeyue: "迮阅", + olzeyue_info: + "限定技。准备阶段,你可以选择一名于你的上个回合结束后对你造成过伤害的角色A及其武将牌上的一个非锁定技B,令A的B失效。然后每轮游戏开始时,A依次视为对你使用X张【杀】(X为B失效状态下经过的完整轮数)。当你因这些【杀】受到伤害后,你令A恢复技能B。", + xindiaodu: "调度", + xindiaodu_info: + "①每回合限一次,与你势力相同的角色使用装备牌时,其可以摸一张牌。②出牌阶段开始时,你可以获得与你势力相同的一名角色装备区内的一张牌,然后你可以将此牌交给另一名与你势力相同的其他角色。", + olhuanshi: "缓释", + olhuanshi_info: + "一名角色的判定牌生效前,你可以令其观看你的手牌并选择你的一张牌,你打出此牌代替判定牌。然后你可以重铸任意张牌(每回合限重铸一次)。", + olhongyuan: "弘援", + olhongyuan_info: "每阶段限一次。当你一次性获得至少两张牌以后,你可以将至多两张牌交给等量名角色。", + olmingzhe: "明哲", + olmingzhe_info: + "锁定技。当你于出牌阶段外失去红色牌后,你展示这些牌中所有背面朝上移动的牌(没有则不展示),然后摸一张牌。", + ahuinan: "阿会喃", + jueman: "蟨蛮", + jueman_info: + "锁定技。一名角色的回合结束时,若本回合被使用过的基本牌数不小于2,且前两张基本牌的使用者:均不为你,你视为使用本回合被使用的第三张基本牌;有且仅有其中之一为你,你摸一张牌。", + ol_liuba: "OL刘巴", + ol_liuba_prefix: "OL", + oltongduo: "统度", + oltongduo_info: + "准备阶段,你可以令一名角色交给你一张手牌,然后出牌阶段结束时,你将此牌置于牌堆顶。", + olzhubi: "铸币", + olzhubi_tag: "币", + olzhubi_info: + "①出牌阶段限X次(X为你的体力上限)。你可以令一名角色重铸一张牌,以此法获得的牌称为“币”。②一名角色的结束阶段,若其有“币”,其观看牌堆底的五张牌,然后可以用任意“币”交换其中等量张牌。", + ol_furong: "傅肜", + olxiaosi: "效死", + olxiaosi_info: + "出牌阶段限一次。你可以选择一名有手牌的其他角色并弃置一张基本牌。若其有可被弃置的基本牌,其弃置一张基本牌。然后你可以以任意顺序使用你与其以此法弃置的牌(无距离和次数限制)。最后若其未以此法弃置牌,你摸一张牌。", + zhangzhi: "张芝", + olbixin: "笔心", + olbixin_info: + "一名角色的准备阶段或结束阶段,你可以声明一种牌的类型(每种类型限[1]次),并选择一种你本轮未使用过且有合法目标的的基本牌。你摸[3]张牌,然后若你有此类型的手牌,你将所有此类型的手牌当此基本牌使用。", + olximo: "洗墨", + olximo_info: + "锁定技。当你发动〖笔心〗后,你移除其描述的前五个字符。若你已发动三次〖笔心〗,交换中括号中的两个数字,失去〖洗墨〗并获得〖飞白〗。", + olfeibai: "飞白", + olfeibai_info: + "转换技,锁定技。阴:当你因执行你使用的非黑色牌的效果而造成伤害时,此伤害值+1;阳:当你因执行你使用的非红色牌的效果而回复体力时,此回复值+1。", + olqizhou: "绮冑", + olqizhou_info: + "锁定技。每个回合开始前,或当你装备区内的牌发生变化后,你失去所有因此技能获得过的额外技能,然后根据你装备区内的花色数获得对应的技能。至少一种:〖短兵〗、至少两种:〖英姿〗、至少三种:〖奋威〗、至少四种:〖澜江〗。", + olshanxi: "闪袭", + olshanxi_info: + "出牌阶段限一次。你可以选择一名攻击范围内不包含你的其他角色,展示你与其的至多X张手牌(X为你的空装备栏数)。若这些牌中有【闪】,则你弃置这些【闪】,然后获得对方的一张未展示的牌。", + macheng: "马承", + olchenglie: "骋烈", + olchenglie_info: + "当你使用【杀】选择目标后,你可以令至多两名角色也成为此牌目标,并亮出牌堆顶的等同于目标数张牌,然后你可以将一张手牌与其中一张牌交换,将这些牌扣置于每名目标角色武将牌上,称为“骋烈”牌。此牌结算结束后:1.若有红色“骋烈”牌的角色:响应过此【杀】,其交给你一张牌;未响应此【杀】,其回复1点体力;2.有“骋烈”牌的角色将其“骋烈”牌置入弃牌堆。", + quhuang: "屈晃", + olqiejian: "切谏", + olqiejian_info: + "当一名角色失去最后的手牌后,你可以摸一张牌,然后令其摸一张牌,你选择一项:1.弃置你或其场上的一张牌;2.你于本轮不能再对其发动此技能。", + olnishou: "泥首", + olnishou_info: + "锁定技。当你装备区里的牌进入弃牌堆后,你选择一项:1.将这些牌中第一张能当【闪电】对你使用的牌当【闪电】使用;2.本阶段结束时,你与一名手牌数最少的角色交换手牌。", + zhanghua: "张华", + olbihun: "弼昏", + olbihun_info: + "锁定技。当你使用牌指定其他角色为目标时,若你的手牌数大于手牌上限且若此牌的目标数:大于1,取消此目标;为1,其获得此牌。", + olchuanwu: "穿屋", + olchuanwu_info: + "锁定技。当你造成或受到伤害后,你令武将牌上的前X个未失效的技能失效直到回合结束。然后你摸等同于你此次失效的技能数张牌(X为你的攻击范围)。", + oljianhe: "剑合", + oljianhe_info: + "出牌阶段每名角色限一次。你可以重铸至少两张同名牌或至少两张装备牌,然后令一名角色选择一项:1.重铸等量张与你以此法重铸的牌类型相同的牌;2.受到你造成的1点雷电伤害。", + dongtuna: "董荼那", + oljianman: "鹣蛮", + oljianman_info: + "锁定技。一名角色的回合结束时,若本回合被使用过的基本牌数不小于2,且前两张基本牌的使用者:均为你,你视为使用其中的一张牌;有且仅有其中之一为你,你弃置另一名使用者一张牌。", + maxiumatie: "马休马铁", + olkenshang: "垦伤", + olkenshang_info: + "你可以将任意张牌当【杀】使用,然后你可以将此牌目标改为所有你攻击范围外的角色。此牌结算结束后,若此牌对应的实体牌数大于X,你摸X张牌(X为此牌造成过的伤害值),否则你失去一个技能。", + rekenshang: "垦伤", + rekenshang_info: + "你可以将至少两张牌当【杀】使用,然后你可以将此牌目标改为等量名角色。此牌结算结束后,若此牌对应的实体牌数大于此牌造成过的伤害值,你摸一张牌。", + ol_zhujun: "OL朱儁", + ol_zhujun_prefix: "OL", + olcuipo: "摧破", + olcuipo_info: + "锁定技。当你使用牌时,若此牌是你本回合使用的第X张牌(X为此牌牌名的字数),则:{若此牌为【杀】或伤害类锦囊牌,则此牌的伤害值基数+1,否则你摸一张牌}。", + ol_zhangyì: "OL张翼", + ol_zhangyì_prefix: "OL", + oldianjun: "殿军", + oldianjun_info: "锁定技。回合结束时,你受到1点无来源伤害,然后执行一个额外的出牌阶段。", + olkangrui: "亢锐", + olkangrui_info: + "当一名角色于其回合内首次受到伤害后,你可以摸一张牌并选择一项:1.令其回复1点体力;2.令其于本回合下次造成的伤害+1。然后当其于本回合造成伤害时,其本回合手牌上限基数为0。", + wangguan: "王瓘", + olmiuyan: "谬焰", + olmiuyan_tag: "invisible", + olmiuyan_info: + "转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的手牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。", + olshilu: "失路", + olshilu_info: + "锁定技。当你受到伤害后,你摸X张牌(X为你的体力值且至多为5)。然后你展示攻击范围内一名角色的一张手牌,令此牌的牌名视为【杀】。", + ol_huban: "OL胡班", + ol_huban_prefix: "OL", + olhuiyun: "晖云", + olhuiyun_tag: "invisible", + olhuiyun_info: + "每轮每项各限一次。你可以将一张牌当【火攻】使用。此牌结算结束后,你选择一项,令目标角色选择是否执行:1.使用展示的牌,然后重铸所有手牌;2.使用一张手牌,然后重铸展示牌;3.摸一张牌。", + sunhong: "孙弘", + olxianbi: "险诐", + olxianbi_info: + "出牌阶段限一次。你可以选择一名角色,然后将手牌摸至或弃置至等同于其装备区里的牌数(至多摸五张),且当你因此弃置一张牌后,你随机获得弃牌堆中的另一张类型相同的牌。", + olzenrun: "谮润", + olzenrun_info: + "每阶段限一次。当你摸牌时,你可以改为获得一名其他角色等量的牌,然后其选择一项:1.摸等量的牌;2.令你本局游戏不能再对其发动〖险诐〗和〖谮润〗。", + luoxian: "罗宪", + oldaili: "带砺", + oldaili_tag: "带砺", + oldaili_info: + "一名角色的回合结束时,若你被展示过的手牌数为偶数,则你可以翻面,摸三张牌并展示之。", + zhangshiping: "张世平", + olhongji: "鸿济", + olhongji_info: + "每轮每项各限一次。一名角色的准备阶段,若其手牌数最少/最多,你可以令其于本回合第一个摸牌阶段/出牌阶段后执行一个额外的摸牌阶段/出牌阶段(若其条件同时满足则只能选择一项)。", + olxinggu: "行贾", + olxinggu_info: + "①游戏开始时,你将牌堆中的三张坐骑牌扣置于武将牌上。②结束阶段,你可以将一张〖行贾①〗牌置于一名其他角色的装备区,然后你从牌堆获得一张♦牌。", + lushi: "卢氏", + olzhuyan: "驻颜", + olzhuyan_info: + "每名角色每项各限一次。结束阶段,你可以令一名角色将以下一项调整至与其上一个结束阶段结束后相同:1.体力值;2.手牌数(体力值至多失去至1,手牌数至多摸至5;若其未执行过准备阶段则改为游戏开始时)。", + olleijie: "雷劫", + olleijie_info: + "准备阶段,你可以令一名角色判定,若结果为♠2~9,其受到2点雷电伤害,否则其摸两张牌。", + releijie: "雷劫", + releijie_info: + "出牌阶段限一次,你可以令一名角色判定,若结果为黑桃2~9,则你视为依次对其使用两张雷【杀】,否则其摸两张牌。", + ol_liuyan: "OL刘焉", + ol_liuyan_prefix: "OL", + olpianan: "偏安", + olpianan_info: + "锁定技。游戏开始或弃牌阶段结束时,你弃置所有不为【闪】的手牌(没有则不弃)。若你的手牌数小于体力值,你获得牌堆或弃牌堆中的前X张【闪】(X为你的体力值与手牌数的差)。", + olyinji: "殷积", + olyinji_info: "锁定技。结束阶段,若你的体力值不为唯一最大,你选择回复1点体力或加1点体力上限。", + olkuisi: "窥伺", + olkuisi_info: + "锁定技。摸牌阶段开始时,你跳过此阶段,然后观看牌堆顶的四张牌并可以使用其中任意张。若你以此法使用的牌数不为2或3,你减1点体力上限。", + ol_wanglang: "OL王朗", + ol_wanglang_prefix: "OL", + oljici: "激词", + oljici_info: + "当你的拼点牌亮出后,若点数不大于X,你可令点数+X并令〖鼓舌〗视为未发动过(X为你的“饶舌”标记数)。", + ol_mengda: "OL孟达", + ol_mengda_prefix: "OL", + olgoude: "苟得", + olgoude_info: + "一名角色的回合结束时,若有与你势力相同的角色执行过以下项,则你可以执行这些角色未执行过的一项:1.摸一张牌;2.弃置一名角色的一张手牌;3.使用一张无对应实体牌的【杀】;4.变更势力。", + haopu: "郝普", + olzhenying: "镇荧", + olzhenying_info: + "出牌阶段限两次。你可以选择一名手牌数不大于你的其他角色,你与其同时将手牌摸或弃置至至多两张。然后你与其中手牌数较少的角色视为对另一名角色使用一张【决斗】。", + ol_wenqin: "文钦", + olguangao: "犷骜", + olguangao_info: + "当你/其他角色使用【杀】时,你/该角色可以额外指定一个目标/你为目标(有距离限制)。然后若你的手牌数为偶数,你摸一张牌并令此牌对任意目标无效(可不选)。", + olhuiqi: "彗企", + olhuiqi_info: + "觉醒技。一名角色回合结束后,若你与其他两名角色于此回合成为过牌的目标,你获得〖偕举〗并获得一个额外的回合。", + olxieju: "偕举", + olxieju_info: "出牌阶段限一次。你可以令任意名本回合成为过牌的目标的角色依次视为使用一张【杀】。", + ol_zhouqun: "周群", + oltianhou: "天候", + oltianhou_info: + "锁定技。准备阶段,你观看牌堆顶的一张牌,且可以用你的一张牌交换此牌。然后你亮出牌堆顶的牌,令一名角色根据此牌的花色获得对应的技能直到你下个准备阶段开始:♠〖骤雨〗;♥〖烈暑〗;♣〖严霜〗;♦〖凝雾〗。", + olchenshuo: "谶说", + olchenshuo_info: + "结束阶段,你可以展示一张手牌,然后亮出牌堆顶的一张牌。若这两张牌类型/花色/点数/牌名字数中任一项相同且已展示的牌数小于3,则你重复此流程,然后获得所有所有展示牌。", + oltianhou_spade: "骤雨", + oltianhou_spade_miehuo: "骤雨", + oltianhou_spade_info: + "锁定技。其他角色造成火属性伤害时,取消之;一名角色受到雷属性伤害后,所有与其座次相邻的角色失去1点体力。", + oltianhou_heart: "烈暑", + oltianhou_heart_info: "锁定技。其他角色的结束阶段开始时,若其体力值为全场最大,则其失去1点体力。", + oltianhou_club: "严霜", + oltianhou_club_info: "锁定技。其他角色的结束阶段开始时,若其体力值为全场最小,则其失去1点体力。", + oltianhou_diamond: "凝雾", + oltianhou_diamond_info: + "锁定技。其他角色使用【杀】指定与其座次不相邻唯一目标时,则其判定。若判定结果的点数大于此【杀】,则此【杀】对其无效。", + duanjiong: "段颎", + olsaogu: "扫谷", + olsaogu_info: + "转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。", + olcuorui: "挫锐", + olcuorui_info: + "锁定技。①游戏开始时,你将手牌摸至场上存活人数张(至多摸至8张)。②当你成为延时锦囊牌的目标后,你跳过下个判定阶段。", + olmouzhu: "谋诛", + olmouzhu_info: + "出牌阶段限一次,你可以令一名有手牌的其他角色交给你一张手牌。然后若其手牌数小于你,其视为使用一张【杀】或【决斗】。", + olyanhuo: "延祸", + olyanhuo_info: "当你死亡时,你可以弃置杀死你的角色至多X张牌(X为你的牌数)。", + olniluan: "逆乱", + olniluan_info: + "体力值大于你的其他角色的结束阶段,若其本回合内使用过【杀】,则你可以将一张黑色牌当作【杀】对其使用(无距离限制)。", + olxiaoxi: "骁袭", + olxiaoxi_info: "一轮游戏开始时,你可以视为使用一张无距离限制的【杀】。", + ol_qianzhao: "牵招", + olweifu: "威抚", + olweifu_info: + "出牌阶段,你可以弃置一张牌并判定。你本回合下次使用与结果类型相同的牌无距离限制,且可以额外指定一个目标。若你弃置的牌与判定牌类型相同,你摸一张牌。", + olkuansai: "款塞", + olkuansai_info: + "每回合限一次,当一张牌指定第一个目标后,若目标数不小于你的体力值,你可以令其中一个目标选择一项:1.交给你一张牌;2.令你回复1点体力。", + ol_luyusheng: "OL陆郁生", + ol_luyusheng_prefix: "OL", + olcangxin: "藏心", + olcangxin_info: + "锁定技。①当你每回合第一次受到伤害时,你观看牌堆底的三张牌并弃置其中任意张牌,然后此伤害-X。②摸牌阶段开始时,你亮出牌堆底的三张牌,然后摸X张牌(X为其中红桃牌的数量)。", + olrunwei: "润微", + olrunwei_info: + "其他角色的弃牌阶段开始时,若其已受伤,则你可以选择一项:①令其弃置一张牌,其本回合手牌上限+1;②令其摸一张牌,其本回合手牌上限-1。", + caoxi: "曹羲", + olgangshu: "刚述", + olgangshu_info: + "①当你使用非基本牌结算结束后,你可以令以下一项数值+1(每项至多加至5):1.攻击范围;2.受〖刚述〗影响的下个摸牌阶段摸牌数;3.使用【杀】的次数上限。②当有牌被你抵消后,重置你〖刚述①〗增加的所有数值。", + oljianxuan: "谏旋", + oljianxuan_info: + "当你受到伤害后,你可以令一名角色摸一张牌,然后若其手牌数等于你〖刚述①〗中的任意一项对应的数值,其重复此流程。", + ol_pengyang: "彭羕", + olxiaofan: "嚣翻", + olxiaofan_info: + "当你需要使用不为【无懈可击】的牌时,你可以观看牌堆底的X+1张牌并使用其中的一张。此牌结算结束时,你依次弃置以下前X个区域中的所有牌:⒈判定区、⒉装备区、⒊手牌区(X为本回合你使用过的牌中包含的类型数)。", + oltuishi: "侻失", + oltuishi_info: + "锁定技。①你不能使用【无懈可击】。②当你使用点数为字母的牌时,你令此牌无效并摸一张牌,且你对手牌数小于你的角色使用的下一张牌无距离和次数限制。③当你使用伤害类卡牌结算完毕后,若此牌为你本回合使用的第三张或以上未造成伤害的卡牌,则你令〖器翻〗于本回合失效。", + ol_tw_zhangji: "张既", + skill_zhangji_A: "技能", + skill_zhangji_A_info: + "出牌阶段限X次(X为你的体力值),当你使用牌指定一名其他角色为目标后,你可以观看其手牌,然后你选择一项:
              1.弃置其一张牌,然后若弃置的牌是能造成火焰伤害的牌,你摸一张牌。
              2.重铸其手牌中的所有【杀】和【决斗】。
              3.若其没有【闪】,你与其互相对对方造成1点伤害。", + skill_zhangji_B: "技能", + skill_zhangji_B_info: + "当你受到1点伤害后,你可令一名手牌数小于体力上限的角色摸三张牌,然后其将手牌数弃置至其体力上限数;当你进入濒死状态时,你可令一名其他角色观看五张魏势力武将牌,其可以选择其中一张代替自己的武将牌(体力和体力上限不变)。", + ol_feiyi: "费祎", + yanru: "宴如", + yanru_info: + "出牌阶段各限一次,若你的手牌数为:①奇数,你可以摸三张牌,然后弃置至少一半手牌(向下取整);②偶数,你可以弃置至少一半手牌,然后摸三张牌。", + hezhong: "和衷", + hezhong_info: + "每回合每项限一次,当你的手牌数变为1后,你可以展示唯一手牌并摸一张牌,然后你选择一项:①本回合使用的下一张点数大于此牌的点数的普通锦囊牌额外结算一次;②本回合使用的下一张点数小于此牌的点数的普通锦囊牌额外结算一次。", + lvboshe: "吕伯奢", + olfushi: "缚豕", + olfushi_info: + "①一名角色使用【杀】结算结束后,若你至其的距离不大于1,你将此【杀】对应的所有实体牌置于武将牌上。②当你需要使用一张【杀】时,你可以将任意张“缚豕”牌置入弃牌堆并摸等量的牌,视为使用一张【杀】并选择X项(X为你以此法重铸的牌数且至多为3):1.你为此【杀】额外指定一个目标;2.你选择此【杀】的一个目标角色,此牌对其造成的伤害-1;3.你选择此【杀】的一个目标角色,此【杀】对其造成的伤害+1。当此【杀】指定最后一个目标后,若此牌被选择的效果选项相邻且此牌的目标角色座位连续,则此【杀】不计入次数限制。", + oldongdao: "东道", + oldongdao_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: + "锁定技。当你受到其他角色造成的伤害后或响应其他角色使用的牌时,你选择一项:①摸一张牌,然后交给其一张牌。②令其摸一张牌,然后其弃置两张牌。", + ol_liwan: "OL李婉", + ol_liwan_prefix: "OL", + ollianju: "联句", + ollianju_info: + "结束阶段,你可以令一名其他角色获得你本回合使用的最后一张牌A对应的所有位于弃牌堆的实体牌并记录A的牌名,然后其下个结束阶段可以令你获得其本回合使用的最后一张牌B对应的所有位于弃牌堆的实体牌,然后若A与B的牌名相同,则你失去1点体力;若A与B的牌名不同,则你可以视为使用A。", + olsilv: "思闾", + olsilv_info: + "锁定技,每回合每项限一次,当你获得或失去你发动〖联句〗记录的最后一次牌名的同名牌后,你展示这些牌,然后摸一张牌。", + xueji_old: "血祭", + xueji_old_info: + "出牌阶段限一次,你可以弃置一张红色牌并对攻击范围内的至多X名角色各造成1点伤害(X为你已损失的体力值),然后这些角色各摸一张牌。", + oldhuxiao: "虎啸", + oldhuxiao_info: "锁定技,当你使用的【杀】被【闪】抵消后,你令此【杀】不计入使用次数。", + oldwuji: "武继", + oldwuji_info: + "觉醒技,结束阶段,若你本回合造成了3点或更多伤害,你加1点体力上限并回复1点体力,并失去技能〖虎啸〗。", + olfeiyang: "飞扬", //olfeiyang_info:'限定技。准备阶段,你可以弃置两张牌,然后弃置判定区的一张牌。', - olfeiyang_info:'准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌。', - caoyu:'曹宇', - olgongjie:'恭节', - olgongjie_info:'每轮的首个回合开始时,你可以令任意名角色获得你的一张牌,然后你摸X张牌(X为你本次失去的花色数)。', - olxiangxv:'相胥', - olxiangxv_info:'当你的手牌数变为全场最少时,你可以获得以下效果:本回合结束时,将手牌数调整至与当前回合角色手牌数相同(至多摸至五张)。', - olxiangzuo:'襄胙', - olxiangzuo_info:'限定技,当你进入濒死状态时,你可以交给当前回合角色任意张牌,若如此做,若你本回合已对其发动过〖恭节〗和〖相胥〗,你回复等量的体力。', - liyi:'李异', - olchanshuang:'缠双', - olchanshuang_info:'①出牌阶段限一次,你可以选择一名其他角色。你与其依次选择〖缠双③〗的一项,然后你与其依次执行各自选择的项。②结束阶段,若X大于0,你执行〖缠双③〗的前X项(X为你本回合以任意形式执行过的〖缠双③〗的选项数)。③选项:1.重铸一张牌;2.使用一张【杀】;3.弃置两张牌。', - olzhanjin:'蘸金', - olzhanjin_info:'锁定技,若你有空置的武器栏,则你视为装备【贯石斧】。', - tianchou:'田畴', - olshandao:'善刀', - olshandao_info:'出牌阶段限一次,你可以选择任意名角色,你选择这些角色的各一张牌,依次将这些牌放置到牌堆顶,然后你视为对这些角色使用【五谷丰登】,然后你视为对这些角色外的所有其他角色使用【万箭齐发】。', - ol_hujinding:'胡金定', - olqingyuan:'轻缘', - olqingyuan_info:'锁定技。①游戏开始时,或当你于本局游戏首次受到伤害后,你选择一名未以此法选择过的其他角色。②每回合限一次,你发动〖轻缘①〗选择过的角色得到牌后,你随机获得其中一名角色的随机一张手牌。', - olchongshen:'重身', - olchongshen_info:'你可以将本轮得到的红色手牌当作【闪】使用。', - guotu:'郭图', - olqushi:'趋势', - olqushi_info:'出牌阶段限一次,你可以摸一张牌,然后将一张手牌扣置于一名其他角色的武将牌上,称为“趋”。目标角色于其结束阶段移去武将牌上的所有“趋”,若其于本回合使用过与“趋”相同类别的牌,则你摸X张牌(X为其本回合使用牌指定过的目标数之和且至多为5)。', - olweijie:'诿解', - olweijie_info:'回合外每名角色的回合限一次,当你需要使用或打出一张基本牌时,你可以弃置距离为1的一名角色的一张手牌,若此牌牌名与你需要使用或打出的牌的牌名相同,则视为你使用或打出之。', - liupan:'刘磐', - olpijing:'披荆', - olpijing_info:'每回合限一次,当你使用黑色【杀】或黑色普通锦囊牌指定唯一目标后,你可以令至多X名其他角色成为此牌的额外目标并依次交给你一张牌(X为你已损失的体力值且X至少为1)。这些角色下次使用基本牌或普通锦囊牌指定唯一目标时,其可令你成为此牌的额外目标或摸一张牌。', - ol_lukai:'OL陆凯', - ol_lukai_prefix:'OL', - olxuanzhu:'玄注', - olxuanzhu_info:'转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。', - oljiane:'謇谔', - oljiane_info:'锁定技。①当你对其他角色使用的牌生效后,其本回合无法抵消牌。②当你抵消牌后,你本回合无法成为牌的目标。', - ol_liupi:'刘辟', - olyicheng:'易城', - olyicheng_info:'出牌阶段限一次,你可以亮出牌堆顶的三张牌,然后你可以以任意手牌交换这些牌,若这三张牌的点数和因此增加,则你可以选择用所有手牌交换这三张牌。', + olfeiyang_info: "准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌。", + caoyu: "曹宇", + olgongjie: "恭节", + olgongjie_info: + "每轮的首个回合开始时,你可以令任意名角色获得你的一张牌,然后你摸X张牌(X为你本次失去的花色数)。", + olxiangxv: "相胥", + olxiangxv_info: + "当你的手牌数变为全场最少时,你可以获得以下效果:本回合结束时,将手牌数调整至与当前回合角色手牌数相同(至多摸至五张),然后若你以此法弃置了至少两张手牌,则你回复1点体力。", + olxiangzuo: "襄胙", + olxiangzuo_info: + "限定技,当你进入濒死状态时,你可以交给一名其他角色任意张牌,然后若你已对其发动过〖恭节〗和〖相胥〗,你回复等量的体力。", + liyi: "李异", + olchanshuang: "缠双", + olchanshuang_info: + "①出牌阶段限一次,你可以选择一名其他角色。你与其依次选择〖缠双③〗的一项,然后你与其依次执行各自选择的项。②结束阶段,若X大于0,你执行〖缠双③〗的前X项(X为你本回合以任意形式执行过的〖缠双③〗的选项数)。③选项:1.重铸一张牌;2.使用一张【杀】;3.弃置两张牌。", + olzhanjin: "蘸金", + olzhanjin_info: "锁定技,若你有空置的武器栏,则你视为装备【贯石斧】。", + tianchou: "田畴", + olshandao: "善刀", + olshandao_info: + "出牌阶段限一次,你可以选择任意名角色,你选择这些角色的各一张牌,依次将这些牌放置到牌堆顶,然后你视为对这些角色使用【五谷丰登】,然后你视为对这些角色外的所有其他角色使用【万箭齐发】。", + ol_hujinding: "胡金定", + olqingyuan: "轻缘", + olqingyuan_info: + "锁定技。①游戏开始时,或当你于本局游戏首次受到伤害后,你选择一名未以此法选择过的其他角色。②每回合限一次,你发动〖轻缘①〗选择过的角色得到牌后,你随机获得其中一名角色的随机一张手牌。", + olchongshen: "重身", + olchongshen_info: "你可以将本轮得到的红色手牌当作【闪】使用。", + guotu: "郭图", + olqushi: "趋势", + olqushi_info: + "出牌阶段限一次,你可以摸一张牌,然后将一张手牌扣置于一名其他角色的武将牌上,称为“趋”。目标角色于其结束阶段移去武将牌上的所有“趋”,若其于本回合使用过与“趋”相同类别的牌,则你摸X张牌(X为其本回合使用牌指定过的目标数之和且至多为5)。", + olweijie: "诿解", + olweijie_info: + "回合外每名角色的回合限一次,当你需要使用或打出一张基本牌时,你可以弃置距离为1的一名角色的一张手牌,若此牌牌名与你需要使用或打出的牌的牌名相同,则视为你使用或打出之。", + liupan: "刘磐", + olpijing: "披荆", + olpijing_info: + "每回合限一次,当你使用黑色【杀】或黑色普通锦囊牌指定唯一目标后,你可以令至多X名其他角色成为此牌的额外目标并依次交给你一张牌(X为你已损失的体力值且X至少为1)。这些角色下次使用基本牌或普通锦囊牌指定唯一目标时,其可令你成为此牌的额外目标或摸一张牌。", + ol_lukai: "OL陆凯", + ol_lukai_prefix: "OL", + olxuanzhu: "玄注", + olxuanzhu_info: + "转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。", + oljiane: "謇谔", + oljiane_info: + "锁定技。①当你对其他角色使用的牌生效后,其本回合无法抵消牌。②当你抵消牌后,你本回合无法成为牌的目标。", + ol_liupi: "刘辟", + olyicheng: "易城", + olyicheng_info: + "出牌阶段限一次,你可以亮出牌堆顶的X张牌(X为你的体力上限),然后你可以以任意手牌交换其中等量张牌,若亮出的牌的点数和因此增加,则你可以选择用所有手牌交换亮出的牌。最后你将亮出的牌置于牌堆顶。", + sp_sunce: "SP孙策", + sp_sunce_prefix: "SP", + olliantao: "连讨", + olliantao_info: + "出牌阶段开始时,你可以令一名其他角色选择一个颜色,然后你依次将此颜色的所有手牌当作【决斗】对其使用直到有一方进入濒死状态,然后你摸X张牌(X为你本次以此法造成的伤害数)。若没有角色因本次技能结算受到伤害,你摸三张牌,本回合手牌上限+3且本回合你不能使用【杀】。", - sp_tianji:'天极·皇室宗亲', - sp_sibi:'四弼·辅国文曲', - sp_tianzhu:'天柱·势冠一方', - sp_nvshi:'女史·留史巾帼', - sp_shaowei:'少微·能人异士', - sp_huben:'虎贲·勇冠三军', - sp_liesi:'列肆·豪商巨贾', - sp_default:"天同·同名异势", - sp_qifu:'灯愿·祈福武将', - sp_wanglang:'OL·限定专属', - sp_zhongdan:"忠胆英杰", - sp_guozhan:"国战", - sp_guozhan2:"国战移植", - sp_others:"其他", - sp_waitforsort:'等待分包', - } + sp_tianji: "天极·皇室宗亲", + sp_sibi: "四弼·辅国文曲", + sp_tianzhu: "天柱·势冠一方", + sp_nvshi: "女史·留史巾帼", + sp_shaowei: "少微·能人异士", + sp_huben: "虎贲·勇冠三军", + sp_liesi: "列肆·豪商巨贾", + sp_default: "天同·同名异势", + sp_qifu: "灯愿·祈福武将", + sp_wanglang: "OL·限定专属", + sp_zhongdan: "忠胆英杰", + sp_guozhan: "国战", + sp_guozhan2: "国战移植", + sp_others: "其他", + sp_waitforsort: "等待分包", + }, }; }); diff --git a/character/sp2.js b/character/sp2.js index 63fe3f59c..de3e006b4 100644 --- a/character/sp2.js +++ b/character/sp2.js @@ -1,481 +1,705 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'sp2', - connect:true, - character:{ - liqueguosi:['male','qun',4,['xiongsuan']], - star_zhangchunhua:['female','wei',3,['starliangyan','starminghui']], - star_yuanshao:['male','qun',4,['starxiaoyan','starzongshi','starjiaowang','staraoshi'],['zhu']], - star_dongzhuo:['male','qun',5,['starweilin','starzhangrong','starhaoshou'],['zhu']], - star_yuanshu:['male','qun',4,['starcanxi','starpizhi','starzhonggu'],['zhu']], - star_caoren:['male','wei',4,['starsujun','starlifeng']], - mp_liuling:['male','jin',3,['mpjiusong','mpmaotao','mpbishi'],['doublegroup:wei:qun:jin']], - dc_jikang:['male','wei',3,['new_qingxian','dcjuexiang']], - dc_jsp_guanyu:['male','wei',4,['new_rewusheng','dcdanji']], - dc_mengda:['male','wei',4,['dclibang','dcwujie']], + name: "sp2", + connect: true, + character: { + liqueguosi: ["male", "qun", 4, ["xiongsuan"]], + star_zhangchunhua: ["female", "wei", 3, ["starliangyan", "starminghui"]], + star_yuanshao: [ + "male", + "qun", + 4, + ["starxiaoyan", "starzongshi", "starjiaowang", "staraoshi"], + ["zhu"], + ], + star_dongzhuo: ["male", "qun", 5, ["starweilin", "starzhangrong", "starhaoshou"], ["zhu"]], + star_yuanshu: ["male", "qun", 4, ["starcanxi", "starpizhi", "starzhonggu"], ["zhu"]], + star_caoren: ["male", "wei", 4, ["starsujun", "starlifeng"]], + mp_liuling: ["male", "jin", 3, ["mpjiusong", "mpmaotao", "mpbishi"], ["doublegroup:wei:qun:jin"]], + 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_fuwan:['male','qun',4,['dcmoukui']], - guānning:['male','shu',3,['dcxiuwen','dclongsong']], - sunhuan:['male','wu',4,['dcniji']], - sunlang:['male','shu',4,['dctingxian','dcbenshi']], - shiyi:['male','wu',3,['dccuichuan','dczhengxu']], - dc_hujinding:['female','shu','3/6',['dcdeshi','dcwuyuan','huaizi']], - liyixiejing:['male','wu',4,['dcdouzhen']], - mushun:['male','qun',4,['dcjinjian','dcshizhao']], - dc_zhaoyǎn:['male','wei',3,['dcfuning','dcbingji']], - wangwei:['male','qun',4,['dcruizhan','dcshilie']], - dc_huban:['male','wei',4,['dcchongyi']], - niufu:['male','qun','4/7',['dcxiaoxi','xiongrao']], - bianxi:['male','wei',4,['dunxi']], - fengfang:['male','qun',3,['dcditing','dcbihuo']], - qinyilu:['male','qun',3,['piaoping','tuoxian','chuaili']], - yanrou:['male','wei',4,['choutao','xiangshu']], - dc_zhuling:['male','wei',4,['dczhanyi']], - licaiwei:['female','wei',3,['yijiao','qibie']], - yanfuren:['female','qun',3,['channi','nifu']], - haomeng:['male','qun',7,['xiongmang']], - re_pangdegong:['male','qun',3,['heqia','yinyi']], - hanmeng:['male','qun',4,['jieliang','quanjiu']], - xinping:['male','qun',3,['fuyuan','zhongjie','yongdi']], - zhangning:['female','qun',3,['tianze','difa']], - tongyuan:['male','qun',4,['chaofeng','chuanshu']], - sp_mifangfushiren:['male','shu',4,['fengshi']], - re_nanhualaoxian:['male','qun',4,['gongxiu','jinghe']], - dufuren:['female','wei',3,['yise','shunshi']], - caoanmin:['male','wei',4,['xianwei']], - re_zoushi:['female','qun',3,['rehuoshui','reqingcheng']], - qiuliju:['male','qun','4/6',['koulve','qljsuiren']], - re_hucheer:['male','qun',4,['redaoji','fuzhong']], - re_dongcheng:['male','qun',4,['xuezhao']], - tangji:['female','qun',3,['kangge','jielie']], - zhangheng:['male','qun',8,['dangzai','liangjue']], - duanwei:['male','qun',4,['langmie']], - re_niujin:['male','wei',4,['recuorui','reliewei']], - zhangmiao:['male','qun',4,['mouni','zongfan']], - liangxing:['male','qun',4,['lulve','lxzhuixi']], - caosong:['male','wei',4,['cslilu','csyizheng']], - re_taoqian:['male','qun',3,['zhaohuo','reyixiang','reyirang']], - zhaozhong:['male','qun',6,['yangzhong','huangkong']], - hanfu:['male','qun',4,['hfjieying','weipo']], - re_quyi:['male','qun',4,['refuqi','jiaozi']], - dongxie:['female','qun',4,['dcjiaoxia','dchumei']], - wangrong:['female','qun',3,['minsi','jijing','zhuide']], - ol_dingyuan:['male','qun',4,['cixiao','xianshuai']], - re_hejin:['male','qun',4,['spmouzhu','spyanhuo']], - re_hansui:['male','qun',4,['spniluan','spweiwu']], - liuhong:['male','qun',4,['yujue','tuxing']], - zhujun:['male','qun',4,['gongjian','kuimang']], - re_maliang:['male','shu',3,['rexiemu','heli'],[]], - caobuxing:['male','wu',3,['moying','juanhui'],[]], - lijue:["male","qun","4/6",["xinfu_langxi","xinfu_yisuan"],[]], - zhangji:["male","qun",4,["xinfu_lveming","xinfu_tunjun"],[]], - fanchou:["male","qun",4,["xinxingluan"],[]], - guosi:["male","qun",4,["xinfu_tanbei","xinfu_sidao"],[]], - lvkai:["male","shu",3,["xinfu_tunan","xinfu_bijing"],[]], - zhanggong:["male","wei",3,["xinfu_zhenxing","xinfu_qianxin"],[]], - weiwenzhugezhi:["male","wu",4,["xinfu_fuhai"],[]], - beimihu:['female','qun',3,['zongkui','guju','baijia']], - xurong:["male","qun",4,["xinfu_xionghuo","xinfu_shajue"],[]], - zhangqiying:["female","qun",3,["xinfu_falu","xinfu_dianhua","xinfu_zhenyi"],[]], - sp_liuqi:['male','qun',3,['rewenji','sptunjiang']], - xf_tangzi:["male","wei",4,["xinfu_xingzhao"],[]], - xf_huangquan:["male","shu",3,["xinfu_dianhu","xinfu_jianji"],[]], - xf_sufei:["male","wu",4,["xinfu_lianpian"],[]], - xushao:['male','qun',4,['pingjian']], - xinpi:['male','wei',3,['xpchijie','yinju']], - lisu:['male','qun',2,['lslixun','lskuizhu']], - zhangwen:['male','wu',3,['songshu','sibian']], - mangyachang:["male","qun",4,["spjiedao"],[]], - xugong:["male","wu",3,["biaozhao","yechou"],[]], - zhangchangpu:["female","wei",3,["yanjiao","xingshen"],[]], - gaolan:['male','qun',4,['xiying']], - sp_shenpei:['male','qun',3,['gangzhi','beizhan']], - xunchen:['male','qun',3,['fenglve','mouzhi'],['clan:颍川荀氏']], - sp_zhanghe:['male','qun',4,['yuanlve']], - sp_xuyou:['male','qun',3,['spshicai','spfushi']], - chunyuqiong:['male','qun',5,['cangchu','sushou','liangying']], - lvkuanglvxiang:['male','qun',4,['liehou','qigong']], + guānning: ["male", "shu", 3, ["dcxiuwen", "longsong"]], + sunhuan: ["male", "wu", 4, ["dcniji"]], + sunlang: ["male", "shu", 4, ["dctingxian", "dcbenshi"]], + shiyi: ["male", "wu", 3, ["dccuichuan", "dczhengxu"]], + dc_hujinding: ["female", "shu", "3/6", ["dcdeshi", "dcwuyuan", "huaizi"]], + liyixiejing: ["male", "wu", 4, ["dcdouzhen"]], + mushun: ["male", "qun", 4, ["dcjinjian", "dcshizhao"]], + dc_zhaoyǎn: ["male", "wei", 3, ["dcfuning", "dcbingji"]], + wangwei: ["male", "qun", 4, ["dcruizhan", "dcshilie"]], + dc_huban: ["male", "wei", 4, ["dcchongyi"]], + niufu: ["male", "qun", "4/7", ["dcxiaoxi", "xiongrao"]], + bianxi: ["male", "wei", 4, ["dunxi"]], + fengfang: ["male", "qun", 3, ["dcditing", "dcbihuo"]], + qinyilu: ["male", "qun", 3, ["piaoping", "tuoxian", "chuaili"]], + yanrou: ["male", "wei", 4, ["choutao", "xiangshu"]], + dc_zhuling: ["male", "wei", 4, ["dczhanyi"]], + licaiwei: ["female", "wei", 3, ["yijiao", "qibie"]], + yanfuren: ["female", "qun", 3, ["channi", "nifu"]], + haomeng: ["male", "qun", 7, ["xiongmang"]], + re_pangdegong: ["male", "qun", 3, ["heqia", "yinyi"]], + hanmeng: ["male", "qun", 4, ["jieliang", "quanjiu"]], + xinping: ["male", "qun", 3, ["fuyuan", "zhongjie", "yongdi"]], + zhangning: ["female", "qun", 3, ["tianze", "difa"]], + tongyuan: ["male", "qun", 4, ["chaofeng", "chuanshu"]], + sp_mifangfushiren: ["male", "shu", 4, ["fengshi"]], + re_nanhualaoxian: ["male", "qun", 4, ["gongxiu", "jinghe"]], + dufuren: ["female", "wei", 3, ["yise", "shunshi"]], + caoanmin: ["male", "wei", 4, ["xianwei"]], + re_zoushi: ["female", "qun", 3, ["rehuoshui", "reqingcheng"]], + qiuliju: ["male", "qun", "4/6", ["koulve", "qljsuiren"]], + re_hucheer: ["male", "qun", 4, ["redaoji", "fuzhong"]], + re_dongcheng: ["male", "qun", 4, ["xuezhao"]], + tangji: ["female", "qun", 3, ["kangge", "jielie"]], + zhangheng: ["male", "qun", 8, ["dangzai", "liangjue"]], + duanwei: ["male", "qun", 4, ["langmie"]], + re_niujin: ["male", "wei", 4, ["recuorui", "reliewei"]], + zhangmiao: ["male", "qun", 4, ["mouni", "zongfan"]], + liangxing: ["male", "qun", 4, ["lulve", "lxzhuixi"]], + caosong: ["male", "wei", 4, ["cslilu", "csyizheng"]], + re_taoqian: ["male", "qun", 3, ["zhaohuo", "reyixiang", "reyirang"]], + zhaozhong: ["male", "qun", 6, ["yangzhong", "huangkong"]], + hanfu: ["male", "qun", 4, ["hfjieying", "weipo"]], + re_quyi: ["male", "qun", 4, ["refuqi", "jiaozi"]], + dongxie: ["female", "qun", 4, ["dcjiaoxia", "dchumei"]], + wangrong: ["female", "qun", 3, ["minsi", "jijing", "zhuide"]], + ol_dingyuan: ["male", "qun", 4, ["cixiao", "xianshuai"]], + re_hejin: ["male", "qun", 4, ["spmouzhu", "spyanhuo"]], + re_hansui: ["male", "qun", 4, ["spniluan", "spweiwu"]], + liuhong: ["male", "qun", 4, ["yujue", "tuxing"]], + zhujun: ["male", "qun", 4, ["gongjian", "kuimang"]], + re_maliang: ["male", "shu", 3, ["rexiemu", "heli"], []], + caobuxing: ["male", "wu", 3, ["moying", "juanhui"], []], + lijue: ["male", "qun", "4/6", ["xinfu_langxi", "xinfu_yisuan"], []], + zhangji: ["male", "qun", 4, ["xinfu_lveming", "xinfu_tunjun"], []], + fanchou: ["male", "qun", 4, ["xinxingluan"], []], + guosi: ["male", "qun", 4, ["xinfu_tanbei", "xinfu_sidao"], []], + lvkai: ["male", "shu", 3, ["xinfu_tunan", "xinfu_bijing"], []], + zhanggong: ["male", "wei", 3, ["xinfu_zhenxing", "xinfu_qianxin"], []], + weiwenzhugezhi: ["male", "wu", 4, ["xinfu_fuhai"], []], + beimihu: ["female", "qun", 3, ["zongkui", "guju", "baijia"]], + xurong: ["male", "qun", 4, ["xinfu_xionghuo", "xinfu_shajue"], []], + zhangqiying: ["female", "qun", 3, ["xinfu_falu", "xinfu_dianhua", "xinfu_zhenyi"], []], + sp_liuqi: ["male", "qun", 3, ["rewenji", "sptunjiang"]], + xf_tangzi: ["male", "wei", 4, ["xinfu_xingzhao"], []], + xf_huangquan: ["male", "shu", 3, ["xinfu_dianhu", "xinfu_jianji"], []], + xf_sufei: ["male", "wu", 4, ["xinfu_lianpian"], []], + xushao: ["male", "qun", 4, ["pingjian"]], + xinpi: ["male", "wei", 3, ["xpchijie", "yinju"]], + lisu: ["male", "qun", 2, ["lslixun", "lskuizhu"]], + zhangwen: ["male", "wu", 3, ["songshu", "sibian"]], + mangyachang: ["male", "qun", 4, ["spjiedao"], []], + xugong: ["male", "wu", 3, ["biaozhao", "yechou"], []], + zhangchangpu: ["female", "wei", 3, ["yanjiao", "xingshen"], []], + gaolan: ["male", "qun", 4, ["xiying"]], + sp_shenpei: ["male", "qun", 3, ["gangzhi", "beizhan"]], + xunchen: ["male", "qun", 3, ["fenglve", "mouzhi"], ["clan:颍川荀氏"]], + sp_zhanghe: ["male", "qun", 4, ["yuanlve"]], + sp_xuyou: ["male", "qun", 3, ["spshicai", "spfushi"]], + chunyuqiong: ["male", "qun", 5, ["cangchu", "sushou", "liangying"]], + lvkuanglvxiang: ["male", "qun", 4, ["liehou", "qigong"]], }, - characterSort:{ - sp2:{ - sp_whlw:["xurong","lijue","zhangji","fanchou","guosi","duanwei","liangxing","zhangheng",'tangji','niufu','dongxie','liqueguosi'], - sp_zlzy:["zhangqiying","lvkai","zhanggong","weiwenzhugezhi","beimihu"], - sp_longzhou:["xf_tangzi","xf_huangquan","xf_sufei","sp_liuqi"], - sp_zizouqi:["mangyachang","xugong","zhangchangpu"], - sp_sbfm:["lisu","xinpi","zhangwen"], - sp_guandu:["sp_zhanghe","xunchen","sp_shenpei","gaolan","lvkuanglvxiang","chunyuqiong","sp_xuyou","xinping","hanmeng"], - sp_qihuan:['zhaozhong','re_hejin','fengfang','mushun'], - sp_binglin:['re_niujin',"sp_mifangfushiren",'licaiwei','dc_zhaoyan','shiyi','sunlang','sunhuan','dc_mengda'], - sp_danqi:['dufuren','qinyilu','bianxi','dc_huban','dc_hujinding','dc_zhaoyǎn','wangwei','liyixiejing','guānning','dc_jsp_guanyu'], - sp_fenghuo:['re_nanhualaoxian','tongyuan','zhangning','re_pangdegong'], - sp_huangjin:['liuhong','zhujun','re_hansui',"xushao"], - sp_fadong:['ol_dingyuan','wangrong','re_quyi','hanfu'], - sp_xuzhou:['re_taoqian','caosong','zhangmiao','qiuliju'], - sp_zhongyuan:['re_hucheer','re_zoushi','caoanmin','re_dongcheng'], - sp_xiaohu:['haomeng','yanfuren','yanrou','dc_zhuling'], - sp_star:['star_caoren','star_yuanshu','star_dongzhuo','star_yuanshao','star_zhangchunhua'], - mini_qixian:['mp_liuling'], - sp2_waitforsort:['caobuxing','re_maliang','dc_jikang'], - } + characterSort: { + sp2: { + sp_whlw: [ + "xurong", + "lijue", + "zhangji", + "fanchou", + "guosi", + "duanwei", + "liangxing", + "zhangheng", + "tangji", + "niufu", + "dongxie", + "liqueguosi", + ], + sp_zlzy: ["zhangqiying", "lvkai", "zhanggong", "weiwenzhugezhi", "beimihu"], + sp_longzhou: ["xf_tangzi", "xf_huangquan", "xf_sufei", "sp_liuqi"], + sp_zizouqi: ["mangyachang", "xugong", "zhangchangpu"], + sp_sbfm: ["lisu", "xinpi", "zhangwen"], + sp_guandu: [ + "sp_zhanghe", + "xunchen", + "sp_shenpei", + "gaolan", + "lvkuanglvxiang", + "chunyuqiong", + "sp_xuyou", + "xinping", + "hanmeng", + ], + sp_qihuan: ["zhaozhong", "re_hejin", "fengfang", "mushun"], + sp_binglin: [ + "re_niujin", + "sp_mifangfushiren", + "licaiwei", + "dc_zhaoyan", + "shiyi", + "sunlang", + "sunhuan", + "dc_mengda", + ], + sp_danqi: [ + "dufuren", + "qinyilu", + "bianxi", + "dc_huban", + "dc_hujinding", + "dc_zhaoyǎn", + "wangwei", + "liyixiejing", + "guānning", + "dc_jsp_guanyu", + ], + sp_fenghuo: ["re_nanhualaoxian", "tongyuan", "zhangning", "re_pangdegong"], + sp_huangjin: ["liuhong", "zhujun", "re_hansui", "xushao"], + sp_fadong: ["ol_dingyuan", "wangrong", "re_quyi", "hanfu"], + sp_xuzhou: ["re_taoqian", "caosong", "zhangmiao", "qiuliju"], + sp_zhongyuan: ["re_hucheer", "re_zoushi", "caoanmin", "re_dongcheng"], + sp_xiaohu: ["haomeng", "yanfuren", "yanrou", "dc_zhuling"], + sp_star: [ + "star_caoren", + "star_yuanshu", + "star_dongzhuo", + "star_yuanshao", + "star_zhangchunhua", + ], + mini_qixian: ["mp_liuling"], + sp2_waitforsort: ["caobuxing", "re_maliang", "dc_jikang"], + }, }, - skill:{ + skill: { //李傕郭汜 - xiongsuan:{ - audio:2, - enable:'phaseUse', - filterTarget:true, - filterCard:lib.filter.cardDiscardable, - position:'h', - usable:1, - async content(event,trigger,player){ - const target=event.target; + xiongsuan: { + audio: 2, + enable: "phaseUse", + filterTarget: true, + filterCard: lib.filter.cardDiscardable, + position: "h", + usable: 1, + async content(event, trigger, player) { + const target = event.target; await target.damage(); await player.draw(3); - if(target!=player) await player.loseHp(); + if (target != player) await player.loseHp(); }, - ai:{ - order:9, - result:{ - player(player,target){ - let res=2*get.effect(player,{name:'draw',player,player}); - if(player!==target) res+=get.effect(player,{name:'losehp'},player,player); + ai: { + order: 9, + result: { + player(player, target) { + let res = 2 * get.effect(player, { name: "draw", player, player }); + if (player !== target) + res += get.effect(player, { name: "losehp" }, player, player); return res; }, - target(player,target){ - return get.damageEffect(target,player,target); + target(player, target) { + return get.damageEffect(target, player, target); }, }, }, }, //张春华 - starliangyan:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - chooseButton:{ - dialog(event,player){ - const name=get.translation(event.result.targets[0]); - const list=[ - '你摸一张牌,其弃置一张牌','你弃置一张牌,其摸一张牌', - '你摸两张牌,其弃置两张牌','你弃置两张牌,其摸两张牌' - ].map((item,i)=>[i,item]); - const dialog=ui.create.dialog( + starliangyan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + chooseButton: { + dialog(event, player) { + const name = get.translation(event.result.targets[0]); + const list = [ + "你摸一张牌,其弃置一张牌", + "你弃置一张牌,其摸一张牌", + "你摸两张牌,其弃置两张牌", + "你弃置两张牌,其摸两张牌", + ].map((item, i) => [i, item]); + const dialog = ui.create.dialog( `梁燕:请选择你与${name}要执行的选项`, - [list.slice(0,2),'tdnodes'], - [list.slice(2,4),'tdnodes'], - 'hidden' + [list.slice(0, 2), "tdnodes"], + [list.slice(2, 4), "tdnodes"], + "hidden" ); return dialog; }, - filter(button,player){ - const link=button.link; - if(link%2===0) return true; - return player.countDiscardableCards(player,'he')>=(link+1)/2; + filter(button, player) { + const link = button.link; + if (link % 2 === 0) return true; + return player.countDiscardableCards(player, "he") >= (link + 1) / 2; }, - check(button){ - const player=get.player(),target=get.event().getParent().result.targets[0]; - const link=button.link; - if(get.attitude(player,target)<=0&&link===2) return 100; - const ph=player.countCards('h'),th=target.countCards('h'); - if(link%2===0){ - const num=(link/2)+1; - if(ph+num===th-num) return 10; - } - else{ - const num=(link+1)/2; - if(ph-num===th+num) return 10; + check(button) { + const player = get.player(), + target = get.event().getParent().result.targets[0]; + const link = button.link; + if (get.attitude(player, target) <= 0 && link === 2) return 100; + const ph = player.countCards("h"), + th = target.countCards("h"); + if (link % 2 === 0) { + const num = link / 2 + 1; + if (ph + num === th - num) return 10; + } else { + const num = (link + 1) / 2; + if (ph - num === th + num) return 10; } return 5; }, - backup(links){ + backup(links) { return { - audio:'starliangyan', - target:get.event().result.targets[0], - link:links[0], - filterTarget(card,player,target){ - return target===lib.skill.starliangyan_backup.target; + audio: "starliangyan", + target: get.event().result.targets[0], + link: links[0], + filterTarget(card, player, target) { + return target === lib.skill.starliangyan_backup.target; }, - selectTarget:-1, - async content(content,trigger,player){ - const target=lib.skill.starliangyan_backup.target; - const link=lib.skill.starliangyan_backup.link; - const num=link<=1?1:2; - const fn=['draw','chooseToDiscard']; - if(link%2===1) fn.reverse(); - await player[fn[0]](num,true,'he'); - await target[fn[1]](num,true,'he'); - if(player.countCards('h')===target.countCards('h')){ - const skipper=[player,target][link%2]; - skipper.skip('phaseDiscard'); - game.log(skipper,'跳过了下一个','#y弃牌阶段'); + selectTarget: -1, + async content(content, trigger, player) { + const target = lib.skill.starliangyan_backup.target; + const link = lib.skill.starliangyan_backup.link; + const num = link <= 1 ? 1 : 2; + const fn = ["draw", "chooseToDiscard"]; + if (link % 2 === 1) fn.reverse(); + await player[fn[0]](num, true, "he"); + await target[fn[1]](num, true, "he"); + if (player.countCards("h") === target.countCards("h")) { + const skipper = [player, target][link % 2]; + skipper.skip("phaseDiscard"); + game.log(skipper, "跳过了下一个", "#y弃牌阶段"); } - } + }, }; }, - prompt(links){ - return '点击“确定”以执行效果'; + prompt(links) { + return "点击“确定”以执行效果"; }, }, - subSkill:{ - backup:{}, + subSkill: { + backup: {}, }, - ai:{ - order(item,player){ - if(!game.hasPlayer(current=>current!==player&&get.attitude(player,current)>0)&&game.hasPlayer(current=>get.attitude(player,current)<=0)) return 10; - if(game.hasPlayer(current=>{ - const del=player.countCards('h')-current.countCards('h'),toFind=[2,4].find(num=>Math.abs(del)===num); - if(toFind===4&&del<0&&get.attitude(player,current)<=0){ - return true; - } - return false; - })) return 10; + ai: { + order(item, player) { + if ( + !game.hasPlayer( + (current) => current !== player && get.attitude(player, current) > 0 + ) && + game.hasPlayer((current) => get.attitude(player, current) <= 0) + ) + return 10; + if ( + game.hasPlayer((current) => { + const del = player.countCards("h") - current.countCards("h"), + toFind = [2, 4].find((num) => Math.abs(del) === num); + if (toFind === 4 && del < 0 && get.attitude(player, current) <= 0) { + return true; + } + return false; + }) + ) + return 10; return 1; }, - result:{ - target(player,target){ - const del=player.countCards('h')-target.countCards('h'),toFind=[2,4].find(num=>Math.abs(del)===num); - if(toFind){ - return -del*(get.attitude(player,target)*Math.min(3,target.countCards('h')))*toFind/10; + result: { + target(player, target) { + const del = player.countCards("h") - target.countCards("h"), + toFind = [2, 4].find((num) => Math.abs(del) === num); + if (toFind) { + return ( + (-del * + (get.attitude(player, target) * Math.min(3, target.countCards("h"))) * + toFind) / + 10 + ); } return -1; }, }, }, }, - starminghui:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter(event,player){ - return player.isMinHandcard()||player.isMaxHandcard(); + starminghui: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter(event, player) { + return player.isMinHandcard() || player.isMaxHandcard(); }, - direct:true, - async content(event,trigger,player){ - let logged=false; - if(player.isMinHandcard()){ - const card=new lib.element.VCard({ - name:'sha', + direct: true, + async content(event, trigger, player) { + let logged = false; + if (player.isMinHandcard()) { + const card = new lib.element.VCard({ + name: "sha", }); - const result=await player.chooseUseTarget(`###${get.prompt('starminghui')}###视为使用一张无距离限制的【杀】`,card,false,'nodistance').set('logSkill','starminghui').forResult(); - if(result.bool) logged=true; + const result = await player + .chooseUseTarget( + `###${get.prompt("starminghui")}###视为使用一张无距离限制的【杀】`, + card, + false, + "nodistance" + ) + .set("logSkill", "starminghui") + .forResult(); + if (result.bool) logged = true; } - const num=player.countCards('h'); - if(player.isMaxHandcard()&&num>0){ - const maxNum=game.findPlayer(current=>{ - if(current===player) return false; - return !game.hasPlayer(current2=>{ - if(current2===player) return false; - return current2.countCards('h')>current.countCards('h'); + const num = player.countCards("h"); + if (player.isMaxHandcard() && num > 0) { + const maxNum = game + .findPlayer((current) => { + if (current === player) return false; + return !game.hasPlayer((current2) => { + if (current2 === player) return false; + return current2.countCards("h") > current.countCards("h"); + }); + }) + .countCards("h"); + const leastDiscardNum = num - maxNum + 1; + const prompt = logged ? `是否将手牌弃置至不为最多?` : get.prompt("starminghui"); + const next = player + .chooseToDiscard( + prompt, + `弃置至少${get.cnNumber(leastDiscardNum)}张手牌,然后你令一名角色回复1点体力` + ) + .set("selectCard", [leastDiscardNum, Infinity]) + .set( + "goon", + game.hasPlayer((current) => + get.recoverEffect(current, get.player(), get.player()) + ) + ) + .set("ai", (card) => { + if (!get.event("goon")) return 0; + if (get.tag(card, "recover")) return 0; + if (ui.selected.cards.length === get.event("selectCard")[0] - 1) + return 6.5 - get.value(card); + return 4 - get.value(card); }); - }).countCards('h'); - const leastDiscardNum=num-maxNum+1; - const prompt=logged?`是否将手牌弃置至不为最多?`:get.prompt('starminghui'); - const next=player.chooseToDiscard(prompt,`弃置至少${get.cnNumber(leastDiscardNum)}张手牌,然后你令一名角色回复1点体力`) - .set('selectCard',[leastDiscardNum,Infinity]) - .set('goon',game.hasPlayer(current=>get.recoverEffect(current,get.player(),get.player()))) - .set('ai',card=>{ - if(!get.event('goon')) return 0; - if(get.tag(card,'recover')) return 0; - if(ui.selected.cards.length===get.event('selectCard')[0]-1) return 6.5-get.value(card); - return 4-get.value(card); - }); - if(!logged) next.set('logSkill','starminghui'); - const result=await next.forResult(); - if(!result.bool) return; - if(!player.isUnderControl(true)&&!player.isOnline()) await game.asyncDelayx(); - const [bool,targets]=await player.chooseTarget('令一名角色回复1点体力') - .set('ai',target=>get.recoverEffect(target,get.player(),get.player())) - .forResult('bool','targets'); - if(bool){ - const target=targets[0]; - player.line(target,'green'); + if (!logged) next.set("logSkill", "starminghui"); + const result = await next.forResult(); + if (!result.bool) return; + if (!player.isUnderControl(true) && !player.isOnline()) await game.asyncDelayx(); + const [bool, targets] = await player + .chooseTarget("令一名角色回复1点体力") + .set("ai", (target) => get.recoverEffect(target, get.player(), get.player())) + .forResult("bool", "targets"); + if (bool) { + const target = targets[0]; + player.line(target, "green"); await target.recover(); } } }, - }, //星袁绍 - starxiaoyan:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:['enterGame'/*,'logSkill'*/], + starxiaoyan: { + audio: 2, + trigger: { + global: "phaseBefore", + player: ["enterGame" /*,'logSkill'*/], }, - filter(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; + filter(event, player) { + if (!game.hasPlayer((current) => current != player)) return false; //if(event.name=='logSkill'&&evt.skill!='starjiaowang') return false; - return event.name!='phase'||game.phaseNumber==0; + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - async content(event,trigger,player){ - let targets=game.filterPlayer(current=>current!=player); + forced: true, + async content(event, trigger, player) { + let targets = game.filterPlayer((current) => current != player); player.line(targets); - for(const target of targets) await target.damage('fire'); - targets=targets.filter(i=>i.isIn()); - if(targets.length){ - for(const target of targets){ - if(!target.countCards('he')) continue; - const {result:{bool}}=await target.chooseToGive('he',player) - .set('prompt','是否交给'+get.translation(player)+'一张牌'+(target.isDamaged()?'并回复1点体力':'')+'?') - .set('ai',card=>{ - const target=get.event('player'),player=get.event('target'); - const att=get.attitude(target,player); - if(get.recoverEffect(target,target,target)<=0){ - if(att<=0) return -get.value(card); - return 0; - } - return 7-get.value(card); - }).set('target',player); - if(bool) await target.recover(); + for (const target of targets) await target.damage("fire"); + targets = targets.filter((i) => i.isIn()); + if (targets.length) { + for (const target of targets) { + if (!target.countCards("he")) continue; + const { + result: { bool }, + } = await target + .chooseToGive("he", player) + .set( + "prompt", + "是否交给" + + get.translation(player) + + "一张牌" + + (target.isDamaged() ? "并回复1点体力" : "") + + "?" + ) + .set("ai", (card) => { + const target = get.event("player"), + player = get.event("target"); + const att = get.attitude(target, player); + if (get.recoverEffect(target, target, target) <= 0) { + if (att <= 0) return -get.value(card); + return 0; + } + return 7 - get.value(card); + }) + .set("target", player); + if (bool) await target.recover(); } } }, }, - starzongshi:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - const cards=player.getCards('h',card=>{ - const type=get.type(card,player); - if(type!='basic'&&type!='trick') return false; - return lib.filter.cardUsable(card,player)&&game.hasPlayer(target=>{ - return lib.filter.targetEnabled2(card,player,target)/*&&lib.filter.targetInRange(card,player,target)*/; - }); + starzongshi: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + const cards = player.getCards("h", (card) => { + const type = get.type(card, player); + if (type != "basic" && type != "trick") return false; + return ( + lib.filter.cardUsable(card, player) && + game.hasPlayer((target) => { + return lib.filter.targetEnabled2( + card, + player, + target + ) /*&&lib.filter.targetInRange(card,player,target)*/; + }) + ); }); - if(!cards.length) return false; - return cards.some(card=>{ - const cardss=player.getCards('h',cardx=>card!=cardx&&get.suit(card,player)==get.suit(cardx,player)); - return cardss.length&&!cardss.some(cardx=>!game.checkMod(cardx,player,'unchanged','cardEnabled2',player)); + if (!cards.length) return false; + return cards.some((card) => { + const cardss = player.getCards( + "h", + (cardx) => card != cardx && get.suit(card, player) == get.suit(cardx, player) + ); + return ( + cardss.length && + !cardss.some( + (cardx) => !game.checkMod(cardx, player, "unchanged", "cardEnabled2", player) + ) + ); }); }, - filterCard(card,player){ - if(ui.selected.cards.length) return false; - const cards=player.getCards('h',card=>{ - const type=get.type(card,player); - if(type!='basic'&&type!='trick') return false; - return lib.filter.cardUsable(card,player)&&game.hasPlayer(target=>{ - return lib.filter.targetEnabled2(card,player,target)/*&&lib.filter.targetInRange(card,player,target)*/; - }); + filterCard(card, player) { + if (ui.selected.cards.length) return false; + const cards = player.getCards("h", (card) => { + const type = get.type(card, player); + if (type != "basic" && type != "trick") return false; + return ( + lib.filter.cardUsable(card, player) && + game.hasPlayer((target) => { + return lib.filter.targetEnabled2( + card, + player, + target + ) /*&&lib.filter.targetInRange(card,player,target)*/; + }) + ); }); - if(!cards.includes(card)) return false; - const cardss=player.getCards('h',cardx=>card!=cardx&&get.suit(card,player)==get.suit(cardx,player)); - return cardss.length&&!cardss.some(cardx=>!game.checkMod(cardx,player,'unchanged','cardEnabled2',player)); + if (!cards.includes(card)) return false; + const cardss = player.getCards( + "h", + (cardx) => card != cardx && get.suit(card, player) == get.suit(cardx, player) + ); + return ( + cardss.length && + !cardss.some( + (cardx) => !game.checkMod(cardx, player, "unchanged", "cardEnabled2", player) + ) + ); }, - selectCard:[1,2], - complexCard:true, - check(card){ - const player=get.event('player'),select=get.copy(get.info(card).selectTarget); + selectCard: [1, 2], + complexCard: true, + check(card) { + const player = get.event("player"), + select = get.copy(get.info(card).selectTarget); let range; - if(select==undefined) range=[1,1]; - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); - const cards=player.getCards('h',cardx=>card!=cardx&&get.suit(card,player)==get.suit(cardx,player)); - let targets=game.filterPlayer(target=>lib.filter.targetEnabled2(card,player,target)/*&&lib.filter.targetInRange(card,player,target)*/&&get.effect(target,card,player,player)>0); - const max=range[1],max2=Math.min(cards.length,targets.length); - if(max>max2) return 0; - targets=targets.sort((a,b)=>get.effect(b,card,player,player)-get.effect(a,card,player,player)).slice(0,max2); - const sum=targets.reduce((num,target)=>num+get.effect(target,card,player,player),0); - if(max==-1){ - if(game.filterPlayer(target=>{ - return lib.filter.targetEnabled2(card,player,target)/*&&lib.filter.targetInRange(card,player,target)*/; - }).reduce((num,target)=>num+get.effect(target,card,player,player),0)>sum) return 0; + if (select == undefined) range = [1, 1]; + else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); + const cards = player.getCards( + "h", + (cardx) => card != cardx && get.suit(card, player) == get.suit(cardx, player) + ); + let targets = game.filterPlayer( + (target) => + lib.filter.targetEnabled2( + card, + player, + target + ) /*&&lib.filter.targetInRange(card,player,target)*/ && + get.effect(target, card, player, player) > 0 + ); + const max = range[1], + max2 = Math.min(cards.length, targets.length); + if (max > max2) return 0; + targets = targets + .sort( + (a, b) => + get.effect(b, card, player, player) - get.effect(a, card, player, player) + ) + .slice(0, max2); + const sum = targets.reduce( + (num, target) => num + get.effect(target, card, player, player), + 0 + ); + if (max == -1) { + if ( + game + .filterPlayer((target) => { + return lib.filter.targetEnabled2( + card, + player, + target + ) /*&&lib.filter.targetInRange(card,player,target)*/; + }) + .reduce((num, target) => num + get.effect(target, card, player, player), 0) > + sum + ) + return 0; } return sum; }, - position:'h', - discard:false, - lose:false, - delay:false, - async content(event,trigger,player){ - const card=event.cards[0],cards=player.getCards('h',cardx=>card!=cardx&&get.suit(card,player)==get.suit(cardx,player)); - await player.showCards([card],get.translation(player)+'发动了【纵势】'); - const cardx=new lib.element.VCard({name:get.name(card,player),nature:get.nature(card,player),cards:cards}); - const {result:{bool,targets}}=await player.chooseTarget((card,player,target)=>{ - //return player.canUse(get.event('cardx'),target); - return lib.filter.targetEnabled2(get.event('cardx'),player,target)/*&&lib.filter.targetInRange(get.event('cardx'),player,target)*/; - },true).set('cardx',cardx).set('selectTarget',[1,cards.length]) - .set('prompt','请选择'+(game.hasNature(cardx)?get.translation(get.nature(cardx)):'')+'【'+get.translation(cardx)+'】('+get.translation(cards)+')的目标') - .set('ai',target=>{ - const player=get.event('player'),card=get.event('cardx'); - return get.effect(target,card,player,player); + position: "h", + discard: false, + lose: false, + delay: false, + async content(event, trigger, player) { + const card = event.cards[0], + cards = player.getCards( + "h", + (cardx) => card != cardx && get.suit(card, player) == get.suit(cardx, player) + ); + await player.showCards([card], get.translation(player) + "发动了【纵势】"); + const cardx = new lib.element.VCard({ + name: get.name(card, player), + nature: get.nature(card, player), + cards: cards, }); - if(bool) player.useCard(cardx,cards,targets.sortBySeat()); + const { + result: { bool, targets }, + } = await player + .chooseTarget((card, player, target) => { + //return player.canUse(get.event('cardx'),target); + return lib.filter.targetEnabled2( + get.event("cardx"), + player, + target + ) /*&&lib.filter.targetInRange(get.event('cardx'),player,target)*/; + }, true) + .set("cardx", cardx) + .set("selectTarget", [1, cards.length]) + .set( + "prompt", + "请选择" + + (game.hasNature(cardx) ? get.translation(get.nature(cardx)) : "") + + "【" + + get.translation(cardx) + + "】(" + + get.translation(cards) + + ")的目标" + ) + .set("ai", (target) => { + const player = get.event("player"), + card = get.event("cardx"); + return get.effect(target, card, player, player); + }); + if (bool) player.useCard(cardx, cards, targets.sortBySeat()); }, - ai:{ - order:9, - result:{player:1}, + ai: { + order: 9, + result: { player: 1 }, }, }, - starjiaowang:{ - audio:2, - trigger:{global:'roundStart'}, - filter(event,player){ - if(game.roundNumber<=1) return false; - const history=game.getAllGlobalHistory(); - for(let i=history.length-2;i>=0;i--){ - const evt=history[i]['everything']; - for(let j=evt.length-1;j>=0;j--){ - if(evt[j].name=='die'&&evt[j].getParent(3).name!='starxiaoyan') return false; + starjiaowang: { + audio: 2, + trigger: { global: "roundStart" }, + filter(event, player) { + if (game.roundNumber <= 1) return false; + const history = game.getAllGlobalHistory(); + for (let i = history.length - 2; i >= 0; i--) { + const evt = history[i]["everything"]; + for (let j = evt.length - 1; j >= 0; j--) { + if (evt[j].name == "die" && evt[j].getParent(3).name != "starxiaoyan") + return false; } - if(history[i].isRound) break; + if (history[i].isRound) break; } return true; }, - forced:true, - async content(event,trigger,player){ + forced: true, + async content(event, trigger, player) { await player.loseHp(); - if(game.hasPlayer(current=>current!=player)) player.useResult({skill:'starxiaoyan'},event); + if (game.hasPlayer((current) => current != player)) + player.useResult({ skill: "starxiaoyan" }, event); }, }, - staraoshi:{ - audio:2, - zhuSkill:true, - global:'staraoshi_global', - subSkill:{ - global:{ - audio:'staraoshi', - forceaudio:true, - enable:'phaseUse', - filter(event,player){ - return player.group=='qun'&&game.hasPlayer(target=>lib.skill.staraoshi.subSkill.global.filterTarget(null,player,target)); + staraoshi: { + audio: 2, + zhuSkill: true, + global: "staraoshi_global", + subSkill: { + global: { + audio: "staraoshi", + forceaudio: true, + enable: "phaseUse", + filter(event, player) { + return ( + player.group == "qun" && + game.hasPlayer((target) => + lib.skill.staraoshi.subSkill.global.filterTarget(null, player, target) + ) + ); }, - filterTarget(card,player,target){ - return target!=player&&target.hasZhuSkill('staraoshi'); + filterTarget(card, player, target) { + return target != player && target.hasZhuSkill("staraoshi"); }, - prompt(){ - const player=get.event('player'); - const targets=game.filterPlayer(target=>lib.skill.staraoshi.subSkill.global.filterTarget(null,player,target)); - return '交给'+get.translation(targets)+(targets.length>1?'中的一人':'')+'一张手牌,然后其可以发动一次【纵势】'; + prompt() { + const player = get.event("player"); + const targets = game.filterPlayer((target) => + lib.skill.staraoshi.subSkill.global.filterTarget(null, player, target) + ); + return ( + "交给" + + get.translation(targets) + + (targets.length > 1 ? "中的一人" : "") + + "一张手牌,然后其可以发动一次【纵势】" + ); }, - filterCard:true, - check(card){ - const player=get.event('player'); - const target=game.filterPlayer(target=>{ - return lib.skill.staraoshi.subSkill.global.filterTarget(null,player,target); - }).sort((a,b)=>b.countCards('h')-a.countCards('h'))[0]; + filterCard: true, + check(card) { + const player = get.event("player"); + const target = game + .filterPlayer((target) => { + return lib.skill.staraoshi.subSkill.global.filterTarget( + null, + player, + target + ); + }) + .sort((a, b) => b.countCards("h") - a.countCards("h"))[0]; return target.getUseValue(card); }, - discard:false, - lose:false, - delay:false, - usable:1, - async content(event,trigger,player){ - const target=event.target,info=get.info('starzongshi'); - await player.give(event.cards,target); - const {result:{bool,cards}}= await target.chooseCard(info.position,(card,player)=>{ - return get.event('info').filterCard(card,player); - }).set('info',info).set('ai',card=>get.event('info').check(card)).set('selectCard',[1,2]).set('complexCard',true) - .set('prompt',get.prompt('starzongshi')).set('prompt2',lib.translate.starzongshi_info.slice(8).slice(0,-1)); - if(bool) target.useResult({skill:'starzongshi',cards:cards},event); + discard: false, + lose: false, + delay: false, + usable: 1, + async content(event, trigger, player) { + const target = event.target, + info = get.info("starzongshi"); + await player.give(event.cards, target); + const { + result: { bool, cards }, + } = await target + .chooseCard(info.position, (card, player) => { + return get.event("info").filterCard(card, player); + }) + .set("info", info) + .set("ai", (card) => get.event("info").check(card)) + .set("selectCard", [1, 2]) + .set("complexCard", true) + .set("prompt", get.prompt("starzongshi")) + .set("prompt2", lib.translate.starzongshi_info.slice(8).slice(0, -1)); + if (bool) target.useResult({ skill: "starzongshi", cards: cards }, event); }, - ai:{ - order:9, - result:{ - target(player,target){ - return target.countCards('h')+1; + ai: { + order: 9, + result: { + target(player, target) { + return target.countCards("h") + 1; }, }, }, @@ -483,637 +707,841 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //星董卓 - starweilin:{ - audio:2, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return !event.player.getHistory('damage').length&&player.getHistory('useCard').length>=event.player.getHp(); + starweilin: { + audio: 2, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + !event.player.getHistory("damage").length && + player.getHistory("useCard").length >= event.player.getHp() + ); }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { trigger.num++; }, }, - starzhangrong:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getHp()>0; + starzhangrong: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getHp() > 0; }, - direct:true, - content:function*(event,map){ - var player=map.player; - var str=get.cnNumber(player.getHp()); - var choiceList=[ - '令至多'+str+'名体力值大于等于你的角色各失去1点体力', - '令至多'+str+'名手牌数大于等于你的角色各弃置一张手牌', - ],list=['cancel2']; - if(game.hasPlayer(target=>{ - if(target==player) return player.countCards('h',card=>lib.filter.cardDiscardable(card,player)); - return target.countCards('h')>=Math.max(1,player.countCards('h')); - })) list.unshift('弃牌'); - else choiceList[1]=''+choiceList[1]+''; - list.unshift('扣血'); - var result=yield player.chooseControl(list).set('prompt','###'+get.prompt('starzhangrong')+'###选择其中一项令任意名符合条件的角色执行,然后你摸等量的牌,回合结束时,若这些角色中有本回合未受到过伤害的角色,则你失去1点体力').set('ai',()=>{ - var player=_status.event.player; - var controls=_status.event.controls.slice(); - /* + direct: true, + content: function* (event, map) { + var player = map.player; + var str = get.cnNumber(player.getHp()); + var choiceList = [ + "令至多" + str + "名体力值大于等于你的角色各失去1点体力", + "令至多" + str + "名手牌数大于等于你的角色各弃置一张手牌", + ], + list = ["cancel2"]; + if ( + game.hasPlayer((target) => { + if (target == player) + return player.countCards("h", (card) => + lib.filter.cardDiscardable(card, player) + ); + return target.countCards("h") >= Math.max(1, player.countCards("h")); + }) + ) + list.unshift("弃牌"); + else choiceList[1] = '' + choiceList[1] + ""; + list.unshift("扣血"); + var result = yield player + .chooseControl(list) + .set( + "prompt", + "###" + + get.prompt("starzhangrong") + + "###选择其中一项令任意名符合条件的角色执行,然后你摸等量的牌,回合结束时,若这些角色中有本回合未受到过伤害的角色,则你失去1点体力" + ) + .set("ai", () => { + var player = _status.event.player; + var controls = _status.event.controls.slice(); + /* var cards=player.getCards('hes',card=>get.tag(card,'damage')&&player.hasValueTarget(card)); var cardx=cards.filter(card=>get.name(card)=='sha'); cardx.sort((a,b)=>player.getUseValue(b)-player.getUseValue(a)); cardx=cardx.slice(Math.min(cardx.length,player.getCardUsable('sha')),cardx.length); cards.removeArray(cardx); */ - var targets1=game.filterPlayer(target=>get.attitude(player,target)<0&&target.getHp()>=player.getHp()&&get.effect(target,{name:'losehp'},player,player)>0/*&&cards.some(card=>player.canUse(card,target))*/); - _status.starzhangrong_check=true; - var targets2=game.filterPlayer(target=>get.attitude(player,target)<0&&target.countCards('h')>=Math.max(1,player.countCards('h'))&&get.effect(target,{name:'guohe_copy2'},player,player)>0/*&&cards.some(card=>player.canUse(card,target))*/); - delete _status.starzhangrong_check; - [targets1,targets2].forEach(list=>{ - list.sort((a,b)=>get.damageEffect(b)-get.damageEffect(a)); - list=list.slice(0,Math.min(player.getHp()/*,cards.length*/)); - }); - if(!controls.includes('弃牌')) return 1-get.sgn(targets1.length); - return Math.max(0,get.sgn(targets2.length-targets1.length)); - }).set('choiceList',choiceList); - if(result.control!='cancel2'){ - var choice=result.index; - var result2=yield player.chooseTarget([1,player.getHp()],'请选择【掌戎】的目标','令至多'+str+'名'+(choice?'手牌数':'体力值')+'大于你的角色各'+(choice?'弃置一张手牌':'失去1点体力'),(card,player,target)=>{ - var name=_status.event.card.name; - if(name=='guohe_copy2'){ - if(target==player) return player.countCards('h',card=>lib.filter.cardDiscardable(card,player)); - return target.countCards('h')>=Math.max(1,player.countCards('h')); - } - return target.getHp()>=player.getHp(); - }).set('ai',target=>{ - var player=_status.event.player; - if(get.attitude(player,target)>=0) return 0; - return get.effect(target,_status.event.card,player,player); - }).set('card',{name:choice?'guohe_copy2':'losehp'}); - if(result2.bool){ - var targets=result2.targets.sortBySeat(); - player.logSkill('starzhangrong',targets); - targets.forEach(target=>{ - target.addTempSkill('starzhangrong_threaten'); - if(choice) target.chooseToDiscard('h',true); + var targets1 = game.filterPlayer( + (target) => + get.attitude(player, target) < 0 && + target.getHp() >= player.getHp() && + get.effect(target, { name: "losehp" }, player, player) > + 0 /*&&cards.some(card=>player.canUse(card,target))*/ + ); + _status.starzhangrong_check = true; + var targets2 = game.filterPlayer( + (target) => + get.attitude(player, target) < 0 && + target.countCards("h") >= Math.max(1, player.countCards("h")) && + get.effect(target, { name: "guohe_copy2" }, player, player) > + 0 /*&&cards.some(card=>player.canUse(card,target))*/ + ); + delete _status.starzhangrong_check; + [targets1, targets2].forEach((list) => { + list.sort((a, b) => get.damageEffect(b) - get.damageEffect(a)); + list = list.slice(0, Math.min(player.getHp() /*,cards.length*/)); + }); + if (!controls.includes("弃牌")) return 1 - get.sgn(targets1.length); + return Math.max(0, get.sgn(targets2.length - targets1.length)); + }) + .set("choiceList", choiceList); + if (result.control != "cancel2") { + var choice = result.index; + var result2 = yield player + .chooseTarget( + [1, player.getHp()], + "请选择【掌戎】的目标", + "令至多" + + str + + "名" + + (choice ? "手牌数" : "体力值") + + "大于你的角色各" + + (choice ? "弃置一张手牌" : "失去1点体力"), + (card, player, target) => { + var name = _status.event.card.name; + if (name == "guohe_copy2") { + if (target == player) + return player.countCards("h", (card) => + lib.filter.cardDiscardable(card, player) + ); + return target.countCards("h") >= Math.max(1, player.countCards("h")); + } + return target.getHp() >= player.getHp(); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + if (get.attitude(player, target) >= 0) return 0; + return get.effect(target, _status.event.card, player, player); + }) + .set("card", { name: choice ? "guohe_copy2" : "losehp" }); + if (result2.bool) { + var targets = result2.targets.sortBySeat(); + player.logSkill("starzhangrong", targets); + targets.forEach((target) => { + target.addTempSkill("starzhangrong_threaten"); + if (choice) target.chooseToDiscard("h", true); else target.loseHp(); }); player.draw(targets.length); - player.when('phaseEnd').then(()=>{ - targets.forEach(target=>target.removeSkill('starzhangrong_threaten')); - var targetx=targets.filter(target=>!target.getHistory('damage').length); - if(targetx.length){ - targetx.forEach(target=>target.chat('乐')); - player.popup('杯具'); - player.loseHp(); - return; - } - player.popup('洗具'); - }).vars({targets:targets}); + player + .when("phaseEnd") + .then(() => { + targets.forEach((target) => target.removeSkill("starzhangrong_threaten")); + var targetx = targets.filter( + (target) => !target.getHistory("damage").length + ); + if (targetx.length) { + targetx.forEach((target) => target.chat("乐")); + player.popup("杯具"); + player.loseHp(); + return; + } + player.popup("洗具"); + }) + .vars({ targets: targets }); } } }, - global:'starzhangrong_check', - subSkill:{ - check:{ - mod:{ - canBeDiscarded:function(card,player,target){ - if(!_status.starzhangrong_check) return; - if(player.hasSkill('starzhangrong')&&get.position(card)!='h') return false; + global: "starzhangrong_check", + subSkill: { + check: { + mod: { + canBeDiscarded: function (card, player, target) { + if (!_status.starzhangrong_check) return; + if (player.hasSkill("starzhangrong") && get.position(card) != "h") + return false; }, }, }, - threaten:{ - charlotte:true, - trigger:{player:'damageEnd'}, - firstDo:true, - forced:true, - popup:false, - content:function(){ - player.removeSkill('starzhangrong_threaten'); + threaten: { + charlotte: true, + trigger: { player: "damageEnd" }, + firstDo: true, + forced: true, + popup: false, + content: function () { + player.removeSkill("starzhangrong_threaten"); }, - ai:{threaten:114514+1919810}, - mark:true, - markimage:'image/card/sha.png', - intro:{content:'我还没受到伤害哟!'}, + ai: { threaten: 114514 + 1919810 }, + mark: true, + markimage: "image/card/sha.png", + intro: { content: "我还没受到伤害哟!" }, }, }, }, - starhaoshou:{ - unique:true, - audio:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.player!=player&&event.card.name=='jiu'&&player.isDamaged()&&event.player.group=='qun'; + starhaoshou: { + unique: true, + audio: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return ( + event.player != player && + event.card.name == "jiu" && + player.isDamaged() && + event.player.group == "qun" + ); }, - direct:true, - zhuSkill:true, - content:function*(event,map){ - var player=map.player,target=map.trigger.player; - var result=yield target.chooseBool(get.prompt('starhaoshou',player),'令'+get.translation(player)+'回复1点体力').set('choice',get.recoverEffect(player,target,target)>0); - if(result.bool){ + direct: true, + zhuSkill: true, + content: function* (event, map) { + var player = map.player, + target = map.trigger.player; + var result = yield target + .chooseBool( + get.prompt("starhaoshou", player), + "令" + get.translation(player) + "回复1点体力" + ) + .set("choice", get.recoverEffect(player, target, target) > 0); + if (result.bool) { target.line(player); - player.logSkill('starhaoshou'); + player.logSkill("starhaoshou"); player.recover(); } }, //global:'starhaoshou_global', - subSkill:{ - global:{ - audio:'starhaoshou', - forceaudio:true, - filter:function(event,player){ - if(!player.countCards('hes',card=>{ - if(get.position(card)=='h'&&_status.connectMode) return true; - return get.name(card)=='jiu'; - })) return false; - return event.type=='dying'&&event.dying&&event.dying!=player&&event.dying.hp<=0&&event.dying.hasZhuSkill('starhaoshou')&&player.group=='qun'; + subSkill: { + global: { + audio: "starhaoshou", + forceaudio: true, + filter: function (event, player) { + if ( + !player.countCards("hes", (card) => { + if (get.position(card) == "h" && _status.connectMode) return true; + return get.name(card) == "jiu"; + }) + ) + return false; + return ( + event.type == "dying" && + event.dying && + event.dying != player && + event.dying.hp <= 0 && + event.dying.hasZhuSkill("starhaoshou") && + player.group == "qun" + ); }, - filterCard:function(card,player){ - return get.name(card)=='jiu'; + filterCard: function (card, player) { + return get.name(card) == "jiu"; }, - check:()=>1, - viewAs:{name:'tao'}, - position:'hes', - prompt:function(){ - return '将一张【酒】当作【桃】对'+get.translation(_status.event.dying)+'使用'; + check: () => 1, + viewAs: { name: "tao" }, + position: "hes", + prompt: function () { + return "将一张【酒】当作【桃】对" + get.translation(_status.event.dying) + "使用"; }, - ai:{ - save:true, - skillTagFilter:function(player,arg,target){ - if(!player.countCards('hes',card=>{ - if(get.position(card)=='h'&&_status.connectMode) return true; - return get.name(card)=='jiu'; - })||player==target||!target.hasSkill('starhaoshou')||player.group!='qun') return false; + ai: { + save: true, + skillTagFilter: function (player, arg, target) { + if ( + !player.countCards("hes", (card) => { + if (get.position(card) == "h" && _status.connectMode) return true; + return get.name(card) == "jiu"; + }) || + player == target || + !target.hasSkill("starhaoshou") || + player.group != "qun" + ) + return false; }, }, }, }, }, //星袁术 - starcanxi:{ - audio:2, - trigger:{ - global:['phaseBefore','roundStart'], - player:'enterGame', + starcanxi: { + audio: 2, + trigger: { + global: ["phaseBefore", "roundStart"], + player: "enterGame", }, - filter:function(event,player,name){ - if(name=='roundStart') return player.getSkills().some(skill=>skill.indexOf('starcanxi_')==0); - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player, name) { + if (name == "roundStart") + return player.getSkills().some((skill) => skill.indexOf("starcanxi_") == 0); + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - content:function(){ - 'step 0' - if(event.triggername!='roundStart'){ - var list=game.filterPlayer().reduce((list,target)=>list.add(target.group),[]); - list.sort((a,b)=>lib.group.indexOf(a)-lib.group.indexOf(b)); - list.forEach(group=>lib.skill.starcanxi.create(group,player)); + forced: true, + content: function () { + "step 0"; + if (event.triggername != "roundStart") { + var list = game.filterPlayer().reduce((list, target) => list.add(target.group), []); + list.sort((a, b) => lib.group.indexOf(a) - lib.group.indexOf(b)); + list.forEach((group) => lib.skill.starcanxi.create(group, player)); event.finish(); return; } - 'step 1' - var groups=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0); - groups=groups.map(group=>group.slice(10)); - groups.sort((a,b)=>lib.group.indexOf(a)-lib.group.indexOf(b)); - var map={}; - groups.forEach(group=>map[group]=get.translation(group+'2')); - event.map=map; - player.chooseButton([ - '###残玺###
              请选择势力和效果
              ', - [Object.values(map),'tdnodes'], - [[ - ['wangsheng',''], - ['xiangsi',''] - ],'textbutton'] - ],2,true).set('filterButton',function(button){ - var list=['wangsheng','xiangsi']; - if(!ui.selected.buttons.length) return true; - return list.includes(ui.selected.buttons[0].link)!=list.includes(button.link); - }).set('ai',function(button){ - var player=_status.event.player; - var map=_status.event.map,list=['wangsheng','xiangsi']; - var getNum=function(group,effect){ - var num=0,sgn=effect=='wangsheng'?1.05:-1; - game.countPlayer(function(current){ - if(!(current==player&&sgn==-1)) num+=get.sgn(get.attitude(player,current))*sgn; - }); - return num; - }; - var listx=[]; - Object.keys(map).forEach(group=>list.forEach(effect=>listx.add([group,effect]))); - listx.sort((a,b)=>getNum(b[0],b[1])-getNum(a[0],a[1])); - if(button.link==map[listx[0][0]]||button.link==listx[0][1]) return 1; - return 0; - }).set('map',map); - 'step 2' - if(result.bool){ - if(!Object.keys(event.map).some(group=>event.map[group]==result.links[0])) result.links.reverse(); + "step 1"; + var groups = player.getSkills().filter((skill) => skill.indexOf("starcanxi_") == 0); + groups = groups.map((group) => group.slice(10)); + groups.sort((a, b) => lib.group.indexOf(a) - lib.group.indexOf(b)); + var map = {}; + groups.forEach((group) => (map[group] = get.translation(group + "2"))); + event.map = map; + player + .chooseButton( + [ + '###残玺###
              请选择势力和效果
              ', + [Object.values(map), "tdnodes"], + [ + [ + [ + "wangsheng", + '', + ], + [ + "xiangsi", + '', + ], + ], + "textbutton", + ], + ], + 2, + true + ) + .set("filterButton", function (button) { + var list = ["wangsheng", "xiangsi"]; + if (!ui.selected.buttons.length) return true; + return list.includes(ui.selected.buttons[0].link) != list.includes(button.link); + }) + .set("ai", function (button) { + var player = _status.event.player; + var map = _status.event.map, + list = ["wangsheng", "xiangsi"]; + var getNum = function (group, effect) { + var num = 0, + sgn = effect == "wangsheng" ? 1.05 : -1; + game.countPlayer(function (current) { + if (!(current == player && sgn == -1)) + num += get.sgn(get.attitude(player, current)) * sgn; + }); + return num; + }; + var listx = []; + Object.keys(map).forEach((group) => + list.forEach((effect) => listx.add([group, effect])) + ); + listx.sort((a, b) => getNum(b[0], b[1]) - getNum(a[0], a[1])); + if (button.link == map[listx[0][0]] || button.link == listx[0][1]) return 1; + return 0; + }) + .set("map", map); + "step 2"; + if (result.bool) { + if (!Object.keys(event.map).some((group) => event.map[group] == result.links[0])) + result.links.reverse(); player.popup(result.links[0]); - var group=Object.keys(event.map).find(group=>event.map[group]==result.links[0]); - var skill='starcanxi_'+result.links[1]; + var group = Object.keys(event.map).find( + (group) => event.map[group] == result.links[0] + ); + var skill = "starcanxi_" + result.links[1]; player.popup(skill); - game.log(player,'选择了','#g'+result.links[0],'、','#y'+get.translation(skill)); - player.addTempSkill(skill,'roundStart'); - player.markAuto(skill,[group]); + game.log( + player, + "选择了", + "#g" + result.links[0], + "、", + "#y" + get.translation(skill) + ); + player.addTempSkill(skill, "roundStart"); + player.markAuto(skill, [group]); } }, - create:function(group,player){ - const skill='starcanxi_'+group; - get.info('starcanxi').createSkill(skill); - if(!_status.postReconnect.starcanxi){ - _status.postReconnect.starcanxi=[get.info('starcanxi').createSkill,[]]; + create: function (group, player) { + const skill = "starcanxi_" + group; + get.info("starcanxi").createSkill(skill); + if (!_status.postReconnect.starcanxi) { + _status.postReconnect.starcanxi = [get.info("starcanxi").createSkill, []]; } _status.postReconnect.starcanxi[1].add(skill); player.addSkill(skill); }, - createSkill(skill){ - if(!lib.skill[skill]) game.broadcastAll(skill=>{ - const group=skill.slice('starcanxi_'.length); - lib.skill[skill]={ - mark:true, - charlotte:true, - onremove:function(player){ - player.addMark('starpizhi',1,false); - }, - intro:{content:'玉玺的一角'}, - }; - lib.translate[skill]='残玺·'+get.translation(group+'2'); - lib.skill[skill].marktext=get.translation(group); - lib.translate[skill+'_bg']=get.translation(group); - },skill); + createSkill(skill) { + if (!lib.skill[skill]) + game.broadcastAll((skill) => { + const group = skill.slice("starcanxi_".length); + lib.skill[skill] = { + mark: true, + charlotte: true, + onremove: function (player) { + player.addMark("starpizhi", 1, false); + }, + intro: { content: "玉玺的一角" }, + }; + lib.translate[skill] = "残玺·" + get.translation(group + "2"); + lib.skill[skill].marktext = get.translation(group); + lib.translate[skill + "_bg"] = get.translation(group); + }, skill); }, - subSkill:{ - wangsheng:{ - charlotte:true, - onremove:true, - trigger:{global:'damageBegin1'}, - filter:function(event,player){ - if(!event.source||!player.getStorage('starcanxi_wangsheng').includes(event.source.group)) return false; - return !event.source.getHistory('sourceDamage').length; + subSkill: { + wangsheng: { + charlotte: true, + onremove: true, + trigger: { global: "damageBegin1" }, + filter: function (event, player) { + if ( + !event.source || + !player.getStorage("starcanxi_wangsheng").includes(event.source.group) + ) + return false; + return !event.source.getHistory("sourceDamage").length; }, - forced:true, - logTarget:'source', - content:function(){ + forced: true, + logTarget: "source", + content: function () { trigger.num++; }, - group:'starcanxi_remove', - global:'starcanxi_effect', - intro:{content:'$势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1'}, + group: "starcanxi_remove", + global: "starcanxi_effect", + intro: { content: "$势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1" }, }, - xiangsi:{ - charlotte:true, - onremove:true, - trigger:{global:'recoverEnd'}, - filter:function(event,player){ - if(!player.getStorage('starcanxi_xiangsi').includes(event.player.group)||event.player==player) return false; - return game.getGlobalHistory('changeHp',function(evt){ - return evt.getParent().name=='recover'&&evt.player==event.player; - }).length==1; + xiangsi: { + charlotte: true, + onremove: true, + trigger: { global: "recoverEnd" }, + filter: function (event, player) { + if ( + !player.getStorage("starcanxi_xiangsi").includes(event.player.group) || + event.player == player + ) + return false; + return ( + game.getGlobalHistory("changeHp", function (evt) { + return evt.getParent().name == "recover" && evt.player == event.player; + }).length == 1 + ); }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { trigger.player.loseHp(); }, - group:['starcanxi_remove','starcanxi_cancel'], - global:'starcanxi_effect', - intro:{content:'其他$势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效'}, - }, - cancel:{ - charlotte:true, - trigger:{global:'useCard'}, - filter:function(event,player){ - if(!event.targets||!event.targets.includes(player)||!player.getStorage('starcanxi_xiangsi').includes(event.player.group)||event.player==player) return false; - return event.player.getHistory('useCard',evt=>evt.targets&&evt.targets.includes(player)).indexOf(event)==0; + group: ["starcanxi_remove", "starcanxi_cancel"], + global: "starcanxi_effect", + intro: { + content: + "其他$势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效", }, - forced:true, - logTarget:'player', - content:function(){ + }, + cancel: { + charlotte: true, + trigger: { global: "useCard" }, + filter: function (event, player) { + if ( + !event.targets || + !event.targets.includes(player) || + !player.getStorage("starcanxi_xiangsi").includes(event.player.group) || + event.player == player + ) + return false; + return ( + event.player + .getHistory( + "useCard", + (evt) => evt.targets && evt.targets.includes(player) + ) + .indexOf(event) == 0 + ); + }, + forced: true, + logTarget: "player", + content: function () { trigger.excluded.add(player); }, }, - effect:{ - mod:{ - globalFrom:function(from,to,distance){ - if(game.hasPlayer(target=>target.getStorage('starcanxi_wangsheng').includes(from.group))) return distance-1; + effect: { + mod: { + globalFrom: function (from, to, distance) { + if ( + game.hasPlayer((target) => + target.getStorage("starcanxi_wangsheng").includes(from.group) + ) + ) + return distance - 1; }, }, - ai:{ - effect:{ - player_use:function(card,player,target){ - var targets=game.filterPlayer(targetx=>targetx!=player&&targetx.getStorage('starcanxi_xiangsi').includes(player.group)); - if(!targets.length) return; - if(get.tag(card,'recover')&&target==player&&target.hp>2) return 0; - if(get.tag(card,'damage')&&targets.includes(target)) return 0.5; + ai: { + effect: { + player_use: function (card, player, target) { + var targets = game.filterPlayer( + (targetx) => + targetx != player && + targetx.getStorage("starcanxi_xiangsi").includes(player.group) + ); + if (!targets.length) return; + if (get.tag(card, "recover") && target == player && target.hp > 2) + return 0; + if (get.tag(card, "damage") && targets.includes(target)) return 0.5; }, }, }, }, - remove:{ - charlotte:true, - trigger:{player:'die'}, - forced:true, - popup:false, - firstDo:true, - forceDie:true, - content:function(){ - player.removeSkill('starcanxi_wangsheng'); - player.removeSkill('starcanxi_xiangsi'); + remove: { + charlotte: true, + trigger: { player: "die" }, + forced: true, + popup: false, + firstDo: true, + forceDie: true, + content: function () { + player.removeSkill("starcanxi_wangsheng"); + player.removeSkill("starcanxi_xiangsi"); }, }, }, }, - starpizhi:{ - audio:2, - trigger:{player:'phaseEnd',global:'die'}, - filter:function(event,player){ - if(event.name=='phase') return player.hasMark('starpizhi'); - if(!player.getStorage('starcanxi_wangsheng').includes(event.player.group)&&!player.getStorage('starcanxi_xiangsi').includes(event.player.group)) return false; - var groups=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0); - groups=groups.map(group=>group.slice(10)); + starpizhi: { + audio: 2, + trigger: { player: "phaseEnd", global: "die" }, + filter: function (event, player) { + if (event.name == "phase") return player.hasMark("starpizhi"); + if ( + !player.getStorage("starcanxi_wangsheng").includes(event.player.group) && + !player.getStorage("starcanxi_xiangsi").includes(event.player.group) + ) + return false; + var groups = player.getSkills().filter((skill) => skill.indexOf("starcanxi_") == 0); + groups = groups.map((group) => group.slice(10)); return groups.includes(event.player.group); }, - forced:true, - content:function(){ - 'step 0' - if(trigger.name=='die'){ - var skills=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0&&skill.slice(10)==trigger.player.group); + forced: true, + content: function () { + "step 0"; + if (trigger.name == "die") { + var skills = player + .getSkills() + .filter( + (skill) => + skill.indexOf("starcanxi_") == 0 && + skill.slice(10) == trigger.player.group + ); player.removeSkill(skills); } - 'step 1' - player.draw(player.countMark('starpizhi')); + "step 1"; + player.draw(player.countMark("starpizhi")); }, - intro:{content:'已失去#个“玺角”'}, - ai:{combo:'starcanxi'}, + intro: { content: "已失去#个“玺角”" }, + ai: { combo: "starcanxi" }, }, - starzhonggu:{ - unique:true, - audio:2, - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ + starzhonggu: { + unique: true, + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { return !event.numFixed; }, - forced:true, - zhuSkill:true, - content:function(){ - var num=(game.roundNumber>=game.countPlayer(current=>current.group=='qun')?2:-1); - trigger.num+=num; + forced: true, + zhuSkill: true, + content: function () { + var num = + game.roundNumber >= game.countPlayer((current) => current.group == "qun") ? 2 : -1; + trigger.num += num; }, }, //星曹仁 - starsujun:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - return player.countCards('h',{type:'basic'})*2==player.countCards('h'); + starsujun: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + return player.countCards("h", { type: "basic" }) * 2 == player.countCards("h"); }, - frequent:true, - locked:false, - content:function(){ + frequent: true, + locked: false, + content: function () { player.draw(2); }, - mod:{ - aiOrder:function(player,card,num){ - var num=player.countCards('h')-2*player.countCards('h',{type:'basic'}); - if(Math.abs(num)!=1) return; - if(num==1&&get.type(card)!='basic') return num+10; - if(num==-1&&get.type(card)=='basic') return num+10; + mod: { + aiOrder: function (player, card, num) { + var num = player.countCards("h") - 2 * player.countCards("h", { type: "basic" }); + if (Math.abs(num) != 1) return; + if (num == 1 && get.type(card) != "basic") return num + 10; + if (num == -1 && get.type(card) == "basic") return num + 10; }, }, }, - starlifeng:{ - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - if(!event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)&&!event.filterCard(get.autoViewAs({name:'wuxie'},'unsure'),player,event)) return false; - return player.hasCard(card=>{ - return !player.getStorage('starlifeng_count').includes(get.color(card,player)); - },'hs'); + starlifeng: { + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + if ( + !event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) && + !event.filterCard(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) + ) + return false; + return player.hasCard((card) => { + return !player.getStorage("starlifeng_count").includes(get.color(card, player)); + }, "hs"); }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - if(event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)) list.push(['基本','','sha']); - if(event.filterCard(get.autoViewAs({name:'wuxie'},'unsure'),player,event)) list.push(['锦囊','','wuxie']); - return ui.create.dialog('砺锋',[list,'vcard']); + chooseButton: { + dialog: function (event, player) { + var list = []; + if (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event)) + list.push(["基本", "", "sha"]); + if (event.filterCard(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event)) + list.push(["锦囊", "", "wuxie"]); + return ui.create.dialog("砺锋", [list, "vcard"]); }, - check:function(button){ - var player=_status.event.player; - return _status.event.getParent().type=='phase'?player.getUseValue({name:button.link[2]}):1 + check: function (button) { + var player = _status.event.player; + return _status.event.getParent().type == "phase" + ? player.getUseValue({ name: button.link[2] }) + : 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:function(card,player){ - return !player.getStorage('starlifeng_count').includes(get.color(card,player)); + filterCard: function (card, player) { + return !player + .getStorage("starlifeng_count") + .includes(get.color(card, player)); }, - precontent:function(){ + precontent: function () { delete event.result.skill; - player.logSkill('starlifeng'); - event.getParent().addCount=false; + player.logSkill("starlifeng"); + event.getParent().addCount = false; }, - popname:true, - viewAs:{ - name:links[0][2], + popname: true, + viewAs: { + name: links[0][2], }, - ai1:function(card){ - var player=_status.event.player; - var num=player.countCards('h')-2*player.countCards('h',{type:'basic'}); - if(player.hasSkill('starsujin')&&Math.abs(num)==1){ - if(num==1&&get.type(card)!='basic') return 15-get.value(card); - if(num==-1&&get.type(card)=='basic') return 15-get.value(card); + ai1: function (card) { + var player = _status.event.player; + var num = + player.countCards("h") - 2 * player.countCards("h", { type: "basic" }); + if (player.hasSkill("starsujin") && Math.abs(num) == 1) { + if (num == 1 && get.type(card) != "basic") return 15 - get.value(card); + if (num == -1 && get.type(card) == "basic") return 15 - get.value(card); } - return 7-get.value(card); + return 7 - get.value(card); }, }; }, - prompt:function(links){ - return '将一张本回合未使用过的颜色的手牌当做【'+get.translation(links[0][2])+'】使用'; + prompt: function (links) { + return ( + "将一张本回合未使用过的颜色的手牌当做【" + get.translation(links[0][2]) + "】使用" + ); }, }, - hiddenCard:function(player,name){ - if(name=='wuxie') return player.countCards('hs',card=>{ - return !player.getStorage('starlifeng_count').includes(get.color(card,player))||_status.connectMode; - }); + hiddenCard: function (player, name) { + if (name == "wuxie") + return player.countCards("hs", (card) => { + return ( + !player.getStorage("starlifeng_count").includes(get.color(card, player)) || + _status.connectMode + ); + }); }, - ai:{ - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - if(!player.countCards('hs',card=>{ - return !player.getStorage('starlifeng_count').includes(get.color(card,player))||_status.connectMode; - })) return false; + ai: { + respondSha: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "respond") return false; + if ( + !player.countCards("hs", (card) => { + return ( + !player + .getStorage("starlifeng_count") + .includes(get.color(card, player)) || _status.connectMode + ); + }) + ) + return false; }, - order:10, - result:{player:1}, + order: 10, + result: { player: 1 }, }, - group:'starlifeng_mark', - subSkill:{ - mark:{ - charlotte:true, - trigger:{global:'useCard1'}, - filter:function(event,player){ - return !player.getStorage('starlifeng_count').includes(get.color(event.card)); + group: "starlifeng_mark", + subSkill: { + mark: { + charlotte: true, + trigger: { global: "useCard1" }, + filter: function (event, player) { + return !player.getStorage("starlifeng_count").includes(get.color(event.card)); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - player.addTempSkill('starlifeng_count'); - player.markAuto('starlifeng_count',[get.color(trigger.card)]); + forced: true, + popup: false, + firstDo: true, + content: function () { + player.addTempSkill("starlifeng_count"); + player.markAuto("starlifeng_count", [get.color(trigger.card)]); }, }, - count:{ - charlotte:true, - onremove:true, + count: { + charlotte: true, + onremove: true, }, }, }, //小程序刘伶 - mpjiusong:{ - audio:2, - enable:'chooseToUse', - trigger:{global:'useCard'}, - filterCard:function(card){ - return get.type2(card)=='trick'; + mpjiusong: { + audio: 2, + enable: "chooseToUse", + trigger: { global: "useCard" }, + filterCard: function (card) { + return get.type2(card) == "trick"; }, - viewAs:{name:'jiu'}, - position:'hs', - viewAsFilter:function(player){ - return player.hasCard(card=>get.type2(card)=='trick','hs'); + viewAs: { name: "jiu" }, + position: "hs", + viewAsFilter: function (player) { + return player.hasCard((card) => get.type2(card) == "trick", "hs"); }, - check:function(card){ - if(get.itemtype(card)!=='card') return true; - if(get.event().type=='dying') return 1/Math.max(0.1,get.value(card)); - return 4-get.value(card); + check: function (card) { + if (get.itemtype(card) !== "card") return true; + if (get.event().type == "dying") return 1 / Math.max(0.1, get.value(card)); + return 4 - get.value(card); }, - prompt:'将一张锦囊牌当【酒】使用', - filter:function(event,player){ - if(event.name=='chooseToUse') return player.hasCard(card=>get.type2(card)=='trick','hs'); - return event.card.name=='jiu'&&player.countMark('mpjiusong')<3; + prompt: "将一张锦囊牌当【酒】使用", + filter: function (event, player) { + if (event.name == "chooseToUse") + return player.hasCard((card) => get.type2(card) == "trick", "hs"); + return event.card.name == "jiu" && player.countMark("mpjiusong") < 3; }, - forced:true, - locked:false, - content:function(){ - player.addMark('mpjiusong'); + forced: true, + locked: false, + content: function () { + player.addMark("mpjiusong"); + }, + marktext: "醉", + intro: { + name: "醉(酒颂/酕醄)", + name2: "醉", + content: "mark", }, - marktext:'醉', - intro:{ - name:'醉(酒颂/酕醄)', - name2:'醉', - content:'mark', - } }, - mpmaotao:{ - audio:2, - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - if(event.targets.length!=1||!event.isFirstTarget) return false; - if(!['basic','trick'].includes(get.type(event.card))) return false; - return event.player!=player&&player.countMark('mpjiusong'); + mpmaotao: { + audio: 2, + trigger: { global: "useCardToPlayer" }, + filter: function (event, player) { + if (event.targets.length != 1 || !event.isFirstTarget) return false; + if (!["basic", "trick"].includes(get.type(event.card))) return false; + return event.player != player && player.countMark("mpjiusong"); }, - prompt2:function(event,player){ + prompt2: function (event, player) { let list; - if(get.type(event.card)!='delay') list=game.filterPlayer(current=>{ - return lib.filter.targetEnabled2(event.card,event.player,current); - }); - else list=game.filterPlayer(current=>current.canAddJudge(event.card)); - const gainText=`${list.length>1&&!player.storage.mpmaotao_gained?`若新目标与原目标相同,你`:''}${!player.storage.mpmaotao_gained?'获得牌堆中的一张锦囊牌。':''}`; - return `移去1枚“醉”${list.length>1?`,令${get.translation(event.card)}目标改为${get.translation(list)}中的一名随机角色`:''}。${gainText}`; + if (get.type(event.card) != "delay") + list = game.filterPlayer((current) => { + return lib.filter.targetEnabled2(event.card, event.player, current); + }); + else list = game.filterPlayer((current) => current.canAddJudge(event.card)); + const gainText = `${ + list.length > 1 && !player.storage.mpmaotao_gained ? `若新目标与原目标相同,你` : "" + }${!player.storage.mpmaotao_gained ? "获得牌堆中的一张锦囊牌。" : ""}`; + return `移去1枚“醉”${ + list.length > 1 + ? `,令${get.translation(event.card)}目标改为${get.translation( + list + )}中的一名随机角色` + : "" + }。${gainText}`; }, - check:function(event,player){ - const eff=get.effect(event.target,event.card,player,player); + check: function (event, player) { + const eff = get.effect(event.target, event.card, player, player); let list; - if(get.type(event.card)!='delay') list=game.filterPlayer(current=>{ - return lib.filter.targetEnabled2(event.card,event.player,current); - }); - else list=game.filterPlayer(current=>current.canAddJudge(event.card)); - let list2=list.filter(current=>get.effect(current,event.card,player,player)>eff); - let list3=list.filter(current=>get.effect(current,event.card,player,player)>0); - return list2.length>=list.length/2||player.countMark('mpjiusong')>=2&&list3.length>=list.length/2; + if (get.type(event.card) != "delay") + list = game.filterPlayer((current) => { + return lib.filter.targetEnabled2(event.card, event.player, current); + }); + else list = game.filterPlayer((current) => current.canAddJudge(event.card)); + let list2 = list.filter( + (current) => get.effect(current, event.card, player, player) > eff + ); + let list3 = list.filter((current) => get.effect(current, event.card, player, player) > 0); + return ( + list2.length >= list.length / 2 || + (player.countMark("mpjiusong") >= 2 && list3.length >= list.length / 2) + ); }, - content:function(){ - player.removeMark('mpjiusong',1); - var list,oriTarget=trigger.target; + content: function () { + player.removeMark("mpjiusong", 1); + var list, + oriTarget = trigger.target; trigger.targets.remove(oriTarget); trigger.getParent().triggeredTargets1.remove(oriTarget); trigger.untrigger(); game.delayx(); - if(get.type(trigger.card)!='delay') list=game.filterPlayer(current=>{ - return lib.filter.targetEnabled2(trigger.card,trigger.player,current); - }); - else list=game.filterPlayer(current=>current.canAddJudge(trigger.card)); - if(list.length) target=list.randomGet(); + if (get.type(trigger.card) != "delay") + list = game.filterPlayer((current) => { + return lib.filter.targetEnabled2(trigger.card, trigger.player, current); + }); + else list = game.filterPlayer((current) => current.canAddJudge(trigger.card)); + if (list.length) target = list.randomGet(); trigger.targets.push(target); - trigger.player.line(target,'thunder'); - game.log(trigger.card,'的目标被改为',target); - if(target==oriTarget&&!player.storage.mpmaotao_gained){ - var card=get.cardPile2(card=>get.type2(card)=='trick'); - if(card){ - if(!player.storage.mpmaotao_gained){ - player.when({global:'phaseAfter'}).then(()=>{ + trigger.player.line(target, "thunder"); + game.log(trigger.card, "的目标被改为", target); + if (target == oriTarget && !player.storage.mpmaotao_gained) { + var card = get.cardPile2((card) => get.type2(card) == "trick"); + if (card) { + if (!player.storage.mpmaotao_gained) { + player.when({ global: "phaseAfter" }).then(() => { delete player.storage.mpmaotao_gained; }); - player.storage.mpmaotao_gained=true; + player.storage.mpmaotao_gained = true; } - player.gain(card,'gain2'); - } - else{ + player.gain(card, "gain2"); + } else { // player.chat('没酒了!'); // game.log('但是牌堆中已经没有','#y酒','了!'); - player.chat('没牌了!'); - game.log('但是牌堆中已经没有','#y锦囊牌','了!'); + player.chat("没牌了!"); + game.log("但是牌堆中已经没有", "#y锦囊牌", "了!"); } } }, }, - mpbishi:{ - audio:2, - forced:true, - trigger:{global:'useCard1'}, - filter:function(event,player){ - if(get.type2(event.card)!='trick'||!get.tag(event.card,'damage')) return false; - if(!lib.skill.xunshi.isXunshi(event.card)) return false; - const targets=event.targets.slice(); + mpbishi: { + audio: 2, + forced: true, + trigger: { global: "useCard1" }, + filter: function (event, player) { + if (get.type2(event.card) != "trick" || !get.tag(event.card, "damage")) return false; + if (!lib.skill.xunshi.isXunshi(event.card)) return false; + const targets = event.targets.slice(); targets.remove(event.player); - return targets.length==game.countPlayer()-2; + return targets.length == game.countPlayer() - 2; + }, + content: function* () {}, + mod: { + targetEnabled: function (card) { + if (get.type2(card) == "trick" && get.tag(card, "damage") > 0) return false; + }, }, - content:function*(){}, - mod:{ - targetEnabled:function(card){ - if(get.type2(card)=='trick'&&get.tag(card,'damage')>0) return false; - } - } }, //十周年嵇康 dcjuexiang: { - derivation: 'dccanyun', - audio: 'juexiang', - trigger: { player: 'die' }, + derivation: "dccanyun", + audio: "juexiang", + trigger: { player: "die" }, forced: true, - locked:false, + locked: false, forceDie: true, skillAnimation: true, - animationColor: 'water', + animationColor: "water", content: function () { - 'step 0' + "step 0"; if (trigger.source && trigger.source.isIn()) { - trigger.source.discard(trigger.source.getCards('e')); + trigger.source.discard(trigger.source.getCards("e")); trigger.source.loseHp(); } - 'step 1' - player.chooseTarget('绝响:是否令一名其他角色获得技能〖残韵〗?', lib.filter.notMe).set('ai', function (target) { - return get.attitude(_status.event.player, target); - }).set('forceDie', true); - 'step 2' + "step 1"; + player + .chooseTarget("绝响:是否令一名其他角色获得技能〖残韵〗?", lib.filter.notMe) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("forceDie", true); + "step 2"; if (result.bool) { var target = result.targets[0]; - player.line(target, 'thunder'); - target.addSkills('dccanyun'); + player.line(target, "thunder"); + target.addSkills("dccanyun"); } }, }, dccanyun: { - enable: 'phaseUse', + enable: "phaseUse", filter: function (event, player) { return game.hasPlayer(function (target) { return lib.skill.dccanyun.filterTarget(null, player, target); @@ -1121,31 +1549,31 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, filterTarget: function (card, player, target) { var list = [player]; - player.getAllHistory('useSkill', function (evt) { - if (evt.skill == 'dccanyun') list.addArray(evt.targets); + player.getAllHistory("useSkill", function (evt) { + if (evt.skill == "dccanyun") list.addArray(evt.targets); }); return !list.includes(target) && !ui.selected.targets.length; }, selectTarget: [1, 2], targetprompt: function (target) { - var pe = _status.event.player.countCards('e', function (card) { + var pe = _status.event.player.countCards("e", function (card) { return ui.selected.cards.includes(card) == false; }); - var te = target.countCards('e'); - if (pe > te) return '回复体力'; - else if (pe == te) return '摸一张牌'; - else if (pe < te) return '失去体力'; + var te = target.countCards("e"); + if (pe > te) return "回复体力"; + else if (pe == te) return "摸一张牌"; + else if (pe < te) return "失去体力"; }, filterCard: true, - position: 'he', + position: "he", check: function (cardx) { var player = _status.event.player; var number = game.countPlayer(function (target) { if (player == target) return false; - var pe = player.countCards('e', function (card) { + var pe = player.countCards("e", function (card) { return card != cardx && ui.selected.cards.includes(card) == false; }); - var te = target.countCards('e'); + var te = target.countCards("e"); if (pe > te && target.isDamaged() && get.attitude(player, target) > 2) return true; else if (pe < te && get.attitude(player, target) < 0) return true; return false; @@ -1155,8 +1583,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, usable: 1, content: function () { - var pe = player.countCards('e'); - var te = target.countCards('e'); + var pe = player.countCards("e"); + var te = target.countCards("e"); if (pe > te) target.recover(); else if (pe == te) target.draw(); else if (pe < te) target.loseHp(); @@ -1168,8 +1596,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ order: 10, result: { target: function (player, target) { - var pe = player.countCards('e'); - var te = target.countCards('e'); + var pe = player.countCards("e"); + var te = target.countCards("e"); if (pe > te && target.isDamaged()) return 2; else if (pe == te) return 1; else if (pe < te) return -2.5; @@ -1179,1121 +1607,1519 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //董翓 - dcjiaoxia:{ - mod:{ - cardUsableTarget:function(card,player,target){ - if(!player.isPhaseUsing()) return; - if(card.name=='sha'&&!player.getStorage('dcjiaoxia_mark').includes(target)) return true; + dcjiaoxia: { + mod: { + cardUsableTarget: function (card, player, target) { + if (!player.isPhaseUsing()) return; + if (card.name == "sha" && !player.getStorage("dcjiaoxia_mark").includes(target)) + return true; }, - targetInRange:function(card,player,target){ - if(!player.isPhaseUsing()) return; - if(card.name=='sha'&&!player.getStorage('dcjiaoxia_mark').includes(target)) return true; + targetInRange: function (card, player, target) { + if (!player.isPhaseUsing()) return; + if (card.name == "sha" && !player.getStorage("dcjiaoxia_mark").includes(target)) + return true; }, }, - audio:2, - locked:false, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('h'); + audio: 2, + locked: false, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h"); }, - check:function(event,player){ - return player.countCards('h',card=>{ - return game.hasPlayer(target=>{ - var cardx=get.autoViewAs({name:'sha'},[card]); - return player.canUse(cardx,target)&&get.effect(target,cardx,player,player)>0&&(!player.hasUseTarget(card)||player.hasValueTarget(card)); + check: function (event, player) { + return player.countCards("h", (card) => { + return game.hasPlayer((target) => { + var cardx = get.autoViewAs({ name: "sha" }, [card]); + return ( + player.canUse(cardx, target) && + get.effect(target, cardx, player, player) > 0 && + (!player.hasUseTarget(card) || player.hasValueTarget(card)) + ); }); }); }, - content:function(){ - var cards=player.getCards('h'); - player.addTempSkill('dcjiaoxia_used','phaseUseAfter'); - player.addGaintag(cards,'dcjiaoxia_used'); + content: function () { + var cards = player.getCards("h"); + player.addTempSkill("dcjiaoxia_used", "phaseUseAfter"); + player.addGaintag(cards, "dcjiaoxia_used"); }, - group:'dcjiaoxia_load', - subSkill:{ - load:{ - charlotte:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(!player.isPhaseUsing()) return false; - return event.card.name=='sha'&&event.targets&&event.targets.some(target=>!player.getStorage('dcjiaoxia_mark').includes(target)); + group: "dcjiaoxia_load", + subSkill: { + load: { + charlotte: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (!player.isPhaseUsing()) return false; + return ( + event.card.name == "sha" && + event.targets && + event.targets.some( + (target) => !player.getStorage("dcjiaoxia_mark").includes(target) + ) + ); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - player.addTempSkill('dcjiaoxia_mark','phaseUseAfter'); - player.markAuto('dcjiaoxia_mark',trigger.targets.filter(target=>!player.getStorage('dcjiaoxia_mark').includes(target))); + forced: true, + popup: false, + firstDo: true, + content: function () { + player.addTempSkill("dcjiaoxia_mark", "phaseUseAfter"); + player.markAuto( + "dcjiaoxia_mark", + trigger.targets.filter( + (target) => !player.getStorage("dcjiaoxia_mark").includes(target) + ) + ); }, }, - mark:{ - charlotte:true, - onremove:true, + mark: { + charlotte: true, + onremove: true, }, - used:{ - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcjiaoxia_used')) return num+1; + used: { + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcjiaoxia_used")) + return num + 1; }, - cardname:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcjiaoxia_used')) return 'sha'; + cardname: function (card, player) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcjiaoxia_used")) + return "sha"; }, }, - charlotte:true, - onremove:function(player){ - player.removeGaintag('dcjiaoxia_used'); + charlotte: true, + onremove: function (player) { + player.removeGaintag("dcjiaoxia_used"); }, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.cards&&event.cards.length==1&&player.hasUseTarget(get.copy(event.cards[0]))&&player.getHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcjiaoxia_used')) return true; - } - return false; - }).length&&player.getHistory('sourceDamage',evt=>evt.card==event.card).length&&player.hasUseTarget(event.cards[0]); + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + event.cards && + event.cards.length == 1 && + player.hasUseTarget(get.copy(event.cards[0])) && + player.getHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcjiaoxia_used")) return true; + } + return false; + }).length && + player.getHistory("sourceDamage", (evt) => evt.card == event.card).length && + player.hasUseTarget(event.cards[0]) + ); }, - direct:true, - content:function(){ - player.chooseUseTarget(trigger.cards[0],get.prompt('dcjiaoxia'),false,false).set('prompt2','使用'+get.translation(card)).logSkill='dcjiaoxia'; + direct: true, + content: function () { + player + .chooseUseTarget(trigger.cards[0], get.prompt("dcjiaoxia"), false, false) + .set("prompt2", "使用" + get.translation(card)).logSkill = "dcjiaoxia"; }, }, }, }, - dchumei:{ - subSkill:{ - 0:{charlotte:true}, - 1:{charlotte:true}, - 2:{charlotte:true}, + dchumei: { + subSkill: { + 0: { charlotte: true }, + 1: { charlotte: true }, + 2: { charlotte: true }, }, - onChooseToUse:function(event){ - if(!game.online&&!event.dchumei_num){ - var player=event.player; - var evtx=event.getParent('phaseUse'); - event.set('dchumei_num',player.getHistory('sourceDamage',evt=>{ - return evt.getParent('phaseUse')==evtx; - }).reduce((sum,evt)=>sum+evt.num,0)); + onChooseToUse: function (event) { + if (!game.online && !event.dchumei_num) { + var player = event.player; + var evtx = event.getParent("phaseUse"); + event.set( + "dchumei_num", + player + .getHistory("sourceDamage", (evt) => { + return evt.getParent("phaseUse") == evtx; + }) + .reduce((sum, evt) => sum + evt.num, 0) + ); } }, - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(typeof event.dchumei_num!='number') return false; - return game.hasPlayer(target=>lib.skill.dchumei.filterTarget(null,player,target)); + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (typeof event.dchumei_num != "number") return false; + return game.hasPlayer((target) => lib.skill.dchumei.filterTarget(null, player, target)); }, - filterTarget:function(card,player,target){ - if(target.getHp()>_status.event.dchumei_num) return false; - if(!player.hasSkill('dchumei_0')) return true; - if(!player.hasSkill('dchumei_1')&&target.countCards('he')) return true; - if(!player.hasSkill('dchumei_2')&&target.isDamaged()) return true; + filterTarget: function (card, player, target) { + if (target.getHp() > _status.event.dchumei_num) return false; + if (!player.hasSkill("dchumei_0")) return true; + if (!player.hasSkill("dchumei_1") && target.countCards("he")) return true; + if (!player.hasSkill("dchumei_2") && target.isDamaged()) return true; return false; }, - content:function(){ - 'step 0' - var str=get.translation(target); - player.chooseButton([ - '狐魅:请选择一项', - [[ - [0,'令'+str+'摸一张牌'], - [1,'令'+str+'交给你一张牌'], - [2,'令'+str+'回复1点体力'], - ].filter(list=>{ - if(player.hasSkill('dchumei_'+list[0])) return false; - if(list[0]==1&&!target.countCards('he')) return false; - if(list[0]==2&&target.isHealthy()) return false; + content: function () { + "step 0"; + var str = get.translation(target); + player + .chooseButton( + [ + "狐魅:请选择一项", + [ + [ + [0, "令" + str + "摸一张牌"], + [1, "令" + str + "交给你一张牌"], + [2, "令" + str + "回复1点体力"], + ].filter((list) => { + if (player.hasSkill("dchumei_" + list[0])) return false; + if (list[0] == 1 && !target.countCards("he")) return false; + if (list[0] == 2 && target.isHealthy()) return false; + return true; + }), + "textbutton", + ], + ], + true + ) + .set("filterButton", (button) => { + var target = _status.event.target; + if (player.hasSkill("dchumei_" + button.link)) return false; + if (button.link == 1 && !target.countCards("he")) return false; + if (button.link == 2 && target.isHealthy()) return false; return true; - }),'textbutton'] - ],true).set('filterButton',button=>{ - var target=_status.event.target; - if(player.hasSkill('dchumei_'+button.link)) return false; - if(button.link==1&&!target.countCards('he')) return false; - if(button.link==2&&target.isHealthy()) return false; - return true; - }).set('ai',function(button){ - var target=_status.event.target; - return [ - get.effect(target,{name:'draw'},player,player), - get.effect(target,{name:'shunshou_copy2'},player,player), - get.recoverEffect(target,player,player), - ][button.link]; - }).set('target',target); - 'step 1' - if(result.bool){ - var num=result.links[0]; - player.addTempSkill('dchumei_'+num,'phaseUseAfter'); - switch(num){ + }) + .set("ai", function (button) { + var target = _status.event.target; + return [ + get.effect(target, { name: "draw" }, player, player), + get.effect(target, { name: "shunshou_copy2" }, player, player), + get.recoverEffect(target, player, player), + ][button.link]; + }) + .set("target", target); + "step 1"; + if (result.bool) { + var num = result.links[0]; + player.addTempSkill("dchumei_" + num, "phaseUseAfter"); + switch (num) { case 0: - target.draw(); - break; + target.draw(); + break; case 1: - target.chooseCard('狐魅:交给'+get.translation(player)+'一张牌','he',true); - break; + target.chooseCard( + "狐魅:交给" + get.translation(player) + "一张牌", + "he", + true + ); + break; case 2: - target.recover(); - break; + target.recover(); + break; } - if(num!=1) event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool) player.gain(result.cards,target,'giveAuto'); + if (num != 1) event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) player.gain(result.cards, target, "giveAuto"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(!player.hasSkill('dchumei_0')) return 1; - if(!player.hasSkill('dchumei_1')) return -1; - if(!player.hasSkill('dchumei_2')) return 1; + ai: { + order: 1, + result: { + target: function (player, target) { + if (!player.hasSkill("dchumei_0")) return 1; + if (!player.hasSkill("dchumei_1")) return -1; + if (!player.hasSkill("dchumei_2")) return 1; }, }, }, }, //魏关羽 - dcdanji:{ - audio:'danji', - skillAnimation:true, - animationColor:'water', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - derivation:['mashu','dcnuchen'], - filter:function(event,player){ - return player.countCards('h')>player.hp; + dcdanji: { + audio: "danji", + skillAnimation: true, + animationColor: "water", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + derivation: ["mashu", "dcnuchen"], + filter: function (event, player) { + return player.countCards("h") > player.hp; }, - async content(event, trigger, player){ - player.awakenSkill('dcdanji'); + async content(event, trigger, player) { + player.awakenSkill("dcdanji"); await player.loseMaxHp(); - await player.recover(player.maxHp-player.hp); - await player.addSkills(['mashu','dcnuchen']); + await player.recover(player.maxHp - player.hp); + await player.addSkills(["mashu", "dcnuchen"]); }, - ai:{ - maixie:true, - skillTagFilter:(player,tag,arg)=>{ - if(tag==='maixie') return player.hp>=2&&!player.storage.dcdanji&&!player.hasSkill('dcnuchen')&&player.countCards('h')===player.hp; + ai: { + maixie: true, + skillTagFilter: (player, tag, arg) => { + if (tag === "maixie") + return ( + player.hp >= 2 && + !player.storage.dcdanji && + !player.hasSkill("dcnuchen") && + player.countCards("h") === player.hp + ); }, - effect:{ - target:(card,player,target)=>{ - let hs=target.countCards('h'); - if(target.hp<3||target.storage.dcdanji||target.hasSkill('dcnuchen')||hs>target.hp+1) return; - if(get.tag(card,'draw')) return 1.6; - if(get.tag(card,'lose')||get.tag(card,'discard')) return [1,-0.8]; - if(hs===target.hp&&get.tag(card,'damage')) return [1,target.hp/3]; - if(hs>target.hp&&target.hp>3&&(card.name==='shan'||card.name==='wuxie')) return 'zeroplayertarget'; - } - } - } + effect: { + target: (card, player, target) => { + let hs = target.countCards("h"); + if ( + target.hp < 3 || + target.storage.dcdanji || + target.hasSkill("dcnuchen") || + hs > target.hp + 1 + ) + return; + if (get.tag(card, "draw")) return 1.6; + if (get.tag(card, "lose") || get.tag(card, "discard")) return [1, -0.8]; + if (hs === target.hp && get.tag(card, "damage")) return [1, target.hp / 3]; + if ( + hs > target.hp && + target.hp > 3 && + (card.name === "shan" || card.name === "wuxie") + ) + return "zeroplayertarget"; + }, + }, + }, }, - dcnuchen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('h')&&target!=player; + dcnuchen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("h") && target != player; }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,true,'h'); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - event.card=card; - player.showCards(card,get.translation(player)+'对'+get.translation(target)+'发动了【怒嗔】'); - } - else event.finish(); - 'step 2' - var suit=get.suit(card); - var str=get.translation(suit); - player.chooseToDiscard('怒嗔:是否弃置至少一张'+str+'牌?','若如此做,你对其造成等量伤害;或点击“取消”,获得其所有'+str+'手牌','he',{suit:suit},[1,Infinity]).set('ai',card=>{ - if(ui.selected.cards.length>=_status.event.num) return 0; - return 6-get.value(card); - }).set('num',function(){ - var eff=get.damageEffect(target,player,player); - if(eff>0){ - if(get.attitude(player,target)>0){ - return 1; - } - var cards=target.getCards('h',{suit:suit}); - if(cards.length>2||get.value(cards)>=6){ + content: function () { + "step 0"; + player.choosePlayerCard(target, true, "h"); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + player.showCards( + card, + get.translation(player) + "对" + get.translation(target) + "发动了【怒嗔】" + ); + } else event.finish(); + "step 2"; + var suit = get.suit(card); + var str = get.translation(suit); + player + .chooseToDiscard( + "怒嗔:是否弃置至少一张" + str + "牌?", + "若如此做,你对其造成等量伤害;或点击“取消”,获得其所有" + str + "手牌", + "he", + { suit: suit }, + [1, Infinity] + ) + .set("ai", (card) => { + if (ui.selected.cards.length >= _status.event.num) return 0; + return 6 - get.value(card); + }) + .set( + "num", + (function () { + var eff = get.damageEffect(target, player, player); + if (eff > 0) { + if (get.attitude(player, target) > 0) { + return 1; + } + var cards = target.getCards("h", { suit: suit }); + if (cards.length > 2 || get.value(cards) >= 6) { + return 0; + } + if ( + !player.hasSkillTag("jueqing", false, target) && + target.hasSkillTag("filterDamage", null, { player: player }) + ) + return 1; + return Infinity; + } return 0; - } - if(!player.hasSkillTag('jueqing',false,target)&&target.hasSkillTag('filterDamage',null,{player:player})) return 1; - return Infinity; - } - return 0; - }()); - 'step 3' - if(result.bool){ + })() + ); + "step 3"; + if (result.bool) { target.damage(result.cards.length); - } - else{ - var cards=target.getCards('h',{suit:get.suit(card)}); - if(cards.length) player.gain(cards,target,'giveAuto','bySelf'); + } else { + var cards = target.getCards("h", { suit: get.suit(card) }); + if (cards.length) player.gain(cards, target, "giveAuto", "bySelf"); } }, - ai:{ - expose:0.4, - order:10, - result:{ - target:function(player,target){ - return -Math.sqrt(target.countCards('h')); - } - } - } + ai: { + expose: 0.4, + order: 10, + result: { + target: function (player, target) { + return -Math.sqrt(target.countCards("h")); + }, + }, + }, }, //孟达 - dclibang:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filter:function(event,player){ - return player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'dclibang'); - },'he')&&game.countPlayer(current=>current!=player)>=2; + dclibang: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filter: function (event, player) { + return ( + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "dclibang"); + }, "he") && game.countPlayer((current) => current != player) >= 2 + ); }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - selectTarget:2, - multiline:true, - multitarget:true, - content:function(){ - 'step 0' - event.num=0; - event.cardsx=[]; + selectTarget: 2, + multiline: true, + multitarget: true, + content: function () { + "step 0"; + event.num = 0; + event.cardsx = []; event.targets.sortBySeat(); - 'step 1' - var current=targets[event.num]; - if(current.countCards('he')) player.gainPlayerCard(current,'he',true,'visibleMove'); + "step 1"; + var current = targets[event.num]; + if (current.countCards("he")) player.gainPlayerCard(current, "he", true, "visibleMove"); event.num++; - 'step 2' - if(result.bool){ - var card=result.cards[0]; + "step 2"; + if (result.bool) { + var card = result.cards[0]; event.cardsx.push(card); } - if(event.num{ - return player.canUse('sha',target); + "step 1"; + var targets = event.getParent(2).targets.filter((target) => { + return player.canUse("sha", target); }); - if(!targets.length) event.finish(); - else player.chooseTarget('利傍:视为对其中一名角色使用一张【杀】',true,(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',targets).set('ai',target=>{ - return get.effect(target,{name:'sha'},player,player); - }); - 'step 2' - if(result.bool){ - player.useCard({name:'sha',isCard:true},result.targets[0],false); + if (!targets.length) event.finish(); + else + player + .chooseTarget( + "利傍:视为对其中一名角色使用一张【杀】", + true, + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("targets", targets) + .set("ai", (target) => { + return get.effect(target, { name: "sha" }, player, player); + }); + "step 2"; + if (result.bool) { + player.useCard({ name: "sha", isCard: true }, result.targets[0], false); } event.finish(); - 'step 3' + "step 3"; player.chooseCardTarget({ - filterCard:function(card){ - return get.itemtype(card)=='card'; + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return _status.event.targets.includes(target); }, - selectCard:2, - targets:event.getParent(2).targets, - position:'he', - prompt:'交给其中一名角色两张牌,或失去1点体力', - ai1:function(card){ + selectCard: 2, + targets: event.getParent(2).targets, + position: "he", + prompt: "交给其中一名角色两张牌,或失去1点体力", + ai1: function (card) { return 1; }, - ai2:function(target){ - var player=_status.event.player,card=ui.selected.cards[0]; - var val=get.value(card,target); - if(val>0) return get.attitude(player,target)*2; - return (val-2)*get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player, + card = ui.selected.cards[0]; + var val = get.value(card, target); + if (val > 0) return get.attitude(player, target) * 2; + return (val - 2) * get.attitude(player, target); }, }); - 'step 4' - if(result.bool){ - player.give(result.cards,result.targets[0]); - } - else player.loseHp(); + "step 4"; + if (result.bool) { + player.give(result.cards, result.targets[0]); + } else player.loseHp(); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0&&ui.selected.targets.length) return 0.1; + ai: { + order: 8, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0 && ui.selected.targets.length) return 0.1; return -1; - } - } - } + }, + }, + }, }, - dcwujie:{ - audio:2, - trigger:{ - global:['discardBegin','drawBegin'], + dcwujie: { + audio: 2, + trigger: { + global: ["discardBegin", "drawBegin"], }, - forced:true, - forceDie:true, - group:'dcwujie_inf', - logTarget:'player', - filter:function(event,player){ - return event.getParent().name=='die'&&event.getParent().source==event.player&&event.player!=player&&event.getParent().player==player; + forced: true, + forceDie: true, + group: "dcwujie_inf", + logTarget: "player", + filter: function (event, player) { + return ( + event.getParent().name == "die" && + event.getParent().source == event.player && + event.player != player && + event.getParent().player == player + ); }, - content:function(){ + content: function () { trigger.cancel(); }, - subSkill:{ - inf:{ - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - if(get.color(event.card)=='none'&&event.addCount!==false) return true; + subSkill: { + inf: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + if (get.color(event.card) == "none" && event.addCount !== false) return true; return false; }, - content:function(){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + content: function () { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; }, - } + }, }, - mod:{ - targetInRange:function(card,player){ + mod: { + targetInRange: function (card, player) { const color = get.color(card); - if (color === 'none' || color === 'unsure') return true; + if (color === "none" || color === "unsure") return true; }, - cardUsable:function(card){ + cardUsable: function (card) { const color = get.color(card); - if (color === 'none' || color === 'unsure') return Infinity; + if (color === "none" || color === "unsure") return Infinity; }, - } + }, }, //关宁 - dcxiuwen:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - return !player.getStorage('dcxiuwen').includes(event.card.name); + dcxiuwen: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + return !player.getStorage("dcxiuwen").includes(event.card.name); }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); - player.markAuto('dcxiuwen',[trigger.card.name]); + player.markAuto("dcxiuwen", [trigger.card.name]); }, - intro:{content:'已使用:$'} + intro: { content: "已使用:$" }, }, - oldlongsong:{ - audio:'dclongsong', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + oldlongsong: { + audio: "dclongsong", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - getSkills:function(target,player,trigger){ - return target.getSkills(null,false).filter(skill=>{ - var skills=game.expandSkills([skill]); - if(skills.filter(skillx=>{ - var info=get.info(skillx); - if(!info||!info.enable||(info.usable&&!(info.usable>=1))) return false; - if(info.enable!='phaseUse'&&(!Array.isArray(info.enable)||!info.enable.includes('phaseUse'))) return false; - if(info.viewAs&&info.usable&&info.usable!=1) return false; - if(info.juexingji||info.hiddenSkill||info.charlotte||info.limited||info.dutySkill) return false; - if((!info.usable||info.usable>1)&&info.filter){ - try{ - var bool1=info.filter(trigger,player); - var num=player.getStat().skill[skillx]; - player.getStat().skill[skillx]=1; - var bool2=info.filter(trigger,player); - if(!num) delete player.getStat().skill[skillx]; - else player.getStat().skill[skillx]=num; - var bool3=!(bool1&&!bool2); - } catch (e) { - console.trace(e); + getSkills: function (target, player, trigger) { + return target.getSkills(null, false).filter((skill) => { + var skills = game.expandSkills([skill]); + if ( + skills.filter((skillx) => { + var info = get.info(skillx); + if (!info || !info.enable || (info.usable && !(info.usable >= 1))) + return false; + if ( + info.enable != "phaseUse" && + (!Array.isArray(info.enable) || !info.enable.includes("phaseUse")) + ) + return false; + if (info.viewAs && info.usable && info.usable != 1) return false; + if ( + info.juexingji || + info.hiddenSkill || + info.charlotte || + info.limited || + info.dutySkill + ) + return false; + if ((!info.usable || info.usable > 1) && info.filter) { + try { + var bool1 = info.filter(trigger, player); + var num = player.getStat().skill[skillx]; + player.getStat().skill[skillx] = 1; + var bool2 = info.filter(trigger, player); + if (!num) delete player.getStat().skill[skillx]; + else player.getStat().skill[skillx] = num; + var bool3 = !(bool1 && !bool2); + } catch (e) { + console.trace(e); + } + if ( + !bool1 && + !bool2 && + get.skillInfoTranslation(skill, player).indexOf("出牌阶段限一次") == + -1 + ) + return false; + if ((bool1 || bool2) && bool3) return false; } - if(!bool1&&!bool2&&get.skillInfoTranslation(skill,player).indexOf('出牌阶段限一次')==-1) return false; - if((bool1||bool2)&&bool3) return false; - } + return true; + }).length + ) return true; - }).length) return true; return false; }); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:true, - selectCard:1, - filterTarget:function(card,player,target){ - return player!=target; + filterCard: true, + selectCard: 1, + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - return 6-get.value(card); + ai1: function (card) { + return 6 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target),trigger=_status.event.getTrigger(),player=_status.event.player; - return lib.skill.oldlongsong.getSkills(target,player,trigger).length*3+att/3; + ai2: function (target) { + var att = get.attitude(_status.event.player, target), + trigger = _status.event.getTrigger(), + player = _status.event.player; + return ( + lib.skill.oldlongsong.getSkills(target, player, trigger).length * 3 + att / 3 + ); }, - prompt:get.prompt2('oldlongsong') + prompt: get.prompt2("oldlongsong"), }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('oldlongsong',target); - event.target=target; - player.line(target,'green'); - player.give(result.cards,target); - var skills=lib.skill.oldlongsong.getSkills(target,player,trigger); - if(skills.length){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - target.disableSkill('oldlongsong_back',skills); - target.markAuto('oldlongsong_back',skills); - target.addTempSkill('oldlongsong_back',['phaseUseAfter','phaseAfter']); - var str=''; - for(var i=0; i0; + player.popup(skills, "thunder"); + }, + }, }, - getSkills:function(target){ - return target.getSkills(null,false).filter(skill=>{ - var str=get.skillInfoTranslation(skill,target); - if(str.indexOf('当你于出牌阶段')!=-1) return true; - var skills=game.expandSkills([skill]); - if(skills.some(skillx=>{ - var info=get.info(skillx); - if(!info||!info.enable) return false; - if(info.enable!='phaseUse'&&info.enable!='chooseToUse'&&(!Array.isArray(info.enable)||!info.enable.includes('phaseUse')&&!info.enable.includes('chooseToUse'))) return false; - if(info.juexingji||info.hiddenSkill||info.charlotte||info.limited||info.dutySkill) return false; - if(info.ai&&info.ai.notemp) return false; + }, + dclongsong: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + getSkills: function (target) { + return target.getSkills(null, false).filter((skill) => { + var str = get.skillInfoTranslation(skill, target); + if (str.indexOf("当你于出牌阶段") != -1) return true; + var skills = game.expandSkills([skill]); + if ( + skills.some((skillx) => { + var info = get.info(skillx); + if (!info || !info.enable) return false; + if ( + info.enable != "phaseUse" && + info.enable != "chooseToUse" && + (!Array.isArray(info.enable) || + (!info.enable.includes("phaseUse") && + !info.enable.includes("chooseToUse"))) + ) + return false; + if ( + info.juexingji || + info.hiddenSkill || + info.charlotte || + info.limited || + info.dutySkill + ) + return false; + if (info.ai && info.ai.notemp) return false; + return true; + }) + ) return true; - })) return true; return false; }); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:{color:'red'}, - selectCard:1, - position:'he', - filterTarget:function(card,player,target){ - return player!=target; + filterCard: { color: "red" }, + selectCard: 1, + position: "he", + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - return 6-get.value(card); + ai1: function (card) { + return 6 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - return lib.skill.dclongsong.getSkills(target).length*2+att/2.5; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + return lib.skill.dclongsong.getSkills(target).length * 2 + att / 2.5; }, - prompt:get.prompt2('dclongsong') + prompt: get.prompt2("dclongsong"), }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dclongsong',target); - event.target=target; - player.line(target,'green'); - player.give(result.cards,target); - var skills=lib.skill.dclongsong.getSkills(target); - if(skills.length){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - target.disableSkill('dclongsong_back',skills); - target.markAuto('dclongsong_back',skills); - player.addTempSkill('dclongsong_remove',['phaseUseAfter','phaseAfter']); - player.markAuto('dclongsong_remove',skills); - target.addTempSkill('dclongsong_back',['phaseUseAfter','phaseAfter']); - var str=''; - for(var i=0; i { + if (target == player) return false; + return target.hasCard((card) => { + if (get.position(card) == "h") return true; + return get.color(card) == "red" && lib.filter.canBeGained(card, player, target); + }, "he"); + }); + }, + async cost(event, trigger, player) { + const func = function (player) { + game.countPlayer((target) => { + if (target != player) { + const skills = lib.skill.dclongsong.getSkills(target); + if (skills.length) { + target.prompt(skills.map((i) => get.translation(i)).join("
              ")); + } + } + }); + }; + if (event.player == game.me) func(player); + else if (event.isOnline()) player.send(func, player); + event.result = await player + .chooseTarget(get.prompt2("longsong"), (card, player, target) => { + if (target == player) return false; + return target.hasCard((card) => { + if (get.position(card) == "h") return true; + return ( + get.color(card) == "red" && lib.filter.canBeGained(card, player, target) + ); + }, "he"); + }) + .set("ai", (target) => { + const player = get.event("player"), + att = get.attitude(player, target); + if ( + att > 0 && + !target + .getGainableCards(player, "he") + .some((card) => get.color(card) == "red") + ) + return 0; + return ( + lib.skill.dclongsong.getSkills(target).length + + (att > 0 + ? 0 + : Math.max( + 0, + get.effect(target, { name: "shunshou_copy2" }, player, player) + )) + ); + }) + .forResult(); + }, + async content(event, trigger, player) { + const target = event.targets[0], + cards = target + .getGainableCards(player, "he") + .filter((card) => get.color(card) == "red"); + if (cards.length) { + let dialog = ["龙诵:获得" + get.translation(target) + "的一张红色牌"]; + let cards1 = cards.filter((i) => get.position(i) == "h"), + cards2 = cards.filter((i) => get.position(i) == "e"); + if (cards1.length) { + dialog.push('
              手牌区
              '); + if (player.hasSkillTag("viewHandcard", null, target, true)) dialog.push(cards1); + else dialog.push([cards1.randomSort(), "blank"]); + } + if (cards2.length) { + dialog.push('
              装备区
              '); + dialog.push(cards2); + } + const { + result: { bool, links }, + } = await player.chooseButton(dialog, true).set("ai", (button) => { + const player = get.event("player"), + target = get.event().getParent().targets[0]; + return get.value(button.link, player) * get.value(button.link, target) * (1 + Math.random()); + }); + if (bool) { + await player.gain(links, target, "giveAuto", "bySelf"); + const skills = lib.skill.dclongsong.getSkills(target); + if (skills.length) { + if (!event.isMine() && !event.isOnline()) await game.asyncDelayx(); + for (const skill of skills) { + player.popup(skill, "thunder"); + await player.addTempSkills(skill, ["phaseUseAfter", "phaseAfter"]); + } + } + } + } else { + player.popup("杯具"); + player.chat("无牌可得?!"); + game.log("但是", target, "没有红色牌可被" + get.translation(player) + "获得!"); } - } + }, }, //伏完 - dcmoukui:{ - audio:'moukui', - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.isFirstTarget; + dcmoukui: { + audio: "moukui", + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.isFirstTarget; }, - content:function(){ - 'step 0' - player.chooseButton([ - get.prompt('dcmoukui'), - [[ - ['draw','摸一张牌'], - ['discard','弃置'+(trigger.targets.length==1?get.translation(trigger.targets[0]):'一名目标角色')+'的一张牌'] - ],'textbutton'] - ]).set('filterButton',button=>{ - if(button.link=='discard'&&_status.event.getTrigger().targets.every(target=>{ - return target.countDiscardableCards(_status.event.player,'he')==0; - })) return false; - return true; - }).set('ai',function(button){ - if(button.link=='discard'&&_status.event.getTrigger().targets.every(target=>{ - return get.effect(target,{name:'guohe_copy2'},_status.event.player)<=0; - })) return 0; - return 1; - }).set('selectButton',[1,2]); - 'step 1' - if(result.bool){ - player.logSkill('dcmoukui'); - var choices=result.links; - event.choices=choices; - if(choices.includes('draw')){ - game.log(player,'选择了','#y选项一'); + content: function () { + "step 0"; + player + .chooseButton([ + get.prompt("dcmoukui"), + [ + [ + ["draw", "摸一张牌"], + [ + "discard", + "弃置" + + (trigger.targets.length == 1 + ? get.translation(trigger.targets[0]) + : "一名目标角色") + + "的一张牌", + ], + ], + "textbutton", + ], + ]) + .set("filterButton", (button) => { + if ( + button.link == "discard" && + _status.event.getTrigger().targets.every((target) => { + return target.countDiscardableCards(_status.event.player, "he") == 0; + }) + ) + return false; + return true; + }) + .set("ai", function (button) { + if ( + button.link == "discard" && + _status.event.getTrigger().targets.every((target) => { + return ( + get.effect(target, { name: "guohe_copy2" }, _status.event.player) <= 0 + ); + }) + ) + return 0; + return 1; + }) + .set("selectButton", [1, 2]); + "step 1"; + if (result.bool) { + player.logSkill("dcmoukui"); + var choices = result.links; + event.choices = choices; + if (choices.includes("draw")) { + game.log(player, "选择了", "#y选项一"); player.draw(); } - if(choices.includes('discard')){ - game.log(player,'选择了','#y选项二'); - if(trigger.targets.length==1) event.directtarget=trigger.targets[0]; - else player.chooseTarget('谋溃:弃置一名目标角色的一张牌',true,(card,player,target)=>{ - return _status.event.getTrigger().targets.includes(target)&&target.countDiscardableCards(player,'he')>0; - }).set('ai',target=>{ - return get.effect(target,{name:'guohe_copy2'},_status.event.player); - }); - } - else event.finish(); - if(choices.length>=2){ - player.addTempSkill('dcmoukui_conseq'); - player.markAuto('dcmoukui_conseq',[trigger.card]); + if (choices.includes("discard")) { + game.log(player, "选择了", "#y选项二"); + if (trigger.targets.length == 1) event.directtarget = trigger.targets[0]; + else + player + .chooseTarget( + "谋溃:弃置一名目标角色的一张牌", + true, + (card, player, target) => { + return ( + _status.event.getTrigger().targets.includes(target) && + target.countDiscardableCards(player, "he") > 0 + ); + } + ) + .set("ai", (target) => { + return get.effect( + target, + { name: "guohe_copy2" }, + _status.event.player + ); + }); + } else event.finish(); + if (choices.length >= 2) { + player.addTempSkill("dcmoukui_conseq"); + player.markAuto("dcmoukui_conseq", [trigger.card]); } } - 'step 2' - player.discardPlayerCard(event.directtarget||result.targets[0],true,'he').boolline=true; + "step 2"; + player.discardPlayerCard( + event.directtarget || result.targets[0], + true, + "he" + ).boolline = true; }, - subSkill:{ - conseq:{ - trigger:{ - global:['shaMiss','useCardToExcluded','eventNeutralized','shaCancelled'], + subSkill: { + conseq: { + trigger: { + global: ["shaMiss", "useCardToExcluded", "eventNeutralized", "shaCancelled"], }, - forced:true, - popup:false, - charlotte:true, - onremove:true, - filter:function(event,player,name){ - if(!event.card) return false; - var cards=player.getStorage('dcmoukui_conseq'); - if(!cards.includes(event.card)) return false; + forced: true, + popup: false, + charlotte: true, + onremove: true, + filter: function (event, player, name) { + if (!event.card) return false; + var cards = player.getStorage("dcmoukui_conseq"); + if (!cards.includes(event.card)) return false; return true; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; game.delayx(); - 'step 1' - trigger.target.discardPlayerCard(player,true,'he').boolline=true; - } - } + "step 1"; + trigger.target.discardPlayerCard(player, true, "he").boolline = true; + }, + }, }, }, //孙桓 - dcniji:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return get.type(event.card)!='equip'; + dcniji: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return get.type(event.card) != "equip"; }, - frequent:true, - group:'dcniji_discard', - content:function(){ - var next=player.draw(); - var evt=trigger.getParent('dcniji_discard'); - if(!evt||evt.player!=player) next.gaintag=['dcniji']; - player.addTempSkill('dcniji_clear'); + frequent: true, + group: "dcniji_discard", + content: function () { + var next = player.draw(); + var evt = trigger.getParent("dcniji_discard"); + if (!evt || evt.player != player) next.gaintag = ["dcniji"]; + player.addTempSkill("dcniji_clear"); }, - subSkill:{ - clear:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('dcniji'); + subSkill: { + clear: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("dcniji"); }, }, - discard:{ - audio:'dcniji', - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasCard(card=>card.hasGaintag('dcniji')&&lib.filter.cardDiscardable(card,player,'dcniji'),'h'); + discard: { + audio: "dcniji", + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.hasCard( + (card) => + card.hasGaintag("dcniji") && + lib.filter.cardDiscardable(card, player, "dcniji"), + "h" + ); }, - forced:true, - locked:false, - content:function(){ - 'step 0' - var cards=player.getCards('h',card=>card.hasGaintag('dcniji')&&lib.filter.cardDiscardable(card,player,'dcniji')); - event.cards=cards; + forced: true, + locked: false, + content: function () { + "step 0"; + var cards = player.getCards( + "h", + (card) => + card.hasGaintag("dcniji") && + lib.filter.cardDiscardable(card, player, "dcniji") + ); + event.cards = cards; // if(cards.length>=player.hp){ - if(cards.some(card=>player.hasUseTarget(card))){ + if (cards.some((card) => player.hasUseTarget(card))) { player.chooseToUse({ - prompt:'是否使用一张“逆击”牌?', - filterCard:function(card,player){ - if(get.itemtype(card)=='card'&&!card.hasGaintag('dcniji')) return false; - return lib.filter.filterCard.apply(this,arguments); + prompt: "是否使用一张“逆击”牌?", + filterCard: function (card, player) { + if (get.itemtype(card) == "card" && !card.hasGaintag("dcniji")) + return false; + return lib.filter.filterCard.apply(this, arguments); }, - ai1:function(card){ + ai1: function (card) { return get.player().getUseValue(card); }, }); } // } - 'step 1' - if(result.bool) game.delayex(); - var cards=cards.filter(card=>get.owner(card)==player&&get.position(card)=='h'&&lib.filter.cardDiscardable(card,player,'dcniji')); - if(cards.length) player.discard(cards); - } - } - } + "step 1"; + if (result.bool) game.delayex(); + var cards = cards.filter( + (card) => + get.owner(card) == player && + get.position(card) == "h" && + lib.filter.cardDiscardable(card, player, "dcniji") + ); + if (cards.length) player.discard(cards); + }, + }, + }, }, //孙狼 - dctingxian:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - usable:1, - filter:function(event,player){ - return event.card.name=='sha'&&event.getParent().triggeredTargets3.length==event.targets.length; + dctingxian: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + usable: 1, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.getParent().triggeredTargets3.length == event.targets.length + ); }, - check:function(event,player){ - return event.targets.some(target=>get.effect(target,event.card,player,player)<=0); + check: function (event, player) { + return event.targets.some( + (target) => get.effect(target, event.card, player, player) <= 0 + ); }, - content:function(){ - 'step 0' - var num=player.countCards('e')+1; - event.num=num; + content: function () { + "step 0"; + var num = player.countCards("e") + 1; + event.num = num; player.draw(num); - 'step 1' - var num=Math.min(trigger.targets.length,num); - player.chooseTarget('铤险:令此杀对其中至多'+get.cnNumber(num)+'个目标无效',[1,num],true,(card,player,target)=>{ - return _status.event.getTrigger().targets.includes(target); - }).set('ai',target=>{ - return 1-get.effect(target,_status.event.getTrigger().card,_status.event.player,_status.event.player); - }); - 'step 2' - if(result.bool){ + "step 1"; + var num = Math.min(trigger.targets.length, num); + player + .chooseTarget( + "铤险:令此杀对其中至多" + get.cnNumber(num) + "个目标无效", + [1, num], + true, + (card, player, target) => { + return _status.event.getTrigger().targets.includes(target); + } + ) + .set("ai", (target) => { + return ( + 1 - + get.effect( + target, + _status.event.getTrigger().card, + _status.event.player, + _status.event.player + ) + ); + }); + "step 2"; + if (result.bool) { player.line(result.targets); trigger.getParent().excluded.addArray(result.targets); } }, - ai:{ - effect:{ - player:function(card,player,target){ - if(_status.event.name=='chooseToUse'&&get.name(card)=='sha'&&(!player.storage.counttrigger||!player.storage.counttrigger.dctingxian)&&!_status._dctingxian_aiChecking){ - _status._dctingxian_aiChecking=true; - var eff=get.effect(target,{name:'sha'},player,player); + ai: { + effect: { + player: function (card, player, target) { + if ( + _status.event.name == "chooseToUse" && + get.name(card) == "sha" && + (!player.storage.counttrigger || !player.storage.counttrigger.dctingxian) && + !_status._dctingxian_aiChecking + ) { + _status._dctingxian_aiChecking = true; + var eff = get.effect(target, { name: "sha" }, player, player); delete _status._dctingxian_aiChecking; - if(eff<0&&ui.selected.targets.filter(targetx=>{ - if(targetx==target) return false; - _status._dctingxian_aiChecking=true; - var eff=get.effect(targetx,{name:'sha'},player,player); - delete _status._dctingxian_aiChecking; - if(eff<0) return true; - }).length { + if (targetx == target) return false; + _status._dctingxian_aiChecking = true; + var eff = get.effect(targetx, { name: "sha" }, player, player); + delete _status._dctingxian_aiChecking; + if (eff < 0) return true; + }).length < + player.countCards("e") + 1 + ) + return [0, 0, 0, 0.5]; } }, - } - } - }, - dcbenshi:{ - audio:2, - forced:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - var card=event.card; - var range; - var select=get.copy(get.info(card).selectTarget); - if(select==undefined){ - if(get.info(card).filterTarget==undefined) return false; - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); - return range[1]==-1; + }, }, - content:function(){}, - mod:{ - attackRangeBase:function(player,num){ - if(num!=='unchanged') return num; - var range=1; - var equips=player.getCards('e',function(card){ - return get.subtype(card)!='equip1'&&(!ui.selected.cards||!ui.selected.cards.includes(card)); + }, + dcbenshi: { + audio: 2, + forced: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + var card = event.card; + var range; + var select = get.copy(get.info(card).selectTarget); + if (select == undefined) { + if (get.info(card).filterTarget == undefined) return false; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); + return range[1] == -1; + }, + content: function () {}, + mod: { + attackRangeBase: function (player, num) { + if (num !== "unchanged") return num; + var range = 1; + var equips = player.getCards("e", function (card) { + return ( + get.subtype(card) != "equip1" && + (!ui.selected.cards || !ui.selected.cards.includes(card)) + ); }); - for(var i=0;i0; + dccuichuan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: true, + filterCard: true, + derivation: "dczuojian", + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' - event.num=target.countCards('e'); - var subtypes=[]; - for(var i=1;i<7;i++){ - if(target.hasEmptySlot(i)) subtypes.push('equip'+i); + content: function () { + "step 0"; + event.num = target.countCards("e"); + var subtypes = []; + for (var i = 1; i < 7; i++) { + if (target.hasEmptySlot(i)) subtypes.push("equip" + i); } - if(subtypes.length){ + if (subtypes.length) { subtypes.randomSort(); - for(var subtype of subtypes){ - var card=get.cardPile2(card=>get.subtype(card)==subtype); - if(card&&target.canUse(card,target)){ - target.chooseUseTarget(card,true,'nopopup'); + for (var subtype of subtypes) { + var card = get.cardPile2((card) => get.subtype(card) == subtype); + if (card && target.canUse(card, target)) { + target.chooseUseTarget(card, true, "nopopup"); break; } } } - 'step 1' - var numx=target.countCards('e'); - if(numx>0) player.draw(numx); + "step 1"; + var numx = target.countCards("e"); + if (numx > 0) player.draw(numx); game.delayx(); - 'step 2' - event.num2=target.countCards('e'); - if(event.num2==4&&num!=4){ - player.trySkillAnimate('dccuichuan_animate','dccuichuan_animate',player.checkShow('dccuichuan')); + "step 2"; + event.num2 = target.countCards("e"); + if (event.num2 == 4 && num != 4) { + player.trySkillAnimate( + "dccuichuan_animate", + "dccuichuan_animate", + player.checkShow("dccuichuan") + ); //player.removeSkill('dccuichuan'); //game.log(player,'失去了技能','#g【榱椽】'); - player.changeSkills(['dczuojian'],['dccuichuan']); + player.changeSkills(["dczuojian"], ["dccuichuan"]); target.insertPhase(); game.delayx(); } }, - subSkill:{ - animate:{ - skillAnimation:true, - animationColor:'wood', - } + subSkill: { + animate: { + skillAnimation: true, + animationColor: "wood", + }, }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(target.countCards('e')==3) return 2; + ai: { + order: 7, + result: { + target: function (player, target) { + if (target.countCards("e") == 3) return 2; return 1; }, - player:function(player,target){ - if(target.countCards('e')==3) return 0.5; - return target.countCards('e')+1; - } - } - } + player: function (player, target) { + if (target.countCards("e") == 3) return 0.5; + return target.countCards("e") + 1; + }, + }, + }, }, - dczhengxu:{ - audio:2, - group:['dczhengxu_lose','dczhengxu_damage'], - subSkill:{ - lose:{ - audio:'dczhengxu', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dczhengxu: { + audio: 2, + group: ["dczhengxu_lose", "dczhengxu_damage"], + subSkill: { + lose: { + audio: "dczhengxu", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - prompt2:function(event,player){ - return '当你失去牌后,若你本回合受到过伤害,你可以摸等量的牌('+get.cnNumber(event.getl(player).cards2.length)+'张)'; + prompt2: function (event, player) { + return ( + "当你失去牌后,若你本回合受到过伤害,你可以摸等量的牌(" + + get.cnNumber(event.getl(player).cards2.length) + + "张)" + ); }, - check:()=>true, - filter:function(event,player){ - if(event.name=='gain'&&event.player==player) return false; - if(!player.getHistory('damage').length||player.hasHistory('useSkill',evt=>evt.skill=='dczhengxu_lose')) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + check: () => true, + filter: function (event, player) { + if (event.name == "gain" && event.player == player) return false; + if ( + !player.getHistory("damage").length || + player.hasHistory("useSkill", (evt) => evt.skill == "dczhengxu_lose") + ) + return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - content:function(){ + content: function () { player.draw(trigger.getl(player).cards2.length); }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if((get.tag(card,'lose')||get.tag(card,'discard'))&&target.getHistory('damage').length&&!target.hasHistory('useSkill',evt=>evt.skill=='dczhengxu_lose')) return [1,1]; - } - } - } - }, - damage:{ - audio:'dczhengxu', - trigger:{ - player:'damageBegin4', + ai: { + effect: { + target: (card, player, target) => { + if ( + (get.tag(card, "lose") || get.tag(card, "discard")) && + target.getHistory("damage").length && + !target.hasHistory("useSkill", (evt) => evt.skill == "dczhengxu_lose") + ) + return [1, 1]; + }, + }, }, - prompt2:'当你受到伤害时,若你本回合失去过牌,你可以防止之', - check:()=>true, - filter:function(event,player){ - if(!player.hasHistory('lose',evt=>evt.cards2&&evt.cards2.length)||player.hasHistory('useSkill',evt=>evt.skill=='dczhengxu_damage')) return false; + }, + damage: { + audio: "dczhengxu", + trigger: { + player: "damageBegin4", + }, + prompt2: "当你受到伤害时,若你本回合失去过牌,你可以防止之", + check: () => true, + filter: function (event, player) { + if ( + !player.hasHistory("lose", (evt) => evt.cards2 && evt.cards2.length) || + player.hasHistory("useSkill", (evt) => evt.skill == "dczhengxu_damage") + ) + return false; return true; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(player.hasSkillTag('jueqing',false,target)||!get.tag(card,'damage')) return; - if(target.hasHistory('useSkill',evt=>evt.skill=='dczhengxu_damage')||!target.hasHistory('lose',evt=>evt.cards2&&evt.cards2.length)) return; - if(get.attitude(player,target)>=0) return 'zeroplayertarget'; - let num=0,shas=player.getCardUsable('sha'),hs=player.getCards('hs',i=>{ - if(i===card||card.cards&&card.cards.includes(i)||!get.tag(i,'damage')||!player.canUse(i,target)) return false; - if(get.name(i)==='sha'){ - num++; - return false; - } - return true; - }); - if(card.name==='sha') shas--; - num=Math.min(num,shas); - num+=hs.length; - if(!num) return 'zeroplayertarget'; - num=1-2/3/num; - return [num,0,num,0]; - } - } - } + ai: { + effect: { + target: (card, player, target) => { + if ( + player.hasSkillTag("jueqing", false, target) || + !get.tag(card, "damage") + ) + return; + if ( + target.hasHistory( + "useSkill", + (evt) => evt.skill == "dczhengxu_damage" + ) || + !target.hasHistory("lose", (evt) => evt.cards2 && evt.cards2.length) + ) + return; + if (get.attitude(player, target) >= 0) return "zeroplayertarget"; + let num = 0, + shas = player.getCardUsable("sha"), + hs = player.getCards("hs", (i) => { + if ( + i === card || + (card.cards && card.cards.includes(i)) || + !get.tag(i, "damage") || + !player.canUse(i, target) + ) + return false; + if (get.name(i) === "sha") { + num++; + return false; + } + return true; + }); + if (card.name === "sha") shas--; + num = Math.min(num, shas); + num += hs.length; + if (!num) return "zeroplayertarget"; + num = 1 - 2 / 3 / num; + return [num, 0, num, 0]; + }, + }, + }, }, - } - }, - dczuojian:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getHistory('useCard',evt=>{ - var evtx=evt.getParent('phaseUse'); - if(evtx&&evtx==event) return true; - return false; - }).length>=player.hp; }, - direct:true, - content:function(){ - 'step 0' - var choices=[]; - var choiceList=['令装备区牌数多于你的角色各摸一张牌','令装备区牌数少于你的角色各弃置一张手牌']; - var num=player.countCards('e'); - var targets=[],targets2=[]; - var eff=0,eff2=0; - for(var target of game.filterPlayer()){ - if(target.countCards('e')>num) { + }, + dczuojian: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return ( + player.getHistory("useCard", (evt) => { + var evtx = evt.getParent("phaseUse"); + if (evtx && evtx == event) return true; + return false; + }).length >= player.hp + ); + }, + direct: true, + content: function () { + "step 0"; + var choices = []; + var choiceList = [ + "令装备区牌数多于你的角色各摸一张牌", + "令装备区牌数少于你的角色各弃置一张手牌", + ]; + var num = player.countCards("e"); + var targets = [], + targets2 = []; + var eff = 0, + eff2 = 0; + for (var target of game.filterPlayer()) { + if (target.countCards("e") > num) { targets.push(target); - eff+=get.attitude(player,target); + eff += get.attitude(player, target); } - if(target.countCards('e')'; - if(targets2.length){ - choices.push('选项二'); - choiceList[1]+='('+get.translation(targets2)+')'; - } - else choiceList[1]=''+choiceList[1]+''; - if(!choices.length) event.finish(); - else player.chooseControl(choices,'cancel2').set('prompt',get.prompt('dczuojian')).set('choiceList',choiceList).set('ai',()=>{ - var controls=_status.event.controls,choice=_status.event.choice; - if(!controls.includes('选项一')||controls.includes('选项二')&&choice==1) return '选项二'; - return '选项一'; - }).set('choice',eff<=0&&eff2<=0?'cancel2':(eff>-eff2?0:1)); - 'step 1' - if(result.control=='选项一'){ - player.logSkill('dczuojian',targets); - game.asyncDraw(targets,1); - } - else if(result.control=='选项二'){ - player.logSkill('dczuojian',event.targets2); - for(var target of event.targets2){ - player.discardPlayerCard('h',target,true); + event.targets = targets; + event.targets2 = targets2; + if (targets.length) { + choices.push("选项一"); + choiceList[0] += "(" + get.translation(targets) + ")"; + } else choiceList[0] = '' + choiceList[0] + ""; + if (targets2.length) { + choices.push("选项二"); + choiceList[1] += "(" + get.translation(targets2) + ")"; + } else choiceList[1] = '' + choiceList[1] + ""; + if (!choices.length) event.finish(); + else + player + .chooseControl(choices, "cancel2") + .set("prompt", get.prompt("dczuojian")) + .set("choiceList", choiceList) + .set("ai", () => { + var controls = _status.event.controls, + choice = _status.event.choice; + if ( + !controls.includes("选项一") || + (controls.includes("选项二") && choice == 1) + ) + return "选项二"; + return "选项一"; + }) + .set("choice", eff <= 0 && eff2 <= 0 ? "cancel2" : eff > -eff2 ? 0 : 1); + "step 1"; + if (result.control == "选项一") { + player.logSkill("dczuojian", targets); + game.asyncDraw(targets, 1); + } else if (result.control == "选项二") { + player.logSkill("dczuojian", event.targets2); + for (var target of event.targets2) { + player.discardPlayerCard("h", target, true); } } - } + }, }, //胡金定 - dcdeshi:{ - audio:2, - trigger:{player:'damageBegin4'}, - forced:true, - filter:function(event,player){ - return player.isDamaged()&&event.card&&event.card.name=='sha'; + dcdeshi: { + audio: 2, + trigger: { player: "damageBegin4" }, + forced: true, + filter: function (event, player) { + return player.isDamaged() && event.card && event.card.name == "sha"; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.cancel(); - for(var func of ['discardPile','cardPile2']){ - var card=get[func](card=>card.name=='sha'); - if(card){ - player.gain(card,'gain2'); + for (var func of ["discardPile", "cardPile2"]) { + var card = get[func]((card) => card.name == "sha"); + if (card) { + player.gain(card, "gain2"); break; } } - 'step 1' + "step 1"; player.loseMaxHp(); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha') return true; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha") return true; return false; }, }, }, - dcwuyuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h','sha')>0; + dcwuyuan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - filterCard:{name:'sha'}, - filterTarget:lib.filter.notMe, - check:function(card){ - var player=_status.event.player; - if(get.color(card)=='red'&&game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged()&&get.attitude(player,current)>2; - })) return 2; - if(get.natureList(card).length) return 1.5; + filterCard: { name: "sha" }, + filterTarget: lib.filter.notMe, + check: function (card) { + var player = _status.event.player; + if ( + get.color(card) == "red" && + game.hasPlayer(function (current) { + return ( + current != player && current.isDamaged() && get.attitude(player, current) > 2 + ); + }) + ) + return 2; + if (get.natureList(card).length) return 1.5; return 1; }, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.give(cards,target,'give'); + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.give(cards, target, "give"); player.recover(); - 'step 1' - var num=1; - if(get.natureList(cards[0]).length) num++; - player.draw('nodelay'); + "step 1"; + var num = 1; + if (get.natureList(cards[0]).length) num++; + player.draw("nodelay"); target.draw(num); - if(get.color(cards[0])=='red') target.recover(); + if (get.color(cards[0]) == "red") target.recover(); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.isDamaged()) return 1; + ai: { + order: 1, + result: { + player: function (player, target) { + if (player.isDamaged()) return 1; return 0; }, - target:function(player,target){ - if(ui.selected.cards.length){ - var num=1; - if(get.natureList(ui.selected.cards[0]).length) num++; - if(target.hasSkillTag('nogain')) num=0; - if(get.color(ui.selected.cards[0])=='red') return num+2 - else return num+1; + target: function (player, target) { + if (ui.selected.cards.length) { + var num = 1; + if (get.natureList(ui.selected.cards[0]).length) num++; + if (target.hasSkillTag("nogain")) num = 0; + if (get.color(ui.selected.cards[0]) == "red") return num + 2; + else return num + 1; } return 1; }, @@ -2301,1879 +3127,2339 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //李异谢旌 - dcdouzhen:{ - audio:2, - trigger:{ - player:['useCard','respond'], + dcdouzhen: { + audio: 2, + trigger: { + player: ["useCard", "respond"], }, - forced:true, - zhuanhuanji:'number', - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - var str='
            • 已转换过'+get.cnNumber(storage||0)+'次。
            • 你的回合内,'; - str+=player.countMark('dcdouzhen')%2?'你的红色基本牌均视为普【杀】且无次数限制。':'你的黑色基本牌均视为【决斗】且使用时获得目标的一张牌。'; + forced: true, + zhuanhuanji: "number", + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + var str = "
            • 已转换过" + get.cnNumber(storage || 0) + "次。
            • 你的回合内,"; + str += + player.countMark("dcdouzhen") % 2 + ? "你的红色基本牌均视为普【杀】且无次数限制。" + : "你的黑色基本牌均视为【决斗】且使用时获得目标的一张牌。"; return str; }, }, - filter:function(event,player){ - if(player !=_status.currentPhase||!event.card.isCard||!event.cards||event.cards.length!=1||get.type(event.cards[0])!='basic') return false; - if(player.countMark('dcdouzhen')%2) return get.color(event.cards[0])=='red'&&event.card.name=='sha'; - return event.name!='respond'&&get.color(event.cards[0])=='black'&&event.card.name=='juedou'; + filter: function (event, player) { + if ( + player != _status.currentPhase || + !event.card.isCard || + !event.cards || + event.cards.length != 1 || + get.type(event.cards[0]) != "basic" + ) + return false; + if (player.countMark("dcdouzhen") % 2) + return get.color(event.cards[0]) == "red" && event.card.name == "sha"; + return ( + event.name != "respond" && + get.color(event.cards[0]) == "black" && + event.card.name == "juedou" + ); }, - content:function(){ - if(player.countMark('dcdouzhen')%2){ + content: function () { + if (player.countMark("dcdouzhen") % 2) { // if(trigger.addCount!==false){ // trigger.addCount=false; // if(player.stat[player.stat.length-1].card.sha>0){ // player.stat[player.stat.length-1].card.sha--; // } // } - }else{ - if(trigger.targets.length&&trigger.targets.filter(i=>i.countGainableCards(player,'he')>0).length) player.gainMultiple(trigger.targets.sortBySeat(),'he'); + } else { + if ( + trigger.targets.length && + trigger.targets.filter((i) => i.countGainableCards(player, "he") > 0).length + ) + player.gainMultiple(trigger.targets.sortBySeat(), "he"); } - player.changeZhuanhuanji('dcdouzhen'); + player.changeZhuanhuanji("dcdouzhen"); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name!='juedou') return; - if(player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)){ - return [1,1]; + ai: { + effect: { + player: function (card, player, target) { + if (card.name != "juedou") return; + if ( + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) { + return [1, 1]; } - var hs1=target.getCards('h','sha'); - var hs2=player.getCards('h',card=>(get.color(card)=='red'&&get.type(card)=='basic')||get.name(card)=='sha'); - var hsx=target.getCards('h'); - if(hs1.length>hs2.length+1||hsx.length>2&&hs2.length==0&&hsx[0].number<6||hsx.length>3&&hs2.length==0||hs1.length>hs2.length&&(!hs2.length||hs1[0].number>hs2[0].number)){ - return [1,-2]; + var hs1 = target.getCards("h", "sha"); + var hs2 = player.getCards( + "h", + (card) => + (get.color(card) == "red" && get.type(card) == "basic") || + get.name(card) == "sha" + ); + var hsx = target.getCards("h"); + if ( + hs1.length > hs2.length + 1 || + (hsx.length > 2 && hs2.length == 0 && hsx[0].number < 6) || + (hsx.length > 3 && hs2.length == 0) || + (hs1.length > hs2.length && (!hs2.length || hs1[0].number > hs2[0].number)) + ) { + return [1, -2]; } - return [1,-0.5]; - } - } + return [1, -0.5]; + }, + }, }, - mod:{ - cardname:function(card,player){ - if(get.type(card,null,false)!='basic'||player!=_status.currentPhase) return; - if(player.countMark('dcdouzhen')%2){ - if(get.color(card)=='red') return 'sha'; - }else{ - if(get.color(card)=='black') return 'juedou'; + mod: { + cardname: function (card, player) { + if (get.type(card, null, false) != "basic" || player != _status.currentPhase) return; + if (player.countMark("dcdouzhen") % 2) { + if (get.color(card) == "red") return "sha"; + } else { + if (get.color(card) == "black") return "juedou"; } }, - cardnature:function(card,player){ - if(get.type(card,null,false)!='basic'||player!=_status.currentPhase) return; - if(player.countMark('dcdouzhen')%2){ - if(get.color(card)=='red') return false; + cardnature: function (card, player) { + if (get.type(card, null, false) != "basic" || player != _status.currentPhase) return; + if (player.countMark("dcdouzhen") % 2) { + if (get.color(card) == "red") return false; } }, - cardUsable:function(card,player){ - if(_status.currentPhase==player&&card.name=='sha'&&player.countMark('dcdouzhen')%2&&get.color(card)=='red'&&card.isCard) return Infinity; - } - } + cardUsable: function (card, player) { + if ( + _status.currentPhase == player && + card.name == "sha" && + player.countMark("dcdouzhen") % 2 && + get.color(card) == "red" && + card.isCard + ) + return Infinity; + }, + }, }, //穆顺 - dcjinjian:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + dcjinjian: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - locked:false, - filter:function(event,player,name){ - return name=='damageSource'||(event.source&&event.source!=player&&event.source.isIn()); + forced: true, + locked: false, + filter: function (event, player, name) { + return ( + name == "damageSource" || + (event.source && event.source != player && event.source.isIn()) + ); }, - content:function(){ - 'step 0' - player.addMark('dcjinjian',1); + content: function () { + "step 0"; + player.addMark("dcjinjian", 1); game.delayx(); - 'step 1' - var source=trigger.source; - if(source&&source!=player&&source.isIn()&&player.canCompare(source)){ - player.chooseBool('是否和'+get.translation(source)+'拼点?','若你赢,则你恢复1点体力').set('goon',(player.countCards('h')==1||player.hasCard(function(card){ - return get.value(card)<=5||get.number(card)>10; - }))&&(get.attitude(player,source)<=0||source.countCards('h')>=4)).set('ai',function(){ - return _status.event.goon; - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.line(trigger.source,'green'); + "step 1"; + var source = trigger.source; + if (source && source != player && source.isIn() && player.canCompare(source)) { + player + .chooseBool( + "是否和" + get.translation(source) + "拼点?", + "若你赢,则你恢复1点体力" + ) + .set( + "goon", + (player.countCards("h") == 1 || + player.hasCard(function (card) { + return get.value(card) <= 5 || get.number(card) > 10; + })) && + (get.attitude(player, source) <= 0 || source.countCards("h") >= 4) + ) + .set("ai", function () { + return _status.event.goon; + }); + } else event.finish(); + "step 2"; + if (result.bool) { + player.line(trigger.source, "green"); player.chooseToCompare(trigger.source); - } - else event.finish(); - 'step 3' - if(result.bool) player.recover(); + } else event.finish(); + "step 3"; + if (result.bool) player.recover(); }, - intro:{ - name2:'劲', - content:'mark', + intro: { + name2: "劲", + content: "mark", }, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('dcjinjian'); + mod: { + attackRange: function (player, num) { + return num + player.countMark("dcjinjian"); }, }, }, - dcshizhao:{ - audio:2, - usable:1, - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcshizhao: { + audio: 2, + usable: 1, + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - return player!=_status.currentPhase&&player.countCards('h')==0&&event.getl(player).hs.length>0; + forced: true, + filter: function (event, player) { + return ( + player != _status.currentPhase && + player.countCards("h") == 0 && + event.getl(player).hs.length > 0 + ); }, - content:function(){ - if(player.hasMark('dcjinjian')){ - player.removeMark('dcjinjian',1); + content: function () { + if (player.hasMark("dcjinjian")) { + player.removeMark("dcjinjian", 1); player.draw(2); - } - else{ - player.addTempSkill('dcshizhao_effect'); - player.addMark('dcshizhao_effect',1,false); + } else { + player.addTempSkill("dcshizhao_effect"); + player.addMark("dcshizhao_effect", 1, false); game.delayx(); } }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - trigger:{player:'damageBegin1'}, - forced:true, - content:function(){ - trigger.num+=player.countMark(event.name); + subSkill: { + effect: { + charlotte: true, + onremove: true, + trigger: { player: "damageBegin1" }, + forced: true, + content: function () { + trigger.num += player.countMark(event.name); player.removeSkill(event.name); }, }, }, + ai: { + combo: "dcjinjian", + }, }, //赵俨 - dcfuning:{ - audio:2, - trigger:{player:'useCard'}, - prompt2:function(event,player){ - return '摸两张牌,然后弃置'+get.cnNumber(1+player.getHistory('useSkill',function(evt){ - return evt.skill=='dcfuning'; - }).length)+'张牌'; + dcfuning: { + audio: 2, + trigger: { player: "useCard" }, + prompt2: function (event, player) { + return ( + "摸两张牌,然后弃置" + + get.cnNumber( + 1 + + player.getHistory("useSkill", function (evt) { + return evt.skill == "dcfuning"; + }).length + ) + + "张牌" + ); }, - check:function(event,player){ - return player.getHistory('useSkill',function(evt){ - return evt.skill=='dcfuning'; - }).length<2; + check: function (event, player) { + return ( + player.getHistory("useSkill", function (evt) { + return evt.skill == "dcfuning"; + }).length < 2 + ); }, - content:function(){ + content: function () { player.draw(2); - player.chooseToDiscard('he',true,+player.getHistory('useSkill',function(evt){ - return evt.skill=='dcfuning'; - }).length); + player.chooseToDiscard( + "he", + true, + +player.getHistory("useSkill", function (evt) { + return evt.skill == "dcfuning"; + }).length + ); }, }, - dcbingji:{ - audio:2, - enable:'phaseUse', - usable:4, - filter:function(event,player){ - var hs=player.getCards('h'),suits=player.getStorage('dcbingji_mark'); - if(!hs.length) return false; - var suit=get.suit(hs[0],player); - if(suit=='none'||suits.includes(suit)) return false; - for(var i=1;ifalse, - selectCard:-1, - filterTarget:function(card,player,target){ - if(!card) card=get.card(); - if(player==target) return false; - return lib.filter.targetEnabled2(card,player,target)&&lib.filter.targetInRange(card,player,target); + filterCard: () => false, + selectCard: -1, + filterTarget: function (card, player, target) { + if (!card) card = get.card(); + if (player == target) return false; + return ( + lib.filter.targetEnabled2(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); }, - selectTarget:1, - ignoreMod:true, - filterOk:()=>true, - precontent:function(){ - player.logSkill('dcbingji'); + selectTarget: 1, + ignoreMod: true, + filterOk: () => true, + precontent: function () { + player.logSkill("dcbingji"); delete event.result.skill; - var hs=player.getCards('h'); - player.showCards(hs,get.translation(player)+'发动了【秉纪】'); - player.markAuto('dcbingji_mark',[get.suit(hs[0],player)]); - player.addTempSkill('dcbingji_mark'); + var hs = player.getCards("h"); + player.showCards(hs, get.translation(player) + "发动了【秉纪】"); + player.markAuto("dcbingji_mark", [get.suit(hs[0], player)]); + player.addTempSkill("dcbingji_mark"); }, - } + }; }, - prompt:function(links,player){ - return '请选择【'+get.translation(links[0][2])+'】的目标'; + prompt: function (links, player) { + return "请选择【" + get.translation(links[0][2]) + "】的目标"; }, }, - subSkill:{ - mark:{ - charlotte:true, - onremove:true, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.addCount!==false&&event.card.name=='sha'&&event.card.storage&&event.card.storage.dcbingji; + subSkill: { + mark: { + charlotte: true, + onremove: true, + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return ( + event.addCount !== false && + event.card.name == "sha" && + event.card.storage && + event.card.storage.dcbingji + ); }, - content:function(){ - trigger.addCount=false; - player.getStat('card').sha--; + content: function () { + trigger.addCount = false; + player.getStat("card").sha--; }, }, }, }, //王威 - dcruizhan:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player!=event.player&&event.player.countCards('h')>=Math.max(1,event.player.hp)&&player.canCompare(event.player); + dcruizhan: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return ( + player != event.player && + event.player.countCards("h") >= Math.max(1, event.player.hp) && + player.canCompare(event.player) + ); }, - logTarget:'player', - check:function(event,player){ - var goon=player.hasCard(function(card){ - return card.name=='sha'||get.value(card)<=5; + logTarget: "player", + check: function (event, player) { + var goon = player.hasCard(function (card) { + return card.name == "sha" || get.value(card) <= 5; }); - var target=event.player; - if(goon&&get.attitude(player,target)<0){ - return get.effect(target,{name:'sha'},player,player)>0; + var target = event.player; + if (goon && get.attitude(player, target) < 0) { + return get.effect(target, { name: "sha" }, player, player) > 0; } return 0; }, - content:function(){ - 'step 0' - event.target=trigger.player; - player.chooseToCompare(event.target).set('ai',function(card){ - if(typeof card=='string'&&lib.skill[card]){ - var ais=lib.skill[card].check||function(){return 0}; + content: function () { + "step 0"; + event.target = trigger.player; + player.chooseToCompare(event.target).set("ai", function (card) { + if (typeof card == "string" && lib.skill[card]) { + var ais = + lib.skill[card].check || + function () { + return 0; + }; return ais(); } - var player=get.owner(card); - var getn=function(card){ - if(player.hasSkill('tianbian')&&get.suit(card)=='heart') return 13; + var player = get.owner(card); + var getn = function (card) { + if (player.hasSkill("tianbian") && get.suit(card) == "heart") return 13; return get.number(card); - } - var event=_status.event.getParent(); - var to=(player==event.player?event.target:event.player); - var addi=(get.value(card)>=8&&get.type(card)!='equip')?-6:0; - if(card.name=='du') addi-=5; - if(player==event.player){ - if(get.name(card,player)=='sha'){ - return 10+getn(card); + }; + var event = _status.event.getParent(); + var to = player == event.player ? event.target : event.player; + var addi = get.value(card) >= 8 && get.type(card) != "equip" ? -6 : 0; + if (card.name == "du") addi -= 5; + if (player == event.player) { + if (get.name(card, player) == "sha") { + return 10 + getn(card); } - return getn(card)-get.value(card)/2+addi; - } - else{ - if(get.name(card,player)=='sha'){ - return -10-getn(card)-get.value(card)/2+addi; + return getn(card) - get.value(card) / 2 + addi; + } else { + if (get.name(card, player) == "sha") { + return -10 - getn(card) - get.value(card) / 2 + addi; } - return getn(card)-get.value(card)/2+addi; + return getn(card) - get.value(card) / 2 + addi; } }); - 'step 1' - var bool1=result.bool; - var bool2=(get.name(result.player,player)=='sha'||get.name(result.target,target)=='sha'); - if(bool1||bool2){ - if(player.canUse('sha',target,false)){ - player.useCard({name:'sha',isCard:true},target,false); - if(!bool1||!bool2) event.finish(); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(target.hasCard(function(card){ - return lib.filter.canBeGained(card,target,player) - },'he')&&player.hasHistory('sourceDamage',function(evt){ - var evtx=evt.getParent('useCard'); - return evtx&&evtx.card==evt.card&&evtx.getParent()==event; - })) player.gainPlayerCard(target,true,'he'); + "step 1"; + var bool1 = result.bool; + var bool2 = + get.name(result.player, player) == "sha" || get.name(result.target, target) == "sha"; + if (bool1 || bool2) { + if (player.canUse("sha", target, false)) { + player.useCard({ name: "sha", isCard: true }, target, false); + if (!bool1 || !bool2) event.finish(); + } else event.finish(); + } else event.finish(); + "step 2"; + if ( + target.hasCard(function (card) { + return lib.filter.canBeGained(card, target, player); + }, "he") && + player.hasHistory("sourceDamage", function (evt) { + var evtx = evt.getParent("useCard"); + return evtx && evtx.card == evt.card && evtx.getParent() == event; + }) + ) + player.gainPlayerCard(target, true, "he"); }, }, - dcshilie:{ - audio:2, - enable:'phaseUse', - usable:1, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('示烈:请选择一项',[[ - ['recover','回复1点体力,将两张牌置于武将牌上作为“示烈”'], - ['losehp','失去1点体力,获得两张“示烈”牌'], - ],'textbutton'],'hidden'); + dcshilie: { + audio: 2, + enable: "phaseUse", + usable: 1, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "示烈:请选择一项", + [ + [ + ["recover", "回复1点体力,将两张牌置于武将牌上作为“示烈”"], + ["losehp", "失去1点体力,获得两张“示烈”牌"], + ], + "textbutton", + ], + "hidden" + ); }, - check:function(button){ - return button.link=='recover'?1:0; + check: function (button) { + return button.link == "recover" ? 1 : 0; }, - backup:function(links,player){ - return get.copy(lib.skill['dcshilie_'+links[0]]); + backup: function (links, player) { + return get.copy(lib.skill["dcshilie_" + links[0]]); }, - prompt:()=>'点击“确定”以执行选项', + prompt: () => "点击“确定”以执行选项", }, - intro:{ - markcount:'expansion', - content:'expansion', + intro: { + markcount: "expansion", + content: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'dcshilie_die', - ai:{ - order:0.5, - result:{ - player:function(player){ - if(player.isDamaged()&&!player.countCards('h','tao')) return 1; + group: "dcshilie_die", + ai: { + order: 0.5, + result: { + player: function (player) { + if (player.isDamaged() && !player.countCards("h", "tao")) return 1; return 0; }, }, }, - subSkill:{ - backup:{}, - recover:{ - audio:'dcshilie', - selectCard:-1, - selectTarget:-1, - filterCard:()=>false, - filterTarget:()=>false, - multitarget:true, - content:function(){ - 'step 0' + subSkill: { + backup: {}, + recover: { + audio: "dcshilie", + selectCard: -1, + selectTarget: -1, + filterCard: () => false, + filterTarget: () => false, + multitarget: true, + content: function () { + "step 0"; player.recover(); - 'step 1' - var hs=player.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length<=2) event._result={bool:true,cards:hs}; - else player.chooseCard('he',2,true,'选择两张牌作为“示烈”牌'); - 'step 2' - if(result.bool){ - player.addToExpansion(result.cards,player,'give').gaintag.add('dcshilie'); - } - else event.finish(); - 'step 3' - var cards=player.getExpansions('dcshilie'); - if(cards.length>game.countPlayer()){ + "step 1"; + var hs = player.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length <= 2) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", 2, true, "选择两张牌作为“示烈”牌"); + "step 2"; + if (result.bool) { + player.addToExpansion(result.cards, player, "give").gaintag.add("dcshilie"); + } else event.finish(); + "step 3"; + var cards = player.getExpansions("dcshilie"); + if (cards.length > game.countPlayer()) { player.loseToDiscardpile(cards.slice(game.countPlayer())); } }, }, - losehp:{ - audio:'dcshilie', - selectCard:-1, - selectTarget:-1, - filterCard:()=>false, - filterTarget:()=>false, - multitarget:true, - content:function(){ - 'step 0' + losehp: { + audio: "dcshilie", + selectCard: -1, + selectTarget: -1, + filterCard: () => false, + filterTarget: () => false, + multitarget: true, + content: function () { + "step 0"; player.loseHp(); - 'step 1' - var hs=player.getExpansions('dcshilie'); - if(!hs.length) event.finish(); - else if(hs.length<=2) event._result={bool:true,links:hs}; - else player.chooseButton(['选择获得两张“示烈”牌',hs],2,true); - 'step 2' - if(result.bool){ - player.gain(result.links,'gain2'); + "step 1"; + var hs = player.getExpansions("dcshilie"); + if (!hs.length) event.finish(); + else if (hs.length <= 2) event._result = { bool: true, links: hs }; + else player.chooseButton(["选择获得两张“示烈”牌", hs], 2, true); + "step 2"; + if (result.bool) { + player.gain(result.links, "gain2"); } }, }, - die:{ - audio:'dcshilie', - forceDie:true, - trigger:{player:'die'}, - filter:function(event,player){ - return player.getExpansions('dcshilie').length>0; + die: { + audio: "dcshilie", + forceDie: true, + trigger: { player: "die" }, + filter: function (event, player) { + return player.getExpansions("dcshilie").length > 0; }, - direct:true, - skillAnimation:true, - animationColor:'metal', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('dcshilie'),'令一名角色获得你的“示烈”牌',function(card,player,target){ - return target!=player&&target!=_status.event.getTrigger().source; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcshilie_die',target); - player.give(player.getExpansions('dcshilie'),target,'give'); + direct: true, + skillAnimation: true, + animationColor: "metal", + content: function () { + "step 0"; + player.chooseTarget( + get.prompt("dcshilie"), + "令一名角色获得你的“示烈”牌", + function (card, player, target) { + return target != player && target != _status.event.getTrigger().source; + } + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcshilie_die", target); + player.give(player.getExpansions("dcshilie"), target, "give"); } }, }, }, }, //胡班 - dcchongyi:{ - audio:2, - init:()=>{ - game.addGlobalSkill('dcchongyi_ai'); + dcchongyi: { + audio: 2, + init: () => { + game.addGlobalSkill("dcchongyi_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('dcchongyi'),true)) game.removeGlobalSkill('dcchongyi_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("dcchongyi"), true)) + game.removeGlobalSkill("dcchongyi_ai"); }, - trigger:{global:'useCard'}, - logTarget:'player', - filter:function(event,player){ - if(event.card.name!='sha'||!event.player.isIn()) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - var goon=false; - var history=event.player.getHistory('useCard',function(evtx){ - if(goon||evtx.getParent('phaseUse')!=evt) return false; - goon=true; + trigger: { global: "useCard" }, + logTarget: "player", + filter: function (event, player) { + if (event.card.name != "sha" || !event.player.isIn()) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + var goon = false; + var history = event.player.getHistory("useCard", function (evtx) { + if (goon || evtx.getParent("phaseUse") != evt) return false; + goon = true; return true; }); - return history[0]==event; + return history[0] == event; }, - prompt2:(event)=>'令其摸两张牌,且使用【杀】的次数上限+1', - check:function(event,player){ - return get.attitude(player,event.player)>0; + prompt2: (event) => "令其摸两张牌,且使用【杀】的次数上限+1", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - var target=trigger.player; + content: function () { + var target = trigger.player; target.draw(2); - target.addMark('dcchongyi_sha',1,false); - target.addTempSkill('dcchongyi_sha'); + target.addMark("dcchongyi_sha", 1, false); + target.addTempSkill("dcchongyi_sha"); }, - group:'dcchongyi_end', - subSkill:{ - ai:{ - mod:{ - aiOrder:function(player,card,num){ - if(card.name!='sha') return; - var evt=_status.event.getParent('phaseUse'); - if(!evt||evt.player!=player) return; - if(player.hasHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; - })) return; - if(game.hasPlayer(function(current){ - return current.hasSkill('dcchongyi')&&get.attitude(player,current)>=0; - })) return num+10; + group: "dcchongyi_end", + subSkill: { + ai: { + mod: { + aiOrder: function (player, card, num) { + if (card.name != "sha") return; + var evt = _status.event.getParent("phaseUse"); + if (!evt || evt.player != player) return; + if ( + player.hasHistory("useCard", function (evtx) { + return evtx.getParent("phaseUse") == evt; + }) + ) + return; + if ( + game.hasPlayer(function (current) { + return ( + current.hasSkill("dcchongyi") && + get.attitude(player, current) >= 0 + ); + }) + ) + return num + 10; }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('dcchongyi'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("dcchongyi"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("dcchongyi_ai"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('dcchongyi_ai'); - } }, - end:{ - audio:'dcchongyi', - trigger:{global:'phaseUseEnd'}, - logTarget:'player', - filter:function(event,player){ - if(!event.player.isIn()) return false; - var history=event.player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; + end: { + audio: "dcchongyi", + trigger: { global: "phaseUseEnd" }, + logTarget: "player", + filter: function (event, player) { + if (!event.player.isIn()) return false; + var history = event.player.getHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == event; }); - return history.length&&history[history.length-1].card.name=='sha'; + return history.length && history[history.length - 1].card.name == "sha"; }, - prompt2:(event)=>'令'+get.translation(event.player)+'本回合的手牌上限+1', - check:function(event,player){ - return get.attitude(player,event.player)>0; + prompt2(event, player) { + const target = event.player; + const history = target.getHistory("useCard", (evt) => { + return evt.getParent("phaseUse") === event; + }); + const evt = history.lastItem, + cards = evt.cards.filterInD("d"); + let str = "令" + get.translation(target) + "本回合的手牌上限+1"; + if (cards.length) str += `,然后你获得${get.translation(cards)}`; + str += "。"; + return str; }, - content:function(){ - var target=trigger.player; - target.addMark('dcchongyi_keep',1,false); - target.addTempSkill('dcchongyi_keep'); - game.delayx(); + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + async content(event, trigger, player) { + const target = trigger.player; + target.addMark("dcchongyi_keep", 1, false); + target.addTempSkill("dcchongyi_keep"); + const history = target.getHistory("useCard", (evt) => { + return evt.getParent("phaseUse") === trigger; + }); + const evt = history.lastItem, + cards = evt.cards.filterInD("d"); + if (cards.length) await player.gain(cards, "gain2"); + else await game.asyncDelayx(); }, }, - sha:{ - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('dcchongyi_sha'); + sha: { + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("dcchongyi_sha"); }, }, - onremove:true, - intro:{content:'使用【杀】的次数上限+#'}, + onremove: true, + intro: { content: "使用【杀】的次数上限+#" }, }, - keep:{ - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('dcchongyi_keep'); + keep: { + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("dcchongyi_keep"); }, }, - onremove:true, - intro:{content:'手牌上限+#'}, + onremove: true, + intro: { content: "手牌上限+#" }, }, }, }, //牛辅 - dcxiaoxi:{ - auto:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - return player.maxHp>1; + dcxiaoxi: { + auto: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + filter: function (event, player) { + return player.maxHp > 1; }, - content:function(){ - 'step 0' - if(player.maxHp<=2) event._result={index:0}; - else player.chooseControl('1点','2点').set('prompt','宵袭:减少1或2点体力上限').set('ai',function(){ - var player=_status.event.player; - if(!game.hasPlayer(function(current){ - if(!player.inRange(current)||get.attitude(player,current)>=0) return false; - if(get.effect(current,{name:'shunshou_copy2'},player,player)>0&¤t.countCards('h')+current.countCards('e',function(card){ - return get.value(card,current)>0; - })>1) return true; - if(get.effect(current,{name:'sha'},player,player)>0&¤t.countCards('hs','shan')+current.hp>1) return true; - })) return 0; - return 1; - }); - 'step 1' - player.loseMaxHp(1+result.index); - event.num=1+result.index; - 'step 2' - if(!game.hasPlayer((current)=>player.inRange(current))) event.finish(); - else player.chooseTarget('请选择【宵袭】的目标','然后你选择一项:⒈获得该角色的'+get.cnNumber(num)+'张牌。⒉视为对其使用'+get.cnNumber(num)+'张【杀】。',function(card,player,target){ - return player.inRange(target); - },true).set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>=0) return 0; - var eff1=get.effect(target,{name:'shunshou_copy2'},player,player); - if(eff1>0&&target.countCards('h')+target.countCards('e',function(card){ - return get.value(card,target)>0; - })>1) eff1*=1.6; - var eff2=player.canUse('sha',target)?get.effect(target,{name:'sha'},player,player):0; - if(eff2>0&&target.countCards('hs','shan')+target.hp>1) eff2*=2; - return Math.max(eff1,eff2); - }); - 'step 3' - var target=result.targets[0]; - player.line(target,'green'); - event.target=target; - var bool1=target.countGainableCards(player,'he')>0; - var bool2=player.canUse('sha',target); - if(!bool1&&!bool2) event.finish(); - else if(bool1&&bool2){ - var str=get.translation(target),numx=get.cnNumber(num); - player.chooseControl().set('choiceList',[ - '获得'+str+'的'+numx+'张牌', - '视为对'+str+'使用'+numx+'张【杀】', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - var eff1=get.effect(target,{name:'shunshou_copy2'},player,player); - if(eff1>0&&target.countCards('h')+target.countCards('e',function(card){ - return get.value(card,target)>0; - })>1) eff1*=1.6; - var eff2=player.canUse('sha',target)?get.effect(target,{name:'sha'},player,player):0; - if(eff2>0&&target.countCards('hs','shan')+target.hp>1) eff2*=2; - return eff1>eff2?0:1; - }); - } - else event._result={index:bool1?0:1}; - 'step 4' - if(result.index==0){ - player.gainPlayerCard(target,true,num,'he'); + content: function () { + "step 0"; + if (player.maxHp <= 2) event._result = { index: 0 }; + else + player + .chooseControl("1点", "2点") + .set("prompt", "宵袭:减少1或2点体力上限") + .set("ai", function () { + var player = _status.event.player; + if ( + !game.hasPlayer(function (current) { + if (!player.inRange(current) || get.attitude(player, current) >= 0) + return false; + if ( + get.effect(current, { name: "shunshou_copy2" }, player, player) > + 0 && + current.countCards("h") + + current.countCards("e", function (card) { + return get.value(card, current) > 0; + }) > + 1 + ) + return true; + if ( + get.effect(current, { name: "sha" }, player, player) > 0 && + current.countCards("hs", "shan") + current.hp > 1 + ) + return true; + }) + ) + return 0; + return 1; + }); + "step 1"; + player.loseMaxHp(1 + result.index); + event.num = 1 + result.index; + "step 2"; + if (!game.hasPlayer((current) => player.inRange(current))) event.finish(); + else + player + .chooseTarget( + "请选择【宵袭】的目标", + "然后你选择一项:⒈获得该角色的" + + get.cnNumber(num) + + "张牌。⒉视为对其使用" + + get.cnNumber(num) + + "张【杀】。", + function (card, player, target) { + return player.inRange(target); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) >= 0) return 0; + var eff1 = get.effect(target, { name: "shunshou_copy2" }, player, player); + if ( + eff1 > 0 && + target.countCards("h") + + target.countCards("e", function (card) { + return get.value(card, target) > 0; + }) > + 1 + ) + eff1 *= 1.6; + var eff2 = player.canUse("sha", target) + ? get.effect(target, { name: "sha" }, player, player) + : 0; + if (eff2 > 0 && target.countCards("hs", "shan") + target.hp > 1) eff2 *= 2; + return Math.max(eff1, eff2); + }); + "step 3"; + var target = result.targets[0]; + player.line(target, "green"); + event.target = target; + var bool1 = target.countGainableCards(player, "he") > 0; + var bool2 = player.canUse("sha", target); + if (!bool1 && !bool2) event.finish(); + else if (bool1 && bool2) { + var str = get.translation(target), + numx = get.cnNumber(num); + player + .chooseControl() + .set("choiceList", [ + "获得" + str + "的" + numx + "张牌", + "视为对" + str + "使用" + numx + "张【杀】", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + var eff1 = get.effect(target, { name: "shunshou_copy2" }, player, player); + if ( + eff1 > 0 && + target.countCards("h") + + target.countCards("e", function (card) { + return get.value(card, target) > 0; + }) > + 1 + ) + eff1 *= 1.6; + var eff2 = player.canUse("sha", target) + ? get.effect(target, { name: "sha" }, player, player) + : 0; + if (eff2 > 0 && target.countCards("hs", "shan") + target.hp > 1) eff2 *= 2; + return eff1 > eff2 ? 0 : 1; + }); + } else event._result = { index: bool1 ? 0 : 1 }; + "step 4"; + if (result.index == 0) { + player.gainPlayerCard(target, true, num, "he"); event.finish(); } - 'step 5' + "step 5"; event.num--; - if(player.canUse('sha',target,false)){ - player.useCard({name:'sha',isCard:true},target,false); - if(event.num>0) event.redo(); + if (player.canUse("sha", target, false)) { + player.useCard({ name: "sha", isCard: true }, target, false); + if (event.num > 0) event.redo(); } }, }, - xiongrao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - limited:true, - skillAnimation:true, - animationColor:'soil', - prompt:function(event,player){ - var str='是否发动【熊扰】?'; - str+=('(可摸'+get.cnNumber(Math.max(0,7-player.maxHp))+'张牌)'); + xiongrao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + limited: true, + skillAnimation: true, + animationColor: "soil", + prompt: function (event, player) { + var str = "是否发动【熊扰】?"; + str += "(可摸" + get.cnNumber(Math.max(0, 7 - player.maxHp)) + "张牌)"; return str; }, - logTarget:(event,player)=>game.filterPlayer((current)=>current!=player), - check:function(event,player){ - return player.maxHp<=3; + logTarget: (event, player) => game.filterPlayer((current) => current != player), + check: function (event, player) { + return player.maxHp <= 3; }, - content:function(){ - player.awakenSkill('xiongrao'); - game.countPlayer(function(current){ - if(current!=player) current.addTempSkill('xiongrao_blocker'); + content: function () { + player.awakenSkill("xiongrao"); + game.countPlayer(function (current) { + if (current != player) current.addTempSkill("xiongrao_blocker"); }); - var num=7-player.maxHp; - if(num>0){ + var num = 7 - player.maxHp; + if (num > 0) { player.gainMaxHp(num); player.draw(num); } }, - subSkill:{ - blocker:{ - init:function(player,skill){ + subSkill: { + blocker: { + init: function (player, skill) { player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); }, - charlotte:true, - locked:true, - skillBlocker:function(skill,player){ - var info=get.info(skill); - return info&&!info.charlotte&&!get.is.locked(skill)&&!info.limited&&!info.juexingji; + charlotte: true, + locked: true, + skillBlocker: function (skill, player) { + var info = get.info(skill); + return ( + info && + !info.charlotte && + !get.is.locked(skill) && + !info.limited && + !info.juexingji + ); }, - mark:true, - marktext:'扰', - intro:{ - content:function(list,player,skill){ - var storage=player.getSkills(null,false,false).filter(function(i){ - return lib.skill.xiongrao_blocker.skillBlocker(i,player); + mark: true, + marktext: "扰", + intro: { + content: function (list, player, skill) { + var storage = player.getSkills(null, false, false).filter(function (i) { + return lib.skill.xiongrao_blocker.skillBlocker(i, player); }); - if(storage.length) return '失效技能:'+get.translation(storage); - return '无失效技能'; - } - } + if (storage.length) return "失效技能:" + get.translation(storage); + return "无失效技能"; + }, + }, }, - } + }, }, //卞喜 - dunxi:{ - audio:2, - trigger:{player:'useCard'}, - direct:true, - filter:function(event,player){ - if(!get.tag(event.card,'damage')) return false; - return event.targets.some(target=>target!=player&&target.isIn()); + dunxi: { + audio: 2, + trigger: { player: "useCard" }, + direct: true, + filter: function (event, player) { + if (!get.tag(event.card, "damage")) return false; + return event.targets.some((target) => target != player && target.isIn()); }, - content:function(){ - 'step 0' - var targets=trigger.targets.filter(function(current){ - return current!=player&¤t.isIn(); + content: function () { + "step 0"; + var targets = trigger.targets.filter(function (current) { + return current != player && current.isIn(); }); - if(targets.length==1){ - event.target=targets[0]; - player.chooseBool(get.prompt('dunxi',event.target),'令'+get.translation(event.target)+'获得一枚“钝”标记').set('goon',get.attitude(player,event.target)<0).set('ai',()=>_status.event.goon); + if (targets.length == 1) { + event.target = targets[0]; + player + .chooseBool( + get.prompt("dunxi", event.target), + "令" + get.translation(event.target) + "获得一枚“钝”标记" + ) + .set("goon", get.attitude(player, event.target) < 0) + .set("ai", () => _status.event.goon); + } else { + player + .chooseTarget( + get.prompt("dunxi"), + "选择一名目标角色获得一枚“钝”标记", + function (card, player, target) { + return ( + target != player && + _status.event.getTrigger().targets.includes(target) + ); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att >= 0) return 0; + return -att / (1 + target.hasMark("dunxi")); + }); } - else{ - player.chooseTarget(get.prompt('dunxi'),'选择一名目标角色获得一枚“钝”标记',function(card,player,target){ - return target!=player&&_status.event.getTrigger().targets.includes(target); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>=0) return 0; - return -att/(1+target.hasMark('dunxi')); - }); - } - 'step 1' - if(result.bool){ - var target=event.target||result.targets[0]; - player.logSkill('dunxi',target); - target.addMark('dunxi',1); + "step 1"; + if (result.bool) { + var target = event.target || result.targets[0]; + player.logSkill("dunxi", target); + target.addMark("dunxi", 1); game.delayx(); } }, - intro:{content:'mark',name2:'钝'}, - group:'dunxi_random', - subSkill:{ - random:{ - audio:'dunxi', - trigger:{global:'useCard'}, - forced:true, - locked:false, - filter:function(event,player){ - if(!event.player.hasMark('dunxi')||event.targets.length!=1||event._dunxi||_status.dying.length) return false; - var type=get.type2(event.card,false); - return (type=='basic'||type=='trick'); + intro: { content: "mark", name2: "钝" }, + group: "dunxi_random", + subSkill: { + random: { + audio: "dunxi", + trigger: { global: "useCard" }, + forced: true, + locked: false, + filter: function (event, player) { + if ( + !event.player.hasMark("dunxi") || + event.targets.length != 1 || + event._dunxi || + _status.dying.length + ) + return false; + var type = get.type2(event.card, false); + return type == "basic" || type == "trick"; }, - logTarget:'player', - line:'fire', - content:function(){ - 'step 0' - trigger._dunxi=true; - trigger.player.removeMark('dunxi',1); - var target=trigger.targets[0]; - event.target=target; + logTarget: "player", + line: "fire", + content: function () { + "step 0"; + trigger._dunxi = true; + trigger.player.removeMark("dunxi", 1); + var target = trigger.targets[0]; + event.target = target; trigger.targets.remove(target); //trigger.triggeredTargets1.remove(target); trigger.untrigger(); game.delayx(); - 'step 1' + "step 1"; var list; - if(get.type(event.card)!='delay') list=game.filterPlayer(function(current){ - return lib.filter.targetEnabled2(trigger.card,trigger.player,current); - }); - else list=game.filterPlayer(function(current){ - return current.canAddJudge(event.card); - }); - if(list.length) target=list.randomGet(); + if (get.type(event.card) != "delay") + list = game.filterPlayer(function (current) { + return lib.filter.targetEnabled2(trigger.card, trigger.player, current); + }); + else + list = game.filterPlayer(function (current) { + return current.canAddJudge(event.card); + }); + if (list.length) target = list.randomGet(); trigger.targets.push(target); - trigger.player.line(target,'fire'); - game.log(trigger.card,'的目标被改为',target); - if(target==event.target){ + trigger.player.line(target, "fire"); + game.log(trigger.card, "的目标被改为", target); + if (target == event.target) { trigger.player.loseHp(); - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.player==trigger.player) evt.skipped=true; + var evt = trigger.getParent("phaseUse"); + if (evt && evt.player == trigger.player) evt.skipped = true; } }, }, }, }, //冯方 - dcditing:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - logTarget:'player', - filter:function(event,player){ - return player.hp>0&&event.player.countCards('h')>0&&event.player.inRange(player); + dcditing: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + logTarget: "player", + filter: function (event, player) { + return player.hp > 0 && event.player.countCards("h") > 0 && event.player.inRange(player); }, - prompt2:(event,player)=>('观看其'+get.cnNumber(Math.min(player.hp,event.player.countCards('h')))+'张手牌并选择其中一张'), - check:function(event,player){ - var target=event.player; - if(get.attitude(player,target)>0) return true; - if(Math.min(player.hp,target.countCards('h'))>2) return true; + prompt2: (event, player) => + "观看其" + + get.cnNumber(Math.min(player.hp, event.player.countCards("h"))) + + "张手牌并选择其中一张", + check: function (event, player) { + var target = event.player; + if (get.attitude(player, target) > 0) return true; + if (Math.min(player.hp, target.countCards("h")) > 2) return true; return false; }, - content:function(){ - 'step 0' - var target=trigger.player; - var cards=target.getCards('h'); - var num=Math.min(cards.length,player.hp),cards2=cards.randomGets(num); - player.chooseButton([get.translation(target)+'的手牌('+num+'/'+cards.length+')',cards2],true).set('ai',function(button){ - var player=_status.event.player,target=_status.event.getTrigger().player,card=button.link; - var att=get.attitude(player,target); - var val=target.getUseValue(card,null,true); - if(val<=0) return -get.value(card,target)/2*get.sgn(att-0.05); - if(target.canUse(card,player)&&get.effect(player,card,target,target)>0){ - var eff=get.effect(player,card,target,player); - if(eff<0) val-=eff; - } - return val; - }); - 'step 1' - if(result.bool){ - player.addTempSkill('dcditing_effect','phaseUseAfter'); - player.storage.dcditing_effect=[trigger.player,result.links[0]]; + content: function () { + "step 0"; + var target = trigger.player; + var cards = target.getCards("h"); + var num = Math.min(cards.length, player.hp), + cards2 = cards.randomGets(num); + player + .chooseButton( + [get.translation(target) + "的手牌(" + num + "/" + cards.length + ")", cards2], + true + ) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.getTrigger().player, + card = button.link; + var att = get.attitude(player, target); + var val = target.getUseValue(card, null, true); + if (val <= 0) return (-get.value(card, target) / 2) * get.sgn(att - 0.05); + if (target.canUse(card, player) && get.effect(player, card, target, target) > 0) { + var eff = get.effect(player, card, target, player); + if (eff < 0) val -= eff; + } + return val; + }); + "step 1"; + if (result.bool) { + player.addTempSkill("dcditing_effect", "phaseUseAfter"); + player.storage.dcditing_effect = [trigger.player, result.links[0]]; } }, - subSkill:{ - effect:{ - audio:'dcditing', - charlotte:true, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - var list=player.storage.dcditing_effect; - return list&&event.player==list[0]&&event.cards.includes(list[1]); + subSkill: { + effect: { + audio: "dcditing", + charlotte: true, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + var list = player.storage.dcditing_effect; + return list && event.player == list[0] && event.cards.includes(list[1]); }, - content:function(){ + content: function () { trigger.excluded.add(player); game.delayx(); }, - group:['dcditing_draw','dcditing_gain'], + group: ["dcditing_draw", "dcditing_gain"], }, - draw:{ - audio:'dcditing', - charlotte:true, - trigger:{global:'useCardAfter'}, - forced:true, - filter:function(event,player){ - var list=player.storage.dcditing_effect; - return list&&event.player==list[0]&&event.cards.includes(list[1])&&!event.targets.includes(player); + draw: { + audio: "dcditing", + charlotte: true, + trigger: { global: "useCardAfter" }, + forced: true, + filter: function (event, player) { + var list = player.storage.dcditing_effect; + return ( + list && + event.player == list[0] && + event.cards.includes(list[1]) && + !event.targets.includes(player) + ); }, - content:function(){ + content: function () { player.draw(2); }, }, - gain:{ - audio:'dcditing', - charlotte:true, - trigger:{global:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - var list=player.storage.dcditing_effect; - return list&&event.player==list[0]&&event.player.getCards('h').includes(list[1]); + gain: { + audio: "dcditing", + charlotte: true, + trigger: { global: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + var list = player.storage.dcditing_effect; + return ( + list && + event.player == list[0] && + event.player.getCards("h").includes(list[1]) + ); }, - content:function(){ - var list=player.storage.dcditing_effect; - player.gain(list[0],list[1],'giveAuto','bySelf'); + content: function () { + var list = player.storage.dcditing_effect; + player.gain(list[0], list[1], "giveAuto", "bySelf"); }, }, }, }, - dcbihuo:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + dcbihuo: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - direct:true, - filter:function(event,player){ - return event.source&&event.player!=event.source; + direct: true, + filter: function (event, player) { + return event.source && event.player != event.source; }, - content:function(){ - 'step 0' - event.num=(event.triggername=='damageEnd'?1:-1); - player.chooseTarget(get.prompt('dcbihuo'),'令一名角色下回合的额定摸牌数'+(event.num>0?'+1':'-1')).set('ai',function(target){ - var player=_status.event.player,num=_status.event.getParent().num; - var att=get.attitude(player,target); - if(num>0){ - if(att<=0) return 0; - if(target.hasJudge('lebu')) return att/10; - return att/Math.sqrt(Math.min(5,1+target.countCards('h')))*Math.sqrt(1+target.hp); - } - if(num<0){ - if(att>=0) return 0; - if((target.storage.dcbihuo_effect||0)<=-2) return -att/10; - return -att/Math.sqrt(Math.min(5,1+target.countCards('h')))*Math.sqrt(1+target.hp); - } - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcbihuo',target); - if(typeof target.storage.dcbihuo_effect!='number') target.storage.dcbihuo_effect=0; - target.storage.dcbihuo_effect+=event.num; - target.addTempSkill('dcbihuo_effect',{player:'phaseAfter'}); + content: function () { + "step 0"; + event.num = event.triggername == "damageEnd" ? 1 : -1; + player + .chooseTarget( + get.prompt("dcbihuo"), + "令一名角色下回合的额定摸牌数" + (event.num > 0 ? "+1" : "-1") + ) + .set("ai", function (target) { + var player = _status.event.player, + num = _status.event.getParent().num; + var att = get.attitude(player, target); + if (num > 0) { + if (att <= 0) return 0; + if (target.hasJudge("lebu")) return att / 10; + return ( + (att / Math.sqrt(Math.min(5, 1 + target.countCards("h")))) * + Math.sqrt(1 + target.hp) + ); + } + if (num < 0) { + if (att >= 0) return 0; + if ((target.storage.dcbihuo_effect || 0) <= -2) return -att / 10; + return ( + (-att / Math.sqrt(Math.min(5, 1 + target.countCards("h")))) * + Math.sqrt(1 + target.hp) + ); + } + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcbihuo", target); + if (typeof target.storage.dcbihuo_effect != "number") + target.storage.dcbihuo_effect = 0; + target.storage.dcbihuo_effect += event.num; + target.addTempSkill("dcbihuo_effect", { player: "phaseAfter" }); game.delayx(); } }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{player:'phaseDrawBegin'}, - forced:true, - onremove:true, - content:function(){ - var num=player.storage.dcbihuo_effect; - trigger.num+=num; - game.log(player,'的额定摸牌数','#g'+(num>=0?'+':'')+num); + subSkill: { + effect: { + charlotte: true, + trigger: { player: "phaseDrawBegin" }, + forced: true, + onremove: true, + content: function () { + var num = player.storage.dcbihuo_effect; + trigger.num += num; + game.log(player, "的额定摸牌数", "#g" + (num >= 0 ? "+" : "") + num); }, - mark:true, - intro:{ - content:(num)=>('额定摸牌数'+(num>=0?'+':'')+num), + mark: true, + intro: { + content: (num) => "额定摸牌数" + (num >= 0 ? "+" : "") + num, }, }, }, }, //秦宜禄 - piaoping:{ - audio:2, - trigger:{player:'useCard'}, - forced:true, - zhuanhuanji:true, - filter:function(event,player){ - return !player.hasSkill('piaoping_blocker',null,null,false); + piaoping: { + audio: 2, + trigger: { player: "useCard" }, + forced: true, + zhuanhuanji: true, + filter: function (event, player) { + return !player.hasSkill("piaoping_blocker", null, null, false); }, - content:function(){ - player.changeZhuanhuanji('piaoping'); - var num=Math.min(player.hp,player.getHistory('useSkill',function(evt){ - return evt.skill=='piaoping'; - }).length); - if(num<=0) return; - if(player.storage.piaoping==true) player.draw(num); - else if(player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'piaoping'); - },'he')){ + content: function () { + player.changeZhuanhuanji("piaoping"); + var num = Math.min( + player.hp, + player.getHistory("useSkill", function (evt) { + return evt.skill == "piaoping"; + }).length + ); + if (num <= 0) return; + if (player.storage.piaoping == true) player.draw(num); + else if ( + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "piaoping"); + }, "he") + ) { game.delayx(); - player.chooseToDiscard(true,'he',num); + player.chooseToDiscard(true, "he", num); } }, - mark:true, - marktext:'☯', - intro:{ - content:function(storage){ - if(storage) return '转换技,锁定技。当你使用一张牌时,你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)'; - return '转换技,锁定技。当你使用一张牌时,你摸X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)'; + mark: true, + marktext: "☯", + intro: { + content: function (storage) { + if (storage) + return "转换技,锁定技。当你使用一张牌时,你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)"; + return "转换技,锁定技。当你使用一张牌时,你摸X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)"; }, }, - subSkill:{blocker:{charlotte:true}}, + subSkill: { blocker: { charlotte: true } }, }, - tuoxian:{ - audio:2, - ai:{combo:'piaoping'}, - trigger:{player:'loseAfter'}, - marktext:'栗', - filter:function(event,player){ - return event.type=='discard'&&event.getParent(3).name=='piaoping'&&player.countMark('tuoxian')>0&&event.cards.filterInD('d').length>0; + tuoxian: { + audio: 2, + ai: { combo: "piaoping" }, + trigger: { player: "loseAfter" }, + marktext: "栗", + filter: function (event, player) { + return ( + event.type == "discard" && + event.getParent(3).name == "piaoping" && + player.countMark("tuoxian") > 0 && + event.cards.filterInD("d").length > 0 + ); }, - direct:true, - content:function(){ - 'step 0' - event.cards=trigger.cards.filterInD('d'); - player.chooseTarget(lib.filter.notMe,get.prompt('tuoxian'),'令一名其他角色获得'+get.translation(event.cards)).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<0) return 0; - if(target.hasSkillTag('nogain')) att/=10; - return att*Math.pow(1+target.countCards('he'),0.25); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('tuoxian',target); - player.removeMark('tuoxian',1); - target.gain(cards,'gain2'); - } - else event.finish(); - 'step 2' - target.chooseControl().set('choiceList',[ - '弃置区域内的'+get.cnNumber(cards.length)+'张牌', - '令'+get.translation(player)+'的〖漂萍〗于本回合内失效', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().player; - if(player.hasCard(function(card){ - return get.effect(player,{name:card.viewAs||card.name},player,player)<0; - },'j')||player.hasCard(function(card){ - return get.value(card,player)<=0; - })) return 0; - if(get.attitude(player,target)<=0||!target.isPhaseUsing()) return 1; - if(!target.needsToDiscard()&&!target.hasCard(function(card){ - return !target.hasValueTarget(card,null,true); - },'hs')) return 1; - return 0; - }); - 'step 3' - if(result.index==0){ - if(target.countCards('j')>0) target.discardPlayerCard(target,cards.length,true,'hej'); - else target.chooseToDiscard('he',true,cards.length); - } - else player.addTempSkill('piaoping_blocker'); + direct: true, + content: function () { + "step 0"; + event.cards = trigger.cards.filterInD("d"); + player + .chooseTarget( + lib.filter.notMe, + get.prompt("tuoxian"), + "令一名其他角色获得" + get.translation(event.cards) + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att < 0) return 0; + if (target.hasSkillTag("nogain")) att /= 10; + return att * Math.pow(1 + target.countCards("he"), 0.25); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("tuoxian", target); + player.removeMark("tuoxian", 1); + target.gain(cards, "gain2"); + } else event.finish(); + "step 2"; + target + .chooseControl() + .set("choiceList", [ + "弃置区域内的" + get.cnNumber(cards.length) + "张牌", + "令" + get.translation(player) + "的〖漂萍〗于本回合内失效", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().player; + if ( + player.hasCard(function (card) { + return ( + get.effect( + player, + { name: card.viewAs || card.name }, + player, + player + ) < 0 + ); + }, "j") || + player.hasCard(function (card) { + return get.value(card, player) <= 0; + }) + ) + return 0; + if (get.attitude(player, target) <= 0 || !target.isPhaseUsing()) return 1; + if ( + !target.needsToDiscard() && + !target.hasCard(function (card) { + return !target.hasValueTarget(card, null, true); + }, "hs") + ) + return 1; + return 0; + }); + "step 3"; + if (result.index == 0) { + if (target.countCards("j") > 0) + target.discardPlayerCard(target, cards.length, true, "hej"); + else target.chooseToDiscard("he", true, cards.length); + } else player.addTempSkill("piaoping_blocker"); }, - init(player){ - player.addMark('tuoxian',1,false); + init(player) { + player.addMark("tuoxian", 1, false); }, - intro:{name2:'栗',content:'剩余可用#次'}, + intro: { name2: "栗", content: "剩余可用#次" }, }, - chuaili:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - if(player==event.player||get.color(event.card)!='black') return false; - if(!player.hasSkill('piaoping',null,null,false)) return false; - return player.storage.piaoping==true||!player.hasSkill('chuaili_blocker',null,null,false); + chuaili: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + if (player == event.player || get.color(event.card) != "black") return false; + if (!player.hasSkill("piaoping", null, null, false)) return false; + return ( + player.storage.piaoping == true || + !player.hasSkill("chuaili_blocker", null, null, false) + ); }, - content:function(){ - if(player.storage.piaoping==true){ - player.changeZhuanhuanji('piaoping'); - } - else{ - player.addMark('tuoxian',1,false); - if(player.countCards('tuoxian')>3) player.addTempSkill('chuaili_blocker'); + content: function () { + if (player.storage.piaoping == true) { + player.changeZhuanhuanji("piaoping"); + } else { + player.addMark("tuoxian", 1, false); + if (player.countCards("tuoxian") > 3) player.addTempSkill("chuaili_blocker"); } game.delayx(); }, - ai:{combo:'piaoping'}, - subSkill:{blocker:{charlotte:true}}, + ai: { combo: "piaoping" }, + subSkill: { blocker: { charlotte: true } }, }, //闫柔 - choutao:{ - audio:2, - trigger:{ - player:'useCard', - target:'useCardToTargeted', + choutao: { + audio: 2, + trigger: { + player: "useCard", + target: "useCardToTargeted", }, - filter:function(event,player){ - if(event.card.name!='sha'||!event.player.isIn()) return false; - if(player==event.player) return player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'choutao'); - },'he'); - return event.player.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,event.player); - },'he'); + filter: function (event, player) { + if (event.card.name != "sha" || !event.player.isIn()) return false; + if (player == event.player) + return player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "choutao"); + }, "he"); + return event.player.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, event.player); + }, "he"); }, - check:function(event,player){ - if(player==event.player){ - if(!player.hasCard(function(card){ - return get.value(card)<=5; - },'he')) return false; - for(var i of event.targets){ - var eff1=get.damageEffect(i,player,player); - if(eff1<0) return false; - if(i.hasShan()&&eff1>0) return true; + check: function (event, player) { + if (player == event.player) { + if ( + !player.hasCard(function (card) { + return get.value(card) <= 5; + }, "he") + ) + return false; + for (var i of event.targets) { + var eff1 = get.damageEffect(i, player, player); + if (eff1 < 0) return false; + if (i.hasShan() && eff1 > 0) return true; } - var sha=false; - return player.getCardUsable({name:'sha'})<=0&&player.hasCard(function(card){ - if(!sha&&get.name(card)=='sha'&&player.getUseValue(card)>0){ - sha=true; - return false; - } - return sha&&get.value(card)<=5; - },'hs'); - } - else{ - var eff1=get.effect(event.player,{name:'guohe_copy2'},player,player); - var eff2=get.damageEffect(player,event.player,player); - if(!player.hasShan()) return eff1>0; - if(eff2>0) return eff1>0; - return player.hp>2&&eff2 0) { + sha = true; + return false; + } + return sha && get.value(card) <= 5; + }, "hs") + ); + } else { + var eff1 = get.effect(event.player, { name: "guohe_copy2" }, player, player); + var eff2 = get.damageEffect(player, event.player, player); + if (!player.hasShan()) return eff1 > 0; + if (eff2 > 0) return eff1 > 0; + return player.hp > 2 && eff2 < eff1; } }, - logTarget:'player', - shaRelated:true, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isOnline()&&!player.isUnderControl()) game.delayx(); - if(player==trigger.player) player.chooseToDiscard('he',true).set('ai',function(card){ - var player=_status.event.player; - var val=player.getUseValue(card); - if(get.name(card)=='sha'&&player.getUseValue(card)>0) val+=5; - return 20-val; - }); - else player.discardPlayerCard(trigger.player,true,'he'); - 'step 1' + logTarget: "player", + shaRelated: true, + content: function () { + "step 0"; + if (player != game.me && !player.isOnline() && !player.isUnderControl()) game.delayx(); + if (player == trigger.player) + player.chooseToDiscard("he", true).set("ai", function (card) { + var player = _status.event.player; + var val = player.getUseValue(card); + if (get.name(card) == "sha" && player.getUseValue(card) > 0) val += 5; + return 20 - val; + }); + else player.discardPlayerCard(trigger.player, true, "he"); + "step 1"; trigger.directHit.addArray(game.players); - if(player==trigger.player&&trigger.addCount!==false){ - trigger.addCount=false; + if (player == trigger.player && trigger.addCount !== false) { + trigger.addCount = false; player.getStat().card.sha--; } }, }, - xiangshu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return (player.getStat('damage')||0)>0&&game.hasPlayer((current)=>current.isDamaged()); + xiangshu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + limited: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return ( + (player.getStat("damage") || 0) > 0 && + game.hasPlayer((current) => current.isDamaged()) + ); }, - content:function(){ - 'step 0' - event.num=Math.min(5,player.getStat('damage')); - player.chooseTarget('是否发动限定技【襄戍】?','令一名角色回复'+event.num+'点体力并摸'+get.cnNumber(event.num)+'张牌',function(card,player,target){ - return target.isDamaged(); - }).set('ai',function(target){ - var num=_status.event.getParent().num,player=_status.event.player; - var att=get.attitude(player,target); - if(att>0&&num>=Math.min(player.hp,2)) return att*Math.sqrt(target.getDamagedHp()); - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.awakenSkill('xiangshu'); - player.logSkill('xiangshu',target); + content: function () { + "step 0"; + event.num = Math.min(5, player.getStat("damage")); + player + .chooseTarget( + "是否发动限定技【襄戍】?", + "令一名角色回复" + event.num + "点体力并摸" + get.cnNumber(event.num) + "张牌", + function (card, player, target) { + return target.isDamaged(); + } + ) + .set("ai", function (target) { + var num = _status.event.getParent().num, + player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0 && num >= Math.min(player.hp, 2)) + return att * Math.sqrt(target.getDamagedHp()); + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.awakenSkill("xiangshu"); + player.logSkill("xiangshu", target); target.recover(num); target.draw(num); - if(player!=target) player.addExpose(0.2); + if (player != target) player.addExpose(0.2); } }, }, //朱灵 - dczhanyi:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - var list=['basic','trick','equip']; - var list2=[]; - var hs=player.getCards('he'); - for(var card of hs){ - var type=get.type2(card,player); - if(list.includes(type)){ - var bool=lib.filter.cardDiscardable(card,player,'dczhanyi'); - if(bool) list2.add(type); - else{ + dczhanyi: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + var list = ["basic", "trick", "equip"]; + var list2 = []; + var hs = player.getCards("he"); + for (var card of hs) { + var type = get.type2(card, player); + if (list.includes(type)) { + var bool = lib.filter.cardDiscardable(card, player, "dczhanyi"); + if (bool) list2.add(type); + else { list.remove(type); list2.remove(type); } } } - return list2.length>0; + return list2.length > 0; }, - content:function(){ - 'step 0' - var list=['basic','trick','equip']; - var list2=[]; - var hs=player.getCards('he'); - for(var card of hs){ - var type=get.type2(card,player); - if(list.includes(type)){ - var bool=lib.filter.cardDiscardable(card,player,'dczhanyi'); - if(bool) list2.add(type); - else{ + content: function () { + "step 0"; + var list = ["basic", "trick", "equip"]; + var list2 = []; + var hs = player.getCards("he"); + for (var card of hs) { + var type = get.type2(card, player); + if (list.includes(type)) { + var bool = lib.filter.cardDiscardable(card, player, "dczhanyi"); + if (bool) list2.add(type); + else { list.remove(type); list2.remove(type); } } } - player.chooseControl(list2,'cancel2').set('prompt',get.prompt('dczhanyi')).set('prompt2','弃置一种类型的所有牌').set('ai',function(){ - var player=_status.event.player; - var getval=function(control){ - if(control=='cancel2') return 0; - var hs=player.getCards('h'),eff=0; - var es=player.getCards('e'); - var ss=player.getCards('s'); - var sha=player.getCardUsable({name:'sha'}); - for(var i of hs){ - var type=get.type2(i); - if(type==control){ - eff-=get.value(i,player); - } - else{ - switch(type){ - case 'basic': - if(sha>0&&get.name(i)=='sha'){ - sha--; - var add=3; - if(!player.hasValueTarget(i)&&player.hasValueTarget(i,false)) add+=player.getUseValue(i,false); - eff+=add; - } - break - case 'trick': - if(player.hasValueTarget(i)) eff+=6; - break; - case 'equip': - if(player.hasValueTarget({name:'guohe_copy2'})) eff+=player.getUseValue({name:'guohe_copy2'}); - break; + player + .chooseControl(list2, "cancel2") + .set("prompt", get.prompt("dczhanyi")) + .set("prompt2", "弃置一种类型的所有牌") + .set("ai", function () { + var player = _status.event.player; + var getval = function (control) { + if (control == "cancel2") return 0; + var hs = player.getCards("h"), + eff = 0; + var es = player.getCards("e"); + var ss = player.getCards("s"); + var sha = player.getCardUsable({ name: "sha" }); + for (var i of hs) { + var type = get.type2(i); + if (type == control) { + eff -= get.value(i, player); + } else { + switch (type) { + case "basic": + if (sha > 0 && get.name(i) == "sha") { + sha--; + var add = 3; + if ( + !player.hasValueTarget(i) && + player.hasValueTarget(i, false) + ) + add += player.getUseValue(i, false); + eff += add; + } + break; + case "trick": + if (player.hasValueTarget(i)) eff += 6; + break; + case "equip": + if (player.hasValueTarget({ name: "guohe_copy2" })) + eff += player.getUseValue({ name: "guohe_copy2" }); + break; + } } } - } - if(control=='equip'){ - for(var i of es) eff-=get.value(i,player); - } - else{ - for(var i of ss){ - var type=get.type2(i); - if(type==control) continue; - switch(type){ - case 'basic': - if(sha>0&&get.name(i)=='sha'){ - sha--; - var add=3; - if(!player.hasValueTarget(i)&&player.hasValueTarget(i,false)) add+=player.getUseValue(i,false); - eff+=add; - } - break - case 'trick': - if(player.hasValueTarget(i)) eff+=6; - break; - case 'equip': - if(player.hasValueTarget({name:'guohe_copy2'})) eff+=player.getUseValue({name:'guohe_copy2'}); - break; + if (control == "equip") { + for (var i of es) eff -= get.value(i, player); + } else { + for (var i of ss) { + var type = get.type2(i); + if (type == control) continue; + switch (type) { + case "basic": + if (sha > 0 && get.name(i) == "sha") { + sha--; + var add = 3; + if ( + !player.hasValueTarget(i) && + player.hasValueTarget(i, false) + ) + add += player.getUseValue(i, false); + eff += add; + } + break; + case "trick": + if (player.hasValueTarget(i)) eff += 6; + break; + case "equip": + if (player.hasValueTarget({ name: "guohe_copy2" })) + eff += player.getUseValue({ name: "guohe_copy2" }); + break; + } } } + return eff; + }; + var controls = _status.event.controls.slice(0); + var eff = 0, + current = "cancel2"; + for (var i of controls) { + var effx = getval(i); + if (effx > eff) { + eff = effx; + current = i; + } } - return eff; - }; - var controls=_status.event.controls.slice(0); - var eff=0,current='cancel2'; - for(var i of controls){ - var effx=getval(i); - if(effx>eff){ - eff=effx; - current=i; - } - } - return current; - }); - 'step 1' - var type=result.control; - if(type!='cancel2'){ - event.type=type; - var cards=player.getCards('he',function(card){ - return get.type2(card,player)==type; + return current; }); - if(cards.length){ - player.logSkill('dczhanyi'); + "step 1"; + var type = result.control; + if (type != "cancel2") { + event.type = type; + var cards = player.getCards("he", function (card) { + return get.type2(card, player) == type; + }); + if (cards.length) { + player.logSkill("dczhanyi"); player.discard(cards); - } - else event.finish(); - } - else event.finish(); - 'step 2' - var list=['basic','trick','equip']; - for(var i of list){ - if(i!=event.type) player.addTempSkill('dczhanyi_'+i,{player:'phaseBegin'}); + } else event.finish(); + } else event.finish(); + "step 2"; + var list = ["basic", "trick", "equip"]; + for (var i of list) { + if (i != event.type) player.addTempSkill("dczhanyi_" + i, { player: "phaseBegin" }); } }, - subSkill:{ - basic:{ - charlotte:true, - marktext:'基', - mark:true, - intro:{ - content:'使用基本牌无距离限制,且伤害值和回复值基数+1', + subSkill: { + basic: { + charlotte: true, + marktext: "基", + mark: true, + intro: { + content: "使用基本牌无距离限制,且伤害值和回复值基数+1", }, - trigger:{source:['damageBegin1','recoverBegin']}, - filter:function(event,player){ - var evt=event.getParent(); - return evt.type=='card'&&get.type(evt.card,false)=='basic'; + trigger: { source: ["damageBegin1", "recoverBegin"] }, + filter: function (event, player) { + var evt = event.getParent(); + return evt.type == "card" && get.type(evt.card, false) == "basic"; }, - forced:true, - logTarget:'player', - content:function(){ + forced: true, + logTarget: "player", + content: function () { trigger.num++; }, - mod:{ - targetInRange:function(card){ - if(get.type(card)=='basic') return true; + mod: { + targetInRange: function (card) { + if (get.type(card) == "basic") return true; }, }, - ai:{ - damageBonus:true, + ai: { + damageBonus: true, }, }, - trick:{ - charlotte:true, - marktext:'锦', - mark:true, - intro:{ - content:'使用锦囊牌时摸一张牌,且锦囊牌不计入本回合的手牌上限', + trick: { + charlotte: true, + marktext: "锦", + mark: true, + intro: { + content: "使用锦囊牌时摸一张牌,且锦囊牌不计入本回合的手牌上限", }, - trigger:{player:'useCard'}, - filter:function(event,player){ - return get.type2(event.card)=='trick'; + trigger: { player: "useCard" }, + filter: function (event, player) { + return get.type2(event.card) == "trick"; }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, - mod:{ - ignoredHandcard:function(card,player){ - if(get.type2(card,player)=='trick') return true; + mod: { + ignoredHandcard: function (card, player) { + if (get.type2(card, player) == "trick") return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.type2(card,player)=='trick') return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.type2(card, player) == "trick") + return false; + }, + }, + }, + equip: { + charlotte: true, + marktext: "装", + mark: true, + intro: { + content: "有装备牌进入你的装备区时,可弃置一名其他角色的一张牌", + }, + trigger: { player: "equipAfter" }, + filter: function (event, player) { + return game.hasPlayer( + (target) => target != player && target.countDiscardableCards(player, "he") > 0 + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + "战意:是否弃置一名其他角色的一张牌?", + function (card, player, target) { + return ( + target != player && target.countDiscardableCards(player, "he") > 0 + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dczhanyi_equip", target); + player.discardPlayerCard(target, "he", true); } }, }, - equip:{ - charlotte:true, - marktext:'装', - mark:true, - intro:{ - content:'有装备牌进入你的装备区时,可弃置一名其他角色的一张牌', - }, - trigger:{player:'equipAfter'}, - filter:function(event,player){ - return game.hasPlayer((target)=>(target!=player&&target.countDiscardableCards(player,'he')>0)); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget('战意:是否弃置一名其他角色的一张牌?',function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dczhanyi_equip',target); - player.discardPlayerCard(target,'he',true); - } - }, - } }, }, //李采薇 - yijiao:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&!current.hasMark('yijiao'); + yijiao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && !current.hasMark("yijiao"); }); }, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasMark('yijiao'); + filterTarget: function (card, player, target) { + return target != player && !target.hasMark("yijiao"); }, - content:function(){ - 'step 0' - player.chooseControl('10个','20个','30个','40个').set('prompt','要令'+get.translation(target)+'获得多少标记?').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - /*if(get.attitude(player,target)<0&&game.hasPlayer(function(current){ + content: function () { + "step 0"; + player + .chooseControl("10个", "20个", "30个", "40个") + .set("prompt", "要令" + get.translation(target) + "获得多少标记?") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + /*if(get.attitude(player,target)<0&&game.hasPlayer(function(current){ return current!=player&¤t!=target&&!current.hasMark('yijiao')&&get.attitude(player,current)<0; })) return 3;*/ - return 0; - }); - 'step 1' - target.addMark('yijiao',10*(1+result.index)); + return 0; + }); + "step 1"; + target.addMark("yijiao", 10 * (1 + result.index)); }, - ai:{ - order:1.1, - result:{ - player:1, - target:-0.5, + ai: { + order: 1.1, + result: { + player: 1, + target: -0.5, }, }, - group:'yijiao_effect', - subSkill:{ - effect:{ - trigger:{global:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return event.player.isIn()&&event.player!=player&&event.player.hasMark('yijiao'); + group: "yijiao_effect", + subSkill: { + effect: { + trigger: { global: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player != player && + event.player.hasMark("yijiao") + ); }, - logTarget:'player', - content:function(){ - var target=trigger.player,num=target.countMark('yijiao'); - var num2=0; - target.getHistory('useCard',function(evt){ - var numz=get.number(evt.card); - if(typeof numz=='number') num2+=numz; + logTarget: "player", + content: function () { + var target = trigger.player, + num = target.countMark("yijiao"); + var num2 = 0; + target.getHistory("useCard", function (evt) { + var numz = get.number(evt.card); + if (typeof numz == "number") num2 += numz; }); - if(num>num2){ - var hs=target.getCards('he',function(card){ - return lib.filter.cardDiscardable(card,target,'yijiao_effect'); + if (num > num2) { + var hs = target.getCards("he", function (card) { + return lib.filter.cardDiscardable(card, target, "yijiao_effect"); }); - if(hs.length) target.discard(hs.randomGets(get.rand(1,3))); - } - else if(num==num2){ + if (hs.length) target.discard(hs.randomGets(get.rand(1, 3))); + } else if (num == num2) { target.insertPhase(); player.draw(2); - } - else{ + } else { player.draw(3); } - target.removeMark('yijiao',num); + target.removeMark("yijiao", num); }, }, }, - intro:{ - onunmark:true, - name2:'异', - content:'mark', + intro: { + onunmark: true, + name2: "异", + content: "mark", }, }, - qibie:{ - audio:2, - trigger:{global:'die'}, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasCard(function(card){ - return !lib.filter.cardDiscardable(card,player,'qibie'); - },'h'); + qibie: { + audio: 2, + trigger: { global: "die" }, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.hasCard(function (card) { + return !lib.filter.cardDiscardable(card, player, "qibie"); + }, "h") + ); }, - check:function(event,player){ - return player.isDamaged()&&player.countCards('h','tao')0; + channi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:lib.filter.notMe, - filterCard:true, - selectCard:[1,Infinity], - check:function(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); + filterTarget: lib.filter.notMe, + filterCard: true, + selectCard: [1, Infinity], + check: function (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, - lose:false, - delay:false, - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' - if(target.countCards('h')>0){ - game.broadcastAll(function(num){ - lib.skill.channi_backup.selectCard=[1,num]; - },cards.length); - var next=target.chooseToUse(); - next.set('openskilldialog','将至多'+get.cnNumber(cards.length)+'张手牌当做【决斗】使用'); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','channi_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + position: "h", + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + if (target.countCards("h") > 0) { + game.broadcastAll(function (num) { + lib.skill.channi_backup.selectCard = [1, num]; + }, cards.length); + var next = target.chooseToUse(); + next.set( + "openskilldialog", + "将至多" + get.cnNumber(cards.length) + "张手牌当做【决斗】使用" + ); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "channi_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('channi_backup'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var evts=target.getHistory('useCard',function(evt){ - return evt.card.name=='juedou'&&evt.getParent(2)==event; + next.backup("channi_backup"); + } else event.finish(); + "step 2"; + if (result.bool) { + var evts = target.getHistory("useCard", function (evt) { + return evt.card.name == "juedou" && evt.getParent(2) == event; }); - if(!evts.length){ + if (!evts.length) { event.finish(); return; } - var num=evts[0].cards.length; - if(target.hasHistory('sourceDamage',function(evt){ - return evt.card&&evt.card.name=='juedou'&&evt.getParent(4)==event; - })) target.draw(num); - } - else event.finish(); - 'step 3' - if(player.countCards('h')>0&&target.hasHistory('damage',function(evt){ - return evt.card&&evt.card.name=='juedou'&&evt.getParent(4)==event; - })) player.chooseToDiscard('h',true,player.countCards('h')); + var num = evts[0].cards.length; + if ( + target.hasHistory("sourceDamage", function (evt) { + return evt.card && evt.card.name == "juedou" && evt.getParent(4) == event; + }) + ) + target.draw(num); + } else event.finish(); + "step 3"; + if ( + player.countCards("h") > 0 && + target.hasHistory("damage", function (evt) { + return evt.card && evt.card.name == "juedou" && evt.getParent(4) == event; + }) + ) + player.chooseToDiscard("h", true, player.countCards("h")); }, - subSkill:{ - backup:{ - filterCard:function(card){ - return get.itemtype(card)=='card'; + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - viewAs:{name:'juedou'}, - position:'h', - filterTarget:lib.filter.targetEnabled, - ai1:(card)=>{ - if(get.name(card)==='sha') return 0; - return 5.5-get.value(card); + viewAs: { name: "juedou" }, + position: "h", + filterTarget: lib.filter.targetEnabled, + ai1: (card) => { + if (get.name(card) === "sha") return 0; + return 5.5 - get.value(card); }, - log:false, - precontent:function(){ + log: false, + precontent: function () { delete event.result.skill; }, }, }, - ai:{ - order:0.3, - result:{ - target:function(player,target){ - if(target==game.me||target.isOnline()||target.hasValueTarget({name:'juedou'})) return 2; - if(player.needsToDiscard()) return 0.5; + ai: { + order: 0.3, + result: { + target: function (player, target) { + if ( + target == game.me || + target.isOnline() || + target.hasValueTarget({ name: "juedou" }) + ) + return 2; + if (player.needsToDiscard()) return 0.5; return 0; }, }, }, }, - nifu:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player.countCards('h')!=3; + nifu: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return player.countCards("h") != 3; }, - content:function(){ - var num=player.countCards('h')-3; - if(num>0) player.chooseToDiscard('h',num,true); + content: function () { + var num = player.countCards("h") - 3; + if (num > 0) player.chooseToDiscard("h", num, true); else player.draw(-num); }, }, //郝萌 - xiongmang:{ - audio:2, - enable:'chooseToUse', - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - return player.countCards('hs')>0; + xiongmang: { + audio: 2, + enable: "chooseToUse", + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + return player.countCards("hs") > 0; }, - selectCard:function(){ - return [1,4]; + selectCard: function () { + return [1, 4]; }, - selectTarget:function(){ - var card=get.card(),player=get.player(); - if(card==undefined) return; - var range=[1,Math.max(1,ui.selected.cards.length)] - game.checkMod(card,player,range,'selectTarget',player); + selectTarget: function () { + var card = get.card(), + player = get.player(); + if (card == undefined) return; + var range = [1, Math.max(1, ui.selected.cards.length)]; + game.checkMod(card, player, range, "selectTarget", player); return range; }, - complexCard:true, - filterCard:function(card){ - if(!ui.selected.cards.length) return true; - var suit=get.suit(card); - for(var i of ui.selected.cards){ - if(get.suit(i)==suit) return false; + complexCard: true, + filterCard: function (card) { + if (!ui.selected.cards.length) return true; + var suit = get.suit(card); + for (var i of ui.selected.cards) { + if (get.suit(i) == suit) return false; } return true; }, - filterOk:function(){ - if(!ui.selected.targets.length) return false; - var card=get.card(),player=get.player(); - if(card==undefined) return; - var range=[1,Math.max(1,ui.selected.cards.length)] - game.checkMod(card,player,range,'selectTarget',player); - if(range[0]<=ui.selected.targets.length&&range[1]>=ui.selected.targets.length||range[0]==-1) return true; + filterOk: function () { + if (!ui.selected.targets.length) return false; + var card = get.card(), + player = get.player(); + if (card == undefined) return; + var range = [1, Math.max(1, ui.selected.cards.length)]; + game.checkMod(card, player, range, "selectTarget", player); + if ( + (range[0] <= ui.selected.targets.length && range[1] >= ui.selected.targets.length) || + range[0] == -1 + ) + return true; return false; }, - check:function(card){ - var player=_status.event.player,card=get.autoViewAs({name:'sha'},ui.selected.cards.concat(card)); - if(game.countPlayer(function(current){ - return (_status.event.filterTarget||lib.filter.filterTarget)(card,player,current)&&get.effect_use(current,card,player,player)>0; - })<=ui.selected.cards.length) return 0; - return 5-get.value(card); + check: function (card) { + var player = _status.event.player, + card = get.autoViewAs({ name: "sha" }, ui.selected.cards.concat(card)); + if ( + game.countPlayer(function (current) { + return ( + (_status.event.filterTarget || lib.filter.filterTarget)( + card, + player, + current + ) && get.effect_use(current, card, player, player) > 0 + ); + }) <= ui.selected.cards.length + ) + return 0; + return 5 - get.value(card); }, - position:'hs', - onuse:function(links,player){ - player.addTempSkill('xiongmang_effect'); + position: "hs", + onuse: function (links, player) { + player.addTempSkill("xiongmang_effect"); }, - ai:{ - order:()=>get.order({name:'sha'})+0.2, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - return player.countCards('hs')>0; + ai: { + order: () => get.order({ name: "sha" }) + 0.2, + respondSha: true, + skillTagFilter: function (player, tag, arg) { + return player.countCards("hs") > 0; }, }, - subSkill:{ - effect:{ - trigger:{player:'useCardAfter'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.skill=='xiongmang'&&!player.hasHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }); + subSkill: { + effect: { + trigger: { player: "useCardAfter" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + player.maxHp > 1 && + event.skill == "xiongmang" && + !player.hasHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }) + ); }, - content:function(){ + content: function () { player.loseMaxHp(); }, }, }, }, //庞德公 - heqia:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer((current)=>current.countCards(current==player?'he':'h')>0); + heqia: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer( + (current) => current.countCards(current == player ? "he" : "h") > 0 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('heqia'), - prompt2:'操作提示:选择要给出的牌和目标角色,或直接选择一名目标角色,令其将牌交给自己', - filterCard:true, - position:'he', - selectCard:function(){ - if(ui.selected.targets.length&&!ui.selected.targets[0].countCards('h')) return [1,Infinity]; - return [0,Infinity]; + prompt: get.prompt("heqia"), + prompt2: + "操作提示:选择要给出的牌和目标角色,或直接选择一名目标角色,令其将牌交给自己", + filterCard: true, + position: "he", + selectCard: function () { + if (ui.selected.targets.length && !ui.selected.targets[0].countCards("h")) + return [1, Infinity]; + return [0, Infinity]; }, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(!ui.selected.cards.length) return target.countCards('h')>0; + filterTarget: function (card, player, target) { + if (player == target) return false; + if (!ui.selected.cards.length) return target.countCards("h") > 0; return true; }, - ai1:function(card){ - if(!_status.event.nogive||ui.selected.cards.length) return 0-get.value(card); - return 1/Math.max(1,get.value(card)); + ai1: function (card) { + if (!_status.event.nogive || ui.selected.cards.length) return 0 - get.value(card); + return 1 / Math.max(1, get.value(card)); }, - ai2:function(target){ - return (get.attitude(player,target)-0.1)*(ui.selected.cards.length?1:-1); + ai2: function (target) { + return (get.attitude(player, target) - 0.1) * (ui.selected.cards.length ? 1 : -1); }, - nogive:!game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)<=0&¤t.countCards('h')>0; + nogive: !game.hasPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) <= 0 && + current.countCards("h") > 0 + ); }), }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('heqia',target); - if(result.cards.length){ - player.give(result.cards,target); - event.source=target; - event.num=result.cards.length; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("heqia", target); + if (result.cards.length) { + player.give(result.cards, target); + event.source = target; + event.num = result.cards.length; event.goto(4); } - } - else event.finish(); - 'step 2' - var he=target.getCards('he'); - if(he.length>0){ - if(he.length>1) target.chooseCard('he',true,[1,Infinity],'选择交给'+get.translation(player)+'任意张牌').set('ai',(card)=>-get.value(card)); - else event._result={bool:true,cards:he}; - } - else event.finish(); - 'step 3' - if(result.bool){ - event.source=player; - target.give(result.cards,player); - event.num=result.cards.length; - } - else event.finish(); - 'step 4' - if(source&&source.isIn()&&source.countCards('h')>0){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)!='basic') continue; - if(source.hasUseTarget({name:name},false)) list.push(['基本','',name]); - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(source.hasUseTarget({name:name,nature:nature},false)) list.push(['基本','',name,nature]); + } else event.finish(); + "step 2"; + var he = target.getCards("he"); + if (he.length > 0) { + if (he.length > 1) + target + .chooseCard( + "he", + true, + [1, Infinity], + "选择交给" + get.translation(player) + "任意张牌" + ) + .set("ai", (card) => -get.value(card)); + else event._result = { bool: true, cards: he }; + } else event.finish(); + "step 3"; + if (result.bool) { + event.source = player; + target.give(result.cards, player); + event.num = result.cards.length; + } else event.finish(); + "step 4"; + if (source && source.isIn() && source.countCards("h") > 0) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) != "basic") continue; + if (source.hasUseTarget({ name: name }, false)) list.push(["基本", "", name]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if (source.hasUseTarget({ name: name, nature: nature }, false)) + list.push(["基本", "", name, nature]); } } } - if(list.length){ - source.chooseButton(['是否将一张手牌当做一种基本牌使用?',[list,'vcard']]).set('ai',(button)=>_status.event.player.getUseValue({name:button.link[2],nature:button.link[3]},false)); - } - else event.finish(); - } - else event.finish(); - 'step 5' - if(result.bool){ - var card={name:result.links[0][2],nature:result.links[0][3]}; - game.broadcastAll(function(card){ - lib.skill.heqia_backup.viewAs=card; - },card); - var next=source.chooseToUse(); - next.set('openskilldialog','将一张手牌当做'+get.translation(card)+'使用'); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','heqia_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + if (list.length) { + source + .chooseButton(["是否将一张手牌当做一种基本牌使用?", [list, "vcard"]]) + .set("ai", (button) => + _status.event.player.getUseValue( + { name: button.link[2], nature: button.link[3] }, + false + ) + ); + } else event.finish(); + } else event.finish(); + "step 5"; + if (result.bool) { + var card = { name: result.links[0][2], nature: result.links[0][3] }; + game.broadcastAll(function (card) { + lib.skill.heqia_backup.viewAs = card; + }, card); + var next = source.chooseToUse(); + next.set("openskilldialog", "将一张手牌当做" + get.translation(card) + "使用"); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "heqia_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('heqia_backup'); + next.backup("heqia_backup"); } }, - group:'heqia_add', - subSkill:{ - backup:{ - filterCard:function(card){ - return get.itemtype(card)=='card'; + group: "heqia_add", + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - position:'h', - filterTarget:lib.filter.targetEnabled, - selectCard:1, - check:(card)=>6-get.value(card), - log:false, - precontent:function(){ + position: "h", + filterTarget: lib.filter.targetEnabled, + selectCard: 1, + check: (card) => 6 - get.value(card), + log: false, + precontent: function () { delete event.result.skill; }, }, - add:{ - trigger:{global:'useCard2'}, - charlotte:true, - direct:true, - filter:function(event,player){ - var evt=event.getParent(2); - if(evt.name!='heqia'||evt.player!=player||!event.targets||evt.num<=event.targets.length) return false; - var card=event.card,info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,event.player,current); - })){ + add: { + trigger: { global: "useCard2" }, + charlotte: true, + direct: true, + filter: function (event, player) { + var evt = event.getParent(2); + if ( + evt.name != "heqia" || + evt.player != player || + !event.targets || + evt.num <= event.targets.length + ) + return false; + var card = event.card, + info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, event.player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var num=trigger.getParent(2).num-trigger.targets.length; - var prompt2='是否为'+get.translation(trigger.card)+'增加至多'+get.cnNumber(num)+'个目标?' - trigger.player.chooseTarget(prompt2,[1,num],function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + var num = trigger.getParent(2).num - trigger.targets.length; + var prompt2 = + "是否为" + + get.translation(trigger.card) + + "增加至多" + + get.cnNumber(num) + + "个目标?"; + trigger.player + .chooseTarget(prompt2, [1, num], function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { trigger.player.line(result.targets); - game.log(result.targets,'也成为了',trigger.card,'的目标') + game.log(result.targets, "也成为了", trigger.card, "的目标"); trigger.targets.addArray(result.targets); } }, }, }, }, - yinyi:{ - audio:2, - trigger:{player:'damageBegin1'}, - forced:true, - usable:1, - filter:function(event,player){ - return event.source&&event.source.hp!=player.hp&&!event.hasNature('linked')&&event.source.countCards('h')!=player.countCards('h'); + yinyi: { + audio: 2, + trigger: { player: "damageBegin1" }, + forced: true, + usable: 1, + filter: function (event, player) { + return ( + event.source && + event.source.hp != player.hp && + !event.hasNature("linked") && + event.source.countCards("h") != player.countCards("h") + ); }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')){ - if(player.hp==target.hp||lib.linked.includes(get.nature(card))) return; - var cards=[card]; - if(card.cards&&card.cards.length) cards.addArray(card.cards); - if(ui.selected.cards.length) cards.addArray(ui.selected.cards); - if(player.countCards('h',function(card){ - return !cards.includes(card); - })==target.countCards('h')) return; - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) { + if (player.hp == target.hp || lib.linked.includes(get.nature(card))) return; + var cards = [card]; + if (card.cards && card.cards.length) cards.addArray(card.cards); + if (ui.selected.cards.length) cards.addArray(ui.selected.cards); + if ( + player.countCards("h", function (card) { + return !cards.includes(card); + }) == target.countCards("h") + ) + return; + return "zeroplayertarget"; } }, }, }, }, //韩猛 - jieliang:{ - trigger:{global:'phaseDrawBegin2'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&!event.numFixed&&event.num>1&&player.countCards('he')>0; + jieliang: { + trigger: { global: "phaseDrawBegin2" }, + direct: true, + filter: function (event, player) { + return ( + event.player != player && + !event.numFixed && + event.num > 1 && + player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - event.target=trigger.player; - player.chooseToDiscard(get.prompt2('jieliang',event.target),'he').set('goon',get.attitude(player,trigger.player)<-2).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 7-get.value(card); - }).logSkill=['jieliang',event.target]; - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + event.target = trigger.player; + player + .chooseToDiscard(get.prompt2("jieliang", event.target), "he") + .set("goon", get.attitude(player, trigger.player) < -2) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 7 - get.value(card); + }).logSkill = ["jieliang", event.target]; + "step 1"; + if (result.bool) { trigger.num--; - if(get.mode()!='identity'||player.identity!='nei') player.addExpose(0.15); - target.addMark('jieliang_less',1,false); - target.addTempSkill('jieliang_less'); - player.addTempSkill('jieliang_gain'); + if (get.mode() != "identity" || player.identity != "nei") player.addExpose(0.15); + target.addMark("jieliang_less", 1, false); + target.addTempSkill("jieliang_less"); + player.addTempSkill("jieliang_gain"); } }, - subSkill:{ - less:{ - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('jieliang_less'); + subSkill: { + less: { + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("jieliang_less"); }, }, - onremove:true, - intro:{content:'手牌上限-#'}, + onremove: true, + intro: { content: "手牌上限-#" }, }, - gain:{ - trigger:{global:'loseAfter'}, - charlotte:true, - direct:true, - filter:function(event,player){ - return event.type=='discard'&&event.player==_status.currentPhase&& - event.getParent(3).name=='phaseDiscard'&&event.cards2.filterInD('d').length>0; + gain: { + trigger: { global: "loseAfter" }, + charlotte: true, + direct: true, + filter: function (event, player) { + return ( + event.type == "discard" && + event.player == _status.currentPhase && + event.getParent(3).name == "phaseDiscard" && + event.cards2.filterInD("d").length > 0 + ); }, - content:function(){ - 'step 0' - player.chooseButton(['截粮:是否获得一张牌?',trigger.cards2.filterInD('d')]).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); - 'step 1' - if(result.bool){ - player.logSkill('jieliang',trigger.player); - player.gain(result.links,'gain2'); + content: function () { + "step 0"; + player + .chooseButton(["截粮:是否获得一张牌?", trigger.cards2.filterInD("d")]) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); + "step 1"; + if (result.bool) { + player.logSkill("jieliang", trigger.player); + player.gain(result.links, "gain2"); } }, }, }, }, - quanjiu:{ - audio:2, - mod:{ - aiOrder:function(player,card,num){ - if((card.name=='jiu'||card.name=='xujiu')&&get.name(card)=='sha') return num+0.5; + quanjiu: { + audio: 2, + mod: { + aiOrder: function (player, card, num) { + if ((card.name == "jiu" || card.name == "xujiu") && get.name(card) == "sha") + return num + 0.5; }, - cardname:function(card,player,name){ - if(card.name=='jiu'||card.name=='xujiu') return 'sha'; + cardname: function (card, player, name) { + if (card.name == "jiu" || card.name == "xujiu") return "sha"; }, }, - trigger:{player:'useCard1'}, - forced:true, - filter:function(event,player){ - return event.addCount!==false&&event.card.isCard&&event.card.name=='sha'&& - event.cards.length==1&&(event.cards[0].name=='jiu'||event.cards[0].name=='xujiu'); + trigger: { player: "useCard1" }, + forced: true, + filter: function (event, player) { + return ( + event.addCount !== false && + event.card.isCard && + event.card.name == "sha" && + event.cards.length == 1 && + (event.cards[0].name == "jiu" || event.cards[0].name == "xujiu") + ); }, - content:function(){ - trigger.addCount=false; + content: function () { + trigger.addCount = false; player.getStat().card.sha--; }, }, //辛评 - fuyuan:{ - audio:2, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - var target=_status.currentPhase; - return target&&target!=player&&target.isIn(); + fuyuan: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + var target = _status.currentPhase; + return target && target != player && target.isIn(); }, - logTarget:function(event,player){ - var target=_status.currentPhase; - return target.countCards('h')0; + check: function (event, player) { + var target = lib.skill.fuyuan.logTarget(event, player); + return get.attitude(player, target) > 0; }, - prompt:'是否发动【辅袁】?', - prompt2:function(event,player){ - var target=lib.skill.fuyuan.logTarget(event,player); - return '令'+get.translation(target)+(target==player?'(你)':'')+'摸一张牌'; + prompt: "是否发动【辅袁】?", + prompt2: function (event, player) { + var target = lib.skill.fuyuan.logTarget(event, player); + return "令" + get.translation(target) + (target == player ? "(你)" : "") + "摸一张牌"; }, - content:function(){ - lib.skill.fuyuan.logTarget(trigger,player).draw(); + content: function () { + lib.skill.fuyuan.logTarget(trigger, player).draw(); }, }, - zhongjie:{ - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'gray', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('zhongjie'),lib.filter.notMe).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ + zhongjie: { + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "gray", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("zhongjie"), lib.filter.notMe) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { //player.awakenSkill('zhongjie'); - var target=result.targets[0]; - player.logSkill('zhongjie',target); + var target = result.targets[0]; + player.logSkill("zhongjie", target); target.gainMaxHp(); target.recover(); target.draw(); @@ -4181,3867 +5467,4707 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //张宁 - tianze:{ - audio:2, - trigger:{global:'useCardAfter'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.isIn()&&get.color(event.card)=='black'&&event.player.hasHistory('lose',function(evt){ - return evt&&evt.hs.length&&evt.getParent()==event; - })&&event.player.isPhaseUsing()&&!player.hasSkill('tianze_block'); + tianze: { + audio: 2, + trigger: { global: "useCardAfter" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.isIn() && + get.color(event.card) == "black" && + event.player.hasHistory("lose", function (evt) { + return evt && evt.hs.length && evt.getParent() == event; + }) && + event.player.isPhaseUsing() && + !player.hasSkill("tianze_block") + ); }, - content:function(){ - 'step 0' - player.addTempSkill('tianze_block'); - if(!player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.color(card,player)=='black'; - },'he')) event.finish(); - else player.chooseToDiscard('he',function(card,player){ - return get.color(card,player)=='black'; - },get.prompt('tianze',trigger.player),'弃置一张黑色牌并对其造成1点伤害').set('ai',function(card){ - if(!_status.event.goon) return 0; - return 8-get.value(card); - }).set('goon',get.damageEffect(trigger.player,player,player)>0).logSkill=['tianze',trigger.player]; - 'step 1' - if(result.bool){ - if(get.mode()!='identity'||player.identity!='nei') player.addExpose(0.2); + content: function () { + "step 0"; + player.addTempSkill("tianze_block"); + if ( + !player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.color(card, player) == "black"; + }, "he") + ) + event.finish(); + else + player + .chooseToDiscard( + "he", + function (card, player) { + return get.color(card, player) == "black"; + }, + get.prompt("tianze", trigger.player), + "弃置一张黑色牌并对其造成1点伤害" + ) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 8 - get.value(card); + }) + .set("goon", get.damageEffect(trigger.player, player, player) > 0).logSkill = [ + "tianze", + trigger.player, + ]; + "step 1"; + if (result.bool) { + if (get.mode() != "identity" || player.identity != "nei") player.addExpose(0.2); trigger.player.damage(); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; game.delayx(); }, - group:'tianze_draw', - subSkill:{ - block:{charlotte:true}, - draw:{ - trigger:{global:'judgeEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.player!=player&&event.result&&event.result.color=='black'; + group: "tianze_draw", + subSkill: { + block: { charlotte: true }, + draw: { + trigger: { global: "judgeEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + return event.player != player && event.result && event.result.color == "black"; }, - content:function(){ + content: function () { player.draw(); }, }, }, }, - difa:{ - trigger:{player:'gainAfter'}, - filter:function(event,player){ - if(player!=_status.currentPhase||event.getParent().name!='draw') return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of event.cards){ - if(hs.includes(i)&&get.color(i,player)=='red'&&lib.filter.cardDiscardable(i,player,'difa')) return true; + difa: { + trigger: { player: "gainAfter" }, + filter: function (event, player) { + if (player != _status.currentPhase || event.getParent().name != "draw") return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of event.cards) { + if ( + hs.includes(i) && + get.color(i, player) == "red" && + lib.filter.cardDiscardable(i, player, "difa") + ) + return true; } return false; }, - usable:1, - check:function(event,player){ - var hs=player.getCards('h'),cards=event.cards.filter(function(i){ - return (hs.includes(i)&&get.color(i,player)=='red'&&lib.filter.cardDiscardable(i,player,'difa')); - }); - var value=get.value(hs,player); - return Array.from(ui.cardPile.childNodes).some(function(card){ - return get.type2(card,false)=='trick'&&get.value(card,player)>value; + usable: 1, + check: function (event, player) { + var hs = player.getCards("h"), + cards = event.cards.filter(function (i) { + return ( + hs.includes(i) && + get.color(i, player) == "red" && + lib.filter.cardDiscardable(i, player, "difa") + ); + }); + var value = get.value(hs, player); + return Array.from(ui.cardPile.childNodes).some(function (card) { + return get.type2(card, false) == "trick" && get.value(card, player) > value; }); }, - content:function(){ - 'step 0' - var hs=player.getCards('h'),cards=trigger.cards.filter(function(i){ - return (hs.includes(i)&&get.color(i,player)=='red'&&lib.filter.cardDiscardable(i,player,'difa')); - }); - if(!cards.length) event.finish(); - else{ - event.cards=cards; + content: function () { + "step 0"; + var hs = player.getCards("h"), + cards = trigger.cards.filter(function (i) { + return ( + hs.includes(i) && + get.color(i, player) == "red" && + lib.filter.cardDiscardable(i, player, "difa") + ); + }); + if (!cards.length) event.finish(); + else { + event.cards = cards; player.discard(cards); } - 'step 1' - var list=lib.inpile.filter(function(i){ - return get.type2(i,false)=='trick'; + "step 1"; + var list = lib.inpile.filter(function (i) { + return get.type2(i, false) == "trick"; }); - if(!list.length) event.finish(); - else player.chooseButton(['选择获得一种锦囊牌',[list.map((i)=>['锦囊','',i]),'vcard']],true).set('ai',function(button){ - var card={name:button.link[2]}; - if(!_status.event.list.includes(card.name)) return 0; - return _status.event.player.getUseValue(card); - }).set('list',Array.from(ui.cardPile.childNodes).filter(function(card){ - return get.type2(card,false)=='trick'; - }).map(function(card){ - return card.name; - }).reduce(function(list,name){ - if(!list.includes(name)) list.add(name); - return list; - },[])); - 'step 2' - var card=get.cardPile(function(i){ - return i.name==result.links[0][2]&&!event.cards.includes(i); + if (!list.length) event.finish(); + else + player + .chooseButton( + ["选择获得一种锦囊牌", [list.map((i) => ["锦囊", "", i]), "vcard"]], + true + ) + .set("ai", function (button) { + var card = { name: button.link[2] }; + if (!_status.event.list.includes(card.name)) return 0; + return _status.event.player.getUseValue(card); + }) + .set( + "list", + Array.from(ui.cardPile.childNodes) + .filter(function (card) { + return get.type2(card, false) == "trick"; + }) + .map(function (card) { + return card.name; + }) + .reduce(function (list, name) { + if (!list.includes(name)) list.add(name); + return list; + }, []) + ); + "step 2"; + var card = get.cardPile(function (i) { + return i.name == result.links[0][2] && !event.cards.includes(i); }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, }, //童渊 - chaofeng:{ - audio:2, - trigger:{source:'damageBegin1'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0&&player.isPhaseUsing()&&!player.hasSkill('chaofeng2'); + chaofeng: { + audio: 2, + trigger: { source: "damageBegin1" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && player.isPhaseUsing() && !player.hasSkill("chaofeng2") + ); }, - content:function(){ - 'step 0' - var str='弃置一张牌并摸一张牌',color,type; - if(trigger.card){ - type=get.type2(trigger.card,false); - color=get.color(trigger.card,false); - if(color!='none') str+=';若弃置'+get.translation(color)+'牌则改为摸两张牌'; - if(type) str+=';若弃置类型为'+get.translation(type)+'的牌则伤害+1'; + content: function () { + "step 0"; + var str = "弃置一张手牌并摸一张牌", + color, + type; + if (trigger.card) { + type = get.type2(trigger.card, false); + color = get.color(trigger.card, false); + if (color != "none") str += ";若弃置" + get.translation(color) + "牌则改为摸两张牌"; + if (type) str += ";若弃置类型为" + get.translation(type) + "的牌则伤害+1"; } - var next=player.chooseToDiscard('he',get.prompt('chaofeng',trigger.player),str); - next.set('ai',function(card){ - var player=_status.event.player,att=_status.event.att; - var val=4.2-get.value(card); - if(get.color(card)==_status.event.color) val+=3; - if(get.type2(card)==_status.event.type){ - if(att<0) val+=4; - else if(att===0) val+=2; - else val=0; + var next = player.chooseToDiscard("h", get.prompt("chaofeng", trigger.player), str); + next.set("ai", function (card) { + var player = _status.event.player, + att = _status.event.att; + var val = 4.2 - get.value(card); + if (get.color(card) == _status.event.color) val += 3; + if (get.type2(card) == _status.event.type) { + if (att < 0) val += 4; + else if (att === 0) val += 2; + else val = 0; } return val; }); - next.set('att',get.attitude(player,trigger.player)); - next.logSkill=['chaofeng',trigger.player]; - if(color!='none'){ - event.color=color; - next.set('color',color); + next.set("att", get.attitude(player, trigger.player)); + next.logSkill = ["chaofeng", trigger.player]; + if (color != "none") { + event.color = color; + next.set("color", color); } - if(type){ - event.type=type; - next.set('type',type); + if (type) { + event.type = type; + next.set("type", type); } - 'step 1' - if(result.bool){ - player.addTempSkill('chaofeng2','phaseUseEnd'); - var card=result.cards[0]; - player.draw((event.color&&get.color(card,card.original=='h'?player:false)==event.color)?2:1); - if(event.type&&get.type2(card,card.original=='h'?player:false)==event.type) trigger.num++; + "step 1"; + if (result.bool) { + player.addTempSkill("chaofeng2", "phaseUseEnd"); + var card = result.cards[0]; + player.draw( + event.color && + get.color(card, card.original == "h" ? player : false) == event.color + ? 2 + : 1 + ); + if ( + event.type && + get.type2(card, card.original == "h" ? player : false) == event.type + ) + trigger.num++; } }, }, - chaofeng2:{}, - chuanshu:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','die']}, - direct:true, - limited:true, - forceDie:true, - filter:function(event,player){ - return player.isDamaged()&&(event.name=='die'||player.isIn()); + chaofeng2: {}, + chuanshu: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "die"] }, + direct: true, + limited: true, + forceDie: true, + filter: function (event, player) { + return player.isDamaged() && (event.name == "die" || player.isIn()); }, - skillAnimation:true, - animationColor:'gray', - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('chuanshu'),'令一名其他角色获得〖朝凤〗').set('ai',function(target){ - return get.attitude(_status.event.player,target) - }).set('forceDie',true); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.awakenSkill('chuanshu'); - player.logSkill('chuanshu',target); - target.addSkills('chaofeng'); - if(player.isDead()) event.finish(); - } - else event.finish(); - 'step 2' + skillAnimation: true, + animationColor: "gray", + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, get.prompt("chuanshu"), "令一名其他角色获得〖朝凤〗") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("forceDie", true); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.awakenSkill("chuanshu"); + player.logSkill("chuanshu", target); + target.addSkills("chaofeng"); + if (player.isDead()) event.finish(); + } else event.finish(); + "step 2"; player.addSkills(lib.skill.chuanshu.derivation); }, - derivation:['ollongdan','drlt_congjian','chuanyun'], + derivation: ["ollongdan", "drlt_congjian", "chuanyun"], }, - longdan_tongyuan:{audio:true}, - ocongjian_tongyuan:{audio:true}, - chuanyun:{ - audio:true, - trigger:{player:'useCardToPlayered'}, - shaRelated:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.countCards('e')>0; + longdan_tongyuan: { audio: true }, + ocongjian_tongyuan: { audio: true }, + chuanyun: { + audio: true, + trigger: { player: "useCardToPlayered" }, + shaRelated: true, + filter: function (event, player) { + return event.card.name == "sha" && event.target.countCards("e") > 0; }, - logTarget:'target', - content:function(){ - var target=trigger.target;card=target.getCards('e').randomGet(); - if(card) target.discard(card); + logTarget: "target", + content: function () { + var target = trigger.target; + card = target.getCards("e").randomGet(); + if (card) target.discard(card); }, }, //南华老仙 - jinghe:{ - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('jinghe_clear'); + jinghe: { + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("jinghe_clear"); }, - selectCard:function(){ - if(ui.selected.targets.length) return [ui.selected.targets.length,4]; - return [1,4]; + selectCard: function () { + if (ui.selected.targets.length) return [ui.selected.targets.length, 4]; + return [1, 4]; }, - selectTarget:function(){ + selectTarget: function () { return ui.selected.cards.length; }, - filterTarget:true, - filterCard:function(card){ - if(ui.selected.cards.length){ - var name=get.name(card); - for(var i of ui.selected.cards){ - if(get.name(i)==name) return false; + filterTarget: true, + filterCard: function (card) { + if (ui.selected.cards.length) { + var name = get.name(card); + for (var i of ui.selected.cards) { + if (get.name(i) == name) return false; } } return true; }, - check:function(card){ - var player=_status.event.player; - if(game.countPlayer(function(current){ - return get.attitude(player,current)>0; - })>ui.selected.cards.length) return 1; + check: function (card) { + var player = _status.event.player; + if ( + game.countPlayer(function (current) { + return get.attitude(player, current) > 0; + }) > ui.selected.cards.length + ) + return 1; return 0; }, - position:'h', - complexCard:true, - discard:false, - lose:false, - delay:false, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - player.showCards(cards,get.translation(player)+'发动了【经合】'); - event.skills=lib.skill.jinghe.derivation.randomGets(4); - player.addTempSkill('jinghe_clear',{player:'phaseBegin'}); + position: "h", + complexCard: true, + discard: false, + lose: false, + delay: false, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + player.showCards(cards, get.translation(player) + "发动了【经合】"); + event.skills = lib.skill.jinghe.derivation.randomGets(4); + player.addTempSkill("jinghe_clear", { player: "phaseBegin" }); event.targets.sortBySeat(); - event.num=0; - 'step 1' - event.target=targets[num]; + event.num = 0; + "step 1"; + event.target = targets[num]; event.num++; - event.target.chooseControl(event.skills,'cancel2').set('choiceList',event.skills.map(function(i){ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','选择获得一个技能'); - 'step 2' - var skill=result.control; - if(skill!='cancel2'){ + event.target + .chooseControl(event.skills, "cancel2") + .set( + "choiceList", + event.skills.map(function (i) { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "选择获得一个技能"); + "step 2"; + var skill = result.control; + if (skill != "cancel2") { event.skills.remove(skill); - target.addAdditionalSkills('jinghe_'+player.playerid,skill); + target.addAdditionalSkills("jinghe_" + player.playerid, skill); target.popup(skill); } - if(event.num1?'各':'')+'摸一张牌'); + if (event.list1.length) + choices.push( + "令" + + get.translation(event.list1) + + (event.list1.length > 1 ? "各" : "") + + "摸一张牌" + ); else event.addIndex++; event.list2.sortBySeat(); - if(event.list2.length) choices.push('令'+get.translation(event.list2)+(event.list2.length>1?'各':'')+'弃置一张手牌'); - player.chooseControl('cancel2').set('choiceList',choices).set('prompt',get.prompt('gongxiu')).set('',function(){ - var evt=_status.event.getParent(); - if(evt.list2.filter(function(current){ - return get.attitude(player,current)<=0&&!current.hasSkillTag('noh'); - }).length-evt.list1.length>1) return 1-evt.addIndex; - return 0; - }); - 'step 1' - if(result.control!='cancel2'){ - if(result.index+event.addIndex==0){ - player.logSkill('gongxiu',event.list1); + if (event.list2.length) + choices.push( + "令" + + get.translation(event.list2) + + (event.list2.length > 1 ? "各" : "") + + "弃置一张手牌" + ); + player + .chooseControl("cancel2") + .set("choiceList", choices) + .set("prompt", get.prompt("gongxiu")) + .set("", function () { + var evt = _status.event.getParent(); + if ( + evt.list2.filter(function (current) { + return get.attitude(player, current) <= 0 && !current.hasSkillTag("noh"); + }).length - + evt.list1.length > + 1 + ) + return 1 - evt.addIndex; + return 0; + }); + "step 1"; + if (result.control != "cancel2") { + if (result.index + event.addIndex == 0) { + player.logSkill("gongxiu", event.list1); game.asyncDraw(event.list1); - } - else{ - player.logSkill('gongxiu',event.list2); - for(var i of event.list2) i.chooseToDiscard('h',true); + } else { + player.logSkill("gongxiu", event.list2); + for (var i of event.list2) i.chooseToDiscard("h", true); event.finish(); } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; game.delayx(); }, - }, - nhyinbing:{ - trigger:{source:'damageBefore'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; + ai: { + combo: "jinghe", }, - content:function(){ + }, + nhyinbing: { + trigger: { source: "damageBefore" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha"; + }, + content: function () { trigger.cancel(); trigger.player.loseHp(trigger.num); }, - group:'nhyinbing_draw', - subSkill:{ - draw:{ - trigger:{global:'loseHpAfter'}, - forced:true, - filter:function(event,player){ - return player!=event.player; + group: "nhyinbing_draw", + subSkill: { + draw: { + trigger: { global: "loseHpAfter" }, + forced: true, + filter: function (event, player) { + return player != event.player; }, - content:function(){ + content: function () { player.draw(); }, }, }, - ai:{ - jueqing:true, - } - }, - nhhuoqi:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + ai: { + jueqing: true, }, - position:'he', - filterCard:true, - filterTarget:function(card,player,target){ + }, + nhhuoqi: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + position: "he", + filterCard: true, + filterTarget: function (card, player, target) { return target.isMinHp(); }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - content:function(){ + content: function () { target.recover(); target.draw(); }, - ai:{ - order:1, - tag:{ - draw:1, - recover:1, + ai: { + order: 1, + tag: { + draw: 1, + recover: 1, }, - result:{ - target:function(player,target){ - if(target.isDamaged()) return 3; - if(ui.selected.cards.length) return 0; + result: { + target: function (player, target) { + if (target.isDamaged()) return 3; + if (ui.selected.cards.length) return 0; return 1; }, }, }, }, - nhguizhu:{ - trigger:{global:'dying'}, - usable:1, - logTarget:'player', - frequent:true, - content:function(){ + nhguizhu: { + trigger: { global: "dying" }, + usable: 1, + logTarget: "player", + frequent: true, + content: function () { player.draw(2); }, }, - nhxianshou:{ - enable:'phaseUse', - usable:1, - filterTarget:true, - content:function(){ - target.draw(target.isHealthy()?2:1); + nhxianshou: { + enable: "phaseUse", + usable: 1, + filterTarget: true, + content: function () { + target.draw(target.isHealthy() ? 2 : 1); }, - ai:{ - order:1, - tag:{ - draw:1, + ai: { + order: 1, + tag: { + draw: 1, }, - result:{ - target:function(player,target){ - return target.isHealthy()?2:0.5; + result: { + target: function (player, target) { + return target.isHealthy() ? 2 : 0.5; }, }, }, }, - nhlundao:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&player!=event.source&&player.countCards('h')!=event.source.countCards('h'); + nhlundao: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.source && + player != event.source && + player.countCards("h") != event.source.countCards("h") + ); }, - logTarget:'source', - check:function(event,player){ - return (player.countCards('h')0; + logTarget: "source", + check: function (event, player) { + return ( + player.countCards("h") < event.source.countCards("h") || + get.effect(event.source, { name: "guohe_copy2" }, player, player) > 0 + ); }, - content:function(){ - if(player.countCards('h')>trigger.source.countCards('h')) player.draw(); - else player.discardPlayerCard(trigger.source,'he',true); + content: function () { + if (player.countCards("h") > trigger.source.countCards("h")) player.draw(); + else player.discardPlayerCard(trigger.source, "he", true); }, }, - nhguanyue:{ - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - content:function(){ - 'step 0' - var cards=get.cards(2); - player.chooseButton(['观月:选择获得一张牌',cards.slice(0)],true).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop(),ui.cardPile.firstChild); - } - 'step 1' - if(result.bool){ - player.gain(result.links,'gain2'); - } - }, - }, - nhyanzheng:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; - }, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('nhyanzheng')).set('goon',function(){ - var num=player.countCards('h')-1; - return game.countPlayer(function(current){ - return get.damageEffect(current,player,player)>0; - })>=Math.min(3,num) - }()).set('ai',function(card){ - if(_status.event.goon) return Math.max(1,get.value(card)); - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('nhyanzheng'); - var cards=player.getCards('h',function(card){ - return card!=result.cards[0]&&lib.filter.cardDiscardable(card,player,'nhyanzheng'); + nhguanyue: { + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + content: function () { + "step 0"; + var cards = get.cards(2); + player + .chooseButton(["观月:选择获得一张牌", cards.slice(0)], true) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); }); - if(cards.length){ - player.discard(cards); - event.num=cards.length; - } - else event.finish(); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop(), ui.cardPile.firstChild); } - else event.finish(); - 'step 2' - num=Math.min(num,game.countPlayer()); - player.chooseTarget([1,num],true,'对'+(num>1?'至多':'')+get.cnNumber(num)+'名角色造成1点伤害').set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); - for(var i of targets) i.damage(); + "step 1"; + if (result.bool) { + player.gain(result.links, "gain2"); + } + }, + }, + nhyanzheng: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + content: function () { + "step 0"; + player + .chooseCard("h", get.prompt("nhyanzheng")) + .set( + "goon", + (function () { + var num = player.countCards("h") - 1; + return ( + game.countPlayer(function (current) { + return get.damageEffect(current, player, player) > 0; + }) >= Math.min(3, num) + ); + })() + ) + .set("ai", function (card) { + if (_status.event.goon) return Math.max(1, get.value(card)); + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("nhyanzheng"); + var cards = player.getCards("h", function (card) { + return ( + card != result.cards[0] && + lib.filter.cardDiscardable(card, player, "nhyanzheng") + ); + }); + if (cards.length) { + player.discard(cards); + event.num = cards.length; + } else event.finish(); + } else event.finish(); + "step 2"; + num = Math.min(num, game.countPlayer()); + player + .chooseTarget( + [1, num], + true, + "对" + (num > 1 ? "至多" : "") + get.cnNumber(num) + "名角色造成1点伤害" + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); + for (var i of targets) i.damage(); } }, }, //樊稠 - xinxingluan:{ - audio:'xinfu_xingluan', - usable:1, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ + xinxingluan: { + audio: "xinfu_xingluan", + usable: 1, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { return player.isPhaseUsing(); }, - async cost(event, trigger, player){ + async cost(event, trigger, player) { const choiceList = [ - '观看牌堆中两张点数为6的牌并获得其中一张', - '令一名其他角色弃置一张点数为6的牌或交给你一张牌', - '获得场上一张点数为6的牌' - ], choices = ['选项一']; - if (game.hasPlayer(current => (current != player && current.countCards('he') > 0))) { - choices.push('选项二'); + "观看牌堆中两张点数为6的牌并获得其中一张", + "令一名其他角色弃置一张点数为6的牌或交给你一张牌", + "获得场上一张点数为6的牌", + ], + choices = ["选项一"]; + if (game.hasPlayer((current) => current != player && current.countCards("he") > 0)) { + choices.push("选项二"); + } else { + choiceList[1] = `${choiceList[1]}`; } - else { - choiceList[1] = `${ choiceList[1] }`; + if ( + game.hasPlayer((current) => { + return current.hasCard(function (card) { + return get.number(card) == 6 && lib.filter.canBeGained(card, current, player); + }, "ej"); + }) + ) { + choices.push("选项三"); + } else { + choiceList[2] = `${choiceList[2]}`; } - if (game.hasPlayer(current => { - return current.hasCard(function(card){ - return get.number(card)==6&&lib.filter.canBeGained(card,current,player); - },'ej'); - })) { - choices.push('选项三'); - } - else { - choiceList[2] = `${ choiceList[2] }`; - } - const result = await player.chooseControl(choices, 'cancel2') - .set('choiceList',choiceList).set('prompt',get.prompt('xinxingluan')) - .set('ai',function(){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - if(current==player) return false; - var att=-get.sgn(get.attitude(player,current)-0.1); - return current.hasCard(function(card){ - return get.number(card)==6&&lib.filter.canBeGained(card,current,player)&&get.sgn(get.useful(card,current))==att; - },'ej'); - })) return '选项三'; - if(game.hasPlayer(function(target){ - if(target==player) return false; - var att=get.attitude(player,target); - return att<0&&target.countCards('he')>0&&!target.hasCard(function(card){ - return get.value(card,target)<=0; - },'he'); - })) return '选项二'; - return '选项一'; - }).forResult(); - if (result.control !== 'cancel2') { - const results = {bool: true, cost_data: {index: choices.indexOf(result.control)}}; - if(results.cost_data.index === 1) { - const {targets} = await player.chooseTarget('令一名其他角色弃置一张点数为6的牌,否则交给你一张牌',true,function(card,player,current){ - return current!=player&¤t.countCards('he')>0; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att>=0) return 0; - if(!target.hasCard(function(card){ - return get.value(card,target)<=0; - },'he')) return -att/Math.sqrt(target.countCards('he')); - return 0; - }).forResult(); + const result = await player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("xinxingluan")) + .set("ai", function () { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + if (current == player) return false; + var att = -get.sgn(get.attitude(player, current) - 0.1); + return current.hasCard(function (card) { + return ( + get.number(card) == 6 && + lib.filter.canBeGained(card, current, player) && + get.sgn(get.useful(card, current)) == att + ); + }, "ej"); + }) + ) + return "选项三"; + if ( + game.hasPlayer(function (target) { + if (target == player) return false; + var att = get.attitude(player, target); + return ( + att < 0 && + target.countCards("he") > 0 && + !target.hasCard(function (card) { + return get.value(card, target) <= 0; + }, "he") + ); + }) + ) + return "选项二"; + return "选项一"; + }) + .forResult(); + if (result.control !== "cancel2") { + const results = { bool: true, cost_data: { index: choices.indexOf(result.control) } }; + if (results.cost_data.index === 1) { + const { targets } = await player + .chooseTarget( + "令一名其他角色弃置一张点数为6的牌,否则交给你一张牌", + true, + function (card, player, current) { + return current != player && current.countCards("he") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + !target.hasCard(function (card) { + return get.value(card, target) <= 0; + }, "he") + ) + return -att / Math.sqrt(target.countCards("he")); + return 0; + }) + .forResult(); results.targets = targets; - } - else if(results.cost_data.index === 2){ - const {targets} = await player.chooseTarget('获得一名角色装备区或判定区内点数为6的牌',true,function(card,player,current){ - return current.hasCard(function(card){ - return get.number(card)==6&&lib.filter.canBeGained(card,current,player); - },'ej'); - }).set('ai',function(target){ - var player=_status.event.player,att=-get.sgn(get.attitude(player,target)-0.1),max=0,ej=target.getCards('ej',function(card){ - return get.number(card)==6&&lib.filter.canBeGained(card,target,player); - }); - for(var i of ej){ - var num=get.useful(i,target)*att; - if(num>max) max=num; - return max; - } - }).forResult(); + } else if (results.cost_data.index === 2) { + const { targets } = await player + .chooseTarget( + "获得一名角色装备区或判定区内点数为6的牌", + true, + function (card, player, current) { + return current.hasCard(function (card) { + return ( + get.number(card) == 6 && + lib.filter.canBeGained(card, current, player) + ); + }, "ej"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = -get.sgn(get.attitude(player, target) - 0.1), + max = 0, + ej = target.getCards("ej", function (card) { + return ( + get.number(card) == 6 && + lib.filter.canBeGained(card, target, player) + ); + }); + for (var i of ej) { + var num = get.useful(i, target) * att; + if (num > max) max = num; + return max; + } + }) + .forResult(); results.targets = targets; } event.result = results; } }, - content:function(){ - 'step 0' + content: function () { + "step 0"; var result = event.cost_data; - if(result.index === 1) event.goto(4); - else if(result.index === 2) event.goto(3); - 'step 1' - var cards=[]; - while(cards.length<2){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&get.number(card)==6; + if (result.index === 1) event.goto(4); + else if (result.index === 2) event.goto(3); + "step 1"; + var cards = []; + while (cards.length < 2) { + var card = get.cardPile2(function (card) { + return !cards.includes(card) && get.number(card) == 6; }); - if(!card) break; + if (!card) break; cards.push(card); } - if(!cards.length){ + if (!cards.length) { player.draw(6); event.finish(); - } - else if(cards.length==1){ - event._result={bool:true,links:cards}; - } - else player.chooseButton(['兴乱:选择获得其中一张',cards],true).set('ai',function(button){ - return get.value(button.link,_status.event.player); - }); - 'step 2' - if(result.bool){ - player.gain(result.links,'gain2'); + } else if (cards.length == 1) { + event._result = { bool: true, links: cards }; + } else + player + .chooseButton(["兴乱:选择获得其中一张", cards], true) + .set("ai", function (button) { + return get.value(button.link, _status.event.player); + }); + "step 2"; + if (result.bool) { + player.gain(result.links, "gain2"); } event.finish(); - 'step 3' - var target=targets[0]; - player.gainPlayerCard(target,'ej',true).set('filterButton',function(button){ - return get.number(button.link)==6; + "step 3"; + var target = targets[0]; + player.gainPlayerCard(target, "ej", true).set("filterButton", function (button) { + return get.number(button.link) == 6; }); event.finish(); - 'step 4' - var target=targets[0]; - event.target=target; - target.chooseToDiscard('he','弃置一张点数为6的牌,否则交给'+get.translation(player)+'一张牌',function(card){ - return get.number(card)==6; - }).ai=(card)=>(8-get.value(card)); - 'step 5' - if(!result.bool){ - target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); - } - else event.finish(); - 'step 6' - if(result.bool) target.give(result.cards,player,'giveAuto'); + "step 4"; + var target = targets[0]; + event.target = target; + target.chooseToDiscard( + "he", + "弃置一张点数为6的牌,否则交给" + get.translation(player) + "一张牌", + function (card) { + return get.number(card) == 6; + } + ).ai = (card) => 8 - get.value(card); + "step 5"; + if (!result.bool) { + target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); + } else event.finish(); + "step 6"; + if (result.bool) target.give(result.cards, player, "giveAuto"); }, }, - rexingluan:{ - audio:'xinfu_xingluan', - usable:1, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.targets&&event.targets.length==1&&typeof get.number(event.card,false)=='number'&&player.isPhaseUsing(); + rexingluan: { + audio: "xinfu_xingluan", + usable: 1, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + event.targets && + event.targets.length == 1 && + typeof get.number(event.card, false) == "number" && + player.isPhaseUsing() + ); }, - direct:true, - content:function(){ - 'step 0' - var str='',num=get.number(trigger.card,false),nums=get.strNumber(num); - var list=game.filterPlayer(function(current){ - return current.hasCard(function(card){ - return get.number(card)==num&&lib.filter.canBeGained(card,current,player); - },'ej'); + direct: true, + content: function () { + "step 0"; + var str = "", + num = get.number(trigger.card, false), + nums = get.strNumber(num); + var list = game.filterPlayer(function (current) { + return current.hasCard(function (card) { + return get.number(card) == num && lib.filter.canBeGained(card, current, player); + }, "ej"); }); - if(list.length){ - str+='获得一名角色装备区或判定区内的一张点数为'+nums+'的牌,或直接从牌堆中获得一张点数为'+nums+'的牌'; - player.chooseTarget(get.prompt('rexingluan'),str,[0,1],function(card,player,target){ - return _status.event.targets.includes(target); - }).set('targets',list).set('ai',function(target){ - if(!target) return 1; - var player=_status.event.player,num=get.number(_status.event.getTrigger().card,false),att=-get.sgn(get.attitude(player,target)); - if(target.hasCard(function(card){ - return get.number(card)==num&&get.effect(target,card,target,player)<0; - },'j')) return 1.2*Math.abs(get.attitude(player,target)); - if(target.hasCard(function(card){ - return get.number(card)==num&&get.sgn(get.value(card,target)+0.1)==att; - },'e')) return Math.abs(get.attitude(player,target)); - return 0; - }); - } - else{ - player.chooseBool(get.prompt('rexingluan'),'从牌堆中获得一张点数为'+nums+'的牌').ai=()=>true; - } - 'step 1' - if(result.bool){ - if(result.targets&&result.targets.length){ - var target=result.targets[0]; - player.logSkill('rexingluan',target); - player.gainPlayerCard(target,'ej',true).set('num',get.number(trigger.card,false)).set('filterButton',function(button){ - return get.number(button.link)==_status.event.num; + if (list.length) { + str += + "获得一名角色装备区或判定区内的一张点数为" + + nums + + "的牌,或直接从牌堆中获得一张点数为" + + nums + + "的牌"; + player + .chooseTarget( + get.prompt("rexingluan"), + str, + [0, 1], + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("targets", list) + .set("ai", function (target) { + if (!target) return 1; + var player = _status.event.player, + num = get.number(_status.event.getTrigger().card, false), + att = -get.sgn(get.attitude(player, target)); + if ( + target.hasCard(function (card) { + return ( + get.number(card) == num && + get.effect(target, card, target, player) < 0 + ); + }, "j") + ) + return 1.2 * Math.abs(get.attitude(player, target)); + if ( + target.hasCard(function (card) { + return ( + get.number(card) == num && + get.sgn(get.value(card, target) + 0.1) == att + ); + }, "e") + ) + return Math.abs(get.attitude(player, target)); + return 0; }); - } - else{ - player.logSkill('rexingluan'); - var num=get.number(trigger.card,false),card=get.cardPile2(function(i){ - return get.number(i,false)==num; - }); - if(card) player.gain(card,'gain2'); + } else { + player.chooseBool( + get.prompt("rexingluan"), + "从牌堆中获得一张点数为" + nums + "的牌" + ).ai = () => true; + } + "step 1"; + if (result.bool) { + if (result.targets && result.targets.length) { + var target = result.targets[0]; + player.logSkill("rexingluan", target); + player + .gainPlayerCard(target, "ej", true) + .set("num", get.number(trigger.card, false)) + .set("filterButton", function (button) { + return get.number(button.link) == _status.event.num; + }); + } else { + player.logSkill("rexingluan"); + var num = get.number(trigger.card, false), + card = get.cardPile2(function (i) { + return get.number(i, false) == num; + }); + if (card) player.gain(card, "gain2"); } } }, }, //杜夫人 - yise:{ - audio:2, - trigger:{ - global:'gainAfter', - player:'loseAsyncAfter', + yise: { + audio: 2, + trigger: { + global: "gainAfter", + player: "loseAsyncAfter", }, - filter:function(event,player){ - if(event.name=='loseAsync'){ - if(event.type!='gain') return false; + filter: function (event, player) { + if (event.name == "loseAsync") { + if (event.type != "gain") return false; } - var cards=event.getl(player).cards2; - return game.hasPlayer(function(current){ - if(current==player) return false; - var cardsx=event.getg(current); - for(var i of cardsx){ - if(cards.includes(i)){ - if(current.isDamaged()) return true; - return get.color(i,player)=='black'; + var cards = event.getl(player).cards2; + return game.hasPlayer(function (current) { + if (current == player) return false; + var cardsx = event.getg(current); + for (var i of cardsx) { + if (cards.includes(i)) { + if (current.isDamaged()) return true; + return get.color(i, player) == "black"; } } return false; }); }, - direct:true, - content:function(){ - 'step 0' - var cards=trigger.getl(player).cards2; - event.cards=cards; - event.targets=game.filterPlayer(function(current){ - if(current==player) return false; - var cardsx=trigger.getg(current); - for(var i of cardsx){ - if(cards.includes(i)) return true; - } - return false; - }).sortBySeat(); - if(!event.targets.length) event.finish(); - 'step 1' - var target=targets.shift(); - var cardsx=trigger.getg(target); - var goon=false; - for(var i of cardsx){ - if(cards.includes(i)){ - if(target.isDamaged()||get.color(i,player)=='black'){goon=true;break;} + direct: true, + content: function () { + "step 0"; + var cards = trigger.getl(player).cards2; + event.cards = cards; + event.targets = game + .filterPlayer(function (current) { + if (current == player) return false; + var cardsx = trigger.getg(current); + for (var i of cardsx) { + if (cards.includes(i)) return true; + } + return false; + }) + .sortBySeat(); + if (!event.targets.length) event.finish(); + "step 1"; + var target = targets.shift(); + var cardsx = trigger.getg(target); + var goon = false; + for (var i of cardsx) { + if (cards.includes(i)) { + if (target.isDamaged() || get.color(i, player) == "black") { + goon = true; + break; + } } } - if(goon){ - var next=game.createEvent('yise_insert'); - next.player=player; - next.target=target; - next.cards=cardsx; + if (goon) { + var next = game.createEvent("yise_insert"); + next.player = player; + next.target = target; + next.cards = cardsx; next.setContent(lib.skill.yise.contentx); } - if(targets.length>0) event.redo(); + if (targets.length > 0) event.redo(); }, - contentx:function(){ - 'step 0' - for(var i of cards){ - event[get.color(i,player)]=true; - if(event.red&&event.black) break; + contentx: function () { + "step 0"; + for (var i of cards) { + event[get.color(i, player)] = true; + if (event.red && event.black) break; } - if(event.red&&target.isDamaged()){ - player.chooseBool( - get.prompt('yise',target), - '令'+get.translation(target)+'回复1点体力' - ).set('ai',()=>get.recoverEffect(_status.event.getParent().target,_status.event.player,_status.event.player)>0); + if (event.red && target.isDamaged()) { + player + .chooseBool( + get.prompt("yise", target), + "令" + get.translation(target) + "回复1点体力" + ) + .set( + "ai", + () => + get.recoverEffect( + _status.event.getParent().target, + _status.event.player, + _status.event.player + ) > 0 + ); } - 'step 1' - if(event.black||event.red&&result.bool) player.logSkill('yise',target); - if(event.red&&result.bool) target.recover(); - if(event.black){ - target.addMark('yise_damage',1,false); - target.addSkill('yise_damage'); + "step 1"; + if (event.black || (event.red && result.bool)) player.logSkill("yise", target); + if (event.red && result.bool) target.recover(); + if (event.black) { + target.addMark("yise_damage", 1, false); + target.addSkill("yise_damage"); } }, - subSkill:{ - damage:{ - trigger:{player:'damageBegin1'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent().name=='sha'; + subSkill: { + damage: { + trigger: { player: "damageBegin1" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.getParent().name == "sha"; }, - content:function(){ - trigger.num+=player.countMark('yise_damage'); - player.removeSkill('yise_damage'); + content: function () { + trigger.num += player.countMark("yise_damage"); + player.removeSkill("yise_damage"); }, - intro:{ - content:'下一次受到杀的伤害+#', + intro: { + content: "下一次受到杀的伤害+#", }, }, }, }, - shunshi:{ - trigger:{player:['damageEnd','phaseZhunbeiBegin']}, - direct:true, - filter:function(event,player){ - return (event.name!='damage'||player!=_status.currentPhase)&&player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t!=event.source; - }); + shunshi: { + trigger: { player: ["damageEnd", "phaseZhunbeiBegin"] }, + direct: true, + filter: function (event, player) { + return ( + (event.name != "damage" || player != _status.currentPhase) && + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current != event.source; + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('shunshi'), - prompt2:'将一张牌交给一名其他角色,并获得+1效果', - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player&&target!=_status.event.source; + prompt: get.prompt("shunshi"), + prompt2: "将一张牌交给一名其他角色,并获得+1效果", + filterCard: true, + filterTarget: function (card, player, target) { + return target != player && target != _status.event.source; }, - position:'he', - source:trigger.source, - ai1:function(card){ - var player=_status.event.player; - if(player.hasSkill('yise')){ - if(get.color(card,player)=='red'&&game.hasPlayer(function(current){ - return current!=player&¤t!=_status.event.source&¤t.isDamaged()&&get.recoverEffect(current,player,player)>0; - })) return 10-get.value(card); - if(get.color(card,player)=='black') return 4-get.value(card); + position: "he", + source: trigger.source, + ai1: function (card) { + var player = _status.event.player; + if (player.hasSkill("yise")) { + if ( + get.color(card, player) == "red" && + game.hasPlayer(function (current) { + return ( + current != player && + current != _status.event.source && + current.isDamaged() && + get.recoverEffect(current, player, player) > 0 + ); + }) + ) + return 10 - get.value(card); + if (get.color(card, player) == "black") return 4 - get.value(card); } - return 8-get.value(card); + return 8 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player,card=ui.selected.cards[0]; - if(player.hasSkill('yise')){ - if(get.color(card)=='red'&&target.isDamaged()) return 2*get.recoverEffect(target,player,player); - if(get.color(card)=='black') return -get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player, + card = ui.selected.cards[0]; + if (player.hasSkill("yise")) { + if (get.color(card) == "red" && target.isDamaged()) + return 2 * get.recoverEffect(target, player, player); + if (get.color(card) == "black") return -get.attitude(player, target); } - if(get.value(card,target)<0) return -get.attitude(player,target); - if(get.value(card,target)<1) return 0.01*-get.attitude(player,target); - return Math.max(1,get.value(card,target)-get.value(card,player))*get.attitude(player,target); + if (get.value(card, target) < 0) return -get.attitude(player, target); + if (get.value(card, target) < 1) return 0.01 * -get.attitude(player, target); + return ( + Math.max(1, get.value(card, target) - get.value(card, player)) * + get.attitude(player, target) + ); }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('shunshi',target); - player.give(result.cards,target); - player.addMark('shunshi_mark',1,false); - player.addTempSkill('shunshi_mark',{player:'phaseEnd'}); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("shunshi", target); + player.give(result.cards, target); + player.addMark("shunshi_mark", 1, false); + player.addTempSkill("shunshi_mark", { player: "phaseEnd" }); } }, - subSkill:{ - mark:{ - onremove:true, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ + subSkill: { + mark: { + onremove: true, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=player.countMark('shunshi_mark'); + content: function () { + trigger.num += player.countMark("shunshi_mark"); }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('shunshi_mark'); + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("shunshi_mark"); }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('shunshi_mark'); + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("shunshi_mark"); }, }, - intro:{ - content:'拥有#层效果', + intro: { + content: "拥有#层效果", }, }, }, }, - xianwei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ + xianwei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { return player.hasEnabledSlot(); }, - content:function(){ - 'step 0' - player.chooseToDisable().ai=function(event,player,list){ - var getVal=function(num){ - var card=player.getEquip(num); - if(card){ - var val=get.value(card); - if(val>0) return 0; - return 5-val; + content: function () { + "step 0"; + player.chooseToDisable().ai = function (event, player, list) { + var getVal = function (num) { + var card = player.getEquip(num); + if (card) { + var val = get.value(card); + if (val > 0) return 0; + return 5 - val; } - switch(num){ - case 'equip3':return 4.5; - case 'equip4':return 4.4; - case 'equip5':return 4.3; - case 'equip2':return (3-player.hp)*1.5; - case 'equip1':{ - if(game.hasPlayer(function(current){ - return (get.realAttitude||get.attitude)(player,current)<0&&get.distance(player,current)>1; - })) return 0; + switch (num) { + case "equip3": + return 4.5; + case "equip4": + return 4.4; + case "equip5": + return 4.3; + case "equip2": + return (3 - player.hp) * 1.5; + case "equip1": { + if ( + game.hasPlayer(function (current) { + return ( + (get.realAttitude || get.attitude)(player, current) < 0 && + get.distance(player, current) > 1 + ); + }) + ) + return 0; return 3.2; } } - } - list.sort(function(a,b){ - return getVal(b)-getVal(a); + }; + list.sort(function (a, b) { + return getVal(b) - getVal(a); }); return list[0]; }; - 'step 1' - var cardType=result.control; - event.cardType=cardType; - var num=player.countDisabledSlot(); - if(num<5) player.draw(5-num); - player.chooseTarget(lib.filter.notMe,'是否令一名其他角色从牌堆中使用一张'+get.translation(cardType)+'牌?').set('ai',function(target){ - var player=_status.event.player,type=_status.event.cardType; - var card=get.cardPile2(function(card){ - return get.subtype(card)==type&&target.canUse(card,target); - }); - if(!card) return 0; - return get.effect(target,card,target,player); - }).set('cardType',event.cardType); - 'step 2' - if(!result.bool) return; - var target=result.targets[0]; - player.line(target,'green'); - var card=get.cardPile2(function(card){ - return get.subtype(card)==event.cardType&&target.canUse(card,target); + "step 1"; + var cardType = result.control; + event.cardType = cardType; + var num = player.countDisabledSlot(); + if (num < 5) player.draw(5 - num); + player + .chooseTarget( + lib.filter.notMe, + "是否令一名其他角色从牌堆中使用一张" + get.translation(cardType) + "牌?" + ) + .set("ai", function (target) { + var player = _status.event.player, + type = _status.event.cardType; + var card = get.cardPile2(function (card) { + return get.subtype(card) == type && target.canUse(card, target); + }); + if (!card) return 0; + return get.effect(target, card, target, player); + }) + .set("cardType", event.cardType); + "step 2"; + if (!result.bool) return; + var target = result.targets[0]; + player.line(target, "green"); + var card = get.cardPile2(function (card) { + return get.subtype(card) == event.cardType && target.canUse(card, target); }); - if(card) target.chooseUseTarget(card,'nopopup',true); + if (card) target.chooseUseTarget(card, "nopopup", true); else target.draw(); }, - group:'xianwei_all', - subSkill:{ - all:{ - trigger:{player:'disableEquipAfter'}, - forced:true, - filter:function(event,player){ + group: "xianwei_all", + subSkill: { + all: { + trigger: { player: "disableEquipAfter" }, + forced: true, + filter: function (event, player) { return !player.hasEnabledSlot(); }, - content:function(){ + content: function () { player.gainMaxHp(2); - player.addSkill('xianwei_effect'); + player.addSkill("xianwei_effect"); }, }, - effect:{ - charlotte:true, - mark:true, - intro:{content:'和其他角色视为在彼此的攻击范围内'}, - mod:{ - inRange:()=>true, - inRangeOf:()=>true, + effect: { + charlotte: true, + mark: true, + intro: { content: "和其他角色视为在彼此的攻击范围内" }, + mod: { + inRange: () => true, + inRangeOf: () => true, }, }, }, }, - rehuoshui:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - var num=Math.min(game.countPlayer()-1,Math.max(1,player.getDamagedHp())); + rehuoshui: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + var num = Math.min(game.countPlayer() - 1, Math.max(1, player.getDamagedHp())); var str; - if(num>1){ - str='选择至多'+get.cnNumber(num)+'名其他角色。'; - var list=['第一名角色的非锁定技失效直到回合结束',';第二名角色交给你一张手牌',';第三名及之后角色弃置装备区内的所有牌']; - for(var i=0;i 1) { + str = "选择至多" + get.cnNumber(num) + "名其他角色。"; + var list = [ + "第一名角色的非锁定技失效直到回合结束", + ";第二名角色交给你一张手牌", + ";第三名及之后角色弃置装备区内的所有牌", + ]; + for (var i = 0; i < Math.min(3, num); i++) { + str += list[i]; } - str+='。'; + str += "。"; + } else str = "令一名其他角色的非锁定技本回合内失效"; + player + .chooseTarget([1, num], get.prompt("rehuoshui"), str, lib.filter.notMe) + .set("ai", function (target) { + var att = -get.attitude(_status.event.player, target); + if (att <= 0) return 0; + if ( + target.hasSkillTag("maixie") || + target.hasSkill("maixie_hp") || + target.hasSkill("maixie_defed") + ) + att *= 3; + return att / get.threaten(target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; + player.logSkill("rehuoshui", targets); + event.targets = targets; + targets[0].addTempSkill("fengyin"); + if (targets.length < 2) event.goto(5); + } else event.finish(); + "step 2"; + if (targets[1].countCards("h") == 0) event.goto(targets.length > 2 ? 4 : 5); + else targets[1].chooseCard("h", true, "交给" + get.translation(player) + "一张手牌"); + "step 3"; + if (result.bool) { + targets[1].give(result.cards, player); } - else str='令一名其他角色的非锁定技本回合内失效'; - player.chooseTarget([1,num],get.prompt('rehuoshui'),str,lib.filter.notMe).set('ai',function(target){ - var att=-get.attitude(_status.event.player,target); - if(att<=0) return 0; - if(target.hasSkillTag('maixie')||target.hasSkill('maixie_hp')||target.hasSkill('maixie_defed')) att*=3; - return att/get.threaten(target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; - player.logSkill('rehuoshui',targets); - event.targets=targets; - targets[0].addTempSkill('fengyin'); - if(targets.length<2) event.goto(5); - } - else event.finish(); - 'step 2' - if(targets[1].countCards('h')==0) event.goto(targets.length>2?4:5); - else targets[1].chooseCard('h',true,'交给'+get.translation(player)+'一张手牌'); - 'step 3' - if(result.bool){ - targets[1].give(result.cards,player); - } - if(targets.length<3) event.goto(5); - 'step 4' - var num=targets[2].countCards('e'); - if(num>0) targets[2].chooseToDiscard('e',true,num); - 'step 5' + if (targets.length < 3) event.goto(5); + "step 4"; + var num = targets[2].countCards("e"); + if (num > 0) targets[2].chooseToDiscard("e", true, num); + "step 5"; game.delayx(); }, }, - reqingcheng:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.reqingcheng.filterTarget(null,player,current)); + reqingcheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => + lib.skill.reqingcheng.filterTarget(null, player, current) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.hasSex('male')&&target.countCards('h')<=player.countCards('h'); + filterTarget: function (card, player, target) { + return ( + target != player && + target.hasSex("male") && + target.countCards("h") <= player.countCards("h") + ); }, - content:function(){ + content: function () { player.swapHandcards(target); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(target.countCards('h')>0) return -Math.max(get.value(target.getCards('h'),player)-get.value(player.getCards('h'),player),0); + ai: { + order: 1, + result: { + player: function (player, target) { + if (target.countCards("h") > 0) + return -Math.max( + get.value(target.getCards("h"), player) - + get.value(player.getCards("h"), player), + 0 + ); return 0; }, }, }, }, //丘力居 - koulve:{ - audio:2, - trigger:{source:'damageSource'}, - logTarget:'player', - filter:function(event,player){ - return event.player.isDamaged()&&event.player.countCards('h')>0&&player.isPhaseUsing(); + koulve: { + audio: 2, + trigger: { source: "damageSource" }, + logTarget: "player", + filter: function (event, player) { + return ( + event.player.isDamaged() && event.player.countCards("h") > 0 && player.isPhaseUsing() + ); }, - check:function(event,player){ - if(player.hp==1&&player.isHealthy()) return false; - return get.attitude(player,event.player)<=0; + check: function (event, player) { + if (player.hp == 1 && player.isHealthy()) return false; + return get.attitude(player, event.player) <= 0; }, - content:function(){ - 'step 0' - player.choosePlayerCard(trigger.player,'h',true,trigger.player.getDamagedHp()); - 'step 1' - var card=result.cards; - event.cards=card; - player.showCards(card,get.translation(player)+'发动了【宼略】'); - 'step 2' - var gains=[],red=false; - var target=trigger.player; - for(var card of cards){ - var type=get.type2(card,target); - if((type=='basic'||type=='trick')&&get.tag(card,'damage')>0) gains.push(card); - if(!red&&get.color(card,target)=='red') red=true; + content: function () { + "step 0"; + player.choosePlayerCard(trigger.player, "h", true, trigger.player.getDamagedHp()); + "step 1"; + var card = result.cards; + event.cards = card; + player.showCards(card, get.translation(player) + "发动了【宼略】"); + "step 2"; + var gains = [], + red = false; + var target = trigger.player; + for (var card of cards) { + var type = get.type2(card, target); + if ((type == "basic" || type == "trick") && get.tag(card, "damage") > 0) + gains.push(card); + if (!red && get.color(card, target) == "red") red = true; } - if(gains.length) player.gain(gains,'gain2'); - if(!red) event.finish(); - 'step 3' - player[player.isDamaged()?'loseMaxHp':'loseHp'](); + if (gains.length) player.gain(gains, "gain2"); + if (!red) event.finish(); + "step 3"; + player[player.isDamaged() ? "loseMaxHp" : "loseHp"](); player.draw(2); }, }, - qljsuiren:{ - audio:2, - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return player.countCards('h',function(card){ - var type=get.type(card,player); - return (type=='basic'||type=='trick')&&get.tag(card,'damage')>0; + qljsuiren: { + audio: 2, + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return player.countCards("h", function (card) { + var type = get.type(card, player); + return (type == "basic" || type == "trick") && get.tag(card, "damage") > 0; }); }, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('qljsuiren'),'将所有伤害性基本牌和锦囊牌交给一名其他角色').set('forceDie',true).set('ai',function(target){ - var player=_status.event.player,cards=_status.event.aiCards; - var att=get.attitude(player,target); - if(att<=0) return 0; - if(target.hasSkillTag('nogain')) att/=100; - var num=0.1; - for(var i of cards) num+=Math.max(0,target.getUseValue(card)); - return num*att; - }).set('aiCards',player.getCards('h',function(card){ - var type=get.type(card,player); - return (type=='basic'||type=='trick')&&get.tag(card,'damage')>0; - })); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qljsuiren',target); - player.give(player.getCards('h',function(card){ - var type=get.type(card,player); - return (type=='basic'||type=='trick')&&get.tag(card,'damage')>0; - }),target,'give'); + content: function () { + "step 0"; + player + .chooseTarget( + lib.filter.notMe, + get.prompt("qljsuiren"), + "将所有伤害性基本牌和锦囊牌交给一名其他角色" + ) + .set("forceDie", true) + .set("ai", function (target) { + var player = _status.event.player, + cards = _status.event.aiCards; + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (target.hasSkillTag("nogain")) att /= 100; + var num = 0.1; + for (var i of cards) num += Math.max(0, target.getUseValue(card)); + return num * att; + }) + .set( + "aiCards", + player.getCards("h", function (card) { + var type = get.type(card, player); + return (type == "basic" || type == "trick") && get.tag(card, "damage") > 0; + }) + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qljsuiren", target); + player.give( + player.getCards("h", function (card) { + var type = get.type(card, player); + return (type == "basic" || type == "trick") && get.tag(card, "damage") > 0; + }), + target, + "give" + ); } }, }, //胡车儿 - redaoji:{ - audio:2, - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - if(player==event.player||get.subtype(event.card,false)!='equip1'||(event.player.isDead()&&!event.cards.filterInD().length)) return false; - var all=event.player.getAllHistory('useCard'); - for(var i of all){ - if(get.subtype(i.card,false)=='equip1') return i==event; + redaoji: { + audio: 2, + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + if ( + player == event.player || + get.subtype(event.card, false) != "equip1" || + (event.player.isDead() && !event.cards.filterInD().length) + ) + return false; + var all = event.player.getAllHistory("useCard"); + for (var i of all) { + if (get.subtype(i.card, false) == "equip1") return i == event; } return false; }, - content:function(){ - 'step 0' - var list=[]; - event.addIndex=0; - if(trigger.cards.filterInD().length>0) list.push('获得'+get.translation(trigger.cards.filterInD())); + content: function () { + "step 0"; + var list = []; + event.addIndex = 0; + if (trigger.cards.filterInD().length > 0) + list.push("获得" + get.translation(trigger.cards.filterInD())); else event.addIndex++; - if(trigger.player.isIn()) list.push('令'+get.translation(trigger.player)+'本回合不能使用或打出【杀】'); - player.chooseControl('cancel2').set('choiceList',list).set('prompt',get.prompt('redaoji',trigger.player)).set('ai',function(){ - var evt=_status.event.getParent(),player=evt.player,evt2=evt._trigger; - if(evt.addIndex==0){ - var noob=get.attitude(player,evt2.player)<0?1:'cancel2'; - if(player.countMark('fuzhong')==3) return noob; - if(get.effect(evt2.targets[0],evt2.card,evt2.player,player)<=0) return 0; - return noob; - } - return get.attitude(player,evt2.player)<0?0:'cancel2'; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('redaoji',trigger.player); + if (trigger.player.isIn()) + list.push("令" + get.translation(trigger.player) + "本回合不能使用或打出【杀】"); + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("prompt", get.prompt("redaoji", trigger.player)) + .set("ai", function () { + var evt = _status.event.getParent(), + player = evt.player, + evt2 = evt._trigger; + if (evt.addIndex == 0) { + var noob = get.attitude(player, evt2.player) < 0 ? 1 : "cancel2"; + if (player.countMark("fuzhong") == 3) return noob; + if (get.effect(evt2.targets[0], evt2.card, evt2.player, player) <= 0) + return 0; + return noob; + } + return get.attitude(player, evt2.player) < 0 ? 0 : "cancel2"; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("redaoji", trigger.player); game.delayx(); - if(result.index+event.addIndex==0){ - player.gain(trigger.cards.filterInD(),'gain2'); - } - else trigger.player.addTempSkill('redaoji2'); + if (result.index + event.addIndex == 0) { + player.gain(trigger.cards.filterInD(), "gain2"); + } else trigger.player.addTempSkill("redaoji2"); } }, }, - redaoji2:{ - charlotte:true, - mark:true, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + redaoji2: { + charlotte: true, + mark: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, - cardRespondable:function(card){ - if(card.name=='sha') return false; + cardRespondable: function (card) { + if (card.name == "sha") return false; }, }, - intro:{ - content:'本回合不能使用或打出杀', + intro: { + content: "本回合不能使用或打出杀", }, }, - fuzhong:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('fuzhong')>3; + fuzhong: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("fuzhong") > 3; }, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,'对一名其他角色造成1点伤害',true).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, "对一名其他角色造成1点伤害", true) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - target.damage('nocard'); + target.damage("nocard"); } - player.removeMark('fuzhong',4); + player.removeMark("fuzhong", 4); }, - marktext:'重', - intro:{content:'mark'}, - group:['fuzhong_gain','fuzhong_yingzi'], - mod:{ - maxHandcard:function(player,num){ - if(player.countMark('fuzhong')>2) return num+3; + marktext: "重", + intro: { content: "mark" }, + group: ["fuzhong_gain", "fuzhong_yingzi"], + mod: { + maxHandcard: function (player, num) { + if (player.countMark("fuzhong") > 2) return num + 3; + }, + globalFrom: function (player, target, num) { + if (player.countMark("fuzhong") > 1) return num - 2; }, - globalFrom:function(player,target,num){ - if(player.countMark('fuzhong')>1) return num-2; - } }, - subSkill:{ - gain:{ - audio:'fuzhong', - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + subSkill: { + gain: { + audio: "fuzhong", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - return player!=_status.currentPhase&&event.getg(player).length>0; + forced: true, + filter: function (event, player) { + return player != _status.currentPhase && event.getg(player).length > 0; }, - content:function(){ - player.addMark('fuzhong',1); + content: function () { + player.addMark("fuzhong", 1); }, }, - yingzi:{ - audio:'fuzhong', - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ - return !event.numFixed&&player.countMark('fuzhong')>0; + yingzi: { + audio: "fuzhong", + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { + return !event.numFixed && player.countMark("fuzhong") > 0; }, - content:function(){ + content: function () { trigger.num++; }, }, }, }, //董承 - xuezhao:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.maxHp>0&&player.countCards('h')>0; + xuezhao: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.maxHp > 0 && player.countCards("h") > 0; }, - filterCard:true, - position:'h', - filterTarget:lib.filter.notMe, - selectTarget:function(){ - return [1,_status.event.player.maxHp]; + filterCard: true, + position: "h", + filterTarget: lib.filter.notMe, + selectTarget: function () { + return [1, _status.event.player.maxHp]; }, - check:function(card){ - return 2*(_status.event.player.maxHp+2)-get.value(card); + check: function (card) { + return 2 * (_status.event.player.maxHp + 2) - get.value(card); }, - content:function(){ - 'step 0' - if(!target.countCards('he')) event._result={bool:false}; - else target.chooseCard('he','交给'+get.translation(player)+'一张牌并摸一张牌,或不能响应其使用的牌直到回合结束').set('ai',function(card){ - var player=_status.event.player,target=_status.event.getParent().player,val=get.value(card); - if(get.attitude(player,target)>0){ - if(get.name(card,target)=='sha'&&target.hasValueTarget(card)) return 30-val; - return 20-val; - } - return -val; - }); - 'step 1' - if(result.bool){ - player.addTempSkill('xuezhao_sha'); - player.addMark('xuezhao_sha',1,false); - target.give(result.cards,player); + content: function () { + "step 0"; + if (!target.countCards("he")) event._result = { bool: false }; + else + target + .chooseCard( + "he", + "交给" + + get.translation(player) + + "一张牌并摸一张牌,或不能响应其使用的牌直到回合结束" + ) + .set("ai", function (card) { + var player = _status.event.player, + target = _status.event.getParent().player, + val = get.value(card); + if (get.attitude(player, target) > 0) { + if (get.name(card, target) == "sha" && target.hasValueTarget(card)) + return 30 - val; + return 20 - val; + } + return -val; + }); + "step 1"; + if (result.bool) { + player.addTempSkill("xuezhao_sha"); + player.addMark("xuezhao_sha", 1, false); + target.give(result.cards, player); target.draw(); - } - else{ - player.addTempSkill('xuezhao_hit'); - player.markAuto('xuezhao_hit',[target]); + } else { + player.addTempSkill("xuezhao_hit"); + player.markAuto("xuezhao_hit", [target]); } }, - ai:{ - threaten:2.4, - order:3.6, - result:{ - player:function(player,target){ - if(get.attitude(target,player)>0){ - if(target.countCards('e',function(card){ - return get.value(card,target)<0; - })) return 3; - return Math.sqrt(target.countCards('he')); + ai: { + threaten: 2.4, + order: 3.6, + result: { + player: function (player, target) { + if (get.attitude(target, player) > 0) { + if ( + target.countCards("e", function (card) { + return get.value(card, target) < 0; + }) + ) + return 3; + return Math.sqrt(target.countCards("he")); } - if(target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&player.countCards('hs',function(card){ - return !ui.selected.cards.includes(card)&&get.name(card)=='sha'&&player.canUse(card,target)&&get.effect(target,card,player,player)!=0; - })) return -Math.sqrt(Math.abs(get.attitude(player,target)))/2; + if ( + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + player.countCards("hs", function (card) { + return ( + !ui.selected.cards.includes(card) && + get.name(card) == "sha" && + player.canUse(card, target) && + get.effect(target, card, player, player) != 0 + ); + }) + ) + return -Math.sqrt(Math.abs(get.attitude(player, target))) / 2; return 0.1; }, }, }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - marktext:'血', - intro:{content:'多杀#刀,誓诛曹贼!'}, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('xuezhao_sha'); + subSkill: { + sha: { + charlotte: true, + onremove: true, + marktext: "血", + intro: { content: "多杀#刀,誓诛曹贼!" }, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("xuezhao_sha"); }, }, }, - hit:{ - charlotte:true, - onremove:true, - marktext:'诏', - intro:{content:'$篡汉,其心可诛!'}, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - content:function(){ - trigger.directHit.addArray(player.getStorage('xuezhao_hit')); + hit: { + charlotte: true, + onremove: true, + marktext: "诏", + intro: { content: "$篡汉,其心可诛!" }, + trigger: { player: "useCard1" }, + forced: true, + popup: false, + content: function () { + trigger.directHit.addArray(player.getStorage("xuezhao_hit")); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return player.getStorage('xuezhao_hit').includes(arg.target); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return player.getStorage("xuezhao_hit").includes(arg.target); }, }, }, }, }, //唐姬 - kangge:{ - audio:2, - trigger:{player:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return player.phaseNumber==1&&!player.storage.kangge&&game.hasPlayer(current=>current!=player); + kangge: { + audio: 2, + trigger: { player: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.phaseNumber == 1 && + !player.storage.kangge && + game.hasPlayer((current) => current != player) + ); }, - content:function(){ - 'step 0' - player.chooseTarget('请选择【抗歌】的目标','其于回合外摸牌后,你摸等量的牌;其进入濒死状态时,你可令其回复体力至1点;其死亡后,你弃置所有牌并失去1点体力',lib.filter.notMe,true).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('kangge',target); - player.addSkill('kangge_clear'); - player.storage.kangge=target; - player.markSkill('kangge'); + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【抗歌】的目标", + "其于回合外摸牌后,你摸等量的牌;其进入濒死状态时,你可令其回复体力至1点;其死亡后,你弃置所有牌并失去1点体力", + lib.filter.notMe, + true + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("kangge", target); + player.addSkill("kangge_clear"); + player.storage.kangge = target; + player.markSkill("kangge"); game.delayx(); } }, - intro:{content:'已指定$为目标'}, - group:['kangge_draw','kangge_dying','kangge_die'], - subSkill:{ - draw:{ - audio:'kangge', - trigger:{ - global:['gainAfter','loseAsyncAfter'], + intro: { content: "已指定$为目标" }, + group: ["kangge_draw", "kangge_dying", "kangge_die"], + subSkill: { + draw: { + audio: "kangge", + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - forced:true, - filter:function(event,player){ - if(player.countMark('kangge_draw')>=3) return false; - var target=player.storage.kangge; - return target&&target!=_status.currentPhase&&event.getg(target).length>0; + forced: true, + filter: function (event, player) { + 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('kangge_draw'),trigger.getg(player.storage.kangge).length); - player.addMark('kangge_draw',num,false); + logTarget: "player", + content: function () { + var num = Math.min( + 3 - player.countMark("kangge_draw"), + trigger.getg(player.storage.kangge).length + ); + player.addMark("kangge_draw", num, false); player.draw(num); }, }, - clear:{ - trigger:{global:'phaseBeginStart'}, - forced:true, - firstDo:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.countMark('kangge_draw')>0; + clear: { + trigger: { global: "phaseBeginStart" }, + forced: true, + firstDo: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.countMark("kangge_draw") > 0; }, - content:function(){ - player.removeMark('kangge_draw',player.countMark('kangge_draw'),false); + content: function () { + player.removeMark("kangge_draw", player.countMark("kangge_draw"), false); }, }, - dying:{ - audio:'kangge', - trigger:{global:'dying'}, - logTarget:'player', - filter:function(event,player){ - return event.player==player.storage.kangge&&event.player.hp<1&&!player.hasSkill('kangge_temp'); + dying: { + audio: "kangge", + trigger: { global: "dying" }, + logTarget: "player", + filter: function (event, player) { + 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; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - prompt2:'令其将体力值回复至1点', - content:function(){ - trigger.player.recover(1-trigger.player.hp); - player.addTempSkill('kangge_temp','roundStart'); + prompt2: "令其将体力值回复至1点", + content: function () { + trigger.player.recover(1 - trigger.player.hp); + player.addTempSkill("kangge_temp", "roundStart"); }, }, - temp:{}, - die:{ - audio:'kangge', - trigger:{global:'dieAfter'}, - filter:function(event,player){ - return event.player==player.storage.kangge; + temp: {}, + die: { + audio: "kangge", + trigger: { global: "dieAfter" }, + filter: function (event, player) { + return event.player == player.storage.kangge; }, - forced:true, - content:function(){ - var cards=player.getCards('he'); - if(cards.length) player.discard(cards); + forced: true, + content: function () { + var cards = player.getCards("he"); + if (cards.length) player.discard(cards); player.loseHp(); }, }, }, - ai:{ - threaten:2, + ai: { + threaten: 2, }, }, - jielie:{ - audio:2, - trigger:{player:'damageBegin4'}, - direct:true, - filter:function(event,player){ - return ((!event.source)||(event.source!=player&&event.source!=player.storage.kangge))&&player.storage.kangge&&player.storage.kangge.isIn(); + jielie: { + audio: 2, + trigger: { player: "damageBegin4" }, + direct: true, + filter: function (event, player) { + 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('jielie')).set('prompt2','防止伤害并改为失去等量体力,且令'+get.translation(player.storage.kangge)+'从弃牌堆中获得等量的花色牌').set('ai',function(){ - var player=_status.event.player; - 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('jielie',player.storage.kangge); + content: function () { + "step 0"; + 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.kangge) <= 0) return "cancel2"; + return lib.suit.randomGet(); + }); + "step 1"; + if (result.control != "cancel2") { + event.suit = result.control; + player.logSkill("jielie", player.storage.kangge); trigger.cancel(); player.loseHp(trigger.num); - } - else event.finish(); - 'step 2' - var cards=[]; - while(cards.length0; - }) - }, - content:function(){ - 'step 0' - player.chooseTarget(function(card,player,target){ - return target!=player&&target.countCards('j',function(card){ - return player.canAddJudge(card); - })>0; - },get.prompt('dangzai'),'将一名其他角色判定区内的一张牌移动到你的判定区内'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dangzai',target); - player.choosePlayerCard(target,'j',true).set('filterButton',function(button){ - return _status.event.player.canAddJudge(button.link); + dangzai: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + !player.isDisabledJudge() && + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("j", function (card) { + return player.canAddJudge(card); + }) > 0 + ); }) - } - else event.finish(); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - var card=result.cards[0]; - target.$give(card,player); + ); + }, + content: function () { + "step 0"; + player.chooseTarget( + function (card, player, target) { + return ( + target != player && + target.countCards("j", function (card) { + return player.canAddJudge(card); + }) > 0 + ); + }, + get.prompt("dangzai"), + "将一名其他角色判定区内的一张牌移动到你的判定区内" + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dangzai", target); + player.choosePlayerCard(target, "j", true).set("filterButton", function (button) { + return _status.event.player.canAddJudge(button.link); + }); + } else event.finish(); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + var card = result.cards[0]; + target.$give(card, player); game.delayx(); - var name=card.viewAs||card.name; - if(card.name!=name){ - player.addJudge(name,card); - } - else{ + var name = card.viewAs || card.name; + if (card.name != name) { + player.addJudge(name, card); + } else { player.addJudge(card); } } }, }, - liangjue:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + liangjue: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - if(player.hp<=1) return false; - if(event.player==player){ - if(event.name=='equip'&&get.color(event.card,player)=='black') return true; - if(event.name=='addJudge'&&get.color(event.cards[0],player)=='black') return true; + forced: true, + filter: function (event, player) { + if (player.hp <= 1) return false; + if (event.player == player) { + if (event.name == "equip" && get.color(event.card, player) == "black") return true; + if (event.name == "addJudge" && get.color(event.cards[0], player) == "black") + return true; } - var evt=event.getl(player); - if(!evt||!evt.es||!evt.js||!evt.es.length&&!evt.js.length) return false; - for(var i of evt.es){ - if(get.color(i,player)=='black') return true; + var evt = event.getl(player); + if (!evt || !evt.es || !evt.js || (!evt.es.length && !evt.js.length)) return false; + for (var i of evt.es) { + if (get.color(i, player) == "black") return true; } - for(var i of evt.js){ - if(get.color(i,player)=='black') return true; + for (var i of evt.js) { + if (get.color(i, player) == "black") return true; } return false; }, - content:function(){ + content: function () { player.loseHp(); player.draw(2); }, }, //狼灭 - langmie:{ - trigger:{global:'phaseUseEnd'}, + langmie: { + trigger: { global: "phaseUseEnd" }, //forced:true, - filter:function(event,player){ - if(player==event.player||!player.countCards('he')) return false; - var map={}; - var list=event.player.getHistory('useCard',function(evt){ - var evt2=evt.getParent('phaseUse'); - return evt2==event; + filter: function (event, player) { + if (player == event.player || !player.countCards("he")) return false; + var map = {}; + var list = event.player.getHistory("useCard", function (evt) { + var evt2 = evt.getParent("phaseUse"); + return evt2 == event; }); - for(var i of list){ - var name=get.type2(i.card,false); - if(!map[name]) map[name]=true; + for (var i of list) { + var name = get.type2(i.card, false); + if (!map[name]) map[name] = true; else return true; } }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); }, - group:'langmie_damage', + group: "langmie_damage", }, - langmie_damage:{ - audio:'langmie', - trigger:{global:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&(event.player.getStat('damage')||0)>1&&player.countCards('he')>0; + langmie_damage: { + audio: "langmie", + trigger: { global: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return ( + event.player != player && + (event.player.getStat("damage") || 0) > 1 && + player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('langmie',trigger.player),'弃置一张牌并对其造成1点伤害').set('goon',get.damageEffect(trigger.player,player,player)>0).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 7-get.value(card); - }).logSkill=['langmie_damage',trigger.player]; - 'step 1' - if(result.bool) trigger.player.damage(); + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("langmie", trigger.player), + "弃置一张牌并对其造成1点伤害" + ) + .set("goon", get.damageEffect(trigger.player, player, player) > 0) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 7 - get.value(card); + }).logSkill = ["langmie_damage", trigger.player]; + "step 1"; + if (result.bool) trigger.player.damage(); }, - ai:{expose:0.2}, + ai: { expose: 0.2 }, }, //牛金 - recuorui:{ - audio:'cuorui', - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.hp>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countGainableCards(player,'h')>0; - }) + recuorui: { + audio: "cuorui", + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return ( + player.hp > 0 && + game.hasPlayer(function (current) { + return current != player && current.countGainableCards(player, "h") > 0; + }) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "h") > 0; }, - selectTarget:function(){ - return [1,_status.event.player.hp]; + selectTarget: function () { + return [1, _status.event.player.hp]; }, - content:function(){ - if(num==0) player.awakenSkill('recuorui'); - player.gainPlayerCard(target,true,'h'); + content: function () { + if (num == 0) player.awakenSkill("recuorui"); + player.gainPlayerCard(target, true, "h"); }, - ai:{ - order:10, - result:{ - player:1, - target:function(player,target){ - if(target.hasSkillTag('noh')) return 0; + ai: { + order: 10, + result: { + player: 1, + target: function (player, target) { + if (target.hasSkillTag("noh")) return 0; return -1; - } - } - } - }, - reliewei:{ - audio:'liewei', - trigger:{global:'dying'}, - filter:function(event,player){ - return player==_status.currentPhase||player.getHistory('useSkill',evt=>evt.skill=='reliewei').length evt.skill == "reliewei").length < + player.getHp() + ); + }, + frequent: true, + content: function () { player.draw(); }, }, //张邈 - mouni:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h','sha')>0; + mouni: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h", "sha") > 0; }, - content:function(){ - 'step 0' - player.addSkill('mouni2'); - player.chooseTarget(get.prompt2('mouni'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,cards=player.getCards('h','sha'); - if(get.attitude(player,target)>=0||!player.canUse(cards[0],target,false)||(!player.hasJudge('lebu')&&target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&!player.hasSkillTag('directHit_ai',true,{ - target:target, - card:cards[0], - },true))) return 0; - return get.effect(target,cards[0],player,player); + content: function () { + "step 0"; + player.addSkill("mouni2"); + player.chooseTarget(get.prompt2("mouni"), lib.filter.notMe).set("ai", function (target) { + var player = _status.event.player, + cards = player.getCards("h", "sha"); + if ( + get.attitude(player, target) >= 0 || + !player.canUse(cards[0], target, false) || + (!player.hasJudge("lebu") && + target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + !player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: cards[0], + }, + true + )) + ) + return 0; + return get.effect(target, cards[0], player, player); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('mouni',target); - event.cards=player.getCards('h','sha'); - } - else event.finish(); - 'step 2' - if(event.mouni_dying) return; - var hs=player.getCards('h'); - cards=cards.filter(function(card){ - return hs.includes(card)&&get.name(card,player)=='sha'&&player.canUse({ - name:'sha', - nature:get.nature(card,player), - isCard:true, - cards:[card], - },target,false); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("mouni", target); + event.cards = player.getCards("h", "sha"); + } else event.finish(); + "step 2"; + if (event.mouni_dying) return; + var hs = player.getCards("h"); + cards = cards.filter(function (card) { + return ( + hs.includes(card) && + get.name(card, player) == "sha" && + player.canUse( + { + name: "sha", + nature: get.nature(card, player), + isCard: true, + cards: [card], + }, + target, + false + ) + ); }); - if(cards.length){ - var card=cards.randomRemove(1)[0]; - player.useCard(target,false,card); + if (cards.length) { + var card = cards.randomRemove(1)[0]; + player.useCard(target, false, card); event.redo(); } - 'step 3' - if(player.getHistory('useCard',function(evt){ - return evt.getParent()==event&&!player.getHistory('sourceDamage',function(evt2){ - return evt.card==evt2.card; - }).length; - }).length){ - player.skip('phaseUse'); - player.skip('phaseDiscard'); + "step 3"; + if ( + player.getHistory("useCard", function (evt) { + return ( + evt.getParent() == event && + !player.getHistory("sourceDamage", function (evt2) { + return evt.card == evt2.card; + }).length + ); + }).length + ) { + player.skip("phaseUse"); + player.skip("phaseDiscard"); } - player.removeSkill('mouni2'); + player.removeSkill("mouni2"); }, }, - mouni2:{ - charlotte:true, - trigger:{global:'dying'}, - forced:true, - firstDo:true, - popup:false, - filter:function(event,player){ - var evt=event.getParent('mouni'); - return evt&&evt.player==player&&evt.target==event.player; + mouni2: { + charlotte: true, + trigger: { global: "dying" }, + forced: true, + firstDo: true, + popup: false, + filter: function (event, player) { + var evt = event.getParent("mouni"); + return evt && evt.player == player && evt.target == event.player; }, - content:function(){ - trigger.getParent('mouni').mouni_dying=true; + content: function () { + trigger.getParent("mouni").mouni_dying = true; }, }, - zongfan:{ - derivation:'zhangu', - trigger:{player:'phaseJieshuBegin'}, - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return !player.getHistory('skipped').includes('phaseUse')&&player.getHistory('useCard',function(evt){ - return evt.getParent().name=='mouni'; - }).length>0; + zongfan: { + derivation: "zhangu", + trigger: { player: "phaseJieshuBegin" }, + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return ( + !player.getHistory("skipped").includes("phaseUse") && + player.getHistory("useCard", function (evt) { + return evt.getParent().name == "mouni"; + }).length > 0 + ); }, - content:function(){ - 'step 0' - player.awakenSkill('zongfan'); - var num=player.countCards('he'); - if(num>0){ + content: function () { + "step 0"; + player.awakenSkill("zongfan"); + var num = player.countCards("he"); + if (num > 0) { player.chooseCardTarget({ - prompt:'是否将任意张牌交给一名其他角色?', - selectCard:[1,num], - filterCard:true, - filterTarget:lib.filter.notMe, - position:'he', - ai1:function(card){ - if(card.name=='du') return 10; - else if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - var player=_status.event.player; - if(ui.selected.cards.length>4||!game.hasPlayer(function(current){ - return get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - })) return 0; - return 1/Math.max(0.1,get.value(card)); + prompt: "是否将任意张牌交给一名其他角色?", + selectCard: [1, num], + filterCard: true, + filterTarget: lib.filter.notMe, + position: "he", + ai1: function (card) { + if (card.name == "du") return 10; + else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") + return 0; + var player = _status.event.player; + if ( + ui.selected.cards.length > 4 || + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return 0; + return 1 / Math.max(0.1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(ui.selected.cards[0].name=='du') return -att; - if(target.hasSkillTag('nogain')) att/=6; + ai2: function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (ui.selected.cards[0].name == "du") return -att; + if (target.hasSkillTag("nogain")) att /= 6; return att; }, }); - } - else event.goto(2); - 'step 1' - if(result.bool){ - var cards=result.cards,target=result.targets[0],num=Math.min(5,cards.length); - player.give(cards,target); + } else event.goto(2); + "step 1"; + if (result.bool) { + var cards = result.cards, + target = result.targets[0], + num = Math.min(5, cards.length); + player.give(cards, target); player.gainMaxHp(num); player.recover(num); } - 'step 2' + "step 2"; //player.removeSkill('mouni'); - player.changeSkills(['zhangu'],['mouni']); + player.changeSkills(["zhangu"], ["mouni"]); }, }, - zhangu:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.maxHp>1&&(player.countCards('h')==0||player.countCards('e')==0) + zhangu: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.maxHp > 1 && (player.countCards("h") == 0 || player.countCards("e") == 0); }, - content:function(){ - var cards=[],types=[]; - for(var i=0;i<3;i++){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&!types.includes(get.type2(card,false)); + content: function () { + var cards = [], + types = []; + for (var i = 0; i < 3; i++) { + var card = get.cardPile2(function (card) { + return !cards.includes(card) && !types.includes(get.type2(card, false)); }); - if(card){ + if (card) { cards.push(card); - types.push(get.type2(card,false)); - } - else break; + types.push(get.type2(card, false)); + } else break; } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); player.loseMaxHp(); }, }, //梁兴 - lulve:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - var hs=player.countCards('h'); - return hs>1&&game.hasPlayer(function(target){ - var ts=target.countCards('h'); - return target!=player&&ts>0&&hs>ts; - }); + lulve: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + var hs = player.countCards("h"); + return ( + hs > 1 && + game.hasPlayer(function (target) { + var ts = target.countCards("h"); + return target != player && ts > 0 && hs > ts; + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('lulve'),function(card,player,target){ - var hs=player.countCards('h'),ts=target.countCards('h'); - return target!=player&&ts>0&&hs>ts; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.isTurnedOver()) return att/10; - if(!player.hasShan()&&target.canUse({name:'sha',isCard:true},player,false)&&get.effect(player,{name:'sha',isCard:true},target,player)<0&&player.hp<4) return 0; - return -att*Math.sqrt(target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('lulve',target); - var str=get.translation(player); - target.chooseControl().set('choiceList',[ - '将所有手牌交给'+str+',然后其将武将牌翻面', - '将武将牌翻面,然后视为对'+str+'使用【杀】', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().player; - if(player.isTurnedOver()) return 1; - if(!target.hasShan()&&player.canUse({name:'sha',isCard:true},target,false)&&get.effect(target,{name:'sha',isCard:true},player,player)<0) return 0; - return Math.random()<0.5?0:1; + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("lulve"), function (card, player, target) { + var hs = player.countCards("h"), + ts = target.countCards("h"); + return target != player && ts > 0 && hs > ts; + }) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.isTurnedOver()) return att / 10; + if ( + !player.hasShan() && + target.canUse({ name: "sha", isCard: true }, player, false) && + get.effect(player, { name: "sha", isCard: true }, target, player) < 0 && + player.hp < 4 + ) + return 0; + return -att * Math.sqrt(target.countCards("h")); }); - } - else event.finish(); - 'step 2' - if(result.index==0){ - target.give(target.getCards('h'),player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("lulve", target); + var str = get.translation(player); + target + .chooseControl() + .set("choiceList", [ + "将所有手牌交给" + str + ",然后其将武将牌翻面", + "将武将牌翻面,然后视为对" + str + "使用【杀】", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().player; + if (player.isTurnedOver()) return 1; + if ( + !target.hasShan() && + player.canUse({ name: "sha", isCard: true }, target, false) && + get.effect(target, { name: "sha", isCard: true }, player, player) < 0 + ) + return 0; + return Math.random() < 0.5 ? 0 : 1; + }); + } else event.finish(); + "step 2"; + if (result.index == 0) { + target.give(target.getCards("h"), player); player.turnOver(); event.finish(); - } - else target.turnOver(); - 'step 3' - if(target.canUse({name:'sha',isCard:true},player,false)) target.useCard({name:'sha',isCard:true},player,false); + } else target.turnOver(); + "step 3"; + if (target.canUse({ name: "sha", isCard: true }, player, false)) + target.useCard({ name: "sha", isCard: true }, player, false); }, }, - lxzhuixi:{ - audio:2, - trigger:{ - player:'damageBegin3', - source:'damageBegin1', + lxzhuixi: { + audio: 2, + trigger: { + player: "damageBegin3", + source: "damageBegin1", }, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.source&&event.player.isTurnedOver()!=event.source.isTurnedOver(); + forced: true, + logTarget: "player", + filter: function (event, player) { + return event.source && event.player.isTurnedOver() != event.source.isTurnedOver(); }, - content:function(){ + content: function () { trigger.num++; }, }, //陶谦和曹嵩 - reyirang:{ - audio:'yirang', - audioname:['re_taoqian'], - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - if(!player.countCards('he',function(card){ - return get.type(card)!='basic'; - })){ + reyirang: { + audio: "yirang", + audioname: ["re_taoqian"], + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + if ( + !player.countCards("he", function (card) { + return get.type(card) != "basic"; + }) + ) { return false; } - return game.hasPlayer(function(current){ - return current!=player; + return game.hasPlayer(function (current) { + return current != player; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('reyirang'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return (get.attitude(_status.event.player,target)-2)*target.maxHp; - }); - 'step 1' - if(result.bool){ - var cards=player.getCards('he',function(card){ - return get.type(card)!='basic'; + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("reyirang"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + return (get.attitude(_status.event.player, target) - 2) * target.maxHp; }); - var target=result.targets[0]; - player.logSkill('reyirang',target); - player.give(cards,target,'give'); - if(target.maxHp>player.maxHp) player.gainMaxHp(target.maxHp-player.maxHp,true); + "step 1"; + if (result.bool) { + var cards = player.getCards("he", function (card) { + return get.type(card) != "basic"; + }); + var target = result.targets[0]; + player.logSkill("reyirang", target); + player.give(cards, target, "give"); + if (target.maxHp > player.maxHp) player.gainMaxHp(target.maxHp - player.maxHp, true); player.recover(cards.length); } - } + }, }, - cslilu:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ + cslilu: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { return !event.numFixed; }, - check:function(event,player){ - return Math.min(player.maxHp,5)-player.countCards('h')>3||game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - }); + check: function (event, player) { + return ( + Math.min(player.maxHp, 5) - player.countCards("h") > 3 || + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - 'step 1' - player.drawTo(Math.min(player.maxHp,5)); - 'step 2' - if(player.countCards('h')>0){ - var str='将至少一张手牌交给一名其他角色'; - var num=player.countMark('cslilu'); - if(num0) str+=('。若给出的牌数大于'+get.cnNumber(num)+'张,则你'); - else str+=',并'; - str+='加1点体力上限并回复1点体力' + "step 1"; + player.drawTo(Math.min(player.maxHp, 5)); + "step 2"; + if (player.countCards("h") > 0) { + var str = "将至少一张手牌交给一名其他角色"; + var num = player.countMark("cslilu"); + if (num < player.countCards("h")) { + if (num > 0) str += "。若给出的牌数大于" + get.cnNumber(num) + "张,则你"; + else str += ",并"; + str += "加1点体力上限并回复1点体力"; } player.chooseCardTarget({ - prompt:str, - filterCard:true, - filterTarget:lib.filter.notMe, - selectCard:[1,Infinity], - forced:true, - ai1:function(card){ - if(ui.selected.cards.length<_status.event.goon){ - if(get.tag(card,'damage')&&game.hasPlayer(function(current){ - current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain')&&!current.hasJudge('lebu')&¤t.hasValueTarget(card); - })) return 1; - return 1/Math.max(0.1,get.value(card)); + prompt: str, + filterCard: true, + filterTarget: lib.filter.notMe, + selectCard: [1, Infinity], + forced: true, + ai1: function (card) { + if (ui.selected.cards.length < _status.event.goon) { + if ( + get.tag(card, "damage") && + game.hasPlayer(function (current) { + current != player && + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") && + !current.hasJudge("lebu") && + current.hasValueTarget(card); + }) + ) + return 1; + return 1 / Math.max(0.1, get.value(card)); } return 0; }, - ai2:function(target){ - return Math.sqrt(5-Math.min(4,target.countCards('h')))*get.attitude(_status.event.player,target); + ai2: function (target) { + return ( + Math.sqrt(5 - Math.min(4, target.countCards("h"))) * + get.attitude(_status.event.player, target) + ); }, - goon:function(){ - if(!game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain')&&!current.hasJudge('lebu'); - })) return 1; - if(num 0 && + !current.hasSkillTag("nogain") && + !current.hasJudge("lebu") + ); + }) + ) + return 1; + if (num < player.countCards("h")) return num + 1; return 1; - }(), + })(), }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var num=player.countMark('cslilu'); - player.give(result.cards,result.targets[0]); - if(result.cards.length>num){ + } else event.finish(); + "step 3"; + if (result.bool) { + var num = player.countMark("cslilu"); + player.give(result.cards, result.targets[0]); + if (result.cards.length > num) { player.gainMaxHp(); player.recover(); } - player.storage.cslilu=result.cards.length; - player.markSkill('cslilu'); + player.storage.cslilu = result.cards.length; + player.markSkill("cslilu"); } }, }, - csyizheng:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('csyizheng'),lib.filter.notMe).set('ai',function(target){ - if(target.isTurnedOver()||target.hasJudge('lebu')) return 0; - return get.attitude(_status.event.player,target)*Math.max(0,target.countCards('h')-2); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('csyizheng',target); - player.storage.csyizheng2=target; - player.addTempSkill('csyizheng2',{player:'phaseBegin'}); + csyizheng: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("csyizheng"), lib.filter.notMe) + .set("ai", function (target) { + if (target.isTurnedOver() || target.hasJudge("lebu")) return 0; + return ( + get.attitude(_status.event.player, target) * + Math.max(0, target.countCards("h") - 2) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("csyizheng", target); + player.storage.csyizheng2 = target; + player.addTempSkill("csyizheng2", { player: "phaseBegin" }); } }, }, - csyizheng2:{ - audio:'csyizheng', - trigger:{ - global:['recoverBegin','damageBegin1'], + csyizheng2: { + audio: "csyizheng", + trigger: { + global: ["recoverBegin", "damageBegin1"], }, - forced:true, - charlotte:true, - logTarget:function(event){ - return event.name=='damage'?event.source:event.player; + forced: true, + charlotte: true, + logTarget: function (event) { + return event.name == "damage" ? event.source : event.player; }, - filter:function(event,player){ - var target=lib.skill.csyizheng2.logTarget(event); - if(target!=player.storage.csyizheng2) return false; - return player.maxHp>target.maxHp; + filter: function (event, player) { + var target = lib.skill.csyizheng2.logTarget(event); + if (target != player.storage.csyizheng2) return false; + return player.maxHp > target.maxHp; }, - content:function(){ + content: function () { player.loseMaxHp(); trigger.num++; }, - mark:'character', - intro:{ - content:'$造成伤害或回复体力时,若你的体力上限大于其,则你减1点体力上限,然后此伤害/回复量+1', + mark: "character", + intro: { + content: + "$造成伤害或回复体力时,若你的体力上限大于其,则你减1点体力上限,然后此伤害/回复量+1", }, }, - reyixiang:{ - audio:'yixiang', - audioname:['re_taoqian'], - trigger:{player:'damageBegin1'}, - forced:true, - filter:function(event,player){ - var evt=event.getParent(2); - if(evt.name!='useCard'||evt.card!=event.card) return false; - var source=evt.player; - var phsu=evt.getParent('phaseUse'); - if(!source||source==player||source!=phsu.player) return false; - return source.getHistory('useCard',function(evt2){ - return evt2.getParent('phaseUse')==phsu; - })[0]==evt; + reyixiang: { + audio: "yixiang", + audioname: ["re_taoqian"], + trigger: { player: "damageBegin1" }, + forced: true, + filter: function (event, player) { + var evt = event.getParent(2); + if (evt.name != "useCard" || evt.card != event.card) return false; + var source = evt.player; + var phsu = evt.getParent("phaseUse"); + if (!source || source == player || source != phsu.player) return false; + return ( + source.getHistory("useCard", function (evt2) { + return evt2.getParent("phaseUse") == phsu; + })[0] == evt + ); }, - content:function(){ + content: function () { trigger.num--; }, - group:'reyixiang_card', - subSkill:{ - card:{ - audio:'yixiang', - audioname:['re_taoqian'], - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - if(get.color(event.card)!='black') return false; - var evt=event.getParent(); - var source=evt.player; - var phsu=evt.getParent('phaseUse'); - if(!source||source==player||source!=phsu.player) return false; - return source.getHistory('useCard',function(evt2){ - return evt2.getParent('phaseUse')==phsu; - }).indexOf(evt)==1; + group: "reyixiang_card", + subSkill: { + card: { + audio: "yixiang", + audioname: ["re_taoqian"], + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + if (get.color(event.card) != "black") return false; + var evt = event.getParent(); + var source = evt.player; + var phsu = evt.getParent("phaseUse"); + if (!source || source == player || source != phsu.player) return false; + return ( + source + .getHistory("useCard", function (evt2) { + return evt2.getParent("phaseUse") == phsu; + }) + .indexOf(evt) == 1 + ); }, - content:function(){ + content: function () { trigger.excluded.add(player); }, }, }, - ai:{ - effect:{ - target:function(card,player,target,current,isLink){ - if(isLink||typeof card!=='object'||!player.isPhaseUsing()) return; + ai: { + effect: { + target: function (card, player, target, current, isLink) { + if (isLink || typeof card !== "object" || !player.isPhaseUsing()) return; var num; - var evt=_status.event.getParent('useCard'),evt2=_status.event.getParent('phaseUse'); - if(evt.card==card){ - num=player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==evt2; - }).indexOf(evt); + var evt = _status.event.getParent("useCard"), + evt2 = _status.event.getParent("phaseUse"); + if (evt.card == card) { + num = player + .getHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == evt2; + }) + .indexOf(evt); + } else + num = player.getHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == evt2; + }).length; + if (num < 0 || num > 1) return; + if (num === 0 && get.tag(card, "damage")) { + if ( + target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) || + !player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }) + ) + return "zerotarget"; + return [0.5, 0, 0.5, 0]; } - else num=player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==evt2; - }).length; - if(num<0||num>1) return; - if(num===0&&get.tag(card,'damage')){ - if(target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })||!player.hasSkillTag('damageBonus',true,{ - target:target, - card:card - })) return 'zerotarget'; - return [0.5,0,0.5,0]; - } - if(num===1&&get.color(card)=='black') return 'zeroplayertarget'; + if (num === 1 && get.color(card) == "black") return "zeroplayertarget"; }, }, }, }, //赵忠 - yangzhong:{ - audio:2, - trigger:{ - source:'damageSource', - player:'damageEnd', + yangzhong: { + audio: 2, + trigger: { + source: "damageSource", + player: "damageEnd", }, - direct:true, - filter:function(event,player){ - var target=event.player,source=event.source; - if(player!=source&&!player.hasSkill('yangzhong')) return false; - if(!target||!source||!target.isIn()||!source.isIn()) return false; - return source.countCards('he')>1; + direct: true, + filter: function (event, player) { + var target = event.player, + source = event.source; + if (player != source && !player.hasSkill("yangzhong")) return false; + if (!target || !source || !target.isIn() || !source.isIn()) return false; + return source.countCards("he") > 1; }, - content:function(){ - 'step 0' - trigger.source.chooseToDiscard('是否对'+get.translation(trigger.player)+'发动【殃众】?','弃置两张牌,并令其失去1点体力','he',2).set('ai',function(card){ - var evt=_status.event; - if(get.attitude(evt.player,evt.getTrigger().player)>=0) return 0; - return 7-get.value(card); - }).logSkill=['yangzhong',trigger.player]; - 'step 1' - if(result.bool) trigger.player.loseHp(); + content: function () { + "step 0"; + trigger.source + .chooseToDiscard( + "是否对" + get.translation(trigger.player) + "发动【殃众】?", + "弃置两张牌,并令其失去1点体力", + "he", + 2 + ) + .set("ai", function (card) { + var evt = _status.event; + if (get.attitude(evt.player, evt.getTrigger().player) >= 0) return 0; + return 7 - get.value(card); + }).logSkill = ["yangzhong", trigger.player]; + "step 1"; + if (result.bool) trigger.player.loseHp(); }, }, - huangkong:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - if(player==_status.currentPhase||player.countCards('h')) return false; - return event.card.name=='sha'||get.type(event.card,false)=='trick'; + huangkong: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + if (player == _status.currentPhase || player.countCards("h")) return false; + return event.card.name == "sha" || get.type(event.card, false) == "trick"; }, - content:function(){ + content: function () { player.draw(2); }, }, - hfjieying:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('hfjieying'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target)*(1+target.countCards('h',function(card){ - return !get.tag(card,'damage')&&target.hasValueTarget(card); - }))/(1+target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('hfjieying',target); - target.addTempSkill('hfjieying2',{player:'phaseJieshuBegin'}); + hfjieying: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("hfjieying"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + return ( + (get.attitude(player, target) * + (1 + + target.countCards("h", function (card) { + return !get.tag(card, "damage") && target.hasValueTarget(card); + }))) / + (1 + target.countCards("h")) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("hfjieying", target); + target.addTempSkill("hfjieying2", { player: "phaseJieshuBegin" }); } }, - ai:{ - expose:0.05, + ai: { + expose: 0.05, }, }, - hfjieying2:{ - mod:{ - cardEnabled:function(card,player){ - if(player.storage.hfjieying2) return false; + hfjieying2: { + mod: { + cardEnabled: function (card, player) { + if (player.storage.hfjieying2) return false; }, - cardSavable:function(card,player){ - if(player.storage.hfjieying2) return false; + cardSavable: function (card, player) { + if (player.storage.hfjieying2) return false; }, - targetInRange:function(card,player){ - if(player==_status.currentPhase&&(card.name=='sha'||get.type(card)=='trick')) return true; + targetInRange: function (card, player) { + if ( + player == _status.currentPhase && + (card.name == "sha" || get.type(card) == "trick") + ) + return true; }, - aiOrder:function(player,card,num){ - var info=get.info(card); - if(!get.tag(card,'damage')&&(!info||!info.toself)) return num+8; + aiOrder: function (player, card, num) { + var info = get.info(card); + if (!get.tag(card, "damage") && (!info || !info.toself)) return num + 8; }, }, - onremove:true, - trigger:{player:'useCard2'}, - direct:true, - charlotte:true, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - var card=event.card; - if(card.name!='sha'&&get.type(card)!='trick')return false; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current); - })){ + onremove: true, + trigger: { player: "useCard2" }, + direct: true, + charlotte: true, + filter: function (event, player) { + if (player != _status.currentPhase || event.targets.length != 1) return false; + var card = event.card; + if (card.name != "sha" && get.type(card) != "trick") return false; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('hfjieying2'),function(card,player,target){ - var player=_status.event.player; - return !_status.event.targets.includes(target)&&lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('card',trigger.card).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget(get.prompt("hfjieying2"), function (card, player, target) { + var player = _status.event.player; + return ( + !_status.event.targets.includes(target) && + lib.filter.targetEnabled2(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("card", trigger.card) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('hfjieying2',event.targets); + "step 2"; + if (event.targets) { + player.logSkill("hfjieying2", event.targets); trigger.targets.addArray(event.targets); } }, - group:'hfjieying3', - mark:true, - intro:{ - content:function(player){ - if(player) return '不能使用牌直到回合结束'; - return '使用【杀】或普通锦囊牌时无距离限制且可以多指定一个目标'; + group: "hfjieying3", + mark: true, + intro: { + content: function (player) { + if (player) return "不能使用牌直到回合结束"; + return "使用【杀】或普通锦囊牌时无距离限制且可以多指定一个目标"; }, }, }, - hfjieying3:{ - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter:function(event,player){ - return !player.storage.hfjieying2&&player==_status.currentPhase; + hfjieying3: { + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter: function (event, player) { + return !player.storage.hfjieying2 && player == _status.currentPhase; }, - content:function(){ - player.storage.hfjieying2=true; + content: function () { + player.storage.hfjieying2 = true; }, }, - weipo:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&!player.hasSkill('weipo3')&&player.countCards('h')player.countCards('h'); + weipo2: { + charlotte: true, + trigger: { global: "useCardAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.weipo && + event.weipo[player.playerid] != undefined && + event.weipo[player.playerid] > player.countCards("h") + ); }, - content:function(){ - 'step 0' - player.addTempSkill('weipo3',{player:'phaseBegin'}); - if(player.countCards('h')&&trigger.player.isIn()){ - player.chooseCard('h',true,'将一张手牌交给'+get.translation(trigger.player)); - } - else event.finish(); - 'step 1' - if(result.bool){ - player.give(result.cards,trigger.player); + content: function () { + "step 0"; + player.addTempSkill("weipo3", { player: "phaseBegin" }); + if (player.countCards("h") && trigger.player.isIn()) { + player.chooseCard("h", true, "将一张手牌交给" + get.translation(trigger.player)); + } else event.finish(); + "step 1"; + if (result.bool) { + player.give(result.cards, trigger.player); } }, }, - weipo3:{charlotte:true}, - refuqi:{ - audio:'fuqi', - forced:true, - trigger:{ - player:"useCard", + weipo3: { charlotte: true }, + refuqi: { + audio: "fuqi", + forced: true, + trigger: { + player: "useCard", }, - filter:function(event,player){ - return event.card&&(get.type(event.card)=='trick'||get.type(event.card)=='basic'&&!['shan','tao','jiu','du'].includes(event.card.name))&&game.hasPlayer(function(current){ - return current!=player&&get.distance(player,current)<=1; - }); + filter: function (event, player) { + return ( + event.card && + (get.type(event.card) == "trick" || + (get.type(event.card) == "basic" && + !["shan", "tao", "jiu", "du"].includes(event.card.name))) && + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) <= 1; + }) + ); }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player&&get.distance(player,current)<=1; - })); + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player && get.distance(player, current) <= 1; + }) + ); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return get.distance(player,arg.target)<=1; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return get.distance(player, arg.target) <= 1; }, }, }, - zhuide:{ - audio:2, - trigger:{player:'die'}, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('zhuide'),lib.filter.notMe).set('ai',function(target){ - return get.attitude(_status.event.player,target); + zhuide: { + audio: 2, + trigger: { player: "die" }, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("zhuide"), lib.filter.notMe).set("ai", function (target) { + return get.attitude(_status.event.player, target); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhuide',target); - var names=[]; - var cards=[]; - while(cards.length<4){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&!names.includes(card.name)&&get.type(card)=='basic'; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhuide", target); + var names = []; + var cards = []; + while (cards.length < 4) { + var card = get.cardPile2(function (card) { + return ( + !cards.includes(card) && + !names.includes(card.name) && + get.type(card) == "basic" + ); }); - if(card){ + if (card) { cards.push(card); names.push(card.name); - } - else break; + } else break; } - if(cards.length) target.gain(cards,'gain2'); + if (cards.length) target.gain(cards, "gain2"); } }, }, - juntun:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.maxHp>1; + juntun: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.maxHp > 1; }, - content:function(){ + content: function () { player.loseMaxHp(); player.draw(player.maxHp); }, }, - jiaojie:{ - audio:2, - mod:{ - ignoredHandcard:function(card,player){ - if(get.color(card)=='red'){ + jiaojie: { + audio: 2, + mod: { + ignoredHandcard: function (card, player) { + if (get.color(card) == "red") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.color(card)=='red'){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.color(card) == "red") { return false; } }, - targetInRange:function(card){ + targetInRange: function (card) { const color = get.color(card); - if (color === 'black' || color === 'unsure') return true; + if (color === "black" || color === "unsure") return true; }, - cardUsable:function(card){ + cardUsable: function (card) { const color = get.color(card); - if (color === 'black' || color === 'unsure') return Infinity; + if (color === "black" || color === "unsure") return Infinity; }, }, }, - decadewuniang:{ - trigger:{ - player:["useCard","respond"], + decadewuniang: { + trigger: { + player: ["useCard", "respond"], }, - audio:'xinfu_wuniang', - direct:true, - filter:function(event,player){ - return event.card.name=='sha'; + audio: "xinfu_wuniang", + direct: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('decadewuniang'),function(card,player,target){ - if(player==target) return false; - return target.countGainableCards(player,'he')>0; - }).set('ai',function(target){ - return 10-get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('decadewuniang',target); - player.line(target,'fire'); - player.gainPlayerCard(target,'he',true); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("decadewuniang"), function (card, player, target) { + if (player == target) return false; + return target.countGainableCards(player, "he") > 0; + }) + .set("ai", function (target) { + return 10 - get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("decadewuniang", target); + player.line(target, "fire"); + player.gainPlayerCard(target, "he", true); target.draw(); - if(!player.storage.decadexushen) event.finish(); - } - else event.finish(); - 'step 2' - var list=game.filterPlayer(function(current){ - return current.name=='dc_guansuo'||current.name2=='dc_guansuo'; + if (!player.storage.decadexushen) event.finish(); + } else event.finish(); + "step 2"; + var list = game.filterPlayer(function (current) { + return current.name == "dc_guansuo" || current.name2 == "dc_guansuo"; }); - if(list.length) game.asyncDraw(list); + if (list.length) game.asyncDraw(list); else event.finish(); - 'step 3' + "step 3"; game.delayx(); }, }, - minsi:{ - audio:2, - enable:'phaseUse', - getResult:function(cards){ - var l=cards.length; - var all=Math.pow(l,2); - var list=[]; - for(var i=1;i0) array.push(cards[j]) + minsi: { + audio: 2, + enable: "phaseUse", + getResult: function (cards) { + var l = cards.length; + var all = Math.pow(l, 2); + var list = []; + for (var i = 1; i < all; i++) { + var array = []; + for (var j = 0; j < l; j++) { + if (Math.floor((i % Math.pow(2, j + 1)) / Math.pow(2, j)) > 0) + array.push(cards[j]); } - var num=0; - for(var k of array){ - num+=get.number(k); + var num = 0; + for (var k of array) { + num += get.number(k); } - if(num==13) list.push(array); + if (num == 13) list.push(array); } - if(list.length){ - list.sort(function(a,b){ - if(a.length!=b.length) return b.length-a.length; - return get.value(a)-get.value(b); + if (list.length) { + list.sort(function (a, b) { + if (a.length != b.length) return b.length - a.length; + return get.value(a) - get.value(b); }); return list[0]; } return list; }, - usable:1, - filterCard:function(card){ - var num=0; - for(var i=0;i0) array.push(cards[j]) + "step 1"; + var num = result.number; + var next = player.chooseToDiscard( + "是否弃置任意张点数之和为" + get.cnNumber(num) + "的牌并回复1点体力?", + function (card) { + var num = 0; + for (var i = 0; i < ui.selected.cards.length; i++) { + num += get.number(ui.selected.cards[i]); } - var numx=0; - for(var k of array){ - numx+=get.number(k); - } - if(numx==num) list.push(array); + return get.number(card) + num <= _status.event.num; + }, + "he" + ); + next.set("num", num); + next.set("complexCard", true); + next.set("selectCard", function () { + var num = 0; + for (var i = 0; i < ui.selected.cards.length; i++) { + num += get.number(ui.selected.cards[i]); } - if(list.length){ - list.sort(function(a,b){ - return get.value(a)-get.value(b); - }); - return list[0]; - } - return list; - }()); - next.set('ai',function(card){ - if(!_status.event.cardResult.includes(card)) return 0; - return 6-get.value(card); + if (num == _status.event.num) return ui.selected.cards.length; + return ui.selected.cards.length + 2; }); - 'step 2' - if(result.bool) player.recover(); + next.set( + "cardResult", + (function () { + var cards = player.getCards("he"); + var l = cards.length; + var all = Math.pow(l, 2); + var list = []; + for (var i = 1; i < all; i++) { + var array = []; + for (var j = 0; j < l; j++) { + if (Math.floor((i % Math.pow(2, j + 1)) / Math.pow(2, j)) > 0) + array.push(cards[j]); + } + var numx = 0; + for (var k of array) { + numx += get.number(k); + } + if (numx == num) list.push(array); + } + if (list.length) { + list.sort(function (a, b) { + return get.value(a) - get.value(b); + }); + return list[0]; + } + return list; + })() + ); + next.set("ai", function (card) { + if (!_status.event.cardResult.includes(card)) return 0; + return 6 - get.value(card); + }); + "step 2"; + if (result.bool) player.recover(); }, }, - cixiao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - if(!game.hasPlayer(function(current){ - return current.hasSkill('panshi'); - })) return true; - return player.countCards('he')>=1&&game.hasPlayer(function(current){ - return current!=player&&!current.hasSkill('panshi'); - }); + cixiao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + if ( + !game.hasPlayer(function (current) { + return current.hasSkill("panshi"); + }) + ) + return true; + return ( + player.countCards("he") >= 1 && + game.hasPlayer(function (current) { + return current != player && !current.hasSkill("panshi"); + }) + ); }, - content:function(){ - 'step 0' - if(game.hasPlayer(function(current){ - return current.hasSkill('panshi'); - })) event.goto(2); - else player.chooseTarget(lib.filter.notMe,get.prompt('cixiao'),'令一名其他角色获得「义子」标记').set('ai',function(target){ - var player=_status.event.player; - var att=-get.attitude(player,target); - return att*target.countCards('h'); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('cixiao',target); - target.addSkills('panshi'); + content: function () { + "step 0"; + if ( + game.hasPlayer(function (current) { + return current.hasSkill("panshi"); + }) + ) + event.goto(2); + else + player + .chooseTarget( + lib.filter.notMe, + get.prompt("cixiao"), + "令一名其他角色获得「义子」标记" + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = -get.attitude(player, target); + return att * target.countCards("h"); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("cixiao", target); + target.addSkills("panshi"); } event.finish(); - 'step 2' - var list=game.filterPlayer(function(current){ - return current.hasSkill('panshi'); + "step 2"; + var list = game.filterPlayer(function (current) { + return current.hasSkill("panshi"); }); player.chooseCardTarget({ - prompt:get.prompt('cixiao'), - prompt2:('弃置一张牌并将'+get.translation(list)+'的「义子」标记转移给其他角色'), - position:'he', - filterTarget:function(card,player,target){ - return player!=target&&!target.hasSkill('panshi'); + prompt: get.prompt("cixiao"), + prompt2: "弃置一张牌并将" + get.translation(list) + "的「义子」标记转移给其他角色", + position: "he", + filterTarget: function (card, player, target) { + return player != target && !target.hasSkill("panshi"); }, - filterCard:lib.filter.cardDiscardable, - ai1:function(card){ - if(_status.event.goon) return 5-get.value(card); + filterCard: lib.filter.cardDiscardable, + ai1: function (card) { + if (_status.event.goon) return 5 - get.value(card); return 0; }, - ai2:function(target){ - var player=_status.event.player; - var att=-get.attitude(player,target); - return att*target.countCards('h'); + ai2: function (target) { + var player = _status.event.player; + var att = -get.attitude(player, target); + return att * target.countCards("h"); }, - goon:function(target){ - var att=-get.attitude(player,target); - return att*target.countCards('h')<=0; - }(list[0]), + goon: (function (target) { + var att = -get.attitude(player, target); + return att * target.countCards("h") <= 0; + })(list[0]), }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('cixiao'); - player.discard(result.cards).delay=false; - player.line2(game.filterPlayer(function(current){ - if(current.hasSkill('panshi')){ - current.removeSkills('panshi'); - return true; - } - }).concat(result.targets),'green'); - target.addSkills('panshi'); - } - else event.finish(); - 'step 4' + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("cixiao"); + player.discard(result.cards).delay = false; + player.line2( + game + .filterPlayer(function (current) { + if (current.hasSkill("panshi")) { + current.removeSkills("panshi"); + return true; + } + }) + .concat(result.targets), + "green" + ); + target.addSkills("panshi"); + } else event.finish(); + "step 4"; game.delayx(); }, - derivation:'panshi', - ai:{threaten:8}, + derivation: "panshi", + ai: { threaten: 8 }, }, - panshi:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('cixiao'); - }); + panshi: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return current != player && current.hasSkill("cixiao"); + }) + ); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('cixiao'); + content: function () { + "step 0"; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("cixiao"); }); - if(targets.length==1){ - event.target=targets[0]; - player.chooseCard('h',true,'叛弑:将一张手牌交给'+get.translation(targets)); - } - else player.chooseCardTarget({ - prompt:'叛弑:将一张手牌交给'+get.translation(targets)+'中的一名角色', - filterCard:true, - position:'h', - targets:targets, - forced:true, - filterTarget:function(card,player,target){ - return _status.event.targets.includes(target); - }, - }); - 'step 1' - if(result.bool){ - if(!target) target=result.targets[0]; + if (targets.length == 1) { + event.target = targets[0]; + player.chooseCard("h", true, "叛弑:将一张手牌交给" + get.translation(targets)); + } else + player.chooseCardTarget({ + prompt: "叛弑:将一张手牌交给" + get.translation(targets) + "中的一名角色", + filterCard: true, + position: "h", + targets: targets, + forced: true, + filterTarget: function (card, player, target) { + return _status.event.targets.includes(target); + }, + }); + "step 1"; + if (result.bool) { + if (!target) target = result.targets[0]; player.line(target); - player.give(result.cards,target); + player.give(result.cards, target); } }, - mark:true, - marktext:'子', - intro:{ - name:'义子', + mark: true, + marktext: "子", + intro: { + name: "义子", //content:'我是儿子', //R·I·P——永远怀念:被棘手砍掉的“我是儿子” - content(_,player){ - const targets=game.filterPlayer2(target=>target.hasSkill('cixiao',null,null,false)).sortBySeat(player); - if(!targets.length) return '我义父呢?!'; - if(['name','name1','name2'].some(name=>{ - if(!player[name]||!get.character(player[name])||typeof get.translation(player[name])!='string') return false; - return player[name].includes('lvbu')&&get.translation(player[name]).includes('吕布'); - })) return '公若不弃,布愿拜为义父'; - return '我是'+get.translation(targets)+'的'+((player)=>{ - switch(player.sex){ - case 'female': - return '义女'; - case 'double': - return '义子义女'; - default: - return '义子'; - } - })(player); + content(_, player) { + const targets = game + .filterPlayer2((target) => target.hasSkill("cixiao", null, null, false)) + .sortBySeat(player); + if (!targets.length) return "我义父呢?!"; + if ( + ["name", "name1", "name2"].some((name) => { + if ( + !player[name] || + !get.character(player[name]) || + typeof get.translation(player[name]) != "string" + ) + return false; + return ( + player[name].includes("lvbu") && + get.translation(player[name]).includes("吕布") + ); + }) + ) + return "公若不弃,布愿拜为义父"; + return ( + "我是" + + get.translation(targets) + + "的" + + ((player) => { + switch (player.sex) { + case "female": + return "义女"; + case "double": + return "义子义女"; + default: + return "义子"; + } + })(player) + ); }, }, - group:'panshi_damage', + group: "panshi_damage", }, - panshi_damage:{ - trigger:{source:'damageBegin1'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return player.isPhaseUsing()&&event.card&&event.card.name=='sha'&&event.player.hasSkill('cixiao'); + panshi_damage: { + trigger: { source: "damageBegin1" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return ( + player.isPhaseUsing() && + event.card && + event.card.name == "sha" && + event.player.hasSkill("cixiao") + ); }, - content:function(){ + content: function () { trigger.num++; - if(['name','name1','name2'].some(name=>{ - if(!player[name]||!get.character(player[name])||typeof get.translation(player[name])!='string') return false; - return player[name].includes('lvbu')&&get.translation(player[name]).includes('吕布'); - })) player.chat('吾堂堂丈夫,安肯为汝子乎!'); - var evt=event.getParent('phaseUse'); - if(evt&&evt.player==player) evt.skipped=true; + if ( + ["name", "name1", "name2"].some((name) => { + if ( + !player[name] || + !get.character(player[name]) || + typeof get.translation(player[name]) != "string" + ) + return false; + return ( + player[name].includes("lvbu") && + get.translation(player[name]).includes("吕布") + ); + }) + ) + player.chat("吾堂堂丈夫,安肯为汝子乎!"); + var evt = event.getParent("phaseUse"); + if (evt && evt.player == player) evt.skipped = true; }, }, - xianshuai:{ - audio:2, - trigger:{global:'damageSource'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&!player.hasSkill('xianshuai2'); + xianshuai: { + audio: 2, + trigger: { global: "damageSource" }, + forced: true, + filter: function (event, player) { + return event.source && event.source.isIn() && !player.hasSkill("xianshuai2"); }, - content:function(){ - player.addTempSkill('xianshuai2','roundStart'); + content: function () { + player.addTempSkill("xianshuai2", "roundStart"); player.draw(); - if(player==trigger.source&&trigger.player.isIn()){ - player.line(trigger.player,'green'); + if (player == trigger.source && trigger.player.isIn()) { + player.line(trigger.player, "green"); trigger.player.damage(); } }, }, - xianshuai2:{charlotte:true}, - decadexushen:{ - derivation:'decadezhennan', - audio:'xinfu_xushen', - trigger:{player:'dying'}, - limited:true, - skillAnimation:true, - animationColor:'orange', - filter:function(event,player){ - return player.hp<1; + xianshuai2: { charlotte: true }, + decadexushen: { + derivation: "decadezhennan", + audio: "xinfu_xushen", + trigger: { player: "dying" }, + limited: true, + skillAnimation: true, + animationColor: "orange", + filter: function (event, player) { + return player.hp < 1; }, - content:function(){ - player.awakenSkill('decadexushen'); - player.addSkills('decadezhennan'); - player.addTempSkill('decadexushen2'); - trigger.decadexushen=true; + content: function () { + player.awakenSkill("decadexushen"); + player.addSkills("decadezhennan"); + player.addTempSkill("decadexushen2"); + trigger.decadexushen = true; player.recover(); }, }, - decadexushen2:{ - trigger:{player:'dyingAfter'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return event.decadexushen==true&&!game.hasPlayer(function(current){ - return current.name=='dc_guansuo'||current.name2=='dc_guansuo'; - }); + decadexushen2: { + trigger: { player: "dyingAfter" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return ( + event.decadexushen == true && + !game.hasPlayer(function (current) { + return current.name == "dc_guansuo" || current.name2 == "dc_guansuo"; + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,'许身:是否令一名其他角色选择是否将其武将牌替换为“关索”并令其摸三张牌?').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(!result.bool){ + content: function () { + "step 0"; + player + .chooseTarget( + lib.filter.notMe, + "许身:是否令一名其他角色选择是否将其武将牌替换为“关索”并令其摸三张牌?" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (!result.bool) { event.finish(); return; } - var target=result.targets[0]; - event.target=target; - player.line(target,'fire'); - target.chooseBool('许身:是否将自己的一张武将牌替换为“关索”并令'+get.translation(player)+'摸三张牌?'); - 'step 2' - if(result.bool){ - if(target.name2!=undefined){ - target.chooseControl(target.name1,target.name2).set('prompt','请选择要更换的武将牌'); - } - else event._result={control:target.name1}; - } - else event.goto(4); - 'step 3' - target.reinitCharacter(result.control,'dc_guansuo'); - 'step 4' + var target = result.targets[0]; + event.target = target; + player.line(target, "fire"); + target.chooseBool( + "许身:是否将自己的一张武将牌替换为“关索”并令" + + get.translation(player) + + "摸三张牌?" + ); + "step 2"; + if (result.bool) { + if (target.name2 != undefined) { + target + .chooseControl(target.name1, target.name2) + .set("prompt", "请选择要更换的武将牌"); + } else event._result = { control: target.name1 }; + } else event.goto(4); + "step 3"; + target.reinitCharacter(result.control, "dc_guansuo"); + "step 4"; target.draw(3); }, }, - decadezhennan:{ - audio:'xinfu_zhennan', - trigger:{ - global:"useCardToPlayered", + decadezhennan: { + audio: "xinfu_zhennan", + trigger: { + global: "useCardToPlayered", }, - filter:function(event,player){ - return event.isFirstTarget&&event.targets&&event.targets.length>1&&get.type2(event.card)=='trick'; + filter: function (event, player) { + return ( + event.isFirstTarget && + event.targets && + event.targets.length > 1 && + get.type2(event.card) == "trick" + ); }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('decadezhennan'),'对一名其他角色造成1点伤害',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('decadezhennan',result.targets); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("decadezhennan"), + "对一名其他角色造成1点伤害", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("decadezhennan", result.targets); result.targets[0].damage(); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - yujue:{ - audio:2, - derivation:'zhihu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ + yujue: { + audio: 2, + derivation: "zhihu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { return player.hasEnabledSlot(); }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('###鬻爵###'+lib.translate.yujue_info); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("###鬻爵###" + lib.translate.yujue_info); }, - chooseControl:function(event,player){ - var list=[]; - for(var i=1;i<6;i++){ - if(player.hasEnabledSlot(i)) list.push('equip'+i); + chooseControl: function (event, player) { + var list = []; + for (var i = 1; i < 6; i++) { + if (player.hasEnabledSlot(i)) list.push("equip" + i); } - list.push('cancel2'); + list.push("cancel2"); return list; }, - check:function(event,player){ - for(var i=5;i>0;i--){ - if(player.hasEmptySlot(i)) return ('equip'+i); + check: function (event, player) { + for (var i = 5; i > 0; i--) { + if (player.hasEmptySlot(i)) return "equip" + i; } - return 'cancel2'; + return "cancel2"; }, - backup:function(result){ - var next=get.copy(lib.skill.yujuex); - next.position=result.control; + backup: function (result) { + var next = get.copy(lib.skill.yujuex); + next.position = result.control; return next; }, }, - ai:{ - order:1, - result:{ - player:function(player){ - if(game.hasPlayer(function(target){ - if(player==target) return false; - var hs=target.countCards('h'); - return hs>2&&get.attitude(player,target)>0; - })) return 1; + ai: { + order: 1, + result: { + player: function (player) { + if ( + game.hasPlayer(function (target) { + if (player == target) return false; + var hs = target.countCards("h"); + return hs > 2 && get.attitude(player, target) > 0; + }) + ) + return 1; return 0; }, }, }, }, - yujuex:{ - audio:'yujue', - async content(event,trigger,player){ + yujuex: { + audio: "yujue", + async content(event, trigger, player) { await player.disableEquip(lib.skill.yujue_backup.position); - if(player.isIn()&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); - })){ - const result = await player.chooseTarget(true,'选择一名角色交给你一张牌并获得技能〖执笏〗',function(card,player,target){ - if(player==target) return false; - return target.countCards('h')>0; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)*target.countCards('h'); - }).forResult(); - if(result.bool){ - var target=result.targets[0]; - event.target=target; + if ( + player.isIn() && + game.hasPlayer(function (current) { + return current != player && current.countCards("h"); + }) + ) { + const result = await player + .chooseTarget( + true, + "选择一名角色交给你一张牌并获得技能〖执笏〗", + function (card, player, target) { + if (player == target) return false; + return target.countCards("h") > 0; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) * target.countCards("h"); + }) + .forResult(); + if (result.bool) { + var target = result.targets[0]; + event.target = target; player.line(target); - const result2 = await target.chooseCard('h',true,'交给'+get.translation(player)+'一张手牌').forResult(); - if(result2.bool&&result2.cards&&result2.cards.length){ - await target.give(result2.cards,player); - target.storage.zhihu_mark=player; - await target.addSkills('zhihu'); - target.addSkill('zhihu_mark'); + const result2 = await target + .chooseCard("h", true, "交给" + get.translation(player) + "一张手牌") + .forResult(); + if (result2.bool && result2.cards && result2.cards.length) { + await target.give(result2.cards, player); + target.storage.zhihu_mark = player; + await target.addSkills("zhihu"); + target.addSkill("zhihu_mark"); } } } }, }, - zhihu:{ - usable:2, - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - return player!=event.player; + zhihu: { + usable: 2, + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + return player != event.player; }, - content:function(){ + content: function () { player.draw(2); }, }, - zhihu_mark:{ - mark:'character', - intro:{ - content:'以$之名,授予汝技能〖执笏〗,直至$的下回合开始为止!', + zhihu_mark: { + mark: "character", + intro: { + content: "以$之名,授予汝技能〖执笏〗,直至$的下回合开始为止!", }, - onremove:function(player){ + onremove: function (player) { delete player.storage.zhihu_mark; - player.removeSkills('zhihu'); + player.removeSkills("zhihu"); }, - trigger:{global:'phaseBeginStart'}, - firstDo:true, - charlotte:true, - silent:true, - filter:function(event,player){ - return event.player==player.storage.zhihu_mark; + trigger: { global: "phaseBeginStart" }, + firstDo: true, + charlotte: true, + silent: true, + filter: function (event, player) { + return event.player == player.storage.zhihu_mark; }, - content:function(){ - player.removeSkill('zhihu_mark'); + content: function () { + player.removeSkill("zhihu_mark"); }, }, - tuxing:{ - audio:2, - trigger:{player:'disableEquipAfter'}, - forced:true, - content:function(){ - 'step 0' + tuxing: { + audio: 2, + trigger: { player: "disableEquipAfter" }, + forced: true, + content: function () { + "step 0"; player.gainMaxHp(); player.recover(); - 'step 1' - if(!player.hasEnabledSlot()){ + "step 1"; + if (!player.hasEnabledSlot()) { player.loseMaxHp(4); - player.addSkill('tuxing2'); + player.addSkill("tuxing2"); } - } + }, }, - tuxing2:{ - audio:'tuxing', - trigger:{source:'damageBegin1'}, - forced:true, - charlotte:true, - content:function(){ + tuxing2: { + audio: "tuxing", + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + content: function () { trigger.num++; }, - mark:true, - intro:{ - content:'造成伤害时,此伤害+1', + mark: true, + intro: { + content: "造成伤害时,此伤害+1", }, }, - gongjian:{ - audio:2, - trigger:{global:'useCardToPlayered'}, - usable:1, - logTarget:function(event){ - return event.parent.gongjian_targets.filter(function(target){ - return event.targets.includes(target)&&target.countCards('he')>0; + gongjian: { + audio: 2, + trigger: { global: "useCardToPlayered" }, + usable: 1, + logTarget: function (event) { + return event.parent.gongjian_targets.filter(function (target) { + return event.targets.includes(target) && target.countCards("he") > 0; }); }, - filter:function(event,player){ - if(event.card.name!='sha'||!event.isFirstTarget) return false; - if(event.parent.gongjian_targets&&event.parent.gongjian_targets.filter(function(target){ - return event.targets.includes(target)&&target.countCards('he')>0; - }).length>0) return true; + filter: function (event, player) { + if (event.card.name != "sha" || !event.isFirstTarget) return false; + if ( + event.parent.gongjian_targets && + event.parent.gongjian_targets.filter(function (target) { + return event.targets.includes(target) && target.countCards("he") > 0; + }).length > 0 + ) + return true; return false; }, - check:function(event,player){ - var targets=event.parent.gongjian_targets.filter(function(target){ - return event.targets.includes(target)&&target.countCards('he')>0; - }),att=0; - for(var i of targets){ - att+=get.attitude(player,i); + check: function (event, player) { + var targets = event.parent.gongjian_targets.filter(function (target) { + return event.targets.includes(target) && target.countCards("he") > 0; + }), + att = 0; + for (var i of targets) { + att += get.attitude(player, i); } - return att<0; + return att < 0; }, - content:function(){ - 'step 0' - event.targets=trigger.parent.gongjian_targets.filter(function(target){ + content: function () { + "step 0"; + event.targets = trigger.parent.gongjian_targets.filter(function (target) { return trigger.targets.includes(target); }); - event.num=0; - 'step 1' - var target=targets[num]; - player.discardPlayerCard(target,true,'he',[1,2]).set('forceAuto',true); - 'step 2' + event.num = 0; + "step 1"; + var target = targets[num]; + player.discardPlayerCard(target, true, "he", [1, 2]).set("forceAuto", true); + "step 2"; event.num++; - if(event.num0; + kuimang: { + audio: 2, + trigger: { global: "dieAfter" }, + forced: true, + filter: function (event, player) { + return ( + player.getAllHistory("sourceDamage", function (target) { + return target.player == event.player; + }).length > 0 + ); }, - content:function(){ + content: function () { player.draw(2); }, }, - rexiemu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return !game.hasPlayer(function(current){ - return current.hasMark('rexiemu'); + rexiemu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return !game.hasPlayer(function (current) { + return current.hasMark("rexiemu"); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('rexiemu'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target)*Math.sqrt(Math.max(1+player.countCards('h'),1+target.countCards('h'))); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('rexiemu',target); - target.addMark('rexiemu',1); - player.addSkill('rexiemu2'); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("rexiemu"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.attitude(player, target) * + Math.sqrt(Math.max(1 + player.countCards("h"), 1 + target.countCards("h"))) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("rexiemu", target); + target.addMark("rexiemu", 1); + player.addSkill("rexiemu2"); } }, - intro:{content:'mark'}, - ai:{ - expose:0.1, + intro: { content: "mark" }, + ai: { + expose: 0.1, }, }, - rexiemu2:{ - audio:'rexiemu', - trigger:{global:['loseAfter']}, - forced:true, - charlotte:true, - usable:1, - filter:function(event,player){ - return (event.player==player||event.player.hasMark('rexiemu'))&&['useCard','respond'].includes(event.getParent().name)&&event.hs&&event.hs.length&& - event.player!=_status.currentPhase&&game.hasPlayer(function(current){ - return current.hasMark('rexiemu'); - }); + rexiemu2: { + audio: "rexiemu", + trigger: { global: ["loseAfter"] }, + forced: true, + charlotte: true, + usable: 1, + filter: function (event, player) { + return ( + (event.player == player || event.player.hasMark("rexiemu")) && + ["useCard", "respond"].includes(event.getParent().name) && + event.hs && + event.hs.length && + event.player != _status.currentPhase && + game.hasPlayer(function (current) { + return current.hasMark("rexiemu"); + }) + ); }, - content:function(){ - 'step 0' - game.asyncDraw(game.filterPlayer(function(current){ - return current==player||current==trigger.player||current.hasMark('rexiemu'); - })); - 'step 1' + content: function () { + "step 0"; + game.asyncDraw( + game.filterPlayer(function (current) { + return ( + current == player || current == trigger.player || current.hasMark("rexiemu") + ); + }) + ); + "step 1"; game.delayx(); }, - group:'rexiemu3', + group: "rexiemu3", }, - rexiemu3:{ - trigger:{player:'phaseBegin'}, - forced:true, - charlotte:true, - silent:true, - firstDo:true, - content:function(){ - player.removeSkill('rexiemu2'); - game.countPlayer(function(current){ - var num=current.countMark('rexiemu'); - if(num) current.removeMark('rexiemu',num); + rexiemu3: { + trigger: { player: "phaseBegin" }, + forced: true, + charlotte: true, + silent: true, + firstDo: true, + content: function () { + player.removeSkill("rexiemu2"); + game.countPlayer(function (current) { + var num = current.countMark("rexiemu"); + if (num) current.removeMark("rexiemu", num); }); }, }, - heli:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.heli.filterTarget(null,player,current); + heli: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return lib.skill.heli.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - return target.countCards('h')=1&&number<=13; + content: function () { + "step 0"; + var number = trigger.getl(player).cards2[0].number; + var numbers = [number - 2, number - 1, number, number + 1, number + 2].filter(function ( + number + ) { + return number >= 1 && number <= 13; }); - if(player.isUnderControl()){ + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ - _status.imchoosing=false; - event._result={ - bool:true, - suit:lib.suit.randomGet(), - number:numbers.randomGet(), + var switchToAuto = function () { + _status.imchoosing = false; + event._result = { + bool: true, + suit: lib.suit.randomGet(), + number: numbers.randomGet(), }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); }; - var chooseButton=function(player,numbers){ - var event=_status.event; - player=player||event.player; - if(!event._result) event._result={}; - var dialog=ui.create.dialog('是否发动【墨影】?','forcebutton','hidden'); - event.dialog=dialog; - dialog.addText('花色'); - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var listi=['spade','heart','club','diamond']; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + td.innerHTML = "" + get.translation(listi[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.suit=link; + this.classList.add("bluebg"); + event._result.suit = link; }); } dialog.content.appendChild(table); - dialog.addText('点数'); - var table2=document.createElement('div'); - table2.classList.add('add-setting'); - table2.style.margin='0'; - table2.style.width='100%'; - table2.style.position='relative'; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + td.innerHTML = "" + num + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.number=link; + this.classList.add("bluebg"); + event._result.number = link; }); } dialog.content.appendChild(table2); - dialog.add('  '); + dialog.add("  "); event.dialog.open(); - event.switchToAuto=function(){ - event._result={ - bool:true, - number:numbers.randomGet(), - suit:lib.suit.randomGet(), + event.switchToAuto = function () { + event._result = { + bool: true, + number: numbers.randomGet(), + suit: lib.suit.randomGet(), }; event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok','cancel2',function(link){ - var result=event._result; - if(link=='cancel2') result.bool=false; - else{ - if(!result.number||!result.suit) return; - result.bool=true; + event.control = ui.create.control("ok", "cancel2", function (link) { + var result = event._result; + if (link == "cancel2") result.bool = false; + else { + if (!result.number || !result.suit) return; + result.bool = true; } event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;i0&&player.countCards('hs')>0; + group: "juanhui3", + enable: "phaseUse", + filter: function (event, player) { + return player.getStorage("juanhui3").length > 0 && player.countCards("hs") > 0; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('绢绘',[player.getStorage('juanhui3'),'vcard'],'hidden') + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("绢绘", [player.getStorage("juanhui3"), "vcard"], "hidden"); }, - filter:function(button,player){ - return lib.filter.cardEnabled({ - name:button.link[2], - nature:button.link[3], - },player,_status.event.getParent()); + filter: function (button, player) { + return lib.filter.cardEnabled( + { + name: button.link[2], + nature: button.link[3], + }, + player, + _status.event.getParent() + ); }, - check:function(button){ - var player=_status.event.player; - var card={ - name:button.link[2], - nature:button.link[3], + check: function (button) { + var player = _status.event.player; + var card = { + name: button.link[2], + nature: button.link[3], }; - if(player.getUseValue(card)>0) return get.order(card); + if (player.getUseValue(card) > 0) return get.order(card); return -1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'juanhui', - popname:true, - filterCard:true, - position:'hs', - viewAs:{ - name:links[0][2], - nature:links[0][3], + audio: "juanhui", + popname: true, + filterCard: true, + position: "hs", + viewAs: { + name: links[0][2], + nature: links[0][3], }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - precontent:function(){ - var card=event.result.card; - if(card.name=='sha') event.getParent().addCount=false; - var vcard=player.storage.juanhui3; - for(var i=0;i0){ - var order2=get.order(card); - if(order2>order) order=order2 + ai: { + order: function (item, player) { + var muniu = player.getStorage("juanhui3"); + var order = 0; + for (var i = 0; i < muniu.length; i++) { + var card = { name: muniu[i][2], nature: muniu[i][3] }; + if (player.getUseValue(card) > 0) { + var order2 = get.order(card); + if (order2 > order) order = order2; } } - return order+0.1; + return order + 0.1; }, - result:{ - player:1, + result: { + player: 1, }, }, }, - juanhui3:{ - charlotte:true, - firstDo:true, - trigger:{ - global:'useCard2', - player:['phaseUseEnd','phaseUseSkipped','useCardAfter'], + juanhui3: { + charlotte: true, + firstDo: true, + trigger: { + global: "useCard2", + player: ["phaseUseEnd", "phaseUseSkipped", "useCardAfter"], }, - silent:true, - filter:function(event,player,name){ - if(event.name=='phaseUse') return true; - else if(name=='useCardAfter') return event.getParent().juanhui; - return event.player==player.storage.juanhui2&&event.player.isPhaseUsing()&& - ['basic','trick'].includes(get.type(event.card))&&player.getStorage('juanhui3').filter(function(vcard){ - return vcard[2]==event.card.name; - }).length==0; + silent: true, + filter: function (event, player, name) { + if (event.name == "phaseUse") return true; + else if (name == "useCardAfter") return event.getParent().juanhui; + return ( + event.player == player.storage.juanhui2 && + event.player.isPhaseUsing() && + ["basic", "trick"].includes(get.type(event.card)) && + player.getStorage("juanhui3").filter(function (vcard) { + return vcard[2] == event.card.name; + }).length == 0 + ); }, - content:function(){ - if(trigger.name=='phaseUse') player.removeSkill('juanhui2'); - else if(event.triggername=='useCardAfter'){ + content: function () { + if (trigger.name == "phaseUse") player.removeSkill("juanhui2"); + else if (event.triggername == "useCardAfter") { player.recover(); player.drawTo(3); - } - else{ - var vcard=[get.type(trigger.card),'',trigger.card.name]; - if(game.hasNature(trigger.card)) vcard.push(get.nature(trigger.card)); + } else { + var vcard = [get.type(trigger.card), "", trigger.card.name]; + if (game.hasNature(trigger.card)) vcard.push(get.nature(trigger.card)); player.storage.juanhui3.push(vcard); - player.markSkill('juanhui2'); + player.markSkill("juanhui2"); } }, }, - mubing:{ - audio:2, - audioname:['sp_key_yuri'], - trigger:{player:'phaseUseBegin'}, + mubing: { + audio: 2, + audioname: ["sp_key_yuri"], + trigger: { player: "phaseUseBegin" }, //direct:true, - frequent:true, - filter:function(event,player){ - return player.countCards('he')>0; + frequent: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - var num=player.storage.mubing2?4:3; - event.num=num; - event.cards=game.cardsGotoOrdering(get.cards(num)).cards; - game.log(player,'展示了',event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - var str=get.translation(player)+'发动了【募兵】'; - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - game.addVideo('showCards',player,[get.translation(player)+'发动了【募兵】',get.cardsInfo(event.cards)]); + content: function () { + "step 0"; + var num = player.storage.mubing2 ? 4 : 3; + event.num = num; + event.cards = game.cardsGotoOrdering(get.cards(num)).cards; + game.log(player, "展示了", event.cards); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str = get.translation(player) + "发动了【募兵】"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + game.addVideo("showCards", player, [ + get.translation(player) + "发动了【募兵】", + get.cardsInfo(event.cards), + ]); game.delay(2); - 'step 1' - var numa=0; - cards.sort(function(a,b){ - return a.number-b.number; + "step 1"; + var numa = 0; + cards.sort(function (a, b) { + return a.number - b.number; }); - for(var i of cards){ - if(get.value(i,player)>0) numa+=get.number(i); + for (var i of cards) { + if (get.value(i, player) > 0) numa += get.number(i); } - player.chooseToDiscard([1,Infinity],'h').set('ai',function(card){ - var player=_status.event.player; - var numa=_status.event.numa; - //if(card.name!='tengjia'&&get.position(card)=='e'&&get.equipValue(card,player)<=0) return 14; - var num=0; - for(var i of ui.selected.cards){ - num+=i.number; - } - if(num>=numa) return 0; - if(card.number+num>=numa) return 15-get.value(card); - if(!ui.selected.cards.length){ - var min=_status.event.min; - if(card.numbermin; - })) return 0; - return card.number; - } - return Math.max(5-get.value(card),card.number); - }).set('prompt',false).set('numa',numa).set('min',cards[0].number); - var func=function(id){ - var dialog=get.idDialog(id); - if(dialog) dialog.content.firstChild.innerHTML='请选择要弃置的牌'; + player + .chooseToDiscard([1, Infinity], "h") + .set("ai", function (card) { + var player = _status.event.player; + var numa = _status.event.numa; + //if(card.name!='tengjia'&&get.position(card)=='e'&&get.equipValue(card,player)<=0) return 14; + var num = 0; + for (var i of ui.selected.cards) { + num += i.number; + } + if (num >= numa) return 0; + if (card.number + num >= numa) return 15 - get.value(card); + if (!ui.selected.cards.length) { + var min = _status.event.min; + if ( + card.number < min && + !player.countCards("h", function (xcard) { + return xcard != card && card.number + xcard.number > min; + }) + ) + return 0; + return card.number; + } + return Math.max(5 - get.value(card), card.number); + }) + .set("prompt", false) + .set("numa", numa) + .set("min", cards[0].number); + var func = function (id) { + var dialog = get.idDialog(id); + if (dialog) dialog.content.firstChild.innerHTML = "请选择要弃置的牌"; }; - if(player==game.me) func(event.videoId); - else if(player.isOnline()) player.send(func,event.videoId); - 'step 2' - if(!result.bool){ + if (player == game.me) func(event.videoId); + else if (player.isOnline()) player.send(func, event.videoId); + "step 2"; + if (!result.bool) { return; } - var numx=0; - for(var i of result.cards){ - numx+=get.number(i); + var numx = 0; + for (var i of result.cards) { + numx += get.number(i); } - event.numx=numx; - var next=player.chooseButton([0,num]); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - var num=0 - for(var i=0;i0; + ziqu: { + audio: 2, + audioname: ["sp_key_yuri"], + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return ( + event.player != player && + !player.getStorage("ziqu").includes(event.player) && + event.player.countCards("he") > 0 + ); }, - check:function(event,player){ - var target=event.player; - var eff=get.damageEffect(target,player,player); - if(get.attitude(player,target)>0){ - if(eff>=0) return false; + check: function (event, player) { + var target = event.player; + var eff = get.damageEffect(target, player, player); + if (get.attitude(player, target) > 0) { + if (eff >= 0) return false; return true; } - if(eff<=0) return true; - if(target.hp==1) return false; - if(event.num>1) return false; - var cards=target.getCards('he'); - for(var i=0;i10) return true; + if (eff <= 0) return true; + if (target.hp == 1) return false; + if (event.num > 1) return false; + var cards = target.getCards("he"); + for (var i = 0; i < cards.length; i++) { + if (get.number(cards[i]) > 10) return true; } return false; }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; trigger.cancel(); - if(!player.storage.ziqu) player.storage.ziqu=[]; + if (!player.storage.ziqu) player.storage.ziqu = []; player.storage.ziqu.push(trigger.player); - player.markSkill('ziqu'); - trigger.player.chooseCard(true,'he',function(card,player){ - return !player.countCards('he',function(cardx){ - return cardx.number>card.number; + player.markSkill("ziqu"); + trigger.player.chooseCard(true, "he", function (card, player) { + return !player.countCards("he", function (cardx) { + return cardx.number > card.number; }); }); - 'step 1' - if(result.bool&&result.cards&&result.cards.length) trigger.player.give(result.cards,player); + "step 1"; + if (result.bool && result.cards && result.cards.length) + trigger.player.give(result.cards, player); }, - intro:{content:'已对$发动过'}, + intro: { content: "已对$发动过" }, }, - mubing_rewrite:{ - mark:true, - intro:{ - content:'出牌阶段开始时,你可以展示牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。', + mubing_rewrite: { + mark: true, + intro: { + content: + "出牌阶段开始时,你可以亮出牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。", }, }, - diaoling:{ - audio:2, - audioname:['sp_key_yuri'], - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'metal', - filter:function(event,player){ - var num=0; - player.getAllHistory('gain',function(evt){ - var evt2=evt.getParent(); - if(evt2.name=='mubing'&&evt2.player==player) num+=evt.cards.filter(function(card){ - return card.name=='sha'||get.subtype(card,false)=='equip1'||(get.type2(card,false)=='trick'&&get.tag({name:card.name},'damage')); - }).length; + diaoling: { + audio: 2, + audioname: ["sp_key_yuri"], + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "metal", + filter: function (event, player) { + var num = 0; + player.getAllHistory("gain", function (evt) { + var evt2 = evt.getParent(); + if (evt2.name == "mubing" && evt2.player == player) + num += evt.cards.filter(function (card) { + return ( + card.name == "sha" || + get.subtype(card, false) == "equip1" || + (get.type2(card, false) == "trick" && + get.tag({ name: card.name }, "damage")) + ); + }).length; }); - return num>=6; + return num >= 6; }, - content:function(){ - player.awakenSkill('diaoling'); - player.storage.mubing2=true; - player.markSkill('mubing_rewrite'); - player.chooseDrawRecover(2,true); + content: function () { + player.awakenSkill("diaoling"); + player.storage.mubing2 = true; + player.markSkill("mubing_rewrite"); + player.chooseDrawRecover(2, true); }, - derivation:'mubing_rewrite', + ai: { + combo: "mubing" + }, + derivation: "mubing_rewrite", }, - refenyin_wufan:{audio:2}, + refenyin_wufan: { audio: 2 }, //官渡之战 - xiying:{ - trigger:{player:'phaseUseBegin'}, - audio:2, - direct:true, - filter:function(event,player){ - return player.countCards('h',function(card){ - return _status.connectMode||get.type(card)!='basic'; - })>0; + xiying: { + trigger: { player: "phaseUseBegin" }, + audio: 2, + direct: true, + filter: function (event, player) { + return ( + player.countCards("h", function (card) { + return _status.connectMode || get.type(card) != "basic"; + }) > 0 + ); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current!=player; + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current != player; }); list.sortBySeat(); - event.targets=list; - player.chooseToDiscard(get.prompt2('xiying'),'h',function(card){ - return get.type(card)!='basic'; - }).set('logSkill',['xiying',list]).set('ai',function(card){ - return _status.event.val-get.value(card) - }).set('val',function(){ - return 4*Math.sqrt(game.countPlayer(function(current){ - return get.attitude(player,current)<0&¤t.countCards('he')>0; - })); - }()); - 'step 1' - if(!result.bool) event.finish(); - else player.addTempSkill('xiying_gain'); - 'step 2' - var target=targets.shift(); - event.target=target; - if(target.isIn()) target.chooseToDiscard('he','弃置一张牌,或本回合内不能使用或打出牌').set('ai',function(card){ - var player=_status.event.player; - var source=_status.event.getTrigger().player; - if(get.attitude(source,player)>0) return -1; - if(_status.event.getRand()>0.5) return 5-get.value(card); - return -1; - }); - 'step 3' - if(target.isIn()&&!result.bool) target.addTempSkill('xiying2'); - if(targets.length) event.goto(2); + event.targets = list; + player + .chooseToDiscard(get.prompt2("xiying"), "h", function (card) { + return get.type(card) != "basic"; + }) + .set("logSkill", ["xiying", list]) + .set("ai", function (card) { + return _status.event.val - get.value(card); + }) + .set( + "val", + (function () { + return ( + 4 * + Math.sqrt( + game.countPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.countCards("he") > 0 + ); + }) + ) + ); + })() + ); + "step 1"; + if (!result.bool) event.finish(); + else player.addTempSkill("xiying_gain"); + "step 2"; + var target = targets.shift(); + event.target = target; + if (target.isIn()) + target + .chooseToDiscard("he", "弃置一张牌,或本回合内不能使用或打出牌") + .set("ai", function (card) { + var player = _status.event.player; + var source = _status.event.getTrigger().player; + if (get.attitude(source, player) > 0) return -1; + if (_status.event.getRand() > 0.5) return 5 - get.value(card); + return -1; + }); + "step 3"; + if (target.isIn() && !result.bool) target.addTempSkill("xiying2"); + if (targets.length) event.goto(2); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.target.hasSkill('xiying2'); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg.target.hasSkill("xiying2"); }, }, - subSkill:{ - gain:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getHistory('sourceDamage',function(evt){ - return evt.isPhaseUsing(player); - }).length>0; + subSkill: { + gain: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + player.getHistory("sourceDamage", function (evt) { + return evt.isPhaseUsing(player); + }).length > 0 + ); }, - content:function(){ - var card=get.cardPile2(function(card){ - var type=get.type(card,false); - if(type!='basic'&&type!='trick') return false; - return get.tag(card,'damage')>0; + content: function () { + var card = get.cardPile2(function (card) { + var type = get.type(card, false); + if (type != "basic" && type != "trick") return false; + return get.tag(card, "damage") > 0; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, }, }, }, - xiying2:{ - mark:true, - intro:{content:'本回合内不能使用或打出牌'}, - mod:{ - cardEnabled2:function(card){ + xiying2: { + mark: true, + intro: { content: "本回合内不能使用或打出牌" }, + mod: { + cardEnabled2: function (card) { return false; }, }, }, - gangzhi:{ - audio:2, - trigger:{ - player:'damageBefore', - source:'damageBefore', + gangzhi: { + audio: 2, + trigger: { + player: "damageBefore", + source: "damageBefore", }, - forced:true, - filter:function(event,player){ - if(event.source==event.player) return false; - if(event.player==player){ - return event.source&&event.source.isIn(); + forced: true, + filter: function (event, player) { + if (event.source == event.player) return false; + if (event.player == player) { + return event.source && event.source.isIn(); } return true; }, - content:function(){ + content: function () { trigger.cancel(); trigger.player.loseHp(trigger.num); }, - ai:{ - jueqing:true, + ai: { + jueqing: true, }, }, - beizhan:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('beizhan')).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - var hs=target.countCards('h'); - var ht=target.maxHp; - if(hs>=ht&&target.isMaxHandcard()) return -att*hs; - if(hsht; - })) return att*2*(ht-hs); + beizhan: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("beizhan")).set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var hs = target.countCards("h"); + var ht = target.maxHp; + if (hs >= ht && target.isMaxHandcard()) return -att * hs; + if ( + hs < ht && + game.hasPlayer(function (current) { + return current.countCards("h") > ht; + }) + ) + return att * 2 * (ht - hs); return 0; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('beizhan',target); - target.drawTo(Math.min(5,target.maxHp)) - target.addSkill('beizhan2'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("beizhan", target); + target.drawTo(Math.min(5, target.maxHp)); + target.addSkill("beizhan2"); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - beizhan2:{ - trigger:{player:'phaseBegin'}, - silent:true, - firstDo:true, - content:function(){ - player.removeSkill('beizhan2'); - if(player.isMaxHandcard()) player.addTempSkill('zishou2'); + beizhan2: { + trigger: { player: "phaseBegin" }, + silent: true, + firstDo: true, + content: function () { + player.removeSkill("beizhan2"); + if (player.isMaxHandcard()) player.addTempSkill("zishou2"); }, - mark:true, - intro:{content:'回合开始时,若手牌数为全场最多,则回合内不能使用牌指定其他角色为目标'}, + mark: true, + intro: { content: "回合开始时,若手牌数为全场最多,则回合内不能使用牌指定其他角色为目标" }, }, - fenglve:{ - audio:2, - trigger:{ - player:"phaseUseBegin", + fenglve: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - content:function(){ - 'step 0' - var goon=player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=12; + direct: true, + content: function () { + "step 0"; + var goon = player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 12; } - if(val<=6){ - return card.number>=13; + if (val <= 6) { + return card.number >= 13; } return false; }); - player.chooseTarget(get.prompt2('fenglve'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - return -get.attitude(player,target)*(1+target.countCards('e'))/(1+target.countCards('j')); - }).set('goon',goon); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('fenglve',target); + player + .chooseTarget(get.prompt2("fenglve"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + return ( + (-get.attitude(player, target) * (1 + target.countCards("e"))) / + (1 + target.countCards("j")) + ); + }) + .set("goon", goon); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("fenglve", target); player.chooseToCompare(target); - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - var num=0; - if(target.countCards('h')) num++; - if(target.countCards('e')) num++; - if(target.countCards('j')) num++; - if(num){ - event.gainner=player; - event.giver=target; - target.choosePlayerCard(target,num,'hej',true).set('filterButton',function(button){ - for(var i=0;i0; + return get.attitude(player, target) * get.value(card, target, "raw") > 0; }, - filter:function(event,player){ - if(event.targets) return false; - var card,target; - if(player==event.player){ - card=event.card1; - target=event.target; + filter: function (event, player) { + if (event.targets) return false; + var card, target; + if (player == event.player) { + card = event.card1; + target = event.target; + } else { + card = event.card2; + target = event.player; } - else{ - card=event.card2; - target=event.player; - } - return get.position(card,true)=='o'; + return get.position(card, true) == "o"; }, - prompt:function(event,player){ - var card,target; - if(player==event.player){ - card=event.card1; - target=event.target; + prompt: function (event, player) { + var card, target; + if (player == event.player) { + card = event.card1; + target = event.target; + } else { + card = event.card2; + target = event.player; } - else{ - card=event.card2; - target=event.player; - } - return '是否发动【锋略】,令'+get.translation(target)+'获得'+get.translation(card)+'?' + return ( + "是否发动【锋略】,令" + + get.translation(target) + + "获得" + + get.translation(card) + + "?" + ); }, - logTarget:function(event,player){ + logTarget: function (event, player) { var target; - if(player==event.player){ - target=event.target; - } - else{ - target=event.player; + if (player == event.player) { + target = event.target; + } else { + target = event.player; } return target; }, - content:function(){ - var card,target; - if(player==trigger.player){ - card=trigger.card1; - target=trigger.target; + content: function () { + var card, target; + if (player == trigger.player) { + card = trigger.card1; + target = trigger.target; + } else { + card = trigger.card2; + target = trigger.player; } - else{ - card=trigger.card2; - target=trigger.player; - } - target.gain(card,'gain2','log'); + target.gain(card, "gain2", "log"); }, }, - mouzhi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0 + mouzhi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - filterTarget:function(card,player,target){ - if(target.storage.mouzhi2&&target.storage.mouzhi2.includes(player)) return false; - return target!=player; + filterCard: true, + filterTarget: function (card, player, target) { + if (target.storage.mouzhi2 && target.storage.mouzhi2.includes(player)) return false; + return target != player; }, - delay:0, - lose:false, - discard:false, - check:function(card){ - if(card.name=='du') return 20; - var player=_status.event.player; - var useval=player.getUseValue(card); - var maxval=0; - game.countPlayer(function(current){ - if(current!=player&&!current.hasSkillTag('nogain')&&get.attitude(player,current)>0){ - var temp=current.getUseValue(card); - if(temp>maxval) maxval=temp; + delay: 0, + lose: false, + discard: false, + check: function (card) { + if (card.name == "du") return 20; + var player = _status.event.player; + var useval = player.getUseValue(card); + var maxval = 0; + game.countPlayer(function (current) { + if ( + current != player && + !current.hasSkillTag("nogain") && + get.attitude(player, current) > 0 + ) { + var temp = current.getUseValue(card); + if (temp > maxval) maxval = temp; } }); - if(maxval>0&&get.tag(card,'damage')) return 15; - if(maxval>useval) return 10; - if(player.needsToDiscard()) return 1/Math.max(0.1,get.value(card)); + if (maxval > 0 && get.tag(card, "damage")) return 15; + if (maxval > useval) return 10; + if (player.needsToDiscard()) return 1 / Math.max(0.1, get.value(card)); return -1; }, - content:function(){ - player.give(cards,target); - target.addTempSkill('mouzhi2',{player:'phaseEnd'}); + content: function () { + player.give(cards, target); + target.addTempSkill("mouzhi2", { player: "phaseEnd" }); target.storage.mouzhi2.add(player); target.storage.mouzhi2.sortBySeat(target); - target.markSkill('mouzhi2'); + target.markSkill("mouzhi2"); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(ui.selected.cards.length){ - var card=ui.selected.cards[0]; - if(card.name=='du') return target.hasSkill('lucia_duqu')?1:-1; - var t=target.getUseValue(card); - var p=player.getUseValue(card); - if(t>p) return 2; - if(t>0) return 1.5 - if(player.needsToDiscard()) return 1; + ai: { + order: 10, + result: { + target: function (player, target) { + if (ui.selected.cards.length) { + var card = ui.selected.cards[0]; + if (card.name == "du") return target.hasSkill("lucia_duqu") ? 1 : -1; + var t = target.getUseValue(card); + var p = player.getUseValue(card); + if (t > p) return 2; + if (t > 0) return 1.5; + if (player.needsToDiscard()) return 1; return 0; } return 0; @@ -8049,83 +10175,87 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - mouzhi2:{ - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + mouzhi2: { + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - onremove:true, - trigger:{source:'damageSource'}, - forced:true, - intro:{ - content:'出牌阶段内第一次对一名其他角色造成伤害时,$摸一张牌', + onremove: true, + trigger: { source: "damageSource" }, + forced: true, + intro: { + content: "出牌阶段内第一次对一名其他角色造成伤害时,$摸一张牌", }, - filter:function(event,player){ - var evt2=event.getParent('phaseUse'); - if(!evt2||evt2.player!=player) return false; - var history=event.player.getHistory('damage',function(evt){ - return evt.source==player&&evt.getParent('phaseUse')==evt2; + filter: function (event, player) { + var evt2 = event.getParent("phaseUse"); + if (!evt2 || evt2.player != player) return false; + var history = event.player.getHistory("damage", function (evt) { + return evt.source == player && evt.getParent("phaseUse") == evt2; }); - return history[0]==event; + return history[0] == event; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; game.asyncDraw(player.storage.mouzhi2); - 'step 1' + "step 1"; game.delay(); }, }, - yuanlve:{ - enable:'phaseUse', - usable:1, - audio:2, - filter:function(event,player){ - return player.countCards('h',function(card){ - return get.type(card)!='equip'; - }) + yuanlve: { + enable: "phaseUse", + usable: 1, + audio: 2, + filter: function (event, player) { + return player.countCards("h", function (card) { + return get.type(card) != "equip"; + }); }, - filterCard:function(card){ - return get.type(card)!='equip'; + filterCard: function (card) { + return get.type(card) != "equip"; }, - filterTarget:lib.filter.notMe, - delay:false, - discard:false, - lose:false, - check:function(card){ - if(card.name=='du') return 20; - var player=_status.event.player; - var useval=player.getUseValue(card); - var maxval=0; - game.countPlayer(function(current){ - if(current!=player&&!current.hasSkillTag('nogain')&&get.attitude(player,current)>0){ - var temp=current.getUseValue(card); - if(temp>maxval) maxval=temp; + filterTarget: lib.filter.notMe, + delay: false, + discard: false, + lose: false, + check: function (card) { + if (card.name == "du") return 20; + var player = _status.event.player; + var useval = player.getUseValue(card); + var maxval = 0; + game.countPlayer(function (current) { + if ( + current != player && + !current.hasSkillTag("nogain") && + get.attitude(player, current) > 0 + ) { + var temp = current.getUseValue(card); + if (temp > maxval) maxval = temp; } }); - if(maxval>useval) return 15; - if(maxval>0) return 10; - if(player.needsToDiscard()) return 1/Math.max(0.1,get.value(card)); + if (maxval > useval) return 15; + if (maxval > 0) return 10; + if (player.needsToDiscard()) return 1 / Math.max(0.1, get.value(card)); return -1; }, - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; target.chooseUseTarget(cards[0]); - 'step 2' - if(result.bool) player.draw(); + "step 2"; + if (result.bool) player.draw(); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(ui.selected.cards.length){ - var card=ui.selected.cards[0]; - if(card.name=='du') return target.hasSkill('lucia_duqu')?1:-1; - var t=target.getUseValue(card); - var p=player.getUseValue(card); - if(t>p) return 2; - if(t>0) return 1.5 - if(player.needsToDiscard()) return 1; + ai: { + order: 10, + result: { + target: function (player, target) { + if (ui.selected.cards.length) { + var card = ui.selected.cards[0]; + if (card.name == "du") return target.hasSkill("lucia_duqu") ? 1 : -1; + var t = target.getUseValue(card); + var p = player.getUseValue(card); + if (t > p) return 2; + if (t > 0) return 1.5; + if (player.needsToDiscard()) return 1; return 0; } return 0; @@ -8134,3583 +10264,4312 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //吕旷吕翔和淳于琼和官渡哔哔机 - spshicai:{ - audio:2, - enable:'phaseUse', - position:'he', - filter:function(event,player){ - return !player.storage.spshicai2||!player.getCards('h').includes(player.storage.spshicai2); + spshicai: { + audio: 2, + enable: "phaseUse", + position: "he", + filter: function (event, player) { + return ( + !player.storage.spshicai2 || !player.getCards("h").includes(player.storage.spshicai2) + ); }, - filterCard:true, - prompt:function(){ - var str='弃置一张牌,然后获得'; - if(get.itemtype(_status.pileTop)=='card') str+=get.translation(_status.pileTop); - else str+='牌堆顶的一张牌'; + filterCard: true, + prompt: function () { + var str = "弃置一张牌,然后获得"; + if (get.itemtype(_status.pileTop) == "card") str += get.translation(_status.pileTop); + else str += "牌堆顶的一张牌"; return str; }, - check:function(card){ - var player=_status.event.player; - var cardx=_status.pileTop; - if(get.itemtype(cardx)!='card') return 0; - var val=player.getUseValue(cardx,null,true); - if(!val) return 0; - var val2=player.getUseValue(card,null,true); - return (val-val2)/Math.max(0.1,get.value(card)); + check: function (card) { + var player = _status.event.player; + var cardx = _status.pileTop; + if (get.itemtype(cardx) != "card") return 0; + var val = player.getUseValue(cardx, null, true); + if (!val) return 0; + var val2 = player.getUseValue(card, null, true); + return (val - val2) / Math.max(0.1, get.value(card)); }, - content:function(){ - var card=get.cards()[0]; - player.storage.spshicai2=card; - player.gain(card,'draw'); - game.log(player,'获得了牌堆顶的一张牌'); + content: function () { + var card = get.cards()[0]; + player.storage.spshicai2 = card; + player.gain(card, "draw"); + game.log(player, "获得了牌堆顶的一张牌"); }, - group:'spshicai_mark', - ai:{ - order:1, - result:{player:1}, + group: "spshicai_mark", + ai: { + order: 1, + result: { player: 1 }, }, }, - spshicai_mark:{ - trigger:{player:'phaseUseBegin'}, - silent:true, - firstDo:true, - content:function(){ - player.addTempSkill('spshicai2','phaseUseEnd'); + spshicai_mark: { + trigger: { player: "phaseUseBegin" }, + silent: true, + firstDo: true, + content: function () { + player.addTempSkill("spshicai2", "phaseUseEnd"); }, }, - spshicai2:{ - onremove:true, - mark:true, - intro:{ - mark:function(dialog,content,player){ - if(player!=game.me) return get.translation(player)+'观看牌堆中...'; - if(get.itemtype(_status.pileTop)!='card') return '牌堆顶无牌'; + spshicai2: { + onremove: true, + mark: true, + intro: { + mark: function (dialog, content, player) { + if (player != game.me) return get.translation(player) + "观看牌堆中..."; + if (get.itemtype(_status.pileTop) != "card") return "牌堆顶无牌"; dialog.add([_status.pileTop]); }, }, }, - spfushi:{ - group:['zezhu','chenggong'], - derivation:['zezhu','chenggong'], - locked:true, + spfushi: { + group: ["zezhu", "chenggong"], + derivation: ["zezhu", "chenggong"], + locked: true, }, - zezhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var enemy=0; - var friend=0; - var zhu=0; - for(var i of game.players){ - if(i.isEnemyOf(player)) enemy++; + zezhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var enemy = 0; + var friend = 0; + var zhu = 0; + for (var i of game.players) { + if (i.isEnemyOf(player)) enemy++; else friend++; - if(i!=player&&i.isZhu) zhu++; + if (i != player && i.isZhu) zhu++; } - return zhu>0&&enemy 0 && enemy < friend; }, - filterTarget:function(card,player,target){ - return target!=player&&target.isZhu; + filterTarget: function (card, player, target) { + return target != player && target.isZhu; }, - selectTarget:-1, - multiline:true, - multitarget:true, - content:function(){ - 'step 0' + selectTarget: -1, + multiline: true, + multitarget: true, + content: function () { + "step 0"; event.targets.sortBySeat(); - event.targets2=event.targets.slice(0); - 'step 1' - var target=event.targets2.shift(); - if(target.countGainableCards(player,'he')>0) player.gainPlayerCard(target,'he',true); + event.targets2 = event.targets.slice(0); + "step 1"; + var target = event.targets2.shift(); + if (target.countGainableCards(player, "he") > 0) + player.gainPlayerCard(target, "he", true); else player.draw(); - if(event.targets2.length) event.redo(); - 'step 2' - if(player.countCards('he')>=targets.length){ - player.chooseCard('he',true,'依次选择'+get.cnNumber(targets.length)+'张牌,分别交给'+get.translation(targets),targets.length).set('ai',function(card){ - var target=_status.event.getParent().targets[ui.selected.cards.length]; - var player=_status.event.player; - return get.attitude(player,target)*get.value(card,target); - }); - } - else event.finish(); - 'step 3' - var list=[]; - for(var i=0;i= targets.length) { + player + .chooseCard( + "he", + true, + "依次选择" + + get.cnNumber(targets.length) + + "张牌,分别交给" + + get.translation(targets), + targets.length + ) + .set("ai", function (card) { + var target = _status.event.getParent().targets[ui.selected.cards.length]; + var player = _status.event.player; + return get.attitude(player, target) * get.value(card, target); + }); + } else event.finish(); + "step 3"; + var list = []; + for (var i = 0; i < targets.length; i++) { + list.push([targets[i], result.cards[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - player:player, - cards:result.cards, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + player: player, + cards: result.cards, + animate: "giveAuto", + }).setContent("gaincardMultiple"); }, - ai:{ - order:6, - result:{player:1}, + ai: { + order: 6, + result: { player: 1 }, }, }, - chenggong:{ - audio:2, - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(!(event.isFirstTarget&&event.targets&&event.targets.length>1&&event.player.isIn())) return false; - var enemy=0; - var friend=0; - for(var i of game.players){ - if(i.isEnemyOf(player)) enemy++; + chenggong: { + audio: 2, + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if ( + !( + event.isFirstTarget && + event.targets && + event.targets.length > 1 && + event.player.isIn() + ) + ) + return false; + var enemy = 0; + var friend = 0; + for (var i of game.players) { + if (i.isEnemyOf(player)) enemy++; else friend++; } - return enemy>friend; + return enemy > friend; }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.draw(); }, }, - cangchu:{ - trigger:{ - global:'phaseBefore', - player:['damageEnd','enterGame'], + cangchu: { + trigger: { + global: "phaseBefore", + player: ["damageEnd", "enterGame"], }, - audio:2, - forced:true, - filter:function(event,player){ - if(event.name!='damage') return (event.name!='phase'||game.phaseNumber==0); - return event.hasNature('fire')&&player.countMark('cangchu')>0; + audio: 2, + forced: true, + filter: function (event, player) { + if (event.name != "damage") return event.name != "phase" || game.phaseNumber == 0; + return event.hasNature("fire") && player.countMark("cangchu") > 0; }, - content:function(){ - if(trigger.name!='damage') player.addMark('cangchu',3); - else{ - player.removeMark('cangchu',Math.min(trigger.num,player.countMark('cangchu'))); - if(!player.hasMark('cangchu')) event.trigger('cangchuAwaken'); + content: function () { + if (trigger.name != "damage") player.addMark("cangchu", 3); + else { + player.removeMark("cangchu", Math.min(trigger.num, player.countMark("cangchu"))); + if (!player.hasMark("cangchu")) event.trigger("cangchuAwaken"); } }, - marktext:'粮', - intro:{ - name2:'粮', - content:'mark', + marktext: "粮", + intro: { + name2: "粮", + content: "mark", }, - ai:{ - threaten:function(player,target){ - return 1+target.countMark('cangchu')/2; + ai: { + threaten: function (player, target) { + return 1 + target.countMark("cangchu") / 2; }, - effect:{ - target:function(card,player,target,current){ - if(target.hasMark('cangchu')){ - if(card.name=='sha'){ - if(lib.skill.global.includes('huoshaowuchao')||game.hasNature(card,'fire')||player.hasSkill('zhuque_skill')) return 2; + effect: { + target: function (card, player, target, current) { + if (target.hasMark("cangchu")) { + if (card.name == "sha") { + if ( + lib.skill.global.includes("huoshaowuchao") || + game.hasNature(card, "fire") || + player.hasSkill("zhuque_skill") + ) + return 2; } - if(get.tag(card,'fireDamage')&¤t<0) return 2; + if (get.tag(card, "fireDamage") && current < 0) return 2; } - } + }, }, + combo: "liangying", }, }, - sushou:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - frequent:true, - async content(event,trigger,player){ - await player.draw(1+player.countMark('cangchu')); - const num=Math.min(player.countCards('h'),player.countCards('he'),game.countPlayer(target=>target!=player&&target.isFriendOf(player))); - if(num){ - let list=[]; - while(num-list.length>0){ - const {result:{bool,targets,cards}}=await player.chooseCardTarget({ - prompt:'宿守:你可以交给友方角色各一张牌', - position:'he', - animate:false, - filterCard(card,player){ - return !get.event('list').some(list=>list[1]==card); - }, - filterTarget(card,player,target){ - return target!=player&&target.isFriendOf(player)&&!get.event('list').some(list=>list[0]==target); - }, - ai1(card){ - if(card.name=='shan') return 1; - return Math.random(); - }, - ai2(target){ - return get.attitude(get.event('player'),target); - }, - }).set('list',list); - if(bool){ - list.push([targets[0],cards[0]]); - player.addGaintag(cards,'olsujian_given'); - } - else break; + sushou: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + frequent: true, + async content(event, trigger, player) { + await player.draw(1 + player.countMark("cangchu")); + const num = Math.min( + player.countCards("h"), + player.countCards("he"), + game.countPlayer((target) => target != player && target.isFriendOf(player)) + ); + if (num) { + let list = []; + if (_status.connectMode) game.broadcastAll(() => (_status.noclearcountdown = true)); + while (num - list.length > 0) { + const { + result: { bool, targets, cards }, + } = await player + .chooseCardTarget({ + prompt: "宿守:你可以交给友方角色各一张牌", + position: "he", + animate: false, + filterCard(card, player) { + return !get.event("list").some((list) => list[1] == card); + }, + filterTarget(card, player, target) { + return ( + target != player && + target.isFriendOf(player) && + !get.event("list").some((list) => list[0] == target) + ); + }, + ai1(card) { + if (card.name == "shan") return 1; + return Math.random(); + }, + ai2(target) { + return get.attitude(get.event("player"), target); + }, + }) + .set("list", list); + if (bool) { + list.push([targets[0], cards[0]]); + player.addGaintag(cards, "olsujian_given"); + } else break; } - if(list.length){ - await game.loseAsync({ - gain_list:list, - player:player, - cards:list.slice().map(list=>list[1]), - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + if (list.length) { + await game + .loseAsync({ + gain_list: list, + player: player, + cards: list.slice().map((list) => list[1]), + giver: player, + animate: "giveAuto", + }) + .setContent("gaincardMultiple"); } } }, }, - liangying:{ - trigger:{ - global:'phaseDrawBegin2', - player:'cangchuAwaken', + liangying: { + trigger: { + global: "phaseDrawBegin2", + player: "cangchuAwaken", }, - forced:true, - audio:1, - logTarget:function(event,player){ - if(event.name=='phaseDraw') return event.player; - return game.filterPlayer(function(current){ + forced: true, + audio: 1, + logTarget: function (event, player) { + if (event.name == "phaseDraw") return event.player; + return game.filterPlayer(function (current) { return current.isEnemyOf(player); }); }, - filter:function(event,player){ - if(event.name=='cangchu') return true; - return player.hasMark('cangchu')&&!event.numFixed&&event.player.isFriendOf(player); + filter: function (event, player) { + if (event.name == "cangchu") return true; + return player.hasMark("cangchu") && !event.numFixed && event.player.isFriendOf(player); }, - content:function(){ - 'step 0' - if(trigger.name=='cangchu'){ + content: function () { + "step 0"; + if (trigger.name == "cangchu") { player.loseMaxHp(); - var list=game.filterPlayer(function(current){ + var list = game.filterPlayer(function (current) { return current.isEnemyOf(player); }); - if(list.length){ - game.asyncDraw(list,2); + if (list.length) { + game.asyncDraw(list, 2); } - } - else{ + } else { trigger.num++; event.finish(); } - 'step 1' + "step 1"; game.delay(); }, - }, - liehou:{ - enable:'phaseUse', - usable:1, - audio:2, - filterTarget:function(card,player,target){ - return player.inRange(target)&&target.countCards('h'); + ai: { + combo: "cangchu", }, - content:function(){ - 'step 0' - target.chooseCard('h',true,'交给'+get.translation(player)+'一张牌'); - 'step 1' - if(result.bool){ - target.give(result.cards,player); - } - else event.finish(); - 'step 2' - if(player.countCards('h')&&game.hasPlayer(function(current){ - return current!=target&&player.inRange(current); - })){ + }, + liehou: { + enable: "phaseUse", + usable: 1, + audio: 2, + filterTarget: function (card, player, target) { + return player.inRange(target) && target.countCards("h"); + }, + content: function () { + "step 0"; + target.chooseCard("h", true, "交给" + get.translation(player) + "一张牌"); + "step 1"; + if (result.bool) { + target.give(result.cards, player); + } else event.finish(); + "step 2"; + if ( + player.countCards("h") && + game.hasPlayer(function (current) { + return current != target && player.inRange(current); + }) + ) { player.chooseCardTarget({ - position:'h', - filterCard:true, - filterTarget:function(card,player,target){ - return target!=_status.event.getParent().target&&player.inRange(target); + position: "h", + filterCard: true, + filterTarget: function (card, player, target) { + return target != _status.event.getParent().target && player.inRange(target); }, - forced:true, - prompt:'将一张手牌交给一名攻击范围内的其他角色', - ai1:function(card){ - var player=_status.event.player; - if(get.name(card)=='du') return 20; - if(game.hasPlayer(function(current){ - return current!=_status.event.getParent().target&&player.inRange(current)&&get.attitude(player,current)>0&¤t.getUseValue(card)>player.getUseValue(card)&¤t.getUseValue(card)>player.getUseValue(card); - })) return 12; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })){ - if(card.name=='wuxie') return 11; - if(card.name=='shan'&&player.countCards('h','shan')>1) return 9 + forced: true, + prompt: "将一张手牌交给一名攻击范围内的其他角色", + ai1: function (card) { + var player = _status.event.player; + if (get.name(card) == "du") return 20; + if ( + game.hasPlayer(function (current) { + return ( + current != _status.event.getParent().target && + player.inRange(current) && + get.attitude(player, current) > 0 && + current.getUseValue(card) > player.getUseValue(card) && + current.getUseValue(card) > player.getUseValue(card) + ); + }) + ) + return 12; + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) { + if (card.name == "wuxie") return 11; + if (card.name == "shan" && player.countCards("h", "shan") > 1) return 9; } - return 6/Math.max(1,get.value(card)); + return 6 / Math.max(1, get.value(card)); }, - ai2:function(target){ - var player=_status.event.player; - var card=ui.selected.cards[0]; - var att=get.attitude(player,target); - if(card.name=='du') return -6*att; - if(att>0){ - if(get.position(card)=='h'&&target.getUseValue(card)>player.getUseValue(card)) return 4*att; - if(get.value(card,target)>get.value(card,player)) return 2*att; - return 1.2*att; + ai2: function (target) { + var player = _status.event.player; + var card = ui.selected.cards[0]; + var att = get.attitude(player, target); + if (card.name == "du") return -6 * att; + if (att > 0) { + if ( + get.position(card) == "h" && + target.getUseValue(card) > player.getUseValue(card) + ) + return 4 * att; + if (get.value(card, target) > get.value(card, player)) return 2 * att; + return 1.2 * att; } - return -att*Math.min(4,target.countCards('he'))/6; + return (-att * Math.min(4, target.countCards("he"))) / 6; }, }); - } - else event.finish(); - 'step 3' - if(result.bool) player.give(result.cards,result.targets[0]); + } else event.finish(); + "step 3"; + if (result.bool) player.give(result.cards, result.targets[0]); }, - ai:{ - order:6, - result:{ - target:-1, + ai: { + order: 6, + result: { + target: -1, }, }, }, - qigong:{ - trigger:{player:'shaMiss'}, - direct:true, - audio:2, - filter:function(event,player){ - return event.target.isIn()&&game.hasPlayer(function(current){ - return current!=event.target&¤t.canUse('sha',event.target,false); - }) + qigong: { + trigger: { player: "shaMiss" }, + direct: true, + audio: 2, + filter: function (event, player) { + return ( + event.target.isIn() && + game.hasPlayer(function (current) { + return current != event.target && current.canUse("sha", event.target, false); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('qigong'),'令一名角色可再对'+get.translation(trigger.target)+'使用一张【杀】',function(card,player,target){ - var source=_status.event.getTrigger().target; - return target!=source&&target.canUse('sha',source,false); - }).set('ai',function(target){ - var player=_status.event.player,card={name:'sha'},source=_status.event.getTrigger().target; - if(target.hasSha()){ - var eff1=get.effect(source,card,target,target); - if(eff1>0) return get.effect(source,card,target,player); - } - return (target!=player)?(Math.random()*get.attitude(player,target)):0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qigong',target); - target.addTempSkill('qigong_ai','chooseToUseEnd'); - target.chooseToUse('是否再对'+get.translation(trigger.target)+'使用一张【杀】?',function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },trigger.target,-1).set('addCount',false).set('oncard',function(){ - _status.event.directHit.addArray(game.players); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("qigong"), + "令一名角色可再对" + get.translation(trigger.target) + "使用一张【杀】", + function (card, player, target) { + var source = _status.event.getTrigger().target; + return target != source && target.canUse("sha", source, false); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + card = { name: "sha" }, + source = _status.event.getTrigger().target; + if (target.hasSha()) { + var eff1 = get.effect(source, card, target, target); + if (eff1 > 0) return get.effect(source, card, target, player); + } + return target != player ? Math.random() * get.attitude(player, target) : 0; }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qigong", target); + target.addTempSkill("qigong_ai", "chooseToUseEnd"); + target + .chooseToUse( + "是否再对" + get.translation(trigger.target) + "使用一张【杀】?", + function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, + trigger.target, + -1 + ) + .set("addCount", false) + .set("oncard", function () { + _status.event.directHit.addArray(game.players); + }); } }, - subSkill:{ - ai:{ - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.card&&arg.card.name=='sha'; + subSkill: { + ai: { + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg.card && arg.card.name == "sha"; }, }, }, }, }, //和沙摩柯一起上线的新服三将 - spjiedao:{ - audio:2, - trigger:{ - source:"damageBegin1", + spjiedao: { + audio: 2, + trigger: { + source: "damageBegin1", }, - filter:function(event,player){ - return player.isDamaged()&&!player.getHistory('sourceDamage').length; + filter: function (event, player) { + return player.isDamaged() && !player.getHistory("sourceDamage").length; }, - logTarget:'player', - direct:true, - check:function(trigger,player){ - if(get.attitude(player,trigger.player)>=-1) return false; - return !trigger.player.hasSkillTag('filterDamage',null,{ - player:player, - card:trigger.card, + logTarget: "player", + direct: true, + check: function (trigger, player) { + if (get.attitude(player, trigger.player) >= -1) return false; + return !trigger.player.hasSkillTag("filterDamage", null, { + player: player, + card: trigger.card, }); }, - content:function(){ - "step 0" - var num=player.getDamagedHp(); - var map={}; - var list=[]; - for(var i=1;i<=num;i++){ - var cn=get.cnNumber(i,true); - map[cn]=i; + content: function () { + "step 0"; + var num = player.getDamagedHp(); + var map = {}; + var list = []; + for (var i = 1; i <= num; i++) { + var cn = get.cnNumber(i, true); + map[cn] = i; list.push(cn); } - event.map=map; - player.chooseControl(list,'cancel2',function(){ - if(!lib.skill.spjiedao.check(_status.event.getTrigger(),player)) return 'cancel2'; - return get.cnNumber(_status.event.goon,true); - }).set('prompt',get.prompt2('spjiedao',trigger.player)).set('goon',num); - "step 1" - if(result.control=='cancel2') return; - player.logSkill('spjiedao',trigger.player); - var num=event.map[result.control]||1; - trigger.num+=num; - var next=game.createEvent('spjiedao_after',null,trigger.getParent()); - next.player=player; - next.target=trigger.player; - next.num=num; - next.setContent(function(){ - if(target.isIn()) player.chooseToDiscard(num,true,'he'); + event.map = map; + player + .chooseControl(list, "cancel2", function () { + if (!lib.skill.spjiedao.check(_status.event.getTrigger(), player)) + return "cancel2"; + return get.cnNumber(_status.event.goon, true); + }) + .set("prompt", get.prompt2("spjiedao", trigger.player)) + .set("goon", num); + "step 1"; + if (result.control == "cancel2") return; + player.logSkill("spjiedao", trigger.player); + var num = event.map[result.control] || 1; + trigger.num += num; + var next = game.createEvent("spjiedao_after", null, trigger.getParent()); + next.player = player; + next.target = trigger.player; + next.num = num; + next.setContent(function () { + if (target.isIn()) player.chooseToDiscard(num, true, "he"); }); }, }, - biaozhao:{ - audio:2, - intro:{ - content:"expansion", - markcount:'expansion', + biaozhao: { + audio: 2, + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - trigger:{ - player:"phaseJieshuBegin", + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0&&!player.getExpansions('biaozhao').length; + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0 && !player.getExpansions("biaozhao").length; }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('biaozhao'),'将一张牌置于武将牌上作为“表”').ai=function(card){ - return 6-get.value(card); - } - 'step 1' - if(result.bool){ - player.logSkill('biaozhao'); - player.addToExpansion(result.cards,player,'give').gaintag.add('biaozhao'); + content: function () { + "step 0"; + player.chooseCard("he", get.prompt("biaozhao"), "将一张牌置于武将牌上作为“表”").ai = + function (card) { + return 6 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.logSkill("biaozhao"); + player.addToExpansion(result.cards, player, "give").gaintag.add("biaozhao"); } }, - ai:{ - notemp:true, + ai: { + notemp: true, }, - group:['biaozhao2','biaozhao3'], + group: ["biaozhao2", "biaozhao3"], }, - biaozhao2:{ - trigger:{ - global:["loseAsyncAfter","loseAfter","cardsDiscardAfter"], + biaozhao2: { + trigger: { + global: ["loseAsyncAfter", "loseAfter", "cardsDiscardAfter"], }, - forced:true, - audio:"biaozhao", - filter:function(event,player){ - if(event.name=='loseAsyncAfter'&&event.type!='discard') return false; - if(event.name=='lose'&&(event.getlx===false||event.position!=ui.discardPile)) return false; - var cards=player.getExpansions('biaozhao'); - if(!cards.length) return false; - var suit=get.suit(cards[0]); - var num=get.number(cards[0]); - var cards=event.getd(); - for(var card of cards){ - if(get.suit(card)==suit&&get.number(card)==num) return true; + forced: true, + audio: "biaozhao", + filter: function (event, player) { + if (event.name == "loseAsyncAfter" && event.type != "discard") return false; + if (event.name == "lose" && (event.getlx === false || event.position != ui.discardPile)) + return false; + var cards = player.getExpansions("biaozhao"); + if (!cards.length) return false; + var suit = get.suit(cards[0]); + var num = get.number(cards[0]); + var cards = event.getd(); + for (var card of cards) { + if (get.suit(card) == suit && get.number(card) == num) return true; } return false; }, - content:function(){ - "step 0" - var card=player.getExpansions('biaozhao')[0]; - if(trigger.getParent().name=='discard'){ - trigger.player.gain(card,player,'give','bySelf'); - } - else{ + content: function () { + "step 0"; + var card = player.getExpansions("biaozhao")[0]; + if (trigger.getParent().name == "discard") { + trigger.player.gain(card, player, "give", "bySelf"); + } else { player.loseToDiscardpile(card); } - "step 1" + "step 1"; player.loseHp(); }, }, - biaozhao3:{ - trigger:{ - player:"phaseZhunbeiBegin", + biaozhao3: { + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - charlotte:true, - audio:"biaozhao", - filter:function(event,player){ - return player.getExpansions('biaozhao').length>0; + forced: true, + charlotte: true, + audio: "biaozhao", + filter: function (event, player) { + return player.getExpansions("biaozhao").length > 0; }, - content:function(){ - "step 0" - var card=player.getExpansions('biaozhao')[0]; + content: function () { + "step 0"; + var card = player.getExpansions("biaozhao")[0]; player.loseToDiscardpile(card); - "step 1" - event.num=0; - game.countPlayer(function(current){ - if(current.countCards('h')>event.num) event.num=current.countCards('h'); + "step 1"; + event.num = 0; + game.countPlayer(function (current) { + if (current.countCards("h") > event.num) event.num = current.countCards("h"); }); - player.chooseTarget('是否令一名角色将手牌摸至'+event.num+'张并回复1点体力?').ai=function(target){ - var num=Math.min(event.num-target.countCards('h'),5); - if(target.isDamaged()) num++; - return num*get.attitude(_status.event.player,target); - }; - "step 2" - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - var draw=Math.min(num-target.countCards('h'),5); - if(draw) target.draw(draw); + player.chooseTarget("是否令一名角色将手牌摸至" + event.num + "张并回复1点体力?").ai = + function (target) { + var num = Math.min(event.num - target.countCards("h"), 5); + if (target.isDamaged()) num++; + return num * get.attitude(_status.event.player, target); + }; + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + var draw = Math.min(num - target.countCards("h"), 5); + if (draw) target.draw(draw); target.recover(); } }, }, - yechou:{ - audio:2, - trigger:{ - player:"die", + yechou: { + audio: 2, + trigger: { + player: "die", }, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'wood', - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('yechou'),function(card,player,target){ - return player!=target&&target.getDamagedHp()>1 - }).set('forceDie',true).set('ai',function(target){ - let att=get.attitude(_status.event.player,target); - if(att>0) return 0; - att=Math.sqrt(0.01-att); - return att*(get.distance(_status.currentPhase,target,'absolute')||game.players.length); - }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('yechou',target); - player.line(target,'green'); - target.addTempSkill('yechou2',{player:'phaseZhunbeiBegin'}); + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "wood", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("yechou"), function (card, player, target) { + return player != target && target.getDamagedHp() > 1; + }) + .set("forceDie", true) + .set("ai", function (target) { + let att = get.attitude(_status.event.player, target); + if (att > 0) return 0; + att = Math.sqrt(0.01 - att); + return ( + att * + (get.distance(_status.currentPhase, target, "absolute") || + game.players.length) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("yechou", target); + player.line(target, "green"); + target.addTempSkill("yechou2", { player: "phaseZhunbeiBegin" }); } }, - ai:{ - expose:0.5, - maixie_defend:true + ai: { + expose: 0.5, + maixie_defend: true, }, }, - "yechou2":{ - mark:true, - marktext:"仇", - intro:{ - content:"每个回合结束时失去1点体力直到回合开始", + yechou2: { + mark: true, + marktext: "仇", + intro: { + content: "每个回合结束时失去1点体力直到回合开始", }, - trigger:{ - global:"phaseAfter", + trigger: { + global: "phaseAfter", + }, + forced: true, + content: function () { + player.loseHp(); }, - forced:true, - content:function(){player.loseHp()}, }, - yanjiao:{ - audio:2, - ai:{ - order:10, - result:{ - player:1, - target:1.1, + yanjiao: { + audio: 2, + ai: { + order: 10, + result: { + player: 1, + target: 1.1, }, }, - enable:"phaseUse", - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - "step 0" - var num=4; - if(player.storage.xingshen){ - num+=player.storage.xingshen; - player.storage.xingshen=0; - player.unmarkSkill('xingshen'); + content: function () { + "step 0"; + var num = 4; + if (player.storage.xingshen) { + num += player.storage.xingshen; + player.storage.xingshen = 0; + player.unmarkSkill("xingshen"); } - if(player.storage.olxingshen){ - num+=player.storage.olxingshen; - player.storage.olxingshen=0; - player.unmarkSkill('olxingshen'); + if (player.storage.olxingshen) { + num += player.storage.olxingshen; + player.storage.olxingshen = 0; + player.unmarkSkill("olxingshen"); } - num=Math.min(10,num); - event.cards=get.cards(num); + num = Math.min(10, num); + event.cards = get.cards(num); game.cardsGotoOrdering(event.cards); player.showCards(event.cards); - "step 1" - event.getedResult=lib.skill.yanjiao.getResult(cards); - if(!event.getedResult.length){ - player.addTempSkill('yanjiao2'); + "step 1"; + event.getedResult = lib.skill.yanjiao.getResult(cards); + if (!event.getedResult.length) { + player.addTempSkill("yanjiao2"); event.finish(); } - "step 2" - target.chooseControl("自动分配","手动分配").set("prompt","【严教】:是否让系统自动分配方案?").ai=function(){ + "step 2"; + target + .chooseControl("自动分配", "手动分配") + .set("prompt", "【严教】:是否让系统自动分配方案?").ai = function () { return 0; }; - "step 3" - if(result.control=="手动分配"){ + "step 3"; + if (result.control == "手动分配") { event.goto(8); } - "step 4" - event.index=0; - event.togain=event.getedResult[event.index]; - target.showCards(event.togain[0],get.translation(target)+'分出的第一份牌'); - "step 5" - target.showCards(event.togain[1],get.translation(target)+'分出的第二份牌'); - "step 6" - target.chooseControl().set('choiceList',[ - '获得'+get.translation(event.togain[0]), - '获得'+get.translation(event.togain[1]) - ]).ai=function(){return Math.random()<0.5?1:0}; - "step 7" - var list=[ - [target,event.togain[result.index]], - [player,event.togain[1-result.index]] + "step 4"; + event.index = 0; + event.togain = event.getedResult[event.index]; + target.showCards(event.togain[0], get.translation(target) + "分出的第一份牌"); + "step 5"; + target.showCards(event.togain[1], get.translation(target) + "分出的第二份牌"); + "step 6"; + target + .chooseControl() + .set("choiceList", [ + "获得" + get.translation(event.togain[0]), + "获得" + get.translation(event.togain[1]), + ]).ai = function () { + return Math.random() < 0.5 ? 1 : 0; + }; + "step 7"; + var list = [ + [target, event.togain[result.index]], + [player, event.togain[1 - result.index]], ]; game.loseAsync({ - gain_list:list, - giver:target, - animate:'gain2', - }).setContent('gaincardMultiple'); - if(event.togain[2].length>1) player.addTempSkill('yanjiao2'); + gain_list: list, + giver: target, + animate: "gain2", + }).setContent("gaincardMultiple"); + if (event.togain[2].length > 1) player.addTempSkill("yanjiao2"); event.finish(); - "step 8" - var next=target.chooseToMove('严教:分出点数相等的两组牌'); - next.set('chooseTime',(cards.length*4).toString()); - next.set('list',[ - ['未分配',cards,function(list){ - var num=0; - for(var i of list) num+=i.number; - return '未分配(点数和'+num+')'; - }], - ['第一组',[],function(list){ - var num=0; - for(var i of list) num+=i.number; - return '第一组(点数和'+num+')'; - }], - ['第二组',[],function(list){ - var num=0; - for(var i of list) num+=i.number; - return '第二组(点数和'+num+')'; - }], + "step 8"; + var next = target.chooseToMove("严教:分出点数相等的两组牌"); + next.set("chooseTime", (cards.length * 4).toString()); + next.set("list", [ + [ + "未分配", + cards, + function (list) { + var num = 0; + for (var i of list) num += i.number; + return "未分配(点数和" + num + ")"; + }, + ], + [ + "第一组", + [], + function (list) { + var num = 0; + for (var i of list) num += i.number; + return "第一组(点数和" + num + ")"; + }, + ], + [ + "第二组", + [], + function (list) { + var num = 0; + for (var i of list) num += i.number; + return "第二组(点数和" + num + ")"; + }, + ], ]); - next.set('filterOk',function(moved){ - var num1=0; - for(var i of moved[1]) num1+=i.number; - if(num1==0) return false; - var num2=0; - for(var i of moved[2]) num2+=i.number; - return num1==num2; - }) - next.set('processAI',()=>false); - "step 9" - if(result.bool){ - var moved=result.moved; - event.getedResult=[[moved[1],moved[2],moved[0]]]; + next.set("filterOk", function (moved) { + var num1 = 0; + for (var i of moved[1]) num1 += i.number; + if (num1 == 0) return false; + var num2 = 0; + for (var i of moved[2]) num2 += i.number; + return num1 == num2; + }); + next.set("processAI", () => false); + "step 9"; + if (result.bool) { + var moved = result.moved; + event.getedResult = [[moved[1], moved[2], moved[0]]]; event.goto(4); - } - else{ - player.addTempSkill('yanjiao2'); + } else { + player.addTempSkill("yanjiao2"); } }, - getResult:function(cards){ - var cl=cards.length; - var maxmium=Math.pow(3,cl); - var filter=function(list){ - if(!list[1].length||!list[0].length) return false; - var num1=0; - for(var i=0;i4) player.storage.xingshen=4; - player.markSkill('xingshen'); + frequent: true, + content: function () { + player.draw(player.isMinHandcard() ? 2 : 1); + if (!player.storage.xingshen) player.storage.xingshen = 0; + player.storage.xingshen += player.isMinHp() ? 2 : 1; + if (player.storage.xingshen > 4) player.storage.xingshen = 4; + player.markSkill("xingshen"); }, }, - pingjian:{ - initList:function(){ - var list=[]; - if(_status.connectMode) list=get.charactersOL(); - else{ - var list=[]; - for(var i in lib.character){ - if(!lib.filter.characterDisabled2(i)&&!lib.filter.characterDisabled(i)) list.push(i); + pingjian: { + initList: function () { + var list = []; + if (_status.connectMode) list = get.charactersOL(); + else { + var list = []; + for (var i in lib.character) { + if (!lib.filter.characterDisabled2(i) && !lib.filter.characterDisabled(i)) + list.push(i); } } - game.countPlayer2(function(current){ + game.countPlayer2(function (current) { list.remove(current.name); list.remove(current.name1); list.remove(current.name2); }); - _status.characterlist=list; + _status.characterlist = list; }, - init:function(player){ - player.addSkill('pingjian_check'); - if(!player.storage.pingjian_check) player.storage.pingjian_check={}; + init: function (player) { + player.addSkill("pingjian_check"); + if (!player.storage.pingjian_check) player.storage.pingjian_check = {}; }, - audio:2, - trigger:{player:['damageEnd','phaseJieshuBegin']}, - frequent:true, - content:function(){ - 'step 0' - if(!_status.characterlist){ + audio: 2, + trigger: { player: ["damageEnd", "phaseJieshuBegin"] }, + frequent: true, + content: function () { + "step 0"; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } - var allList=_status.characterlist.slice(0); - game.countPlayer(function(current){ - if(current.name&&lib.character[current.name]&¤t.name.indexOf('gz_shibing')!=0&¤t.name.indexOf('gz_jun_')!=0) allList.add(current.name); - if(current.name1&&lib.character[current.name1]&¤t.name1.indexOf('gz_shibing')!=0&¤t.name1.indexOf('gz_jun_')!=0) allList.add(current.name1); - if(current.name2&&lib.character[current.name2]&¤t.name2.indexOf('gz_shibing')!=0&¤t.name2.indexOf('gz_jun_')!=0) allList.add(current.name2); + var allList = _status.characterlist.slice(0); + game.countPlayer(function (current) { + if ( + current.name && + lib.character[current.name] && + current.name.indexOf("gz_shibing") != 0 && + current.name.indexOf("gz_jun_") != 0 + ) + allList.add(current.name); + if ( + current.name1 && + lib.character[current.name1] && + current.name1.indexOf("gz_shibing") != 0 && + current.name1.indexOf("gz_jun_") != 0 + ) + allList.add(current.name1); + if ( + current.name2 && + lib.character[current.name2] && + current.name2.indexOf("gz_shibing") != 0 && + current.name2.indexOf("gz_jun_") != 0 + ) + allList.add(current.name2); }); - var list=[]; - var skills=[]; - var map=[]; + var list = []; + var skills = []; + var map = []; allList.randomSort(); - var name2=event.triggername; - for(var i=0;i2) break; + if (list.length > 2) break; } - if(skills.length){ - event.list=list; - player.chooseControl(skills).set('dialog',['评鉴:请选择尝试发动的技能',[list,'character']]); - } - else event.finish(); - 'step 1' - player.markAuto('pingjian',[result.control]); + if (skills.length) { + event.list = list; + player + .chooseControl(skills) + .set("dialog", ["评鉴:请选择尝试发动的技能", [list, "character"]]); + } else event.finish(); + "step 1"; + player.markAuto("pingjian", [result.control]); player.addTempSkill(result.control); - player.storage.pingjian_check[result.control]=(trigger.name=='damage'?trigger:'phaseJieshu'); - var name=event.list.find(name=>lib.character[name][3].includes(result.control)); + player.storage.pingjian_check[result.control] = + trigger.name == "damage" ? trigger : "phaseJieshu"; + var name = event.list.find((name) => lib.character[name][3].includes(result.control)); // if(name) lib.skill.rehuashen.createAudio(name,result.control,'xushao'); - if(name) game.broadcastAll((player,name)=>player.tempname.add(name),player,name); + if (name) game.broadcastAll((player, name) => player.tempname.add(name), player, name); }, - group:'pingjian_use', - phaseUse_special:[], - ai:{threaten:5}, + group: "pingjian_use", + phaseUse_special: [], + ai: { threaten: 5 }, }, - pingjian_use:{ - audio:'pingjian', - enable:'phaseUse', - usable:1, - prompt:()=>lib.translate.pingjian_info, - content:function(){ - 'step 0' - var list=[]; - var skills=[]; - var map=[]; - var evt=event.getParent(2); - if(!_status.characterlist){ + pingjian_use: { + audio: "pingjian", + enable: "phaseUse", + usable: 1, + prompt: () => lib.translate.pingjian_info, + content: function () { + "step 0"; + var list = []; + var skills = []; + var map = []; + var evt = event.getParent(2); + if (!_status.characterlist) { lib.skill.pingjian.initList(); } - var allList=_status.characterlist.slice(0); - game.countPlayer(function(current){ - if(current.name&&lib.character[current.name]&¤t.name.indexOf('gz_shibing')!=0&¤t.name.indexOf('gz_jun_')!=0) allList.add(current.name); - if(current.name1&&lib.character[current.name1]&¤t.name1.indexOf('gz_shibing')!=0&¤t.name1.indexOf('gz_jun_')!=0) allList.add(current.name1); - if(current.name2&&lib.character[current.name2]&¤t.name2.indexOf('gz_shibing')!=0&¤t.name2.indexOf('gz_jun_')!=0) allList.add(current.name2); + var allList = _status.characterlist.slice(0); + game.countPlayer(function (current) { + if ( + current.name && + lib.character[current.name] && + current.name.indexOf("gz_shibing") != 0 && + current.name.indexOf("gz_jun_") != 0 + ) + allList.add(current.name); + if ( + current.name1 && + lib.character[current.name1] && + current.name1.indexOf("gz_shibing") != 0 && + current.name1.indexOf("gz_jun_") != 0 + ) + allList.add(current.name1); + if ( + current.name2 && + lib.character[current.name2] && + current.name2.indexOf("gz_shibing") != 0 && + current.name2.indexOf("gz_jun_") != 0 + ) + allList.add(current.name2); }); allList.randomSort(); - for(var i=0;i2) break; + if (list.length > 2) break; } - if(skills.length){ - event.list=list; - player.chooseControl(skills).set('dialog',['评鉴:请选择尝试发动的技能',[list,'character']]); - } - else event.finish(); - 'step 1' - player.markAuto('pingjian',[result.control]); + if (skills.length) { + event.list = list; + player + .chooseControl(skills) + .set("dialog", ["评鉴:请选择尝试发动的技能", [list, "character"]]); + } else event.finish(); + "step 1"; + player.markAuto("pingjian", [result.control]); player.addTempSkill(result.control); - player.storage.pingjian_check[result.control]='phaseUse'; - var name=event.list.find(name=>lib.character[name][3].includes(result.control)); + player.storage.pingjian_check[result.control] = "phaseUse"; + var name = event.list.find((name) => lib.character[name][3].includes(result.control)); // if(name) lib.skill.rehuashen.createAudio(name,result.control,'xushao'); - if(name) game.broadcastAll((player,name)=>player.tempname.add(name),player,name); + if (name) game.broadcastAll((player, name) => player.tempname.add(name), player, name); }, - ai:{order:12,result:{player:1}}, + ai: { order: 12, result: { player: 1 } }, }, - pingjian_check:{ - charlotte:true, - trigger:{player:['useSkill','logSkillBegin']}, - filter:function(event,player){ - var info=get.info(event.skill); - if(info&&info.charlotte) return false; - var skill=event.sourceSkill||event.skill; + pingjian_check: { + charlotte: true, + trigger: { player: ["useSkill", "logSkillBegin"] }, + filter: function (event, player) { + var info = get.info(event.skill); + if (info && info.charlotte) return false; + var skill = event.sourceSkill || event.skill; return player.storage.pingjian_check[skill]; }, - direct:true, - firstDo:true, - priority:Infinity, - content:function(){ - var skill=trigger.sourceSkill||trigger.skill; + direct: true, + firstDo: true, + priority: Infinity, + content: function () { + var skill = trigger.sourceSkill || trigger.skill; player.removeSkill(skill); - const names=player.tempname&&player.tempname.filter(i=>lib.character[i][3].includes(skill)); - if(names) game.broadcastAll((player,names)=>player.tempname.removeArray(names),player,names); + const names = + player.tempname && player.tempname.filter((i) => lib.character[i][3].includes(skill)); + if (names) + game.broadcastAll( + (player, names) => player.tempname.removeArray(names), + player, + names + ); delete player.storage.pingjian_check[skill]; }, - group:'pingjian_check2', + group: "pingjian_check2", }, - pingjian_check2:{ - charlotte:true, - trigger:{player:['phaseUseEnd','damageEnd','phaseJieshuBegin']}, - filter:function(event,player){ - return Object.keys(player.storage.pingjian_check).find(function(skill){ - if(event.name!='damage') return player.storage.pingjian_check[skill]==event.name; - return player.storage.pingjian_check[skill]==event; + pingjian_check2: { + charlotte: true, + trigger: { player: ["phaseUseEnd", "damageEnd", "phaseJieshuBegin"] }, + filter: function (event, player) { + return Object.keys(player.storage.pingjian_check).find(function (skill) { + if (event.name != "damage") return player.storage.pingjian_check[skill] == event.name; + return player.storage.pingjian_check[skill] == event; }); }, - direct:true, - lastDo:true, - priority:-Infinity, - content:function(){ - var skills=Object.keys(player.storage.pingjian_check).filter(function(skill){ - if(trigger.name!='damage') return player.storage.pingjian_check[skill]==trigger.name; - return player.storage.pingjian_check[skill]==trigger; + direct: true, + lastDo: true, + priority: -Infinity, + content: function () { + var skills = Object.keys(player.storage.pingjian_check).filter(function (skill) { + if (trigger.name != "damage") + return player.storage.pingjian_check[skill] == trigger.name; + return player.storage.pingjian_check[skill] == trigger; }); player.removeSkill(skills); - const names=player.tempname&&player.tempname.filter(i=>skills.some(skill=>lib.character[i][3].includes(skill))); - if(names) game.broadcastAll((player,names)=>player.tempname.removeArray(names),player,names); - for(var skill of skills) delete player.storage.pingjian_check[skill]; + const names = + player.tempname && + player.tempname.filter((i) => + skills.some((skill) => lib.character[i][3].includes(skill)) + ); + if (names) + game.broadcastAll( + (player, names) => player.tempname.removeArray(names), + player, + names + ); + for (var skill of skills) delete player.storage.pingjian_check[skill]; }, }, //上兵伐谋 //伊籍在标包 不会移动 - songshu:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('songshu_reflectionblue',null,null,false)&&player.countCards('h')>0; + songshu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + !player.hasSkill("songshu_reflectionblue", null, null, false) && + player.countCards("h") > 0 + ); }, - filterTarget:function(card,player,target){ - return target!=player&&player.canCompare(target); + filterTarget: function (card, player, target) { + return target != player && player.canCompare(target); }, - content:function(){ - 'step 0' - player.chooseToCompare(target).set('small',get.attitude(player,target)>0); - 'step 1' - if(!result.bool){ - player.draw(2,'nodelay'); + content: function () { + "step 0"; + player.chooseToCompare(target).set("small", get.attitude(player, target) > 0); + "step 1"; + if (!result.bool) { + player.draw(2, "nodelay"); target.draw(2); - player.addTempSkill('songshu_reflectionblue','phaseUseAfter'); - } - else{ - target.addTempSkill('songshu_ai'); + player.addTempSkill("songshu_reflectionblue", "phaseUseAfter"); + } else { + target.addTempSkill("songshu_ai"); } }, - ai:{ - basic:{ - order:1 + ai: { + basic: { + order: 1, }, - expose:0.2, - result:{ - target:function(player,target){ - if(target.hasSkill('songshu_ai',null,null,false)) return 0; - var maxnum=0; - var cards2=target.getCards('h'); - for(var i=0;imaxnum){ - maxnum=get.number(cards2[i]); + expose: 0.2, + result: { + target: function (player, target) { + if (target.hasSkill("songshu_ai", null, null, false)) return 0; + var maxnum = 0; + var cards2 = target.getCards("h"); + for (var i = 0; i < cards2.length; i++) { + if (get.number(cards2[i]) > maxnum) { + maxnum = get.number(cards2[i]); } } - if(maxnum>10) maxnum=10; - if(maxnum<5&&cards2.length>1) maxnum=5; - var cards=player.getCards('h'); - for(var i=0;i 10) maxnum = 10; + if (maxnum < 5 && cards2.length > 1) maxnum = 5; + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + if (get.number(cards[i]) < maxnum) return 1; } return 0; - } - } - } + }, + }, + }, }, - songshu_ai:{charlotte:true}, - songshu_reflectionblue:{charlotte:true}, - sibian:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ + songshu_ai: { charlotte: true }, + songshu_reflectionblue: { charlotte: true }, + sibian: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - event.cards=get.cards(4); + event.cards = get.cards(4); game.cardsGotoOrdering(event.cards); player.showCards(event.cards); - 'step 1' - cards.sort(function(a,b){ - return b.number-a.number; + "step 1"; + cards.sort(function (a, b) { + return b.number - a.number; }); - var gains=[]; - var mx=[cards[0].number,cards[3].number]; - for(var i=0;i0) player.chooseTarget('是否令一名手牌数最少的角色获得'+get.translation(cards),function(card,player,target){ - return target.isMinHandcard(); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); + player.gain(gains, "gain2"); + if (cards.length > 0) + player + .chooseTarget( + "是否令一名手牌数最少的角色获得" + get.translation(cards), + function (card, player, target) { + return target.isMinHandcard(); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); player.addExpose(0.2); - target.gain(cards,'gain2'); + target.gain(cards, "gain2"); } }, }, - lslixun:{ - audio:2, - forced:true, - trigger:{player:'damageBegin4'}, - marktext:'珠', - intro:{ - name2:'珠', - content:'共有#个“珠”', + lslixun: { + audio: 2, + forced: true, + trigger: { player: "damageBegin4" }, + marktext: "珠", + intro: { + name2: "珠", + content: "共有#个“珠”", }, - content:function(){ + content: function () { trigger.cancel(); - player.addMark('lslixun',trigger.num); + player.addMark("lslixun", trigger.num); }, - group:'lslixun_fate', + group: "lslixun_fate", }, - lslixun_fate:{ - audio:'lslixun', - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('lslixun')>0; + lslixun_fate: { + audio: "lslixun", + trigger: { player: "phaseUseBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("lslixun") > 0; }, - content:function(){ - 'step 0' - event.forceDie=true; - _status.lslixun=player.countMark('lslixun'); - player.judge(function(card){ - if(get.number(card)<_status.lslixun) return -_status.lslixun; + content: function () { + "step 0"; + event.forceDie = true; + _status.lslixun = player.countMark("lslixun"); + player.judge(function (card) { + if (get.number(card) < _status.lslixun) return -_status.lslixun; return 1; - }).judge2=function(result){ - return result.bool?true:false; + }).judge2 = function (result) { + return result.bool ? true : false; }; - 'step 1' + "step 1"; delete _status.lslixun; - if(!result.bool){ - player.chooseToDiscard([1,player.countMark('lslixun')],'h').ai=lib.skill.qiangxi.check; - } - else event.finish(); - 'step 2' - var num=player.countMark('lslixun'); - if(result.cards&&result.cards.length) num-=result.cards.length; - if(num) player.loseHp(num); + if (!result.bool) { + player.chooseToDiscard([1, player.countMark("lslixun")], "h").ai = + lib.skill.qiangxi.check; + } else event.finish(); + "step 2"; + var num = player.countMark("lslixun"); + if (result.cards && result.cards.length) num -= result.cards.length; + if (num) player.loseHp(num); }, }, - lskuizhu:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.isMaxHp(true)==false; + lskuizhu: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.isMaxHp(true) == false; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('lskuizhu'),function(card,player,target){ - return target!=player&&target.isMaxHp(); - }).ai=function(target){ - var player=_status.event.player; - var ts=Math.min(5,target.countCards('h')); - var delta=ts-player.countCards('h'); - if(delta<=0) return 0; - if(get.attitude(player,target)<1) return false; - return target.countCards('he',function(card){ - return lib.skill.zhiheng.check(card)>0; - })>1?delta:0; + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("lskuizhu"), function (card, player, target) { + return target != player && target.isMaxHp(); + }).ai = function (target) { + var player = _status.event.player; + var ts = Math.min(5, target.countCards("h")); + var delta = ts - player.countCards("h"); + if (delta <= 0) return 0; + if (get.attitude(player, target) < 1) return false; + return target.countCards("he", function (card) { + return lib.skill.zhiheng.check(card) > 0; + }) > 1 + ? delta + : 0; }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('lskuizhu',target); - player.drawTo(Math.min(5,target.countCards('h'))); - } - else event.finish(); - 'step 2' - if(!player.countCards('h')){ + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("lskuizhu", target); + player.drawTo(Math.min(5, target.countCards("h"))); + } else event.finish(); + "step 2"; + if (!player.countCards("h")) { event.finish(); return; } target.viewHandcards(player); - 'step 3' - if(!target.countCards('h')){ + "step 3"; + if (!target.countCards("h")) { event.finish(); return; } - target.chooseToDiscard(true,'h',[1,player.countCards('h')],'弃置至多'+get.cnNumber(player.countCards('h'))+'张手牌,并获得'+get.translation(player)+'等量的手牌').ai=function(card){ - if(ui.selected.cards.length>1) return -1; - return lib.skill.zhiheng.check.apply(this,arguments) + target.chooseToDiscard( + true, + "h", + [1, player.countCards("h")], + "弃置至多" + + get.cnNumber(player.countCards("h")) + + "张手牌,并获得" + + get.translation(player) + + "等量的手牌" + ).ai = function (card) { + if (ui.selected.cards.length > 1) return -1; + return lib.skill.zhiheng.check.apply(this, arguments); }; - 'step 4' - if(result.bool&&result.cards&&result.cards.length&&player.countGainableCards(target,'h')>0){ - target.gainPlayerCard(player,'h',true,result.cards.length).visible=true; + "step 4"; + if ( + result.bool && + result.cards && + result.cards.length && + player.countGainableCards(target, "h") > 0 + ) { + target.gainPlayerCard(player, "h", true, result.cards.length).visible = true; } - 'step 5' - if(result.bool&&result.cards&&result.cards.length>1){ - var bool=player.storage.lslixun>0!==true; - player.chooseTarget(bool,'令'+get.translation(target)+'对其攻击范围内的一名角色造成1点伤害'+(bool?'':',或点「取消」移去一个“珠”'),function(card,player,target){ - var source=_status.event.source; - return target!=source&&source.inRange(target); - }).set('source',target).set('ai',function(target){ - return get.damageEffect(target,_status.event.source,_status.event.player); - }); - } - else event.finish(); - 'step 6' - if(result.bool&&result.targets&&result.targets.length){ + "step 5"; + if (result.bool && result.cards && result.cards.length > 1) { + var bool = player.storage.lslixun > 0 !== true; + player + .chooseTarget( + bool, + "令" + + get.translation(target) + + "对其攻击范围内的一名角色造成1点伤害" + + (bool ? "" : ",或点「取消」移去一个“珠”"), + function (card, player, target) { + var source = _status.event.source; + return target != source && source.inRange(target); + } + ) + .set("source", target) + .set("ai", function (target) { + return get.damageEffect(target, _status.event.source, _status.event.player); + }); + } else event.finish(); + "step 6"; + if (result.bool && result.targets && result.targets.length) { player.line(result.targets[0]); result.targets[0].damage(target); - } - else{ - player.removeMark('lslixun',1); + } else { + player.removeMark("lslixun", 1); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - xpchijie:{ - audio:2, - trigger:{ - target:'useCardToAfter', + xpchijie: { + audio: 2, + trigger: { + target: "useCardToAfter", }, - filter:function(event,player){ - var evt=event.getParent(); - var targets=evt.targets.slice(evt.num+1); - return event.player!=player&&targets.length>0; + filter: function (event, player) { + var evt = event.getParent(); + var targets = evt.targets.slice(evt.num + 1); + return event.player != player && targets.length > 0; }, - usable:1, - prompt2:function(event,player){ - var evt=event.getParent(); - var targets=evt.targets.slice(evt.num+1); - return '令'+get.translation(event.card)+'对'+get.translation(targets)+'无效'; + usable: 1, + prompt2: function (event, player) { + var evt = event.getParent(); + var targets = evt.targets.slice(evt.num + 1); + return "令" + get.translation(event.card) + "对" + get.translation(targets) + "无效"; }, - check:function(event,player){ - var evt=event.getParent(); - var targets=evt.targets.slice(evt.num+1); - var num=0; - for(var i=0;i0&&!game.hasPlayer2(function(current){ - return current.getHistory('damage',function(evt){ - return evt.card==event.card; - }).length>0; - }); + xpchijie2: { + trigger: { global: "useCardAfter" }, + audio: "xpchijie", + filter: function (event, player) { + return ( + event.player != player && + event.targets.includes(player) && + event.cards.filterInD().length > 0 && + !game.hasPlayer2(function (current) { + return ( + current.getHistory("damage", function (evt) { + return evt.card == event.card; + }).length > 0 + ); + }) + ); }, - usable:1, - check:function(event,player){ - return get.value(event.cards.filterInD(),player,'raw')>0; + usable: 1, + check: function (event, player) { + return get.value(event.cards.filterInD(), player, "raw") > 0; }, - prompt2:function(event,player){ - return '获得'+get.translation(event.cards.filterInD())+'。'; + prompt2: function (event, player) { + return "获得" + get.translation(event.cards.filterInD()) + "。"; }, - content:function(){ - player.gain(trigger.cards.filterInD(),'log','gain2'); + content: function () { + player.gain(trigger.cards.filterInD(), "log", "gain2"); }, }, - xpchijie4:{}, - yinju:{ - audio:2, - enable:'phaseUse', - limited:true, - filterTarget:lib.filter.notMe, - skillAnimation:true, - animationColor:'water', - content:function(){ - player.awakenSkill('yinju'); - player.storage.yinju2=target; - player.addTempSkill('yinju2'); + xpchijie4: {}, + yinju: { + audio: 2, + enable: "phaseUse", + limited: true, + filterTarget: lib.filter.notMe, + skillAnimation: true, + animationColor: "water", + content: function () { + player.awakenSkill("yinju"); + player.storage.yinju2 = target; + player.addTempSkill("yinju2"); }, - ai:{ - result:{ - order:10, - player:function(player,target){ - if(player.countCards('hs',function(card){ - return get.tag(card,'damage')&&player.canUse(card,target); - })>=1&&target.hp<=2) return 0.1; - if(player.countCards('hes',function(card){ - return player.canUse(card,target); - })<=2) return -100; + ai: { + result: { + order: 10, + player: function (player, target) { + if ( + player.countCards("hs", function (card) { + return get.tag(card, "damage") && player.canUse(card, target); + }) >= 1 && + target.hp <= 2 + ) + return 0.1; + if ( + player.countCards("hes", function (card) { + return player.canUse(card, target); + }) <= 2 + ) + return -100; return 1; }, - target:function(player,target){ - return target.isDamaged()?5:3; + target: function (player, target) { + return target.isDamaged() ? 5 : 3; }, - } - } + }, + }, }, - yinju2:{ - trigger:{ - player:'useCardToPlayered', - source:'damageBefore', + yinju2: { + trigger: { + player: "useCardToPlayered", + source: "damageBefore", }, - forced:true, - onremove:true, - filter:function(event,player,name){ - if(name=='useCardToPlayered') return event.target==player.storage.yinju2; - return event.player==player.storage.yinju2; + forced: true, + onremove: true, + filter: function (event, player, name) { + if (name == "useCardToPlayered") return event.target == player.storage.yinju2; + return event.player == player.storage.yinju2; }, - logTarget:function(event){ - return event[event.name=='damage'?'player':'target']; + logTarget: function (event) { + return event[event.name == "damage" ? "player" : "target"]; }, - content:function(){ - 'step 0' - if(trigger.name=='damage'){ + content: function () { + "step 0"; + if (trigger.name == "damage") { trigger.cancel(); trigger.player.recover(trigger.num); event.finish(); + } else { + game.asyncDraw([player, trigger.target]); } - else{ - game.asyncDraw([player,trigger.target]); - } - 'step 1' + "step 1"; game.delayx(); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(target!=player.storage.yinju2) return; - if(card.name=='lebu') return; - if(card.name!=='huogong'&&get.tag(card,'damage')&&target.isDamaged()) [1,0.6,0,2.4]; - return [1,0.6,1,0.6]; + ai: { + effect: { + player: function (card, player, target) { + if (target != player.storage.yinju2) return; + if (card.name == "lebu") return; + if (card.name !== "huogong" && get.tag(card, "damage") && target.isDamaged()) + [1, 0.6, 0, 2.4]; + return [1, 0.6, 1, 0.6]; }, }, }, }, - rewenji:{ - audio:'spwenji', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); + rewenji: { + audio: "spwenji", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he"); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('rewenji'),function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return Math.sqrt(att)/10; - return 5-att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('rewenji',target); - target.chooseCard('he',true,'问计:将一张牌交给'+get.translation(player)); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("rewenji"), function (card, player, target) { + return target != player && target.countCards("he") > 0; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return Math.sqrt(att) / 10; + return 5 - att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("rewenji", target); + target.chooseCard("he", true, "问计:将一张牌交给" + get.translation(player)); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.addTempSkill('rewenji_respond'); - player.storage.rewenji_respond=get.type2(result.cards[0],target); - event.target.give(result.cards,player,true); + "step 2"; + if (result.bool) { + player.addTempSkill("rewenji_respond"); + player.storage.rewenji_respond = get.type2(result.cards[0], target); + event.target.give(result.cards, player, true); } }, - subSkill:{ - respond:{ - onremove:true, - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - audio:'spwenji', - filter:function(event,player){ - return get.type2(event.card)==player.storage.rewenji_respond; + subSkill: { + respond: { + onremove: true, + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + audio: "spwenji", + filter: function (event, player) { + return get.type2(event.card) == player.storage.rewenji_respond; }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player; - })); + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player; + }) + ); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return get.type2(arg.card)==player.storage.rewenji_respond; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return get.type2(arg.card) == player.storage.rewenji_respond; }, }, - } - } + }, + }, }, - spwenji:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); + spwenji: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he"); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('spwenji'),function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0) return Math.sqrt(att)/10; - return 5-att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('spwenji',target); - target.chooseCard('he',true,'问计:将一张牌交给'+get.translation(player)); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("spwenji"), function (card, player, target) { + return target != player && target.countCards("he") > 0; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) return Math.sqrt(att) / 10; + return 5 - att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("spwenji", target); + target.chooseCard("he", true, "问计:将一张牌交给" + get.translation(player)); + } else { event.finish(); } - 'step 2' - if(result.bool){ - player.addTempSkill('spwenji_respond'); - player.storage.spwenji_respond=result.cards[0].name; - event.target.give(result.cards,player,true); + "step 2"; + if (result.bool) { + player.addTempSkill("spwenji_respond"); + player.storage.spwenji_respond = result.cards[0].name; + event.target.give(result.cards, player, true); } }, - subSkill:{ - respond:{ - onremove:true, - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - audio:'spwenji', - filter:function(event,player){ - return event.card.name==player.storage.spwenji_respond; + subSkill: { + respond: { + onremove: true, + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + audio: "spwenji", + filter: function (event, player) { + return event.card.name == player.storage.spwenji_respond; }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player; - })); + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player; + }) + ); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.card.name==player.storage.spwenji_respond; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg.card.name == player.storage.spwenji_respond; }, }, - } - } + }, + }, }, - sptunjiang:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ + sptunjiang: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { //if(player.getHistory('skipped').includes('phaseUse')) return false; - return player.getHistory('useCard',function(evt){ - if(evt.targets&&evt.targets.length&&evt.isPhaseUsing()){ - var targets=evt.targets.slice(0); - while(targets.includes(player)) targets.remove(player); - return targets.length>0; - } - return false; - }).length==0; + return ( + player.getHistory("useCard", function (evt) { + if (evt.targets && evt.targets.length && evt.isPhaseUsing()) { + var targets = evt.targets.slice(0); + while (targets.includes(player)) targets.remove(player); + return targets.length > 0; + } + return false; + }).length == 0 + ); }, - content:function(){ + content: function () { player.draw(game.countGroup()); }, }, - bingzhao:{ - audio:2, - unique:true, - zhuSkill:true, - forced:true, - locked:false, - intro:{ - content:function(group){ - return '已选择了'+get.translation(group)+'势力' + bingzhao: { + audio: 2, + unique: true, + zhuSkill: true, + forced: true, + locked: false, + intro: { + content: function (group) { + return "已选择了" + get.translation(group) + "势力"; }, }, - trigger:{global:['phaseBefore','zhuUpdate']}, - filter:function(event,player){ - if(!lib.group.some(function(group){ - if(group==player.group) return false; - return lib.group.includes(group)||game.hasPlayer(function(current){ - return current.group==group; - }); - })) return false; - return !player.storage.bingzhao&&player.hasZhuSkill('bingzhao')&&(event.name!='phase'||game.phaseNumber==0); - }, - content:function(){ - 'step 0' - var list=lib.group.filter(function(group){ - if(group==player.group) return false; - return lib.group.includes(group)||game.hasPlayer(function(current){ - return current.group==group; - }); - }); - player.chooseControl(list).set('prompt','秉诏:请选择一个其他势力').set('ai',function(){ - var listx=list.slice(0); - listx.sort(function(a,b){ - return game.countPlayer(function(current){ - return current!=player&¤t.group==b; - })-game.countPlayer(function(current){ - return current!=player&¤t.group==a; - }); + trigger: { global: ["phaseBefore", "zhuUpdate"] }, + filter: function (event, player) { + if ( + !lib.group.some(function (group) { + if (group == player.group) return false; + return ( + lib.group.includes(group) || + game.hasPlayer(function (current) { + return current.group == group; + }) + ); }) - return listx[0]; + ) + return false; + return ( + !player.storage.bingzhao && + player.hasZhuSkill("bingzhao") && + (event.name != "phase" || game.phaseNumber == 0) + ); + }, + content: function () { + "step 0"; + var list = lib.group.filter(function (group) { + if (group == player.group) return false; + return ( + lib.group.includes(group) || + game.hasPlayer(function (current) { + return current.group == group; + }) + ); }); - 'step 1' - var group=result.control; - player.popup(get.translation(group)+'势力',get.groupnature(group,'raw')); - game.log(player,'选择了','#y'+get.translation(group)+'势力'); - player.storage.bingzhao=group; - player.markSkill('bingzhao'); + player + .chooseControl(list) + .set("prompt", "秉诏:请选择一个其他势力") + .set("ai", function () { + var listx = list.slice(0); + listx.sort(function (a, b) { + return ( + game.countPlayer(function (current) { + return current != player && current.group == b; + }) - + game.countPlayer(function (current) { + return current != player && current.group == a; + }) + ); + }); + return listx[0]; + }); + "step 1"; + var group = result.control; + player.popup(get.translation(group) + "势力", get.groupnature(group, "raw")); + game.log(player, "选择了", "#y" + get.translation(group) + "势力"); + player.storage.bingzhao = group; + player.markSkill("bingzhao"); }, }, - baijia:{ - audio:2, - audioname:['tw_beimihu'], - unique:true, - derivation:'bmcanshi', - juexingji:true, - ai:{ - combo:'guju' + baijia: { + audio: 2, + audioname: ["tw_beimihu"], + unique: true, + derivation: "bmcanshi", + juexingji: true, + ai: { + combo: "guju", }, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.hasSkill('guju')&&player.storage.guju>=7; + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.hasSkill("guju") && player.storage.guju >= 7; }, - content:function(){ - player.awakenSkill('baijia'); + content: function () { + player.awakenSkill("baijia"); player.gainMaxHp(); player.recover(); - var list=game.filterPlayer(); - for(var i=0;i1; - }; - } - else event.finish(); - 'step 2' - if(result.bool){ - trigger.player.logSkill('bingzhao',player); + player.markSkill("guju"); + "step 1"; + if ( + player.hasZhuSkill("bingzhao", trigger.player) && + trigger.player.group == player.storage.bingzhao && + trigger.player.isIn() + ) { + trigger.player.chooseBool("是否对" + get.translation(player) + "发动【秉诏】?").ai = + function () { + return get.attitude(trigger.player, player) > 1; + }; + } else event.finish(); + "step 2"; + if (result.bool) { + trigger.player.logSkill("bingzhao", player); player.draw(); player.storage.guju++; - player.markSkill('guju'); + player.markSkill("guju"); } }, - ai:{ - combo:'zongkui' - } + ai: { + combo: "zongkui", + }, }, - zongkui:{ - trigger:{ - player:'phaseBeforeEnd', - global:'roundStart', + zongkui: { + trigger: { + player: "phaseBeforeEnd", + global: "roundStart", }, - direct:true, - audio:2, - audioname:['tw_beimihu'], - filter:function(event,player,name){ - return game.hasPlayer(function(current){ - if(name=='roundStart'&&!current.isMinHp()) return false; - return current!=player&&!current.hasMark('zongkui_mark'); + direct: true, + audio: 2, + audioname: ["tw_beimihu"], + filter: function (event, player, name) { + return game.hasPlayer(function (current) { + if (name == "roundStart" && !current.isMinHp()) return false; + return current != player && !current.hasMark("zongkui_mark"); }); }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(function(current){ - if(event.triggername=='roundStart'&&!current.isMinHp()) return false; - return current!=player&&!current.hasMark('zongkui_mark'); + content: function () { + "step 0"; + var targets = game.filterPlayer(function (current) { + if (event.triggername == "roundStart" && !current.isMinHp()) return false; + return current != player && !current.hasMark("zongkui_mark"); }); - if(event.triggername=='roundStart'&&targets.length==1){ - event._result={bool:true,targets:targets}; + if (event.triggername == "roundStart" && targets.length == 1) { + event._result = { bool: true, targets: targets }; + } else { + var next = player + .chooseTarget( + get.prompt("zongkui"), + "令一名" + + (event.triggername == "roundStart" ? "体力值最小的" : "") + + "其他角色获得“傀”标记", + function (card, player, target) { + if (_status.event.round && !target.isMinHp()) return false; + return target != player && !target.hasMark("zongkui_mark"); + } + ) + .set("ai", function (target) { + var num = target.isMinHp() ? 0.5 : 1; + return num * get.threaten(target); + }) + .set("round", event.triggername == "roundStart"); + if (event.triggername == "roundStart") next.set("forced", true); } - else{ - var next=player.chooseTarget(get.prompt('zongkui'),'令一名'+(event.triggername=='roundStart'?'体力值最小的':'')+'其他角色获得“傀”标记',function(card,player,target){ - if(_status.event.round&&!target.isMinHp()) return false; - return target!=player&&!target.hasMark('zongkui_mark'); - }).set('ai',function(target){ - var num=target.isMinHp()?0.5:1; - return num*get.threaten(target); - }).set('round',event.triggername=='roundStart'); - if(event.triggername=='roundStart') next.set('forced',true); - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zongkui',target); - target.addMark('zongkui_mark',1); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zongkui", target); + target.addMark("zongkui_mark", 1); game.delayx(); } }, - subSkill:{ - mark:{ - marktext:'傀', - intro:{ - name2:'傀', - content:'mark' - } - } + subSkill: { + mark: { + marktext: "傀", + intro: { + name2: "傀", + content: "mark", + }, + }, + }, + ai: { + combo: "guju", + threaten: 1.4, }, - ai:{ - combo:'guju', - threaten:1.4 - } }, - "xinfu_langxi":{ - audio:2, - trigger:{ - player:"phaseZhunbeiBegin", + xinfu_langxi: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", }, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.hp<=player.hp; + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.hp <= player.hp; }); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('xinfu_langxi'),'对一名体力值不大于你的其他角色造成0-2点随机伤害',function(card,player,target){ - return target.hp<=player.hp&&target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('xinfu_langxi',result.targets); - var num=[1,2,0].randomGet(); - if(get.isLuckyStar(player)) num=2; - player.line(result.targets[0],'green'); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xinfu_langxi"), + "对一名体力值不大于你的其他角色造成0-2点随机伤害", + function (card, player, target) { + return target.hp <= player.hp && target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("xinfu_langxi", result.targets); + var num = [1, 2, 0].randomGet(); + if (get.isLuckyStar(player)) num = 2; + player.line(result.targets[0], "green"); result.targets[0].damage(num); } }, - ai:{ - expose:0.25, - threaten:1.7, + ai: { + expose: 0.25, + threaten: 1.7, }, }, - "xinfu_yisuan":{ - usable:1, - audio:2, - trigger:{ - player:"useCardEnd", + xinfu_yisuan: { + usable: 1, + audio: 2, + trigger: { + player: "useCardEnd", }, - check:function(event,player){ - return get.value(event.cards)+player.maxHp*2-18>0; + check: function (event, player) { + return get.value(event.cards) + player.maxHp * 2 - 18 > 0; }, - prompt2:function(event,player){ - return '你可以减1点体力上限,然后获得'+get.translation(event.cards.filterInD())+'。'; + prompt2: function (event, player) { + return "你可以减1点体力上限,然后获得" + get.translation(event.cards.filterInD()) + "。"; }, - filter:function(event,player){ - return player.isPhaseUsing()&&get.type(event.card)=='trick'&&event.cards.filterInD().length>0; + filter: function (event, player) { + return ( + player.isPhaseUsing() && + get.type(event.card) == "trick" && + event.cards.filterInD().length > 0 + ); }, - content:function(){ + content: function () { player.loseMaxHp(); - player.gain(trigger.cards.filterInD(),'gain2','log'); + player.gain(trigger.cards.filterInD(), "gain2", "log"); }, }, - "xinfu_xingluan":{ - usable:1, - audio:2, - trigger:{ - player:"useCardAfter", + xinfu_xingluan: { + usable: 1, + audio: 2, + trigger: { + player: "useCardAfter", }, - filter:function(event,player){ - if(!player.isPhaseUsing()) return false; - if(get.type(event.card)==undefined) return false; - return (event.targets&&event.targets.length==1); + filter: function (event, player) { + if (!player.isPhaseUsing()) return false; + if (get.type(event.card) == undefined) return false; + return event.targets && event.targets.length == 1; }, - content:function(){ - var card=get.cardPile2(function(card){ - return card.number==6; + content: function () { + var card = get.cardPile2(function (card) { + return card.number == 6; }); - if(!card){ - player.chat('无牌可得了吗'); - game.log('但是牌堆里面已经没有点数为6的牌了!'); + if (!card) { + player.chat("无牌可得了吗"); + game.log("但是牌堆里面已经没有点数为6的牌了!"); event.finish(); return; } - player.gain(card,'gain2'); + player.gain(card, "gain2"); }, }, - "xinfu_lveming":{ - init:function(player){ - player.storage.xinfu_lveming=0; + xinfu_lveming: { + init: function (player) { + player.storage.xinfu_lveming = 0; }, - mark:true, - intro:{ - content:"已发动过#次", + mark: true, + intro: { + content: "已发动过#次", }, - audio:2, - enable:"phaseUse", - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('e')get.strNumber(i)); - target.chooseControl(list).set('ai',function(){ - return get.rand(0,12); - }).set('prompt','请选择一个点数'); - "step 1" - if(result.control){ - target.$damagepop(result.control,'thunder'); - var num=result.index+1; - event.num=num; + content: function () { + "step 0"; + var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].map((i) => get.strNumber(i)); + target + .chooseControl(list) + .set("ai", function () { + return get.rand(0, 12); + }) + .set("prompt", "请选择一个点数"); + "step 1"; + if (result.control) { + target.$damagepop(result.control, "thunder"); + var num = result.index + 1; + event.num = num; + } else { + target.$damagepop("K", "thunder"); + event.num = 13; } - else{ - target.$damagepop('K','thunder'); - event.num=13; - } - game.log(target,'选择的点数是','#y'+get.strNumber(event.num)); + game.log(target, "选择的点数是", "#y" + get.strNumber(event.num)); player.storage.xinfu_lveming++; - player.judge(function(card){ - if(card.number==_status.event.getParent('xinfu_lveming').num) return 4; + player.judge(function (card) { + if (card.number == _status.event.getParent("xinfu_lveming").num) return 4; return 0; }); - "step 2" - if(result.bool==true){ + "step 2"; + if (result.bool == true) { target.damage(2); - } - else{ - var card=target.getCards('hej').randomGet(); - player.gain(card,target,'giveAuto','bySelf'); + } else { + var card = target.getCards("hej").randomGet(); + player.gain(card, target, "giveAuto", "bySelf"); } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - var numj=target.countCards('j'); - var numhe=target.countCards('he'); - if(numhe==0) return numj>0?6:-6; - return -6-(numj+1)/numhe; + ai: { + order: 9, + result: { + target: function (player, target) { + var numj = target.countCards("j"); + var numhe = target.countCards("he"); + if (numhe == 0) return numj > 0 ? 6 : -6; + return -6 - (numj + 1) / numhe; }, }, - threaten:1.1, + threaten: 1.1, }, }, - "xinfu_tunjun":{ - skillAnimation:true, - animationColor:'metal', - limited:true, - unique:true, - enable:"phaseUse", - audio:2, - filter:function(event,player){ - if(player.storage.xinfu_tunjun) return false; - return player.storage.xinfu_lveming&&player.storage.xinfu_lveming>0; + xinfu_tunjun: { + skillAnimation: true, + animationColor: "metal", + limited: true, + unique: true, + enable: "phaseUse", + audio: 2, + filter: function (event, player) { + if (player.storage.xinfu_tunjun) return false; + return player.storage.xinfu_lveming && player.storage.xinfu_lveming > 0; }, - filterTarget:true, - selectTarget:1, - content:function(){ - "step 0" - player.awakenSkill('xinfu_tunjun'); - event.num=player.storage.xinfu_lveming; - event.toequip=[]; - "step 1" - var equip=get.cardPile(function(card){ - var bool1=true; - for(var i=0;i0) event.goto(1); - "step 3" - for (var i=0;i 0) event.goto(1); + "step 3"; + for (var i = 0; i < event.toequip.length; i++) { + target + .chooseUseTarget(event.toequip[i], true) + .set("animate", false) + .set("nopopup", true); } }, - ai:{ - order:function(){ - var player=_status.event.player,num=0; - for(var i=1;i<6;i++){ - num+=player.countEquipableSlot(i); + ai: { + combo: "xinfu_lveming", + order: function () { + var player = _status.event.player, + num = 0; + for (var i = 1; i < 6; i++) { + num += player.countEquipableSlot(i); } - if(num<=2) return 6; - if(player.hp<=2||!game.hasPlayer((current)=>{ - if(player==current||get.attitude(player,current)<0||current.hp<=1) return false; - return current.hp>2||current.countCards('hs')>2; - })) return 1; + if (num <= 2) return 6; + if ( + player.hp <= 2 || + !game.hasPlayer((current) => { + if (player == current || get.attitude(player, current) < 0 || current.hp <= 1) + return false; + return current.hp > 2 || current.countCards("hs") > 2; + }) + ) + return 1; return 0; }, - result:{ - target:function(player,target){ - var num=0; - for(var i=1;i<6;i++){ - num+=target.countEquipableSlot(i); + result: { + target: function (player, target) { + var num = 0; + for (var i = 1; i < 6; i++) { + num += target.countEquipableSlot(i); } return num; - } - } - }, - mark:true, - intro:{ - content:"limited", - }, - init:function(player){ - player.storage.xinfu_tunjun=false; - }, - }, - "xinfu_tanbei":{ - audio:2, - enable:"phaseUse", - usable:1, - filterTarget:function(card,player,target){ - return player!=target; - }, - content:function(){ - "step 0" - if(target.countCards('hej')==0){ - event._result={index:1}; - } - else{ - target.chooseControl().set('choiceList',[ - '令'+get.translation(player)+'随机获得你区域内的一张牌,然后其本回合内不能再对你使用牌。', - '令'+get.translation(player)+'本回合内对你使用牌没有次数与距离限制。', - ]).set('ai',function(){ - var list=[0,1]; - return list.randomGet(); - }); - } - "step 1" - player.addTempSkill('tanbei_effect3'); - if(result.index==0){ - var card=target.getCards('hej').randomGet(); - player.gain(card,target,'giveAuto','bySelf'); - target.addTempSkill('tanbei_effect2'); - } - else{ - target.addTempSkill('tanbei_effect1'); - } - }, - ai:{ - order:function(){ - return [2,4,6,8,10].randomGet(); - }, - result:{ - target:function(player,target){ - return -2-target.countCards('h'); }, }, - threaten:1.1, + }, + mark: true, + intro: { + content: "limited", + }, + init: function (player) { + player.storage.xinfu_tunjun = false; }, }, - tanbei_effect3:{ - charlotte:true, - mod:{ - targetInRange:function(card,player,target){ - if(target.hasSkill('tanbei_effect1')){ + xinfu_tanbei: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target; + }, + content: function () { + "step 0"; + if (target.countCards("hej") == 0) { + event._result = { index: 1 }; + } else { + target + .chooseControl() + .set("choiceList", [ + "令" + + get.translation(player) + + "随机获得你区域内的一张牌,然后其本回合内不能再对你使用牌。", + "令" + get.translation(player) + "本回合内对你使用牌没有次数与距离限制。", + ]) + .set("ai", function () { + var list = [0, 1]; + return list.randomGet(); + }); + } + "step 1"; + player.addTempSkill("tanbei_effect3"); + if (result.index == 0) { + var card = target.getCards("hej").randomGet(); + player.gain(card, target, "giveAuto", "bySelf"); + target.addTempSkill("tanbei_effect2"); + } else { + target.addTempSkill("tanbei_effect1"); + } + }, + ai: { + order: function () { + return [2, 4, 6, 8, 10].randomGet(); + }, + result: { + target: function (player, target) { + return -2 - target.countCards("h"); + }, + }, + threaten: 1.1, + }, + }, + tanbei_effect3: { + charlotte: true, + mod: { + targetInRange: function (card, player, target) { + if (target.hasSkill("tanbei_effect1")) { return true; } }, - cardUsableTarget:function(card,player,target){ - if(target.hasSkill('tanbei_effect1')) return true; + cardUsableTarget: function (card, player, target) { + if (target.hasSkill("tanbei_effect1")) return true; }, - playerEnabled:function(card,player,target){ - if(target.hasSkill('tanbei_effect2')) return false; + playerEnabled: function (card, player, target) { + if (target.hasSkill("tanbei_effect2")) return false; }, }, }, - "xinfu_sidao":{ - audio:2, - trigger:{ - player:'useCardAfter', + xinfu_sidao: { + audio: 2, + trigger: { + player: "useCardAfter", }, - filter:function(event,player){ - if(player.hasSkill('xinfu_sidaoy')||!player.countCards('hs')) return false; - if(!event.targets||!event.targets.length||!event.isPhaseUsing(player)) return false; - var history=player.getHistory('useCard'); - var index=history.indexOf(event)-1; - if(index<0) return false; - var evt=history[index]; - if(!evt||!evt.targets||!evt.targets.length||!evt.isPhaseUsing(player)) return false; - for(var i=0;itarget.getUseValue({name:'sha',cards:cards})?0:1); - } - else if(bool1){ - event.directindex=0; - } - else if(bool2){ - event.directindex=1; - } - else{ - ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + if (bool1 && bool2) { + target + .chooseControl(function () { + return 0; + }) + .set("choiceList", [ + "使用" + get.translation(cards) + "。(没有距离限制)", + "将" + get.translation(cards) + "当做【杀】使用。", + ]) + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + target.getUseValue(card, false) > + target.getUseValue({ name: "sha", cards: cards }) + ? 0 + : 1 + ); + } else if (bool1) { + event.directindex = 0; + } else if (bool2) { + event.directindex = 1; + } else { + ui.cardPile.insertBefore(card, ui.cardPile.firstChild); event.finish(); } - 'step 2' - var card=cards[0]; - if(result&&typeof event.directindex!='number'){ - event.directindex=result.index; + "step 2"; + var card = cards[0]; + if (result && typeof event.directindex != "number") { + event.directindex = result.index; } - if(event.directindex==1){ - target.chooseUseTarget({name:'sha'},cards,true,false).viewAs=false; - } - else{ - target.chooseUseTarget(card,true,false,'nodistance'); + if (event.directindex == 1) { + target.chooseUseTarget({ name: "sha" }, cards, true, false).viewAs = false; + } else { + target.chooseUseTarget(card, true, false, "nodistance"); } }, - ai:{ - order:7, - result:{ - target:1, + ai: { + order: 7, + result: { + target: 1, }, }, }, - "xinfu_bijing":{ - audio:2, - subSkill:{ - lose:{ - trigger:{ - global:"phaseDiscardBegin", + xinfu_bijing: { + audio: 2, + subSkill: { + lose: { + trigger: { + global: "phaseDiscardBegin", }, - audio:'xinfu_bijing', - charlotte:true, - filter:function(event,player){ - if(event.player==player) return false; - return player.getHistory('lose',function(evt){ - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('xinfu_bijing')) return true; - } - }).length>0&&event.player.countCards('he')>0; + audio: "xinfu_bijing", + charlotte: true, + filter: function (event, player) { + if (event.player == player) return false; + return ( + player.getHistory("lose", function (evt) { + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("xinfu_bijing")) return true; + } + }).length > 0 && event.player.countCards("he") > 0 + ); }, - forced:true, - logTarget:'player', - content:function(){ - trigger.player.chooseToDiscard(2,true,'he'); + forced: true, + logTarget: "player", + content: function () { + trigger.player.chooseToDiscard(2, true, "he"); }, - sub:true, + sub: true, }, - discard:{ - trigger:{ - player:"phaseZhunbeiBegin", + discard: { + trigger: { + player: "phaseZhunbeiBegin", }, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.hasCard(card=>card.hasGaintag('xinfu_bijing')&&player.canRecast(card),'h'); + forced: true, + charlotte: true, + filter: function (event, player) { + return player.hasCard( + (card) => card.hasGaintag("xinfu_bijing") && player.canRecast(card), + "h" + ); }, - content:function(){ - player.recast(player.getCards('h',card=>card.hasGaintag('xinfu_bijing')&&player.canRecast(card))); + content: function () { + player.recast( + player.getCards( + "h", + (card) => card.hasGaintag("xinfu_bijing") && player.canRecast(card) + ) + ); }, - sub:true, + sub: true, }, }, - trigger:{ - player:"phaseJieshuBegin", + trigger: { + player: "phaseJieshuBegin", }, - direct:true, - filter:function(player,event){ - return event.countCards('h')>0; + direct: true, + filter: function (player, event) { + return event.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('xinfu_bijing'),'h',[1,2]).set('ai',function(card){ - if(card.name=='shan') return 6; - return 6-get.value(card); + content: function () { + "step 0"; + player.chooseCard(get.prompt2("xinfu_bijing"), "h", [1, 2]).set("ai", function (card) { + if (card.name == "shan") return 6; + return 6 - get.value(card); }); - 'step 1' - if(result.bool){ - player.logSkill('xinfu_bijing'); - player.addGaintag(result.cards,'xinfu_bijing'); - player.addSkill('xinfu_bijing_lose'); - player.addSkill('xinfu_bijing_discard'); + "step 1"; + if (result.bool) { + player.logSkill("xinfu_bijing"); + player.addGaintag(result.cards, "xinfu_bijing"); + player.addSkill("xinfu_bijing_lose"); + player.addSkill("xinfu_bijing_discard"); } }, }, - xinfu_zhenxing:{ - audio:2, - trigger:{ - player:["damageEnd","phaseJieshuBegin"], + xinfu_zhenxing: { + audio: 2, + trigger: { + player: ["damageEnd", "phaseJieshuBegin"], }, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('一张','两张','三张','cancel2').set('prompt',get.prompt2('xinfu_zhenxing')).set('',function(){return 0}); - 'step 1' - if(result.control=='cancel2') event.finish(); - else{ - player.logSkill('xinfu_zhenxing'); - event.num={一张:1,两张:2,三张:3}[result.control]; + direct: true, + content: function () { + "step 0"; + player + .chooseControl("一张", "两张", "三张", "cancel2") + .set("prompt", get.prompt2("xinfu_zhenxing")) + .set("", function () { + return 0; + }); + "step 1"; + if (result.control == "cancel2") event.finish(); + else { + player.logSkill("xinfu_zhenxing"); + event.num = { 一张: 1, 两张: 2, 三张: 3 }[result.control]; } - 'step 2' - event.cards=get.cards(num); - player.chooseButton(['【镇行】:请选择要获得的牌',event.cards]).set('filterButton',function(button){ - var cards=_status.event.cards; - for(var i=0;i=0;i--){ - if(result.bool&&result.links.includes(event.cards[i])){ - player.gain(event.cards[i],'gain2'); - } - else{ + "step 2"; + event.cards = get.cards(num); + player + .chooseButton(["【镇行】:请选择要获得的牌", event.cards]) + .set("filterButton", function (button) { + var cards = _status.event.cards; + for (var i = 0; i < cards.length; i++) { + if (button.link != cards[i] && get.suit(cards[i]) == get.suit(button.link)) + return false; + } + return true; + }) + .set("ai", function (button) { + return get.value(button.link); + }) + .set("cards", event.cards); + "step 3"; + var tothrow = []; + for (var i = event.cards.length - 1; i >= 0; i--) { + if (result.bool && result.links.includes(event.cards[i])) { + player.gain(event.cards[i], "gain2"); + } else { event.cards[i].fix(); - ui.cardPile.insertBefore(event.cards[i],ui.cardPile.childNodes[0]); + ui.cardPile.insertBefore(event.cards[i], ui.cardPile.childNodes[0]); } } game.updateRoundNumber(); }, }, - "xinfu_qianxin":{ - audio:2, - group:["xinfu_qianxin2"], - enable:"phaseUse", - usable:1, - onChooseToUse:function(event){ - if(!game.online){ - var num1=game.players.length-1; - var player=event.player; - var num2=ui.cardPile.childElementCount; - var num3=num2; - if(num1>num2) num3=0; - else if(player.storage.xinfu_qianxin){ - for(var i=0;i num2) num3 = 0; + else if (player.storage.xinfu_qianxin) { + for (var i = 0; i < num2; i++) { + if (player.storage.xinfu_qianxin.includes(ui.cardPile.childNodes[i])) { + num3 = 0; + break; } } } - event.set('qianxinNum',num3); + event.set("qianxinNum", num3); } }, - filter:function(event,player){ - return event.qianxinNum&&event.qianxinNum>0; + filter: function (event, player) { + return event.qianxinNum && event.qianxinNum > 0; }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - filterCard:true, - selectCard:function(){ - var num1=game.players.length-1; - var num2=_status.event.qianxinNum; - return [1,Math.floor(num2/num1)]; + filterCard: true, + selectCard: function () { + var num1 = game.players.length - 1; + var num2 = _status.event.qianxinNum; + return [1, Math.floor(num2 / num1)]; }, - discard:false, - check:function(){ + discard: false, + check: function () { return -1; }, - delay:false, - lose:false, - prompt:function(){ - return '选择一名角色并将任意张手牌放置于牌堆中'+get.cnNumber(game.players.length)+'倍数的位置(先选择的牌在上)'; + delay: false, + lose: false, + prompt: function () { + return ( + "选择一名角色并将任意张手牌放置于牌堆中" + + get.cnNumber(game.players.length) + + "倍数的位置(先选择的牌在上)" + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.$throw(cards.length); - player.storage.xinfu_qianxin=cards.slice(0); - player.storage.xinfu_qianxin2=target; + player.storage.xinfu_qianxin = cards.slice(0); + player.storage.xinfu_qianxin2 = target; //cards.reverse(); - player.lose(cards,ui.cardPile).insert_index=function(event,card){ - var num1=game.players.length,i=event.cards.indexOf(card); - var num3=num1*(i+1)-1; + player.lose(cards, ui.cardPile).insert_index = function (event, card) { + var num1 = game.players.length, + i = event.cards.indexOf(card); + var num3 = num1 * (i + 1) - 1; return ui.cardPile.childNodes[num3]; }; - 'step 1' + "step 1"; game.updateRoundNumber(); - game.log(player,'把',get.cnNumber(cards.length),'张牌放在了牌堆里'); + game.log(player, "把", get.cnNumber(cards.length), "张牌放在了牌堆里"); game.delayx(); }, - ai:{ - order:1, - result:{ - target:-1, + ai: { + order: 1, + result: { + target: -1, }, }, }, - "xinfu_qianxin2":{ - subSkill:{ - dis:{ - mod:{ - maxHandcard:function(player,num){ - return num-2; + xinfu_qianxin2: { + subSkill: { + dis: { + mod: { + maxHandcard: function (player, num) { + return num - 2; }, }, - sub:true, + sub: true, }, }, - forced:true, - locked:false, - audio:'xinfu_qianxin', - logTarget:'player', - trigger:{ - global:"phaseDiscardBegin", + forced: true, + locked: false, + audio: "xinfu_qianxin", + logTarget: "player", + trigger: { + global: "phaseDiscardBegin", }, - filter:function(event,player){ - if(player.storage.xinfu_qianxin2!=event.player) return false; - if(!player.storage.xinfu_qianxin) return false; - var hs=event.player.getCards('h'); - var cs=player.storage.xinfu_qianxin; - var bool=false; - var history=event.player.getHistory('gain') - for(var i=0;i=4){ - event._result={index:1}; + if (player.countCards("h") >= 4) { + event._result = { index: 1 }; + } else { + trigger.player + .chooseControl() + .set("choiceList", [ + "令" + get.translation(player) + "将手牌摸至四张", + "令自己本回合的手牌上限-2", + ]) + .set("ai", function () { + var player = _status.event.player; + var source = _status.event.getParent().player; + if (get.attitude(player, source) > 0) return 0; + if (player.hp - player.countCards("h") > 1) return 1; + return [0, 1].randomGet(); + }); } - else{ - trigger.player.chooseControl().set('choiceList',[ - '令'+get.translation(player)+'将手牌摸至四张', - '令自己本回合的手牌上限-2' - ]).set('ai',function(){ - var player=_status.event.player; - var source=_status.event.getParent().player; - if(get.attitude(player,source)>0) return 0; - if(player.hp-player.countCards('h')>1) return 1; - return [0,1].randomGet(); - }) - } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { player.drawTo(4); - } - else{ - trigger.player.addTempSkill('xinfu_qianxin2_dis'); + } else { + trigger.player.addTempSkill("xinfu_qianxin2_dis"); } }, }, - "xinfu_fuhai":{ - subSkill:{ - next:{}, - previous:{}, + xinfu_fuhai: { + subSkill: { + next: {}, + previous: {}, }, - audio:2, - group:["fuhai_clear"], - intro:{ - content:"已指定过#个目标", + audio: 2, + group: ["fuhai_clear"], + intro: { + content: "已指定过#个目标", }, - enable:"phaseUse", - filter:function(event,player){ - if(player.hasSkill('xinfu_fuhai_next')&&player.hasSkill('xinfu_fuhai_previous')) return false; - return player.countCards('h')>0; + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("xinfu_fuhai_next") && player.hasSkill("xinfu_fuhai_previous")) + return false; + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - if(![player.next,player.previous].includes(target)||target.countCards('h')==0) return false; - if(player.hasSkill('xinfu_fuhai_next')) return target==player.previous; - if(player.hasSkill('xinfu_fuhai_previous')) return target==player.next; + filterTarget: function (card, player, target) { + if (![player.next, player.previous].includes(target) || target.countCards("h") == 0) + return false; + if (player.hasSkill("xinfu_fuhai_next")) return target == player.previous; + if (player.hasSkill("xinfu_fuhai_previous")) return target == player.next; return true; }, - line:false, - content:function(){ - 'step 0' - event.side=target==player.next?'next':'previous'; - event.current=target; - if(!player.storage.xinfu_fuhai) player.storage.xinfu_fuhai=1; - player.addTempSkill('xinfu_fuhai_'+event.side,'phaseUseAfter'); - 'step 1' - if(player.countCards('h')==0||event.current.countCards('h')==0||event.current==player){ - event.finish(); - return; + line: false, + content: function () { + "step 0"; + event.side = target == player.next ? "next" : "previous"; + event.current = target; + if (!player.storage.xinfu_fuhai) player.storage.xinfu_fuhai = 1; + player.addTempSkill("xinfu_fuhai_" + event.side, "phaseUseAfter"); + "step 1"; + if ( + player.countCards("h") == 0 || + event.current.countCards("h") == 0 || + event.current == player + ) { + event.finish(); + return; } - var next=event.current[event.side]; - if(get.attitude(event.current,player)>0){ - if(get.attitude(next,target)<=0||next.countCards('h')==0||player.countCards('h')==1){ - event.stopm=true; - event.stopt=true + var next = event.current[event.side]; + if (get.attitude(event.current, player) > 0) { + if ( + get.attitude(next, target) <= 0 || + next.countCards("h") == 0 || + player.countCards("h") == 1 + ) { + event.stopm = true; + event.stopt = true; + } else { + event.stopm = false; + event.stopt = false; } - else{ - event.stopm=false; - event.stopt=false; + } else { + if (get.attitude(next, target) >= 0) { + event.stopt = true; + event.stopm = false; + } else { + event.stopt = false; + event.stopm = false; } } - else{ - if(get.attitude(next,target)>=0){ - event.stopt=true; - event.stopm=false; - } - else{ - event.stopt=false; - event.stopm=false; - } - } - player.markSkill('xinfu_fuhai'); - player.line(event.current,'green'); - player.chooseCard('请选择要展示的牌',true).set('ai',function(card){ - if(_status.event.stop) return 14-get.number(card); - return get.number(card) - }).set('stop',event.stopm); - 'step 2' - event.mes=result.cards[0]; + player.markSkill("xinfu_fuhai"); + player.line(event.current, "green"); + player + .chooseCard("请选择要展示的牌", true) + .set("ai", function (card) { + if (_status.event.stop) return 14 - get.number(card); + return get.number(card); + }) + .set("stop", event.stopm); + "step 2"; + event.mes = result.cards[0]; player.showCards(event.mes); - 'step 3' - event.current.chooseCard('请选择要展示的牌',true).set('ai',function(card){ - if(_status.event.stop) return get.number(card); - return 14-get.number(card); - }).set('stop',event.stopt); - 'step 4' - event.tes=result.cards[0]; + "step 3"; + event.current + .chooseCard("请选择要展示的牌", true) + .set("ai", function (card) { + if (_status.event.stop) return get.number(card); + return 14 - get.number(card); + }) + .set("stop", event.stopt); + "step 4"; + event.tes = result.cards[0]; event.current.showCards(event.tes); - 'step 5' - var num1=get.number(event.mes); - var num2=get.number(event.tes); - if(num10&&event.current.countCards('h')>0&&event.current!=player) event.goto(1); + event.current = event.current[event.side]; + if ( + player.countCards("h") > 0 && + event.current.countCards("h") > 0 && + event.current != player + ) + event.goto(1); } }, - ai:{ - order:1, - result:{ - player:function(player,target){ - var hs=player.countCards('h'); - var side=target==player.next?'next':'previous'; - var current=player; - for(var i=0;i0) return 1; + ai: { + order: 1, + result: { + player: function (player, target) { + var hs = player.countCards("h"); + var side = target == player.next ? "next" : "previous"; + var current = player; + for (var i = 0; i < hs; i++) { + current = current[side]; + if (current == player || !current.countCards("h")) return 0; + if (get.attitude(current, player) > 0) return 1; } return 0; }, }, }, }, - "fuhai_clear":{ - trigger:{ - player:"phaseAfter", + fuhai_clear: { + trigger: { + player: "phaseAfter", }, - forced:true, - silent:true, - popup:false, - filter:function(event,player){ - return player.storage.xinfu_fuhai!=undefined; + forced: true, + silent: true, + popup: false, + filter: function (event, player) { + return player.storage.xinfu_fuhai != undefined; }, - content:function(){ - player.unmarkSkill('xinfu_fuhai'); + content: function () { + player.unmarkSkill("xinfu_fuhai"); delete player.storage.xinfu_fuhai; }, }, - "xz_xunxun":{ - filter:function(event,player){ - var num=game.countPlayer(function(current){ + xz_xunxun: { + filter: function (event, player) { + var num = game.countPlayer(function (current) { return current.isDamaged(); }); - return num>=1&&!player.hasSkill('xunxun'); + return num >= 1 && !player.hasSkill("xunxun"); }, - audio:2, - trigger:{ - player:"phaseDrawBegin1", + audio: 2, + trigger: { + player: "phaseDrawBegin1", }, //priority:10, - content:function(){ - 'step 0' - var cards=get.cards(4); + content: function () { + "step 0"; + var cards = get.cards(4); game.cardsGotoOrdering(cards); - var next=player.chooseToMove('恂恂:将两张牌置于牌堆顶',true); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('filterMove',function(from,to,moved){ - if(to==1&&moved[1].length>=2) return false; + var next = player.chooseToMove("恂恂:将两张牌置于牌堆顶", true); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("filterMove", function (from, to, moved) { + if (to == 1 && moved[1].length >= 2) return false; return true; }); - next.set('filterOk',function(moved){ - return moved[1].length==2; + next.set("filterOk", function (moved) { + return moved[1].length == 2; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.value(a); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.value(a); }); - return [cards,cards.splice(2)]; - }) - 'step 1' - var top=result.moved[0]; - var bottom=result.moved[1]; + return [cards, cards.splice(2)]; + }); + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i=1){ - str='
            • 视为拥有技能“恂恂”'; + }); + var str = "暂无任何效果"; + if (num >= 1) { + str = "
            • 视为拥有技能“恂恂”"; } - if(num>=2){ - str+=';使用装备牌时摸一张牌'; + if (num >= 2) { + str += ";使用装备牌时摸一张牌"; } - if(num>=3){ - str+=';始终跳过弃牌阶段'; + if (num >= 3) { + str += ";始终跳过弃牌阶段"; } - if(num==0||num>=4){ - str+=';造成的伤害+1'; + if (num == 0 || num >= 4) { + str += ";造成的伤害+1"; } return str; }, }, - trigger:{ - player:"useCard", + trigger: { + player: "useCard", }, - forced:true, - filter:function(event,player){ - if(get.type(event.card)!='equip') return false; - var num=game.countPlayer(function(current){ + forced: true, + filter: function (event, player) { + if (get.type(event.card) != "equip") return false; + var num = game.countPlayer(function (current) { return current.isDamaged(); }); - return num>=2; + return num >= 2; }, - content:function(){ + content: function () { player.draw(); }, }, - "xinfu_xingzhao2":{ - audio:true, - trigger:{ - player:['phaseJudgeBefore','phaseDiscardBefore'], + xinfu_xingzhao2: { + audio: true, + trigger: { + player: ["phaseJudgeBefore", "phaseDiscardBefore"], }, - forced:true, - filter:function(event,player){ - var num=game.countPlayer(function(current){ + forced: true, + filter: function (event, player) { + var num = game.countPlayer(function (current) { return current.isDamaged(); }); - return num>=3; + return num >= 3; }, - content:function(){ + content: function () { trigger.cancel(); - game.log(player,'跳过了'+(trigger.name=='phaseJudge'?'判定':'弃牌')+'阶段'); + game.log(player, "跳过了" + (trigger.name == "phaseJudge" ? "判定" : "弃牌") + "阶段"); }, }, - xinfu_xingzhao3:{ - audio:'xinfu_xingzhao', - trigger:{ - source:'damageBegin1', + xinfu_xingzhao3: { + audio: "xinfu_xingzhao", + trigger: { + source: "damageBegin1", }, - forced:true, - filter:function(event,player){ - var num=game.countPlayer(function(current){ + forced: true, + filter: function (event, player) { + var num = game.countPlayer(function (current) { return current.isDamaged(); }); - return num==0||num>=4; + return num == 0 || num >= 4; }, - content:function(){ + content: function () { trigger.num++; }, }, - "xinfu_dianhu":{ - audio:2, - trigger:{ - global:"phaseBefore", - player:"enterGame", + xinfu_dianhu: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - content:function(){ - 'step 0' - player.chooseTarget('选择【点虎】的目标',lib.translate.xinfu_dianhu_info,true,function(card,player,target){ - return target!=player&&!target.hasSkill('xinfu_dianhu2'); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att<0) return -att+3; - return Math.random(); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(target,'成为了','【点虎】','的目标'); - target.storage.xinfu_dianhu2=player; - target.addTempSkill('xinfu_dianhu2',{player:'die'}); + content: function () { + "step 0"; + player + .chooseTarget( + "选择【点虎】的目标", + lib.translate.xinfu_dianhu_info, + true, + function (card, player, target) { + return target != player && !target.hasSkill("xinfu_dianhu2"); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att < 0) return -att + 3; + return Math.random(); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(target, "成为了", "【点虎】", "的目标"); + target.storage.xinfu_dianhu2 = player; + target.addTempSkill("xinfu_dianhu2", { player: "die" }); } }, }, - xinfu_dianhu2:{ - mark:"character", - intro:{ - content:"当你受到来自$的伤害或回复体力后,$摸一张牌", + xinfu_dianhu2: { + mark: "character", + intro: { + content: "当你受到来自$的伤害或回复体力后,$摸一张牌", }, - nopop:true, - trigger:{ - player:["damageEnd","recoverEnd"], + nopop: true, + trigger: { + player: ["damageEnd", "recoverEnd"], }, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - if(player.storage.xinfu_dianhu2&&player.storage.xinfu_dianhu2.isIn()){ - if(event.name=='damage') return event.source==player.storage.xinfu_dianhu2; + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + if (player.storage.xinfu_dianhu2 && player.storage.xinfu_dianhu2.isIn()) { + if (event.name == "damage") return event.source == player.storage.xinfu_dianhu2; return true; } }, - content:function(){ - 'step 0' - var target=player.storage.xinfu_dianhu2; - target.logSkill('xinfu_dianhu'); + content: function () { + "step 0"; + var target = player.storage.xinfu_dianhu2; + target.logSkill("xinfu_dianhu"); target.draw(); }, - onremove:true, + onremove: true, }, - "xinfu_jianji":{ - audio:2, - enable:"phaseUse", - usable:1, - filterTarget:function(card,player,target){ - return target!=player; + xinfu_jianji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.draw(); - 'step 1' - var card=result[0]; - if(card&&game.hasPlayer(function(current){ - return target.canUse(card,current); - })&&get.owner(card)==target){ + "step 1"; + var card = result[0]; + if ( + card && + game.hasPlayer(function (current) { + return target.canUse(card, current); + }) && + get.owner(card) == target + ) { target.chooseToUse({ - prompt:'是否使用'+get.translation(card)+'?', - filterCard:function(cardx,player,target){ - return cardx==_status.event.cardx; + prompt: "是否使用" + get.translation(card) + "?", + filterCard: function (cardx, player, target) { + return cardx == _status.event.cardx; }, - cardx:card, + cardx: card, }); } }, - ai:{ - order:7.5, - result:{ - target:1, + ai: { + order: 7.5, + result: { + target: 1, }, }, }, - "xinfu_lianpian":{ - audio:2, - usable:3, - trigger:{ - player:"useCardToPlayered", + xinfu_lianpian: { + audio: 2, + usable: 3, + trigger: { + player: "useCardToPlayered", }, - frequent:true, - filter:function(event,player){ - if(!event.targets||!event.targets.length|| - event.getParent().triggeredTargets3.length>1||!event.isPhaseUsing(player)) return false; - var evt=player.getLastUsed(1); - if(!evt||!evt.targets||!evt.targets.length||!evt.isPhaseUsing(player)) return false; - for(var i=0;i 1 || + !event.isPhaseUsing(player) + ) + return false; + var evt = player.getLastUsed(1); + if (!evt || !evt.targets || !evt.targets.length || !evt.isPhaseUsing(player)) + return false; + for (var i = 0; i < event.targets.length; i++) { + if (evt.targets.includes(event.targets[i])) return true; } return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - event.card=result[0]; - var ablers=player.getLastUsed(1).targets.slice(0); - for(var i=0;i0; - })){ - return num+10; + locked: false, + mod: { + aiOrder: function (player, card, num) { + if ( + player.isPhaseUsing() && + (!player.storage.counttrigger || + !player.storage.counttrigger.xinfu_lianpian || + !player.storage.counttrigger.xinfu_lianpian < 3) + ) { + var evt = player.getLastUsed(); + if ( + evt && + evt.targets && + evt.targets.length && + evt.isPhaseUsing(player) && + game.hasPlayer(function (current) { + return ( + evt.targets.includes(current) && + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + return num + 10; } } }, }, - ai:{ - effect:{ - player:function(card,player,target){ - var evt=player.getLastUsed(); - if(evt&&evt.targets.includes(target)&&(!player.storage.counttrigger||!player.storage.counttrigger.xinfu_lianpian||!player.storage.counttrigger.xinfu_lianpian<3)&&player.isPhaseUsing(player)) return [1.5,0]; - } + ai: { + effect: { + player: function (card, player, target) { + var evt = player.getLastUsed(); + if ( + evt && + evt.targets.includes(target) && + (!player.storage.counttrigger || + !player.storage.counttrigger.xinfu_lianpian || + !player.storage.counttrigger.xinfu_lianpian < 3) && + player.isPhaseUsing(player) + ) + return [1.5, 0]; + }, }, }, }, //糜芳傅士仁 - fengshi:{ - audio:'mffengshi', - audioname:['sp_mifangfushiren'], - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget) return false; - return event.targets.some(target=>{ - return player.countCards('h')>target.countCards('h')&&target.countCards('he')>0&&player.hasCard(card=>{ - return lib.filter.cardDiscardable(card,player,'fengshi'); - },'he'); + fengshi: { + audio: "mffengshi", + audioname: ["sp_mifangfushiren"], + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget) return false; + return event.targets.some((target) => { + return ( + player.countCards("h") > target.countCards("h") && + target.countCards("he") > 0 && + player.hasCard((card) => { + return lib.filter.cardDiscardable(card, player, "fengshi"); + }, "he") + ); }); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('fengshi'),'弃置你与一名目标角色的各一张牌,然后令'+get.translation(event.card)+'对其造成的伤害+1',(card,player,target)=>{ - const targets=get.event().getTrigger().targets; - if(!targets.includes(target)) return false; - return player.countCards('h')>target.countCards('h')&&target.countCards('he')>0&&player.hasCard(card=>{ - return lib.filter.cardDiscardable(card,player,'fengshi'); - },'he'); - }).set('ai',target=>{ - const player=get.event('player'); - const card=get.event().getTrigger().card; - if(!get.info('dcmffengshi').check({card:card,target:target})) return 0; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - if(bool){ - const target=targets[0]; - player.logSkill('fengshi',target); - await player.chooseToDiscard('he',true); - await player.discardPlayerCard(target,'he',true); - if(get.tag(trigger.card,'damage')){ - var id=target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number') map[id].extraDamage=0; + direct: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("fengshi"), + "弃置你与一名目标角色的各一张牌,然后令" + + get.translation(event.card) + + "对其造成的伤害+1", + (card, player, target) => { + const targets = get.event().getTrigger().targets; + if (!targets.includes(target)) return false; + return ( + player.countCards("h") > target.countCards("h") && + target.countCards("he") > 0 && + player.hasCard((card) => { + return lib.filter.cardDiscardable(card, player, "fengshi"); + }, "he") + ); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + const card = get.event().getTrigger().card; + if (!get.info("dcmffengshi").check({ card: card, target: target })) return 0; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + if (bool) { + const target = targets[0]; + player.logSkill("fengshi", target); + await player.chooseToDiscard("he", true); + await player.discardPlayerCard(target, "he", true); + if (get.tag(trigger.card, "damage")) { + var id = target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") map[id].extraDamage = 0; map[id].extraDamage++; } } }, - group:'fengshi_target', - subSkill:{ - target:{ - inherit:'dcmffengshi', - trigger:{target:'useCardToTargeted'}, - filter(event,player){ - if(event.player==event.target) return false; - return event.player.countCards('h')>player.countCards('h')&&event.player.countCards('he')>0&&player.hasCard(card=>{ - return lib.filter.cardDiscardable(card,player,'fengshi'); - },'he'); + group: "fengshi_target", + subSkill: { + target: { + inherit: "dcmffengshi", + trigger: { target: "useCardToTargeted" }, + filter(event, player) { + if (event.player == event.target) return false; + return ( + event.player.countCards("h") > player.countCards("h") && + event.player.countCards("he") > 0 && + player.hasCard((card) => { + return lib.filter.cardDiscardable(card, player, "fengshi"); + }, "he") + ); }, - async content(event,trigger,player){ - const target=trigger.player; - await player.chooseToDiscard('he',true); - await player.discardPlayerCard(target,'he',true); - if(get.tag(trigger.card,'damage')){ - var id=player.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number') map[id].extraDamage=0; + async content(event, trigger, player) { + const target = trigger.player; + await player.chooseToDiscard("he", true); + await player.discardPlayerCard(target, "he", true); + if (get.tag(trigger.card, "damage")) { + var id = player.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") map[id].extraDamage = 0; map[id].extraDamage++; } }, }, }, }, - dcmffengshi:{ - audio:'mffengshi', - audioname:['sp_mifangfushiren'], - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + dcmffengshi: { + audio: "mffengshi", + audioname: ["sp_mifangfushiren"], + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter:function(event,player,name){ - if(event.player==event.target||event.targets.length!=1) return false; - return event.player.countCards('h')>event.target.countCards('h')&&event.target.countCards('he')>0&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'dcmffengshi'); - },'he'); + filter: function (event, player, name) { + if (event.player == event.target || event.targets.length != 1) return false; + return ( + event.player.countCards("h") > event.target.countCards("h") && + event.target.countCards("he") > 0 && + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "dcmffengshi"); + }, "he") + ); }, - logTarget:function(event,player){ - return player==event.player?event.target:event.player; + logTarget: function (event, player) { + return player == event.player ? event.target : event.player; }, - prompt2:function(event,player){ - var target=lib.skill.dcmffengshi.logTarget(event,player); - return '弃置你与'+get.translation(target)+'的各一张牌,然后令'+get.translation(event.card)+'的伤害+1'; + prompt2: function (event, player) { + var target = lib.skill.dcmffengshi.logTarget(event, player); + return ( + "弃置你与" + + get.translation(target) + + "的各一张牌,然后令" + + get.translation(event.card) + + "的伤害+1" + ); }, - check:function(event,player){ - var viewer=player,player=event.player,target=event.target; - if(viewer==player){ - if(get.attitude(viewer,target)>=0) return false; - if(player.countCards('he',(card)=>get.value(card,player)<5)) return true; - var card=get.event().getTrigger().card; - if((get.tag(card,'damage')||target.countCards('he',(card)=>get.value(card,target)>6))&&player.countCards('he',(card)=>get.value(card,player)<7)) return true; + check: function (event, player) { + var viewer = player, + player = event.player, + target = event.target; + if (viewer == player) { + if (get.attitude(viewer, target) >= 0) return false; + if (player.countCards("he", (card) => get.value(card, player) < 5)) return true; + var card = get.event().getTrigger().card; + if ( + (get.tag(card, "damage") || + target.countCards("he", (card) => get.value(card, target) > 6)) && + player.countCards("he", (card) => get.value(card, player) < 7) + ) + return true; return false; - } - else{ - if(get.attitude(viewer,player)>=0) return false; - if(!get.tag(card,'damage')) return false; - if(viewer.countCards('he')>player.countCards('he')) return true; - if(viewer.countCards('he',(card)=>get.value(card,target)>6)) return false; + } else { + if (get.attitude(viewer, player) >= 0) return false; + if (!get.tag(card, "damage")) return false; + if (viewer.countCards("he") > player.countCards("he")) return true; + if (viewer.countCards("he", (card) => get.value(card, target) > 6)) return false; return true; } }, - content:function(){ - if(get.tag(trigger.card,'damage')) trigger.getParent().baseDamage++; - var target=lib.skill.dcmffengshi.logTarget(trigger,player); - player.chooseToDiscard('he',true); - player.discardPlayerCard(target,'he',true); + content: function () { + if (get.tag(trigger.card, "damage")) trigger.getParent().baseDamage++; + var target = lib.skill.dcmffengshi.logTarget(trigger, player); + player.chooseToDiscard("he", true); + player.discardPlayerCard(target, "he", true); }, }, - mffengshi:{ - audio:2, - audioname:['sp_mifangfushiren'], - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + mffengshi: { + audio: 2, + audioname: ["sp_mifangfushiren"], + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - direct:true, - preHidden:true, - filter:function(event,player){ - if(event.player==event.target||event.targets.length!=1) return false; - if(player!=event.player&&!player.hasSkill('mffengshi')) return false; - return event.player.countCards('h')>event.target.countCards('h')&&event.target.countCards('he')>0; + direct: true, + preHidden: true, + filter: function (event, player) { + if (event.player == event.target || event.targets.length != 1) return false; + if (player != event.player && !player.hasSkill("mffengshi")) return false; + return ( + event.player.countCards("h") > event.target.countCards("h") && + event.target.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - event.source=trigger.player; - event.target=(player==trigger.target?trigger.player:trigger.target); + content: function () { + "step 0"; + event.source = trigger.player; + event.target = player == trigger.target ? trigger.player : trigger.target; var str; - if(player==trigger.player) str='弃置自己的和该角色'; - else str='令其弃置其与你的'; - var next=trigger.player.chooseBool('是否对'+get.translation(trigger.target)+'发动【锋势】?',str+'的各一张牌,然后令'+get.translation(trigger.card)+'的伤害+1').set('ai',function(){ - var player=_status.event.getParent().player; - var target=_status.event.getParent().target; - var viewer=_status.event.player; - if(viewer==player){ - if(get.attitude(viewer,target)>=0) return false; - if(player.countCards('he',(card)=>get.value(card,player)<5)) return true; - var card=_status.event.getTrigger().card; - if((get.tag(card,'damage')||target.countCards('he',(card)=>get.value(card,target)>6))&&player.countCards('he',(card)=>get.value(card,player)<7)) return true; - return false; + if (player == trigger.player) str = "弃置自己的和该角色"; + else str = "令其弃置其与你的"; + var next = trigger.player + .chooseBool( + "是否对" + get.translation(trigger.target) + "发动【锋势】?", + str + "的各一张牌,然后令" + get.translation(trigger.card) + "的伤害+1" + ) + .set("ai", function () { + var player = _status.event.getParent().player; + var target = _status.event.getParent().target; + var viewer = _status.event.player; + if (viewer == player) { + if (get.attitude(viewer, target) >= 0) return false; + if (player.countCards("he", (card) => get.value(card, player) < 5)) + return true; + var card = _status.event.getTrigger().card; + if ( + (get.tag(card, "damage") || + target.countCards("he", (card) => get.value(card, target) > 6)) && + player.countCards("he", (card) => get.value(card, player) < 7) + ) + return true; + return false; + } else { + if (get.attitude(viewer, player) >= 0) return false; + if (!get.tag(card, "damage")) return false; + if (viewer.countCards("he") > player.countCards("he")) return true; + if (viewer.countCards("he", (card) => get.value(card, target) > 6)) + return false; + return true; + } + }); + if (player == next.player) next.setHiddenSkill("mffengshi"); + "step 1"; + if (result.bool) { + if (player == source) player.logSkill("mffengshi", target); + else { + player.logSkill("mffengshi"); + source.line(player, "green"); } - else{ - if(get.attitude(viewer,player)>=0) return false; - if(!get.tag(card,'damage')) return false; - if(viewer.countCards('he')>player.countCards('he')) return true; - if(viewer.countCards('he',(card)=>get.value(card,target)>6)) return false; - return true; - } - }); - if(player==next.player) next.setHiddenSkill('mffengshi'); - 'step 1' - if(result.bool){ - if(player==source) player.logSkill('mffengshi',target); - else{ - player.logSkill('mffengshi'); - source.line(player,'green'); - } - if(get.tag(trigger.card,'damage')) trigger.getParent().baseDamage++; - player.chooseToDiscard('he',true); - } - else event.finish(); - 'step 2' - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true); + if (get.tag(trigger.card, "damage")) trigger.getParent().baseDamage++; + player.chooseToDiscard("he", true); + } else event.finish(); + "step 2"; + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true); }, }, }, - card:{ - }, - characterIntro:{ - tangji:'唐姬,会稽太守唐瑁女,弘农怀王刘辩的妃子。刘辩死后,唐姬回归故里,因节烈不愿改嫁他人,后被汉献帝下诏封为弘农王妃。', - lijue:"李傕(一说“傕”读音“què”)(?—198年),字稚然。北地郡泥阳县(今陕西省耀县)人,汉末群雄之一。东汉末年汉献帝时的军阀、权臣,官至大司马、车骑将军、开府、领司隶校尉、假节。
              李傕本为董卓部将,后被董卓的女婿牛辅派遣至中牟与朱儁交战,大破朱儁,进而至陈留、颍川等地劫掠。初平三年(192年)董卓和牛辅被杀后,李傕归无所依,于是采用贾诩之谋,伙同郭汜、张济、樊稠等原董卓部曲将攻向长安。击败吕布,杀死王允等人,占领长安,把持朝廷大权。后诸将不和,李傕在会议上杀死了樊稠,又与郭汜分别劫持了汉献帝和众臣,相互交战,张济率兵赶来和解,于是二人罢兵,李傕出屯池阳黄白城,郭汜、张济等人随汉献帝东归前往弘农。
              后来,李傕、郭汜、张济反悔,联合起来追击汉献帝,与杨奉、董承等人几番交战。汉献帝一路逃亡,狼狈不堪,到达安邑,与李傕等人讲和。不久,汉献帝被曹操迎往许都。建安三年(198年),曹操派谒者仆射裴茂召集关西诸将段煨等人征讨李傕,灭其三族。", - zhangji:"张济(?-196年),武威郡祖厉县(今甘肃靖远东南)人。东汉末年割据军阀之一。 张济原为董卓部将,董卓被诛杀后,张济与李傕一同率军攻破长安,任中郎将。不久,升任镇东将军,封平阳侯,出屯弘农。献帝东迁时,张济升任骠骑将军,率军护卫献帝,后来因与董承等人有矛盾,便与李傕、郭汜一同追赶献帝。 建安元年(196年),张济因军队缺粮而进攻穰城,中流矢而死。死后,部队由侄儿张绣接管。", - guosi:"郭汜(?-197年),又名郭多,凉州张掖(今甘肃张掖西北)人,东汉末年将领、军阀,献帝时权臣。原为董卓部下。董卓被杀后,凉州众将归无所依,于是采用贾诩之谋,联兵将攻向长安,击败吕布,杀死王允等人,占领长安,把持朝廷大权。几年后,郭汜被部将伍习杀死。", - fanchou:"樊稠(?—195年),凉州金城(治今甘肃永靖西北)人。东汉末年军阀、将领。官至右将军,封万年侯。 原为董卓部将,董卓死后,伙同李傕、郭汜、张济等人合众十余万反扑长安,败吕布、杀王允,把持朝政。后马腾因与李傕有隙,于是联合韩遂举兵进攻,李傕派樊稠、郭汜等与其交战,大败马腾、韩遂于长平观下。樊稠追至陈仓,与韩遂友好罢兵,却遭李傕猜疑。兴平二年(195年),李傕让外甥骑都尉胡封在会议上将樊稠刺死(一说趁醉用杖击杀)。", - lvkai:"吕凯(?―225年),字季平,永昌郡不韦县(今云南保山东北)人,三国时期蜀汉官员。初任永昌郡五官掾功曹。章武三年(223年),建宁太守雍闿反叛,投降吴国,吴国任雍闿为永昌太守,吕凯闭境抗拒雍闿。建兴三年(225年),丞相诸葛亮南征,表奏吕凯功劳,任命他为云南太守,封阳迁亭侯。吕凯还未上任,便被叛乱的少数民族杀害。", - zhanggong:"张恭(生卒年不详),三国时期魏国大臣,与子张就一同闻名于西域。官至西域戊己校尉、关内侯,赠执金吾。初为敦煌郡功曹。东汉末河西大乱,太守马艾卒官,他被众人推为代理长史,遂派儿子张就请曹操委任太守,直至新太守到任。魏文帝时拜西域戊己校尉。魏明帝时去世。", - weiwenzhugezhi:"卫温 (?—231年),三国时期东吴将领,曾任将军职。诸葛直(?—231年),三国时期东吴将领。黄龙二年(230年)正月,孙权派卫温、诸葛直带领上万士兵出海寻找夷洲、亶洲,想要俘获那里的民众以充实东吴的人口,陆逊和全琮都谏言反对,孙权不听。230年和卫温一起登上台湾(当时的台湾叫做夷洲),他们是中国历史上记载的最早登陆台湾的人。卫温和诸葛直花费了约一年时间行军,士兵们因为疾病死去了十分之八到十分之九,因为亶洲太过遥远,卫温和诸葛直最终没能到达那里,只带了几千名夷洲的人返回。黄龙三年(231年),孙权认为诸葛直违背诏令,劳财伤民,无功而返,和卫温一同入狱被处死。", - xurong:"徐荣(?-192年),玄菟人(一说为辽东襄平人,《公孙度传》中说公孙度本辽东襄平人,迁居玄菟,为同郡徐荣所举,任辽东太守。同郡当是同“玄菟”郡),东汉末年将领。本为中郎将,曾向董卓推举同郡出身的公孙度出任辽东太守。于汴水之战中击败曹操的独立追击军,以及在梁东之战中击败孙坚的部队。在董卓死后,受司徒王允的命令与李傕、郭汜交战,因部将胡珍投降,寡不敌众,于新丰之战被击败,战死在乱军之中。", - zhangqiying:"张琪瑛(196年-217年),字不详(或琪瑛为字,名不详),祖籍沛国丰县(今江苏省丰县)。她的曾祖父张陵是西汉留侯张良的十一世孙、天师道(五斗米道)教祖,她的父亲是东汉末年割据汉中的军阀张鲁。张琪瑛继承家说,是五斗米教的传人。", - beimihu:'卑弥呼(ひみこ,约159年-约249年,有的史书也写成“俾弥呼”)是日本弥生时代邪马台国(今日本本州近畿地区)的女王,在《三国志·魏书·倭人传》中有关于她的记载。关于她的真实身份一直众说纷纭,是个极具神秘色彩的古代女性统治者。亦是日本古代宗教鬼道教的发源者。', - liuqi:'刘琦(?-209年)。兖州山阳郡高平县(今山东省济宁市微山县两城镇)人。荆州牧刘表的长子、谏议大夫刘琮兄。官至荆州刺史。建安十四年(209年)病逝。', - tangzi:"唐咨(生卒年不详),三国时魏利城(今江苏赣榆西)人。魏文帝黄初中利城郡反,推唐咨为主。后为魏军击破,遂亡至吴,官至左将军,封侯、持节。后助诸葛诞拒魏,兵败被俘。为安抚吴国军民,魏主拜唐咨为安远将军。", - huangquan:"黄权(?-240年),字公衡。巴西郡阆中县(今四川阆中)人。三国时期蜀汉、曹魏将领。
              黄权年轻时为郡吏,后被益州牧刘璋召为主簿。曾劝谏刘璋不要迎接刘备,因而被外放为广汉县长。刘璋败,才降刘备,被拜为偏将军。建计取汉中,拜护军。刘备为汉中王,仍领益州牧,以黄权为治中从事。及刘备称帝,将伐吴,黄权劝谏而不纳。以其为镇北将军,督江北军以防魏师进攻。刘备伐吴败还,而归途隔绝,黄权不得归,无奈之下率部降魏。被魏文帝所赏识,拜镇南将军,封育阳侯,加侍中,使同车陪乘。后领益州刺史,进驻河南。景初三年(239年),迁车骑将军、仪同三司。正始元年(240年),黄权去世,谥号“景”。", - sufei:"苏飞(生卒年不详),东汉末年人物,原为东汉末年荆州牧刘表的部将,任江夏都督。
              苏飞与甘宁交好,但是数次向黄祖推荐都失败。甘宁决定投效孙权时助其逃离。后来甘宁率吴军攻破江夏,苏飞兵败被俘。孙权打算将苏飞处斩,但是因为甘宁用性命担保而赦免了苏飞。降吴后官至军都督。", + card: {}, + characterIntro: { + tangji: "唐姬,会稽太守唐瑁女,弘农怀王刘辩的妃子。刘辩死后,唐姬回归故里,因节烈不愿改嫁他人,后被汉献帝下诏封为弘农王妃。", + lijue: "李傕(一说“傕”读音“què”)(?—198年),字稚然。北地郡泥阳县(今陕西省耀县)人,汉末群雄之一。东汉末年汉献帝时的军阀、权臣,官至大司马、车骑将军、开府、领司隶校尉、假节。
              李傕本为董卓部将,后被董卓的女婿牛辅派遣至中牟与朱儁交战,大破朱儁,进而至陈留、颍川等地劫掠。初平三年(192年)董卓和牛辅被杀后,李傕归无所依,于是采用贾诩之谋,伙同郭汜、张济、樊稠等原董卓部曲将攻向长安。击败吕布,杀死王允等人,占领长安,把持朝廷大权。后诸将不和,李傕在会议上杀死了樊稠,又与郭汜分别劫持了汉献帝和众臣,相互交战,张济率兵赶来和解,于是二人罢兵,李傕出屯池阳黄白城,郭汜、张济等人随汉献帝东归前往弘农。
              后来,李傕、郭汜、张济反悔,联合起来追击汉献帝,与杨奉、董承等人几番交战。汉献帝一路逃亡,狼狈不堪,到达安邑,与李傕等人讲和。不久,汉献帝被曹操迎往许都。建安三年(198年),曹操派谒者仆射裴茂召集关西诸将段煨等人征讨李傕,灭其三族。", + zhangji: + "张济(?-196年),武威郡祖厉县(今甘肃靖远东南)人。东汉末年割据军阀之一。 张济原为董卓部将,董卓被诛杀后,张济与李傕一同率军攻破长安,任中郎将。不久,升任镇东将军,封平阳侯,出屯弘农。献帝东迁时,张济升任骠骑将军,率军护卫献帝,后来因与董承等人有矛盾,便与李傕、郭汜一同追赶献帝。 建安元年(196年),张济因军队缺粮而进攻穰城,中流矢而死。死后,部队由侄儿张绣接管。", + guosi: "郭汜(?-197年),又名郭多,凉州张掖(今甘肃张掖西北)人,东汉末年将领、军阀,献帝时权臣。原为董卓部下。董卓被杀后,凉州众将归无所依,于是采用贾诩之谋,联兵将攻向长安,击败吕布,杀死王允等人,占领长安,把持朝廷大权。几年后,郭汜被部将伍习杀死。", + fanchou: + "樊稠(?—195年),凉州金城(治今甘肃永靖西北)人。东汉末年军阀、将领。官至右将军,封万年侯。 原为董卓部将,董卓死后,伙同李傕、郭汜、张济等人合众十余万反扑长安,败吕布、杀王允,把持朝政。后马腾因与李傕有隙,于是联合韩遂举兵进攻,李傕派樊稠、郭汜等与其交战,大败马腾、韩遂于长平观下。樊稠追至陈仓,与韩遂友好罢兵,却遭李傕猜疑。兴平二年(195年),李傕让外甥骑都尉胡封在会议上将樊稠刺死(一说趁醉用杖击杀)。", + lvkai: "吕凯(?―225年),字季平,永昌郡不韦县(今云南保山东北)人,三国时期蜀汉官员。初任永昌郡五官掾功曹。章武三年(223年),建宁太守雍闿反叛,投降吴国,吴国任雍闿为永昌太守,吕凯闭境抗拒雍闿。建兴三年(225年),丞相诸葛亮南征,表奏吕凯功劳,任命他为云南太守,封阳迁亭侯。吕凯还未上任,便被叛乱的少数民族杀害。", + zhanggong: + "张恭(生卒年不详),三国时期魏国大臣,与子张就一同闻名于西域。官至西域戊己校尉、关内侯,赠执金吾。初为敦煌郡功曹。东汉末河西大乱,太守马艾卒官,他被众人推为代理长史,遂派儿子张就请曹操委任太守,直至新太守到任。魏文帝时拜西域戊己校尉。魏明帝时去世。", + weiwenzhugezhi: + "卫温 (?—231年),三国时期东吴将领,曾任将军职。诸葛直(?—231年),三国时期东吴将领。黄龙二年(230年)正月,孙权派卫温、诸葛直带领上万士兵出海寻找夷洲、亶洲,想要俘获那里的民众以充实东吴的人口,陆逊和全琮都谏言反对,孙权不听。230年和卫温一起登上台湾(当时的台湾叫做夷洲),他们是中国历史上记载的最早登陆台湾的人。卫温和诸葛直花费了约一年时间行军,士兵们因为疾病死去了十分之八到十分之九,因为亶洲太过遥远,卫温和诸葛直最终没能到达那里,只带了几千名夷洲的人返回。黄龙三年(231年),孙权认为诸葛直违背诏令,劳财伤民,无功而返,和卫温一同入狱被处死。", + xurong: "徐荣(?-192年),玄菟人(一说为辽东襄平人,《公孙度传》中说公孙度本辽东襄平人,迁居玄菟,为同郡徐荣所举,任辽东太守。同郡当是同“玄菟”郡),东汉末年将领。本为中郎将,曾向董卓推举同郡出身的公孙度出任辽东太守。于汴水之战中击败曹操的独立追击军,以及在梁东之战中击败孙坚的部队。在董卓死后,受司徒王允的命令与李傕、郭汜交战,因部将胡珍投降,寡不敌众,于新丰之战被击败,战死在乱军之中。", + zhangqiying: + "张琪瑛(196年-217年),字不详(或琪瑛为字,名不详),祖籍沛国丰县(今江苏省丰县)。她的曾祖父张陵是西汉留侯张良的十一世孙、天师道(五斗米道)教祖,她的父亲是东汉末年割据汉中的军阀张鲁。张琪瑛继承家说,是五斗米教的传人。", + beimihu: + "卑弥呼(ひみこ,约159年-约249年,有的史书也写成“俾弥呼”)是日本弥生时代邪马台国(今日本本州近畿地区)的女王,在《三国志·魏书·倭人传》中有关于她的记载。关于她的真实身份一直众说纷纭,是个极具神秘色彩的古代女性统治者。亦是日本古代宗教鬼道教的发源者。", + liuqi: "刘琦(?-209年)。兖州山阳郡高平县(今山东省济宁市微山县两城镇)人。荆州牧刘表的长子、谏议大夫刘琮兄。官至荆州刺史。建安十四年(209年)病逝。", + tangzi: "唐咨(生卒年不详),三国时魏利城(今江苏赣榆西)人。魏文帝黄初中利城郡反,推唐咨为主。后为魏军击破,遂亡至吴,官至左将军,封侯、持节。后助诸葛诞拒魏,兵败被俘。为安抚吴国军民,魏主拜唐咨为安远将军。", + huangquan: + "黄权(?-240年),字公衡。巴西郡阆中县(今四川阆中)人。三国时期蜀汉、曹魏将领。
              黄权年轻时为郡吏,后被益州牧刘璋召为主簿。曾劝谏刘璋不要迎接刘备,因而被外放为广汉县长。刘璋败,才降刘备,被拜为偏将军。建计取汉中,拜护军。刘备为汉中王,仍领益州牧,以黄权为治中从事。及刘备称帝,将伐吴,黄权劝谏而不纳。以其为镇北将军,督江北军以防魏师进攻。刘备伐吴败还,而归途隔绝,黄权不得归,无奈之下率部降魏。被魏文帝所赏识,拜镇南将军,封育阳侯,加侍中,使同车陪乘。后领益州刺史,进驻河南。景初三年(239年),迁车骑将军、仪同三司。正始元年(240年),黄权去世,谥号“景”。", + sufei: "苏飞(生卒年不详),东汉末年人物,原为东汉末年荆州牧刘表的部将,任江夏都督。
              苏飞与甘宁交好,但是数次向黄祖推荐都失败。甘宁决定投效孙权时助其逃离。后来甘宁率吴军攻破江夏,苏飞兵败被俘。孙权打算将苏飞处斩,但是因为甘宁用性命担保而赦免了苏飞。降吴后官至军都督。", - zhangchangpu:"钟会的母亲。《母夫人张氏传》:夫人张氏,字昌蒲,太原兹氏人,太傅定陵成侯之命妇也。", - xugong:"许贡是东汉末官吏。先后任吴郡都尉、太守,欲送密信给曹操,要曹操注意孙策,却被孙策发现而被杀。许贡生前招揽了一些门客,当中有三人不忘故主,千方百计想要手刃仇人。建安五年(公元200年),广陵太守陈登派人秘密联系孙策治下的山贼余党,企图颠覆孙策在江东的统治。孙策决定讨伐陈登,行军到丹徒时,许贡门客终于找到了机会。因为孙策有单骑出猎,在野外思考的习惯,三门客趁孙策轻装外出打猎时,放冷箭射中孙策面颊。这些门客后来在与孙策的搏斗中,被赶到的侍卫杀死。孙策此后因为伤口感染,并且俊美的容貌被毁,终于不治身亡,去世时年仅26岁。", - mangyachang:"南蛮王孟获的部将,使一口截头大刀,骑一匹黄骠马。率军与蜀军交战,战败王平。后被平北将军马岱斩杀。只出现在《三国演义》里,正史中无此人。", - xushao:'许劭(150年—195年),字子将。汝南平舆(今河南平舆县射桥镇)人。东汉末年著名人物评论家。据说他每月都要对当时人物进行一次品评,人称为“月旦评”。曾任汝南郡功曹,后南渡投靠扬州刺史刘繇。刘繇被孙策击败后,许劭随其逃往豫章郡,并在豫章去世。', - zhangwen:'张温(193年—230年),字惠恕,吴郡吴县(今江苏苏州)人。少修节操,容貌奇伟。孙权召拜议郎、选曹尚书,徙太子太傅。黄武三年(224),以辅义中郎将身份出使蜀汉,孙权原先害怕诸葛亮会有意留难张温,但张温不担心。在呈上蜀汉朝廷的文书刻意称颂蜀汉,以表明和解的诚意,重建两国关系。他在蜀汉表现出色,得蜀汉朝廷重视。回东吴后不久,被调进豫章的军队,事业上再无进展。孙权一方面介怀他出使蜀汉时称颂蜀汉,又嫌他声名太盛,恐怕张温不会尽忠地由他任用。当时正好碰上暨艳事件,暨艳是张温引荐的臣子,但他滥用职权,升迁评定等只看自己喜恶。事件被揭发后暨艳及同党徐彪都自杀。孙权见此,于是以张温与暨艳、徐彪等人多有来往而下罪张温,后更将张温发还到家乡吴郡。将军骆统曾上书为张温辩解,但孙权不理会。六年后,张温病逝。', - lisu:'李肃(?-192年),五原(治今内蒙古包头西北)人。永汉三年四月,司徒王允、尚书仆射士孙瑞、卓将吕布共谋诛卓。是时,天子有疾新愈,大会未央殿。布使同郡骑都尉肃等、将亲兵十馀人,伪著卫士服守掖门。布怀诏书。卓至,肃等格卓。卓惊呼布所在。布曰“有诏”,遂杀卓,夷三族。后卓女婿中郎将牛辅典兵别屯陕,分遣校尉李傕、郭汜、张济略陈留、颍川诸县。卓死,吕布使李肃至陕,欲以诏命诛辅。辅等逆与肃战,肃败走弘农,布诛肃。', - xinpi:'辛毗(生卒年不详),字佐治,颍川阳翟人。三国时期曹魏大臣。原居陇西(郡治在今甘肃临洮县),东汉光武帝建武年间,其先人东迁。当初,辛毗跟随其兄事袁绍。曹操任司空时,征召辛毗,他不受命。官渡战后,辛毗事袁绍的儿子袁谭。公元204年,曹操攻下邺城,上表推荐辛毗任议郎,后为丞相长史。公元220年,曹丕即皇帝位,以辛毗为侍中,赐爵关内侯,后赐广平亭侯。魏明帝即位,封辛毗颍乡侯,食邑三百户,后为卫尉。公元234年,诸葛亮屯兵渭南,司马懿上表魏明帝。魏明帝任辛毗为大将军军师,加使持节号。诸葛亮病逝后,辛毗返回,仍任卫尉。不久,逝世,谥肃侯。', + zhangchangpu: + "钟会的母亲。《母夫人张氏传》:夫人张氏,字昌蒲,太原兹氏人,太傅定陵成侯之命妇也。", + xugong: "许贡是东汉末官吏。先后任吴郡都尉、太守,欲送密信给曹操,要曹操注意孙策,却被孙策发现而被杀。许贡生前招揽了一些门客,当中有三人不忘故主,千方百计想要手刃仇人。建安五年(公元200年),广陵太守陈登派人秘密联系孙策治下的山贼余党,企图颠覆孙策在江东的统治。孙策决定讨伐陈登,行军到丹徒时,许贡门客终于找到了机会。因为孙策有单骑出猎,在野外思考的习惯,三门客趁孙策轻装外出打猎时,放冷箭射中孙策面颊。这些门客后来在与孙策的搏斗中,被赶到的侍卫杀死。孙策此后因为伤口感染,并且俊美的容貌被毁,终于不治身亡,去世时年仅26岁。", + mangyachang: + "南蛮王孟获的部将,使一口截头大刀,骑一匹黄骠马。率军与蜀军交战,战败王平。后被平北将军马岱斩杀。只出现在《三国演义》里,正史中无此人。", + xushao: "许劭(150年—195年),字子将。汝南平舆(今河南平舆县射桥镇)人。东汉末年著名人物评论家。据说他每月都要对当时人物进行一次品评,人称为“月旦评”。曾任汝南郡功曹,后南渡投靠扬州刺史刘繇。刘繇被孙策击败后,许劭随其逃往豫章郡,并在豫章去世。", + zhangwen: + "张温(193年—230年),字惠恕,吴郡吴县(今江苏苏州)人。少修节操,容貌奇伟。孙权召拜议郎、选曹尚书,徙太子太傅。黄武三年(224),以辅义中郎将身份出使蜀汉,孙权原先害怕诸葛亮会有意留难张温,但张温不担心。在呈上蜀汉朝廷的文书刻意称颂蜀汉,以表明和解的诚意,重建两国关系。他在蜀汉表现出色,得蜀汉朝廷重视。回东吴后不久,被调进豫章的军队,事业上再无进展。孙权一方面介怀他出使蜀汉时称颂蜀汉,又嫌他声名太盛,恐怕张温不会尽忠地由他任用。当时正好碰上暨艳事件,暨艳是张温引荐的臣子,但他滥用职权,升迁评定等只看自己喜恶。事件被揭发后暨艳及同党徐彪都自杀。孙权见此,于是以张温与暨艳、徐彪等人多有来往而下罪张温,后更将张温发还到家乡吴郡。将军骆统曾上书为张温辩解,但孙权不理会。六年后,张温病逝。", + lisu: "李肃(?-192年),五原(治今内蒙古包头西北)人。永汉三年四月,司徒王允、尚书仆射士孙瑞、卓将吕布共谋诛卓。是时,天子有疾新愈,大会未央殿。布使同郡骑都尉肃等、将亲兵十馀人,伪著卫士服守掖门。布怀诏书。卓至,肃等格卓。卓惊呼布所在。布曰“有诏”,遂杀卓,夷三族。后卓女婿中郎将牛辅典兵别屯陕,分遣校尉李傕、郭汜、张济略陈留、颍川诸县。卓死,吕布使李肃至陕,欲以诏命诛辅。辅等逆与肃战,肃败走弘农,布诛肃。", + xinpi: "辛毗(生卒年不详),字佐治,颍川阳翟人。三国时期曹魏大臣。原居陇西(郡治在今甘肃临洮县),东汉光武帝建武年间,其先人东迁。当初,辛毗跟随其兄事袁绍。曹操任司空时,征召辛毗,他不受命。官渡战后,辛毗事袁绍的儿子袁谭。公元204年,曹操攻下邺城,上表推荐辛毗任议郎,后为丞相长史。公元220年,曹丕即皇帝位,以辛毗为侍中,赐爵关内侯,后赐广平亭侯。魏明帝即位,封辛毗颍乡侯,食邑三百户,后为卫尉。公元234年,诸葛亮屯兵渭南,司马懿上表魏明帝。魏明帝任辛毗为大将军军师,加使持节号。诸葛亮病逝后,辛毗返回,仍任卫尉。不久,逝世,谥肃侯。", - liuzan:'字正明,会稽长山人人,曾任左护军,有两子:留略、留平。少为会稽郡吏,曾参与镇压黄巾起义,后被东吴大将凌统所引用,任屯骑校尉。吴五凤二年(公元255年)留赞任左护军,随孙峻征淮南,因病撤军,被魏将蒋班围困于道,力战而死,时年73岁。', - zhujun:'朱儁(?-195年),字公伟。会稽郡上虞县(今浙江绍兴上虞区)人。东汉末年名将。朱儁出身寒门,赡养母亲,以好义轻财闻名,受乡里敬重。后被太守徐珪举为孝廉,任兰陵令,颇有治绩。再升任交州刺史,以家兵五千大破叛军,平定交州。战后以功封都亭侯,入朝为谏议大夫。光和七年(184年),黄巾起义爆发,朱儁以右中郎将、持节平定三郡之地,以功进封西乡侯,迁镇贼中郎将。又率军讨平黄巾,“威声满天下”。中平二年(185年),进拜右车骑将军,更封钱塘侯。后为河内太守,击退进逼的张燕。权臣董卓秉政时,想任朱儁为副手,遭其婉拒。其后出逃荆州,更屯军中牟,徐州刺史陶谦等欲推举他为太师,并传檄各州牧伯,相邀讨伐李傕、奉迎天子。但朱儁却奉诏入京任太仆。初平三年(192年),升任太尉、录尚书事。兴平元年(194年),行骠骑将军事,持节镇关东,因故未成行。兴平二年(195年),李傕与郭汜相互攻杀,郭汜扣留朱儁作为人质。朱儁性格刚烈,即日发病而死。', - liuhong:'汉灵帝刘宏(157年,一作156年-189年5月13日),生于冀州河间国(今河北深州)。东汉第十二位皇帝(168年-189年在位),汉章帝刘炟的玄孙。刘宏早年世袭解渎亭侯。永康元年(167年)十二月,汉桓帝刘志逝世,刘宏被外戚窦氏挑选为皇位继承人,于建宁元年(168年)正月即位。刘宏在位的大部分时期,施行党锢及宦官政治。他又设置西园,巧立名目搜刮钱财,甚至卖官鬻爵以用于自己享乐。在位晚期,爆发了黄巾起义,而凉州等地也陷入持续动乱之中。中平六年(189年),刘宏去世,谥号孝灵皇帝,葬于文陵。刘宏喜好辞赋,作有《皇羲篇》、《追德赋》、《令仪颂》、《招商歌》等。', - wangrong:'汉灵怀皇后王荣(?~181年),赵国邯郸(今河北邯郸市)人。五官中郎将王苞孙女,汉灵帝刘宏妃子,汉献帝刘协生母。初以良家子选入掖庭,封为美人,服侍汉灵帝。光和四年(181年),生下陈留王刘协,惨遭灵思皇后毒杀。王荣死后,汉灵帝曾作《追德赋》、《令仪颂》。永汉元年(189年),其子刘协即位,是为汉献帝,追谥灵怀皇后,葬于文昭陵。', - hanfu:'韩馥(?—191年),字文节,颍川郡(今河南禹州)人。东汉末年的诸侯,冀州牧。韩馥担任过东汉的御史中丞,之后被董卓举荐为冀州牧;在各诸侯起兵讨伐董卓时,韩馥也是其中之一的参与者。韩馥与袁绍也曾经有意立刘虞为皇帝。当时冀州民殷人盛,兵粮优足,于是袁绍便用计夺取冀州,韩馥被迫投靠张邈;之后张邈与袁绍的使者见面,韩馥以为是要来杀害自己的,于是在厕所中以刻书用的小刀自杀。', - zhaozhong:'赵忠(?—189年),安平人,东汉末年宦官,赵延之兄。桓帝、灵帝时,历为小黄门、中常侍、大长秋、车骑将军等职,封都乡侯。在职时以搜刮暴敛、骄纵贪婪见称,灵帝极为宠信,常谓“赵常侍是我母”。中平六年(189年),何进谋诛宦官,事泄,他和其余几个常侍设计伏杀何进,袁绍、袁术等人闻何进被杀,入宫杀尽宦官,后捕杀赵忠。', - caosong:'曹嵩(?—194年),字巨高,沛郡谯县(今安徽省亳州市)人。东汉大臣,大长秋曹腾的养子,曹操之父亲。门荫入仕,历任司隶校尉、鸿胪卿、大司农,位列九卿,位高权重。中平四年(187年),靠着贿赂中官,出任太尉,位列三公。中平五年(188年),受累于黄巾之乱,坐罪免官。兴平元年(194年),投奔兖州牧曹操,遇害于徐州。延康元年(220年),追尊魏国太王。曹魏建立后,追尊皇帝,谥号为太。', - liangxing:'梁兴(?-212年),武威郡姑臧人也,东汉末年凉州军阀之一。与张横、贾诩、段煨是同乡,曾斩杀李傕。建安十六年,同韩遂、马超联合,起兵反抗曹操。梁兴率步骑五千夜袭曹军先头部队徐晃,被击退。联军战败后,梁兴逃到蓝田,劫掠周围郡县。夏侯渊进攻蓝田联合郑浑征讨梁兴,梁兴战败,不知所终。', - zhangmiao:'张邈(?-195年),字孟卓,东平寿张(今山东东平县)人。东汉大臣、名士,“八厨”之一。举孝廉出身,授骑都尉,出任陈留太守。参与讨伐董卓,参加汴水之战,归附于曹操。兴平元年(194年),趁着曹操讨伐徐州牧陶谦,联合陈宫发动叛乱,迎立吕布为兖州牧。受到曹操讨伐,兵败投奔徐州牧刘备。兴平二年,张邈向袁术借兵途中,被部下所杀。', - duanwei:'段煨(?~209年),字忠明,武威郡姑臧(今甘肃省武威市)人也。东汉末年将领,东汉太尉段颎同族兄弟,与太尉贾诩、张济、宣威侯张绣乃是同乡。原为董卓帐下将领,奉命屯兵华阴,勤劳农业。兴平二年(195年),迎接汉献帝刘协东归洛阳,供给衣食补给,与护驾将领杨定不和,引发激战十余天,听从汉献帝刘协劝解。东汉建安三年(198年),攻打黄白城,击杀李傕,夷其三族,封为镇远将军、闅乡亭侯、北地太守,累迁大鸿胪、金光禄大夫。建安十四年(209年),寿终正寝。', - zhangheng:'张横,生卒年不详,武威郡姑臧人,东汉末年凉州军阀之一。与梁兴、贾诩、段煨乃是同乡。建安三年(198),张横与梁兴、段煨等斩杀李傕。十六年(211),同韩遂、马超联合,起兵反抗曹操,兵败后不知所终。', - wenqin:'文钦(?~258年),字仲若,沛国谯郡(今安徽省亳州市)人,三国时期曹魏将领,曹操部将文稷之子。魏明帝太和年间文钦任牙门将、五营校督,后拜庐江太守、冠军将军,嘉平元年(249年),曹爽及其同党在高平陵之变中被杀,文钦心中不安,执政的司马氏集团为了安抚文钦,升其为前将军、扬州刺史,任职期间结交镇东将军毌丘俭。击退吴国太傅诸葛恪进攻,取得一定战果。正元二年(255年),文钦与镇东将军毌丘俭在扬州起兵讨伐司马师,兵败后投奔吴国,被封为镇北大将军、幽州牧,封谯侯。甘露二年(257年),文钦随吴军援救起兵反抗司马氏的诸葛诞,此后因被司马昭大军围困,军情告急,文钦与诸葛诞本就有矛盾,对文钦日益不满的诸葛诞遂将文钦杀死。淮南平定之后,文钦遗体被其二子收敛安葬。', - qiuliju:'丘力居,东汉末年的辽西乌丸大人。拉拢中山太守张纯反叛东汉,寇略青、徐、幽、冀四州,杀略吏民。死时认为儿子楼班年幼,于是让从子蹋顿总摄三王部。', - liuba:'刘巴(?-222年),字子初,荆州零陵郡烝阳县(今湖南省衡阳县、邵东县一带)人,东汉末年至三国时期蜀汉时期官员、名士。刘巴少知名,荆州牧刘表多次征用推举,刘巴均不应就。曹操征伐荆州,荆州士人多归刘备,刘巴却北上投靠曹操。后受曹操命令招降荆南三郡,不料先为刘备所得,刘巴不能复命曹操,遂远至交趾,又辗转进入益州。刘备平定益州后,刘巴归附刘备,为左将军西曹掾,法正死后接任尚书令。章武二年(222年)去世。刘巴博学多才,为刘备解决入蜀后的财政困难问题,又与诸葛亮等共制蜀汉的法律文件《蜀科》。为人简朴清高,退无私交,曹魏大臣陈群甚敬重之。所著录于《刘令君集》。', - pengyang:'彭羕(184年-220年),字永年,广汉(今四川广汉北)人。东汉末年官吏。彭羕起初在益州任书佐,但后来其他人向益州牧刘璋诽谤他,刘璋于是以“髡钳”(剃去头发和胡须,并戴上刑具)处罚他,并且贬奴隶。此时刘备入蜀,彭羕想投靠刘备,于是去见庞统。庞统和他会面后很欣赏他,而法正亦很清楚彭羕,于是二人共同向刘备推荐彭羕。刘备多次命令彭羕传递军情和指示给诸将,表现都十分满意,日渐被赏识。刘备入主益州,领益州牧后就任命他为治州从事。彭羕见此,又变得嚣张自矜,诸葛亮对他礼待但心中并不喜欢他,多次密告刘备,说彭羕“心大志广,难可保安”。刘备见诸葛亮这样说,决定疏远彭羕,又观察他行事,于是贬他为江阳太守。彭羕见将被派往外地,心感不悦,与马超见面时又曾对他说“老革荒悖,可复道邪!”“卿为其外,我为其内,天下不足定也。”马超听后大惊,彭羕走后以他的说话告发彭羕,彭羕于是被收监下狱。最后彭羕被处死,死时三十七岁。', - dongxie:'董卓之女,牛辅之妻。在《三国群英传》中名为董宜,在电视剧《三国群英会之吕布与貂蝉》中名为董媛。', - caoanmin:'曹安民(?-197年),沛国谯县(今安徽亳州)人,字安民。东汉时期人物,曹德之子,曹操之侄,曹昂的堂兄弟,曹丕的堂兄,死于宛城之战。按曹丕《典论》记载的“亡兄孝廉子脩、从兄安民遇害。”等情况来看,安民应该是曹操侄子错不了,曹丕是他们属于兄弟关系肯定不会弄错。另外从典论的记载来看安民是和子脩并提的,子脩是曹昂的字,安民则肯定也是字不是名,至于三国志中记载则应取自曹丕之《典论》但陈寿又不知曹安民其名,故写为“长子昂、弟子安民”。', - dufuren:'杜夫人(生卒年不详),东汉末年至三国时人。有异色,原为吕布将秦宜禄之妻,生子秦朗。后为曹操纳为妾,又生曹林、曹衮、金乡公主。', - mifangfushiren:'麋芳(生卒年不详),字子方,东海郡朐县(今江苏省连云港市)人。汉末三国时期蜀国将领,刘备糜夫人的兄弟。麋芳本为徐州牧陶谦部下,曾被曹操表为彭城相。后来辞官,随刘备从徐州辗转至邺城、汝南、新野、长坂坡、江夏等地,奔波多年。傅士仁(生卒年不详),字君义,幽州广阳郡(今北京市)人,刘备手下将领。受到刘备的重用,但被关羽轻慢。
              刘备称汉中王时,糜芳为南郡太守,但受到关羽的轻慢。后来,因未完成供给军资的任务而被关羽责骂,心中不安。吕蒙袭取荆州时,将已经投降的傅士仁展示给糜芳,麋芳于是选择投降,导致关羽兵败被杀。此后,在吴国担任将军,并且为吴征伐。', - tongyuan:'童渊,字雄付,武术名家,与并州李彦是结拜兄弟,两人均师承义父玉真子,两人分别娶了河北颜家的两位大小姐颜云、颜雨。童飞之父,有张任、张绣为入室弟子,晚年收赵云为关门弟子,传其毕生所学。其成名技为“百鸟朝凤枪”。童渊是南方苏州评话三国中的原创人物,在历史中以及《三国演义》中并不存在。', + liuzan: "字正明,会稽长山人人,曾任左护军,有两子:留略、留平。少为会稽郡吏,曾参与镇压黄巾起义,后被东吴大将凌统所引用,任屯骑校尉。吴五凤二年(公元255年)留赞任左护军,随孙峻征淮南,因病撤军,被魏将蒋班围困于道,力战而死,时年73岁。", + zhujun: "朱儁(?-195年),字公伟。会稽郡上虞县(今浙江绍兴上虞区)人。东汉末年名将。朱儁出身寒门,赡养母亲,以好义轻财闻名,受乡里敬重。后被太守徐珪举为孝廉,任兰陵令,颇有治绩。再升任交州刺史,以家兵五千大破叛军,平定交州。战后以功封都亭侯,入朝为谏议大夫。光和七年(184年),黄巾起义爆发,朱儁以右中郎将、持节平定三郡之地,以功进封西乡侯,迁镇贼中郎将。又率军讨平黄巾,“威声满天下”。中平二年(185年),进拜右车骑将军,更封钱塘侯。后为河内太守,击退进逼的张燕。权臣董卓秉政时,想任朱儁为副手,遭其婉拒。其后出逃荆州,更屯军中牟,徐州刺史陶谦等欲推举他为太师,并传檄各州牧伯,相邀讨伐李傕、奉迎天子。但朱儁却奉诏入京任太仆。初平三年(192年),升任太尉、录尚书事。兴平元年(194年),行骠骑将军事,持节镇关东,因故未成行。兴平二年(195年),李傕与郭汜相互攻杀,郭汜扣留朱儁作为人质。朱儁性格刚烈,即日发病而死。", + liuhong: + "汉灵帝刘宏(157年,一作156年-189年5月13日),生于冀州河间国(今河北深州)。东汉第十二位皇帝(168年-189年在位),汉章帝刘炟的玄孙。刘宏早年世袭解渎亭侯。永康元年(167年)十二月,汉桓帝刘志逝世,刘宏被外戚窦氏挑选为皇位继承人,于建宁元年(168年)正月即位。刘宏在位的大部分时期,施行党锢及宦官政治。他又设置西园,巧立名目搜刮钱财,甚至卖官鬻爵以用于自己享乐。在位晚期,爆发了黄巾起义,而凉州等地也陷入持续动乱之中。中平六年(189年),刘宏去世,谥号孝灵皇帝,葬于文陵。刘宏喜好辞赋,作有《皇羲篇》、《追德赋》、《令仪颂》、《招商歌》等。", + wangrong: + "汉灵怀皇后王荣(?~181年),赵国邯郸(今河北邯郸市)人。五官中郎将王苞孙女,汉灵帝刘宏妃子,汉献帝刘协生母。初以良家子选入掖庭,封为美人,服侍汉灵帝。光和四年(181年),生下陈留王刘协,惨遭灵思皇后毒杀。王荣死后,汉灵帝曾作《追德赋》、《令仪颂》。永汉元年(189年),其子刘协即位,是为汉献帝,追谥灵怀皇后,葬于文昭陵。", + hanfu: "韩馥(?—191年),字文节,颍川郡(今河南禹州)人。东汉末年的诸侯,冀州牧。韩馥担任过东汉的御史中丞,之后被董卓举荐为冀州牧;在各诸侯起兵讨伐董卓时,韩馥也是其中之一的参与者。韩馥与袁绍也曾经有意立刘虞为皇帝。当时冀州民殷人盛,兵粮优足,于是袁绍便用计夺取冀州,韩馥被迫投靠张邈;之后张邈与袁绍的使者见面,韩馥以为是要来杀害自己的,于是在厕所中以刻书用的小刀自杀。", + zhaozhong: + "赵忠(?—189年),安平人,东汉末年宦官,赵延之兄。桓帝、灵帝时,历为小黄门、中常侍、大长秋、车骑将军等职,封都乡侯。在职时以搜刮暴敛、骄纵贪婪见称,灵帝极为宠信,常谓“赵常侍是我母”。中平六年(189年),何进谋诛宦官,事泄,他和其余几个常侍设计伏杀何进,袁绍、袁术等人闻何进被杀,入宫杀尽宦官,后捕杀赵忠。", + caosong: + "曹嵩(?—194年),字巨高,沛郡谯县(今安徽省亳州市)人。东汉大臣,大长秋曹腾的养子,曹操之父亲。门荫入仕,历任司隶校尉、鸿胪卿、大司农,位列九卿,位高权重。中平四年(187年),靠着贿赂中官,出任太尉,位列三公。中平五年(188年),受累于黄巾之乱,坐罪免官。兴平元年(194年),投奔兖州牧曹操,遇害于徐州。延康元年(220年),追尊魏国太王。曹魏建立后,追尊皇帝,谥号为太。", + liangxing: + "梁兴(?-212年),武威郡姑臧人也,东汉末年凉州军阀之一。与张横、贾诩、段煨是同乡,曾斩杀李傕。建安十六年,同韩遂、马超联合,起兵反抗曹操。梁兴率步骑五千夜袭曹军先头部队徐晃,被击退。联军战败后,梁兴逃到蓝田,劫掠周围郡县。夏侯渊进攻蓝田联合郑浑征讨梁兴,梁兴战败,不知所终。", + zhangmiao: + "张邈(?-195年),字孟卓,东平寿张(今山东东平县)人。东汉大臣、名士,“八厨”之一。举孝廉出身,授骑都尉,出任陈留太守。参与讨伐董卓,参加汴水之战,归附于曹操。兴平元年(194年),趁着曹操讨伐徐州牧陶谦,联合陈宫发动叛乱,迎立吕布为兖州牧。受到曹操讨伐,兵败投奔徐州牧刘备。兴平二年,张邈向袁术借兵途中,被部下所杀。", + duanwei: + "段煨(?~209年),字忠明,武威郡姑臧(今甘肃省武威市)人也。东汉末年将领,东汉太尉段颎同族兄弟,与太尉贾诩、张济、宣威侯张绣乃是同乡。原为董卓帐下将领,奉命屯兵华阴,勤劳农业。兴平二年(195年),迎接汉献帝刘协东归洛阳,供给衣食补给,与护驾将领杨定不和,引发激战十余天,听从汉献帝刘协劝解。东汉建安三年(198年),攻打黄白城,击杀李傕,夷其三族,封为镇远将军、闅乡亭侯、北地太守,累迁大鸿胪、金光禄大夫。建安十四年(209年),寿终正寝。", + zhangheng: + "张横,生卒年不详,武威郡姑臧人,东汉末年凉州军阀之一。与梁兴、贾诩、段煨乃是同乡。建安三年(198),张横与梁兴、段煨等斩杀李傕。十六年(211),同韩遂、马超联合,起兵反抗曹操,兵败后不知所终。", + wenqin: "文钦(?~258年),字仲若,沛国谯郡(今安徽省亳州市)人,三国时期曹魏将领,曹操部将文稷之子。魏明帝太和年间文钦任牙门将、五营校督,后拜庐江太守、冠军将军,嘉平元年(249年),曹爽及其同党在高平陵之变中被杀,文钦心中不安,执政的司马氏集团为了安抚文钦,升其为前将军、扬州刺史,任职期间结交镇东将军毌丘俭。击退吴国太傅诸葛恪进攻,取得一定战果。正元二年(255年),文钦与镇东将军毌丘俭在扬州起兵讨伐司马师,兵败后投奔吴国,被封为镇北大将军、幽州牧,封谯侯。甘露二年(257年),文钦随吴军援救起兵反抗司马氏的诸葛诞,此后因被司马昭大军围困,军情告急,文钦与诸葛诞本就有矛盾,对文钦日益不满的诸葛诞遂将文钦杀死。淮南平定之后,文钦遗体被其二子收敛安葬。", + qiuliju: + "丘力居,东汉末年的辽西乌丸大人。拉拢中山太守张纯反叛东汉,寇略青、徐、幽、冀四州,杀略吏民。死时认为儿子楼班年幼,于是让从子蹋顿总摄三王部。", + liuba: "刘巴(?-222年),字子初,荆州零陵郡烝阳县(今湖南省衡阳县、邵东县一带)人,东汉末年至三国时期蜀汉时期官员、名士。刘巴少知名,荆州牧刘表多次征用推举,刘巴均不应就。曹操征伐荆州,荆州士人多归刘备,刘巴却北上投靠曹操。后受曹操命令招降荆南三郡,不料先为刘备所得,刘巴不能复命曹操,遂远至交趾,又辗转进入益州。刘备平定益州后,刘巴归附刘备,为左将军西曹掾,法正死后接任尚书令。章武二年(222年)去世。刘巴博学多才,为刘备解决入蜀后的财政困难问题,又与诸葛亮等共制蜀汉的法律文件《蜀科》。为人简朴清高,退无私交,曹魏大臣陈群甚敬重之。所著录于《刘令君集》。", + pengyang: + "彭羕(184年-220年),字永年,广汉(今四川广汉北)人。东汉末年官吏。彭羕起初在益州任书佐,但后来其他人向益州牧刘璋诽谤他,刘璋于是以“髡钳”(剃去头发和胡须,并戴上刑具)处罚他,并且贬奴隶。此时刘备入蜀,彭羕想投靠刘备,于是去见庞统。庞统和他会面后很欣赏他,而法正亦很清楚彭羕,于是二人共同向刘备推荐彭羕。刘备多次命令彭羕传递军情和指示给诸将,表现都十分满意,日渐被赏识。刘备入主益州,领益州牧后就任命他为治州从事。彭羕见此,又变得嚣张自矜,诸葛亮对他礼待但心中并不喜欢他,多次密告刘备,说彭羕“心大志广,难可保安”。刘备见诸葛亮这样说,决定疏远彭羕,又观察他行事,于是贬他为江阳太守。彭羕见将被派往外地,心感不悦,与马超见面时又曾对他说“老革荒悖,可复道邪!”“卿为其外,我为其内,天下不足定也。”马超听后大惊,彭羕走后以他的说话告发彭羕,彭羕于是被收监下狱。最后彭羕被处死,死时三十七岁。", + dongxie: + "董卓之女,牛辅之妻。在《三国群英传》中名为董宜,在电视剧《三国群英会之吕布与貂蝉》中名为董媛。", + caoanmin: + "曹安民(?-197年),沛国谯县(今安徽亳州)人,字安民。东汉时期人物,曹德之子,曹操之侄,曹昂的堂兄弟,曹丕的堂兄,死于宛城之战。按曹丕《典论》记载的“亡兄孝廉子脩、从兄安民遇害。”等情况来看,安民应该是曹操侄子错不了,曹丕是他们属于兄弟关系肯定不会弄错。另外从典论的记载来看安民是和子脩并提的,子脩是曹昂的字,安民则肯定也是字不是名,至于三国志中记载则应取自曹丕之《典论》但陈寿又不知曹安民其名,故写为“长子昂、弟子安民”。", + dufuren: + "杜夫人(生卒年不详),东汉末年至三国时人。有异色,原为吕布将秦宜禄之妻,生子秦朗。后为曹操纳为妾,又生曹林、曹衮、金乡公主。", + mifangfushiren: + "麋芳(生卒年不详),字子方,东海郡朐县(今江苏省连云港市)人。汉末三国时期蜀国将领,刘备糜夫人的兄弟。麋芳本为徐州牧陶谦部下,曾被曹操表为彭城相。后来辞官,随刘备从徐州辗转至邺城、汝南、新野、长坂坡、江夏等地,奔波多年。傅士仁(生卒年不详),字君义,幽州广阳郡(今北京市)人,刘备手下将领。受到刘备的重用,但被关羽轻慢。
              刘备称汉中王时,糜芳为南郡太守,但受到关羽的轻慢。后来,因未完成供给军资的任务而被关羽责骂,心中不安。吕蒙袭取荆州时,将已经投降的傅士仁展示给糜芳,麋芳于是选择投降,导致关羽兵败被杀。此后,在吴国担任将军,并且为吴征伐。", + tongyuan: + "童渊,字雄付,武术名家,与并州李彦是结拜兄弟,两人均师承义父玉真子,两人分别娶了河北颜家的两位大小姐颜云、颜雨。童飞之父,有张任、张绣为入室弟子,晚年收赵云为关门弟子,传其毕生所学。其成名技为“百鸟朝凤枪”。童渊是南方苏州评话三国中的原创人物,在历史中以及《三国演义》中并不存在。", //zhangning:'张宁,东汉末年大贤良师张角的女儿。自幼学习太平道法,掌握天地法则。', - xinping:'辛评(?-204年),字仲治,颍川阳翟人,东汉末年人物。曹魏卫尉辛毗之兄。原是韩馥部下,韩馥逃亡后转而辅佐袁绍。袁绍死后,辛评、郭图欲立袁谭为主,与审配等不和。后来曹操破邺,其弟辛毗在城下劝降。审配怒遣手下将辛评全家杀害。', - hanmeng:'韩猛,又名韩若、韩荀、韩泣(上荀下大) ,东汉末年袁绍帐下名将,或与《曹瞒传》所言韩莒子为同一人。公元200年,官渡之战爆发。袁绍派遣韩猛劫掠曹操军的西道,被曹军部将曹仁击破于鸡洛山。袁绍又派韩猛前去运送粮车,因为轻敌被曹军部将徐晃、史涣击退。', - yanfuren:'《三国志》中东汉末年著名武将吕布有一妻子,但姓名未载于史书,或为魏续的姐妹魏氏。在李傕郭汜之乱期间曾受困,幸亏被庞舒所救,私藏于府中而得以幸免。吕布被曹操围困时,反对陈宫的计谋,导致了吕布的失败。《三国演义》中,姓严,通称严夫人,和吕布生有一女欲嫁于袁术之子,未果,吕布失败后与其女一同送往许昌。', - haomeng:'郝萌(?-196年),东汉末年吕布帐下名将。建安元年(196年),郝萌在袁术的怂恿下反叛吕布,曾一度打得吕布躲入厕所。后来,被吕布部将高顺所阻,其部将曹性临阵反叛,最终被高顺所杀。在小说《三国演义》中,吕布被围下邳时,郝萌护送许汜王楷回城时,被张飞擒获,被曹操所杀。', - licaiwei:'李采薇,生卒年不详,汉末将领庞德之妻,庞会之母。襄樊之战时,庞德任先锋,随于禁率军增援驻守樊城的曹仁。出战前,他将妻子李采薇与年仅六岁的儿子庞会叫来面前,对李采薇说:“吾今为先锋,义当效死疆场。我若死,汝好生看养吾儿。吾儿有异相,长大必当与吾报仇也。”李采薇闻言,与儿子痛哭送别庞德。她知道丈夫已下定决心,若无法胜利归还则必当战死沙场,绝不会投降求生。其后前线果然传来消息:魏军全军覆没,于禁投降,庞德誓死不降被关羽所杀。其子庞会自幼丧父,由母亲抚养长大。成年后,庞会性格勇烈,有先父之风。他多次立下战功,深受魏文帝曹丕的喜爱。后来庞会随钟会、邓艾伐蜀,成都城破之后,尽灭关氏家以报父仇。', - yanrou:'阎柔(生卒年不详),燕国广阳(今北京市附近)人。三国时期曹魏名将。年少时曾被乌丸、鲜卑俘虏,后来却得到他们的信任。刘虞死后,阎柔被鲜于辅等推举为乌丸司马,联系鲜卑为刘虞报仇,和公孙瓒对抗。在官渡之战时归曹操,拜护乌丸校尉,对曹操讨伐乌丸有功,赐爵关内侯。曹操待其如子,曹丕也视其如亲兄弟,阎柔坐镇北方,统帅幽州兵马,抗击胡人的入侵。曹丕即位后,阎柔被拜为度辽将军。', - qinyilu:'秦宜禄(?—200年),并州云中郡云中县人(今内蒙古自治区呼和浩特市托克托县古城镇)。东汉军阀吕布的部将。吕布战败后归降曹操,后为张飞所杀。', - fengfang:'冯方,其字不详,司隶人。初掌校事,监察京师及周边地区,刺探文武百官秘事。十常侍之乱后,董卓进京,掌控朝政。冯方认为他胸怀不臣之心,于是弃官携女儿冯妤至江南避祸。其后董卓果然乱政,京师之地生灵涂炭,更将洛阳付之一炬。冯方因其先见之明得以保全家人。
              冯妤长大成人后,有倾国之貌。一日袁术登城观景,得见冯妤,心中非常喜欢,于是将其纳为夫人。冯方心忧自家女儿不谙世事,于是将可以让人更显妩媚的家传宝梳交给她,希望能借此使其获得袁术的宠爱。其后果然传来袁术偏爱冯夫人的消息,冯方因此宽心,接受了袁术的征辟,为其效力。然而好景不长,没过多久,冯妤自缢身亡的消息传出,冯方悲愤不已,弃官而走,自此销声匿迹。', - bianxi:'小说《三国演义》里的人物。汜水关守将,并州人氏。原是黄巾余党,后投曹操,拨来守汜水关。善使流星锤。在镇国寺设下伏兵欲谋害千里寻兄的关羽,但是寺中僧人普净暗示加以解救。最后被关羽斩杀。', - niufu:'牛辅,东汉末年武将,东汉相国董卓的女婿。曾任中郎将,征讨白波军,不能取胜。董卓被杀时,牛辅别屯于陕地。吕布派李肃前去征讨牛辅,被牛辅击败。后来,牛辅营中有士兵半夜背叛出逃,造成内乱,牛辅以为整营皆叛,于是带着金银珠宝,独与亲信胡赤儿等五六人逾城北渡河。赤儿等人以绳索系在牛辅腰间将其从城头放下,但赤儿等因为谋财而在离地面数丈高的地方就松开了绳子使得牛辅重重摔在地上腰部受伤,而后赤儿与诸胡人将牛辅斩首,将其首级送去长安。', - wangwei:'王威,东汉末年人。荆州刺史刘表部下将领,乃忠义之士。刘表亡后,刘琮投降曹操,王威向刘琮献计偷袭曹操,刘琮没有采纳。小说《三国演义》中,曹操表刘琮为青州刺史,使远离故乡,时只有王威追随,曹操复遣于禁追杀刘琮等人,王威亦于乱军中殉主。', - liyixiejing:'李异(生卒年不详),三国时吴将领,曾随陆逊大败蜀军。谢旌(生卒年不详),三国时期吴国名将,会稽(今属浙江)人。建安末,李异与谢旌率水陆三千,破蜀将詹晏、陈凤。刘备领兵攻孙权,李异与陆议等屯巫、秭归,为蜀将所破。黄武元年(222),陆逊破刘备于猇亭,他追踪蜀军,屯驻南山。建安二十四年,陆逊击败关羽后,遣李异、谢旌二人将水陆军三千,进攻蜀将詹晏、陈凤。李异率水军,谢旌率陆军,于险要之地设防,击败詹晏,生擒陈凤。其后进攻房陵太守邓辅、南乡太守郭睦,大破之。又攻秭归大姓文布、邓凯等所合夷兵数千人,大胜,文布、邓凯落荒而逃。在《三国演义》中,两人为孙桓麾下部将,皆有“万夫不当之勇”。刘备攻吴时,谢旌迎战张苞,不敌败走。李异接战,被关兴所斩。次日,谢旌于乱军中被张苞一矛刺死。', - shiyi:'是仪(生卒年不详),本名氏仪,字子羽,北海郡营陵县(今山东昌乐)人,三国时期吴国官员。仕东汉、东吴两朝,早年曾在本县营陵县及本郡北海郡任官,后在东吴历任骑都尉、忠义校尉、裨将军、偏将军、侍中、中执法、尚书仆射等官。先封都亭侯,后进封都乡侯。年八十一岁时病逝,死前要求节葬。', - sunlang:'孙狼(生卒年不详),东汉末农民起义军首领。建安二十三年(218)陆浑(今河南嵩县东北)县长张固发民服徭役,百姓惶俱,狼等乘机发动起义,杀县主簿,攻破县城,后南下投奔蜀将关羽。', - sp_jiaxu:'字文和,武威姑臧人。三国时期魏国著名谋士。曾先后担任三国军阀李傕、张绣、曹操的谋士。官至魏国太尉,谥曰肃侯。', - sunhuan:'孙桓(198年-223年),字叔武,吴郡富春(今浙江杭州富阳区)人,三国时期吴国建武将军。孙河第三子。仪容端正,器怀聪明,博学强记,能论议应对,孙权常称为“宗室颜渊”。初擢为武卫都尉。建安二十四年(219年),参与由吕蒙指挥的袭击荆州行动,从讨关羽于华容,招揽关羽余众,得五千人以及大量牛马器械。黄武元年(222年),孙桓二十五岁,拜安东中郎将,跟随陆逊抗击进攻东吴的刘备。当时刘备率领众多兵众进攻,满山都是蜀军,孙桓奋战,与陆逊等协力击破蜀军。刘备兵败逃走,孙桓截击,“斩上夔道,扼要径”,差点生擒刘备。战后孙桓因功拜建武将军,封丹徒侯,督牛渚,修筑横江坞,期间逝世。', - guānning:'关宁,《三国演义》的虚构人物,为关定之子,关平的哥哥,学文。关羽前往冀州寻找刘备时曾居于关定庄,关定命关宁、关平二子出拜。后关羽同刘备回到关定庄时,关羽向刘备介绍关宁、关平二人,关定即提出让关平拜关羽为义父。', - mushun:'穆顺,小说《三国演义》中的人物,男,东汉末宦官。献帝欲修书与国舅伏完,共谋图曹公。因顺为宦官中之忠义可托者,乃命顺往送书。顺藏书于发中,潜出禁宫,径至完宅,将书呈上。及完回书付顺,顺乃藏于头髻内,辞完回宫。然公闻信,先于宫门等候,顺回遇公,公喝左右,遍搜身上,并无夹带,放行。忽然风吹落其帽。公又唤回,取帽视之,遍观无物,还帽令戴。顺双手倒戴其帽。公心疑,令左右搜其头发中,搜出伏完书来。公见书大怒,执下顺于密室问之,顺不肯招。当晚将顺、完等宗族二百余口,皆斩于市。', - jsp_guanyu:'关羽,字云长。曾水淹七军、擒于禁、斩庞德、威震华夏,吓得曹操差点迁都躲避,但是东吴偷袭荆州,关羽兵败被害。后传说吕蒙因关羽之魂索命而死。', - liuling:'刘伶(约221年-约300年),字伯伦,西晋沛国(治今安徽濉溪县西北)人,竹林七贤之一,中国魏晋时期作家,名士。
              刘伶自幼便失去了父爱,因其父亲身材矮小,及至长大成人后,刘伶身高也不过六尺。魏齐王曹芳正始之末(249年),刘伶已成为当世名重一时的名士,并且常与嵇康、阮籍、阮咸集会于山阳竹林之下,饮酒赋诗,弹琴作歌。晋武帝司马炎泰始初年(265年)前后,曾做过一段时间的建威参军,不久朝廷下诏,入宫中策问。他大谈老庄,强调无为而治,非但没有得到重用,反而连参军之职也被罢免了,从此再无仕进。晋惠帝司马衷永康元年(300年)前后,以寿而终。
              刘伶有“品酒第一人”的美称,也被酒行业传颂至今,后人以古瀑河边上的井水酿酒,还取刘伶墓地的黄土垒成窖池酿酒,为了纪念刘伶,当地百姓也将“润泉涌”更名为“刘伶醉”。其传世作品仅有《酒德颂》《北芒客舍》两篇,其中《酒德颂》所表现出的藐视一切存在的气概,敌视礼教之士的反抗精神,既高扬了人格的力量,批判了当时的黑暗政治,同时也抒发了压抑的愤世之情,充满了浪漫色彩,气魄豪迈,用辞又骈偶间行,有无意追求而自至的特点,对后代影响极大。', + xinping: + "辛评(?-204年),字仲治,颍川阳翟人,东汉末年人物。曹魏卫尉辛毗之兄。原是韩馥部下,韩馥逃亡后转而辅佐袁绍。袁绍死后,辛评、郭图欲立袁谭为主,与审配等不和。后来曹操破邺,其弟辛毗在城下劝降。审配怒遣手下将辛评全家杀害。", + hanmeng: + "韩猛,又名韩若、韩荀、韩泣(上荀下大) ,东汉末年袁绍帐下名将,或与《曹瞒传》所言韩莒子为同一人。公元200年,官渡之战爆发。袁绍派遣韩猛劫掠曹操军的西道,被曹军部将曹仁击破于鸡洛山。袁绍又派韩猛前去运送粮车,因为轻敌被曹军部将徐晃、史涣击退。", + yanfuren: + "《三国志》中东汉末年著名武将吕布有一妻子,但姓名未载于史书,或为魏续的姐妹魏氏。在李傕郭汜之乱期间曾受困,幸亏被庞舒所救,私藏于府中而得以幸免。吕布被曹操围困时,反对陈宫的计谋,导致了吕布的失败。《三国演义》中,姓严,通称严夫人,和吕布生有一女欲嫁于袁术之子,未果,吕布失败后与其女一同送往许昌。", + haomeng: + "郝萌(?-196年),东汉末年吕布帐下名将。建安元年(196年),郝萌在袁术的怂恿下反叛吕布,曾一度打得吕布躲入厕所。后来,被吕布部将高顺所阻,其部将曹性临阵反叛,最终被高顺所杀。在小说《三国演义》中,吕布被围下邳时,郝萌护送许汜王楷回城时,被张飞擒获,被曹操所杀。", + licaiwei: + "李采薇,生卒年不详,汉末将领庞德之妻,庞会之母。襄樊之战时,庞德任先锋,随于禁率军增援驻守樊城的曹仁。出战前,他将妻子李采薇与年仅六岁的儿子庞会叫来面前,对李采薇说:“吾今为先锋,义当效死疆场。我若死,汝好生看养吾儿。吾儿有异相,长大必当与吾报仇也。”李采薇闻言,与儿子痛哭送别庞德。她知道丈夫已下定决心,若无法胜利归还则必当战死沙场,绝不会投降求生。其后前线果然传来消息:魏军全军覆没,于禁投降,庞德誓死不降被关羽所杀。其子庞会自幼丧父,由母亲抚养长大。成年后,庞会性格勇烈,有先父之风。他多次立下战功,深受魏文帝曹丕的喜爱。后来庞会随钟会、邓艾伐蜀,成都城破之后,尽灭关氏家以报父仇。", + yanrou: "阎柔(生卒年不详),燕国广阳(今北京市附近)人。三国时期曹魏名将。年少时曾被乌丸、鲜卑俘虏,后来却得到他们的信任。刘虞死后,阎柔被鲜于辅等推举为乌丸司马,联系鲜卑为刘虞报仇,和公孙瓒对抗。在官渡之战时归曹操,拜护乌丸校尉,对曹操讨伐乌丸有功,赐爵关内侯。曹操待其如子,曹丕也视其如亲兄弟,阎柔坐镇北方,统帅幽州兵马,抗击胡人的入侵。曹丕即位后,阎柔被拜为度辽将军。", + qinyilu: + "秦宜禄(?—200年),并州云中郡云中县人(今内蒙古自治区呼和浩特市托克托县古城镇)。东汉军阀吕布的部将。吕布战败后归降曹操,后为张飞所杀。", + fengfang: + "冯方,其字不详,司隶人。初掌校事,监察京师及周边地区,刺探文武百官秘事。十常侍之乱后,董卓进京,掌控朝政。冯方认为他胸怀不臣之心,于是弃官携女儿冯妤至江南避祸。其后董卓果然乱政,京师之地生灵涂炭,更将洛阳付之一炬。冯方因其先见之明得以保全家人。
              冯妤长大成人后,有倾国之貌。一日袁术登城观景,得见冯妤,心中非常喜欢,于是将其纳为夫人。冯方心忧自家女儿不谙世事,于是将可以让人更显妩媚的家传宝梳交给她,希望能借此使其获得袁术的宠爱。其后果然传来袁术偏爱冯夫人的消息,冯方因此宽心,接受了袁术的征辟,为其效力。然而好景不长,没过多久,冯妤自缢身亡的消息传出,冯方悲愤不已,弃官而走,自此销声匿迹。", + bianxi: "小说《三国演义》里的人物。汜水关守将,并州人氏。原是黄巾余党,后投曹操,拨来守汜水关。善使流星锤。在镇国寺设下伏兵欲谋害千里寻兄的关羽,但是寺中僧人普净暗示加以解救。最后被关羽斩杀。", + niufu: "牛辅,东汉末年武将,东汉相国董卓的女婿。曾任中郎将,征讨白波军,不能取胜。董卓被杀时,牛辅别屯于陕地。吕布派李肃前去征讨牛辅,被牛辅击败。后来,牛辅营中有士兵半夜背叛出逃,造成内乱,牛辅以为整营皆叛,于是带着金银珠宝,独与亲信胡赤儿等五六人逾城北渡河。赤儿等人以绳索系在牛辅腰间将其从城头放下,但赤儿等因为谋财而在离地面数丈高的地方就松开了绳子使得牛辅重重摔在地上腰部受伤,而后赤儿与诸胡人将牛辅斩首,将其首级送去长安。", + wangwei: + "王威,东汉末年人。荆州刺史刘表部下将领,乃忠义之士。刘表亡后,刘琮投降曹操,王威向刘琮献计偷袭曹操,刘琮没有采纳。小说《三国演义》中,曹操表刘琮为青州刺史,使远离故乡,时只有王威追随,曹操复遣于禁追杀刘琮等人,王威亦于乱军中殉主。", + liyixiejing: + "李异(生卒年不详),三国时吴将领,曾随陆逊大败蜀军。谢旌(生卒年不详),三国时期吴国名将,会稽(今属浙江)人。建安末,李异与谢旌率水陆三千,破蜀将詹晏、陈凤。刘备领兵攻孙权,李异与陆议等屯巫、秭归,为蜀将所破。黄武元年(222),陆逊破刘备于猇亭,他追踪蜀军,屯驻南山。建安二十四年,陆逊击败关羽后,遣李异、谢旌二人将水陆军三千,进攻蜀将詹晏、陈凤。李异率水军,谢旌率陆军,于险要之地设防,击败詹晏,生擒陈凤。其后进攻房陵太守邓辅、南乡太守郭睦,大破之。又攻秭归大姓文布、邓凯等所合夷兵数千人,大胜,文布、邓凯落荒而逃。在《三国演义》中,两人为孙桓麾下部将,皆有“万夫不当之勇”。刘备攻吴时,谢旌迎战张苞,不敌败走。李异接战,被关兴所斩。次日,谢旌于乱军中被张苞一矛刺死。", + shiyi: "是仪(生卒年不详),本名氏仪,字子羽,北海郡营陵县(今山东昌乐)人,三国时期吴国官员。仕东汉、东吴两朝,早年曾在本县营陵县及本郡北海郡任官,后在东吴历任骑都尉、忠义校尉、裨将军、偏将军、侍中、中执法、尚书仆射等官。先封都亭侯,后进封都乡侯。年八十一岁时病逝,死前要求节葬。", + sunlang: + "孙狼(生卒年不详),东汉末农民起义军首领。建安二十三年(218)陆浑(今河南嵩县东北)县长张固发民服徭役,百姓惶俱,狼等乘机发动起义,杀县主簿,攻破县城,后南下投奔蜀将关羽。", + sp_jiaxu: + "字文和,武威姑臧人。三国时期魏国著名谋士。曾先后担任三国军阀李傕、张绣、曹操的谋士。官至魏国太尉,谥曰肃侯。", + sunhuan: + "孙桓(198年-223年),字叔武,吴郡富春(今浙江杭州富阳区)人,三国时期吴国建武将军。孙河第三子。仪容端正,器怀聪明,博学强记,能论议应对,孙权常称为“宗室颜渊”。初擢为武卫都尉。建安二十四年(219年),参与由吕蒙指挥的袭击荆州行动,从讨关羽于华容,招揽关羽余众,得五千人以及大量牛马器械。黄武元年(222年),孙桓二十五岁,拜安东中郎将,跟随陆逊抗击进攻东吴的刘备。当时刘备率领众多兵众进攻,满山都是蜀军,孙桓奋战,与陆逊等协力击破蜀军。刘备兵败逃走,孙桓截击,“斩上夔道,扼要径”,差点生擒刘备。战后孙桓因功拜建武将军,封丹徒侯,督牛渚,修筑横江坞,期间逝世。", + guānning: + "关宁,《三国演义》的虚构人物,为关定之子,关平的哥哥,学文。关羽前往冀州寻找刘备时曾居于关定庄,关定命关宁、关平二子出拜。后关羽同刘备回到关定庄时,关羽向刘备介绍关宁、关平二人,关定即提出让关平拜关羽为义父。", + mushun: "穆顺,小说《三国演义》中的人物,男,东汉末宦官。献帝欲修书与国舅伏完,共谋图曹公。因顺为宦官中之忠义可托者,乃命顺往送书。顺藏书于发中,潜出禁宫,径至完宅,将书呈上。及完回书付顺,顺乃藏于头髻内,辞完回宫。然公闻信,先于宫门等候,顺回遇公,公喝左右,遍搜身上,并无夹带,放行。忽然风吹落其帽。公又唤回,取帽视之,遍观无物,还帽令戴。顺双手倒戴其帽。公心疑,令左右搜其头发中,搜出伏完书来。公见书大怒,执下顺于密室问之,顺不肯招。当晚将顺、完等宗族二百余口,皆斩于市。", + jsp_guanyu: + "关羽,字云长。曾水淹七军、擒于禁、斩庞德、威震华夏,吓得曹操差点迁都躲避,但是东吴偷袭荆州,关羽兵败被害。后传说吕蒙因关羽之魂索命而死。", + liuling: + "刘伶(约221年-约300年),字伯伦,西晋沛国(治今安徽濉溪县西北)人,竹林七贤之一,中国魏晋时期作家,名士。
              刘伶自幼便失去了父爱,因其父亲身材矮小,及至长大成人后,刘伶身高也不过六尺。魏齐王曹芳正始之末(249年),刘伶已成为当世名重一时的名士,并且常与嵇康、阮籍、阮咸集会于山阳竹林之下,饮酒赋诗,弹琴作歌。晋武帝司马炎泰始初年(265年)前后,曾做过一段时间的建威参军,不久朝廷下诏,入宫中策问。他大谈老庄,强调无为而治,非但没有得到重用,反而连参军之职也被罢免了,从此再无仕进。晋惠帝司马衷永康元年(300年)前后,以寿而终。
              刘伶有“品酒第一人”的美称,也被酒行业传颂至今,后人以古瀑河边上的井水酿酒,还取刘伶墓地的黄土垒成窖池酿酒,为了纪念刘伶,当地百姓也将“润泉涌”更名为“刘伶醉”。其传世作品仅有《酒德颂》《北芒客舍》两篇,其中《酒德颂》所表现出的藐视一切存在的气概,敌视礼教之士的反抗精神,既高扬了人格的力量,批判了当时的黑暗政治,同时也抒发了压抑的愤世之情,充满了浪漫色彩,气魄豪迈,用辞又骈偶间行,有无意追求而自至的特点,对后代影响极大。", }, - characterTitle:{ - chunyuqiong:'#b对决限定武将', - sp_xuyou:'#g4v4限定武将', + characterTitle: { + chunyuqiong: "#b对决限定武将", + sp_xuyou: "#g4v4限定武将", }, - characterFilter:{ - chunyuqiong:function(mode){ - return mode!='identity'&&mode!='guozhan'; + characterFilter: { + chunyuqiong: function (mode) { + return mode != "identity" && mode != "guozhan"; }, - sp_xuyou:function(mode){ - return mode=='versus'&&['guandu','4v4','four'].includes(_status.mode); + sp_xuyou: function (mode) { + return mode == "versus" && ["guandu", "4v4", "four"].includes(_status.mode); }, }, - dynamicTranslate:{ - mubing:function(player){ - if(player.storage.mubing2) return '出牌阶段开始时,你可以展示牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。'; - return '出牌阶段开始时,你可以展示牌堆顶的三张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。'; + dynamicTranslate: { + mubing: function (player) { + if (player.storage.mubing2) + return "出牌阶段开始时,你可以亮出牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。"; + return "出牌阶段开始时,你可以亮出牌堆顶的三张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。"; }, - piaoping:function(player){ - if(player.storage.piaoping) return '转换技,锁定技。当你使用一张牌时,阴:你摸X张牌。阳:你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)'; + piaoping: function (player) { + if (player.storage.piaoping) + return '转换技,锁定技。当你使用一张牌时,阴:你摸X张牌。阳:你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)'; return '转换技,锁定技。当你使用一张牌时,阴:你摸X张牌。阳:你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)'; }, - chuaili:function(player){ - if(!player.hasSkill('piaoping',null,null,false)) return '锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。'; - if(player.storage.piaoping) return '锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。'; + chuaili: function (player) { + if (!player.hasSkill("piaoping", null, null, false)) + return "锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。"; + if (player.storage.piaoping) + return '锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。'; return '锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。'; }, - dcdouzhen:function(player){ - var str='锁定技。①转换技。你的回合内,'; - if(player.countMark('dcdouzhen')%2) str+='阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。'; - else str+='阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。'; + dcdouzhen: function (player) { + var str = "锁定技。①转换技。你的回合内,"; + if (player.countMark("dcdouzhen") % 2) + str += + '阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。'; + else + str += + '阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。'; return str; }, }, - perfectPair:{ - nanhualaoxian:['zuoci','yuji'], - re_nanhualaoxian:['zuoci','yuji'], + perfectPair: { + nanhualaoxian: ["zuoci", "yuji"], + re_nanhualaoxian: ["zuoci", "yuji"], }, - characterReplace:{ - lijue:['lijue','ns_lijue'], - fanchou:['fanchou','tw_fanchou','ns_fanchou'], - zhangji:['zhangji','ns_zhangji'], - zhangchangpu:['ol_zhangchangpu','zhangchangpu','sp_zhangchangpu'], - huangfusong:['huangfusong','sp_huangfusong','jsrg_huangfusong','old_huangfusong'], - dingyuan:['ol_dingyuan','dingyuan'], - quyi:['quyi','re_quyi'], - hansui:['hansui','re_hansui','xin_hansui','jsrg_hansui'], - jin_simashi:['dc_simashi','jin_simashi','simashi'], - jin_yanghuiyu:['jin_yanghuiyu','yanghuiyu'], - taoqian:['re_taoqian','taoqian'], - jsp_liubei:['jsrg_liubei','jsp_liubei'], - dongcheng:['re_dongcheng','dongcheng'], - hucheer:['re_hucheer','hucheer','tw_hucheer'], - nanhualaoxian:['re_nanhualaoxian','nanhualaoxian','jsrg_nanhualaoxian'], - pangdegong:['re_pangdegong','pangdegong'], - zhujun:['ol_zhujun','zhujun','sp_zhujun','jsrg_zhujun'], - tw_liuhong:['liuhong','tw_liuhong','jsrg_liuhong'], - re_hejin:['hejin','re_hejin','tw_hejin','jsrg_hejin'], - hujinding:['dc_hujinding','ol_hujinding','hujinding'], - caosong:['caosong','sp_caosong'], - re_niujin:['niujin','re_niujin','tw_niujin'], - haomeng:['haomeng','tw_haomeng'], - zhangning:['zhangning','tw_zhangning'], - caoanmin:['caoanmin','ns_caoanmin'], - duanwei:['duanwei','junk_duanwei'], - xushao:['xushao','jsrg_xushao'], - huban:['ol_huban','dc_huban','mb_huban'], - mengda:['ol_mengda','dc_mengda','pe_mengda'], - jsp_guanyu:['jsp_guanyu','dc_jsp_guanyu','jsrg_guanyu'], - mushun:['mushun','sp_mushun'], - wangjun:['dc_wangjun','wangjun'], - zoushi:['re_zoushi','jsrg_zoushi'], - zhangmancheng:['dc_zhangmancheng','tw_zhangmancheng'], + characterReplace: { + lijue: ["lijue", "ns_lijue"], + fanchou: ["fanchou", "tw_fanchou", "ns_fanchou"], + zhangji: ["zhangji", "ns_zhangji"], + zhangchangpu: ["ol_zhangchangpu", "zhangchangpu", "sp_zhangchangpu"], + huangfusong: ["huangfusong", "sp_huangfusong", "jsrg_huangfusong", "old_huangfusong"], + dingyuan: ["ol_dingyuan", "dingyuan"], + quyi: ["quyi", "re_quyi"], + hansui: ["hansui", "re_hansui", "xin_hansui", "jsrg_hansui"], + jin_simashi: ["dc_simashi", "jin_simashi", "simashi"], + jin_yanghuiyu: ["jin_yanghuiyu", "yanghuiyu"], + taoqian: ["re_taoqian", "taoqian"], + jsp_liubei: ["jsrg_liubei", "jsp_liubei"], + dongcheng: ["re_dongcheng", "dongcheng"], + hucheer: ["re_hucheer", "hucheer", "tw_hucheer"], + nanhualaoxian: ["re_nanhualaoxian", "nanhualaoxian", "jsrg_nanhualaoxian"], + pangdegong: ["re_pangdegong", "pangdegong"], + zhujun: ["ol_zhujun", "zhujun", "sp_zhujun", "jsrg_zhujun"], + tw_liuhong: ["liuhong", "tw_liuhong", "jsrg_liuhong"], + re_hejin: ["hejin", "re_hejin", "tw_hejin", "jsrg_hejin"], + hujinding: ["dc_hujinding", "ol_hujinding", "hujinding"], + caosong: ["caosong", "sp_caosong"], + re_niujin: ["niujin", "re_niujin", "tw_niujin"], + haomeng: ["haomeng", "tw_haomeng"], + zhangning: ["zhangning", "tw_zhangning"], + caoanmin: ["caoanmin", "ns_caoanmin"], + duanwei: ["duanwei", "junk_duanwei"], + xushao: ["xushao", "jsrg_xushao"], + huban: ["ol_huban", "dc_huban", "mb_huban"], + mengda: ["ol_mengda", "dc_mengda", "pe_mengda"], + jsp_guanyu: ["jsp_guanyu", "dc_jsp_guanyu", "jsrg_guanyu"], + mushun: ["mushun", "sp_mushun"], + wangjun: ["dc_wangjun", "wangjun"], + zoushi: ["re_zoushi", "jsrg_zoushi"], + zhangmancheng: ["dc_zhangmancheng", "tw_zhangmancheng"], }, - translate:{ - lijue:"李傕", - zhangji:"张济", - fanchou:"樊稠", - guosi:"郭汜", - lvkai:"吕凯", - zhanggong:"张恭", - weiwenzhugezhi:"卫温诸葛直", - xurong:"徐荣", - zhangqiying:"张琪瑛", - sp_liuqi:'刘琦', - xf_tangzi:"唐咨", - gz_xf_huangquan:"黄权", - xf_huangquan:"OL黄权", - xf_huangquan_prefix:"OL", - gz_xf_sufei:"苏飞", - xf_sufei:"OL苏飞", - xf_sufei_prefix:"OL", - "xinfu_langxi":"狼袭", - "xinfu_langxi_info":"准备阶段,你可以对一名体力小于或等于你的其他角色造成0~2点随机伤害。", - "xinfu_yisuan":"亦算", - "xinfu_yisuan_info":"每回合限一次。当你于出牌阶段内使用的锦囊牌结算结束后,你可以减1点体力上限并获得此牌对应的所有实体牌。", - "xinfu_xingluan":"兴乱", - "xinfu_xingluan_info":"每回合限一次。当你于出牌阶段内使用的仅指定一个目标的牌结算完成后,你可以从牌堆中随机获得一张点数为6的牌。", - "xinfu_lveming":"掠命", - "xinfu_lveming_info":"出牌阶段限一次,你可以选择一名装备区装备比你少的角色,令其选择一个点数,然后你进行判定:
              若点数相同,你对其造成2点伤害;
              若点数不同,则你随机获得其区域内的一张牌。", - "xinfu_tunjun":"屯军", - "xinfu_tunjun_info":"限定技,出牌阶段,你可以选择一名角色,令其随机使用牌堆中的X张装备牌。(X为你发动过“掠命”的次数)", - "xinfu_tanbei":"贪狈", - "xinfu_tanbei_info":"出牌阶段限一次,你可以令一名其他角色选择一项:1.令你随机获得其区域内的一张牌,本回合内你不能对其使用牌。2.令你此回合内对其使用牌没有次数与距离限制。", - "xinfu_sidao":"伺盗", - xinfu_sidaox:'伺盗', - "xinfu_sidao_info":"出牌阶段限一次,当你对一名其他角色连续使用两张牌后,你可以将一张手牌当做【顺手牵羊】对其使用。", - "tanbei_effect1":"贪狈", - "tanbei_effect1_info":"", - "tanbei_effect2":"贪狈", - "tanbei_effect2_info":"", + translate: { + lijue: "李傕", + zhangji: "张济", + fanchou: "樊稠", + guosi: "郭汜", + lvkai: "吕凯", + zhanggong: "张恭", + weiwenzhugezhi: "卫温诸葛直", + xurong: "徐荣", + zhangqiying: "张琪瑛", + sp_liuqi: "刘琦", + xf_tangzi: "唐咨", + gz_xf_huangquan: "黄权", + xf_huangquan: "OL黄权", + xf_huangquan_prefix: "OL", + gz_xf_sufei: "苏飞", + xf_sufei: "OL苏飞", + xf_sufei_prefix: "OL", + xinfu_langxi: "狼袭", + xinfu_langxi_info: "准备阶段,你可以对一名体力小于或等于你的其他角色造成0~2点随机伤害。", + xinfu_yisuan: "亦算", + xinfu_yisuan_info: + "每回合限一次。当你于出牌阶段内使用的锦囊牌结算结束后,你可以减1点体力上限并获得此牌对应的所有实体牌。", + xinfu_xingluan: "兴乱", + xinfu_xingluan_info: + "每回合限一次。当你于出牌阶段内使用的仅指定一个目标的牌结算完成后,你可以从牌堆中随机获得一张点数为6的牌。", + xinfu_lveming: "掠命", + xinfu_lveming_info: + "出牌阶段限一次,你可以选择一名装备区装备比你少的角色,令其选择一个点数,然后你进行判定:
              若点数相同,你对其造成2点伤害;
              若点数不同,则你随机获得其区域内的一张牌。", + xinfu_tunjun: "屯军", + xinfu_tunjun_info: + "限定技,出牌阶段,你可以选择一名角色,令其随机使用牌堆中的X张装备牌。(X为你发动过“掠命”的次数)", + xinfu_tanbei: "贪狈", + xinfu_tanbei_info: + "出牌阶段限一次,你可以令一名其他角色选择一项:1.令你随机获得其区域内的一张牌,本回合内你不能对其使用牌。2.令你此回合内对其使用牌没有次数与距离限制。", + xinfu_sidao: "伺盗", + xinfu_sidaox: "伺盗", + xinfu_sidao_info: + "出牌阶段限一次,当你对一名其他角色连续使用两张牌后,你可以将一张手牌当做【顺手牵羊】对其使用。", + tanbei_effect1: "贪狈", + tanbei_effect1_info: "", + tanbei_effect2: "贪狈", + tanbei_effect2_info: "", - "xinfu_tunan":"图南", - "xinfu_tunan_info":"出牌阶段限一次,你可以展示牌堆顶的一张牌并选择一名其他角色,然后该角色选择一项:使用此牌(无距离限制);或将此牌当普通【杀】使用。", - "xinfu_bijing":"闭境", - "xinfu_bijing_info":"结束阶段,你可以选择至多两张手牌并标记为“闭境”,然后你获得如下效果:1.其他角色的弃牌阶段开始时,若你于本回合内失去过“闭境”,其弃置两张牌;2.准备阶段,你重铸所有“闭境”牌。", - "xinfu_zhenxing":"镇行", - "xinfu_zhenxing_info":"结束阶段开始时或当你受到伤害后,你可以观看牌堆顶的至多三张牌,然后你获得其中与其余牌花色均不相同的一张牌。", - "xinfu_qianxin":"遣信", - "xinfu_qianxin_info":"出牌阶段限一次,若牌堆中没有“信”,你可以选择一名角色并将任意张手牌放置于牌堆中X倍数的位置(X为存活人数),称为“信”。该角色的弃牌阶段开始时,若其手牌区内有于本回合内获得过的“信”,其选择一项:令你将手牌摸至四张;本回合手牌上限-2。", - "qianxin_effect":"遣信", - "qianxin_effect_info":"", - "xinfu_qianxin2":"遣信", - "xinfu_qianxin2_info":"", + xinfu_tunan: "图南", + xinfu_tunan_info: + "出牌阶段限一次,你可以亮出牌堆顶的一张牌并选择一名其他角色,然后该角色选择一项:使用此牌(无距离限制);或将此牌当普通【杀】使用。", + xinfu_bijing: "闭境", + xinfu_bijing_info: + "结束阶段,你可以选择至多两张手牌并标记为“闭境”,然后你获得如下效果:1.其他角色的弃牌阶段开始时,若你于本回合内失去过“闭境”,其弃置两张牌;2.准备阶段,你重铸所有“闭境”牌。", + xinfu_zhenxing: "镇行", + xinfu_zhenxing_info: + "结束阶段开始时或当你受到伤害后,你可以观看牌堆顶的至多三张牌,然后你获得其中与其余牌花色均不相同的一张牌。", + xinfu_qianxin: "遣信", + xinfu_qianxin_info: + "出牌阶段限一次,若牌堆中没有“信”,你可以选择一名角色并将任意张手牌放置于牌堆中X倍数的位置(X为存活人数),称为“信”。该角色的弃牌阶段开始时,若其手牌区内有于本回合内获得过的“信”,其选择一项:令你将手牌摸至四张;本回合手牌上限-2。", + qianxin_effect: "遣信", + qianxin_effect_info: "", + xinfu_qianxin2: "遣信", + xinfu_qianxin2_info: "", - "xinfu_fuhai":"浮海", - "xinfu_fuhai_info":"出牌阶段每个方向限一次,你可以展示一张手牌并选择上家或下家。该角色展示一张手牌,若你展示的牌点数大于等于其展示的牌点数,你弃置你展示的牌,然后继续对其上家或下家重复此流程;若你展示的牌点数小于该展示角色牌的点数,则该角色弃置其展示的牌,然后你与其各摸X张牌(X为你此回合内发动此技能选择的角色数),且你此阶段内不能再发动〖浮海〗。", - "fuhai_clear":"浮海", - "fuhai_clear_info":"", + xinfu_fuhai: "浮海", + xinfu_fuhai_info: + "出牌阶段每个方向限一次,你可以展示一张手牌并选择上家或下家。该角色展示一张手牌,若你展示的牌点数大于等于其展示的牌点数,你弃置你展示的牌,然后继续对其上家或下家重复此流程;若你展示的牌点数小于该展示角色牌的点数,则该角色弃置其展示的牌,然后你与其各摸X张牌(X为你此回合内发动此技能选择的角色数),且你此阶段内不能再发动〖浮海〗。", + fuhai_clear: "浮海", + fuhai_clear_info: "", - "xz_xunxun":"恂恂", - "xz_xunxun_info":"摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。", - "xinfu_xingzhao":"兴棹", - "xinfu_xingzhao_info":"锁定技。若X≥1,你视为拥有技能〖恂恂〗。若X≥2,当你使用装备牌时,你摸一张牌。若X≥3,判定阶段或弃牌阶段开始时,你跳过此阶段。若X=0或X≥4,当你造成伤害时,此伤害+1(X为场上已受伤的角色数)。", - "xinfu_xingzhao2":"兴棹", - "xinfu_xingzhao2_info":"", - xinfu_xingzhao3:'兴棹', - "xinfu_dianhu":"点虎", - "xinfu_dianhu_info":"锁定技,游戏开始时,你选择一名其他角色。当其受到来自你的伤害后或回复体力后,你摸一张牌。", - "xinfu_dianhu2":"点虎", - "xinfu_dianhu2_info":"", - "xinfu_jianji":"谏计", - "xinfu_jianji_info":"出牌阶段限一次,你可以令一名其他角色摸一张牌。然后该角色可以使用此牌。", - "xinfu_lianpian":"联翩", - "xinfu_lianpian_info":"出牌阶段限三次。当你对一名角色连续使用牌时,你可以摸一张牌,然后可以将一张牌交给该角色。", - spwenji:'问计', - spwenji_info:'出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌名称相同的牌时不能被其他角色响应。', - rewenji:'问计', - rewenji_info:'出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌类型相同的牌时不能被其他角色响应。', - sptunjiang:'屯江', - sptunjiang_info:'结束阶段,若你未于本回合的出牌阶段内使用牌指定过其他角色为目标,则你可以摸X张牌(X为全场势力数)。', - zongkui:'纵傀', - zongkui_mark:'纵傀', - zongkui_mark_bg:'傀', - zongkui_info:'回合开始前,你可以指定一名未拥有“傀”标记的其他角色,令其获得一枚“傀”标记。一轮游戏开始时,你指定一名体力值最少且没有“傀”标记的其他角色,令其获得一枚“傀”标记。', - guju:'骨疽', - guju_info:'锁定技,拥有“傀”标记的角色受到伤害后,你摸一张牌。', - baijia:'拜假', - baijia_info:'觉醒技,准备阶段,若你因〖骨疽〗得到的牌不少于7张,则你增加1点体力上限,回复1点体力,然后令所有未拥有“傀”标记的其他角色获得“傀”标记,最后失去技能〖骨疽〗,并获得技能〖蚕食〗。', - bmcanshi:'蚕食', - bmcanshi_info:'一名角色使用基本牌或普通锦囊牌指定你为唯一目标时,若其有“傀”标记,你可以取消之,然后其失去“傀”标记;你使用牌仅指定一名角色为目标时,你可以额外指定任意名带有“傀”标记的角色为目标(无距离限制),然后这些角色失去“傀”标记。', + xz_xunxun: "恂恂", + xz_xunxun_info: + "摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。", + xinfu_xingzhao: "兴棹", + xinfu_xingzhao_info: + "锁定技。若X≥1,你视为拥有技能〖恂恂〗。若X≥2,当你使用装备牌时,你摸一张牌。若X≥3,判定阶段或弃牌阶段开始时,你跳过此阶段。若X=0或X≥4,当你造成伤害时,此伤害+1(X为场上已受伤的角色数)。", + xinfu_xingzhao2: "兴棹", + xinfu_xingzhao2_info: "", + xinfu_xingzhao3: "兴棹", + xinfu_dianhu: "点虎", + xinfu_dianhu_info: + "锁定技,游戏开始时,你选择一名其他角色。当其受到来自你的伤害后或回复体力后,你摸一张牌。", + xinfu_dianhu2: "点虎", + xinfu_dianhu2_info: "", + xinfu_jianji: "谏计", + xinfu_jianji_info: "出牌阶段限一次,你可以令一名其他角色摸一张牌。然后该角色可以使用此牌。", + xinfu_lianpian: "联翩", + xinfu_lianpian_info: + "出牌阶段限三次。当你对一名角色连续使用牌时,你可以摸一张牌,然后可以将一张牌交给该角色。", + spwenji: "问计", + spwenji_info: + "出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌名称相同的牌时不能被其他角色响应。", + rewenji: "问计", + rewenji_info: + "出牌阶段开始时,你可以令一名其他角色交给你一张牌。你于本回合内使用与该牌类型相同的牌时不能被其他角色响应。", + sptunjiang: "屯江", + sptunjiang_info: + "结束阶段,若你未于本回合的出牌阶段内使用牌指定过其他角色为目标,则你可以摸X张牌(X为全场势力数)。", + zongkui: "纵傀", + zongkui_mark: "纵傀", + zongkui_mark_bg: "傀", + zongkui_info: + "回合开始前,你可以指定一名未拥有“傀”标记的其他角色,令其获得一枚“傀”标记。一轮游戏开始时,你指定一名体力值最少且没有“傀”标记的其他角色,令其获得一枚“傀”标记。", + guju: "骨疽", + guju_info: "锁定技,拥有“傀”标记的角色受到伤害后,你摸一张牌。", + baijia: "拜假", + baijia_info: + "觉醒技,准备阶段,若你因〖骨疽〗得到的牌不少于7张,则你增加1点体力上限,回复1点体力,然后令所有未拥有“傀”标记的其他角色获得“傀”标记,最后失去技能〖骨疽〗,并获得技能〖蚕食〗。", + bmcanshi: "蚕食", + bmcanshi_info: + "一名角色使用基本牌或普通锦囊牌指定你为唯一目标时,若其有“傀”标记,你可以取消之,然后其失去“傀”标记;你使用牌仅指定一名角色为目标时,你可以额外指定任意名带有“傀”标记的角色为目标(无距离限制),然后这些角色失去“傀”标记。", - xinpi:'辛毗', - lisu:'李肃', - zhangwen:'张温', - xushao:'许劭', - mangyachang:"忙牙长", - xugong:"许贡", - zhangchangpu:"张昌蒲", - pingjian:'评荐', - pingjian_use:'评荐', - pingjian_info:'结束阶段开始时/当你受到伤害后/出牌阶段限一次,你可以令系统随机检索出三张拥有发动时机为结束阶段开始时/当你受到伤害后/出牌阶段的技能的武将牌。然后你可以选择尝试发动其中一个技能。每个技能每局游戏只能选择一次。', + xinpi: "辛毗", + lisu: "李肃", + zhangwen: "张温", + xushao: "许劭", + mangyachang: "忙牙长", + xugong: "许贡", + zhangchangpu: "张昌蒲", + pingjian: "评荐", + pingjian_use: "评荐", + pingjian_info: + "结束阶段开始时/当你受到伤害后/出牌阶段限一次,你可以令系统随机检索出三张拥有发动时机为结束阶段开始时/当你受到伤害后/出牌阶段的技能的武将牌。然后你可以选择尝试发动其中一个技能。每个技能每局游戏只能选择一次。", - songshu:'颂蜀', - songshu_info:'出牌阶段,你可以和其他角色拼点。若你没赢,你与其各摸两张牌,且你本阶段内不能再发动〖颂蜀〗。', - sibian:'思辩', - sibian_info:'摸牌阶段,你可以放弃摸牌,改为亮出牌堆顶的四张牌,然后获得其中所有点数最大与点数最小的牌,且可以将剩余的牌交给手牌数最少的角色。', - lslixun:'利熏', - lslixun_fate:'利熏', - lslixun_info:'锁定技,当你受到伤害时,你防止此伤害,然后获得等同于伤害值的“珠”标记。出牌阶段开始时,你进行判定,若结果点数小于“珠”的数量,你弃置等同于“珠”数量的手牌(若弃牌的牌数不够,则失去剩余数量的体力值)。', - lskuizhu:'馈珠', - lskuizhu_info:'出牌阶段结束时,你可以选择体力值为全场最多的一名其他角色,将手牌摸至与该角色相同(最多摸至五张),然后该角色观看你的手牌,弃置任意张手牌并从观看的牌中获得等量的牌。若其得到的牌大于一张,则你选择一项:移去一个“珠”;或令其对其攻击范围内的一名角色造成1点伤害。', - xpchijie:'持节', - xpchijie_info:'每回合每项各限一次。1.当其他角色使用的牌对你结算结束后,你可以令此牌对所有后续目标无效。2.其他角色使用的牌结算完成时,若你是此牌的目标之一且此牌未造成过伤害,则你可以获得此牌对应的所有实体牌。', - xpchijie2:'持节', - yinju:'引裾', - yinju_info:'限定技,出牌阶段,你可以选择一名其他角色。若如此做,当你于此阶段内使用牌指定其为目标后,你与其各摸一张牌;当你即将对其造成伤害时,防止此伤害,然后其回复等量的体力。', - yinju2:'引裾', + songshu: "颂蜀", + songshu_info: + "出牌阶段,你可以和其他角色拼点。若你没赢,你与其各摸两张牌,且你本阶段内不能再发动〖颂蜀〗。", + sibian: "思辩", + sibian_info: + "摸牌阶段,你可以放弃摸牌,改为亮出牌堆顶的四张牌,然后获得其中所有点数最大与点数最小的牌,且可以将剩余的牌交给手牌数最少的角色。", + lslixun: "利熏", + lslixun_fate: "利熏", + lslixun_info: + "锁定技,当你受到伤害时,你防止此伤害,然后获得等同于伤害值的“珠”标记。出牌阶段开始时,你进行判定,若结果点数小于“珠”的数量,你弃置等同于“珠”数量的手牌(若弃牌的牌数不够,则失去剩余数量的体力值)。", + lskuizhu: "馈珠", + lskuizhu_info: + "出牌阶段结束时,你可以选择体力值为全场最多的一名其他角色,将手牌摸至与该角色相同(最多摸至五张),然后该角色观看你的手牌,弃置任意张手牌并从观看的牌中获得等量的牌。若其得到的牌大于一张,则你选择一项:移去一个“珠”;或令其对其攻击范围内的一名角色造成1点伤害。", + xpchijie: "持节", + xpchijie_info: + "每回合每项各限一次。1.当其他角色使用的牌对你结算结束后,你可以令此牌对所有后续目标无效。2.其他角色使用的牌结算完成时,若你是此牌的目标之一且此牌未造成过伤害,则你可以获得此牌对应的所有实体牌。", + xpchijie2: "持节", + yinju: "引裾", + yinju_info: + "限定技,出牌阶段,你可以选择一名其他角色。若如此做,当你于此阶段内使用牌指定其为目标后,你与其各摸一张牌;当你即将对其造成伤害时,防止此伤害,然后其回复等量的体力。", + yinju2: "引裾", - spjiedao:"截刀", - "spjiedao_info":"当你每回合第一次造成伤害时,你可令此伤害至多+X(X为你损失的体力值)。然后若受到此伤害的角色没有死亡,你弃置等同于此伤害加值的牌。", - biaozhao:"表召", - "biaozhao_info":"结束阶段,你可以将一张牌置于武将牌上,称为“表”。当有一张与“表”花色点数均相同的牌进入弃牌堆后,你将“表”置入弃牌堆并失去1点体力,若此牌是其他角色因弃置而进入弃牌堆的,则改为该角色获得“表”。准备阶段,若你的武将牌上有“表”,则你将“表”置入弃牌堆。然后你选择一名角色,该角色回复1点体力且将手牌摸至与全场手牌数最多的人相同(最多摸五张)。", - "biaozhao2":"表召", - "biaozhao2_info":"", - "biaozhao3":"表召", - "biaozhao3_info":"", - yechou:"业仇", - "yechou_info":"当你死亡时,你可以选择一名已损失体力值大于1的角色。直到其下个回合开始前,每个回合结束时,该角色失去1点体力。", - "yechou2":"业仇", - "yechou2_info":"", - yanjiao:"严教", - "yanjiao_info":"出牌阶段限一次,你可以选择一名其他角色并从牌堆顶亮出四张牌。该角色将这些牌分成点数之和相等的两组,你与其各获得其中一组,然后将剩余未分组的牌置入弃牌堆。若未分组的牌超过一张,则你本回合手牌上限-1。", - "yanjiao2":"严教", - "yanjiao2_info":"", - xingshen:"省身", - "xingshen_info":"当你受到伤害后,你可以摸一张牌且下一次发动〖严教〗亮出的牌数+1。若你的手牌数为全场最少,则改为摸两张牌;若你的体力值为全场最少,则〖严教〗亮出的牌数改为+2(加值总数不能超过4)。", + spjiedao: "截刀", + spjiedao_info: + "当你每回合第一次造成伤害时,你可令此伤害至多+X(X为你损失的体力值)。然后若受到此伤害的角色没有死亡,你弃置等同于此伤害加值的牌。", + biaozhao: "表召", + biaozhao_info: + "结束阶段,你可以将一张牌置于武将牌上,称为“表”。当有一张与“表”花色点数均相同的牌进入弃牌堆后,你将“表”置入弃牌堆并失去1点体力,若此牌是其他角色因弃置而进入弃牌堆的,则改为该角色获得“表”。准备阶段,若你的武将牌上有“表”,则你将“表”置入弃牌堆。然后你选择一名角色,该角色回复1点体力且将手牌摸至与全场手牌数最多的人相同(最多摸五张)。", + biaozhao2: "表召", + biaozhao2_info: "", + biaozhao3: "表召", + biaozhao3_info: "", + yechou: "业仇", + yechou_info: + "当你死亡时,你可以选择一名已损失体力值大于1的角色。直到其下个回合开始前,每个回合结束时,该角色失去1点体力。", + yechou2: "业仇", + yechou2_info: "", + yanjiao: "严教", + yanjiao_info: + "出牌阶段限一次,你可以选择一名其他角色并从牌堆顶亮出四张牌。该角色将这些牌分成点数之和相等的两组,你与其各获得其中一组,然后将剩余未分组的牌置入弃牌堆。若未分组的牌超过一张,则你本回合手牌上限-1。", + yanjiao2: "严教", + yanjiao2_info: "", + xingshen: "省身", + xingshen_info: + "当你受到伤害后,你可以摸一张牌且下一次发动〖严教〗亮出的牌数+1。若你的手牌数为全场最少,则改为摸两张牌;若你的体力值为全场最少,则〖严教〗亮出的牌数改为+2(加值总数不能超过4)。", - sp_zhanghe:'SP张郃', - sp_zhanghe_prefix:'SP', - yuanlve:'远略', - yuanlve_info:'出牌阶段限一次,你可以将一张非装备牌交给一名角色,然后该角色可以使用该牌并令你摸一张牌。', - xunchen:'OL荀谌', - xunchen_prefix:'OL', - fenglve:'锋略', - fenglve2:'锋略', - fenglve_info:'出牌阶段开始时,你可以与一名角色拼点,若你赢,该角色将其区域内的各一张牌交给你;若你没赢,你交给其一张牌。当你的单人拼点结算后,你可以令对方获得你拼点的牌。', - mouzhi:'谋识', - mouzhi2:'谋识', - mouzhi_info:'出牌阶段限一次,你可以将一张手牌交给一名角色,若如此做,当其于其下回合的出牌阶段内对一名角色造成伤害后,若是此阶段其第一次对该角色造成伤害,你摸一张牌。', - sp_shenpei:'SP审配', - sp_shenpei_prefix:'SP', - gangzhi:'刚直', - gangzhi_info:'锁定技,当你即将受到其他角色造成的伤害时,或即将对其他角色造成伤害时,你防止此伤害,改为受到伤害的角色失去等量的体力。', - beizhan:'备战', - beizhan2:'备战', - beizhan_info:'结束阶段,你可以令一名角色将手牌摸至体力上限(至多为5)。其下个回合开始时,若其手牌数为全场最多,则其此回合内使用的牌不能指定其他角色为目标。', - gaolan:'OL高览', - gaolan_prefix:'OL', - xiying:'袭营', - xiying2:'袭营', - xiying_info:'出牌阶段开始时,你可以弃置一张非基本手牌,然后令所有其他角色依次选择一项:弃置一张牌,或本回合内不能使用或打出牌;且你本回合内获得如下效果:结束阶段,若你于本回合的出牌阶段内造成过伤害,则你从牌堆中获得一张伤害性基本牌或普通锦囊牌。', - lvkuanglvxiang:'OL吕旷吕翔', - lvkuanglvxiang_prefix:'OL', - liehou:'列侯', - liehou_info:'出牌阶段限一次,你可以令一名攻击范围内的角色交给你一张手牌,然后你将一张手牌交给攻击范围内的另一名角色。', - qigong:'齐攻', - qigong_info:'当你使用的【杀】被【闪】抵消之后,你可以令一名角色再对目标角色使用一张【杀】(不可被响应)。', - chunyuqiong:'淳于琼', - sushou:'宿守', - sushou_info:'弃牌阶段开始时,你可以摸X+1张牌(X为“粮”数),然后可以交给任意名友方角色各一张牌。', - cangchu:'仓储', - cangchu_info:'锁定技,游戏开始时,你获得3枚“粮”标记,当你受到1点火焰伤害后,你失去一枚“粮”标记。', - liangying:'粮营', - liangying_info:'锁定技,若你有“粮”标记,则友方角色摸牌阶段摸牌数+1;当你失去所有“粮”标记后,你减1点体力上限,然后令敌方角色各摸两张牌。', - sp_xuyou:'SP许攸', - sp_xuyou_prefix:'SP', - spshicai:'恃才', - spshicai2:'恃才', - spshicai_info:'出牌阶段,牌堆顶的一张牌对你可见。你可以弃置一张牌,然后获得牌堆顶的一张牌,且不能再发动〖恃才〗直到此牌离开你的手牌区。', - spfushi:'附势', - spfushi_info:'锁定技,若己方存活角色数:大于敌方,你视为拥有〖择主〗;小于敌方,你视为拥有〖逞功〗。', - zezhu:'择主', - zezhu_info:'出牌阶段限一次,你可以获得双方主帅的各一张牌(若无牌则改为你摸一张牌),然后交给双方主帅各一张牌。', - chenggong:'逞功', - chenggong_info:'当有角色使用牌指定目标后,若此牌对目标数大于1,则你可令使用者摸一张牌。', - sp_zhangliao:'SP张辽', - sp_zhangliao_prefix:'SP', + sp_zhanghe: "SP张郃", + sp_zhanghe_prefix: "SP", + yuanlve: "远略", + yuanlve_info: + "出牌阶段限一次,你可以将一张非装备牌交给一名角色,然后该角色可以使用该牌并令你摸一张牌。", + xunchen: "OL荀谌", + xunchen_prefix: "OL", + fenglve: "锋略", + fenglve2: "锋略", + fenglve_info: + "出牌阶段开始时,你可以与一名角色拼点,若你赢,该角色将其区域内的各一张牌交给你;若你没赢,你交给其一张牌。当你的单人拼点结算后,你可以令对方获得你拼点的牌。", + mouzhi: "谋识", + mouzhi2: "谋识", + mouzhi_info: + "出牌阶段限一次,你可以将一张手牌交给一名角色,若如此做,当其于其下回合的出牌阶段内对一名角色造成伤害后,若是此阶段其第一次对该角色造成伤害,你摸一张牌。", + sp_shenpei: "SP审配", + sp_shenpei_prefix: "SP", + gangzhi: "刚直", + gangzhi_info: + "锁定技,当你即将受到其他角色造成的伤害时,或即将对其他角色造成伤害时,你防止此伤害,改为受到伤害的角色失去等量的体力。", + beizhan: "备战", + beizhan2: "备战", + beizhan_info: + "结束阶段,你可以令一名角色将手牌摸至体力上限(至多为5)。其下个回合开始时,若其手牌数为全场最多,则其此回合内使用的牌不能指定其他角色为目标。", + gaolan: "OL高览", + gaolan_prefix: "OL", + xiying: "袭营", + xiying2: "袭营", + xiying_info: + "出牌阶段开始时,你可以弃置一张非基本手牌,然后令所有其他角色依次选择一项:弃置一张牌,或本回合内不能使用或打出牌;且你本回合内获得如下效果:结束阶段,若你于本回合的出牌阶段内造成过伤害,则你从牌堆中获得一张伤害性基本牌或普通锦囊牌。", + lvkuanglvxiang: "OL吕旷吕翔", + lvkuanglvxiang_prefix: "OL", + liehou: "列侯", + liehou_info: + "出牌阶段限一次,你可以令一名攻击范围内的角色交给你一张手牌,然后你将一张手牌交给攻击范围内的另一名角色。", + qigong: "齐攻", + qigong_info: + "当你使用的【杀】被【闪】抵消之后,你可以令一名角色再对目标角色使用一张【杀】(不可被响应)。", + chunyuqiong: "淳于琼", + sushou: "宿守", + sushou_info: "弃牌阶段开始时,你可以摸X+1张牌(X为“粮”数),然后可以交给任意名友方角色各一张牌。", + cangchu: "仓储", + cangchu_info: + "锁定技,游戏开始时,你获得3枚“粮”标记,当你受到1点火焰伤害后,你失去一枚“粮”标记。", + liangying: "粮营", + liangying_info: + "锁定技,若你有“粮”标记,则友方角色摸牌阶段摸牌数+1;当你失去所有“粮”标记后,你减1点体力上限,然后令敌方角色各摸两张牌。", + sp_xuyou: "SP许攸", + sp_xuyou_prefix: "SP", + spshicai: "恃才", + spshicai2: "恃才", + spshicai_info: + "出牌阶段,牌堆顶的一张牌对你可见。你可以弃置一张牌,然后获得牌堆顶的一张牌,且不能再发动〖恃才〗直到此牌离开你的手牌区。", + spfushi: "附势", + spfushi_info: + "锁定技,若己方存活角色数:大于敌方,你视为拥有〖择主〗;小于敌方,你视为拥有〖逞功〗。", + zezhu: "择主", + zezhu_info: + "出牌阶段限一次,你可以获得双方主帅的各一张牌(若无牌则改为你摸一张牌),然后交给双方主帅各一张牌。", + chenggong: "逞功", + chenggong_info: "当有角色使用牌指定目标后,若此牌对目标数大于1,则你可令使用者摸一张牌。", + sp_zhangliao: "SP张辽", + sp_zhangliao_prefix: "SP", //这仨技能给SP仲村由理毫无违和感好吗!!! - mubing:'募兵', - mubing_info:'出牌阶段开始时,你可以展示牌堆顶的三张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。', - ziqu:'资取', - ziqu_info:'每名角色限一次,当你对有牌的其他角色造成伤害后,你可以防止此伤害。然后其将其点数最大的牌交给你。', - diaoling:'调令', - diaoling_info:'觉醒技,准备阶段,若你已因〖募兵〗获得了6张或更多的【杀】或武器牌或伤害锦囊牌,则你回复1点体力或摸两张牌,然后修改〖募兵〗。', - mubing_rewrite:'募兵·改', - mubing_rewrite_info:'出牌阶段开始时,你可以展示牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。', - caobuxing:'曹不兴', - moying:'墨影', - moying_info:'每回合限一次,当你于回合外不因使用而失去单一一张锦囊牌或装备牌后,你可以选择一个花色和与此牌点数差绝对值不超过2的点数,然后获得牌堆中所有与此牌花色点数相同的牌。', - juanhui:'绢绘', - juanhui2:'绢绘', - juanhui2_backup:'绢绘', - juanhui_info:'结束阶段,你可以选择一名其他角色。记录该角色下回合的出牌阶段里使用的基本牌和普通锦囊牌(每种牌名限记一次),你的下回合出牌阶段,可将一张手牌当这些牌里的任意一张牌使用(每张限使用一次,且【杀】不计次数)。当"绢绘"的牌全部用完时,你回复1点体力并将手牌摸至三张。', - re_maliang:'新杀马良', - re_maliang_prefix:'新杀', - rexiemu:'协穆', - rexiemu_info:'结束阶段,若全场没有“协穆”标记,你可以选择一名角色获得“协穆”标记直到你的下回合开始。你或该角色在各自的回合外使用或打出手牌时,你与其各摸一张牌(每回合限一次)。', - heli:'贺励', - heli_info:'出牌阶段限一次,你可以选择手牌数比你少的一名其他角色。该角色展示所有手牌,然后每缺少一种类型的牌,便从牌堆中随机获得一张此类型的牌。', - zhujun:'朱儁', - gongjian:'攻坚', - gongjian_info:'每回合限一次,当有角色使用【杀】指定第一个目标后,若此【杀】的目标和本局游戏内被使用的上一张【杀】的目标的交集A不为空,则你可以依次弃置A中所有角色的至多两张牌,然后获得以此法弃置的所有【杀】。', - kuimang:'溃蟒', - kuimang_info:'锁定技,一名角色死亡后,若你对其造成过伤害,你摸两张牌。', - liuhong:'刘宏', - yujue:'鬻爵', - yujue_backup:'鬻爵', - yujue_info:'出牌阶段限一次,你可以废除一个装备栏,然后令一名有手牌的其他角色交给你一张手牌。其获得〖执笏〗直到你的下回合开始。', - zhihu:'执笏', - zhihu_mark:'执笏', - zhihu_info:'锁定技,每回合限两次,当你对其他角色造成伤害后,你摸两张牌。', - tuxing:'图兴', - tuxing2:'图兴', - tuxing_info:'锁定技,当你废除一个装备栏时,你加1点体力上限并回复1点体力。然后若你所有的装备栏均已被废除,则你减4点体力上限,且本局游戏内造成的伤害+1。', - re_hejin:'新杀何进', - re_hejin_prefix:'新杀', - xin_baosanniang:'新杀鲍三娘', - xin_baosanniang_prefix:'新杀', - decadexushen:"许身", - decadexushen2:'许身', - decadexushen_info:"限定技,当你进入濒死状态后,你可以回复1点体力并获得技能“镇南”,然后如果你脱离濒死状态且“关索”不在场,你可令一名其他角色选择是否用“关索”代替其武将并令其摸三张牌。", - decadezhennan:"镇南", - decadezhennan_info:"当有角色使用普通锦囊牌指定目标后,若此牌目标数大于1,你可以对一名其他角色造成1点伤害。", - ol_dingyuan:'丁原', - cixiao:'慈孝', - cixiao_info:'准备阶段,若场上没有“义子”标记,你可令一名其他角色获得一个“义子”标记;若场上有“义子”标记,你可以弃置一张牌移动“义子”标记。拥有“义子”标记的角色获得技能“叛弑”。', - panshi:'叛弑', - panshi_info:'锁定技,准备阶段,你交给有“慈孝”技能的角色一张手牌;当你于出牌阶段因使用【杀】对其他角色造成伤害时,若其拥有技能“慈孝”,则此伤害+1,且你结束出牌阶段。', - xianshuai:'先率', - xianshuai_info:'锁定技,有角色造成伤害后,若此伤害是本轮第一次造成伤害:你摸一张牌;若伤害来源是你,则你对受伤角色再造成1点伤害。', - wangrong:'王荣', - minsi:'敏思', - minsi2:'敏思', - minsi_info:'出牌阶段限一次,你可以弃置任意张点数之和为13的牌,然后摸两倍数量的牌。以此法得到的牌中,黑色牌本回合无距离限制,红色牌本回合不计入手牌上限。', - jijing:'吉境', - jijing_info:'当你受到伤害后,你可以进行一次判定,然后若你弃置任意张点数之和与判定结果点数相同的牌,你回复1点体力。', - zhuide:'追德', - zhuide_info:'当你死亡时,你可令一名其他角色从牌堆中获得四张名称各不相同的基本牌。', - decadewuniang:'武娘', - decadewuniang_info:'当你使用或打出【杀】时,你可以获得一名其他角色的一张牌。若如此做,其摸一张牌。(若你已发动许身,则关索也摸一张牌)', - dongxie:'董翓', - juntun:'军屯', - juntun_info:'锁定技,准备阶段,若X大于1,则你减1点体力上限并摸X张牌(X为你的体力上限)。', - jiaojie:'狡黠', - jiaojie_info:'锁定技,你的红色牌不计入手牌上限。你使用黑色牌无距离和次数限制。', - dcjiaoxia:'狡黠', - dcjiaoxia_info:'①出牌阶段开始时,你可以令自己的所有手牌于此阶段均视为【杀】。若如此做,你使用以此法转化的【杀】造成伤害后,你可以使用此牌对应的原卡牌。②出牌阶段,你对你本阶段未使用过【杀】的角色使用【杀】无距离和次数限制。', - dchumei:'狐魅', - dchumei_info:'出牌阶段各限一次,你可以选择一名体力值不大于X的角色,令其:①摸一张牌。②交给你一张牌。③回复1点体力。(X为你本阶段造成的伤害数)', - buchen:'不臣', - buchen_info:'隐匿技,你于其他角色的回合登场时,可获得当前回合角色的一张牌。', - smyyingshi:'鹰视', - smyyingshi_info:'锁定技,出牌阶段,你可观看牌堆顶的X张牌(X为你的体力上限)。', - xiongzhi:'雄志', - xiongzhi_info:'限定技,出牌阶段,你可展示牌堆顶的一张牌并使用之。若如此做,你重复此流程,直到你以此法展示的牌无法使用。', - quanbian:'权变', - quanbian2:'权变', - quanbian_info:'当你于出牌阶段内使用/打出手牌时,若此牌有花色且你本回合内未使用/打出过该花色的其他手牌,则你可以选择一项:①摸一张牌。②将牌堆顶X张牌中的一张置于牌堆底(X为你的体力上限)。若你发动此技能,则你本回合内不能再使用与此牌花色相同的手牌。', - re_hansui:'新杀韩遂', - re_hansui_prefix:'新杀', - re_quyi:'新杀麴义', - re_quyi_prefix:'新杀', - refuqi:'伏骑', - refuqi_info:'锁定技,当你使用牌时,你令所有距离为1的其他角色不能使用或打出牌响应此牌。', - hanfu:'韩馥', - hfjieying:'节应', - hfjieying2:'节应', - hfjieying3:'节应', - hfjieying_info:'结束阶段,你可以选择一名其他角色,该角色下回合使用【杀】或普通锦囊牌无距离限制且可多指定一个目标,且当其造成伤害后,其无法再使用牌直到回合结束。', - weipo:'危迫', - weipo_info:'锁定技,其他角色使用【杀】或普通锦囊牌指定你为目标后,若你的手牌数小于X,则你将手牌摸至X张,并记录摸牌事件结算后的手牌数Y。此牌结算结束后,若你的手牌数小于Y,则你将一张手牌交给此牌的使用者,且此技能失效直到你的下回合开始。(X为你的体力上限且至多为5)', - zhaozhong:'赵忠', - yangzhong:'殃众', - yangzhong_info:'当你造成或受到伤害后,若受伤角色和伤害来源均存活,则伤害来源可弃置两张牌,然后令受伤角色失去1点体力。', - huangkong:'惶恐', - huangkong_info:'锁定技,当你于回合外成为【杀】或普通锦囊牌的目标后,若你没有手牌,则你摸两张牌。', - re_taoqian:'陶谦', - reyixiang:'义襄', - reyixiang_info:'锁定技,其他角色于其出牌阶段内使用的第一张牌对你的伤害-1;其使用的第二张牌若为黑色,则对你无效。', - caosong:'曹嵩', - cslilu:'礼赂', - cslilu_info:'摸牌阶段,你可以放弃摸牌,改为将手牌摸至X张(X为你的体力上限和5中的最小值),然后将至少一张手牌交给一名其他角色。若你以此法给出的牌数大于你上次以此法给出的牌数,则你加1点体力上限并回复1点体力。', - csyizheng:'翊正', - csyizheng2:'翊正', - csyizheng_info:'结束阶段开始时,你可以选择一名其他角色。你的下回合开始前,当该角色造成伤害或回复体力时,若其体力上限小于你,则你减1点体力上限,且令此伤害值/回复值+1。', - reyirang:'揖让', - reyirang_info:'出牌阶段开始时,你可以将所有非基本牌交给一名其他角色。若其体力上限大于你,则你将体力上限调整至与其相同。然后你回复X点体力(X为你以此法交给其的牌数)。', - liangxing:'梁兴', - lulve:'掳掠', - lulve_info:'出牌阶段开始时,你可选择一名有手牌且手牌数少于你的角色。其选择一项:①将所有手牌交给你,然后你将武将牌翻面。②将武将牌翻面,然后其视为对你使用一张【杀】。', - lxzhuixi:'追袭', - lxzhuixi_info:'锁定技,当你造成伤害或受到伤害时,若受伤角色的翻面状态和伤害来源的翻面状态不同,则此伤害+1。', - zhangmiao:'张邈', - mouni:'谋逆', - mouni_info:'准备阶段,你可对一名其他角色依次使用你手牌中所有的【杀】(若其进入了濒死状态,则终止此流程)。然后若这些【杀】中有未造成伤害的【杀】,则你跳过本回合的出牌阶段和弃牌阶段。', - zongfan:'纵反', - zongfan_info:'觉醒技。结束阶段,若你本回合内因〖谋逆〗使用过【杀】且未跳过本回合的出牌阶段,则你将任意张牌交给一名其他角色,然后加X点体力上限并回复X点体力(X为你以此法给出的牌数且至多为5)。最后失去〖谋逆〗并获得〖战孤〗。', - zhangu:'战孤', - zhangu_info:'锁定技,准备阶段,若你的体力上限大于1且没有手牌/装备区内没有牌,则你减1点体力上限,然后从牌堆中获得三张类型不同的牌。', - re_niujin:'新杀牛金', - re_niujin_prefix:'新杀', - recuorui:'摧锐', - recuorui_info:'限定技,出牌阶段,你可以依次获得至多X名角色的各一张手牌(X为你的体力值)。', - reliewei:'裂围', - reliewei_info:'每回合限Y次,当有角色进入濒死状态时,你可以摸一张牌(Y为你的体力值,若当前回合角色为你,则Y为Infinity)。', - duanwei:'段煨', - langmie:'狼灭', - langmie_damage:'狼灭', - langmie_info:'其他角色的出牌阶段结束时,若其本阶段内使用过的牌中有类型相同的牌,则你可以摸一张牌;其他角色的结束阶段开始时,若其本回合内造成的伤害大于1,则你可以弃置一张牌并对其造成1点伤害。', - zhangheng:'张横', - dangzai:'挡灾', - dangzai_info:'出牌阶段开始时,你可将一名其他角色判定区内的一张牌移动至你的判定区内。', - liangjue:'粮绝', - liangjue_info:'锁定技,当有黑色牌进入或者离开你的判定区或装备区后,若你的体力值大于1,你失去1点体力,然后摸两张牌。', - tangji:'唐姬', - kangge:'抗歌', - kangge_info:'你的第一个回合开始时,选择一名其他角色,该角色每次于其回合外得到牌后,你摸等量的牌(每回合至多摸三张);其进入濒死状态时,你可令其回复体力至1点(每轮限一次)。该角色死亡时,你弃置所有牌并失去1点体力。', - jielie:'节烈', - jielie_info:'当你受到除自己和“抗歌”角色以外的角色造成的伤害时,你可以防止此伤害并选择一种花色,然后你失去X点体力,令“抗歌”角色从弃牌堆中随机获得X张此花色的牌(X为伤害值)。', - re_dongcheng:'董承', - xuezhao:'血诏', - xuezhao_info:'出牌阶段限一次,你可弃置一张手牌并选择至多X名其他角色(X为你的体力上限)。这些角色依次选择是否交给你一张牌,若选择是,该角色摸一张牌且你本回合可多使用一张【杀】;若选择否,该角色本回合无法响应你使用的牌。', - re_hucheer:'胡车儿', - redaoji:'盗戟', - redaoji2:'盗戟', - redaoji_info:'其他角色第一次使用武器牌时,你可选择一项:①获得此牌。②令其本回合内不能使用或打出【杀】。', - fuzhong:'负重', - fuzhong_info:'锁定技,当你于回合外得到牌后,你获得一枚“重”标记。若X:大于0,你于摸牌阶段开始时令额定摸牌数+1;大于1,你至其他角色的距离-2;大于2,你的手牌上限+3;大于3,结束阶段开始时,你对一名其他角色造成1点伤害,然后移去4枚“重”(X为“重”数)。', - qiuliju:'丘力居', - koulve:'寇略', - koulve_info:'当你于出牌阶段内对其他角色造成伤害后,你可以展示其X张手牌(X为其已损失的体力值)。若这些牌中:有带有伤害标签的基本牌或锦囊牌,则你获得之;有红色牌,则你失去1点体力(若已受伤则改为减1点体力上限),然后摸两张牌。', - qljsuiren:'随认', - qljsuiren_info:'当你死亡时,你可以将手牌中所有的带有伤害标签的基本牌或锦囊牌交给一名其他角色。', - re_zoushi:'邹氏', - rehuoshui:'祸水', - rehuoshui_info:'准备阶段,你可以选择至多X名角色(X为你已损失的体力值且至少为1)。你令这些角色中第一名角色的非锁定技失效直到回合结束;第二名角色交给你一张手牌;第三名及之后角色弃置装备区内的所有牌。', - reqingcheng:'倾城', - reqingcheng_info:'出牌阶段限一次,你可以与一名手牌数不大于你的男性角色交换手牌。', - caoanmin:'曹安民', - xianwei:'险卫', - xianwei_info:'锁定技,准备阶段,你废除一个装备栏并摸X张牌(X为你未废除的装备栏数),然后你可以令一名其他角色对其自己使用一张牌堆中的一张与此装备栏副类别相同的装备牌(没有可使用的牌则改为摸一张牌)。当你废除所有装备栏后,你加2点体力上限,然后你与所有其他角色视为在彼此的攻击范围内。', - dufuren:'杜夫人', - yise:'异色', - yise_info:'其他角色得到你的牌后,若这些牌中:有红色牌,你可令其回复1点体力;有黑色牌,其下次受到因执行【杀】的效果造成的伤害时,此伤害+1。', - shunshi:'顺世', - shunshi_info:'准备阶段开始时,或当你受到伤害后,你可将一张牌交给一名不为伤害来源的其他角色并获得如下效果直到你的回合结束:摸牌阶段的额定摸牌数+1,使用【杀】的次数上限+1,手牌上限+1。', - rexingluan:'兴乱', - rexingluan_info:'出牌阶段限一次,当你使用的仅指定一个目标的牌结算完成后,你可以获得场上一张与此牌点数相同的牌,或获得牌堆中随机一张点数与此牌相同的牌。', - xinxingluan:'兴乱', - xinxingluan_info:'每回合限一次。当你于出牌阶段内使用牌结算结束后,你可选择一项:①观看牌堆中的两张点数为6的牌并获得其中一张(没有则改为摸六张牌);②令一名其他角色弃置一张点数为6的牌或交给你一张牌;③获得场上的一张点数为6的牌。', - re_nanhualaoxian:'南华老仙', - gongxiu:'共修', - gongxiu_info:'结束阶段,若你本回合内发动过〖经合〗,则你选择一项:①令所有本回合内成为过〖经合〗目标的角色各摸一张牌;②令所有本回合内未成为过〖经合〗目标的角色各弃置一张手牌。', - jinghe:'经合', - jinghe_info:'出牌阶段限一次,你可以展示至多四张牌名各不相同的牌并选择等量的角色。系统从“写满技能的天书”中随机选择等量的技能,然后这些角色依次选择获得其中的一个。', - nhyinbing:'阴兵', - nhyinbing_info:'锁定技,你使用的【杀】造成伤害改为失去体力。其他角色失去体力后,你摸一张牌。', - nhhuoqi:'活气', - nhhuoqi_info:'出牌阶段限一次,你可以弃置一张牌,然后令体力值最少的一名角色回复1点体力并摸一张牌。', - nhguizhu:'鬼助', - nhguizhu_info:'一名角色进入濒死状态时,你可以摸两张牌(每回合限一次)。', - nhxianshou:'仙授', - nhxianshou_info:'出牌阶段限一次,你可以选择一名角色令其摸一张牌。若其未受伤,则多摸一张。', - nhlundao:'论道', - nhlundao_info:'当你受到伤害后,若伤害来源比你手牌多,你可以弃置其一张牌;若伤害来源比你手牌少,你摸一张牌。', - nhguanyue:'观月', - nhguanyue_info:'结束阶段,你可以观看牌堆顶两张牌,然后获得其中—张,另一张放回牌堆顶。', - nhyanzheng:'言政', - nhyanzheng_info:'准备阶段,若你的手牌数大于1,你可以保留一张手牌并弃置其余的牌,然后选择至多等于弃牌数量的角色,对这些角色各造成1点伤害。', - sp_mifangfushiren:'糜芳傅士仁', - mffengshi:'锋势', - mffengshi_info:'当你使用牌指定唯一目标后,或成为其他角色使用牌的唯一目标后,若此牌使用者的手牌数大于此牌目标的手牌数,则此牌的使用者可令你弃置自己和对方的各一张牌,并令此牌的伤害值+1。', - dcmffengshi:'锋势', - dcmffengshi_info:'当你使用牌指定唯一目标后,或成为其他角色使用牌的唯一目标后,若此牌使用者的手牌数大于此牌目标的手牌数,则你可弃置自己和对方的各一张牌,并令此牌的伤害值+1。', - fengshi:'锋势', - fengshi_info:'当你使用牌指定第一个目标后,你可弃置你与其中一名手牌数小于你的目标角色的各一张牌,并令此牌对其造成的伤害+1;当你成为其他角色使用牌的目标后,若你的手牌数小于其,则你可以弃置你与其的各一张牌,并令此牌对你造成的伤害+1。', - tongyuan:'童渊', - chaofeng:'朝凤', - chaofeng_info:'出牌阶段限一次。当你造成伤害时,你可以弃置一张牌,然后摸一张牌。若此伤害的渠道为牌且你弃置的牌:与此牌颜色相同,则你改为摸两张牌;与此牌类型相同,则此伤害+1。', - chuanshu:'传术', - chuanshu_info:'限定技。准备阶段,若你已受伤;或当你死亡时,你可令一名其他角色获得〖朝凤〗。然后你获得〖龙胆〗、〖从谏〗和〖穿云〗。', - chuanyun:'穿云', - chuanyun_info:'当你使用【杀】指定目标后,你可令目标角色随机弃置其装备区内的一张牌。', - zhangning:'张宁', - tianze:'天则', - tianze_info:'①每回合限触发一次。其他角色于其出牌阶段内使用的黑色手牌结算结束后,你可以弃置一张黑色牌,并对其造成1点伤害。②其他角色的判定生效后,若结果为黑色,则你摸一张牌。', - difa:'地法', - difa_info:'每回合限一次。当你于回合内因摸牌而得到红色牌时,你可以弃置之。然后你选择一个锦囊牌的牌名,并从牌堆中获得一张此牌名的牌。', - xinping:'辛评', - fuyuan:'辅袁', - fuyuan_info:'当你于回合外使用或打出牌时,若当前回合角色的手牌数:不小于你,你可摸一张牌;小于你,你可令其摸一张牌。', - zhongjie:'忠节', - zhongjie_info:'当你死亡时,你可令一名其他角色加1点体力上限并回复1点体力,然后摸一张牌。', - hanmeng:'韩猛', - jieliang:'截粮', - jieliang_info:'其他角色的摸牌阶段开始时,你可弃置一张牌,令其本阶段的摸牌数和本回合的手牌上限-1。然后当其于本回合的弃牌阶段内因弃置而失去牌后,你可获得其中的一张。', - quanjiu:'劝酒', - quanjiu_info:'锁定技。①你手牌区中的【酒】的牌名视为【杀】。②你使用对应的实体牌为一张【酒】的非转化【杀】不计入次数限制。', - re_pangdegong:'庞德公', - heqia:'和洽', - heqia_info:'出牌阶段开始时,你可选择一项:①将任意张牌交给一名其他角色。②令一名有手牌的其他角色交给你任意张牌。然后以此法得到牌的角色可以将一张手牌当作任意基本牌使用,且当其声明使用此牌后,可以为此牌增加至至多X个目标(X为以此法移动的牌数)。', - yinyi:'隐逸', - yinyi_info:'锁定技。每回合限一次,当你受到非属性伤害时,若你的手牌数和体力值与伤害来源均不相同,则你防止此伤害。', - haomeng:'郝萌', - xiongmang:'雄莽', - xiongmang_info:'你可将任意张花色各不相同的手牌当做目标数上限为X的【杀】使用(X为此【杀】对应的实体牌数)。此【杀】使用结算结束后,若你未造成过渠道为此牌的伤害,则你减1点体力上限。', - yanfuren:'严夫人', - channi:'谗逆', - channi_info:'出牌阶段限一次。你可将任意张手牌交给一名其他角色,然后其可以将至多等量的手牌当做【决斗】使用。若其因此【决斗】造成了伤害,则其摸X张牌(X为此【决斗】对应的实体牌数)。若其因此【决斗】受到过伤害,则你弃置所有手牌。', - nifu:'匿伏', - nifu_info:'锁定技。一名角色的回合结束时,你将手牌摸至或弃置至三张。', - licaiwei:'李采薇', - yijiao:'异教', - yijiao_info:'出牌阶段限一次,你可以选择一名没有“异”标记的其他角色并声明一个整数X(X∈[1,4]),该角色获得10X个“异”标记。有“异”标记的角色的结束阶段,其移去“异”标记,且若其本回合使用牌的点数之和:1.小于“异”标记数,其随机弃置至多三张手牌;2.等于“异”标记数,你摸两张牌且该角色本回合结束后进行一个额外的回合;3.大于“异”标记数,你摸三张牌。', - qibie:'泣别', - qibie_info:'一名角色死亡后,若你有手牌且这些手牌均可被弃置,则你可以弃置所有手牌,然后回复1点体力并摸X+2张牌(X为你弃置的牌数)。', - dc_zhuling:'朱灵', - dczhanyi:'战意', - dczhanyi_info:'出牌阶段开始时,你可以弃置所有基本牌/锦囊牌/装备牌,然后获得另外两种类型的牌对应的效果直到你的下个回合开始:基本牌、你使用基本牌无距离限制,且伤害值和回复值基数+1;锦囊牌、你使用锦囊牌时摸一张牌,且锦囊牌不计入手牌上限;装备牌,当装备牌进入你的装备区时,你可弃置一名其他角色的一张牌。', - yanrou:'阎柔', - choutao:'仇讨', - choutao_info:'当你使用【杀】时,或成为【杀】的目标后,你可以弃置此【杀】使用者的一张牌,令此【杀】不可被响应。若你是此【杀】的使用者,则你令此【杀】不计入次数限制。', - xiangshu:'襄戍', - xiangshu_info:'限定技。结束阶段开始时,若你本回合内造成过伤害,则你可以选择一名已受伤的角色。该角色回复X点体力并摸X张牌(X为你本回合内造成的伤害值总和且至多为5)。', - qinyilu:'秦宜禄', - piaoping:'漂萍', - piaoping_info:'转换技,锁定技。当你使用一张牌时,阴:你摸X张牌。阳:你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)', - tuoxian:'托献', - tuoxian_info:'每局游戏限一次。当你因执行〖漂萍〗的效果而弃置牌后,你可令一名其他角色获得这些牌,然后令该角色选择一项:⒈弃置区域内等量的牌。⒉令你的〖漂萍〗失效直到回合结束。', - chuaili:'惴栗', - chuaili_info:'锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。', - fengfang:'冯方', - dcditing:'谛听', - dcditing_info:'其他角色的出牌阶段开始时,若你在该角色的攻击范围内,则你可以观看其的X张手牌(X为你的体力值)并选择其中一张,且获得如下效果:①当其使用对应实体牌包含此牌的牌指定你为目标后,你令此牌对你无效。②当其使用对应实体牌包含此牌的牌结算结束后,若你不是此牌的目标,则你摸两张牌。③其出牌阶段结束时,若此牌位于其的手牌区,则你获得此牌。', - dcbihuo:'避祸', - dcbihuo_info:'①当你受到其他角色造成的伤害后,你可令一名角色下回合摸牌阶段的额定摸牌数+1。②当你对其他角色造成伤害后,你可令一名角色下回合摸牌阶段的额定摸牌数-1。', - bianxi:'卞喜', - dunxi:'钝袭', - dunxi_info:'①当你使用具有伤害标签的牌时,你可以令一名不为你的目标角色获得一枚“钝”。②有“钝”的角色使用基本牌或锦囊牌时,若此牌目标数为1且此时没有角色处于濒死状态,你令其移去一枚“钝”。系统随机选择一名角色,并将此牌的目标改为该角色。若该角色和原目标相同,则其失去1点体力。若其正处于出牌阶段内,则结束此阶段。', - niufu:'牛辅', - dcxiaoxi:'宵袭', - dcxiaoxi_info:'锁定技。出牌阶段开始时,你声明X并减X点体力上限(X∈[1,2])。然后你选择一名攻击范围内的其他角色并选择一项:⒈获得该角色的X张牌。⒉视为对其使用X张【杀】。', - xiongrao:'熊扰', - xiongrao_info:'限定技。准备阶段开始时,你可以选择所有其他角色。这些角色本回合内所有不为锁定技、限定技、觉醒技的普通技能失效。然后你将体力上限增加至7点并摸X张牌(X为你以此法增加的体力上限数)。', - dc_huban:'胡班', - dcchongyi:'崇义', - dcchongyi_info:'①一名角色使用【杀】时,若此牌是其于当前出牌阶段内使用的第一张牌,则你可以令其摸两张牌,且其本回合使用【杀】的次数上限+1。②一名角色的出牌阶段结束时,若其于此阶段内使用的最后一张牌为【杀】,则你可以令其本回合的手牌上限+1。', - wangwei:'王威', - dcruizhan:'锐战', - dcruizhan_info:'其他角色的准备阶段开始时,若其的手牌数不小于其体力值,则你可以和其拼点。若你赢或拼点牌中有【杀】,则你视为对其使用一张【杀】。然后若此【杀】造成了伤害且以上两个条件均被满足,则你获得其一张牌。', - dcshilie:'示烈', - dcshilie_info:'①出牌阶段限一次。你可以选择一项:⒈回复1点体力,将两张牌置于武将牌上作为“示烈”。若“示烈”牌数大于存活人数,则你将最早的多余牌置入弃牌堆;⒉失去1点体力,获得两张“示烈”牌。(满血则不回血,无牌则不移动)②当你死亡时,你可以将所有“示烈”牌交给一名其他角色。', - dc_zhaoyǎn:'赵俨', - dcfuning:'抚宁', - dcfuning_info:'当你使用牌时,你可以摸两张牌,然后弃置X张牌(X为你本回合内发动过〖抚宁〗的次数)。', - dcbingji:'秉纪', - dcbingji_info:'出牌阶段每种花色各限一次。若你有手牌且这些牌的花色均相同,则你可以展示手牌,然后选择一名其他角色,视为对其使用一张【杀】或【桃】(有距离限制)。', - mushun:'穆顺', - dcjinjian:'劲坚', - dcjinjian_info:'①当你受到其他角色造成的伤害后或造成伤害后,你获得一枚“劲”。然后你可以和伤害来源拼点,若你赢,你恢复1点体力。②你的攻击范围+X(X为“劲”数)。', - dcshizhao:'失诏', - dcshizhao_info:'锁定技。每回合限一次,当你于回合外失去手牌后,若你没有手牌,且你:有“劲”,则你移去一枚“劲”并摸两张牌;没有“劲”,则你本回合下一次受到的伤害+1。', - liyixiejing:'李异谢旌', - dcdouzhen:'斗阵', - dcdouzhen_info:'锁定技。①转换技。你的回合内,阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。', - dc_hujinding:'新杀胡金定', - dc_hujinding_prefix:'新杀', - dcdeshi:'德释', - dcdeshi_info:'锁定技。当你受到【杀】的伤害时,若你已受伤,则你防止此伤害并令系统从弃牌堆/牌堆中检索一张【杀】,你获得此【杀】,然后减1点体力上限。', - dcwuyuan:'武缘', - dcwuyuan_info:'出牌阶段限一次。你可将一张【杀】交给一名其他角色,然后你回复1点体力,你与其各摸一张牌。若此【杀】为:红色【杀】,其回复1点体力;属性【杀】,其改为摸两张牌。', - shiyi:'是仪', - dccuichuan:'榱椽', - dccuichuan_info:'出牌阶段限一次。你可以弃置一张手牌并选择一名角色,其随机使用牌堆里一张其空置装备栏对应副类别且其能对其使用的装备牌,你摸X张牌(X为其装备区里的牌数)。然后若其装备区里的牌数增加至四张,你失去〖榱椽〗,获得〖佐谏〗,且令其获得一个额外回合。', - dczhengxu:'正序', - dczhengxu_info:'每回合每项限一次。①当你受到伤害时,若你本回合失去过牌,你可以防止此伤害。②当你失去牌后,若你本回合受到过伤害,你可以摸等量的牌。', - dczuojian:'佐谏', - dczuojian_info:'出牌阶段结束时,若你于此阶段使用过的牌数不小于体力值,你可以选择一项:1.令装备区牌数多于你的角色各摸一张牌;2.弃置装备区牌数少于你的角色各一张手牌。', - sunlang:'孙狼', - dctingxian:'铤险', - dctingxian_info:'每回合限一次。当你使用【杀】指定最后一个目标后,你可以摸X张牌,然后令此【杀】对其中至多X个目标无效(X为你装备区的牌数+1)。', - dcbenshi:'奔矢', - dcbenshi_info:'锁定技。①你的攻击范围+1。②你的攻击范围基数不受装备区内武器牌的影响。③由你使用的【杀】的牌面信息中的“使用目标”产生的规则改为“攻击范围内的所有角色”。', - sunhuan:'孙桓', - dcniji:'逆击', - dcniji_info:'①当你成为非装备牌的目标后,你可以摸一张牌,称为“逆击”。②一名角色的结束阶段,你可以使用一张“逆击”牌,然后弃置所有“逆击”牌。', + mubing: "募兵", + mubing_info: + "出牌阶段开始时,你可以亮出牌堆顶的三张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。", + ziqu: "资取", + ziqu_info: + "每名角色限一次,当你对有牌的其他角色造成伤害后,你可以防止此伤害。然后其将其点数最大的牌交给你。", + diaoling: "调令", + diaoling_info: + "觉醒技,准备阶段,若你已因〖募兵〗获得了6张或更多的【杀】或武器牌或伤害锦囊牌,则你回复1点体力或摸两张牌,然后修改〖募兵〗。", + mubing_rewrite: "募兵·改", + mubing_rewrite_info: + "出牌阶段开始时,你可以亮出牌堆顶的四张牌。你可弃置任意张手牌,并可获得任意张点数之和不大于你弃置的牌点数之和的牌。然后你可将以此法得到的牌以任意方式交给其他角色。", + caobuxing: "曹不兴", + moying: "墨影", + moying_info: + "每回合限一次,当你于回合外不因使用而失去单一一张锦囊牌或装备牌后,你可以选择一个花色和与此牌点数差绝对值不超过2的点数,然后获得牌堆中所有与此牌花色点数相同的牌。", + juanhui: "绢绘", + juanhui2: "绢绘", + juanhui2_backup: "绢绘", + juanhui_info: + '结束阶段,你可以选择一名其他角色。记录该角色下回合的出牌阶段里使用的基本牌和普通锦囊牌(每种牌名限记一次),你的下回合出牌阶段,可将一张手牌当这些牌里的任意一张牌使用(每张限使用一次,且【杀】不计次数)。当"绢绘"的牌全部用完时,你回复1点体力并将手牌摸至三张。', + re_maliang: "新杀马良", + re_maliang_prefix: "新杀", + rexiemu: "协穆", + rexiemu_info: + "结束阶段,若全场没有“协穆”标记,你可以选择一名角色获得“协穆”标记直到你的下回合开始。你或该角色在各自的回合外使用或打出手牌时,你与其各摸一张牌(每回合限一次)。", + heli: "贺励", + heli_info: + "出牌阶段限一次,你可以选择手牌数比你少的一名其他角色。该角色展示所有手牌,然后每缺少一种类型的牌,便从牌堆中随机获得一张此类型的牌。", + zhujun: "朱儁", + gongjian: "攻坚", + gongjian_info: + "每回合限一次,当有角色使用【杀】指定第一个目标后,若此【杀】的目标和本局游戏内被使用的上一张【杀】的目标的交集A不为空,则你可以依次弃置A中所有角色的至多两张牌,然后获得以此法弃置的所有【杀】。", + kuimang: "溃蟒", + kuimang_info: "锁定技,一名角色死亡后,若你对其造成过伤害,你摸两张牌。", + liuhong: "刘宏", + yujue: "鬻爵", + yujue_backup: "鬻爵", + yujue_info: + "出牌阶段限一次,你可以废除一个装备栏,然后令一名有手牌的其他角色交给你一张手牌。其获得〖执笏〗直到你的下回合开始。", + zhihu: "执笏", + zhihu_mark: "执笏", + zhihu_info: "锁定技,每回合限两次,当你对其他角色造成伤害后,你摸两张牌。", + tuxing: "图兴", + tuxing2: "图兴", + tuxing_info: + "锁定技,当你废除一个装备栏时,你加1点体力上限并回复1点体力。然后若你所有的装备栏均已被废除,则你减4点体力上限,且本局游戏内造成的伤害+1。", + re_hejin: "新杀何进", + re_hejin_prefix: "新杀", + xin_baosanniang: "新杀鲍三娘", + xin_baosanniang_prefix: "新杀", + decadexushen: "许身", + decadexushen2: "许身", + decadexushen_info: + "限定技,当你进入濒死状态后,你可以回复1点体力并获得技能“镇南”,然后如果你脱离濒死状态且“关索”不在场,你可令一名其他角色选择是否用“关索”代替其武将并令其摸三张牌。", + decadezhennan: "镇南", + decadezhennan_info: + "当有角色使用普通锦囊牌指定目标后,若此牌目标数大于1,你可以对一名其他角色造成1点伤害。", + ol_dingyuan: "丁原", + cixiao: "慈孝", + cixiao_info: + "准备阶段,若场上没有“义子”标记,你可令一名其他角色获得一个“义子”标记;若场上有“义子”标记,你可以弃置一张牌移动“义子”标记。拥有“义子”标记的角色获得技能“叛弑”。", + panshi: "叛弑", + panshi_info: + "锁定技,准备阶段,你交给有“慈孝”技能的角色一张手牌;当你于出牌阶段因使用【杀】对其他角色造成伤害时,若其拥有技能“慈孝”,则此伤害+1,且你结束出牌阶段。", + xianshuai: "先率", + xianshuai_info: + "锁定技,有角色造成伤害后,若此伤害是本轮第一次造成伤害:你摸一张牌;若伤害来源是你,则你对受伤角色再造成1点伤害。", + wangrong: "王荣", + minsi: "敏思", + minsi2: "敏思", + minsi_info: + "出牌阶段限一次,你可以弃置任意张点数之和为13的牌,然后摸两倍数量的牌。以此法得到的牌中,黑色牌本回合无距离限制,红色牌本回合不计入手牌上限。", + jijing: "吉境", + jijing_info: + "当你受到伤害后,你可以进行一次判定,然后若你弃置任意张点数之和与判定结果点数相同的牌,你回复1点体力。", + zhuide: "追德", + zhuide_info: "当你死亡时,你可令一名其他角色从牌堆中获得四张名称各不相同的基本牌。", + decadewuniang: "武娘", + decadewuniang_info: + "当你使用或打出【杀】时,你可以获得一名其他角色的一张牌。若如此做,其摸一张牌。(若你已发动许身,则关索也摸一张牌)", + dongxie: "董翓", + juntun: "军屯", + juntun_info: "锁定技,准备阶段,若X大于1,则你减1点体力上限并摸X张牌(X为你的体力上限)。", + jiaojie: "狡黠", + jiaojie_info: "锁定技,你的红色牌不计入手牌上限。你使用黑色牌无距离和次数限制。", + dcjiaoxia: "狡黠", + dcjiaoxia_info: + "①出牌阶段开始时,你可以令自己的所有手牌于此阶段均视为【杀】。若如此做,你使用以此法转化的【杀】造成伤害后,你可以使用此牌对应的原卡牌。②出牌阶段,你对你本阶段未使用过【杀】的角色使用【杀】无距离和次数限制。", + dchumei: "狐魅", + dchumei_info: + "出牌阶段各限一次,你可以选择一名体力值不大于X的角色,令其:①摸一张牌。②交给你一张牌。③回复1点体力。(X为你本阶段造成的伤害数)", + buchen: "不臣", + buchen_info: "隐匿技,你于其他角色的回合登场时,可获得当前回合角色的一张牌。", + smyyingshi: "鹰视", + smyyingshi_info: "锁定技,出牌阶段,你可观看牌堆顶的X张牌(X为你的体力上限)。", + xiongzhi: "雄志", + xiongzhi_info: + "限定技,出牌阶段,你可亮出牌堆顶的一张牌并使用之。若如此做,你重复此流程,直到你以此法展示的牌无法使用。", + quanbian: "权变", + quanbian2: "权变", + quanbian_info: + "当你于出牌阶段内使用/打出手牌时,若此牌有花色且你本回合内未使用/打出过该花色的其他手牌,则你可以选择一项:①摸一张牌。②将牌堆顶X张牌中的一张置于牌堆底(X为你的体力上限)。若你发动此技能,则你本回合内不能再使用与此牌花色相同的手牌。", + re_hansui: "新杀韩遂", + re_hansui_prefix: "新杀", + re_quyi: "新杀麴义", + re_quyi_prefix: "新杀", + refuqi: "伏骑", + refuqi_info: "锁定技,当你使用牌时,你令所有距离为1的其他角色不能使用或打出牌响应此牌。", + hanfu: "韩馥", + hfjieying: "节应", + hfjieying2: "节应", + hfjieying3: "节应", + hfjieying_info: + "结束阶段,你可以选择一名其他角色,该角色下回合使用目标数为1的【杀】或普通锦囊牌无距离限制且可多指定一个目标,且当其造成伤害后,其无法再使用牌直到回合结束。", + weipo: "危迫", + weipo_info: + "锁定技,其他角色使用【杀】或普通锦囊牌指定你为目标后,若你的手牌数小于X,则你将手牌摸至X张,并记录摸牌事件结算后的手牌数Y。此牌结算结束后,若你的手牌数小于Y,则你将一张手牌交给此牌的使用者,且此技能失效直到你的下回合开始。(X为你的体力上限且至多为5)", + zhaozhong: "赵忠", + yangzhong: "殃众", + yangzhong_info: + "当你造成或受到伤害后,若受伤角色和伤害来源均存活,则伤害来源可弃置两张牌,然后令受伤角色失去1点体力。", + huangkong: "惶恐", + huangkong_info: + "锁定技,当你于回合外成为【杀】或普通锦囊牌的目标后,若你没有手牌,则你摸两张牌。", + re_taoqian: "陶谦", + reyixiang: "义襄", + reyixiang_info: + "锁定技,其他角色于其出牌阶段内使用的第一张牌对你的伤害-1;其使用的第二张牌若为黑色,则对你无效。", + caosong: "曹嵩", + cslilu: "礼赂", + cslilu_info: + "摸牌阶段,你可以放弃摸牌,改为将手牌摸至X张(X为你的体力上限和5中的最小值),然后将至少一张手牌交给一名其他角色。若你以此法给出的牌数大于你上次以此法给出的牌数,则你加1点体力上限并回复1点体力。", + csyizheng: "翊正", + csyizheng2: "翊正", + csyizheng_info: + "结束阶段开始时,你可以选择一名其他角色。你的下回合开始前,当该角色造成伤害或回复体力时,若其体力上限小于你,则你减1点体力上限,且令此伤害值/回复值+1。", + reyirang: "揖让", + reyirang_info: + "出牌阶段开始时,你可以将所有非基本牌交给一名其他角色。若其体力上限大于你,则你将体力上限调整至与其相同。然后你回复X点体力(X为你以此法交给其的牌数)。", + liangxing: "梁兴", + lulve: "掳掠", + lulve_info: + "出牌阶段开始时,你可选择一名有手牌且手牌数少于你的角色。其选择一项:①将所有手牌交给你,然后你将武将牌翻面。②将武将牌翻面,然后其视为对你使用一张【杀】。", + lxzhuixi: "追袭", + lxzhuixi_info: + "锁定技,当你造成伤害或受到伤害时,若受伤角色的翻面状态和伤害来源的翻面状态不同,则此伤害+1。", + zhangmiao: "张邈", + mouni: "谋逆", + mouni_info: + "准备阶段,你可对一名其他角色依次使用你手牌中所有的【杀】(若其进入了濒死状态,则终止此流程)。然后若这些【杀】中有未造成伤害的【杀】,则你跳过本回合的出牌阶段和弃牌阶段。", + zongfan: "纵反", + zongfan_info: + "觉醒技。结束阶段,若你本回合内因〖谋逆〗使用过【杀】且未跳过本回合的出牌阶段,则你将任意张牌交给一名其他角色,然后加X点体力上限并回复X点体力(X为你以此法给出的牌数且至多为5)。最后失去〖谋逆〗并获得〖战孤〗。", + zhangu: "战孤", + zhangu_info: + "锁定技,准备阶段,若你的体力上限大于1且没有手牌/装备区内没有牌,则你减1点体力上限,然后从牌堆中获得三张类型不同的牌。", + re_niujin: "新杀牛金", + re_niujin_prefix: "新杀", + recuorui: "摧锐", + recuorui_info: "限定技,出牌阶段,你可以依次获得至多X名角色的各一张手牌(X为你的体力值)。", + reliewei: "裂围", + reliewei_info: + "每回合限Y次,当有角色进入濒死状态时,你可以摸一张牌(Y为你的体力值,若当前回合角色为你,则Y为Infinity)。", + duanwei: "段煨", + langmie: "狼灭", + langmie_damage: "狼灭", + langmie_info: + "其他角色的出牌阶段结束时,若其本阶段内使用过的牌中有类型相同的牌,则你可以摸一张牌;其他角色的结束阶段开始时,若其本回合内造成的伤害大于1,则你可以弃置一张牌并对其造成1点伤害。", + zhangheng: "张横", + dangzai: "挡灾", + dangzai_info: "出牌阶段开始时,你可将一名其他角色判定区内的一张牌移动至你的判定区内。", + liangjue: "粮绝", + liangjue_info: + "锁定技,当有黑色牌进入或者离开你的判定区或装备区后,若你的体力值大于1,你失去1点体力,然后摸两张牌。", + tangji: "唐姬", + kangge: "抗歌", + kangge_info: + "你的第一个回合开始时,选择一名其他角色,该角色每次于其回合外得到牌后,你摸等量的牌(每回合至多摸三张);其进入濒死状态时,你可令其回复体力至1点(每轮限一次)。该角色死亡时,你弃置所有牌并失去1点体力。", + jielie: "节烈", + jielie_info: + "当你受到除自己和“抗歌”角色以外的角色造成的伤害时,你可以防止此伤害并选择一种花色,然后你失去X点体力,令“抗歌”角色从弃牌堆中随机获得X张此花色的牌(X为伤害值)。", + re_dongcheng: "董承", + xuezhao: "血诏", + xuezhao_info: + "出牌阶段限一次,你可弃置一张手牌并选择至多X名其他角色(X为你的体力上限)。这些角色依次选择是否交给你一张牌,若选择是,该角色摸一张牌且你本回合可多使用一张【杀】;若选择否,该角色本回合无法响应你使用的牌。", + re_hucheer: "胡车儿", + redaoji: "盗戟", + redaoji2: "盗戟", + redaoji_info: + "其他角色第一次使用武器牌时,你可选择一项:①获得此牌。②令其本回合内不能使用或打出【杀】。", + fuzhong: "负重", + fuzhong_info: + "锁定技,当你于回合外得到牌后,你获得一枚“重”标记。若X:大于0,你于摸牌阶段开始时令额定摸牌数+1;大于1,你至其他角色的距离-2;大于2,你的手牌上限+3;大于3,结束阶段开始时,你对一名其他角色造成1点伤害,然后移去4枚“重”(X为“重”数)。", + qiuliju: "丘力居", + koulve: "寇略", + koulve_info: + "当你于出牌阶段内对其他角色造成伤害后,你可以展示其X张手牌(X为其已损失的体力值)。若这些牌中:有带有伤害标签的基本牌或锦囊牌,则你获得之;有红色牌,则你失去1点体力(若已受伤则改为减1点体力上限),然后摸两张牌。", + qljsuiren: "随认", + qljsuiren_info: "当你死亡时,你可以将手牌中所有的带有伤害标签的基本牌或锦囊牌交给一名其他角色。", + re_zoushi: "邹氏", + rehuoshui: "祸水", + rehuoshui_info: + "准备阶段,你可以选择至多X名角色(X为你已损失的体力值且至少为1)。你令这些角色中第一名角色的非锁定技失效直到回合结束;第二名角色交给你一张手牌;第三名及之后角色弃置装备区内的所有牌。", + reqingcheng: "倾城", + reqingcheng_info: "出牌阶段限一次,你可以与一名手牌数不大于你的男性角色交换手牌。", + caoanmin: "曹安民", + xianwei: "险卫", + xianwei_info: + "锁定技,准备阶段,你废除一个装备栏并摸X张牌(X为你未废除的装备栏数),然后你可以令一名其他角色对其自己使用一张牌堆中的一张与此装备栏副类别相同的装备牌(没有可使用的牌则改为摸一张牌)。当你废除所有装备栏后,你加2点体力上限,然后你与所有其他角色视为在彼此的攻击范围内。", + dufuren: "杜夫人", + yise: "异色", + yise_info: + "其他角色得到你的牌后,若这些牌中:有红色牌,你可令其回复1点体力;有黑色牌,其下次受到因执行【杀】的效果造成的伤害时,此伤害+1。", + shunshi: "顺世", + shunshi_info: + "准备阶段开始时,或当你受到伤害后,你可将一张牌交给一名不为伤害来源的其他角色并获得如下效果直到你的回合结束:摸牌阶段的额定摸牌数+1,使用【杀】的次数上限+1,手牌上限+1。", + rexingluan: "兴乱", + rexingluan_info: + "出牌阶段限一次,当你使用的仅指定一个目标的牌结算完成后,你可以获得场上一张与此牌点数相同的牌,或获得牌堆中随机一张点数与此牌相同的牌。", + xinxingluan: "兴乱", + xinxingluan_info: + "每回合限一次。当你于出牌阶段内使用牌结算结束后,你可选择一项:①观看牌堆中的两张点数为6的牌并获得其中一张(没有则改为摸六张牌);②令一名其他角色弃置一张点数为6的牌或交给你一张牌;③获得场上的一张点数为6的牌。", + re_nanhualaoxian: "南华老仙", + gongxiu: "共修", + gongxiu_info: + "结束阶段,若你本回合内发动过〖经合〗,则你选择一项:①令所有本回合内成为过〖经合〗目标的角色各摸一张牌;②令所有本回合内未成为过〖经合〗目标的角色各弃置一张手牌。", + jinghe: "经合", + jinghe_info: + "出牌阶段限一次,你可以展示至多四张牌名各不相同的牌并选择等量的角色。系统从“写满技能的天书”中随机选择等量的技能,然后这些角色依次选择获得其中的一个。", + nhyinbing: "阴兵", + nhyinbing_info: "锁定技,你使用的【杀】造成伤害改为失去体力。其他角色失去体力后,你摸一张牌。", + nhhuoqi: "活气", + nhhuoqi_info: + "出牌阶段限一次,你可以弃置一张牌,然后令体力值最少的一名角色回复1点体力并摸一张牌。", + nhguizhu: "鬼助", + nhguizhu_info: "一名角色进入濒死状态时,你可以摸两张牌(每回合限一次)。", + nhxianshou: "仙授", + nhxianshou_info: "出牌阶段限一次,你可以选择一名角色令其摸一张牌。若其未受伤,则多摸一张。", + nhlundao: "论道", + nhlundao_info: + "当你受到伤害后,若伤害来源比你手牌多,你可以弃置其一张牌;若伤害来源比你手牌少,你摸一张牌。", + nhguanyue: "观月", + nhguanyue_info: "结束阶段,你可以观看牌堆顶两张牌,然后获得其中—张,另一张放回牌堆顶。", + nhyanzheng: "言政", + nhyanzheng_info: + "准备阶段,若你的手牌数大于1,你可以保留一张手牌并弃置其余的牌,然后选择至多等于弃牌数量的角色,对这些角色各造成1点伤害。", + sp_mifangfushiren: "糜芳傅士仁", + mffengshi: "锋势", + mffengshi_info: + "当你使用牌指定唯一目标后,或成为其他角色使用牌的唯一目标后,若此牌使用者的手牌数大于此牌目标的手牌数,则此牌的使用者可令你弃置自己和对方的各一张牌,并令此牌的伤害值+1。", + dcmffengshi: "锋势", + dcmffengshi_info: + "当你使用牌指定唯一目标后,或成为其他角色使用牌的唯一目标后,若此牌使用者的手牌数大于此牌目标的手牌数,则你可弃置自己和对方的各一张牌,并令此牌的伤害值+1。", + fengshi: "锋势", + fengshi_info: + "当你使用牌指定第一个目标后,你可弃置你与其中一名手牌数小于你的目标角色的各一张牌,并令此牌对其造成的伤害+1;当你成为其他角色使用牌的目标后,若你的手牌数小于其,则你可以弃置你与其的各一张牌,并令此牌对你造成的伤害+1。", + tongyuan: "童渊", + chaofeng: "朝凤", + chaofeng_info: + "出牌阶段限一次。当你造成伤害时,你可以弃置一张手牌,然后摸一张牌。若此伤害的渠道为牌且你弃置的牌:与此牌颜色相同,则你改为摸两张牌;与此牌类型相同,则此伤害+1。", + chuanshu: "传术", + chuanshu_info: + "限定技。准备阶段,若你已受伤;或当你死亡时,你可令一名其他角色获得〖朝凤〗。然后你获得〖龙胆〗、〖从谏〗和〖穿云〗。", + chuanyun: "穿云", + chuanyun_info: "当你使用【杀】指定目标后,你可令目标角色随机弃置其装备区内的一张牌。", + zhangning: "张宁", + tianze: "天则", + tianze_info: + "①每回合限触发一次。其他角色于其出牌阶段内使用的黑色手牌结算结束后,你可以弃置一张黑色牌,并对其造成1点伤害。②其他角色的判定生效后,若结果为黑色,则你摸一张牌。", + difa: "地法", + difa_info: + "每回合限一次。当你于回合内因摸牌而得到红色牌时,你可以弃置之。然后你选择一个锦囊牌的牌名,并从牌堆中获得一张此牌名的牌。", + xinping: "辛评", + fuyuan: "辅袁", + fuyuan_info: + "当你于回合外使用或打出牌时,若当前回合角色的手牌数:不小于你,你可摸一张牌;小于你,你可令其摸一张牌。", + zhongjie: "忠节", + zhongjie_info: "当你死亡时,你可令一名其他角色加1点体力上限并回复1点体力,然后摸一张牌。", + hanmeng: "韩猛", + jieliang: "截粮", + jieliang_info: + "其他角色的摸牌阶段开始时,你可弃置一张牌,令其本阶段的摸牌数和本回合的手牌上限-1。然后当其于本回合的弃牌阶段内因弃置而失去牌后,你可获得其中的一张。", + quanjiu: "劝酒", + quanjiu_info: + "锁定技。①你手牌区中的【酒】的牌名视为【杀】。②你使用对应的实体牌为一张【酒】的非转化【杀】不计入次数限制。", + re_pangdegong: "庞德公", + heqia: "和洽", + heqia_info: + "出牌阶段开始时,你可选择一项:①将任意张牌交给一名其他角色。②令一名有手牌的其他角色交给你任意张牌。然后以此法得到牌的角色可以将一张手牌当作任意基本牌使用,且当其声明使用此牌后,可以为此牌增加至至多X个目标(X为以此法移动的牌数)。", + yinyi: "隐逸", + yinyi_info: + "锁定技。每回合限一次,当你受到非属性伤害时,若你的手牌数和体力值与伤害来源均不相同,则你防止此伤害。", + haomeng: "郝萌", + xiongmang: "雄莽", + xiongmang_info: + "你可将任意张花色各不相同的手牌当做目标数上限为X的【杀】使用(X为此【杀】对应的实体牌数)。此【杀】使用结算结束后,若你未造成过渠道为此牌的伤害且体力上限大于1,则你减1点体力上限。", + yanfuren: "严夫人", + channi: "谗逆", + channi_info: + "出牌阶段限一次。你可将任意张手牌交给一名其他角色,然后其可以将至多等量的手牌当做【决斗】使用。若其因此【决斗】造成了伤害,则其摸X张牌(X为此【决斗】对应的实体牌数)。若其因此【决斗】受到过伤害,则你弃置所有手牌。", + nifu: "匿伏", + nifu_info: "锁定技。一名角色的回合结束时,你将手牌摸至或弃置至三张。", + licaiwei: "李采薇", + yijiao: "异教", + yijiao_info: + "出牌阶段限一次,你可以选择一名没有“异”标记的其他角色并声明一个整数X(X∈[1,4]),该角色获得10X个“异”标记。有“异”标记的角色的结束阶段,其移去“异”标记,且若其本回合使用牌的点数之和:1.小于“异”标记数,其随机弃置至多三张手牌;2.等于“异”标记数,你摸两张牌且该角色本回合结束后进行一个额外的回合;3.大于“异”标记数,你摸三张牌。", + qibie: "泣别", + qibie_info: + "一名角色死亡后,若你有手牌且这些手牌均可被弃置,则你可以弃置所有手牌,然后回复1点体力并摸X+2张牌(X为你弃置的牌数)。", + dc_zhuling: "朱灵", + dczhanyi: "战意", + dczhanyi_info: + "出牌阶段开始时,你可以弃置所有基本牌/锦囊牌/装备牌,然后获得另外两种类型的牌对应的效果直到你的下个回合开始:基本牌、你使用基本牌无距离限制,且伤害值和回复值基数+1;锦囊牌、你使用锦囊牌时摸一张牌,且锦囊牌不计入手牌上限;装备牌,当装备牌进入你的装备区时,你可弃置一名其他角色的一张牌。", + yanrou: "阎柔", + choutao: "仇讨", + choutao_info: + "当你使用【杀】时,或成为【杀】的目标后,你可以弃置此【杀】使用者的一张牌,令此【杀】不可被响应。若你是此【杀】的使用者,则你令此【杀】不计入次数限制。", + xiangshu: "襄戍", + xiangshu_info: + "限定技。结束阶段开始时,若你本回合内造成过伤害,则你可以选择一名已受伤的角色。该角色回复X点体力并摸X张牌(X为你本回合内造成的伤害值总和且至多为5)。", + qinyilu: "秦宜禄", + piaoping: "漂萍", + piaoping_info: + "转换技,锁定技。当你使用一张牌时,阴:你摸X张牌。阳:你弃置X张牌。(X为你本阶段内发动过〖漂萍〗的次数且至多等于你的体力值)", + tuoxian: "托献", + tuoxian_info: + "每局游戏限一次。当你因执行〖漂萍〗的效果而弃置牌后,你可令一名其他角色获得这些牌,然后令该角色选择一项:⒈弃置区域内等量的牌。⒉令你的〖漂萍〗失效直到回合结束。", + chuaili: "惴栗", + chuaili_info: + "锁定技。当你成为其他角色使用黑色牌的目标后,若你的〖漂萍〗:处于阳状态,则你将〖漂萍〗转换至阴状态;处于阴状态,则你令〖托献〗发动次数+1,然后若〖托献〗发动次数大于3,则〖惴栗〗于本回合内失效。", + fengfang: "冯方", + dcditing: "谛听", + dcditing_info: + "其他角色的出牌阶段开始时,若你在该角色的攻击范围内,则你可以观看其的X张手牌(X为你的体力值)并选择其中一张,且获得如下效果:①当其使用对应实体牌包含此牌的牌指定你为目标后,你令此牌对你无效。②当其使用对应实体牌包含此牌的牌结算结束后,若你不是此牌的目标,则你摸两张牌。③其出牌阶段结束时,若此牌位于其的手牌区,则你获得此牌。", + dcbihuo: "避祸", + dcbihuo_info: + "①当你受到其他角色造成的伤害后,你可令一名角色下回合摸牌阶段的额定摸牌数+1。②当你对其他角色造成伤害后,你可令一名角色下回合摸牌阶段的额定摸牌数-1。", + bianxi: "卞喜", + dunxi: "钝袭", + dunxi_info: + "①当你使用具有伤害标签的牌时,你可以令一名不为你的目标角色获得一枚“钝”。②有“钝”的角色使用基本牌或锦囊牌时,若此牌目标数为1且此时没有角色处于濒死状态,你令其移去一枚“钝”。系统随机选择一名角色,并将此牌的目标改为该角色。若该角色和原目标相同,则其失去1点体力。若其正处于出牌阶段内,则结束此阶段。", + niufu: "牛辅", + dcxiaoxi: "宵袭", + dcxiaoxi_info: + "锁定技。出牌阶段开始时,你声明X并减X点体力上限(X∈[1,2])。然后你选择一名攻击范围内的其他角色并选择一项:⒈获得该角色的X张牌。⒉视为对其使用X张【杀】。", + xiongrao: "熊扰", + xiongrao_info: + "限定技。准备阶段开始时,你可以选择所有其他角色。这些角色本回合内所有不为锁定技、限定技、觉醒技的普通技能失效。然后你将体力上限增加至7点并摸X张牌(X为你以此法增加的体力上限数)。", + dc_huban: "胡班", + dcchongyi: "崇义", + dcchongyi_info: + "①一名角色使用【杀】时,若此牌是其于当前出牌阶段内使用的第一张牌,则你可以令其摸两张牌,且其本回合使用【杀】的次数上限+1。②一名角色的出牌阶段结束时,若其于此阶段内使用的最后一张牌为【杀】,则你可以令其本回合的手牌上限+1,然后你获得此【杀】。", + wangwei: "王威", + dcruizhan: "锐战", + dcruizhan_info: + "其他角色的准备阶段开始时,若其的手牌数不小于其体力值,则你可以和其拼点。若你赢或拼点牌中有【杀】,则你视为对其使用一张【杀】。然后若此【杀】造成了伤害且以上两个条件均被满足,则你获得其一张牌。", + dcshilie: "示烈", + dcshilie_info: + "①出牌阶段限一次。你可以选择一项:⒈回复1点体力,将两张牌置于武将牌上作为“示烈”。若“示烈”牌数大于存活人数,则你将最早的多余牌置入弃牌堆;⒉失去1点体力,获得两张“示烈”牌。(满血则不回血,无牌则不移动)②当你死亡时,你可以将所有“示烈”牌交给一名不为伤害来源的其他角色。", + dc_zhaoyǎn: "赵俨", + dcfuning: "抚宁", + dcfuning_info: + "当你使用牌时,你可以摸两张牌,然后弃置X张牌(X为你本回合内发动过〖抚宁〗的次数)。", + dcbingji: "秉纪", + dcbingji_info: + "出牌阶段每种花色各限一次。若你有手牌且这些牌的花色均相同,则你可以展示手牌,然后选择一名其他角色,视为对其使用一张【杀】或【桃】(有距离限制)。", + mushun: "穆顺", + dcjinjian: "劲坚", + dcjinjian_info: + "①当你受到其他角色造成的伤害后或造成伤害后,你获得一枚“劲”。然后你可以和伤害来源拼点,若你赢,你恢复1点体力。②你的攻击范围+X(X为“劲”数)。", + dcshizhao: "失诏", + dcshizhao_info: + "锁定技。每回合限一次,当你于回合外失去手牌后,若你没有手牌,且你:有“劲”,则你移去一枚“劲”并摸两张牌;没有“劲”,则你本回合下一次受到的伤害+1。", + liyixiejing: "李异谢旌", + dcdouzhen: "斗阵", + dcdouzhen_info: + "锁定技。①转换技。你的回合内,阴:当你使用非转化且对应的实体牌为一张黑色基本牌的【决斗】时,你获得目标角色各一张牌并获得1枚“☯”;阳:当你使用或打出非转化且对应的实体牌为一张红色基本牌的【杀】时,你获得1枚“☯”。②若你的“☯”数为:偶数,你的黑色基本牌均视为【决斗】;奇数,你的红色基本牌均视为无次数限制的普【杀】。", + dc_hujinding: "新杀胡金定", + dc_hujinding_prefix: "新杀", + dcdeshi: "德释", + dcdeshi_info: + "锁定技。当你受到【杀】的伤害时,若你已受伤,则你防止此伤害并令系统从弃牌堆/牌堆中检索一张【杀】,你获得此【杀】,然后减1点体力上限。", + dcwuyuan: "武缘", + dcwuyuan_info: + "出牌阶段限一次。你可将一张【杀】交给一名其他角色,然后你回复1点体力,你与其各摸一张牌。若此【杀】为:红色【杀】,其回复1点体力;属性【杀】,其改为摸两张牌。", + shiyi: "是仪", + dccuichuan: "榱椽", + dccuichuan_info: + "出牌阶段限一次。你可以弃置一张手牌并选择一名角色,其随机使用牌堆里一张其空置装备栏对应副类别且其能对其使用的装备牌,你摸X张牌(X为其装备区里的牌数)。然后若其装备区里的牌数增加至四张,你失去〖榱椽〗,获得〖佐谏〗,且令其获得一个额外回合。", + dczhengxu: "正序", + dczhengxu_info: + "每回合每项限一次。①当你受到伤害时,若你本回合失去过牌,你可以防止此伤害。②当你失去牌后,若你本回合受到过伤害,你可以摸等量的牌。", + dczuojian: "佐谏", + dczuojian_info: + "出牌阶段结束时,若你于此阶段使用过的牌数不小于体力值,你可以选择一项:1.令装备区牌数多于你的角色各摸一张牌;2.弃置装备区牌数少于你的角色各一张手牌。", + sunlang: "孙狼", + dctingxian: "铤险", + dctingxian_info: + "每回合限一次。当你使用【杀】指定最后一个目标后,你可以摸X张牌,然后令此【杀】对其中至多X个目标无效(X为你装备区的牌数+1)。", + dcbenshi: "奔矢", + dcbenshi_info: + "锁定技。①你的攻击范围+1。②你的攻击范围基数不受装备区内武器牌的影响。③由你使用的【杀】的牌面信息中的“使用目标”产生的规则改为“攻击范围内的所有角色”。", + sunhuan: "孙桓", + dcniji: "逆击", + dcniji_info: + "①当你成为非装备牌的目标后,你可以摸一张牌,称为“逆击”。②一名角色的结束阶段,你可以使用一张“逆击”牌,然后弃置所有“逆击”牌。", //dc_fuwan:'新杀伏完', //dc_fuwan_prefix:'新杀', //dc_fuwan_ab:'伏完', - dcmoukui:'谋溃', - dcmoukui_info:'当你使用【杀】指定第一个目标后,你可以选择任意项:1.摸一张牌;2.弃置其中一个目标角色一张牌。若你均选择,当此【杀】被无效后或被抵消后,该角色弃置你一张牌。', - guānning:'关宁', - dcxiuwen:'修文', - dcxiuwen_info:'当你使用牌时,若你未记录此牌牌名,你可以记录之并摸一张牌。', - oldlongsong:'龙诵', - oldlongsong_info:'出牌阶段开始时,你可以将一张手牌交给一名其他角色。然后其须选择其所有的发动时机为出牌阶段内的空闲时间点且你至多能于此阶段发动一次的技能,其于此阶段这些技能失效,你获得这些技能。', - dclongsong:'龙诵', - dclongsong_info:'出牌阶段开始时,你可以将一张红色牌交给一名其他角色。然后其须选择其所有的发动时机包含“出牌阶段”的技能,其于此阶段这些技能失效,你获得这些技能且至多可以发动一次。', - dc_mengda:'孟达', - dclibang:'利傍', - dclibang_info:'出牌阶段限一次。你可以弃置一张牌,正面向上获得两名其他角色的各一张牌。然后你判定,若结果与这两张牌的颜色均不同,你交给其中一名角色两张牌或失去1点体力,否则你获得判定牌并视为对其中一名角色使用一张【杀】。', - dcwujie:'无节', - dcwujie_info:'锁定技。①你使用无色牌无任何次数限制且无距离限制。②当其他角色执行杀死你的奖惩而摸牌或弃牌时,取消之。', - dc_jsp_guanyu:'新杀SP关羽', - dc_jsp_guanyu_prefix:'新杀SP', - dcdanji:'单骑', - dcdanji_info:'觉醒技。准备阶段,若你的手牌数大于体力值,你减1点体力上限,将体力回复至体力上限,然后获得〖马术〗和〖怒嗔〗。', - dcnuchen:'怒嗔', - dcnuchen_info:'出牌阶段限一次。你可以展示一名其他角色的一张手牌,然后选择一项:1.弃置任意张该花色的牌,对其造成等量伤害;2.获得该角色手牌中所有此花色的牌。', - dc_jikang:'新杀嵇康', - dc_jikang_prefix:'新杀', - dcjuexiang:'绝响', - dcjuexiang_info:'当你死亡时,杀死你的角色弃置其装备区内的所有牌并失去1点体力,然后你可以令一名其他角色获得〖残韵〗。', - dccanyun:'残韵', - dccanyun_info:'每名角色限一次。出牌阶段,你可以弃置一张牌并选择一名其他角色,然后若其装备区里的牌数:小于你,其回复1点体力;大于你,其失去1点体力;等于你,其摸一张牌。若你的体力值为1,你摸一张牌。', - mp_liuling:'刘伶', - mpjiusong:'酒颂', - mpjiusong_info:'①你可以将一张锦囊牌当【酒】使用。②当一名角色使用【酒】时,你获得1枚“醉”标记(“醉”数至多为3)。', - mpmaotao:'酕醄', - mpmaotao_info:'当其他角色使用基本牌或普通锦囊牌指定唯一目标时,你可以移去1枚“醉”,令此牌的目标改为随机一名合法角色(无距离限制)。若目标角色与原目标相同且你本回合未以此法获得过牌,你从牌堆中随机获得一张锦囊牌。', - mpbishi:'避世', - mpbishi_info:'锁定技。你不能成为伤害类锦囊牌的目标。', - star_caoren:'星曹仁', - star_caoren_prefix:'星', - starsujun:'肃军', - starsujun_info:'当你使用一张牌时,若你手牌中的基本牌和非基本牌的牌数相等,你可以摸两张牌。', - starlifeng:'砺锋', - starlifeng_info:'你可以将一张本回合未有角色使用过的颜色的手牌当做不计入次数的【杀】或【无懈可击】使用。', - star_yuanshu:'星袁术', - star_yuanshu_prefix:'星', - starcanxi:'残玺', - starcanxi_wangsheng:'妄生', - starcanxi_xiangsi:'向死', - starcanxi_cancel:'向死', - starcanxi_info:'锁定技。①游戏开始时,你获得场上所有角色的势力对应的“玺角”标记。②一轮游戏开始时,你选择一个“玺角”对应势力并选择以下一项:1.妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;2.向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。', - starpizhi:'圮秩', - starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记且你本轮发动〖向死〗的势力与其相同,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)', - starzhonggu:'冢骨', - starzhonggu_info:'主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。', - star_dongzhuo:'星董卓', - star_dongzhuo_prefix:'星', - starweilin:'威临', - starweilin_info:'锁定技。当你于回合内对一名其他角色造成伤害时,若其本回合未受到过伤害,且你本回合使用的牌数大于等于其体力值,则此伤害+1。', - starzhangrong:'掌戎', - starzhangrong_info:'准备阶段,你可以选择令至多X名体力值大于等于你的角色各失去1点体力或令至多X名手牌数大于等于你的角色各弃置一张手牌(X为你的体力值)。若如此做,你摸等同于选择角色数的牌,且本回合结束时,若这些角色中存在本回合未受到过伤害的角色,则你失去1点体力。', - starhaoshou:'豪首', + dcmoukui: "谋溃", + dcmoukui_info: + "当你使用【杀】指定第一个目标后,你可以选择任意项:1.摸一张牌;2.弃置其中一个目标角色一张牌。若你均选择,当此【杀】被无效后或被抵消后,该角色弃置你一张牌。", + guānning: "关宁", + dcxiuwen: "修文", + dcxiuwen_info: "当你使用牌时,若你未记录此牌牌名,你可以记录之并摸一张牌。", + oldlongsong: "龙诵", + oldlongsong_info: + "出牌阶段开始时,你可以将一张手牌交给一名其他角色。然后其须选择其所有的发动时机为出牌阶段内的空闲时间点且你至多能于此阶段发动一次的技能,其于此阶段这些技能失效,你获得这些技能。", + dclongsong: "龙诵", + dclongsong_info: + "出牌阶段开始时,你可以将一张红色牌交给一名其他角色。然后其须选择其所有的发动时机包含“出牌阶段”的技能,其于此阶段这些技能失效,你获得这些技能且至多可以发动一次。", + longsong: "龙诵", + longsong_info: + "出牌阶段开始时,你可以获得一名其他角色的一张红色牌,然后你本阶段视为拥有其所有的发动时机包含“出牌阶段”的技能。", + dc_mengda: "孟达", + dclibang: "利傍", + dclibang_info: + "出牌阶段限一次。你可以弃置一张牌,正面向上获得两名其他角色的各一张牌。然后你判定,若结果与这两张牌的颜色均不同,你交给其中一名角色两张牌或失去1点体力,否则你获得判定牌并视为对其中一名角色使用一张【杀】。", + dcwujie: "无节", + dcwujie_info: + "锁定技。①你使用无色牌无任何次数限制且无距离限制。②当其他角色执行杀死你的奖惩而摸牌或弃牌时,取消之。", + dc_jsp_guanyu: "新杀SP关羽", + dc_jsp_guanyu_prefix: "新杀SP", + dcdanji: "单骑", + dcdanji_info: + "觉醒技。准备阶段,若你的手牌数大于体力值,你减1点体力上限,将体力回复至体力上限,然后获得〖马术〗和〖怒嗔〗。", + dcnuchen: "怒嗔", + dcnuchen_info: + "出牌阶段限一次。你可以展示一名其他角色的一张手牌,然后选择一项:1.弃置任意张该花色的牌,对其造成等量伤害;2.获得该角色手牌中所有此花色的牌。", + dc_jikang: "新杀嵇康", + dc_jikang_prefix: "新杀", + dcjuexiang: "绝响", + dcjuexiang_info: + "当你死亡时,杀死你的角色弃置其装备区内的所有牌并失去1点体力,然后你可以令一名其他角色获得〖残韵〗。", + dccanyun: "残韵", + dccanyun_info: + "每名角色限一次。出牌阶段,你可以弃置一张牌并选择一名其他角色,然后若其装备区里的牌数:小于你,其回复1点体力;大于你,其失去1点体力;等于你,其摸一张牌。若你的体力值为1,你摸一张牌。", + mp_liuling: "刘伶", + mpjiusong: "酒颂", + mpjiusong_info: + "①你可以将一张锦囊牌当【酒】使用。②当一名角色使用【酒】时,你获得1枚“醉”标记(“醉”数至多为3)。", + mpmaotao: "酕醄", + mpmaotao_info: + "当其他角色使用基本牌或普通锦囊牌指定唯一目标时,你可以移去1枚“醉”,令此牌的目标改为随机一名合法角色(无距离限制)。若目标角色与原目标相同且你本回合未以此法获得过牌,你从牌堆中随机获得一张锦囊牌。", + mpbishi: "避世", + mpbishi_info: "锁定技。你不能成为伤害类锦囊牌的目标。", + star_caoren: "星曹仁", + star_caoren_prefix: "星", + starsujun: "肃军", + starsujun_info: "当你使用一张牌时,若你手牌中的基本牌和非基本牌的牌数相等,你可以摸两张牌。", + starlifeng: "砺锋", + starlifeng_info: + "你可以将一张本回合未有角色使用过的颜色的手牌当做不计入次数的【杀】或【无懈可击】使用。", + star_yuanshu: "星袁术", + star_yuanshu_prefix: "星", + starcanxi: "残玺", + starcanxi_wangsheng: "妄生", + starcanxi_xiangsi: "向死", + starcanxi_cancel: "向死", + starcanxi_info: + "锁定技。①游戏开始时,你获得场上所有角色的势力对应的“玺角”标记。②一轮游戏开始时,你选择一个“玺角”对应势力并选择以下一项:1.妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;2.向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。", + starpizhi: "圮秩", + starpizhi_info: + "锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记且你本轮发动〖向死〗的势力与其相同,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)", + starzhonggu: "冢骨", + starzhonggu_info: + "主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。", + star_dongzhuo: "星董卓", + star_dongzhuo_prefix: "星", + starweilin: "威临", + starweilin_info: + "锁定技。当你于回合内对一名其他角色造成伤害时,若其本回合未受到过伤害,且你本回合使用的牌数大于等于其体力值,则此伤害+1。", + starzhangrong: "掌戎", + starzhangrong_info: + "准备阶段,你可以选择令至多X名体力值大于等于你的角色各失去1点体力或令至多X名手牌数大于等于你的角色各弃置一张手牌(X为你的体力值)。若如此做,你摸等同于选择角色数的牌,且本回合结束时,若这些角色中存在本回合未受到过伤害的角色,则你失去1点体力。", + starhaoshou: "豪首", //starhaoshou_info:'主公技。①其他群势力角色使用【酒】结算完毕后,其可以令你回复1点体力。②当你处于濒死状态时,其他群势力角色可以将【酒】当作【桃】对你使用。', - starhaoshou_info:'主公技。其他群势力角色使用【酒】结算完毕后,其可以令你回复1点体力。', - star_yuanshao:'星袁绍', - star_yuanshao_prefix:'星', - starxiaoyan:'硝焰', - starxiaoyan_info:'锁定技,游戏开始时,你对所有其他角色各造成1点火属性伤害,然后这些角色可依次交给你一张牌并回复1点体力。', - starzongshi:'纵势', - starzongshi_info:'出牌阶段,你可以展示一张可展示目标的基本牌或普通锦囊牌,然后你将手牌中所有与此牌花色相同的其他牌当作此牌使用(无距离限制),且此牌至多指定转化牌数的目标。', - starjiaowang:'骄妄', - starjiaowang_info:'锁定技,非首轮游戏开始时,若上一轮没有角色死亡(因〖硝焰〗死亡的角色除外),则你失去1点体力并发动〖硝焰〗。', - staraoshi:'傲势', - staraoshi_info:'主公技,其他群势力角色的出牌阶段限一次,其可以交给你一张手牌,然后你可以发动一次〖纵势〗。', - star_zhangchunhua:'星张春华', - star_zhangchunhua_prefix:'星', - starliangyan:'梁燕', - starliangyan_info:'出牌阶段限一次。你可以选择一名其他角色,你摸/弃置至多两张牌,令其弃置/摸等量的牌。然后若你与其手牌数相同,以此法摸牌的角色跳过其下一个弃牌阶段。', - starminghui:'明慧', - starminghui_info:'一名角色的回合结束时,若你的手牌数:最少,你可以视为使用一张无距离限制的【杀】;最多,你可以将手牌弃置至你手牌数不为最多,然后令一名角色回复1点体力。', - liqueguosi:'李傕郭汜', - xiongsuan:'凶算', - xiongsuan_info:'出牌阶段限一次,你可以弃置一张手牌并对一名角色造成1点伤害,然后你摸三张牌。若该角色不为你,你失去1点体力。', + starhaoshou_info: "主公技。其他群势力角色使用【酒】结算完毕后,其可以令你回复1点体力。", + star_yuanshao: "星袁绍", + star_yuanshao_prefix: "星", + starxiaoyan: "硝焰", + starxiaoyan_info: + "锁定技,游戏开始时,你对所有其他角色各造成1点火属性伤害,然后这些角色可依次交给你一张牌并回复1点体力。", + starzongshi: "纵势", + starzongshi_info: + "出牌阶段,你可以展示一张可展示目标的基本牌或普通锦囊牌,然后你将手牌中所有与此牌花色相同的其他牌当作此牌使用(无距离限制),且此牌至多指定转化牌数的目标。", + starjiaowang: "骄妄", + starjiaowang_info: + "锁定技,非首轮游戏开始时,若上一轮没有角色死亡(因〖硝焰〗死亡的角色除外),则你失去1点体力并发动〖硝焰〗。", + staraoshi: "傲势", + staraoshi_info: + "主公技,其他群势力角色的出牌阶段限一次,其可以交给你一张手牌,然后你可以发动一次〖纵势〗。", + star_zhangchunhua: "星张春华", + star_zhangchunhua_prefix: "星", + starliangyan: "梁燕", + starliangyan_info: + "出牌阶段限一次。你可以选择一名其他角色,你摸/弃置至多两张牌,令其弃置/摸等量的牌。然后若你与其手牌数相同,以此法摸牌的角色跳过其下一个弃牌阶段。", + starminghui: "明慧", + starminghui_info: + "一名角色的回合结束时,若你的手牌数:最少,你可以视为使用一张无距离限制的【杀】;最多,你可以将手牌弃置至你手牌数不为最多,然后令一名角色回复1点体力。", + liqueguosi: "李傕郭汜", + xiongsuan: "凶算", + xiongsuan_info: + "出牌阶段限一次,你可以弃置一张手牌并对一名角色造成1点伤害,然后你摸三张牌。若该角色不为你,你失去1点体力。", - sp_whlw:"文和乱武", - sp_zlzy:"逐鹿中原", - sp_longzhou:"同舟共济", - sp_zizouqi:"自走棋", - sp_sbfm:'上兵伐谋', - sp_shengun:'三国奇人传', - sp_guandu:'官渡之战', - sp_huangjin:'列传·黄巾之乱', - sp_fadong:'列传·诸侯伐董', - sp_xuzhou:'列传·徐州风云', - sp_qihuan:'戚宦之争', - sp_zhongyuan:'列传·中原狼烟', - sp_binglin:'兵临城下', - sp_xiaohu:'列传·虓虎悲歌', - sp_fenghuo:'烽火连天', - sp_danqi:'千里单骑', - sp_star:'将星系列', - mini_qixian:'小程序·竹林七贤', - sp2_waitforsort:'等待分包', + sp_whlw: "文和乱武", + sp_zlzy: "逐鹿中原", + sp_longzhou: "同舟共济", + sp_zizouqi: "自走棋", + sp_sbfm: "上兵伐谋", + sp_shengun: "三国奇人传", + sp_guandu: "官渡之战", + sp_huangjin: "列传·黄巾之乱", + sp_fadong: "列传·诸侯伐董", + sp_xuzhou: "列传·徐州风云", + sp_qihuan: "戚宦之争", + sp_zhongyuan: "列传·中原狼烟", + sp_binglin: "兵临城下", + sp_xiaohu: "列传·虓虎悲歌", + sp_fenghuo: "烽火连天", + sp_danqi: "千里单骑", + sp_star: "将星系列", + mini_qixian: "小程序·竹林七贤", + sp2_waitforsort: "等待分包", + }, + pinyins: { + 卑弥呼: ["Himiko"], }, - pinyins:{ - 卑弥呼:['Himiko'] - } }; }); diff --git a/character/standard.js b/character/standard.js index 7b312ba4a..6f2226595 100755 --- a/character/standard.js +++ b/character/standard.js @@ -1,2548 +1,2927 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'standard', - connect:true, - characterSort:{ - standard:{ - standard_2008:["caocao","simayi","xiahoudun","zhangliao","xuzhu","guojia","zhenji","liubei","guanyu","zhangfei","zhugeliang","zhaoyun","machao","huangyueying","sunquan","ganning","lvmeng","huanggai","zhouyu","daqiao","luxun","sunshangxiang","huatuo","lvbu","diaochan"], - standard_2013:['old_re_lidian',"huaxiong","re_yuanshu"], - standard_2019:["gongsunzan","xf_yiji"], - standard_2023:["std_panfeng",'ganfuren'], + name: "standard", + connect: true, + characterSort: { + standard: { + standard_2008: [ + "caocao", + "simayi", + "xiahoudun", + "zhangliao", + "xuzhu", + "guojia", + "zhenji", + "liubei", + "guanyu", + "zhangfei", + "zhugeliang", + "zhaoyun", + "machao", + "huangyueying", + "sunquan", + "ganning", + "lvmeng", + "huanggai", + "zhouyu", + "daqiao", + "luxun", + "sunshangxiang", + "huatuo", + "lvbu", + "diaochan", + ], + standard_2013: ["old_re_lidian", "huaxiong", "re_yuanshu"], + standard_2019: ["gongsunzan", "xf_yiji"], + standard_2023: ["std_panfeng", "ganfuren"], }, }, - character:{ - old_re_lidian:['male','wei',3,['xunxun','wangxi'],['die_audio:lidian']], - ganfuren:['female','shu',3,['stdshushen','shenzhi']], - std_panfeng:['male','qun',4,['stdkuangfu']], - caocao:['male','wei',4,['jianxiong','hujia'],['zhu']], - simayi:['male','wei',3,['fankui','guicai']], - xiahoudun:['male','wei',4,['ganglie']], - zhangliao:['male','wei',4,['tuxi']], - xuzhu:['male','wei',4,['luoyi']], - guojia:['male','wei',3,['tiandu','yiji']], - zhenji:['female','wei',3,['luoshen','qingguo']], - liubei:['male','shu',4,['rende','jijiang'],['zhu']], - guanyu:['male','shu',4,['wusheng']], - zhangfei:['male','shu',4,['paoxiao']], - zhugeliang:['male','shu',3,['guanxing','kongcheng']], - zhaoyun:['male','shu',4,['longdan']], - machao:['male','shu',4,['mashu','tieji']], - huangyueying:['female','shu',3,['jizhi','qicai']], - sunquan:['male','wu',4,['zhiheng','jiuyuan'],['zhu']], - ganning:['male','wu',4,['qixi']], - lvmeng:['male','wu',4,['keji']], - huanggai:['male','wu',4,['kurou']], - zhouyu:['male','wu',3,['yingzi','fanjian']], - daqiao:['female','wu',3,['guose','liuli']], - luxun:['male','wu',3,['qianxun','lianying']], - sunshangxiang:['female','wu',3,['xiaoji','jieyin']], - huatuo:['male','qun',3,['qingnang','jijiu']], - lvbu:['male','qun',4,['wushuang']], - diaochan:['female','qun',3,['lijian','biyue']], - huaxiong:['male','qun',6,['yaowu']], - gongsunzan:['male','qun',4,['reyicong']], + character: { + old_re_lidian: ["male", "wei", 3, ["xunxun", "wangxi"], ["die_audio:lidian"]], + ganfuren: ["female", "shu", 3, ["stdshushen", "shenzhi"]], + std_panfeng: ["male", "qun", 4, ["stdkuangfu"]], + caocao: ["male", "wei", 4, ["jianxiong", "hujia"], ["zhu"]], + simayi: ["male", "wei", 3, ["fankui", "guicai"]], + xiahoudun: ["male", "wei", 4, ["ganglie"]], + zhangliao: ["male", "wei", 4, ["tuxi"]], + xuzhu: ["male", "wei", 4, ["luoyi"]], + guojia: ["male", "wei", 3, ["tiandu", "yiji"]], + zhenji: ["female", "wei", 3, ["luoshen", "qingguo"]], + liubei: ["male", "shu", 4, ["rende", "jijiang"], ["zhu"]], + guanyu: ["male", "shu", 4, ["wusheng"]], + zhangfei: ["male", "shu", 4, ["paoxiao"]], + zhugeliang: ["male", "shu", 3, ["guanxing", "kongcheng"]], + zhaoyun: ["male", "shu", 4, ["longdan"]], + machao: ["male", "shu", 4, ["mashu", "tieji"]], + huangyueying: ["female", "shu", 3, ["jizhi", "qicai"]], + sunquan: ["male", "wu", 4, ["zhiheng", "jiuyuan"], ["zhu"]], + ganning: ["male", "wu", 4, ["qixi"]], + lvmeng: ["male", "wu", 4, ["keji"]], + huanggai: ["male", "wu", 4, ["kurou"]], + zhouyu: ["male", "wu", 3, ["yingzi", "fanjian"]], + daqiao: ["female", "wu", 3, ["guose", "liuli"]], + luxun: ["male", "wu", 3, ["qianxun", "lianying"]], + sunshangxiang: ["female", "wu", 3, ["xiaoji", "jieyin"]], + huatuo: ["male", "qun", 3, ["qingnang", "jijiu"]], + lvbu: ["male", "qun", 4, ["wushuang"]], + diaochan: ["female", "qun", 3, ["lijian", "biyue"]], + huaxiong: ["male", "qun", 6, ["yaowu"]], + gongsunzan: ["male", "qun", 4, ["reyicong"]], - xf_yiji:["male","shu",3,["xinfu_jijie","xinfu_jiyuan"],[]], - re_yuanshu:['male','qun',4,['rewangzun','retongji']], + xf_yiji: ["male", "shu", 3, ["xinfu_jijie", "xinfu_jiyuan"], []], + re_yuanshu: ["male", "qun", 4, ["rewangzun", "retongji"]], }, - characterIntro:{ - liubei:'先主姓刘,讳备,字玄德,涿郡涿县人,汉景帝子中山靖王胜之后也。以仁德治天下。', - guanyu:'字云长,本字长生,并州河东解州人。五虎上将之首,爵至汉寿亭侯,谥曰“壮缪侯”。被奉为“关圣帝君”,崇为“武圣”。', - zhangfei:'字翼德,涿郡人,燕颔虎须,豹头环眼。有诗云:“长坂坡头杀气生,横枪立马眼圆睁。一声好似轰雷震,独退曹家百万兵”。', - zhugeliang:'字孔明,号卧龙,琅琊阳都人,蜀汉丞相。在世时被封为武乡侯,谥曰忠武侯。著有《出师表》、《诫子书》等。怀不世之才,以空城戏司马,能观星象而通鬼神。', - zhaoyun:'字子龙,常山真定人。身长八尺,姿颜雄伟。长坂坡单骑救阿斗,先主云:“子龙一身都是胆也。”', - machao:'字孟起,扶风茂陵人。面如冠玉,目如流星,虎体猿臂,彪腹狼腰,声雄力猛。因衣着讲究,举止非凡,故人称“锦马超”。麾铁骑,捻金枪。', - huangyueying:'荆州沔南白水人,沔阳名士黄承彦之女,诸葛亮之妻,诸葛瞻之母。容貌甚丑,而有奇才:上通天文,下察地理,韬略近于诸书无所不晓,诸葛亮在南阳闻其贤而迎娶。', - sunquan:'吴大帝,字仲谋,吴郡富春县人。统领吴与蜀魏三足鼎立,制衡天下。', - ganning:'字兴霸,巴郡临江人,祖籍荆州南阳郡。为人勇猛刚强,忠心耿耿,勇往无前。曾带兵百人于二更奇袭曹营,大挫其锐气。', - lvmeng:'字子明,汝南富陂人。陈寿评曰:“吕蒙勇而有谋断,识军计,谲郝普,擒关羽,最其妙者。初虽轻果妄杀,终于克己,有国士之量,岂徒武将而已乎!”', - huanggai:'字公覆,零陵郡泉陵县人。官至偏将军、武陵太守。以苦肉计骗曹孟德,亲往诈降,火烧战船,重创敌军。', - zhouyu:'字公瑾,庐江舒县人,任东吴三军大都督,雄姿英发,人称“美周郎”。赤壁之战前,巧用反间计杀了精通水战的叛将蔡瑁、张允。', - daqiao:'庐江皖县人,为乔公长女,孙策之妻,小乔之姊。与小乔并称为“江东二乔”,容貌国色流离。', - luxun:'本名陆议,字伯言,吴郡吴县人。历任东吴大都督、丞相。吴大帝孙权兄孙策之婿,世代为江东大族。以谦逊之书麻痹关羽,夺取荆州,又有火烧连营大破蜀军。', - sunshangxiang:'孙夫人,乃孙权之妹。刘备定荆州,孙权进妹与其结姻,重固盟好。孙夫人才捷刚猛,有诸兄之风。后人为其立庙,号曰“枭姬庙”。', - caocao:'魏武帝曹操,字孟德,小名阿瞒、吉利,沛国谯人。精兵法,善诗歌,乃治世之能臣,乱世之奸雄也。', - simayi:'晋宣帝,字仲达,河内温人。曾任职过曹魏的大都督,太尉,太傅。少有奇节,聪明多大略,博学洽闻,伏膺儒教,世之鬼才也。', - xiahoudun:'字元让,沛国谯人。有拔矢啖睛之勇,性格勇猛刚烈。', - zhangliao:'字文远,魏雁门马邑人。官至前将军、征东将军、晋阳侯。武功高强,又谋略过人,多次建立奇功,以800人突袭孙权十万大军,皆望风披靡。', - xuzhu:'字仲康,谯国谯县人。和典韦一同统率着曹操的亲卫队“虎卫军”。因为他十分勇猛,所以有“虎痴”的绰号。曾有裸衣斗马超之举。', - guojia:'字奉孝,颍川阳翟人,官至军师祭酒。惜天妒英才,英年早逝。有诗云:“良计环环不遗策,每临制变满座惊”。', - zhenji:'中山无极人,别称甄洛或甄宓,庙号文昭甄皇后。魏文帝曹丕的正室。懂诗文,有倾国倾城之貌,《洛神赋》即是曹植为她所作。', - huatuo:'字元化,一名旉,沛国谯人,“建安三神医”之一。集平生之所得著《青囊经》,现已失传。', - lvbu:'字奉先,五原郡九原县人。三国第一猛将,曾独力战刘关张三人,其武力世之无双。时人语曰:“人中有吕布,马中有赤兔。”', - diaochan:'中国古代四大美女之一,有闭月羞花之貌。司徒王允之义女,由王允授意施行连环计,离间董卓、吕布,借布手除卓。后貂蝉成为吕布的妾。', - huaxiong:'董卓旗下名将,自荐抵抗山东地区反对董卓的诸侯联军于汜水关前,他先后斩杀济北相鲍信之弟鲍忠和孙坚部将祖茂、以及袁术部将俞涉和韩馥手下潘凤等人,最后关东联军派出关羽与之一对一决斗而被杀。', + characterIntro: { + liubei: "先主姓刘,讳备,字玄德,涿郡涿县人,汉景帝子中山靖王胜之后也。以仁德治天下。", + guanyu: "字云长,本字长生,并州河东解州人。五虎上将之首,爵至汉寿亭侯,谥曰“壮缪侯”。被奉为“关圣帝君”,崇为“武圣”。", + zhangfei: + "字翼德,涿郡人,燕颔虎须,豹头环眼。有诗云:“长坂坡头杀气生,横枪立马眼圆睁。一声好似轰雷震,独退曹家百万兵”。", + zhugeliang: + "字孔明,号卧龙,琅琊阳都人,蜀汉丞相。在世时被封为武乡侯,谥曰忠武侯。著有《出师表》、《诫子书》等。怀不世之才,以空城戏司马,能观星象而通鬼神。", + zhaoyun: "字子龙,常山真定人。身长八尺,姿颜雄伟。长坂坡单骑救阿斗,先主云:“子龙一身都是胆也。”", + machao: "字孟起,扶风茂陵人。面如冠玉,目如流星,虎体猿臂,彪腹狼腰,声雄力猛。因衣着讲究,举止非凡,故人称“锦马超”。麾铁骑,捻金枪。", + huangyueying: + "荆州沔南白水人,沔阳名士黄承彦之女,诸葛亮之妻,诸葛瞻之母。容貌甚丑,而有奇才:上通天文,下察地理,韬略近于诸书无所不晓,诸葛亮在南阳闻其贤而迎娶。", + sunquan: "吴大帝,字仲谋,吴郡富春县人。统领吴与蜀魏三足鼎立,制衡天下。", + ganning: + "字兴霸,巴郡临江人,祖籍荆州南阳郡。为人勇猛刚强,忠心耿耿,勇往无前。曾带兵百人于二更奇袭曹营,大挫其锐气。", + lvmeng: "字子明,汝南富陂人。陈寿评曰:“吕蒙勇而有谋断,识军计,谲郝普,擒关羽,最其妙者。初虽轻果妄杀,终于克己,有国士之量,岂徒武将而已乎!”", + huanggai: + "字公覆,零陵郡泉陵县人。官至偏将军、武陵太守。以苦肉计骗曹孟德,亲往诈降,火烧战船,重创敌军。", + zhouyu: "字公瑾,庐江舒县人,任东吴三军大都督,雄姿英发,人称“美周郎”。赤壁之战前,巧用反间计杀了精通水战的叛将蔡瑁、张允。", + daqiao: "庐江皖县人,为乔公长女,孙策之妻,小乔之姊。与小乔并称为“江东二乔”,容貌国色流离。", + luxun: "本名陆议,字伯言,吴郡吴县人。历任东吴大都督、丞相。吴大帝孙权兄孙策之婿,世代为江东大族。以谦逊之书麻痹关羽,夺取荆州,又有火烧连营大破蜀军。", + sunshangxiang: + "孙夫人,乃孙权之妹。刘备定荆州,孙权进妹与其结姻,重固盟好。孙夫人才捷刚猛,有诸兄之风。后人为其立庙,号曰“枭姬庙”。", + caocao: "魏武帝曹操,字孟德,小名阿瞒、吉利,沛国谯人。精兵法,善诗歌,乃治世之能臣,乱世之奸雄也。", + simayi: "晋宣帝,字仲达,河内温人。曾任职过曹魏的大都督,太尉,太傅。少有奇节,聪明多大略,博学洽闻,伏膺儒教,世之鬼才也。", + xiahoudun: "字元让,沛国谯人。有拔矢啖睛之勇,性格勇猛刚烈。", + zhangliao: + "字文远,魏雁门马邑人。官至前将军、征东将军、晋阳侯。武功高强,又谋略过人,多次建立奇功,以800人突袭孙权十万大军,皆望风披靡。", + xuzhu: "字仲康,谯国谯县人。和典韦一同统率着曹操的亲卫队“虎卫军”。因为他十分勇猛,所以有“虎痴”的绰号。曾有裸衣斗马超之举。", + guojia: "字奉孝,颍川阳翟人,官至军师祭酒。惜天妒英才,英年早逝。有诗云:“良计环环不遗策,每临制变满座惊”。", + zhenji: "中山无极人,别称甄洛或甄宓,庙号文昭甄皇后。魏文帝曹丕的正室。懂诗文,有倾国倾城之貌,《洛神赋》即是曹植为她所作。", + huatuo: "字元化,一名旉,沛国谯人,“建安三神医”之一。集平生之所得著《青囊经》,现已失传。", + lvbu: "字奉先,五原郡九原县人。三国第一猛将,曾独力战刘关张三人,其武力世之无双。时人语曰:“人中有吕布,马中有赤兔。”", + diaochan: + "中国古代四大美女之一,有闭月羞花之貌。司徒王允之义女,由王允授意施行连环计,离间董卓、吕布,借布手除卓。后貂蝉成为吕布的妾。", + huaxiong: + "董卓旗下名将,自荐抵抗山东地区反对董卓的诸侯联军于汜水关前,他先后斩杀济北相鲍信之弟鲍忠和孙坚部将祖茂、以及袁术部将俞涉和韩馥手下潘凤等人,最后关东联军派出关羽与之一对一决斗而被杀。", - xf_yiji:"伊籍,字机伯,生卒年不详,兖州山阳郡(今山东金乡县)人,三国时期蜀汉官员。年少时依附于同乡刘表。刘备落难到荆州时,伊籍时常拜访,托请刘备照顾。建安十三年(208年),刘表病死,伊籍便转投刘备,一起渡江南下。建安十六年(211年),刘备入蜀帮助刘璋,伊籍亦有跟随。随后刘备和刘璋双方决裂。建安十九年(214年),刘备平定益州,任命伊籍为左将军从事中郎,其待遇次于简雍、孙乾等。后升任昭文将军,并与诸葛亮、法正、刘巴、李严共同编制《蜀科》。", + xf_yiji: + "伊籍,字机伯,生卒年不详,兖州山阳郡(今山东金乡县)人,三国时期蜀汉官员。年少时依附于同乡刘表。刘备落难到荆州时,伊籍时常拜访,托请刘备照顾。建安十三年(208年),刘表病死,伊籍便转投刘备,一起渡江南下。建安十六年(211年),刘备入蜀帮助刘璋,伊籍亦有跟随。随后刘备和刘璋双方决裂。建安十九年(214年),刘备平定益州,任命伊籍为左将军从事中郎,其待遇次于简雍、孙乾等。后升任昭文将军,并与诸葛亮、法正、刘巴、李严共同编制《蜀科》。", }, - perfectPair:{ - xiahoudun:['xiahouyuan'], - zhenji:['caopi'], - caocao:['xuzhu','dianwei','bianfuren'], - huangzhong:['weiyan'], - zhugeliang:['jiangwei','jiangfei','huangyueying'], - liubei:['guanyu','zhangfei','ganfuren'], - zhaoyun:['liushan'], - daqiao:['xiaoqiao'], - zhouyu:['huanggai','xiaoqiao','zhouyi'], - sunquan:['zhoutai'], - lvbu:['diaochan','lvlingqi'], - machao:['madai','mayunlu','yangwan'], - zhangliao:['zangba'], - ganning:['lingtong','xf_sufei'], - guanyu:['zhangfei','liaohua'], + perfectPair: { + xiahoudun: ["xiahouyuan"], + zhenji: ["caopi"], + caocao: ["xuzhu", "dianwei", "bianfuren"], + huangzhong: ["weiyan"], + zhugeliang: ["jiangwei", "jiangfei", "huangyueying"], + liubei: ["guanyu", "zhangfei", "ganfuren"], + zhaoyun: ["liushan"], + daqiao: ["xiaoqiao"], + zhouyu: ["huanggai", "xiaoqiao", "zhouyi"], + sunquan: ["zhoutai"], + lvbu: ["diaochan", "lvlingqi"], + machao: ["madai", "mayunlu", "yangwan"], + zhangliao: ["zangba"], + ganning: ["lingtong", "xf_sufei"], + guanyu: ["zhangfei", "liaohua"], }, - skill:{ + skill: { //标准版甘夫人 - stdshushen:{ - audio:'shushen', - trigger:{player:'recoverEnd'}, - getIndex(event){ - return event.num||1; + stdshushen: { + audio: "shushen", + trigger: { player: "recoverEnd" }, + getIndex(event) { + return event.num || 1; }, - async cost(event,trigger,player){ - event.result = await player.chooseTarget(get.prompt2('stdshushen'),lib.filter.notMe) - .set('ai',target=>get.attitude(_status.event.player,target)).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("stdshushen"), lib.filter.notMe) + .set("ai", (target) => get.attitude(_status.event.player, target)) + .forResult(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { const target = event.targets[0]; - await target.draw(target.countCards('h') > 0 ? 1 : 2); + await target.draw(target.countCards("h") > 0 ? 1 : 2); }, - ai:{threaten:0.8,expose:0.1}, + ai: { threaten: 0.8, expose: 0.1 }, }, - stdkuangfu:{ - audio:'xinkuangfu', - trigger:{source:'damageSource'}, - forced:true, - usable:1, - filter(event,player){ - return player.isPhaseUsing()&&event.card&&event.card.name=='sha'&&event.player!=player&&event.player.isIn(); + stdkuangfu: { + audio: "xinkuangfu", + trigger: { source: "damageSource" }, + forced: true, + usable: 1, + filter(event, player) { + return ( + player.isPhaseUsing() && + event.card && + event.card.name == "sha" && + event.player != player && + event.player.isIn() + ); }, - async content(event,trigger,player){ - if(trigger.player.hpplayer.hp; + ai: { + halfneg: true, }, - logTarget:'player', - async content(event,trigger,player){ + }, + rewangzun: { + trigger: { global: "phaseZhunbeiBegin" }, + forced: true, + audio: "wangzun", + filter(event, player) { + return event.player.hp > player.hp; + }, + logTarget: "player", + async content(event, trigger, player) { player.draw(); - let zhu=false; - const target=trigger.player; - switch(get.mode()){ - case 'identity':{ - zhu=target.isZhu; + let zhu = false; + const target = trigger.player; + switch (get.mode()) { + case "identity": { + zhu = target.isZhu; break; } - case 'guozhan':{ - zhu=get.is.jun(target); + case "guozhan": { + zhu = get.is.jun(target); break; } - case 'versus':{ - zhu=target.identity=='zhu'; + case "versus": { + zhu = target.identity == "zhu"; break; } - case 'doudizhu':{ - zhu=target==game.zhu; + case "doudizhu": { + zhu = target == game.zhu; break; } } - if(zhu){ + if (zhu) { player.draw(); - target.addTempSkill('rewangzun2'); - target.addMark('rewangzun2',1,false); + target.addTempSkill("rewangzun2"); + target.addMark("rewangzun2", 1, false); } }, }, - rewangzun2:{ - onremove:true, - mod:{ - maxHandcard(player,num){ - return num-player.countMark('rewangzun2'); + rewangzun2: { + onremove: true, + mod: { + maxHandcard(player, num) { + return num - player.countMark("rewangzun2"); }, }, - intro:{content:'手牌上限-#'}, + intro: { content: "手牌上限-#" }, }, - retongji:{ - trigger:{global:'useCardToTarget'}, - logTarget:'target', - audio:'tongji', - filter(event,player){ - return event.card.name=='sha'&&event.player!=player&&!event.targets.includes(player)&& - event.target.inRange(player)&&event.target.countCards('he')>0; + retongji: { + trigger: { global: "useCardToTarget" }, + logTarget: "target", + audio: "tongji", + filter(event, player) { + return ( + event.card.name == "sha" && + event.player != player && + !event.targets.includes(player) && + event.target.inRange(player) && + event.target.countCards("he") > 0 + ); }, - async cost(event, trigger, player){ - const {result} = await trigger.target.chooseCard('he', '是否对'+get.translation(player)+'发动【同疾】?', - '弃置一张牌,将'+get.translation(trigger.card)+'转移给'+get.translation(player), lib.filter.cardDiscardable) - .set('ai',card=>{ - if(!_status.event.check) return -1; - return get.unuseful(card)+9; - }) - .set('check',(()=>{ - if(trigger.target.countCards('h','shan')){ - return -get.attitude(trigger.target,player); - } - if(get.attitude(trigger.target,player)<5){ - return 6-get.attitude(trigger.target,player); - } - if(trigger.target.hp==1&&player.countCards('h','shan')==0){ - return 10-get.attitude(trigger.target,player); - } - if(trigger.target.hp==2&&player.countCards('h','shan')==0){ - return 8-get.attitude(trigger.target,player); - } - return -1; - })()>0); - if(result.bool){ + async cost(event, trigger, player) { + const { result } = await trigger.target + .chooseCard( + "he", + "是否对" + get.translation(player) + "发动【同疾】?", + "弃置一张牌,将" + + get.translation(trigger.card) + + "转移给" + + get.translation(player), + lib.filter.cardDiscardable + ) + .set("ai", (card) => { + if (!_status.event.check) return -1; + return get.unuseful(card) + 9; + }) + .set( + "check", + (() => { + if (trigger.target.countCards("h", "shan")) { + return -get.attitude(trigger.target, player); + } + if (get.attitude(trigger.target, player) < 5) { + return 6 - get.attitude(trigger.target, player); + } + if (trigger.target.hp == 1 && player.countCards("h", "shan") == 0) { + return 10 - get.attitude(trigger.target, player); + } + if (trigger.target.hp == 2 && player.countCards("h", "shan") == 0) { + return 8 - get.attitude(trigger.target, player); + } + return -1; + })() > 0 + ); + if (result.bool) { event.result = { - bool:true, - cost_data:{ - cards: result.cards - } + bool: true, + cost_data: { + cards: result.cards, + }, }; } }, - async content(event,trigger,player){ + async content(event, trigger, player) { trigger.target.discard(event.cost_data.cards); - const evt=trigger.getParent(); + const evt = trigger.getParent(); evt.triggeredTargets2.remove(trigger.target); evt.targets.remove(trigger.target); evt.targets.push(player); }, - }, - hujia:{ - audio:2, - audioname:['re_caocao'], - unique:true, - zhuSkill:true, - trigger:{player:['chooseToRespondBefore','chooseToUseBefore']}, - filter(event,player){ - if(event.responded) return false; - if(player.storage.hujiaing) return false; - if(!player.hasZhuSkill('hujia')) return false; - if(!event.filterCard({name:'shan',isCard:true},player,event)) return false; - return game.hasPlayer(current=>current!=player&¤t.group=='wei'); + ai: { + neg: true }, - check(event,player){ - if(get.damageEffect(player,event.player,player)>=0) return false; + }, + hujia: { + audio: 2, + audioname: ["re_caocao"], + unique: true, + zhuSkill: true, + trigger: { player: ["chooseToRespondBefore", "chooseToUseBefore"] }, + filter(event, player) { + if (event.responded) return false; + if (player.storage.hujiaing) return false; + if (!player.hasZhuSkill("hujia")) return false; + if (!event.filterCard({ name: "shan", isCard: true }, player, event)) return false; + return game.hasPlayer((current) => current != player && current.group == "wei"); + }, + check(event, player) { + if (get.damageEffect(player, event.player, player) >= 0) return false; return true; }, - async content(event,trigger,player){ - while(true){ + async content(event, trigger, player) { + while (true) { let bool; - if(!event.current) event.current=player.next; - if(event.current==player) return; - else if(event.current.group=='wei'){ - if((event.current==game.me&&!_status.auto)||( - get.attitude(event.current,player)>2)|| - event.current.isOnline()){ - player.storage.hujiaing=true; - const next=event.current.chooseToRespond('是否替'+get.translation(player)+'打出一张闪?',{name:'shan'}); - next.set('ai',()=>{ - const event=_status.event; - return (get.attitude(event.player,event.source)-2); + if (!event.current) event.current = player.next; + if (event.current == player) return; + else if (event.current.group == "wei") { + if ( + (event.current == game.me && !_status.auto) || + get.attitude(event.current, player) > 2 || + event.current.isOnline() + ) { + player.storage.hujiaing = true; + const next = event.current.chooseToRespond( + "是否替" + get.translation(player) + "打出一张闪?", + { name: "shan" } + ); + next.set("ai", () => { + const event = _status.event; + return get.attitude(event.player, event.source) - 2; }); - next.set('skillwarn','替'+get.translation(player)+'打出一张闪'); - next.autochoose=lib.filter.autoRespondShan; - next.set('source',player); - bool=(await next).result.bool; + next.set("skillwarn", "替" + get.translation(player) + "打出一张闪"); + next.autochoose = lib.filter.autoRespondShan; + next.set("source", player); + bool = (await next).result.bool; } } - player.storage.hujiaing=false; - if(bool){ - trigger.result={bool:true,card:{name:'shan',isCard:true}}; - trigger.responded=true; - trigger.animate=false; - if(typeof event.current.ai.shown=='number'&&event.current.ai.shown<0.95){ - event.current.ai.shown+=0.3; - if(event.current.ai.shown>0.95) event.current.ai.shown=0.95; + player.storage.hujiaing = false; + if (bool) { + trigger.result = { bool: true, card: { name: "shan", isCard: true } }; + trigger.responded = true; + trigger.animate = false; + if (typeof event.current.ai.shown == "number" && event.current.ai.shown < 0.95) { + event.current.ai.shown += 0.3; + if (event.current.ai.shown > 0.95) event.current.ai.shown = 0.95; } return; - } - else{ - event.current=event.current.next; + } else { + event.current = event.current.next; } } }, - ai:{ - respondShan:true, - skillTagFilter(player){ - if(player.storage.hujiaing) return false; - if(!player.hasZhuSkill('hujia')) return false; - return game.hasPlayer(current=>current!=player&¤t.group=='wei'); + ai: { + respondShan: true, + skillTagFilter(player) { + if (player.storage.hujiaing) return false; + if (!player.hasZhuSkill("hujia")) return false; + return game.hasPlayer((current) => current != player && current.group == "wei"); }, }, }, - jianxiong:{ - audio:2, - preHidden:true, - trigger:{player:'damageEnd'}, - filter(event,player){ - return get.itemtype(event.cards)=='cards'&&get.position(event.cards[0],true)=='o'; + jianxiong: { + audio: 2, + preHidden: true, + trigger: { player: "damageEnd" }, + filter(event, player) { + return get.itemtype(event.cards) == "cards" && get.position(event.cards[0], true) == "o"; }, - async content(event,trigger,player){ - player.gain(trigger.cards,'gain2'); + async content(event, trigger, player) { + player.gain(trigger.cards, "gain2"); + }, + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.tag(card, "damage")) return [1, 0.55]; + }, + }, }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.tag(card,'damage')) return [1,0.55]; - } - } - } }, - fankui:{ - audio:2, - trigger:{player:'damageEnd'}, - logTarget:'source', - preHidden:true, - filter(event,player){ - return event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')>0&&event.num>0; + fankui: { + audio: 2, + trigger: { player: "damageEnd" }, + logTarget: "source", + preHidden: true, + filter(event, player) { + return ( + event.source && + event.source.countGainableCards(player, event.source != player ? "he" : "e") > 0 && + event.num > 0 + ); }, - async content(event,trigger,player){ - player.gainPlayerCard(true,trigger.source,trigger.source!=player?'he':'e'); + async content(event, trigger, player) { + player.gainPlayerCard(true, trigger.source, trigger.source != player ? "he" : "e"); }, - ai:{ - maixie_defend:true, - effect:{ - target(card,player,target){ - if(player.countCards('he')>1&&get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - if(get.attitude(target,player)<0) return [1,1]; + ai: { + maixie_defend: true, + effect: { + target(card, player, target) { + if (player.countCards("he") > 1 && get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + if (get.attitude(target, player) < 0) return [1, 1]; } - } - } - } - }, - guicai:{ - audio:2, - trigger:{global:'judge'}, - preHidden:true, - filter(event,player){ - return player.countCards(get.mode()=='guozhan'?'hes':'hs')>0; + }, + }, }, - async cost(event, trigger, player){ - const {result:{bool,cards}}=await player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('guicai'),get.mode()=='guozhan'?'hes':'hs',card=>{ - const player=_status.event.player; - const mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - const mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',card=>{ - const trigger=_status.event.getTrigger(); - const player=_status.event.player; - const judging=_status.event.judging; - const result=trigger.judge(card)-trigger.judge(judging); - const attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result-get.value(card)/2; - } - else{ - return -result-get.value(card)/2; - } - }).set('judging',trigger.player.judging[0]).setHiddenSkill('guicai'); - if(bool) event.result = {bool,cost_data:{cards}} + }, + guicai: { + audio: 2, + trigger: { global: "judge" }, + preHidden: true, + filter(event, player) { + return player.countCards(get.mode() == "guozhan" ? "hes" : "hs") > 0; + }, + async cost(event, trigger, player) { + const { + result: { bool, cards }, + } = await player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("guicai"), + get.mode() == "guozhan" ? "hes" : "hs", + (card) => { + const player = _status.event.player; + const mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + const mod = game.checkMod( + card, + player, + "unchanged", + "cardRespondable", + player + ); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", (card) => { + const trigger = _status.event.getTrigger(); + const player = _status.event.player; + const judging = _status.event.judging; + const result = trigger.judge(card) - trigger.judge(judging); + const attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result - get.value(card) / 2; + } else { + return -result - get.value(card) / 2; + } + }) + .set("judging", trigger.player.judging[0]) + .setHiddenSkill("guicai"); + if (bool) event.result = { bool, cost_data: { cards } }; }, //技能的logSkill跟着打出牌走 不进行logSkill - popup:false, - async content(event,trigger,player){ + popup: false, + async content(event, trigger, player) { const chooseCardResultCards = event.cost_data.cards; - player.respond(chooseCardResultCards,'guicai','highlight','noOrdering'); - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + player.respond(chooseCardResultCards, "guicai", "highlight", "noOrdering"); + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo("deletenode", player, get.cardsInfo([trigger.player.judging[0].clone])); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=chooseCardResultCards[0]; + trigger.player.judging[0] = chooseCardResultCards[0]; trigger.orderingCards.addArray(chooseCardResultCards); - game.log(trigger.player,'的判定牌改为',chooseCardResultCards[0]); + game.log(trigger.player, "的判定牌改为", chooseCardResultCards[0]); game.asyncDelay(2); }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, - ganglie:{ - audio:2, - trigger:{player:'damageEnd'}, - filter(event,player){ - return (event.source!=undefined); + ganglie: { + audio: 2, + trigger: { player: "damageEnd" }, + filter(event, player) { + return event.source != undefined; }, - check(event,player){ - return (get.attitude(player,event.source)<=0); + check(event, player) { + return get.attitude(player, event.source) <= 0; }, - logTarget:'source', - async content(event,trigger,player){ - const judgeEvent=player.judge(card=>{ - if(get.suit(card)=='heart') return -2; + logTarget: "source", + async content(event, trigger, player) { + const judgeEvent = player.judge((card) => { + if (get.suit(card) == "heart") return -2; return 2; }); - judgeEvent.judge2=result=>result.bool; - const {result:{judge}}=await judgeEvent; - if(judge<2) return; - const {result:{bool}}=await trigger.source.chooseToDiscard(2) - .set('ai',card=>{ - if(card.name=='tao') return -10; - if(card.name=='jiu'&&_status.event.player.hp==1) return -10; - return get.unuseful(card)+2.5*(5-get.owner(card).hp); + judgeEvent.judge2 = (result) => result.bool; + const { + result: { judge }, + } = await judgeEvent; + if (judge < 2) return; + const { + result: { bool }, + } = await trigger.source.chooseToDiscard(2).set("ai", (card) => { + if (card.name == "tao") return -10; + if (card.name == "jiu" && _status.event.player.hp == 1) return -10; + return get.unuseful(card) + 2.5 * (5 - get.owner(card).hp); }); - if(bool==false){ + if (bool == false) { trigger.source.damage(); } }, - ai:{ - maixie_defend:true, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; + ai: { + maixie_defend: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; return 0.8; // if(get.tag(card,'damage')&&get.damageEffect(target,player,player)>0) return [1,0,0,-1.5]; - } - } - } + }, + }, + }, }, - ganglie_three:{ - audio:'ganglie', - trigger:{player:'damageEnd'}, - async cost(event, trigger, player){ - const {result} = await player.chooseTarget(get.prompt2('ganglie_three'),(card,player,target)=>{ - return target.isEnemyOf(player); - }).set('ai',target=>{ - return -get.attitude(_status.event.player,target)/Math.sqrt(1+target.countCards('h')); - }); + ganglie_three: { + audio: "ganglie", + trigger: { player: "damageEnd" }, + async cost(event, trigger, player) { + const { result } = await player + .chooseTarget(get.prompt2("ganglie_three"), (card, player, target) => { + return target.isEnemyOf(player); + }) + .set("ai", (target) => { + return ( + -get.attitude(_status.event.player, target) / + Math.sqrt(1 + target.countCards("h")) + ); + }); event.result = result; }, - async content(event, trigger, player){ + async content(event, trigger, player) { event.target = event.targets[0]; - player.logSkill('ganglie_three', event.target); - const judgeEvent=player.judge(card=>{ - if(get.suit(card)=='heart') return -2; + player.logSkill("ganglie_three", event.target); + const judgeEvent = player.judge((card) => { + if (get.suit(card) == "heart") return -2; return 2; }); - judgeEvent.judge2 = (result => result.bool); - const {result:{judge}} = await judgeEvent; + judgeEvent.judge2 = (result) => result.bool; + const { + result: { judge }, + } = await judgeEvent; if (judge < 2) return; - const {result:{bool:chooseToDiscardResultBool}} = await event.target.chooseToDiscard(2).set('ai',card=>{ - if (card.name=='tao') return -10; - if (card.name=='jiu' && _status.event.player.hp==1) return -10; - return get.unuseful(card)+2.5*(5-get.owner(card).hp); + const { + result: { bool: chooseToDiscardResultBool }, + } = await event.target.chooseToDiscard(2).set("ai", (card) => { + if (card.name == "tao") return -10; + if (card.name == "jiu" && _status.event.player.hp == 1) return -10; + return get.unuseful(card) + 2.5 * (5 - get.owner(card).hp); }); if (chooseToDiscardResultBool === false) { event.target.damage(); } }, - ai:{ - maixie_defend:true, - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; + ai: { + maixie_defend: true, + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; return 0.8; // if(get.tag(card,'damage')&&get.damageEffect(target,player,player)>0) return [1,0,0,-1.5]; - } - } - } + }, + }, + }, }, - tuxi:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter(event,player){ + tuxi: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter(event, player) { return !event.numFixed; }, - async cost(event, trigger, player){ - let num = game.countPlayer(current => current != player && current.countCards('h') && get.attitude(player,current) <= 0); - let check = (num >= 2); - const {result} = await player.chooseTarget(get.prompt('tuxi'), '获得其他一至两名角色的各一张手牌', [1,2], (card, player, target) => { - return target.countCards('h') > 0 && player != target; - }, target => { - if (!_status.event.aicheck) return 0; - const att=get.attitude(_status.event.player, target); - if (target.hasSkill('tuntian')) return att / 10; - return 1 - att; - }).set('aicheck', check); + async cost(event, trigger, player) { + let num = game.countPlayer( + (current) => + current != player && current.countCards("h") && get.attitude(player, current) <= 0 + ); + let check = num >= 2; + const { result } = await player + .chooseTarget( + get.prompt("tuxi"), + "获得其他一至两名角色的各一张手牌", + [1, 2], + (card, player, target) => { + return target.countCards("h") > 0 && player != target; + }, + (target) => { + if (!_status.event.aicheck) return 0; + const att = get.attitude(_status.event.player, target); + if (target.hasSkill("tuntian")) return att / 10; + return 1 - att; + } + ) + .set("aicheck", check); event.result = result; }, - async content(event, trigger, player){ + async content(event, trigger, player) { player.gainMultiple(event.targets); trigger.changeToZero(); game.asyncDelay(); }, - ai:{ - threaten:2, - expose:0.3 - } + ai: { + threaten: 2, + expose: 0.3, + }, }, - luoyi:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - check(event,player){ - if(player.skipList.includes('phaseUse')||player.countCards('h')<3) return false; - if(!player.hasSha()) return false; - return game.hasPlayer(current=>get.attitude(player,current)<0&&player.canUse('sha',current)); + luoyi: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + check(event, player) { + if (player.skipList.includes("phaseUse") || player.countCards("h") < 3) return false; + if (!player.hasSha()) return false; + return game.hasPlayer( + (current) => get.attitude(player, current) < 0 && player.canUse("sha", current) + ); }, - preHidden:true, - filter(event,player){ - return !event.numFixed&&event.num>0; + preHidden: true, + filter(event, player) { + return !event.numFixed && event.num > 0; }, - async content(event,trigger,player){ - player.addTempSkill('luoyi2','phaseJieshuBegin'); + async content(event, trigger, player) { + player.addTempSkill("luoyi2", "phaseJieshuBegin"); trigger.num--; - } - }, - luoyi2:{ - trigger:{source:'damageBegin1'}, - filter(event){ - return event.card&&(event.card.name=='sha'||event.card.name=='juedou')&&event.notLink(); }, - forced:true, - async content(event,trigger,player){ + }, + luoyi2: { + trigger: { source: "damageBegin1" }, + filter(event) { + return ( + event.card && + (event.card.name == "sha" || event.card.name == "juedou") && + event.notLink() + ); + }, + forced: true, + async content(event, trigger, player) { trigger.num++; }, - ai:{ - damageBonus:true - } + ai: { + damageBonus: true, + }, }, - tiandu:{ - audio:2, - audioname:['re_guojia','xizhicai','gz_nagisa'], - trigger:{player:'judgeEnd'}, - preHidden:true, - frequent(event){ + tiandu: { + audio: 2, + audioname: ["re_guojia", "xizhicai", "gz_nagisa"], + trigger: { player: "judgeEnd" }, + preHidden: true, + frequent(event) { //if(get.mode()=='guozhan') return false; - return event.result.card.name!=='du'; + return event.result.card.name !== "du"; }, - check(event){ - return event.result.card.name!=='du'; + check(event) { + return event.result.card.name !== "du"; }, - filter(event,player){ - return get.position(event.result.card,true)=='o'; + filter(event, player) { + return get.position(event.result.card, true) == "o"; + }, + async content(event, trigger, player) { + player.gain(trigger.result.card, "gain2"); }, - async content(event,trigger,player){ - player.gain(trigger.result.card,'gain2'); - } }, - yiji:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - filter(event){ - return event.num>0; + yiji: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + filter(event) { + return event.num > 0; }, - getIndex(event, player, triggername){ + getIndex(event, player, triggername) { return event.num; }, - async content(event, trigger, player){ - const {cards}=await game.cardsGotoOrdering(get.cards(2)); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - if(!cards.length) return; + async content(event, trigger, player) { + const { cards } = await game.cardsGotoOrdering(get.cards(2)); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + event.given_map = {}; + if (!cards.length) return; // event.goto -> do while - do{ - const {result:{bool,links}} = - cards.length==1? - {result:{links:cards.slice(0),bool: true}}: - await player.chooseCardButton('遗计:请选择要分配的牌',true,cards,[1,cards.length]) - .set('ai',()=>{ - if(ui.selected.buttons.length==0) return 1; - return 0; - }); - if(!bool) return; + do { + const { + result: { bool, links }, + } = + cards.length == 1 + ? { result: { links: cards.slice(0), bool: true } } + : await player + .chooseCardButton("遗计:请选择要分配的牌", true, cards, [ + 1, + cards.length, + ]) + .set("ai", () => { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + if (!bool) return; cards.removeArray(links); - event.togive=links.slice(0); - const {result:{targets}}=await player.chooseTarget('选择一名角色获得'+get.translation(links),true) - .set('ai',target=>{ - const att=get.attitude(_status.event.player,target); - if(_status.event.enemy){ + event.togive = links.slice(0); + const { + result: { targets }, + } = await player + .chooseTarget("选择一名角色获得" + get.translation(links), true) + .set("ai", (target) => { + const att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { return -att; - } - else if(att>0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; } }) - .set('enemy',get.value(event.togive[0],player,'raw')<0); - if(targets.length){ - const id=targets[0].playerid, - map=event.given_map; - if(!map[id]) map[id]=[]; + .set("enemy", get.value(event.togive[0], player, "raw") < 0); + if (targets.length) { + const id = targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - }while(cards.length>0); - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + } while (cards.length > 0); + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - const list=[]; - for(const i in event.given_map){ - const source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - if(player!==source&&(get.mode()!=='identity'||player.identity!=='nei')) player.addExpose(0.2); + const list = []; + for (const i in event.given_map) { + const source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + if (player !== source && (get.mode() !== "identity" || player.identity !== "nei")) + player.addExpose(0.2); list.push([source, event.given_map[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'draw', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "draw", + }).setContent("gaincardMultiple"); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - let num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target(card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + let num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } - } - } - } + }, + }, + }, }, - luoshen:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - preHidden:true, - async content(event,trigger,player){ - while(true){ - if(event.cards==undefined) event.cards=[]; - const judgeEvent=player.judge(card=>{ - if(get.color(card)=='black') return 1.5; + luoshen: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + preHidden: true, + async content(event, trigger, player) { + while (true) { + if (event.cards == undefined) event.cards = []; + const judgeEvent = player.judge((card) => { + if (get.color(card) == "black") return 1.5; return -1.5; }); - judgeEvent.judge2=result=>result.bool; - if(get.mode()!='guozhan'&&!player.hasSkillTag('rejudge')) judgeEvent.set('callback',async event=>{ - if(event.judgeResult.color=='black'&&get.position(event.card,true)=='o') await player.gain(event.card,'gain2'); - }); - else judgeEvent.set('callback',async event=>{ - if(event.judgeResult.color=='black') event.getParent().orderingCards.remove(event.card); - }); - const {result:{judge,card}}=await judgeEvent; + judgeEvent.judge2 = (result) => result.bool; + if (get.mode() != "guozhan" && !player.hasSkillTag("rejudge")) + judgeEvent.set("callback", async (event) => { + if ( + event.judgeResult.color == "black" && + get.position(event.card, true) == "o" + ) + await player.gain(event.card, "gain2"); + }); + else + judgeEvent.set("callback", async (event) => { + if (event.judgeResult.color == "black") + event.getParent().orderingCards.remove(event.card); + }); + const { + result: { judge, card }, + } = await judgeEvent; let bool; - if(judge>0){ + if (judge > 0) { event.cards.push(card); - bool=(await player.chooseBool('是否再次发动【洛神】?').set('frequentSkill','luoshen')).result.bool; - } - else{ - for(let i=0;i{ - if(get.color(card)=='black') return 1.5; - return -1.5; - },ui.special); - judgeEvent.judge2=result=>result.bool; - const {result:{judge,card}}=await judgeEvent; - let bool; - if(judge>0){ - event.cards.push(card); - bool=lib.config.autoskilllist.includes('luoshen')?(await player.chooseBool('是否再次发动【洛神】?')).result.bool:true; - } - else{ - for(let i=0;i { + if (get.color(card) == "black") return 1.5; + return -1.5; + }, ui.special); + judgeEvent.judge2 = (result) => result.bool; + const { + result: { judge, card }, + } = await judgeEvent; + let bool; + if (judge > 0) { + event.cards.push(card); + bool = lib.config.autoskilllist.includes("luoshen") + ? (await player.chooseBool("是否再次发动【洛神】?")).result.bool + : true; + } else { + for (let i = 0; i < event.cards.length; i++) { + if (get.position(event.cards[i]) != "s") { + event.cards.splice(i, 1); + i--; + } + } + player.gain(event.cards, "gain2"); + player.storage.xinluoshen = event.cards.slice(0); + return; + } + if (!bool) { + if (event.cards.length) { + player.gain(event.cards, "gain2"); + player.storage.xinluoshen = event.cards.slice(0); return; } } } }, - mod:{ - ignoredHandcard(card,player){ - if(get.is.altered('xinluoshen')&&player.storage.xinluoshen&&player.storage.xinluoshen.includes(card)){ + mod: { + ignoredHandcard(card, player) { + if ( + get.is.altered("xinluoshen") && + player.storage.xinluoshen && + player.storage.xinluoshen.includes(card) + ) { return true; } - } + }, }, - group:'xinluoshen_clear', - subSkill:{ - clear:{ - trigger:{player:'phaseAfter'}, - silent:true, - async content(event,trigger,player){ + group: "xinluoshen_clear", + subSkill: { + clear: { + trigger: { player: "phaseAfter" }, + silent: true, + async content(event, trigger, player) { delete player.storage.xinluoshen; - } - } - } + }, + }, + }, }, - qingguo:{ - mod:{ - aiValue(player,card,num){ - if(get.name(card)!='shan'&&get.color(card)!='black') return; - const cards=player.getCards('hs',card=>get.name(card)=='shan'||get.color(card)=='black'); - cards.sort((a,b)=>{ - return (get.name(b)=='shan'?1:2)-(get.name(a)=='shan'?1:2); + qingguo: { + mod: { + aiValue(player, card, num) { + if (get.name(card) != "shan" && get.color(card) != "black") return; + const cards = player.getCards( + "hs", + (card) => get.name(card) == "shan" || get.color(card) == "black" + ); + cards.sort((a, b) => { + return (get.name(b) == "shan" ? 1 : 2) - (get.name(a) == "shan" ? 1 : 2); }); - const geti=()=>{ - if(cards.includes(card)) cards.indexOf(card); + const geti = () => { + if (cards.includes(card)) cards.indexOf(card); return cards.length; }; - if(get.name(card)=='shan') return Math.min(num,[6,4,3][Math.min(geti(),2)])*0.6; - return Math.max(num,[6.5,4,3][Math.min(geti(),2)]); + if (get.name(card) == "shan") + return Math.min(num, [6, 4, 3][Math.min(geti(), 2)]) * 0.6; + return Math.max(num, [6.5, 4, 3][Math.min(geti(), 2)]); }, - aiUseful(){ - return lib.skill.qingguo.mod.aiValue.apply(this,arguments); + aiUseful() { + return lib.skill.qingguo.mod.aiValue.apply(this, arguments); }, }, - locked:false, - audio:2, - audioname:['sb_zhenji'], - enable:['chooseToRespond','chooseToUse'], - filterCard(card){ - return get.color(card)=='black'; + locked: false, + audio: 2, + audioname: ["sb_zhenji"], + enable: ["chooseToRespond", "chooseToUse"], + filterCard(card) { + return get.color(card) == "black"; }, - viewAs:{name:'shan'}, - viewAsFilter(player){ - if(!player.countCards('hs',{color:'black'})) return false; + viewAs: { name: "shan" }, + viewAsFilter(player) { + if (!player.countCards("hs", { color: "black" })) return false; }, - position:'hs', - prompt:'将一张黑色手牌当闪使用或打出', - check(){return 1}, - ai:{ - order:3, - respondShan:true, - skillTagFilter(player){ - if(!player.countCards('hs',{color:'black'})) return false; + position: "hs", + prompt: "将一张黑色手牌当闪使用或打出", + check() { + return 1; + }, + ai: { + order: 3, + respondShan: true, + skillTagFilter(player) { + if (!player.countCards("hs", { color: "black" })) return false; }, - effect:{ - target(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.6 - } - } - } + effect: { + target(card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.6; + }, + }, + }, }, - rende:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:[1,Infinity], - discard:false, - lose:false, - delay:0, - filterTarget(card,player,target){ - return player!=target; + rende: { + audio: 2, + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + discard: false, + lose: false, + delay: 0, + filterTarget(card, player, target) { + return player != target; }, - check(card){ - if(ui.selected.cards.length>1) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - const player=get.owner(card); - let num=0; - const evt2=_status.event.getParent(); - player.getHistory('lose',evt=>{ - if(evt.getParent().skill=='rende'&&evt.getParent(3)==evt2) num+=evt.cards.length; + check(card) { + if (ui.selected.cards.length > 1) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + const player = get.owner(card); + let num = 0; + const evt2 = _status.event.getParent(); + player.getHistory("lose", (evt) => { + if (evt.getParent().skill == "rende" && evt.getParent(3) == evt2) + num += evt.cards.length; }); - if(player.hp==player.maxHp||num>1||player.countCards('h')<=1){ - if(ui.selected.cards.length){ + if (player.hp == player.maxHp || num > 1 || player.countCards("h") <= 1) { + if (ui.selected.cards.length) { return -1; } - const players=game.filterPlayer(); - for(let i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + const players = game.filterPlayer(); + for (let i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - async content(event,trigger,player){ - const evt2=event.getParent(3); - let num=0; - player.getHistory('lose',evt=>{ - if(evt.getParent(2).name=='rende'&&evt.getParent(5)==evt2) num+=evt.cards.length; + async content(event, trigger, player) { + const evt2 = event.getParent(3); + let num = 0; + player.getHistory("lose", (evt) => { + if (evt.getParent(2).name == "rende" && evt.getParent(5) == evt2) + num += evt.cards.length; }); - player.give(event.cards,event.target); - if(num<2&&num+event.cards.length>1) player.recover(); + player.give(event.cards, event.target); + if (num < 2 && num + event.cards.length > 1) player.recover(); }, - ai:{ - order(skill,player){ - if(player.hp1){ + ai: { + order(skill, player) { + if ( + player.hp < player.maxHp && + player.storage.rende < 2 && + player.countCards("h") > 1 + ) { return 10; } return 1; }, - result:{ - target(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - return target.hasSkillTag('nodu')?0:-10; + result: { + target(player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + return target.hasSkillTag("nodu") ? 0 : -10; } - if(target.hasJudge('lebu')) return 0; - const nh=target.countCards('h'); - const np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.rende<0||player.countCards('h')<=1){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + const nh = target.countCards("h"); + const np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.rende < 0 || + player.countCards("h") <= 1 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); - } + return Math.max(1, 5 - nh); + }, }, - effect:{ - target(card,player,target){ - if(player==target&&get.type(card)=='equip'){ - if(player.countCards('e',{subtype:get.subtype(card)})){ - const players=game.filterPlayer(); - for(let i=0;i0){ + effect: { + target(card, player, target) { + if (player == target && get.type(card) == "equip") { + if (player.countCards("e", { subtype: get.subtype(card) })) { + const players = game.filterPlayer(); + for (let i = 0; i < players.length; i++) { + if (players[i] != player && get.attitude(player, players[i]) > 0) { return 0; } } } } - } + }, }, - threaten:0.8 - } - }, - rende1:{ - trigger:{player:'phaseUseBegin'}, - silent:true, - async content(event,trigger,player){ - player.storage.rende=0; - } - }, - jijiang:{ - audio:'jijiang1', - audioname:['liushan','re_liubei','re_liushan','ol_liushan'], - unique:true, - group:['jijiang1'], - zhuSkill:true, - filter(event,player){ - if(!player.hasZhuSkill('jijiang')||!game.hasPlayer(current=>current!=player&¤t.group=='shu')) return false; - return !event.jijiang&&(event.type!='phase'||!player.hasSkill('jijiang3')); + threaten: 0.8, }, - enable:['chooseToUse','chooseToRespond'], - viewAs:{name:'sha'}, - filterCard(){return false}, - selectCard:-1, - ai:{ - order(){ - return get.order({name:'sha'})+0.3; + }, + rende1: { + trigger: { player: "phaseUseBegin" }, + silent: true, + async content(event, trigger, player) { + player.storage.rende = 0; + }, + }, + jijiang: { + audio: "jijiang1", + audioname: ["liushan", "re_liubei", "re_liushan", "ol_liushan"], + unique: true, + group: ["jijiang1"], + zhuSkill: true, + filter(event, player) { + if ( + !player.hasZhuSkill("jijiang") || + !game.hasPlayer((current) => current != player && current.group == "shu") + ) + return false; + return !event.jijiang && (event.type != "phase" || !player.hasSkill("jijiang3")); + }, + enable: ["chooseToUse", "chooseToRespond"], + viewAs: { name: "sha" }, + filterCard() { + return false; + }, + selectCard: -1, + ai: { + order() { + return get.order({ name: "sha" }) + 0.3; }, - respondSha:true, - skillTagFilter(player){ - if(!player.hasZhuSkill('jijiang')||!game.hasPlayer(current=>current!=player&¤t.group=='shu')) return false; + respondSha: true, + skillTagFilter(player) { + if ( + !player.hasZhuSkill("jijiang") || + !game.hasPlayer((current) => current != player && current.group == "shu") + ) + return false; }, }, }, - jijiang1:{ - audio:2, - audioname:['liushan','re_liubei','re_liushan','ol_liushan'], - trigger:{player:['useCardBegin','respondBegin']}, - logTarget:'targets', - filter(event,player){ - return event.skill=='jijiang'; + jijiang1: { + audio: 2, + audioname: ["liushan", "re_liubei", "re_liushan", "ol_liushan"], + trigger: { player: ["useCardBegin", "respondBegin"] }, + logTarget: "targets", + filter(event, player) { + return event.skill == "jijiang"; }, - forced:true, - async content(event,trigger,player){ + forced: true, + async content(event, trigger, player) { delete trigger.skill; - trigger.getParent().set('jijiang',true); - while(true){ - if(event.current==undefined) event.current=player.next; - if(event.current==player){ - player.addTempSkill('jijiang3'); + trigger.getParent().set("jijiang", true); + while (true) { + if (event.current == undefined) event.current = player.next; + if (event.current == player) { + player.addTempSkill("jijiang3"); trigger.cancel(); trigger.getParent().goto(0); return; - } - else if(event.current.group=='shu'){ - const chooseToRespondEvent=event.current.chooseToRespond('是否替'+get.translation(player)+'打出一张杀?',{name:'sha'}); - chooseToRespondEvent.set('ai',()=>{ - const event=_status.event; - return (get.attitude(event.player,event.source)-2); + } else if (event.current.group == "shu") { + const chooseToRespondEvent = event.current.chooseToRespond( + "是否替" + get.translation(player) + "打出一张杀?", + { name: "sha" } + ); + chooseToRespondEvent.set("ai", () => { + const event = _status.event; + return get.attitude(event.player, event.source) - 2; }); - chooseToRespondEvent.set('source',player); - chooseToRespondEvent.set('jijiang',true); - chooseToRespondEvent.set('skillwarn','替'+get.translation(player)+'打出一张杀'); - chooseToRespondEvent.noOrdering=true; - chooseToRespondEvent.autochoose=lib.filter.autoRespondSha; - const {bool,card,cards}=(await chooseToRespondEvent).result; - if(bool){ - trigger.card=card; - trigger.cards=cards; - trigger.throw=false; - if(typeof event.current.ai.shown=='number'&&event.current.ai.shown<0.95){ - event.current.ai.shown+=0.3; - if(event.current.ai.shown>0.95) event.current.ai.shown=0.95; + chooseToRespondEvent.set("source", player); + chooseToRespondEvent.set("jijiang", true); + chooseToRespondEvent.set( + "skillwarn", + "替" + get.translation(player) + "打出一张杀" + ); + chooseToRespondEvent.noOrdering = true; + chooseToRespondEvent.autochoose = lib.filter.autoRespondSha; + const { bool, card, cards } = (await chooseToRespondEvent).result; + if (bool) { + trigger.card = card; + trigger.cards = cards; + trigger.throw = false; + if ( + typeof event.current.ai.shown == "number" && + event.current.ai.shown < 0.95 + ) { + event.current.ai.shown += 0.3; + if (event.current.ai.shown > 0.95) event.current.ai.shown = 0.95; } return; - } - else event.current=event.current.next; - } - else event.current=event.current.next; + } else event.current = event.current.next; + } else event.current = event.current.next; } - } + }, }, - jijiang3:{ - trigger:{global:['useCardAfter','useSkillAfter','phaseAfter']}, - silent:true, - charlotte:true, - filter(event){ - return event.skill!='jijiang'&&event.skill!='qinwang'; + jijiang3: { + trigger: { global: ["useCardAfter", "useSkillAfter", "phaseAfter"] }, + silent: true, + charlotte: true, + filter(event) { + return event.skill != "jijiang" && event.skill != "qinwang"; + }, + async content(event, trigger, player) { + player.removeSkill("jijiang3"); }, - async content(event,trigger,player){ - player.removeSkill('jijiang3'); - } }, - wusheng:{ - audio:2, - audioname2:{ - old_guanzhang:'old_fuhun', - old_guanyu:'wusheng_re_guanyu', + wusheng: { + audio: 2, + audioname2: { + old_guanzhang: "old_fuhun", + old_guanyu: "wusheng_re_guanyu", }, - audioname:['re_guanyu','guanzhang','jsp_guanyu','guansuo','re_guanzhang','dc_jsp_guanyu'], - enable:['chooseToRespond','chooseToUse'], - filterCard(card,player){ - if(get.zhu(player,'shouyue')) return true; - return get.color(card)=='red'; + audioname: [ + "re_guanyu", + "guanzhang", + "jsp_guanyu", + "guansuo", + "re_guanzhang", + "dc_jsp_guanyu", + ], + enable: ["chooseToRespond", "chooseToUse"], + filterCard(card, player) { + if (get.zhu(player, "shouyue")) return true; + return get.color(card) == "red"; }, - position:'hes', - viewAs:{name:'sha'}, - viewAsFilter(player){ - if(get.zhu(player,'shouyue')){ - if(!player.countCards('hes')) return false; - } - else{ - if(!player.countCards('hes',{color:'red'})) return false; + position: "hes", + viewAs: { name: "sha" }, + viewAsFilter(player) { + if (get.zhu(player, "shouyue")) { + if (!player.countCards("hes")) return false; + } else { + if (!player.countCards("hes", { color: "red" })) return false; } }, - prompt:'将一张红色牌当杀使用或打出', - check(card){ - const val=get.value(card); - if(_status.event.name=='chooseToRespond') return 1/Math.max(0.1,val); - return 5-val; + prompt: "将一张红色牌当杀使用或打出", + check(card) { + const val = get.value(card); + if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val); + return 5 - val; }, - ai:{ - skillTagFilter(player){ - if(get.zhu(player,'shouyue')){ - if(!player.countCards('hes')) return false; - } - else{ - if(!player.countCards('hes',{color:'red'})) return false; + ai: { + skillTagFilter(player) { + if (get.zhu(player, "shouyue")) { + if (!player.countCards("hes")) return false; + } else { + if (!player.countCards("hes", { color: "red" })) return false; } }, - respondSha:true, - } - }, - wusheng_re_guanyu:{audio:2}, - zhongyi:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - filterCard:true, - position:'he', - filter(event,player){ - return player.countCards('he')>0; - }, - discard:false, - lose:false, - async content(event,trigger,player){ - player.awakenSkill('zhongyi'); - player.addTempSkill('zhongyi2','roundStart'); - player.addToExpansion(player,'give',event.cards).gaintag.add('zhongyi2'); + respondSha: true, }, }, - zhongyi2:{ - trigger:{global:'damageBegin1'}, - forced:true, - popup:false, - logTarget:'source', - filter(event,player){ - return event.getParent().name=='sha'&&event.source&&event.source.isFriendOf(player); + wusheng_re_guanyu: { audio: 2 }, + zhongyi: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + filterCard: true, + position: "he", + filter(event, player) { + return player.countCards("he") > 0; }, - async content(event,trigger,player){trigger.num++}, - intro:{content:'expansion',markcount:'expansion'}, - onremove(player,skill){ - const cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + discard: false, + lose: false, + async content(event, trigger, player) { + player.awakenSkill("zhongyi"); + player.addTempSkill("zhongyi2", "roundStart"); + player.addToExpansion(player, "give", event.cards).gaintag.add("zhongyi2"); }, }, - paoxiao:{ - audio:2, - firstDo:true, - audioname:['re_zhangfei','guanzhang','xiahouba'], + zhongyi2: { + trigger: { global: "damageBegin1" }, + forced: true, + popup: false, + logTarget: "source", + filter(event, player) { + return event.getParent().name == "sha" && event.source && event.source.isFriendOf(player); + }, + async content(event, trigger, player) { + trigger.num++; + }, + intro: { content: "expansion", markcount: "expansion" }, + onremove(player, skill) { + const cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + }, + paoxiao: { + audio: 2, + firstDo: true, + audioname: ["re_zhangfei", "guanzhang", "xiahouba"], audioname2: { - old_guanzhang:'old_fuhun', - dc_xiahouba:'paoxiao_xiahouba', + old_guanzhang: "old_fuhun", + dc_xiahouba: "paoxiao_xiahouba", }, - trigger:{player:'useCard1'}, - forced:true, - filter(event,player){ - return !event.audioed&&event.card.name=='sha'&&player.countUsed('sha',true)>1&&event.getParent().type=='phase'; + trigger: { player: "useCard1" }, + forced: true, + filter(event, player) { + return ( + !event.audioed && + event.card.name == "sha" && + player.countUsed("sha", true) > 1 && + event.getParent().type == "phase" + ); }, - async content(event,trigger,player){ - trigger.audioed=true; + async content(event, trigger, player) { + trigger.audioed = true; }, - mod:{ - cardUsable(card,player,num){ - if(card.name=='sha') return Infinity; - } + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return Infinity; + }, }, - ai:{ - unequip:true, - skillTagFilter(player,tag,arg){ - if(!get.zhu(player,'shouyue')) return false; - if(arg&&arg.name=='sha') return true; + ai: { + unequip: true, + skillTagFilter(player, tag, arg) { + if (!get.zhu(player, "shouyue")) return false; + if (arg && arg.name == "sha") return true; return false; - } - } + }, + }, }, - paoxiao_xiahouba:{audio:2}, - guanxing_fail:{}, - guanxing:{ - audio:2, - audioname:['jiangwei','re_jiangwei','re_zhugeliang','ol_jiangwei'], - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - preHidden:true, - async content(event,trigger,player){ - const num=player.hasSkill('yizhi')&&player.hasSkill('guanxing')?5:Math.min(5,game.countPlayer()); - const cards=get.cards(num); + paoxiao_xiahouba: { audio: 2 }, + guanxing_fail: {}, + guanxing: { + audio: 2, + audioname: ["jiangwei", "re_jiangwei", "re_zhugeliang", "ol_jiangwei"], + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + preHidden: true, + async content(event, trigger, player) { + const num = + player.hasSkill("yizhi") && player.hasSkill("guanxing") + ? 5 + : Math.min(5, game.countPlayer()); + const cards = get.cards(num); game.cardsGotoOrdering(cards); - const next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','观星:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=list=>{ - const cards=list[0][1],player=_status.event.player; - const top=[]; - const judges=player.getCards('j'); - let stopped=false; - if(!player.hasWuxie()){ - for(let i=0;ijudge(b)-judge(a)); - if(judge(cards[0])<0){ - stopped=true;break; - } - else{ + const next = player.chooseToMove(); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("prompt", "观星:点击将牌移动到牌堆顶或牌堆底"); + next.processAI = (list) => { + const cards = list[0][1], + player = _status.event.player; + const top = []; + const judges = player.getCards("j"); + let stopped = false; + if (!player.hasWuxie()) { + for (let i = 0; i < judges.length; i++) { + const judge = get.judge(judges[i]); + cards.sort((a, b) => judge(b) - judge(a)); + if (judge(cards[0]) < 0) { + stopped = true; + break; + } else { top.unshift(cards.shift()); } } } let bottom; - if(!stopped){ - cards.sort((a,b)=>get.value(b,player)-get.value(a,player)); - while(cards.length){ - if(get.value(cards[0],player)<=5) break; + if (!stopped) { + cards.sort((a, b) => get.value(b, player) - get.value(a, player)); + while (cards.length) { + if (get.value(cards[0], player) <= 5) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - const {result:{moved}}=await next; - const top=moved[0]; - const bottom=moved[1]; + bottom = cards; + return [top, bottom]; + }; + const { + result: { moved }, + } = await next; + const top = moved[0]; + const bottom = moved[1]; top.reverse(); - game.cardsGotoPile( - top.concat(bottom), - ['top_cards',top], - (event,card)=>{ - if(event.top_cards.includes(card)) return ui.cardPile.firstChild; - return null; - } - ); - player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下'); - game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶'); + game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => { + if (event.top_cards.includes(card)) return ui.cardPile.firstChild; + return null; + }); + player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下"); + game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶"); game.asyncDelayx(); }, - ai:{ - threaten:1.2 - } - }, - kongcheng:{ - mod:{ - targetEnabled(card,player,target,now){ - if(target.countCards('h')==0){ - if(card.name=='sha'||card.name=='juedou') return false; - } - } + ai: { + threaten: 1.2, }, - group:'kongcheng1', - audio:'kongcheng1', - audioname:['re_zhugeliang'], - ai:{ - noh:true, - skillTagFilter(player,tag){ - if(tag=='noh'){ - if(player.countCards('h')!=1) return false; - } - } - } }, - kongcheng1:{ - audio:2, - trigger:{player:'loseEnd'}, - forced:true, - firstDo:true, - audioname:['re_zhugeliang'], - filter(event,player){ - if(player.countCards('h')) return false; - for(let i=0;i{ - if(get.zhu(_status.event.player,'shouyue')){ - if(get.suit(card)!='spade') return 2; - } - else{ - if(get.color(card)=='red') return 2; + }, + mashu2: { + mod: { + globalFrom(from, to, distance) { + return distance - 1; + }, + }, + }, + feiying: { + mod: { + globalTo(from, to, distance) { + return distance + 1; + }, + }, + }, + tieji: { + audio: 2, + shaRelated: true, + trigger: { player: "useCardToPlayered" }, + check(event, player) { + return get.attitude(player, event.target) <= 0; + }, + filter(event, player) { + return event.card.name == "sha"; + }, + logTarget: "target", + preHidden: true, + async content(event, trigger, player) { + const judgeEvent = player.judge((card) => { + if (get.zhu(_status.event.player, "shouyue")) { + if (get.suit(card) != "spade") return 2; + } else { + if (get.color(card) == "red") return 2; } return -0.5; }); - judgeEvent.judge2=result=>result.bool; - const {result:{bool}}=await judgeEvent; - if(bool){ + judgeEvent.judge2 = (result) => result.bool; + const { + result: { bool }, + } = await judgeEvent; + if (bool) { trigger.getParent().directHit.add(trigger.target); } }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(get.attitude(player,arg.target)>0||arg.card.name!='sha'||!ui.cardPile.firstChild||get.color(ui.cardPile.firstChild,player)!='red') return false; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if ( + get.attitude(player, arg.target) > 0 || + arg.card.name != "sha" || + !ui.cardPile.firstChild || + get.color(ui.cardPile.firstChild, player) != "red" + ) + return false; }, }, }, - jizhi:{ - audio:2, - audioname:['jianyong'], - trigger:{player:'useCard'}, - frequent:true, - preHidden:true, - filter(event){ - return (get.type(event.card)=='trick'&&event.card.isCard); + jizhi: { + audio: 2, + audioname: ["jianyong"], + trigger: { player: "useCard" }, + frequent: true, + preHidden: true, + filter(event) { + return get.type(event.card) == "trick" && event.card.isCard; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.draw(); }, - ai:{ - threaten:1.4, - noautowuxie:true, - } - }, - xinjizhi:{ - audio:'jizhi', - trigger:{player:'useCard'}, - frequent:true, - // alter:true, - filter(event){ - if(get.type(event.card)=='delay') return false; - return (get.type(event.card,'trick')=='trick'&&event.cards[0]&&event.cards[0]==event.card); + ai: { + threaten: 1.4, + noautowuxie: true, }, - async content(event, trigger, player){ + }, + xinjizhi: { + audio: "jizhi", + trigger: { player: "useCard" }, + frequent: true, + // alter:true, + filter(event) { + if (get.type(event.card) == "delay") return false; + return ( + get.type(event.card, "trick") == "trick" && + event.cards[0] && + event.cards[0] == event.card + ); + }, + async content(event, trigger, player) { player.draw(); }, - ai:{ - threaten:1.4, - noautowuxie:true, + ai: { + threaten: 1.4, + noautowuxie: true, }, }, - qicai:{ - mod:{ - targetInRange(card,player,target,now){ - if(['trick','delay'].includes(get.type(card))) return true; - } + qicai: { + mod: { + targetInRange(card, player, target, now) { + if (["trick", "delay"].includes(get.type(card))) return true; + }, }, }, - xinqicai:{ + xinqicai: { // alter:true, - mod:{ - targetInRange(card,player,target,now){ - if(['trick','delay'].includes(get.type(card))) return true; - } + mod: { + targetInRange(card, player, target, now) { + if (["trick", "delay"].includes(get.type(card))) return true; + }, }, }, - xinzhiheng:{ - audio:'zhiheng', - mod:{ - aiOrder(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(card)>=8)){ - return 8-get.value(card); + usable: 1, + position: "he", + filterCard: true, + selectCard: [1, Infinity], + check(card) { + const player = _status.event.player; + if ( + get.is.altered("xinzhiheng") && + get.position(card) == "h" && + !player.countCards("h", (card) => get.value(card) >= 8) + ) { + return 8 - get.value(card); } - return 6-get.value(card) + return 6 - get.value(card); }, - delay:0, - async content(event,trigger,player){ - if(!player.hasSkill('xinzhiheng_delay')) game.asyncDelayx(); + delay: 0, + async content(event, trigger, player) { + if (!player.hasSkill("xinzhiheng_delay")) game.asyncDelayx(); player.draw(event.cards.length); }, - group:'xinzhiheng_draw', - subSkill:{ - draw:{ - trigger:{player:'loseEnd'}, - silent:true, - filter(event,player){ - if(event.getParent(2).skill!='xinzhiheng') return false; - if(!get.is.altered('xinzhiheng')) return false; - if(player.countCards('h')) return false; - for(let i=0;iget.value(i)>Math.max(6,9-player.hp),'he')) return 1; + ai: { + order(item, player) { + if (player.hasCard((i) => get.value(i) > Math.max(6, 9 - player.hp), "he")) return 1; return 10; }, - result:{ - player:1 + result: { + player: 1, }, - nokeep:true, - skillTagFilter(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'); + nokeep: true, + skillTagFilter(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 + threaten: 1.55, }, }, - zhiheng:{ - audio:2, - audioname:['gz_jun_sunquan'], - mod:{ - aiOrder(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)0) return false; - if(event.player.group!='wu') return false; + trigger: { target: "taoBegin" }, + zhuSkill: true, + forced: true, + filter(event, player) { + if (get.is.altered("xinjiuyuan")) return false; + if (event.player == player) return false; + if (!player.hasZhuSkill("jiuyuan")) return false; + if (player.hp > 0) return false; + if (event.player.group != "wu") return false; return true; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.recover(); }, - global:'xinjiuyuan2', + global: "xinjiuyuan2", }, - xinjiuyuan2:{ - audio:'jiuyuan', - forceaudio:true, - trigger:{player:'taoBegin'}, - filter(event,player){ - if(!get.is.altered('xinjiuyuan')) return false; - if(player.group!='wu') return false; - return game.hasPlayer(target=>{ - return player!=target&&target.isDamaged()&&target.hp { + return ( + player != target && + target.isDamaged() && + target.hp < player.hp && + target.hasZhuSkill("xinjiuyuan", player) + ); }); }, - direct:true, - async content(event,trigger,player){ - event.list=game.filterPlayer(target=>player!=target&&target.isDamaged()&&target.hp0){ - const current=event.list.shift(); - event.current=current; - const {result:{bool}}=await player.chooseBool(get.prompt('xinjiuyuan',current)).set('choice',get.attitude(player,current)>0); - if(bool){ - player.logSkill('xinjiuyuan',event.current); + direct: true, + async content(event, trigger, player) { + event.list = game + .filterPlayer( + (target) => + player != target && + target.isDamaged() && + target.hp < player.hp && + target.hasZhuSkill("xinjiuyuan", player) + ) + .sortBySeat(); + while (event.list.length > 0) { + const current = event.list.shift(); + event.current = current; + const { + result: { bool }, + } = await player + .chooseBool(get.prompt("xinjiuyuan", current)) + .set("choice", get.attitude(player, current) > 0); + if (bool) { + player.logSkill("xinjiuyuan", event.current); event.current.recover(); player.draw(); } } - } - }, - qixi:{ - audio:2, - audioname:['re_ganning','re_heqi'], - enable:'chooseToUse', - filterCard(card){ - return get.color(card)=='black'; }, - position:'hes', - viewAs:{name:'guohe'}, - viewAsFilter(player){ - if(!player.countCards('hes',{color:'black'})) return false; - }, - prompt:'将一张黑色牌当过河拆桥使用', - check(card){return 4-get.value(card)} }, - keji:{ - audio:2, - audioname:['re_lvmeng','sp_lvmeng'], - trigger:{player:'phaseDiscardBefore'}, - frequent(event,player){ + qixi: { + audio: 2, + audioname: ["re_ganning", "re_heqi"], + enable: "chooseToUse", + filterCard(card) { + return get.color(card) == "black"; + }, + position: "hes", + viewAs: { name: "guohe" }, + viewAsFilter(player) { + if (!player.countCards("hes", { color: "black" })) return false; + }, + prompt: "将一张黑色牌当过河拆桥使用", + check(card) { + return 4 - get.value(card); + }, + }, + keji: { + audio: 2, + audioname: ["re_lvmeng", "sp_lvmeng"], + trigger: { player: "phaseDiscardBefore" }, + frequent(event, player) { return player.needsToDiscard(); }, - filter(event,player){ - if(player.getHistory('skipped').includes('phaseUse')) return true; - const history=player.getHistory('useCard').concat(player.getHistory('respond')); - for(let i=0;i=player.hp-1) return -1; - if(player.hp<3) return -1; + result: { + player(player) { + if (player.countCards("h") >= player.hp - 1) return -1; + if (player.hp < 3) return -1; return 1; - } - } - } + }, + }, + }, }, - yingzi:{ - audio:2, - audioname:['sp_lvmeng'], - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - filter(event,player){ + yingzi: { + audio: 2, + audioname: ["sp_lvmeng"], + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + filter(event, player) { return !event.numFixed; }, - async content(event,trigger,player){ + async content(event, trigger, player) { trigger.num++; }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - fanjian:{ - audio:2, - enable:'phaseUse', - usable:1, - filter(event,player){ - return player.countCards('h')>0; + fanjian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return player.countCards("h") > 0; }, - filterTarget(card,player,target){ - return player!=target; + filterTarget(card, player, target) { + return player != target; }, - async content(event,trigger,player){ - const target=event.target; - const control=await target.chooseControl('heart2','diamond2','club2','spade2').set('ai',event=>{ - switch(Math.floor(Math.random()*6)){ - case 0:return 'heart2'; - case 1:case 4:case 5:return 'diamond2'; - case 2:return 'club2'; - case 3:return 'spade2'; - } - }) - .forResultControl(); - game.log(target,'选择了'+get.translation(control)); - event.choice=control; - target.chat('我选'+get.translation(event.choice)); - const {result:{bool,cards}}=await target.gainPlayerCard(player,true,'h'); - if(bool&&get.suit(cards[0],player)+'2'!=event.choice) target.damage('nocard'); + async content(event, trigger, player) { + const target = event.target; + const control = await target + .chooseControl("heart2", "diamond2", "club2", "spade2") + .set("ai", (event) => { + switch (Math.floor(Math.random() * 6)) { + case 0: + return "heart2"; + case 1: + case 4: + case 5: + return "diamond2"; + case 2: + return "club2"; + case 3: + return "spade2"; + } + }) + .forResultControl(); + game.log(target, "选择了" + get.translation(control)); + event.choice = control; + target.chat("我选" + get.translation(event.choice)); + const { + result: { bool, cards }, + } = await target.gainPlayerCard(player, true, "h"); + if (bool && get.suit(cards[0], player) + "2" != event.choice) target.damage("nocard"); + }, + ai: { + order: 1, + result: { + target(player, target) { + const eff = get.damageEffect(target, player); + if (eff >= 0) return 1 + eff; + let value = 0, + i; + const cards = player.getCards("h"); + for (i = 0; i < cards.length; i++) value += get.value(cards[i]); + value /= player.countCards("h"); + if (target.hp == 1) return Math.min(0, value - 7); + return Math.min(0, value - 5); + }, + }, }, - ai:{ - order:1, - result:{ - target(player,target){ - const eff=get.damageEffect(target,player); - if(eff>=0) return 1+eff; - let value=0,i; - const cards=player.getCards('h'); - for(i=0;i0; + guose: { + audio: 2, + filter(event, player) { + return player.countCards("hes", { suit: "diamond" }) > 0; }, - enable:'chooseToUse', - filterCard(card){ - return get.suit(card)=='diamond'; + enable: "chooseToUse", + filterCard(card) { + return get.suit(card) == "diamond"; + }, + position: "hes", + viewAs: { name: "lebu" }, + prompt: "将一张方片牌当乐不思蜀使用", + check(card) { + return 6 - get.value(card); + }, + ai: { + threaten: 1.5, }, - position:'hes', - viewAs:{name:'lebu'}, - prompt:'将一张方片牌当乐不思蜀使用', - check(card){return 6-get.value(card)}, - ai:{ - threaten:1.5 - } }, - liuli:{ - audio:2, - audioname:['re_daqiao','daxiaoqiao'], - trigger:{target:'useCardToTarget'}, - preHidden:true, - filter(event,player){ - if(event.card.name!='sha') return false; - if(player.countCards('he')==0) return false; - return game.hasPlayer(current=>{ - return player.inRange(current)&¤t!=event.player&& - current!=player&&lib.filter.targetEnabled(event.card,event.player,current); + liuli: { + audio: 2, + audioname: ["re_daqiao", "daxiaoqiao"], + trigger: { target: "useCardToTarget" }, + preHidden: true, + filter(event, player) { + if (event.card.name != "sha") return false; + if (player.countCards("he") == 0) return false; + return game.hasPlayer((current) => { + return ( + player.inRange(current) && + current != event.player && + current != player && + lib.filter.targetEnabled(event.card, event.player, current) + ); }); }, - async cost(event,trigger,player){ - event.result = await player.chooseCardTarget({ - position:'he', - filterCard:lib.filter.cardDiscardable, - filterTarget:(card,player,target)=>{ - const trigger=_status.event; - if(player.inRange(target)&&target!=trigger.source){ - if(lib.filter.targetEnabled(trigger.card,trigger.source,target)) return true; - } - return false; - }, - ai1:card=>get.unuseful(card)+9, - ai2:target=>{ - if(_status.event.player.countCards('h','shan')){ - return -get.attitude(_status.event.player,target); - } - if(get.attitude(_status.event.player,target)<5){ - return 6-get.attitude(_status.event.player,target); - } - if(_status.event.player.hp==1&&player.countCards('h','shan')==0){ - return 10-get.attitude(_status.event.player,target); - } - if(_status.event.player.hp==2&&player.countCards('h','shan')==0){ - return 8-get.attitude(_status.event.player,target); - } - return -1; - }, - prompt:get.prompt('liuli'), - prompt2:'弃置一张牌,将此【杀】转移给攻击范围内的一名其他角色', - source:trigger.player, - card:trigger.card, - }) - .setHiddenSkill(event.name).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseCardTarget({ + position: "he", + filterCard: lib.filter.cardDiscardable, + filterTarget: (card, player, target) => { + const trigger = _status.event; + if (player.inRange(target) && target != trigger.source) { + if (lib.filter.targetEnabled(trigger.card, trigger.source, target)) + return true; + } + return false; + }, + ai1: (card) => get.unuseful(card) + 9, + ai2: (target) => { + if (_status.event.player.countCards("h", "shan")) { + return -get.attitude(_status.event.player, target); + } + if (get.attitude(_status.event.player, target) < 5) { + return 6 - get.attitude(_status.event.player, target); + } + if (_status.event.player.hp == 1 && player.countCards("h", "shan") == 0) { + return 10 - get.attitude(_status.event.player, target); + } + if (_status.event.player.hp == 2 && player.countCards("h", "shan") == 0) { + return 8 - get.attitude(_status.event.player, target); + } + return -1; + }, + prompt: get.prompt("liuli"), + prompt2: "弃置一张牌,将此【杀】转移给攻击范围内的一名其他角色", + source: trigger.player, + card: trigger.card, + }) + .setHiddenSkill(event.name) + .forResult(); }, - async content(event,trigger,player){ + async content(event, trigger, player) { const target = event.targets[0]; - player.logSkill(event.name,target); + player.logSkill(event.name, target); player.discard(event.cards); - const evt=trigger.getParent(); + const evt = trigger.getParent(); evt.triggeredTargets2.remove(player); evt.targets.remove(player); evt.targets.push(target); }, - ai:{ - effect:{ - target(card,player,target){ - if(target.countCards('he')==0) return; - if(card.name!='sha') return; - let min=1; - const friend=get.attitude(player,target)>0; - const vcard={name:'shacopy',nature:card.nature,suit:card.suit}; - const players=game.filterPlayer(); - for(let i=0;i0){ - if(!player.canUse(card,players[0])){ - return [0,0.1]; + ai: { + effect: { + target(card, player, target) { + if (target.countCards("he") == 0) return; + if (card.name != "sha") return; + let min = 1; + const friend = get.attitude(player, target) > 0; + const vcard = { name: "shacopy", nature: card.nature, suit: card.suit }; + const players = game.filterPlayer(); + for (let i = 0; i < players.length; i++) { + if ( + player != players[i] && + get.attitude(target, players[i]) < 0 && + target.canUse(card, players[i]) + ) { + if (!friend) return 0; + if (get.effect(players[i], vcard, player, player) > 0) { + if (!player.canUse(card, players[0])) { + return [0, 0.1]; } - min=0; + min = 0; } } } return min; - } - } - } + }, + }, + }, }, - qianxun:{ - mod:{ - targetEnabled(card,player,target,now){ - if(card.name=='shunshou'||card.name=='lebu') return false; - } + qianxun: { + mod: { + targetEnabled(card, player, target, now) { + if (card.name == "shunshou" || card.name == "lebu") return false; + }, }, - audio:2, + audio: 2, }, - lianying:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + lianying: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - frequent:true, - filter(event,player){ - if(player.countCards('h')) return false; - const evt=event.getl(player); - return evt&&evt.player==player&&evt.hs&&evt.hs.length>0; + frequent: true, + filter(event, player) { + if (player.countCards("h")) return false; + const evt = event.getl(player); + return evt && evt.player == player && evt.hs && evt.hs.length > 0; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.draw(); }, - ai:{ - threaten:0.8, - effect:{ - target(card){ - if(card.name=='guohe'||card.name=='liuxinghuoyu') return 0.5; + ai: { + threaten: 0.8, + effect: { + target(card) { + if (card.name == "guohe" || card.name == "liuxinghuoyu") return 0.5; + }, + }, + noh: true, + skillTagFilter(player, tag) { + if (tag == "noh") { + if (player.countCards("h") != 1) return false; } }, - noh:true, - skillTagFilter(player,tag){ - if(tag=='noh'){ - if(player.countCards('h')!=1) return false; - } - } - } - }, - xiaoji:{ - audio:2, - audioname:['sp_sunshangxiang','re_sunshangxiang'], - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], }, - frequent:true, - getIndex(event, player){ - const evt=event.getl(player); + }, + xiaoji: { + audio: 2, + audioname: ["sp_sunshangxiang", "re_sunshangxiang"], + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + frequent: true, + getIndex(event, player) { + const evt = event.getl(player); if (evt && evt.player === player && evt.es) return evt.es.length; return false; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.draw(2); }, - ai:{ - noe:true, - reverseEquip:true, - effect:{ - target(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } - } - } - }, - jieyin:{ - audio:2, - enable:'phaseUse', - filterCard:true, - usable:1, - selectCard:2, - check(card){ - const player=get.owner(card); - if(player.countCards('h')>player.hp) return 8-get.value(card); - if(player.hp=target.maxHp) return false; - if(target==player) return false; + }, + jieyin: { + audio: 2, + enable: "phaseUse", + filterCard: true, + usable: 1, + selectCard: 2, + check(card) { + const player = get.owner(card); + if (player.countCards("h") > player.hp) return 8 - get.value(card); + if (player.hp < player.maxHp) return 6 - get.value(card); + return 4 - get.value(card); + }, + filterTarget(card, player, target) { + if (!target.hasSex("male")) return false; + if (target.hp >= target.maxHp) return false; + if (target == player) return false; return true; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.recover(); event.target.recover(); }, - ai:{ - order:5.5, - result:{ - player(player){ - if(player.hpplayer.hp) return 0 + ai: { + order: 5.5, + result: { + player(player) { + if (player.hp < player.maxHp) return 4; + if (player.countCards("h") > player.hp) return 0; return -1; }, - target:4 + target: 4, }, - threaten:2, - } + threaten: 2, + }, }, - xinjieyin:{ - group:['xinjieyin_old','xinjieyin_new'], + xinjieyin: { + group: ["xinjieyin_old", "xinjieyin_new"], // alter:true, - subSkill:{ - new:{ - audio:'jieyin', - enable:'phaseUse', - filterCard:true, - usable:1, - position:'he', - filter(event,player){ - if(!get.is.altered('xinjieyin')) return false; - return player.countCards('he')>0; + subSkill: { + new: { + audio: "jieyin", + enable: "phaseUse", + filterCard: true, + usable: 1, + position: "he", + filter(event, player) { + if (!get.is.altered("xinjieyin")) return false; + return player.countCards("he") > 0; }, - check(card){ - const player=_status.event.player; - if(get.position(card)=='e'){ - const subtype=get.subtype(card); - if(!game.hasPlayer(current=>{ - return current!=player&¤t.hp!=player.hp&&get.attitude(player,current)>0&&!current.countCards('e',{subtype}); - })){ + check(card) { + const player = _status.event.player; + if (get.position(card) == "e") { + const subtype = get.subtype(card); + if ( + !game.hasPlayer((current) => { + return ( + current != player && + current.hp != player.hp && + get.attitude(player, current) > 0 && + !current.countCards("e", { subtype }) + ); + }) + ) { return 0; } // 你还想我兼容{subtype:subtype}?不可能! - if(player.countCards('h',{subtype})) return 20-get.value(card); - return 10-get.value(card); - } - else{ - if(player.countCards('e')) return 0; - if(player.countCards('h',{type:'equip'})) return 0; - return 8-get.value(card); + if (player.countCards("h", { subtype })) return 20 - get.value(card); + return 10 - get.value(card); + } else { + if (player.countCards("e")) return 0; + if (player.countCards("h", { type: "equip" })) return 0; + return 8 - get.value(card); } }, - filterTarget(card,player,target){ - if(!target.hasSex('male')) return false; - card=ui.selected.cards[0]; - if(!card) return false; - if(get.position(card)=='e'&&target.countCards('e',{subtype:get.subtype(card)})) return false; + filterTarget(card, player, target) { + if (!target.hasSex("male")) return false; + card = ui.selected.cards[0]; + if (!card) return false; + if ( + get.position(card) == "e" && + target.countCards("e", { subtype: get.subtype(card) }) + ) + return false; return true; }, - discard:false, - delay:0, - lose:false, - async content(event,trigger,player){ - const {cards,target}=event; - if(get.position(cards[0])=='e'){ - player.$give(cards,target); + discard: false, + delay: 0, + lose: false, + async content(event, trigger, player) { + const { cards, target } = event; + if (get.position(cards[0]) == "e") { + player.$give(cards, target); target.equip(cards[0]); - } - else{ + } else { player.discard(cards); } - if(player.hp>target.hp){ + if (player.hp > target.hp) { player.draw(); - if(target.isDamaged()) target.recover(); - } - else if(player.hp{ - const es=player.getCards('e'); - for(let i=0;i { + const es = player.getCards("e"); + for (let i = 0; i < es.length; i++) { + if (player.countCards("h", { subtype: get.subtype(es[i]) })) + return true; } return false; - } - if(player.hptarget.hp){ - if(target.isHealthy()){ - if(!player.needsToDiscard(1)||goon()) return 0.1; + if (player.hp > target.hp) { + if (target.isHealthy()) { + if (!player.needsToDiscard(1) || goon()) return 0.1; return 0; } return 1; } return 0; - } - } - } + }, + }, + }, }, - old:{ - audio:'jieyin', - enable:'phaseUse', - filterCard:true, - usable:1, - selectCard:2, - filter(event,player){ - if(get.is.altered('xinjieyin')) return false; - return player.countCards('h')>=2; + old: { + audio: "jieyin", + enable: "phaseUse", + filterCard: true, + usable: 1, + selectCard: 2, + filter(event, player) { + if (get.is.altered("xinjieyin")) return false; + return player.countCards("h") >= 2; }, - check(card){ - const player=get.owner(card); - if(player.countCards('h')>player.hp) return 8-get.value(card); - if(player.hp player.hp) return 8 - get.value(card); + if (player.hp < player.maxHp) return 6 - get.value(card); + return 4 - get.value(card); }, - filterTarget(card,player,target){ - if(!target.hasSex('male')) return false; - if(target.hp>=target.maxHp) return false; - if(target==player) return false; + filterTarget(card, player, target) { + if (!target.hasSex("male")) return false; + if (target.hp >= target.maxHp) return false; + if (target == player) return false; return true; }, - async content(event,trigger,player){ + async content(event, trigger, player) { player.recover(); event.target.recover(); }, - ai:{ - order:5.5, - result:{ - player(player){ - if(player.hpplayer.hp) return 0 + ai: { + order: 5.5, + result: { + player(player) { + if (player.hp < player.maxHp) return 4; + if (player.countCards("h") > player.hp) return 0; return -1; }, - target:4 - } - } - } + target: 4, + }, + }, + }, + }, + ai: { + threaten: 2.3, }, - ai:{ - threaten:2.3 - } }, - qingnang:{ - audio:2, - enable:'phaseUse', - filterCard:true, - usable:1, - check(card){ - return 9-get.value(card); + qingnang: { + audio: 2, + enable: "phaseUse", + filterCard: true, + usable: 1, + check(card) { + return 9 - get.value(card); }, - filterTarget(card,player,target){ - if(target.hp>=target.maxHp) return false; + filterTarget(card, player, target) { + if (target.hp >= target.maxHp) return false; return true; }, - async content(event,trigger,player){ + async content(event, trigger, player) { event.target.recover(); }, - ai:{ - order:9, - result:{ - target(player,target){ - if(target.hp==1) return 5; - if(player==target&&player.countCards('h')>player.hp) return 5; + ai: { + order: 9, + result: { + target(player, target) { + if (target.hp == 1) return 5; + if (player == target && player.countCards("h") > player.hp) return 5; return 2; - } + }, }, - threaten:2 - } + threaten: 2, + }, }, - jijiu:{ - mod:{ - aiValue(player,card,num){ - if(get.name(card)!='tao'&&get.color(card)!='red') return; - const cards=player.getCards('hs',card=>get.name(card)=='tao'||get.color(card)=='red'); - cards.sort((a,b)=>(get.name(a)=='tao'?1:2)-(get.name(b)=='tao'?1:2)); - var geti=()=>{ - if(cards.includes(card)) cards.indexOf(card); + jijiu: { + mod: { + aiValue(player, card, num) { + if (get.name(card) != "tao" && get.color(card) != "red") return; + const cards = player.getCards( + "hs", + (card) => get.name(card) == "tao" || get.color(card) == "red" + ); + cards.sort((a, b) => (get.name(a) == "tao" ? 1 : 2) - (get.name(b) == "tao" ? 1 : 2)); + var geti = () => { + if (cards.includes(card)) cards.indexOf(card); return cards.length; }; - return Math.max(num,[6.5,4,3,2][Math.min(geti(),2)]); + return Math.max(num, [6.5, 4, 3, 2][Math.min(geti(), 2)]); }, - aiUseful(){ - return lib.skill.kanpo.mod.aiValue.apply(this,arguments); + aiUseful() { + return lib.skill.kanpo.mod.aiValue.apply(this, arguments); }, }, - locked:false, - audio:2, - audioname:['re_huatuo'], - enable:'chooseToUse', - viewAsFilter(player){ - return player!=_status.currentPhase&&player.countCards('hes',{color:'red'})>0; + locked: false, + audio: 2, + audioname: ["re_huatuo"], + enable: "chooseToUse", + viewAsFilter(player) { + return player != _status.currentPhase && player.countCards("hes", { color: "red" }) > 0; }, - filterCard(card){ - return get.color(card)=='red'; + filterCard(card) { + return get.color(card) == "red"; + }, + position: "hes", + viewAs: { name: "tao" }, + prompt: "将一张红色牌当桃使用", + check(card) { + return 15 - get.value(card); + }, + ai: { + threaten: 1.5, }, - position:'hes', - viewAs:{name:'tao'}, - prompt:'将一张红色牌当桃使用', - check(card){return 15-get.value(card)}, - ai:{ - threaten:1.5, - } }, - wushuang:{ - shaRelated:true, - audio:2, - audioname:['re_lvbu','shen_lvbu','lvlingqi'], - forced:true, - locked:true, - group:['wushuang1','wushuang2'], - preHidden:['wushuang1','wushuang2'], + wushuang: { + shaRelated: true, + audio: 2, + audioname: ["re_lvbu", "shen_lvbu", "lvlingqi"], + forced: true, + locked: true, + group: ["wushuang1", "wushuang2"], + preHidden: ["wushuang1", "wushuang2"], }, - wushuang1:{ - audio:'wushuang', - audioname:['re_lvbu','shen_lvbu','lvlingqi'], - trigger:{player:'useCardToPlayered'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'&&!event.getParent().directHit.includes(event.target); + wushuang1: { + audio: "wushuang", + audioname: ["re_lvbu", "shen_lvbu", "lvlingqi"], + trigger: { player: "useCardToPlayered" }, + forced: true, + filter(event, player) { + return event.card.name == "sha" && !event.getParent().directHit.includes(event.target); }, //priority:-1, - logTarget:'target', - async content(event,trigger,player){ - const id=trigger.target.playerid; - const map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + logTarget: "target", + async content(event, trigger, player) { + const id = trigger.target.playerid; + const map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; - } - else{ - map[id].shanRequired=2; + } else { + map[id].shanRequired = 2; } }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(arg.card.name!='sha'||arg.target.countCards('h','shan')>1) return false; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if (arg.card.name != "sha" || arg.target.countCards("h", "shan") > 1) return false; }, }, }, - wushuang2:{ - audio:'wushuang', - audioname:['re_lvbu','shen_lvbu','lvlingqi'], - trigger:{player:'useCardToPlayered',target:'useCardToTargeted'}, - forced:true, - logTarget(trigger,player){ - return player==trigger.player?trigger.target:trigger.player + wushuang2: { + audio: "wushuang", + audioname: ["re_lvbu", "shen_lvbu", "lvlingqi"], + trigger: { player: "useCardToPlayered", target: "useCardToTargeted" }, + forced: true, + logTarget(trigger, player) { + return player == trigger.player ? trigger.target : trigger.player; }, - filter(event,player){ - return event.card.name=='juedou'; + filter(event, player) { + return event.card.name == "juedou"; }, //priority:-1, - async content(event,trigger,player){ - const id=(player==trigger.player?trigger.target:trigger.player)['playerid']; - const idt=trigger.target.playerid; - const map=trigger.getParent().customArgs; - if(!map[idt]) map[idt]={}; - if(!map[idt].shaReq) map[idt].shaReq={}; - if(!map[idt].shaReq[id]) map[idt].shaReq[id]=1; + async content(event, trigger, player) { + const id = (player == trigger.player ? trigger.target : trigger.player)["playerid"]; + const idt = trigger.target.playerid; + const map = trigger.getParent().customArgs; + if (!map[idt]) map[idt] = {}; + if (!map[idt].shaReq) map[idt].shaReq = {}; + if (!map[idt].shaReq[id]) map[idt].shaReq[id] = 1; map[idt].shaReq[id]++; }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(arg.card.name!='juedou'||Math.floor(arg.target.countCards('h','sha')/2)>player.countCards('h','sha')) return false; - } - } - }, - zhanshen:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - skillAnimation:true, - animationColor:'gray', - filter(event,player){ - return player.isDamaged()&&game.dead.filter(target=>target.isFriendOf(player)).length>0 - }, - async content(event,trigger,player){ - player.awakenSkill('zhanshen'); - const cards=player.getEquips(1); - if(cards.length) player.discard(cards); - player.loseMaxHp(); - player.addSkills(['mashu','shenji']); - }, - derivation:['mashu','shenji'], - }, - shenji:{ - mod:{ - selectTarget(card,player,range){ - if(range[1]==-1) return; - if(card.name=='sha') range[1]+=2; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if ( + arg.card.name != "juedou" || + Math.floor(arg.target.countCards("h", "sha") / 2) > player.countCards("h", "sha") + ) + return false; }, - cardUsable(card,player,num){ - if(card.name=='sha') return num+1; - } }, }, - lijian:{ - audio:2, - audioname:['re_diaochan'], - enable:'phaseUse', - usable:1, - filter(event,player){ - return game.countPlayer(current=>current!=player&¤t.hasSex('male'))>1; + zhanshen: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + skillAnimation: true, + animationColor: "gray", + filter(event, player) { + return ( + player.isDamaged() && + game.dead.filter((target) => target.isFriendOf(player)).length > 0 + ); }, - check(card){return 10-get.value(card)}, - filterCard:true, - position:'he', - filterTarget(card,player,target){ - if(player==target) return false; - if(!target.hasSex('male')) return false; - if(ui.selected.targets.length==1){ - return target.canUse({name:'juedou'},ui.selected.targets[0]); + async content(event, trigger, player) { + player.awakenSkill("zhanshen"); + const cards = player.getEquips(1); + if (cards.length) player.discard(cards); + player.loseMaxHp(); + player.addSkills(["mashu", "shenji"]); + }, + derivation: ["mashu", "shenji"], + }, + shenji: { + mod: { + selectTarget(card, player, range) { + if (range[1] == -1) return; + if (card.name == "sha") range[1] += 2; + }, + cardUsable(card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + }, + lijian: { + audio: 2, + audioname: ["re_diaochan"], + enable: "phaseUse", + usable: 1, + filter(event, player) { + return game.countPlayer((current) => current != player && current.hasSex("male")) > 1; + }, + check(card) { + return 10 - get.value(card); + }, + filterCard: true, + position: "he", + filterTarget(card, player, target) { + if (player == target) return false; + if (!target.hasSex("male")) return false; + if (ui.selected.targets.length == 1) { + return target.canUse({ name: "juedou" }, ui.selected.targets[0]); } return true; }, - targetprompt:['先出杀','后出杀'], - selectTarget:2, - multitarget:true, - async content(event,trigger,player){ - const useCardEvent=event.targets[1].useCard({name:'juedou',isCard:true},'nowuxie',event.targets[0],'noai'); - useCardEvent.animate=false; + targetprompt: ["先出杀", "后出杀"], + selectTarget: 2, + multitarget: true, + async content(event, trigger, player) { + const useCardEvent = event.targets[1].useCard( + { name: "juedou", isCard: true }, + "nowuxie", + event.targets[0], + "noai" + ); + useCardEvent.animate = false; game.asyncDelay(0.5); }, - ai:{ - order:8, - result:{ - target(player,target){ - if(ui.selected.targets.length==0){ + ai: { + order: 8, + result: { + target(player, target) { + if (ui.selected.targets.length == 0) { return -3; + } else { + return get.effect(target, { name: "juedou" }, ui.selected.targets[0], target); } - else{ - return get.effect(target,{name:'juedou'},ui.selected.targets[0],target); - } - } + }, }, - expose:0.4, - threaten:3, - } + expose: 0.4, + threaten: 3, + }, }, - biyue:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - preHidden:true, - async content(event,trigger,player){ + biyue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + preHidden: true, + async content(event, trigger, player) { player.draw(); }, }, - xinbiyue:{ - audio:'biyue', - trigger:{player:'phaseJieshuBegin'}, - frequent:true, + xinbiyue: { + audio: "biyue", + trigger: { player: "phaseJieshuBegin" }, + frequent: true, // alter:true, - async content(event,trigger,player){ + async content(event, trigger, player) { player.draw(); }, }, - yaowu:{ - trigger:{player:'damageBegin3'}, + yaowu: { + trigger: { player: "damageBegin3" }, //priority:1, - audio:2, - filter(event){ - if(event.card&&(event.card.name=='sha')){ - if(get.color(event.card)=='red') return true; + audio: 2, + filter(event) { + if (event.card && event.card.name == "sha") { + if (get.color(event.card) == "red") return true; } return false; }, - forced:true, - check(){return false;}, - async content(event,trigger,player){ + forced: true, + check() { + return false; + }, + async content(event, trigger, player) { trigger.source.chooseDrawRecover(true); }, - ai:{ - effect:{ - target(card,player,target,current){ - if(card.name=='sha'&&(get.color(card)=='red')){ - return [1,-2]; + ai: { + halfneg: true, + effect: { + target(card, player, target, current) { + if (card.name == "sha" && get.color(card) == "red") { + return [1, -2]; } - } - } - } + }, + }, + }, }, - "new_jiangchi":{ - audio:2, - trigger:{ - player:"phaseDrawEnd", + new_jiangchi: { + audio: 2, + trigger: { + player: "phaseDrawEnd", }, - async cost(event,trigger,player){ - const list=['弃牌','摸牌','cancel2']; - if(!player.countCards('he')) list.remove('弃牌'); - const control=await player.chooseControl(list,()=>{ - const player=_status.event.player; - if(list.includes('弃牌')){ - if(player.countCards('h')>3&&player.countCards('h','sha')>1){ - return '弃牌'; + async cost(event, trigger, player) { + const list = ["弃牌", "摸牌", "cancel2"]; + if (!player.countCards("he")) list.remove("弃牌"); + const control = await player + .chooseControl(list, () => { + const player = _status.event.player; + if (list.includes("弃牌")) { + if (player.countCards("h") > 3 && player.countCards("h", "sha") > 1) { + return "弃牌"; + } + if (player.countCards("h", "sha") > 2) { + return "弃牌"; + } } - if(player.countCards('h','sha')>2){ - return '弃牌'; + if (!player.countCards("h", "sha")) { + return "摸牌"; } - } - if(!player.countCards('h','sha')){ - return '摸牌'; - } - return 'cancel2'; - }) - .set('prompt',get.prompt2('new_jiangchi')) - .forResultControl(); - if (control === 'cancel2') event.result = {bool: false}; - else event.result = { - bool: true, - cost_data: control - }; + return "cancel2"; + }) + .set("prompt", get.prompt2("new_jiangchi")) + .forResultControl(); + if (control === "cancel2") event.result = { bool: false }; + else + event.result = { + bool: true, + cost_data: control, + }; }, - async content(event,trigger,player){ + async content(event, trigger, player) { const control = event.cost_data; - if(control=='弃牌'){ - player.chooseToDiscard(true,'he'); - player.addTempSkill('jiangchi2','phaseUseEnd'); - } - else if(control=='摸牌'){ + if (control == "弃牌") { + player.chooseToDiscard(true, "he"); + player.addTempSkill("jiangchi2", "phaseUseEnd"); + } else if (control == "摸牌") { player.draw(); - player.addTempSkill('new_jiangchi3','phaseEnd'); + player.addTempSkill("new_jiangchi3", "phaseEnd"); } }, }, - new_jiangchi3:{ - mod:{ - cardEnabled(card){ - if(card.name=='sha') return false; + new_jiangchi3: { + mod: { + cardEnabled(card) { + if (card.name == "sha") return false; }, - cardRespondable(card){ - if(card.name=='sha') return false; + cardRespondable(card) { + if (card.name == "sha") return false; }, - ignoredHandcard(card,player){ - if(get.name(card)=='sha') return true; + ignoredHandcard(card, player) { + if (get.name(card) == "sha") return true; }, - cardDiscardable(card,player,name){ - if(name=='phaseDiscard'&&get.name(card)=='sha') return false; + cardDiscardable(card, player, name) { + if (name == "phaseDiscard" && get.name(card) == "sha") return false; }, }, }, - xinfu_jijie:{ - enable:"phaseUse", - usable:1, - audio:2, - async content(event,trigger,player){ - const card=get.bottomCards()[0]; + xinfu_jijie: { + enable: "phaseUse", + usable: 1, + audio: 2, + async content(event, trigger, player) { + const card = get.bottomCards()[0]; game.cardsGotoOrdering(card); - event.card=card; - const {result:{bool,targets}}=await player.chooseTarget(true).set('ai',target=>{ - let att=get.attitude(_status.event.player,target); - if(_status.event.du){ - if(target.hasSkillTag('nodu')) return 0.5; - return -att; - } - if(att>0){ - if(_status.event.player!=target) att+=2; - return att+Math.max(0,5-target.countCards('h')); - } - return att; - }).set('du',event.card.name=='du').set('createDialog',[ - '机捷:选择一名角色获得此牌', - [card] - ]); - if(bool){ - const target=targets[0]; - player.line(target,'green'); - const gainEvent=target.gain(card,'draw'); - gainEvent.giver=player; + event.card = card; + const { + result: { bool, targets }, + } = await player + .chooseTarget(true) + .set("ai", (target) => { + let att = get.attitude(_status.event.player, target); + if (_status.event.du) { + if (target.hasSkillTag("nodu")) return 0.5; + return -att; + } + if (att > 0) { + if (_status.event.player != target) att += 2; + return att + Math.max(0, 5 - target.countCards("h")); + } + return att; + }) + .set("du", event.card.name == "du") + .set("createDialog", ["机捷:选择一名角色获得此牌", [card]]); + if (bool) { + const target = targets[0]; + player.line(target, "green"); + const gainEvent = target.gain(card, "draw"); + gainEvent.giver = player; } }, - ai:{ - order:7.2, - result:{ - player:1, + ai: { + order: 7.2, + result: { + player: 1, }, }, }, - xinfu_jiyuan:{ - trigger:{ - global:['dying','gainAfter','loseAsyncAfter'], + xinfu_jiyuan: { + trigger: { + global: ["dying", "gainAfter", "loseAsyncAfter"], }, - audio:2, - getIndex:function(event, player){ - if (event.name !== 'loseAsync') return [event.player]; - else return game.filterPlayer(current => current != player && event.getg(current).length > 0).sortBySeat(); + audio: 2, + getIndex: function (event, player) { + if (event.name !== "loseAsync") return [event.player]; + else + return game + .filterPlayer((current) => current != player && event.getg(current).length > 0) + .sortBySeat(); }, - filter(event, player, triggername, target){ + filter(event, player, triggername, target) { if (!target.isIn()) return false; - if (event.name === 'dying') return true; + if (event.name === "dying") return true; if (event.giver !== player) return false; - if (event.name === 'gain') { - return event.player!=player&&event.getg(target).length>0; + if (event.name === "gain") { + return event.player != player && event.getg(target).length > 0; } - return game.hasPlayer(current=>current!=player&&event.getg(current).length>0); + return game.hasPlayer((current) => current != player && event.getg(current).length > 0); }, - logTarget(event, player, triggername, target){ + logTarget(event, player, triggername, target) { return target; }, - check(event, player, triggername, target){ - return get.attitude(player,target) > 0; + check(event, player, triggername, target) { + return get.attitude(player, target) > 0; }, - async content(event, trigger, player){ + async content(event, trigger, player) { event.targets[0].draw(); }, }, }, - characterReplace:{ - caocao:['caocao','re_caocao','sb_caocao','dc_caocao'], - guojia:['guojia','re_guojia','ps1059_guojia','ps2070_guojia'], - simayi:['simayi','re_simayi','jsrg_simayi','ps_simayi','ps2068_simayi'], - jin_simayi:['jin_simayi','junk_simayi','ps_jin_simayi'], - zhenji:['zhenji','re_zhenji','sb_zhenji','yj_zhenji'], - xuzhu:['xuzhu','re_xuzhu'], - zhangliao:['zhangliao','re_zhangliao'], - sp_zhangliao:['sp_zhangliao','yj_zhangliao','jsrg_zhangliao'], - xiahoudun:['xiahoudun','re_xiahoudun','xin_xiahoudun','sb_xiahoudun'], - liubei:['liubei','re_liubei','sb_liubei','dc_liubei','junk_liubei'], - guanyu:['guanyu','re_guanyu','ol_sb_guanyu','sb_guanyu','ps_guanyu','old_guanyu','junk_guanyu'], - zhangfei:['zhangfei','re_zhangfei','old_zhangfei','xin_zhangfei','sb_zhangfei','tw_zhangfei','jsrg_zhangfei','yj_zhangfei'], - zhaoyun:['zhaoyun','re_zhaoyun','old_zhaoyun','sb_zhaoyun','jsrg_zhaoyun','ps2063_zhaoyun','ps2067_zhaoyun'], - sp_zhaoyun:['sp_zhaoyun','jsp_zhaoyun'], - machao:['machao','re_machao','sb_machao','ps_machao'], - sp_machao:['sp_machao','dc_sp_machao','jsrg_machao','old_machao'], - zhugeliang:['zhugeliang','re_zhugeliang','sb_zhugeliang','ps2066_zhugeliang','ps_zhugeliang'], - huangyueying:['huangyueying','re_huangyueying','junk_huangyueying','sb_huangyueying'], - sunquan:['sunquan','re_sunquan','sb_sunquan','dc_sunquan'], - zhouyu:['zhouyu','re_zhouyu','dc_sb_zhouyu','sb_zhouyu','ps1062_zhouyu','ps2080_zhouyu'], - luxun:['luxun','re_luxun','jsrg_luxun'], - lvmeng:['lvmeng','re_lvmeng','sb_lvmeng'], - huanggai:['huanggai','re_huanggai','sb_huanggai'], - daqiao:['daqiao','re_daqiao','sb_daqiao'], - sunshangxiang:['sunshangxiang','re_sunshangxiang','sb_sunshangxiang','jsrg_sunshangxiang'], - ganning:['ganning','re_ganning','sb_ganning','yongjian_ganning'], - yj_ganning:['yj_ganning','sp_ganning'], - lvbu:['lvbu','re_lvbu','jsrg_lvbu','ps_lvbu'], - diaochan:['diaochan','re_diaochan','sb_diaochan'], - huatuo:['huatuo','re_huatuo','old_huatuo'], - huaxiong:['huaxiong','re_huaxiong','old_huaxiong','sb_huaxiong','ol_huaxiong'], - yuanshu:['yuanshu','re_yuanshu','yl_yuanshu','old_yuanshu','ol_yuanshu','star_yuanshu'], - gongsunzan:['gongsunzan','re_gongsunzan','dc_gongsunzan','xin_gongsunzan'], - re_lidian:['re_lidian','old_re_lidian','junk_lidian'], + characterReplace: { + caocao: ["caocao", "re_caocao", "sb_caocao", "dc_caocao"], + guojia: ["guojia", "re_guojia", "ps1059_guojia", "ps2070_guojia"], + simayi: ["simayi", "re_simayi", "jsrg_simayi", "ps_simayi", "ps2068_simayi"], + jin_simayi: ["jin_simayi", "junk_simayi", "ps_jin_simayi"], + zhenji: ["zhenji", "re_zhenji", "sb_zhenji", "yj_zhenji"], + xuzhu: ["xuzhu", "re_xuzhu"], + zhangliao: ["zhangliao", "re_zhangliao"], + sp_zhangliao: ["sp_zhangliao", "yj_zhangliao", "jsrg_zhangliao"], + xiahoudun: ["xiahoudun", "re_xiahoudun", "xin_xiahoudun", "sb_xiahoudun"], + liubei: ["liubei", "re_liubei", "sb_liubei", "dc_liubei", "junk_liubei"], + guanyu: [ + "guanyu", + "re_guanyu", + "ol_sb_guanyu", + "sb_guanyu", + "ps_guanyu", + "old_guanyu", + "junk_guanyu", + ], + zhangfei: [ + "zhangfei", + "re_zhangfei", + "old_zhangfei", + "xin_zhangfei", + "sb_zhangfei", + "tw_zhangfei", + "jsrg_zhangfei", + "yj_zhangfei", + ], + zhaoyun: [ + "zhaoyun", + "re_zhaoyun", + "old_zhaoyun", + "sb_zhaoyun", + "jsrg_zhaoyun", + "ps2063_zhaoyun", + "ps2067_zhaoyun", + ], + sp_zhaoyun: ["sp_zhaoyun", "jsp_zhaoyun"], + machao: ["machao", "re_machao", "sb_machao", "ps_machao"], + sp_machao: ["sp_machao", "dc_sp_machao", "jsrg_machao", "old_machao"], + zhugeliang: [ + "zhugeliang", + "re_zhugeliang", + "sb_zhugeliang", + "ps2066_zhugeliang", + "ps_zhugeliang", + ], + huangyueying: ["huangyueying", "re_huangyueying", "junk_huangyueying", "sb_huangyueying"], + sunquan: ["sunquan", "re_sunquan", "sb_sunquan", "dc_sunquan"], + zhouyu: ["zhouyu", "re_zhouyu", "dc_sb_zhouyu", "sb_zhouyu", "ps1062_zhouyu", "ps2080_zhouyu"], + luxun: ["luxun", "re_luxun", "jsrg_luxun"], + lvmeng: ["lvmeng", "re_lvmeng", "sb_lvmeng"], + huanggai: ["huanggai", "re_huanggai", "sb_huanggai"], + daqiao: ["daqiao", "re_daqiao", "sb_daqiao"], + sunshangxiang: ["sunshangxiang", "re_sunshangxiang", "sb_sunshangxiang", "jsrg_sunshangxiang"], + ganning: ["ganning", "re_ganning", "sb_ganning", "yongjian_ganning"], + yj_ganning: ["yj_ganning", "sp_ganning"], + lvbu: ["lvbu", "re_lvbu", "jsrg_lvbu", "ps_lvbu"], + diaochan: ["diaochan", "re_diaochan", "sb_diaochan"], + huatuo: ["huatuo", "re_huatuo", "old_huatuo"], + huaxiong: ["huaxiong", "re_huaxiong", "old_huaxiong", "sb_huaxiong", "ol_huaxiong"], + yuanshu: ["yuanshu", "re_yuanshu", "yl_yuanshu", "old_yuanshu", "ol_yuanshu", "star_yuanshu"], + gongsunzan: ["gongsunzan", "re_gongsunzan", "dc_gongsunzan", "xin_gongsunzan"], + re_lidian: ["re_lidian", "old_re_lidian", "junk_lidian"], }, - translate:{ - caocao:'曹操', - hujia:'护驾', - hujia_info:'主公技,当你需要使用或打出一张【闪】时,你可以令其他魏势力角色选择是否打出一张【闪】。若有角色响应,则你视为使用或打出了一张【闪】。', - jianxiong:'奸雄', - jianxiong_info:'当你受到伤害后,你可以获得对你造成伤害的牌。', + translate: { + caocao: "曹操", + hujia: "护驾", + hujia_info: + "主公技,当你需要使用或打出一张【闪】时,你可以令其他魏势力角色选择是否打出一张【闪】。若有角色响应,则你视为使用或打出了一张【闪】。", + jianxiong: "奸雄", + jianxiong_info: "当你受到伤害后,你可以获得对你造成伤害的牌。", - simayi:'司马懿', - fankui:'反馈', - fankui_info:'当你受到伤害后,你可以获得伤害来源的一张牌。', - guicai:'鬼才', - guicai_info:'一名角色的判定牌生效前,你可以打出一张手牌代替之。', - guicai_info_guozhan:'一名角色的判定牌生效前,你可以打出一张牌代替之。', + simayi: "司马懿", + fankui: "反馈", + fankui_info: "当你受到伤害后,你可以获得伤害来源的一张牌。", + guicai: "鬼才", + guicai_info: "一名角色的判定牌生效前,你可以打出一张手牌代替之。", + guicai_info_guozhan: "一名角色的判定牌生效前,你可以打出一张牌代替之。", - xiahoudun:'夏侯惇', - zhangliao:'张辽', - xuzhu:'许褚', - guojia:'郭嘉', - zhenji:'甄宓', - liubei:'刘备', - guanyu:'关羽', - zhangfei:'张飞', - zhugeliang:'诸葛亮', - zhaoyun:'赵云', - machao:'马超', - huangyueying:'黄月英', - sunquan:'孙权', - ganning:'甘宁', - lvmeng:'吕蒙', - huanggai:'黄盖', - zhouyu:'周瑜', - daqiao:'大乔', - luxun:'陆逊', - sunshangxiang:'孙尚香', - huatuo:'华佗', - lvbu:'吕布', - diaochan:'貂蝉', - huaxiong:'华雄', - "xf_yiji":"伊籍", - re_yuanshu:'袁术', - caozhang:'曹彰', + xiahoudun: "夏侯惇", + zhangliao: "张辽", + xuzhu: "许褚", + guojia: "郭嘉", + zhenji: "甄宓", + liubei: "刘备", + guanyu: "关羽", + zhangfei: "张飞", + zhugeliang: "诸葛亮", + zhaoyun: "赵云", + machao: "马超", + huangyueying: "黄月英", + sunquan: "孙权", + ganning: "甘宁", + lvmeng: "吕蒙", + huanggai: "黄盖", + zhouyu: "周瑜", + daqiao: "大乔", + luxun: "陆逊", + sunshangxiang: "孙尚香", + huatuo: "华佗", + lvbu: "吕布", + diaochan: "貂蝉", + huaxiong: "华雄", + xf_yiji: "伊籍", + re_yuanshu: "袁术", + caozhang: "曹彰", - ganglie:'刚烈', - tuxi:'突袭', - luoyi:'裸衣', - luoyi2:'裸衣', - tiandu:'天妒', - yiji:'遗计', - luoshen:'洛神', - xinluoshen:'洛神', - qingguo:'倾国', - rende:'仁德', - jijiang:'激将', - jijiang1:'激将', - jijiang2:'激将', - wusheng:'武圣', - paoxiao:'咆哮', - guanxing:'观星', - kongcheng:'空城', - kongcheng1:'空城', - longdan:'龙胆', - longdan1:'龙胆', - longdan2:'龙胆', - mashu:'马术', - mashu2:'马术', - feiying:'飞影', - tieji:'铁骑', - jizhi:'集智', - qicai:'奇才', - zhiheng:'制衡', - jiuyuan:'救援', - qixi:'奇袭', - keji:'克己', - kurou:'苦肉', - yingzi:'英姿', - fanjian:'反间', - guose:'国色', - liuli:'流离', - qianxun:'谦逊', - lianying:'连营', - xiaoji:'枭姬', - jieyin:'结姻', - xinjieyin:'结姻', - qingnang:'青囊', - jijiu:'急救', - wushuang:'无双', - wushuang1:'无双', - wushuang2:'无双', - lijian:'离间', - biyue:'闭月', - xinbiyue:'闭月', - pileTop:'牌堆顶', - pileBottom:'牌堆底', - ganglie_info:'当你受到伤害后,你可以判定。若结果不为红桃,则伤害来源须弃置两张手牌,否则受到来自你的1点伤害。', - tuxi_info:'摸牌阶段,你可以改为获得至多两名其他角色的各一张手牌。', - luoyi_info:'摸牌阶段,你可以少摸一张牌。若如此做,当你本回合内使用【杀】或【决斗】造成伤害时,此伤害+1。', - tiandu_info:'当你的判定牌生效后,你可以获得之。', - yiji_info:'当你受到1点伤害后,你可以观看牌堆顶的两张牌,然后将其分配给任意角色。', - luoshen_info:'准备阶段,你可以判定。若结果为黑色,你获得判定牌。你可重复此流程,直到出现红色的判定结果。', - luoshen_info_guozhan:'准备阶段,你可以判定。若结果为黑色,则可以继续判定,直到出现红色的判定牌。然后你获得所有黑色的判定牌。(判定结果为黑色的牌在此过程中不会进入弃牌堆)', - xinluoshen_info:'准备阶段,你可以判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。', - xinluoshen_info_alter:'准备阶段,你可以判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。你通过洛神获得的牌,不计入当前回合的手牌上限。', - qingguo_info:'你可以将一张黑色手牌当做【闪】使用或打出。', - rende_info:'出牌阶段,你可以将任意张手牌交给其他角色。当你以此法于一回合内给出第二张牌时,你回复1点体力。', - jijiang_info:'主公技,当你需要使用或打出【杀】时,你可以令其他蜀势力角色依次选择是否打出一张【杀】。若有角色响应,则你视为使用或打出了此【杀】。', - wusheng_info:'你可以将一张红色牌当做【杀】使用或打出。', - paoxiao_info:'锁定技,出牌阶段,你使用【杀】没有数量限制。', - guanxing_info:'准备阶段,你可以观看牌堆顶的X张牌,并将其以任意顺序置于牌堆项或牌堆底。(X为存活角色数且至多为5)', - kongcheng_info:'锁定技,当你没有手牌时,你不能成为【杀】或【决斗】的目标。', - longdan_info:'你可以将【杀】当做【闪】,或将【闪】当做【杀】使用或打出。', - mashu_info:'锁定技,你计算与其他角色的距离时-1。', - mashu2_info:'锁定技,你计算与其他角色的距离时-1。', - feiying_info:'锁定技,其他角色计算与你的距离时+1。', - tieji_info:'当你使用【杀】指定目标后,你可以进行判定。若结果为红色,则此【杀】不可被闪避。', - jizhi_info:'当你使用非转化的普通锦囊牌时,你可以摸一张牌。', - xinjizhi:'集智', - xinjizhi_info:'当你使用非转化的普通锦囊牌时,你可以摸一张牌。', - xinjizhi_info_alter:'每当你使用一张非转化的锦囊牌,可以摸一张牌,如果摸到的是基本牌,你可以弃置这张牌,然后本回合手牌上限+1。', - xinqicai:'奇才', - xinqicai_info:'锁定技,你使用锦囊牌无距离限制。', - xinqicai_info_alter:'锁定技,你使用的锦囊牌无距离限制,你装备区内的牌不能被弃置。', - qicai_info:'锁定技,你使用锦囊牌无距离限制。', - zhiheng_info:'出牌阶段限一次,你可以弃置任意张牌,然后摸等量的牌。', - xinzhiheng:'制衡', - xinzhiheng_info:'出牌阶段限1次,你可以弃置任意张牌并摸等量的牌。', - xinzhiheng_info_alter:'出牌阶段限1次,你可以弃置任意张牌并摸等量的牌,如果在发动制衡时弃置了所有手牌,你额外摸一张牌。', - jiuyuan_info:'主公技,锁定技,其他吴势力角色对你使用的【桃】的回复值+1。', - xinjiuyuan:'救援', - xinjiuyuan_info:'主公技,锁定技,濒死阶段,吴势力角色对你使用的[桃]额外回复1点体力。', - xinjiuyuan_info_alter:'主公技,其他吴势力角色对自己使用【桃】时,若其体力值大于你,其可以令你回复1点体力,然后其摸一张牌。', - qixi_info:'你可以将一张黑色牌当做【过河拆桥】使用。', - keji_info:'弃牌阶段开始时,若你于本回合的出牌阶段内没有过使用或打出过【杀】,则你可以跳过此阶段。', - kurou_info:'出牌阶段,你可以失去1点体力,然后摸两张牌。', - yingzi_info:'摸牌阶段,你可以多摸一张牌。', - fanjian_info:'出牌阶段限一次。你可以令一名角色选择一种花色,然后其获得你的一张手牌。若其以此法选择的花色与其得到的牌花色不同,则你对其造成1点伤害。', - guose_info:'你可以将一张方片牌当做【乐不思蜀】使用。', - liuli_info:'当你成为【杀】的目标时,你可以弃置一张牌并将此【杀】转移给攻击范围内的一名其他角色(不能是此【杀】的使用者)。', - qianxun_info:'锁定技,你不能成为【顺手牵羊】和【乐不思蜀】的目标。', - lianying_info:'当你失去最后的手牌时,你可以摸一张牌。', - xiaoji_info:'当你失去一张装备区内的牌后,你可以摸两张牌。', - jieyin_info:'出牌阶段限一次,你可以弃置两张手牌并选择一名已经受伤的男性角色。你与其各回复1点体力。', - xinjieyin_info:'出牌阶段,你可以弃置两张牌并选择1名已经受伤的男性角色,你与其各回复1点体力,每阶段限一次。', - xinjieyin_old_info:'出牌阶段,你可以弃置两张牌并选择1名已经受伤的男性角色,你与其各回复1点体力,每阶段限一次。', - xinjieyin_new_info:'出牌阶段限1次,你可以选择一名男性角色,弃置一张手牌或将一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。', - xinjieyin_info_alter:'出牌阶段限1次,你可以选择一名男性角色,弃置一张手牌或将一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。', - qingnang_info:'出牌阶段限一次,你可以弃置一张手牌并令一名角色回复1点体力。', - jijiu_info:'你的回合外,你可以将一张红色牌当做【桃】使用。', - wushuang_info:'锁定技,当你使用【杀】或【决斗】指定目标后,你令此牌需要依次使用或打出两张【闪】或【杀】响应。', - lijian_info:'出牌阶段限一次,你可以弃置一张牌,视为一名男性角色对另一名男性角色使用一张【决斗】(不可被【无懈可击】响应)。', - biyue_info:'结束阶段,你可以摸一张牌。', - xinbiyue_info:'结束阶段,你可以摸一张牌。', - xinbiyue_info_alter:'结束阶段,你可以摸一张牌,如果你没有手牌,改为摸两张牌。', - yaowu:'耀武', - yaowu_info:'锁定技,一名角色使用红色【杀】对你造成伤害时,该角色回复1点体力或摸一张牌。', - "new_jiangchi":"将驰", - "new_jiangchi_info":"摸牌阶段结束时,你可以选择一项:1、摸一张牌,若如此做,你本回合内不能使用或打出【杀】且【杀】不计入手牌上限。 2、弃置一张牌,若如此做,出牌阶段你使用【杀】无距离限制且你可以额外使用一张【杀】,直到回合结束。", - xinfu_jijie:"机捷", - xinfu_jijie_info:"出牌阶段限一次。你可以观看牌堆底的一张牌,然后将其交给一名角色。", - xinfu_jiyuan:"急援", - xinfu_jiyuan_info:"当有角色进入濒死状态时,或你将牌交给一名其他角色后,你可以令该角色摸一张牌。", - ganglie_three:'刚烈', - ganglie_three_info:'当你受到伤害后,你可令一名敌方角色判定。若结果不为♥,其弃置两张牌或受到来自你的1点伤害。', - zhongyi:'忠义', - zhongyi2:'忠义', - zhongyi_info:'限定技,出牌阶段,你可以将一张牌置于武将牌上。你的武将牌上有〖忠义〗牌时,己方角色使用【杀】造成的伤害+1。下轮游戏开始时,你将〖忠义〗牌置入弃牌堆。', - zhanshen:'战神', - zhanshen_info:'觉醒技,准备阶段,若场上有已死亡的其他己方角色且你已受伤,则你弃置装备区的武器牌,减1点体力上限,获得技能〖马术〗和〖神戟〗。', - shenji:'神戟', - shenji_info:'锁定技,你使用【杀】指定的目标数上限+2,次数上限+1。', - rewangzun:'妄尊', - rewangzun2:'妄尊', - rewangzun_info:'锁定技,一名其他角色的准备阶段开始时,若其体力值大于你,你摸一张牌。然后若其身份为主公/主帅/君主/地主且明置,则你摸一张牌,且其本回合的手牌上限-1。', - retongji:'同疾', - retongji_info:'攻击范围内包含你的角色成为【杀】的目标时,若你不是此【杀】的使用者或目标,其可弃置一张牌,然后将此【杀】转移给你。', - std_panfeng:'潘凤', - stdkuangfu:'狂斧', - stdkuangfu_info:'锁定技。出牌阶段限一次。当你使用【杀】对其他角色造成伤害后,若其体力值:小于你,你摸两张牌;不小于你,你失去1点体力。', - ganfuren:'甘夫人', - stdshushen:'淑慎', - stdshushen_info:'当你回复1点体力时,你可以令一名其他角色摸一张牌(若其没有手牌则改为摸两张牌)。', - old_re_lidian:'李典', + ganglie: "刚烈", + tuxi: "突袭", + luoyi: "裸衣", + luoyi2: "裸衣", + tiandu: "天妒", + yiji: "遗计", + luoshen: "洛神", + xinluoshen: "洛神", + qingguo: "倾国", + rende: "仁德", + jijiang: "激将", + jijiang1: "激将", + jijiang2: "激将", + wusheng: "武圣", + paoxiao: "咆哮", + guanxing: "观星", + kongcheng: "空城", + kongcheng1: "空城", + longdan: "龙胆", + longdan1: "龙胆", + longdan2: "龙胆", + mashu: "马术", + mashu2: "马术", + feiying: "飞影", + tieji: "铁骑", + jizhi: "集智", + qicai: "奇才", + zhiheng: "制衡", + jiuyuan: "救援", + qixi: "奇袭", + keji: "克己", + kurou: "苦肉", + yingzi: "英姿", + fanjian: "反间", + guose: "国色", + liuli: "流离", + qianxun: "谦逊", + lianying: "连营", + xiaoji: "枭姬", + jieyin: "结姻", + xinjieyin: "结姻", + qingnang: "青囊", + jijiu: "急救", + wushuang: "无双", + wushuang1: "无双", + wushuang2: "无双", + lijian: "离间", + biyue: "闭月", + xinbiyue: "闭月", + pileTop: "牌堆顶", + pileBottom: "牌堆底", + ganglie_info: + "当你受到伤害后,你可以判定。若结果不为红桃,则伤害来源须弃置两张手牌,否则受到来自你的1点伤害。", + tuxi_info: "摸牌阶段,你可以改为获得至多两名其他角色的各一张手牌。", + luoyi_info: + "摸牌阶段,你可以少摸一张牌。若如此做,当你本回合内使用【杀】或【决斗】造成伤害时,此伤害+1。", + tiandu_info: "当你的判定牌生效后,你可以获得之。", + yiji_info: "当你受到1点伤害后,你可以观看牌堆顶的两张牌,然后将其分配给任意角色。", + luoshen_info: + "准备阶段,你可以判定。若结果为黑色,你获得判定牌。你可重复此流程,直到出现红色的判定结果。", + luoshen_info_guozhan: + "准备阶段,你可以判定。若结果为黑色,则可以继续判定,直到出现红色的判定牌。然后你获得所有黑色的判定牌。(判定结果为黑色的牌在此过程中不会进入弃牌堆)", + xinluoshen_info: + "准备阶段,你可以判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。", + xinluoshen_info_alter: + "准备阶段,你可以判定,若为黑色则可以继续判定,直到出现红色。然后你获得所有黑色的判定牌。你通过洛神获得的牌,不计入当前回合的手牌上限。", + qingguo_info: "你可以将一张黑色手牌当做【闪】使用或打出。", + rende_info: + "出牌阶段,你可以将任意张手牌交给其他角色。当你以此法于一回合内给出第二张牌时,你回复1点体力。", + jijiang_info: + "主公技,当你需要使用或打出【杀】时,你可以令其他蜀势力角色依次选择是否打出一张【杀】。若有角色响应,则你视为使用或打出了此【杀】。", + wusheng_info: "你可以将一张红色牌当做【杀】使用或打出。", + paoxiao_info: "锁定技,出牌阶段,你使用【杀】没有数量限制。", + guanxing_info: + "准备阶段,你可以观看牌堆顶的X张牌,并将其以任意顺序置于牌堆项或牌堆底。(X为存活角色数且至多为5)", + kongcheng_info: "锁定技,当你没有手牌时,你不能成为【杀】或【决斗】的目标。", + longdan_info: "你可以将【杀】当做【闪】,或将【闪】当做【杀】使用或打出。", + mashu_info: "锁定技,你计算与其他角色的距离时-1。", + mashu2_info: "锁定技,你计算与其他角色的距离时-1。", + feiying_info: "锁定技,其他角色计算与你的距离时+1。", + tieji_info: "当你使用【杀】指定目标后,你可以进行判定。若结果为红色,则此【杀】不可被闪避。", + jizhi_info: "当你使用非转化的普通锦囊牌时,你可以摸一张牌。", + xinjizhi: "集智", + xinjizhi_info: "当你使用非转化的普通锦囊牌时,你可以摸一张牌。", + xinjizhi_info_alter: + "每当你使用一张非转化的锦囊牌,可以摸一张牌,如果摸到的是基本牌,你可以弃置这张牌,然后本回合手牌上限+1。", + xinqicai: "奇才", + xinqicai_info: "锁定技,你使用锦囊牌无距离限制。", + xinqicai_info_alter: "锁定技,你使用的锦囊牌无距离限制,你装备区内的牌不能被弃置。", + qicai_info: "锁定技,你使用锦囊牌无距离限制。", + zhiheng_info: "出牌阶段限一次,你可以弃置任意张牌,然后摸等量的牌。", + xinzhiheng: "制衡", + xinzhiheng_info: "出牌阶段限1次,你可以弃置任意张牌并摸等量的牌。", + xinzhiheng_info_alter: + "出牌阶段限1次,你可以弃置任意张牌并摸等量的牌,如果在发动制衡时弃置了所有手牌,你额外摸一张牌。", + jiuyuan_info: "主公技,锁定技,其他吴势力角色对你使用的【桃】的回复值+1。", + xinjiuyuan: "救援", + xinjiuyuan_info: "主公技,锁定技,濒死阶段,吴势力角色对你使用的[桃]额外回复1点体力。", + xinjiuyuan_info_alter: + "主公技,其他吴势力角色对自己使用【桃】时,若其体力值大于你,其可以令你回复1点体力,然后其摸一张牌。", + qixi_info: "你可以将一张黑色牌当做【过河拆桥】使用。", + keji_info: + "弃牌阶段开始时,若你于本回合的出牌阶段内没有过使用或打出过【杀】,则你可以跳过此阶段。", + kurou_info: "出牌阶段,你可以失去1点体力,然后摸两张牌。", + yingzi_info: "摸牌阶段,你可以多摸一张牌。", + fanjian_info: + "出牌阶段限一次。你可以令一名角色选择一种花色,然后其获得你的一张手牌。若其以此法选择的花色与其得到的牌花色不同,则你对其造成1点伤害。", + guose_info: "你可以将一张方片牌当做【乐不思蜀】使用。", + liuli_info: + "当你成为【杀】的目标时,你可以弃置一张牌并将此【杀】转移给攻击范围内的一名其他角色(不能是此【杀】的使用者)。", + qianxun_info: "锁定技,你不能成为【顺手牵羊】和【乐不思蜀】的目标。", + lianying_info: "当你失去最后的手牌时,你可以摸一张牌。", + xiaoji_info: "当你失去一张装备区内的牌后,你可以摸两张牌。", + jieyin_info: + "出牌阶段限一次,你可以弃置两张手牌并选择一名已经受伤的男性角色。你与其各回复1点体力。", + xinjieyin_info: + "出牌阶段,你可以弃置两张牌并选择1名已经受伤的男性角色,你与其各回复1点体力,每阶段限一次。", + xinjieyin_old_info: + "出牌阶段,你可以弃置两张牌并选择1名已经受伤的男性角色,你与其各回复1点体力,每阶段限一次。", + xinjieyin_new_info: + "出牌阶段限1次,你可以选择一名男性角色,弃置一张手牌或将一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。", + xinjieyin_info_alter: + "出牌阶段限1次,你可以选择一名男性角色,弃置一张手牌或将一张装备牌置于其装备区,你与其体力较高的角色摸一张牌,体力值较低的角色回复1点体力。", + qingnang_info: "出牌阶段限一次,你可以弃置一张手牌并令一名角色回复1点体力。", + jijiu_info: "你的回合外,你可以将一张红色牌当做【桃】使用。", + wushuang_info: + "锁定技,当你使用【杀】或【决斗】指定目标后,你令此牌需要依次使用或打出两张【闪】或【杀】响应。", + lijian_info: + "出牌阶段限一次,你可以弃置一张牌,视为一名男性角色对另一名男性角色使用一张【决斗】(不可被【无懈可击】响应)。", + biyue_info: "结束阶段,你可以摸一张牌。", + xinbiyue_info: "结束阶段,你可以摸一张牌。", + xinbiyue_info_alter: "结束阶段,你可以摸一张牌,如果你没有手牌,改为摸两张牌。", + yaowu: "耀武", + yaowu_info: "锁定技,一名角色使用红色【杀】对你造成伤害时,该角色回复1点体力或摸一张牌。", + new_jiangchi: "将驰", + new_jiangchi_info: + "摸牌阶段结束时,你可以选择一项:1、摸一张牌,若如此做,你本回合内不能使用或打出【杀】且【杀】不计入手牌上限。 2、弃置一张牌,若如此做,出牌阶段你使用【杀】无距离限制且你可以额外使用一张【杀】,直到回合结束。", + xinfu_jijie: "机捷", + xinfu_jijie_info: "出牌阶段限一次。你可以观看牌堆底的一张牌,然后将其交给一名角色。", + xinfu_jiyuan: "急援", + xinfu_jiyuan_info: "当有角色进入濒死状态时,或你将牌交给一名其他角色后,你可以令该角色摸一张牌。", + ganglie_three: "刚烈", + ganglie_three_info: + "当你受到伤害后,你可令一名敌方角色判定。若结果不为♥,其弃置两张牌或受到来自你的1点伤害。", + zhongyi: "忠义", + zhongyi2: "忠义", + zhongyi_info: + "限定技,出牌阶段,你可以将一张牌置于武将牌上。你的武将牌上有〖忠义〗牌时,己方角色使用【杀】造成的伤害+1。下轮游戏开始时,你将〖忠义〗牌置入弃牌堆。", + zhanshen: "战神", + zhanshen_info: + "觉醒技,准备阶段,若场上有已死亡的其他己方角色且你已受伤,则你弃置装备区的武器牌,减1点体力上限,获得技能〖马术〗和〖神戟〗。", + shenji: "神戟", + shenji_info: "锁定技,你使用【杀】指定的目标数上限+2,次数上限+1。", + rewangzun: "妄尊", + rewangzun2: "妄尊", + rewangzun_info: + "锁定技,一名其他角色的准备阶段开始时,若其体力值大于你,你摸一张牌。然后若其身份为主公/主帅/君主/地主且明置,则你摸一张牌,且其本回合的手牌上限-1。", + retongji: "同疾", + retongji_info: + "攻击范围内包含你的角色成为【杀】的目标时,若你不是此【杀】的使用者或目标,其可弃置一张牌,然后将此【杀】转移给你。", + std_panfeng: "潘凤", + stdkuangfu: "狂斧", + stdkuangfu_info: + "锁定技。出牌阶段限一次。当你使用【杀】对其他角色造成伤害后,若其体力值:小于你,你摸两张牌;不小于你,你失去1点体力。", + ganfuren: "甘夫人", + stdshushen: "淑慎", + stdshushen_info: + "当你回复1点体力时,你可以令一名其他角色摸一张牌(若其没有手牌则改为摸两张牌)。", + old_re_lidian: "李典", - standard_2008:"2008版标准包", - standard_2013:"2013版标准包", - standard_2019:"2019版标准包", - standard_2023:"2023版标准包", + standard_2008: "2008版标准包", + standard_2013: "2013版标准包", + standard_2019: "2019版标准包", + standard_2023: "2023版标准包", }, }; }); diff --git a/character/swd.js b/character/swd.js index ff0ae770b..ab7437725 100644 --- a/character/swd.js +++ b/character/swd.js @@ -1,84 +1,84 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'swd', - character:{ - swd_huzhongxian:['male','wu',3,['daofa','xielv','hujing']], + name: "swd", + character: { + swd_huzhongxian: ["male", "wu", 3, ["daofa", "xielv", "hujing"]], - swd_anka:['male','qun',3,['songci','anlianying']], - swd_septem:['male','qun',4,['jiying','liaoyuan','yishan']], - swd_kama:['female','qun',3,['yueren','shangshi']], + swd_anka: ["male", "qun", 3, ["songci", "anlianying"]], + swd_septem: ["male", "qun", 4, ["jiying", "liaoyuan", "yishan"]], + swd_kama: ["female", "qun", 3, ["yueren", "shangshi"]], // swd_miles:['male','qun',4,['aojian','miles_xueyi','mohua2']], - swd_nicole:['female','qun',3,['huanjian','lingwu','minjing']], - swd_wangsiyue:['female','wei',3,['duishi','biyue']], - swd_weida:['female','qun',3,['yueren','zhenlie','duijue']], - swd_xuanyuanjianxian:['male','qun',4,['pozhou','huajian','xuanyuan']], + swd_nicole: ["female", "qun", 3, ["huanjian", "lingwu", "minjing"]], + swd_wangsiyue: ["female", "wei", 3, ["duishi", "biyue"]], + swd_weida: ["female", "qun", 3, ["yueren", "zhenlie", "duijue"]], + swd_xuanyuanjianxian: ["male", "qun", 4, ["pozhou", "huajian", "xuanyuan"]], - swd_chenjingchou:['male','wu',3,['youyin','yihua']], - swd_duguningke:['female','qun',3,['nlianji','touxi']], - swd_guyue:['male','wei',3,['gtiandao','gxianyin','wangchen']], - swd_tuobayuer:['female','shu',4,['swdliuhong','poyue','niepan']], - swd_yuwentuo:['male','shu',4,['wushuang','xielei','kunlunjing']], - swd_yuxiaoxue:['female','wei',3,['huanhun','daixing','yinyue']], + swd_chenjingchou: ["male", "wu", 3, ["youyin", "yihua"]], + swd_duguningke: ["female", "qun", 3, ["nlianji", "touxi"]], + swd_guyue: ["male", "wei", 3, ["gtiandao", "gxianyin", "wangchen"]], + swd_tuobayuer: ["female", "shu", 4, ["swdliuhong", "poyue", "niepan"]], + swd_yuwentuo: ["male", "shu", 4, ["wushuang", "xielei", "kunlunjing"]], + swd_yuxiaoxue: ["female", "wei", 3, ["huanhun", "daixing", "yinyue"]], - swd_jiliang:['male','wu',3,['yunchou','gongxin','jqimou']], - swd_shuijing:['female','qun',4,['mojian','duanyue','tuzhen']], - swd_quxian:['female','qun',3,['mojian','huanxia']], - swd_xiyan:['male','qun',3,['jiefen','datong']], - swd_cheyun:['female','wu',3,['cyxianjiang','cyqiaoxie','shengong']], - swd_huanyuanzhi:['male','qun',3,['swdtianshu','lanzhi','mufeng']], - swd_murongshi:['female','shu',4,['duanyi','guxing']], - swd_jipeng:['male','wu',3,['reyingzi','guozao']], - swd_qi:['male','qun',3,['yaotong','heihuo','pojian']], + swd_jiliang: ["male", "wu", 3, ["yunchou", "gongxin", "jqimou"]], + swd_shuijing: ["female", "qun", 4, ["mojian", "duanyue", "tuzhen"]], + swd_quxian: ["female", "qun", 3, ["mojian", "huanxia"]], + swd_xiyan: ["male", "qun", 3, ["jiefen", "datong"]], + swd_cheyun: ["female", "wu", 3, ["cyxianjiang", "cyqiaoxie", "shengong"]], + swd_huanyuanzhi: ["male", "qun", 3, ["swdtianshu", "lanzhi", "mufeng"]], + swd_murongshi: ["female", "shu", 4, ["duanyi", "guxing"]], + swd_jipeng: ["male", "wu", 3, ["reyingzi", "guozao"]], + swd_qi: ["male", "qun", 3, ["yaotong", "heihuo", "pojian"]], - swd_luchengxuan:['male','wu',4,['ljifeng','lxianglong']], - swd_xiarou:['female','shu',3,['xianghui','huiqi']], - swd_moye:['female','wu',3,['rexue','liuli','senluo']], + swd_luchengxuan: ["male", "wu", 4, ["ljifeng", "lxianglong"]], + swd_xiarou: ["female", "shu", 3, ["xianghui", "huiqi"]], + swd_moye: ["female", "wu", 3, ["rexue", "liuli", "senluo"]], - swd_zhaoyun:['male','shu',4,['longdan','pozhen','tanlin']], - swd_hengai:['female','shu',3,['funiao','ningxian','hlingbo']], - swd_duanmeng:['female','shu',4,['xuanying','lieren']], - swd_jiangwu:['male','shu',4,['yijue','dangping']], - swd_tuwei:['male','shu',3,['zhanlu','susheng']], - swd_yeyaxi:['female','shu',3,['rexue','huopu','shenyan']], + swd_zhaoyun: ["male", "shu", 4, ["longdan", "pozhen", "tanlin"]], + swd_hengai: ["female", "shu", 3, ["funiao", "ningxian", "hlingbo"]], + swd_duanmeng: ["female", "shu", 4, ["xuanying", "lieren"]], + swd_jiangwu: ["male", "shu", 4, ["yijue", "dangping"]], + swd_tuwei: ["male", "shu", 3, ["zhanlu", "susheng"]], + swd_yeyaxi: ["female", "shu", 3, ["rexue", "huopu", "shenyan"]], - swd_muyun:['male','wei',4,['zhuhai','polang','jikong']], - swd_lanyin:['female','wei',3,['xingdian','yulin','luomei']], - swd_zhiyin:['female','wei',3,['xuehuang','ningshuang','zhuyu']], - swd_qiner:['female','wei',3,['huanyin','tianhuo','xuanzhou']], - swd_jiuyou:['male','wei',3,['lexue']], - swd_duopeng:['male','wu',3,['luanji','reyingzi']], + swd_muyun: ["male", "wei", 4, ["zhuhai", "polang", "jikong"]], + swd_lanyin: ["female", "wei", 3, ["xingdian", "yulin", "luomei"]], + swd_zhiyin: ["female", "wei", 3, ["xuehuang", "ningshuang", "zhuyu"]], + swd_qiner: ["female", "wei", 3, ["huanyin", "tianhuo", "xuanzhou"]], + swd_jiuyou: ["male", "wei", 3, ["lexue"]], + swd_duopeng: ["male", "wu", 3, ["luanji", "reyingzi"]], - swd_fengtianling:['male','shu',4,['guiyan','jiang']], - swd_huyue:['female','wu',3,['hyunshen','fengming']], - swd_jialanduo:['male','qun',4,['xianyin','mailun']], - swd_rongshuang:['female','wu',3,['suiyan','duanxing']], - swd_zhuoshanzhu:['male','wu',4,['suiyan','wanjun']], - swd_jiting:['female','wei',4,['guanhu','lingshi']], + swd_fengtianling: ["male", "shu", 4, ["guiyan", "jiang"]], + swd_huyue: ["female", "wu", 3, ["hyunshen", "fengming"]], + swd_jialanduo: ["male", "qun", 4, ["xianyin", "mailun"]], + swd_rongshuang: ["female", "wu", 3, ["suiyan", "duanxing"]], + swd_zhuoshanzhu: ["male", "wu", 4, ["suiyan", "wanjun"]], + swd_jiting: ["female", "wei", 4, ["guanhu", "lingshi"]], - swd_sikongyu:['male','wu',4,['sliufeng','linyun','hutian']], - swd_muyue:['female','wei',3,['xingzhui','lingxian','shouyin']], - swd_ziqiao:['female','shu',3,['guaili','fuyan']], - swd_fengyu:['male','shu',4,['fzhenwei','shangxi']], + swd_sikongyu: ["male", "wu", 4, ["sliufeng", "linyun", "hutian"]], + swd_muyue: ["female", "wei", 3, ["xingzhui", "lingxian", "shouyin"]], + swd_ziqiao: ["female", "shu", 3, ["guaili", "fuyan"]], + swd_fengyu: ["male", "shu", 4, ["fzhenwei", "shangxi"]], // swd_wushi:['male','wei',3,['zhoufu','yingbin','xuying']], // swd_lanmoshen:['female','wei',3,['bingjian','lieren']], - swd_huanglei:['male','qun',3,['jilve','gongshen','gaizao']], + swd_huanglei: ["male", "qun", 3, ["jilve", "gongshen", "gaizao"]], // swd_libai:['female','qun',3,['miaobi','zhexian']], - swd_kendi:['male','qun',3,['zhanxing','kbolan']], + swd_kendi: ["male", "qun", 3, ["zhanxing", "kbolan"]], // swd_lijing:['male','qun',4,['tianyi','zhuhai']], - swd_lilian:['female','qun',3,['swd_wuxie','lqingcheng']], + swd_lilian: ["female", "qun", 3, ["swd_wuxie", "lqingcheng"]], // swd_linming:['male','qun',3,['shelie','bifa']], // swd_philis:['male','qun',4,['yicong','wangxi']], // swd_pepin:['male','qun',4,['rejianxiong','quhu']], - swd_kangnalishi:['male','qun',1,['busi','xuying','yinguo']], - swd_xuanyuanjiantong:['male','qun',3,['chengjian','huanling']], - swd_huiyan:['male','qun',4,['hwendao','lingfeng','hxunzhi']], + swd_kangnalishi: ["male", "qun", 1, ["busi", "xuying", "yinguo"]], + swd_xuanyuanjiantong: ["male", "qun", 3, ["chengjian", "huanling"]], + swd_huiyan: ["male", "qun", 4, ["hwendao", "lingfeng", "hxunzhi"]], // swd_chenfu:['male','qun',4,['xuanzhou','bingfeng']], // swd_chengyaojin:['male','qun',4,['jiuchi','jufu']], - swd_shanxiaoxiao:['female','wu',3,['shehun','xiaomoyu']], - swd_yuchiyanhong:['female','shu',3,['huanxing','meihuo']], + swd_shanxiaoxiao: ["female", "wu", 3, ["shehun", "xiaomoyu"]], + swd_yuchiyanhong: ["female", "shu", 3, ["huanxing", "meihuo"]], // swd_hanteng:['male','qun',4,['kuangfu']], // swd_heran:['male','qun',3,['yujian','guiyin','shejie']], // swd_xingtian:['male','qun',8,[]], @@ -87,2342 +87,2534 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // swd_yangshuo:['male','qun',4,['longdan','luomu']], // swd_zhanglie:['male','qun',4,['huajin','poxiao']], - swd_hanluo:['male','qun',5,['tiebi']], - swd_fu:['male','qun',5,['yudun']], - swd_linyue:['male','wei',3,['zhenjiu','lmazui']], - swd_zidashu:['male','wu',3,['shoulie','hudun']], - swd_maixing:['male','wu',3,['toudan','shending']], - swd_fuyan:['male','qun',4,['lianda']], - swd_haidapang:['female','wu',3,['bingjian','rumeng']], - swd_shaowei:['female','shu',3,['jianji','huangyu']], + swd_hanluo: ["male", "qun", 5, ["tiebi"]], + swd_fu: ["male", "qun", 5, ["yudun"]], + swd_linyue: ["male", "wei", 3, ["zhenjiu", "lmazui"]], + swd_zidashu: ["male", "wu", 3, ["shoulie", "hudun"]], + swd_maixing: ["male", "wu", 3, ["toudan", "shending"]], + swd_fuyan: ["male", "qun", 4, ["lianda"]], + swd_haidapang: ["female", "wu", 3, ["bingjian", "rumeng"]], + swd_shaowei: ["female", "shu", 3, ["jianji", "huangyu"]], - swd_youzhao:['male','shu',4,['longdan','yuchen']], - swd_shangzhang:['male','shu',4,['lianwu']], - swd_situqiang:['female','shu',3,['fengze','lingyue','jinlin']], + swd_youzhao: ["male", "shu", 4, ["longdan", "yuchen"]], + swd_shangzhang: ["male", "shu", 4, ["lianwu"]], + swd_situqiang: ["female", "shu", 3, ["fengze", "lingyue", "jinlin"]], - swd_chunyuheng:['male','wei',2,['jueqing','shengshou','xuying']], - swd_hanlong:['male','wei',4,['ciqiu','siji']], - swd_yuli:['female','wu',3,['lingxin','tianxiang']], - swd_zhanggao:['male','wei',4,['yicong','poxing']], - swd_shuwaner:['female','shu',3,['sxianjing','huodan']], - swd_xiaohuanglong:['male','wei',3,['yeying','juxi']], + swd_chunyuheng: ["male", "wei", 2, ["jueqing", "shengshou", "xuying"]], + swd_hanlong: ["male", "wei", 4, ["ciqiu", "siji"]], + swd_yuli: ["female", "wu", 3, ["lingxin", "tianxiang"]], + swd_zhanggao: ["male", "wei", 4, ["yicong", "poxing"]], + swd_shuwaner: ["female", "shu", 3, ["sxianjing", "huodan"]], + swd_xiaohuanglong: ["male", "wei", 3, ["yeying", "juxi"]], - swd_hupo:['male','wu',3,['dunxing','guiying']], - swd_jiangziya:['male','wu',3,['mingfu','tianlun']], + swd_hupo: ["male", "wu", 3, ["dunxing", "guiying"]], + swd_jiangziya: ["male", "wu", 3, ["mingfu", "tianlun"]], }, - characterIntro:{ - swd_kendi:'占星大师老肯迪的孙子,老肯迪死后,他也自称肯迪,伪装成老肯迪,以保护老肯迪的藏书。肯迪平常以接受委托抄书与翻译拉丁文书籍为业,除了占星术以外,其余知识也相当广博。为了增长见闻,什么可怕的地方都敢去,所以认识薇达与不少的军官。后来,肯迪的子孙成为伊斯兰地区的大学者,以因果定律的学说著名于世。', - swd_shuwaner:'第一代祝犁黄汉卿的妻子,二代祝犁黄采儿的母亲。陷阱机关师,擅长火系陷阱,并能驱使一种可爆裂来杀敌之神秘「火丹」技术。', - swd_xiaohuanglong:'龙族之幻兽,后土之神将它送给兰茵避险,以保护她安全。', - swd_huzhongxian:'炼妖壶是女娲神所创,是以开天辟地创造生命的工具,开创出万物后即遗留于某一处水底神殿中。由巴蛇及蛟龟守护该神器,过了约莫千年之久,炼妖壶已可幻化成人形,即为壶中仙。此时正因人类对异类的排斥,巴蛇对此愤愤不平,壶中仙与巴蛇讨论人魔共存的方法,但巴蛇觉得壶中仙是另有所图。自不采用,一日趁壶中仙不注意,将炼妖壶的妖怪全数释放,留下蛟龟看守练妖壶,巴蛇率领魔族大军反攻人类,从此人魔之战一直持续着。', - swd_anka:'安卡在数千年前,曾经是法老王的宠物。在法老王过世后,本来要当陪葬品,却被一位也要被陪葬的祭司带着逃走,安卡借着长期跟随祭司,学得不少后来传到欧洲的黑魔法,成了一只猫精。但在欧洲黑猫很不受欢迎,之后遇上卡玛,成为共患难的好友。安卡有许多癖好,像是收集漂亮的石头把它藏起来,若是日后又发现会很高兴。', - swd_septem:'欧洲梅罗文加王朝高卢出生的东方人与日耳曼混血儿,宇文拓的后人。深受丕平三世的器重,主要担任收集情报等工作,因为屡立大功而被受封为骑士。后因接受丕平三世的任务而秘密离开高卢前往东方寻找所谓的战争不败之术,由此踏上漫漫征途。', - swd_kama:'来自印度的爱情精灵,与一只来自埃及的有翼黑猫一同旅行,黑猫名叫安卡。数百年来,卡玛跟人类有数不尽的爱情故事,大部分都以悲剧收场,她不断的在人间徘徊,为的是寻找永恒的知己。', - swd_nicole:'前世是独孤宁珂,灵魂被古月仙人用伏羲琴净化,因此未受到魔界污染。她没有过去的记忆,因此个性单纯,对许多事都好奇。后来受撒旦派遣来引导赛特,希望赛特能加入撒旦的阵营。', - swd_wangsiyue:'长安名士的孙女,熟读四书以及佛经,有才女之称,还没出嫁就有大批追求者,她的字画就能在市集上以高价卖出。她非常喜欢诗,特别是古朴的诗经的诗句,遇到说不出口的事,就用吟诗的方式表达。', - swd_weida:'阿拉伯女性,凯利宾瓦力德之后裔,女中豪杰,做事干脆利落,不喜欢拖拖拉拉。长期的军旅生涯,使她的行事作风与一般女性不同。阿拉伯世界的女子长年戴着面纱,不能与男子一起走路,薇达则是通通不遵守。', - swd_xuanyuanjianxian:'东汉末年,年幼的徐暮云的神识被应龙之女分离出来时附于野狼尸体上,化作金狼。因总想夺回成年徐暮云神识所控制的肉身而时常袭击徐暮云。在木门道获得剑气后化为人形,前往遥远的云和山的彼端,归隐为轩辕剑仙。平常能言善道,出口成章,甚至杀人出血成“书画”为其一绝。', - swd_xuanyuanjiantong:'由轩辕剑鞘幻化而成的仙童,好奇心很重,完全是个小孩子的心,跟轩辕剑仙成一老一少的对比。', - swd_chenjingchou:'为陈朝后裔。忠臣陈辅以“靖北虏,复国仇”为他命名“靖仇”。将所有的复国重任全都寄托于他身上。虽然师傅对其寄予厚望,但长大后的陈靖仇却个性温柔,只喜欢诗词与音乐,非常讨厌杀戮,无心复国,一心只想过着与世无争的平静生活。因这样的性格,被其师责为软弱无能、胸无大志。', - swd_duguningke:'西方魔王撒旦手下的女魔将。由撒旦派往神州,目的是扩大赤贯星在神州九天结界上所划开的裂痕。是撒旦侵略神州的前锋。与宇文拓自幼相识,对他怀有感情。因不愿在宇文拓面前吃下撒旦之果而变得丑陋,在赤贯星上败给陈靖仇一行人后悲凉死去,后古月圣将她的魂魄放入伏羲琴中净化99年,宇文拓带着她的魂魄一路西行,回到欧洲。经过净化后忘记前世记忆,转世成为妮可。', - swd_guyue:'仙山岛最深处隐居的年轻仙人,飘逸潇洒,气质不凡。据说他的医术在仙界,也堪称是第一、第二位之绝。真身为一只白狐,后与修炼成仙的何然同归仙山岛隐居,二人经常在对弈亭对弈,不问世事。', - swd_tuobayuer:'本是拓跋部落(鲜卑)遗民,世世代代保护拓跋族神器“神农鼎”。年幼的她有一次随族人外出游牧时,隋炀帝为凸显天威而发兵侵略冲袭留守的部民,父母惨死,神鼎被夺。自此对隋人产生极深敌意,苦苦恳求姐夫张烈教她武艺,日夜勤练,打算伺机南下找回神鼎,并替父母报仇。', - swd_yuwentuo:'又名杨拓,本是北周皇室后裔,因国家被隋朝所篡,他自小流落於民间。幸好隋朝名将杨素发现了他,看出他的素质,就收他为徒,并让自己师弟杨义臣收他为义子。12岁那年曾用轩辕剑歼灭南陈旧部叛乱,杨素死後,宇文拓就担负起继续捍卫杨家天下的重责大任。后通过昆仑镜预见未来,得知赤贯将要划破九天神州结界,决定再也不管隋家天下安危,转而全心寻找上古神器,只想阻止这场危机,担负起挽救神州的重任。', - swd_yuxiaoxue:'女娲石转世,自幼孤儿,由月河村客栈老板贺老伯抚养,满头白发被当地村人认为是不祥的象征,备受歧视。后来她村子被村人祭祀的河神所摧毁,村人把责任全归咎于她,她因而被永远逐出了自己故乡。', - swd_jiliang:'故韩王国贵族出身,世代公卿,祖父被封于张邑,因此也以张为氏。喜好思考,心思敏捷聪慧,好奇心非常旺盛。尽管看来手无缚鸡之力,但却能以过人的智慧,凭藉著最少的情报,而去推演出全局;以一人之力,而胜过千军万马。', - swd_shuijing:'墨家的年轻女弟子,故赵王国人。亲人在秦战火中丧生,被协防赵国的墨家弟子在废墟之中发现,带回交由墨家夫人收容抚养。', - swd_quxian:'墨家年轻女弟子,故楚王国人。出身贵族,带有独特高贵气质。由于亲眼目睹全家死于秦人机关部队,心中有难以抹灭之阴影。', - swd_xiyan:'来自云中界的灵犀族,被壶中仙选中做为入室弟子,由他负责整合云中界的种族纠纷。', - swd_cheyun:'令狐国人,祖父是令狐国的大夫。但昔日由于研究“御木为兵”的“木甲术”而被政敌北宫大夫构陷,最后遭到抄家灭族;车芸年幼,因之只被处以刖刑,需以木制义肢来行走。由家臣端木氏抚养,之后她继续秘密研究祖父的木甲术,誓要效忠国家,为祖父及家人平反。', - swd_huanyuanzhi:'东晋名将桓温的亲属,为了改变淝水之战秦灭晋的结局而来到春秋时代,成为了晋国太辰宫的“九龙子”祭司之一,人称“肆龙子”,代号为 “负屃”。设置五岳阵法把王霸之气汇聚晋国,好让一千年后变成晋灭秦,和四百年以前来自不同时空的土耀使者墨老先生是同一个灵魂。', - swd_murongshi:'自称昔日夏朝时负责保管「夏后祭器」的涂山氏后人,实际是从经桓远之改动的历史中穿越回来,目的是在太一之轮上刻下秦克晋生克从而改变历史。和车芸、苻殷是不同历史中同一灵魂的人。', - swd_jipeng:'聒噪自大的鹦鹉国王,鹦鹉王国「多毛国」国王。原是野心家蜀桑子部下,被壶中仙丢入「云中界」后,在那里建立了自己的鹦鹉王国。由于曾偷吃壶中仙的长生丹药,因此老化速度变慢,聒噪威力不减当年。为了保护老主人女儿(墨家夫人),随同水镜返回人间,参与对抗赤松子的战争。', - swd_qi:'上古文明的术者,沉睡千年后醒来,梦想重建古代王朝。古代蜀国的科学家,是一个天才少年。', - swd_luchengxuan:'从小便拥有着强大的力量,可是不懂得控制,被周遭的人当成怪物般的看待,导致养成阴郁犹疑不轻易吐露心声的性格,后来在探索自己拥有力量与生命意义的旅程中,逐渐历练成熟,进而立志发挥自己的力量协助他人。', - swd_xiarou:'纯洁无瑕的气质与温柔婉约的外表,让人以为她手无缚鸡之力,但其实体内蕴藏有相当强的灵力,与生俱来个性温柔娴静,聪慧坚强,带领着族人勇敢面对他族的侵略,希望苍生皆能过着和平安稳的生活。', - swd_moye:'青龙圣者手下,对于青龙圣者有着莫名崇拜,常因沉不住气而搞砸许多事,不过还是很受族人的喜爱,单纯的个性让她丝毫不会烦恼任何事太久。后奉青龙圣者委派携带圣宇盘前往山海界西方寻找继任青龙圣者。', - swd_zhaoyun:'朝云出生于三国时期普通的民家,荆州襄阳人。父亲皇甫疾,乃昔日刘表麾下的水师参军,荆州投降后,被曹魏所征召,后惨死于赤壁,母亲韩氏,则于关羽北伐时,死于逃难途中。朝云为把剩余不多的干粮留给一起逃难的姊弟,决心自我牺牲,趁夜偷偷离开他们,躲在荒野中,后来在饥寒交迫之中昏死,为路过的名将赵云救起。赵云将他带至一收容战火孤儿的组织,让他有栖身之所。后来,朝云在一次支援粮秣运输工作中,意外以剑气救了误入曹贼陷阱中的赵云及所属部队,此后,赵云便夜夜蒙面,把朝云带至营后的山上,传授枪戟武术。最终朝云在天干十杰选拔中获得首位拿下“焉逢”称号,成为蜀汉精英部队“飞羽”的“羽之部”领导人。', - swd_hengai:'充满神秘色彩之女子。聪明而慧黠,凡事颇有自己见地。携上古神器「炼妖壶」在身,不时会同情敌人,又不喜杀戮的姑娘。擅法术,一头异于常人之蓝色长发,据说乃昔日为修练高深法术所造成。她对焉逢甚有好感,却又保持距离,态度甚为微妙。', - swd_duanmeng:'马良之女,本名马蕴。马良死后流落南蛮,后在诸葛亮平定南中时被马良之弟马谡找到并收为义女。马谡因街亭失守被斩,马蕴认为父亲是优秀幕僚而非将帅之才,街亭失守主因在于诸葛亮用人不当。为建立功勋,洗刷父亲的污名,马蕴加入飞羽部队,在「天干十杰」选拔中获得第二名「端蒙」称号,成为飞之部领导人', - swd_jiangwu:'故巴东郡主簿严函之子,因诸葛亮曾为父亲严函洗脱冤情,故对其为人与公忠体国的精神十分景仰,因此将报效朝廷一事,置于个人一己的功业之上。左手持巨弓,右手配强弩,擅远距离攻击,有百步穿杨能力。他与焉逢乃是战场上一起出生入死之多年至交,二人情深谊厚,因此平日彼此之间从不以代号互称,而皆直称对方本名。以自己能身为「飞羽」一员而深深自豪。', - swd_tuwei:'容貌清秀,但沉默寡言的青年。平日常闭目若有所思,偶一说话,也仅简单几个字回应而已。与横艾为同门之师姊弟,但飞羽「十杰」排名却意外地在横艾之上。他与横艾一样,坚不透露所属之道术门派,来历神秘。擅长疗愈系之法术', - swd_yeyaxi:'孙尚香的义女,深色肌肤,大眼睛,天真无邪。是吴帝孙权派人出海寻找传说中之夷洲、亶洲时,所掳回之夷洲当地原住民少女。耶亚希心里偷恋焉逢,于是在孙尚香请托下,随焉逢一行人共同旅行历练。', - swd_muyun:'皇甫朝云之弟,幼时遭逢变故,流落荒野,幸得魏国前御史中丞徐庶所救,将之收为养子,抚养成人。在洛阳的那段童年时光中,暮云与青梅竹马兰茵、以及魏国名将张郃之孙张诰相交甚笃,一同习剑成长。十年匆匆,暮云如今已是英姿焕发、名满洛阳的少年剑客,但为求精进,暮云始终勤练剑术,希望有朝一日能以一身武艺协助恩师张郃,报效朝廷。', - swd_lanyin:'魏国名将张郃,府中之女剑僮。性格温婉可人,剑术高超,身手利落,深为张郃所赏识。与暮云为青梅竹马,二人情投意合,经常一起行动。真实身份为应龙之女。', - swd_zhiyin:'女性法师,自称多年前随师父旅行至洛阳时与兰茵相遇,认作姊妹,实际与兰茵均为应龙之女的分身。个性果决,伶俐慧黠。于并西胡匈之地修习道术、降妖伏魔。', - swd_qiner:'「铜雀尊者」之副领导人,赤衣尊者,虽年纪轻轻,却有着令人难以置信之惊人实力,能施展许多强大而罕见的术法。随身总是抱着一只琵琶,以音律操纵幻术、幻兽来进行各式各样之攻击。天女青儿赠予巫山女神瑶姬的四样乐器中的磬所化。', - swd_jiuyou:'本名久须毗呼,来自东方邪马台国之清秀少年。他乃是多年前邪马台国领袖日御子(卑弥呼)私下派遣至辽东接触的使臣之一,由于对中原风土民情、文化制度深为着迷,便决定留下游历。身手非凡能使术法与剑术,持有剑、镜、玉三大法器。', - swd_duopeng:'来自桃源界之多毛民,自称是多毛国疾鹏大王驾前第一勇士「禽灵天尊铁爪无敌啸风攫魂多毛翔鹏大元帅」。多鹏不小心打碎了留侯夫人夫君(姬良)送给她的最喜爱的琉璃花瓶,担心被留侯夫人(水镜)宰了煮了吃。于是逃离了桃源仙境,来到了轩辕界。遇见了寻找盘古斧的兰茵,带领兰茵到云中界寻找盘古斧。', - swd_fengtianling:'商朝东方最强大的诸侯国──奄国大夫凤千平之子,外貌不俗,时刻流露出强烈的贵族气质与自信,但他脸上仍保有些许少年之青涩。从小生长在商民大族中的凤天凌,家中有一位哥哥,两人从小跟随住在太山上的师父习剑,剑术天分十分被肯定。', - swd_huyue:'九尾狐妖,商亡后狐妖一族被商朝太师诛灭,因年幼未被发现而逃过一劫。与幼时的凤天凌因巧合相遇,与其成为好友。', - swd_jialanduo:'迦兰多来自遥远的身毒国,身为身毒皇室的后裔,他却只身一人千里迢迢来到中原,只为了寻找昔日比他更早之前便独自前来中原、但如今却音信全无的亲姐姐。', - swd_rongshuang:'蓉霜来自中原西南方的古蜀国,是师承古蜀文明“战甲”一派的谜样少女。由于蓉霜初懂中原语言,因此在战甲师群中战力不算特别强大的她,也一起被派遣前来中原执行任务。', - swd_zhuoshanzhu:'战甲技能非常优秀的浊山铸,深受黑火门掌门师尊的重视,并有意指定他为自己的继承人。当师尊得知中原曾出现黑火踪迹,便下令浊山铸率领众徒前往中原,务必将黑火带回蜀国。任务途中,浊山铸为了保蓉霜周全,惨遭敌对门派痛下杀手,被埋葬在异国他乡黄土之下。', - swd_jiting:'周朝王姬,好武且崇尚英雄,擅长于箭术与驭车。其人飒爽英姿、风华绝代,以长弓为贴身武器。逃不开政治婚姻的宿命,因对未来夫君充满好奇并且不愿盲目嫁人,遂毅然离开镐京去寻求真相。', - swd_sikongyu:'来自有熊村,祖先自夏朝被灭后一直四处迁徙躲避战乱。习练的武功是司空一家代代相传的棍术,但也痴迷于研究陷阱、鸣竹等防御外来者入侵的机关,希望通过自己的本领使族人过上安稳的生活。', - swd_muyue:'华胥人,千年前,颛顼帝与华胥国主联手施行“绝地天通”之阵关闭天门,以绝世人登天之妄想,平天下之乱。“绝地天通”阵势浩大,需以华胥族人的魂灵为祭,沐月本欲替代被选为做辅祭的姐姐入阵,却在最后时刻因信念不够坚定,错过了施术时间。最终,天门关闭,华胥国被建木托升至天际,沐月独自留守在华胥。千年后,相柳为重开天门,借助青榆和伏羲琴之力试图破坏结界,沐月因此坠入人间。', - swd_ziqiao:'子国巫人之女,拥有凭神的体质。身材虽然娇小,却拥有常人所没有的力量,能够轻易的挥动巨斧作战。', - swd_fengyu:'商朝王子,化名凤煜四处游历,希望能找到解决商朝内忧外患的局面的方法', - swd_huanglei:'擅长古传的机关术(鲁班一脉),曾经在任官于唐朝政府少府监,因为被李林甫排挤而对政府怀恨在心。他出任高仙芝的参谋,出了主意灭掉石国,又企图干扰大食(阿拉伯)改朝换代,引起怛罗斯之战。当高仙芝返回长安,听其余的部属劝告,又因怛罗斯之战失利跟黄雷脱不了关系,疏远黄雷。黄雷转而投靠安禄山,想藉安禄山的叛乱取得势力。', - swd_lilian:'生长在一个贵族家庭,是第三千金,她父亲已经许婚给其他贵族,但她却迷恋上来做客的骑士麦尔斯,之后麦尔斯出任务到威尼斯,莉莲也偷偷的带着她的爱犬波尔去追随他。', - swd_kangnalishi:'梅罗文加护教骑士的指导教士,直属罗马教皇。在高卢没有一个人喜欢这个神情诡异的人。讲话都会带给人恐惧感。他称麦尔斯是他教出来最完美的骑士。', - swd_huiyan:'慧彦俗名刘书经,从小被誉为神童,一心想金榜题名,由于过于狂妄自大,在考场取笑主考官而被逐出考场,觉得了无生趣,也不敢回乡面对乡亲父老,游荡到嵩山时,对那些会武术的和尚发生兴趣,于是就在少林寺出家。慧彦天资聪颖,无论在武术、佛学上几乎凌驾师辈后来对少林祖师达摩的事迹产生兴趣。当时唐僧玄奘去天竺取经的事迹为世人尊崇,而从天竺来到达摩所教的(禅宗)却还有些出入,于是想亲身去天竺求证,获得唐玄宗支持,让他持使节信符出关。但唐玄宗额外交代一些军事上的任务,慧彦必须协助探查远至大食附近诸国的军事情势。', - swd_shanxiaoxiao:'独孤宁珂的婢女,是宁珂来到中原之后收伏的千年琵琶精。', - swd_yuchiyanhong:'独孤宁珂的婢女,是宁珂来到中原之后收伏之千年狐狸精。', - swd_hanluo:'寒洛是玄武国世子,因与知盈的婚事遭其父玄武侯反对,而与之私奔。', - swd_fu:'福来自毛民国,因助陆承轩、夏柔搭救被毛民抓来做祭品的莫耶而得罪族人,而后随陆承轩等人离开。', - swd_linyue:'来自氐人国的老医生,医术高明。醉心于各种医学技术,因此常外出云游,四处学习。随遇而安的个性让他不过于担心身边的人事物。', - swd_zidashu:'周侥国王子,十分仰慕陆承轩等人的高超武艺,故随其一同游历,磨练自己。', - swd_maixing:'奇肱国老神丁的徒弟。虽然是奇肱族近来难见的天才,但好胜的个性,让他常与旁人发生争执,孤独的他在没有比较之下更以为自己技术高超,另急躁的个性也让他急于试验自己未完成的工艺品,以致于常造成大乌龙。', - swd_fuyan:'俱有满腔的热血与爱国心,外表虽然像其他白虎族人一样勇猛,其实是自幼常生病的药罐子。', - swd_haidapang:'一目民,能在远处就注意到周遭的状况,一有危险马上逃跑!过于小心翼翼的性格,对于外界既害怕又好奇,总是张着大眼睛四处观望,又像惊弓之鸟似的随时保持警戒,做好逃跑的准备。', - swd_shaowei:'生在朱雀国,个性高傲、善变,因与主角战斗受伤,因而忘记过去的朱雀族少女。时而天真迷惘、时而冷漠无情、时而阴狠狡诈,不知何者是她的本性。', - swd_youzhao:'名将赵云之孙,枪法凛冽,胆识过人。一心追求建立不世之功业,期许自己能协助大汉讨灭曹贼,克复中原,以光耀祖先之名声。性格冷傲孤高,对自己在「天干十杰」名次排行战之中,竟输给了籍籍无名之孤儿焉逢,暗自耿耿为怀不已。执行任务时,出手迅疾猛狠,对敌人毫不留情,是极出色之菁英战士。', - swd_shangzhang:'端蒙之弟,马谡之子。由于姊姊不顾家族劝阻,坚持加入飞羽,他十分担忧她的安危,便努力苦练武艺,历经艰难之后,终于在高手如林的飞羽「天干十杰」争夺战之中,以遍体鳞伤却仍力战不懈之姿,撼动所有战友,最后如愿挤入了十天干最末一个名位。他配属于「飞之部」,在姊姊身边默默守护她。', - swd_situqiang:'原籍长安,父亲原是魏国医官,后因治疫不力遭罢,举家放逐。父亲死后,司徒蔷便想运用其自幼所习的知识,行走各地教授防疫知识。', - swd_chunyuheng:'字长生。身拥承袭淳于一脉的绝顶医术,却不轻易替人治病。因淳于一族不长命且无法治好自己的怪病,导致性情古怪孤僻,且言谈之间尽是轻生之词,让人难以亲近。最后知晓原因后,得同伴帮助,消除诅咒。', - swd_hanlong:'魁梧高大,身手矫健,能单手持巨刃而面不改色,是一本事卓绝之勇士。原为并西之地的胡族,因该地官员贪暴,其父反抗却遭杀害,他为照顾母亲,无奈沦为草莽盗匪,靠打劫路过达官显贵以维生。', - swd_yuli:'他人以为是鱼妖而自称是鱼仙的混仙。在徐暮云等人追查鱼妖传闻的真相时,与其相遇,却从此成为助她成仙的伙伴。', - swd_zhanggao:'字柏乔,为大魏名将张郃之孙,同时亦是徐暮云情谊深笃之挚友。暮云视他彷若兄长,十分尊敬。不时与暮云切磋剑术,互相砥砺,同为洛阳著名之少年剑客。', - swd_hupo:'属于山林鬼神一族,全身雪白,眼睛碧蓝,一对长而尖细的耳朵,长着一簇蓬松的大尾巴。它的同族都是力量强大的山林鬼魅,但一般人并看不到它们,只有拥有特殊能力的人才能看得见。', - swd_jiangziya:'周军统帅、周朝开国元勋,是一位尤其擅长法术攻击的权谋大家。曾修改了用于记载宇宙间万物生克关系的神器“太一之轮”,并留下了“周克商”的生克,造就牧野之战的胜利。', + characterIntro: { + swd_kendi: + "占星大师老肯迪的孙子,老肯迪死后,他也自称肯迪,伪装成老肯迪,以保护老肯迪的藏书。肯迪平常以接受委托抄书与翻译拉丁文书籍为业,除了占星术以外,其余知识也相当广博。为了增长见闻,什么可怕的地方都敢去,所以认识薇达与不少的军官。后来,肯迪的子孙成为伊斯兰地区的大学者,以因果定律的学说著名于世。", + swd_shuwaner: + "第一代祝犁黄汉卿的妻子,二代祝犁黄采儿的母亲。陷阱机关师,擅长火系陷阱,并能驱使一种可爆裂来杀敌之神秘「火丹」技术。", + swd_xiaohuanglong: "龙族之幻兽,后土之神将它送给兰茵避险,以保护她安全。", + swd_huzhongxian: + "炼妖壶是女娲神所创,是以开天辟地创造生命的工具,开创出万物后即遗留于某一处水底神殿中。由巴蛇及蛟龟守护该神器,过了约莫千年之久,炼妖壶已可幻化成人形,即为壶中仙。此时正因人类对异类的排斥,巴蛇对此愤愤不平,壶中仙与巴蛇讨论人魔共存的方法,但巴蛇觉得壶中仙是另有所图。自不采用,一日趁壶中仙不注意,将炼妖壶的妖怪全数释放,留下蛟龟看守练妖壶,巴蛇率领魔族大军反攻人类,从此人魔之战一直持续着。", + swd_anka: + "安卡在数千年前,曾经是法老王的宠物。在法老王过世后,本来要当陪葬品,却被一位也要被陪葬的祭司带着逃走,安卡借着长期跟随祭司,学得不少后来传到欧洲的黑魔法,成了一只猫精。但在欧洲黑猫很不受欢迎,之后遇上卡玛,成为共患难的好友。安卡有许多癖好,像是收集漂亮的石头把它藏起来,若是日后又发现会很高兴。", + swd_septem: + "欧洲梅罗文加王朝高卢出生的东方人与日耳曼混血儿,宇文拓的后人。深受丕平三世的器重,主要担任收集情报等工作,因为屡立大功而被受封为骑士。后因接受丕平三世的任务而秘密离开高卢前往东方寻找所谓的战争不败之术,由此踏上漫漫征途。", + swd_kama: + "来自印度的爱情精灵,与一只来自埃及的有翼黑猫一同旅行,黑猫名叫安卡。数百年来,卡玛跟人类有数不尽的爱情故事,大部分都以悲剧收场,她不断的在人间徘徊,为的是寻找永恒的知己。", + swd_nicole: + "前世是独孤宁珂,灵魂被古月仙人用伏羲琴净化,因此未受到魔界污染。她没有过去的记忆,因此个性单纯,对许多事都好奇。后来受撒旦派遣来引导赛特,希望赛特能加入撒旦的阵营。", + swd_wangsiyue: + "长安名士的孙女,熟读四书以及佛经,有才女之称,还没出嫁就有大批追求者,她的字画就能在市集上以高价卖出。她非常喜欢诗,特别是古朴的诗经的诗句,遇到说不出口的事,就用吟诗的方式表达。", + swd_weida: + "阿拉伯女性,凯利宾瓦力德之后裔,女中豪杰,做事干脆利落,不喜欢拖拖拉拉。长期的军旅生涯,使她的行事作风与一般女性不同。阿拉伯世界的女子长年戴着面纱,不能与男子一起走路,薇达则是通通不遵守。", + swd_xuanyuanjianxian: + "东汉末年,年幼的徐暮云的神识被应龙之女分离出来时附于野狼尸体上,化作金狼。因总想夺回成年徐暮云神识所控制的肉身而时常袭击徐暮云。在木门道获得剑气后化为人形,前往遥远的云和山的彼端,归隐为轩辕剑仙。平常能言善道,出口成章,甚至杀人出血成“书画”为其一绝。", + swd_xuanyuanjiantong: + "由轩辕剑鞘幻化而成的仙童,好奇心很重,完全是个小孩子的心,跟轩辕剑仙成一老一少的对比。", + swd_chenjingchou: + "为陈朝后裔。忠臣陈辅以“靖北虏,复国仇”为他命名“靖仇”。将所有的复国重任全都寄托于他身上。虽然师傅对其寄予厚望,但长大后的陈靖仇却个性温柔,只喜欢诗词与音乐,非常讨厌杀戮,无心复国,一心只想过着与世无争的平静生活。因这样的性格,被其师责为软弱无能、胸无大志。", + swd_duguningke: + "西方魔王撒旦手下的女魔将。由撒旦派往神州,目的是扩大赤贯星在神州九天结界上所划开的裂痕。是撒旦侵略神州的前锋。与宇文拓自幼相识,对他怀有感情。因不愿在宇文拓面前吃下撒旦之果而变得丑陋,在赤贯星上败给陈靖仇一行人后悲凉死去,后古月圣将她的魂魄放入伏羲琴中净化99年,宇文拓带着她的魂魄一路西行,回到欧洲。经过净化后忘记前世记忆,转世成为妮可。", + swd_guyue: + "仙山岛最深处隐居的年轻仙人,飘逸潇洒,气质不凡。据说他的医术在仙界,也堪称是第一、第二位之绝。真身为一只白狐,后与修炼成仙的何然同归仙山岛隐居,二人经常在对弈亭对弈,不问世事。", + swd_tuobayuer: + "本是拓跋部落(鲜卑)遗民,世世代代保护拓跋族神器“神农鼎”。年幼的她有一次随族人外出游牧时,隋炀帝为凸显天威而发兵侵略冲袭留守的部民,父母惨死,神鼎被夺。自此对隋人产生极深敌意,苦苦恳求姐夫张烈教她武艺,日夜勤练,打算伺机南下找回神鼎,并替父母报仇。", + swd_yuwentuo: + "又名杨拓,本是北周皇室后裔,因国家被隋朝所篡,他自小流落於民间。幸好隋朝名将杨素发现了他,看出他的素质,就收他为徒,并让自己师弟杨义臣收他为义子。12岁那年曾用轩辕剑歼灭南陈旧部叛乱,杨素死後,宇文拓就担负起继续捍卫杨家天下的重责大任。后通过昆仑镜预见未来,得知赤贯将要划破九天神州结界,决定再也不管隋家天下安危,转而全心寻找上古神器,只想阻止这场危机,担负起挽救神州的重任。", + swd_yuxiaoxue: + "女娲石转世,自幼孤儿,由月河村客栈老板贺老伯抚养,满头白发被当地村人认为是不祥的象征,备受歧视。后来她村子被村人祭祀的河神所摧毁,村人把责任全归咎于她,她因而被永远逐出了自己故乡。", + swd_jiliang: + "故韩王国贵族出身,世代公卿,祖父被封于张邑,因此也以张为氏。喜好思考,心思敏捷聪慧,好奇心非常旺盛。尽管看来手无缚鸡之力,但却能以过人的智慧,凭藉著最少的情报,而去推演出全局;以一人之力,而胜过千军万马。", + swd_shuijing: + "墨家的年轻女弟子,故赵王国人。亲人在秦战火中丧生,被协防赵国的墨家弟子在废墟之中发现,带回交由墨家夫人收容抚养。", + swd_quxian: + "墨家年轻女弟子,故楚王国人。出身贵族,带有独特高贵气质。由于亲眼目睹全家死于秦人机关部队,心中有难以抹灭之阴影。", + swd_xiyan: "来自云中界的灵犀族,被壶中仙选中做为入室弟子,由他负责整合云中界的种族纠纷。", + swd_cheyun: + "令狐国人,祖父是令狐国的大夫。但昔日由于研究“御木为兵”的“木甲术”而被政敌北宫大夫构陷,最后遭到抄家灭族;车芸年幼,因之只被处以刖刑,需以木制义肢来行走。由家臣端木氏抚养,之后她继续秘密研究祖父的木甲术,誓要效忠国家,为祖父及家人平反。", + swd_huanyuanzhi: + "东晋名将桓温的亲属,为了改变淝水之战秦灭晋的结局而来到春秋时代,成为了晋国太辰宫的“九龙子”祭司之一,人称“肆龙子”,代号为 “负屃”。设置五岳阵法把王霸之气汇聚晋国,好让一千年后变成晋灭秦,和四百年以前来自不同时空的土耀使者墨老先生是同一个灵魂。", + swd_murongshi: + "自称昔日夏朝时负责保管「夏后祭器」的涂山氏后人,实际是从经桓远之改动的历史中穿越回来,目的是在太一之轮上刻下秦克晋生克从而改变历史。和车芸、苻殷是不同历史中同一灵魂的人。", + swd_jipeng: + "聒噪自大的鹦鹉国王,鹦鹉王国「多毛国」国王。原是野心家蜀桑子部下,被壶中仙丢入「云中界」后,在那里建立了自己的鹦鹉王国。由于曾偷吃壶中仙的长生丹药,因此老化速度变慢,聒噪威力不减当年。为了保护老主人女儿(墨家夫人),随同水镜返回人间,参与对抗赤松子的战争。", + swd_qi: "上古文明的术者,沉睡千年后醒来,梦想重建古代王朝。古代蜀国的科学家,是一个天才少年。", + swd_luchengxuan: + "从小便拥有着强大的力量,可是不懂得控制,被周遭的人当成怪物般的看待,导致养成阴郁犹疑不轻易吐露心声的性格,后来在探索自己拥有力量与生命意义的旅程中,逐渐历练成熟,进而立志发挥自己的力量协助他人。", + swd_xiarou: + "纯洁无瑕的气质与温柔婉约的外表,让人以为她手无缚鸡之力,但其实体内蕴藏有相当强的灵力,与生俱来个性温柔娴静,聪慧坚强,带领着族人勇敢面对他族的侵略,希望苍生皆能过着和平安稳的生活。", + swd_moye: + "青龙圣者手下,对于青龙圣者有着莫名崇拜,常因沉不住气而搞砸许多事,不过还是很受族人的喜爱,单纯的个性让她丝毫不会烦恼任何事太久。后奉青龙圣者委派携带圣宇盘前往山海界西方寻找继任青龙圣者。", + swd_zhaoyun: + "朝云出生于三国时期普通的民家,荆州襄阳人。父亲皇甫疾,乃昔日刘表麾下的水师参军,荆州投降后,被曹魏所征召,后惨死于赤壁,母亲韩氏,则于关羽北伐时,死于逃难途中。朝云为把剩余不多的干粮留给一起逃难的姊弟,决心自我牺牲,趁夜偷偷离开他们,躲在荒野中,后来在饥寒交迫之中昏死,为路过的名将赵云救起。赵云将他带至一收容战火孤儿的组织,让他有栖身之所。后来,朝云在一次支援粮秣运输工作中,意外以剑气救了误入曹贼陷阱中的赵云及所属部队,此后,赵云便夜夜蒙面,把朝云带至营后的山上,传授枪戟武术。最终朝云在天干十杰选拔中获得首位拿下“焉逢”称号,成为蜀汉精英部队“飞羽”的“羽之部”领导人。", + swd_hengai: + "充满神秘色彩之女子。聪明而慧黠,凡事颇有自己见地。携上古神器「炼妖壶」在身,不时会同情敌人,又不喜杀戮的姑娘。擅法术,一头异于常人之蓝色长发,据说乃昔日为修练高深法术所造成。她对焉逢甚有好感,却又保持距离,态度甚为微妙。", + swd_duanmeng: + "马良之女,本名马蕴。马良死后流落南蛮,后在诸葛亮平定南中时被马良之弟马谡找到并收为义女。马谡因街亭失守被斩,马蕴认为父亲是优秀幕僚而非将帅之才,街亭失守主因在于诸葛亮用人不当。为建立功勋,洗刷父亲的污名,马蕴加入飞羽部队,在「天干十杰」选拔中获得第二名「端蒙」称号,成为飞之部领导人", + swd_jiangwu: + "故巴东郡主簿严函之子,因诸葛亮曾为父亲严函洗脱冤情,故对其为人与公忠体国的精神十分景仰,因此将报效朝廷一事,置于个人一己的功业之上。左手持巨弓,右手配强弩,擅远距离攻击,有百步穿杨能力。他与焉逢乃是战场上一起出生入死之多年至交,二人情深谊厚,因此平日彼此之间从不以代号互称,而皆直称对方本名。以自己能身为「飞羽」一员而深深自豪。", + swd_tuwei: + "容貌清秀,但沉默寡言的青年。平日常闭目若有所思,偶一说话,也仅简单几个字回应而已。与横艾为同门之师姊弟,但飞羽「十杰」排名却意外地在横艾之上。他与横艾一样,坚不透露所属之道术门派,来历神秘。擅长疗愈系之法术", + swd_yeyaxi: + "孙尚香的义女,深色肌肤,大眼睛,天真无邪。是吴帝孙权派人出海寻找传说中之夷洲、亶洲时,所掳回之夷洲当地原住民少女。耶亚希心里偷恋焉逢,于是在孙尚香请托下,随焉逢一行人共同旅行历练。", + swd_muyun: + "皇甫朝云之弟,幼时遭逢变故,流落荒野,幸得魏国前御史中丞徐庶所救,将之收为养子,抚养成人。在洛阳的那段童年时光中,暮云与青梅竹马兰茵、以及魏国名将张郃之孙张诰相交甚笃,一同习剑成长。十年匆匆,暮云如今已是英姿焕发、名满洛阳的少年剑客,但为求精进,暮云始终勤练剑术,希望有朝一日能以一身武艺协助恩师张郃,报效朝廷。", + swd_lanyin: + "魏国名将张郃,府中之女剑僮。性格温婉可人,剑术高超,身手利落,深为张郃所赏识。与暮云为青梅竹马,二人情投意合,经常一起行动。真实身份为应龙之女。", + swd_zhiyin: + "女性法师,自称多年前随师父旅行至洛阳时与兰茵相遇,认作姊妹,实际与兰茵均为应龙之女的分身。个性果决,伶俐慧黠。于并西胡匈之地修习道术、降妖伏魔。", + swd_qiner: + "「铜雀尊者」之副领导人,赤衣尊者,虽年纪轻轻,却有着令人难以置信之惊人实力,能施展许多强大而罕见的术法。随身总是抱着一只琵琶,以音律操纵幻术、幻兽来进行各式各样之攻击。天女青儿赠予巫山女神瑶姬的四样乐器中的磬所化。", + swd_jiuyou: + "本名久须毗呼,来自东方邪马台国之清秀少年。他乃是多年前邪马台国领袖日御子(卑弥呼)私下派遣至辽东接触的使臣之一,由于对中原风土民情、文化制度深为着迷,便决定留下游历。身手非凡能使术法与剑术,持有剑、镜、玉三大法器。", + swd_duopeng: + "来自桃源界之多毛民,自称是多毛国疾鹏大王驾前第一勇士「禽灵天尊铁爪无敌啸风攫魂多毛翔鹏大元帅」。多鹏不小心打碎了留侯夫人夫君(姬良)送给她的最喜爱的琉璃花瓶,担心被留侯夫人(水镜)宰了煮了吃。于是逃离了桃源仙境,来到了轩辕界。遇见了寻找盘古斧的兰茵,带领兰茵到云中界寻找盘古斧。", + swd_fengtianling: + "商朝东方最强大的诸侯国──奄国大夫凤千平之子,外貌不俗,时刻流露出强烈的贵族气质与自信,但他脸上仍保有些许少年之青涩。从小生长在商民大族中的凤天凌,家中有一位哥哥,两人从小跟随住在太山上的师父习剑,剑术天分十分被肯定。", + swd_huyue: + "九尾狐妖,商亡后狐妖一族被商朝太师诛灭,因年幼未被发现而逃过一劫。与幼时的凤天凌因巧合相遇,与其成为好友。", + swd_jialanduo: + "迦兰多来自遥远的身毒国,身为身毒皇室的后裔,他却只身一人千里迢迢来到中原,只为了寻找昔日比他更早之前便独自前来中原、但如今却音信全无的亲姐姐。", + swd_rongshuang: + "蓉霜来自中原西南方的古蜀国,是师承古蜀文明“战甲”一派的谜样少女。由于蓉霜初懂中原语言,因此在战甲师群中战力不算特别强大的她,也一起被派遣前来中原执行任务。", + swd_zhuoshanzhu: + "战甲技能非常优秀的浊山铸,深受黑火门掌门师尊的重视,并有意指定他为自己的继承人。当师尊得知中原曾出现黑火踪迹,便下令浊山铸率领众徒前往中原,务必将黑火带回蜀国。任务途中,浊山铸为了保蓉霜周全,惨遭敌对门派痛下杀手,被埋葬在异国他乡黄土之下。", + swd_jiting: + "周朝王姬,好武且崇尚英雄,擅长于箭术与驭车。其人飒爽英姿、风华绝代,以长弓为贴身武器。逃不开政治婚姻的宿命,因对未来夫君充满好奇并且不愿盲目嫁人,遂毅然离开镐京去寻求真相。", + swd_sikongyu: + "来自有熊村,祖先自夏朝被灭后一直四处迁徙躲避战乱。习练的武功是司空一家代代相传的棍术,但也痴迷于研究陷阱、鸣竹等防御外来者入侵的机关,希望通过自己的本领使族人过上安稳的生活。", + swd_muyue: + "华胥人,千年前,颛顼帝与华胥国主联手施行“绝地天通”之阵关闭天门,以绝世人登天之妄想,平天下之乱。“绝地天通”阵势浩大,需以华胥族人的魂灵为祭,沐月本欲替代被选为做辅祭的姐姐入阵,却在最后时刻因信念不够坚定,错过了施术时间。最终,天门关闭,华胥国被建木托升至天际,沐月独自留守在华胥。千年后,相柳为重开天门,借助青榆和伏羲琴之力试图破坏结界,沐月因此坠入人间。", + swd_ziqiao: + "子国巫人之女,拥有凭神的体质。身材虽然娇小,却拥有常人所没有的力量,能够轻易的挥动巨斧作战。", + swd_fengyu: "商朝王子,化名凤煜四处游历,希望能找到解决商朝内忧外患的局面的方法", + swd_huanglei: + "擅长古传的机关术(鲁班一脉),曾经在任官于唐朝政府少府监,因为被李林甫排挤而对政府怀恨在心。他出任高仙芝的参谋,出了主意灭掉石国,又企图干扰大食(阿拉伯)改朝换代,引起怛罗斯之战。当高仙芝返回长安,听其余的部属劝告,又因怛罗斯之战失利跟黄雷脱不了关系,疏远黄雷。黄雷转而投靠安禄山,想藉安禄山的叛乱取得势力。", + swd_lilian: + "生长在一个贵族家庭,是第三千金,她父亲已经许婚给其他贵族,但她却迷恋上来做客的骑士麦尔斯,之后麦尔斯出任务到威尼斯,莉莲也偷偷的带着她的爱犬波尔去追随他。", + swd_kangnalishi: + "梅罗文加护教骑士的指导教士,直属罗马教皇。在高卢没有一个人喜欢这个神情诡异的人。讲话都会带给人恐惧感。他称麦尔斯是他教出来最完美的骑士。", + swd_huiyan: + "慧彦俗名刘书经,从小被誉为神童,一心想金榜题名,由于过于狂妄自大,在考场取笑主考官而被逐出考场,觉得了无生趣,也不敢回乡面对乡亲父老,游荡到嵩山时,对那些会武术的和尚发生兴趣,于是就在少林寺出家。慧彦天资聪颖,无论在武术、佛学上几乎凌驾师辈后来对少林祖师达摩的事迹产生兴趣。当时唐僧玄奘去天竺取经的事迹为世人尊崇,而从天竺来到达摩所教的(禅宗)却还有些出入,于是想亲身去天竺求证,获得唐玄宗支持,让他持使节信符出关。但唐玄宗额外交代一些军事上的任务,慧彦必须协助探查远至大食附近诸国的军事情势。", + swd_shanxiaoxiao: "独孤宁珂的婢女,是宁珂来到中原之后收伏的千年琵琶精。", + swd_yuchiyanhong: "独孤宁珂的婢女,是宁珂来到中原之后收伏之千年狐狸精。", + swd_hanluo: "寒洛是玄武国世子,因与知盈的婚事遭其父玄武侯反对,而与之私奔。", + swd_fu: "福来自毛民国,因助陆承轩、夏柔搭救被毛民抓来做祭品的莫耶而得罪族人,而后随陆承轩等人离开。", + swd_linyue: + "来自氐人国的老医生,医术高明。醉心于各种医学技术,因此常外出云游,四处学习。随遇而安的个性让他不过于担心身边的人事物。", + swd_zidashu: "周侥国王子,十分仰慕陆承轩等人的高超武艺,故随其一同游历,磨练自己。", + swd_maixing: + "奇肱国老神丁的徒弟。虽然是奇肱族近来难见的天才,但好胜的个性,让他常与旁人发生争执,孤独的他在没有比较之下更以为自己技术高超,另急躁的个性也让他急于试验自己未完成的工艺品,以致于常造成大乌龙。", + swd_fuyan: "俱有满腔的热血与爱国心,外表虽然像其他白虎族人一样勇猛,其实是自幼常生病的药罐子。", + swd_haidapang: + "一目民,能在远处就注意到周遭的状况,一有危险马上逃跑!过于小心翼翼的性格,对于外界既害怕又好奇,总是张着大眼睛四处观望,又像惊弓之鸟似的随时保持警戒,做好逃跑的准备。", + swd_shaowei: + "生在朱雀国,个性高傲、善变,因与主角战斗受伤,因而忘记过去的朱雀族少女。时而天真迷惘、时而冷漠无情、时而阴狠狡诈,不知何者是她的本性。", + swd_youzhao: + "名将赵云之孙,枪法凛冽,胆识过人。一心追求建立不世之功业,期许自己能协助大汉讨灭曹贼,克复中原,以光耀祖先之名声。性格冷傲孤高,对自己在「天干十杰」名次排行战之中,竟输给了籍籍无名之孤儿焉逢,暗自耿耿为怀不已。执行任务时,出手迅疾猛狠,对敌人毫不留情,是极出色之菁英战士。", + swd_shangzhang: + "端蒙之弟,马谡之子。由于姊姊不顾家族劝阻,坚持加入飞羽,他十分担忧她的安危,便努力苦练武艺,历经艰难之后,终于在高手如林的飞羽「天干十杰」争夺战之中,以遍体鳞伤却仍力战不懈之姿,撼动所有战友,最后如愿挤入了十天干最末一个名位。他配属于「飞之部」,在姊姊身边默默守护她。", + swd_situqiang: + "原籍长安,父亲原是魏国医官,后因治疫不力遭罢,举家放逐。父亲死后,司徒蔷便想运用其自幼所习的知识,行走各地教授防疫知识。", + swd_chunyuheng: + "字长生。身拥承袭淳于一脉的绝顶医术,却不轻易替人治病。因淳于一族不长命且无法治好自己的怪病,导致性情古怪孤僻,且言谈之间尽是轻生之词,让人难以亲近。最后知晓原因后,得同伴帮助,消除诅咒。", + swd_hanlong: + "魁梧高大,身手矫健,能单手持巨刃而面不改色,是一本事卓绝之勇士。原为并西之地的胡族,因该地官员贪暴,其父反抗却遭杀害,他为照顾母亲,无奈沦为草莽盗匪,靠打劫路过达官显贵以维生。", + swd_yuli: + "他人以为是鱼妖而自称是鱼仙的混仙。在徐暮云等人追查鱼妖传闻的真相时,与其相遇,却从此成为助她成仙的伙伴。", + swd_zhanggao: + "字柏乔,为大魏名将张郃之孙,同时亦是徐暮云情谊深笃之挚友。暮云视他彷若兄长,十分尊敬。不时与暮云切磋剑术,互相砥砺,同为洛阳著名之少年剑客。", + swd_hupo: + "属于山林鬼神一族,全身雪白,眼睛碧蓝,一对长而尖细的耳朵,长着一簇蓬松的大尾巴。它的同族都是力量强大的山林鬼魅,但一般人并看不到它们,只有拥有特殊能力的人才能看得见。", + swd_jiangziya: + "周军统帅、周朝开国元勋,是一位尤其擅长法术攻击的权谋大家。曾修改了用于记载宇宙间万物生克关系的神器“太一之轮”,并留下了“周克商”的生克,造就牧野之战的胜利。", }, - perfectPair:{ - swd_fengtianling:['swd_huyue','swd_jiting'], - swd_rongshuang:['swd_zhuoshanzhu'], - swd_jialanduo:['swd_zhuoshanzhu'], - swd_sikongyu:['swd_muyue'], - swd_fengyu:['swd_ziqiao'], - swd_zhaoyun:['swd_hengai','swd_yeyaxi','zhaoyun'], - swd_hengai:['zhugeliang','sp_zhugeliang'], - swd_duanmeng:['swd_shangzhang'], - swd_shangzhang:['swd_situqiang'], - swd_tuwei:['swd_hengai'], - swd_jiangwu:['swd_zhaoyun'], - swd_muyun:['swd_lanyin','swd_zhiyin','swd_zhanggao','xushu'], - swd_lanyin:['swd_zhiyin'], - swd_yuli:['swd_chunyuheng'], - swd_jiuyou:['swd_zhiyin'], - swd_qiner:['swd_hengai'], - swd_huzhongxian:['swd_jiliang','swd_jipeng','swd_xiyan'], - swd_anka:['swd_kama'], - swd_septem:['swd_nicole','swd_kama','swd_weida','swd_wangsiyue','swd_huiyan'], - swd_nicole:['swd_lilian'], - swd_xuanyuanjianxian:['swd_xuanyuanjiantong'], - swd_chenjingchou:['swd_yuxiaoxue','swd_tuobayuer'], - swd_yuxiaoxue:['swd_yuwentuo'], - swd_zhanglie:['swd_tuobayuer'], - swd_duguningke:['swd_yuwentuo','swd_shanxiaoxiao','swd_yuchiyanhong'], - swd_jiliang:['swd_shuijing','swd_jipeng'], - swd_jipeng:['swd_duopeng'], - swd_cheyun:['swd_huanyuanzhi','swd_murongshi'], - swd_murongshi:['swd_huanyuanzhi','swd_shuijing'], - swd_huanyuanzhi:['swd_jipeng'], - swd_qi:['swd_huzhongxian'], - swd_luchengxuan:['swd_xiarou'], + perfectPair: { + swd_fengtianling: ["swd_huyue", "swd_jiting"], + swd_rongshuang: ["swd_zhuoshanzhu"], + swd_jialanduo: ["swd_zhuoshanzhu"], + swd_sikongyu: ["swd_muyue"], + swd_fengyu: ["swd_ziqiao"], + swd_zhaoyun: ["swd_hengai", "swd_yeyaxi", "zhaoyun"], + swd_hengai: ["zhugeliang", "sp_zhugeliang"], + swd_duanmeng: ["swd_shangzhang"], + swd_shangzhang: ["swd_situqiang"], + swd_tuwei: ["swd_hengai"], + swd_jiangwu: ["swd_zhaoyun"], + swd_muyun: ["swd_lanyin", "swd_zhiyin", "swd_zhanggao", "xushu"], + swd_lanyin: ["swd_zhiyin"], + swd_yuli: ["swd_chunyuheng"], + swd_jiuyou: ["swd_zhiyin"], + swd_qiner: ["swd_hengai"], + swd_huzhongxian: ["swd_jiliang", "swd_jipeng", "swd_xiyan"], + swd_anka: ["swd_kama"], + swd_septem: ["swd_nicole", "swd_kama", "swd_weida", "swd_wangsiyue", "swd_huiyan"], + swd_nicole: ["swd_lilian"], + swd_xuanyuanjianxian: ["swd_xuanyuanjiantong"], + swd_chenjingchou: ["swd_yuxiaoxue", "swd_tuobayuer"], + swd_yuxiaoxue: ["swd_yuwentuo"], + swd_zhanglie: ["swd_tuobayuer"], + swd_duguningke: ["swd_yuwentuo", "swd_shanxiaoxiao", "swd_yuchiyanhong"], + swd_jiliang: ["swd_shuijing", "swd_jipeng"], + swd_jipeng: ["swd_duopeng"], + swd_cheyun: ["swd_huanyuanzhi", "swd_murongshi"], + swd_murongshi: ["swd_huanyuanzhi", "swd_shuijing"], + swd_huanyuanzhi: ["swd_jipeng"], + swd_qi: ["swd_huzhongxian"], + swd_luchengxuan: ["swd_xiarou"], }, - skill:{ - cyqiaoxie:{ - trigger:{player:'loseEnd'}, - frequent:true, + skill: { + cyqiaoxie: { + trigger: { player: "loseEnd" }, + frequent: true, // alter:true, - filter:function(event,player){ - if(event.type=='use') return false; - for(var i=0;i1){ - prompt='###'+prompt+'###(剩余'+get.cnNumber(event.num)+'次)'; + if (list.length) { + var prompt = get.prompt("cyqiaoxie"); + if (event.num > 1) { + prompt = "###" + prompt + "###(剩余" + get.cnNumber(event.num) + "次)"; } - player.chooseVCardButton(list.randomGets(3),prompt); - } - else{ + player.chooseVCardButton(list.randomGets(3), prompt); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.chooseUseTarget(true,game.createCard(result.links[0][2])); + "step 2"; + if (result.bool) { + player.chooseUseTarget(true, game.createCard(result.links[0][2])); } event.num--; - if(event.num>0){ + if (event.num > 0) { event.goto(1); } }, - ai:{ - noe:true, - reverseEquip:true, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip') return [1,3]; - } - } - } - }, - cyxianjiang:{ - trigger:{player:'useCardToBegin'}, - init:function(player){ - player.storage.cyxianjiang=[]; + ai: { + noe: true, + reverseEquip: true, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") return [1, 3]; + }, + }, }, - filter:function(event,player){ - if(event.target!=player&&event.targets&&event.targets.length==1){ - if(player.storage.cyxianjiang.includes(event.target)) return false; - return event.target.countCards('e',function(card){ - return !player.countCards('he',card.name); + }, + cyxianjiang: { + trigger: { player: "useCardToBegin" }, + init: function (player) { + player.storage.cyxianjiang = []; + }, + filter: function (event, player) { + if (event.target != player && event.targets && event.targets.length == 1) { + if (player.storage.cyxianjiang.includes(event.target)) return false; + return event.target.countCards("e", function (card) { + return !player.countCards("he", card.name); }); } return false; }, - direct:true, - content:function(){ - 'step 0' - player.choosePlayerCard(trigger.target,'e',get.prompt('cyxianjiang')).set('ai',get.buttonValue).set('filterButton',function(button){ - return !player.countCards('he',button.link.name); - }); - 'step 1' - if(result.bool){ - player.logSkill('cyxianjiang'); - var card=result.links[0]; - player.equip(game.createCard(card),true); + direct: true, + content: function () { + "step 0"; + player + .choosePlayerCard(trigger.target, "e", get.prompt("cyxianjiang")) + .set("ai", get.buttonValue) + .set("filterButton", function (button) { + return !player.countCards("he", button.link.name); + }); + "step 1"; + if (result.bool) { + player.logSkill("cyxianjiang"); + var card = result.links[0]; + player.equip(game.createCard(card), true); player.storage.cyxianjiang.add(trigger.target); } }, - group:'cyxianjiang_clear', - subSkill:{ - clear:{ - trigger:{global:'phaseAfter'}, - silent:true, - content:function(){ - player.storage.cyxianjiang.length=0; - } - } - } + group: "cyxianjiang_clear", + subSkill: { + clear: { + trigger: { global: "phaseAfter" }, + silent: true, + content: function () { + player.storage.cyxianjiang.length = 0; + }, + }, + }, }, - cyzhencha:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); - })){ + cyzhencha: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if ( + !game.hasPlayer(function (current) { + return current != player && current.countCards("h"); + }) + ) { return false; } - if(!player.countCards('h',{type:'basic'})) return false; - var es=player.getCards('e'); - for(var i=0;i0; - }).set('autodelay',0.5).ai=function(target){ - return -get.attitude(player,target); + cyzhencha_shuiyun: { + trigger: { player: "phaseBegin" }, + direct: true, + thundertext: true, + content: function () { + "step 0"; + player + .chooseTarget( + [1, 1], + "水云:你可以弃置一名角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + } + ) + .set("autodelay", 0.5).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('cyzhencha_shuiyun',result.targets); - player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + "step 1"; + if (result.bool) { + player.logSkill("cyzhencha_shuiyun", result.targets); + player.discardPlayerCard(result.targets[0], "he", true); + } else { event.finish(); } }, - onremove:function(player){ - _status.event.insert(lib.skill.cyzhencha_shuiyun.content,{player:player}); - } + onremove: function (player) { + _status.event.insert(lib.skill.cyzhencha_shuiyun.content, { player: player }); + }, }, - cyzhencha_liuzi:{ - trigger:{player:'phaseDrawBegin'}, - frequent:true, - thundertext:true, - content:function(){ + cyzhencha_liuzi: { + trigger: { player: "phaseDrawBegin" }, + frequent: true, + thundertext: true, + content: function () { trigger.num++; }, - onremove:function(player){ + onremove: function (player) { player.draw(); - } + }, }, - cyzhencha_yijin:{ - trigger:{player:'phaseBegin'}, - direct:true, - thundertext:true, - content:function(){ - "step 0" - player.chooseTarget([1,1],'水云:你可以弃置一名角色的一张牌',function(card,player,target){ - if(player==target) return false; - return target.countCards('he')>0; - }).set('autodelay',0.5).ai=function(target){ - return -get.attitude(player,target); + cyzhencha_yijin: { + trigger: { player: "phaseBegin" }, + direct: true, + thundertext: true, + content: function () { + "step 0"; + player + .chooseTarget( + [1, 1], + "水云:你可以弃置一名角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + } + ) + .set("autodelay", 0.5).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('cyzhencha_shuiyun',result.targets); - player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + "step 1"; + if (result.bool) { + player.logSkill("cyzhencha_shuiyun", result.targets); + player.discardPlayerCard(result.targets[0], "he", true); + } else { event.finish(); } }, - onremove:function(player){ - _status.event.insert(lib.skill.cyzhencha_shuiyun.content,{player:player}); - } - }, - cyzhencha_qingling:{ - inhert:'cyzhencha_shuiyun' - }, - cyzhencha_qiandian:{ - inhert:'cyzhencha_shuiyun' - }, - cyqiaoxie_old:{ - enable:'phaseUse', - filterCard:function(card){ - return get.type(card,'trick')=='trick'; + onremove: function (player) { + _status.event.insert(lib.skill.cyzhencha_shuiyun.content, { player: player }); }, - usable:1, - filter:function(event,player){ - var current=[]; - var es=player.getCards('e'); - for(var i=0;i7){ - map[i]=0;break; - } - else if(val<=5){ + for (var i in map) { + var hs = player.getCards("h", { suit: i }); + for (var j = 0; j < hs.length; j++) { + var val = get.value(hs[j], player, "raw"); + if (val > 7) { + map[i] = 0; + break; + } else if (val <= 5) { map[i]++; - if(val<=4){ - map[i]+=0.5; + if (val <= 4) { + map[i] += 0.5; } - if(val<0){ - map[i]+=2; + if (val < 0) { + map[i] += 2; } } } - if(map[i]>max){ - choice=i; - max=map[i]; + if (map[i] > max) { + choice = i; + max = map[i]; } } - var controls=['heart2','spade2','diamond2','club2']; - for(var i=0;i=3){ - return controls[2]; - } - else{ - return controls[0]; - } - }).set('prompt','选择一个花色从牌堆中获得'+hs.length+'张该花色的牌'); - event.num=hs.length; - 'step 2' - if(result.control){ - var suit=result.control.slice(0,result.control.length-1); - var cards=[]; - for(var i=0;i= 3) { + return controls[2]; + } else { + return controls[0]; + } + }) + .set("prompt", "选择一个花色从牌堆中获得" + hs.length + "张该花色的牌"); + event.num = hs.length; + "step 2"; + if (result.control) { + var suit = result.control.slice(0, result.control.length - 1); + var cards = []; + for (var i = 0; i < event.num; i++) { + var card = get.cardPile(function (card) { + return get.suit(card) == suit; }); - if(card){ + if (card) { ui.special.appendChild(card); cards.push(card); - } - else{ + } else { break; } } - if(cards.length){ + if (cards.length) { player.directgain(cards); player.$draw(cards.length); game.delay(); - game.log(player,'获得了'+get.cnNumber(cards.length)+'张','#y'+get.translation(suit+'2')+'牌'); + game.log( + player, + "获得了" + get.cnNumber(cards.length) + "张", + "#y" + get.translation(suit + "2") + "牌" + ); } } }, - ai:{ - order:7, - result:{ - player:function(player){ - var list=['club','heart','diamond','spade']; - for(var i=0;i7){ - bool=false;break; - } - else if(val<=4){ - bool=true; + ai: { + order: 7, + result: { + player: function (player) { + var list = ["club", "heart", "diamond", "spade"]; + for (var i = 0; i < list.length; i++) { + var hs = player.getCards("h", { suit: list[i] }); + var bool = false; + for (var j = 0; j < hs.length; j++) { + var val = get.value(hs[j], player); + if (val > 7) { + bool = false; + break; + } else if (val <= 4) { + bool = true; } } - if(bool){ + if (bool) { return 1; } } return 0; - } - } - } + }, + }, + }, }, - yeying:{ - enable:'phaseUse', - usable:1, - viewAs:{name:'qiankunbiao'}, - viewAsFilter:function(player){ - return player.countCards('he',{color:'black'}); + yeying: { + enable: "phaseUse", + usable: 1, + viewAs: { name: "qiankunbiao" }, + viewAsFilter: function (player) { + return player.countCards("he", { color: "black" }); }, - filterCard:{color:'black'}, - position:'he', - check:function(card){ - return 7-get.value(card); + filterCard: { color: "black" }, + position: "he", + check: function (card) { + return 7 - get.value(card); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - juxi:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.storage.juxi>=game.countPlayer(); + juxi: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.storage.juxi >= game.countPlayer(); }, - filterTarget:true, - init:function(player){ - player.storage.juxi=0; + filterTarget: true, + init: function (player) { + player.storage.juxi = 0; }, - init2:function(player){ - if(get.mode()=='guozhan'){ - player.logSkill('juxi'); + init2: function (player) { + if (get.mode() == "guozhan") { + player.logSkill("juxi"); } }, - intro:{ - content:'mark' + intro: { + content: "mark", }, - content:function(){ - 'step 0' - player.storage.juxi-=game.countPlayer(); - player.syncStorage('juxi'); - if(player.storage.juxi<=0){ - player.unmarkSkill('juxi'); - } - else{ + content: function () { + "step 0"; + player.storage.juxi -= game.countPlayer(); + player.syncStorage("juxi"); + if (player.storage.juxi <= 0) { + player.unmarkSkill("juxi"); + } else { player.updateMarks(); } - if(target.isDamaged()){ - player.chooseControl(function(){ - if(get.attitude(player,target)>0) return 1; - return 0; - }).set('choiceList',[ - '对'+get.translation(target)+'造成1点伤害', - '令'+get.translation(target)+'回复1点体力', - ]) - } - else{ + if (target.isDamaged()) { + player + .chooseControl(function () { + if (get.attitude(player, target) > 0) return 1; + return 0; + }) + .set("choiceList", [ + "对" + get.translation(target) + "造成1点伤害", + "令" + get.translation(target) + "回复1点体力", + ]); + } else { target.damage(); event.finish(); } - 'step 1' - if(result.control=='选项一'){ + "step 1"; + if (result.control == "选项一") { target.damage(); - } - else{ + } else { target.recover(); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0){ - if(target.isDamaged()) return get.recoverEffect(target,player,target); + ai: { + order: 7, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) { + if (target.isDamaged()) return get.recoverEffect(target, player, target); return 0; + } else { + return get.damageEffect(target, player, target); } - else{ - return get.damageEffect(target,player,target); - } - } - } - }, - group:'juxi_count', - subSkill:{ - count:{ - trigger:{global:'discardAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return _status.currentPhase!=event.player; }, - content:function(){ + }, + }, + group: "juxi_count", + subSkill: { + count: { + trigger: { global: "discardAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return _status.currentPhase != event.player; + }, + content: function () { player.storage.juxi++; - player.syncStorage('juxi'); - player.markSkill('juxi'); + player.syncStorage("juxi"); + player.markSkill("juxi"); player.updateMarks(); }, - } - } - }, - jiefen:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('h')>player.countCards('h'); + }, }, - filter:function(event,player){ + }, + jiefen: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("h") > player.countCards("h"); + }, + filter: function (event, player) { return !player.isMaxHandcard(); }, - content:function(){ - 'step 0' - target.chooseCard('h',true,'交给'+get.translation(player)+'一张牌'); - 'step 1' - if(result.bool){ - player.gain(result.cards,target); - target.$giveAuto(result.cards,player); - } - else{ + content: function () { + "step 0"; + target.chooseCard("h", true, "交给" + get.translation(player) + "一张牌"); + "step 1"; + if (result.bool) { + player.gain(result.cards, target); + target.$giveAuto(result.cards, player); + } else { event.finish(); } - 'step 2' - var nh=player.countCards('h'); - if(game.hasPlayer(function(current){ - return current.countCards('h')max){ - max=nh; + datong: { + trigger: { global: "phaseEnd" }, + frequent: true, + filter: function (event, player) { + var max = player.countCards("h"); + var min = max; + game.countPlayer(function (current) { + var nh = current.countCards("h"); + if (nh > max) { + max = nh; } - if(nh0; + huodan: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "red" }, + filter: function (event, player) { + return player.countCards("he", { color: "red" }) > 0; }, - filterTarget:true, - selectTarget:[1,2], - position:'he', - check:function(card){ - return 7-get.value(card); + filterTarget: true, + selectTarget: [1, 2], + position: "he", + check: function (card) { + return 7 - get.value(card); }, - contentBefore:function(){ + contentBefore: function () { player.loseHp(); }, // alter:true, - content:function(){ - if(targets.length==1){ - target.damage('fire',2); - if(get.is.altered('huodan')) target.draw(); - } - else{ - target.damage('fire'); + content: function () { + if (targets.length == 1) { + target.damage("fire", 2); + if (get.is.altered("huodan")) target.draw(); + } else { + target.damage("fire"); } }, - line:'fire', - ai:{ - order:15, - expose:0.2, - threaten:1.5, - result:{ - target:function(player,target){ - if(player.hp<2) return 0; - if(get.attitude(player,target)>=0) return 0; - if(target.hp>player.hp) return 0; - var eff=get.damageEffect(target,player,target,'fire'); - if(eff<0){ - if(ui.selected.targets.length&&target.hp>1&&ui.selected.targets[0].hp>1){ + line: "fire", + ai: { + order: 15, + expose: 0.2, + threaten: 1.5, + result: { + target: function (player, target) { + if (player.hp < 2) return 0; + if (get.attitude(player, target) >= 0) return 0; + if (target.hp > player.hp) return 0; + var eff = get.damageEffect(target, player, target, "fire"); + if (eff < 0) { + if ( + ui.selected.targets.length && + target.hp > 1 && + ui.selected.targets[0].hp > 1 + ) { return 0; } - if(target.nodying) return eff/10; - return eff/Math.sqrt(target.hp); + if (target.nodying) return eff / 10; + return eff / Math.sqrt(target.hp); } return 0; - } - } - } + }, + }, + }, }, - sxianjing:{ - enable:'phaseUse', - filter:function(event,player){ - var suits=[]; - for(var i=0;i0; + "step 1"; + player.randomGain(trigger.player, true); }, - content:function(){ - var card=player.storage.sxianjing.randomGet(); + }, + damage: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player.storage.sxianjing.length > 0; + }, + content: function () { + var card = player.storage.sxianjing.randomGet(); player.storage.sxianjing.remove(card); - player.gain(card,'draw'); - player.syncStorage('sxianjing'); - if(player.storage.sxianjing.length){ + player.gain(card, "draw"); + player.syncStorage("sxianjing"); + if (player.storage.sxianjing.length) { player.updateMarks(); + } else { + player.unmarkSkill("sxianjing"); } - else{ - player.unmarkSkill('sxianjing'); - } - } - } - } - }, - zhanxing:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - selectCard:[1,Infinity], - filter:function(event,player){ - return player.countCards('he')>0; + }, + }, }, - check:function(card){ - switch(ui.selected.cards.length){ - case 0: return 8-get.value(card); - case 1: return 6-get.value(card); - case 2: return 3-get.value(card); + }, + zhanxing: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + selectCard: [1, Infinity], + filter: function (event, player) { + return player.countCards("he") > 0; + }, + check: function (card) { + switch (ui.selected.cards.length) { + case 0: + return 8 - get.value(card); + case 1: + return 6 - get.value(card); + case 2: + return 3 - get.value(card); } return 0; }, - content:function(){ - 'step 0' - var list=get.cards(cards.length); - event.list=list; + content: function () { + "step 0"; + var list = get.cards(cards.length); + event.list = list; player.showCards(list); - 'step 1' - var suits=[]; - event.suits=suits; - for(var i=0;i2&& - get.damageEffect(trigger.target,trigger.player,player)<0); - next.ai=function(card){ - if(goon){ - if(trigger.target.hp==1) return 10-get.value(card); - return 7-get.value(card); + }, + tiebi: { + trigger: { global: "shaBegin" }, + filter: function (event, player) { + return ( + player.countCards("h", { color: "black" }) && + !event.target.hujia && + get.distance(player, event.target) <= 1 + ); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt("tiebi", trigger.target), { + color: "black", + }); + var goon = + get.attitude(player, trigger.target) > 2 && + get.damageEffect(trigger.target, trigger.player, player) < 0; + next.ai = function (card) { + if (goon) { + if (trigger.target.hp == 1) return 10 - get.value(card); + return 7 - get.value(card); } return 0; }; - next.logSkill=['tiebi',trigger.target]; - "step 1" - if(result.bool){ + next.logSkill = ["tiebi", trigger.target]; + "step 1"; + if (result.bool) { trigger.target.changeHujia(); } }, - ai:{ - threaten:1.1 - } + ai: { + threaten: 1.1, + }, }, - shenyan:{ - trigger:{source:'damageBegin'}, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - return !player.storage.shenyan&&event.hasNature('fire'); + shenyan: { + trigger: { source: "damageBegin" }, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + return !player.storage.shenyan && event.hasNature("fire"); }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - mark:true, - logTarget:'player', - init:function(player){ - player.storage.shenyan=false; + mark: true, + logTarget: "player", + init: function (player) { + player.storage.shenyan = false; }, - check:function(event,player){ - if(get.attitude(player,event.player)>=0) return 0; - if(player.hasUnknown()) return 0; - var num=0,players=game.filterPlayer(); - for(var i=0;i0){ + check: function (event, player) { + if (get.attitude(player, event.player) >= 0) return 0; + if (player.hasUnknown()) return 0; + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + players[i] != event.player && + get.distance(event.player, players[i]) <= 1 + ) { + var eff = get.damageEffect(players[i], player, player, "fire"); + if (eff > 0) { num++; - } - else if(eff<0){ + } else if (eff < 0) { num--; } } } - return num>0; + return num > 0; }, - content:function(){ + content: function () { trigger.num++; - player.addSkill('shenyan2'); - player.storage.shenyan=true; - player.awakenSkill('shenyan'); - player.storage.shenyan2=[]; - var players=game.filterPlayer(); - for(var i=0;i0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - target.chooseToDiscard(2,'h',true).delay=false; - 'step 1' + content: function () { + "step 0"; + target.chooseToDiscard(2, "h", true).delay = false; + "step 1"; target.draw(); }, - selectTarget:-1, - ai:{ - order:9, - result:{ - target:-1 - } - } + selectTarget: -1, + ai: { + order: 9, + result: { + target: -1, + }, + }, }, - xuanying:{ - subSkill:{ - sha:{ - enable:'chooseToUse', - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(player.isLinked()) return false; + xuanying: { + subSkill: { + sha: { + enable: "chooseToUse", + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (player.isLinked()) return false; }, - precontent:function(){ + precontent: function () { player.link(); // player.getStat().card.sha--; }, - filterCard:function(){return false}, - selectCard:-1, - prompt:'横置武将牌,视为使用一张无视距离的杀', - ai:{ - order:function(){ + filterCard: function () { + return false; + }, + selectCard: -1, + prompt: "横置武将牌,视为使用一张无视距离的杀", + ai: { + order: function () { // if(_status.event.player.countCards('h',{type:'equip'})) return 9; return 3.15; }, - skillTagFilter:function(player,tag,arg){ - if(arg!='use') return false; - if(player.isLinked()) return false; + skillTagFilter: function (player, tag, arg) { + if (arg != "use") return false; + if (player.isLinked()) return false; }, - respondSha:true, + respondSha: true, }, - mod:{ - targetInRange:function(card){ - if(_status.event.skill=='xuanying_sha') return true; - } + mod: { + targetInRange: function (card) { + if (_status.event.skill == "xuanying_sha") return true; + }, }, }, - shan:{ - trigger:{player:['chooseToRespondBegin','chooseToUseBegin']}, - filter:function(event,player){ - if(!player.isLinked()) return false; - if(event.responded) return false; - if(!event.filterCard({name:'shan'},player,event)) return false; + shan: { + trigger: { player: ["chooseToRespondBegin", "chooseToUseBegin"] }, + filter: function (event, player) { + if (!player.isLinked()) return false; + if (event.responded) return false; + if (!event.filterCard({ name: "shan" }, player, event)) return false; return true; }, - check:function(event,player){ - if(get.damageEffect(player,event.player,player)>=0) return false; + check: function (event, player) { + if (get.damageEffect(player, event.player, player) >= 0) return false; return true; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.link(); - 'step 1' + "step 1"; trigger.untrigger(); - trigger.responded=true; - trigger.result={bool:true,card:{name:'shan'}} + trigger.responded = true; + trigger.result = { bool: true, card: { name: "shan" } }; }, - ai:{ - respondShan:true, - target:function(card,player,target,current){ - if(!player.isLinked()&¤t<0) return 1.5; - if(!target.hasFriend()) return; - if(get.tag(card,'loseCard')&&_status.currentPhase!=target&&target.countCards('he')){ - return [0.5,Math.max(2,target.countCards('h'))]; + ai: { + respondShan: true, + target: function (card, player, target, current) { + if (!player.isLinked() && current < 0) return 1.5; + if (!target.hasFriend()) return; + if ( + get.tag(card, "loseCard") && + _status.currentPhase != target && + target.countCards("he") + ) { + return [0.5, Math.max(2, target.countCards("h"))]; } - if(get.tag(card,'respondSha')||get.tag(card,'respondShan')){ - if(get.attitude(player,target)>0&&card.name=='juedou') return; - return [0.5,target.countCards('h','sha')+target.countCards('h','shan')]; + if (get.tag(card, "respondSha") || get.tag(card, "respondShan")) { + if (get.attitude(player, target) > 0 && card.name == "juedou") return; + return [ + 0.5, + target.countCards("h", "sha") + target.countCards("h", "shan"), + ]; } - } - } + }, + }, }, - damage:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isAlive()&&player.isLinked()&& - lib.filter.targetEnabled({name:'sha'},player,event.source); + damage: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.source && + event.source.isAlive() && + player.isLinked() && + lib.filter.targetEnabled({ name: "sha" }, player, event.source) + ); }, - check:function(event,player){ - return get.effect(event.source,{name:'sha'},player,player)>0; + check: function (event, player) { + return get.effect(event.source, { name: "sha" }, player, player) > 0; }, - logTarget:'source', - content:function(){ - 'step 0' + logTarget: "source", + content: function () { + "step 0"; player.link(); - 'step 1' - player.useCard({name:'sha'},trigger.source); - } - }, - use:{ - trigger:{player:'loseEnd'}, - direct:true, - filter:function(event,player){ - return _status.currentPhase!=player&&player.isLinked()&&event.cards&&event.cards.length; + "step 1"; + player.useCard({ name: "sha" }, trigger.source); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('xuanying'),function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); - }).set('ai',function(target){ - return get.effect(target,{name:'sha'},_status.event.player); - }).set('autodelay',0.5); - 'step 1' - if(result.bool){ - player.logSkill('xuanying'); + }, + use: { + trigger: { player: "loseEnd" }, + direct: true, + filter: function (event, player) { + return ( + _status.currentPhase != player && + player.isLinked() && + event.cards && + event.cards.length + ); + }, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("xuanying"), function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); + }) + .set("ai", function (target) { + return get.effect(target, { name: "sha" }, _status.event.player); + }) + .set("autodelay", 0.5); + "step 1"; + if (result.bool) { + player.logSkill("xuanying"); player.link(); - player.useCard({name:'sha'},result.targets,false); + player.useCard({ name: "sha" }, result.targets, false); } }, - } + }, }, - group:['xuanying_sha','xuanying_use'], - ai:{ - threaten:function(player,target){ - if(target.isLinked()) return 0.7; + group: ["xuanying_sha", "xuanying_use"], + ai: { + threaten: function (player, target) { + if (target.isLinked()) return 0.7; return 1.4; - } - } - }, - hwendao:{ - trigger:{player:['useCardAfter','respondAfter',]}, - check:function(event,player){ - return get.attitude(player,_status.currentPhase)<=0; + }, }, - logTarget:function(){ + }, + hwendao: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + check: function (event, player) { + return get.attitude(player, _status.currentPhase) <= 0; + }, + logTarget: function () { return _status.currentPhase; }, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(!_status.currentPhase.countCards('he')) return false; - return event.cards&&event.cards.length==1; + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (!_status.currentPhase.countCards("he")) return false; + return event.cards && event.cards.length == 1; }, - content:function(){ - 'step 0' - var suit=get.suit(trigger.cards[0]); - var goon=(get.attitude(_status.currentPhase,player)<=0); - _status.currentPhase.chooseToDiscard('弃置一张'+get.translation(suit+'2')+ - '牌,或令'+get.translation(player)+'获得你的一张牌',{suit:suit}).ai=function(card){ - if(goon) return 8-get.value(card); + content: function () { + "step 0"; + var suit = get.suit(trigger.cards[0]); + var goon = get.attitude(_status.currentPhase, player) <= 0; + _status.currentPhase.chooseToDiscard( + "弃置一张" + + get.translation(suit + "2") + + "牌,或令" + + get.translation(player) + + "获得你的一张牌", + { suit: suit } + ).ai = function (card) { + if (goon) return 8 - get.value(card); return 0; - } - 'step 1' - if(!result.bool){ - player.gainPlayerCard(_status.currentPhase,'he',true); + }; + "step 1"; + if (!result.bool) { + player.gainPlayerCard(_status.currentPhase, "he", true); } }, - ai:{ - threaten:0.7 - } + ai: { + threaten: 0.7, + }, }, - lingfeng:{ - trigger:{player:'phaseEnd'}, - frequent:true, - filter:function(event,player){ - return player.countUsed()>=Math.min(3,player.hp); + lingfeng: { + trigger: { player: "phaseEnd" }, + frequent: true, + filter: function (event, player) { + return player.countUsed() >= Math.min(3, player.hp); }, - content:function(){ - 'step 0' - player.chooseTarget('凌锋',function(card,player,target){ - return player!=target&&get.distance(player,target,'attack')<=1; - }).set('prompt2','造成1点伤害,或取消并获得1点护甲').ai=function(target){ - if(player.hp==1) return 0; - if(player.hp==2&&target.hp>=3) return 0; - return get.damageEffect(target,player,player); - } - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseTarget("凌锋", function (card, player, target) { + return player != target && get.distance(player, target, "attack") <= 1; + }) + .set("prompt2", "造成1点伤害,或取消并获得1点护甲").ai = function (target) { + if (player.hp == 1) return 0; + if (player.hp == 2 && target.hp >= 3) return 0; + return get.damageEffect(target, player, player); + }; + "step 1"; + if (result.bool) { player.line(result.targets[0]); result.targets[0].damage(); - } - else{ + } else { player.changeHujia(); } }, - ai:{ - order:-10, - result:{ - target:2 + ai: { + order: -10, + result: { + target: 2, }, - threaten:1.5 - } + threaten: 1.5, + }, }, - hxunzhi:{ - unique:true, - enable:'phaseUse', - derivation:['wusheng','paoxiao'], - filter:function(event,player){ + hxunzhi: { + unique: true, + enable: "phaseUse", + derivation: ["wusheng", "paoxiao"], + filter: function (event, player) { return !player.storage.hxunzhi; }, // alter:true, - init:function(player){ - player.storage.hxunzhi=false; + init: function (player) { + player.storage.hxunzhi = false; }, - mark:true, - intro:{ - content:'limited' + mark: true, + intro: { + content: "limited", }, - skillAnimation:true, - animationColor:'fire', - content:function(){ - 'step 0' - player.awakenSkill('hxunzhi'); - player.storage.hxunzhi=true; - if(!get.is.altered('hxunzhi')){ - var targets=game.filterPlayer(function(current){ - return player.canUse('wanjian',current); + skillAnimation: true, + animationColor: "fire", + content: function () { + "step 0"; + player.awakenSkill("hxunzhi"); + player.storage.hxunzhi = true; + if (!get.is.altered("hxunzhi")) { + var targets = game.filterPlayer(function (current) { + return player.canUse("wanjian", current); }); targets.sort(lib.sort.seat); - player.useCard({name:'wanjian'},targets); + player.useCard({ name: "wanjian" }, targets); } - 'step 1' - player.addSkill('wusheng'); - player.addSkill('paoxiao'); - player.addSkill('hxunzhi2'); + "step 1"; + player.addSkill("wusheng"); + player.addSkill("paoxiao"); + player.addSkill("hxunzhi2"); }, - ai:{ - order:2, - result:{ - player:function(player){ - if(get.mode()=='identity'){ - if(player.identity=='zhu') return 0; - if(player.identity=='nei') return 0; + ai: { + order: 2, + result: { + player: function (player) { + if (get.mode() == "identity") { + if (player.identity == "zhu") return 0; + if (player.identity == "nei") return 0; + } else if (get.mode() == "guozhan") { + if (player.identity == "ye") return 0; + if (player.isUnseen()) return 0; } - else if(get.mode()=='guozhan'){ - if(player.identity=='ye') return 0; - if(player.isUnseen()) return 0; - } - if(player.hp==1) return 1; - if(player.hasUnknown()) return 0; - if(!player.hasFriend()) return 0; - var enemies=player.getEnemies(); - if(enemies.length+1==game.players.length) return 0; - var num=player.hasCard(function(card){ - return card.name=='sha'||get.color(card)=='red'; + if (player.hp == 1) return 1; + if (player.hasUnknown()) return 0; + if (!player.hasFriend()) return 0; + var enemies = player.getEnemies(); + if (enemies.length + 1 == game.players.length) return 0; + var num = player.hasCard(function (card) { + return card.name == "sha" || get.color(card) == "red"; }); - if(num<2) return 0; - for(var i=0;i0&& - !enemies[i].getEquip(2)&&num>enemies[i].hp&&enemies[i].hp<=2){ + if (num < 2) return 0; + for (var i = 0; i < enemies.length; i++) { + if ( + player.canUse("sha", enemies[i]) && + get.effect(enemies[i], { name: "sha" }, player, player) > 0 && + !enemies[i].getEquip(2) && + num > enemies[i].hp && + enemies[i].hp <= 2 + ) { return 1; } } return 0; - } - } - } + }, + }, + }, }, - hxunzhi2:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('xunzhi2'); + hxunzhi2: { + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("xunzhi2"); player.die(); - } + }, }, - hjifeng:{ - enable:'phaseUse', - filter:function(event,player){ - if(!player.countCards('h')) return false; - if(player.countCards('h',{type:'jiqi'})) return false; + hjifeng: { + enable: "phaseUse", + filter: function (event, player) { + if (!player.countCards("h")) return false; + if (player.countCards("h", { type: "jiqi" })) return false; return true; }, - discard:false, - prepare:'throw2', - usable:1, - check:function(card){ - return 6-get.value(card); + discard: false, + prepare: "throw2", + usable: 1, + check: function (card) { + return 6 - get.value(card); }, - filterCard:true, - content:function(){ - var name=get.suit(cards[0]); - ui.cardPile.insertBefore(cards[0],ui.cardPile.firstChild); - switch(name){ - case 'spade':name='qinglongzhigui';break; - case 'club':name='baishouzhihu';break; - case 'diamond':name='zhuquezhizhang';break; - case 'heart':name='xuanwuzhihuang';break; + filterCard: true, + content: function () { + var name = get.suit(cards[0]); + ui.cardPile.insertBefore(cards[0], ui.cardPile.firstChild); + switch (name) { + case "spade": + name = "qinglongzhigui"; + break; + case "club": + name = "baishouzhihu"; + break; + case "diamond": + name = "zhuquezhizhang"; + break; + case "heart": + name = "xuanwuzhihuang"; + break; } - player.gain(get.cardPile(name)||game.createCard(name),'draw'); + player.gain(get.cardPile(name) || game.createCard(name), "draw"); + }, + ai: { + order: 4, + result: { + player: 1, + }, }, - ai:{ - order:4, - result:{ - player:1 - } - } }, - hjifeng_old:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - if(!player.countCards('he',{type:'equip'})) return false; - if(player.countCards('h',{type:'jiqi'})) return false; - if(get.cardPile(function(card){return get.type(card)=='jiqi'})) return true; + hjifeng_old: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + if (!player.countCards("he", { type: "equip" })) return false; + if (player.countCards("h", { type: "jiqi" })) return false; + if ( + get.cardPile(function (card) { + return get.type(card) == "jiqi"; + }) + ) + return true; return false; }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard('he','祭风:是否弃置一张装备牌并获得一张祭器牌?',{type:'equip'}).set('ai',function(card){ - return 6-get.value(card); - }).logSkill='hjifeng'; - 'step 1' - if(result.bool){ - var card=get.cardPile(function(card){ - return get.type(card)=='jiqi'&&card.name.indexOf('yuchan')!=0; - })||get.cardPile(function(card){ - return get.type(card)=='jiqi'; - }); - if(card){ - player.gain(card,'draw'); + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard("he", "祭风:是否弃置一张装备牌并获得一张祭器牌?", { + type: "equip", + }) + .set("ai", function (card) { + return 6 - get.value(card); + }).logSkill = "hjifeng"; + "step 1"; + if (result.bool) { + var card = + get.cardPile(function (card) { + return get.type(card) == "jiqi" && card.name.indexOf("yuchan") != 0; + }) || + get.cardPile(function (card) { + return get.type(card) == "jiqi"; + }); + if (card) { + player.gain(card, "draw"); } } - } + }, }, - lmazui:{ - audio:'mazui', - enable:'phaseUse', - usable:1, - filterCard:{color:'black'}, - filterTarget:function(card,player,target){ - return !target.hasSkill('lmazui2'); + lmazui: { + audio: "mazui", + enable: "phaseUse", + usable: 1, + filterCard: { color: "black" }, + filterTarget: function (card, player, target) { + return !target.hasSkill("lmazui2"); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - discard:false, - prepare:'give', - content:function(){ - target.storage.lmazui2=cards[0]; - target.addSkill('lmazui2'); - game.addVideo('storage',target,['lmazui2',get.cardInfo(target.storage.lmazui2),'card']); + discard: false, + prepare: "give", + content: function () { + target.storage.lmazui2 = cards[0]; + target.addSkill("lmazui2"); + game.addVideo("storage", target, [ + "lmazui2", + get.cardInfo(target.storage.lmazui2), + "card", + ]); }, - ai:{ - expose:0.2, - result:{ - target:function(player,target){ + ai: { + expose: 0.2, + result: { + target: function (player, target) { return -target.hp; - } + }, }, - order:4, - threaten:1.2 - } - }, - lmazui2:{ - trigger:{source:'damageBegin'}, - forced:true, - mark:'card', - filter:function(event){ - return event.num>0; + order: 4, + threaten: 1.2, }, - content:function(){ + }, + lmazui2: { + trigger: { source: "damageBegin" }, + forced: true, + mark: "card", + filter: function (event) { + return event.num > 0; + }, + content: function () { trigger.num--; - player.addSkill('lmazui3'); - player.removeSkill('lmazui2'); + player.addSkill("lmazui3"); + player.removeSkill("lmazui2"); + }, + intro: { + content: "card", }, - intro:{ - content:'card' - } }, - lmazui3:{ - trigger:{source:['damageEnd','damageZero']}, - forced:true, - popup:false, - content:function(){ - player.gain(player.storage.lmazui2,'gain2','log'); - player.removeSkill('lmazui3'); + lmazui3: { + trigger: { source: ["damageEnd", "damageZero"] }, + forced: true, + popup: false, + content: function () { + player.gain(player.storage.lmazui2, "gain2", "log"); + player.removeSkill("lmazui3"); delete player.storage.lmazui2; - } + }, }, - hyunshen:{ - trigger:{player:['respond','useCard']}, - filter:function(event,player){ - return event.card.name=='shan'; + hyunshen: { + trigger: { player: ["respond", "useCard"] }, + filter: function (event, player) { + return event.card.name == "shan"; }, - frequent:true, - init:function(player){ - player.storage.hyunshen=0; + frequent: true, + init: function (player) { + player.storage.hyunshen = 0; }, - content:function(){ + content: function () { player.storage.hyunshen++; - player.markSkill('hyunshen'); + player.markSkill("hyunshen"); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'respondShan')){ - var shans=target.countCards('h','shan'); - var hs=target.countCards('h'); - if(shans>1) return [1,1]; - if(shans&&hs>2) return [1,1]; - if(shans) return [1,0.5]; - if(hs>2) return [1,0.3]; - if(hs>1) return [1,0.2]; - return [1.2,0]; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "respondShan")) { + var shans = target.countCards("h", "shan"); + var hs = target.countCards("h"); + if (shans > 1) return [1, 1]; + if (shans && hs > 2) return [1, 1]; + if (shans) return [1, 0.5]; + if (hs > 2) return [1, 0.3]; + if (hs > 1) return [1, 0.2]; + return [1.2, 0]; } - } + }, }, - threaten:0.8 + threaten: 0.8, }, - intro:{ - content:'mark' + intro: { + content: "mark", }, - group:'hyunshen2' + group: "hyunshen2", }, - hyunshen2:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event,player){ - return player.storage.hyunshen>0; + hyunshen2: { + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + return player.storage.hyunshen > 0; }, - content:function(){ + content: function () { player.draw(player.storage.hyunshen); - player.storage.hyunshen=0; - player.unmarkSkill('hyunshen'); + player.storage.hyunshen = 0; + player.unmarkSkill("hyunshen"); + }, + mod: { + globalTo: function (from, to, distance) { + if (typeof to.storage.hyunshen == "number") return distance + to.storage.hyunshen; + }, }, - mod:{ - globalTo:function(from,to,distance){ - if(typeof to.storage.hyunshen=='number') return distance+to.storage.hyunshen; - } - } }, - hlingbo:{ - audio:['lingbo',2], - trigger:{player:['respond','useCard']}, - filter:function(event,player){ - return event.card.name=='shan'; + hlingbo: { + audio: ["lingbo", 2], + trigger: { player: ["respond", "useCard"] }, + filter: function (event, player) { + return event.card.name == "shan"; }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(2); }, - ai:{ - mingzhi:false, - useShan:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'respondShan')){ - var shans=target.countCards('h','shan'); - var hs=target.countCards('h'); - if(shans>1) return [0,1]; - if(shans&&hs>2) return [0,1]; - if(shans) return [0,0]; - if(hs>2) return [0,0]; - if(hs>1) return [1,0.5]; - return [1.5,0]; + ai: { + mingzhi: false, + useShan: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "respondShan")) { + var shans = target.countCards("h", "shan"); + var hs = target.countCards("h"); + if (shans > 1) return [0, 1]; + if (shans && hs > 2) return [0, 1]; + if (shans) return [0, 0]; + if (hs > 2) return [0, 0]; + if (hs > 1) return [1, 0.5]; + return [1.5, 0]; } - } + }, }, - threaten:0.8 - } - }, - gtiandao:{ - audio:true, - trigger:{global:'judge'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + threaten: 0.8, }, - content:function(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('gtiandao'),'he').ai=function(card){ - var trigger=_status.event.parent._trigger; - var player=_status.event.player; - var result=trigger.judge(card)-trigger.judge(trigger.player.judging[0]); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ + }, + gtiandao: { + audio: true, + trigger: { global: "judge" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + content: function () { + "step 0"; + player.chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("gtiandao"), + "he" + ).ai = function (card) { + var trigger = _status.event.parent._trigger; + var player = _status.event.player; + var result = trigger.judge(card) - trigger.judge(trigger.player.judging[0]); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { return result; - } - else{ + } else { return -result; } }; - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight'); - } - else{ + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight"); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.logSkill('gtiandao'); + "step 2"; + if (result.bool) { + player.logSkill("gtiandao"); player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.position.appendChild(result.cards[0]); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); } - "step 3" + "step 3"; game.delay(2); }, - ai:{ - tag:{ - rejudge:1 + ai: { + tag: { + rejudge: 1, }, - threaten:1.5 - } - }, - jinlin:{ - enable:'phaseUse', - unique:true, - mark:true, - skillAnimation:true, - animationColor:'metal', - init:function(player){ - player.storage.jinlin=false; + threaten: 1.5, }, - filter:function(event,player){ - if(player.storage.jinlin) return false; + }, + jinlin: { + enable: "phaseUse", + unique: true, + mark: true, + skillAnimation: true, + animationColor: "metal", + init: function (player) { + player.storage.jinlin = false; + }, + filter: function (event, player) { + if (player.storage.jinlin) return false; return true; }, - filterTarget:true, - selectTarget:[1,Infinity], - contentBefore:function(){ - player.awakenSkill('jinlin'); - player.storage.jinlin=true; + filterTarget: true, + selectTarget: [1, Infinity], + contentBefore: function () { + player.awakenSkill("jinlin"); + player.storage.jinlin = true; }, - content:function(){ + content: function () { target.changeHujia(3); - target.addSkill('jinlin2'); - target.storage.jinlin2=3; + target.addSkill("jinlin2"); + target.storage.jinlin2 = 3; }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(player.hp==1) return 1; - var num=0; - var players=game.filterPlayer(); - for(var i=0;i2){ - if(players[i].hp==1) return 1; - if(players[i].hp==2) { - if(players[i].countCards('h')==0) return 1; + ai: { + order: 1, + result: { + target: function (player, target) { + if (player.hp == 1) return 1; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 2) { + if (players[i].hp == 1) return 1; + if (players[i].hp == 2) { + if (players[i].countCards("h") == 0) return 1; num++; } } } - if(player.hasUnknown()) return 0; - if(num>1) return 1; + if (player.hasUnknown()) return 0; + if (num > 1) return 1; return 0; - } + }, }, }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - jinlin2:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - if(player.hujia>0){ + jinlin2: { + trigger: { player: "phaseBegin" }, + silent: true, + content: function () { + if (player.hujia > 0) { player.changeHujia(-1); } player.storage.jinlin2--; - if(player.hujia==0||player.storage.jinlin2==0){ - player.removeSkill('jinlin2'); + if (player.hujia == 0 || player.storage.jinlin2 == 0) { + player.removeSkill("jinlin2"); delete player.storage.jinlin2; } }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, - lingyue:{ - trigger:{player:'shaBegin'}, - check:function(event,player){ - return get.attitude(player,event.target)<0; + lingyue: { + trigger: { player: "shaBegin" }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - logTarget:'target', - filter:function(event,player){ - return event.target.countCards('he')>0; + logTarget: "target", + filter: function (event, player) { + return event.target.countCards("he") > 0; + }, + content: function () { + trigger.target.chooseToDiscard("he", true); }, - content:function(){ - trigger.target.chooseToDiscard('he',true); - } }, - fengze:{ - enable:'phaseUse', - filterCard:{color:'black'}, - selectCard:1, - position:'he', - usable:1, - viewAs:{name:'taoyuan'}, - filter:function(event,player){ - return player.countCards('he',{color:'black'})>0; + fengze: { + enable: "phaseUse", + filterCard: { color: "black" }, + selectCard: 1, + position: "he", + usable: 1, + viewAs: { name: "taoyuan" }, + filter: function (event, player) { + return player.countCards("he", { color: "black" }) > 0; }, - audio:true, - prompt:'将一张黑色牌当作桃园结义使用', - check:function(card){ - return 7-get.useful(card) + audio: true, + prompt: "将一张黑色牌当作桃园结义使用", + check: function (card) { + return 7 - get.useful(card); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - zaowu:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h',{suit:['spade','heart']})>0; + zaowu: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", { suit: ["spade", "heart"] }) > 0; }, - filterCard:{suit:['spade','heart']}, - viewAs:{name:'fengyinzhidan'}, - check:function(card){ - return 7-get.value(card); + filterCard: { suit: ["spade", "heart"] }, + viewAs: { name: "fengyinzhidan" }, + check: function (card) { + return 7 - get.value(card); + }, + ai: { + order: 8.5, }, - ai:{ - order:8.5, - } }, - huanxia:{ - enable:'chooseToUse', - filterCard:function(card){ - return get.color(card)=='red'; + huanxia: { + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "red"; }, - position:'he', - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(!player.countCards('he',{color:'red'})) return false; + position: "he", + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (!player.countCards("he", { color: "red" })) return false; }, - prompt:'将一张红色牌当杀使用', - check:function(card){return 5-get.value(card)}, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; + prompt: "将一张红色牌当杀使用", + check: function (card) { + return 5 - get.value(card); + }, + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.1; }, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(arg!='use') return false; - if(!player.countCards('he',{color:'red'})) return false; + respondSha: true, + skillTagFilter: function (player, tag, arg) { + if (arg != "use") return false; + if (!player.countCards("he", { color: "red" })) return false; }, }, - group:['huanxia_expire','huanxia_draw','huanxia_gain'], - subSkill:{ - expire:{ - trigger:{source:'damageAfter'}, - forced:true, - popup:false, - filter:function(event){ - return event.parent.skill=='huanxia'; + group: ["huanxia_expire", "huanxia_draw", "huanxia_gain"], + subSkill: { + expire: { + trigger: { source: "damageAfter" }, + forced: true, + popup: false, + filter: function (event) { + return event.parent.skill == "huanxia"; + }, + content: function () { + player.storage.huanxia = true; }, - content:function(){ - player.storage.huanxia=true; - } }, - draw:{ - trigger:{player:'shaAfter'}, - forced:true, - popup:false, - content:function(){ - if(trigger.parent.skill=='huanxia'){ - var card=trigger.cards[0]; - if(get.itemtype(card)=='card'&&get.position(card)=='d'&&!player.storage.huanxia){ + draw: { + trigger: { player: "shaAfter" }, + forced: true, + popup: false, + content: function () { + if (trigger.parent.skill == "huanxia") { + var card = trigger.cards[0]; + if ( + get.itemtype(card) == "card" && + get.position(card) == "d" && + !player.storage.huanxia + ) { ui.special.appendChild(card); - if(!player.storage.huanxia_draw){ - player.storage.huanxia_draw=[]; + if (!player.storage.huanxia_draw) { + player.storage.huanxia_draw = []; } player.storage.huanxia_draw.push(card); } } delete player.storage.huanxia; - } + }, }, - gain:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ + gain: { + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { return player.storage.huanxia_draw; }, - content:function(){ - player.gain(player.storage.huanxia_draw,'gain2'); + content: function () { + player.gain(player.storage.huanxia_draw, "gain2"); delete player.storage.huanxia_draw; - } - } - } + }, + }, + }, }, - kongmo:{ - trigger:{player:'useCardAfter'}, - forced:true, - filter:function(event,player){ - if(event.parent.name=='kongmo') return false; - if(!event.targets||!event.card) return false; - var type=get.type(event.card); - if(type!='basic'&&type!='trick') return false; - var card=game.createCard(event.card.name,event.card.suit,event.card.number); - for(var i=0;i=0) return 0; - if(get.population('fan')<3) return 0; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.hasSkillTag("noturn")) return 0; + if (game.phaseNumber < game.players.length) return 0; + if (game.phaseNumber < game.players.length * 2 && player.hp == player.maxHp) + return 0; + if (player.hasUnknown()) return 0; + switch (lib.config.mode) { + case "identity": { + switch (player.identity) { + case "zhu": { + if (get.situation() >= 0) return 0; + if (get.population("fan") < 3) return 0; return -1; } - case 'zhong':{ - if(get.population('fan')<3) return 0; + case "zhong": { + if (get.population("fan") < 3) return 0; return -1; } - case 'nei':return 0; - case 'fan':{ - if(get.population('fan')==0) return 0; - if(get.population('zhong')<2) return 0; + case "nei": + return 0; + case "fan": { + if (get.population("fan") == 0) return 0; + if (get.population("zhong") < 2) return 0; return -1; } } break; } - case 'guozhan':{ - if(player.identity=='unknown') return 0; - return get.population(player.identity)>=3?-1:0; + case "guozhan": { + if (player.identity == "unknown") return 0; + return get.population(player.identity) >= 3 ? -1 : 0; } - default:{ + default: { return -1; } } }, - } - } - }, - bingfeng2:{ - mod:{ - cardEnabled:function(){ - return false; }, - cardUsable:function(){ - return false; - }, - cardRespondable:function(){ - return false; - }, - cardSavable:function(){ - return false; - } }, - trigger:{player:'turnOverAfter'}, - forced:true, - filter:function(event,player){ + }, + bingfeng2: { + mod: { + cardEnabled: function () { + return false; + }, + cardUsable: function () { + return false; + }, + cardRespondable: function () { + return false; + }, + cardSavable: function () { + return false; + }, + }, + trigger: { player: "turnOverAfter" }, + forced: true, + filter: function (event, player) { return !player.isTurnedOver(); }, - content:function(){ - player.removeSkill('bingfeng2'); - } + content: function () { + player.removeSkill("bingfeng2"); + }, }, - yudun:{ - mod:{ - cardEnabled:function(card,player){ - if(get.type(card,'trick')=='trick') return false; + yudun: { + mod: { + cardEnabled: function (card, player) { + if (get.type(card, "trick") == "trick") return false; }, - cardRespondable:function(card,player){ - if(get.type(card,'trick')=='trick') return false; + cardRespondable: function (card, player) { + if (get.type(card, "trick") == "trick") return false; }, - cardSavable:function(card,player){ - if(get.type(card,'trick')=='trick') return false; + cardSavable: function (card, player) { + if (get.type(card, "trick") == "trick") return false; }, }, - enable:'chooseToUse', - filterCard:function(card){ - return get.type(card,'trick')=='trick'; + enable: "chooseToUse", + filterCard: function (card) { + return get.type(card, "trick") == "trick"; }, - selectCard:2, - viewAs:{name:'sha'}, - viewAsFilter:function(player){ - if(player.countCards('h',{type:['trick','delay']})<2) return false; + selectCard: 2, + viewAs: { name: "sha" }, + viewAsFilter: function (player) { + if (player.countCards("h", { type: ["trick", "delay"] }) < 2) return false; }, - check:function(){return 1}, - ai:{ - skillTagFilter:function(player,tag,arg){ - if(arg!='use') return false; - if(player.countCards('h',{type:['trick','delay']})<2) return false; + check: function () { + return 1; + }, + ai: { + skillTagFilter: function (player, tag, arg) { + if (arg != "use") return false; + if (player.countCards("h", { type: ["trick", "delay"] }) < 2) return false; }, - respondSha:true, - order:function(){ - return get.order({name:'sha'})+0.1; + respondSha: true, + order: function () { + return get.order({ name: "sha" }) + 0.1; }, - useful:-1, - value:-1 + useful: -1, + value: -1, }, - group:'yudun_count', - subSkill:{ - count:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.skill=='yudun'&&_status.currentPhase==player; + group: "yudun_count", + subSkill: { + count: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.skill == "yudun" && _status.currentPhase == player; }, - content:function(){ + content: function () { player.getStat().card.sha--; - } - } - } + }, + }, + }, }, - guozao:{ - trigger:{global:'damageEnd'}, - forced:true, - logv:false, + guozao: { + trigger: { global: "damageEnd" }, + forced: true, + logv: false, // alter:true, - check:function(event,player){ - return game.hasPlayer(function(current){ - return get.attitude(player,current)>2&¤t.countCards('h')==1 + check: function (event, player) { + return game.hasPlayer(function (current) { + return get.attitude(player, current) > 2 && current.countCards("h") == 1; }); }, - filter:function(event,player){ - if(event.source==player) return false; - if(get.distance(player,event.player)>1) return false; - return game.hasPlayer(function(current){ - return current.countCards('h'); + filter: function (event, player) { + if (event.source == player) return false; + if (get.distance(player, event.player) > 1) return false; + return game.hasPlayer(function (current) { + return current.countCards("h"); }); }, - content:function(){ - "step 0" - var cards=[]; - if(ui.cardPile.childNodes.length<3){ - var discardcards=get.cards(3); - for(var i=0;i0&&get.distance(player,target)<=dist; - }).ai=function(target){ - var att=get.attitude(player,target); - var hs=target.getCards('h'); - var num=hs.length; - if(num<=1) return att*2; - if(num==2){ - for(var i=0;i6) return att; + var next = (player.chooseTarget(true, dialog, function (card, player, target) { + return target.countCards("h") > 0 && get.distance(player, target) <= dist; + }).ai = function (target) { + var att = get.attitude(player, target); + var hs = target.getCards("h"); + var num = hs.length; + if (num <= 1) return att * 2; + if (num == 2) { + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i], target, "raw") > 6) return att; } - if(target==player){ - for(var i=0;i<2;i++){ - if(get.value(cards[i],target,'raw')>6) return -1; + if (target == player) { + for (var i = 0; i < 2; i++) { + if (get.value(cards[i], target, "raw") > 6) return -1; } } - return att/2; + return att / 2; } - if(num==3){ - if(target==player){ - var num2=0; - for(var i=0;i<3;i++){ - num2+=get.value(cards[i],player,'raw'); - num2-=get.value(hs[i],player,'raw'); + if (num == 3) { + if (target == player) { + var num2 = 0; + for (var i = 0; i < 3; i++) { + num2 += get.value(cards[i], player, "raw"); + num2 -= get.value(hs[i], player, "raw"); } - if(num2>0) return 0.5; - if(num2<0) return -0.5; + if (num2 > 0) return 0.5; + if (num2 < 0) return -0.5; } return 0; } - return -att/2; - }; - "step 1" - if(result.bool&&result.targets[0]){ - var target=result.targets[0]; - player.line(target,'green'); + return -att / 2; + }); + "step 1"; + if (result.bool && result.targets[0]) { + var target = result.targets[0]; + player.line(target, "green"); // player.logSkill('guozao',target,'green',true); - var cards=target.getCards('h'); - target.lose(cards)._triggered=null; - game.log(target,'弃置了',cards,',并获得三张牌'); + var cards = target.getCards("h"); + target.lose(cards)._triggered = null; + game.log(target, "弃置了", cards, ",并获得三张牌"); // target.$draw(3); target.$throw(cards); - target.gain(event.cards,'draw')._triggered=null; - } - else{ + target.gain(event.cards, "draw")._triggered = null; + } else { event.finish(); } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - heihuo:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0&&player.countCards('he',{type:'equip'})>0&&!player.hasSkill('heihuo2'); + heihuo: { + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + player.countCards("he", { type: "equip" }) > 0 && + !player.hasSkill("heihuo2") + ); }, - filterCard:function(card){ - return get.type(card)=='equip'; + filterCard: function (card) { + return get.type(card) == "equip"; }, - position:'he', - check:function(card){ - var player=_status.currentPhase; - var nh=player.countCards('h'); - var pos=get.position(card); - if(nh<2) return 0; - if(nh>4) return 0; - if(nh==4&&pos=='e') return 0; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card)+(pos=='e'?0.4:0); + position: "he", + check: function (card) { + var player = _status.currentPhase; + var nh = player.countCards("h"); + var pos = get.position(card); + if (nh < 2) return 0; + if (nh > 4) return 0; + if (nh == 4 && pos == "e") return 0; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card) + (pos == "e" ? 0.4 : 0); } - return 5.5-get.value(card)+(pos=='e'?0.4:0); + return 5.5 - get.value(card) + (pos == "e" ? 0.4 : 0); }, - content:function(){ - "step 0" - player.draw(player.countCards('h')); - "step 1" - if(player.countCards('h')>=8){ - player.damage(3,'fire'); - player.addTempSkill('heihuo2'); + content: function () { + "step 0"; + player.draw(player.countCards("h")); + "step 1"; + if (player.countCards("h") >= 8) { + player.damage(3, "fire"); + player.addTempSkill("heihuo2"); } }, - ai:{ - order:10, - threaten:1.4, - result:{ - player:1 - } - } - }, - heihuo2:{}, - yaotong:{ - // alter:true, - group:['yaotong1','yaotong2','yaotong3'], - ai:{ - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ - if(tag=='respondShan'&&get.is.altered('yaotong')) return false; - if(player.countCards('h')%2==0) return false; + ai: { + order: 10, + threaten: 1.4, + result: { + player: 1, }, }, - threaten:1.3 }, - yaotong1:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:true, - viewAs:{name:'sha'}, - filter:function(event,player){ - var num=player.countCards('h'); - if(num==0) return false; - return num%2==1; + heihuo2: {}, + yaotong: { + // alter:true, + group: ["yaotong1", "yaotong2", "yaotong3"], + ai: { + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { + if (tag == "respondShan" && get.is.altered("yaotong")) return false; + if (player.countCards("h") % 2 == 0) return false; + }, }, - prompt:'将一张手牌当作杀使用或打出', - check:function(card){return 6-get.value(card)} + threaten: 1.3, }, - yaotong2:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:true, - viewAs:{name:'shan'}, - filter:function(event,player){ - if(get.is.altered('yaotong')) return false; - var num=player.countCards('h'); - if(num==0) return false; - return num%2==1; + yaotong1: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: true, + viewAs: { name: "sha" }, + filter: function (event, player) { + var num = player.countCards("h"); + if (num == 0) return false; + return num % 2 == 1; + }, + prompt: "将一张手牌当作杀使用或打出", + check: function (card) { + return 6 - get.value(card); }, - prompt:'将一张手牌当作闪使用或打出', - check:function(card){return 6-get.value(card)} }, - yaotong3:{ - enable:'chooseToUse', - filterCard:true, - viewAs:{name:'wuxie'}, - filter:function(event,player){ - var num=player.countCards('h'); - if(num==0) return false; - return num%2==0; + yaotong2: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: true, + viewAs: { name: "shan" }, + filter: function (event, player) { + if (get.is.altered("yaotong")) return false; + var num = player.countCards("h"); + if (num == 0) return false; + return num % 2 == 1; }, - viewAsFilter:function(player){ - var num=player.countCards('h'); - if(num==0) return false; - return num%2==0; + prompt: "将一张手牌当作闪使用或打出", + check: function (card) { + return 6 - get.value(card); }, - prompt:'将一张手牌当作无懈可击使用', - check:function(card){return 7-get.value(card)}, }, - yaotong4:{ - enable:'chooseToUse', - filterCard:true, - viewAs:{name:'tao'}, - filter:function(event,player){ - var num=player.countCards('h'); - if(num==0) return false; - return num%2==0; + yaotong3: { + enable: "chooseToUse", + filterCard: true, + viewAs: { name: "wuxie" }, + filter: function (event, player) { + var num = player.countCards("h"); + if (num == 0) return false; + return num % 2 == 0; }, - viewAsFilter:function(player){ - var num=player.countCards('h'); - if(num==0) return false; - return num%2==0; + viewAsFilter: function (player) { + var num = player.countCards("h"); + if (num == 0) return false; + return num % 2 == 0; + }, + prompt: "将一张手牌当作无懈可击使用", + check: function (card) { + return 7 - get.value(card); }, - prompt:'将一张手牌当作桃使用', - check:function(card){return 9-get.value(card)}, }, - pojian:{ - trigger:{player:'loseEnd'}, - filter:function(event,player){ - if(player.countCards('h')) return false; - for(var i=0;i0; + huajin: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:'he', - content:function(){ - player.addSkill('huajin2'); + filterCard: true, + position: "he", + content: function () { + player.addSkill("huajin2"); }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - ai:{ - order:10, - result:{ - player:function(player){ - if(player.countCards('h','juedou')) return 1; - if(player.countCards('h','sha')==0) return 0; - var players=game.filterPlayer(); - for(var i=0;i0){ + ai: { + order: 10, + result: { + player: function (player) { + if (player.countCards("h", "juedou")) return 1; + if (player.countCards("h", "sha") == 0) return 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + player.canUse("sha", players[i]) && + get.effect(players[i], { name: "sha" }, player, player) > 0 + ) { return 1; } } return 0; - } - } - } + }, + }, + }, }, - huajin2:{ - trigger:{source:'damageBegin'}, - forced:true, - content:function(){ + huajin2: { + trigger: { source: "damageBegin" }, + forced: true, + content: function () { trigger.num++; }, - group:'huajin3' + group: "huajin3", }, - huajin3:{ - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('huajin2'); - } + huajin3: { + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("huajin2"); + }, }, - yuchen:{ - trigger:{player:['useCard','respondAfter']}, - direct:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.cards){ - for(var i=0;i0; - }).set('autodelay',trigger.name=='respond'?0.5:1).ai=function(target){ - return -get.attitude(player,target); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("yuchen"), function (card, player, target) { + return player != target && target.countCards("he") > 0; + }) + .set("autodelay", trigger.name == "respond" ? 0.5 : 1).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('yuchen',result.targets); - player.discardPlayerCard(result.targets[0],true); + "step 1"; + if (result.bool) { + player.logSkill("yuchen", result.targets); + player.discardPlayerCard(result.targets[0], true); } }, - ai:{ - threaten:0.7 - } + ai: { + threaten: 0.7, + }, }, - bingjian:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',{color:'black',name:'sha'})>0; + bingjian: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { color: "black", name: "sha" }) > 0; }, - filterCard:function(card){ - return card.name=='sha'&&get.color(card)=='black'; + filterCard: function (card) { + return card.name == "sha" && get.color(card) == "black"; }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return player != target && target.countCards("h") > 0; }, - line:'thunder', - content:function(){ - "step 0" + line: "thunder", + content: function () { + "step 0"; target.showHandcards(); - "step 1" - var cards=target.getCards('h','shan'); - if(cards.length){ + "step 1"; + var cards = target.getCards("h", "shan"); + if (cards.length) { target.discard(cards); - } - else{ - target.damage('thunder'); + } else { + target.damage("thunder"); } }, - ai:{ - order:5, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'thunder'); - } + ai: { + order: 5, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "thunder"); + }, }, - expose:0.2 - } - }, - rumeng:{ - trigger:{global:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return event.player!=player&&player.countCards('he',{type:'basic'})2; - var next=player.chooseToDiscard(function(card){ - return get.type(card)!='basic'; - },get.prompt('rumeng',trigger.player),'he'); - next.logSkill=['rumeng',trigger.player]; - next.ai=function(card){ - if(yep){ - return 6-get.value(card); + }, + rumeng: { + trigger: { global: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return ( + event.player != player && + player.countCards("he", { type: "basic" }) < player.countCards("he") + ); + }, + content: function () { + "step 0"; + var yep = get.attitude(player, trigger.player) < 0 && trigger.player.countCards("h") > 2; + var next = player.chooseToDiscard( + function (card) { + return get.type(card) != "basic"; + }, + get.prompt("rumeng", trigger.player), + "he" + ); + next.logSkill = ["rumeng", trigger.player]; + next.ai = function (card) { + if (yep) { + return 6 - get.value(card); } return 0; - } - "step 1" - if(result.bool){ - trigger.player.chooseToDiscard({type:'basic'},'入梦:弃置一张基本牌或跳过出牌及弃牌阶段').ai=function(card){ - return 5-get.value(card); - } - } - else{ + }; + "step 1"; + if (result.bool) { + trigger.player.chooseToDiscard( + { type: "basic" }, + "入梦:弃置一张基本牌或跳过出牌及弃牌阶段" + ).ai = function (card) { + return 5 - get.value(card); + }; + } else { event.finish(); } - "step 2" - if(!result.bool){ + "step 2"; + if (!result.bool) { trigger.cancel(); - trigger.player.skip('phaseDiscard'); + trigger.player.skip("phaseDiscard"); } }, - ai:{ - expose:0.1 - } - }, - lianda:{ - trigger:{player:'shaAfter'}, - direct:true, - filter:function(event,player){ - return event.target.isAlive()&&player.countCards('he')>0&&!player.hasSkill('lianda2'); + ai: { + expose: 0.1, }, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he',get.prompt('lianda')); - next.ai=function(card){ - if(get.effect(trigger.target,{name:'sha'},player,player)>0){ - return 7-get.value(card); + }, + lianda: { + trigger: { player: "shaAfter" }, + direct: true, + filter: function (event, player) { + return ( + event.target.isAlive() && player.countCards("he") > 0 && !player.hasSkill("lianda2") + ); + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard("he", get.prompt("lianda")); + next.ai = function (card) { + if (get.effect(trigger.target, { name: "sha" }, player, player) > 0) { + return 7 - get.value(card); } return 0; + }; + next.logSkill = "lianda"; + "step 1"; + if (result.bool) { + player.addTempSkill("lianda2"); + player.useCard({ name: "sha" }, trigger.target); } - next.logSkill='lianda'; - "step 1" - if(result.bool){ - player.addTempSkill('lianda2'); - player.useCard({name:'sha'},trigger.target); - } - } - }, - lianda2:{}, - huiqi:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.hp3){ - return att+Math.max(0,5-target.countCards('h')); + if (att > 3) { + return att + Math.max(0, 5 - target.countCards("h")); } - return att/4; + return att / 4; } - if(att>3){ - return att+Math.max(0,5-target.countCards('h')); + if (att > 3) { + return att + Math.max(0, 5 - target.countCards("h")); } return att; - } - "step 1" - if(result.bool){ - player.logSkill('huiqi',result.targets); - result.targets[0].draw(player.maxHp-player.hp); + }; + "step 1"; + if (result.bool) { + player.logSkill("huiqi", result.targets); + result.targets[0].draw(player.maxHp - player.hp); } }, - ai:{ - expose:0.2, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - return [1,0.5]; + ai: { + expose: 0.2, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + return [1, 0.5]; } - } - } - } + }, + }, + }, }, - xianghui:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'red'}, - filter:function(event,player){ - if(!player.countCards('h',{color:'red'})) return false; - var players=game.filterPlayer(); - var min=players[0].hp; - for(var i=0;i2){ - if(player.countCards('h','shan')||player.getEquip(2)|| - trigger.target.hp==1||player.hp>trigger.target.hp+1){ - if(!trigger.target.countCards('h','shan')||trigger.target.countCards('h') 2) { + if ( + player.countCards("h", "shan") || + player.getEquip(2) || + trigger.target.hp == 1 || + player.hp > trigger.target.hp + 1 + ) { + if ( + !trigger.target.countCards("h", "shan") || + trigger.target.countCards("h") < player.countCards("h") + ) { + save = true; } } } - var next=player.chooseToDiscard('he',get.prompt('hzhenwei')); - next.logSkill=['hzhenwei',trigger.target]; - next.ai=function(card){ - if(save){ - return 7-get.value(card); + var next = player.chooseToDiscard("he", get.prompt("hzhenwei")); + next.logSkill = ["hzhenwei", trigger.target]; + next.ai = function (card) { + if (save) { + return 7 - get.value(card); } return 0; - } - "step 1" - if(result.bool){ - trigger.target=player; - player.addSkill('hzhenwei2'); + }; + "step 1"; + if (result.bool) { + trigger.target = player; + player.addSkill("hzhenwei2"); game.delay(); } }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='sha') return 1.3; - } - } - } + ai: { + effect: { + target: function (card) { + if (card.name == "sha") return 1.3; + }, + }, + }, }, - hzhenwei2:{ - trigger:{target:'shaAfter'}, - forced:true, - popup:false, - content:function(){ + hzhenwei2: { + trigger: { target: "shaAfter" }, + forced: true, + popup: false, + content: function () { player.draw(); - player.removeSkill('hzhenwei2'); - } + player.removeSkill("hzhenwei2"); + }, }, - fzhenwei:{ - trigger:{global:'respondEnd'}, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - if(event.player==player) return false; - if(event.cards){ - for(var i=0;i3){ - return 100-target.countCards('h'); + event.cards = cards; + player + .chooseTarget(get.prompt("fzhenwei"), function (card, player, target) { + return target != trigger.player; + }) + .set("autodelay", 0.5).ai = function (target) { + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (att > 3) { + return 100 - target.countCards("h"); } return att; - } - "step 1" - if(result.bool){ - player.logSkill('fzhenwei',result.targets); - result.targets[0].gain(event.cards,'gain2','log'); + }; + "step 1"; + if (result.bool) { + player.logSkill("fzhenwei", result.targets); + result.targets[0].gain(event.cards, "gain2", "log"); } }, - ai:{ - expose:0.1, - threaten:1.6 - } + ai: { + expose: 0.1, + threaten: 1.6, + }, }, - shangxi:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - if(player.countCards('he')==0) return false; - return game.hasPlayer(function(current){ - return (current!=player&&get.distance(player,current,'attack')<=1&&player.hp<=current.hp); + shangxi: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + if (player.countCards("he") == 0) return false; + return game.hasPlayer(function (current) { + return ( + current != player && + get.distance(player, current, "attack") <= 1 && + player.hp <= current.hp + ); }); }, - content:function(){ - "step 0" - var next=player.chooseCardTarget({ - position:'he', - filterTarget:function(card,player,target){ - return get.distance(player,target,'attack')<=1&& - player!=target&&player.hp<=target.hp; + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + position: "he", + filterTarget: function (card, player, target) { + return ( + get.distance(player, target, "attack") <= 1 && + player != target && + player.hp <= target.hp + ); }, - filterCard:lib.filter.cardDiscardable, - ai1:function(card){ - return 9-get.value(card); + filterCard: lib.filter.cardDiscardable, + ai1: function (card) { + return 9 - get.value(card); }, - ai2:function(target){ - return get.damageEffect(target,player,player); + ai2: function (target) { + return get.damageEffect(target, player, player); }, - prompt:get.prompt('shangxi') + prompt: get.prompt("shangxi"), }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - player.logSkill('shangxi',result.targets); + player.logSkill("shangxi", result.targets); result.targets[0].damage(); } }, - ai:{ - expose:0.3 - } - }, - fuyan:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event){ - return event.num>0; + ai: { + expose: 0.3, }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('fuyan'),function(card,player,target){ + }, + fuyan: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event) { + return event.num > 0; + }, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("fuyan"), function (card, player, target) { return !target.hujia; - }).ai=function(target){ - if(get.attitude(player,target)<=0) return 0; - var eff=-get.damageEffect(target,target,player)+(player==target?2:0); - if(target.hp==1) eff+=2; - return Math.min(1,eff); + }).ai = function (target) { + if (get.attitude(player, target) <= 0) return 0; + var eff = -get.damageEffect(target, target, player) + (player == target ? 2 : 0); + if (target.hp == 1) eff += 2; + return Math.min(1, eff); }; - "step 1" - if(result.bool){ - player.logSkill('fuyan',result.targets); - var target=result.targets[0]; + "step 1"; + if (result.bool) { + player.logSkill("fuyan", result.targets); + var target = result.targets[0]; target.changeHujia(); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; return 0.7; } - } + }, }, - expose:0.2 - } - }, - fuyan2:{ - trigger:{player:'damageBegin'}, - filter:function(event,player){ - return event.num>0; + expose: 0.2, }, - forced:true, - mark:'card', - content:function(){ + }, + fuyan2: { + trigger: { player: "damageBegin" }, + filter: function (event, player) { + return event.num > 0; + }, + forced: true, + mark: "card", + content: function () { trigger.num--; - player.removeSkill('fuyan2'); + player.removeSkill("fuyan2"); player.storage.fuyan2.discard(); delete player.storage.fuyan2; }, - intro:{ - content:'card' - } + intro: { + content: "card", + }, }, - pingshen:{ - trigger:{source:'damageBegin'}, - unique:true, - silent:true, - content:function(){ - trigger.player.addSkill('pingshen2'); - trigger.player.storage.pingshen=player; - } + pingshen: { + trigger: { source: "damageBegin" }, + unique: true, + silent: true, + content: function () { + trigger.player.addSkill("pingshen2"); + trigger.player.storage.pingshen = player; + }, }, - pingshen2:{ - enable:'phaseUse', - unique:true, - mark:true, - init:function(player){ - player.storage.pingshen2=false; + pingshen2: { + enable: "phaseUse", + unique: true, + mark: true, + init: function (player) { + player.storage.pingshen2 = false; }, - filter:function(event,player){ - return !player.storage.pingshen2&&player.storage.pingshen.isAlive(); + filter: function (event, player) { + return !player.storage.pingshen2 && player.storage.pingshen.isAlive(); }, - filterCard:true, - filterTarget:function(card,player,target){ - return target==player.storage.pingshen; + filterCard: true, + filterTarget: function (card, player, target) { + return target == player.storage.pingshen; }, - selectTarget:-1, - position:'he', - content:function(){ - player.storage.pingshen2=true; - player.unmarkSkill('pingshen2'); - player.gain(target.getCards('h'),target); - target.$give(target.countCards('h'),player); + selectTarget: -1, + position: "he", + content: function () { + player.storage.pingshen2 = true; + player.unmarkSkill("pingshen2"); + player.gain(target.getCards("h"), target); + target.$give(target.countCards("h"), player); player.turnOver(); - player.addSkill('pingshen3'); + player.addSkill("pingshen3"); }, - check:function(card){return 8-get.value(card);}, - intro:{ - content:'limited' + check: function (card) { + return 8 - get.value(card); }, - ai:{ - order:10, - result:{ - player:function(player){ - if(player.classList.contains('turnedover')) return 10; - if(get.attitude(player,player.storage.pingshen)>=0){ + intro: { + content: "limited", + }, + ai: { + order: 10, + result: { + player: function (player) { + if (player.classList.contains("turnedover")) return 10; + if (get.attitude(player, player.storage.pingshen) >= 0) { return 0; } - if(player.storage.pingshen.countCards('h')>player.storage.pingshen.hp) return 1; + if (player.storage.pingshen.countCards("h") > player.storage.pingshen.hp) + return 1; return 0; - } + }, }, - effect:{ - target:function(card,player,target){ - if(!target.storage.pingshen2){ - if(card.name=='guiyoujie') return [0,1]; + effect: { + target: function (card, player, target) { + if (!target.storage.pingshen2) { + if (card.name == "guiyoujie") return [0, 1]; } - } - } + }, + }, }, }, - pingshen3:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - content:function(){ - "step 0" - player.removeSkill('pingshen3'); - if(player.storage.pingshen.classList.contains('dead')){ + pingshen3: { + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + content: function () { + "step 0"; + player.removeSkill("pingshen3"); + if (player.storage.pingshen.classList.contains("dead")) { event.finish(); + } else { + player.chooseCard("he", true, player.storage.pingshen.hp); } - else{ - player.chooseCard('he',true,player.storage.pingshen.hp); - } - "step 1" - player.storage.pingshen.gain(result.cards,player); - player.$give(result.cards.length,player.storage.pingshen); - } - }, - guaili:{ - trigger:{source:'damageBegin'}, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.parent.name!='_lianhuan'&&event.parent.name!='_lianhuan2'; + "step 1"; + player.storage.pingshen.gain(result.cards, player); + player.$give(result.cards.length, player.storage.pingshen); }, - forced:true, - content:function(){ + }, + guaili: { + trigger: { source: "damageBegin" }, + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + event.parent.name != "_lianhuan" && + event.parent.name != "_lianhuan2" + ); + }, + forced: true, + content: function () { trigger.num++; - player.addSkill('guaili2'); - } - }, - guaili2:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('guaili2'); - player.chooseToDiscard(2,true); - } - }, - xingzhui:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('he')>0; + player.addSkill("guaili2"); }, - check:function(card){ - if(get.type(card)=='equip'){ - var distance=get.info(card).distance; - if(distance){ - if(distance.attackFrom<0||distance.globalFrom<0) return 10; + }, + guaili2: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("guaili2"); + player.chooseToDiscard(2, true); + }, + }, + xingzhui: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; + }, + check: function (card) { + if (get.type(card) == "equip") { + var distance = get.info(card).distance; + if (distance) { + if (distance.attackFrom < 0 || distance.globalFrom < 0) return 10; } } - return 7-get.value(card); + return 7 - get.value(card); }, - content:function(){ - "step 0" - event.type=get.type(cards[0],'trick'); - var dme=get.damageEffect(target,player,target); - target.chooseToDiscard('he',function(card){ - return get.type(card,'trick')==event.type; - },'弃置一张牌'+get.translation(event.type)+'牌,或受到1点伤害').ai=function(card){ - if(dme<0){ - return 8-get.value(card); + content: function () { + "step 0"; + event.type = get.type(cards[0], "trick"); + var dme = get.damageEffect(target, player, target); + target.chooseToDiscard( + "he", + function (card) { + return get.type(card, "trick") == event.type; + }, + "弃置一张牌" + get.translation(event.type) + "牌,或受到1点伤害" + ).ai = function (card) { + if (dme < 0) { + return 8 - get.value(card); } return 0; - } - "step 1" - if(!result.bool){ + }; + "step 1"; + if (!result.bool) { target.damage(); } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return get.damageEffect(target,player); - } + ai: { + order: 9, + result: { + target: function (player, target) { + return get.damageEffect(target, player); + }, }, - threaten:2, - expose:0.2 - } + threaten: 2, + expose: 0.2, + }, }, - lingxian:{ - trigger:{player:['respond','useCard']}, - direct:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(get.itemtype(event.cards)!='cards') return false; - return game.hasPlayer(function(current){ - return get.distance(player,current,'attack')>1&&player!=current; + lingxian: { + trigger: { player: ["respond", "useCard"] }, + direct: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (get.itemtype(event.cards) != "cards") return false; + return game.hasPlayer(function (current) { + return get.distance(player, current, "attack") > 1 && player != current; }); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('lingxian'),function(card,player,target){ - return get.distance(player,target,'attack')>1&&player!=target; - }).ai=function(target){ - var att=get.attitude(player,target); - if(att<=-0.5) return 0; - if(att<=3) return att+0.5; - return att+Math.min(0.5,5-target.countCards('h')); - } - "step 1" - if(result.bool){ - game.asyncDraw([player,result.targets[0]]); - player.logSkill('lingxian',result.targets); + content: function () { + "step 0"; + player.chooseTarget(get.prompt("lingxian"), function (card, player, target) { + return get.distance(player, target, "attack") > 1 && player != target; + }).ai = function (target) { + var att = get.attitude(player, target); + if (att <= -0.5) return 0; + if (att <= 3) return att + 0.5; + return att + Math.min(0.5, 5 - target.countCards("h")); + }; + "step 1"; + if (result.bool) { + game.asyncDraw([player, result.targets[0]]); + player.logSkill("lingxian", result.targets); } }, - ai:{ - mingzhi:false, - effect:{ - target:function(card,player,target){ - if(player==_status.currentPhase) return; - if(!game.hasPlayer(function(current){ - return get.distance(player,current,'attack')>1&&player!=current&&get.attitude(player,current)>=0; - })){ + ai: { + mingzhi: false, + effect: { + target: function (card, player, target) { + if (player == _status.currentPhase) return; + if ( + !game.hasPlayer(function (current) { + return ( + get.distance(player, current, "attack") > 1 && + player != current && + get.attitude(player, current) >= 0 + ); + }) + ) { return; } - if(get.type(card)=='equip'&&player==target){ - var distance=get.info(card).distance; - if(distance){ - if(distance.attackFrom<0||distance.globalFrom<0) return 0; + if (get.type(card) == "equip" && player == target) { + var distance = get.info(card).distance; + if (distance) { + if (distance.attackFrom < 0 || distance.globalFrom < 0) return 0; + } + } else { + if (!target.hasFriend()) return; + var hs = target.countCards("h"); + if (get.tag(card, "respondShan")) { + var shans = target.countCards("h", "shan"); + if (shans > 1) return [0, 1]; + if (shans && hs > 2) return [0, 1]; + if (shans) return [0, 0]; + if (hs > 2) return [0, 0]; + if (hs > 1) return [1, 0.5]; + return [1.5, 0]; + } + if (get.tag(card, "respondSha")) { + var shas = target.countCards("h", "sha"); + if (shas > 1) return [0, 1]; + if (shas && hs > 2) return [0, 1]; + if (shas) return [0, 0]; + if (hs > 2) return [0, 0]; + if (hs > 1) return [1, 0.5]; + return [1.5, 0]; } } - else{ - if(!target.hasFriend()) return; - var hs=target.countCards('h'); - if(get.tag(card,'respondShan')){ - var shans=target.countCards('h','shan'); - if(shans>1) return [0,1]; - if(shans&&hs>2) return [0,1]; - if(shans) return [0,0]; - if(hs>2) return [0,0]; - if(hs>1) return [1,0.5]; - return [1.5,0]; - } - if(get.tag(card,'respondSha')){ - var shas=target.countCards('h','sha'); - if(shas>1) return [0,1]; - if(shas&&hs>2) return [0,1]; - if(shas) return [0,0]; - if(hs>2) return [0,0]; - if(hs>1) return [1,0.5]; - return [1.5,0]; - } - } - } + }, }, - threaten:0.8, - expose:0.1 - } - }, - shouyin:{ - skillAnimation:'epic', - animationColor:'water', - unique:true, - enable:'chooseToUse', - init:function(player){ - player.storage.shouyin=false; + threaten: 0.8, + expose: 0.1, }, - mark:true, - filter:function(event,player){ - if(event.type!='dying') return false; - if(player.storage.shouyin) return false; - if(player.isTurnedOver()) return false; + }, + shouyin: { + skillAnimation: "epic", + animationColor: "water", + unique: true, + enable: "chooseToUse", + init: function (player) { + player.storage.shouyin = false; + }, + mark: true, + filter: function (event, player) { + if (event.type != "dying") return false; + if (player.storage.shouyin) return false; + if (player.isTurnedOver()) return false; return true; }, - content:function(){ - "step 0" - player.awakenSkill('shouyin'); - player.storage.shouyin=true; + content: function () { + "step 0"; + player.awakenSkill("shouyin"); + player.storage.shouyin = true; player.turnOver(); - "step 1" - event.targets=game.filterPlayer(); + "step 1"; + event.targets = game.filterPlayer(); event.targets.sort(lib.sort.seat); - "step 2" - if(event.targets.length){ - var target=event.targets.shift(); - if(target.hp=target.hp){ + sliufeng: { + mod: { + targetInRange: function (card, player, target) { + if (card.name == "sha" && player.hp >= target.hp) { return true; } - } + }, }, }, - linyun:{ - enable:'chooseToUse', - filterCard:true, - selectCard:2, - position:'he', - viewAs:{name:'sha'}, - prompt:'将两张牌当杀使用', - check:function(card){ - if(_status.event.player.countCards('h')<4) return 6-get.useful(card); - return 7-get.useful(card); + linyun: { + enable: "chooseToUse", + filterCard: true, + selectCard: 2, + position: "he", + viewAs: { name: "sha" }, + prompt: "将两张牌当杀使用", + check: function (card) { + if (_status.event.player.countCards("h") < 4) return 6 - get.useful(card); + return 7 - get.useful(card); }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; - } + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.1; + }, }, - group:['linyun2'] + group: ["linyun2"], }, - linyun2:{ - trigger:{player:'shaBegin'}, - filter:function(event){ - return event.skill=='linyun' + linyun2: { + trigger: { player: "shaBegin" }, + filter: function (event) { + return event.skill == "linyun"; }, - forced:true, - popup:false, - content:function(){ - "step 0" - var next=trigger.target.chooseToRespond({name:'shan'}); - next.autochoose=lib.filter.autoRespondShan; - next.ai=function(card){ - if(trigger.target.countCards('h','shan')>1){ + forced: true, + popup: false, + content: function () { + "step 0"; + var next = trigger.target.chooseToRespond({ name: "shan" }); + next.autochoose = lib.filter.autoRespondShan; + next.ai = function (card) { + if (trigger.target.countCards("h", "shan") > 1) { return get.unuseful2(card); } return -1; }; - "step 1" - if(result.bool==false){ + "step 1"; + if (result.bool == false) { trigger.untrigger(); - trigger.directHit=true; + trigger.directHit = true; } }, - ai:{ - threaten:1.3 - } - }, - linyun3:{ - trigger:{source:'damageAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.parent.skill=='linyun'&&!player.hasSkill('linyun4'); + ai: { + threaten: 1.3, }, - content:function(){ - player.draw(); - player.addTempSkill('linyun4','shaAfter') - } }, - linyun4:{}, - bofeng:{ - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&player.hp>=target.hp){ + linyun3: { + trigger: { source: "damageAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.parent.skill == "linyun" && !player.hasSkill("linyun4"); + }, + content: function () { + player.draw(); + player.addTempSkill("linyun4", "shaAfter"); + }, + }, + linyun4: {}, + bofeng: { + mod: { + targetInRange: function (card, player, target) { + if (card.name == "sha" && player.hp >= target.hp) { return true; } - } + }, }, - trigger:{player:'shaBegin'}, - check:function(event,player){ - return get.attitude(player,event.target)<0; + trigger: { player: "shaBegin" }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - content:function(){ - "step 0" - trigger.target.chooseToRespond({name:'shan'}); - "step 1" - if(result.bool==false){ + content: function () { + "step 0"; + trigger.target.chooseToRespond({ name: "shan" }); + "step 1"; + if (result.bool == false) { trigger.untrigger(); - trigger.directHit=true; - player.addTempSkill('bofeng2','shaEnd'); + trigger.directHit = true; + player.addTempSkill("bofeng2", "shaEnd"); } }, - ai:{ - threaten:1.3 - } - }, - bofeng2:{ - trigger:{source:'damageBegin'}, - filter:function(event){ - return (event.card&&(event.card.name=='sha')&&event.parent.name!='_lianhuan'&&event.parent.name!='_lianhuan2'); + ai: { + threaten: 1.3, }, - forced:true, - popup:false, - content:function(){ + }, + bofeng2: { + trigger: { source: "damageBegin" }, + filter: function (event) { + return ( + event.card && + event.card.name == "sha" && + event.parent.name != "_lianhuan" && + event.parent.name != "_lianhuan2" + ); + }, + forced: true, + popup: false, + content: function () { trigger.num++; }, }, - hutian:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0&&!player.storage.hutian; + hutian: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0 && !player.storage.hutian; }, - content:function(){ - "step 0" - var next=player.chooseCardTarget({ - filterTarget:function(card,player,target){ - return target.maxHp>=ui.selected.cards.length; + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + filterTarget: function (card, player, target) { + return target.maxHp >= ui.selected.cards.length; }, - filterCard:true, - selectCard:[1,player.countCards('he')], - ai1:function(card){ - var useful=get.useful(card); - if(card.name=='du'){ - useful=-5; + filterCard: true, + selectCard: [1, player.countCards("he")], + ai1: function (card) { + var useful = get.useful(card); + if (card.name == "du") { + useful = -5; } - if(ui.selected.cards.length==0&&player.hp==1) return 11-useful; - if(ui.selected.cards.length>1) return 0; - return 7-useful; + if (ui.selected.cards.length == 0 && player.hp == 1) return 11 - useful; + if (ui.selected.cards.length > 1) return 0; + return 7 - useful; }, - ai2:function(target){ - if(target.hp>ui.selected.cards.length){ + ai2: function (target) { + if (target.hp > ui.selected.cards.length) { return 0; } - return get.attitude(player,target); + return get.attitude(player, target); }, - position:'he', - prompt:get.prompt('hutian') + position: "he", + prompt: get.prompt("hutian"), }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.$give(result.cards,target); - player.lose(result.cards,ui.special); - player.storage.hutian=target; - player.logSkill('hutian',result.targets); - player.addTempSkill('hutian4'); - target.addSkill('hutian2'); - target.storage.hutian2=result.cards; - game.addVideo('storage',target,['hutian2',get.cardsInfo(result.cards),'cards']); - } - else{ + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.$give(result.cards, target); + player.lose(result.cards, ui.special); + player.storage.hutian = target; + player.logSkill("hutian", result.targets); + player.addTempSkill("hutian4"); + target.addSkill("hutian2"); + target.storage.hutian2 = result.cards; + game.addVideo("storage", target, ["hutian2", get.cardsInfo(result.cards), "cards"]); + } else { event.finish(); } - "step 2" - var target=event.target; - if(target.storage.hutian2&&target.hp0; + hutian4: {}, + chengjian: { + trigger: { global: "damageEnd" }, + check: function (event, player) { + return get.attitude(player, event.source) > 0; }, - filter:function(event,player){ - return event.source&&event.card&&event.card.name=='sha'&&event.source!=player; + filter: function (event, player) { + return event.source && event.card && event.card.name == "sha" && event.source != player; }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { trigger.source.draw(); }, - ai:{ - expose:0.1, - threaten:1.2 - } + ai: { + expose: 0.1, + threaten: 1.2, + }, }, - huanxing:{ - trigger:{player:'phaseBegin'}, - group:'huanxing2', - direct:true, - content:function(){ - "step 0" - if(player.countCards('he')){ + huanxing: { + trigger: { player: "phaseBegin" }, + group: "huanxing2", + direct: true, + content: function () { + "step 0"; + if (player.countCards("he")) { player.chooseCardTarget({ - prompt:get.prompt('huanxing'), - filterCard:lib.filter.cardDiscardable, - position:'he', - filterTarget:function(card,player,target){ - if(target==player) return false; - if(target.sex!='male') return false; - var name=target.name.indexOf('unknown')==0?target.name2:target.name; - if(name==player.storage.huanxing) return false; - var info=lib.character[name]; - if(info){ - var skills=info[3]; - for(var j=0;j0) return 0; - return 7-get.value(card); + ai1: function (card) { + if ( + player.additionalSkills.huanxing && + player.additionalSkills.huanxing.length > 0 + ) + return 0; + return 7 - get.value(card); + }, + ai2: function (target) { + if (target.isMin()) return 0; + return 6 - target.maxHp; }, - ai2:function(target){ - if(target.isMin()) return 0; - return 6-target.maxHp; - } }); - } - else{ + } else { event.finish(); } - "step 1" - if(result.bool){ - player.unmark(player.storage.huanxing+'_charactermark'); + "step 1"; + if (result.bool) { + player.unmark(player.storage.huanxing + "_charactermark"); player.discard(result.cards); - player.logSkill('huanxing',result.targets); - var name=result.targets[0].name; - if(name.indexOf('unknown')==0){ - name=result.targets[0].name2; + player.logSkill("huanxing", result.targets); + var name = result.targets[0].name; + if (name.indexOf("unknown") == 0) { + name = result.targets[0].name2; } - var list=[]; - var skills=lib.character[name][3]; - for(var j=0;j0; + ai: { + threaten: 1.5, }, - content:function(){ - player.unmark(player.storage.huanxing+'_charactermark'); - player.removeAdditionalSkill('huanxing'); + }, + huanxing2: { + trigger: { player: "damageAfter" }, + priority: -15, + forced: true, + filter: function (event, player) { + return player.additionalSkills.huanxing && player.additionalSkills.huanxing.length > 0; + }, + content: function () { + player.unmark(player.storage.huanxing + "_charactermark"); + player.removeAdditionalSkill("huanxing"); delete player.storage.huanxing; player.checkMarks(); - } + }, }, - guiying:{ - enable:'chooseToUse', - filterCard:{color:'black'}, - position:'he', - viewAs:{name:'toulianghuanzhu'}, - prompt:'将一张黑色牌当作偷梁换柱使用', - check:function(card){ - if(_status.event.player.countCards('h')>_status.event.player.hp){ - return 5-get.value(card) + guiying: { + enable: "chooseToUse", + filterCard: { color: "black" }, + position: "he", + viewAs: { name: "toulianghuanzhu" }, + prompt: "将一张黑色牌当作偷梁换柱使用", + check: function (card) { + if (_status.event.player.countCards("h") > _status.event.player.hp) { + return 5 - get.value(card); } return 0; }, }, - suiyan:{ - trigger:{source:'damageEnd'}, - direct:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player.countCards('e'); + suiyan: { + trigger: { source: "damageEnd" }, + direct: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player.countCards("e"); }, - content:function(){ - "step 0" - var att=get.attitude(player,trigger.player); - var next=player.chooseToDiscard('he',get.prompt('suiyan')); - next.ai=function(card){ - if(att<0) return 7-get.value(card); + content: function () { + "step 0"; + var att = get.attitude(player, trigger.player); + var next = player.chooseToDiscard("he", get.prompt("suiyan")); + next.ai = function (card) { + if (att < 0) return 7 - get.value(card); return -1; - } - next.logSkill=['suiyan',trigger.player]; - "step 1" - if(result.bool){ - trigger.player.discard(trigger.player.getCards('e')); + }; + next.logSkill = ["suiyan", trigger.player]; + "step 1"; + if (result.bool) { + trigger.player.discard(trigger.player.getCards("e")); } }, - ai:{ - expose:0.3 + ai: { + expose: 0.3, }, }, - ningxian:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he',{color:'black'})>0; + ningxian: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he", { color: "black" }) > 0; }, - content:function(){ - "step 0" - var enemy=game.countPlayer(function(current){ - return current!=player&&get.damageEffect(current,player,player)>0; + content: function () { + "step 0"; + var enemy = game.countPlayer(function (current) { + return current != player && get.damageEffect(current, player, player) > 0; }); - var next=player.chooseCardTarget({ - position:'he', - filterTarget:function(card,player,target){ - return player!=target; + var next = player.chooseCardTarget({ + position: "he", + filterTarget: function (card, player, target) { + return player != target; }, - selectCard:[1,player.countCards('he',{color:'black'})], - selectTarget:function(){ - if(ui.selected.targets.length>ui.selected.cards.length){ - game.uncheck('target'); + selectCard: [1, player.countCards("he", { color: "black" })], + selectTarget: function () { + if (ui.selected.targets.length > ui.selected.cards.length) { + game.uncheck("target"); } return ui.selected.cards.length; }, - filterCard:function(card,player){ - return get.color(card)=='black'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.color(card) == "black" && lib.filter.cardDiscardable(card, player); }, - ai1:function(card){ - if(ui.selected.cards.length>=enemy) return 0; - return 9-get.value(card); + ai1: function (card) { + if (ui.selected.cards.length >= enemy) return 0; + return 9 - get.value(card); }, - ai2:function(target){ - return get.damageEffect(target,player,player); + ai2: function (target) { + return get.damageEffect(target, player, player); }, - prompt:get.prompt('ningxian') + prompt: get.prompt("ningxian"), }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - player.logSkill('ningxian',result.targets); - event.targets=result.targets; + player.logSkill("ningxian", result.targets); + event.targets = result.targets; event.targets.sort(lib.sort.seat); - } - else{ + } else { event.finish(); } - "step 2" - if(event.targets.length){ + "step 2"; + if (event.targets.length) { event.targets.shift().damage(); event.redo(); } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-0.5]; - if(!target.hasFriend()){ - if(get.mode()=='guozhan'){ - if(!player.hasFriend()) return; - } - else{ + ai: { + maixie: true, + maixie_hp: true, + effect: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -0.5]; + if (!target.hasFriend()) { + if (get.mode() == "guozhan") { + if (!player.hasFriend()) return; + } else { return; } } - if(target.countCards('h')>2||target.countCards('e',{color:'black'})){ - return [1,0,0,-1]; + if (target.countCards("h") > 2 || target.countCards("e", { color: "black" })) { + return [1, 0, 0, -1]; } - return [1,-0.5]; + return [1, -0.5]; } }, - } + }, }, - xuanyuan:{ - trigger:{player:'phaseEnd'}, - unique:true, - forceunique:true, - direct:true, - filter:function(event,player){ - if(!player.countCards('he',{suit:'spade'})) return false; - for(var i=0;i=4) return [1,1.5]; - if(target.hp==3) return [1,1]; - if(target.hp==2) return [1,0.5]; + group: "pozhou2", + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + if (player.hp >= 4) return [1, 1.5]; + if (target.hp == 3) return [1, 1]; + if (target.hp == 2) return [1, 0.5]; } - } - } - } + }, + }, + }, }, - pozhou2:{ - enable:'phaseUse', - filter:function(event,player){ - return player.storage.pozhou>0; + pozhou2: { + enable: "phaseUse", + filter: function (event, player) { + return player.storage.pozhou > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('fengyin'); + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("fengyin"); }, - selectTarget:function(){ - return [1,_status.event.player.storage.pozhou]; + selectTarget: function () { + return [1, _status.event.player.storage.pozhou]; }, - prompt:'出牌阶段,你可以指定任意名其他角色并弃置等量的破咒标记,令目标的非锁定技失效直到其下一回合结束', - content:function(){ + prompt: "出牌阶段,你可以指定任意名其他角色并弃置等量的破咒标记,令目标的非锁定技失效直到其下一回合结束", + content: function () { player.storage.pozhou--; - if(!player.storage.pozhou){ - player.unmarkSkill('pozhou'); - } - else{ + if (!player.storage.pozhou) { + player.unmarkSkill("pozhou"); + } else { player.updateMarks(); } - target.addTempSkill('fengyin',{player:'phaseAfter'}); + target.addTempSkill("fengyin", { player: "phaseAfter" }); }, - ai:{ - order:11, - result:{ - target:function(player,target){ - var skills=target.getSkills(); - for(var i=0;i0&&player!=event.player; + filter: function (event, player) { + return player.storage.pozhou > 0 && player != event.player; }, - prompt:function(event,player){ - return '###是否弃置一枚破咒标记令'+get.translation(event.player)+ - '的非锁定技失效?###(剩余'+player.storage.pozhou+'枚)'; + prompt: function (event, player) { + return ( + "###是否弃置一枚破咒标记令" + + get.translation(event.player) + + "的非锁定技失效?###(剩余" + + player.storage.pozhou + + "枚)" + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { player.storage.pozhou--; - if(!player.storage.pozhou){ - player.unmarkSkill('pozhou'); - } - else{ + if (!player.storage.pozhou) { + player.unmarkSkill("pozhou"); + } else { player.updateMarks(); } - trigger.player.addTempSkill('fengyin',{player:'phaseBegin'}); - } + trigger.player.addTempSkill("fengyin", { player: "phaseBegin" }); + }, }, - fengmo:{ - enable:'phaseUse', - usable:1, - filter:function(){ - return game.countPlayer(function(current){ - return current.getEquip(1); - })>=1; + fengmo: { + enable: "phaseUse", + usable: 1, + filter: function () { + return ( + game.countPlayer(function (current) { + return current.getEquip(1); + }) >= 1 + ); }, - filterTarget:function(card,player,target){ - return player!=target&&!target.isTurnedOver(); + filterTarget: function (card, player, target) { + return player != target && !target.isTurnedOver(); }, - content:function(){ - "step 0" - event.targets=[]; - event.num=0; - var players=game.filterPlayer(); - for(var i=0;i1){ - return 12-get.equipValue(card); + duanyue: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: { type: "equip" }, + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 12 - get.equipValue(card); } - return 8-get.equipValue(card); + return 8 - get.equipValue(card); }, - filter:function(event,player){ - return player.countCards('he',{type:'equip'}); + filter: function (event, player) { + return player.countCards("he", { type: "equip" }); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - content:function(){ + content: function () { target.damage(); }, - ai:{ - order:9.5, - expose:0.2, - result:{ - player:function(player,target){ - return get.damageEffect(target,player,player); - } - } - } + ai: { + order: 9.5, + expose: 0.2, + result: { + player: function (player, target) { + return get.damageEffect(target, player, player); + }, + }, + }, }, - tuzhen:{ - trigger:{source:'damageAfter'}, - filter:function(event,player){ - return event.player.isIn()&&event.player!=player&&event.player.hasCard(function(card){ - return get.type(card)!='basic'; - }); + tuzhen: { + trigger: { source: "damageAfter" }, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player != player && + event.player.hasCard(function (card) { + return get.type(card) != "basic"; + }) + ); }, // alter:true, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)<0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - content:function(){ - var hs=trigger.player.getCards('h',function(card){ - return get.type(card)!='basic'; + content: function () { + var hs = trigger.player.getCards("h", function (card) { + return get.type(card) != "basic"; }); - if(get.is.altered('tuzhen')){ - hs=hs.randomGet(); + if (get.is.altered("tuzhen")) { + hs = hs.randomGet(); } trigger.player.discard(hs); - } - }, - mojian:{ - trigger:{player:'shaBegin'}, - check:function(event,player){ - if(get.attitude(player,event.target)>0) return true; - return player.hp 0) return true; + return player.hp < player.maxHp; + }, + logTarget: "target", + content: function () { + "step 0"; trigger.target.draw(); - "step 1" + "step 1"; player.recover(); - } - }, - swdliuhong:{ - trigger:{player:['useCard']}, - frequent:true, - filter:function(event){ - return event.card&&event.card.name=='sha'; }, - content:function(){ - player.draw(); - } }, - poyue:{ - mod:{ - targetInRange:function(card,player){ - if(card.name=='sha'&&get.color(card)=='black') return true; + swdliuhong: { + trigger: { player: ["useCard"] }, + frequent: true, + filter: function (event) { + return event.card && event.card.name == "sha"; + }, + content: function () { + player.draw(); + }, + }, + poyue: { + mod: { + targetInRange: function (card, player) { + if (card.name == "sha" && get.color(card) == "black") return true; + }, + cardUsable: function (card) { + if (get.is.altered("poyue")) return; + if (card.name == "sha" && get.color(card) == "red") return Infinity; }, - cardUsable:function(card){ - if(get.is.altered('poyue')) return; - if(card.name=='sha'&&get.color(card)=='red') return Infinity; - } }, // alter:true, - trigger:{player:'useCard'}, - filter:function(event,player){ - if(get.is.altered('poyue')) return false; - return event.card.name=='sha'&&get.color(event.card)=='red'; + trigger: { player: "useCard" }, + filter: function (event, player) { + if (get.is.altered("poyue")) return false; + return event.card.name == "sha" && get.color(event.card) == "red"; }, - forced:true, - content:function(){ - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + forced: true, + content: function () { + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, - group:'poyue2' + group: "poyue2", }, - poyue2:{ - trigger:{player:'shaBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&get.color(event.card)=='red'; + poyue2: { + trigger: { player: "shaBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card && get.color(event.card) == "red"; + }, + content: function () { + trigger.directHit = true; }, - content:function(){ - trigger.directHit=true; - } }, - jianji:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0&&lib.filter.cardEnabled({name:'sha'},player); + jianji: { + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countCards("he", { type: "equip" }) > 0 && + lib.filter.cardEnabled({ name: "sha" }, player) + ); }, - usable:1, - filterCard:{type:'equip'}, - position:'he', - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); + usable: 1, + filterCard: { type: "equip" }, + position: "he", + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - return 6-get.equipValue(card); + return 6 - get.equipValue(card); }, - discard:false, - prepare:'throw', - delay:false, - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); + discard: false, + prepare: "throw", + delay: false, + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); }, - content:function(){ - "step 0" - player.addAdditionalSkill('jianji','unequip'); + content: function () { + "step 0"; + player.addAdditionalSkill("jianji", "unequip"); player.draw(); - player.useCard({name:'sha'},cards,targets,false).animate=false; - player.line(targets,'fire'); - "step 1" - player.removeAdditionalSkill('jianji'); + player.useCard({ name: "sha" }, cards, targets, false).animate = false; + player.line(targets, "fire"); + "step 1"; + player.removeAdditionalSkill("jianji"); }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.1; }, - result:{ - target:function(player,target){ - player.addAdditionalSkill('jianji_ai','unequip'); - var eff=get.effect(target,{name:'sha'},player,target); - player.removeAdditionalSkill('jianji_ai'); + result: { + target: function (player, target) { + player.addAdditionalSkill("jianji_ai", "unequip"); + var eff = get.effect(target, { name: "sha" }, player, target); + player.removeAdditionalSkill("jianji_ai"); return eff; - } + }, }, - effect:{ - player:function(card,player){ - if(_status.currentPhase!=player) return; - if(get.type(card)=='equip'&& - player.countCards('e',{subtype:get.subtype(card)})&& - lib.filter.filterCard({name:'sha'},player)){ + effect: { + player: function (card, player) { + if (_status.currentPhase != player) return; + if ( + get.type(card) == "equip" && + player.countCards("e", { subtype: get.subtype(card) }) && + lib.filter.filterCard({ name: "sha" }, player) + ) { return 0; } - } + }, }, - threaten:1.3 - } - }, - huangyu:{ - enable:'phaseUse', - filter:function(event,player){ - if(!lib.card.chiyuxi) return false; - return !player.getStat('skill').huangyu&&player.countCards('he',{color:'red'})>1; + threaten: 1.3, }, - filterCard:{color:'red'}, - selectCard:2, - position:'he', - viewAs:{name:'chiyuxi',nature:'fire'}, - check:function(card){ - var player=_status.event.player; - if(player.hasSkill('jianji')&&get.type(card)=='equip'&& - lib.filter.filterCard({name:'sha'},player)){ + }, + huangyu: { + enable: "phaseUse", + filter: function (event, player) { + if (!lib.card.chiyuxi) return false; + return !player.getStat("skill").huangyu && player.countCards("he", { color: "red" }) > 1; + }, + filterCard: { color: "red" }, + selectCard: 2, + position: "he", + viewAs: { name: "chiyuxi", nature: "fire" }, + check: function (card) { + var player = _status.event.player; + if ( + player.hasSkill("jianji") && + get.type(card) == "equip" && + lib.filter.filterCard({ name: "sha" }, player) + ) { return 0; } - return 6-get.value(card) + return 6 - get.value(card); + }, + ai: { + order: 8, + expose: 0.2, + threaten: 1.2, }, - ai:{ - order:8, - expose:0.2, - threaten:1.2 - } }, - gongshen:{ - trigger:{global:'useCard'}, - priority:15, - filter:function(event,player){ - var type=get.type(event.card,'trick'); - if(type!='basic'&&type!='trick') return false; - return event.player!=player&&player.countCards('he',{type:'equip'})>0&& - event.targets&&event.targets.length>0; + gongshen: { + trigger: { global: "useCard" }, + priority: 15, + filter: function (event, player) { + var type = get.type(event.card, "trick"); + if (type != "basic" && type != "trick") return false; + return ( + event.player != player && + player.countCards("he", { type: "equip" }) > 0 && + event.targets && + event.targets.length > 0 + ); }, - direct:true, - content:function(){ - "step 0" - var effect=0; - for(var i=0;i=7&&get.type(trigger.card)=='trick') return val; - if(nme=='tao') return val; - if(nme=='wuzhong') return val; - if(nme=='zengbin') return val; - if(nme=='wangmeizhike') return val; - if(nme=='shunshou'&&player==trigger.targets[0]) return val; - if(nme=='guohe'&&player==trigger.targets[0]) return val; - if(nme=='liuxinghuoyu') return val; - if(nme=='nanman') return val; - if(nme=='wanjian') return val; - if(nme=='jingleishan') return val; - if(nme=='chiyuxi') return val; - if((nme=='juedou')&&(player==trigger.targets[0]||trigger.targets[0].hp==1)) return val; - if(nme=='chenhuodajie') return val; - if(nme=='lebu'&&trigger.targets[0].countCards('h')>trigger.targets[0].hp) return val; - if(nme=='sha'&&trigger.targets[0].hp==1&&!trigger.targets[0].hasShan()) return val; - if(nme=='jiedao'&&trigger.targets[0]==player) return val; - if(nme=='yihuajiemu'&&trigger.targets[0]==player) return val; - if(nme=='shuiyanqijun'&&trigger.targets.includes(player)) return val; + str += "的" + get.translation(trigger.card) + "失效"; + var next = player.chooseToDiscard("he", { type: "equip" }, get.prompt("gongshen")); + next.prompt2 = str; + next.logSkill = ["gongshen", trigger.player]; + next.autodelay = true; + next.ai = function (card) { + if (effect < 0) { + var val = 9 - get.value(card); + var nme = trigger.card.name; + if (get.value(trigger.card) >= 7 && get.type(trigger.card) == "trick") return val; + if (nme == "tao") return val; + if (nme == "wuzhong") return val; + if (nme == "zengbin") return val; + if (nme == "wangmeizhike") return val; + if (nme == "shunshou" && player == trigger.targets[0]) return val; + if (nme == "guohe" && player == trigger.targets[0]) return val; + if (nme == "liuxinghuoyu") return val; + if (nme == "nanman") return val; + if (nme == "wanjian") return val; + if (nme == "jingleishan") return val; + if (nme == "chiyuxi") return val; + if ( + nme == "juedou" && + (player == trigger.targets[0] || trigger.targets[0].hp == 1) + ) + return val; + if (nme == "chenhuodajie") return val; + if (nme == "lebu" && trigger.targets[0].countCards("h") > trigger.targets[0].hp) + return val; + if (nme == "sha" && trigger.targets[0].hp == 1 && !trigger.targets[0].hasShan()) + return val; + if (nme == "jiedao" && trigger.targets[0] == player) return val; + if (nme == "yihuajiemu" && trigger.targets[0] == player) return val; + if (nme == "shuiyanqijun" && trigger.targets.includes(player)) return val; return 0; } return -1; - } - "step 1" - if(result.bool){ + }; + "step 1"; + if (result.bool) { // game.delay(2); trigger.cancel(); } }, - ai:{ - effect:{ - player:function(card,player,target){ - if(player!=target) return; - if(get.type(card)=='equip'&&!player.needsToDiscard()){ - return [0,0,0,0]; + ai: { + effect: { + player: function (card, player, target) { + if (player != target) return; + if (get.type(card) == "equip" && !player.needsToDiscard()) { + return [0, 0, 0, 0]; } - } + }, }, - threaten:2, - expose:0.3 - } - }, - xiaozhan:{ - trigger:{global:'useCard'}, - priority:15, - filter:function(event,player){ - return event.card.name=='sha'&&event.player!=player&& - player.countCards('h','sha')>0&&event.targets.includes(player)==false; + threaten: 2, + expose: 0.3, }, - direct:true, - content:function(){ - "step 0" - var effect=0; - for(var i=0;i 0 && + event.targets.includes(player) == false + ); + }, + direct: true, + content: function () { + "step 0"; + var effect = 0; + for (var i = 0; i < trigger.targets.length; i++) { + effect += get.effect(trigger.targets[i], trigger.card, trigger.player, player); } - var str='是否弃置一张杀令'+get.translation(trigger.player); - if(trigger.targets&&trigger.targets.length){ - str+='对'+get.translation(trigger.targets); + var str = "是否弃置一张杀令" + get.translation(trigger.player); + if (trigger.targets && trigger.targets.length) { + str += "对" + get.translation(trigger.targets); } - str+='的'+get.translation(trigger.card)+'失效?' - player.chooseToDiscard('h',{name:'sha'},str).ai=function(card){ - if(effect<0){ - return 9-get.value(card); + str += "的" + get.translation(trigger.card) + "失效?"; + player.chooseToDiscard("h", { name: "sha" }, str).ai = function (card) { + if (effect < 0) { + return 9 - get.value(card); } return -1; - } - "step 1" - if(result.bool){ + }; + "step 1"; + if (result.bool) { trigger.cancel(); - player.logSkill('xiaozhan'); + player.logSkill("xiaozhan"); } }, - ai:{ - threaten:1.2, - expose:0.1 - } + ai: { + threaten: 1.2, + expose: 0.1, + }, }, - chuanyue:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + chuanyue: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - selectCard:2, - filterCard:true, - discard:false, - prepare:'throw', - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'juedou'},player,target); + selectCard: 2, + filterCard: true, + discard: false, + prepare: "throw", + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "juedou" }, player, target); }, - check:function(card){ - return Math.max(7-get.value(card),7-get.useful(card)); + check: function (card) { + return Math.max(7 - get.value(card), 7 - get.useful(card)); }, - content:function(){ - player.useCard({name:'juedou'},targets,cards).animate=false; + content: function () { + player.useCard({ name: "juedou" }, targets, cards).animate = false; }, - ai:{ - result:{ - target:function(player,target){ - return get.effect(target,{name:'juedou'},player,target); - } + ai: { + result: { + target: function (player, target) { + return get.effect(target, { name: "juedou" }, player, target); + }, }, - order:8, - } - }, - dangping:{ - trigger:{source:'damageAfter'}, - direct:true, - filter:function(event,player){ - return event.parent.name!='dangping'&&!player.hasSkill('dangping2')&&player.countCards('he')>0; + order: 8, }, - content:function(){ - "step 0" - var next=player.chooseCardTarget({ - position:'he', - filterTarget:function(card,player,target){ - return player!=target&&trigger.player!=target&&get.distance(trigger.player,target)<=1; + }, + dangping: { + trigger: { source: "damageAfter" }, + direct: true, + filter: function (event, player) { + return ( + event.parent.name != "dangping" && + !player.hasSkill("dangping2") && + player.countCards("he") > 0 + ); + }, + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + position: "he", + filterTarget: function (card, player, target) { + return ( + player != target && + trigger.player != target && + get.distance(trigger.player, target) <= 1 + ); }, - filterCard:lib.filter.cardDiscardable, - ai1:function(card){ - return get.unuseful(card)+9; + filterCard: lib.filter.cardDiscardable, + ai1: function (card) { + return get.unuseful(card) + 9; }, - ai2:function(target){ - return get.damageEffect(target,player,player); + ai2: function (target) { + return get.damageEffect(target, player, player); }, - prompt:get.prompt('dangping') + prompt: get.prompt("dangping"), }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.discard(result.cards); - player.logSkill('dangping',result.targets); - player.addTempSkill('dangping2'); + player.logSkill("dangping", result.targets); + player.addTempSkill("dangping2"); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { result.targets[0].damage(); } - } + }, }, - dangping2:{}, - duishi:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkill('duishi2'); + dangping2: {}, + duishi: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h") > 0 && !player.hasSkill("duishi2"); }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h')>0&&!target.hasSkill('duishi3'); + filterTarget: function (card, player, target) { + return player != target && target.countCards("h") > 0 && !target.hasSkill("duishi3"); }, - filterCard:true, - check:function(card){return 8-get.value(card)}, - content:function(){ - "step 0" - var suit=get.suit(cards[0]); - target.chooseToDiscard({suit:suit},'h','对诗:弃置一张'+get.translation(suit)+ - '牌,或令'+get.translation(player)+'获得你一张牌').ai=function(card){ - if(get.attitude(target,player)>0) return 0; - return 9-get.value(card); - } - "step 1" - if(result.bool){ - target.addTempSkill('duishi3'); - } - else{ - player.gainPlayerCard(target,'he',true); - player.addTempSkill('duishi2'); + filterCard: true, + check: function (card) { + return 8 - get.value(card); + }, + content: function () { + "step 0"; + var suit = get.suit(cards[0]); + target.chooseToDiscard( + { suit: suit }, + "h", + "对诗:弃置一张" + + get.translation(suit) + + "牌,或令" + + get.translation(player) + + "获得你一张牌" + ).ai = function (card) { + if (get.attitude(target, player) > 0) return 0; + return 9 - get.value(card); + }; + "step 1"; + if (result.bool) { + target.addTempSkill("duishi3"); + } else { + player.gainPlayerCard(target, "he", true); + player.addTempSkill("duishi2"); } }, - ai:{ - order:9, - threaten:1.5, - result:{ - target:-2, - player:0.5 + ai: { + order: 9, + threaten: 1.5, + result: { + target: -2, + player: 0.5, }, - expose:0.2 - } - }, - duishi2:{}, - duishi3:{}, - guisi:{ - trigger:{target:'shaBefore'}, - popup:false, - direct:true, - filter:function(event,player){ - return player.countCards('h'); + expose: 0.2, }, - content:function(){ - "step 0" - player.chooseCard('是否交给'+get.translation(trigger.player)+'一张牌并取消此杀?').ai=function(card){ - if(get.attitude(player,trigger.player)>0){ - return 9-get.value(card); + }, + duishi2: {}, + duishi3: {}, + guisi: { + trigger: { target: "shaBefore" }, + popup: false, + direct: true, + filter: function (event, player) { + return player.countCards("h"); + }, + content: function () { + "step 0"; + player.chooseCard( + "是否交给" + get.translation(trigger.player) + "一张牌并取消此杀?" + ).ai = function (card) { + if (get.attitude(player, trigger.player) > 0) { + return 9 - get.value(card); } - if(player.countCards('h',{name:'shan'})) return -1; - return 7-get.value(card); - } - "step 1" - if(result.bool){ - player.logSkill('guisi'); - trigger.player.gain(result.cards,player); - player.$give(result.cards,trigger.player); + if (player.countCards("h", { name: "shan" })) return -1; + return 7 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.logSkill("guisi"); + trigger.player.gain(result.cards, player); + player.$give(result.cards, trigger.player); trigger.cancel(); } }, }, - lianwu:{ - mod:{ - selectTarget:function(card,player,range){ - if(card.name=='sha'&&range[1]!=-1) range[1]++; + lianwu: { + mod: { + selectTarget: function (card, player, range) { + if (card.name == "sha" && range[1] != -1) range[1]++; }, }, - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return event.card&&get.color(event.card)=='red'; + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return event.card && get.color(event.card) == "red"; + }, + content: function () { + trigger.directHit = true; }, - content:function(){ - trigger.directHit=true; - } }, - mingfu:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',{suit:'club'})>0; + mingfu: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { suit: "club" }) > 0; }, - position:'he', - filterCard:{suit:'club'}, - discard:false, - prepare:'throw', - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'guiyoujie'},player,target); + position: "he", + filterCard: { suit: "club" }, + discard: false, + prepare: "throw", + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "guiyoujie" }, player, target); }, - check:function(card){ - if(card.name=='du') return 20; - return Math.max(7-get.value(card),7-get.useful(card)); + check: function (card) { + if (card.name == "du") return 20; + return Math.max(7 - get.value(card), 7 - get.useful(card)); }, - content:function(){ - target.addJudge('guiyoujie',cards); + content: function () { + target.addJudge("guiyoujie", cards); }, - ai:{ - result:{ - target:function(player,target){ - return get.effect(target,{name:'guiyoujie'},player,target); - } - }, - order:8, - } - }, - mufeng_old:{ - init:function(player){ - player.storage.mufeng=0; - }, - group:['mufeng_gain','mufeng_lose'], - mark:true, - intro:{ - content:function(storage){ - if(storage>0){ - return '防御距离+'+storage; - } - else if(storage<0){ - return '防御距离'+storage; - } - else{ - return '无距离变化'; - } - } - }, - subSkill:{ - lose:{ - trigger:{global:'dieAfter'}, - forced:true, - filter:function(event,player){ - return player.storage.mufeng>game.players.length/2; + ai: { + result: { + target: function (player, target) { + return get.effect(target, { name: "guiyoujie" }, player, target); }, - content:function(){ - player.storage.mufeng=0; + }, + order: 8, + }, + }, + mufeng_old: { + init: function (player) { + player.storage.mufeng = 0; + }, + group: ["mufeng_gain", "mufeng_lose"], + mark: true, + intro: { + content: function (storage) { + if (storage > 0) { + return "防御距离+" + storage; + } else if (storage < 0) { + return "防御距离" + storage; + } else { + return "无距离变化"; + } + }, + }, + subSkill: { + lose: { + trigger: { global: "dieAfter" }, + forced: true, + filter: function (event, player) { + return player.storage.mufeng > game.players.length / 2; + }, + content: function () { + player.storage.mufeng = 0; player.updateMarks(); - } - }, - gain:{ - trigger:{player:'loseEnd'}, - forced:true, - filter:function(event,player){ - return _status.currentPhase!=player; }, - content:function(){ + }, + gain: { + trigger: { player: "loseEnd" }, + forced: true, + filter: function (event, player) { + return _status.currentPhase != player; + }, + content: function () { player.storage.mufeng++; - if(player.storage.mufeng>game.players.length/2){ - player.storage.mufeng=0; + if (player.storage.mufeng > game.players.length / 2) { + player.storage.mufeng = 0; } player.updateMarks(); + }, + }, + }, + mod: { + globalTo: function (from, to, distance) { + if (typeof to.storage.mufeng == "number") { + return distance + to.storage.mufeng; } }, }, - mod:{ - globalTo:function(from,to,distance){ - if(typeof to.storage.mufeng=='number'){ - return distance+to.storage.mufeng; - } - } - } }, - mufeng:{ - trigger:{player:'phaseEnd'}, - frequent:true, - filter:function(event,player){ - return player.hasSkill('mufeng_used'); + mufeng: { + trigger: { player: "phaseEnd" }, + frequent: true, + filter: function (event, player) { + return player.hasSkill("mufeng_used"); }, - content:function(){ + content: function () { player.discoverCard(); }, - subSkill:{ - used:{}, - count:{ - trigger:{player:'useCard'}, - silent:true, - filter:function(event,player){ - return _status.currentPhase==player&&get.type(event.card)=='basic'; + subSkill: { + used: {}, + count: { + trigger: { player: "useCard" }, + silent: true, + filter: function (event, player) { + return _status.currentPhase == player && get.type(event.card) == "basic"; }, - content:function(){ - player.addTempSkill('mufeng_used'); - } - } + content: function () { + player.addTempSkill("mufeng_used"); + }, + }, }, - group:'mufeng_count' + group: "mufeng_count", }, - mufeng_old2:{ - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - return !player.hasSkill('mufeng2')&&event.player!=player&& - Math.min(5,event.player.countCards('h'))>player.countCards('h'); + mufeng_old2: { + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return ( + !player.hasSkill("mufeng2") && + event.player != player && + Math.min(5, event.player.countCards("h")) > player.countCards("h") + ); }, - content:function(){ - player.draw(Math.min(5,trigger.player.countCards('h'))-player.countCards('h')); - player.addTempSkill('mufeng2',{player:'phaseBegin'}); + content: function () { + player.draw(Math.min(5, trigger.player.countCards("h")) - player.countCards("h")); + player.addTempSkill("mufeng2", { player: "phaseBegin" }); }, }, - mufeng2:{}, - jiying:{ - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; - } + mufeng2: {}, + jiying: { + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; + }, }, }, - minjing:{ - trigger:{player:'damageBegin'}, - forced:true, - filter:function(event,player){ - if(player.getEquip(2)) return false; - return lib.skill.guangshatianyi.filter(event,player); + minjing: { + trigger: { player: "damageBegin" }, + forced: true, + filter: function (event, player) { + if (player.getEquip(2)) return false; + return lib.skill.guangshatianyi.filter(event, player); }, - content:function(){ + content: function () { trigger.num--; }, - ai:{ - threaten:0.8 - } + ai: { + threaten: 0.8, + }, }, - touxi:{ - trigger:{global:'phaseEnd'}, - check:function(event,player){ - if(get.damageEffect(event.player,player,player,'thunder')>0){ - if(get.is.altered('touxi')&&get.attitude(player,event.player)<0&&player.countCards('he')){ - if(event.player.hp==1&&player.hp>1){ + touxi: { + trigger: { global: "phaseEnd" }, + check: function (event, player) { + if (get.damageEffect(event.player, player, player, "thunder") > 0) { + if ( + get.is.altered("touxi") && + get.attitude(player, event.player) < 0 && + player.countCards("he") + ) { + if (event.player.hp == 1 && player.hp > 1) { return true; } - } - else{ + } else { return true; } } return false; }, // alter:true, - filter:function(event,player){ - return event.player!=player&&!player.hasSkill('touxi2')&&event.player.isAlive(); + filter: function (event, player) { + return event.player != player && !player.hasSkill("touxi2") && event.player.isAlive(); }, - logTarget:'player', - content:function(){ - "step 0" - player.judge(function(card){ - if(get.color(card)=='black') return 1; + logTarget: "player", + content: function () { + "step 0"; + player.judge(function (card) { + if (get.color(card) == "black") return 1; return -1; }); - "step 1" - if(result.bool){ - trigger.player.damage('thunder'); - player.addSkill('touxi2'); + "step 1"; + if (result.bool) { + trigger.player.damage("thunder"); + player.addSkill("touxi2"); event.finish(); - } - else{ - if(player.countCards('he')){ - var att=get.attitude(trigger.player,player); - trigger.player[get.is.altered('touxi')?'gainPlayerCard':'discardPlayerCard'](player,'he',function(button){ - if(att>0) return 0; - return get.buttonValue(button); - }); + } else { + if (player.countCards("he")) { + var att = get.attitude(trigger.player, player); + trigger.player[get.is.altered("touxi") ? "gainPlayerCard" : "discardPlayerCard"]( + player, + "he", + function (button) { + if (att > 0) return 0; + return get.buttonValue(button); + } + ); } } }, - ai:{ - expose:0.3, - threaten:1.2 - } + ai: { + expose: 0.3, + threaten: 1.2, + }, }, - touxi2:{ - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('touxi2'); - } + touxi2: { + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("touxi2"); + }, }, - nlianji:{ - audio:'lianji', - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(!ui.selected.targets.length) return target.countCards('h')>0; + nlianji: { + audio: "lianji", + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + if (player == target) return false; + if (!ui.selected.targets.length) return target.countCards("h") > 0; return ui.selected.targets[0].canCompare(target); }, - selectTarget:2, - multitarget:true, - multiline:true, - filter:function(event,player){ - return player.countCards('h')>0; + selectTarget: 2, + multitarget: true, + multiline: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - prepare:'throw', - discard:false, - filterCard:true, - check:function(card){ - return 6-get.value(card); + prepare: "throw", + discard: false, + filterCard: true, + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - "step 0" - if(targets[0].canCompare(targets[1])){ + content: function () { + "step 0"; + if (targets[0].canCompare(targets[1])) { targets[0].chooseToCompare(targets[1]); - } - else{ + } else { event.finish(); } - "step 1" - if(result.bool){ - targets[0].gain(cards,'log'); + "step 1"; + if (result.bool) { + targets[0].gain(cards, "log"); targets[0].$gain2(cards); targets[1].damage(targets[0]); - } - else if(!result.tie){ - targets[1].gain(cards,'log'); + } else if (!result.tie) { + targets[1].gain(cards, "log"); targets[1].$gain2(cards); targets[0].damage(targets[1]); } }, - ai:{ - expose:0.3, - threaten:2, - order:9, - result:{ - target:-1 - } + ai: { + expose: 0.3, + threaten: 2, + order: 9, + result: { + target: -1, + }, }, }, - lianji2:{ - group:['lianji3','lianji4'] + lianji2: { + group: ["lianji3", "lianji4"], }, - lianji3:{ - trigger:{player:'shaHit'}, - forced:true, - popup:false, - content:function(){ - player.storage.lianji2=true; - } + lianji3: { + trigger: { player: "shaHit" }, + forced: true, + popup: false, + content: function () { + player.storage.lianji2 = true; + }, }, - lianji4:{ - trigger:{player:'shaAfter'}, - forced:true, - popup:false, - content:function(){ - if(!player.storage.lianji2){ - player.damage('thunder',player.storage.lianji); + lianji4: { + trigger: { player: "shaAfter" }, + forced: true, + popup: false, + content: function () { + if (!player.storage.lianji2) { + player.damage("thunder", player.storage.lianji); } delete player.storage.lianji; delete player.storage.lianji2; - player.removeSkill('lianji2'); - } - }, - yinmo:{}, - miedao:{ - group:['miedao1','miedao2'], - ai:{ - threaten:1.4 - } - }, - miedao1:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ - return player.hp=player.maxHp-1) return [0,0]; - } - } - } + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, + }, + }, }, - moyan:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hp0; + moyan: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hp < player.maxHp && player.countCards("h", { color: "red" }) > 0; }, - filterTarget:function(card,player,target){ - return player!=target;//&&get.distance(player,target,'attack')<=1; + filterTarget: function (card, player, target) { + return player != target; //&&get.distance(player,target,'attack')<=1; }, - selectTarget:function(){ + selectTarget: function () { return ui.selected.cards.length; }, - selectCard:function(){ - var player=_status.currentPhase; - return [1,Math.min(game.players.length-1,player.maxHp-player.hp)]; + selectCard: function () { + var player = _status.currentPhase; + return [1, Math.min(game.players.length - 1, player.maxHp - player.hp)]; }, - filterCard:function(card){ - return get.color(card)=='red'; + filterCard: function (card) { + return get.color(card) == "red"; }, - check:function(card){ - if(ui.selected.cards.length==0){ - return 8-get.value(card); + check: function (card) { + if (ui.selected.cards.length == 0) { + return 8 - get.value(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - line:'fire', - content:function(){ - "step 0" - target.damage('fire'); - "step 1" + line: "fire", + content: function () { + "step 0"; + target.damage("fire"); + "step 1"; // target.draw(); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'fire'); - } + ai: { + order: 9, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "fire"); + }, }, - threaten:function(player,target){ - if(target.hp==1) return 2; - if(target.hp==2) return 1.5; + threaten: function (player, target) { + if (target.hp == 1) return 2; + if (target.hp == 2) return 1.5; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(target.hp==target.maxHp) return [0,1]; + maixie: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (target.hp == target.maxHp) return [0, 1]; } - if(get.tag(card,'recover')&&player.hp>=player.maxHp-1) return [0,0]; - } - } - } - }, - shejie:{ - trigger:{player:'damageEnd'}, - priority:9, - check:function(event,player){ - return get.attitude(player,event.source)<0; - }, - filter:function(event){ - return event&&event.source; - }, - content:function(){ - trigger.source.addSkill('shejie2'); - }, - ai:{ - threaten:0.4 - } - }, - shejie2:{ - unique:true, - trigger:{player:'phaseBegin'}, - forced:true, - priority:10, - mod:{ - cardEnabled:function(){ - return false; + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, }, - cardUsable:function(){ - return false; - }, - cardRespondable:function(){ - return false; - }, - cardSavable:function(){ - return false; - } - }, - content:function(){ - player.removeSkill('shejie2') }, }, - guiyin:{ - trigger:{player:'phaseDiscardEnd'}, - frequent:true, - filter:function(event,player){ - return event.cards&&event.cards.length>1 + shejie: { + trigger: { player: "damageEnd" }, + priority: 9, + check: function (event, player) { + return get.attitude(player, event.source) < 0; }, - content:function(){ + filter: function (event) { + return event && event.source; + }, + content: function () { + trigger.source.addSkill("shejie2"); + }, + ai: { + threaten: 0.4, + }, + }, + shejie2: { + unique: true, + trigger: { player: "phaseBegin" }, + forced: true, + priority: 10, + mod: { + cardEnabled: function () { + return false; + }, + cardUsable: function () { + return false; + }, + cardRespondable: function () { + return false; + }, + cardSavable: function () { + return false; + }, + }, + content: function () { + player.removeSkill("shejie2"); + }, + }, + guiyin: { + trigger: { player: "phaseDiscardEnd" }, + frequent: true, + filter: function (event, player) { + return event.cards && event.cards.length > 1; + }, + content: function () { player.draw(2); }, }, - wangchen:{ - trigger:{player:'phaseDiscardEnd'}, - direct:true, - filter:function(event,player){ - if(event.cards){ + wangchen: { + trigger: { player: "phaseDiscardEnd" }, + direct: true, + filter: function (event, player) { + if (event.cards) { // if(!get.is.altered('wangchen')) return true; - for(var i=0;i=2; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('yihua',trigger.player),2); - next.ai=function(card){ - if(get.effect(player,trigger.card)<0){ - if(card.name=='liuxinghuoyu') return 7-get.value(card); - return 5-get.value(card); + }, + yihua: { + trigger: { target: "useCardToBefore" }, + popup: false, + direct: true, + filter: function (event, player) { + if (event.addedTargets) return false; + // return event.card&&get.color(event.card)=='red'&&event.player!=player; + return event.targets.length == 1 && event.player != player && player.countCards("h") >= 2; + }, + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt("yihua", trigger.player), 2); + next.ai = function (card) { + if (get.effect(player, trigger.card) < 0) { + if (card.name == "liuxinghuoyu") return 7 - get.value(card); + return 5 - get.value(card); } return 0; }; - next.prompt2='反弹'+get.translation(trigger.player)+'的'+get.translation(trigger.card); - next.logSkill=['yihua',trigger.player]; - "step 1" - if(result.bool){ + next.prompt2 = + "反弹" + get.translation(trigger.player) + "的" + get.translation(trigger.card); + next.logSkill = ["yihua", trigger.player]; + "step 1"; + if (result.bool) { // player.discard(result.cards); - trigger.target=trigger.player; - trigger.player=player; + trigger.target = trigger.player; + trigger.player = player; trigger.untrigger(); - trigger.trigger('useCardToBefore'); + trigger.trigger("useCardToBefore"); } // "step 2" // if(result.bool){ @@ -4994,383 +5318,418 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // game.delay(); // } }, - ai:{ - threaten:function(player,target){ - if(target.countCards('h')<=2){ + ai: { + threaten: function (player, target) { + if (target.countCards("h") <= 2) { return 2; } - return 2/(target.countCards('h')-1); - } - } + return 2 / (target.countCards("h") - 1); + }, + }, }, - youyin:{ - trigger:{global:'discardAfter'}, - filter:function(event,player){ - if(event.player==player) return false; - if(player.countCards('h')>=5) return false; - for(var i=0;i= 5) return false; + for (var i = 0; i < event.cards.length; i++) { + if (get.type(event.cards[i]) != "basic") { return true; } } return false; }, - frequent:true, - content:function(){ - "step 0" - if(trigger.delay==false) game.delay(); - "step 1" + frequent: true, + content: function () { + "step 0"; + if (trigger.delay == false) game.delay(); + "step 1"; player.draw(); }, }, - anlianying:{ - trigger:{player:'loseEnd'}, - frequent:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - for(var i=0;i0; + zhanlu: { + enable: "phaseUse", + filterCard: function (card) { + var suit = get.suit(card); + return suit == "spade"; }, - check:function(card){ - return 10-get.value(card) + position: "he", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { suit: "spade" }) > 0; }, - filterTarget:function(card,player,target){ - if(target.hp>=target.maxHp) return false; + check: function (card) { + return 10 - get.value(card); + }, + filterTarget: function (card, player, target) { + if (target.hp >= target.maxHp) return false; return true; }, - selectTarget:[1,3], - content:function(){ + selectTarget: [1, 3], + content: function () { target.recover(); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(player==target&&player.countCards('h')>player.hp) return 20; - return get.recoverEffect(target,player,target); - } + ai: { + order: 10, + result: { + target: function (player, target) { + if (player == target && player.countCards("h") > player.hp) return 20; + return get.recoverEffect(target, player, target); + }, }, - threaten:2 - } + threaten: 2, + }, }, - huopu:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:function(card){ - return get.suit(card)=='heart'; + huopu: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: function (card) { + return get.suit(card) == "heart"; }, - viewAs:{name:'liuxinghuoyu'}, - viewAsFilter:function(player){ - if(!player.countCards('he',{suit:'heart'})) return false; + viewAs: { name: "liuxinghuoyu" }, + viewAsFilter: function (player) { + if (!player.countCards("he", { suit: "heart" })) return false; + }, + prompt: "将一张红桃手牌当作流星火羽使用", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + threaten: 1.4, + order: 9, }, - prompt:'将一张红桃手牌当作流星火羽使用', - check:function(card){return 6-get.value(card)}, - ai:{ - threaten:1.4, - order:9, - } }, - rexue:{ - trigger:{global:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return lib.filter.targetEnabled({name:'sha'},player,event.player)&&player.hasSha(null,true); + rexue: { + trigger: { global: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return ( + lib.filter.targetEnabled({ name: "sha" }, player, event.player) && + player.hasSha(null, true) + ); }, - content:function(){ - var next=player.chooseToUse({name:'sha'},'热血:是否对'+get.translation(trigger.player)+'使用一张杀',trigger.player,-1); - next.logSkill='rexue'; - next.oncard=function(){ + content: function () { + var next = player.chooseToUse( + { name: "sha" }, + "热血:是否对" + get.translation(trigger.player) + "使用一张杀", + trigger.player, + -1 + ); + next.logSkill = "rexue"; + next.oncard = function () { player.draw(); - } - } + }; + }, }, - shengshou:{ - enable:'phaseUse', - filterCard:function(card){ - return get.color(card)=='black'; + shengshou: { + enable: "phaseUse", + filterCard: function (card) { + return get.color(card) == "black"; + }, + viewAs: { name: "caoyao" }, + prompt: "将一张黑色手牌当作草药使用", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + threaten: 1.6, }, - viewAs:{name:'caoyao'}, - prompt:'将一张黑色手牌当作草药使用', - check:function(card){return 6-get.value(card)}, - ai:{ - threaten:1.6 - } }, - huanjian:{ - enable:'phaseUse', - filterCard:function(card){ - return get.color(card)=='black'; + huanjian: { + enable: "phaseUse", + filterCard: function (card) { + return get.color(card) == "black"; }, - viewAs:{name:'bingpotong'}, - position:'he', - filter:function(event,player){ - return player.countCards('h',{color:'black'})>0; + viewAs: { name: "bingpotong" }, + position: "he", + filter: function (event, player) { + return player.countCards("h", { color: "black" }) > 0; }, - viewAsFilter:function(player){ - if(!player.countCards('he',{color:'black'})) return false; + viewAsFilter: function (player) { + if (!player.countCards("he", { color: "black" })) return false; + }, + prompt: "将一张黑色牌当作冰魄针使用", + check: function (card) { + return 5 - get.value(card); + }, + ai: { + threaten: 1.1, }, - prompt:'将一张黑色牌当作冰魄针使用', - check:function(card){return 5-get.value(card)}, - ai:{ - threaten:1.1 - } }, - benlei:{ - enable:'phaseUse', - viewAs:{name:'jingleishan',nature:'thunder'}, - filterCard:function(card,player){ + benlei: { + enable: "phaseUse", + viewAs: { name: "jingleishan", nature: "thunder" }, + filterCard: function (card, player) { return true; }, - selectCard:3, - position:'he', - prompt:'将三张牌当作惊雷闪使用', - check:function(card){ - return 4-get.value(card); + selectCard: 3, + position: "he", + prompt: "将三张牌当作惊雷闪使用", + check: function (card) { + return 4 - get.value(card); + }, + group: "benlei2", + ai: { + basic: { + order: 10, + }, }, - group:'benlei2', - ai:{ - basic:{ - order:10 - } - } }, - benlei2:{ - trigger:{source:'damageAfter'}, - filter:function(event,player){ - return event.hasNature('thunder')&&player.hp0; - } - else{ - return player.countCards('h')>0; + filter: function (event, player) { + if (player.hasSkill("susheng2")) return false; + if (get.is.altered("susheng")) { + return player.countCards("h", { color: "red" }) > 0; + } else { + return player.countCards("h") > 0; } }, - content:function(){ - "step 0" - var att=get.attitude(player,trigger.player); - var nh=player.countCards('h'); + content: function () { + "step 0"; + var att = get.attitude(player, trigger.player); + var nh = player.countCards("h"); var next; - if(get.is.altered('susheng')){ - next=player.chooseToDiscard(get.prompt('susheng',trigger.player),{color:'red'}); + if (get.is.altered("susheng")) { + next = player.chooseToDiscard(get.prompt("susheng", trigger.player), { + color: "red", + }); + } else { + next = player.chooseToDiscard(get.prompt("susheng", trigger.player)); } - else{ - next=player.chooseToDiscard(get.prompt('susheng',trigger.player)); - } - next.logSkill=['susheng',trigger.player]; - next.ai=function(card){ - if(att>3||(att>1&&nh>2)){ + next.logSkill = ["susheng", trigger.player]; + next.ai = function (card) { + if (att > 3 || (att > 1 && nh > 2)) { return get.unuseful2(card); } return 0; }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { // player.chooseToDiscard('h',true); trigger.cancel(); - trigger.player.hp=1; - if(trigger.player.maxHp<1) trigger.player.maxHp=1; + trigger.player.hp = 1; + if (trigger.player.maxHp < 1) trigger.player.maxHp = 1; trigger.player.update(); - player.addTempSkill('susheng2'); + player.addTempSkill("susheng2"); } }, - ai:{ - threaten:2 - } + ai: { + threaten: 2, + }, }, - susheng2:{}, - kunlunjing:{ - unique:true, + susheng2: {}, + kunlunjing: { + unique: true, // alter:true, - group:['kunlunjing1','kunlunjing2'], - video:function(player,data){ - for(var i in data){ - var current=game.playerMap[i]; - current.node.handcards1.innerHTML=''; - current.node.handcards2.innerHTML=''; - current.node.equips.innerHTML=''; - current.node.judges.innerHTML=''; + group: ["kunlunjing1", "kunlunjing2"], + video: function (player, data) { + for (var i in data) { + var current = game.playerMap[i]; + current.node.handcards1.innerHTML = ""; + current.node.handcards2.innerHTML = ""; + current.node.equips.innerHTML = ""; + current.node.judges.innerHTML = ""; current.directgain(get.infoCards(data[i].h)); - var es=get.infoCards(data[i].e); - for(var j=0;j0){ - num+=num2; - } - else if(att<0){ - num-=num2; + onremove: ["kunlunjing", "kunlunjing2"], + check: function (event, player) { + if (get.is.altered("kunlunjing")) return false; + var storage = player.storage.kunlunjing; + var num = 0; + for (var i = 0; i < storage.length; i++) { + if (game.players.includes(storage[i].player)) { + var att = get.attitude(player, storage[i].player); + var num2 = + storage[i].value - + storage[i].player.countCards("he") + + storage[i].player.countCards("j"); + if (att > 0) { + num += num2; + } else if (att < 0) { + num -= num2; } } } - return num>Math.min(2,game.players.length/2); + return num > Math.min(2, game.players.length / 2); }, - content:function(){ - "step 0" + content: function () { + "step 0"; game.delay(0.5); - "step 1" + "step 1"; game.animate.window(1); - "step 2" - var storage=event.player.storage.kunlunjing; - for(var i=0;i0 + oldliaoyuan: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return player!=target + filterTarget: function (card, player, target) { + return player != target; }, - filterCard:function(card,player){ - if(ui.selected.cards.length){ - return get.suit(card)==get.suit(ui.selected.cards[0]); + filterCard: function (card, player) { + if (ui.selected.cards.length) { + return get.suit(card) == get.suit(ui.selected.cards[0]); } - var cards=player.getCards('h'); - for(var i=0;i0 + oldliaoyuan2: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return player!=target + filterTarget: function (card, player, target) { + return player != target; }, - filterCard:function(card,player){ - if(ui.selected.cards.length){ - return get.suit(card)==get.suit(ui.selected.cards[0]); + filterCard: function (card, player) { + if (ui.selected.cards.length) { + return get.suit(card) == get.suit(ui.selected.cards[0]); } - var cards=player.getCards('h'); - for(var i=0;i0; + shehun: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; }, - filterCard:function(card){ - var suit=get.suit(card); - for(var i=0;ilength) return -1.5+eff; - return -1+eff; - } + ai: { + order: 6, + result: { + target: function (player, target) { + var eff = get.damageEffect(target, player); + var num = target.countCards("he"); + var length = ui.selected.cards.length; + if (num == length) return -2 + eff; + if (num > length) return -1.5 + eff; + return -1 + eff; + }, }, - expose:0.2 - } + expose: 0.2, + }, }, - liaoyuan:{ - trigger:{player:'shaBegin'}, - direct:true, - filter:function(event,player){ - if(get.itemtype(event.cards)!='cards') return false; - return player.countCards('he',{suit:get.suit(event.cards)})>0; + liaoyuan: { + trigger: { player: "shaBegin" }, + direct: true, + filter: function (event, player) { + if (get.itemtype(event.cards) != "cards") return false; + return player.countCards("he", { suit: get.suit(event.cards) }) > 0; }, // alter:true, - content:function(){ - "step 0" - player.storage.liaoyuan=0; - event.num=0; - event.cards=[]; - "step 1" - var suit=get.suit(trigger.cards); - event.suit=suit; - player.chooseCard('he',get.prompt('liaoyuan'),function(card,player){ - return get.suit(card)==suit&&lib.filter.cardDiscardable(card,player); - }).ai=function(card){ - if(get.attitude(player,trigger.target)>=0) return 0; - if(get.effect(trigger.target,{name:'sha'},player,player)>0){ - return 7-get.value(card); + content: function () { + "step 0"; + player.storage.liaoyuan = 0; + event.num = 0; + event.cards = []; + "step 1"; + var suit = get.suit(trigger.cards); + event.suit = suit; + player.chooseCard("he", get.prompt("liaoyuan"), function (card, player) { + return get.suit(card) == suit && lib.filter.cardDiscardable(card, player); + }).ai = function (card) { + if (get.attitude(player, trigger.target) >= 0) return 0; + if (get.effect(trigger.target, { name: "sha" }, player, player) > 0) { + return 7 - get.value(card); } return 0; - } - "step 2" - if(result.bool){ - if(event.num==0){ - player.logSkill('liaoyuan'); + }; + "step 2"; + if (result.bool) { + if (event.num == 0) { + player.logSkill("liaoyuan"); } player.discard(result.cards); event.num++; - if(player.countCards('he',{suit:event.suit})>1&&!get.is.altered('liaoyuan')){ + if ( + player.countCards("he", { suit: event.suit }) > 1 && + !get.is.altered("liaoyuan") + ) { event.goto(1); } } - "step 3" - if(event.num){ - var next=trigger.target.chooseToRespond({name:'shan'},'请打出一张闪响应燎原'); - next.ai=get.unuseful2; - if(event.num>1) next.set('prompt2','共需额外打出'+event.num+'张闪'); - } - else{ + "step 3"; + if (event.num) { + var next = trigger.target.chooseToRespond({ name: "shan" }, "请打出一张闪响应燎原"); + next.ai = get.unuseful2; + if (event.num > 1) next.set("prompt2", "共需额外打出" + event.num + "张闪"); + } else { event.finish(); } - "step 4" - if(result.bool){ + "step 4"; + if (result.bool) { event.num--; event.goto(3); - } - else{ + } else { trigger.untrigger(); - trigger.directHit=true; - player.storage.liaoyuan=event.num; + trigger.directHit = true; + player.storage.liaoyuan = event.num; } }, - group:['liaoyuan2','liaoyuan3'] + group: ["liaoyuan2", "liaoyuan3"], }, - liaoyuan2:{ - trigger:{source:'damageBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.storage.liaoyuan>0&&event.parent.name!='_lianhuan'&&event.parent.name!='_lianhuan2'; + liaoyuan2: { + trigger: { source: "damageBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + player.storage.liaoyuan > 0 && + event.parent.name != "_lianhuan" && + event.parent.name != "_lianhuan2" + ); }, - content:function(){ - trigger.num+=player.storage.liaoyuan; - player.storage.liaoyuan=0; - } - }, - liaoyuan3:{ - trigger:{player:'shaEnd'}, - silent:true, - content:function(){ - player.storage.liaoyuan=0; - } - }, - dunxing:{ - direct:true, - filter:function(event,player){ - if(event.player==player) return false; - return player.countCards('he')>0; + content: function () { + trigger.num += player.storage.liaoyuan; + player.storage.liaoyuan = 0; }, - trigger:{target:'useCardToBefore'}, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he',get.prompt(event.name)); - next.logSkill=event.name; - next.ai=function(card){ - if(get.tag(trigger.card,'multitarget')&&!get.tag(card,'multineg')) return 0; - if(get.value(trigger.card,trigger.player,'raw')<5) return 0; - if(get.tag(trigger.card,'respondSha')&&player.hasSha()) return 0; - if(get.tag(trigger.card,'respondShan')&&player.hasShan()) return 0; - if(get.effect(player,trigger.card,trigger.player,player)<0){ - return 7-get.value(card); + }, + liaoyuan3: { + trigger: { player: "shaEnd" }, + silent: true, + content: function () { + player.storage.liaoyuan = 0; + }, + }, + dunxing: { + direct: true, + filter: function (event, player) { + if (event.player == player) return false; + return player.countCards("he") > 0; + }, + trigger: { target: "useCardToBefore" }, + content: function () { + "step 0"; + var next = player.chooseToDiscard("he", get.prompt(event.name)); + next.logSkill = event.name; + next.ai = function (card) { + if (get.tag(trigger.card, "multitarget") && !get.tag(card, "multineg")) return 0; + if (get.value(trigger.card, trigger.player, "raw") < 5) return 0; + if (get.tag(trigger.card, "respondSha") && player.hasSha()) return 0; + if (get.tag(trigger.card, "respondShan") && player.hasShan()) return 0; + if (get.effect(player, trigger.card, trigger.player, player) < 0) { + return 7 - get.value(card); } return 0; - } - next.prompt2='弃置一张牌并进行一次判定,若结果不为红桃则'+get.translation(trigger.card)+'失效'; - "step 1" - if(result.bool){ - player.judge(function(card){ - return get.suit(card)=='heart'?-1:1; + }; + next.prompt2 = + "弃置一张牌并进行一次判定,若结果不为红桃则" + get.translation(trigger.card) + "失效"; + "step 1"; + if (result.bool) { + player.judge(function (card) { + return get.suit(card) == "heart" ? -1 : 1; }); - } - else{ + } else { event.finish(); } - "step 2" - if(result.suit!='heart'){ + "step 2"; + if (result.suit != "heart") { trigger.cancel(); } - } + }, }, - qiaoxie:{ - group:['qiaoxie2','qiaoxie3'], - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip') return [1,3]; - } + qiaoxie: { + group: ["qiaoxie2", "qiaoxie3"], + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") return [1, 3]; + }, }, - reverseEquip:true, - noe:true, - } + reverseEquip: true, + noe: true, + }, }, - qiaoxie2:{ - trigger:{player:'equipEnd'}, - frequent:true, + qiaoxie2: { + trigger: { player: "equipEnd" }, + frequent: true, //filter:function(event,player){ // for(var i=0;i0; - }).set('autodelay',0.5).ai=function(target){ - return -get.attitude(player,target); + content: function () { + "step 0"; + player + .chooseTarget([1, 1], "请选择巧械的目标", function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + }) + .set("autodelay", 0.5).ai = function (target) { + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('qiaoxie3',result.targets); - player.discardPlayerCard(result.targets[0],'he',true); - } - else{ + "step 1"; + if (result.bool) { + player.logSkill("qiaoxie3", result.targets); + player.discardPlayerCard(result.targets[0], "he", true); + } else { event.finish(); } }, }, - qiaoxie4:{ - trigger:{player:['loseEnd']}, - frequent:true, - filter:function(event,player){ - if(typeof lib.cardType.hslingjian!='number') return false; - if(!player.equiping) return false; - for(var i=0;i0; - }).ai=function(target){ - var att=get.attitude(player,target); - if(att<=0){ - return 1-att+(target.countCards('e')?2:0); + content: function () { + "step 0"; + player.chooseTarget([1, 1], get.prompt("meihuo"), function (card, player, target) { + if (player == target) return false; + return target.countCards("he") > 0; + }).ai = function (target) { + var att = get.attitude(player, target); + if (att <= 0) { + return 1 - att + (target.countCards("e") ? 2 : 0); } return 0; }; - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('meihuo',event.target); - player.choosePlayerCard(event.target,'he',true).ai=function(button){ - var card=button.link; - if(get.position(card)=='e') return get.equipValue(card); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("meihuo", event.target); + player.choosePlayerCard(event.target, "he", true).ai = function (button) { + var card = button.link; + if (get.position(card) == "e") return get.equipValue(card); return 5; }; } - "step 2" - if(result.bool){ - if(get.position(result.buttons[0].link)=='e'){ + "step 2"; + if (result.bool) { + if (get.position(result.buttons[0].link) == "e") { player.equip(result.buttons[0].link); + } else { + player.gain(result.buttons[0].link, event.target); } - else{ - player.gain(result.buttons[0].link,event.target); - } - event.target.$giveAuto(result.buttons[0].link,player); + event.target.$giveAuto(result.buttons[0].link, player); } }, }, - yishan:{ - group:'yishan2', - notemp:true, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - var content=player.storage.yishan; - for(var i=0;i最近失去的牌'); - var cards=[]; - for(var i=0;i=4) break; + if (cards.length >= 4) break; } } - if(cards.length){ + if (cards.length) { dialog.add(cards); - } - else{ - dialog.add('(无)'); + } else { + dialog.add("(无)"); } }, - content:function(content,player){ - var str='最近失去的牌:'; - var cards=[]; - for(var i=0;i=4) break; + if (cards.length >= 4) break; } } - if(cards.length){ - str+=get.translation(cards); - } - else{ - str+='无'; + if (cards.length) { + str += get.translation(cards); + } else { + str += "无"; } return str; - } - } + }, + }, }, - yishan2:{ - trigger:{player:'loseEnd'}, - silent:true, - content:function(){ - for(var i=0;i1; + return get.distance(event.target, player, "attack") > 1; + }, + content: function () { + trigger.directHit = true; }, - content:function(){ - trigger.directHit=true; - } }, - poxing:{ - trigger:{source:'damageBegin'}, - filter:function(trigger,player){ - return trigger.player.hp>player.hp; + poxing: { + trigger: { source: "damageBegin" }, + filter: function (trigger, player) { + return trigger.player.hp > player.hp; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num++; - } - }, - luomu:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player.countCards('hej'); }, - content:function(){ - trigger.player.discard(trigger.player.getCards('hej').randomGet()); - } }, - huanhun:{ - trigger:{global:'dying'}, - priority:6, - filter:function(event,player){ - if(event.player.hp>0) return false; - if(get.is.altered('huanhun')) return player.countCards('h',{color:'red'})>0; - return player.countCards('he')>0; + luomu: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player.countCards("hej"); + }, + content: function () { + trigger.player.discard(trigger.player.getCards("hej").randomGet()); + }, + }, + huanhun: { + trigger: { global: "dying" }, + priority: 6, + filter: function (event, player) { + if (event.player.hp > 0) return false; + if (get.is.altered("huanhun")) return player.countCards("h", { color: "red" }) > 0; + return player.countCards("he") > 0; }, // alter:true, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.is.altered('huanhun')?'h':'he',get.prompt2('huanhun',trigger.player),function(card){ - if(get.is.altered('huanhun')){ - return get.color(card)=='red'; + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + get.is.altered("huanhun") ? "h" : "he", + get.prompt2("huanhun", trigger.player), + function (card) { + if (get.is.altered("huanhun")) { + return get.color(card) == "red"; + } else { + return true; + } } - else{ - return true; - } - }); - next.logSkill=['huanhun',trigger.player]; - next.ai=function(card){ - if(card.name=='tao') return 0; - if(get.attitude(player,trigger.player)>0){ - return 8-get.value(card); + ); + next.logSkill = ["huanhun", trigger.player]; + next.ai = function (card) { + if (card.name == "tao") return 0; + if (get.attitude(player, trigger.player) > 0) { + return 8 - get.value(card); } return 0; }; - "step 1" - if(result.bool){ - event.card=result.cards[0]; - trigger.player.judge(function(card){ - return get.color(card)=='red'?1:0; + "step 1"; + if (result.bool) { + event.card = result.cards[0]; + trigger.player.judge(function (card) { + return get.color(card) == "red" ? 1 : 0; }); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { trigger.player.recover(); - } - else if(event.card.isInPile()){ - trigger.player.gain(event.card,'gain2'); + } else if (event.card.isInPile()) { + trigger.player.gain(event.card, "gain2"); } }, - ai:{ - threaten:1.6, - expose:0.2 - } + ai: { + threaten: 1.6, + expose: 0.2, + }, }, - huanhun_old:{ - enable:'phaseUse', - forbid:['versus'], - filter:function(){ - return game.dead.length>0 + huanhun_old: { + enable: "phaseUse", + forbid: ["versus"], + filter: function () { + return game.dead.length > 0; }, - usable:1, - filterCard:function(card){ - return get.suit(card)=='heart'; + usable: 1, + filterCard: function (card) { + return get.suit(card) == "heart"; }, - direct:true, - content:function(){ - "step 0" - var list=[]; - for(var i=0;i2) return 3; + ai: { + order: 10, + result: { + player: function (player) { + for (var i = 0; i < game.dead.length; i++) { + if (get.attitude(player, game.dead[i]) > 2) return 3; } return 0; - } + }, }, - threaten:2, - } - }, - yinyue:{ - trigger:{global:'recoverAfter'}, - check:function(event,player){ - return get.attitude(player,event.player)>0; + threaten: 2, }, - logTarget:'player', + }, + yinyue: { + trigger: { global: "recoverAfter" }, + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + logTarget: "player", // alter:true, - content:function(){ - "step 0" + content: function () { + "step 0"; // if(get.is.altered('yinyue')){ // trigger.player.draw(); // event.finish(); // } // else - if(trigger.player!=player&&trigger.player.countCards('h')>=player.countCards('h')){ - game.asyncDraw([trigger.player,player]); - } - else{ + if ( + trigger.player != player && + trigger.player.countCards("h") >= player.countCards("h") + ) { + game.asyncDraw([trigger.player, player]); + } else { trigger.player.draw(); event.finish(); } - "step 1" + "step 1"; game.delay(); }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - daofa:{ - trigger:{global:'damageAfter'}, - check:function(event,player){ - return event.source&&get.attitude(player,event.source)<0; + daofa: { + trigger: { global: "damageAfter" }, + check: function (event, player) { + return event.source && get.attitude(player, event.source) < 0; }, - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.countCards('he'); + filter: function (event, player) { + return event.source && event.source != player && event.source.countCards("he"); }, - logTarget:'source', - content:function(){ - trigger.source.chooseToDiscard('he',true); + logTarget: "source", + content: function () { + trigger.source.chooseToDiscard("he", true); + }, + ai: { + expose: 0.2, + threaten: 1.5, }, - ai:{ - expose:0.2, - threaten:1.5 - } }, - daixing:{ - group:['daixing2','daixing3'], - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + daixing: { + group: ["daixing2", "daixing3"], + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt2('daixing'),'he',[1,player.countCards('he')]); - next.logSkill='daixing'; - next.ai=function(card){ - if(ui.selected.cards.length>=2) return 0; - if(ui.selected.cards.length==1){ - if(player.countCards('h')>player.hp){ - return 3-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard(get.prompt2("daixing"), "he", [ + 1, + player.countCards("he"), + ]); + next.logSkill = "daixing"; + next.ai = function (card) { + if (ui.selected.cards.length >= 2) return 0; + if (ui.selected.cards.length == 1) { + if (player.countCards("h") > player.hp) { + return 3 - get.value(card); } return 0; } - return 6-get.value(card); + return 6 - get.value(card); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.changeHujia(result.cards.length); - player.storage.daixing=result.cards.length; + player.storage.daixing = result.cards.length; } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(target.storage.daixing>1) return 0.1; - if(target.storage.daixing==1) return 0.5; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (target.storage.daixing > 1) return 0.1; + if (target.storage.daixing == 1) return 0.5; } return 1.5; - } - } + }, + }, + }, + intro: { + content: "mark", }, - intro:{ - content:'mark' - } }, - daixing2:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - if(player.storage.daixing){ + daixing2: { + trigger: { player: "phaseBegin" }, + silent: true, + content: function () { + if (player.storage.daixing) { player.changeHujia(-player.storage.daixing); - player.storage.daixing=0; + player.storage.daixing = 0; } - } - }, - daixing3:{ - trigger:{player:['damageEnd','damageZero']}, - silent:true, - filter:function(event,player){ - return player.storage.daixing>0&&event.hujia>0; }, - content:function(){ - player.storage.daixing-=trigger.hujia; - if(player.storage.daixing<0){ - player.storage.daixing=0; - } - } }, - swd_wuxie:{ - mod:{ - targetEnabled:function(card,player,target){ - if(get.type(card)=='delay'&&player!=target){ + daixing3: { + trigger: { player: ["damageEnd", "damageZero"] }, + silent: true, + filter: function (event, player) { + return player.storage.daixing > 0 && event.hujia > 0; + }, + content: function () { + player.storage.daixing -= trigger.hujia; + if (player.storage.daixing < 0) { + player.storage.daixing = 0; + } + }, + }, + swd_wuxie: { + mod: { + targetEnabled: function (card, player, target) { + if (get.type(card) == "delay" && player != target) { return false; } - } - } + }, + }, }, - lqingcheng:{ - trigger:{player:'phaseEnd'}, - frequent:true, - content:function(){ - "step 0" - if(event.cards==undefined) event.cards=[]; - player.judge(function(card){ - if(get.color(card)=='red') return 1.5; + lqingcheng: { + trigger: { player: "phaseEnd" }, + frequent: true, + content: function () { + "step 0"; + if (event.cards == undefined) event.cards = []; + player.judge(function (card) { + if (get.color(card) == "red") return 1.5; return -1.5; - },ui.special); - "step 1" - if(result.judge>0){ + }, ui.special); + "step 1"; + if (result.judge > 0) { event.cards.push(result.card); - if(event.cards.length==3){ + if (event.cards.length == 3) { player.gain(event.cards); - if(event.cards.length){ + if (event.cards.length) { player.$draw(event.cards); } event.finish(); + } else if (lib.config.autoskilllist.includes("lqingcheng")) { + player.chooseBool("是否再次发动【倾城】?"); + } else { + event._result = { bool: true }; } - else if(lib.config.autoskilllist.includes('lqingcheng')){ - player.chooseBool('是否再次发动【倾城】?'); - } - else{ - event._result={bool:true}; - } - } - else{ + } else { player.gain(event.cards); - if(event.cards.length){ + if (event.cards.length) { player.$draw(event.cards); } event.finish(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { event.goto(0); - } - else{ + } else { player.gain(event.cards); - if(event.cards.length){ + if (event.cards.length) { player.$draw(event.cards); } } }, - ai:{ - threaten:1.4 - } + ai: { + threaten: 1.4, + }, }, - lingxin:{ - trigger:{player:'phaseEnd'}, - frequent:true, - content:function(){ - "step 0" - event.cards=get.cards(3); + lingxin: { + trigger: { player: "phaseEnd" }, + frequent: true, + content: function () { + "step 0"; + event.cards = get.cards(3); player.showCards(event.cards); - "step 1" - for(var i=0;i=player.hp&&event.skill!='lingwu'; + lingwu: { + trigger: { player: "phaseAfter" }, + frequent: true, + filter: function (event, player) { + return player.countUsed() >= player.hp && event.skill != "lingwu"; }, - content:function(){ + content: function () { player.insertPhase(); }, - ai:{ - order:-10, - result:{ - target:2 + ai: { + order: -10, + result: { + target: 2, }, - threaten:1.5 - } + threaten: 1.5, + }, }, - xianjiang_old:{ - enable:'phaseUse', - position:'he', - usable:1, - filterCard:function(card,player){ - if(player.storage.xianjiang&&player.storage.xianjiang.includes(card)) return false; - return get.type(card)=='equip'; + xianjiang_old: { + enable: "phaseUse", + position: "he", + usable: 1, + filterCard: function (card, player) { + if (player.storage.xianjiang && player.storage.xianjiang.includes(card)) return false; + return get.type(card) == "equip"; }, - init:function(player){ - player.storage.xianjiang=[]; + init: function (player) { + player.storage.xianjiang = []; }, - check:function(card){ - return 10-get.value(card); + check: function (card) { + return 10 - get.value(card); }, - prompt:'将一张装备牌永久转化为任意一张装备牌', - content:function(){ - "step 0" - var list=[]; - var suit=get.suit(cards[0]); - var number=get.number(cards[0]); - for(var i in lib.card){ - if(lib.card[i].mode&&lib.card[i].mode.includes(lib.config.mode)==false) continue; - if(lib.card[i].type=='equip'&&cards[0].name!=i){ - if(get.equipValue({name:i})<10) list.push([suit,number,i]); + prompt: "将一张装备牌永久转化为任意一张装备牌", + content: function () { + "step 0"; + var list = []; + var suit = get.suit(cards[0]); + var number = get.number(cards[0]); + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; + if (lib.card[i].type == "equip" && cards[0].name != i) { + if (get.equipValue({ name: i }) < 10) list.push([suit, number, i]); } } - var dialog=ui.create.dialog([list,'vcard']); - player.chooseButton(dialog,true,function(button){ - return get.value({name:button.link[2]},player); + var dialog = ui.create.dialog([list, "vcard"]); + player.chooseButton(dialog, true, function (button) { + return get.value({ name: button.link[2] }, player); }); - "step 1" + "step 1"; cards[0].init(result.buttons[0].link); player.gain(cards[0]); player.$gain(cards[0]); game.delay(); player.storage.xianjiang.add(cards[0]); }, - ai:{ - order:9, - result:{ - player:1 + ai: { + order: 9, + result: { + player: 1, }, - threaten:2, - } - }, - xianjiang2:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.hasSkill('xianjiang'); + threaten: 2, }, - content:function(){ - player.storage.xianjiang=[]; - } }, - xianjiang:{ - enable:'phaseUse', + xianjiang2: { + trigger: { player: "phaseUseBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.hasSkill("xianjiang"); + }, + content: function () { + player.storage.xianjiang = []; + }, + }, + xianjiang: { + enable: "phaseUse", // alter:true, - filterCard:function(card){ - return get.type(card,'trick')=='trick'; + filterCard: function (card) { + return get.type(card, "trick") == "trick"; }, - usable:1, - filter:function(event,player){ - if(get.is.altered('xianjiang')&&player.countCards('e')) return false; - if(player.countCards('h',{type:'trick'})) return true; - if(player.countCards('h',{type:'delay'})) return true; + usable: 1, + filter: function (event, player) { + if (get.is.altered("xianjiang") && player.countCards("e")) return false; + if (player.countCards("h", { type: "trick" })) return true; + if (player.countCards("h", { type: "delay" })) return true; return false; }, - selectCard:1, - check:function(card){ - return 8-get.value(card); + selectCard: 1, + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - var card=game.createCard(get.inpile('equip').randomGet()); + content: function () { + var card = game.createCard(get.inpile("equip").randomGet()); player.equip(card); player.$gain2(card); game.delay(); }, - ai:{ - result:{ - player:1 + ai: { + result: { + player: 1, }, - order:9 - } + order: 9, + }, }, - shengong:{ - trigger:{player:['chooseToRespondBegin']}, - filter:function(event,player){ - if(event.responded) return false; - if(!player.countCards('he')) return false; - if(event.filterCard({name:'shan'})){ - if(game.hasPlayer(function(current){ - return current!=player&¤t.getEquip(2); - })){ + shengong: { + trigger: { player: ["chooseToRespondBegin"] }, + filter: function (event, player) { + if (event.responded) return false; + if (!player.countCards("he")) return false; + if (event.filterCard({ name: "shan" })) { + if ( + game.hasPlayer(function (current) { + return current != player && current.getEquip(2); + }) + ) { return true; } } - if(event.filterCard({name:'sha'})){ - if(game.hasPlayer(function(current){ - return current!=player&¤t.getEquip(1); - })){ + if (event.filterCard({ name: "sha" })) { + if ( + game.hasPlayer(function (current) { + return current != player && current.getEquip(1); + }) + ) { return true; } } return false; }, - direct:true, - content:function(){ - "step 0" - var list=[]; - var players=game.filterPlayer(); - if(trigger.filterCard({name:'shan'})){ - for(var i=0;i0; + huajian: { + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - "step 0" - var next=player.chooseCardTarget({ - position:'he', - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); + content: function () { + "step 0"; + var next = player.chooseCardTarget({ + position: "he", + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); }, - filterCard:true, - ai1:function(card){ - return get.unuseful(card)+9; + filterCard: true, + ai1: function (card) { + return get.unuseful(card) + 9; }, - ai2:function(target){ - return get.effect(target,{name:'sha'},player); + ai2: function (target) { + return get.effect(target, { name: "sha" }, player); }, - prompt:get.prompt('huajian') + prompt: get.prompt("huajian"), }); - "step 1" - if(result.bool){ - player.logSkill('huajian'); - player.useCard({name:'sha'},result.cards,result.targets,false); + "step 1"; + if (result.bool) { + player.logSkill("huajian"); + player.useCard({ name: "sha" }, result.cards, result.targets, false); } }, - ai:{ - expose:0.2, - } - }, - polang:{ - trigger:{source:'damageEnd'}, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player.countCards('e'); - }, - direct:true, - logTarget:'player', - content:function(){ - player.discardPlayerCard(trigger.player,'e',get.prompt('polang',trigger.player)).logSkill='polang'; - }, - ai:{ - expose:0.3 + ai: { + expose: 0.2, }, }, - jikong:{ - trigger:{player:['loseEnd','phaseBegin']}, - direct:true, - usable:1, + polang: { + trigger: { source: "damageEnd" }, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player.countCards("e"); + }, + direct: true, + logTarget: "player", + content: function () { + player.discardPlayerCard( + trigger.player, + "e", + get.prompt("polang", trigger.player) + ).logSkill = "polang"; + }, + ai: { + expose: 0.3, + }, + }, + jikong: { + trigger: { player: ["loseEnd", "phaseBegin"] }, + direct: true, + usable: 1, // alter:true, - filter:function(event,player){ - if(event.name=='phase') return true; - if(get.is.altered('jikong')) return false; - if(player.countCards('h')) return false; - for(var i=0;i2&&event.card&&event.card.name=='sha'; + }, }, - content:function(){ - "step 0" + }, + xielei: { + trigger: { player: ["useCard", "respondAfter"] }, + direct: true, + filter: function (event) { + return game.countPlayer() > 2 && event.card && event.card.name == "sha"; + }, + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('xielei'), - filterCard:lib.filter.cardDiscardable, - position:'he', - filterTarget:function(card,player,target){ - if(player==target) return false; - if(trigger.name=='respond'){ - return trigger.source!=target; - } - else{ + prompt: get.prompt("xielei"), + filterCard: lib.filter.cardDiscardable, + position: "he", + filterTarget: function (card, player, target) { + if (player == target) return false; + if (trigger.name == "respond") { + return trigger.source != target; + } else { return !trigger.targets.includes(target); } }, - ai1:function(card){ - return 8-get.value(card); + ai1: function (card) { + return 8 - get.value(card); + }, + ai2: function (target) { + return get.damageEffect(target, player, player, "thunder"); }, - ai2:function(target){ - return get.damageEffect(target,player,player,'thunder'); - } }); - "step 1" - if(result.bool&&!event.isMine()){ + "step 1"; + if (result.bool && !event.isMine()) { game.delayx(); } - "step 2" - if(result.bool){ - player.logSkill('xielei',result.targets,'thunder'); + "step 2"; + if (result.bool) { + player.logSkill("xielei", result.targets, "thunder"); player.discard(result.cards); - result.targets[0].damage('thunder'); + result.targets[0].damage("thunder"); } }, - ai:{ - expose:0.3, - threaten:1.6 - } + ai: { + expose: 0.3, + threaten: 1.6, + }, }, - jingjie:{ - enable:'phaseUse', - init:function(player){ - player.storage.jingjie=false; + jingjie: { + enable: "phaseUse", + init: function (player) { + player.storage.jingjie = false; }, - mark:true, - intro:{ - content:'limited', + mark: true, + intro: { + content: "limited", }, - filter:function(event,player){ + filter: function (event, player) { return !player.storage.jingjie; }, - content:function(){ - 'step 0' - player.storage.jingjie=true; - player.unmarkSkill('jingjie'); - event.targets=game.filterPlayer(); - for(var i=0;i0){ - num-=players[i].countCards('he')-2; - } - else if(att<0){ - num+=players[i].countCards('he')-2; + ai: { + threaten: 1.3, + order: 1, + result: { + player: function (player) { + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var att = get.attitude(player, players[i]); + if (att > 0) { + num -= players[i].countCards("he") - 2; + } else if (att < 0) { + num += players[i].countCards("he") - 2; } } - if(player.hp==1) return num-1; - return num-players.length/2; - } - } - } - }, - ningjian:{ - group:['ningjian1','ningjian2'], - ai:{ - effect:{ - target:function(card,player,target){ - if(target.countCards('he')&&(get.tag(card,'respondShan')||get.tag(card,'respondSha'))) return 0.6 - } + if (player.hp == 1) return num - 1; + return num - players.length / 2; + }, }, - respondSha:true, - respondShan:true, - } - }, - ningjian1:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:{color:'black'}, - viewAs:{name:'sha'}, - position:'he', - prompt:'将一张黑色牌当杀打出', - check:function(card){return 6-get.value(card)} - }, - ningjian2:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:{color:'red'}, - viewAs:{name:'shan'}, - position:'he', - prompt:'将一张红色牌当闪使用或打出', - check:function(card){return 6-get.value(card)} - }, - duoren:{ - trigger:{target:'shaMiss'}, - filter:function(event){ - return event.player.getEquip(1)!=undefined; }, - check:function(event,player){ - return get.attitude(player,event.player)<0; + }, + ningjian: { + group: ["ningjian1", "ningjian2"], + ai: { + effect: { + target: function (card, player, target) { + if ( + target.countCards("he") && + (get.tag(card, "respondShan") || get.tag(card, "respondSha")) + ) + return 0.6; + }, + }, + respondSha: true, + respondShan: true, }, - priority:5, - content:function(){ - trigger.player.$give(trigger.player.getEquip(1),player); - player.gain(trigger.player.getEquip(1),trigger.player); + }, + ningjian1: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: { color: "black" }, + viewAs: { name: "sha" }, + position: "he", + prompt: "将一张黑色牌当杀打出", + check: function (card) { + return 6 - get.value(card); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&target.countCards('h')>1&&player.getEquip(1)){ - return [1,0.5,0,-0.5]; + }, + ningjian2: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: { color: "red" }, + viewAs: { name: "shan" }, + position: "he", + prompt: "将一张红色牌当闪使用或打出", + check: function (card) { + return 6 - get.value(card); + }, + }, + duoren: { + trigger: { target: "shaMiss" }, + filter: function (event) { + return event.player.getEquip(1) != undefined; + }, + check: function (event, player) { + return get.attitude(player, event.player) < 0; + }, + priority: 5, + content: function () { + trigger.player.$give(trigger.player.getEquip(1), player); + player.gain(trigger.player.getEquip(1), trigger.player); + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (card.name == "sha" && target.countCards("h") > 1 && player.getEquip(1)) { + return [1, 0.5, 0, -0.5]; } - } - } - } + }, + }, + }, // filter:function(event){ // return event.player.countCards('e')>0; // }, @@ -6746,188 +7174,199 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }, }, - taixu:{ - enable:'phaseUse', - filter:function(event,player){ - return (!player.storage.taixu)&&player.countCards('hej'); + taixu: { + enable: "phaseUse", + filter: function (event, player) { + return !player.storage.taixu && player.countCards("hej"); }, - filterTarget:function(card,player,target){ - return player!=target&&target.hp>1; + filterTarget: function (card, player, target) { + return player != target && target.hp > 1; }, - content:function(){ - player.discard(player.getCards('hej')); - player.storage.taixu=true; - target.damage(player.maxHp-player.hp); + content: function () { + player.discard(player.getCards("hej")); + player.storage.taixu = true; + target.damage(player.maxHp - player.hp); }, - ai:{ - basic:{ - order:1, + ai: { + basic: { + order: 1, }, - result:{ - target:function(player,target){ - if(player.maxHp-player.hp<2) return 0; + result: { + target: function (player, target) { + if (player.maxHp - player.hp < 2) return 0; return -2; }, - player:function(player,target){ - return -0.5*player.countCards('he'); - } - } - } + player: function (player, target) { + return -0.5 * player.countCards("he"); + }, + }, + }, }, - pozhen:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - if(!event.source) return false; - if(get.is.altered('pozhen')){ - return event.source.countCards('h')>player.countCards('h'); + pozhen: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + if (!event.source) return false; + if (get.is.altered("pozhen")) { + return event.source.countCards("h") > player.countCards("h"); } - return event.source.countCards('h')!=player.countCards('h'); + return event.source.countCards("h") != player.countCards("h"); }, // alter:true, // check:function(event,player){ // return get.attitude(player,event.source)<0; // }, - direct:true, - content:function(){ - "step 0" - var num=player.countCards('h')-trigger.source.countCards('h'); - event.num=num; - if(num>0){ - var next=player.chooseToDiscard(num,get.prompt('pozhen',trigger.source),'弃置'+num+'张手牌,并对'+get.translation(trigger.source)+'造成1点伤害'); - next.logSkill=['pozhen',trigger.source]; - next.ai=function(card){ - if(get.damageEffect(trigger.source,player,player)>0&&num<=2){ - return 6-get.value(card); + direct: true, + content: function () { + "step 0"; + var num = player.countCards("h") - trigger.source.countCards("h"); + event.num = num; + if (num > 0) { + var next = player.chooseToDiscard( + num, + get.prompt("pozhen", trigger.source), + "弃置" + num + "张手牌,并对" + get.translation(trigger.source) + "造成1点伤害" + ); + next.logSkill = ["pozhen", trigger.source]; + next.ai = function (card) { + if (get.damageEffect(trigger.source, player, player) > 0 && num <= 2) { + return 6 - get.value(card); } return -1; - } - } - else if(num<0){ - player.chooseBool(get.prompt('pozhen',trigger.source),'弃置'+get.translation(trigger.source)+(-num)+'张手牌').ai=function(){ - return get.attitude(player,trigger.source)<0; - } - } - else{ + }; + } else if (num < 0) { + player.chooseBool( + get.prompt("pozhen", trigger.source), + "弃置" + get.translation(trigger.source) + -num + "张手牌" + ).ai = function () { + return get.attitude(player, trigger.source) < 0; + }; + } else { event.finish(); } - "step 1" - if(result.bool){ - if(event.num>0){ + "step 1"; + if (result.bool) { + if (event.num > 0) { trigger.source.damage(); - } - else{ - player.logSkill('pozhen',trigger.source); - var cards=trigger.source.getCards('h'); + } else { + player.logSkill("pozhen", trigger.source); + var cards = trigger.source.getCards("h"); cards.sort(lib.sort.random); - trigger.source.discard(cards.slice(0,-event.num)); + trigger.source.discard(cards.slice(0, -event.num)); } } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - var num=player.countCards('h')-target.countCards('h'); - if(num>0){ - return [1,0,0,-num/2]; + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + var num = player.countCards("h") - target.countCards("h"); + if (num > 0) { + return [1, 0, 0, -num / 2]; } - if(num<0&&!get.is.altered('pozhen')){ - return [1,0,0,-0.5]; + if (num < 0 && !get.is.altered("pozhen")) { + return [1, 0, 0, -0.5]; } } - } - } - } - }, - tanlin_defence:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return player.countCards('h')&&event.source&&event.source.countCards('h'); + }, + }, }, - direct:true, - content:function(){ - "step 0" - player.chooseToDiscard([1,trigger.source.countCards('h')],'弃置任意张手牌并令伤害来源弃置等量手牌').ai=function(card){ - if(ui.selected.cards.length>=trigger.source.countCards('h')) return -1; - if(ui.selected.cards.length==0) return 8-get.value(card); - return 4-get.value(card); - } - "step 1" - if(result.bool){ - player.logSkill('tanlin'); - trigger.source.randomDiscard('h',result.cards.length); - } - else{ + }, + tanlin_defence: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return player.countCards("h") && event.source && event.source.countCards("h"); + }, + direct: true, + content: function () { + "step 0"; + player.chooseToDiscard( + [1, trigger.source.countCards("h")], + "弃置任意张手牌并令伤害来源弃置等量手牌" + ).ai = function (card) { + if (ui.selected.cards.length >= trigger.source.countCards("h")) return -1; + if (ui.selected.cards.length == 0) return 8 - get.value(card); + return 4 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.logSkill("tanlin"); + trigger.source.randomDiscard("h", result.cards.length); + } else { event.finish(); } - "step 2" + "step 2"; player.draw(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&target.countCards('h')&&target.hp>1&&player!=target) return [1,0.2,0,-0.2]; - } - } - } + ai: { + effect: { + target: function (card, player, target) { + if ( + get.tag(card, "damage") && + target.countCards("h") && + target.hp > 1 && + player != target + ) + return [1, 0.2, 0, -0.2]; + }, + }, + }, }, - tanlin:{ - enable:'phaseUse', - usable:1, - group:'tanlin4', + tanlin: { + enable: "phaseUse", + usable: 1, + group: "tanlin4", // alter:true, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h'); + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" - player.chooseToCompare(target).set('preserve','win'); - "step 1" - if(result.bool){ - if(target.hasSkill('tanlin2')==false){ - target.addSkill('tanlin2'); - player.addSkill('tanlin3'); - if(get.is.altered('tanlin')){ + content: function () { + "step 0"; + player.chooseToCompare(target).set("preserve", "win"); + "step 1"; + if (result.bool) { + if (target.hasSkill("tanlin2") == false) { + target.addSkill("tanlin2"); + player.addSkill("tanlin3"); + if (get.is.altered("tanlin")) { player.gain([result.target]); player.$gain2([result.target]); - } - else{ - player.gain([result.player,result.target]); - player.$gain2([result.player,result.target]); + } else { + player.gain([result.player, result.target]); + player.$gain2([result.player, result.target]); } } - } - else{ + } else { player.damage(target); } }, - ai:{ - result:{ - target:function(player,target){ - var cards=player.getCards('h'); - var num=target.countCards('h'); - if(num>cards.length+3&&player.hp>1) return -2; - if(num>cards.length+1&&player.hp>1) return -1; - if(num==cards.length-1&&player.hp>1&&!get.is.altered('pozhen')) return -1; - for(var i=0;i9) return num==1?-1:-0.5; + ai: { + result: { + target: function (player, target) { + var cards = player.getCards("h"); + var num = target.countCards("h"); + if (num > cards.length + 3 && player.hp > 1) return -2; + if (num > cards.length + 1 && player.hp > 1) return -1; + if (num == cards.length - 1 && player.hp > 1 && !get.is.altered("pozhen")) + return -1; + for (var i = 0; i < cards.length; i++) { + if (cards[i].number > 9) return num == 1 ? -1 : -0.5; } return 0; - } + }, }, - order:9, - } + order: 9, + }, }, - tanlin2:{ - trigger:{global:'phaseAfter'}, - forced:true, - content:function(){ - player.removeSkill('tanlin2'); + tanlin2: { + trigger: { global: "phaseAfter" }, + forced: true, + content: function () { + player.removeSkill("tanlin2"); }, // mod:{ // cardEnabled:function(){ @@ -6944,231 +7383,283 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }, }, - tanlin3:{ - trigger:{global:'phaseAfter'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('tanlin3'); + tanlin3: { + trigger: { global: "phaseAfter" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("tanlin3"); }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } - }, - }, - tanlin4:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(target.hasSkill('tanlin2')) return true; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, - yunchou_old:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h'); + tanlin4: { + mod: { + targetInRange: function (card, player, target, now) { + if (target.hasSkill("tanlin2")) return true; + }, }, - filterCard:true, - selectCard:[1,Infinity], - content:function(){ - "step 0" - var card=target.getCards('h').randomGet(); - if(!card){ + }, + yunchou_old: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); + }, + filterCard: true, + selectCard: [1, Infinity], + content: function () { + "step 0"; + var card = target.getCards("h").randomGet(); + if (!card) { event.finish(); return; } target.discard(card); - var color=get.color(card); - var suit=get.suit(card); - var num1=0,num2=0; - for(var i=0;i0; + mark: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('swdtianshu')).ai=function(card){ - if(get.position(card)=='h') return 5-get.useful(card); - return 4-get.value(card); - }.logSkill='swdtianshu'; - 'step 1' - if(result.bool){ - var list=[]; - for(var i in lib.character){ - if(lib.character[i][4]&&(lib.character[i][4].includes('boss')||lib.character[i][4].includes('hiddenboss'))) continue; - if(i==player.name||i==player.name1||i==player.name2) continue; - for(var j=0;j0; + swdtianshu2: { + enable: "phaseUse", + filter: function (event, player) { + return ( + !player.hasSkill("swdtianshu3") && + player.storage.swdtianshu && + player.storage.swdtianshu.length > 0 + ); }, - intro:{ - nocount:true + intro: { + nocount: true, }, - delay:0, - content:function(){ - 'step 0' - var list=player.storage.swdtianshu; - if(player.additionalSkills.swdtianshu){ + delay: 0, + content: function () { + "step 0"; + var list = player.storage.swdtianshu; + if (player.additionalSkills.swdtianshu) { player.removeSkill(player.additionalSkills.swdtianshu); } - event.skillai=function(list){ - return get.max(list,get.skillRank,'item'); + event.skillai = function (list) { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - var dialog=ui.create.dialog('forcebutton'); - dialog.add('选择获得一项技能'); - _status.event.list=list; - var clickItem=function(){ - _status.event._result=this.link; + if (event.isMine()) { + var dialog = ui.create.dialog("forcebutton"); + dialog.add("选择获得一项技能"); + _status.event.list = list; + var clickItem = function () { + _status.event._result = this.link; game.resume(); }; - for(var i=0;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); - event.dialog=dialog; - event.switchToAuto=function(){ - event._result=event.skillai(list); + dialog.add(ui.create.div(".placeholder")); + event.dialog = dialog; + event.switchToAuto = function () { + event._result = event.skillai(list); game.resume(); }; game.pause(); - _status.imchoosing=true; + _status.imchoosing = true; + } else { + event._result = event.skillai(list); } - else{ - event._result=event.skillai(list); - } - "step 1" - _status.imchoosing=false; - if(event.dialog){ + "step 1"; + _status.imchoosing = false; + if (event.dialog) { event.dialog.close(); } - var link=result; + var link = result; player.addSkill(link); player.skills.remove(link); - player.additionalSkills.swdtianshu=link; + player.additionalSkills.swdtianshu = link; player.popup(link); - var target=player.storage.swdtianshu2[player.storage.swdtianshu.indexOf(link)]; - player.markSkillCharacter('swdtianshu2',target,get.translation(link),lib.translate[link+'_info']); + var target = player.storage.swdtianshu2[player.storage.swdtianshu.indexOf(link)]; + player.markSkillCharacter( + "swdtianshu2", + target, + get.translation(link), + lib.translate[link + "_info"] + ); player.checkMarks(); - player.addSkill('swdtianshu3'); + player.addSkill("swdtianshu3"); }, - ai:{ - order:10, - result:{ - player:function(player){ + ai: { + order: 10, + result: { + player: function (player) { return 1; - } - } - } + }, + }, + }, }, - swdtianshu3:{ - trigger:{global:['useCardAfter','useSkillAfter','phaseAfter']}, - silent:true, - filter:function(event){ - return event.skill!='swdtianshu2'; + swdtianshu3: { + trigger: { global: ["useCardAfter", "useSkillAfter", "phaseAfter"] }, + silent: true, + filter: function (event) { + return event.skill != "swdtianshu2"; + }, + content: function () { + player.removeSkill("swdtianshu3"); }, - content:function(){ - player.removeSkill('swdtianshu3'); - } }, - swdtianshu:{ - unique:true, - enable:'phaseUse', - filterCard:function(card){ - return get.type(card,'trick')=='trick'; + swdtianshu: { + unique: true, + enable: "phaseUse", + filterCard: function (card) { + return get.type(card, "trick") == "trick"; }, - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay']})>0; + filter: function (event, player) { + return player.countCards("h", { type: ["trick", "delay"] }) > 0; }, - filterTarget: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;i
              【'+ - translation+'】
              '+lib.translate[list[i]+'_info']+'
              '); - item.firstChild.addEventListener('click',clickItem); - item.firstChild.link=list[i]; + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; } } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); return dialog; }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - "step 0" + content: function () { + "step 0"; // target.gain(cards,player); - event.skillai=function(list){ - return get.max(list,get.skillRank,'item'); + event.skillai = function (list) { + return get.max(list, get.skillRank, "item"); }; - if(event.isMine()){ - event.dialog=lib.skill.swdtianshu.createDialog(player,target); - event.switchToAuto=function(){ - event._result=event.skillai(event.list); + if (event.isMine()) { + event.dialog = lib.skill.swdtianshu.createDialog(player, target); + event.switchToAuto = function () { + event._result = event.skillai(event.list); game.resume(); }; - _status.imchoosing=true; + _status.imchoosing = true; game.pause(); + } else { + event._result = event.skillai( + lib.skill.swdtianshu.createDialog(player, target, true) + ); } - else{ - event._result=event.skillai(lib.skill.swdtianshu.createDialog(player,target,true)); - } - "step 1" - _status.imchoosing=false; - if(event.dialog){ + "step 1"; + _status.imchoosing = false; + if (event.dialog) { event.dialog.close(); } - var link=result; - player.addAdditionalSkill('swdtianshu',link); + var link = result; + player.addAdditionalSkill("swdtianshu", link); player.popup(link); - player.markSkillCharacter('swdtianshu',target,get.translation(link),lib.translate[link+'_info']); - player.storage.swdtianshu=target; + player.markSkillCharacter( + "swdtianshu", + target, + get.translation(link), + lib.translate[link + "_info"] + ); + player.storage.swdtianshu = target; player.checkMarks(); - game.log(player,'获得了技能','【'+get.translation(link)+'】'); + game.log(player, "获得了技能", "【" + get.translation(link) + "】"); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(player.countCards('h')>player.hp) return 1; + ai: { + order: 1, + result: { + player: function (player, target) { + if (player.countCards("h") > player.hp) return 1; return 0; - } - } - } - }, - swdtianshu_remove:{ - trigger:{global:'dieAfter'}, - silent:true, - filter:function(event,player){ - return event.player==player.storage.swdtianshu; + }, + }, }, - content:function(){ - player.unmarkSkill('swdtianshu'); - player.removeAdditionalSkill('swdtianshu'); - delete player.storage.swdtianshu; - } }, - swdtianshu2_old:{ - trigger:{player:'phaseBegin'}, - direct:true, - priority:-9, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('swdtianshu'),lib.skill.swdtianshu.filterTarget).ai=function(target){ - if(target.maxHp<5) return Math.random()*(5-target.maxHp); - return -1; - }; - "step 1" - if(result.bool){ - player.logSkill('swdtianshu',result.targets); - event.target=result.targets[0]; - if(event.isMine()){ + swdtianshu_remove: { + trigger: { global: "dieAfter" }, + silent: true, + filter: function (event, player) { + return event.player == player.storage.swdtianshu; + }, + content: function () { + player.unmarkSkill("swdtianshu"); + player.removeAdditionalSkill("swdtianshu"); + delete player.storage.swdtianshu; + }, + }, + swdtianshu2_old: { + trigger: { player: "phaseBegin" }, + direct: true, + priority: -9, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("swdtianshu"), lib.skill.swdtianshu.filterTarget).ai = + function (target) { + if (target.maxHp < 5) return Math.random() * (5 - target.maxHp); + return -1; + }; + "step 1"; + if (result.bool) { + player.logSkill("swdtianshu", result.targets); + event.target = result.targets[0]; + if (event.isMine()) { ui.auto.hide(); - event.dialog=lib.skill.swdtianshu.createDialog(player,result.targets[0]); + event.dialog = lib.skill.swdtianshu.createDialog(player, result.targets[0]); game.pause(); - } - else{ - var target=result.targets[0]; - var names=[]; - var list=[]; - 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; + xingdian: { + enable: "phaseUse", + usable: 1, + filterCard: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, // filterTarget:function(card,player,target){ // return player!=target&&target.countCards('h')>0; // }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, // selectTarget:[1,2], - content:function(){ - 'step 0' - event.list=game.filterPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('he'); - }).randomGets(2).sortBySeat(); - 'step 1' - if(event.list.length){ - var target=event.list.shift(); - player.line(target,'green'); - if(event.list.length){ - target.randomDiscard('he',false); - } - else{ - target.randomDiscard('he'); + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + return current.isEnemyOf(player) && current.countCards("he"); + }) + .randomGets(2) + .sortBySeat(); + "step 1"; + if (event.list.length) { + var target = event.list.shift(); + player.line(target, "green"); + if (event.list.length) { + target.randomDiscard("he", false); + } else { + target.randomDiscard("he"); } event.redo(); } }, - ai:{ - order:9, - result:{ - player:function(player){ - if(game.countPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('he'); - })>=2){ + ai: { + order: 9, + result: { + player: function (player) { + if ( + game.countPlayer(function (current) { + return current.isEnemyOf(player) && current.countCards("he"); + }) >= 2 + ) { return 1; } return 0; - } + }, // target:function(player,target){ // if(target.countCards('h')==1) return -1.5; // return -1; // } }, - } - }, - yulin:{ - trigger:{player:'damageBefore'}, - priority:-10, - filter:function(event,player){ - return player.countCards('he',{type:'equip'}); }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he','是否弃置一张装备牌抵消伤害?',function(card,player){ - return get.type(card)=='equip'; - }); - next.logSkill='yulin'; - next.ai=function(card){ - if(player.hp==1||trigger.num>1){ - return 9-get.value(card); + }, + yulin: { + trigger: { player: "damageBefore" }, + priority: -10, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "是否弃置一张装备牌抵消伤害?", + function (card, player) { + return get.type(card) == "equip"; } - if(player.hp==2){ - return 8-get.value(card); + ); + next.logSkill = "yulin"; + next.ai = function (card) { + if (player.hp == 1 || trigger.num > 1) { + return 9 - get.value(card); } - return 7-get.value(card); + if (player.hp == 2) { + return 8 - get.value(card); + } + return 7 - get.value(card); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { game.delay(); trigger.cancel(); } - } + }, }, - funiao:{ - enable:'phaseUse', - usable:1, - prepare:'give2', - filterTarget:function(card,player,target){ - if(player==target) return false; + funiao: { + enable: "phaseUse", + usable: 1, + prepare: "give2", + filterTarget: function (card, player, target) { + if (player == target) return false; return true; }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - check:function(card){ - if(card.name=='du') return 20; - return 7-get.value(card); + filterCard: true, + check: function (card) { + if (card.name == "du") return 20; + return 7 - get.value(card); }, - discard:false, - content:function(){ - 'step 0' - target.gain(cards,player).delay=false; + discard: false, + content: function () { + "step 0"; + target.gain(cards, player).delay = false; player.draw(); - 'step 1' - if(target.countCards('h')){ + "step 1"; + if (target.countCards("h")) { player.viewHandcards(target); } }, - ai:{ - result:{ - target:function(player,target){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ + ai: { + result: { + target: function (player, target) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { return -1; } return 1; }, }, - order:2 - } + order: 2, + }, }, - funiao_old:{ - enable:'phaseUse', - discard:false, - prepare:'give2', - filterTarget:function(card,player,target){ - if(player==target) return false; - if(player.countCards('h')==0) return false; - if(target.storage.funiao) return false; + funiao_old: { + enable: "phaseUse", + discard: false, + prepare: "give2", + filterTarget: function (card, player, target) { + if (player == target) return false; + if (player.countCards("h") == 0) return false; + if (target.storage.funiao) return false; return true; }, - filterCard:true, - check:function(card){ - if(card.name=='du') return 20; - if(get.owner(card).countCards('h')0; + filterTarget: function (card, player, target) { + return get.distance(player, target) <= 1 || player == target; }, - selectTarget:-1, - content:function(){ - target.damage('fire'); + filter: function (event, player) { + return player.countCards("h", { color: "red" }) > 0; }, - line:'fire', - ai:{ - order:1, - result:{ - target:function(player,target){ - var eff=get.damageEffect(target,player,target,'fire'); - if(player==target&&player.hp<=1&&eff<0){ - eff*10; + selectTarget: -1, + content: function () { + target.damage("fire"); + }, + line: "fire", + ai: { + order: 1, + result: { + target: function (player, target) { + var eff = get.damageEffect(target, player, target, "fire"); + if (player == target && player.hp <= 1 && eff < 0) { + eff * 10; } return eff; - } - } - } + }, + }, + }, }, - xuehuang:{ - enable:'phaseUse', - init:function(player){ - player.storage.xuehuang=false; + xuehuang: { + enable: "phaseUse", + init: function (player) { + player.storage.xuehuang = false; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - mark:true, - unique:true, - skillAnimation:true, - animationColor:'fire', - line:'fire', - filter:function(event,player){ - return !player.storage.xuehuang&& - player.countCards('h',{color:'red'})>0&& - player.countCards('h',{color:'black'})==0; + mark: true, + unique: true, + skillAnimation: true, + animationColor: "fire", + line: "fire", + filter: function (event, player) { + return ( + !player.storage.xuehuang && + player.countCards("h", { color: "red" }) > 0 && + player.countCards("h", { color: "black" }) == 0 + ); }, - content:function(){ - 'step 0' - player.storage.xuehuang=true; - player.awakenSkill('xuehuang'); + content: function () { + "step 0"; + player.storage.xuehuang = true; + player.awakenSkill("xuehuang"); player.showHandcards(); - var cards=player.getCards('h'); + var cards = player.getCards("h"); player.discard(cards); - event.num=cards.length; - 'step 1' - if(event.num){ - var targets=player.getEnemies().randomGets(2); - if(!targets.length){ + event.num = cards.length; + "step 1"; + if (event.num) { + var targets = player.getEnemies().randomGets(2); + if (!targets.length) { event.finish(); return; } - player.useCard({name:'sha',nature:'fire'},targets); + player.useCard({ name: "sha", nature: "fire" }, targets); event.num--; event.redo(); } }, - ai:{ - order:9, - result:{ - player:function(player){ - if(player.countCards('h',{color:'red'})<2) return 0; - if(player.hasCard(function(card){ - return get.color(card)=='red'&&get.value(card)>8; - })){ + ai: { + order: 9, + result: { + player: function (player) { + if (player.countCards("h", { color: "red" }) < 2) return 0; + if ( + player.hasCard(function (card) { + return get.color(card) == "red" && get.value(card) > 8; + }) + ) { return 0; } return 1; - } - } - } + }, + }, + }, }, - zhuyu:{ - trigger:{global:'damageBegin'}, - filter:function(event,player){ - if(!event.player.isLinked()) return false; - if(!event.notLink()) return false; - if(player.countCards('he',{color:'red'})) return true; + zhuyu: { + trigger: { global: "damageBegin" }, + filter: function (event, player) { + if (!event.player.isLinked()) return false; + if (!event.notLink()) return false; + if (player.countCards("he", { color: "red" })) return true; return false; }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('朱羽:是否弃置一张红色牌使'+get.translation(trigger.player)+'受到的伤害+1?','he',function(card){ - return get.color(card)=='red'; - }); - next.logSkill=['zhuyu',trigger.player,'fire']; - var num=game.countPlayer(function(current){ - if(current.isLinked()){ - if(trigger.hasNature()){ - return get.sgn(get.damageEffect(current,player,player,'fire')); - } - else{ - if(current==trigger.player){ - return get.sgn(get.damageEffect(current,player,player,'fire')); - } - else{ - return 2*get.sgn(get.damageEffect(current,player,player,'fire')); + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "朱羽:是否弃置一张红色牌使" + get.translation(trigger.player) + "受到的伤害+1?", + "he", + function (card) { + return get.color(card) == "red"; + } + ); + next.logSkill = ["zhuyu", trigger.player, "fire"]; + var num = game.countPlayer(function (current) { + if (current.isLinked()) { + if (trigger.hasNature()) { + return get.sgn(get.damageEffect(current, player, player, "fire")); + } else { + if (current == trigger.player) { + return get.sgn(get.damageEffect(current, player, player, "fire")); + } else { + return 2 * get.sgn(get.damageEffect(current, player, player, "fire")); } } } }); - next.ai=function(card){ - if(trigger.player.hasSkillTag('nofire')) return 0; - if(num>0){ - return 9-get.value(card); + next.ai = function (card) { + if (trigger.player.hasSkillTag("nofire")) return 0; + if (num > 0) { + return 9 - get.value(card); } return 0; }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { trigger.num++; - game.setNature(trigger,'fire'); + game.setNature(trigger, "fire"); } - } + }, }, - ningshuang:{ - trigger:{target:'useCardToBegin'}, - filter:function(event,player){ - if(get.color(event.card)!='black') return false; - if(!event.player) return false; - if(event.player==player) return false; - if(event.player.isLinked()&&event.player.isTurnedOver()) return false; - if(player.countCards('he',{color:'black'})) return true; + ningshuang: { + trigger: { target: "useCardToBegin" }, + filter: function (event, player) { + if (get.color(event.card) != "black") return false; + if (!event.player) return false; + if (event.player == player) return false; + if (event.player.isLinked() && event.player.isTurnedOver()) return false; + if (player.countCards("he", { color: "black" })) return true; return false; }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('凝霜:是否弃置一张黑色牌使'+get.translation(trigger.player)+'横置或翻面?','he',function(card){ - return get.color(card)=='black'; - }); - next.logSkill=['ningshuang',trigger.player]; - next.ai=function(card){ - if(trigger.player.hasSkillTag('noturn')&&trigger.player.isLinked()) return 0; - if(get.attitude(player,trigger.player)<0){ - return 9-get.value(card); + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "凝霜:是否弃置一张黑色牌使" + get.translation(trigger.player) + "横置或翻面?", + "he", + function (card) { + return get.color(card) == "black"; + } + ); + next.logSkill = ["ningshuang", trigger.player]; + next.ai = function (card) { + if (trigger.player.hasSkillTag("noturn") && trigger.player.isLinked()) return 0; + if (get.attitude(player, trigger.player) < 0) { + return 9 - get.value(card); } return 0; }; - "step 1" - if(result.bool){ - if(trigger.player.isTurnedOver()){ + "step 1"; + if (result.bool) { + if (trigger.player.isTurnedOver()) { trigger.player.loseHp(); } - if(trigger.player.isLinked()){ + if (trigger.player.isLinked()) { trigger.player.turnOver(); - } - else{ + } else { trigger.player.link(); player.draw(); } } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.color(card)=='black'&&get.attitude(target,player)<0&&target.countCards('h')>0){ - return [1,0.1,0,-target.countCards('h')/4]; + ai: { + effect: { + target: function (card, player, target) { + if ( + get.color(card) == "black" && + get.attitude(target, player) < 0 && + target.countCards("h") > 0 + ) { + return [1, 0.1, 0, -target.countCards("h") / 4]; } - } - } - } + }, + }, + }, }, - zaowu_old:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:function(card,player,target){ - if(ui.selected.cards.length==0) return true; - for(var i=0;i=10) continue; - if(i!='list') list.push([suit,number,i]); + content: function () { + "step 0"; + var list = []; + var suit = ["heart", "diamond", "club", "spade"].randomGet(); + var number = Math.floor(Math.random() * 13) + 1; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; + if (get.value({ name: i }) >= 10) continue; + if (i != "list") list.push([suit, number, i]); } - var dialog=ui.create.dialog([list,'vcard']); - player.chooseButton(dialog,2,true,function(button){ - return get.value({name:button.link[2]},player); + var dialog = ui.create.dialog([list, "vcard"]); + player.chooseButton(dialog, 2, true, function (button) { + return get.value({ name: button.link[2] }, player); }); - "step 1" - var cards=[ui.create.card(),ui.create.card()]; + "step 1"; + var cards = [ui.create.card(), ui.create.card()]; cards[0].init(result.buttons[0].link); cards[1].init(result.buttons[1].link); player.gain(cards); player.$gain(cards); game.delay(); }, - ai:{ - order:8, - result:{ - player:1 + ai: { + order: 8, + result: { + player: 1, }, - threaten:1.6 - } + threaten: 1.6, + }, }, - xielv:{ - trigger:{player:'phaseDiscardEnd'}, - filter:function(event,player){ - var cards=player.getCards('h'); - if(cards.length<2) return false; - var color=get.color(cards[0]); - for(var i=1;i0; + check: function (event, player) { + if (player.isDamaged()) return true; + return ( + game.countPlayer(function (current) { + if (current.countCards("j")) return get.sgn(get.attitude(player, current)); + }) > 0 + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' + "step 1"; player.recover(); - event.targets=game.filterPlayer(function(current){ - return current.countCards('j'); + event.targets = game.filterPlayer(function (current) { + return current.countCards("j"); }); event.targets.sortBySeat(); - 'step 2' - if(event.targets.length){ - var current=event.targets.shift(); - var js=current.getCards('j'); - if(js.length){ + "step 2"; + if (event.targets.length) { + var current = event.targets.shift(); + var js = current.getCards("j"); + if (js.length) { current.discard(js); - player.line(current,'green'); + player.line(current, "green"); } event.redo(); } }, - ai:{ - expose:0.1, - } + ai: { + expose: 0.1, + }, }, - xiaomoyu:{ - trigger:{source:'damageEnd'}, - priority:1, - forced:true, - filter:function(event,player){ - return !player.hasSkill('xiaomoyu2'); + xiaomoyu: { + trigger: { source: "damageEnd" }, + priority: 1, + forced: true, + filter: function (event, player) { + return !player.hasSkill("xiaomoyu2"); }, - content:function(){ - "step 0" - player.addTempSkill('xiaomoyu2'); - if(player.hp0; + xiangu: { + mod: { + maxHandcard: function (player, num) { + if (player.hp < player.maxHp) return num + player.maxHp - player.hp; + }, }, - usable:1, - selectTarget:-1, - filter:function(){ - return game.hasPlayer(function(current){ - return current.countCards('j'); + }, + tianhuo: { + enable: "phaseUse", + filterTarget: function (card, player, target) { + return target.countCards("j") > 0; + }, + usable: 1, + selectTarget: -1, + filter: function () { + return game.hasPlayer(function (current) { + return current.countCards("j"); }); }, - line:'fire', - content:function(){ - "step 0" - event.num=target.countCards('j'); - target.discard(target.getCards('j')); - "step 1" - target.damage(event.num,'fire','nosource') + line: "fire", + content: function () { + "step 0"; + event.num = target.countCards("j"); + target.discard(target.getCards("j")); + "step 1"; + target.damage(event.num, "fire", "nosource"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var eff=get.damageEffect(target,player,target,'fire'); - if(eff>=0) return eff+1; - var judges=target.getCards('j'); - if(!judges.length) return 0; - if(target.hp==1||judges.length>1) return -judges.length; - var name=judges[0].viewAs||judges[0].name; - if(name=='shandian'||name=='huoshan'||name=='hongshui') return -judges.length; + ai: { + order: 1, + result: { + target: function (player, target) { + var eff = get.damageEffect(target, player, target, "fire"); + if (eff >= 0) return eff + 1; + var judges = target.getCards("j"); + if (!judges.length) return 0; + if (target.hp == 1 || judges.length > 1) return -judges.length; + var name = judges[0].viewAs || judges[0].name; + if (name == "shandian" || name == "huoshan" || name == "hongshui") + return -judges.length; return 0; - } - } - } - }, - huanyin:{ - trigger:{target:'useCardToBefore'}, - forced:true, - priority:5.9, - filter:function(event,player){ - return event.player!=player; + }, + }, }, - content:function(){ - "step 0" - var effect=get.effect(player,trigger.card,trigger.player,player); - player.judge(function(card){ - switch(get.suit(card)){ - case 'spade':return -effect; - case 'heart':return 1; - default:return 0; + }, + huanyin: { + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 5.9, + filter: function (event, player) { + return event.player != player; + }, + content: function () { + "step 0"; + var effect = get.effect(player, trigger.card, trigger.player, player); + player.judge(function (card) { + switch (get.suit(card)) { + case "spade": + return -effect; + case "heart": + return 1; + default: + return 0; } }); - "step 1" - switch(result.suit){ - case 'spade':{ + "step 1"; + switch (result.suit) { + case "spade": { trigger.cancel(); break; } - case 'heart':{ + case "heart": { player.draw(); break; } } }, - ai:{ - effect:{ - target:function(card,player,target){ - return 0.7 - } + ai: { + effect: { + target: function (card, player, target) { + return 0.7; + }, }, - threaten:0.8 - } + threaten: 0.8, + }, }, - xuanzhou:{ - enable:'phaseUse', - usable:1, - discard:false, - filter:function(event,player){ - return player.countCards('he',{type:'trick'})>0; + xuanzhou: { + enable: "phaseUse", + usable: 1, + discard: false, + filter: function (event, player) { + return player.countCards("he", { type: "trick" }) > 0; }, - prepare:'throw', - position:'he', - filterCard:{type:'trick'}, - filterTarget:function(card,player,target){ - return player!=target; + prepare: "throw", + position: "he", + filterCard: { type: "trick" }, + filterTarget: function (card, player, target) { + return player != target; }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - "step 0" - var list=[]; - for(var i in lib.card){ - if(lib.card[i].mode&&lib.card[i].mode.includes(lib.config.mode)==false) continue; - if(lib.card[i].type=='delay') list.push([cards[0].suit,cards[0].number,i]); + content: function () { + "step 0"; + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; + if (lib.card[i].type == "delay") list.push([cards[0].suit, cards[0].number, i]); } - var dialog=ui.create.dialog('玄咒',[list,'vcard']); - var bing=target.countCards('h')<=1; - player.chooseButton(dialog,true,function(button){ - if(get.effect(target,{name:button.link[2]},player,player)>0){ - if(button.link[2]=='bingliang'){ - if(bing) return 2; + var dialog = ui.create.dialog("玄咒", [list, "vcard"]); + var bing = target.countCards("h") <= 1; + player.chooseButton(dialog, true, function (button) { + if (get.effect(target, { name: button.link[2] }, player, player) > 0) { + if (button.link[2] == "bingliang") { + if (bing) return 2; return 0.7; } - if(button.link[2]=='lebu'){ + if (button.link[2] == "lebu") { return 1; } - if(button.link[2]=='guiyoujie'){ + if (button.link[2] == "guiyoujie") { return 0.5; } - if(button.link[2]=='caomu'){ + if (button.link[2] == "caomu") { return 0.3; } return 0.2; } return 0; - }).filterButton=function(button){ + }).filterButton = function (button) { return !target.hasJudge(button.link[2]); }; - "step 1" - target.addJudge(result.links[0][2],cards); + "step 1"; + target.addJudge(result.links[0][2], cards); }, - ai:{ - result:{ - player:function(player,target){ - var eff=0; - for(var i in lib.card){ - if(lib.card[i].type=='delay'){ - var current=get.effect(target,{name:i},player,player); - if(current>eff){ - eff=current; + ai: { + result: { + player: function (player, target) { + var eff = 0; + for (var i in lib.card) { + if (lib.card[i].type == "delay") { + var current = get.effect(target, { name: i }, player, player); + if (current > eff) { + eff = current; } } } return eff; - } + }, }, - order:9.5, - } + order: 9.5, + }, }, - tianlun:{ - unique:true, - trigger:{global:'judge'}, - direct:true, - filter:function(event){ - if(event.card) return true; - return game.hasPlayer(function(current){ - return current.countCards('j'); + tianlun: { + unique: true, + trigger: { global: "judge" }, + direct: true, + filter: function (event) { + if (event.card) return true; + return game.hasPlayer(function (current) { + return current.countCards("j"); }); }, - content:function(){ - "step 0" - var list=[]; - if(trigger.card) list.push(trigger.card); - var players=game.filterPlayer(); - for(var i=0;i1) return true; - var eff=get.damageEffect(event.player,player,player); - if(player.hp==player.maxHp) return eff<0; - return eff<=0; + ai: { + tag: { + rejudge: 0.6, + }, }, - content:function(){ + }, + lanzhi_old: { + trigger: { source: "damageBefore" }, + logTarget: "player", + check: function (event, player) { + if (player.hp == 1 && event.player.hp > 1) return true; + var eff = get.damageEffect(event.player, player, player); + if (player.hp == player.maxHp) return eff < 0; + return eff <= 0; + }, + content: function () { trigger.cancel(); player.recover(); }, }, - lanzhi:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - if(get.suit(event.card)=='club'){ - return game.hasPlayer(function(current){ - return current.hp<=player.hp&¤t.isDamaged(); + lanzhi: { + trigger: { player: "useCard" }, + filter: function (event, player) { + if (get.suit(event.card) == "club") { + return game.hasPlayer(function (current) { + return current.hp <= player.hp && current.isDamaged(); }); } return false; }, - prompt:function(event,player){ - var list=game.filterPlayer(function(current){ - return current.hp<=player.hp&¤t.isDamaged(); + prompt: function (event, player) { + var list = game.filterPlayer(function (current) { + return current.hp <= player.hp && current.isDamaged(); }); - return get.prompt('lanzhi',list); + return get.prompt("lanzhi", list); }, - check:function(event,player){ - var list=game.filterPlayer(function(current){ - return current.hp<=player.hp&¤t.isDamaged(); + check: function (event, player) { + var list = game.filterPlayer(function (current) { + return current.hp <= player.hp && current.isDamaged(); }); - var num=0; - for(var i=0;i0){ + var num = 0; + for (var i = 0; i < list.length; i++) { + var eff = get.recoverEffect(list[i], player, player); + if (eff > 0) { num++; - } - else{ + } else { num--; } } - return num>0; + return num > 0; }, - content:function(){ - "step 0" - var list=game.filterPlayer(function(current){ - return current.hp<=player.hp&¤t.isDamaged(); + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current.hp <= player.hp && current.isDamaged(); }); - player.line(list,'green'); + player.line(list, "green"); list.sort(lib.sort.seat); - event.list=list; - "step 1" - if(event.list.length){ + event.list = list; + "step 1"; + if (event.list.length) { event.list.shift().recover(); event.redo(); } }, - ai:{ - expose:0.3, - threaten:1.5 - } + ai: { + expose: 0.3, + threaten: 1.5, + }, }, - lanzhi2:{}, - duanyi:{ - enable:'phaseUse', - usable:1, + lanzhi2: {}, + duanyi: { + enable: "phaseUse", + usable: 1, // alter:true, - filter:function(event,player){ - return player.countCards('h','sha')>1; + filter: function (event, player) { + return player.countCards("h", "sha") > 1; }, - filterCard:{name:'sha'}, - selectCard:2, - filterTarget:function(card,player,target){ - return player!=target; + filterCard: { name: "sha" }, + selectCard: 2, + filterTarget: function (card, player, target) { + return player != target; }, - check:function(card){ - return 10-get.value(card); + check: function (card) { + return 10 - get.value(card); }, - content:function(){ - "step 0" + content: function () { + "step 0"; target.damage(); - if(get.is.altered('duanyi')){ + if (get.is.altered("duanyi")) { event.finish(); } - "step 1" - var he=target.getCards('he'); - target.discard(he.randomGets(target.maxHp-target.hp)); + "step 1"; + var he = target.getCards("he"); + target.discard(he.randomGets(target.maxHp - target.hp)); }, - ai:{ - expose:0.3, - result:{ - target:function(player,target){ - return get.damageEffect(target,player)-(target.maxHp-target.hp)/2; - } + ai: { + expose: 0.3, + result: { + target: function (player, target) { + return get.damageEffect(target, player) - (target.maxHp - target.hp) / 2; + }, }, - order:5 - } - }, - guxing:{ - group:['guxing1','guxing3'] - }, - guxing1:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var min=Math.max(1,player.maxHp-player.hp); - return player.countCards('h')<=min&&player.countCards('h')>0&& - lib.filter.filterCard({name:'sha'},player); + order: 5, }, - filterCard:true, - selectCard:-1, + }, + guxing: { + group: ["guxing1", "guxing3"], + }, + guxing1: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var min = Math.max(1, player.maxHp - player.hp); + return ( + player.countCards("h") <= min && + player.countCards("h") > 0 && + lib.filter.filterCard({ name: "sha" }, player) + ); + }, + filterCard: true, + selectCard: -1, // viewAs:{name:'sha'}, - discard:false, - prepare:'throw', - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); + discard: false, + prepare: "throw", + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); }, - content:function(){ - "step 0" + content: function () { + "step 0"; delete player.storage.guxing; targets.sort(lib.sort.seat); - player.useCard({name:'sha'},cards,targets,'guxing').animate=false; - "step 1" - if(player.storage.guxing){ + player.useCard({ name: "sha" }, cards, targets, "guxing").animate = false; + "step 1"; + if (player.storage.guxing) { player.draw(player.storage.guxing); delete player.storage.guxing; } }, - multitarget:true, - multiline:true, - selectTarget:[1,3], - ai:{ - order:function(){ - if(_status.event.player.countCards('h')==1) return 10; - return get.order({name:'sha'})+0.1; + multitarget: true, + multiline: true, + selectTarget: [1, 3], + ai: { + order: function () { + if (_status.event.player.countCards("h") == 1) return 10; + return get.order({ name: "sha" }) + 0.1; }, - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,target); - } + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, }, - threaten:function(player,target){ - if(target.hp=player.maxHp-1) return [0,0]; - } - } - } }, - jifeng:{ - mod:{ - selectTarget:function(card,player,range){ - if(range[0]!=1||range[1]!=1) return; - var range2=get.select(get.info(card).selectTarget); - if(range2[0]!=1&&range2[1]!=1) return; - if(card.name=='sha'||get.type(card)=='trick') range[1]=Infinity; + swdxueyi: { + trigger: { player: "phaseDrawBegin" }, + frequent: true, + content: function () { + trigger.num += player.maxHp - player.hp; + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (target.hp == target.maxHp) return [0, 1]; + } + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, }, }, - trigger:{player:'useCardToBefore'}, - priority:6, - forced:true, - popup:false, - filter:function(event,player){ - if(event.targets.length<=1) return false; - if(event.card.name=='sha') return true; - else if(get.type(event.card)=='trick'){ - var range=get.select(get.info(event.card).selectTarget); - if(range[0]==1&&range[1]==1) return true; + }, + jifeng: { + mod: { + selectTarget: function (card, player, range) { + if (range[0] != 1 || range[1] != 1) return; + var range2 = get.select(get.info(card).selectTarget); + if (range2[0] != 1 && range2[1] != 1) return; + if (card.name == "sha" || get.type(card) == "trick") range[1] = Infinity; + }, + }, + trigger: { player: "useCardToBefore" }, + priority: 6, + forced: true, + popup: false, + filter: function (event, player) { + if (event.targets.length <= 1) return false; + if (event.card.name == "sha") return true; + else if (get.type(event.card) == "trick") { + var range = get.select(get.info(event.card).selectTarget); + if (range[0] == 1 && range[1] == 1) return true; } return false; }, - content:function(){ - if(Math.random()>(1.3+trigger.targets.length/5)/trigger.targets.length){ - trigger.target.popup('失误'); + content: function () { + if (Math.random() > (1.3 + trigger.targets.length / 5) / trigger.targets.length) { + trigger.target.popup("失误"); trigger.cancel(); } - } + }, }, - mohua2:{ - unique:true, - trigger:{player:'dying'}, - priority:10, - forced:true, - content:function(){ - "step 0" - player.removeSkill('miles_xueyi'); - player.removeSkill('aojian'); - player.removeSkill('mohua2'); - player.addSkill('moyan'); - player.addSkill('miedao'); - player.addSkill('jifeng'); - player.addSkill('swd_xiuluo'); + mohua2: { + unique: true, + trigger: { player: "dying" }, + priority: 10, + forced: true, + content: function () { + "step 0"; + player.removeSkill("miles_xueyi"); + player.removeSkill("aojian"); + player.removeSkill("mohua2"); + player.addSkill("moyan"); + player.addSkill("miedao"); + player.addSkill("jifeng"); + player.addSkill("swd_xiuluo"); - lib.character.swd_satan=['','qun',4,['moyan','miedao','jifeng','swd_xiuluo'],['temp']]; - if(player.name=='swd_miles') player.name='swd_satan'; - if(player.name1=='swd_miles') player.name1='swd_satan'; - if(player.name2=='swd_miles'){ - player.name2='swd_satan'; - player.node.avatar2.setBackground('swd_satan','character'); + lib.character.swd_satan = [ + "", + "qun", + 4, + ["moyan", "miedao", "jifeng", "swd_xiuluo"], + ["temp"], + ]; + if (player.name == "swd_miles") player.name = "swd_satan"; + if (player.name1 == "swd_miles") player.name1 = "swd_satan"; + if (player.name2 == "swd_miles") { + player.name2 = "swd_satan"; + player.node.avatar2.setBackground("swd_satan", "character"); + } else { + player.node.avatar.setBackground("swd_satan", "character"); } - else{ - player.node.avatar.setBackground('swd_satan','character'); - } - "step 1" + "step 1"; player.recover(2); - "step 2" + "step 2"; player.draw(2); }, }, - liexin:{ - trigger:{source:'damageBegin'}, - direct:true, - content:function(){ - "step 0" - player.chooseToDiscard('是否弃置一张牌使伤害+1?','he').ai=function(card){ - if(get.attitude(player,trigger.player)<0){ - return 7-get.value(card); + liexin: { + trigger: { source: "damageBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseToDiscard("是否弃置一张牌使伤害+1?", "he").ai = function (card) { + if (get.attitude(player, trigger.player) < 0) { + return 7 - get.value(card); } - } - "step 1" - if(result.bool){ - player.logSkill('liexin'); + }; + "step 1"; + if (result.bool) { + player.logSkill("liexin"); trigger.num++; } }, - ai:{ - threaten:1.8 - } + ai: { + threaten: 1.8, + }, }, - mohua:{ - trigger:{player:'dying'}, - priority:10, - forced:true, - mode:['identity'], - content:function(){ - "step 0" - var skills=['wuying','xiehun','jumo']; - if(lib.config.mode_choice.double_character){ - skills.push('swd_xiuluo'); + mohua: { + trigger: { player: "dying" }, + priority: 10, + forced: true, + mode: ["identity"], + content: function () { + "step 0"; + var skills = ["wuying", "xiehun", "jumo"]; + if (lib.config.mode_choice.double_character) { + skills.push("swd_xiuluo"); } - lib.character.swd_satan=['','qun',6,skills,['temp']]; - if(!_status.ai.customAttitude) _status.ai.customAttitude=[]; - _status.ai.customAttitude.push(function(from,to){ - if(from.storage.xiehun){ - if(to==game.zhu) return 10; + lib.character.swd_satan = ["", "qun", 6, skills, ["temp"]]; + if (!_status.ai.customAttitude) _status.ai.customAttitude = []; + _status.ai.customAttitude.push(function (from, to) { + if (from.storage.xiehun) { + if (to == game.zhu) return 10; return -10; } - if(to.storage.xiehun){ + if (to.storage.xiehun) { return 0; } }); player.uninit(); - player.init('swd_satan'); - player.hp=game.players.length; + player.init("swd_satan"); + player.hp = game.players.length; player.update(); - game.zhu=player; - player.identity='zhu'; - player.setIdentity('魔'); - player.identityShown=true; - var players=get.players(false,true); - for(var i=0;i0){ + if (num > 0) { player.draw(num); } }, }, - duijue:{ - enable:'phaseUse', - mark:true, - unique:true, - forceunique:true, - skillAnimation:true, - filter:function(event,player){ - if(event.skill) return false; + duijue: { + enable: "phaseUse", + mark: true, + unique: true, + forceunique: true, + skillAnimation: true, + filter: function (event, player) { + if (event.skill) return false; return !player.storage.duijue; }, - filterTarget:function(card,player,target){ - if(target.hp<=1) return false; + filterTarget: function (card, player, target) { + if (target.hp <= 1) return false; // if(get.mode()=='identity'&&_status.mode=='zhong'&&game.zhu&&!game.zhu.isZhu){ // return target==game.zhong; // } // if(target.identity=='zhu'||get.is.jun(target)) return false; - return player!=target; + return player != target; }, - content:function(){ - player.storage.duijue=true; - player.awakenSkill('duijue'); - var evt=_status.event; - for(var i=0;i<10;i++){ - if(evt&&evt.getParent){ - evt=evt.getParent(); + content: function () { + player.storage.duijue = true; + player.awakenSkill("duijue"); + var evt = _status.event; + for (var i = 0; i < 10; i++) { + if (evt && evt.getParent) { + evt = evt.getParent(); } - if(evt.name=='phaseUse'){ - evt.skipped=true; + if (evt.name == "phaseUse") { + evt.skipped = true; break; } } - player.storage.duijue3=target; - player.addSkill('duijue3'); + player.storage.duijue3 = target; + player.addSkill("duijue3"); }, - duijueLoop:function(){ - 'step 0' - targets[0].phase('duijue'); - 'step 1' + duijueLoop: function () { + "step 0"; + targets[0].phase("duijue"); + "step 1"; ui.duijueLoop.round--; - ui.duijueLoop.innerHTML=get.cnNumber(ui.duijueLoop.round)+'回合'; - if(targets[0].isDead()||targets[1].isDead()||ui.duijueLoop.round==0){ + ui.duijueLoop.innerHTML = get.cnNumber(ui.duijueLoop.round) + "回合"; + if (targets[0].isDead() || targets[1].isDead() || ui.duijueLoop.round == 0) { event.goto(3); + } else { + targets[1].phase("duijue"); } - else{ - targets[1].phase('duijue'); - } - 'step 2' + "step 2"; ui.duijueLoop.round--; - ui.duijueLoop.innerHTML=get.cnNumber(ui.duijueLoop.round)+'回合'; - if(targets[0].isDead()||targets[1].isDead()||ui.duijueLoop.round==0){ + ui.duijueLoop.innerHTML = get.cnNumber(ui.duijueLoop.round) + "回合"; + if (targets[0].isDead() || targets[1].isDead() || ui.duijueLoop.round == 0) { event.goto(3); - } - else{ + } else { event.goto(0); } - 'step 3' - for(var i=0;i=3) return -1; - if(target.hp= 3) return -1; + if (target.hp < player.hp && target.countCards("h") <= player.countCards("h")) + return -1; return 0; - } - } - } + }, + }, + }, }, - duijue3:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - priority:-50, - content:function(){ - var target=player.storage.duijue3; + duijue3: { + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + priority: -50, + content: function () { + var target = player.storage.duijue3; delete player.storage.duijue3; - player.removeSkill('duijue3'); - if(!target.isAlive()){ + player.removeSkill("duijue3"); + if (!target.isAlive()) { event.finish(); return; } - var next=player.insertEvent('duijueLoop',lib.skill.duijue.duijueLoop,{ - targets:[target,player], - num:0, - backup:[], - source:player, + var next = player.insertEvent("duijueLoop", lib.skill.duijue.duijueLoop, { + targets: [target, player], + num: 0, + backup: [], + source: player, }); - next.forceDie=true; - for(var i=0;i0&& - get.attitude(player,trigger.source)<0&& - get.damageEffect(trigger.player,trigger.source,player)< - get.damageEffect(trigger.source,trigger.player,player); - var next=player.chooseToDiscard('是否将伤害来源('+get.translation(trigger.source)+ - ')和目标('+get.translation(trigger.player)+')对调?','he'); - next.ai=function(card){ - if(go){ - return 10-get.value(card); + content: function () { + "step 0"; + var go = + get.attitude(player, trigger.player) > 0 && + get.attitude(player, trigger.source) < 0 && + get.damageEffect(trigger.player, trigger.source, player) < + get.damageEffect(trigger.source, trigger.player, player); + var next = player.chooseToDiscard( + "是否将伤害来源(" + + get.translation(trigger.source) + + ")和目标(" + + get.translation(trigger.player) + + ")对调?", + "he" + ); + next.ai = function (card) { + if (go) { + return 10 - get.value(card); } return 0; }; - next.logSkill='yinguo'; - "step 1" - if(result.bool){ - var target=trigger.player; - trigger.player=trigger.source; - trigger.source=target; - trigger.trigger('damageBefore'); - player.addTempSkill('yinguo2',['damageAfter','damageCancelled']); + next.logSkill = "yinguo"; + "step 1"; + if (result.bool) { + var target = trigger.player; + trigger.player = trigger.source; + trigger.source = target; + trigger.trigger("damageBefore"); + player.addTempSkill("yinguo2", ["damageAfter", "damageCancelled"]); } }, - ai:{ - threaten:10, - expose:0.5, + ai: { + threaten: 10, + expose: 0.5, }, - global:'yinguo3' + global: "yinguo3", }, - yinguo2:{}, - yinguo3:{ - ai:{ - effect:{ - target:function(card,player,target){ - if(!get.tag(card,'damage')) return; - if(target.hasSkill('yinguo')) return; - var source=game.findPlayer(function(current){ - return current.hasSkill('yinguo'); + yinguo2: {}, + yinguo3: { + ai: { + effect: { + target: function (card, player, target) { + if (!get.tag(card, "damage")) return; + if (target.hasSkill("yinguo")) return; + var source = game.findPlayer(function (current) { + return current.hasSkill("yinguo"); }); - if(source&&source.countCards('he')){ - if(get.attitude(source,player)<0&&get.attitude(source,target)>0){ - return [0,0,0,-1]; + if (source && source.countCards("he")) { + if (get.attitude(source, player) < 0 && get.attitude(source, target) > 0) { + return [0, 0, 0, -1]; } } - } - } - } + }, + }, + }, }, - guiyan:{ - unique:true, - enable:'phaseUse', - usable:1, - intro:{ - content:'濒死时回复1点体力并失去鬼眼' + guiyan: { + unique: true, + enable: "phaseUse", + usable: 1, + intro: { + content: "濒死时回复1点体力并失去鬼眼", }, - mark:true, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('h'); + mark: true, + filterTarget: function (card, player, target) { + return player != target && target.countCards("h"); }, - content:function(){ - "step 0" - player.chooseCardButton(target,target.getCards('h')).set('ai',function(button){ + content: function () { + "step 0"; + player.chooseCardButton(target, target.getCards("h")).set("ai", function (button) { return get.value(button.link); - }).filterButton=function(button){ - return get.suit(button.link)=='club'; - } - "step 1" - if(result.bool){ - player.gain(result.links[0],target); - target.$giveAuto(result.links[0],player); + }).filterButton = function (button) { + return get.suit(button.link) == "club"; + }; + "step 1"; + if (result.bool) { + player.gain(result.links[0], target); + target.$giveAuto(result.links[0], player); } }, - ai:{ - order:11, - result:{ - target:-1, - player:1, + ai: { + order: 11, + result: { + target: -1, + player: 1, }, - threaten:1.3 + threaten: 1.3, }, - group:['guiyan2'], + group: ["guiyan2"], }, - guiyan2:{ - trigger:{player:'dying'}, - priority:6, - forced:true, - content:function(){ + guiyan2: { + trigger: { player: "dying" }, + priority: 6, + forced: true, + content: function () { player.recover(); - player.removeSkill('guiyan'); - player.removeSkill('guiyan2'); - } + player.removeSkill("guiyan"); + player.removeSkill("guiyan2"); + }, }, - yunshen_old:{ - mod:{ - globalFrom:function(from,to,distance){ - if(!from.getEquip(1)) return distance-1; + yunshen_old: { + mod: { + globalFrom: function (from, to, distance) { + if (!from.getEquip(1)) return distance - 1; }, - globalTo:function(from,to,distance){ - if(!to.getEquip(2)) return distance+1; - } - } + globalTo: function (from, to, distance) { + if (!to.getEquip(2)) return distance + 1; + }, + }, }, - suiyan_old:{ - enable:'phaseUse', - usable:1, - filterCard:function(card){ - return get.type(card)=='basic'; + suiyan_old: { + enable: "phaseUse", + usable: 1, + filterCard: function (card) { + return get.type(card) == "basic"; }, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('e'); + filterTarget: function (card, player, target) { + return player != target && target.countCards("e"); }, - content:function(){ - var num=Math.floor(Math.random()*3); - if(num==0){ + content: function () { + var num = Math.floor(Math.random() * 3); + if (num == 0) { player.draw(); - } - else{ - target.discard(target.getCards('e').sort(lib.sort.random).splice(0,num)); + } else { + target.discard(target.getCards("e").sort(lib.sort.random).splice(0, num)); } }, - ai:{ - order:7, - result:{ - target:-1, + ai: { + order: 7, + result: { + target: -1, }, - threaten:1.2 - } + threaten: 1.2, + }, }, - xianyin:{ - enable:'phaseUse', - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('j')&¤t!=player; + xianyin: { + enable: "phaseUse", + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("j") && current != player; }); }, - content:function(){ - "step 0" - event.targets=game.filterPlayer(function(current){ - return current.countCards('j')&¤t!=player; + content: function () { + "step 0"; + event.targets = game.filterPlayer(function (current) { + return current.countCards("j") && current != player; }); event.targets.sort(lib.sort.seat); - "step 1" - if(event.targets.length){ - event.target=event.targets.shift(); - event.target.discard(event.target.getCards('j')); - player.line(event.target,'green'); - } - else{ + "step 1"; + if (event.targets.length) { + event.target = event.targets.shift(); + event.target.discard(event.target.getCards("j")); + player.line(event.target, "green"); + } else { event.finish(); } - "step 2" - if(event.target.countCards('h')){ - event.target.chooseCard('选择一张手牌交给'+get.translation(player),true).ai=function(card){ - return -get.value(card); - } - } - else{ + "step 2"; + if (event.target.countCards("h")) { + event.target.chooseCard("选择一张手牌交给" + get.translation(player), true).ai = + function (card) { + return -get.value(card); + }; + } else { event.goto(1); } - "step 3" - if(result.bool){ - player.gain(result.cards[0],target); - target.$give(1,player); + "step 3"; + if (result.bool) { + player.gain(result.cards[0], target); + target.$give(1, player); } event.goto(1); }, - ai:{ - order:9, - result:{ - player:function(player){ - var num=0,players=game.filterPlayer(); - for(var i=0;i=0&& - get.attitude(players[i],player)>=0){ + ai: { + order: 9, + result: { + player: function (player) { + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && players[i].countCards("j")) { + if ( + get.attitude(player, players[i]) >= 0 && + get.attitude(players[i], player) >= 0 + ) { num++; - } - else{ + } else { num--; } } } return num; - } - } - } - }, - mailun:{ - unique:true, - trigger:{player:'phaseBegin'}, - direct:true, - intro:{ - content:function(storage){ - if(!storage) return '无'; - return lib.skill.mailun.effects[storage-1]; - } + }, + }, }, - effects:[ - '减少1点体力并增加1点体力上限', - '增加1点体力并减少1点体力上限', - '令你即将造成和即将受到的首次伤害-1', - '令你即将造成和即将受到的首次伤害+1', - '少摸一张牌并令手牌上限+1', - '多摸一张牌并令手牌上限-1', - '进攻距离+1,防御距离-1', - '进攻距离-1,防御距离+1' + }, + mailun: { + unique: true, + trigger: { player: "phaseBegin" }, + direct: true, + intro: { + content: function (storage) { + if (!storage) return "无"; + return lib.skill.mailun.effects[storage - 1]; + }, + }, + effects: [ + "减少1点体力并增加1点体力上限", + "增加1点体力并减少1点体力上限", + "令你即将造成和即将受到的首次伤害-1", + "令你即将造成和即将受到的首次伤害+1", + "少摸一张牌并令手牌上限+1", + "多摸一张牌并令手牌上限-1", + "进攻距离+1,防御距离-1", + "进攻距离-1,防御距离+1", ], - content:function(){ - "step 0" - player.removeSkill('mailun31'); - player.removeSkill('mailun32'); - player.removeSkill('mailun41'); - player.removeSkill('mailun42'); - player.removeSkill('mailun5'); - player.removeSkill('mailun6'); - player.removeSkill('mailun7'); - player.removeSkill('mailun8'); - if(event.isMine()){ + content: function () { + "step 0"; + player.removeSkill("mailun31"); + player.removeSkill("mailun32"); + player.removeSkill("mailun41"); + player.removeSkill("mailun42"); + player.removeSkill("mailun5"); + player.removeSkill("mailun6"); + player.removeSkill("mailun7"); + player.removeSkill("mailun8"); + if (event.isMine()) { ui.auto.hide(); - event.dialog=ui.create.dialog('脉轮:选择一个效果','forcebutton'); - var effects=lib.skill.mailun.effects; - var clickItem=function(){ - event.choice=this.link; + event.dialog = ui.create.dialog("脉轮:选择一个效果", "forcebutton"); + var effects = lib.skill.mailun.effects; + var clickItem = function () { + event.choice = this.link; game.resume(); + }; + for (var i = 0; i < 8; i++) { + if (i == 0 && player.maxHp == 6) continue; + var item = event.dialog.add( + '" + ); + item.addEventListener("click", clickItem); + item.link = i + 1; } - for(var i=0;i<8;i++){ - if(i==0&&player.maxHp==6) continue; - var item=event.dialog.add(''); - item.addEventListener('click',clickItem); - item.link=i+1; - } - event.control=ui.create.control('取消',function(){ - event.choice=0; + event.control = ui.create.control("取消", function () { + event.choice = 0; game.resume(); }); - event.dialog.add(ui.create.div('.placeholder')); - event.dialog.add(ui.create.div('.placeholder')); - event.dialog.add(ui.create.div('.placeholder')); + event.dialog.add(ui.create.div(".placeholder")); + event.dialog.add(ui.create.div(".placeholder")); + event.dialog.add(ui.create.div(".placeholder")); game.pause(); - } - else{ + } else { var ctrl; - if(player.hp<=1){ - if(player.maxHp>3){ - ctrl=2; + if (player.hp <= 1) { + if (player.maxHp > 3) { + ctrl = 2; + } else { + ctrl = 3; } - else{ - ctrl=3; + } else if (player.hp == 2) { + if (player.maxHp > 4) { + ctrl = 2; + } else if (player.countCards("h") == 0) { + ctrl = 6; + } else { + ctrl = 3; } + } else if (player.countCards("h") < player.hp) { + ctrl = 6; + } else if (player.countCards("h") > player.hp + 1) { + ctrl = 5; } - else if(player.hp==2){ - if(player.maxHp>4){ - ctrl=2; - } - else if(player.countCards('h')==0){ - ctrl=6; - } - else{ - ctrl=3; - } - } - else if(player.countCards('h')player.hp+1){ - ctrl=5; - } - event.choice=ctrl; + event.choice = ctrl; } - "step 1" + "step 1"; ui.auto.show(); - player.storage.mailun=event.choice; - game.addVideo('storage',player,['mailun',player.storage.mailun]); - if(event.choice){ - player.logSkill('mailun'); - player.markSkill('mailun'); - switch(event.choice){ - case 1:{ + player.storage.mailun = event.choice; + game.addVideo("storage", player, ["mailun", player.storage.mailun]); + if (event.choice) { + player.logSkill("mailun"); + player.markSkill("mailun"); + switch (event.choice) { + case 1: { player.loseHp(); player.gainMaxHp(); break; } - case 2:{ + case 2: { player.recover(); player.loseMaxHp(); break; } - case 3:{ - player.addSkill('mailun31'); - player.addSkill('mailun32'); + case 3: { + player.addSkill("mailun31"); + player.addSkill("mailun32"); break; } - case 4:{ - player.addSkill('mailun41'); - player.addSkill('mailun42'); + case 4: { + player.addSkill("mailun41"); + player.addSkill("mailun42"); break; } - case 5:{ - player.addSkill('mailun5'); + case 5: { + player.addSkill("mailun5"); break; } - case 6:{ - player.addSkill('mailun6'); + case 6: { + player.addSkill("mailun6"); break; } - case 7:{ - player.addSkill('mailun7'); + case 7: { + player.addSkill("mailun7"); break; } - case 8:{ - player.addSkill('mailun8'); + case 8: { + player.addSkill("mailun8"); break; } } + } else { + player.unmarkSkill("mailun"); } - else{ - player.unmarkSkill('mailun'); - } - if(event.dialog){ + if (event.dialog) { event.dialog.close(); } - if(event.control){ + if (event.control) { event.control.close(); } - } + }, }, - mailun31:{ - trigger:{source:'damageBegin'}, - forced:true, - content:function(){ + mailun31: { + trigger: { source: "damageBegin" }, + forced: true, + content: function () { trigger.num--; - player.removeSkill('mailun31'); - } + player.removeSkill("mailun31"); + }, }, - mailun32:{ - trigger:{player:'damageBegin'}, - forced:true, - content:function(){ + mailun32: { + trigger: { player: "damageBegin" }, + forced: true, + content: function () { trigger.num--; - player.removeSkill('mailun32'); - } + player.removeSkill("mailun32"); + }, }, - mailun41:{ - trigger:{source:'damageBegin'}, - forced:true, - content:function(){ + mailun41: { + trigger: { source: "damageBegin" }, + forced: true, + content: function () { trigger.num++; - player.removeSkill('mailun41'); - } + player.removeSkill("mailun41"); + }, }, - mailun42:{ - trigger:{player:'damageBegin'}, - forced:true, - content:function(){ + mailun42: { + trigger: { player: "damageBegin" }, + forced: true, + content: function () { trigger.num++; - player.removeSkill('mailun42'); - } + player.removeSkill("mailun42"); + }, }, - mailun5:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - popup:false, - content:function(){ + mailun5: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + popup: false, + content: function () { trigger.num--; }, - mod:{ - maxHandcard:function(player,num){ - return num+1; - } - } - }, - mailun6:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - popup:false, - content:function(){ - trigger.num++; - }, - mod:{ - maxHandcard:function(player,num){ - return num-1; - } - } - }, - mailun7:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance-1; + mod: { + maxHandcard: function (player, num) { + return num + 1; }, - globalTo:function(from,to,distance){ - return distance-1; - } - } - }, - mailun8:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance+1; - }, - globalTo:function(from,to,distance){ - return distance+1; - } - } - }, - fengming:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0; }, - filterCard:{type:'equip'}, - position:'he', - filterTarget:true, - content:function(){ - "step 0" + }, + mailun6: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + popup: false, + content: function () { + trigger.num++; + }, + mod: { + maxHandcard: function (player, num) { + return num - 1; + }, + }, + }, + mailun7: { + mod: { + globalFrom: function (from, to, distance) { + return distance - 1; + }, + globalTo: function (from, to, distance) { + return distance - 1; + }, + }, + }, + mailun8: { + mod: { + globalFrom: function (from, to, distance) { + return distance + 1; + }, + globalTo: function (from, to, distance) { + return distance + 1; + }, + }, + }, + fengming: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; + }, + filterCard: { type: "equip" }, + position: "he", + filterTarget: true, + content: function () { + "step 0"; target.recover(); - "step 1" + "step 1"; target.draw(); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(target.hp0; + wanjun: { + enable: "chooseToUse", + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; }, - filterCard:function(card){ - return get.type(card)=='equip'; + filterCard: function (card) { + return get.type(card) == "equip"; }, - position:'he', - viewAs:{name:'nanman'}, - prompt:'将一张装备牌当南蛮入侵使用', - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); + position: "he", + viewAs: { name: "nanman" }, + prompt: "将一张装备牌当南蛮入侵使用", + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - if(player.countCards('h')0){ - return att+5; + huanling: { + trigger: { player: "phaseEnd" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("huanling"), function (card, player, target) { + return player != target; + }).ai = function (target) { + if (target.hasSkillTag("noturn")) return 0; + var att = get.attitude(player, target); + if (target.isTurnedOver()) { + if (att > 0) { + return att + 5; } return -1; } - if(player.isTurnedOver()){ - return 5-att; + if (player.isTurnedOver()) { + return 5 - att; } - if(att<=-3){ + if (att <= -3) { return -att; } return 0; }; - "step 1" - if(result.bool){ - player.logSkill('huanling',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("huanling", result.targets); player.turnOver(); result.targets[0].turnOver(); } }, - group:'huanling2', - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='guiyoujie') return [0,2]; - if(target.isTurnedOver()){ - if(get.tag(card,'damage')) return 0; + group: "huanling2", + ai: { + effect: { + target: function (card, player, target, current) { + if (card.name == "guiyoujie") return [0, 2]; + if (target.isTurnedOver()) { + if (get.tag(card, "damage")) return 0; } - } + }, }, - expose:0.2 - } + expose: 0.2, + }, }, - huanling2:{ - trigger:{player:'damageBefore'}, - filter:function(event,player){ + huanling2: { + trigger: { player: "damageBefore" }, + filter: function (event, player) { return player.isTurnedOver(); }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); }, }, - ljifeng:{ - mod:{ - selectTarget:function(card,player,range){ - if(card.name=='sha'&&range[1]!=-1) range[1]+=player.maxHp-player.hp; + ljifeng: { + mod: { + selectTarget: function (card, player, range) { + if (card.name == "sha" && range[1] != -1) range[1] += player.maxHp - player.hp; + }, + attackFrom: function (from, to, distance) { + return distance + from.hp - from.maxHp; }, - attackFrom:function(from,to,distance){ - return distance+from.hp-from.maxHp; - } }, }, - ljifeng_old:{ - trigger:{player:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + ljifeng_old: { + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" - var check=player.countCards('h')<=player.hp+(player.hp>2?2:1); + content: function () { + "step 0"; + var check = player.countCards("h") <= player.hp + (player.hp > 2 ? 2 : 1); player.chooseCardTarget({ - prompt:get.prompt('ljifeng'), - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - if(player==target) return false; - return player.canUse({name:'sha'},target,false); + prompt: get.prompt("ljifeng"), + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + if (player == target) return false; + return player.canUse({ name: "sha" }, target, false); }, - selectTarget:[1,2], - ai1:function(card){ - if(!check) return 0; - return 8-get.value(card); + selectTarget: [1, 2], + ai1: function (card) { + if (!check) return 0; + return 8 - get.value(card); + }, + ai2: function (target) { + if (!check) return 0; + return get.effect(target, { name: "sha" }, player); }, - ai2:function(target){ - if(!check) return 0; - return get.effect(target,{name:'sha'},player); - } }); - "step 1" - if(result.bool){ - player.logSkill('ljifeng',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("ljifeng", result.targets); player.discard(result.cards); - player.useCard({name:'sha'},result.targets).animate=false; + player.useCard({ name: "sha" }, result.targets).animate = false; trigger.cancel(); } - } + }, }, - lxianglong:{ - trigger:{target:'shaMiss'}, - priority:5, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(function(card,player,target){ - return player.canUse('sha',target); - },get.prompt('lxianglong')).ai=function(target){ - return get.effect(target,{name:'sha'},player,player); - } - "step 1" - if(result.bool){ - player.logSkill('lxianglong',result.targets); - player.useCard({name:'sha'},trigger.cards,result.targets).animate=false; + lxianglong: { + trigger: { target: "shaMiss" }, + priority: 5, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(function (card, player, target) { + return player.canUse("sha", target); + }, get.prompt("lxianglong")).ai = function (target) { + return get.effect(target, { name: "sha" }, player, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("lxianglong", result.targets); + player.useCard({ name: "sha" }, trigger.cards, result.targets).animate = false; game.delay(); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='sha'&&target.countCards('h')) return 0.7; - } - } - } - }, - zhenjiu:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'red'}, - filterTarget:function(card,player,target){ - return !target.hasSkill('zhenjiu2'); - }, - check:function(card){ - return 8-get.value(card); - }, - discard:false, - prepare:'give', - content:function(){ - target.storage.zhenjiu2=cards[0]; - game.addVideo('storage',target,['zhenjiu2',get.cardInfo(target.storage.zhenjiu2),'card']); - target.addSkill('zhenjiu2'); - }, - ai:{ - result:{ - target:function(player,target){ - if(target.hpplayer.hp) return 0.5; - return 0; - } + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "sha" && target.countCards("h")) return 0.7; + }, }, - order:9, - threaten:1.7 - } + }, }, - zhenjiu2:{ - trigger:{player:'phaseBegin'}, - forced:true, - mark:'card', - content:function(){ + zhenjiu: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "red" }, + filterTarget: function (card, player, target) { + return !target.hasSkill("zhenjiu2"); + }, + check: function (card) { + return 8 - get.value(card); + }, + discard: false, + prepare: "give", + content: function () { + target.storage.zhenjiu2 = cards[0]; + game.addVideo("storage", target, [ + "zhenjiu2", + get.cardInfo(target.storage.zhenjiu2), + "card", + ]); + target.addSkill("zhenjiu2"); + }, + ai: { + result: { + target: function (player, target) { + if (target.hp < target.maxHp) { + return target == player ? 1 : 1.5; + } + if (player.countCards("h") > player.hp) return 0.5; + return 0; + }, + }, + order: 9, + threaten: 1.7, + }, + }, + zhenjiu2: { + trigger: { player: "phaseBegin" }, + forced: true, + mark: "card", + content: function () { player.recover(); - player.gain(player.storage.zhenjiu2,'gain2','log'); - player.removeSkill('zhenjiu2'); + player.gain(player.storage.zhenjiu2, "gain2", "log"); + player.removeSkill("zhenjiu2"); delete player.storage.zhenjiu2; }, - intro:{ - content:'card' - } - }, - shoulie:{ - trigger:{player:'shaBegin'}, - direct:true, - content:function(){ - "step 0" - var dis=trigger.target.countCards('h','shan')||trigger.target.hasSkillTag('freeShan',false,{ - player:player, - card:trigger.card - },true)||trigger.target.countCards('h')>2; - var next=player.chooseToDiscard(get.prompt('shoulie',trigger.target)); - next.ai=function(card){ - if(dis) return 7-get.value(card); - return 0; - } - next.logSkill='shoulie'; - "step 1" - if(result.bool){ - trigger.directHit=true; - } - } - }, - hudun:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return !player.hujia&&event.player!=player; + intro: { + content: "card", }, - content:function(){ + }, + shoulie: { + trigger: { player: "shaBegin" }, + direct: true, + content: function () { + "step 0"; + var dis = + trigger.target.countCards("h", "shan") || + trigger.target.hasSkillTag( + "freeShan", + false, + { + player: player, + card: trigger.card, + }, + true + ) || + trigger.target.countCards("h") > 2; + var next = player.chooseToDiscard(get.prompt("shoulie", trigger.target)); + next.ai = function (card) { + if (dis) return 7 - get.value(card); + return 0; + }; + next.logSkill = "shoulie"; + "step 1"; + if (result.bool) { + trigger.directHit = true; + } + }, + }, + hudun: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return !player.hujia && event.player != player; + }, + content: function () { player.changeHujia(); player.update(); }, }, - toudan:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',{suit:'spade'}); + toudan: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he", { suit: "spade" }); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - filterCard:{suit:'spade'}, - check:function(card){ - return 10-get.value(card); + filterCard: { suit: "spade" }, + check: function (card) { + return 10 - get.value(card); }, - position:'he', - line:'fire', - content:function(){ - "step 0" - target.damage('fire'); - event.targets=game.filterPlayer(function(current){ - return get.distance(target,current)<=1; + position: "he", + line: "fire", + content: function () { + "step 0"; + target.damage("fire"); + event.targets = game.filterPlayer(function (current) { + return get.distance(target, current) <= 1; }); event.targets.sortBySeat(event.target); event.targets.unshift(player); - "step 1" - if(event.targets.length){ - var current=event.targets.shift(); - if(current.countCards('he')){ - current.chooseToDiscard('he',true); + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); + if (current.countCards("he")) { + current.chooseToDiscard("he", true); } event.redo(); } }, - ai:{ - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'fire'); - } + ai: { + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "fire"); + }, }, - order:10, - threaten:1.5 - } + order: 10, + threaten: 1.5, + }, }, - shending:{ - inherit:'longfan', - filter:function(event,player){ + shending: { + inherit: "longfan", + filter: function (event, player) { return !player.getEquip(5); }, - ai:{ - order:11, - result:{ - player:1, + ai: { + order: 11, + result: { + player: 1, }, - effect:{ - target:function(card,player,target){ - if(player!=target) return; - if(get.subtype(card)=='equip5'){ - if(get.equipValue(card)<=7) return 0; + effect: { + target: function (card, player, target) { + if (player != target) return; + if (get.subtype(card) == "equip5") { + if (get.equipValue(card) <= 7) return 0; } - } + }, }, - threaten:1.2 - } + threaten: 1.2, + }, }, - poxiao:{ - mod:{ - attackFrom:function(from,to,distance){ - if(!from.getEquip(1)) return distance-1; + poxiao: { + mod: { + attackFrom: function (from, to, distance) { + if (!from.getEquip(1)) return distance - 1; }, - selectTarget:function(card,player,range){ - if(!player.getEquip(1)&&card.name=='sha') range[1]++; - } - }, - enable:'chooseToUse', - filterCard:{type:'equip'}, - filter:function(event,player){ - return player.countCards('he',{type:'equip'}); - }, - position:'he', - viewAs:{name:'sha'}, - prompt:'将一张闪当杀使用或打出', - check:function(card){ - if(get.subtype(card)=='equip1') return 10-get.value(card); - return 7-get.equipValue(card); - }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; + selectTarget: function (card, player, range) { + if (!player.getEquip(1) && card.name == "sha") range[1]++; }, - effect:{ - target:function(card,player){ - if(get.subtype(card)=='equip1'){ - var num=0,players=game.filterPlayer(); - for(var i=0;i1) return 'zeroplayertarget'; + if (num > 1) return "zeroplayertarget"; } } } - } - } - } + }, + }, + }, }, }, - translate:{ - swd_yangshuo:'杨硕', - swd_septem:'赛特', - swd_yuxiaoxue:'于小雪', - swd_lilian:'莉莲', - swd_cheyun:'车芸', - swd_jipeng:'疾鹏', - swd_muyun:'徐暮云', - swd_zhaoyun:'皇甫朝云', - swd_jiliang:'姬良', - swd_lanyin:'兰茵', - swd_zhiyin:'芝茵', - swd_hengai:'横艾', - swd_huzhongxian:'壶中仙', - swd_qiner:'磬儿', - swd_huanyuanzhi:'桓远之', - swd_murongshi:'慕容诗', - swd_hupo:'琥珀', - swd_miles:'麦尔斯', - swd_kangnalishi:'康那里士', - swd_satan:'撒旦', - swd_philis:'菲力斯', - swd_weida:'薇达', - swd_fengtianling:'凤天凌', - swd_huyue:'瑚月', - swd_jiting:'姬亭', - swd_rongshuang:'蓉霜', - swd_zhuoshanzhu:'浊山铸', - swd_jialanduo:'迦兰多', - swd_linming:'林明', - swd_duanmeng:'端蒙', - swd_nicole:'妮可', - swd_kendi:'肯迪', - swd_lijing:'李靖', - swd_hanteng:'韩腾', - swd_yuwentuo:'宇文拓', - swd_shanxiaoxiao:'单小小', - swd_yuchiyanhong:'尉迟嫣红', - swd_pepin:'丕平', - swd_anka:'安卡', - swd_jiangwu:'疆梧', - swd_situqiang:'司徒蔷', - swd_tuwei:'徒维', - swd_yeyaxi:'耶亚希', - swd_chunyuheng:'淳于恒', - swd_duguningke:'独孤宁珂', - swd_duguningke2:'魔化宁珂', - swd_chenjingchou:'陈靖仇', - swd_zhanglie:'张烈', - swd_guyue:'古月圣', - swd_kama:'卡玛', - swd_yuli:'玉澧', - swd_duopeng:'多鹏', - swd_jiangziya:'姜子牙', - swd_heran:'何然', - swd_zhanggao:'张诰', - swd_hanlong:'韩龙', - swd_jiuyou:'久悠', - swd_qingming:'青冥', - swd_shangzhang:'尚章', - swd_youzhao:'游兆', - swd_wangsiyue:'王思月', - swd_huanglei:'黄雷', - swd_tuobayuer:'拓跋玉儿', - swd_tuobayueer:'拓跋月儿', - swd_chengyaojin:'程咬金', - swd_qinshubao:'秦叔宝', - swd_lishimin:'李世民', - swd_shuijing:'水镜', - swd_xuanyuanjianxian:'轩辕剑仙', - swd_xuanyuanjiantong:'轩辕剑童', - swd_luchengxuan:'陆承轩', - swd_xiarou:'夏柔', - swd_moye:'莫耶', - swd_fu:'毛民·福', - swd_hanluo:'寒洛', - swd_linyue:'临月', - swd_zidashu:'子大暑', - swd_maixing:'麦星', - swd_haidapang:'海大胖', - swd_shaowei:'少微', - swd_fuyan:'符验', - swd_huiyan:'慧彦', - swd_sikongyu:'司空宇', - swd_muyue:'沐月', - swd_ziqiao:'子巧', - swd_fengyu:'凤煜', - swd_qi:'柒', - swd_chenfu:'陈辅', - swd_libai:'李白', - swd_xingtian:'刑天', - swd_lanmoshen:'蓝魔神', - swd_wushi:'巫师', - swd_quxian:'屈娴', - swd_xiyan:'犀衍', - swd_shuwaner:'舒莞儿', - swd_xiaohuanglong:'小黄龙', + translate: { + swd_yangshuo: "杨硕", + swd_septem: "赛特", + swd_yuxiaoxue: "于小雪", + swd_lilian: "莉莲", + swd_cheyun: "车芸", + swd_jipeng: "疾鹏", + swd_muyun: "徐暮云", + swd_zhaoyun: "皇甫朝云", + swd_jiliang: "姬良", + swd_lanyin: "兰茵", + swd_zhiyin: "芝茵", + swd_hengai: "横艾", + swd_huzhongxian: "壶中仙", + swd_qiner: "磬儿", + swd_huanyuanzhi: "桓远之", + swd_murongshi: "慕容诗", + swd_hupo: "琥珀", + swd_miles: "麦尔斯", + swd_kangnalishi: "康那里士", + swd_satan: "撒旦", + swd_philis: "菲力斯", + swd_weida: "薇达", + swd_fengtianling: "凤天凌", + swd_huyue: "瑚月", + swd_jiting: "姬亭", + swd_rongshuang: "蓉霜", + swd_zhuoshanzhu: "浊山铸", + swd_jialanduo: "迦兰多", + swd_linming: "林明", + swd_duanmeng: "端蒙", + swd_nicole: "妮可", + swd_kendi: "肯迪", + swd_lijing: "李靖", + swd_hanteng: "韩腾", + swd_yuwentuo: "宇文拓", + swd_shanxiaoxiao: "单小小", + swd_yuchiyanhong: "尉迟嫣红", + swd_pepin: "丕平", + swd_anka: "安卡", + swd_jiangwu: "疆梧", + swd_situqiang: "司徒蔷", + swd_tuwei: "徒维", + swd_yeyaxi: "耶亚希", + swd_chunyuheng: "淳于恒", + swd_duguningke: "独孤宁珂", + swd_duguningke2: "魔化宁珂", + swd_chenjingchou: "陈靖仇", + swd_zhanglie: "张烈", + swd_guyue: "古月圣", + swd_kama: "卡玛", + swd_yuli: "玉澧", + swd_duopeng: "多鹏", + swd_jiangziya: "姜子牙", + swd_heran: "何然", + swd_zhanggao: "张诰", + swd_hanlong: "韩龙", + swd_jiuyou: "久悠", + swd_qingming: "青冥", + swd_shangzhang: "尚章", + swd_youzhao: "游兆", + swd_wangsiyue: "王思月", + swd_huanglei: "黄雷", + swd_tuobayuer: "拓跋玉儿", + swd_tuobayueer: "拓跋月儿", + swd_chengyaojin: "程咬金", + swd_qinshubao: "秦叔宝", + swd_lishimin: "李世民", + swd_shuijing: "水镜", + swd_xuanyuanjianxian: "轩辕剑仙", + swd_xuanyuanjiantong: "轩辕剑童", + swd_luchengxuan: "陆承轩", + swd_xiarou: "夏柔", + swd_moye: "莫耶", + swd_fu: "毛民·福", + swd_hanluo: "寒洛", + swd_linyue: "临月", + swd_zidashu: "子大暑", + swd_maixing: "麦星", + swd_haidapang: "海大胖", + swd_shaowei: "少微", + swd_fuyan: "符验", + swd_huiyan: "慧彦", + swd_sikongyu: "司空宇", + swd_muyue: "沐月", + swd_ziqiao: "子巧", + swd_fengyu: "凤煜", + swd_qi: "柒", + swd_chenfu: "陈辅", + swd_libai: "李白", + swd_xingtian: "刑天", + swd_lanmoshen: "蓝魔神", + swd_wushi: "巫师", + swd_quxian: "屈娴", + swd_xiyan: "犀衍", + swd_shuwaner: "舒莞儿", + swd_xiaohuanglong: "小黄龙", - cyshuiyun:'水云', - cyshuiyun_info:'准备阶段,你可以弃置一名其他角色的一张牌;每当你失去此技能,你可以弃置一名其他角色的一张牌。', - cyliuzi:'流紫', - cyliuzi_info:'摸牌阶段,你可以额外摸一张牌;每当你失去此技能,你可以摸一张牌。', - cyyijin:'异金', - cyyijin_info:'出牌阶段,你可以对一名体力值为全场最多的角色造成1点伤害;每当你失去此技能,你可以对一名体力值为全场最多的角色造成1点伤害。', - cyqingling:'青凌', - cyqingling_info:'弃牌阶段,若你弃置了至少一张牌,你可以获得1点护甲;每当你失去此技能,你可以获得1点护甲。', - cyqiandian:'千靛', - cyqiandian_info:'结束阶段,你可以视为使用一张惊雷闪;每当你失去此技能,你可以视为使用一张惊雷闪。', - gxianyin:'仙音', - gxianyin_info:'出牌阶段限一次,你可以选择一种花色,将你的手牌中该花色的牌移至弃牌堆,然后选择另一种花色,从牌堆中获得等量的该花色的牌。', + cyshuiyun: "水云", + cyshuiyun_info: + "准备阶段,你可以弃置一名其他角色的一张牌;每当你失去此技能,你可以弃置一名其他角色的一张牌。", + cyliuzi: "流紫", + cyliuzi_info: "摸牌阶段,你可以额外摸一张牌;每当你失去此技能,你可以摸一张牌。", + cyyijin: "异金", + cyyijin_info: + "出牌阶段,你可以对一名体力值为全场最多的角色造成1点伤害;每当你失去此技能,你可以对一名体力值为全场最多的角色造成1点伤害。", + cyqingling: "青凌", + cyqingling_info: + "弃牌阶段,若你弃置了至少一张牌,你可以获得1点护甲;每当你失去此技能,你可以获得1点护甲。", + cyqiandian: "千靛", + cyqiandian_info: + "结束阶段,你可以视为使用一张惊雷闪;每当你失去此技能,你可以视为使用一张惊雷闪。", + gxianyin: "仙音", + gxianyin_info: + "出牌阶段限一次,你可以选择一种花色,将你的手牌中该花色的牌移至弃牌堆,然后选择另一种花色,从牌堆中获得等量的该花色的牌。", // gxianyin_info_alter:'', - cyxianjiang:'仙匠', - cyxianjiang_info:'每当你使用一张牌指定唯一目标时,你可以复制对方装备区内的一张你没有的牌,并置入你的装备区,每回合对一名角色最多发动一次。', - cyqiaoxie:'巧械', - cyqiaoxie_info:'每当你失去一张装备牌(使用除外),你可以随机观看三张机关牌,并使用其中一张。', - cyqiaoxie_info_alter:'每当你装备一件装备,若你的手牌数不大于体力值,你可以摸一张牌;每当你失去一件装备牌,你可以随机观看2张机关牌,并使用其中一张。', - cyzhencha:'侦察', - cyzhencha_info:'出牌阶段限一次,若你的装备区内的可强化装备,你可以弃置一张基本牌并观看一名其他角色的手牌,若其中有与你弃置的牌颜色相同的牌,你随机升级装备区内的一件装备,否则你摸一张牌;你根据装备区内升级的装备数获得额外技能。', - cylingjia:'灵甲', - cylingjia_info:'出牌阶段限一次,你可以弃置一张装备牌,然后令云狐随机装备一件装备(不替换现有装备)并将其强化。', - cyqiaobo:'巧补', - cyqiaobo_info:'出牌阶段限一次,你可以弃置一张锦囊牌,然后令云狐回复1点体力。', - cqiaoxie:'巧械', - cqiaoxie_info:'出牌阶段限一次,你可以将一张锦囊牌当作零件袋使用;每当你使用一张零件牌,你获得1点技能点数。', - xiufu:'修复', - xiufu_info:'出牌阶段,你可以弃置一张装备牌或机关牌,令云狐回复1点体力。', - yhshengong:'神工', - yhshengong_info:'游戏开始时,你获得3点技能点数;每当你造成1点伤害,你获得1点技能点数;出牌阶段,你可以通过消耗技能点令云狐获得新的技能(云狐体力为0时无法学习或发动技能)。', - juxi:'聚息', - juxi_info:'锁定技,每当一名角色于其回合外弃置牌,你获得一枚聚息标记;出牌阶段限一次,你可以移去X枚聚息标记,然后选择一项:对一名角造成1点伤害,或令一名角色回复1点体力,X为存活角色数。', - yeying:'曳影', - yeying_info:'出牌阶段限一次,你可以将一张黑色牌当作乾坤镖使用。', - jiefen:'解纷', - jiefen_info:'出牌阶段限一次,你可以令一名手牌数多于你的角色交给你一张牌,然后你交给一名手牌数少于你的角色一张牌。', - datong:'大同', - datong_info:'任意一名角色的结束阶段,若全场手牌数最多和最少的角色手牌数之差不超过1,你摸两张牌。', - huodan:'火丹', - huodan_info:'出牌阶段限一次,你可以弃置一张红色牌并失去1点体力,然后将2点火属性伤害分配给1~2名角色。', - huodan_info_alter:'出牌阶段限一次,你可以弃置一张红色牌并失去1点体力,然后将2点火属性伤害分配给1~2名角色;若你只分配了一名角色,该角色在结算后摸一张牌。', - sxianjing:'陷阱', - sxianjing_bg:'阱', - sxianjing_info:'出牌阶段,你可以将一张手牌背面朝上置于你的武将牌上(不能与已有花色相同)。当一名其他角色使用与一张“陷阱”牌花色相同的牌指定你为目标时,你移去对应的“陷阱”牌,然后随机获得该角色的一张牌。每当你受到一次伤害,你随机将一张“陷阱”牌返回手牌。', - zhanxing:'占星', - zhanxing_info:'出牌阶段限一次,你可以弃置任意张牌,并亮出牌堆顶的等量的牌,并根据亮出的牌包含的花色执行以下效果:♦︎摸两张牌;♥回复1点体力(若未损失体力改为获得1点护甲);♣令所有敌人随机弃置一张牌;♠令一名角色受到1点无来源的雷属性伤害。', - kbolan:'博览', - kbolan_info:'每当你摸牌时,你可以额外摸一张牌,然后摸牌结束时将一张手牌置于牌堆顶。', - gaizao:'改造', - gaizao_info:'每当你即将装备一张牌(特殊类装备除外),若你的装备区内对应位置已有牌,你可以永久改变此牌的装备类型使其装备在装备区内的空余位置。', - lingshi:'灵矢', - lingshi_info:'你的装备区内每有一张牌,你的攻击范围+2;当你的装备区内有武器牌或防具牌时,你的杀不可闪避;当你的装备区内有马时,你摸牌阶段额外摸一张牌;当你的装备内的宝物牌时,你回合内可以额外使用一张杀。', - tiebi:'铁壁', - tiebi_info:'当距离你1以内的一名角色成为杀的目标时,若其没有护甲,你可以弃置一张黑色手牌使其获得1点护甲。', - shenyan:'神炎', - shenyan_bg:'炎', - shenyan_info:'限定技,当你即将造成火焰伤害时,你可以令此伤害+1,并对目标距离1以内的所有其他角色各造成1点火焰伤害。', - xuanying:'旋影', - xuanying_info:'你可以横置你的武将牌,视为使用一张无视距离的杀;每当你于回合外失去牌,你可以竖置你的武将牌,视为使用一张无视距离的杀。', - hwendao:'问道', - hwendao_info:'每当你于回合外使用或打出一张牌,你可以令当前回合角色弃置一张与之花色相同的牌,否则你获得其一张牌。', - lingfeng:'凌锋', - lingfeng_info:'结束阶段,若你本回合内使用了至少X张牌,你可以选择一项:获得1点护甲,或对攻击范围内的一名角色造成1点伤害(X为你当前的体力值且最多为3)。', - hxunzhi:'殉志', - hxunzhi_info:'限定技,出牌阶段,你可以视为使用一张万箭齐发并获得技能武圣、咆哮,若如此做,你在此阶段结束时死亡。', - hxunzhi_info_alter:'限定技,出牌阶段,你可以获得技能武圣、咆哮,若如此做,你在此阶段结束时死亡。', - lmazui:'麻醉', - lmazui2:'麻醉', - lmazui_info:'出牌阶段限一次,你可以将一张黑色手牌置于一名角色的武将牌上,该角色造成的下一次伤害-1,然后获得此牌。', - hyunshen:'云身', - hyunshen2:'云身', - hyunshen_info:'每当你打出一张闪,你可以令你的防御距离+1;准备阶段,你将累计的防御距离清零,然后摸等量的牌。', - hlingbo:'凌波', - hlingbo_info:'每当你使用或打出一张闪,你可以摸两张牌。', - gtiandao:'天道', - gtiandao_info:'任意一名角色的判定生效前,你可以打出一张牌替换之。', - nlianji:'连计', - nlianji_info:'出牌阶段限一次,你可以选择一张手牌并指定两名角色进行拼点。若拼点结果不为平局,拼点赢的角色获得此牌,并对没赢的角色造成1点伤害。', - fengze:'风泽', - fengze_info:'出牌阶段限一次,你可以将一张黑色牌当作桃园结义使用。', - lingyue:'凌月', - lingyue_info:'每当你使用一张杀,你可以令目标弃置一张牌。', - jinlin:'金鳞', - jinlin_info:'限定技,出牌阶段,你可以令任意名角色各获得3点护甲,获得护甲的角色于每个准备阶段失去1点护甲,直到首次失去所有护甲或累计以此法失去3点护甲。', - huanxia:'幻霞', - huanxia_info:'你可以将一张红色牌当作杀使用,若此杀未造成伤害,你在结束阶段收回此牌。', - jingjie:'幻镜', - jingjie_info:'限定技,出牌阶段,你可以令所有角色弃置所有牌,然后摸两张牌(不触发任何技能)。', - kongmo:'恐魔', - kongmo_info:'锁定技,你使用基本牌或普通锦囊牌后将额外结算一次卡牌效果。', - jufu:'巨斧', - jufu_info:'锁定技,当你有武器牌时,杀造成的伤害+1。', - huajing:'化精', - huajing_info:'每当你使用锦囊牌造成伤害,可以回复1点体力并摸一张牌。', - pingxu:'冯虚', - pingxu_info:'锁定技,当你没有武器牌时,你的进攻距离+1;当你没有防具牌时,你的防御距离+1。', - yudun:'愚钝', - yudun_info:'锁定技,你无法使用锦囊牌;你可以将两张锦囊牌当作一张不计入出杀次数的杀使用。', - bingfeng:'冰封', - bingfeng2:'冰封', - bingfeng2_info:'不能使用或打出手牌。', - bingfeng_info:'限定技,出牌阶段,你可以指定至多三个目标与其一同翻面,且处于翻面状态时不能使用或打出手牌;若如此做,你失去技能玄咒并减少1点体力上限。', - guozao:'聒噪', - guozao_info:'锁定技,每当距离你1以内的角色受到一次伤害,若伤害来源不你,你须观看牌堆顶的三张牌,然后指定距离2以内的一名有手牌角色将手牌与这些牌交换。', - guozao_info_alter:'锁定技,每当距离你1以内的角色受到一次伤害,若伤害来源不你,你须观看牌堆顶的三张牌,然后指定距离1以内的一名有手牌角色将手牌与这些牌交换。', - heihuo:'黑火', - heihuo_info:'出牌阶段,你可以弃置一张装备牌,令你的手牌数加倍;若你的手牌因此达到8张或更多,你立即受到3点火焰伤害且本回合内不能再次发动黑火。', - yaotong:'妖瞳', - yaotong1:'妖瞳', - yaotong2:'妖瞳', - yaotong3:'妖瞳', - yaotong4:'妖瞳', - yaotong_info:'当你的手牌数为奇数时,你可以将一张手牌当作杀或闪使用或打出,当你的手牌数为偶数时,你可以将一张手牌当作无懈可击使用。', - yaotong_info_alter:'当你的手牌数为奇数时,你可以将一张手牌当作杀使用或打出,当你的手牌数为偶数时,你可以将一张手牌当作无懈可击使用。', - pojian:'破茧', - pojian_info:'每当你失去最后一张手牌,可以从牌堆中获得一张装备牌并装备之。', - huajin:'化金', - huajin2:'化金', - huajin_info:'出牌阶段限一次,你可以弃置一张牌令你造成的伤害+1,直到你的下一回合开始。', - poxiao:'破霄', - poxiao_info:'你可以将一张装备牌当杀使用;当你没有武器牌时,你的攻击范围+1,杀可以额外指定一个目标。', - jianji:'箭疾', - jianji_info:'你可以将一张装备牌当杀使用,然后摸一张牌,此杀无视距离和防具,且不计入回合内出杀限制。', - yuchen:'浴尘', - yuchen_info:'每当你于回合外使用或打出一张黑色牌,你可以弃置一名角色的一张牌。', - huangyu:'凰羽', - huangyu_info:'出牌阶段限一次,你可以将两张红色牌当炽羽袭使用。', - bingjian:'冰箭', - bingjian_info:'出牌阶段限一次,你可以弃置一张黑色的杀,令一名有手牌的其他角色展示手牌并弃置其中的所有闪,若其没有闪则受到1点雷电伤害。', - rumeng:'入梦', - rumeng_info:'其他角色的出牌阶段前,你可以弃置一张非基本牌,并令其选择一项:弃置一张基本牌,或跳过出牌及弃牌阶段。', - lianda:'连打', - lianda_info:'当你使用一杀结算完毕后,可以弃置一张牌视为对目标再使用一张杀。', - xianghui:'祥晖', - xianghui_info:'出牌阶段限一次,你可以弃置一张红色手牌,然后令场上体力值最少的角色各回复1点体力。', - huiqi:'回气', - huiqi_info:'每当你受到一次伤害,可令一名其他角色摸X张牌,X为你已损失的体力值。', - toudan:'投弹', - toudan_info:'出牌阶段限一次,你可以弃置一张黑桃牌对一名其他角色造成1点火焰伤害,然后你与距离该角色1以内的所有角色各弃置一张牌。', - shending:'神丁', - shending_info:'锁定技,若你没有宝物牌,视为装备了蓝格怪衣。', - hzhenwei:'镇卫', - hzhenwei_info:'当一名其他角色成为杀的目标后,若你在杀的使用者的攻击范围内,你可以弃置一张牌将此杀转移给自己,并在杀结算完毕后摸一张牌。', - shoulie:'狩猎', - shoulie_info:'当你使用一张杀指定目标后,可以弃置一张手牌令此杀不可闪避。', - hudun:'盾甲', - hudun_bg:'盾', - hudun2:'盾甲', - hudun_info:'锁定技,当你对其他角色造成伤害后,若你没有护甲,你获得1点护甲值。', - zhenjiu:'针灸', - zhenjiu2:'针灸', - zhenjiu_info:'出牌阶段限一次,你可以将一张红色手牌置于一名角色的武将牌上,该角色于下一个准备阶段回复1点体力,然后获得此牌。', - ljifeng:'疾风', - ljifeng_info:'锁定技,你的攻击范围+X,杀可以额外指定X个目标,X为你已损失的体力值。', - lxianglong:'翔龙', - lxianglong_info:'每当你闪避一张杀,你可以视为使用一张杀。', - shangxi:'伤袭', - shangxi_info:'准备阶段,你可以弃置一张牌,并对攻击范围内一名体力值不小于你的其他角色造成1点伤害。', - fzhenwei:'镇威', - fzhenwei_info:'在你的回合内,你可以将其他角色打出的卡牌交给除该角色外的任意一名角色。', - fuyan:'覆岩', - fuyan2:'覆岩', - fuyan_info:'每当你受到一次伤害,可以令一名没有护甲的角色获得1点护甲值。', - guaili:'怪力', - guaili_info:'锁定技,你的杀造成的伤害+1,造成伤害后需弃置两张手牌。', - pingshen:'凭神', - pingshen2:'凭神', - pingshen_info:'锁定技,受到过你的伤害的角色可在回合内对你发动一次【离魂】(每局限发动一次)。', - xingzhui:'星坠', - xingzhui_info:'出牌阶段限一次,你可以弃置一张牌,并令一名有牌的其他角色弃置一张类别相同的牌,否则受到1点伤害。', - lingxian:'凌仙', - lingxian_info:'每当你于回合外使用或打出一张手牌,你可以选择攻击范围外的一名其他角色与你各摸一张牌。', - shouyin:'守印', - shouyin_info:'限定技,当任意一名角色处于濒死状态时,若你的武将牌正朝上,可以将武将牌翻面,然后令场上所有存活角色将体力回复至体力上限。', - shouyin_info_alter:'限定技,当任意一名角色处于濒死状态时,若你的武将牌正朝上,可以将武将牌翻面,然后令场上所有存活角色回复2点体力。', - bofeng:'搏风', - bofeng_info:'锁定技,体力值不大于你的角色视为在你的攻击范围;当你使用杀指定目标时,可令目标额外打出一张闪,否则此杀不可闪避且造成的伤害+1。', - hutian:'护天', - hutian2:'护天', - hutian3:'护天', - hutian_info:'结束阶段,你可以将任意张牌置于一名角色的武将牌上,则该角色的体力值始终不能小于“护天”牌数;在你的下一个结束阶段,该角色获得武将牌上的“护天”牌(在此回合不能再次发动)。', - linyun:'凌云', - linyun_info:'你可以将两张牌当作杀使用,此杀需要额外一张闪才能闪避。', - sliufeng:'流风', - sliufeng_info:'锁定技,体力值不大于你的角色视为在你的攻击范围。', - chengjian:'承剑', - chengjian_info:'每当其他角色使用杀造成一次伤害,你可以令其摸一张牌。', - huanling:'幻灵', - huanling2:'幻灵', - huanling_info:'结束阶段,你可以选择一名角色与你同时翻面;翻面状态下,你防止一切伤害。', - xiaozhan:'消战', - xiaozhan_info:'其他角色使用杀时,若你不是杀的目标,可以弃置一张杀取消之。', - xielei:'挟雷', - xielei_info:'每当你使用或打出一张杀,可以弃置一张牌并对目标以外的一名角色造成1点雷电伤害。', - dangping:'荡平', - dangping_info:'每当你造成一次伤害,可以弃置一张手牌对其距离1以内的另一名角色造成1点伤害,每回合限一次。', - guisi:'归思', - guisi_info:'每当你成为杀的目标,你可以交给对方一张手牌并取消之。', - duishi:'对诗', - duishi_info:'出牌阶段,你可以弃置一张手牌,并指定一名有手牌的角色选择一项:1)弃置一张与之花色相同的手牌,本回合内对诗不能再次指定其为目标,2)令你获得其一张牌,对诗失效直到回合结束。', - anlianying:'连营', - anlianying_info:'每当你失去最后一张手牌,可摸两张牌。', - lianwu:'连舞', - lianwu_info:'锁定技,你的杀可以额外指定一个目标,你的红杀不可被闪避。', - jiying:'疾鹰', - jiying_info:'锁定技,你使用杀无视距离。', - daofa:'道法', - daofa_info:'每当有一名其他角色造成伤害,你可以令其弃置一张牌。', - xiaomoyu:'魔愈', - xiaomoyu_info:'锁定技,每当你于一个回合内首次造成伤害,你回复1点体力,若你没有受伤,则改为摸一张牌。', - yihua:'移花', - yihua_info:'每当你成为其他角色的某张卡牌的唯一目标时,你可以弃置两张手牌,将使用者与目标对调。', - youyin:'游吟', - youyin_info:'每当有其他角色弃置卡牌时,若其中有非基本牌且你的手牌数不超过5,你可以摸一张牌。', - rexue:'热血', - rexue_info:'任意一名角色的准备阶段,你可以对其使用一张杀,并摸一张牌。', - huopu:'火瀑', - huopu_info:'出牌阶段限一次,你可以将一张红桃牌当作流星火羽使用。', - benlei:'奔雷', - benlei2:'奔雷', - benlei_info:'你可以将三张牌当惊雷闪使用;每当你造成一次雷属性伤害,你回复1点体力。', - lingwu:'灵舞', - lingwu_info:'回合结束后,若你在本回合内使用的牌数不少于当前体力值,你可以进行一个额外的回合(不可重复发动)。', - miejing:'灭境', - miejing_info:'限制技,你可以弃置所有黑色牌,然后令所有其他角色受到1点雷电伤害。', - lingxin:'灵心', - lingxin_info:'结束阶段,你可以亮出牌堆顶的三张牌,然后获得其中的红桃牌。', - fushen:'附身', - fushen_info:'回合开始前,你可以将自己移出游戏,并代替另一名角色进行一回合,然后失去1点体力。', - fushen2:'附身', - wangchen:'忘尘', - wangchen_info:'弃牌阶段结束时,若你于此阶段弃置了基本牌,你可以令一名角色翻面。', - wangchen_info_alter:'弃牌阶段结束时,若你于此阶段弃置了基本牌,你可以令一名角色翻面并获得1点护甲。', + cyxianjiang: "仙匠", + cyxianjiang_info: + "每当你使用一张牌指定唯一目标时,你可以复制对方装备区内的一张你没有的牌,并置入你的装备区,每回合对一名角色最多发动一次。", + cyqiaoxie: "巧械", + cyqiaoxie_info: "每当你失去一张装备牌(使用除外),你可以随机观看三张机关牌,并使用其中一张。", + cyqiaoxie_info_alter: + "每当你装备一件装备,若你的手牌数不大于体力值,你可以摸一张牌;每当你失去一件装备牌,你可以随机观看2张机关牌,并使用其中一张。", + cyzhencha: "侦察", + cyzhencha_info: + "出牌阶段限一次,若你的装备区内的可强化装备,你可以弃置一张基本牌并观看一名其他角色的手牌,若其中有与你弃置的牌颜色相同的牌,你随机升级装备区内的一件装备,否则你摸一张牌;你根据装备区内升级的装备数获得额外技能。", + cylingjia: "灵甲", + cylingjia_info: + "出牌阶段限一次,你可以弃置一张装备牌,然后令云狐随机装备一件装备(不替换现有装备)并将其强化。", + cyqiaobo: "巧补", + cyqiaobo_info: "出牌阶段限一次,你可以弃置一张锦囊牌,然后令云狐回复1点体力。", + cqiaoxie: "巧械", + cqiaoxie_info: + "出牌阶段限一次,你可以将一张锦囊牌当作零件袋使用;每当你使用一张零件牌,你获得1点技能点数。", + xiufu: "修复", + xiufu_info: "出牌阶段,你可以弃置一张装备牌或机关牌,令云狐回复1点体力。", + yhshengong: "神工", + yhshengong_info: + "游戏开始时,你获得3点技能点数;每当你造成1点伤害,你获得1点技能点数;出牌阶段,你可以通过消耗技能点令云狐获得新的技能(云狐体力为0时无法学习或发动技能)。", + juxi: "聚息", + juxi_info: + "锁定技,每当一名角色于其回合外弃置牌,你获得一枚聚息标记;出牌阶段限一次,你可以移去X枚聚息标记,然后选择一项:对一名角造成1点伤害,或令一名角色回复1点体力,X为存活角色数。", + yeying: "曳影", + yeying_info: "出牌阶段限一次,你可以将一张黑色牌当作乾坤镖使用。", + jiefen: "解纷", + jiefen_info: + "出牌阶段限一次,你可以令一名手牌数多于你的角色交给你一张牌,然后你交给一名手牌数少于你的角色一张牌。", + datong: "大同", + datong_info: + "任意一名角色的结束阶段,若全场手牌数最多和最少的角色手牌数之差不超过1,你摸两张牌。", + huodan: "火丹", + huodan_info: + "出牌阶段限一次,你可以弃置一张红色牌并失去1点体力,然后将2点火属性伤害分配给1~2名角色。", + huodan_info_alter: + "出牌阶段限一次,你可以弃置一张红色牌并失去1点体力,然后将2点火属性伤害分配给1~2名角色;若你只分配了一名角色,该角色在结算后摸一张牌。", + sxianjing: "陷阱", + sxianjing_bg: "阱", + sxianjing_info: + "出牌阶段,你可以将一张手牌背面朝上置于你的武将牌上(不能与已有花色相同)。当一名其他角色使用与一张“陷阱”牌花色相同的牌指定你为目标时,你移去对应的“陷阱”牌,然后随机获得该角色的一张牌。每当你受到一次伤害,你随机将一张“陷阱”牌返回手牌。", + zhanxing: "占星", + zhanxing_info: + "出牌阶段限一次,你可以弃置任意张牌,并亮出牌堆顶的等量的牌,并根据亮出的牌包含的花色执行以下效果:♦︎摸两张牌;♥回复1点体力(若未损失体力改为获得1点护甲);♣令所有敌人随机弃置一张牌;♠令一名角色受到1点无来源的雷属性伤害。", + kbolan: "博览", + kbolan_info: "每当你摸牌时,你可以额外摸一张牌,然后摸牌结束时将一张手牌置于牌堆顶。", + gaizao: "改造", + gaizao_info: + "每当你即将装备一张牌(特殊类装备除外),若你的装备区内对应位置已有牌,你可以永久改变此牌的装备类型使其装备在装备区内的空余位置。", + lingshi: "灵矢", + lingshi_info: + "你的装备区内每有一张牌,你的攻击范围+2;当你的装备区内有武器牌或防具牌时,你的杀不可闪避;当你的装备区内有马时,你摸牌阶段额外摸一张牌;当你的装备内的宝物牌时,你回合内可以额外使用一张杀。", + tiebi: "铁壁", + tiebi_info: + "当距离你1以内的一名角色成为杀的目标时,若其没有护甲,你可以弃置一张黑色手牌使其获得1点护甲。", + shenyan: "神炎", + shenyan_bg: "炎", + shenyan_info: + "限定技,当你即将造成火焰伤害时,你可以令此伤害+1,并对目标距离1以内的所有其他角色各造成1点火焰伤害。", + xuanying: "旋影", + xuanying_info: + "你可以横置你的武将牌,视为使用一张无视距离的杀;每当你于回合外失去牌,你可以竖置你的武将牌,视为使用一张无视距离的杀。", + hwendao: "问道", + hwendao_info: + "每当你于回合外使用或打出一张牌,你可以令当前回合角色弃置一张与之花色相同的牌,否则你获得其一张牌。", + lingfeng: "凌锋", + lingfeng_info: + "结束阶段,若你本回合内使用了至少X张牌,你可以选择一项:获得1点护甲,或对攻击范围内的一名角色造成1点伤害(X为你当前的体力值且最多为3)。", + hxunzhi: "殉志", + hxunzhi_info: + "限定技,出牌阶段,你可以视为使用一张万箭齐发并获得技能武圣、咆哮,若如此做,你在此阶段结束时死亡。", + hxunzhi_info_alter: + "限定技,出牌阶段,你可以获得技能武圣、咆哮,若如此做,你在此阶段结束时死亡。", + lmazui: "麻醉", + lmazui2: "麻醉", + lmazui_info: + "出牌阶段限一次,你可以将一张黑色手牌置于一名角色的武将牌上,该角色造成的下一次伤害-1,然后获得此牌。", + hyunshen: "云身", + hyunshen2: "云身", + hyunshen_info: + "每当你打出一张闪,你可以令你的防御距离+1;准备阶段,你将累计的防御距离清零,然后摸等量的牌。", + hlingbo: "凌波", + hlingbo_info: "每当你使用或打出一张闪,你可以摸两张牌。", + gtiandao: "天道", + gtiandao_info: "任意一名角色的判定生效前,你可以打出一张牌替换之。", + nlianji: "连计", + nlianji_info: + "出牌阶段限一次,你可以选择一张手牌并指定两名角色进行拼点。若拼点结果不为平局,拼点赢的角色获得此牌,并对没赢的角色造成1点伤害。", + fengze: "风泽", + fengze_info: "出牌阶段限一次,你可以将一张黑色牌当作桃园结义使用。", + lingyue: "凌月", + lingyue_info: "每当你使用一张杀,你可以令目标弃置一张牌。", + jinlin: "金鳞", + jinlin_info: + "限定技,出牌阶段,你可以令任意名角色各获得3点护甲,获得护甲的角色于每个准备阶段失去1点护甲,直到首次失去所有护甲或累计以此法失去3点护甲。", + huanxia: "幻霞", + huanxia_info: "你可以将一张红色牌当作杀使用,若此杀未造成伤害,你在结束阶段收回此牌。", + jingjie: "幻镜", + jingjie_info: "限定技,出牌阶段,你可以令所有角色弃置所有牌,然后摸两张牌(不触发任何技能)。", + kongmo: "恐魔", + kongmo_info: "锁定技,你使用基本牌或普通锦囊牌后将额外结算一次卡牌效果。", + jufu: "巨斧", + jufu_info: "锁定技,当你有武器牌时,杀造成的伤害+1。", + huajing: "化精", + huajing_info: "每当你使用锦囊牌造成伤害,可以回复1点体力并摸一张牌。", + pingxu: "冯虚", + pingxu_info: "锁定技,当你没有武器牌时,你的进攻距离+1;当你没有防具牌时,你的防御距离+1。", + yudun: "愚钝", + yudun_info: "锁定技,你无法使用锦囊牌;你可以将两张锦囊牌当作一张不计入出杀次数的杀使用。", + bingfeng: "冰封", + bingfeng2: "冰封", + bingfeng2_info: "不能使用或打出手牌。", + bingfeng_info: + "限定技,出牌阶段,你可以指定至多三个目标与其一同翻面,且处于翻面状态时不能使用或打出手牌;若如此做,你失去技能玄咒并减少1点体力上限。", + guozao: "聒噪", + guozao_info: + "锁定技,每当距离你1以内的角色受到一次伤害,若伤害来源不你,你须观看牌堆顶的三张牌,然后指定距离2以内的一名有手牌角色将手牌与这些牌交换。", + guozao_info_alter: + "锁定技,每当距离你1以内的角色受到一次伤害,若伤害来源不你,你须观看牌堆顶的三张牌,然后指定距离1以内的一名有手牌角色将手牌与这些牌交换。", + heihuo: "黑火", + heihuo_info: + "出牌阶段,你可以弃置一张装备牌,令你的手牌数加倍;若你的手牌因此达到8张或更多,你立即受到3点火焰伤害且本回合内不能再次发动黑火。", + yaotong: "妖瞳", + yaotong1: "妖瞳", + yaotong2: "妖瞳", + yaotong3: "妖瞳", + yaotong4: "妖瞳", + yaotong_info: + "当你的手牌数为奇数时,你可以将一张手牌当作杀或闪使用或打出,当你的手牌数为偶数时,你可以将一张手牌当作无懈可击使用。", + yaotong_info_alter: + "当你的手牌数为奇数时,你可以将一张手牌当作杀使用或打出,当你的手牌数为偶数时,你可以将一张手牌当作无懈可击使用。", + pojian: "破茧", + pojian_info: "每当你失去最后一张手牌,可以从牌堆中获得一张装备牌并装备之。", + huajin: "化金", + huajin2: "化金", + huajin_info: "出牌阶段限一次,你可以弃置一张牌令你造成的伤害+1,直到你的下一回合开始。", + poxiao: "破霄", + poxiao_info: + "你可以将一张装备牌当杀使用;当你没有武器牌时,你的攻击范围+1,杀可以额外指定一个目标。", + jianji: "箭疾", + jianji_info: + "你可以将一张装备牌当杀使用,然后摸一张牌,此杀无视距离和防具,且不计入回合内出杀限制。", + yuchen: "浴尘", + yuchen_info: "每当你于回合外使用或打出一张黑色牌,你可以弃置一名角色的一张牌。", + huangyu: "凰羽", + huangyu_info: "出牌阶段限一次,你可以将两张红色牌当炽羽袭使用。", + bingjian: "冰箭", + bingjian_info: + "出牌阶段限一次,你可以弃置一张黑色的杀,令一名有手牌的其他角色展示手牌并弃置其中的所有闪,若其没有闪则受到1点雷电伤害。", + rumeng: "入梦", + rumeng_info: + "其他角色的出牌阶段前,你可以弃置一张非基本牌,并令其选择一项:弃置一张基本牌,或跳过出牌及弃牌阶段。", + lianda: "连打", + lianda_info: "当你使用一杀结算完毕后,可以弃置一张牌视为对目标再使用一张杀。", + xianghui: "祥晖", + xianghui_info: + "出牌阶段限一次,你可以弃置一张红色手牌,然后令场上体力值最少的角色各回复1点体力。", + huiqi: "回气", + huiqi_info: "每当你受到一次伤害,可令一名其他角色摸X张牌,X为你已损失的体力值。", + toudan: "投弹", + toudan_info: + "出牌阶段限一次,你可以弃置一张黑桃牌对一名其他角色造成1点火焰伤害,然后你与距离该角色1以内的所有角色各弃置一张牌。", + shending: "神丁", + shending_info: "锁定技,若你没有宝物牌,视为装备了蓝格怪衣。", + hzhenwei: "镇卫", + hzhenwei_info: + "当一名其他角色成为杀的目标后,若你在杀的使用者的攻击范围内,你可以弃置一张牌将此杀转移给自己,并在杀结算完毕后摸一张牌。", + shoulie: "狩猎", + shoulie_info: "当你使用一张杀指定目标后,可以弃置一张手牌令此杀不可闪避。", + hudun: "盾甲", + hudun_bg: "盾", + hudun2: "盾甲", + hudun_info: "锁定技,当你对其他角色造成伤害后,若你没有护甲,你获得1点护甲值。", + zhenjiu: "针灸", + zhenjiu2: "针灸", + zhenjiu_info: + "出牌阶段限一次,你可以将一张红色手牌置于一名角色的武将牌上,该角色于下一个准备阶段回复1点体力,然后获得此牌。", + ljifeng: "疾风", + ljifeng_info: "锁定技,你的攻击范围+X,杀可以额外指定X个目标,X为你已损失的体力值。", + lxianglong: "翔龙", + lxianglong_info: "每当你闪避一张杀,你可以视为使用一张杀。", + shangxi: "伤袭", + shangxi_info: + "准备阶段,你可以弃置一张牌,并对攻击范围内一名体力值不小于你的其他角色造成1点伤害。", + fzhenwei: "镇威", + fzhenwei_info: "在你的回合内,你可以将其他角色打出的卡牌交给除该角色外的任意一名角色。", + fuyan: "覆岩", + fuyan2: "覆岩", + fuyan_info: "每当你受到一次伤害,可以令一名没有护甲的角色获得1点护甲值。", + guaili: "怪力", + guaili_info: "锁定技,你的杀造成的伤害+1,造成伤害后需弃置两张手牌。", + pingshen: "凭神", + pingshen2: "凭神", + pingshen_info: "锁定技,受到过你的伤害的角色可在回合内对你发动一次【离魂】(每局限发动一次)。", + xingzhui: "星坠", + xingzhui_info: + "出牌阶段限一次,你可以弃置一张牌,并令一名有牌的其他角色弃置一张类别相同的牌,否则受到1点伤害。", + lingxian: "凌仙", + lingxian_info: + "每当你于回合外使用或打出一张手牌,你可以选择攻击范围外的一名其他角色与你各摸一张牌。", + shouyin: "守印", + shouyin_info: + "限定技,当任意一名角色处于濒死状态时,若你的武将牌正朝上,可以将武将牌翻面,然后令场上所有存活角色将体力回复至体力上限。", + shouyin_info_alter: + "限定技,当任意一名角色处于濒死状态时,若你的武将牌正朝上,可以将武将牌翻面,然后令场上所有存活角色回复2点体力。", + bofeng: "搏风", + bofeng_info: + "锁定技,体力值不大于你的角色视为在你的攻击范围;当你使用杀指定目标时,可令目标额外打出一张闪,否则此杀不可闪避且造成的伤害+1。", + hutian: "护天", + hutian2: "护天", + hutian3: "护天", + hutian_info: + "结束阶段,你可以将任意张牌置于一名角色的武将牌上,则该角色的体力值始终不能小于“护天”牌数;在你的下一个结束阶段,该角色获得武将牌上的“护天”牌(在此回合不能再次发动)。", + linyun: "凌云", + linyun_info: "你可以将两张牌当作杀使用,此杀需要额外一张闪才能闪避。", + sliufeng: "流风", + sliufeng_info: "锁定技,体力值不大于你的角色视为在你的攻击范围。", + chengjian: "承剑", + chengjian_info: "每当其他角色使用杀造成一次伤害,你可以令其摸一张牌。", + huanling: "幻灵", + huanling2: "幻灵", + huanling_info: "结束阶段,你可以选择一名角色与你同时翻面;翻面状态下,你防止一切伤害。", + xiaozhan: "消战", + xiaozhan_info: "其他角色使用杀时,若你不是杀的目标,可以弃置一张杀取消之。", + xielei: "挟雷", + xielei_info: "每当你使用或打出一张杀,可以弃置一张牌并对目标以外的一名角色造成1点雷电伤害。", + dangping: "荡平", + dangping_info: + "每当你造成一次伤害,可以弃置一张手牌对其距离1以内的另一名角色造成1点伤害,每回合限一次。", + guisi: "归思", + guisi_info: "每当你成为杀的目标,你可以交给对方一张手牌并取消之。", + duishi: "对诗", + duishi_info: + "出牌阶段,你可以弃置一张手牌,并指定一名有手牌的角色选择一项:1)弃置一张与之花色相同的手牌,本回合内对诗不能再次指定其为目标,2)令你获得其一张牌,对诗失效直到回合结束。", + anlianying: "连营", + anlianying_info: "每当你失去最后一张手牌,可摸两张牌。", + lianwu: "连舞", + lianwu_info: "锁定技,你的杀可以额外指定一个目标,你的红杀不可被闪避。", + jiying: "疾鹰", + jiying_info: "锁定技,你使用杀无视距离。", + daofa: "道法", + daofa_info: "每当有一名其他角色造成伤害,你可以令其弃置一张牌。", + xiaomoyu: "魔愈", + xiaomoyu_info: + "锁定技,每当你于一个回合内首次造成伤害,你回复1点体力,若你没有受伤,则改为摸一张牌。", + yihua: "移花", + yihua_info: "每当你成为其他角色的某张卡牌的唯一目标时,你可以弃置两张手牌,将使用者与目标对调。", + youyin: "游吟", + youyin_info: "每当有其他角色弃置卡牌时,若其中有非基本牌且你的手牌数不超过5,你可以摸一张牌。", + rexue: "热血", + rexue_info: "任意一名角色的准备阶段,你可以对其使用一张杀,并摸一张牌。", + huopu: "火瀑", + huopu_info: "出牌阶段限一次,你可以将一张红桃牌当作流星火羽使用。", + benlei: "奔雷", + benlei2: "奔雷", + benlei_info: "你可以将三张牌当惊雷闪使用;每当你造成一次雷属性伤害,你回复1点体力。", + lingwu: "灵舞", + lingwu_info: + "回合结束后,若你在本回合内使用的牌数不少于当前体力值,你可以进行一个额外的回合(不可重复发动)。", + miejing: "灭境", + miejing_info: "限制技,你可以弃置所有黑色牌,然后令所有其他角色受到1点雷电伤害。", + lingxin: "灵心", + lingxin_info: "结束阶段,你可以亮出牌堆顶的三张牌,然后获得其中的红桃牌。", + fushen: "附身", + fushen_info: "回合开始前,你可以将自己移出游戏,并代替另一名角色进行一回合,然后失去1点体力。", + fushen2: "附身", + wangchen: "忘尘", + wangchen_info: "弃牌阶段结束时,若你于此阶段弃置了基本牌,你可以令一名角色翻面。", + wangchen_info_alter: + "弃牌阶段结束时,若你于此阶段弃置了基本牌,你可以令一名角色翻面并获得1点护甲。", // wangchen_info:'若你于弃牌阶段弃置了基本牌,可令一名角色翻面。', // wangchen_info:'弃牌阶段结束时,若你于此阶段弃置了基本牌,可将一名其他角色移出游戏直到你死亡或下一回合开始。', - guiyin:'归隐', - guiyin_info:'若你于弃牌阶段弃置了至少两张牌,你可以摸两张牌。', - shejie:'设界', - shejie2:'设界', - shejie_info:'每当你受到一次伤害,可以令伤害来源不能使用或打出其手牌,直到其下一回合开始。', - shejie2_info:'不能使用或打出手牌,直到下一回合开始。', - yinyue:'引月', - yinyue_info:'每当有一名角色回复一次体力,你可以令其摸一张牌,若该角色不是你且你的手牌数不大于该角色,你也摸一张牌。', - yinyue_info_alter:'每当有一名角色回复一次体力,你可以令其摸一张牌。', - mohua2:'魔化', - mohua2_info:'锁定技,当你进入濒死状态时,你立即变身为撒旦,将体力回复至2,然后摸两张牌。', - liexin:'裂心', - liexin_info:'每当你即将造成伤害,你可以弃置一张牌令伤害+1。', - swdxueyi:'血裔', - swdxueyi_info:'锁定技,你摸牌阶段额外摸X张牌,X为你已损失的体力值。', - moyan:'血焰', - moyan_info:'出牌阶段,你可以弃置X张红色手牌,然后对至多X名角色各造成1点火焰伤害,X为你已损失的体力值。每阶段限一次。', - aojian:'傲剑', - aojian_info:'出牌阶段,你可以弃置X张手牌,然后对攻击范围内至多X名角色各造成1点伤害,X为你已损失的体力值。每阶段限一次。', - milesxiehun:'邪魂', - milesxiehun_info:'锁定技,出牌阶段结束后,你令随机X名角色各弃置一张牌,X为你已损失的体力值且至少为1。', - liaochen:'撩尘', - liaochen_info:'锁定技,出牌阶段结束后,所有角色需弃置一张牌。', - yinmo:'引魔', - yinmo_info:'锁定技,当你对场上所有角色发动〖连计〗后,你立即变身为魔化宁珂,然后对所有其他角色造成1点雷电伤害。', - huanxing:'幻形', - huanxing2:'幻形', - huanxing_info:'准备阶段,你可以弃置一张牌并选择一名男性角色,获得其所有技能,直到你首次受到伤害。', - meihuo:'魅惑', - meihuo_info:'每当你失去最后一张装备牌,你可以获得一名其他角色的一张牌,若此牌来自装备区,你立即装备之。', + guiyin: "归隐", + guiyin_info: "若你于弃牌阶段弃置了至少两张牌,你可以摸两张牌。", + shejie: "设界", + shejie2: "设界", + shejie_info: "每当你受到一次伤害,可以令伤害来源不能使用或打出其手牌,直到其下一回合开始。", + shejie2_info: "不能使用或打出手牌,直到下一回合开始。", + yinyue: "引月", + yinyue_info: + "每当有一名角色回复一次体力,你可以令其摸一张牌,若该角色不是你且你的手牌数不大于该角色,你也摸一张牌。", + yinyue_info_alter: "每当有一名角色回复一次体力,你可以令其摸一张牌。", + mohua2: "魔化", + mohua2_info: "锁定技,当你进入濒死状态时,你立即变身为撒旦,将体力回复至2,然后摸两张牌。", + liexin: "裂心", + liexin_info: "每当你即将造成伤害,你可以弃置一张牌令伤害+1。", + swdxueyi: "血裔", + swdxueyi_info: "锁定技,你摸牌阶段额外摸X张牌,X为你已损失的体力值。", + moyan: "血焰", + moyan_info: + "出牌阶段,你可以弃置X张红色手牌,然后对至多X名角色各造成1点火焰伤害,X为你已损失的体力值。每阶段限一次。", + aojian: "傲剑", + aojian_info: + "出牌阶段,你可以弃置X张手牌,然后对攻击范围内至多X名角色各造成1点伤害,X为你已损失的体力值。每阶段限一次。", + milesxiehun: "邪魂", + milesxiehun_info: + "锁定技,出牌阶段结束后,你令随机X名角色各弃置一张牌,X为你已损失的体力值且至少为1。", + liaochen: "撩尘", + liaochen_info: "锁定技,出牌阶段结束后,所有角色需弃置一张牌。", + yinmo: "引魔", + yinmo_info: + "锁定技,当你对场上所有角色发动〖连计〗后,你立即变身为魔化宁珂,然后对所有其他角色造成1点雷电伤害。", + huanxing: "幻形", + huanxing2: "幻形", + huanxing_info: + "准备阶段,你可以弃置一张牌并选择一名男性角色,获得其所有技能,直到你首次受到伤害。", + meihuo: "魅惑", + meihuo_info: + "每当你失去最后一张装备牌,你可以获得一名其他角色的一张牌,若此牌来自装备区,你立即装备之。", - touxi:'偷袭', - touxi_info:'在其他角色的结束阶段,你可以进行一次判定,若结果为黑色,你对其造成1点雷电伤害,且直到下一回合开始不能再次发动偷袭;若结果为红色,对方可以弃置你的一张牌。', - touxi_info_alter:'在其他角色的结束阶段,你可以进行一次判定,若结果为黑色,你对其造成1点雷电伤害,且直到下一回合开始不能再次发动偷袭;若结果为红色,对方可以获得你的一张牌。', - minjing:'明镜', - minjing_info:'若你没有防具牌,你视为装备了光纱天衣。', - jqimou:'奇谋', - jqimou_info:'每当你于回合外受到一次伤害,你可以摸一张牌,并可以使用一张牌。', - mufeng:'沐风', - mufeng_info:'结束阶段,若你本回合使用过基本牌,则可发现一张牌。', - mufeng_info_alter:'结束阶段,你可以将手牌数补至当前体力值。', - mufeng_old2_info:'在一名角色的结束阶段,若你的手牌数比其少,你可以将手牌补至与该角色相同(最多补至5),每轮限一次。', - hjifeng:'祭风', - hjifeng_info:'出牌阶段限一次,若你手牌中没有祭器牌,你可以将一张手牌置于牌堆顶,并根据其花色获得对应祭器:黑桃-青龙之圭;梅花-白兽之琥;方片-朱雀之璋;红桃-玄武之璜。', - mufeng_old_info:'锁定技,每当你于回合外失去牌,你的防御距离+1;若防御距离的变化值超过了存活角色数的一半,则降至0。', - lexue:'乐学', - lexue_info:'回合内,你随机获得制衡、集智、缔盟、驱虎中的一个技能;回合外,你随机获得遗计、急救、鬼道、反馈中的一个技能。', - mingfu:'冥缚', - mingfu_info:'出牌阶段限一次,你可以将一张梅花牌当鬼幽结使用。', - chuanyue:'穿月', - chuanyue_info:'出牌阶段限一次,你可以将两张手牌当决斗使用。', + touxi: "偷袭", + touxi_info: + "在其他角色的结束阶段,你可以进行一次判定,若结果为黑色,你对其造成1点雷电伤害,且直到下一回合开始不能再次发动偷袭;若结果为红色,对方可以弃置你的一张牌。", + touxi_info_alter: + "在其他角色的结束阶段,你可以进行一次判定,若结果为黑色,你对其造成1点雷电伤害,且直到下一回合开始不能再次发动偷袭;若结果为红色,对方可以获得你的一张牌。", + minjing: "明镜", + minjing_info: "若你没有防具牌,你视为装备了光纱天衣。", + jqimou: "奇谋", + jqimou_info: "每当你于回合外受到一次伤害,你可以摸一张牌,并可以使用一张牌。", + mufeng: "沐风", + mufeng_info: "结束阶段,若你本回合使用过基本牌,则可发现一张牌。", + mufeng_info_alter: "结束阶段,你可以将手牌数补至当前体力值。", + mufeng_old2_info: + "在一名角色的结束阶段,若你的手牌数比其少,你可以将手牌补至与该角色相同(最多补至5),每轮限一次。", + hjifeng: "祭风", + hjifeng_info: + "出牌阶段限一次,若你手牌中没有祭器牌,你可以将一张手牌置于牌堆顶,并根据其花色获得对应祭器:黑桃-青龙之圭;梅花-白兽之琥;方片-朱雀之璋;红桃-玄武之璜。", + mufeng_old_info: + "锁定技,每当你于回合外失去牌,你的防御距离+1;若防御距离的变化值超过了存活角色数的一半,则降至0。", + lexue: "乐学", + lexue_info: + "回合内,你随机获得制衡、集智、缔盟、驱虎中的一个技能;回合外,你随机获得遗计、急救、鬼道、反馈中的一个技能。", + mingfu: "冥缚", + mingfu_info: "出牌阶段限一次,你可以将一张梅花牌当鬼幽结使用。", + chuanyue: "穿月", + chuanyue_info: "出牌阶段限一次,你可以将两张手牌当决斗使用。", - miedao:'灭道', - miedao1:'灭道', - miedao2:'灭道', - miedao_info:'锁定技,摸牌阶段,你额外摸X张牌;弃牌阶段,你至少须弃X张牌(不足则全弃),X为你已损失的体力值。', + miedao: "灭道", + miedao1: "灭道", + miedao2: "灭道", + miedao_info: + "锁定技,摸牌阶段,你额外摸X张牌;弃牌阶段,你至少须弃X张牌(不足则全弃),X为你已损失的体力值。", - senluo:'森罗', - senluo_info:'出牌阶段限一次,若你的手牌数为全场最少或之一,你可以令所有有手牌的其他角色弃置两张手牌然后摸一张牌。', - polang:'破浪', - polang_info:'每当你造成一次伤害,可以一张对方的装备牌。', - jikong:'亟空', - jikong2:'亟空', - jikong_info:'准备阶段,你可以指定一名角色视为对其使用一张雷杀;每当你失去最后一张手牌,你可以指定一名角色视为对其使用一张雷杀(每回合限发动一次)。', - jikong_info_alter:'准备阶段,你可以指定一名角色视为对其使用一张雷杀。', - xiangu:'仙骨', - xiangu_info:'锁定技,你的手牌上限不会因体力值的减少而减少。', - hujing:'壶境', - hujing_info:'锁定技,准备阶段,若弃牌堆中有炼妖壶,你装备之;当你的装备区内有炼妖壶时,你的手牌上限+2。', - huajian:'化剑', - huajian_info:'出牌阶段结束时,你可以将一张牌当作杀对任意一名角色使用。', - xuanyuan:'轩辕', - xuanyuan_info:'锁定技,你无视【轩辕剑】的装备条件及失去体力的效果;结束阶段,你可以弃置一张黑桃牌从弃牌堆中获得【轩辕剑】并装备之。', - jilve:'极略', - jilve_backup:'极略', - jilve2:'极略', - jilve_info:'出牌阶段,你可以观看牌堆顶的三张牌,然后使用其中的非装备牌。每回合最多发动三次。', - jilve_info_alter:'出牌阶段,你可以观看牌堆顶的两张牌,然后使用其中的非装备牌。每回合最多发动三次。', - gongshen:'工神', - gongshen_info:'任意一名其他角色使用一张基本牌或锦囊牌指定目标后,你可以弃置一张装备牌令其失效。', + senluo: "森罗", + senluo_info: + "出牌阶段限一次,若你的手牌数为全场最少或之一,你可以令所有有手牌的其他角色弃置两张手牌然后摸一张牌。", + polang: "破浪", + polang_info: "每当你造成一次伤害,可以一张对方的装备牌。", + jikong: "亟空", + jikong2: "亟空", + jikong_info: + "准备阶段,你可以指定一名角色视为对其使用一张雷杀;每当你失去最后一张手牌,你可以指定一名角色视为对其使用一张雷杀(每回合限发动一次)。", + jikong_info_alter: "准备阶段,你可以指定一名角色视为对其使用一张雷杀。", + xiangu: "仙骨", + xiangu_info: "锁定技,你的手牌上限不会因体力值的减少而减少。", + hujing: "壶境", + hujing_info: + "锁定技,准备阶段,若弃牌堆中有炼妖壶,你装备之;当你的装备区内有炼妖壶时,你的手牌上限+2。", + huajian: "化剑", + huajian_info: "出牌阶段结束时,你可以将一张牌当作杀对任意一名角色使用。", + xuanyuan: "轩辕", + xuanyuan_info: + "锁定技,你无视【轩辕剑】的装备条件及失去体力的效果;结束阶段,你可以弃置一张黑桃牌从弃牌堆中获得【轩辕剑】并装备之。", + jilve: "极略", + jilve_backup: "极略", + jilve2: "极略", + jilve_info: "出牌阶段,你可以观看牌堆顶的三张牌,然后使用其中的非装备牌。每回合最多发动三次。", + jilve_info_alter: + "出牌阶段,你可以观看牌堆顶的两张牌,然后使用其中的非装备牌。每回合最多发动三次。", + gongshen: "工神", + gongshen_info: "任意一名其他角色使用一张基本牌或锦囊牌指定目标后,你可以弃置一张装备牌令其失效。", - swdliuhong:'流虹', - swdliuhong_info:'每当你使用一张杀,可以摸一张牌。', - poyue:'破月', - poyue_info:'锁定技,你的黑杀无视距离,红色杀不计入回合内的出杀限制且不可闪避。', - poyue_info_alter:'锁定技,你的黑杀无视距离,红色杀不可闪避。', - mojian:'墨剑', - mojian_info:'每当你使用杀并指定目标后,你可以令其摸一张牌,然后你回复1点体力。', - duanyue:'断月', - duanyue_info:'出牌阶段限一次,你可以弃置一张装备牌,对一名其他角色造成1点伤害。', - tuzhen:'突阵', - tuzhen_info:'当你造成一次伤害后,你可以弃置对方手牌中的非基本牌。', - tuzhen_info_alter:'当你造成一次伤害后,你可以弃置对方手牌中的一张非基本牌。', - fengmo:'封魔', - fengmo_info:'出牌阶段限一次,你可以弃置场所有武器牌(至少两张),然后令一名未翻面的角色摸等量的牌并翻面。', - pozhou:'破咒', - pozhou_bg:'破', - pozhou2:'破咒', - pozhou_info:'每当你受到一次伤害,你获得一枚破咒标记。出牌阶段,你可以指定任意名其他角色并弃置等量的破咒标记,令目标的非锁定技失效直到其下一回合结束。', - xuanzhou:'玄咒', - xuanzhou_info:'出牌阶段限一次,你可以将一张普通锦囊牌当作任意一张延时锦囊,对任意一名角色使用(无视锦囊使用范围限制)。', - ningxian:'凝霰', - ningxian_info:'每当你受到一次伤害,你可以弃置任意张黑色牌并选择等量其他角色对其各造成1点伤害。', - guanhu:'贯鹄', - guanhu_info:'每当你使用杀造成伤害,你可以弃置对方一张手牌和一张装备牌。', - chuanyang:'穿杨', - chuanyang_info:'每当你使用一张杀,若你不在目标的攻击范围,你可以令此杀不可闪避。', - fengming:'凤鸣', - fengming_info:'出牌阶段限一次,你可以弃置一张装备牌,令一名角色恢复1点体力并摸一张牌。', - duanxing:'锻星', - duanxing_info:'每当你装备一张未强化的装备牌,可以视为一名角色使用一张杀。', - wanjun:'万钧', - wanjun_info:'你可以将一张装备牌当作南蛮入侵使用。', - dunxing:'遁形', - dunxing_info:'当你成为其他角色卡牌的目标时,你可以弃置一张牌并进行一次判定,若不为红桃,则取消之。', - guiying:'鬼影', - guiying_info:'你可以将一张黑色牌当偷梁换柱使用。', - shehun:'摄魂', - shehun_info:'出牌阶段限一次,你可以弃置任意张花色不同的牌,另一名其他角色弃置等量的牌,若其弃置的牌中有牌的花色与你弃置的牌相同,你对其造成1点伤害。', + swdliuhong: "流虹", + swdliuhong_info: "每当你使用一张杀,可以摸一张牌。", + poyue: "破月", + poyue_info: "锁定技,你的黑杀无视距离,红色杀不计入回合内的出杀限制且不可闪避。", + poyue_info_alter: "锁定技,你的黑杀无视距离,红色杀不可闪避。", + mojian: "墨剑", + mojian_info: "每当你使用杀并指定目标后,你可以令其摸一张牌,然后你回复1点体力。", + duanyue: "断月", + duanyue_info: "出牌阶段限一次,你可以弃置一张装备牌,对一名其他角色造成1点伤害。", + tuzhen: "突阵", + tuzhen_info: "当你造成一次伤害后,你可以弃置对方手牌中的非基本牌。", + tuzhen_info_alter: "当你造成一次伤害后,你可以弃置对方手牌中的一张非基本牌。", + fengmo: "封魔", + fengmo_info: + "出牌阶段限一次,你可以弃置场所有武器牌(至少两张),然后令一名未翻面的角色摸等量的牌并翻面。", + pozhou: "破咒", + pozhou_bg: "破", + pozhou2: "破咒", + pozhou_info: + "每当你受到一次伤害,你获得一枚破咒标记。出牌阶段,你可以指定任意名其他角色并弃置等量的破咒标记,令目标的非锁定技失效直到其下一回合结束。", + xuanzhou: "玄咒", + xuanzhou_info: + "出牌阶段限一次,你可以将一张普通锦囊牌当作任意一张延时锦囊,对任意一名角色使用(无视锦囊使用范围限制)。", + ningxian: "凝霰", + ningxian_info: "每当你受到一次伤害,你可以弃置任意张黑色牌并选择等量其他角色对其各造成1点伤害。", + guanhu: "贯鹄", + guanhu_info: "每当你使用杀造成伤害,你可以弃置对方一张手牌和一张装备牌。", + chuanyang: "穿杨", + chuanyang_info: "每当你使用一张杀,若你不在目标的攻击范围,你可以令此杀不可闪避。", + fengming: "凤鸣", + fengming_info: "出牌阶段限一次,你可以弃置一张装备牌,令一名角色恢复1点体力并摸一张牌。", + duanxing: "锻星", + duanxing_info: "每当你装备一张未强化的装备牌,可以视为一名角色使用一张杀。", + wanjun: "万钧", + wanjun_info: "你可以将一张装备牌当作南蛮入侵使用。", + dunxing: "遁形", + dunxing_info: + "当你成为其他角色卡牌的目标时,你可以弃置一张牌并进行一次判定,若不为红桃,则取消之。", + guiying: "鬼影", + guiying_info: "你可以将一张黑色牌当偷梁换柱使用。", + shehun: "摄魂", + shehun_info: + "出牌阶段限一次,你可以弃置任意张花色不同的牌,另一名其他角色弃置等量的牌,若其弃置的牌中有牌的花色与你弃置的牌相同,你对其造成1点伤害。", - zhanlu:'沾露', - luomu:'落木', - jifeng:'魔影', - liaoyuan:'燎原', - huanhun:'唤魂', - daixing:'代形', - yishan:'异闪', - yishan2:'异闪', - swd_wuxie:'无邪', - lqingcheng:'倾城', - xianjiang:'仙匠', - xianjiang3:'仙匠', - shengong:'神工', - ningjian:'凝剑', - ningjian1:'凝剑', - ningjian2:'凝剑', - taixu:'太虚', - duoren:'夺刃', - tanlin:'探麟', - tanlin2:'探麟', - pozhen:'破阵', - yunchou:'运筹', - swdtianshu:'天书', - swdtianshu_bg:'书', - swdtianshu2:'天书', - xingdian:'星点', - luomei:'落梅', - yulin:'玉鳞', - funiao:'符鸟', - xuehuang:'血凰', - xuehuang_bg:'凰', - zhuyu:'朱羽', - ningshuang:'凝霜', - zaowu:'造物', + zhanlu: "沾露", + luomu: "落木", + jifeng: "魔影", + liaoyuan: "燎原", + huanhun: "唤魂", + daixing: "代形", + yishan: "异闪", + yishan2: "异闪", + swd_wuxie: "无邪", + lqingcheng: "倾城", + xianjiang: "仙匠", + xianjiang3: "仙匠", + shengong: "神工", + ningjian: "凝剑", + ningjian1: "凝剑", + ningjian2: "凝剑", + taixu: "太虚", + duoren: "夺刃", + tanlin: "探麟", + tanlin2: "探麟", + pozhen: "破阵", + yunchou: "运筹", + swdtianshu: "天书", + swdtianshu_bg: "书", + swdtianshu2: "天书", + xingdian: "星点", + luomei: "落梅", + yulin: "玉鳞", + funiao: "符鸟", + xuehuang: "血凰", + xuehuang_bg: "凰", + zhuyu: "朱羽", + ningshuang: "凝霜", + zaowu: "造物", // shouhua:'收化', - xielv:'谐率', - tianhuo:'天火', - huanyin:'幻音', - tianlun:'天轮', - hlongyin:'龙吟', - lanzhi:'兰芷', - duanyi:'断意', - miesheng:'灭生', - guxing:'孤星', - guxing1:'孤星', - guxing2:'孤星', - poxing:'破星', - mohua:'魔化', - miles_xueyi:'血裔', - wuying:'无影', - xiehun:'邪魂', - xiehun1:'邪魂', - xiehun2:'邪魂', - xiehun3:'邪魂', - jumo:'聚魔', - duijue:'对决', - duijue_bg:'决', - yueren:'月刃', - busi:'不死', - xuying:'虚影', - yinguo:'因果', - guiyan:'鬼眼', - guiyan2:'鬼眼', - swd_xiuluo:'修罗', - suiyan:'碎岩', - suiyan_info:'每当你造成一次伤害,可以弃置一张牌并弃置对方的全部装备牌。', - xianyin:'散结', - qiaoxie:'巧械', - qiaoxie2:'巧械', - qiaoxie3:'巧械', - qiaoxie4:'巧械', - mailun:'脉轮', - mailun31:'脉轮', - mailun32:'脉轮', - mailun41:'脉轮', - mailun42:'脉轮', - kunlunjing:'幻镜', - kunlunjing1:'幻镜', - kunlunjing2:'幻镜', - susheng:'苏生', - shengshou:'圣手', - huanjian:'幻箭', - huanjian_info:'出牌阶段,你可以将一张黑色牌当作冰魄针使用。', - shengshou_info:'你可以将一张黑色手牌当作草药使用。', - susheng_info:'在任意一名角色即将死亡时,你可以弃置一张手牌防止其死亡,并将其体力回复至1,每回合限发动一次。', - susheng_info_alter:'在任意一名角色即将死亡时,你可以弃置一张红色手牌防止其死亡,并将其体力回复至1,每回合限发动一次。', - zhanlu_info:'出牌阶段限一次,你可以弃置一张黑桃牌令至多3名角色各回复1点体力。', - kunlunjing_info:'准备阶段,若你的体力值小于上回合结束时的体力值,你可以将场上所有牌还原到你上一回合结束时的位置。', - kunlunjing_info_alter:'准备阶段,若你的体力值小于上回合结束时的体力值,你可以将场上所有牌还原到你上一回合结束时的位置,然后失去1点体力。', - swd_xiuluo_info:'准备阶段,你可以弃一张手牌来弃置你判断区里的一张延时类锦囊(必须花色相同)。', - xianyin_info:'出牌阶段,你可以令所有判定区内有牌的角色弃置判定区内的牌,然后交给你一张手牌。', - qiaoxie_info:'每当你装备一张牌,可摸一张牌;每当你失去一张装备牌(不含替换),你可以弃置其他角色的一张牌。', - mailun_info:'准备阶段,你可以选择一个脉轮效果直到下一回合开始。', - guiyan_info:'出牌阶段,你可以观看一名角色的手牌,并获得其中一张梅花牌,每阶段限一次。当你首次进入濒死状态时,你须回复1点体力并失去技能鬼眼。', - busi_info:'锁定技,当你进入濒死状态时,你进行一次判定,若结果不为黑桃,你将体力回复至1并将武将牌翻至背面。', - xuying_info:'锁定技,每当你即将受到伤害,你防止此伤害,若你此时有手牌,你失去1点体力。', - yinguo_info:'除你之外的任意一名角色即将受到受到伤害时,若有伤害来源,你可以弃置一张牌将伤害来源和目标对调。', - yueren_info:'每当你使用一张杀,可以进行一次判定,若结果为黑色,你弃置目标一张牌,若结果为红色,你将此杀收回,每回合限发动一次。', - duijue_info:'限定技,出牌阶段,你可以指定一名体力值大于1的其他角色,你结束出牌阶段,并在回合结束后将所有其他角色移出游戏,然后该角色与你轮流进行回合,直到有一方死亡或一共进行六个回合为止。', - wuying_info:'锁定技,你的杀和单体x锦囊目标锁定为范围内的所有角色。', - xiehun_info:'锁定技,受到来自你伤害的角色进入混乱状态,行为不受控制,且会攻击队友,直到你的下一回合开始。', - jumo_info:'锁定技,结束阶段,你摸X-1张牌,X为未进入混乱状态的角色数与进入混乱状态的角色数之差(若为双将则改为X)。', - jifeng_info:'你的杀和单体锦囊可以额外指定任意个目标,若如此做,此卡牌有一定机率失效,指定的目标越多失效的概率越大。', - mohua_info:'锁定技,在身份局中,当你进入濒死状态时,你立即变身为撒旦,体力上限变为现存角色数(至少为4),并成为其他所有角色的共同敌人。', - miles_xueyi_info:'锁定技,你防止即将受到的伤害,然后失去1点体力。', - duanyi_info:'出牌阶段限一次,你可以弃置两张杀,对一名角色造成1点伤害,然后其随机弃置X张牌,X为其已损失的体力值。', - duanyi_info_alter:'出牌阶段限一次,你可以弃置两张杀,并对一名角色造成1点伤害。', - guxing_info:'出牌阶段,你可以将最后至多X张手牌当杀使用,此杀无视距离且可以指定至多3个目标,每造成一次伤害,你摸一张牌,X为你已损失的体力值且至少为1。', - tianlun_info:'任意一名角色的判定牌生效前,你可以弃置一张场上角色的判定牌代替之。', - hlongyin_info:'出牌阶段,你可以弃置任意张颜色相同且点数不同的牌,并获得逆时针座位距离与卡牌点数相同的角色区域内的一张牌。每阶段限一次。', - lanzhi_info:'每当你使用一张梅花牌,你可以令所有体力值不大于你的角色回复1点体力。', - lanzhi_old_info:'每当你即将造成伤害,可以防止此伤害,然后摸两张牌。每回合限发动一次。', - tianhuo_info:'出牌阶段,你可以令所有角色弃置其判定区域内的牌,并受到没有来源的等量火焰伤害,每阶段限一次。', - huanyin_info:'锁定技,每当你成为其他角色的卡牌的目标时,你进行一次判定,若为黑桃则取消之,若为红桃你摸一张牌。', - luomu_info:'锁定技,每当你造成伤害时,受伤害角色随机弃置一张牌。', - poxing_info:'锁定技,每当你即将造成伤害,若目标的体力值大于你,你令伤害+1。', - liaoyuan_info:'每当你使用一张杀指定目标后,你可以弃置任意张与此杀花色相同的牌,若如此做,目标需额外打出等量的闪,每少打出一张闪,此杀的伤害+1。', - liaoyuan_info_alter:'每当你使用一张杀指定目标后,你可以弃置一张与此杀花色相同的牌,若如此做,目标需额外打出一张闪,若目标没打出闪,此杀的伤害+1。', - yishan_info:'每当你受到一次伤害,你可以重新获得最近失去的两张牌。', - huanhun_info:'当一名角色进入濒死状态时,你可以弃置一张牌并令其进行一次判定,若结果为红色,其回复1点体力,否则其获得你弃置的牌。', - huanhun_info_alter:'当一名角色进入濒死状态时,你可以弃置一张红色手牌并令其进行一次判定,若结果为红色,其回复1点体力,否则其获得你弃置的牌。', - daixing_info:'结束阶段,你可以弃置任意张牌并获得等量的护甲;这些护甲将在你的下个准备阶段消失。', - swd_wuxie_info:'锁定技,你不能成为其他角色的延时锦囊的目标。', - lqingcheng_info:'结束阶段,你可以进行判定,若为红色则可以继续判定,最多判定3次,判定结束后将判定成功的牌收入手牌。', - xianjiang_old_info:'出牌阶段,你可以将一张装备牌永久转化为任意一张其它装备牌,一张牌在一个阶段只能转化一次。', - xianjiang_info:'出牌阶段限一次,你可以弃置一张锦囊牌并随机装备一件装备。', - xianjiang_info_alter:'出牌阶段限一次,若你装备内没有牌,你可以弃置一张锦囊牌并随机装备一件装备。', - shengong_info:'每当你需要打出一张杀或闪时,你可以弃置一名其他角色装备区内的一张武器牌或防具牌,视为打出一张杀或闪,然后该角色摸一张牌,你弃一张牌。', - ningjian_info:'你可以将一张红色牌当闪、黑色牌当杀使用或打出。', - taixu_info:'限定技,你可以弃置你的所有牌(至少1张),并对一名体力值大于1为其他角色造成X点火焰伤害,X为你已损失的体力值且至少为1。', - duoren_info:'每当你闪避一张杀,你可以立即获得来源的武器牌。', - tanlin_info:'出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你获得双方拼点牌、对该角色使用卡牌无视距离且可以额外使用一张杀直到回合结束,若你没赢,你受到该角色的1点伤害。', - tanlin_info_alter:'出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你获得对方拼点牌、对该角色使用卡牌无视距离且可以额外使用一张杀直到回合结束,若你没赢,你受到该角色的1点伤害。', - pozhen_info:'每当你受到一次伤害,若你的手牌数大于伤害来源,你可以弃置X张手牌对其造成1点伤害;若你的手牌数小于伤害来源,你可以弃置其X张手牌。X为你与伤害来源的手牌数之差。', - pozhen_info_alter:'每当你受到一次伤害,若你的手牌数小于伤害来源,你可以弃置其X张手牌。X为你与伤害来源的手牌数之差。', - yunchou_info:'出牌阶段限一次,你可以弃置一张手牌,并弃置一名其他角色的一张手牌,若两张牌颜色相同,你摸一张牌,否则对方摸一张牌。', - yunchou_info_alter:'出牌阶段限一次,你可以弃置一张非基本手牌,并弃置一名其他角色的一张手牌,若两张牌颜色相同,你摸一张牌,否则对方摸一张牌。', - swdtianshu_old_info:'结束阶段,你可以弃置一张牌并从三名随机武将中选择一个,在2X回合后你将其所有技能加入你的天书列表,X为其技能数;在技能加入天书列表时,或于出牌阶段,你可以装备一项天书列表中的技能。', - swdtianshu_info:'出牌阶段,你可以弃置一张锦囊牌,然后获得一名其他角色的一项技能直到该角色死亡(替换以此法获得的前一个技能)。', - zaowu_info:'出牌阶段限一次,你可以将一张黑桃或红桃手牌当作封印之蛋使用。', - luomei_info:'每当你使用或打出一张梅花花色的牌,你可以摸一张牌。', - xingdian_info:'出牌阶段限一次,你可以弃置一张手牌,然后随机弃置两名敌人各一张牌。', - yulin_info:'每当你即将受到伤害,你可以弃置一张装备牌抵消此伤害。', - funiao_info:'出牌阶段限一次,你可以将一张手牌交给一名其他角色,然后摸一张牌并观看其手牌。', - funiao_old_info:'出牌阶段,你可以交给一名角色一张手牌,然后观看其手牌,每个阶段对一名角色只能发动一次。', - xuehuang_info:'限定技,出牌阶段,若你没有黑色手牌,你可以展示并弃置所有手牌,每弃置一张牌视为使用一张火杀,随机指定两名敌人为目标。', - zhuyu_info:'每当一名横置的角色即将受到伤害时,你可以弃置一张红色牌令此伤害+1并变为火属性。', - ningshuang_info:'每当你成为黑色牌的目标,你可以弃置一张黑色牌将其横置,并摸一张牌,若其已经模置则改为将其翻面。', - zaowu_old_info:'出牌阶段,你可以弃置三张不同类型的牌,创造任意两张牌并获得之。', - xielv_info:'弃牌阶段结束后,若你的所有手牌(至少两张)颜色均相同,你可以展示所有手牌,然后回复1点体力并弃置场上的所有判定牌。', + xielv: "谐率", + tianhuo: "天火", + huanyin: "幻音", + tianlun: "天轮", + hlongyin: "龙吟", + lanzhi: "兰芷", + duanyi: "断意", + miesheng: "灭生", + guxing: "孤星", + guxing1: "孤星", + guxing2: "孤星", + poxing: "破星", + mohua: "魔化", + miles_xueyi: "血裔", + wuying: "无影", + xiehun: "邪魂", + xiehun1: "邪魂", + xiehun2: "邪魂", + xiehun3: "邪魂", + jumo: "聚魔", + duijue: "对决", + duijue_bg: "决", + yueren: "月刃", + busi: "不死", + xuying: "虚影", + yinguo: "因果", + guiyan: "鬼眼", + guiyan2: "鬼眼", + swd_xiuluo: "修罗", + suiyan: "碎岩", + suiyan_info: "每当你造成一次伤害,可以弃置一张牌并弃置对方的全部装备牌。", + xianyin: "散结", + qiaoxie: "巧械", + qiaoxie2: "巧械", + qiaoxie3: "巧械", + qiaoxie4: "巧械", + mailun: "脉轮", + mailun31: "脉轮", + mailun32: "脉轮", + mailun41: "脉轮", + mailun42: "脉轮", + kunlunjing: "幻镜", + kunlunjing1: "幻镜", + kunlunjing2: "幻镜", + susheng: "苏生", + shengshou: "圣手", + huanjian: "幻箭", + huanjian_info: "出牌阶段,你可以将一张黑色牌当作冰魄针使用。", + shengshou_info: "你可以将一张黑色手牌当作草药使用。", + susheng_info: + "在任意一名角色即将死亡时,你可以弃置一张手牌防止其死亡,并将其体力回复至1,每回合限发动一次。", + susheng_info_alter: + "在任意一名角色即将死亡时,你可以弃置一张红色手牌防止其死亡,并将其体力回复至1,每回合限发动一次。", + zhanlu_info: "出牌阶段限一次,你可以弃置一张黑桃牌令至多3名角色各回复1点体力。", + kunlunjing_info: + "准备阶段,若你的体力值小于上回合结束时的体力值,你可以将场上所有牌还原到你上一回合结束时的位置。", + kunlunjing_info_alter: + "准备阶段,若你的体力值小于上回合结束时的体力值,你可以将场上所有牌还原到你上一回合结束时的位置,然后失去1点体力。", + swd_xiuluo_info: "准备阶段,你可以弃一张手牌来弃置你判断区里的一张延时类锦囊(必须花色相同)。", + xianyin_info: "出牌阶段,你可以令所有判定区内有牌的角色弃置判定区内的牌,然后交给你一张手牌。", + qiaoxie_info: + "每当你装备一张牌,可摸一张牌;每当你失去一张装备牌(不含替换),你可以弃置其他角色的一张牌。", + mailun_info: "准备阶段,你可以选择一个脉轮效果直到下一回合开始。", + guiyan_info: + "出牌阶段,你可以观看一名角色的手牌,并获得其中一张梅花牌,每阶段限一次。当你首次进入濒死状态时,你须回复1点体力并失去技能鬼眼。", + busi_info: + "锁定技,当你进入濒死状态时,你进行一次判定,若结果不为黑桃,你将体力回复至1并将武将牌翻至背面。", + xuying_info: "锁定技,每当你即将受到伤害,你防止此伤害,若你此时有手牌,你失去1点体力。", + yinguo_info: + "除你之外的任意一名角色即将受到受到伤害时,若有伤害来源,你可以弃置一张牌将伤害来源和目标对调。", + yueren_info: + "每当你使用一张杀,可以进行一次判定,若结果为黑色,你弃置目标一张牌,若结果为红色,你将此杀收回,每回合限发动一次。", + duijue_info: + "限定技,出牌阶段,你可以指定一名体力值大于1的其他角色,你结束出牌阶段,并在回合结束后将所有其他角色移出游戏,然后该角色与你轮流进行回合,直到有一方死亡或一共进行六个回合为止。", + wuying_info: "锁定技,你的杀和单体x锦囊目标锁定为范围内的所有角色。", + xiehun_info: + "锁定技,受到来自你伤害的角色进入混乱状态,行为不受控制,且会攻击队友,直到你的下一回合开始。", + jumo_info: + "锁定技,结束阶段,你摸X-1张牌,X为未进入混乱状态的角色数与进入混乱状态的角色数之差(若为双将则改为X)。", + jifeng_info: + "你的杀和单体锦囊可以额外指定任意个目标,若如此做,此卡牌有一定机率失效,指定的目标越多失效的概率越大。", + mohua_info: + "锁定技,在身份局中,当你进入濒死状态时,你立即变身为撒旦,体力上限变为现存角色数(至少为4),并成为其他所有角色的共同敌人。", + miles_xueyi_info: "锁定技,你防止即将受到的伤害,然后失去1点体力。", + duanyi_info: + "出牌阶段限一次,你可以弃置两张杀,对一名角色造成1点伤害,然后其随机弃置X张牌,X为其已损失的体力值。", + duanyi_info_alter: "出牌阶段限一次,你可以弃置两张杀,并对一名角色造成1点伤害。", + guxing_info: + "出牌阶段,你可以将最后至多X张手牌当杀使用,此杀无视距离且可以指定至多3个目标,每造成一次伤害,你摸一张牌,X为你已损失的体力值且至少为1。", + tianlun_info: "任意一名角色的判定牌生效前,你可以弃置一张场上角色的判定牌代替之。", + hlongyin_info: + "出牌阶段,你可以弃置任意张颜色相同且点数不同的牌,并获得逆时针座位距离与卡牌点数相同的角色区域内的一张牌。每阶段限一次。", + lanzhi_info: "每当你使用一张梅花牌,你可以令所有体力值不大于你的角色回复1点体力。", + lanzhi_old_info: "每当你即将造成伤害,可以防止此伤害,然后摸两张牌。每回合限发动一次。", + tianhuo_info: + "出牌阶段,你可以令所有角色弃置其判定区域内的牌,并受到没有来源的等量火焰伤害,每阶段限一次。", + huanyin_info: + "锁定技,每当你成为其他角色的卡牌的目标时,你进行一次判定,若为黑桃则取消之,若为红桃你摸一张牌。", + luomu_info: "锁定技,每当你造成伤害时,受伤害角色随机弃置一张牌。", + poxing_info: "锁定技,每当你即将造成伤害,若目标的体力值大于你,你令伤害+1。", + liaoyuan_info: + "每当你使用一张杀指定目标后,你可以弃置任意张与此杀花色相同的牌,若如此做,目标需额外打出等量的闪,每少打出一张闪,此杀的伤害+1。", + liaoyuan_info_alter: + "每当你使用一张杀指定目标后,你可以弃置一张与此杀花色相同的牌,若如此做,目标需额外打出一张闪,若目标没打出闪,此杀的伤害+1。", + yishan_info: "每当你受到一次伤害,你可以重新获得最近失去的两张牌。", + huanhun_info: + "当一名角色进入濒死状态时,你可以弃置一张牌并令其进行一次判定,若结果为红色,其回复1点体力,否则其获得你弃置的牌。", + huanhun_info_alter: + "当一名角色进入濒死状态时,你可以弃置一张红色手牌并令其进行一次判定,若结果为红色,其回复1点体力,否则其获得你弃置的牌。", + daixing_info: "结束阶段,你可以弃置任意张牌并获得等量的护甲;这些护甲将在你的下个准备阶段消失。", + swd_wuxie_info: "锁定技,你不能成为其他角色的延时锦囊的目标。", + lqingcheng_info: + "结束阶段,你可以进行判定,若为红色则可以继续判定,最多判定3次,判定结束后将判定成功的牌收入手牌。", + xianjiang_old_info: + "出牌阶段,你可以将一张装备牌永久转化为任意一张其它装备牌,一张牌在一个阶段只能转化一次。", + xianjiang_info: "出牌阶段限一次,你可以弃置一张锦囊牌并随机装备一件装备。", + xianjiang_info_alter: + "出牌阶段限一次,若你装备内没有牌,你可以弃置一张锦囊牌并随机装备一件装备。", + shengong_info: + "每当你需要打出一张杀或闪时,你可以弃置一名其他角色装备区内的一张武器牌或防具牌,视为打出一张杀或闪,然后该角色摸一张牌,你弃一张牌。", + ningjian_info: "你可以将一张红色牌当闪、黑色牌当杀使用或打出。", + taixu_info: + "限定技,你可以弃置你的所有牌(至少1张),并对一名体力值大于1为其他角色造成X点火焰伤害,X为你已损失的体力值且至少为1。", + duoren_info: "每当你闪避一张杀,你可以立即获得来源的武器牌。", + tanlin_info: + "出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你获得双方拼点牌、对该角色使用卡牌无视距离且可以额外使用一张杀直到回合结束,若你没赢,你受到该角色的1点伤害。", + tanlin_info_alter: + "出牌阶段限一次,你可以与一名其他角色进行拼点,若你赢,你获得对方拼点牌、对该角色使用卡牌无视距离且可以额外使用一张杀直到回合结束,若你没赢,你受到该角色的1点伤害。", + pozhen_info: + "每当你受到一次伤害,若你的手牌数大于伤害来源,你可以弃置X张手牌对其造成1点伤害;若你的手牌数小于伤害来源,你可以弃置其X张手牌。X为你与伤害来源的手牌数之差。", + pozhen_info_alter: + "每当你受到一次伤害,若你的手牌数小于伤害来源,你可以弃置其X张手牌。X为你与伤害来源的手牌数之差。", + yunchou_info: + "出牌阶段限一次,你可以弃置一张手牌,并弃置一名其他角色的一张手牌,若两张牌颜色相同,你摸一张牌,否则对方摸一张牌。", + yunchou_info_alter: + "出牌阶段限一次,你可以弃置一张非基本手牌,并弃置一名其他角色的一张手牌,若两张牌颜色相同,你摸一张牌,否则对方摸一张牌。", + swdtianshu_old_info: + "结束阶段,你可以弃置一张牌并从三名随机武将中选择一个,在2X回合后你将其所有技能加入你的天书列表,X为其技能数;在技能加入天书列表时,或于出牌阶段,你可以装备一项天书列表中的技能。", + swdtianshu_info: + "出牌阶段,你可以弃置一张锦囊牌,然后获得一名其他角色的一项技能直到该角色死亡(替换以此法获得的前一个技能)。", + zaowu_info: "出牌阶段限一次,你可以将一张黑桃或红桃手牌当作封印之蛋使用。", + luomei_info: "每当你使用或打出一张梅花花色的牌,你可以摸一张牌。", + xingdian_info: "出牌阶段限一次,你可以弃置一张手牌,然后随机弃置两名敌人各一张牌。", + yulin_info: "每当你即将受到伤害,你可以弃置一张装备牌抵消此伤害。", + funiao_info: "出牌阶段限一次,你可以将一张手牌交给一名其他角色,然后摸一张牌并观看其手牌。", + funiao_old_info: + "出牌阶段,你可以交给一名角色一张手牌,然后观看其手牌,每个阶段对一名角色只能发动一次。", + xuehuang_info: + "限定技,出牌阶段,若你没有黑色手牌,你可以展示并弃置所有手牌,每弃置一张牌视为使用一张火杀,随机指定两名敌人为目标。", + zhuyu_info: "每当一名横置的角色即将受到伤害时,你可以弃置一张红色牌令此伤害+1并变为火属性。", + ningshuang_info: + "每当你成为黑色牌的目标,你可以弃置一张黑色牌将其横置,并摸一张牌,若其已经模置则改为将其翻面。", + zaowu_old_info: "出牌阶段,你可以弃置三张不同类型的牌,创造任意两张牌并获得之。", + xielv_info: + "弃牌阶段结束后,若你的所有手牌(至少两张)颜色均相同,你可以展示所有手牌,然后回复1点体力并弃置场上的所有判定牌。", }, }; }); diff --git a/character/tw.js b/character/tw.js index 20d136399..e4e72e310 100644 --- a/character/tw.js +++ b/character/tw.js @@ -1,2470 +1,3326 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'tw', - connect:true, - characterSort:{ - tw:{ - tw_sp:['tw_yanliang','tw_wenchou','tw_yuantan','tw_zhangzhao','tw_zhanghong','tw_fuwan','tw_yujin','tw_zhaoxiang','tw_hucheer','tw_hejin','tw_mayunlu','tw_re_caohong','tw_zangba','tw_liuhong','tw_tianyu','jiachong','duosidawang','wuban','yuejiu','tw_caocao','tw_zhangmancheng','tw_caozhao','tw_wangchang','tw_puyangxing','tw_jiangji','tw_niujin','tw_xiahouen','tw_xiahoushang','tw_zhangji','tw_zhangnan','tw_fengxí','tw_furong','tw_liwei','tw_yangyi','tw_daxiaoqiao','tw_dengzhi','tw_baoxin','tw_bingyuan','tw_fanchou','tw_haomeng','tw_huchuquan','tw_jianshuo','tw_jiling','tw_liufuren','tw_liuzhang','tw_mateng','tw_niufudongxie','tw_qiaorui','tw_weixu','tw_yanxiang','tw_yufuluo','tw_zhangning','tw_dengzhi','tw_yangyi','tw_yangang','tw_gongsunfan'], - tw_yunchouzhi:['tw_wangcan','tw_dongzhao','tw_bianfuren','tw_feiyi','tw_chenzhen','tw_xunchen'], - tw_yunchouxin:['tw_wangling','tw_huojun','tw_wujing','tw_zhouchu'], - tw_yunchouren:['tw_xujing','tw_qiaogong'], - tw_yunchouyong:['tw_zongyu','tw_chendong','tw_sunyi'], - tw_yunchouyan:['tw_jiangqing'], - tw_zhu:['tw_beimihu','tw_ol_sunjian','ol_liuyu','tw_menghuo'], - tw_swordsman:['xia_yuzhenzi','xia_shie','xia_shitao','xia_guanyu','xia_liubei','xia_xiahousone','xia_xiahoudun','xia_zhangwei','xia_xushu','xia_wangyue','xia_liyàn','xia_tongyuan','xia_lusu','xia_dianwei','xia_zhaoe','xia_xiahouzie'], - tw_mobile:['nashime','tw_gexuan','tw_zhugeguo'], - tw_mobile2:['tw_chengpu','tw_guohuai','old_quancong','tw_caoxiu','tw_guanqiujian','tw_re_fazheng','tw_madai','tw_zhangfei','tw_guyong','tw_handang','tw_xuezong','tw_yl_luzhi'], - tw_yijiang:['tw_caoang','tw_caohong','tw_zumao','tw_dingfeng','tw_maliang','tw_xiahouba'], - tw_english:['kaisa'], + name: "tw", + connect: true, + characterSort: { + tw: { + tw_sp: [ + "tw_yanliang", + "tw_wenchou", + "tw_yuantan", + "tw_zhangzhao", + "tw_zhanghong", + "tw_fuwan", + "tw_yujin", + "tw_zhaoxiang", + "tw_hucheer", + "tw_hejin", + "tw_mayunlu", + "tw_re_caohong", + "tw_zangba", + "tw_liuhong", + "tw_tianyu", + "jiachong", + "duosidawang", + "wuban", + "yuejiu", + "tw_caocao", + "tw_zhangmancheng", + "tw_caozhao", + "tw_wangchang", + "tw_puyangxing", + "tw_jiangji", + "tw_niujin", + "tw_xiahouen", + "tw_xiahoushang", + "tw_zhangji", + "tw_zhangnan", + "tw_fengxí", + "tw_furong", + "tw_liwei", + "tw_yangyi", + "tw_daxiaoqiao", + "tw_dengzhi", + "tw_baoxin", + "tw_bingyuan", + "tw_fanchou", + "tw_haomeng", + "tw_huchuquan", + "tw_jianshuo", + "tw_jiling", + "tw_liufuren", + "tw_liuzhang", + "tw_mateng", + "tw_niufudongxie", + "tw_qiaorui", + "tw_weixu", + "tw_yanxiang", + "tw_yufuluo", + "tw_zhangning", + "tw_dengzhi", + "tw_yangyi", + "tw_yangang", + "tw_gongsunfan", + ], + tw_yunchouzhi: [ + "tw_wangcan", + "tw_dongzhao", + "tw_bianfuren", + "tw_feiyi", + "tw_chenzhen", + "tw_xunchen", + ], + tw_yunchouxin: ["tw_wangling", "tw_huojun", "tw_wujing", "tw_zhouchu"], + tw_yunchouren: ["tw_xujing", "tw_qiaogong"], + tw_yunchouyong: ["tw_zongyu", "tw_chendong", "tw_sunyi"], + tw_yunchouyan: ["tw_jiangqing"], + tw_zhu: ["tw_beimihu", "tw_ol_sunjian", "ol_liuyu", "tw_menghuo"], + tw_swordsman: [ + "xia_yuzhenzi", + "xia_shie", + "xia_shitao", + "xia_guanyu", + "xia_liubei", + "xia_xiahousone", + "xia_xiahoudun", + "xia_zhangwei", + "xia_xushu", + "xia_wangyue", + "xia_liyàn", + "xia_tongyuan", + "xia_lusu", + "xia_dianwei", + "xia_zhaoe", + "xia_xiahouzie", + ], + tw_mobile: ["nashime", "tw_gexuan", "tw_zhugeguo"], + tw_mobile2: [ + "tw_chengpu", + "tw_guohuai", + "old_quancong", + "tw_caoxiu", + "tw_guanqiujian", + "tw_re_fazheng", + "tw_madai", + "tw_zhangfei", + "tw_guyong", + "tw_handang", + "tw_xuezong", + "tw_yl_luzhi", + ], + tw_yijiang: [ + "tw_caoang", + "tw_caohong", + "tw_zumao", + "tw_dingfeng", + "tw_maliang", + "tw_xiahouba", + ], + tw_english: ["kaisa"], }, }, - character:{ - tw_yanliang:['male','qun',4,['twduwang','twylyanshi']], - tw_wenchou:['male','qun',4,['twjuexing','twxiayong']], - tw_yuantan:['male','qun',4,['twqiaosi','twbaizu']], - xia_yuzhenzi:['male','qun',3,['twhuajing','twtianshou']], - xia_shie:['male','wei',4,['twdengjian','twxinshou']], - xia_shitao:['male','qun',4,['twjieqiu','twenchou']], - xia_guanyu:['male','qun',4,['twzhongyi','twchue']], - xia_liubei:['male','shu',4,['twshenyi','twxinghan']], - xia_xiahousone:['female','qun',3,['twchengxi']], - xia_xiahoudun:['male','qun',4,['twdanlie']], - xia_zhangwei:['female','qun',3,['twhuzhong','twfenwang']], - tw_zhanghong:['male','wu',3,['twquanqian','twrouke']], - tw_zhangzhao:['male','wu',3,['twlijian','twchungang']], - tw_ol_sunjian:['male','wu','4/5',['gzyinghun','wulie','twpolu'],['zhu']], - tw_menghuo:['male','qun',4,['huoshou','rezaiqi','twqiushou'],['zhu']], - ol_liuyu:['male','qun',2,['zongzuo','zhige','twchongwang'],['zhu']], - tw_gongsunfan:['male','qun',4,['twhuiyuan','twshoushou']], - tw_yangang:['male','qun',4,['twzhiqu','twxianfeng']], - xia_xiahouzie:['female','qun','3/4',['twxuechang','twduoren']], - xia_zhaoe:['female','qun',3,['twyanshi','twrenchou']], - xia_lusu:['male','qun',4,['twkaizeng','twyangming']], - xia_dianwei:['male','qun',4,['twliexi','twshezhong']], - tw_bingyuan:['male','qun',3,['twbingde','twqingtao']], - tw_niufudongxie:['double','qun',4,['twjuntun','twxiongxi','twxiafeng']], - tw_jianshuo:['male','qun',6,['twkunsi']], - tw_jiangji:['male','wei',3,['twjichou','twjilun']], - tw_mateng:['male','qun',4,['mashu','twxiongzheng','twluannian'],['zhu']], - tw_baoxin:['male','qun',4,['twmutao','twyimou']], - tw_liufuren:['female','qun',3,['twzhuidu','twshigong']], - tw_yufuluo:['male','qun',6,['twjiekuang','twneirao']], - tw_fengxí:['male','shu',4,['twqingkou']], - tw_zhangji:['male','wei',3,['twdingzhen','twyouye']], - tw_zhangnan:['male','shu',4,['twfenwu']], - tw_huchuquan:['male','qun',4,['twfupan']], - tw_liwei:['male','shu',4,['twjiaohua']], - tw_yanxiang:['male','qun',3,['twkujian','twruilian']], - tw_xiahouen:['male','wei',5,['twfujian','twjianwei']], - tw_xiahoushang:['male','wei',4,['twtanfeng']], - tw_qiaorui:['male','qun',5,['twxiawei','twqiongji']], - tw_haomeng:['male','qun',4,['twgongge']], - tw_weixu:['male','qun',4,['twsuizheng','twtuidao']], - xia_xushu:['male','qun',4,['twjiange','twxiawang']], - xia_wangyue:['male','qun',4,['twyulong','twjianming']], - xia_liyàn:['male','qun',4,['twzhenhu','twlvren']], - xia_tongyuan:['male','qun',4,['twchaofeng','twchuanshu']], - tw_zhangning:['female','qun',3,['twxingzhui','twjuchen']], - tw_yangyi:['male','shu',3,['duoduan','twgongsun']], - tw_dengzhi:['male','shu',3,['twjimeng','shuaiyan']], - tw_wangling:['male','wei',4,['twmibei','twxingqi'],['clan:太原王氏']], - tw_zhugeguo:['female','shu',3,['twqirang','twyuhua']], - tw_fanchou:['male','qun',4,['twxingluan']], - tw_xujing:['male','shu',3,['twboming','twejian']], - tw_zhangfei:['male','shu',4,['new_repaoxiao','twxuhe']], - tw_xuezong:['male','wu',3,['funan','twjiexun']], - tw_xunchen:['male','qun',3,['twweipo','mjchenshi','twmouzhi']], - tw_jiangqing:['male','wu',4,['twshangyi','twxiangyu']], - tw_guyong:['male','wu',3,['twgyshenxing','twbingyi']], - tw_chendong:['male','wu',4,['twyilie','twfenming']], - tw_handang:['male','wu',4,['twgongji','twjiefan']], - tw_jiling:['male','qun',4,['twshuangren']], - tw_re_fazheng:['male','shu',3,['twxuanhuo','twenyuan']], - tw_madai:['male','shu',4,['mashu','twqianxi']], - tw_niujin:['male','wei',4,['twcuorui','twliewei']], - tw_guanqiujian:['male','wei',3,['twzhengrong','twhongju']], - tw_daxiaoqiao:['female','wu',3,['twxingwu','twpingting'],['tempname:daxiaoqiao']], - tw_furong:['male','shu',4,['twxuewei','twliechi']], - tw_yl_luzhi:['male','qun',3,['twmingren','twzhenliang']], - tw_liuzhang:['male','qun',3,['jutu','twyaohu','rehuaibi']], - tw_zongyu:['male','shu',3,['twzhibian','twyuyan']], - tw_zhouchu:['male','wu',4,['twguoyi','twchuhai']], - tw_qiaogong:['male','wu',3,['twyizhu','twluanchou']], - tw_feiyi:['male','shu',3,['twshengxi','twkuanji']], - tw_bianfuren:['female','wei',3,['twwanwei','twyuejian']], - tw_chenzhen:['male','shu',3,['twmuyue','twchayi']], - tw_caoxiu:['male','wei',4,['twqianju','twqingxi']], - tw_sunyi:['male','wu',4,['twzaoli']], - tw_puyangxing:['male','wu',4,['twzhengjian','twzhongchi']], - tw_tianyu:['male','wei',4,['twzhenxi','twyangshi']], - old_quancong:['male','wu',4,['zhenshan']], - tw_wujing:['male','wu',4,['twfenghan','twcongji']], - tw_wangcan:['male','wei',3,['twdianyi','twyingji','twshanghe']], - tw_wangchang:['male','wei',3,['twkaiji','twshepan'],['clan:太原王氏']], - tw_caozhao:['male','wei',4,['twfuzuan','twchongqi']], - tw_guohuai:["male","wei",4,["twjingce","yuzhang"]], - tw_chengpu:['male','wu',4,['twlihuo','twchunlao']], - tw_zhangmancheng:['male','qun',4,['twfengji','twyiju','twbudao']], - tw_caocao:['male','qun',4,['twlingfa']], - tw_liuhong:['male','qun',4,['twyujue','twgezhi','twfengqi'],['zhu']], - tw_huojun:['male','shu',4,['twsidai','twjieyu']], - tw_zangba:['male','wei',4,['twhanyu','twhengjiang']], - tw_re_caohong:['male','wei',4,['twyuanhu','twjuezhu']], - tw_mayunlu:['female','shu',4,['mashu','twfengpo']], - tw_hejin:['male','qun',4,['twmouzhu','twyanhuo']], - tw_hucheer:['male','qun',4,['twshenxing','twdaoji']], - tw_yujin:['male','qun',4,['xinzhenjun']], - tw_fuwan:['male','qun',4,['twmoukui']], - tw_zhaoxiang:['female','shu',4,['refanghun','twfuhan','twqueshi']], - yuejiu:['male','qun',4,['cuijin']], - wuban:['male','shu',4,['jintao'],['clan:陈留吴氏']], - duosidawang:['male','qun','4/5',['equan','manji']], - jiachong:['male','qun',3,['beini','dingfa']], - tw_dongzhao:['male','wei',3,['twmiaolve','twyingjia']], - tw_gexuan:['male','qun',3,['twdanfa','twlingbao','twsidao']], - tw_beimihu:['female','qun',3,['zongkui','guju','baijia','bingzhao'],['zhu']], - nashime:['male','qun',3,['chijie','waishi','renshe']], - tw_xiahouba:['male','shu',4,['twyanqin','twbaobian']], - tw_zumao:['male','wu',4,['twtijin']], - tw_caoang:['male','wei',4,['twxiaolian']], - tw_dingfeng:['male','wu',4,['twqijia','twzhuchen']], - tw_caohong:['male','wei',4,['twhuzhu','twliancai']], - tw_maliang:['male','shu',3,['twrangyi','twbaimei']], - kaisa:["male","western",4,["zhengfu"]], + character: { + tw_yanliang: ["male", "qun", 4, ["twduwang", "twylyanshi"]], + tw_wenchou: ["male", "qun", 4, ["twjuexing", "twxiayong"]], + tw_yuantan: ["male", "qun", 4, ["twqiaosi", "twbaizu"]], + xia_yuzhenzi: ["male", "qun", 3, ["twhuajing", "twtianshou"]], + xia_shie: ["male", "wei", 4, ["twdengjian", "twxinshou"]], + xia_shitao: ["male", "qun", 4, ["twjieqiu", "twenchou"]], + xia_guanyu: ["male", "qun", 4, ["twzhongyi", "twchue"]], + xia_liubei: ["male", "shu", 4, ["twshenyi", "twxinghan"]], + xia_xiahousone: ["female", "qun", 3, ["twchengxi"]], + xia_xiahoudun: ["male", "qun", 4, ["twdanlie"]], + xia_zhangwei: ["female", "qun", 3, ["twhuzhong", "twfenwang"]], + tw_zhanghong: ["male", "wu", 3, ["twquanqian", "twrouke"]], + tw_zhangzhao: ["male", "wu", 3, ["twlijian", "twchungang"]], + tw_ol_sunjian: ["male", "wu", "4/5", ["gzyinghun", "wulie", "twpolu"], ["zhu"]], + tw_menghuo: ["male", "qun", 4, ["huoshou", "rezaiqi", "twqiushou"], ["zhu"]], + ol_liuyu: ["male", "qun", 2, ["zongzuo", "zhige", "twchongwang"], ["zhu"]], + tw_gongsunfan: ["male", "qun", 4, ["twhuiyuan", "twshoushou"]], + tw_yangang: ["male", "qun", 4, ["twzhiqu", "twxianfeng"]], + xia_xiahouzie: ["female", "qun", "3/4", ["twxuechang", "twduoren"]], + xia_zhaoe: ["female", "qun", 3, ["twyanshi", "twrenchou"]], + xia_lusu: ["male", "qun", 4, ["twkaizeng", "twyangming"]], + xia_dianwei: ["male", "qun", 4, ["twliexi", "twshezhong"]], + tw_bingyuan: ["male", "qun", 3, ["twbingde", "twqingtao"]], + tw_niufudongxie: ["double", "qun", 4, ["twjuntun", "twxiongxi", "twxiafeng"]], + tw_jianshuo: ["male", "qun", 6, ["twkunsi"]], + tw_jiangji: ["male", "wei", 3, ["twjichou", "twjilun"]], + tw_mateng: ["male", "qun", 4, ["mashu", "twxiongzheng", "twluannian"], ["zhu"]], + tw_baoxin: ["male", "qun", 4, ["twmutao", "twyimou"]], + tw_liufuren: ["female", "qun", 3, ["twzhuidu", "twshigong"]], + tw_yufuluo: ["male", "qun", 6, ["twjiekuang", "twneirao"]], + tw_fengxí: ["male", "shu", 4, ["twqingkou"]], + tw_zhangji: ["male", "wei", 3, ["twdingzhen", "twyouye"]], + tw_zhangnan: ["male", "shu", 4, ["twfenwu"]], + tw_huchuquan: ["male", "qun", 4, ["twfupan"]], + tw_liwei: ["male", "shu", 4, ["twjiaohua"]], + tw_yanxiang: ["male", "qun", 3, ["twkujian", "twruilian"]], + tw_xiahouen: ["male", "wei", 5, ["twfujian", "twjianwei"]], + tw_xiahoushang: ["male", "wei", 4, ["twtanfeng"]], + tw_qiaorui: ["male", "qun", 5, ["twxiawei", "twqiongji"]], + tw_haomeng: ["male", "qun", 4, ["twgongge"]], + tw_weixu: ["male", "qun", 4, ["twsuizheng", "twtuidao"]], + xia_xushu: ["male", "qun", 4, ["twjiange", "twxiawang"]], + xia_wangyue: ["male", "qun", 4, ["twyulong", "twjianming"]], + xia_liyàn: ["male", "qun", 4, ["twzhenhu", "twlvren"]], + xia_tongyuan: ["male", "qun", 4, ["twchaofeng", "twchuanshu"]], + tw_zhangning: ["female", "qun", 3, ["twxingzhui", "twjuchen"]], + tw_yangyi: ["male", "shu", 3, ["duoduan", "twgongsun"]], + tw_dengzhi: ["male", "shu", 3, ["twjimeng", "shuaiyan"]], + tw_wangling: ["male", "wei", 4, ["twmibei", "twxingqi"], ["clan:太原王氏"]], + tw_zhugeguo: ["female", "shu", 3, ["twqirang", "twyuhua"]], + tw_fanchou: ["male", "qun", 4, ["twxingluan"]], + tw_xujing: ["male", "shu", 3, ["twboming", "twejian"]], + tw_zhangfei: ["male", "shu", 4, ["new_repaoxiao", "twxuhe"]], + tw_xuezong: ["male", "wu", 3, ["funan", "twjiexun"]], + tw_xunchen: ["male", "qun", 3, ["twweipo", "mjchenshi", "twmouzhi"]], + tw_jiangqing: ["male", "wu", 4, ["twshangyi", "twxiangyu"]], + tw_guyong: ["male", "wu", 3, ["twgyshenxing", "twbingyi"]], + tw_chendong: ["male", "wu", 4, ["twyilie", "twfenming"]], + tw_handang: ["male", "wu", 4, ["twgongji", "twjiefan"]], + tw_jiling: ["male", "qun", 4, ["twshuangren"]], + tw_re_fazheng: ["male", "shu", 3, ["twxuanhuo", "twenyuan"]], + tw_madai: ["male", "shu", 4, ["mashu", "twqianxi"]], + tw_niujin: ["male", "wei", 4, ["twcuorui", "twliewei"]], + tw_guanqiujian: ["male", "wei", 3, ["twzhengrong", "twhongju"]], + tw_daxiaoqiao: ["female", "wu", 3, ["twxingwu", "twpingting"], ["tempname:daxiaoqiao"]], + tw_furong: ["male", "shu", 4, ["twxuewei", "twliechi"]], + tw_yl_luzhi: ["male", "qun", 3, ["twmingren", "twzhenliang"]], + tw_liuzhang: ["male", "qun", 3, ["jutu", "twyaohu", "rehuaibi"]], + tw_zongyu: ["male", "shu", 3, ["twzhibian", "twyuyan"]], + tw_zhouchu: ["male", "wu", 4, ["twguoyi", "twchuhai"]], + tw_qiaogong: ["male", "wu", 3, ["twyizhu", "twluanchou"]], + tw_feiyi: ["male", "shu", 3, ["twshengxi", "twkuanji"]], + tw_bianfuren: ["female", "wei", 3, ["twwanwei", "twyuejian"]], + tw_chenzhen: ["male", "shu", 3, ["twmuyue", "twchayi"]], + tw_caoxiu: ["male", "wei", 4, ["twqianju", "twqingxi"]], + tw_sunyi: ["male", "wu", 4, ["twzaoli"]], + tw_puyangxing: ["male", "wu", 4, ["twzhengjian", "twzhongchi"]], + tw_tianyu: ["male", "wei", 4, ["twzhenxi", "twyangshi"]], + old_quancong: ["male", "wu", 4, ["zhenshan"]], + tw_wujing: ["male", "wu", 4, ["twfenghan", "twcongji"]], + tw_wangcan: ["male", "wei", 3, ["twdianyi", "twyingji", "twshanghe"]], + tw_wangchang: ["male", "wei", 3, ["twkaiji", "twshepan"], ["clan:太原王氏"]], + tw_caozhao: ["male", "wei", 4, ["twfuzuan", "twchongqi"]], + tw_guohuai: ["male", "wei", 4, ["twjingce", "yuzhang"]], + tw_chengpu: ["male", "wu", 4, ["twlihuo", "twchunlao"]], + tw_zhangmancheng: ["male", "qun", 4, ["twfengji", "twyiju", "twbudao"]], + tw_caocao: ["male", "qun", 4, ["twlingfa"]], + tw_liuhong: ["male", "qun", 4, ["twyujue", "twgezhi", "twfengqi"], ["zhu"]], + tw_huojun: ["male", "shu", 4, ["twsidai", "twjieyu"]], + tw_zangba: ["male", "wei", 4, ["twhanyu", "twhengjiang"]], + tw_re_caohong: ["male", "wei", 4, ["twyuanhu", "twjuezhu"]], + tw_mayunlu: ["female", "shu", 4, ["mashu", "twfengpo"]], + tw_hejin: ["male", "qun", 4, ["twmouzhu", "twyanhuo"]], + tw_hucheer: ["male", "qun", 4, ["twshenxing", "twdaoji"]], + tw_yujin: ["male", "qun", 4, ["xinzhenjun"]], + tw_fuwan: ["male", "qun", 4, ["twmoukui"]], + tw_zhaoxiang: ["female", "shu", 4, ["refanghun", "twfuhan", "twqueshi"]], + yuejiu: ["male", "qun", 4, ["cuijin"]], + wuban: ["male", "shu", 4, ["jintao"], ["clan:陈留吴氏"]], + duosidawang: ["male", "qun", "4/5", ["equan", "manji"]], + jiachong: ["male", "qun", 3, ["beini", "dingfa"]], + tw_dongzhao: ["male", "wei", 3, ["twmiaolve", "twyingjia"]], + tw_gexuan: ["male", "qun", 3, ["twdanfa", "twlingbao", "twsidao"]], + tw_beimihu: ["female", "qun", 3, ["zongkui", "guju", "baijia", "bingzhao"], ["zhu"]], + nashime: ["male", "qun", 3, ["chijie", "waishi", "renshe"]], + tw_xiahouba: ["male", "shu", 4, ["twyanqin", "twbaobian"]], + tw_zumao: ["male", "wu", 4, ["twtijin"]], + tw_caoang: ["male", "wei", 4, ["twxiaolian"]], + tw_dingfeng: ["male", "wu", 4, ["twqijia", "twzhuchen"]], + tw_caohong: ["male", "wei", 4, ["twhuzhu", "twliancai"]], + tw_maliang: ["male", "shu", 3, ["twrangyi", "twbaimei"]], + kaisa: ["male", "western", 4, ["zhengfu"]], }, - characterIntro:{ - yanliang:'颜良(?~200年),字公骥,安平郡堂阳县(今河北省新河县)人。东汉末年河北将领。颜良性格促狭,虽骁勇不可独任,为一夫之勇。官渡之战,袁绍令颜良进攻白马(今河南滑县)。曹操采用军师荀攸“声东击西、轻兵掩袭”之计,大败袁军,颜良本人也被关羽亲自斩杀死,白马之围遂解。据说颜之推是其后人。', - wenchou:'文丑(?~200年),东汉末年河北将领。文丑为一夫之勇。建安五年(200年),带领左将军刘备进驻延津,误中曹操军师荀攸的“饵敌”之计,其麾下“五六千骑”惨败于“不满六百”的曹军骑兵。文丑本人也死于乱军之中,葬于河南省禹州市。', - yuantan:'袁谭(?-205年),字显思,汝南郡汝阳县,袁绍长子,曾任青州刺史。建安元年(196年),击败田楷、孔融,完全占据青州。袁绍去世后,审配等伪立遗令,拥立袁尚为继承人,袁谭不能继位,心怀愤恨。后袁谭、袁尚二人的矛盾彻底爆发,袁谭联合曹操共同攻打袁尚。建安十年,曹操兴兵进攻南皮,袁谭奋力抵抗,终于在曹操急攻之下战败,为曹纯麾下虎豹骑所杀。', - yuzhenzi:'评书三国中的人物,其人有徒弟兼义子童渊、徒弟并州李彦,有徒孙常山赵子龙、北地枪王张绣、张任等人。', - shie:'三国人物,善剑术。桓、灵间,有虎贲王越以剑术称于京师,阿得其法。魏帝曹丕曾从阿学剑术。曹丕在《典论·自叙》中说:“余又学击剑,阅师多矣,四方之法各异,唯京师为善。桓、灵之间,有虎贲王越善斯术,称於京师。河南史阿言昔与越游,具得其法,余从阿学精熟。尝与平虏将军刘勋、奋威将军邓展等共饮,宿闻展善有手臂,晓五兵,又称其能空手入白刃。余与论剑良久,谓将军非法也,余顾尝好之,又得善术,因求与余对。', - shitao:'石韬,字广元,即石广元,颍川(今河南禹州)人,仕魏,官拜典农校尉、郡守。初平年间,石韬与徐庶一同来到荆州,在荆州时与诸葛亮和庞统等人相善。与崔州平(名钧)、孟公威(名建)、徐元直(名庶)为“诸葛四友”。', - xiahousone:'夏侯子萼,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为在貂蝉不在时血婆娑的实际首领。在海外服中,设定为夏侯惇的养女,继承了夏侯紫萼的血婆娑,之后“夏侯紫萼”这个名字就被隐匿于历史之中,而“夏侯子萼”则成为了血婆娑的首领“血蔷薇”的固定名号。', - zhangwei:'张葳,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为被夏侯子萼救下后加入的血婆娑成员。在海外服中,设定为张奂的养女,张奂为宦官迫害时与其失散,为神秘女子所救并学得武艺,后与夏侯紫萼一起建立血婆娑。在李儒分成时为了保护百姓而牺牲。', - nashime:'难升米(なしめ,或なんしょうまい)是倭国大夫。景初二年六月,受女王卑弥呼之命,与都市牛利出使魏国,被魏国拜为率善中郎将。', - jiachong:'贾充(217年—282年),字公闾,平阳襄陵(今山西襄汾)人,三国曹魏至西晋时期大臣,曹魏豫州刺史贾逵之子。西晋王朝的开国元勋。出身平阳贾氏。曾参与镇压淮南二叛和弑杀魏帝曹髦,因此深得司马氏信任,其女儿贾褒(一名荃)及贾南风分别嫁予司马炎弟司马攸及次子司马衷,与司马氏结为姻亲,地位显赫。晋朝建立后,转任车骑将军、散骑常侍、尚书仆射,后升任司空、太尉等要职。更封鲁郡公。咸宁末,为使持节、假黄钺、大都督征讨吴国。吴国平定后,增邑八千户。太康三年(282年),贾充去世。西晋朝廷追赠他为太宰,礼官议谥曰荒,司马炎不采纳,改谥为武。有集五卷。', - duosidawang:'朵思大王是《三国演义》中人物,南蛮秃龙洞的元帅,孟获弟弟孟优的朋友,据说是南蛮第一智者。', - wuban:'吴班,字元雄,生卒年不详,兖州陈留郡(治今河南省开封市)人。三国时期蜀汉将领。为领军,随刘备参加伐吴之战,后又随蜀汉丞相诸葛亮参加北伐曹魏的战争,并于公元231年(建兴九年)的北伐中大破司马懿。官至骠骑将军,封绵竹侯。吴班以豪爽侠义著称于当时,又因族妹吴氏是蜀汉穆皇后,在蜀汉将领中有较高的地位。', - yuejiu:'乐就(?-197),在袁术为攻徐州而大兴七军之际,以督战官之身份担任联络之役。但是,袁术军不幸战败,其也在寿春被曹操军逮捕并遭到斩首。', - huojun:'霍峻(178年—217年),字仲邈,南郡枝江(今湖北枝江)人,东汉末年刘备麾下名将。其兄霍笃曾在故乡聚部众数百人。后霍笃逝世,刘表以霍峻继承其部曲。208年(建安十三年),刘表病逝,霍峻便率部曲归降刘备,并被任为中郎将。后随刘备入蜀,刘备从葭萌还袭刘璋,留霍峻守葭萌城。张鲁遣将杨帛劝降霍峻,霍峻严词拒绝,杨帛退去。后刘璋将扶禁、向存等率万余人由阆水上,攻围霍峻,城中兵不过数百人,霍峻坚守一年,伺机将其击破。刘备定蜀,嘉霍峻之功,于是分广汉为梓潼郡,以峻为梓潼太守、裨将军。三年后去世,还葬成都。刘备亲率群僚临会吊祭,留宿墓上,当时的人都为他感到荣幸。', - zhangmancheng:'张曼成(?—184年6月),东汉末年黄巾之乱时南阳黄巾军首领,杀郡守褚贡,一度占据宛城数月,后为秦颉所杀。', - caozhao:'曹肇(?-244年),字长思,沛国谯县(今安徽亳州)人。三国时期魏国大臣,大司马曹休之子。容貌俊美,有当世才度,深得魏明帝宠信,官至散骑常侍、屯骑校尉。魏明帝临死,与燕王曹宇等托付后事。不果,以长平侯归第。正始五年(244年)卒,追赠为卫将军。', - wangchang:'王昶(2世纪-259年),字文舒,太原郡晋阳县(今山西太原)人。三国时期曹魏将领,东汉代郡太守王泽之子。出身太原王氏,少有名气,进入曹丕幕府,授太子文学。曹丕即位后,拜散骑侍郎,迁兖州刺史,撰写《治论》、《兵书》,作为朝廷提供施政参考。魏明帝曹叡即位后,升任扬烈将军,封关内侯。齐王曹芳即位,迁徐州刺史,拜征南将军。太傅司马懿掌权后,深得器重,奏请伐吴,在江陵取得重大胜利,升任征南大将军、开府仪同三司,晋爵京陵侯。正元年间(255年),参与平定“淮南三乱”有功,迁骠骑大将军,守司空。甘露四年(259年),去世,赠司徒,谥号为穆。', - puyangxing:'濮阳兴(?-264年),字子元,陈留(治今河南开封)人,三国时期东吴大臣,吴景帝孙休末年至末帝孙皓初年任丞相。孙权时为上虞县令,后升任尚书左曹、五官中郎将、会稽太守。孙休即位,征召为太常卫将军、平军国事,封外黄侯。永安三年(260年),力主建丹杨湖田,事倍功半,百姓大怨。后升任丞相。永安七年(264年),孙休去世,濮阳兴与张布迎立孙皓。担任侍郎,兼任青州牧。同年被万彧谮毁,流放广州,途中被孙皓派人追杀,并夷三族。', - re_caohong:'字子廉,沛国谯(今安徽亳县)人,曹操从弟,曾献马并救护曹操。后多随军征伐,平兖州、征刘表、讨祝臂。曹丕即位时封曹洪为骠骑将军。曹叡即位,拜曹洪为后将军,更封乐城侯,后复拜为骠骑将军。曹洪逝世,追谥曰恭侯。', - jiangji:'蒋济(?—249年5月18日),字子通,楚国平阿(今安徽省怀远县常坟镇孔岗)人。三国后期曹魏名臣,历仕曹操、曹丕、曹睿、曹芳四朝。蒋济在汉末出任九江郡吏、扬州别驾。后被曹操聘为丹杨太守,不久升任丞相府主薄,西曹属,成为曹操的心腹谋士。魏文帝时期,蒋济出任东中郎将,代替曹仁统率大军,后升任尚书。魏明帝时期,蒋济出任中护军,封侯关内,功勋颇多。景初年间担任护军将军、散骑常侍等职。曹芳继位之后,转任领军将军,封昌陵亭侯,又代司马懿为太尉。正始十年(249年),蒋济随司马懿推翻曹爽势力之后,晋封都乡侯,同年卒(一说为蒋济觉得失信于曹爽,不久后自责忧愤而死),谥曰景侯。', - huchuquan:'呼厨泉(生卒年不详),东汉末年、三国时期匈奴单于。南匈奴羌渠单于之子,于夫罗之弟。于夫罗死后继任成为单于,曾数次依附,又反叛东汉。建安七年(公元202年),呼厨泉统领南匈奴诸部作乱平阳,钟繇率诸军围之。河北袁氏将领高干、郭援等前来增援呼厨泉,与钟繇及关中诸将大战于平阳。最终,呼厨泉惨败,从此归降曹操。建安二十一年(216年),呼厨泉被留在了邺城,南匈奴遂被分为五部。', - xiahouen:'夏侯恩是古典小说《三国演义》中的人物,为曹操随身之背剑心腹。曹操有宝剑二口:一名“倚天剑”,一名“青釭剑”。倚天剑镇威,青釭剑杀人。倚天剑曹操自佩之,青釭剑令夏侯恩佩之。那青釭剑削铁如泥,锋利无比。《三国演义》第四十一回《刘玄德携民渡江 赵子龙单骑救主》中描写:当时夏侯恩自恃勇力,背着曹操,只顾引人抢夺掳掠。不想撞着赵云,被他一枪刺死。青釭剑自此归赵云所有。', - xiahoushang:'夏侯尚(?~226年),字伯仁,沛国谯郡(今安徽省亳州市)人。三国时期曹魏将领,征西将军夏侯渊的堂侄。曹操平定冀州,以为军司马、五官将文学,迁黄门侍郎,随曹彰远征乌桓,得胜归来。与魏文帝曹丕亲近友好,以为征南将军,领荆州刺史,假节、都督南方诸军事,攻拔蜀国上庸,平定三郡九县,升为征南大将军;江陵击败吴将诸葛瑾,升为荆州牧,封昌陵乡侯。黄初七年(226年),去世,谥号为悼,其子夏侯玄继嗣。正始四年,配享魏武帝曹操庙庭。', - zhangnan:'张南(?-公元222年),字文进。三国时期蜀汉将领。刘备攻伐吴国时,张南担任前部。后刘备被陆逊击败,张南兵败战死。', - fengxí:'冯习(?—222年),字休元,南郡(治今湖北省荆州市公安县)人。三国时期蜀汉将领。随刘备入川,并于刘备攻伐孙吴时担任领军,后在猇亭被吴将陆逊击败,兵败战死。', - liwei:'李遗,生卒年不详,三国时期蜀汉名臣李恢之子,关羽女儿关银屏之夫。正史鲜有其生平记载,多见于关银屏的民间传说,其名在民间传说中被传为“李蔚”,因为遗为多音字且民间传说为口头相传并不知道具体字形之故,当以史书《三国志》作李遗为正。死后夫妇二人合葬于俞元县(今云南澄江)关三小姐墓。其父去世后,继承了汉兴亭候的爵位。', - baoxin:'鲍信(151年-192年),泰山平阳(今山东新泰)人。东汉末年济北相,讨伐董卓的诸路人马之一。鲍信受何进征召在外募兵,回到洛阳时适逢董卓进京,鲍信劝袁绍除掉董卓,袁绍不同意。后袁绍、曹操等人起兵对抗董卓,鲍信也起兵响应。后联盟破裂,鲍信劝戒曹操静观其变。青州黄巾军进攻兖州,刺史刘岱不听鲍信所劝贸然出战,兵败战死。鲍信便把曹操迎立为兖州牧。在与黄巾军交战期间,鲍信为救曹操不幸战死,曹操后来追记功绩,赐封其子。', - bingyuan:'邴原(生卒年不详),字根矩,北海朱虚(今山东临朐东)人。东汉末年名士、大臣。邴原家贫、早孤。初为北海相孔融所举。曹操为司空时,任邴原为东阁祭酒。建安十五年(210年),邴原担任丞相征事,后又代凉茂为五官将长史,闭门自守,非公事不出。随曹操征吴,于途中去世。', - jianshuo:'蹇硕(?—189年),东汉末宦官。中平五年(188年),蹇硕为上军校尉,汉灵帝以蹇硕壮健而有武略,对其特别信任,并以其为西园军元帅,领导袁绍、曹操等八校尉,以监督司隶校尉以下诸官。蹇硕虽然握有兵权,但对何进非常畏忌,曾和宦官们一起说服灵帝派遣何进西击边章、韩遂。中平六年(189年),灵帝在病重时将刘协托给蹇硕。灵帝去世后,蹇硕想先杀何进再立刘协为天子,但因手下司马潘隐与何进有旧对何进使眼色而失败。刘辩继承帝位后,蹇硕与中常侍赵忠、郭胜等写信欲合谋除去何进兄弟,因郭胜与何进为同郡且何进及何皇后发迹亦有其功劳于是亲信何氏便怂恿赵忠等人不听蹇硕之计,且将蹇硕的书信告知何进,何进于是便派黄门将之诛杀,其部下士兵亦被何进所领。', - liufuren:'刘夫人,东汉末年军阀袁绍的后妻,袁谭与袁尚的母亲。袁绍的二子中,袁谭年长而贤惠,袁尚年幼相貌美好。袁绍的后妻刘夫人有宠,她偏爱少子袁尚而讨厌长子袁谭,多次称赞袁尚的才能,袁绍也为三子的容貌感到惊奇,想要作为继承人,于是让袁谭做哥哥的后代,出外任青州刺史,后导致二子相争。。', - niufudongxie:'牛辅,东汉末年武将,东汉相国董卓的女婿。董翓,牛辅之妻,董卓之女。牛辅曾任中郎将,征讨白波军,不能取胜。董卓被杀时,牛辅别屯于陕地。吕布派李肃前去征讨牛辅,被牛辅击败。后来,牛辅营中有士兵半夜背叛出逃,造成内乱,牛辅以为整营皆叛,于是带着金银珠宝,独与亲信胡赤儿等五六人逾城北渡河。赤儿等人以绳索系在牛辅腰间将其从城头放下,但赤儿等因为谋财而在离地面数丈高的地方就松开了绳子使得牛辅重重摔在地上腰部受伤,而后赤儿与诸胡人将牛辅斩首,将其首级送去长安。', - tw_zhangji:'张既(?—223年),字德容,冯翊高陵(今陕西西安市高陵区)人。汉末三国时期曹魏名臣。举秀才出身,授新丰县令,治绩为三辅第一。河东之战时,劝说马腾参与讨伐高干、张晟叛乱。迁京兆尹,抚民兴政,联合夏侯渊平宋建,定临洮,取狄道,安郡民,迁徙氐人。张鲁投降后,建议曹操迁徙汉中百姓充实三辅,辅助曹洪击败吴兰。魏国建立后,拜尚书。黄初二年(221年),临危受命,拜雍州刺史,平定诸胡叛乱。迁凉州刺史,封西乡侯。在任期间,降苏衡,邻戴众,修工事,安抚百姓,平定西平郡麹光叛乱。一生以惠政闻名,征辟杨阜、胡遵等人,皆有名位。黄初四年(223年)去世。魏明帝曹叡即位后,追谥肃侯,其子张缉为关内侯。', - qiaorui:'桥蕤(?—197年),东汉末年袁术部下将领,为袁术开拓地盘立下了一定战功。曹操进攻袁术时,担任迎击军的先锋。在寿春与曹操军大战,被夏侯惇杀死。据正史记载,他曾经被袁术任命为大将军。', - weixu:'魏续,东汉末年吕布帐下名将。与吕布有亲,吕布将高顺兵归续管。汉献帝建安三年(198年),曹操率军攻吕布,围之三月。魏续与侯成、宋宪缚陈宫,降曹。吕布被迫降,被缢杀在白门楼。', - yanxiang:'阎象,东汉末期人物,袁术的主簿。献帝兴平二年(195),手执玉玺的袁术要称帝时,问于部下,只有阎象引用周文王虽拥有三分之二的天下还向殷称臣的故事进行劝谏。却未被采纳。', - yufuluo:'东汉时匈奴单于。亦称於夫罗、栾提于夫罗、于扶罗。羌渠单于子,右贤王。前赵刘渊之祖。于东汉中平年间带兵来到中原协助东汉政府镇压起义,赶上本国叛乱,其父被杀,于是留在中原,与白波军联合,在太原、河东等地劫掠。汉末军阀混战之际,于夫罗先后与袁绍、张杨、袁术等人联合,两次与曹操交战,均被击败。后来,于夫罗去世,其弟呼厨泉继任成为单于,其子刘豹被立为左贤王。', - sp_xunchen:'荀谌,字友若,荀彧之兄(一说荀彧之弟),荀绲之子,颍川人。曾任军阀袁绍的幕僚。帮助袁绍游说韩馥,夺取了冀州。', - sp_xujing:'许靖(?—222年),字文休。汝南郡平舆县(今河南省平舆县)人。汉末至三国蜀汉时期重臣、名士、评论家。许靖因与从弟许邵俱以品评人物而闻名于世。后被刘翊推举为孝廉,任尚书郎。曾先后投奔孔伷、陈祎、许贡、王朗等人,于孙策攻王朗前与家属俱避难交州,受到交趾太守士燮礼待。其后受益州牧刘璋邀请,相继为巴郡、广汉、蜀郡太守。于刘备包围成都时欲越墙叛逃,为刘璋所获。刘备定蜀后欲将其弃用,在法正的建议下方以其为左将军长史。建安二十三年(218年),刘备称汉中王,任命许靖为汉中王傅。章武元年(221年),刘备称帝,任命许靖为司徒,位列三公。章武二年(222年),去世。有文集二卷。', - sp_zongyu:'宗预(?-264年),字德艳 ,荆州南阳郡安众县(今河南省南阳市)人。三国时期蜀汉官员、将领。曾随张飞入蜀助平益州,又受辟为丞相诸葛亮手下主簿,升任参军、右中郎将。诸葛亮逝世后,宗预受命出使孙吴,得到孙权的赞赏。迁后将军,出督永安,又升任征西大将军,并受封关内侯。公元258年(景耀元年),因病回成都,受任镇军大将军。蜀汉灭亡后,宗预随后主刘禅徙往洛阳,在中途病逝。宗预为人坦率耿直,多次出使孙吴并深得孙权的敬重,为吴、汉两国同盟的巩固作出了一定的贡献。', - sp_chendong:'陈武,东吴将领,孙策攻打刘繇,陈武前来相助,孙策非常喜爱陈武,拜为校尉,使作先锋。陈武以十数骑兵力杀敌五十余人。后于赤壁等战役屡立功勋。董袭献上严虎的人头来降孙策。赤壁之战,董袭受周瑜命,分兵去汉阳,合肥会战时接应太史慈,逍遥津支援孙权。濡须口之战时,董袭在船上督战,船覆董袭坚守殉职。', - xia_wangyue:'王越,东汉末年游侠(生卒年不详),乃辽东燕山人士,擅使剑术, 三国时期史阿的师父,曹丕的师公,官职虎贲将军。在史书《典论》中略有记载。', - liyàn:'李彦,号称"并州第一戟",是童渊的师兄。早年间两人在玉真子门下一起习武,后成年出师开枝散叶。同为并州人的吕布在得知李彦的名声后,投入其门下学习武艺。', - re_fazheng:'字孝直,本为刘璋部下,刘备围成都时劝说刘璋投降,而后又与刘备进取汉中,献计将曹操大将夏侯渊斩首。法正善奇谋,深受刘备信任和敬重。', - xin_guyong:'为蔡邕之徒。其为人少言语,不饮酒,严厉正大,被张纮推荐仕于孙权。孙权任命他为会稽郡丞,行太守事,后不断升迁,官至吴国丞相。顾雍为官,多进良言,有功于吴。', - zhaoe:'赵娥,东汉酒泉郡禄福县(即肃州)人。丈夫庞子夏,表氏县(今高台县)人。庞子夏去世后,赵娥在禄福县抚养其子庞淯。她的父亲被李寿杀死。灵帝光和二年(公元179年)二月上旬的一天早晨,赵娥在都亭前与李寿相遇,她奋力挥刀杀死了李寿,随后到了都亭尊长的面前认罪伏法。后来,凉州刺史周洪、酒泉太守刘班等人共同上表朝廷,禀奏赵娥的烈义行为,刻石立碑显其赵家门户。黄门侍郎梁宽还著书追述赵娥的事迹,为其作传。西晋政治家傅玄为其作《秦女休行》诗,加以赞美。', - xiahouzie:'夏侯紫萼,游卡桌游《三国杀阵面对决》中虚构的人物。幼年因天天帮病种的母亲采紫萼得其名。亲眼目睹母亲被宦官所杀,愤怒之下夺过佩剑斩下宦官的头颅。被神秘人所救,发现了自己的身世,决心与宦官争斗到底。后再闯荡江湖的过程中,与夏侯惇义结金兰,以夏侯家姓氏称呼。', - yangang:'严纲(163~191年),东汉末年公孙瓒部下的冀州刺史。汉献帝初平二年(191年),袁绍与公孙瓒在界桥交战,严纲为袁绍部下麹义所斩。', - gongsunfan:'公孙范,辽西令支(今河北迁安)人。东汉末年武将,公孙瓒从弟,官至勃海太守。公孙瓒起兵攻打袁绍之时,袁绍畏惧公孙瓒的势力,将自己的勃海太守印绶给予公孙范,意图和解,结果公孙范反而起勃海之兵帮助公孙瓒。初平二年(191年),公孙范以勃海兵助公孙瓒率二万人大破青、徐黄巾军。最后于界桥之战与公孙瓒一同败走。', - zhangzhao:'张昭(156年-236年),字子布。徐州彭城县(今江苏省徐州市)人。汉末三国时期孙吴政权重臣。东汉末年,张昭为避战乱而南渡至扬州。孙策创业时,任命其为长史、抚军中郎将,将文武之事都委任于张昭。孙策临终前,将其弟孙权托付给张昭,张昭率群僚辅立孙权,并安抚百姓、讨伐叛军,与周瑜等辅助孙权稳定局势。孙权每次出征,常留张昭镇守后方,领幕府事,并敬称他为“张公”。赤壁之战时,张昭鉴于曹操势大,持主降论,从而被排挤出军政决策中心。孙权代理车骑将军时,任命张昭为军师。孙权被封为吴王后,任绥远将军,封由拳侯。此后曾参与撰定朝仪。孙权两次要设立丞相时,众人都推举张昭,孙权以张昭敢于直谏、性格刚直为由而不用他,先后用孙邵、顾雍。黄龙元年(229年),孙权称帝,张昭以年老多病为由,上还官位及所统领部属,改拜辅吴将军、班亚三司,改封娄侯。晚年时一度不参与政事,在家著书,即使偶有参加朝议,也常与孙权产生激烈冲突。嘉禾五年(236年),张昭去世,享年八十一岁,谥号“文”。张昭容貌严正,敢于直言谏诤,一生以忠于孙氏基业为任,但因其与孙权在个性、军政策略等方面的深层矛盾,使其以“入宫则拜孤,出宫则拜君”的地位,却终身不得任丞相。著有《春秋左氏传解》及《论语注》,今皆佚失。', - zhanghong:'张纮(153年~212年),字子纲,徐州广陵(江苏省扬州市广陵区人)人。东汉末年文学家、官员,和张昭一起合称“二张”。曾被大将军何进、太尉朱儁、司空荀爽辟为掾属,皆不就,避难江东。孙策平定江东前,亲自多次登门邀请,张纮出仕为官。孙权即位时,建议孙权迁都秣陵。建安十七年(212年),病逝,时年六十岁,孙权为之流涕。', + characterIntro: { + yanliang: + "颜良(?~200年),字公骥,安平郡堂阳县(今河北省新河县)人。东汉末年河北将领。颜良性格促狭,虽骁勇不可独任,为一夫之勇。官渡之战,袁绍令颜良进攻白马(今河南滑县)。曹操采用军师荀攸“声东击西、轻兵掩袭”之计,大败袁军,颜良本人也被关羽亲自斩杀死,白马之围遂解。据说颜之推是其后人。", + wenchou: + "文丑(?~200年),东汉末年河北将领。文丑为一夫之勇。建安五年(200年),带领左将军刘备进驻延津,误中曹操军师荀攸的“饵敌”之计,其麾下“五六千骑”惨败于“不满六百”的曹军骑兵。文丑本人也死于乱军之中,葬于河南省禹州市。", + yuantan: + "袁谭(?-205年),字显思,汝南郡汝阳县,袁绍长子,曾任青州刺史。建安元年(196年),击败田楷、孔融,完全占据青州。袁绍去世后,审配等伪立遗令,拥立袁尚为继承人,袁谭不能继位,心怀愤恨。后袁谭、袁尚二人的矛盾彻底爆发,袁谭联合曹操共同攻打袁尚。建安十年,曹操兴兵进攻南皮,袁谭奋力抵抗,终于在曹操急攻之下战败,为曹纯麾下虎豹骑所杀。", + yuzhenzi: + "评书三国中的人物,其人有徒弟兼义子童渊、徒弟并州李彦,有徒孙常山赵子龙、北地枪王张绣、张任等人。", + shie: "三国人物,善剑术。桓、灵间,有虎贲王越以剑术称于京师,阿得其法。魏帝曹丕曾从阿学剑术。曹丕在《典论·自叙》中说:“余又学击剑,阅师多矣,四方之法各异,唯京师为善。桓、灵之间,有虎贲王越善斯术,称於京师。河南史阿言昔与越游,具得其法,余从阿学精熟。尝与平虏将军刘勋、奋威将军邓展等共饮,宿闻展善有手臂,晓五兵,又称其能空手入白刃。余与论剑良久,谓将军非法也,余顾尝好之,又得善术,因求与余对。", + shitao: "石韬,字广元,即石广元,颍川(今河南禹州)人,仕魏,官拜典农校尉、郡守。初平年间,石韬与徐庶一同来到荆州,在荆州时与诸葛亮和庞统等人相善。与崔州平(名钧)、孟公威(名建)、徐元直(名庶)为“诸葛四友”。", + xiahousone: + "夏侯子萼,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为在貂蝉不在时血婆娑的实际首领。在海外服中,设定为夏侯惇的养女,继承了夏侯紫萼的血婆娑,之后“夏侯紫萼”这个名字就被隐匿于历史之中,而“夏侯子萼”则成为了血婆娑的首领“血蔷薇”的固定名号。", + zhangwei: + "张葳,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为被夏侯子萼救下后加入的血婆娑成员。在海外服中,设定为张奂的养女,张奂为宦官迫害时与其失散,为神秘女子所救并学得武艺,后与夏侯紫萼一起建立血婆娑。在李儒分成时为了保护百姓而牺牲。", + nashime: + "难升米(なしめ,或なんしょうまい)是倭国大夫。景初二年六月,受女王卑弥呼之命,与都市牛利出使魏国,被魏国拜为率善中郎将。", + jiachong: + "贾充(217年—282年),字公闾,平阳襄陵(今山西襄汾)人,三国曹魏至西晋时期大臣,曹魏豫州刺史贾逵之子。西晋王朝的开国元勋。出身平阳贾氏。曾参与镇压淮南二叛和弑杀魏帝曹髦,因此深得司马氏信任,其女儿贾褒(一名荃)及贾南风分别嫁予司马炎弟司马攸及次子司马衷,与司马氏结为姻亲,地位显赫。晋朝建立后,转任车骑将军、散骑常侍、尚书仆射,后升任司空、太尉等要职。更封鲁郡公。咸宁末,为使持节、假黄钺、大都督征讨吴国。吴国平定后,增邑八千户。太康三年(282年),贾充去世。西晋朝廷追赠他为太宰,礼官议谥曰荒,司马炎不采纳,改谥为武。有集五卷。", + duosidawang: + "朵思大王是《三国演义》中人物,南蛮秃龙洞的元帅,孟获弟弟孟优的朋友,据说是南蛮第一智者。", + wuban: "吴班,字元雄,生卒年不详,兖州陈留郡(治今河南省开封市)人。三国时期蜀汉将领。为领军,随刘备参加伐吴之战,后又随蜀汉丞相诸葛亮参加北伐曹魏的战争,并于公元231年(建兴九年)的北伐中大破司马懿。官至骠骑将军,封绵竹侯。吴班以豪爽侠义著称于当时,又因族妹吴氏是蜀汉穆皇后,在蜀汉将领中有较高的地位。", + yuejiu: "乐就(?-197),在袁术为攻徐州而大兴七军之际,以督战官之身份担任联络之役。但是,袁术军不幸战败,其也在寿春被曹操军逮捕并遭到斩首。", + huojun: "霍峻(178年—217年),字仲邈,南郡枝江(今湖北枝江)人,东汉末年刘备麾下名将。其兄霍笃曾在故乡聚部众数百人。后霍笃逝世,刘表以霍峻继承其部曲。208年(建安十三年),刘表病逝,霍峻便率部曲归降刘备,并被任为中郎将。后随刘备入蜀,刘备从葭萌还袭刘璋,留霍峻守葭萌城。张鲁遣将杨帛劝降霍峻,霍峻严词拒绝,杨帛退去。后刘璋将扶禁、向存等率万余人由阆水上,攻围霍峻,城中兵不过数百人,霍峻坚守一年,伺机将其击破。刘备定蜀,嘉霍峻之功,于是分广汉为梓潼郡,以峻为梓潼太守、裨将军。三年后去世,还葬成都。刘备亲率群僚临会吊祭,留宿墓上,当时的人都为他感到荣幸。", + zhangmancheng: + "张曼成(?—184年6月),东汉末年黄巾之乱时南阳黄巾军首领,杀郡守褚贡,一度占据宛城数月,后为秦颉所杀。", + caozhao: + "曹肇(?-244年),字长思,沛国谯县(今安徽亳州)人。三国时期魏国大臣,大司马曹休之子。容貌俊美,有当世才度,深得魏明帝宠信,官至散骑常侍、屯骑校尉。魏明帝临死,与燕王曹宇等托付后事。不果,以长平侯归第。正始五年(244年)卒,追赠为卫将军。", + wangchang: + "王昶(2世纪-259年),字文舒,太原郡晋阳县(今山西太原)人。三国时期曹魏将领,东汉代郡太守王泽之子。出身太原王氏,少有名气,进入曹丕幕府,授太子文学。曹丕即位后,拜散骑侍郎,迁兖州刺史,撰写《治论》、《兵书》,作为朝廷提供施政参考。魏明帝曹叡即位后,升任扬烈将军,封关内侯。齐王曹芳即位,迁徐州刺史,拜征南将军。太傅司马懿掌权后,深得器重,奏请伐吴,在江陵取得重大胜利,升任征南大将军、开府仪同三司,晋爵京陵侯。正元年间(255年),参与平定“淮南三乱”有功,迁骠骑大将军,守司空。甘露四年(259年),去世,赠司徒,谥号为穆。", + puyangxing: + "濮阳兴(?-264年),字子元,陈留(治今河南开封)人,三国时期东吴大臣,吴景帝孙休末年至末帝孙皓初年任丞相。孙权时为上虞县令,后升任尚书左曹、五官中郎将、会稽太守。孙休即位,征召为太常卫将军、平军国事,封外黄侯。永安三年(260年),力主建丹杨湖田,事倍功半,百姓大怨。后升任丞相。永安七年(264年),孙休去世,濮阳兴与张布迎立孙皓。担任侍郎,兼任青州牧。同年被万彧谮毁,流放广州,途中被孙皓派人追杀,并夷三族。", + re_caohong: + "字子廉,沛国谯(今安徽亳县)人,曹操从弟,曾献马并救护曹操。后多随军征伐,平兖州、征刘表、讨祝臂。曹丕即位时封曹洪为骠骑将军。曹叡即位,拜曹洪为后将军,更封乐城侯,后复拜为骠骑将军。曹洪逝世,追谥曰恭侯。", + jiangji: + "蒋济(?—249年5月18日),字子通,楚国平阿(今安徽省怀远县常坟镇孔岗)人。三国后期曹魏名臣,历仕曹操、曹丕、曹睿、曹芳四朝。蒋济在汉末出任九江郡吏、扬州别驾。后被曹操聘为丹杨太守,不久升任丞相府主薄,西曹属,成为曹操的心腹谋士。魏文帝时期,蒋济出任东中郎将,代替曹仁统率大军,后升任尚书。魏明帝时期,蒋济出任中护军,封侯关内,功勋颇多。景初年间担任护军将军、散骑常侍等职。曹芳继位之后,转任领军将军,封昌陵亭侯,又代司马懿为太尉。正始十年(249年),蒋济随司马懿推翻曹爽势力之后,晋封都乡侯,同年卒(一说为蒋济觉得失信于曹爽,不久后自责忧愤而死),谥曰景侯。", + huchuquan: + "呼厨泉(生卒年不详),东汉末年、三国时期匈奴单于。南匈奴羌渠单于之子,于夫罗之弟。于夫罗死后继任成为单于,曾数次依附,又反叛东汉。建安七年(公元202年),呼厨泉统领南匈奴诸部作乱平阳,钟繇率诸军围之。河北袁氏将领高干、郭援等前来增援呼厨泉,与钟繇及关中诸将大战于平阳。最终,呼厨泉惨败,从此归降曹操。建安二十一年(216年),呼厨泉被留在了邺城,南匈奴遂被分为五部。", + xiahouen: + "夏侯恩是古典小说《三国演义》中的人物,为曹操随身之背剑心腹。曹操有宝剑二口:一名“倚天剑”,一名“青釭剑”。倚天剑镇威,青釭剑杀人。倚天剑曹操自佩之,青釭剑令夏侯恩佩之。那青釭剑削铁如泥,锋利无比。《三国演义》第四十一回《刘玄德携民渡江 赵子龙单骑救主》中描写:当时夏侯恩自恃勇力,背着曹操,只顾引人抢夺掳掠。不想撞着赵云,被他一枪刺死。青釭剑自此归赵云所有。", + xiahoushang: + "夏侯尚(?~226年),字伯仁,沛国谯郡(今安徽省亳州市)人。三国时期曹魏将领,征西将军夏侯渊的堂侄。曹操平定冀州,以为军司马、五官将文学,迁黄门侍郎,随曹彰远征乌桓,得胜归来。与魏文帝曹丕亲近友好,以为征南将军,领荆州刺史,假节、都督南方诸军事,攻拔蜀国上庸,平定三郡九县,升为征南大将军;江陵击败吴将诸葛瑾,升为荆州牧,封昌陵乡侯。黄初七年(226年),去世,谥号为悼,其子夏侯玄继嗣。正始四年,配享魏武帝曹操庙庭。", + zhangnan: + "张南(?-公元222年),字文进。三国时期蜀汉将领。刘备攻伐吴国时,张南担任前部。后刘备被陆逊击败,张南兵败战死。", + fengxí: "冯习(?—222年),字休元,南郡(治今湖北省荆州市公安县)人。三国时期蜀汉将领。随刘备入川,并于刘备攻伐孙吴时担任领军,后在猇亭被吴将陆逊击败,兵败战死。", + liwei: "李遗,生卒年不详,三国时期蜀汉名臣李恢之子,关羽女儿关银屏之夫。正史鲜有其生平记载,多见于关银屏的民间传说,其名在民间传说中被传为“李蔚”,因为遗为多音字且民间传说为口头相传并不知道具体字形之故,当以史书《三国志》作李遗为正。死后夫妇二人合葬于俞元县(今云南澄江)关三小姐墓。其父去世后,继承了汉兴亭候的爵位。", + baoxin: "鲍信(151年-192年),泰山平阳(今山东新泰)人。东汉末年济北相,讨伐董卓的诸路人马之一。鲍信受何进征召在外募兵,回到洛阳时适逢董卓进京,鲍信劝袁绍除掉董卓,袁绍不同意。后袁绍、曹操等人起兵对抗董卓,鲍信也起兵响应。后联盟破裂,鲍信劝戒曹操静观其变。青州黄巾军进攻兖州,刺史刘岱不听鲍信所劝贸然出战,兵败战死。鲍信便把曹操迎立为兖州牧。在与黄巾军交战期间,鲍信为救曹操不幸战死,曹操后来追记功绩,赐封其子。", + bingyuan: + "邴原(生卒年不详),字根矩,北海朱虚(今山东临朐东)人。东汉末年名士、大臣。邴原家贫、早孤。初为北海相孔融所举。曹操为司空时,任邴原为东阁祭酒。建安十五年(210年),邴原担任丞相征事,后又代凉茂为五官将长史,闭门自守,非公事不出。随曹操征吴,于途中去世。", + jianshuo: + "蹇硕(?—189年),东汉末宦官。中平五年(188年),蹇硕为上军校尉,汉灵帝以蹇硕壮健而有武略,对其特别信任,并以其为西园军元帅,领导袁绍、曹操等八校尉,以监督司隶校尉以下诸官。蹇硕虽然握有兵权,但对何进非常畏忌,曾和宦官们一起说服灵帝派遣何进西击边章、韩遂。中平六年(189年),灵帝在病重时将刘协托给蹇硕。灵帝去世后,蹇硕想先杀何进再立刘协为天子,但因手下司马潘隐与何进有旧对何进使眼色而失败。刘辩继承帝位后,蹇硕与中常侍赵忠、郭胜等写信欲合谋除去何进兄弟,因郭胜与何进为同郡且何进及何皇后发迹亦有其功劳于是亲信何氏便怂恿赵忠等人不听蹇硕之计,且将蹇硕的书信告知何进,何进于是便派黄门将之诛杀,其部下士兵亦被何进所领。", + liufuren: + "刘夫人,东汉末年军阀袁绍的后妻,袁谭与袁尚的母亲。袁绍的二子中,袁谭年长而贤惠,袁尚年幼相貌美好。袁绍的后妻刘夫人有宠,她偏爱少子袁尚而讨厌长子袁谭,多次称赞袁尚的才能,袁绍也为三子的容貌感到惊奇,想要作为继承人,于是让袁谭做哥哥的后代,出外任青州刺史,后导致二子相争。。", + niufudongxie: + "牛辅,东汉末年武将,东汉相国董卓的女婿。董翓,牛辅之妻,董卓之女。牛辅曾任中郎将,征讨白波军,不能取胜。董卓被杀时,牛辅别屯于陕地。吕布派李肃前去征讨牛辅,被牛辅击败。后来,牛辅营中有士兵半夜背叛出逃,造成内乱,牛辅以为整营皆叛,于是带着金银珠宝,独与亲信胡赤儿等五六人逾城北渡河。赤儿等人以绳索系在牛辅腰间将其从城头放下,但赤儿等因为谋财而在离地面数丈高的地方就松开了绳子使得牛辅重重摔在地上腰部受伤,而后赤儿与诸胡人将牛辅斩首,将其首级送去长安。", + tw_zhangji: + "张既(?—223年),字德容,冯翊高陵(今陕西西安市高陵区)人。汉末三国时期曹魏名臣。举秀才出身,授新丰县令,治绩为三辅第一。河东之战时,劝说马腾参与讨伐高干、张晟叛乱。迁京兆尹,抚民兴政,联合夏侯渊平宋建,定临洮,取狄道,安郡民,迁徙氐人。张鲁投降后,建议曹操迁徙汉中百姓充实三辅,辅助曹洪击败吴兰。魏国建立后,拜尚书。黄初二年(221年),临危受命,拜雍州刺史,平定诸胡叛乱。迁凉州刺史,封西乡侯。在任期间,降苏衡,邻戴众,修工事,安抚百姓,平定西平郡麹光叛乱。一生以惠政闻名,征辟杨阜、胡遵等人,皆有名位。黄初四年(223年)去世。魏明帝曹叡即位后,追谥肃侯,其子张缉为关内侯。", + qiaorui: + "桥蕤(?—197年),东汉末年袁术部下将领,为袁术开拓地盘立下了一定战功。曹操进攻袁术时,担任迎击军的先锋。在寿春与曹操军大战,被夏侯惇杀死。据正史记载,他曾经被袁术任命为大将军。", + weixu: "魏续,东汉末年吕布帐下名将。与吕布有亲,吕布将高顺兵归续管。汉献帝建安三年(198年),曹操率军攻吕布,围之三月。魏续与侯成、宋宪缚陈宫,降曹。吕布被迫降,被缢杀在白门楼。", + yanxiang: + "阎象,东汉末期人物,袁术的主簿。献帝兴平二年(195),手执玉玺的袁术要称帝时,问于部下,只有阎象引用周文王虽拥有三分之二的天下还向殷称臣的故事进行劝谏。却未被采纳。", + yufuluo: + "东汉时匈奴单于。亦称於夫罗、栾提于夫罗、于扶罗。羌渠单于子,右贤王。前赵刘渊之祖。于东汉中平年间带兵来到中原协助东汉政府镇压起义,赶上本国叛乱,其父被杀,于是留在中原,与白波军联合,在太原、河东等地劫掠。汉末军阀混战之际,于夫罗先后与袁绍、张杨、袁术等人联合,两次与曹操交战,均被击败。后来,于夫罗去世,其弟呼厨泉继任成为单于,其子刘豹被立为左贤王。", + sp_xunchen: + "荀谌,字友若,荀彧之兄(一说荀彧之弟),荀绲之子,颍川人。曾任军阀袁绍的幕僚。帮助袁绍游说韩馥,夺取了冀州。", + sp_xujing: + "许靖(?—222年),字文休。汝南郡平舆县(今河南省平舆县)人。汉末至三国蜀汉时期重臣、名士、评论家。许靖因与从弟许邵俱以品评人物而闻名于世。后被刘翊推举为孝廉,任尚书郎。曾先后投奔孔伷、陈祎、许贡、王朗等人,于孙策攻王朗前与家属俱避难交州,受到交趾太守士燮礼待。其后受益州牧刘璋邀请,相继为巴郡、广汉、蜀郡太守。于刘备包围成都时欲越墙叛逃,为刘璋所获。刘备定蜀后欲将其弃用,在法正的建议下方以其为左将军长史。建安二十三年(218年),刘备称汉中王,任命许靖为汉中王傅。章武元年(221年),刘备称帝,任命许靖为司徒,位列三公。章武二年(222年),去世。有文集二卷。", + sp_zongyu: + "宗预(?-264年),字德艳 ,荆州南阳郡安众县(今河南省南阳市)人。三国时期蜀汉官员、将领。曾随张飞入蜀助平益州,又受辟为丞相诸葛亮手下主簿,升任参军、右中郎将。诸葛亮逝世后,宗预受命出使孙吴,得到孙权的赞赏。迁后将军,出督永安,又升任征西大将军,并受封关内侯。公元258年(景耀元年),因病回成都,受任镇军大将军。蜀汉灭亡后,宗预随后主刘禅徙往洛阳,在中途病逝。宗预为人坦率耿直,多次出使孙吴并深得孙权的敬重,为吴、汉两国同盟的巩固作出了一定的贡献。", + sp_chendong: + "陈武,东吴将领,孙策攻打刘繇,陈武前来相助,孙策非常喜爱陈武,拜为校尉,使作先锋。陈武以十数骑兵力杀敌五十余人。后于赤壁等战役屡立功勋。董袭献上严虎的人头来降孙策。赤壁之战,董袭受周瑜命,分兵去汉阳,合肥会战时接应太史慈,逍遥津支援孙权。濡须口之战时,董袭在船上督战,船覆董袭坚守殉职。", + xia_wangyue: + "王越,东汉末年游侠(生卒年不详),乃辽东燕山人士,擅使剑术, 三国时期史阿的师父,曹丕的师公,官职虎贲将军。在史书《典论》中略有记载。", + liyàn: '李彦,号称"并州第一戟",是童渊的师兄。早年间两人在玉真子门下一起习武,后成年出师开枝散叶。同为并州人的吕布在得知李彦的名声后,投入其门下学习武艺。', + re_fazheng: + "字孝直,本为刘璋部下,刘备围成都时劝说刘璋投降,而后又与刘备进取汉中,献计将曹操大将夏侯渊斩首。法正善奇谋,深受刘备信任和敬重。", + xin_guyong: + "为蔡邕之徒。其为人少言语,不饮酒,严厉正大,被张纮推荐仕于孙权。孙权任命他为会稽郡丞,行太守事,后不断升迁,官至吴国丞相。顾雍为官,多进良言,有功于吴。", + zhaoe: "赵娥,东汉酒泉郡禄福县(即肃州)人。丈夫庞子夏,表氏县(今高台县)人。庞子夏去世后,赵娥在禄福县抚养其子庞淯。她的父亲被李寿杀死。灵帝光和二年(公元179年)二月上旬的一天早晨,赵娥在都亭前与李寿相遇,她奋力挥刀杀死了李寿,随后到了都亭尊长的面前认罪伏法。后来,凉州刺史周洪、酒泉太守刘班等人共同上表朝廷,禀奏赵娥的烈义行为,刻石立碑显其赵家门户。黄门侍郎梁宽还著书追述赵娥的事迹,为其作传。西晋政治家傅玄为其作《秦女休行》诗,加以赞美。", + xiahouzie: + "夏侯紫萼,游卡桌游《三国杀阵面对决》中虚构的人物。幼年因天天帮病种的母亲采紫萼得其名。亲眼目睹母亲被宦官所杀,愤怒之下夺过佩剑斩下宦官的头颅。被神秘人所救,发现了自己的身世,决心与宦官争斗到底。后再闯荡江湖的过程中,与夏侯惇义结金兰,以夏侯家姓氏称呼。", + yangang: + "严纲(163~191年),东汉末年公孙瓒部下的冀州刺史。汉献帝初平二年(191年),袁绍与公孙瓒在界桥交战,严纲为袁绍部下麹义所斩。", + gongsunfan: + "公孙范,辽西令支(今河北迁安)人。东汉末年武将,公孙瓒从弟,官至勃海太守。公孙瓒起兵攻打袁绍之时,袁绍畏惧公孙瓒的势力,将自己的勃海太守印绶给予公孙范,意图和解,结果公孙范反而起勃海之兵帮助公孙瓒。初平二年(191年),公孙范以勃海兵助公孙瓒率二万人大破青、徐黄巾军。最后于界桥之战与公孙瓒一同败走。", + zhangzhao: + "张昭(156年-236年),字子布。徐州彭城县(今江苏省徐州市)人。汉末三国时期孙吴政权重臣。东汉末年,张昭为避战乱而南渡至扬州。孙策创业时,任命其为长史、抚军中郎将,将文武之事都委任于张昭。孙策临终前,将其弟孙权托付给张昭,张昭率群僚辅立孙权,并安抚百姓、讨伐叛军,与周瑜等辅助孙权稳定局势。孙权每次出征,常留张昭镇守后方,领幕府事,并敬称他为“张公”。赤壁之战时,张昭鉴于曹操势大,持主降论,从而被排挤出军政决策中心。孙权代理车骑将军时,任命张昭为军师。孙权被封为吴王后,任绥远将军,封由拳侯。此后曾参与撰定朝仪。孙权两次要设立丞相时,众人都推举张昭,孙权以张昭敢于直谏、性格刚直为由而不用他,先后用孙邵、顾雍。黄龙元年(229年),孙权称帝,张昭以年老多病为由,上还官位及所统领部属,改拜辅吴将军、班亚三司,改封娄侯。晚年时一度不参与政事,在家著书,即使偶有参加朝议,也常与孙权产生激烈冲突。嘉禾五年(236年),张昭去世,享年八十一岁,谥号“文”。张昭容貌严正,敢于直言谏诤,一生以忠于孙氏基业为任,但因其与孙权在个性、军政策略等方面的深层矛盾,使其以“入宫则拜孤,出宫则拜君”的地位,却终身不得任丞相。著有《春秋左氏传解》及《论语注》,今皆佚失。", + zhanghong: + "张纮(153年~212年),字子纲,徐州广陵(江苏省扬州市广陵区人)人。东汉末年文学家、官员,和张昭一起合称“二张”。曾被大将军何进、太尉朱儁、司空荀爽辟为掾属,皆不就,避难江东。孙策平定江东前,亲自多次登门邀请,张纮出仕为官。孙权即位时,建议孙权迁都秣陵。建安十七年(212年),病逝,时年六十岁,孙权为之流涕。", }, - card:{ - dz_mantianguohai:{ - fullskin:true, - type:'trick', - enable:true, - derivation:'tw_dongzhao', - global:['dz_mantianguohai'], - selectTarget:[1,2], - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('hej')>0; + card: { + dz_mantianguohai: { + fullskin: true, + type: "trick", + enable: true, + derivation: "tw_dongzhao", + global: ["dz_mantianguohai"], + selectTarget: [1, 2], + filterTarget: function (card, player, target) { + return target != player && target.countCards("hej") > 0; }, - content:function(){ - player.gainPlayerCard(target,'hej',true); + content: function () { + player.gainPlayerCard(target, "hej", true); }, - contentAfter:function(){ - 'step 0' - var evtx=event.getParent(); - event.targets=targets.filter(function(target){ - return target.hasHistory('lose',function(evt){ - return evt.getParent(3).name=='dz_mantianguohai'&&evt.getParent(4)==evtx; + contentAfter: function () { + "step 0"; + var evtx = event.getParent(); + event.targets = targets.filter(function (target) { + return target.hasHistory("lose", function (evt) { + return evt.getParent(3).name == "dz_mantianguohai" && evt.getParent(4) == evtx; }); }); - if(!event.targets.length||!player.countCards('he')) event.finish(); - 'step 1' - var target=targets.shift(); - event.target=target; - var next=player.chooseCard('he',true,'交给'+get.translation(target)+'一张牌'); - if(player.hasSkill('twyingjia')&&player.countUsed('dz_mantianguohai')==1) next.set('ai',function(card){ - if(card.name=='dz_mantianguohai') return -10; - return -get.value(card,_status.event.getParent().target); - }); - 'step 2' - if(result.bool){ - player.give(result.cards,target); + if (!event.targets.length || !player.countCards("he")) event.finish(); + "step 1"; + var target = targets.shift(); + event.target = target; + var next = player.chooseCard("he", true, "交给" + get.translation(target) + "一张牌"); + if (player.hasSkill("twyingjia") && player.countUsed("dz_mantianguohai") == 1) + next.set("ai", function (card) { + if (card.name == "dz_mantianguohai") return -10; + return -get.value(card, _status.event.getParent().target); + }); + "step 2"; + if (result.bool) { + player.give(result.cards, target); } - 'step 3' - if(targets.length&&player.countCards('h')>0) event.goto(1); + "step 3"; + if (targets.length && player.countCards("h") > 0) event.goto(1); }, - ai:{ - order:6, - tag:{ - lose:1, - loseCard:1, + ai: { + order: 6, + tag: { + lose: 1, + loseCard: 1, }, - result:{ - target:-0.1, + result: { + target: -0.1, }, }, }, - gx_lingbaoxianhu:{ - fullskin:true, - type:'equip', - subtype:'equip1', - derivation:'tw_gexuan', - distance:{attackFrom:-2}, - ai:{ - basic:{ - equipValue:4.5, - } + gx_lingbaoxianhu: { + fullskin: true, + type: "equip", + subtype: "equip1", + derivation: "tw_gexuan", + distance: { attackFrom: -2 }, + ai: { + basic: { + equipValue: 4.5, + }, }, - skills:['gx_lingbaoxianhu'] + skills: ["gx_lingbaoxianhu"], }, - gx_taijifuchen:{ - fullskin:true, - type:'equip', - subtype:'equip1', - derivation:'tw_gexuan', - distance:{attackFrom:-4}, - ai:{ - basic:{ - equipValue:4.5, - } + gx_taijifuchen: { + fullskin: true, + type: "equip", + subtype: "equip1", + derivation: "tw_gexuan", + distance: { attackFrom: -4 }, + ai: { + basic: { + equipValue: 4.5, + }, }, - skills:['gx_taijifuchen'] + skills: ["gx_taijifuchen"], }, - gx_chongyingshenfu:{ - fullskin:true, - type:'equip', - subtype:'equip2', - derivation:'tw_gexuan', - ai:{ - basic:{ - equipValue:7, - } + gx_chongyingshenfu: { + fullskin: true, + type: "equip", + subtype: "equip2", + derivation: "tw_gexuan", + ai: { + basic: { + equipValue: 7, + }, }, - skills:['gx_chongyingshenfu'], - loseDelay:false, + skills: ["gx_chongyingshenfu"], + loseDelay: false, }, - meiyingqiang:{ - fullskin:true, - type:'equip', - subtype:'equip1', - cardimage:'yinyueqiang', - derivation:'tw_zhaoxiang', - distance:{attackFrom:-2}, - ai:{ - basic:{ - equipValue:4.5, - } + meiyingqiang: { + fullskin: true, + type: "equip", + subtype: "equip1", + cardimage: "yinyueqiang", + derivation: "tw_zhaoxiang", + distance: { attackFrom: -2 }, + ai: { + basic: { + equipValue: 4.5, + }, }, - skills:['meiyingqiang'], + skills: ["meiyingqiang"], }, }, - characterFilter:{ - nashime:function(mode){ - return mode!='guozhan'; + characterFilter: { + nashime: function (mode) { + return mode != "guozhan"; }, - tw_xiahouba:function(mode){ - return mode!='guozhan'; + tw_xiahouba: function (mode) { + return mode != "guozhan"; }, }, - skill:{ + skill: { //颜良文丑,但是颜良+文丑 - twduwang:{ - audio:3, - dutySkill:true, - derivation:['twxiayong','twylyanshix'], - global:'twduwang_global', - group:['twduwang_effect','twduwang_achieve','twduwang_fail'], - onremove:['twduwang','twduwang_fail'], - subSkill:{ - effect:{ - audio:'twduwang1.mp3', - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(target=>{ - return target!=player&&target.hasCard(card=>{ - if(get.position(card)=='h') return true; - return target.canUse(get.autoViewAs({name:'juedou'},[card]),player,false); - },'he'); + twduwang: { + audio: 3, + dutySkill: true, + derivation: ["twxiayong", "twylyanshix"], + global: "twduwang_global", + group: ["twduwang_effect", "twduwang_achieve", "twduwang_fail"], + onremove: ["twduwang", "twduwang_fail"], + subSkill: { + effect: { + audio: "twduwang1.mp3", + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((target) => { + return ( + target != player && + target.hasCard((card) => { + if (get.position(card) == "h") return true; + return target.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + player, + false + ); + }, "he") + ); }); }, - async cost(event,trigger,player){ - let {result}=await player.chooseTarget([1,3],(_,player,target)=>{ - return target!=player&&target.hasCard(card=>{ - if(get.position(card)=='h') return true; - return target.canUse(get.autoViewAs({name:'juedou'},[card]),player,false); - },'he'); - }).set('prompt',get.prompt('twduwang')).set('ai',target=>{ - const player=get.event('player'); - const num=game.countPlayer(current=>{ - return current!=player&¤t.hasCard(card=>{ - if(get.position(card)=='h') return true; - return current.canUse(get.autoViewAs({name:'juedou'},[card]),player,false); - },'he')&&get.effect(current,{name:'guohe_copy2'},current,player)+get.effect(player,{name:'juedou'},current,player)>0; - }); - return (Math.min(num,3)+1)*get.effect(player,{name:'draw'},player,player)+get.effect(target,{name:'guohe_copy2'},target,player)+get.effect(player,{name:'juedou'},target,player); - }).set('prompt2','选择至多三名其他角色并摸选择角色数+1的牌,然后这些角色须将一张牌当作【决斗】对你使用'); - if(result.bool) result.targets.sortBySeat(); - event.result=result; + async cost(event, trigger, player) { + let { result } = await player + .chooseTarget([1, 3], (_, player, target) => { + return ( + target != player && + target.hasCard((card) => { + if (get.position(card) == "h") return true; + return target.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + player, + false + ); + }, "he") + ); + }) + .set("prompt", get.prompt("twduwang")) + .set("ai", (target) => { + const player = get.event("player"); + const num = game.countPlayer((current) => { + return ( + current != player && + current.hasCard((card) => { + if (get.position(card) == "h") return true; + return current.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + player, + false + ); + }, "he") && + get.effect(current, { name: "guohe_copy2" }, current, player) + + get.effect(player, { name: "juedou" }, current, player) > + 0 + ); + }); + return ( + (Math.min(num, 3) + 1) * + get.effect(player, { name: "draw" }, player, player) + + get.effect(target, { name: "guohe_copy2" }, target, player) + + get.effect(player, { name: "juedou" }, target, player) + ); + }) + .set( + "prompt2", + "选择至多三名其他角色并摸选择角色数+1的牌,然后这些角色须将一张牌当作【决斗】对你使用" + ); + if (result.bool) result.targets.sortBySeat(); + event.result = result; }, - async content(event,trigger,player){ - const targets=event.targets; - await player.draw(targets.length+1); + async content(event, trigger, player) { + const targets = event.targets; + await player.draw(targets.length + 1); await game.asyncDelayx(); - for(const target of targets){ - if(!target.hasCard(card=>{ - return target.canUse(get.autoViewAs({name:'juedou'},[card]),player,false); - },'he')) continue; - await target.chooseToUse() - .set('forced',true) - .set('openskilldialog','独往:将一张牌当作【决斗】对'+get.translation(player)+'使用') - .set('norestore',true) - .set('_backupevent','twduwang_backup') - .set('targetRequired',true) - .set('complexSelect',true) - .set('custom',{ - add:{}, - replace:{window:function(){}} - }) - .backup('twduwang_backup') - .set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }) - .set('sourcex',player) - .set('addCount',false); + for (const target of targets) { + if ( + !target.hasCard((card) => { + return target.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + player, + false + ); + }, "he") + ) + continue; + await target + .chooseToUse() + .set("forced", true) + .set( + "openskilldialog", + "独往:将一张牌当作【决斗】对" + get.translation(player) + "使用" + ) + .set("norestore", true) + .set("_backupevent", "twduwang_backup") + .set("targetRequired", true) + .set("complexSelect", true) + .set("custom", { + add: {}, + replace: { window: function () {} }, + }) + .backup("twduwang_backup") + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", player) + .set("addCount", false); await game.asyncDelayx(); } }, }, - backup:{ - viewAs:{name:'juedou'}, - position:'he', - filterCard(card,player){ - const cardx=get.autoViewAs({name:'juedou'},[card]); - return lib.filter.targetEnabledx(cardx,player,get.event('sourcex')); + backup: { + viewAs: { name: "juedou" }, + position: "he", + filterCard(card, player) { + const cardx = get.autoViewAs({ name: "juedou" }, [card]); + return lib.filter.targetEnabledx(cardx, player, get.event("sourcex")); }, - check(card){ - if(get.name(card)=='sha') return 5-get.value(card); - return 8-get.value(card); + check(card) { + if (get.name(card) == "sha") return 5 - get.value(card); + return 8 - get.value(card); }, - precontent(){ + precontent() { delete event.result.skill; - } + }, }, - achieve:{ - audio:'twduwang2.mp3', - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - if(player.storage.twduwang_fail) return false; - const history=player.actionHistory; - if(history.length<2) return false; - for(let i=history.length-2;i>=0;i--){ - if(history[i].isMe&&!history[i].isSkipped){ - let num=history[i].useCard.filter(evt=>{ - return evt.card.name=='juedou'; - }).length,targets=game.players.slice().concat(game.dead.slice()); - for(const target of targets){ - num+=target.actionHistory[i].useCard.filter(evt=>{ - return evt.card.name=='juedou'&&evt.targets&&evt.targets.includes(player); + achieve: { + audio: "twduwang2.mp3", + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + if (player.storage.twduwang_fail) return false; + const history = player.actionHistory; + if (history.length < 2) return false; + for (let i = history.length - 2; i >= 0; i--) { + if (history[i].isMe && !history[i].isSkipped) { + let num = history[i].useCard.filter((evt) => { + return evt.card.name == "juedou"; + }).length, + targets = game.players.slice().concat(game.dead.slice()); + for (const target of targets) { + num += target.actionHistory[i].useCard.filter((evt) => { + return ( + evt.card.name == "juedou" && + evt.targets && + evt.targets.includes(player) + ); }).length; } - return num>=(targets.length<4?3:4); + return num >= (targets.length < 4 ? 3 : 4); } } return false; }, - forced:true, - skillAnimation:true, - animationColor:'metal', - async content(event,trigger,player){ - player.awakenSkill('twduwang'); - game.log(player,'完成使命'); - if(player.awakenedSkills.includes('twduwang')){ - player.restoreSkill('twduwang'); - game.log(player,'重置了技能','#g【独往】'); + forced: true, + skillAnimation: true, + animationColor: "metal", + async content(event, trigger, player) { + player.awakenSkill("twduwang"); + game.log(player, "完成使命"); + if (player.awakenedSkills.includes("twduwang")) { + player.restoreSkill("twduwang"); + game.log(player, "重置了技能", "#g【独往】"); } - if(!player.storage.twduwang_fail){ - player.storage.twduwang_fail=true; - game.log(player,'修改了技能','#g【独往】'); + if (!player.storage.twduwang_fail) { + player.storage.twduwang_fail = true; + game.log(player, "修改了技能", "#g【独往】"); } - let result,bool1=(player.hasSkill('twxiayong',null,false,false)),bool2=(!player.awakenedSkills.includes('twylyanshi')&&player.storage.twduwang_ylyanshi); - if(bool1&&bool2) result={index:2}; - else if(bool1) result={index:1}; - else if(bool2) result={index:0}; - else result=await player.chooseControl().set('choiceList',[ - '获得〖狭勇〗', - '重置〖延势〗并为其添加历战效果', - ]).set('prompt','独往:请选择一项').set('ai',()=>{ - const player=get.event('player'),num=game.countPlayer(current=>{ - return current!=player&¤t.hasCard(card=>{ - if(get.position(card)=='h') return true; - return current.canUse(get.autoViewAs({name:'juedou'},[card]),player,false); - },'he')&&(get.effect(current,{name:'guohe_copy2'},current,player)/2.5+get.effect(player,{name:'juedou'},current,player)>0); - }); - return num>=2?0:1; - }).forResult(); - if(result.index==0) await player.addSkills('twxiayong'); - if(result.index==1){ - player.popup('twylyanshi'); - if(player.awakenedSkills.includes('twylyanshi')){ - player.restoreSkill('twylyanshi'); - game.log(player,'重置了技能','#g【延势】'); + let result, + bool1 = player.hasSkill("twxiayong", null, false, false), + bool2 = + !player.awakenedSkills.includes("twylyanshi") && + player.storage.twduwang_ylyanshi; + if (bool1 && bool2) result = { index: 2 }; + else if (bool1) result = { index: 1 }; + else if (bool2) result = { index: 0 }; + else + result = await player + .chooseControl() + .set("choiceList", ["获得〖狭勇〗", "重置〖延势〗并为其添加历战效果"]) + .set("prompt", "独往:请选择一项") + .set("ai", () => { + const player = get.event("player"), + num = game.countPlayer((current) => { + return ( + current != player && + current.hasCard((card) => { + if (get.position(card) == "h") return true; + return current.canUse( + get.autoViewAs({ name: "juedou" }, [card]), + player, + false + ); + }, "he") && + get.effect( + current, + { name: "guohe_copy2" }, + current, + player + ) / + 2.5 + + get.effect( + player, + { name: "juedou" }, + current, + player + ) > + 0 + ); + }); + return num >= 2 ? 0 : 1; + }) + .forResult(); + if (result.index == 0) await player.addSkills("twxiayong"); + if (result.index == 1) { + player.popup("twylyanshi"); + if (player.awakenedSkills.includes("twylyanshi")) { + player.restoreSkill("twylyanshi"); + game.log(player, "重置了技能", "#g【延势】"); } - if(!player.storage.twduwang_ylyanshi){ - player.storage.twduwang_ylyanshi=true; - game.log(player,'修改了技能','#g【延势】'); + if (!player.storage.twduwang_ylyanshi) { + player.storage.twduwang_ylyanshi = true; + game.log(player, "修改了技能", "#g【延势】"); } } }, }, - fail:{ - audio:'twduwang3.mp3', - trigger:{player:'die'}, - forceDie:true, - filter(event,player){ + fail: { + audio: "twduwang3.mp3", + trigger: { player: "die" }, + forceDie: true, + filter(event, player) { return !player.storage.twduwang_fail; }, - forced:true, - content(){ - player.awakenSkill('twduwang'); - game.log(player,'使命失败'); + forced: true, + content() { + player.awakenSkill("twduwang"); + game.log(player, "使命失败"); }, }, - global:{ - mod:{ - cardSavable(card,player,target){ - if(card.name=='tao'&&target!=player&&target.hasSkill('twduwang')&&!target.storage.twduwang_fail) return false; + global: { + mod: { + cardSavable(card, player, target) { + if ( + card.name == "tao" && + target != player && + target.hasSkill("twduwang") && + !target.storage.twduwang_fail + ) + return false; }, }, - audio:'twduwang3.mp3', - trigger:{player:'dying'}, - filter(event,player){ - return player.hasSkill('twduwang')&&!player.storage.twduwang_fail; + audio: "twduwang3.mp3", + trigger: { player: "dying" }, + filter(event, player) { + return player.hasSkill("twduwang") && !player.storage.twduwang_fail; }, - forced:true, - content(){}, + forced: true, + content() {}, }, }, }, - twylyanshi:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter(event,player){ - return ['juedou','binglinchengxiax'].concat(get.zhinangs()).some(name=>{ - const info={name:name}; - return get.info(info)&&player.hasCard(card=>{ - return get.name(card)=='sha'&&event.filterCard({name:name,cards:[card]},player,event); - },'hs'); + twylyanshi: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filter(event, player) { + return ["juedou", "binglinchengxiax"].concat(get.zhinangs()).some((name) => { + const info = { name: name }; + return ( + get.info(info) && + player.hasCard((card) => { + return ( + get.name(card) == "sha" && + event.filterCard({ name: name, cards: [card] }, player, event) + ); + }, "hs") + ); }); }, - limited:true, - skillAnimation:true, - animationColor:'fire', - onremove:['twylyanshi','twduwang_ylyanshi'], - chooseButton:{ - dialog(event,player){ - const list=['juedou','binglinchengxiax'].concat(get.zhinangs()).filter(name=>{ - const info={name:name}; - return get.info(info)&&player.hasCard(card=>{ - return get.name(card)=='sha'&&event.filterCard({name:name,cards:[card]},player,event); - },'hs'); - }).map(name=>[get.translation(get.type(name)),'',name]); - return ui.create.dialog('延势',[list,'vcard']); + limited: true, + skillAnimation: true, + animationColor: "fire", + onremove: ["twylyanshi", "twduwang_ylyanshi"], + chooseButton: { + dialog(event, player) { + const list = ["juedou", "binglinchengxiax"] + .concat(get.zhinangs()) + .filter((name) => { + const info = { name: name }; + return ( + get.info(info) && + player.hasCard((card) => { + return ( + get.name(card) == "sha" && + event.filterCard({ name: name, cards: [card] }, player, event) + ); + }, "hs") + ); + }) + .map((name) => [get.translation(get.type(name)), "", name]); + return ui.create.dialog("延势", [list, "vcard"]); }, - check(button){ - return get.event('player').getUseValue({name:button.link[2]}); + check(button) { + return get.event("player").getUseValue({ name: button.link[2] }); }, - backup(links,player){ + backup(links, player) { return { - audio:'twylyanshi', - filterCard(card,player){ - return get.name(card)=='sha'; + audio: "twylyanshi", + filterCard(card, player) { + return get.name(card) == "sha"; }, - popname:true, - check(card){ - return 5-get.value(card); + popname: true, + check(card) { + return 5 - get.value(card); }, - position:'hs', - viewAs:{name:links[0][2]}, - precontent(){ + position: "hs", + viewAs: { name: links[0][2] }, + precontent() { delete event.result.skill; - player.logSkill('twylyanshi'); - player.awakenSkill('twylyanshi'); - if(player.storage.twduwang_ylyanshi){ - player.when({global:'phaseEnd'}).then(()=>{ - if(player.awakenedSkills.includes('twylyanshi')){ - player.popup('历战'); - player.restoreSkill('twylyanshi'); - game.log(player,'触发了','#g【延势】','的','#y历战','效果'); + player.logSkill("twylyanshi"); + player.awakenSkill("twylyanshi"); + if (player.storage.twduwang_ylyanshi) { + player.when({ global: "phaseEnd" }).then(() => { + if (player.awakenedSkills.includes("twylyanshi")) { + player.popup("历战"); + player.restoreSkill("twylyanshi"); + game.log(player, "触发了", "#g【延势】", "的", "#y历战", "效果"); } }); } }, - } + }; + }, + prompt(links, player) { + return "将一张【杀】当作" + "【" + get.translation(links[0][2]) + "】使用"; }, - prompt(links,player){ - return '将一张【杀】当作'+'【'+get.translation(links[0][2])+'】使用'; - } }, - subSkill:{backup:{}}, - hiddenCard(player,name){ - if(player.awakenedSkills.includes('twylyanshi')||!player.countCards('hs',card=>_status.connectMode||get.name(card)=='sha')) return false; - return ['juedou','binglinchengxiax'].concat(get.zhinangs()).includes(name); + subSkill: { backup: {} }, + hiddenCard(player, name) { + if ( + player.awakenedSkills.includes("twylyanshi") || + !player.countCards("hs", (card) => _status.connectMode || get.name(card) == "sha") + ) + return false; + return ["juedou", "binglinchengxiax"].concat(get.zhinangs()).includes(name); }, - ai:{ - order(item,player){ - if(!player||_status.event.type!='phase') return 0.001; - let max=0,names=['juedou','binglinchengxiax'].concat(get.zhinangs()).filter(name=>{ - const info={name:name}; - return get.info(info)&&player.hasCard(card=>{ - return get.name(card)=='sha'&&player.hasValueTarget(get.autoViewAs(info,[card]),true,true); - },'hs'); + ai: { + order(item, player) { + if (!player || _status.event.type != "phase") return 0.001; + let max = 0, + names = ["juedou", "binglinchengxiax"].concat(get.zhinangs()).filter((name) => { + const info = { name: name }; + return ( + get.info(info) && + player.hasCard((card) => { + return ( + get.name(card) == "sha" && + player.hasValueTarget(get.autoViewAs(info, [card]), true, true) + ); + }, "hs") + ); + }); + if (!names.length) return 0; + names = names.map((namex) => { + return { name: namex }; }); - if(!names.length) return 0; - names=names.map(namex=>{return {name:namex}}); - names.forEach(card=>{ - if(player.getUseValue(card)>0){ - let temp=get.order(card); - if(temp>max) max=temp; + names.forEach((card) => { + if (player.getUseValue(card) > 0) { + let temp = get.order(card); + if (temp > max) max = temp; } }); - if(max>0) max+=0.3; + if (max > 0) max += 0.3; return max; }, - result:{player:1}, + result: { player: 1 }, }, }, - twjuexing:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>get.info('twjuexing').filterTarget(null,player,target)); + twjuexing: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => + get.info("twjuexing").filterTarget(null, player, target) + ); }, - filterTarget(_,player,target){ - const card=new lib.element.VCard({name:'juedou'}); - return target!=player&&player.canUse(card,target); + filterTarget(_, player, target) { + const card = new lib.element.VCard({ name: "juedou" }); + return target != player && player.canUse(card, target); }, - usable:1, - onremove:'twjuexing_lizhan', - async content(event,trigger,player){ - player.when({global:'phaseEnd'}).then(()=>{ - player.popup('历战'); - player.addSkill('twjuexing_lizhan'); - player.addMark('twjuexing_lizhan',1,false); - game.log(player,'触发了','#g【绝行】','的','#y历战','效果'); + usable: 1, + onremove: "twjuexing_lizhan", + async content(event, trigger, player) { + player.when({ global: "phaseEnd" }).then(() => { + player.popup("历战"); + player.addSkill("twjuexing_lizhan"); + player.addMark("twjuexing_lizhan", 1, false); + game.log(player, "触发了", "#g【绝行】", "的", "#y历战", "效果"); }); - const target=event.target; - const card=new lib.element.VCard({name:'juedou'}); - player.addTempSkill('twjuexing_effect'); - player.when({global:'useCardAfter'}).filter(evtx=>evtx.getParent()==event) - .then(()=>{ - let list=[]; - var targets=[player].concat(trigger.targets); - for(const i of targets){ - if(i.isIn()&&i.hasCard(card=>card.hasGaintag('twjuexing'),'h')){ - list.push([i,i.getCards('h',card=>card.hasGaintag('twjuexing'))]); - } - } - if(list.length){ - game.loseAsync({lose_list:list}).setContent('discardMultiple'); - } - }).then(()=>{ - let listx=[]; - var targets=[player].concat(trigger.targets); - for(const i of targets){ - if(i.isIn()&&i.getExpansions('twjuexing_buff').length){ - listx.push([i,i.getExpansions('twjuexing_buff')]); - } - } - if(listx.length){ - game.loseAsync({gain_list:listx,animate:'draw'}).setContent('gaincardMultiple'); - } - }).then(()=>{ - var targets=[player].concat(trigger.targets); - targets.forEach(current=>{ - current.removeSkill('twjuexing_buff'); - }); - game.delay(); - }); - await player.useCard(card,target,false); - }, - ai:{ - order:1, - result:{ - target(player,target){ - return get.sgn(get.attitude(player,target))*get.effect(target,{name:'juedou'},player,player)*((player.getHp()+1)/(target.getHp()+1)); - }, - }, - }, - subSkill:{ - effect:{ - trigger:{global:'useCardToBegin'}, - forced:true, - popup:false, - charlotte:true, - filter(event,player){ - return event.getParent(2).name==='twjuexing'; - }, - async content(event,trigger,player){ - const target=trigger.target; - player.addSkill('twjuexing_buff'); - target.addSkill('twjuexing_buff'); - let list=[]; - for(const i of [player,target]){ - if(i.isIn()&&i.countCards('h')){ - list.push([i,i.getCards('h')]); + const target = event.target; + const card = new lib.element.VCard({ name: "juedou" }); + player.addTempSkill("twjuexing_effect"); + player + .when({ global: "useCardAfter" }) + .filter((evtx) => evtx.getParent() == event) + .then(() => { + let list = []; + var targets = [player].concat(trigger.targets); + for (const i of targets) { + if (i.isIn() && i.hasCard((card) => card.hasGaintag("twjuexing"), "h")) { + list.push([i, i.getCards("h", (card) => card.hasGaintag("twjuexing"))]); } } - if(list.length){ - await game.loseAsync({ - lose_list:list, - log:true, - animate:'giveAuto', - gaintag:['twjuexing_buff'], - }).setContent(get.info('sbquhu').addToExpansionMultiple); + if (list.length) { + game.loseAsync({ lose_list: list }).setContent("discardMultiple"); } - if(player.getHp()>0) await player.draw(player.getHp(),(target.getHp()>0?'nodelay':'')).set('gaintag',['twjuexing']); - if(target.getHp()>0) await target.draw(target.getHp()).set('gaintag',['twjuexing']); + }) + .then(() => { + let listx = []; + var targets = [player].concat(trigger.targets); + for (const i of targets) { + if (i.isIn() && i.getExpansions("twjuexing_buff").length) { + listx.push([i, i.getExpansions("twjuexing_buff")]); + } + } + if (listx.length) { + game.loseAsync({ gain_list: listx, animate: "draw" }).setContent( + "gaincardMultiple" + ); + } + }) + .then(() => { + var targets = [player].concat(trigger.targets); + targets.forEach((current) => { + current.removeSkill("twjuexing_buff"); + }); + game.delay(); + }); + await player.useCard(card, target, false); + }, + ai: { + order: 1, + result: { + target(player, target) { + return ( + get.sgn(get.attitude(player, target)) * + get.effect(target, { name: "juedou" }, player, player) * + ((player.getHp() + 1) / (target.getHp() + 1)) + ); + }, + }, + }, + subSkill: { + effect: { + trigger: { global: "useCardToBegin" }, + forced: true, + popup: false, + charlotte: true, + filter(event, player) { + return event.getParent(2).name === "twjuexing"; + }, + async content(event, trigger, player) { + const target = trigger.target; + player.addSkill("twjuexing_buff"); + target.addSkill("twjuexing_buff"); + let list = []; + for (const i of [player, target]) { + if (i.isIn() && i.countCards("h")) { + list.push([i, i.getCards("h")]); + } + } + if (list.length) { + await game + .loseAsync({ + lose_list: list, + log: true, + animate: "giveAuto", + gaintag: ["twjuexing_buff"], + }) + .setContent(get.info("sbquhu").addToExpansionMultiple); + } + if (player.getHp() > 0) + await player + .draw(player.getHp(), target.getHp() > 0 ? "nodelay" : "") + .set("gaintag", ["twjuexing"]); + if (target.getHp() > 0) + await target.draw(target.getHp()).set("gaintag", ["twjuexing"]); await game.asyncDelay(); - } - }, - lizhan:{ - charlotte:true, - onremove:true, - marktext:'战', - intro:{content:'因【绝行】摸牌时,摸牌数+#'}, - trigger:{player:'drawBegin'}, - filter(event,player){ - if(!player.hasMark('twjuexing_lizhan')) return false; - return (event.gaintag||[]).includes('twjuexing'); - }, - forced:true, - popup:false, - content(){ - player.popup('历战'); - game.log(player,'触发了','#g【绝行】','的','#y历战','效果'); - trigger.num+=player.countMark('twjuexing_lizhan'); }, }, - buff:{ - charlotte:true, - onremove(player,skill){ - const cards=player.getExpansions(skill); - if(cards.length) player.gain(cards,'gain2'); + lizhan: { + charlotte: true, + onremove: true, + marktext: "战", + intro: { content: "因【绝行】摸牌时,摸牌数+#" }, + trigger: { player: "drawBegin" }, + filter(event, player) { + if (!player.hasMark("twjuexing_lizhan")) return false; + return (event.gaintag || []).includes("twjuexing"); }, - intro:{ - markcount:'expansion', - mark(dialog,_,player){ - var cards=player.getExpansions('twjuexing_buff'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; + forced: true, + popup: false, + content() { + player.popup("历战"); + game.log(player, "触发了", "#g【绝行】", "的", "#y历战", "效果"); + trigger.num += player.countMark("twjuexing_lizhan"); + }, + }, + buff: { + charlotte: true, + onremove(player, skill) { + const cards = player.getExpansions(skill); + if (cards.length) player.gain(cards, "gain2"); + }, + intro: { + markcount: "expansion", + mark(dialog, _, player) { + var cards = player.getExpansions("twjuexing_buff"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, }, }, - twxiayong:{ - audio:2, - audioname:['tw_yanliang'], - locked:true, - group:'twxiayong_effect', - subSkill:{ - effect:{ - trigger:{global:'damageBegin1'}, - filter(event,player){ - if(event.getParent().type!='card'||event.card.name!='juedou'||!event.player.isIn()) return false; - const evt=game.getGlobalHistory('useCard',evt=>evt.card==event.card)[0]; - if(evt&&evt.targets&&(event.player!=player||player.countCards('h'))){ - if(evt.player==player){ - return evt.targets.includes(event.player)&&event.player!=player; + twxiayong: { + audio: 2, + audioname: ["tw_yanliang"], + locked: true, + group: "twxiayong_effect", + subSkill: { + effect: { + trigger: { global: "damageBegin1" }, + filter(event, player) { + if ( + event.getParent().type != "card" || + event.card.name != "juedou" || + !event.player.isIn() + ) + return false; + const evt = game.getGlobalHistory("useCard", (evt) => evt.card == event.card)[0]; + if (evt && evt.targets && (event.player != player || player.countCards("h"))) { + if (evt.player == player) { + return evt.targets.includes(event.player) && event.player != player; } - return evt.targets.includes(player)&&evt.player!=player; + return evt.targets.includes(player) && evt.player != player; } return false; }, - forced:true, - popup:false, - async content(event,trigger,player){ - await player.logSkill('twxiayong'+(trigger.player===player?'1':'2'),trigger.player); - if(trigger.player===player){ - const cards=player.getCards('h',card=>{ - return lib.filter.cardDiscardable(card,player,'twxiayong'); + forced: true, + popup: false, + async content(event, trigger, player) { + await player.logSkill( + "twxiayong" + (trigger.player === player ? "1" : "2"), + trigger.player + ); + if (trigger.player === player) { + const cards = player.getCards("h", (card) => { + return lib.filter.cardDiscardable(card, player, "twxiayong"); }); - if(cards.length>0) player.discard(cards.randomGet()); - } - else{ - trigger.increase('num'); + if (cards.length > 0) player.discard(cards.randomGet()); + } else { + trigger.increase("num"); } }, }, }, }, - twxiayong1:{ - audio:true, - audioname:['tw_yanliang'], - sourceSkill:'twxiayong', + twxiayong1: { + audio: true, + audioname: ["tw_yanliang"], + sourceSkill: "twxiayong", }, - twxiayong2:{ - inherit:'twxiayong1', + twxiayong2: { + inherit: "twxiayong1", }, //袁谭 - twqiaosi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return get.info('twqiaosi').getCards(player).length; + twqiaosi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return get.info("twqiaosi").getCards(player).length; }, - check(event,player){ - const cards=get.info('twqiaosi').getCards(player); - if(cards.reduce((sum,card)=>sum+get.value(card),0)) return false; - if(cards.length>=player.getHp()||cards.some(card=>get.name(card,player)=='tao'||get.name(card,player)=='jiu')) return true; - return player.getHp()>2&&cards.length>1; + check(event, player) { + const cards = get.info("twqiaosi").getCards(player); + if (cards.reduce((sum, card) => sum + get.value(card), 0)) return false; + if ( + cards.length >= player.getHp() || + cards.some( + (card) => get.name(card, player) == "tao" || get.name(card, player) == "jiu" + ) + ) + return true; + return player.getHp() > 2 && cards.length > 1; }, - prompt2(event,player){ - const cards=get.info('twqiaosi').getCards(player); - let str='获得'+get.translation(cards); - if(cards.lengthevt.position==ui.discardPile); - if(history.length){ - for(const evt of history) cards.addArray(evt.cards2.filterInD('d')); + getCards(player) { + let cards = [], + targets = game.players.slice().concat(game.dead.slice()); + for (const target of targets) { + if (target == player) continue; + const history = target.getHistory("lose", (evt) => evt.position == ui.discardPile); + if (history.length) { + for (const evt of history) cards.addArray(evt.cards2.filterInD("d")); } } - const historyx=game.getGlobalHistory('cardMove',evt=>{ - if(evt.name!='cardsDiscard') return false; - const evtx=evt.getParent(); - if(evtx.name!='orderingDiscard') return false; - const evt2=(evtx.relatedEvent||evtx.getParent()); - const current=evt2.player; - if(evt2.name=='phaseJudge'||current==player) return false; - return current.hasHistory('lose',evtx3=>{ - const evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evt2!=evtx4) return false; - return evtx3.getl(current).cards2.length>0; + const historyx = game.getGlobalHistory("cardMove", (evt) => { + if (evt.name != "cardsDiscard") return false; + const evtx = evt.getParent(); + if (evtx.name != "orderingDiscard") return false; + const evt2 = evtx.relatedEvent || evtx.getParent(); + const current = evt2.player; + if (evt2.name == "phaseJudge" || current == player) return false; + return current.hasHistory("lose", (evtx3) => { + const evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evt2 != evtx4) return false; + return evtx3.getl(current).cards2.length > 0; }); }); - if(historyx.length){ - for(const evtx of historyx) cards.addArray(evtx.cards.filterInD('d')); + if (historyx.length) { + for (const evtx of historyx) cards.addArray(evtx.cards.filterInD("d")); } return cards; }, }, - twbaizu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.isDamaged()&&player.countCards('h')&&game.hasPlayer(target=>{ - return target!=player&&target.countCards('h'); - })&&(player.getHp()+player.countMark('twbaizu_lizhan')); + twbaizu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player.isDamaged() && + player.countCards("h") && + game.hasPlayer((target) => { + return target != player && target.countCards("h"); + }) && + player.getHp() + player.countMark("twbaizu_lizhan") + ); }, - locked:true, - async cost(event,trigger,player){ - const sum=player.getHp()+player.countMark('twbaizu_lizhan'),filterTarget=(_,player,target)=>{ - return target!=player&&target.countCards('h'); - }; - let targets=game.filterPlayer(target=>filterTarget(null,player,target)); - if(targets.length>sum){ - targets=await player.chooseTarget('请选择【败族】的目标','令你和这些角色同时弃置一张手牌,然后你对与你弃置牌类别相同的其他角色各造成1点伤害',filterTarget,sum,true).set('ai',target=>{ - const player=get.event('player'); - return get.effect(target,{name:'guohe_copy2'},target,player)+get.damageEffect(target,player,player); - }).forResultTargets(); + locked: true, + async cost(event, trigger, player) { + const sum = player.getHp() + player.countMark("twbaizu_lizhan"), + filterTarget = (_, player, target) => { + return target != player && target.countCards("h"); + }; + let targets = game.filterPlayer((target) => filterTarget(null, player, target)); + if (targets.length > sum) { + targets = await player + .chooseTarget( + "请选择【败族】的目标", + "令你和这些角色同时弃置一张手牌,然后你对与你弃置牌类别相同的其他角色各造成1点伤害", + filterTarget, + sum, + true + ) + .set("ai", (target) => { + const player = get.event("player"); + return ( + get.effect(target, { name: "guohe_copy2" }, target, player) + + get.damageEffect(target, player, player) + ); + }) + .forResultTargets(); } - event.result={bool:true,targets}; + event.result = { bool: true, targets }; }, - async content(event,trigger,player){ - const targets=event.targets.slice().sortBySeat(); + async content(event, trigger, player) { + const targets = event.targets.slice().sortBySeat(); player.line(targets); - let list=[player].concat(targets).filter(target=>target.countDiscardableCards(target,'h')); - if(list.length){ - let discards=[]; - const {result}=await player.chooseCardOL(list,'败族:请弃置一张手牌',(card,player)=>{ - return lib.filter.cardDiscardable(card,player); - },true).set('ai',get.unuseful); - if(result){ - for(let i=0;i target.countDiscardableCards(target, "h")); + if (list.length) { + let discards = []; + const { result } = await player + .chooseCardOL( + list, + "败族:请弃置一张手牌", + (card, player) => { + return lib.filter.cardDiscardable(card, player); + }, + true + ) + .set("ai", get.unuseful); + if (result) { + for (let i = 0; i < result.length; i++) { + discards.push([list[i], result[i].cards]); } - await game.loseAsync({lose_list:discards}).setContent('discardMultiple'); - list=list.filter(i=>get.type2(result[0].cards[0])==get.type2(result[list.indexOf(i)].cards[0])); - if(list.length){ - for(const i of list){ - if(i===player) continue; + await game.loseAsync({ lose_list: discards }).setContent("discardMultiple"); + list = list.filter( + (i) => + get.type2(result[0].cards[0]) == + get.type2(result[list.indexOf(i)].cards[0]) + ); + if (list.length) { + for (const i of list) { + if (i === player) continue; player.line(i); await i.damage(); } } } } - player.when({global:'phaseEnd'}).then(()=>{ - player.popup('历战'); - player.addMark('twbaizu_lizhan',1,false); - game.log(player,'触发了','#g【败族】','的','#y历战','效果'); + player.when({ global: "phaseEnd" }).then(() => { + player.popup("历战"); + player.addMark("twbaizu_lizhan", 1, false); + game.log(player, "触发了", "#g【败族】", "的", "#y历战", "效果"); }); }, - subSkill:{ - lizhan:{ - charlotte:true, - onremove:true, - marktext:'战', - intro:{content:'【败族】目标选择数+#'}, + subSkill: { + lizhan: { + charlotte: true, + onremove: true, + marktext: "战", + intro: { content: "【败族】目标选择数+#" }, }, }, }, //玉真子 - twhuajing:{ - audio:2, - getSkills(player){ - return player.getCards('e',card=>get.subtype(card)=='equip1').reduce((list,card)=>{ - const info=get.info(card); - if(info&&info.skills) return list.addArray(info.skills); - return list; - },[]); + twhuajing: { + audio: 2, + getSkills(player) { + return player + .getCards("e", (card) => get.subtype(card) == "equip1") + .reduce((list, card) => { + const info = get.info(card); + if (info && info.skills) return list.addArray(info.skills); + return list; + }, []); }, - trigger:{global:'phaseBefore',player:'enterGame'}, - filter(event,player){ - return event.name!='phase'||game.phaseNumber==0; + trigger: { global: "phaseBefore", player: "enterGame" }, + filter(event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - async content(event,trigger,player){ - const skills=lib.skill.twhuajing.derivation; - for(const eff of skills){ - player.addMark(eff,1); + forced: true, + locked: false, + async content(event, trigger, player) { + const skills = lib.skill.twhuajing.derivation; + for (const eff of skills) { + player.addMark(eff, 1); player.unmarkSkill(eff); } - player.markSkill('twhuajing'); + player.markSkill("twhuajing"); }, - global:'twhuajing_global', - group:'twhuajing_use', - derivation:['twhuajing_jian','twhuajing_dao','twhuajing_fu','twhuajing_qiang','twhuajing_ji','twhuajing_gong'], - marktext:'武', - intro:{ - markcount(storage,player){ - return lib.skill.twhuajing.derivation.filter(skill=>player.hasMark(skill)).length; + global: "twhuajing_global", + group: "twhuajing_use", + derivation: [ + "twhuajing_jian", + "twhuajing_dao", + "twhuajing_fu", + "twhuajing_qiang", + "twhuajing_ji", + "twhuajing_gong", + ], + marktext: "武", + intro: { + markcount(storage, player) { + return lib.skill.twhuajing.derivation.filter((skill) => player.hasMark(skill)).length; }, - content(storage,player){ - const skills=lib.skill.twhuajing.derivation.filter(skill=>player.hasMark(skill)); - if(!skills.length) return '功力已消耗殆尽'; - let str='当前武功:'; - for(const eff of skills){ - str+='
            • '; - str+=lib.translate[eff]; - str+=':'; - str+=lib.translate[eff+'_info']; + content(storage, player) { + const skills = lib.skill.twhuajing.derivation.filter((skill) => + player.hasMark(skill) + ); + if (!skills.length) return "功力已消耗殆尽"; + let str = "当前武功:"; + for (const eff of skills) { + str += "
            • "; + str += lib.translate[eff]; + str += ":"; + str += lib.translate[eff + "_info"]; } return str; }, }, - subSkill:{ - global:{ - mod:{ - attackRange(player,num){ - const skills=lib.skill.twhuajing.derivation.filter(skill=>player.hasMark(skill)||player.hasSkill(skill)); - if(skills.length) return num+skills.length*game.countPlayer(target=>target.hasSkill('twhuajing')); + subSkill: { + global: { + mod: { + attackRange(player, num) { + const skills = lib.skill.twhuajing.derivation.filter( + (skill) => player.hasMark(skill) || player.hasSkill(skill) + ); + if (skills.length) + return ( + num + + skills.length * + game.countPlayer((target) => target.hasSkill("twhuajing")) + ); }, }, }, - use:{ - audio:'twhuajing', - enable:'phaseUse', - filter(event,player){ - return lib.skill.twhuajing.derivation.some(skill=>player.hasMark(skill)); + use: { + audio: "twhuajing", + enable: "phaseUse", + filter(event, player) { + return lib.skill.twhuajing.derivation.some((skill) => player.hasMark(skill)); }, - filterCard:true, - selectCard:[1,4], - position:'h', - complexCard:true, - discard:false, - lose:false, - delay:false, - check(card){ - const player=get.event('player'),skills=lib.skill.twhuajing.derivation.filter(skill=>player.hasMark(skill)); - if(ui.selected.cards.some(cardx=>get.suit(cardx,player)==get.suit(card,player))) return 0; - return skills.length-ui.selected.cards.length; + filterCard: true, + selectCard: [1, 4], + position: "h", + complexCard: true, + discard: false, + lose: false, + delay: false, + check(card) { + const player = get.event("player"), + skills = lib.skill.twhuajing.derivation.filter((skill) => + player.hasMark(skill) + ); + if ( + ui.selected.cards.some( + (cardx) => get.suit(cardx, player) == get.suit(card, player) + ) + ) + return 0; + return skills.length - ui.selected.cards.length; }, - usable:1, - prompt:'展示至多四张手牌,然后根据这些牌含有的花色数于本回合获得等量你拥有的“武”标记的效果', - async content(event,trigger,player){ - await player.showCards(event.cards,get.translation(player)+'发动了【化境】'); - const skills=lib.skill.twhuajing.derivation.filter(skill=>player.hasMark(skill)); - const gainSkills=skills.randomGets(Math.min(skills.length,event.cards.reduce((list,cardx)=>list.add(get.suit(cardx,player)),[]).length)); - for(const eff of gainSkills) player.popup(eff); + usable: 1, + prompt: "展示至多四张手牌,然后根据这些牌含有的花色数于本回合获得等量你拥有的“武”标记的效果", + async content(event, trigger, player) { + await player.showCards(event.cards, get.translation(player) + "发动了【化境】"); + const skills = lib.skill.twhuajing.derivation.filter((skill) => + player.hasMark(skill) + ); + const gainSkills = skills.randomGets( + Math.min( + skills.length, + event.cards.reduce((list, cardx) => list.add(get.suit(cardx, player)), []) + .length + ) + ); + for (const eff of gainSkills) player.popup(eff); player.addTempSkill(gainSkills); - player.addTempSkill('twhuajing_blocker'); - player.getHistory('custom').push({twhuajing_skills:gainSkills}); + player.addTempSkill("twhuajing_blocker"); + player.getHistory("custom").push({ twhuajing_skills: gainSkills }); }, - ai:{ - order:12, - result:{ - player(player){ - return player.countCards('hs',card=>{ - return get.name(card)=='sha'&&player.hasValueTarget(card,false,true); + ai: { + order: 12, + result: { + player(player) { + return player.countCards("hs", (card) => { + return ( + get.name(card) == "sha" && + player.hasValueTarget(card, false, true) + ); }); }, }, }, }, - jian:{ - charlotte:true, - mark:true, - marktext:'剑', - intro:{ - name:'化境·剑', - name2:'剑', - markcount:()=>0, - content:()=>lib.translate.twhuajing_jian_info, + jian: { + charlotte: true, + mark: true, + marktext: "剑", + intro: { + name: "化境·剑", + name2: "剑", + markcount: () => 0, + content: () => lib.translate.twhuajing_jian_info, }, - nopop:true, - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return event.card.name=='sha'&&event.target.countCards('he'); + nopop: true, + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return event.card.name == "sha" && event.target.countCards("he"); }, - forced:true, - logTarget:'target', - async content(event,trigger,player){ - const target=trigger.target; - const cards=target.getDiscardableCards(player,'he'); - target.discard(cards.randomGets(Math.min(2,cards.length))).discarder=player; + forced: true, + logTarget: "target", + async content(event, trigger, player) { + const target = trigger.target; + const cards = target.getDiscardableCards(player, "he"); + target.discard(cards.randomGets(Math.min(2, cards.length))).discarder = player; }, }, - dao:{ - charlotte:true, - mark:true, - marktext:'刀', - intro:{ - name:'化境·刀', - name2:'刀', - markcount:()=>0, - content:()=>lib.translate.twhuajing_dao_info, + dao: { + charlotte: true, + mark: true, + marktext: "刀", + intro: { + name: "化境·刀", + name2: "刀", + markcount: () => 0, + content: () => lib.translate.twhuajing_dao_info, }, - nopop:true, - inherit:'guding_skill', - equipSkill:false, + nopop: true, + inherit: "guding_skill", + equipSkill: false, }, - fu:{ - charlotte:true, - mark:true, - marktext:'斧', - intro:{ - name:'化境·斧', - name2:'斧', - markcount:()=>0, - content:()=>lib.translate.twhuajing_fu_info, + fu: { + charlotte: true, + mark: true, + marktext: "斧", + intro: { + name: "化境·斧", + name2: "斧", + markcount: () => 0, + content: () => lib.translate.twhuajing_fu_info, }, - nopop:true, - trigger:{player:'shaMiss'}, - forced:true, - logTarget:'target', - async content(event,trigger,player){ + nopop: true, + trigger: { player: "shaMiss" }, + forced: true, + logTarget: "target", + async content(event, trigger, player) { trigger.target.damage(); }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(!arg||!arg.card||arg.card.name!='sha'||!arg.baseDamage||arg.baseDamage<=1) return false; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if ( + !arg || + !arg.card || + arg.card.name != "sha" || + !arg.baseDamage || + arg.baseDamage <= 1 + ) + return false; return true; }, }, }, - qiang:{ - charlotte:true, - mark:true, - marktext:'枪', - intro:{ - name:'化境·枪', - name2:'枪', - markcount:()=>0, - content:()=>lib.translate.twhuajing_qiang_info, + qiang: { + charlotte: true, + mark: true, + marktext: "枪", + intro: { + name: "化境·枪", + name2: "枪", + markcount: () => 0, + content: () => lib.translate.twhuajing_qiang_info, }, - nopop:true, - trigger:{player:'useCardAfter'}, - filter(event,player){ - return event.card.name=='sha'&&get.color(event.card)=='black'; + nopop: true, + trigger: { player: "useCardAfter" }, + filter(event, player) { + return event.card.name == "sha" && get.color(event.card) == "black"; }, - forced:true, - async content(event,trigger,player){ - const card=get.cardPile(card=>card.name=='shan'); - if(card) player.gain(card,'gain2'); + forced: true, + async content(event, trigger, player) { + const card = get.cardPile((card) => card.name == "shan"); + if (card) player.gain(card, "gain2"); }, }, - ji:{ - charlotte:true, - mark:true, - marktext:'戟', - intro:{ - name:'化境·戟', - name2:'戟', - markcount:()=>0, - content:()=>lib.translate.twhuajing_ji_info, + ji: { + charlotte: true, + mark: true, + marktext: "戟", + intro: { + name: "化境·戟", + name2: "戟", + markcount: () => 0, + content: () => lib.translate.twhuajing_ji_info, }, - nopop:true, - trigger:{source:'damageBegin3'}, - filter(event,player){ - return event.card&&event.card.name=='sha'; + nopop: true, + trigger: { source: "damageBegin3" }, + filter(event, player) { + return event.card && event.card.name == "sha"; }, - forced:true, - async content(event,trigger,player){ + forced: true, + async content(event, trigger, player) { player.draw(trigger.num); }, }, - gong:{ - charlotte:true, - mark:true, - marktext:'弓', - intro:{ - name:'化境·弓', - name2:'弓', - markcount:()=>0, - content:()=>lib.translate.twhuajing_gong_info, + gong: { + charlotte: true, + mark: true, + marktext: "弓", + intro: { + name: "化境·弓", + name2: "弓", + markcount: () => 0, + content: () => lib.translate.twhuajing_gong_info, }, - nopop:true, - trigger:{source:'damageSource'}, - filter(event,player){ - return event.card&&event.card.name=='sha'&&event.player.countDiscardableCards(player,'e'); + nopop: true, + trigger: { source: "damageSource" }, + filter(event, player) { + return ( + event.card && + event.card.name == "sha" && + event.player.countDiscardableCards(player, "e") + ); }, - forced:true, - logTarget:'player', - async content(event,trigger,player){ - trigger.player.discard(trigger.player.getDiscardableCards(player,'e').randomGets(1)).discarder=player; + forced: true, + logTarget: "player", + async content(event, trigger, player) { + trigger.player.discard( + trigger.player.getDiscardableCards(player, "e").randomGets(1) + ).discarder = player; }, }, - blocker:{ - charlotte:true, - init(player,skill){ - player.disableSkill(skill,lib.skill.twhuajing.getSkills(player)); + blocker: { + charlotte: true, + init(player, skill) { + player.disableSkill(skill, lib.skill.twhuajing.getSkills(player)); }, - onremove(player,skill){ + onremove(player, skill) { player.enableSkill(skill); }, - mod:{ - attackRange(player,num){ - return num-player.getEquipRange(); + mod: { + attackRange(player, num) { + return num - player.getEquipRange(); }, }, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter','phaseBefore'], + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + "phaseBefore", + ], }, - filter(event,player){ - if(event.name=='phase') return true; - if(event.name=='equip'&&event.player==player&&get.subtype(event.card)=='equip1') return true; - const evt=event.getl(player); - return evt&&evt.player==player&&evt.es&&evt.es.some(card=>get.subtype(card)=='equip1'); + filter(event, player) { + if (event.name == "phase") return true; + if ( + event.name == "equip" && + event.player == player && + get.subtype(event.card) == "equip1" + ) + return true; + const evt = event.getl(player); + return ( + evt && + evt.player == player && + evt.es && + evt.es.some((card) => get.subtype(card) == "equip1") + ); }, - forced:true, - popup:false, - firstDo:true, - async content(event,trigger,player){ - player.enableSkill('twhuajing_blocker'); - player.disableSkill('twhuajing_blocker',lib.skill.twhuajing.getSkills(player)); + forced: true, + popup: false, + firstDo: true, + async content(event, trigger, player) { + player.enableSkill("twhuajing_blocker"); + player.disableSkill("twhuajing_blocker", lib.skill.twhuajing.getSkills(player)); }, - ai:{unequip_equip1:true}, + ai: { unequip_equip1: true }, }, }, }, - twtianshou:{ - audio:2, - trigger:{player:'phaseEnd'}, - filter(event,player){ - return player.getHistory('sourceDamage',evt=>{ - return evt.card&&evt.card.name=='sha'; - }).length&&player.getHistory('custom',evt=>{ - return evt.twhuajing_skills; - }).reduce((list,evt)=>list.addArray(evt.twhuajing_skills),[]).some(skill=>player.hasMark(skill)); + twtianshou: { + audio: 2, + trigger: { player: "phaseEnd" }, + filter(event, player) { + return ( + player.getHistory("sourceDamage", (evt) => { + return evt.card && evt.card.name == "sha"; + }).length && + player + .getHistory("custom", (evt) => { + return evt.twhuajing_skills; + }) + .reduce((list, evt) => list.addArray(evt.twhuajing_skills), []) + .some((skill) => player.hasMark(skill)) + ); }, - forced:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(lib.filter.notMe,true) - .set('prompt','天授:令一名其他角色获得1枚“武”并获得此标记的效果') - .set('ai',target=>{ - const player=get.event('player'),att=get.attitude(player,target); - const card=new lib.element.VCard({name:'sha'}); - if(att>0) return game.countPlayer(aim=>{ - return target.canUse(card,target)&&get.effect(aim,card,target,player)>0&&get.effect(aim,card,target,target)>0; - })+10; - if(att==0) return 1.5+Math.random(); - return 0.1+Math.random(); - }); - if(bool){ - const target=targets[0]; - const skills=player.getHistory('custom',evt=>{ - return evt.twhuajing_skills; - }).reduce((list,evt)=>list.addArray(evt.twhuajing_skills),[]).filter(skill=>player.hasMark(skill)); - let choiceList=skills.map(i=>{ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              ' + - '
              '+get.skillInfoTranslation(i,player)+'
              '; + forced: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget(lib.filter.notMe, true) + .set("prompt", "天授:令一名其他角色获得1枚“武”并获得此标记的效果") + .set("ai", (target) => { + const player = get.event("player"), + att = get.attitude(player, target); + const card = new lib.element.VCard({ name: "sha" }); + if (att > 0) + return ( + game.countPlayer((aim) => { + return ( + target.canUse(card, target) && + get.effect(aim, card, target, player) > 0 && + get.effect(aim, card, target, target) > 0 + ); + }) + 10 + ); + if (att == 0) return 1.5 + Math.random(); + return 0.1 + Math.random(); }); - const {result:{control}}=await player.chooseControl(skills) - .set('prompt','选择令'+get.translation(target)+'获得的“武”') - .set('choiceList',choiceList).set('displayIndex',false).set('ai',()=>get.event('controls').randomGet()); - if(control){ - player.removeMark(control,1); - player.markSkill('twhuajing'); - player.popup(control,'metal'); - target.addTempSkill(control,{player:'phaseAfter'}); - target.addTempSkill('twhuajing_blocker',{player:'phaseAfter'}); - target.getHistory('custom').push({twhuajing_skills:[control]}); + if (bool) { + const target = targets[0]; + const skills = player + .getHistory("custom", (evt) => { + return evt.twhuajing_skills; + }) + .reduce((list, evt) => list.addArray(evt.twhuajing_skills), []) + .filter((skill) => player.hasMark(skill)); + let choiceList = skills.map((i) => { + return ( + '
              【' + + get.translation(lib.translate[i + "_ab"] || get.translation(i).slice(0, 2)) + + "】
              " + + "
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }); + const { + result: { control }, + } = await player + .chooseControl(skills) + .set("prompt", "选择令" + get.translation(target) + "获得的“武”") + .set("choiceList", choiceList) + .set("displayIndex", false) + .set("ai", () => get.event("controls").randomGet()); + if (control) { + player.removeMark(control, 1); + player.markSkill("twhuajing"); + player.popup(control, "metal"); + target.addTempSkill(control, { player: "phaseAfter" }); + target.addTempSkill("twhuajing_blocker", { player: "phaseAfter" }); + target.getHistory("custom").push({ twhuajing_skills: [control] }); await player.draw(2); } } }, - ai:{combo:'twhuajing'}, + ai: { combo: "twhuajing" }, }, //史阿 - twdengjian:{ - audio:2, - trigger:{global:'phaseDiscardEnd'}, - filter(event,player){ - if(player.hasSkill('twdengjian_ban')) return false; - return event.player!=player&&lib.skill.twdengjian.getCards(player,event.player).length; + twdengjian: { + audio: 2, + trigger: { global: "phaseDiscardEnd" }, + filter(event, player) { + if (player.hasSkill("twdengjian_ban")) return false; + return ( + event.player != player && lib.skill.twdengjian.getCards(player, event.player).length + ); }, - getCards(player,target){ - let cards=target.getHistory('useCard',evt=>{ - return evt.cards&&evt.cards.filterInD('d').some(card=>get.name(card,false)=='sha')&&target.getHistory('sourceDamage',evtx=>{ - return evtx.card&&evtx.card==evt.card; - }).length; - }).reduce((list,evt)=>list.addArray(evt.cards.filterInD('d').filter(card=>get.name(card,false)=='sha')),[]); - if(cards.length){ - const history=player.actionHistory; - for(let i=history.length-1;i>=0;i--){ - for(let evt of history[i].gain){ - if(evt.getParent().name=='twdengjian'){ - const card=evt.cards[0]; - cards=cards.filter(cardx=>get.color(cardx)!=get.color(card)); - if(!cards.length) break; + getCards(player, target) { + let cards = target + .getHistory("useCard", (evt) => { + return ( + evt.cards && + evt.cards.filterInD("d").some((card) => get.name(card, false) == "sha") && + target.getHistory("sourceDamage", (evtx) => { + return evtx.card && evtx.card == evt.card; + }).length + ); + }) + .reduce( + (list, evt) => + list.addArray( + evt.cards.filterInD("d").filter((card) => get.name(card, false) == "sha") + ), + [] + ); + if (cards.length) { + const history = player.actionHistory; + for (let i = history.length - 1; i >= 0; i--) { + for (let evt of history[i].gain) { + if (evt.getParent().name == "twdengjian") { + const card = evt.cards[0]; + cards = cards.filter((cardx) => get.color(cardx) != get.color(card)); + if (!cards.length) break; } } - if(history[i].isRound) break; + if (history[i].isRound) break; } } return cards; }, //direct:true, - frequent:true, - async content(event,trigger,player){ - const cards=lib.skill.twdengjian.getCards(player,trigger.player); + frequent: true, + async content(event, trigger, player) { + const cards = lib.skill.twdengjian.getCards(player, trigger.player); /*const {result:{bool}}=await player.chooseToDiscard(get.prompt('twdengjian'),'he') .set('prompt2','弃置一张牌并随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】') .set('ai',card=>7-get.value(card)) .set('logSkill','twdengjian'); - if(bool) */await player.gain(cards.randomGet(),'gain2').gaintag.add('twdengjianx'); + if(bool) */ await player.gain(cards.randomGet(), "gain2").gaintag.add("twdengjianx"); }, - group:'twdengjian_buff', - subSkill:{ - ban:{charlotte:true}, - buff:{ - mod:{ - aiOrder(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('twdengjianx')) return num+0.1; + group: "twdengjian_buff", + subSkill: { + ban: { charlotte: true }, + buff: { + mod: { + aiOrder(player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("twdengjianx")) + return num + 0.1; }, }, - audio:'twdengjian', - trigger:{player:'useCard1'}, - filter(event,player){ - return event.cards&&event.cards.length==1&&player.getHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twdengjianx')) return true; - } - return false; - }).length&&event.addCount!==false; + audio: "twdengjian", + trigger: { player: "useCard1" }, + filter(event, player) { + return ( + event.cards && + event.cards.length == 1 && + player.getHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twdengjianx")) return true; + } + return false; + }).length && + event.addCount !== false + ); }, - forced:true, - locked:false, - async content(event,trigger,player){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0) player.stat[player.stat.length-1].card.sha--; - game.log(trigger.card,'不计入次数限制'); + forced: true, + locked: false, + async content(event, trigger, player) { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) + player.stat[player.stat.length - 1].card.sha--; + game.log(trigger.card, "不计入次数限制"); }, }, }, }, - twdengjianx:{}, - twxinshou:{ - audio:2, - trigger:{player:'useCard'}, - filter(event,player){ - if(event.card.name!='sha') return false; - const goon=(!player.getHistory('useCard',evt=>{ - return evt!=event&&evt.card.name=='sha'&&get.color(evt.card)==get.color(event.card); - }).length&&player.isPhaseUsing()); - if(!player.hasSkill('twxinshou_0')) return goon; - if(!player.hasSkill('twxinshou_1')) return goon&&game.hasPlayer(target=>target!=player); - return !player.hasSkill('twdengjian_ban')&&game.hasPlayer(target=>{ - if(target==player) return false; - return !target.hasSkill('twdengjian',null,null,false); - })&&player.hasSkill('twdengjian',null,null,false); + twdengjianx: {}, + twxinshou: { + audio: 2, + trigger: { player: "useCard" }, + filter(event, player) { + if (event.card.name != "sha") return false; + const goon = + !player.getHistory("useCard", (evt) => { + return ( + evt != event && + evt.card.name == "sha" && + get.color(evt.card) == get.color(event.card) + ); + }).length && player.isPhaseUsing(); + if (!player.hasSkill("twxinshou_0")) return goon; + if (!player.hasSkill("twxinshou_1")) + return goon && game.hasPlayer((target) => target != player); + return ( + !player.hasSkill("twdengjian_ban") && + game.hasPlayer((target) => { + if (target == player) return false; + return !target.hasSkill("twdengjian", null, null, false); + }) && + player.hasSkill("twdengjian", null, null, false) + ); }, - direct:true, - async content(event,trigger,player){ - if(player.hasSkill('twxinshou_0')&&player.hasSkill('twxinshou_1')){ - const {result:{bool,targets}}=await player.chooseTarget((card,player,target)=>{ - return target!=player&&!target.hasSkill('twdengjian',null,null,false); - }).set('ai',target=>{ - const player=get.event('player'); - if(get.attitude(player,target)>0){ - if(target.isTurnedOver()) return 0; - const card=new lib.element.VCard({name:'sha'}); - if(game.hasPlayer(aim=>{ - return target.canUse(card,target)&&get.effect(aim,card,target,player)>0&&get.effect(aim,card,target,target)>0; - })) return target.countCards('h')-3; - return 0; - } - return 0; - }) - .set('prompt',get.prompt('twxinshou')) - .set('prompt2','令【登剑】失效并令一名其他角色获得【登剑】,你的下个回合开始时,其失去【登剑】,若其这期间使用【杀】造成过伤害,则你结束【登剑】的失效状态'); - if(bool){ - const target=targets[0]; - player.logSkill('twxinshou',target); - player.addSkill('twdengjian_ban'); - target.addAdditionalSkills('twxinshou_'+player.playerid,'twdengjian'); - player.popup('登剑'); - target.popup('登剑'); - game.log(player,'将','#g【登剑】','传授给了',target); - game.log(player,'的','#g【登剑】','被失效了'); - player.when('phaseBegin').then(()=>{ - target.removeAdditionalSkills('twxinshou_'+player.playerid); - }).then(()=>{ - const history=game.getAllGlobalHistory('everything'); - for(let i=history.length-1;i>=0;i--){ - const evt=history[i]; - if(evt.name=='damage'&&evt.card&&evt.source&&evt.card.name=='sha'&&evt.source==target){ - player.popup('洗具'); - player.removeSkill('twdengjian_ban'); - game.log(player,'结束了','#g【登剑】','的失效状态'); - return; - } - if(evt==evtx) break; + direct: true, + async content(event, trigger, player) { + if (player.hasSkill("twxinshou_0") && player.hasSkill("twxinshou_1")) { + const { + result: { bool, targets }, + } = await player + .chooseTarget((card, player, target) => { + return target != player && !target.hasSkill("twdengjian", null, null, false); + }) + .set("ai", (target) => { + const player = get.event("player"); + if (get.attitude(player, target) > 0) { + if (target.isTurnedOver()) return 0; + const card = new lib.element.VCard({ name: "sha" }); + if ( + game.hasPlayer((aim) => { + return ( + target.canUse(card, target) && + get.effect(aim, card, target, player) > 0 && + get.effect(aim, card, target, target) > 0 + ); + }) + ) + return target.countCards("h") - 3; + return 0; } - player.popup('杯具'); - player.chat('剑法废掉了...'); - }).vars({target:target,evtx:event}); + return 0; + }) + .set("prompt", get.prompt("twxinshou")) + .set( + "prompt2", + "令【登剑】失效并令一名其他角色获得【登剑】,你的下个回合开始时,其失去【登剑】,若其这期间使用【杀】造成过伤害,则你结束【登剑】的失效状态" + ); + if (bool) { + const target = targets[0]; + player.logSkill("twxinshou", target); + player.addSkill("twdengjian_ban"); + target.addAdditionalSkills("twxinshou_" + player.playerid, "twdengjian"); + player.popup("登剑"); + target.popup("登剑"); + game.log(player, "将", "#g【登剑】", "传授给了", target); + game.log(player, "的", "#g【登剑】", "被失效了"); + player + .when("phaseBegin") + .then(() => { + target.removeAdditionalSkills("twxinshou_" + player.playerid); + }) + .then(() => { + const history = game.getAllGlobalHistory("everything"); + for (let i = history.length - 1; i >= 0; i--) { + const evt = history[i]; + if ( + evt.name == "damage" && + evt.card && + evt.source && + evt.card.name == "sha" && + evt.source == target + ) { + player.popup("洗具"); + player.removeSkill("twdengjian_ban"); + game.log(player, "结束了", "#g【登剑】", "的失效状态"); + return; + } + if (evt == evtx) break; + } + player.popup("杯具"); + player.chat("剑法废掉了..."); + }) + .vars({ target: target, evtx: event }); } - } - else{ - let choice=[],choiceList=['摸一张牌','交给一名其他角色一张牌']; - if(!player.hasSkill('twxinshou_0')) choice.push('摸牌'); - else choiceList[0]=''+choiceList[0]+''; - if(!player.hasSkill('twxinshou_1')&&game.hasPlayer(target=>target!=player)) choice.push('给牌'); - else choiceList[1]=''+choiceList[1]+''; - const {result:{control}}=await player.chooseControl(choice,'cancel2') - .set('prompt',get.prompt('twxinshou')).set('choiceList',choiceList) - .set('ai',()=>{ - if(get.event('controls').includes('摸牌')) return '摸牌'; - const player=get.event('player'); - return (game.hasPlayer(target=>{ - if(target==player) return false; - if(player.countCards('he',card=>card.name=='du')&&get.attitude(player,target)<=0) return true; - if(player.countCards('he',card=>get.value(card,player)<0&&get.attitude(player,target)*get.value(card,target)>0)) return true; - return get.attitude(player,target)>0; - })&&get.event('controls').includes('给牌'))?'给牌':'cancel2'; - }); - if(control=='cancel2') return; - player.logSkill('twxinshou'); - if(control=='摸牌'){ - player.addTempSkill('twxinshou_0'); + } else { + let choice = [], + choiceList = ["摸一张牌", "交给一名其他角色一张牌"]; + if (!player.hasSkill("twxinshou_0")) choice.push("摸牌"); + else choiceList[0] = '' + choiceList[0] + ""; + if (!player.hasSkill("twxinshou_1") && game.hasPlayer((target) => target != player)) + choice.push("给牌"); + else choiceList[1] = '' + choiceList[1] + ""; + const { + result: { control }, + } = await player + .chooseControl(choice, "cancel2") + .set("prompt", get.prompt("twxinshou")) + .set("choiceList", choiceList) + .set("ai", () => { + if (get.event("controls").includes("摸牌")) return "摸牌"; + const player = get.event("player"); + return game.hasPlayer((target) => { + if (target == player) return false; + if ( + player.countCards("he", (card) => card.name == "du") && + get.attitude(player, target) <= 0 + ) + return true; + if ( + player.countCards( + "he", + (card) => + get.value(card, player) < 0 && + get.attitude(player, target) * get.value(card, target) > 0 + ) + ) + return true; + return get.attitude(player, target) > 0; + }) && get.event("controls").includes("给牌") + ? "给牌" + : "cancel2"; + }); + if (control == "cancel2") return; + player.logSkill("twxinshou"); + if (control == "摸牌") { + player.addTempSkill("twxinshou_0"); await player.draw(); } - if(control=='给牌'){ - player.addTempSkill('twxinshou_1'); - const {result:{bool,targets}}=await player.chooseTarget('交给一名其他角色一张牌',lib.filter.notMe,true).set('ai',target=>{ - const player=get.event('player'),att=get.attitude(player,target); - if(player.countCards('he',card=>card.name=='du')) return -att; - let cards=player.getCards('he',card=>get.value(card,player)<0); - if(cards.length){ - cards.sort((a,b)=>get.value(a,player)-get.value(b,player)); - return get.value(cards[0],target)*att; - } - return att; - }); - if(bool){ - const target=targets[0]; + if (control == "给牌") { + player.addTempSkill("twxinshou_1"); + const { + result: { bool, targets }, + } = await player + .chooseTarget("交给一名其他角色一张牌", lib.filter.notMe, true) + .set("ai", (target) => { + const player = get.event("player"), + att = get.attitude(player, target); + if (player.countCards("he", (card) => card.name == "du")) return -att; + let cards = player.getCards("he", (card) => get.value(card, player) < 0); + if (cards.length) { + cards.sort((a, b) => get.value(a, player) - get.value(b, player)); + return get.value(cards[0], target) * att; + } + return att; + }); + if (bool) { + const target = targets[0]; player.line(target); - await player.chooseToGive(target,'he',true); + await player.chooseToGive(target, "he", true); } } } }, - subSkill:{ - '0':{charlotte:true}, - '1':{charlotte:true}, + subSkill: { + 0: { charlotte: true }, + 1: { charlotte: true }, }, }, //石韬 - twjieqiu:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>lib.skill.twjieqiu.filterTarget(null,player,target)); + twjieqiu: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => lib.skill.twjieqiu.filterTarget(null, player, target)); }, - filterTarget(card,player,target){ - return target!=player&&!target.hasDisabledSlot(); + filterTarget(card, player, target) { + return target != player && !target.hasDisabledSlot(); }, - usable:1, - async content(event,trigger,player){ - const target=event.target,num=target.countCards('e'); - let disables=[]; - for(let i=1;i<=5;i++){ - for(let j=0;j!p.hasDisabledSlot()) - .then(()=>player.removeSkill('twjieqiu_buff')); + if (num) await target.draw(num); + target.addSkill("twjieqiu_buff"); + target.markAuto("twjieqiu_buff", [player]); + target + .when("enableEquipEnd") + .filter((e, p) => !p.hasDisabledSlot()) + .then(() => player.removeSkill("twjieqiu_buff")); }, - ai:{ - order:7, - result:{ - target(player,target){ - return -target.countCards('e')-(get.attitude(player,target)<0?1:0); + ai: { + order: 7, + result: { + target(player, target) { + return -target.countCards("e") - (get.attitude(player, target) < 0 ? 1 : 0); }, }, }, - subSkill:{ - used:{charlotte:true}, - buff:{ - charlotte:true, - onremove:true, - trigger:{player:'phaseDiscardEnd'}, - filter(event,player){ - return player.hasDisabledSlot()&&event.cards&&event.cards.length; + subSkill: { + used: { charlotte: true }, + buff: { + charlotte: true, + onremove: true, + trigger: { player: "phaseDiscardEnd" }, + filter(event, player) { + return player.hasDisabledSlot() && event.cards && event.cards.length; }, - forced:true, - popup:false, - async content(event,trigger,player){ - const num=trigger.cards.length; - let list=[],map={}; - for(let i=1;i<6;i++){ - map[get.translation('equip'+i)]=('equip'+i); - if(player.hasDisabledSlot(i)){ - for(let j=0;jget.translation(i)); - const {result:{bool,links}}=await player.chooseButton([ - '劫囚:请选择你要恢复的装备栏', - [transList,'tdnodes'], - ],Math.min(transList.length,num),true).set('map',map) - .set('ai',button=>['equip5','equip4','equip1','equip3','equip2'].indexOf(get.event('map')[button.link])+2); - if(bool) await player.enableEquip(links.slice().map(i=>map[i])); + let result; + const transList = list.map((i) => get.translation(i)); + if (transList.length <= num) result = { bool: true, links: transList }; + else + result = await player + .chooseButton( + ["劫囚:请选择你要恢复的装备栏", [transList, "tdnodes"]], + Math.min(transList.length, num), + true + ) + .set("map", map) + .set( + "ai", + (button) => + ["equip5", "equip4", "equip1", "equip3", "equip2"].indexOf( + get.event("map")[button.link] + ) + 2 + ) + .forResult(); + if (result.bool) + await player.enableEquip(result.links.slice().map((i) => map[i])); }, - group:['twjieqiu_end'], + group: ["twjieqiu_end"], }, - end:{ - charlotte:true, - trigger:{player:'phaseEnd'}, - filter(event,player){ - return player.hasDisabledSlot()&&player.getStorage('twjieqiu_buff').some(target=>{ - return target.isIn()&&!target.hasSkill('twjieqiu_used'); - }); + end: { + charlotte: true, + trigger: { player: "phaseEnd" }, + filter(event, player) { + return ( + player.hasDisabledSlot() && + player.getStorage("twjieqiu_buff").some((target) => { + return target.isIn() && !target.hasSkill("twjieqiu_used"); + }) + ); }, - forced:true, - popup:false, - async content(event,trigger,player){ - const targets=player.getStorage('twjieqiu_buff').filter(target=>{ - return target.isIn()&&!target.hasSkill('twjieqiu_used'); - }).sortBySeat(); - for(const target of targets){ - target.popup('劫囚'); - target.addTempSkill('twjieqiu_used','roundStart'); + forced: true, + popup: false, + async content(event, trigger, player) { + const targets = player + .getStorage("twjieqiu_buff") + .filter((target) => { + return target.isIn() && !target.hasSkill("twjieqiu_used"); + }) + .sortBySeat(); + for (const target of targets) { + target.popup("劫囚"); + target.addTempSkill("twjieqiu_used", "roundStart"); target.insertPhase(); } }, }, }, }, - twenchou:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(current=>lib.skill.twenchou.filterTarget(null,player,current)); + twenchou: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((current) => + lib.skill.twenchou.filterTarget(null, player, current) + ); }, - position:'he', - filterTarget(card,player,target){ - return target!=player&&target.countCards('h')&&target.hasDisabledSlot(); + position: "he", + filterTarget(card, player, target) { + return target != player && target.countCards("h") && target.hasDisabledSlot(); }, - usable:1, - async content(event,trigger,player){ - const target=event.target; - await player.gainPlayerCard(target,'h',true,'visible'); - let list=[],map={}; - for(let i=1;i<6;i++){ - map[get.translation('equip'+i)]=('equip'+i); - if(target.hasDisabledSlot(i)){ - list.push('equip'+i); + usable: 1, + async content(event, trigger, player) { + const target = event.target; + await player.gainPlayerCard(target, "h", true, "visible"); + let list = [], + map = {}; + for (let i = 1; i < 6; i++) { + map[get.translation("equip" + i)] = "equip" + i; + if (target.hasDisabledSlot(i)) { + list.push("equip" + i); } } - const transList=list.map(i=>get.translation(i)); - const {result:{bool,links}}=await player.chooseButton([ - '恩仇:请选择'+get.translation(target)+'要恢复的装备栏', - [transList,'tdnodes'], - ],true).set('map',map) - .set('ai',button=>1/(['equip5','equip4','equip1','equip3','equip2'].indexOf(get.event('map')[button.link])+2)); - if(bool) await target.enableEquip(links.slice().map(i=>map[i])); + let result; + const transList = list.map((i) => get.translation(i)); + if (transList.length == 1) result = { bool: true, links: transList }; + else + result = await player + .chooseButton( + [ + "恩仇:请选择" + get.translation(target) + "要恢复的装备栏", + [transList, "tdnodes"], + ], + true + ) + .set("map", map) + .set( + "ai", + (button) => + 1 / + (["equip5", "equip4", "equip1", "equip3", "equip2"].indexOf( + get.event("map")[button.link] + ) + + 2) + ) + .forResult(); + if (result.bool) await target.enableEquip(result.links.slice().map((i) => map[i])); }, - ai:{ - order:9, - result:{target:-1}, + ai: { + order: 9, + result: { target: -1 }, }, }, //侠关羽 - twzhongyi:{ - mod:{ - targetInRange(card){ - if(card.name=='sha') return true; + twzhongyi: { + mod: { + targetInRange(card) { + if (card.name == "sha") return true; }, }, - audio:2, - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(event.card.name!='sha') return false; - return player.getHistory('sourceDamage',evt=>evt.card&&evt.card==event.card).length; + audio: 2, + trigger: { player: "useCardAfter" }, + filter(event, player) { + if (event.card.name != "sha") return false; + return player.getHistory("sourceDamage", (evt) => evt.card && evt.card == event.card) + .length; }, - forced:true, - async content(event,trigger,player){ + forced: true, + async content(event, trigger, player) { //const num=player.getHistory('sourceDamage',evt=>evt.card&&evt.card==trigger.card).reduce((sum,evt)=>sum+evt.num,0); - const num=game.countPlayer2(target=>{ - return target.hasHistory('damage',evt=>{ - return evt.card&&evt.card==trigger.card; + const num = game.countPlayer2((target) => { + return target.hasHistory("damage", (evt) => { + return evt.card && evt.card == trigger.card; }); }); - const num2=1+player.getAllHistory('custom',evt=>evt.twzhongyi).length; - let choice=['摸牌'],choiceList=['摸'+get.cnNumber(num)+'张牌']; - if(player.isDamaged()){ - choice.addArray(['回血','背水!']); + const num2 = 1 + player.getAllHistory("custom", (evt) => evt.twzhongyi).length; + let choice = ["摸牌"], + choiceList = ["摸" + get.cnNumber(num) + "张牌"]; + if (player.isDamaged()) { + choice.addArray(["回血", "背水!"]); choiceList.addArray([ - '回复'+num+'点体力', - '失去'+num2+'点体力,依次执行以上所有项', + "回复" + num + "点体力", + "失去" + num2 + "点体力,依次执行以上所有项", ]); } - const {result:{control}}=await player.chooseControl(choice) - .set('prompt','忠义:请选择一项').set('choiceList',choiceList) - .set('ai',()=>{ - const player=get.event('player'); - const num=get.event('num'),num2=get.event('num2'); - if(player.isHealthy()) return '摸牌'; - return (player.hp+player.countCards('hs',card=>player.canSaveCard(card,player))-num2>0&&num>num2)?'背水!':'回血'; - }).set('num',num).set('num2',num2); - if(control!='cancel2'){ - if(control=='背水!'){ + const { + result: { control }, + } = await player + .chooseControl(choice) + .set("prompt", "忠义:请选择一项") + .set("choiceList", choiceList) + .set("ai", () => { + const player = get.event("player"); + const num = get.event("num"), + num2 = get.event("num2"); + if (player.isHealthy()) return "摸牌"; + return player.hp + + player.countCards("hs", (card) => player.canSaveCard(card, player)) - + num2 > + 0 && num > num2 + ? "背水!" + : "回血"; + }) + .set("num", num) + .set("num2", num2); + if (control != "cancel2") { + if (control == "背水!") { await player.loseHp(num2); - player.getHistory('custom').push({twzhongyi:true}); + player.getHistory("custom").push({ twzhongyi: true }); } - if(control!='回血') await player.draw(num); - if(control!='摸牌') await player.recover(num); + if (control != "回血") await player.draw(num); + if (control != "摸牌") await player.recover(num); } }, }, - twchue:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter(event,player){ - return event.card.name=='sha'&&event.isFirstTarget&&event.targets.length==1&&game.hasPlayer(target=>!event.targets.includes(target)&&player.canUse(event.card,target)); + twchue: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter(event, player) { + return ( + event.card.name == "sha" && + event.isFirstTarget && + event.targets.length == 1 && + game.hasPlayer( + (target) => !event.targets.includes(target) && player.canUse(event.card, target) + ) + ); }, - prompt2:'失去1点体力,额外指定至多等同于你体力值的目标', - check(event,player){ - return player.hp+player.countCards('hs',card=>player.canSaveCard(card,player))-1>0; + prompt2: "失去1点体力,额外指定至多等同于你体力值的目标", + check(event, player) { + return ( + player.hp + player.countCards("hs", (card) => player.canSaveCard(card, player)) - 1 > + 0 + ); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await player.loseHp(); - const targetx=trigger.targets.slice(),num=player.getHp(); - if(!num) return; - const {result:{bool,targets}}=await player.chooseTarget('额外指定至多'+get.cnNumber(num)+'名目标',[1,num],(card,player,target)=>{ - const trigger=_status.event.getTrigger(); - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); - }).set('ai',target=>{ - const player=get.event('player'),trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,player,player); - }); - if(!bool) return; + const targetx = trigger.targets.slice(), + num = player.getHp(); + if (!num) return; + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "额外指定至多" + get.cnNumber(num) + "名目标", + [1, num], + (card, player, target) => { + const trigger = _status.event.getTrigger(); + return ( + !trigger.targets.includes(target) && player.canUse(trigger.card, target) + ); + } + ) + .set("ai", (target) => { + const player = get.event("player"), + trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, player, player); + }); + if (!bool) return; player.line(targets); trigger.targets.addArray(targets); }, - group:['twchue_gain','twchue_effect'], - marktext:'勇', - intro:{ - name:'勇', - content:'mark', + group: ["twchue_gain", "twchue_effect"], + marktext: "勇", + intro: { + name: "勇", + content: "mark", }, - subSkill:{ - gain:{ - audio:'twchue', - trigger:{player:['damageEnd','loseHpEnd']}, - forced:true, - locked:false, - async content(event,trigger,player){ + subSkill: { + gain: { + audio: "twchue", + trigger: { player: ["damageEnd", "loseHpEnd"] }, + forced: true, + locked: false, + async content(event, trigger, player) { await player.draw(); - player.addMark('twchue',1); + player.addMark("twchue", 1); }, }, - effect:{ - audio:'twchue', - trigger:{global:'phaseEnd'}, - filter(event,player){ - const card=new lib.element.VCard({name:'sha'}); - return player.hasUseTarget(card)&&/*player.getHistory('useSkill',evt=>{ + effect: { + audio: "twchue", + trigger: { global: "phaseEnd" }, + filter(event, player) { + const card = new lib.element.VCard({ name: "sha" }); + return ( + player.hasUseTarget(card) && + /*player.getHistory('useSkill',evt=>{ return evt.skill=='twchue_gain'; - }).length&&player.getHp()&&*/player.countMark('twchue')>=player.getHp(); + }).length&&player.getHp()&&*/ player.countMark("twchue") >= player.getHp() + ); }, - check(event,player){ - return player.hasValueTarget(new lib.element.VCard({name:'sha'})); + check(event, player) { + return player.hasValueTarget(new lib.element.VCard({ name: "sha" })); }, - prompt2(event,player){ - const num=player.getHp(); - return '失去'+num+'个“勇”标记,视为使用一张造成的伤害+1且可以额外指定'+num+'个目标的【杀】'; + prompt2(event, player) { + const num = player.getHp(); + return ( + "失去" + + num + + "个“勇”标记,视为使用一张造成的伤害+1且可以额外指定" + + num + + "个目标的【杀】" + ); }, - async content(event,trigger,player){ - const num=player.getHp(); - player.removeMark('twchue',num); - const card=new lib.element.VCard({name:'sha'}); - player.when('useCard2') - .filter(evt=>evt.getParent(2)==event&&game.hasPlayer(target=>!evt.targets.includes(target)&&player.canUse(evt.card,target))) - .assign({ - firstDo:true, - }) - .then(()=>{ - trigger.baseDamage++; - player.chooseTarget('额外指定至多'+get.cnNumber(num)+'名目标',[1,num],(card,player,target)=>{ - const trigger=_status.event.getTrigger(); - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); - }).set('ai',target=>{ - const player=get.event('player'),trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,player,player); - }); - }) - .then(()=>{ - if(result.bool){ - const targets=result.targets; - player.line(targets); - trigger.targets.addArray(targets); - } - }).vars({num:num}); - player.chooseUseTarget('视为使用造成的伤害+1且可以额外指定'+num+'个目标的【杀】',card,false,true); + async content(event, trigger, player) { + const num = player.getHp(); + player.removeMark("twchue", num); + const card = new lib.element.VCard({ name: "sha" }); + player + .when("useCard2") + .filter( + (evt) => + evt.getParent(2) == event && + game.hasPlayer( + (target) => + !evt.targets.includes(target) && + player.canUse(evt.card, target) + ) + ) + .assign({ + firstDo: true, + }) + .then(() => { + trigger.baseDamage++; + player + .chooseTarget( + "额外指定至多" + get.cnNumber(num) + "名目标", + [1, num], + (card, player, target) => { + const trigger = _status.event.getTrigger(); + return ( + !trigger.targets.includes(target) && + player.canUse(trigger.card, target) + ); + } + ) + .set("ai", (target) => { + const player = get.event("player"), + trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, player, player); + }); + }) + .then(() => { + if (result.bool) { + const targets = result.targets; + player.line(targets); + trigger.targets.addArray(targets); + } + }) + .vars({ num: num }); + player.chooseUseTarget( + "视为使用造成的伤害+1且可以额外指定" + num + "个目标的【杀】", + card, + false, + true + ); }, }, }, }, //夏侯惇 - twdanlie:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return game.hasPlayer(target=>player.canCompare(target)); + twdanlie: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return game.hasPlayer((target) => player.canCompare(target)); }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return player.canCompare(target); }, - usable:1, - selectTarget:[1,3], - multitarget:true, - multiline:true, - group:'twdanlie_add', - content:function(){ - 'step 0' - player.chooseToCompare(targets).setContent('chooseToCompareMeanwhile'); - 'step 1' - if(result.winner&&result.winner==player){ + usable: 1, + selectTarget: [1, 3], + multitarget: true, + multiline: true, + group: "twdanlie_add", + content: function () { + "step 0"; + player.chooseToCompare(targets).setContent("chooseToCompareMeanwhile"); + "step 1"; + if (result.winner && result.winner == player) { player.line(targets); - targets.forEach(target=>target.damage()); - } - else player.loseHp(); + targets.forEach((target) => target.damage()); + } else player.loseHp(); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(player.getHp()>2) return -get.damageEffect(target,player,player)-10/target.countCards('h'); - var hs=player.getCards('h').sort((a,b)=>b.number-a.number); - var ts=target.getCards('h').sort((a,b)=>b.number-a.number); - if(!hs.length||!ts.length) return 0; - if(Math.min(13,hs[0].number+player.getDamagedHp())>ts[0].number) return -get.damageEffect(target,player,player); + ai: { + order: 10, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if (player.getHp() > 2) + return ( + -get.damageEffect(target, player, player) - 10 / target.countCards("h") + ); + var hs = player.getCards("h").sort((a, b) => b.number - a.number); + var ts = target.getCards("h").sort((a, b) => b.number - a.number); + if (!hs.length || !ts.length) return 0; + if (Math.min(13, hs[0].number + player.getDamagedHp()) > ts[0].number) + return -get.damageEffect(target, player, player); return 0; }, }, }, - subSkill:{ - add:{ - audio:'twdanlie', - trigger:{player:'compare',target:'compare'}, - filter:function(event,player){ - if(!player.isDamaged()) return false; - if(player!=event.target&&event.iwhile) return false; + subSkill: { + add: { + audio: "twdanlie", + trigger: { player: "compare", target: "compare" }, + filter: function (event, player) { + if (!player.isDamaged()) return false; + if (player != event.target && event.iwhile) return false; return true; }, - forced:true, - locked:false, - content:function(){ - var num=player.getDamagedHp(); - if(player==trigger.player){ - trigger.num1+=num; - if(trigger.num1>13) trigger.num1=13; + forced: true, + locked: false, + content: function () { + var num = player.getDamagedHp(); + if (player == trigger.player) { + trigger.num1 += num; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += num; + if (trigger.num2 > 13) trigger.num2 = 13; } - else{ - trigger.num2+=num; - if(trigger.num2>13) trigger.num2=13; - } - game.log(player,'的拼点牌点数+',num); + game.log(player, "的拼点牌点数+", num); }, }, }, }, //张葳 - twhuzhong:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - return event.card.name=='sha'&&!game.hasNature(event.card,'linked')&&event.targets.length==1&&player.isPhaseUsing()&&(game.hasPlayer(target=>!event.targets.includes(target)&&player.canUse(event.card,target))||event.target.countCards('h')>0); + twhuzhong: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !game.hasNature(event.card, "linked") && + event.targets.length == 1 && + player.isPhaseUsing() && + (game.hasPlayer( + (target) => !event.targets.includes(target) && player.canUse(event.card, target) + ) || + event.target.countCards("h") > 0) + ); }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - var list=['cancel2']; - var choiceList=[ - '令此【杀】可以额外指定一个目标', - '弃置'+get.translation(target)+'一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】', + direct: true, + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + var list = ["cancel2"]; + var choiceList = [ + "令此【杀】可以额外指定一个目标", + "弃置" + + get.translation(target) + + "一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】", ]; - if(target.countCards('h')) list.unshift('其弃置'); - else choiceList[1]=''+choiceList[1]+''; - if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx))) list.unshift('多指'); - else choiceList[0]=''+choiceList[0]+''; - player.chooseControl(list).set('choiceList',choiceList).set('ai',()=>{ - var controls=_status.event.controls; - var trigger=_status.event.getTrigger(); - var player=trigger.player; - var target=trigger.target; - if(controls.includes('其弃置')&&_status.event.goon) return '其弃置'; - if(controls.includes('多指')){ - if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx)&&get.effect(targetx,trigger.card,player,player)>0)) return '你弃置'; - } - return 'cancel2'; - }).set('goon',function(){ - var d1=true; - if(player.hasSkill('jueqing')||player.hasSkill('gangzhi')) d1=false; - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||player.hasSkillTag('directHit_ai',true,{ - target:target, - card:trigger.card, - },true)){ - if(!target.hasSkill('gangzhi')) d1=false; - if(!target.hasSkillTag('filterDamage',null,{ - player:player, - card:trigger.card, - })&&get.attitude(player,target)<0) return true; - } - if(d1) return get.damageEffect(player,player,player)>0; - return false; - }()).set('prompt','护众:是否摸一张牌并执行其中一项?'); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twhuzhong',target); - player.draw(); - if(result.control=='其弃置'){ - player.discardPlayerCard(target,'h',true); - player.when('useCardAfter').filter(evt=>evt==trigger.getParent()).then(()=>{ - if(player.getHistory('sourceDamage',evt=>evt.card==trigger.card).length){ - player.draw(); - player.addTempSkill('twhuzhong_sha','phaseUseAfter'); - player.addMark('twhuzhong_sha',1,false); + if (target.countCards("h")) list.unshift("其弃置"); + else choiceList[1] = '' + choiceList[1] + ""; + if ( + game.hasPlayer( + (targetx) => + !trigger.targets.includes(targetx) && player.canUse(trigger.card, targetx) + ) + ) + list.unshift("多指"); + else choiceList[0] = '' + choiceList[0] + ""; + player + .chooseControl(list) + .set("choiceList", choiceList) + .set("ai", () => { + var controls = _status.event.controls; + var trigger = _status.event.getTrigger(); + var player = trigger.player; + var target = trigger.target; + if (controls.includes("其弃置") && _status.event.goon) return "其弃置"; + if (controls.includes("多指")) { + if ( + game.hasPlayer( + (targetx) => + !trigger.targets.includes(targetx) && + player.canUse(trigger.card, targetx) && + get.effect(targetx, trigger.card, player, player) > 0 + ) + ) + return "你弃置"; + } + return "cancel2"; + }) + .set( + "goon", + (function () { + var d1 = true; + if (player.hasSkill("jueqing") || player.hasSkill("gangzhi")) d1 = false; + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: trigger.card, + }, + true + ) + ) { + if (!target.hasSkill("gangzhi")) d1 = false; + if ( + !target.hasSkillTag("filterDamage", null, { + player: player, + card: trigger.card, + }) && + get.attitude(player, target) < 0 + ) + return true; } - }); + if (d1) return get.damageEffect(player, player, player) > 0; + return false; + })() + ) + .set("prompt", "护众:是否摸一张牌并执行其中一项?"); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twhuzhong", target); + player.draw(); + if (result.control == "其弃置") { + player.discardPlayerCard(target, "h", true); + player + .when("useCardAfter") + .filter((evt) => evt == trigger.getParent()) + .then(() => { + if ( + player.getHistory("sourceDamage", (evt) => evt.card == trigger.card) + .length + ) { + player.draw(); + player.addTempSkill("twhuzhong_sha", "phaseUseAfter"); + player.addMark("twhuzhong_sha", 1, false); + } + }); event.finish(); } - } - else event.finish(); - 'step 2' - player.chooseTarget('请选择'+get.translation(trigger.card)+'的额外目标',function(card,player,target){ - var trigger=_status.event.getTrigger(); - return !trigger.targets.includes(target)&&player.canUse(trigger.card,target); - }).set('ai',function(target){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - return get.effect(target,trigger.card,player,player); - }); - 'step 3' - if(result.bool){ + } else event.finish(); + "step 2"; + player + .chooseTarget( + "请选择" + get.translation(trigger.card) + "的额外目标", + function (card, player, target) { + var trigger = _status.event.getTrigger(); + return ( + !trigger.targets.includes(target) && player.canUse(trigger.card, target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + return get.effect(target, trigger.card, player, player); + }); + "step 3"; + if (result.bool) { player.line(result.targets); trigger.getParent().targets.addArray(result.targets); - game.log(result.targets,'成为了',trigger.card,'的额外目标'); + game.log(result.targets, "成为了", trigger.card, "的额外目标"); } }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('twhuzhong_sha'); + subSkill: { + sha: { + charlotte: true, + onremove: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("twhuzhong_sha"); }, }, - } - } + }, + }, }, - twfenwang:{ - audio:2, - trigger:{source:'damageBegin2',player:'damageBegin4'}, - filter:function(event,player,name){ - if(name=='damageBegin2'){ - return !event.hasNature()&&player.countCards('h')>=event.player.countCards('h'); + twfenwang: { + audio: 2, + trigger: { source: "damageBegin2", player: "damageBegin4" }, + filter: function (event, player, name) { + if (name == "damageBegin2") { + return !event.hasNature() && player.countCards("h") >= event.player.countCards("h"); } return event.hasNature(); }, - forced:true, - content:function(){ - 'step 0' - if(event.triggername=='damageBegin2'){ + forced: true, + content: function () { + "step 0"; + if (event.triggername == "damageBegin2") { player.line(trigger.player); trigger.num++; event.finish(); - } - else player.chooseToDiscard('h','弃置一张手牌,或令此伤害+1').set('ai',function(card){ - return 8-get.value(card); - }); - 'step 1' - if(!result.bool) trigger.num++; + } else + player.chooseToDiscard("h", "弃置一张手牌,或令此伤害+1").set("ai", function (card) { + return 8 - get.value(card); + }); + "step 1"; + if (!result.bool) trigger.num++; }, }, //夏侯子萼 //差点和夏侯紫萼搞混 - twchengxi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return game.hasPlayer(target=>lib.skill.twchengxi.filterTarget(null,player,target)); + twchengxi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return game.hasPlayer((target) => lib.skill.twchengxi.filterTarget(null, player, target)); }, - filterTarget:function(card,player,target){ - if(player.getStorage('twchengxi_used').includes(target)||target==player) return false; - return !player.hasSkillTag('noCompareSource')&&target.countCards('h')>0&&!target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + if (player.getStorage("twchengxi_used").includes(target) || target == player) + return false; + return ( + !player.hasSkillTag("noCompareSource") && + target.countCards("h") > 0 && + !target.hasSkillTag("noCompareTarget") + ); }, - content:function(){ - 'step 0' - if(!player.storage.twchengxi_used){ - player.when('phaseUseAfter').then(()=>delete player.storage.twchengxi_used); + content: function () { + "step 0"; + if (!player.storage.twchengxi_used) { + player.when("phaseUseAfter").then(() => delete player.storage.twchengxi_used); } - player.markAuto('twchengxi_used',[target]); + player.markAuto("twchengxi_used", [target]); player.draw(); - 'step 1' - if(player.canCompare(target)) player.chooseToCompare(target); + "step 1"; + if (player.canCompare(target)) player.chooseToCompare(target); else event.finish(); - 'step 2' - if(result.bool){ - player.addSkill('twchengxi_effect'); - } - else{ - var card={name:'sha',isCard:true}; - if(target.canUse(card,player,false)) target.useCard(card,player,false); + "step 2"; + if (result.bool) { + player.addSkill("twchengxi_effect"); + } else { + var card = { name: "sha", isCard: true }; + if (target.canUse(card, player, false)) target.useCard(card, player, false); } }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(player.hasSkill('twchengxi_effect')) return 0; - var hs=player.getCards('h').sort((a,b)=>b.number-a.number); - var ts=target.getCards('h').sort((a,b)=>b.number-a.number); - if(!hs.length||!ts.length) return 0; - if(hs[0].number>ts[0].number) return -3; - if(!target.canUse({name:'sha',isCard:true},player,false)) return -1; + ai: { + order: 8, + result: { + target: function (player, target) { + if (player.hasSkill("twchengxi_effect")) return 0; + var hs = player.getCards("h").sort((a, b) => b.number - a.number); + var ts = target.getCards("h").sort((a, b) => b.number - a.number); + if (!hs.length || !ts.length) return 0; + if (hs[0].number > ts[0].number) return -3; + if (!target.canUse({ name: "sha", isCard: true }, player, false)) return -1; return 0; }, }, }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return get.type(event.card)=='basic'||get.type(event.card)=='trick'; + subSkill: { + effect: { + charlotte: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return get.type(event.card) == "basic" || get.type(event.card) == "trick"; }, - forced:true, - popup:false, - content:function(){ - player.removeSkill('twchengxi_effect'); - player.when('useCardAfter').filter(evt=>evt==trigger).then(()=>{ - if(trigger.targets){ - var card={ - name:trigger.card.name, - isCard:true, - }; - var targets=trigger.targets.filter(i=>i.isIn()&&player.canUse(card,i,false)); - if(targets.length) player.useCard(card,targets,false); - } - }); + forced: true, + popup: false, + content: function () { + player.removeSkill("twchengxi_effect"); + player + .when("useCardAfter") + .filter((evt) => evt == trigger) + .then(() => { + if (trigger.targets) { + var card = { + name: trigger.card.name, + isCard: true, + }; + var targets = trigger.targets.filter( + (i) => i.isIn() && player.canUse(card, i, false) + ); + if (targets.length) player.useCard(card, targets, false); + } + }); + }, + mark: true, + marktext: "袭", + intro: { + content: + "使用的下一张基本牌或非延时锦囊牌结算完毕后视为对相同目标再使用一张无次数限制的同名牌", }, - mark:true, - marktext:'袭', - intro:{content:'使用的下一张基本牌或非延时锦囊牌结算完毕后视为对相同目标再使用一张无次数限制的同名牌'}, }, }, }, //侠刘备 - twshenyi:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(!event.player.isIn()) return false; - if(event.player.getHistory('damage').indexOf(event)!=0) return false; - return event.player==player||player.inRange(event.player); + twshenyi: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if (!event.player.isIn()) return false; + if (event.player.getHistory("damage").indexOf(event) != 0) return false; + return event.player == player || player.inRange(event.player); }, - usable:1, - direct:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - var list=get.inpileVCardList(info=>{ - return ['basic','trick','delay'].includes(info[0])&&!player.getStorage('twshenyi').includes(info[2]); + usable: 1, + direct: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger; + var list = get.inpileVCardList((info) => { + return ( + ["basic", "trick", "delay"].includes(info[0]) && + !player.getStorage("twshenyi").includes(info[2]) + ); }); - var dialog=[`###${get.prompt('twshenyi',trigger.player)}###
              从牌堆中将一张牌作为“侠义”置于武将牌上${player!=trigger.player&&player.countCards('h')?',然后将任意张手牌交给其':''}
              `,[list,'vcard']]; - var result=yield player.chooseButton(dialog).set('ai',function(button){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player,name=button.link[2]; - if(!get.cardPile2(card=>card.name==name)) return 0; - var value=get.value({name:name}); - if(['tao','jiu','caochuan','wuxie'].includes(name)&&get.event().getRand()>0.4) return value*2; + var dialog = [ + `###${get.prompt( + "twshenyi", + trigger.player + )}###
              从牌堆中将一张牌作为“侠义”置于武将牌上${ + player != trigger.player && player.countCards("h") + ? ",然后将任意张手牌交给其" + : "" + }
              `, + [list, "vcard"], + ]; + var result = yield player.chooseButton(dialog).set("ai", function (button) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player, + name = button.link[2]; + if (!get.cardPile2((card) => card.name == name)) return 0; + var value = get.value({ name: name }); + if (["tao", "jiu", "caochuan", "wuxie"].includes(name) && get.event().getRand() > 0.4) + return value * 2; return value; }); - if(result.bool){ - var name=result.links[0][2],nature=result.links[0][3]; - var cardx={name:name,nature:nature}; - player.logSkill('twshenyi',trigger.player); + if (result.bool) { + var name = result.links[0][2], + nature = result.links[0][3]; + var cardx = { name: name, nature: nature }; + player.logSkill("twshenyi", trigger.player); player.popup(cardx); - player.markAuto('twshenyi',[name]); - game.log(player,'声明了',`#y${get.translation(cardx)}`); - var card=get.cardPile2(card=>get.name(card,false)==name&&get.nature(card,false)==nature); - if(card) player.addToExpansion([card],'gain2').gaintag.add('twshenyi'); - else{ - var card=get.cardPile2(card=>get.type2(card)==get.type2(name)); - if(card) player.addToExpansion([card],'gain2').gaintag.add('twshenyi'); - else player.chat('无牌可得?!'); + player.markAuto("twshenyi", [name]); + game.log(player, "声明了", `#y${get.translation(cardx)}`); + var card = get.cardPile2( + (card) => get.name(card, false) == name && get.nature(card, false) == nature + ); + if (card) player.addToExpansion([card], "gain2").gaintag.add("twshenyi"); + else { + var card = get.cardPile2((card) => get.type2(card) == get.type2(name)); + if (card) player.addToExpansion([card], "gain2").gaintag.add("twshenyi"); + else player.chat("无牌可得?!"); } - if(trigger.player!=player&&player.countCards('h')){ + if (trigger.player != player && player.countCards("h")) { game.delayex(); - var skill='twshenyi_'+player.playerid; - game.broadcastAll(lib.skill.twshenyi.createGainTag,skill,player.name); - game.addVideo('skill',player,['twshenyi',[skill,player.name]]); - var result2=yield player.chooseCard('伸义:是否将任意张牌交给'+get.translation(trigger.player)+'?',[1,player.countCards('h')]).set('ai',card=>{ - if(!_status.event.goon) return 0; - return 7-get.value(card); - }).set('goon',get.attitude(player,trigger.player)>0); - if(result2.bool){ - player.give(result2.cards,trigger.player).gaintag.add(skill); - player.addSkill('twshenyi_draw'); + var skill = "twshenyi_" + player.playerid; + game.broadcastAll(lib.skill.twshenyi.createGainTag, skill, player.name); + game.addVideo("skill", player, ["twshenyi", [skill, player.name]]); + var result2 = yield player + .chooseCard( + "伸义:是否将任意张牌交给" + get.translation(trigger.player) + "?", + [1, player.countCards("h")] + ) + .set("ai", (card) => { + if (!_status.event.goon) return 0; + return 7 - get.value(card); + }) + .set("goon", get.attitude(player, trigger.player) > 0); + if (result2.bool) { + player.give(result2.cards, trigger.player).gaintag.add(skill); + player.addSkill("twshenyi_draw"); } } - } - else player.storage.counttrigger.twshenyi--; + } else player.storage.counttrigger.twshenyi--; }, - video:(player,info)=>lib.skill.twshenyi.createGainTag(info[0],info[1]), - createGainTag:function(skill,name){ - if(!lib.skill[skill]){ - lib.skill[skill]={charlotte:true}; - lib.translate[skill]='义·'+get.translation(name); + video: (player, info) => lib.skill.twshenyi.createGainTag(info[0], info[1]), + createGainTag: function (skill, name) { + if (!lib.skill[skill]) { + lib.skill[skill] = { charlotte: true }; + lib.translate[skill] = "义·" + get.translation(name); } - if(!_status.postReconnect.twshenyi){ - _status.postReconnect.twshenyi=[ - lib.skill.twshenyi.createGainTag,[],[] - ]; + if (!_status.postReconnect.twshenyi) { + _status.postReconnect.twshenyi = [lib.skill.twshenyi.createGainTag, [], []]; } _status.postReconnect.twshenyi[1].add(skill); _status.postReconnect.twshenyi[2].add(name); }, - marktext:'义', - intro:{ - name:'侠义', - content:'expansion', - markcount:'expansion', + marktext: "义", + intro: { + name: "侠义", + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ + onremove: function (player, skill) { delete player.storage[skill]; //var cards=player.getExpansions(skill); //if(cards.length) player.loseToDiscardpile(cards); }, - subSkill:{ - draw:{ - charlotte:true, - audio:'twshenyi', - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + draw: { + charlotte: true, + audio: "twshenyi", + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var skill='twshenyi_'+player.playerid; - return game.hasPlayer(target=>{ - var evt=event.getl(target); - if(!evt||!evt.hs||!evt.hs.length) return false; - for(let i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes(skill)) return true; + filter: function (event, player) { + var skill = "twshenyi_" + player.playerid; + return game.hasPlayer((target) => { + var evt = event.getl(target); + if (!evt || !evt.hs || !evt.hs.length) return false; + for (let i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes(skill)) return true; } return false; }); }, - forced:true, - direct:true, - content:function(){ - var skill='twshenyi_'+player.playerid; - var num=0; - var targets=game.filterPlayer(target=>{ - var evt=trigger.getl(target); - var numx=0; - if(!evt||!evt.hs||!evt.hs.length) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes(skill)) numx++; + forced: true, + direct: true, + content: function () { + var skill = "twshenyi_" + player.playerid; + var num = 0; + var targets = game.filterPlayer((target) => { + var evt = trigger.getl(target); + var numx = 0; + if (!evt || !evt.hs || !evt.hs.length) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes(skill)) numx++; } - if(numx>0) return num+=numx; + if (numx > 0) return (num += numx); return false; }); - if(num>0){ - player.logSkill('twshenyi_draw',targets); + if (num > 0) { + player.logSkill("twshenyi_draw", targets); player.draw(num); } }, }, }, }, - twxinghan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getExpansions('twshenyi').length>game.countPlayer(); + twxinghan: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getExpansions("twshenyi").length > game.countPlayer(); }, - check:function(event,player){ - if(player.hp>=3||(player.countCards('h')>=4&&player.getExpansions('twshenyi').every(card=>!player.hasValueTarget(card)||!get.tag(card,'damage')||!lib.skill.xunshi.isXunshi(card)))) return false; - return player.getExpansions('twshenyi').some(card=>player.hasValueTarget(card)); + check: function (event, player) { + if ( + player.hp >= 3 || + (player.countCards("h") >= 4 && + player + .getExpansions("twshenyi") + .every( + (card) => + !player.hasValueTarget(card) || + !get.tag(card, "damage") || + !lib.skill.xunshi.isXunshi(card) + )) + ) + return false; + return player.getExpansions("twshenyi").some((card) => player.hasValueTarget(card)); }, - direct:true, - content:function*(event,map){ - var player=map.player; - var result=yield player.chooseBool().set('createDialog',[ - get.prompt('twxinghan'), - `
              按顺序使用以下“侠义”牌。但是回合结束时你须弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)
              `, - player.getExpansions('twshenyi').filter(card=>player.hasUseTarget(card)).reverse(), - 'hidden', - ]).set('choice',lib.skill.twxinghan.check(null,player)); - if(!result.bool){ + direct: true, + content: function* (event, map) { + var player = map.player; + var result = yield player + .chooseBool() + .set("createDialog", [ + get.prompt("twxinghan"), + `
              按顺序使用以下“侠义”牌。但是回合结束时你须弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)
              `, + player + .getExpansions("twshenyi") + .filter((card) => player.hasUseTarget(card)) + .reverse(), + "hidden", + ]) + .set("choice", lib.skill.twxinghan.check(null, player)); + if (!result.bool) { event.finish(); return; } - while(true){ - var cards=player.getExpansions('twshenyi').filter(card=>player.hasUseTarget(card)).reverse(); - if(!cards.length) break; - yield player.chooseUseTarget(true,cards[0],false); + while (true) { + var cards = player + .getExpansions("twshenyi") + .filter((card) => player.hasUseTarget(card)) + .reverse(); + if (!cards.length) break; + yield player.chooseUseTarget(true, cards[0], false); } - player.when('phaseEnd').then(()=>{ - if(player.countCards('h')) player.chooseToDiscard(player.countCards('h'),true); - var num=Math.max(1,player.getHp()-1); + player.when("phaseEnd").then(() => { + if (player.countCards("h")) player.chooseToDiscard(player.countCards("h"), true); + var num = Math.max(1, player.getHp() - 1); player.loseHp(num); }); }, - group:'twxinghan_init', - subSkill:{ - init:{ - audio:'twxinghan', - trigger:{ - player:['loseEnd','dying','phaseBefore','phaseAfter','dyingAfter','die'], - global:['equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], + group: "twxinghan_init", + subSkill: { + init: { + audio: "twxinghan", + trigger: { + player: ["loseEnd", "dying", "phaseBefore", "phaseAfter", "dyingAfter", "die"], + global: [ + "equipEnd", + "addJudgeEnd", + "gainEnd", + "loseAsyncEnd", + "addToExpansionEnd", + ], }, - filter:function(event,player){ - return (player.getExpansions('twshenyi').length&&event.name!='die'&&(_status.currentPhase!=player||player.isDying()))^player.hasSkill('twxinghan_in'); + filter: function (event, player) { + return ( + (player.getExpansions("twshenyi").length && + event.name != "die" && + (_status.currentPhase != player || player.isDying())) ^ + player.hasSkill("twxinghan_in") + ); }, - forced:true, - firstDo:true, - silent:true, - forceDie:true, - content:function(){ - if(player.getExpansions('twshenyi').length&&trigger.name!='die'&&(_status.currentPhase!=player||player.isDying())){ - var cards=player.getExpansions('twshenyi'); - var cardsx=cards.map(card=>{ - var cardx=ui.create.card(); + forced: true, + firstDo: true, + silent: true, + forceDie: true, + content: function () { + if ( + player.getExpansions("twshenyi").length && + trigger.name != "die" && + (_status.currentPhase != player || player.isDying()) + ) { + var cards = player.getExpansions("twshenyi"); + var cardsx = cards.map((card) => { + var cardx = ui.create.card(); cardx.init(get.cardInfo(card)); - cardx._cardid=card.cardid; + cardx._cardid = card.cardid; return cardx; }); - player.directgains(cardsx,null,'twxinghan_tag'); - player.addSkill('twxinghan_in'); - } - else player.removeSkill('twxinghan_in'); + player.directgains(cardsx, null, "twxinghan_tag"); + player.addSkill("twxinghan_in"); + } else player.removeSkill("twxinghan_in"); }, }, - in:{ - charlotte:true, - audio:'twxinghan', - trigger:{player:'addToExpansionEnd'}, - filter:function(event,player){ - return event.gaintag.includes('twshenyi'); + in: { + charlotte: true, + audio: "twxinghan", + trigger: { player: "addToExpansionEnd" }, + filter: function (event, player) { + return event.gaintag.includes("twshenyi"); }, - forced:true, - locked:false, - silent:true, - content:function(){ - 'step 0' - var cards2=player.getCards('s',card=>card.hasGaintag('twxinghan_tag')); - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards2,player); + forced: true, + locked: false, + silent: true, + content: function () { + "step 0"; + var cards2 = player.getCards("s", (card) => card.hasGaintag("twxinghan_tag")); + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards2, + player + ); } - cards2.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - 'step 1' - var cards=player.getExpansions('twshenyi'); - var cardsx=cards.map(card=>{ - var cardx=ui.create.card(); + cards2.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + "step 1"; + var cards = player.getExpansions("twshenyi"); + var cardsx = cards.map((card) => { + var cardx = ui.create.card(); cardx.init(get.cardInfo(card)); - cardx._cardid=card.cardid; + cardx._cardid = card.cardid; return cardx; }); - player.directgains(cardsx,null,'twxinghan_tag'); + player.directgains(cardsx, null, "twxinghan_tag"); }, - onremove:function(player){ - var cards2=player.getCards('s',card=>card.hasGaintag('twxinghan_tag')); - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards2,player); + onremove: function (player) { + var cards2 = player.getCards("s", (card) => card.hasGaintag("twxinghan_tag")); + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards2, + player + ); } - cards2.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); + cards2.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); }, - group:'twxinghan_use', + group: "twxinghan_use", }, - use:{ - charlotte:true, - trigger:{player:['useCardBefore','respondBefore']}, - filter:function(event,player){ - var cards=player.getCards('s',card=>card.hasGaintag('twxinghan_tag')&&card._cardid); - return event.cards&&event.cards.some(card=>{ - return cards.includes(card); - }); + use: { + charlotte: true, + trigger: { player: ["useCardBefore", "respondBefore"] }, + filter: function (event, player) { + var cards = player.getCards( + "s", + (card) => card.hasGaintag("twxinghan_tag") && card._cardid + ); + return ( + event.cards && + event.cards.some((card) => { + return cards.includes(card); + }) + ); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - var idList=player.getCards('s',card=>card.hasGaintag('twxinghan_tag')).map(i=>i._cardid); - var cards=player.getExpansions('twshenyi'); - var cards2=[]; - for(var card of trigger.cards){ - var cardx=cards.find(cardx=>cardx.cardid==card._cardid); - if(cardx) cards2.push(cardx); + forced: true, + popup: false, + firstDo: true, + content: function () { + var idList = player + .getCards("s", (card) => card.hasGaintag("twxinghan_tag")) + .map((i) => i._cardid); + var cards = player.getExpansions("twshenyi"); + var cards2 = []; + for (var card of trigger.cards) { + var cardx = cards.find((cardx) => cardx.cardid == card._cardid); + if (cardx) cards2.push(cardx); } - var cards3=trigger.cards.slice(); - trigger.cards=cards2; - trigger.card.cards=cards2; - if(player.isOnline2()){ - player.send(function(cards,player){ - cards.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); - },cards3,player); + var cards3 = trigger.cards.slice(); + trigger.cards = cards2; + trigger.card.cards = cards2; + if (player.isOnline2()) { + player.send( + function (cards, player) { + cards.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); + }, + cards3, + player + ); } - cards3.forEach(i=>i.delete()); - if(player==game.me) ui.updatehl(); + cards3.forEach((i) => i.delete()); + if (player == game.me) ui.updatehl(); }, }, }, + ai: { + combo: "twshenyi", + }, }, //张纮 - twquanqian:{ - audio:2, - sunbenSkill:true, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('twquanqian_sunben')&&player.countCards('h')&&game.countPlayer()>1; + twquanqian: { + audio: 2, + sunbenSkill: true, + enable: "phaseUse", + filter: function (event, player) { + return ( + !player.hasSkill("twquanqian_sunben") && + player.countCards("h") && + game.countPlayer() > 1 + ); }, - filterCard:function(card,player){ - return !ui.selected.cards.some(cardx=>get.suit(cardx,player)==get.suit(card,player)); + filterCard: function (card, player) { + return !ui.selected.cards.some( + (cardx) => get.suit(cardx, player) == get.suit(card, player) + ); }, - selectCard:[1,4], - check:function(card){ - return 1/(get.value(card)||0.5); + selectCard: [1, 4], + check: function (card) { + return 1 / (get.value(card) || 0.5); }, - position:'h', - complexCard:true, - discard:false, - lose:false, - delay:false, - filterTarget:lib.filter.notMe, - usable:1, - content:function(){ - 'step 0' - player.addSkill('twquanqian_sunben'); - player.give(cards,target); - if(cards.length<2) event.finish(); - 'step 1' - var card=get.cardPile2(card=>get.type(card)=='equip'); - if(card) player.gain(card,'gain2'); - 'step 2' - if(player.countCards('h')>=target.countCards('h')){ - if(target.countCards('h')) event._result={index:1}; + position: "h", + complexCard: true, + discard: false, + lose: false, + delay: false, + filterTarget: lib.filter.notMe, + usable: 1, + content: function () { + "step 0"; + player.addSkill("twquanqian_sunben"); + player.give(cards, target); + if (cards.length < 2) event.finish(); + "step 1"; + var card = get.cardPile2((card) => get.type(card) == "equip"); + if (card) player.gain(card, "gain2"); + "step 2"; + if (player.countCards("h") >= target.countCards("h")) { + if (target.countCards("h")) event._result = { index: 1 }; else event.finish(); + } else { + var str = get.translation(target); + player + .chooseControl() + .set("choiceList", [ + "将手牌数摸至与" + str + "相同", + "观看" + str + "的手牌并获得其一种花色的所有手牌", + ]) + .set("ai", () => { + var player = _status.event.player; + var target = _status.event.target; + if ( + target.countCards("h") - player.countCards("h") > + target.countCards("h") / 4 || + get.attitude(player, target) > 0 + ) + return 0; + return 1; + }) + .set("target", target); } - else{ - var str=get.translation(target); - player.chooseControl().set('choiceList',[ - '将手牌数摸至与'+str+'相同', - '观看'+str+'的手牌并获得其一种花色的所有手牌', - ]).set('ai',()=>{ - var player=_status.event.player; - var target=_status.event.target; - if(target.countCards('h')-player.countCards('h')>target.countCards('h')/4||get.attitude(player,target)>0) return 0; - return 1; - }).set('target',target); - } - 'step 3' - if(result.index==0){ - player.drawTo(target.countCards('h')); + "step 3"; + if (result.index == 0) { + player.drawTo(target.countCards("h")); event.finish(); return; } - var list=[]; - var dialog=['劝迁:获得'+get.translation(target)+'一种花色的所有牌']; - for(var suit of lib.suit.concat('none')){ - if(target.countCards('h',{suit:suit})){ - dialog.push('
              '+get.translation(suit+'2')+'牌
              '); - dialog.push(target.getCards('h',{suit:suit})); + var list = []; + var dialog = ["劝迁:获得" + get.translation(target) + "一种花色的所有牌"]; + for (var suit of lib.suit.concat("none")) { + if (target.countCards("h", { suit: suit })) { + dialog.push( + '
              ' + get.translation(suit + "2") + "牌
              " + ); + dialog.push(target.getCards("h", { suit: suit })); list.push(suit); } } - if(!list.length){ + if (!list.length) { event.finish(); return; } - player.chooseControl(list).set('dialog',dialog).set('ai',()=>{ - return _status.event.control; - }).set('control',(()=>{ - var getv=(cards)=>cards.map(i=>get.value(i)).reduce((p,c)=>p+c,0); - return list.sort((a,b)=>{ - return getv(target.getCards('h',{suit:b}))-getv(target.getCards('h',{suit:a})); - })[0]; - })()); - 'step 4' - if(result.control) player.gain(target.getCards('h',{suit:result.control}),target,'give'); + player + .chooseControl(list) + .set("dialog", dialog) + .set("ai", () => { + return _status.event.control; + }) + .set( + "control", + (() => { + var getv = (cards) => + cards.map((i) => get.value(i)).reduce((p, c) => p + c, 0); + return list.sort((a, b) => { + return ( + getv(target.getCards("h", { suit: b })) - + getv(target.getCards("h", { suit: a })) + ); + })[0]; + })() + ); + "step 4"; + if (result.control) + player.gain(target.getCards("h", { suit: result.control }), target, "give"); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - return target.countCards('h'); + ai: { + order: 7, + result: { + target: function (player, target) { + return target.countCards("h"); }, }, }, - subSkill:{ - sunben:{ - charlotte:true, - init:function(player){ - player.storage.twquanqian_sunben=0; + subSkill: { + sunben: { + charlotte: true, + init: function (player) { + player.storage.twquanqian_sunben = 0; }, - onremove:true, - mark:true, - intro:{ - markcount:function(num){ - return (num||0).toString(); + onremove: true, + mark: true, + intro: { + markcount: function (num) { + return (num || 0).toString(); }, - content:'弃牌进度:#/6', + content: "弃牌进度:#/6", }, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - if(event.type!='discard') return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length; + filter: function (event, player) { + if (event.type != "discard") return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length; }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - 'step 0' - player.addMark('twquanqian_sunben',trigger.getl(player).hs.length,false); - 'step 1' - if(player.countMark('twquanqian_sunben')>=6){ - player.removeSkill('twquanqian_sunben'); - player.popup('劝迁'); - game.log(player,'恢复了技能','#g【劝迁】'); + forced: true, + popup: false, + firstDo: true, + content: function () { + "step 0"; + player.addMark("twquanqian_sunben", trigger.getl(player).hs.length, false); + "step 1"; + if (player.countMark("twquanqian_sunben") >= 6) { + player.removeSkill("twquanqian_sunben"); + player.popup("劝迁"); + game.log(player, "恢复了技能", "#g【劝迁】"); } }, }, }, }, - twrouke:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter' + twrouke: { + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - if(evt&&evt.player==player) return false; - return event.getg(player).length>1; + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + if (evt && evt.player == player) return false; + return event.getg(player).length > 1; }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, }, //张昭 - twlijian:{ - getCards:function(event){ - var cards=[]; - game.countPlayer2(function(current){ - current.checkHistory('lose',function(evt){ - if(evt.position==ui.discardPile&&evt.getParent('phaseDiscard')==event) cards.addArray(evt.cards); - }) + twlijian: { + getCards: function (event) { + var cards = []; + game.countPlayer2(function (current) { + current.checkHistory("lose", function (evt) { + if (evt.position == ui.discardPile && evt.getParent("phaseDiscard") == event) + cards.addArray(evt.cards); + }); }); - game.checkGlobalHistory('cardMove',function(evt){ - if(evt.name=='cardsDiscard'&&evt.getParent('phaseDiscard')==event) cards.addArray(evt.cards); + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name == "cardsDiscard" && evt.getParent("phaseDiscard") == event) + cards.addArray(evt.cards); }); - return cards.filterInD('d'); + return cards.filterInD("d"); }, - audio:2, - sunbenSkill:true, - trigger:{global:'phaseDiscardEnd'}, - filter:function(event,player){ - if(player.hasSkill('twlijian_sunben')) return false; - if(event.player!=player&&event.player.isIn()){ + audio: 2, + sunbenSkill: true, + trigger: { global: "phaseDiscardEnd" }, + filter: function (event, player) { + if (player.hasSkill("twlijian_sunben")) return false; + if (event.player != player && event.player.isIn()) { return lib.skill.twlijian.getCards(event).length; } return false; }, - prompt2:()=>'选择任意张本阶段进入弃牌堆的牌令其获得,然后你获得剩余的牌,若其获得的牌数大于你,则你可以对其造成1点伤害', - logTarget:'player', - content:function(){ - 'step 0' - player.addSkill('twlijian_sunben'); - var cards=lib.skill.twlijian.getCards(trigger),target=trigger.player; - event.cards=cards;event.target=target; - player.chooseToMove('力荐:请分配'+get.translation(target)+'和你获得的牌',true).set('list',[ - [get.translation(target)+'获得的牌',cards], - ['你获得的牌'], - ]).set('processAI',function(list){ - var player=_status.event.player; - var target=_status.event.getTrigger().player; - var att=get.attitude(player,target); - var cards=_status.event.cards; - var cardx=cards.filter(card=>card.name=='du'); - var cardy=cards.removeArray(cardx); - switch(get.sgn(att)){ - case 1: - return [cards,[]]; - case 0: - return [cardx,cardy]; - case -1: - var num=Math.ceil(cards.length/2)+(cards.length%2==0?1:0); - if(num>1&&player.hasSkill('twchungang')) num--; - if(get.damageEffect(target,player,player)<=0||num>2||cardx.length>cardy.length) return [cardx,cardy]; - var num2=cardy.length-cardx.length; - num2=Math.ceil(num2/2)+(num2%2==0?1:0); - cardy.sort((a,b)=>get.value(b)-get.value(a)); - cardx.addArray(cardy.slice(num,cardy.length)); - return [cardx,cardy.slice(0,num)]; - } - }).set('cards',cards); - 'step 1' - if(result.bool){ - target.gain(result.moved[0],'gain2'); - player.gain(result.moved[1],'gain2'); - if(result.moved[0].length>result.moved[1].length){ - player.chooseBool('是否对'+get.translation(target)+'造成1点伤害?').set('choice',get.damageEffect(target,player,player)>0); - } - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ + prompt2: () => + "选择任意张本阶段进入弃牌堆的牌令其获得,然后你获得剩余的牌,若其获得的牌数大于你,则你可以对其造成1点伤害", + logTarget: "player", + content: function () { + "step 0"; + player.addSkill("twlijian_sunben"); + var cards = lib.skill.twlijian.getCards(trigger), + target = trigger.player; + event.cards = cards; + event.target = target; + player + .chooseToMove("力荐:请分配" + get.translation(target) + "和你获得的牌", true) + .set("list", [[get.translation(target) + "获得的牌", cards], ["你获得的牌"]]) + .set("processAI", function (list) { + var player = _status.event.player; + var target = _status.event.getTrigger().player; + var att = get.attitude(player, target); + var cards = _status.event.cards; + var cardx = cards.filter((card) => card.name == "du"); + var cardy = cards.removeArray(cardx); + switch (get.sgn(att)) { + case 1: + return [cards, []]; + case 0: + return [cardx, cardy]; + case -1: + var num = Math.ceil(cards.length / 2) + (cards.length % 2 == 0 ? 1 : 0); + if (num > 1 && player.hasSkill("twchungang")) num--; + if ( + get.damageEffect(target, player, player) <= 0 || + num > 2 || + cardx.length > cardy.length + ) + return [cardx, cardy]; + var num2 = cardy.length - cardx.length; + num2 = Math.ceil(num2 / 2) + (num2 % 2 == 0 ? 1 : 0); + cardy.sort((a, b) => get.value(b) - get.value(a)); + cardx.addArray(cardy.slice(num, cardy.length)); + return [cardx, cardy.slice(0, num)]; + } + }) + .set("cards", cards); + "step 1"; + if (result.bool) { + target.gain(result.moved[0], "gain2"); + player.gain(result.moved[1], "gain2"); + if (result.moved[0].length > result.moved[1].length) { + player + .chooseBool("是否对" + get.translation(target) + "造成1点伤害?") + .set("choice", get.damageEffect(target, player, player) > 0); + } else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { player.line(target); target.damage(); } }, - subSkill:{ - sunben:{ - charlotte:true, - init:function(player){ - player.storage.twlijian_sunben=0; + subSkill: { + sunben: { + charlotte: true, + init: function (player) { + player.storage.twlijian_sunben = 0; }, - onremove:true, - mark:true, - intro:{ - markcount:function(num){ - return (num||0).toString(); + onremove: true, + mark: true, + intro: { + markcount: function (num) { + return (num || 0).toString(); }, - content:'弃牌堆进入牌进度:#/8', + content: "弃牌堆进入牌进度:#/8", }, - trigger:{global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter']}, - filter:function(event,player){ - var cards=event.getd(); - if(!cards.length) return false; - var list=cards.slice(); - game.checkGlobalHistory('cardMove',function(evt){ - if(evt==event||evt.getParent()==event||(evt.name!='lose'&&evt.name!='cardsDiscard')) return false; - if(evt.name=='lose'&&evt.position!=ui.discardPile) return false; - list.removeArray(evt.cards); - },event); - return list.length>0; + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - 'step 0' - var cards=trigger.getd().slice(); - game.checkGlobalHistory('cardMove',function(evt){ - if(evt==trigger||evt.getParent()==trigger||(evt.name!='lose'&&evt.name!='cardsDiscard')) return false; - if(evt.name=='lose'&&evt.position!=ui.discardPile) return false; - cards.removeArray(evt.cards); - },trigger); - player.addMark('twlijian_sunben',cards.length,false); - 'step 1' - if(player.countMark('twlijian_sunben')>=8){ - player.removeSkill('twlijian_sunben'); - player.popup('力荐'); - game.log(player,'恢复了技能','#g【力荐】'); + filter: function (event, player) { + var cards = event.getd(); + if (!cards.length) return false; + var list = cards.slice(); + game.checkGlobalHistory( + "cardMove", + function (evt) { + if ( + evt == event || + evt.getParent() == event || + (evt.name != "lose" && evt.name != "cardsDiscard") + ) + return false; + if (evt.name == "lose" && evt.position != ui.discardPile) return false; + list.removeArray(evt.cards); + }, + event + ); + return list.length > 0; + }, + forced: true, + popup: false, + firstDo: true, + content: function () { + "step 0"; + var cards = trigger.getd().slice(); + game.checkGlobalHistory( + "cardMove", + function (evt) { + if ( + evt == trigger || + evt.getParent() == trigger || + (evt.name != "lose" && evt.name != "cardsDiscard") + ) + return false; + if (evt.name == "lose" && evt.position != ui.discardPile) return false; + cards.removeArray(evt.cards); + }, + trigger + ); + player.addMark("twlijian_sunben", cards.length, false); + "step 1"; + if (player.countMark("twlijian_sunben") >= 8) { + player.removeSkill("twlijian_sunben"); + player.popup("力荐"); + game.log(player, "恢复了技能", "#g【力荐】"); } }, }, }, }, - twchungang:{ - audio:2, - init: ()=>{ - game.addGlobalSkill('twchungang_global'); + twchungang: { + audio: 2, + init: () => { + game.addGlobalSkill("twchungang_global"); }, - onremove: player => { - if (!game.hasPlayer(i => { - return player !== i && i.hasSkill('twchungang'); - }, true)) game.removeGlobalSkill('twchungang_global'); + onremove: (player) => { + if ( + !game.hasPlayer((i) => { + return player !== i && i.hasSkill("twchungang"); + }, true) + ) + game.removeGlobalSkill("twchungang_global"); }, - trigger:{global:['gainAfter','loseAsyncAfter']}, - filter:function(event,player){ - var evt=event.getParent('phaseDraw'); - return game.hasPlayer(target=>{ - if(target==player||(evt&&evt.player==target)) return false; - return event.getg(target).length>1&&target.countCards('he'); + trigger: { global: ["gainAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + var evt = event.getParent("phaseDraw"); + return game.hasPlayer((target) => { + if (target == player || (evt && evt.player == target)) return false; + return event.getg(target).length > 1 && target.countCards("he"); }); }, - forced:true, - logTarget:function(event,player){ - var evt=event.getParent('phaseDraw'); - return game.filterPlayer(target=>{ - if(target==player||evt&&evt.player==target) return false; - return event.getg(target).length>1&&target.countCards('he'); + forced: true, + logTarget: function (event, player) { + var evt = event.getParent("phaseDraw"); + return game.filterPlayer((target) => { + if (target == player || (evt && evt.player == target)) return false; + return event.getg(target).length > 1 && target.countCards("he"); }); }, - content:function(){ - for(var i of lib.skill.twchungang.logTarget(trigger,player)){ - i.chooseToDiscard('he',true); + content: function () { + for (var i of lib.skill.twchungang.logTarget(trigger, player)) { + i.chooseToDiscard("he", true); } }, subSkill: { global: { trigger: { - player: 'dieAfter' + player: "dieAfter", }, filter(event, player) { - return !game.hasPlayer(i => i.hasSkill('twchungang'), true) + return !game.hasPlayer((i) => i.hasSkill("twchungang"), true); }, silent: true, forceDie: true, charlotte: true, content() { - game.removeGlobalSkill('twchungang_global'); + game.removeGlobalSkill("twchungang_global"); }, ai: { effect: { target(card, player, target) { - if ((get.tag(card, 'gain') || 0) < 2 && (get.tag(card, 'draw') || 0) < 2) return; - let evt = _status.event.getParent('phaseDraw'), dis = game.countPlayer(i => { - return target !== i && i.hasSkill('twchungang'); - }); - if (!dis || evt && evt.player === target) return; + if ((get.tag(card, "gain") || 0) < 2 && (get.tag(card, "draw") || 0) < 2) + return; + let evt = _status.event.getParent("phaseDraw"), + dis = game.countPlayer((i) => { + return target !== i && i.hasSkill("twchungang"); + }); + if (!dis || (evt && evt.player === target)) return; return [1, -dis]; - } - } - } - } - } + }, + }, + }, + }, + }, }, //海外主公技 //张鲁 twshijun: { unique: true, - global: 'twshijun_global', + global: "twshijun_global", audio: 2, zhuSkill: true, - ai: { combo: 'yishe' }, + ai: { combo: "yishe" }, subSkill: { global: { - audio: 'twshijun', + audio: "twshijun", usable: 1, - enable: 'phaseUse', + enable: "phaseUse", forceaudio: true, filter: function (event, player) { - return player.group == 'qun' && game.hasPlayer(function (current) { - return current != player && current.hasZhuSkill('twshijun', player) && !current.getExpansions('yishe').length; - }); + return ( + player.group == "qun" && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasZhuSkill("twshijun", player) && + !current.getExpansions("yishe").length + ); + }) + ); }, filterTarget: function (card, player, target) { - return target != player && target.hasZhuSkill('twshijun', player) && !target.getExpansions('yishe').length; + return ( + target != player && + target.hasZhuSkill("twshijun", player) && + !target.getExpansions("yishe").length + ); }, - prompt: '摸一张牌然后将一张牌作为“米”置于主公的武将牌上', + prompt: "摸一张牌然后将一张牌作为“米”置于主公的武将牌上", content: function () { - 'step 0' + "step 0"; player.draw(); - if (player.countCards('he')) player.chooseCard('将一张牌置于' + get.translation(target) + '的武将牌上', 'he', true); + if (player.countCards("he")) + player.chooseCard( + "将一张牌置于" + get.translation(target) + "的武将牌上", + "he", + true + ); else event.finish(); - 'step 1' - if (result.bool) target.addToExpansion(result.cards, player, 'give').gaintag.add('yishe'); + "step 1"; + if (result.bool) + target.addToExpansion(result.cards, player, "give").gaintag.add("yishe"); }, ai: { order: 7, @@ -2478,38 +3334,55 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //张绣 twjuxiang: { unique: true, - global: 'twjuxiang_global', + global: "twjuxiang_global", audio: 2, zhuSkill: true, subSkill: { global: { - audio: 'twjuxiang', + audio: "twjuxiang", usable: 1, - enable: 'phaseUse', + enable: "phaseUse", forceaudio: true, filter: function (event, player) { - return player.countCards('e') && player.group == 'qun' && game.hasPlayer(function (target) { - return target != player && target.hasZhuSkill('twjuxiang', player) && player.countCards('e',card=>target.hasEmptySlot(get.subtype(card))||target.hasDisabledSlot(get.subtype(card))); - }); + return ( + player.countCards("e") && + player.group == "qun" && + game.hasPlayer(function (target) { + return ( + target != player && + target.hasZhuSkill("twjuxiang", player) && + player.countCards( + "e", + (card) => + target.hasEmptySlot(get.subtype(card)) || + target.hasDisabledSlot(get.subtype(card)) + ) + ); + }) + ); }, filterTarget: function (card, player, target) { - return target != player && target.hasZhuSkill('twjuxiang', player) && (target.hasEmptySlot(get.subtype(ui.selected.cards[0]))||target.hasDisabledSlot(get.subtype(ui.selected.cards[0]))); + return ( + target != player && + target.hasZhuSkill("twjuxiang", player) && + (target.hasEmptySlot(get.subtype(ui.selected.cards[0])) || + target.hasDisabledSlot(get.subtype(ui.selected.cards[0]))) + ); }, - filterCard: { type: 'equip' }, - position: 'e', + filterCard: { type: "equip" }, + position: "e", check: function (card) { return get.value(card); }, - prompt: '将装备区中的一张牌置入主公的装备区中或恢复主公的对应装备栏', + prompt: "将装备区中的一张牌置入主公的装备区中或恢复主公的对应装备栏", discard: false, lose: false, content: function () { if (target.hasEmptySlot(get.subtype(cards[0]))) { player.$give(cards[0], target, false); target.equip(cards[0]); - } - else { - target.gain(cards[0], player, 'give'); + } else { + target.gain(cards[0], player, "give"); target.enableEquip(get.subtype(cards[0])); } }, @@ -2525,33 +3398,38 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //孙坚 twpolu: { unique: true, - audio: 'repolu', - trigger: { global: ['dieAfter', 'die'] }, + audio: "repolu", + trigger: { global: ["dieAfter", "die"] }, forceDie: true, zhuSkill: true, filter: function (event, player, name) { - if (!player.hasZhuSkill('twpolu')) return false; - if (name == 'dieAfter' && event.source && event.source.group == 'wu') return true; - if (name == 'die' && event.player.group == 'wu') return true; + if (!player.hasZhuSkill("twpolu")) return false; + if (name == "dieAfter" && event.source && event.source.group == "wu") return true; + if (name == "die" && event.player.group == "wu") return true; return false; }, direct: true, content: function () { - 'step 0' + "step 0"; if (!player.storage.twpolu) player.storage.twpolu = 0; event.num = player.storage.twpolu + 1; - player.chooseTarget([1, Infinity], get.prompt('twpolu'), '令任意名角色摸' + get.cnNumber(event.num) + '张牌').set('forceDie', true).ai = function (target) { + player + .chooseTarget( + [1, Infinity], + get.prompt("twpolu"), + "令任意名角色摸" + get.cnNumber(event.num) + "张牌" + ) + .set("forceDie", true).ai = function (target) { return get.attitude(_status.event.player, target); }; - 'step 1' + "step 1"; if (result.bool) { player.storage.twpolu++; result.targets.sortBySeat(); - player.logSkill('repolu', result.targets); + player.logSkill("repolu", result.targets); game.asyncDraw(result.targets, num); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; game.delay(); }, }, @@ -2559,179 +3437,203 @@ game.import('character',function(lib,game,ui,get,ai,_status){ twqiushou: { unique: true, audio: 2, - trigger: { global: 'useCardAfter' }, + trigger: { global: "useCardAfter" }, filter: function (event, player) { - if (event.card.name != 'nanman') return false; - var num = 0, bool = false; + if (event.card.name != "nanman") return false; + var num = 0, + bool = false; for (var i of event.targets) { if (!i.isAlive()) bool = true; - i.getHistory('damage', function (evt) { + i.getHistory("damage", function (evt) { if (evt.getParent(2) == event) num += evt.num; }); } - return player.hasZhuSkill('twqiushou') && (bool || num > 3); + return player.hasZhuSkill("twqiushou") && (bool || num > 3); }, zhuSkill: true, forced: true, logTarget: function (event, player) { return game.filterPlayer(function (target) { - return ['shu', 'qun'].includes(target.group); + return ["shu", "qun"].includes(target.group); }); }, content: function () { - 'step 0' + "step 0"; game.asyncDraw(lib.skill.twqiushou.logTarget(trigger.player)); - 'step 1' + "step 1"; game.delayx(); }, }, //刘协 - twzhuiting:{ - unique:true, - zhuSkill:true, - audio:2, - global:'twzhuiting_global', - subSkill:{ - global:{ - hiddenWuxie:function(player,info){ - if(player.group!='wei'&&player.group!='qun') return false; - const target=info.target,card=info.card; - if(!target||target==player||!target.hasZhuSkill('twzhuiting')) return false; - if(_status.connectMode&&player.countCards('hs')>0) return true; - const color=get.color(card,false); - if(color=='none') return false; - return player.hasCard(card=>get.color(card)==color,'hes'); + twzhuiting: { + unique: true, + zhuSkill: true, + audio: 2, + global: "twzhuiting_global", + subSkill: { + global: { + hiddenWuxie: function (player, info) { + if (player.group != "wei" && player.group != "qun") return false; + const target = info.target, + card = info.card; + if (!target || target == player || !target.hasZhuSkill("twzhuiting")) + return false; + if (_status.connectMode && player.countCards("hs") > 0) return true; + const color = get.color(card, false); + if (color == "none") return false; + return player.hasCard((card) => get.color(card) == color, "hes"); }, - audio:'twzhuiting', - forceaudio:true, - enable:'chooseToUse', - filter:function(event,player){ - if(event.type!='wuxie'||player.group!='wei'&&player.group!='qun') return false; - const info=event.info_map,target=info.target,card=info.card; - if(!target||target==player||!target.hasZhuSkill('twzhuiting')) return false; - const color=get.color(card,false); - if(color=='none') return false; - return player.hasCard(card=>get.color(card)==color,'hes'); + audio: "twzhuiting", + forceaudio: true, + enable: "chooseToUse", + filter: function (event, player) { + if (event.type != "wuxie" || (player.group != "wei" && player.group != "qun")) + return false; + const info = event.info_map, + target = info.target, + card = info.card; + if (!target || target == player || !target.hasZhuSkill("twzhuiting")) + return false; + const color = get.color(card, false); + if (color == "none") return false; + return player.hasCard((card) => get.color(card) == color, "hes"); }, - filterCard:function(card){ - const info=_status.event.info_map; - return info&&get.color(card)==get.color(info.card,false); + filterCard: function (card) { + const info = _status.event.info_map; + return info && get.color(card) == get.color(info.card, false); }, - viewAs:{name:'wuxie'}, - position:'hes', - prompt:function(){ - const info=_status.event.info_map; - return '将一张'+get.translation(get.color(info.card))+'牌当作【无懈可击】对'+get.translation(info.target)+'使用'; + viewAs: { name: "wuxie" }, + position: "hes", + prompt: function () { + const info = _status.event.info_map; + return ( + "将一张" + + get.translation(get.color(info.card)) + + "牌当作【无懈可击】对" + + get.translation(info.target) + + "使用" + ); }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, }, }, }, //刘繇 - twniju:{ - audio:2, - zhuSkill:true, - trigger:{ - global:'compare', + twniju: { + audio: 2, + zhuSkill: true, + trigger: { + global: "compare", }, - priority:1, - filter(event,player){ - if(!player.hasZhuSkill('twniju')) return false; - if(event.iwhile||(event.target&&event.compareMeanwhile)) return false; - const participant=[event.player]; - if(event.targets) participant.addArray(event.targets); + priority: 1, + filter(event, player) { + if (!player.hasZhuSkill("twniju")) return false; + if (event.iwhile || (event.target && event.compareMeanwhile)) return false; + const participant = [event.player]; + if (event.targets) participant.addArray(event.targets); else participant.add(event.target); return participant.includes(player); }, - direct:true, - async content(event,trigger,player){ - const num=game.countPlayer(current=>current.group==='qun'); - const dialog=[ - get.prompt('twniju'), + direct: true, + async content(event, trigger, player) { + const num = game.countPlayer((current) => current.group === "qun"); + const dialog = [ + get.prompt("twniju"), `
              令一张拼点牌的点数+${num}或-${num}
              `, - [[ - ['addNumber','增加'], - ['subtractNumber','减少'] - ],'tdnodes'], + [ + [ + ["addNumber", "增加"], + ["subtractNumber", "减少"], + ], + "tdnodes", + ], ]; - const lose_list=trigger.lose_list.slice().sort((a,b)=>lib.sort.seat(a[0],b[0])); - dialog.push(`
              ${lose_list.map(list=>{ - return get.translation(list[0]); - }).join('  /  ')}
              `); - const cards=lose_list.map(list=>list[1]).flat(); + const lose_list = trigger.lose_list.slice().sort((a, b) => lib.sort.seat(a[0], b[0])); + dialog.push( + `
              ${lose_list + .map((list) => { + return get.translation(list[0]); + }) + .join("  /  ")}
              ` + ); + const cards = lose_list.map((list) => list[1]).flat(); dialog.push(cards); - const result=await player.chooseButton(dialog,2) - .set('filterButton',button=>{ - const type=typeof button.link; - if(ui.selected.buttons.length&&type===typeof ui.selected.buttons[0].link) return false; + const result = await player + .chooseButton(dialog, 2) + .set("filterButton", (button) => { + const type = typeof button.link; + if (ui.selected.buttons.length && type === typeof ui.selected.buttons[0].link) + return false; return true; }) - .forResult() - if(!result.bool) return; - const {links}=result; - if(typeof links[0]!=='string') links.reverse(); - let [fn,card]=links; - const selectedPlayer=lose_list.find(item=>{ - if(Array.isArray(item[1])) return item[1].includes(card); - return item[1]==card; + .forResult(); + if (!result.bool) return; + const { links } = result; + if (typeof links[0] !== "string") links.reverse(); + let [fn, card] = links; + const selectedPlayer = lose_list.find((item) => { + if (Array.isArray(item[1])) return item[1].includes(card); + return item[1] == card; })[0]; - player.logSkill('twniju',selectedPlayer); - selectedPlayer.addTempSkill('twniju_change'); - if(!selectedPlayer.storage.twniju_change) selectedPlayer.storage.twniju_change=[]; - selectedPlayer.storage.twniju_change.push([fn,num,card]); - player.when('chooseToCompareAfter') - .filter(evt=>evt===trigger) + player.logSkill("twniju", selectedPlayer); + selectedPlayer.addTempSkill("twniju_change"); + if (!selectedPlayer.storage.twniju_change) selectedPlayer.storage.twniju_change = []; + selectedPlayer.storage.twniju_change.push([fn, num, card]); + player + .when("chooseToCompareAfter") + .filter((evt) => evt === trigger) .vars({ - toDraw:num, + toDraw: num, }) - .then(()=>{ - const num1=trigger.result.num1,num2=trigger.result.num2; - let bool=false; - if(typeof num1==='number'&&typeof num2==='number'){ - if(num1===num2){ - bool=true; + .then(() => { + const num1 = trigger.result.num1, + num2 = trigger.result.num2; + let bool = false; + if (typeof num1 === "number" && typeof num2 === "number") { + if (num1 === num2) { + bool = true; + } + } else { + const num1List = num1.toUniqued(); + const totalList = num1List.concat(num2).toUniqued(); + if (totalList.length < num1List.length + num2.length) { + bool = true; } } - else{ - const num1List=num1.toUniqued(); - const totalList=num1List.concat(num2).toUniqued(); - if(totalList.length{ - const cards=Array.isArray(list[1])?list[1]:[list[1]]; - return list[0]===player&&storage.some(s=>cards.includes(s[2])); + subSkill: { + change: { + trigger: { global: "compare" }, + filter(event, player) { + const storage = player.getStorage("twniju_change"); + if (!storage.length) return false; + if ((player !== event.player || event.iwhile) && player !== event.target) + return false; + return event.lose_list.some((list) => { + const cards = Array.isArray(list[1]) ? list[1] : [list[1]]; + return list[0] === player && storage.some((s) => cards.includes(s[2])); }); }, - charlotte:true, - forced:true, - silent:true, - async content(event,trigger,player){ - const [fn,num]=player.getStorage('twniju_change').find(s=>{ - return trigger.lose_list.some(list=>{ - const cards=Array.isArray(list[1])?list[1]:[list[1]]; - return list[0]===player&&cards.includes(s[2]); + charlotte: true, + forced: true, + silent: true, + async content(event, trigger, player) { + const [fn, num] = player.getStorage("twniju_change").find((s) => { + return trigger.lose_list.some((list) => { + const cards = Array.isArray(list[1]) ? list[1] : [list[1]]; + return list[0] === player && cards.includes(s[2]); }); }); - const numId=player===trigger.player?'num1':'num2'; - trigger[fn](numId,num); - if(trigger[numId]>13) trigger[numId]=13; - else if(trigger[numId]<1) trigger[numId]=1; - game.log(player,'的拼点牌点数',fn==='addNumber'?'+':'-',num); - } + const numId = player === trigger.player ? "num1" : "num2"; + trigger[fn](numId, num); + if (trigger[numId] > 13) trigger[numId] = 13; + else if (trigger[numId] < 1) trigger[numId] = 1; + game.log(player, "的拼点牌点数", fn === "addNumber" ? "+" : "-", num); + }, }, }, }, @@ -2743,68 +3645,90 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, mod: { playerEnabled: function (card, player, target) { - if (!player.hasZhuSkill('twchongwang')) return; - if (get.tag(card, 'damage') > 0 && player.storage.twchongwangx.includes(target)) return false; + if (!player.hasZhuSkill("twchongwang")) return; + if (get.tag(card, "damage") > 0 && player.storage.twchongwangx.includes(target)) + return false; }, targetEnabled: function (card, player, target) { - if (!target.hasZhuSkill('twchongwang')) return; - if (get.tag(card, 'damage') > 0 && target.storage.twchongwangx.includes(player)) return false; + if (!target.hasZhuSkill("twchongwang")) return; + if (get.tag(card, "damage") > 0 && target.storage.twchongwangx.includes(player)) + return false; }, }, - locked:false, + locked: false, unique: true, onremove: true, - global: 'twchongwang_global', - group: 'twchongwang_clear', + global: "twchongwang_global", + group: "twchongwang_clear", audio: 2, zhuSkill: true, subSkill: { clear: { charlotte: true, - trigger: { player: 'phaseAfter' }, + trigger: { player: "phaseAfter" }, direct: true, content: function () { player.storage.twchongwangx = []; }, }, global: { - trigger: { player: 'phaseUseBegin' }, + trigger: { player: "phaseUseBegin" }, filter: function (event, player) { - return player.group == 'qun' && game.hasPlayer(function (current) { - return current != player && current.hasZhuSkill('twchongwang', player) && !current.storage.twchongwang.includes(player); - }); + return ( + player.group == "qun" && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasZhuSkill("twchongwang", player) && + !current.storage.twchongwang.includes(player) + ); + }) + ); }, direct: true, content: function () { - 'step 0' + "step 0"; player.chooseCardTarget({ - prompt: '崇望:是否将一张牌交给主公并获得双重庇护?', + prompt: "崇望:是否将一张牌交给主公并获得双重庇护?", selectCard: 1, filterCard: true, filterTarget: function (card, player, target) { - return target != player && target.hasZhuSkill('twchongwang', player) && !target.storage.twchongwang.includes(player); + return ( + target != player && + target.hasZhuSkill("twchongwang", player) && + !target.storage.twchongwang.includes(player) + ); }, - position: 'he', + position: "he", ai1: function (card) { - if (card.name == 'du') return 10; - else if (ui.selected.cards.length && ui.selected.cards[0].name == 'du') return 0; + if (card.name == "du") return 10; + else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") + return 0; var player = _status.event.player; - if (ui.selected.cards.length > 4 || !game.hasPlayer(function (current) { - return get.attitude(player, current) > 0 && !current.hasSkillTag('nogain'); - })) return 0; + if ( + ui.selected.cards.length > 4 || + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + return 0; return 1 / Math.max(0.1, get.value(card)); }, ai2: function (target) { - var player = _status.event.player, att = get.attitude(player, target); - if (ui.selected.cards[0].name == 'du') return -att; - if (target.hasSkillTag('nogain')) att /= 6; + var player = _status.event.player, + att = get.attitude(player, target); + if (ui.selected.cards[0].name == "du") return -att; + if (target.hasSkillTag("nogain")) att /= 6; return att; }, }); - 'step 1' + "step 1"; if (result.bool) { - player.logSkill('twchongwang', result.targets[0]); - result.targets[0].gain(result.cards, player, 'giveAuto'); + player.logSkill("twchongwang", result.targets[0]); + result.targets[0].gain(result.cards, player, "giveAuto"); result.targets[0].storage.twchongwang.push(player); result.targets[0].storage.twchongwangx.push(player); } @@ -2813,3345 +3737,4021 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //公孙范 - twhuiyuan:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var type=get.type2(event.card); - return !player.hasHistory('gain',evtx=>{ - if(evtx.getParent('phaseUse')!=evt) return false; - return evtx.cards.some(card=>get.type2(card)==type); + twhuiyuan: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var type = get.type2(event.card); + return !player.hasHistory("gain", (evtx) => { + if (evtx.getParent("phaseUse") != evt) return false; + return evtx.cards.some((card) => get.type2(card) == type); }); }, - direct:true, - content:function(){ - 'step 0' - var prompt2='展示一名角色的一张手牌。若展示牌为'+get.translation(get.type2(trigger.card))+'牌,则你获得之,否则其弃置之并摸一张牌。然后若其在你的攻击范围内,且你不在其攻击范围内,你对其造成1点伤害'; - player.chooseTarget(get.prompt('twhuiyuan'),prompt2,(card,player,target)=>{ - return target.countCards('h'); - }).set('ai',target=>{ - var player=_status.event.player; - var att=get.attitude(player,target); - return -att+(player.inRange(target)&&!target.inRange(player)?get.damageEffect(target,player,player)/3:0); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twhuiyuan',target); - player.choosePlayerCard(target,'h',true,'回援:展示'+get.translation(target)+'一张手牌'); - } - else event.finish(); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - target.showCards([card],get.translation(target)+'【回援】展示'); - if(get.type2(card)==get.type2(trigger.card)){ - if(lib.filter.canBeGained(card,target,player)){ - player.gain(card,target,'giveAuto','bySelf'); + direct: true, + content: function () { + "step 0"; + var prompt2 = + "展示一名角色的一张手牌。若展示牌为" + + get.translation(get.type2(trigger.card)) + + "牌,则你获得之,否则其弃置之并摸一张牌。然后若其在你的攻击范围内,且你不在其攻击范围内,你对其造成1点伤害"; + player + .chooseTarget(get.prompt("twhuiyuan"), prompt2, (card, player, target) => { + return target.countCards("h"); + }) + .set("ai", (target) => { + var player = _status.event.player; + var att = get.attitude(player, target); + return ( + -att + + (player.inRange(target) && !target.inRange(player) + ? get.damageEffect(target, player, player) / 3 + : 0) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twhuiyuan", target); + player.choosePlayerCard( + target, + "h", + true, + "回援:展示" + get.translation(target) + "一张手牌" + ); + } else event.finish(); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + target.showCards([card], get.translation(target) + "【回援】展示"); + if (get.type2(card) == get.type2(trigger.card)) { + if (lib.filter.canBeGained(card, target, player)) { + player.gain(card, target, "giveAuto", "bySelf"); } - } - else{ - if(lib.filter.canBeDiscarded(card,target,player)){ - target.discard(card,'notBySelf'); + } else { + if (lib.filter.canBeDiscarded(card, target, player)) { + target.discard(card, "notBySelf"); target.draw(); } } - } - else event.finish(); - 'step 3' - if(player.inRange(target)&&!target.inRange(player)){ - game.log(player,'触发了','#y搏击','效果'); + } else event.finish(); + "step 3"; + if (player.inRange(target) && !target.inRange(player)) { + game.log(player, "触发了", "#y搏击", "效果"); player.line(target); target.damage(); } }, - ai:{ - expose:0.2, - threaten:3, - } + ai: { + expose: 0.2, + threaten: 3, + }, }, - twshoushou:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + twshoushou: { + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - var cards=event.getg(player); - if(!cards.length) return false; - return game.hasPlayer(current=>{ - return event.getl(current).cards2.length; - })&&game.hasPlayer(current=>{ - return current.inRange(player); - }); + filter: function (event, player) { + var cards = event.getg(player); + if (!cards.length) return false; + return ( + game.hasPlayer((current) => { + return event.getl(current).cards2.length; + }) && + game.hasPlayer((current) => { + return current.inRange(player); + }) + ); }, - forced:true, - locked:false, - group:'twshoushou_damage', - onremove:function(player){ - if(player.countMark('twshoushou_plus')-player.countMark('twshoushou_minus')==0){ - player.removeSkill('twshoushou_distance'); + forced: true, + locked: false, + group: "twshoushou_damage", + onremove: function (player) { + if (player.countMark("twshoushou_plus") - player.countMark("twshoushou_minus") == 0) { + player.removeSkill("twshoushou_distance"); } }, - content:function(){ - player.addSkill('twshoushou_distance'); - player.addMark('twshoushou_plus',1,false); + content: function () { + player.addSkill("twshoushou_distance"); + player.addMark("twshoushou_plus", 1, false); }, - ai:{ - halfneg:true, + ai: { + halfneg: true, }, - subSkill:{ - damage:{ - trigger:{ - player:'damageEnd', - source:'damageSource' + subSkill: { + damage: { + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current!=player&&!current.inRange(player); + filter: function (event, player) { + return game.hasPlayer((current) => { + return current != player && !current.inRange(player); }); }, - forced:true, - locked:false, - content:function(){ - player.addSkill('twshoushou_distance'); - player.addMark('twshoushou_minus',1,false); - } - }, - distance:{ - mark:true, - marktext:'绶', - intro:{ - markcount:function(storage,player){ - return player.countMark('twshoushou_plus')-player.countMark('twshoushou_minus'); - }, - content:function(storage,player){ - var dis=player.countMark('twshoushou_plus')-player.countMark('twshoushou_minus'); - return '其他角色至你的距离'+(dis>=0?'+':'')+dis; - } + forced: true, + locked: false, + content: function () { + player.addSkill("twshoushou_distance"); + player.addMark("twshoushou_minus", 1, false); }, - mod:{ - globalTo:function(from,to,distance){ - return distance+to.countMark('twshoushou_plus')-to.countMark('twshoushou_minus'); - } - } - } - } + }, + distance: { + mark: true, + marktext: "绶", + intro: { + markcount: function (storage, player) { + return ( + player.countMark("twshoushou_plus") - player.countMark("twshoushou_minus") + ); + }, + content: function (storage, player) { + var dis = + player.countMark("twshoushou_plus") - + player.countMark("twshoushou_minus"); + return "其他角色至你的距离" + (dis >= 0 ? "+" : "") + dis; + }, + }, + mod: { + globalTo: function (from, to, distance) { + return ( + distance + + to.countMark("twshoushou_plus") - + to.countMark("twshoushou_minus") + ); + }, + }, + }, + }, }, //严纲 - twzhiqu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - var count=get.cnNumber(game.countPlayer(current=>{ - return get.distance(player,current)<=1; - })); - player.chooseTarget(get.prompt('twzhiqu'),'选择一名其他角色并视为使用牌堆顶'+count+'张牌中的【杀】。若你与其均在对方的攻击范围内,你改为依次对其使用牌堆顶'+count+'张牌中的【杀】或锦囊牌。',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player)*(get.distance(player,target)==1?2:1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twzhiqu',target); - event.fight=player.inRange(target)&&target.inRange(player); - if(event.fight) game.log(player,'触发了','#y搏击','效果'); - event.cards=game.cardsGotoOrdering(get.cards(game.countPlayer(current=>{ - return get.distance(player,current)<=1; - }))).cards.slice(); - } - else event.finish(); - 'step 2' - if(player.isIn()&&target.isIn()&&cards.length){ - do var card=cards.shift(); - while(get.name(card)!='sha'&&(!event.fight||get.type2(card)!='trick')&&cards.length); - if(get.name(card)!='sha'&&(!event.fight||get.type2(card)!='trick')) return; - player.showCards([card],get.translation(player)+'发动了【直取】'); - player.chooseUseTarget(card,true,false,'nodistance').set('filterTarget',function(card,player,target){ - var evt=_status.event; - if(_status.event.name=='chooseTarget') evt=evt.getParent(); - if(target!=player&&target!=evt.twzhiqu_target) return false; - return lib.filter.targetEnabledx(card,player,target); - }).set('twzhiqu_target',target); + twzhiqu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + var count = get.cnNumber( + game.countPlayer((current) => { + return get.distance(player, current) <= 1; + }) + ); + player + .chooseTarget( + get.prompt("twzhiqu"), + "选择一名其他角色并视为使用牌堆顶" + + count + + "张牌中的【杀】。若你与其均在对方的攻击范围内,你改为依次对其使用牌堆顶" + + count + + "张牌中的【杀】或锦囊牌。", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + get.effect(target, { name: "sha" }, player, player) * + (get.distance(player, target) == 1 ? 2 : 1) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twzhiqu", target); + event.fight = player.inRange(target) && target.inRange(player); + if (event.fight) game.log(player, "触发了", "#y搏击", "效果"); + event.cards = game + .cardsGotoOrdering( + get.cards( + game.countPlayer((current) => { + return get.distance(player, current) <= 1; + }) + ) + ) + .cards.slice(); + } else event.finish(); + "step 2"; + if (player.isIn() && target.isIn() && cards.length) { + do var card = cards.shift(); + while ( + get.name(card) != "sha" && + (!event.fight || get.type2(card) != "trick") && + cards.length + ); + if (get.name(card) != "sha" && (!event.fight || get.type2(card) != "trick")) return; + player.showCards([card], get.translation(player) + "发动了【直取】"); + player + .chooseUseTarget(card, true, false, "nodistance") + .set("filterTarget", function (card, player, target) { + var evt = _status.event; + if (_status.event.name == "chooseTarget") evt = evt.getParent(); + if (target != player && target != evt.twzhiqu_target) return false; + return lib.filter.targetEnabledx(card, player, target); + }) + .set("twzhiqu_target", target); event.redo(); } - } - }, - twxianfeng:{ - audio:2, - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(!player.isPhaseUsing()) return false; - if(player==event.player) return false; - if(!event.player.isIn()) return false; - if(!event.card) return false; - return event.card.name=='sha'||get.type(event.card)=='trick'&&get.tag(event.card,'damage'); }, - logTarget:'player', - check:function(event,player){ - 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; + }, + twxianfeng: { + audio: 2, + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (!player.isPhaseUsing()) return false; + if (player == event.player) return false; + if (!event.player.isIn()) return false; + if (!event.card) return false; + return ( + event.card.name == "sha" || + (get.type(event.card) == "trick" && get.tag(event.card, "damage")) + ); + }, + logTarget: "player", + check: function (event, player) { + 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' - var target=trigger.player; - event.target=target; - target.chooseControl().set('choiceList',[ - '你摸一张牌,然后直到'+get.translation(player)+'下个回合开始时,其至其他角色的距离-1', - get.translation(player)+'摸一张牌,然后直到其下个回合开始时,你至其的距离-1', - ]).set('prompt','先锋:请选择一项').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var att=get.attitude(target,player); - if(att===0) return 0; - if(player.hasSkill('twzhiqu')){ - var cnt=game.countPlayer(current=>get.distance(player,current)===2); - if(att>0){ - if(cnt||player.needsToDiscard(1)) return 0; - return 1; - } - if(!cnt) return 0; - if(cnt>=2||get.distance(target,player,'attack')===2||get.distance(target,player)===2) return 1; - return 0; - } - 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){ + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + target + .chooseControl() + .set("choiceList", [ + "你摸一张牌,然后直到" + + get.translation(player) + + "下个回合开始时,其至其他角色的距离-1", + get.translation(player) + "摸一张牌,然后直到其下个回合开始时,你至其的距离-1", + ]) + .set("prompt", "先锋:请选择一项") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var att = get.attitude(target, player); + if (att === 0) return 0; + if (player.hasSkill("twzhiqu")) { + var cnt = game.countPlayer( + (current) => get.distance(player, current) === 2 + ); + if (att > 0) { + if (cnt || player.needsToDiscard(1)) return 0; + return 1; + } + if (!cnt) return 0; + if ( + cnt >= 2 || + get.distance(target, player, "attack") === 2 || + get.distance(target, player) === 2 + ) + return 1; + return 0; + } + if ( + att < 0 || + (player.needsToDiscard(1) && + game.hasPlayer(function (current) { + return ( + current !== player && + current !== target && + !player.inRange(current) + ); + })) + ) + return 0; + return [0, 1].randomGet(); + })() + ); + "step 1"; + if (result.index == 0) { target.draw(); - player.addTempSkill('twxianfeng_me',{player:'phaseBegin'}); - player.addMark('twxianfeng_me',1,false); - } - else{ + player.addTempSkill("twxianfeng_me", { player: "phaseBegin" }); + player.addMark("twxianfeng_me", 1, false); + } else { player.draw(); - target.addSkill('twxianfeng_others'); - if(!target.storage.twxianfeng_others) target.storage.twxianfeng_others={}; - if(typeof target.storage.twxianfeng_others[player.playerid]!='number') target.storage.twxianfeng_others[player.playerid]=0; + target.addSkill("twxianfeng_others"); + if (!target.storage.twxianfeng_others) target.storage.twxianfeng_others = {}; + if (typeof target.storage.twxianfeng_others[player.playerid] != "number") + target.storage.twxianfeng_others[player.playerid] = 0; target.storage.twxianfeng_others[player.playerid]++; } }, - subSkill:{ - me:{ - charlotte:true, - mark:true, - intro:{content:'至其他角色的距离-#'}, - mod:{ - globalFrom:function(from,to,distance){ - return distance-from.countMark('twxianfeng_me'); - } - } - }, - others:{ - trigger:{global:['phaseBegin','die']}, - filter:function(event,player){ - return player.storage.twxianfeng_others&&player.storage.twxianfeng_others[event.player.playerid]; + subSkill: { + me: { + charlotte: true, + mark: true, + intro: { content: "至其他角色的距离-#" }, + mod: { + globalFrom: function (from, to, distance) { + return distance - from.countMark("twxianfeng_me"); + }, }, - charlotte:true, - mark:true, - forced:true, - intro:{ - markcount:function(storage,player){ - var max=0; - for(var id in storage){ - if(storage[id]>max) max=storage[id]; + }, + others: { + trigger: { global: ["phaseBegin", "die"] }, + filter: function (event, player) { + return ( + player.storage.twxianfeng_others && + player.storage.twxianfeng_others[event.player.playerid] + ); + }, + charlotte: true, + mark: true, + forced: true, + intro: { + markcount: function (storage, player) { + var max = 0; + for (var id in storage) { + if (storage[id] > max) max = storage[id]; } return max; }, - content:function(storage,player){ - if(!storage) return ''; - var str=''; - var map=(_status.connectMode?lib.playerOL:game.playerMap); - for(var id in storage){ - str+='至'+get.translation(map[id])+'的距离-'+storage[id]+'、'; + content: function (storage, player) { + if (!storage) return ""; + var str = ""; + var map = _status.connectMode ? lib.playerOL : game.playerMap; + for (var id in storage) { + str += "至" + get.translation(map[id]) + "的距离-" + storage[id] + "、"; } - return str.slice(0,-1); + return str.slice(0, -1); }, }, - content:function(){ + content: function () { delete player.storage.twxianfeng_others[trigger.player.playerid]; - if(get.is.empty(player.storage.twxianfeng_others)) player.removeSkill('twxianfeng_others'); + if (get.is.empty(player.storage.twxianfeng_others)) + player.removeSkill("twxianfeng_others"); + }, + mod: { + globalFrom: function (from, to, distance) { + if ( + from.storage.twxianfeng_others && + typeof from.storage.twxianfeng_others[to.playerid] == "number" + ) + return distance - from.storage.twxianfeng_others[to.playerid]; + }, }, - mod:{ - globalFrom:function(from,to,distance){ - if(from.storage.twxianfeng_others&&typeof from.storage.twxianfeng_others[to.playerid]=='number') return distance-from.storage.twxianfeng_others[to.playerid]; - } - } }, - } + }, }, //夏侯紫萼 - twxuechang:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + twxuechang: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - if(!target.countGainableCards(player,'he')) event.finish(); - else player.gainPlayerCard(target,'he',true); - } - else{ + "step 1"; + if (result.bool) { + if (!target.countGainableCards(player, "he")) event.finish(); + else player.gainPlayerCard(target, "he", true); + } else { player.damage(target); - player.addSkill('twxuechang_add'); - if(!player.storage.twxuechang_add) player.storage.twxuechang_add={}; - if(!player.storage.twxuechang_add[target.playerid]) player.storage.twxuechang_add[target.playerid]=0; + player.addSkill("twxuechang_add"); + if (!player.storage.twxuechang_add) player.storage.twxuechang_add = {}; + if (!player.storage.twxuechang_add[target.playerid]) + player.storage.twxuechang_add[target.playerid] = 0; player.storage.twxuechang_add[target.playerid]++; - player.markSkill('twxuechang_add'); + player.markSkill("twxuechang_add"); event.finish(); } - 'step 2' - var card=result.cards[0]; - if(get.type(card)=='equip'){ - var card={name:'sha',isCard:true}; - if(player.canUse(card,target,false)) player.useCard(card,target,'noai',false); + "step 2"; + var card = result.cards[0]; + if (get.type(card) == "equip") { + var card = { name: "sha", isCard: true }; + if (player.canUse(card, target, false)) player.useCard(card, target, "noai", false); } }, - ai:{ - order:6.5, - result:{ - target:function(player,target){ - var hs=player.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + ai: { + order: 6.5, + result: { + target: function (player, target) { + var hs = player.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - var ts=target.getCards('h').sort(function(a,b){ - return get.number(b)-get.number(a); + var ts = target.getCards("h").sort(function (a, b) { + return get.number(b) - get.number(a); }); - if(!hs.length||!ts.length) return 0; - if(get.number(hs[0])>get.number(ts[0])||get.number(hs[0])-ts.length>=(9+Math.min(2,player.hp/2))) return get.sgnAttitude(player,target)*get.effect(target,{name:'shunshou_copy2'},player,player); + if (!hs.length || !ts.length) return 0; + if ( + get.number(hs[0]) > get.number(ts[0]) || + get.number(hs[0]) - ts.length >= 9 + Math.min(2, player.hp / 2) + ) + return ( + get.sgnAttitude(player, target) * + get.effect(target, { name: "shunshou_copy2" }, player, player) + ); return 0; - } - } + }, + }, }, - subSkill:{ - add:{ - audio:'twxuechang', - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return player.storage.twxuechang_add&&player.storage.twxuechang_add[event.player.playerid]; + subSkill: { + add: { + audio: "twxuechang", + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + player.storage.twxuechang_add && + player.storage.twxuechang_add[event.player.playerid] + ); }, - forced:true, - charlotte:true, - content:function(){ - trigger.num+=player.storage.twxuechang_add[trigger.player.playerid]; + forced: true, + charlotte: true, + content: function () { + trigger.num += player.storage.twxuechang_add[trigger.player.playerid]; delete player.storage.twxuechang_add[trigger.player.playerid]; - if(get.is.empty(player.storage.twxuechang_add)) player.removeSkill('twxuechang_add'); - else player.markSkill('twxuechang_add'); + if (get.is.empty(player.storage.twxuechang_add)) + player.removeSkill("twxuechang_add"); + else player.markSkill("twxuechang_add"); }, - marktext:'偿', - intro:{ - content:function(storage,player){ - if(!storage) return ''; - var str=''; - var map=(_status.connectMode?lib.playerOL:game.playerMap); - for(var i in storage){ - str+='
            • 下次对'+get.translation(map[i])+'造成的伤害+'+storage[i]; + marktext: "偿", + intro: { + content: function (storage, player) { + if (!storage) return ""; + var str = ""; + var map = _status.connectMode ? lib.playerOL : game.playerMap; + for (var i in storage) { + str += + "
            • 下次对" + get.translation(map[i]) + "造成的伤害+" + storage[i]; } return str; - } - } - } - } + }, + }, + }, + }, }, - twduoren:{ - audio:2, - trigger:{source:'dieAfter'}, - check:function(event,player){ - if(player.hp<3&&!player.isDamaged()) return false; - var skills=event.player.getSkills(null,false,false).filter(skill=>{ - if(player.hasSkill(skill,null,false,false)) return false; - var info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; + twduoren: { + audio: 2, + trigger: { source: "dieAfter" }, + check: function (event, player) { + if (player.hp < 3 && !player.isDamaged()) return false; + var skills = event.player.getSkills(null, false, false).filter((skill) => { + if (player.hasSkill(skill, null, false, false)) return false; + var info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }); - return skills.length>0; + return skills.length > 0; }, - group:'twduoren_remove', - prompt2:function(event,player){ - var skills=event.player.getSkills(null,false,false).filter(skill=>{ - if(player.hasSkill(skill,null,false,false)) return false; - var info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; + group: "twduoren_remove", + prompt2: function (event, player) { + var skills = event.player.getSkills(null, false, false).filter((skill) => { + if (player.hasSkill(skill, null, false, false)) return false; + var info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }); - var str=''; - for(var i of skills){ - str+='〖'+get.translation(i)+'〗、'; + var str = ""; + for (var i of skills) { + str += "〖" + get.translation(i) + "〗、"; } - str=str.slice(0,str.length-1); - return '减1点体力上限,然后'+(str.length?'获得'+str:'听一句技能配音'); + str = str.slice(0, str.length - 1); + return "减1点体力上限,然后" + (str.length ? "获得" + str : "听一句技能配音"); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' - var skills=trigger.player.getSkills(null,false,false).filter(skill=>{ - if(player.hasSkill(skill,null,false,false)) return false; - var info=get.info(skill); - return info&&!info.hiddenSkill&&!info.zhuSkill&&!info.charlotte; + "step 1"; + var skills = trigger.player.getSkills(null, false, false).filter((skill) => { + if (player.hasSkill(skill, null, false, false)) return false; + var info = get.info(skill); + return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }); - if(skills.length){ + if (skills.length) { //for(var i of skills) player.addSkillLog(i); player.addSkills(skills); - player.markAuto('twduoren',skills); - game.broadcastAll(function(list){ + player.markAuto("twduoren", skills); + game.broadcastAll(function (list) { game.expandSkills(list); - for(var i of list){ - var info=lib.skill[i]; - if(!info) continue; - if(!info.audioname2) info.audioname2={}; - info.audioname2.xia_xiahouzie='twduoren'; + for (var i of list) { + var info = lib.skill[i]; + if (!info) continue; + if (!info.audioname2) info.audioname2 = {}; + info.audioname2.xia_xiahouzie = "twduoren"; } - },skills); + }, skills); } }, - subSkill:{ - remove:{ - trigger:{source:'dying'}, - filter:function(event,player){ - return event.player!=player&&player.getStorage('twduoren').some(skill=>{ - return player.hasSkill(skill,null,false,false); - }); + subSkill: { + remove: { + trigger: { source: "dying" }, + filter: function (event, player) { + return ( + event.player != player && + player.getStorage("twduoren").some((skill) => { + return player.hasSkill(skill, null, false, false); + }) + ); }, - forced:true, - locked:false, - content:function(){ - player.removeSkills(player.getStorage('twduoren')); + forced: true, + locked: false, + content: function () { + player.removeSkills(player.getStorage("twduoren")); delete player.storage.twduoren; - } - } - } + }, + }, + }, }, //赵娥 - twyanshi:{ - audio:2, - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - locked:false, - direct:true, - onremove:true, - intro:{ - content:'players' + twyanshi: { + audio: 2, + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + 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); + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - group:['twyanshi_hurt','twyanshi_damage'], - content:function(){ - 'step 0' - player.chooseTarget('言誓:选择一名其他角色',lib.filter.notMe,true).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twyanshi',target); - player.markAuto('twyanshi',[target]); + group: ["twyanshi_hurt", "twyanshi_damage"], + content: function () { + "step 0"; + player + .chooseTarget("言誓:选择一名其他角色", lib.filter.notMe, true) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twyanshi", target); + player.markAuto("twyanshi", [target]); } }, - mod:{ - targetInRange:function(card,player,target){ - if(target.hasMark('twyanshi_mark')) return true; + mod: { + targetInRange: function (card, player, target) { + if (target.hasMark("twyanshi_mark")) return true; }, }, - subSkill:{ - hurt:{ - audio:'twyanshi', - trigger:{ - global:'damageEnd', + subSkill: { + hurt: { + audio: "twyanshi", + trigger: { + global: "damageEnd", }, - forced:true, - locked:false, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - return player==event.player&&!player.getStorage('twyanshi').includes(event.source)||player!=event.source&&player.getStorage('twyanshi').includes(event.player); + forced: true, + locked: false, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + return ( + (player == event.player && + !player.getStorage("twyanshi").includes(event.source)) || + (player != event.source && + player.getStorage("twyanshi").includes(event.player)) + ); + }, + content: function () { + trigger.source.addMark("twyanshi_mark", 1); }, - content:function(){ - trigger.source.addMark('twyanshi_mark',1); - } }, - damage:{ - audio:'twyanshi', - trigger:{ - source:['damageBegin1','damageSource'], + damage: { + audio: "twyanshi", + trigger: { + source: ["damageBegin1", "damageSource"], }, - forced:true, - locked:false, - filter:function(event,player){ - return event.player.hasMark('twyanshi_mark'); + forced: true, + locked: false, + filter: function (event, player) { + return event.player.hasMark("twyanshi_mark"); }, - content:function(){ - 'step 0' - if(event.triggername=='damageBegin1'){ + content: function () { + "step 0"; + if (event.triggername == "damageBegin1") { trigger.num++; - } - else{ + } else { player.draw(trigger.num); - trigger.player.removeMark('twyanshi_mark',trigger.player.countMark('twyanshi_mark')); + trigger.player.removeMark( + "twyanshi_mark", + trigger.player.countMark("twyanshi_mark") + ); } - } - }, - mark:{ - marktext:'誓', - intro:{ - name:'誓', - name2:'誓', - content:'mark' }, - } - } + }, + mark: { + marktext: "誓", + intro: { + name: "誓", + name2: "誓", + content: "mark", + }, + }, + }, }, - twrenchou:{ - audio:2, - trigger:{global:'die'}, - forced:true, - forceDie:true, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - if(event.player==player){ - return player.getStorage('twyanshi').some(i=>i.isIn()&&i.hp>0); + twrenchou: { + audio: 2, + trigger: { global: "die" }, + forced: true, + forceDie: true, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + if (event.player == player) { + return player.getStorage("twyanshi").some((i) => i.isIn() && i.hp > 0); } - if(player.getStorage('twyanshi').includes(event.player)){ - return player.isIn()&&player.hp>0; + if (player.getStorage("twyanshi").includes(event.player)) { + return player.isIn() && player.hp > 0; } return false; }, - logTarget:'source', - line:false, - skillAnimation:true, - animationColor:'water', - global:'twrenchou_ai', - content:function(){ - 'step 0' - var avengers=[]; - if(trigger.player==player){ - avengers=player.getStorage('twyanshi').filter(i=>i.isIn()&&i.hp>0); + logTarget: "source", + line: false, + skillAnimation: true, + animationColor: "water", + global: "twrenchou_ai", + content: function () { + "step 0"; + var avengers = []; + if (trigger.player == player) { + avengers = player.getStorage("twyanshi").filter((i) => i.isIn() && i.hp > 0); } - if(player.getStorage('twyanshi').includes(trigger.player)){ - avengers=[player]; + if (player.getStorage("twyanshi").includes(trigger.player)) { + avengers = [player]; } - event.avengers=avengers; - 'step 1' - var avenger=event.avengers.shift(); - avenger.line(trigger.source,'fire'); - trigger.source.damage(avenger,avenger.hp); - 'step 2' - if(event.avengers.length&&trigger.source.isIn()) event.goto(1); + event.avengers = avengers; + "step 1"; + var avenger = event.avengers.shift(); + avenger.line(trigger.source, "fire"); + trigger.source.damage(avenger, avenger.hp); + "step 2"; + if (event.avengers.length && trigger.source.isIn()) event.goto(1); }, - ai:{ - combo:'twyanshi', + ai: { + combo: "twyanshi", }, - subSkill:{ - ai:{ - ai:{ - effect:{ - target:function(card,player,target){ - if(!get.tag(card,'damage')) return; - if(target.hp>1) return; - var num=0; - game.filterPlayer(current=>{ - if(current.getStorage('twyanshi').some(i=>target==i)){ - num+=current.hp; + subSkill: { + ai: { + ai: { + effect: { + target: function (card, player, target) { + if (!get.tag(card, "damage")) return; + if (target.hp > 1) return; + var num = 0; + game.filterPlayer((current) => { + if (current.getStorage("twyanshi").some((i) => target == i)) { + num += current.hp; } }); - var targets=target.getStorage('twyanshi').filter(i=>i.isIn()); - for(var targetx of targets){ - num+=targetx.hp; + var targets = target.getStorage("twyanshi").filter((i) => i.isIn()); + for (var targetx of targets) { + num += targetx.hp; } - if(num>=player.hp) return 0; - if(num>0) return [1,0,0,0.5-1.5*num]; - } - } - } - } - } + if (num >= player.hp) return 0; + if (num > 0) return [1, 0, 0, 0.5 - 1.5 * num]; + }, + }, + }, + }, + }, }, //侠典韦 - twliexi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.countCards('he'); + twliexi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.countCards("he"); }, - direct:true, - content:function(){ - 'step 0' - var list=[[],[]]; - for(var current of game.players){ - if(current==player) continue; - var cards=[]; - var weapon=false; - for(var card of player.getCards('he')){ - if(!lib.filter.cardDiscardable(card,player)) continue; - if(get.subtype(card)=='equip1'&&!ui.selected.cards.some(i=>get.subtype(i)=='equip1')){ - if(16-get.value(card)>0){ + direct: true, + content: function () { + "step 0"; + var list = [[], []]; + for (var current of game.players) { + if (current == player) continue; + var cards = []; + var weapon = false; + for (var card of player.getCards("he")) { + if (!lib.filter.cardDiscardable(card, player)) continue; + if ( + get.subtype(card) == "equip1" && + !ui.selected.cards.some((i) => get.subtype(i) == "equip1") + ) { + if (16 - get.value(card) > 0) { cards.push(card); - weapon=true; + weapon = true; } } - if(7-get.value(card)>0) cards.push(card); + if (7 - get.value(card) > 0) cards.push(card); } - if(cards.length>current.hp){ - var val=0; - for(var card of cards){ - if(get.subtype(card)!='equip1') val+=get.value(card); + if (cards.length > current.hp) { + var val = 0; + for (var card of cards) { + if (get.subtype(card) != "equip1") val += get.value(card); } - if(val<30) list[0].push(current); + if (val < 30) list[0].push(current); } - if(weapon&&player.hp>2||get.damageEffect(player,current,player)>10) list[1].push(current); + if ((weapon && player.hp > 2) || get.damageEffect(player, current, player) > 10) + list[1].push(current); } - list[0].sort((a,b)=>{ - return get.damageEffect(b,player,player)-get.damageEffect(a,player,player); + list[0].sort((a, b) => { + return get.damageEffect(b, player, player) - get.damageEffect(a, player, player); }); player.chooseCardTarget({ - filterCard:lib.filter.cardDiscardable, - selectCard:[1,Infinity], - position:'he', - filterTarget:lib.filter.notMe, - prompt:get.prompt2('twliexi'), - targetsx:[list[0][0],list[1][0]], - ai1:function(card){ - var targetx=_status.event.targetsx[0]; - var hasWeapon=ui.selected.cards.some(i=>get.subtype(i)=='equip1'); - if(!targetx){ - var targetx=_status.event.targetsx[1]; - if(get.subtype(card)=='equip1'&&!hasWeapon) return 30-get.value(card); + filterCard: lib.filter.cardDiscardable, + selectCard: [1, Infinity], + position: "he", + filterTarget: lib.filter.notMe, + prompt: get.prompt2("twliexi"), + targetsx: [list[0][0], list[1][0]], + ai1: function (card) { + var targetx = _status.event.targetsx[0]; + var hasWeapon = ui.selected.cards.some((i) => get.subtype(i) == "equip1"); + if (!targetx) { + var targetx = _status.event.targetsx[1]; + if (get.subtype(card) == "equip1" && !hasWeapon) return 30 - get.value(card); return -get.value(card); } - if(ui.selected.cards.length>targetx.hp) return 0; - if(get.subtype(card)=='equip1'&&!hasWeapon) return 30-get.value(card); - return 7-get.value(card); + if (ui.selected.cards.length > targetx.hp) return 0; + if (get.subtype(card) == "equip1" && !hasWeapon) return 30 - get.value(card); + return 7 - get.value(card); }, - ai2:function(target){ - var targetx=_status.event.targetsx[0]||_status.event.targetsx[1]; - if(targetx==target) return 10; + ai2: function (target) { + var targetx = _status.event.targetsx[0] || _status.event.targetsx[1]; + if (targetx == target) return 10; return 0; }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var cards=result.cards; - player.logSkill('twliexi',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var cards = result.cards; + player.logSkill("twliexi", target); player.discard(cards); - if(cards.length>target.hp) target.damage(); + if (cards.length > target.hp) target.damage(); else player.damage(target); - var goon=false; - for(var card of cards){ - if(get.subtype(card)=='equip1'){ - goon=true; + var goon = false; + for (var card of cards) { + if (get.subtype(card) == "equip1") { + goon = true; break; } } - if(!goon) event.finish(); - } - else event.finish(); - 'step 2' + if (!goon) event.finish(); + } else event.finish(); + "step 2"; game.delayx(); target.damage(); - } + }, }, - twshezhong:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - var damage=player.getHistory('sourceDamage').length; - if(damage){ - player.chooseTarget(get.prompt('twshezhong'),'令至多'+get.cnNumber(damage)+'名其他角色下个摸牌阶段的摸牌数-1',[1,damage],lib.filter.notMe).set('ai',target=>{ - return -get.attitude(_status.event.player,target); - }); - } - else event.goto(2); - 'step 1' - if(result.bool){ - var targets=result.targets; - player.logSkill('twshezhong',targets); - for(var target of targets){ - target.addSkill('twshezhong_minus'); - target.addMark('twshezhong_minus',1,false); + twshezhong: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + var damage = player.getHistory("sourceDamage").length; + if (damage) { + player + .chooseTarget( + get.prompt("twshezhong"), + "令至多" + get.cnNumber(damage) + "名其他角色下个摸牌阶段的摸牌数-1", + [1, damage], + lib.filter.notMe + ) + .set("ai", (target) => { + return -get.attitude(_status.event.player, target); + }); + } else event.goto(2); + "step 1"; + if (result.bool) { + var targets = result.targets; + player.logSkill("twshezhong", targets); + for (var target of targets) { + target.addSkill("twshezhong_minus"); + target.addMark("twshezhong_minus", 1, false); } } - 'step 2' - var targets=[]; - for(var evt of player.getHistory('damage')){ - if(evt.source&&evt.source.isIn()) targets.add(evt.source); + "step 2"; + var targets = []; + for (var evt of player.getHistory("damage")) { + if (evt.source && evt.source.isIn()) targets.add(evt.source); } - if(targets.length){ - player.chooseTarget(get.prompt('twshezhong'),'将手牌摸至一名与一名本回合对你造成过伤害的角色的体力值相同,且至多摸至五张',(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('ai',target=>{ - return Math.max(0.1,target.hp-_status.event.player.countCards('h')); - }).set('targets',targets); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twshezhong',target); - var num=Math.min(target.hp,5)-player.countCards('h'); - if(num>0) player.draw(num); + if (targets.length) { + player + .chooseTarget( + get.prompt("twshezhong"), + "将手牌摸至一名与一名本回合对你造成过伤害的角色的体力值相同,且至多摸至五张", + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("ai", (target) => { + return Math.max(0.1, target.hp - _status.event.player.countCards("h")); + }) + .set("targets", targets); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twshezhong", target); + var num = Math.min(target.hp, 5) - player.countCards("h"); + if (num > 0) player.draw(num); } }, - subSkill:{ - minus:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - onremove:true, - content:function(){ - var num=player.countMark('twshezhong_minus'); - trigger.num-=num; - game.log(player,'的额定摸牌数','#g-'+num); - player.removeSkill('twshezhong_minus'); + subSkill: { + minus: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + onremove: true, + content: function () { + var num = player.countMark("twshezhong_minus"); + trigger.num -= num; + game.log(player, "的额定摸牌数", "#g-" + num); + player.removeSkill("twshezhong_minus"); }, - mark:true, - intro:{ - content:'额定摸牌数-#', + mark: true, + intro: { + content: "额定摸牌数-#", }, - } - } + }, + }, }, //侠鲁肃 - twkaizeng:{ - audio:2, - global:'twkaizeng_want', - refuseInfo:['不给','拒绝'], - subSkill:{ - want:{ - audio:'twkaizeng', - forceaudio:true, - enable:'phaseUse', - usable:1, - charlotte:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - return current!=player&¤t.hasSkill('twkaizeng'); + twkaizeng: { + audio: 2, + global: "twkaizeng_want", + refuseInfo: ["不给", "拒绝"], + subSkill: { + want: { + audio: "twkaizeng", + forceaudio: true, + enable: "phaseUse", + usable: 1, + charlotte: true, + filter: function (event, player) { + return game.hasPlayer((current) => { + return current != player && current.hasSkill("twkaizeng"); }); }, - chooseButton:{ - dialog:function(event,player){ - var targets=game.filterPlayer(current=>{ - return current!=player&¤t.hasSkill('twkaizeng'); + chooseButton: { + dialog: function (event, player) { + var targets = game.filterPlayer((current) => { + return current != player && current.hasSkill("twkaizeng"); }); - return ui.create.dialog('###慨赠###'+'选择一种基本牌的牌名或非基本牌的类型,然后令'+get.translation(targets)+(targets.length>1?'中的一人':'')+'选择是否交给你任意张牌'); + return ui.create.dialog( + "###慨赠###" + + "选择一种基本牌的牌名或非基本牌的类型,然后令" + + get.translation(targets) + + (targets.length > 1 ? "中的一人" : "") + + "选择是否交给你任意张牌" + ); }, - chooseControl:function(){ - var list=[]; - var basic=[]; - for(var i=0;icurrent!=player&¤t.hasSkill('twkaizeng')); - targets.sort((a,b)=>get.attitude(player,b)-get.attitude(player,a)); - var cards=targets[0].getCards('h'); - var list=[]; - for(var card of cards){ - var type=get.type2(card); - if(type=='basic') list.add(get.name(card)); + var targets = game.filterPlayer( + (current) => current != player && current.hasSkill("twkaizeng") + ); + targets.sort((a, b) => get.attitude(player, b) - get.attitude(player, a)); + var cards = targets[0].getCards("h"); + var list = []; + for (var card of cards) { + var type = get.type2(card); + if (type == "basic") list.add(get.name(card)); else list.add(type); } - var need=['trick','equip'].randomSort(); - need.addArray(['sha','jiu'].randomSort()); - for(var type of need){ - if(list.includes(type)) return type; + var need = ["trick", "equip"].randomSort(); + need.addArray(["sha", "jiu"].randomSort()); + for (var type of need) { + if (list.includes(type)) return type; } return list.randomGet(); }, - backup:function(result,player){ + backup: function (result, player) { return { - audio:'twkaizeng', - type:result.control, - log:false, - delay:false, - filterTarget:function(card,player,target){ - return target.hasSkill('twkaizeng'); + audio: "twkaizeng", + type: result.control, + log: false, + delay: false, + filterTarget: function (card, player, target) { + return target.hasSkill("twkaizeng"); }, - selectTarget:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('twkaizeng'); + selectTarget: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("twkaizeng"); }); - return targets.length>1?1:-1; + return targets.length > 1 ? 1 : -1; }, - prepare:function(cards,player,targets){ - targets[0].logSkill('twkaizeng_want',player); + prepare: function (cards, player, targets) { + targets[0].logSkill("twkaizeng_want", player); }, - content:function(){ - 'step 0' - var type=lib.skill.twkaizeng_want_backup.type; - var isbasic=lib.card[type]; - target.chooseCard('慨赠:是否交给'+get.translation(player)+'任意张手牌?','若你以此法:交给其至少两张牌,你摸一张牌;交给其的牌包含其选择的牌名或类型,你获得一张不为此牌名或类型的牌',[1,Infinity]).set('ai',card=>{ - if(!_status.event.goon) return -get.value(card); - var player=_status.event.player,target=_status.event.getParent().player; - if(ui.selected.cards.length>player.countCards('h')/2&&ui.selected.cards.length>=2) return 0; - var type=_status.event.type; - var isbasic=lib.card[type]; - var add=0; - if(!ui.selected.cards.some(i=>get[isbasic?'name':'type2'](i,target)==type)) add+=3; - if(ui.selected.cards.length<2) add+=3; - return get.value(card,target)-get.value(card,player)+add; - }).set('type',type).set('goon',get.attitude(target,player)>0); - 'step 1' - if(result.bool){ - var cards=result.cards; - event.cards=cards; - target.give(cards,player); - } - else{ - var refuseInfo=lib.skill.twkaizeng.refuseInfo.slice(); - if(get.attitude(target,player)<0) refuseInfo.push('没门'); + content: function () { + "step 0"; + var type = lib.skill.twkaizeng_want_backup.type; + var isbasic = lib.card[type]; + target + .chooseCard( + "慨赠:是否交给" + get.translation(player) + "任意张手牌?", + "若你以此法:交给其至少两张牌,你摸一张牌;交给其的牌包含其选择的牌名或类型,你获得一张不为此牌名或类型的牌", + [1, Infinity] + ) + .set("ai", (card) => { + if (!_status.event.goon) return -get.value(card); + var player = _status.event.player, + target = _status.event.getParent().player; + if ( + ui.selected.cards.length > player.countCards("h") / 2 && + ui.selected.cards.length >= 2 + ) + return 0; + var type = _status.event.type; + var isbasic = lib.card[type]; + var add = 0; + if ( + !ui.selected.cards.some( + (i) => + get[isbasic ? "name" : "type2"](i, target) == type + ) + ) + add += 3; + if (ui.selected.cards.length < 2) add += 3; + return ( + get.value(card, target) - get.value(card, player) + add + ); + }) + .set("type", type) + .set("goon", get.attitude(target, player) > 0); + "step 1"; + if (result.bool) { + var cards = result.cards; + event.cards = cards; + target.give(cards, player); + } else { + var refuseInfo = lib.skill.twkaizeng.refuseInfo.slice(); + if (get.attitude(target, player) < 0) refuseInfo.push("没门"); target.chat(refuseInfo.randomGet()); event.finish(); } - 'step 2' - if(cards.length>1) target.draw(); - 'step 3' - var type=lib.skill.twkaizeng_want_backup.type; - var isbasic=lib.card[type]; - var fn=isbasic?'name':'type2'; - if(cards.some(card=>get[fn](card,player)==type)){ - var card=get.cardPile(cardx=>{ - return get[fn](cardx,target)!=type; + "step 2"; + if (cards.length > 1) target.draw(); + "step 3"; + var type = lib.skill.twkaizeng_want_backup.type; + var isbasic = lib.card[type]; + var fn = isbasic ? "name" : "type2"; + if (cards.some((card) => get[fn](card, player) == type)) { + var card = get.cardPile((cardx) => { + return get[fn](cardx, target) != type; }); - if(card) target.gain(card,'gain2'); + if (card) target.gain(card, "gain2"); } - 'step 4' + "step 4"; game.delayx(); }, - ai:{ - result:{ - target:1, + ai: { + result: { + target: 1, }, }, - } + }; }, - prompt:()=>'请选择一名有【慨赠】的角色', + prompt: () => "请选择一名有【慨赠】的角色", }, - ai:{ - order:10, - result:{ - player:function(player){ - var targets=game.filterPlayer(current=>{ - return current!=player&¤t.hasSkill('twkaizeng'); + ai: { + order: 10, + result: { + player: function (player) { + var targets = game.filterPlayer((current) => { + return current != player && current.hasSkill("twkaizeng"); }); - for(var i of targets) if(get.attitude(player,i)>0) return 1; + for (var i of targets) if (get.attitude(player, i) > 0) return 1; return 0; - } - }, - }, - }, - want_backup:{}, - }, - ai:{ - threaten:3 - } - }, - twyangming:{ - audio:2, - trigger:{ - player:'phaseUseEnd', - }, - frequent:true, - filter:function(event,player){ - return player.hasHistory('useCard',evt=>evt.getParent('phaseUse')==event); - }, - content:function(){ - var types=[]; - var history=player.getHistory('useCard',evt=>evt.getParent('phaseUse')==trigger); - for(var evt of history){ - types.add(get.type2(evt.card)); - } - var num=types.length; - player.draw(num); - player.addTempSkill('twyangming_limit'); - player.addMark('twyangming_limit',num,false); - game.log(player,'本回合的手牌上限','#g+'+num); - }, - subSkill:{ - limit:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('twyangming_limit'); - } - } - } - } - }, - //邴原 - twbingde:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')&&player.getStorage('twbingde_clear').length<4; - }, - onChooseToUse:function(event){ - if(event.type=='phase'&&!game.online){ - var map={}; - event.player.getHistory('useCard',evt=>{ - var evtx=evt.getParent('phaseUse'),suit=get.suit(evt.card); - if(!lib.suit.includes(suit)) return; - if(evtx!=event.getParent('phaseUse')) return; - if(typeof map[suit]!='number') map[suit]=0; - map[suit]++; - }); - event.set('twbingde_map',map); - } - }, - chooseButton:{ - dialog:function(event,player){ - var str=get.translation('twbingde_info'),str2=''; - if(event.twbingde_map){ - str2='
              本回合使用牌对应花色数:
              '; - str2+='
              '; - for(var suit of lib.suit){ - str2+=get.translation(suit)+':'+get.cnNumber(event.twbingde_map[suit]||0)+'张;'; - } - str2=str2.slice(0,str2.length-1)+'
              '; - } - return ui.create.dialog('###秉德###'+str,str2); - }, - chooseControl:function(event,player){ - var list=lib.suit.slice(); - list.removeArray(player.getStorage('twbingde_clear')); - list.push('cancel2'); - return list; - }, - check:function(event,player){ - var map=event.twbingde_map; - var suit=lib.suit.filter(i=>!player.getStorage('twbingde_clear').includes(i)).sort((a,b)=>{ - return map[b]-map[a]; - })[0]; - if(map[suit]==0) return 'cancel2'; - return suit; - }, - backup:function(result,player){ - return { - audio:'twbingde', - filterCard:true, - selectCard:1, - position:'he', - suit:result.control, - check:function(card){ - var suit=lib.skill.twbingde.suit; - if(get.suit(card)==suit) return 10-get.value(card); - return 6-get.value(card); - }, - content:function(){ - 'step 0' - var suit=lib.skill.twbingde_backup.suit,num=0; - player.popup(suit+2); - game.log(player,'选择了','#y'+suit+2); - player.addTempSkill('twbingde_clear','phaseUseAfter'); - player.markAuto('twbingde_clear',[suit]); - player.getHistory('useCard',evt=>{ - var evtx=evt.getParent('phaseUse'),suitx=get.suit(evt.card); - if(!evtx||evtx!=event.getParent('phaseUse')||suit!=suitx) return false; - num++; - }); - if(num>0) player.draw(num); - 'step 1' - if(get.suit(cards[0],player)==lib.skill.twbingde_backup.suit){ - delete player.getStat('skill').twbingde; - } - }, - ai:{ - result:{ - player:1, }, }, - } + }, }, - prompt:()=>'秉德:弃置一张牌', + want_backup: {}, }, - ai:{ - order:2, - result:{player:1} - }, - subSkill:{ - backup:{}, - clear:{ - charlotte:true, - onremove:true, - } + ai: { + threaten: 3, }, }, - twqingtao:{ - audio:2, - trigger:{player:'phaseDrawEnd'}, - filter:function(event,player){ - return player.countCards('he'); + twyangming: { + audio: 2, + trigger: { + player: "phaseUseEnd", }, - direct:true, - group:'twqingtao_jieshu', - content:function(){ - 'step 0' - player.chooseCard(get.prompt2('twqingtao'),'he',lib.filter.cardRecastable).set('ai',function(card){ - if(card.name=='jiu'||get.type(card)!='basic') return 10-get.value(card); - return 6-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('twqingtao'); - player.recast(result.cards); - if(get.name(result.cards[0])=='jiu'||get.type(result.cards[0],false,player)!='basic') player.draw(); + frequent: true, + filter: function (event, player) { + return player.hasHistory("useCard", (evt) => evt.getParent("phaseUse") == event); + }, + content: function () { + var types = []; + var history = player.getHistory("useCard", (evt) => evt.getParent("phaseUse") == trigger); + for (var evt of history) { + types.add(get.type2(evt.card)); + } + var num = types.length; + player.draw(num); + player.addTempSkill("twyangming_limit"); + player.addMark("twyangming_limit", num, false); + game.log(player, "本回合的手牌上限", "#g+" + num); + }, + subSkill: { + limit: { + charlotte: true, + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("twyangming_limit"); + }, + }, + }, + }, + }, + //邴原 + twbingde: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") && player.getStorage("twbingde_clear").length < 4; + }, + onChooseToUse: function (event) { + if (event.type == "phase" && !game.online) { + var map = {}; + event.player.getHistory("useCard", (evt) => { + var evtx = evt.getParent("phaseUse"), + suit = get.suit(evt.card); + if (!lib.suit.includes(suit)) return; + if (evtx != event.getParent("phaseUse")) return; + if (typeof map[suit] != "number") map[suit] = 0; + map[suit]++; + }); + event.set("twbingde_map", map); } }, - subSkill:{ - jieshu:{ - audio:'twqingtao', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('he')>0&&!player.hasHistory('useSkill',evt=>evt.skill=='twqingtao'); + chooseButton: { + dialog: function (event, player) { + var str = get.translation("twbingde_info"), + str2 = ""; + if (event.twbingde_map) { + str2 = '
              本回合使用牌对应花色数:
              '; + str2 += '
              '; + for (var suit of lib.suit) { + str2 += + get.translation(suit) + + ":" + + get.cnNumber(event.twbingde_map[suit] || 0) + + "张;"; + } + str2 = str2.slice(0, str2.length - 1) + "
              "; + } + return ui.create.dialog("###秉德###" + str, str2); + }, + chooseControl: function (event, player) { + var list = lib.suit.slice(); + list.removeArray(player.getStorage("twbingde_clear")); + list.push("cancel2"); + return list; + }, + check: function (event, player) { + var map = event.twbingde_map; + var suit = lib.suit + .filter((i) => !player.getStorage("twbingde_clear").includes(i)) + .sort((a, b) => { + return map[b] - map[a]; + })[0]; + if (map[suit] == 0) return "cancel2"; + return suit; + }, + backup: function (result, player) { + return { + audio: "twbingde", + filterCard: true, + selectCard: 1, + position: "he", + suit: result.control, + check: function (card) { + var suit = lib.skill.twbingde.suit; + if (get.suit(card) == suit) return 10 - get.value(card); + return 6 - get.value(card); + }, + content: function () { + "step 0"; + var suit = lib.skill.twbingde_backup.suit, + num = 0; + player.popup(suit + 2); + game.log(player, "选择了", "#y" + suit + 2); + player.addTempSkill("twbingde_clear", "phaseUseAfter"); + player.markAuto("twbingde_clear", [suit]); + player.getHistory("useCard", (evt) => { + var evtx = evt.getParent("phaseUse"), + suitx = get.suit(evt.card); + if (!evtx || evtx != event.getParent("phaseUse") || suit != suitx) + return false; + num++; + }); + if (num > 0) player.draw(num); + "step 1"; + if (get.suit(cards[0], player) == lib.skill.twbingde_backup.suit) { + delete player.getStat("skill").twbingde; + } + }, + ai: { + result: { + player: 1, + }, + }, + }; + }, + prompt: () => "秉德:弃置一张牌", + }, + ai: { + order: 2, + result: { player: 1 }, + }, + subSkill: { + backup: {}, + clear: { + charlotte: true, + onremove: true, + }, + }, + }, + twqingtao: { + audio: 2, + trigger: { player: "phaseDrawEnd" }, + filter: function (event, player) { + return player.countCards("he"); + }, + direct: true, + group: "twqingtao_jieshu", + content: function () { + "step 0"; + player + .chooseCard(get.prompt2("twqingtao"), "he", lib.filter.cardRecastable) + .set("ai", function (card) { + if (card.name == "jiu" || get.type(card) != "basic") return 10 - get.value(card); + return 6 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("twqingtao"); + player.recast(result.cards); + if ( + get.name(result.cards[0]) == "jiu" || + get.type(result.cards[0], false, player) != "basic" + ) + player.draw(); + } + }, + subSkill: { + jieshu: { + audio: "twqingtao", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + !player.hasHistory("useSkill", (evt) => evt.skill == "twqingtao") + ); }, - direct:true, - content:function(){ - var next=game.createEvent('twqingtao'); - next.player=player; + direct: true, + content: function () { + var next = game.createEvent("twqingtao"); + next.player = player; next.setContent(lib.skill.twqingtao.content); }, - } - } - }, - //牛董 - twjuntun:{ - audio:2, - trigger:{ - global:['phaseBefore','dieAfter'], - player:'enterGame', - }, - init:function(player){lib.skill.baonvezhi.change(player,0)}, - direct:true, - derivation:['twxiongjun','baonvezhi_faq'], - group:'twjuntun_extra', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.hasPlayer(current=>{ - return !current.hasSkill('twxiongjun'); - }); - }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twjuntun'),'令一名角色获得〖凶军〗',(card,player,target)=>{ - return !target.hasSkill('twxiongjun'); - }).set('ai',target=>get.attitude(player,target)-2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twjuntun',target); - target.addSkills('twxiongjun'); - if(target!=player) player.addExpose(0.25); - } - }, - subSkill:{ - extra:{ - audio:2, - trigger:{global:'damageSource'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.source&&event.source.hasSkill('twxiongjun')&&event.source!=player; - }, - logTarget:'source', - content:function(){ - lib.skill.baonvezhi.change(player,trigger.num); - } }, }, }, - baonvezhi:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + //牛董 + twjuntun: { + audio: 2, + trigger: { + global: ["phaseBefore", "dieAfter"], + player: "enterGame", }, - silent:true, - forced:true, - charlotte:true, - baonvezhi_max:5, - change:function(player,num){ - var baonvezhi_max=lib.skill.baonvezhi.baonvezhi_max; - player.addSkill('baonvezhi'); - var tmp=player.countMark('baonvezhi'); - if(tmp+num>baonvezhi_max) num=baonvezhi_max-tmp; - else if(tmp+num<0) num=-tmp; - if(num===0) return; - player[num>0?'addMark':'removeMark']('baonvezhi',Math.abs(num),false); - game.log(player,num>=0?'获得了':'失去了',get.cnNumber(Math.abs(num))+'点暴虐值'); - player[player.countMark('baonvezhi')>0?'markSkill':'unmarkSkill']('baonvezhi'); + init: function (player) { + lib.skill.baonvezhi.change(player, 0); }, - filter:function(event,player){ - return player.countMark('baonvezhi') { + return !current.hasSkill("twxiongjun"); + }) + ); }, - content:function(){ - lib.skill.baonvezhi.change(player,trigger.num); - }, - marktext:'暴', - intro:{ - name:'暴虐值', - content:function(storage,player){ - return get.translation(player)+'的暴虐值为'+(player.storage.baonvezhi||0); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twjuntun"), + "令一名角色获得〖凶军〗", + (card, player, target) => { + return !target.hasSkill("twxiongjun"); + } + ) + .set("ai", (target) => get.attitude(player, target) - 2); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twjuntun", target); + target.addSkills("twxiongjun"); + if (target != player) player.addExpose(0.25); } - } + }, + subSkill: { + extra: { + audio: 2, + trigger: { global: "damageSource" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + event.source && event.source.hasSkill("twxiongjun") && event.source != player + ); + }, + logTarget: "source", + content: function () { + lib.skill.baonvezhi.change(player, trigger.num); + }, + }, + }, }, - baonvezhi_faq:{}, - twxiongjun:{ - init:function(player){lib.skill.baonvezhi.change(player,0)}, - trigger:{source:'damageSource'}, - forced:true, - usable:1, - content:function(){ - var targets=game.filterPlayer(current=>current.hasSkill('twxiongjun')).sortBySeat(); - player.line(targets,'green'); + baonvezhi: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", + }, + silent: true, + forced: true, + charlotte: true, + baonvezhi_max: 5, + change: function (player, num) { + var baonvezhi_max = lib.skill.baonvezhi.baonvezhi_max; + player.addSkill("baonvezhi"); + var tmp = player.countMark("baonvezhi"); + if (tmp + num > baonvezhi_max) num = baonvezhi_max - tmp; + else if (tmp + num < 0) num = -tmp; + if (num === 0) return; + player[num > 0 ? "addMark" : "removeMark"]("baonvezhi", Math.abs(num), false); + game.log( + player, + num >= 0 ? "获得了" : "失去了", + get.cnNumber(Math.abs(num)) + '点暴虐值' + ); + player[player.countMark("baonvezhi") > 0 ? "markSkill" : "unmarkSkill"]("baonvezhi"); + }, + filter: function (event, player) { + return player.countMark("baonvezhi") < lib.skill.baonvezhi.baonvezhi_max; + }, + content: function () { + lib.skill.baonvezhi.change(player, trigger.num); + }, + marktext: "暴", + intro: { + name: "暴虐值", + content: function (storage, player) { + return get.translation(player) + "的暴虐值为" + (player.storage.baonvezhi || 0); + }, + }, + }, + baonvezhi_faq: {}, + twxiongjun: { + init: function (player) { + lib.skill.baonvezhi.change(player, 0); + }, + trigger: { source: "damageSource" }, + forced: true, + usable: 1, + content: function () { + var targets = game.filterPlayer((current) => current.hasSkill("twxiongjun")).sortBySeat(); + player.line(targets, "green"); game.asyncDraw(targets); }, }, - twxiongxi:{ - audio:2, - enable:'phaseUse', - usable:1, - init:function(player){lib.skill.baonvezhi.change(player,0)}, - filterCard:()=>true, - selectCard:function(){ - return (lib.skill.baonvezhi.baonvezhi_max||5)-_status.event.player.countMark('baonvezhi'); + twxiongxi: { + audio: 2, + enable: "phaseUse", + usable: 1, + init: function (player) { + lib.skill.baonvezhi.change(player, 0); }, - check:function(card){ - return 6-get.value(card); + filterCard: () => true, + selectCard: function () { + return ( + (lib.skill.baonvezhi.baonvezhi_max || 5) - _status.event.player.countMark("baonvezhi") + ); }, - position:'he', - filterTarget:function(card,player,target){ - return target!=player; + check: function (card) { + return 6 - get.value(card); }, - content:function(){ + position: "he", + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { target.damage(); }, - ai:{ - expose:0.25, - order:8, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,player); - } - } - } + ai: { + expose: 0.25, + order: 8, + result: { + target: function (player, target) { + return get.damageEffect(target, player, player); + }, + }, + }, }, - twxiafeng:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countMark('baonvezhi')>0; + twxiafeng: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countMark("baonvezhi") > 0; }, - init:function(player){lib.skill.baonvezhi.change(player,0)}, - direct:true, - content:function(){ - 'step 0' - player.chooseButton(['黠凤:选择要消耗的暴虐值',[['tw_bn_1','tw_bn_2','tw_bn_3'],'vcard']],(button)=>{ - var num=player.countCards('hs',card=>get.tag(card,'damage')&&game.hasPlayer(current=>get.effect(current,card,player,player)>0)); - if(num<=0) return 0; - if(num>=3) num=3; - if(button.link[2]=='tw_bn_'+num) return 10; - return 1; - }).set('filterButton',(button)=>{ - var player=_status.event.player; - var link=button.link[2]; - if(link[link.length-1]*1>player.storage.baonvezhi) return false; - return true; - }); - 'step 1' - if(result.bool){ - player.logSkill('twxiafeng'); - var link=result.links[0][2],num=link[link.length-1]*1; - player.addTempSkill('twxiafeng_effect'); - player.storage.twxiafeng_effect=num; - lib.skill.baonvezhi.change(player,-num); + init: function (player) { + lib.skill.baonvezhi.change(player, 0); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseButton( + ["黠凤:选择要消耗的暴虐值", [["tw_bn_1", "tw_bn_2", "tw_bn_3"], "vcard"]], + (button) => { + var num = player.countCards( + "hs", + (card) => + get.tag(card, "damage") && + game.hasPlayer( + (current) => get.effect(current, card, player, player) > 0 + ) + ); + if (num <= 0) return 0; + if (num >= 3) num = 3; + if (button.link[2] == "tw_bn_" + num) return 10; + return 1; + } + ) + .set("filterButton", (button) => { + var player = _status.event.player; + var link = button.link[2]; + if (link[link.length - 1] * 1 > player.storage.baonvezhi) return false; + return true; + }); + "step 1"; + if (result.bool) { + player.logSkill("twxiafeng"); + var link = result.links[0][2], + num = link[link.length - 1] * 1; + player.addTempSkill("twxiafeng_effect"); + player.storage.twxiafeng_effect = num; + lib.skill.baonvezhi.change(player, -num); } }, - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - filter:function(event,player){ + subSkill: { + effect: { + trigger: { player: "useCard" }, + filter: function (event, player) { return !player.storage.twxiafeng_effect2; }, - forced:true, - content:function(){ - var count=player.getHistory('useCard',evt=>evt.getParent('phaseUse').player==player).length; - if(count==player.storage.twxiafeng_effect){ - player.storage.twxiafeng_effect2=true; + forced: true, + content: function () { + var count = player.getHistory( + "useCard", + (evt) => evt.getParent("phaseUse").player == player + ).length; + if (count == player.storage.twxiafeng_effect) { + player.storage.twxiafeng_effect2 = true; } - if(count<=player.storage.twxiafeng_effect){ + if (count <= player.storage.twxiafeng_effect) { trigger.directHit.addArray(game.players); - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; } } }, - onremove:function(player){ + onremove: function (player) { delete player.storage.twxiafeng_effect; delete player.storage.twxiafeng_effect2; }, - mod:{ - targetInRange:function(card,player,target,now){ - if(!player.storage.twxiafeng_effect2) return true; + mod: { + targetInRange: function (card, player, target, now) { + if (!player.storage.twxiafeng_effect2) return true; }, - cardUsableTarget:function(card,player,target){ - if(!player.storage.twxiafeng_effect2) return true; + cardUsableTarget: function (card, player, target) { + if (!player.storage.twxiafeng_effect2) return true; + }, + maxHandcard: function (player, num) { + return num + (player.storage.twxiafeng_effect || 0); }, - maxHandcard:function(player,num){ - return num+(player.storage.twxiafeng_effect||0); - } }, - } - } + }, + }, }, //蒋济 - twjichou:{ - audio:2, - enable:'chooseToUse', - group:['twjichou_ban','twjichou_give'], - filter:function(event,player){ - if(player.hasSkill('twjichou_used')&&player.hasSkill('twjichou_given')) return false; - if(!player.hasSkill('twjichou_used')){ - var record=player.getStorage('twjichou'); - for(var i of lib.inpile){ - var type=get.type(i); - if(type=='trick'&&!record.includes(i)&&event.filterCard({name:i,isCard:true},player,event)) return true; + twjichou: { + audio: 2, + enable: "chooseToUse", + group: ["twjichou_ban", "twjichou_give"], + filter: function (event, player) { + if (player.hasSkill("twjichou_used") && player.hasSkill("twjichou_given")) return false; + if (!player.hasSkill("twjichou_used")) { + var record = player.getStorage("twjichou"); + for (var i of lib.inpile) { + var type = get.type(i); + if ( + type == "trick" && + !record.includes(i) && + event.filterCard({ name: i, isCard: true }, player, event) + ) + return true; } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('急筹'); - if(!player.hasSkill('twjichou_used')&&!player.hasSkill('twjichou_given')&&event.type=='phase'&&player.countCards('h',card=>{ - return player.getStorage('twjichou').includes(get.name(card)); - })){ - dialog._chosenOpt=[]; - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var list=['视为使用牌','交出锦囊牌']; - for(var i of list){ - var td=ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode'); - td.innerHTML=''+i+''; - td.link=i; - if(i==list[0]){ - td.classList.add('bluebg'); + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("急筹"); + if ( + !player.hasSkill("twjichou_used") && + !player.hasSkill("twjichou_given") && + event.type == "phase" && + player.countCards("h", (card) => { + return player.getStorage("twjichou").includes(get.name(card)); + }) + ) { + dialog._chosenOpt = []; + var table = document.createElement("div"); + table.classList.add("add-setting"); + table.style.margin = "0"; + table.style.width = "100%"; + table.style.position = "relative"; + var list = ["视为使用牌", "交出锦囊牌"]; + for (var i of list) { + var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); + td.innerHTML = "" + i + ""; + td.link = i; + if (i == list[0]) { + td.classList.add("bluebg"); dialog._chosenOpt.add(td); } - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.clicked) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - _status.clicked=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(link=='交出锦囊牌') game.uncheck(); - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); - dialog._chosenOpt.remove(current); + td.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function () { + if (_status.dragged) return; + if (_status.clicked) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + _status.clicked = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (link == "交出锦囊牌") game.uncheck(); + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); + dialog._chosenOpt.remove(current); + } + dialog._chosenOpt.add(this); + this.classList.add("bluebg"); + game.check(); } - dialog._chosenOpt.add(this); - this.classList.add('bluebg'); - game.check(); - }); + ); table.appendChild(td); dialog.buttons.add(td); } dialog.content.appendChild(table); } - var list=[],record=player.getStorage('twjichou'); - for(var name of lib.inpile){ - if(get.type(name)=='trick'&&!record.includes(name)&&event.filterCard({name:name,isCard:true},player,event)) list.push(['锦囊','',name]); + var list = [], + record = player.getStorage("twjichou"); + for (var name of lib.inpile) { + if ( + get.type(name) == "trick" && + !record.includes(name) && + event.filterCard({ name: name, isCard: true }, player, event) + ) + list.push(["锦囊", "", name]); } - dialog.add([list,'vcard']); + dialog.add([list, "vcard"]); return dialog; }, - filter:function(button){ - if(_status.event.dialog){ - var opts=_status.event.dialog._chosenOpt; - if(opts&&opts.length&&opts[0].link=='交出锦囊牌'&&typeof button.link!=typeof opts[0].link){ + filter: function (button) { + if (_status.event.dialog) { + var opts = _status.event.dialog._chosenOpt; + if ( + opts && + opts.length && + opts[0].link == "交出锦囊牌" && + typeof button.link != typeof opts[0].link + ) { return false; } return true; } return false; }, - select:function(){ - if(_status.event.dialog){ - var opts=_status.event.dialog._chosenOpt; - return opts&&opts.length&&opts[0].link=='交出锦囊牌'?0:1; + select: function () { + if (_status.event.dialog) { + var opts = _status.event.dialog._chosenOpt; + return opts && opts.length && opts[0].link == "交出锦囊牌" ? 0 : 1; } return 0; }, - check:function(button){ - if(_status.event.getParent().type!='phase') return 1; - var player=_status.event.player; - if(['wugu','zhulu_card','yiyi','lulitongxin','lianjunshengyan','diaohulishan'].includes(button.link[2])) return 0.1; - return player.getUseValue({name:button.link[2]}); + check: function (button) { + if (_status.event.getParent().type != "phase") return 1; + var player = _status.event.player; + if ( + [ + "wugu", + "zhulu_card", + "yiyi", + "lulitongxin", + "lianjunshengyan", + "diaohulishan", + ].includes(button.link[2]) + ) + return 0.1; + return player.getUseValue({ name: button.link[2] }); }, - backup:function(links,player){ - var isUse=links.length==1; - var backup=get.copy(lib.skill['twjichou_'+(isUse?'use':'give')]); - if(isUse) backup.viewAs={name:links[0][2],isCard:true}; + backup: function (links, player) { + var isUse = links.length == 1; + var backup = get.copy(lib.skill["twjichou_" + (isUse ? "use" : "give")]); + if (isUse) backup.viewAs = { name: links[0][2], isCard: true }; return backup; }, - prompt:function(links,player){ - var isUse=links.length==1; - return '急筹:'+(isUse?('视为使用'+get.translation(links[0][2])+''):'选择要交出的牌和要交给的目标'); - } + prompt: function (links, player) { + var isUse = links.length == 1; + return ( + "急筹:" + + (isUse + ? "视为使用" + get.translation(links[0][2]) + "" + : "选择要交出的牌和要交给的目标") + ); + }, }, - hiddenCard:function(player,name){ - if(player.hasSkill('twjichou_used')) return false; - var type=get.type(name); - return type=='trick'&&!player.getStorage('twjichou').includes(name); + hiddenCard: function (player, name) { + if (player.hasSkill("twjichou_used")) return false; + var type = get.type(name); + return type == "trick" && !player.getStorage("twjichou").includes(name); }, - marktext:'筹', - intro:{ - markcount:function(storage,player){ - if(storage&&storage.length) return storage.length; + marktext: "筹", + intro: { + markcount: function (storage, player) { + if (storage && storage.length) return storage.length; return 0; }, - content:'已记录牌名:$', + content: "已记录牌名:$", }, - ai:{ - order:1, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + ai: { + order: 1, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - backup:{}, - used:{charlotte:true}, - given:{charlotte:true}, - ban:{ - trigger:{global:'useCard1'}, - filter:function(event,player){ - return player.getStorage('twjichou').includes(event.card.name); + subSkill: { + backup: {}, + used: { charlotte: true }, + given: { charlotte: true }, + ban: { + trigger: { global: "useCard1" }, + filter: function (event, player) { + return player.getStorage("twjichou").includes(event.card.name); }, - forced:true, - locked:false, - silent:true, - content:function(){ + forced: true, + locked: false, + silent: true, + content: function () { trigger.directHit.add(player); }, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('twjichou').includes(card.name)&&(get.position(card)=='h'||card.cards&&card.cards.some(i=>get.position(i)=='h'))) return false; + mod: { + cardEnabled: function (card, player) { + if ( + player.getStorage("twjichou").includes(card.name) && + (get.position(card) == "h" || + (card.cards && card.cards.some((i) => get.position(i) == "h"))) + ) + return false; }, - cardSavable:function(card,player){ - if(player.getStorage('twjichou').includes(card.name)&&(get.position(card)=='h'||card.cards&&card.cards.some(i=>get.position(i)=='h'))) return false; + cardSavable: function (card, player) { + if ( + player.getStorage("twjichou").includes(card.name) && + (get.position(card) == "h" || + (card.cards && card.cards.some((i) => get.position(i) == "h"))) + ) + return false; }, - aiValue:function(player,card){ - if(get.type(card)!='trick'||_status.twjichou_give_aiCheck) return; - if(!player.getFriends().length&&player.getStorage('twjichou').includes(get.name(card))) return 0; + aiValue: function (player, card) { + if (get.type(card) != "trick" || _status.twjichou_give_aiCheck) return; + if ( + !player.getFriends().length && + player.getStorage("twjichou").includes(get.name(card)) + ) + return 0; }, - aiUseful:function(){ - return lib.skill.twjichou_ban.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.twjichou_ban.mod.aiValue.apply(this, arguments); }, }, }, - use:{ - filterCard:()=>false, - selectCard:-1, - audio:'twjichou', - popname:true, - onuse:function(links,player){ - player.markAuto('twjichou',[links.card.name]); - player.syncStorage('twjichou'); - player.addTempSkill('twjichou_used'); + use: { + filterCard: () => false, + selectCard: -1, + audio: "twjichou", + popname: true, + onuse: function (links, player) { + player.markAuto("twjichou", [links.card.name]); + player.syncStorage("twjichou"); + player.addTempSkill("twjichou_used"); }, }, - give:{ - audio:'twjichou', - enable:'phaseUse', - filter:function(event,player){ - return player.hasSkill('twjichou_used')&&!player.hasSkill('twjichou_given')&&player.countCards('h',i=>player.getStorage('twjichou').includes(get.name(i))); + give: { + audio: "twjichou", + enable: "phaseUse", + filter: function (event, player) { + return ( + player.hasSkill("twjichou_used") && + !player.hasSkill("twjichou_given") && + player.countCards("h", (i) => + player.getStorage("twjichou").includes(get.name(i)) + ) + ); }, - filterTarget:function(card,player,target){ - return target!=player; + filterTarget: function (card, player, target) { + return target != player; }, - filterCard:function(card,player){ - return player.getStorage('twjichou').includes(get.name(card)); + filterCard: function (card, player) { + return player.getStorage("twjichou").includes(get.name(card)); }, - check:function(card){ - _status.twjichou_give_aiCheck=true; - var val=get.value(card); + check: function (card) { + _status.twjichou_give_aiCheck = true; + var val = get.value(card); delete _status.twjichou_give_aiCheck; return val; }, - prompt:()=>'选择要交出的牌和要交给的目标', - selectCard:1, - discard:false, - lose:false, - delay:false, - content:function(){ - player.give(cards,target); - player.addTempSkill('twjichou_given','phaseUseAfter'); + prompt: () => "选择要交出的牌和要交给的目标", + selectCard: 1, + discard: false, + lose: false, + delay: false, + content: function () { + player.give(cards, target); + player.addTempSkill("twjichou_given", "phaseUseAfter"); }, - ai:{ - order:0.9, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(target.hasJudge('lebu')) return 0; - return target.getCards('h',card=>player.getStorage('twjichou').includes(get.name(card))).reduce((p,c)=>p+(target.getUseValue(c)||1),0); - } + ai: { + order: 0.9, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (target.hasJudge("lebu")) return 0; + return target + .getCards("h", (card) => + player.getStorage("twjichou").includes(get.name(card)) + ) + .reduce((p, c) => p + (target.getUseValue(c) || 1), 0); + }, }, - } + }, }, - } + }, }, - twjilun:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - 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(name=>{ - return !player.getStorage('twjilun').includes(name)&&player.hasUseTarget({name:name}); - }).length==0) - choiceList[1]=''+choiceList[1]+''; - else choices.push('选项二'); - player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('prompt',get.prompt('twjilun')).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('twjilun').includes(name)) continue; - if(player.getUseValue({name:name})>4*val) return 1; - } - return 0; - }).set('num',num); - 'step 1' - if(result.control!='cancel2'){ - if(result.control=='选项一'){ - player.logSkill('twjilun'); + twjilun: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + 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((name) => { + return ( + !player.getStorage("twjilun").includes(name) && + player.hasUseTarget({ name: name }) + ); + }).length == 0 + ) + choiceList[1] = '' + choiceList[1] + ""; + else choices.push("选项二"); + player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("twjilun")) + .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("twjilun").includes(name)) continue; + if (player.getUseValue({ name: name }) > 4 * val) return 1; + } + return 0; + }) + .set("num", num); + "step 1"; + if (result.control != "cancel2") { + if (result.control == "选项一") { + player.logSkill("twjilun"); player.draw(num); event.finish(); - } - else{ - var list=[]; - for(var name of player.getStorage('twjichou')){ - if(!player.getStorage('twjilun').includes(name)){ - list.push(['锦囊','',name]); + } else { + var list = []; + for (var name of player.getStorage("twjichou")) { + if (!player.getStorage("twjilun").includes(name)) { + list.push(["锦囊", "", name]); } } - player.chooseButton(['###机论###
              是否视为使用一张〖急筹〗已记录的普通锦囊牌?
              ',[list,'vcard']]).set('filterButton',button=>{ - return _status.event.player.hasUseTarget({name:button.link[2]}); - }).set('ai',button=>{ - return _status.event.getParent().player.getUseValue({name:button.link[2]},null,true); - }); + player + .chooseButton([ + '###机论###
              是否视为使用一张〖急筹〗已记录的普通锦囊牌?
              ', + [list, "vcard"], + ]) + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget({ name: button.link[2] }); + }) + .set("ai", (button) => { + return _status.event + .getParent() + .player.getUseValue({ name: button.link[2] }, null, true); + }); } } else event.finish(); - 'step 2' - if(result.bool){ - var card={name:result.links[0][2],isCard:true}; - player.chooseUseTarget(card,true).set('logSkill','twjilun'); - player.markAuto('twjilun',[card.name]); - player.syncStorage('twjilun'); + "step 2"; + if (result.bool) { + var card = { name: result.links[0][2], isCard: true }; + player.chooseUseTarget(card, true).set("logSkill", "twjilun"); + player.markAuto("twjilun", [card.name]); + player.syncStorage("twjilun"); } else event.goto(0); }, - marktext:'论', - intro:{ - markcount:function(storage,player){ - if(storage&&storage.length) return storage.length; + marktext: "论", + intro: { + markcount: function (storage, player) { + if (storage && storage.length) return storage.length; return 0; }, - content:'已记录牌名:$', + content: "已记录牌名:$", + }, + ai: { + maixie: true, + maixie_defend: true, + threaten: 0.7, }, - ai:{ - maixie:true, - maixie_defend:true, - threaten:0.7, - } }, //蹇硕 - twkunsi:{ - audio:2, - enable:'phaseUse', - onremove:true, - derivation:'twlinglu', - filter:function(event,player){ - return game.hasPlayer(function(current){ - return player.canUse({name:'sha',isCard:true},current,false)&¤t!=player&&!player.getStorage('twkunsi').includes(current); + twkunsi: { + audio: 2, + enable: "phaseUse", + onremove: true, + derivation: "twlinglu", + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + player.canUse({ name: "sha", isCard: true }, current, false) && + current != player && + !player.getStorage("twkunsi").includes(current) + ); }); }, - filterTarget:function(card,player,target){ - return player.canUse({name:'sha',isCard:true},target,false)&&target!=player&&!player.getStorage('twkunsi').includes(target); + filterTarget: function (card, player, target) { + return ( + player.canUse({ name: "sha", isCard: true }, target, false) && + target != player && + !player.getStorage("twkunsi").includes(target) + ); }, - content:function(){ - 'step 0' - player.markAuto('twkunsi',[target]); + content: function () { + "step 0"; + player.markAuto("twkunsi", [target]); player.storage.twkunsi.sortBySeat(); - player.markSkill('twkunsi'); - player.useCard({name:'sha',isCard:true},target,false).animate=false; - 'step 1' - if(!player.hasHistory('sourceDamage',function(evt){ - var card=evt.card; - if(!card||card.name!='sha') return false; - var evtx=evt.getParent('useCard'); - return evtx.card==card&&evtx.getParent()==event; - })){ + player.markSkill("twkunsi"); + player.useCard({ name: "sha", isCard: true }, target, false).animate = false; + "step 1"; + if ( + !player.hasHistory("sourceDamage", function (evt) { + var card = evt.card; + if (!card || card.name != "sha") return false; + var evtx = evt.getParent("useCard"); + return evtx.card == card && evtx.getParent() == event; + }) + ) { player.line(target); - target.markAuto('twlinglu',[player]); - target.addAdditionalSkills('twkunsi_temp','twlinglu'); - player.markAuto('twkunsi_clear',[target]); - player.addTempSkill('twkunsi_clear',{player:'phaseBegin'}); + target.markAuto("twlinglu", [player]); + target.addAdditionalSkills("twkunsi_temp", "twlinglu"); + player.markAuto("twkunsi_clear", [target]); + player.addTempSkill("twkunsi_clear", { player: "phaseBegin" }); } }, - intro:{content:'已对$发动过〖困兕〗'}, - ai:{ - order:function(){ - return get.order({name:'sha'})-0.1; + intro: { content: "已对$发动过〖困兕〗" }, + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.1; }, - expose:0.2, - result:{ - target:function(player,target){ - if(target.countCards('h')<=target.hp&&!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&get.effect(target,{name:'sha',isCard:true},player,player)>0) return -1; - else if(target.countCards('h')>target.hp&&target.hp>2&&target.hasShan()) return 1; + expose: 0.2, + result: { + target: function (player, target) { + if ( + target.countCards("h") <= target.hp && + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + get.effect(target, { name: "sha", isCard: true }, player, player) > 0 + ) + return -1; + else if (target.countCards("h") > target.hp && target.hp > 2 && target.hasShan()) + return 1; return 0; }, }, }, - subSkill:{ - clear:{ - forced:true, - onremove:function(player,skill){ - var targets=player.getStorage(skill); - for(var target of targets){ - if(target.isIn()){ - target.removeAdditionalSkill('twkunsi_temp'); + subSkill: { + clear: { + forced: true, + onremove: function (player, skill) { + var targets = player.getStorage(skill); + for (var target of targets) { + if (target.isIn()) { + target.removeAdditionalSkill("twkunsi_temp"); } } }, }, }, }, - twlinglu:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player; + twlinglu: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player; }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twlinglu'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.countCards('hs')>4&&target.hp>=3) return att; - if(player.getStorage('twlinglu').includes(target)) return -2*att; - return -att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twlinglu',target); - target.addTempSkill('twlinglu_order',{player:'phaseAfter'}); - if(!target.storage.twlinglu_settle) target.storage.twlinglu_settle=[]; - target.storage.twlinglu_settle.unshift([player,1]); - if(player.getStorage('twlinglu').includes(target)) player.chooseBool('是否令'+get.translation(target)+'于〖令戮〗失败时进行两次结算?').set('ai',function(){return true}); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twlinglu"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.countCards("hs") > 4 && target.hp >= 3) return att; + if (player.getStorage("twlinglu").includes(target)) return -2 * att; + return -att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twlinglu", target); + target.addTempSkill("twlinglu_order", { player: "phaseAfter" }); + if (!target.storage.twlinglu_settle) target.storage.twlinglu_settle = []; + target.storage.twlinglu_settle.unshift([player, 1]); + if (player.getStorage("twlinglu").includes(target)) + player + .chooseBool( + "是否令" + get.translation(target) + "于〖令戮〗失败时进行两次结算?" + ) + .set("ai", function () { + return true; + }); else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ + } else event.finish(); + "step 2"; + if (result.bool) { target.storage.twlinglu_settle[0][1]++; - game.log(target,'于本次强令失败时进行两次结算'); + game.log(target, "于本次强令失败时进行两次结算"); } }, - ai:{expose:0.2}, - subSkill:{ - order:{ - audio:2, - trigger:{source:'damageSource'}, - group:'twlinglu_settle', - silent:true, - charlotte:true, - onremove:true, - mark:true, - marktext:'令', - intro:{ - content:function(storage,player){ - return '
            • 任务目标:于你下回合结束前造成的伤害不小于2点
            • 已造成'+player.countMark('twlinglu_order')+'点伤害'; - } + ai: { expose: 0.2 }, + subSkill: { + order: { + audio: 2, + trigger: { source: "damageSource" }, + group: "twlinglu_settle", + silent: true, + charlotte: true, + onremove: true, + mark: true, + marktext: "令", + intro: { + content: function (storage, player) { + return ( + "
            • 任务目标:于你下回合结束前造成的伤害不小于2点
            • 已造成" + + player.countMark("twlinglu_order") + + "点伤害" + ); + }, }, - content:function(){ - player.addMark('twlinglu_order',trigger.num,false); + content: function () { + player.addMark("twlinglu_order", trigger.num, false); }, }, - settle:{ - audio:'twlinglu_order', - trigger:{player:'phaseEnd'}, - charlotte:true, - silent:true, - onremove:true, - filter:function(event,player){ - return player.getStorage('twlinglu_settle').length>0; + settle: { + audio: "twlinglu_order", + trigger: { player: "phaseEnd" }, + charlotte: true, + silent: true, + onremove: true, + filter: function (event, player) { + return player.getStorage("twlinglu_settle").length > 0; }, - content:function(){ - 'step 0' - var list=player.getStorage('twlinglu_settle').shift(); - var target=list[0],count=list[1]||1; - event.target=target; event.count=count; - 'step 1' - if(player.countMark('twlinglu_order')>=2){ - game.log(player,'成功完成了',target,'发布的','#g【令戮】','强令'); - player.popup('强令成功','wood'); + content: function () { + "step 0"; + var list = player.getStorage("twlinglu_settle").shift(); + var target = list[0], + count = list[1] || 1; + event.target = target; + event.count = count; + "step 1"; + if (player.countMark("twlinglu_order") >= 2) { + game.log(player, "成功完成了", target, "发布的", "#g【令戮】", "强令"); + player.popup("强令成功", "wood"); player.draw(2); event.finish(); + } else { + game.log(player, "未完成", target, "发布的", "#g【令戮】", "强令"); + player.popup("强令失败", "fire"); } - else{ - game.log(player,'未完成',target,'发布的','#g【令戮】','强令'); - player.popup('强令失败','fire'); - } - 'step 2' - if(player.countMark('twlinglu_order')>=2){ + "step 2"; + if (player.countMark("twlinglu_order") >= 2) { game.delayx(); - } - else{ + } else { event.count--; player.loseHp(); } - 'step 3' - if(event.count>0) event.goto(2); - 'step 4' - if(player.getStorage('twlinglu_settle').length>0){ + "step 3"; + if (event.count > 0) event.goto(2); + "step 4"; + if (player.getStorage("twlinglu_settle").length > 0) { event.goto(0); game.delayx(); } }, - } + }, }, }, //马腾 - twxiongzheng:{ - audio:2, - onremove:true, - trigger:{global:'roundStart'}, - direct:true, - content:function(){ - 'step 0' - var target=player.storage.twxiongzheng_target; + twxiongzheng: { + audio: 2, + onremove: true, + trigger: { global: "roundStart" }, + direct: true, + content: function () { + "step 0"; + var target = player.storage.twxiongzheng_target; delete player.storage.twxiongzheng_target; - if(!target){event.goto(4);return;} - event.target=target; - var list=[],list2=[]; - var history=target.actionHistory; - if(history.length<2){event.goto(4);return;} - for(var i=history.length-2;i>=0;i--){ - for(var evt of history[i].damage){ - if(evt.source) list.add(evt.source); + if (!target) { + event.goto(4); + return; + } + event.target = target; + var list = [], + list2 = []; + var history = target.actionHistory; + if (history.length < 2) { + event.goto(4); + return; + } + for (var i = history.length - 2; i >= 0; i--) { + for (var evt of history[i].damage) { + if (evt.source) list.add(evt.source); } - if(history[i].isRound) break; + if (history[i].isRound) break; } - var list2=game.filterPlayer(i=>i!=player).removeArray(list); - event.list=list; event.list2=list2; - var choiceList=[ - '视为对任意名上一轮未对'+get.translation(target)+'造成过伤害的角色使用一张【杀】', - '令任意名上一轮对'+get.translation(target)+'造成过伤害的角色摸两张牌' + var list2 = game.filterPlayer((i) => i != player).removeArray(list); + event.list = list; + event.list2 = list2; + var choiceList = [ + "视为对任意名上一轮未对" + get.translation(target) + "造成过伤害的角色使用一张【杀】", + "令任意名上一轮对" + get.translation(target) + "造成过伤害的角色摸两张牌", ]; - var choices=[]; - if(list2.length){ - choices.push('选项一'); - choiceList[0]+='('+get.translation(list2)+')'; - } - else choiceList[0]=''+choiceList[0]+''; - if(list.length){ - choices.push('选项二'); - choiceList[1]+='('+get.translation(list)+')'; - } - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('prompt','雄争:是否选择一项?').set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player; - var list=_status.event.getParent().list,list2=_status.event.getParent().list2; - var eff=list.map(target=>{ - if(target==player) return 0; - return get.effect(target,{name:'sha'},player,player); - }).reduce((p,c)=>p+c,0),eff2=list2.map(target=>2*get.effect(target,{name:'draw'},player,player)).reduce((p,c)=>p+c,0); - if(_status.event.controls.includes('选项二')&&eff2>eff) return '选项二'; - if(eff>0) return 0; - return 'cancel2'; - }); - 'step 1' - if(result.control=='选项一'){ - event.bool=true; - if(event.list2.length) player.chooseTarget('雄争:请选择任意名满足条件的角色,你视为依次对这些角色使用一张杀',[1,Infinity],true,function(card,player,target){ - return player.canUse('sha',target,false,false)&&_status.event.getParent().list2.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); + var choices = []; + if (list2.length) { + choices.push("选项一"); + choiceList[0] += "(" + get.translation(list2) + ")"; + } else choiceList[0] = '' + choiceList[0] + ""; + if (list.length) { + choices.push("选项二"); + choiceList[1] += "(" + get.translation(list) + ")"; + } else choiceList[1] = '' + choiceList[1] + ""; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("prompt", "雄争:是否选择一项?") + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player; + var list = _status.event.getParent().list, + list2 = _status.event.getParent().list2; + var eff = list + .map((target) => { + if (target == player) return 0; + return get.effect(target, { name: "sha" }, player, player); + }) + .reduce((p, c) => p + c, 0), + eff2 = list2 + .map((target) => 2 * get.effect(target, { name: "draw" }, player, player)) + .reduce((p, c) => p + c, 0); + if (_status.event.controls.includes("选项二") && eff2 > eff) return "选项二"; + if (eff > 0) return 0; + return "cancel2"; }); + "step 1"; + if (result.control == "选项一") { + event.bool = true; + if (event.list2.length) + player + .chooseTarget( + "雄争:请选择任意名满足条件的角色,你视为依次对这些角色使用一张杀", + [1, Infinity], + true, + function (card, player, target) { + return ( + player.canUse("sha", target, false, false) && + _status.event.getParent().list2.includes(target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }); else event.finish(); - } - else if(result.control=='选项二'){ - event.bool=false; - if(event.list.length) player.chooseTarget('雄争:请选择任意名满足条件的角色,这些角色摸两张牌',[1,Infinity],true,function(card,player,target){ - return _status.event.getParent().list.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'draw'},player,player); - }); + } else if (result.control == "选项二") { + event.bool = false; + if (event.list.length) + player + .chooseTarget( + "雄争:请选择任意名满足条件的角色,这些角色摸两张牌", + [1, Infinity], + true, + function (card, player, target) { + return _status.event.getParent().list.includes(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "draw" }, player, player); + }); else event.finish(); - } - else event.goto(3); - 'step 2' + } else event.goto(3); + "step 2"; result.targets.sortBySeat(); - player.logSkill('twxiongzheng',result.targets); - if(event.bool){ - for(var i of result.targets) player.useCard({name:'sha',isCard:true},i,false); - } - else game.asyncDraw(result.targets,2); - 'step 3' - if(!game.hasPlayer(function(current){ - return !player.getStorage('twxiongzheng').includes(current); - })) event.finish(); + player.logSkill("twxiongzheng", result.targets); + if (event.bool) { + for (var i of result.targets) player.useCard({ name: "sha", isCard: true }, i, false); + } else game.asyncDraw(result.targets, 2); + "step 3"; + if ( + !game.hasPlayer(function (current) { + return !player.getStorage("twxiongzheng").includes(current); + }) + ) + event.finish(); else game.delayx(); - 'step 4' - player.chooseTarget(get.prompt('twxiongzheng'),'选择一名未选择过的角色,称为“雄争”角色',function(card,player,target){ - return !player.getStorage('twxiongzheng').includes(target); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(game.roundNumber<=1&&player.hasUnknown()) return 0; - return -att; - }); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twxiongzheng',target); - player.markAuto('twxiongzheng',[target]); - player.storage.twxiongzheng_target=target; - player.addTempSkill('twxiongzheng_mark','roundStart'); - target.addTempSkill('twxiongzheng_threaten','roundStart'); + "step 4"; + player + .chooseTarget( + get.prompt("twxiongzheng"), + "选择一名未选择过的角色,称为“雄争”角色", + function (card, player, target) { + return !player.getStorage("twxiongzheng").includes(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (game.roundNumber <= 1 && player.hasUnknown()) return 0; + return -att; + }); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twxiongzheng", target); + player.markAuto("twxiongzheng", [target]); + player.storage.twxiongzheng_target = target; + player.addTempSkill("twxiongzheng_mark", "roundStart"); + target.addTempSkill("twxiongzheng_threaten", "roundStart"); game.delayx(); } }, - subSkill:{ - mark:{ - intro:{ - content:'$参与了〖雄争〗的争斗', - onunmark:true, + subSkill: { + mark: { + intro: { + content: "$参与了〖雄争〗的争斗", + onunmark: true, }, - charlotte:true, - onremove:true, - trigger:{global:'damage'}, - firstDo:true, - direct:true, - filter:function(event,player){ - return event.player==player.storage.twxiongzheng_target&&get.itemtype(event.source)=='player'; + charlotte: true, + onremove: true, + trigger: { global: "damage" }, + firstDo: true, + direct: true, + filter: function (event, player) { + return ( + event.player == player.storage.twxiongzheng_target && + get.itemtype(event.source) == "player" + ); }, - content:function(){ - player.markAuto('twxiongzheng_mark',[trigger.source]); + content: function () { + player.markAuto("twxiongzheng_mark", [trigger.source]); }, }, - threaten:{ - mark:true, - intro:{content:'本轮〖雄争〗目标'}, - ai:{threaten:10}, + threaten: { + mark: true, + intro: { content: "本轮〖雄争〗目标" }, + ai: { threaten: 10 }, }, }, }, - twluannian:{ - audio:2, - global:'twluannian_global', - unique:true, - zhuSkill:true, - subSkill:{ - global:{ - audio:'twluannian', - enable:'phaseUse', - usable:1, - forceaudio:true, - onChooseToUse:function(event){ - if(!game.online){ - var num=1; - game.countPlayer2(current=>{ - var history=current.actionHistory; - for(var i=history.length-1;i>=0;i--){ - for(var evt of history[i].useSkill){ - if(evt.skill=='twluannian_global') num++; + twluannian: { + audio: 2, + global: "twluannian_global", + unique: true, + zhuSkill: true, + subSkill: { + global: { + audio: "twluannian", + enable: "phaseUse", + usable: 1, + forceaudio: true, + onChooseToUse: function (event) { + if (!game.online) { + var num = 1; + game.countPlayer2((current) => { + var history = current.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + for (var evt of history[i].useSkill) { + if (evt.skill == "twluannian_global") num++; } - if(history[i].isRound) break; + if (history[i].isRound) break; } }); - event.set('twluannian_num',num); + event.set("twluannian_num", num); } }, - filter:function(event,player){ - if(!event.twluannian_num) return false; - return player.group=='qun'&&player.countCards('he')>=event.twluannian_num&&game.hasPlayer(function(current){ - var target=current.storage.twxiongzheng_target; - return target&&target.isIn()&¤t!=player&¤t.hasZhuSkill('twluannian',player) - }) + filter: function (event, player) { + if (!event.twluannian_num) return false; + return ( + player.group == "qun" && + player.countCards("he") >= event.twluannian_num && + game.hasPlayer(function (current) { + var target = current.storage.twxiongzheng_target; + return ( + target && + target.isIn() && + current != player && + current.hasZhuSkill("twluannian", player) + ); + }) + ); }, - filterCard:true, - position:'he', - prompt:function(){ - var player=_status.event.player; - var num=_status.event.twluannian_num - var list=game.filterPlayer(function(current){ - return current.hasZhuSkill('twluannian',player); - }).map(i=>i.storage.twxiongzheng_target).sortBySeat(); - return '弃置'+get.cnNumber(num)+'张牌,对'+get.translation(list)+(list.length>1?'中的一人':'')+'造成1点伤害'; + filterCard: true, + position: "he", + prompt: function () { + var player = _status.event.player; + var num = _status.event.twluannian_num; + var list = game + .filterPlayer(function (current) { + return current.hasZhuSkill("twluannian", player); + }) + .map((i) => i.storage.twxiongzheng_target) + .sortBySeat(); + return ( + "弃置" + + get.cnNumber(num) + + "张牌,对" + + get.translation(list) + + (list.length > 1 ? "中的一人" : "") + + "造成1点伤害" + ); }, - selectCard:function(){ + selectCard: function () { return _status.event.twluannian_num; }, - complexSelect:true, - complexCard:true, - filterTarget:function(card,player,target){ - return game.filterPlayer(function(current){ - return current.hasZhuSkill('twluannian',player); - }).map(i=>i.storage.twxiongzheng_target).includes(target); + complexSelect: true, + complexCard: true, + filterTarget: function (card, player, target) { + return game + .filterPlayer(function (current) { + return current.hasZhuSkill("twluannian", player); + }) + .map((i) => i.storage.twxiongzheng_target) + .includes(target); }, - selectTarget:function(){ - return game.filterPlayer(function(current){ - return current.hasZhuSkill('twluannian',_status.event.player); - }).map(i=>i.storage.twxiongzheng_target).filter(i=>i&&i.isIn()).length>1?1:-1; + selectTarget: function () { + return game + .filterPlayer(function (current) { + return current.hasZhuSkill("twluannian", _status.event.player); + }) + .map((i) => i.storage.twxiongzheng_target) + .filter((i) => i && i.isIn()).length > 1 + ? 1 + : -1; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - content:function(){ + content: function () { target.damage(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); - } + ai: { + order: 7, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); + }, }, - expose:0.25, + expose: 0.25, }, }, }, }, //鲍信 - twmutao:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('h'); + twmutao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("h"); }, - content:function(){ - 'step 0' - event.togive=target.getNext(); - var cards=target.getCards('h',{name:'sha'}); - if(!cards.length){ - game.log('但',target,'没有','#y杀','!'); + content: function () { + "step 0"; + event.togive = target.getNext(); + var cards = target.getCards("h", { name: "sha" }); + if (!cards.length) { + game.log("但", target, "没有", "#y杀", "!"); event.finish(); } - 'step 1' - var cards=target.getCards('h',{name:'sha'}),card=cards.randomRemove(1)[0]; - target.give(card,event.togive); - if(cards.length){ - event.togive=event.togive.getNext(); + "step 1"; + var cards = target.getCards("h", { name: "sha" }), + card = cards.randomRemove(1)[0]; + target.give(card, event.togive); + if (cards.length) { + event.togive = event.togive.getNext(); event.redo(); } - 'step 2' + "step 2"; target.line(event.togive); - event.togive.damage(Math.min(2,event.togive.countCards('h',{name:'sha'})),target); + event.togive.damage(Math.min(2, event.togive.countCards("h", { name: "sha" })), target); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - var num=0,numx=target.countCards('h',{name:'sha'}),targetx=target; - for(var i=0; i0&&att2<0) num=0.25; - if(att1<0&&att2<0) num=4; - return att1*num*numx*(targetx.countCards('h',{name:'sha'})+1); + var att1 = get.attitude(player, target), + att2 = get.attitude(player, targetx); + if (att1 > 0 && att2 < 0) num = 0.25; + if (att1 < 0 && att2 < 0) num = 4; + return att1 * num * numx * (targetx.countCards("h", { name: "sha" }) + 1); }, }, }, }, - twyimou:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return event.player.isIn()&&get.distance(player,event.player)<=1; + twyimou: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return event.player.isIn() && get.distance(player, event.player) <= 1; }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)>0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - 'step 0' - if(trigger.player!=player) player.addExpose(0.3); - var target=get.translation(trigger.player); - var choiceList=[ - '令'+target+'获得牌堆里的一张【杀】', - '令'+target+'将一张牌交给另一名角色,然后'+target+'摸两张牌', - '背水!'+(trigger.player!=player?'将所有手牌交给'+target+',然后':'')+'依次执行以上所有选项', + content: function () { + "step 0"; + if (trigger.player != player) player.addExpose(0.3); + var target = get.translation(trigger.player); + var choiceList = [ + "令" + target + "获得牌堆里的一张【杀】", + "令" + target + "将一张牌交给另一名角色,然后" + target + "摸两张牌", + "背水!" + + (trigger.player != player ? "将所有手牌交给" + target + ",然后" : "") + + "依次执行以上所有选项", ]; - var list=['选项一']; - if(trigger.player.countCards('h')) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(player.countCards('h')) list.push('背水!'); - else choiceList[2]=''+choiceList[2]+''; - 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.hp>=target.countCards('h')+2||target==player)&&list.includes('背水!')) return '背水!'; - if(target.countCards('h')&&list.includes('选项二')) return '选项二'; - return '选项一'; - }).set('list',list); - 'step 1' - event.choice=result.control; - if(event.choice=='背水!'&&player!=trigger.player) player.give(player.getCards('h'),trigger.player); - 'step 2' - if(event.choice!='选项二'){ - var card=get.cardPile2(function(card){ - return card.name=='sha'; + var list = ["选项一"]; + if (trigger.player.countCards("h")) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (player.countCards("h")) list.push("背水!"); + else choiceList[2] = '' + choiceList[2] + ""; + 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.hp >= target.countCards("h") + 2 || target == player) && + list.includes("背水!") + ) + return "背水!"; + if (target.countCards("h") && list.includes("选项二")) return "选项二"; + return "选项一"; + }) + .set("list", list); + "step 1"; + event.choice = result.control; + if (event.choice == "背水!" && player != trigger.player) + player.give(player.getCards("h"), trigger.player); + "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(); + 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; - }, - }); + "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]; + "step 4"; + var target = result.targets[0]; trigger.player.line(target); - trigger.player.give(result.cards,target); + trigger.player.give(result.cards, target); trigger.player.draw(2); }, - ai:{ - threaten:2.5, + ai: { + threaten: 2.5, }, }, //刘夫人 - twzhuidu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged(); + twzhuidu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isDamaged(); }); }, - filterTarget:function(card,player,target){ - if(player==target) return false; + filterTarget: function (card, player, target) { + if (player == target) return false; return target.isDamaged(); }, - chooseButton:{ - dialog:function(event,player){ - var name=get.translation(event.result.targets[0]); - var dialog=ui.create.dialog('追妒:选择一项','hidden'); - dialog.add([[ - ['damage','对'+name+'造成1点伤害'], - ['discard','弃置'+name+'装备区里的一张牌'], - ['both','背水!若该角色为女性,弃置一张牌,然后依次执行以上所有选项'], - ],'textbutton']); + chooseButton: { + dialog: function (event, player) { + var name = get.translation(event.result.targets[0]); + var dialog = ui.create.dialog("追妒:选择一项", "hidden"); + dialog.add([ + [ + ["damage", "对" + name + "造成1点伤害"], + ["discard", "弃置" + name + "装备区里的一张牌"], + ["both", "背水!若该角色为女性,弃置一张牌,然后依次执行以上所有选项"], + ], + "textbutton", + ]); return dialog; }, - filter:function(button,player){ - var target=_status.event.getParent().result.targets[0]; - var link=button.link; - if(link=='damage') return true; - if(link=='discard') return target.countCards('e'); - return target.hasSex('female')&&player.countDiscardableCards(player,'he')>0; + filter: function (button, player) { + var target = _status.event.getParent().result.targets[0]; + var link = button.link; + if (link == "damage") return true; + if (link == "discard") return target.countCards("e"); + return target.hasSex("female") && player.countDiscardableCards(player, "he") > 0; }, - check:function(button){ - switch (button.link){ - case 'damage': + check: function (button) { + switch (button.link) { + case "damage": return 10; - case 'discard': + case "discard": return 1; - case 'both': + case "both": return 15; } }, - backup:function(links){ - var backup={ - audio:'twzhuidu', - target:_status.event.result.targets[0], - choice:links[0], - filterTarget:function(card,player,target){ - return target==lib.skill.twzhuidu_backup.target; + backup: function (links) { + var backup = { + audio: "twzhuidu", + target: _status.event.result.targets[0], + choice: links[0], + filterTarget: function (card, player, target) { + return target == lib.skill.twzhuidu_backup.target; }, - selectTarget:-1, - content:function(){ - var target=lib.skill.twzhuidu_backup.target; - var choice=lib.skill.twzhuidu_backup.choice; - if(choice!='discard') target.damage(); - if(choice!='damage') player.discardPlayerCard(target,'e',true); - } - } - if(links[0]=='both'){ - backup.filterCard=true; - backup.position='he'; + selectTarget: -1, + content: function () { + var target = lib.skill.twzhuidu_backup.target; + var choice = lib.skill.twzhuidu_backup.choice; + if (choice != "discard") target.damage(); + if (choice != "damage") player.discardPlayerCard(target, "e", true); + }, + }; + if (links[0] == "both") { + backup.filterCard = true; + backup.position = "he"; } return backup; }, - prompt:function(links){ - var name=get.translation(_status.event.result.targets[0]); - switch (links[0]){ - case 'damage': - return '对'+name+'造成1点伤害'; - case 'discard': - return '弃置'+name+'装备区里的一张牌'; - case 'both': - return '背水!弃置一张牌,然后对'+name+'造成1点伤害并弃置其装备区里的一张牌'; + prompt: function (links) { + var name = get.translation(_status.event.result.targets[0]); + switch (links[0]) { + case "damage": + return "对" + name + "造成1点伤害"; + case "discard": + return "弃置" + name + "装备区里的一张牌"; + case "both": + return ( + "背水!弃置一张牌,然后对" + name + "造成1点伤害并弃置其装备区里的一张牌" + ); } }, }, - subSkill:{ - backup:{}, + subSkill: { + backup: {}, }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(target.hasSex('female')&&target.countCards('e')&&player.countCards('he')) return -2; + ai: { + order: 7, + result: { + target: function (player, target) { + if (target.hasSex("female") && target.countCards("e") && player.countCards("he")) + return -2; return -1; }, }, }, }, - twshigong:{ - audio:2, - trigger:{player:'dying'}, - filter:function(event,player){ - var target=_status.currentPhase; - return player.hp<=0&&target&&target.isIn()&&target!=player; + twshigong: { + audio: 2, + trigger: { player: "dying" }, + filter: function (event, player) { + var target = _status.currentPhase; + return player.hp <= 0 && target && target.isIn() && target != player; }, - skillAnimation:true, - animationColor:'gray', - limited:true, - logTarget:function(event,player){ + skillAnimation: true, + animationColor: "gray", + limited: true, + logTarget: function (event, player) { return _status.currentPhase; }, - content:function(){ - 'step 0' - player.awakenSkill('twshigong'); - var target=_status.currentPhase; - if(target.hp<=0) event._result={bool:false}; - else target.chooseToDiscard('h',target.hp,get.translation(player)+'对你发动了【示恭】,是否弃置'+get.cnNumber(target.hp)+'张手牌?','若如此做,其将体力回复至1点;或者点击“取消”加1点体力上限并回复1点体力,摸一张牌,然后其将体力回复至体力上限').set('ai',card=>{ - if(!_status.event.goon) return 0; - return 7-get.value(card); - }).set('goon',get.attitude(target,player)>=0); - 'step 1' - var target=_status.currentPhase; - if(result.bool){ - var num=1-player.hp; - if(num>0) player.recover(num); + content: function () { + "step 0"; + player.awakenSkill("twshigong"); + var target = _status.currentPhase; + if (target.hp <= 0) event._result = { bool: false }; + else + target + .chooseToDiscard( + "h", + target.hp, + get.translation(player) + + "对你发动了【示恭】,是否弃置" + + get.cnNumber(target.hp) + + "张手牌?", + "若如此做,其将体力回复至1点;或者点击“取消”加1点体力上限并回复1点体力,摸一张牌,然后其将体力回复至体力上限" + ) + .set("ai", (card) => { + if (!_status.event.goon) return 0; + return 7 - get.value(card); + }) + .set("goon", get.attitude(target, player) >= 0); + "step 1"; + var target = _status.currentPhase; + if (result.bool) { + var num = 1 - player.hp; + if (num > 0) player.recover(num); event.finish(); - } - else{ + } else { target.gainMaxHp(); target.recover(); target.draw(); } - 'step 2' - var num=player.maxHp-player.hp; - if(num>0) player.recover(num); + "step 2"; + var num = player.maxHp - player.hp; + if (num > 0) player.recover(num); }, }, //王淩 - twmibei:{ - audio:'mibei', - trigger:{player:'useCardAfter'}, - group:['twmibei_mark','twmibei_fail'], - forced:true, - locked:false, - direct:true, - dutySkill:true, - derivation:'twmouli', - filter:function(event,player){ - var map={basic:0,trick:0,equip:0}; - for(var name of player.getStorage('twmibei')){ - var type=get.type2(name); - if(typeof map[type]=='number') map[type]++; + twmibei: { + audio: "mibei", + trigger: { player: "useCardAfter" }, + group: ["twmibei_mark", "twmibei_fail"], + forced: true, + locked: false, + direct: true, + dutySkill: true, + derivation: "twmouli", + filter: function (event, player) { + var map = { basic: 0, trick: 0, equip: 0 }; + for (var name of player.getStorage("twmibei")) { + var type = get.type2(name); + if (typeof map[type] == "number") map[type]++; } - for(var i in map){ - if(map[i]<2) return false; + for (var i in map) { + if (map[i] < 2) return false; } return true; }, - content:function(){ - player.awakenSkill('twmibei'); - player.logSkill('twmibei_achieve'); - game.log(player,'成功完成使命'); - player.addSkills('twmouli'); + content: function () { + player.awakenSkill("twmibei"); + player.logSkill("twmibei_achieve"); + game.log(player, "成功完成使命"); + player.addSkills("twmouli"); }, - intro:{content:'已使用牌名:$'}, - subSkill:{ - achieve:{ - audio:'mibei1', - skillAnimation:true, - animationColor:'water', + intro: { content: "已使用牌名:$" }, + subSkill: { + achieve: { + audio: "mibei1", + skillAnimation: true, + animationColor: "water", }, - mark:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - return !player.getStorage('twmibei').includes(event.card.name); + mark: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + return !player.getStorage("twmibei").includes(event.card.name); }, - charlotte:true, - forced:true, - silent:true, - dutySkill:true, - content:function(){ - player.markAuto('twmibei',[trigger.card.name]); + charlotte: true, + forced: true, + silent: true, + dutySkill: true, + content: function () { + player.markAuto("twmibei", [trigger.card.name]); }, }, - fail:{ - audio:'mibei2', - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - return !player.getHistory('useCard').length; + fail: { + audio: "mibei2", + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + return !player.getHistory("useCard").length; }, - content:function(){ - game.log(player,'使命失败'); + content: function () { + game.log(player, "使命失败"); delete player.storage.twmibei; - player.addTempSkill('twmibei_less'); - player.addMark('twmibei_less',1,false); + player.addTempSkill("twmibei_less"); + player.addMark("twmibei_less", 1, false); }, }, - less:{ - charlotte:true, - marktext:'缚', - intro:{content:'本回合手牌上限-#'}, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('twmibei_less'); + less: { + charlotte: true, + marktext: "缚", + intro: { content: "本回合手牌上限-#" }, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("twmibei_less"); }, }, }, }, }, - twxingqi:{ - audio:'xingqi', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - var num=0; - game.countPlayer(function(current){ - num+=current.countCards('ej'); + twxingqi: { + audio: "xingqi", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + var num = 0; + game.countPlayer(function (current) { + num += current.countCards("ej"); }); - return num>player.hp; + return num > player.hp; }, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - player.awakenSkill('twxingqi'); + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + player.awakenSkill("twxingqi"); player.recover(); - if(!player.awakenedSkills.includes('twmibei')){ - var list=['basic','equip','trick'],cards=[]; - for(var i of list){ - var card=get.cardPile2(function(card){ - return get.type(card)==i; + if (!player.awakenedSkills.includes("twmibei")) { + var list = ["basic", "equip", "trick"], + cards = []; + for (var i of list) { + var card = get.cardPile2(function (card) { + return get.type(card) == i; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); - } - else player.addSkill('twxingqi_range'); + if (cards.length) player.gain(cards, "gain2"); + } else player.addSkill("twxingqi_range"); }, - subSkill:{ - range:{ - charlotte:true, - mark:true, - marktext:'启', - mod:{ - targetInRange:()=>true, + subSkill: { + range: { + charlotte: true, + mark: true, + marktext: "启", + mod: { + targetInRange: () => true, }, - intro:{content:'使用牌无距离限制'}, + intro: { content: "使用牌无距离限制" }, }, }, }, - twmouli:{ - audio:'mouli', - enable:'chooseToUse', - filter:function(event,player){ - if(event.type=='wuxie') return false; - if(player.hasSkill('twmouli_used')) return false; - if(!Array.isArray(event.twmouli)) return false; - for(var card of event.twmouli){ - if(event.filterCard(card,player,event)) return true; + twmouli: { + audio: "mouli", + enable: "chooseToUse", + filter: function (event, player) { + if (event.type == "wuxie") return false; + if (player.hasSkill("twmouli_used")) return false; + if (!Array.isArray(event.twmouli)) return false; + for (var card of event.twmouli) { + if (event.filterCard(card, player, event)) return true; } return false; }, - onChooseToUse:function(event){ - if(game.online||!event.player.hasSkill('twmouli')) return; - var cards=[]; - for(var i=0;ifalse, - selectCard:-1, - viewAs:{name:links[0].name,isCard:true,cards:[links[0]]}, - popname:true, - precontent:function(){ - player.logSkill('twmouli'); - player.addTempSkill('twmouli_used'); + audio: "mouli", + filterCard: () => false, + selectCard: -1, + viewAs: { name: links[0].name, isCard: true, cards: [links[0]] }, + popname: true, + precontent: function () { + player.logSkill("twmouli"); + player.addTempSkill("twmouli_used"); delete event.result.skill; - var name=event.result.card.name; - event.result.cards=event.result.card.cards; - event.result.card=get.autoViewAs(event.result.cards[0]); - event.result.card.name=name; - var next=game.createEvent('twmouli_update'); + var name = event.result.card.name; + event.result.cards = event.result.card.cards; + event.result.card = get.autoViewAs(event.result.cards[0]); + event.result.card.name = name; + var next = game.createEvent("twmouli_update"); event.next.remove(next); event.getParent().after.push(next); - next.setContent(function(){game.updateRoundNumber()}); + next.setContent(function () { + game.updateRoundNumber(); + }); }, - } + }; }, - prompt:function(links,player){ - return '使用牌堆中的'+get.translation(links); + prompt: function (links, player) { + return "使用牌堆中的" + get.translation(links); }, }, - hiddenCard:function(player,name){ - return get.type(name)=='basic'&&!player.getStat('skill').twmouli; + hiddenCard: function (player, name) { + return get.type(name) == "basic" && !player.getStat("skill").twmouli; }, - subSkill:{ - used:{charlotte:true}, + subSkill: { + used: { charlotte: true }, }, - ai:{ - effect:{ - target:function(card,player,target,effect){ - if(get.tag(card,'respondShan')) return 0.7; - if(get.tag(card,'respondSha')) return 0.7; + ai: { + effect: { + target: function (card, player, target, effect) { + if (get.tag(card, "respondShan")) return 0.7; + if (get.tag(card, "respondSha")) return 0.7; }, }, - order:11, - respondSha:true, - respondShan:true, - fireAttack:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - var list=[]; - for(var i=0;icards.some(card=>get.type2(card)==type)); - let fs=game.filterPlayer(i=>get.attitude(_status.event.player,i)>0).sort((a,b)=>{ - if(a===player){//尽量把player往前放 - if(a.hpget.attitude(_status.event.player,i)<0).sort((a,b)=>a.hp-b.hp), - types=list.map(type=>{ - let num=0; - for(let i of event.cards){ - if(get.type2(i)==type) num++; - } - return [type,num]; - }).sort((a,b)=>b[1]-a[1]); - event.tempCache={ - max:-Infinity, - tars:[] + twxingluan: { + audio: "xinfu_xingluan", + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + content: function () { + "step 0"; + event.cards = game.cardsGotoOrdering(get.cards(6)).cards; + event.list = []; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + var str; + if (player == game.me && !_status.auto) str = "兴乱:选择分配一种类别的牌"; + else str = "兴乱"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + event.time = get.utc(); + game.addVideo("showCards", player, ["兴乱", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + "step 1"; + var list = ["basic", "trick", "equip"].filter((type) => + cards.some((card) => get.type2(card) == type) + ); + let fs = game + .filterPlayer((i) => get.attitude(_status.event.player, i) > 0) + .sort((a, b) => { + if (a === player) { + //尽量把player往前放 + if (a.hp < b.hp) return 1; + return -1; + } + if (b === player) { + if (b.hp < a.hp) return -1; + return 1; + } + return b.hp - a.hp; + }), + es = game + .filterPlayer((i) => get.attitude(_status.event.player, i) < 0) + .sort((a, b) => a.hp - b.hp), + types = list + .map((type) => { + let num = 0; + for (let i of event.cards) { + if (get.type2(i) == type) num++; + } + return [type, num]; + }) + .sort((a, b) => b[1] - a[1]); + event.tempCache = { + max: -Infinity, + tars: [], }; - for(let idx=0;idx=type){//都分给敌人 - e=-type; - while(temp= type) { + //都分给敌人 + e = -type; + while (temp < es.length && temp < type) { + e += 10 / (2 + es[temp].hp); tars.push(es[temp]); temp++; } - if(e>event.tempCache.max){ - event.tempCache.type=types[idx][0]; - event.tempCache.max=e; - event.tempCache.tars=tars.slice(0); + if (e > event.tempCache.max) { + event.tempCache.type = types[idx][0]; + event.tempCache.max = e; + event.tempCache.tars = tars.slice(0); delete event.tempCache.more; } } - if(fs.length*3>=type){//都分给队友 - tars=[]; - f=type-10/(2+fs[0].hp); - temp=type-Math.max(3,type);//让血厚的尽可能多拿 - if(temp){ - if(fs.length<3){ + if (fs.length * 3 >= type) { + //都分给队友 + tars = []; + f = type - 10 / (2 + fs[0].hp); + temp = type - Math.max(3, type); //让血厚的尽可能多拿 + if (temp) { + if (fs.length < 3) { tars.push(fs[1]); - if(temp>=3) f-=10/(2+fs[1].hp); - } - else{ - if(player!==fs[0]){ + if (temp >= 3) f -= 10 / (2 + fs[1].hp); + } else { + if (player !== fs[0]) { tars.push(player); - temp-=Math.max(2,temp); + temp -= Math.max(2, temp); } - if(temp) tars.addArray(fs.filter(i=>fs[0]!==i&&player!==i).sort((a,b)=>{ - return get.attitude(_status.event.player,b)-get.attitude(_status.event.player,a); - }).slice(temp<3?-1:-2)); + if (temp) + tars.addArray( + fs + .filter((i) => fs[0] !== i && player !== i) + .sort((a, b) => { + return ( + get.attitude(_status.event.player, b) - + get.attitude(_status.event.player, a) + ); + }) + .slice(temp < 3 ? -1 : -2) + ); } } - if(f>event.tempCache.max){ - event.tempCache.type=types[idx][0]; - event.tempCache.max=f; - event.tempCache.more=fs[0]; - event.tempCache.tars=tars.slice(0); + if (f > event.tempCache.max) { + event.tempCache.type = types[idx][0]; + event.tempCache.max = f; + event.tempCache.more = fs[0]; + event.tempCache.tars = tars.slice(0); } } } - player.chooseControl(list).set('ai',function(){ - return _status.event.type; - }).set('type',event.tempCache.type); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - event.cardsx=[]; - var type=result.control; - for(var j of cards){ - if(type==get.type2(j)) event.cardsx.push(j); + player + .chooseControl(list) + .set("ai", function () { + return _status.event.type; + }) + .set("type", event.tempCache.type); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + event.cardsx = []; + var type = result.control; + for (var j of cards) { + if (type == get.type2(j)) event.cardsx.push(j); } - var time=1000-(get.utc()-event.time); - if(time>0) game.delay(0,time); - player.$gain2(event.cardsx,false); + var time = 1000 - (get.utc() - event.time); + if (time > 0) game.delay(0, time); + player.$gain2(event.cardsx, false); game.delayx(); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - event.num=0; - 'step 3' - if(event.cardsx.length>1){ - player.chooseCardButton('兴乱:请选择要分配的牌',true,event.cardsx,[1,Math.min(3,event.cardsx.length)]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return get.buttonValue(button); - return 0; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cardsx.length==1){ - event._result={links:event.cardsx.slice(0),bool:true}; - } - else{ + event.given_map = {}; + event.num = 0; + "step 3"; + if (event.cardsx.length > 1) { + player + .chooseCardButton("兴乱:请选择要分配的牌", true, event.cardsx, [ + 1, + Math.min(3, event.cardsx.length), + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return get.buttonValue(button); + return 0; + }); + } else if (event.cardsx.length == 1) { + event._result = { links: event.cardsx.slice(0), bool: true }; + } else { event.goto(6); } - 'step 4' - if(result.bool){ - var cards=result.links; - event.togive=cards.slice(0); - player.chooseTarget('选择获得'+get.translation(cards)+'的角色',event.cardsx.length==1,(card,player,target)=>{ - var map=_status.event.getParent().given_map; - var togive=_status.event.getParent().togive; - return (map[target.playerid]||[]).length+togive.length<=3; - }).set('ai',function(target){ - let targets=_status.event.targets,att=get.attitude(_status.event.player,target); - if(targets.length){ - if(targets.includes(target)) return Math.max(1,att*_status.event.value); - return 0; - } - return att*_status.event.value; - }).set('value',cards.reduce((p,c)=>p+get.value(c,player,'raw'),0)).set('more',event.tempCache.more).set('targets',function(){ - let arr=[],arr2=[]; - if(event.tempCache.more&&(event.given_map[event.tempCache.more.playerid]||[]).length+cards.length<=3) return [event.tempCache.more]; - for(let cur of event.tempCache.tars){ - let map=(event.given_map[cur.playerid]||[]).length; - if(map+cards.length<=3){ - if(map) arr2.push(cur); - else arr.push(cur); + "step 4"; + if (result.bool) { + var cards = result.links; + event.togive = cards.slice(0); + player + .chooseTarget( + "选择获得" + get.translation(cards) + "的角色", + event.cardsx.length == 1, + (card, player, target) => { + var map = _status.event.getParent().given_map; + var togive = _status.event.getParent().togive; + return (map[target.playerid] || []).length + togive.length <= 3; } - } - if(arr.length) return arr; - return arr2; - }()); + ) + .set("ai", function (target) { + let targets = _status.event.targets, + att = get.attitude(_status.event.player, target); + if (targets.length) { + if (targets.includes(target)) + return Math.max(1, att * _status.event.value); + return 0; + } + return att * _status.event.value; + }) + .set( + "value", + cards.reduce((p, c) => p + get.value(c, player, "raw"), 0) + ) + .set("more", event.tempCache.more) + .set( + "targets", + (function () { + let arr = [], + arr2 = []; + if ( + event.tempCache.more && + (event.given_map[event.tempCache.more.playerid] || []).length + + cards.length <= + 3 + ) + return [event.tempCache.more]; + for (let cur of event.tempCache.tars) { + let map = (event.given_map[cur.playerid] || []).length; + if (map + cards.length <= 3) { + if (map) arr2.push(cur); + else arr.push(cur); + } + } + if (arr.length) return arr; + return arr2; + })() + ); } - 'step 5' - if(result.bool){ + "step 5"; + if (result.bool) { event.cardsx.removeArray(event.togive); - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(event.cardsx.length>0) event.goto(3); + if (event.cardsx.length > 0) event.goto(3); + } else event.goto(3); + "step 6"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - else event.goto(3); - 'step 6' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - } - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - if(player==source) event.num+=event.given_map[i].length; - player.line(source,'green'); - game.log(source,'获得了',event.given_map[i]); - list.push([source,event.given_map[i]]); + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (player == source) event.num += event.given_map[i].length; + player.line(source, "green"); + game.log(source, "获得了", event.given_map[i]); + list.push([source, event.given_map[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'gain2', - }).setContent('gaincardMultiple'); - 'step 7' - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - if(event.given_map[i].length>=num) list.push(source); + gain_list: list, + giver: player, + animate: "gain2", + }).setContent("gaincardMultiple"); + "step 7"; + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (event.given_map[i].length >= num) list.push(source); } list.sortBySeat(); player.line(list); - for(var i of list){ + for (var i of list) { i.loseHp(); } }, }, //许靖 - twboming:{ - audio:'boming', - enable:'phaseUse', - usable:2, - filter:function(event,player){ - return player.countCards('he'); + twboming: { + audio: "boming", + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + return player.countCards("he"); }, - filterCard:true, - position:'he', - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - content:function(){ - player.give(cards,target); + filterCard: true, + position: "he", + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + content: function () { + player.give(cards, target); }, - check:function(card){ - return 5-get.value(card); + check: function (card) { + return 5 - get.value(card); }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - var card=ui.selected.cards[0]; - if(get.attitude(player,target)<0&&player.hasSkill('twejian')){ - var dam=get.damageEffect(target,player,target); - if(dam>0) return dam; - var type=get.type(card,target),ts=target.getCards('he',function(card){ - return get.type(card)==type; - }); - if(ts.length){ - var val=get.value(ts,target); - if(val>get.value(card)) return -Math.max(1,val); + ai: { + order: 10, + result: { + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + var card = ui.selected.cards[0]; + if (get.attitude(player, target) < 0 && player.hasSkill("twejian")) { + var dam = get.damageEffect(target, player, target); + if (dam > 0) return dam; + var type = get.type(card, target), + ts = target.getCards("he", function (card) { + return get.type(card) == type; + }); + if (ts.length) { + var val = get.value(ts, target); + if (val > get.value(card)) return -Math.max(1, val); return 0; } } - return get.value(card,target)/1.5; + return get.value(card, target) / 1.5; }, }, }, - group:'twboming_draw', - subSkill:{ - draw:{ - audio:'boming', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - var num=0; - for(var target of game.filterPlayer(i=>i!=player)){ - target.getHistory('gain',evt=>num+=evt.cards.length); - if(num>1) return true; + group: "twboming_draw", + subSkill: { + draw: { + audio: "boming", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + var num = 0; + for (var target of game.filterPlayer((i) => i != player)) { + target.getHistory("gain", (evt) => (num += evt.cards.length)); + if (num > 1) return true; } return false; }, - content:function(){ + content: function () { player.draw(2); }, }, }, }, - twejian:{ - audio:'ejian', - trigger:{ - global:['gainAfter','loseAsyncAfter'] + twejian: { + audio: "ejian", + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - if(event.name=='gain'){ - var cards=event.getg(event.player); - if(!cards.length) return false; - var cards2=event.getl(player).cards2; - for(var i of cards2){ - if(cards.includes(i)&&event.player.countCards('he',card=>{ - return card!=i&&get.type2(card)==get.type2(i); - })) return true; + filter: function (event, player) { + if (event.name == "gain") { + var cards = event.getg(event.player); + if (!cards.length) return false; + var cards2 = event.getl(player).cards2; + for (var i of cards2) { + if ( + cards.includes(i) && + event.player.countCards("he", (card) => { + return card != i && get.type2(card) == get.type2(i); + }) + ) + return true; } return false; - } - else{ - if(event.type!='gain') return false; - var cards=event.getl(player).cards2; - if(!cards.length) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; - var cardsx=event.getg(current); - for(var i of cardsx){ - if(cards.includes(i)&¤t.countCards('he',card=>{ - return card!=i&&get.type2(card)==get.type2(i); - })) return true; + } else { + if (event.type != "gain") return false; + var cards = event.getl(player).cards2; + if (!cards.length) return false; + return game.hasPlayer((current) => { + if (current == player) return false; + var cardsx = event.getg(current); + for (var i of cardsx) { + if ( + cards.includes(i) && + current.countCards("he", (card) => { + return card != i && get.type2(card) == get.type2(i); + }) + ) + return true; } return false; }); } }, - logTarget:function(event,player){ - if(event.name=='gain') return event.player; - else{ - var cards=event.getl(player).cards2; - return game.filterPlayer(current=>{ - if(current==player) return false; - var cardsx=event.getg(current); - for(var i of cardsx){ - if(cards.includes(i)&¤t.countCards('he',card=>{ - return card!=i&&get.type2(card)==get.type2(i); - })) return true; + logTarget: function (event, player) { + if (event.name == "gain") return event.player; + else { + var cards = event.getl(player).cards2; + return game.filterPlayer((current) => { + if (current == player) return false; + var cardsx = event.getg(current); + for (var i of cardsx) { + if ( + cards.includes(i) && + current.countCards("he", (card) => { + return card != i && get.type2(card) == get.type2(i); + }) + ) + return true; } return false; }); } }, - direct:true, - content:function(){ - 'step 0' - if(trigger.name=='gain') event.targets=[trigger.player]; - else{ - var cards=trigger.getl(player).cards2; - event.targets=game.filterPlayer(current=>{ - if(current==player) return false; - var cardsx=trigger.getg(current); - for(var i of cardsx){ - if(cards.includes(i)&¤t.countCards('he',card=>{ - return card!=i&&get.type2(card)==get.type2(i); - })) return true; + direct: true, + content: function () { + "step 0"; + if (trigger.name == "gain") event.targets = [trigger.player]; + else { + var cards = trigger.getl(player).cards2; + event.targets = game.filterPlayer((current) => { + if (current == player) return false; + var cardsx = trigger.getg(current); + for (var i of cardsx) { + if ( + cards.includes(i) && + current.countCards("he", (card) => { + return card != i && get.type2(card) == get.type2(i); + }) + ) + return true; } return false; }); } - 'step 1' - var target=event.targets.shift(); - event.target=target; - player.chooseBool(get.prompt('twejian',target),'当其他角色得到你的牌后,若其有其他与此牌类型相同的牌,你可以令其选择一项:1.受到你造成的1点伤害;2.弃置这些牌').set('ai',()=>{ - return get.attitude(player,_status.event.getParent().target)<0; - }); - 'step 2' - if(result.bool){ - player.logSkill('twejian',target); - var cards=trigger.getg(target); - event.cards=cards; - event.cardType=[]; - for(var card of cards){ - event.cardType.add(get.type(card,'trick',target)); + "step 1"; + var target = event.targets.shift(); + event.target = target; + player + .chooseBool( + get.prompt("twejian", target), + "当其他角色得到你的牌后,若其有其他与此牌类型相同的牌,你可以令其选择一项:1.受到你造成的1点伤害;2.弃置这些牌" + ) + .set("ai", () => { + return get.attitude(player, _status.event.getParent().target) < 0; + }); + "step 2"; + if (result.bool) { + player.logSkill("twejian", target); + var cards = trigger.getg(target); + event.cards = cards; + event.cardType = []; + for (var card of cards) { + event.cardType.add(get.type(card, "trick", target)); } - var list=['选项一','选项二']; - target.chooseControl(list).set('prompt','恶荐:请选择一项').set('choiceList',[ - '受到1点伤害', - '弃置所有除'+get.translation(cards)+'外的'+get.translation(event.cardType)+'牌', - ]).set('ai',function(){ - var player=_status.event.player; - var types=_status.event.cardType,cards=player.getCards('he',function(card){ - return types.includes(get.type2(card)); - }); - if(cards.length==1) return '选项二'; - if(cards.length>=2){ - for(var i=0; i= 2) { + for (var i = 0; i < cards.length; i++) { + if (get.tag(cards[i], "save")) return "选项一"; + } } - } - if(player.hp==1) return '选项二'; - for(var i=0; i=8) return '选项一'; - } - if(cards.length>2&&player.hp>2) return '选项一'; - if(cards.length>3) return '选项一'; - return '选项二'; - }).set('cardType',event.cardType); - } - else event.goto(4); - 'step 3' - if(result.control=='选项一') target.damage(); - else target.discard(target.getCards('he',card=>{ - return event.cardType.includes(get.type2(card))&&!cards.includes(card); - })); - 'step 4' - if(event.targets.length>0) event.goto(1); + if (player.hp == 1) return "选项二"; + for (var i = 0; i < cards.length; i++) { + if (get.value(cards[i]) >= 8) return "选项一"; + } + if (cards.length > 2 && player.hp > 2) return "选项一"; + if (cards.length > 3) return "选项一"; + return "选项二"; + }) + .set("cardType", event.cardType); + } else event.goto(4); + "step 3"; + if (result.control == "选项一") target.damage(); + else + target.discard( + target.getCards("he", (card) => { + return event.cardType.includes(get.type2(card)) && !cards.includes(card); + }) + ); + "step 4"; + if (event.targets.length > 0) event.goto(1); else event.finish(); }, - ai:{ - expose:0.3, + ai: { + expose: 0.3, }, }, //张飞 - twxuhe:{ - audio:'retishen', - trigger:{player:'shaMiss'}, - check:function(event,player){ - return get.attitude(player,event.target)<0; + twxuhe: { + audio: "retishen", + trigger: { player: "shaMiss" }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - logTarget:'target', - content:function(){ - 'step 0' - trigger.target.chooseControl().set('choiceList',[ - '受到'+get.translation(player)+'对你造成的1点伤害', - '令'+get.translation(player)+'使用的下一张牌对你造成的伤害+2' - ]).set('ai',function(){ - var target=_status.event.player,player=_status.event.getParent().player; - if(target.hp<=3&&target.hp>1&&player.countCards('hs',function(card){ - return get.tag(card,'damage')&&player.canUse(card,target); - })>0) return 0; - return 1; - }); - 'step 1' - var target=trigger.target; - switch (result.index){ + logTarget: "target", + content: function () { + "step 0"; + trigger.target + .chooseControl() + .set("choiceList", [ + "受到" + get.translation(player) + "对你造成的1点伤害", + "令" + get.translation(player) + "使用的下一张牌对你造成的伤害+2", + ]) + .set("ai", function () { + var target = _status.event.player, + player = _status.event.getParent().player; + if ( + target.hp <= 3 && + target.hp > 1 && + player.countCards("hs", function (card) { + return get.tag(card, "damage") && player.canUse(card, target); + }) > 0 + ) + return 0; + return 1; + }); + "step 1"; + var target = trigger.target; + switch (result.index) { case 0: - player.line(target,'fire'); + player.line(target, "fire"); target.damage(); break; case 1: - target.line(player,'fire'); - player.storage.twxuhe_damage=target; - trigger.getParent().twxuhe=true; - player.addTempSkill('twxuhe_damage'); + target.line(player, "fire"); + player.storage.twxuhe_damage = target; + trigger.getParent().twxuhe = true; + player.addTempSkill("twxuhe_damage"); break; } }, - subSkill:{ - damage:{ - charlotte:true, - onremove:true, - mark:true, - intro:{content:'本回合使用的下一张牌对$造成伤害时,此伤害+2'}, - trigger:{ - source:'damageBegin1', - player:'useCardAfter', + subSkill: { + damage: { + charlotte: true, + onremove: true, + mark: true, + intro: { content: "本回合使用的下一张牌对$造成伤害时,此伤害+2" }, + trigger: { + source: "damageBegin1", + player: "useCardAfter", }, - direct:true, - filter:function(event,player){ - if(event.name=='useCard') return !event.twxuhe; - if(!event.card) return false; - var evt=event.getParent(2); - var history=player.getHistory('useCard'); - return evt.name=='useCard'&&history[history.indexOf(evt)-1].twxuhe; + direct: true, + filter: function (event, player) { + if (event.name == "useCard") return !event.twxuhe; + if (!event.card) return false; + var evt = event.getParent(2); + var history = player.getHistory("useCard"); + return evt.name == "useCard" && history[history.indexOf(evt) - 1].twxuhe; }, - content:function(){ - if(trigger.name!='useCard') trigger.num+=2; - player.removeSkill('twxuhe_damage'); + content: function () { + if (trigger.name != "useCard") trigger.num += 2; + player.removeSkill("twxuhe_damage"); }, - } + }, }, }, //薛综 - twjiexun:{ - intro:{content:'已发动#次'}, - audio:'jiexun', - trigger:{player:'phaseJieshuBegin'}, - onremove:true, - direct:true, - derivation:['twfunanx','twjiexunx'], - content:function(){ - 'step 0' - var suits={}; - game.countPlayer(current=>{ - for(var card of current.getCards('ej')) { - if(typeof suits[get.suit(card)]!='number') suits[get.suit(card)]=0; + twjiexun: { + intro: { content: "已发动#次" }, + audio: "jiexun", + trigger: { player: "phaseJieshuBegin" }, + onremove: true, + direct: true, + derivation: ["twfunanx", "twjiexunx"], + content: function () { + "step 0"; + var suits = {}; + game.countPlayer((current) => { + for (var card of current.getCards("ej")) { + if (typeof suits[get.suit(card)] != "number") suits[get.suit(card)] = 0; suits[get.suit(card)]++; } }); - var choices=lib.suit.slice(); - choices.push('cancel2'); - var str=lib.suit.map(suit=>{ - return get.translation(suit)+':'+get.cnNumber(suits[suit]||0)+'张' - }).join(';'); - player.chooseControl(choices).set('prompt',get.prompt('twjiexun')+'(已发动过'+get.cnNumber(player.countMark('twjiexun'))+'次)').set('ai',function(){ - var player=_status.event.player; - var map={}; - game.countPlayer(current=>{ - for(var card of current.getCards('ej')) { - if(typeof map[get.suit(card)]!='number') map[get.suit(card)]=0; - map[get.suit(card)]++; - } + var choices = lib.suit.slice(); + choices.push("cancel2"); + var str = lib.suit + .map((suit) => { + return get.translation(suit) + ":" + get.cnNumber(suits[suit] || 0) + "张"; + }) + .join(";"); + player + .chooseControl(choices) + .set( + "prompt", + get.prompt("twjiexun") + + "(已发动过" + + get.cnNumber(player.countMark("twjiexun")) + + "次)" + ) + .set("ai", function () { + var player = _status.event.player; + var map = {}; + game.countPlayer((current) => { + for (var card of current.getCards("ej")) { + if (typeof map[get.suit(card)] != "number") map[get.suit(card)] = 0; + map[get.suit(card)]++; + } + }); + for (var suit in map) map[suit] = Math.abs(map[suit]); + var bool = game.hasPlayer( + (current) => get.attitude(player, current) > 0 && player != current + ); + var list = lib.suit + .slice() + .sort((a, b) => (bool ? 1 : -1) * ((map[b] || 0) - (map[a] || 0))); + if ((bool && map[list[0]] > 0) || !bool || player.hasMark("twjiexun")) + return list[0]; + return "cancel2"; + }) + .set("prompt2", get.skillInfoTranslation("twjiexun", player) + "
              " + str); + "step 1"; + if (result.control != "cancel2") { + var suit = result.control; + event.suit = suit; + var num1 = game.countPlayer(function (current) { + return current.countCards("ej", { suit: suit }); }); - for(var suit in map) map[suit]=Math.abs(map[suit]); - var bool=game.hasPlayer(current=>get.attitude(player,current)>0&&player!=current); - var list=lib.suit.slice().sort((a,b)=>(bool?1:-1)*((map[b]||0)-(map[a]||0))); - if(bool&&map[list[0]]>0||!bool||player.hasMark('twjiexun')) return list[0]; - return 'cancel2'; - }).set('prompt2',get.skillInfoTranslation('twjiexun',player)+'
              '+str); - 'step 1' - if(result.control!='cancel2'){ - var suit=result.control; - event.suit=suit; - var num1=game.countPlayer(function(current){ - return current.countCards('ej',{suit:suit}); - }); - var num2=player.countMark('twjiexun'); - event.num1=num1; - event.num2=num2; - var str='令一名其他角色摸'+get.cnNumber(num1)+'张牌'; - if(num2) str+=',然后弃置'+get.cnNumber(num2)+'张牌'; - player.chooseTarget('请选择【诫训】的目标',str,lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - return _status.event.eff*get.sgn(att)+att/114514; - }).set('eff',num1>=num2&&num1>0?1:-1); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twjiexun',target); - if(player.hasMark('twjiexun')||event.num1) player.addExpose(0.2); + var num2 = player.countMark("twjiexun"); + event.num1 = num1; + event.num2 = num2; + var str = "令一名其他角色摸" + get.cnNumber(num1) + "张牌"; + if (num2) str += ",然后弃置" + get.cnNumber(num2) + "张牌"; + player + .chooseTarget("请选择【诫训】的目标", str, lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + return _status.event.eff * get.sgn(att) + att / 114514; + }) + .set("eff", num1 >= num2 && num1 > 0 ? 1 : -1); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twjiexun", target); + if (player.hasMark("twjiexun") || event.num1) player.addExpose(0.2); player.popup(event.suit); - game.log(player,'选择了','#y'+get.translation(event.suit)); - player.addMark('twjiexun',1,false); - if(event.num1) target.draw(event.num1); - } + game.log(player, "选择了", "#y" + get.translation(event.suit)); + player.addMark("twjiexun", 1, false); + if (event.num1) target.draw(event.num1); + } else event.finish(); + "step 3"; + if (event.num2) target.chooseToDiscard(event.num2, true, "he"); else event.finish(); - 'step 3' - if(event.num2) target.chooseToDiscard(event.num2,true,'he'); - else event.finish(); - 'step 4' - if(result.bool&&result.autochoose&&result.cards.length==result.rawcards.length&&!player.hasSkill('funan_jiexun')){ - player.chooseControl().set('choiceList',[ - '摸'+get.cnNumber(event.num2)+'张牌,将【诫训】的发动次数归零', - '修改【复难】和【诫训】' - ]).set('ai',()=>_status.event.choice).set('prompt','诫训:选择一项').set('choice',event.num2>=4?0:(event.num2<=1?1:[0,1].randomGet())); - } - else event.finish(); - 'step 5' - if(result.index==0){ + "step 4"; + if ( + result.bool && + result.autochoose && + result.cards.length == result.rawcards.length && + !player.hasSkill("funan_jiexun") + ) { + player + .chooseControl() + .set("choiceList", [ + "摸" + get.cnNumber(event.num2) + "张牌,将【诫训】的发动次数归零", + "修改【复难】和【诫训】", + ]) + .set("ai", () => _status.event.choice) + .set("prompt", "诫训:选择一项") + .set("choice", event.num2 >= 4 ? 0 : event.num2 <= 1 ? 1 : [0, 1].randomGet()); + } else event.finish(); + "step 5"; + if (result.index == 0) { player.draw(event.num2); - player.removeMark('twjiexun',player.countMark('twjiexun'),false); - game.log(player,'归零了','#g【诫训】','的发动次数'); - } - else { - game.log(player,'修改了','#g【复难】','和','#g【诫训】'); - player.addSkill('funan_jiexun'); + player.removeMark("twjiexun", player.countMark("twjiexun"), false); + game.log(player, "归零了", "#g【诫训】", "的发动次数"); + } else { + game.log(player, "修改了", "#g【复难】", "和", "#g【诫训】"); + player.addSkill("funan_jiexun"); } }, }, //张宁 - twxingzhui:{ - audio:2, - enable:'phaseUse', - usable:1, - mahouSkill:true, - filter:function(event,player){ - return !player.hasSkill('twxingzhui_mahou'); + twxingzhui: { + audio: 2, + enable: "phaseUse", + usable: 1, + mahouSkill: true, + filter: function (event, player) { + return !player.hasSkill("twxingzhui_mahou"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - player.chooseControl('1回合','2回合','3回合').set('prompt','请选择施法时长').set('ai',function(){ - return 2; - }); - 'step 1' - player.storage.twxingzhui_mahou=[result.index+1,result.index+1]; - player.addTempSkill('twxingzhui_mahou',{player:'die'}); + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + return 2; + }); + "step 1"; + player.storage.twxingzhui_mahou = [result.index + 1, result.index + 1]; + player.addTempSkill("twxingzhui_mahou", { player: "die" }); }, - ai:{ - order:2, - result:{ - player:function(player,target){ - if(!player.hasFriend()) return 0; - if(player.hp>1) return 1; + ai: { + order: 2, + result: { + player: function (player, target) { + if (!player.hasFriend()) return 0; + if (player.hp > 1) return 1; return 0; }, }, }, - subSkill:{ - mahou:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - 'step 0' - var list=player.storage.twxingzhui_mahou; + subSkill: { + mahou: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + "step 0"; + var list = player.storage.twxingzhui_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的','#g星坠','魔法生效'); - player.logSkill('twxingzhui'); - var num=list[0]; - event.num=num; - var cards=game.cardsGotoOrdering(get.cards(num*2)).cards; - event.cards=cards; - player.showCards(cards,get.translation(player)+'发动了【星坠】'); - player.removeSkill('twxingzhui_mahou'); - } - else{ - game.log(player,'的','#g星坠','魔法剩余','#g'+(list[1])+'回合'); - player.markSkill('twxingzhui_mahou'); + if (list[1] == 0) { + game.log(player, "的", "#g星坠", "魔法生效"); + player.logSkill("twxingzhui"); + var num = list[0]; + event.num = num; + var cards = game.cardsGotoOrdering(get.cards(num * 2)).cards; + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【星坠】"); + player.removeSkill("twxingzhui_mahou"); + } else { + game.log(player, "的", "#g星坠", "魔法剩余", "#g" + list[1] + "回合"); + player.markSkill("twxingzhui_mahou"); event.finish(); } - 'step 1' - var cards2=[]; - for(var card of event.cards){ - if(get.color(card,false)=='black') cards2.push(card); + "step 1"; + var cards2 = []; + for (var card of event.cards) { + if (get.color(card, false) == "black") cards2.push(card); } - if(!cards2.length) event.finish(); - else{ - event.cards2=cards2; - var str='令一名其他角色获得其中的黑色牌('+get.translation(cards2)+')'; - if(cards2.length>=event.num) str+=',然后对其造成'+get.cnNumber(event.num)+'点伤害'; - player.chooseTarget('请选择〖星坠〗的目标',str,lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(_status.event.getParent().cards2.length>=_status.event.getParent().num) return get.damageEffect(target,player,player,'thunder'); - return get.attitude(player,target); - }); + if (!cards2.length) event.finish(); + else { + event.cards2 = cards2; + var str = "令一名其他角色获得其中的黑色牌(" + get.translation(cards2) + ")"; + if (cards2.length >= event.num) + str += ",然后对其造成" + get.cnNumber(event.num) + "点伤害"; + player + .chooseTarget("请选择〖星坠〗的目标", str, lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + if ( + _status.event.getParent().cards2.length >= + _status.event.getParent().num + ) + return get.damageEffect(target, player, player, "thunder"); + return get.attitude(player, target); + }); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - target.gain(event.cards2,'gain2'); - if(event.cards2.length>=num) target.damage(event.num,'thunder'); + target.gain(event.cards2, "gain2"); + if (event.cards2.length >= num) target.damage(event.num, "thunder"); } }, - mark:true, - onremove:true, - marktext:'♗', - intro:{ - name:'施法:星坠', - markcount:function(storage){ - if(storage) return storage[1]; + mark: true, + onremove: true, + marktext: "♗", + intro: { + name: "施法:星坠", + markcount: function (storage) { + if (storage) return storage[1]; return 0; }, - content:function(storage){ - if(storage) return '经过'+storage[1]+'个“回合结束时”后,亮出牌堆顶的'+get.cnNumber(storage[0]*2)+'张牌并执行后续效果'; - return '未指定施法效果'; + content: function (storage) { + if (storage) + return ( + "经过" + + storage[1] + + "个“回合结束时”后,亮出牌堆顶的" + + get.cnNumber(storage[0] * 2) + + "张牌并执行后续效果" + ); + return "未指定施法效果"; }, }, }, }, }, - twjuchen:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>player.countCards('h'); - })&&game.hasPlayer(function(current){ - return current!=player&¤t.hp>player.hp; - }); + twjuchen: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > player.countCards("h"); + }) && + game.hasPlayer(function (current) { + return current != player && current.hp > player.hp; + }) + ); }, - logTarget:function(event,player){ + logTarget: function (event, player) { return game.players.sortBySeat(player); }, - content:function(){ - 'step 0' - event.num=0; - event.cards=[]; - event.targets=game.players.sortBySeat(player); - 'step 1' - var target=targets[num]; - if(target.countCards('he')) target.chooseToDiscard('he',true); - else event._result={bool:false}; - 'step 2' - if(result.bool&&Array.isArray(result.cards)) event.cards.addArray(result.cards); + content: function () { + "step 0"; + event.num = 0; + event.cards = []; + event.targets = game.players.sortBySeat(player); + "step 1"; + var target = targets[num]; + if (target.countCards("he")) target.chooseToDiscard("he", true); + else event._result = { bool: false }; + "step 2"; + if (result.bool && Array.isArray(result.cards)) event.cards.addArray(result.cards); event.num++; - if(event.num1) return false; - if(_status.dying.length) return false; - if(player==event.player) return false; - if(event.target.hp>=player.hp) return false; - if(!['basic','trick'].includes(get.type(event.card))) return false; + twjiekuang: { + audio: 2, + trigger: { global: "useCardToTargeted" }, + filter: function (event, player) { + if (!event.target || event.targets.length > 1) return false; + if (_status.dying.length) return false; + if (player == event.player) return false; + if (event.target.hp >= player.hp) return false; + if (!["basic", "trick"].includes(get.type(event.card))) return false; return true; }, - usable:1, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('失去体力','减体力上限','cancel2').set('prompt',get.prompt2('twjiekuang',trigger.target)).set('ai',function(card){ - if(_status.event.aisave){ - if(player.isDamaged()) return '减体力上限'; - return '失去体力'; - } - return 'cancel2'; - }).set('aisave',function(){ - var save=false; - if(get.attitude(player,trigger.target)>2){ - if(trigger.card.name=='sha'){ - if(player.countCards('h','shan')||player.getEquip(2) || - trigger.target.hp==1||player.hp>trigger.target.hp+1){ - if(!trigger.target.countCards('h','shan')||trigger.target.countCards('h') 2) { + if (trigger.card.name == "sha") { + if ( + player.countCards("h", "shan") || + player.getEquip(2) || + trigger.target.hp == 1 || + player.hp > trigger.target.hp + 1 + ) { + if ( + !trigger.target.countCards("h", "shan") || + trigger.target.countCards("h") < player.countCards("h") + ) { + save = true; + } + } + } else if (trigger.card.name == "juedou" && trigger.target.hp == 1) { + save = true; + } else if ( + trigger.card.name == "shunshou" && + get.attitude(player, trigger.player) < 0 && + get.attitude(trigger.player, trigger.target) < 0 + ) { + save = true; } } - } - else if(trigger.card.name=='juedou'&&trigger.target.hp==1){ - save=true; - } - else if(trigger.card.name=='shunshou' && - get.attitude(player,trigger.player)<0 && - get.attitude(trigger.player,trigger.target)<0){ - save=true; - } - } - return save; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twjiekuang',trigger.target); - player[result.control=='失去体力'?'loseHp':'loseMaxHp'](); - player.addTempSkill('twjiekuang_after'); - trigger.getParent().twjiekuang=true; + return save; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twjiekuang", trigger.target); + player[result.control == "失去体力" ? "loseHp" : "loseMaxHp"](); + player.addTempSkill("twjiekuang_after"); + trigger.getParent().twjiekuang = true; trigger.getParent().targets.remove(trigger.target); trigger.getParent().triggeredTargets4.remove(trigger.target); trigger.getParent().targets.push(player); trigger.untrigger(); game.delayx(); trigger.player.line(player); - } - else player.storage.counttrigger.twjiekuang--; + } else player.storage.counttrigger.twjiekuang--; }, - subSkill:{ - after:{ - charlotte:true, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ + subSkill: { + after: { + charlotte: true, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { return event.twjiekuang; }, - direct:true, - content:function(){ - player.removeSkill('twjiekuang_after'); - var card=get.autoViewAs({ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true + direct: true, + content: function () { + player.removeSkill("twjiekuang_after"); + var card = get.autoViewAs({ + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, }); - if(!game.countPlayer2(current=>{ - return current.hasHistory('damage',evt=>evt.card==trigger.card); - })&&player.canUse(card,trigger.player,false)){ - player.useCard(card,trigger.player,false); + if ( + !game.countPlayer2((current) => { + return current.hasHistory("damage", (evt) => evt.card == trigger.card); + }) && + player.canUse(card, trigger.player, false) + ) { + player.useCard(card, trigger.player, false); } }, }, }, }, - twneirao:{ - audio:2, - derivation:'twluanlve', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return Math.max(0,player.hp)+player.maxHp<=9; + twneirao: { + audio: 2, + derivation: "twluanlve", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return Math.max(0, player.hp) + player.maxHp <= 9; }, - content:function(){ - 'step 0' - player.awakenSkill('twneirao'); - player.removeSkills('twjiekuang'); - 'step 1' - var num=player.countCards('he'),cards=[]; - player.discard(player.getCards('he')); - for(var i=0;i=player.countMark('twluanlve'); + viewAsFilter: function (player) { + return ( + player.isPhaseUsing() && + player.countCards("hs", { name: "sha" }) >= player.countMark("twluanlve") + ); }, - filterCard:function(card,player){ - if(player.countMark('twluanlve')==0) return false; - return card.name=='sha'; + filterCard: function (card, player) { + if (player.countMark("twluanlve") == 0) return false; + return card.name == "sha"; }, - selectCard:function(){ - var player=_status.event.player; - if(player.countMark('twluanlve')==0) return -1; - return player.countMark('twluanlve'); + selectCard: function () { + var player = _status.event.player; + if (player.countMark("twluanlve") == 0) return -1; + return player.countMark("twluanlve"); }, - onChooseToUse:function(event){ - if(!game.online&&event.type=='phase'){ - var targets=[]; - game.countPlayer2(current=>{ - var history=current.getHistory('useCard'); - if(!history.length) return false; - for(var evt of history){ - if(evt.card&&evt.card.name=='shunshou'){ + onChooseToUse: function (event) { + if (!game.online && event.type == "phase") { + var targets = []; + game.countPlayer2((current) => { + var history = current.getHistory("useCard"); + if (!history.length) return false; + for (var evt of history) { + if (evt.card && evt.card.name == "shunshou") { targets.addArray(evt.targets); } } }); - event.set('twluanlve_ban',targets); + event.set("twluanlve_ban", targets); } }, - position:'hs', - log:false, - group:['twluanlve_directHit'], - precontent:function(){ - player.logSkill('twluanlve'); - player.addMark('twluanlve',1,false); + position: "hs", + log: false, + group: ["twluanlve_directHit"], + precontent: function () { + player.logSkill("twluanlve"); + player.addMark("twluanlve", 1, false); }, - ai:{ - order:function(){ - return get.order({name:'shunshou'})+1; + ai: { + order: function () { + return get.order({ name: "shunshou" }) + 1; }, }, - mod:{ - playerEnabled:function(card,player,target){ - if(!_status.event.twluanlve_ban||!Array.isArray(_status.event.twluanlve_ban)) return; - if(player.isPhaseUsing()&&card.name=='shunshou'&&card.storage&&card.storage.twluanlve&&_status.event.twluanlve_ban.includes(target)) return false; + mod: { + playerEnabled: function (card, player, target) { + if (!_status.event.twluanlve_ban || !Array.isArray(_status.event.twluanlve_ban)) + return; + if ( + player.isPhaseUsing() && + card.name == "shunshou" && + card.storage && + card.storage.twluanlve && + _status.event.twluanlve_ban.includes(target) + ) + return false; }, }, - subSkill:{ - directHit:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='shunshou'; + subSkill: { + directHit: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "shunshou"; }, - direct:true, - content:function(){ + direct: true, + content: function () { trigger.directHit.addArray(game.players); - game.log(trigger.card,'不可被响应'); + game.log(trigger.card, "不可被响应"); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg&&arg.card&&arg.card.name=='shunshou'; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return arg && arg.card && arg.card.name == "shunshou"; }, }, - } + }, }, }, //冯习 - twqingkou:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return player.canUse('juedou',current,false); + twqingkou: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return player.canUse("juedou", current, false); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twqingkou'),'视为对一名其他角色使用一张【决斗】',function(card,player,target){ - return player.canUse('juedou',target,false); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'juedou'},player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twqingkou',target); - player.useCard({name:'juedou',isCard:true,storage:{twqingkou:true}},target,false); - player.addTempSkill('twqingkou_after'); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twqingkou"), + "视为对一名其他角色使用一张【决斗】", + function (card, player, target) { + return player.canUse("juedou", target, false); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "juedou" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twqingkou", target); + player.useCard( + { name: "juedou", isCard: true, storage: { twqingkou: true } }, + target, + false + ); + player.addTempSkill("twqingkou_after"); } }, - subSkill:{ - after:{ - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.card.storage&&event.card.storage.twqingkou; + subSkill: { + after: { + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return event.card.storage && event.card.storage.twqingkou; }, - charlotte:true, - direct:true, - content:function(){ - var targets=game.filterPlayer(current=>{ - return current.hasHistory('sourceDamage',function(evt){ - return evt.card==trigger.card; - }); - }).sortBySeat(); - for(var target of targets){ + charlotte: true, + direct: true, + content: function () { + var targets = game + .filterPlayer((current) => { + return current.hasHistory("sourceDamage", function (evt) { + return evt.card == trigger.card; + }); + }) + .sortBySeat(); + for (var target of targets) { target.draw(); - if(target==player){ - player.skip('phaseJudge'); - game.log(player,'跳过了','#y判定阶段'); - player.skip('phaseDiscard'); - game.log(player,'跳过了','#y弃牌阶段'); + if (target == player) { + player.skip("phaseJudge"); + game.log(player, "跳过了", "#y判定阶段"); + player.skip("phaseDiscard"); + game.log(player, "跳过了", "#y弃牌阶段"); } } }, @@ -6159,1802 +7759,2309 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //张既 - twdingzhen:{ - audio:2, - trigger:{global:'roundStart'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return get.distance(player,current)<=Math.max(0,player.hp); + twdingzhen: { + audio: 2, + trigger: { global: "roundStart" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return get.distance(player, current) <= Math.max(0, player.hp); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twdingzhen'),[1,Infinity],function(card,player,target){ - return get.distance(player,target)<=player.hp; - }).set('ai',function(target){ - var player=_status.event.player; - if(target==player) return 0; - return Math.max(-get.attitude(player,target),1); - }); - 'step 1' - if(result.bool){ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt2("twdingzhen"), + [1, Infinity], + function (card, player, target) { + return get.distance(player, target) <= player.hp; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (target == player) return 0; + return Math.max(-get.attitude(player, target), 1); + }); + "step 1"; + if (result.bool) { result.targets.sortBySeat(); - var targets=result.targets; - event.targets=targets; - player.logSkill('twdingzhen',targets); - event.num=0; + var targets = result.targets; + event.targets = targets; + player.logSkill("twdingzhen", targets); + event.num = 0; + } else event.finish(); + "step 2"; + var target = targets[num]; + event.target = target; + target + .chooseToDiscard( + "h", + { name: "sha" }, + "定镇:弃置一张【杀】,或本轮你于回合内使用的第一张牌不能指定" + + get.translation(player) + + "为目标" + ) + .set("ai", function (card) { + if (_status.event.goon) return 1; + return 0; + }) + .set( + "goon", + get.attitude(target, player) < 0 && + player.countCards("hs") <= 3 && + target.countCards("hs", (card) => { + return target.hasValueTarget(card); + }) > 1 + ); + "step 3"; + if (result.bool) target.addExpose(0.1); + else { + target.addSkill("twdingzhen_target"); + target.markAuto("twdingzhen_target", [player]); } - else event.finish(); - 'step 2' - var target=targets[num]; - event.target=target; - target.chooseToDiscard('h',{name:'sha'},'定镇:弃置一张【杀】,或本轮你于回合内使用的第一张牌不能指定'+get.translation(player)+'为目标').set('ai',function(card){ - if(_status.event.goon) return 1; - return 0; - }).set('goon',get.attitude(target,player)<0&&player.countCards('hs')<=3&&target.countCards('hs',card=>{ - return target.hasValueTarget(card); - })>1); - 'step 3' - if(result.bool) target.addExpose(0.1); - else{ - target.addSkill('twdingzhen_target'); - target.markAuto('twdingzhen_target',[player]); - } - 'step 4' - if(event.num0, - content:'回合内使用的第一张牌不能指定$为目标', + intro: { + markcount: () => 0, + content: "回合内使用的第一张牌不能指定$为目标", }, - mod:{ - playerEnabled:function(card,player,target){ - if(_status.currentPhase==player&&!player.countUsed()&&player.getStorage('twdingzhen_target').includes(target)) return false; + mod: { + playerEnabled: function (card, player, target) { + if ( + _status.currentPhase == player && + !player.countUsed() && + player.getStorage("twdingzhen_target").includes(target) + ) + return false; }, }, }, }, }, - twyouye:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player!=player&&!event.player.getHistory('sourceDamage',function(evt){ - return evt.player==player; - }).length&&player.getExpansions('twyouye').length<5; + twyouye: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player != player && + !event.player.getHistory("sourceDamage", function (evt) { + return evt.player == player; + }).length && + player.getExpansions("twyouye").length < 5 + ); }, - forced:true, - group:'twyouye_give', - content:function(){ - player.addToExpansion(get.cards(),'gain2').gaintag.add('twyouye'); + forced: true, + group: "twyouye_give", + content: function () { + player.addToExpansion(get.cards(), "gain2").gaintag.add("twyouye"); }, - marktext:'蓄', - intro:{ - name:'蓄(攸业)', - content:'expansion', - markcount:'expansion', + marktext: "蓄", + intro: { + name: "蓄(攸业)", + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - subSkill:{ - give:{ - audio:'twyouye', - trigger:{source:'damageSource',player:'damageEnd'}, - filter:function(event,player){ - return player.getExpansions('twyouye').length; + subSkill: { + give: { + audio: "twyouye", + trigger: { source: "damageSource", player: "damageEnd" }, + filter: function (event, player) { + return player.getExpansions("twyouye").length; }, - forced:true, - content:function(){ - 'step 0' - event.boolx=_status.currentPhase&&_status.currentPhase.isIn(); - event.cards=player.getExpansions('twyouye'); - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 1' - if(event.cards.length>1){ - player.chooseCardButton('攸业:请选择要分配的牌',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length) return 0; - return get.value(button.link,_status.event.player); + forced: true, + content: function () { + "step 0"; + event.boolx = _status.currentPhase && _status.currentPhase.isIn(); + event.cards = player.getExpansions("twyouye"); + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cards.length==1) event._result={links:event.cards.slice(0),bool:true}; + event.given_map = {}; + "step 1"; + if (event.cards.length > 1) { + player + .chooseCardButton("攸业:请选择要分配的牌", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length) return 0; + return get.value(button.link, _status.event.player); + }); + } else if (event.cards.length == 1) + event._result = { links: event.cards.slice(0), bool: true }; else event.finish(); - 'step 2' - if(result.bool){ - var cards=result.links; - event.cards2=cards; - player.chooseTarget('选择一名角色获得'+get.translation(cards),function(card,player,target){ - var evt=_status.event.getParent(); - var cards=evt.cards,cards2=evt.cards2.slice(); - if(cards.removeArray(cards2).length>0||!evt.boolx) return true; - return target==_status.currentPhase; - },event.cards.length==1).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.enemy) return Math.max(0.01,100-att); - else if(att>0) return Math.max(0.1,att/(1+target.countCards('h')+(_status.event.getParent().given_map[target.playerid]||0))); - else return Math.max(0.01,(100+att)/100); - }).set('enemy',get.value(cards[0],player,'raw')<0); + "step 2"; + if (result.bool) { + var cards = result.links; + event.cards2 = cards; + player + .chooseTarget( + "选择一名角色获得" + get.translation(cards), + function (card, player, target) { + var evt = _status.event.getParent(); + var cards = evt.cards, + cards2 = evt.cards2.slice(); + if (cards.removeArray(cards2).length > 0 || !evt.boolx) + return true; + return target == _status.currentPhase; + }, + event.cards.length == 1 + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) return Math.max(0.01, 100 - att); + else if (att > 0) + return Math.max( + 0.1, + att / + (1 + + target.countCards("h") + + (_status.event.getParent().given_map[ + target.playerid + ] || 0)) + ); + else return Math.max(0.01, (100 + att) / 100); + }) + .set("enemy", get.value(cards[0], player, "raw") < 0); } - 'step 3' - if(result.bool){ - var cards=event.cards2; + "step 3"; + if (result.bool) { + var cards = event.cards2; event.cards.removeArray(cards); - event.togive=cards.slice(0); - if(result.targets.length){ - if(result.targets[0]==_status.currentPhase) event.boolx=false; - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + event.togive = cards.slice(0); + if (result.targets.length) { + if (result.targets[0] == _status.currentPhase) event.boolx = false; + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(event.cards.length>0) event.goto(1); - } - else event.goto(1); - 'step 4' - if(_status.connectMode) game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - list.push([source,event.given_map[i]]); - game.log(source,'获得了',event.given_map[i]); + if (event.cards.length > 0) event.goto(1); + } else event.goto(1); + "step 4"; + if (_status.connectMode) + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + list.push([source, event.given_map[i]]); + game.log(source, "获得了", event.given_map[i]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'gain2', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "gain2", + }).setContent("gaincardMultiple"); }, }, }, }, //荀谌 - twweipo:{ - audio:'mjweipo', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('he'); + twweipo: { + audio: "mjweipo", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("he"); }); }, - filterTarget:function(card,player,target){ - return target.countCards('he'); + filterTarget: function (card, player, target) { + return target.countCards("he"); }, - content:function(){ - 'step 0' - target.chooseToDiscard('he',true); - 'step 1' - var list=['binglinchengxiax']; + content: function () { + "step 0"; + target.chooseToDiscard("he", true); + "step 1"; + var list = ["binglinchengxiax"]; list.addArray(get.zhinangs()); - player.chooseButton(['危迫:令其获得一张智囊牌或【兵临城下】',[list,'vcard']],true).set('ai',function(button){ - return _status.event.getParent().target.getUseValue({name:button.link[2]}); - }); - 'step 2' - if(result.bool){ - var name=result.links[0][2],card=false; - game.log(player,'选择了','#y'+get.translation(name)); - if(name=='binglinchengxiax'){ - if(!_status.binglinchengxiax){ - _status.binglinchengxiax=[ - ['spade',7], - ['club',7], - ['club',13], + player + .chooseButton(["危迫:令其获得一张智囊牌或【兵临城下】", [list, "vcard"]], true) + .set("ai", function (button) { + return _status.event.getParent().target.getUseValue({ name: button.link[2] }); + }); + "step 2"; + if (result.bool) { + var name = result.links[0][2], + card = false; + game.log(player, "选择了", "#y" + get.translation(name)); + if (name == "binglinchengxiax") { + if (!_status.binglinchengxiax) { + _status.binglinchengxiax = [ + ["spade", 7], + ["club", 7], + ["club", 13], ]; - game.broadcastAll(function(){lib.inpile.add('binglinchengxiax')}); + game.broadcastAll(function () { + lib.inpile.add("binglinchengxiax"); + }); } - if(_status.binglinchengxiax.length){ - var info=_status.binglinchengxiax.randomRemove(); - card=game.createCard2('binglinchengxiax',info[0],info[1]); + if (_status.binglinchengxiax.length) { + var info = _status.binglinchengxiax.randomRemove(); + card = game.createCard2("binglinchengxiax", info[0], info[1]); } } - if(!card) card=get.cardPile(name); - if(card) target.gain(card,'gain2'); + if (!card) card = get.cardPile(name); + if (card) target.gain(card, "gain2"); } }, - ai:{ - order:7.1, - result:{ - target:function(player,target){ - if(target==player) return player.countCards('he')?10:0.01; - return (target.countCards('he')+0.5)*Math.sqrt(Math.max(1,target.hp)); + ai: { + order: 7.1, + result: { + target: function (player, target) { + if (target == player) return player.countCards("he") ? 10 : 0.01; + return (target.countCards("he") + 0.5) * Math.sqrt(Math.max(1, target.hp)); }, }, }, }, - twmouzhi:{ - audio:'mjmouzhi', - intro:{content:'上次受到伤害的颜色:$'}, - trigger:{player:'damageBegin4'}, - forced:true, - group:'twmouzhi_mark', - filter:function(event,player){ - if(!event.card||get.color(event.card)=='none') return false; - var all=player.getAllHistory('damage'); - if(!all.length) return false; - return all[all.length-1].card&&get.color(all[all.length-1].card)==get.color(event.card); + twmouzhi: { + audio: "mjmouzhi", + intro: { content: "上次受到伤害的颜色:$" }, + trigger: { player: "damageBegin4" }, + forced: true, + group: "twmouzhi_mark", + filter: function (event, player) { + if (!event.card || get.color(event.card) == "none") return false; + var all = player.getAllHistory("damage"); + if (!all.length) return false; + return ( + all[all.length - 1].card && + get.color(all[all.length - 1].card) == get.color(event.card) + ); }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(typeof card==='object'&&get.tag(card,'damage')){ - let color=get.color(card); - if(color==='none') return; - let all=target.getAllHistory('damage'); - if(!all.length||!all[all.length-1].card) return; - if(get.color(all[all.length-1].card)===color) return 'zeroplayertarget'; + ai: { + effect: { + target: (card, player, target) => { + if (typeof card === "object" && get.tag(card, "damage")) { + let color = get.color(card); + if (color === "none") return; + let all = target.getAllHistory("damage"); + if (!all.length || !all[all.length - 1].card) return; + if (get.color(all[all.length - 1].card) === color) return "zeroplayertarget"; } }, }, }, - subSkill:{ - mark:{ - trigger:{player:'damage'}, - silent:true, - firstDo:true, - content:function(){ - if(!trigger.card||get.color(trigger.card)=='none') player.unmarkSkill('twmouzhi'); + subSkill: { + mark: { + trigger: { player: "damage" }, + silent: true, + firstDo: true, + content: function () { + if (!trigger.card || get.color(trigger.card) == "none") + player.unmarkSkill("twmouzhi"); else { - player.markSkill('twmouzhi'); - player.storage.twmouzhi=get.color(trigger.card); - game.broadcastAll(function(player,color){ - if(player.marks.twmouzhi){ - player.marks.twmouzhi.firstChild.innerHTML=''; - } - player.storage.twmouzhi=color; - },player,player.storage.twmouzhi) + player.markSkill("twmouzhi"); + player.storage.twmouzhi = get.color(trigger.card); + game.broadcastAll( + function (player, color) { + if (player.marks.twmouzhi) { + player.marks.twmouzhi.firstChild.innerHTML = + ""; + } + player.storage.twmouzhi = color; + }, + player, + player.storage.twmouzhi + ); } }, }, }, }, //蒋钦 - twshangyi:{ - audio:'shangyi', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h'); - }); + twshangyi: { + audio: "shangyi", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") && + game.hasPlayer(function (current) { + return current != player && current.countCards("h"); + }) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); }, - filterCard:true, - position:'he', - content:function(){ - 'step 0' + filterCard: true, + position: "he", + content: function () { + "step 0"; target.viewHandcards(player); var chooseButton; - if(player.countCards('h')) chooseButton=player.chooseButton([1,2],['###尚义###
              选择'+get.translation(target)+'的一张手牌以弃置,或选择你与其的各一张牌以交换
              ','
              '+get.translation(target)+'的手牌
              ',target.getCards('h'),'
              你的手牌
              ',player.getCards('h')],true); - else chooseButton=player.chooseButton(['###尚义###
              弃置'+get.translation(target)+'的一张手牌
              ','
              '+get.translation(target)+'的手牌
              ',target.getCards('h')],true); - chooseButton.set('target',target); - chooseButton.set('ai',function(button){ - var player=_status.event.player,owner=get.owner(button.link),color=get.color(button.link,owner),value=get.value(button.link,owner); - if(player.countCards('h')){ - if(!ui.selected.buttons.length){ - if(player.countCards('h',function(card){ - return get.color(card,player)=='red'&&get.value(card)<6; - })&&color=='red'&&value>7) return value*3; + if (player.countCards("h")) + chooseButton = player.chooseButton( + [1, 2], + [ + '###尚义###
              选择' + + get.translation(target) + + "的一张手牌以弃置,或选择你与其的各一张牌以交换
              ", + '
              ' + get.translation(target) + "的手牌
              ", + target.getCards("h"), + '
              你的手牌
              ', + player.getCards("h"), + ], + true + ); + else + chooseButton = player.chooseButton( + [ + '###尚义###
              弃置' + + get.translation(target) + + "的一张手牌
              ", + '
              ' + get.translation(target) + "的手牌
              ", + target.getCards("h"), + ], + true + ); + chooseButton.set("target", target); + chooseButton.set("ai", function (button) { + var player = _status.event.player, + owner = get.owner(button.link), + color = get.color(button.link, owner), + value = get.value(button.link, owner); + if (player.countCards("h")) { + if (!ui.selected.buttons.length) { + if ( + player.countCards("h", function (card) { + return get.color(card, player) == "red" && get.value(card) < 6; + }) && + color == "red" && + value > 7 + ) + return value * 3; return value; + } else { + if (get.value(ui.selected.buttons[0].link) < 4) return 0; + return ( + 4 + + (get.color( + ui.selected.buttons[0].link, + get.owner(ui.selected.buttons[0].link) + ) == "red" + ? 3 + : 1) - + value + ); } - else { - if(get.value(ui.selected.buttons[0].link)<4) return 0; - return 4+(get.color(ui.selected.buttons[0].link,get.owner(ui.selected.buttons[0].link))=='red'?3:1)-value; - } - } - else { - if(color=='black') return value*1.5; + } else { + if (color == "black") return value * 1.5; return value; } }); - chooseButton.set('filterButton',function(button){ - if(get.itemtype(button.link)!='card') return false; - if(!ui.selected.buttons.length&&get.owner(button.link)!=_status.event.target) return false; - if(ui.selected.buttons.length&&get.owner(ui.selected.buttons[0].link)==get.owner(button.link)) return false; + chooseButton.set("filterButton", function (button) { + if (get.itemtype(button.link) != "card") return false; + if (!ui.selected.buttons.length && get.owner(button.link) != _status.event.target) + return false; + if ( + ui.selected.buttons.length && + get.owner(ui.selected.buttons[0].link) == get.owner(button.link) + ) + return false; return true; }); - 'step 1' - if(result.bool){ - if(result.links.length==1){ - target.discard(result.links[0]).discarder=player; - if(get.color(result.links[0],target)!='black') event.finish(); + "step 1"; + if (result.bool) { + if (result.links.length == 1) { + target.discard(result.links[0]).discarder = player; + if (get.color(result.links[0], target) != "black") event.finish(); + } else { + var links = result.links.slice(); + if (get.owner(links[0]) != player) links.reverse(); + var card1 = links[0], + card2 = links[1]; + player.swapHandcards(target, [card1], [card2]); + if (get.color(card1, player) != "red" || get.color(card2, target) != "red") + event.finish(); } - else { - var links=result.links.slice(); - if(get.owner(links[0])!=player) links.reverse(); - var card1=links[0],card2=links[1]; - player.swapHandcards(target,[card1],[card2]); - if(get.color(card1,player)!='red'||get.color(card2,target)!='red') event.finish(); - } - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; player.draw(); }, - ai:{ - order:10, - result:{target:-1}, + ai: { + order: 10, + result: { target: -1 }, }, }, - twxiangyu:{ - group:'twxiangyu_lose', - shaRelated:true, - audio:'zniaoxiang', - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&get.distance(player,event.player){ - return current.getHistory('lose').length; + 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; }); - if(targets.length){ - player.addTempSkill('twxiangyu_range'); - player.markAuto('twxiangyu_range',targets); + if (targets.length) { + player.addTempSkill("twxiangyu_range"); + player.markAuto("twxiangyu_range", targets); } } }, - content:function(){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + content: function () { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; - } - else map[id].shanRequired=2; + } else map[id].shanRequired = 2; }, - mod:{ - attackRange:function(player,num){ - return num+Math.min(5,player.getStorage('twxiangyu_range').length); + mod: { + attackRange: function (player, num) { + return num + Math.min(5, player.getStorage("twxiangyu_range").length); }, }, - subSkill:{ - lose:{ - trigger:{ - global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + lose: { + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - return player==_status.currentPhase&&game.hasPlayer(function(current){ - if(player.getStorage('twxiangyu_range').includes(current)) return false; - var evt=event.getl(current); - return evt&&evt.cards2&&evt.cards2.length>0; - }); + filter: function (event, player) { + return ( + player == _status.currentPhase && + game.hasPlayer(function (current) { + if (player.getStorage("twxiangyu_range").includes(current)) return false; + var evt = event.getl(current); + return evt && evt.cards2 && evt.cards2.length > 0; + }) + ); }, - silent:true, - charlotte:true, - content:function(){ - player.addTempSkill('twxiangyu_range'); - player.markAuto('twxiangyu_range',game.filterPlayer(function(current){ - if(player.getStorage('twxiangyu_range').includes(current)) return false; - var evt=trigger.getl(current); - return evt&&evt.cards2&&evt.cards2.length>0; - })); - player.syncStorage('twxiangyu_range'); + silent: true, + charlotte: true, + content: function () { + player.addTempSkill("twxiangyu_range"); + player.markAuto( + "twxiangyu_range", + game.filterPlayer(function (current) { + if (player.getStorage("twxiangyu_range").includes(current)) return false; + var evt = trigger.getl(current); + return evt && evt.cards2 && evt.cards2.length > 0; + }) + ); + player.syncStorage("twxiangyu_range"); }, }, - range:{ - marktext:'羽', - intro:{ - content:function(storage,player){ - var num=Math.min(5,storage?storage.length:0); - return '攻击范围+'+num; + range: { + marktext: "羽", + intro: { + content: function (storage, player) { + var num = Math.min(5, storage ? storage.length : 0); + return "攻击范围+" + num; }, }, - charlotte:true, - onremove:true, + charlotte: true, + onremove: true, }, }, }, //顾雍 - twgyshenxing:{ - audio:'xinshenxing', - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('he')>=Math.min(2,player.countMark('twgyshenxing')); + twgyshenxing: { + audio: "xinshenxing", + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") >= Math.min(2, player.countMark("twgyshenxing")); }, - selectCard:function(){ - return Math.min(2,_status.event.player.countMark('twgyshenxing')); + selectCard: function () { + return Math.min(2, _status.event.player.countMark("twgyshenxing")); }, - prompt:function(){ - return '弃置'+get.cnNumber(Math.min(2,_status.event.player.countMark('twgyshenxing')))+'张牌并摸一张牌'; + prompt: function () { + return ( + "弃置" + + get.cnNumber(Math.min(2, _status.event.player.countMark("twgyshenxing"))) + + "张牌并摸一张牌" + ); }, - check:function(card){ - var num=_status.event.player.countCards('h',{color:get.color(card)}); - if(get.position(card)=='e') num++; - return (Math.max(4,7.1-num)-get.value(card))/num; + check: function (card) { + var num = _status.event.player.countCards("h", { color: get.color(card) }); + if (get.position(card) == "e") num++; + return (Math.max(4, 7.1 - num) - get.value(card)) / num; }, - filterCard:true, - position:'he', - content:function(){ + filterCard: true, + position: "he", + content: function () { player.draw(); - player.addMark('twgyshenxing',1); + player.addMark("twgyshenxing", 1); }, - marktext:'慎', - intro:{content:'已发动过#次'}, - ai:{ - order:function(item,player){ - if(!player.hasMark('twgyshenxing')) return 10; + marktext: "慎", + intro: { content: "已发动过#次" }, + ai: { + order: function (item, player) { + if (!player.hasMark("twgyshenxing")) return 10; return 1; }, - result:{player:1}, + result: { player: 1 }, }, }, - twbingyi:{ - audio:'bingyi_xin_guyong', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h'); + twbingyi: { + audio: "bingyi_xin_guyong", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h"); }, - filterx:function(event,player){ - var cards=player.getCards('h'); - if(cards.length==1) return true; - var color=get.color(cards[0],player),type=get.type2(cards[0],player); - for(var i=1; iplayer.getCardUsable({name:'sha'})){ - return player.hp>2?2:0; - } - return 1; - }).set('prompt',get.prompt('twyilie')); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twyilie'); - game.log(player,'选择了','#g【毅烈】','的','#y'+result.control); - if(result.index%2==0) player.addTempSkill('twyilie_add','phaseUseEnd'); - if(result.index>0) player.addTempSkill('twyilie_miss'); - if(result.index==2) player.loseHp(); + twyilie: { + audio: "spyilie", + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseControl("选项一", "选项二", "背水!", "cancel2") + .set("choiceList", [ + "本阶段内使用【杀】的次数上限+1", + "本回合内使用【杀】指定处于连环状态的目标后,或使用【杀】被【闪】抵消时,摸一张牌", + "背水!失去1点体力并依次执行上述所有选项", + ]) + .set("ai", function () { + if ( + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) > player.getCardUsable({ name: "sha" }) + ) { + return player.hp > 2 ? 2 : 0; + } + return 1; + }) + .set("prompt", get.prompt("twyilie")); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twyilie"); + game.log(player, "选择了", "#g【毅烈】", "的", "#y" + result.control); + if (result.index % 2 == 0) player.addTempSkill("twyilie_add", "phaseUseEnd"); + if (result.index > 0) player.addTempSkill("twyilie_miss"); + if (result.index == 2) player.loseHp(); } }, - subSkill:{ - add:{ - charlotte:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + subSkill: { + add: { + charlotte: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, - mark:true, - intro:{content:'本阶段使用【杀】的次数上限+1'}, + mark: true, + intro: { content: "本阶段使用【杀】的次数上限+1" }, }, - miss:{ - charlotte:true, - audio:'spyilie', - trigger:{player:['useCardToTargeted','shaMiss']}, - filter:function(event,player,name){ - if(name=='useCardToTargeted') return event.card.name=='sha'&&event.target.isLinked(); + miss: { + charlotte: true, + audio: "spyilie", + trigger: { player: ["useCardToTargeted", "shaMiss"] }, + filter: function (event, player, name) { + if (name == "useCardToTargeted") + return event.card.name == "sha" && event.target.isLinked(); return true; }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, }, }, }, - twfenming:{ - audio:'spfenming', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(target){ - return target!=player&&(target.countCards('he')||!target.isLinked()); + twfenming: { + audio: "spfenming", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (target) { + return target != player && (target.countCards("he") || !target.isLinked()); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twfenming'),function(card,player,target){ - return target!=player&&(target.countCards('he')||!target.isLinked()); - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twfenming',target); - var list=[],choiceList=[ - '令'+get.translation(target)+'弃置一张牌', - '令'+get.translation(target)+'横置', - '背水!横置并依次令'+get.translation(target)+'执行上述所有选项', - ]; - if(target.countCards('he')) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(!target.isLinked()) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(target.countCards('he')&&!target.isLinked()&&!player.isLinked()) list.push('背水!'); - else choiceList[2]=''+choiceList[2]+''; - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('choiceList',choiceList).set('ai',function(){ - var list=_status.event.controls; - if(list.includes('背水!')) return '背水!'; - if(list.includes('选项一')) return '选项一'; - return '选项二'; - }).set('prompt','奋命:请选择一项'); - } - else event.finish(); - 'step 2' - game.log(player,'选择了','#y'+result.control); - if(result.control=='背水!'&&!player.isLinked()) player.link(true); - if(result.control!='选项二') target.chooseToDiscard('he',true); - if(result.control!='选项一'&&!target.isLinked()) target.link(true); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twfenming"), function (card, player, target) { + return target != player && (target.countCards("he") || !target.isLinked()); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twfenming", target); + var list = [], + choiceList = [ + "令" + get.translation(target) + "弃置一张牌", + "令" + get.translation(target) + "横置", + "背水!横置并依次令" + get.translation(target) + "执行上述所有选项", + ]; + if (target.countCards("he")) list.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (!target.isLinked()) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (target.countCards("he") && !target.isLinked() && !player.isLinked()) + list.push("背水!"); + else choiceList[2] = '' + choiceList[2] + ""; + if (list.length == 1) event._result = { control: list[0] }; + else + player + .chooseControl(list) + .set("choiceList", choiceList) + .set("ai", function () { + var list = _status.event.controls; + if (list.includes("背水!")) return "背水!"; + if (list.includes("选项一")) return "选项一"; + return "选项二"; + }) + .set("prompt", "奋命:请选择一项"); + } else event.finish(); + "step 2"; + game.log(player, "选择了", "#y" + result.control); + if (result.control == "背水!" && !player.isLinked()) player.link(true); + if (result.control != "选项二") target.chooseToDiscard("he", true); + if (result.control != "选项一" && !target.isLinked()) target.link(true); }, }, //韩当 - twgongji:{ - audio:'regongji', - enable:'phaseUse', - usable:1, - position:'he', - filterCard:true, - locked:false, - filter:function(event,player){ - return player.countCards('he'); + twgongji: { + audio: "regongji", + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: true, + locked: false, + filter: function (event, player) { + return player.countCards("he"); }, - check:function(card){ - var base=0,player=_status.event.player,suit=get.suit(card,player),added=false,added2=false,added3; - if(get.type(card)=='equip'&&game.hasPlayer(function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - })) base+=6; - var hs=player.getCards('h'); - var muniu=player.getEquip('muniu'); - if(muniu&&card!=muniu&&muniu.cards) hs=hs.concat(muniu.cards); - for(var i of hs){ - if(i!=card&&get.name(i)=='sha'){ - if(get.suit(i,player)==suit){ - if(player.hasValueTarget(i,false)){ - added3=true; - base+=5.5; + check: function (card) { + var base = 0, + player = _status.event.player, + suit = get.suit(card, player), + added = false, + added2 = false, + added3; + if ( + get.type(card) == "equip" && + game.hasPlayer(function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + }) + ) + base += 6; + var hs = player.getCards("h"); + var muniu = player.getEquip("muniu"); + if (muniu && card != muniu && muniu.cards) hs = hs.concat(muniu.cards); + for (var i of hs) { + if (i != card && get.name(i) == "sha") { + if (get.suit(i, player) == suit) { + if (player.hasValueTarget(i, false)) { + added3 = true; + base += 5.5; } - } - else { - if(player.hasValueTarget(i,false)) added2=true; - if(!added&&!player.hasValueTarget(i,null,true)&&player.hasValueTarget(i,false,true)){ - base+=4; - added=true; + } else { + if (player.hasValueTarget(i, false)) added2 = true; + if ( + !added && + !player.hasValueTarget(i, null, true) && + player.hasValueTarget(i, false, true) + ) { + base += 4; + added = true; } } } } - if(added3&&!added2) base-=4.5; - return base-get.value(card); + if (added3 && !added2) base -= 4.5; + return base - get.value(card); }, - content:function(){ - 'step 0' - player.addTempSkill('twgongji2'); - player.markAuto('twgongji2',[get.suit(cards[0],player)]); - 'step 1' - if(get.type(cards[0],null,cards[0].original=='h'?player:false)=='equip'){ - player.chooseTarget('是否弃置一名角色的一张牌?',function(card,player,target){ - return player!=target&&target.countCards('he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - player.line(result.targets,'green'); - player.discardPlayerCard(result.targets[0],'he',true); + content: function () { + "step 0"; + player.addTempSkill("twgongji2"); + player.markAuto("twgongji2", [get.suit(cards[0], player)]); + "step 1"; + if (get.type(cards[0], null, cards[0].original == "h" ? player : false) == "equip") { + player + .chooseTarget("是否弃置一名角色的一张牌?", function (card, player, target) { + return player != target && target.countCards("he"); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + player.line(result.targets, "green"); + player.discardPlayerCard(result.targets[0], "he", true); } }, - mod:{ - attackRangeBase:function(){ + mod: { + attackRangeBase: function () { return Infinity; }, }, - ai:{ - order:4.5, - result:{player:1}, + ai: { + order: 4.5, + result: { player: 1 }, }, }, - twgongji2:{ - charlotte:true, - onremove:true, - mark:true, - intro:{content:'使用$花色的杀无任何次数限制'}, - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(_status.currentPhase==player&&event.card.name=='sha'&& - player.getStorage('twgongji2').includes(get.suit(event.card))&&event.addCount!==false) return true; + twgongji2: { + charlotte: true, + onremove: true, + mark: true, + intro: { content: "使用$花色的杀无任何次数限制" }, + trigger: { player: "useCard1" }, + filter: function (event, player) { + if ( + _status.currentPhase == player && + event.card.name == "sha" && + player.getStorage("twgongji2").includes(get.suit(event.card)) && + event.addCount !== false + ) + return true; return false; }, - forced:true, - locked:false, - popup:false, - firstDo:true, - content:function(){ - trigger.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + forced: true, + locked: false, + popup: false, + firstDo: true, + content: function () { + trigger.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, - mod:{ - cardUsable:function(card,player){ - if(card.name=='sha'){ + mod: { + cardUsable: function (card, player) { + if (card.name == "sha") { const suit = get.suit(card); - return suit === 'unsure' || player.getStorage('twgongji2').includes(suit); + return suit === "unsure" || player.getStorage("twgongji2").includes(suit); } }, - aiOrder:function(player,card,num){ - if(get.name(card)=='sha'&&!player.getStorage('twgongji2').includes(get.suit(card))) return num+1; + aiOrder: function (player, card, num) { + if ( + get.name(card) == "sha" && + !player.getStorage("twgongji2").includes(get.suit(card)) + ) + return num + 1; }, }, }, - twjiefan:{ - skillAnimation:true, - animationColor:'wood', - audio:'jiefan_re_handang', - limited:true, - enable:'phaseUse', - filterTarget:true, - content:function(){ - 'step 0' - player.awakenSkill('twjiefan'); - event.players=game.filterPlayer(function(current){ - return current!=target&¤t.inRange(target); + twjiefan: { + skillAnimation: true, + animationColor: "wood", + audio: "jiefan_re_handang", + limited: true, + enable: "phaseUse", + filterTarget: true, + content: function () { + "step 0"; + player.awakenSkill("twjiefan"); + event.players = game.filterPlayer(function (current) { + return current != target && current.inRange(target); }); event.players.sortBySeat(); - 'step 1' - if(event.players.length){ - event.current=event.players.shift(); - event.current.addTempClass('target'); - player.line(event.current,'green'); - if(!event.current.countCards('he')||!target.isIn()) event._result={bool:false}; - else{ - event.current.chooseToDiscard({subtype:'equip1'},'he','解烦:弃置一张武器牌,或令'+get.translation(target)+'摸一张牌').set('ai',function(card){ - if(!_status.event.target.isIn()) return 0; - if(get.attitude(_status.event.player,_status.event.target)<0) return 7-get.value(card); - return -1; - }).set('target',target); + "step 1"; + if (event.players.length) { + event.current = event.players.shift(); + event.current.addTempClass("target"); + player.line(event.current, "green"); + if (!event.current.countCards("he") || !target.isIn()) + event._result = { bool: false }; + else { + event.current + .chooseToDiscard( + { subtype: "equip1" }, + "he", + "解烦:弃置一张武器牌,或令" + get.translation(target) + "摸一张牌" + ) + .set("ai", function (card) { + if (!_status.event.target.isIn()) return 0; + if (get.attitude(_status.event.player, _status.event.target) < 0) + return 7 - get.value(card); + return -1; + }) + .set("target", target); } - } - else { - player.addSkill('twjiefan2'); - player.markAuto('twjiefan2',[target]); + } else { + player.addSkill("twjiefan2"); + player.markAuto("twjiefan2", [target]); event.finish(); } - 'step 2' - if(!result.bool&&target.isIn()) target.draw(); + "step 2"; + if (!result.bool && target.isIn()) target.draw(); event.goto(1); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(player.hp>2&&game.phaseNumber 2 && game.phaseNumber < game.players.length * 2) return 0; + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != target && players[i].inRange(target)) { num++; } } return num; - } - } - } - }, - twjiefan2:{ - charlotte:true, - onremove:true, - trigger:{global:'dying'}, - filter:function(event,player){ - return player.getStorage('twjiefan2').includes(event.player); - }, - forced:true, - popup:false, - content:function(){ - player.removeSkill('twjiefan2'); - player.restoreSkill('twjiefan'); + }, + }, }, }, - jiefan_re_handang:{audio:2}, + twjiefan2: { + charlotte: true, + onremove: true, + trigger: { global: "dying" }, + filter: function (event, player) { + return player.getStorage("twjiefan2").includes(event.player); + }, + forced: true, + popup: false, + content: function () { + player.removeSkill("twjiefan2"); + player.restoreSkill("twjiefan"); + }, + }, + jiefan_re_handang: { audio: 2 }, //纪灵 - twshuangren:{ - audio:'shuangren', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player,name){ - if(!player.countCards('h')) return false; - if(name=='phaseUseEnd') return !player.hasHistory('sourceDamage',function(evt){ - return evt.card.name=='sha'&&event.getParent('phaseUse')==evt; - }); + twshuangren: { + audio: "shuangren", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player, name) { + if (!player.countCards("h")) return false; + if (name == "phaseUseEnd") + return !player.hasHistory("sourceDamage", function (evt) { + return evt.card.name == "sha" && event.getParent("phaseUse") == evt; + }); return true; }, - direct:true, - group:'twshuangren_end', - preHidden:true, - content:function(){ - 'step 0' - var forced=event.getParent(2).name=='twshuangren_end'&&game.hasPlayer(current=>{ - return player.canCompare(current); - }); - var str='与一名角色拼点,若你:赢,你可以视为对至多两名至其的距离不大于1的角色使用一张【杀】;没赢,其可以视为对你使用一张【杀】'; - player.chooseTarget(forced?'双刃:选择一名角色':get.prompt('twshuangren'),str,forced,(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',target=>{ - if(_status.event.goon) return get.effect(target,{name:'sha'},_status.event.player); - return 0; - }).set('goon',event.triggername!='phaseUseBegin'||(player.countCards('hs','sha')>0&&player.hasValueTarget({name:'sha'}))); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twshuangren',target); - if(player.canCompare(target)) player.chooseToCompare(target); - else event.finish(); - } - else event.finish(); - 'step 2' - if(result.bool){ - event.sha=true; - player.chooseTarget([1,2],'请选择【杀】的目标',true,function(card,player,target){ - if(!player.canUse('sha',target,false,false)) return false; - return get.distance(target,_status.event.targetx)<=1; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }).set('targetx',target); - } - else target.chooseBool('双刃:是否视为对'+get.translation(player)+'使用一张杀?').set('choice',get.effect(player,{name:'sha'},target,target)>0); - 'step 3' - if(result.bool){ - if(event.sha==true) { - result.targets.sortBySeat(); - for(var i of result.targets){ - player.useCard({name:'sha',isCard:true},i,false); + direct: true, + group: "twshuangren_end", + preHidden: true, + content: function () { + "step 0"; + var forced = + event.getParent(2).name == "twshuangren_end" && + game.hasPlayer((current) => { + return player.canCompare(current); + }); + var str = + "与一名角色拼点,若你:赢,你可以视为对至多两名至其的距离不大于1的角色使用一张【杀】;没赢,其可以视为对你使用一张【杀】"; + player + .chooseTarget( + forced ? "双刃:选择一名角色" : get.prompt("twshuangren"), + str, + forced, + (card, player, target) => { + return player.canCompare(target); } - } - else target.useCard({name:'sha',isCard:true},player,false); + ) + .set("ai", (target) => { + if (_status.event.goon) + return get.effect(target, { name: "sha" }, _status.event.player); + return 0; + }) + .set( + "goon", + event.triggername != "phaseUseBegin" || + (player.countCards("hs", "sha") > 0 && player.hasValueTarget({ name: "sha" })) + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twshuangren", target); + if (player.canCompare(target)) player.chooseToCompare(target); + else event.finish(); + } else event.finish(); + "step 2"; + if (result.bool) { + event.sha = true; + player + .chooseTarget( + [1, 2], + "请选择【杀】的目标", + true, + function (card, player, target) { + if (!player.canUse("sha", target, false, false)) return false; + return get.distance(target, _status.event.targetx) <= 1; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }) + .set("targetx", target); + } else + target + .chooseBool("双刃:是否视为对" + get.translation(player) + "使用一张杀?") + .set("choice", get.effect(player, { name: "sha" }, target, target) > 0); + "step 3"; + if (result.bool) { + if (event.sha == true) { + result.targets.sortBySeat(); + for (var i of result.targets) { + player.useCard({ name: "sha", isCard: true }, i, false); + } + } else target.useCard({ name: "sha", isCard: true }, player, false); } }, - subSkill:{ - end:{ - audio:'shuangren', - trigger:{player:'phaseUseEnd'}, - filter:function(event,player,name){ - if(!player.countCards('h')) return false; - return !player.hasHistory('useSkill',function(evt){ - return evt.skill=='twshuangren'; - })&&!player.hasHistory('sourceDamage',function(evt){ - return evt.card&&evt.card.name=='sha'; - }); + subSkill: { + end: { + audio: "shuangren", + trigger: { player: "phaseUseEnd" }, + filter: function (event, player, name) { + if (!player.countCards("h")) return false; + return ( + !player.hasHistory("useSkill", function (evt) { + return evt.skill == "twshuangren"; + }) && + !player.hasHistory("sourceDamage", function (evt) { + return evt.card && evt.card.name == "sha"; + }) + ); }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('twshuangren'),'弃置一张牌发动〖双刃〗','he').set('ai',function(card){ - if(_status.event.goon) return 5-get.value(card); - return 0; - }).set('goon',function(){ - return player.hasCard(function(card){ - if(player.needsToDiscard()>1) return card.number>10&&get.value(card)<=5; - return (card.number>=9&&get.value(card)<=5)||get.value(card)<=3; - }); - }()).setHiddenSkill('twshuangren').set('logSkill','twshuangren'); - 'step 1' - if(result.bool){ - player.useSkill('twshuangren'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt("twshuangren"), "弃置一张牌发动〖双刃〗", "he") + .set("ai", function (card) { + if (_status.event.goon) return 5 - get.value(card); + return 0; + }) + .set( + "goon", + (function () { + return player.hasCard(function (card) { + if (player.needsToDiscard() > 1) + return card.number > 10 && get.value(card) <= 5; + return ( + (card.number >= 9 && get.value(card) <= 5) || + get.value(card) <= 3 + ); + }); + })() + ) + .setHiddenSkill("twshuangren") + .set("logSkill", "twshuangren"); + "step 1"; + if (result.bool) { + player.useSkill("twshuangren"); } - } - } - } + }, + }, + }, }, //法正 - twxuanhuo:{ - audio:'rexuanhuo', - trigger:{player:'phaseDrawEnd'}, - filter:function(event,player){ - return player.countCards('he')>1&&game.countPlayer()>2; + twxuanhuo: { + audio: "rexuanhuo", + trigger: { player: "phaseDrawEnd" }, + filter: function (event, player) { + return player.countCards("he") > 1 && game.countPlayer() > 2; }, - direct:true, - content:function(){ - 'step 0' - var ai2=function(target){ - var player=_status.event.player; - if(get.attitude(player,target)<=0) return 0; - var list=['sha','juedou']; - var num=Math.max.apply(Math,list.map(function(i){ - return target.getUseValue({name:i,isCard:true},false); - })); - if(target.hasSkillTag('nogain')) num/=4; + direct: true, + content: function () { + "step 0"; + var ai2 = function (target) { + var player = _status.event.player; + if (get.attitude(player, target) <= 0) return 0; + var list = ["sha", "juedou"]; + var num = Math.max.apply( + Math, + list.map(function (i) { + return target.getUseValue({ name: i, isCard: true }, false); + }) + ); + if (target.hasSkillTag("nogain")) num /= 4; return num; }; player.chooseCardTarget({ - prompt:get.prompt2('twxuanhuo'), - filterCard:true, - selectCard:2, - position:'he', - filterTarget:lib.filter.notMe, - goon:game.hasPlayer(function(current){ - return current!=player&&ai2(player,current)>0; + prompt: get.prompt2("twxuanhuo"), + filterCard: true, + selectCard: 2, + position: "he", + filterTarget: lib.filter.notMe, + goon: game.hasPlayer(function (current) { + return current != player && ai2(player, current) > 0; }), - ai1:function(card){ - if(!_status.event.goon) return 0; - return 7-get.value(card); + ai1: function (card) { + if (!_status.event.goon) return 0; + return 7 - get.value(card); }, - ai2:ai2, + ai2: ai2, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twxuanhuo',target); - player.give(result.cards,target); - } + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twxuanhuo", target); + player.give(result.cards, target); + } else event.finish(); + "step 2"; + if ( + game.hasPlayer(function (current) { + return current != player && current != target; + }) + ) + player + .chooseTarget( + function (card, player, target) { + return target != player && target != _status.event.target; + }, + "选择" + get.translation(target) + "使用【杀】或【决斗】的目标", + true + ) + .set("target", target) + .set("ai", function (target) { + var evt = _status.event; + var list = ["sha", "juedou"]; + return Math.max.apply( + Math, + list.map(function (i) { + var card = { name: i, isCard: true }; + if (!evt.target.canUse(card, target, false)) return 0; + return get.effect(target, card, evt.target, evt.player); + }) + ); + }); else event.finish(); - 'step 2' - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target; - })) player.chooseTarget(function(card,player,target){ - return target!=player&&target!=_status.event.target; - },'选择'+get.translation(target)+'使用【杀】或【决斗】的目标',true).set('target',target).set('ai',function(target){ - var evt=_status.event; - var list=['sha','juedou']; - return Math.max.apply(Math,list.map(function(i){ - var card={name:i,isCard:true}; - if(!evt.target.canUse(card,target,false)) return 0; - return get.effect(target,card,evt.target,evt.player); - })); - }); - else event.finish(); - 'step 3' - var target2=result.targets[0]; - event.target2=target2; + "step 3"; + var target2 = result.targets[0]; + event.target2 = target2; player.line(target2); - var vcards=[]; - if(target.canUse({name:'sha',isCard:true},target2,false)) vcards.push(['基本','','sha']); - if(target.canUse({name:'juedou',isCard:true},target2,false)) vcards.push(['锦囊','','juedou']); - if(!vcards.length){ - if(!target.countCards('h')) event.finish(); - else event._result={index:1}; + var vcards = []; + if (target.canUse({ name: "sha", isCard: true }, target2, false)) + vcards.push(["基本", "", "sha"]); + if (target.canUse({ name: "juedou", isCard: true }, target2, false)) + vcards.push(["锦囊", "", "juedou"]); + if (!vcards.length) { + if (!target.countCards("h")) event.finish(); + else event._result = { index: 1 }; + } else if (!target.countCards("h")) { + event.vcards = vcards; + event._result = { index: 0 }; + } else { + event.vcards = vcards; + target + .chooseControl() + .set("choiceList", [ + "视为对" + get.translation(target2) + "使用一张【杀】或【决斗】", + "令" + get.translation(player) + "获得你的两张牌", + ]); } - else if(!target.countCards('h')){ - event.vcards=vcards; - event._result={index:0}; - } - else { - event.vcards=vcards; - target.chooseControl().set('choiceList',[ - '视为对'+get.translation(target2)+'使用一张【杀】或【决斗】', - '令'+get.translation(player)+'获得你的两张牌', - ]); - } - 'step 4' - if(result.index==0){ - if(event.vcards.length==1) event._result={links:event.vcards,bool:true}; - else target.chooseButton(['请选择要对'+get.translation(event.target2)+'使用的牌',[event.vcards,'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - return get.effect(_status.event.getParent().target2,{name:button.link[2],isCard:true},player,player); - }); - } - else { - player.gainPlayerCard(target,2,'he',true); + "step 4"; + if (result.index == 0) { + if (event.vcards.length == 1) event._result = { links: event.vcards, bool: true }; + else + target + .chooseButton( + [ + "请选择要对" + get.translation(event.target2) + "使用的牌", + [event.vcards, "vcard"], + ], + true + ) + .set("ai", function (button) { + var player = _status.event.player; + return get.effect( + _status.event.getParent().target2, + { name: button.link[2], isCard: true }, + player, + player + ); + }); + } else { + player.gainPlayerCard(target, 2, "he", true); event.finish(); } - 'step 5' - if(result.bool) target.useCard({name:result.links[0][2],isCard:true},false,event.target2); + "step 5"; + if (result.bool) + target.useCard({ name: result.links[0][2], isCard: true }, false, event.target2); }, - ai:{ - expose:0.15, + ai: { + expose: 0.15, }, }, - twenyuan:{ - audio:'reenyuan', - group:['twenyuan1','twenyuan2'], + twenyuan: { + audio: "reenyuan", + group: ["twenyuan1", "twenyuan2"], }, - twenyuan1:{ - audio:'reenyuan', - trigger:{ - global:['gainAfter','loseAsyncAfter'] + twenyuan1: { + audio: "reenyuan", + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - direct:true, - filter:function(event,player){ - var cards=event.getg(player); - if(!cards.length||cards.length<2) return false; - return game.countPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(evt&&evt.cards&&evt.cards.filter(card=>cards.includes(card)).length>=2) return true; + direct: true, + filter: function (event, player) { + var cards = event.getg(player); + if (!cards.length || cards.length < 2) return false; + return game.countPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (evt && evt.cards && evt.cards.filter((card) => cards.includes(card)).length >= 2) + return true; return false; }); }, - check:function(event,player){ - var cards=event.getg(player); - var target=game.filterPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(evt&&evt.cards&&evt.cards.filter(card=>cards.includes(card)).length>=2) return true; + check: function (event, player) { + var cards = event.getg(player); + var target = game.filterPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (evt && evt.cards && evt.cards.filter((card) => cards.includes(card)).length >= 2) + return true; return false; })[0]; - return get.attitude(player,target)>0; + return get.attitude(player, target) > 0; }, - logTarget:function(event,player){ - var cards=event.getg(player); - return game.filterPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(evt&&evt.cards&&evt.cards.filter(card=>cards.includes(card)).length>=2) return true; + logTarget: function (event, player) { + var cards = event.getg(player); + return game.filterPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (evt && evt.cards && evt.cards.filter((card) => cards.includes(card)).length >= 2) + return true; return false; }); }, - content:function(){ - 'step 0' - var target=lib.skill.twenyuan1.logTarget(trigger,player)[0]; - event.target=target; - var list=['摸一张牌']; - var prompt2='令'+get.translation(target)+'摸一张牌'; - if((!target.countCards('h')||!target.countCards('e'))&&target.isDamaged()){ - list.push('回复1点体力'); - prompt2+='或回复1点体力'; + content: function () { + "step 0"; + var target = lib.skill.twenyuan1.logTarget(trigger, player)[0]; + event.target = target; + var list = ["摸一张牌"]; + var prompt2 = "令" + get.translation(target) + "摸一张牌"; + if ((!target.countCards("h") || !target.countCards("e")) && target.isDamaged()) { + list.push("回复1点体力"); + prompt2 += "或回复1点体力"; } - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('twenyuan',target)).set('prompt2',prompt2).set('ai',()=>_status.event.choice).set('choice',function(){ - if(get.attitude(player,target)>0){ - if(target.hp<=2&&list.includes('回复1点体力')) return '回复1点体力'; - return 0; - } - return 'cancel2'; - }()); - 'step 1' - if(result.control=='cancel2'){ - event.finish(); return; + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("twenyuan", target)) + .set("prompt2", prompt2) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + if (get.attitude(player, target) > 0) { + if (target.hp <= 2 && list.includes("回复1点体力")) return "回复1点体力"; + return 0; + } + return "cancel2"; + })() + ); + "step 1"; + if (result.control == "cancel2") { + event.finish(); + return; } - player.logSkill('twenyuan1',target); - if(result.control=='回复1点体力') target.recover(); + player.logSkill("twenyuan1", target); + if (result.control == "回复1点体力") target.recover(); else target.draw(); }, }, - twenyuan2:{ - audio:'reenyuan', - trigger:{player:'damageEnd'}, - logTarget:'source', - filter:function(event,player){ - return event.source&&event.source.isIn(); + twenyuan2: { + audio: "reenyuan", + trigger: { player: "damageEnd" }, + logTarget: "source", + filter: function (event, player) { + return event.source && event.source.isIn(); }, - check:function(event,player){ - var att=get.attitude(player,event.source); - var num=event.source.countCards('h'); - if(att<=0) return true; - if(get.effect(event.source,{name:'losehp'},player,event.source)>0) return true; - if(num>2) return true; - if(num) return att<4; + check: function (event, player) { + var att = get.attitude(player, event.source); + var num = event.source.countCards("h"); + if (att <= 0) return true; + if (get.effect(event.source, { name: "losehp" }, player, event.source) > 0) return true; + if (num > 2) return true; + if (num) return att < 4; return false; }, - prompt2:'令其选择一项:1.失去1点体力;2.交给你一张手牌,若此牌的花色不为♥,你摸一张牌。', - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' - var target=trigger.source; + prompt2: "令其选择一项:1.失去1点体力;2.交给你一张手牌,若此牌的花色不为♥,你摸一张牌。", + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; + var target = trigger.source; event.count--; - if(!target.countCards('h')) event._result={bool:false}; - else target.chooseCard('h','恩怨:将一张手牌交给'+get.translation(player)+',或失去1点体力').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - if(get.suit(card)!='heart') return 15-get.value(card); - return 11-get.value(card); - } - else { - var num=12-_status.event.player.hp*2; - if(get.suit(card)!='heart') num-=2; - return num-get.value(card); - } - }); - 'step 2' - var target=trigger.source; - if(result.bool){ - var card=result.cards[0]; - event.card=card; - target.give(card,player); - } - else{ + if (!target.countCards("h")) event._result = { bool: false }; + else + target + .chooseCard( + "h", + "恩怨:将一张手牌交给" + get.translation(player) + ",或失去1点体力" + ) + .set("ai", function (card) { + if ( + get.attitude(_status.event.player, _status.event.getParent().player) > 0 + ) { + if (get.suit(card) != "heart") return 15 - get.value(card); + return 11 - get.value(card); + } else { + var num = 12 - _status.event.player.hp * 2; + if (get.suit(card) != "heart") num -= 2; + return num - get.value(card); + } + }); + "step 2"; + var target = trigger.source; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + target.give(card, player); + } else { target.loseHp(); event.goto(4); } - 'step 3' - if(get.suit(card)!='heart') player.draw(); - 'step 4' - var target=trigger.source; - if(target.isIn()&&event.count>0&&player.hasSkill('twenyuan')) player.chooseBool(get.prompt('twenyuan',target),lib.skill.twenyuan2.prompt2).set('ai',function(){ - var evt=_status.event.getTrigger(); - return lib.skill.twenyuan2.check(evt,evt.player); - }); + "step 3"; + if (get.suit(card) != "heart") player.draw(); + "step 4"; + var target = trigger.source; + if (target.isIn() && event.count > 0 && player.hasSkill("twenyuan")) + player + .chooseBool(get.prompt("twenyuan", target), lib.skill.twenyuan2.prompt2) + .set("ai", function () { + var evt = _status.event.getTrigger(); + return lib.skill.twenyuan2.check(evt, evt.player); + }); else event.finish(); - 'step 5' - if(result.bool){ - player.logSkill('twenyuan2',trigger.source); + "step 5"; + if (result.bool) { + player.logSkill("twenyuan2", trigger.source); event.goto(1); } }, }, //马岱 - twqianxi:{ - audio:'qianxi', - trigger:{player:'phaseZhunbeiBegin'}, - preHidden:true, - content:function(){ - 'step 0' + twqianxi: { + audio: "qianxi", + trigger: { player: "phaseZhunbeiBegin" }, + preHidden: true, + content: function () { + "step 0"; player.draw(); - 'step 1' - if(player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'tweqianxi'),'he')) player.chooseToDiscard('he',true); + "step 1"; + if (player.hasCard((card) => lib.filter.cardDiscardable(card, player, "tweqianxi"), "he")) + player.chooseToDiscard("he", true); else event.finish(); - 'step 2' - if(!result.bool||!game.hasPlayer(target=>{ - return player!=target&&get.distance(player,target)<=1; - })){ + "step 2"; + if ( + !result.bool || + !game.hasPlayer((target) => { + return player != target && get.distance(player, target) <= 1; + }) + ) { event.finish(); return; } - event.color=get.color(result.cards[0],player); - player.chooseTarget(function(card,player,target){ - return player!=target&&get.distance(player,target)<=1; - },true).set('ai',function(target){ - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player)+5; - }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; + event.color = get.color(result.cards[0], player); + player + .chooseTarget(function (card, player, target) { + return player != target && get.distance(player, target) <= 1; + }, true) + .set("ai", function (target) { + return ( + get.effect( + target, + { name: "sha" }, + _status.event.player, + _status.event.player + ) + 5 + ); + }); + "step 3"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - target.storage.twqianxi2=event.color; - target.addTempSkill('twqianxi2'); - player.addTempSkill('twqianxi_self'); - player.markAuto('twqianxi_self',[target]); + target.storage.twqianxi2 = event.color; + target.addTempSkill("twqianxi2"); + player.addTempSkill("twqianxi_self"); + player.markAuto("twqianxi_self", [target]); } }, - subSkill:{ - self:{ - audio:'qianxi', - charlotte:true, - onremove:true, - forced:true, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasHistory('sourceDamage',evt=>{ - if(!evt.card||evt.card.name!='sha'||!evt.player.isIn()) return false; - if(player.getStorage('twqianxi_self').includes(evt.player)) return true; + subSkill: { + self: { + audio: "qianxi", + charlotte: true, + onremove: true, + forced: true, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.hasHistory("sourceDamage", (evt) => { + if (!evt.card || evt.card.name != "sha" || !evt.player.isIn()) return false; + if (player.getStorage("twqianxi_self").includes(evt.player)) return true; return false; }); }, - content:function(){ - 'step 0' - var targets=[]; - player.getHistory('sourceDamage',evt=>{ - if(!evt.card||evt.card.name!='sha') return false; - if(player.getStorage('twqianxi_self').includes(evt.player)){ + content: function () { + "step 0"; + var targets = []; + player.getHistory("sourceDamage", (evt) => { + if (!evt.card || evt.card.name != "sha") return false; + if (player.getStorage("twqianxi_self").includes(evt.player)) { targets.add(evt.player); } return false; }); player.line(targets); - for(var target of targets){ - target.storage.twqianxi3=target.storage.twqianxi2; - target.addTempSkill('twqianxi3',{player:'phaseAfter'}); + for (var target of targets) { + target.storage.twqianxi3 = target.storage.twqianxi2; + target.addTempSkill("twqianxi3", { player: "phaseAfter" }); } - } - } - } - }, - twqianxi2:{ - mark:true, - charlotte:true, - onremove:true, - intro:{ - markcount:()=>0, - content:function(storage){ - return '不能使用或打出'+get.translation(storage)+'手牌'; - }, - }, - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&get.color(card)==player.getStorage('twqianxi2')&&get.position(card)=='h') return false; + }, }, }, }, - twqianxi3:{ - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&get.color(card)!=player.getStorage('twqianxi3')&&get.position(card)=='h') return false; + twqianxi2: { + mark: true, + charlotte: true, + onremove: true, + intro: { + markcount: () => 0, + content: function (storage) { + return "不能使用或打出" + get.translation(storage) + "手牌"; }, }, - mark:true, - intro:{ - content:function(storage){ - return '不能使用或打出非'+get.translation(storage)+'手牌'; + mod: { + cardEnabled2: function (card, player) { + if ( + get.itemtype(card) == "card" && + get.color(card) == player.getStorage("twqianxi2") && + get.position(card) == "h" + ) + return false; }, }, - charlotte:true, - onremove:true, + }, + twqianxi3: { + mod: { + cardEnabled2: function (card, player) { + if ( + get.itemtype(card) == "card" && + get.color(card) != player.getStorage("twqianxi3") && + get.position(card) == "h" + ) + return false; + }, + }, + mark: true, + intro: { + content: function (storage) { + return "不能使用或打出非" + get.translation(storage) + "手牌"; + }, + }, + charlotte: true, + onremove: true, }, //牛金 - twcuorui:{ - audio:'cuorui', - limited:true, - skillAnimation:true, - animationColor:'thunder', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>player.countCards('h'); + twcuorui: { + audio: "cuorui", + limited: true, + skillAnimation: true, + animationColor: "thunder", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") > player.countCards("h"); }); }, - check:function(event,player){ - var num=0; - for(var target of game.players){ - if(target!=player&&target.countCards('h')>num) num=target.countCards('h'); + check: function (event, player) { + var num = 0; + for (var target of game.players) { + if (target != player && target.countCards("h") > num) num = target.countCards("h"); } - num=Math.min(num,5+player.countCards('h')); - return num-player.countCards('h')>=2; + num = Math.min(num, 5 + player.countCards("h")); + return num - player.countCards("h") >= 2; }, - prompt:function(event,player){ - var num=0; - for(var target of game.players){ - if(target!=player&&target.countCards('h')>num) num=target.countCards('h'); + prompt: function (event, player) { + var num = 0; + for (var target of game.players) { + if (target != player && target.countCards("h") > num) num = target.countCards("h"); } - num=Math.min(num,5+player.countCards('h')); - return get.prompt('twcuorui')+'(可摸'+get.cnNumber(num-player.countCards('h'))+'张牌)'; + num = Math.min(num, 5 + player.countCards("h")); + return ( + get.prompt("twcuorui") + + "(可摸" + + get.cnNumber(num - player.countCards("h")) + + "张牌)" + ); }, - content:function(){ - 'step 0' - player.awakenSkill('twcuorui'); - var num=0; - for(var target of game.players){ - if(target!=player&&target.countCards('h')>num) num=target.countCards('h'); + content: function () { + "step 0"; + player.awakenSkill("twcuorui"); + var num = 0; + for (var target of game.players) { + if (target != player && target.countCards("h") > num) num = target.countCards("h"); } - num=Math.min(num,5+player.countCards('h')); + num = Math.min(num, 5 + player.countCards("h")); player.drawTo(num); - if(!player.isDisabledJudge()){ + if (!player.isDisabledJudge()) { player.disableJudge(); event.finish(); - } - else player.chooseTarget('挫锐:是否对一名其他角色造成1点伤害?',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ + } else + player + .chooseTarget("挫锐:是否对一名其他角色造成1点伤害?", lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { player.line(result.targets[0]); result.targets[0].damage(); } }, }, - twliewei:{ - audio:'liewei', - trigger:{source:'dieAfter'}, - forced:true, - content:function(){ - 'step 0' - if(!player.hasSkill('twcuorui',null,null,false)||!player.awakenedSkills.includes('twcuorui')) event._result={index:0}; - else player.chooseControl().set('prompt','裂围:请选择一项').set('choiceList',[ - '摸两张牌', - '重置〖挫锐〗' - ]).set('ai',function(){ - return 1; - }); - 'step 1' - if(result.index==0) player.draw(2); - else player.restoreSkill('twcuorui'); + twliewei: { + audio: "liewei", + trigger: { source: "dieAfter" }, + forced: true, + content: function () { + "step 0"; + if ( + !player.hasSkill("twcuorui", null, null, false) || + !player.awakenedSkills.includes("twcuorui") + ) + event._result = { index: 0 }; + else + player + .chooseControl() + .set("prompt", "裂围:请选择一项") + .set("choiceList", ["摸两张牌", "重置〖挫锐〗"]) + .set("ai", function () { + return 1; + }); + "step 1"; + if (result.index == 0) player.draw(2); + else player.restoreSkill("twcuorui"); }, }, //母兵脸 - twzhengrong:{ - audio:'drlt_zhenrong', - trigger:{player:'useCardAfter',source:'damageSource'}, - filter:function(event,player){ - if(!event.isPhaseUsing(player)) return false; - if(event.name=='damage') return player.getHistory('sourceDamage',evt=>{ - return evt.getParent('phaseUse')==event.getParent('phaseUse'); - }).indexOf(event)==0; - if(!event.targets||event.targets.every(target=>target==player)) return false; - return player.getAllHistory('useCard',function(evt){ - if(!evt.isPhaseUsing(player)) return false; - if(evt.targets.every(target=>target==player)) return false; - return true; - }).indexOf(event)%2==1; + twzhengrong: { + audio: "drlt_zhenrong", + trigger: { player: "useCardAfter", source: "damageSource" }, + filter: function (event, player) { + if (!event.isPhaseUsing(player)) return false; + if (event.name == "damage") + return ( + player + .getHistory("sourceDamage", (evt) => { + return evt.getParent("phaseUse") == event.getParent("phaseUse"); + }) + .indexOf(event) == 0 + ); + if (!event.targets || event.targets.every((target) => target == player)) return false; + return ( + player + .getAllHistory("useCard", function (evt) { + if (!evt.isPhaseUsing(player)) return false; + if (evt.targets.every((target) => target == player)) return false; + return true; + }) + .indexOf(event) % + 2 == + 1 + ); }, - direct:true, - content:function(){ - 'step 0' - if(!game.hasPlayer(function(target){ - return target!=player&&target.countCards('he'); - })){ + direct: true, + content: function () { + "step 0"; + if ( + !game.hasPlayer(function (target) { + return target != player && target.countCards("he"); + }) + ) { event.finish(); return; } - player.chooseTarget(get.prompt('twzhengrong'),'将一名其他角色的一张牌置于武将牌上,称为“荣”',function(card,player,target){ - return target!=player&&target.countCards('he'); - }).set('ai',function(target){ - return get.effect(target,{name:'guohe_copy2'},_status.event.player,_status.event.player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=result.targets[0]; - player.logSkill('twzhengrong',target); - player.choosePlayerCard(target,'he',true); - } - else event.finish(); - 'step 2' - if(result.bool) player.addToExpansion(result.links,target,'give').gaintag.add('twzhengrong'); + player + .chooseTarget( + get.prompt("twzhengrong"), + "将一名其他角色的一张牌置于武将牌上,称为“荣”", + function (card, player, target) { + return target != player && target.countCards("he"); + } + ) + .set("ai", function (target) { + return get.effect( + target, + { name: "guohe_copy2" }, + _status.event.player, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = result.targets[0]; + player.logSkill("twzhengrong", target); + player.choosePlayerCard(target, "he", true); + } else event.finish(); + "step 2"; + if (result.bool) + player.addToExpansion(result.links, target, "give").gaintag.add("twzhengrong"); }, - marktext:'荣', - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "荣", + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + intro: { + content: "expansion", + markcount: "expansion", }, - intro:{ - content:'expansion', - markcount:'expansion', - } }, - twhongju:{ - derivation:['twqingce','twsaotao'], - audio:'drlt_hongju', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.getExpansions('twzhengrong').length>=3; + twhongju: { + derivation: ["twqingce", "twsaotao"], + audio: "drlt_hongju", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.getExpansions("twzhengrong").length >= 3; }, - content:function(){ - 'step 0' - player.awakenSkill('twhongju'); - player.draw(player.getExpansions('twzhengrong').length); - 'step 1' - if(player.countCards('h')==0) event.goto(3); - else{ - var next=player.chooseToMove('鸿举:请选择要交换的手牌和“荣”'); - next.set('list',[ - [get.translation(player)+'(你)的“荣”',player.getExpansions('twzhengrong'),'twzhengrong_tag'], - ['手牌区',player.getCards('h')], + content: function () { + "step 0"; + player.awakenSkill("twhongju"); + player.draw(player.getExpansions("twzhengrong").length); + "step 1"; + if (player.countCards("h") == 0) event.goto(3); + else { + var next = player.chooseToMove("鸿举:请选择要交换的手牌和“荣”"); + next.set("list", [ + [ + get.translation(player) + "(你)的“荣”", + player.getExpansions("twzhengrong"), + "twzhengrong_tag", + ], + ["手牌区", player.getCards("h")], ]); - next.set('filterMove',function(from,to){ - return typeof to!='number'; + next.set("filterMove", function (from, to) { + return typeof to != "number"; }); - next.set('processAI',function(list){ - var player=_status.event.player,cards=list[0][1].concat(list[1][1]).sort(function(a,b){ - return player.getUseValue(a)-player.getUseValue(b); - }),cards2=cards.splice(0,player.getExpansions('twzhengrong').length); - return [cards2,cards]; + next.set("processAI", function (list) { + var player = _status.event.player, + cards = list[0][1].concat(list[1][1]).sort(function (a, b) { + return player.getUseValue(a) - player.getUseValue(b); + }), + cards2 = cards.splice(0, player.getExpansions("twzhengrong").length); + return [cards2, cards]; }); } - 'step 2' - if(result.bool){ - var pushs=result.moved[0],gains=result.moved[1]; - pushs.removeArray(player.getExpansions('twzhengrong')); - gains.removeArray(player.getCards('h')); - if(!pushs.length||pushs.length!=gains.length) return; - player.addToExpansion(pushs,player,'giveAuto').gaintag.add('twzhengrong'); - game.log(player,'将',pushs,'作为“荣”置于武将牌上'); - player.gain(gains,'gain2'); + "step 2"; + if (result.bool) { + var pushs = result.moved[0], + gains = result.moved[1]; + pushs.removeArray(player.getExpansions("twzhengrong")); + gains.removeArray(player.getCards("h")); + if (!pushs.length || pushs.length != gains.length) return; + player.addToExpansion(pushs, player, "giveAuto").gaintag.add("twzhengrong"); + game.log(player, "将", pushs, "作为“荣”置于武将牌上"); + player.gain(gains, "gain2"); } - 'step 3' - player.addSkills('twqingce'); - player.chooseBool('是否减1点体力上限并获得〖扫讨〗?').set('ai',()=>_status.event.bool).set('bool',player.isDamaged()&&player.countCards('h')>=3?(Math.random()<0.5?true:false):false); - 'step 4' - if(result.bool){ + "step 3"; + player.addSkills("twqingce"); + player + .chooseBool("是否减1点体力上限并获得〖扫讨〗?") + .set("ai", () => _status.event.bool) + .set( + "bool", + player.isDamaged() && player.countCards("h") >= 3 + ? Math.random() < 0.5 + ? true + : false + : false + ); + "step 4"; + if (result.bool) { player.loseMaxHp(); - player.addSkills('twsaotao'); + player.addSkills("twsaotao"); game.delayx(); } }, - }, - twqingce:{ - enable:'phaseUse', - audio:'drlt_qingce', - filter:function(event,player){ - return player.getExpansions('twzhengrong').length>0; + ai: { + combo: "twzhengrong" }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('清侧:请选择要移去的“荣”',player.getExpansions('twzhengrong'),'hidden'); + }, + twqingce: { + enable: "phaseUse", + audio: "drlt_qingce", + filter: function (event, player) { + return player.getExpansions("twzhengrong").length > 0; + }, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog( + "清侧:请选择要移去的“荣”", + player.getExpansions("twzhengrong"), + "hidden" + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - card:links[0], - filterCard:function(){return false}, - selectCard:-1, - filterTarget:function(card,player,target){ - return target.countDiscardableCards(player,'hej')>0; + card: links[0], + filterCard: function () { + return false; }, - delay:false, - audio:'drlt_qingce', - content:lib.skill.twqingce.contentx, - ai:{ - result:{ - target:function(player,target){ - return get.effect(target,{name:'guohe'},player,target); + selectCard: -1, + filterTarget: function (card, player, target) { + return target.countDiscardableCards(player, "hej") > 0; + }, + delay: false, + audio: "drlt_qingce", + content: lib.skill.twqingce.contentx, + ai: { + result: { + target: function (player, target) { + return get.effect(target, { name: "guohe" }, player, target); }, }, }, - } + }; }, - prompt:()=>'弃置一名角色区域内的一张牌', + prompt: () => "弃置一名角色区域内的一张牌", }, - contentx:function(){ - 'step 0' - var card=lib.skill.twqingce_backup.card; + contentx: function () { + "step 0"; + var card = lib.skill.twqingce_backup.card; player.loseToDiscardpile([card]); - 'step 1' - if(target.countDiscardableCards(player,'hej')>0) player.discardPlayerCard('hej',true,target); + "step 1"; + if (target.countDiscardableCards(player, "hej") > 0) + player.discardPlayerCard("hej", true, target); }, - ai:{ - order:8, - result:{ - player:function(player){ - if(game.hasPlayer(function(target){ - return get.effect(target,{name:'guohe'},player,player)>4*Math.max(0,5-player.getExpansions('twzhengrong').length); - })) return 1; + ai: { + order: 8, + result: { + player: function (player) { + if ( + game.hasPlayer(function (target) { + return ( + get.effect(target, { name: "guohe" }, player, player) > + 4 * Math.max(0, 5 - player.getExpansions("twzhengrong").length) + ); + }) + ) + return 1; return 0; }, }, }, }, - twsaotao:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='sha'||get.type(event.card)=='trick'; + twsaotao: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "sha" || get.type(event.card) == "trick"; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.directHit.addArray(game.players); }, - ai:{directHit_ai:true}, + ai: { directHit_ai: true }, }, //大小乔 - twxingwu:{ - audio:'xingwu', - trigger:{player:'phaseDiscardBegin'}, - filter:function(event,player){ - return player.countCards('he'); + twxingwu: { + audio: "xingwu", + trigger: { player: "phaseDiscardBegin" }, + filter: function (event, player) { + return player.countCards("he"); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('twxingwu'),'将一张牌置于武将牌上作为“星舞”').set('ai',function(card){ - if(_status.event.goon) return 20-get.value(card); - return 7-get.value(card); - }).set('goon',player.needsToDiscard()||player.getExpansions('twxingwu').length>1); - 'step 1' - if(result.bool){ - player.logSkill('twxingwu'); - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('twxingwu'); - } - else event.finish(); - 'step 2' + direct: true, + content: function () { + "step 0"; + player + .chooseCard("he", get.prompt("twxingwu"), "将一张牌置于武将牌上作为“星舞”") + .set("ai", function (card) { + if (_status.event.goon) return 20 - get.value(card); + return 7 - get.value(card); + }) + .set("goon", player.needsToDiscard() || player.getExpansions("twxingwu").length > 1); + "step 1"; + if (result.bool) { + player.logSkill("twxingwu"); + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("twxingwu"); + } else event.finish(); + "step 2"; game.delayx(); - if(player.getExpansions('twxingwu').length<3||!game.hasPlayer(current=>current!=player)) event.finish(); - 'step 3' - player.chooseButton(['是否移去三张“星舞”牌并发射核弹?',player.getExpansions('twxingwu')],3).set('ai',function(button){ - if(_status.event.goon) return 1; - return 0; - }).set('goon',game.hasPlayer(current=>get.damageEffect(current,player,player)<0)); - 'step 4' - if(result.bool) player.loseToDiscardpile(result.links); + if ( + player.getExpansions("twxingwu").length < 3 || + !game.hasPlayer((current) => current != player) + ) + event.finish(); + "step 3"; + player + .chooseButton( + ["是否移去三张“星舞”牌并发射核弹?", player.getExpansions("twxingwu")], + 3 + ) + .set("ai", function (button) { + if (_status.event.goon) return 1; + return 0; + }) + .set( + "goon", + game.hasPlayer((current) => get.damageEffect(current, player, player) < 0) + ); + "step 4"; + if (result.bool) player.loseToDiscardpile(result.links); else event.finish(); - 'step 5' - player.chooseTarget('星舞:选择一名其他角色','弃置其装备区内的所有牌。然后对其造成2点伤害(若其性别包含女性则改为1点)',true,lib.filter.notMe).set('ai',function(target){ - return get.damageEffect(target,player,player)*Math.sqrt(4+target.countCards('e',function(card){ - return get.value(card,target)>0; - }))*(target.hasSex('female')?1:2); - }); - 'step 6' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; - player.line(target,'green'); - var num=target.countCards('e'); - if(num) player.discardPlayerCard(target,'e',num,true); - target.damage(target.hasSex('female')?1:2); + "step 5"; + player + .chooseTarget( + "星舞:选择一名其他角色", + "弃置其装备区内的所有牌。然后对其造成2点伤害(若其性别包含女性则改为1点)", + true, + lib.filter.notMe + ) + .set("ai", function (target) { + return ( + get.damageEffect(target, player, player) * + Math.sqrt( + 4 + + target.countCards("e", function (card) { + return get.value(card, target) > 0; + }) + ) * + (target.hasSex("female") ? 1 : 2) + ); + }); + "step 6"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; + player.line(target, "green"); + var num = target.countCards("e"); + if (num) player.discardPlayerCard(target, "e", num, true); + target.damage(target.hasSex("female") ? 1 : 2); } }, - intro:{ - content:'expansion', - markcount:'expansion', - onunmark:function(storage,player){ - if(player.hasSkill('twpingting')) return; - player.removeAdditionalSkill('twpingting'); + intro: { + content: "expansion", + markcount: "expansion", + onunmark: function (storage, player) { + if (player.hasSkill("twpingting")) return; + player.removeAdditionalSkill("twpingting"); }, }, - onremove:function(player,skill){ - if(player.hasSkill('twpingting')) return; - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + if (player.hasSkill("twpingting")) return; + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, }, - twpingting:{ - audio:2, - trigger:{global:['roundStart','dying']}, - init:function(player,skill){ - if(player.getExpansions('twxingwu').length) player.addAdditionalSkill(skill,['tianxiang','liuli']); + twpingting: { + audio: 2, + trigger: { global: ["roundStart", "dying"] }, + init: function (player, skill) { + if (player.getExpansions("twxingwu").length) + player.addAdditionalSkill(skill, ["tianxiang", "liuli"]); else player.removeAdditionalSkill(skill); }, - filter:function(event,player){ - if(event.name=='dying') return player==_status.currentPhase&&event.player!=player; + filter: function (event, player) { + if (event.name == "dying") + return player == _status.currentPhase && event.player != player; return true; }, - forced:true, - group:'twpingting_update', - derivation:['tianxiang','liuli'], - content:function(){ - 'step 0' + forced: true, + group: "twpingting_update", + derivation: ["tianxiang", "liuli"], + content: function () { + "step 0"; player.draw(); - player.chooseCard('he','娉婷:将一张牌置于武将牌上,称为“星舞”',true).set('ai',function(card){ - return -get.value(card); - }); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('twxingwu'); - } - }, - onremove:function(player,skill){ - if(player.hasSkill('twxingwu')) return; - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); - }, - subSkill:{ - update:{ - trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']}, - filter:function(event,player){ - var cards=player.getExpansions('twxingwu'),skills=player.additionalSkills.twpingting; - return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length))); - }, - forced:true, - silent:true, - content:function(){ - lib.skill.twpingting.init(player,'twpingting'); - } - } - } - }, - tianxiang_daxiaoqiao:{audio:2,inherit:'tianxiang'}, - liuli_daxiaoqiao:{audio:2,inherit:'liuli'}, - //傅肜 - twxuewei:{ - audio:'xuewei', - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player!=player&&game.players.length>2&&!player.hasSkill('twxuewei_round'); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twxuewei'),function(card,player,target){ - return target!=player&&target!=_status.event.getTrigger().player; - }).set('ai',function(target){ - if(get.attitude(player,_status.event.getTrigger().player)>=0) return 0; - return get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twxuewei',trigger.player,false); - player.addTempSkill('twxuewei_round','roundStart'); - player.line2([trigger.player,target]); - trigger.player.chooseControl('选项一','选项二').set('choiceList',[ - '本回合不能对'+get.translation(target)+'使用【杀】且手牌上限-2', - '令'+get.translation(player)+'视为对你使用一张【决斗】', - ]).set('ai',function(){ - var player=_status.event.player,source=_status.event.getParent().player; - if(get.effect(player,{name:'juedou'},source,player)>0) return 1; - if(player.hp-player.countCards('h')>2||player.hp<=2) return 0; - return 1; + player + .chooseCard("he", "娉婷:将一张牌置于武将牌上,称为“星舞”", true) + .set("ai", function (card) { + return -get.value(card); }); + "step 1"; + if (result.bool) { + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("twxingwu"); } - else event.finish(); - 'step 2' - game.log(trigger.player,'选择了','#g【血卫】','的','#y'+result.control); - if(result.control=='选项一'){ - trigger.player.markAuto('twxuewei_block',[target]); - trigger.player.addTempSkill('twxuewei_block'); - } - else player.useCard({name:'juedou',isCard:true},trigger.player,false); }, - subSkill:{ - round:{charlotte:true}, - block:{ - charlotte:true, - onremove:true, - locked:true, - mark:true, - marktext:'卫', - intro:{ - content:function(storage,player){ - if(!storage||!storage.length) return; - return '不能对'+get.translation(storage)+'使用【杀】;手牌上限-'+(2*storage.length); - } + onremove: function (player, skill) { + if (player.hasSkill("twxingwu")) return; + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + subSkill: { + update: { + trigger: { player: ["loseAfter", "loseAsyncAfter", "addToExpansionAfter"] }, + filter: function (event, player) { + var cards = player.getExpansions("twxingwu"), + skills = player.additionalSkills.twpingting; + return !( + (cards.length && skills && skills.length) || + (!cards.length && (!skills || !skills.length)) + ); }, - mod:{ - maxHandcard:function(player,num){ - return num-2*player.getStorage('twxuewei_block').length; + forced: true, + silent: true, + content: function () { + lib.skill.twpingting.init(player, "twpingting"); + }, + }, + }, + }, + tianxiang_daxiaoqiao: { audio: 2, inherit: "tianxiang" }, + liuli_daxiaoqiao: { audio: 2, inherit: "liuli" }, + //傅肜 + twxuewei: { + audio: "xuewei", + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return ( + event.player != player && + game.players.length > 2 && + !player.hasSkill("twxuewei_round") + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twxuewei"), function (card, player, target) { + return target != player && target != _status.event.getTrigger().player; + }) + .set("ai", function (target) { + if (get.attitude(player, _status.event.getTrigger().player) >= 0) return 0; + return get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twxuewei", trigger.player, false); + player.addTempSkill("twxuewei_round", "roundStart"); + player.line2([trigger.player, target]); + trigger.player + .chooseControl("选项一", "选项二") + .set("choiceList", [ + "本回合不能对" + get.translation(target) + "使用【杀】且手牌上限-2", + "令" + get.translation(player) + "视为对你使用一张【决斗】", + ]) + .set("ai", function () { + var player = _status.event.player, + source = _status.event.getParent().player; + if (get.effect(player, { name: "juedou" }, source, player) > 0) return 1; + if (player.hp - player.countCards("h") > 2 || player.hp <= 2) return 0; + return 1; + }); + } else event.finish(); + "step 2"; + game.log(trigger.player, "选择了", "#g【血卫】", "的", "#y" + result.control); + if (result.control == "选项一") { + trigger.player.markAuto("twxuewei_block", [target]); + trigger.player.addTempSkill("twxuewei_block"); + } else player.useCard({ name: "juedou", isCard: true }, trigger.player, false); + }, + subSkill: { + round: { charlotte: true }, + block: { + charlotte: true, + onremove: true, + locked: true, + mark: true, + marktext: "卫", + intro: { + content: function (storage, player) { + if (!storage || !storage.length) return; + return ( + "不能对" + + get.translation(storage) + + "使用【杀】;手牌上限-" + + 2 * storage.length + ); }, - playerEnabled:function(card,player,target){ - if(card.name=='sha'&&player.getStorage('twxuewei_block').includes(target)) return false; + }, + mod: { + maxHandcard: function (player, num) { + return num - 2 * player.getStorage("twxuewei_block").length; + }, + playerEnabled: function (card, player, target) { + if ( + card.name == "sha" && + player.getStorage("twxuewei_block").includes(target) + ) + return false; }, }, }, }, }, - twliechi:{ - audio:'liechi', - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.hp>=player.hp&&(event.source.countCards('h')>player.countCards('h')||event.source.countCards('he')); + twliechi: { + audio: "liechi", + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.source && + event.source.hp >= player.hp && + (event.source.countCards("h") > player.countCards("h") || + event.source.countCards("he")) + ); }, - direct:true, - content:function(){ - 'step 0' - var num=trigger.source.countCards('h')-player.countCards('h'); - event.num=num; - var list=[],choiceList=[ - '令'+get.translation(trigger.source)+'弃置'+get.cnNumber(num)+'张手牌', - '弃置'+get.translation(trigger.source)+'一张牌', - '背水!弃置一张装备牌,然后依次执行以上所有选项', - ]; - if(trigger.source.countCards('h')>player.countCards('h')) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(trigger.source.countCards('he')) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(trigger.source.countCards('h')>player.countCards('h')&&trigger.source.countCards('he')&&player.countCards('he',{type:'equip'})&&game.getGlobalHistory('changeHp',evt=>{ - return evt.player==player&&evt.getParent()._dyinged; - }).length) list.push('背水!'); - else choiceList[2]=''+choiceList[2]+'(未进入过濒死状态)'; - player.chooseControl(list,'cancel2').set('prompt',get.prompt('twliechi',trigger.source)).set('choiceList',choiceList).set('ai',()=>_status.event.choice).set('choice',function(){ - if(get.attitude(player,trigger.source)>0) return 'cancel2'; - if(list.includes('背水!')) return '背水!'; - if(num>1) return '选项一'; - return '选项二'; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twliechi',trigger.source); - game.log(player,'选择了','#g【烈斥】','的','#y'+result.control); - if(result.control=='背水!') player.chooseToDiscard('he',{type:'equip'},true); - if(result.control!='选项二') trigger.source.chooseToDiscard('h',num,true); - if(result.control!='选项一') player.discardPlayerCard(trigger.source,'he',true); + direct: true, + content: function () { + "step 0"; + var num = trigger.source.countCards("h") - player.countCards("h"); + event.num = num; + var list = [], + choiceList = [ + "令" + get.translation(trigger.source) + "弃置" + get.cnNumber(num) + "张手牌", + "弃置" + get.translation(trigger.source) + "一张牌", + "背水!弃置一张装备牌,然后依次执行以上所有选项", + ]; + if (trigger.source.countCards("h") > player.countCards("h")) list.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if (trigger.source.countCards("he")) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if ( + trigger.source.countCards("h") > player.countCards("h") && + trigger.source.countCards("he") && + player.countCards("he", { type: "equip" }) && + game.getGlobalHistory("changeHp", (evt) => { + return evt.player == player && evt.getParent()._dyinged; + }).length + ) + list.push("背水!"); + else + choiceList[2] = + '' + choiceList[2] + "(未进入过濒死状态)"; + player + .chooseControl(list, "cancel2") + .set("prompt", get.prompt("twliechi", trigger.source)) + .set("choiceList", choiceList) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + if (get.attitude(player, trigger.source) > 0) return "cancel2"; + if (list.includes("背水!")) return "背水!"; + if (num > 1) return "选项一"; + return "选项二"; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twliechi", trigger.source); + game.log(player, "选择了", "#g【烈斥】", "的", "#y" + result.control); + if (result.control == "背水!") player.chooseToDiscard("he", { type: "equip" }, true); + if (result.control != "选项二") trigger.source.chooseToDiscard("h", num, true); + if (result.control != "选项一") player.discardPlayerCard(trigger.source, "he", true); } - } + }, }, //卢植 - twmingren:{ - marktext:'任', - intro:{ - content:'expansion', - markcount:'expansion', + twmingren: { + marktext: "任", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'twmingren_change', - audio:'nzry_mingren_1', - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&!player.getExpansions('twmingren').length; + group: "twmingren_change", + audio: "nzry_mingren_1", + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + !player.getExpansions("twmingren").length + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(); - 'step 1' - if(!player.countCards('h')) event.finish(); - else player.chooseCard('h','明任:将一张手牌置于武将牌上,称为“任”',true).set('ai',function(card){ - return 6-get.value(card); - }); - 'step 2' - if(result.bool) player.addToExpansion(result.cards[0],player,'give','log').gaintag.add('twmingren'); - }, - subSkill:{ - change:{ - audio:'nzry_mingren_1', - trigger:{player:['phaseUseBegin','phaseUseEnd']}, - filter:function(event,player){ - return player.countCards('he')&&player.getExpansions('twmingren').length; - }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('twmingren'),'用一张牌替换“任”('+get.translation(player.getExpansions('twmingren')[0])+')').set('ai',function(card){ - var player=_status.event.player; - var color=get.color(card); - if(color==get.color(player.getExpansions('twmingren')[0])) return false; - var num=0; - var list=[]; - player.countCards('he',function(cardx){ - if(cardx!=card||get.color(cardx)!=color) return false; - if(list.includes(cardx.name)) return false; - list.push(cardx.name); - switch (cardx.name){ - case 'wuxie':num+=(game.countPlayer()/2.2); break; - case 'caochuan':num+=1.1; break; - case 'shan':num+=1; break; - } - }); - return num*(30-get.value(card)); + "step 1"; + if (!player.countCards("h")) event.finish(); + else + player + .chooseCard("h", "明任:将一张手牌置于武将牌上,称为“任”", true) + .set("ai", function (card) { + return 6 - get.value(card); }); - 'step 1' - if(result.bool){ - player.logSkill('twmingren'); - player.addToExpansion(result.cards[0],'log','give',player).gaintag.add('twmingren'); - var card=player.getExpansions('twmingren')[0]; - if(card) player.gain(card,'gain2'); + "step 2"; + if (result.bool) + player + .addToExpansion(result.cards[0], player, "give", "log") + .gaintag.add("twmingren"); + }, + subSkill: { + change: { + audio: "nzry_mingren_1", + trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, + filter: function (event, player) { + return player.countCards("he") && player.getExpansions("twmingren").length; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + "he", + get.prompt("twmingren"), + "用一张牌替换“任”(" + + get.translation(player.getExpansions("twmingren")[0]) + + ")" + ) + .set("ai", function (card) { + var player = _status.event.player; + var color = get.color(card); + if (color == get.color(player.getExpansions("twmingren")[0])) + return false; + var num = 0; + var list = []; + player.countCards("he", function (cardx) { + if (cardx != card || get.color(cardx) != color) return false; + if (list.includes(cardx.name)) return false; + list.push(cardx.name); + switch (cardx.name) { + case "wuxie": + num += game.countPlayer() / 2.2; + break; + case "caochuan": + num += 1.1; + break; + case "shan": + num += 1; + break; + } + }); + return num * (30 - get.value(card)); + }); + "step 1"; + if (result.bool) { + player.logSkill("twmingren"); + player + .addToExpansion(result.cards[0], "log", "give", player) + .gaintag.add("twmingren"); + var card = player.getExpansions("twmingren")[0]; + if (card) player.gain(card, "gain2"); } }, }, }, }, - twzhenliang:{ - group:['twzhenliang_1','twzhenliang_2'], - audio:'nzry_zhenliang_1', - mark:true, - zhuanhuanji:true, - marktext:'☯', - intro:{ - content:function(storage,player,skill){ - if(player.storage.twzhenliang==true) return '当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。'; - return '出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。'; + twzhenliang: { + group: ["twzhenliang_1", "twzhenliang_2"], + audio: "nzry_zhenliang_1", + mark: true, + zhuanhuanji: true, + marktext: "☯", + intro: { + content: function (storage, player, skill) { + if (player.storage.twzhenliang == true) + return "当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。"; + return "出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。"; }, }, - subSkill:{ - 1:{ - audio:'nzry_zhenliang_1', - enable:'phaseUse', - filter:function(event,player){ - if(player.storage.twzhenliang) return false; - return game.hasPlayer(function(current){ + subSkill: { + 1: { + audio: "nzry_zhenliang_1", + enable: "phaseUse", + filter: function (event, player) { + if (player.storage.twzhenliang) return false; + return game.hasPlayer(function (current) { return player.inRange(current); }); }, - position:'he', - filterCard:true, - filterTarget:function(card,player,target){ + position: "he", + filterCard: true, + filterTarget: function (card, player, target) { return player.inRange(target); }, - check:function(card){ - var player=_status.event.player,cardx=player.getExpansions('twmingren')[0]; - if(cardx&&get.color(cardx,player)==get.color(card,player)) return 10-get.value(card); - return 7-get.value(card); + check: function (card) { + var player = _status.event.player, + cardx = player.getExpansions("twmingren")[0]; + if (cardx && get.color(cardx, player) == get.color(card, player)) + return 10 - get.value(card); + return 7 - get.value(card); }, - prompt:'弃置一张牌并对攻击范围内的一名角色造成1点伤害', - content:function(){ - 'step 0' - player.changeZhuanhuanji('twzhenliang'); - var cardx=player.getExpansions('twmingren')[0]; - target.damage('nocard'); - if(!cardx||get.color(cards[0],player)!=get.color(cardx,player)) event.finish(); - 'step 1' + prompt: "弃置一张牌并对攻击范围内的一名角色造成1点伤害", + content: function () { + "step 0"; + player.changeZhuanhuanji("twzhenliang"); + var cardx = player.getExpansions("twmingren")[0]; + target.damage("nocard"); + if (!cardx || get.color(cards[0], player) != get.color(cardx, player)) + event.finish(); + "step 1"; player.draw(); }, - ai:{ - order:5, - result:{ - player:function(player,target){ - return get.damageEffect(target,player,player); + ai: { + order: 5, + result: { + player: function (player, target) { + return get.damageEffect(target, player, player); }, }, }, }, - 2:{ - audio:'nzry_zhenliang_1', - trigger:{global:'damageBegin4'}, - filter:function(event,player){ - if(_status.currentPhase==player||!player.storage.twzhenliang) return false; - return player.countCards('he')&&event.num>0&&(event.player==player||player.inRange(event.player)); + 2: { + audio: "nzry_zhenliang_1", + trigger: { global: "damageBegin4" }, + filter: function (event, player) { + if (_status.currentPhase == player || !player.storage.twzhenliang) return false; + return ( + player.countCards("he") && + event.num > 0 && + (event.player == player || player.inRange(event.player)) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('twzhenliang',trigger.player),'弃置一张牌令此伤害-1').set('ai',function(card){ - if(_status.event.goon){ - var player=_status.event.player,cardx=player.getExpansions('twmingren')[0]; - if(cardx&&get.color(cardx,player)==get.color(card,player)) return 10-get.value(card); - return 6-get.value(card); - } - return 0; - }).set('goon',get.attitude(player,trigger.player)>0).logSkill=['twzhenliang',trigger.player]; - 'step 1' - if(result.bool){ - player.changeZhuanhuanji('twzhenliang'); - var cardx=player.getExpansions('twmingren')[0]; - if(cardx&&get.color(result.cards[0],player)==get.color(cardx,player)) player.draw(); + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("twzhenliang", trigger.player), + "弃置一张牌令此伤害-1" + ) + .set("ai", function (card) { + if (_status.event.goon) { + var player = _status.event.player, + cardx = player.getExpansions("twmingren")[0]; + if (cardx && get.color(cardx, player) == get.color(card, player)) + return 10 - get.value(card); + return 6 - get.value(card); + } + return 0; + }) + .set("goon", get.attitude(player, trigger.player) > 0).logSkill = [ + "twzhenliang", + trigger.player, + ]; + "step 1"; + if (result.bool) { + player.changeZhuanhuanji("twzhenliang"); + var cardx = player.getExpansions("twmingren")[0]; + if (cardx && get.color(result.cards[0], player) == get.color(cardx, player)) + player.draw(); trigger.num--; } }, @@ -7962,367 +10069,492 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //张南 - twfenwu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&&player.canUse('sha',current,false,false); + twfenwu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && player.canUse("sha", current, false, false); }); }, - direct:true, - content:function(){ - 'step 0' - var list=[]; - player.getHistory('useCard',function(evt){ - if(get.type(evt.card)!='basic') return; - var name=evt.card.name,nature=game.hasNature(evt.card)?get.nature(evt.card):''; - if(!list.includes(name+nature)) list.push(name+nature); + direct: true, + content: function () { + "step 0"; + var list = []; + player.getHistory("useCard", function (evt) { + if (get.type(evt.card) != "basic") return; + var name = evt.card.name, + nature = game.hasNature(evt.card) ? get.nature(evt.card) : ""; + if (!list.includes(name + nature)) list.push(name + nature); }); - event.addDamage=list.length>1; - player.chooseTarget(get.prompt('twfenwu'),'失去1点体力并视为使用一张无距离限制的【杀】'+(event.addDamage?'(伤害基数+1)':''),function(card,player,target){ - return target!=player&&player.canUse('sha',target,false,false); - }).set('ai',function(target){ - var player=_status.event.player; - if(player.hp+player.countCards('hs',{name:['tao','jiu']})<=1) return -1; - var num=1; - if((!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||player.hasSkillTag('directHit_ai',true,{ - target:target, - card:{name:'sha'}, - },true))&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:{name:'sha'}, - })){ - num=1.3; - } - return get.effect(target,{name:'sha'},player,player)*num; - }); - 'step 1' - if(result.bool){ - var num=1; - var target=result.targets[0]; - player.logSkill('twfenwu',target); + event.addDamage = list.length > 1; + player + .chooseTarget( + get.prompt("twfenwu"), + "失去1点体力并视为使用一张无距离限制的【杀】" + + (event.addDamage ? "(伤害基数+1)" : ""), + function (card, player, target) { + return target != player && player.canUse("sha", target, false, false); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (player.hp + player.countCards("hs", { name: ["tao", "jiu"] }) <= 1) return -1; + var num = 1; + if ( + (!target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: { name: "sha" }, + }, + true + )) && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: { name: "sha" }, + }) + ) { + num = 1.3; + } + return get.effect(target, { name: "sha" }, player, player) * num; + }); + "step 1"; + if (result.bool) { + var num = 1; + var target = result.targets[0]; + player.logSkill("twfenwu", target); player.loseHp(); - if(event.addDamage){ - num=2; - game.log('#y杀','的伤害基数+1'); + if (event.addDamage) { + num = 2; + game.log("#y杀", "的伤害基数+1"); } - player.useCard({name:'sha',isCard:true},target,false).baseDamage=num; + player.useCard({ name: "sha", isCard: true }, target, false).baseDamage = num; } }, }, //呼厨泉 - twfupan:{ - audio:3, - trigger:{ - player:'damageEnd', - source:'damageSource' + twfupan: { + audio: 3, + trigger: { + player: "damageEnd", + source: "damageSource", }, - check:()=>true, - onremove:true, - content:function(){ - 'step 0' - if(!player.storage.twfupan) player.storage.twfupan={}; + check: () => true, + onremove: true, + content: function () { + "step 0"; + if (!player.storage.twfupan) player.storage.twfupan = {}; player.draw(trigger.num); - 'step 1' - if(player.countCards('he')&&game.hasPlayer(current=>{ - return !(player.storage.twfupan[current.playerid]>=2)&&player!=current; - })){ + "step 1"; + if ( + player.countCards("he") && + game.hasPlayer((current) => { + return !(player.storage.twfupan[current.playerid] >= 2) && player != current; + }) + ) { player.chooseCardTarget({ - filterCard:true, - selectCard:1, - position:'he', - forced:true, - targetprompt:function(target){ - return !_status.event.player.storage.twfupan[target.playerid]?'你摸两张牌':'对其
              造成伤害'; + filterCard: true, + selectCard: 1, + position: "he", + forced: true, + targetprompt: function (target) { + return !_status.event.player.storage.twfupan[target.playerid] + ? "你摸两张牌" + : "对其
              造成伤害"; }, - filterTarget:function(card,player,target){ - return !(player.storage.twfupan[target.playerid]>=2)&&player!=target; + filterTarget: function (card, player, target) { + return !(player.storage.twfupan[target.playerid] >= 2) && player != target; }, - ai1:function(card){ - var player=_status.event.player; - if(get.value(card,false,'raw')<0) return 20*get.value(card); - if(player==_status.currentPhase) return 20-player.getUseValue(card); - return 20-get.value(card); + ai1: function (card) { + var player = _status.event.player; + if (get.value(card, false, "raw") < 0) return 20 * get.value(card); + if (player == _status.currentPhase) return 20 - player.getUseValue(card); + return 20 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(ui.selected.cards.length&&get.value(ui.selected.cards[0],false,'raw')<0){ - return -0.1-att; + ai2: function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if ( + ui.selected.cards.length && + get.value(ui.selected.cards[0], false, "raw") < 0 + ) { + return -0.1 - att; } - if(player.storage.twfupan[target.playerid]===undefined) return 5; - else if(player.storage.twfupan[target.playerid]===1) return get.damageEffect(target,player,player); + if (player.storage.twfupan[target.playerid] === undefined) return 5; + else if (player.storage.twfupan[target.playerid] === 1) + return get.damageEffect(target, player, player); return 1; }, - prompt:'请选择要交出的卡牌和目标角色' + prompt: "请选择要交出的卡牌和目标角色", }); - }else event.finish(); - 'step 2' - if(result.bool){ - var cards=result.cards,target=result.targets[0]; - player.line(target,'green'); - player.give(cards,target); - event.target=target; - if(!player.storage.twfupan[target.playerid]){ - player.storage.twfupan[target.playerid]=1; + } else event.finish(); + "step 2"; + if (result.bool) { + var cards = result.cards, + target = result.targets[0]; + player.line(target, "green"); + player.give(cards, target); + event.target = target; + if (!player.storage.twfupan[target.playerid]) { + player.storage.twfupan[target.playerid] = 1; player.draw(2); event.finish(); - }else{ - player.chooseBool('复叛:是否对'+get.translation(target)+'造成1点伤害?','然后你不能再因此技能交给其牌').set('ai',()=>_status.event.bool).set('bool',get.damageEffect(target,player,player)>0); + } else { + player + .chooseBool( + "复叛:是否对" + get.translation(target) + "造成1点伤害?", + "然后你不能再因此技能交给其牌" + ) + .set("ai", () => _status.event.bool) + .set("bool", get.damageEffect(target, player, player) > 0); } } - 'step 3' - if(result.bool){ - player.line(target,'fire'); + "step 3"; + if (result.bool) { + player.line(target, "fire"); target.damage(); player.storage.twfupan[target.playerid]++; } }, - ai:{ - maixie:true, - maixie_hp:true, - threaten:0.9, - } + ai: { + maixie: true, + maixie_hp: true, + threaten: 0.9, + }, }, //刘璋 - twyaohu:{ - audio:'yinlang', - trigger:{player:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return !player.hasSkill('twyaohu_round')&&game.hasPlayer(function(current){ - return current.group&¤t.group!='unknown'; - }); + twyaohu: { + audio: "yinlang", + trigger: { player: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return ( + !player.hasSkill("twyaohu_round") && + game.hasPlayer(function (current) { + return current.group && current.group != "unknown"; + }) + ); }, - content:function(){ - 'step 0' - var list=[]; - game.countPlayer(function(current){ - if(current.group&¤t.group!='unknown') list.add(current.group); + content: function () { + "step 0"; + var list = []; + game.countPlayer(function (current) { + if (current.group && current.group != "unknown") list.add(current.group); }); - list.sort(function(a,b){ - return lib.group.indexOf(a)-lib.group.indexOf(b); + list.sort(function (a, b) { + return lib.group.indexOf(a) - lib.group.indexOf(b); }); - if(!player.hasSkill('twyaohu')) list.push('cancel2'); - player.chooseControl(list).set('prompt','邀虎:请选择一个势力').set('ai',function(){ - return _status.event.choice; - }).set('choice',function(){ - var getn=function(group){ - return game.countPlayer(function(current){ - if(current.group!=group) return false; - if(player==current) return 2; - if(get.attitude(current,player)>0) return 1; - return 1.3; - }); - } - list.sort(function(a,b){ - return getn(b)-getn(a); - }); - return list[0]; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twyaohu',game.filterPlayer(function(current){ - return current.group==result.control; - })); - game.log(player,'选择了','#y'+get.translation(result.control+2)); - player.storage.yaohu=result.control; - player.storage.twyaohu=result.control; - player.markSkill('twyaohu'); + if (!player.hasSkill("twyaohu")) list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", "邀虎:请选择一个势力") + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var getn = function (group) { + return game.countPlayer(function (current) { + if (current.group != group) return false; + if (player == current) return 2; + if (get.attitude(current, player) > 0) return 1; + return 1.3; + }); + }; + list.sort(function (a, b) { + return getn(b) - getn(a); + }); + return list[0]; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill( + "twyaohu", + game.filterPlayer(function (current) { + return current.group == result.control; + }) + ); + game.log(player, "选择了", "#y" + get.translation(result.control + 2)); + player.storage.yaohu = result.control; + player.storage.twyaohu = result.control; + player.markSkill("twyaohu"); } }, - ai:{combo:'jutu'}, - intro:{content:'已选择了$势力'}, - group:'twyaohu_gain', - subSkill:{ - round:{}, - gain:{ - audio:'yinlang', - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player.group==player.storage.yaohu&&event.player.isIn()&&player.getExpansions('jutu').length>0; + ai: { combo: "jutu" }, + intro: { content: "已选择了$势力" }, + group: "twyaohu_gain", + subSkill: { + round: {}, + gain: { + audio: "yinlang", + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return ( + event.player.group == player.storage.yaohu && + event.player.isIn() && + player.getExpansions("jutu").length > 0 + ); }, - forced:true, - locked:false, - logTarget:'player', - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - target.chooseButton(['选择获得一张“生”',player.getExpansions('jutu')],true).set('ai',function(button){ - return get.value(button.link,player); - }); - 'step 1' - if(result.bool){ - target.gain(result.links,'give',player); - } - 'step 2' - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target; - })){ - player.chooseTarget(true,'选择'+get.translation(target)+'使用【杀】的目标',function(card,player,target){ - return target!=player&&target!=_status.event.source; - }).set('source',target).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,{name:'sha'},evt.source,evt.player); + forced: true, + locked: false, + logTarget: "player", + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + target + .chooseButton(["选择获得一张“生”", player.getExpansions("jutu")], true) + .set("ai", function (button) { + return get.value(button.link, player); }); + "step 1"; + if (result.bool) { + target.gain(result.links, "give", player); } - else { - event._result={bool:false}; + "step 2"; + if ( + game.hasPlayer(function (current) { + return current != player && current != target; + }) + ) { + player + .chooseTarget( + true, + "选择" + get.translation(target) + "使用【杀】的目标", + function (card, player, target) { + return target != player && target != _status.event.source; + } + ) + .set("source", target) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, { name: "sha" }, evt.source, evt.player); + }); + } else { + event._result = { bool: false }; event.goto(4); } - 'step 3' - var target2=result.targets[0]; - player.line(target2,'green'); - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'对'+get.translation(target2)+'使用一张杀,否则本回合使用伤害牌指定'+get.translation(player)+'为目标时须交给'+get.translation(player)+'两张牌,否则此牌对'+get.translation(player)+'无效').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',target2).set('addCount',false); - 'step 4' - if(!result.bool) player.addTempSkill('twyaohu_effect'); + "step 3"; + var target2 = result.targets[0]; + player.line(target2, "green"); + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "对" + + get.translation(target2) + + "使用一张杀,否则本回合使用伤害牌指定" + + get.translation(player) + + "为目标时须交给" + + get.translation(player) + + "两张牌,否则此牌对" + + get.translation(player) + + "无效") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", target2) + .set("addCount", false); + "step 4"; + if (!result.bool) player.addTempSkill("twyaohu_effect"); }, }, - effect:{ - audio:'yinlang', - trigger:{global:'useCardToPlayer'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return event.target==player&&get.tag(event.card,'damage'); + effect: { + audio: "yinlang", + trigger: { global: "useCardToPlayer" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return event.target == player && get.tag(event.card, "damage"); }, - logTarget:'player', - content:function(){ - 'step 0' - var hs=trigger.player.getCards('he'); - if(hs.length<2) event._result={bool:false}; - else trigger.player.chooseCard(2,'交给'+get.translation(player)+'两张牌,否则取消'+get.translation(trigger.card)+'对其的目标','he').set('ai',card=>{ - if(_status.event.goon) return 5-get.value(card); - return 0; - }).set('goon',get.effect(player,trigger.card,trigger.player,trigger.player)>0); - 'step 1' - if(result.bool){ - trigger.player.give(result.cards,player); - }else{ + logTarget: "player", + content: function () { + "step 0"; + var hs = trigger.player.getCards("he"); + if (hs.length < 2) event._result = { bool: false }; + else + trigger.player + .chooseCard( + 2, + "交给" + + get.translation(player) + + "两张牌,否则取消" + + get.translation(trigger.card) + + "对其的目标", + "he" + ) + .set("ai", (card) => { + if (_status.event.goon) return 5 - get.value(card); + return 0; + }) + .set( + "goon", + get.effect(player, trigger.card, trigger.player, trigger.player) > 0 + ); + "step 1"; + if (result.bool) { + trigger.player.give(result.cards, player); + } else { trigger.untrigger(); trigger.targets.remove(player); trigger.getParent().triggeredTargets1.remove(player); } }, - } + }, }, }, //李遗 - twjiaohua:{ - audio:2, - trigger:{global:'gainAfter'}, - filter:function(event,player){ - if(event.getParent().name!='draw') return false; - if(event.player!=player&&!event.player.isMinHp()) return false; - var cards=event.cards,list=['basic','trick','equip']; - for(var card of cards) if(list.includes(get.type2(card))) list.remove(get.type2(card)); - for(var type of event.player.getStorage('twjiaohua_gained')) if(list.includes(type)) list.remove(type); - return list.length>0; + twjiaohua: { + audio: 2, + trigger: { global: "gainAfter" }, + filter: function (event, player) { + if (event.getParent().name != "draw") return false; + if (event.player != player && !event.player.isMinHp()) return false; + var cards = event.cards, + list = ["basic", "trick", "equip"]; + for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card)); + for (var type of event.player.getStorage("twjiaohua_gained")) + if (list.includes(type)) list.remove(type); + return list.length > 0; }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - prompt2:function(event,player){ - var cards=event.cards,list=['basic','trick','equip']; - for(var card of cards) if(list.includes(get.type2(card))) list.remove(get.type2(card)); - for(var type of event.player.getStorage('twjiaohua_gained')) if(list.includes(type)) list.remove(type); - var name=event.player==player?'你':get.translation(event.player); - return '令'+name+'从牌堆或弃牌堆中获得一张'+(event.player.isUnderControl(true)?list.map(i=>get.translation(i)+'牌').join('、').replace(/(.*)、/, '$1或'):'本次未获得的类别的牌'); + prompt2: function (event, player) { + var cards = event.cards, + list = ["basic", "trick", "equip"]; + for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card)); + for (var type of event.player.getStorage("twjiaohua_gained")) + if (list.includes(type)) list.remove(type); + var name = event.player == player ? "你" : get.translation(event.player); + return ( + "令" + + name + + "从牌堆或弃牌堆中获得一张" + + (event.player.isUnderControl(true) + ? list + .map((i) => get.translation(i) + "牌") + .join("、") + .replace(/(.*)、/, "$1或") + : "本次未获得的类别的牌") + ); }, - logTarget:'player', - content:function(){ - trigger.player.addTempSkill('twjiaohua_gained'); - var cards=trigger.cards,list=['basic','trick','equip']; - for(var card of cards) if(list.includes(get.type2(card))) list.remove(get.type2(card)); - for(var type of trigger.player.getStorage('twjiaohua_gained')) if(list.includes(type)) list.remove(type); + logTarget: "player", + content: function () { + trigger.player.addTempSkill("twjiaohua_gained"); + var cards = trigger.cards, + list = ["basic", "trick", "equip"]; + for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card)); + for (var type of trigger.player.getStorage("twjiaohua_gained")) + if (list.includes(type)) list.remove(type); list.randomSort(); - var card=get.cardPile(function(card){ + var card = get.cardPile(function (card) { return list.includes(get.type2(card)); }); - if(card){ - trigger.player.gain(card,'gain2'); - trigger.player.markAuto('twjiaohua_gained',[get.type2(card)]); + if (card) { + trigger.player.gain(card, "gain2"); + trigger.player.markAuto("twjiaohua_gained", [get.type2(card)]); } }, - subSkill:{ - gained:{onremove:true,charlotte:true} - } + subSkill: { + gained: { onremove: true, charlotte: true }, + }, }, //阎象 - twkujian:{ - audio:3, - enable:'phaseUse', - filterCard:true, - selectCard:[1,3], - usable:1, - discard:false, - lose:false, - delay:false, - filterTarget:lib.filter.notMe, - global:'twkujian_ai', - check:function(card){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(ui.selected.cards.length>=Math.max(2,player.countCards('h')-player.hp)) return 0; - if(player.hp==player.maxHp||player.storage.jsprende<0||player.countCards('h')<=1){ - var players=game.filterPlayer(); - for(var i=0; i= Math.max(2, player.countCards("h") - player.hp)) return 0; + if ( + player.hp == player.maxHp || + player.storage.jsprende < 0 || + player.countCards("h") <= 1 + ) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && !players[i].isTurnedOver() && - !players[i].hasJudge('lebu') && - get.attitude(player,players[i])>=3 && - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - content:function(){ - player.give(cards,target).gaintag.add('twkujianx'); - player.addSkill('twkujian_draw'); - player.addSkill('twkujian_discard'); + content: function () { + player.give(cards, target).gaintag.add("twkujianx"); + player.addSkill("twkujian_draw"); + player.addSkill("twkujian_discard"); }, - ai:{ - expose:0.2, - order:7, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - if(target.hasSkillTag('nodu')) return 0; + ai: { + expose: 0.2, + order: 7, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + if (target.hasSkillTag("nodu")) return 0; return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - var np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.jsprende<0||player.countCards('h')<=1){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + var np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.jsprende < 0 || + player.countCards("h") <= 1 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); + return Math.max(1, 5 - nh); }, }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.type(card)=='equip'){ - if(player.countCards('e',{subtype:get.subtype(card)})){ - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })){ + effect: { + target: function (card, player, target) { + if (player == target && get.type(card) == "equip") { + if (player.countCards("e", { subtype: get.subtype(card) })) { + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) { return 0; } } @@ -8330,389 +10562,463 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - subSkill:{ - draw:{ - audio:'twkujian', - trigger:{global:['useCardAfter','respondAfter']}, - forced:true, - logTarget:'player', - charlotte:true, - filter:function(event,player){ - return event.player.hasHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twkujianx')) return true; + subSkill: { + draw: { + audio: "twkujian", + trigger: { global: ["useCardAfter", "respondAfter"] }, + forced: true, + logTarget: "player", + charlotte: true, + filter: function (event, player) { + return event.player.hasHistory("lose", (evt) => { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twkujianx")) return true; } }); }, - content:function(){ - 'step 0' - game.asyncDraw([player,trigger.player]); - 'step 1' + content: function () { + "step 0"; + game.asyncDraw([player, trigger.player]); + "step 1"; game.delayx(); - } + }, }, - discard:{ - audio:'twkujian', - trigger:{global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter']}, - forced:true, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - var evt=event.getl(current); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - var name=event.getParent().name; - if(name=='useCard'||name=='respond') return false; - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('twkujianx')) return true; + discard: { + audio: "twkujian", + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + forced: true, + logTarget: function (event, player) { + return game.filterPlayer(function (current) { + var evt = event.getl(current); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + var name = event.getParent().name; + if (name == "useCard" || name == "respond") return false; + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("twkujianx")) return true; } return false; } - return current.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twkujianx')) return true; + return current.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twkujianx")) return true; } return false; }); }); }, - charlotte:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - var evt=event.getl(current); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - var name=event.getParent().name; - if(name=='useCard'||name=='respond') return false; - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('twkujianx')) return true; + charlotte: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + var evt = event.getl(current); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + var name = event.getParent().name; + if (name == "useCard" || name == "respond") return false; + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("twkujianx")) return true; } return false; } - return current.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twkujianx')) return true; + return current.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twkujianx")) return true; } return false; }); }); }, - content:function(){ - 'step 0' - var event=trigger; - var targets=game.filterPlayer(function(current){ - var evt=event.getl(current); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - var name=event.getParent().name; - if(name=='useCard'||name=='respond') return false; - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('twkujianx')) return true; + content: function () { + "step 0"; + var event = trigger; + var targets = game.filterPlayer(function (current) { + var evt = event.getl(current); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + var name = event.getParent().name; + if (name == "useCard" || name == "respond") return false; + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("twkujianx")) return true; } return false; } - return current.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twkujianx')) return true; + return current.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twkujianx")) return true; } return false; }); }); targets.add(player); targets.sortBySeat(); - _status.event.targets=targets; - 'step 1' - var target=targets.shift(); - if(target.countCards('he')>0) target.chooseToDiscard('he',true); - if(targets.length>0) event.redo(); - } + _status.event.targets = targets; + "step 1"; + var target = targets.shift(); + if (target.countCards("he") > 0) target.chooseToDiscard("he", true); + if (targets.length > 0) event.redo(); + }, }, - ai:{ - charlotte:true, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(card.cards&&card.cards.some(i=>i.hasGaintag('twkujianx'))&&game.hasPlayer(current=>{ - return get.attitude(player,current)>0; - })) return [1,1]; + ai: { + charlotte: true, + ai: { + effect: { + player_use: function (card, player, target) { + if ( + card.cards && + card.cards.some((i) => i.hasGaintag("twkujianx")) && + game.hasPlayer((current) => { + return get.attitude(player, current) > 0; + }) + ) + return [1, 1]; }, }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('twkujianx')&&game.hasPlayer(current=>{ - return get.attitude(player,current)>0; - })) return num+0.5; + mod: { + aiOrder: function (player, card, num) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("twkujianx") && + game.hasPlayer((current) => { + return get.attitude(player, current) > 0; + }) + ) + return num + 0.5; }, - aiValue:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('twkujianx')&&game.hasPlayer(current=>{ - return get.attitude(player,current)>0; - })) return num+0.5; - } - } - } - } + aiValue: function (player, card, num) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("twkujianx") && + game.hasPlayer((current) => { + return get.attitude(player, current) > 0; + }) + ) + return num + 0.5; + }, + }, + }, + }, }, - twruilian:{ - audio:2, - trigger:{global:'roundStart'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twruilian')).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target),eff=att/(player==target?2:1)+1; - if(att>=0){ - if(target.hasSkill('yongsi')) return eff*5; - if(target.hasSkill('zhiheng')||target.hasSkill('rezhiheng')) return eff*4; - if(target.hasSkill('rekurou')) return eff*3; - if(target.hasSkill('xinlianji')||target.hasSkill('dclianji')) return eff*2; - if(target.needsToDiscard()) return eff*1.5; + twruilian: { + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("twruilian")).set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target), + eff = att / (player == target ? 2 : 1) + 1; + if (att >= 0) { + if (target.hasSkill("yongsi")) return eff * 5; + if (target.hasSkill("zhiheng") || target.hasSkill("rezhiheng")) return eff * 4; + if (target.hasSkill("rekurou")) return eff * 3; + if (target.hasSkill("xinlianji") || target.hasSkill("dclianji")) return eff * 2; + if (target.needsToDiscard()) return eff * 1.5; return eff; } return 0; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twruilian',target); - player.markAuto('twruilian2',[target]); - player.addSkill('twruilian2'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twruilian", target); + player.markAuto("twruilian2", [target]); + player.addSkill("twruilian2"); } }, }, - twruilian2:{ - trigger:{global:'phaseEnd'}, - direct:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return player.getStorage('twruilian2').includes(event.player); + twruilian2: { + trigger: { global: "phaseEnd" }, + direct: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return player.getStorage("twruilian2").includes(event.player); }, - intro:{content:'已选择$'}, - content:function(){ - 'step 0' - player.removeSkill('twruilian2'); - var target=trigger.player; - event.target=target; - var cards=[]; - target.getHistory('lose',function(evt){ - if(evt.type=='discard') cards.addArray(evt.cards2); + intro: { content: "已选择$" }, + content: function () { + "step 0"; + player.removeSkill("twruilian2"); + var target = trigger.player; + event.target = target; + var cards = []; + target.getHistory("lose", function (evt) { + if (evt.type == "discard") cards.addArray(evt.cards2); }); - if(cards.length<2) event.finish(); - else event.cards=cards; - 'step 1' - var list=[]; - for(var type of ['basic','trick','equip']){ - for(var card of event.cards){ - if(get.type2(card)==type){ + if (cards.length < 2) event.finish(); + else event.cards = cards; + "step 1"; + var list = []; + for (var type of ["basic", "trick", "equip"]) { + for (var card of event.cards) { + if (get.type2(card) == type) { list.push(type); break; } } } - list.push('cancel2'); - player.chooseControl(list).set('prompt','睿敛:是否与'+get.translation(target)+'各获得一种类型的牌?').set('ai',function(){ - var player=_status.event.player,list=_status.event.controls; - if(player.hp<=3&&!player.countCards('h',{name:['shan','tao']})&&list.includes('basic')) return 'basic'; - if(player.countCards('he',{type:'equip'})<2&&list.includes('equip')) return 'equip'; - if(list.includes('trick')) return 'trick'; - return list.remove('cancel2').randomGet(); - }); - 'step 2' - if(result.control!='cancel2'){ - player.logSkill('twruilian2',target); - var type=result.control; - var list=[target,player].sortBySeat(_status.currentPhase),cards=[]; - for(var current of list){ - var card=get.discardPile(function(card){ - return get.type2(card)==type&&!cards.includes(card); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", "睿敛:是否与" + get.translation(target) + "各获得一种类型的牌?") + .set("ai", function () { + var player = _status.event.player, + list = _status.event.controls; + if ( + player.hp <= 3 && + !player.countCards("h", { name: ["shan", "tao"] }) && + list.includes("basic") + ) + return "basic"; + if (player.countCards("he", { type: "equip" }) < 2 && list.includes("equip")) + return "equip"; + if (list.includes("trick")) return "trick"; + return list.remove("cancel2").randomGet(); + }); + "step 2"; + if (result.control != "cancel2") { + player.logSkill("twruilian2", target); + var type = result.control; + var list = [target, player].sortBySeat(_status.currentPhase), + cards = []; + for (var current of list) { + var card = get.discardPile(function (card) { + return get.type2(card) == type && !cards.includes(card); }); - if(card){ + if (card) { cards.push(card); - current.gain(card,'gain2'); + current.gain(card, "gain2"); } } } }, }, //夏侯恩 - twfujian:{ - audio:2, - group:'twfujian_lose', - trigger:{ - global:'phaseBefore', - player:['enterGame','phaseZhunbeiBegin'] + twfujian: { + audio: 2, + group: "twfujian_lose", + trigger: { + global: "phaseBefore", + player: ["enterGame", "phaseZhunbeiBegin"], }, - filter:function(event,player){ - if(player.getEquips(1).length) return false; - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + if (player.getEquips(1).length) return false; + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - content:function(){ - var card=get.cardPile2(function(card){ - return get.type(card)=='equip'&&get.subtype(card)=='equip1'; + forced: true, + content: function () { + var card = get.cardPile2(function (card) { + return get.type(card) == "equip" && get.subtype(card) == "equip1"; }); - event.card=card; - if(card) player.equip(card); - else{ - game.log('但是牌堆中没有武器牌了!'); + event.card = card; + if (card) player.equip(card); + else { + game.log("但是牌堆中没有武器牌了!"); event.finish(); } }, - subSkill:{ - lose:{ - audio:'twfujian', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + lose: { + audio: "twfujian", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - if(evt&&evt.cards2&&evt.cards2.some(i=>get.subtype(i)=='equip1')) return true; + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + if (evt && evt.cards2 && evt.cards2.some((i) => get.subtype(i) == "equip1")) + return true; return false; }, - forced:true, - content:function(){ + forced: true, + content: function () { player.loseHp(); }, }, }, }, - twjianwei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(!player.getEquips(1).length) return false; - return game.hasPlayer(function(current){ - return player.inRange(current)&&player.canCompare(current); + twjianwei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (!player.getEquips(1).length) return false; + return game.hasPlayer(function (current) { + return player.inRange(current) && player.canCompare(current); }); }, - pindianCheck:function(player,target){ - var hs=player.getCards('h').sort(function(a,b){ - return b.number-a.number; + pindianCheck: function (player, target) { + var hs = player.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - var ts=target.getCards('h').sort(function(a,b){ - return b.number-a.number; + var ts = target.getCards("h").sort(function (a, b) { + return b.number - a.number; }); - if(!hs.length||!ts.length) return 0; - if(Math.min(13,hs[0].number+player.getAttackRange())>ts[0].number||ts[0].number>9&&get.value(ts[0])<=5||target.countCards('j')) return true; + if (!hs.length || !ts.length) return 0; + if ( + Math.min(13, hs[0].number + player.getAttackRange()) > ts[0].number || + (ts[0].number > 9 && get.value(ts[0]) <= 5) || + target.countCards("j") + ) + return true; return false; }, - direct:true, - locked:false, - group:['twjianwei_pindian','twjianwei_zhaocha'], - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twjianwei'),'与攻击范围内的一名角色拼点。若你赢,你获得其每个区域里的一张牌;若其赢,其获得你装备区里的武器牌',function(card,player,target){ - return player.inRange(target)&&player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player; - if(lib.skill.twjianwei.pindianCheck(player,target)) return -5*get.attitude(player,target); - return -get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twjianwei',target); + direct: true, + locked: false, + group: ["twjianwei_pindian", "twjianwei_zhaocha"], + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twjianwei"), + "与攻击范围内的一名角色拼点。若你赢,你获得其每个区域里的一张牌;若其赢,其获得你装备区里的武器牌", + function (card, player, target) { + return player.inRange(target) && player.canCompare(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + if (lib.skill.twjianwei.pindianCheck(player, target)) + return -5 * get.attitude(player, target); + return -get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twjianwei", target); player.chooseToCompare(target); - } - else event.finish(); - 'step 2' - if(result.bool){ - var num=0; - if(target.countCards('h')) num++; - if(target.countCards('e')) num++; - if(target.countCards('j')) num++; - if(num){ - player.gainPlayerCard(target,num,'hej',true).set('filterButton',function(button){ - for(var i=0; i13) trigger.num1=13; + forced: true, + locked: false, + content: function () { + var num = player.getAttackRange(); + if (player == trigger.player) { + trigger.num1 += num; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += num; + if (trigger.num2 > 13) trigger.num2 = 13; } - else { - trigger.num2+=num; - if(trigger.num2>13) trigger.num2=13; - } - game.log(player,'的拼点牌点数+'+num); + game.log(player, "的拼点牌点数+" + num); }, }, //你是故意找茬是不是 - zhaocha:{ - trigger:{global:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(event.player==player) return false; + zhaocha: { + trigger: { global: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (event.player == player) return false; return event.player.canCompare(player); }, - direct:true, - content:function(){ - 'step 0' - trigger.player.chooseBool('剑威:是否与'+get.translation(player)+'拼点?','若你赢,你获得其装备区里的武器牌;若其赢,其获得你每个区域里的一张牌').set('ai',()=>_status.event.choice).set('choice',get.attitude(trigger.player,player)<0&&!lib.skill.twjianwei.pindianCheck(player,trigger.player)); - 'step 1' - if(result.bool){ - trigger.player.logSkill('twjianwei',player); + direct: true, + content: function () { + "step 0"; + trigger.player + .chooseBool( + "剑威:是否与" + get.translation(player) + "拼点?", + "若你赢,你获得其装备区里的武器牌;若其赢,其获得你每个区域里的一张牌" + ) + .set("ai", () => _status.event.choice) + .set( + "choice", + get.attitude(trigger.player, player) < 0 && + !lib.skill.twjianwei.pindianCheck(player, trigger.player) + ); + "step 1"; + if (result.bool) { + trigger.player.logSkill("twjianwei", player); trigger.player.chooseToCompare(player); - } - else event.finish(); - 'step 2' - if(!result.tie){ - if(result.bool){ - var card=player.getEquips(1); - if(card.length) trigger.player.gain(card,player,'give'); - } - else { - var num=0; - if(trigger.player.countCards('h')) num++; - if(trigger.player.countCards('e')) num++; - if(trigger.player.countCards('j')) num++; - if(num) player.gainPlayerCard(trigger.player,num,'hej',true).set('filterButton',function(button){ - for(var i=0; i0; + twtanfeng: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countDiscardableCards(player, "hej") > 0; }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twtanfeng'),function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'hej')>0; - }).set('ai',function(target){ - var player=_status.event.player,num=1; - if(get.attitude(player,target)>0) num=3; - else if(!target.countCards('he')||!target.canUse('sha',player)){ - if(target.hp+target.countCards('hs',{name:['tao','jiu']})<=1) num=2; - else num=1.2; - } - return get.effect(target,{name:'guohe'},player,player)*num*((player.hp<=1&&get.attitude(player,target)<=0)?0:1); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twtanfeng',target); - player.discardPlayerCard(target,'hej',true); - } - else event.finish(); - 'step 2' + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twtanfeng"), function (card, player, target) { + return target != player && target.countDiscardableCards(player, "hej") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player, + num = 1; + if (get.attitude(player, target) > 0) num = 3; + else if (!target.countCards("he") || !target.canUse("sha", player)) { + if (target.hp + target.countCards("hs", { name: ["tao", "jiu"] }) <= 1) + num = 2; + else num = 1.2; + } + return ( + get.effect(target, { name: "guohe" }, player, player) * + num * + (player.hp <= 1 && get.attitude(player, target) <= 0 ? 0 : 1) + ); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twtanfeng", target); + player.discardPlayerCard(target, "hej", true); + } else event.finish(); + "step 2"; target.chooseCardTarget({ - position:'hes', - prompt:'选择一张牌当做【杀】对'+get.translation(player)+'使用', - prompt2:'或点击“取消”,受到其造成的1点火焰伤害,并令其跳过本回合的一个阶段(准备阶段和结束阶段除外)', - filterCard:function(card,player){ - return player.canUse(get.autoViewAs({name:'sha'},[card]),_status.event.getParent().player,false); + position: "hes", + prompt: "选择一张牌当做【杀】对" + get.translation(player) + "使用", + prompt2: + "或点击“取消”,受到其造成的1点火焰伤害,并令其跳过本回合的一个阶段(准备阶段和结束阶段除外)", + filterCard: function (card, player) { + return player.canUse( + get.autoViewAs({ name: "sha" }, [card]), + _status.event.getParent().player, + false + ); }, - filterTarget:function(card,player,target){ - var source=_status.event.getParent().player; - if(target!=source&&!ui.selected.targets.includes(source)) return false; - card=get.autoViewAs({name:'sha'},[card]); - return lib.filter.filterTarget.apply(this,arguments); + filterTarget: function (card, player, target) { + var source = _status.event.getParent().player; + if (target != source && !ui.selected.targets.includes(source)) return false; + card = get.autoViewAs({ name: "sha" }, [card]); + return lib.filter.filterTarget.apply(this, arguments); }, - selectTarget:function(){ - var card=get.card(),player=get.player(); - if(!card) return; - card=get.autoViewAs({name:'sha'},[card]); - var range=[1,1]; - game.checkMod(card,player,range,'selectTarget',player); + selectTarget: function () { + var card = get.card(), + player = get.player(); + if (!card) return; + card = get.autoViewAs({ name: "sha" }, [card]); + var range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); return range; }, - ai1:function(card){ - var player=_status.event.player,target=_status.event.getParent().player; - var eff=get.effect(target,get.autoViewAs({name:'sha'},[card]),player,player); - var eff2=get.damageEffect(player,target,player,'fire'); - if(eff<0||eff2>0||eff2>eff||get.tag(card,'recover')) return 0; - return (player.hp==1?10:6)-get.value(card); + ai1: function (card) { + var player = _status.event.player, + target = _status.event.getParent().player; + var eff = get.effect( + target, + get.autoViewAs({ name: "sha" }, [card]), + player, + player + ); + var eff2 = get.damageEffect(player, target, player, "fire"); + if (eff < 0 || eff2 > 0 || eff2 > eff || get.tag(card, "recover")) return 0; + return (player.hp == 1 ? 10 : 6) - get.value(card); + }, + ai2: function (target) { + if (target == _status.event.getParent().player) return 100; + return get.effect(target, { name: "sha" }, _status.event.player); }, - ai2:function(target){ - if(target==_status.event.getParent().player) return 100; - return get.effect(target,{name:'sha'},_status.event.player); - } }); - 'step 3' - if(result.bool){ - var cards=result.cards,targets=result.targets; - var cardx=get.autoViewAs({name:'sha'},cards); - target.useCard(cardx,cards,targets,false); + "step 3"; + if (result.bool) { + var cards = result.cards, + targets = result.targets; + var cardx = get.autoViewAs({ name: "sha" }, cards); + target.useCard(cardx, cards, targets, false); event.finish(); + } else { + player.line(target, "fire"); + target.damage(1, "fire"); } - else{ - player.line(target,'fire'); - target.damage(1,'fire'); + "step 4"; + if (!target.isIn()) { + event.finish(); + return; } - 'step 4' - if(!target.isIn()){ - event.finish(); return; - } - var list=[]; - var list2=[]; - event.map={phaseJudge:'判定阶段',phaseDraw:'摸牌阶段',phaseUse:'出牌阶段',phaseDiscard:'弃牌阶段'}; - for(var i of ['phaseJudge','phaseDraw','phaseUse','phaseDiscard']){ - if(!player.skipList.includes(i)){ - i=event.map[i]; + var list = []; + var list2 = []; + event.map = { + phaseJudge: "判定阶段", + phaseDraw: "摸牌阶段", + phaseUse: "出牌阶段", + phaseDiscard: "弃牌阶段", + }; + for (var i of ["phaseJudge", "phaseDraw", "phaseUse", "phaseDiscard"]) { + if (!player.skipList.includes(i)) { + i = event.map[i]; list.push(i); - if(i!='判定阶段'&&i!='弃牌阶段') list2.push(i); + if (i != "判定阶段" && i != "弃牌阶段") list2.push(i); } } - target.chooseControl(list).set('prompt','探锋:令'+get.translation(player)+'跳过一个阶段').set('ai',function(){ - return _status.event.choice; - }).set('choice',function(){ - var att=get.attitude(target,player); - var num=player.countCards('j'); - if(att>0){ - if(list.includes('判定阶段')&&num>0) return '判定阶段'; - return '弃牌阶段'; - } - if(list.includes('摸牌阶段')&&player.hasJudge('lebu')) return '摸牌阶段'; - if(list.includes('出牌阶段')&&player.hasJudge('bingliang')||player.needsToDiscard()>0) return '出牌阶段'; - return list2.randomGet(); - }()); - 'step 5' - for(var i in event.map){ - if(event.map[i]==result.control) player.skip(i); + target + .chooseControl(list) + .set("prompt", "探锋:令" + get.translation(player) + "跳过一个阶段") + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var att = get.attitude(target, player); + var num = player.countCards("j"); + if (att > 0) { + if (list.includes("判定阶段") && num > 0) return "判定阶段"; + return "弃牌阶段"; + } + if (list.includes("摸牌阶段") && player.hasJudge("lebu")) return "摸牌阶段"; + if ( + (list.includes("出牌阶段") && player.hasJudge("bingliang")) || + player.needsToDiscard() > 0 + ) + return "出牌阶段"; + return list2.randomGet(); + })() + ); + "step 5"; + for (var i in event.map) { + if (event.map[i] == result.control) player.skip(i); } target.popup(result.control); target.line(player); - game.log(player,'跳过了','#y'+result.control); + game.log(player, "跳过了", "#y" + result.control); }, }, //宗预 - twzhibian:{ - audio:'zhibian', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return game.hasPlayer((current)=>(current!=player&&player.canCompare(current))); + twzhibian: { + audio: "zhibian", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return game.hasPlayer((current) => current != player && player.canCompare(current)); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twzhibian'),'与一名其他角色拼点',function(card,player,target){ - return target!=player&&player.canCompare(target); - }).set('ai',function(target){ - if(!_status.event.goon) return false; - var att=get.attitude(player,target); - if(att<0&&(target.countCards('h')>1||target.countCards('e',function(card){ - return player.canEquip(card)&&get.effect(player,card,target,player)>0; - }))) return -att/Math.sqrt(target.countCards('h')); - if(!player.isDamaged()) return false; - if(att<=0) return (1-att)/Math.sqrt(target.countCards('h')); - return Math.sqrt(2/att*Math.sqrt(target.countCards('h'))); - }).set('goon',function(){ - if(!player.hasCard(function(card){ - return (card.number>=14-player.hp&&get.value(card)<=5); - })) return false; - return true; - }()); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twzhibian',target); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twzhibian"), + "与一名其他角色拼点", + function (card, player, target) { + return target != player && player.canCompare(target); + } + ) + .set("ai", function (target) { + if (!_status.event.goon) return false; + var att = get.attitude(player, target); + if ( + att < 0 && + (target.countCards("h") > 1 || + target.countCards("e", function (card) { + return ( + player.canEquip(card) && + get.effect(player, card, target, player) > 0 + ); + })) + ) + return -att / Math.sqrt(target.countCards("h")); + if (!player.isDamaged()) return false; + if (att <= 0) return (1 - att) / Math.sqrt(target.countCards("h")); + return Math.sqrt((2 / att) * Math.sqrt(target.countCards("h"))); + }) + .set( + "goon", + (function () { + if ( + !player.hasCard(function (card) { + return card.number >= 14 - player.hp && get.value(card) <= 5; + }) + ) + return false; + return true; + })() + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twzhibian", target); player.chooseToCompare(target); - } - else event.finish(); - 'step 2' - if(result.bool){ - var list=[],list2=[ - '将'+get.translation(target)+'区域中的一张牌移动到你的区域内', - '回复1点体力', - '背水!弃置一张非基本牌,并依次执行上述所有选项', - ]; - if(target.countCards('h')||target.hasCard(function(card){ - return player.canEquip(card); - },'e')||target.hasCard(function(card){ - return player.canAddJudge(card); - },'j')) list.push('选项一'); - else list2[0]=''+list2[0]+''; - if(player.isDamaged()) list.push('选项二'); - else list2[1]=''+list2[1]+''; - if(!list.length){event.finish(); return;} - if(player.countCards('he',card=>get.type(card)!='basic')) list.push('背水!') - else list2[2]=''+list2[2]+''; - list.push('cancel2'); - player.chooseControl(list).set('prompt','直辩:选择一项').set('choiceList',list2).set('ai',function(){ - var target=_status.event.getParent().target; - if(_status.event.controls.includes('背水!')&&player.isDamaged()&&(target.countCards('h')||target.countCards('e',function(card){ - return player.canEquip(card)&&get.value(card,target)>=4+player.getDamagedHp(); - }))) return 2; - if(player.isDamaged()&&(player.hp<=2||(!target.countCards('h')&&!target.countCards('e',function(card){ - return player.canEquip(card)&&get.value(card,target)>=4+player.getDamagedHp(); - })))) return 1; - return 0; - }); - } - else { + } else event.finish(); + "step 2"; + if (result.bool) { + var list = [], + list2 = [ + "将" + get.translation(target) + "区域中的一张牌移动到你的区域内", + "回复1点体力", + "背水!弃置一张非基本牌,并依次执行上述所有选项", + ]; + if ( + target.countCards("h") || + target.hasCard(function (card) { + return player.canEquip(card); + }, "e") || + target.hasCard(function (card) { + return player.canAddJudge(card); + }, "j") + ) + list.push("选项一"); + else list2[0] = '' + list2[0] + ""; + if (player.isDamaged()) list.push("选项二"); + else list2[1] = '' + list2[1] + ""; + if (!list.length) { + event.finish(); + return; + } + if (player.countCards("he", (card) => get.type(card) != "basic")) list.push("背水!"); + else list2[2] = '' + list2[2] + ""; + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", "直辩:选择一项") + .set("choiceList", list2) + .set("ai", function () { + var target = _status.event.getParent().target; + if ( + _status.event.controls.includes("背水!") && + player.isDamaged() && + (target.countCards("h") || + target.countCards("e", function (card) { + return ( + player.canEquip(card) && + get.value(card, target) >= 4 + player.getDamagedHp() + ); + })) + ) + return 2; + if ( + player.isDamaged() && + (player.hp <= 2 || + (!target.countCards("h") && + !target.countCards("e", function (card) { + return ( + player.canEquip(card) && + get.value(card, target) >= 4 + player.getDamagedHp() + ); + }))) + ) + return 1; + return 0; + }); + } else { player.loseHp(); event.finish(); } - 'step 3' - if(result.control!='cancel2'){ - event.control=result.control; - if(result.control=='背水!'&&player.countCards('he',function(card){ - return get.type(card)!='basic'; - })) player.chooseToDiscard('he',true,function(card){ - return get.type(card)!='basic'; - }); - } - else event.finish(); - 'step 4' - if(event.control=='选项一'||event.control=='背水!'){ - player.choosePlayerCard(target,'hej',true).set('ai',get.buttonValue); - } - else event.goto(6); - 'step 5' - if(result.bool){ - var card=result.cards[0]; - switch (get.position(card)){ - case 'h':player.gain(card,target,'giveAuto'); break; - case 'e':target.$give(card,player,false); player.equip(card); break; - case 'j':target.$give(card,player,false); player.addJudge(card); break; + "step 3"; + if (result.control != "cancel2") { + event.control = result.control; + if ( + result.control == "背水!" && + player.countCards("he", function (card) { + return get.type(card) != "basic"; + }) + ) + player.chooseToDiscard("he", true, function (card) { + return get.type(card) != "basic"; + }); + } else event.finish(); + "step 4"; + if (event.control == "选项一" || event.control == "背水!") { + player.choosePlayerCard(target, "hej", true).set("ai", get.buttonValue); + } else event.goto(6); + "step 5"; + if (result.bool) { + var card = result.cards[0]; + switch (get.position(card)) { + case "h": + player.gain(card, target, "giveAuto"); + break; + case "e": + target.$give(card, player, false); + player.equip(card); + break; + case "j": + target.$give(card, player, false); + player.addJudge(card); + break; } } - 'step 6' - if(event.control=='选项二'||event.control=='背水!') player.recover(); + "step 6"; + if (event.control == "选项二" || event.control == "背水!") player.recover(); }, }, - twyuyan:{ - audio:'yuyan', - trigger:{target:'useCardToTarget'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.card.isCard&&player.hp=13||!trigger.player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.number(card)>num; - },'he')))||(typeof num!='number'&&!trigger.player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return get.type(card)!='basic'; - },'he'))) event._result={bool:false}; - else trigger.player.chooseCard('he',function(card){ - if(typeof _status.event.number=='number') return get.number(card)>_status.event.number; - return get.type(card)!='basic'; - },'交给'+get.translation(player)+'一张'+str+'牌,或取消'+get.translation(trigger.card)+'对其的目标').set('number',num).set('ai',function(card){ - if(card.name=='shan'||card.name=='tao'||card.name=='jiu') return false; - return 6-get.value(card); - }); - 'step 1' - if(result.bool) trigger.player.give(result.cards,player); - else{ + forced: true, + logTarget: "player", + content: function () { + "step 0"; + var num = get.number(trigger.card), + str = ""; + if (typeof num == "number") str = "点数大于" + get.cnNumber(num) + "的"; + else str = "非基本"; + if ( + (typeof num == "number" && + (num >= 13 || + !trigger.player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.number(card) > num; + }, "he"))) || + (typeof num != "number" && + !trigger.player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return get.type(card) != "basic"; + }, "he")) + ) + event._result = { bool: false }; + else + trigger.player + .chooseCard( + "he", + function (card) { + if (typeof _status.event.number == "number") + return get.number(card) > _status.event.number; + return get.type(card) != "basic"; + }, + "交给" + + get.translation(player) + + "一张" + + str + + "牌,或取消" + + get.translation(trigger.card) + + "对其的目标" + ) + .set("number", num) + .set("ai", function (card) { + if (card.name == "shan" || card.name == "tao" || card.name == "jiu") + return false; + return 6 - get.value(card); + }); + "step 1"; + if (result.bool) trigger.player.give(result.cards, player); + else { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&&player.hp>target.hp&&get.attitude(player,target)<0){ - var num=get.number(card); - var bs=player.getCards('h',function(cardx){ - return (typeof num=='number'?(get.number(cardx)>num):(get.type(cardx)!='basic'))&&!['','',''].includes(cardx.name); + ai: { + effect: { + target: function (card, player, target, current) { + if ( + card.name == "sha" && + player.hp > target.hp && + get.attitude(player, target) < 0 + ) { + var num = get.number(card); + var bs = player.getCards("h", function (cardx) { + return ( + (typeof num == "number" + ? get.number(cardx) > num + : get.type(cardx) != "basic") && + !["", "", ""].includes(cardx.name) + ); }); - if(bs.length<2) return 0; - if(player.hasSkill('jiu')||player.hasSkill('tianxianjiu')) return; - if(bs.length<=2){ - for(var i=0; i{ - if(player!=evt.player&&evt._dyinged) targets.add(evt.player); + twchuhai: { + audio: "chuhai", + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + var targets = []; + player.getHistory("sourceDamage", (evt) => { + if (player != evt.player && evt._dyinged) targets.add(evt.player); }); - return targets.length>=2; + return targets.length >= 2; }, - forced:true, - locked:false, - dutySkill:true, - skillAnimation:true, - animationColor:'wood', - group:'twchuhai_lose', - content:function(){ - 'step 0' - game.log(player,'成功完成使命'); - player.awakenSkill('twchuhai'); - if(!player.isDisabledJudge()) player.disableJudge(); - event.current=player.next; - 'step 1' - if(!event.current.countCards('he')) event.goto(3); - else event.current.chooseCard('交给'+get.translation(player)+'一张牌','he',true).set('ai',get.disvalue2); - 'step 2' - if(result.bool&&result.cards&&result.cards.length) event.current.give(result.cards,player); - 'step 3' - event.current=event.current.next; - if(event.current!=player) event.goto(1); + forced: true, + locked: false, + dutySkill: true, + skillAnimation: true, + animationColor: "wood", + group: "twchuhai_lose", + content: function () { + "step 0"; + game.log(player, "成功完成使命"); + player.awakenSkill("twchuhai"); + if (!player.isDisabledJudge()) player.disableJudge(); + event.current = player.next; + "step 1"; + if (!event.current.countCards("he")) event.goto(3); + else + event.current + .chooseCard("交给" + get.translation(player) + "一张牌", "he", true) + .set("ai", get.disvalue2); + "step 2"; + if (result.bool && result.cards && result.cards.length) + event.current.give(result.cards, player); + "step 3"; + event.current = event.current.next; + if (event.current != player) event.goto(1); }, - subSkill:{ - lose:{ - audio:'chuhai', - trigger:{ - global:['gainAfter','loseAsyncAfter'] + subSkill: { + lose: { + audio: "chuhai", + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - forced:true, - dutySkill:true, - filter:function(event,player){ - var cards=event.getg(player); - if(!cards.length) return false; - return game.hasPlayer(current=>{ - if(current==player) return false; - var evt=event.getl(current); - if(evt&&evt.cards&&evt.cards.length) return true; + forced: true, + dutySkill: true, + filter: function (event, player) { + var cards = event.getg(player); + if (!cards.length) return false; + return game.hasPlayer((current) => { + if (current == player) return false; + var evt = event.getl(current); + if (evt && evt.cards && evt.cards.length) return true; return false; }); }, - content:function(){ - 'step 0' - var cards=trigger.getg(player); - if(!cards.length){ + content: function () { + "step 0"; + var cards = trigger.getg(player); + if (!cards.length) { event.finish(); return; } - player.chooseCard('h','除害:将其中一张得到的牌置入弃牌堆',true,function(card){ - return _status.event.cards.includes(card); - }).set('ai',function(card){ - return -get.value(card); - }).set('cards',cards); - 'step 1' - if(result.bool) player.loseToDiscardpile(result.cards); + player + .chooseCard("h", "除害:将其中一张得到的牌置入弃牌堆", true, function (card) { + return _status.event.cards.includes(card); + }) + .set("ai", function (card) { + return -get.value(card); + }) + .set("cards", cards); + "step 1"; + if (result.bool) player.loseToDiscardpile(result.cards); }, }, }, }, //桥公 - twyizhu:{ - audio:'yizhu', - group:['twyizhu_use','twyizhu_discard'], - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - content:function(){ - 'step 0' + twyizhu: { + audio: "yizhu", + group: ["twyizhu_use", "twyizhu_discard"], + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + content: function () { + "step 0"; player.draw(2); - 'step 1' - var hs=player.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length<=2) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,2,'选择两张牌洗入牌堆'); - 'step 2' - if(result.bool){ - player.$throw(result.cards.length,1000); - player.lose(result.cards,ui.cardPile).insert_index=function(){ - return ui.cardPile.childNodes[get.rand(0,game.players.length*2-2)]; - } - player.markAuto('twyizhu',result.cards); - } - else event.finish(); - 'step 3' + "step 1"; + var hs = player.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length <= 2) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", true, 2, "选择两张牌洗入牌堆"); + "step 2"; + if (result.bool) { + player.$throw(result.cards.length, 1000); + player.lose(result.cards, ui.cardPile).insert_index = function () { + return ui.cardPile.childNodes[get.rand(0, game.players.length * 2 - 2)]; + }; + player.markAuto("twyizhu", result.cards); + } else event.finish(); + "step 3"; game.updateRoundNumber(); game.delayx(); }, - intro:{ - mark:function(dialog,content,player){ - if(player==game.me||player.isUnderControl()) dialog.addAuto(content); + intro: { + mark: function (dialog, content, player) { + if (player == game.me || player.isUnderControl()) dialog.addAuto(content); else { - var names=[]; - for(var i of content) names.add(i.name); + var names = []; + for (var i of content) names.add(i.name); return get.translation(names); } }, }, - subSkill:{ - use:{ - audio:'yizhu', - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - return player.getStorage('twyizhu').length&& - event.player!=player&&event.targets.length==1&& - event.cards.filter(function(i){ - return player.getStorage('twyizhu').includes(i); - }).length>0; + subSkill: { + use: { + audio: "yizhu", + trigger: { global: "useCardToPlayer" }, + filter: function (event, player) { + return ( + player.getStorage("twyizhu").length && + event.player != player && + event.targets.length == 1 && + event.cards.filter(function (i) { + return player.getStorage("twyizhu").includes(i); + }).length > 0 + ); }, - logTarget:'player', - forced:true, - locked:false, - content:function(){ - 'step 0' - var list=[]; - if(!game.hasPlayer(function(current){ - return current!=trigger.target&&lib.filter.targetEnabled2(trigger.card,trigger.player,current); - })) event.goto(3); - var filter=function(event,player){ - var card=event.card,info=get.info(card); - if(info.allowMultiple==false) return false; - if(!info.multitarget){ - return game.hasPlayer(current=>lib.filter.targetEnabled2(card,player,current)); + logTarget: "player", + forced: true, + locked: false, + content: function () { + "step 0"; + var list = []; + if ( + !game.hasPlayer(function (current) { + return ( + current != trigger.target && + lib.filter.targetEnabled2(trigger.card, trigger.player, current) + ); + }) + ) + event.goto(3); + var filter = function (event, player) { + var card = event.card, + info = get.info(card); + if (info.allowMultiple == false) return false; + if (!info.multitarget) { + return game.hasPlayer((current) => + lib.filter.targetEnabled2(card, player, current) + ); } return false; - } - var enable=filter(trigger.getParent(),trigger.player); - var prompt2='操作提示:'; - if(enable) prompt2+='选择一名合法的其他角色,以增加其为目标;或'; - prompt2+='选择目标角色('+get.translation(trigger.target)+')和另一名合法的角色,以取消前者为目标并增加后者为目标'; - player.chooseTarget('遗珠:是否'+(enable?'增加或':'')+'修改目标?',prompt2,[enable?1:2,2],(card,player,target)=>{ - var evt=_status.event.getTrigger(),card=evt.card; - if(target==evt.target) return true; - if(ui.selected.targets.length&&ui.selected.targets[0]!=evt.target) return false; - return lib.filter.targetEnabled2(card,evt.player,target); - }).set('targetprompt',target=>{ - return target==_status.event.targetx?'取消目标':'增加目标'; - }).set('filterOk',()=>{ - if(ui.selected.targets.length==1&&ui.selected.targets[0]==_status.event.targetx) return false; - return true; - }).set('ai',target=>{ - var evt=_status.event.getTrigger(),card=evt.card,player=_status.event.player; - if(target==evt.target&&get.effect(evt.target,card,evt.player,player)<0) return 100; - if(target==evt.target) return -100; - return get.effect(target,card,evt.player,player); - }).set('targetx',trigger.target).set('card',trigger.card); - 'step 1' - if(result.bool){ - var target=result.targets[result.targets[0]==trigger.target?1:0]; - if(result.targets.length>1) { - player.line2([trigger.target,target]); + }; + var enable = filter(trigger.getParent(), trigger.player); + var prompt2 = "操作提示:"; + if (enable) prompt2 += "选择一名合法的其他角色,以增加其为目标;或"; + prompt2 += + "选择目标角色(" + + get.translation(trigger.target) + + ")和另一名合法的角色,以取消前者为目标并增加后者为目标"; + player + .chooseTarget( + "遗珠:是否" + (enable ? "增加或" : "") + "修改目标?", + prompt2, + [enable ? 1 : 2, 2], + (card, player, target) => { + var evt = _status.event.getTrigger(), + card = evt.card; + if (target == evt.target) return true; + if ( + ui.selected.targets.length && + ui.selected.targets[0] != evt.target + ) + return false; + return lib.filter.targetEnabled2(card, evt.player, target); + } + ) + .set("targetprompt", (target) => { + return target == _status.event.targetx ? "取消目标" : "增加目标"; + }) + .set("filterOk", () => { + if ( + ui.selected.targets.length == 1 && + ui.selected.targets[0] == _status.event.targetx + ) + return false; + return true; + }) + .set("ai", (target) => { + var evt = _status.event.getTrigger(), + card = evt.card, + player = _status.event.player; + if ( + target == evt.target && + get.effect(evt.target, card, evt.player, player) < 0 + ) + return 100; + if (target == evt.target) return -100; + return get.effect(target, card, evt.player, player); + }) + .set("targetx", trigger.target) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + var target = result.targets[result.targets[0] == trigger.target ? 1 : 0]; + if (result.targets.length > 1) { + player.line2([trigger.target, target]); trigger.targets.remove(trigger.target); trigger.getParent().triggeredTargets1.remove(trigger.target); trigger.untrigger(); - } - else player.line(target); + } else player.line(target); trigger.targets.push(target); } - 'step 2' - var list=trigger.cards.filter(function(i){ - return player.getStorage('twyizhu').includes(i); + "step 2"; + var list = trigger.cards.filter(function (i) { + return player.getStorage("twyizhu").includes(i); }); - player.unmarkAuto('twyizhu',list); + player.unmarkAuto("twyizhu", list); player.draw(); game.delayx(); }, }, - discard:{ - trigger:{ - global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter'], + discard: { + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - silent:true, - forced:true, - locked:false, - filter:function(event,player){ - return player.getStorage('twyizhu').length&&event.getd().filter(function(i){ - return player.getStorage('twyizhu').includes(i); - }).length>0; + silent: true, + forced: true, + locked: false, + filter: function (event, player) { + return ( + player.getStorage("twyizhu").length && + event.getd().filter(function (i) { + return player.getStorage("twyizhu").includes(i); + }).length > 0 + ); }, - content:function(){ - var list=trigger.getd().filter(function(i){ - return player.getStorage('twyizhu').includes(i); + content: function () { + var list = trigger.getd().filter(function (i) { + return player.getStorage("twyizhu").includes(i); }); - player.unmarkAuto('twyizhu',list); + player.unmarkAuto("twyizhu", list); }, }, }, }, - twluanchou:{ - audio:'luanchou', - enable:'phaseUse', - usable:1, - selectTarget:2, - filterTarget:true, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - game.filterPlayer().sortBySeat().forEach(function(current){ - current.removeSkills('twgonghuan'); - }); - 'step 1' + twluanchou: { + audio: "luanchou", + enable: "phaseUse", + usable: 1, + selectTarget: 2, + filterTarget: true, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + game.filterPlayer() + .sortBySeat() + .forEach(function (current) { + current.removeSkills("twgonghuan"); + }); + "step 1"; targets.sortBySeat(); - for(var i of targets) i.addSkills('twgonghuan'); + for (var i of targets) i.addSkills("twgonghuan"); }, - derivation:'twgonghuan', - ai:{ - order:10, - expose:0.2, - result:{ - target:function(player,target){ - return Math.max(0.1,target.hp)*(get.attitude(player,target)+20); + derivation: "twgonghuan", + ai: { + order: 10, + expose: 0.2, + result: { + target: function (player, target) { + return Math.max(0.1, target.hp) * (get.attitude(player, target) + 20); }, }, }, }, - twgonghuan:{ - audio:'gonghuan', - trigger:{global:'damageBegin4'}, - usable:1, - filter:function(event,player){ - if(event.player==player) return false; - return !event.twgonghuan&&event.player.hp<=player.hp&&event.player.hasSkill('twgonghuan'); + twgonghuan: { + audio: "gonghuan", + trigger: { global: "damageBegin4" }, + usable: 1, + filter: function (event, player) { + if (event.player == player) return false; + return ( + !event.twgonghuan && + event.player.hp <= player.hp && + event.player.hasSkill("twgonghuan") + ); }, - check:function(event,player){ - if(get.damageEffect(event.player,event.source,player)>0||(get.attitude(player,event.player)>0&&get.damageEffect(event.player,event.source,event.player)>0)) return false; - return get.attitude(player,event.player)>0&&event.player.hp0); + check: function (event, player) { + if ( + get.damageEffect(event.player, event.source, player) > 0 || + (get.attitude(player, event.player) > 0 && + get.damageEffect(event.player, event.source, event.player) > 0) + ) + return false; + return ( + get.attitude(player, event.player) > 0 && + event.player.hp < player.hp && + ((["君", "主"].includes(lib.translate[event.player.identity]) && + !["野", "内"].includes(lib.translate[player.identity])) || + player.hp + player.hujia - event.num > 0) + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.cancel(); - player.damage(trigger.source?trigger.source:'nosource',trigger.nature,trigger.num).set('card',trigger.card).set('cards',trigger.cards).twgonghuan=true; + player + .damage(trigger.source ? trigger.source : "nosource", trigger.nature, trigger.num) + .set("card", trigger.card) + .set("cards", trigger.cards).twgonghuan = true; }, }, //桥蕤 - twxiawei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - locked:false, - group:['twxiawei_init','twxiawei_lose','twxiawei_unmark'], - content:function(){ - 'step 0' - player.chooseControl('1','2','3','4','cancel2').set('prompt',get.prompt('twxiawei')).set('prompt2','妄行:将X+1张牌置于武将牌上,称为“威”').set('ai',function(){ - var player=_status.event.player; - if(player.maxHp>3) return 3; - return Math.min(3,player.countCards('he')+1); - }); - 'step 1' - if(result.control!='cancel2'){ - var num=result.index+1,cards=get.cards(num+1); - player.logSkill('twxiawei'); - player.addTempSkill('wangxing'); - player.addMark('wangxing',num,false); - player.$gain2(cards,false); - game.log(player,'将',cards,'作为“威”置于了武将牌上'); - player.loseToSpecial(cards,'twxiawei').visible=true; - } - else event.finish(); - 'step 2' - player.markSkill('twxiawei'); + twxiawei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + locked: false, + group: ["twxiawei_init", "twxiawei_lose", "twxiawei_unmark"], + content: function () { + "step 0"; + player + .chooseControl("1", "2", "3", "4", "cancel2") + .set("prompt", get.prompt("twxiawei")) + .set("prompt2", "妄行:将X+1张牌置于武将牌上,称为“威”") + .set("ai", function () { + var player = _status.event.player; + if (player.maxHp > 3) return 3; + return Math.min(3, player.countCards("he") + 1); + }); + "step 1"; + if (result.control != "cancel2") { + var num = result.index + 1, + cards = get.cards(num + 1); + player.logSkill("twxiawei"); + player.addTempSkill("wangxing"); + player.addMark("wangxing", num, false); + player.$gain2(cards, false); + game.log(player, "将", cards, "作为“威”置于了武将牌上"); + player.loseToSpecial(cards, "twxiawei").visible = true; + } else event.finish(); + "step 2"; + player.markSkill("twxiawei"); game.delayx(); }, - marktext:'威', - intro:{ - mark:function(dialog,storage,player){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('twxiawei'); + marktext: "威", + intro: { + mark: function (dialog, storage, player) { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); - if(!cards||!cards.length) return; + if (!cards || !cards.length) return; dialog.addAuto(cards); }, - markcount:function(storage,player){ - return player.countCards('s',function(card){ - return card.hasGaintag('twxiawei'); + markcount: function (storage, player) { + return player.countCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); }, - onunmark:function(storage,player){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('twxiawei'); + onunmark: function (storage, player) { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); - if(cards.length){ + if (cards.length) { player.loseToDiscardpile(cards); } }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('twxiawei')) return num+0.5; + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("twxiawei")) return num + 0.5; }, }, - subSkill:{ - init:{ - audio:'twxiawei', - trigger:{global:'phaseBefore',player:'enterGame'}, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + subSkill: { + init: { + audio: "twxiawei", + 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 cards=[]; - for(var i=1;i<=2;i++){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&get.type(card)=='basic'; + forced: true, + locked: false, + content: function () { + "step 0"; + var cards = []; + for (var i = 1; i <= 2; i++) { + var card = get.cardPile2(function (card) { + return !cards.includes(card) && get.type(card) == "basic"; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length){ - player.$gain2(cards,false); - game.log(player,'将',cards,'作为“威”置于了武将牌上'); - player.loseToSpecial(cards,'twxiawei').visible=true; - } - else event.finish(); - 'step 1' - player.markSkill('twxiawei'); + if (cards.length) { + player.$gain2(cards, false); + game.log(player, "将", cards, "作为“威”置于了武将牌上"); + player.loseToSpecial(cards, "twxiawei").visible = true; + } else event.finish(); + "step 1"; + player.markSkill("twxiawei"); game.delayx(); }, }, - lose:{ - audio:'twxiawei', - trigger:{player:'phaseBegin'}, - filter:function(event,player){ - return player.countCards('s',function(card){ - return card.hasGaintag('twxiawei'); + lose: { + audio: "twxiawei", + trigger: { player: "phaseBegin" }, + filter: function (event, player) { + return player.countCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); }, - forced:true, - locked:false, - content:function(){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('twxiawei'); + forced: true, + locked: false, + content: function () { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); player.loseToDiscardpile(cards); }, }, - unmark:{ - trigger:{player:'loseAfter'}, - filter:function(event,player){ - if(!event.ss||!event.ss.length) return false; - return !player.countCards('s',function(card){ - return card.hasGaintag('twxiawei'); + unmark: { + trigger: { player: "loseAfter" }, + filter: function (event, player) { + if (!event.ss || !event.ss.length) return false; + return !player.countCards("s", function (card) { + return card.hasGaintag("twxiawei"); }); }, - charlotte:true, - forced:true, - silent:true, - content:function(){ - player.unmarkSkill('twxiawei'); + charlotte: true, + forced: true, + silent: true, + content: function () { + player.unmarkSkill("twxiawei"); }, }, }, }, - wangxing:{ - trigger:{player:'phaseEnd'}, - charlotte:true, - onremove:true, - forced:true, - popup:false, - filter:function(event,player){ - return player.countMark('wangxing')>0; + wangxing: { + trigger: { player: "phaseEnd" }, + charlotte: true, + onremove: true, + forced: true, + popup: false, + filter: function (event, player) { + return player.countMark("wangxing") > 0; }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',player.countMark('wangxing'),'妄行:请弃置'+get.cnNumber(player.countMark('wangxing'))+'张牌,或减1点体力上限').set('ai',function(card){ - var player=_status.event.player; - if(player.maxHp==1) return 100-get.value(card); - return 5+Math.max(0,5-player.maxHp)-get.value(card); - }); - 'step 1' - if(!result.bool) player.loseMaxHp(); + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + player.countMark("wangxing"), + "妄行:请弃置" + + get.cnNumber(player.countMark("wangxing")) + + "张牌,或减1点体力上限" + ) + .set("ai", function (card) { + var player = _status.event.player; + if (player.maxHp == 1) return 100 - get.value(card); + return 5 + Math.max(0, 5 - player.maxHp) - get.value(card); + }); + "step 1"; + if (!result.bool) player.loseMaxHp(); }, - intro:{content:'回合结束时,你须弃置#张牌,否则减1点体力上限'}, + intro: { content: "回合结束时,你须弃置#张牌,否则减1点体力上限" }, }, - twqiongji:{ - audio:2, - trigger:{player:['useCardAfter','respondAfter','damageBegin3']}, - filter:function(event,player){ - if(event.name=='damage') return !player.countCards('s',function(card){ - return card.hasGaintag('twxiawei'); - }); - return !player.hasSkill('twqiongji_silent')&&player.getHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('twxiawei')) return true; - } - return false; - }).length>0; + twqiongji: { + audio: 2, + trigger: { player: ["useCardAfter", "respondAfter", "damageBegin3"] }, + filter: function (event, player) { + if (event.name == "damage") + return !player.countCards("s", function (card) { + return card.hasGaintag("twxiawei"); + }); + return ( + !player.hasSkill("twqiongji_silent") && + player.getHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("twxiawei")) return true; + } + return false; + }).length > 0 + ); }, - forced:true, - content:function(){ - if(trigger.name=='damage') trigger.num++; + forced: true, + content: function () { + if (trigger.name == "damage") trigger.num++; else { player.draw(); - player.addTempSkill('twqiongji_silent'); + player.addTempSkill("twqiongji_silent"); } }, - ai:{combo:'twxiawei'}, - subSkill:{silent:{charlotte:true}}, + ai: { + combo: "twxiawei", + halfneg: true, + }, + subSkill: { silent: { charlotte: true } }, }, //卞夫人 - twwanwei:{ - audio:'wanwei', - trigger:{global:'damageBegin4'}, - filter:function(event,player){ + twwanwei: { + audio: "wanwei", + trigger: { global: "damageBegin4" }, + filter: function (event, player) { return event.player.isMinHp(); }, - check:function(event,player){ - return get.attitude(player,event.player)>0&&event.player.hp 0 && event.player.hp < player.hp; }, - usable:1, - logTarget:'player', - prompt2:function(event,player){ - if(player!=event.player){ - return '防止'+get.translation(event.player)+'即将受到的'+event.num+'点伤害,然后你失去1点体力'; - } - else if(event.player==player||!game.hasPlayer(function(current){ - return current!=player&¤t.maxHp>player.maxHp - })){ - return '于当前回合的结束阶段获得牌堆顶的牌并展示牌堆底的牌,若展示的牌能被使用,你使用之'; + usable: 1, + logTarget: "player", + prompt2: function (event, player) { + if (player != event.player) { + return ( + "防止" + + get.translation(event.player) + + "即将受到的" + + event.num + + "点伤害,然后你失去1点体力" + ); + } else if ( + event.player == player || + !game.hasPlayer(function (current) { + return current != player && current.maxHp > player.maxHp; + }) + ) { + return "于当前回合的结束阶段获得牌堆顶的牌并亮出牌堆底的牌,若展示的牌能被使用,你使用之"; } }, - content:function(){ - if(trigger.player!=player){ + content: function () { + if (trigger.player != player) { trigger.cancel(); player.loseHp(); } - if(trigger.player==player||!game.hasPlayer(function(current){ - return current!=player&¤t.maxHp>player.maxHp - })) player.addTempSkill('twwanwei_effect'); + if ( + trigger.player == player || + !game.hasPlayer(function (current) { + return current != player && current.maxHp > player.maxHp; + }) + ) + player.addTempSkill("twwanwei_effect"); }, - subSkill:{ - effect:{ - audio:'wanwei', - charlotte:true, - trigger:{global:'phaseJieshuBegin'}, - prompt2:'获得牌堆顶的牌并展示牌堆底的牌,若展示的牌能被使用,你使用之', - content:function(){ - 'step 0' - var card=get.cards()[0]; - player.gain(card,'gain2'); - 'step 1' - var card=get.bottomCards()[0]; + subSkill: { + effect: { + audio: "wanwei", + charlotte: true, + trigger: { global: "phaseJieshuBegin" }, + prompt2: "获得牌堆顶的牌并亮出牌堆底的牌,若展示的牌能被使用,你使用之", + content: function () { + "step 0"; + var card = get.cards()[0]; + player.gain(card, "gain2"); + "step 1"; + var card = get.bottomCards()[0]; ui.cardPile.appendChild(card); game.updateRoundNumber(); - player.showCards([card],get.translation(player)+'挽危:牌堆底的牌'); - if(player.hasUseTarget(card)) player.chooseUseTarget(card,true); + player.showCards([card], get.translation(player) + "挽危:牌堆底的牌"); + if (player.hasUseTarget(card)) player.chooseUseTarget(card, true); }, }, }, }, - twyuejian:{ - audio:'yuejian', - enable:'phaseUse', - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - var num=Math.max(1,player.countCards('h')-player.getHandcardLimit()); - return [1,num]; + twyuejian: { + audio: "yuejian", + enable: "phaseUse", + filterCard: true, + selectCard: function () { + var player = _status.event.player; + var num = Math.max(1, player.countCards("h") - player.getHandcardLimit()); + return [1, num]; }, - complexCard:true, - discard:false, - loseTo:'cardPile', - insert:true, - visible:true, - delay:false, - position:'he', - usable:1, - check:function(card){ - if(ui.selected.cards.length>=3) return 0; - var player=_status.event.player; - var num=Math.max(1,player.countCards('h')-player.getHandcardLimit()); - if(num>=3) return 5-get.value(card); - if(num>=2&&player.isDamaged()&&ui.selected.cards.length<1) return 7-get.value(card); - if(num>=1&&player.isDamaged()&&!ui.selected.cards.length) return 6-get.value(card); + complexCard: true, + discard: false, + loseTo: "cardPile", + insert: true, + visible: true, + delay: false, + position: "he", + usable: 1, + check: function (card) { + if (ui.selected.cards.length >= 3) return 0; + var player = _status.event.player; + var num = Math.max(1, player.countCards("h") - player.getHandcardLimit()); + if (num >= 3) return 5 - get.value(card); + if (num >= 2 && player.isDamaged() && ui.selected.cards.length < 1) + return 7 - get.value(card); + if (num >= 1 && player.isDamaged() && !ui.selected.cards.length) + return 6 - get.value(card); return 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.$throw(cards.length); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','约俭:将这些牌置于牌堆顶或牌堆底'); - next.set('processAI',function(list){ - var cards=list[0][1],player=_status.event.player; - var target=player.next; - var att=get.sgn(get.attitude(player,target)); - var top=[]; - var judges=target.getCards('j'); - var stopped=false; - if(player!=target||!target.hasWuxie()){ - for(var i=0;i0)) break; + while (cards.length) { + if (get.value(cards[0], player) <= 5 == att > 0) break; top.unshift(cards.shift()); } } - bottom=cards.sort(function(a,b){ - return player.getUseValue(a)-player.getUseValue(b); + bottom = cards.sort(function (a, b) { + return player.getUseValue(a) - player.getUseValue(b); }); - return [top,bottom]; + return [top, bottom]; }); - 'step 1' - var top=result.moved[0]; - var bottom=result.moved[1]; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i=3) player.gainMaxHp(); - 'step 3' - if(cards.length>=2) player.recover(); - 'step 4' - if(cards.length>=1){ - player.addSkill('twyuejian_effect'); - player.addMark('twyuejian_effect',1,false); + "step 2"; + if (cards.length >= 3) player.gainMaxHp(); + "step 3"; + if (cards.length >= 2) player.recover(); + "step 4"; + if (cards.length >= 1) { + player.addSkill("twyuejian_effect"); + player.addMark("twyuejian_effect", 1, false); } }, - ai:{ - order:5, - result:{player:1}, + ai: { + order: 5, + result: { player: 1 }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - marktext:'俭', - intro:{ - content:'手牌上限+#', + subSkill: { + effect: { + charlotte: true, + onremove: true, + marktext: "俭", + intro: { + content: "手牌上限+#", }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('twyuejian_effect'); + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("twyuejian_effect"); }, }, }, }, }, //陈震 - twmuyue:{ - audio:1, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')||player.hasSkill('twmuyue_effect'); + twmuyue: { + audio: 1, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") || player.hasSkill("twmuyue_effect"); }, - chooseButton:{ - dialog:function(){ - var list=[]; - for(var i of lib.inpile){ - var type=get.type(i); - if(type=='basic'||type=='trick') list.push([type,'',i]); + chooseButton: { + dialog: function () { + var list = []; + for (var i of lib.inpile) { + var type = get.type(i); + if (type == "basic" || type == "trick") list.push([type, "", i]); } - return ui.create.dialog('睦约',[list,'vcard']); + return ui.create.dialog("睦约", [list, "vcard"]); }, - check:function(button){ - if(!get.cardPile2(function(cardx){ - return cardx.name==button.link[2]; - })) return 0; - return get.value({name:button.link[2]}); + check: function (button) { + if ( + !get.cardPile2(function (cardx) { + return cardx.name == button.link[2]; + }) + ) + return 0; + return get.value({ name: button.link[2] }); }, - backup:function(links,player){ - return{ - audio:'twmuyue', - filterCard:function(card,player,target){ - return !player.hasSkill('twmuyue_effect'); + backup: function (links, player) { + return { + audio: "twmuyue", + filterCard: function (card, player, target) { + return !player.hasSkill("twmuyue_effect"); }, - selectCard:function(){ - var player=_status.event.player; - return player.hasSkill('twmuyue_effect')?-1:1; + selectCard: function () { + var player = _status.event.player; + return player.hasSkill("twmuyue_effect") ? -1 : 1; }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - position:'he', - card:links[0], - filterTarget:true, - content:function(){ - 'step 0' - var card=lib.skill.twmuyue_backup.card; - event.card=card; - player.removeSkill('twmuyue_effect'); - var cardx=get.cardPile2(function(cardx){ - return cardx.name==card[2]; + position: "he", + card: links[0], + filterTarget: true, + content: function () { + "step 0"; + var card = lib.skill.twmuyue_backup.card; + event.card = card; + player.removeSkill("twmuyue_effect"); + var cardx = get.cardPile2(function (cardx) { + return cardx.name == card[2]; }); - player.line(target,'green'); - if(cardx) target.gain(cardx,'gain2'); - else{ - player.chat('无牌可得了吗?!'); - game.log('但是牌堆中已经没有','#g【'+get.translation(card[2])+'】','了!'); + player.line(target, "green"); + if (cardx) target.gain(cardx, "gain2"); + else { + player.chat("无牌可得了吗?!"); + game.log( + "但是牌堆中已经没有", + "#g【" + get.translation(card[2]) + "】", + "了!" + ); } - 'step 1' - if(cards&&cards.length&&get.name(cards[0],player)==card[2]) player.addSkill('twmuyue_effect'); + "step 1"; + if (cards && cards.length && get.name(cards[0], player) == card[2]) + player.addSkill("twmuyue_effect"); }, - ai:{ - result:{ - target:function(player,target){ - var att=Math.abs(get.attitude(player,target)); - if(target.hasSkill('nogain')) att/=10; - return att/Math.sqrt(get.distance(player,target,'absolute')); - } - } + ai: { + result: { + target: function (player, target) { + var att = Math.abs(get.attitude(player, target)); + if (target.hasSkill("nogain")) att /= 10; + return att / Math.sqrt(get.distance(player, target, "absolute")); + }, + }, }, - } + }; }, - prompt:function(links,player){ - return (player.hasSkill('twmuyue_effect')?'':'弃置一张牌,')+'令一名角色从牌堆中获得一张【'+get.translation(links[0][2])+'】'; - } - }, - ai:{ - order:3, - result:{player:1}, - }, - subSkill:{ - effect:{ - charlotte:true, - mark:true, - intro:{content:'下一次发动【睦约】无需弃牌'}, + prompt: function (links, player) { + return ( + (player.hasSkill("twmuyue_effect") ? "" : "弃置一张牌,") + + "令一名角色从牌堆中获得一张【" + + get.translation(links[0][2]) + + "】" + ); }, - backup:{}, + }, + ai: { + order: 3, + result: { player: 1 }, + }, + subSkill: { + effect: { + charlotte: true, + mark: true, + intro: { content: "下一次发动【睦约】无需弃牌" }, + }, + backup: {}, }, }, - twchayi:{ - audio:1, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twchayi'),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return -get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twchayi',target); - if(!target.countCards('h')) event._result={index:1}; - else target.chooseControl().set('choiceList',[ - '展示手牌', - '下一次使用牌时候弃一张牌', - ]); - } - else event.finish(); - 'step 2' - target.storage.twchayi_re=[result.index,target.countCards('h')]; - target.addSkill('twchayi_re'); - target.markSkill('twchayi_re'); - if(result.index==0) target.showCards(target.getCards('h'),get.translation(target)+'的手牌'); - else{ - target.addMark('twchayi_effect',1,false); - target.addSkill('twchayi_effect'); + twchayi: { + audio: 1, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twchayi"), lib.filter.notMe) + .set("ai", function (target) { + var player = _status.event.player; + return -get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twchayi", target); + if (!target.countCards("h")) event._result = { index: 1 }; + else + target + .chooseControl() + .set("choiceList", ["展示手牌", "下一次使用牌时候弃一张牌"]); + } else event.finish(); + "step 2"; + target.storage.twchayi_re = [result.index, target.countCards("h")]; + target.addSkill("twchayi_re"); + target.markSkill("twchayi_re"); + if (result.index == 0) + target.showCards(target.getCards("h"), get.translation(target) + "的手牌"); + else { + target.addMark("twchayi_effect", 1, false); + target.addSkill("twchayi_effect"); } }, - subSkill:{ - effect:{ - intro:{content:'使用下一张牌时弃置&张牌'}, - charlotte:true, - onremove:true, - audio:'twchayi', - trigger:{player:'useCard'}, - forced:true, - content:function(){ - player.chooseToDiscard('he',true,player.countMark('twchayi_effect')); - player.removeSkill('twchayi_effect'); + subSkill: { + effect: { + intro: { content: "使用下一张牌时弃置&张牌" }, + charlotte: true, + onremove: true, + audio: "twchayi", + trigger: { player: "useCard" }, + forced: true, + content: function () { + player.chooseToDiscard("he", true, player.countMark("twchayi_effect")); + player.removeSkill("twchayi_effect"); }, }, - re:{ - charlotte:true, - onremove:true, - audio:'twchayi', - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ + re: { + charlotte: true, + onremove: true, + audio: "twchayi", + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { return player.storage.twchayi_re; }, - content:function(){ - if(player.countCards('h')!=player.storage.twchayi_re[1]){ - player.popup('察异'); - if(player.storage.twchayi_re[0]==0){ - player.addMark('twchayi_effect',1,false); - player.addSkill('twchayi_effect'); - } - else player.showCards(player.getCards('h'),get.translation(player)+'的手牌'); + content: function () { + if (player.countCards("h") != player.storage.twchayi_re[1]) { + player.popup("察异"); + if (player.storage.twchayi_re[0] == 0) { + player.addMark("twchayi_effect", 1, false); + player.addSkill("twchayi_effect"); + } else + player.showCards( + player.getCards("h"), + get.translation(player) + "的手牌" + ); } - player.removeSkill('twchayi_re'); + player.removeSkill("twchayi_re"); }, - marktext:'异', - intro:{ - markcount:function(storage,player){ - if(!storage||!storage.length) return 0; + marktext: "异", + intro: { + markcount: function (storage, player) { + if (!storage || !storage.length) return 0; return storage[1]; }, - content:function(storage,player){ - if(!storage||!storage.length) return; - return '下个回合结束时,若你的手牌数不为'+storage[1]+',你'+(storage[0]==0?'下次使用牌时弃置一张牌':'展示所有手牌'); - } - } + content: function (storage, player) { + if (!storage || !storage.length) return; + return ( + "下个回合结束时,若你的手牌数不为" + + storage[1] + + ",你" + + (storage[0] == 0 ? "下次使用牌时弃置一张牌" : "展示所有手牌") + ); + }, + }, }, }, }, //费祎 - twshengxi:{ - audio:'shengxi_feiyi', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getHistory('useCard').length>0&&player.getHistory('sourceDamage').length==0; + twshengxi: { + audio: "shengxi_feiyi", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.getHistory("useCard").length > 0 && + player.getHistory("sourceDamage").length == 0 + ); }, - direct:true, - content:function(){ - 'step 0' - var list=get.zhinangs(); - player.chooseButton(['###'+get.prompt('twshengxi')+'###获得一张智囊并摸一张牌',[list,'vcard']]).set('ai',function(card){ - return (Math.random()+0.5)*get.value({name:card.link[2]},_status.event.player) - }); - 'step 1' - if(result.bool){ - player.logSkill('twshengxi'); - var card=get.cardPile2(function(card){ - return card.name==result.links[0][2]; + direct: true, + content: function () { + "step 0"; + var list = get.zhinangs(); + player + .chooseButton([ + "###" + get.prompt("twshengxi") + "###获得一张智囊并摸一张牌", + [list, "vcard"], + ]) + .set("ai", function (card) { + return ( + (Math.random() + 0.5) * + get.value({ name: card.link[2] }, _status.event.player) + ); }); - if(card) player.gain(card,'gain2'); + "step 1"; + if (result.bool) { + player.logSkill("twshengxi"); + var card = get.cardPile2(function (card) { + return card.name == result.links[0][2]; + }); + if (card) player.gain(card, "gain2"); player.draw(); } }, - group:'twshengxi_zhunbei', - subfrequent:['zhunbei'], - subSkill:{ - zhunbei:{ - audio:'shengxi_feiyi', - trigger:{player:'phaseZhunbeiBegin'}, - frequent:true, - prompt2:'从游戏外或牌堆中获得一张【调剂盐梅】', - content:function(){ - if(!_status.tiaojiyanmei_suits||_status.tiaojiyanmei_suits.length>0){ - if(!lib.inpile.includes('tiaojiyanmei')){ - game.broadcastAll(function(){lib.inpile.add('tiaojiyanmei')}); + group: "twshengxi_zhunbei", + subfrequent: ["zhunbei"], + subSkill: { + zhunbei: { + audio: "shengxi_feiyi", + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + prompt2: "从游戏外或牌堆中获得一张【调剂盐梅】", + content: function () { + if (!_status.tiaojiyanmei_suits || _status.tiaojiyanmei_suits.length > 0) { + if (!lib.inpile.includes("tiaojiyanmei")) { + game.broadcastAll(function () { + lib.inpile.add("tiaojiyanmei"); + }); } - if(!_status.tiaojiyanmei_suits) _status.tiaojiyanmei_suits=lib.suit.slice(0); - player.gain(game.createCard2('tiaojiyanmei',_status.tiaojiyanmei_suits.randomRemove(),6),'gain2'); - } - else { - var card=get.cardPile2(function(card){ - return card.name=='tiaojiyanmei'; + if (!_status.tiaojiyanmei_suits) + _status.tiaojiyanmei_suits = lib.suit.slice(0); + player.gain( + game.createCard2( + "tiaojiyanmei", + _status.tiaojiyanmei_suits.randomRemove(), + 6 + ), + "gain2" + ); + } else { + var card = get.cardPile2(function (card) { + return card.name == "tiaojiyanmei"; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } }, }, }, }, - twkuanji:{ - audio:'fyjianyu', - trigger:{ - player:'loseAfter', - global:['cardsDiscardAfter','loseAsyncAfter','equipAfter'], + twkuanji: { + audio: "fyjianyu", + trigger: { + player: "loseAfter", + global: ["cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, - filter:function(event,player){ - if(event.name!='cardsDiscard'){ - return event.getd(player,'cards2').length>0; - } - else{ - if(event.cards.filterInD('d').length<=0) return false; - var evt=event.getParent(); - if(evt.name!='orderingDiscard') return false; - var evtx=(evt.relatedEvent||evt.getParent()); - if(evtx.player!=player) return false; - if(evtx.name=='useCard') return false; - return player.hasHistory('lose',evtxx=>{ - return evtx==(evtxx.relatedEvent||evtxx.getParent()); + filter: function (event, player) { + if (event.name != "cardsDiscard") { + return event.getd(player, "cards2").length > 0; + } else { + if (event.cards.filterInD("d").length <= 0) return false; + var evt = event.getParent(); + if (evt.name != "orderingDiscard") return false; + var evtx = evt.relatedEvent || evt.getParent(); + if (evtx.player != player) return false; + if (evtx.name == "useCard") return false; + return player.hasHistory("lose", (evtxx) => { + return evtx == (evtxx.relatedEvent || evtxx.getParent()); }); } }, - usable:1, - direct:true, - content:function(){ - 'step 0' - var cards=[]; - if(trigger.name!='cardsDiscard'){ - cards=trigger.getd(player,'cards2'); - } - else cards=trigger.cards.filterInD('d'); - player.chooseButton(['宽济:是否将一张牌交给一名其他角色?',cards]).set('ai',function(button){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })) return Math.abs(get.value(button.link,'raw'))+1; - return -get.value(button.link,'raw'); - }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget('请选择【宽济】的目标','令一名其他角色获得'+get.translation(card),lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target)*get.value(_status.event.getParent().card,target)*(target.hasSkillTag('nogain')?0.1:1); + usable: 1, + direct: true, + content: function () { + "step 0"; + var cards = []; + if (trigger.name != "cardsDiscard") { + cards = trigger.getd(player, "cards2"); + } else cards = trigger.cards.filterInD("d"); + player + .chooseButton(["宽济:是否将一张牌交给一名其他角色?", cards]) + .set("ai", function (button) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) + return Math.abs(get.value(button.link, "raw")) + 1; + return -get.value(button.link, "raw"); }); - } - else{ + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget( + "请选择【宽济】的目标", + "令一名其他角色获得" + get.translation(card), + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.attitude(player, target) * + get.value(_status.event.getParent().card, target) * + (target.hasSkillTag("nogain") ? 0.1 : 1) + ); + }); + } else { player.storage.counttrigger.twkuanji--; event.finish(); } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twkuanji',target); - target.gain(card,'gain2'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twkuanji", target); + target.gain(card, "gain2"); } }, }, - shengxi_feiyi:{audio:2}, + shengxi_feiyi: { audio: 2 }, //王越 - twyulong:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget) return false; - if(event.card.name!='sha') return false; - return event.targets.some(target=>player.canCompare(target)); + twyulong: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget) return false; + if (event.card.name != "sha") return false; + return event.targets.some((target) => player.canCompare(target)); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twyulong'),(card,player,target)=>{ - return _status.event.getTrigger().targets.includes(target)&&player.canCompare(target); - }).set('ai',target=>{ - if(player.hasCard(card=>get.value(card)<6,'h')) return -get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twyulong',target); - if(player.canCompare(target)){ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twyulong"), (card, player, target) => { + return ( + _status.event.getTrigger().targets.includes(target) && + player.canCompare(target) + ); + }) + .set("ai", (target) => { + if (player.hasCard((card) => get.value(card) < 6, "h")) + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twyulong", target); + if (player.canCompare(target)) { player.chooseToCompare(target); } - } - else{ + } else { event.finish(); } - 'step 2' - if(result.bool){ - var color=get.color(result.player,false); - if(color=='black') trigger.getParent().baseDamage++; - else if(color=='red') trigger.directHit.addArray(game.players); - trigger.getParent().twyulong=true; - player.addTempSkill('twyulong_addCount'); + "step 2"; + if (result.bool) { + var color = get.color(result.player, false); + if (color == "black") trigger.getParent().baseDamage++; + else if (color == "red") trigger.directHit.addArray(game.players); + trigger.getParent().twyulong = true; + player.addTempSkill("twyulong_addCount"); } }, - subSkill:{ - addCount:{ - charlotte:true, - forced:true, - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(!event.card||event.card.name!='sha') return false; - var evt=event.getParent(2); - if(evt.name!='useCard'||!evt.twyulong) return false; + subSkill: { + addCount: { + charlotte: true, + forced: true, + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (!event.card || event.card.name != "sha") return false; + var evt = event.getParent(2); + if (evt.name != "useCard" || !evt.twyulong) return false; return true; }, - content:function(){ - var evt=trigger.getParent(2); - if(evt.addCount!==false){ - evt.addCount=false; - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + content: function () { + var evt = trigger.getParent(2); + if (evt.addCount !== false) { + evt.addCount = false; + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } } - } - } - } + }, + }, + }, }, - twjianming:{ - audio:2, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - if(event.card.name!='sha'||!lib.suit.includes(get.suit(event.card))) return false; - var list=[]; - player.getHistory('useCard',function(evt){ - if(evt.card.name=='sha'){ - if(event.card!=evt.card) list.push(get.suit(evt.card)); + twjianming: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + if (event.card.name != "sha" || !lib.suit.includes(get.suit(event.card))) return false; + var list = []; + player.getHistory("useCard", function (evt) { + if (evt.card.name == "sha") { + if (event.card != evt.card) list.push(get.suit(evt.card)); } }); - player.getHistory('respond',function(evt){ - if(evt.card.name=='sha'){ - if(event.card!=evt.card) list.push(get.suit(evt.card)); + player.getHistory("respond", function (evt) { + if (evt.card.name == "sha") { + if (event.card != evt.card) list.push(get.suit(evt.card)); } }); return !list.includes(get.suit(event.card)); }, - forced:true, - content:function(){ + forced: true, + content: function () { player.draw(); }, }, //李彦 - twzhenhu:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - if(!event.isFirstTarget||!get.tag(event.card,'damage')) return false; - return !player.hasSkillTag('noCompareSource')&&game.hasPlayer(target=>{ - return player.canCompare(target,true); - }); + twzhenhu: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + if (!event.isFirstTarget || !get.tag(event.card, "damage")) return false; + return ( + !player.hasSkillTag("noCompareSource") && + game.hasPlayer((target) => { + return player.canCompare(target, true); + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twzhenhu'),[1,3],function(card,player,target){ - return player.canCompare(target,true); - }).set('ai',function(target){ - var player=_status.event.player,targets=_status.event.getTrigger().targets; - var num=0; - if(player.hasSkill('twlvren')) num+=2*(ui.selected.targets.length+1); - if(player.hasSkill('twchuanshu_effect')) num+=3; - var hs=player.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - if(hs.length==0) return -1; - var ts=target.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - if(Math.min(13,get.number(hs[0])+num)<=get.number(ts[0])) return -1; - return get.effect(target,{name:'guohe_copy2'},player,player)/2+(targets.includes(target)?get.damageEffect(target,player,player):0); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - event.targets=targets; - player.logSkill('twzhenhu',targets); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twzhenhu"), [1, 3], function (card, player, target) { + return player.canCompare(target, true); + }) + .set("ai", function (target) { + var player = _status.event.player, + targets = _status.event.getTrigger().targets; + var num = 0; + if (player.hasSkill("twlvren")) num += 2 * (ui.selected.targets.length + 1); + if (player.hasSkill("twchuanshu_effect")) num += 3; + var hs = player.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + if (hs.length == 0) return -1; + var ts = target.getCards("h").sort((a, b) => get.number(b) - get.number(a)); + if (Math.min(13, get.number(hs[0]) + num) <= get.number(ts[0])) return -1; + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) / 2 + + (targets.includes(target) ? get.damageEffect(target, player, player) : 0) + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + event.targets = targets; + player.logSkill("twzhenhu", targets); player.draw(); - } - else event.finish(); - 'step 2' - player.chooseToCompare(targets,function(card){ - return get.number(card); - }).setContent('chooseToCompareMeanwhile'); - 'step 3' - if(result.winner&&result.winner==player){ + } else event.finish(); + "step 2"; + player + .chooseToCompare(targets, function (card) { + return get.number(card); + }) + .setContent("chooseToCompareMeanwhile"); + "step 3"; + if (result.winner && result.winner == player) { event.targets.remove(result.winner); - player.line(event.targets,trigger.card.nature); - player.addTempSkill('twzhenhu_add'); - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.twzhenhu=event.targets; - } - else player.loseHp(); + player.line(event.targets, trigger.card.nature); + player.addTempSkill("twzhenhu_add"); + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.twzhenhu = event.targets; + } else player.loseHp(); }, - subSkill:{ - add:{ - charlotte:true, - onremove:true, - forced:true, - popup:false, - trigger:{global:'damageBegin1'}, - filter:function(event,player){ - if(!event.card||!event.card.storage) return false; - var targets=event.card.storage.twzhenhu; - return targets&&targets.includes(event.player); + subSkill: { + add: { + charlotte: true, + onremove: true, + forced: true, + popup: false, + trigger: { global: "damageBegin1" }, + filter: function (event, player) { + if (!event.card || !event.card.storage) return false; + var targets = event.card.storage.twzhenhu; + return targets && targets.includes(event.player); }, - content:function(){ + content: function () { trigger.num++; }, }, }, }, - twlvren:{ - audio:2, - trigger:{source:'damageBegin3'}, - filter:function(event,player){ - return event.player!=player&&event.player.isIn()&&!event.player.hasMark('twlvren'); + twlvren: { + audio: 2, + trigger: { source: "damageBegin3" }, + filter: function (event, player) { + return event.player != player && event.player.isIn() && !event.player.hasMark("twlvren"); }, - logTarget:'player', - forced:true, - locked:false, - group:['twlvren_more','twlvren_add'], - content:function(){ - trigger.player.addMark('twlvren',1); + logTarget: "player", + forced: true, + locked: false, + group: ["twlvren_more", "twlvren_add"], + content: function () { + trigger.player.addMark("twlvren", 1); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(target&&target.hasMark('twlvren')) return 0.33; - } - } + ai: { + effect: { + player: function (card, player, target) { + if (target && target.hasMark("twlvren")) return 0.33; + }, + }, }, - marktext:'刃', - intro:{name2:'刃',content:'mark'}, - subSkill:{ - more:{ - audio:'twlvren', - trigger:{player:'useCard2'}, - filter:function(event,player){ - var card=event.card,info=get.info(card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - return get.tag(card,'damage')&&event.targets&&game.hasPlayer(function(target){ - return target.hasMark('twlvren')&&!event.targets.includes(target)&&lib.filter.targetEnabled2(card,player,target); - }); + marktext: "刃", + intro: { name2: "刃", content: "mark" }, + subSkill: { + more: { + audio: "twlvren", + trigger: { player: "useCard2" }, + filter: function (event, player) { + var card = event.card, + info = get.info(card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + return ( + get.tag(card, "damage") && + event.targets && + game.hasPlayer(function (target) { + return ( + target.hasMark("twlvren") && + !event.targets.includes(target) && + lib.filter.targetEnabled2(card, player, target) + ); + }) + ); } return false; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twlvren'),'为'+get.translation(trigger.card)+'额外指定一个有“刃”的角色为目标',function(card,player,target){ - var evt=_status.event.getTrigger(); - return target.hasMark('twlvren')&&!evt.targets.includes(target)&&lib.filter.targetEnabled2(evt.card,player,target); - }).set('ai',function(target){ - return get.effect(target,_status.event.getTrigger().card,_status.event.player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; - player.logSkill('twlvren',targets); - player.line(targets,trigger.card.nature); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twlvren"), + "为" + get.translation(trigger.card) + "额外指定一个有“刃”的角色为目标", + function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target.hasMark("twlvren") && + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) + ); + } + ) + .set("ai", function (target) { + return get.effect( + target, + _status.event.getTrigger().card, + _status.event.player + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; + player.logSkill("twlvren", targets); + player.line(targets, trigger.card.nature); trigger.targets.addArray(targets); - for(var i of targets) i.removeMark('twlvren',i.countMark('twlvren'),false); + for (var i of targets) i.removeMark("twlvren", i.countMark("twlvren"), false); } }, }, - add:{ - audio:'twlvren', - trigger:{player:'compare',target:'compare'}, - filter:function(event,player){ - if(player!=event.target&&event.iwhile) return false; + add: { + audio: "twlvren", + trigger: { player: "compare", target: "compare" }, + filter: function (event, player) { + if (player != event.target && event.iwhile) return false; return true; }, - forced:true, - locked:false, - content:function(){ - var num=2*trigger.lose_list.length; - if(player==trigger.player){ - trigger.num1+=num; - if(trigger.num1>13) trigger.num1=13; + forced: true, + locked: false, + content: function () { + var num = 2 * trigger.lose_list.length; + if (player == trigger.player) { + trigger.num1 += num; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += num; + if (trigger.num2 > 13) trigger.num2 = 13; } - else{ - trigger.num2+=num; - if(trigger.num2>13) trigger.num2=13; - } - game.log(player,'的拼点牌点数+',num); + game.log(player, "的拼点牌点数+", num); }, }, }, }, //童渊 - twchaofeng:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - if(!['sha','shan'].includes(name)) return false; - return player.hasCard(function(card){ - const name2=get.name(card); - return (name2=='sha'||name2=='shan')&&name!=name2; - },'hs'); + twchaofeng: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + if (!["sha", "shan"].includes(name)) return false; + return player.hasCard(function (card) { + const name2 = get.name(card); + return (name2 == "sha" || name2 == "shan") && name != name2; + }, "hs"); }, - filter:function(event,player){ - const names=[]; - if(event.filterCard(get.autoViewAs({name:'sha'},'unsure'),player,event)) names.push('shan'); - if(event.filterCard(get.autoViewAs({name:'shan'},'unsure'),player,event)) names.push('sha'); - return names.length>0&&player.hasCard(function(card){ - return names.includes(get.name(card)); - },'hs'); + filter: function (event, player) { + const names = []; + if (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event)) + names.push("shan"); + if (event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) + names.push("sha"); + return ( + names.length > 0 && + player.hasCard(function (card) { + return names.includes(get.name(card)); + }, "hs") + ); //return false; }, - group:'twchaofeng_compare', - chooseButton:{ - dialog:function(event,player){ - var list=[]; - if(event.filterCard({name:'sha'},player,event)){ - list.push(['基本','','sha']); - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + group: "twchaofeng_compare", + chooseButton: { + dialog: function (event, player) { + var list = []; + if (event.filterCard({ name: "sha" }, player, event)) { + list.push(["基本", "", "sha"]); + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } - if(event.filterCard({name:'shan'},player,event)){ - list.push(['基本','','shan']); + if (event.filterCard({ name: "shan" }, player, event)) { + list.push(["基本", "", "shan"]); } - var dialog=ui.create.dialog('朝凤',[list,'vcard'],'hidden'); - dialog.direct=true; + var dialog = ui.create.dialog("朝凤", [list, "vcard"], "hidden"); + dialog.direct = true; return dialog; }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(_status.event.getParent().type!='phase'||game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch (button.link[2]){ - case 'shan':return 5; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder'||button.link[3]=='ice') return 2.92; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + _status.event.getParent().type != "phase" || + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "shan": + return 5; + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder" || button.link[3] == "ice") + return 2.92; else return 2.9; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'twchaofeng', - name:links[0][2], - filterCard:function(card,player,target){ - if(lib.skill.twchaofeng_backup.name=='sha') return get.name(card)=='shan'; - else return get.name(card)=='sha'; + audio: "twchaofeng", + name: links[0][2], + filterCard: function (card, player, target) { + if (lib.skill.twchaofeng_backup.name == "sha") + return get.name(card) == "shan"; + else return get.name(card) == "sha"; }, - selectCard:1, - check:function(card,player,target){ - return 6-get.value(card); + selectCard: 1, + check: function (card, player, target) { + return 6 - get.value(card); }, - viewAs:{name:links[0][2],nature:links[0][3]}, - position:'hs', - popname:true, - } + viewAs: { name: links[0][2], nature: links[0][3] }, + position: "hs", + popname: true, + }; }, - prompt:function(links,player){ - var view,use; - if(links[0][2]=='sha'){ - use='【闪】'; - view=get.translation(links[0][3]||'')+'【'+get.translation(links[0][2])+'】'; + prompt: function (links, player) { + var view, use; + if (links[0][2] == "sha") { + use = "【闪】"; + view = + get.translation(links[0][3] || "") + + "【" + + get.translation(links[0][2]) + + "】"; + } else { + use = "【杀】"; + view = "【闪】"; } - else{ - use='【杀】'; - view='【闪】'; - } - return '将一张'+use+'当做'+view+(_status.event.name=='chooseToUse'?'使用':'打出'); + return ( + "将一张" + + use + + "当做" + + view + + (_status.event.name == "chooseToUse" ? "使用" : "打出") + ); }, }, - ai:{ - skillTagFilter:function(player,tag){ + ai: { + skillTagFilter: function (player, tag) { var name; - switch (tag){ - case 'respondSha':name='shan'; break; - case 'respondShan':name='sha'; break; + switch (tag) { + case "respondSha": + name = "shan"; + break; + case "respondShan": + name = "sha"; + break; } - if(!player.countCards('hs',name)) return false; + if (!player.countCards("hs", name)) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - var max=0; - if(player.countCards('hs','shan')>0&&lib.inpile_nature.some(i=>player.getUseValue({name:'sha',nature:i})>0)){ - var temp=get.order({name:'sha'}); - if(temp>max) max=temp; + order: function (item, player) { + if (player && _status.event.type == "phase") { + var max = 0; + if ( + player.countCards("hs", "shan") > 0 && + lib.inpile_nature.some( + (i) => player.getUseValue({ name: "sha", nature: i }) > 0 + ) + ) { + var temp = get.order({ name: "sha" }); + if (temp > max) max = temp; } - if(max>0) max+=0.3; + if (max > 0) max += 0.3; return max; } return 4; }, - result:{ - player:1, + result: { + player: 1, }, - respondSha:true, - respondShan:true, - fireAttack:true, + respondSha: true, + respondShan: true, + fireAttack: true, }, - subSkill:{ - compare:{ - audio:'twchaofeng', - trigger:{player:'phaseUseBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twchaofeng'),'选择至多三名角色共同拼点。赢的角色视为对所有没赢的角色使用一张火【杀】',[1,3],(card,player,target)=>{ - return player.canCompare(target); - }).set('ai',function(target){ - var player=_status.event.player,targets=_status.event.getTrigger().targets; - var num=0,card={name:'sha',nature:'fire',isCard:true}; - if(target.hasSkill('twlvren')) num+=2*(ui.selected.targets.length+1); - if(target.hasSkill('twchuanshu_effect')) num+=3; - var hs=player.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - var ts=target.getCards('h').sort((a,b)=>get.number(b)-get.number(a)); - if(get.number(hs[0])<=Math.min(13,get.number(ts[0])+num)){ - return 6+get.effect(player,card,target,target); - } - return get.effect(target,{name:'guohe_copy2'},player,player)/2+get.effect(target,card,player,player); - }); - 'step 1' - if(result.bool){ - event.targets=result.targets; - player.logSkill('twchaofeng_compare',event.targets); - player.chooseToCompare(event.targets).setContent('chooseToCompareMeanwhile'); - } - 'step 2' - if(result.winner){ - var targets=[player].addArray(event.targets).sortBySeat(player); - targets.remove(result.winner); - var card={name:'sha',nature:'fire',isCard:true}; - var targetsx=targets.filter(function(target){ - return result.winner.canUse(card,target,false); + subSkill: { + compare: { + audio: "twchaofeng", + trigger: { player: "phaseUseBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twchaofeng"), + "选择至多三名角色共同拼点。赢的角色视为对所有没赢的角色使用一张火【杀】", + [1, 3], + (card, player, target) => { + return player.canCompare(target); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + targets = _status.event.getTrigger().targets; + var num = 0, + card = { name: "sha", nature: "fire", isCard: true }; + if (target.hasSkill("twlvren")) + num += 2 * (ui.selected.targets.length + 1); + if (target.hasSkill("twchuanshu_effect")) num += 3; + var hs = player + .getCards("h") + .sort((a, b) => get.number(b) - get.number(a)); + var ts = target + .getCards("h") + .sort((a, b) => get.number(b) - get.number(a)); + if (get.number(hs[0]) <= Math.min(13, get.number(ts[0]) + num)) { + return 6 + get.effect(player, card, target, target); + } + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) / 2 + + get.effect(target, card, player, player) + ); }); - if(targetsx.length) result.winner.useCard(card,targetsx,'noai').set('addCount',false); + "step 1"; + if (result.bool) { + event.targets = result.targets; + player.logSkill("twchaofeng_compare", event.targets); + player.chooseToCompare(event.targets).setContent("chooseToCompareMeanwhile"); } - } - } - } + "step 2"; + if (result.winner) { + var targets = [player].addArray(event.targets).sortBySeat(player); + targets.remove(result.winner); + var card = { name: "sha", nature: "fire", isCard: true }; + var targetsx = targets.filter(function (target) { + return result.winner.canUse(card, target, false); + }); + if (targetsx.length) + result.winner.useCard(card, targetsx, "noai").set("addCount", false); + } + }, + }, + }, }, - twchuanshu:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - limited:true, - skillAnimation:true, - animationColor:'qun', - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twchuanshu')).set('ai',target=>get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - player.awakenSkill('twchuanshu'); - var target=result.targets[0]; - player.logSkill('twchuanshu',target); - target.addMark('twchuanshu_mark',1,false); - target.addSkill('twchuanshu_effect'); - target.markAuto('twchuanshu_effect',[player]); - player.addSkill('twchuanshu_clear'); - player.markAuto('twchuanshu_clear',[target]); + twchuanshu: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + limited: true, + skillAnimation: true, + animationColor: "qun", + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twchuanshu")) + .set("ai", (target) => get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + player.awakenSkill("twchuanshu"); + var target = result.targets[0]; + player.logSkill("twchuanshu", target); + target.addMark("twchuanshu_mark", 1, false); + target.addSkill("twchuanshu_effect"); + target.markAuto("twchuanshu_effect", [player]); + player.addSkill("twchuanshu_clear"); + player.markAuto("twchuanshu_clear", [target]); } }, - subSkill:{ - mark:{ - charlotte:true, + subSkill: { + mark: { + charlotte: true, }, - effect:{ - audio:'twchuanshu', - trigger:{ - player:'compare', - target:'compare', + effect: { + audio: "twchuanshu", + trigger: { + player: "compare", + target: "compare", }, - direct:true, - forced:true, - charlotte:true, - nopop:true, - mark:true, - intro:{ - content:function(storage,player){ - var shisyou=player.getStorage('twchuanshu_effect').filter(i=>i.isIn()); - var str='
            • 拼点牌点数+3;' - if(player.hasMark('twchuanshu_mark')){ - str+='
            • 使用的下一张【杀】对除'+get.translation(shisyou)+'外的角色造成伤害时,此伤害+'+player.countMark('twchuanshu_mark')+';'; - if(!shisyou.includes(player)){ - str+='
            • 使用的下一张【杀】结算结束后,'+get.translation(shisyou)+'摸等同于伤害值的牌;'; + direct: true, + forced: true, + charlotte: true, + nopop: true, + mark: true, + intro: { + content: function (storage, player) { + var shisyou = player.getStorage("twchuanshu_effect").filter((i) => i.isIn()); + var str = "
            • 拼点牌点数+3;"; + if (player.hasMark("twchuanshu_mark")) { + str += + "
            • 使用的下一张【杀】对除" + + get.translation(shisyou) + + "外的角色造成伤害时,此伤害+" + + player.countMark("twchuanshu_mark") + + ";"; + if (!shisyou.includes(player)) { + str += + "
            • 使用的下一张【杀】结算结束后," + + get.translation(shisyou) + + "摸等同于伤害值的牌;"; } } - str=str.slice(0,-1)+'。'; + str = str.slice(0, -1) + "。"; return str; - } + }, }, - filter:function(event,player,name){ - if(event.player==player&&event.iwhile>0) return false; - return (player==event.player?event.num1:event.num2)<13; + filter: function (event, player, name) { + if (event.player == player && event.iwhile > 0) return false; + return (player == event.player ? event.num1 : event.num2) < 13; }, - content:function(){ - game.log(player,'的拼点牌点数+3'); - if(player==trigger.player) trigger.num1=Math.min(13,trigger.num1+3); - else trigger.num2=Math.min(13,trigger.num2+3); + content: function () { + game.log(player, "的拼点牌点数+3"); + if (player == trigger.player) trigger.num1 = Math.min(13, trigger.num1 + 3); + else trigger.num2 = Math.min(13, trigger.num2 + 3); }, - group:'twchuanshu_damage', + group: "twchuanshu_damage", }, - damage:{ - charlotte:true, - trigger:{player:['useCard','useCardAfter'],source:'damageBegin1'}, - filter:function(event,player,name){ - if(name=='useCard') return (event.card.name=='sha'&&player.hasMark('twchuanshu_mark')); - if(name=='damageBegin1') return event.card&&event.card.twchuanshu_mark&&!player.getStorage('twchuanshu_effect').includes(event.player); - return event.card.twchuanshu_mark&&player.hasHistory('sourceDamage',function(evt){ - return evt.card==event.card; - })&&player.getStorage('twchuanshu_effect').filter(function(target){ - return target.isIn()&&target!=player; - }).length; + damage: { + charlotte: true, + trigger: { player: ["useCard", "useCardAfter"], source: "damageBegin1" }, + filter: function (event, player, name) { + if (name == "useCard") + return event.card.name == "sha" && player.hasMark("twchuanshu_mark"); + if (name == "damageBegin1") + return ( + event.card && + event.card.twchuanshu_mark && + !player.getStorage("twchuanshu_effect").includes(event.player) + ); + return ( + event.card.twchuanshu_mark && + player.hasHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }) && + player.getStorage("twchuanshu_effect").filter(function (target) { + return target.isIn() && target != player; + }).length + ); }, - forced:true, - content:function(){ - var name=event.triggername; - if(name=='useCard'){ - var num=player.countMark('twchuanshu_mark'); - trigger.card.twchuanshu_mark=num; - player.removeMark('twchuanshu_mark',num,false); - } - else if(name=='damageBegin1') trigger.num++; - else{ - var num1=trigger.card.twchuanshu_mark; - var num2=0; - player.getHistory('sourceDamage',function(evt){ - if(evt.card==trigger.card) num2+=evt.num; + forced: true, + content: function () { + var name = event.triggername; + if (name == "useCard") { + var num = player.countMark("twchuanshu_mark"); + trigger.card.twchuanshu_mark = num; + player.removeMark("twchuanshu_mark", num, false); + } else if (name == "damageBegin1") trigger.num++; + else { + var num1 = trigger.card.twchuanshu_mark; + var num2 = 0; + player.getHistory("sourceDamage", function (evt) { + if (evt.card == trigger.card) num2 += evt.num; }); - var targets=player.getStorage('twchuanshu_effect').filter(function(target){ - return target.isIn()&&target!=player; - }); - if(targets.length==1) targets[0].draw(num1*num2); - else game.asyncDraw(targets,num1*num2); + var targets = player + .getStorage("twchuanshu_effect") + .filter(function (target) { + return target.isIn() && target != player; + }); + if (targets.length == 1) targets[0].draw(num1 * num2); + else game.asyncDraw(targets, num1 * num2); } }, }, - clear:{ - charlotte:true, - onremove:true, - trigger:{player:'phaseBegin'}, - filter:function(event,player){ - return player.getStorage('twchuanshu_clear').length; + clear: { + charlotte: true, + onremove: true, + trigger: { player: "phaseBegin" }, + filter: function (event, player) { + return player.getStorage("twchuanshu_clear").length; }, - forced:true, - silent:true, - content:function(){ - 'step 0' - var targets=player.getStorage('twchuanshu_clear'); - for(var target of targets){ - target.unmarkAuto('twchuanshu_effect',[player]); - if(!target.getStorage('twchuanshu_effect').length) target.removeSkill('twchuanshu_effect'); + forced: true, + silent: true, + content: function () { + "step 0"; + var targets = player.getStorage("twchuanshu_clear"); + for (var target of targets) { + target.unmarkAuto("twchuanshu_effect", [player]); + if (!target.getStorage("twchuanshu_effect").length) + target.removeSkill("twchuanshu_effect"); } - 'step 1' - player.removeSkill('twchuanshu_clear'); + "step 1"; + player.removeSkill("twchuanshu_clear"); }, }, }, }, //徐庶 - twjiange:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filterCard:function(card,player){ - return get.type(card)!='basic'; + twjiange: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + filterCard: function (card, player) { + return get.type(card) != "basic"; }, - usable:1, - locked:false, - viewAs:{name:'sha',storage:{twjiange:true}}, - viewAsFilter:function(player){ - if(!player.countCards('hes',function(card){ - return get.type(card)!='basic'; - })) return false; + usable: 1, + locked: false, + viewAs: { name: "sha", storage: { twjiange: true } }, + viewAsFilter: function (player) { + if ( + !player.countCards("hes", function (card) { + return get.type(card) != "basic"; + }) + ) + return false; }, - position:'hes', - selectCard:function(){ - return _status.event.skill=='twjiange'?1:Infinity; + position: "hes", + selectCard: function () { + return _status.event.skill == "twjiange" ? 1 : Infinity; }, - precontent:function(){ - if(player!=_status.currentPhase){ - player.when({player:['useCard','respond']}) - .filter(evt=>evt.skill=='twjiange') - .then(()=>player.draw()); + precontent: function () { + if (player != _status.currentPhase) { + player + .when({ player: ["useCard", "respond"] }) + .filter((evt) => evt.skill == "twjiange") + .then(() => player.draw()); } - event.getParent().addCount=false; + event.getParent().addCount = false; }, - prompt:'将一张非基本牌当杀使用或打出', - check:function(card){ - var val=get.value(card); - if(_status.event.name=='chooseToRespond') return 1/Math.max(0.1,val); - return 6-val; + prompt: "将一张非基本牌当杀使用或打出", + check: function (card) { + var val = get.value(card); + if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val); + return 6 - val; }, - ai:{ - order:function(item,player){ - var target=_status.currentPhase; - if(!target||target!=player) return 7; + ai: { + order: function (item, player) { + var target = _status.currentPhase; + if (!target || target != player) return 7; return 1; }, - respondSha:true, - skillTagFilter:function(player){ - if(!player.countCards('hes',function(card){ - return get.type(card)!='basic'; - })) return false; + respondSha: true, + skillTagFilter: function (player) { + if ( + !player.countCards("hes", function (card) { + return get.type(card) != "basic"; + }) + ) + return false; }, }, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.twjiange) return true; + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.twjiange) return true; }, - cardUsable:function(card,player,num){ - if(card.storage&&card.storage.twjiange) return Infinity; + cardUsable: function (card, player, num) { + if (card.storage && card.storage.twjiange) return Infinity; }, - } + }, }, - twxiawang:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - if(!event.source||get.distance(player,event.player)>1||!player.canUse('sha',event.source,false,false)) return false; - return player.countCards('h')>0; + twxiawang: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + if ( + !event.source || + get.distance(player, event.player) > 1 || + !player.canUse("sha", event.source, false, false) + ) + return false; + return player.countCards("h") > 0; }, - direct:true, - content:function(){ - player.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'侠望:是否对'+get.translation(trigger.source)+'使用一张杀?').set('logSkill','twxiawang').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',trigger.source); - player.addTempSkill('twxiawang_damage'); + direct: true, + content: function () { + player + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "侠望:是否对" + get.translation(trigger.source) + "使用一张杀?") + .set("logSkill", "twxiawang") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", trigger.source); + player.addTempSkill("twxiawang_damage"); }, - subSkill:{ - damage:{ - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.getParent(2).name!='twxiawang') return false; - if(!player.hasHistory('sourceDamage',evt=>evt.card==event.card)) return false; - for(var phase of lib.phaseName){ - var evt=event.getParent(phase); - if(evt&&evt.name==phase) return true; + subSkill: { + damage: { + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.getParent(2).name != "twxiawang") return false; + if (!player.hasHistory("sourceDamage", (evt) => evt.card == event.card)) + return false; + for (var phase of lib.phaseName) { + var evt = event.getParent(phase); + if (evt && evt.name == phase) return true; } return false; }, - content:function(){ - player.popup() - player.removeSkill('twjiange_damage'); - for(var phase of lib.phaseName){ - var evt=event.getParent(phase); - if(evt&&evt.name==phase){ - var name=['准备','判定','摸牌','出牌','弃牌','结束'][lib.phaseName.indexOf(phase)]; - game.log(player,'令',_status.currentPhase,'结束了'+name+'阶段'); - player.line(_status.currentPhase,'thunder'); - evt.skipped=true; + content: function () { + player.popup(); + player.removeSkill("twjiange_damage"); + for (var phase of lib.phaseName) { + var evt = event.getParent(phase); + if (evt && evt.name == phase) { + var name = ["准备", "判定", "摸牌", "出牌", "弃牌", "结束"][ + lib.phaseName.indexOf(phase) + ]; + game.log(player, "令", _status.currentPhase, "结束了" + name + "阶段"); + player.line(_status.currentPhase, "thunder"); + evt.skipped = true; } } - } - } + }, + }, }, }, //好萌 - twgongge:{ - audio:3, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget||!event.targets) return false; - return get.tag(event.card,'damage'); + twgongge: { + audio: 3, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget || !event.targets) return false; + return get.tag(event.card, "damage"); }, - direct:true, - usable:1, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twgongge'),function(card,player,target){ - var trigger=_status.event.getTrigger(); - return trigger.targets.includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - var att=get.attitude(player,target); - var damageNum=trigger.getParent().baseDamage; - var map=trigger.getParent().customArgs,id=target.playerid; - if(map[id]){ - if(typeof map[id].baseDamage=='number') damageNum=map[id].baseDamage; - if(typeof map[id].extraDamage=='number') damageNum+=map[id].extraDamage; - } - if(target.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:trigger.card, - })) damageNum=1; - var num=target.getSkills(null,false,false).filter(function(skill){ - var info=get.info(skill); - return info&&!info.charlotte; - }).length+1; - var list=[0,0,0]; - var player=_status.event.player; - list[0]=num; - list[1]=(get.effect(target,{name:'guohe_copy2'},player,player)>0?((target.hp-damageNumget.damageEffect(target,player,player)?(Math.min(num-1,target.getDamagedHp())):(num-1))*2; - return Math.max.apply(Math,list); - }).set('yimie',function(trigger,player,target,damageNum){ - var hit=true; - var att=get.attitude(player,target); - if(get.type(trigger.card)=='trick'&&trigger.player.countCards('hs',{name:'wuxie'})) hit=false; - if(trigger.card.name=='huogong'&&trigger.player.countCards('h',function(card){ - var list=[]; - for(var i of player.getCards('h')) list.push(get.suit(i)); - return !list.includes(get.suit(card)); - })) hit=false; - var key; - switch (trigger.card.name){ - case 'sha':case 'wanjian':key=['shan']; break; - case 'juedou':case 'nanman':case 'jiedao':key=['sha']; break; - default:key=[]; break; - } - if(get.type(trigger.card)=='trick') key.push('wuxie'); - key.push('caochuan'); - var bool1=((get.recoverEffect(target,player,player)>0)?1:-1); - var bool2=(((att>0&&!hit)||(target.countCards('hs',{name:key})&&!trigger.getParent().directHit.includes(target)))?1:-1); - if(att<=0&&target.hp-damageNum>0) return false; - return bool1=bool2&&att!=0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twgongge',target); - var num=target.getSkills(null,false,false).filter(function(skill){ - var info=get.info(skill); - return info&&!info.charlotte; - }).length+1; - event.num=num; - var list=[]; - var choiceList=[ - '摸'+get.cnNumber(num)+'张牌,若'+get.translation(target)+'响应此牌,则你跳过下个摸牌阶段', - '弃置'+get.translation(target)+get.cnNumber(num)+'张牌,此牌结算完毕后,若'+get.translation(target)+'的体力值不小于你,你交给'+get.translation(target)+get.cnNumber(num-1)+'张牌', - '令此牌对'+get.translation(target)+'造成的伤害+'+(num-1)+',此伤害结算完成后,其回复等量的体力值' - ]; - list.push('摸牌'); - if(target.countDiscardableCards(player,'he')) list.push('拆牌'); - else choiceList[1]=''+choiceList[1]+''; - list.push('加伤'); - player.chooseControl(list).set('prompt','攻阁:请选择一项('+get.translation(target)+'对应X值:'+(num-1)+')').set('ai',()=>_status.event.choice).set('choice',function(){ - var att=get.attitude(player,target); - var damageNum=trigger.getParent().baseDamage; - var map=trigger.getParent().customArgs,id=target.playerid; - if(map[id]){ - if(typeof map[id].baseDamage=='number') damageNum=map[id].baseDamage; - if(typeof map[id].extraDamage=='number') damageNum+=map[id].extraDamage; + direct: true, + usable: 1, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twgongge"), function (card, player, target) { + var trigger = _status.event.getTrigger(); + return trigger.targets.includes(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + var att = get.attitude(player, target); + var damageNum = trigger.getParent().baseDamage; + var map = trigger.getParent().customArgs, + id = target.playerid; + if (map[id]) { + if (typeof map[id].baseDamage == "number") damageNum = map[id].baseDamage; + if (typeof map[id].extraDamage == "number") damageNum += map[id].extraDamage; } - if(target.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:trigger.card, - })) damageNum=1; - var yimie=function(){ - if(damageNum==1) return false; - var hit=true; - if(get.type(trigger.card)=='trick'&&trigger.player.countCards('hs',{name:'wuxie'})) hit=false; - if(trigger.card.name=='huogong'&&trigger.player.countCards('h',function(card){ - var list=[]; - for(var i of player.getCards('h')) list.push(get.suit(i)); + if ( + target.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: trigger.card, + }) + ) + damageNum = 1; + var num = + target.getSkills(null, false, false).filter(function (skill) { + var info = get.info(skill); + return info && !info.charlotte; + }).length + 1; + var list = [0, 0, 0]; + var player = _status.event.player; + list[0] = num; + list[1] = + get.effect(target, { name: "guohe_copy2" }, player, player) > 0 + ? target.hp - damageNum < player.hp + ? num + : num - Math.min(player.getCards("he"), num - 1) + : 0; + if (_status.event.yimie(trigger, player, target, damageNum)) + list[2] = + (get.recoverEffect(target, player, player) > + get.damageEffect(target, player, player) + ? Math.min(num - 1, target.getDamagedHp()) + : num - 1) * 2; + return Math.max.apply(Math, list); + }) + .set("yimie", function (trigger, player, target, damageNum) { + var hit = true; + var att = get.attitude(player, target); + if ( + get.type(trigger.card) == "trick" && + trigger.player.countCards("hs", { name: "wuxie" }) + ) + hit = false; + if ( + trigger.card.name == "huogong" && + trigger.player.countCards("h", function (card) { + var list = []; + for (var i of player.getCards("h")) list.push(get.suit(i)); return !list.includes(get.suit(card)); - })) hit=false; - var key; - switch (trigger.card.name){ - case 'sha':case 'wanjian':key=['shan']; break; - case 'juedou':case 'nanman':case 'jiedao':key=['sha']; break; - default:key=[]; break; - } - key.push('caochuan'); - var bool1=((get.recoverEffect(target,player,player)>0)?1:-1); - var bool2=(((att>0&&!hit)||(target.countCards('hs',{name:key})&&!trigger.getParent().directHit.includes(target)))?1:-1); - if(att<=0&&target.hp-damageNum>0) return false; - return bool1=bool2&&att!=0; - }; - if(yimie()) return '加伤'; - if(list.includes('拆牌')&&get.effect(target,{name:'guohe_copy2'},player,player)>0&&target.hp-damageNum 0 ? 1 : -1; + var bool2 = + (att > 0 && !hit) || + (target.countCards("hs", { name: key }) && + !trigger.getParent().directHit.includes(target)) + ? 1 + : -1; + if (att <= 0 && target.hp - damageNum > 0) return false; + return (bool1 = bool2 && att != 0); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twgongge", target); + var num = + target.getSkills(null, false, false).filter(function (skill) { + var info = get.info(skill); + return info && !info.charlotte; + }).length + 1; + event.num = num; + var list = []; + var choiceList = [ + "摸" + + get.cnNumber(num) + + "张牌,若" + + get.translation(target) + + "响应此牌,则你跳过下个摸牌阶段", + "弃置" + + get.translation(target) + + get.cnNumber(num) + + "张牌,此牌结算完毕后,若" + + get.translation(target) + + "的体力值不小于你,你交给" + + get.translation(target) + + get.cnNumber(num - 1) + + "张牌", + "令此牌对" + + get.translation(target) + + "造成的伤害+" + + (num - 1) + + ",此伤害结算完成后,其回复等量的体力值", + ]; + list.push("摸牌"); + if (target.countDiscardableCards(player, "he")) list.push("拆牌"); + else choiceList[1] = '' + choiceList[1] + ""; + list.push("加伤"); + player + .chooseControl(list) + .set( + "prompt", + "攻阁:请选择一项(" + + get.translation(target) + + "对应X值:" + + (num - 1) + + ")" + ) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + var att = get.attitude(player, target); + var damageNum = trigger.getParent().baseDamage; + var map = trigger.getParent().customArgs, + id = target.playerid; + if (map[id]) { + if (typeof map[id].baseDamage == "number") + damageNum = map[id].baseDamage; + if (typeof map[id].extraDamage == "number") + damageNum += map[id].extraDamage; + } + if ( + target.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: trigger.card, + }) + ) + damageNum = 1; + var yimie = function () { + if (damageNum == 1) return false; + var hit = true; + if ( + get.type(trigger.card) == "trick" && + trigger.player.countCards("hs", { name: "wuxie" }) + ) + hit = false; + if ( + trigger.card.name == "huogong" && + trigger.player.countCards("h", function (card) { + var list = []; + for (var i of player.getCards("h")) list.push(get.suit(i)); + return !list.includes(get.suit(card)); + }) + ) + hit = false; + var key; + switch (trigger.card.name) { + case "sha": + case "wanjian": + key = ["shan"]; + break; + case "juedou": + case "nanman": + case "jiedao": + key = ["sha"]; + break; + default: + key = []; + break; + } + key.push("caochuan"); + var bool1 = get.recoverEffect(target, player, player) > 0 ? 1 : -1; + var bool2 = + (att > 0 && !hit) || + (target.countCards("hs", { name: key }) && + !trigger.getParent().directHit.includes(target)) + ? 1 + : -1; + if (att <= 0 && target.hp - damageNum > 0) return false; + return (bool1 = bool2 && att != 0); + }; + if (yimie()) return "加伤"; + if ( + list.includes("拆牌") && + get.effect(target, { name: "guohe_copy2" }, player, player) > 0 && + target.hp - damageNum < player.hp + ) + return "拆牌"; + return "摸牌"; + })() + ) + .set("choiceList", choiceList); + } else { player.storage.counttrigger.twgongge--; event.finish(); } - 'step 2' - game.log(player,'选择了','#y'+result.control); - switch(result.control){ - case '摸牌': + "step 2"; + game.log(player, "选择了", "#y" + result.control); + switch (result.control) { + case "摸牌": player.draw(num); - player.addTempSkill('twgongge_buff1'); - var evt={ - card:trigger.card, - target:target, + player.addTempSkill("twgongge_buff1"); + var evt = { + card: trigger.card, + target: target, }; - player.storage.twgongge_buff1=evt; + player.storage.twgongge_buff1 = evt; break; - case '拆牌': - player.discardPlayerCard(num,target,'he',true); - player.addTempSkill('twgongge_buff2'); - var evt={ - card:trigger.card, - target:target, - num:num-1, + case "拆牌": + player.discardPlayerCard(num, target, "he", true); + player.addTempSkill("twgongge_buff2"); + var evt = { + card: trigger.card, + target: target, + num: num - 1, }; - player.storage.twgongge_buff2=evt; + player.storage.twgongge_buff2 = evt; break; - case '加伤': - player.addTempSkill('twgongge_buff3'); - var evt={ - card:trigger.card, - target:target, - num:num-1, + case "加伤": + player.addTempSkill("twgongge_buff3"); + var evt = { + card: trigger.card, + target: target, + num: num - 1, }; - player.storage.twgongge_buff3=evt; + player.storage.twgongge_buff3 = evt; break; } }, - subSkill:{ + subSkill: { //摸牌后续 - buff1:{ - charlotte:true, - onremove:true, - trigger:{global:['useCard','respond']}, - filter:function(event,player){ - if(player.skipList.includes('phaseDraw')) return false; - if(!Array.isArray(event.respondTo)||player!=event.respondTo[0]) return false; - var evt=player.storage.twgongge_buff1; - if(evt.target==event.player&&evt.card==event.respondTo[1]) return true; + buff1: { + charlotte: true, + onremove: true, + trigger: { global: ["useCard", "respond"] }, + filter: function (event, player) { + if (player.skipList.includes("phaseDraw")) return false; + if (!Array.isArray(event.respondTo) || player != event.respondTo[0]) return false; + var evt = player.storage.twgongge_buff1; + if (evt.target == event.player && evt.card == event.respondTo[1]) return true; return false; }, - direct:true, - popup:false, - content:function(){ - player.skip('phaseDraw'); - game.log(player,'跳过了下个','#g摸牌阶段'); - player.addTempSkill('twgongge_buff1_mark','phaseDrawSkipped'); + direct: true, + popup: false, + content: function () { + player.skip("phaseDraw"); + game.log(player, "跳过了下个", "#g摸牌阶段"); + player.addTempSkill("twgongge_buff1_mark", "phaseDrawSkipped"); }, }, //拆牌后续 - buff2:{ - charlotte:true, - onremove:true, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(!player.countCards('he')) return false; - var evt=player.storage.twgongge_buff2; - if(evt.card==event.card&&evt.target.isIn()&&evt.target.hp>=player.hp) return true; + buff2: { + charlotte: true, + onremove: true, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if (!player.countCards("he")) return false; + var evt = player.storage.twgongge_buff2; + if (evt.card == event.card && evt.target.isIn() && evt.target.hp >= player.hp) + return true; return false; }, - direct:true, - popup:false, - content:function(){ - 'step 0' - var evt=player.storage.twgongge_buff2; - var target=evt.target,num=evt.num; - event.target=target; - if(player.countCards('he')<=num) event._result={bool:true,cards:player.getCards('he')}; - else player.chooseCard('he',num,'攻阁:交给'+get.translation(target)+get.cnNumber(num)+'张牌',true); - 'step 1' - if(result.bool) player.give(result.cards,target); + direct: true, + popup: false, + content: function () { + "step 0"; + var evt = player.storage.twgongge_buff2; + var target = evt.target, + num = evt.num; + event.target = target; + if (player.countCards("he") <= num) + event._result = { bool: true, cards: player.getCards("he") }; + else + player.chooseCard( + "he", + num, + "攻阁:交给" + get.translation(target) + get.cnNumber(num) + "张牌", + true + ); + "step 1"; + if (result.bool) player.give(result.cards, target); }, }, //加伤后续 - buff3:{ - charlotte:true, - onremove:true, - trigger:{source:'damageBegin1',player:'useCardAfter'}, - filter:function(event,player){ - if(!event.card) return false; - var evt=player.storage.twgongge_buff3; - if(evt.card==event.card&&evt.target.isIn()&&(event.name=='useCard'||event.player==evt.target)) return true; + buff3: { + charlotte: true, + onremove: true, + trigger: { source: "damageBegin1", player: "useCardAfter" }, + filter: function (event, player) { + if (!event.card) return false; + var evt = player.storage.twgongge_buff3; + if ( + evt.card == event.card && + evt.target.isIn() && + (event.name == "useCard" || event.player == evt.target) + ) + return true; return false; }, - direct:true, - popup:false, - content:function(){ - var evt=player.storage.twgongge_buff3; - if(trigger.name=='damage') trigger.num+=evt.num; - else if(evt.target.isIn()) evt.target.recover(evt.num); + direct: true, + popup: false, + content: function () { + var evt = player.storage.twgongge_buff3; + if (trigger.name == "damage") trigger.num += evt.num; + else if (evt.target.isIn()) evt.target.recover(evt.num); }, }, - buff1_mark:{ - mark:true, - intro:{ - content:'跳过下一个摸牌阶段', + buff1_mark: { + mark: true, + intro: { + content: "跳过下一个摸牌阶段", }, - } + }, }, }, //魏续 - twsuizheng:{ - audio:3, - trigger:{global:'phaseBefore',player:'enterGame'}, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); + twsuizheng: { + audio: 3, + trigger: { global: "phaseBefore", player: "enterGame" }, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); }, - forced:true, - content:function(){ - 'step 0' - player.chooseTarget('请选择【随征】的目标',lib.translate.twsuizheng_info,lib.filter.notMe,true).set('ai',function(target){ - var player=_status.event.player; - return Math.max(1+get.attitude(player,target)*get.threaten(target),Math.random()); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; + forced: true, + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【随征】的目标", + lib.translate.twsuizheng_info, + lib.filter.notMe, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return Math.max( + 1 + get.attitude(player, target) * get.threaten(target), + Math.random() + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - game.log(player,'选择了',target,'作为','“随征”角色'); - player.markAuto('twsuizheng',[target]); - player.addSkill('twsuizheng_draw'); - player.addSkill('twsuizheng_xianfu'); + game.log(player, "选择了", target, "作为", "“随征”角色"); + player.markAuto("twsuizheng", [target]); + player.addSkill("twsuizheng_draw"); + player.addSkill("twsuizheng_xianfu"); } }, - ai:{expose:0.3}, - intro:{content:'已选择$为“随征”角色'}, - subSkill:{ - draw:{ - charlotte:true, - audio:'twsuizheng', - trigger:{global:'damageSource'}, - filter:function(event,player){ - return player.getStorage('twsuizheng').includes(event.source); + ai: { expose: 0.3 }, + intro: { content: "已选择$为“随征”角色" }, + subSkill: { + draw: { + charlotte: true, + audio: "twsuizheng", + trigger: { global: "damageSource" }, + filter: function (event, player) { + return player.getStorage("twsuizheng").includes(event.source); }, - forced:true, - logTarget:'source', - content:function(){ + forced: true, + logTarget: "source", + content: function () { player.draw(); }, }, - xianfu:{ - audio:'twsuizheng', - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return player.getStorage('twsuizheng').includes(event.player)&&event.player.isIn(); + xianfu: { + audio: "twsuizheng", + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return ( + player.getStorage("twsuizheng").includes(event.player) && event.player.isIn() + ); }, - forced:true, - charlotte:true, - logTarget:'player', - content:function(){ - 'step 0' - player.chooseToDiscard(2,'随征:弃置两张基本牌','若你弃牌,你令'+get.translation(trigger.player)+'回复1点体力;或点击“取消”失去1点体力,令'+get.translation(trigger.player)+'获得一张【杀】或【决斗】',{type:'basic'}).set('ai',function(card){ - if(_status.event.refuse) return -1; - return 6-get.value(card); - }).set('refuse',get.attitude(player,trigger.player)<=0||get.effect(player,{name:'losehp'})>=0); - 'step 1' - if(result.bool) trigger.player.recover(); + forced: true, + charlotte: true, + logTarget: "player", + content: function () { + "step 0"; + player + .chooseToDiscard( + 2, + "随征:弃置两张基本牌", + "若你弃牌,你令" + + get.translation(trigger.player) + + "回复1点体力;或点击“取消”失去1点体力,令" + + get.translation(trigger.player) + + "获得一张【杀】或【决斗】", + { type: "basic" } + ) + .set("ai", function (card) { + if (_status.event.refuse) return -1; + return 6 - get.value(card); + }) + .set( + "refuse", + get.attitude(player, trigger.player) <= 0 || + get.effect(player, { name: "losehp" }) >= 0 + ); + "step 1"; + if (result.bool) trigger.player.recover(); else { player.loseHp(); - var card=get.cardPile(function(card){ - return card.name=='sha'||card.name=='juedou'; + var card = get.cardPile(function (card) { + return card.name == "sha" || card.name == "juedou"; }); - if(card) trigger.player.gain(card,'gain2'); + if (card) trigger.player.gain(card, "gain2"); } }, }, }, }, - twtuidao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - var targets=player.getStorage('twsuizheng'); - if(!targets.length) return false; - return targets.some(target=>target.hp<=2||!target.isIn()); + twtuidao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + var targets = player.getStorage("twsuizheng"); + if (!targets.length) return false; + return targets.some((target) => target.hp <= 2 || !target.isIn()); }, - check:function(event,player){ - var targets=player.getStorage('twsuizheng'); - var val=0; - for(var target of targets){ - if(target.hp<=2&&target.isIn()) val-=get.attitude(player,target); - else if(!target.isIn()) val+=6; + check: function (event, player) { + var targets = player.getStorage("twsuizheng"); + var val = 0; + for (var target of targets) { + if (target.hp <= 2 && target.isIn()) val -= get.attitude(player, target); + else if (!target.isIn()) val += 6; } - return val>0; + return val > 0; }, - limited:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.awakenSkill('twtuidao'); - var list1=['equip3','equip4'].map(i=>get.translation(i)),list2=['basic','trick','equip'].map(i=>get.translation(i)); - var targets=player.getStorage('twsuizheng'),str=get.translation(targets); - if(targets.length) str='与'+str; - player.chooseButton(2,true,[ - '颓盗:废除你'+str+'的一个坐骑栏废除并选择一个类别', - '坐骑栏', - [list1,'tdnodes'], - '类别', - [list2,'tdnodes'], - ]).set('filterButton',function(button){ - var list=_status.event.list,link=button.link; - if(ui.selected.buttons.length){ - if(list.includes(ui.selected.buttons[0].link)&&list.includes(link)) return false; - if(!list.includes(ui.selected.buttons[0].link)&&!list.includes(link)) return false; - } - return true; - }).set('ai',function(button){ - var player=_status.event.player; - var list=_status.event.list,link=button.link; - if(list.includes(link)){ - if(player.hasDisabledSlot(4)) return '攻击马'; - if(player.hasDisabledSlot(3)) return '防御马'; - return '攻击马'; - } - if(!list.includes(link)){ - var player=_status.event.player; - var targets=player.getStorage('twsuizheng'); - for(var target of targets){ - if(target.isIn()){ - var listx=[0,0,0],list2=['basic','trick','equip'].map(i=>get.translation(i)); - for(var i of target.getCards('he')) listx[list2.indexOf(get.translation(get.type2(i)))]++; - return list2[listx.indexOf(Math.max.apply(Math,listx))]; - } + limited: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player.awakenSkill("twtuidao"); + var list1 = ["equip3", "equip4"].map((i) => get.translation(i)), + list2 = ["basic", "trick", "equip"].map((i) => get.translation(i)); + var targets = player.getStorage("twsuizheng"), + str = get.translation(targets); + if (targets.length) str = "与" + str; + player + .chooseButton(2, true, [ + "颓盗:废除你" + str + "的一个坐骑栏废除并选择一个类别", + "坐骑栏", + [list1, "tdnodes"], + "类别", + [list2, "tdnodes"], + ]) + .set("filterButton", function (button) { + var list = _status.event.list, + link = button.link; + if (ui.selected.buttons.length) { + if (list.includes(ui.selected.buttons[0].link) && list.includes(link)) + return false; + if (!list.includes(ui.selected.buttons[0].link) && !list.includes(link)) + return false; } - return 1+Math.random(); - } - }).set('list',list1); - 'step 1' - if(result.links[0].indexOf('马')==-1) result.links.reverse(); - var subtype=result.links[0]=='防御马'?'equip3':'equip4',type={基本:'basic',锦囊:'trick',装备:'equip'}[result.links[1]]; + return true; + }) + .set("ai", function (button) { + var player = _status.event.player; + var list = _status.event.list, + link = button.link; + if (list.includes(link)) { + if (player.hasDisabledSlot(4)) return "攻击马"; + if (player.hasDisabledSlot(3)) return "防御马"; + return "攻击马"; + } + if (!list.includes(link)) { + var player = _status.event.player; + var targets = player.getStorage("twsuizheng"); + for (var target of targets) { + if (target.isIn()) { + var listx = [0, 0, 0], + list2 = ["basic", "trick", "equip"].map((i) => + get.translation(i) + ); + for (var i of target.getCards("he")) + listx[list2.indexOf(get.translation(get.type2(i)))]++; + return list2[listx.indexOf(Math.max.apply(Math, listx))]; + } + } + return 1 + Math.random(); + } + }) + .set("list", list1); + "step 1"; + if (result.links[0].indexOf("马") == -1) result.links.reverse(); + var subtype = result.links[0] == "防御马" ? "equip3" : "equip4", + type = { 基本: "basic", 锦囊: "trick", 装备: "equip" }[result.links[1]]; player.disableEquip(subtype); - var targets=player.getStorage('twsuizheng') - for(var target of targets){ - if(target&&target.isIn()){ + var targets = player.getStorage("twsuizheng"); + for (var target of targets) { + if (target && target.isIn()) { target.disableEquip(subtype); - var cards=target.getCards('he',card=>get.type2(card)==type); - player.gain(cards,target,'give'); - event.gainners=cards; - } - else{ - var cards=[]; - for(var i=1; i<=2; i++){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&get.type2(card)==type; + var cards = target.getCards("he", (card) => get.type2(card) == type); + player.gain(cards, target, "give"); + event.gainners = cards; + } else { + var cards = []; + for (var i = 1; i <= 2; i++) { + var card = get.cardPile2(function (card) { + return !cards.includes(card) && get.type2(card) == type; }); - if(card) cards.push(card); + if (card) cards.push(card); else break; } - player.gain(cards,'gain2'); - event.gainners=cards; + player.gain(cards, "gain2"); + event.gainners = cards; } } - 'step 2' - player.chooseTarget('请重新选择【随征】目标',true,function(card,player,target){ - return !player.getStorage('twsuizheng').includes(target); - }).set('ai',function(target){ - var player=_status.event.player; - return Math.max(1+get.attitude(player,target)*get.threaten(target),Math.random()); - }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + player + .chooseTarget("请重新选择【随征】目标", true, function (card, player, target) { + return !player.getStorage("twsuizheng").includes(target); + }) + .set("ai", function (target) { + var player = _status.event.player; + return Math.max( + 1 + get.attitude(player, target) * get.threaten(target), + Math.random() + ); + }); + "step 3"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - game.log(player,'选择了',target,'作为','“随征”角色'); - delete player.storage.twsuizheng - player.markAuto('twsuizheng',[target]); + game.log(player, "选择了", target, "作为", "“随征”角色"); + delete player.storage.twsuizheng; + player.markAuto("twsuizheng", [target]); } }, - ai:{combo:'twsuizheng'}, + ai: { combo: "twsuizheng" }, }, //曹休 - twqianju:{ - audio:2, - trigger:{source:'damageSource'}, - filter:function(event,player){ - return get.distance(player,event.player)<=1&&player.countCards('e')<5; + twqianju: { + audio: 2, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return get.distance(player, event.player) <= 1 && player.countCards("e") < 5; }, - forced:true, - usable:1, - content:function(){ - var card=get.cardPile(function(card){ - return get.type(card)=='equip'&&player.canEquip(card); + forced: true, + usable: 1, + content: function () { + var card = get.cardPile(function (card) { + return get.type(card) == "equip" && player.canEquip(card); }); - if(card){ + if (card) { player.$gain2(card); game.delayx(); player.equip(card); } }, - mod:{ - globalFrom:function(from,to,distance){ - return distance-from.countCards('e'); + mod: { + globalFrom: function (from, to, distance) { + return distance - from.countCards("e"); }, }, }, - twqingxi:{ - audio:'xinqingxi', - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'&&player.getHistory('useCard',evt=>evt.card.name=='sha').indexOf(event.getParent())==0; + twqingxi: { + audio: "xinqingxi", + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + player + .getHistory("useCard", (evt) => evt.card.name == "sha") + .indexOf(event.getParent()) == 0 + ); }, - check:function(event,player){ + check: function (event, player) { return true; }, - logTarget:'target', - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - if(!target.countCards('e')) event._result={index:0}; - else target.chooseControl().set('ai',function(){ - if(_status.event.goon||player.hp>2) return 0; - return 1; - }).set('choiceList',[ - '令'+get.translation(player)+'摸'+get.cnNumber(Math.max(1,player.countCards('e')))+'张牌,且此【杀】不可被响应', - '弃置装备区中的所有牌并弃置'+get.translation(player)+'装备区等量的牌,此【杀】造成的伤害+1' - ]).set('goon',get.attitude(target,player)>0); - 'step 1' - if(result.index==0){ - player.draw(Math.max(1,player.countCards('e'))); + logTarget: "target", + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + if (!target.countCards("e")) event._result = { index: 0 }; + else + target + .chooseControl() + .set("ai", function () { + if (_status.event.goon || player.hp > 2) return 0; + return 1; + }) + .set("choiceList", [ + "令" + + get.translation(player) + + "摸" + + get.cnNumber(Math.max(1, player.countCards("e"))) + + "张牌,且此【杀】不可被响应", + "弃置装备区中的所有牌并弃置" + + get.translation(player) + + "装备区等量的牌,此【杀】造成的伤害+1", + ]) + .set("goon", get.attitude(target, player) > 0); + "step 1"; + if (result.index == 0) { + player.draw(Math.max(1, player.countCards("e"))); trigger.getParent().directHit.add(target); - game.log(trigger.card,'不可被',target,'响应'); + game.log(trigger.card, "不可被", target, "响应"); event.finish(); + } else { + var num = target.countCards("e"); + target.discard(target.getCards("e")); + target.discardPlayerCard(player, "e", num, true); } - else{ - var num=target.countCards('e'); - target.discard(target.getCards('e')); - target.discardPlayerCard(player,'e',num,true); - } - 'step 2' - var map=trigger.customArgs; - var id=target.playerid; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + "step 2"; + var map = trigger.customArgs; + var id = target.playerid; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; - game.log(trigger.card,'对',target,'造成的伤害+1'); + game.log(trigger.card, "对", target, "造成的伤害+1"); game.delayx(); }, }, //孙翊 - twzaoli:{ - audio:'zaoli', - trigger:{player:'phaseUseBegin'}, - init:function(player){ - if(player.isPhaseUsing()){ - var hs=player.getCards('h'); - player.getHistory('gain',function(evt){ + twzaoli: { + audio: "zaoli", + trigger: { player: "phaseUseBegin" }, + init: function (player) { + if (player.isPhaseUsing()) { + var hs = player.getCards("h"); + player.getHistory("gain", function (evt) { hs.removeArray(evt.cards); }); - if(hs.length) player.addGaintag(hs,'twzaoli'); + if (hs.length) player.addGaintag(hs, "twzaoli"); } }, - filter:function(event,player){ - return player.countCards('he'); + filter: function (event, player) { + return player.countCards("he"); }, - forced:true, - group:'twzaoli_mark', - content:function(){ - 'step 0' - if(player.countCards('h',card=>get.type(card)!='equip')){ - player.chooseCard('h',[1,Infinity],true,'躁厉:请选择至少一张非装备手牌,你弃置这些牌和所有装备牌',(card,player)=>{ - return get.type(card)!='equip'&&lib.filter.cardDiscardable(card,player,'twzaoli'); - }).set('ai',function(card){ - if(!card.hasGaintag('twzaoli_temp')) return 5-get.value(card); - return 1; - }); - } - 'step 1' - var cards=player.getCards('he',{type:'equip'}); - var subtype=[]; - event.subtype=subtype.addArray(cards.map(card=>get.subtype(card))); - cards.addArray(result.cards||[]); - if(cards.length) player.discard(cards); - event.cards=cards; - 'step 2' - player.draw(cards.length); - 'step 3' - var num=0; - if(event.subtype.length){ - for(var i of event.subtype){ - var card=get.cardPile2(function(card){ - return get.type(card)=='equip'&&get.subtype(card)==i; + forced: true, + group: "twzaoli_mark", + content: function () { + "step 0"; + if (player.countCards("h", (card) => get.type(card) != "equip")) { + player + .chooseCard( + "h", + [1, Infinity], + true, + "躁厉:请选择至少一张非装备手牌,你弃置这些牌和所有装备牌", + (card, player) => { + return ( + get.type(card) != "equip" && + lib.filter.cardDiscardable(card, player, "twzaoli") + ); + } + ) + .set("ai", function (card) { + if (!card.hasGaintag("twzaoli_temp")) return 5 - get.value(card); + return 1; }); - if(card){ + } + "step 1"; + var cards = player.getCards("he", { type: "equip" }); + var subtype = []; + event.subtype = subtype.addArray(cards.map((card) => get.subtype(card))); + cards.addArray(result.cards || []); + if (cards.length) player.discard(cards); + event.cards = cards; + "step 2"; + player.draw(cards.length); + "step 3"; + var num = 0; + if (event.subtype.length) { + for (var i of event.subtype) { + var card = get.cardPile2(function (card) { + return get.type(card) == "equip" && get.subtype(card) == i; + }); + if (card) { num++; player.$gain2(card); game.delayx(); @@ -11038,1513 +13969,1892 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } } - if(num<=2) event.finish(); - 'step 4' + if (num <= 2) event.finish(); + "step 4"; player.loseHp(); }, - onremove:function(player){ - player.removeGaintag('twzaoli'); + onremove: function (player) { + player.removeGaintag("twzaoli"); }, - mod:{ - cardEnabled2:function(card,player){ - if(player.isPhaseUsing()&&get.itemtype(card)=='card'&&card.hasGaintag('twzaoli')) return false; + mod: { + cardEnabled2: function (card, player) { + if ( + player.isPhaseUsing() && + get.itemtype(card) == "card" && + card.hasGaintag("twzaoli") + ) + return false; }, }, - subSkill:{ - mark:{ - trigger:{player:['phaseUseBegin','phaseUseAfter','phaseAfter']}, - filter:function(event,player){ - return player.countCards('h'); + subSkill: { + mark: { + trigger: { player: ["phaseUseBegin", "phaseUseAfter", "phaseAfter"] }, + filter: function (event, player) { + return player.countCards("h"); }, - direct:true, - firstDo:true, - content:function(){ - if(event.triggername=='phaseUseBegin'){ - var hs=player.getCards('h'); - player.getHistory('gain',function(evt){ + direct: true, + firstDo: true, + content: function () { + if (event.triggername == "phaseUseBegin") { + var hs = player.getCards("h"); + player.getHistory("gain", function (evt) { hs.removeArray(evt.cards); }); - if(hs.length) player.addGaintag(hs,'twzaoli'); - } - else{ - player.removeGaintag('twzaoli'); + if (hs.length) player.addGaintag(hs, "twzaoli"); + } else { + player.removeGaintag("twzaoli"); } }, - } + }, }, }, //邓芝 - twjimeng:{ - audio:'jimeng', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countGainableCards(player,'he')>0; - }) + twjimeng: { + audio: "jimeng", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countGainableCards(player, "he") > 0; + }); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'hej')>0; + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "hej") > 0; }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'hej',true); - 'step 1' - var hs=player.getCards('he'); - if(hs.length){ - if(hs.length==1) event._result={bool:true,cards:hs}; - else player.chooseCard(true,'交给'+get.translation(target)+'一张牌','he',true); - } - else event.finish(); - 'step 2' - player.give(result.cards,target); - 'step 3' - if(target.hp>=player.hp) player.draw(); + content: function () { + "step 0"; + player.gainPlayerCard(target, "hej", true); + "step 1"; + var hs = player.getCards("he"); + if (hs.length) { + if (hs.length == 1) event._result = { bool: true, cards: hs }; + else player.chooseCard(true, "交给" + get.translation(target) + "一张牌", "he", true); + } else event.finish(); + "step 2"; + player.give(result.cards, target); + "step 3"; + if (target.hp >= player.hp) player.draw(); }, - ai:{ - order:8, - result:{ - player:function(player,target){ - if(target.hp>=player.hp) return 1; + ai: { + order: 8, + result: { + player: function (player, target) { + if (target.hp >= player.hp) return 1; return 0; }, - target:function(player,target){ - return get.effect(target,{name:'shunshou'},player,target)/10; - } - } - } + target: function (player, target) { + return get.effect(target, { name: "shunshou" }, player, target) / 10; + }, + }, + }, }, //杨仪 - twgongsun:{ - audio:'gongsun', - trigger:{player:'phaseUseBegin'}, - forced:true, - direct:true, - filter:function(event,player){ - return game.hasPlayer(current=>player.inRange(current)); + twgongsun: { + audio: "gongsun", + trigger: { player: "phaseUseBegin" }, + forced: true, + direct: true, + filter: function (event, player) { + return game.hasPlayer((current) => player.inRange(current)); }, - content:function(){ - 'step 0' - player.chooseTarget('共损:请选择一名攻击范围内的角色',lib.translate.twgongsun_info,true,function(card,player,target){ - return player!=target&&player.inRange(target); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*(1+target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twgongsun',target); - player.addTempSkill('twgongsun_shadow',{player:['phaseBegin','die']}); - player.chooseControl(lib.suit).set('prompt','共损:请选择一个花色').set('ai',function(button){ - return lib.suit.randomGet(); + content: function () { + "step 0"; + player + .chooseTarget( + "共损:请选择一名攻击范围内的角色", + lib.translate.twgongsun_info, + true, + function (card, player, target) { + return player != target && player.inRange(target); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) * (1 + target.countCards("h")); }); - } - else event.finish(); - 'step 2' - var suit=result.control; - player.popup(suit+2,'soil'); - game.log(player,'选择了',suit+2); - player.storage.twgongsun_shadow.push([target,suit]); - player.markSkill('twgongsun_shadow'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twgongsun", target); + player.addTempSkill("twgongsun_shadow", { player: ["phaseBegin", "die"] }); + player + .chooseControl(lib.suit) + .set("prompt", "共损:请选择一个花色") + .set("ai", function (button) { + return lib.suit.randomGet(); + }); + } else event.finish(); + "step 2"; + var suit = result.control; + player.popup(suit + 2, "soil"); + game.log(player, "选择了", suit + 2); + player.storage.twgongsun_shadow.push([target, suit]); + player.markSkill("twgongsun_shadow"); }, }, - twgongsun_shadow:{ - global:'twgongsun_shadow2', - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + twgongsun_shadow: { + global: "twgongsun_shadow2", + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - marktext:'损', - onremove:true, - intro:{ - content:function(shadow){ - var str=''; - for(var i=0;i0) str+='
              ' - str+=get.translation(shadow[i][0]); - str+=':'; - str+=get.translation(shadow[i][1]); + marktext: "损", + onremove: true, + intro: { + content: function (shadow) { + var str = ""; + for (var i = 0; i < shadow.length; i++) { + if (i > 0) str += "
              "; + str += get.translation(shadow[i][0]); + str += ":"; + str += get.translation(shadow[i][1]); } return str; }, }, - mod:{ - cardEnabled:function(card,player){ - var list=player.storage.twgongsun_shadow; - for(var i=0;iMath.random()<=0.5?0:1); - 'step 1' - player.addSkill('twzhengjian_eff'+result.index); - game.log(player,'获得了','#g【征建】','的','#y效果'+get.cnNumber(result.index+1,true)); + content: function () { + "step 0"; + player + .chooseControl() + .set("prompt", "征建:请选择一种效果") + .set("choiceList", [ + "令“出牌阶段内未使用过非基本牌”的其他角色受到惩罚", + "令“出牌阶段内未得到过牌”的其他角色受到惩罚", + ]) + .set("ai", () => (Math.random() <= 0.5 ? 0 : 1)); + "step 1"; + player.addSkill("twzhengjian_eff" + result.index); + game.log( + player, + "获得了", + "#g【征建】", + "的", + "#y效果" + get.cnNumber(result.index + 1, true) + ); game.delayx(); }, - onremove:true, - subSkill:{ - eff0:{ - audio:'twzhengjian', - trigger:{global:'phaseUseEnd'}, - forced:true, - charlotte:true, - marktext:'建', - mark:true, - filter:function(event,player){ - if(event.player==player||event._twzhengjian||!event.player.isIn()) return false; - if(event.player.hasHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event&&get.type(evt.card)!='basic'; - })) return false; - return player.storage.twzhengjian||event.player.countCards('he')>0; + onremove: true, + subSkill: { + eff0: { + audio: "twzhengjian", + trigger: { global: "phaseUseEnd" }, + forced: true, + charlotte: true, + marktext: "建", + mark: true, + filter: function (event, player) { + if (event.player == player || event._twzhengjian || !event.player.isIn()) + return false; + if ( + event.player.hasHistory("useCard", function (evt) { + return ( + evt.getParent("phaseUse") == event && get.type(evt.card) != "basic" + ); + }) + ) + return false; + return player.storage.twzhengjian || event.player.countCards("he") > 0; }, - logTarget:'player', - content:function(){ - 'step 0' - trigger._twzhengjian=true; - var target=trigger.player; - event.target=target; - if(player.storage.twzhengjian){ - player.chooseBool('征建:是否对'+get.translation(target)+'造成1点伤害?').set('ai',()=>_status.event.goon).set('goon',get.damageEffect(target,player,_status.event.player)>0); + logTarget: "player", + content: function () { + "step 0"; + trigger._twzhengjian = true; + var target = trigger.player; + event.target = target; + if (player.storage.twzhengjian) { + player + .chooseBool("征建:是否对" + get.translation(target) + "造成1点伤害?") + .set("ai", () => _status.event.goon) + .set("goon", get.damageEffect(target, player, _status.event.player) > 0); + } else { + target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); } - else{ - target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); + "step 1"; + if (result.bool) { + if (result.cards && result.cards.length) { + target.give(result.cards, player).type = "twzhengjian"; + } else target.damage(); } - 'step 1' - if(result.bool){ - if(result.cards&&result.cards.length){ - target.give(result.cards,player).type='twzhengjian'; - } - else target.damage(); - } - player.chooseBool('是否变更【征建】的效果?').set('ai',()=>Math.random()>0.5); - 'step 2' - if(result.bool){ - player.removeSkill('twzhengjian_eff0'); - player.addSkill('twzhengjian_eff1'); - game.log(player,'将','#g【征建】','的效果变更为','#y效果二'); + player + .chooseBool("是否变更【征建】的效果?") + .set("ai", () => Math.random() > 0.5); + "step 2"; + if (result.bool) { + player.removeSkill("twzhengjian_eff0"); + player.addSkill("twzhengjian_eff1"); + game.log(player, "将", "#g【征建】", "的效果变更为", "#y效果二"); } }, - intro:{ - content:function(storage,player){ - if(player.storage.twzhengjian) return '其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果二。'; - return '其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。'; + intro: { + content: function (storage, player) { + if (player.storage.twzhengjian) + return "其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果二。"; + return "其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。"; }, }, }, - eff1:{ - audio:'twzhengjian', - trigger:{global:'phaseUseEnd'}, - forced:true, - charlotte:true, - marktext:'征', - mark:true, - filter:function(event,player){ - if(event.player==player||event._twzhengjian||!event.player.isIn()) return false; - if(event.player.hasHistory('gain',function(evt){ - return evt.getParent('phaseUse')==event; - })) return false; - return player.storage.twzhengjian||event.player.countCards('he')>0; + eff1: { + audio: "twzhengjian", + trigger: { global: "phaseUseEnd" }, + forced: true, + charlotte: true, + marktext: "征", + mark: true, + filter: function (event, player) { + if (event.player == player || event._twzhengjian || !event.player.isIn()) + return false; + if ( + event.player.hasHistory("gain", function (evt) { + return evt.getParent("phaseUse") == event; + }) + ) + return false; + return player.storage.twzhengjian || event.player.countCards("he") > 0; }, - logTarget:'player', - content:function(){ - 'step 0' - trigger._twzhengjian=true; - var target=trigger.player; - event.target=target; - if(player.storage.twzhengjian){ - player.chooseBool('征建:是否对'+get.translation(target)+'造成1点伤害?').set('ai',()=>_status.event.goon).set('goon',get.damageEffect(target,player,_status.event.player)>0); + logTarget: "player", + content: function () { + "step 0"; + trigger._twzhengjian = true; + var target = trigger.player; + event.target = target; + if (player.storage.twzhengjian) { + player + .chooseBool("征建:是否对" + get.translation(target) + "造成1点伤害?") + .set("ai", () => _status.event.goon) + .set("goon", get.damageEffect(target, player, _status.event.player) > 0); + } else { + target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); } - else{ - target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌'); + "step 1"; + if (result.bool) { + if (result.cards && result.cards.length) { + target.give(result.cards, player).type = "twzhengjian"; + } else target.damage(); } - 'step 1' - if(result.bool){ - if(result.cards&&result.cards.length){ - target.give(result.cards,player).type='twzhengjian'; - } - else target.damage(); - } - player.chooseBool('是否变更【征建】的效果?').set('ai',()=>Math.random()>0.5); - 'step 2' - if(result.bool){ - player.removeSkill('twzhengjian_eff1'); - player.addSkill('twzhengjian_eff0'); - game.log(player,'将','#g【征建】','的效果变更为','#y效果一'); + player + .chooseBool("是否变更【征建】的效果?") + .set("ai", () => Math.random() > 0.5); + "step 2"; + if (result.bool) { + player.removeSkill("twzhengjian_eff1"); + player.addSkill("twzhengjian_eff0"); + game.log(player, "将", "#g【征建】", "的效果变更为", "#y效果一"); } }, - intro:{ - content:function(storage,player){ - if(player.storage.twzhengjian) return '其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果一。'; - return '其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。'; + intro: { + content: function (storage, player) { + if (player.storage.twzhengjian) + return "其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果一。"; + return "其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。"; }, }, }, }, }, - twzhongchi:{ - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + twzhongchi: { + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - forced:true, - skillAnimation:true, - animationColor:'wood', - filter:function(event,player){ - if(player.storage.twzhengjian||!player.hasSkill('twzhengjian',null,null,false)||!event.getg(player).length) return false; - var num1=game.countPlayer2(); - var list=[]; - player.getAllHistory('gain',function(evt){ - if(evt.type=='twzhengjian') list.add(evt.source); + forced: true, + skillAnimation: true, + animationColor: "wood", + filter: function (event, player) { + if ( + player.storage.twzhengjian || + !player.hasSkill("twzhengjian", null, null, false) || + !event.getg(player).length + ) + return false; + var num1 = game.countPlayer2(); + var list = []; + player.getAllHistory("gain", function (evt) { + if (evt.type == "twzhengjian") list.add(evt.source); }); - return list.length>=Math.ceil(num1/2); + return list.length >= Math.ceil(num1 / 2); }, - content:function(){ - 'step 0' - player.awakenSkill('twzhongchi'); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("twzhongchi"); + "step 1"; player.recover(2); - player.addSkill('twzhongchi_effect'); - player.storage.twzhengjian=true; - 'step 2' + player.addSkill("twzhongchi_effect"); + player.storage.twzhengjian = true; + "step 2"; game.delayx(); }, - subSkill:{ - effect:{ - mark:true, - marktext:'斥', - intro:{content:'受到渠道为【杀】的伤害+1'}, - trigger:{player:'damageBegin1'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; + subSkill: { + effect: { + mark: true, + marktext: "斥", + intro: { content: "受到渠道为【杀】的伤害+1" }, + trigger: { player: "damageBegin1" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha"; }, - content:function(){ + content: function () { trigger.num++; }, }, }, + ai: { + combo: "twzhengjian", + }, }, //田豫 - twzhenxi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - var target=event.target; - return event.card.name=='sha'&&(target.countCards('h')>0||target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card); - }) - },'e')||target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canAddJudge(card); - }) - },'j')); + twzhenxi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + var target = event.target; + return ( + event.card.name == "sha" && + (target.countCards("h") > 0 || + target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canEquip(card); + }); + }, "e") || + target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canAddJudge(card); + }); + }, "j")) + ); }, - usable:1, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - var str=get.translation(target); - var list=[ - '弃置'+str+'的'+get.cnNumber(get.distance(player,target))+'张手牌', - '将'+str+'装备区或判定区内的一张牌移动到另一名角色的对应区域内', + usable: 1, + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + var str = get.translation(target); + var list = [ + "弃置" + str + "的" + get.cnNumber(get.distance(player, target)) + "张手牌", + "将" + str + "装备区或判定区内的一张牌移动到另一名角色的对应区域内", ]; - var choices=[]; - if(target.countCards('h')>0) choices.push('选项一'); - else list[0]=''+list[0]+''; - if(target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card); - }) - },'e')||target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canAddJudge(card); - }) - },'j')) choices.push('选项二'); - else list[1]=''+list[1]+''; - if(choices.length==2&&(target.hp>player.hp||target.isMaxHp())) choices.push('全部执行'); - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',list).set('prompt',get.prompt('twzhenxi',target)).set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().target; - var eff1=0,eff2=0; - var choices=_status.event.controls.slice(0); - if(choices.includes('选项一')){ - eff1=-get.distance(player,target)*get.attitude(player,target); - } - if(choices.includes('选项二')){ - var equip=0,judge=0,att=get.attitude(player,target); - var es=target.getCards('e'),js=target.getCards('j'); - for(var i of es){ - var val=get.value(i); - if(att>0){ - if(val<=Math.min(0,equip)&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(i)&&get.effect(current,i,player,player)>0; - })) equip=val; - } - else{ - if(val>Math.max(0,equip)&&game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(i)&&get.effect(current,i,player,player)>0; - })) equip=val; - } + var choices = []; + if (target.countCards("h") > 0) choices.push("选项一"); + else list[0] = '' + list[0] + ""; + if ( + target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canEquip(card); + }); + }, "e") || + target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canAddJudge(card); + }); + }, "j") + ) + choices.push("选项二"); + else list[1] = '' + list[1] + ""; + if (choices.length == 2 && (target.hp > player.hp || target.isMaxHp())) + choices.push("全部执行"); + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", list) + .set("prompt", get.prompt("twzhenxi", target)) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().target; + var eff1 = 0, + eff2 = 0; + var choices = _status.event.controls.slice(0); + if (choices.includes("选项一")) { + eff1 = -get.distance(player, target) * get.attitude(player, target); } - for(var i of js){ - var card={name:i.viewAs||i.name}; - var effect=get.effect(target,card,player,player); - if(effect<0){ - game.countPlayer(function(current){ - if(current!=target&¤t.canAddJudge(i)){ - var eff=get.effect(current,card,player,player); - judge=Math.max(eff,judge); - } - }); + if (choices.includes("选项二")) { + var equip = 0, + judge = 0, + att = get.attitude(player, target); + var es = target.getCards("e"), + js = target.getCards("j"); + for (var i of es) { + var val = get.value(i); + if (att > 0) { + if ( + val <= Math.min(0, equip) && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(i) && + get.effect(current, i, player, player) > 0 + ); + }) + ) + equip = val; + } else { + if ( + val > Math.max(0, equip) && + game.hasPlayer(function (current) { + return ( + current != target && + current.canEquip(i) && + get.effect(current, i, player, player) > 0 + ); + }) + ) + equip = val; + } } + for (var i of js) { + var card = { name: i.viewAs || i.name }; + var effect = get.effect(target, card, player, player); + if (effect < 0) { + game.countPlayer(function (current) { + if (current != target && current.canAddJudge(i)) { + var eff = get.effect(current, card, player, player); + judge = Math.max(eff, judge); + } + }); + } + } + eff2 = Math.max(-equip * att, judge); } - eff2=Math.max(-equip*att,judge); - } - if(eff1>0){ - if(eff2>0){ - if(choices.includes('全部执行')) return '全部执行'; - else if(eff2>=eff1) return '选项二'; - } - return '选项一'; - } - else if(eff2>0) return '选项二'; - return 'cancel2'; - }); - 'step 1' - if(result.control=='cancel2'){ + if (eff1 > 0) { + if (eff2 > 0) { + if (choices.includes("全部执行")) return "全部执行"; + else if (eff2 >= eff1) return "选项二"; + } + return "选项一"; + } else if (eff2 > 0) return "选项二"; + return "cancel2"; + }); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - player.logSkill('twzhenxi',target); - event.control=result.control; - if(event.control!='选项二') player.discardPlayerCard(target,true,'h',get.distance(player,target)); - if(event.control=='选项一') event.finish(); - 'step 2' - if(event.control!='选项一'&&(target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canEquip(card); - }) - },'e')||target.hasCard(function(card){ - return game.hasPlayer(function(current){ - return current!=target&¤t.canAddJudge(card); - }) - },'j'))){ - player.chooseTarget(true,'将'+get.translation(target)+'区域内的一张牌移动给另一名角色',function(card,player,target){ - var source=_status.event.preTarget; - if(source==target) return false; - return source.hasCard(function(card){ - return target.canEquip(card); - },'e')||source.hasCard(function(card){ - return target.canAddJudge(card); - },'j'); - }).set('preTarget',target).set('ai',function(target){ - var player=_status.event.player,source=_status.event.preTarget; - var att=get.attitude(player,source); - var es=source.getCards('e',function(card){ - return target.canEquip(card); - }),js=source.getCards('j',function(card){ - return target.canAddJudge(card); + player.logSkill("twzhenxi", target); + event.control = result.control; + if (event.control != "选项二") + player.discardPlayerCard(target, true, "h", get.distance(player, target)); + if (event.control == "选项一") event.finish(); + "step 2"; + if ( + event.control != "选项一" && + (target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canEquip(card); }); - var eff=0; - for(var i of es){ - var val=get.value(i,source); - if(att>0?val<=0:val>0){ - eff=Math.max(eff,get.effect(target,i,player,player)); + }, "e") || + target.hasCard(function (card) { + return game.hasPlayer(function (current) { + return current != target && current.canAddJudge(card); + }); + }, "j")) + ) { + player + .chooseTarget( + true, + "将" + get.translation(target) + "区域内的一张牌移动给另一名角色", + function (card, player, target) { + var source = _status.event.preTarget; + if (source == target) return false; + return ( + source.hasCard(function (card) { + return target.canEquip(card); + }, "e") || + source.hasCard(function (card) { + return target.canAddJudge(card); + }, "j") + ); } - } - for(var i of js){ - var card={name:i.viewAs||i.name}; - if(get.effect(source,card,player,player)<0){ - eff=Math.max(eff,get.effect(target,card,player,player)); + ) + .set("preTarget", target) + .set("ai", function (target) { + var player = _status.event.player, + source = _status.event.preTarget; + var att = get.attitude(player, source); + var es = source.getCards("e", function (card) { + return target.canEquip(card); + }), + js = source.getCards("j", function (card) { + return target.canAddJudge(card); + }); + var eff = 0; + for (var i of es) { + var val = get.value(i, source); + if (att > 0 ? val <= 0 : val > 0) { + eff = Math.max(eff, get.effect(target, i, player, player)); + } } - } - return eff; - }); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target2=result.targets[0]; - event.target2=target2; - player.choosePlayerCard('ej',true,function(button){ - var player=_status.event.player; - var targets0=_status.event.targets0; - var targets1=_status.event.targets1; - if(get.attitude(player,targets0)>0&&get.attitude(player,targets1)<0){ - if(get.position(button.link)=='j') return 12; - if(get.value(button.link,targets0)<0&&get.effect(targets1,button.link,player,targets1)>0) return 10; - return 0; - } - else{ - if(get.position(button.link)=='j') return -10; - return get.value(button.link)*get.effect(targets1,button.link,player,targets1); - } - },target).set('targets0',target).set('targets1',target2).set('filterButton',function(button){ - var targets1=_status.event.targets1; - if(get.position(button.link)=='j'){ - return targets1.canAddJudge(button.link); - } - else{ - return targets1.canEquip(button.link); - } - }).set('ai',function(button){ - var player=_status.event.player,target=_status.event.targets1,source=_status.event.targets0; - var att=get.attitude(player,source); - var card=button.link; - if(get.position(card)=='e'){ - var val=get.value(card); - if(att>0?val>0:val<=0) return 0; - return get.effect(target,card,player,player); - } - var cardx={name:card.viewAs||card.name}; - if(get.effect(source,cardx,player,player)>=0) return 0; - return get.effect(target,cardx,player,player) - }); - } - else{ + for (var i of js) { + var card = { name: i.viewAs || i.name }; + if (get.effect(source, card, player, player) < 0) { + eff = Math.max(eff, get.effect(target, card, player, player)); + } + } + return eff; + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var target2 = result.targets[0]; + event.target2 = target2; + player + .choosePlayerCard( + "ej", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if ( + get.attitude(player, targets0) > 0 && + get.attitude(player, targets1) < 0 + ) { + if (get.position(button.link) == "j") return 12; + if ( + get.value(button.link, targets0) < 0 && + get.effect(targets1, button.link, player, targets1) > 0 + ) + return 10; + return 0; + } else { + if (get.position(button.link) == "j") return -10; + return ( + get.value(button.link) * + get.effect(targets1, button.link, player, targets1) + ); + } + }, + target + ) + .set("targets0", target) + .set("targets1", target2) + .set("filterButton", function (button) { + var targets1 = _status.event.targets1; + if (get.position(button.link) == "j") { + return targets1.canAddJudge(button.link); + } else { + return targets1.canEquip(button.link); + } + }) + .set("ai", function (button) { + var player = _status.event.player, + target = _status.event.targets1, + source = _status.event.targets0; + var att = get.attitude(player, source); + var card = button.link; + if (get.position(card) == "e") { + var val = get.value(card); + if (att > 0 ? val > 0 : val <= 0) return 0; + return get.effect(target, card, player, player); + } + var cardx = { name: card.viewAs || card.name }; + if (get.effect(source, cardx, player, player) >= 0) return 0; + return get.effect(target, cardx, player, player); + }); + } else { event.finish(); } - 'step 4' - if(result.bool&&result.links.length){ - var link=result.links[0]; - if(get.position(link)=='e'){ + "step 4"; + if (result.bool && result.links.length) { + var link = result.links[0]; + if (get.position(link) == "e") { event.target2.equip(link); - } - else if(link.viewAs){ - event.target2.addJudge({name:link.viewAs},[link]); - } - else{ + } else if (link.viewAs) { + event.target2.addJudge({ name: link.viewAs }, [link]); + } else { event.target2.addJudge(link); } - target.$give(link,event.target2,false); - game.log(target,'的',link,'被移动给了',event.target2); + target.$give(link, event.target2, false); + game.log(target, "的", link, "被移动给了", event.target2); game.delay(); } }, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.name||arg.name!='sha') return false; - if(player.storage.counttrigger&&player.storage.counttrigger.twzhenxi) return false; - if(!arg.target) return false; - var card=arg.target.getEquip(2); - return card&&get.value(card)>0&&game.hasPlayer(function(current){ - return current!=arg.target&¤t.canEquip(card)&&get.effect(current,card,player,player)>0; - }) + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.name || arg.name != "sha") return false; + if (player.storage.counttrigger && player.storage.counttrigger.twzhenxi) return false; + if (!arg.target) return false; + var card = arg.target.getEquip(2); + return ( + card && + get.value(card) > 0 && + game.hasPlayer(function (current) { + return ( + current != arg.target && + current.canEquip(card) && + get.effect(current, card, player, player) > 0 + ); + }) + ); }, }, }, - twyangshi:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - content:function(){ - if(game.hasPlayer(function(current){ - return current!=player&&!player.inRange(current); - })){ - player.addSkill('twyangshi_distance'); - player.addMark('twyangshi_distance',1,false); - } - else{ - var card=get.cardPile2(function(card){ - return card.name=='sha'; + twyangshi: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + content: function () { + if ( + game.hasPlayer(function (current) { + return current != player && !player.inRange(current); + }) + ) { + player.addSkill("twyangshi_distance"); + player.addMark("twyangshi_distance", 1, false); + } else { + var card = get.cardPile2(function (card) { + return card.name == "sha"; }); - if(card) player.gain(card,'gain2'); - else game.log('但是牌堆里已经没有杀了!'); + if (card) player.gain(card, "gain2"); + else game.log("但是牌堆里已经没有杀了!"); } }, - subSkill:{ - distance:{ - charlotte:true, - onremove:true, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('twyangshi_distance'); + subSkill: { + distance: { + charlotte: true, + onremove: true, + mod: { + attackRange: function (player, num) { + return num + player.countMark("twyangshi_distance"); }, }, - intro:{ - content:'攻击范围+#', + intro: { + content: "攻击范围+#", }, }, }, }, //全琮 - zhenshan:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - filter:function(event,player){ - if(event.type=='wuxie'||player.hasSkill('zhenshan_used')) return false; - var nh=player.countCards('h'); - if(!game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')0; - })){ - if(card.name=='sha'){ - var eff=player.getUseValue(card); - if(eff>0) return 2.9+eff/10; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if (card.name == "jiu") return 0; + if ( + game.hasPlayer(function (current) { + return get.effect(current, card, player, player) > 0; + }) + ) { + if (card.name == "sha") { + var eff = player.getUseValue(card); + if (eff > 0) return 2.9 + eff / 10; return 0; - } - else if(card.name=='tao'||card.name=='shan'){ + } else if (card.name == "tao" || card.name == "shan") { return 4; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:function(){return false}, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + filterCard: function () { + return false; }, - selectCard:-1, - precontent:function(){ - 'step 0' - player.chooseTarget('选择一名手牌数小于你的角色交换手牌',function(card,player,target){ - return target!=player&&target.countCards('h')0&¤t.countCards('h') 0 && current.countCards("h") < nh; + }) + ) { + if (event.type == "dying") { + if (event.filterCard({ name: "tao" }, player, event)) { return 0.5; } - } - else{ - if(event.filterCard({name:'tao'},player,event)||event.filterCard({name:'shan'},player,event)){ + } else { + if ( + event.filterCard({ name: "tao" }, player, event) || + event.filterCard({ name: "shan" }, player, event) + ) { return 4; } - if(event.filterCard({name:'sha'},player,event)){ + if (event.filterCard({ name: "sha" }, player, event)) { return 2.9; } } } return 0; }, - save:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(player.hasSkill('zhenshan_used')) return false; - var nh=player.countCards('h'); - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')0&&(event.card.name=='sha'||get.type(event.card,false)=='trick'&&get.tag(event.card,'damage')>0); + twfenghan: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + direct: true, + usable: 1, + filter: function (event, player) { + return ( + event.isFirstTarget && + event.targets.length > 0 && + (event.card.name == "sha" || + (get.type(event.card, false) == "trick" && get.tag(event.card, "damage") > 0)) + ); }, - content:function(){ - 'step 0' - var num=trigger.targets.length; - player.chooseTarget([1,num],get.prompt('twfenghan'),'令至多'+get.cnNumber(num)+'名角色各摸一张牌').set('ai',function(target){ - return Math.sqrt(5-Math.min(4,target.countCards('h')))*get.attitude(_status.event.player,target)*(target.hasSkillTag('nogain')?0.1:1); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('twfenghan',targets); - if(targets.length>1) game.asyncDraw(targets); - else{ + content: function () { + "step 0"; + var num = trigger.targets.length; + player + .chooseTarget( + [1, num], + get.prompt("twfenghan"), + "令至多" + get.cnNumber(num) + "名角色各摸一张牌" + ) + .set("ai", function (target) { + return ( + Math.sqrt(5 - Math.min(4, target.countCards("h"))) * + get.attitude(_status.event.player, target) * + (target.hasSkillTag("nogain") ? 0.1 : 1) + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("twfenghan", targets); + if (targets.length > 1) game.asyncDraw(targets); + else { targets[0].draw(); event.finish(); } - } - else{ + } else { player.storage.counttrigger.twfenghan--; event.finish(); } - 'step 2' + "step 2"; game.delayx(); }, }, - twcongji:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + twcongji: { + audio: 2, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - direct:true, - filter:function(event,player){ - if(player==_status.currentPhase||event.type!='discard'||event.getlx===false||!game.hasPlayer((current)=>current!=player)) return false; - var evt=event.getl(player); - for(var i of evt.cards2){ - if(get.color(i,player)=='red'&&get.position(i,true)=='d') return true; + direct: true, + filter: function (event, player) { + if ( + player == _status.currentPhase || + event.type != "discard" || + event.getlx === false || + !game.hasPlayer((current) => current != player) + ) + return false; + var evt = event.getl(player); + for (var i of evt.cards2) { + if (get.color(i, player) == "red" && get.position(i, true) == "d") return true; } return false; }, - content:function(){ - 'step 0' - var cards=[],cards2=trigger.getl(player).cards2; - for(var i of cards2){ - if(get.color(i,player)=='red'&&get.position(i,true)=='d') cards.push(i); + content: function () { + "step 0"; + var cards = [], + cards2 = trigger.getl(player).cards2; + for (var i of cards2) { + if (get.color(i, player) == "red" && get.position(i, true) == "d") cards.push(i); } - player.chooseButton(['从击:选择任意张牌交给其他角色',cards],[1,cards.length]).set('goon',game.hasPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0; - })).set('ai',function(button){ - if(_status.event.goon) return get.value(button.link); - return button.link.name=='du'?1:0; - }); - 'step 1' - if(result.bool){ - event.cards=result.links; - player.chooseTarget('选择一名角色获得以下牌:',get.translation(cards),true,lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player,cards=_status.event.getParent().cards; - if(cards[0].name=='du') return -get.attitude(player,target); - var att=get.attitude(player,target); - if(att<=0) return 0; - if(target.hasSkillTag('nogain')) att/=10; - if(target.hasJudge('lebu')) att/=4; - return get.value(cards,target)*att; + player + .chooseButton(["从击:选择任意张牌交给其他角色", cards], [1, cards.length]) + .set( + "goon", + game.hasPlayer(function (current) { + return current != player && get.attitude(player, current) > 0; + }) + ) + .set("ai", function (button) { + if (_status.event.goon) return get.value(button.link); + return button.link.name == "du" ? 1 : 0; }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twcongji',target); - target.gain(cards,'gain2'); + "step 1"; + if (result.bool) { + event.cards = result.links; + player + .chooseTarget( + "选择一名角色获得以下牌:", + get.translation(cards), + true, + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player, + cards = _status.event.getParent().cards; + if (cards[0].name == "du") return -get.attitude(player, target); + var att = get.attitude(player, target); + if (att <= 0) return 0; + if (target.hasSkillTag("nogain")) att /= 10; + if (target.hasJudge("lebu")) att /= 4; + return get.value(cards, target) * att; + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twcongji", target); + target.gain(cards, "gain2"); } }, }, //王粲 - twdianyi:{ - audio:2, - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ - if(!player.getHistory('sourceDamage').length) return player.countCards('h')!=4; - return player.countCards('h')>0; + twdianyi: { + audio: 2, + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { + if (!player.getHistory("sourceDamage").length) return player.countCards("h") != 4; + return player.countCards("h") > 0; }, - content:function(){ - var num=player.countCards('h'); - if(player.getHistory('sourceDamage').length) player.chooseToDiscard('h',true,num); - else if(num>4) player.chooseToDiscard('h',true,num-4); + content: function () { + var num = player.countCards("h"); + if (player.getHistory("sourceDamage").length) player.chooseToDiscard("h", true, num); + else if (num > 4) player.chooseToDiscard("h", true, num - 4); else player.drawTo(4); }, }, - twyingji:{ - audio:2, - enable:['chooseToUse','chooseToRespond'], - hiddenCard:function(player,name){ - return player!=_status.currentPhase&&lib.inpile.includes(name)&&player.countCards('h')==0; + twyingji: { + audio: 2, + enable: ["chooseToUse", "chooseToRespond"], + hiddenCard: function (player, name) { + return ( + player != _status.currentPhase && + lib.inpile.includes(name) && + player.countCards("h") == 0 + ); }, - filter:function(event,player){ - if(player==_status.currentPhase||player.countCards('h')>0) return false; - for(var i of lib.inpile){ - if(i=='wuxie') continue; - var type=get.type(i); - if((type=='basic'||type=='trick')&&event.filterCard({name:i,isCard:true},player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - if(event.filterCard({name:i,nature:j,isCard:true},player,event)) return true; + filter: function (event, player) { + if (player == _status.currentPhase || player.countCards("h") > 0) return false; + for (var i of lib.inpile) { + if (i == "wuxie") continue; + var type = get.type(i); + if ( + (type == "basic" || type == "trick") && + event.filterCard({ name: i, isCard: true }, player, event) + ) + return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + if (event.filterCard({ name: i, nature: j, isCard: true }, player, event)) + return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of lib.inpile){ - if(i=='wuxie') continue; - var type=get.type(i); - if(type=='basic'||type=='trick'){ - var card={name:i,isCard:true}; - if(event.filterCard(card,player,event)) list.push([type,'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - card.nature=j; - if(event.filterCard(card,player,event)) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of lib.inpile) { + if (i == "wuxie") continue; + var type = get.type(i); + if (type == "basic" || type == "trick") { + var card = { name: i, isCard: true }; + if (event.filterCard(card, player, event)) list.push([type, "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + card.nature = j; + if (event.filterCard(card, player, event)) + list.push(["基本", "", "sha", j]); } } } } - return ui.create.dialog('应机',[list,'vcard']); + return ui.create.dialog("应机", [list, "vcard"]); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - var val=_status.event.getParent().type=='phase'?player.getUseValue(card):1; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; return val; }, - backup:function(links,player){ + backup: function (links, player) { return { - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, }, - filterCard:()=>false, - selectCard:-1, - precontent:function(){ - player.logSkill('twyingji'); - player.draw('nodelay'); + filterCard: () => false, + selectCard: -1, + precontent: function () { + player.logSkill("twyingji"); + player.draw("nodelay"); delete event.result.skill; }, - } + }; }, - prompt:function(links){ - return '将一张手牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt: function (links) { + return ( + "将一张手牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - fireAttack:true, - respondShan:true, - respondSha:true, - skillTagFilter:function(player){ - if(player==_status.currentPhase||player.countCards('h')>0) return false; + ai: { + fireAttack: true, + respondShan: true, + respondSha: true, + skillTagFilter: function (player) { + if (player == _status.currentPhase || player.countCards("h") > 0) return false; }, - order:10, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying)>0; + order: 10, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying) > 0; return 1; }, }, }, - group:['twyingji_wuxie'], + group: ["twyingji_wuxie"], }, - twyingji_wuxie:{ - enable:'chooseToUse', - viewAs:{ - name:'wuxie', - isCard:true, + twyingji_wuxie: { + enable: "chooseToUse", + viewAs: { + name: "wuxie", + isCard: true, }, - viewAsFilter:function(player){ - return player!=_status.currentPhase&&player.countCards('h')==0; + viewAsFilter: function (player) { + return player != _status.currentPhase && player.countCards("h") == 0; }, - filterCard:()=>false, - prompt:'视为使用【无懈可击】并摸一张牌', - selectCard:[0,1], - check:()=>1, - precontent:function(){ - player.logSkill('twyingji'); - player.draw('nodelay'); + filterCard: () => false, + prompt: "视为使用【无懈可击】并摸一张牌", + selectCard: [0, 1], + check: () => 1, + precontent: function () { + player.logSkill("twyingji"); + player.draw("nodelay"); delete event.result.skill; }, - ai:{ - order:4, + ai: { + order: 4, }, }, - twshanghe:{ - trigger:{player:'dying'}, - limited:true, - audio:2, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - }) - }, - prompt:'是否发动【觞贺】?', - skillAnimation:true, - animationColor:'soil', - logTarget:(event,player)=>game.filterPlayer((current)=>current!=player), - content:function(){ - "step 0" - player.awakenSkill('twshanghe'); - event.targets=game.filterPlayer((current)=>current!=player); - event.num=0; - event.jiu=false; - "step 1" - event.current=targets[num]; - if(!event.current.countCards('he')) event.goto(3); - else event.current.chooseCard('交给'+get.translation(player)+'一张牌','he',true).set('ai',function(card){ - var evt=_status.event.getParent(); - return 100-get.value(card); + twshanghe: { + trigger: { player: "dying" }, + limited: true, + audio: 2, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; }); - "step 2" - if(result.bool&&result.cards&&result.cards.length){ - event.current.give(result.cards,player); - if(!event.jiu&&get.name(result.cards[0],player)=='jiu') event.jiu=true; + }, + prompt: "是否发动【觞贺】?", + skillAnimation: true, + animationColor: "soil", + logTarget: (event, player) => game.filterPlayer((current) => current != player), + content: function () { + "step 0"; + player.awakenSkill("twshanghe"); + event.targets = game.filterPlayer((current) => current != player); + event.num = 0; + event.jiu = false; + "step 1"; + event.current = targets[num]; + if (!event.current.countCards("he")) event.goto(3); + else + event.current + .chooseCard("交给" + get.translation(player) + "一张牌", "he", true) + .set("ai", function (card) { + var evt = _status.event.getParent(); + return 100 - get.value(card); + }); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + event.current.give(result.cards, player); + if (!event.jiu && get.name(result.cards[0], player) == "jiu") event.jiu = true; } - "step 3" + "step 3"; event.num++; - if(event.num1) game.delayx(); - if(game.hasPlayer(function(current){ - return targets.includes(current)&¤t.hasHistory('gain',function(evt){ - return evt.getParent(2)==event&&get.type(evt.cards[0],current)!='basic'; + } else event.finish(); + "step 2"; + if (targets.length > 1) game.delayx(); + if ( + game.hasPlayer(function (current) { + return ( + targets.includes(current) && + current.hasHistory("gain", function (evt) { + return ( + evt.getParent(2) == event && + get.type(evt.cards[0], current) != "basic" + ); + }) + ); }) - })) player.draw(); + ) + player.draw(); }, - group:'twkaiji_count', - subSkill:{ - count:{ - trigger:{global:'dying'}, - forced:true, - firstDo:true, - silent:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return !player.getStorage('twkaiji').includes(event.player); + group: "twkaiji_count", + subSkill: { + count: { + trigger: { global: "dying" }, + forced: true, + firstDo: true, + silent: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return !player.getStorage("twkaiji").includes(event.player); }, - content:function(){ - player.markAuto('twkaiji',[trigger.player]); + content: function () { + player.markAuto("twkaiji", [trigger.player]); }, }, }, }, - twshepan:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - usable:1, - direct:true, - filter:function(event,player){ - return player!=event.player; + twshepan: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + usable: 1, + direct: true, + filter: function (event, player) { + return player != event.player; }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - var choiceList=[ - '摸一张牌', - '将'+get.translation(target)+'区域内的一张牌置于牌堆顶', + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + var choiceList = [ + "摸一张牌", + "将" + get.translation(target) + "区域内的一张牌置于牌堆顶", ]; - var choices=['选项一']; - if(target.countCards('hej')>0) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('choice',function(){ - if(choices.length>2&&get.effect(target,{name:'guohe_copy'},player,player)>0) return 1; - return 0; - }()) - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twshepan',target); - if(result.index==1) player.choosePlayerCard(target,'hej',true); - else{ + var choices = ["选项一"]; + if (target.countCards("hej") > 0) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set( + "choice", + (function () { + if ( + choices.length > 2 && + get.effect(target, { name: "guohe_copy" }, player, player) > 0 + ) + return 1; + return 0; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twshepan", target); + if (result.index == 1) player.choosePlayerCard(target, "hej", true); + else { player.draw(); event.goto(3); } - } - else{ + } else { player.storage.counttrigger.twshepan--; event.finish(); } - 'step 2' - var card=result.cards[0]; - target.$throw(get.position(card)=='h'?1:card,1000); - target.lose(card,ui.cardPile,'insert'); - 'step 3' + "step 2"; + var card = result.cards[0]; + target.$throw(get.position(card) == "h" ? 1 : card, 1000); + target.lose(card, ui.cardPile, "insert"); + "step 3"; game.delayx(); - if(target.isIn()&&player.countCards('h')==target.countCards('h')){ + if (target.isIn() && player.countCards("h") == target.countCards("h")) { player.storage.counttrigger.twshepan--; - player.chooseBool('是否令'+get.translation(trigger.card)+'对自己无效?').set('ai',function(){ - var evt=_status.event.getTrigger(); - return get.effect(evt.target,evt.card,evt.player,evt.target)<0; - }); - } - else event.finish(); - 'step 4' - if(result.bool) trigger.excluded.add(player); + player + .chooseBool("是否令" + get.translation(trigger.card) + "对自己无效?") + .set("ai", function () { + var evt = _status.event.getTrigger(); + return get.effect(evt.target, evt.card, evt.player, evt.target) < 0; + }); + } else event.finish(); + "step 4"; + if (result.bool) trigger.excluded.add(player); }, }, //曹肇 - twfuzuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.getSkills(null,false,false).filter(function(i){ - return get.is.zhuanhuanji(i,current); - }).length>0; + twfuzuan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current.getSkills(null, false, false).filter(function (i) { + return get.is.zhuanhuanji(i, current); + }).length > 0 + ); }); }, - filterTarget:function(card,player,target){ - return target.getSkills(null,false,false).filter(function(i){ - return get.is.zhuanhuanji(i,target); - }).length>0; + filterTarget: function (card, player, target) { + return ( + target.getSkills(null, false, false).filter(function (i) { + return get.is.zhuanhuanji(i, target); + }).length > 0 + ); }, - content:function(){ - 'step 0' - var list=target.getSkills(null,false,false).filter(function(i){ - return get.is.zhuanhuanji(i,target); + content: function () { + "step 0"; + var list = target.getSkills(null, false, false).filter(function (i) { + return get.is.zhuanhuanji(i, target); }); - if(list.length==1){ - event._result={control:list[0]}; - } - else player.chooseControl(list).set('prompt','选择变更'+get.translation(target)+'一个技能的状态').set('choice',list.includes('twfeifu')?'twfeifu':0).set('ai',()=>_status.event.choice); - 'step 1' - var skill=result.control; + if (list.length == 1) { + event._result = { control: list[0] }; + } else + player + .chooseControl(list) + .set("prompt", "选择变更" + get.translation(target) + "一个技能的状态") + .set("choice", list.includes("twfeifu") ? "twfeifu" : 0) + .set("ai", () => _status.event.choice); + "step 1"; + var skill = result.control; target.changeZhuanhuanji(skill); - target.popup(skill,'wood'); - game.log(target,'的','#g【'+get.translation(skill)+'】','发生了状态变更'); + target.popup(skill, "wood"); + game.log(target, "的", "#g【" + get.translation(skill) + "】", "发生了状态变更"); game.delayx(); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(!target.hasSkill('twfeifu')) return 0; - return target.storage.twfeifu?-1:1; + ai: { + order: 8, + result: { + target: function (player, target) { + if (!target.hasSkill("twfeifu")) return 0; + return target.storage.twfeifu ? -1 : 1; }, }, }, - group:'twfuzuan_damage', - subSkill:{ - damage:{ - audio:'twfuzuan', - trigger:{ - player:'damageEnd', - source:'damageSource', + group: "twfuzuan_damage", + subSkill: { + damage: { + audio: "twfuzuan", + trigger: { + player: "damageEnd", + source: "damageSource", }, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.getSkills(null,false,false).filter(function(i){ - return get.is.zhuanhuanji(i,current); - }).length>0; + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current.getSkills(null, false, false).filter(function (i) { + return get.is.zhuanhuanji(i, current); + }).length > 0 + ); }); }, - content:function(){ - 'step 0' - player.chooseTarget(lib.skill.twfuzuan.filterTarget,get.prompt('twfuzuan'),'变更一名角色的一个转换技的状态').set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,'twfuzuan',player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twfuzuan',target); - var next=game.createEvent('twfuzuan'); - next.player=player; - next.target=target; + content: function () { + "step 0"; + player + .chooseTarget( + lib.skill.twfuzuan.filterTarget, + get.prompt("twfuzuan"), + "变更一名角色的一个转换技的状态" + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, "twfuzuan", player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twfuzuan", target); + var next = game.createEvent("twfuzuan"); + next.player = player; + next.target = target; next.setContent(lib.skill.twfuzuan.content); } }, }, }, }, - twchongqi:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + twchongqi: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - logTarget:()=>game.filterPlayer().sortBySeat(), - content:function(){ - 'step 0' - game.filterPlayer().sortBySeat().forEach(function(current){ - current.addSkills('twfeifu'); - }); + logTarget: () => game.filterPlayer().sortBySeat(), + content: function () { + "step 0"; + game.filterPlayer() + .sortBySeat() + .forEach(function (current) { + current.addSkills("twfeifu"); + }); //game.log(player,'令所有其他角色获得了技能','#g【非服】') game.delayx(); - 'step 1' - player.chooseTarget('是否减1点体力上限,并令一名其他角色获得技能【复纂】?',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - if(player.hasUnknown()&&!target.isZhu) return 0; - if(player.getEnemies().includes(target)) return 0; - return get.attitude(player,target); - }); - 'step 2' - if(result.bool){ + "step 1"; + player + .chooseTarget( + "是否减1点体力上限,并令一名其他角色获得技能【复纂】?", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + if (player.hasUnknown() && !target.isZhu) return 0; + if (player.getEnemies().includes(target)) return 0; + return get.attitude(player, target); + }); + "step 2"; + if (result.bool) { player.loseMaxHp(); - var target=result.targets[0]; - player.line(target,'fire'); - target.addSkills('twfuzuan'); + var target = result.targets[0]; + player.line(target, "fire"); + target.addSkills("twfuzuan"); game.delayx(); } }, - derivation:'twfeifu', + derivation: "twfeifu", }, - twfeifu:{ - audio:2, - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + twfeifu: { + audio: 2, + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - zhuanhuanji:true, - forced:true, - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - return (storage?'当你使用【杀】指定唯一目标后':'当你成为【杀】的唯一目标后')+'目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。'; + zhuanhuanji: true, + forced: true, + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + return ( + (storage ? "当你使用【杀】指定唯一目标后" : "当你成为【杀】的唯一目标后") + + "目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。" + ); }, }, - filter:function(event,player,name){ - return event.card.name=='sha'&&event.targets.length==1 - &&event.player.isIn()&&event.target.countCards('he')>0&& - (name=='useCardToPlayered')==Boolean(player.storage.twfeifu); + filter: function (event, player, name) { + return ( + event.card.name == "sha" && + event.targets.length == 1 && + event.player.isIn() && + event.target.countCards("he") > 0 && + (name == "useCardToPlayered") == Boolean(player.storage.twfeifu) + ); }, - logTarget:function(event,player){ - return player.storage.twfeifu?event.target:event.player; + logTarget: function (event, player) { + return player.storage.twfeifu ? event.target : event.player; }, - content:function(){ - 'step 0' - player.changeZhuanhuanji('twfeifu'); - trigger.target.chooseCard('he',true,'非服:交给'+get.translation(trigger.player)+'一张牌','若选择装备牌,则其可以使用此牌'); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - event.card=card; - trigger.target.give(card,trigger.player); - } - else event.finish(); - 'step 2' - var target=trigger.player; - if(target.getCards('h').includes(card)&&get.type(card,target)=='equip'&&target.hasUseTarget(card)) target.chooseUseTarget(card,'nopopup'); + content: function () { + "step 0"; + player.changeZhuanhuanji("twfeifu"); + trigger.target.chooseCard( + "he", + true, + "非服:交给" + get.translation(trigger.player) + "一张牌", + "若选择装备牌,则其可以使用此牌" + ); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; + trigger.target.give(card, trigger.player); + } else event.finish(); + "step 2"; + var target = trigger.player; + if ( + target.getCards("h").includes(card) && + get.type(card, target) == "equip" && + target.hasUseTarget(card) + ) + target.chooseUseTarget(card, "nopopup"); }, }, //Powered by @污言噫对 - twjingce:{ - marktext:"策", - intro:{ - name:"策", - content:"mark", + twjingce: { + marktext: "策", + intro: { + name: "策", + content: "mark", }, - audio:2, - trigger:{player:"useCardAfter"}, - filter:function(event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var history=player.getHistory('useCard',function(evtx){ - return evtx.getParent('phaseUse')==evt; + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var history = player.getHistory("useCard", function (evtx) { + return evtx.getParent("phaseUse") == evt; }); - return history&&history.indexOf(event)==player.hp-1; + return history && history.indexOf(event) == player.hp - 1; }, - frequent:true, - content:function(){ - 'step 0' + frequent: true, + content: function () { + "step 0"; player.draw(2); - 'step 1' - if(player.getHistory('sourceDamage').length||player.getHistory('gain',function(evt){ - return evt.getParent('phaseUse')==trigger.getParent('phaseUse')&&evt.getParent().name=='draw'; - }).length>1) player.addMark('twjingce',1); + "step 1"; + if ( + player.getHistory("sourceDamage").length || + player.getHistory("gain", function (evt) { + return ( + evt.getParent("phaseUse") == trigger.getParent("phaseUse") && + evt.getParent().name == "draw" + ); + }).length > 1 + ) + player.addMark("twjingce", 1); }, }, - yuzhang:{ - audio:2, - trigger:{ - player:"damageEnd", + yuzhang: { + audio: 2, + trigger: { + player: "damageEnd", }, - filter:function(event,player){ - return event.source&&player.hasMark('twjingce'); + filter: function (event, player) { + return event.source && player.hasMark("twjingce"); }, - direct:true, - content:function(){ - 'step 0' - var choiceList=['令'+get.translation(trigger.source)+'本回合不能再使用或打出牌']; - if (trigger.source.countCards('he')) choiceList.push('令'+get.translation(trigger.source)+'弃置两张牌'); - player.chooseControl('cancel2').set('prompt2',get.prompt2('yuzhang')).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,source=_status.event.source; - if(get.attitude(player,source)>=0) return 'cancel2'; - if(source.hasSkillTag('noh')||source.hasSkillTag('noe')||source.countCards('h')>=4) return 0; - if(source.hp>1&&source.countCards('he')>1) return 1; - return [0,1].randomGet(); - }).set('source',trigger.source); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('yuzhang',trigger.source); - player.removeMark('twjingce',1); - if(result.index==0) trigger.source.addTempSkill('yuzhang_dontuse'); - else trigger.source.chooseToDiscard('he',2,true); + direct: true, + content: function () { + "step 0"; + var choiceList = ["令" + get.translation(trigger.source) + "本回合不能再使用或打出牌"]; + if (trigger.source.countCards("he")) + choiceList.push("令" + get.translation(trigger.source) + "弃置两张牌"); + player + .chooseControl("cancel2") + .set("prompt2", get.prompt2("yuzhang")) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + source = _status.event.source; + if (get.attitude(player, source) >= 0) return "cancel2"; + if ( + source.hasSkillTag("noh") || + source.hasSkillTag("noe") || + source.countCards("h") >= 4 + ) + return 0; + if (source.hp > 1 && source.countCards("he") > 1) return 1; + return [0, 1].randomGet(); + }) + .set("source", trigger.source); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("yuzhang", trigger.source); + player.removeMark("twjingce", 1); + if (result.index == 0) trigger.source.addTempSkill("yuzhang_dontuse"); + else trigger.source.chooseToDiscard("he", 2, true); } }, - group:"yuzhang_skip", - subSkill:{ - skip:{ - audio:'yuzhang', - trigger:{ - player:['phaseZhunbeiBefore',"phaseJudgeBefore","phaseDrawBefore","phaseUseBefore","phaseDiscardBefore",'phaseJieshuBefore'], + group: "yuzhang_skip", + subSkill: { + skip: { + audio: "yuzhang", + trigger: { + player: [ + "phaseZhunbeiBefore", + "phaseJudgeBefore", + "phaseDrawBefore", + "phaseUseBefore", + "phaseDiscardBefore", + "phaseJieshuBefore", + ], }, - filter:function(event,player){ - return player.hasMark('twjingce'); + filter: function (event, player) { + return player.hasMark("twjingce"); }, - prompt2:function(event,player){ - var str='弃置一枚“策”并跳过'; - var list=lib.skill.yuzhang.subSkill.skip.trigger.player.slice(); - list=list.map(i=>i.slice(0,-6)); - str+=['准备','判定','摸牌','出牌','弃牌','结束'][list.indexOf(event.name)]; - str+='阶段'; + prompt2: function (event, player) { + var str = "弃置一枚“策”并跳过"; + var list = lib.skill.yuzhang.subSkill.skip.trigger.player.slice(); + list = list.map((i) => i.slice(0, -6)); + str += ["准备", "判定", "摸牌", "出牌", "弃牌", "结束"][list.indexOf(event.name)]; + str += "阶段"; return str; }, - check:function(event,player){ - if(event.name=='phaseDiscard') return player.needsToDiscard(); - if(event.name=='phaseJudge') return player.countCards('j'); + check: function (event, player) { + if (event.name == "phaseDiscard") return player.needsToDiscard(); + if (event.name == "phaseJudge") return player.countCards("j"); return false; }, - content:function(){ - player.removeMark('twjingce',1); + content: function () { + player.removeMark("twjingce", 1); trigger.cancel(); }, }, - dontuse:{ - charlotte:true, - mark:true, - mod:{ - cardEnabled2:function(card){ + dontuse: { + charlotte: true, + mark: true, + mod: { + cardEnabled2: function (card) { return false; }, }, - intro:{ - content:"不能使用或打出牌", + intro: { + content: "不能使用或打出牌", }, }, }, + ai: { + combo: "twjingce", + }, }, - twlihuo:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + twlihuo: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; return false; }, - audio:'lihuo', - prompt2:function(event){ - return '将'+get.translation(event.card)+'改为火属性'; + audio: "lihuo", + prompt2: function (event) { + return "将" + get.translation(event.card) + "改为火属性"; }, - audioname:['re_chengpu'], - check:function(event,player){ - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current)&&get.effect(current,{name:'sha',nature:'fire',cards:event.cards.slice(0)},player,player)>0; + audioname: ["re_chengpu"], + check: function (event, player) { + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + player.canUse(event.card, current) && + get.effect( + current, + { name: "sha", nature: "fire", cards: event.cards.slice(0) }, + player, + player + ) > 0 + ); }); }, - content:function(){ - game.setNature(trigger.card,'fire'); - trigger.card.twlihuo_buffed=true; + content: function () { + game.setNature(trigger.card, "fire"); + trigger.card.twlihuo_buffed = true; }, - group:['twlihuo2','twlihuo3'], - ai:{ - fireAttack:true, + group: ["twlihuo2", "twlihuo3"], + ai: { + fireAttack: true, }, }, - twlihuo2:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha'||!game.hasNature(event.card,'fire')) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current); + twlihuo2: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twlihuo'),'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target); - }).set('sourcex',trigger.targets).set('card',trigger.card).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!_status.connectMode) game.delayx(); - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twlihuo"), + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("card", trigger.card) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !_status.connectMode) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - player.logSkill('twlihuo',event.target); + "step 2"; + player.logSkill("twlihuo", event.target); trigger.targets.push(event.target); }, }, - twlihuo3:{ - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return event.card.twlihuo_buffed=true&&player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card&&evt._dyinged; - }).length>0; + twlihuo3: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return (event.card.twlihuo_buffed = + true && + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card && evt._dyinged; + }).length > 0); }, - forced:true, - audio:'lihuo', - audioname:['re_chengpu'], - content:function(){ + forced: true, + audio: "lihuo", + audioname: ["re_chengpu"], + content: function () { player.loseHp(); - } + }, }, - twchunlao:{ - audio:'chunlao', - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('hej')>0; - })&&!game.hasPlayer(function(current){ - return current.getExpansions('twchunlao').length>0; - }); + twchunlao: { + audio: "chunlao", + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return ( + game.hasPlayer(function (current) { + return current.countCards("hej") > 0; + }) && + !game.hasPlayer(function (current) { + return current.getExpansions("twchunlao").length > 0; + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twchunlao'),'将一名角色区域内的一张牌作为“醇”置于其武将牌上',function(card,player,target){ - return target.countCards('hej')>0; - }).set('ai',function(target){ - return (get.attitude(_status.event.player,target))*(player==target?1:2); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twchunlao',target); - player.choosePlayerCard(target,'hej',true); - } - else event.finish(); - 'step 2' - if(result.bool){ - target.addToExpansion(result.cards,target,'give').gaintag.add('twchunlao'); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twchunlao"), + "将一名角色区域内的一张牌作为“醇”置于其武将牌上", + function (card, player, target) { + return target.countCards("hej") > 0; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) * (player == target ? 1 : 2); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twchunlao", target); + player.choosePlayerCard(target, "hej", true); + } else event.finish(); + "step 2"; + if (result.bool) { + target.addToExpansion(result.cards, target, "give").gaintag.add("twchunlao"); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - group:['twchunlao_sha','twchunlao_dying'], - subSkill:{ - sha:{ - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.player.countCards('he')>0&&event.player.getExpansions('twchunlao').length>0; + group: ["twchunlao_sha", "twchunlao_dying"], + subSkill: { + sha: { + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.player.countCards("he") > 0 && + event.player.getExpansions("twchunlao").length > 0 + ); }, - content:function(){ - 'step 0' - event.target=trigger.player; - event.target.chooseCard('he','醇醪:是否交给'+get.translation(player)+'一张牌,令'+get.translation(trigger.card)+'的伤害值基数+1?').set('ai',function(card){ - if(!_status.event.goon) return 3.5-get.value(card); - return 7-get.value(card); - }).set('goon',function(){ - if(get.attitude(target,player)<0) return false; - var d1=true; - if(trigger.player.hasSkill('jueqing')||trigger.player.hasSkill('gangzhi')) d1=false; - for(var target of trigger.targets){ - if(!target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||trigger.player.hasSkillTag('directHit_ai',true,{ - target:target, - card:trigger.card, - },true)){ - if(!target.hasSkill('gangzhi')) d1=false; - if(!target.hasSkillTag('filterDamage',null,{ - player:trigger.player, - card:trigger.card, - })&&get.attitude(player,target)<0) return true; - } - } - return d1; - }()); - if(!event.target.isUnderControl(true)&&!event.target.isOnline()) game.delayx(); - 'step 1' - if(result.bool){ - target.logSkill('twchunlao',player); - if(!target.hasSkill('twchunlao')) game.trySkillAudio('twchunlao',player); - if(player!=target) target.give(result.cards,player,'giveAuto'); + content: function () { + "step 0"; + event.target = trigger.player; + event.target + .chooseCard( + "he", + "醇醪:是否交给" + + get.translation(player) + + "一张牌,令" + + get.translation(trigger.card) + + "的伤害值基数+1?" + ) + .set("ai", function (card) { + if (!_status.event.goon) return 3.5 - get.value(card); + return 7 - get.value(card); + }) + .set( + "goon", + (function () { + if (get.attitude(target, player) < 0) return false; + var d1 = true; + if ( + trigger.player.hasSkill("jueqing") || + trigger.player.hasSkill("gangzhi") + ) + d1 = false; + for (var target of trigger.targets) { + if ( + !target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + trigger.player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: trigger.card, + }, + true + ) + ) { + if (!target.hasSkill("gangzhi")) d1 = false; + if ( + !target.hasSkillTag("filterDamage", null, { + player: trigger.player, + card: trigger.card, + }) && + get.attitude(player, target) < 0 + ) + return true; + } + } + return d1; + })() + ); + if (!event.target.isUnderControl(true) && !event.target.isOnline()) game.delayx(); + "step 1"; + if (result.bool) { + target.logSkill("twchunlao", player); + if (!target.hasSkill("twchunlao")) game.trySkillAudio("twchunlao", player); + if (player != target) target.give(result.cards, player, "giveAuto"); trigger.baseDamage++; } }, }, - dying:{ - audio:'chunlao', - trigger:{global:'dying'}, - logTarget:'player', - filter:function(event,player){ - return event.player.getExpansions('twchunlao').length>0; + dying: { + audio: "chunlao", + trigger: { global: "dying" }, + logTarget: "player", + filter: function (event, player) { + return event.player.getExpansions("twchunlao").length > 0; }, - prompt2:(event,player)=>('移去'+get.translation(event.player)+'武将牌上的“醇”并摸一张牌,然后令其回复1点体力'), - check:function(event,player){ - return get.attitude(player,event.player)>0; + prompt2: (event, player) => + "移去" + + get.translation(event.player) + + "武将牌上的“醇”并摸一张牌,然后令其回复1点体力", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - content:function(){ - var target=trigger.player,cards=target.getExpansions('twchunlao'); - if(cards.length) target.loseToDiscardpile(cards); + content: function () { + var target = trigger.player, + cards = target.getExpansions("twchunlao"); + if (cards.length) target.loseToDiscardpile(cards); player.draw(); target.recover(); }, @@ -12552,4219 +15862,5241 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //张曼成 - twfengji:{ - audio:2, - mahouSkill:true, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return !player.getExpansions('twfengji').length&&!player.hasSkill('twfengji_mahou')&&player.countCards('he'); + twfengji: { + audio: 2, + mahouSkill: true, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ( + !player.getExpansions("twfengji").length && + !player.hasSkill("twfengji_mahou") && + player.countCards("he") + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt2('twfengji')).set('ai',function(card){ - var name=card.name,num=0; - for(var i=0;i0){ - safe++; - next=next.next; + "step 1"; + if (result.bool) { + player.logSkill("twfengji"); + player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("twfengji"); + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + var player = _status.event.player; + var safe = Math.min( + player.getHandcardLimit(), + player.countCards("h", "shan") + ); + if (safe < Math.min(3, game.countPlayer())) { + var next = player.next; + while (next != player && get.attitude(next, player) > 0) { + safe++; + next = next.next; + } } - } - return Math.max(2,Math.min(safe,3,game.countPlayer()))-1; - }); - } - else event.finish(); - 'step 2' - player.storage.twfengji_mahou=[result.index+1,result.index+1]; - player.addTempSkill('twfengji_mahou',{player:'die'}); + return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1; + }); + } else event.finish(); + "step 2"; + player.storage.twfengji_mahou = [result.index + 1, result.index + 1]; + player.addTempSkill("twfengji_mahou", { player: "die" }); }, - marktext:'示', - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "示", + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - subSkill:{ - mahou:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - var list=player.storage.twfengji_mahou; + subSkill: { + mahou: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + var list = player.storage.twfengji_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的“蜂集”魔法生效'); - player.logSkill('twfengji'); - var cards=player.getExpansions('twfengji'); - if(cards.length){ - var cards2=[],num=list[0]; - for(var card of cards){ - for(var i=0;i0; + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + return player.getExpansions("twfengji").length > 0; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num++; - var cards=player.getExpansions('twfengji'); - if(cards.length) player.loseToDiscardpile(cards); + var cards = player.getExpansions("twfengji"); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - halfneg:true, - combo:'twfengji', + ai: { + halfneg: true, + combo: "twfengji", }, }, - twbudao:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - derivation:['twzhouhu','twharvestinori','twzuhuo','twzhouzu','twhuangjin','twguimen','twdidao'], - limited:true, - skillAnimation:true, - animationColor:'metal', - check:function(event,player){ - return !player.hasUnknown()||!player.hasFriend(); + twbudao: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + derivation: [ + "twzhouhu", + "twharvestinori", + "twzuhuo", + "twzhouzu", + "twhuangjin", + "twguimen", + "twdidao", + ], + limited: true, + skillAnimation: true, + animationColor: "metal", + check: function (event, player) { + return !player.hasUnknown() || !player.hasFriend(); }, - skillValue:{ - twzhouhu:(target)=>Math.random()<0.6?0.1:1, - twzuhuo:(target,player)=>get.damageEffect(target,player,player)>0?0.1:1, - twharvestinori:(target)=>0.9+Math.random()/5, - twhuangjin:(target)=>Math.random()/5, - twguimen:(target)=>Math.sqrt(Math.min(3,target.countCards('he',{suit:'spade'})))*0.09, - twzhouzu:(target)=>{ - var rand=Math.random(); - if(rand<0.8) return 1-Math.sqrt(0.8-rand); + skillValue: { + twzhouhu: (target) => (Math.random() < 0.6 ? 0.1 : 1), + twzuhuo: (target, player) => (get.damageEffect(target, player, player) > 0 ? 0.1 : 1), + twharvestinori: (target) => 0.9 + Math.random() / 5, + twhuangjin: (target) => Math.random() / 5, + twguimen: (target) => + Math.sqrt(Math.min(3, target.countCards("he", { suit: "spade" }))) * 0.09, + twzhouzu: (target) => { + var rand = Math.random(); + if (rand < 0.8) return 1 - Math.sqrt(0.8 - rand); return 1; }, - twdidao:(target,player)=>{ - if([target,player].some(current=>current.getSkills().some(skill=>{ - var info=get.info(skill); - if(!info||!info.ai||!info.ai.rejudge) return false; - return true; - }))){ + twdidao: (target, player) => { + if ( + [target, player].some((current) => + current.getSkills().some((skill) => { + var info = get.info(skill); + if (!info || !info.ai || !info.ai.rejudge) return false; + return true; + }) + ) + ) { return 0.05; } - return 0.85+Math.random()/5; - } + return 0.85 + Math.random() / 5; + }, }, - content:function(){ - 'step 0' - player.awakenSkill('twbudao'); + content: function () { + "step 0"; + player.awakenSkill("twbudao"); player.loseMaxHp(); player.recover(); - var skills=lib.skill.twbudao.derivation,map=lib.skill.twbudao.skillValue; - skills=skills.randomGets(3); - var target=game.filterPlayer().sort((a,b)=>get.attitude(player,b)-get.attitude(player,a))[0]; - if(player.identity=='nei'||get.attitude(player,target)<6) target=player; - player.chooseControl(skills).set('choiceList',skills.map(function(i){ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','布道:选择获得一个技能').set('ai',()=>{ - return _status.event.choice; - }).set('choice',skills.sort((a,b)=>(map[b](target,player)||0.5)-(map[a](target,player)||0.5))[0]); - 'step 1' - var skill=result.control; + var skills = lib.skill.twbudao.derivation, + map = lib.skill.twbudao.skillValue; + skills = skills.randomGets(3); + var target = game + .filterPlayer() + .sort((a, b) => get.attitude(player, b) - get.attitude(player, a))[0]; + if (player.identity == "nei" || get.attitude(player, target) < 6) target = player; + player + .chooseControl(skills) + .set( + "choiceList", + skills.map(function (i) { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "布道:选择获得一个技能") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + skills.sort( + (a, b) => (map[b](target, player) || 0.5) - (map[a](target, player) || 0.5) + )[0] + ); + "step 1"; + var skill = result.control; player.addSkills(skill); - event.twbudao_skill=skill; - player.chooseTarget(lib.filter.notMe,'是否令一名其他角色也获得【'+get.translation(skill)+'】?').set('ai',function(target){ - var player=_status.event.player; - if(player.identity=='nei') return 0; - return get.attitude(player,target); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); + event.twbudao_skill = skill; + player + .chooseTarget( + lib.filter.notMe, + "是否令一名其他角色也获得【" + get.translation(skill) + "】?" + ) + .set("ai", function (target) { + var player = _status.event.player; + if (player.identity == "nei") return 0; + return get.attitude(player, target); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); target.addSkills(event.twbudao_skill); - var cards=target.getCards('he'); - if(!cards.length) event.finish(); - else if(cards.length==1) event._result={bool:true,cards:cards}; - else target.chooseCard('he',true,'交给'+get.translation(player)+'一张牌作为学费'); - } - else event.finish(); - 'step 3' - if(result.bool) target.give(result.cards,player); + var cards = target.getCards("he"); + if (!cards.length) event.finish(); + else if (cards.length == 1) event._result = { bool: true, cards: cards }; + else + target.chooseCard( + "he", + true, + "交给" + get.translation(player) + "一张牌作为学费" + ); + } else event.finish(); + "step 3"; + if (result.bool) target.give(result.cards, player); }, }, - twzhouhu:{ - audio:2, - mahouSkill:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkill('twzhouhu_mahou')&&player.countCards('h',lib.skill.twzhouhu.filterCard)>0; + twzhouhu: { + audio: 2, + mahouSkill: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + !player.hasSkill("twzhouhu_mahou") && + player.countCards("h", lib.skill.twzhouhu.filterCard) > 0 + ); }, - filterCard:{color:'red'}, - check:function(card){ - if(_status.event.player.isHealthy()) return 0; - return 7-get.value(card); + filterCard: { color: "red" }, + check: function (card) { + if (_status.event.player.isHealthy()) return 0; + return 7 - get.value(card); }, - content:function(){ - 'step 0' - player.chooseControl('1回合','2回合','3回合').set('prompt','请选择施法时长').set('ai',function(){ - var player=_status.event.player; - var safe=1; - if(safe0){ - safe++; - next=next.next; + content: function () { + "step 0"; + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + var player = _status.event.player; + var safe = 1; + if (safe < Math.min(3, game.countPlayer(), player.getDamagedHp())) { + var next = player.next; + while (next != player && get.attitude(next, player) > 0) { + safe++; + next = next.next; + } } - } - return Math.max(1,Math.min(safe,3,game.countPlayer(),player.getDamagedHp()))-1; - }); - 'step 1' - player.storage.twzhouhu_mahou=[result.index+1,result.index+1]; - player.addTempSkill('twzhouhu_mahou',{player:'die'}); + return ( + Math.max(1, Math.min(safe, 3, game.countPlayer(), player.getDamagedHp())) - 1 + ); + }); + "step 1"; + player.storage.twzhouhu_mahou = [result.index + 1, result.index + 1]; + player.addTempSkill("twzhouhu_mahou", { player: "die" }); }, - ai:{ - order:2, - result:{ - player:1, + ai: { + order: 2, + result: { + player: 1, }, }, - subSkill:{ - mahou:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - var list=player.storage.twzhouhu_mahou; + subSkill: { + mahou: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + var list = player.storage.twzhouhu_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的“咒护”魔法生效'); - player.logSkill('twzhouhu'); - var num=list[0]; + if (list[1] == 0) { + game.log(player, "的“咒护”魔法生效"); + player.logSkill("twzhouhu"); + var num = list[0]; player.recover(num); - player.removeSkill('twzhouhu_mahou'); - } - else{ - game.log(player,'的“咒护”魔法剩余','#g'+(list[1])+'回合'); - player.markSkill('twzhouhu_mahou'); + player.removeSkill("twzhouhu_mahou"); + } else { + game.log(player, "的“咒护”魔法剩余", "#g" + list[1] + "回合"); + player.markSkill("twzhouhu_mahou"); } }, - mark:true, - onremove:true, - marktext:'♗', - intro:{ - name:'施法:咒护', - markcount:function(storage){ - if(storage) return storage[1]; + mark: true, + onremove: true, + marktext: "♗", + intro: { + name: "施法:咒护", + markcount: function (storage) { + if (storage) return storage[1]; return 0; }, - content:function(storage){ - if(storage){ - return '经过'+storage[1]+'个“回合结束时”后,回复'+storage[0]+'点体力'; + content: function (storage) { + if (storage) { + return ( + "经过" + storage[1] + "个“回合结束时”后,回复" + storage[0] + "点体力" + ); } - return '未指定施法效果'; + return "未指定施法效果"; }, }, }, }, }, - twharvestinori:{ - audio:2, - mahouSkill:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkill('twharvestinori_mahou')&&player.countCards('h',lib.skill.twharvestinori.filterCard)>0; + twharvestinori: { + audio: 2, + mahouSkill: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + !player.hasSkill("twharvestinori_mahou") && + player.countCards("h", lib.skill.twharvestinori.filterCard) > 0 + ); }, - filterCard:{color:'black'}, - check:function(card){ - return 8-get.value(card); + filterCard: { color: "black" }, + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - 'step 0' - player.chooseControl('1回合','2回合','3回合').set('prompt','请选择施法时长').set('ai',function(){ - var player=_status.event.player; - var safe=player.hp; - if(safe0){ - safe++; - next=next.next; + content: function () { + "step 0"; + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + var player = _status.event.player; + var safe = player.hp; + if (safe < Math.min(3, game.countPlayer())) { + var next = player.next; + while (next != player && get.attitude(next, player) > 0) { + safe++; + next = next.next; + } } - } - return Math.max(1,Math.min(safe,3,game.countPlayer()))-1; - }); - 'step 1' - player.storage.twharvestinori_mahou=[result.index+1,result.index+1]; - player.addTempSkill('twharvestinori_mahou',{player:'die'}); + return Math.max(1, Math.min(safe, 3, game.countPlayer())) - 1; + }); + "step 1"; + player.storage.twharvestinori_mahou = [result.index + 1, result.index + 1]; + player.addTempSkill("twharvestinori_mahou", { player: "die" }); }, - ai:{ - order:8, - result:{ - player:1, + ai: { + order: 8, + result: { + player: 1, }, }, - subSkill:{ - mahou:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - var list=player.storage.twharvestinori_mahou; + subSkill: { + mahou: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + var list = player.storage.twharvestinori_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的“丰祈”魔法生效'); - player.logSkill('twharvestinori'); - var num=list[0]*2; + if (list[1] == 0) { + game.log(player, "的“丰祈”魔法生效"); + player.logSkill("twharvestinori"); + var num = list[0] * 2; player.draw(num); - player.removeSkill('twharvestinori_mahou'); - } - else{ - game.log(player,'的“丰祈”魔法剩余','#g'+(list[1])+'回合'); - player.markSkill('twharvestinori_mahou'); + player.removeSkill("twharvestinori_mahou"); + } else { + game.log(player, "的“丰祈”魔法剩余", "#g" + list[1] + "回合"); + player.markSkill("twharvestinori_mahou"); } }, - mark:true, - onremove:true, - marktext:'♗', - intro:{ - name:'施法:丰祈', - markcount:function(storage){ - if(storage) return storage[1]; + mark: true, + onremove: true, + marktext: "♗", + intro: { + name: "施法:丰祈", + markcount: function (storage) { + if (storage) return storage[1]; return 0; }, - content:function(storage){ - if(storage){ - return '经过'+storage[1]+'个“回合结束时”后,摸'+storage[0]*2+'张牌'; + content: function (storage) { + if (storage) { + return ( + "经过" + storage[1] + "个“回合结束时”后,摸" + storage[0] * 2 + "张牌" + ); } - return '未指定施法效果'; + return "未指定施法效果"; }, }, }, }, }, - twzuhuo:{ - audio:2, - mahouSkill:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkill('twzuhuo_mahou')&&player.countCards('he',lib.skill.twzuhuo.filterCard)>0; + twzuhuo: { + audio: 2, + mahouSkill: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + !player.hasSkill("twzuhuo_mahou") && + player.countCards("he", lib.skill.twzuhuo.filterCard) > 0 + ); }, - filterCard:function(card){ - return get.type(card)!='basic'; + filterCard: function (card) { + return get.type(card) != "basic"; }, - position:'he', - check:function(card){ - return 7-get.value(card); + position: "he", + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' - player.chooseControl('1回合','2回合','3回合').set('prompt','请选择施法时长').set('ai',function(){ - var player=_status.event.player; - var safe=Math.min(player.getHandcardLimit(),player.countCards('h','shan')); - if(safe0){ - safe++; - next=next.next; + content: function () { + "step 0"; + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + var player = _status.event.player; + var safe = Math.min(player.getHandcardLimit(), player.countCards("h", "shan")); + if (safe < Math.min(3, game.countPlayer())) { + var next = player.next; + while (next != player && get.attitude(next, player) > 0) { + safe++; + next = next.next; + } } - } - return Math.max(2,Math.min(safe,3,game.countPlayer()))-1; - }); - 'step 1' - player.storage.twzuhuo_mahou=[result.index+1,result.index+1]; - player.addTempSkill('twzuhuo_mahou',{player:'die'}); + return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1; + }); + "step 1"; + player.storage.twzuhuo_mahou = [result.index + 1, result.index + 1]; + player.addTempSkill("twzuhuo_mahou", { player: "die" }); }, - ai:{ - order:2, - result:{ - player:1, + ai: { + order: 2, + result: { + player: 1, }, }, - subSkill:{ - mahou:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - var list=player.storage.twzuhuo_mahou; + subSkill: { + mahou: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + var list = player.storage.twzuhuo_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的“阻祸”魔法生效'); - player.logSkill('twzuhuo'); - var num=list[0]; - player.addSkill('twzuhuo_effect'); - player.addMark('twzuhuo_effect',num,false); - player.removeSkill('twzuhuo_mahou'); - } - else{ - game.log(player,'的“阻祸”魔法剩余','#g'+(list[1])+'回合'); - player.markSkill('twzuhuo_mahou'); + if (list[1] == 0) { + game.log(player, "的“阻祸”魔法生效"); + player.logSkill("twzuhuo"); + var num = list[0]; + player.addSkill("twzuhuo_effect"); + player.addMark("twzuhuo_effect", num, false); + player.removeSkill("twzuhuo_mahou"); + } else { + game.log(player, "的“阻祸”魔法剩余", "#g" + list[1] + "回合"); + player.markSkill("twzuhuo_mahou"); } }, - mark:true, - onremove:true, - marktext:'♗', - intro:{ - name:'施法:阻祸', - markcount:function(storage){ - if(storage) return storage[1]; + mark: true, + onremove: true, + marktext: "♗", + intro: { + name: "施法:阻祸", + markcount: function (storage) { + if (storage) return storage[1]; return 0; }, - content:function(storage){ - if(storage){ - return '经过'+storage[1]+'个“回合结束时”后,获得'+storage[0]+'层“防止一次伤害”的效果'; + content: function (storage) { + if (storage) { + return ( + "经过" + + storage[1] + + "个“回合结束时”后,获得" + + storage[0] + + "层“防止一次伤害”的效果" + ); } - return '未指定施法效果'; + return "未指定施法效果"; }, }, }, - effect:{ - charlotte:true, - onremove:true, - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - return player.hasMark('twzuhuo_effect'); + effect: { + charlotte: true, + onremove: true, + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + return player.hasMark("twzuhuo_effect"); }, - content:function(){ + content: function () { trigger.cancel(); - player.removeMark('twzuhuo_effect',1,false); - if(!player.countMark('twzuhuo_effect')) player.removeSkill('twzuhuo_effect'); + player.removeMark("twzuhuo_effect", 1, false); + if (!player.countMark("twzuhuo_effect")) player.removeSkill("twzuhuo_effect"); }, - marktext:'阻︎', - intro:{ - onremove:true, - content:'防止接下来的#次伤害', + marktext: "阻︎", + intro: { + onremove: true, + content: "防止接下来的#次伤害", }, }, }, }, - twzhouzu:{ - audio:2, - enable:'phaseUse', - usable:1, - mahouSkill:true, - filter:function(event,player){ - return !player.hasSkill('twzhouzu_mahou'); + twzhouzu: { + audio: 2, + enable: "phaseUse", + usable: 1, + mahouSkill: true, + filter: function (event, player) { + return !player.hasSkill("twzhouzu_mahou"); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - line:false, - delay:false, - content:function(){ - 'step 0' - player.chooseControl('1回合','2回合','3回合').set('prompt','请选择施法时长').set('ai',function(){ - var player=_status.event.player; - var safe=1; - if(safe0){ - safe++; - next=next.next; + line: false, + delay: false, + content: function () { + "step 0"; + player + .chooseControl("1回合", "2回合", "3回合") + .set("prompt", "请选择施法时长") + .set("ai", function () { + var player = _status.event.player; + var safe = 1; + if (safe < Math.min(3, game.countPlayer())) { + var next = player.next; + while (next != player && get.attitude(next, player) > 0) { + safe++; + next = next.next; + } } - } - return Math.max(2,Math.min(safe,3,game.countPlayer()))-1; - }); - 'step 1' - player.storage.twzhouzu_mahou=[result.index+1,result.index+1,target]; - player.addTempSkill('twzhouzu_mahou',{player:'die'}); + return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1; + }); + "step 1"; + player.storage.twzhouzu_mahou = [result.index + 1, result.index + 1, target]; + player.addTempSkill("twzhouzu_mahou", { player: "die" }); }, - subSkill:{ - mahou:{ - trigger:{ - global:'phaseEnd', + subSkill: { + mahou: { + trigger: { + global: "phaseEnd", }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - var list=player.storage.twzhouzu_mahou; + forced: true, + popup: false, + charlotte: true, + content: function () { + var list = player.storage.twzhouzu_mahou; list[1]--; - if(list[1]==0){ - game.log(player,'的“咒诅”魔法生效'); - var num=list[0],target=list[2]; - player.logSkill('twzhouzu',target); - target.chooseToDiscard(get.translation(player)+'对你的“咒诅”魔法生效,请弃置'+get.cnNumber(list[0])+'张牌',list[0],true); - target.damage('thunder'); - player.removeSkill('twzhouzu_mahou'); - } - else{ - game.log(player,'的“咒阻”魔法剩余','#g'+(list[1])+'回合'); - player.markSkill('twzhouzu_mahou'); + if (list[1] == 0) { + game.log(player, "的“咒诅”魔法生效"); + var num = list[0], + target = list[2]; + player.logSkill("twzhouzu", target); + target.chooseToDiscard( + get.translation(player) + + "对你的“咒诅”魔法生效,请弃置" + + get.cnNumber(list[0]) + + "张牌", + list[0], + true + ); + target.damage("thunder"); + player.removeSkill("twzhouzu_mahou"); + } else { + game.log(player, "的“咒阻”魔法剩余", "#g" + list[1] + "回合"); + player.markSkill("twzhouzu_mahou"); } }, - mark:true, - onremove:true, - marktext:'♗', - intro:{ - name:'施法:咒诅', - markcount:function(storage){ - if(storage) return storage[1]; + mark: true, + onremove: true, + marktext: "♗", + intro: { + name: "施法:咒诅", + markcount: function (storage) { + if (storage) return storage[1]; return 0; }, - content:function(storage){ - if(storage){ - return '经过'+storage[1]+'个“回合结束时”后,你令'+get.translation(storage[2])+'弃置'+get.cnNumber(storage[0])+'张牌,然后你对其造成1点雷电伤害'; + content: function (storage) { + if (storage) { + return ( + "经过" + + storage[1] + + "个“回合结束时”后,你令" + + get.translation(storage[2]) + + "弃置" + + get.cnNumber(storage[0]) + + "张牌,然后你对其造成1点雷电伤害" + ); } - return '未指定施法效果'; + return "未指定施法效果"; }, - } + }, }, }, - ai:{ - order:1, - result:{ - target:-5, + ai: { + order: 1, + result: { + target: -5, }, - } + }, }, - twhuangjin:{ - audio:2, - trigger:{target:'useCardToTarget'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.card.name=='sha'&&typeof get.number(event.card)=='number'; + twhuangjin: { + audio: 2, + trigger: { target: "useCardToTarget" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return event.card.name == "sha" && typeof get.number(event.card) == "number"; }, - content:function(){ - 'step 0' - player.judge(function(result){ - var evt=_status.event.getTrigger(); - if(Math.abs(get.number(result)-get.number(evt.card))<=1) return 2; + content: function () { + "step 0"; + player.judge(function (result) { + var evt = _status.event.getTrigger(); + if (Math.abs(get.number(result) - get.number(evt.card)) <= 1) return 2; return -1; - }).judge2=function(result){ + }).judge2 = function (result) { return result.bool; }; - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.getParent().excluded.add(player); } }, - ai:{ - effect:{ - target:function(card,player,target,current,isLink){ - if(card.name=='sha'&&!isLink) return 0.8; + ai: { + effect: { + target: function (card, player, target, current, isLink) { + if (card.name == "sha" && !isLink) return 0.8; }, }, }, }, - twguimen:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + twguimen: { + audio: 2, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - direct:true, - filter:function(event,player){ - if(event.type!='discard') return false; - var evt=event.getl(player); - for(var card of evt.cards2){ - if(get.suit(card,player)=='spade') return true; + direct: true, + filter: function (event, player) { + if (event.type != "discard") return false; + var evt = event.getl(player); + for (var card of evt.cards2) { + if (get.suit(card, player) == "spade") return true; } return false; }, - forced:true, - content:function(){ - 'step 0' - var cards=[]; - var evt=trigger.getl(player); - for(var card of evt.cards2){ - if(get.suit(card,player)=='spade') cards.push(card); + forced: true, + content: function () { + "step 0"; + var cards = []; + var evt = trigger.getl(player); + for (var card of evt.cards2) { + if (get.suit(card, player) == "spade") cards.push(card); } - if(!cards.length) event.finish(); - else event.cards=cards; - 'step 1' - if(event.cards.length==1){ - event._result={bool:true,links:event.cards}; + if (!cards.length) event.finish(); + else event.cards = cards; + "step 1"; + if (event.cards.length == 1) { + event._result = { bool: true, links: event.cards }; + } else { + player.chooseButton(["鬼门:选择一张♠牌,为其进行判定", event.cards], true); } - else{ - player.chooseButton(['鬼门:选择一张♠牌,为其进行判定',event.cards],true); - } - 'step 2' - if(result.bool&&result.links){ - event.judgingSpade=result.links[0]; + "step 2"; + if (result.bool && result.links) { + event.judgingSpade = result.links[0]; event.cards.remove(event.judgingSpade); - game.log(player,'选择','#y'+get.translation(event.judgingSpade),'进行判定'); - player.judge(function(result){ - var card=_status.event.getParent().judgingSpade; - if(Math.abs(get.number(result)-get.number(card))<=1) return 4; + game.log(player, "选择", "#y" + get.translation(event.judgingSpade), "进行判定"); + player.judge(function (result) { + var card = _status.event.getParent().judgingSpade; + if (Math.abs(get.number(result) - get.number(card)) <= 1) return 4; return -1; - }).judge2=function(result){ + }).judge2 = function (result) { return result.bool; }; } else event.finish(); - 'step 3' - if(result.bool&&game.hasPlayer(current=>current!=player)){ - player.chooseTarget('选择一名其他角色,对其造成2点雷电伤害',lib.filter.notMe,true).set('ai',target=>get.damageEffect(target,player,player,'thunder')); + "step 3"; + if (result.bool && game.hasPlayer((current) => current != player)) { + player + .chooseTarget("选择一名其他角色,对其造成2点雷电伤害", lib.filter.notMe, true) + .set("ai", (target) => get.damageEffect(target, player, player, "thunder")); } - 'step 4' - if(result.bool){ - player.line(result.targets[0],'thunder'); - result.targets[0].damage(2,'thunder'); + "step 4"; + if (result.bool) { + player.line(result.targets[0], "thunder"); + result.targets[0].damage(2, "thunder"); } - if(event.cards.length) event.goto(1); - } - }, - twdidao:{ - audio:2, - trigger:{global:'judge'}, - filter:function(event,player){ - return player.countCards('hes'); + if (event.cards.length) event.goto(1); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为' + - get.translation(trigger.player.judging[0])+','+get.prompt('twdidao'),'hes',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0){ - if(trigger.player!=player) return 0; - var checkx=get.color(card,player)==get.color(judging); - if(checkx>0) return checkx; + }, + twdidao: { + audio: 2, + trigger: { global: "judge" }, + filter: function (event, player) { + return player.countCards("hes"); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("twdidao"), + "hes", + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) { + if (trigger.player != player) return 0; + var checkx = get.color(card, player) == get.color(judging); + if (checkx > 0) return checkx; return 0; } - return result*(attitude>0?1:-1); - }).set('judging',trigger.player.judging[0]); - 'step 1' - if(result.bool){ - player.respond(result.cards,'highlight','twdidao','noOrdering'); - } - else{ + return result * (attitude > 0 ? 1 : -1); + }) + .set("judging", trigger.player.judging[0]); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "twdidao", "noOrdering"); + } else { event.finish(); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - var card=result.cards[0]; - if(get.color(card,player)==get.color(trigger.player.judging[0])) player.draw('nodelay'); - trigger.player.judging[0]=result.cards[0]; + var card = result.cards[0]; + if (get.color(card, player) == get.color(trigger.player.judging[0])) + player.draw("nodelay"); + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); } - 'step 3' + "step 3"; game.delay(2); }, - ai:{ - rejudge:true, - tag:{ - rejudge:1 - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, //群曹操 - twlingfa:{ - audio:2, - trigger:{global:'roundStart'}, - direct:true, - content:function(){ - 'step 0' - if(game.roundNumber<3||!player.hasSkill('twlingfa')){ + twlingfa: { + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + content: function () { + "step 0"; + if (game.roundNumber < 3 || !player.hasSkill("twlingfa")) { var str; - switch(game.roundNumber){ - case 1:str='获得如下效果直到本轮结束:其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。';break; - case 2:str='获得如下效果直到本轮结束:其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。';break; - default:str='失去【令法】并获得【治暗】';break; - } - player.chooseBool(get.prompt('twlingfa'),str); - } - else event._result={bool:true}; - 'step 1' - if(result.bool){ - switch(game.roundNumber){ + switch (game.roundNumber) { case 1: - player.logSkill('twlingfa',game.filterPlayer((current)=>current!=player).sortBySeat()); - player.addTempSkill('twlingfa_sha','roundStart'); + str = + "获得如下效果直到本轮结束:其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。"; break; case 2: - player.logSkill('twlingfa',game.filterPlayer((current)=>current!=player).sortBySeat()); - player.addTempSkill('twlingfa_tao','roundStart'); + str = + "获得如下效果直到本轮结束:其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。"; break; default: - player.logSkill('twlingfa'); - player.addSkills(['twzhian'],['twlingfa']); + str = "失去【令法】并获得【治暗】"; + break; + } + player.chooseBool(get.prompt("twlingfa"), str); + } else event._result = { bool: true }; + "step 1"; + if (result.bool) { + switch (game.roundNumber) { + case 1: + player.logSkill( + "twlingfa", + game.filterPlayer((current) => current != player).sortBySeat() + ); + player.addTempSkill("twlingfa_sha", "roundStart"); + break; + case 2: + player.logSkill( + "twlingfa", + game.filterPlayer((current) => current != player).sortBySeat() + ); + player.addTempSkill("twlingfa_tao", "roundStart"); + break; + default: + player.logSkill("twlingfa"); + player.addSkills(["twzhian"], ["twlingfa"]); break; } } }, - subSkill:{ - sha:{ - audio:'twlingfa', - trigger:{global:'useCard'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player!=event.player&&event.card.name=='sha'&&event.player.countCards('he')>0; + subSkill: { + sha: { + audio: "twlingfa", + trigger: { global: "useCard" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return ( + player != event.player && + event.card.name == "sha" && + event.player.countCards("he") > 0 + ); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; game.delayx(); - trigger.player.chooseToDiscard('he','令法:弃置一张牌,或受到来自'+get.translation(player)+'的1点伤害').set('goon',get.damageEffect(trigger.player,player,trigger.player)<0).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 8-get.value(card); - }); - 'step 1' - if(!result.bool){ + trigger.player + .chooseToDiscard( + "he", + "令法:弃置一张牌,或受到来自" + get.translation(player) + "的1点伤害" + ) + .set("goon", get.damageEffect(trigger.player, player, trigger.player) < 0) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 8 - get.value(card); + }); + "step 1"; + if (!result.bool) { trigger.player.damage(); } }, - mark:true, - marktext:'', - intro:{content:'其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。'}, + mark: true, + marktext: '', + intro: { + content: + "其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。", + }, }, - tao:{ - audio:'twlingfa', - trigger:{global:'useCard'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player!=event.player&&event.card.name=='tao'&&event.player.countCards('he')>0; + tao: { + audio: "twlingfa", + trigger: { global: "useCard" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return ( + player != event.player && + event.card.name == "tao" && + event.player.countCards("he") > 0 + ); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; game.delayx(); - trigger.player.chooseCard('he','令法:交给'+get.translation(player)+'一张牌,否则受到来自其的1点伤害').set('goon',get.damageEffect(trigger.player,player,trigger.player)<0).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 8-get.value(card); - }); - 'step 1' - if(!result.bool){ + trigger.player + .chooseCard( + "he", + "令法:交给" + get.translation(player) + "一张牌,否则受到来自其的1点伤害" + ) + .set("goon", get.damageEffect(trigger.player, player, trigger.player) < 0) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 8 - get.value(card); + }); + "step 1"; + if (!result.bool) { trigger.player.damage(); - } - else trigger.player.give(result.cards,player); + } else trigger.player.give(result.cards, player); + }, + mark: true, + marktext: '', + intro: { + content: + "其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。", }, - mark:true, - marktext:'', - intro:{content:'其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。'}, }, }, - derivation:'twzhian', + derivation: "twzhian", }, - twzhian:{ - audio:2, - init:function(player){ - game.addGlobalSkill('twzhian_ai'); + twzhian: { + audio: 2, + init: function (player) { + game.addGlobalSkill("twzhian_ai"); }, - onremove:function(player){ - if(!game.hasPlayer((current)=>current.hasSkill('twzhian'),true)) game.removeGlobalSkill('twzhian_ai'); + onremove: function (player) { + if (!game.hasPlayer((current) => current.hasSkill("twzhian"), true)) + game.removeGlobalSkill("twzhian_ai"); }, - usable:1, - trigger:{global:'useCardAfter'}, - direct:true, - filter:function(event,player){ - var type=get.type(event.card); - if(type!='delay'&&type!='equip') return false; - if(event.cards.length!=1) return false; - var position=get.position(event.cards[0]); - if(position=='e'||position=='j') return true; + usable: 1, + trigger: { global: "useCardAfter" }, + direct: true, + filter: function (event, player) { + var type = get.type(event.card); + if (type != "delay" && type != "equip") return false; + if (event.cards.length != 1) return false; + var position = get.position(event.cards[0]); + if (position == "e" || position == "j") return true; return event.player.isIn(); }, - content:function(){ - 'step 0' - var str=get.translation(trigger.cards[0]),owner=get.owner(trigger.cards[0]); - var choiceList=[ - '弃置'+(owner?(get.translation(owner)+'区域内的'):'')+str, - '弃置一张手牌并获得'+str, - '对'+get.translation(trigger.player)+'造成1点伤害', + content: function () { + "step 0"; + var str = get.translation(trigger.cards[0]), + owner = get.owner(trigger.cards[0]); + var choiceList = [ + "弃置" + (owner ? get.translation(owner) + "区域内的" : "") + str, + "弃置一张手牌并获得" + str, + "对" + get.translation(trigger.player) + "造成1点伤害", ]; - var choices=[]; - if(owner&&lib.filter.canBeDiscarded(card,player,owner)) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(owner&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'twzhian'); - },'h')&&lib.filter.canBeGained(card,player,owner)) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(trigger.player.isIn()) choices.push('选项三'); - else choiceList[2]=''+choiceList[2]+''; - player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('prompt',get.prompt('twzhian')).set('ai',function(){ - var player=_status.event.player,choices=_status.event.controls.slice(0); - var card=_status.event.getTrigger().cards[0],owner=get.owner(card); - var getEffect=function(choice){ - if(choice=='cancel2') return 0.1; - if(choice=='选项三'){ - return get.damageEffect(_status.event.getTrigger().player,player,player); - } - var result; - if(get.position(card)=='j'){ - result=-get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)*get.sgn(get.attitude(player,owner)); - } - else result=-(get.value(card,owner)-0.01)*get.sgn(get.attitude(player,owner)); - if(choice=='选项一') return result; - if(player.hasCard(function(cardx){ - return lib.filter.cardDiscardable(cardx,player,'twzhian')&&get.value(cardx,player)"; + if ( + owner && + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "twzhian"); + }, "h") && + lib.filter.canBeGained(card, player, owner) + ) + choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (trigger.player.isIn()) choices.push("选项三"); + else choiceList[2] = '' + choiceList[2] + ""; + player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("twzhian")) + .set("ai", function () { + var player = _status.event.player, + choices = _status.event.controls.slice(0); + var card = _status.event.getTrigger().cards[0], + owner = get.owner(card); + var getEffect = function (choice) { + if (choice == "cancel2") return 0.1; + if (choice == "选项三") { + return get.damageEffect( + _status.event.getTrigger().player, + player, + player + ); + } + var result; + if (get.position(card) == "j") { + result = + -get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) * get.sgn(get.attitude(player, owner)); + } else + result = + -(get.value(card, owner) - 0.01) * + get.sgn(get.attitude(player, owner)); + if (choice == "选项一") return result; + if ( + player.hasCard(function (cardx) { + return ( + lib.filter.cardDiscardable(cardx, player, "twzhian") && + get.value(cardx, player) < get.value(card, player) + ); + }, "h") + ) + return result * 1.2; + return 0; + }; + choices.sort(function (a, b) { + return getEffect(b) - getEffect(a); + }); + return choices[0]; }); - return choices[0]; - }); - 'step 1' - if(result.control!='cancel2'){ - var card=trigger.cards[0],owner=get.owner(card); - switch(result.control){ - case '选项一': - player.logSkill('twzhian',owner); - owner.discard(card,'notBySelf'); + "step 1"; + if (result.control != "cancel2") { + var card = trigger.cards[0], + owner = get.owner(card); + switch (result.control) { + case "选项一": + player.logSkill("twzhian", owner); + owner.discard(card, "notBySelf"); event.finish(); break; - case '选项二': - player.chooseToDiscard('h',true).logSkill=['twzhian',owner]; - event.target=owner; + case "选项二": + player.chooseToDiscard("h", true).logSkill = ["twzhian", owner]; + event.target = owner; break; - case '选项三': - player.logSkill('twzhian',trigger.player); + case "选项三": + player.logSkill("twzhian", trigger.player); trigger.player.damage(); event.finish(); break; } - } - else player.storage.counttrigger.twzhian--; - 'step 2' - if(result.bool&&target.getCards('ej').includes(trigger.cards[0])) player.gain(trigger.cards,target,'give','bySelf'); + } else player.storage.counttrigger.twzhian--; + "step 2"; + if (result.bool && target.getCards("ej").includes(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); + 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'); + 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]; - } - } - } - } - } + 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, - global:'twyujue_give', - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + twyujue: { + audio: 2, + global: "twyujue_give", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - direct:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - var cards=event.getg(player); - if(!cards.length) return false; - return game.hasPlayer(function(current){ - if(current==player) return false; - var evt=event.getl(current); - if(!evt||!evt.cards2||!evt.cards2.filter((card)=>cards.includes(card)).length) return false; - return (!current.hasSkill('twyujue_effect0'))||(!current.hasSkill('twyujue_effect1')); - }) + direct: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + var cards = event.getg(player); + if (!cards.length) return false; + return game.hasPlayer(function (current) { + if (current == player) return false; + var evt = event.getl(current); + if (!evt || !evt.cards2 || !evt.cards2.filter((card) => cards.includes(card)).length) + return false; + return !current.hasSkill("twyujue_effect0") || !current.hasSkill("twyujue_effect1"); + }); }, - content:function(){ - 'step 0' - var cards=trigger.getg(player); - var list=game.filterPlayer(function(current){ - if(current==player) return false; - var evt=trigger.getl(current); - if(!evt||!evt.cards2||!evt.cards2.filter((card)=>cards.includes(card)).length) return false; - return (!current.hasSkill('twyujue_effect0'))||(!current.hasSkill('twyujue_effect1')); - }).sortBySeat(); - event.targets=list; - 'step 1' - var target=event.targets.shift(); - if(target.isIn()){ - event.target=target; - var num=2; - if(target.hasSkill('twyujue_effect0')) num--; - if(target.hasSkill('twyujue_effect1')) num--; - var cards=trigger.getg(player); - num=Math.min(num,trigger.getl(target).cards2.filter(i=>cards.includes(i)).length); - if(num>0) event.count=num; - else if(targets.length>0) event.redo(); + content: function () { + "step 0"; + var cards = trigger.getg(player); + var list = game + .filterPlayer(function (current) { + if (current == player) return false; + var evt = trigger.getl(current); + if ( + !evt || + !evt.cards2 || + !evt.cards2.filter((card) => cards.includes(card)).length + ) + return false; + return ( + !current.hasSkill("twyujue_effect0") || !current.hasSkill("twyujue_effect1") + ); + }) + .sortBySeat(); + event.targets = list; + "step 1"; + var target = event.targets.shift(); + if (target.isIn()) { + event.target = target; + var num = 2; + if (target.hasSkill("twyujue_effect0")) num--; + if (target.hasSkill("twyujue_effect1")) num--; + var cards = trigger.getg(player); + num = Math.min( + num, + trigger.getl(target).cards2.filter((i) => cards.includes(i)).length + ); + if (num > 0) event.count = num; + else if (targets.length > 0) event.redo(); else event.finish(); - } - else if(targets.length>0) event.redo(); + } else if (targets.length > 0) event.redo(); else event.finish(); - 'step 2' + "step 2"; event.count--; - player.chooseBool(get.prompt('twyujue',target),'可令其选择本回合内未选择过的一项:⒈弃置攻击范围内一名角色的一张牌。⒉下一次使用牌时,从牌堆中获得一张同类别的牌。').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0; - }); - 'step 3' - if(result.bool){ - player.logSkill('twyujue',target); - var list=[0,1]; - if(target.hasSkill('twyujue_effect0')) list.remove(0); - if(target.hasSkill('twyujue_effect1')) list.remove(1); - if(!list.length) event.goto(6); - else if(list.length==1) event._result={index:list[0]}; - else target.chooseControl().set('choiceList',['弃置攻击范围内一名角色的一张牌','下一次使用牌时,从牌堆中获得一张同类别的牌']).set('ai',function(){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return player.inRange(current)&¤t.countDiscardableCards(player,'he')>0&&get.effect(current,{name:'guohe_copy2'},player,player)>0; - })) return 0; - return 1; + player + .chooseBool( + get.prompt("twyujue", target), + "可令其选择本回合内未选择过的一项:⒈弃置攻击范围内一名角色的一张牌。⒉下一次使用牌时,从牌堆中获得一张同类别的牌。" + ) + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 0; }); + "step 3"; + if (result.bool) { + player.logSkill("twyujue", target); + var list = [0, 1]; + if (target.hasSkill("twyujue_effect0")) list.remove(0); + if (target.hasSkill("twyujue_effect1")) list.remove(1); + if (!list.length) event.goto(6); + else if (list.length == 1) event._result = { index: list[0] }; + else + target + .chooseControl() + .set("choiceList", [ + "弃置攻击范围内一名角色的一张牌", + "下一次使用牌时,从牌堆中获得一张同类别的牌", + ]) + .set("ai", function () { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + player.inRange(current) && + current.countDiscardableCards(player, "he") > 0 && + get.effect(current, { name: "guohe_copy2" }, player, player) > + 0 + ); + }) + ) + return 0; + return 1; + }); + } else event.goto(6); + "step 4"; + target.addTempSkill("twyujue_effect" + result.index); + if (result.index == 0) { + if ( + game.hasPlayer(function (current) { + return ( + target.inRange(current) && current.countDiscardableCards(target, "he") > 0 + ); + }) + ) { + target + .chooseTarget( + "弃置攻击范围内一名角色的一张牌", + true, + function (card, player, target) { + return ( + player.inRange(target) && + target.countDiscardableCards(player, "he") > 0 + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + } else event.goto(6); + } else event.goto(6); + "step 5"; + if (result.bool) { + var target2 = result.targets[0]; + target.line(target2, "green"); + target.discardPlayerCard(target2, "he", true); } - else event.goto(6); - 'step 4' - target.addTempSkill('twyujue_effect'+result.index); - if(result.index==0){ - if(game.hasPlayer(function(current){ - return target.inRange(current)&¤t.countDiscardableCards(target,'he')>0; - })){ - target.chooseTarget('弃置攻击范围内一名角色的一张牌',true,function(card,player,target){ - return player.inRange(target)&&target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player) - }); - } - else event.goto(6); - } - else event.goto(6); - 'step 5' - if(result.bool){ - var target2=result.targets[0]; - target.line(target2,'green'); - target.discardPlayerCard(target2,'he',true); - } - 'step 6' + "step 6"; game.delayx(); - if(event.count>0) event.goto(2); - else if(targets.length) event.goto(1); + if (event.count > 0) event.goto(2); + else if (targets.length) event.goto(1); }, - subSkill:{ - clear:{ - onremove:true, + subSkill: { + clear: { + onremove: true, }, - effect0:{charlotte:true}, - effect1:{ - charlotte:true, - trigger:{player:'useCard'}, - usable:1, - forced:true, - popup:false, - content:function(){ - player.unmarkSkill('twyujue_effect1'); - var type2=get.type2(trigger.card,false); - var card=get.cardPile2(function(card){ - return get.type2(card,false)==type2; + effect0: { charlotte: true }, + effect1: { + charlotte: true, + trigger: { player: "useCard" }, + usable: 1, + forced: true, + popup: false, + content: function () { + player.unmarkSkill("twyujue_effect1"); + var type2 = get.type2(trigger.card, false); + var card = get.cardPile2(function (card) { + return get.type2(card, false) == type2; }); - if(card) trigger.player.gain(card,'gain2'); + if (card) trigger.player.gain(card, "gain2"); }, - mark:true, - marktext:'爵', - intro:{content:'使用下一张牌时,从牌堆中获得一张类型相同的牌'}, + mark: true, + marktext: "爵", + intro: { content: "使用下一张牌时,从牌堆中获得一张类型相同的牌" }, }, }, }, - twyujue_give:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(!player.countCards('he')) return false; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('twyujue'); + twyujue_give: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (!player.countCards("he")) return false; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("twyujue"); }); - if(!targets.length) return false; - for(var target of targets){ - var num=2; - if(player.group=='qun'&&target.hasZhuSkill('twfengqi',player)) num=4; - if(target.countMark('twyujue_clear')=Math.max(1,ui.selected.cards.length); + filterCard: true, + filterTarget: function (card, player, target) { + if (!target.hasSkill("twyujue")) return false; + var num = 2; + if (player.group == "qun" && target.hasZhuSkill("twfengqi", player)) num = 4; + return num - target.countMark("twyujue_clear") >= Math.max(1, ui.selected.cards.length); }, - selectTarget:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('twyujue'); + selectTarget: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("twyujue"); }); - return targets.length>1?1:-1; + return targets.length > 1 ? 1 : -1; }, - complexSelect:true, - prompt:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('twyujue'); + complexSelect: true, + prompt: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("twyujue"); }); - return '将任意张牌交给'+get.translation(targets)+(targets.length>1?'中的一人':''); + return ( + "将任意张牌交给" + get.translation(targets) + (targets.length > 1 ? "中的一人" : "") + ); }, - position:'he', - discard:false, - lose:false, - delay:false, - check:function(card){ - if(ui.selected.cards.length) return 0; - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return lib.skill.twyujue_give.filterTarget(null,player,current)&&get.attitude(player,current)>0; - })){ - var val=get.value(card); - if(val<=0&&get.position(card)=='e') return 100-val; - if(!player.hasSkill('twyujue_effect1')&&player.hasCard(function(cardx){ - return cardx!=card&&player.getUseValue(cardx,null,true)>0; - },'hs')) return 6-get.value(card); - if(!player.hasSkill('twyujue_effect0')&&game.hasPlayer(function(current){ - return player.inRange(current)&¤t.countDiscardableCards(player,'he')>0&&get.effect(current,{name:'guohe_copy2'},player,player)>0; - })) return 5.5-get.value(card); + position: "he", + discard: false, + lose: false, + delay: false, + check: function (card) { + if (ui.selected.cards.length) return 0; + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + lib.skill.twyujue_give.filterTarget(null, player, current) && + get.attitude(player, current) > 0 + ); + }) + ) { + var val = get.value(card); + if (val <= 0 && get.position(card) == "e") return 100 - val; + if ( + !player.hasSkill("twyujue_effect1") && + player.hasCard(function (cardx) { + return cardx != card && player.getUseValue(cardx, null, true) > 0; + }, "hs") + ) + return 6 - get.value(card); + if ( + !player.hasSkill("twyujue_effect0") && + game.hasPlayer(function (current) { + return ( + player.inRange(current) && + current.countDiscardableCards(player, "he") > 0 && + get.effect(current, { name: "guohe_copy2" }, player, player) > 0 + ); + }) + ) + return 5.5 - get.value(card); } return 0; }, - content:function(){ - game.trySkillAudio('twyujue',target); - player.give(cards,target); - target.addTempSkill('twyujue_clear'); - target.addMark('twyujue_clear',cards.length,false); + content: function () { + game.trySkillAudio("twyujue", target); + player.give(cards, target); + target.addTempSkill("twyujue_clear"); + target.addMark("twyujue_clear", cards.length, false); }, - ai:{ - order:10, - result:{target:1}, + ai: { + order: 10, + result: { target: 1 }, }, }, - twgezhi:{ - audio:2, - trigger:{player:'useCard'}, - direct:true, - filter:function(event,player){ - if(!player.countCards('h')) return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var type=get.type2(event.card,false); - return !player.hasHistory('useCard',function(evtx){ - return evtx!=event&&get.type2(evtx.card,false)==type&&evtx.getParent('phaseUse')==evt; - },event); + twgezhi: { + audio: 2, + trigger: { player: "useCard" }, + direct: true, + filter: function (event, player) { + if (!player.countCards("h")) return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var type = get.type2(event.card, false); + return !player.hasHistory( + "useCard", + function (evtx) { + return ( + evtx != event && + get.type2(evtx.card, false) == type && + evtx.getParent("phaseUse") == evt + ); + }, + event + ); }, - content:function(){ - 'step 0' - if(!event.isMine()&&!event.isOnline()) game.delayx(); - player.chooseCard('是否发动【革制】重铸一张牌?',lib.filter.cardRecastable).set('ai',function(card){ - return 5.5-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('twgezhi'); + content: function () { + "step 0"; + if (!event.isMine() && !event.isOnline()) game.delayx(); + player + .chooseCard("是否发动【革制】重铸一张牌?", lib.filter.cardRecastable) + .set("ai", function (card) { + return 5.5 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("twgezhi"); player.recast(result.cards); } }, - group:'twgezhi_buff', - subSkill:{ - buff:{ - audio:'twgezhi', - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - return evt.getParent(3).name=='twgezhi'&&evt.getParent('phaseUse')==event; - }).length>1; + group: "twgezhi_buff", + subSkill: { + buff: { + audio: "twgezhi", + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return ( + player.getHistory("lose", function (evt) { + return ( + evt.getParent(3).name == "twgezhi" && + evt.getParent("phaseUse") == event + ); + }).length > 1 + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('twgezhi'),'你可以令一名角色选择获得一个其未获得过的效果:⒈攻击范围+2;⒉手牌上限+2;⒊加1点体力上限。',function(card,player,target){ - return !target.hasSkill('twgezhi_选项一')||!target.hasSkill('twgezhi_选项二')||!target.hasSkill('twgezhi_选项三'); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('twgezhi',target); - var list=[]; - for(var i=1;i<=3;i++){ - var str='选项'+get.cnNumber(i,true); - if(!target.hasSkill('twgezhi_'+str)) list.push(str); - } - if(list.length==1) event._result={control:list[0]}; - else target.chooseControl(list).set('choiceList',['令自己的攻击范围+2','令自己的手牌上限+2','令自己的体力上限+1']).set('ai',function(){ - var player=_status.event.player,controls=_status.event.controls; - if(controls.includes('选项一')&&game.hasPlayer(function(current){ - return (get.realAttitude||get.attitude)(player,current)<0&&get.distance(player,current,'attack')>1; - })) return '选项一'; - if(controls.includes('选项二')&&player.needsToDiscard()) return '选项二'; - if(controls.includes('选项三')) return '选项三'; - return controls.randomGet(); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("twgezhi"), + "你可以令一名角色选择获得一个其未获得过的效果:⒈攻击范围+2;⒉手牌上限+2;⒊加1点体力上限。", + function (card, player, target) { + return ( + !target.hasSkill("twgezhi_选项一") || + !target.hasSkill("twgezhi_选项二") || + !target.hasSkill("twgezhi_选项三") + ); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); }); - } - else{ - event._triggered=null; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("twgezhi", target); + var list = []; + for (var i = 1; i <= 3; i++) { + var str = "选项" + get.cnNumber(i, true); + if (!target.hasSkill("twgezhi_" + str)) list.push(str); + } + if (list.length == 1) event._result = { control: list[0] }; + else + target + .chooseControl(list) + .set("choiceList", [ + "令自己的攻击范围+2", + "令自己的手牌上限+2", + "令自己的体力上限+1", + ]) + .set("ai", function () { + var player = _status.event.player, + controls = _status.event.controls; + if ( + controls.includes("选项一") && + game.hasPlayer(function (current) { + return ( + (get.realAttitude || get.attitude)(player, current) < + 0 && get.distance(player, current, "attack") > 1 + ); + }) + ) + return "选项一"; + if (controls.includes("选项二") && player.needsToDiscard()) + return "选项二"; + if (controls.includes("选项三")) return "选项三"; + return controls.randomGet(); + }); + } else { + event._triggered = null; event.finish(); } - 'step 2' - target.addSkill('twgezhi_'+result.control); - if(result.control=='选项三') target.gainMaxHp(); - 'step 3' + "step 2"; + target.addSkill("twgezhi_" + result.control); + if (result.control == "选项三") target.gainMaxHp(); + "step 3"; game.delayx(); }, }, - 选项一:{ - charlotte:true, - mod:{ - attackFrom:function(from,to,distance){ - return distance-2; + 选项一: { + charlotte: true, + mod: { + attackFrom: function (from, to, distance) { + return distance - 2; }, }, - mark:true, - marktext:' +2 ', - intro:{content:'攻击范围+2'}, + mark: true, + marktext: " +2 ", + intro: { content: "攻击范围+2" }, }, - 选项二:{ - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+2; + 选项二: { + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + 2; }, }, - mark:true, - marktext:' +2 ', - intro:{content:'手牌上限+2'}, + mark: true, + marktext: " +2 ", + intro: { content: "手牌上限+2" }, }, - 选项三:{ - charlotte:true, - mark:true, - marktext:' +1 ', - intro:{content:'体力上限+1'}, + 选项三: { + charlotte: true, + mark: true, + marktext: " +1 ", + intro: { content: "体力上限+1" }, }, }, }, - twfengqi:{ - audio:2, - zhuSkill:true, - trigger:{player:'twgezhi_buffAfter'}, - direct:true, - filter:function(event,player){ - if(!event.target||!event.target.isIn()||!player.hasZhuSkill('twfengqi',event.target)) return false; - var target=event.target; - return target.getStockSkills(true,true).some(skill=>{ - if(target.hasSkill(skill)) return false; - var info=get.info(skill); - return info&&info.zhuSkill; + twfengqi: { + audio: 2, + zhuSkill: true, + trigger: { player: "twgezhi_buffAfter" }, + direct: true, + filter: function (event, player) { + if ( + !event.target || + !event.target.isIn() || + !player.hasZhuSkill("twfengqi", event.target) + ) + return false; + var target = event.target; + return target.getStockSkills(true, true).some((skill) => { + if (target.hasSkill(skill)) return false; + var info = get.info(skill); + return info && info.zhuSkill; }); }, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - event.target=trigger.target; - event.target.chooseBool(get.prompt('twfengqi'),'获得武将牌上的所有主公技'); - 'step 1' - if(result.bool){ - target.logSkill('twfengqi',player); - var skills=target.getStockSkills(true,true).filter(skill=>{ - if(target.hasSkill(skill)) return false; - var info=get.info(skill); - return info&&info.zhuSkill; + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + event.target = trigger.target; + event.target.chooseBool(get.prompt("twfengqi"), "获得武将牌上的所有主公技"); + "step 1"; + if (result.bool) { + target.logSkill("twfengqi", player); + var skills = target.getStockSkills(true, true).filter((skill) => { + if (target.hasSkill(skill)) return false; + var info = get.info(skill); + return info && info.zhuSkill; }); target.addSkills(skills); //for(var i of skills) target.addSkillLog(i); } }, }, - twsidai:{ - audio:2, - enable:'phaseUse', - usable:1, - locked:false, - limited:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - var cards=player.getCards('h',{type:'basic'}); - if(!cards.length) return false; - for(var i of cards){ - if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) return false; + twsidai: { + audio: 2, + enable: "phaseUse", + usable: 1, + locked: false, + limited: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + var cards = player.getCards("h", { type: "basic" }); + if (!cards.length) return false; + for (var i of cards) { + if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false; } - return event.filterCard(get.autoViewAs({name:'sha',storage:{twsidai:true}},cards),player,event); + return event.filterCard( + get.autoViewAs({ name: "sha", storage: { twsidai: true } }, cards), + player, + event + ); }, - viewAs:{name:'sha',storage:{twsidai:true}}, - filterCard:{type:'basic'}, - selectCard:-1, - check:()=>1, - onuse:function(result,player){ - player.awakenSkill('twsidai'); - player.addTempSkill('twsidai_effect'); + viewAs: { name: "sha", storage: { twsidai: true } }, + filterCard: { type: "basic" }, + selectCard: -1, + check: () => 1, + onuse: function (result, player) { + player.awakenSkill("twsidai"); + player.addTempSkill("twsidai_effect"); }, - ai:{ - order:2.9, - result:{ - target:function(player,target){ - var cards=ui.selected.cards.slice(0); - var names=[]; - for(var i of cards) names.add(i.name); - if(names.length=0) return -20; - return lib.card.sha.ai.result.target.apply(this,arguments); + ai: { + order: 2.9, + result: { + target: function (player, target) { + var cards = ui.selected.cards.slice(0); + var names = []; + for (var i of cards) names.add(i.name); + if (names.length < player.hp) return 0; + if (player.hasUnknown() && (player.identity != "fan" || !target.isZhu)) return 0; + if (get.attitude(player, target) >= 0) return -20; + return lib.card.sha.ai.result.target.apply(this, arguments); }, }, }, - mod:{ - cardUsable:function(card){ - if(card.storage&&card.storage.twsidai) return Infinity; + mod: { + cardUsable: function (card) { + if (card.storage && card.storage.twsidai) return Infinity; }, - targetInRange:function(card){ - if(card.storage&&card.storage.twsidai) return true; + targetInRange: function (card) { + if (card.storage && card.storage.twsidai) return true; }, }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.twsidai||event.getParent().type!='card') return false; - for(var i of event.cards){ - if(i.name=='jiu') return true; + subSkill: { + effect: { + charlotte: true, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.twsidai || + event.getParent().type != "card" + ) + return false; + for (var i of event.cards) { + if (i.name == "jiu") return true; } return false; }, - forced:true, - popup:false, - content:function(){ - trigger.num*=2; - game.log(trigger.card,'的伤害值','#y×2'); + forced: true, + popup: false, + content: function () { + trigger.num *= 2; + game.log(trigger.card, "的伤害值", "#y×2"); }, - group:['twsidai_tao','twsidai_shan'], + group: ["twsidai_tao", "twsidai_shan"], }, - tao:{ - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.twsidai||!event.player.isIn()) return false; - for(var i of event.cards){ - if(i.name=='tao') return true; + tao: { + trigger: { source: "damageSource" }, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.twsidai || + !event.player.isIn() + ) + return false; + for (var i of event.cards) { + if (i.name == "tao") return true; } return false; }, - forced:true, - popup:false, - content:function(){ + forced: true, + popup: false, + content: function () { trigger.player.loseMaxHp(); }, }, - shan:{ - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.twsidai||!event.target.isIn()) return false; - for(var i of event.cards){ - if(i.name=='shan') return true; + shan: { + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.twsidai || + !event.target.isIn() + ) + return false; + for (var i of event.cards) { + if (i.name == "shan") return true; } return false; }, - forced:true, - popup:false, - content:function(){ - 'step 0' - trigger.target.chooseToDiscard('h',{type:'basic'},'弃置一张基本牌,否则不能响应'+get.translation(trigger.card)).set('ai',function(card){ - var player=_status.event.player; - if(player.hasCard('hs',function(cardx){ - return cardx!=card&&get.name(cardx,player)=='shan'; - })) return 12-get.value(card); - return 0; - }); - 'step 1' - if(!result.bool) trigger.directHit.add(trigger.target); + forced: true, + popup: false, + content: function () { + "step 0"; + trigger.target + .chooseToDiscard( + "h", + { type: "basic" }, + "弃置一张基本牌,否则不能响应" + get.translation(trigger.card) + ) + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.hasCard("hs", function (cardx) { + return cardx != card && get.name(cardx, player) == "shan"; + }) + ) + return 12 - get.value(card); + return 0; + }); + "step 1"; + if (!result.bool) trigger.directHit.add(trigger.target); }, }, }, }, - twjieyu:{ - audio:2, - trigger:{player:['phaseJieshuBegin','damageEnd']}, - round:1, - filter:function(event,player){ - if(event.name!='phaseJieshu'){ - var history=player.getHistory('damage'); - for(var i of history){ - if(i==event) break; + twjieyu: { + audio: 2, + trigger: { player: ["phaseJieshuBegin", "damageEnd"] }, + round: 1, + filter: function (event, player) { + if (event.name != "phaseJieshu") { + var history = player.getHistory("damage"); + for (var i of history) { + if (i == event) break; return false; } - var all=player.actionHistory; - for(var i=all.length-2;i>=0;i--){ - if(all[i].damage.length) return false; - if(all[i].isRound) break; + var all = player.actionHistory; + for (var i = all.length - 2; i >= 0; i--) { + if (all[i].damage.length) return false; + if (all[i].isRound) break; } } - return player.countCards('h')>0&&!player.hasCard(function(card){ - return !lib.filter.cardDiscardable(card,player,'twjieyu'); - },'h') + return ( + player.countCards("h") > 0 && + !player.hasCard(function (card) { + return !lib.filter.cardDiscardable(card, player, "twjieyu"); + }, "h") + ); }, - check:function(event,player){ - var cards=[],names=[]; - for(var i=0;ieffect1; + check: function (event, player) { + var effect1 = get.effect(event.target, event.card, player, player); + var effect2 = 0, + targets = lib.skill.twhengjiang.logTarget(event, player); + for (var i of targets) effect2 += get.effect(i, event.card, player, player); + return effect2 > effect1; }, - content:function(){ - var targets=lib.skill.twhengjiang.logTarget(trigger,player); - trigger.targets.length=0; + content: function () { + var targets = lib.skill.twhengjiang.logTarget(trigger, player); + trigger.targets.length = 0; trigger.targets.addArray(targets); - trigger.getParent().triggeredTargets1.length=0; - trigger.getParent().twhengjiang_buffed=true; - player.addTempSkill('twhengjiang2','phaseUseAfter'); + trigger.getParent().triggeredTargets1.length = 0; + trigger.getParent().twhengjiang_buffed = true; + player.addTempSkill("twhengjiang2", "phaseUseAfter"); }, }, - twhengjiang2:{ - charlotte:true, - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.twhengjiang_buffed&&game.hasPlayer2(function(current){ - return current!=player&&(current.hasHistory('useCard',function(evt){ - return evt.respondTo&&evt.respondTo[1]==event.card; - })||current.hasHistory('respond',function(evt){ - return evt.respondTo&&evt.respondTo[1]==event.card; - })) - }); + twhengjiang2: { + charlotte: true, + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return ( + event.twhengjiang_buffed && + game.hasPlayer2(function (current) { + return ( + current != player && + (current.hasHistory("useCard", function (evt) { + return evt.respondTo && evt.respondTo[1] == event.card; + }) || + current.hasHistory("respond", function (evt) { + return evt.respondTo && evt.respondTo[1] == event.card; + })) + ); + }) + ); }, - content:function(){ - player.draw(game.countPlayer2(function(current){ - return current!=player&&(current.hasHistory('useCard',function(evt){ - return evt.respondTo&&evt.respondTo[1]==trigger.card; - })||current.hasHistory('respond',function(evt){ - return evt.respondTo&&evt.respondTo[1]==trigger.card; - })) - })); + content: function () { + player.draw( + game.countPlayer2(function (current) { + return ( + current != player && + (current.hasHistory("useCard", function (evt) { + return evt.respondTo && evt.respondTo[1] == trigger.card; + }) || + current.hasHistory("respond", function (evt) { + return evt.respondTo && evt.respondTo[1] == trigger.card; + })) + ); + }) + ); }, }, - twyuanhu:{ - audio:'yuanhu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard({type:'equip'},'eh'); + twyuanhu: { + audio: "yuanhu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hasCard({ type: "equip" }, "eh"); }, - filterCard:{type:'equip'}, - filterTarget:function(card,player,target){ - var card=ui.selected.cards[0]; + filterCard: { type: "equip" }, + filterTarget: function (card, player, target) { + var card = ui.selected.cards[0]; return target.canEquip(card); }, - discard:false, - lose:false, - prepare:'give', - position:'he', - check:function(card){ - if(get.position(card)=='h') return 9-get.value(card); - return 7-get.value(card); + discard: false, + lose: false, + prepare: "give", + position: "he", + check: function (card) { + if (get.position(card) == "h") return 9 - get.value(card); + return 7 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.equip(cards[0]); - 'step 1' + "step 1"; event.goto(3); - switch(get.subtype(cards[0])){ - case 'equip1': - if(game.hasPlayer(function(current){ - return current!=target&&get.distance(target,current)==1&¤t.countCards('hej')>0; - })){ - player.chooseTarget(true,'弃置一名距离'+get.translation(target)+'为1的角色区域内的一张牌',function(card,player,target){ - var current=_status.event.current; - return current!=target&&get.distance(current,target)==1&¤t.countCards('hej')>0; - }).set('current',target).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy'},player,player); - }); + switch (get.subtype(cards[0])) { + case "equip1": + if ( + game.hasPlayer(function (current) { + return ( + current != target && + get.distance(target, current) == 1 && + current.countCards("hej") > 0 + ); + }) + ) { + player + .chooseTarget( + true, + "弃置一名距离" + get.translation(target) + "为1的角色区域内的一张牌", + function (card, player, target) { + var current = _status.event.current; + return ( + current != target && + get.distance(current, target) == 1 && + current.countCards("hej") > 0 + ); + } + ) + .set("current", target) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy" }, player, player); + }); event.goto(2); } break; - case 'equip2': + case "equip2": target.draw(); break; - case 'equip3': case 'equip4': case 'equip5': case 'equip6': + case "equip3": + case "equip4": + case "equip5": + case "equip6": target.recover(); break; } - 'step 2' - var target=result.targets[0]; + "step 2"; + var target = result.targets[0]; player.line(target); - player.discardPlayerCard(target,true,'hej'); - 'step 3' - if(target.hp<=player.hp||target.countCards('h')<=player.countCards('h')){ + player.discardPlayerCard(target, true, "hej"); + "step 3"; + if (target.hp <= player.hp || target.countCards("h") <= player.countCards("h")) { player.draw(); - player.addTempSkill('twyuanhu_end'); + player.addTempSkill("twyuanhu_end"); } }, - ai:{ - order:10, - result:{ - player:function(player,target){ - if(get.attitude(player,target)==0) return 0; - if(!ui.selected.cards.length) return; - var eff=get.effect(target,ui.selected.cards[0],player,player),sub=get.subtype(ui.selected.cards[0],false); - if(target==player) eff+=4; - else{ - var hp=player.hp,hs=player.countCards('h',(card)=>card!=ui.selected.cards[0]); - var tp=target.hp,ts=target.countCards('h'); - if(sub=='equip2') ts++; - if(tp card != ui.selected.cards[0]); + var tp = target.hp, + ts = target.countCards("h"); + if (sub == "equip2") ts++; + if ( + tp < target.maxHp && + (sub == "equip3" || sub == "equip4" || sub == "equip5" || sub == "equip6") + ) + tp++; + if (tp <= hp || ts <= hs) eff += 2; } - if(sub=='equip1'){ - var list=game.filterPlayer(function(current){ - return current!=target&&get.distance(target,current)==1&¤t.countCards('hej')<0; - }).map(function(i){ - return get.effect(i,{name:'guohe_copy'},player,player); - }).sort((a,b)=>b-a); - if(list.length) eff+=list[0]; + if (sub == "equip1") { + var list = game + .filterPlayer(function (current) { + return ( + current != target && + get.distance(target, current) == 1 && + current.countCards("hej") < 0 + ); + }) + .map(function (i) { + return get.effect(i, { name: "guohe_copy" }, player, player); + }) + .sort((a, b) => b - a); + if (list.length) eff += list[0]; } return eff; }, - target:function(player,target){ - if(!ui.selected.cards.length) return 0; - var sub=get.subtype(ui.selected.cards[0],false); - var eff=get.effect(target,ui.selected.cards[0],player,target); - if(sub=='equip2') eff+=(get.effect(target,{name:'draw'},target,target)); - if(target.isDamaged()&&(sub=='equip3'||sub=='equip4'||sub=='equip5'||sub=='equip6')) eff+=get.recoverEffect(target,player,player); + target: function (player, target) { + if (!ui.selected.cards.length) return 0; + var sub = get.subtype(ui.selected.cards[0], false); + var eff = get.effect(target, ui.selected.cards[0], player, target); + if (sub == "equip2") eff += get.effect(target, { name: "draw" }, target, target); + if ( + target.isDamaged() && + (sub == "equip3" || sub == "equip4" || sub == "equip5" || sub == "equip6") + ) + eff += get.recoverEffect(target, player, player); return eff; }, }, }, - subSkill:{ - end:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - charlotte:true, - filter:function(event,player){ - return player.hasSkill('twyuanhu')&&player.hasCard({type:'equip'},'eh'); + subSkill: { + end: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + charlotte: true, + filter: function (event, player) { + return player.hasSkill("twyuanhu") && player.hasCard({ type: "equip" }, "eh"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('twyuanhu'), - prompt2:'将一张装备牌置入一名角色的装备区内。若此牌为:武器牌,你弃置与其距离为1的另一名角色区域的一张牌;防具牌,其摸一张牌;坐骑牌或宝物牌,其回复1点体力。然后若其体力值或手牌数不大于你,则你摸一张牌。', - filterCard:lib.skill.twyuanhu.filterCard, - filterTarget:lib.skill.twyuanhu.filterTarget, - position:'he', - ai1:lib.skill.twyuanhu.check, - ai2:function(target){ - var player=_status.event.player; - return get.effect(target,'twyuanhu',player,player); + prompt: get.prompt("twyuanhu"), + prompt2: + "将一张装备牌置入一名角色的装备区内。若此牌为:武器牌,你弃置与其距离为1的另一名角色区域的一张牌;防具牌,其摸一张牌;坐骑牌或宝物牌,其回复1点体力。然后若其体力值或手牌数不大于你,则你摸一张牌。", + filterCard: lib.skill.twyuanhu.filterCard, + filterTarget: lib.skill.twyuanhu.filterTarget, + position: "he", + ai1: lib.skill.twyuanhu.check, + ai2: function (target) { + var player = _status.event.player; + return get.effect(target, "twyuanhu", player, player); }, }); - 'step 1' - if(result.bool){ - result.skill='twyuanhu'; - player.useResult(result,event); + "step 1"; + if (result.bool) { + result.skill = "twyuanhu"; + player.useResult(result, event); } }, }, }, }, - twjuezhu:{ - audio:2, - limited:true, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.hasEnabledSlot(3)||player.hasEnabledSlot(4); + twjuezhu: { + audio: 2, + limited: true, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.hasEnabledSlot(3) || player.hasEnabledSlot(4); }, - skillAnimation:true, - animationColor:'water', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('twjuezhu'),[1,2],function(card,player,target){ - return !ui.selected.targets.length&&!target.hasSkill('feiying'); - }).set('multitarget',true).set('promptbar','none').set('ai',function(target){ - if(player.hasUnknown()) return false; - return get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - var list=[]; - if(player.hasEnabledSlot(3)) list.push('equip3'); - if(player.hasEnabledSlot(4)) list.push('equip4'); - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('prompt','选择废除一个坐骑栏'); - } - else event.finish(); - 'step 2' - player.logSkill('twjuezhu',target); - player.awakenSkill('twjuezhu'); + skillAnimation: true, + animationColor: "water", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("twjuezhu"), [1, 2], function (card, player, target) { + return !ui.selected.targets.length && !target.hasSkill("feiying"); + }) + .set("multitarget", true) + .set("promptbar", "none") + .set("ai", function (target) { + if (player.hasUnknown()) return false; + return get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + var list = []; + if (player.hasEnabledSlot(3)) list.push("equip3"); + if (player.hasEnabledSlot(4)) list.push("equip4"); + if (list.length == 1) event._result = { control: list[0] }; + else player.chooseControl(list).set("prompt", "选择废除一个坐骑栏"); + } else event.finish(); + "step 2"; + player.logSkill("twjuezhu", target); + player.awakenSkill("twjuezhu"); player.disableEquip(result.control); target.disableJudge(); - player.markAuto('twjuezhu_restore',[[target,result.control]]); - player.addSkill('twjuezhu_restore'); - target.addSkills('feiying'); + player.markAuto("twjuezhu_restore", [[target, result.control]]); + player.addSkill("twjuezhu_restore"); + target.addSkills("feiying"); }, - subSkill:{ - restore:{ - trigger:{global:'die'}, - forced:true, - charlotte:true, - filter:function(event,player){ - for(var i of player.getStorage('twjuezhu_restore')){ - if(i[0]==event.player&&player.hasDisabledSlot(i[1])) return true; + subSkill: { + restore: { + trigger: { global: "die" }, + forced: true, + charlotte: true, + filter: function (event, player) { + for (var i of player.getStorage("twjuezhu_restore")) { + if (i[0] == event.player && player.hasDisabledSlot(i[1])) return true; } return false; }, - content:function(){ - var list=[]; - for(var i of player.getStorage('twjuezhu_restore')){ - if(i[0]==trigger.player&&player.hasDisabledSlot(i[1])) list.push(i[1]); + content: function () { + var list = []; + for (var i of player.getStorage("twjuezhu_restore")) { + if (i[0] == trigger.player && player.hasDisabledSlot(i[1])) list.push(i[1]); } player.enableEquip(list); }, }, }, - derivation:'feiying', + derivation: "feiying", }, - twfengpo:{ - audio:'fengpo', - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - filter:function(event,player){ - return (event.card.name=='sha'||event.card.name=='juedou')&&event.targets.length==1&&event.target.countCards('h')>0; + twfengpo: { + audio: "fengpo", + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + filter: function (event, player) { + return ( + (event.card.name == "sha" || event.card.name == "juedou") && + event.targets.length == 1 && + event.target.countCards("h") > 0 + ); }, - onremove:true, - content:function(){ - 'step 0' - event.target=trigger.target; + onremove: true, + content: function () { + "step 0"; + event.target = trigger.target; player.viewHandcards(trigger.target); - 'step 1' - var num=target.countCards('h',player.storage.twfengpo?{color:'red'}:{suit:'diamond'}); - if(!num){ + "step 1"; + var num = target.countCards( + "h", + player.storage.twfengpo ? { color: "red" } : { suit: "diamond" } + ); + if (!num) { event.finish(); return; } - event.num=num; - player.chooseControl().set('choiceList',[ - '摸'+num+'张牌', - '令'+get.translation(trigger.card)+'的伤害值基数+'+num, - ]); - 'step 2' - if(result.index==0) player.draw(num); - else trigger.getParent().baseDamage+=num; + event.num = num; + player + .chooseControl() + .set("choiceList", [ + "摸" + num + "张牌", + "令" + get.translation(trigger.card) + "的伤害值基数+" + num, + ]); + "step 2"; + if (result.index == 0) player.draw(num); + else trigger.getParent().baseDamage += num; }, - group:'twfengpo_kill', - subSkill:{ - kill:{ - audio:'fengpo', - trigger:{source:'die'}, - forced:true, - filter:(event,player)=>!player.storage.twfengpo, - skillAnimation:true, - animationColor:'fire', - content:function(){ - player.storage.twfengpo=true; - player.popup('凤魄'); - game.log(player,'恢复了技能','#g【凤魄】'); + group: "twfengpo_kill", + subSkill: { + kill: { + audio: "fengpo", + trigger: { source: "die" }, + forced: true, + filter: (event, player) => !player.storage.twfengpo, + skillAnimation: true, + animationColor: "fire", + content: function () { + player.storage.twfengpo = true; + player.popup("凤魄"); + game.log(player, "恢复了技能", "#g【凤魄】"); }, }, }, }, - twmouzhu:{ - audio:'mouzhu', - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - contentBefore:function(){ - var target=targets[0],evt=event.getParent(); - evt._target=target; - var list=game.filterPlayer(function(current){ - return current!=player&¤t!=target&¤t.hp<=player.hp; + twmouzhu: { + audio: "mouzhu", + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + contentBefore: function () { + var target = targets[0], + evt = event.getParent(); + evt._target = target; + var list = game.filterPlayer(function (current) { + return current != player && current != target && current.hp <= player.hp; }); - if(!list.length){ + if (!list.length) { player.loseHp(); evt.finish(); - } - else{ - evt.targets=list.sortBySeat(); + } else { + evt.targets = list.sortBySeat(); player.line(list); } }, - content:function(){ - 'step 0' - target.chooseCard('he','是否交给'+get.translation(player)+'一张牌?').set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('goon',get.attitude(target,player)>0); - 'step 1' - if(result.bool){ - target.give(result.cards,player); - } - else{ - game.log(target,'拒绝给牌'); + content: function () { + "step 0"; + target + .chooseCard("he", "是否交给" + get.translation(player) + "一张牌?") + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", get.attitude(target, player) > 0); + "step 1"; + if (result.bool) { + target.give(result.cards, player); + } else { + game.log(target, "拒绝给牌"); } }, - contentAfter:function(){ - 'step 0' - var num=0,par=event.getParent(); - player.getHistory('gain',function(evt){ - if(evt.getParent(2)==par) num+=evt.cards.length; + contentAfter: function () { + "step 0"; + var num = 0, + par = event.getParent(); + player.getHistory("gain", function (evt) { + if (evt.getParent(2) == par) num += evt.cards.length; }); - if(!num){ + if (!num) { player.loseHp(); - for(var i of targets) i.loseHp(); + for (var i of targets) i.loseHp(); event.finish(); - } - else{ - var target=event.getParent()._target; - event.target=target; - event.num=num; - var bool1=player.canUse('sha',target,false),bool2=player.canUse('juedou',target,false); - if(bool1&&bool2) target.chooseControl('sha','juedou').set('prompt','谋诛:视为被'+get.translation(player)+'使用一张…').set('prompt2','(伤害值基数:'+num+')').set('ai',function(){ - var target=_status.event.player,player=_status.event.getParent().player; - if(target.hasShan()||get.effect(target,{name:'sha'},player,target)>0) return 'sha'; - if(get.effect(target,{name:'juedou'},player,target)>0) return 'juedou'; - return 'sha'; - }); - else if(bool1) event._result={control:'sha'}; - else if(bool2) event._result={control:'juedou'}; + } else { + var target = event.getParent()._target; + event.target = target; + event.num = num; + var bool1 = player.canUse("sha", target, false), + bool2 = player.canUse("juedou", target, false); + if (bool1 && bool2) + target + .chooseControl("sha", "juedou") + .set("prompt", "谋诛:视为被" + get.translation(player) + "使用一张…") + .set("prompt2", "(伤害值基数:" + num + ")") + .set("ai", function () { + var target = _status.event.player, + player = _status.event.getParent().player; + if ( + target.hasShan() || + get.effect(target, { name: "sha" }, player, target) > 0 + ) + return "sha"; + if (get.effect(target, { name: "juedou" }, player, target) > 0) + return "juedou"; + return "sha"; + }); + else if (bool1) event._result = { control: "sha" }; + else if (bool2) event._result = { control: "juedou" }; else event.finish(); } - 'step 1' - if(result.control&&lib.card[result.control]) player.useCard({ - name:result.control, - isCard:true, - },false,target).baseDamage=num; + "step 1"; + if (result.control && lib.card[result.control]) + player.useCard( + { + name: result.control, + isCard: true, + }, + false, + target + ).baseDamage = num; }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>=0) return 0; - var list=game.filterPlayer(function(current){ - return current!=player&¤t!=target&¤t.hp<=player.hp; + ai: { + order: 9, + result: { + target: function (player, target) { + if (get.attitude(player, target) >= 0) return 0; + var list = game.filterPlayer(function (current) { + return current != player && current != target && current.hp <= player.hp; }); - if(!list.length) return 0; - return -Math.min(-get.effect(target,{name:'sha'},player,target),-get.effect(target,{name:'juedou'},player,target))*list.reduce(function(num,current){ - return num+(2+get.sgn(get.attitude(current,player))); - },0); + if (!list.length) return 0; + return ( + -Math.min( + -get.effect(target, { name: "sha" }, player, target), + -get.effect(target, { name: "juedou" }, player, target) + ) * + list.reduce(function (num, current) { + return num + (2 + get.sgn(get.attitude(current, player))); + }, 0) + ); }, }, }, }, - twyanhuo:{ - audio:'yanhuo', - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + twyanhuo: { + audio: "yanhuo", + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - content:function(){ - 'step 0' - var num=player.countCards('he'),str=get.cnNumber(num); - event.num1=num; - event.num2=1; - var list=['令一名其他角色弃置'+str+'张牌']; - if(num>1){ - list.push('令至多'+str+'名其他角色各弃置一张牌'); + content: function () { + "step 0"; + var num = player.countCards("he"), + str = get.cnNumber(num); + event.num1 = num; + event.num2 = 1; + var list = ["令一名其他角色弃置" + str + "张牌"]; + if (num > 1) { + list.push("令至多" + str + "名其他角色各弃置一张牌"); } - player.chooseControl('cancel2').set('choiceList',list).set('prompt',get.prompt('twyanhuo')).set('forceDie',true); - 'step 1' - if(result.control!='cancel2'){ - if(result.index==0){ - event.num2=event.num1; - event.num1=1; + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("prompt", get.prompt("twyanhuo")) + .set("forceDie", true); + "step 1"; + if (result.control != "cancel2") { + if (result.index == 0) { + event.num2 = event.num1; + event.num1 = 1; } - player.chooseTarget([1,event.num1],true,'请选择【延祸】的目标',function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('forceDie',true).set('ai',function(target){ - return -get.attitude(_status.event.player,target) - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('twyanhuo',targets); - for(var i of targets) i.chooseToDiscard(true,'he',event.num2); + player + .chooseTarget( + [1, event.num1], + true, + "请选择【延祸】的目标", + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("forceDie", true) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("twyanhuo", targets); + for (var i of targets) i.chooseToDiscard(true, "he", event.num2); } }, }, - twshenxing:{ - mod:{ - globalFrom:function(player,target,distance){ - var es=player.getCards('e',function(card){ + twshenxing: { + mod: { + globalFrom: function (player, target, distance) { + var es = player.getCards("e", function (card) { return !ui.selected.cards.includes(card); }); - for(var i of es){ - var type=get.subtype(i); - if(type=='equip3'||type=='equip4'||type=='equip6') return distance; + for (var i of es) { + var type = get.subtype(i); + if (type == "equip3" || type == "equip4" || type == "equip6") return distance; } - return distance-1; + return distance - 1; }, - maxHandcard:function(player,distance){ - var es=player.getCards('e',function(card){ + maxHandcard: function (player, distance) { + var es = player.getCards("e", function (card) { return !ui.selected.cards.includes(card); }); - for(var i of es){ - var type=get.subtype(i); - if(type=='equip3'||type=='equip4'||type=='equip6') return distance; + for (var i of es) { + var type = get.subtype(i); + if (type == "equip3" || type == "equip4" || type == "equip6") return distance; } - return distance+1; + return distance + 1; }, }, }, - twdaoji:{ - audio:'daoji', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard(lib.skill.twdaoji.filterCard,'he'); + twdaoji: { + audio: "daoji", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hasCard(lib.skill.twdaoji.filterCard, "he"); }, - filterCard:function(card){ - return get.type(card)!='basic'; + filterCard: function (card) { + return get.type(card) != "basic"; }, - position:'he', - filterTarget:function(card,player,target){ - return target!=player&&player.inRange(target)&&target.hasCard((card)=>lib.filter.canBeGained(card,target,player),'he'); + position: "he", + filterTarget: function (card, player, target) { + return ( + target != player && + player.inRange(target) && + target.hasCard((card) => lib.filter.canBeGained(card, target, player), "he") + ); }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'he',true); - 'step 1' - if(result.bool&&result.cards&&result.cards.length==1){ - var card=result.cards[0]; - if(player.getCards('h').includes(card)){ - var type=get.type(card); - if(type=='basic') player.draw(); - else if(type=='equip'){ - if(player.hasUseTarget(card)) player.chooseUseTarget(card,'nopopup',true); - target.damage('nocard'); + content: function () { + "step 0"; + player.gainPlayerCard(target, "he", true); + "step 1"; + if (result.bool && result.cards && result.cards.length == 1) { + var card = result.cards[0]; + if (player.getCards("h").includes(card)) { + var type = get.type(card); + if (type == "basic") player.draw(); + else if (type == "equip") { + if (player.hasUseTarget(card)) player.chooseUseTarget(card, "nopopup", true); + target.damage("nocard"); } } } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - var eff=get.effect(target,{name:'shunshou_copy2'},player,target); - if(target.countCards('e')>0) eff+=get.damageEffect(target,player,target); + ai: { + order: 6, + result: { + target: function (player, target) { + var eff = get.effect(target, { name: "shunshou_copy2" }, player, target); + if (target.countCards("e") > 0) eff += get.damageEffect(target, player, target); return eff; }, }, }, }, - xinzhenjun:{ - audio:2, - trigger:{ - player:'phaseUseBegin' + xinzhenjun: { + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:true, - filterTarget:lib.filter.notMe, - position:'he', - prompt:get.prompt2('xinzhenjun'), - ai1:function(card){ - var player=_status.event.player; - if(card.name=='sha'&&get.color(card)=='red'){ - for(var i=0;i0&¤t.hasValueTarget(card)) return 7; + filterCard: true, + filterTarget: lib.filter.notMe, + position: "he", + prompt: get.prompt2("xinzhenjun"), + ai1: function (card) { + var player = _status.event.player; + if (card.name == "sha" && get.color(card) == "red") { + for (var i = 0; i < game.players.length; i++) { + var current = game.players[i]; + if ( + current != player && + get.attitude(player, current) > 0 && + current.hasValueTarget(card) + ) + return 7; } return 0; } - return 7-get.value(card); + return 7 - get.value(card); }, - ai2:function(target){ - var player=_status.event.player; - var card=ui.selected.cards[0]; - var att=get.attitude(player,target); - if(get.value(card)<0) return -att*2; - if(target.countCards('h',{name:'sha',color:'red'})||target.hasSkill('wusheng')||target.hasSkill('new_rewusheng')||target.hasSkill('wushen')||(card.name=='sha'&&get.color(card)=='red'&&target.hasValueTarget(card))) return att*2; - var eff=0; - game.countPlayer(function(current){ - if(target!=current&&get.distance(target,current,'attack')>1) return; - var eff2=get.damageEffect(current,player,player); - if(eff2>eff) eff=eff2; + ai2: function (target) { + var player = _status.event.player; + var card = ui.selected.cards[0]; + var att = get.attitude(player, target); + if (get.value(card) < 0) return -att * 2; + if ( + target.countCards("h", { name: "sha", color: "red" }) || + target.hasSkill("wusheng") || + target.hasSkill("new_rewusheng") || + target.hasSkill("wushen") || + (card.name == "sha" && + get.color(card) == "red" && + target.hasValueTarget(card)) + ) + return att * 2; + var eff = 0; + game.countPlayer(function (current) { + if (target != current && get.distance(target, current, "attack") > 1) return; + var eff2 = get.damageEffect(current, player, player); + if (eff2 > eff) eff = eff2; }); - if(att>0&&eff>0) eff+=2*att; + if (att > 0 && eff > 0) eff += 2 * att; return eff; }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xinzhenjun',target); - player.give(result.cards,target) - } - else event.finish(); - 'step 2' + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xinzhenjun", target); + player.give(result.cards, target); + } else event.finish(); + "step 2"; target.chooseToUse({ - filterCard:function(card){ - return get.name(card)=='sha'&&get.color(card)!='black'&&lib.filter.cardEnabled.apply(this,arguments); + filterCard: function (card) { + return ( + get.name(card) == "sha" && + get.color(card) != "black" && + lib.filter.cardEnabled.apply(this, arguments) + ); }, - prompt:'请使用一张不为黑色的【杀】,否则'+get.translation(player)+'可以对你或你攻击范围内的一名其他角色造成1点伤害', + prompt: + "请使用一张不为黑色的【杀】,否则" + + get.translation(player) + + "可以对你或你攻击范围内的一名其他角色造成1点伤害", }); - 'step 3' - if(result.bool){ - var num=1; - game.countPlayer2(function(current){ - current.getHistory('damage',function(evt){ - if(evt.getParent(evt.notLink()?4:8)==event) num+=evt.num; + "step 3"; + if (result.bool) { + var num = 1; + game.countPlayer2(function (current) { + current.getHistory("damage", function (evt) { + if (evt.getParent(evt.notLink() ? 4 : 8) == event) num += evt.num; }); }); player.draw(num); event.finish(); - } - else{ - player.chooseTarget('是否对'+get.translation(target)+'或其攻击范围内的一名角色造成1点伤害?',function(card,player,target){ - return target==_status.event.targetx||_status.event.targetx.inRange(target); - }).set('targetx',event.target).ai=function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player) + } else { + player + .chooseTarget( + "是否对" + get.translation(target) + "或其攻击范围内的一名角色造成1点伤害?", + function (card, player, target) { + return ( + target == _status.event.targetx || + _status.event.targetx.inRange(target) + ); + } + ) + .set("targetx", event.target).ai = function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); }; } - 'step 4' - if(result.bool){ + "step 4"; + if (result.bool) { player.line(result.targets); - result.targets[0].damage('nocard'); + result.targets[0].damage("nocard"); } }, }, - twmoukui:{ - audio:'moukui', - trigger:{player:'useCardToPlayered'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; + twmoukui: { + audio: "moukui", + trigger: { player: "useCardToPlayered" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return event.card && event.card.name == "sha"; }, - content:function(){ - 'step 0' - var list=['选项一']; - if(trigger.target.countDiscardableCards(player,'he')>0) list.push('选项二'); - list.push('背水!'); - list.push('cancel2'); - player.chooseControl(list).set('choiceList',[ - '摸一张牌', - '弃置'+get.translation(trigger.target)+'的一张牌', - '背水!依次执行以上两项。然后若此【杀】未令其进入濒死状态,则其弃置你的一张牌。', - ]).set('prompt',get.prompt('twmoukui',trigger.target)).setHiddenSkill('twmoukui'); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.target; - player.logSkill('twmoukui',target); - if(result.control=='选项一'||result.control=='背水!') player.draw(); - if(result.control=='选项二'||result.control=='背水!') player.discardPlayerCard(target,true,'he'); - if(result.control=='背水!'){ - player.addTempSkill('twmoukui_effect'); - var evt=trigger.getParent(); - if(!evt.twmoukui_effect) evt.twmoukui_effect=[]; + content: function () { + "step 0"; + var list = ["选项一"]; + if (trigger.target.countDiscardableCards(player, "he") > 0) list.push("选项二"); + list.push("背水!"); + list.push("cancel2"); + player + .chooseControl(list) + .set("choiceList", [ + "摸一张牌", + "弃置" + get.translation(trigger.target) + "的一张牌", + "背水!依次执行以上两项。然后若此【杀】未令其进入濒死状态,则其弃置你的一张牌。", + ]) + .set("prompt", get.prompt("twmoukui", trigger.target)) + .setHiddenSkill("twmoukui"); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.target; + player.logSkill("twmoukui", target); + if (result.control == "选项一" || result.control == "背水!") player.draw(); + if (result.control == "选项二" || result.control == "背水!") + player.discardPlayerCard(target, true, "he"); + if (result.control == "背水!") { + player.addTempSkill("twmoukui_effect"); + var evt = trigger.getParent(); + if (!evt.twmoukui_effect) evt.twmoukui_effect = []; evt.twmoukui_effect.add(target); } } }, - subSkill:{ - effect:{ - trigger:{player:'useCardAfter'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return event.twmoukui_effect&&event.twmoukui_effect.filter(function(current){ - return current.isIn()&&!current.hasHistory('damage',function(evt){ - return evt._dyinged&&evt.card==event.card; - }); - }).length>0; + subSkill: { + effect: { + trigger: { player: "useCardAfter" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return ( + event.twmoukui_effect && + event.twmoukui_effect.filter(function (current) { + return ( + current.isIn() && + !current.hasHistory("damage", function (evt) { + return evt._dyinged && evt.card == event.card; + }) + ); + }).length > 0 + ); }, - content:function(){ - var list=trigger.twmoukui_effect.filter(function(current){ - return current.isIn()&&!current.hasHistory('damage',function(evt){ - return evt._dyinged&&evt.card==event.card; - }); - }).sortBySeat(); - for(var i of list){ - i.discardPlayerCard(player,true,'he').boolline=true; + content: function () { + var list = trigger.twmoukui_effect + .filter(function (current) { + return ( + current.isIn() && + !current.hasHistory("damage", function (evt) { + return evt._dyinged && evt.card == event.card; + }) + ); + }) + .sortBySeat(); + for (var i of list) { + i.discardPlayerCard(player, true, "he").boolline = true; } }, }, }, }, - twfuhan:{ - audio:'fuhan', - trigger:{player:'phaseZhunbeiBegin'}, - unique:true, - limited:true, - skillAnimation:true, - animationColor:'orange', - forceunique:true, - filter:function(event,player){ - return player.countMark('fanghun')>0; + twfuhan: { + audio: "fuhan", + trigger: { player: "phaseZhunbeiBegin" }, + unique: true, + limited: true, + skillAnimation: true, + animationColor: "orange", + forceunique: true, + filter: function (event, player) { + return player.countMark("fanghun") > 0; }, - prompt:function(event,player){ - var num=Math.max(2,player.storage.fanghun); - num=Math.min(num,8); - return get.prompt('twfuhan')+'(体力上限:'+num+')'; + prompt: function (event, player) { + var num = Math.max(2, player.storage.fanghun); + num = Math.min(num, 8); + return get.prompt("twfuhan") + "(体力上限:" + num + ")"; }, - check:function(event,player){ - if(player.storage.fanghun>=Math.min(4,player.maxHp)) return true; - if(player.hp<=2&&player.storage.fanghun>=3) return true; + check: function (event, player) { + if (player.storage.fanghun >= Math.min(4, player.maxHp)) return true; + if (player.hp <= 2 && player.storage.fanghun >= 3) return true; return false; }, - content:function(){ - 'step 0' - var num=Math.max(2,player.storage.fanghun); - num=Math.min(num,8); - event.num=num; - player.removeMark('fanghun',player.storage.fanghun); - player.awakenSkill('twfuhan'); - if(_status.characterlist){ - list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - var name=_status.characterlist[i]; - if(lib.character[name][1]=='shu') list.push(name); + content: function () { + "step 0"; + var num = Math.max(2, player.storage.fanghun); + num = Math.min(num, 8); + event.num = num; + player.removeMark("fanghun", player.storage.fanghun); + player.awakenSkill("twfuhan"); + if (_status.characterlist) { + list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + var name = _status.characterlist[i]; + if (lib.character[name][1] == "shu") list.push(name); } - } - else if(_status.connectMode){ - list=get.charactersOL(function(i){ - return lib.character[i][1]!='shu'; + } else if (_status.connectMode) { + list = get.charactersOL(function (i) { + return lib.character[i][1] != "shu"; + }); + } else { + list = get.gainableCharacters(function (info) { + return info[1] == "shu"; }); } - else{ - list=get.gainableCharacters(function(info){ - return info[1]=='shu'; - }); - } - var players=game.players.concat(game.dead); - for(var i=0;i0) player.gainMaxHp(num); + "step 2"; + var num = event.num - player.maxHp; + if (num > 0) player.gainMaxHp(num); else player.loseMaxHp(-num); player.recover(); - 'step 3' - var card=get.cardPile('meiyingqiang','field'); - if(card){ - player.gain(card,'gain2','log'); + "step 3"; + var card = get.cardPile("meiyingqiang", "field"); + if (card) { + player.gain(card, "gain2", "log"); + } + }, + ai: { + combo: "refanghun", + }, + }, + twqueshi: { + trigger: { + global: "phaseBefore", + player: "enterGame", + }, + forced: true, + locked: false, + filter: function (event, player) { + return (event.name != "phase" || game.phaseNumber == 0) && player.hasEquipableSlot(1); + }, + content: function () { + if (!lib.inpile.includes("meiyingqiang")) { + lib.inpile.push("meiyingqiang"); + player.equip(game.createCard("meiyingqiang", "diamond", 12)); + } else { + var card = get.cardPile(function (card) { + return card.name == "meiyingqiang" && !player.getEquips(1).includes(card); + }, "field"); + if (card) player.equip(card); } }, }, - twqueshi:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + meiyingqiang: { + equipSkill: true, + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.hasEquipableSlot(1); - }, - content:function(){ - if(!lib.inpile.includes('meiyingqiang')){ - lib.inpile.push('meiyingqiang'); - player.equip(game.createCard('meiyingqiang','diamond',12)); - } - else{ - var card=get.cardPile(function(card){ - return card.name=='meiyingqiang'&&!player.getEquips(1).includes(card); - },'field'); - if(card) player.equip(card); - } - }, - }, - meiyingqiang:{ - equipSkill:true, - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], - }, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - var list=player.getHistory('lose',function(evt){ - return evt.cards2&&evt.cards2.length; + filter: function (event, player) { + if (player == _status.currentPhase) return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + var list = player.getHistory("lose", function (evt) { + return evt.cards2 && evt.cards2.length; }); - if(event.name=='lose'){ - if(list.indexOf(event)!=0) return false; + if (event.name == "lose") { + if (list.indexOf(event) != 0) return false; + } else { + if ( + !player.hasHistory("lose", function (evt) { + return evt.getParent() == event && list.indexOf(evt) == 0; + }) + ) + return false; } - else{ - if(!player.hasHistory('lose',function(evt){ - return evt.getParent()==event&&list.indexOf(evt)==0; - })) return false; - } - return _status.connectMode||!lib.config.skip_shan||player.hasSha(); + return _status.connectMode || !lib.config.skip_shan || player.hasSha(); }, - direct:true, - content:function(){ - if(trigger.delay===false) game.delayx(); - player.chooseToUse('梅影枪:是否使用一张【杀】?',function(card){ - if(get.name(card)!='sha') return false; - return lib.filter.cardEnabled.apply(this,arguments); - }).set('addCount',false).logSkill='meiyingqiang'; + direct: true, + content: function () { + if (trigger.delay === false) game.delayx(); + player + .chooseToUse("梅影枪:是否使用一张【杀】?", function (card) { + if (get.name(card) != "sha") return false; + return lib.filter.cardEnabled.apply(this, arguments); + }) + .set("addCount", false).logSkill = "meiyingqiang"; }, }, - cuijin:{ - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&(event.player==player||player.inRange(event.player))&&player.countCards('he')>0; + cuijin: { + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + (event.player == player || player.inRange(event.player)) && + player.countCards("he") > 0 + ); }, - checkx(event,player){ - let d1=true,e=false; - if(event.player.hasSkill('jueqing')||event.player.hasSkill('gangzhi')) d1=false; - for(let tar of event.targets){ - if(event.card.name=='sha'){ - if(!tar.mayHaveShan(player,'use',tar.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))||event.player.hasSkillTag('directHit_ai',true,{ - target:tar, - card:event.card, - },true)){ - if(!tar.hasSkill('gangzhi')) d1=false; - if(!tar.hasSkillTag('filterDamage',null,{ - player:event.player, - card:event.card, - })){ - let att=get.attitude(_status.event.player,tar); - if(att>0) return false; - if(att<0) e=true; + checkx(event, player) { + let d1 = true, + e = false; + if (event.player.hasSkill("jueqing") || event.player.hasSkill("gangzhi")) d1 = false; + for (let tar of event.targets) { + if (event.card.name == "sha") { + if ( + !tar.mayHaveShan( + player, + "use", + tar.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + event.player.hasSkillTag( + "directHit_ai", + true, + { + target: tar, + card: event.card, + }, + true + ) + ) { + if (!tar.hasSkill("gangzhi")) d1 = false; + if ( + !tar.hasSkillTag("filterDamage", null, { + player: event.player, + card: event.card, + }) + ) { + let att = get.attitude(_status.event.player, tar); + if (att > 0) return false; + if (att < 0) e = true; } } - } - else e=true; + } else e = true; } - if(e) return true; - if(d1) return get.damageEffect(event.player,player,_status.event.player)>0; + if (e) return true; + if (d1) return get.damageEffect(event.player, player, _status.event.player) > 0; return false; }, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isOnline()) game.delayx(); - var target=trigger.player; - event.target=target; - player.chooseToDiscard('he',get.prompt('cuijin',target),'弃置一张牌并令'+get.translation(trigger.player)+'使用的【杀】伤害+1,但若其未造成伤害,则你对其造成1点伤害。').set('ai',function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }).set('goon',lib.skill.cuijin.checkx(trigger,player)).logSkill=['cuijin',target]; - 'step 1' - if(result.bool){ - if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + content: function () { + "step 0"; + if (player != game.me && !player.isOnline()) game.delayx(); + var target = trigger.player; + event.target = target; + player + .chooseToDiscard( + "he", + get.prompt("cuijin", target), + "弃置一张牌并令" + + get.translation(trigger.player) + + "使用的【杀】伤害+1,但若其未造成伤害,则你对其造成1点伤害。" + ) + .set("ai", function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }) + .set("goon", lib.skill.cuijin.checkx(trigger, player)).logSkill = ["cuijin", target]; + "step 1"; + if (result.bool) { + if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1; trigger.baseDamage++; - player.addTempSkill('cuijin_damage'); - player.markAuto('cuijin_damage',[trigger.card]); + player.addTempSkill("cuijin_damage"); + player.markAuto("cuijin_damage", [trigger.card]); } }, - subSkill:{ - damage:{ - trigger:{global:'useCardAfter'}, - forced:true, - popup:false, - charlotte:true, - onremove:true, - filter:function(event,player){ + subSkill: { + damage: { + trigger: { global: "useCardAfter" }, + forced: true, + popup: false, + charlotte: true, + onremove: true, + filter: function (event, player) { return player.storage.cuijin_damage.includes(event.card); }, - content:function(){ + content: function () { player.storage.cuijin_damage.remove(trigger.card); - if(!player.storage.cuijin_damage.length) player.removeSkill('cuijin_damage'); - if(trigger.player.isIn()&&!game.hasPlayer2(function(current){ - return current.hasHistory('damage',function(evt){ - return evt.card==trigger.card; - }); - })){ - player.line(trigger.player,'green'); + if (!player.storage.cuijin_damage.length) player.removeSkill("cuijin_damage"); + if ( + trigger.player.isIn() && + !game.hasPlayer2(function (current) { + return current.hasHistory("damage", function (evt) { + return evt.card == trigger.card; + }); + }) + ) { + player.line(trigger.player, "green"); trigger.player.damage(); } }, }, }, }, - jintao:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + jintao: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, - targetInRange:function(card){ - if(card.name=='sha') return true; + targetInRange: function (card) { + if (card.name == "sha") return true; }, }, - audio:2, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=player) return false; - var index=player.getHistory('useCard',function(evtx){ - return evtx.card.name=='sha'&&evtx.getParent('phaseUse')==evt; - }).indexOf(event); - return index==0||index==1; + audio: 2, + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != player) return false; + var index = player + .getHistory("useCard", function (evtx) { + return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt; + }) + .indexOf(event); + return index == 0 || index == 1; }, - 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,'伤害+1'); - if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + 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, "伤害+1"); + if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1; trigger.baseDamage++; - } - else{ - game.log(trigger.card,'不可被响应'); + } else { + game.log(trigger.card, "不可被响应"); trigger.directHit.addArray(game.players); } }, }, - equan:{ - audio:2, - trigger:{global:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player==_status.currentPhase&&event.player.isIn(); + equan: { + audio: 2, + trigger: { global: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player == _status.currentPhase && event.player.isIn(); }, - logTarget:'player', - content:function(){ - trigger.player.addMark('equan',trigger.num,false); + logTarget: "player", + content: function () { + trigger.player.addMark("equan", trigger.num, false); }, - group:['equan_block','equan_lose'], - marktext:'毒', - intro:{ - name:'恶泉(毒)', - name2:'毒', + group: ["equan_block", "equan_lose"], + marktext: "毒", + intro: { + name: "恶泉(毒)", + name2: "毒", }, - subSkill:{ - lose:{ - audio:'equan', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(){ - return game.hasPlayer(function(current){ - return current.hasMark('equan'); + subSkill: { + lose: { + audio: "equan", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function () { + return game.hasPlayer(function (current) { + return current.hasMark("equan"); }); }, - logTarget:function(){ - return game.filterPlayer(function(current){ - return current.hasMark('equan'); + logTarget: function () { + return game.filterPlayer(function (current) { + return current.hasMark("equan"); }); }, - content:function(){ - game.countPlayer(function(current){ - var num=current.countMark('equan'); - if(num){ - current.removeMark('equan',num); + content: function () { + game.countPlayer(function (current) { + var num = current.countMark("equan"); + if (num) { + current.removeMark("equan", num); current.loseHp(num); } }); }, }, - block:{ - trigger:{global:'dyingBegin'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - var evt=event.getParent(2); - return evt.name=='equan_lose'&&evt.player==player; + block: { + trigger: { global: "dyingBegin" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + var evt = event.getParent(2); + return evt.name == "equan_lose" && evt.player == player; }, - content:function(){ - trigger.player.addTempSkill('baiban'); + content: function () { + trigger.player.addTempSkill("baiban"); }, }, }, }, - manji:{ - audio:2, - trigger:{global:'loseHpAfter'}, - forced:true, - filter:function(event,player){ - return player!=event.player&&(player.hp>=event.player.hp||player.isDamaged()); + manji: { + audio: 2, + trigger: { global: "loseHpAfter" }, + forced: true, + filter: function (event, player) { + return player != event.player && (player.hp >= event.player.hp || player.isDamaged()); }, - logTarget:'player', - content:function(){ - if(player.hp<=trigger.player.hp) player.recover(); - if(player.hp>=trigger.player.hp) player.draw(); + logTarget: "player", + content: function () { + if (player.hp <= trigger.player.hp) player.recover(); + if (player.hp >= trigger.player.hp) player.draw(); }, }, - beini:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - var str=get.translation(target); - player.chooseControl().set('choiceList',[ - '摸两张牌,然后令'+str+'视为对自己使用【杀】', - '令'+str+'摸两张牌,然后视为对其使用【杀】', - ]).set('ai',function(){ - var evt=_status.event.getParent(),player=evt.player,target=evt.target; - var card={name:'sha',isCard:true},att=get.attitude(player,target)>0; - if(!target.canUse(card,player,false)||get.effect(player,card,target,player)>=0) return 0; - if(att&&(!player.canUse(card,target,false)||get.effect(target,card,player,player)>=0)) return 1; - if(target.hasSkill('nogain')&&player.canUse(card,target,false)&&get.effect(target,card,player,player)>0) return 1; - if(player.hasShan()) return 0; - if(att&&target.hasShan()) return 1; - return 0; - }); - 'step 1' - var list=[player,target]; - if(result.index==1) list.reverse(); - event.list=list; - list[0].draw(2); - 'step 2' - var list=event.list; - if(list[1].isIn()&&list[0].isIn()&&list[1].canUse('sha',list[0],false)) list[1].useCard({name:'sha',isCard:true},list[0],false,'noai'); + beini: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.hp >= player.hp; }, - ai:{ - order:5, - expose:0, - result:{ - player:function(player,target){ - var card={name:'sha',isCard:true},att=get.attitude(player,target)>0; - if(!target.canUse(card,player,false)||get.effect(player,card,target,player)>=0) return 2; - if(att&&(!player.canUse(card,target,false)||get.effect(target,card,player,player)>=0)) return 2; - if(target.hasSkill('nogain')&&player.canUse(card,target,false)) return get.effect(target,card,player,player) - if(player.hasShan()) return 1; - if(att&&target.hasShan()) return 1; + content: function () { + "step 0"; + var str = get.translation(target); + player + .chooseControl() + .set("choiceList", [ + "摸两张牌,然后令" + str + "视为对自己使用【杀】", + "令" + str + "摸两张牌,然后视为对其使用【杀】", + ]) + .set("ai", function () { + var evt = _status.event.getParent(), + player = evt.player, + target = evt.target; + var card = { name: "sha", isCard: true }, + att = get.attitude(player, target) > 0; + if ( + !target.canUse(card, player, false) || + get.effect(player, card, target, player) >= 0 + ) + return 0; + if ( + att && + (!player.canUse(card, target, false) || + get.effect(target, card, player, player) >= 0) + ) + return 1; + if ( + target.hasSkill("nogain") && + player.canUse(card, target, false) && + get.effect(target, card, player, player) > 0 + ) + return 1; + if (player.hasShan()) return 0; + if (att && target.hasShan()) return 1; + return 0; + }); + "step 1"; + var list = [player, target]; + if (result.index == 1) list.reverse(); + event.list = list; + list[0].draw(2); + "step 2"; + var list = event.list; + if (list[1].isIn() && list[0].isIn() && list[1].canUse("sha", list[0], false)) + list[1].useCard({ name: "sha", isCard: true }, list[0], false, "noai"); + }, + ai: { + order: 5, + expose: 0, + result: { + player: function (player, target) { + var card = { name: "sha", isCard: true }, + att = get.attitude(player, target) > 0; + if ( + !target.canUse(card, player, false) || + get.effect(player, card, target, player) >= 0 + ) + return 2; + if ( + att && + (!player.canUse(card, target, false) || + get.effect(target, card, player, player) >= 0) + ) + return 2; + if (target.hasSkill("nogain") && player.canUse(card, target, false)) + return get.effect(target, card, player, player); + if (player.hasShan()) return 1; + if (att && target.hasShan()) return 1; return 0; }, }, }, }, - dingfa:{ - audio:2, - trigger:{player:'phaseDiscardAfter'}, - direct:true, - filter:function(event,player){ - var num=0; - player.getHistory('lose',function(evt){ - num+=evt.cards2.length; + dingfa: { + audio: 2, + trigger: { player: "phaseDiscardAfter" }, + direct: true, + filter: function (event, player) { + var num = 0; + player.getHistory("lose", function (evt) { + num += evt.cards2.length; }); - return num>=player.hp; + return num >= player.hp; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('dingfa'),'操作提示:选择自己以回复体力,或选择其他角色以造成伤害',function(card,player,target){ - return target==player?player.isDamaged():true; - }).set('ai',function(target){ - return target!=player?get.damageEffect(target,player,player):get.recoverEffect(player,player,player) - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dingfa',target); - if(target==player) player.recover(); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("dingfa"), + "操作提示:选择自己以回复体力,或选择其他角色以造成伤害", + function (card, player, target) { + return target == player ? player.isDamaged() : true; + } + ) + .set("ai", function (target) { + return target != player + ? get.damageEffect(target, player, player) + : get.recoverEffect(player, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dingfa", target); + if (target == player) player.recover(); else target.damage(); } }, }, - dz_mantianguohai:{ - mod:{ - ignoredHandcard:function(card,player){ - if(get.name(card)=='dz_mantianguohai') return true; + dz_mantianguohai: { + mod: { + ignoredHandcard: function (card, player) { + if (get.name(card) == "dz_mantianguohai") return true; }, - cardDiscardable:function(card,player,name){ - if(name=='cardsDiscard'&&get.name(card)=='dz_mantianguohai') return false; + cardDiscardable: function (card, player, name) { + if (name == "cardsDiscard" && get.name(card) == "dz_mantianguohai") return false; }, }, }, - twmiaolve:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + twmiaolve: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - content:function(){ - if(!lib.inpile.includes('dz_mantianguohai')) lib.inpile.add('dz_mantianguohai'); - if(!_status.dz_mantianguohai_suits) _status.dz_mantianguohai_suits=lib.suit.slice(0); - var list=_status.dz_mantianguohai_suits.randomRemove(2).map(function(i){ - return game.createCard2('dz_mantianguohai',i,5); + forced: true, + locked: false, + content: function () { + if (!lib.inpile.includes("dz_mantianguohai")) lib.inpile.add("dz_mantianguohai"); + if (!_status.dz_mantianguohai_suits) _status.dz_mantianguohai_suits = lib.suit.slice(0); + var list = _status.dz_mantianguohai_suits.randomRemove(2).map(function (i) { + return game.createCard2("dz_mantianguohai", i, 5); }); - if(list.length) player.gain(list,'gain2','log'); + if (list.length) player.gain(list, "gain2", "log"); }, - group:'twmiaolve_damage', - subSkill:{ - damage:{ - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + group: "twmiaolve_damage", + subSkill: { + damage: { + trigger: { player: "damageEnd" }, + direct: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; - var list=['dz_mantianguohai']; + var list = ["dz_mantianguohai"]; list.addArray(get.zhinangs()); - player.chooseButton([get.prompt('twmiaolve'),[list,'vcard']]).set('ai',function(button){ - if(button.link[2]=='dz_mantianguohai'&&player.countCards('hs','dz_mantianguohai')<2) return 10; - return get.value({name:button.link[2]}); - }); - 'step 2' - if(result.bool){ - player.logSkill('twmiaolve'); - var name=result.links[0][2]; - if(name=='dz_mantianguohai'){ - if(!lib.inpile.includes('dz_mantianguohai')) lib.inpile.add('dz_mantianguohai'); - if(!_status.dz_mantianguohai_suits) _status.dz_mantianguohai_suits=lib.suit.slice(0); - if(_status.dz_mantianguohai_suits.length) player.gain(game.createCard2('dz_mantianguohai',_status.dz_mantianguohai_suits.randomRemove(),5),'gain2'); - else{ - var card=get.cardPile(function(card){ - return card.name==name; + player + .chooseButton([get.prompt("twmiaolve"), [list, "vcard"]]) + .set("ai", function (button) { + if ( + button.link[2] == "dz_mantianguohai" && + player.countCards("hs", "dz_mantianguohai") < 2 + ) + return 10; + return get.value({ name: button.link[2] }); + }); + "step 2"; + if (result.bool) { + player.logSkill("twmiaolve"); + var name = result.links[0][2]; + if (name == "dz_mantianguohai") { + if (!lib.inpile.includes("dz_mantianguohai")) + lib.inpile.add("dz_mantianguohai"); + if (!_status.dz_mantianguohai_suits) + _status.dz_mantianguohai_suits = lib.suit.slice(0); + if (_status.dz_mantianguohai_suits.length) + player.gain( + game.createCard2( + "dz_mantianguohai", + _status.dz_mantianguohai_suits.randomRemove(), + 5 + ), + "gain2" + ); + else { + var card = get.cardPile(function (card) { + return card.name == name; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } player.draw(); - } - else{ - var card=get.cardPile(function(card){ - return card.name==name; + } else { + var card = get.cardPile(function (card) { + return card.name == name; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); } - if(event.count>0&&player.hasSkill('twmiaolve')) event.goto(1); + if (event.count > 0 && player.hasSkill("twmiaolve")) event.goto(1); } }, }, }, }, - twyingjia:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - filter:function(event,player){ - if(!player.countCards('he')) return false; - var history=player.getHistory('useCard'),map={}; - for(var i of history){ - if(get.type2(i.card)=='trick'){ - if(!map[i.card.name]) map[i.card.name]=true; + twyingjia: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + filter: function (event, player) { + if (!player.countCards("he")) return false; + var history = player.getHistory("useCard"), + map = {}; + for (var i of history) { + if (get.type2(i.card) == "trick") { + if (!map[i.card.name]) map[i.card.name] = true; else return true; } } return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt('twyingjia'), - prompt2:'弃置一张牌并令一名角色进行一个额外回合', - filterCard:lib.filter.cardDiscardable, - filterTarget:true, - ai1:function(card){ - return 8-get.value(card); + prompt: get.prompt("twyingjia"), + prompt2: "弃置一张牌并令一名角色进行一个额外回合", + filterCard: lib.filter.cardDiscardable, + filterTarget: true, + ai1: function (card) { + return 8 - get.value(card); }, - ai2:function(target){ - if(target.hasJudge('lebu')) return -1; - var player=_status.event.player; - if(get.attitude(player,target)>4){ - return get.threaten(target)/Math.sqrt(target.hp+1)/Math.sqrt(target.countCards('h')+1); + ai2: function (target) { + if (target.hasJudge("lebu")) return -1; + var player = _status.event.player; + if (get.attitude(player, target) > 4) { + return ( + get.threaten(target) / + Math.sqrt(target.hp + 1) / + Math.sqrt(target.countCards("h") + 1) + ); } return -1; }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('twyingjia',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("twyingjia", target); player.discard(result.cards); target.insertPhase(); } }, }, - gx_lingbaoxianhu:{ - trigger:{ - source:'damageSource', - global:'dieAfter', + gx_lingbaoxianhu: { + trigger: { + source: "damageSource", + global: "dieAfter", }, - forced:true, - equipSkill:true, - filter:function(event,player){ - if(event.name=='damage') return event.num>1; + forced: true, + equipSkill: true, + filter: function (event, player) { + if (event.name == "damage") return event.num > 1; return true; }, - content:function(){ + content: function () { player.gainMaxHp(); player.recover(); }, }, - gx_taijifuchen:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'; + gx_taijifuchen: { + trigger: { player: "useCardToPlayered" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + return event.card && event.card.name == "sha"; }, - logTarget:'target', - content:function(){ - 'step 0' - var suit=get.suit(trigger.card); - var num=trigger.target.countCards('h','shan'); - var next=trigger.target.chooseToDiscard('弃置一张牌,或不能响应'+get.translation(trigger.card),'he').set('ai',function(card){ - var num=_status.event.num; - if(num==0) return 0; - if(card.name=='shan') return num>1?2:0; - return (get.suit(card)!=_status.event.suit?9:6)-get.value(card); - }).set('num',num); - if(lib.suit.includes(suit)){ - next.set('prompt2','若弃置的是'+get.translation(suit)+'牌,则改为'+get.translation(player)+'获得之'); - next.set('suit',suit); + logTarget: "target", + content: function () { + "step 0"; + var suit = get.suit(trigger.card); + var num = trigger.target.countCards("h", "shan"); + var next = trigger.target + .chooseToDiscard("弃置一张牌,或不能响应" + get.translation(trigger.card), "he") + .set("ai", function (card) { + var num = _status.event.num; + if (num == 0) return 0; + if (card.name == "shan") return num > 1 ? 2 : 0; + return (get.suit(card) != _status.event.suit ? 9 : 6) - get.value(card); + }) + .set("num", num); + if (lib.suit.includes(suit)) { + next.set( + "prompt2", + "若弃置的是" + + get.translation(suit) + + "牌,则改为" + + get.translation(player) + + "获得之" + ); + next.set("suit", suit); } - 'step 1' - if(result.bool){ - var card=result.cards[0]; - if(get.suit(card,trigger.target)==get.suit(trigger.card,false)&&get.position(card)=='d') player.gain(card,'gain2'); - } - else trigger.directHit.add(trigger.target); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + if ( + get.suit(card, trigger.target) == get.suit(trigger.card, false) && + get.position(card) == "d" + ) + player.gain(card, "gain2"); + } else trigger.directHit.add(trigger.target); }, }, - gx_chongyingshenfu:{ - trigger:{player:'damageEnd'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - if(!event.card||!event.card.name||player.getStorage('gx_chongyingshenfu_effect').includes(event.card.name)) return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source.hasSkillTag('unequip',false,{ - name:event.card.name, - target:player, - card:event.card, - })) return false; + gx_chongyingshenfu: { + trigger: { player: "damageEnd" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + if ( + !event.card || + !event.card.name || + player.getStorage("gx_chongyingshenfu_effect").includes(event.card.name) + ) + return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source.hasSkillTag("unequip", false, { + name: event.card.name, + target: player, + card: event.card, + }) + ) + return false; return true; }, - content:function(){ - player.markAuto('gx_chongyingshenfu_effect',[trigger.card.name]); + content: function () { + player.markAuto("gx_chongyingshenfu_effect", [trigger.card.name]); }, - group:'gx_chongyingshenfu_effect', - subSkill:{ - effect:{ - trigger:{player:'damageBegin4'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - if(!event.card||!event.card.name||!player.storage.gx_chongyingshenfu_effect||!player.getStorage('gx_chongyingshenfu_effect').includes(event.card.name)) return false; - if(player.hasSkillTag('unequip2')) return false; - if(event.source.hasSkillTag('unequip',false,{ - name:event.card.name, - target:player, - card:event.card, - })) return false; + group: "gx_chongyingshenfu_effect", + subSkill: { + effect: { + trigger: { player: "damageBegin4" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + if ( + !event.card || + !event.card.name || + !player.storage.gx_chongyingshenfu_effect || + !player.getStorage("gx_chongyingshenfu_effect").includes(event.card.name) + ) + return false; + if (player.hasSkillTag("unequip2")) return false; + if ( + event.source.hasSkillTag("unequip", false, { + name: event.card.name, + target: player, + card: event.card, + }) + ) + return false; return true; }, - content:function(){ + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(typeof card=='object'&&target.storage.gx_chongyingshenfu_effect&&target.getStorage('gx_chongyingshenfu_effect').includes(card.name)&&!target.hasSkillTag('unequip2')&& - (get.itemtype(player)!=='player'||!player.hasSkillTag('jueqing',false,target)&&!player.hasSkillTag('unequip',false,{ - name:card.name, - target:target, - card:card, - }))){ - if(player&&player.hasSkillTag('damageBonus',true,{ - target:target, - card:card - })) return 0.5; - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target) { + if ( + typeof card == "object" && + target.storage.gx_chongyingshenfu_effect && + target.getStorage("gx_chongyingshenfu_effect").includes(card.name) && + !target.hasSkillTag("unequip2") && + (get.itemtype(player) !== "player" || + (!player.hasSkillTag("jueqing", false, target) && + !player.hasSkillTag("unequip", false, { + name: card.name, + target: target, + card: card, + }))) + ) { + if ( + player && + player.hasSkillTag("damageBonus", true, { + target: target, + card: card, + }) + ) + return 0.5; + return "zeroplayertarget"; } - } - } + }, + }, }, - onremove:true, - intro:{ - content:'受到$造成的伤害-1', + onremove: true, + intro: { + content: "受到$造成的伤害-1", }, }, }, }, - twdanfa:{ - audio:2, - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - filter:function(event,player){ - return player.countCards('he')>0; + twdanfa: { + audio: 2, + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + filter: function (event, player) { + return player.countCards("he") > 0; }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('twdanfa'),'将一张牌作为“丹”置于武将牌上').set('ai',function(card){ - if(player.storage.twdanfa){ - var suit=get.suit(card); - for(var i of player.storage.twdanfa){ - if(get.suit(i,false)==suit) return 4-get.value(card); + direct: true, + content: function () { + "step 0"; + player + .chooseCard("he", get.prompt("twdanfa"), "将一张牌作为“丹”置于武将牌上") + .set("ai", function (card) { + if (player.storage.twdanfa) { + var suit = get.suit(card); + for (var i of player.storage.twdanfa) { + if (get.suit(i, false) == suit) return 4 - get.value(card); + } } - } - return 5.5-get.value(card); - }); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - player.logSkill('twdanfa'); - game.log(player,'将',card,'放在了武将牌上'); - player.$give(card,player,false); - player.lose(card,ui.special,'toStorage'); - player.markAuto('twdanfa',result.cards); - } - else event.finish(); - 'step 2' + return 5.5 - get.value(card); + }); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + player.logSkill("twdanfa"); + game.log(player, "将", card, "放在了武将牌上"); + player.$give(card, player, false); + player.lose(card, ui.special, "toStorage"); + player.markAuto("twdanfa", result.cards); + } else event.finish(); + "step 2"; game.delayx(); }, - mark:true, - intro:{ - content:'cards', - onunmark:'throw', + mark: true, + intro: { + content: "cards", + onunmark: "throw", }, - group:'twdanfa_draw', - subSkill:{ - draw:{ - audio:'twdanfa', - trigger:{player:'useCard'}, - forced:true, - locked:false, - filter:function(event,player){ - if(!player.storage.twdanfa||!player.storage.twdanfa.length) return false; - var suit=get.suit(event.card,false); - if(suit=='none'||player.storage.twdanfa_count&&player.storage.twdanfa_count.includes(suit)) return false; - for(var i of player.storage.twdanfa){ - if(get.suit(i,false)==suit) return true; + group: "twdanfa_draw", + subSkill: { + draw: { + audio: "twdanfa", + trigger: { player: "useCard" }, + forced: true, + locked: false, + filter: function (event, player) { + if (!player.storage.twdanfa || !player.storage.twdanfa.length) return false; + var suit = get.suit(event.card, false); + if ( + suit == "none" || + (player.storage.twdanfa_count && player.storage.twdanfa_count.includes(suit)) + ) + return false; + for (var i of player.storage.twdanfa) { + if (get.suit(i, false) == suit) return true; } return false; }, - content:function(){ + content: function () { player.draw(); - player.addTempSkill('twdanfa_count'); - if(!player.storage.twdanfa_count) player.storage.twdanfa_count=[]; - player.storage.twdanfa_count.push(get.suit(trigger.card,false)); + player.addTempSkill("twdanfa_count"); + if (!player.storage.twdanfa_count) player.storage.twdanfa_count = []; + player.storage.twdanfa_count.push(get.suit(trigger.card, false)); }, }, - count:{onremove:true}, + count: { onremove: true }, }, }, - twlingbao:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var list=player.getStorage('twdanfa'); - if(list.length<2) return false; - var suit=get.suit(list[0],false); - for(var i=1;ifalse; - obj.selectCard=-1; + select: 2, + backup: function (links) { + var obj = get.copy(lib.skill["twlingbao_" + get.color(links)]); + obj.cards = links; + obj.audio = "twlingbao"; + obj.filterCard = () => false; + obj.selectCard = -1; return obj; }, - prompt:function(links){ - return lib.skill['twlingbao_'+get.color(links)].prompt; + prompt: function (links) { + return lib.skill["twlingbao_" + get.color(links)].prompt; }, - check:function(button){ - var storage=_status.event.player.storage.twdanfa.slice(0); + check: function (button) { + var storage = _status.event.player.storage.twdanfa.slice(0); storage.remove(button.link); - if(storage.filter(function(card){ - return card.suit==button.link.suit; - }).length) return 1+Math.random(); + if ( + storage.filter(function (card) { + return card.suit == button.link.suit; + }).length + ) + return 1 + Math.random(); return 0; }, }, - subSkill:{ - red:{ - filterTarget:function(card,player,target){ + subSkill: { + red: { + filterTarget: function (card, player, target) { return target.isDamaged(); }, - delay:false, - prompt:'令一名角色回复1点体力', - content:function(){ - 'step 0' - var cards=lib.skill.twlingbao_backup.cards; - player.$throw(cards,1000); - player.unmarkAuto('twdanfa',cards); - game.log(player,'将',cards,'置入了弃牌堆'); + delay: false, + prompt: "令一名角色回复1点体力", + content: function () { + "step 0"; + var cards = lib.skill.twlingbao_backup.cards; + player.$throw(cards, 1000); + player.unmarkAuto("twdanfa", cards); + game.log(player, "将", cards, "置入了弃牌堆"); game.delayx(); game.cardsDiscard(cards); - 'step 1' + "step 1"; target.recover(); }, - ai:{ - tag:{ - recover:1, + ai: { + tag: { + recover: 1, }, - result:{ - target:1.5, + result: { + target: 1.5, }, }, }, - black:{ - filterTarget:function(card,player,target){ - return target.countDiscardableCards(player,'hej')>0; + black: { + filterTarget: function (card, player, target) { + return target.countDiscardableCards(player, "hej") > 0; }, - delay:false, - prompt:'弃置一名角色区域内至多两张区域不同的牌', - content:function(){ - 'step 0' - var cards=lib.skill.twlingbao_backup.cards; - player.$throw(cards,1000); - player.unmarkAuto('twdanfa',cards); - game.log(player,'将',cards,'置入了弃牌堆'); + delay: false, + prompt: "弃置一名角色区域内至多两张区域不同的牌", + content: function () { + "step 0"; + var cards = lib.skill.twlingbao_backup.cards; + player.$throw(cards, 1000); + player.unmarkAuto("twdanfa", cards); + game.log(player, "将", cards, "置入了弃牌堆"); game.delayx(); game.cardsDiscard(cards); - 'step 1' - var num=0; - if(target.countDiscardableCards(player,'h')) num++; - if(target.countDiscardableCards(player,'e')) num++; - if(target.countDiscardableCards(player,'j')) num++; - if(num){ - player.discardPlayerCard(target,[1,Math.max(2,num)],'hej',true).set('filterButton',function(button){ - for(var i=0;i0&&target.countCards('e',function(card){ - return get.value(card,target)<=0; - })>0&&target.countCards('j',function(card){ - return get.effect(target,card,target,target)<0; - })>8) return 3; - if(target.countCards('h')>0&&target.countCards('e',function(card){ - return get.value(card,target)>0; - })>0) return -2; + result: { + target: function (player, target) { + if ( + get.attitude(player, target) > 0 && + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) > 0 && + target.countCards("j", function (card) { + return get.effect(target, card, target, target) < 0; + }) > 8 + ) + return 3; + if ( + target.countCards("h") > 0 && + target.countCards("e", function (card) { + return get.value(card, target) > 0; + }) > 0 + ) + return -2; return 0; }, }, }, }, - none:{ - selectTarget:2, - filterTarget:function(card,player,target){ - if(!ui.selected.targets.length) return true; - return target.countCards('he')>0; + none: { + selectTarget: 2, + filterTarget: function (card, player, target) { + if (!ui.selected.targets.length) return true; + return target.countCards("he") > 0; }, - complexSelect:true, - targetprompt:['摸牌','弃牌'], - delay:false, - prompt:'令一名角色摸一张牌并令另一名角色弃置一张牌', - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - var cards=lib.skill.twlingbao_backup.cards; - player.$throw(cards,1000); - player.unmarkAuto('twdanfa',cards); - game.log(player,'将',cards,'置入了弃牌堆'); + complexSelect: true, + targetprompt: ["摸牌", "弃牌"], + delay: false, + prompt: "令一名角色摸一张牌并令另一名角色弃置一张牌", + multitarget: true, + multiline: true, + content: function () { + "step 0"; + var cards = lib.skill.twlingbao_backup.cards; + player.$throw(cards, 1000); + player.unmarkAuto("twdanfa", cards); + game.log(player, "将", cards, "置入了弃牌堆"); game.delayx(); game.cardsDiscard(cards); - 'step 1' + "step 1"; targets[0].draw(); - targets[1].chooseToDiscard('he',true); + targets[1].chooseToDiscard("he", true); }, - ai:{ - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return 1; - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })>0) return 1; + ai: { + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return 1; + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) > 0 + ) + return 1; return -1; }, }, }, }, - backup:{audio:'twlingbao'}, + backup: { audio: "twlingbao" }, }, - ai:{ - order:1, - result:{player:1}, + ai: { + order: 1, + result: { player: 1 }, + combo: "twdanfa", }, }, - twsidao:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + twsidao: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&!player.storage.twsidao; + forced: true, + locked: false, + filter: function (event, player) { + return (event.name != "phase" || game.phaseNumber == 0) && !player.storage.twsidao; }, - content:function(){ - 'step 0' - player.chooseButton(['请选择你的初始法宝',[['gx_lingbaoxianhu','gx_taijifuchen','gx_chongyingshenfu'],'vcard']],true).set('ai',function(button){ - return button.link[2]=='gx_chongyingshenfu'?2:1; - }); - 'step 1' - if(result.bool){ - var card=game.createCard2(result.links[0][2]); + content: function () { + "step 0"; + player + .chooseButton( + [ + "请选择你的初始法宝", + [["gx_lingbaoxianhu", "gx_taijifuchen", "gx_chongyingshenfu"], "vcard"], + ], + true + ) + .set("ai", function (button) { + return button.link[2] == "gx_chongyingshenfu" ? 2 : 1; + }); + "step 1"; + if (result.bool) { + var card = game.createCard2(result.links[0][2]); lib.inpile.add(result.links[0][2]); - player.storage.twsidao=card; - player.chooseUseTarget(card,'nopopup',true); + player.storage.twsidao = card; + player.chooseUseTarget(card, "nopopup", true); } }, - group:'twsidao_equip', - subSkill:{ - equip:{ - audio:'twsidao', - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - var card=player.storage.twsidao; - return card&&card.isInPile()&&player.hasUseTarget(card); + group: "twsidao_equip", + subSkill: { + equip: { + audio: "twsidao", + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + var card = player.storage.twsidao; + return card && card.isInPile() && player.hasUseTarget(card); }, - content:function(){ - player.chooseUseTarget(player.storage.twsidao,'nopopup',true); + content: function () { + player.chooseUseTarget(player.storage.twsidao, "nopopup", true); }, }, }, }, - twrangyi:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + twrangyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:lib.filter.notMe, - delay:0, - content:function(){ - 'step 0' - event.cards=player.getCards('h'); - player.give(event.cards,target).gaintag.add('twrangyi'); - target.addTempSkill('twrangyi2'); - 'step 1' + filterTarget: lib.filter.notMe, + delay: 0, + content: function () { + "step 0"; + event.cards = player.getCards("h"); + player.give(event.cards, target).gaintag.add("twrangyi"); + target.addTempSkill("twrangyi2"); + "step 1"; target.chooseToUse({ - prompt:'请使用得到的一张牌,或者受到来自'+get.translation(player)+'的1点伤害', - filterCard:function(card,player){ - if(get.itemtype(card)!='card'||!card.hasGaintag('twrangyi')) return false; - return lib.filter.filterCard(card,player,event); + prompt: "请使用得到的一张牌,或者受到来自" + get.translation(player) + "的1点伤害", + filterCard: function (card, player) { + if (get.itemtype(card) != "card" || !card.hasGaintag("twrangyi")) return false; + return lib.filter.filterCard(card, player, event); }, - cards:cards, + cards: cards, }); - 'step 2' - target.removeSkill('twrangyi2'); - if(!result.bool) target.damage('nocard'); + "step 2"; + target.removeSkill("twrangyi2"); + if (!result.bool) target.damage("nocard"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var hs=player.getCards('h'); - for(var i=0;i0; + twrangyi2: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + var evt = event.getParent(2); + return ( + evt.name == "twrangyi" && + evt.player.isIn() && + player.countCards("h", function (card) { + return card.hasGaintag("twrangyi"); + }) > 0 + ); }, - content:function(){ - var cards=player.getCards('h',function(card){ - return card.hasGaintag('twrangyi'); + content: function () { + var cards = player.getCards("h", function (card) { + return card.hasGaintag("twrangyi"); }); game.delayx(); - player.give(cards,trigger.getParent(2).player); + player.give(cards, trigger.getParent(2).player); }, - onremove:function(player){ - player.removeGaintag('twrangyi'); + onremove: function (player) { + player.removeGaintag("twrangyi"); }, }, - twbaimei:{ - audio:2, - trigger:{ - player:"damageBegin4", + twbaimei: { + audio: 2, + trigger: { + player: "damageBegin4", }, - forced:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - if(event.hasNature()) return true; - return get.type(event.card,'trick')=='trick'; + forced: true, + filter: function (event, player) { + if (player.countCards("h")) return false; + if (event.hasNature()) return true; + return get.type(event.card, "trick") == "trick"; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target.countCards('h')) return; - if(get.tag(card,'natureDamage')) return 'zeroplayertarget'; - if(get.type(card)=='trick'&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (target.countCards("h")) return; + if (get.tag(card, "natureDamage")) return "zeroplayertarget"; + if (get.type(card) == "trick" && get.tag(card, "damage")) { + return "zeroplayertarget"; } }, }, }, }, - twhuzhu:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(e,player){ - return player.countCards('e')>0; + twhuzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (e, player) { + return player.countCards("e") > 0; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0 + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - target.chooseCard('交给'+get.translation(player)+'一张手牌','h',true); - 'step 1' - target.give(result.cards,player); - 'step 2' - if(player.countGainableCards(player,'e')) target.gainPlayerCard(player,'e',true); - 'step 3' - if(target.isDamaged()&&target.hp<=player.hp){ - player.chooseBool('是否令'+get.translation(target)+'回复1点体力?').set('ai',function(){ - return get.recoverEffect(target,player,player); - }); + content: function () { + "step 0"; + target.chooseCard("交给" + get.translation(player) + "一张手牌", "h", true); + "step 1"; + target.give(result.cards, player); + "step 2"; + if (player.countGainableCards(player, "e")) target.gainPlayerCard(player, "e", true); + "step 3"; + if (target.isDamaged() && target.hp <= player.hp) { + player + .chooseBool("是否令" + get.translation(target) + "回复1点体力?") + .set("ai", function () { + return get.recoverEffect(target, player, player); + }); } - 'step 4' - if(result.bool) target.recover(); + "step 4"; + if (result.bool) target.recover(); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - var eff=(target.isDamaged()&&target.hp<=player.hp)?get.recoverEffect(target,player,target):0; - if(eff<=0&&!player.countGainableCards(target,'e')) return -1; + ai: { + order: 8, + result: { + target: function (player, target) { + var eff = + target.isDamaged() && target.hp <= player.hp + ? get.recoverEffect(target, player, target) + : 0; + if (eff <= 0 && !player.countGainableCards(target, "e")) return -1; return eff; }, }, }, }, - twliancai:{ - audio:2, - trigger:{player:['turnOverEnd','phaseJieshuBegin']}, - filter:function(card,player,target){ - return target=='phaseJieshuBegin'||player.countCards('h')0; + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "e") > 0; }, - check:function(card,player){ - if(card.name=='turnOver') return true; - if(player.isTurnedOver()) return true; - if(player.hp-player.countCards('h')>1) return true; - return game.hasPlayer(function(current){ - return lib.skill.twliancai.filterTarget(null,player,current)&&lib.skill.twliancai.filterAI(current); + check: function (card, player) { + if (card.name == "turnOver") return true; + if (player.isTurnedOver()) return true; + if (player.hp - player.countCards("h") > 1) return true; + return game.hasPlayer(function (current) { + return ( + lib.skill.twliancai.filterTarget(null, player, current) && + lib.skill.twliancai.filterAI(current) + ); }); }, - filterAI:function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(target.isDamaged()&&target.countCards('e','baiyin')&&att>0) return 2*att; + filterAI: function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (target.isDamaged() && target.countCards("e", "baiyin") && att > 0) return 2 * att; return -att; }, - prompt2:function(card,player,target){ - return card.name=='phaseJieshu'?'将武将牌翻面,然后获得一名其他角色装备区内的一张牌':'将手牌摸至与体力值相同'; + prompt2: function (card, player, target) { + return card.name == "phaseJieshu" + ? "将武将牌翻面,然后获得一名其他角色装备区内的一张牌" + : "将手牌摸至与体力值相同"; }, - content:function(){ - 'step 0' - if(event.triggername=='phaseJieshuBegin') player.turnOver(); - else{ - player.draw(player.hp-player.countCards('h')); + content: function () { + "step 0"; + if (event.triggername == "phaseJieshuBegin") player.turnOver(); + else { + player.draw(player.hp - player.countCards("h")); event.finish(); } - 'step 1' - player.chooseTarget('获得一名角色装备区内的一张牌',lib.skill.twliancai.filterTarget).ai=lib.skill.twliancai.filterAI; - 'step 2' - if(result.bool){ - player.line(result.targets,'thunder'); - player.gainPlayerCard('e',true,result.targets[0]); + "step 1"; + player.chooseTarget("获得一名角色装备区内的一张牌", lib.skill.twliancai.filterTarget).ai = + lib.skill.twliancai.filterAI; + "step 2"; + if (result.bool) { + player.line(result.targets, "thunder"); + player.gainPlayerCard("e", true, result.targets[0]); } }, }, - twqijia:{ + twqijia: { //group:'twqijia_alka', - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('e',function(card){ - return !player.getStorage('twqijia_alka').includes(get.subtype(card)); + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("e", function (card) { + return !player.getStorage("twqijia_alka").includes(get.subtype(card)); }); }, - filterTarget:function(card,player,target){ - return target!=player&&player.canUse({name:'sha'},target); + filterTarget: function (card, player, target) { + return target != player && player.canUse({ name: "sha" }, target); }, - position:'e', - filterCard:function(card,player){ - return !player.getStorage('twqijia_alka').includes(get.subtype(card)); + position: "e", + filterCard: function (card, player) { + return !player.getStorage("twqijia_alka").includes(get.subtype(card)); }, - content:function(){ - 'step 0' - player.addTempSkill('twqijia_alka'); + content: function () { + "step 0"; + player.addTempSkill("twqijia_alka"); player.storage.twqijia_alka.push(get.subtype(cards[0])); - player.useCard({name:'sha'},target,false); + player.useCard({ name: "sha" }, target, false); }, - subSkill:{ - alka:{ - charlotte:true, - onremove:function(player){ + subSkill: { + alka: { + charlotte: true, + onremove: function (player) { delete player.storage.twqijia_alka; delete player.storage.twzhuchen; - player.unmarkSkill('twzhuchen'); + player.unmarkSkill("twzhuchen"); }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; - if(!player.storage.twzhuchen) player.storage.twzhuchen=[]; + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; + if (!player.storage.twzhuchen) player.storage.twzhuchen = []; }, - mod:{ - globalFrom:function(from,to,distance){ - if(from.storage.twzhuchen&&from.storage.twzhuchen.includes(to)) return -Infinity; - } - }, - }, - }, - check:function(card){ - return 7-get.value(card); - }, - ai:{ - order:function(){ - return get.order({name:'sha'})-0.2; - }, - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,player); - }, - }, - }, - }, - twzhuchen:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h',lib.skill.twzhuchen.filterCard)>0; - }, - filterCard:function(card,player){ - var name=get.name(card,player); - return name=='tao'||name=='jiu'; - }, - filterTarget:lib.filter.notMe, - content:function(){ - player.addTempSkill('twqijia_alka'); - player.storage.twzhuchen.add(target); - player.markSkill('twzhuchen'); - }, - intro:{ - content:function(content,player){ - return '至'+get.translation(content)+'的距离视为1'; - }, - }, - }, - twxiaolian:{ - audio:2, - trigger:{global:'useCardToTarget'}, - logTarget:'target', - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.player!=player&& - event.targets.length==1&&event.targets[0]!=player; - }, - check:function(event,player){ - return get.effect(event.targets[0],event.card,event.player,player)<=get.effect(player,event.card,event.player,player); - }, - content:function(){ - trigger.getParent().twxiaolian=trigger.targets[0]; - trigger.targets.length=0; - trigger.getParent().triggeredTargets2.length=0; - trigger.targets.push(player); - }, - group:'twxiaolian_damage', - subSkill:{ - distance:{ - sub:true, - charlotte:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; - }, - mark:true, - marktext:'马', - intro:{ - content:'cards', - onunmark:'throw', - }, - mod:{ - globalTo:function(from,to,distance){ - if(from!=to&&to.storage.twxiaolian_distance) return distance+to.storage.twxiaolian_distance.length; + mod: { + globalFrom: function (from, to, distance) { + if (from.storage.twzhuchen && from.storage.twzhuchen.includes(to)) + return -Infinity; }, }, }, - damage:{ - sub:true, - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return event.getParent(2).twxiaolian!=undefined; + }, + check: function (card) { + return 7 - get.value(card); + }, + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.2; + }, + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, player); }, - content:function(){ - 'step 0' - var target=trigger.getParent(2).twxiaolian; - event.target=target; - player.chooseCard('是否将一张牌当做【马】置于'+get.translation(target)+'的武将牌旁?','he').ai=function(card){ - if(get.attitude(_status.event.player,_status.event.getParent('twxiaolian_damage').target)>2) return 7-get.value(card); + }, + }, + }, + twzhuchen: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", lib.skill.twzhuchen.filterCard) > 0; + }, + filterCard: function (card, player) { + var name = get.name(card, player); + return name == "tao" || name == "jiu"; + }, + filterTarget: lib.filter.notMe, + content: function () { + player.addTempSkill("twqijia_alka"); + player.storage.twzhuchen.add(target); + player.markSkill("twzhuchen"); + }, + intro: { + content: function (content, player) { + return "至" + get.translation(content) + "的距离视为1"; + }, + }, + }, + twxiaolian: { + audio: 2, + trigger: { global: "useCardToTarget" }, + logTarget: "target", + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.player != player && + event.targets.length == 1 && + event.targets[0] != player + ); + }, + check: function (event, player) { + return ( + get.effect(event.targets[0], event.card, event.player, player) <= + get.effect(player, event.card, event.player, player) + ); + }, + content: function () { + trigger.getParent().twxiaolian = trigger.targets[0]; + trigger.targets.length = 0; + trigger.getParent().triggeredTargets2.length = 0; + trigger.targets.push(player); + }, + group: "twxiaolian_damage", + subSkill: { + distance: { + sub: true, + charlotte: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; + }, + mark: true, + marktext: "马", + intro: { + content: "cards", + onunmark: "throw", + }, + mod: { + globalTo: function (from, to, distance) { + if (from != to && to.storage.twxiaolian_distance) + return distance + to.storage.twxiaolian_distance.length; + }, + }, + }, + damage: { + sub: true, + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return event.getParent(2).twxiaolian != undefined; + }, + content: function () { + "step 0"; + var target = trigger.getParent(2).twxiaolian; + event.target = target; + player.chooseCard( + "是否将一张牌当做【马】置于" + get.translation(target) + "的武将牌旁?", + "he" + ).ai = function (card) { + if ( + get.attitude( + _status.event.player, + _status.event.getParent("twxiaolian_damage").target + ) > 2 + ) + return 7 - get.value(card); return 0; }; - 'step 1' - if(result.bool){ - player.logSkill('twxiaolian',target); - player.lose(result.cards,ui.special,'toStorage'); - target.addSkill('twxiaolian_distance'); + "step 1"; + if (result.bool) { + player.logSkill("twxiaolian", target); + player.lose(result.cards, ui.special, "toStorage"); + target.addSkill("twxiaolian_distance"); target.storage.twxiaolian_distance.addArray(result.cards); - target.markSkill('twxiaolian_distance'); + target.markSkill("twxiaolian_distance"); } }, }, }, }, - twtijin:{ - audio:2, - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.player!=player&&event.target!=player&& - event.targets.length==1&&event.player.inRange(player); + twtijin: { + audio: 2, + trigger: { global: "useCardToPlayer" }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.player != player && + event.target != player && + event.targets.length == 1 && + event.player.inRange(player) + ); }, - logTarget:'target', - check:function(event,player){ - return get.effect(event.targets[0],event.card,event.player,player)<=get.effect(player,event.card,event.player,player); + logTarget: "target", + check: function (event, player) { + return ( + get.effect(event.targets[0], event.card, event.player, player) <= + get.effect(player, event.card, event.player, player) + ); }, - content:function(){ - 'step 0' - trigger.targets.length=0; - trigger.getParent().triggeredTargets1.length=0; + content: function () { + "step 0"; + trigger.targets.length = 0; + trigger.getParent().triggeredTargets1.length = 0; trigger.targets.push(player); - var next=game.createEvent('twtijin_discard',null,trigger.getParent(2)); - next.player=player; - next.target=trigger.player; - next.setContent(function(){ - if(target.isDead()||!target.countCards('he')) return; - player.line(target,'green'); - player.discardPlayerCard(target,true,'he'); + var next = game.createEvent("twtijin_discard", null, trigger.getParent(2)); + next.player = player; + next.target = trigger.player; + next.setContent(function () { + if (target.isDead() || !target.countCards("he")) return; + player.line(target, "green"); + player.discardPlayerCard(target, true, "he"); }); }, }, - twyanqin:{ - forbid:['guozhan'], - audio:2, - trigger:{player:'phaseBegin'}, - direct:true, - content:function(){ - 'step 0' - var list=[]; - if(player.group!='wei') list.push('wei2'); - if(player.group!='shu') list.push('shu2'); - list.push('cancel2'); - player.chooseControl(list).set('ai',function(){ - return list.randomGet(); - }).set('prompt',get.prompt2('twyanqin')); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('twyanqin'); - var group=result.control.slice(0,3); + twyanqin: { + forbid: ["guozhan"], + audio: 2, + trigger: { player: "phaseBegin" }, + direct: true, + content: function () { + "step 0"; + var list = []; + if (player.group != "wei") list.push("wei2"); + if (player.group != "shu") list.push("shu2"); + list.push("cancel2"); + player + .chooseControl(list) + .set("ai", function () { + return list.randomGet(); + }) + .set("prompt", get.prompt2("twyanqin")); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("twyanqin"); + var group = result.control.slice(0, 3); player.changeGroup(group); } }, }, - twbaobian:{ - audio:2, - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - var card=event.card; - if(!card||(card.name!='sha'&&card.name!='juedou')) return false; - return event.player.group==player.group||event.player.countCards('h')>event.player.hp + twbaobian: { + audio: 2, + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + var card = event.card; + if (!card || (card.name != "sha" && card.name != "juedou")) return false; + return ( + event.player.group == player.group || event.player.countCards("h") > event.player.hp + ); }, - check:function(event,player){ - var att=get.attitude(player,event.player); - if(event.player.group==player.group) return att>0; - return att<0; + check: function (event, player) { + var att = get.attitude(player, event.player); + if (event.player.group == player.group) return att > 0; + return att < 0; }, - logTarget:'player', - content:function(){ - var target=trigger.player; - if(target.group==player.group){ + logTarget: "player", + content: function () { + var target = trigger.player; + if (target.group == player.group) { trigger.cancel(); - var num=target.maxHp-target.countCards('h'); - if(num) target.draw(num); - } - else{ - player.discardPlayerCard(target,'h',true,target.countCards('h')-target.hp) + var num = target.maxHp - target.countCards("h"); + if (num) target.draw(num); + } else { + player.discardPlayerCard(target, "h", true, target.countCards("h") - target.hp); } }, }, - chijie:{ - audio:true, - forbid:['guozhan'], - trigger:{ - global:'phaseBefore', - player:'enterGame', + chijie: { + audio: true, + forbid: ["guozhan"], + trigger: { + global: "phaseBefore", + player: "enterGame", }, - direct:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.hasPlayer(function(current){ - return current.group!=player.group&&lib.group.includes(current.group); + direct: true, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + game.hasPlayer(function (current) { + return current.group != player.group && lib.group.includes(current.group); + }) + ); + }, + content: function () { + "step 0"; + var list = lib.group.filter(function (group) { + return ( + group != player.group && + game.hasPlayer(function (current) { + return current.group == group; + }) + ); }); - }, - content:function(){ - 'step 0' - var list=lib.group.filter(function(group){ - return group!=player.group&&game.hasPlayer(function(current){ - return current.group==group; + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("chijie")) + .set("prompt2", "将自己的势力变更为场上存在的一个势力") + .set("ai", function () { + return list.randomGet(); }); - }); - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('chijie')).set('prompt2','将自己的势力变更为场上存在的一个势力').set('ai',function(){ - return list.randomGet(); - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('chijie'); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("chijie"); player.changeGroup(result.control); } }, }, - waishi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - let used=player.getStat('skill').waishi; - if(used&&used>player.countMark('waishi_remover')) return false; - return player.countCards('he')>0&&game.hasPlayer(target=>target!=player&&target.countCards('h')>0); + waishi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + let used = player.getStat("skill").waishi; + if (used && used > player.countMark("waishi_remover")) return false; + return ( + player.countCards("he") > 0 && + game.hasPlayer((target) => target != player && target.countCards("h") > 0) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>=ui.selected.cards.length; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") >= ui.selected.cards.length; }, - filterCard:true, - position:'he', - check:function(card){ - if(!game.hasPlayer(function(current){ - return current!=_status.event.player&¤t.countCards('h')>ui.selected.cards.length; - })) return 0; - return 6-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + if ( + !game.hasPlayer(function (current) { + return ( + current != _status.event.player && + current.countCards("h") > ui.selected.cards.length + ); + }) + ) + return 0; + return 6 - get.value(card); }, - selectCard:function(){ - if(!ui.selected.targets.length) return [1,game.countGroup()]; - return [1,Math.min(ui.selected.targets[0].countCards('h'),game.countGroup())]; + selectCard: function () { + if (!ui.selected.targets.length) return [1, game.countGroup()]; + return [1, Math.min(ui.selected.targets[0].countCards("h"), game.countGroup())]; }, - discard:false, - lose:false, - delay:0, - content:function(){ - 'step 0' - player.choosePlayerCard(target,true,'h',cards.length); - 'step 1' - player.swapHandcards(target,cards,result.cards); + discard: false, + lose: false, + delay: 0, + content: function () { + "step 0"; + player.choosePlayerCard(target, true, "h", cards.length); + "step 1"; + player.swapHandcards(target, cards, result.cards); game.delayex(); - 'step 2' - if(target.countCards('h')>player.countCards('h')||player.group==target.group) player.draw(); + "step 2"; + if (target.countCards("h") > player.countCards("h") || player.group == target.group) + player.draw(); }, - ai:{ - order:7, - result:{ - player:function(player,target){ - if(player.countCards('h'){ - return current.group!=player.group&&lib.group.includes(current.group); - })) controls.unshift('选项一'); - if(game.hasPlayer(current=>current!=player)) controls.push('选项三'); - player.chooseControl(controls,'cancel2').set('prompt',get.prompt('renshe')).set('choiceList',choiceList).set('ai',function(){ - if(game.hasPlayer(function(current){ - return get.attitude(player,current)>0||current.hasSkillTag('nogain'); - })) return '选项三' - return '选项二'; - }); - 'step 1' - if(result.control=='cancel2') event.finish(); - else{ - player.logSkill('renshe'); - switch(result.control){ - case '选项一': + var controls = ["选项二"]; + if ( + game.hasPlayer((current) => { + return current.group != player.group && lib.group.includes(current.group); + }) + ) + controls.unshift("选项一"); + if (game.hasPlayer((current) => current != player)) controls.push("选项三"); + player + .chooseControl(controls, "cancel2") + .set("prompt", get.prompt("renshe")) + .set("choiceList", choiceList) + .set("ai", function () { + if ( + game.hasPlayer(function (current) { + return get.attitude(player, current) > 0 || current.hasSkillTag("nogain"); + }) + ) + return "选项三"; + return "选项二"; + }); + "step 1"; + if (result.control == "cancel2") event.finish(); + else { + player.logSkill("renshe"); + switch (result.control) { + case "选项一": event.goto(3); break; - case '选项二': - player.addMark('waishi_remover',1,false); - player.addTempSkill('waishi_remover',{player:'phaseUseAfter'}); + case "选项二": + player.addMark("waishi_remover", 1, false); + player.addTempSkill("waishi_remover", { player: "phaseUseAfter" }); event.finish(); break; - case '选项三': - player.chooseTarget('请选择一名角色,与其各摸一张牌',lib.filter.notMe,true).set('ai',function(target){ - if(target.hasSkillTag('nogain')) return 0.1; - return get.attitude(_status.event.player,target); - }) + case "选项三": + player + .chooseTarget("请选择一名角色,与其各摸一张牌", lib.filter.notMe, true) + .set("ai", function (target) { + if (target.hasSkillTag("nogain")) return 0.1; + return get.attitude(_status.event.player, target); + }); } } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.asyncDraw([player,target].sortBySeat()); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.asyncDraw([player, target].sortBySeat()); } game.delayex(); event.finish(); - 'step 3' - var list=lib.group.filter(function(group){ - return group!=player.group&&game.hasPlayer(function(current){ - return current.group==group; + "step 3"; + var list = lib.group.filter(function (group) { + return ( + group != player.group && + game.hasPlayer(function (current) { + return current.group == group; + }) + ); + }); + player + .chooseControl(list) + .set("prompt", get.prompt("chijie")) + .set("prompt2", "将自己的势力变更为场上存在的一个势力") + .set("ai", function () { + return list.randomGet(); }); - }); - player.chooseControl(list).set('prompt',get.prompt('chijie')).set('prompt2','将自己的势力变更为场上存在的一个势力').set('ai',function(){ - return list.randomGet(); - }); - 'step 4' + "step 4"; player.changeGroup(result.control); }, }, //英文版特典武将凯撒 - zhengfu:{ - trigger:{ - player:"useCardToPlayered", + zhengfu: { + trigger: { + player: "useCardToPlayered", }, - check:function (event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - filter:function(event,player){ - return event.card.name=='sha'; + filter: function (event, player) { + return event.card.name == "sha"; }, - logTarget:"target", - line:false, - content:function(){ - 'step 0' - player.line(trigger.target,{color:[220, 90, 139]}); - player.chooseControl(['basic','trick','equip']).set('ai',function(){ - var player=_status.event.target; - if(!player.countCards('h','sha')&&player.countCards('h','shan')) return 'trick'; - return 'basic'; - }).set('prompt','请选择一种牌的类别').set('target',trigger.target); - 'step 1' - trigger.target.chooseCard('he','交给'+get.translation(player)+'一张'+get.translation(result.control)+'牌,否则此【杀】不可被闪避',function(card){ - return get.type2(card)==_status.event.control; - }).set('ai',function(card){ - var num=_status.event.num; - if(num==0) return 0; - if(card.name=='shan') return num>1?2:0; - return 8-get.value(card); - }).set('num',trigger.target.countCards('h','shan')).set('control',result.control); - 'step 2' - if(result.bool){ - var cards=result.cards; - trigger.target.give(cards,player); - } - else{ + logTarget: "target", + line: false, + content: function () { + "step 0"; + player.line(trigger.target, { color: [220, 90, 139] }); + player + .chooseControl(["basic", "trick", "equip"]) + .set("ai", function () { + var player = _status.event.target; + if (!player.countCards("h", "sha") && player.countCards("h", "shan")) + return "trick"; + return "basic"; + }) + .set("prompt", "请选择一种牌的类别") + .set("target", trigger.target); + "step 1"; + trigger.target + .chooseCard( + "he", + "交给" + + get.translation(player) + + "一张" + + get.translation(result.control) + + "牌,否则此【杀】不可被闪避", + function (card) { + return get.type2(card) == _status.event.control; + } + ) + .set("ai", function (card) { + var num = _status.event.num; + if (num == 0) return 0; + if (card.name == "shan") return num > 1 ? 2 : 0; + return 8 - get.value(card); + }) + .set("num", trigger.target.countCards("h", "shan")) + .set("control", result.control); + "step 2"; + if (result.bool) { + var cards = result.cards; + trigger.target.give(cards, player); + } else { trigger.getParent().directHit.add(trigger.target); game.delay(); } - } - } + }, + }, }, - perfectPair:{ - tw_liufuren:['yuanshao'], - tw_xiahoushang:['caopi'], + perfectPair: { + tw_liufuren: ["yuanshao"], + tw_xiahoushang: ["caopi"], }, - characterReplace:{ - tw_caocao:['tw_caocao','jsrg_caocao','yj_caocao'], - mateng:['tw_mateng','mateng'], - xiahouen:['tw_xiahouen','jsrg_xiahouen'], - jiangji:['dc_jiangji','tw_jiangji','jiangji'], - baoxin:['tw_baoxin','baoxin'], - yanxiang:['yanxiang','tw_yanxiang'], - liwei:['liwei','tw_liwei'], + characterReplace: { + tw_caocao: ["tw_caocao", "jsrg_caocao", "yj_caocao"], + mateng: ["tw_mateng", "mateng"], + xiahouen: ["tw_xiahouen", "jsrg_xiahouen"], + jiangji: ["dc_jiangji", "tw_jiangji", "jiangji"], + baoxin: ["tw_baoxin", "baoxin"], + yanxiang: ["yanxiang", "tw_yanxiang"], + liwei: ["liwei", "tw_liwei"], }, - dynamicTranslate:{ - twfeifu:function(player){ - var str='锁定技,转换技。'; - if(!player.storage.twfeifu) str+=''; - str+='阴:当你成为【杀】的唯一目标后;'; - if(!player.storage.twfeifu) str+=''; - if(player.storage.twfeifu) str+=''; - str+='阳:当你使用【杀】指定唯一目标后;'; - if(player.storage.twfeifu) str+=''; - str+='目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。'; + dynamicTranslate: { + twfeifu: function (player) { + var str = "锁定技,转换技。"; + if (!player.storage.twfeifu) str += ''; + str += "阴:当你成为【杀】的唯一目标后;"; + if (!player.storage.twfeifu) str += ""; + if (player.storage.twfeifu) str += ''; + str += "阳:当你使用【杀】指定唯一目标后;"; + if (player.storage.twfeifu) str += ""; + str += "目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。"; return str; }, - twfengpo:function(player){ - if(player.storage.twfengpo) return '当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的红色牌数)。'; - return '①当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的♦数)。②当你杀死一名角色后,你将〖凤魄①〗中的“♦数”改为“红色牌数”。'; + twfengpo: function (player) { + if (player.storage.twfengpo) + return "当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的红色牌数)。"; + return "①当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的♦数)。②当你杀死一名角色后,你将〖凤魄①〗中的“♦数”改为“红色牌数”。"; }, - twjiexun:function(player){ - return lib.translate[player.hasSkill('funan_jiexun')?'twjiexunx_info':'twjiexun_info']; + twjiexun: function (player) { + return lib.translate[player.hasSkill("funan_jiexun") ? "twjiexunx_info" : "twjiexun_info"]; }, twzhenliang: function (player) { - if(player.storage.twzhenliang) return '转换技。阴:出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。阳:当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。'; + if (player.storage.twzhenliang) + return '转换技。阴:出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。阳:当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。'; return '转换技。阴:出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。阳:当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。'; }, - twdengjian:function(player){ - let str='①其他角色的弃牌阶段结束时,你可以随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】,称为“剑法”。'; - if(player.hasSkill('twdengjian_ban')) str=''+str+''; - str+='②你使用“剑法”牌不计入次数限制。'; + twdengjian: function (player) { + let str = + "①其他角色的弃牌阶段结束时,你可以随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】,称为“剑法”。"; + if (player.hasSkill("twdengjian_ban")) str = '' + str + ""; + str += "②你使用“剑法”牌不计入次数限制。"; return str; }, - twduwang(player){ - let str='使命技。'; - if(!player.storage.twduwang_fail) str+='①'; - str+='出牌阶段开始时,你可以选择至多三名有牌的其他角色,摸X张牌(X为选择角色数+1),然后这些角色依次将一张牌当【决斗】对你使用。'; - if(!player.storage.twduwang_fail) str+=`\ + twduwang(player) { + let str = "使命技。"; + if (!player.storage.twduwang_fail) str += "①"; + str += + "出牌阶段开始时,你可以选择至多三名有牌的其他角色,摸X张牌(X为选择角色数+1),然后这些角色依次将一张牌当【决斗】对你使用。"; + if (!player.storage.twduwang_fail) + str += `\ ②当你处于濒死状态时,其他角色不能对你使用【桃】。\ ③使命:使用【决斗】或成为【决斗】目标的次数之和不小于4(若游戏总人数小于4则改为3)。\ ④成功:准备阶段,若你于你的上回合完成了〖独往③〗的使命,则你重置〖独往〗并将〖独往〗修改至只保留〖独往①〗的效果,选择一项:⒈获得〖狭勇〗;⒉重置〖延势〗并令其获得历战效果。\ ⑤失败:当你死亡时,使命失败。`; return str; }, - twylyanshi(player){ - return lib.translate[(player.storage.twduwang_ylyanshi?'twylyanshix':'twylyanshi')+'_info']; + twylyanshi(player) { + return lib.translate[ + (player.storage.twduwang_ylyanshi ? "twylyanshix" : "twylyanshi") + "_info" + ]; }, }, - translate:{ - tw_beimihu:'TW卑弥呼', - tw_beimihu_prefix:'TW', - nashime:'难升米', - tw_xiahouba:'TW夏侯霸', - tw_xiahouba_prefix:'TW', - tw_zumao:'TW祖茂', - tw_zumao_prefix:'TW', - tw_caoang:'TW曹昂', - tw_caoang_prefix:'TW', - tw_dingfeng:'TW丁奉', - tw_dingfeng_prefix:'TW', - tw_caohong:'TW将曹洪', - tw_caohong_prefix:'TW将', - tw_maliang:'TW马良', - tw_maliang_prefix:'TW', + translate: { + tw_beimihu: "TW卑弥呼", + tw_beimihu_prefix: "TW", + nashime: "难升米", + tw_xiahouba: "TW夏侯霸", + tw_xiahouba_prefix: "TW", + tw_zumao: "TW祖茂", + tw_zumao_prefix: "TW", + tw_caoang: "TW曹昂", + tw_caoang_prefix: "TW", + tw_dingfeng: "TW丁奉", + tw_dingfeng_prefix: "TW", + tw_caohong: "TW将曹洪", + tw_caohong_prefix: "TW将", + tw_maliang: "TW马良", + tw_maliang_prefix: "TW", - twyanqin:'姻亲', - twyanqin_info:'准备阶段,你可以将势力变更为魏或蜀。', - twbaobian:'豹变', - twbaobian_info:'当你使用【杀】或【决斗】造成伤害时,若目标角色的势力与你相同,则你可以防止此伤害,然后其将手牌数补充至与体力值相同。若不同且其手牌数大于体力值,则你可以将其手牌弃置至与其体力值相同。', - twtijin:'替巾', - twtijin_info:'当你攻击范围内的一名其他角色使用【杀】指定另一名其他角色为目标时,你可以将此【杀】的目标改为你。若如此做,此【杀】结算完成后,你弃置该角色的一张牌。', - twxiaolian:'孝廉', - twxiaolian_info:'当一名其他角色使用【杀】指定另一名其他角色为目标时,你可以将此【杀】的目标改为你。若如此做,当你受到此【杀】的伤害后,你可以将一张牌置于此【杀】原目标的武将牌旁,称为“马”,且令其获得如下效果:其他角色计算至其的距离+X(X为其武将牌旁的“马”数)。', - twqijia:'弃甲', - twqijia_info:'出牌阶段,你可以弃置一张装备区内的牌(每种类型的装备牌限一次),然后视为对攻击范围内的一名其他角色使用了一张【杀】。', - twzhuchen:'诛綝', - twzhuchen_info:'出牌阶段,你可以弃置一张【桃】或【酒】并选择一名其他角色。你与其的距离视为1直到此阶段结束。', - twhuzhu:'护主', - twhuzhu_info:'出牌阶段限一次,若你的装备区内有牌,则你可以令一名其他角色交给你一张手牌,然后获得你装备区内的一张牌。若其体力值不大于你,则你可以令其回复1点体力。', - twliancai:'敛财', - twliancai_info:'结束阶段,你可以将武将牌翻面,然后获得一名其他角色装备区内的一张牌。当你的武将牌翻面时,你可以将手牌补至与体力值相同。', - twrangyi:'攘夷', - twrangyi2:'攘夷', - twrangyi_info:'出牌阶段限一次,你可以将所有手牌交给一名其他角色,然后令其选择一项:1.使用其中的一张牌,并于此牌被使用时将其余的牌交还给你。2.受到来自你的1点伤害。', - twbaimei:'白眉', - twbaimei_info:'锁定技,若你没有手牌,则防止你受到的所有属性伤害和锦囊牌造成的伤害。', - chijie:'持节', - chijie_info:' 游戏开始时,你可以选择一个现存势力,你的势力视为该势力。', - waishi:'外使', - waishi_info:' 出牌阶段限一次,你可以用至多X张牌交换一名其他角色等量的手牌(X为现存势力数),然后若其与你势力相同或手牌多于你,你摸一张牌。', - renshe:'忍涉', - renshe_info:'当你受到伤害后,你可以选择一项:将势力改为现存的另一个势力;或可以额外发动一次“外使”直到你的下个出牌阶段结束;或与另一名其他角色各摸一张牌。', - tw_gexuan:'TW葛玄', - tw_gexuan_prefix:'TW', - twdanfa:'丹法', - twdanfa_info:'准备阶段或结束阶段开始时,你可将一张牌置于武将牌上,称为“丹”。每回合每种花色限一次,当你使用牌时,若“丹”中有与此牌花色相同的牌,则你摸一张牌。', - twlingbao:'灵宝', - twlingbao_info:'出牌阶段限一次,你可以将两张花色不同的“丹”置入弃牌堆。若这两张牌:均为红色,你令一名其他角色回复1点体力;均为黑色,你弃置一名其他角色区域内至多两张区域不同牌;颜色不同,则你令一名角色摸一张牌,并令另一名角色弃置一张牌。', - twsidao:'司道', - twsidao_info:'游戏开始时,你选择一张“法宝”置入装备区。准备阶段,若你以此法选择的法宝在牌堆/弃牌堆中,则你使用之。', - gx_lingbaoxianhu:'灵宝仙壶', - gx_lingbaoxianhu_info:'锁定技,当你造成点数大于1的伤害后,或有角色死亡后,你加1点体力上限并回复1点体力。', - gx_taijifuchen:'太极拂尘', - gx_taijifuchen_info:'锁定技,当你使用【杀】指定目标后,你令目标角色选择一项:①弃置一张牌,若此牌和【杀】花色相同,则你获得之。②其不可响应此【杀】。', - gx_chongyingshenfu:'冲应神符', - gx_chongyingshenfu_info:'锁定技。①当你受到牌造成的伤害后,你记录此牌的名称。②当你受到〖冲应神符①〗记录过的牌造成的伤害时,你令此牌伤害-1。', - tw_dongzhao:'TW董昭', - tw_dongzhao_prefix:'TW', - twmiaolve:'妙略', - twmiaolve_info:'游戏开始时,你获得两张【瞒天过海】。当你受到1点伤害后,你可选择:①获得一张【瞒天过海】并摸一张牌。②获得一张智囊。', - twyingjia:'迎驾', - twyingjia_info:'一名角色的回合结束时,若你本回合内使用过两张或更多的同名锦囊牌,则你可弃置一张手牌并令一名角色进行一个额外回合。', - dz_mantianguohai:'瞒天过海', - dz_mantianguohai_info:'此牌不计入拥有者的手牌上限。出牌阶段,对一至两名区域内有牌的其他角色使用。你获得目标角色一张牌,然后依次交给每名目标角色各一张牌。', - jiachong:'TW贾充', - jiachong_prefix:'TW', - beini:'悖逆', - beini_info:'出牌阶段限一次,你可以选择一名体力值不小于你的角色,令你或其摸两张牌,然后未摸牌的角色视为对摸牌的角色使用一张【杀】。', - dingfa:'定法', - dingfa_info:'弃牌阶段结束时,若本回合你失去的牌数不小于你的体力值,你可以选择一项:1、回复1点体力;2、对一名其他角色造成1点伤害。', - duosidawang:'朵思大王', - equan:'恶泉', - equan_info:'锁定技。①当有角色于你的回合内受到伤害后,其获得X枚“毒”(X为伤害值)。②准备阶段,你令所有拥有“毒”标记的角色移去所有“毒”标记并失去等量的体力。③当有角色因〖恶泉②〗进入濒死状态时,你令其所有技能失效直到回合结束。', - manji:'蛮汲', - manji_info:'锁定技。其他角色失去体力后,若你的体力值:不大于该角色,你回复1点体力;不小于该角色,你摸一张牌。', - wuban:'TW吴班', - wuban_prefix:'TW', - jintao:'进讨', - jintao_info:'锁定技,你使用【杀】无距离限制且次数上限+1。你于出牌阶段内使用的第一张【杀】伤害+1,第二张【杀】不可被响应。', - yuejiu:'TW乐就', - yuejiu_prefix:'TW', - cuijin:'催进', - cuijin_info:'当你或你攻击范围内的角色使用【杀】时,你可以弃置一张牌并获得如下效果:此【杀】的伤害值基数+1,且当此【杀】结算结束后,若未造成过伤害,则你对使用者造成1点伤害。', - tw_zhaoxiang:'TW赵襄', - tw_zhaoxiang_prefix:'TW', - twfuhan:'扶汉', - twfuhan_info:'限定技。准备阶段开始时时,你可以移去所有"梅影"标记,然后从五张未登场的蜀势力武将牌中选择一名获得其所有技能,将体力上限数调整为以此技能移去所有“梅影”标记的数量(最少为2,最多为8)并回复1点体力,然后从牌堆/弃牌堆/场上获得【梅影枪】。', - twqueshi:'鹊拾', - twqueshi_info:'游戏开始时,你将【梅影枪】置于你的装备区。', - meiyingqiang:'梅影枪', - meiyingqiang_info:'当你于其他角色的回合内第一次失去牌时,你可以使用一张【杀】。', - tw_fuwan:'TW伏完', - tw_fuwan_prefix:'TW', - twmoukui:'谋溃', - twmoukui_info:'当你使用【杀】指定目标后,你可以选择一项:①摸一张牌;②弃置该角色的一张牌;③背水:若此【杀】未因造成伤害而令该角色进入过濒死状态,则该角色弃置你的一张牌。', - tw_yujin:'SP于禁', - tw_yujin_prefix:'SP', - xinzhenjun:'镇军', - xinzhenjun_info:'出牌阶段开始时,你可以将一张牌交给一名其他角色,令其选择是否使用一张不为黑色的【杀】。若其选择是,则你于此【杀】结算完成后摸1+X张牌(X为此【杀】造成的伤害总点数)。若其选择否,则你对其或其攻击范围内的一名其他角色造成1点伤害。', - tw_hucheer:'TW胡车儿', - tw_hucheer_prefix:'TW', - twshenxing:'神行', - twshenxing_info:'锁定技。若你的装备区内没有坐骑牌,则你至其他角色的距离-1且手牌上限+1。', - twdaoji:'盗戟', - twdaoji_info:'出牌阶段限一次,你可以弃置一张非基本牌并选择一名攻击范围内的角色,获得其一张牌。若你以此法得到的牌为:基本牌,你摸一张牌;装备牌,你使用此牌并对其造成1点伤害。', - tw_hejin:'TW何进', - tw_hejin_prefix:'TW', - twmouzhu:'谋诛', - twmouzhu_info:'出牌阶段限一次,你可以选择一名其他角色A。你令除A外所有体力值小于等于你的其他角色依次选择是否交给你一张牌。若你以此法得到的牌数X:等于0,你和所有进行选择的角色依次失去1点体力。大于0,你令A选择由你视为对其使用一张伤害值基数为X的【杀】或【决斗】。', - twyanhuo:'延祸', - twyanhuo_info:'当你死亡时,你可以选择一项:①令一名其他角色弃置X张牌。②令X名其他角色依次弃置一张牌。(X为你的牌数)', - tw_mayunlu:'TW马云禄', - tw_mayunlu_prefix:'TW', - twfengpo:'凤魄', - twfengpo_info:'①当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的♦数)。②当你杀死一名角色后,你将〖凤魄①〗中的“♦数”改为“红色牌数”。', - tw_re_caohong:'TW曹洪', - tw_re_caohong_prefix:'TW', - twyuanhu:'援护', - twyuanhu_info:'出牌阶段限一次。你可将一张装备牌置入一名角色的装备区内。若此牌为:武器牌,你弃置与其距离为1的另一名角色区域的一张牌;防具牌,其摸一张牌;坐骑牌或宝物牌,其回复1点体力。然后若其体力值或手牌数不大于你,则你摸一张牌,且你可以于本回合的结束阶段发动一次〖援护〗。', - twjuezhu:'决助', - twjuezhu_info:'限定技。准备阶段,你可废除一个坐骑栏,令一名角色获得〖飞影〗并废除判定区。该角色死亡后,你恢复以此法废除的装备栏。', - tw_zangba:'TW臧霸', - tw_zangba_prefix:'TW', - twhanyu:'捍御', - twhanyu_info:'锁定技。游戏开始时,你获得牌堆中的基本牌,锦囊牌,装备牌各一张。', - twhengjiang:'横江', - twhengjiang_info:'出牌阶段限一次,当你使用基本牌或普通锦囊牌指定唯一目标后,你可将此牌的目标改为攻击范围内的所有合法目标,然后你于此牌结算结束后摸X张牌(X为因响应此牌而使用或打出过牌的角色数)。', - tw_huojun:'TW霍峻', - tw_huojun_prefix:'TW', - twsidai:'伺怠', - twsidai_info:'限定技。出牌阶段,你可以将手牌区内的所有基本牌当做【杀】使用(无距离和次数限制)。若此牌对应的实体牌中:包含【闪】,则目标角色成为此牌的目标后,需弃置一张基本牌,否则不可响应此牌;包含【桃】,则当目标角色受到此牌的伤害后,其减1点体力上限;包含【酒】,则当目标角色受到此牌的伤害时,此伤害×2。', - twjieyu:'竭御', - twjieyu_info:'每轮限一次。结束阶段开始时,或当你于一轮内第一次受到伤害后,你可以弃置所有手牌,然后从弃牌堆中获得不同牌名的基本牌各一张。', - tw_liuhong:'TW刘宏', - tw_liuhong_prefix:'TW', - twyujue:'鬻爵', - twyujue_give:'鬻爵', - twyujue_info:'①其他角色的出牌阶段内,可以交给你任意张牌(每阶段上限为两张)。②当你于回合外获得其他角色的一张牌后,你可令其选择本回合内未选择过的一项:⒈弃置攻击范围内一名角色的一张牌。⒉下一次使用牌时,从牌堆中获得一张同类别的牌。', - twgezhi:'革制', - twgezhi_info:'①当你于出牌阶段内首次使用某种类别的牌时,你可以重铸一张手牌。②出牌阶段结束时,若你本阶段内因〖革制①〗失去过至少两张牌,则你可以令一名角色选择获得一个其未获得过的效果:⒈攻击范围+2;⒉手牌上限+2;⒊加1点体力上限。', - twfengqi:'烽起', - twfengqi_info:'主公技,锁定技。①其他群势力角色发动〖鬻爵①〗时,将每阶段上限改为四张。②以其他角色为目标的〖革制②〗结算结束后,目标角色可以获得其武将牌上的主公技。', - tw_caocao:'TW曹操', - tw_caocao_prefix:'TW', - twlingfa:'令法', - twlingfa_info:'①第一轮游戏开始时,你可选择获得如下效果直到本轮结束:其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。②第二轮游戏开始时,你可选择获得如下效果直到本轮结束:其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。③第三轮游戏开始时,你失去〖令法〗并获得〖治暗〗。', - twzhian:'治暗', - twzhian_info:'每回合限一次。一名角色使用装备牌或延时锦囊牌后,你可选择:⒈弃置位于场上的此牌。⒉弃置一张手牌并获得位于场上的此牌。⒊对其造成1点伤害。', - tw_zhangmancheng:'TW张曼成', - tw_zhangmancheng_prefix:'TW', - twfengji:'蜂集', - twfengji_info:'出牌阶段开始时,若你没有“示”,则你可以将一张牌作为“示”置于武将牌上并施法:从牌堆中获得X张与“示”牌名相同的牌,然后移去“示”。', - twyiju:'蚁聚', - twyiju_info:'若你的武将牌上有“示”,则:①你使用【杀】的次数上限和攻击范围的基数改为你的体力值。②当你受到伤害时,你移去“示”,且令此伤害+1。', - twbudao:'布道', - twbudao_info:'限定技。准备阶段,你可减1点体力上限,回复1点体力并选择获得一个〖布道〗技能池里的技能(三选一)。然后你可以令一名其他角色也获得此技能并交给你一张牌。', - twzhouhu:'咒护', - twzhouhu_info:'出牌阶段限一次。你可以弃置一张红色手牌并施法:回复X点体力。', - twharvestinori:'丰祈', - twharvestinori_info:'出牌阶段限一次。你可以弃置一张黑色手牌并施法:摸2X张牌。', - twzuhuo:'阻祸', - twzuhuo_info:'出牌阶段限一次。你可以弃置一张非基本牌并施法:防止你受到的下X次伤害。', - twzhouzu:'咒诅', - twzhouzu_info:'出牌阶段限一次。你可以对一名其他角色施法:其弃置X张牌,然后你对其造成1点雷电伤害。', - twhuangjin:'黄巾', - twhuangjin_info:'锁定技。当你一名角色使用【杀】指定你为目标时,若此【杀】有点数,你判定,若点数与此【杀】点数差值不大于1,则此【杀】对你无效。', - twguimen:'鬼门', - twguimen_info:'锁定技。当你弃置牌时,若其中有♠牌,你为每一张♠牌判定,若此牌点数与结果之差不大于1,你对一名其他角色造成2点雷电伤害。', - twdidao:'地道', - twdidao_info:'一名角色的判定牌生效前,你可以打出一张牌作为判定牌并获得原判定牌。若你以此法打出的牌与原判定牌颜色相同,你摸一张牌。', - tw_chengpu:'TW程普', - tw_chengpu_prefix:'TW', - twlihuo:'疠火', - twlihuo2:'疠火', - twlihuo3:'疠火', - twlihuo_info:'①当你声明使用普【杀】后,你可以将此【杀】改为火【杀】。此牌使用结算结束后,若有角色因此【杀】造成的伤害进入过濒死状态,则你失去1点体力。②当你使用火【杀】选择目标后,你可为此牌增加一个目标。', - twchunlao:'醇醪', - twchunlao_info:'①准备阶段,若场上没有“醇”,则你可将一名角色区域内的一张牌置于其武将牌上,称为“醇”。②一名角色使用【杀】时,若其有“醇”,则其可以交给你一张牌,令此【杀】的伤害值基数+1。③一名角色进入濒死状态时,若其有“醇”,则你可以移去“醇”并摸一张牌,然后令其回复1点体力。', - tw_guohuai:'TW郭淮', - tw_guohuai_prefix:'TW', - twjingce:"精策", - twjingce_info:"当你于出牌阶段使用第X张牌结算完毕后,你可以摸两张牌(X为你的体力值)。若此阶段你此前已摸过牌或本回合造成过伤害,你获得一枚“策”标记。", - yuzhang:"御嶂", - yuzhang_info:"你可以弃置一枚“策”标记,然后跳过一个阶段。当你受到伤害后,你可弃置一枚“策”标记,然后选择一项:⒈令伤害来源弃置两张牌;⒉令伤害来源本回合不能再使用或打出牌。", - tw_caozhao:'曹肇', - twfuzuan:'复纂', - twfuzuan_info:'出牌阶段限一次/当你受到伤害后/当你对其他角色造成伤害后,你可选择一名拥有转换技的角色,变更其的一个转换技的的状态。', - twchongqi:'宠齐', - twchongqi_info:'锁定技。游戏开始时,你令所有角色获得〖非服〗。然后你可减1点体力上限,令一名其他角色获得〖复纂〗。', - twfeifu:'非服', - twfeifu_info:'锁定技,转换技。阴:当你成为【杀】的唯一目标后;阳:当你使用【杀】指定唯一目标后;目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。', - tw_wangchang:'TW王昶', - tw_wangchang_prefix:'TW', - twkaiji:'开济', - twkaiji_info:'准备阶段,你可令至多X名角色各摸一张牌(X为本局游戏内进入过濒死状态的角色数+1)。若有角色以此法获得了非基本牌,则你摸一张牌。', - twshepan:'慑叛', - twshepan_info:'每回合限一次。当你成为其他角色使用牌的目标后,你可选择一项:⒈摸一张牌。⒉将其区域内的一张牌置于牌堆顶。然后若你的手牌数与其相等,则你将此技能的发动次数归零,且可以令此牌对你无效。', - tw_wangcan:'TW王粲', - tw_wangcan_prefix:'TW', - twdianyi:'典仪', - twdianyi_info:'锁定技。你的回合结束时,若你本回合内:造成过伤害,你弃置所有手牌;未造成过伤害,你将手牌数调整至四张。', - twyingji:'应机', - twyingji_wuxie:'应机', - twyingji_info:'当你于回合外需要使用或打出一张基本牌或普通锦囊牌时,若你没有手牌,则你可摸一张牌,然后视为使用或打出此牌。', - twshanghe:'觞贺', - twshanghe_info:'限定技。当你进入濒死状态时,你可令所有其他角色依次交给你一张牌;若这些牌中没有【酒】,则你将体力回复至1点。', - tw_wujing:'TW吴景', - tw_wujing_prefix:'TW', - twfenghan:'锋捍', - twfenghan_info:'每回合限一次。当你使用【杀】或伤害类锦囊牌指定第一个目标后,你可令至多X名角色各摸一张牌(X为此牌的目标数)。', - twcongji:'从击', - twcongji_info:'当你的红色牌于回合外因弃置而进入弃牌堆后,你可令一名其他角色获得这些牌。', - old_quancong:'TW全琮', - old_quancong_prefix:'TW', - zhenshan:'振赡', - zhenshan_info:'每回合限一次,当你需要使用或打出一张基本牌时,你可以与一名手牌数少于你的角色交换手牌,视为使用或打出此牌。', - tw_tianyu:'TW田豫', - tw_tianyu_prefix:'TW', - gz_tw_tianyu:'田豫', - twzhenxi:'震袭', - twzhenxi_info:'每回合限一次。当你使用【杀】指定目标后,你可选择一项:⒈弃置其X张手牌(X为你至其的距离);⒉将其装备区或判定区内的一张牌移动到另一名角色的装备区或判定区内。若其体力值大于你或其体力值为全场最高,则你可以改为依次执行以上两项。', - twyangshi:'扬师', - twyangshi_info:'锁定技。当你受到伤害后,若场上有不在你攻击范围内的其他角色,则你令攻击范围+1;若没有,则你从牌堆中获得一张【杀】。', - tw_puyangxing:'濮阳兴', - twzhengjian:'征建', - twzhengjian_info:'游戏开始时,你可选择获得一项效果:⒈其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。⒉其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。', - twzhongchi:'众斥', - twzhongchi_info:'锁定技,限定技。当你因〖征建〗而得到牌后,若已经有至少X名角色因〖征建〗而交给你过牌(X为游戏人数的一半且向上取整),则你回复2点体力,且于本局游戏内受到渠道为【杀】的伤害+1,且你将〖征建〗中的“其须交给你一张牌”改为“你可对其造成1点伤害”。', - tw_bingyuan:'邴原', - twbingde:'秉德', - twbingde_info:'出牌阶段限一次。你可以选择一个本阶段未选择过的花色并弃置一张牌,你摸等同于本阶段你使用此花色的牌数,然后若你以此法弃置的牌的花色与你选择的花色相同,你令你〖秉德〗于此阶段发动的次数上限+1。', - twqingtao:'清滔', - twqingtao_info:'①摸牌阶段结束时,你可以重铸一张牌。若此牌为【酒】或非基本牌,你摸一张牌。②结束阶段,若你本回合未发动〖清滔①〗,你可以发动〖清滔①〗。', - tw_jiangji:'TW蒋济', - tw_jiangji_prefix:'TW', - twjichou:'急筹', - twjichou_info:'①每回合限一次。你可以视为使用一张未被〖急筹①〗记录过的普通锦囊牌并记录此牌。②你无法响应或{使用对应实体牌包含你的手牌的}〖急筹①〗记录过的锦囊牌。③出牌阶段限一次。你可将手牌中的一张〖急筹①〗记录过的锦囊牌交给其他角色。', - twjilun:'机论', - twjilun_info:'当你受到伤害后,你可以摸X张牌(X为〖急筹①〗记录数且至少为1,至多为5),或视为使用一张〖急筹①〗记录过且未被〖机论〗记录过的普通锦囊牌并记录此牌。', - tw_niufudongxie:'牛辅董翓', - baonvezhi_faq:'关于暴虐值', - baonvezhi_faq_info:'
            • 当你造成或受到伤害后,你获得等量的暴虐值;
            • 暴虐值的上限为5。', - twjuntun:'军屯', - twjuntun_info:'①游戏开始时或当其他角色死亡后,你可令一名角色获得〖凶军〗。②当其他角色造成伤害后,若其拥有〖凶军〗,你获得等同于此次伤害值的暴虐值。', - twxiongxi:'凶袭', - twxiongxi_info:'出牌阶段限一次。你可以弃置X张牌对一名其他角色造成1点伤害(X为你的暴虐值与暴虐值上限之差)。', - twxiafeng:'黠凤', - twxiafeng_info:'出牌阶段开始时,你可消耗至多3点暴虐值并获得如下效果直到回合结束:你使用的前X张牌没有距离和次数限制且不可被响应,你的手牌上限+X(X为你以此法消耗的暴虐值)。', - tw_bn_1:'一点', - tw_bn_2:'两点', - tw_bn_3:'三点', - tw_bn_1_bg:'一', - tw_bn_2_bg:'二', - tw_bn_3_bg:'三', - twxiongjun:'凶军', - twxiongjun_info:'锁定技,每回合限一次。当你造成伤害后,所有拥有〖凶军〗的角色摸一张牌。', - tw_jianshuo:'蹇硕', - twkunsi:'困兕', - twkunsi_info:'出牌阶段,你可以视为对一名未以此法选择过的其他角色使用一张【杀】。若此【杀】未造成伤害,其获得〖令戮〗直到你下回合开始,且当你成为其〖令戮〗的目标后,其可令你于〖令戮〗失败时进行两次结算。', - twlinglu:'令戮', - twlinglu_info:'强令:①任务:执行角色于其下回合结束前造成的伤害不小于2点。②成功:其摸两张牌。③失败:其失去1点体力。', - tw_mateng:'TW马腾', - tw_mateng_prefix:'TW', - twxiongzheng:'雄争', - twxiongzheng_info:'一轮游戏开始时,①若你上一轮发动过〖雄争〗且选择过“雄争”角色,你可以选择一项:1.视为对任意名上一轮内未对“雄争”角色造成过伤害的角色依次使用一张【杀】;2.令任意名上一轮对“雄争”角色造成过伤害的角色摸两张牌。②你可以选择一名未以此法选择过的角色,称为“雄争”角色。', - twluannian:'乱年', - twluannian_info:'主公技。其他群势力角色的出牌阶段限一次。其可以弃置X张牌并对“雄争”角色造成1点伤害(X为所有角色于本轮发动〖乱年〗的次数+1)。', - tw_baoxin:'TW鲍信', - tw_baoxin_prefix:'TW', - twmutao:'募讨', - twmutao_info:'出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】依次交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。', - twyimou:'毅谋', - twyimou_info:'当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色并摸两张牌;3.背水:将所有手牌交给其(若受伤角色为你则跳过此步骤),然后依次执行上述所有选项。', - tw_liufuren:'刘夫人', - twzhuidu:'追妒', - twzhuidu_info:'出牌阶段限一次。你可以选择一名已受伤的其他角色并选择一项:1.对其造成1点伤害;2.弃置其装备区里的一张牌;3.背水:若该角色为女性,弃置一张牌,然后依次执行上述所有选项。', - twshigong:'示恭', - twshigong_info:'限定技。当你于回合外进入濒死状态时,你可以令当前回合角色选择一项:1.加1点体力上限并回复1点体力,摸一张牌,然后令你将体力回复至体力上限;2.弃置X张手牌,然后令你将体力回复至1点(X为其体力值)。', - tw_wangling:'TW王淩', - tw_wangling_prefix:'TW', - twmibei:'秘备', - twmibei_info:'使命技。①使命:使用每种类型且牌名不同的牌各两张。②成功:当你使用牌后,若你于本次事件完成了〖秘备①〗的使命,你获得〖谋立〗。③失败:出牌阶段结束时,若你本回合未使用过牌,你本回合手牌上限-1并重置〖秘备〗。', - twxingqi:'星启', - twxingqi_info:'觉醒技。准备阶段,若场上的牌数大于你的体力值,你回复1点体力,然后若〖秘备〗:未完成,你从牌堆中获得每种类型的牌各一张;已完成,本局游戏你使用牌无距离限制。', - twmouli:'谋立', - twmouli_backup:'谋立', - twmouli_info:'每回合限一次。你可以使用牌堆中的一张基本牌。', - tw_zhugeguo:'TW诸葛果', - tw_zhugeguo_prefix:'TW', - twqirang:'祈禳', - twqirang_info:'当有装备牌进入你的装备区时,你可以从牌堆中获得一张锦囊牌,你本阶段使用此牌无距离限制且不可被响应,且当你使用此牌时,你可以为这张牌增加或减少一个目标。', - twyuhua:'羽化', - twyuhua_info:'锁定技。①你的非基本牌不计入手牌上限。②当你于回合外失去牌后,若其中有非基本牌,你可以卜算X,然后你可以摸X张牌(X为其中非基本牌数且至多为5)。', - tw_fanchou:'TW樊稠', - tw_fanchou_prefix:'TW', - twxingluan:'兴乱', - twxingluan_info:'结束阶段,你可以亮出牌堆顶的六张牌,然后你可以选择一种类型的牌并分配给任意角色(每名角色至多三张)。然后所有以此法得到过牌且得到的牌数不少于你的角色失去1点体力。', - tw_xujing:'TW许靖', - tw_xujing_prefix:'TW', - twboming:'博名', - twboming_info:'①出牌阶段限两次。你可以将一张牌交给一名其他角色。②结束阶段,若所有其他角色于此回合得到的牌数之和大于1,你摸两张牌。', - twejian:'恶荐', - twejian_info:'当其他角色得到你的牌后,若其有其他与此牌类型相同的牌,你可以令其选择一项:1.受到你造成的1点伤害;2.弃置这些牌。', - tw_zhangfei:'TW张飞', - tw_zhangfei_prefix:'TW', - twxuhe:'虚吓', - twxuhe_info:'当你使用的【杀】被【闪】抵消时,你可以令其选择一项:1.受到你造成的1点伤害;2.本回合你使用的下一张牌对其造成伤害时,此伤害+2。', - tw_xuezong:'TW薛综', - tw_xuezong_prefix:'TW', - twjiexun:'诫训', - twjiexun_info:'结束阶段,你可以选择一个花色并令一名其他角色摸等同于场上此花色牌数张牌,然后其弃置X张牌。若其以此法弃置了所有牌,你选择一项:1.摸X张牌,然后将X归零;2.修改〖复难〗和〖诫训〗(X为此前〖诫训〗的发动次数)。', - twfunanx:'复难·改', - twjiexunx:'诫训·改', - twfunanx_info:'当其他角色使用或打出牌响应你使用的牌时,你可获得其使用或打出的牌。', - twjiexunx_info:'结束阶段,你可选择一个花色并令一名其他角色摸等同于场上此花色牌数张牌,然后其弃置X张牌(X为此前〖诫训〗的发动次数)。', - tw_zhangning:'TW张宁', - tw_zhangning_prefix:'TW', - twxingzhui:'星坠', - twxingzhui_info:'出牌阶段限一次。你可以失去1点体力并施法:亮出牌堆顶2X张牌,若其中有黑色牌,则你可令一名其他角色获得这些黑色牌。若黑色牌的数量不小于X,则你对其造成X点雷电伤害。', - twjuchen:'聚尘', - twjuchen_info:'结束阶段,若你的手牌数和体力值均不为全场最多,则你可以令所有角色弃置一张牌,然后你获得其中的红色牌。', - tw_yufuluo:'于夫罗', - twjiekuang:'竭匡', - twjiekuang_info:'每回合限一次。当一名体力值小于你的角色成为其他角色使用基本牌或普通锦囊牌的唯一目标后,若没有角色处于濒死状态,你可以失去1点体力或减1点体力上限,将此牌的目标转移给你。然后此牌结算结束后,若此牌未造成伤害且此牌的使用者是你使用此牌名的牌的合法目标,你视为对此牌的使用者使用一张同名牌。', - twneirao:'内扰', - twneirao_info:'觉醒技。准备阶段,若你的体力值与体力上限之和不大于9,你失去〖竭匡〗,弃置所有牌并从牌堆或弃牌堆中获得等量的【杀】,然后获得〖乱掠〗。', - twluanlve:'乱掠', - twluanlve_info:'①出牌阶段,你可以将X张【杀】当做【顺手牵羊】对一名本阶段未成为过【顺手牵羊】的目标的角色使用(X为你以此法使用【顺手牵羊】的次数)。②当你使用牌时,若此牌为【顺手牵羊】,你令此牌不能被响应。', - tw_fengxí:'冯习', - twqingkou:'轻寇', - twqingkou_info:'准备阶段,你可以视为对一名其他角色使用一张【决斗】。然后此牌的伤害来源摸一张牌,若伤害来源包括你,你跳过本回合的判定阶段和弃牌阶段。', - tw_zhangji:'张既', - twdingzhen:'定镇',//丁真 - twdingzhen_info:'一轮游戏开始时,你可以选择任意名你至其距离不大于X的角色(X为你的体力值),这些角色选择一项:1.弃置一张【杀】;2.本轮其于回合内使用的第一张牌不能指定你为目标。', - twyouye:'攸业', - twyouye_info:'锁定技。①其他角色的结束阶段,若其本回合未对你造成过伤害且“蓄”数小于5,你将牌堆顶的牌置于武将牌上,称为“蓄”。②当你造成或受到伤害后,若你有“蓄”,你将所有“蓄”分配给任意角色(若当前回合角色存活,则你至少为当前回合角色分配一张)。', - tw_xunchen:'TW荀谌', - tw_xunchen_prefix:'TW', - twweipo:'危迫', - twweipo_info:'出牌阶段限一次。你可以令一名角色弃置一张牌,然后令其获得一张【兵临城下】或一张由你选择的智囊牌。', - twmouzhi:'谋识', - twmouzhi_info:'锁定技。当你受到伤害时,若伤害渠道对应的牌和你上次受到的伤害渠道对应的牌颜色相同,则你防止此伤害。', - tw_jiangqing:'TW蒋钦', - tw_jiangqing_prefix:'TW', - twshangyi:'尚义', - twshangyi_info:'出牌阶段限一次。你可以弃置一张牌并选择一名有手牌的其他角色,你令其观看你的手牌,然后你观看其手牌并选择一项:1.弃置其中一张牌;2.与其交换一张手牌。若你以此法弃置了其的黑色牌,或你与其交换的两张牌均为红色,你摸一张牌。', - twxiangyu:'翔羽', - twxiangyu_info:'锁定技。①你于回合内的攻击范围+X(X为本回合失去过牌的角色数且至多为5)。②当你使用【杀】指定目标后,若你至目标角色的距离小于你的攻击范围,你令此目标角色抵消此【杀】所需使用的【闪】数+1。', - twgyshenxing:'慎行', - twgyshenxing_info:'出牌阶段,你可以弃置X张牌,然后摸一张牌并获得1枚“慎”标记(X为你的“慎”数且至多为2)。', - tw_guyong:'TW顾雍', - tw_guyong_prefix:'TW', - twbingyi:'秉壹', - twbingyi_info:'结束阶段,你可以展示所有手牌,若这些牌的颜色均相同或类别均相同,你可以令至多Y名角色各摸一张牌(Y为你的手牌数)。若你以此法展示的牌数大于1且这些牌的颜色均相同且类别均相同,你移去所有“慎”。', - twyilie:'毅烈', - twyilie_info:'出牌阶段开始时,你可以选择一项:1.本阶段内使用【杀】的次数上限+1;2.本回合内使用【杀】指定处于连环状态的目标后,或使用【杀】被【闪】抵消时,摸一张牌;3.背水:失去1点体力,然后依次执行上述所有选项。', - tw_chendong:'TW陈武董袭', - tw_chendong_prefix:'TW', - twfenming:'奋命', - twfenming_info:'准备阶段,你可以选择一名其他角色并选择一项:1.令其弃置一张牌;2.令其横置;3.背水:横置,然后依次执行上述所有选项。', - tw_handang:'TW韩当', - tw_handang_prefix:'TW', - twgongji:'弓骑', - twgongji2:'弓骑', - twgongji_info:'①你的攻击范围无限。②出牌阶段限一次,你可以弃置一张牌,然后你使用与此牌花色相同的【杀】无任何次数限制直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。', - twjiefan:'解烦', - twjiefan_info:'限定技。出牌阶段,你可以选择一名角色,令攻击范围内含有其的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。然后当其第一次进入濒死状态后,你重置〖解烦〗。', - tw_jiling:'TW纪灵', - tw_jiling_prefix:'TW', - twshuangren:'双刃', - twshuangren_info:'①出牌阶段开始时,你可以与一名角色拼点。若你:赢,你可以视为对至多两名至其的距离不大于1的角色依次使用一张【杀】;没赢,其可以视为对你使用一张【杀】。②出牌阶段结束时,若你本回合未发动过〖双刃①〗且未造成过渠道为【杀】的伤害,你可以弃置一张牌发动〖双刃①〗。', - tw_re_fazheng:'TW法正', - tw_re_fazheng_prefix:'TW', - twxuanhuo:'眩惑', - twxuanhuo_info:'摸牌阶段结束时,你可以交给一名其他角色两张牌,然后其选择一项:1.视为对你选择的另一名其他角色使用一张【杀】或【决斗】,2.令你获得其两张牌。', - twenyuan:'恩怨', - twenyuan1:'恩怨', - twenyuan2:'恩怨', - twenyuan_info:'①当你获得一名其他角色的至少两张牌后,你可以令其摸一张牌,若其手牌区或装备区没有牌,则你可以改为令其回复1点体力。②当你受到1点伤害后,你可令伤害来源选择一项:1.失去1点体力;2.交给你一张手牌,若此牌的花色不为♥,你摸一张牌。', - tw_madai:'TW马岱', - tw_madai_prefix:'TW', - twqianxi:'潜袭', - twqianxi2:'潜袭', - twqianxi3:'潜袭', - twqianxi2_bg:'潜', - twqianxi3_bg:'袭', - twqianxi_info:'准备阶段,你可以摸一张牌并弃置一张牌,令一名距离为1的角色本回合不能使用或打出与你弃置的牌颜色相同的手牌。然后本回合的结束阶段,若你本回合对其造成过渠道为【杀】的伤害,你令其不能使用或打出与你以此法弃置的牌颜色不同的牌直到其下回合结束。', - tw_niujin:'TW牛金', - tw_niujin_prefix:'TW', - twcuorui:'挫锐', - twcuorui_info:'限定技。准备阶段,你可以将手牌摸至X张(X为场上角色手牌数最多的角色的手牌数,且至多摸5张)。然后若你的判定区:未废除,你废除判定区;已废除,你可以对一名其他角色造成1点伤害。', - twliewei:'裂围', - twliewei_info:'锁定技。当你杀死一名角色后,你选择一项:1.摸两张牌;2.若你拥有〖挫锐〗且〖挫锐〗已发动过,重置〖挫锐〗。', - tw_guanqiujian:'TW毌丘俭', - tw_guanqiujian_prefix:'TW', - twzhengrong:'征荣', - twzhengrong_tag:'荣', - twzhengrong_info:'当你于出牌阶段使用牌结算结束后,若此牌为你于本局游戏你的出牌阶段内使用的第偶数张指定了其他角色为目标的牌,或你于出牌阶段第一次造成伤害后,你可以将一名其他角色的一张牌置于你的武将牌上,称为“荣”。', - twhongju:'鸿举', - twhongju_info:'觉醒技。准备阶段,若你的“荣”数不小于3,你摸等同于“荣”数的牌,且可以用任意手牌交换等量的“荣”,获得〖清侧〗,然后可以减1点体力上限并获得〖扫讨〗。', - twqingce:'清侧', - twqingce_backup:'清侧', - twqingce_info:'出牌阶段,你可以将一张“荣”置入弃牌堆并选择一名区域内有牌的角色,你弃置其区域里的一张牌。', - twsaotao:'扫讨', - twsaotao_info:'锁定技。你使用【杀】和普通锦囊牌不能被响应。', - tw_daxiaoqiao:'TW大乔小乔', - tw_daxiaoqiao_prefix:'TW', - twxingwu:'星舞', - twxingwu_info:'弃牌阶段开始时,你可以将一张牌置于武将牌上,称为“星舞”。然后你可移去三张“星舞”,弃置一名其他角色装备区里的所有牌,然后对其造成2点伤害(若其性别包含女性则改为1点伤害)。', - twpingting:'娉婷', - twpingting_info:'锁定技。①一轮游戏开始时或其他角色于你的回合内进入濒死状态时,你摸一张牌并将一张牌置于武将牌上,称为“星舞”。②若你有“星舞”,你视为拥有〖天香〗和〖流离〗。', - tw_furong:'TW傅肜', - tw_furong_prefix:'TW', - twxuewei:'血卫', - twxuewei_info:'每轮限一次。一名其他角色A的出牌阶段开始时,你可以选择另一名其他角色B,然后你令A选择一项:1.本回合不能对B使用【杀】且手牌上限-2;2.你视为对A使用一张【决斗】。', - twliechi:'烈斥', - twliechi_info:'当你受到伤害后,若伤害来源的体力值不小于你,你可以选择一项:1.令其将手牌数弃置至与你的手牌数相同;2.弃置其一张牌;3.背水:若你本回合进入过濒死状态,弃置一张装备牌,然后依次执行上述所有选项。', - tw_yl_luzhi:'TW卢植', - tw_yl_luzhi_prefix:'TW', - twmingren:'明任', - twmingren_info:'①游戏开始时,你摸一张牌,然后将一张手牌置于武将牌上,称为“任”。②出牌阶段开始时或出牌阶段结束时,你可以用一张牌替换“任”。', - twzhenliang:'贞良', - twzhenliang_info:'转换技。阴:出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。阳:当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。', - tw_zhangnan:'张南', - twfenwu:'奋武', - twfenwu_info:'结束阶段,你可以失去1点体力并视为使用一张无距离限制的【杀】。若本回合你使用过的基本牌种数大于1,此【杀】伤害基数+1。', - tw_huchuquan:'呼厨泉', - twfupan:'复叛', - twfupan_info:'当你造成或受到伤害后,你可以摸X张牌并将一张牌交给一名其他角色(X为伤害值)。若你此前:未以此法交给过该角色牌,你摸两张牌;以此法交给过该角色牌,你可{对其造成1点伤害,然后你不能再以此法交给其牌}。', - tw_liuzhang:'TW刘璋', - tw_liuzhang_prefix:'TW', - twyaohu:'邀虎', - twyaohu_info:'每轮限一次。回合开始时,你须选择场上的一个势力。该势力的角色的出牌阶段开始时,其获得你的一张“生”,然后其须选择一项:1.对你指定的另一名的其他角色使用一张【杀】(无距离限制);2.本回合其使用伤害牌指定你为目标时须交给你两张牌,否则取消此目标。', - tw_liwei:'TW李遗', - tw_liwei_prefix:'TW', - twjiaohua:'教化', - twjiaohua_info:'当你或体力值最小的其他角色因摸牌而得到牌后,你可以令该角色从牌堆或弃牌堆中获得一张本次未获得的类别的牌(每种类别每回合限一次)。', - tw_yanxiang:'TW阎象', - tw_yanxiang_prefix:'TW', - twkujian:'苦谏', - twkujianx:'谏', - twkujian_info:'出牌阶段限一次。你可以将至多三张手牌交给一名其他角色,称为“谏”,你获得以下效果:当其他角色使用或打出牌后,若其中有“谏”,你与其各摸一张牌;当其他角色不因使用或打出而失去牌后,若其中有“谏”,你与其各弃置一张牌。', - twruilian:'睿敛', - twruilian2:'睿敛', - twruilian_info:'一轮游戏开始时,你可以选择一名角色。其下回合结束时,若其本回合弃置过至少两张牌,你可以选择其本回合弃置过的一种类别,你与其各从弃牌堆中获得一张此类别的牌。', - tw_xiahouen:'夏侯恩', - twfujian:'负剑', - twfujian_info:'锁定技。①游戏开始时或准备阶段,若你的装备区里没有武器牌,你随机将牌堆中的一张武器牌置入装备区。②当你于回合外失去武器牌后,你失去1点体力。', - twjianwei:'剑威', - twjianwei_info:'①若你的装备区里有武器牌,你使用【杀】无视防具且拼点牌点数+X(X为你的攻击范围)。②{其他角色的准备阶段,其可以与你拼点}/{准备阶段,你可以与攻击范围内的一名角色拼点}。若你赢,你获得其每个区域内的各一张牌;若其赢,其获得你装备区里的武器牌。', - tw_xiahoushang:'夏侯尚', - twtanfeng:'探锋', - twtanfeng_info:'准备阶段,你可以弃置一名其他角色区域内的一张牌,然后其选择一项:1.受到你造成的1点火焰伤害,然后令你跳过本回合的一个阶段(准备阶段和结束阶段除外);2.将一张牌当做【杀】对你使用(有距离限制)。', - tw_zongyu:'TW宗预', - tw_zongyu_prefix:'TW', - twzhibian:'直辩', - twzhibian_info:'出牌阶段开始时,你可以与一名其他角色拼点。若你赢,你可以选择一项:{1.将其区域里的一张牌移动到你的对应区域;2.回复1点体力;3.背水:弃置一张非基本牌,然后依次执行上述所有选项};若你没赢,你失去1点体力。', - twyuyan:'御严', - twyuyan_info:'锁定技。当你成为体力值大于你的角色使用的【杀】的目标时,你令使用者选择一项:1.交给你一张点数大于此【杀】的牌(若此【杀】无点数则改为非基本牌)。2.取消此目标。', - tw_zhouchu:'TW周处', - tw_zhouchu_prefix:'TW', - twguoyi:'果毅', - twguoyi_info:'当你不因〖果毅〗使用【杀】或普通锦囊牌指定一名其他角色为目标后,若其体力值或手牌数最大,或你的手牌数不大于X(X为你已损失的体力值+1),你可令其选择一项:1.本回合不能使用或打出手牌;2.弃置X张牌。若条件均满足,或其于本回合两个选项均已选择过,则你于此牌结算结束后依次视为对此牌的所有目标使用一张名称和属性相同的牌。', - twchuhai:'除害', - twchuhai_info:'使命技。①使命:令至少两名其他角色进入濒死状态。②成功:一名角色的回合结束时,若你于本回合完成了〖除害①〗的使命,你废除判定区,然后每名其他角色依次交给你一张牌。③当你获得其他角色的牌后,你须将其中的一张牌置入弃牌堆。', - tw_qiaogong:'TW桥公', - tw_qiaogong_prefix:'TW', - twyizhu:'遗珠', - twyizhu_info:'①结束阶段,你摸两张牌,然后将两张牌随机插入牌堆前2X张牌的位置中,称为“遗珠”(X为角色数,选择牌的牌名对其他角色可见)。②当有其他角色使用“遗珠”指定唯一目标时,你可以选择一项:1.增加一个目标;2.取消此目标,增加一个目标。然后移除此牌对应的“遗珠”记录并摸一张牌。', - twluanchou:'鸾俦', - twluanchou_info:'出牌阶段限一次。你可以令两名角色获得〖共患〗直到你下次发动此技能。', - twgonghuan:'共患', - twgonghuan_info:'每回合限一次。当其他角色受到伤害时,若其拥有〖共患〗且其体力值不大于你,你可以将此伤害转移给你(不触发〖共患〗)。', - tw_qiaorui:'TW桥蕤', - tw_qiaorui_prefix:'TW', - wangxing:'妄行', - twxiawei:'狭威', - twxiawei_info:'①游戏开始时,你将牌堆中的两张基本牌置于武将牌上,称为“威”。②回合开始时,你将所有“威”置入弃牌堆。③你可以将“威”如手牌般使用或打出。④妄行:准备阶段,你可以将牌堆顶的X+1张牌置于武将牌上,称为“威”。', - twqiongji:'穷技', - twqiongji_info:'锁定技。①每回合限一次。当你使用或打出“威”后,你摸一张牌。②当你受到伤害时,若你没有“威”,此伤害+1。', - tw_bianfuren:'TW卞夫人', - tw_bianfuren_prefix:'TW', - twwanwei:'挽危', - twwanwei_info:'每回合限一次。当一名体力值最小的角色受到伤害时:若该角色不为你,你可以防止此伤害,然后失去1点体力;若该角色为你,或你的体力上限最大,你可以于当前回合的结束阶段获得牌堆顶的牌并展示牌堆底的牌,若展示的牌能被使用,你使用之。', - twyuejian:'约俭', - twyuejian_info:'出牌阶段限一次。你可以将X张牌置于牌堆顶或牌堆底(X为你的手牌数减你的手牌上限且至少为1)。若你以此法失去的牌数:不小于3,你的体力上限+1;不小于2,你回复1点体力;不小于1,你的手牌上限+1。', - tw_chenzhen:'TW陈震', - tw_chenzhen_prefix:'TW', - twmuyue:'睦约', - twmuyue_info:'出牌阶段限一次。你可以弃置一张牌并选择一个基本牌或普通锦囊牌的牌名,然后令一名角色从牌堆中获得一张此牌名的牌。若你以此法弃置的牌的牌名与你选择的牌名相同,你下次发动〖睦约〗无需弃牌。', - twchayi:'察异', - twchayi_info:'结束阶段,你可以选择一名其他角色,令其选择一项:1.展示所有手牌;2.下次使用牌时弃置一张牌。该角色的下个回合结束时,若其手牌数与其上一次成为〖察异〗目标后的手牌数不相同,其执行另一项。', - tw_feiyi:'TW费祎', - tw_feiyi_prefix:'TW', - twshengxi:'生息', - twshengxi_info:'①准备阶段,你可以获得一张【调剂盐梅】。②结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊并摸一张牌。', - twkuanji:'宽济', - twkuanji_info:'每回合限一次。当你的牌不因使用而进入弃牌堆后,你可以令一名其他角色获得其中的一张牌。', - xia_wangyue:'王越', - twyulong:'驭龙', - twyulong_info:'当你使用【杀】指定第一个目标后,你可以与一名目标角色拼点。若你赢,且你此次的拼点牌为:黑色,此【杀】伤害+1;红色,此【杀】不可被响应。当此【杀】造成伤害后,若你赢,你令此【杀】不计入次数。', - twjianming:'剑鸣', - twjianming_info:'锁定技。每回合每种花色限一次,当你使用或打出【杀】时,你摸一张牌。', - xia_liyàn:'李彦', - twzhenhu:'震虎', - twzhenhu_info:'当你使用伤害牌指定第一个目标时,你可以摸一张牌并与至多三名其他角色共同拼点。若你赢,此牌对所有本次拼点没赢的角色造成的伤害+1;若你没赢,你失去1点体力。', - twlvren:'履刃', - twlvren_info:'①当你对其他角色造成伤害时,你令其获得1枚“刃”标记。②当你使用伤害牌时,你可以额外指定一名有“刃”的角色并移去其所有“刃”。③你的拼点牌点数+2X(X为参与此次拼点的角色数)。', - xia_tongyuan:'侠童渊', - xia_tongyuan_prefix:'侠', - twchaofeng:'朝凤', - twchaofeng_backup:'朝凤', - twchaofeng_info:'①你可以将一张【杀】当做【闪】、【闪】当做任意一种【杀】使用或打出。②出牌阶段开始时,你可以与至多三名角色共同拼点。赢的角色视为对所有没赢的角色使用一张火【杀】。', - twchuanshu:'传术', - twchuanshu_info:'限定技。准备阶段,你可以选择一名角色。直到你的下回合开始,其获得以下效果:1.当其拼点牌亮出时,此牌点数+3;2.其使用的下一张【杀】对除你外的角色造成伤害时,此伤害+1;3.若其不为你,其使用的下一张【杀】结算结束后,你摸等同于其因此【杀】造成的伤害值数的牌。', - xia_xushu:'侠徐庶', - xia_xushu_prefix:'侠', - twjiange:'剑歌', - twjiange_info:'每回合限一次。你可以将一张非基本牌当做【杀】使用或打出(无距离和次数限制,且不计入次数)。若此时不为你的回合,你摸一张牌。', - twxiawang:'侠望', - twxiawang_info:'当一名角色受到伤害后,若你至其的距离不大于1,你可以对伤害来源使用一张【杀】。当此【杀】结算结束后,若你造成过渠道为此牌的伤害,结束当前阶段。', - tw_haomeng:'TW郝萌', - tw_haomeng_prefix:'TW', - twgongge:'攻阁', - twgongge_info:'摧坚:你可以选择一项:1.摸X+1张牌。其响应此牌后,跳过你的下一个摸牌阶段;2.弃置其X+1张牌。此牌结算结束后,若其体力值不小于你,你交给其X张牌;3.此牌对其造成的伤害+X。此牌结算结束后,其回复X点体力。', - tw_weixu:'魏续', - twsuizheng:'随征', - twsuizheng_info:'锁定技。游戏开始时,你选择一名其他角色,称为“随征”角色。你获得以下效果:当“随征”角色造成伤害后,你摸一张牌;当“随征”角色受到伤害后,你选择一项:1.失去1点体力,令其从牌堆或弃牌堆中获得一张【杀】或【决斗】;2.弃置两张基本牌,令其回复1点体力。', - twtuidao:'颓盗', - twtuidao_info:'限定技。准备阶段,若“随征”角色的体力值不大于2或“随征”角色已死亡,你可以废除你与其的一个坐骑栏并选择一个类别,然后若“随征”角色存活,你获得其所有此类别的牌,否则你从牌堆中获得两张此类别的牌。然后你将“随征”角色改为另一名角色。', - tw_caoxiu:'TW曹休', - tw_caoxiu_prefix:'TW', - twqianju:'千驹', - twqianju_info:'锁定技。①你计算与其他角色的距离-X(X为你装备区的牌数)。②每回合限一次。当你对距离为1以内的角色造成伤害后,若你的装备区存在空置装备栏,你从牌堆或弃牌堆中将一张你空置装备栏对应副类别的装备牌置于你的装备区。', - twqingxi:'倾袭', - twqingxi_info:'当你使用张【杀】指定目标后,若此牌为你于本回合使用的第一张【杀】,你可以令目标角色选择一项:1.令你摸Y张牌,此【杀】不可被其响应(Y为你装备区的牌数且至少为1);2.若其装备区里有牌,弃置装备区里的所有牌,然后弃置你装备区里的等量张牌,令此【杀】对其造成的伤害+1。', - tw_sunyi:'TW孙翊', - tw_sunyi_prefix:'TW', - twzaoli:'躁厉', - twzaoli_info:'锁定技。①出牌阶段,你只能使用或打出你本回合得到的手牌。②出牌阶段开始时,你须弃置你区域内的所有装备牌并弃置任意张非装备手牌,你摸等量的牌,从牌堆中将你此次弃置的装备牌对应副类别的装备牌置入装备区。若你以此法置入了超过两张装备牌,你失去1点体力。', - tw_yangyi:'TW杨仪', - tw_yangyi_prefix:'TW', - twgongsun:'共损', - twgongsun_shadow:'共损', - twgongsun_info:'锁定技。出牌阶段开始时,你选择攻击范围内的一名其他角色并选择一种花色,直至你的下个回合开始前或你死亡时,你与其均无法使用、打出或弃置该花色的手牌。', - tw_dengzhi:'TW邓芝', - tw_dengzhi_prefix:'TW', - twjimeng:'急盟', - twjimeng_info:'出牌阶段限一次。你可以获得一名其他角色区域内的一张牌,然后交给其一张牌。若其体力值不小于你,你摸一张牌。', - xia_lusu:'侠鲁肃', - xia_lusu_prefix:'侠', - twkaizeng:'慨赠', - twkaizeng_info:'其他角色的出牌阶段限一次。其可以选择一种基本牌的牌名或非基本牌的类型,然后令你选择是否交给其任意张手牌。若你以此法:交给其至少两张牌,你摸一张牌;交给其的牌中包含其选择的牌名或类型的牌,你获得一张与此牌名或类型不同的牌。', - twyangming:'扬名', - twyangming_info:'出牌阶段结束时,你可以摸X张牌,且令本回合的手牌上限+X(X为你本阶段使用过的牌的类型数)。', - xia_dianwei:'侠典韦', - xia_dianwei_prefix:'侠', - twliexi:'烈袭', - twliexi_info:'准备阶段,你可以弃置任意张牌并选择一名其他角色。若你以此法弃置的牌数大于其体力值,你对其造成1点伤害;否则其对你造成1点伤害。然后若你弃置的牌中有武器牌,你对其造成1点伤害。', - twshezhong:'慑众', - twshezhong_info:'结束阶段,若你:本回合对其他角色造成过伤害,你可以令至多X名其他角色下个摸牌阶段的额定摸牌数-1(X为你本回合造成的伤害值);本回合受到过伤害,你可以将手牌摸至与其中一名伤害来源的体力值相同(至多摸至5)。', - xia_zhaoe:'赵娥', - twyanshi:'言誓', - twyanshi_info:'①游戏开始时,你选择一名其他角色,称为“言誓”角色。②当你或“言誓”角色受到二者之外角色造成的伤害后,伤害来源获得1枚“誓”标记。③你对有“誓”的角色使用牌无距离限制。④当你对有“誓”的角色造成伤害时,此伤害+1,且当你对这些角色造成伤害后,你摸等同于伤害值的牌并移去其所有“誓”。', - twrenchou:'刃仇', - twrenchou_info:'锁定技。当你或“言誓”角色死亡时,若二者中的另一名角色A存活,A对杀死你或其的角色造成X点伤害(X为A的体力值)。', - xia_xiahouzie:'夏侯紫萼', - twxuechang:'血偿', - twxuechang_info:'出牌阶段限一次。你可以与一名其他角色拼点。若你:赢,你获得其一张牌,若此牌为装备牌,你视为对其使用一张【杀】;没赢,其对你造成1点伤害,且你下次对其造成的伤害+1。', - twduoren:'夺刃', - twduoren_info:'①当你杀死角色后,你可以减1点体力上限,然后获得其所有的非主公技和非隐匿技。②当你令其他角色进入濒死状态时,你失去因〖夺刃①〗获得的技能。', - tw_yangang:'严纲', - twzhiqu:'直取', - twzhiqu_info:'结束阶段,你可以选择一名其他角色并依次使用牌堆顶X张牌中的【杀】。搏击:依次使用牌堆顶X张牌中的锦囊牌(X为你距离不大于1内的角色数,且你或其以外的角色不是你以此法使用牌的合法目标)。', - twxianfeng:'先锋', - twxianfeng_info:'当你于出牌阶段使用【杀】或伤害类锦囊牌对其他角色造成伤害后,你可以令受伤角色选择一项:1.其摸一张牌,然后直到你下个回合开始时,你至其他角色的距离-1;2.你摸一张牌,然后直到你下个回合开始时,其至你的距离-1。', - tw_gongsunfan:'公孙范', - twhuiyuan:'回援', - twhuiyuan_info:'当你于出牌阶段使用牌结算结束后,若你未于此阶段获得过此类型的牌,你可以展示一名角色的一张手牌,若此牌与你使用的牌类型相同,你获得此牌,否则你弃置此牌,然后其摸一张牌。游击:对其造成1点伤害。', - twshoushou:'收绶', - twshoushou_info:'①当你获得其他角色的牌时,若你在任意角色的攻击范围内,其他角色至你的距离+1。②当你造成或受到伤害后,若你不在任意其他角色的攻击范围内,其他角色至你的距离-1。', - twshijun:'师君', - twshijun_info:'主公技,其他群势力角色出牌阶段限一次,若你没有“米”,其可以摸一张牌,然后将一张牌置于你的武将牌上,称为“米”。', - twjuxiang:'踞襄', - twjuxiang_info:'主公技,其他群势力角色出牌阶段限一次,其可以选择其装备区的一张牌移动到你的装备区中,若你对应的装备栏已被废除,则改为交给你此装备牌,然后恢复你的对应装备栏。', - tw_ol_sunjian:'TW孙坚', - tw_ol_sunjian_prefix:'TW', - twpolu:'破虏', - twpolu_info:'主公技,当吴势力角色杀死一名角色或死亡后,你可以令任意名角色各摸X张牌(X为你此前发动过此技能的次数+1)。', - tw_menghuo:'TW孟获', - tw_menghuo_prefix:'TW', - twqiushou:'酋首', - twqiushou_info:'主公技,锁定技,当一张【南蛮入侵】结算结束后,若此牌造成的伤害大于3点或有角色因此死亡,所有蜀势力和群势力角色各摸一张牌。', - twzhuiting:'坠廷', - twzhuiting_info:'主公技,当一张锦囊牌即将对你生效时,其他魏势力角色和群势力角色可将一张与此牌颜色相同的牌当作【无懈可击】使用。', - twniju:'逆拒', - twniju_info:'主公技。当你的拼点牌亮出后,你可以令本次拼点事件中的一张拼点牌的点数+X或-X。然后当本次拼点事件结束后,若有两张拼点牌的点数相等,你摸X张牌(X为场上群势力角色数)。', - ol_liuyu:'TW刘虞', - ol_liuyu_prefix:'TW', - twchongwang:'崇望', - twchongwang_info:'主公技,其他群势力角色的出牌阶段开始时,其可以交给你一张牌,然后你与其使用【杀】或伤害性锦囊牌指定目标时不能指定对方为目标直至你的下回合结束(每名角色限发动一次)。', - tw_zhangzhao:'张昭', - twlijian:'力荐', - twlijian_info:'昂扬技。其他角色的弃牌阶段结束时,你可以令其获得任意本阶段进入弃牌堆的牌(可不选),然后你获得其余的牌,若其得到的牌数大于你,你可以对其造成1点伤害。
              激昂:八张牌进入弃牌堆。', - twchungang:'纯刚', - twchungang_info:'锁定技。一名其他角色于摸牌阶段外得到超过一张牌时,你令其弃置一张牌。', - tw_zhanghong:'张纮', - twquanqian:'劝迁', - twquanqian_info:'昂扬技。出牌阶段限一次,你可以将至多四张花色各不相同的手牌交给一名其他角色,然后若你交出的牌数大于1,则你从牌堆中获得一张装备牌,然后选择一项:①将手牌数摸至与其相同;②观看其手牌并获得其一种花色的所有牌。
              激昂:你弃置六张手牌。', - twrouke:'柔克', - twrouke_info:'锁定技。当你于摸牌阶段外得到超过一张牌时,你摸一张牌。', - kaisa:"凯撒", - zhengfu:"征服", - zhengfu_info:"当你使用【杀】指定目标时,你可以选择一种牌的类别,然后除非目标角色交给你一种该类别的牌,否则其不能闪避此【杀】。", - xia_xiahoudun:'侠夏侯惇', - xia_xiahoudun_prefix:'侠', - twdanlie:'胆烈', - twdanlie_info:'①出牌阶段限一次。你可以与至多三名其他角色共同拼点。若你赢,你对没赢的角色依次造成1点伤害;若你没赢,你失去1点体力。②你的拼点牌点数+X(X为你已损失的体力值)。', - xia_zhangwei:'张葳', - twhuzhong:'护众', - twhuzhong_info:'当你于出牌阶段使用无属性【杀】指定唯一目标角色时,你可以摸一张牌并选择一项:①为此牌额外选择一个目标;②弃置其一张手牌,此牌结算完毕后,若此牌造成过伤害,则你摸一张牌且本阶段可以额外使用一张【杀】。', - twfenwang:'焚亡', - twfenwang_info:'锁定技。①当你受到属性伤害时,你须弃置一张牌或令此伤害+1。②当你对其他角色造成非属性伤害时,若你的手牌数大于等于其,则此伤害+1。', - xia_xiahousone:'夏侯子萼', - twchengxi:'承袭', - twchengxi_info:'出牌阶段每名角色限一次,你可以摸一张牌并与一名其他角色拼点。若你赢,你使用的下一张基本牌或非延时锦囊牌结算完毕后,你视为对原目标使用一张无次数限制的同名牌;若你没赢,其视为对你使用一张无距离限制的【杀】。', - xia_liubei:'侠刘备', - xia_liubei_prefix:'侠', - twshenyi:'伸义', - twshenyi_info:'每回合限一次,当你或你攻击范围内的一名角色于一回合内首次受到伤害后,你可以声明一种基本牌或锦囊牌(每种牌名限一次),然后从牌堆中将一张同名牌(若没有同名牌则改为同类型的牌)称为“侠义”置于武将牌上。若受伤角色不为你,则你可以将任意张手牌交给其,且当其失去一张你以此法交给其的牌后,你摸一张牌。', - twxinghan:'兴汉', - twxinghan_info:'①你的回合外或你处于濒死状态时,你可以如手牌般使用或打出“侠义”牌。②准备阶段,若“侠义”牌数大于存活角色数,则你可以依次使用其中所有可以使用的牌。然后你获得如下效果:回合结束时,你弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)。', - twxinghan_tag:'侠义', - xia_guanyu:'侠关羽', - xia_guanyu_prefix:'侠', - twzhongyi:'忠义', - twzhongyi_info:'锁定技。①你使用【杀】无距离限制。②当你使用【杀】结算完毕后,你选择一项:⒈摸X张牌;⒉回复X点体力;⒊背水:失去Y点体力,依次执行以上两项(X为受到此牌造成的伤害的角色数,Y为你本局游戏选择此项的次数)。', - twchue:'除恶', - twchue_info:'①当你使用【杀】指定唯一目标时,若场上存在可称为此【杀】目标的非目标角色,则你可以失去1点体力,为此牌额外指定Z个目标。②当你受到伤害或失去体力后,你摸一张牌并获得1个“勇”标记。③回合结束时,若你的“勇”标记数大于等于Z,则你可以失去Z个“勇”标记,视为使用一张伤害+1且可以额外指定Z个目标的【杀】。(Z为你的体力值)', - xia_shitao:'石韬', - twjieqiu:'劫囚', - twjieqiu_info:'出牌阶段限一次,你可以选择一名装备区没有废除栏的其他角色,废除其所有装备栏,然后其摸X张牌(X为其废除装备栏前的装备区牌数),直到其恢复所有装备栏前:其弃牌阶段结束时,其恢复等同于其弃置牌数的装备栏;其回合结束时,若其仍有已废除的装备栏,则你执行一个额外回合(每轮限一次)。', - twenchou:'恩仇', - twenchou_info:'出牌阶段限一次,你可以观看一名存在废除装备栏的其他角色的手牌并获得其中一张牌,然后你恢复其一个装备栏。', - xia_shie:'史阿', - twdengjian:'登剑', - twdengjianx:'剑法', - twdengjian_info:'①其他角色的弃牌阶段结束时,你可以随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】,称为“剑法”。②你使用“剑法”牌不计入次数限制。', - twxinshou:'心授', - twxinshou_info:'①当你于出牌阶段使用【杀】时,若此【杀】与你本回合使用的所有其他【杀】的颜色均不相同,则你可以选择执行以下一项本回合未执行过的项:⒈摸一张牌;⒉交给一名其他角色一张牌。②当你使用【杀】时,若〖心授①〗的两项本回合均已被你选择过,则你可以令〖登剑①〗失效并令一名其他角色获得〖登剑〗,你的下个回合开始时,其失去〖登剑〗,若其这期间使用【杀】造成过伤害,则你结束〖登剑①〗的失效状态。', - xia_yuzhenzi:'玉真子', - twhuajing:'化境', - twhuajing_info:'①游戏开始时,你获得6个效果各不相同的无效果“武”标记。②一名拥有“武”标记的角色的攻击范围+X(X为其拥有的“武”标记数)。③出牌阶段限一次,你可以展示至多四张手牌,然后根据这些牌含有的花色数于本回合获得等量你拥有的“武”标记的效果。④拥有“武”标记效果的角色的武器牌失效(武器牌不提供攻击范围且武器技能失效)。', - twhuajing_jian:'剑', - twhuajing_jian_info:'当你使用【杀】指定目标后,你随机弃置目标角色两张牌。', - twhuajing_dao:'刀', - twhuajing_dao_info:'当你使用【杀】对没有手牌的目标角色造成伤害时,此伤害+1。', - twhuajing_fu:'斧', - twhuajing_fu_info:'当你使用的【杀】被【闪】响应后,你对目标角色造成1点伤害。', - twhuajing_qiang:'枪', - twhuajing_qiang_info:'当你使用黑色【杀】结算完毕后,你从牌堆或弃牌堆中获得一张【闪】。', - twhuajing_ji:'戟', - twhuajing_ji_info:'当你使用【杀】造成伤害时,你摸一张牌。', - twhuajing_gong:'弓', - twhuajing_gong_info:'当你使用【杀】造成伤害后,你随机弃置受伤角色装备区里的一张牌。', - twtianshou:'天授', - twtianshou_info:'锁定技,回合结束时,若你本回合使用【杀】造成过伤害,且你拥有本回合获得过效果的“武”标记,则你须将其中一个“武”标记交给一名其他角色并令其获得此标记的效果直到其回合结束,然后你摸两张牌。', - tw_yanliang:'颜良', - tw_wenchou:'文丑', - tw_yuantan:'袁谭', - twduwang:'独往', - twduwang_info:'使命技。①出牌阶段开始时,你可以选择至多三名有牌的其他角色,摸X张牌(X为选择角色数+1),然后这些角色依次将一张牌当【决斗】对你使用。②当你处于濒死状态时,其他角色不能对你使用【桃】。③使命:使用【决斗】或成为【决斗】目标的次数之和不小于4(若游戏总人数小于4则改为3)。④成功:准备阶段,若你于你的上回合完成了〖独往③〗的使命,则你重置〖独往〗并将〖独往〗修改至只保留〖独往①〗的效果,选择一项:⒈获得〖狭勇〗;⒉重置〖延势〗并令其获得历战效果。⑤失败:当你死亡时,使命失败。', - twylyanshi:'延势', - twylyanshi_info:'限定技。你可以将一张【杀】当作【决斗】、【兵临城下】或任意智囊牌使用或打出。', - twylyanshix:'延势·改', - twylyanshix_info:'限定技。你可以将一张【杀】当作【决斗】、【兵临城下】或任意智囊牌使用或打出。历战:重置〖延势〗。', - twjuexing:'绝行', - twjuexing_info:'出牌阶段限一次。你可以视为对一名其他角色使用一张【决斗】。此牌对一名角色生效时,你与其将所有手牌扣置于武将牌上,然后各摸等同于当前体力值的牌。此牌结算结束后,你与所有目标角色弃置本次以此法摸的牌,然后获得扣置于武将牌上的牌。历战:当你因〖绝行〗摸牌时,摸牌数+1。', - twxiayong:'狭勇', - twxiayong1:'狭勇', - twxiayong2:'狭勇', - twxiayong_info:'锁定技。当你使用的【决斗】或目标角色包括你的【决斗】造成伤害时,若受伤角色为你,则你随机弃置一张手牌;否则你令此伤害+1。', - twqiaosi:'峭嗣', - twqiaosi_info:'结束阶段,你可以获得由其他角色区域直接置入或经由处理区置入弃牌堆的所有牌,然后若你以此法获得的牌数小于你的体力值,则你失去1点体力。', - twbaizu:'败族', - twbaizu_info:'锁定技。结束阶段,若你已受伤且你有手牌,则你须选择X名有手牌的其他角色(X为你的体力值),你与这些角色同时弃置一张手牌,然后你对与你弃置牌类别相同的所有其他角色各造成1点伤害。历战:〖败族〗目标选择数+1。', + twyanqin: "姻亲", + twyanqin_info: "准备阶段,你可以将势力变更为魏或蜀。", + twbaobian: "豹变", + twbaobian_info: + "当你使用【杀】或【决斗】造成伤害时,若目标角色的势力与你相同,则你可以防止此伤害,然后其将手牌数补充至与体力值相同。若不同且其手牌数大于体力值,则你可以将其手牌弃置至与其体力值相同。", + twtijin: "替巾", + twtijin_info: + "当你攻击范围内的一名其他角色使用【杀】指定另一名其他角色为目标时,你可以将此【杀】的目标改为你。若如此做,此【杀】结算完成后,你弃置该角色的一张牌。", + twxiaolian: "孝廉", + twxiaolian_info: + "当一名其他角色使用【杀】指定另一名其他角色为目标时,你可以将此【杀】的目标改为你。若如此做,当你受到此【杀】的伤害后,你可以将一张牌置于此【杀】原目标的武将牌旁,称为“马”,且令其获得如下效果:其他角色计算至其的距离+X(X为其武将牌旁的“马”数)。", + twqijia: "弃甲", + twqijia_info: + "出牌阶段,你可以弃置一张装备区内的牌(每种类型的装备牌限一次),然后视为对攻击范围内的一名其他角色使用了一张【杀】。", + twzhuchen: "诛綝", + twzhuchen_info: + "出牌阶段,你可以弃置一张【桃】或【酒】并选择一名其他角色。你与其的距离视为1直到此阶段结束。", + twhuzhu: "护主", + twhuzhu_info: + "出牌阶段限一次,若你的装备区内有牌,则你可以令一名其他角色交给你一张手牌,然后获得你装备区内的一张牌。若其体力值不大于你,则你可以令其回复1点体力。", + twliancai: "敛财", + twliancai_info: + "结束阶段,你可以将武将牌翻面,然后获得一名其他角色装备区内的一张牌。当你的武将牌翻面时,你可以将手牌补至与体力值相同。", + twrangyi: "攘夷", + twrangyi2: "攘夷", + twrangyi_info: + "出牌阶段限一次,你可以将所有手牌交给一名其他角色,然后令其选择一项:1.使用其中的一张牌,并于此牌被使用时将其余的牌交还给你。2.受到来自你的1点伤害。", + twbaimei: "白眉", + twbaimei_info: "锁定技,若你没有手牌,则防止你受到的所有属性伤害和锦囊牌造成的伤害。", + chijie: "持节", + chijie_info: " 游戏开始时,你可以选择一个现存势力,你的势力视为该势力。", + waishi: "外使", + waishi_info: + " 出牌阶段限一次,你可以用至多X张牌交换一名其他角色等量的手牌(X为现存势力数),然后若其与你势力相同或手牌多于你,你摸一张牌。", + renshe: "忍涉", + renshe_info: + "当你受到伤害后,你可以选择一项:将势力改为现存的另一个势力;或可以额外发动一次“外使”直到你的下个出牌阶段结束;或与另一名其他角色各摸一张牌。", + tw_gexuan: "TW葛玄", + tw_gexuan_prefix: "TW", + twdanfa: "丹法", + twdanfa_info: + "准备阶段或结束阶段开始时,你可将一张牌置于武将牌上,称为“丹”。每回合每种花色限一次,当你使用牌时,若“丹”中有与此牌花色相同的牌,则你摸一张牌。", + twlingbao: "灵宝", + twlingbao_info: + "出牌阶段限一次,你可以将两张花色不同的“丹”置入弃牌堆。若这两张牌:均为红色,你令一名其他角色回复1点体力;均为黑色,你弃置一名其他角色区域内至多两张区域不同牌;颜色不同,则你令一名角色摸一张牌,并令另一名角色弃置一张牌。", + twsidao: "司道", + twsidao_info: + "游戏开始时,你选择一张“法宝”置入装备区。准备阶段,若你以此法选择的法宝在牌堆/弃牌堆中,则你使用之。", + gx_lingbaoxianhu: "灵宝仙壶", + gx_lingbaoxianhu_info: + "锁定技,当你造成点数大于1的伤害后,或有角色死亡后,你加1点体力上限并回复1点体力。", + gx_taijifuchen: "太极拂尘", + gx_taijifuchen_info: + "锁定技,当你使用【杀】指定目标后,你令目标角色选择一项:①弃置一张牌,若此牌和【杀】花色相同,则你获得之。②其不可响应此【杀】。", + gx_chongyingshenfu: "冲应神符", + gx_chongyingshenfu_info: + "锁定技。①当你受到牌造成的伤害后,你记录此牌的名称。②当你受到〖冲应神符①〗记录过的牌造成的伤害时,你令此牌伤害-1。", + tw_dongzhao: "TW董昭", + tw_dongzhao_prefix: "TW", + twmiaolve: "妙略", + twmiaolve_info: + "游戏开始时,你获得两张【瞒天过海】。当你受到1点伤害后,你可选择:①获得一张【瞒天过海】并摸一张牌。②获得一张智囊。", + twyingjia: "迎驾", + twyingjia_info: + "一名角色的回合结束时,若你本回合内使用过两张或更多的同名锦囊牌,则你可弃置一张手牌并令一名角色进行一个额外回合。", + dz_mantianguohai: "瞒天过海", + dz_mantianguohai_info: + "此牌不计入拥有者的手牌上限。出牌阶段,对一至两名区域内有牌的其他角色使用。你获得目标角色一张牌,然后依次交给每名目标角色各一张牌。", + jiachong: "TW贾充", + jiachong_prefix: "TW", + beini: "悖逆", + beini_info: + "出牌阶段限一次,你可以选择一名体力值不小于你的角色,令你或其摸两张牌,然后未摸牌的角色视为对摸牌的角色使用一张【杀】。", + dingfa: "定法", + dingfa_info: + "弃牌阶段结束时,若本回合你失去的牌数不小于你的体力值,你可以选择一项:1、回复1点体力;2、对一名其他角色造成1点伤害。", + duosidawang: "朵思大王", + equan: "恶泉", + equan_info: + "锁定技。①当有角色于你的回合内受到伤害后,其获得X枚“毒”(X为伤害值)。②准备阶段,你令所有拥有“毒”标记的角色移去所有“毒”标记并失去等量的体力。③当有角色因〖恶泉②〗进入濒死状态时,你令其所有技能失效直到回合结束。", + manji: "蛮汲", + manji_info: + "锁定技。其他角色失去体力后,若你的体力值:不大于该角色,你回复1点体力;不小于该角色,你摸一张牌。", + wuban: "TW吴班", + wuban_prefix: "TW", + jintao: "进讨", + jintao_info: + "锁定技,你使用【杀】无距离限制且次数上限+1。你于出牌阶段内使用的第一张【杀】伤害+1,第二张【杀】不可被响应。", + yuejiu: "TW乐就", + yuejiu_prefix: "TW", + cuijin: "催进", + cuijin_info: + "当你或你攻击范围内的角色使用【杀】时,你可以弃置一张牌并获得如下效果:此【杀】的伤害值基数+1,且当此【杀】结算结束后,若未造成过伤害,则你对使用者造成1点伤害。", + tw_zhaoxiang: "TW赵襄", + tw_zhaoxiang_prefix: "TW", + twfuhan: "扶汉", + twfuhan_info: + '限定技。准备阶段开始时时,你可以移去所有"梅影"标记,然后从五张未登场的蜀势力武将牌中选择一名获得其所有技能,将体力上限数调整为以此技能移去所有“梅影”标记的数量(最少为2,最多为8)并回复1点体力,然后从牌堆/弃牌堆/场上获得【梅影枪】。', + twqueshi: "鹊拾", + twqueshi_info: "游戏开始时,你将【梅影枪】置于你的装备区。", + meiyingqiang: "梅影枪", + meiyingqiang_info: "当你于其他角色的回合内第一次失去牌时,你可以使用一张【杀】。", + tw_fuwan: "TW伏完", + tw_fuwan_prefix: "TW", + twmoukui: "谋溃", + twmoukui_info: + "当你使用【杀】指定目标后,你可以选择一项:①摸一张牌;②弃置该角色的一张牌;③背水:若此【杀】未因造成伤害而令该角色进入过濒死状态,则该角色弃置你的一张牌。", + tw_yujin: "SP于禁", + tw_yujin_prefix: "SP", + xinzhenjun: "镇军", + xinzhenjun_info: + "出牌阶段开始时,你可以将一张牌交给一名其他角色,令其选择是否使用一张不为黑色的【杀】。若其选择是,则你于此【杀】结算完成后摸1+X张牌(X为此【杀】造成的伤害总点数)。若其选择否,则你对其或其攻击范围内的一名其他角色造成1点伤害。", + tw_hucheer: "TW胡车儿", + tw_hucheer_prefix: "TW", + twshenxing: "神行", + twshenxing_info: "锁定技。若你的装备区内没有坐骑牌,则你至其他角色的距离-1且手牌上限+1。", + twdaoji: "盗戟", + twdaoji_info: + "出牌阶段限一次,你可以弃置一张非基本牌并选择一名攻击范围内的角色,获得其一张牌。若你以此法得到的牌为:基本牌,你摸一张牌;装备牌,你使用此牌并对其造成1点伤害。", + tw_hejin: "TW何进", + tw_hejin_prefix: "TW", + twmouzhu: "谋诛", + twmouzhu_info: + "出牌阶段限一次,你可以选择一名其他角色A。你令除A外所有体力值小于等于你的其他角色依次选择是否交给你一张牌。若你以此法得到的牌数X:等于0,你和所有进行选择的角色依次失去1点体力。大于0,你令A选择由你视为对其使用一张伤害值基数为X的【杀】或【决斗】。", + twyanhuo: "延祸", + twyanhuo_info: + "当你死亡时,你可以选择一项:①令一名其他角色弃置X张牌。②令X名其他角色依次弃置一张牌。(X为你的牌数)", + tw_mayunlu: "TW马云禄", + tw_mayunlu_prefix: "TW", + twfengpo: "凤魄", + twfengpo_info: + "①当你使用【杀】或【决斗】指定唯一目标后,你可观看目标角色的手牌并选择一项:⒈摸X张牌。⒉令此牌的伤害值基数+X(X为其手牌中的♦数)。②当你杀死一名角色后,你将〖凤魄①〗中的“♦数”改为“红色牌数”。", + tw_re_caohong: "TW曹洪", + tw_re_caohong_prefix: "TW", + twyuanhu: "援护", + twyuanhu_info: + "出牌阶段限一次。你可将一张装备牌置入一名角色的装备区内。若此牌为:武器牌,你弃置与其距离为1的另一名角色区域的一张牌;防具牌,其摸一张牌;坐骑牌或宝物牌,其回复1点体力。然后若其体力值或手牌数不大于你,则你摸一张牌,且你可以于本回合的结束阶段发动一次〖援护〗。", + twjuezhu: "决助", + twjuezhu_info: + "限定技。准备阶段,你可废除一个坐骑栏,令一名角色获得〖飞影〗并废除判定区。该角色死亡后,你恢复以此法废除的装备栏。", + tw_zangba: "TW臧霸", + tw_zangba_prefix: "TW", + twhanyu: "捍御", + twhanyu_info: "锁定技。游戏开始时,你获得牌堆中的基本牌,锦囊牌,装备牌各一张。", + twhengjiang: "横江", + twhengjiang_info: + "出牌阶段限一次,当你使用基本牌或普通锦囊牌指定唯一目标后,你可将此牌的目标改为攻击范围内的所有合法目标,然后你于此牌结算结束后摸X张牌(X为因响应此牌而使用或打出过牌的角色数)。", + tw_huojun: "TW霍峻", + tw_huojun_prefix: "TW", + twsidai: "伺怠", + twsidai_info: + "限定技。出牌阶段,你可以将手牌区内的所有基本牌当做【杀】使用(无距离和次数限制)。若此牌对应的实体牌中:包含【闪】,则目标角色成为此牌的目标后,需弃置一张基本牌,否则不可响应此牌;包含【桃】,则当目标角色受到此牌的伤害后,其减1点体力上限;包含【酒】,则当目标角色受到此牌的伤害时,此伤害×2。", + twjieyu: "竭御", + twjieyu_info: + "每轮限一次。结束阶段开始时,或当你于一轮内第一次受到伤害后,你可以弃置所有手牌,然后从弃牌堆中获得不同牌名的基本牌各一张。", + tw_liuhong: "TW刘宏", + tw_liuhong_prefix: "TW", + twyujue: "鬻爵", + twyujue_give: "鬻爵", + twyujue_info: + "①其他角色的出牌阶段内,可以交给你任意张牌(每阶段上限为两张)。②当你于回合外获得其他角色的一张牌后,你可令其选择本回合内未选择过的一项:⒈弃置攻击范围内一名角色的一张牌。⒉下一次使用牌时,从牌堆中获得一张同类别的牌。", + twgezhi: "革制", + twgezhi_info: + "①当你于出牌阶段内首次使用某种类别的牌时,你可以重铸一张手牌。②出牌阶段结束时,若你本阶段内因〖革制①〗失去过至少两张牌,则你可以令一名角色选择获得一个其未获得过的效果:⒈攻击范围+2;⒉手牌上限+2;⒊加1点体力上限。", + twfengqi: "烽起", + twfengqi_info: + "主公技,锁定技。①其他群势力角色发动〖鬻爵①〗时,将每阶段上限改为四张。②以其他角色为目标的〖革制②〗结算结束后,目标角色可以获得其武将牌上的主公技。", + tw_caocao: "TW曹操", + tw_caocao_prefix: "TW", + twlingfa: "令法", + twlingfa_info: + "①第一轮游戏开始时,你可选择获得如下效果直到本轮结束:其他角色使用【杀】时,若其有牌,则其需弃置一张牌,否则受到你造成的1点伤害。②第二轮游戏开始时,你可选择获得如下效果直到本轮结束:其他角色使用【桃】结算结束后,若其有牌,则其需交给你一张牌,否则受到你造成的1点伤害。③第三轮游戏开始时,你失去〖令法〗并获得〖治暗〗。", + twzhian: "治暗", + twzhian_info: + "每回合限一次。一名角色使用装备牌或延时锦囊牌后,你可选择:⒈弃置位于场上的此牌。⒉弃置一张手牌并获得位于场上的此牌。⒊对其造成1点伤害。", + tw_zhangmancheng: "TW张曼成", + tw_zhangmancheng_prefix: "TW", + twfengji: "蜂集", + twfengji_info: + "出牌阶段开始时,若你没有“示”,则你可以将一张牌作为“示”置于武将牌上并施法:从牌堆中获得X张与“示”牌名相同的牌,然后移去“示”。", + twyiju: "蚁聚", + twyiju_info: + "若你的武将牌上有“示”,则:①你使用【杀】的次数上限和攻击范围的基数改为你的体力值。②当你受到伤害时,你移去“示”,且令此伤害+1。", + twbudao: "布道", + twbudao_info: + "限定技。准备阶段,你可减1点体力上限,回复1点体力并选择获得一个〖布道〗技能池里的技能(三选一)。然后你可以令一名其他角色也获得此技能并交给你一张牌。", + twzhouhu: "咒护", + twzhouhu_info: "出牌阶段限一次。你可以弃置一张红色手牌并施法:回复X点体力。", + twharvestinori: "丰祈", + twharvestinori_info: "出牌阶段限一次。你可以弃置一张黑色手牌并施法:摸2X张牌。", + twzuhuo: "阻祸", + twzuhuo_info: "出牌阶段限一次。你可以弃置一张非基本牌并施法:防止你受到的下X次伤害。", + twzhouzu: "咒诅", + twzhouzu_info: + "出牌阶段限一次。你可以对一名其他角色施法:其弃置X张牌,然后你对其造成1点雷电伤害。", + twhuangjin: "黄巾", + twhuangjin_info: + "锁定技。当你一名角色使用【杀】指定你为目标时,若此【杀】有点数,你判定,若点数与此【杀】点数差值不大于1,则此【杀】对你无效。", + twguimen: "鬼门", + twguimen_info: + "锁定技。当你弃置牌时,若其中有♠牌,你为每一张♠牌判定,若此牌点数与结果之差不大于1,你对一名其他角色造成2点雷电伤害。", + twdidao: "地道", + twdidao_info: + "一名角色的判定牌生效前,你可以打出一张牌作为判定牌并获得原判定牌。若你以此法打出的牌与原判定牌颜色相同,你摸一张牌。", + tw_chengpu: "TW程普", + tw_chengpu_prefix: "TW", + twlihuo: "疠火", + twlihuo2: "疠火", + twlihuo3: "疠火", + twlihuo_info: + "①当你声明使用普【杀】后,你可以将此【杀】改为火【杀】。此牌使用结算结束后,若有角色因此【杀】造成的伤害进入过濒死状态,则你失去1点体力。②当你使用火【杀】选择目标后,你可为此牌增加一个目标。", + twchunlao: "醇醪", + twchunlao_info: + "①准备阶段,若场上没有“醇”,则你可将一名角色区域内的一张牌置于其武将牌上,称为“醇”。②一名角色使用【杀】时,若其有“醇”,则其可以交给你一张牌,令此【杀】的伤害值基数+1。③一名角色进入濒死状态时,若其有“醇”,则你可以移去“醇”并摸一张牌,然后令其回复1点体力。", + tw_guohuai: "TW郭淮", + tw_guohuai_prefix: "TW", + twjingce: "精策", + twjingce_info: + "当你于出牌阶段使用第X张牌结算完毕后,你可以摸两张牌(X为你的体力值)。若此阶段你此前已摸过牌或本回合造成过伤害,你获得一枚“策”标记。", + yuzhang: "御嶂", + yuzhang_info: + "你可以弃置一枚“策”标记,然后跳过一个阶段。当你受到伤害后,你可弃置一枚“策”标记,然后选择一项:⒈令伤害来源弃置两张牌;⒉令伤害来源本回合不能再使用或打出牌。", + tw_caozhao: "曹肇", + twfuzuan: "复纂", + twfuzuan_info: + "出牌阶段限一次/当你受到伤害后/当你对其他角色造成伤害后,你可选择一名拥有转换技的角色,变更其的一个转换技的的状态。", + twchongqi: "宠齐", + twchongqi_info: + "锁定技。游戏开始时,你令所有角色获得〖非服〗。然后你可减1点体力上限,令一名其他角色获得〖复纂〗。", + twfeifu: "非服", + twfeifu_info: + "锁定技,转换技。阴:当你成为【杀】的唯一目标后;阳:当你使用【杀】指定唯一目标后;目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。", + tw_wangchang: "TW王昶", + tw_wangchang_prefix: "TW", + twkaiji: "开济", + twkaiji_info: + "准备阶段,你可令至多X名角色各摸一张牌(X为本局游戏内进入过濒死状态的角色数+1)。若有角色以此法获得了非基本牌,则你摸一张牌。", + twshepan: "慑叛", + twshepan_info: + "每回合限一次。当你成为其他角色使用牌的目标后,你可选择一项:⒈摸一张牌。⒉将其区域内的一张牌置于牌堆顶。然后若你的手牌数与其相等,则你将此技能的发动次数归零,且可以令此牌对你无效。", + tw_wangcan: "TW王粲", + tw_wangcan_prefix: "TW", + twdianyi: "典仪", + twdianyi_info: + "锁定技。你的回合结束时,若你本回合内:造成过伤害,你弃置所有手牌;未造成过伤害,你将手牌数调整至四张。", + twyingji: "应机", + twyingji_wuxie: "应机", + twyingji_info: + "当你于回合外需要使用或打出一张基本牌或普通锦囊牌时,若你没有手牌,则你可摸一张牌,然后视为使用或打出此牌。", + twshanghe: "觞贺", + twshanghe_info: + "限定技。当你进入濒死状态时,你可令所有其他角色依次交给你一张牌;若这些牌中没有【酒】,则你将体力回复至1点。", + tw_wujing: "TW吴景", + tw_wujing_prefix: "TW", + twfenghan: "锋捍", + twfenghan_info: + "每回合限一次。当你使用【杀】或伤害类锦囊牌指定第一个目标后,你可令至多X名角色各摸一张牌(X为此牌的目标数)。", + twcongji: "从击", + twcongji_info: "当你的红色牌于回合外因弃置而进入弃牌堆后,你可令一名其他角色获得这些牌。", + old_quancong: "TW全琮", + old_quancong_prefix: "TW", + zhenshan: "振赡", + zhenshan_info: + "每回合限一次,当你需要使用或打出一张基本牌时,你可以与一名手牌数少于你的角色交换手牌,视为使用或打出此牌。", + tw_tianyu: "TW田豫", + tw_tianyu_prefix: "TW", + gz_tw_tianyu: "田豫", + twzhenxi: "震袭", + twzhenxi_info: + "每回合限一次。当你使用【杀】指定目标后,你可选择一项:⒈弃置其X张手牌(X为你至其的距离);⒉将其装备区或判定区内的一张牌移动到另一名角色的装备区或判定区内。若其体力值大于你或其体力值为全场最高,则你可以改为依次执行以上两项。", + twyangshi: "扬师", + twyangshi_info: + "锁定技。当你受到伤害后,若场上有不在你攻击范围内的其他角色,则你令攻击范围+1;若没有,则你从牌堆中获得一张【杀】。", + tw_puyangxing: "濮阳兴", + twzhengjian: "征建", + twzhengjian_info: + "游戏开始时,你可选择获得一项效果:⒈其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。⒉其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。", + twzhongchi: "众斥", + twzhongchi_info: + "锁定技,限定技。当你因〖征建〗而得到牌后,若已经有至少X名角色因〖征建〗而交给你过牌(X为游戏人数的一半且向上取整),则你回复2点体力,且于本局游戏内受到渠道为【杀】的伤害+1,且你将〖征建〗中的“其须交给你一张牌”改为“你可对其造成1点伤害”。", + tw_bingyuan: "邴原", + twbingde: "秉德", + twbingde_info: + "出牌阶段限一次。你可以选择一个本阶段未选择过的花色并弃置一张牌,你摸等同于本阶段你使用此花色的牌数,然后若你以此法弃置的牌的花色与你选择的花色相同,你令你〖秉德〗于此阶段发动的次数上限+1。", + twqingtao: "清滔", + twqingtao_info: + "①摸牌阶段结束时,你可以重铸一张牌。若此牌为【酒】或非基本牌,你摸一张牌。②结束阶段,若你本回合未发动〖清滔①〗,你可以发动〖清滔①〗。", + tw_jiangji: "TW蒋济", + tw_jiangji_prefix: "TW", + twjichou: "急筹", + twjichou_info: + "①每回合限一次。你可以视为使用一张未被〖急筹①〗记录过的普通锦囊牌并记录此牌。②你无法响应或{使用对应实体牌包含你的手牌的}〖急筹①〗记录过的锦囊牌。③出牌阶段限一次。你可将手牌中的一张〖急筹①〗记录过的锦囊牌交给其他角色。", + twjilun: "机论", + twjilun_info: + "当你受到伤害后,你可以摸X张牌(X为〖急筹①〗记录数且至少为1,至多为5),或视为使用一张〖急筹①〗记录过且未被〖机论〗记录过的普通锦囊牌并记录此牌。", + tw_niufudongxie: "牛辅董翓", + baonvezhi_faq: "关于暴虐值", + baonvezhi_faq_info: "
            • 当你造成或受到伤害后,你获得等量的暴虐值;
            • 暴虐值的上限为5。", + twjuntun: "军屯", + twjuntun_info: + "①游戏开始时或当其他角色死亡后,你可令一名角色获得〖凶军〗。②当其他角色造成伤害后,若其拥有〖凶军〗,你获得等同于此次伤害值的暴虐值。", + twxiongxi: "凶袭", + twxiongxi_info: + "出牌阶段限一次。你可以弃置X张牌对一名其他角色造成1点伤害(X为你的暴虐值与暴虐值上限之差)。", + twxiafeng: "黠凤", + twxiafeng_info: + "出牌阶段开始时,你可消耗至多3点暴虐值并获得如下效果直到回合结束:你使用的前X张牌没有距离和次数限制且不可被响应,你的手牌上限+X(X为你以此法消耗的暴虐值)。", + tw_bn_1: "一点", + tw_bn_2: "两点", + tw_bn_3: "三点", + tw_bn_1_bg: "一", + tw_bn_2_bg: "二", + tw_bn_3_bg: "三", + twxiongjun: "凶军", + twxiongjun_info: "锁定技,每回合限一次。当你造成伤害后,所有拥有〖凶军〗的角色摸一张牌。", + tw_jianshuo: "蹇硕", + twkunsi: "困兕", + twkunsi_info: + "出牌阶段,你可以视为对一名未以此法选择过的其他角色使用一张【杀】。若此【杀】未造成伤害,其获得〖令戮〗直到你下回合开始,且当你成为其〖令戮〗的目标后,其可令你于〖令戮〗失败时进行两次结算。", + twlinglu: "令戮", + twlinglu_info: + "强令:①任务:执行角色于其下回合结束前造成的伤害不小于2点。②成功:其摸两张牌。③失败:其失去1点体力。", + tw_mateng: "TW马腾", + tw_mateng_prefix: "TW", + twxiongzheng: "雄争", + twxiongzheng_info: + "一轮游戏开始时,①若你上一轮发动过〖雄争〗且选择过“雄争”角色,你可以选择一项:1.视为对任意名上一轮内未对“雄争”角色造成过伤害的角色依次使用一张【杀】;2.令任意名上一轮对“雄争”角色造成过伤害的角色摸两张牌。②你可以选择一名未以此法选择过的角色,称为“雄争”角色。", + twluannian: "乱年", + twluannian_info: + "主公技。其他群势力角色的出牌阶段限一次。其可以弃置X张牌并对“雄争”角色造成1点伤害(X为所有角色于本轮发动〖乱年〗的次数+1)。", + tw_baoxin: "TW鲍信", + tw_baoxin_prefix: "TW", + twmutao: "募讨", + twmutao_info: + "出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】依次交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。", + twyimou: "毅谋", + twyimou_info: + "当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色并摸两张牌;3.背水:将所有手牌交给其(若受伤角色为你则跳过此步骤),然后依次执行上述所有选项。", + tw_liufuren: "刘夫人", + twzhuidu: "追妒", + twzhuidu_info: + "出牌阶段限一次。你可以选择一名已受伤的其他角色并选择一项:1.对其造成1点伤害;2.弃置其装备区里的一张牌;3.背水:若该角色为女性,弃置一张牌,然后依次执行上述所有选项。", + twshigong: "示恭", + twshigong_info: + "限定技。当你于回合外进入濒死状态时,你可以令当前回合角色选择一项:1.加1点体力上限并回复1点体力,摸一张牌,然后令你将体力回复至体力上限;2.弃置X张手牌,然后令你将体力回复至1点(X为其体力值)。", + tw_wangling: "TW王淩", + tw_wangling_prefix: "TW", + twmibei: "秘备", + twmibei_info: + "使命技。①使命:使用每种类型且牌名不同的牌各两张。②成功:当你使用牌后,若你于本次事件完成了〖秘备①〗的使命,你获得〖谋立〗。③失败:出牌阶段结束时,若你本回合未使用过牌,你本回合手牌上限-1并重置〖秘备〗。", + twxingqi: "星启", + twxingqi_info: + "觉醒技。准备阶段,若场上的牌数大于你的体力值,你回复1点体力,然后若〖秘备〗:未完成,你从牌堆中获得每种类型的牌各一张;已完成,本局游戏你使用牌无距离限制。", + twmouli: "谋立", + twmouli_backup: "谋立", + twmouli_info: "每回合限一次。你可以使用牌堆中的一张基本牌。", + tw_zhugeguo: "TW诸葛果", + tw_zhugeguo_prefix: "TW", + twqirang: "祈禳", + twqirang_info: + "当有装备牌进入你的装备区时,你可以从牌堆中获得一张锦囊牌,你本阶段使用此牌无距离限制且不可被响应,且当你使用此牌时,你可以为这张牌增加或减少一个目标。", + twyuhua: "羽化", + twyuhua_info: + "锁定技。①你的非基本牌不计入手牌上限。②当你于回合外失去牌后,若其中有非基本牌,你可以卜算X,然后你可以摸X张牌(X为其中非基本牌数且至多为5)。", + tw_fanchou: "TW樊稠", + tw_fanchou_prefix: "TW", + twxingluan: "兴乱", + twxingluan_info: + "结束阶段,你可以亮出牌堆顶的六张牌,然后你可以选择一种类型的牌并分配给任意角色(每名角色至多三张)。然后所有以此法得到过牌且得到的牌数不少于你的角色失去1点体力。", + tw_xujing: "TW许靖", + tw_xujing_prefix: "TW", + twboming: "博名", + twboming_info: + "①出牌阶段限两次。你可以将一张牌交给一名其他角色。②结束阶段,若所有其他角色于此回合得到的牌数之和大于1,你摸两张牌。", + twejian: "恶荐", + twejian_info: + "当其他角色得到你的牌后,若其有其他与此牌类型相同的牌,你可以令其选择一项:1.受到你造成的1点伤害;2.弃置这些牌。", + tw_zhangfei: "TW张飞", + tw_zhangfei_prefix: "TW", + twxuhe: "虚吓", + twxuhe_info: + "当你使用的【杀】被【闪】抵消时,你可以令其选择一项:1.受到你造成的1点伤害;2.本回合你使用的下一张牌对其造成伤害时,此伤害+2。", + tw_xuezong: "TW薛综", + tw_xuezong_prefix: "TW", + twjiexun: "诫训", + twjiexun_info: + "结束阶段,你可以选择一个花色并令一名其他角色摸等同于场上此花色牌数张牌,然后其弃置X张牌。若其以此法弃置了所有牌,你选择一项:1.摸X张牌,然后将X归零;2.修改〖复难〗和〖诫训〗(X为此前〖诫训〗的发动次数)。", + twfunanx: "复难·改", + twjiexunx: "诫训·改", + twfunanx_info: "当其他角色使用或打出牌响应你使用的牌时,你可获得其使用或打出的牌。", + twjiexunx_info: + "结束阶段,你可选择一个花色并令一名其他角色摸等同于场上此花色牌数张牌,然后其弃置X张牌(X为此前〖诫训〗的发动次数)。", + tw_zhangning: "TW张宁", + tw_zhangning_prefix: "TW", + twxingzhui: "星坠", + twxingzhui_info: + "出牌阶段限一次。你可以失去1点体力并施法:亮出牌堆顶2X张牌,若其中有黑色牌,则你可令一名其他角色获得这些黑色牌。若黑色牌的数量不小于X,则你对其造成X点雷电伤害。", + twjuchen: "聚尘", + twjuchen_info: + "结束阶段,若你的手牌数和体力值均不为全场最多,则你可以令所有角色弃置一张牌,然后你获得其中的红色牌。", + tw_yufuluo: "于夫罗", + twjiekuang: "竭匡", + twjiekuang_info: + "每回合限一次。当一名体力值小于你的角色成为其他角色使用基本牌或普通锦囊牌的唯一目标后,若没有角色处于濒死状态,你可以失去1点体力或减1点体力上限,将此牌的目标转移给你。然后此牌结算结束后,若此牌未造成伤害且此牌的使用者是你使用此牌名的牌的合法目标,你视为对此牌的使用者使用一张同名牌。", + twneirao: "内扰", + twneirao_info: + "觉醒技。准备阶段,若你的体力值与体力上限之和不大于9,你失去〖竭匡〗,弃置所有牌并从牌堆或弃牌堆中获得等量的【杀】,然后获得〖乱掠〗。", + twluanlve: "乱掠", + twluanlve_info: + "①出牌阶段,你可以将X张【杀】当做【顺手牵羊】对一名本阶段未成为过【顺手牵羊】的目标的角色使用(X为你以此法使用【顺手牵羊】的次数)。②当你使用牌时,若此牌为【顺手牵羊】,你令此牌不能被响应。", + tw_fengxí: "冯习", + twqingkou: "轻寇", + twqingkou_info: + "准备阶段,你可以视为对一名其他角色使用一张【决斗】。然后此牌的伤害来源摸一张牌,若伤害来源包括你,你跳过本回合的判定阶段和弃牌阶段。", + tw_zhangji: "张既", + twdingzhen: "定镇", //丁真 + twdingzhen_info: + "一轮游戏开始时,你可以选择任意名你至其距离不大于X的角色(X为你的体力值),这些角色选择一项:1.弃置一张【杀】;2.本轮其于回合内使用的第一张牌不能指定你为目标。", + twyouye: "攸业", + twyouye_info: + "锁定技。①其他角色的结束阶段,若其本回合未对你造成过伤害且“蓄”数小于5,你将牌堆顶的牌置于武将牌上,称为“蓄”。②当你造成或受到伤害后,若你有“蓄”,你将所有“蓄”分配给任意角色(若当前回合角色存活,则你至少为当前回合角色分配一张)。", + tw_xunchen: "TW荀谌", + tw_xunchen_prefix: "TW", + twweipo: "危迫", + twweipo_info: + "出牌阶段限一次。你可以令一名角色弃置一张牌,然后令其获得一张【兵临城下】或一张由你选择的智囊牌。", + twmouzhi: "谋识", + twmouzhi_info: + "锁定技。当你受到伤害时,若伤害渠道对应的牌和你上次受到的伤害渠道对应的牌颜色相同,则你防止此伤害。", + tw_jiangqing: "TW蒋钦", + tw_jiangqing_prefix: "TW", + twshangyi: "尚义", + twshangyi_info: + "出牌阶段限一次。你可以弃置一张牌并选择一名有手牌的其他角色,你令其观看你的手牌,然后你观看其手牌并选择一项:1.弃置其中一张牌;2.与其交换一张手牌。若你以此法弃置了其的黑色牌,或你与其交换的两张牌均为红色,你摸一张牌。", + twxiangyu: "翔羽", + twxiangyu_info: + "锁定技。①你于回合内的攻击范围+X(X为本回合失去过牌的角色数且至多为5)。②当你使用【杀】指定目标后,若你至目标角色的距离小于你的攻击范围,你令此目标角色抵消此【杀】所需使用的【闪】数+1。", + twgyshenxing: "慎行", + twgyshenxing_info: + "出牌阶段,你可以弃置X张牌,然后摸一张牌并获得1枚“慎”标记(X为你的“慎”数且至多为2)。", + tw_guyong: "TW顾雍", + tw_guyong_prefix: "TW", + twbingyi: "秉壹", + twbingyi_info: + "结束阶段,你可以展示所有手牌,若这些牌的颜色均相同或类别均相同,你可以令至多Y名角色各摸一张牌(Y为你的手牌数)。若你以此法展示的牌数大于1且这些牌的颜色均相同且类别均相同,你移去所有“慎”。", + twyilie: "毅烈", + twyilie_info: + "出牌阶段开始时,你可以选择一项:1.本阶段内使用【杀】的次数上限+1;2.本回合内使用【杀】指定处于连环状态的目标后,或使用【杀】被【闪】抵消时,摸一张牌;3.背水:失去1点体力,然后依次执行上述所有选项。", + tw_chendong: "TW陈武董袭", + tw_chendong_prefix: "TW", + twfenming: "奋命", + twfenming_info: + "准备阶段,你可以选择一名其他角色并选择一项:1.令其弃置一张牌;2.令其横置;3.背水:横置,然后依次执行上述所有选项。", + tw_handang: "TW韩当", + tw_handang_prefix: "TW", + twgongji: "弓骑", + twgongji2: "弓骑", + twgongji_info: + "①你的攻击范围无限。②出牌阶段限一次,你可以弃置一张牌,然后你使用与此牌花色相同的【杀】无任何次数限制直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。", + twjiefan: "解烦", + twjiefan_info: + "限定技。出牌阶段,你可以选择一名角色,令攻击范围内含有其的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。然后当其第一次进入濒死状态后,你重置〖解烦〗。", + tw_jiling: "TW纪灵", + tw_jiling_prefix: "TW", + twshuangren: "双刃", + twshuangren_info: + "①出牌阶段开始时,你可以与一名角色拼点。若你:赢,你可以视为对至多两名至其的距离不大于1的角色依次使用一张【杀】;没赢,其可以视为对你使用一张【杀】。②出牌阶段结束时,若你本回合未发动过〖双刃①〗且未造成过渠道为【杀】的伤害,你可以弃置一张牌发动〖双刃①〗。", + tw_re_fazheng: "TW法正", + tw_re_fazheng_prefix: "TW", + twxuanhuo: "眩惑", + twxuanhuo_info: + "摸牌阶段结束时,你可以交给一名其他角色两张牌,然后其选择一项:1.视为对你选择的另一名其他角色使用一张【杀】或【决斗】,2.令你获得其两张牌。", + twenyuan: "恩怨", + twenyuan1: "恩怨", + twenyuan2: "恩怨", + twenyuan_info: + "①当你获得一名其他角色的至少两张牌后,你可以令其摸一张牌,若其手牌区或装备区没有牌,则你可以改为令其回复1点体力。②当你受到1点伤害后,你可令伤害来源选择一项:1.失去1点体力;2.交给你一张手牌,若此牌的花色不为♥,你摸一张牌。", + tw_madai: "TW马岱", + tw_madai_prefix: "TW", + twqianxi: "潜袭", + twqianxi2: "潜袭", + twqianxi3: "潜袭", + twqianxi2_bg: "潜", + twqianxi3_bg: "袭", + twqianxi_info: + "准备阶段,你可以摸一张牌并弃置一张牌,令一名距离为1的角色本回合不能使用或打出与你弃置的牌颜色相同的手牌。然后本回合的结束阶段,若你本回合对其造成过渠道为【杀】的伤害,你令其不能使用或打出与你以此法弃置的牌颜色不同的牌直到其下回合结束。", + tw_niujin: "TW牛金", + tw_niujin_prefix: "TW", + twcuorui: "挫锐", + twcuorui_info: + "限定技。准备阶段,你可以将手牌摸至X张(X为场上角色手牌数最多的角色的手牌数,且至多摸5张)。然后若你的判定区:未废除,你废除判定区;已废除,你可以对一名其他角色造成1点伤害。", + twliewei: "裂围", + twliewei_info: + "锁定技。当你杀死一名角色后,你选择一项:1.摸两张牌;2.若你拥有〖挫锐〗且〖挫锐〗已发动过,重置〖挫锐〗。", + tw_guanqiujian: "TW毌丘俭", + tw_guanqiujian_prefix: "TW", + twzhengrong: "征荣", + twzhengrong_tag: "荣", + twzhengrong_info: + "当你于出牌阶段使用牌结算结束后,若此牌为你于本局游戏你的出牌阶段内使用的第偶数张指定了其他角色为目标的牌,或你于出牌阶段第一次造成伤害后,你可以将一名其他角色的一张牌置于你的武将牌上,称为“荣”。", + twhongju: "鸿举", + twhongju_info: + "觉醒技。准备阶段,若你的“荣”数不小于3,你摸等同于“荣”数的牌,且可以用任意手牌交换等量的“荣”,获得〖清侧〗,然后可以减1点体力上限并获得〖扫讨〗。", + twqingce: "清侧", + twqingce_backup: "清侧", + twqingce_info: + "出牌阶段,你可以将一张“荣”置入弃牌堆并选择一名区域内有牌的角色,你弃置其区域里的一张牌。", + twsaotao: "扫讨", + twsaotao_info: "锁定技。你使用【杀】和普通锦囊牌不能被响应。", + tw_daxiaoqiao: "TW大乔小乔", + tw_daxiaoqiao_prefix: "TW", + twxingwu: "星舞", + twxingwu_info: + "弃牌阶段开始时,你可以将一张牌置于武将牌上,称为“星舞”。然后你可移去三张“星舞”,弃置一名其他角色装备区里的所有牌,然后对其造成2点伤害(若其性别包含女性则改为1点伤害)。", + twpingting: "娉婷", + twpingting_info: + "锁定技。①一轮游戏开始时或其他角色于你的回合内进入濒死状态时,你摸一张牌并将一张牌置于武将牌上,称为“星舞”。②若你有“星舞”,你视为拥有〖天香〗和〖流离〗。", + tw_furong: "TW傅肜", + tw_furong_prefix: "TW", + twxuewei: "血卫", + twxuewei_info: + "每轮限一次。一名其他角色A的出牌阶段开始时,你可以选择另一名其他角色B,然后你令A选择一项:1.本回合不能对B使用【杀】且手牌上限-2;2.你视为对A使用一张【决斗】。", + twliechi: "烈斥", + twliechi_info: + "当你受到伤害后,若伤害来源的体力值不小于你,你可以选择一项:1.令其将手牌数弃置至与你的手牌数相同;2.弃置其一张牌;3.背水:若你本回合进入过濒死状态,弃置一张装备牌,然后依次执行上述所有选项。", + tw_yl_luzhi: "TW卢植", + tw_yl_luzhi_prefix: "TW", + twmingren: "明任", + twmingren_info: + "①游戏开始时,你摸一张牌,然后将一张手牌置于武将牌上,称为“任”。②出牌阶段开始时或出牌阶段结束时,你可以用一张牌替换“任”。", + twzhenliang: "贞良", + twzhenliang_info: + "转换技。阴:出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。阳:当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同,你摸一张牌。", + tw_zhangnan: "张南", + twfenwu: "奋武", + twfenwu_info: + "结束阶段,你可以失去1点体力并视为使用一张无距离限制的【杀】。若本回合你使用过的基本牌种数大于1,此【杀】伤害基数+1。", + tw_huchuquan: "呼厨泉", + twfupan: "复叛", + twfupan_info: + "当你造成或受到伤害后,你可以摸X张牌并将一张牌交给一名其他角色(X为伤害值)。若你此前:未以此法交给过该角色牌,你摸两张牌;以此法交给过该角色牌,你可{对其造成1点伤害,然后你不能再以此法交给其牌}。", + tw_liuzhang: "TW刘璋", + tw_liuzhang_prefix: "TW", + twyaohu: "邀虎", + twyaohu_info: + "每轮限一次。回合开始时,你须选择场上的一个势力。该势力的角色的出牌阶段开始时,其获得你的一张“生”,然后其须选择一项:1.对你指定的另一名的其他角色使用一张【杀】(无距离限制);2.本回合其使用伤害牌指定你为目标时须交给你两张牌,否则取消此目标。", + tw_liwei: "TW李遗", + tw_liwei_prefix: "TW", + twjiaohua: "教化", + twjiaohua_info: + "当你或体力值最小的其他角色因摸牌而得到牌后,你可以令该角色从牌堆或弃牌堆中获得一张本次未获得的类别的牌(每种类别每回合限一次)。", + tw_yanxiang: "TW阎象", + tw_yanxiang_prefix: "TW", + twkujian: "苦谏", + twkujianx: "谏", + twkujian_info: + "出牌阶段限一次。你可以将至多三张手牌交给一名其他角色,称为“谏”,你获得以下效果:当其他角色使用或打出牌后,若其中有“谏”,你与其各摸一张牌;当其他角色不因使用或打出而失去牌后,若其中有“谏”,你与其各弃置一张牌。", + twruilian: "睿敛", + twruilian2: "睿敛", + twruilian_info: + "一轮游戏开始时,你可以选择一名角色。其下回合结束时,若其本回合弃置过至少两张牌,你可以选择其本回合弃置过的一种类别,你与其各从弃牌堆中获得一张此类别的牌。", + tw_xiahouen: "夏侯恩", + twfujian: "负剑", + twfujian_info: + "锁定技。①游戏开始时或准备阶段,若你的装备区里没有武器牌,你随机将牌堆中的一张武器牌置入装备区。②当你于回合外失去武器牌后,你失去1点体力。", + twjianwei: "剑威", + twjianwei_info: + "①若你的装备区里有武器牌,你使用【杀】无视防具且拼点牌点数+X(X为你的攻击范围)。②{其他角色的准备阶段,其可以与你拼点}/{准备阶段,你可以与攻击范围内的一名角色拼点}。若你赢,你获得其每个区域内的各一张牌;若其赢,其获得你装备区里的武器牌。", + tw_xiahoushang: "夏侯尚", + twtanfeng: "探锋", + twtanfeng_info: + "准备阶段,你可以弃置一名其他角色区域内的一张牌,然后其选择一项:1.受到你造成的1点火焰伤害,然后令你跳过本回合的一个阶段(准备阶段和结束阶段除外);2.将一张牌当做【杀】对你使用(有距离限制)。", + tw_zongyu: "TW宗预", + tw_zongyu_prefix: "TW", + twzhibian: "直辩", + twzhibian_info: + "出牌阶段开始时,你可以与一名其他角色拼点。若你赢,你可以选择一项:{1.将其区域里的一张牌移动到你的对应区域;2.回复1点体力;3.背水:弃置一张非基本牌,然后依次执行上述所有选项};若你没赢,你失去1点体力。", + twyuyan: "御严", + twyuyan_info: + "锁定技。当你成为体力值大于你的角色使用的【杀】的目标时,你令使用者选择一项:1.交给你一张点数大于此【杀】的牌(若此【杀】无点数则改为非基本牌)。2.取消此目标。", + tw_zhouchu: "TW周处", + tw_zhouchu_prefix: "TW", + twguoyi: "果毅", + twguoyi_info: + "当你不因〖果毅〗使用【杀】或普通锦囊牌指定一名其他角色为目标后,若其体力值或手牌数最大,或你的手牌数不大于X(X为你已损失的体力值+1),你可令其选择一项:1.本回合不能使用或打出手牌;2.弃置X张牌。若条件均满足,或其于本回合两个选项均已选择过,则你于此牌结算结束后依次视为对此牌的所有目标使用一张名称和属性相同的牌。", + twchuhai: "除害", + twchuhai_info: + "使命技。①使命:令至少两名其他角色进入濒死状态。②成功:一名角色的回合结束时,若你于本回合完成了〖除害①〗的使命,你废除判定区,然后每名其他角色依次交给你一张牌。③当你获得其他角色的牌后,你须将其中的一张牌置入弃牌堆。", + tw_qiaogong: "TW桥公", + tw_qiaogong_prefix: "TW", + twyizhu: "遗珠", + twyizhu_info: + "①结束阶段,你摸两张牌,然后将两张牌随机插入牌堆前2X张牌的位置中,称为“遗珠”(X为角色数,选择牌的牌名对其他角色可见)。②当有其他角色使用“遗珠”指定唯一目标时,你可以选择一项:1.增加一个目标;2.取消此目标,增加一个目标。然后移除此牌对应的“遗珠”记录并摸一张牌。", + twluanchou: "鸾俦", + twluanchou_info: "出牌阶段限一次。你可以令两名角色获得〖共患〗直到你下次发动此技能。", + twgonghuan: "共患", + twgonghuan_info: + "每回合限一次。当其他角色受到伤害时,若其拥有〖共患〗且其体力值不大于你,你可以将此伤害转移给你(不触发〖共患〗)。", + tw_qiaorui: "TW桥蕤", + tw_qiaorui_prefix: "TW", + wangxing: "妄行", + twxiawei: "狭威", + twxiawei_info: + "①游戏开始时,你将牌堆中的两张基本牌置于武将牌上,称为“威”。②回合开始时,你将所有“威”置入弃牌堆。③你可以将“威”如手牌般使用或打出。④妄行:准备阶段,你可以将牌堆顶的X+1张牌置于武将牌上,称为“威”。", + twqiongji: "穷技", + twqiongji_info: + "锁定技。①每回合限一次。当你使用或打出“威”后,你摸一张牌。②当你受到伤害时,若你没有“威”,此伤害+1。", + tw_bianfuren: "TW卞夫人", + tw_bianfuren_prefix: "TW", + twwanwei: "挽危", + twwanwei_info: + "每回合限一次。当一名体力值最小的角色受到伤害时:若该角色不为你,你可以防止此伤害,然后失去1点体力;若该角色为你,或你的体力上限最大,你可以于当前回合的结束阶段获得牌堆顶的牌并亮出牌堆底的牌,若展示的牌能被使用,你使用之。", + twyuejian: "约俭", + twyuejian_info: + "出牌阶段限一次。你可以将X张牌置于牌堆顶或牌堆底(X为你的手牌数减你的手牌上限且至少为1)。若你以此法失去的牌数:不小于3,你的体力上限+1;不小于2,你回复1点体力;不小于1,你的手牌上限+1。", + tw_chenzhen: "TW陈震", + tw_chenzhen_prefix: "TW", + twmuyue: "睦约", + twmuyue_info: + "出牌阶段限一次。你可以弃置一张牌并选择一个基本牌或普通锦囊牌的牌名,然后令一名角色从牌堆中获得一张此牌名的牌。若你以此法弃置的牌的牌名与你选择的牌名相同,你下次发动〖睦约〗无需弃牌。", + twchayi: "察异", + twchayi_info: + "结束阶段,你可以选择一名其他角色,令其选择一项:1.展示所有手牌;2.下次使用牌时弃置一张牌。该角色的下个回合结束时,若其手牌数与其上一次成为〖察异〗目标后的手牌数不相同,其执行另一项。", + tw_feiyi: "TW费祎", + tw_feiyi_prefix: "TW", + twshengxi: "生息", + twshengxi_info: + "①准备阶段,你可以获得一张【调剂盐梅】。②结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊并摸一张牌。", + twkuanji: "宽济", + twkuanji_info: + "每回合限一次。当你的牌不因使用而进入弃牌堆后,你可以令一名其他角色获得其中的一张牌。", + xia_wangyue: "王越", + twyulong: "驭龙", + twyulong_info: + "当你使用【杀】指定第一个目标后,你可以与一名目标角色拼点。若你赢,且你此次的拼点牌为:黑色,此【杀】伤害+1;红色,此【杀】不可被响应。当此【杀】造成伤害后,若你赢,你令此【杀】不计入次数。", + twjianming: "剑鸣", + twjianming_info: "锁定技。每回合每种花色限一次,当你使用或打出【杀】时,你摸一张牌。", + xia_liyàn: "李彦", + twzhenhu: "震虎", + twzhenhu_info: + "当你使用伤害牌指定第一个目标时,你可以摸一张牌并与至多三名其他角色共同拼点。若你赢,此牌对所有本次拼点没赢的角色造成的伤害+1;若你没赢,你失去1点体力。", + twlvren: "履刃", + twlvren_info: + "①当你对其他角色造成伤害时,你令其获得1枚“刃”标记。②当你使用伤害牌时,你可以额外指定一名有“刃”的角色并移去其所有“刃”。③你的拼点牌点数+2X(X为参与此次拼点的角色数)。", + xia_tongyuan: "侠童渊", + xia_tongyuan_prefix: "侠", + twchaofeng: "朝凤", + twchaofeng_backup: "朝凤", + twchaofeng_info: + "①你可以将一张【杀】当做【闪】、【闪】当做任意一种【杀】使用或打出。②出牌阶段开始时,你可以与至多三名角色共同拼点。赢的角色视为对所有没赢的角色使用一张火【杀】。", + twchuanshu: "传术", + twchuanshu_info: + "限定技。准备阶段,你可以选择一名角色。直到你的下回合开始,其获得以下效果:1.当其拼点牌亮出时,此牌点数+3;2.其使用的下一张【杀】对除你外的角色造成伤害时,此伤害+1;3.若其不为你,其使用的下一张【杀】结算结束后,你摸等同于其因此【杀】造成的伤害值数的牌。", + xia_xushu: "侠徐庶", + xia_xushu_prefix: "侠", + twjiange: "剑歌", + twjiange_info: + "每回合限一次。你可以将一张非基本牌当做【杀】使用或打出(无距离和次数限制,且不计入次数)。若此时不为你的回合,你摸一张牌。", + twxiawang: "侠望", + twxiawang_info: + "当一名角色受到伤害后,若你至其的距离不大于1,你可以对伤害来源使用一张【杀】。当此【杀】结算结束后,若你造成过渠道为此牌的伤害,结束当前阶段。", + tw_haomeng: "TW郝萌", + tw_haomeng_prefix: "TW", + twgongge: "攻阁", + twgongge_info: + "摧坚:你可以选择一项:1.摸X+1张牌。其响应此牌后,跳过你的下一个摸牌阶段;2.弃置其X+1张牌。此牌结算结束后,若其体力值不小于你,你交给其X张牌;3.此牌对其造成的伤害+X。此牌结算结束后,其回复X点体力。", + tw_weixu: "魏续", + twsuizheng: "随征", + twsuizheng_info: + "锁定技。游戏开始时,你选择一名其他角色,称为“随征”角色。你获得以下效果:当“随征”角色造成伤害后,你摸一张牌;当“随征”角色受到伤害后,你选择一项:1.失去1点体力,令其从牌堆或弃牌堆中获得一张【杀】或【决斗】;2.弃置两张基本牌,令其回复1点体力。", + twtuidao: "颓盗", + twtuidao_info: + "限定技。准备阶段,若“随征”角色的体力值不大于2或“随征”角色已死亡,你可以废除你与其的一个坐骑栏并选择一个类别,然后若“随征”角色存活,你获得其所有此类别的牌,否则你从牌堆中获得两张此类别的牌。然后你将“随征”角色改为另一名角色。", + tw_caoxiu: "TW曹休", + tw_caoxiu_prefix: "TW", + twqianju: "千驹", + twqianju_info: + "锁定技。①你计算与其他角色的距离-X(X为你装备区的牌数)。②每回合限一次。当你对距离为1以内的角色造成伤害后,若你的装备区存在空置装备栏,你从牌堆或弃牌堆中将一张你空置装备栏对应副类别的装备牌置于你的装备区。", + twqingxi: "倾袭", + twqingxi_info: + "当你使用张【杀】指定目标后,若此牌为你于本回合使用的第一张【杀】,你可以令目标角色选择一项:1.令你摸Y张牌,此【杀】不可被其响应(Y为你装备区的牌数且至少为1);2.若其装备区里有牌,弃置装备区里的所有牌,然后弃置你装备区里的等量张牌,令此【杀】对其造成的伤害+1。", + tw_sunyi: "TW孙翊", + tw_sunyi_prefix: "TW", + twzaoli: "躁厉", + twzaoli_info: + "锁定技。①出牌阶段,你只能使用或打出你本回合得到的手牌。②出牌阶段开始时,你须弃置你区域内的所有装备牌并弃置任意张非装备手牌,你摸等量的牌,从牌堆中将你此次弃置的装备牌对应副类别的装备牌置入装备区。若你以此法置入了超过两张装备牌,你失去1点体力。", + tw_yangyi: "TW杨仪", + tw_yangyi_prefix: "TW", + twgongsun: "共损", + twgongsun_shadow: "共损", + twgongsun_info: + "锁定技。出牌阶段开始时,你选择攻击范围内的一名其他角色并选择一种花色,直至你的下个回合开始前或你死亡时,你与其均无法使用、打出或弃置该花色的手牌。", + tw_dengzhi: "TW邓芝", + tw_dengzhi_prefix: "TW", + twjimeng: "急盟", + twjimeng_info: + "出牌阶段限一次。你可以获得一名其他角色区域内的一张牌,然后交给其一张牌。若其体力值不小于你,你摸一张牌。", + xia_lusu: "侠鲁肃", + xia_lusu_prefix: "侠", + twkaizeng: "慨赠", + twkaizeng_info: + "其他角色的出牌阶段限一次。其可以选择一种基本牌的牌名或非基本牌的类型,然后令你选择是否交给其任意张手牌。若你以此法:交给其至少两张牌,你摸一张牌;交给其的牌中包含其选择的牌名或类型的牌,你获得一张与此牌名或类型不同的牌。", + twyangming: "扬名", + twyangming_info: + "出牌阶段结束时,你可以摸X张牌,且令本回合的手牌上限+X(X为你本阶段使用过的牌的类型数)。", + xia_dianwei: "侠典韦", + xia_dianwei_prefix: "侠", + twliexi: "烈袭", + twliexi_info: + "准备阶段,你可以弃置任意张牌并选择一名其他角色。若你以此法弃置的牌数大于其体力值,你对其造成1点伤害;否则其对你造成1点伤害。然后若你弃置的牌中有武器牌,你对其造成1点伤害。", + twshezhong: "慑众", + twshezhong_info: + "结束阶段,若你:本回合对其他角色造成过伤害,你可以令至多X名其他角色下个摸牌阶段的额定摸牌数-1(X为你本回合造成的伤害值);本回合受到过伤害,你可以将手牌摸至与其中一名伤害来源的体力值相同(至多摸至5)。", + xia_zhaoe: "赵娥", + twyanshi: "言誓", + twyanshi_info: + "①游戏开始时,你选择一名其他角色,称为“言誓”角色。②当你或“言誓”角色受到二者之外角色造成的伤害后,伤害来源获得1枚“誓”标记。③你对有“誓”的角色使用牌无距离限制。④当你对有“誓”的角色造成伤害时,此伤害+1,且当你对这些角色造成伤害后,你摸等同于伤害值的牌并移去其所有“誓”。", + twrenchou: "刃仇", + twrenchou_info: + "锁定技。当你或“言誓”角色死亡时,若二者中的另一名角色A存活,A对杀死你或其的角色造成X点伤害(X为A的体力值)。", + xia_xiahouzie: "夏侯紫萼", + twxuechang: "血偿", + twxuechang_info: + "出牌阶段限一次。你可以与一名其他角色拼点。若你:赢,你获得其一张牌,若此牌为装备牌,你视为对其使用一张【杀】;没赢,其对你造成1点伤害,且你下次对其造成的伤害+1。", + twduoren: "夺刃", + twduoren_info: + "①当你杀死角色后,你可以减1点体力上限,然后获得其所有的非主公技和非隐匿技。②当你令其他角色进入濒死状态时,你失去因〖夺刃①〗获得的技能。", + tw_yangang: "严纲", + twzhiqu: "直取", + twzhiqu_info: + "结束阶段,你可以选择一名其他角色并依次使用牌堆顶X张牌中的【杀】。搏击:依次使用牌堆顶X张牌中的锦囊牌(X为你距离不大于1内的角色数,且你或其以外的角色不是你以此法使用牌的合法目标)。", + twxianfeng: "先锋", + twxianfeng_info: + "当你于出牌阶段使用【杀】或伤害类锦囊牌对其他角色造成伤害后,你可以令受伤角色选择一项:1.其摸一张牌,然后直到你下个回合开始时,你至其他角色的距离-1;2.你摸一张牌,然后直到你下个回合开始时,其至你的距离-1。", + tw_gongsunfan: "公孙范", + twhuiyuan: "回援", + twhuiyuan_info: + "当你于出牌阶段使用牌结算结束后,若你未于此阶段获得过此类型的牌,你可以展示一名角色的一张手牌,若此牌与你使用的牌类型相同,你获得此牌,否则你弃置此牌,然后其摸一张牌。游击:对其造成1点伤害。", + twshoushou: "收绶", + twshoushou_info: + "①当你获得其他角色的牌时,若你在任意角色的攻击范围内,其他角色至你的距离+1。②当你造成或受到伤害后,若你不在任意其他角色的攻击范围内,其他角色至你的距离-1。", + twshijun: "师君", + twshijun_info: + "主公技,其他群势力角色出牌阶段限一次,若你没有“米”,其可以摸一张牌,然后将一张牌置于你的武将牌上,称为“米”。", + twjuxiang: "踞襄", + twjuxiang_info: + "主公技,其他群势力角色出牌阶段限一次,其可以选择其装备区的一张牌移动到你的装备区中,若你对应的装备栏已被废除,则改为交给你此装备牌,然后恢复你的对应装备栏。", + tw_ol_sunjian: "TW孙坚", + tw_ol_sunjian_prefix: "TW", + twpolu: "破虏", + twpolu_info: + "主公技,当吴势力角色杀死一名角色或死亡后,你可以令任意名角色各摸X张牌(X为你此前发动过此技能的次数+1)。", + tw_menghuo: "TW孟获", + tw_menghuo_prefix: "TW", + twqiushou: "酋首", + twqiushou_info: + "主公技,锁定技,当一张【南蛮入侵】结算结束后,若此牌造成的伤害大于3点或有角色因此死亡,所有蜀势力和群势力角色各摸一张牌。", + twzhuiting: "坠廷", + twzhuiting_info: + "主公技,当一张锦囊牌即将对你生效时,其他魏势力角色和群势力角色可将一张与此牌颜色相同的牌当作【无懈可击】使用。", + twniju: "逆拒", + twniju_info: + "主公技。当你的拼点牌亮出后,你可以令本次拼点事件中的一张拼点牌的点数+X或-X。然后当本次拼点事件结束后,若有两张拼点牌的点数相等,你摸X张牌(X为场上群势力角色数)。", + ol_liuyu: "TW刘虞", + ol_liuyu_prefix: "TW", + twchongwang: "崇望", + twchongwang_info: + "主公技,其他群势力角色的出牌阶段开始时,其可以交给你一张牌,然后你与其使用【杀】或伤害性锦囊牌指定目标时不能指定对方为目标直至你的下回合结束(每名角色限发动一次)。", + tw_zhangzhao: "张昭", + twlijian: "力荐", + twlijian_info: + "昂扬技。其他角色的弃牌阶段结束时,你可以令其获得任意本阶段进入弃牌堆的牌(可不选),然后你获得其余的牌,若其得到的牌数大于你,你可以对其造成1点伤害。
              激昂:八张牌进入弃牌堆。", + twchungang: "纯刚", + twchungang_info: "锁定技。一名其他角色于摸牌阶段外得到超过一张牌时,你令其弃置一张牌。", + tw_zhanghong: "张纮", + twquanqian: "劝迁", + twquanqian_info: + "昂扬技。出牌阶段限一次,你可以将至多四张花色各不相同的手牌交给一名其他角色,然后若你交出的牌数大于1,则你从牌堆中获得一张装备牌,然后选择一项:①将手牌数摸至与其相同;②观看其手牌并获得其一种花色的所有牌。
              激昂:你弃置六张手牌。", + twrouke: "柔克", + twrouke_info: "锁定技。当你于摸牌阶段外得到超过一张牌时,你摸一张牌。", + kaisa: "凯撒", + zhengfu: "征服", + zhengfu_info: + "当你使用【杀】指定目标时,你可以选择一种牌的类别,然后除非目标角色交给你一种该类别的牌,否则其不能闪避此【杀】。", + xia_xiahoudun: "侠夏侯惇", + xia_xiahoudun_prefix: "侠", + twdanlie: "胆烈", + twdanlie_info: + "①出牌阶段限一次。你可以与至多三名其他角色共同拼点。若你赢,你对没赢的角色依次造成1点伤害;若你没赢,你失去1点体力。②你的拼点牌点数+X(X为你已损失的体力值)。", + xia_zhangwei: "张葳", + twhuzhong: "护众", + twhuzhong_info: + "当你于出牌阶段使用无属性【杀】指定唯一目标角色时,你可以摸一张牌并选择一项:①为此牌额外选择一个目标;②弃置其一张手牌,此牌结算完毕后,若此牌造成过伤害,则你摸一张牌且本阶段可以额外使用一张【杀】。", + twfenwang: "焚亡", + twfenwang_info: + "锁定技。①当你受到属性伤害时,你须弃置一张牌或令此伤害+1。②当你对其他角色造成非属性伤害时,若你的手牌数大于等于其,则此伤害+1。", + xia_xiahousone: "夏侯子萼", + twchengxi: "承袭", + twchengxi_info: + "出牌阶段每名角色限一次,你可以摸一张牌并与一名其他角色拼点。若你赢,你使用的下一张基本牌或非延时锦囊牌结算完毕后,你视为对原目标使用一张无次数限制的同名牌;若你没赢,其视为对你使用一张无距离限制的【杀】。", + xia_liubei: "侠刘备", + xia_liubei_prefix: "侠", + twshenyi: "伸义", + twshenyi_info: + "每回合限一次,当你或你攻击范围内的一名角色于一回合内首次受到伤害后,你可以声明一种基本牌或锦囊牌(每种牌名限一次),然后从牌堆中将一张同名牌(若没有同名牌则改为同类型的牌)称为“侠义”置于武将牌上。若受伤角色不为你,则你可以将任意张手牌交给其,且当其失去一张你以此法交给其的牌后,你摸一张牌。", + twxinghan: "兴汉", + twxinghan_info: + "①你的回合外或你处于濒死状态时,你可以如手牌般使用或打出“侠义”牌。②准备阶段,若“侠义”牌数大于存活角色数,则你可以依次使用其中所有可以使用的牌。然后你获得如下效果:回合结束时,你弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)。", + twxinghan_tag: "侠义", + xia_guanyu: "侠关羽", + xia_guanyu_prefix: "侠", + twzhongyi: "忠义", + twzhongyi_info: + "锁定技。①你使用【杀】无距离限制。②当你使用【杀】结算完毕后,你选择一项:⒈摸X张牌;⒉回复X点体力;⒊背水:失去Y点体力,依次执行以上两项(X为受到此牌造成的伤害的角色数,Y为你本局游戏选择此项的次数)。", + twchue: "除恶", + twchue_info: + "①当你使用【杀】指定唯一目标时,若场上存在可称为此【杀】目标的非目标角色,则你可以失去1点体力,为此牌额外指定Z个目标。②当你受到伤害或失去体力后,你摸一张牌并获得1个“勇”标记。③回合结束时,若你的“勇”标记数大于等于Z,则你可以失去Z个“勇”标记,视为使用一张伤害+1且可以额外指定Z个目标的【杀】。(Z为你的体力值)", + xia_shitao: "石韬", + twjieqiu: "劫囚", + twjieqiu_info: + "出牌阶段限一次,你可以选择一名装备区没有废除栏的其他角色,废除其所有装备栏,然后其摸X张牌(X为其废除装备栏前的装备区牌数),直到其恢复所有装备栏前:其弃牌阶段结束时,其恢复等同于其弃置牌数的装备栏;其回合结束时,若其仍有已废除的装备栏,则你执行一个额外回合(每轮限一次)。", + twenchou: "恩仇", + twenchou_info: + "出牌阶段限一次,你可以观看一名存在废除装备栏的其他角色的手牌并获得其中一张牌,然后你恢复其一个装备栏。", + xia_shie: "史阿", + twdengjian: "登剑", + twdengjianx: "剑法", + twdengjian_info: + "①其他角色的弃牌阶段结束时,你可以随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】,称为“剑法”。②你使用“剑法”牌不计入次数限制。", + twxinshou: "心授", + twxinshou_info: + "①当你于出牌阶段使用【杀】时,若此【杀】与你本回合使用的所有其他【杀】的颜色均不相同,则你可以选择执行以下一项本回合未执行过的项:⒈摸一张牌;⒉交给一名其他角色一张牌。②当你使用【杀】时,若〖心授①〗的两项本回合均已被你选择过,则你可以令〖登剑①〗失效并令一名其他角色获得〖登剑〗,你的下个回合开始时,其失去〖登剑〗,若其这期间使用【杀】造成过伤害,则你结束〖登剑①〗的失效状态。", + xia_yuzhenzi: "玉真子", + twhuajing: "化境", + twhuajing_info: + "①游戏开始时,你获得6个效果各不相同的无效果“武”标记。②一名拥有“武”标记的角色的攻击范围+X(X为其拥有的“武”标记数)。③出牌阶段限一次,你可以展示至多四张手牌,然后根据这些牌含有的花色数于本回合获得等量你拥有的“武”标记的效果。④拥有“武”标记效果的角色的武器牌失效(武器牌不提供攻击范围且武器技能失效)。", + twhuajing_jian: "剑", + twhuajing_jian_info: "当你使用【杀】指定目标后,你随机弃置目标角色两张牌。", + twhuajing_dao: "刀", + twhuajing_dao_info: "当你使用【杀】对没有手牌的目标角色造成伤害时,此伤害+1。", + twhuajing_fu: "斧", + twhuajing_fu_info: "当你使用的【杀】被【闪】响应后,你对目标角色造成1点伤害。", + twhuajing_qiang: "枪", + twhuajing_qiang_info: "当你使用黑色【杀】结算完毕后,你从牌堆或弃牌堆中获得一张【闪】。", + twhuajing_ji: "戟", + twhuajing_ji_info: "当你使用【杀】造成伤害时,你摸一张牌。", + twhuajing_gong: "弓", + twhuajing_gong_info: "当你使用【杀】造成伤害后,你随机弃置受伤角色装备区里的一张牌。", + twtianshou: "天授", + twtianshou_info: + "锁定技,回合结束时,若你本回合使用【杀】造成过伤害,且你拥有本回合获得过效果的“武”标记,则你须将其中一个“武”标记交给一名其他角色并令其获得此标记的效果直到其回合结束,然后你摸两张牌。", + tw_yanliang: "颜良", + tw_wenchou: "文丑", + tw_yuantan: "袁谭", + twduwang: "独往", + twduwang_info: + "使命技。①出牌阶段开始时,你可以选择至多三名有牌的其他角色,摸X张牌(X为选择角色数+1),然后这些角色依次将一张牌当【决斗】对你使用。②当你处于濒死状态时,其他角色不能对你使用【桃】。③使命:使用【决斗】或成为【决斗】目标的次数之和不小于4(若游戏总人数小于4则改为3)。④成功:准备阶段,若你于你的上回合完成了〖独往③〗的使命,则你重置〖独往〗并将〖独往〗修改至只保留〖独往①〗的效果,选择一项:⒈获得〖狭勇〗;⒉重置〖延势〗并令其获得历战效果。⑤失败:当你死亡时,使命失败。", + twylyanshi: "延势", + twylyanshi_info: "限定技。你可以将一张【杀】当作【决斗】、【兵临城下】或任意智囊牌使用或打出。", + twylyanshix: "延势·改", + twylyanshix_info: + "限定技。你可以将一张【杀】当作【决斗】、【兵临城下】或任意智囊牌使用或打出。历战:重置〖延势〗。", + twjuexing: "绝行", + twjuexing_info: + "出牌阶段限一次。你可以视为对一名其他角色使用一张【决斗】。此牌对一名角色生效时,你与其将所有手牌扣置于武将牌上,然后各摸等同于当前体力值的牌。此牌结算结束后,你与所有目标角色弃置本次以此法摸的牌,然后获得扣置于武将牌上的牌。历战:当你因〖绝行〗摸牌时,摸牌数+1。", + twxiayong: "狭勇", + twxiayong1: "狭勇", + twxiayong2: "狭勇", + twxiayong_info: + "锁定技。当你使用的【决斗】或目标角色包括你的【决斗】造成伤害时,若受伤角色为你,则你随机弃置一张手牌;否则你令此伤害+1。", + twqiaosi: "峭嗣", + twqiaosi_info: + "结束阶段,你可以获得由其他角色区域直接置入或经由处理区置入弃牌堆的所有牌,然后若你以此法获得的牌数小于你的体力值,则你失去1点体力。", + twbaizu: "败族", + twbaizu_info: + "锁定技。结束阶段,若你已受伤且你有手牌,则你须选择X名有手牌的其他角色(X为你的体力值),你与这些角色同时弃置一张手牌,然后你对与你弃置牌类别相同的所有其他角色各造成1点伤害。历战:〖败族〗目标选择数+1。", - tw_mobile:'海外服·稀有专属', - tw_yunchouzhi:'运筹帷幄·智', - tw_yunchouxin:'运筹帷幄·信', - tw_yunchouren:'运筹帷幄·仁', - tw_yunchouyong:'运筹帷幄·勇', - tw_yunchouyan:'运筹帷幄·严', - tw_zhu:'海外服·主公', - tw_sp:'海外服·SP', - tw_swordsman:'海外服·武侠篇', - tw_mobile2:'海外服·异构', - tw_yijiang:'一将成名TW', - tw_english:'英文版', + tw_mobile: "海外服·稀有专属", + tw_yunchouzhi: "运筹帷幄·智", + tw_yunchouxin: "运筹帷幄·信", + tw_yunchouren: "运筹帷幄·仁", + tw_yunchouyong: "运筹帷幄·勇", + tw_yunchouyan: "运筹帷幄·严", + tw_zhu: "海外服·主公", + tw_sp: "海外服·SP", + tw_swordsman: "海外服·武侠篇", + tw_mobile2: "海外服·异构", + tw_yijiang: "一将成名TW", + tw_english: "英文版", + }, + pinyins: { + 凯撒: ["Caesar"], + 难升米: ["Nashime"], }, - pinyins:{ - 凯撒:['Caesar'], - 难升米:['Nashime'] - } }; }); diff --git a/character/xiake.js b/character/xiake.js index 4875b6b7d..ed4caee9f 100644 --- a/character/xiake.js +++ b/character/xiake.js @@ -1,118 +1,123 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ - return { - name:'xiake', - character:{ - // xk_dongfangweiming:['male','shu',4,[]], - xk_guyuexuan:['male','qun',4,['rouquan','gzhenji']], - xk_jinji:['male','shu',4,['zhongzhan','lianpo']], - // xk_shenxiangyun:['female','wei',3,['zhenjiu']], - xk_fujianhan:['male','qun',4,['zuijian','zitong']], - }, - skill:{ - zhongzhan:{ - trigger:{source:'damageBegin'}, - logTarget:'player', - check:function(event,player){ - if(get.damageEffect(event.player,player,player)>0&& - get.attitude(player,event.player)<0){ - return player.hp>event.player.hp&&player.hp>=2; - } - return false; - }, - content:function(){ - player.loseHp(); - trigger.num++; - } - }, - rouquan:{ - mod:{ - selectTarget:function(card,player,range){ - if(card.name=='sha'&&!player.getEquip(1)&&range[1]!=-1) range[1]=Infinity; - } - }, - enable:'phaseUse', - position:'e', - filter:function(event,player){ - return player.hasCard(card=>lib.skill.rouquan.filterCard(card,player),lib.skill.rouquan.position); - }, - filterCard:lib.filter.cardRecastable, - prompt:'将要重铸的牌置入弃牌堆并摸一张牌', - discard:false, - lose:false, - delay:false, - check:function(card,player){ - var val=get.equipValue(card); - var player=_status.event.player; - var cards=player.getCards('h',{subtype:get.subtype(card)}); - for(var i=0;i=val){ - return 1; - } - } - return 0; - }, - content:function(){ - player.recast(cards); - }, - ai:{ - order:9.5, - result:{ - player:1 - } - } - }, - gzhenji:{ - trigger:{source:'damageEnd'}, - frequent:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return _status.currentPhase==player&&event.card&&event.card.name=='sha'; - }, - content:function(){ - player.draw(); - player.addTempSkill('gzhenji3'); - } - }, - gzhenji3:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } - }, - }, - zitong:{ - trigger:{player:'useCard'}, - frequent:true, - filter:function(event,player){ - return _status.currentPhase==player&&player.countUsed()==3; - }, - content:function(){ - var card=get.cardPile('chuansongmen'); - if(!card){ - card=game.createCard('chuansongmen'); - } - player.gain(card,'gain2'); - }, - ai:{ - threaten:1.2 - } - } - }, - translate:{ - xk_dongfangweiming:'东方未明', - xk_guyuexuan:'谷月轩', - xk_jinji:'荆棘', - xk_shenxiangyun:'沈湘芸', - xk_fujianhan:'傅剑寒', - zhongzhan:'重斩', - zhongzhan_info:'每当你即将造成伤害,你可失去1点体力令伤害+1。', - gzhenji:'震击', - gzhenji_info:'你使用杀造成伤害后,可以摸一张牌,并且本回合内可以额外使用一张杀。', - rouquan:'柔拳', - rouquan_info:'你可以重铸装备区内的牌;当你没有武器牌时,你的杀可以指定任意个目标。', - zitong:'通悟', - zitong_info:'当你于自己的回合内使用第三张牌时,你可以将一张传送门置于你的手牌。', - }, - }; -}); +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { + return { + name: "xiake", + character: { + // xk_dongfangweiming:['male','shu',4,[]], + xk_guyuexuan: ["male", "qun", 4, ["rouquan", "gzhenji"]], + xk_jinji: ["male", "shu", 4, ["zhongzhan", "lianpo"]], + // xk_shenxiangyun:['female','wei',3,['zhenjiu']], + xk_fujianhan: ["male", "qun", 4, ["zuijian", "zitong"]], + }, + skill: { + zhongzhan: { + trigger: { source: "damageBegin" }, + logTarget: "player", + check: function (event, player) { + if ( + get.damageEffect(event.player, player, player) > 0 && + get.attitude(player, event.player) < 0 + ) { + return player.hp > event.player.hp && player.hp >= 2; + } + return false; + }, + content: function () { + player.loseHp(); + trigger.num++; + }, + }, + rouquan: { + mod: { + selectTarget: function (card, player, range) { + if (card.name == "sha" && !player.getEquip(1) && range[1] != -1) range[1] = Infinity; + }, + }, + enable: "phaseUse", + position: "e", + filter: function (event, player) { + return player.hasCard( + (card) => lib.skill.rouquan.filterCard(card, player), + lib.skill.rouquan.position + ); + }, + filterCard: lib.filter.cardRecastable, + prompt: "将要重铸的牌置入弃牌堆并摸一张牌", + discard: false, + lose: false, + delay: false, + check: function (card, player) { + var val = get.equipValue(card); + var player = _status.event.player; + var cards = player.getCards("h", { subtype: get.subtype(card) }); + for (var i = 0; i < cards.length; i++) { + if (get.equipValue(cards[i]) >= val) { + return 1; + } + } + return 0; + }, + content: function () { + player.recast(cards); + }, + ai: { + order: 9.5, + result: { + player: 1, + }, + }, + }, + gzhenji: { + trigger: { source: "damageEnd" }, + frequent: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return _status.currentPhase == player && event.card && event.card.name == "sha"; + }, + content: function () { + player.draw(); + player.addTempSkill("gzhenji3"); + }, + }, + gzhenji3: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + }, + zitong: { + trigger: { player: "useCard" }, + frequent: true, + filter: function (event, player) { + return _status.currentPhase == player && player.countUsed() == 3; + }, + content: function () { + var card = get.cardPile("chuansongmen"); + if (!card) { + card = game.createCard("chuansongmen"); + } + player.gain(card, "gain2"); + }, + ai: { + threaten: 1.2, + }, + }, + }, + translate: { + xk_dongfangweiming: "东方未明", + xk_guyuexuan: "谷月轩", + xk_jinji: "荆棘", + xk_shenxiangyun: "沈湘芸", + xk_fujianhan: "傅剑寒", + zhongzhan: "重斩", + zhongzhan_info: "每当你即将造成伤害,你可失去1点体力令伤害+1。", + gzhenji: "震击", + gzhenji_info: "你使用杀造成伤害后,可以摸一张牌,并且本回合内可以额外使用一张杀。", + rouquan: "柔拳", + rouquan_info: "你可以重铸装备区内的牌;当你没有武器牌时,你的杀可以指定任意个目标。", + zitong: "通悟", + zitong_info: "当你于自己的回合内使用第三张牌时,你可以将一张传送门置于你的手牌。", + }, + }; +}); diff --git a/character/xianding.js b/character/xianding.js index a415b07e4..693673dfc 100644 --- a/character/xianding.js +++ b/character/xianding.js @@ -1,259 +1,1066 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'xianding', - connect:true, - character:{ - caofang:['male','wei',4,['dczhimin','dcjujian'],['zhu']], - dc_sb_simayi:['male','wei',3,['dcsbquanmou','dcsbpingliao']], - chendong:['male','wu',4,['dcduanxie','fenming']], - lvfan:['male','wu',3,['diaodu','diancai']], - cuimao:['male','wei',3,['zhengbi','fengying']], - huzun:['male','wei',4,['dczhantao','dcanjing']], - zhugemengxue:['female','wei',3,['dcjichun','dchanying']], - bailingyun:['female','wei',3,['dclinghui','dcxiace','dcyuxin']], - dc_qinghegongzhu:['female','wei',3,['dczhangji','dczengou']], - caoxian:['female','wei',3,['dclingxi','dczhifou']], - dc_sb_zhouyu:['male','wu',4,['dcsbronghuo','dcsbyingmou']], - dc_sb_lusu:['male','wu',3,['dcsbmingshi','dcsbmengmou']], - zhangjian:['male','qun',105,['dc_zj_a','dc_zj_b'],['unseen']], - zhugeruoxue:['female','wei',3,['dcqiongying','dcnuanhui']], - caoyi:['female','wei',4,['dcmiyi','dcyinjun']], - malingli:['female','shu',3,['dclima','dcxiaoyin','dchuahuo']], - wu_luxun:['male','wu',3,['dcxiongmu','dczhangcai','dcruxian']], - dc_xujing:['male','shu',3,['dcshangyu','dccaixia']], - dc_zhaoxiang:['female','shu',4,['refanghun','refuhan']], - dc_guansuo:['male','shu',4,['xinzhengnan','xiefang']], - xin_baosanniang:['female','shu',3,['decadewuniang','decadexushen']], - dc_shixie:['male','qun',3,['rebiluan','ollixia']], - dc_sp_machao:['male','qun',4,['zhuiji','dc_olshichou']], - old_huangfusong:['male','qun',4,['xinfenyue']], - dc_xiahouba:['male','shu',4,['rebaobian']], - dc_daxiaoqiao:['female','wu',3,['dcxingwu','dcluoyan'],['tempname:daxiaoqiao']], - tianshangyi:['female','wei',3,['dcposuo','dcxiaoren']], - sunlingluan:['female','wu',3,['dclingyue','dcpandi']], - dc_wangjun:['male','qun',4,['dctongye','dcchangqu']], - zhoubuyi:['male','wei',3,['dcshiji','dcsilun']], - dc_duyu:['male','wei',4,['dcjianguo','dcdyqingshi']], - ganfurenmifuren:['female','shu',3,['dcchanjuan','dcxunbie']], - dc_ganfuren:['female','shu',3,['dcshushen','dcshenzhi']], - dc_mifuren:['female','shu',3,['dcguixiu','dccunsi']], - wanglang:['male','wei',3,['regushe','rejici']], - ruanji:['male','wei',3,['dczhaowen','dcjiudun']], - wu_zhugeliang:['male','shu','4/7',['dcjincui','dcqingshi','dczhizhe']], - duanqiaoxiao:['female','wei',3,['dccaizhuang','dchuayi']], - zhangjinyun:['female','shu',3,['dchuizhi','dcjijiao']], - huanfan:['male','wei',3,['dcjianzheng','dcfumou']], - chentai:['male','wei',4,['dcctjiuxian','dcchenyong']], - sunyu:['male','wu',3,['dcquanshou','dcshexue']], - xizheng:['male','shu',3,['dcdanyi','dcwencan']], - dc_ruiji:['female','wu',4,['dcwangyuan','dclingyin','dcliying']], - zerong:['male','qun',4,['dccansi','dcfozong']], - xielingyu:['female','wu',3,['dcyuandi','dcxinyou']], - dc_yangbiao:['male','qun',3,['dczhaohan','dcjinjie','dcjue']], - dc_tengfanglan:['female','wu',3,['dcluochong','dcaichen']], - yanghong:['male','qun',3,['dcjianji','dcyuanmo']], - xuelingyun:['female','wei',3,['dcxialei','dcanzhi']], - dc_wangyun:['male','qun',4,['dclianji','dcmoucheng'],['clan:太原王氏']], - dc_zhouxuān:['male','wei',3,['dcwumei','dczhanmeng']], - chengbing:['male','wu',3,['dcjingzao','dcenyu']], - dongguiren:['female','qun',3,['dclianzhi','dclingfang','dcfengying']], - yuanji:['female','wu',3,['dcfangdu','dcjiexing']], - zhujianping:['male','qun',3,['dcxiangmian','dctianji']], - zhaozhi:['male','shu',3,['dctongguan','dcmengjie']], - dc_liuye:['male','wei',3,['dcpoyuan','dchuace']], - luyi:['female','qun',3,['dcyaoyi','dcfuxue']], - dingshangwan:['female','wei',3,['dcfengyan','dcfudao']], - quanhuijie:['female','wu',3,['dchuishu','dcyishu','dcligong']], - dukui:['male','wei',3,['dcfanyin','dcpeiqi']], - zhangfen:['male','wu',4,['dcwanglu','dcxianzhu','dcchaixie']], - liuhui:['male','qun',4,['dcgeyuan','dcjieshu','dcgusuan']], - dc_wangchang:['male','wei',3,['dckaiji','dcpingxi'],['clan:太原王氏']], - zhaoang:['male','wei','3/4',['dczhongjie','dcsushou']], - caohua:['female','wei',3,['caiyi','guili']], - dc_liuyu:['male','qun',3,['dcsuifu','dcpijing']], - dc_huangzu:['male','qun',4,['dcjinggong','dcxiaojuan']], - laiyinger:['female','qun',3,['xiaowu','huaping']], - caomao:['male','wei','3/4',['qianlong','fensi','juetao','zhushi'],['zhu']], - dc_luotong:['male','wu',3,['renzheng','jinjian']], - re_fengfangnv:['female','qun',3,['tiqi','baoshu']], - wufan:['male','wu',4,['tianyun','wfyuyan']], - re_zhangbao:['male','qun',3,['xinzhoufu','xinyingbing']], - re_sunyi:['male','wu',5,['syjiqiao','syxiongyi']], - caojinyu:['female','wei',3,['yuqi','shanshen','xianjing']], - zhouyi:['female','wu',3,['zhukou','mengqing']], - re_panshu:['female','wu',3,['zhiren','yaner']], - yangwan:['female','shu',3,['youyan','zhuihuan']], - ruanyu:['male','wei',3,['xingzuo','miaoxian']], - fanyufeng:['female','qun',3,['bazhan','jiaoying']], - guozhao:['female','wei',3,['pianchong','zunwei']], - re_xinxianying:['female','wei',3,['rezhongjian','recaishi']], - liubian:['male','qun',3,['shiyuan','dushi','yuwei'],['zhu']], - re_liuzan:['male','wu',4,['refenyin','liji']], - wenyang:['male','wei',5,['xinlvli','choujue']], - wangshuang:['male','wei',8,['spzhuilie']], - huaman:['female','shu',3,['manyi','mansi','souying','zhanyuan']], - puyuan:['male','shu',4,['pytianjiang','pyzhuren']], - guanlu:['male','wei',3,['tuiyan','busuan','mingjie']], - gexuan:['male','wu',3,['gxlianhua','zhafu']], - leitong:['male','shu',4,['kuiji']], - wulan:['male','shu',4,['wlcuorui']], + name: "xianding", + connect: true, + character: { + sp_zhenji: ["female", "qun", 3, ["dcjijie", "dchuiji"]], + wu_guanyu: ["male", "shu", 5, ["dcjuewu", "dcwuyou", "dcyixian"]], + caofang: ["male", "wei", 4, ["dczhimin", "dcjujian"], ["zhu"]], + dc_sb_simayi: ["male", "wei", 3, ["dcsbquanmou", "dcsbpingliao"]], + chendong: ["male", "wu", 4, ["dcduanxie", "fenming"]], + lvfan: ["male", "wu", 3, ["diaodu", "diancai"]], + cuimao: ["male", "wei", 3, ["zhengbi", "fengying"]], + huzun: ["male", "wei", 4, ["dczhantao", "dcanjing"]], + zhugemengxue: ["female", "wei", 3, ["dcjichun", "dchanying"]], + bailingyun: ["female", "wei", 3, ["dclinghui", "dcxiace", "dcyuxin"]], + dc_qinghegongzhu: ["female", "wei", 3, ["dczhangji", "dczengou"]], + caoxian: ["female", "wei", 3, ["dclingxi", "dczhifou"]], + dc_sb_zhouyu: ["male", "wu", 4, ["dcsbronghuo", "dcsbyingmou"]], + dc_sb_lusu: ["male", "wu", 3, ["dcsbmingshi", "dcsbmengmou"]], + zhangjian: ["male", "qun", 105, ["dc_zj_a", "dc_zj_b"], ["unseen"]], + zhugeruoxue: ["female", "wei", 3, ["dcqiongying", "dcnuanhui"]], + caoyi: ["female", "wei", 4, ["dcmiyi", "dcyinjun"]], + malingli: ["female", "shu", 3, ["dclima", "dcxiaoyin", "dchuahuo"]], + wu_luxun: ["male", "wu", 3, ["dcxiongmu", "dczhangcai", "dcruxian"]], + dc_xujing: ["male", "shu", 3, ["dcshangyu", "dccaixia"]], + dc_zhaoxiang: ["female", "shu", 4, ["refanghun", "refuhan"]], + dc_guansuo: ["male", "shu", 4, ["xinzhengnan", "xiefang"]], + xin_baosanniang: ["female", "shu", 3, ["decadewuniang", "decadexushen"]], + dc_shixie: ["male", "qun", 3, ["rebiluan", "ollixia"]], + dc_sp_machao: ["male", "qun", 4, ["zhuiji", "dc_olshichou"]], + old_huangfusong: ["male", "qun", 4, ["xinfenyue"]], + dc_xiahouba: ["male", "shu", 4, ["rebaobian"]], + dc_daxiaoqiao: ["female", "wu", 3, ["dcxingwu", "dcluoyan"], ["tempname:daxiaoqiao"]], + tianshangyi: ["female", "wei", 3, ["dcposuo", "dcxiaoren"]], + sunlingluan: ["female", "wu", 3, ["dclingyue", "dcpandi"]], + dc_wangjun: ["male", "qun", 4, ["dctongye", "dcchangqu"]], + zhoubuyi: ["male", "wei", 3, ["dcshiji", "dcsilun"]], + dc_duyu: ["male", "wei", 4, ["dcjianguo", "dcdyqingshi"]], + ganfurenmifuren: ["female", "shu", 3, ["dcchanjuan", "dcxunbie"]], + dc_ganfuren: ["female", "shu", 3, ["dcshushen", "dcshenzhi"]], + dc_mifuren: ["female", "shu", 3, ["dcguixiu", "dccunsi"]], + wanglang: ["male", "wei", 3, ["regushe", "rejici"]], + ruanji: ["male", "wei", 3, ["dczhaowen", "dcjiudun"]], + wu_zhugeliang: ["male", "shu", "4/7", ["dcjincui", "dcqingshi", "dczhizhe"]], + duanqiaoxiao: ["female", "wei", 3, ["dccaizhuang", "dchuayi"]], + zhangjinyun: ["female", "shu", 3, ["dchuizhi", "dcjijiao"]], + huanfan: ["male", "wei", 3, ["dcjianzheng", "dcfumou"]], + chentai: ["male", "wei", 4, ["dcctjiuxian", "dcchenyong"]], + sunyu: ["male", "wu", 3, ["dcquanshou", "dcshexue"]], + xizheng: ["male", "shu", 3, ["dcdanyi", "dcwencan"]], + dc_ruiji: ["female", "wu", 4, ["dcwangyuan", "dclingyin", "dcliying"]], + zerong: ["male", "qun", 4, ["dccansi", "dcfozong"]], + xielingyu: ["female", "wu", 3, ["dcyuandi", "dcxinyou"]], + dc_yangbiao: ["male", "qun", 3, ["dczhaohan", "dcjinjie", "dcjue"]], + dc_tengfanglan: ["female", "wu", 3, ["dcluochong", "dcaichen"]], + yanghong: ["male", "qun", 3, ["dcjianji", "dcyuanmo"]], + xuelingyun: ["female", "wei", 3, ["dcxialei", "dcanzhi"]], + dc_wangyun: ["male", "qun", 4, ["dclianji", "dcmoucheng"], ["clan:太原王氏"]], + dc_zhouxuān: ["male", "wei", 3, ["dcwumei", "dczhanmeng"]], + chengbing: ["male", "wu", 3, ["dcjingzao", "dcenyu"]], + dongguiren: ["female", "qun", 3, ["dclianzhi", "dclingfang", "dcfengying"]], + yuanji: ["female", "wu", 3, ["dcfangdu", "dcjiexing"]], + zhujianping: ["male", "qun", 3, ["dcxiangmian", "dctianji"]], + zhaozhi: ["male", "shu", 3, ["dctongguan", "dcmengjie"]], + dc_liuye: ["male", "wei", 3, ["dcpoyuan", "dchuace"]], + luyi: ["female", "qun", 3, ["dcyaoyi", "dcfuxue"]], + dingshangwan: ["female", "wei", 3, ["dcfengyan", "dcfudao"]], + quanhuijie: ["female", "wu", 3, ["dchuishu", "dcyishu", "dcligong"]], + dukui: ["male", "wei", 3, ["dcfanyin", "dcpeiqi"]], + zhangfen: ["male", "wu", 4, ["dcwanglu", "dcxianzhu", "dcchaixie"]], + liuhui: ["male", "qun", 4, ["dcgeyuan", "dcjieshu", "dcgusuan"]], + dc_wangchang: ["male", "wei", 3, ["dckaiji", "dcpingxi"], ["clan:太原王氏"]], + zhaoang: ["male", "wei", "3/4", ["dczhongjie", "dcsushou"]], + caohua: ["female", "wei", 3, ["caiyi", "guili"]], + dc_liuyu: ["male", "qun", 3, ["dcsuifu", "dcpijing"]], + dc_huangzu: ["male", "qun", 4, ["dcjinggong", "dcxiaojuan"]], + laiyinger: ["female", "qun", 3, ["xiaowu", "huaping"]], + caomao: ["male", "wei", "3/4", ["qianlong", "fensi", "juetao", "zhushi"], ["zhu"]], + dc_luotong: ["male", "wu", 3, ["renzheng", "jinjian"]], + re_fengfangnv: ["female", "qun", 3, ["tiqi", "baoshu"]], + wufan: ["male", "wu", 4, ["tianyun", "wfyuyan"]], + re_zhangbao: ["male", "qun", 3, ["xinzhoufu", "xinyingbing"]], + re_sunyi: ["male", "wu", 5, ["syjiqiao", "syxiongyi"]], + caojinyu: ["female", "wei", 3, ["yuqi", "shanshen", "xianjing"]], + zhouyi: ["female", "wu", 3, ["zhukou", "mengqing"]], + re_panshu: ["female", "wu", 3, ["zhiren", "yaner"]], + yangwan: ["female", "shu", 3, ["youyan", "zhuihuan"]], + ruanyu: ["male", "wei", 3, ["xingzuo", "miaoxian"]], + fanyufeng: ["female", "qun", 3, ["bazhan", "jiaoying"]], + guozhao: ["female", "wei", 3, ["pianchong", "zunwei"]], + re_xinxianying: ["female", "wei", 3, ["rezhongjian", "recaishi"]], + liubian: ["male", "qun", 3, ["shiyuan", "dushi", "yuwei"], ["zhu"]], + re_liuzan: ["male", "wu", 4, ["refenyin", "liji"]], + wenyang: ["male", "wei", 5, ["xinlvli", "choujue"]], + wangshuang: ["male", "wei", 8, ["spzhuilie"]], + huaman: ["female", "shu", 3, ["manyi", "mansi", "souying", "zhanyuan"]], + puyuan: ["male", "shu", 4, ["pytianjiang", "pyzhuren"]], + guanlu: ["male", "wei", 3, ["tuiyan", "busuan", "mingjie"]], + gexuan: ["male", "wu", 3, ["gxlianhua", "zhafu"]], + leitong: ["male", "shu", 4, ["kuiji"]], + wulan: ["male", "shu", 4, ["wlcuorui"]], }, - characterSort:{ - xianding:{ - sp2_huben:['chendong','wangshuang','wenyang','re_liuzan','dc_huangzu','wulan','leitong','chentai','dc_duyu','dc_wangjun','dc_xiahouba','old_huangfusong','huzun'], - sp2_shengun:["puyuan","guanlu","gexuan",'wufan','re_zhangbao','dukui','zhaozhi','zhujianping','dc_zhouxuān','zerong'], - sp2_bizhe:['dc_luotong','dc_wangchang','chengbing','dc_yangbiao','ruanji','cuimao'], - sp2_huangjia:['caomao','liubian','dc_liuyu','quanhuijie','dingshangwan','yuanji','xielingyu','sunyu','ganfurenmifuren','dc_ganfuren','dc_mifuren','dc_shixie','caofang'], - sp2_zhangtai:['guozhao','fanyufeng','ruanyu','yangwan','re_panshu'], - sp2_jinse:['caojinyu','re_sunyi','re_fengfangnv','caohua','laiyinger','zhangfen','zhugeruoxue','caoxian','dc_qinghegongzhu','zhugemengxue'], - sp2_yinyu:['zhouyi','luyi','sunlingluan','caoyi'], - sp2_wangzhe:['dc_daxiaoqiao','dc_sp_machao'], - sp2_doukou:['re_xinxianying','huaman','xuelingyun','dc_ruiji','duanqiaoxiao','tianshangyi','malingli','bailingyun'], - sp2_jichu:['zhaoang','dc_liuye','dc_wangyun','yanghong','huanfan','xizheng','lvfan'], - sp2_yuxiu:['dongguiren','dc_tengfanglan','zhangjinyun','zhoubuyi','dc_xujing'], - sp2_qifu:['dc_guansuo','xin_baosanniang','dc_zhaoxiang'], - sp2_gaoshan:['wanglang','liuhui','zhangjian'], - sp2_wumiao:['wu_zhugeliang','wu_luxun'], - sp2_mouding:['dc_sb_lusu','dc_sb_zhouyu','dc_sb_simayi'], - } + characterSort: { + xianding: { + sp2_huben: [ + "chendong", + "wangshuang", + "wenyang", + "re_liuzan", + "dc_huangzu", + "wulan", + "leitong", + "chentai", + "dc_duyu", + "dc_wangjun", + "dc_xiahouba", + "old_huangfusong", + "huzun", + ], + sp2_shengun: [ + "puyuan", + "guanlu", + "gexuan", + "wufan", + "re_zhangbao", + "dukui", + "zhaozhi", + "zhujianping", + "dc_zhouxuān", + "zerong", + ], + sp2_bizhe: ["dc_luotong", "dc_wangchang", "chengbing", "dc_yangbiao", "ruanji", "cuimao"], + sp2_huangjia: [ + "caomao", + "liubian", + "dc_liuyu", + "quanhuijie", + "dingshangwan", + "yuanji", + "xielingyu", + "sunyu", + "ganfurenmifuren", + "dc_ganfuren", + "dc_mifuren", + "dc_shixie", + "caofang", + ], + sp2_zhangtai: ["guozhao", "fanyufeng", "ruanyu", "yangwan", "re_panshu"], + sp2_jinse: [ + "caojinyu", + "re_sunyi", + "re_fengfangnv", + "caohua", + "laiyinger", + "zhangfen", + "zhugeruoxue", + "caoxian", + "dc_qinghegongzhu", + "zhugemengxue", + ], + sp2_yinyu: ["zhouyi", "luyi", "sunlingluan", "caoyi"], + sp2_wangzhe: ["dc_daxiaoqiao", "dc_sp_machao", "sp_zhenji"], + sp2_doukou: [ + "re_xinxianying", + "huaman", + "xuelingyun", + "dc_ruiji", + "duanqiaoxiao", + "tianshangyi", + "malingli", + "bailingyun", + ], + sp2_jichu: ["zhaoang", "dc_liuye", "dc_wangyun", "yanghong", "huanfan", "xizheng", "lvfan"], + sp2_yuxiu: ["dongguiren", "dc_tengfanglan", "zhangjinyun", "zhoubuyi", "dc_xujing"], + sp2_qifu: ["dc_guansuo", "xin_baosanniang", "dc_zhaoxiang"], + sp2_gaoshan: ["wanglang", "liuhui", "zhangjian"], + sp2_wumiao: ["wu_zhugeliang", "wu_luxun", "wu_guanyu"], + sp2_mouding: ["dc_sb_lusu", "dc_sb_zhouyu", "dc_sb_simayi"], + }, }, - characterSubstitute:{ - dc_sb_simayi:[ - ], + characterSubstitute: { + dc_sb_simayi: [], }, - skill:{ - //曹芳 - dczhimin:{ - audio:2, - trigger:{global:'roundStart'}, - filter(event,player){ - return game.hasPlayer(current=>current!=player&¤t.countCards('h'))&&player.getHp()>0; + skill: { + //武关羽 + dcjuewu: { + audio: 2, + enable: "chooseToUse", + filter(event, player) { + if ( + !player.hasCard((card) => { + return _status.connectMode || get.number(card) === 2; + }, "hes") + ) + return false; + for (const name of ["shuiyanqijuny"].concat(lib.inpile)) { + if (player.getStorage("dcjuewu_used").includes(name)) continue; + const card = get.autoViewAs({ name }, "unsure"); + if (!get.tag(card, "damage")) continue; + if (event.filterCard(card, player, event)) return true; + if (name === "sha") { + for (const nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return true; + } + } + } + return false; }, - forced:true, - group:['dczhimin_mark','dczhimin_draw'], - async content(event,trigger,player){ - const targets = await player.chooseTarget(`置民:请选择至多${get.cnNumber(player.getHp())}名其他角色`, '你获得这些角色各自手牌中的随机一张点数最小的牌', (card, player, target) => { - return target !== player && target.countCards('h'); - }, [1, player.getHp()], true).set('ai', target => { + hiddenCard(player, name) { + if (!lib.inpile.includes(name)) return false; + if (player.getStorage("dcjuewu_used").includes(name)) return false; + if ( + !player.hasCard((card) => { + return _status.connectMode || get.number(card) === 2; + }, "hes") + ) + return false; + return get.tag({ name }, "damage"); + }, + group: "dcjuewu_inTwo", + chooseButton: { + dialog(event, player) { + let list = get.inpileVCardList((info) => { + return get.tag({ name: info[2] }, "damage"); + }); + if (!list.some((info) => info[2] === "shuiyanqijuny")) + list.add(["锦囊", "", "shuiyanqijuny"]); + list = list.filter((info) => { + const name = info[2], + nature = info[3]; + if (player.getStorage("dcjuewu_used").includes(name)) return false; + const card = get.autoViewAs({ name, nature }, "unsure"); + return event.filterCard(card, player, event); + }); + return ui.create.dialog("绝武", [list, "vcard"]); + }, + check(button) { + if (get.event().getParent().type != "phase") return 1; const player = get.player(); - return get.effect(target, {name:'shunshou_copy', position: 'h'}, player, player) + 0.1; - }).forResultTargets(); - if (!targets || !targets.length) return; - targets.sortBySeat(trigger.player); - player.line(targets, 'thunder'); - const toGain = []; - for (const target of targets) { - const cards = target.getCards('h'), minNumber = cards.map(card => get.number(card)).sort((a, b) => a - b)[0]; - const gainableCards = cards.filter(card => { - return get.number(card) === minNumber && lib.filter.canBeGained(card, player, target); - }).randomSort(); - toGain.push(gainableCards[0]); - } - if (toGain.length) await player.gain(toGain, 'giveAuto'); - await game.asyncDelayx(); + return player.getUseValue({ + name: button.link[2], + nature: button.link[3], + }); + }, + backup(links, player) { + return { + audio: "dcjuewu", + filterCard(card, player) { + return get.number(card) === 2; + }, + position: "hes", + check(card) { + return 8 - get.value(card); + }, + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], + }, + precontent() { + if (!player.storage.dcjuewu_used) { + player.when({ global: "phaseAfter" }).then(() => { + delete player.storage.dcjuewu_used; + }); + } + player.markAuto("dcjuewu_used", event.result.card.name); + }, + }; + }, + prompt(links, player) { + return ( + "将一张点数为2的牌当" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); + }, }, - ai:{ - threaten:5.8, - }, - mod:{ - aiOrder(player,card,num){ - if(num>0&&get.itemtype(card)==='card'&&card.hasGaintag('dczhimin_tag')&&player.countCards('h',cardx=>{ - return cardx.hasGaintag('dczhimin_tag')&&cardx!==card; - })get.position(card)==='h'&&get.owner(card)===player)) return false; - return true; + filter(event, player) { + const cards = event.getg(player); + if (!cards.length) return false; + return game.hasPlayer((current) => { + if (current === player) return false; + const evt = event.getl(current); + return evt && evt.hs.length + evt.es.length + evt.js.length > 0; + }); }, - async content(event,trigger,player){ - player.addGaintag(trigger.getg(player).filter(card=>get.position(card)==='h'&&get.owner(card)===player), 'dczhimin_tag'); + forced: true, + locked: false, + async content(event, trigger, player) { + player.addGaintag(trigger.getg(player), "dcjuewu_two"); + player.addSkill("dcjuewu_two"); }, }, - draw:{ - audio:'dczhimin', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + two: { + charlotte: true, + mod: { + cardnumber(card) { + if (card.hasGaintag("dcjuewu_two")) return 2; + }, }, - forced:true, - filter(event,player){ - const evt=event.getl(player); - if(!evt.hs.length) return false; - return Object.values(evt.gaintag_map).flat().includes('dczhimin_tag'); + }, + }, + ai: { + fireAttack: true, + respondSha: true, + skillTagFilter(player) { + if ( + !player.hasCard((card) => { + return _status.connectMode || get.number(card) === 2; + }, "hes") + ) + return false; + }, + order: 1, + result: { + player(player) { + if (get.event("dying")) return get.attitude(player, get.event("dying")); + return 1; }, - async content(event,trigger,player){ - const count = player.maxHp - player.countCards('h'); - if (count <= 0) return; - await player.draw(count); - } }, }, }, - dcjujian:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuSkill:true, - filter(event,player){ - return game.hasPlayer(current=>{ - return player.hasZhuSkill('dcjujian',current)&¤t.group==='wei'&¤t!==player; + dcwuyou: { + audio: 2, + global: "dcwuyou_g", + subSkill: { + g: { + audio: "dcwuyou", + enable: "phaseUse", + usable: 1, + filter(event, player) { + if (!player.countCards("h")) return false; + return game.hasPlayer((current) => { + return current.hasSkill("dcwuyou"); + }); + }, + filterCard: true, + filterTarget(card, player, target) { + return target.hasSkill("dcwuyou"); + }, + selectTarget() { + const count = game.countPlayer((current) => { + return current.hasSkill("dcwuyou"); + }); + return count > 1 ? 1 : -1; + }, + check(card) { + const player = get.player(); + const hasFriend = game.hasPlayer((current) => { + return current.hasSkill("dcwuyou") && get.attitude(player, current) > 0; + }); + return (hasFriend ? 7 : 1) - get.value(card); + }, + prompt() { + const player = get.player(), + list = game.filterPlayer((current) => { + return current.hasSkill("dcwuyou"); + }), + list2 = list.filter((current) => current !== player); + const moreThanOne = list.length > 1, + includesMe = list.includes(player); + let str = "选择一张手牌,"; + if (includesMe) str += `点击“确定”,${moreThanOne ? "或" : ""}`; + if (moreThanOne || !includesMe) + str += `将此牌交给${get.translation(list2)}${ + list2.length > 1 ? "中的一人" : "" + },`; + str += "然后执行后续效果。"; + return str; + }, + discard: false, + lose: false, + delay: false, + async content(event, trigger, player) { + const { target } = event; + const isMe = target === player; + let { cards } = event; + if (!isMe) await player.give(cards, target); + const names = lib.inpile + .filter((name) => { + return get.type2(name) !== "equip"; + }) + .randomGets(5); + if (names.includes("sha")) + names.splice( + names.indexOf("sha") + 1, + 0, + ...lib.inpile_nature.map((nature) => ["sha", nature]) + ); + const vcard = names.map((namex) => { + let name = namex, + nature; + if (Array.isArray(namex)) [name, nature] = namex; + const info = [get.type(name), "", name, nature]; + return info; + }); + const links = await target + .chooseButton(["武佑:选择一个牌名", [vcard, "vcard"]], true) + .set("user", player) + .set("ai", (button) => { + const player = get.player(), + user = get.event("user"); + return ( + user.getUseValue({ name: button.link[2], nature: button.link[3] }) * + get.attitude(player, user) + ); + }) + .forResultLinks(); + if (!links || !links.length) return; + const viewAs = { name: links[0][2], nature: links[0][3] }; + if (!isMe) { + cards = await target.chooseToGive(player, true).forResultCards(); + } + const card = cards[0]; + if (player.getCards("h").includes(card)) { + if (!player.storage.dcwuyou_transfer) player.storage.dcwuyou_transfer = {}; + player.storage.dcwuyou_transfer[card.cardid] = viewAs; + player.addGaintag(cards, "dcwuyou_transfer"); + player.addSkill("dcwuyou_transfer"); + } + }, + ai: { + order: 10, + result: { + player(player, target) { + if (get.attitude(player, target) > 0) return 2; + return 1; + }, + target: 0.5, + }, + }, + }, + transfer: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + charlotte: true, + filter(event, player) { + if (event.addCount === false) return false; + return player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (const i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcwuyou_transfer")) return true; + } + return false; + }); + }, + async content(event, trigger, player) { + trigger.addCount = false; + const stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] === "number") stat[name]--; + }, + mod: { + cardname(card, player) { + const map = player.storage.dcwuyou_transfer; + if ( + map && + map[card.cardid] && + get.itemtype(card) == "card" && + card.hasGaintag("dcwuyou_transfer") + ) + return map[card.cardid].name; + }, + cardnature(card, player) { + const map = player.storage.dcwuyou_transfer; + if ( + map && + map[card.cardid] && + get.itemtype(card) == "card" && + card.hasGaintag("dcwuyou_transfer") + ) + return map[card.cardid].nature || false; + }, + cardUsable(card) { + if (!card.cards) return; + if (card.cards.some((card) => card.hasGaintag("dcwuyou_transfer"))) + return Infinity; + }, + }, + }, + }, + }, + dcyixian: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "metal", + chooseButton: { + dialog(event, player) { + const dialog = ui.create.dialog("义贤:你可以选择一项", "hidden"); + dialog.add([ + [ + ["field", "获得场上的所有装备牌"], + ["discardPile", "获得弃牌堆中的所有装备牌"], + ], + "textbutton", + ]); + return dialog; + }, + check(button) { + const player = get.player(); + if (button.link == "field") + return game + .filterPlayer() + .map((current) => { + const cards = current.getCards("e"), + att = get.sgnAttitude(player, current); + return cards + .map((card) => { + return ( + Math.max( + player.hasSkill("dcjuewu") ? 5 : 0, + get.value(card, player) + ) - + get.value(card, current) * att + ); + }) + .reduce((p, c) => p + c, 0); + }) + .reduce((p, c) => p + c, 0); + if (button.link == "discardPile") + return Array.from(ui.discardPile.childNodes) + .filter((card) => { + return get.type(card) === "equip"; + }) + .map((card) => { + return Math.max( + player.hasSkill("dcjuewu") ? 5 : 0, + get.value(card, player) + ); + }) + .reduce((p, c) => p + c, 0); + return 0.1; + }, + backup(links) { + return { + filterCard: () => false, + selectCard: -1, + pos: links[0], + filterTarget: () => false, + selectTarget: -1, + popup: false, + direct: true, + async content(event, trigger, player) { + await player.logSkill("dcyixian"); + player.awakenSkill("dcyixian"); + const position = lib.skill.dcyixian_backup.pos; + let cards = []; + if (position === "field") { + cards.addArray( + game + .filterPlayer() + .map((current) => current.getCards("e")) + .flat() + ); + } else { + cards.addArray( + Array.from(ui.discardPile.childNodes).filter((card) => { + return get.type(card) === "equip"; + }) + ); + } + if (!cards.length) return; + await player.gain(cards, position === "field" ? "give" : "gain2"); + const pairs = game.filterPlayer().map((current) => { + let lostNum = 0; + current.checkHistory("lose", (evt) => { + if (evt.getParent(2) === event) lostNum += evt.cards2.length; + }); + return [current, lostNum]; + }); + for (const pair of pairs) { + const [target, num] = pair; + if (!num) continue; + const bool = await player + .chooseBool( + `是否令${get.translation(target)}摸${get.cnNumber( + num + )}张牌并回复1点体力?` + ) + .set( + "choice", + get.effect(target, { name: "draw" }, player, player) + + get.recoverEffect(target, player, player) / 5 > + 0 + ) + .forResultBool(); + if (bool) { + player.line(target, "green"); + await target.draw(num); + await target.recover(); + } + if (!event.isMine() && !event.isOnline()) await game.asyncDelayx(); + } + }, + }; + }, + prompt(links) { + return `点击“确定”,从${links[0] === "field" ? "场上" : "弃牌堆中"}获得所有装备牌`; + }, + }, + subSkill: { + backup: {}, + }, + ai: { + order: 10, + threaten: 2.9, + result: { + player(player) { + const enemies = game.filterPlayer((current) => { + return ( + get.rawAttitude(player, current) < 0 && + get.attitude(player, current) >= 0 + ); + }), + knownEnemies = game.filterPlayer((current) => { + return get.attitude(player, current) < 0; + }); + if ( + (!knownEnemies.length && player.countCards("e") > 1) || + (player.getHp() > 3 && + enemies.length > 0 && + knownEnemies.length < 2 && + knownEnemies.length < enemies.length && + !knownEnemies.some((enemy) => get.attitude(player, enemy) <= -9)) + ) + return 0; + const val1 = game + .filterPlayer() + .map((current) => { + const cards = current.getCards("e"), + att = get.sgnAttitude(player, current); + return cards + .map((card) => { + return ( + Math.max( + player.hasSkill("dcjuewu") ? 5 : 0, + get.value(card, player) + ) - + get.value(card, current) * att + ); + }) + .reduce((p, c) => p + c, 0); + }) + .reduce((p, c) => p + c, 0); + const val2 = Array.from(ui.discardPile.childNodes) + .filter((card) => { + return get.type(card) === "equip"; + }) + .map((card) => { + return Math.max( + player.hasSkill("dcjuewu") ? 5 : 0, + get.value(card, player) + ); + }) + .reduce((p, c) => p + c, 0); + return Math.max(val1, val2) > 20 ? 4 : 0; + }, + }, + }, + }, + //SP甄宓 + dcjijie: { + audio: 2, + trigger: { + global: ["gainAfter", "loseAsyncAfter", "recoverAfter"], + }, + getIndex(event, player) { + if (event.name !== "loseAsync") return [[event.player]]; + return [ + game + .filterPlayer((current) => { + return ( + current !== player && + _status.currentPhase !== current && + event.getg(current).length > 0 + ); + }) + .sortBySeat(), + ]; + }, + filter(event, player, triggername, targets) { + if ( + player + .getStorage("dcjijie_used") + .includes(event.name == "recover" ? "recover" : "draw") + ) + return false; + if (event.name === "recover") + return ( + targets[0] !== player && _status.currentPhase !== targets[0] && player.isDamaged() + ); + return targets.some((current) => { + return ( + current !== player && + _status.currentPhase !== current && + event.getg(current).length > 0 + ); }); }, - filterTarget(_,player,target){ - return player.hasZhuSkill('dcjujian',target)&&target.group==='wei'&&target!==player; + forced: true, + logTarget(event, player, triggername, targets) { + return targets; }, - async content(event,trigger,player){ + async content(event, trigger, player) { + player.addTempSkill("dcjijie_used"); + if (trigger.name === "recover") { + player.markAuto("dcjijie_used", ["recover"]); + await player.recover(trigger.num); + } else { + const count = game.countPlayer((current) => { + if (current === player || _status.currentPhase === current) return 0; + return trigger.getg(current).length; + }); + player.markAuto("dcjijie_used", ["draw"]); + await player.draw(count); + } + }, + subSkill: { + used: { + charlotte: true, + onremove: true, + }, + }, + }, + dchuiji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: true, + chooseButton: { + dialog(event, player) { + const name = get.translation(event.result.targets[0]); + const dialog = ui.create.dialog( + `惠济:请选择要令${name}执行的选项`, + [ + [ + ["draw", "令其摸两张牌"], + ["equip", "令其随机使用牌堆中的一张装备牌"], + ], + "textbutton", + ], + "hidden" + ); + return dialog; + }, + filter(button, player) { + const target = get.event().getParent().result.targets[0]; + const link = button.link; + if (button.link === "equip" && target.isMin()) return false; + return true; + }, + check(button) { + const player = get.player(), + target = get.event().getParent().result.targets[0]; + const link = button.link; + const att = get.attitude(player, target) / 5; + const hs = target.countCards("h"); + if (link === "draw") { + return (2 - (hs + 2 > game.countPlayer()) * hs) * att; + } + return (1.1 - (hs > game.countPlayer()) * hs) * att; + }, + backup(links) { + return { + audio: "dchuiji", + target: get.event().result.targets[0], + link: links[0], + filterTarget(card, player, target) { + return target === lib.skill.dchuiji_backup.target; + }, + selectTarget: -1, + async content(event, trigger, player) { + const link = lib.skill.dchuiji_backup.link; + const { target } = event; + if (link === "draw") await target.draw(2); + else { + const card = get.cardPile2((card) => { + if (get.type(card) !== "equip") return false; + return target.canUse(card, target) && !get.cardtag(card, "gifts"); + }); + if (card) await target.chooseUseTarget(card, true).set("nopopup", true); + else { + game.log("但是牌堆里没有", target, "的装备!"); + await game.asyncDelayx(); + } + } + if (target.countCards("h") < game.countPlayer()) return; + player + .when({ global: "wuguRemained" }) + .filter((evt) => { + return evt.getParent(3) === event; + }) + .vars({ originalOwner: target }) + .then(() => { + const remained = trigger.remained.filterInD("d"); + if (!remained.length) return event.finish(); + player.line(originalOwner); + originalOwner.gain(remained, "gain2"); + }); + await target.chooseUseTarget( + { + name: "wugu", + storage: { + fixedShownCards: target.getCards("h"), + }, + }, + true + ); + }, + }; + }, + prompt(links) { + return "点击“确定”以执行效果"; + }, + }, + subSkill: { + backup: {}, + }, + ai: { + order(item, player) { + if ( + !game.hasPlayer( + (current) => current !== player && get.attitude(player, current) > 0 + ) && + game.hasPlayer((current) => get.attitude(player, current) <= 0) + ) + return 10; + if ( + game.hasPlayer((current) => { + const del = player.countCards("h") - current.countCards("h"), + toFind = [2, 4].find((num) => Math.abs(del) === num); + if (toFind === 4 && del < 0 && get.attitude(player, current) <= 0) { + return true; + } + return false; + }) + ) + return 10; + return 1; + }, + result: { + target(player, target) { + const del = player.countCards("h") - target.countCards("h"), + toFind = [2, 4].find((num) => Math.abs(del) === num); + if (toFind) { + return ( + (-del * + (get.attitude(player, target) * Math.min(3, target.countCards("h"))) * + toFind) / + 10 + ); + } + return -1; + }, + }, + }, + }, + //曹芳 + dczhimin: { + audio: 2, + trigger: { global: "roundStart" }, + filter(event, player) { + return ( + game.hasPlayer((current) => current != player && current.countCards("h")) && + player.getHp() > 0 + ); + }, + forced: true, + group: ["dczhimin_mark", "dczhimin_draw"], + async content(event, trigger, player) { + const targets = await player + .chooseTarget( + `置民:请选择至多${get.cnNumber(player.getHp())}名其他角色`, + "你获得这些角色各自手牌中的随机一张点数最小的牌", + (card, player, target) => { + return target !== player && target.countCards("h"); + }, + [1, player.getHp()], + true + ) + .set("ai", (target) => { + const player = get.player(); + return ( + get.effect(target, { name: "shunshou_copy", position: "h" }, player, player) + + 0.1 + ); + }) + .forResultTargets(); + if (!targets || !targets.length) return; + targets.sortBySeat(trigger.player); + player.line(targets, "thunder"); + const toGain = []; + for (const target of targets) { + const cards = target.getCards("h"), + minNumber = cards.map((card) => get.number(card)).sort((a, b) => a - b)[0]; + const gainableCards = cards + .filter((card) => { + return ( + get.number(card) === minNumber && + lib.filter.canBeGained(card, player, target) + ); + }) + .randomSort(); + toGain.push(gainableCards[0]); + } + if (toGain.length) await player.gain(toGain, "giveAuto"); + await game.asyncDelayx(); + }, + ai: { + threaten: 5.8, + }, + mod: { + aiOrder(player, card, num) { + if ( + num > 0 && + get.itemtype(card) === "card" && + card.hasGaintag("dczhimin_tag") && + player.countCards("h", (cardx) => { + return cardx.hasGaintag("dczhimin_tag") && cardx !== card; + }) < player.maxHp + ) + return num / 10; + }, + }, + subSkill: { + mark: { + audio: "dczhimin", + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", + }, + forced: true, + filter(event, player) { + if ( + _status.currentPhase === player || + !event + .getg(player) + .some((card) => get.position(card) === "h" && get.owner(card) === player) + ) + return false; + return true; + }, + async content(event, trigger, player) { + player.addGaintag( + trigger + .getg(player) + .filter( + (card) => get.position(card) === "h" && get.owner(card) === player + ), + "dczhimin_tag" + ); + }, + }, + draw: { + audio: "dczhimin", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + forced: true, + filter(event, player) { + const evt = event.getl(player); + if (!evt.hs.length) return false; + return Object.values(evt.gaintag_map).flat().includes("dczhimin_tag"); + }, + async content(event, trigger, player) { + const count = player.maxHp - player.countCards("h"); + if (count <= 0) return; + await player.draw(count); + }, + }, + }, + }, + dcjujian: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuSkill: true, + filter(event, player) { + return game.hasPlayer((current) => { + return ( + player.hasZhuSkill("dcjujian", current) && + current.group === "wei" && + current !== player + ); + }); + }, + filterTarget(_, player, target) { + return ( + player.hasZhuSkill("dcjujian", target) && target.group === "wei" && target !== player + ); + }, + async content(event, trigger, player) { const target = event.targets[0]; await target.draw(); - target.addTempSkill('dcjujian_forbid', 'roundStart'); - target.markAuto('dcjujian_forbid', player); + target.addTempSkill("dcjujian_forbid", "roundStart"); + target.markAuto("dcjujian_forbid", player); }, - ai:{ - result:{ - target(player,target){ - const num=target.countCards('hs',card=>{ - return get.type(card)=='trick'&&target.canUse(card,player)&&get.effect(player,card,target,player)<-2; - }),att=get.attitude(player,target); - if(att<0) return -0.74*num; + ai: { + result: { + target(player, target) { + const num = target.countCards("hs", (card) => { + return ( + get.type(card) == "trick" && + target.canUse(card, player) && + get.effect(player, card, target, player) < -2 + ); + }), + att = get.attitude(player, target); + if (att < 0) return -0.74 * num; return 1.5; }, }, }, - subSkill:{ - forbid:{ - audio:'dcjujian', - trigger:{ - player:'useCardToBefore', + subSkill: { + forbid: { + audio: "dcjujian", + trigger: { + player: "useCardToBefore", }, - filter(event,player){ - if(get.type(event.card)!=='trick') return false; - return player.getStorage('dcjujian_forbid').includes(event.target); + filter(event, player) { + if (get.type(event.card) !== "trick") return false; + return player.getStorage("dcjujian_forbid").includes(event.target); }, - forced:true, - charlotte:true, - onremove:true, - direct:true, - async content(event,trigger,player){ - await trigger.target.logSkill('dcjujian_forbid', player); + forced: true, + charlotte: true, + onremove: true, + direct: true, + async content(event, trigger, player) { + await trigger.target.logSkill("dcjujian_forbid", player); trigger.cancel(); }, - intro:{ - content:'使用普通锦囊牌对$无效', + intro: { + content: "使用普通锦囊牌对$无效", }, - ai:{ - effect:{ - player(card,player,target,current){ - if(get.type(card)=='trick'&&player.getStorage('dcjujian_forbid').includes(target)) return 'zeroplayertarget'; + ai: { + effect: { + player(card, player, target, current) { + if ( + get.type(card) == "trick" && + player.getStorage("dcjujian_forbid").includes(target) + ) + return "zeroplayertarget"; }, }, }, @@ -261,331 +1068,426 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //谋司马懿 - dcsbquanmou:{ - audio:2, - audioname:['dc_sb_simayi_shadow'], - zhuanhuanji:true, - marktext:'☯', - enable:'phaseUse', - filter(event,player){ - const selected=player.getStorage('dcsbquanmou_selected'); - return game.hasPlayer(current=>!selected.includes(current)&&player.inRange(current)&¤t.countCards('he')>0); + dcsbquanmou: { + audio: 2, + audioname: ["dc_sb_simayi_shadow"], + zhuanhuanji: true, + marktext: "☯", + enable: "phaseUse", + filter(event, player) { + const selected = player.getStorage("dcsbquanmou_selected"); + return game.hasPlayer( + (current) => + !selected.includes(current) && + player.inRange(current) && + current.countCards("he") > 0 + ); }, - filterTarget(card,player,target){ - if(player===target) return false; - const selected=player.getStorage('dcsbquanmou_selected'); - return !selected.includes(target)&&player.inRange(target)&&target.countCards('he')>0; + filterTarget(card, player, target) { + if (player === target) return false; + const selected = player.getStorage("dcsbquanmou_selected"); + return ( + !selected.includes(target) && player.inRange(target) && target.countCards("he") > 0 + ); }, - prompt(){ + prompt() { const player = get.player(); - if(player.storage.dcsbquanmou) return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。'; - return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害时,取消之。'; + if (player.storage.dcsbquanmou) + return "转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。"; + return "转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害时,取消之。"; }, - async content(event,trigger,player){ + async content(event, trigger, player) { const target = event.targets[0]; - player.changeZhuanhuanji('dcsbquanmou'); - player.changeSkin('dcsbquanmou','dc_sb_simayi'+(player.storage.dcsbquanmou?'_shadow':'')); - player.markAuto('dcsbquanmou_selected', [target]); - const cards = await target.chooseCard('he', true, `选择交给${get.translation(player)}一张牌`).forResultCards(); + player.changeZhuanhuanji("dcsbquanmou"); + player.changeSkin( + "dcsbquanmou", + "dc_sb_simayi" + (player.storage.dcsbquanmou ? "_shadow" : "") + ); + player.markAuto("dcsbquanmou_selected", [target]); + const cards = await target + .chooseCard("he", true, `选择交给${get.translation(player)}一张牌`) + .forResultCards(); if (cards && cards.length) { await target.give(cards, player); const key = `dcsbquanmou_${Boolean(!player.storage.dcsbquanmou)}`; - player.addTempSkill(key, {global:['phaseUseBefore','phaseChange']}); + player.addTempSkill(key, { global: ["phaseUseBefore", "phaseChange"] }); player.markAuto(key, [target]); target.addAdditionalSkill(`${key}_${player.playerid}`, `${key}_mark`); } }, - ai:{ - order:9, - result:{ - player:function(player,target){ - if(player.storage.dcsbquanmou) return 1; - return 1+game.countPlayer(i=>player!==i&&target!==i&&!i.hasSkill('false_mark')&&get.attitude(player,i)<0); + ai: { + order: 9, + result: { + player: function (player, target) { + if (player.storage.dcsbquanmou) return 1; + return ( + 1 + + game.countPlayer( + (i) => + player !== i && + target !== i && + !i.hasSkill("false_mark") && + get.attitude(player, i) < 0 + ) + ); }, - target:function(player,target){ - let res=target.hasSkillTag('noh')?0:-1; - if(player.storage.dcsbquanmou) return res+0.6; + target: function (player, target) { + let res = target.hasSkillTag("noh") ? 0 : -1; + if (player.storage.dcsbquanmou) return res + 0.6; return res; }, }, }, - onremove:true, - mark:true, - intro:{ - content:(storage)=>{ - if(storage) return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。'; - return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害时,取消之。'; - } + onremove: true, + mark: true, + intro: { + content: (storage) => { + if (storage) + return "转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。"; + return "转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。当你于本阶段内下次对其造成伤害时,取消之。"; + }, }, - subSkill:{ - true:{ - charlotte:true, - audio:'dcsbquanmou', - audioname:['dc_sb_simayi_shadow'], - trigger:{source:'damageSource'}, - forced:true, - popup:false, - filter(event,player){ - return player.getStorage('dcsbquanmou_true').includes(event.player); + subSkill: { + true: { + charlotte: true, + audio: "dcsbquanmou", + audioname: ["dc_sb_simayi_shadow"], + trigger: { source: "damageSource" }, + forced: true, + popup: false, + filter(event, player) { + return player.getStorage("dcsbquanmou_true").includes(event.player); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const target = trigger.player; - player.getStorage('dcsbquanmou_true').remove(target); + player.getStorage("dcsbquanmou_true").remove(target); target.removeAdditionalSkill(`dcsbquanmou_true_${player.playerid}`); - if(game.hasPlayer(current => (current != player && current != target))){ - const result = await player.chooseTarget([1,3], `权谋:是否对${get.translation(target)}之外的至多三名其他角色各造成1点伤害?`, (card, player, target)=>{ - return target != player && target != get.event().getTrigger().player; - }).set('ai',target => { - const player = get.player(); - return get.damageEffect(target, player, player); - }).forResult(); + if (game.hasPlayer((current) => current != player && current != target)) { + const result = await player + .chooseTarget( + [1, 3], + `权谋:是否对${get.translation( + target + )}之外的至多三名其他角色各造成1点伤害?`, + (card, player, target) => { + return ( + target != player && target != get.event().getTrigger().player + ); + } + ) + .set("ai", (target) => { + const player = get.player(); + return get.damageEffect(target, player, player); + }) + .forResult(); if (result.bool) { - await player.logSkill('dcsbquanmou', result.targets); - for(let i of result.targets){ - if(i.isIn()) await i.damage(); + await player.logSkill("dcsbquanmou", result.targets); + for (let i of result.targets) { + if (i.isIn()) await i.damage(); } } } }, - onremove(player,skill){ - game.filterPlayer(current=>{ + onremove(player, skill) { + game.filterPlayer((current) => { current.removeAdditionalSkill(`${skill}_${player.playerid}`); }); delete player.storage[skill]; delete player.storage.dcsbquanmou_selected; }, }, - true_mark:{ - charlotte:true, - mark:true, - marktext:'讨', - intro:{ - name:'权谋 - 阳', - content:()=>{ - return `当你下次受到${get.translation(_status.currentPhase)}造成的伤害后,其可以对除你之外的至多三名其他角色各造成1点伤害。` + true_mark: { + charlotte: true, + mark: true, + marktext: "讨", + intro: { + name: "权谋 - 阳", + content: () => { + return `当你下次受到${get.translation( + _status.currentPhase + )}造成的伤害后,其可以对除你之外的至多三名其他角色各造成1点伤害。`; }, }, - ai:{ - threaten:2.5, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')&&player&&player.hasSkill('dcsbquanmou_true')){ - let tars=game.countPlayer(i=>player!==i&&target!==i&&get.attitude(player,target)<0&&!target.hasSkill('dcsbquanmou_false_mark')); - return [1,0,1,6*Math.min(3,tars)/(3+Math.pow(target.countCards('h'),2))]; + ai: { + threaten: 2.5, + effect: { + target(card, player, target) { + if ( + get.tag(card, "damage") && + player && + player.hasSkill("dcsbquanmou_true") + ) { + let tars = game.countPlayer( + (i) => + player !== i && + target !== i && + get.attitude(player, target) < 0 && + !target.hasSkill("dcsbquanmou_false_mark") + ); + return [ + 1, + 0, + 1, + (6 * Math.min(3, tars)) / + (3 + Math.pow(target.countCards("h"), 2)), + ]; } - } - } + }, + }, }, }, - false:{ - charlotte:true, - audio:'dcsbquanmou', - audioname:['dc_sb_simayi_shadow'], - trigger:{source:'damageBegin2'}, - forced:true, - filter(event,player){ - return player.getStorage('dcsbquanmou_false').includes(event.player); + false: { + charlotte: true, + audio: "dcsbquanmou", + audioname: ["dc_sb_simayi_shadow"], + trigger: { source: "damageBegin2" }, + forced: true, + filter(event, player) { + return player.getStorage("dcsbquanmou_false").includes(event.player); }, - async content(event, trigger, player){ + async content(event, trigger, player) { const target = trigger.player; - player.getStorage('dcsbquanmou_false').remove(target); + player.getStorage("dcsbquanmou_false").remove(target); target.removeAdditionalSkill(`dcsbquanmou_false_${player.playerid}`); trigger.cancel(); }, - onremove(player,skill){ - game.filterPlayer(current=>{ + onremove(player, skill) { + game.filterPlayer((current) => { current.removeAdditionalSkill(`${skill}_${player.playerid}`); }); delete player.storage[skill]; delete player.storage.dcsbquanmou_selected; }, }, - false_mark:{ - charlotte:true, - mark:true, - marktext:'抚', - intro:{ - name:'权谋 - 阴', - content:()=>{ - return `当你下次受到${get.translation(_status.currentPhase)}造成的伤害时,防止此伤害。` + false_mark: { + charlotte: true, + mark: true, + marktext: "抚", + intro: { + name: "权谋 - 阴", + content: () => { + return `当你下次受到${get.translation( + _status.currentPhase + )}造成的伤害时,防止此伤害。`; }, }, - ai:{ - nodamage:true, - nofire:true, - nothunder:true, - skillTagFilter(player,tag,arg){ - return (arg&&arg.player&&arg.player.hasSkill('dcsbquanmou_false')); + ai: { + nodamage: true, + nofire: true, + nothunder: true, + skillTagFilter(player, tag, arg) { + return arg && arg.player && arg.player.hasSkill("dcsbquanmou_false"); + }, + effect: { + target(card, player, target) { + if ( + get.tag(card, "damage") && + player && + player.hasSkill("dcsbquanmou_false") + ) + return "zeroplayertarget"; + }, }, - effect:{ - target(card,player,target){ - if(get.tag(card,'damage')&&player&&player.hasSkill('dcsbquanmou_false')) return 'zeroplayertarget'; - } - } }, }, }, }, - dcsbpingliao:{ - audio:2, - audioname:['dc_sb_simayi_shadow'], - trigger:{player:'useCard'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'; + dcsbpingliao: { + audio: 2, + audioname: ["dc_sb_simayi_shadow"], + trigger: { player: "useCard" }, + forced: true, + filter(event, player) { + return event.card.name == "sha"; }, - logTarget(event,player){ - return game.filterPlayer(current=>player.inRange(current)); + logTarget(event, player) { + return game.filterPlayer((current) => player.inRange(current)); }, async content(event, trigger, player) { const unrespondedTargets = []; const respondedTargets = []; let nonnonTargetResponded = false; const targets = game.filterPlayer().sortBySeat(); - const prompt = `###是否打出红色基本牌响应${get.translation(player)}?###${get.translation(player)}使用了一张不公开目标的${get.translation(trigger.card)}。若你选择响应且你不是此牌的隐藏目标,则其摸两张牌;若你选择不响应且你是此牌的隐藏目标,则你本回合内不能使用或打出手牌。` + const prompt = `###是否打出红色基本牌响应${get.translation(player)}?###${get.translation( + player + )}使用了一张不公开目标的${get.translation( + trigger.card + )}。若你选择响应且你不是此牌的隐藏目标,则其摸两张牌;若你选择不响应且你是此牌的隐藏目标,则你本回合内不能使用或打出手牌。`; for (let target of targets) { if (target.isIn() && player.inRange(target)) { - const result = await target.chooseToRespond(prompt, (card,player)=>{ - if (get.type(card) !== 'basic') return false; - const color = get.color(card); - return (color == 'red' || color == 'unsure'); - }).set('ai',card => { - const player = get.player(), event = get.event(); - const source = event.getParent().player; - //是队友且没有其他疑似队友的选手响应 那响应一下 - if (get.attitude(player,source) > 0){ - if(!event.respondedTargets.some(current => { - return get.attitude(player, current) > 0 || get.attitude(source, current) >= 0; - })) return get.order(card); - return -1; - } - //如果自己没有其他的闪桃就不响应 - else { - const needsTao = (player.hp <= 1); - const shanAndTao = player.getCards('hs', card=>{ - const name = get.name(card); - return name == 'shan' || (needsTao && name == 'shan'); - }); - shanAndTao.remove(card); - if(card.cards) shanAndTao.removeArray(card.cards); - if(!shanAndTao.length) return 0; - } - return event.getRand('dcsbpingliao') > (1 / Math.max(1,player.hp)) ? 0 : get.order(card); - }).set('respondedTargets', respondedTargets).forResult(); + const result = await target + .chooseToRespond(prompt, (card, player) => { + if (get.type(card) !== "basic") return false; + const color = get.color(card); + return color == "red" || color == "unsure"; + }) + .set("ai", (card) => { + const player = get.player(), + event = get.event(); + const source = event.getParent().player; + //是队友且没有其他疑似队友的选手响应 那响应一下 + if (get.attitude(player, source) > 0) { + if ( + !event.respondedTargets.some((current) => { + return ( + get.attitude(player, current) > 0 || + get.attitude(source, current) >= 0 + ); + }) + ) + return get.order(card); + return -1; + } + //如果自己没有其他的闪桃就不响应 + else { + const needsTao = player.hp <= 1; + const shanAndTao = player.getCards("hs", (card) => { + const name = get.name(card); + return name == "shan" || (needsTao && name == "shan"); + }); + shanAndTao.remove(card); + if (card.cards) shanAndTao.removeArray(card.cards); + if (!shanAndTao.length) return 0; + } + return event.getRand("dcsbpingliao") > 1 / Math.max(1, player.hp) + ? 0 + : get.order(card); + }) + .set("respondedTargets", respondedTargets) + .forResult(); if (result.bool) { respondedTargets.push(target); - if(!trigger.targets.includes(target)) nonnonTargetResponded = true; + if (!trigger.targets.includes(target)) nonnonTargetResponded = true; await game.asyncDelay(); - } - else if (trigger.targets.includes(target)) unrespondedTargets.push(target); + } else if (trigger.targets.includes(target)) unrespondedTargets.push(target); } } - unrespondedTargets.forEach(current => { - current.addTempSkill('dcsbpingliao_blocker'); - game.log(current,'本回合内无法使用或打出手牌'); + unrespondedTargets.forEach((current) => { + current.addTempSkill("dcsbpingliao_blocker"); + game.log(current, "本回合内无法使用或打出手牌"); }); if (nonnonTargetResponded) { player.draw(2); - player.addTempSkill('dcsbpingliao_buff', {global:'phaseChange'}); - player.addMark('dcsbpingliao_buff',1,false); + player.addTempSkill("dcsbpingliao_buff", { global: "phaseChange" }); + player.addMark("dcsbpingliao_buff", 1, false); } }, - ai:{ - ignoreLogAI:true, - skillTagFilter:function(player,tag,args){ - if(args){ - return args.card&&get.name(args.card)=='sha'; + ai: { + ignoreLogAI: true, + skillTagFilter: function (player, tag, args) { + if (args) { + return args.card && get.name(args.card) == "sha"; } }, }, - group:'dcsbpingliao_hide', - subSkill:{ - hide:{ - trigger:{player:'useCard0'}, - forced:true, - filter(event,player){ - return event.card.name=='sha'; + group: "dcsbpingliao_hide", + subSkill: { + hide: { + trigger: { player: "useCard0" }, + forced: true, + filter(event, player) { + return event.card.name == "sha"; }, - async content(event, trigger, player){ + async content(event, trigger, player) { trigger.hideTargets = true; - game.log(player,'隐藏了',trigger.card,'的目标'); + game.log(player, "隐藏了", trigger.card, "的目标"); }, }, - buff:{ - onremove:true, - charlotte:true, - mod:{ - cardUsable(card, player, num){ - if(card.name=='sha') return num + player.countMark('dcsbpingliao_buff'); - } + buff: { + onremove: true, + charlotte: true, + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + player.countMark("dcsbpingliao_buff"); + }, }, - mark:true, - intro:{ - content:'本阶段内使用【杀】的次数上限+#', + mark: true, + intro: { + content: "本阶段内使用【杀】的次数上限+#", }, }, - blocker:{ - charlotte:true, - mod:{ - cardEnabled2(card, player){ - if(player.getCards('h').includes(card)) return false; - } + blocker: { + charlotte: true, + mod: { + cardEnabled2(card, player) { + if (player.getCards("h").includes(card)) return false; + }, }, - mark:true, - marktext:'封', - intro:{ - content:'本回合内不能使用或打出手牌', + mark: true, + marktext: "封", + intro: { + content: "本回合内不能使用或打出手牌", }, }, }, }, //陈武董袭 - dcduanxie:{ - audio:'duanxie', - inherit:'duanxie', - selectTarget:1, + dcduanxie: { + audio: "duanxie", + inherit: "duanxie", + selectTarget: 1, }, //吕范 - diaodu:{ - audio:2, - trigger:{player:['phaseUseBegin','logSkill']}, - filter(event,player){ - if(event.name=='logSkill'&&event.skill!='diancai') return false; - return game.hasPlayer(target=>{ - return get.distance(player,target)<=1&&target.countGainableCards(player,'e'); + diaodu: { + audio: 2, + trigger: { player: ["phaseUseBegin", "logSkill"] }, + filter(event, player) { + if (event.name == "logSkill" && event.skill != "diancai") return false; + return game.hasPlayer((target) => { + return get.distance(player, target) <= 1 && target.countGainableCards(player, "e"); }); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt2('diaodu'),(card,player,target)=>{ - return get.distance(player,target)<=1&&target.countGainableCards(player,'e'); - }).set('ai',target=>{ - const player=get.event('player'),att=get.attitude(player,target); - let num=0; - if(target.hasSkill('gzxiaoji')) num+=2.5; - if(target.isDamaged()&&target.getEquip('baiyin')) num+=2.5; - if(target.hasSkill('xuanlve')) num+=2; - return get.sgn(att)*num+(target==player?1:0); - }); - if(bool){ - const aim=targets[0]; - player.logSkill('diaodu',aim); - const {result:{bool,cards}}=await player.gainPlayerCard(aim,'e',true); - if(bool&&game.hasPlayer(target=>target!=aim)){ - const card=cards[0]; - const {result:{bool,targets}}=await player.chooseTarget('调度:将'+get.translation(card)+'交给另一名角色',(card,player,target)=>{ - return target!=get.event('aim'); - },true).set('ai',target=>{ - const player=get.event('player'); - return get.attitude(player,target); - }).set('aim',aim); - if(bool&&get.owner(card)==player){ - const target=targets[0]; - player.line(target,'green'); - if(target!=player) await player.give([card],target); - if(get.owner(card)==target){ - const {result:{bool}}=await target.chooseUseTarget(card); - if(bool) await player.draw(); + direct: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget(get.prompt2("diaodu"), (card, player, target) => { + return ( + get.distance(player, target) <= 1 && target.countGainableCards(player, "e") + ); + }) + .set("ai", (target) => { + const player = get.event("player"), + att = get.attitude(player, target); + let num = 0; + if (target.hasSkill("gzxiaoji")) num += 2.5; + if (target.isDamaged() && target.getEquip("baiyin")) num += 2.5; + if (target.hasSkill("xuanlve")) num += 2; + return get.sgn(att) * num + (target == player ? 1 : 0); + }); + if (bool) { + const aim = targets[0]; + player.logSkill("diaodu", aim); + const { + result: { bool, cards }, + } = await player.gainPlayerCard(aim, "e", true); + if (bool && game.hasPlayer((target) => target != aim)) { + const card = cards[0]; + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "调度:将" + get.translation(card) + "交给另一名角色", + (card, player, target) => { + return target != get.event("aim"); + }, + true + ) + .set("ai", (target) => { + const player = get.event("player"); + return get.attitude(player, target); + }) + .set("aim", aim); + if (bool && get.owner(card) == player) { + const target = targets[0]; + player.line(target, "green"); + if (target != player) await player.give([card], target); + if (get.owner(card) == target) { + const { + result: { bool }, + } = await target.chooseUseTarget(card); + if (bool) await player.draw(); else await target.draw(); } } @@ -593,441 +1495,627 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, }, - diancai:{ - audio:2, - inherit:'mbdiancai', - filter(event,player){ - if(_status.currentPhase===player) return false; - let num=player.getHistory('lose',evt=>{ - return evt.cards2&&evt.cards2.length&&evt.getParent('phaseUse')==event; - }).reduce((sum,evt)=>{ - return sum+evt.cards2.length; - },0); - return num>=Math.min(5,player.getHp()); + diancai: { + audio: 2, + inherit: "mbdiancai", + filter(event, player) { + if (_status.currentPhase === player) return false; + let num = player + .getHistory("lose", (evt) => { + return evt.cards2 && evt.cards2.length && evt.getParent("phaseUse") == event; + }) + .reduce((sum, evt) => { + return sum + evt.cards2.length; + }, 0); + return num >= Math.min(5, player.getHp()); }, }, //崔琰毛玠 - zhengbi:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter(event,player){ - return game.hasPlayer(target=>target!=player); + zhengbi: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter(event, player) { + return game.hasPlayer((target) => target != player); }, - direct:true, - async content(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt2('zhengbi'),lib.filter.notMe).set('ai',target=>{ - const player=get.event('player'); - return -get.attitude(player,target)*target.countCards('he'); - }); - if(bool){ - const target=targets[0],str=get.translation(target); - player.logSkill('zhengbi',target); - let choiceList=['此阶段结束时,若'+str+'本阶段获得过牌,则你获得其手牌区和装备区各一张牌']; - if(player.countCards('h',{type:'basic'})) choiceList.push('交给'+str+'一张基本牌,然后其交给你一张非基本牌或两张基本牌'); - const {result:{index}}=await player.chooseControl().set('choiceList',choiceList).set('ai',()=>get.event('controls').length-1); - if(index==0){ + direct: true, + async content(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget(get.prompt2("zhengbi"), lib.filter.notMe) + .set("ai", (target) => { + const player = get.event("player"); + return -get.attitude(player, target) * target.countCards("he"); + }); + if (bool) { + const target = targets[0], + str = get.translation(target); + player.logSkill("zhengbi", target); + let choiceList = [ + "此阶段结束时,若" + str + "本阶段获得过牌,则你获得其手牌区和装备区各一张牌", + ]; + if (player.countCards("h", { type: "basic" })) + choiceList.push( + "交给" + str + "一张基本牌,然后其交给你一张非基本牌或两张基本牌" + ); + const { + result: { index }, + } = await player + .chooseControl() + .set("choiceList", choiceList) + .set("ai", () => get.event("controls").length - 1); + if (index == 0) { player.line(target); - player.when('phaseUseEnd').filter(evt=>evt==trigger).then(()=>{ - if(target.isIn()&&target.getHistory('gain',evt=>evt.getParent('phaseUse')==trigger).length){ - player.line(target); - let num=(target.countGainableCards(player,'h')>0)+(target.countGainableCards(player,'e')>0); - if(num){ - player.gainPlayerCard(target,num,'he',true).set('filterButton',button=>{ - return !ui.selected.buttons.some(but=>get.position(button.link)==get.position(but.link)); - }); - } - } - }).vars({target:target}); - } - else{ - const {result:{bool}}=await player.chooseToGive(target,{type:'basic'},true).set('prompt','征辟:交给'+str+'一张基本牌'); - if(bool){ - let choices=[]; - if(target.countCards('he',{type:['trick','delay','equip']})) choices.push('一张非基本牌'); - if(target.countCards('h',{type:'basic'})>1) choices.push('两张基本牌'); - if(choices.length){ - const {result:{control}}=await target.chooseControl(choices).set('ai',function(event,player){ - if(choices.length>1){ - if(player.countCards('he',{type:['trick','delay','equip']},function(card){return get.value(card)<7})) return 0; - return 1; + player + .when("phaseUseEnd") + .filter((evt) => evt == trigger) + .then(() => { + if ( + target.isIn() && + target.getHistory( + "gain", + (evt) => evt.getParent("phaseUse") == trigger + ).length + ) { + player.line(target); + let num = + (target.countGainableCards(player, "h") > 0) + + (target.countGainableCards(player, "e") > 0); + if (num) { + player + .gainPlayerCard(target, num, "he", true) + .set("filterButton", (button) => { + return !ui.selected.buttons.some( + (but) => + get.position(button.link) == + get.position(but.link) + ); + }); } - return 0; - }).set('prompt','征辟:交给'+get.translation(player)+'…'); - const check=(control=='一张非基本牌'); - await target.chooseToGive('he',(check?1:2),{type:(check?['trick','delay','equip']:'basic')},player,true).set('prompt','征辟:交给'+get.translation(player)+control); - } - else if(target.countCards('h')) await target.give(target.getCards('h'),player); + } + }) + .vars({ target: target }); + } else { + const { + result: { bool }, + } = await player + .chooseToGive(target, { type: "basic" }, true) + .set("prompt", "征辟:交给" + str + "一张基本牌"); + if (bool) { + let choices = []; + if (target.countCards("he", { type: ["trick", "delay", "equip"] })) + choices.push("一张非基本牌"); + if (target.countCards("h", { type: "basic" }) > 1) choices.push("两张基本牌"); + if (choices.length) { + const { + result: { control }, + } = await target + .chooseControl(choices) + .set("ai", function (event, player) { + if (choices.length > 1) { + if ( + player.countCards( + "he", + { type: ["trick", "delay", "equip"] }, + function (card) { + return get.value(card) < 7; + } + ) + ) + return 0; + return 1; + } + return 0; + }) + .set("prompt", "征辟:交给" + get.translation(player) + "…"); + const check = control == "一张非基本牌"; + await target + .chooseToGive( + "he", + check ? 1 : 2, + { type: check ? ["trick", "delay", "equip"] : "basic" }, + player, + true + ) + .set("prompt", "征辟:交给" + get.translation(player) + control); + } else if (target.countCards("h")) + await target.give(target.getCards("h"), player); } } } }, }, - fengying:{ - unique:true, - limited:true, - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.countCards('h')&&player.countCards('h')==player.countDiscardableCards(player,'h'); + fengying: { + unique: true, + limited: true, + audio: 2, + enable: "phaseUse", + filter(event, player) { + return ( + player.countCards("h") && + player.countCards("h") == player.countDiscardableCards(player, "h") + ); }, - skillAnimation:true, - animationColor:'thunder', - async content(event,trigger,player){ - player.awakenSkill('fengying'); - await player.discard(player.getCards('h')); - const evt=player.insertPhase(); - player.when('phaseBegin').filter(evtx=>evtx==evt).then(()=>{ - if(player.isMinHp()&&player.maxHp>0&&player.countCards('h') evtx == evt) + .then(() => { + if ( + player.isMinHp() && + player.maxHp > 0 && + player.countCards("h") < player.maxHp + ) { + player.drawTo(player.maxHp); + } + }); }, - ai:{ - order:0.0001, - result:{ - player(player){ - return player.isMinHp()?1:0; + ai: { + order: 0.0001, + result: { + player(player) { + return player.isMinHp() ? 1 : 0; }, }, }, }, //胡遵 - dczhantao:{ - audio:2, - trigger:{global:'damageEnd'}, - filter(event,player){ - if(!event.player.isIn()||(event.player!==player&&!player.inRange(event.player))) return false; - return event.source&&event.source!=player; + dczhantao: { + audio: 2, + trigger: { global: "damageEnd" }, + filter(event, player) { + if (!event.player.isIn() || (event.player !== player && !player.inRange(event.player))) + return false; + return event.source && event.source != player; }, - check(event,player){ - if(!event.source.isIn()||!event.card||typeof get.number(event.card)!=='number') return 0; - return get.effect(event.source,{name:'sha'},player,player)>=0; - }, - logTarget:'player', - async content(event,trigger,player){ - player.judge(card=>{ - const evt=get.event().getParent(get.event('eventName')).getTrigger(); - if(!evt.source.isIn()||!evt.card||typeof get.number(evt.card)!=='number') return 0; - if(get.number(card)>get.number(evt.card)) return 1.5; + check(event, player) { + if (!event.source.isIn() || !event.card || typeof get.number(event.card) !== "number") return 0; - }).set('judge2',r=>r.bool).set('callback',()=>{ - const evtx=event.getParent(); - const evt=event.getParent(evtx.eventName).getTrigger(); - if(!evt.source.isIn()||!evt.card||typeof get.number(evt.card)!=='number') return; - if(event.judgeResult.number>get.number(evt.card)){ - const sha=new lib.element.VCard({name:'sha'}),target=evt.source; - if(player.canUse(sha,target,false,false)){ - player.useCard(sha,target,false); - } - } - }) - .set('eventName',event.name) - } - }, - dcanjing:{ - audio:2, - trigger:{source:'damageSource'}, - filter(event,player){ - return game.hasPlayer(current=>current.isDamaged()); + return get.effect(event.source, { name: "sha" }, player, player) >= 0; }, - usable:1, - direct:true, - async content(event,trigger,player){ - const maxCount=player.getAllHistory('useSkill',evt=>evt.skill==='dcanjing').length+1; - const result=await player.chooseTarget(get.prompt2('dcanjing'),(card,player,target)=>target.isDamaged(),[1,maxCount]) - .set('ai',target=>{ - return get.attitude(get.player(),target)>0; + logTarget: "player", + async content(event, trigger, player) { + player + .judge((card) => { + const evt = get.event().getParent(get.event("eventName")).getTrigger(); + if (!evt.source.isIn() || !evt.card || typeof get.number(evt.card) !== "number") + return 0; + if (get.number(card) > get.number(evt.card)) return 1.5; + return 0; + }) + .set("judge2", (r) => r.bool) + .set("callback", () => { + const evtx = event.getParent(); + const evt = event.getParent(evtx.eventName).getTrigger(); + if (!evt.source.isIn() || !evt.card || typeof get.number(evt.card) !== "number") + return; + if (event.judgeResult.number > get.number(evt.card)) { + const sha = new lib.element.VCard({ name: "sha" }), + target = evt.source; + if (player.canUse(sha, target, false, false)) { + player.useCard(sha, target, false); + } + } + }) + .set("eventName", event.name); + }, + }, + dcanjing: { + audio: 2, + trigger: { source: "damageSource" }, + filter(event, player) { + return game.hasPlayer((current) => current.isDamaged()); + }, + usable: 1, + direct: true, + async content(event, trigger, player) { + const maxCount = + player.getAllHistory("useSkill", (evt) => evt.skill === "dcanjing").length + 1; + const result = await player + .chooseTarget(get.prompt2("dcanjing"), (card, player, target) => target.isDamaged(), [ + 1, + maxCount, + ]) + .set("ai", (target) => { + return get.attitude(get.player(), target) > 0; }) .forResult(); - if(!result.bool) return player.storage.counttrigger.dcanjing--; - const targets=result.targets.slice(); + if (!result.bool) return player.storage.counttrigger.dcanjing--; + const targets = result.targets.slice(); targets.sortBySeat(_status.currentPhase); - player.logSkill('dcanjing',targets); - for(const target of targets) await target.draw(); - const minHp=targets.map(i=>i.getHp()).sort((a,b)=>a-b)[0]; + player.logSkill("dcanjing", targets); + for (const target of targets) await target.draw(); + const minHp = targets.map((i) => i.getHp()).sort((a, b) => a - b)[0]; await game.asyncDelayx(); - for(const target of targets){ - if(!target.isIn()) continue; - if(target.getHp()===minHp) await target.recover(); + for (const target of targets) { + if (!target.isIn()) continue; + if (target.getHp() === minHp) await target.recover(); } - } + }, }, //诸葛梦雪 - dcjichun:{ - audio:2, - enable:'phaseUse', - filter(event,player){ - return player.countCards('he',card=>lib.skill.dcjichun.filterCard(card,player)); + dcjichun: { + audio: 2, + enable: "phaseUse", + filter(event, player) { + return player.countCards("he", (card) => lib.skill.dcjichun.filterCard(card, player)); }, - filterCard(card,player){ - if(!get.cardNameLength(card)||ui.selected.cards.length) return false; - if(game.hasPlayer(target=>{ - return target.countCards('h'){ - return target.countCards('h')>player.countCards('h')&&target.countDiscardableCards(player,'hej'); - })) return true; + filterCard(card, player) { + if (!get.cardNameLength(card) || ui.selected.cards.length) return false; + if ( + game.hasPlayer((target) => { + return target.countCards("h") < player.countCards("h"); + }) + ) + return true; + if ( + lib.filter.cardDiscardable(card, player) && + game.hasPlayer((target) => { + return ( + target.countCards("h") > player.countCards("h") && + target.countDiscardableCards(player, "hej") + ); + }) + ) + return true; return false; }, - selectCard:[1,2], - filterTarget(cardx,player,target){ - if(!ui.selected.cards.length) return false; - const card=ui.selected.cards[0]; - if(target.countCards('h')player.countCards('h')&&target.countDiscardableCards(player,'hej')) return true; + selectCard: [1, 2], + filterTarget(cardx, player, target) { + if (!ui.selected.cards.length) return false; + const card = ui.selected.cards[0]; + if (target.countCards("h") < player.countCards("h")) return true; + if ( + lib.filter.cardDiscardable(card, player) && + target.countCards("h") > player.countCards("h") && + target.countDiscardableCards(player, "hej") + ) + return true; return false; }, - usable:1, - position:'he', - check(card){ + usable: 1, + position: "he", + check(card) { return get.cardNameLength(card); }, - complexCard:true, - complexSelect:true, - lose:false, - discard:false, - delay:false, - targetprompt(){ - const target=ui.selected.targets[0],player=get.event('player'); - return target.countCards('h')get.type(card)=='equip'&&!get.cardtag(card,'gifts')); - if(!card){ - player.chat('无牌可得?!'); - game.log('但是牌堆已经没有装备牌了!'); + dchanying: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + frequent: true, + async content(event, trigger, player) { + const card = get.cardPile( + (card) => get.type(card) == "equip" && !get.cardtag(card, "gifts") + ); + if (!card) { + player.chat("无牌可得?!"); + game.log("但是牌堆已经没有装备牌了!"); return; } - await player.showCards([card],get.translation(player)+'发动了【寒英】'); - if(game.hasPlayer(target=>target.countCards('h')==player.countCards('h')&&target.hasUseTarget(card))){ - const {result:{bool,targets}}=await player.chooseTarget('请选择使用'+get.translation(card)+'的目标角色',(card,player,target)=>{ - return target.countCards('h')==player.countCards('h')&&target.hasUseTarget(get.event('card')); - },true).set('ai',target=>get.effect(target,get.event('card'),target,get.event('player'))).set('card',card); - if(bool){ - const target=targets[0]; + await player.showCards([card], get.translation(player) + "发动了【寒英】"); + if ( + game.hasPlayer( + (target) => + target.countCards("h") == player.countCards("h") && target.hasUseTarget(card) + ) + ) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "请选择使用" + get.translation(card) + "的目标角色", + (card, player, target) => { + return ( + target.countCards("h") == player.countCards("h") && + target.hasUseTarget(get.event("card")) + ); + }, + true + ) + .set("ai", (target) => + get.effect(target, get.event("card"), target, get.event("player")) + ) + .set("card", card); + if (bool) { + const target = targets[0]; player.line(target); - target.chooseUseTarget(card,true,'nopopup'); + target.chooseUseTarget(card, true, "nopopup"); } - } - else{ - player.chat('无人可装?!'); - game.log('但是场上没有角色可以使用',card,'!'); + } else { + player.chat("无人可装?!"); + game.log("但是场上没有角色可以使用", card, "!"); } }, }, //柏灵筠 - dclinghui:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - if(_status.currentPhase===player) return true; - return game.getGlobalHistory('everything',evt=>evt.name=='dying').length; + dclinghui: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + if (_status.currentPhase === player) return true; + return game.getGlobalHistory("everything", (evt) => evt.name == "dying").length; }, - frequent:true, - async content(event,trigger,player){ - let cards=get.cards(3); + frequent: true, + async content(event, trigger, player) { + let cards = get.cards(3); await game.cardsGotoOrdering(cards); - const {result:{bool,links}}=await player.chooseButton(['灵慧:是否使用其中的一张牌并随机获得其中一张剩余牌?',cards]).set('filterButton',button=>{ - return get.player().hasUseTarget(button.link); - }).set('ai',button=>{ - return get.event('player').getUseValue(button.link); - }); - if(bool){ - const card=links[0]; + const { + result: { bool, links }, + } = await player + .chooseButton(["灵慧:是否使用其中的一张牌并随机获得其中一张剩余牌?", cards]) + .set("filterButton", (button) => { + return get.player().hasUseTarget(button.link); + }) + .set("ai", (button) => { + return get.event("player").getUseValue(button.link); + }); + if (bool) { + const card = links[0]; cards.remove(card); - player.$gain2(card,false); + player.$gain2(card, false); await game.asyncDelayx(); - await player.chooseUseTarget(true,card,false); - cards=cards.filterInD(); - if(cards.length){ - const cardx=cards.randomRemove(); - await player.gain(cardx,'gain2'); + await player.chooseUseTarget(true, card, false); + cards = cards.filterInD(); + if (cards.length) { + const cardx = cards.randomRemove(); + await player.gain(cardx, "gain2"); } } - if(cards.length){ + if (cards.length) { cards.reverse(); - game.cardsGotoPile(cards.filterInD(),'insert'); - game.log(player,'将',get.cnNumber(cards.length),'张牌置于了牌堆顶'); + game.cardsGotoPile(cards.filterInD(), "insert"); + game.log(player, "将", get.cnNumber(cards.length), "张牌置于了牌堆顶"); } }, }, - dcxiace:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + dcxiace: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter(event,player){ - const bool1=(event.player==player&&!player.hasHistory('custom',evt=>evt.dcxiace=='player')&&game.hasPlayer(target=>target!=player&&!target.hasSkill('fengyin'))); - const bool2=(event.source&&event.source==player&&!player.hasHistory('custom',evt=>evt.dcxiace=='source')&&player.isDamaged()&&player.countCards('he',card=>{ - if(_status.connectMode&&get.position(card)=='h') return true; - return lib.filter.cardDiscardable(card,player); - })); - return bool1||bool2; - }, - direct:true, - async content(event,trigger,player){ - if(trigger.player==player&&!player.hasHistory('custom',evt=>evt.dcxiace=='player')&&game.hasPlayer(target=>target!=player&&!target.hasSkill('fengyin'))){ - const {result:{bool,targets}}=await player.chooseTarget((card,player,target)=>{ - return target!=player&&!target.hasSkill('fengyin'); - }).set('prompt',get.prompt('dcxiace')).set('prompt2','令一名其他角色的非锁定技于本回合失效') - .set('ai',target=>{ - const player=get.event('player'); - return -get.sgn(get.attitude(player,target))*(target.getSkills(null,false,false).filter(skill=>{ - return !get.is.locked(skill); - }).length+1)*(target===_status.currentPhase?10:1); + filter(event, player) { + const bool1 = + event.player == player && + !player.hasHistory("custom", (evt) => evt.dcxiace == "player") && + game.hasPlayer((target) => target != player && !target.hasSkill("fengyin")); + const bool2 = + event.source && + event.source == player && + !player.hasHistory("custom", (evt) => evt.dcxiace == "source") && + player.isDamaged() && + player.countCards("he", (card) => { + if (_status.connectMode && get.position(card) == "h") return true; + return lib.filter.cardDiscardable(card, player); }); - if(bool){ - const target=targets[0]; - player.logSkill('dcxiace',target); - player.getHistory('custom').push({dcxiace:'player'}); - target.addTempSkill('fengyin'); + return bool1 || bool2; + }, + direct: true, + async content(event, trigger, player) { + if ( + trigger.player == player && + !player.hasHistory("custom", (evt) => evt.dcxiace == "player") && + game.hasPlayer((target) => target != player && !target.hasSkill("fengyin")) + ) { + const { + result: { bool, targets }, + } = await player + .chooseTarget((card, player, target) => { + return target != player && !target.hasSkill("fengyin"); + }) + .set("prompt", get.prompt("dcxiace")) + .set("prompt2", "令一名其他角色的非锁定技于本回合失效") + .set("ai", (target) => { + const player = get.event("player"); + return ( + -get.sgn(get.attitude(player, target)) * + (target.getSkills(null, false, false).filter((skill) => { + return !get.is.locked(skill); + }).length + + 1) * + (target === _status.currentPhase ? 10 : 1) + ); + }); + if (bool) { + const target = targets[0]; + player.logSkill("dcxiace", target); + player.getHistory("custom").push({ dcxiace: "player" }); + target.addTempSkill("fengyin"); } } - if(trigger.source&&trigger.source==player&&!player.hasHistory('custom',evt=>evt.dcxiace=='source')&&player.isDamaged()&&player.countCards('he',card=>{ - if(_status.connectMode&&get.position(card)=='h') return true; - return lib.filter.cardDiscardable(card,player); - })&&player.hasSkill('dcxiace')){ - const {result:{bool}}=await player.chooseToDiscard('he',get.prompt('dcxiace'),'弃置一张牌并回复1点体力').set('ai',card=>{ - const player=get.event('player'); - if(get.recoverEffect(player,player,player)<=0) return 0; - return 7-get.value(card); - }).set('logSkill','dcxiace'); - if(bool){ - player.getHistory('custom').push({dcxiace:'source'}); + if ( + trigger.source && + trigger.source == player && + !player.hasHistory("custom", (evt) => evt.dcxiace == "source") && + player.isDamaged() && + player.countCards("he", (card) => { + if (_status.connectMode && get.position(card) == "h") return true; + return lib.filter.cardDiscardable(card, player); + }) && + player.hasSkill("dcxiace") + ) { + const { + result: { bool }, + } = await player + .chooseToDiscard("he", get.prompt("dcxiace"), "弃置一张牌并回复1点体力") + .set("ai", (card) => { + const player = get.event("player"); + if (get.recoverEffect(player, player, player) <= 0) return 0; + return 7 - get.value(card); + }) + .set("logSkill", "dcxiace"); + if (bool) { + player.getHistory("custom").push({ dcxiace: "source" }); await player.recover(); } } }, }, - dcyuxin:{ - unique:true, - limited:true, - audio:2, - trigger:{global:'dying'}, - filter(event,player){ - return event.player.hp<(event.player==player?1:player.getHp()); + dcyuxin: { + unique: true, + limited: true, + audio: 2, + trigger: { global: "dying" }, + filter(event, player) { + return event.player.hp < (event.player == player ? 1 : player.getHp()); }, - prompt2(event,player){ - return '令其将体力值回复至'+(event.player==player?1:player.getHp())+'点'; + prompt2(event, player) { + return "令其将体力值回复至" + (event.player == player ? 1 : player.getHp()) + "点"; }, - check(event,player){ - if(get.recoverEffect(event.player,player,player)<=0) return false; - return lib.skill.luanfeng.check(event,player); + check(event, player) { + if (get.recoverEffect(event.player, player, player) <= 0) return false; + return lib.skill.luanfeng.check(event, player); }, - logTarget:'player', - skillAnimation:true, - animationColor:'thunder', - async content(event,trigger,player){ - player.awakenSkill('dcyuxin'); - trigger.player.recover((trigger.player==player?1:player.getHp())-trigger.player.hp); + logTarget: "player", + skillAnimation: true, + animationColor: "thunder", + async content(event, trigger, player) { + player.awakenSkill("dcyuxin"); + trigger.player.recover( + (trigger.player == player ? 1 : player.getHp()) - trigger.player.hp + ); }, }, //清河公主 - dczhangji:{ - audio:2, - trigger:{global:'useCard'}, - filter:function(event,player){ - return event.targets&&event.targets.length>1&&event.targets.includes(player); + dczhangji: { + audio: 2, + trigger: { global: "useCard" }, + filter: function (event, player) { + return event.targets && event.targets.length > 1 && event.targets.includes(player); }, - forced:true, - logTarget:'player', - content:function*(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.player; - let targets=trigger.targets.slice(); - targets.sortBySeat((_status.currentPhase||target)); + forced: true, + logTarget: "player", + content: function* (event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.player; + let targets = trigger.targets.slice(); + targets.sortBySeat(_status.currentPhase || target); targets.remove(player); - player.when({global:'useCardToTargeted'}).filter(evt=>targets.length&&evt.getParent()==trigger&&evt.targets.length==evt.getParent().triggeredTargets4.length).then(()=>{ - trigger.getParent().targets=[player].concat(targets); - trigger.getParent().triggeredTargets4=[player].concat(targets); - }).vars({targets:targets}); - player.when({target:['useCardToEnd','useCardToExcluded']}).filter(evt=>targets.length&&evt.getParent()==trigger).then(()=>{ - player.draw(targets.length); - }).vars({targets:targets}); + player + .when({ global: "useCardToTargeted" }) + .filter( + (evt) => + targets.length && + evt.getParent() == trigger && + evt.targets.length == evt.getParent().triggeredTargets4.length + ) + .then(() => { + trigger.getParent().targets = [player].concat(targets); + trigger.getParent().triggeredTargets4 = [player].concat(targets); + }) + .vars({ targets: targets }); + player + .when({ target: ["useCardToEnd", "useCardToExcluded"] }) + .filter((evt) => targets.length && evt.getParent() == trigger) + .then(() => { + player.draw(targets.length); + }) + .vars({ targets: targets }); }, }, - dczengou:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.maxHp>0&&player.countCards('he')>0; + dczengou: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.maxHp > 0 && player.countCards("he") > 0; }, - filterCard:true, - selectCard:()=>[1,_status.event.player.maxHp], - position:'he', - filterTarget:lib.filter.notMe, - discard:false, - lose:false, - delay:false, - usable:1, - check:function(card){ - if(card.name=='tao'||card.name=='jiu') return 0; - return 1/(get.value(card)||0.5); + filterCard: true, + selectCard: () => [1, _status.event.player.maxHp], + position: "he", + filterTarget: lib.filter.notMe, + discard: false, + lose: false, + delay: false, + usable: 1, + check: function (card) { + if (card.name == "tao" || card.name == "jiu") return 0; + return 1 / (get.value(card) || 0.5); }, - content:function*(event,map){ - const player=map.player,cards=event.cards,target=event.target; - yield player.give(cards,target).gaintag.add('dczengou_debuff'); + content: function* (event, map) { + const player = map.player, + cards = event.cards, + target = event.target; + yield player.give(cards, target).gaintag.add("dczengou_debuff"); yield player.draw(cards.length); - target.addSkill('dczengou_debuff'); + target.addSkill("dczengou_debuff"); }, - ai:{ - order:10, - result:{target:-1}, + ai: { + order: 10, + result: { target: -1 }, }, - subSkill:{ - debuff:{ - charlotte:true, - mark:true, - intro:{content:'下次体力值增加或使用牌结算完毕后展示所有手牌,然后失去手牌中“谮构”牌数的体力值'}, - trigger:{player:['changeHp','useCardAfter']}, - filter:function(event,player){ - return event.name=='useCard'||event.num>0; + subSkill: { + debuff: { + charlotte: true, + mark: true, + intro: { + content: + "下次体力值增加或使用牌结算完毕后展示所有手牌,然后失去手牌中“谮构”牌数的体力值", }, - forced:true, - popup:false, - content:function(){ - player.removeSkill('dczengou_debuff'); - const cards=player.getCards('h',card=>card.hasGaintag('dczengou_debuff')); + trigger: { player: ["changeHp", "useCardAfter"] }, + filter: function (event, player) { + return event.name == "useCard" || event.num > 0; + }, + forced: true, + popup: false, + content: function () { + player.removeSkill("dczengou_debuff"); + const cards = player.getCards("h", (card) => card.hasGaintag("dczengou_debuff")); player.showHandcards(); - if(cards.length) player.loseHp(cards.length); + if (cards.length) player.loseHp(cards.length); }, - mod:{ - aiValue:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dczengou_debuff')) return -1; + mod: { + aiValue: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dczengou_debuff")) + return -1; }, - aiUseful:function(){ - return lib.skill.dczengou.subSkill.debuff.mod.aiValue.apply(this,arguments); + aiUseful: function () { + return lib.skill.dczengou.subSkill.debuff.mod.aiValue.apply(this, arguments); }, - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dczengou_debuff')){ - const cards=player.getCards('h',card=>card.hasGaintag('dczengou_debuff')); - if(cards.length==1) return num+10; + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dczengou_debuff")) { + const cards = player.getCards("h", (card) => + card.hasGaintag("dczengou_debuff") + ); + if (cards.length == 1) return num + 10; return 0; } }, @@ -1036,1149 +2124,1629 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //曹宪 - dclingxi:{ - audio:2, - trigger:{player:['phaseUseBegin','phaseUseEnd']}, - filter:function(event,player){ - return player.countCards('he')&&player.maxHp>0; + dclingxi: { + audio: 2, + trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, + filter: function (event, player) { + return player.countCards("he") && player.maxHp > 0; }, - direct:true, - content:function*(event,map){ - var player=map.player,num=player.maxHp; - var result=yield player.chooseCard(get.prompt('dclingxi'),'将至多'+get.cnNumber(num)+'张牌称为“翼”置于武将牌上','he',[1,num]).set('ai',card=>{ - let player=_status.event.player,dis=player.needsToDiscard(0,(i,player)=>{ - return !player.canIgnoreHandcard(i)&&!ui.selected.cards.includes(i); - }), - cards=ui.selected.cards.concat(player.getExpansions('dclingxi')), - suit=get.suit(card,false); - if(_status.event.suits.length<4) _status.event.suits.add(get.suit(ui.selected.cards.at(-1),false)); - if(_status.event.triggerName==='phaseUseEnd'){ - if(_status.event.suits.includes(suit)) return (dis?10:3)-get.useful(card); - return (dis?6:1)-get.useful(card); - } - _status.event.hvt.remove(ui.selected.cards.at(-1)); - if(_status.event.hvt.length===1&&card===_status.event.hvt[0]) return 0; - let temp; - if(!cards.some(i=>{ - temp=get.suit(i,false); - return cards.some(j=>{ - return i!==j&&suit===get.suit(j,false); - }); - })&&suit===temp) return 15-get.value(card); - if(!_status.event.hvt.length){ - if(_status.event.suits.includes(suit)) return (dis?10:3)-get.useful(card); - return (dis?6:1)-get.useful(card); - } - if(_status.event.hvt.includes(card)){ - if(!_status.event.suits.includes(suit)) return 6-get.value(card); - if(card.name==='sha') return 3-get.value(card); - return 1-get.value(card); - } - return 15-get.value(card); - }).set('complexCard',true).set('hvt',player.getCards('hs',card=>{ - return card.name==='zhuge'||player.hasValueTarget(card,null,true); - })).set('suits',(()=>{ - let suits=[]; - player.getExpansions('dclingxi').forEach(i=>{ - suits.add(get.suit(i,false)); - }); - return suits; - })()).set('triggerName',event.triggername); - if(result.bool){ - player.logSkill('dclingxi'); - player.addToExpansion(result.cards,player,'give').gaintag.add('dclingxi'); + direct: true, + content: function* (event, map) { + var player = map.player, + num = player.maxHp; + var result = yield player + .chooseCard( + get.prompt("dclingxi"), + "将至多" + get.cnNumber(num) + "张牌称为“翼”置于武将牌上", + "he", + [1, num] + ) + .set("ai", (card) => { + let player = _status.event.player, + dis = player.needsToDiscard(0, (i, player) => { + return !player.canIgnoreHandcard(i) && !ui.selected.cards.includes(i); + }), + cards = ui.selected.cards.concat(player.getExpansions("dclingxi")), + suit = get.suit(card, false); + if (_status.event.suits.length < 4) + _status.event.suits.add(get.suit(ui.selected.cards.at(-1), false)); + if (_status.event.triggerName === "phaseUseEnd") { + if (_status.event.suits.includes(suit)) + return (dis ? 10 : 3) - get.useful(card); + return (dis ? 6 : 1) - get.useful(card); + } + _status.event.hvt.remove(ui.selected.cards.at(-1)); + if (_status.event.hvt.length === 1 && card === _status.event.hvt[0]) return 0; + let temp; + if ( + !cards.some((i) => { + temp = get.suit(i, false); + return cards.some((j) => { + return i !== j && suit === get.suit(j, false); + }); + }) && + suit === temp + ) + return 15 - get.value(card); + if (!_status.event.hvt.length) { + if (_status.event.suits.includes(suit)) + return (dis ? 10 : 3) - get.useful(card); + return (dis ? 6 : 1) - get.useful(card); + } + if (_status.event.hvt.includes(card)) { + if (!_status.event.suits.includes(suit)) return 6 - get.value(card); + if (card.name === "sha") return 3 - get.value(card); + return 1 - get.value(card); + } + return 15 - get.value(card); + }) + .set("complexCard", true) + .set( + "hvt", + player.getCards("hs", (card) => { + return card.name === "zhuge" || player.hasValueTarget(card, null, true); + }) + ) + .set( + "suits", + (() => { + let suits = []; + player.getExpansions("dclingxi").forEach((i) => { + suits.add(get.suit(i, false)); + }); + return suits; + })() + ) + .set("triggerName", event.triggername); + if (result.bool) { + player.logSkill("dclingxi"); + player.addToExpansion(result.cards, player, "give").gaintag.add("dclingxi"); } }, - marktext:'翼', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "翼", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'dclingxi_effect', - subSkill:{ - effect:{ - audio:'dclingxi', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter'], + group: "dclingxi_effect", + subSkill: { + effect: { + audio: "dclingxi", + trigger: { + player: "loseAfter", + global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - var num=2*player.getExpansions('dclingxi').reduce((list,card)=>list.add(get.suit(card,false)),[]).length; - num-=player.countCards('h'); - if(!num) return false; - if(event.name=='lose'&&event.getlx!==false){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('dclingxi')) return true; + filter: function (event, player) { + var num = + 2 * + player + .getExpansions("dclingxi") + .reduce((list, card) => list.add(get.suit(card, false)), []).length; + num -= player.countCards("h"); + if (!num) return false; + if (event.name == "lose" && event.getlx !== false) { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("dclingxi")) return true; } return false; } - return game.getGlobalHistory('cardMove',function(evt){ - if(evt.name!='lose'||event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dclingxi')&&evt.player==player) return true; + return game.getGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dclingxi") && evt.player == player) + return true; } return false; }).length; }, - forced:true, - locked:false, - content:function(){ - var num=2*player.getExpansions('dclingxi').reduce((list,card)=>list.add(get.suit(card,false)),[]).length; - num-=player.countCards('h'); - if(num>0) player.draw(num); - else player.chooseToDiscard('h',-num,true); + forced: true, + locked: false, + content: function () { + var num = + 2 * + player + .getExpansions("dclingxi") + .reduce((list, card) => list.add(get.suit(card, false)), []).length; + num -= player.countCards("h"); + if (num > 0) player.draw(num); + else player.chooseToDiscard("h", -num, true); }, }, }, - }, - dczhifou:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - var num=player.getHistory('useSkill',evt=>evt.skill=='dczhifou').length+1; - return player.getExpansions('dclingxi').length>=num; + ai: { + combo: "dczhifou", }, - direct:true, - content:function*(event,map){ - var player=map.player,cards=player.getExpansions('dclingxi'); - var num=player.getHistory('useSkill',evt=>evt.skill=='dczhifou').length+1; - var result=yield player.chooseButton(['###'+get.prompt('dczhifou')+'###移去至少'+get.cnNumber(num)+'张武将牌上的“翼”',cards],[num,cards.length]).set('ai',button=>{ - if(!_status.event.res.bool) return 0; - if(_status.event.res.cards.includes(button.link)) return 1; - return 0; - }).set('num',num).set('res',(()=>{ - if(player.isPhaseUsing()&&player.hasCard(i=>{ - return player.hasValueTarget(i,null,true); - },'h')) return false; - let suits=[],cs=player.getExpansions('dclingxi'),cards=[],temp=num; - for(let i=0;i0){ - cards.push(cs.pop()); - temp--; - } - temp=suits.length*2-player.countCards('h'); - if(temp>0||!temp&&num evt.skill == "dczhifou").length + 1; + return player.getExpansions("dclingxi").length >= num; + }, + direct: true, + content: function* (event, map) { + var player = map.player, + cards = player.getExpansions("dclingxi"); + var num = player.getHistory("useSkill", (evt) => evt.skill == "dczhifou").length + 1; + var result = yield player + .chooseButton( + [ + "###" + + get.prompt("dczhifou") + + "###移去至少" + + get.cnNumber(num) + + "张武将牌上的“翼”", + cards, + ], + [num, cards.length] + ) + .set("ai", (button) => { + if (!_status.event.res.bool) return 0; + if (_status.event.res.cards.includes(button.link)) return 1; + return 0; + }) + .set("num", num) + .set( + "res", + (() => { + if ( + player.isPhaseUsing() && + player.hasCard((i) => { + return player.hasValueTarget(i, null, true); + }, "h") + ) + return false; + let suits = [], + cs = player.getExpansions("dclingxi"), + cards = [], + temp = num; + for (let i = 0; i < cs.length; i++) { + if (!temp) break; + let suit = get.suit(cs[i], false); + if (suits.includes(suit)) { + cards.push(cs.splice(i--, 1)[0]); + temp--; + } else suits.push(suit); + } + while (temp > 0) { + cards.push(cs.pop()); + temp--; + } + temp = suits.length * 2 - player.countCards("h"); + if (temp > 0 || (!temp && num < Math.max(2, 5 - player.hp))) cs = true; + else cs = false; + return { + bool: cs, + cards: cards, + }; + })() + ); + if (result.bool) { + player.logSkill("dczhifou"); player.loseToDiscardpile(result.links); - var list=[],choiceList=[ - '将一张牌称为“翼”置于你的武将牌上', - '弃置两张牌', - '失去1点体力', - ]; - if(!player.hasSkill('dczhifou_0')&&game.hasPlayer(target=>target.countCards('he'))) list.push('置入“翼”'); - else choiceList[0]=''+choiceList[0]+''; - if(!player.hasSkill('dczhifou_1')&&game.hasPlayer(target=>{ - return target==player?target.countDiscardableCards(target,'he'):target.countCards('he'); - })) list.push('弃置卡牌'); - else choiceList[1]=''+choiceList[1]+''; - if(!player.hasSkill('dczhifou_2')) list.push('失去体力'); - else choiceList[2]=''+choiceList[2]+''; - if(!list.length) return; - var str=''; - for(var i of list){ - str+=i; - str+='、'; + var list = [], + choiceList = ["将一张牌称为“翼”置于你的武将牌上", "弃置两张牌", "失去1点体力"]; + if ( + !player.hasSkill("dczhifou_0") && + game.hasPlayer((target) => target.countCards("he")) + ) + list.push("置入“翼”"); + else choiceList[0] = '' + choiceList[0] + ""; + if ( + !player.hasSkill("dczhifou_1") && + game.hasPlayer((target) => { + return target == player + ? target.countDiscardableCards(target, "he") + : target.countCards("he"); + }) + ) + list.push("弃置卡牌"); + else choiceList[1] = '' + choiceList[1] + ""; + if (!player.hasSkill("dczhifou_2")) list.push("失去体力"); + else choiceList[2] = '' + choiceList[2] + ""; + if (!list.length) return; + var str = ""; + for (var i of list) { + str += i; + str += "、"; } - str=str.slice(0,-1); - var result2=yield player.chooseTarget('知否:令一名角色执行以下一项',str,(card,player,target)=>{ - if(!player.hasSkill('dczhifou_2')) return true; - if(!player.hasSkill('dczhifou_0')&&target.countCards('he')) return true; - return target==player?target.countDiscardableCards(target,'he'):target.countCards('he'); - },true).set('ai',target=>{ - var player=_status.event.player,list=[]; - if(!player.hasSkill('dczhifou_0')) list.push(get.effect(target,{name:'guohe_copy2'},target,player)/2); - if(!player.hasSkill('dczhifou_1')) list.push(get.effect(target,{name:'guohe_copy2'},target,player)); - if(!player.hasSkill('dczhifou_2')) list.push(get.effect(target,{name:'losehp'},player,player)); - return list.sort((a,b)=>b-a)[0]; - }); - if(result2.bool){ - var target=result2.targets[0]; + str = str.slice(0, -1); + var result2 = yield player + .chooseTarget( + "知否:令一名角色执行以下一项", + str, + (card, player, target) => { + if (!player.hasSkill("dczhifou_2")) return true; + if (!player.hasSkill("dczhifou_0") && target.countCards("he")) + return true; + return target == player + ? target.countDiscardableCards(target, "he") + : target.countCards("he"); + }, + true + ) + .set("ai", (target) => { + var player = _status.event.player, + list = []; + if (!player.hasSkill("dczhifou_0")) + list.push( + get.effect(target, { name: "guohe_copy2" }, target, player) / 2 + ); + if (!player.hasSkill("dczhifou_1")) + list.push(get.effect(target, { name: "guohe_copy2" }, target, player)); + if (!player.hasSkill("dczhifou_2")) + list.push(get.effect(target, { name: "losehp" }, player, player)); + return list.sort((a, b) => b - a)[0]; + }); + if (result2.bool) { + var target = result2.targets[0]; player.line(target); - list=list.filter(control=>{ - if(control=='失去体力') return true; - if(control=='置入“翼”'&&target.countCards('he')) return true; - return target.countDiscardableCards(target,'he'); + list = list.filter((control) => { + if (control == "失去体力") return true; + if (control == "置入“翼”" && target.countCards("he")) return true; + return target.countDiscardableCards(target, "he"); }); var result3; - if(!list.length){ - game.log(target,'没有可执行项'); + if (!list.length) { + game.log(target, "没有可执行项"); return; - } - else if(list.length==1) result3={control:list[0]}; - else result3=yield player.chooseControl(list).set('prompt','知否:请选择一项').set('choiceList',choiceList.map(str=>'令'+get.translation(target)+str)).set('ai',()=>{ - var player=_status.event.player; - var target=_status.event.target; - var getNum=function(control){ - return [ - get.effect(target,{name:'guohe_copy2'},target,player)/2, - get.effect(target,{name:'guohe_copy2'},target,player), - get.effect(target,{name:'losehp'},target,player), - ][['置入“翼”','弃置卡牌','失去体力'].indexOf(control)]; - }; - var controls=_status.event.controls.slice(); - return controls.sort((a,b)=>getNum(b)-getNum(a))[0]; - }).set('target',target); - switch(result3.control){ - case '置入“翼”': - player.addTempSkill('dczhifou_0'); - var result4=yield target.chooseCard('he',choiceList[0],true); - if(result4.bool) player.addToExpansion(result4.cards,target,'give').gaintag.add('dclingxi'); + } else if (list.length == 1) result3 = { control: list[0] }; + else + result3 = yield player + .chooseControl(list) + .set("prompt", "知否:请选择一项") + .set( + "choiceList", + choiceList.map((str) => "令" + get.translation(target) + str) + ) + .set("ai", () => { + var player = _status.event.player; + var target = _status.event.target; + var getNum = function (control) { + return [ + get.effect(target, { name: "guohe_copy2" }, target, player) / + 2, + get.effect(target, { name: "guohe_copy2" }, target, player), + get.effect(target, { name: "losehp" }, target, player), + ][["置入“翼”", "弃置卡牌", "失去体力"].indexOf(control)]; + }; + var controls = _status.event.controls.slice(); + return controls.sort((a, b) => getNum(b) - getNum(a))[0]; + }) + .set("target", target); + switch (result3.control) { + case "置入“翼”": + player.addTempSkill("dczhifou_0"); + var result4 = yield target.chooseCard("he", choiceList[0], true); + if (result4.bool) + player + .addToExpansion(result4.cards, target, "give") + .gaintag.add("dclingxi"); break; - case '弃置卡牌': - player.addTempSkill('dczhifou_1'); - target.chooseToDiscard('he',2,true); + case "弃置卡牌": + player.addTempSkill("dczhifou_1"); + target.chooseToDiscard("he", 2, true); break; - case '失去体力': - player.addTempSkill('dczhifou_2'); + case "失去体力": + player.addTempSkill("dczhifou_2"); target.loseHp(); break; } } } }, - subSkill:{ - '0':{charlotte:true}, - '1':{charlotte:true}, - '2':{charlotte:true}, + subSkill: { + 0: { charlotte: true }, + 1: { charlotte: true }, + 2: { charlotte: true }, + }, + ai: { + combo: "dclingxi", }, }, //周瑜 //无 双 万 军 取 首 - dcsbronghuo:{ - audio:2, - trigger:{player:'useCard1'}, - filter:function(event,player){ - return (event.card.name=='sha'&&game.hasNature(event.card,'fire'))||event.card.name=='huogong'; + dcsbronghuo: { + audio: 2, + trigger: { player: "useCard1" }, + filter: function (event, player) { + return ( + (event.card.name == "sha" && game.hasNature(event.card, "fire")) || + event.card.name == "huogong" + ); }, - forced:true, - content:function(){ - trigger.baseDamage=game.countGroup(); + forced: true, + content: function () { + trigger.baseDamage = game.countGroup(); }, - ai:{threaten:3.5}, + ai: { threaten: 3.5 }, }, - dcsbyingmou:{ - mark:true, - marktext:'☯', - zhuanhuanji:true, - intro:{ - content:function(storage){ - if(!storage) return '每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】。' - return '每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。'; + dcsbyingmou: { + mark: true, + marktext: "☯", + zhuanhuanji: true, + intro: { + content: function (storage) { + if (!storage) + return "每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】。"; + return "每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。"; }, }, - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.isFirstTarget; + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.isFirstTarget && event.targets.some((target) => target != player); }, - usable:1, - direct:true, - content:function*(event,map){ - var result,player=map.player,targets=map.trigger.targets; - var storage=player.storage.dcsbyingmou; - if(storage){ - result=yield player.chooseCardTarget({ - prompt:get.prompt('dcsbyingmou'), - prompt2:'选择一名目标角色,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)', - filterTarget:function(card,player,target){ - if(!ui.selected.targets.length) return _status.event.targets.includes(target); - return target.isMaxHandcard(); - }, - selectTarget:2, - complexSelect:true, - complexTarget:true, - multitarget:true, - targetprompt:['目标角色','使用角色'], - filterCard:()=>false, - selectCard:-1, - ai2:function(target){ - var player=_status.event.player; - var getNum=function(player,target,source){ - return player.getCards('h',card=>{ - if(get.name(card)!='sha'&&(get.type(card)!='trick'||!get.tag(card,'damage'))) return false; - return player.canUse(card,target,false); - }).reduce((sum,card)=>sum+get.effect(target,card,player,source),0); - }; - if(!ui.selected.targets.length){ - var targets=game.filterPlayer(target=>target.isMaxHandcard()); - targets.sort((a,b)=>getNum(b,target,player)-getNum(a,target,player)); - return getNum(targets[0],target,player)+1; - } - return getNum(target,ui.selected.targets[0],player)+1; - }, - }).set('targets',targets); - } - else result=yield player.chooseTarget(get.prompt('dcsbyingmou'),'选择一名目标角色,将手牌数摸至与其相同,然后视为对其使用一张【火攻】',(card,player,target)=>_status.event.targets.includes(target)).set('ai',target=>{ - var player=_status.event.player; - return Math.max(0,Math.min(5,target.countCards('h')-player.countCards('h')))*2+get.effect(target,{name:'huogong'},player,player); - }).set('targets',targets); - if(result.bool){ - var target=result.targets[0]; - if(storage){ - player.logSkill('dcsbyingmou',result.targets,false); + usable: 1, + direct: true, + content: function* (event, map) { + var result, + player = map.player, + targets = map.trigger.targets; + var storage = player.storage.dcsbyingmou; + if (storage) { + result = yield player + .chooseCardTarget({ + prompt: get.prompt("dcsbyingmou"), + prompt2: + "选择一名目标角色,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)", + filterTarget: function (card, player, target) { + if (!ui.selected.targets.length) + return _status.event.targets.includes(target); + return target.isMaxHandcard(); + }, + selectTarget: 2, + complexSelect: true, + complexTarget: true, + multitarget: true, + targetprompt: ["目标角色", "使用角色"], + filterCard: () => false, + selectCard: -1, + ai2: function (target) { + var player = _status.event.player; + var getNum = function (player, target, source) { + return player + .getCards("h", (card) => { + if ( + get.name(card) != "sha" && + (get.type(card) != "trick" || !get.tag(card, "damage")) + ) + return false; + return player.canUse(card, target, false); + }) + .reduce( + (sum, card) => sum + get.effect(target, card, player, source), + 0 + ); + }; + if (!ui.selected.targets.length) { + var targets = game.filterPlayer((target) => target.isMaxHandcard()); + targets.sort( + (a, b) => getNum(b, target, player) - getNum(a, target, player) + ); + return getNum(targets[0], target, player) + 1; + } + return getNum(target, ui.selected.targets[0], player) + 1; + }, + }) + .set("targets", targets); + } else + result = yield player + .chooseTarget( + get.prompt("dcsbyingmou"), + "选择一名目标角色,将手牌数摸至与其相同,然后视为对其使用一张【火攻】", + (card, player, target) => _status.event.targets.includes(target) + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + Math.max( + 0, + Math.min(5, target.countCards("h") - player.countCards("h")) + ) * + 2 + + get.effect(target, { name: "huogong" }, player, player) + ); + }) + .set("targets", targets); + if (result.bool) { + var target = result.targets[0]; + if (storage) { + player.logSkill("dcsbyingmou", result.targets, false); player.line2(result.targets); - player.changeZhuanhuanji('dcsbyingmou'); - var source=result.targets[1],discard=true; - while(true){ - var cards=source.getCards('h',card=>{ - if(get.name(card)!='sha'&&(get.type(card)!='trick'||!get.tag(card,'damage'))) return false; - return source.canUse(card,target,false); + player.changeZhuanhuanji("dcsbyingmou"); + var source = result.targets[1], + discard = true; + while (true) { + var cards = source.getCards("h", (card) => { + if ( + get.name(card) != "sha" && + (get.type(card) != "trick" || !get.tag(card, "damage")) + ) + return false; + return source.canUse(card, target, false); }); - if(cards.length){ - if(discard) discard=false; - yield source.useCard(cards.randomGet(),target,false); - } - else break; + if (cards.length) { + if (discard) discard = false; + yield source.useCard(cards.randomGet(), target, false); + } else break; } - if(discard&&player.countCards('h')evt==trigger&&player.countCards('h')).then(()=>{ - var str='明势:请展示三张牌并令一名其他角色选择获得其中的一张牌'; - if(player.countCards('h')<=3) str='明势:展示手牌并令一名其他角色选择获得其中的一张牌'; - player.chooseCardTarget({ - prompt:str, - filterTarget:lib.filter.notMe, - filterCard:true, - selectCard:function(){ - var player=_status.event.player; - if(player.countCards('h')<=3) return -1; - return 3; - }, - position:'h', - forced:true, - ai1:function(card){ - return -get.value(card); - }, - ai2:function(target){ - var player=_status.event.player; - if(player.hasSkill('dcsbmengmou')&&!get.is.blocked('dcsbmengmou',player)&&player.storage.dcsbmengmou&&get.attitude(player,target)<0) return get.effect(target,{name:'losehp'},player,player); - return get.attitude(player,target); - }, + frequent: true, + content: function () { + trigger.num += 2; + player + .when("phaseDrawEnd") + .filter((evt, player) => evt == trigger && player.countCards("h")) + .then(() => { + var str = "明势:请展示三张牌并令一名其他角色选择获得其中的一张牌"; + if (player.countCards("h") <= 3) + str = "明势:展示手牌并令一名其他角色选择获得其中的一张牌"; + player.chooseCardTarget({ + prompt: str, + filterTarget: lib.filter.notMe, + filterCard: true, + selectCard: function () { + var player = _status.event.player; + if (player.countCards("h") <= 3) return -1; + return 3; + }, + position: "h", + forced: true, + ai1: function (card) { + return -get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + if ( + player.hasSkill("dcsbmengmou") && + !get.is.blocked("dcsbmengmou", player) && + player.storage.dcsbmengmou && + get.attitude(player, target) < 0 + ) + return get.effect(target, { name: "losehp" }, player, player); + return get.attitude(player, target); + }, + }); + }) + .then(() => { + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var cards = result.cards; + player.showCards(cards, get.translation(player) + "发动了【明势】"); + target + .chooseButton(["明势:请获得其中一张牌", cards], true) + .set("filterButton", (button) => { + return lib.filter.canBeGained( + button.link, + _status.event.source, + _status.event.player + ); + }) + .set("ai", (button) => get.value(button.link)) + .set("source", player); + } else event.finish(); + }) + .then(() => { + if (result.bool) { + var card = result.links[0]; + if (lib.filter.canBeGained(card, player, target)) + target.gain(card, player, "giveAuto"); + else game.log("但", card, "不能被", player, "获得!"); + } }); - }).then(()=>{ - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var cards=result.cards; - player.showCards(cards,get.translation(player)+'发动了【明势】'); - target.chooseButton(['明势:请获得其中一张牌',cards],true).set('filterButton',button=>{ - return lib.filter.canBeGained(button.link,_status.event.source,_status.event.player); - }).set('ai',button=>get.value(button.link)).set('source',player); - } - else event.finish(); - }).then(()=>{ - if(result.bool){ - var card=result.links[0]; - if(lib.filter.canBeGained(card,player,target)) target.gain(card,player,'giveAuto'); - else game.log('但',card,'不能被',player,'获得!'); - } - }); }, }, - dcsbmengmou:{ - mark:true, - marktext:'☯', - zhuanhuanji:true, - intro:{ - content:function(storage){ - if(!storage) return '每回合限一次,当你得到其他角色的牌后,或其他角色得到你的牌后,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力。(X为你的体力上限)'; - return '每回合限一次,当你得到其他角色的牌后,或其他角色得到你的牌后,你可令该角色打出至多X张【杀】,然后其失去Y点体力。(X为你的体力上限,Y为X-其打出【杀】数)'; + dcsbmengmou: { + mark: true, + marktext: "☯", + zhuanhuanji: true, + intro: { + content: function (storage) { + if (!storage) + return "每回合限一次,当你得到其他角色的牌后,或其他角色得到你的牌后,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力。(X为你的体力上限)"; + return "每回合限一次,当你得到其他角色的牌后,或其他角色得到你的牌后,你可令该角色打出至多X张【杀】,然后其失去Y点体力。(X为你的体力上限,Y为X-其打出【杀】数)"; }, }, - audio:2, - trigger:{global:['gainAfter','loseAsyncAfter']}, - filter:function(event,player){ - if(typeof player.maxHp!='number'||player.maxHp<=0) return false; - if(event.name=='loseAsync'&&event.type!='gain') return false; - if(player.hasSkill('dcsbmengmou_true')&&player.hasSkill('dcsbmengmou_false')) return false; - var cards1=event.getl(player).cards2,cards2=event.getg(player); - return game.hasPlayer(function(current){ - if(current==player) return false; - var cardsx=event.getg(current); - return cardsx.some(i=>cards1.includes(i)); - })||game.hasPlayer(function(current){ - if(current==player) return false; - var cardsx=event.getl(current).cards2; - return cards2.some(i=>cardsx.includes(i)); - }); + audio: 2, + trigger: { global: ["gainAfter", "loseAsyncAfter"] }, + filter: function (event, player) { + if (typeof player.maxHp != "number" || player.maxHp <= 0) return false; + if (event.name == "loseAsync" && event.type != "gain") return false; + if (player.hasSkill("dcsbmengmou_true") && player.hasSkill("dcsbmengmou_false")) + return false; + var cards1 = event.getl(player).cards2, + cards2 = event.getg(player); + return ( + game.hasPlayer(function (current) { + if (current == player) return false; + var cardsx = event.getg(current); + return cardsx.some((i) => cards1.includes(i)); + }) || + game.hasPlayer(function (current) { + if (current == player) return false; + var cardsx = event.getl(current).cards2; + return cards2.some((i) => cardsx.includes(i)); + }) + ); }, - direct:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - var storage=player.storage.dcsbmengmou; - player.addTempSkill('dcsbmengmou_effect','dcsbmengmouAfter'); - var targets=[],num=player.maxHp; - var cards1=trigger.getl(player).cards2; - var cards2=trigger.getg(player); - targets.addArray(game.filterPlayer(function(current){ - if(current==player) return false; - var cardsx=trigger.getg(current); - return cardsx.some(i=>cards1.includes(i)); - })); - targets.addArray(game.filterPlayer(function(current){ - if(current==player) return false; - var cardsx=trigger.getl(current).cards2; - return cards2.some(i=>cardsx.includes(i)); - })); + direct: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger; + var storage = player.storage.dcsbmengmou; + player.addTempSkill("dcsbmengmou_effect", "dcsbmengmouAfter"); + var targets = [], + num = player.maxHp; + var cards1 = trigger.getl(player).cards2; + var cards2 = trigger.getg(player); + targets.addArray( + game.filterPlayer(function (current) { + if (current == player) return false; + var cardsx = trigger.getg(current); + return cardsx.some((i) => cards1.includes(i)); + }) + ); + targets.addArray( + game.filterPlayer(function (current) { + if (current == player) return false; + var cardsx = trigger.getl(current).cards2; + return cards2.some((i) => cardsx.includes(i)); + }) + ); targets.sortBySeat(); - var check_true=function(player,target){ - if(get.attitude(player,target)>0){ - if(target.countCards('hs',card=>{ - if(get.name(card)!='sha') return false; - return target.hasValueTarget(card); - })) return 4; + var check_true = function (player, target) { + if (get.attitude(player, target) > 0) { + if ( + target.countCards("hs", (card) => { + if (get.name(card) != "sha") return false; + return target.hasValueTarget(card); + }) + ) + return 4; return 0.5; } - if(get.attitude(player,target)<0){ - if(!target.countCards('hs',card=>{ - if(get.name(card)!='sha') return false; - return target.hasValueTarget(card); - })){ - if(target.countCards('hs',card=>{ - if(get.name(card)!='sha') return false; - return target.hasUseTarget(card); - })) return -3; + if (get.attitude(player, target) < 0) { + if ( + !target.countCards("hs", (card) => { + if (get.name(card) != "sha") return false; + return target.hasValueTarget(card); + }) + ) { + if ( + target.countCards("hs", (card) => { + if (get.name(card) != "sha") return false; + return target.hasUseTarget(card); + }) + ) + return -3; return -1; } return 0; } return 0; }; - var check_false=function(player,target){ - if(get.attitude(player,target)<0) return get.effect(target,{name:'losehp'},player,player); + var check_false = function (player, target) { + if (get.attitude(player, target) < 0) + return get.effect(target, { name: "losehp" }, player, player); return 0; }; - var result,target; - if(targets.length==1){ - target=targets[0]; + var result, target; + if (targets.length == 1) { + target = targets[0]; var str; - if(storage) str='令'+get.translation(target)+'打出至多'+get.cnNumber(num)+'张【杀】,然后其失去Y点体力。(Y为'+num+'-其打出【杀】数)'; - else str='令'+get.translation(target)+'使用至多'+get.cnNumber(num)+'张【杀】,其每以此法造成1点伤害,其回复1点体力'; - result=yield player.chooseBool(get.prompt('dcsbmengmou',target),str).set('choice',(storage?check_false(player,target):check_true(player,target))>0); + if (storage) + str = + "令" + + get.translation(target) + + "打出至多" + + get.cnNumber(num) + + "张【杀】,然后其失去Y点体力。(Y为" + + num + + "-其打出【杀】数)"; + else + str = + "令" + + get.translation(target) + + "使用至多" + + get.cnNumber(num) + + "张【杀】,其每以此法造成1点伤害,其回复1点体力"; + result = yield player + .chooseBool(get.prompt("dcsbmengmou", target), str) + .set( + "choice", + (storage ? check_false(player, target) : check_true(player, target)) > 0 + ); + } else { + result = yield player + .chooseTarget( + get.prompt("dcsbmengmou"), + lib.skill.dcsbmengmou.intro.content(storage), + (card, player, target) => _status.event.targets.includes(target) + ) + .set("ai", (target) => { + return _status.event.check(_status.event.player, target); + }) + .set("targets", targets) + .set("check", storage ? check_false : check_true) + .set("ainmate", false); } - else{ - result=yield player.chooseTarget(get.prompt('dcsbmengmou'),lib.skill.dcsbmengmou.intro.content(storage),(card,player,target)=>_status.event.targets.includes(target)).set('ai',target=>{ - return _status.event.check(_status.event.player,target); - }).set('targets',targets).set('check',storage?check_false:check_true).set('ainmate',false); - } - if(result.bool){ - if(!target) target=result.targets[0]; - player.logSkill('dcsbmengmou',target); - player.addTempSkill('dcsbmengmou_'+(storage||false)); - player.changeZhuanhuanji('dcsbmengmou'); - while(num>0){ + if (result.bool) { + if (!target) target = result.targets[0]; + player.logSkill("dcsbmengmou", target); + player.addTempSkill("dcsbmengmou_" + (storage || false)); + player.changeZhuanhuanji("dcsbmengmou"); + while (num > 0) { num--; var result2; - if(storage){ - result2=yield target.chooseToRespond((card,player)=>{ - return get.name(card)=='sha'; - }).set('ai',card=>{ - return 1+Math.random(); - }).set('prompt','盟谋:是否打出一张【杀】?').set('prompt2','当前进度:'+(3-num)+'/3'); - } - else result2=yield target.chooseToUse(card=>{ - if(!lib.filter.cardEnabled(card,_status.event.player,_status.event)) return false; - return get.name(card)=='sha'; - }).set('prompt','盟谋:是否使用一张【杀】?').set('prompt2','当前进度:'+(3-num)+'/3'); - if(!result2.bool){ - if(storage){ - target.popup('杯具'); - target.loseHp(num+1); + if (storage) { + result2 = yield target + .chooseToRespond((card, player) => { + return get.name(card) == "sha"; + }) + .set("ai", (card) => { + return 1 + Math.random(); + }) + .set("prompt", "盟谋:是否打出一张【杀】?") + .set("prompt2", "当前进度:" + (3 - num) + "/3"); + } else + result2 = yield target + .chooseToUse((card) => { + if ( + !lib.filter.cardEnabled(card, _status.event.player, _status.event) + ) + return false; + return get.name(card) == "sha"; + }) + .set("prompt", "盟谋:是否使用一张【杀】?") + .set("prompt2", "当前进度:" + (3 - num) + "/3"); + if (!result2.bool) { + if (storage) { + target.popup("杯具"); + target.loseHp(num + 1); } break; } } } }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{global:'damageSource'}, - filter:function(event,player){ - if(!event.source||event.getParent().type!='card') return false; - if(event.source.isHealthy()||event.card.name!='sha') return false; - return event.getParent(4).name=='dcsbmengmou'&&event.getParent(4).player==player; + subSkill: { + effect: { + charlotte: true, + trigger: { global: "damageSource" }, + filter: function (event, player) { + if (!event.source || event.getParent().type != "card") return false; + if (event.source.isHealthy() || event.card.name != "sha") return false; + return ( + event.getParent(4).name == "dcsbmengmou" && + event.getParent(4).player == player + ); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ + forced: true, + popup: false, + firstDo: true, + content: function () { trigger.source.recover(trigger.num); }, }, - true:{charlotte:true}, - false:{charlotte:false}, + true: { charlotte: true }, + false: { charlotte: false }, }, }, //张臶 - dc_zj_a:{ - audio:2, - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - return event.getParent().type=='card'; + dc_zj_a: { + audio: 2, + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + return event.getParent().type == "card"; }, - forced:true, - content:function(){ - var num=get.number(trigger.card); - if(typeof num=='number'&&num>0) trigger.num=num; + forced: true, + content: function () { + var num = get.number(trigger.card); + if (typeof num == "number" && num > 0) trigger.num = num; else trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&typeof get.number(card)!='number') return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && typeof get.number(card) != "number") + return "zeroplayertarget"; }, }, }, }, - dc_zj_b:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countDiscardableCards(player,'he'); + dc_zj_b: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countDiscardableCards(player, "he"); }, - direct:true, - content:function*(event,map){ - var player=map.player; - var result=yield player.chooseTarget(get.prompt2('dc_zj_b'),lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - if(!player.hasFriend()) return 0; - return -game.countPlayer(current=>current.inRange(target)&&get.attitude(current,target)<0&&get.damageEffect(target,current,current)>0); - }); - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dc_zj_b',target); - player.discard(player.getCards('he')).discarder=player; - target.addSkill('dc_zj_a'); - target.addSkill('dc_zj_b_threaten'); - player.when('phaseBegin').then(()=>{ - if(target.isIn()){ - target.removeSkill('dc_zj_a'); - target.removeSkill('dc_zj_b_threaten'); - } - }).vars({target:target}); + direct: true, + content: function* (event, map) { + var player = map.player; + var result = yield player + .chooseTarget(get.prompt2("dc_zj_b"), lib.filter.notMe) + .set("ai", (target) => { + var player = _status.event.player; + if (!player.hasFriend()) return 0; + return -game.countPlayer( + (current) => + current.inRange(target) && + get.attitude(current, target) < 0 && + get.damageEffect(target, current, current) > 0 + ); + }); + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dc_zj_b", target); + player.discard(player.getCards("he")).discarder = player; + target.addSkill("dc_zj_a"); + target.addSkill("dc_zj_b_threaten"); + player + .when("phaseBegin") + .then(() => { + if (target.isIn()) { + target.removeSkill("dc_zj_a"); + target.removeSkill("dc_zj_b_threaten"); + } + }) + .vars({ target: target }); } }, - subSkill:{ + subSkill: { //定要将你赶尽杀绝 - threaten:{ - charlotte:true, - mark:true, - marktext:'噩', - intro:{content:'已经开始汗流浃背了'}, - ai:{threaten:114514*1919810}, + threaten: { + charlotte: true, + mark: true, + marktext: "噩", + intro: { content: "已经开始汗流浃背了" }, + ai: { threaten: 114514 * 1919810 }, }, }, }, //诸葛若雪 - dcqiongying:{ - audio:2, - enable:'phaseUse', - usable:1, - direct:true, - filter:function(event,player){ + dcqiongying: { + audio: 2, + enable: "phaseUse", + usable: 1, + direct: true, + filter: function (event, player) { return player.canMoveCard(); }, - content:function*(event,map){ - const player=map.player; - event.pushHandler('onNextMoveCard',(event,option)=>{ - if(_status.connectMode&&event.step==1&&event._result.bool&&option.state=='end'){ - game.broadcastAll(()=>{ + content: function* (event, map) { + const player = map.player; + event.pushHandler("onNextMoveCard", (event, option) => { + if ( + _status.connectMode && + event.step == 1 && + event._result.bool && + option.state == "end" + ) { + game.broadcastAll(() => { delete _status.noclearcountdown; game.stopCountChoose(); }); } }); - let result=yield player.moveCard(false,`###琼英###移动场上的一张牌,然后弃置一张与此牌花色相同的手牌(若没有则展示手牌)。`).set('logSkill','dcqiongying').set('custom',{ - add:{}, - replace:{ - window:()=>{ - if(get.event().name=='chooseTarget') ui.click.cancel(); - } - }, - }); - if(result.bool){ - const card=result.card,suit=get.suit(card); - if(!player.hasCard({suit:suit})) player.showHandcards(); - else player.chooseToDiscard({suit:suit},true,`请弃置一张${get.translation(suit)}手牌`); - } - else{ - player.getStat('skill').dcqiongying--; + let result = yield player + .moveCard( + false, + `###琼英###移动场上的一张牌,然后弃置一张与此牌花色相同的手牌(若没有则展示手牌)。` + ) + .set("logSkill", "dcqiongying") + .set("custom", { + add: {}, + replace: { + window: () => { + if (get.event().name == "chooseTarget") ui.click.cancel(); + }, + }, + }); + if (result.bool) { + const card = result.card, + suit = get.suit(card); + if (!player.hasCard({ suit: suit })) player.showHandcards(); + else + player.chooseToDiscard( + { suit: suit }, + true, + `请弃置一张${get.translation(suit)}手牌` + ); + } else { + player.getStat("skill").dcqiongying--; } }, - ai:{ - expose:0.2, - order:function(item,player){ - if(player.countCards('h')<=4) return 0.5; + ai: { + expose: 0.2, + order: function (item, player) { + if (player.countCards("h") <= 4) return 0.5; return 9; }, - result:{ - player:function(player){ - if(player.canMoveCard(true)) return 1; + result: { + player: function (player) { + if (player.canMoveCard(true)) return 1; return 0; - } - } - } + }, + }, + }, }, - dcnuanhui:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function*(event,map){ - const player=map.player; - let result=yield player.chooseTarget(get.prompt('dcnuanhui'),'选择一名装备区有牌的角色,该角色可以依次使用X张基本牌(X为其装备区牌数且至少为1)').set('ai',target=>{ - return get.event('aiTarget')==target?10:0; - }).set('aiTarget',(()=>{ - const player=get.player(); - const list=get.inpileVCardList(info=>{ - return info[0]=='basic'; - }); - if(!list.length) return null; - const getUseValue=target=>{ - if(get.attitude(player,target)<=0) return -1; - const toUse=[]; - const hp=target.hp; - let eff=0,count=Math.max(1,target.countCards('e')); - while(count--){ - target.hp=Math.min(target.maxHp,target.hp+toUse.filter(card=>card.name=='tao').length); - const listx=list.map(info=>{ - const card=new lib.element.VCard({name:info[2],nature:info[3],isCard:true}); - return [card,target.getUseValue(card)]; - }).sort((a,b)=>{ - return b[1]-a[1]; + dcnuanhui: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function* (event, map) { + const player = map.player; + let result = yield player + .chooseTarget( + get.prompt("dcnuanhui"), + "选择一名装备区有牌的角色,该角色可以依次使用X张基本牌(X为其装备区牌数且至少为1)" + ) + .set("ai", (target) => { + return get.event("aiTarget") == target ? 10 : 0; + }) + .set( + "aiTarget", + (() => { + const player = get.player(); + const list = get.inpileVCardList((info) => { + return info[0] == "basic"; }); - const mostValuablePair=listx[0].slice(); - if(mostValuablePair[1]<=0) mostValuablePair[1]=0; - eff+=mostValuablePair[1]; - toUse.push(mostValuablePair[0]); - target.hp=hp; - } - if(toUse.length>1&&eff>0){ - eff-=target.getCards('e',card=>{ - return lib.filter.cardDiscardable(card,target,'dcnuanhui'); - }).map(card=>{ - return get.value(card,target); - }).reduce((p,c)=>{ - return p+c; - },0); - } - return eff; - } - const playerList=game.filterPlayer().map(current=>[current,getUseValue(current)]).sort((a,b)=>b[1]-a[1]); - if(playerList[0][1]<=0) return null; - return playerList[0][0]; - })()); - if(!result.bool) return event.finish(); - const target=result.targets[0]; - player.logSkill('dcnuanhui',target); - if(!target.isUnderControl(true)&&!target.isOnline()) game.delayx(); - const total=Math.max(1,target.countCards('e')); - let count=0,forced=false,used=[],discard=false; - while(count{ - return info[0]=='basic'&&target.hasUseTarget({name:info[2],nature:info[3],isCard:true}); + if (!list.length) return null; + const getUseValue = (target) => { + if (get.attitude(player, target) <= 0) return -1; + const toUse = []; + const hp = target.hp; + let eff = 0, + count = Math.max(1, target.countCards("e")); + while (count--) { + target.hp = Math.min( + target.maxHp, + target.hp + toUse.filter((card) => card.name == "tao").length + ); + const listx = list + .map((info) => { + const card = new lib.element.VCard({ + name: info[2], + nature: info[3], + isCard: true, + }); + return [card, target.getUseValue(card)]; + }) + .sort((a, b) => { + return b[1] - a[1]; + }); + const mostValuablePair = listx[0].slice(); + if (mostValuablePair[1] <= 0) mostValuablePair[1] = 0; + eff += mostValuablePair[1]; + toUse.push(mostValuablePair[0]); + target.hp = hp; + } + if (toUse.length > 1 && eff > 0) { + eff -= target + .getCards("e", (card) => { + return lib.filter.cardDiscardable(card, target, "dcnuanhui"); + }) + .map((card) => { + return get.value(card, target); + }) + .reduce((p, c) => { + return p + c; + }, 0); + } + return eff; + }; + const playerList = game + .filterPlayer() + .map((current) => [current, getUseValue(current)]) + .sort((a, b) => b[1] - a[1]); + if (playerList[0][1] <= 0) return null; + return playerList[0][0]; + })() + ); + if (!result.bool) return event.finish(); + const target = result.targets[0]; + player.logSkill("dcnuanhui", target); + if (!target.isUnderControl(true) && !target.isOnline()) game.delayx(); + const total = Math.max(1, target.countCards("e")); + let count = 0, + forced = false, + used = [], + discard = false; + while (count < total) { + const basicList = get.inpileVCardList((info) => { + return ( + info[0] == "basic" && + target.hasUseTarget({ name: info[2], nature: info[3], isCard: true }) + ); }); - if(!basicList.length){ - game.log('但是',target,'无牌可出!'); + if (!basicList.length) { + game.log("但是", target, "无牌可出!"); break; } - const str=forced?'视为使用一张基本牌':'是否视为使用一张基本牌?'; - const result=yield target.chooseButton([str,[basicList,'vcard']],forced).set('ai',button=>{ - return get.player().getUseValue({name:button.link[2],nature:button.link[3],isCard:true}); - }); - if(!result.bool){ - game.log('但是',target,'不愿出牌!'); + const str = forced ? "视为使用一张基本牌" : "是否视为使用一张基本牌?"; + const result = yield target + .chooseButton([str, [basicList, "vcard"]], forced) + .set("ai", (button) => { + return get.player().getUseValue({ + name: button.link[2], + nature: button.link[3], + isCard: true, + }); + }); + if (!result.bool) { + game.log("但是", target, "不愿出牌!"); break; } - forced=true; - const card=new lib.element.VCard({name:result.links[0][2],nature:result.links[0][3],isCard:true}); - const result2=yield target.chooseUseTarget(card,true,false); - if(!discard&&result2.bool){ - if(used.includes(result.links[0][2])) discard=true; + forced = true; + const card = new lib.element.VCard({ + name: result.links[0][2], + nature: result.links[0][3], + isCard: true, + }); + const result2 = yield target.chooseUseTarget(card, true, false); + if (!discard && result2.bool) { + if (used.includes(result.links[0][2])) discard = true; else used.add(result.links[0][2]); } count++; } - if(discard){ - const cards=target.getCards('e',card=>{ - return lib.filter.cardDiscardable(card,target,'dcnuanhui'); + if (discard) { + const cards = target.getCards("e", (card) => { + return lib.filter.cardDiscardable(card, target, "dcnuanhui"); }); - if(cards.length) target.discard(cards).discarder=target; + if (cards.length) target.discard(cards).discarder = target; } }, - ai:{ - expose:0.3, - threaten:3.7, + ai: { + expose: 0.3, + threaten: 3.7, }, }, //曹轶 - dcmiyi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function*(event,map){ - const player=map.player; - if(_status.connectMode) game.broadcastAll(()=>{_status.noclearcountdown=true}); - let result=yield player.chooseControl(['回复体力','受到伤害'],'cancel2').set('choiceList',[ - '令你即将选择的角色各回复1点体力', - '令你即将选择的角色各受到你造成的1点伤害' - ]).set('prompt',get.prompt('dcmiyi')).set('ai',()=>{ - return get.event('choice'); - }).set('choice',(()=>{ - let damage=0; - game.countPlayer(current=>{ - let eff=get.damageEffect(current,player,player); - if(!current.isDamaged()){ - if(eff>0) eff=-eff; - } - else if(current.hasSkillTag('maixie')){ - if(get.attitude(player,current)<=0){ - if(current.getHp(true)>=2) eff=0; - else eff/=10; - } - else if(current.getHp(true)>=2){ - eff+=30; - } - } - else eff/=3; - damage+=eff; + dcmiyi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function* (event, map) { + const player = map.player; + if (_status.connectMode) + game.broadcastAll(() => { + _status.noclearcountdown = true; + }); + let result = yield player + .chooseControl(["回复体力", "受到伤害"], "cancel2") + .set("choiceList", [ + "令你即将选择的角色各回复1点体力", + "令你即将选择的角色各受到你造成的1点伤害", + ]) + .set("prompt", get.prompt("dcmiyi")) + .set("ai", () => { + return get.event("choice"); }) - if(damage<-20) return 0; - if(damage>5) return 1; - if(lib.skill.mbhuiyao.getUnrealDamageTargets(player,[[player],game.filterPlayer()])) return 0; - return 'cancel2'; - })()); - if(result.control=='cancel2'){ - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} + .set( + "choice", + (() => { + let damage = 0; + game.countPlayer((current) => { + let eff = get.damageEffect(current, player, player); + if (!current.isDamaged()) { + if (eff > 0) eff = -eff; + } else if (current.hasSkillTag("maixie")) { + if (get.attitude(player, current) <= 0) { + if (current.getHp(true) >= 2) eff = 0; + else eff /= 10; + } else if (current.getHp(true) >= 2) { + eff += 30; + } + } else eff /= 3; + damage += eff; + }); + if (damage < -20) return 0; + if (damage > 5) return 1; + if ( + lib.skill.mbhuiyao.getUnrealDamageTargets(player, [ + [player], + game.filterPlayer(), + ]) + ) + return 0; + return "cancel2"; + })() + ); + if (result.control == "cancel2") { + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } return event.finish(); } - const func=['recover','damage'],ind=result.index; - const fn=func[ind]; - result=yield player.chooseTarget(`蜜饴:令任意名角色${result.control.slice(0,2)}1点${result.control.slice(2)}`,[1,Infinity]).set('ai',target=>{ - const toDamage=get.event('toDamage'); - let eff=get.damageEffect(target,player,player); - if(toDamage){ - if(target.hasSkillTag('maixie')){ - if(get.attitude(player,target)<=0){ - if(target.getHp(true)>=2) eff=0; - else eff/=10; - } - else if(target.getHp(true)>=2){ - eff+=30; + const func = ["recover", "damage"], + ind = result.index; + const fn = func[ind]; + result = yield player + .chooseTarget( + `蜜饴:令任意名角色${result.control.slice(0, 2)}1点${result.control.slice(2)}`, + [1, Infinity] + ) + .set("ai", (target) => { + const toDamage = get.event("toDamage"); + let eff = get.damageEffect(target, player, player); + if (toDamage) { + if (target.hasSkillTag("maixie")) { + if (get.attitude(player, target) <= 0) { + if (target.getHp(true) >= 2) eff = 0; + else eff /= 10; + } else if (target.getHp(true) >= 2) { + eff += 30; + } } + return eff; } - return eff; - } - if(!target.isDamaged()){ - eff*=-2; - } - if(target.getHp(true)>=2) return -eff; - return 0; - }).set('toDamage',result.index==1); - if(_status.connectMode){game.broadcastAll(()=>{delete _status.noclearcountdown;game.stopCountChoose()})} - if(!result.bool) return event.finish(); - const targets=result.targets.slice().sortBySeat(); - player.logSkill('dcmiyi',targets,fn=='damage'?'fire':'green'); - while(targets.length){ - const target=targets.shift(); - if(!target.isIn()) continue; - target[fn](); - target.when({global:'phaseJieshuBegin'}).vars({ - fn:func[ind^1], - source:player, - }).then(()=>{ - if(source.isIn()){ - if(!trigger._dcmiyi_logged){ - source.logSkill('dcmiyi'); - trigger._dcmiyi_logged=true; - } - source.line(player,fn=='damage'?'fire':'green'); + if (!target.isDamaged()) { + eff *= -2; } - player[fn](source); + if (target.getHp(true) >= 2) return -eff; + return 0; + }) + .set("toDamage", result.index == 1); + if (_status.connectMode) { + game.broadcastAll(() => { + delete _status.noclearcountdown; + game.stopCountChoose(); }); } + if (!result.bool) return event.finish(); + const targets = result.targets.slice().sortBySeat(); + player.logSkill("dcmiyi", targets, fn == "damage" ? "fire" : "green"); + while (targets.length) { + const target = targets.shift(); + if (!target.isIn()) continue; + target[fn](); + target + .when({ global: "phaseJieshuBegin" }) + .vars({ + fn: func[ind ^ 1], + source: player, + }) + .then(() => { + if (source.isIn()) { + if (!trigger._dcmiyi_logged) { + source.logSkill("dcmiyi"); + trigger._dcmiyi_logged = true; + } + source.line(player, fn == "damage" ? "fire" : "green"); + } + player[fn](source); + }); + } }, }, - dcyinjun:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(get.name(event.card,false)!='sha'&&get.type2(event.card)!='trick') return false; - if(event.targets.length!=1||!event.targets[0].isIn()) return false; - if(!player.canUse(new lib.element.VCard({name:'sha'}),event.targets[0],false)) return false; - return player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - return event.cards.every(card=>{ + dcyinjun: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if (get.name(event.card, false) != "sha" && get.type2(event.card) != "trick") + return false; + if (event.targets.length != 1 || !event.targets[0].isIn()) return false; + if (!player.canUse(new lib.element.VCard({ name: "sha" }), event.targets[0], false)) + return false; + return player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + return event.cards.every((card) => { return evt.hs.includes(card); }); }); }, - prompt2:function(event,player){ + prompt2: function (event, player) { return `视为对${get.translation(event.targets)}使用一张无伤害来源的【杀】`; }, - check:function(event,player){ - const sha=new lib.element.VCard({name:'sha'}); - return Math.max(...[event.targets[0],player].map(source=>get.effect(event.targets[0],sha,source,player)))>0; + check: function (event, player) { + const sha = new lib.element.VCard({ name: "sha" }); + return ( + Math.max( + ...[event.targets[0], player].map((source) => + get.effect(event.targets[0], sha, source, player) + ) + ) > 0 + ); }, - logTarget:'targets', - content:function*(event,map){ - const player=map.player,trigger=map.trigger,target=trigger.targets[0]; - yield player.useCard(new lib.element.VCard({name:'sha'}),target,false).oncard=()=>{ - get.event().customArgs.default.customSource={ - isDead:()=>true, - } - }; - if(player.getHistory('useSkill',evt=>evt.skill=='dcyinjun').length>player.getHp()){ - player.tempBanSkill('dcyinjun'); + logTarget: "targets", + content: function* (event, map) { + const player = map.player, + trigger = map.trigger, + target = trigger.targets[0]; + yield (player.useCard(new lib.element.VCard({ name: "sha" }), target, false).oncard = + () => { + get.event().customArgs.default.customSource = { + isDead: () => true, + }; + }); + if ( + player.getHistory("useSkill", (evt) => evt.skill == "dcyinjun").length > + player.getHp() + ) { + player.tempBanSkill("dcyinjun"); } - } + }, }, //马伶俐 - dclima:{ - audio:2, - mod:{ - globalFrom:function(from,to,distance){ - return distance-Math.max(1,game.countPlayer(current=>{ - return current.countCards('e',card=>{ - return get.is.attackingMount(card)||get.is.defendingMount(card); - }); - })); - } - } + dclima: { + audio: 2, + mod: { + globalFrom: function (from, to, distance) { + return ( + distance - + Math.max( + 1, + game.countPlayer((current) => { + return current.countCards("e", (card) => { + return get.is.attackingMount(card) || get.is.defendingMount(card); + }); + }) + ) + ); + }, + }, }, - dcxiaoyin:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(current=>get.distance(player,current)<=1); + dcxiaoyin: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer((current) => get.distance(player, current) <= 1); }, - group:'dcxiaoyin_damage', - prompt2:function(event,player){ - return `亮出牌堆顶的${get.cnNumber(game.countPlayer(current=>get.distance(player,current)<=1))}张牌,获得其中的红色牌,将其中任意张黑色牌置于等量名座次连续的其他角色的武将牌上。`; + group: "dcxiaoyin_damage", + prompt2: function (event, player) { + return `亮出牌堆顶的${get.cnNumber( + game.countPlayer((current) => get.distance(player, current) <= 1) + )}张牌,获得其中的红色牌,将其中任意张黑色牌置于等量名座次连续的其他角色的武将牌上。`; }, - frequent:true, - check:()=>true, - content:function*(event,map){ - var player=map.player; - var count=game.countPlayer(current=>get.distance(player,current)<=1); - var cards=game.cardsGotoOrdering(get.cards(count)).cards; - yield player.showCards(cards,`${get.translation(player)}【硝引】亮出`); - player.gain(cards.filter(i=>get.color(i,false)=='red'),'gain2'); - var blackOnes=cards.filter(i=>get.color(i,false)=='black'); - if(!blackOnes.length) return event.finish(); - event.videoId=lib.status.videoId++; - var func=(cards,id)=>{ - var dialog=ui.create.dialog('硝引:剩余的黑色牌',`
              请选择至多${get.cnNumber(cards.length)}名座次连续的其他角色,然后将以下这些牌置于这些角色的武将牌上。
              `,cards); - dialog.videoId=id; + frequent: true, + check: () => true, + content: function* (event, map) { + var player = map.player; + var count = game.countPlayer((current) => get.distance(player, current) <= 1); + var cards = game.cardsGotoOrdering(get.cards(count)).cards; + yield player.showCards(cards, `${get.translation(player)}【硝引】亮出`); + player.gain( + cards.filter((i) => get.color(i, false) == "red"), + "gain2" + ); + var blackOnes = cards.filter((i) => get.color(i, false) == "black"); + if (!blackOnes.length) return event.finish(); + event.videoId = lib.status.videoId++; + var func = (cards, id) => { + var dialog = ui.create.dialog( + "硝引:剩余的黑色牌", + `
              请选择至多${get.cnNumber( + cards.length + )}名座次连续的其他角色,然后将以下这些牌置于这些角色的武将牌上。
              `, + cards + ); + dialog.videoId = id; return dialog; }; - if(player==game.me) func(blackOnes,event.videoId); - else if(player.isOnline2()){ - player.send(func,blackOnes,event.videoId); + if (player == game.me) func(blackOnes, event.videoId); + else if (player.isOnline2()) { + player.send(func, blackOnes, event.videoId); } - var targets=game.filterPlayer(current=>current!=player); - if(targets.length==1) var result={bool:true,targets:targets}; - else var result=yield player.chooseTarget([1,blackOnes.length],true,(card,player,target)=>{ - if(player==target) return false; - var selected=ui.selected.targets; - if(!selected.length) return true; - for(var i of selected){ - if(i.getNext()==target||i.getPrevious()==target) return true; - } - return false; - }).set('complexSelect',true).set('complexTarget',true).set('multitarget',true).set('multiline',true).set('ai',target=>{ - if(get.event('aiTargets').includes(target)) return 10; - return 0.1; - }).set('aiTargets',(()=>{ - var targets=game.filterPlayer(i=>i!=player).sortBySeat(player); - var maxEff=-Infinity,aiTargets=[]; - for(var i=0;i{ - return get.damageEffect(current,current,player,'fire'); - }).reduce((p,c)=>{ - return p+c; - },0); - if(tmpEff>maxEff){ - maxEff=tmpEff; - aiTargets=targetsx; + var targets = game.filterPlayer((current) => current != player); + if (targets.length == 1) var result = { bool: true, targets: targets }; + else + var result = yield player + .chooseTarget([1, blackOnes.length], true, (card, player, target) => { + if (player == target) return false; + var selected = ui.selected.targets; + if (!selected.length) return true; + for (var i of selected) { + if (i.getNext() == target || i.getPrevious() == target) return true; } - } - } - return aiTargets; - })()).set('prompt',false); - if(!result.bool){ + return false; + }) + .set("complexSelect", true) + .set("complexTarget", true) + .set("multitarget", true) + .set("multiline", true) + .set("ai", (target) => { + if (get.event("aiTargets").includes(target)) return 10; + return 0.1; + }) + .set( + "aiTargets", + (() => { + var targets = game.filterPlayer((i) => i != player).sortBySeat(player); + var maxEff = -Infinity, + aiTargets = []; + for (var i = 0; i < targets.length; i++) { + for (var j = 0; j < blackOnes.length; j++) { + if (targets.length < i + j) break; + var targetsx = targets.slice(i, j); + var tmpEff = targetsx + .map((current) => { + return get.damageEffect(current, current, player, "fire"); + }) + .reduce((p, c) => { + return p + c; + }, 0); + if (tmpEff > maxEff) { + maxEff = tmpEff; + aiTargets = targetsx; + } + } + } + return aiTargets; + })() + ) + .set("prompt", false); + if (!result.bool) { event.finish(); return; } - var func=(num,id)=>{ - var dialog=get.idDialog(id); - if(dialog) dialog.content.childNodes[1].innerHTML=`
              将${get.cnNumber(num)}张黑色牌按照选择的角色的座次顺序置于这些角色武将牌上
              `; + var func = (num, id) => { + var dialog = get.idDialog(id); + if (dialog) + dialog.content.childNodes[1].innerHTML = `
              将${get.cnNumber( + num + )}张黑色牌按照选择的角色的座次顺序置于这些角色武将牌上
              `; }; - var targets=result.targets.slice().sortBySeat(player); - var num=targets.length; - if(player==game.me) func(num,event.videoId); - else if(player.isOnline2()) player.send(func,num,event.videoId); - if(blackOnes.length==1) var result={bool:true,links:blackOnes}; - else var result=yield player.chooseButton(true,num).set('dialog',event.videoId).set('ai',()=>1); - game.broadcastAll('closeDialog',event.videoId); - if(result.bool){ - var cards=result.links; + var targets = result.targets.slice().sortBySeat(player); + var num = targets.length; + if (player == game.me) func(num, event.videoId); + else if (player.isOnline2()) player.send(func, num, event.videoId); + if (blackOnes.length == 1) var result = { bool: true, links: blackOnes }; + else + var result = yield player + .chooseButton(true, num) + .set("dialog", event.videoId) + .set("ai", () => 1); + game.broadcastAll("closeDialog", event.videoId); + if (result.bool) { + var cards = result.links; player.line(targets); - targets.forEach((current,ind)=>{ - current.addToExpansion(cards[ind],'gain2').gaintag.add('dcxiaoyin'); - game.log(current,'将',cards[ind],'当“硝引”置于了武将牌上'); + targets.forEach((current, ind) => { + current.addToExpansion(cards[ind], "gain2").gaintag.add("dcxiaoyin"); + game.log(current, "将", cards[ind], "当“硝引”置于了武将牌上"); }); } }, - marktext:'硝', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "硝", + intro: { + content: "expansion", + markcount: "expansion", }, - subSkill:{ - damage:{ - audio:'dcxiaoyin', - trigger:{global:'damageBegin3'}, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - return event.player.getExpansions('dcxiaoyin').length; + subSkill: { + damage: { + audio: "dcxiaoyin", + trigger: { global: "damageBegin3" }, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + return event.player.getExpansions("dcxiaoyin").length; }, - direct:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - var source=trigger.source,target=trigger.player; - var cards=target.getExpansions('dcxiaoyin'); - if(trigger.hasNature('fire')){ - var types=cards.map(i=>get.type2(i,false)); - var str=get.translation(types).replace(/(.*)、/, '$1或'); - var result=yield source.chooseCard(`硝引:是否弃置一张${str}牌?`,`若如此做,将${get.translation(target)}的所有“硝引”牌置入弃牌堆,令你对其造成的伤害+1`,'he',function(card,player){ - if(!get.event('types').includes(get.type2(card))) return false; - return lib.filter.cardDiscardable.apply(this,arguments); - }).set('types',types).set('ai',card=>{ - if(get.event('goon')) return 7-get.value(card); - return 0; - }).set('goon',get.damageEffect(target,player,player,'fire')>0&&get.attitude(player,target)<=0); - if(result.bool){ - player.logSkill('dcxiaoyin_damage',source); - source.line(target,'fire'); - source.discard(result.cards).discarder=source; - game.delayex(); - target.loseToDiscardpile(cards); - trigger.addNumber('num',1); - } + //direct:true, + async cost(event, trigger, player) { + const source = trigger.source, + target = trigger.player; + const cards = target.getExpansions("dcxiaoyin"); + if (trigger.hasNature("fire")) { + const types = cards.map((i) => get.type2(i, false)); + const str = get.translation(types).replace(/(.*)、/, "$1或"); + event.result = await source + .chooseCard( + `硝引:是否弃置一张${str}牌?`, + `若如此做,将${get.translation( + target + )}的对应的“硝引”牌置入弃牌堆,令你对其造成的伤害+1`, + "he", + function (card, player) { + if (!get.event("types").includes(get.type2(card))) return false; + return lib.filter.cardDiscardable.apply(this, arguments); + } + ) + .set("types", types) + .set("ai", (card) => { + if (get.event("goon")) return 7 - get.value(card); + return 0; + }) + .set( + "goon", + get.damageEffect(target, player, player, "fire") > 0 && + get.attitude(player, target) <= 0 + ) + .forResult(); + } else { + event.result = await source + .chooseBool( + `###是否响应${get.translation( + player + )}的【硝引】?###获得${get.translation( + target + )}的一张“硝引”牌(${get.translation( + cards + )}),然后将你对其造成的此次伤害改为火焰伤害。` + ) + .set( + "choice", + (() => { + if ( + get.damageEffect(target, source, source, "fire") < + get.damageEffect(target, source, source) - 5 + ) + return false; + if (cards.map((i) => get.value(i)).reduce((p, c) => p + c, 0) > 0) + return true; + return false; + })() + ) + .forResult(); } - else{ - var result=yield source.chooseBool(`###是否响应${get.translation(player)}的【硝引】?###获得${get.translation(target)}的“硝引”牌(${get.translation(cards)}),然后将你对其造成的此次伤害改为火焰伤害。`).set('choice',(()=>{ - if(get.damageEffect(target,source,source,'fire')get.value(i)).reduce((p,c)=>p+c,0)>0) return true; - return false; - })()); - if(result.bool){ - player.logSkill('dcxiaoyin_damage',source); - source.line(target,'fire'); - source.gain(cards,target,'give'); - game.setNature(trigger,'fire'); + }, + async content(event, trigger, player) { + const source = trigger.source, + target = trigger.player; + if (trigger.hasNature("fire")) { + source.line(target, "fire"); + const type = get.type2(event.cards[0]); + await source.discard(event.cards).set("discarder", source); + //await game.asyncDelayx(); + const cardsToDiscard = target + .getExpansions("dcxiaoyin") + .filter((card) => get.type2(card, false) === type); + if (cardsToDiscard.length === 1) + await target.loseToDiscardpile(cardsToDiscard); + else if (cardsToDiscard.length > 1) { + const result = await source + .chooseButton( + [ + `请选择移去${get.translation(source)}的一张“硝引”牌`, + cardsToDiscard, + ], + true + ) + .forResult(); + await target.loseToDiscardpile(result.links); } + trigger.addNumber("num", 1); + } else { + source.line(target, "fire"); + const cards = target.getExpansions("dcxiaoyin"); + if (cards.length === 1) await source.gain(cards, target, "give"); + else if (cards.length > 1) { + const result = await source + .chooseButton( + [`请选择获得${get.translation(source)}的一张“硝引”牌`, cards], + true + ) + .forResult(); + await source.gain(result.links, target, "give"); + } + game.setNature(trigger, "fire"); } }, }, }, - ai:{ - threaten:4, + ai: { + threaten: 4, }, }, - dchuahuo:{ - audio:2, - enable:'phaseUse', - usable:1, - viewAs:{ - name:'sha', - nature:'fire', - storage:{dchuahuo:true}, + dchuahuo: { + audio: 2, + enable: "phaseUse", + usable: 1, + viewAs: { + name: "sha", + nature: "fire", + storage: { dchuahuo: true }, }, - filterCard:{color:'red'}, - position:'hs', - filter:function(event,player){ - return player.countCards('hs',{color:'red'}); + filterCard: { color: "red" }, + position: "hs", + filter: function (event, player) { + return player.countCards("hs", { color: "red" }); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - precontent:function(){ - event.getParent().addCount=false; - player.when('useCardToPlayer').filter(evt=>evt.card.storage&&evt.card.storage.dchuahuo).then(()=>{ - if(trigger.target.getExpansions('dcxiaoyin').length){ - var targets=game.filterPlayer(current=>{ - return current.getExpansions('dcxiaoyin').length; - }); - player.chooseBool(`是否更改${get.translation(trigger.card)}的目标?`,`将此牌的目标改为所有有“硝引”的角色(${get.translation(targets)})。`) - .set('choice',targets.map(current=>get.effect(current,trigger.card,player,player)).reduce((p,c)=>p+c,0)>get.effect(trigger.target,trigger.card,player,player)); - } - else event.finish(); - }).then(()=>{ - if(result.bool){ - trigger.targets.length=0; - trigger.getParent().triggeredTargets1.length=0; - trigger.untrigger(); - var targets=game.filterPlayer(current=>{ - return current.getExpansions('dcxiaoyin').length; - }); - player.line(targets,'fire'); - trigger.targets.addArray(targets); - game.log(targets,'成为了',trigger.card,'的新目标'); - game.delayx(); - } - }) + precontent: function () { + event.getParent().addCount = false; + player + .when("useCardToPlayer") + .filter((evt) => evt.card.storage && evt.card.storage.dchuahuo) + .then(() => { + if (trigger.target.getExpansions("dcxiaoyin").length) { + var targets = game.filterPlayer((current) => { + return current.getExpansions("dcxiaoyin").length; + }); + player + .chooseBool( + `是否更改${get.translation(trigger.card)}的目标?`, + `将此牌的目标改为所有有“硝引”的角色(${get.translation(targets)})。` + ) + .set( + "choice", + targets + .map((current) => + get.effect(current, trigger.card, player, player) + ) + .reduce((p, c) => p + c, 0) > + get.effect(trigger.target, trigger.card, player, player) + ); + } else event.finish(); + }) + .then(() => { + if (result.bool) { + trigger.targets.length = 0; + trigger.getParent().triggeredTargets1.length = 0; + trigger.untrigger(); + var targets = game.filterPlayer((current) => { + return current.getExpansions("dcxiaoyin").length; + }); + player.line(targets, "fire"); + trigger.targets.addArray(targets); + game.log(targets, "成为了", trigger.card, "的新目标"); + game.delayx(); + } + }); + }, + ai: { + order: () => get.order({ name: "sha" }) + 0.2, + result: { player: 1 }, }, - ai:{ - order:()=>get.order({name:'sha'})+0.2, - result:{player:1}, - } }, //武陆逊 - dcxiongmu:{ - audio:2, - trigger:{global:'roundStart'}, + dcxiongmu: { + audio: 2, + trigger: { global: "roundStart" }, // filter:function(event,player){ // return player.countCards('h'){ - return 6-get.value(card); - }); - 'step 2' - if(result.bool){ - var cards=result.cards; - event.cards=cards; - game.log(player,`将${get.cnNumber(cards.length)}张牌置入了牌堆`); - player.loseToDiscardpile(cards,ui.cardPile,'blank').set('log',false).insert_index=function(){ - return ui.cardPile.childNodes[get.rand(0,ui.cardPile.childNodes.length-1)]; - }; - } - else event.finish(); - 'step 3' - var list=[],shown=[] - var piles=['cardPile','discardPile']; - for(var pile of piles){ - for(var i=0;i { + return 6 - get.value(card); + }); + "step 2"; + if (result.bool) { + var cards = result.cards; + event.cards = cards; + game.log(player, `将${get.cnNumber(cards.length)}张牌置入了牌堆`); + player.loseToDiscardpile(cards, ui.cardPile, "blank").set("log", false).insert_index = + function () { + return ui.cardPile.childNodes[get.rand(0, ui.cardPile.childNodes.length - 1)]; + }; + } else event.finish(); + "step 3"; + var list = [], + shown = []; + var piles = ["cardPile", "discardPile"]; + for (var pile of piles) { + for (var i = 0; i < ui[pile].childNodes.length; i++) { + var card = ui[pile].childNodes[i]; + var number = get.number(card, false); + if (!list.includes(card) && number == 8) { list.push(card); - if(pile=='discardPile') shown.push(card); - if(list.length>=cards.length) break; + if (pile == "discardPile") shown.push(card); + if (list.length >= cards.length) break; } } - if(list.length>=cards.length) break; + if (list.length >= cards.length) break; } - if(list.length){ - var next=player.gain(list); - next.shown_cards=shown; - next.set('animate',function(event){ - var player=event.player,cards=event.cards,shown=event.shown_cards; - if(shown.length0){ - player.$gain2(shown,false); - game.log(player,'从弃牌堆获得了',shown); + if (shown.length > 0) { + player.$gain2(shown, false); + game.log(player, "从弃牌堆获得了", shown); } return 500; }); - next.gaintag.add('dcxiongmu_tag'); - player.addTempSkill('dcxiongmu_tag','roundStart'); + next.gaintag.add("dcxiongmu_tag"); + player.addTempSkill("dcxiongmu_tag", "roundStart"); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target.countCards('h')>target.getHp()||player.hasSkillTag('jueqing')) return; - if(player._dcxiongmu_temp) return; - if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; - if(get.tag(card,'damage')){ - if(target.getHistory('damage').length>0){ - return [1,-2]; - } - else{ - if(get.attitude(player,target)>0&&target.hp>1){ + ai: { + effect: { + target: function (card, player, target) { + if (target.countCards("h") > target.getHp() || player.hasSkillTag("jueqing")) + return; + if (player._dcxiongmu_temp) return; + if ( + _status.event.getParent("useCard", true) || + _status.event.getParent("_wuxie", true) + ) + return; + if (get.tag(card, "damage")) { + if (target.getHistory("damage").length > 0) { + return [1, -2]; + } else { + if (get.attitude(player, target) > 0 && target.hp > 1) { return 0; } - if(get.attitude(player,target)<0&&!player.hasSkillTag('damageBonus')){ - if(card.name=='sha') return; - var sha=false; - player._dcxiongmu_temp=true; - var num=player.countCards('h',function(card){ - if(card.name=='sha'){ - if(sha){ + if ( + get.attitude(player, target) < 0 && + !player.hasSkillTag("damageBonus") + ) { + if (card.name == "sha") return; + var sha = false; + player._dcxiongmu_temp = true; + var num = player.countCards("h", function (card) { + if (card.name == "sha") { + if (sha) { return false; - } - else{ - sha=true; + } else { + sha = true; } } - return get.tag(card,'damage')&&player.canUse(card,target)&&get.effect(target,card,player,player)>0; + return ( + get.tag(card, "damage") && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); }); delete player._dcxiongmu_temp; - if(player.hasSkillTag('damage')){ + if (player.hasSkillTag("damage")) { num++; } - if(num<2){ - var enemies=player.getEnemies(); - if(enemies.length==1&&enemies[0]==target&&player.needsToDiscard()){ + if (num < 2) { + var enemies = player.getEnemies(); + if ( + enemies.length == 1 && + enemies[0] == target && + player.needsToDiscard() + ) { return; } return 0; @@ -2186,3506 +3754,4274 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } } - } - } - }, - subSkill:{ - minus:{ - audio:'dcxiongmu', - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return player.countCards('h')<=player.getHp()&&game.getGlobalHistory('everything',evt=>{ - return evt.name=='damage'&&evt.player==player; - },event).indexOf(event)==0; }, - forced:true, - locked:false, - content:function(){ + }, + }, + subSkill: { + minus: { + audio: "dcxiongmu", + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return ( + player.countCards("h") <= player.getHp() && + game + .getGlobalHistory( + "everything", + (evt) => { + return evt.name == "damage" && evt.player == player; + }, + event + ) + .indexOf(event) == 0 + ); + }, + forced: true, + locked: false, + content: function () { trigger.num--; - } + }, }, - tag:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('dcxiongmu_tag'); + tag: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("dcxiongmu_tag"); }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcxiongmu_tag')) return true; + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcxiongmu_tag")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcxiongmu_tag')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcxiongmu_tag")) return false; }, }, - } - } + }, + }, }, - dczhangcai:{ - audio:2, - mod:{ - aiOrder:(player,card,num)=>{ - if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0; + dczhangcai: { + audio: 2, + mod: { + aiOrder: (player, card, num) => { + if ( + num > 0 && + get.tag(card, "draw") && + ui.cardPile.childNodes.length + ui.discardPile.childNodes.length < 20 + ) + return 0; }, - aiValue:(player,card,num)=>{ - if(num>0&&card.name==='zhuge') return 20; + aiValue: (player, card, num) => { + if (num > 0 && card.name === "zhuge") return 20; + }, + aiUseful: (player, card, num) => { + if (num > 0 && card.name === "zhuge") return 10; }, - aiUseful:(player,card,num)=>{ - if(num>0&&card.name==='zhuge') return 10; - } }, - trigger:{ - player:['useCard','respond'], + trigger: { + player: ["useCard", "respond"], }, - filter:function(event,player){ - if(player.hasSkill('dczhangcai_all')) return true; - return get.number(event.card)==8; + filter: function (event, player) { + if (player.hasSkill("dczhangcai_all")) return true; + return get.number(event.card) == 8; }, - prompt2:function(event,player){ - const num=player.hasSkill('dczhangcai_all')?get.number(event.card):8; - let count=1; - if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num)) - return '你可以摸'+get.cnNumber(count)+'张牌。'; + prompt2: function (event, player) { + const num = player.hasSkill("dczhangcai_all") ? get.number(event.card) : 8; + let count = 1; + if (typeof num == "number") + count = Math.max( + 1, + player.countCards("h", (card) => get.number(card) == num) + ); + return "你可以摸" + get.cnNumber(count) + "张牌。"; }, - check:(event,player)=>{ - const num=player.hasSkill('dczhangcai_all')?get.number(event.card):8; - let count=1; - if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num)); - return ui.cardPile.childNodes.length+ui.discardPile.childNodes.length>=count; + check: (event, player) => { + const num = player.hasSkill("dczhangcai_all") ? get.number(event.card) : 8; + let count = 1; + if (typeof num == "number") + count = Math.max( + 1, + player.countCards("h", (card) => get.number(card) == num) + ); + return ui.cardPile.childNodes.length + ui.discardPile.childNodes.length >= count; }, - frequent:true, - locked:false, - content:function(){ - var num=player.hasSkill('dczhangcai_all')?get.number(trigger.card):8; - var count=1; - if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num)); + frequent: true, + locked: false, + content: function () { + var num = player.hasSkill("dczhangcai_all") ? get.number(trigger.card) : 8; + var count = 1; + if (typeof num == "number") + count = Math.max( + 1, + player.countCards("h", (card) => get.number(card) == num) + ); player.draw(count); }, - ai:{ - threaten:4, + ai: { + threaten: 4, }, - subSkill:{ - all:{ - charlotte:true, - mark:true, - intro:{ - content:'当你使用或打出牌时,你可以摸X张牌(X为你手牌中与此牌点数相同的牌数且至少为1)' + subSkill: { + all: { + charlotte: true, + mark: true, + intro: { + content: + "当你使用或打出牌时,你可以摸X张牌(X为你手牌中与此牌点数相同的牌数且至少为1)", }, }, - } - }, - dcruxian:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'wood', - content:function(){ - 'step 0' - player.awakenSkill('dcruxian'); - player.addTempSkill('dczhangcai_all',{player:'phaseBegin'}); }, - ai:{ - order:15, - result:{ - player:function(player){ - if(!player.hasSkill('dczhangcai')) return 0; - if(player.countCards('hs',card=>get.number(card)!=8&&player.hasValueTarget(card))>3||player.hp==1) return 5; + }, + dcruxian: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "wood", + content: function () { + "step 0"; + player.awakenSkill("dcruxian"); + player.addTempSkill("dczhangcai_all", { player: "phaseBegin" }); + }, + ai: { + combo: "dczhangcai", + order: 15, + result: { + player: function (player) { + if (!player.hasSkill("dczhangcai")) return 0; + if ( + player.countCards( + "hs", + (card) => get.number(card) != 8 && player.hasValueTarget(card) + ) > 3 || + player.hp == 1 + ) + return 5; return 0; - } - } - } + }, + }, + }, }, //新杀许靖 - dcshangyu:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + dcshangyu: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - return event.name!='phase'||game.phaseNumber==0; + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - content:function(){ - 'step 0' - var card=get.cardPile(card=>get.name(card,false)=='sha'); - if(card){ - event.card=card; - player.gain(card,'gain2').gaintag.add('dcshangyu_tag'); - player.markAuto('dcshangyu',card); - } - else{ - player.chat('不是,连杀都没有?'); + forced: true, + content: function () { + "step 0"; + var card = get.cardPile((card) => get.name(card, false) == "sha"); + if (card) { + event.card = card; + player.gain(card, "gain2").gaintag.add("dcshangyu_tag"); + player.markAuto("dcshangyu", card); + } else { + player.chat("不是,连杀都没有?"); event.finish(); } - 'step 1' - if(get.owner(card)==player&&get.position(card)=='h'&&game.hasPlayer(current=>current!=player)){ - let targets=game.filterPlayer(i=>{ - return get.attitude(player,i)>0; - },null,true).sortBySeat(get.zhu(player)||game.findPlayer(i=>{ - return i.getSeatNum()===1; - })); - if(targets.includes(player)) targets=targets.slice(0,targets.indexOf(player)); - player.chooseTarget(`是否将${get.translation(card)}交给一名其他角色?`,lib.filter.notMe).set('ai',target=>{ - let idx=_status.event.targets.indexOf(target); - if(idx<0) return -1; - return 1/(idx+1); - }).set('targets',targets); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if ( + get.owner(card) == player && + get.position(card) == "h" && + game.hasPlayer((current) => current != player) + ) { + let targets = game + .filterPlayer( + (i) => { + return get.attitude(player, i) > 0; + }, + null, + true + ) + .sortBySeat( + get.zhu(player) || + game.findPlayer((i) => { + return i.getSeatNum() === 1; + }) + ); + if (targets.includes(player)) targets = targets.slice(0, targets.indexOf(player)); + player + .chooseTarget( + `是否将${get.translation(card)}交给一名其他角色?`, + lib.filter.notMe + ) + .set("ai", (target) => { + let idx = _status.event.targets.indexOf(target); + if (idx < 0) return -1; + return 1 / (idx + 1); + }) + .set("targets", targets); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.2); - player.give(card,target).gaintag.add('dcshangyu_tag'); + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.2); + player.give(card, target).gaintag.add("dcshangyu_tag"); } - player.addSkill('dcshangyu_effect'); + player.addSkill("dcshangyu_effect"); }, - subSkill:{ - effect:{ - audio:'dcshangyu', - trigger:{ - global:'damageSource', + subSkill: { + effect: { + audio: "dcshangyu", + trigger: { + global: "damageSource", }, - filter:function(event,player){ - return event.cards&&event.cards.some(card=>player.getStorage('dcshangyu').includes(card)); + filter: function (event, player) { + return ( + event.cards && + event.cards.some((card) => player.getStorage("dcshangyu").includes(card)) + ); }, - forced:true, - charlotte:true, - direct:true, - group:['dcshangyu_transfer','dcshangyu_addTag'], - content:function(){ - 'step 0' - var list=[player]; - if(trigger.source&&trigger.source.isIn()){ - player.logSkill('dcshangyu_effect',trigger.source); + forced: true, + charlotte: true, + direct: true, + group: ["dcshangyu_transfer", "dcshangyu_addTag"], + content: function () { + "step 0"; + var list = [player]; + if (trigger.source && trigger.source.isIn()) { + player.logSkill("dcshangyu_effect", trigger.source); list.push(trigger.source); - } - else player.logSkill('dcshangyu_effect'); + } else player.logSkill("dcshangyu_effect"); list.sortBySeat(); game.asyncDraw(list); - } - }, - transfer:{ - audio:'dcshangyu', - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], }, - forced:true, - direct:true, - filter:function(event,player){ - if(!game.hasPlayer(current=>{ - return !player.getStorage('dcshangyu_transfer').includes(current); - })) return false; - return event.getd().some(card=>{ - return get.position(card)=='d'&&player.getStorage('dcshangyu').includes(card); + }, + transfer: { + audio: "dcshangyu", + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], + }, + forced: true, + direct: true, + filter: function (event, player) { + if ( + !game.hasPlayer((current) => { + return !player.getStorage("dcshangyu_transfer").includes(current); + }) + ) + return false; + return event.getd().some((card) => { + return ( + get.position(card) == "d" && player.getStorage("dcshangyu").includes(card) + ); }); }, - content:function(){ - 'step 0' - var cards=trigger.getd().filter(card=>{ - return get.position(card)=='d'&&player.getStorage('dcshangyu').includes(card); - }),targets=game.filterPlayer(current=>{ - return !player.getStorage('dcshangyu_transfer').includes(current); - }).sortBySeat(_status.currentPhase); - if(targets.length&&targets[0]===_status.currentPhase&&!_status.currentPhase.getCardUsable('sha')) targets.push(targets.shift()); - event.cards=cards; - player.chooseTarget(`赏誉:将${get.translation(cards)}交给一名可选角色`,(card,player,target)=>{ - return !player.getStorage('dcshangyu_transfer').includes(target); - },true).set('ai',target=>{ - let att=get.sgnAttitude(_status.event.player,target),idx=1+_status.event.targets.indexOf(target); - if(att<0) return -idx; - return att+1/idx; - }).set('targets',targets); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcshangyu_transfer',target); - if(!player.storage.dcshangyu_transfer){ - player.when({global:'phaseAfter'}) - .then(()=>{ - player.unmarkSkill('dcshangyu_transfer'); - delete player.storage.dcshangyu_transfer; - }); + content: function () { + "step 0"; + var cards = trigger.getd().filter((card) => { + return ( + get.position(card) == "d" && + player.getStorage("dcshangyu").includes(card) + ); + }), + targets = game + .filterPlayer((current) => { + return !player.getStorage("dcshangyu_transfer").includes(current); + }) + .sortBySeat(_status.currentPhase); + if ( + targets.length && + targets[0] === _status.currentPhase && + !_status.currentPhase.getCardUsable("sha") + ) + targets.push(targets.shift()); + event.cards = cards; + player + .chooseTarget( + `赏誉:将${get.translation(cards)}交给一名可选角色`, + (card, player, target) => { + return !player.getStorage("dcshangyu_transfer").includes(target); + }, + true + ) + .set("ai", (target) => { + let att = get.sgnAttitude(_status.event.player, target), + idx = 1 + _status.event.targets.indexOf(target); + if (att < 0) return -idx; + return att + 1 / idx; + }) + .set("targets", targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcshangyu_transfer", target); + if (!player.storage.dcshangyu_transfer) { + player.when({ global: "phaseAfter" }).then(() => { + player.unmarkSkill("dcshangyu_transfer"); + delete player.storage.dcshangyu_transfer; + }); } - player.markAuto('dcshangyu_transfer',target); - target.gain(cards,'gain2').set('giver',player).gaintag.add('dcshangyu_tag'); + player.markAuto("dcshangyu_transfer", target); + target.gain(cards, "gain2").set("giver", player).gaintag.add("dcshangyu_tag"); } }, - intro:{ - content:'本回合已交给过$', + intro: { + content: "本回合已交给过$", }, }, - addTag:{ - trigger:{ - global:['gainAfter','loseAsyncAfter'], + addTag: { + trigger: { + global: ["gainAfter", "loseAsyncAfter"], }, - charlotte:true, - popup:false, - silent:true, - lastDo:true, - filter:function(event,player){ - return game.hasPlayer(current=>{ - var cards=event.getg(current); - return cards.some(card=>player.getStorage('dcshangyu').includes(card)); + charlotte: true, + popup: false, + silent: true, + lastDo: true, + filter: function (event, player) { + return game.hasPlayer((current) => { + var cards = event.getg(current); + return cards.some((card) => player.getStorage("dcshangyu").includes(card)); }); }, - content:function(){ - game.countPlayer(current=>{ - var cards=trigger.getg(current); - if(cards.length){ - cards=cards.filter(card=>player.getStorage('dcshangyu').includes(card)); - current.addGaintag(cards,'dcshangyu_tag'); + content: function () { + game.countPlayer((current) => { + var cards = trigger.getg(current); + if (cards.length) { + cards = cards.filter((card) => + player.getStorage("dcshangyu").includes(card) + ); + current.addGaintag(cards, "dcshangyu_tag"); } }); }, }, }, }, - dccaixia:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + dccaixia: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter:function(event,player){ - return !player.hasMark('dccaixia_clear'); + filter: function (event, player) { + return !player.hasMark("dccaixia_clear"); }, - direct:true, - locked:false, - content:function(){ - 'step 0' - var choices=Array.from({length:Math.min(5,game.players.length+game.dead.length)}).map((_,i)=>get.cnNumber(i+1,true)); - player.chooseControl(choices,'cancel2').set('prompt',get.prompt('dccaixia')).set('prompt2','你可以摸至多'+get.cnNumber(choices.length)+'张牌,但是你此后需要再使用等量的牌才可再发动本技能。').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var cards=player.getCards('hs',card=>get.name(card,player)!=='sha'&&player.hasValueTarget(card)); - var damage=Math.min(player.getCardUsable({name:'sha'}),player.countCards('hs','sha'))+cards.filter(i=>get.tag(i,'damage')).length; - if(player.isPhaseUsing()||player.hp+player.hujia+player.countCards('hs',i=>get.tag(card,'recover'))>2){ - if(damage) return Math.min(choices.length-1,cards.length-damage); - return Math.min(choices.length-1,cards.length-1); - } - return choices.length-1; - }()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dccaixia'); - var num=result.index+1; + direct: true, + locked: false, + content: function () { + "step 0"; + var choices = Array.from({ + length: Math.min(5, game.players.length + game.dead.length), + }).map((_, i) => get.cnNumber(i + 1, true)); + player + .chooseControl(choices, "cancel2") + .set("prompt", get.prompt("dccaixia")) + .set( + "prompt2", + "你可以摸至多" + + get.cnNumber(choices.length) + + "张牌,但是你此后需要再使用等量的牌才可再发动本技能。" + ) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var cards = player.getCards( + "hs", + (card) => get.name(card, player) !== "sha" && player.hasValueTarget(card) + ); + var damage = + Math.min( + player.getCardUsable({ name: "sha" }), + player.countCards("hs", "sha") + ) + cards.filter((i) => get.tag(i, "damage")).length; + if ( + player.isPhaseUsing() || + player.hp + + player.hujia + + player.countCards("hs", (i) => get.tag(card, "recover")) > + 2 + ) { + if (damage) return Math.min(choices.length - 1, cards.length - damage); + return Math.min(choices.length - 1, cards.length - 1); + } + return choices.length - 1; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dccaixia"); + var num = result.index + 1; player.draw(num); - player.addMark('dccaixia_clear',num); - player.addSkill('dccaixia_clear'); + player.addMark("dccaixia_clear", num); + player.addSkill("dccaixia_clear"); } }, - mod:{ - aiOrder:function(player,card,num){ - if(!get.tag(card,'damage')) return; - if(player.countMark('dccaixia_clear')>1) return num/3; - return num+6; + mod: { + aiOrder: function (player, card, num) { + if (!get.tag(card, "damage")) return; + if (player.countMark("dccaixia_clear") > 1) return num / 3; + return num + 6; }, }, - subSkill:{ - clear:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - return player.hasMark('dccaixia_clear'); + subSkill: { + clear: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + return player.hasMark("dccaixia_clear"); }, - forced:true, - popup:false, - charlotte:true, - content:function(){ - player.removeMark('dccaixia_clear',1); + forced: true, + popup: false, + charlotte: true, + content: function () { + player.removeMark("dccaixia_clear", 1); }, - intro:{ - name:'才瑕', - name2:'瑕', - content:'距离刷新技能还需使用&张牌', + intro: { + name: "才瑕", + name2: "瑕", + content: "距离刷新技能还需使用&张牌", }, - } + }, }, }, //十周年二乔 dcxingwu: { intro: { - content: 'expansion', - markcount: 'expansion', + content: "expansion", + markcount: "expansion", onunmark: function (storage, player) { - player.removeAdditionalSkill('dcluoyan'); + player.removeAdditionalSkill("dcluoyan"); }, }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, - audio: 'xingwu', - trigger: { player: 'phaseDiscardBegin' }, + audio: "xingwu", + trigger: { player: "phaseDiscardBegin" }, filter: function (event, player) { - return player.countCards('h'); + return player.countCards("h"); }, direct: true, content: function () { - 'step 0' - player.chooseCard('h', get.prompt('dcxingwu'), '将一张手牌作为“舞”置于武将牌上').set('ai', function (card) { - var att = 1, list = []; - for (var i of player.getExpansions('dcxingwu')) { - if (!list.includes(get.suit(i))) list.push(get.suit(i)); - } - if (!list.includes(get.suit(card))) att = 2; - if (_status.event.goon) return (20 - get.value(card)) * att; - return (7 - get.value(card)) * att; - }).set('goon', player.needsToDiscard() || player.getExpansions('dcxingwu').length == 2); - 'step 1' + "step 0"; + player + .chooseCard("h", get.prompt("dcxingwu"), "将一张手牌作为“舞”置于武将牌上") + .set("ai", function (card) { + var att = 1, + list = []; + for (var i of player.getExpansions("dcxingwu")) { + if (!list.includes(get.suit(i))) list.push(get.suit(i)); + } + if (!list.includes(get.suit(card))) att = 2; + if (_status.event.goon) return (20 - get.value(card)) * att; + return (7 - get.value(card)) * att; + }) + .set("goon", player.needsToDiscard() || player.getExpansions("dcxingwu").length == 2); + "step 1"; if (result.bool) { - player.logSkill('dcxingwu'); + player.logSkill("dcxingwu"); var cards = result.cards; - player.addToExpansion(cards, player, 'give').gaintag.add('dcxingwu'); + player.addToExpansion(cards, player, "give").gaintag.add("dcxingwu"); } - 'step 2' + "step 2"; game.delayx(); - if (player.getExpansions('dcxingwu').length > 2) { - player.chooseButton(['是否移去三张“舞”并发射核弹?', player.getExpansions('dcxingwu')], 3).ai = (button) => { - if (game.hasPlayer(function (current) { - return get.attitude(player, current) < 0; - })) return 1; + if (player.getExpansions("dcxingwu").length > 2) { + player.chooseButton( + ["是否移去三张“舞”并发射核弹?", player.getExpansions("dcxingwu")], + 3 + ).ai = (button) => { + if ( + game.hasPlayer(function (current) { + return get.attitude(player, current) < 0; + }) + ) + return 1; return 0; - } - } - else event.finish(); - 'step 3' + }; + } else event.finish(); + "step 3"; if (result.bool) { event.cards = result.links; - var list = [], str = [ - '小型', - '中型', - '巨型' - ]; + var list = [], + str = [ + "小型", + "中型", + "巨型", + ]; for (var i of event.cards) { if (!list.includes(get.suit(i))) list.push(get.suit(i)); } - player.chooseTarget('请选择' + str[list.length - 1] + '核弹的投射的目标(伤害:' + list.length + '点)', lib.filter.notMe, true).ai = (target) => { + player.chooseTarget( + "请选择" + + str[list.length - 1] + + "核弹的投射的目标(伤害:" + + list.length + + "点)", + lib.filter.notMe, + true + ).ai = (target) => { var att = 1; - if (target.sex == 'male') att = 1.5; - if (target.hp == target.sex == 'male' ? 2 : 1) att *= 1.2; - if (get.mode() == 'identity' && player.identity == 'fan' && target.isZhu) att *= 3; - return (-get.attitude(player, target)) * att * (Math.max(1, target.countCards('e'))); - } + if (target.sex == "male") att = 1.5; + if ((target.hp == target.sex) == "male" ? 2 : 1) att *= 1.2; + if (get.mode() == "identity" && player.identity == "fan" && target.isZhu) + att *= 3; + return -get.attitude(player, target) * att * Math.max(1, target.countCards("e")); + }; } - 'step 4' + "step 4"; if (result.bool) { var list = []; for (var i of event.cards) { if (!list.includes(get.suit(i))) list.push(get.suit(i)); } player.loseToDiscardpile(event.cards); - player.logSkill('dcxingwu', result.targets[0]); - player.discardPlayerCard(result.targets[0], 'e', result.targets[0].countCards('e'), true); - result.targets[0].damage(result.targets[0].sex == 'female' ? 1 : list.length); + player.logSkill("dcxingwu", result.targets[0]); + player.discardPlayerCard( + result.targets[0], + "e", + result.targets[0].countCards("e"), + true + ); + result.targets[0].damage(result.targets[0].sex == "female" ? 1 : list.length); } }, }, - dcluoyan:{ - derivation:['retianxiang','liuli'], - init:function(player){ - if(player.getExpansions('dcxingwu').length) player.addAdditionalSkill('dcluoyan',['retianxiang','liuli']); - else player.removeAdditionalSkill('dcluoyan'); + dcluoyan: { + derivation: ["retianxiang", "liuli"], + init: function (player) { + if (player.getExpansions("dcxingwu").length) + player.addAdditionalSkill("dcluoyan", ["retianxiang", "liuli"]); + else player.removeAdditionalSkill("dcluoyan"); }, - onremove:function(player){ - player.removeAdditionalSkill('dcluoyan'); + onremove: function (player) { + player.removeAdditionalSkill("dcluoyan"); }, - trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']}, - filter:function(event,player){ - var cards=player.getExpansions('dcxingwu'),skills=player.additionalSkills.dcluoyan; - return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length))); + trigger: { player: ["loseAfter", "loseAsyncAfter", "addToExpansionAfter"] }, + filter: function (event, player) { + var cards = player.getExpansions("dcxingwu"), + skills = player.additionalSkills.dcluoyan; + return !( + (cards.length && skills && skills.length) || + (!cards.length && (!skills || !skills.length)) + ); }, - forced:true, - silent:true, - content:function(){ - lib.skill.dcluoyan.init(player,'dcluoyan'); + forced: true, + silent: true, + content: function () { + lib.skill.dcluoyan.init(player, "dcluoyan"); + }, + ai: { + combo: "dcxingwu" }, }, - retianxiang_daxiaoqiao:{ - audio:'tianxiang_daxiaoqiao', - inherit:'retianxiang', + retianxiang_daxiaoqiao: { + audio: "tianxiang_daxiaoqiao", + inherit: "retianxiang", }, //田尚衣 - dcposuo:{ - onChooseToUse:function(event){ - if(!game.online&&!event.dcposuo_cards){ - var player=event.player; - var evtx=event.getParent('phaseUse'); - var suits=lib.suit.slice(0).reverse(); - suits=suits.filter(suit=>!player.getStorage('dcposuo_suits').includes(suit)&&player.countCards('hs',card=>get.suit(card,player)==suit)); - if(!suits.length||player.getHistory('sourceDamage',evt=>{ - return evt.player!=player&&evt.getParent('phaseUse')==evtx; - }).length) event.set('dcposuo_cards',undefined); - else{ - var list=[],cards=Array.from(ui.cardPile.childNodes); + dcposuo: { + onChooseToUse: function (event) { + if (!game.online && !event.dcposuo_cards) { + var player = event.player; + var evtx = event.getParent("phaseUse"); + var suits = lib.suit.slice(0).reverse(); + suits = suits.filter( + (suit) => + !player.getStorage("dcposuo_suits").includes(suit) && + player.countCards("hs", (card) => get.suit(card, player) == suit) + ); + if ( + !suits.length || + player.getHistory("sourceDamage", (evt) => { + return evt.player != player && evt.getParent("phaseUse") == evtx; + }).length + ) + event.set("dcposuo_cards", undefined); + else { + var list = [], + cards = Array.from(ui.cardPile.childNodes); cards.addArray(Array.from(ui.discardPile.childNodes)); - game.countPlayer(current=>cards.addArray(current.getCards('hejxs'))); - for(var name of lib.inpile){ - if(!get.tag({name:name},'damage')||get.type(new lib.element.VCard({name:name}))==='delay') continue; - let same=cards.filter(card=>get.name(card,false)==name&&!get.natureList(card,false).length); - if(same.length){ - for(var suit of suits){ - if(same.some(card=>get.suit(card,false)==suit)){ - list.push([suit,'',name,undefined,suit]); + game.countPlayer((current) => cards.addArray(current.getCards("hejxs"))); + for (var name of lib.inpile) { + if ( + !get.tag({ name: name }, "damage") || + get.type(new lib.element.VCard({ name: name })) === "delay" + ) + continue; + let same = cards.filter( + (card) => + get.name(card, false) == name && !get.natureList(card, false).length + ); + if (same.length) { + for (var suit of suits) { + if (same.some((card) => get.suit(card, false) == suit)) { + list.push([suit, "", name, undefined, suit]); } } } - for(var nature of lib.inpile_nature){ - same=cards.filter(card=>get.name(card,false)==name&&get.is.sameNature(get.natureList(card,false),nature)); - if(same.length){ - for(var suit of suits){ - if(same.some(card=>get.suit(card,false)==suit)){ - list.push([suit,'',name,nature,suit]); + for (var nature of lib.inpile_nature) { + same = cards.filter( + (card) => + get.name(card, false) == name && + get.is.sameNature(get.natureList(card, false), nature) + ); + if (same.length) { + for (var suit of suits) { + if (same.some((card) => get.suit(card, false) == suit)) { + list.push([suit, "", name, nature, suit]); } } } } } - event.set('dcposuo_cards',list); + event.set("dcposuo_cards", list); } } }, - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return event.dcposuo_cards&&event.dcposuo_cards.length; + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return event.dcposuo_cards && event.dcposuo_cards.length; }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('婆娑',[event.dcposuo_cards,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("婆娑", [event.dcposuo_cards, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - return player.getUseValue({name:button.link[2],nature:button.link[3]}); + check: function (button) { + var player = _status.event.player; + return player.getUseValue({ name: button.link[2], nature: button.link[3] }); }, - backup:function(links,player){ + backup: function (links, player) { return { - suit:links[0][4], - filterCard:function(card,player){ - return get.suit(card,player)==lib.skill.dcposuo_backup.suit; + suit: links[0][4], + filterCard: function (card, player) { + return get.suit(card, player) == lib.skill.dcposuo_backup.suit; }, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, }, - check:function(card){ - return 6.5-get.value(card); + check: function (card) { + return 6.5 - get.value(card); }, - precontent:function(){ - player.logSkill('dcposuo'); + precontent: function () { + player.logSkill("dcposuo"); delete event.result.skill; - player.addTempSkill('dcposuo_suits','phaseUseAfter'); - player.markAuto('dcposuo_suits',[get.suit(event.result.cards[0])]); + player.addTempSkill("dcposuo_suits", "phaseUseAfter"); + player.markAuto("dcposuo_suits", [get.suit(event.result.cards[0])]); }, - } + }; }, - prompt:function(links,player){ - var suit=links[0][4]; - var name=links[0][2]; - var nature=links[0][3]; - return '将一张'+get.translation(suit)+'牌当作'+(get.translation(nature)||'')+get.translation(name)+'使用'; + prompt: function (links, player) { + var suit = links[0][4]; + var name = links[0][2]; + var nature = links[0][3]; + return ( + "将一张" + + get.translation(suit) + + "牌当作" + + (get.translation(nature) || "") + + get.translation(name) + + "使用" + ); }, }, - ai:{ - order:10, - result:{player:1}, + ai: { + order: 10, + result: { player: 1 }, }, - subSkill:{ - suits:{ - charlotte:true, - onremove:true, + subSkill: { + suits: { + charlotte: true, + onremove: true, }, }, }, - dcxiaoren:{ - audio:2, - trigger:{ - source:'damageSource' + dcxiaoren: { + audio: 2, + trigger: { + source: "damageSource", }, - usable:1, - check:(event,player)=>{ - let rev=game.countPlayer(i=>{ - return i.isDamaged()&&get.attitude(_status.event.player,i)>0; + usable: 1, + check: (event, player) => { + let rev = game.countPlayer((i) => { + return i.isDamaged() && get.attitude(_status.event.player, i) > 0; }); - if(!event.player.isIn()||game.countPlayer()<2) return rev; - if(get.damageEffect(event.player.getPrevious(),player,_status.event.player)>-rev) return true; - return get.damageEffect(event.player.getNext(),player,_status.event.player)>-rev; + if (!event.player.isIn() || game.countPlayer() < 2) return rev; + if (get.damageEffect(event.player.getPrevious(), player, _status.event.player) > -rev) + return true; + return get.damageEffect(event.player.getNext(), player, _status.event.player) > -rev; }, - content:function(){ - 'step 0' - player.addTempSkill('dcxiaoren_dying'); - event.target=trigger.player; - 'step 1' + content: function () { + "step 0"; + player.addTempSkill("dcxiaoren_dying"); + event.target = trigger.player; + "step 1"; player.judge(); - 'step 2' - if(result.color=='red') player.chooseTarget('绡刃:是否令一名角色回复1点体力(若回满则额外摸一张牌)?').set('ai',target=>{ - let rec=get.recoverEffect(target,_status.event.player,_status.event.player); - if(target.getDamagedHp()<=1) return rec+get.effect(target,{name:'draw'},target,_status.event.player); - return rec; - }); - else if(result.color!='black'||!trigger.player.isIn()||game.countPlayer()<2) event.goto(9); + "step 2"; + if (result.color == "red") + player + .chooseTarget("绡刃:是否令一名角色回复1点体力(若回满则额外摸一张牌)?") + .set("ai", (target) => { + let rec = get.recoverEffect( + target, + _status.event.player, + _status.event.player + ); + if (target.getDamagedHp() <= 1) + return ( + rec + + get.effect(target, { name: "draw" }, target, _status.event.player) + ); + return rec; + }); + else if (result.color != "black" || !trigger.player.isIn() || game.countPlayer() < 2) + event.goto(9); else event.goto(5); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - event.target=target; + "step 3"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; player.line(target); target.recover(); - } - else event.goto(9); - 'step 4' - if(event.target.isHealthy()) event.target.draw(); + } else event.goto(9); + "step 4"; + if (event.target.isHealthy()) event.target.draw(); event.goto(9); - 'step 5' - var targets=[].addArray([target.getPrevious(),target.getNext()]); - if(targets.length>1) player.chooseTarget('绡刃:对其中一名角色造成1点伤害',(card,player,target)=>{ - return _status.event.targets.includes(target); - },true).set('ai',target=>{ - let player=_status.event.player; - return get.damageEffect(target,player,player); - }).set('targets',targets); - else if(targets.length) event._result={bool:true,targets:targets}; - 'step 6' - if(result.bool){ - let target=result.targets[0]; - event.target=target; + "step 5"; + var targets = [].addArray([target.getPrevious(), target.getNext()]); + if (targets.length > 1) + player + .chooseTarget( + "绡刃:对其中一名角色造成1点伤害", + (card, player, target) => { + return _status.event.targets.includes(target); + }, + true + ) + .set("ai", (target) => { + let player = _status.event.player; + return get.damageEffect(target, player, player); + }) + .set("targets", targets); + else if (targets.length) event._result = { bool: true, targets: targets }; + "step 6"; + if (result.bool) { + let target = result.targets[0]; + event.target = target; player.line(target); - target.damage('nocard'); - } - else event.goto(9); - 'step 7' - if(player.storage.dcxiaoren_dying||get.is.blocked(event.name,player)) event._result={bool:false}; - else if(event.frequent) event._result={bool:true}; - else player.chooseBool('绡刃:是否再次进行判定并执行对应效果直到未能执行此项或有角色进入濒死状态?').set('ai',function(){ - return _status.event.bool; - }).set('bool',lib.skill.dcxiaoren.check({player:event.target},player)); - 'step 8' - if(result.bool){ - event.frequent=true; + target.damage("nocard"); + } else event.goto(9); + "step 7"; + if (player.storage.dcxiaoren_dying || get.is.blocked(event.name, player)) + event._result = { bool: false }; + else if (event.frequent) event._result = { bool: true }; + else + player + .chooseBool( + "绡刃:是否再次进行判定并执行对应效果直到未能执行此项或有角色进入濒死状态?" + ) + .set("ai", function () { + return _status.event.bool; + }) + .set("bool", lib.skill.dcxiaoren.check({ player: event.target }, player)); + "step 8"; + if (result.bool) { + event.frequent = true; event.goto(1); } - 'step 9' - player.removeSkill('dcxiaoren_dying'); + "step 9"; + player.removeSkill("dcxiaoren_dying"); }, - subSkill:{ - dying:{ - init:(player)=>{ + subSkill: { + dying: { + init: (player) => { delete player.storage.dcxiaoren_dying; }, - onremove:(player)=>{ + onremove: (player) => { delete player.storage.dcxiaoren_dying; }, - trigger:{global:'dying'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - player.storage.dcxiaoren_dying=true; - } + trigger: { global: "dying" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + player.storage.dcxiaoren_dying = true; + }, }, - } + }, }, //孙翎鸾 - dclingyue:{ - audio:2, - trigger:{global:'damageSource'}, - forced:true, - filter:function(event,player){ - if(!event.source||!event.source.isIn()) return false; - var history=event.source.actionHistory; - for(var i=history.length-1;i>=0;i--){ - if(i==history.length-1){ - if(history[i].sourceDamage.indexOf(event)>0) return false; - } - else if(history[i].sourceDamage.some(evt=>evt!=event)) return false; - if(history[i].isRound) break; + dclingyue: { + audio: 2, + trigger: { global: "damageSource" }, + forced: true, + filter: function (event, player) { + if (!event.source || !event.source.isIn()) return false; + var history = event.source.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + if (i == history.length - 1) { + if (history[i].sourceDamage.indexOf(event) > 0) return false; + } else if (history[i].sourceDamage.some((evt) => evt != event)) return false; + if (history[i].isRound) break; } return true; }, - content:function(){ - var num=1,current=_status.currentPhase; - if(current&&trigger.source!=current){ - var num=0,players=game.players.slice(0).concat(game.dead); - for(var target of players){ - target.getHistory('sourceDamage',function(evt){ - num+=evt.num; + content: function () { + var num = 1, + current = _status.currentPhase; + if (current && trigger.source != current) { + var num = 0, + players = game.players.slice(0).concat(game.dead); + for (var target of players) { + target.getHistory("sourceDamage", function (evt) { + num += evt.num; }); } } player.draw(num); }, }, - dcpandi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - var players=event.dcpandi; - if(!players||!players.length) return false; - var source=player.storage.dcpandi_effect; - return get.itemtype(source)!='player'||!source.isIn(); + dcpandi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + var players = event.dcpandi; + if (!players || !players.length) return false; + var source = player.storage.dcpandi_effect; + return get.itemtype(source) != "player" || !source.isIn(); }, - pandi_wrapKey:function(){ + pandi_wrapKey: function () { var str = ""; - for(var arg of arguments){ - if(arg === null || arg === undefined){ - str += (arg + "-"); + for (var arg of arguments) { + if (arg === null || arg === undefined) { + str += arg + "-"; continue; } - switch(get.itemtype(arg)){ - case 'player': - str+=("p:"+arg.playerid); + switch (get.itemtype(arg)) { + case "player": + str += "p:" + arg.playerid; break; - case 'card': - if(arg.cardid){ - str+=("c:"+arg.cardid); - }else{ - str+=("c:"+arg.name); + case "card": + if (arg.cardid) { + str += "c:" + arg.cardid; + } else { + str += "c:" + arg.name; } break; default: - str+=("n:"+arg); + str += "n:" + arg; break; } - str+="-"; + str += "-"; } return str; }, - pandi_effect:function(target,card,player,viewer){ - if(!_status.event)return get.effect(target,card,player,viewer); - var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); - var effect = _status.event.getTempCache('effect',key); - if(effect !== undefined)return effect; - effect = get.effect(target,card,player,viewer); - _status.event.putTempCache('effect',key,effect); + pandi_effect: function (target, card, player, viewer) { + if (!_status.event) return get.effect(target, card, player, viewer); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null, arguments); + var effect = _status.event.getTempCache("effect", key); + if (effect !== undefined) return effect; + effect = get.effect(target, card, player, viewer); + _status.event.putTempCache("effect", key, effect); return effect; }, - pandi_canUse:function(player,card,target,arg1,arg2){ - if(!_status.event)return player.canUse(card,target,arg1,arg2); - var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); - var effect = _status.event.getTempCache('canUse',key); - if(effect !== undefined)return effect; - effect = player.canUse(card,target,arg1,arg2); - _status.event.putTempCache('canUse',key,effect); + pandi_canUse: function (player, card, target, arg1, arg2) { + if (!_status.event) return player.canUse(card, target, arg1, arg2); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null, arguments); + var effect = _status.event.getTempCache("canUse", key); + if (effect !== undefined) return effect; + effect = player.canUse(card, target, arg1, arg2); + _status.event.putTempCache("canUse", key, effect); return effect; }, - pandi_effect_use:function(target,card,player,viewer){ - if(!_status.event)return get.effect_use(target,card,player,viewer); - var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); - var effect = _status.event.getTempCache('effect_use',key); - if(effect !== undefined)return effect; - effect = get.effect_use(target,card,player,viewer); - _status.event.putTempCache('effect_use',key,effect); + pandi_effect_use: function (target, card, player, viewer) { + if (!_status.event) return get.effect_use(target, card, player, viewer); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null, arguments); + var effect = _status.event.getTempCache("effect_use", key); + if (effect !== undefined) return effect; + effect = get.effect_use(target, card, player, viewer); + _status.event.putTempCache("effect_use", key, effect); return effect; }, - onChooseToUse:function(event){ - if(!game.online&&event.type=='phase'&&!event.dcpandi){ - var players=game.filterPlayer(function(current){ - return current!=event.player&¤t.getHistory('sourceDamage').length==0; - }) - event.set('dcpandi',players) + onChooseToUse: function (event) { + if (!game.online && event.type == "phase" && !event.dcpandi) { + var players = game.filterPlayer(function (current) { + return current != event.player && current.getHistory("sourceDamage").length == 0; + }); + event.set("dcpandi", players); } }, - filterTarget:function(card,player,target){ - var players=_status.event.dcpandi; - if(!players||!players.length) return false; + filterTarget: function (card, player, target) { + var players = _status.event.dcpandi; + if (!players || !players.length) return false; return players.includes(target); }, - content:function(){ - if(target.isIn()){ - player.storage.dcpandi_effect=target; - player.addTempSkill('dcpandi_effect','phaseUseAfter'); + content: function () { + if (target.isIn()) { + player.storage.dcpandi_effect = target; + player.addTempSkill("dcpandi_effect", "phaseUseAfter"); } }, - ai:{ - threaten:4, - order:12, - result:{ - player:function(player,target){ - return player.getCards('hs').reduce(function(eff,card){ - return Math.max(eff,lib.skill.dcpandi.getUseValue(card,target,player)-lib.skill.dcpandi.getUseValue(card,player,player)) - },0) + ai: { + threaten: 4, + order: 12, + result: { + player: function (player, target) { + return player.getCards("hs").reduce(function (eff, card) { + return Math.max( + eff, + lib.skill.dcpandi.getUseValue(card, target, player) - + lib.skill.dcpandi.getUseValue(card, player, player) + ); + }, 0); }, }, }, - getUseValue:function(card,player,viewer){ - if(typeof(card)=='string'){ - card={name:card,isCard:true}; + getUseValue: function (card, player, viewer) { + if (typeof card == "string") { + card = { name: card, isCard: true }; } - var key = lib.skill.dcpandi.pandi_wrapKey(card,player,viewer); - if(_status.event){ - var uv = _status.event.getTempCache('getUseValue',key); - if(uv!==undefined){ + var key = lib.skill.dcpandi.pandi_wrapKey(card, player, viewer); + if (_status.event) { + var uv = _status.event.getTempCache("getUseValue", key); + if (uv !== undefined) { return uv; } } - var targets=game.filterPlayer(); - var value=[]; - var min=0; - var info=get.info(card); - if(!info||info.notarget){ - if(_status.event){ - _status.event.putTempCache('getUseValue',key,0); + var targets = game.filterPlayer(); + var value = []; + var min = 0; + var info = get.info(card); + if (!info || info.notarget) { + if (_status.event) { + _status.event.putTempCache("getUseValue", key, 0); } return 0; } var range; - var select=get.copy(info.selectTarget); - if(select==undefined){ - if(info.filterTarget==undefined) { - if(_status.event){ - _status.event.putTempCache('getUseValue',key,true); + var select = get.copy(info.selectTarget); + if (select == undefined) { + if (info.filterTarget == undefined) { + if (_status.event) { + _status.event.putTempCache("getUseValue", key, true); } return true; } - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - if(info.singleCard) range=[1,1]; - game.checkMod(card,player,range,'selectTarget',player); - if(!range){ - if(_status.event){ - _status.event.putTempCache('getUseValue',key,0); + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); + if (!range) { + if (_status.event) { + _status.event.putTempCache("getUseValue", key, 0); } return 0; } - for(var i=0;iplayer.storage.dcpandi_effect, - content:function(){ - trigger.player=player.storage.dcpandi_effect; - trigger.noai=true; - player.removeSkill('dcpandi_effect'); + logTarget: (event, player) => player.storage.dcpandi_effect, + content: function () { + trigger.player = player.storage.dcpandi_effect; + trigger.noai = true; + player.removeSkill("dcpandi_effect"); game.delay(0.5); }, - ai:{ - order:function(card,player,target,current){ - if(typeof card!='object') return; - var source=player.storage.dcpandi_effect; - if(!source.isIn()||get.itemtype(source)!='player'||get.itemtype(source.storage.dcpandi_effect)=='player') return; - return [0,lib.skill.dcpandi.pandi_effect_use(target,card,source,player),0,lib.skill.dcpandi.pandi_effect(target,card,source,target)] + ai: { + order: function (card, player, target, current) { + if (typeof card != "object") return; + var source = player.storage.dcpandi_effect; + if ( + !source.isIn() || + get.itemtype(source) != "player" || + get.itemtype(source.storage.dcpandi_effect) == "player" + ) + return; + return [ + 0, + lib.skill.dcpandi.pandi_effect_use(target, card, source, player), + 0, + lib.skill.dcpandi.pandi_effect(target, card, source, target), + ]; }, }, - mod:{ - selectCard:function(card,player,range){ - var source=player.storage.dcpandi_effect; - if(!source.isIn()||get.itemtype(source)!='player'||get.itemtype(source.storage.dcpandi_effect)=='player') return; - var range,info=get.info(card); - var select=get.copy(info.selectTarget); - if(select==undefined){ - if(info.filterTarget==undefined) return [0,0]; - range=[1,1]; - } - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,source); - game.checkMod(card,source,range,'selectTarget',source); + mod: { + selectCard: function (card, player, range) { + var source = player.storage.dcpandi_effect; + if ( + !source.isIn() || + get.itemtype(source) != "player" || + get.itemtype(source.storage.dcpandi_effect) == "player" + ) + return; + var range, + info = get.info(card); + var select = get.copy(info.selectTarget); + if (select == undefined) { + if (info.filterTarget == undefined) return [0, 0]; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, source); + game.checkMod(card, source, range, "selectTarget", source); }, - cardEnabled2:function(card,player,event){ - var source=player.storage.dcpandi_effect; - if(!source.isIn()||get.itemtype(source)!='player'||get.itemtype(source.storage.dcpandi_effect)=='player') return; - var check=game.checkMod(card,source,event,'unchanged','cardEnabled2',source); + cardEnabled2: function (card, player, event) { + var source = player.storage.dcpandi_effect; + if ( + !source.isIn() || + get.itemtype(source) != "player" || + get.itemtype(source.storage.dcpandi_effect) == "player" + ) + return; + var check = game.checkMod( + card, + source, + event, + "unchanged", + "cardEnabled2", + source + ); return check; }, - cardEnabled:function(card,player,event){ - var source=player.storage.dcpandi_effect; - if(!source.isIn()||get.itemtype(source)!='player'||get.itemtype(source.storage.dcpandi_effect)=='player') return; - if(event==='forceEnable'){ - var mod=game.checkMod(card,source,event,'unchanged','cardEnabled',source); - if(mod!='unchanged') return mod; + cardEnabled: function (card, player, event) { + var source = player.storage.dcpandi_effect; + if ( + !source.isIn() || + get.itemtype(source) != "player" || + get.itemtype(source.storage.dcpandi_effect) == "player" + ) + return; + if (event === "forceEnable") { + var mod = game.checkMod( + card, + source, + event, + "unchanged", + "cardEnabled", + source + ); + if (mod != "unchanged") return mod; return true; - } - else{ - var filter=get.info(card).enable; - if(!filter) return; - var mod=game.checkMod(card,player,source,'unchanged','cardEnabled',source); - if(mod!='unchanged') return mod; - if(typeof filter=='boolean') return filter; - if(typeof filter=='function') return filter(card,source,event); + } else { + var filter = get.info(card).enable; + if (!filter) return; + var mod = game.checkMod( + card, + player, + source, + "unchanged", + "cardEnabled", + source + ); + if (mod != "unchanged") return mod; + if (typeof filter == "boolean") return filter; + if (typeof filter == "function") return filter(card, source, event); } }, - cardUsable:function(card,player,num){ - var source=player.storage.dcpandi_effect; - if(!source.isIn()||get.itemtype(source)!='player'||get.itemtype(source.storage.dcpandi_effect)=='player') return; - var event=_status.event; - if(event.type=='chooseToUse_button') event=event.getParent(); - if(source!=_status.event.player) return true; - if(info.updateUsable=='phaseUse'){ - if(event.getParent().name!='phaseUse') return true; - if(event.getParent().player!=source) return true; + cardUsable: function (card, player, num) { + var source = player.storage.dcpandi_effect; + if ( + !source.isIn() || + get.itemtype(source) != "player" || + get.itemtype(source.storage.dcpandi_effect) == "player" + ) + return; + var event = _status.event; + if (event.type == "chooseToUse_button") event = event.getParent(); + if (source != _status.event.player) return true; + if (info.updateUsable == "phaseUse") { + if (event.getParent().name != "phaseUse") return true; + if (event.getParent().player != source) return true; } - event.addCount_extra=true; - var num=info.usable; - if(typeof num=='function') num=num(card,source); - num=game.checkMod(card,source,num,event,'cardUsable',source); - if(typeof num!='number') return true; - if(source.countUsed(card)4) return false; - if(event.name=='die') return true; - return event.name!='phase'||game.phaseNumber==0; + forced: true, + filter: function (event, player) { + if (game.countGroup() > 4) return false; + if (event.name == "die") return true; + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - player.addSkill('dctongye_buff'); - var num=game.countGroup(); - if(num<=4){ - player.addMark('dctongye_handcard',3,false); - game.log(player,'手牌上限','#y+3'); + content: function () { + player.addSkill("dctongye_buff"); + var num = game.countGroup(); + if (num <= 4) { + player.addMark("dctongye_handcard", 3, false); + game.log(player, "手牌上限", "#y+3"); } - if(num<=3){ - player.addMark('dctongye_range',3,false); - game.log(player,'攻击范围','#y+3'); + if (num <= 3) { + player.addMark("dctongye_range", 3, false); + game.log(player, "攻击范围", "#y+3"); } - if(num<=2){ - player.addMark('dctongye_sha',3,false); - game.log(player,'使用杀的次数上限','#y+3'); + if (num <= 2) { + player.addMark("dctongye_sha", 3, false); + game.log(player, "使用杀的次数上限", "#y+3"); } - if(num<=1){ - player.addMark('dctongye_draw',3,false); - game.log(player,'摸牌阶段额定摸牌数','#y+3'); + if (num <= 1) { + player.addMark("dctongye_draw", 3, false); + game.log(player, "摸牌阶段额定摸牌数", "#y+3"); } }, - subSkill:{ - buff:{ - audio:'dctongye', - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ - if(!player.hasMark('dctongye_draw')) return false; + subSkill: { + buff: { + audio: "dctongye", + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { + if (!player.hasMark("dctongye_draw")) return false; return !event.numFixed; }, - content:function(){ - trigger.num+=player.countMark('dctongye_draw'); + content: function () { + trigger.num += player.countMark("dctongye_draw"); }, - charlotte:true, - onremove:['dctongye_handcard','dctongye_range','dctongye_sha','dctongye_draw'], - mark:true, - marktext:'统', - intro:{ - content:function(storage,player){ - var str=''; - var hand=player.countMark('dctongye_handcard'),range=player.countMark('dctongye_range'),sha=player.countMark('dctongye_sha'),draw=player.countMark('dctongye_draw'); - if(hand>0){ - str+='
            • 手牌上限+'+hand+';'; + charlotte: true, + onremove: ["dctongye_handcard", "dctongye_range", "dctongye_sha", "dctongye_draw"], + mark: true, + marktext: "统", + intro: { + content: function (storage, player) { + var str = ""; + var hand = player.countMark("dctongye_handcard"), + range = player.countMark("dctongye_range"), + sha = player.countMark("dctongye_sha"), + draw = player.countMark("dctongye_draw"); + if (hand > 0) { + str += "
            • 手牌上限+" + hand + ";"; } - if(range>0){ - str+='
            • 攻击范围+'+range+';'; + if (range > 0) { + str += "
            • 攻击范围+" + range + ";"; } - if(sha>0){ - str+='
            • 使用【杀】的次数上限+'+sha+';' + if (sha > 0) { + str += "
            • 使用【杀】的次数上限+" + sha + ";"; } - if(draw>0){ - str+='
            • 摸牌阶段额定摸牌数+'+draw+'。'; + if (draw > 0) { + str += "
            • 摸牌阶段额定摸牌数+" + draw + "。"; } - str=str.slice(0,-1)+'。'; + str = str.slice(0, -1) + "。"; return str; - } + }, }, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('dctongye_handcard'); + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("dctongye_handcard"); }, - attackRange:function(player,num){ - return num+player.countMark('dctongye_range'); + attackRange: function (player, num) { + return num + player.countMark("dctongye_range"); }, - cardUsable:function(card,player,num){ - if(card.name=='sha'){ - return num+player.countMark('dctongye_sha'); + cardUsable: function (card, player, num) { + if (card.name == "sha") { + return num + player.countMark("dctongye_sha"); } }, }, - ai:{ - threaten:2.6, + ai: { + threaten: 2.6, }, }, }, }, - dcmianyao:{ - audio:2, - trigger:{ - player:'phaseDrawEnd', + dcmianyao: { + audio: 2, + trigger: { + player: "phaseDrawEnd", }, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('h',get.prompt('dcmianyao'),'展示点数最小的一张牌并随机插入牌堆中,然后于回合结束时摸此牌点数张牌。',function(card,player){ - var num=get.number(card,player); - return !player.hasCard(card2=>{ - return card!=card2&&get.number(card2,player) { + return card != card2 && get.number(card2, player) < num; + }); + } + ) + .set("ai", (card) => { + var player = _status.event.player; + var value = player.getUseValue(card, null, true); + if (value > 5 && get.number(card) <= 2) return 0; + return 1 + 1 / Math.max(0.1, value); }); - }).set('ai',card=>{ - var player=_status.event.player; - var value=player.getUseValue(card,null,true); - if(value>5&&get.number(card)<=2) return 0; - return 1+1/Math.max(0.1,value); - }); - 'step 1' - if(result.bool){ - player.logSkill('dcmianyao'); - var card=result.cards[0]; - event.card=card; - player.showCards([card],get.translation(player)+'发动了【免徭】'); - } - else event.finish(); - 'step 2' - player.$throw(1,1000); - player.lose(card,ui.cardPile).insert_index=function(){ - return ui.cardPile.childNodes[get.rand(0,ui.cardPile.childNodes.length-1)]; - } - player.addTempSkill('dcmianyao_draw'); - var num=get.number(card); - if(num>0) player.addMark('dcmianyao_draw',num,false); + "step 1"; + if (result.bool) { + player.logSkill("dcmianyao"); + var card = result.cards[0]; + event.card = card; + player.showCards([card], get.translation(player) + "发动了【免徭】"); + } else event.finish(); + "step 2"; + player.$throw(1, 1000); + player.lose(card, ui.cardPile).insert_index = function () { + return ui.cardPile.childNodes[get.rand(0, ui.cardPile.childNodes.length - 1)]; + }; + player.addTempSkill("dcmianyao_draw"); + var num = get.number(card); + if (num > 0) player.addMark("dcmianyao_draw", num, false); }, - subSkill:{ - draw:{ - trigger:{ - player:'phaseEnd', + subSkill: { + draw: { + trigger: { + player: "phaseEnd", }, - filter:function(event,player){ - return player.hasMark('dcmianyao_draw'); + filter: function (event, player) { + return player.hasMark("dcmianyao_draw"); }, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - player.draw(player.countMark('dcmianyao_draw')); + forced: true, + charlotte: true, + onremove: true, + content: function () { + player.draw(player.countMark("dcmianyao_draw")); }, - } - } + }, + }, }, - dcchangqu:{ - audio:2, - enable:'phaseUse', - usable:1, - selectTarget:function(){ - return [1,game.countPlayer()-1]; + dcchangqu: { + audio: 2, + enable: "phaseUse", + usable: 1, + selectTarget: function () { + return [1, game.countPlayer() - 1]; }, - complexSelect:true, - complexTarget:true, - multitarget:true, - multiline:true, - filterTarget:function(card,player,target){ - if(player==target) return false; - var next=player.getNext(),prev=player.getPrevious(); - var selected=ui.selected.targets; - if(!selected.includes(next)&&!selected.includes(prev)) return (target==next||target==prev); - for(var i of selected){ - if(i.getNext()==target||i.getPrevious()==target) return true; + complexSelect: true, + complexTarget: true, + multitarget: true, + multiline: true, + filterTarget: function (card, player, target) { + if (player == target) return false; + var next = player.getNext(), + prev = player.getPrevious(); + var selected = ui.selected.targets; + if (!selected.includes(next) && !selected.includes(prev)) + return target == next || target == prev; + for (var i of selected) { + if (i.getNext() == target || i.getPrevious() == target) return true; } return false; }, - contentBefore:function(){ - event.getParent()._dcchangqu_targets=targets.slice(); + contentBefore: function () { + event.getParent()._dcchangqu_targets = targets.slice(); }, - content:function(){ - 'step 0' - event.targets=event.getParent()._dcchangqu_targets; - var current=targets[0]; - current.addMark('dcchangqu_warship'); - current.addMark('dcchangqu_warshipx',1,false); - event.num=0; + content: function () { + "step 0"; + event.targets = event.getParent()._dcchangqu_targets; + var current = targets[0]; + current.addMark("dcchangqu_warship"); + current.addMark("dcchangqu_warshipx", 1, false); + event.num = 0; game.delayx(); - 'step 1' - var target=targets.shift(); - event.target=target; - var num=Math.max(1,event.num); - var nextPlayer=targets.find(i=>{ + "step 1"; + var target = targets.shift(); + event.target = target; + var num = Math.max(1, event.num); + var nextPlayer = targets.find((i) => { return i.isIn(); }); - if(target.hasMark('dcchangqu_warshipx')){ - var prompt2='是否交给'+get.translation(player)+get.cnNumber(num)+'张手牌?'+(nextPlayer?'若如此做,将“战舰”移动给'+get.translation(nextPlayer)+',':',')+'否则你下次受到的属性伤害值+'+num; - target.chooseCard(get.translation(player)+'对你发动了【长驱】',prompt2,num).set('ai',card=>{ - if(_status.event.att>0) return 15-get.value(card); - if(_status.event.take) return 0; - return 8.2-0.8*Math.min(5,_status.event.target.hp+_status.event.target.hujia)-get.value(card); - }).set('att',get.attitude(target,player)).set('take',function(){ - var base=num; - var getEffect=function(target,player,num){ - var natures=['fire','thunder','ice']; - return natures.map(nature=>{ - return get.damageEffect(target,target,player,nature)*Math.sqrt(num)/Math.min(1.5,1+target.countCards('h')); - }).reduce((sum,eff)=>{ - return sum+eff; - },0)/natures.length; - } - var eff=getEffect(player,player,base); - return targets.some((current,ind)=>{ - var num=base+ind+1; - var effx=getEffect(current,player,num); - return effx { + if (_status.event.att > 0) return 15 - get.value(card); + if (_status.event.take) return 0; + return ( + 8.2 - + 0.8 * Math.min(5, _status.event.target.hp + _status.event.target.hujia) - + get.value(card) + ); + }) + .set("att", get.attitude(target, player)) + .set("take", function () { + var base = num; + var getEffect = function (target, player, num) { + var natures = ["fire", "thunder", "ice"]; + return ( + natures + .map((nature) => { + return ( + (get.damageEffect(target, target, player, nature) * + Math.sqrt(num)) / + Math.min(1.5, 1 + target.countCards("h")) + ); + }) + .reduce((sum, eff) => { + return sum + eff; + }, 0) / natures.length + ); + }; + var eff = getEffect(player, player, base); + return targets + .some((current, ind) => { + var num = base + ind + 1; + var effx = getEffect(current, player, num); + return effx < eff; + }) + .set("target", target); + }); + } else event.goto(4); + "step 2"; + if (result.bool) { + var cards = result.cards; + target.give(cards, player); event.num++; - } - else{ - target.addSkill('dcchangqu_add'); - target.addMark('dcchangqu_add',Math.max(1,event.num),false); + } else { + target.addSkill("dcchangqu_add"); + target.addMark("dcchangqu_add", Math.max(1, event.num), false); target.link(true); event.goto(4); } - 'step 3' - var nextPlayer=targets.find(i=>{ + "step 3"; + var nextPlayer = targets.find((i) => { return i.isIn(); }); - if(nextPlayer){ + if (nextPlayer) { target.line(nextPlayer); - nextPlayer.addMark('dcchangqu_warship',target.countMark('dcchangqu_warship')); - nextPlayer.addMark('dcchangqu_warshipx',target.countMark('dcchangqu_warshipx'),false); + nextPlayer.addMark("dcchangqu_warship", target.countMark("dcchangqu_warship")); + nextPlayer.addMark( + "dcchangqu_warshipx", + target.countMark("dcchangqu_warshipx"), + false + ); event.goto(1); game.delayx(); } - target.removeMark('dcchangqu_warship',target.countMark('dcchangqu_warship')); - target.removeMark('dcchangqu_warshipx',target.countMark('dcchangqu_warshipx'),false); - 'step 4' - var targets=game.players.slice().concat(game.dead); - targets.forEach(i=>{ + target.removeMark("dcchangqu_warship", target.countMark("dcchangqu_warship")); + target.removeMark("dcchangqu_warshipx", target.countMark("dcchangqu_warshipx"), false); + "step 4"; + var targets = game.players.slice().concat(game.dead); + targets.forEach((i) => { delete i.storage.dcchangqu_warshipx; }); }, - ai:{ - order:10, - expose:0.05, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var targets=game.filterPlayer(i=>i!=player); + ai: { + order: 10, + expose: 0.05, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + var targets = game.filterPlayer((i) => i != player); targets.sortBySeat(player); - var targets2=targets.reverse(); - var sum=0; - var maxSum=-Infinity,maxIndex=-1; - var maxSum2=-Infinity,maxIndex2=-1; - for(var i=0;imaxSum){ - maxSum=sum; - maxIndex=i; + var targets2 = targets.reverse(); + var sum = 0; + var maxSum = -Infinity, + maxIndex = -1; + var maxSum2 = -Infinity, + maxIndex2 = -1; + for (var i = 0; i < targets.length; i++) { + var current = targets[i]; + var att = -get.attitude(player, current) - 0.1; + var val = Math.sqrt(i + 1) * att; + val /= 0.01 + Math.max(3, current.countCards("h") / 2); + sum += val; + if (sum > maxSum) { + maxSum = sum; + maxIndex = i; } } - var sum=0; - for(var i=0;imaxSum2){ - maxSum2=sum; - maxIndex2=i; + var sum = 0; + for (var i = 0; i < targets2.length; i++) { + var current = targets[i]; + var att = -get.attitude(player, current) - 0.1; + var val = Math.sqrt(i + 1) * att; + val /= 0.01 + Math.max(3, current.countCards("h") / 2); + sum += val; + if (sum > maxSum2) { + maxSum2 = sum; + maxIndex2 = i; } } - if(maxSummaxIndex) return -100*get.sgnAttitude(player,target); - if(target==targets[ui.selected.targets.length]) return get.sgnAttitude(player,target); + if (ui.selected.targets.length > maxIndex) + return -100 * get.sgnAttitude(player, target); + if (target == targets[ui.selected.targets.length]) + return get.sgnAttitude(player, target); return 0; - } + }, }, }, - subSkill:{ - warship:{ - marktext:'舰', - intro:{ - name:'战舰', - name2:'战舰', - content:'这里停了&艘战舰!不过啥用没有。', - } + subSkill: { + warship: { + marktext: "舰", + intro: { + name: "战舰", + name2: "战舰", + content: "这里停了&艘战舰!不过啥用没有。", + }, }, - add:{ - trigger:{ - player:'damageBegin3', + add: { + trigger: { + player: "damageBegin3", }, - filter:function(event,player){ - return event.hasNature()&&player.hasMark('dcchangqu_add'); + filter: function (event, player) { + return event.hasNature() && player.hasMark("dcchangqu_add"); }, - forced:true, - onremove:true, - charlotte:true, - content:function(){ - 'step 0' - trigger.num+=player.countMark('dcchangqu_add'); - player.removeSkill('dcchangqu_add'); + forced: true, + onremove: true, + charlotte: true, + content: function () { + "step 0"; + trigger.num += player.countMark("dcchangqu_add"); + player.removeSkill("dcchangqu_add"); + }, + marktext: "驱", + intro: { + content: "下次受到的属性伤害+#", }, - marktext:'驱', - intro:{ - content:'下次受到的属性伤害+#', - } }, - } + }, }, //周不疑 - dcshiji:{ - audio:2, - trigger:{ - global:'phaseJieshuBegin', + dcshiji: { + audio: 2, + trigger: { + global: "phaseJieshuBegin", }, - filter:function(event,player){ - return event.player.isIn()&&!event.player.getHistory('sourceDamage').length; + filter: function (event, player) { + return event.player.isIn() && !event.player.getHistory("sourceDamage").length; }, - direct:true, - content:function(){ - 'step 0' - trigger.player.addTempSkill('dcshiji_forbidself'); - var list=[]; - for(var name of lib.inpile){ - var type=get.type(name); - if(type!='trick') continue; - if(player.getStorage('dcshiji_used').includes(name)) continue; - var card={ - name:name, - storage:{dcshiji:true}, + direct: true, + content: function () { + "step 0"; + trigger.player.addTempSkill("dcshiji_forbidself"); + var list = []; + for (var name of lib.inpile) { + var type = get.type(name); + if (type != "trick") continue; + if (player.getStorage("dcshiji_used").includes(name)) continue; + var card = { + name: name, + storage: { dcshiji: true }, }; - if(trigger.player.hasUseTarget(card)){ - list.push([type,'',name]); + if (trigger.player.hasUseTarget(card)) { + list.push([type, "", name]); } } - if(list.length){ - player.chooseButton([get.prompt('dcshiji',trigger.player),[list,'vcard']]).set('ai',button=>{ - if(_status.event.tochoose) return _status.event.getTrigger().player.getUseValue({name:button.link[2]}); - return 0; - }).set('tochoose',get.attitude(player,trigger.player)>0&&trigger.player.hasCard(card=>{ - return get.value(card)<7; - },'hes')); - } - else event.finish(); - 'step 1' - if(result.bool){ - var card={ - name:result.links[0][2], - storage:{dcshiji:true}, + if (list.length) { + player + .chooseButton([get.prompt("dcshiji", trigger.player), [list, "vcard"]]) + .set("ai", (button) => { + if (_status.event.tochoose) + return _status.event + .getTrigger() + .player.getUseValue({ name: button.link[2] }); + return 0; + }) + .set( + "tochoose", + get.attitude(player, trigger.player) > 0 && + trigger.player.hasCard((card) => { + return get.value(card) < 7; + }, "hes") + ); + } else event.finish(); + "step 1"; + if (result.bool) { + var card = { + name: result.links[0][2], + storage: { dcshiji: true }, }; - var str=get.translation(card); - player.logSkill('dcshiji',trigger.player); - player.addTempSkill('dcshiji_used','roundStart'); - player.markAuto('dcshiji_used',[card.name]); + var str = get.translation(card); + player.logSkill("dcshiji", trigger.player); + player.addTempSkill("dcshiji_used", "roundStart"); + player.markAuto("dcshiji_used", [card.name]); player.popup(str); - game.log(player,'声明了','#y'+str); - game.broadcastAll(function(card){ - lib.skill.dcshiji_backup.viewAs=card; - lib.skill.dcshiji_backup.prompt='十计:是否将一张牌当做'+get.translation(card)+'使用?'; - },card); - var next=trigger.player.chooseToUse(); - next.set('openskilldialog','十计:是否将一张牌当做'+get.translation(card)+'使用?'); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','dcshiji_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + game.log(player, "声明了", "#y" + str); + game.broadcastAll(function (card) { + lib.skill.dcshiji_backup.viewAs = card; + lib.skill.dcshiji_backup.prompt = + "十计:是否将一张牌当做" + get.translation(card) + "使用?"; + }, card); + var next = trigger.player.chooseToUse(); + next.set( + "openskilldialog", + "十计:是否将一张牌当做" + get.translation(card) + "使用?" + ); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "dcshiji_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('dcshiji_backup'); + next.backup("dcshiji_backup"); } }, - subSkill:{ - backup:{ - filterCard:function(card){ - return get.itemtype(card)=='card'; + subSkill: { + backup: { + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - position:'hes', - selectCard:1, - check:(card)=>7-get.value(card), - popname:true, + position: "hes", + selectCard: 1, + check: (card) => 7 - get.value(card), + popname: true, }, - used:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'计', - intro:{ - content:'本轮已声明过$', + used: { + charlotte: true, + onremove: true, + mark: true, + marktext: "计", + intro: { + content: "本轮已声明过$", }, }, - forbidself:{ - charlotte:true, - mod:{ - targetEnabled:function(card,player,target){ - if(player==target&&card.storage&&card.storage.dcshiji) return false; + forbidself: { + charlotte: true, + mod: { + targetEnabled: function (card, player, target) { + if (player == target && card.storage && card.storage.dcshiji) return false; }, }, - } - } - }, - dcsilun:{ - audio:2, - trigger:{ - player:['phaseZhunbeiBegin','damageEnd'], + }, }, - frequent:true, - content:function(){ - 'step 0' + }, + dcsilun: { + audio: 2, + trigger: { + player: ["phaseZhunbeiBegin", "damageEnd"], + }, + frequent: true, + content: function () { + "step 0"; player.draw(4); - event.count=0; - event.equipCount={}; - game.countPlayer(current=>{ - event.equipCount[current.playerid]=current.countCards('e'); - },true); - 'step 1' - if(!player.countCards('he')) event.goto(5); - else player.chooseCard('四论:选择一张牌('+(event.count+1)+'/'+'4)','然后选择将此牌置于场上或牌堆的两端',true,'he').set('ai',card=>{ - var player=_status.event.player; - if(['equip','delay'].includes(get.type(card))&&player.hasValueTarget(card)) return 50; - return 50-get.value(card); - }); - 'step 2' - if(result.bool){ - var card=result.cards[0]; - event.card=card; + event.count = 0; + event.equipCount = {}; + game.countPlayer((current) => { + event.equipCount[current.playerid] = current.countCards("e"); + }, true); + "step 1"; + if (!player.countCards("he")) event.goto(5); + else + player + .chooseCard( + "四论:选择一张牌(" + (event.count + 1) + "/" + "4)", + "然后选择将此牌置于场上或牌堆的两端", + true, + "he" + ) + .set("ai", (card) => { + var player = _status.event.player; + if ( + ["equip", "delay"].includes(get.type(card)) && + player.hasValueTarget(card) + ) + return 50; + return 50 - get.value(card); + }); + "step 2"; + if (result.bool) { + var card = result.cards[0]; + event.card = card; event.count++; - var choices=['牌堆顶','牌堆底']; - var type=get.type(card); - if(type=='equip'&&game.hasPlayer(current=>{ - return current.canEquip(card); - })||type=='delay'&&game.hasPlayer(current=>{ - return current.canAddJudge(card); - })) choices.unshift('场上'); - player.chooseControl(choices).set('prompt','请选择要将'+get.translation(card)+'置于的位置').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(['equip','delay'].includes(get.type(card))&&player.hasValueTarget(card)&&choices.includes('场上')) return '场上'; - var val=get.value(card); - var next=_status.currentPhase; - if(next){ - if(trigger.name=='damage') next=next.getNext(); - if(get.attitude(player,next)>0&&val>=6||get.attitude(player,next)<0&&val<=4.5) return '牌堆顶'; - } - return '牌堆底'; - }()); + var choices = ["牌堆顶", "牌堆底"]; + var type = get.type(card); + if ( + (type == "equip" && + game.hasPlayer((current) => { + return current.canEquip(card); + })) || + (type == "delay" && + game.hasPlayer((current) => { + return current.canAddJudge(card); + })) + ) + choices.unshift("场上"); + player + .chooseControl(choices) + .set("prompt", "请选择要将" + get.translation(card) + "置于的位置") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if ( + ["equip", "delay"].includes(get.type(card)) && + player.hasValueTarget(card) && + choices.includes("场上") + ) + return "场上"; + var val = get.value(card); + var next = _status.currentPhase; + if (next) { + if (trigger.name == "damage") next = next.getNext(); + if ( + (get.attitude(player, next) > 0 && val >= 6) || + (get.attitude(player, next) < 0 && val <= 4.5) + ) + return "牌堆顶"; + } + return "牌堆底"; + })() + ); } - 'step 3' - if(result.control=='场上'){ - var type=get.type(card); - player.chooseTarget('将'+get.translation(card)+'置于一名角色的场上',true,(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',game.filterPlayer(current=>{ - if(type=='equip') return current.canEquip(card); - if(type=='delay') return current.canAddJudge(card); - return false; - })).set('ai',target=>{ - var player=_status.event.player; - var card=_status.event.card; - return get.attitude(player,target)*(get.type(card)=='equip'?get.value(card,target):get.effect(target,{ - name:card.viewAs||card.name, - cards:[card], - },target,target)); - }).set('card',card); + "step 3"; + if (result.control == "场上") { + var type = get.type(card); + player + .chooseTarget( + "将" + get.translation(card) + "置于一名角色的场上", + true, + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set( + "targets", + game.filterPlayer((current) => { + if (type == "equip") return current.canEquip(card); + if (type == "delay") return current.canAddJudge(card); + return false; + }) + ) + .set("ai", (target) => { + var player = _status.event.player; + var card = _status.event.card; + return ( + get.attitude(player, target) * + (get.type(card) == "equip" + ? get.value(card, target) + : get.effect( + target, + { + name: card.viewAs || card.name, + cards: [card], + }, + target, + target + )) + ); + }) + .set("card", card); + } else { + player.$throw(card, 1000); + var next = player.lose(card, ui.cardPile, "visible"); + if (result.control == "牌堆顶") next.insert_card = true; + game.log(player, "将", card, "置于了", "#y" + result.control); } - else{ - player.$throw(card,1000); - var next=player.lose(card,ui.cardPile,'visible'); - if(result.control=='牌堆顶') next.insert_card=true; - game.log(player,'将',card,'置于了','#y'+result.control); - } - 'step 4' - if(result.bool&&result.targets&&result.targets.length){ - var target=result.targets[0]; + "step 4"; + if (result.bool && result.targets && result.targets.length) { + var target = result.targets[0]; player.line(target); - player.$give(card,target,false); - if(get.type(card)=='equip'){ + player.$give(card, target, false); + if (get.type(card) == "equip") { target.equip(card); - } - else{ + } else { target.addJudge(card); } } - 'step 5' - game.countPlayer(current=>{ - var count=current.countCards('e'); - var prevCount=event.equipCount[current.playerid]||0; - if(count!=prevCount){ + "step 5"; + game.countPlayer((current) => { + var count = current.countCards("e"); + var prevCount = event.equipCount[current.playerid] || 0; + if (count != prevCount) { current.link(false); current.turnOver(false); } - event.equipCount[current.playerid]=count; + event.equipCount[current.playerid] = count; }); - if(event.count<4) event.goto(1); - } + if (event.count < 4) event.goto(1); + }, }, //杜预 - dcjianguo:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('dcjianguo_0')||!player.hasSkill('dcjianguo_1'); + dcjianguo: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("dcjianguo_0") || !player.hasSkill("dcjianguo_1"); }, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('谏国:请选择一项','hidden'); - dialog.add([[ - ['discard','令一名角色摸一张牌,然后弃置一半手牌'], - ['draw','令一名角色弃置一张牌,然后摸等同于手牌数一半的牌'] - ],'textbutton']); + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("谏国:请选择一项", "hidden"); + dialog.add([ + [ + ["discard", "令一名角色摸一张牌,然后弃置一半手牌"], + ["draw", "令一名角色弃置一张牌,然后摸等同于手牌数一半的牌"], + ], + "textbutton", + ]); return dialog; }, - filter:function(button,player){ - if(button.link=='discard'&&player.hasSkill('dcjianguo_0')) return false; - if(button.link=='draw'&&player.hasSkill('dcjianguo_1')) return false; + filter: function (button, player) { + if (button.link == "discard" && player.hasSkill("dcjianguo_0")) return false; + if (button.link == "draw" && player.hasSkill("dcjianguo_1")) return false; return true; }, - check:function(button){ - var player=_status.event.player; - if(button.link=='discard'){ - var discard=Math.max.apply(Math,game.filterPlayer(current=>{ - return lib.skill.dcjianguo_discard.filterTarget(null,player,current); - }).map(current=>{ - return get.effect(current,'dcjianguo_discard',player,player); - })); + check: function (button) { + var player = _status.event.player; + if (button.link == "discard") { + var discard = Math.max.apply( + Math, + game + .filterPlayer((current) => { + return lib.skill.dcjianguo_discard.filterTarget( + null, + player, + current + ); + }) + .map((current) => { + return get.effect(current, "dcjianguo_discard", player, player); + }) + ); return discard; } - if(button.link=='draw'){ - var draw=Math.max.apply(Math,game.filterPlayer(current=>{ - return lib.skill.dcjianguo_draw.filterTarget(null,player,current); - }).map(current=>{ - return get.effect(current,'dcjianguo_draw',player,player); - })); + if (button.link == "draw") { + var draw = Math.max.apply( + Math, + game + .filterPlayer((current) => { + return lib.skill.dcjianguo_draw.filterTarget(null, player, current); + }) + .map((current) => { + return get.effect(current, "dcjianguo_draw", player, player); + }) + ); return draw; } return 0; }, - backup:function(links){ - return get.copy(lib.skill['dcjianguo_'+links[0]]); + backup: function (links) { + return get.copy(lib.skill["dcjianguo_" + links[0]]); }, - prompt:function(links){ - if(links[0]=='discard') return '令一名角色摸一张牌,然后弃置一半手牌'; - return '令一名角色弃置一张牌,然后摸等同于手牌数一半的牌'; + prompt: function (links) { + if (links[0] == "discard") return "令一名角色摸一张牌,然后弃置一半手牌"; + return "令一名角色弃置一张牌,然后摸等同于手牌数一半的牌"; }, }, - ai:{ - order:10, - threaten:2.8, - result:{ + ai: { + order: 10, + threaten: 2.8, + result: { //想让杜预两个技能自我联动写起来太累了,开摆 - player:1, + player: 1, }, }, - subSkill:{ - '0':{charlotte:true}, - '1':{charlotte:true}, - backup:{audio:'dcjianguo'}, - discard:{ - audio:'dcjianguo', - filterTarget:()=>true, - filterCard:()=>false, - selectCard:-1, - content:function(){ - 'step 0' - player.addTempSkill('dcjianguo_0','phaseUseAfter'); + subSkill: { + 0: { charlotte: true }, + 1: { charlotte: true }, + backup: { audio: "dcjianguo" }, + discard: { + audio: "dcjianguo", + filterTarget: () => true, + filterCard: () => false, + selectCard: -1, + content: function () { + "step 0"; + player.addTempSkill("dcjianguo_0", "phaseUseAfter"); target.draw(); game.delayex(); - 'step 1' - var num=Math.ceil(target.countCards('h')/2); - if(num>0) target.chooseToDiscard(num,true,'谏国:请弃置'+get.cnNumber(num)+'张手牌'); + "step 1"; + var num = Math.ceil(target.countCards("h") / 2); + if (num > 0) + target.chooseToDiscard( + num, + true, + "谏国:请弃置" + get.cnNumber(num) + "张手牌" + ); }, - ai:{ - result:{ - target:function(player,target){ - return 1.1-Math.floor(target.countCards('h')/2); + ai: { + result: { + target: function (player, target) { + return 1.1 - Math.floor(target.countCards("h") / 2); }, }, - tag:{ - gain:1, - loseCard:2, + tag: { + gain: 1, + loseCard: 2, }, }, }, - draw:{ - audio:'dcjianguo', - filterTarget:function(card,player,target){ - return target.countCards('he'); + draw: { + audio: "dcjianguo", + filterTarget: function (card, player, target) { + return target.countCards("he"); }, - filterCard:()=>false, - selectCard:-1, - content:function(){ - 'step 0' - player.addTempSkill('dcjianguo_1','phaseUseAfter'); - target.chooseToDiscard('he',true,'谏国:请弃置一张牌'); - 'step 1' - var num=Math.ceil(target.countCards('h')/2); - if(num>0) target.draw(num); + filterCard: () => false, + selectCard: -1, + content: function () { + "step 0"; + player.addTempSkill("dcjianguo_1", "phaseUseAfter"); + target.chooseToDiscard("he", true, "谏国:请弃置一张牌"); + "step 1"; + var num = Math.ceil(target.countCards("h") / 2); + if (num > 0) target.draw(num); }, - ai:{ - result:{ - target:function(player,target){ - var fix=0; - var num=target.countCards('h'); - if(player==target&&num%2==1&&num>=5) fix+=1; - return Math.ceil(num/2-0.5)+fix; + ai: { + result: { + target: function (player, target) { + var fix = 0; + var num = target.countCards("h"); + if (player == target && num % 2 == 1 && num >= 5) fix += 1; + return Math.ceil(num / 2 - 0.5) + fix; }, }, - tag:{ - loseCard:1, - gain:2, + tag: { + loseCard: 1, + gain: 2, }, }, }, }, }, - dcdyqingshi:{ - audio:2, - trigger:{ - player:'useCardToPlayered', + dcdyqingshi: { + audio: 2, + trigger: { + player: "useCardToPlayered", }, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - if(!event.isFirstTarget) return false; - if(event.card.name!='sha'&&get.type(event.card,false)!='trick') return false; - if(player.countCards('h')!=player.getHistory('useCard').indexOf(event.getParent())+1) return false; - return event.targets.some(target=>{ - return target!=player&&target.isIn(); + filter: function (event, player) { + if (player != _status.currentPhase) return false; + if (!event.isFirstTarget) return false; + if (event.card.name != "sha" && get.type(event.card, false) != "trick") return false; + if (player.countCards("h") != player.getHistory("useCard").indexOf(event.getParent()) + 1) + return false; + return event.targets.some((target) => { + return target != player && target.isIn(); }); }, - direct:true, - locked:false, - content:function(){ - 'step 0' - var targets=trigger.targets.filter(target=>{ - return target!=player&&target.isIn(); + direct: true, + locked: false, + content: function () { + "step 0"; + var targets = trigger.targets.filter((target) => { + return target != player && target.isIn(); }); - player.chooseTarget(get.prompt('dcdyqingshi'),'对一名不为你的目标角色造成1点伤害',(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('ai',target=>{ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }).set('targets',targets); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcdyqingshi',target); + player + .chooseTarget( + get.prompt("dcdyqingshi"), + "对一名不为你的目标角色造成1点伤害", + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }) + .set("targets", targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcdyqingshi", target); target.damage(); } }, - mod:{ - aiOrder:function(player,card,num){ - if(_status.currentPhase!=player) return; - var cardsh=[]; - if(Array.isArray(card.cards)){ - cardsh.addArray(card.cards.filter(card=>{ - return get.position(card)=='h'; - })); + mod: { + aiOrder: function (player, card, num) { + if (_status.currentPhase != player) return; + var cardsh = []; + if (Array.isArray(card.cards)) { + cardsh.addArray( + card.cards.filter((card) => { + return get.position(card) == "h"; + }) + ); } - var del=player.countCards('h')-cardsh.length-player.getHistory('useCard').length-1; - if(del<0) return; - if(del>0){ - if(card.name=='sha'||get.type(card,false)!='trick') return num/3; - return num+1; + var del = + player.countCards("h") - cardsh.length - player.getHistory("useCard").length - 1; + if (del < 0) return; + if (del > 0) { + if (card.name == "sha" || get.type(card, false) != "trick") return num / 3; + return num + 1; } - return num+15; + return num + 15; }, }, }, //甘糜 - dcchanjuan:{ - init:function(player){ - if(!player.storage.dcchanjuan){ - player.storage.dcchanjuan={}; + dcchanjuan: { + init: function (player) { + if (!player.storage.dcchanjuan) { + player.storage.dcchanjuan = {}; } }, - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(event.targets.length!=1||!player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - return event.cards.every(card=>evt.hs.includes(card)); - })) return false; - if(!['basic','trick'].includes(get.type(event.card,false))) return false; - if(event.getParent(2).name=='dcchanjuan') return false; - return !player.storage.dcchanjuan[event.card.name]||player.storage.dcchanjuan[event.card.name]<2; + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if ( + event.targets.length != 1 || + !player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + return event.cards.every((card) => evt.hs.includes(card)); + }) + ) + return false; + if (!["basic", "trick"].includes(get.type(event.card, false))) return false; + if (event.getParent(2).name == "dcchanjuan") return false; + return ( + !player.storage.dcchanjuan[event.card.name] || + player.storage.dcchanjuan[event.card.name] < 2 + ); }, - direct:true, - content:function(){ - 'step 0' - var card={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - } - player.chooseUseTarget(card,get.prompt('dcchanjuan'),false,false).set('prompt2','视为再使用一张'+get.translation(card)).set('logSkill','dcchanjuan'); - 'step 1' - if(result.bool){ - if(!player.storage.dcchanjuan[trigger.card.name]) player.storage.dcchanjuan[trigger.card.name]=0; + direct: true, + content: function () { + "step 0"; + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + }; + player + .chooseUseTarget(card, get.prompt("dcchanjuan"), false, false) + .set("prompt2", "视为再使用一张" + get.translation(card)) + .set("logSkill", "dcchanjuan"); + "step 1"; + if (result.bool) { + if (!player.storage.dcchanjuan[trigger.card.name]) + player.storage.dcchanjuan[trigger.card.name] = 0; player.storage.dcchanjuan[trigger.card.name]++; - var list1=trigger.targets,list2=result.targets; - if(list1.slice().removeArray(list2).length==0&&list2.slice().removeArray(list1).length==0) player.draw(); + var list1 = trigger.targets, + list2 = result.targets; + if ( + list1.slice().removeArray(list2).length == 0 && + list2.slice().removeArray(list1).length == 0 + ) + player.draw(); } }, - ai:{threaten:2}, - mark:true, - intro:{ - markcount:(storage)=>0, - content:function(storage){ - var str='已使用牌名:',names=Object.keys(storage); - if(!names.length) str+='无'; - else names.forEach(name=>{ - str+='
            • 【'; - str+=get.translation(name); - str+='】:'; - str+=storage[name]+'次'; - }); + ai: { threaten: 2 }, + mark: true, + intro: { + markcount: (storage) => 0, + content: function (storage) { + var str = "已使用牌名:", + names = Object.keys(storage); + if (!names.length) str += "无"; + else + names.forEach((name) => { + str += "
            • 【"; + str += get.translation(name); + str += "】:"; + str += storage[name] + "次"; + }); return str; }, }, }, - dcxunbie:{ - audio:2, - trigger:{ - player:'dying', + dcxunbie: { + audio: 2, + trigger: { + player: "dying", }, - filter:function(event,player){ - if(player.hp>0) return false; - var characters=['dc_ganfuren','dc_mifuren']; - game.countPlayer(current=>{ - if(current.name1=='dc_ganfuren'||current.name2=='dc_ganfuren'){ - characters.remove('dc_ganfuren'); + filter: function (event, player) { + if (player.hp > 0) return false; + var characters = ["dc_ganfuren", "dc_mifuren"]; + game.countPlayer((current) => { + if (current.name1 == "dc_ganfuren" || current.name2 == "dc_ganfuren") { + characters.remove("dc_ganfuren"); } - if(current.name1=='dc_mifuren'||current.name2=='dc_mifuren'){ - characters.remove('dc_mifuren'); + if (current.name1 == "dc_mifuren" || current.name2 == "dc_mifuren") { + characters.remove("dc_mifuren"); } }); return characters.length; }, - check:()=>true, - skillAnimation:true, - animationColor:'fire', - limited:true, - derivation:['dcyongjue','dcshushen','dcshenzhi','dcguixiu','dccunsi'], - content:function(){ - 'step 0' - player.awakenSkill('dcxunbie'); - if(player.name1=='ganfurenmifuren'||player.name2=='ganfurenmifuren'){ - var characters=['dc_ganfuren','dc_mifuren']; - game.countPlayer(current=>{ - if(current.name1=='dc_ganfuren'||current.name2=='dc_ganfuren'){ - characters.remove('dc_ganfuren'); + check: () => true, + skillAnimation: true, + animationColor: "fire", + limited: true, + derivation: ["dcyongjue", "dcshushen", "dcshenzhi", "dcguixiu", "dccunsi"], + content: function () { + "step 0"; + player.awakenSkill("dcxunbie"); + if (player.name1 == "ganfurenmifuren" || player.name2 == "ganfurenmifuren") { + var characters = ["dc_ganfuren", "dc_mifuren"]; + game.countPlayer((current) => { + if (current.name1 == "dc_ganfuren" || current.name2 == "dc_ganfuren") { + characters.remove("dc_ganfuren"); } - if(current.name1=='dc_mifuren'||current.name2=='dc_mifuren'){ - characters.remove('dc_mifuren'); + if (current.name1 == "dc_mifuren" || current.name2 == "dc_mifuren") { + characters.remove("dc_mifuren"); } }); - if(characters.length==1) event._result={control:characters[0]}; - else{ - player.chooseControl(characters).set('dialog',[ - '选择要替换成的武将', - [characters,'character'] - ]).set('ai',()=>[0,1].randomGet()); + if (characters.length == 1) event._result = { control: characters[0] }; + else { + player + .chooseControl(characters) + .set("dialog", ["选择要替换成的武将", [characters, "character"]]) + .set("ai", () => [0, 1].randomGet()); } - } - else event.goto(2); - 'step 1' - var character=result.control; - if(!_status.characterlist){ + } else event.goto(2); + "step 1"; + var character = result.control; + if (!_status.characterlist) { lib.skill.pingjian.initList(); } - player.reinitCharacter('ganfurenmifuren',character); - 'step 2' - player.recover(1-player.hp); - player.addTempSkill('dcxunbie_muteki',{player:'phaseAfter'}); + player.reinitCharacter("ganfurenmifuren", character); + "step 2"; + player.recover(1 - player.hp); + player.addTempSkill("dcxunbie_muteki", { player: "phaseAfter" }); }, - subSkill:{ - muteki:{ - trigger:{ - player:'damageBegin4', + subSkill: { + muteki: { + trigger: { + player: "damageBegin4", }, - charlotte:true, - forced:true, - content:function(){ + charlotte: true, + forced: true, + content: function () { trigger.cancel(); }, - mark:true, - intro:{content:'防止受到的所有伤害直到我的回合结束'}, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')) return 'zeroplayertarget'; - } + mark: true, + intro: { content: "防止受到的所有伤害直到我的回合结束" }, + ai: { + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) return "zeroplayertarget"; + }, }, - } - } - } + }, + }, + }, }, //散装版糜夫人 - dcguixiu:{ - audio:'guixiu', - trigger:{ - player:'phaseBegin', + dcguixiu: { + audio: "guixiu", + trigger: { + player: "phaseBegin", }, - forced:true, - onremove:true, - filter:function(event,player){ - return !player.hasMark('dcguixiu'); + forced: true, + onremove: true, + filter: function (event, player) { + return !player.hasMark("dcguixiu"); }, - group:'dcguixiu_rec', - content:function(){ - player.addMark('dcguixiu',1,false); + group: "dcguixiu_rec", + content: function () { + player.addMark("dcguixiu", 1, false); player.draw(2); }, - subSkill:{ - rec:{ - audio:'guixiu', - trigger:{ - player:'useSkillAfter', + subSkill: { + rec: { + audio: "guixiu", + trigger: { + player: "useSkillAfter", }, - forced:true, - filter:function(event,player){ - return event.skill=='dccunsi'&&player.isDamaged(); + forced: true, + filter: function (event, player) { + return event.skill == "dccunsi" && player.isDamaged(); }, - content:function(){ + content: function () { player.recover(); - } - } - } + }, + }, + }, }, - dccunsi:{ - audio:'cunsi', - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - filterTarget:true, - derivation:'dcyongjue', - content:function(){ - 'step 0' - player.awakenSkill('dccunsi'); - target.addSkillLog('dcyongjue'); - if(target!=player) player.draw(2); + dccunsi: { + audio: "cunsi", + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + filterTarget: true, + derivation: "dcyongjue", + content: function () { + "step 0"; + player.awakenSkill("dccunsi"); + target.addSkillLog("dcyongjue"); + if (target != player) player.draw(2); + }, + ai: { + order: 10, + result: { + target: 1, + }, }, - ai:{ - order:10, - result:{ - target:1, - } - } }, - dcyongjue:{ - audio:'yongjue', - trigger:{ - player:'useCard', + dcyongjue: { + audio: "yongjue", + trigger: { + player: "useCard", }, - filter:function(event,player){ - var evtx=event.getParent('phaseUse'); - if(!evtx||evtx.player!=player) return false; - return player.getHistory('useCard',evt=>{ - return evt.card.name=='sha'&&event.getParent('phaseUse')==evtx; - }).indexOf(event)==0; + filter: function (event, player) { + var evtx = event.getParent("phaseUse"); + if (!evtx || evtx.player != player) return false; + return ( + player + .getHistory("useCard", (evt) => { + return evt.card.name == "sha" && event.getParent("phaseUse") == evtx; + }) + .indexOf(event) == 0 + ); }, - direct:true, - content:function(){ - 'step 0' - var choices=['选项一']; - var choiceList=['令'+get.translation(trigger.card)+'不计入次数','获得此牌']; - if(trigger.cards.length){ - choices.push('选项二'); - choiceList[1]='获得'+get.translation(trigger.cards); - } - else choiceList[1]=''+choiceList[1]+''; - choices.push('cancel2'); - player.chooseControl(choices).set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(choices.length==3&&trigger.addCount===false) return 1; - if(player.getCardUsable({name:'sha'})"; + choices.push("cancel2"); + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (choices.length == 3 && trigger.addCount === false) return 1; + if (player.getCardUsable({ name: "sha" }) < player.countCards("hs", "sha")) + return 0; + if (choices.length == 3) return 1; + return 0; + })() + ); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - player.logSkill('dcyongjue'); - game.log(player,'选择了','#y'+result.control); - if(result.control=='选项一'){ - if(trigger.addCount!==false){ - trigger.addCount=false; + player.logSkill("dcyongjue"); + game.log(player, "选择了", "#y" + result.control); + if (result.control == "选项一") { + if (trigger.addCount !== false) { + trigger.addCount = false; trigger.player.getStat().card.sha--; } + } else { + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2"); } - else{ - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2'); - } - } + }, }, //散装版甘夫人 - dcshushen:{ - audio:'shushen', - trigger:{ - player:'recoverEnd', + dcshushen: { + audio: "shushen", + trigger: { + player: "recoverEnd", }, - direct:true, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - player.chooseTarget(get.prompt('dcshushen'),'选择一名其他角色,然后令其回复1点体力或令你与其各摸一张牌',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return get.recoverEffect(target,player,player)/2+get.attitude(player,target); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dcshushen',target); + direct: true, + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + player + .chooseTarget( + get.prompt("dcshushen"), + "选择一名其他角色,然后令其回复1点体力或令你与其各摸一张牌", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + get.recoverEffect(target, player, player) / 2 + get.attitude(player, target) + ); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dcshushen", target); event.num--; - var choices=['选项二']; - var choiceList=[ - '令'+get.translation(target)+'回复1点体力', - '你与'+get.translation(target)+'各摸一张牌' + var choices = ["选项二"]; + var choiceList = [ + "令" + get.translation(target) + "回复1点体力", + "你与" + get.translation(target) + "各摸一张牌", ]; - if(target.isDamaged()) choices.unshift('选项一'); - else choiceList[0]=''+choiceList[0]+''; - player.chooseControl(choices).set('choiceList',choiceList).set('prompt','淑慎:请选择一项').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(target.hp<=2||get.recoverEffect(target,player,player)>20) return 0; - return '选项二'; - }()); - } - else event.finish(); - 'step 3' - if(result.control=='选项一'){ + if (target.isDamaged()) choices.unshift("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("prompt", "淑慎:请选择一项") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (target.hp <= 2 || get.recoverEffect(target, player, player) > 20) + return 0; + return "选项二"; + })() + ); + } else event.finish(); + "step 3"; + if (result.control == "选项一") { target.recover(); - } - else{ - var drawers=[player,target].sortBySeat(_status.currentPhase); + } else { + var drawers = [player, target].sortBySeat(_status.currentPhase); game.asyncDraw(drawers); } - 'step 4' - if(event.num>0) event.goto(1); - } + "step 4"; + if (event.num > 0) event.goto(1); + }, }, - dcshenzhi:{ - audio:'shenzhi', - trigger:{ - player:'phaseZhunbeiBegin', + dcshenzhi: { + audio: "shenzhi", + trigger: { + player: "phaseZhunbeiBegin", }, - filter:function(event,player){ - return player.countCards('h')>player.hp; + filter: function (event, player) { + return player.countCards("h") > player.hp; }, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('dcshenzhi'),'弃置一张手牌,然后回复1点体力').set('logSkill','dcshenzhi').set('ai',card=>{ - var player=_status.event.player; - if(!player.isDamaged()) return 0; - return Math.min(3,10-2*player.hp)-get.value(card); - }); - 'step 1' - if(result.bool){ + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard(get.prompt("dcshenzhi"), "弃置一张手牌,然后回复1点体力") + .set("logSkill", "dcshenzhi") + .set("ai", (card) => { + var player = _status.event.player; + if (!player.isDamaged()) return 0; + return Math.min(3, 10 - 2 * player.hp) - get.value(card); + }); + "step 1"; + if (result.bool) { player.recover(); } - } + }, }, //阮籍 - dczhaowen:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.countCards('h'); + dczhaowen: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h"); }, - check:function(event,player){ - return player.hasCard(card=>{ - return get.color(card)=='black'||get.color(card)=='red'&&player.hasValueTarget(card); + check: function (event, player) { + return player.hasCard((card) => { + return ( + get.color(card) == "black" || + (get.color(card) == "red" && player.hasValueTarget(card)) + ); }); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - player.addTempSkill('dczhaowen_effect'); - game.broadcastAll(function(cards){ - cards.forEach(card=>card.addGaintag('dczhaowen_tag')); - },player.getCards('h')); + "step 1"; + player.addTempSkill("dczhaowen_effect"); + game.broadcastAll(function (cards) { + cards.forEach((card) => card.addGaintag("dczhaowen_tag")); + }, player.getCards("h")); }, - ai:{ - threaten:3 + ai: { + threaten: 3, }, - subSkill:{ - effect:{ - audio:'dczhaowen', - enable:'chooseToUse', - charlotte:true, - onremove:function(player){ - player.removeGaintag('dczhaowen_tag'); + subSkill: { + effect: { + audio: "dczhaowen", + enable: "chooseToUse", + charlotte: true, + onremove: function (player) { + player.removeGaintag("dczhaowen_tag"); }, - hiddenCard:function(player,name){ - return get.type(name)=='trick'&&!player.getStorage('dczhaowen_viewed').includes(name)&&player.countCards('h',card=>{ - return get.color(card)=='black'&&card.hasGaintag('dczhaowen_tag'); - })>0; + hiddenCard: function (player, name) { + return ( + get.type(name) == "trick" && + !player.getStorage("dczhaowen_viewed").includes(name) && + player.countCards("h", (card) => { + return get.color(card) == "black" && card.hasGaintag("dczhaowen_tag"); + }) > 0 + ); }, - filter:function(event,player){ - if(!player.hasCard(card=>{ - return get.color(card)=='black'&&card.hasGaintag('dczhaowen_tag'); - })) return false; - var storage=player.getStorage('dczhaowen_viewed'); - for(var i of lib.inpile){ - if(!storage.includes(i)&&get.type(i)=='trick'&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)) return true; + filter: function (event, player) { + if ( + !player.hasCard((card) => { + return get.color(card) == "black" && card.hasGaintag("dczhaowen_tag"); + }) + ) + return false; + var storage = player.getStorage("dczhaowen_viewed"); + for (var i of lib.inpile) { + if ( + !storage.includes(i) && + get.type(i) == "trick" && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var cards=player.getCards('h',card=>{ - return get.color(card)=='black'&&card.hasGaintag('dczhaowen_tag'); + chooseButton: { + dialog: function (event, player) { + var cards = player.getCards("h", (card) => { + return get.color(card) == "black" && card.hasGaintag("dczhaowen_tag"); }); - var storage=player.getStorage('dczhaowen_viewed'); - var list=[]; - for(var i of lib.inpile){ - if(!storage.includes(i)&&get.type(i)=='trick'&&event.filterCard(get.autoViewAs({name:i},'unsure'),player,event)){ - list.push(['锦囊','',i]); + var storage = player.getStorage("dczhaowen_viewed"); + var list = []; + for (var i of lib.inpile) { + if ( + !storage.includes(i) && + get.type(i) == "trick" && + event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event) + ) { + list.push(["锦囊", "", i]); } } - return ui.create.dialog('昭文',[list,'vcard'],'hidden'); + return ui.create.dialog("昭文", [list, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - return player.getUseValue({name:button.link[2]})+1; + check: function (button) { + var player = _status.event.player; + return player.getUseValue({ name: button.link[2] }) + 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'dczhaowen', - popname:true, - filterCard:function(card,player){ - return get.color(card)=='black'&&card.hasGaintag('dczhaowen_tag'); + audio: "dczhaowen", + popname: true, + filterCard: function (card, player) { + return get.color(card) == "black" && card.hasGaintag("dczhaowen_tag"); }, - selectCard:1, - position:'h', - viewAs:{ - name:links[0][2], + selectCard: 1, + position: "h", + viewAs: { + name: links[0][2], }, - onuse:function(links,player){ - player.addTempSkill('dczhaowen_viewed'); - player.markAuto('dczhaowen_viewed',[links.card.name]); + onuse: function (links, player) { + player.addTempSkill("dczhaowen_viewed"); + player.markAuto("dczhaowen_viewed", [links.card.name]); }, - } + }; }, - prompt:function(links,player){ - return '将一张展示过的黑色手牌当做'+get.translation(links[0][2])+'使用'; + prompt: function (links, player) { + return "将一张展示过的黑色手牌当做" + get.translation(links[0][2]) + "使用"; }, }, - group:'dczhaowen_draw', - mod:{ - aiOrder:function(player,card,num){ - var cards=[]; - if(card.cards) cards.addArray(cards); - if(get.itemtype(card)=='card') cards.push(card); - for(var cardx of cards){ - if(get.color(cardx)!='red') continue; - if(cardx.hasGaintag('dczhaowen_tag')) return num+0.2; + group: "dczhaowen_draw", + mod: { + aiOrder: function (player, card, num) { + var cards = []; + if (card.cards) cards.addArray(cards); + if (get.itemtype(card) == "card") cards.push(card); + for (var cardx of cards) { + if (get.color(cardx) != "red") continue; + if (cardx.hasGaintag("dczhaowen_tag")) return num + 0.2; } }, }, - ai:{ - order:12, - result:{ - player:1, + ai: { + order: 12, + result: { + player: 1, }, }, }, - draw:{ - audio:'dczhaowen', - forced:true, - charlotte:true, - trigger:{player:'useCard'}, - filter:function(event,player){ - var cards=event.cards.filter(card=>get.color(card,player)=='red'); - return player.hasHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dczhaowen_tag')){ - if(cards.some(card=>card.cardid==i)) return true; + draw: { + audio: "dczhaowen", + forced: true, + charlotte: true, + trigger: { player: "useCard" }, + filter: function (event, player) { + var cards = event.cards.filter((card) => get.color(card, player) == "red"); + return player.hasHistory("lose", (evt) => { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dczhaowen_tag")) { + if (cards.some((card) => card.cardid == i)) return true; } } }); }, - content:function(){ - var num=0; - var cards=trigger.cards.filter(card=>get.color(card,player)=='red'); - player.getHistory('lose',evt=>{ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dczhaowen_tag')){ - if(cards.some(card=>card.cardid==i)) num++; + content: function () { + var num = 0; + var cards = trigger.cards.filter((card) => get.color(card, player) == "red"); + player.getHistory("lose", (evt) => { + if (trigger != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dczhaowen_tag")) { + if (cards.some((card) => card.cardid == i)) num++; } } }); - while(num--) player.draw(); + while (num--) player.draw(); + }, + ai: { + effect: { + player: (card, player, target) => { + if ( + get.itemtype(card) === "card" && + cardx.hasGaintag("dczhaowen_tag") && + get.color(card, player) === "red" + ) + return [1, 1]; + }, + }, }, - ai:{ - effect:{ - player:(card,player,target)=>{ - if(get.itemtype(card)==='card'&&cardx.hasGaintag('dczhaowen_tag')&&get.color(card,player)==='red') return [1,1]; - } - } - } }, - viewed:{ - onremove:true, - charlotte:true, + viewed: { + onremove: true, + charlotte: true, }, - effect_backup:{ - audio:'dczhaowen', + effect_backup: { + audio: "dczhaowen", }, - } + }, }, - dcjiudun:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - if(event.player==player||get.color(event.card)!='black') return false; - if(player.hasSkill('jiu')) return player.countCards('h',card=>{ - return _status.connectMode||lib.filter.cardDiscardable(card,player,'dcjiudun'); - }); + dcjiudun: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + if (event.player == player || get.color(event.card) != "black") return false; + if (player.hasSkill("jiu")) + return player.countCards("h", (card) => { + return ( + _status.connectMode || lib.filter.cardDiscardable(card, player, "dcjiudun") + ); + }); return true; }, - direct:true, - content:function(){ - 'step 0' - if(player.hasSkill('jiu')){ - player.chooseToDiscard(get.prompt('dcjiudun'),'
              弃置一张手牌,令'+get.translation(trigger.card)+'对你无效
              ').set('logSkill','dcjiudun').set('ai',card=>{ - if(_status.event.goon) return 4.5+Math.max(0,3-player.hp)-get.value(card); - return 0; - }).set('goon',function(){ - if(get.effect(player,trigger.card,trigger.player,player)<-4*Math.max(0,5-Math.sqrt(player.countCards('h')))) return true; - return false; - }()); + direct: true, + content: function () { + "step 0"; + if (player.hasSkill("jiu")) { + player + .chooseToDiscard( + get.prompt("dcjiudun"), + '
              弃置一张手牌,令' + + get.translation(trigger.card) + + "对你无效
              " + ) + .set("logSkill", "dcjiudun") + .set("ai", (card) => { + if (_status.event.goon) + return 4.5 + Math.max(0, 3 - player.hp) - get.value(card); + return 0; + }) + .set( + "goon", + (function () { + if ( + get.effect(player, trigger.card, trigger.player, player) < + -4 * Math.max(0, 5 - Math.sqrt(player.countCards("h"))) + ) + return true; + return false; + })() + ); event.goto(2); + } else { + player + .chooseBool(get.prompt("dcjiudun"), "摸一张牌,然后视为使用一张【酒】") + .set("ai", () => 1); } - else{ - player.chooseBool(get.prompt('dcjiudun'),'摸一张牌,然后视为使用一张【酒】').set('ai',()=>1); - } - 'step 1' - if(result.bool){ - player.logSkill('dcjiudun'); + "step 1"; + if (result.bool) { + player.logSkill("dcjiudun"); player.draw(); - player.chooseUseTarget('jiu',true); + player.chooseUseTarget("jiu", true); } event.finish(); - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { trigger.excluded.add(player); - game.log(trigger.card,'对',player,'无效'); + game.log(trigger.card, "对", player, "无效"); } }, - ai:{ - jiuSustain:true, - skillTagFilter:function(player,tag,name){ - if(name!='phase') return false; + ai: { + jiuSustain: true, + skillTagFilter: function (player, tag, name) { + if (name != "phase") return false; }, - effect:{ - target:(card,player,target)=>{ - if(player===target||typeof card!=='object'||get.color(card)!=='black') return; - if(target.hasSkill('jiu')){ - if(card.name!=='huogong'&&get.tag(card,'damage')&&get.attitude(player,target)<=0&&target.hasCard(i=>{ - return _status.connectMode||lib.filter.cardDiscardable(i,player,'dcjiudun'); - },'h')) return [0,-1]; - } - else return [1,1.2]; - } - } - } + effect: { + target: (card, player, target) => { + if (player === target || typeof card !== "object" || get.color(card) !== "black") + return; + if (target.hasSkill("jiu")) { + if ( + card.name !== "huogong" && + get.tag(card, "damage") && + get.attitude(player, target) <= 0 && + target.hasCard((i) => { + return ( + _status.connectMode || + lib.filter.cardDiscardable(i, player, "dcjiudun") + ); + }, "h") + ) + return [0, -1]; + } else return [1, 1.2]; + }, + }, + }, }, //武诸葛 - dcjincui:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ + dcjincui: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { return true; }, - forced:true, - group:'dcjincui_advent', - content:function(){ - 'step 0' - var num=0; - for(var i=0;i=player.maxHp) break; + if (num >= player.maxHp) break; } } - if(num<1) num=1; - if(num>player.hp) player.recover(num-player.hp); - else if(num player.hp) player.recover(num - player.hp); + else if (num < player.hp) player.loseHp(player.hp - num); + "step 1"; + var num = player.hp; + var cards = get.cards(num); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','尽瘁:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var target=(_status.event.getTrigger().name=='phaseZhunbei')?player:player.next; - var att=get.sgn(get.attitude(player,target)); - var top=[]; - var judges=target.getCards('j'); - var stopped=false; - if(player!=target||!target.hasWuxie()){ - for(var i=0;i0)) break; + while (cards.length) { + if (get.value(cards[0], player) <= 5 == att > 0) break; top.unshift(cards.shift()); } } - bottom=cards; - return [top,bottom]; - } - 'step 2' - var top=result.moved[0]; - var bottom=result.moved[1]; + bottom = cards; + return [top, bottom]; + }; + "step 2"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i=target.hp){ - bool=true; + if (num >= target.hp) { + bool = true; break; } } } - if(bool) return 0.2; - } - }, - threaten:0.6, - }, - subSkill:{ - advent:{ - audio:'dcjincui', - trigger:{global:'phaseBefore',player:'enterGame'}, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.countCards('h')<7; + if (bool) return 0.2; }, - content:function(){ + }, + threaten: 0.6, + }, + subSkill: { + advent: { + audio: "dcjincui", + trigger: { global: "phaseBefore", player: "enterGame" }, + forced: true, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && player.countCards("h") < 7 + ); + }, + content: function () { player.drawTo(7); - } - } + }, + }, }, }, - dcqingshi:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - if(!player.isPhaseUsing()||player.hasSkill('dcqingshi_blocker')) return false; - if(player.getStorage('dcqingshi_clear').includes(event.card.name)) return false; - if(player.hasCard(card=>{ - return get.name(card)==event.card.name; - })) return true; + dcqingshi: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + if (!player.isPhaseUsing() || player.hasSkill("dcqingshi_blocker")) return false; + if (player.getStorage("dcqingshi_clear").includes(event.card.name)) return false; + if ( + player.hasCard((card) => { + return get.name(card) == event.card.name; + }) + ) + return true; return false; }, - direct:true, - content:function(){ - 'step 0' - var choices=[]; - var choiceList=[ - '令'+get.translation(trigger.card)+'对其中一个目标角色造成的伤害+1', - '令任意名其他角色各摸一张牌', - '摸三张牌,然后〖情势〗于本回合失效' + direct: true, + content: function () { + "step 0"; + var choices = []; + var choiceList = [ + "令" + get.translation(trigger.card) + "对其中一个目标角色造成的伤害+1", + "令任意名其他角色各摸一张牌", + "摸三张牌,然后〖情势〗于本回合失效", ]; - if(trigger.targets&&trigger.targets.length) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+'(无目标角色)'; - if(game.countPlayer(i=>i!=player)) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(player.hp>0) choices.push('选项三'); - else choiceList[2]=''+choiceList[1]+'(体力值为0)'; - player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('prompt',get.prompt('dcqingshi')).set('ai',()=>{ - return _status.event.choice; - }).set('choice',(()=>{ - var choicesx=choices.slice(); - var cards=player.getCards('hs'); - var bool1=get.tag(trigger.card,'damage')&&choicesx.includes('选项一')&&trigger.targets.some(current=>{ - return get.attitude(player,current)<0; - }),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;i"; + if (game.countPlayer((i) => i != player)) choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (player.hp > 0) choices.push("选项三"); + else choiceList[2] = '' + choiceList[1] + "(体力值为0)"; + player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("prompt", get.prompt("dcqingshi")) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (() => { + var choicesx = choices.slice(); + var cards = player.getCards("hs"); + var bool1 = + get.tag(trigger.card, "damage") && + choicesx.includes("选项一") && + trigger.targets.some((current) => { + return get.attitude(player, current) < 0; + }), + 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; i < cards.length; i++) { + var name = get.name(cards[i]); + if (player.getStorage("dcqingshi_clear").includes(name)) continue; + for (var j = i + 1; j < cards.length; j++) { + if ( + name === get.name(cards[j]) && + get.position(cards[i]) + get.position(cards[j]) !== "ss" && + player.hasValueTarget(cards[i]) + ) { + choicesx.remove("选项三"); + break; + } + } } } + if (bool2 > 2) return "选项二"; + if (choicesx.includes("选项三")) return "选项三"; + if (bool2 === 2) return "选项二"; + if (bool1) return "选项一"; + if (bool2) return "选项二"; + return "cancel2"; + })() + ); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dcqingshi"); + game.log(player, "选择了", "#y" + result.control); + var index = ["选项一", "选项二", "选项三"].indexOf(result.control) + 1; + player.addTempSkill("dcqingshi_clear"); + player.markAuto("dcqingshi_clear", [trigger.card.name]); + var next = game.createEvent("dcqingshi_after"); + next.player = player; + next.card = trigger.card; + next.setContent(lib.skill.dcqingshi["content" + index]); + } + }, + content1: function () { + "step 0"; + player + .chooseTarget( + "令" + get.translation(card) + "对其中一个目标造成的伤害+1", + true, + (card, player, target) => { + return _status.event.targets.includes(target); } - } - if(bool2>2) return '选项二'; - if(choicesx.includes('选项三')) return '选项三'; - if(bool2===2) return '选项二'; - if(bool1) return '选项一'; - if(bool2) return '选项二'; - return 'cancel2'; - })()); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dcqingshi'); - game.log(player,'选择了','#y'+result.control); - var index=['选项一','选项二','选项三'].indexOf(result.control)+1; - player.addTempSkill('dcqingshi_clear'); - player.markAuto('dcqingshi_clear',[trigger.card.name]); - var next=game.createEvent('dcqingshi_after'); - next.player=player; - next.card=trigger.card; - next.setContent(lib.skill.dcqingshi['content'+index]); - } - }, - content1:function(){ - 'step 0' - player.chooseTarget('令'+get.translation(card)+'对其中一个目标造成的伤害+1',true,(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('ai',target=>{ - return 2-get.attitude(_status.event.player,target); - }).set('targets',event.getParent().getTrigger().targets); - 'step 1' - if(result.bool){ - var target=result.targets[0]; + ) + .set("ai", (target) => { + return 2 - get.attitude(_status.event.player, target); + }) + .set("targets", event.getParent().getTrigger().targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - player.addTempSkill('dcqingshi_ex'); - if(!player.storage.dcqingshi_ex) player.storage.dcqingshi_ex=[]; - player.storage.dcqingshi_ex.push([target,card]); + player.addTempSkill("dcqingshi_ex"); + if (!player.storage.dcqingshi_ex) player.storage.dcqingshi_ex = []; + player.storage.dcqingshi_ex.push([target, card]); } }, - content2:function(){ - 'step 0' - player.chooseTarget('令任意名其他角色各摸一张牌',[1,Infinity],true,lib.filter.notMe).set('ai',target=>{ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; + content2: function () { + "step 0"; + player + .chooseTarget("令任意名其他角色各摸一张牌", [1, Infinity], true, lib.filter.notMe) + .set("ai", (target) => { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.sortBySeat(); player.line(targets); game.asyncDraw(targets); game.delayex(); } }, - content3:function(){ - 'step 0' + content3: function () { + "step 0"; player.draw(3); - player.addTempSkill('dcqingshi_blocker'); + player.addTempSkill("dcqingshi_blocker"); }, - subSkill:{ - ex:{ - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return player.storage.dcqingshi_ex&&player.storage.dcqingshi_ex.some(info=>{ - return info[0]==event.player&&info[1]==event.card; - }); + subSkill: { + ex: { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + player.storage.dcqingshi_ex && + player.storage.dcqingshi_ex.some((info) => { + return info[0] == event.player && info[1] == event.card; + }) + ); }, - forced:true, - charlotte:true, - popup:false, - onremove:true, - content:function(){ + forced: true, + charlotte: true, + popup: false, + onremove: true, + content: function () { trigger.num++; - for(var i=0;i0&&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(0,(i,player)=>{ - return !player.canIgnoreHandcard(i)&&get.useful(i)>6; - })) return num*1.5; - return num*10; - } + for (var i = 0; i < player.storage.dcqingshi_ex.length; i++) { + if (player.storage.dcqingshi_ex[i][1] == trigger.card) + player.storage.dcqingshi_ex.splice(i--, 1); } }, - trigger:{player:['useCardAfter','respondAfter']}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dczhizhe')){ - if(event.cards.some(card=>{ - return get.position(card,true)=='o'&&card.cardid==i; - })) return true; + }, + clear: { + onremove: true, + charlotte: true, + }, + blocker: { charlotte: true }, + }, + ai: { + threaten: 6, + }, + }, + dczhizhe: { + audio: 2, + enable: "phaseUse", + limited: true, + filterCard: true, + position: "h", + discard: false, + lose: false, + delay: false, + skillAnimation: true, + animationColor: "metal", + check: function (card) { + if (get.type(card) != "basic" && get.type(card) != "trick") return 0; + return get.value(card) - 7.5; + }, + content: function () { + "step 0"; + var card = cards[0]; + player.awakenSkill("dczhizhe"); + var cardx = game.createCard2(card.name, card.suit, card.number, card.nature); + player.gain(cardx).gaintag.add("dczhizhe"); + player.addSkill("dczhizhe_effect"); + }, + ai: { + order: 15, + result: { + player: 1, + }, + }, + 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(0, (i, player) => { + return !player.canIgnoreHandcard(i) && get.useful(i) > 6; + }) + ) + return num * 1.5; + return num * 10; + } + }, + }, + trigger: { player: ["useCardAfter", "respondAfter"] }, + charlotte: true, + forced: true, + filter: function (event, player) { + return player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dczhizhe")) { + if ( + event.cards.some((card) => { + return get.position(card, true) == "o" && card.cardid == i; + }) + ) + return true; } } return false; }); }, - content:function(){ - 'step 0' - var cards=[]; - player.getHistory('lose',function(evt){ - if(evt.getParent()!=trigger) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dczhizhe')){ - var cardsx=trigger.cards.filter(card=>{ - return get.position(card,true)=='o'&&card.cardid==i; + content: function () { + "step 0"; + var cards = []; + player.getHistory("lose", function (evt) { + if (evt.getParent() != trigger) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dczhizhe")) { + var cardsx = trigger.cards.filter((card) => { + return get.position(card, true) == "o" && card.cardid == i; }); - if(cardsx.length) cards.addArray(cardsx); + if (cardsx.length) cards.addArray(cardsx); } } }); - if(cards.length){ - player.gain(cards,'gain2').gaintag.addArray(['dczhizhe','dczhizhe_clear']); - player.addTempSkill('dczhizhe_clear'); + if (cards.length) { + player.gain(cards, "gain2").gaintag.addArray(["dczhizhe", "dczhizhe_clear"]); + player.addTempSkill("dczhizhe_clear"); } }, }, - clear:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('dczhizhe_clear'); + clear: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("dczhizhe_clear"); }, - mod:{ - cardEnabled2:function(card,player){ - var cards=[]; - if(card.cards) cards.addArray(cards); - if(get.itemtype(card)=='card') cards.push(card); - for(var cardx of cards){ - if(cardx.hasGaintag('dczhizhe_clear')) return false; + mod: { + cardEnabled2: function (card, player) { + var cards = []; + if (card.cards) cards.addArray(cards); + if (get.itemtype(card) == "card") cards.push(card); + for (var cardx of cards) { + if (cardx.hasGaintag("dczhizhe_clear")) return false; } }, - cardRespondable:function(card,player){ - var cards=[]; - if(card.cards) cards.addArray(cards); - if(get.itemtype(card)=='card') cards.push(card); - for(var cardx of cards){ - if(cardx.hasGaintag('dczhizhe_clear')) return false; + cardRespondable: function (card, player) { + var cards = []; + if (card.cards) cards.addArray(cards); + if (get.itemtype(card) == "card") cards.push(card); + for (var cardx of cards) { + if (cardx.hasGaintag("dczhizhe_clear")) return false; } }, - cardSavable:function(card,player){ - var cards=[]; - if(card.cards) cards.addArray(cards); - if(get.itemtype(card)=='card') cards.push(card); - for(var cardx of cards){ - if(cardx.hasGaintag('dczhizhe_clear')) return false; + cardSavable: function (card, player) { + var cards = []; + if (card.cards) cards.addArray(cards); + if (get.itemtype(card) == "card") cards.push(card); + for (var cardx of cards) { + if (cardx.hasGaintag("dczhizhe_clear")) return false; } }, - } - } - } + }, + }, + }, }, //段巧笑 - dccaizhuang:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'dccaizhuang'); - },'he'); + dccaizhuang: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "dccaizhuang"); + }, "he"); }, - complexCard:true, - selectCard:[1,Infinity], - position:'he', - filterCard:true, - check:function(card){ - let cache=lib.skill.dccaizhuang.tempCache(); - if(!cache||cache.no) return 0; - let player=_status.event.player,suit=get.suit(card); - if(ui.selected.cards.filter(i=>{ - return get.suit(i)===suit; - }).length<(cache[suit]||0)){ - if(get.position(card)==='h') return 15-get.value(card); - return 9-get.value(card); + complexCard: true, + selectCard: [1, Infinity], + position: "he", + filterCard: true, + check: function (card) { + let cache = lib.skill.dccaizhuang.tempCache(); + if (!cache || cache.no) return 0; + let player = _status.event.player, + suit = get.suit(card); + if ( + ui.selected.cards.filter((i) => { + return get.suit(i) === suit; + }).length < (cache[suit] || 0) + ) { + if (get.position(card) === "h") return 15 - get.value(card); + return 9 - get.value(card); } return 0; }, - tempCache(){ - let cache=_status.event.getTempCache('dccaizhuang','dsuits'); - if(cache) return cache; - cache={no:true}; - _status.event.putTempCache('dccaizhuang','dsuits',cache); - let player=_status.event.player,suits={}; - lib.suit.forEach(i=>{ - suits[i]=0; + tempCache() { + let cache = _status.event.getTempCache("dccaizhuang", "dsuits"); + if (cache) return cache; + cache = { no: true }; + _status.event.putTempCache("dccaizhuang", "dsuits", cache); + let player = _status.event.player, + suits = {}; + lib.suit.forEach((i) => { + suits[i] = 0; }); - player.getCards('h',i=>{ - let suit=get.suit(i); - if(lib.suit.includes(suit)) suits[suit]++; + player.getCards("h", (i) => { + let suit = get.suit(i); + if (lib.suit.includes(suit)) suits[suit]++; }); - let sortedSuits=Object.fromEntries(Object.entries(suits).sort((a,b)=>b[1]-a[1])); - let dis=0,idx=0,dsuits=0,leave=0; - for(let i in sortedSuits){ + let sortedSuits = Object.fromEntries(Object.entries(suits).sort((a, b) => b[1] - a[1])); + let dis = 0, + idx = 0, + dsuits = 0, + leave = 0; + for (let i in sortedSuits) { idx++; - if(!sortedSuits[i]) continue; - let num=1; - if(idx>2||sortedSuits[i]<3) num=sortedSuits[i]; - cache[i]=num; - dis+=num; - suits[i]-=num; + if (!sortedSuits[i]) continue; + let num = 1; + if (idx > 2 || sortedSuits[i] < 3) num = sortedSuits[i]; + cache[i] = num; + dis += num; + suits[i] -= num; dsuits++; } - for(let i in suits){ - if(suits[i]) leave++; + for (let i in suits) { + if (suits[i]) leave++; } - player.getCards('e',i=>{ - let suit=get.suit(i); - if(!cache[suit]){ + player.getCards("e", (i) => { + let suit = get.suit(i); + if (!cache[suit]) { dsuits++; - cache[suit]=1; + cache[suit] = 1; dis++; } }); - let draw=0,e=[0,1,4/3,2,4]; - if(dsuits<=leave) return false; - do{ - draw+=e[dsuits--]; - }while(dsuits>leave); - if(draw>dis){ + let draw = 0, + e = [0, 1, 4 / 3, 2, 4]; + if (dsuits <= leave) return false; + do { + draw += e[dsuits--]; + } while (dsuits > leave); + if (draw > dis) { delete cache.no; - _status.event.putTempCache('dccaizhuang','dsuits',cache); + _status.event.putTempCache("dccaizhuang", "dsuits", cache); return cache; } return false; }, - content:function(){ - 'step 0' - var suits=[]; - cards.forEach(i=>{ - if(suits.length>=4) return; - let suit=get.suit(i,player); - if(lib.suit.includes(suit)) suits.add(suit); + content: function () { + "step 0"; + var suits = []; + cards.forEach((i) => { + if (suits.length >= 4) return; + let suit = get.suit(i, player); + if (lib.suit.includes(suit)) suits.add(suit); }); - event.num=suits.length; - 'step 1' - var suits=[]; - player.countCards('h',card=>{ - if(suits.length>=4) return; - var suit=get.suit(card); - if(lib.suit.includes(suit)) suits.add(suit); + event.num = suits.length; + "step 1"; + var suits = []; + player.countCards("h", (card) => { + if (suits.length >= 4) return; + var suit = get.suit(card); + if (lib.suit.includes(suit)) suits.add(suit); }); - if(suits.length>=event.num) event.finish(); - 'step 2' + if (suits.length >= event.num) event.finish(); + "step 2"; player.draw(); event.goto(1); }, - ai:{ - order:2, - result:{player:1}, + ai: { + order: 2, + result: { player: 1 }, }, }, - dchuayi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - content:function(){ - 'step 0' - player.judge(()=>1).judge2=(result)=>result.bool; - 'step 1' - var color=result.color; - if(color=='red'||color=='black') player.addTempSkill('dchuayi_'+color,{player:'phaseBegin'}); + dchuayi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + content: function () { + "step 0"; + player.judge(() => 1).judge2 = (result) => result.bool; + "step 1"; + var color = result.color; + if (color == "red" || color == "black") + player.addTempSkill("dchuayi_" + color, { player: "phaseBegin" }); }, - subSkill:{ - red:{ - trigger:{global:'phaseEnd'}, - charlotte:true, - forced:true, - content:function(){ + subSkill: { + red: { + trigger: { global: "phaseEnd" }, + charlotte: true, + forced: true, + content: function () { player.draw(); }, - mark:true, - intro:{ - name:'华衣·红', - content:'一名角色的回合结束时,你摸一张牌' + mark: true, + intro: { + name: "华衣·红", + content: "一名角色的回合结束时,你摸一张牌", }, }, - black:{ - trigger:{player:'damageEnd'}, - charlotte:true, - forced:true, - content:function(){ + black: { + trigger: { player: "damageEnd" }, + charlotte: true, + forced: true, + content: function () { player.draw(2); }, - mark:true, - intro:{ - name:'华衣·黑', - content:'当你受到伤害后,摸两张牌' + mark: true, + intro: { + name: "华衣·黑", + content: "当你受到伤害后,摸两张牌", }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.5; - else num=0.3; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.5; + else num = 0.3; } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } - } - } - } - } - } + }, + }, + }, + }, + }, }, //张瑾云 - dchuizhi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseToDiscard(get.prompt('dchuizhi'),'你可以选择弃置任意张手牌并点击“确定”,将手牌摸至与全场手牌数最多的角色数相同。',[0,Infinity]).set('logSkill','dchuizhi').set('ai',card=>{ - if(_status.event.isMax){ - if(ui.selected.cards.length) return -get.value(card); - return 0; - } - return 6-get.value(card); - }).set('isMax',player.isMaxHandcard()); - 'step 1' - if(result.bool){ - var num=0,targets=game.filterPlayer(); - for(var current of targets){ - if(current.isMaxHandcard()){ - num=current.countCards('h'); + dchuizhi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("dchuizhi"), + "你可以选择弃置任意张手牌并点击“确定”,将手牌摸至与全场手牌数最多的角色数相同。", + [0, Infinity] + ) + .set("logSkill", "dchuizhi") + .set("ai", (card) => { + if (_status.event.isMax) { + if (ui.selected.cards.length) return -get.value(card); + return 0; + } + return 6 - get.value(card); + }) + .set("isMax", player.isMaxHandcard()); + "step 1"; + if (result.bool) { + var num = 0, + targets = game.filterPlayer(); + for (var current of targets) { + if (current.isMaxHandcard()) { + num = current.countCards("h"); break; } } - num=Math.max(1,Math.min(5,num-player.countCards('h'))); + num = Math.max(1, Math.min(5, num - player.countCards("h"))); player.draw(num); } - } + }, }, - dcjijiao:{ - audio:2, - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'orange', - init:function(player){ - player.addSkill('dcjijiao_machi'); + dcjijiao: { + audio: 2, + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "orange", + init: function (player) { + player.addSkill("dcjijiao_machi"); }, - onremove:function(player){ - player.removeSkill('dcjijiao_machi'); + onremove: function (player) { + player.removeSkill("dcjijiao_machi"); }, - onChooseToUse:function(event){ - if(event.dcjijiao==undefined&&!game.online){ - var bool=lib.skill.dcjijiao.getCards(event.player,true); - event.set('dcjijiao',bool); + onChooseToUse: function (event) { + if (event.dcjijiao == undefined && !game.online) { + var bool = lib.skill.dcjijiao.getCards(event.player, true); + event.set("dcjijiao", bool); } }, - filter:function(event,player){ + filter: function (event, player) { return event.dcjijiao; }, - filterTarget:true, - getCards:function(player,bool){ - var cards=Array.from(ui.discardPile.childNodes); - var gains=cards.slice(0); - var history=game.getAllGlobalHistory('cardMove',function(evt){ - if(evt.name=='lose') return evt.position==ui.discardPile; - return evt.name=='cardsDiscard'; + filterTarget: true, + getCards: function (player, bool) { + var cards = Array.from(ui.discardPile.childNodes); + var gains = cards.slice(0); + var history = game.getAllGlobalHistory("cardMove", function (evt) { + if (evt.name == "lose") return evt.position == ui.discardPile; + return evt.name == "cardsDiscard"; }); - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - var cards2=evt.cards.filter(function(card){ + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + var cards2 = evt.cards.filter(function (card) { return cards.includes(card); }); - if(cards2.length){ - if(!lib.skill.dcjijiao.isUse(evt,player)){ + if (cards2.length) { + if (!lib.skill.dcjijiao.isUse(evt, player)) { gains.removeArray(cards2); } cards.removeArray(cards2); } - if(!cards.length) break; + if (!cards.length) break; } - if(bool) return gains.some(card=>get.type2(card,false)=='trick'); - return gains.filter(card=>get.type2(card,false)=='trick'); + if (bool) return gains.some((card) => get.type2(card, false) == "trick"); + return gains.filter((card) => get.type2(card, false) == "trick"); }, - isUse:function(event,player){ - if(event.name!='cardsDiscard') return (event.type=='discard'&&event.player==player); - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evt2=(evtx.relatedEvent||evtx.getParent()); - return (evt2.name=='useCard'&&evt2.player==player); + isUse: function (event, player) { + if (event.name != "cardsDiscard") + return event.type == "discard" && event.player == player; + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evt2 = evtx.relatedEvent || evtx.getParent(); + return evt2.name == "useCard" && evt2.player == player; }, - content:function(){ - player.awakenSkill('dcjijiao'); - var cards=lib.skill.dcjijiao.getCards(player); - if(cards.length){ - target.gain(cards,'gain2').gaintag.add('dcjijiao'); - target.addSkill('dcjijiao_nowuxie'); + content: function () { + player.awakenSkill("dcjijiao"); + var cards = lib.skill.dcjijiao.getCards(player); + if (cards.length) { + target.gain(cards, "gain2").gaintag.add("dcjijiao"); + target.addSkill("dcjijiao_nowuxie"); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ - 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; + ai: { + order: 1, + result: { + target: function (player, target) { + 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 && current.countCards("hes") < 3 + ) <= 1 + ) + return 0; return 5; - } - } - }, - subSkill:{ - machi:{ - charlotte:true, - forced:true, - popup:false, - trigger:{ - global:['washCard','die'], }, - filter:function(event,player){ - return player.hasSkill('dcjijiao',null,false,false); - }, - content:function(){ - player.addSkill('dcjijiao_risutoa'); - } }, - risutoa:{ - charlotte:true, - forced:true, - popup:false, - trigger:{global:'phaseAfter'}, - content:function(){ - if(player.awakenedSkills.includes('dcjijiao')){ - player.restoreSkill('dcjijiao'); - game.log(player,'重置了','#g【继椒】'); + }, + subSkill: { + machi: { + charlotte: true, + forced: true, + popup: false, + trigger: { + global: ["washCard", "die"], + }, + filter: function (event, player) { + return player.hasSkill("dcjijiao", null, false, false); + }, + content: function () { + player.addSkill("dcjijiao_risutoa"); + }, + }, + risutoa: { + charlotte: true, + forced: true, + popup: false, + trigger: { global: "phaseAfter" }, + content: function () { + if (player.awakenedSkills.includes("dcjijiao")) { + player.restoreSkill("dcjijiao"); + game.log(player, "重置了", "#g【继椒】"); //player.removeSkill('dcjijiao_machi'); } - player.removeSkill('dcjijiao_risutoa'); - } + player.removeSkill("dcjijiao_risutoa"); + }, }, - nowuxie:{ - trigger:{player:'useCard1'}, - forced:true, - charlotte:true, - firstDo:true, - popup:false, - filter:function(event,player){ - if(get.type(event.card)!='trick') return false; - return player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('dcjijiao')) return true; + nowuxie: { + trigger: { player: "useCard1" }, + forced: true, + charlotte: true, + firstDo: true, + popup: false, + filter: function (event, player) { + if (get.type(event.card) != "trick") return false; + return player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("dcjijiao")) return true; } return false; }); }, - content:function(){ - trigger.nowuxie=true; + content: function () { + trigger.nowuxie = true; }, - onremove:function(player){ - player.removeGaintag('dcjijiao'); + onremove: function (player) { + player.removeGaintag("dcjijiao"); }, - } - } + }, + }, }, //桓范 - dcjianzheng:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.countCards('h')&&target!=player; + dcjianzheng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("h") && target != player; }, - content:function(){ - 'step 0' - var forced=target.hasCard(i=>player.hasUseTarget(i),'h'); - player.choosePlayerCard(target,'h','visible',forced,'获得并使用其中一张牌').set('filterButton',button=>{ - return _status.event.player.hasUseTarget(button.link); - }).set('ai',button=>{ - return _status.event.player.getUseValue(button.link); - }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.gain(card,'giveAuto'); + content: function () { + "step 0"; + var forced = target.hasCard((i) => player.hasUseTarget(i), "h"); + player + .choosePlayerCard(target, "h", "visible", forced, "获得并使用其中一张牌") + .set("filterButton", (button) => { + return _status.event.player.hasUseTarget(button.link); + }) + .set("ai", (button) => { + return _status.event.player.getUseValue(button.link); + }); + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player.gain(card, "giveAuto"); + } else event.goto(3); + "step 2"; + if (get.position(card) == "h" && get.owner(card) == player && player.hasUseTarget(card)) { + if (get.name(card, player) == "sha") player.chooseUseTarget(card, true, false); + else player.chooseUseTarget(card, true); } - else event.goto(3); - 'step 2' - if(get.position(card)=='h'&&get.owner(card)==player&&player.hasUseTarget(card)){ - if(get.name(card,player)=='sha') player.chooseUseTarget(card,true,false); - else player.chooseUseTarget(card,true); - } - 'step 3' - if(player.hasHistory('useCard',evt=>{ - return evt.getParent(2).name=='dcjianzheng'&&evt.targets.includes(target); - })){ + "step 3"; + if ( + player.hasHistory("useCard", (evt) => { + return evt.getParent(2).name == "dcjianzheng" && evt.targets.includes(target); + }) + ) { player.link(true); target.link(true); - } - else event.finish(); - 'step 4' + } else event.finish(); + "step 4"; target.viewHandcards(player); }, - ai:{ - order:10, - expose:0.2, - result:{ - target:function(player,target){ - return -Math.sqrt(target.countCards('h')); - } - } - } + ai: { + order: 10, + expose: 0.2, + result: { + target: function (player, target) { + return -Math.sqrt(target.countCards("h")); + }, + }, + }, }, //fumo! - dcfumou:{ - audio:2, - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.getDamagedHp()>0; + dcfumou: { + audio: 2, + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return player.getDamagedHp() > 0; }, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - player.chooseTarget(get.prompt2('dcfumou'),[1,player.getDamagedHp()]).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(target.countCards('h')>=3||target.countCards('e')&&!target.isDamaged()){ - if(!target.canMoveCard()) return -att; - else if(!target.canMoveCard(true)) return -att/5; - } - return att; - }); - 'step 2' - if(result.bool){ - var targets=result.targets; - targets.sortBySeat(player); - event.targets=targets; - player.logSkill('dcfumou',targets); - event.num--; - } - else event.finish(); - 'step 3' - var target=targets.shift(); - event.target=target; - var choices=[]; - var choiceList=[ - '移动场上的一张牌', - '弃置所有手牌并摸两张牌', - '弃置装备区里的所有牌并回复1点体力' - ]; - if(target.canMoveCard()) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(target.countCards('h')&&!target.hasCard(card=>{ - return !lib.filter.cardDiscardable(card,target,'dcfumou'); - },'h')) choices.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(target.countCards('e')&&!target.hasCard(card=>{ - return !lib.filter.cardDiscardable(card,target,'dcfumou'); - },'h')) choices.push('选项三'); - else choiceList[2]=''+choiceList[2]+''; - if(choices.length){ - target.chooseControl(choices).set('prompt','腹谋:请选择一项').set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(choices.length==1) return choices[0]; - var func=(choice,target)=>{ - switch(choice){ - case '选项一': - if(target.canMoveCard(true)) return 5; - return 3; - case '选项二': - if(target.countCards('h')<2&&get.value(target.getCards('h')[0])<6) return 4.5; - return 4.5-target.countCards('h'); - case '选项三': - var e2=target.getEquip(2); - if(target.hp+target.countCards('hs',['tao','jiu'])<2&&!e2) return 5.5; - if(get.recoverEffect(target,target,target)<=0) return 3; - if(!e2) return 4.4; - return 5-1.5*target.countCards('e'); - } + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + player + .chooseTarget(get.prompt2("dcfumou"), [1, player.getDamagedHp()]) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if ( + target.countCards("h") >= 3 || + (target.countCards("e") && !target.isDamaged()) + ) { + if (!target.canMoveCard()) return -att; + else if (!target.canMoveCard(true)) return -att / 5; } - var choicesx=choices.map(i=>[i,func(i,target)]).sort((a,b)=>b[1]-a[1]); - return choicesx[0][0]; - }()); - } - else event.goto(5); - 'step 4' - game.log(target,'选择了','#y'+result.control); - if(result.control=='选项一'){ + return att; + }); + "step 2"; + if (result.bool) { + var targets = result.targets; + targets.sortBySeat(player); + event.targets = targets; + player.logSkill("dcfumou", targets); + event.num--; + } else event.finish(); + "step 3"; + var target = targets.shift(); + event.target = target; + var choices = []; + var choiceList = [ + "移动场上的一张牌", + "弃置所有手牌并摸两张牌", + "弃置装备区里的所有牌并回复1点体力", + ]; + if (target.canMoveCard()) choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if ( + target.countCards("h") && + !target.hasCard((card) => { + return !lib.filter.cardDiscardable(card, target, "dcfumou"); + }, "h") + ) + choices.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if ( + target.countCards("e") && + !target.hasCard((card) => { + return !lib.filter.cardDiscardable(card, target, "dcfumou"); + }, "h") + ) + choices.push("选项三"); + else choiceList[2] = '' + choiceList[2] + ""; + if (choices.length) { + target + .chooseControl(choices) + .set("prompt", "腹谋:请选择一项") + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (choices.length == 1) return choices[0]; + var func = (choice, target) => { + switch (choice) { + case "选项一": + if (target.canMoveCard(true)) return 5; + return 3; + case "选项二": + if ( + target.countCards("h") < 2 && + get.value(target.getCards("h")[0]) < 6 + ) + return 4.5; + return 4.5 - target.countCards("h"); + case "选项三": + var e2 = target.getEquip(2); + if ( + target.hp + target.countCards("hs", ["tao", "jiu"]) < 2 && + !e2 + ) + return 5.5; + if (get.recoverEffect(target, target, target) <= 0) return 3; + if (!e2) return 4.4; + return 5 - 1.5 * target.countCards("e"); + } + }; + var choicesx = choices + .map((i) => [i, func(i, target)]) + .sort((a, b) => b[1] - a[1]); + return choicesx[0][0]; + })() + ); + } else event.goto(5); + "step 4"; + game.log(target, "选择了", "#y" + result.control); + if (result.control == "选项一") { target.moveCard(true); - } - else if(result.control=='选项二'){ - target.chooseToDiscard(true,'h',target.countCards('h')); + } else if (result.control == "选项二") { + target.chooseToDiscard(true, "h", target.countCards("h")); target.draw(2); - } - else{ - target.chooseToDiscard(true,'e',target.countCards('e')); + } else { + target.chooseToDiscard(true, "e", target.countCards("e")); target.recover(); } - 'step 5' - if(event.targets.length) event.goto(3); + "step 5"; + if (event.targets.length) event.goto(3); // else if(event.num) event.goto(1); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()) num=0.7; - else num=0.5; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) num = 0.7; + else num = 0.5; } - if(target.hp==2&&target.hasFriend()) return [1,num*1.5]; - if(target.hp>=2) return [1,num]; + if (target.hp == 2 && target.hasFriend()) return [1, num * 1.5]; + if (target.hp >= 2) return [1, num]; } }, }, - } + }, }, //陈泰 - dcctjiuxian:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:lib.filter.cardRecastable, - selectCard:function(){ - return Math.ceil(_status.event.player.countCards('h')/2); + dcctjiuxian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: lib.filter.cardRecastable, + selectCard: function () { + return Math.ceil(_status.event.player.countCards("h") / 2); }, - check:function(card){ - return 6.5-get.value(card); + check: function (card) { + return 6.5 - get.value(card); }, - discard:false, - lose:false, - delay:false, - content:function(){ - 'step 0' + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; player.recast(cards); - 'step 1' - player.addTempSkill('dcctjiuxian_help'); - player.chooseUseTarget({ - name:'juedou', - isCard:true, - storage:{dcctjiuxian:true} - },true); + "step 1"; + player.addTempSkill("dcctjiuxian_help"); + player.chooseUseTarget( + { + name: "juedou", + isCard: true, + storage: { dcctjiuxian: true }, + }, + true + ); }, - ai:{ - order:function(){ - return 0.9*get.order({name:'juedou'}); + ai: { + order: function () { + return 0.9 * get.order({ name: "juedou" }); }, - tag:{ - respond:2, - respondSha:2, - damage:1, + 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)); + 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) && current.isDamaged()) + receff = Math.max(receff, get.recoverEffect(current, i, i)); }); - if(jdeff+receff/5>maxval){ - target=i; - maxval=jdeff+receff/5; + if (jdeff + receff / 5 > maxval) { + target = i; + maxval = jdeff + receff / 5; } } - if(target) return maxval/80; + if (target) return maxval / 80; return 0; - } - } - }, - subSkill:{ - help:{ - trigger:{global:'damageSource'}, - filter:function(event,player){ - return event.card&&event.card.storage&&event.card.storage.dcctjiuxian&&event.player.isIn()&& - event.getParent(2).targets.includes(event.player)&&game.hasPlayer(current=>{ - return current!=player&&event.player.inRange(current)&¤t.isDamaged(); - }); }, - direct:true, - forced:true, - charlotte:true, - content:function(){ - 'step 0' - player.chooseTarget('救陷:是否令其攻击范围内的一名其他角色回复1点体力?',(card,player,target)=>{ - if(_status.event.player==target) return false; - return target.isDamaged()&&_status.event.targetx.inRange(target); - }).set('targetx',trigger.player).set('ai',target=>get.recoverEffect(target,_status.event.player,_status.event.player)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcctjiuxian_help',target); + }, + }, + subSkill: { + help: { + trigger: { global: "damageSource" }, + filter: function (event, player) { + return ( + event.card && + event.card.storage && + event.card.storage.dcctjiuxian && + event.player.isIn() && + event.getParent(2).targets.includes(event.player) && + game.hasPlayer((current) => { + return ( + current != player && + event.player.inRange(current) && + current.isDamaged() + ); + }) + ); + }, + direct: true, + forced: true, + charlotte: true, + content: function () { + "step 0"; + player + .chooseTarget( + "救陷:是否令其攻击范围内的一名其他角色回复1点体力?", + (card, player, target) => { + if (_status.event.player == target) return false; + return target.isDamaged() && _status.event.targetx.inRange(target); + } + ) + .set("targetx", trigger.player) + .set("ai", (target) => + get.recoverEffect(target, _status.event.player, _status.event.player) + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcctjiuxian_help", target); target.recover(player); } - } - } - } - }, - dcchenyong:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - return player.getHistory('useCard').length; + }, + }, }, - content:function(){ - var types=[]; - var history=player.getHistory('useCard'); - for(var evt of history){ + }, + dcchenyong: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { + return player.getHistory("useCard").length; + }, + content: function () { + var types = []; + var history = player.getHistory("useCard"); + for (var evt of history) { types.add(get.type2(evt.card)); } - var num=types.length; + var num = types.length; player.draw(num); }, - ai:{threaten:2.2} + ai: { threaten: 2.2 }, }, //孙瑜 - dcquanshou:{ - audio:2, - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - return event.player.countCards('h')<=event.player.maxHp; + dcquanshou: { + audio: 2, + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + return event.player.countCards("h") <= event.player.maxHp; }, - logTarget:'player', - check:function(event,player){ - if(get.attitude(player,event.player)>0) return true; - const draw=event.player.maxHp-event.player.countCards('h'); - return draw<=2&&event.player.getHp(true)-draw>=1; + logTarget: "player", + check: function (event, player) { + if (get.attitude(player, event.player) > 0) return true; + const draw = event.player.maxHp - event.player.countCards("h"); + return draw <= 2 && event.player.getHp(true) - draw >= 1; }, - content:function(){ - 'step 0' - var draw=Math.min(5,trigger.player.maxHp-trigger.player.countCards('h')); - trigger.player.chooseControl().set('choiceList',[ - (draw>0?'摸'+get.cnNumber(draw)+'张牌,然后':'令')+'你本回合使用【杀】的次数上限-1', - '当你本回合使用牌被抵消后,'+get.translation(player)+'摸一张牌' - ]).set('ai',()=>_status.event.choice).set('choice',function(){ - var draw=Math.min(5,Math.max(0,trigger.player.maxHp-trigger.player.countCards('h'))); - if(get.attitude(trigger.player,player)>0){ - if(draw>=3||trigger.player.getCardUsable('sha')>1) return '选项一'; - if(!draw||draw<=1&&trigger.player.countCards('hs',card=>{ - return get.name(card)=='sha'&&trigger.player.hasValueTarget(card); - })) return '选项二'; - return '选项一'; - } - else{ - if(draw>=4) return '选项一'; - if(draw<2&&trigger.player.countCards('hs',card=>{ - return trigger.player.hasValueTarget(card); - })) return '选项二'; - return '选项一'; - } - }()).set('prompt','劝守:请选择一项'); - 'step 1' - game.log(trigger.player,'选择了','#y'+result.control); - if(result.control=='选项一'){ - var draw=Math.min(5,trigger.player.maxHp-trigger.player.countCards('h')); - if(draw>0) trigger.player.draw(draw); - trigger.player.addTempSkill('dcquanshou_sha'); - trigger.player.addMark('dcquanshou_sha',1,false); - } - else{ - trigger.player.addTempSkill('dcquanshou_respond'); - trigger.player.markAuto('dcquanshou_respond',[player]); + content: function () { + "step 0"; + var draw = Math.min(5, trigger.player.maxHp - trigger.player.countCards("h")); + trigger.player + .chooseControl() + .set("choiceList", [ + (draw > 0 ? "摸" + get.cnNumber(draw) + "张牌,然后" : "令") + + "你本回合使用【杀】的次数上限-1", + "当你本回合使用牌被抵消后," + get.translation(player) + "摸一张牌", + ]) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + var draw = Math.min( + 5, + Math.max(0, trigger.player.maxHp - trigger.player.countCards("h")) + ); + if (get.attitude(trigger.player, player) > 0) { + if (draw >= 3 || trigger.player.getCardUsable("sha") > 1) return "选项一"; + if ( + !draw || + (draw <= 1 && + trigger.player.countCards("hs", (card) => { + return ( + get.name(card) == "sha" && + trigger.player.hasValueTarget(card) + ); + })) + ) + return "选项二"; + return "选项一"; + } else { + if (draw >= 4) return "选项一"; + if ( + draw < 2 && + trigger.player.countCards("hs", (card) => { + return trigger.player.hasValueTarget(card); + }) + ) + return "选项二"; + return "选项一"; + } + })() + ) + .set("prompt", "劝守:请选择一项"); + "step 1"; + game.log(trigger.player, "选择了", "#y" + result.control); + if (result.control == "选项一") { + var draw = Math.min(5, trigger.player.maxHp - trigger.player.countCards("h")); + if (draw > 0) trigger.player.draw(draw); + trigger.player.addTempSkill("dcquanshou_sha"); + trigger.player.addMark("dcquanshou_sha", 1, false); + } else { + trigger.player.addTempSkill("dcquanshou_respond"); + trigger.player.markAuto("dcquanshou_respond", [player]); } }, - ai:{ - expose:0.1 + ai: { + expose: 0.1, }, - subSkill:{ - sha:{ - charlotte:true, - onremove:true, - marktext:'守', - intro:{content:'使用【杀】的次数上限-#'}, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num-player.countMark('dcquanshou_sha'); + subSkill: { + sha: { + charlotte: true, + onremove: true, + marktext: "守", + intro: { content: "使用【杀】的次数上限-#" }, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num - player.countMark("dcquanshou_sha"); }, - } - }, - respond:{ - trigger:{player:['shaMiss','eventNeutralized']}, - filter:function(event,player){ - if(event.type!='card'&&event.name!='_wuxie') return false; - return player.getStorage('dcquanshou_respond').some(i=>i.isIn()); }, - forced:true, - popup:false, - charlotte:true, - onremove:true, - marktext:'', - intro:{content:'本回合使用的牌被抵消后,$摸一张牌'}, - content:function(){ - var targets=player.getStorage('dcquanshou_respond'); + }, + respond: { + trigger: { player: ["shaMiss", "eventNeutralized"] }, + filter: function (event, player) { + if (event.type != "card" && event.name != "_wuxie") return false; + return player.getStorage("dcquanshou_respond").some((i) => i.isIn()); + }, + forced: true, + popup: false, + charlotte: true, + onremove: true, + marktext: '', + intro: { content: "本回合使用的牌被抵消后,$摸一张牌" }, + content: function () { + var targets = player.getStorage("dcquanshou_respond"); targets.sortBySeat(); - for(var target of targets){ - if(target.isIn()){ - target.logSkill('dcquanshou_respond',player); + for (var target of targets) { + if (target.isIn()) { + target.logSkill("dcquanshou_respond", player); target.draw(); } } - } - } - } - }, - dcshexue:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - var cards=lib.skill.dcshexue.getLast(); - return cards.some(card=>player.hasUseTarget(card,false)); + }, + }, }, - getLast:function(){ - var cards=[]; - for(var current of game.filterPlayer()){ - var history=current.actionHistory; - if(history.length<2) continue; - if(history[history.length-2].isMe){ - var evts=history[history.length-2].useCard; - for(var i=evts.length-1;i>=0;i--){ - var evt=evts[i]; - if(get.type(evt.card)!='basic'&&get.type(evt.card)!='trick') continue; - var evtx=evt.getParent('phaseUse'); - if(evtx&&evtx.player==current) cards.push({name:evt.card.name,nature:evt.card.nature}); + }, + dcshexue: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + var cards = lib.skill.dcshexue.getLast(); + return cards.some((card) => player.hasUseTarget(card, false)); + }, + getLast: function () { + var cards = []; + for (var current of game.filterPlayer()) { + var history = current.actionHistory; + if (history.length < 2) continue; + if (history[history.length - 2].isMe) { + var evts = history[history.length - 2].useCard; + for (var i = evts.length - 1; i >= 0; i--) { + var evt = evts[i]; + if (get.type(evt.card) != "basic" && get.type(evt.card) != "trick") continue; + var evtx = evt.getParent("phaseUse"); + if (evtx && evtx.player == current) + cards.push({ name: evt.card.name, nature: evt.card.nature }); } } } return cards; }, - direct:true, - group:'dcshexue_end', - content:function(){ - 'step 0' - var cards=lib.skill.dcshexue.getLast(); - cards=cards.filter(card=>player.hasUseTarget(card,false)); - player.chooseButton(['设学:是否将一张牌当作其中一张牌使用?',[cards,'vcard']]); - 'step 1' - if(!result.bool) return; - var card=result.links[0]; - game.broadcastAll(function(card){ - lib.skill.dcshexue_backup.viewAs=card; - },card); - var next=player.chooseToUse(); - next.set('openskilldialog',`###${get.prompt('dcshexue')}###将一张牌当做${get.translation(card.nature)||''}【${get.translation(card.name)}】使用`); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','dcshexue_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + direct: true, + group: "dcshexue_end", + content: function () { + "step 0"; + var cards = lib.skill.dcshexue.getLast(); + cards = cards.filter((card) => player.hasUseTarget(card, false)); + player.chooseButton(["设学:是否将一张牌当作其中一张牌使用?", [cards, "vcard"]]); + "step 1"; + if (!result.bool) return; + var card = result.links[0]; + game.broadcastAll(function (card) { + lib.skill.dcshexue_backup.viewAs = card; + }, card); + var next = player.chooseToUse(); + next.set( + "openskilldialog", + `###${get.prompt("dcshexue")}###将一张牌当做${ + get.translation(card.nature) || "" + }【${get.translation(card.name)}】使用` + ); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "dcshexue_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('dcshexue_backup'); + next.backup("dcshexue_backup"); }, - subSkill:{ - backup:{ - audio:'dcshexue', - filterCard:function(card){ - return get.itemtype(card)=='card'; + subSkill: { + backup: { + audio: "dcshexue", + filterCard: function (card) { + return get.itemtype(card) == "card"; }, - filterTarget:lib.filter.targetEnabled, - position:'hes', - selectCard:1, - check:(card)=>6-get.value(card), - popname:true, + filterTarget: lib.filter.targetEnabled, + position: "hes", + selectCard: 1, + check: (card) => 6 - get.value(card), + popname: true, }, - end:{ - audio:'dcshexue', - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getHistory('useCard',evt=>{ - return evt.getParent('phaseUse')==event&&(get.type(evt.card)=='basic'||get.type(evt.card)=='trick'); + end: { + audio: "dcshexue", + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return player.getHistory("useCard", (evt) => { + return ( + evt.getParent("phaseUse") == event && + (get.type(evt.card) == "basic" || get.type(evt.card) == "trick") + ); }).length; }, - prompt2:function(event,player){ - return '令下一回合的角色于其出牌阶段开始时选择是否将一张牌当做你本阶段使用过的一张基本牌或普通锦囊牌使用?'; + prompt2: function (event, player) { + return "令下一回合的角色于其出牌阶段开始时选择是否将一张牌当做你本阶段使用过的一张基本牌或普通锦囊牌使用?"; }, - check:function(event,player){ - let evt=event.getParent('phase').getParent(); - let nextPlayer=player.getNext(); - if(evt&&evt.next&&evt.next.length){ - nextPlayer=evt.next[0].player; + check: function (event, player) { + let evt = event.getParent("phase").getParent(); + let nextPlayer = player.getNext(); + if (evt && evt.next && evt.next.length) { + nextPlayer = evt.next[0].player; } - return get.attitude(player,nextPlayer)>0; + return get.attitude(player, nextPlayer) > 0; }, - content:function(){ - var history=player.getHistory('useCard',evt=>{ - return evt.getParent('phaseUse')==trigger&&(get.type(evt.card)=='basic'||get.type(evt.card)=='trick'); + content: function () { + var history = player.getHistory("useCard", (evt) => { + return ( + evt.getParent("phaseUse") == trigger && + (get.type(evt.card) == "basic" || get.type(evt.card) == "trick") + ); }); - player.addSkill('dcshexue_studyclear'); - if(!player.storage.dcshexue_studyclear) player.storage.dcshexue_studyclear=[]; - history.forEach(evt=>{ - var card=evt.card; - card={name:card.name,nature:card.nature}; + player.addSkill("dcshexue_studyclear"); + if (!player.storage.dcshexue_studyclear) player.storage.dcshexue_studyclear = []; + history.forEach((evt) => { + var card = evt.card; + card = { name: card.name, nature: card.nature }; player.storage.dcshexue_studyclear.push(card); }); - } - }, - study:{ - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.getStorage('dcshexue_study').some(i=>event.player.hasUseTarget(i,false)); }, - onremove:true, - charlotte:true, - direct:true, - content:function(){ - 'step 0' - event.cards=player.getStorage('dcshexue_study'); - 'step 1' - var card=cards.pop(); - if(trigger.player.hasUseTarget(card,false)){ - game.broadcastAll(function(card){ - lib.skill.dcshexue_backup.viewAs=card; - lib.skill.dcshexue_backup.prompt='设学:是否将一张牌当做'+get.translation(card)+'使用?'; - },card); - var next=trigger.player.chooseToUse(); - next.set('openskilldialog',`###${get.prompt('dcshexue_study')}###将一张牌当做${get.translation(card.nature)||''}【${get.translation(card.name)}】使用`); - next.set('norestore',true); - next.set('addCount',false); - next.set('_backupevent','dcshexue_backup'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} - }); - next.backup('dcshexue_backup'); - } - if(cards.length) event.redo(); - } }, - studyclear:{ - trigger:{global:'phaseBegin'}, - charlotte:true, - forceDie:true, - silent:true, - onremove:true, - lastDo:true, - content:function(){ - trigger.player.addTempSkill('dcshexue_study'); - if(!trigger.player.storage.dcshexue_study) trigger.player.storage.dcshexue_study=[]; - trigger.player.storage.dcshexue_study=trigger.player.storage.dcshexue_study.concat(player.getStorage('dcshexue_studyclear')); - player.removeSkill('dcshexue_studyclear'); - } - } - } + study: { + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player + .getStorage("dcshexue_study") + .some((i) => event.player.hasUseTarget(i, false)); + }, + onremove: true, + charlotte: true, + direct: true, + content: function () { + "step 0"; + event.cards = player.getStorage("dcshexue_study"); + "step 1"; + var card = cards.pop(); + if (trigger.player.hasUseTarget(card, false)) { + game.broadcastAll(function (card) { + lib.skill.dcshexue_backup.viewAs = card; + lib.skill.dcshexue_backup.prompt = + "设学:是否将一张牌当做" + get.translation(card) + "使用?"; + }, card); + var next = trigger.player.chooseToUse(); + next.set( + "openskilldialog", + `###${get.prompt("dcshexue_study")}###将一张牌当做${ + get.translation(card.nature) || "" + }【${get.translation(card.name)}】使用` + ); + next.set("norestore", true); + next.set("addCount", false); + next.set("_backupevent", "dcshexue_backup"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, + }); + next.backup("dcshexue_backup"); + } + if (cards.length) event.redo(); + }, + }, + studyclear: { + trigger: { global: "phaseBegin" }, + charlotte: true, + forceDie: true, + silent: true, + onremove: true, + lastDo: true, + content: function () { + trigger.player.addTempSkill("dcshexue_study"); + if (!trigger.player.storage.dcshexue_study) + trigger.player.storage.dcshexue_study = []; + trigger.player.storage.dcshexue_study = + trigger.player.storage.dcshexue_study.concat( + player.getStorage("dcshexue_studyclear") + ); + player.removeSkill("dcshexue_studyclear"); + }, + }, + }, }, //郤正 - dcdanyi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget) return false; - if(!event.targets||!event.targets.length) return false; - var evt=lib.skill.dcjianying.getLastUsed(player,event.getParent()); - if(!evt||!evt.targets||!evt.targets.length) return false; - return event.targets.some(target=>evt.targets.includes(target)); + dcdanyi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget) return false; + if (!event.targets || !event.targets.length) return false; + var evt = lib.skill.dcjianying.getLastUsed(player, event.getParent()); + if (!evt || !evt.targets || !evt.targets.length) return false; + return event.targets.some((target) => evt.targets.includes(target)); }, - frequent:true, - locked:false, - content:function(){ - var evt=lib.skill.dcjianying.getLastUsed(player,trigger.getParent()); - player.draw(trigger.targets.filter(target=>evt.targets.includes(target)).length); + frequent: true, + locked: false, + content: function () { + var evt = lib.skill.dcjianying.getLastUsed(player, trigger.getParent()); + player.draw(trigger.targets.filter((target) => evt.targets.includes(target)).length); }, - locked:false, - mod:{ - aiOrder:function(player,card,num){ - var evt=player.getLastUsed(); - if(evt&&evt.targets&&evt.targets.length&&game.hasPlayer(current=>{ - return evt.targets.includes(current)&&player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })) return num+10; + locked: false, + mod: { + aiOrder: function (player, card, num) { + var evt = player.getLastUsed(); + if ( + evt && + evt.targets && + evt.targets.length && + game.hasPlayer((current) => { + return ( + evt.targets.includes(current) && + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) + return num + 10; }, }, - ai:{ - effect:{ - player:function(card,player,target){ - var evt=player.getLastUsed(); - if(evt&&evt.targets.includes(target)) return [1.5,0]; + ai: { + effect: { + player: function (card, player, target) { + var evt = player.getLastUsed(); + if (evt && evt.targets.includes(target)) return [1.5, 0]; }, }, }, }, - dcwencan:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - if(ui.selected.targets.length){ - if(ui.selected.targets[0].hp==target.hp) return false; + dcwencan: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + if (ui.selected.targets.length) { + if (ui.selected.targets[0].hp == target.hp) return false; } - return target!=player; + return target != player; }, - selectTarget:[1,2], - complexTarget:true, - multiline:true, - content:function(){ - 'step 0' - target.chooseToDiscard(get.translation(player)+'对你发动了【文灿】','是否弃置两张花色不同的牌?或者点击“取消”,令其本回合对你使用牌无距离和次数限制','he',2,(card,player)=>{ - if(!ui.selected.cards.length) return true; - var suit=get.suit(card,player); - for(var i of ui.selected.cards){ - if(get.suit(i,player)==suit) return false; - } - return true; - }).set('complexCard',true).set('ai',card=>{ - if(_status.event.nofear) return 0; - return 5-get.value(card); - }).set('nofear',player.countCards('hs',card=>{ - return get.tag(card,'damage')&&player.canUse(card,target,false)&&get.effect(target,card,player,target)<=0; - }) { + if (!ui.selected.cards.length) return true; + var suit = get.suit(card, player); + for (var i of ui.selected.cards) { + if (get.suit(i, player) == suit) return false; + } + return true; + } + ) + .set("complexCard", true) + .set("ai", (card) => { + if (_status.event.nofear) return 0; + return 5 - get.value(card); + }) + .set( + "nofear", + player.countCards("hs", (card) => { + return ( + get.tag(card, "damage") && + player.canUse(card, target, false) && + get.effect(target, card, player, target) <= 0 + ); + }) < target.hp + ); + "step 1"; + if (!result.bool) { + player.addTempSkill("dcwencan_paoxiao"); + player.markAuto("dcwencan_paoxiao", [target]); } }, - subSkill:{ - paoxiao:{ - charlotte:true, - onremove:true, - marktext:'灿', - intro:{content:'对$使用牌无距离和次数限制'}, - mod:{ - cardUsableTarget:function(card,player,target){ - if(player.getStorage('dcwencan_paoxiao').includes(target)) return true; + subSkill: { + paoxiao: { + charlotte: true, + onremove: true, + marktext: "灿", + intro: { content: "对$使用牌无距离和次数限制" }, + mod: { + cardUsableTarget: function (card, player, target) { + if (player.getStorage("dcwencan_paoxiao").includes(target)) return true; }, - targetInRange:function(card,player,target){ - if(player.getStorage('dcwencan_paoxiao').includes(target)) return true; + targetInRange: function (card, player, target) { + if (player.getStorage("dcwencan_paoxiao").includes(target)) return true; }, - } - } + }, + }, + }, + ai: { + order: 9, + result: { target: -1 }, }, - ai:{ - order:9, - result:{target:-1} - } }, //芮姬 - dcwangyuan:{ - audio:2, - trigger:{ - player:['loseAfter','logSkill'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + dcwangyuan: { + audio: 2, + trigger: { + player: ["loseAfter", "logSkill"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - frequent:true, - filter:function(event,player,name){ - if(player==_status.currentPhase) return (name=='logSkill'&&event.skill=='dcliying'&&player.getExpansions('dcwangyuan').length=game.countPlayer()) return false; - if(event.name=='gain'&&event.player==player) return false; - var evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>0; + frequent: true, + filter: function (event, player, name) { + if (player == _status.currentPhase) + return ( + name == "logSkill" && + event.skill == "dcliying" && + player.getExpansions("dcwangyuan").length < game.countPlayer2() + ); + if (name == "logSkill") return false; + if (player.getExpansions("dcwangyuan").length >= game.countPlayer()) return false; + if (event.name == "gain" && event.player == player) return false; + var evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('dcwangyuan'); - var card=get.cardPile2(cardx=>{ - var type=get.type2(cardx); - return (type=='basic'||type=='trick')&&!cards.some(cardxx=>get.name(cardx,false)==get.name(cardxx,false)); + content: function () { + "step 0"; + var cards = player.getExpansions("dcwangyuan"); + var card = get.cardPile2((cardx) => { + var type = get.type2(cardx); + return ( + (type == "basic" || type == "trick") && + !cards.some((cardxx) => get.name(cardx, false) == get.name(cardxx, false)) + ); }); - if(card) player.addToExpansion(card,'gain2').gaintag.add('dcwangyuan'); + if (card) player.addToExpansion(card, "gain2").gaintag.add("dcwangyuan"); }, - marktext:'妄', - intro:{ - name:'妄(妄缘/铃音)', - content:'expansion', - markcount:'expansion', + ai: { + combo: "dclingyin", + }, + marktext: "妄", + intro: { + name: "妄(妄缘/铃音)", + content: "expansion", + markcount: "expansion", }, }, - dclingyin:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return player.getExpansions('dcwangyuan').length; + dclingyin: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.getExpansions("dcwangyuan").length; }, - direct:true, - content:function(){ - 'step 0' - var cards=player.getExpansions('dcwangyuan'); - player.chooseButton([ - get.prompt('dclingyin')+'(当前轮数:'+get.cnNumber(game.roundNumber,true)+')', - cards - ],[1,game.roundNumber]).set('ai',button=>{ - var color=_status.event.color,player=_status.event.player; - if(ui.selected.buttons.length>0&&ui.selected.buttons.length==player.getExpansions('dcwangyuan').length-1) return 0; - if(color==1) return get.value(button.link); - if(color) return get.color(button.link)==color?1:0; - return 0; - }).set('color',function(){ - var cardsR=cards.filter(i=>get.color(i)=='red'); - if(cardsR.length==cards.length||cardsR.length==0||cards.length<=game.roundNumber) return 1; - if(cardsR.length<=game.roundNumber) return 'red'; - if(cards.length-cardsR.length<=game.roundNumber) return 'black'; - return 1; - }()); - 'step 1' - if(result.bool){ - player.logSkill('dclingyin'); - var cards=result.links; - player.gain(cards,'gain2'); - var cardsx=player.getExpansions('dcwangyuan').removeArray(cards); - if(cardsx.length<=1||get.color(cardsx)!='none'){ - player.addTempSkill('dclingyin_effect'); - player.addMark('dclingyin_effect',1,false); - game.log(player,'获得了','#g【铃音】','的后续效果'); + direct: true, + content: function () { + "step 0"; + var cards = player.getExpansions("dcwangyuan"); + player + .chooseButton( + [ + get.prompt("dclingyin") + + "(当前轮数:" + + get.cnNumber(game.roundNumber, true) + + ")", + cards, + ], + [1, game.roundNumber] + ) + .set("ai", (button) => { + var color = _status.event.color, + player = _status.event.player; + if ( + ui.selected.buttons.length > 0 && + ui.selected.buttons.length == player.getExpansions("dcwangyuan").length - 1 + ) + return 0; + if (color == 1) return get.value(button.link); + if (color) return get.color(button.link) == color ? 1 : 0; + return 0; + }) + .set( + "color", + (function () { + var cardsR = cards.filter((i) => get.color(i) == "red"); + if ( + cardsR.length == cards.length || + cardsR.length == 0 || + cards.length <= game.roundNumber + ) + return 1; + if (cardsR.length <= game.roundNumber) return "red"; + if (cards.length - cardsR.length <= game.roundNumber) return "black"; + return 1; + })() + ); + "step 1"; + if (result.bool) { + player.logSkill("dclingyin"); + var cards = result.links; + player.gain(cards, "gain2"); + var cardsx = player.getExpansions("dcwangyuan").removeArray(cards); + if (cardsx.length <= 1 || get.color(cardsx) != "none") { + player.addTempSkill("dclingyin_effect"); + player.addMark("dclingyin_effect", 1, false); + game.log(player, "获得了", "#g【铃音】", "的后续效果"); } } }, - ai:{ - combo:'dcwangyuan', - threaten:3, + ai: { + combo: "dcwangyuan", + threaten: 3, }, - subSkill:{ - effect:{ - audio:'dclingyin', - enable:'phaseUse', - trigger:{source:'damageBegin1'}, - viewAs:{name:'juedou'}, - charlotte:true, - forced:true, - onremove:true, - prompt:'将一张武器牌或防具牌当【决斗】使用', - filterCard:function(card){ - return get.subtype(card)=='equip1'||get.subtype(card)=='equip2'; + subSkill: { + effect: { + audio: "dclingyin", + enable: "phaseUse", + trigger: { source: "damageBegin1" }, + viewAs: { name: "juedou" }, + charlotte: true, + forced: true, + onremove: true, + prompt: "将一张武器牌或防具牌当【决斗】使用", + filterCard: function (card) { + return get.subtype(card) == "equip1" || get.subtype(card) == "equip2"; }, - position:'hes', - filter:function(event,player){ - if(event.name=='chooseToUse') return player.countCards('hes',{subtype:['equip1','equip2']})>0; - return event.player!=player; + position: "hes", + filter: function (event, player) { + if (event.name == "chooseToUse") + return player.countCards("hes", { subtype: ["equip1", "equip2"] }) > 0; + return event.player != player; }, - content:function(){ - trigger.num+=player.countMark('dclingyin_effect'); + content: function () { + trigger.num += player.countMark("dclingyin_effect"); }, - ai:{ - damageBonus:true, - } - } - } + ai: { + damageBonus: true, + }, + }, + }, }, - dcliying:{ - audio:2, - usable:1, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + dcliying: { + audio: 2, + usable: 1, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - var cards=event.getg(player).filter(i=>get.owner(i)==player&&get.position(i)=='h'); - if(!cards.length) return false; - var evt=event.getParent('phaseDraw'); - if(evt&&evt.name=='phaseDraw') return false; + filter: function (event, player) { + var cards = event + .getg(player) + .filter((i) => get.owner(i) == player && get.position(i) == "h"); + if (!cards.length) return false; + var evt = event.getParent("phaseDraw"); + if (evt && evt.name == "phaseDraw") return false; return true; }, - direct:true, - content:function(){ - 'step 0' - var cards=trigger.getg(player).filter(i=>get.owner(i)==player&&get.position(i)=='h'); - player.chooseCardTarget({ - prompt:get.prompt('dcliying'), - prompt2:'选择本次获得的任意张牌交给一名其他角色,然后摸一张牌', - filterTarget:lib.filter.notMe, - filterCard:card=>_status.event.cards.includes(card), - cards:cards, - selectCard:[1,cards.length], - ai1:function(card){ - if(ui.selected.cards.length) return 0; - return 3/(Math.abs(get.value(card))+0.1) - }, - ai2:function(target){ - return get.value(ui.selected.cards,target)*get.attitude(_status.event.player,target); - }, - }).set('cards',cards); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcliying',target); - player.give(result.cards,target); + direct: true, + content: function () { + "step 0"; + var cards = trigger + .getg(player) + .filter((i) => get.owner(i) == player && get.position(i) == "h"); + player + .chooseCardTarget({ + prompt: get.prompt("dcliying"), + prompt2: "选择本次获得的任意张牌交给一名其他角色,然后摸一张牌", + filterTarget: lib.filter.notMe, + filterCard: (card) => _status.event.cards.includes(card), + cards: cards, + selectCard: [1, cards.length], + ai1: function (card) { + if (ui.selected.cards.length) return 0; + return 3 / (Math.abs(get.value(card)) + 0.1); + }, + ai2: function (target) { + return ( + get.value(ui.selected.cards, target) * + get.attitude(_status.event.player, target) + ); + }, + }) + .set("cards", cards); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcliying", target); + player.give(result.cards, target); player.draw(); //if(player!=_status.currentPhase) event.finish(); - } - else{ + } else { player.storage.counttrigger.dcliying--; event.finish(); - }/* + } /* 'step 2' var cards=player.getExpansions('dcwangyuan'); var card=get.cardPile2(cardx=>{ @@ -5693,4148 +8029,5079 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return (type=='basic'||type=='trick')&&!cards.some(cardxx=>get.name(cardx,false)==get.name(cardxx,false)); }); if(card) player.addToExpansion(card,'gain2').gaintag.add('dcwangyuan');*/ - } + }, }, //谢灵毓 - dcyuandi:{ - audio:2, - init:()=>{ - game.addGlobalSkill('dcyuandi_ai'); + dcyuandi: { + audio: 2, + init: () => { + game.addGlobalSkill("dcyuandi_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('dcyuandi'),true)) game.removeGlobalSkill('dcyuandi_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("dcyuandi"), true)) + game.removeGlobalSkill("dcyuandi_ai"); }, - trigger:{global:'useCard'}, - filter:function(event,player){ - var evt=event.getParent('phaseUse'); - if(!evt||evt.player!=event.player) return false; - if(event.player==player||!event.targets||event.targets.length>1||event.targets[0]!=event.player) return false; - return event.player.getHistory('useCard',evtx=>{ - return evtx.getParent('phaseUse')==evt; - }).indexOf(event)==0; + trigger: { global: "useCard" }, + filter: function (event, player) { + var evt = event.getParent("phaseUse"); + if (!evt || evt.player != event.player) return false; + if ( + event.player == player || + !event.targets || + event.targets.length > 1 || + event.targets[0] != event.player + ) + return false; + return ( + event.player + .getHistory("useCard", (evtx) => { + return evtx.getParent("phaseUse") == evt; + }) + .indexOf(event) == 0 + ); }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.player; - var name=get.translation(target); - var choices=['选项二']; - var choiceList=['弃置'+name+'一张手牌','你与'+name+'各摸一张牌']; - if(target.countDiscardableCards(player,'h')) choices.unshift('选项一'); - else choiceList[0]=''+choiceList[0]+''; - player.chooseControl(choices,'cancel2').set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('prompt',get.prompt('dcyuandi',trigger.player)).set('choice',function(){ - if(get.attitude(player,target)<0){ - if(choices.includes('选项一')) return '选项一'; - return 'cancel2'; - } - return '选项二'; - }()); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.player; - 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]); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + var name = get.translation(target); + var choices = ["选项二"]; + var choiceList = ["弃置" + name + "一张手牌", "你与" + name + "各摸一张牌"]; + if (target.countDiscardableCards(player, "h")) choices.unshift("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + player + .chooseControl(choices, "cancel2") + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set("prompt", get.prompt("dcyuandi", trigger.player)) + .set( + "choice", + (function () { + if (get.attitude(player, target) < 0) { + if (choices.includes("选项一")) return "选项一"; + return "cancel2"; + } + return "选项二"; + })() + ); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.player; + 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]); } }, - subSkill:{ - ai:{ - mod:{ - aiOrder:function(player,card,num){ - var info=get.info(card); - if(!info||!info.toself) return; - var evt=_status.event.getParent('phaseUse'); - if(!evt||evt.player!=player) return; - if(player.hasHistory('useCard',evtx=>evtx.getParent('phaseUse')==evt)) return; - if(game.hasPlayer(current=>{ - return current.hasSkill('dcyuandi')&&get.attitude(player,current)>=0; - })) return num+10; - return num/3; + subSkill: { + ai: { + mod: { + aiOrder: function (player, card, num) { + var info = get.info(card); + if (!info || !info.toself) return; + var evt = _status.event.getParent("phaseUse"); + if (!evt || evt.player != player) return; + if (player.hasHistory("useCard", (evtx) => evtx.getParent("phaseUse") == evt)) + return; + if ( + game.hasPlayer((current) => { + return ( + current.hasSkill("dcyuandi") && get.attitude(player, current) >= 0 + ); + }) + ) + return num + 10; + return num / 3; }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('dcyuandi'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("dcyuandi"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("dcyuandi_ai"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('dcyuandi_ai'); - } }, - } - }, - dcxinyou:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h'){ - return evt.getParent(2)==event&&evt.cards.length>=3; - })) check|=1; - if(game.getGlobalHistory('changeHp',evt=>{ - return evt.getParent().name=='recover'&&evt.getParent(2)==event; - }).length) check|=2; - if(check>0){ - player.addTempSkill('dcxinyou_effect'); - player.storage.dcxinyou_effect=check; + "step 1"; + var check = 0; + if ( + player.hasHistory("gain", (evt) => { + return evt.getParent(2) == event && evt.cards.length >= 3; + }) + ) + check |= 1; + if ( + game.getGlobalHistory("changeHp", (evt) => { + return evt.getParent().name == "recover" && evt.getParent(2) == event; + }).length + ) + check |= 2; + if (check > 0) { + player.addTempSkill("dcxinyou_effect"); + player.storage.dcxinyou_effect = check; } }, - ai:{ - order:1, - result:{player:1} + ai: { + order: 1, + result: { player: 1 }, }, - subSkill:{ - effect:{ - audio:'dcxinyou', - trigger:{player:'phaseJieshuBegin'}, - charlotte:true, - forced:true, - onremove:true, - filter:function(event,player){ + subSkill: { + effect: { + audio: "dcxinyou", + trigger: { player: "phaseJieshuBegin" }, + charlotte: true, + forced: true, + onremove: true, + filter: function (event, player) { return player.storage.dcxinyou_effect; }, - content:function(){ - if((player.storage.dcxinyou_effect&1)>0) player.loseHp(); - if((player.storage.dcxinyou_effect&2)>0) player.chooseToDiscard('心幽:请弃置一张牌',1,true,'he'); - } - } - } + content: function () { + if ((player.storage.dcxinyou_effect & 1) > 0) player.loseHp(); + if ((player.storage.dcxinyou_effect & 2) > 0) + player.chooseToDiscard("心幽:请弃置一张牌", 1, true, "he"); + }, + }, + }, }, //笮融 - dccansi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ - 'step 0' + dccansi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { + "step 0"; player.recover(); - if(!game.hasPlayer(current=>current!=player)) event.finish(); - else player.chooseTarget('残肆:选择一名其他角色',true,lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - var list=['recover','sha','juedou','huogong']; - return list.reduce((p,c)=>{ - return p+get.effect(target,{name:c},player,player); - },0); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'fire'); + if (!game.hasPlayer((current) => current != player)) event.finish(); + else + player + .chooseTarget("残肆:选择一名其他角色", true, lib.filter.notMe) + .set("ai", (target) => { + var player = _status.event.player; + var list = ["recover", "sha", "juedou", "huogong"]; + return list.reduce((p, c) => { + return p + get.effect(target, { name: c }, player, player); + }, 0); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "fire"); target.recover(); - event.list=['sha','juedou','huogong']; - player.addTempSkill('dccansi_draw'); - player.storage.dccansi_draw=target; - } - else event.finish(); - 'step 2' - var card={name:event.list.shift(),isCard:true}; - if(target.isIn()&&player.canUse(card,target,false)) player.useCard(card,target,false); - if(event.list.length) event.redo(); - 'step 3' - player.removeSkill('dccansi_draw'); + event.list = ["sha", "juedou", "huogong"]; + player.addTempSkill("dccansi_draw"); + player.storage.dccansi_draw = target; + } else event.finish(); + "step 2"; + var card = { name: event.list.shift(), isCard: true }; + if (target.isIn() && player.canUse(card, target, false)) + player.useCard(card, target, false); + if (event.list.length) event.redo(); + "step 3"; + player.removeSkill("dccansi_draw"); }, - subSkill:{ - draw:{ - trigger:{global:'damageEnd'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.getParent(3).name=='dccansi'&&player.storage.dccansi_draw==event.player; + subSkill: { + draw: { + trigger: { global: "damageEnd" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + event.getParent(3).name == "dccansi" && + player.storage.dccansi_draw == event.player + ); }, - content:function(){ - for(var i=0;i7; + dcfozong: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return player.countCards("h") > 7; }, - forced:true, - direct:true, - intro:{ - markcount:'expansion', - content:'expansion', + forced: true, + direct: true, + intro: { + markcount: "expansion", + content: "expansion", }, - content:function(){ - 'step 0' - var num=player.countCards('h')-7; - player.chooseCard('佛宗:将'+get.cnNumber(num)+'张手牌置于武将上',true,num); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.logSkill('dcfozong'); - player.addToExpansion(cards,player,'give').gaintag.add('dcfozong'); + content: function () { + "step 0"; + var num = player.countCards("h") - 7; + player.chooseCard("佛宗:将" + get.cnNumber(num) + "张手牌置于武将上", true, num); + "step 1"; + if (result.bool) { + var cards = result.cards; + player.logSkill("dcfozong"); + player.addToExpansion(cards, player, "give").gaintag.add("dcfozong"); } - 'step 2' - var cards=player.getExpansions('dcfozong'); - if(cards.length<7) event.finish(); - else{ - event.targets=game.filterPlayer(i=>i!=player).sortBySeat(player); + "step 2"; + var cards = player.getExpansions("dcfozong"); + if (cards.length < 7) event.finish(); + else { + event.targets = game.filterPlayer((i) => i != player).sortBySeat(player); game.delayx(); } - 'step 3' - var target=targets.shift(); - event.target=target; + "step 3"; + var target = targets.shift(); + event.target = target; player.line(target); - var cards=player.getExpansions('dcfozong'); - if(!cards.length) event._result={bool:false}; - else target.chooseButton(['###佛宗###
              获得一张牌并令'+get.translation(player)+'回复1点体力,或点击“取消”令其失去1点体力
              ',cards]).set('ai',button=>{ - if(_status.event.refuse) return get.value(button.link)-7.5; - return get.value(button.link); - }).set('refuse',get.attitude(target,player)<1&&get.effect(player,{name:'losehp'},player,target)>0); - 'step 4' - if(result.bool){ - var card=result.links[0]; - target.gain(card,'give',player); + var cards = player.getExpansions("dcfozong"); + if (!cards.length) event._result = { bool: false }; + else + target + .chooseButton([ + '###佛宗###
              获得一张牌并令' + + get.translation(player) + + "回复1点体力,或点击“取消”令其失去1点体力
              ", + cards, + ]) + .set("ai", (button) => { + if (_status.event.refuse) return get.value(button.link) - 7.5; + return get.value(button.link); + }) + .set( + "refuse", + get.attitude(target, player) < 1 && + get.effect(player, { name: "losehp" }, player, target) > 0 + ); + "step 4"; + if (result.bool) { + var card = result.links[0]; + target.gain(card, "give", player); player.recover(target); - } - else player.loseHp(); - 'step 5' - if(targets.length) event.goto(3); + } else player.loseHp(); + "step 5"; + if (targets.length) event.goto(3); }, - ai:{halfneg:true} + ai: { halfneg: true }, }, //滕芳兰 - dcluochong:{ - audio:2, - trigger:{global:'roundStart'}, - filter:function(event,player){ - return game.hasPlayer(current=>current.countDiscardableCards(player,'hej')>0); + dcluochong: { + audio: 2, + trigger: { global: "roundStart" }, + filter: function (event, player) { + return game.hasPlayer((current) => current.countDiscardableCards(player, "hej") > 0); }, - direct:true, - async content(event,trigger,player){ - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); + direct: true, + async content(event, trigger, player) { + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); const lose_list = []; - let num = 4 - player.countMark('dcluochong'); - while (num>0) { - const result = await player.chooseTarget( - get.prompt('dcluochong'), - `弃置任意名角色区域内的累计至多${num}张牌`, - (card,player,target)=>{ - return target.hasCard(card => { - const discarded = _status.event.lose_list.find(item => item[0] == target); - if (discarded && discarded[1].includes(card)) return false; - return lib.filter.canBeDiscarded(card,player,target,'dcluochong'); - }, 'hej') - } - ).set('ai',target=>{ - const player = _status.event.player, discarded = _status.event.lose_list.find(item => item[0] == target); - if(discarded){ - if (target == player) return 0; - const num = discarded[1].length; - if (num > 1 && player.hp + player.hujia > 2) return 0; - } - if (target == player){ - if(ui.cardPile.childNodes.length > 80 && player.hasCard(card => get.value(card) < 8)) return 20; - return 0; - } - return get.effect(target, {name:'guohe_copy2'}, player, player); - }).set('lose_list',lose_list).forResult(); + let num = 4 - player.countMark("dcluochong"); + while (num > 0) { + const result = await player + .chooseTarget( + get.prompt("dcluochong"), + `弃置任意名角色区域内的累计至多${num}张牌`, + (card, player, target) => { + return target.hasCard((card) => { + const discarded = _status.event.lose_list.find( + (item) => item[0] == target + ); + if (discarded && discarded[1].includes(card)) return false; + return lib.filter.canBeDiscarded(card, player, target, "dcluochong"); + }, "hej"); + } + ) + .set("ai", (target) => { + const player = _status.event.player, + discarded = _status.event.lose_list.find((item) => item[0] == target); + if (discarded) { + if (target == player) return 0; + const num = discarded[1].length; + if (num > 1 && player.hp + player.hujia > 2) return 0; + } + if (target == player) { + if ( + ui.cardPile.childNodes.length > 80 && + player.hasCard((card) => get.value(card) < 8) + ) + return 20; + return 0; + } + return get.effect(target, { name: "guohe_copy2" }, player, player); + }) + .set("lose_list", lose_list) + .forResult(); if (result.bool) { const target = result.targets[0]; - const cards = await player.choosePlayerCard(target, true, 'hej', [1,num], `选择弃置${get.translation(target)}区域内的牌`).set('filterButton',(button) => { - const card = button.link, target = _status.event.target, player = get.player(); - const discarded = _status.event.lose_list.find(item => item[0] == target); - if (discarded && discarded[1].includes(card)) return false; - return lib.filter.canBeDiscarded(card, player, target,'dcluochong'); - }).set('lose_list',lose_list).set('ai', button => { - if (ui.selected.buttons.length>0) return false; - var val = get.buttonValue(button); - if (get.attitude(_status.event.player, _status.event.target) > 0) return -val; - return val; - }).forResultCards(); + const cards = await player + .choosePlayerCard( + target, + true, + "hej", + [1, num], + `选择弃置${get.translation(target)}区域内的牌` + ) + .set("filterButton", (button) => { + const card = button.link, + target = _status.event.target, + player = get.player(); + const discarded = _status.event.lose_list.find( + (item) => item[0] == target + ); + if (discarded && discarded[1].includes(card)) return false; + return lib.filter.canBeDiscarded(card, player, target, "dcluochong"); + }) + .set("lose_list", lose_list) + .set("ai", (button) => { + if (ui.selected.buttons.length > 0) return false; + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, _status.event.target) > 0) + return -val; + return val; + }) + .forResultCards(); num -= cards.length; - const index = lose_list.find(item => item[0] == target); + const index = lose_list.find((item) => item[0] == target); if (!index) { lose_list.push([target, cards]); - } - else { + } else { index[1].addArray(cards); } - } - else { + } else { break; } } if (_status.connectMode) { - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - if (lose_list.length>0) { + if (lose_list.length > 0) { lib.tempSortSeat = trigger.player; - lose_list.sort((a,b)=>{ - return lib.sort.seat(a[0],b[0]); + lose_list.sort((a, b) => { + return lib.sort.seat(a[0], b[0]); }); delete lib.tempSortSeat; - player.logSkill('dcluochong',lose_list.map(i => i[0])); - if (lose_list.some(i => i[1].length > 2)) { - game.log(player,'可弃置牌数','#g-1'); - player.addMark('dcluochong',1,false); + player.logSkill( + "dcluochong", + lose_list.map((i) => i[0]) + ); + if (lose_list.some((i) => i[1].length > 2)) { + game.log(player, "可弃置牌数", "#g-1"); + player.addMark("dcluochong", 1, false); } - if (lose_list[0].length==1) { + if (lose_list[0].length == 1) { lose_list[0][0].discard(lose_list[0][1]); - } - else{ + } else { game.loseAsync({ - lose_list:lose_list, - discarder:player, - }).setContent('discardMultiple'); + lose_list: lose_list, + discarder: player, + }).setContent("discardMultiple"); } } }, - ai:{ - threaten:2.5, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='delay'&¤t<0){ - var current=_status.currentPhase; - if(current.getSeatNum()>target.getSeatNum()) return 'zerotarget'; + ai: { + threaten: 2.5, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "delay" && current < 0) { + var current = _status.currentPhase; + if (current.getSeatNum() > target.getSeatNum()) return "zerotarget"; } }, }, }, }, - dcaichen:{ - audio:2, - init:function(player){ - game.addGlobalSkill('dcaichen_hit'); + dcaichen: { + audio: 2, + init: function (player) { + game.addGlobalSkill("dcaichen_hit"); }, - onremove:function(player){ - if(!game.hasPlayer(current=>current.hasSkill('dcaichen'),true)) game.removeGlobalSkill('dcaichen_hit'); + onremove: function (player) { + if (!game.hasPlayer((current) => current.hasSkill("dcaichen"), true)) + game.removeGlobalSkill("dcaichen_hit"); }, - trigger:{ - player:['loseAfter','phaseDiscardBefore'], - global:'loseAsyncAfter', - target:'useCardToTargeted' + trigger: { + player: ["loseAfter", "phaseDiscardBefore"], + global: "loseAsyncAfter", + target: "useCardToTargeted", }, - filter:function(event,player,name){ - if(event.name=='phaseDiscard') return ui.cardPile.childNodes.length>40; - if(name=='useCardToTargeted') return ui.cardPile.childNodes.length<40&&get.suit(event.card)=='spade'; - if(event.getParent().name!='dcluochong') return false; - if(event.name=='loseAsync'&&!event.getl(player).cards.length) return false; - return ui.cardPile.childNodes.length>80; + filter: function (event, player, name) { + if (event.name == "phaseDiscard") return ui.cardPile.childNodes.length > 40; + if (name == "useCardToTargeted") + return ui.cardPile.childNodes.length < 40 && get.suit(event.card) == "spade"; + if (event.getParent().name != "dcluochong") return false; + if (event.name == "loseAsync" && !event.getl(player).cards.length) return false; + return ui.cardPile.childNodes.length > 80; }, - forced:true, - content:function(){ - if(trigger.name.indexOf('lose')==0) player.draw(2); - else if(trigger.name=='phaseDiscard'){ + forced: true, + content: function () { + if (trigger.name.indexOf("lose") == 0) player.draw(2); + else if (trigger.name == "phaseDiscard") { trigger.cancel(); - game.log(player,'跳过了弃牌阶段'); - } - else{ + game.log(player, "跳过了弃牌阶段"); + } else { trigger.directHit.add(player); - game.log(player,'不可响应',trigger.card); + game.log(player, "不可响应", trigger.card); } }, - subSkill:{ - hit:{ - trigger:{player:'dieAfter'}, - filter:function(event,player){ - return !game.hasPlayer(current=>current.hasSkill('dcaichen'),true); + subSkill: { + hit: { + trigger: { player: "dieAfter" }, + filter: function (event, player) { + return !game.hasPlayer((current) => current.hasSkill("dcaichen"), true); }, - silent:true, - forceDie:true, - content:function(){ - game.removeGlobalSkill('dcaichen_hit'); + 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'; - } - } - } - } + 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" + ); + }, + }, + }, + }, }, //杨彪 - dczhaohan:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - filter:function(event,player){ + dczhaohan: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=2; - trigger.dczhaohan=true; - player.addTempSkill('dczhaohan_choose','phaseDrawAfter'); + content: function () { + trigger.num += 2; + trigger.dczhaohan = true; + player.addTempSkill("dczhaohan_choose", "phaseDrawAfter"); }, - subSkill:{ - choose:{ - trigger:{player:'gainAfter'}, - filter:function(event,player){ - return event.getParent(2).dczhaohan&&player.countCards('h')>=2; + subSkill: { + choose: { + trigger: { player: "gainAfter" }, + filter: function (event, player) { + return event.getParent(2).dczhaohan && player.countCards("h") >= 2; }, - forced:true, - charlotte:true, - popup:false, - content:function(){ - 'step 0' - var choices=[],choiceList=[ - '将两张手牌交给一名没有手牌的角色', - '弃置两张手牌' - ]; - if(game.hasPlayer(current=>current.countCards('h')==0)) choices.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - choices.push('选项二'); - if(choices.length==1) event._result={control:'选项二'}; - else player.chooseControl(choices).set('choiceList',choiceList).set('ai',()=>_status.event.choice).set('choice',function(){ - if(game.hasPlayer(current=>{ - return current.countCards('h')==0&&get.attitude(player,current)>0; - })) return '选项一'; - return '选项二'; - }()); - 'step 1' - if(result.control=='选项一'){ + forced: true, + charlotte: true, + popup: false, + content: function () { + "step 0"; + var choices = [], + choiceList = ["将两张手牌交给一名没有手牌的角色", "弃置两张手牌"]; + if (game.hasPlayer((current) => current.countCards("h") == 0)) + choices.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + choices.push("选项二"); + if (choices.length == 1) event._result = { control: "选项二" }; + else + player + .chooseControl(choices) + .set("choiceList", choiceList) + .set("ai", () => _status.event.choice) + .set( + "choice", + (function () { + if ( + game.hasPlayer((current) => { + return ( + current.countCards("h") == 0 && + get.attitude(player, current) > 0 + ); + }) + ) + return "选项一"; + return "选项二"; + })() + ); + "step 1"; + if (result.control == "选项一") { player.chooseCardTarget({ - filterCard:true, - selectCard:2, - forced:true, - filterTarget:function(card,player,target){ - return !target.countCards('h'); + filterCard: true, + selectCard: 2, + forced: true, + filterTarget: function (card, player, target) { + return !target.countCards("h"); }, - ai1:function(card){ - return 7-get.value(card); + ai1: function (card) { + return 7 - get.value(card); }, - ai2:function(target){ - return get.attitude(_status.event.player,target); + ai2: function (target) { + return get.attitude(_status.event.player, target); }, - prompt:'将两张手牌交给一名没有手牌的角色' + prompt: "将两张手牌交给一名没有手牌的角色", }); - } - else{ - player.chooseToDiscard('昭汉:请弃置两张手牌',true,2); + } else { + player.chooseToDiscard("昭汉:请弃置两张手牌", true, 2); event.finish(); } - 'step 2' - if(result.bool){ - player.give(result.cards,result.targets[0]); + "step 2"; + if (result.bool) { + player.give(result.cards, result.targets[0]); } - } - } - } + }, + }, + }, }, - dcjinjie:{ - audio:2, - trigger:{global:'dying'}, - hasPhase:function(player){ - var history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - if(history[i].isMe) return true; - if(history[i].isRound) break; + dcjinjie: { + audio: 2, + trigger: { global: "dying" }, + hasPhase: function (player) { + var history = player.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + if (history[i].isMe) return true; + if (history[i].isRound) break; } return false; }, - direct:true, - content:function(){ - 'step 0' - player.chooseBool(get.prompt('dcjinjie',trigger.player),'令其摸一张牌').set('ai',()=>{ - return get.attitude(_status.event.player,_status.event.getTrigger().player)>0; - }); - 'step 1' - if(result.bool){ - player.logSkill('dcjinjie',trigger.player); - trigger.player.draw(); - } - else event.finish(); - if(lib.skill.dcjinjie.hasPhase(player)) event.finish(); - 'step 2' - var num=0; - var history=player.actionHistory; - for(var i=history.length-1;i>=0;i--){ - for(var evt of history[i].useSkill){ - if(evt.skill=='dcjinjie') num++; - } - if(history[i].isRound) break; - } - if(num==0){ - player.chooseBool(get.prompt('dcjinjie',trigger.player),'令其回复1点体力').set('ai',()=>{ - var player=_status.event.player; - return get.effect(_status.event.getTrigger().player,{name:'tao'},player,player)>0; + direct: true, + content: function () { + "step 0"; + player + .chooseBool(get.prompt("dcjinjie", trigger.player), "令其摸一张牌") + .set("ai", () => { + return get.attitude(_status.event.player, _status.event.getTrigger().player) > 0; }); + "step 1"; + if (result.bool) { + player.logSkill("dcjinjie", trigger.player); + trigger.player.draw(); + } else event.finish(); + if (lib.skill.dcjinjie.hasPhase(player)) event.finish(); + "step 2"; + var num = 0; + var history = player.actionHistory; + for (var i = history.length - 1; i >= 0; i--) { + for (var evt of history[i].useSkill) { + if (evt.skill == "dcjinjie") num++; + } + if (history[i].isRound) break; } - else{ - player.chooseToDiscard(get.prompt('dcjinjie',trigger.player),'弃置'+get.cnNumber(num)+'张牌,令其回复1点体力','he',num).set('ai',card=>{ - if(_status.event.eff>0) return get.value({name:'tao'})-get.value(card); - return 0; - }).set('eff',get.effect(trigger.player,{name:'tao'},player,player)); + if (num == 0) { + player + .chooseBool(get.prompt("dcjinjie", trigger.player), "令其回复1点体力") + .set("ai", () => { + var player = _status.event.player; + return ( + get.effect( + _status.event.getTrigger().player, + { name: "tao" }, + player, + player + ) > 0 + ); + }); + } else { + player + .chooseToDiscard( + get.prompt("dcjinjie", trigger.player), + "弃置" + get.cnNumber(num) + "张牌,令其回复1点体力", + "he", + num + ) + .set("ai", (card) => { + if (_status.event.eff > 0) + return get.value({ name: "tao" }) - get.value(card); + return 0; + }) + .set("eff", get.effect(trigger.player, { name: "tao" }, player, player)); } - 'step 3' - if(result.bool){ - player.line(trigger.player,'green'); + "step 3"; + if (result.bool) { + player.line(trigger.player, "green"); trigger.player.recover(); } }, }, - dcjue:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(current=>(current.getHp()>player.getHp()||current.countCards('h')>player.countCards('h'))&&player.canUse('sha',current,false)); + dcjue: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer( + (current) => + (current.getHp() > player.getHp() || + current.countCards("h") > player.countCards("h")) && + player.canUse("sha", current, false) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('dcjue'),'视为对一名体力值或手牌数大于你的角色使用一张【杀】',(card,player,target)=>{ - return player.canUse('sha',target,false)&&(target.getHp()>player.getHp()||target.countCards('h')>player.countCards('h')); - }).set('ai',target=>{ - return get.effect(target,{name:'sha'},_status.event.player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcjue',target); - player.useCard({name:'sha',isCard:true},target,false); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("dcjue"), + "视为对一名体力值或手牌数大于你的角色使用一张【杀】", + (card, player, target) => { + return ( + player.canUse("sha", target, false) && + (target.getHp() > player.getHp() || + target.countCards("h") > player.countCards("h")) + ); + } + ) + .set("ai", (target) => { + return get.effect(target, { name: "sha" }, _status.event.player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcjue", target); + player.useCard({ name: "sha", isCard: true }, target, false); } }, }, //杨弘 - dcjianji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.getAttackRange()>=1; + dcjianji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.getAttackRange() >= 1; }, - selectTarget:function(){ - return [1,_status.event.player.getAttackRange()]; + selectTarget: function () { + return [1, _status.event.player.getAttackRange()]; }, - complexSelect:true, - complexTarget:true, - filterTarget:function(card,player,target){ - var selected=ui.selected.targets; - if(!selected.length) return true; - for(var i of selected){ - if(i.getNext()==target||i.getPrevious()==target) return true; + complexSelect: true, + complexTarget: true, + filterTarget: function (card, player, target) { + var selected = ui.selected.targets; + if (!selected.length) return true; + for (var i of selected) { + if (i.getNext() == target || i.getPrevious() == target) return true; } return false; }, - contentBefore:function(){ - event.getParent()._dcjianji_discarded=[]; + contentBefore: function () { + event.getParent()._dcjianji_discarded = []; }, - content:function(){ - 'step 0' - if(target.countCards('he')>0) target.chooseToDiscard(true,'he'); + content: function () { + "step 0"; + if (target.countCards("he") > 0) target.chooseToDiscard(true, "he"); else event.finish(); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { event.getParent()._dcjianji_discarded.push(target); } }, - contentAfter:function(){ - 'step 0' - var list=targets.filter(target=>{ - var num=target.countCards('h'); - return targets.every(targetx=>{ - return targetx.countCards('h')<=num; + contentAfter: function () { + "step 0"; + var list = targets.filter((target) => { + var num = target.countCards("h"); + return targets.every((targetx) => { + return targetx.countCards("h") <= num; }); }); - if(list.length){ - event.list=list; - event.current=event.list.shift(); + if (list.length) { + event.list = list; + event.current = event.list.shift(); event.getParent()._dcjianji_discarded.remove(player); - event.targets=event.getParent()._dcjianji_discarded; - } - else event.finish(); - 'step 1' - var targets=event.targets.slice(); + event.targets = event.getParent()._dcjianji_discarded; + } else event.finish(); + "step 1"; + var targets = event.targets.slice(); targets.remove(event.current); - if(!targets.length) event._result={bool:false}; - else event.current.chooseTarget('间计:是否视为对除'+get.translation(player)+'外的弃置过牌的一名角色使用一张杀?',(card,player,target)=>{ - return _status.event.targets.includes(target)&&player.canUse('sha',target,false); - }).set('targets',event.targets).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'sha'},player,player); - }); - 'step 2' - if(result.bool){ - event.current.useCard({name:'sha',isCard:true},result.targets,false); + if (!targets.length) event._result = { bool: false }; + else + event.current + .chooseTarget( + "间计:是否视为对除" + + get.translation(player) + + "外的弃置过牌的一名角色使用一张杀?", + (card, player, target) => { + return ( + _status.event.targets.includes(target) && + player.canUse("sha", target, false) + ); + } + ) + .set("targets", event.targets) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "sha" }, player, player); + }); + "step 2"; + if (result.bool) { + event.current.useCard({ name: "sha", isCard: true }, result.targets, false); } - 'step 3' - if(event.list.length){ - event.current=event.list.shift(); + "step 3"; + if (event.list.length) { + event.current = event.list.shift(); event.goto(1); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - var eff=get.effect(target,{name:'guohe_copy2'},player,target)/2; - if(ui.selected.targets.length&&eff<0){ - var len=target.countCards('h'); - if(ui.selected.targets.every(i=>{ - return i.countCards('h'){ - return get.effect(i,{name:'sha'},target,player)>0; - })) return 0.1; + ai: { + order: 7, + result: { + target: function (player, target) { + var eff = get.effect(target, { name: "guohe_copy2" }, player, target) / 2; + if (ui.selected.targets.length && eff < 0) { + var len = target.countCards("h"); + if ( + ui.selected.targets.every((i) => { + return i.countCards("h") < len + 1; + }) && + ui.selected.targets.some((i) => { + return get.effect(i, { name: "sha" }, target, player) > 0; + }) + ) + return 0.1; } - return ui.selected.targets.reduce((p,c)=>p+get.effect(c,{name:'guohe_copy2'},player,c)/2,0)+eff; - } - } - }, - }, - dcyuanmo:{ - audio:2, - trigger:{player:['damageEnd','phaseZhunbeiBegin']}, - direct:true, - group:'dcyuanmo_add', - init:function(player){player.storage.dcyuanmo_range=0}, - change:function(player,num){ - player.addSkill('dcyuanmo_range'); - if(typeof player.storage.dcyuanmo_range!=='number') player.storage.dcyuanmo_range=0; - if(!num) return; - player.storage.dcyuanmo_range+=num; - if(player.storage.dcyuanmo_range!=0) player.markSkill('dcyuanmo_range'); - else player.unmarkSkill('dcyuanmo_range'); - game.log(player,'的攻击范围',(num>0?'+':'')+num); - }, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(current=>player.inRange(current)); - var choiceList=['攻击范围+1。然后若你攻击范围内的角色数因此增加,你可以获得其中任意名角色的一张牌','攻击范围-1。然后你摸两张牌']; - player.chooseControl('cancel2').set('prompt',get.prompt('dcyuanmo')).set('choiceList',choiceList).set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - if(trigger.name=='phaseZhunbei'&&player.getAttackRange()==1&&!player.hasCard(card=>{ - if(get.subtype(card)!='equip1'&&!player.hasUseTarget(card)) return false; - var num=1; - var info=get.info(card,false); - if(info&&info.distance&&typeof info.distance.attackFrom=='number') num-=info.distance.attackFrom; - return num>1; - },'hs')) return '选项一'; - var targets=event.targets.slice(),targetsx=[]; - var _tmp=player.storage.dcyuanmo_range; - player.storage.dcyuanmo_range++; - try{ - targetsx=game.filterPlayer(current=>player.inRange(current)); - } - catch(e){ - player.storage.dcyuanmo_range=_tmp - } - player.storage.dcyuanmo_range=_tmp; - targetsx.removeArray(targets); - return targetsx.reduce((p,c)=>{ - return p+Math.max(0,get.effect(c,{name:'shunshou_copy2'},player,player)); - },0)>get.effect(player,{name:'draw'},player,player)*1.3?'选项一':'选项二'; - }()); - 'step 1' - if(result.control=='cancel2'){ - event.finish(); return; - } - player.logSkill('dcyuanmo'); - if(result.control=='选项一'){ - lib.skill.dcyuanmo.change(player,1); - var targetsx=game.filterPlayer(current=>player.inRange(current)); - if(targetsx.length<=targets.length){ - event.finish(); - } - else event.targets=targetsx.removeArray(targets); - } - else{ - lib.skill.dcyuanmo.change(player,-1); - player.draw(2); - event.finish(); - } - 'step 2' - player.chooseTarget('远谟:获得任意名本次进入你攻击范围的角色的一张牌',[1,targets.length],(card,player,target)=>{ - return _status.event.getParent().targets.includes(target)&&target.countGainableCards(player,'he')>0; - }).set('ai',target=>{ - var player=_status.event.player; - return get.effect(target,{name:'shunshou_copy2'},player,player); - }); - 'step 3' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets); - for(var target of targets){ - player.gainPlayerCard(target,'he',true); - } - } - }, - subSkill:{ - add:{ - audio:'dcyuanmo', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return !game.hasPlayer(current=>player.inRange(current)); - }, - prompt2:'令你的攻击范围+1', - check:()=>true, - content:function(){ - lib.skill.dcyuanmo.change(player,1); - }, - }, - range:{ - charlotte:true, - intro:{ - content:function(storage,player){ - var num=player.storage.dcyuanmo_range; - return '攻击范围'+(num>=0?'+':'')+num; - } - }, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('dcyuanmo_range'); - }, - }, - } - }, - }, - //薛灵芸 - dcxialei:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['cardsDiscardAfter','loseAsyncAfter','equipAfter'], - }, - filter:function(event,player){ - if(player.countMark('dcxialei_clear')>=3) return false; - if(event.name!='cardsDiscard'){ - return event.getd(player,'cards2').some(i=>get.color(i,player)=='red'); - } - else{ - if(!event.cards.filterInD('d').some(i=>get.color(i,player)=='red')) return false; - var evt=event.getParent(); - if(evt.name!='orderingDiscard') return false; - var evtx=(evt.relatedEvent||evt.getParent()); - if(evtx.player!=player) return false; - return player.hasHistory('lose',evtxx=>{ - return evtx==(evtxx.relatedEvent||evtxx.getParent())&&evtxx.cards2.length>0; - }); - } - }, - content:function(){ - 'step 0' - var cards=get.cards(3-player.countMark('dcxialei_clear')); - event.cards=cards; - game.cardsGotoOrdering(cards); - if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton(['霞泪:获得其中的一张牌',cards],true); - 'step 1' - if(result.bool){ - var card=result.links[0]; - player.gain(card,'gain2'); - event.cards.remove(card); - if(event.cards.length){ - player.chooseBool().set('createDialog',['是否将剩余牌置于牌堆底?',event.cards]).set('ai',()=>_status.event.bool).set('bool',function(){ - if(!player.hasSkill('dcanzhi')) return Math.random()<0.5; - if(player.hasSkill('dcanzhi_blocker')){ - var next=_status.currentPhase.getNext(); - var judges=next.getCards('j'); - var val=0; - if(judges.length&&!next.hasWuxie()){ - var att=get.attitude(player,next); - for(var i=0;;i++){ - var judge=judges[i]&&get.judge(judges[i]),card=event.cards[i]; - if(!judge||!card) break; - val+=judge(card)*att; - i++; - } - } - if(val>0) return false; - else if(val==0) return Math.random()<0.5; - return true; - } - var card=event.cards[0]; - if(get.color(card,player)=='red'&&player.isPhaseUsing()&&player.countCards('hs',card=>{ - return get.color(card)=='red'&&player.hasValueTarget(card)&&['basic','trick'].includes(get.type(card)); - })>0) return false; - if(get.color(card,player)=='black') return false; - return true; - }()); - } - else event.goto(3); - } else event.finish(); - 'step 2' - if(result.bool){ - player.popup('牌堆底'); - game.log(player,'将'+get.cnNumber(event.cards.length)+'张牌置于了牌堆底'); - } - else player.popup('牌堆顶'); - while(cards.length){ - var card=cards.pop(); - card.fix(); - if(result.bool) ui.cardPile.appendChild(card); - else ui.cardPile.insertBefore(card,ui.cardPile.firstChild); - } - game.updateRoundNumber(); - 'step 3' - player.addMark('dcxialei_clear',1,false); - player.addTempSkill('dcxialei_clear'); - }, - subSkill:{clear:{onremove:true}} - }, - dcanzhi:{ - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('dcanzhi_blocker'); - }, - group:'dcanzhi_damage', - content:function(){ - 'step 0' - player.judge(result=>{ - if(get.color(result)=='red') return _status.event.getParent().player.countMark('dcxialei_clear')/2; - return 2; - }).judge2=result=>result.bool; - 'step 1' - if(result.color=='red'){ - player.removeSkill('dcxialei_clear'); - event.finish(); - } - else if(result.color=='black'){ - player.addTempSkill('dcanzhi_blocker'); - player.chooseTarget('暗织:是否令一名非当前回合角色获得本回合进入弃牌堆的两张牌?',(card,player,target)=>{ - return target!=_status.currentPhase; - }).set('ai',target=>{ - return get.effect(target,{name:'wuzhong'},_status.event.player); - }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target); - var cards=[]; - game.getGlobalHistory('cardMove',evt=>{ - if(evt.name=='lose'&&evt.position==ui.discardPile||evt.name=='cardsDiscard'){ - cards.addArray(evt.cards.filterInD('d')); - } - }); - 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.value(button.link,target); - }); - } - }else event.finish(); - 'step 3' - if(result.bool){ - target.gain(result.links,'gain2'); - } - }, - ai:{ - combo:'dcxialei', - order:function(item,player){ - if(player.countMark('dcxialei_clear')>=2) return 10; - if(player.hasHistory('useSkill',evt=>evt.skill=='dcxialei')&&get.color(ui.cardPile.firstChild,player)=='red'&&player.countMark('dcxialei_clear')>0) return 9; - return 1; - }, - result:{ - player:function(player){ - return 1; - } - } - }, - subSkill:{ - damage:{ - audio:'dcanzhi', - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return !player.hasSkill('dcanzhi_blocker'); - }, - check:function(event,player){ - return game.hasPlayer(current=>{ - return get.attitude(player,current)>0&¤t!=_status.currentPhase; - }); - }, - prompt2:'你判定,若结果为红色,你重置〖霞泪〗的观看牌数;若结果为黑色,〖暗织〗于本回合失效,然后你可以令一名非当前回合角色获得本回合进入弃牌堆的两张牌。', - content:function(){ - event.setContent(lib.skill.dcanzhi.content); - event.goto(0); - } - }, - blocker:{charlotte:true} - } - }, - //十周年王允 - dclianji:{ - enable:'phaseUse', - audio:'wylianji', - usable:1, - check:function(card){ - return 5-get.value(card); - }, - filterTarget:function(card,player,target){ - return target!=player; - }, - filterCard:true, - content:function(){ - 'step 0' - var card=get.cardPile2(function(card){ - return get.subtype(card)=='equip1'&&targets[0].hasUseTarget(card); - }); - if(card){ - if(card.name=='qinggang'&&!lib.inpile.includes('qibaodao')){ - card.remove(); - card=game.createCard('qibaodao',card.suit,card.number); - } - targets[0].chooseUseTarget(card,true,'nopopup','nothrow'); - } - else{ - player.chat('没有装备牌了吗'); - game.log('但是牌堆里已经没有装备牌了!'); - } - 'step 1' - game.updateRoundNumber(); - targets[0].chooseToUse(get.translation(player)+'对你发动了【连计】', - {name:'sha'}).set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target==_status.event.source) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('addCount',false).set('source',player).set('prompt2','对除'+get.translation(player)+'外的一名角色使用一张【杀】,并将装备区内的武器牌交给其中一名目标角色;或点击“取消”,令'+get.translation(player)+'视为对你使用一张【杀】,并获得你装备区内的武器牌'); - 'step 2' - var card=targets[0].getEquips(1); - if(result.bool){ - player.addSkill('dclianji_1'); - if(card.length&&result.targets.filter(target=>target.isIn()).length>0){ - event.card=card; - targets[0].chooseTarget(true,'将'+get.translation(card)+'交给一名目标角色',(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - var card=_status.event.getParent().card[0]; - return (target.hasSkillTag('nogain')?0:get.attitude(_status.event.player,target))*Math.max(0.1,target.getUseValue(card)); - }).set('targets',result.targets); - } else event.finish(); - } - else{ - player.addSkill('dclianji_2'); - event.goto(4); - } - 'step 3' - targets[0].give(card,result.targets[0],'give'); - event.finish(); - 'step 4' - player.useCard({name:'sha',isCard:true},targets[0],false); - 'step 5' - var card=targets[0].getEquips(1); - if(card.length) targets[0].give(card,player,'give'); - }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(game.countPlayer()==2) return -3; - if(!target.getEquip(1)){ - if(game.hasPlayer(function(current){ - return current!=target&&!current.hasSkillTag('nogain')&&get.attitude(current,target)>0; - })) return 3; - return -3; - } - if(!game.hasPlayer(function(current){ - return current!=target&&!current.hasSkillTag('nogain')&&get.attitude(current,target)>0; - })) return -6; - return 4-get.value(target.getEquip(1)); + return ( + ui.selected.targets.reduce( + (p, c) => p + get.effect(c, { name: "guohe_copy2" }, player, c) / 2, + 0 + ) + eff + ); }, }, }, - subSkill:{ - 1:{charlotte:true,onremove:true}, - 2:{charlotte:true,onremove:true}, - } }, - dcmoucheng:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:'moucheng', - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'gray', - derivation:'xinjingong', - unique:true, - filter:function(event,player){ - return player.hasSkill('dclianji_1')&&player.hasSkill('dclianji_2'); + dcyuanmo: { + audio: 2, + trigger: { player: ["damageEnd", "phaseZhunbeiBegin"] }, + direct: true, + group: "dcyuanmo_add", + init: function (player) { + player.storage.dcyuanmo_range = 0; }, - content:function(){ - player.awakenSkill('dcmoucheng'); - player.changeSkills(['xinjingong'],['dclianji']); + change: function (player, num) { + player.addSkill("dcyuanmo_range"); + if (typeof player.storage.dcyuanmo_range !== "number") player.storage.dcyuanmo_range = 0; + if (!num) return; + player.storage.dcyuanmo_range += num; + if (player.storage.dcyuanmo_range != 0) player.markSkill("dcyuanmo_range"); + else player.unmarkSkill("dcyuanmo_range"); + game.log(player, "的攻击范围", (num > 0 ? "+" : "") + num); }, - }, - //周宣 - dcwumei:{ - audio:2, - trigger:{player:'phaseBeginStart'}, - filter:function(event,player){ - return !player.hasSkill('dcwumei_used'); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('dcwumei')).set('ai',target=>{ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcwumei',target); - player.addTempSkill('dcwumei_used','roundStart'); - target.insertPhase(); - target.addTempSkill('dcwumei_wake','phaseAfter'); - var targets=game.filterPlayer(); - if(!target.storage.dcwumei_wake) target.storage.dcwumei_wake=[[],[]]; - for(var targetx of targets){ - target.storage.dcwumei_wake[0].push(targetx); - target.storage.dcwumei_wake[1].push(targetx.hp); - } - target.markSkill('dcwumei_wake'); - if(!trigger._finished){ - trigger.finish(); - trigger.untrigger(true); - trigger._triggered=5; - game.players.slice().concat(game.dead).forEach(current=>{ - current.getHistory().isSkipped=true; - current.getStat().isSkipped=true; - }); - 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, - filter:function(event,player){ - return player.storage.dcwumei_wake&&player.storage.dcwumei_wake.length; - }, - content:function(){ - var storage=player.storage.dcwumei_wake; - for(var i=0;i'; - str+='
            • '+str2; - } - return str; - } - } - }, - all:{ - trigger:{player:'dieAfter'}, - filter:function(event,player){ - return !game.hasPlayer(current=>current.hasSkill('dcwumei_wake'),true); - }, - 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; - } - } - } - } - } - }, - dczhanmeng:{ - audio:2, - trigger:{player:'useCard'}, - filter(event,player){ - return !player.hasSkill('dczhanmeng_choice1')||!player.hasSkill('dczhanmeng_choice2')|| - !player.hasSkill('dczhanmeng_choice0')&&!game.hasPlayer2(current=>{ - const history=current.actionHistory; - if(history.length<2) return false; - for(let i=history.length-2;i>=0;i--){ - if(history[i].isSkipped) continue; - const list=history[i].useCard.map(evt=>evt.card.name); - return list.includes(event.card.name); - } - return false; - },true); - }, - direct:true, - content(){ - 'step 0' - var list=[]; - var choiceList=[ - '上回合若没有同名牌被使用过,你获得一张非伤害牌', - '下回合当同名牌首次被使用后,你获得一张伤害牌', - '令一名其他角色弃置两张牌,若点数之和大于10,你对其造成1点火焰伤害' + content: function () { + "step 0"; + event.targets = game.filterPlayer((current) => player.inRange(current)); + var choiceList = [ + "攻击范围+1。然后若你攻击范围内的角色数因此增加,你可以获得其中任意名角色的一张牌", + "攻击范围-1。然后你摸两张牌", ]; - var used=game.hasPlayer2(current=>{ - var history=current.actionHistory; - if(history.length<2) return false; - for(let i=history.length-2;i>=0;i--){ - if(history[i].isSkipped) continue; - const list=history[i].useCard.map(evt=>evt.card.name); - return list.includes(trigger.card.name); - } - return false; - },true); - if(!player.hasSkill('dczhanmeng_choice0')&&!used) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+(used?'(同名牌被使用过)':'(已选择)')+''; - if(!player.hasSkill('dczhanmeng_choice1')) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+'(已选择)'; - var other=game.hasPlayer(current=>current!=player); - if(!player.hasSkill('dczhanmeng_choice2')&&other) list.push('选项三'); - else choiceList[2]=''+choiceList[2]+(!other?'(没人啦)':'(已选择)')+''; - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('dczhanmeng')).set('ai',()=>{ - var choices=_status.event.controls.slice().remove('cancel2'); - var player=_status.event.player,evt=_status.event.getTrigger(); - if(!game.hasPlayer(current=>get.attitude(player,current)<0)) choices.remove('选项三'); - else if(choices.includes('选项三')) return '选项三'; - if(choices.includes('选项二')){ - if(evt.card.name=='sha') return '选项二'; - if(get.type(evt.card,null,false)=='equip') choices.remove('选项二'); - } - if(!choices.length) return 'cancel2'; - return choices.randomGet(); - }).set('choiceList',choiceList); - 'step 1' - if(result.control=='cancel2'){event.finish();return;} - if(result.control=='选项一'){ - player.logSkill('dczhanmeng'); - game.log(player,'选择了','#y'+result.control); - player.addTempSkill('dczhanmeng_choice0'); - var card=get.cardPile2(card=>{ - return !get.tag(card,'damage'); - }); - if(card) player.gain(card,'gain2'); - event.finish(); - } - else if(result.control=='选项二'){ - player.logSkill('dczhanmeng'); - game.log(player,'选择了','#y'+result.control); - player.addTempSkill('dczhanmeng_choice1'); - trigger['dczhanmeng_'+player.playerid]=true; - player.addSkill('dczhanmeng_delay'); - event.finish(); - } - else{ - player.addTempSkill('dczhanmeng_choice2'); - player.chooseTarget('占梦:令一名其他角色弃置两张牌',lib.filter.notMe,true).set('ai',target=>{ - var player=_status.event.player; - var eff1=get.effect(target,{name:'guohe_copy2'},player,player)+0.1; - var eff2=get.damageEffect(target,player,player,'fire')+0.1; - if(eff1<0&&eff2<0) return -eff1*eff2; - return eff1*eff2; - }); - } - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('dczhanmeng',target); - game.log(player,'选择了','#y选项三'); - target.chooseToDiscard(2,'he',true); - } else event.finish(); - 'step 3' - if(result.bool){ - var cards=result.cards; - var num=0; - for(var card of cards){ - num+=get.number(card,false); - } - if(num>10){ - player.line(target,'fire'); - target.damage('fire'); - } - } - }, - ai:{threaten:8}, - subSkill:{ - delay:{ - trigger:{global:['useCardAfter','phaseBeginStart']}, - charlotte:true, - forced:true, - popup:false, - silent:true, - filter(event,player,name){ - var history=player.actionHistory; - if(history.length<2) return false; - var list=history[history.length-2].useCard; - if(name=='phaseBeginStart'){ - return !list.some(evt=>evt['dczhanmeng_'+player.playerid]); - } - for(var evt of list){ - if(evt['dczhanmeng_'+player.playerid]&&event.card.name==evt.card.name&&game.getGlobalHistory('useCard',evtx=>{ - return evtx.card.name==event.card.name; - }).indexOf(event)==0) return true; - } - return false; - }, - content(){ - if(event.triggername!='phaseBeginStart'){ - player.logSkill('dczhanmeng_delay'); - var card=get.cardPile2(card=>{ - return get.tag(card,'damage'); - }); - if(card) player.gain(card,'gain2'); - } - else player.removeSkill('dczhanmeng_delay'); - } - }, - choice0:{charlotte:true}, - choice1:{charlotte:true}, - choice2:{charlotte:true}, - } - }, - //程秉 - dcjingzao:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - if(3+player.countMark('dcjingzao_add')-player.countMark('dcjingzao_ban')<=0) return false; - return game.hasPlayer(current=>lib.skill.dcjingzao.filterTarget(null,player,current)); - }, - filterTarget:function(card,player,target){ - return player!=target&&!target.hasSkill('dcjingzao_temp'); - }, - content:function(){ - 'step 0' - target.addTempSkill('dcjingzao_temp'); - var cards=game.cardsGotoOrdering(get.cards(3+player.countMark('dcjingzao_add')-player.countMark('dcjingzao_ban'))).cards; - event.cards=cards; - game.log(player,'亮出了',event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,target,id,cards){ - var str=get.translation(player)+'对'+(target==game.me?'你':get.translation(target))+'发动了【经造】'; - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,target,event.videoId,event.cards); - game.addVideo('showCards',player,[get.translation(player)+'发动了【经造】',get.cardsInfo(event.cards)]); - game.delay(cards.length-1); - 'step 1' - target.chooseToDiscard('he').set('prompt',false).set('filterCard',card=>{ - var names=_status.event.getParent().cards.map(i=>i.name); - return names.includes(get.name(card)); - }).set('ai',card=>{ - var target=_status.event.player,player=_status.event.getParent().player; - var att=get.attitude(target,player),val=get.value(card); - if(!lib.skill.dcjingzao.filter(null,player)){ - if(att>0) return 0; - return 6-val; - } - else{ - if(att>0) return 4-val; - return 0; - } - }); - var update=function(id,source){ - var dialog=get.idDialog(id); - if(dialog){ - var div=ui.create.div('',dialog.content,1); - var name=get.translation(source); - div.innerHTML='弃置一张满足条件的牌,然后'+name+'〖经造〗本回合亮出牌数+1;或点“取消”令'+name+'随机获得每种牌名的牌各一张,且〖经造〗本回合失效'; - ui.update(); - } - }; - if(target==game.me) update(event.videoId,player); - else if(target.isOnline()) target.send(update,event.videoId,player); - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - if(result.bool){ - player.addTempSkill('dcjingzao_add'); - player.addMark('dcjingzao_add',1,false); - } - else{ - var cards=cards.randomSort(),cards2=[]; - for(var card of cards){ - if(!cards2.map(i=>i.name).includes(card.name)) cards2.push(card); - } - if(cards2.length) player.gain(cards2,'gain2'); - player.addTempSkill('dcjingzao_ban'); - player.addMark('dcjingzao_ban',cards2.length,false); - } - }, - ai:{ - order:7, - result:{ - player:1, - } - }, - subSkill:{ - add:{charlotte:true,onremove:true}, - ban:{charlotte:true,onremove:true}, - temp:{charlotte:true} - } - }, - dcenyu:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return event.player!=player&&game.hasPlayer2(current=>{ - return current.hasHistory('useCard',evt=>{ - return evt.card.name==event.card.name&&evt!=event.getParent()&&evt.targets&&evt.targets.includes(player); - }); - })&&(event.card.name=='sha'||get.type(event.card)=='trick'); - }, - content:function(){ - trigger.getParent().excluded.add(player); - }, - ai:{ - effect:{ - target:(card,player,target)=>{ - if(player===target) return; - if(game.hasPlayer2(current=>{ - return current.hasHistory('useCard',evt=>evt.card.name==card.name&&evt.targets&&evt.targets.includes(target)); - })&&(card.name=='sha'||get.type(card)=='trick')) return 'zeroplayertarget'; - } - } - } - }, - //董贵人 - dclianzhi:{ - audio:2, - trigger:{player:'dying'}, - usable:1, - forced:true, - locked:false, - derivation:'dcshouze', - group:['dclianzhi_connect','dclianzhi_reproach'], - filter:function(event,player){ - return player.getStorage('dclianzhi').filter(i=>i&&i.isIn()).length; - }, - content:function(){ - player.recover(); - game.asyncDraw([player].concat(player.getStorage('dclianzhi').filter(i=>i&&i.isIn())).sortBySeat()); - }, - ai:{ - threaten:0.6, - }, - subSkill:{ - connect:{ - audio:'dclianzhi', - trigger:{ - player:'enterGame', - global:'phaseBefore', - }, - forced:true, - direct:true, - filter:function(event,player){ - return game.hasPlayer(current=>current!=player)&&(event.name!='phase'||game.phaseNumber==0); - }, - content:function(){ - 'step 0' - player.chooseTarget('连枝:请选择一名其他角色',lib.translate.dclianzhi_info,true,(card,player,target)=>{ - return target!=player&&!player.getStorage('dclianzhi').includes(target); - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(att>0) return att+1; - if(att==0) return Math.random(); - return att; - }).set('animate',false); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dclianzhi'); - player.markAuto('dclianzhi',[target]); - } - }, - }, - reproach:{ - audio:'dclianzhi', - trigger:{global:'dieAfter'}, - filter:function(event,player){ - return player.getStorage('dclianzhi').includes(event.player); - }, - direct:true, - content:function(){ - 'step 0' - var num=Math.max(1,player.countMark('dclingfang')); - player.chooseTarget(get.prompt('dclianzhi'),'选择一名其他角色,你与其各获得〖受责〗,且其获得'+num+'枚“绞”标记',(card,player,target)=>{ - return target!=player; - }).set('ai',target=>-get.attitude(_status.event.player,target)); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dclianzhi_reproach',target); - player.addSkills('dcshouze'); - target.addSkills('dcshouze'); - target.addMark('dclingfang',Math.max(1,player.countMark('dclingfang'))); - } - }, - } - } - }, - dclingfang:{ - audio:2, - trigger:{ - player:'phaseZhunbeiBegin', - global:'useCardAfter', - }, - forced:true, - filter:function(event,player){ - if(event.name!='useCard') return true; - if(get.color(event.card)!='black') return false; - if(event.player==player) return !event.targets||!event.targets.includes(player); - return event.targets&&event.targets.includes(player); - }, - content:function(){ - player.addMark('dclingfang',1); - }, - marktext:'绞', - intro:{ - name:'绞', - name2:'绞', - content:'mark' - } - }, - dcfengying:{ - audio:2, - enable:'chooseToUse', - group:'dcfengying_record', - locked:false, - filter:function(event,player){ - var mark=player.countMark('dclingfang'); - if(mark<=0||!player.hasCard(card=>get.number(card)<=mark,'hs')) return false; - var storage=player.getStorage('dcfengying'); - if(!storage.length) return false; - var storage2=player.getStorage('dcfengying_used') - return storage.some(name=>{ - return !storage2.includes(name)&&event.filterCard(get.autoViewAs({name},'unsure'),player,event); - }); - }, - hiddenCard:function(player,name){ - var list=player.getStorage('dcfengying'); - if(player.getStorage('dcfengying_used').includes(name)) return false; - return list.includes(name)&&player.hasCard((card)=>(get.number(card)<=player.countMark('dclingfang')),'hs'); - }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of player.storage.dcfengying){ - if(get.type(name)=='basic') list.push(['基本','',name]); - if(get.type(name)=='trick') list.push(['锦囊','',name]); - } - return ui.create.dialog('风影',[list,'vcard']); - }, - filter:function(button,player){ - var card={name:button.link[2],storage:{dcfengying:true}}; - if(player.getStorage('dcfengying_used').includes(card.name)) return false; - return _status.event.getParent().filterCard(get.autoViewAs(card,'unsure'),player,_status.event.getParent()); - }, - check:function(button){ - var player=_status.event.player; - if(player.countCards('hs',button.link[2])>0) return 0; - if(button.link[2]=='wugu') return; - var effect=player.getUseValue(button.link[2]); - if(effect>0) return effect; - return 0; - }, - backup:function(links,player){ - return { - filterCard:function(card,player,event){ - return get.number(card)<=player.countMark('dclingfang'); - }, - audio:'dcfengying', - selectCard:1, - popname:true, - check:function(card){ - return 6-get.value(card)+get.number(card)/15; - }, - position:'hs', - viewAs:{ - name:links[0][2], - storage:{dcfengying:true}, - }, - precontent:function(){ - player.logSkill('dcfengying'); - player.addTempSkill('dcfengying_used'); - player.markAuto('dcfengying_used',[event.result.card.name]); - event.getParent().addCount=false; - delete event.result.skill; - } - } - }, - prompt:function(links,player){ - return '将一张点数不大于'+get.strNumber(player.countMark('dclingfang'))+'的手牌当做'+get.translation(links[0][2])+'使用(无距离和次数限制)'; - } - }, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.dcfengying) return true; - }, - cardUsable:function(card,player){ - if(card.storage&&card.storage.dcfengying) return Infinity; - }, - }, - ai:{ - order:4, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); - return 1; - } - }, - threaten:2, - }, - subSkill:{ - record:{ - trigger:{global:'phaseBegin'}, - filter:function(event,player){ - return ui.discardPile.childNodes.length>0; - }, - forced:true, - popup:false, - content:function(){ - player.storage.dcfengying=[]; - for(var i=0;i{ - return lib.inpile.indexOf(a)-lib.inpile.indexOf(b); - }); - } - }, - used:{ - charlotte:true, - onremove:true, - intro:{ - content:'已使用过$', - }, - }, - } - }, - dcshouze:{ - audio:true, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('dclingfang')>0; - }, - content:function(){ - 'step 0' - player.removeMark('dclingfang',1); - 'step 1' - var card=get.discardPile(card=>get.color(card,false)=='black'); - if(card) player.gain(card,'gain2'); - player.loseHp(); - } - }, - //袁姬 - dcmengchi:{ - audio:'dcfangdu', - trigger:{player:['linkBefore','damageEnd']}, - forced:true, - filter:function(event,player){ - var num=player.getStat('gain'); - if(num&&num>0) return false; - if(event.name=='link') return !player.isLinked(); - return event.hasNature(); - }, - content:function(){ - if(trigger.name=='link') trigger.cancel(); - else player.recover(); - }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.itemtype(player)!='player'||player._dcmengchi_aiChecking||target.getStat('gain')) return; - if(card.name=='tiesuo'&&!target.isLinked()) return 0; - if(player.hasSkillTag('jueqing',false,target)) return; - if(!get.tag(card,'damage')||get.tag(card,'natureDamage')) return; - if(target.hp<=1) return 0.75; - if(!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })&&player.hasSkillTag('damageBonus',false,{ - target:target, - card:card - })){ - if(target.hp>2) return 0.5; - return 0.75; - } - if(get.attitude(player,target)>0) return [0,0]; - var sha=player.getCardUsable({name:'sha'}); - player._dcmengchi_aiChecking=true; - var num=player.countCards('h',function(card){ - if(get.name(card)=='sha'){ - if(sha==0) return false; - else sha--; + player + .chooseControl("cancel2") + .set("prompt", get.prompt("dcyuanmo")) + .set("choiceList", choiceList) + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if ( + trigger.name == "phaseZhunbei" && + player.getAttackRange() == 1 && + !player.hasCard((card) => { + if (get.subtype(card) != "equip1" && !player.hasUseTarget(card)) + return false; + var num = 1; + var info = get.info(card, false); + if ( + info && + info.distance && + typeof info.distance.attackFrom == "number" + ) + num -= info.distance.attackFrom; + return num > 1; + }, "hs") + ) + return "选项一"; + var targets = event.targets.slice(), + targetsx = []; + var _tmp = player.storage.dcyuanmo_range; + player.storage.dcyuanmo_range++; + try { + targetsx = game.filterPlayer((current) => player.inRange(current)); + } catch (e) { + player.storage.dcyuanmo_range = _tmp; } - return player.canUse(card,target)&&get.effect(target,card,player,player)>0; - }); - delete player._dcmengchi_aiChecking; - if(player.hasSkillTag('damage')) num++; - if(num<2) return [0,0]; - }, - }, - }, - mod:{ - cardEnabled:function(card,player){ - if(!player.getStat('gain')) return false; - }, - cardSavable:function(card,player){ - if(!player.getStat('gain')) return false; - }, - }, - }, - dcfangdu:{ - audio:2, - trigger:{ - player:'damageEnd', - }, - forced:true, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - return !event.hasNature()&&!player.hasHistory('damage',evt=>{ - return !evt.hasNature()&&evt!=event; - },event)||event.hasNature()&&!player.hasHistory('damage',evt=>{ - return evt.hasNature()&&evt!=event; - },event)&&event.source&&event.source.isIn()&&event.source.countGainableCards(player,'h'); - }, - content:function(){ - 'step 0' - if(!trigger.hasNature()){ - player.recover(); - } - else{ - var cards=trigger.source.getGainableCards(player,'h'); - if(cards.length){ - player.gain(cards.randomGet(),trigger.source,'giveAuto','bySelf'); - } - } - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player._dcfangdu_aiChecking||target==_status.currentPhase) return; - if(!get.tag(card,'damage')||player.hasSkillTag('jueqing',false,target)) return; - if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; - if(!get.tag(card,'natureDamage')){ - if(target.hasHistory('damage',evt=>!evt.hasNature())) return 1.5; - else if(target.hp<=1||player.hasSkillTag('damageBonus',false,{ - target:target, - card:card - })&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })) return 0.75; - else{ - if(get.attitude(player,target)>0) return [0,0]; - var sha=player.getCardUsable({name:'sha'}); - player._dcfangdu_aiChecking=true; - var num=player.countCards('h',function(card){ - if(get.name(card)=='sha'){ - if(sha==0) return false; - else sha--; - } - return player.canUse(card,target)&&get.effect(target,card,player,player)>0; - }); - delete player._dcfangdu_aiChecking; - if(player.hasSkillTag('damage')) num++; - if(num<2) return [0,0]; - } - } - if(get.tag(card,'natureDamage')&&!target.hasHistory('damage',evt=>evt.hasNature())&&player.countCards('he')>1) return [1,1,1,-1]; - } - } - } - }, - dcjiexing:{ - audio:2, - trigger:{player:['recoverEnd','damageEnd','loseHpEnd']}, - check:function(event,player){ - var current=_status.currentPhase; - if(!player.hasSkill('dcmengchi')||get.attitude(player,current)>=0) return true; - var num=player.getStat('gain'); - if(num&&num>0) return true; - if(current.countCards('hs',card=>current.canUse(card,player)&&get.effect(player,card,current,player)<0)>=2) return false; - return true; - }, - frequent:'check', - content:function(){ - player.draw().gaintag=['dcjiexing']; - player.addTempSkill('dcjiexing_add'); - }, - subSkill:{ - add:{ - charlotte:true, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('dcjiexing')) return true; - }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('dcjiexing')) return false; - }, - }, - onremove:function(player){ - player.removeGaintag('dcjiexing'); - }, - } - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'recover')) return [1,1]; - if(get.tag(card,'damage')){ - var draw=0.9; - if(target.hasSkill('dcmengchi')&&target.getStat('gain')) draw=1.8; - if(target.hp<=1||card.name=='sha'&&player.hasSkill('jiu')||get.itemtype(player)=='player'&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })&&player.hasSkillTag('damageBonus',false,{ - target:target, - card:card - })){ - if(target.hp>2) return [1,draw]; - return; - } - return [1,draw]; - } - } - } - } - }, - //朱建平 - olddcxiangmian:{ - audio:'dcxiangmian', - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return !player.getStorage('olddcxiangmian').includes(event.player)&&player!=event.player; - }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)<0; - }, - content:function(){ - 'step 0' - player.judge(card=>2/Math.sqrt(get.number(card,false))).set('judge2',result=>result.bool); - 'step 1' - player.markAuto('olddcxiangmian',[trigger.player]); - trigger.player.addSkill('olddcxiangmian_countdown'); - if (!trigger.player.storage['olddcxiangmian_countdown']) trigger.player.storage['olddcxiangmian_countdown'] = []; - [player.playerid, result.suit, result.number].forEach(i => trigger.player.storage['olddcxiangmian_countdown'].push(i)); - trigger.player.markSkill('olddcxiangmian_countdown'); - }, - intro:{content:'已对$发动过技能'}, - ai:{ - expose:0.3, - }, - subSkill:{ - countdown:{ - trigger:{player:'useCardAfter'}, - mark:true, - marktext:'噬', - silent:true, - forced:true, - charlotte:true, - intro:{ - markcount:function(storage){ - if(storage){ - var list=storage.filter((_,i)=>i%3==2); - return Math.min.apply(null,list); - } - }, - content:function(storage,player){ - var str='使用' - for(var i=0;ii%3==1)).includes(get.suit(event.card,player)); - }, - content:function(){ - 'step 0' - var storage=player.getStorage('olddcxiangmian_countdown'); - for(var i=0;i0) player.loseHp(player.hp); - i--; - } - } - }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card!='object') return; - var storage=player.getStorage('olddcxiangmian_countdown'); - for(var i=0;ilib.skill.dcxiangmian.filterTarget(null,player,current)); - }, - filterTarget:function(card,player,target){ - return !player.getStorage('dcxiangmian').includes(target)&&player!=target; - }, - content:function(){ - 'step 0' - target.judge(card=>-2/Math.sqrt(get.number(card,false))).set('judge2',result=>result.bool===false?true:false); - 'step 1' - player.markAuto('dcxiangmian',[target]); - target.addSkill('dcxiangmian_countdown'); - if (!target.storage['dcxiangmian_countdown']) target.storage['dcxiangmian_countdown']=[]; - [player.playerid,result.suit,result.number].forEach(i=>target.storage['dcxiangmian_countdown'].push(i)); - target.markSkill('dcxiangmian_countdown'); - }, - intro:{content:'已对$发动过技能'}, - ai:{ - expose:0.3, - order:10, - result:{target:-5} - }, - subSkill:{ - countdown:{ - trigger:{player:'useCardAfter'}, - mark:true, - marktext:'💀', - silent:true, - forced:true, - charlotte:true, - intro:{ - markcount:function(storage){ - if(storage){ - var list=storage.filter((_,i)=>i%3==2); - return Math.min.apply(null,list); - } - }, - content:function(storage,player){ - if(!storage) return; - var str='使用'; - str+=get.cnNumber(Math.min.apply(null,storage.filter((_,i)=>i%3==2)))+'张牌后,或使用一张'; - for(var i=0;ii%3==1)).includes(get.suit(event.card,player)); - return true; - }, - content:function(){ - 'step 0' - var storage=player.getStorage('dcxiangmian_countdown'); - for(var i=0;i0) player.loseHp(player.hp); - i--; - } - } - }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card!='object') return; - var storage=player.getStorage('dcxiangmian_countdown'); - for(var i=0;i{ - if(get[fn](card,player)==get[fn](cardxx,player)&&!cards.includes(cardxx)){ - return true; - } - }); - if(cardx) cards.push(cardx); - } - /*if(cards.length&&!player.isMaxHandcard(true)) player.draw(); - else*/ if(cards.length) player.gain(cards,'gain2') - } - }, - //赵直 - dctongguan:{ - trigger:{ - global:'phaseBegin', - }, - filter:function(event,player){ - return event.player.getAllHistory().filter(history=>{ - return history.isMe&&!history.isSkipped; - }).indexOf(event.player.getHistory())===0&&lib.skill.dctongguan.derivation.some(i=>{ - return (player.getStorage('dctongguan')[i]||0)<2; - }); - }, - forced:true, - locked:false, - logTarget:'player', - derivation:['dctongguan_wuyong','dctongguan_gangying','dctongguan_duomou','dctongguan_guojue','dctongguan_renzhi'], - content:function(){ - 'step 0' - var skills=lib.skill.dctongguan.derivation.slice(); - player.chooseControl(skills.filter(i=>{ - return (player.getStorage('dctongguan')[i]||0)<2; - })).set('choiceList',skills.map(i=>{ - var info=''; - switch (player.getStorage('dctongguan')[i]){ - case 1: - info=' style="opacity:0.65;"'; - break; - case 2: - info=' style="text-decoration:line-through; opacity:0.3;"'; - break; - } - return '
              「'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'」
              ' + - ''+get.skillInfoTranslation(i,player)+'(已选过'+get.cnNumber(player.getStorage('dctongguan')[i]||0)+'次)'+''; - })).set('displayIndex',false).set('prompt','统观:为'+get.translation(trigger.player)+'选择一个属性').set('ai',function(){ - var controls=_status.event.controls,target=_status.event.getTrigger().player; - var str=target.getSkills(null,false,false).map(i=>get.skillInfoTranslation(i)).join(''); - var choices=[]; - if(controls.includes('dctongguan_wuyong')&&/你对\S{1,15}造成\S{1,10}伤害/.test(str)) choices.push('dctongguan_wuyong'); - if(controls.includes('dctongguan_gangying')&&/回复\S{1,5}体力/.test(str)&&_status.event.player.getFriends().length) choices.push('dctongguan_gangying'); - if(controls.includes('dctongguan_duomou')&&/你(可|可以)?摸\S{1,3}张牌/.test(str)) choices.push('dctongguan_duomou'); - if(controls.includes('dctongguan_guojue')&&/(当【过河拆桥】使用|((弃置|获得)\S{1,5}其他角色\S{1,7}牌|))/.test(str)) choices.push('dctongguan_guojue'); - if(controls.includes('dctongguan_renzhi')&&/交给\S{0,5}其他角色/.test(str)&&_status.event.player.getFriends().length) choices.push('dctongguan_renzhi'); - if(choices.length) return choices.randomGet(); - return _status.event.controls.randomGet(); - }); - 'step 1' - if(result.control){ - var skill=result.control; - var func=lib.skill.dctongguan.localMark; - if(event.player==game.me) func(skill,trigger.player) - else if(event.isOnline()) player.send(func,skill,trigger.player) - // game.log(player,'为',trigger.player,'选择了','#g「'+get.translation(skill)+'」','属性'); - game.log(player,'为',trigger.player,'选择了','#g一个属性'); - // player.popup(skill); - trigger.player.addSkill(skill); - if(!player.storage.dctongguan) player.storage.dctongguan={}; - if(!player.storage.dctongguan[skill]) player.storage.dctongguan[skill]=0; - player.storage.dctongguan[skill]++; - } - }, - localMark:function(skill,player){ - var name=skill,info; - if(player.marks[name]) player.updateMarks(); - if(lib.skill[name]) info=lib.skill[name].intro; - if(!info) return; - if(player.marks[name]) player.marks[name].info=info; - else player.marks[name]=player.mark(name,info); - player.updateMarks(); - }, - subSkill:{ - forceFinish:{charlotte:true}, - wuyong:{ - marktext:'勇', - intro:{ - name:'武勇', - content:'属性目标:造成伤害', - }, - charlotte:true, - silent:true, - nopop:true, - }, - gangying:{ - marktext:'刚', - intro:{ - name:'刚硬', - content:'属性目标:回复体力,或于得到牌后手牌数大于体力值', - }, - charlotte:true, - silent:true, - forced:true, - nopop:true, - lastDo:true, - trigger:{player:'gainEnd'}, - filter:function(event,player){ - return player.countCards('h')>player.hp; - }, - content:function(){ - trigger._dctongguan_gangying=true; - }, - }, - duomou:{ - marktext:'谋', - intro:{ - name:'多谋', - content:'属性目标:于摸牌阶段外摸牌', - }, - charlotte:true, - silent:true, - nopop:true, - }, - guojue:{ - marktext:'决', - intro:{ - name:'果决', - content:'属性目标:弃置或获得其他角色牌', - }, - charlotte:true, - silent:true, - nopop:true, - }, - renzhi:{ - marktext:'仁', - intro:{ - name:'仁智', - content:'属性目标:交给其他角色牌', - }, - charlotte:true, - silent:true, - nopop:true, - }, - } - }, - dcmengjie:{ - trigger:{ - global:'phaseEnd', - }, - forced:true, - direct:true, - locked:false, - filter:function(event,player){ - var target=event.player; - if((target.hasSkill('dctongguan_gangying')&&(target.hasHistory('gain',function(evt){ - return evt._dctongguan_gangying==true; - })||game.getGlobalHistory('changeHp',function(evt){ - return evt.player==target&&(evt.getParent().name=='recover'||target.countCards('h')>target.hp); - }).length>0)) || - target.hasSkill('dctongguan_wuyong')&&target.getHistory('sourceDamage').length || - target.hasSkill('dctongguan_duomou')&&target.getHistory('gain',evt=>evt.getParent().name=='draw'&&evt.getParent('phaseDraw').name!='phaseDraw').length){ - return true; - } - var guojue=false,renzhi=false; - game.countPlayer2(current=>{ - if(current==target) return false; - if(!guojue&¤t.hasHistory('lose',evt=>{ - if(evt.type=='discard'){ - if((evt.discarder||evt.getParent(2).player)!=target) return false; - if(!evt.getl(current).cards2.length) return false; - return true; - } - else if(evt.type=='gain'){ - var evtx=evt.getParent(); - if(evtx.giver||evtx.getParent().name=='gift') return false; - var cards=evtx.getg(target); - if(!cards.length) return false; - var cards2=evtx.getl(current).cards2; - for(var card of cards2){ - if(cards.includes(card)) return true; - } - } - return false; - })) guojue=true; - if(!renzhi&¤t.hasHistory('gain',evt=>{ - if(evt.giver!=target||evt.getParent().name=='gift') return false; - return evt.cards.length; - })) renzhi=true; - }); - return target.hasSkill('dctongguan_guojue')&&guojue||target.hasSkill('dctongguan_renzhi')&&renzhi; - }, - rules:[ - (target)=>target.getHistory('sourceDamage').length, - (target)=>target.hasHistory('gain',function(evt){ - return evt._dctongguan_gangying; - })||game.getGlobalHistory('changeHp',function(evt){ - return evt.player==target&&evt.getParent().name=='recover'; - }).length>0||target.countCards('h')>target.hp, - (target)=>target.getHistory('gain',evt=>evt.getParent().name=='draw'&&evt.getParent('phaseDraw').name!='phaseDraw').length, - (target,bool)=>bool, - (target,bool)=>bool - ], - content:function(){ - 'step 0' - event.nowProperty=0; - var target=trigger.player; - var guojue=false,renzhi=false; - game.countPlayer2(current=>{ - if(current==target) return false; - if(!guojue&¤t.hasHistory('lose',evt=>{ - if(evt.type=='discard'){ - if((evt.discarder||evt.getParent(2).player)!=target) return false; - if(!evt.getl(current).cards2.length) return false; - return true; - } - else if(evt.type=='gain'){ - var evtx=evt.getParent(); - if(evtx.giver||evtx.getParent().name=='gift') return false; - var cards=evtx.getg(target); - if(!cards.length) return false; - var cards2=evtx.getl(current).cards2; - for(var card of cards2){ - if(cards.includes(card)) return true; - } - } - return false; - })) guojue=true; - if(!renzhi&¤t.hasHistory('gain',evt=>{ - if(evt.giver!=target||evt.getParent().name=='gift') return false; - return evt.cards.length; - })) renzhi=true; - }); - event.guojue=guojue; event.renzhi=renzhi; - 'step 1' - if(event.nowProperty>=5){ + player.storage.dcyuanmo_range = _tmp; + targetsx.removeArray(targets); + return targetsx.reduce((p, c) => { + return ( + p + + Math.max(0, get.effect(c, { name: "shunshou_copy2" }, player, player)) + ); + }, 0) > + get.effect(player, { name: "draw" }, player, player) * 1.3 + ? "选项一" + : "选项二"; + })() + ); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - var skills=lib.skill.dctongguan.derivation; - if(trigger.player.hasSkill(skills[event.nowProperty])&&lib.skill.dcmengjie.rules[event.nowProperty](trigger.player,event[event.nowProperty==3?'guojue':'renzhi'])){ - event.goto(2+event.nowProperty*2); + player.logSkill("dcyuanmo"); + if (result.control == "选项一") { + lib.skill.dcyuanmo.change(player, 1); + var targetsx = game.filterPlayer((current) => player.inRange(current)); + if (targetsx.length <= targets.length) { + event.finish(); + } else event.targets = targetsx.removeArray(targets); + } else { + lib.skill.dcyuanmo.change(player, -1); + player.draw(2); + event.finish(); + } + "step 2"; + player + .chooseTarget( + "远谟:获得任意名本次进入你攻击范围的角色的一张牌", + [1, targets.length], + (card, player, target) => { + return ( + _status.event.getParent().targets.includes(target) && + target.countGainableCards(player, "he") > 0 + ); + } + ) + .set("ai", (target) => { + var player = _status.event.player; + return get.effect(target, { name: "shunshou_copy2" }, player, player); + }); + "step 3"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets); + for (var target of targets) { + player.gainPlayerCard(target, "he", true); + } + } + }, + subSkill: { + add: { + audio: "dcyuanmo", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return !game.hasPlayer((current) => player.inRange(current)); + }, + prompt2: "令你的攻击范围+1", + check: () => true, + content: function () { + lib.skill.dcyuanmo.change(player, 1); + }, + }, + range: { + charlotte: true, + intro: { + content: function (storage, player) { + var num = player.storage.dcyuanmo_range; + return "攻击范围" + (num >= 0 ? "+" : "") + num; + }, + }, + mod: { + attackRange: function (player, num) { + return num + player.countMark("dcyuanmo_range"); + }, + }, + }, + }, + }, + //薛灵芸 + dcxialei: { + audio: 2, + trigger: { + player: "loseAfter", + global: ["cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], + }, + filter: function (event, player) { + if (player.countMark("dcxialei_clear") >= 3) return false; + if (event.name != "cardsDiscard") { + return event.getd(player, "cards2").some((i) => get.color(i, player) == "red"); + } else { + if (!event.cards.filterInD("d").some((i) => get.color(i, player) == "red")) + return false; + var evt = event.getParent(); + if (evt.name != "orderingDiscard") return false; + var evtx = evt.relatedEvent || evt.getParent(); + if (evtx.player != player) return false; + return player.hasHistory("lose", (evtxx) => { + return ( + evtx == (evtxx.relatedEvent || evtxx.getParent()) && evtxx.cards2.length > 0 + ); + }); + } + }, + content: function () { + "step 0"; + var cards = get.cards(3 - player.countMark("dcxialei_clear")); + event.cards = cards; + game.cardsGotoOrdering(cards); + if (cards.length == 1) event._result = { bool: true, links: cards }; + else player.chooseButton(["霞泪:获得其中的一张牌", cards], true); + "step 1"; + if (result.bool) { + var card = result.links[0]; + player.gain(card, "gain2"); + event.cards.remove(card); + if (event.cards.length) { + player + .chooseBool() + .set("createDialog", ["是否将剩余牌置于牌堆底?", event.cards]) + .set("ai", () => _status.event.bool) + .set( + "bool", + (function () { + if (!player.hasSkill("dcanzhi")) return Math.random() < 0.5; + if (player.hasSkill("dcanzhi_blocker")) { + var next = _status.currentPhase.getNext(); + var judges = next.getCards("j"); + var val = 0; + if (judges.length && !next.hasWuxie()) { + var att = get.attitude(player, next); + for (var i = 0; ; i++) { + var judge = judges[i] && get.judge(judges[i]), + card = event.cards[i]; + if (!judge || !card) break; + val += judge(card) * att; + i++; + } + } + if (val > 0) return false; + else if (val == 0) return Math.random() < 0.5; + return true; + } + var card = event.cards[0]; + if ( + get.color(card, player) == "red" && + player.isPhaseUsing() && + player.countCards("hs", (card) => { + return ( + get.color(card) == "red" && + player.hasValueTarget(card) && + ["basic", "trick"].includes(get.type(card)) + ); + }) > 0 + ) + return false; + if (get.color(card, player) == "black") return false; + return true; + })() + ); + } else event.goto(3); + } else event.finish(); + "step 2"; + if (result.bool) { + player.popup("牌堆底"); + game.log(player, "将" + get.cnNumber(event.cards.length) + "张牌置于了牌堆底"); + } else player.popup("牌堆顶"); + while (cards.length) { + var card = cards.pop(); + card.fix(); + if (result.bool) ui.cardPile.appendChild(card); + else ui.cardPile.insertBefore(card, ui.cardPile.firstChild); + } + game.updateRoundNumber(); + "step 3"; + player.addMark("dcxialei_clear", 1, false); + player.addTempSkill("dcxialei_clear"); + }, + subSkill: { clear: { onremove: true } }, + }, + dcanzhi: { + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("dcanzhi_blocker"); + }, + group: "dcanzhi_damage", + content: function () { + "step 0"; + player.judge((result) => { + if (get.color(result) == "red") + return _status.event.getParent().player.countMark("dcxialei_clear") / 2; + return 2; + }).judge2 = (result) => result.bool; + "step 1"; + if (result.color == "red") { + player.removeSkill("dcxialei_clear"); + event.finish(); + } else if (result.color == "black") { + player.addTempSkill("dcanzhi_blocker"); + player + .chooseTarget( + "暗织:是否令一名非当前回合角色获得本回合进入弃牌堆的两张牌?", + (card, player, target) => { + return target != _status.currentPhase; + } + ) + .set("ai", (target) => { + return get.effect(target, { name: "wuzhong" }, _status.event.player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target); + var cards = []; + game.getGlobalHistory("cardMove", (evt) => { + if ( + (evt.name == "lose" && evt.position == ui.discardPile) || + evt.name == "cardsDiscard" + ) { + cards.addArray(evt.cards.filterInD("d")); + } + }); + 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.value(button.link, target); + }); + } + } else event.finish(); + "step 3"; + if (result.bool) { + target.gain(result.links, "gain2"); + } + }, + ai: { + combo: "dcxialei", + order: function (item, player) { + if (player.countMark("dcxialei_clear") >= 2) return 10; + if ( + player.hasHistory("useSkill", (evt) => evt.skill == "dcxialei") && + get.color(ui.cardPile.firstChild, player) == "red" && + player.countMark("dcxialei_clear") > 0 + ) + return 9; + return 1; + }, + result: { + player: function (player) { + return 1; + }, + }, + }, + subSkill: { + damage: { + audio: "dcanzhi", + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return !player.hasSkill("dcanzhi_blocker"); + }, + check: function (event, player) { + return game.hasPlayer((current) => { + return get.attitude(player, current) > 0 && current != _status.currentPhase; + }); + }, + prompt2: + "你判定,若结果为红色,你重置〖霞泪〗的观看牌数;若结果为黑色,〖暗织〗于本回合失效,然后你可以令一名非当前回合角色获得本回合进入弃牌堆的两张牌。", + content: function () { + event.setContent(lib.skill.dcanzhi.content); + event.goto(0); + }, + }, + blocker: { charlotte: true }, + }, + }, + //十周年王允 + dclianji: { + enable: "phaseUse", + audio: "wylianji", + usable: 1, + check: function (card) { + return 5 - get.value(card); + }, + filterTarget: function (card, player, target) { + return target != player; + }, + filterCard: true, + content: function () { + "step 0"; + var card = get.cardPile2(function (card) { + return get.subtype(card) == "equip1" && targets[0].hasUseTarget(card); + }); + if (card) { + if (card.name == "qinggang" && !lib.inpile.includes("qibaodao")) { + card.remove(); + card = game.createCard("qibaodao", card.suit, card.number); + } + targets[0].chooseUseTarget(card, true, "nopopup", "nothrow"); + } else { + player.chat("没有装备牌了吗"); + game.log("但是牌堆里已经没有装备牌了!"); + } + "step 1"; + game.updateRoundNumber(); + targets[0] + .chooseToUse(get.translation(player) + "对你发动了【连计】", { name: "sha" }) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if (target == _status.event.source) return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("addCount", false) + .set("source", player) + .set( + "prompt2", + "对除" + + get.translation(player) + + "外的一名角色使用一张【杀】,并将装备区内的武器牌交给其中一名目标角色;或点击“取消”,令" + + get.translation(player) + + "视为对你使用一张【杀】,并获得你装备区内的武器牌" + ); + "step 2"; + var card = targets[0].getEquips(1); + if (result.bool) { + player.addSkill("dclianji_1"); + if (card.length && result.targets.filter((target) => target.isIn()).length > 0) { + event.card = card; + targets[0] + .chooseTarget( + true, + "将" + get.translation(card) + "交给一名目标角色", + (card, player, target) => { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + var card = _status.event.getParent().card[0]; + return ( + (target.hasSkillTag("nogain") + ? 0 + : get.attitude(_status.event.player, target)) * + Math.max(0.1, target.getUseValue(card)) + ); + }) + .set("targets", result.targets); + } else event.finish(); + } else { + player.addSkill("dclianji_2"); + event.goto(4); + } + "step 3"; + targets[0].give(card, result.targets[0], "give"); + event.finish(); + "step 4"; + player.useCard({ name: "sha", isCard: true }, targets[0], false); + "step 5"; + var card = targets[0].getEquips(1); + if (card.length) targets[0].give(card, player, "give"); + }, + ai: { + order: 4, + result: { + target: function (player, target) { + if (game.countPlayer() == 2) return -3; + if (!target.getEquip(1)) { + if ( + game.hasPlayer(function (current) { + return ( + current != target && + !current.hasSkillTag("nogain") && + get.attitude(current, target) > 0 + ); + }) + ) + return 3; + return -3; + } + if ( + !game.hasPlayer(function (current) { + return ( + current != target && + !current.hasSkillTag("nogain") && + get.attitude(current, target) > 0 + ); + }) + ) + return -6; + return 4 - get.value(target.getEquip(1)); + }, + }, + }, + subSkill: { + 1: { charlotte: true, onremove: true }, + 2: { charlotte: true, onremove: true }, + }, + }, + dcmoucheng: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: "moucheng", + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "gray", + derivation: "xinjingong", + unique: true, + filter: function (event, player) { + return player.hasSkill("dclianji_1") && player.hasSkill("dclianji_2"); + }, + content: function () { + player.awakenSkill("dcmoucheng"); + player.changeSkills(["xinjingong"], ["dclianji"]); + }, + }, + //周宣 + dcwumei: { + audio: 2, + trigger: { player: "phaseBeginStart" }, + filter: function (event, player) { + return !player.hasSkill("dcwumei_used"); + }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("dcwumei")).set("ai", (target) => { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcwumei", target); + player.addTempSkill("dcwumei_used", "roundStart"); + target.insertPhase(); + target.addTempSkill("dcwumei_wake", "phaseAfter"); + var targets = game.filterPlayer(); + if (!target.storage.dcwumei_wake) target.storage.dcwumei_wake = [[], []]; + for (var targetx of targets) { + target.storage.dcwumei_wake[0].push(targetx); + target.storage.dcwumei_wake[1].push(targetx.hp); + } + target.markSkill("dcwumei_wake"); + if (!trigger._finished) { + trigger.finish(); + trigger.untrigger(true); + trigger._triggered = 5; + game.players + .slice() + .concat(game.dead) + .forEach((current) => { + current.getHistory().isSkipped = true; + current.getStat().isSkipped = true; + }); + 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, + filter: function (event, player) { + return player.storage.dcwumei_wake && player.storage.dcwumei_wake.length; + }, + content: function () { + var storage = player.storage.dcwumei_wake; + for (var i = 0; i < storage[0].length; i++) { + var target = storage[0][i]; + if (target && target.isIn()) { + if (target.hp != storage[1][i]) { + game.log( + target, + "将体力从", + get.cnNumber(target.hp, true), + "改为", + get.cnNumber(storage[1][i], true) + ); + target.changeHp(storage[1][i] - target.hp)._triggered = null; + } + } + } + player.removeSkill("dcwumei_wake"); + }, + marktext: "寐", + intro: { + markcount: function (storage, player) { + if (!storage || !storage.length) return 0; + return storage[0].length; + }, + content: function (storage, player) { + if (!storage || !storage.length) return "无信息"; + var str = "所有角色于回合开始时的体力值:
              "; + for (var i = 0; i < storage[0].length; i++) { + var str2 = get.translation(storage[0][i]) + ":" + storage[1][i]; + if (!storage[0][i].isIn()) + str2 = '' + str2 + "(已故)"; + str += "
            • " + str2; + } + return str; + }, + }, + }, + all: { + trigger: { player: "dieAfter" }, + filter: function (event, player) { + return !game.hasPlayer((current) => current.hasSkill("dcwumei_wake"), true); + }, + 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; + }, + }, + }, + }, + }, + }, + dczhanmeng: { + audio: 2, + trigger: { player: "useCard" }, + filter(event, player) { + return ( + !player.hasSkill("dczhanmeng_choice1") || + !player.hasSkill("dczhanmeng_choice2") || + (!player.hasSkill("dczhanmeng_choice0") && + !game.hasPlayer2((current) => { + const history = current.actionHistory; + if (history.length < 2) return false; + for (let i = history.length - 2; i >= 0; i--) { + if (history[i].isSkipped) continue; + const list = history[i].useCard.map((evt) => evt.card.name); + return list.includes(event.card.name); + } + return false; + }, true)) + ); + }, + direct: true, + content() { + "step 0"; + var list = []; + var choiceList = [ + "上回合若没有同名牌被使用过,你获得一张非伤害牌", + "下回合当同名牌首次被使用后,你获得一张伤害牌", + "令一名其他角色弃置两张牌,若点数之和大于10,你对其造成1点火焰伤害", + ]; + var used = game.hasPlayer2((current) => { + var history = current.actionHistory; + if (history.length < 2) return false; + for (let i = history.length - 2; i >= 0; i--) { + if (history[i].isSkipped) continue; + const list = history[i].useCard.map((evt) => evt.card.name); + return list.includes(trigger.card.name); + } + return false; + }, true); + if (!player.hasSkill("dczhanmeng_choice0") && !used) list.push("选项一"); + else + choiceList[0] = + '' + + choiceList[0] + + (used ? "(同名牌被使用过)" : "(已选择)") + + ""; + if (!player.hasSkill("dczhanmeng_choice1")) list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + "(已选择)"; + var other = game.hasPlayer((current) => current != player); + if (!player.hasSkill("dczhanmeng_choice2") && other) list.push("选项三"); + else + choiceList[2] = + '' + + choiceList[2] + + (!other ? "(没人啦)" : "(已选择)") + + ""; + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("dczhanmeng")) + .set("ai", () => { + var choices = _status.event.controls.slice().remove("cancel2"); + var player = _status.event.player, + evt = _status.event.getTrigger(); + if (!game.hasPlayer((current) => get.attitude(player, current) < 0)) + choices.remove("选项三"); + else if (choices.includes("选项三")) return "选项三"; + if (choices.includes("选项二")) { + if (evt.card.name == "sha") return "选项二"; + if (get.type(evt.card, null, false) == "equip") choices.remove("选项二"); + } + if (!choices.length) return "cancel2"; + return choices.randomGet(); + }) + .set("choiceList", choiceList); + "step 1"; + if (result.control == "cancel2") { + event.finish(); + return; + } + if (result.control == "选项一") { + player.logSkill("dczhanmeng"); + game.log(player, "选择了", "#y" + result.control); + player.addTempSkill("dczhanmeng_choice0"); + var card = get.cardPile2((card) => { + return !get.tag(card, "damage"); + }); + if (card) player.gain(card, "gain2"); + event.finish(); + } else if (result.control == "选项二") { + player.logSkill("dczhanmeng"); + game.log(player, "选择了", "#y" + result.control); + player.addTempSkill("dczhanmeng_choice1"); + trigger["dczhanmeng_" + player.playerid] = true; + player.addSkill("dczhanmeng_delay"); + event.finish(); + } else { + player.addTempSkill("dczhanmeng_choice2"); + player + .chooseTarget("占梦:令一名其他角色弃置两张牌", lib.filter.notMe, true) + .set("ai", (target) => { + var player = _status.event.player; + var eff1 = get.effect(target, { name: "guohe_copy2" }, player, player) + 0.1; + var eff2 = get.damageEffect(target, player, player, "fire") + 0.1; + if (eff1 < 0 && eff2 < 0) return -eff1 * eff2; + return eff1 * eff2; + }); + } + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("dczhanmeng", target); + game.log(player, "选择了", "#y选项三"); + target.chooseToDiscard(2, "he", true); + } else event.finish(); + "step 3"; + if (result.bool) { + var cards = result.cards; + var num = 0; + for (var card of cards) { + num += get.number(card, false); + } + if (num > 10) { + player.line(target, "fire"); + target.damage("fire"); + } + } + }, + ai: { threaten: 8 }, + subSkill: { + delay: { + trigger: { global: ["useCardAfter", "phaseBeginStart"] }, + charlotte: true, + forced: true, + popup: false, + silent: true, + filter(event, player, name) { + var history = player.actionHistory; + if (history.length < 2) return false; + var list = history[history.length - 2].useCard; + if (name == "phaseBeginStart") { + return !list.some((evt) => evt["dczhanmeng_" + player.playerid]); + } + for (var evt of list) { + if ( + evt["dczhanmeng_" + player.playerid] && + event.card.name == evt.card.name && + game + .getGlobalHistory("useCard", (evtx) => { + return evtx.card.name == event.card.name; + }) + .indexOf(event) == 0 + ) + return true; + } + return false; + }, + content() { + if (event.triggername != "phaseBeginStart") { + player.logSkill("dczhanmeng_delay"); + var card = get.cardPile2((card) => { + return get.tag(card, "damage"); + }); + if (card) player.gain(card, "gain2"); + } else player.removeSkill("dczhanmeng_delay"); + }, + }, + choice0: { charlotte: true }, + choice1: { charlotte: true }, + choice2: { charlotte: true }, + }, + }, + //程秉 + dcjingzao: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + if (3 + player.countMark("dcjingzao_add") - player.countMark("dcjingzao_ban") <= 0) + return false; + return game.hasPlayer((current) => + lib.skill.dcjingzao.filterTarget(null, player, current) + ); + }, + filterTarget: function (card, player, target) { + return player != target && !target.hasSkill("dcjingzao_temp"); + }, + content: function () { + "step 0"; + target.addTempSkill("dcjingzao_temp"); + var cards = game.cardsGotoOrdering( + get.cards(3 + player.countMark("dcjingzao_add") - player.countMark("dcjingzao_ban")) + ).cards; + event.cards = cards; + game.log(player, "亮出了", event.cards); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, target, id, cards) { + var str = + get.translation(player) + + "对" + + (target == game.me ? "你" : get.translation(target)) + + "发动了【经造】"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + target, + event.videoId, + event.cards + ); + game.addVideo("showCards", player, [ + get.translation(player) + "发动了【经造】", + get.cardsInfo(event.cards), + ]); + game.delay(cards.length - 1); + "step 1"; + target + .chooseToDiscard("he") + .set("prompt", false) + .set("filterCard", (card) => { + var names = _status.event.getParent().cards.map((i) => i.name); + return names.includes(get.name(card)); + }) + .set("ai", (card) => { + var target = _status.event.player, + player = _status.event.getParent().player; + var att = get.attitude(target, player), + val = get.value(card); + if (!lib.skill.dcjingzao.filter(null, player)) { + if (att > 0) return 0; + return 6 - val; + } else { + if (att > 0) return 4 - val; + return 0; + } + }); + var update = function (id, source) { + var dialog = get.idDialog(id); + if (dialog) { + var div = ui.create.div("", dialog.content, 1); + var name = get.translation(source); + div.innerHTML = + "弃置一张满足条件的牌,然后" + + name + + "〖经造〗本回合亮出牌数+1;或点“取消”令" + + name + + "随机获得每种牌名的牌各一张,且〖经造〗本回合失效"; + ui.update(); + } + }; + if (target == game.me) update(event.videoId, player); + else if (target.isOnline()) target.send(update, event.videoId, player); + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + if (result.bool) { + player.addTempSkill("dcjingzao_add"); + player.addMark("dcjingzao_add", 1, false); + } else { + var cards = cards.randomSort(), + cards2 = []; + for (var card of cards) { + if (!cards2.map((i) => i.name).includes(card.name)) cards2.push(card); + } + if (cards2.length) player.gain(cards2, "gain2"); + player.addTempSkill("dcjingzao_ban"); + player.addMark("dcjingzao_ban", cards2.length, false); + } + }, + ai: { + order: 7, + result: { + player: 1, + }, + }, + subSkill: { + add: { charlotte: true, onremove: true }, + ban: { charlotte: true, onremove: true }, + temp: { charlotte: true }, + }, + }, + dcenyu: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + return ( + event.player != player && + game.hasPlayer2((current) => { + return current.hasHistory("useCard", (evt) => { + return ( + evt.card.name == event.card.name && + evt != event.getParent() && + evt.targets && + evt.targets.includes(player) + ); + }); + }) && + (event.card.name == "sha" || get.type(event.card) == "trick") + ); + }, + content: function () { + trigger.getParent().excluded.add(player); + }, + ai: { + effect: { + target: (card, player, target) => { + if (player === target) return; + if ( + game.hasPlayer2((current) => { + return current.hasHistory( + "useCard", + (evt) => + evt.card.name == card.name && + evt.targets && + evt.targets.includes(target) + ); + }) && + (card.name == "sha" || get.type(card) == "trick") + ) + return "zeroplayertarget"; + }, + }, + }, + }, + //董贵人 + dclianzhi: { + audio: 2, + trigger: { player: "dying" }, + usable: 1, + forced: true, + locked: false, + derivation: "dcshouze", + group: ["dclianzhi_connect", "dclianzhi_reproach"], + filter: function (event, player) { + return player.getStorage("dclianzhi").filter((i) => i && i.isIn()).length; + }, + content: function () { + player.recover(); + game.asyncDraw( + [player] + .concat(player.getStorage("dclianzhi").filter((i) => i && i.isIn())) + .sortBySeat() + ); + }, + ai: { + threaten: 0.6, + }, + subSkill: { + connect: { + audio: "dclianzhi", + trigger: { + player: "enterGame", + global: "phaseBefore", + }, + forced: true, + direct: true, + filter: function (event, player) { + return ( + game.hasPlayer((current) => current != player) && + (event.name != "phase" || game.phaseNumber == 0) + ); + }, + content: function () { + "step 0"; + player + .chooseTarget( + "连枝:请选择一名其他角色", + lib.translate.dclianzhi_info, + true, + (card, player, target) => { + return ( + target != player && + !player.getStorage("dclianzhi").includes(target) + ); + } + ) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (att > 0) return att + 1; + if (att == 0) return Math.random(); + return att; + }) + .set("animate", false); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dclianzhi"); + player.markAuto("dclianzhi", [target]); + } + }, + }, + reproach: { + audio: "dclianzhi", + trigger: { global: "dieAfter" }, + filter: function (event, player) { + return player.getStorage("dclianzhi").includes(event.player); + }, + direct: true, + content: function () { + "step 0"; + var num = Math.max(1, player.countMark("dclingfang")); + player + .chooseTarget( + get.prompt("dclianzhi"), + "选择一名其他角色,你与其各获得〖受责〗,且其获得" + num + "枚“绞”标记", + (card, player, target) => { + return target != player; + } + ) + .set("ai", (target) => -get.attitude(_status.event.player, target)); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dclianzhi_reproach", target); + player.addSkills("dcshouze"); + target.addSkills("dcshouze"); + target.addMark("dclingfang", Math.max(1, player.countMark("dclingfang"))); + } + }, + }, + }, + }, + dclingfang: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", + global: "useCardAfter", + }, + forced: true, + filter: function (event, player) { + if (event.name != "useCard") return true; + if (get.color(event.card) != "black") return false; + if (event.player == player) return !event.targets || !event.targets.includes(player); + return event.targets && event.targets.includes(player); + }, + content: function () { + player.addMark("dclingfang", 1); + }, + ai: { + combo: "dcfengying", + }, + marktext: "绞", + intro: { + name: "绞", + name2: "绞", + content: "mark", + }, + }, + dcfengying: { + audio: 2, + enable: "chooseToUse", + group: "dcfengying_record", + locked: false, + filter: function (event, player) { + var mark = player.countMark("dclingfang"); + if (mark <= 0 || !player.hasCard((card) => get.number(card) <= mark, "hs")) return false; + var storage = player.getStorage("dcfengying"); + if (!storage.length) return false; + var storage2 = player.getStorage("dcfengying_used"); + return storage.some((name) => { + return ( + !storage2.includes(name) && + event.filterCard(get.autoViewAs({ name }, "unsure"), player, event) + ); + }); + }, + hiddenCard: function (player, name) { + var list = player.getStorage("dcfengying"); + if (player.getStorage("dcfengying_used").includes(name)) return false; + return ( + list.includes(name) && + player.hasCard((card) => get.number(card) <= player.countMark("dclingfang"), "hs") + ); + }, + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of player.storage.dcfengying) { + if (get.type(name) == "basic") list.push(["基本", "", name]); + if (get.type(name) == "trick") list.push(["锦囊", "", name]); + } + return ui.create.dialog("风影", [list, "vcard"]); + }, + filter: function (button, player) { + var card = { name: button.link[2], storage: { dcfengying: true } }; + if (player.getStorage("dcfengying_used").includes(card.name)) return false; + return _status.event + .getParent() + .filterCard(get.autoViewAs(card, "unsure"), player, _status.event.getParent()); + }, + check: function (button) { + var player = _status.event.player; + if (player.countCards("hs", button.link[2]) > 0) return 0; + if (button.link[2] == "wugu") return; + var effect = player.getUseValue(button.link[2]); + if (effect > 0) return effect; + return 0; + }, + backup: function (links, player) { + return { + filterCard: function (card, player, event) { + return get.number(card) <= player.countMark("dclingfang"); + }, + audio: "dcfengying", + selectCard: 1, + popname: true, + check: function (card) { + return 6 - get.value(card) + get.number(card) / 15; + }, + position: "hs", + viewAs: { + name: links[0][2], + storage: { dcfengying: true }, + }, + precontent: function () { + player.logSkill("dcfengying"); + player.addTempSkill("dcfengying_used"); + player.markAuto("dcfengying_used", [event.result.card.name]); + event.getParent().addCount = false; + delete event.result.skill; + }, + }; + }, + prompt: function (links, player) { + return ( + "将一张点数不大于" + + get.strNumber(player.countMark("dclingfang")) + + "的手牌当做" + + get.translation(links[0][2]) + + "使用(无距离和次数限制)" + ); + }, + }, + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.dcfengying) return true; + }, + cardUsable: function (card, player) { + if (card.storage && card.storage.dcfengying) return Infinity; + }, + }, + ai: { + order: 4, + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); + return 1; + }, + }, + threaten: 2, + combo: "dclingfang", + }, + subSkill: { + record: { + trigger: { global: "phaseBegin" }, + filter: function (event, player) { + return ui.discardPile.childNodes.length > 0; + }, + forced: true, + popup: false, + content: function () { + player.storage.dcfengying = []; + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var card = ui.discardPile.childNodes[i]; + if (get.color(card, false) != "black") continue; + if (!["basic", "trick"].includes(get.type(card))) continue; + player.storage.dcfengying.add(card.name); + } + player.storage.dcfengying.sort((a, b) => { + return lib.inpile.indexOf(a) - lib.inpile.indexOf(b); + }); + }, + }, + used: { + charlotte: true, + onremove: true, + intro: { + content: "已使用过$", + }, + }, + }, + }, + dcshouze: { + audio: true, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("dclingfang") > 0; + }, + content: function () { + "step 0"; + player.removeMark("dclingfang", 1); + "step 1"; + var card = get.discardPile((card) => get.color(card, false) == "black"); + if (card) player.gain(card, "gain2"); + player.loseHp(); + }, + ai: { + combo: "dclingfang", + }, + }, + //袁姬 + dcmengchi: { + audio: "dcfangdu", + trigger: { player: ["linkBefore", "damageEnd"] }, + forced: true, + filter: function (event, player) { + var num = player.getStat("gain"); + if (num && num > 0) return false; + if (event.name == "link") return !player.isLinked(); + return event.hasNature(); + }, + content: function () { + if (trigger.name == "link") trigger.cancel(); + else player.recover(); + }, + ai: { + effect: { + target: function (card, player, target, current) { + if ( + get.itemtype(player) != "player" || + player._dcmengchi_aiChecking || + target.getStat("gain") + ) + return; + if (card.name == "tiesuo" && !target.isLinked()) return 0; + if (player.hasSkillTag("jueqing", false, target)) return; + if (!get.tag(card, "damage") || get.tag(card, "natureDamage")) return; + if (target.hp <= 1) return 0.75; + if ( + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) && + player.hasSkillTag("damageBonus", false, { + target: target, + card: card, + }) + ) { + if (target.hp > 2) return 0.5; + return 0.75; + } + if (get.attitude(player, target) > 0) return [0, 0]; + var sha = player.getCardUsable({ name: "sha" }); + player._dcmengchi_aiChecking = true; + var num = player.countCards("h", function (card) { + if (get.name(card) == "sha") { + if (sha == 0) return false; + else sha--; + } + return ( + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); + }); + delete player._dcmengchi_aiChecking; + if (player.hasSkillTag("damage")) num++; + if (num < 2) return [0, 0]; + }, + }, + }, + mod: { + cardEnabled: function (card, player) { + if (!player.getStat("gain")) return false; + }, + cardSavable: function (card, player) { + if (!player.getStat("gain")) return false; + }, + }, + }, + dcfangdu: { + audio: 2, + trigger: { + player: "damageEnd", + }, + forced: true, + filter: function (event, player) { + if (player == _status.currentPhase) return false; + return ( + (!event.hasNature() && + !player.hasHistory( + "damage", + (evt) => { + return !evt.hasNature() && evt != event; + }, + event + )) || + (event.hasNature() && + !player.hasHistory( + "damage", + (evt) => { + return evt.hasNature() && evt != event; + }, + event + ) && + event.source && + event.source.isIn() && + event.source.countGainableCards(player, "h")) + ); + }, + content: function () { + "step 0"; + if (!trigger.hasNature()) { + player.recover(); + } else { + var cards = trigger.source.getGainableCards(player, "h"); + if (cards.length) { + player.gain(cards.randomGet(), trigger.source, "giveAuto", "bySelf"); + } + } + }, + ai: { + effect: { + target: function (card, player, target) { + if (player._dcfangdu_aiChecking || target == _status.currentPhase) return; + if (!get.tag(card, "damage") || player.hasSkillTag("jueqing", false, target)) + return; + if ( + _status.event.getParent("useCard", true) || + _status.event.getParent("_wuxie", true) + ) + return; + if (!get.tag(card, "natureDamage")) { + if (target.hasHistory("damage", (evt) => !evt.hasNature())) return 1.5; + else if ( + target.hp <= 1 || + (player.hasSkillTag("damageBonus", false, { + target: target, + card: card, + }) && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + })) + ) + return 0.75; + else { + if (get.attitude(player, target) > 0) return [0, 0]; + var sha = player.getCardUsable({ name: "sha" }); + player._dcfangdu_aiChecking = true; + var num = player.countCards("h", function (card) { + if (get.name(card) == "sha") { + if (sha == 0) return false; + else sha--; + } + return ( + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); + }); + delete player._dcfangdu_aiChecking; + if (player.hasSkillTag("damage")) num++; + if (num < 2) return [0, 0]; + } + } + if ( + get.tag(card, "natureDamage") && + !target.hasHistory("damage", (evt) => evt.hasNature()) && + player.countCards("he") > 1 + ) + return [1, 1, 1, -1]; + }, + }, + }, + }, + dcjiexing: { + audio: 2, + trigger: { player: ["recoverEnd", "damageEnd", "loseHpEnd"] }, + check: function (event, player) { + var current = _status.currentPhase; + if (!player.hasSkill("dcmengchi") || get.attitude(player, current) >= 0) return true; + var num = player.getStat("gain"); + if (num && num > 0) return true; + if ( + current.countCards( + "hs", + (card) => + current.canUse(card, player) && get.effect(player, card, current, player) < 0 + ) >= 2 + ) + return false; + return true; + }, + frequent: "check", + content: function () { + player.draw().gaintag = ["dcjiexing"]; + player.addTempSkill("dcjiexing_add"); + }, + subSkill: { + add: { + charlotte: true, + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("dcjiexing")) return true; + }, + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("dcjiexing")) return false; + }, + }, + onremove: function (player) { + player.removeGaintag("dcjiexing"); + }, + }, + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "recover")) return [1, 1]; + if (get.tag(card, "damage")) { + var draw = 0.9; + if (target.hasSkill("dcmengchi") && target.getStat("gain")) draw = 1.8; + if ( + target.hp <= 1 || + (card.name == "sha" && player.hasSkill("jiu")) || + (get.itemtype(player) == "player" && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) && + player.hasSkillTag("damageBonus", false, { + target: target, + card: card, + })) + ) { + if (target.hp > 2) return [1, draw]; + return; + } + return [1, draw]; + } + }, + }, + }, + }, + //朱建平 + olddcxiangmian: { + audio: "dcxiangmian", + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + !player.getStorage("olddcxiangmian").includes(event.player) && player != event.player + ); + }, + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) < 0; + }, + content: function () { + "step 0"; + player + .judge((card) => 2 / Math.sqrt(get.number(card, false))) + .set("judge2", (result) => result.bool); + "step 1"; + player.markAuto("olddcxiangmian", [trigger.player]); + trigger.player.addSkill("olddcxiangmian_countdown"); + if (!trigger.player.storage["olddcxiangmian_countdown"]) + trigger.player.storage["olddcxiangmian_countdown"] = []; + [player.playerid, result.suit, result.number].forEach((i) => + trigger.player.storage["olddcxiangmian_countdown"].push(i) + ); + trigger.player.markSkill("olddcxiangmian_countdown"); + }, + intro: { content: "已对$发动过技能" }, + ai: { + expose: 0.3, + }, + subSkill: { + countdown: { + trigger: { player: "useCardAfter" }, + mark: true, + marktext: "噬", + silent: true, + forced: true, + charlotte: true, + intro: { + markcount: function (storage) { + if (storage) { + var list = storage.filter((_, i) => i % 3 == 2); + return Math.min.apply(null, list); + } + }, + content: function (storage, player) { + var str = "使用"; + for (var i = 0; i < storage.length / 3; i++) { + str += + get.cnNumber(storage[i * 3 + 2]) + + "张" + + get.translation(storage[i * 3 + 1]) + + "牌、"; + } + str = str.slice(0, -1); + str += "后,失去等同于体力值的体力"; + return str; + }, + }, + filter: function (event, player) { + if (!player.getStorage("olddcxiangmian_countdown").length) return false; + return player + .getStorage("olddcxiangmian_countdown") + .filter((_, i) => i % 3 == 1) + .includes(get.suit(event.card, player)); + }, + content: function () { + "step 0"; + var storage = player.getStorage("olddcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if (storage[i * 3 + 1] == get.suit(trigger.card, player)) { + storage[i * 3 + 2]--; + } + } + player.markSkill("olddcxiangmian_countdown"); + "step 1"; + var storage = player.getStorage("olddcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if (storage[i * 3 + 2] <= 0) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + player.logSkill("olddcxiangmian_countdown"); + var target = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.storage["olddcxiangmian_countdown"].splice(i * 3, 3); + if (!player.getStorage("olddcxiangmian_countdown").length) { + player.removeSkill("olddcxiangmian_countdown"); + } + if (player.hp > 0) player.loseHp(player.hp); + i--; + } + } + }, + ai: { + effect: { + player_use: function (card, player, target) { + if (typeof card != "object") return; + var storage = player.getStorage("olddcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if ( + get.suit(card, player) == storage[i * 3 + 1] && + storage[i * 3 + 2] == 1 && + !player.canSave(player) && + !get.tag(card, "save") + ) + return "zeroplayertarget"; + } + }, + }, + }, + }, + }, + }, + dcxiangmian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => + lib.skill.dcxiangmian.filterTarget(null, player, current) + ); + }, + filterTarget: function (card, player, target) { + return !player.getStorage("dcxiangmian").includes(target) && player != target; + }, + content: function () { + "step 0"; + target + .judge((card) => -2 / Math.sqrt(get.number(card, false))) + .set("judge2", (result) => (result.bool === false ? true : false)); + "step 1"; + player.markAuto("dcxiangmian", [target]); + target.addSkill("dcxiangmian_countdown"); + if (!target.storage["dcxiangmian_countdown"]) + target.storage["dcxiangmian_countdown"] = []; + [player.playerid, result.suit, result.number].forEach((i) => + target.storage["dcxiangmian_countdown"].push(i) + ); + target.markSkill("dcxiangmian_countdown"); + }, + intro: { content: "已对$发动过技能" }, + ai: { + expose: 0.3, + order: 10, + result: { target: -5 }, + }, + subSkill: { + countdown: { + trigger: { player: "useCardAfter" }, + mark: true, + marktext: "💀", + silent: true, + forced: true, + charlotte: true, + intro: { + markcount: function (storage) { + if (storage) { + var list = storage.filter((_, i) => i % 3 == 2); + return Math.min.apply(null, list); + } + }, + content: function (storage, player) { + if (!storage) return; + var str = "使用"; + str += + get.cnNumber( + Math.min.apply( + null, + storage.filter((_, i) => i % 3 == 2) + ) + ) + "张牌后,或使用一张"; + for (var i = 0; i < storage.length / 3; i++) { + str += get.translation(storage[i * 3 + 1]) + "、"; + } + str = str.slice(0, -1); + str += "后,失去等同于体力值的体力"; + return str; + }, + }, + filter: function (event, player) { + if (!player.getStorage("dcxiangmian_countdown").length) return false; + //return (player.getStorage('dcxiangmian_countdown').filter((_,i)=>i%3==1)).includes(get.suit(event.card,player)); + return true; + }, + content: function () { + "step 0"; + var storage = player.getStorage("dcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if (storage[i * 3 + 1] == get.suit(trigger.card, player)) { + storage[i * 3 + 2] = 0; + } else storage[i * 3 + 2]--; + } + player.markSkill("dcxiangmian_countdown"); + "step 1"; + var storage = player.getStorage("dcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if (storage[i * 3 + 2] <= 0) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + player.logSkill("dcxiangmian_countdown"); + player.storage["dcxiangmian_countdown"].splice(i * 3, 3); + if (!player.getStorage("dcxiangmian_countdown").length) { + player.removeSkill("dcxiangmian_countdown"); + } + if (player.hp > 0) player.loseHp(player.hp); + i--; + } + } + }, + ai: { + effect: { + player_use: function (card, player, target) { + if (typeof card != "object") return; + var storage = player.getStorage("dcxiangmian_countdown"); + for (var i = 0; i < storage.length / 3; i++) { + if ( + (storage[i * 3 + 2] == 1 || + get.suit(card, player) == storage[i * 3 + 1]) && + !player.canSave(player) && + !get.tag(card, "save") + ) + return "zeroplayertarget"; + } + }, + }, + }, + }, + }, + }, + dctianji: { + audio: 2, + trigger: { global: "cardsDiscardAfter" }, + forced: true, + filter: function (event, player) { + var evt = event.getParent().relatedEvent; + return evt && evt.name == "judge" && event.cards.filterInD("d").length; + }, + content: function () { + var card = trigger.cards[0], + cards = [], + func = ["type2", "suit", "number"]; + for (var fn of func) { + var cardx = get.cardPile2((cardxx) => { + if (get[fn](card, player) == get[fn](cardxx, player) && !cards.includes(cardxx)) { + return true; + } + }); + if (cardx) cards.push(cardx); + } + /*if(cards.length&&!player.isMaxHandcard(true)) player.draw(); + else*/ if (cards.length) player.gain(cards, "gain2"); + }, + }, + //赵直 + dctongguan: { + trigger: { + global: "phaseBegin", + }, + filter: function (event, player) { + return ( + event.player + .getAllHistory() + .filter((history) => { + return history.isMe && !history.isSkipped; + }) + .indexOf(event.player.getHistory()) === 0 && + lib.skill.dctongguan.derivation.some((i) => { + return (player.getStorage("dctongguan")[i] || 0) < 2; + }) + ); + }, + forced: true, + locked: false, + logTarget: "player", + derivation: [ + "dctongguan_wuyong", + "dctongguan_gangying", + "dctongguan_duomou", + "dctongguan_guojue", + "dctongguan_renzhi", + ], + content: function () { + "step 0"; + var skills = lib.skill.dctongguan.derivation.slice(); + player + .chooseControl( + skills.filter((i) => { + return (player.getStorage("dctongguan")[i] || 0) < 2; + }) + ) + .set( + "choiceList", + skills.map((i) => { + var info = ""; + switch (player.getStorage("dctongguan")[i]) { + case 1: + info = ' style="opacity:0.65;"'; + break; + case 2: + info = ' style="text-decoration:line-through; opacity:0.3;"'; + break; + } + return ( + '
              「' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "」
              " + + "" + + get.skillInfoTranslation(i, player) + + "(已选过" + + get.cnNumber(player.getStorage("dctongguan")[i] || 0) + + "次)" + + "" + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "统观:为" + get.translation(trigger.player) + "选择一个属性") + .set("ai", function () { + var controls = _status.event.controls, + target = _status.event.getTrigger().player; + var str = target + .getSkills(null, false, false) + .map((i) => get.skillInfoTranslation(i)) + .join(""); + var choices = []; + if ( + controls.includes("dctongguan_wuyong") && + /你对\S{1,15}造成\S{1,10}伤害/.test(str) + ) + choices.push("dctongguan_wuyong"); + if ( + controls.includes("dctongguan_gangying") && + /回复\S{1,5}体力/.test(str) && + _status.event.player.getFriends().length + ) + choices.push("dctongguan_gangying"); + if ( + controls.includes("dctongguan_duomou") && + /你(可|可以)?摸\S{1,3}张牌/.test(str) + ) + choices.push("dctongguan_duomou"); + if ( + controls.includes("dctongguan_guojue") && + /(当【过河拆桥】使用|((弃置|获得)\S{1,5}其他角色\S{1,7}牌|))/.test(str) + ) + choices.push("dctongguan_guojue"); + if ( + controls.includes("dctongguan_renzhi") && + /交给\S{0,5}其他角色/.test(str) && + _status.event.player.getFriends().length + ) + choices.push("dctongguan_renzhi"); + if (choices.length) return choices.randomGet(); + return _status.event.controls.randomGet(); + }); + "step 1"; + if (result.control) { + var skill = result.control; + var func = lib.skill.dctongguan.localMark; + if (event.player == game.me) func(skill, trigger.player); + else if (event.isOnline()) player.send(func, skill, trigger.player); + // game.log(player,'为',trigger.player,'选择了','#g「'+get.translation(skill)+'」','属性'); + game.log(player, "为", trigger.player, "选择了", "#g一个属性"); + // player.popup(skill); + trigger.player.addSkill(skill); + if (!player.storage.dctongguan) player.storage.dctongguan = {}; + if (!player.storage.dctongguan[skill]) player.storage.dctongguan[skill] = 0; + player.storage.dctongguan[skill]++; + } + }, + localMark: function (skill, player) { + var name = skill, + info; + if (player.marks[name]) player.updateMarks(); + if (lib.skill[name]) info = lib.skill[name].intro; + if (!info) return; + if (player.marks[name]) player.marks[name].info = info; + else player.marks[name] = player.mark(name, info); + player.updateMarks(); + }, + ai: { + combo: "dcmengjie", + }, + subSkill: { + forceFinish: { charlotte: true }, + wuyong: { + marktext: "勇", + intro: { + name: "武勇", + content: "属性目标:造成伤害", + }, + charlotte: true, + silent: true, + nopop: true, + }, + gangying: { + marktext: "刚", + intro: { + name: "刚硬", + content: "属性目标:回复体力,或于得到牌后手牌数大于体力值", + }, + charlotte: true, + silent: true, + forced: true, + nopop: true, + lastDo: true, + trigger: { player: "gainEnd" }, + filter: function (event, player) { + return player.countCards("h") > player.hp; + }, + content: function () { + trigger._dctongguan_gangying = true; + }, + }, + duomou: { + marktext: "谋", + intro: { + name: "多谋", + content: "属性目标:于摸牌阶段外摸牌", + }, + charlotte: true, + silent: true, + nopop: true, + }, + guojue: { + marktext: "决", + intro: { + name: "果决", + content: "属性目标:弃置或获得其他角色牌", + }, + charlotte: true, + silent: true, + nopop: true, + }, + renzhi: { + marktext: "仁", + intro: { + name: "仁智", + content: "属性目标:交给其他角色牌", + }, + charlotte: true, + silent: true, + nopop: true, + }, + }, + }, + dcmengjie: { + trigger: { + global: "phaseEnd", + }, + forced: true, + direct: true, + locked: false, + filter: function (event, player) { + var target = event.player; + if ( + (target.hasSkill("dctongguan_gangying") && + (target.hasHistory("gain", function (evt) { + return evt._dctongguan_gangying == true; + }) || + game.getGlobalHistory("changeHp", function (evt) { + return ( + evt.player == target && + (evt.getParent().name == "recover" || + target.countCards("h") > target.hp) + ); + }).length > 0)) || + (target.hasSkill("dctongguan_wuyong") && target.getHistory("sourceDamage").length) || + (target.hasSkill("dctongguan_duomou") && + target.getHistory( + "gain", + (evt) => + evt.getParent().name == "draw" && + evt.getParent("phaseDraw").name != "phaseDraw" + ).length) + ) { + return true; + } + var guojue = false, + renzhi = false; + game.countPlayer2((current) => { + if (current == target) return false; + if ( + !guojue && + current.hasHistory("lose", (evt) => { + if (evt.type == "discard") { + if ((evt.discarder || evt.getParent(2).player) != target) return false; + if (!evt.getl(current).cards2.length) return false; + return true; + } else if (evt.type == "gain") { + var evtx = evt.getParent(); + if (evtx.giver || evtx.getParent().name == "gift") return false; + var cards = evtx.getg(target); + if (!cards.length) return false; + var cards2 = evtx.getl(current).cards2; + for (var card of cards2) { + if (cards.includes(card)) return true; + } + } + return false; + }) + ) + guojue = true; + if ( + !renzhi && + current.hasHistory("gain", (evt) => { + if (evt.giver != target || evt.getParent().name == "gift") return false; + return evt.cards.length; + }) + ) + renzhi = true; + }); + return ( + (target.hasSkill("dctongguan_guojue") && guojue) || + (target.hasSkill("dctongguan_renzhi") && renzhi) + ); + }, + rules: [ + (target) => target.getHistory("sourceDamage").length, + (target) => + target.hasHistory("gain", function (evt) { + return evt._dctongguan_gangying; + }) || + game.getGlobalHistory("changeHp", function (evt) { + return evt.player == target && evt.getParent().name == "recover"; + }).length > 0 || + target.countCards("h") > target.hp, + (target) => + target.getHistory( + "gain", + (evt) => + evt.getParent().name == "draw" && + evt.getParent("phaseDraw").name != "phaseDraw" + ).length, + (target, bool) => bool, + (target, bool) => bool, + ], + content: function () { + "step 0"; + event.nowProperty = 0; + var target = trigger.player; + var guojue = false, + renzhi = false; + game.countPlayer2((current) => { + if (current == target) return false; + if ( + !guojue && + current.hasHistory("lose", (evt) => { + if (evt.type == "discard") { + if ((evt.discarder || evt.getParent(2).player) != target) return false; + if (!evt.getl(current).cards2.length) return false; + return true; + } else if (evt.type == "gain") { + var evtx = evt.getParent(); + if (evtx.giver || evtx.getParent().name == "gift") return false; + var cards = evtx.getg(target); + if (!cards.length) return false; + var cards2 = evtx.getl(current).cards2; + for (var card of cards2) { + if (cards.includes(card)) return true; + } + } + return false; + }) + ) + guojue = true; + if ( + !renzhi && + current.hasHistory("gain", (evt) => { + if (evt.giver != target || evt.getParent().name == "gift") return false; + return evt.cards.length; + }) + ) + renzhi = true; + }); + event.guojue = guojue; + event.renzhi = renzhi; + "step 1"; + if (event.nowProperty >= 5) { + event.finish(); + return; + } + var skills = lib.skill.dctongguan.derivation; + if ( + trigger.player.hasSkill(skills[event.nowProperty]) && + lib.skill.dcmengjie.rules[event.nowProperty]( + trigger.player, + event[event.nowProperty == 3 ? "guojue" : "renzhi"] + ) + ) { + event.goto(2 + event.nowProperty * 2); } else event.redo(); event.nowProperty++; - 'step 2' - if(!game.hasPlayer(current=>current!=player)) event._result={bool:false}; - else player.chooseTarget('梦解:对一名其他角色造成1点伤害',true,lib.filter.notMe).set('ai',target=>get.damageEffect(target,player,player)); - 'step 3' - if(result.bool){ - player.logSkill('dcmengjie',result.targets[0]); + "step 2"; + if (!game.hasPlayer((current) => current != player)) event._result = { bool: false }; + else + player + .chooseTarget("梦解:对一名其他角色造成1点伤害", true, lib.filter.notMe) + .set("ai", (target) => get.damageEffect(target, player, player)); + "step 3"; + if (result.bool) { + player.logSkill("dcmengjie", result.targets[0]); result.targets[0].damage(); } game.delayx(); event.goto(1); - 'step 4' - if(game.hasPlayer(target=>target!=player&&target.isDamaged())) player.chooseTarget('梦解:令一名角色回复1点体力',function(card,player,target){ - return target.isDamaged(); - }).set('ai',target=>get.recoverEffect(target,player,player)); - else event._result={bool:false}; - 'step 5' - if(result.bool){ - player.logSkill('dcmengjie',result.targets[0]); + "step 4"; + if (game.hasPlayer((target) => target != player && target.isDamaged())) + player + .chooseTarget("梦解:令一名角色回复1点体力", function (card, player, target) { + return target.isDamaged(); + }) + .set("ai", (target) => get.recoverEffect(target, player, player)); + else event._result = { bool: false }; + "step 5"; + if (result.bool) { + player.logSkill("dcmengjie", result.targets[0]); result.targets[0].recover(); } game.delayx(); event.goto(1); - 'step 6' - player.logSkill('dcmengjie'); + "step 6"; + player.logSkill("dcmengjie"); player.draw(2); - 'step 7' + "step 7"; game.delayx(); event.goto(1); - 'step 8' - if(game.hasPlayer(target=>target.countDiscardableCards(player,'hej'))) player.chooseTarget('梦解:弃置一名角色区域内至多两张牌',true,(card,player,target)=>{ - return target.countDiscardableCards(player,'hej'); - }).set('ai',target=>get.effect(target,{name:'guohe'},player,player)); - else event._result={bool:false}; - 'step 9' - if(result.bool){ - player.logSkill('dcmengjie',result.targets[0]); - player.discardPlayerCard(result.targets[0],true,'hej',[1,2]); + "step 8"; + if (game.hasPlayer((target) => target.countDiscardableCards(player, "hej"))) + player + .chooseTarget( + "梦解:弃置一名角色区域内至多两张牌", + true, + (card, player, target) => { + return target.countDiscardableCards(player, "hej"); + } + ) + .set("ai", (target) => get.effect(target, { name: "guohe" }, player, player)); + else event._result = { bool: false }; + "step 9"; + if (result.bool) { + player.logSkill("dcmengjie", result.targets[0]); + player.discardPlayerCard(result.targets[0], true, "hej", [1, 2]); } game.delayx(); event.goto(1); - 'step 10' - if(!game.hasPlayer(current=>current!=player)) event._result={bool:false}; - else player.chooseTarget('梦解:令一名其他角色将手牌补至上限',true,(card,player,target)=>{ - return target!=player; - }).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(target.hasSkillTag('nogain')) att/=6; - if(att>2){ - return Math.min(5,target.maxHp)-target.countCards('h'); - } - return att/3; - }); - 'step 11' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcmengjie',target); - var num=Math.min(5,target.maxHp-target.countCards('h')); + "step 10"; + if (!game.hasPlayer((current) => current != player)) event._result = { bool: false }; + else + player + .chooseTarget( + "梦解:令一名其他角色将手牌补至上限", + true, + (card, player, target) => { + return target != player; + } + ) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 6; + if (att > 2) { + return Math.min(5, target.maxHp) - target.countCards("h"); + } + return att / 3; + }); + "step 11"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcmengjie", target); + var num = Math.min(5, target.maxHp - target.countCards("h")); target.draw(num); } game.delayx(); event.goto(1); - } + }, + ai: { + combo: "dctongguan", + }, }, //刘晔 - dcpoyuan:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:['phaseZhunbeiBegin','enterGame'], + dcpoyuan: { + audio: 2, + trigger: { + global: "phaseBefore", + player: ["phaseZhunbeiBegin", "enterGame"], }, - filter:function(event,player){ - if(event.name=='phase'&&game.phaseNumber>0) return false; - if(player.getEquip('pilitoushiche')){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countDiscardableCards(player,'he')>0; + filter: function (event, player) { + if (event.name == "phase" && game.phaseNumber > 0) return false; + if (player.getEquip("pilitoushiche")) { + return game.hasPlayer(function (current) { + return current != player && current.countDiscardableCards(player, "he") > 0; }); - } - else{ + } else { return player.hasEquipableSlot(5); } }, - direct:true, - content:function(){ - 'step 0' - if(player.getEquip('pilitoushiche')){ + direct: true, + content: function () { + "step 0"; + if (player.getEquip("pilitoushiche")) { event.goto(2); - player.chooseTarget(get.prompt('dcpoyuan'),'弃置一名其他角色的至多两张牌',function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player,cards=target.getDiscardableCards(player,'he'); - var att=get.attitude(player,target); - if(att<0&&target.hasSkillTag('noe')) att/=2; - var zheng=[],fu=[]; - for(var i of cards){ - var val=get.value(i,target); - if(val>0) zheng.push(i); - else fu.push(i); - } - zheng.sort((a,b)=>get.value(b,target)-get.value(a,target)); - fu.sort((a,b)=>get.value(b,target)-get.value(a,target)); - zheng=zheng.slice(0,2); - fu=fu.slice(0,2); - var eff1=0,eff2=0; - for(var i of zheng) eff1+=get.value(i,target); - for(var i of fu){ - if(get.position(i)=='e') eff2+=(1-get.value(i,target)); - } - return -att*Math.max(eff1,eff2); - }); + player + .chooseTarget( + get.prompt("dcpoyuan"), + "弃置一名其他角色的至多两张牌", + function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + cards = target.getDiscardableCards(player, "he"); + var att = get.attitude(player, target); + if (att < 0 && target.hasSkillTag("noe")) att /= 2; + var zheng = [], + fu = []; + for (var i of cards) { + var val = get.value(i, target); + if (val > 0) zheng.push(i); + else fu.push(i); + } + zheng.sort((a, b) => get.value(b, target) - get.value(a, target)); + fu.sort((a, b) => get.value(b, target) - get.value(a, target)); + zheng = zheng.slice(0, 2); + fu = fu.slice(0, 2); + var eff1 = 0, + eff2 = 0; + for (var i of zheng) eff1 += get.value(i, target); + for (var i of fu) { + if (get.position(i) == "e") eff2 += 1 - get.value(i, target); + } + return -att * Math.max(eff1, eff2); + }); + } else { + player + .chooseBool(get.prompt("dcpoyuan"), "装备一张【霹雳投石车】") + .set("ai", function () { + return true; + }); } - else{ - player.chooseBool(get.prompt('dcpoyuan'),'装备一张【霹雳投石车】').set('ai',function(){ - return true; - }) - } - 'step 1' - if(result.bool){ - player.logSkill('dcpoyuan'); - var card=game.createCard('pilitoushiche','diamond',9); + "step 1"; + if (result.bool) { + player.logSkill("dcpoyuan"); + var card = game.createCard("pilitoushiche", "diamond", 9); player.$gain2(card); game.delayx(); player.equip(card); } event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcpoyuan',target); - player.discardPlayerCard(target,true,'he',[1,2]) + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcpoyuan", target); + player.discardPlayerCard(target, true, "he", [1, 2]); } }, }, - dchuace:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return event.dchuace&&event.dchuace.length>0&&player.countCards('hs')>0; + dchuace: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return event.dchuace && event.dchuace.length > 0 && player.countCards("hs") > 0; }, - onChooseToUse:function(event){ - if(game.online||event.dchuace) return; - var list=lib.inpile.filter(function(i){ - return get.type(i)=='trick'&&lib.filter.filterCard({name:i},event.player,event); + onChooseToUse: function (event) { + if (game.online || event.dchuace) return; + var list = lib.inpile.filter(function (i) { + return ( + get.type(i) == "trick" && lib.filter.filterCard({ name: i }, event.player, event) + ); }); - if(!list.length){ - event.set('dchuace',list); + if (!list.length) { + event.set("dchuace", list); return; } - var history=_status.globalHistory; - var stop=false; - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - if(!stop){ - if(evt.isRound) stop=true; + var history = _status.globalHistory; + var stop = false; + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + if (!stop) { + if (evt.isRound) stop = true; continue; - } - else{ - for(var j of evt.useCard) list.remove(j.card.name); - if(evt.isRound) break; + } else { + for (var j of evt.useCard) list.remove(j.card.name); + if (evt.isRound) break; } } - event.set('dchuace',list); + event.set("dchuace", list); }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('画策',[event.dchuace,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("画策", [event.dchuace, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player,card={name:button.link[2]}; + check: function (button) { + var player = _status.event.player, + card = { name: button.link[2] }; return player.getUseValue(card); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'dchuace', - viewAs:{name:links[0][2]}, - ai1:(card)=>7-get.value(card), - filterCard:true, - position:'hs', - popname:true, - } + audio: "dchuace", + viewAs: { name: links[0][2] }, + ai1: (card) => 7 - get.value(card), + filterCard: true, + position: "hs", + popname: true, + }; }, - prompt:function(links,player){ - return '将一张手牌当做【'+get.translation(links[0][2])+'】使用'; + prompt: function (links, player) { + return "将一张手牌当做【" + get.translation(links[0][2]) + "】使用"; }, }, - ai:{ - order:6, - result:{player:1}, + ai: { + order: 6, + result: { player: 1 }, }, - subSkill:{backup:{}}, + subSkill: { backup: {} }, }, - pilitoushiche:{ - trigger:{player:['useCard','respond']}, - forced:true, - equipSkill:true, - filter:function(event,player){ - return get.type(event.card)=='basic'; + pilitoushiche: { + trigger: { player: ["useCard", "respond"] }, + forced: true, + equipSkill: true, + filter: function (event, player) { + return get.type(event.card) == "basic"; }, - content:function(){ - if(player==_status.currentPhase) trigger.baseDamage++; + content: function () { + if (player == _status.currentPhase) trigger.baseDamage++; else player.draw(); }, - mod:{ - targetInRange:function(card,player){ - if(get.type(card)=='basic'&&player==_status.currentPhase) return true; + mod: { + targetInRange: function (card, player) { + if (get.type(card) == "basic" && player == _status.currentPhase) return true; }, - } + }, }, //路易 - dcyaoyi:{ - audio:2, - getZhuanhuanji:function(player,bool){ - var skills=player.getSkills(null,false,false).filter(function(i){ - return get.is.zhuanhuanji(i,player); + dcyaoyi: { + audio: 2, + getZhuanhuanji: function (player, bool) { + var skills = player.getSkills(null, false, false).filter(function (i) { + return get.is.zhuanhuanji(i, player); }); - if(!bool) return skills; - if(!skills.length) return 'none'; - var state=lib.skill.dcyaoyi.getState(player,skills[0]); - for(var i=1;i0&&!player.getStat('skill').dcshoutan; + dcshoutan: { + audio: 2, + enable: "phaseUse", + position: "h", + filter: function (event, player) { + if (player.hasSkill("dcyaoyi")) + return !player.hasSkill("dcshoutan_blocker", null, null, false); + return player.countCards("h") > 0 && !player.getStat("skill").dcshoutan; }, - selectCard:function(){ - if(_status.event.player.hasSkill('dcyaoyi')) return [0,1]; - return [1,1]; + selectCard: function () { + if (_status.event.player.hasSkill("dcyaoyi")) return [0, 1]; + return [1, 1]; }, - filterCard:function(card,player){ - if(player.hasSkill('dcyaoyi')) return false; - var color=get.color(card,player); - if(player.storage.dcshoutan) return color=='black'; - return color!='black'; + filterCard: function (card, player) { + if (player.hasSkill("dcyaoyi")) return false; + var color = get.color(card, player); + if (player.storage.dcshoutan) return color == "black"; + return color != "black"; }, - prompt:function(){ - var player=_status.event.player; - if(player.hasSkill('dcyaoyi')) return '点击“确认”来变更转换技状态'; - if(player.storage.dcshoutan) return '弃置一张黑色手牌,变更转换技状态'; - return '弃置一张非黑色手牌,变更转换技状态'; + prompt: function () { + var player = _status.event.player; + if (player.hasSkill("dcyaoyi")) return "点击“确认”来变更转换技状态"; + if (player.storage.dcshoutan) return "弃置一张黑色手牌,变更转换技状态"; + return "弃置一张非黑色手牌,变更转换技状态"; }, - check:function(card){ - return 11-get.value(card); + check: function (card) { + return 11 - get.value(card); }, - content:function(){ - player.changeZhuanhuanji('dcshoutan'); - player.addTempSkill('dcshoutan_blocker',{player:['useCard1','useSkillBegin','phaseUseEnd']}); + content: function () { + player.changeZhuanhuanji("dcshoutan"); + player.addTempSkill("dcshoutan_blocker", { + player: ["useCard1", "useSkillBegin", "phaseUseEnd"], + }); }, - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content:function(storage,player){ - if(storage) return '转换技。出牌阶段限一次,你可以弃置一张黑色手牌。'; - return '转换技。出牌阶段限一次,你可以弃置一张不为黑色的手牌。'; + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content: function (storage, player) { + if (storage) return "转换技。出牌阶段限一次,你可以弃置一张黑色手牌。"; + return "转换技。出牌阶段限一次,你可以弃置一张不为黑色的手牌。"; }, }, - ai:{ - order:0.1, - result:{ - player:function(player){ - var base=0; - if(ui.selected.cards.length) base=get.value(ui.selected.cards[0]); - var status=player.storage.dcshoutan; - var cards=player.getCards('hs',function(card){ + ai: { + order: 0.1, + result: { + player: function (player) { + var base = 0; + if (ui.selected.cards.length) base = get.value(ui.selected.cards[0]); + var status = player.storage.dcshoutan; + var cards = player.getCards("hs", function (card) { return !ui.selected.cards.includes(card); }); - for(var card of cards){ - var val1=player.getUseValue(card,null,true); - player.storage.dcshoutan=!status; - var val2=0; - try{ - val2=player.getUseValue(card,null,true); - }catch(e){ - player.storage.dcshoutan=status; + for (var card of cards) { + var val1 = player.getUseValue(card, null, true); + player.storage.dcshoutan = !status; + var val2 = 0; + try { + val2 = player.getUseValue(card, null, true); + } catch (e) { + player.storage.dcshoutan = status; } - player.storage.dcshoutan=status; - if(val2>val1) base-=(val2-val1); + player.storage.dcshoutan = status; + if (val2 > val1) base -= val2 - val1; } - if(base<0) return 1; + if (base < 0) return 1; return 0; }, }, }, - subSkill:{blocker:{charlotte:true}}, + subSkill: { blocker: { charlotte: true } }, }, - dcfuxue:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.hp>0&&ui.discardPile.childNodes.length>0; + dcfuxue: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.hp > 0 && ui.discardPile.childNodes.length > 0; }, - content:function(){ - 'step 0' - var cards=Array.from(ui.discardPile.childNodes); - var gains=cards.slice(0); - var history=game.getAllGlobalHistory('cardMove',function(evt){ - if(evt.name=='lose') return evt.position==ui.discardPile; - return evt.name=='cardsDiscard'; + content: function () { + "step 0"; + var cards = Array.from(ui.discardPile.childNodes); + var gains = cards.slice(0); + var history = game.getAllGlobalHistory("cardMove", function (evt) { + if (evt.name == "lose") return evt.position == ui.discardPile; + return evt.name == "cardsDiscard"; }); - for(var i=history.length-1;i>=0;i--){ - var evt=history[i]; - var cards2=evt.cards.filter(function(card){ + for (var i = history.length - 1; i >= 0; i--) { + var evt = history[i]; + var cards2 = evt.cards.filter(function (card) { return cards.includes(card); }); - if(cards2.length){ - if(lib.skill.dcfuxue.isUse(evt)){ + if (cards2.length) { + if (lib.skill.dcfuxue.isUse(evt)) { gains.removeArray(cards2); } cards.removeArray(cards2); } - if(!cards.length) break; + if (!cards.length) break; } - if(gains.length){ - var num=player.hp; - player.chooseButton([ - '复学:选择获得'+(num>0?'至多':'')+get.cnNumber(num)+'张牌', - gains, - ],[1,num]).set('ai',function(button){ - var player=_status.event.player,card=button.link; - var getn=function(card){ - return player.countCards('h',card.name)+ui.selected.buttons.filter((button)=>button.link.name==card.name).length; - } - var val=player.getUseValue(card); - if(card.name=='tao'&&getn(card)>=player.getDamagedHp()) return 0; - if(card.name=='sha'&&getn(card)>=player.getCardUsable('sha')) return 0; - return val; - }); - } - else event.finish(); - 'step 1' - if(result.bool){ - player.logSkill('dcfuxue'); - player.gain(result.links,'gain2').gaintag.add('dcfuxue'); + if (gains.length) { + var num = player.hp; + player + .chooseButton( + [ + "复学:选择获得" + (num > 0 ? "至多" : "") + get.cnNumber(num) + "张牌", + gains, + ], + [1, num] + ) + .set("ai", function (button) { + var player = _status.event.player, + card = button.link; + var getn = function (card) { + return ( + player.countCards("h", card.name) + + ui.selected.buttons.filter((button) => button.link.name == card.name) + .length + ); + }; + var val = player.getUseValue(card); + if (card.name == "tao" && getn(card) >= player.getDamagedHp()) return 0; + if (card.name == "sha" && getn(card) >= player.getCardUsable("sha")) return 0; + return val; + }); + } else event.finish(); + "step 1"; + if (result.bool) { + player.logSkill("dcfuxue"); + player.gain(result.links, "gain2").gaintag.add("dcfuxue"); } }, - isUse:function(event){ - if(event.name!='cardsDiscard') return false; - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evt2=(evtx.relatedEvent||evtx.getParent()); - return (evt2.name=='phaseJudge'||evt2.name=='useCard'); + isUse: function (event) { + if (event.name != "cardsDiscard") return false; + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evt2 = evtx.relatedEvent || evtx.getParent(); + return evt2.name == "phaseJudge" || evt2.name == "useCard"; }, - group:'dcfuxue_draw', - subSkill:{ - draw:{ - audio:'dcfuxue', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('dcfuxue')) return num+0.5; + group: "dcfuxue_draw", + subSkill: { + draw: { + audio: "dcfuxue", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("dcfuxue")) + return num + 0.5; }, }, - filter:function(event,player){ - return player.hp>0&&!player.hasCard(function(card){ - return card.hasGaintag('dcfuxue'); - },'h'); + filter: function (event, player) { + return ( + player.hp > 0 && + !player.hasCard(function (card) { + return card.hasGaintag("dcfuxue"); + }, "h") + ); }, - content:function(){ + content: function () { player.draw(player.hp); }, }, }, }, //丁尚涴 - dcfengyan:{ - enable:'phaseUse', - usable:2, - chooseButton:{ - dialog:function(event,player){ - var dialog=ui.create.dialog('讽言:请选择一项','hidden'); - dialog.add([[ - ['gain','令一名体力值不大于你的其他角色交给你一张手牌'], - ['sha','视为对一名手牌数不大于你的其他角色使用一张【杀】'] - ],'textbutton']); + dcfengyan: { + enable: "phaseUse", + usable: 2, + chooseButton: { + dialog: function (event, player) { + var dialog = ui.create.dialog("讽言:请选择一项", "hidden"); + dialog.add([ + [ + ["gain", "令一名体力值不大于你的其他角色交给你一张手牌"], + ["sha", "视为对一名手牌数不大于你的其他角色使用一张【杀】"], + ], + "textbutton", + ]); return dialog; }, - filter:function(button,player){ - return !player.hasSkill('dcfengyan_'+button.link,null,null,false); + filter: function (button, player) { + return !player.hasSkill("dcfengyan_" + button.link, null, null, false); }, - check:function(button){ - var player=_status.event.player; - if(button.link=='gain'&&game.hasPlayer(function(current){ - return lib.skill.dcfengyan_gain.filterTarget(null,player,current)&&get.effect(current,'dcfengyan_gain',player,player)>0; - })) return 4; - if(button.link=='sha'&&game.hasPlayer(function(current){ - return lib.skill.dcfengyan_sha.filterTarget(null,player,current)&&get.effect(current,'dcfengyan_sha',player,player)>0; - })) return 4; + check: function (button) { + var player = _status.event.player; + if ( + button.link == "gain" && + game.hasPlayer(function (current) { + return ( + lib.skill.dcfengyan_gain.filterTarget(null, player, current) && + get.effect(current, "dcfengyan_gain", player, player) > 0 + ); + }) + ) + return 4; + if ( + button.link == "sha" && + game.hasPlayer(function (current) { + return ( + lib.skill.dcfengyan_sha.filterTarget(null, player, current) && + get.effect(current, "dcfengyan_sha", player, player) > 0 + ); + }) + ) + return 4; return 2; }, - backup:function(links){ - return get.copy(lib.skill['dcfengyan_'+links[0]]); + backup: function (links) { + return get.copy(lib.skill["dcfengyan_" + links[0]]); }, - prompt:function(links){ - if(links[0]=='gain') return '令一名体力值不大于你的其他角色交给你一张手牌'; - return '视为对一名手牌数不大于你的其他角色使用【杀】'; + prompt: function (links) { + if (links[0] == "gain") return "令一名体力值不大于你的其他角色交给你一张手牌"; + return "视为对一名手牌数不大于你的其他角色使用【杀】"; }, }, - ai:{ - order:10, - threaten:1.7, - result:{player:1}, + ai: { + order: 10, + threaten: 1.7, + result: { player: 1 }, }, - subSkill:{ - backup:{audio:'dcfengyan'}, - gain:{ - audio:'dcfengyan', - filterTarget:function(card,player,target){ - return target!=player&&target.hp<=player.hp&&target.countCards('h')>0; + subSkill: { + backup: { audio: "dcfengyan" }, + gain: { + audio: "dcfengyan", + filterTarget: function (card, player, target) { + return target != player && target.hp <= player.hp && target.countCards("h") > 0; }, - filterCard:()=>false, - selectCard:-1, - content:function(){ - 'step 0' - player.addTempSkill('dcfengyan_gain','phaseUseAfter'); - target.chooseCard('h',true,'交给'+get.translation(player)+'一张牌'); - 'step 1' - if(result.bool) target.give(result.cards,player); + filterCard: () => false, + selectCard: -1, + content: function () { + "step 0"; + player.addTempSkill("dcfengyan_gain", "phaseUseAfter"); + target.chooseCard("h", true, "交给" + get.translation(player) + "一张牌"); + "step 1"; + if (result.bool) target.give(result.cards, player); }, - ai:{ - tag:{ - loseCard:1, - gain:1, + ai: { + tag: { + loseCard: 1, + gain: 1, }, - result:{ - player:0.1, - target:-1, + result: { + player: 0.1, + target: -1, }, }, }, - sha:{ - audio:'dcfengyan', - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')<=player.countCards('h')&&player.canUse('sha',target,false); + sha: { + audio: "dcfengyan", + filterTarget: function (card, player, target) { + return ( + target != player && + target.countCards("h") <= player.countCards("h") && + player.canUse("sha", target, false) + ); }, - filterCard:()=>false, - selectCard:-1, - content:function(){ - player.addTempSkill('dcfengyan_sha','phaseUseAfter'); - player.useCard({ - name:'sha', - isCard:true, - },target,false); + filterCard: () => false, + selectCard: -1, + content: function () { + player.addTempSkill("dcfengyan_sha", "phaseUseAfter"); + player.useCard( + { + name: "sha", + isCard: true, + }, + target, + false + ); }, - ai:{ - result:{ - player:function(player,target){ - return get.effect(target,{ - name:'sha', - isCard:true, - },player,player); + ai: { + result: { + player: function (player, target) { + return get.effect( + target, + { + name: "sha", + isCard: true, + }, + player, + player + ); }, }, }, }, }, }, - dcfudao:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + dcfudao: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&game.hasPlayer((current)=>current!=player); + forced: true, + locked: false, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && + game.hasPlayer((current) => current != player) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(true,lib.filter.notMe,'抚悼:请选择一名“继子”','你或“继子”每回合首次使用牌指定对方为目标后各摸两张牌;杀死你或“继子”的角色称为“决裂”。你或“继子”对“决裂”造成的伤害+1。“决裂”对你使用牌后,其本回合内不能再使用牌。').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dcfudao',target); - game.log(target,'成为了',player,'的继子'); - player.addSkill('dcfudao_effect'); - target.addSkill('dcfudao_effect'); - player.markAuto('dcfudao_effect',[target]); - target.markAuto('dcfudao_effect',[player]); + content: function () { + "step 0"; + player + .chooseTarget( + true, + lib.filter.notMe, + "抚悼:请选择一名“继子”", + "你或“继子”每回合首次使用牌指定对方为目标后各摸两张牌;杀死你或“继子”的角色称为“决裂”。你或“继子”对“决裂”造成的伤害+1。“决裂”对你使用牌后,其本回合内不能再使用牌。" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dcfudao", target); + game.log(target, "成为了", player, "的继子"); + player.addSkill("dcfudao_effect"); + target.addSkill("dcfudao_effect"); + player.markAuto("dcfudao_effect", [target]); + target.markAuto("dcfudao_effect", [player]); } }, - group:'dcfudao_refuse', - subSkill:{ - effect:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - charlotte:true, - usable:1, - filter:function(event,player){ - var target=event.target; - if(player==target||!target.isIn()) return false; - return player.getStorage('dcfudao_effect').includes(target); + group: "dcfudao_refuse", + subSkill: { + effect: { + trigger: { player: "useCardToPlayered" }, + forced: true, + charlotte: true, + usable: 1, + filter: function (event, player) { + var target = event.target; + if (player == target || !target.isIn()) return false; + return player.getStorage("dcfudao_effect").includes(target); }, - logTarget:'target', - content:function(){ - 'step 0' - var list=[player,trigger.target]; + logTarget: "target", + content: function () { + "step 0"; + var list = [player, trigger.target]; list.sortBySeat(); - game.asyncDraw(list,2); - 'step 1' + game.asyncDraw(list, 2); + "step 1"; game.delayx(); }, - marktext:'继', - intro:{content:'已和$成为继母子关系'}, - group:['dcfudao_revenge','dcfudao_deadmark'], + marktext: "继", + intro: { content: "已和$成为继母子关系" }, + group: ["dcfudao_revenge", "dcfudao_deadmark"], }, - deadmark:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - lastDo:true, - silent:true, - filter:function(event,player){ - return get.itemtype(event.source)=='player'; + deadmark: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + lastDo: true, + silent: true, + filter: function (event, player) { + return get.itemtype(event.source) == "player"; }, - content:function(){ - trigger.source.markAuto('dcfudao_deadmark',[player]); + content: function () { + trigger.source.markAuto("dcfudao_deadmark", [player]); }, - marktext:'裂', - intro:{ - name:'决裂', - content:'你害死了$!', + marktext: "裂", + intro: { + name: "决裂", + content: "你害死了$!", }, }, - revenge:{ - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event,player){ - var storage1=event.player.getStorage('dcfudao_deadmark'),storage2=player.getStorage('dcfudao_effect'); - for(var i of storage1){ - if(storage2.includes(i)) return true; + revenge: { + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event, player) { + var storage1 = event.player.getStorage("dcfudao_deadmark"), + storage2 = player.getStorage("dcfudao_effect"); + for (var i of storage1) { + if (storage2.includes(i)) return true; } return false; }, - content:function(){ + content: function () { trigger.num++; }, - logTarget:'player', + logTarget: "player", }, - refuse:{ - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - var storage1=event.player.getStorage('dcfudao_deadmark'),storage2=player.getStorage('dcfudao_effect'); - for(var i of storage1){ - if(storage2.includes(i)) return true; + refuse: { + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + var storage1 = event.player.getStorage("dcfudao_deadmark"), + storage2 = player.getStorage("dcfudao_effect"); + for (var i of storage1) { + if (storage2.includes(i)) return true; } return false; }, - content:function(){ - trigger.player.addTempSkill('dcfudao_blocker'); + content: function () { + trigger.player.addTempSkill("dcfudao_blocker"); }, - logTarget:'player', + logTarget: "player", }, - blocker:{ - charlotte:true, - mod:{ - cardEnabled:()=>false, - cardSavable:()=>false, + blocker: { + charlotte: true, + mod: { + cardEnabled: () => false, + cardSavable: () => false, }, }, }, }, //全惠解 - dchuishu:{ - audio:2, - getList:function(player){ - if(!player.storage.dchuishu) return [3,1,2]; + dchuishu: { + audio: 2, + getList: function (player) { + if (!player.storage.dchuishu) return [3, 1, 2]; return player.storage.dchuishu.slice(0); }, - trigger:{player:'phaseDrawEnd'}, - content:function(){ - 'step 0' - var list=lib.skill.dchuishu.getList(player); - event.list=list; + trigger: { player: "phaseDrawEnd" }, + content: function () { + "step 0"; + var list = lib.skill.dchuishu.getList(player); + event.list = list; player.draw(list[0]); - 'step 1' - player.addTempSkill('dchuishu_effect'); - player.chooseToDiscard('h',true,event.list[1]); + "step 1"; + player.addTempSkill("dchuishu_effect"); + player.chooseToDiscard("h", true, event.list[1]); }, - onremove:true, - mark:true, - intro:{ - markcount:function(storage,player){ - var list=lib.skill.dchuishu.getList(player); - return Math.max.apply(Math,list); + onremove: true, + mark: true, + intro: { + markcount: function (storage, player) { + var list = lib.skill.dchuishu.getList(player); + return Math.max.apply(Math, list); }, - content:function(storage,player){ - var list=lib.skill.dchuishu.getList(player); - return '摸牌阶段结束时,你可以摸['+list[0]+']张牌。若如此做:你弃置['+list[1]+']张手牌,且当你于本回合内弃置第['+list[2]+']+1张牌后,你从弃牌堆中获得['+list[2]+']张非基本牌。'; + content: function (storage, player) { + var list = lib.skill.dchuishu.getList(player); + return ( + "摸牌阶段结束时,你可以摸[" + + list[0] + + "]张牌。若如此做:你弃置[" + + list[1] + + "]张手牌,且当你于本回合内弃置第[" + + list[2] + + "]+1张牌后,你从弃牌堆中获得[" + + list[2] + + "]张非基本牌。" + ); }, }, - subSkill:{ - effect:{ - charlotte:true, - audio:'dchuishu', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + subSkill: { + effect: { + charlotte: true, + audio: "dchuishu", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - var num=lib.skill.dchuishu.getList(player)[2]; - if(typeof num!='number') return false; - if(event.type!='discard'||event.getlx===false) return false; - var evt=event.getl(player); - if(evt.cards2.length==0) return false; - var prev=0,goon=true; - player.getHistory('lose',function(evt){ - if(!goon||evt.type!='discard') return false; - prev+=evt.cards2.length; - if(evt==event||event.getParent()==event){ - goon=false; + filter: function (event, player) { + var num = lib.skill.dchuishu.getList(player)[2]; + if (typeof num != "number") return false; + if (event.type != "discard" || event.getlx === false) return false; + var evt = event.getl(player); + if (evt.cards2.length == 0) return false; + var prev = 0, + goon = true; + player.getHistory("lose", function (evt) { + if (!goon || evt.type != "discard") return false; + prev += evt.cards2.length; + if (evt == event || event.getParent() == event) { + goon = false; return false; } }); - return prev>num; + return prev > num; }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - var num=lib.skill.dchuishu.getList(player)[2]; - var cards=[]; - for(var i=0;imax) max=i; + content: function () { + "step 0"; + var list = lib.skill.dchuishu.getList(player); + var min = list[0], + max = list[0]; + for (var i of list) { + if (i < min) min = i; + if (i > max) max = i; } - var exps=['摸牌数[','弃牌数[','目标牌数[']; - var choices_min=[],choices_max=[]; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current) current.classList.remove('bluebg'); - this.classList.add('bluebg'); - event._result.min=link; - }); + td.innerHTML = "" + min[i] + ""; + td.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) current.classList.remove("bluebg"); + this.classList.add("bluebg"); + event._result.min = link; + } + ); } dialog.content.appendChild(table); - dialog.addText('最大值-1'); - var table2=document.createElement('div'); - table2.classList.add('add-setting'); - table2.style.margin='0'; - table2.style.width='100%'; - table2.style.position='relative'; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current) current.classList.remove('bluebg'); - this.classList.add('bluebg'); - event._result.max=link; - }); + td.innerHTML = "" + max[i] + ""; + td.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) current.classList.remove("bluebg"); + this.classList.add("bluebg"); + event._result.max = link; + } + ); } dialog.content.appendChild(table2); - dialog.add('  '); + dialog.add("  "); event.dialog.open(); - event.switchToAuto=function(){ - event._result={ - bool:true, - min:min[0], - max:max[0], + event.switchToAuto = function () { + event._result = { + bool: true, + min: min[0], + max: max[0], }; event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok',function(link){ - var result=event._result; - if(!result.min||!result.max) return; - result.bool=true; + event.control = ui.create.control("ok", function (link) { + var result = event._result; + if (!result.min || !result.max) return; + result.bool = true; event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;i=5) return true; + dcligong: { + audio: 2, + juexingji: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + if (!player.hasSkill("dchuishu")) return false; + var list = lib.skill.dchuishu.getList(player); + for (var i of list) { + if (i >= 5) return true; } return false; }, - skillAnimation:true, - animationColor:'wood', - content:function(){ - 'step 0' - player.awakenSkill('dcligong'); + skillAnimation: true, + animationColor: "wood", + content: function () { + "step 0"; + player.awakenSkill("dcligong"); player.gainMaxHp(); player.recover(); - 'step 1' - player.removeSkills('dcyishu'); - 'step 2' + "step 1"; + player.removeSkills("dcyishu"); + "step 2"; var list; - if(_status.characterlist){ - list=[]; - for(var i=0;i<_status.characterlist.length;i++){ - var name=_status.characterlist[i]; - if(lib.character[name][1]=='wu'&&(lib.character[name][0]=='female'||lib.character[name][0]=='double')) list.push(name); + if (_status.characterlist) { + list = []; + for (var i = 0; i < _status.characterlist.length; i++) { + var name = _status.characterlist[i]; + if ( + lib.character[name][1] == "wu" && + (lib.character[name][0] == "female" || lib.character[name][0] == "double") + ) + list.push(name); } - } - else if(_status.connectMode){ - list=get.charactersOL(function(i){ - return lib.character[i][1]!='wu'||(lib.character[i][0]!='female'&&lib.character[i][0]!='double'); + } else if (_status.connectMode) { + list = get.charactersOL(function (i) { + return ( + lib.character[i][1] != "wu" || + (lib.character[i][0] != "female" && lib.character[i][0] != "double") + ); + }); + } else { + list = get.gainableCharacters(function (info) { + return info[1] == "wu" && (info[0] == "female" || info[0] == "double"); }); } - else{ - list=get.gainableCharacters(function(info){ - return info[1]=='wu'&&(info[0]=='female'||info[0]=='double'); - }); - } - var players=game.players.concat(game.dead); - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(!this.classList.contains('bluebg')){ - if(rSkill.length>=2) return; + td.innerHTML = "" + get.translation(skills[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (!this.classList.contains("bluebg")) { + if (rSkill.length >= 2) return; rSkill.add(link); - this.classList.add('bluebg'); - } - else{ - this.classList.remove('bluebg'); + this.classList.add("bluebg"); + } else { + this.classList.remove("bluebg"); rSkill.remove(link); } }); } dialog.content.appendChild(table); - dialog.add('  '); + dialog.add("  "); dialog.open(); - event.switchToAuto=function(){ + event.switchToAuto = function () { event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok',function(link){ + event.control = ui.create.control("ok", function (link) { event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;i0; + dcfanyin: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return ui.cardPile.childNodes.length > 0; }, - frequent:true, - locked:false, - content:function(){ - 'step 0' - var card=false; - if(typeof event.num!='number'){ - var num=false; - for(var i=0;i'+choiceList[0]+'(已强化)'); - } - else{ - list.push('选项'+get.cnNumber(i,true)); - if(num) choiceList[i-1]+=('(已强化'+num+'次)'); + var list = []; + var card = player.getEquip("dagongche"); + for (var i = 1; i <= 3; i++) { + var key = "大攻车选项" + get.cnNumber(i, true); + var num = card.storage[key]; + if (i == 1) { + if (!num) list.push("选项一"); + else + choiceList[0] = + '' + choiceList[0] + "(已强化)"; + } else { + list.push("选项" + get.cnNumber(i, true)); + if (num) choiceList[i - 1] += "(已强化" + num + "次)"; } } - player.chooseControl(list,'cancel2').set('prompt','是否发动【陷筑】强化【大攻车】?').set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,controls=_status.event.controls.slice(0); - var getval=function(choice){ - var card=player.getEquip('dagongche'); - if(choice=='选项一'){ - card.storage.大攻车选项一=1; - var goon=false; - if(game.hasPlayer(function(current){ - var eff1=0,eff2=0; - var cardx={name:'sha',isCard:true}; - if(player.canUse(cardx,current)) eff1=get.effect(current,cardx,player,player); - cardx.storage={dagongche:true}; - if(player.canUse(cardx,current)) eff2=get.effect(current,cardx,player,player); - return (eff2>eff1); - })) goon=true; - delete card.storage.大攻车选项一; - if(goon) return 5; + player + .chooseControl(list, "cancel2") + .set("prompt", "是否发动【陷筑】强化【大攻车】?") + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + controls = _status.event.controls.slice(0); + var getval = function (choice) { + var card = player.getEquip("dagongche"); + if (choice == "选项一") { + card.storage.大攻车选项一 = 1; + var goon = false; + if ( + game.hasPlayer(function (current) { + var eff1 = 0, + eff2 = 0; + var cardx = { name: "sha", isCard: true }; + if (player.canUse(cardx, current)) + eff1 = get.effect(current, cardx, player, player); + cardx.storage = { dagongche: true }; + if (player.canUse(cardx, current)) + eff2 = get.effect(current, cardx, player, player); + return eff2 > eff1; + }) + ) + goon = true; + delete card.storage.大攻车选项一; + if (goon) return 5; + return 0; + } else if (choice == "选项二") { + var num = 1; + if (card.storage.大攻车选项二) num += card.storage.大攻车选项二; + var cardx = { name: "sha", isCard: true }; + if ( + game.countPlayer(function (current) { + return ( + player.canUse(cardx, current) && + get.effect(current, cardx, player, player) > 0 + ); + }) > num + ) + return 2; + } else if (choice == "选项三") return 1; return 0; + }; + var eff = 0, + current = "cancel2"; + for (var i of controls) { + var effx = getval(i); + if (effx > eff) { + eff = effx; + current = i; + } } - else if(choice=='选项二'){ - var num=1; - if(card.storage.大攻车选项二) num+=card.storage.大攻车选项二; - var cardx={name:'sha',isCard:true}; - if(game.countPlayer(function(current){ - return player.canUse(cardx,current)&&get.effect(current,cardx,player,player)>0; - })>num) return 2; - } - else if(choice=='选项三') return 1; - return 0; - }; - var eff=0,current='cancel2'; - for(var i of controls){ - var effx=getval(i); - if(effx>eff){ - eff=effx; - current=i; - } - } - return current; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('dcxianzhu'); - var card=player.getEquip('dagongche'),key='大攻车'+result.control; - if(!card.storage[key]) card.storage[key]=0; + return current; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("dcxianzhu"); + var card = player.getEquip("dagongche"), + key = "大攻车" + result.control; + if (!card.storage[key]) card.storage[key] = 0; card.storage[key]++; lib.skill.dcwanglu.broadcast(player); } }, - }, - dcchaixie:{ - audio:2, - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + ai: { + combo: "dcwanglu", }, - forced:true, - filter:function(event,player){ - var evt=event.getl(player); - if(!evt||!evt.es||!evt.es.length) return false; - for(var card of evt.es){ - if(card.name=='dagongche'){ - for(var i=1;i<=3;i++){ - if(card.storage['大攻车选项'+get.cnNumber(i,true)]) return true; + }, + dcchaixie: { + audio: 2, + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + forced: true, + filter: function (event, player) { + var evt = event.getl(player); + if (!evt || !evt.es || !evt.es.length) return false; + for (var card of evt.es) { + if (card.name == "dagongche") { + for (var i = 1; i <= 3; i++) { + if (card.storage["大攻车选项" + get.cnNumber(i, true)]) return true; } } } return false; }, - content:function(){ - var num=0; - var evt=trigger.getl(player); - for(var card of evt.es){ - if(card.name=='dagongche'){ - for(var i=1;i<=3;i++){ - var key='大攻车选项'+get.cnNumber(i,true); - if(card.storage[key]) num+=card.storage[key]; + content: function () { + var num = 0; + var evt = trigger.getl(player); + for (var card of evt.es) { + if (card.name == "dagongche") { + for (var i = 1; i <= 3; i++) { + var key = "大攻车选项" + get.cnNumber(i, true); + if (card.storage[key]) num += card.storage[key]; } } } player.draw(num); }, + ai: { + combo: "dcwanglu", + }, }, - dagongche_skill:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - var cardx={ - name:'sha', - isCard:true, - storage:{dagongche:true}, + dagongche_skill: { + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + var cardx = { + name: "sha", + isCard: true, + storage: { dagongche: true }, }; return player.hasUseTarget(cardx); }, - equipSkill:true, - content:function(){ - var card={ - name:'sha', - isCard:true, - storage:{dagongche:true}, + equipSkill: true, + content: function () { + var card = { + name: "sha", + isCard: true, + storage: { dagongche: true }, }; lib.skill.dcwanglu.broadcast(player); - player.chooseUseTarget(card,'大攻车:是否视为使用【杀】?',false).logSkill='dagongche_skill'; + player.chooseUseTarget(card, "大攻车:是否视为使用【杀】?", false).logSkill = + "dagongche_skill"; }, - mod:{ - targetInRange:function(card,player,target){ - if(card.storage&&card.storage.dagongche){ - var cardx=player.getEquip('dagongche'); - if(cardx&&cardx.storage.大攻车选项一) return true; + mod: { + targetInRange: function (card, player, target) { + if (card.storage && card.storage.dagongche) { + var cardx = player.getEquip("dagongche"); + if (cardx && cardx.storage.大攻车选项一) return true; } }, - selectTarget:function(card,player,range){ - if(card.storage&&card.storage.dagongche&&range[1]!=-1){ - var cardx=player.getEquip('dagongche'); - if(cardx&&cardx.storage.大攻车选项二) range[1]+=cardx.storage.大攻车选项二; + selectTarget: function (card, player, range) { + if (card.storage && card.storage.dagongche && range[1] != -1) { + var cardx = player.getEquip("dagongche"); + if (cardx && cardx.storage.大攻车选项二) range[1] += cardx.storage.大攻车选项二; } }, - canBeDiscarded:function(card){ - if(card.name=='dagongche'&&get.position(card)=='e'){ - for(var i=1;i<=3;i++){ - if(card.storage['大攻车选项'+get.cnNumber(i,true)]) return; + canBeDiscarded: function (card) { + if (card.name == "dagongche" && get.position(card) == "e") { + for (var i = 1; i <= 3; i++) { + if (card.storage["大攻车选项" + get.cnNumber(i, true)]) return; } return false; } }, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.card.storage||!arg.card.storage.dagongche) return false; - var card=player.getEquip('dagongche'); - if(!card||!card.storage.大攻车选项一) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.card || !arg.card.storage || !arg.card.storage.dagongche) + return false; + var card = player.getEquip("dagongche"); + if (!card || !card.storage.大攻车选项一) return false; }, }, - group:'dagongche_skill_discard', - subSkill:{ - discard:{ - trigger:{source:'damageSource'}, - equipSkill:true, - forced:true, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.dagongche) return false; - if(event.getParent().type!='card') return false; - return event.player.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,event.player,player); - },'he'); + group: "dagongche_skill_discard", + subSkill: { + discard: { + trigger: { source: "damageSource" }, + equipSkill: true, + forced: true, + filter: function (event, player) { + if (!event.card || !event.card.storage || !event.card.storage.dagongche) + return false; + if (event.getParent().type != "card") return false; + return event.player.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, event.player, player); + }, "he"); }, - logTarget:'player', - content:function(){ - var num=1; - var cardx=player.getEquip('dagongche'); - if(cardx&&cardx.storage.大攻车选项三) num+=cardx.storage.大攻车选项三; - player.discardPlayerCard(trigger.player,true,num,'he'); + logTarget: "player", + content: function () { + var num = 1; + var cardx = player.getEquip("dagongche"); + if (cardx && cardx.storage.大攻车选项三) num += cardx.storage.大攻车选项三; + player.discardPlayerCard(trigger.player, true, num, "he"); }, }, }, }, //刘徽 - dcgeyuan:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter','cardsDiscardAfter','equipAfter'], + dcgeyuan: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - filter:function(event,player){ - var cards=event.getd(); - for(var i of cards){ - if(lib.skill.dcgeyuan.filterNumber(player,get.number(i,false))) return true; + forced: true, + filter: function (event, player) { + var cards = event.getd(); + for (var i of cards) { + if (lib.skill.dcgeyuan.filterNumber(player, get.number(i, false))) return true; } return false; }, - content:function(){ - 'step 0' - event.cards=trigger.getd(); - 'step 1' - var card=false; - for(var i of cards){ - if(lib.skill.dcgeyuan.filterNumber(player,get.number(i,false))){ - card=i; + content: function () { + "step 0"; + event.cards = trigger.getd(); + "step 1"; + var card = false; + for (var i of cards) { + if (lib.skill.dcgeyuan.filterNumber(player, get.number(i, false))) { + card = i; cards.remove(card); break; } } - if(card){ - var number=get.number(card,false); - game.log(player,'将','#y'+get.strNumber(number),'记录为','#g“圆环之弧”'); - player.markAuto('dcgeyuan_homura',[number]); - player.markSkill('dcgeyuan'); - if(player.getStorage('dcgeyuan').length>player.getStorage('dcgeyuan_homura').length){ - if(cards.length>0) event.redo(); - else event.finish() - } - else if(player.storage.dcgusuan) event.goto(5); - } - else event.finish(); - 'step 2' - var list=player.getStorage('dcgeyuan_homura'); - var num1=list[0],num2=list[list.length-1]; - event.cards2=[]; - var lose_list=[],players=game.filterPlayer(); - for(var current of players){ - var cards=current.getCards('ej',function(card){ - var num=get.number(card); - return num==num1||num==num2; + if (card) { + var number = get.number(card, false); + game.log(player, "将", "#y" + get.strNumber(number), "记录为", "#g“圆环之弧”"); + player.markAuto("dcgeyuan_homura", [number]); + player.markSkill("dcgeyuan"); + if ( + player.getStorage("dcgeyuan").length > player.getStorage("dcgeyuan_homura").length + ) { + if (cards.length > 0) event.redo(); + else event.finish(); + } else if (player.storage.dcgusuan) event.goto(5); + } else event.finish(); + "step 2"; + var list = player.getStorage("dcgeyuan_homura"); + var num1 = list[0], + num2 = list[list.length - 1]; + event.cards2 = []; + var lose_list = [], + players = game.filterPlayer(); + for (var current of players) { + var cards = current.getCards("ej", function (card) { + var num = get.number(card); + return num == num1 || num == num2; }); - if(cards.length>0){ + if (cards.length > 0) { current.$throw(cards); - lose_list.push([current,cards]); + lose_list.push([current, cards]); event.cards2.addArray(cards); } } - if(lose_list.length){ - event.lose_list=lose_list; + if (lose_list.length) { + event.lose_list = lose_list; game.loseAsync({ - lose_list:lose_list, - }).setContent('chooseToCompareLose'); + lose_list: lose_list, + }).setContent("chooseToCompareLose"); } - 'step 3' - var list=player.getStorage('dcgeyuan_homura'); - var num1=list[0],num2=list[list.length-1]; - var cards=event.cards2; - for(var i=0;i0){ - if(event.lose_list) game.delayx(); - player.gain(cards,'gain2'); + if (cards.length > 0) { + if (event.lose_list) game.delayx(); + player.gain(cards, "gain2"); } - 'step 4' - var list=player.getStorage('dcgeyuan_homura'); - var num1=list[0],num2=list[list.length-1]; - player.storage.dcgeyuan_homura=[]; - game.log(player,'清空了','#g“圆环之弧”'); - player.markSkill('dcgeyuan'); - if(player.getStorage('dcgeyuan').length>3){ - player.unmarkAuto('dcgeyuan',[num1,num2]); - game.log(player,'从','#g“圆环之理”','中移除了','#y'+get.strNumber(num1),'和','#y'+get.strNumber(num2)); + "step 4"; + var list = player.getStorage("dcgeyuan_homura"); + var num1 = list[0], + num2 = list[list.length - 1]; + player.storage.dcgeyuan_homura = []; + game.log(player, "清空了", "#g“圆环之弧”"); + player.markSkill("dcgeyuan"); + if (player.getStorage("dcgeyuan").length > 3) { + player.unmarkAuto("dcgeyuan", [num1, num2]); + game.log( + player, + "从", + "#g“圆环之理”", + "中移除了", + "#y" + get.strNumber(num1), + "和", + "#y" + get.strNumber(num2) + ); } event.finish(); - 'step 5' - player.chooseTarget('割圆:选择至多三名角色','第一名角色摸三张牌,第二名角色弃置四张牌,第三名角色将所有手牌与牌堆底的牌交换',true,[1,3]); - 'step 6' - if(result.bool){ - var targets=result.targets; - event.targets=targets; + "step 5"; + player.chooseTarget( + "割圆:选择至多三名角色", + "第一名角色摸三张牌,第二名角色弃置四张牌,第三名角色将所有手牌与牌堆底的牌交换", + true, + [1, 3] + ); + "step 6"; + if (result.bool) { + var targets = result.targets; + event.targets = targets; player.line(targets); targets[0].draw(3); - if(targets.length<2) event.goto(4); - } - else event.goto(4); - 'step 7' - if(targets[1].countCards('he')>0) targets[1].chooseToDiscard('he',true,4); - if(targets.length<3) event.goto(4); - 'step 8' - var target=targets[2]; - var cards=get.bottomCards(5); + if (targets.length < 2) event.goto(4); + } else event.goto(4); + "step 7"; + if (targets[1].countCards("he") > 0) targets[1].chooseToDiscard("he", true, 4); + if (targets.length < 3) event.goto(4); + "step 8"; + var target = targets[2]; + var cards = get.bottomCards(5); game.cardsGotoOrdering(cards); - var hs=target.getCards('h'); - if(hs.length>0) target.lose(hs,ui.cardPile); - target.gain(cards,'draw'); + var hs = target.getCards("h"); + if (hs.length > 0) target.lose(hs, ui.cardPile); + target.gain(cards, "draw"); event.goto(4); }, - group:'dcgeyuan_kyubey', - filterNumber:function(player,num){ - var list1=player.getStorage('dcgeyuan'); - var list2=player.getStorage('dcgeyuan_homura'); - if(!list1.includes(num)) return false; - if(!list2.length) return true; - if(list2.includes(num)) return false; - var madoka=list1.indexOf(num); - for(var i of list2){ - var homura=list1.indexOf(i); - var dist=Math.abs(madoka-homura); - if(dist==1||dist==list1.length-1) return true; + group: "dcgeyuan_kyubey", + filterNumber: function (player, num) { + var list1 = player.getStorage("dcgeyuan"); + var list2 = player.getStorage("dcgeyuan_homura"); + if (!list1.includes(num)) return false; + if (!list2.length) return true; + if (list2.includes(num)) return false; + var madoka = list1.indexOf(num); + for (var i of list2) { + var homura = list1.indexOf(i); + var dist = Math.abs(madoka - homura); + if (dist == 1 || dist == list1.length - 1) return true; } return false; }, - subSkill:{ - kyubey:{ - audio:'dcgeyuan', - trigger:{ - global:'phaseBefore', - player:'enterGame', + subSkill: { + kyubey: { + audio: "dcgeyuan", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&!player.storage.dcgusuan; + forced: true, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && !player.storage.dcgusuan + ); }, - content:function(){ - var list=[]; - for(var i=1;i<=13;i++){ + content: function () { + var list = []; + for (var i = 1; i <= 13; i++) { list.push(i); } list.randomSort(); - player.storage.dcgeyuan=list; - player.markSkill('dcgeyuan'); - var str='#y'; - for(var i=0;i<13;i++){ - str+=get.strNumber(list[i]); - if(i!=12) str+=','; + player.storage.dcgeyuan = list; + player.markSkill("dcgeyuan"); + var str = "#y"; + for (var i = 0; i < 13; i++) { + str += get.strNumber(list[i]); + if (i != 12) str += ","; } - game.log(player,'将','#y“圆环之理”','赋值为',str); + game.log(player, "将", "#y“圆环之理”", "赋值为", str); }, }, }, - intro:{ - name:'圆环之理', - markcount:function(storage,player){ - if(!player.storage.dcgeyuan||!player.getStorage('dcgeyuan_homura').length) return 0; - var list=player.storage.dcgeyuan.filter(i=>lib.skill.dcgeyuan.filterNumber(player,i)); - if(!list.length) return 0; - list=list.map(num=>{ - var list=[1,10,11,12,13]; - if(list.includes(num)) return ['A','X','J','Q','K'][list.indexOf(num)]; + intro: { + name: "圆环之理", + markcount: function (storage, player) { + if (!player.storage.dcgeyuan || !player.getStorage("dcgeyuan_homura").length) + return 0; + var list = player.storage.dcgeyuan.filter((i) => + lib.skill.dcgeyuan.filterNumber(player, i) + ); + if (!list.length) return 0; + list = list.map((num) => { + var list = [1, 10, 11, 12, 13]; + if (list.includes(num)) return ["A", "X", "J", "Q", "K"][list.indexOf(num)]; return parseFloat(num); }); - return list.reduce((str,num)=>{ - return str+num; - },''); + return list.reduce((str, num) => { + return str + num; + }, ""); }, - mark:function(dialog,storage,player){ - dialog.content.style['overflow-x']='visible'; - var list=storage; - if(!storage||!storage.length) return '(圆环之理尚不存在)'; - var list2=player.getStorage('dcgeyuan_homura'); - var core=document.createElement('div'); - core.style.width='0'; - var centerX=-15,centerY=80,radius=80; - var radian=Math.PI*2/list.length; - var fulllist=['A','2','3','4','5','6','7','8','9','10','J','Q','K']; - for(var i=0;i['+fulllist[list[i]-1]+']'; - td.style.position='absolute'; + mark: function (dialog, storage, player) { + dialog.content.style["overflow-x"] = "visible"; + var list = storage; + if (!storage || !storage.length) return "(圆环之理尚不存在)"; + var list2 = player.getStorage("dcgeyuan_homura"); + var core = document.createElement("div"); + core.style.width = "0"; + var centerX = -15, + centerY = 80, + radius = 80; + var radian = (Math.PI * 2) / list.length; + var fulllist = [ + "A", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "J", + "Q", + "K", + ]; + for (var i = 0; i < list.length; i++) { + var td = document.createElement("div"); + var color = ""; + if (list2[0] == list[i]) color = ' class="yellowtext"'; + else if (list2.includes(list[i])) color = ' class="greentext"'; + td.innerHTML = "[" + fulllist[list[i] - 1] + "]"; + td.style.position = "absolute"; core.appendChild(td); - td.style.left=(centerX+radius*Math.sin(radian*i))+'px'; - td.style.top=(centerY-radius*Math.cos(radian*i))+'px'; + td.style.left = centerX + radius * Math.sin(radian * i) + "px"; + td.style.top = centerY - radius * Math.cos(radian * i) + "px"; } dialog.content.appendChild(core); }, }, }, - dcjieshu:{ - audio:2, - trigger:{player:['useCard','respond']}, - forced:true, - filter:function(event,player){ - var num=get.number(event.card,false); - if(typeof num!='number') return false; - return lib.skill.dcgeyuan.filterNumber(player,num) + dcjieshu: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + forced: true, + filter: function (event, player) { + var num = get.number(event.card, false); + if (typeof num != "number") return false; + return lib.skill.dcgeyuan.filterNumber(player, num); }, - content:function(){ + content: function () { player.draw(); }, - mod:{ - ignoredHandcard:function(card,player){ - if(!player.getStorage('dcgeyuan').includes(get.number(card))) return true; + mod: { + ignoredHandcard: function (card, player) { + if (!player.getStorage("dcgeyuan").includes(get.number(card))) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&!player.getStorage('dcgeyuan').includes(get.number(card))) return false; + cardDiscardable: function (card, player, name) { + if ( + name == "phaseDiscard" && + !player.getStorage("dcgeyuan").includes(get.number(card)) + ) + return false; }, }, }, - dcgusuan:{ - audio:2, - trigger:{global:'phaseEnd'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'soil', - filter:function(event,player){ - return player.getStorage('dcgeyuan').length==3; + dcgusuan: { + audio: 2, + trigger: { global: "phaseEnd" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "soil", + filter: function (event, player) { + return player.getStorage("dcgeyuan").length == 3; }, - content:function(){ - player.awakenSkill('dcgusuan'); - player.storage.dcgusuan=true; + content: function () { + player.awakenSkill("dcgusuan"); + player.storage.dcgusuan = true; player.loseMaxHp(); }, - ai:{combo:'dcgeyuan'}, - derivation:'dcgeyuan_magica', + ai: { combo: "dcgeyuan" }, + derivation: "dcgeyuan_magica", }, //王昶 - dckaiji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.maxHp<=0) return false; - if(!player.storage.dckaiji) return true; - return player.hasCard((card)=>lib.filter.cardDiscardable(card,player,'phaseUse'),'he'); + dckaiji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (player.maxHp <= 0) return false; + if (!player.storage.dckaiji) return true; + return player.hasCard( + (card) => lib.filter.cardDiscardable(card, player, "phaseUse"), + "he" + ); }, - filterCard:function(card,player){ - if(!player.storage.dckaiji) return false; + filterCard: function (card, player) { + if (!player.storage.dckaiji) return false; return true; }, - position:'he', - selectCard:function(){ - var player=_status.event.player; - return player.storage.dckaiji?[1,player.maxHp]:-1; + position: "he", + selectCard: function () { + var player = _status.event.player; + return player.storage.dckaiji ? [1, player.maxHp] : -1; }, - check:function(card){ - var player=_status.event.player; - if(!player.hasSkill('dcpingxi')) return 0; - var num=lib.skill.dcpingxi.getNum()+ui.selected.cards.length; - if(num0; - })){ - if(get.position(card)=='h'&&player.needsToDiscard(0,(i,player)=>{ - return !ui.selected.cards.includes(i)&&!player.canIgnoreHandcard(i); - })) return 7+1/Math.max(1,get.value(card)); - return 7-get.value(card); + check: function (card) { + var player = _status.event.player; + if (!player.hasSkill("dcpingxi")) return 0; + var num = lib.skill.dcpingxi.getNum() + ui.selected.cards.length; + if ( + num < + game.countPlayer(function (current) { + if (current == player || current.countCards("he") == 0) return false; + return ( + get.effect(current, { name: "guohe_copy2" }, player, player) + + get.effect(current, { name: "sha" }, player, player) > + 0 + ); + }) + ) { + if ( + get.position(card) == "h" && + player.needsToDiscard(0, (i, player) => { + return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); + }) + ) + return 7 + 1 / Math.max(1, get.value(card)); + return 7 - get.value(card); } return 0; }, - content:function(){ - player.changeZhuanhuanji('dckaiji'); - if(!cards.length) player.draw(Math.min(player.maxHp,5)); + content: function () { + player.changeZhuanhuanji("dckaiji"); + if (!cards.length) player.draw(Math.min(player.maxHp, 5)); }, - zhuanhuanji:true, - mark:true, - marktext:'☯', - intro:{ - content:(storage)=>('转换技。出牌阶段限一次,你可以'+(storage?'弃置至多X张牌':'摸X张牌')+'(X为你的体力上限且至多为5)。'), + zhuanhuanji: true, + mark: true, + marktext: "☯", + intro: { + content: (storage) => + "转换技。出牌阶段限一次,你可以" + + (storage ? "弃置至多X张牌" : "摸X张牌") + + "(X为你的体力上限且至多为5)。", }, - ai:{ - threaten:1.6, - order:function(item,player){ - if(player.storage.dckaiji) return 0.1; + ai: { + threaten: 1.6, + order: function (item, player) { + if (player.storage.dckaiji) return 0.1; return 8; }, - result:{player:1}, + result: { player: 1 }, }, }, - dcpingxi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - getNum:function(){ - var num=0; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name=='lose'&&evt.type=='discard') num+=evt.cards2.length; + dcpingxi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + getNum: function () { + var num = 0; + game.getGlobalHistory("cardMove", function (evt) { + if (evt.name == "lose" && evt.type == "discard") num += evt.cards2.length; }); return num; }, - filter:function(event,player){ - return lib.skill.dcpingxi.getNum()>0&&game.hasPlayer(function(current){ - return current!=player; - }); + filter: function (event, player) { + return ( + lib.skill.dcpingxi.getNum() > 0 && + game.hasPlayer(function (current) { + return current != player; + }) + ); }, - content:function(){ - 'step 0' - var num=lib.skill.dcpingxi.getNum(); - player.chooseTarget([1,num],function(card,player,target){ - return target!=player; - },get.prompt('dcpingxi'),'选择至多'+get.cnNumber(num)+'名其他角色。弃置这些角色的各一张牌,然后视为对这些角色使用一张【杀】').set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player)+get.effect(target,{name:'sha'},player,player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - event.targets=targets; - player.logSkill('dcpingxi',targets); - event.num=0; - } - else event.finish(); - 'step 2' - var target=targets[num]; - if(target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he')) player.discardPlayerCard(target,'he',true); + content: function () { + "step 0"; + var num = lib.skill.dcpingxi.getNum(); + player + .chooseTarget( + [1, num], + function (card, player, target) { + return target != player; + }, + get.prompt("dcpingxi"), + "选择至多" + + get.cnNumber(num) + + "名其他角色。弃置这些角色的各一张牌,然后视为对这些角色使用一张【杀】" + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.effect(target, { name: "guohe_copy2" }, player, player) + + get.effect(target, { name: "sha" }, player, player) + ); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + event.targets = targets; + player.logSkill("dcpingxi", targets); + event.num = 0; + } else event.finish(); + "step 2"; + var target = targets[num]; + if ( + target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ) + player.discardPlayerCard(target, "he", true); event.num++; - if(event.num0) player.useCard({ - name:'sha', - isCard:true, - },targetsx); + if (targetsx.length > 0) + player.useCard( + { + name: "sha", + isCard: true, + }, + targetsx + ); }, }, //赵昂 - dczhongjie:{ - audio:2, - round:1, - trigger:{global:'dying'}, - logTarget:'player', - filter:function(event,player){ - return event.player.hp<1&&event.reason&&event.reason.name=='loseHp'; + dczhongjie: { + audio: 2, + round: 1, + trigger: { global: "dying" }, + logTarget: "player", + filter: function (event, player) { + return event.player.hp < 1 && event.reason && event.reason.name == "loseHp"; }, - check:function(event,player){ - return get.attitude(player,event.player)>2; + check: function (event, player) { + return get.attitude(player, event.player) > 2; }, - content:function(){ + content: function () { trigger.player.recover(); trigger.player.draw(); }, }, - dcsushou:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return player.hp>0&&event.player.isMaxHandcard(true); + dcsushou: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return player.hp > 0 && event.player.isMaxHandcard(true); }, - logTarget:'player', - check:function(event,player){ - var num=player.hp; - if(player.hasSkill('dczhongjie')&&(player.storage.dczhongjie_roundcount||0)1; + logTarget: "player", + check: function (event, player) { + var num = player.hp; + if ( + player.hasSkill("dczhongjie") && + (player.storage.dczhongjie_roundcount || 0) < game.roundNumber + ) + num++; + return num > 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - event.target=trigger.player; - 'step 1' - var num=player.getDamagedHp(); - if(num>0) player.draw(num); - if(player==target) event.finish(); - 'step 2' - var ts=target.getCards('h'); - if(ts.length<2) event.finish(); - else{ - var hs=player.getCards('h'); - ts=ts.randomGets(Math.floor(ts.length/2)); - if(!hs.length){ - player.viewCards(get.translation(target)+'的部分手牌'); + event.target = trigger.player; + "step 1"; + var num = player.getDamagedHp(); + if (num > 0) player.draw(num); + if (player == target) event.finish(); + "step 2"; + var ts = target.getCards("h"); + if (ts.length < 2) event.finish(); + else { + var hs = player.getCards("h"); + ts = ts.randomGets(Math.floor(ts.length / 2)); + if (!hs.length) { + player.viewCards(get.translation(target) + "的部分手牌"); event.finish(); return; } - var next=player.chooseToMove('夙守:交换至多'+get.cnNumber(Math.min(hs.length,ts.length,player.getDamagedHp()))+'张牌'); - next.set('list',[ - [get.translation(target)+'的部分手牌',ts,'dcsushou_tag'], - ['你的手牌',hs], + var next = player.chooseToMove( + "夙守:交换至多" + + get.cnNumber(Math.min(hs.length, ts.length, player.getDamagedHp())) + + "张牌" + ); + next.set("list", [ + [get.translation(target) + "的部分手牌", ts, "dcsushou_tag"], + ["你的手牌", hs], ]); - next.set('filterMove',function(from,to,moved){ - if(typeof to=='number') return false; - var player=_status.event.player; - var hs=player.getCards('h'); - var changed=hs.filter(function(card){ + next.set("filterMove", function (from, to, moved) { + if (typeof to == "number") return false; + var player = _status.event.player; + var hs = player.getCards("h"); + var changed = hs.filter(function (card) { return !moved[1].includes(card); }); - var changed2=moved[1].filter(function(card){ + var changed2 = moved[1].filter(function (card) { return !hs.includes(card); }); - if(changed.length{ - return player.getUseValue(b,null,true)-player.getUseValue(a,null,true); - }).slice(0,_status.event.max),give=list[1][1].sort((a,b)=>{ - return get.value(a,player)-get.value(b,player); - }).slice(0,_status.event.max); - for(let i of gain){ - if(get.value(i,player) { + return ( + player.getUseValue(b, null, true) - + player.getUseValue(a, null, true) + ); + }) + .slice(0, _status.event.max), + give = list[1][1] + .sort((a, b) => { + return get.value(a, player) - get.value(b, player); + }) + .slice(0, _status.event.max); + for (let i of gain) { + if (get.value(i, player) < get.value(give[0], player)) continue; + let j = give.shift(); list[0][1].remove(i); list[0][1].push(j); list[1][1].remove(j); list[1][1].push(i); - if(!give.length) break; + if (!give.length) break; } } - return [list[0][1],list[1][1]]; + return [list[0][1], list[1][1]]; }); } - 'step 3' - var moved=result.moved; - var hs=player.getCards('h'),ts=target.getCards('h'); - var cards1=[],cards2=[]; - for(var i of result.moved[0]){ - if(!ts.includes(i)) cards1.push(i); + "step 3"; + var moved = result.moved; + var hs = player.getCards("h"), + ts = target.getCards("h"); + var cards1 = [], + cards2 = []; + for (var i of result.moved[0]) { + if (!ts.includes(i)) cards1.push(i); } - for(var i of result.moved[1]){ - if(!hs.includes(i)) cards2.push(i); + for (var i of result.moved[1]) { + if (!hs.includes(i)) cards2.push(i); } - if(cards1.length){ - player.swapHandcards(target,cards1,cards2); + if (cards1.length) { + player.swapHandcards(target, cards1, cards2); } }, }, //蓝曹华 - caiyi:{ - audio:2, - zhuanhuanji:true, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - onremove:function(player){ + caiyi: { + audio: 2, + zhuanhuanji: true, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + onremove: function (player) { delete player.storage.caiyi; delete player.storage.caiyi_info; }, - filter:function(event,player){ - if(player.storage.caiyi_info){ - if(player.storage.caiyi_info[player.storage.caiyi?1:0].length>=4) return false; + filter: function (event, player) { + if (player.storage.caiyi_info) { + if (player.storage.caiyi_info[player.storage.caiyi ? 1 : 0].length >= 4) return false; } return true; }, - choices:[[ - '回复X点体力', - '摸X张牌', - '复原武将牌', - '随机执行一个已经移除过的选项', - ],[ - '受到X点伤害', - '弃置X张牌', - '翻面并横置', - '随机执行一个已经移除过的选项', - ]], - filterx:[[ - (player)=>player.isDamaged(), - ()=>true, - (player)=>player.isTurnedOver()||player.isLinked(), - ()=>true, - ],[ - ()=>true, - (player)=>player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'caiyi'); - },'he'), - (player)=>!player.isTurnedOver()||!player.isLinked(), - ()=>true, - ]], - content:function(){ - 'step 0' - if(!player.storage.caiyi_info) player.storage.caiyi_info=[[],[]]; - var index=player.storage.caiyi?1:0; - event.index=index; - var list=player.storage.caiyi_info[index],choices=lib.skill.caiyi.choices[index],numbers=['⒈',';⒉',';⒊',';⒋']; - event.num=4-list.length; - var str='令一名角色选择执行其中一项:'; - for(var i=0;i<4;i++){ - if(list.includes(i)) continue; - if(i==3&&!list.length) continue; - str+=numbers.shift(); - str+=choices[i]; + choices: [ + ["回复X点体力", "摸X张牌", "复原武将牌", "随机执行一个已经移除过的选项"], + ["受到X点伤害", "弃置X张牌", "翻面并横置", "随机执行一个已经移除过的选项"], + ], + filterx: [ + [ + (player) => player.isDamaged(), + () => true, + (player) => player.isTurnedOver() || player.isLinked(), + () => true, + ], + [ + () => true, + (player) => + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "caiyi"); + }, "he"), + (player) => !player.isTurnedOver() || !player.isLinked(), + () => true, + ], + ], + content: function () { + "step 0"; + if (!player.storage.caiyi_info) player.storage.caiyi_info = [[], []]; + var index = player.storage.caiyi ? 1 : 0; + event.index = index; + var list = player.storage.caiyi_info[index], + choices = lib.skill.caiyi.choices[index], + numbers = ["⒈", ";⒉", ";⒊", ";⒋"]; + event.num = 4 - list.length; + var str = "令一名角色选择执行其中一项:"; + for (var i = 0; i < 4; i++) { + if (list.includes(i)) continue; + if (i == 3 && !list.length) continue; + str += numbers.shift(); + str += choices[i]; } - str+='。'; - str=str.replace(/X/g,get.cnNumber(event.num)); - player.chooseTarget(get.prompt('caiyi')+'(当前状态:'+(index?'阳':'阴')+')',str).set('ai',function(target){ - var player=_status.event.player; - return (player.storage.caiyi?-1:1)*get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('caiyi',target); - player.changeZhuanhuanji('caiyi'); - event.goto(event.index==1?5:2); - } - else event.finish(); - 'step 2' - var list=[],str=get.cnNumber(num); - var choiceList=[ - '回复'+str+'点体力。', - '摸'+str+'张牌。', - '将武将牌翻至正面且重置。', - '随机执行一个已经被移除的选项。', + str += "。"; + str = str.replace(/X/g, get.cnNumber(event.num)); + player + .chooseTarget( + get.prompt("caiyi") + "(当前状态:" + (index ? "阳" : "阴") + ")", + str + ) + .set("ai", function (target) { + var player = _status.event.player; + return (player.storage.caiyi ? -1 : 1) * get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("caiyi", target); + player.changeZhuanhuanji("caiyi"); + event.goto(event.index == 1 ? 5 : 2); + } else event.finish(); + "step 2"; + var list = [], + str = get.cnNumber(num); + var choiceList = [ + "回复" + str + "点体力。", + "摸" + str + "张牌。", + "将武将牌翻至正面且重置。", + "随机执行一个已经被移除的选项。", ]; - var storage=player.storage.caiyi_info[event.index]; - for(var i=0;i<4;i++){ - if(storage.includes(i)){ - choiceList[i]=(''+choiceList[i]+''); - } - else if(!lib.skill.caiyi.filterx[event.index][i](target)||(i==3&&!storage.length)){ - choiceList[i]=(''+choiceList[i]+''); - } - else list.push('选项'+get.cnNumber(i+1,true)) + var storage = player.storage.caiyi_info[event.index]; + for (var i = 0; i < 4; i++) { + if (storage.includes(i)) { + choiceList[i] = + '' + + choiceList[i] + + ""; + } else if ( + !lib.skill.caiyi.filterx[event.index][i](target) || + (i == 3 && !storage.length) + ) { + choiceList[i] = '' + choiceList[i] + ""; + } else list.push("选项" + get.cnNumber(i + 1, true)); } - if(!list.length){ + if (!list.length) { event.finish(); return; } - target.chooseControl(list).set('choiceList',choiceList).set('ai',function(){ - var evt=_status.event,player=evt.player; - var list=evt.controls.slice(0); - var gett=function(choice){ - if(choice=='cancel2') return 0.1; - var max=0,func={ - 选项一:function(current){ - max=get.recoverEffect(current,player,player)*Math.min(evt.getParent().num,player.getDamagedHp()); - }, - 选项二:function(target){ - max=get.effect(target,{name:'draw'},player,player)*evt.getParent().num; - }, - 选项三:function(target){ - if(player.isTurnedOver()) max+=25; - if(player.isLinked()) max+=get.effect(player,{name:'tiesuo'},player,player); - }, - 选项四:function(target){ - max=3; - }, - }[choice]; - func(player); - return max; - }; - return list.sort(function(a,b){ - return gett(b)-gett(a); - })[0]; - }); - 'step 3' - var index2=['选项一','选项二','选项三','选项四'].indexOf(result.control); - player.storage.caiyi_info[event.index].push(index2); - if(index2==3){ - var list=player.storage.caiyi_info[event.index].filter(function(i){ - return i!=3&&lib.skill.caiyi.filterx[event.index][i](target); + target + .chooseControl(list) + .set("choiceList", choiceList) + .set("ai", function () { + var evt = _status.event, + player = evt.player; + var list = evt.controls.slice(0); + var gett = function (choice) { + if (choice == "cancel2") return 0.1; + var max = 0, + func = { + 选项一: function (current) { + max = + get.recoverEffect(current, player, player) * + Math.min(evt.getParent().num, player.getDamagedHp()); + }, + 选项二: function (target) { + max = + get.effect(target, { name: "draw" }, player, player) * + evt.getParent().num; + }, + 选项三: function (target) { + if (player.isTurnedOver()) max += 25; + if (player.isLinked()) + max += get.effect(player, { name: "tiesuo" }, player, player); + }, + 选项四: function (target) { + max = 3; + }, + }[choice]; + func(player); + return max; + }; + return list.sort(function (a, b) { + return gett(b) - gett(a); + })[0]; }); - if(!list.length){ + "step 3"; + var index2 = ["选项一", "选项二", "选项三", "选项四"].indexOf(result.control); + player.storage.caiyi_info[event.index].push(index2); + if (index2 == 3) { + var list = player.storage.caiyi_info[event.index].filter(function (i) { + return i != 3 && lib.skill.caiyi.filterx[event.index][i](target); + }); + if (!list.length) { event.finish(); return; } - index2=list.randomGet(); + index2 = list.randomGet(); } - switch(index2){ + switch (index2) { case 0: target.recover(num); break; @@ -9842,2083 +13109,2494 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.draw(num); break; case 2: - !target.isTurnedOver()||target.turnOver(); + !target.isTurnedOver() || target.turnOver(); break; } - if(index2!=2) event.finish(); - 'step 4' - !target.isLinked()||target.link(); + if (index2 != 2) event.finish(); + "step 4"; + !target.isLinked() || target.link(); event.finish(); - 'step 5' - var list=[],str=get.cnNumber(num); - var choiceList=[ - '受到'+str+'点伤害。', - '弃置'+str+'张牌。', - '将武将牌翻至背面并横置。', - '随机执行一个已经被移除的选项。', + "step 5"; + var list = [], + str = get.cnNumber(num); + var choiceList = [ + "受到" + str + "点伤害。", + "弃置" + str + "张牌。", + "将武将牌翻至背面并横置。", + "随机执行一个已经被移除的选项。", ]; - var storage=player.storage.caiyi_info[event.index]; - for(var i=0;i<4;i++){ - if(storage.includes(i)){ - choiceList[i]=(''+choiceList[i]+''); - } - else if(!lib.skill.caiyi.filterx[event.index][i](target)||(i==3&&!storage.length)){ - choiceList[i]=(''+choiceList[i]+''); - } - else list.push('选项'+get.cnNumber(i+1,true)) + var storage = player.storage.caiyi_info[event.index]; + for (var i = 0; i < 4; i++) { + if (storage.includes(i)) { + choiceList[i] = + '' + + choiceList[i] + + ""; + } else if ( + !lib.skill.caiyi.filterx[event.index][i](target) || + (i == 3 && !storage.length) + ) { + choiceList[i] = '' + choiceList[i] + ""; + } else list.push("选项" + get.cnNumber(i + 1, true)); } - if(!list.length){ + if (!list.length) { event.finish(); return; } - target.chooseControl(list).set('choiceList',choiceList).set('ai',function(){ - var evt=_status.event,player=evt.player; - var list=evt.controls.slice(0); - var gett=function(choice){ - if(choice=='cancel2') return 0.1; - var max=0,func={ - 选项一:function(current){ - max=get.effect(current,{name:'damage'},player,player)*evt.getParent().num; - }, - 选项二:function(target){ - max=get.effect(target,{name:'guohe_copy2'},player,player)*Math.min(player.countCards('he'),evt.getParent().num); - }, - 选项三:function(target){ - if(!player.isTurnedOver()) max-=5; - if(!player.isLinked()) max+=get.effect(player,{name:'tiesuo'},player,player); - }, - 选项四:function(target){ - max=-3; - }, - }[choice]; - func(player); - return max; - }; - return list.sort(function(a,b){ - return gett(b)-gett(a); - })[0]; - }); - 'step 6' - var index2=['选项一','选项二','选项三','选项四'].indexOf(result.control); - player.storage.caiyi_info[event.index].push(index2); - if(index2==3){ - var list=player.storage.caiyi_info[event.index].filter(function(i){ - return i!=3&&lib.skill.caiyi.filterx[event.index][i](target); + target + .chooseControl(list) + .set("choiceList", choiceList) + .set("ai", function () { + var evt = _status.event, + player = evt.player; + var list = evt.controls.slice(0); + var gett = function (choice) { + if (choice == "cancel2") return 0.1; + var max = 0, + func = { + 选项一: function (current) { + max = + get.effect(current, { name: "damage" }, player, player) * + evt.getParent().num; + }, + 选项二: function (target) { + max = + get.effect(target, { name: "guohe_copy2" }, player, player) * + Math.min(player.countCards("he"), evt.getParent().num); + }, + 选项三: function (target) { + if (!player.isTurnedOver()) max -= 5; + if (!player.isLinked()) + max += get.effect(player, { name: "tiesuo" }, player, player); + }, + 选项四: function (target) { + max = -3; + }, + }[choice]; + func(player); + return max; + }; + return list.sort(function (a, b) { + return gett(b) - gett(a); + })[0]; }); - if(!list.length){ + "step 6"; + var index2 = ["选项一", "选项二", "选项三", "选项四"].indexOf(result.control); + player.storage.caiyi_info[event.index].push(index2); + if (index2 == 3) { + var list = player.storage.caiyi_info[event.index].filter(function (i) { + return i != 3 && lib.skill.caiyi.filterx[event.index][i](target); + }); + if (!list.length) { event.finish(); return; } - index2=list.randomGet(); + index2 = list.randomGet(); } - switch(index2){ + switch (index2) { case 0: target.damage(num); break; case 1: - target.chooseToDiscard(num,true,'he'); + target.chooseToDiscard(num, true, "he"); break; case 2: - target.isTurnedOver()||target.turnOver(); + target.isTurnedOver() || target.turnOver(); break; } - if(index2!=2) event.finish(); - 'step 7' - target.isLinked()||target.link(); + if (index2 != 2) event.finish(); + "step 7"; + target.isLinked() || target.link(); event.finish(); }, - mark:true, - marktext:'☯', - intro:{ - content:function(storage){ - if(storage) return '转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项:⒈受到X点伤害。⒉弃置X张牌。⒊翻面并横置。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。'; - return '转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项:⒈回复X点体力。⒉摸X张牌,⒊复原武将牌。⒋随机执行一个已经移除过的阴选项。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。'; + mark: true, + marktext: "☯", + intro: { + content: function (storage) { + if (storage) + return "转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项:⒈受到X点伤害。⒉弃置X张牌。⒊翻面并横置。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。"; + return "转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项:⒈回复X点体力。⒉摸X张牌,⒊复原武将牌。⒋随机执行一个已经移除过的阴选项。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。"; }, }, }, - guili:{ - audio:2, - trigger:{player:'phaseBegin'}, - forced:true, - locked:false, - filter:function(event,player){ - return player.phaseNumber==1&&game.hasPlayer((current)=>current!=player); + guili: { + audio: 2, + trigger: { player: "phaseBegin" }, + forced: true, + locked: false, + filter: function (event, player) { + return player.phaseNumber == 1 && game.hasPlayer((current) => current != player); }, - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,true,'请选择【归离】的目标',lib.translate.guili_info).set('ai',function(target){ - return -get.threaten(target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'选择了',target); - player.storage.guili_insert=target; - player.addSkill('guili_insert'); + content: function () { + "step 0"; + player + .chooseTarget( + lib.filter.notMe, + true, + "请选择【归离】的目标", + lib.translate.guili_info + ) + .set("ai", function (target) { + return -get.threaten(target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "选择了", target); + player.storage.guili_insert = target; + player.addSkill("guili_insert"); game.delayx(); } }, - onremove:true, - subSkill:{ - insert:{ - mark:true, - intro:{ - content:'players' + onremove: true, + subSkill: { + insert: { + mark: true, + intro: { + content: "players", }, - trigger:{global:'phaseAfter'}, - forced:true, - charlotte:true, - logTarget:'player', - filter:function(event,player){ - if(event.player!=player.storage.guili_insert) return false; - if(event.player.getHistory('sourceDamage').length>0) return false; - var history=event.player.actionHistory; - if(history[history.length-1].isRound) return true; - for(var i=history.length-2;i>=0;i--){ - if(history[i].isMe) return false; - if(history[i].isRound) return true; + trigger: { global: "phaseAfter" }, + forced: true, + charlotte: true, + logTarget: "player", + filter: function (event, player) { + if (event.player != player.storage.guili_insert) return false; + if (event.player.getHistory("sourceDamage").length > 0) return false; + var history = event.player.actionHistory; + if (history[history.length - 1].isRound) return true; + for (var i = history.length - 2; i >= 0; i--) { + if (history[i].isMe) return false; + if (history[i].isRound) return true; } return false; }, - content:function(){ + content: function () { player.insertPhase(); }, }, }, }, //刘虞 - dcsuifu:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - if(player==event.player||!event.player.countCards('h')) return false; - var num=0; - game.countPlayer(function(current){ - if(current==player||current.getSeatNum()==1){ - current.getHistory('damage',function(evt){ - num+=evt.num; + dcsuifu: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + if (player == event.player || !event.player.countCards("h")) return false; + var num = 0; + game.countPlayer(function (current) { + if (current == player || current.getSeatNum() == 1) { + current.getHistory("damage", function (evt) { + num += evt.num; }); } }); - return num>=2; + return num >= 2; }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)<=0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function(){ - 'step 0' - var target=trigger.player,cards=target.getCards('h'); - target.lose(cards,ui.cardPile,'insert'); + content: function () { + "step 0"; + var target = trigger.player, + cards = target.getCards("h"); + target.lose(cards, ui.cardPile, "insert"); target.$throw(cards.length); game.updateRoundNumber(); - game.log(player,'将',target,'的',get.cnNumber(cards.length),'张手牌置于牌堆顶'); - 'step 1' + game.log(player, "将", target, "的", get.cnNumber(cards.length), "张手牌置于牌堆顶"); + "step 1"; game.delayx(); - player.chooseUseTarget({name:'wugu',isCard:true},true); + player.chooseUseTarget({ name: "wugu", isCard: true }, true); }, }, - dcpijing:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget([1,game.countPlayer()],get.prompt('dcpijing'),'令任意名角色获得技能〖自牧〗').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets; + dcpijing: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + [1, game.countPlayer()], + get.prompt("dcpijing"), + "令任意名角色获得技能〖自牧〗" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets; targets.add(player); targets.sortBySeat(); - player.logSkill('dcpijing',targets); - game.countPlayer(function(current){ - if(!targets.includes(current)) current.removeSkills('dczimu'); - else current.addSkills('dczimu'); + player.logSkill("dcpijing", targets); + game.countPlayer(function (current) { + if (!targets.includes(current)) current.removeSkills("dczimu"); + else current.addSkills("dczimu"); }); game.delayx(); } }, - derivation:'dczimu', + derivation: "dczimu", }, - dczimu:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - mark:true, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return current.hasSkill('dczimu',null,null,false); - }).sortBySeat(); + dczimu: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + mark: true, + logTarget: function (event, player) { + return game + .filterPlayer(function (current) { + return current.hasSkill("dczimu", null, null, false); + }) + .sortBySeat(); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current.hasSkill('dczimu',null,null,false); + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current.hasSkill("dczimu", null, null, false); }); - if(list.length>0){ - if(list.length==1) list[0].draw(); - else{ + if (list.length > 0) { + if (list.length == 1) list[0].draw(); + else { game.asyncDraw(list); - event.delay=true; + event.delay = true; } } - 'step 1' - player.removeSkills('dczimu'); - if(event.delay) game.delayx(); + "step 1"; + player.removeSkills("dczimu"); + if (event.delay) game.delayx(); + }, + marktext: "牧", + intro: { + content: + "锁定技。当你受到伤害后,你令所有拥有〖自牧〗的角色各摸一张牌,然后你失去〖自牧〗。", }, - marktext:'牧', - intro:{content:'锁定技。当你受到伤害后,你令所有拥有〖自牧〗的角色各摸一张牌,然后你失去〖自牧〗。'}, }, //黄祖 - dcjinggong:{ - audio:2, - enable:'chooseToUse', - locked:false, - mod:{ - targetInRange:function(card){ - if(card.storage&&card.storage.dcjinggong) return true; + dcjinggong: { + audio: 2, + enable: "chooseToUse", + locked: false, + mod: { + targetInRange: function (card) { + if (card.storage && card.storage.dcjinggong) return true; }, }, - viewAsFilter:function(player){ - return player.hasCard(function(card){ - return get.type(card)=='equip'; - },'ehs'); + viewAsFilter: function (player) { + return player.hasCard(function (card) { + return get.type(card) == "equip"; + }, "ehs"); }, - position:'hes', - filterCard:{type:'equip'}, - viewAs:{ - name:'sha', - storage:{dcjinggong:true}, + position: "hes", + filterCard: { type: "equip" }, + viewAs: { + name: "sha", + storage: { dcjinggong: true }, }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - return player.hasCard(function(card){ - return get.type(card)=='equip'; - },'ehs'); + ai: { + respondSha: true, + skillTagFilter: function (player) { + return player.hasCard(function (card) { + return get.type(card) == "equip"; + }, "ehs"); }, }, - group:'dcjinggong_base', - subSkill:{ - base:{ - trigger:{player:'useCard1'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return event.skill=='dcjinggong'&&event.targets.length>0; + group: "dcjinggong_base", + subSkill: { + base: { + trigger: { player: "useCard1" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return event.skill == "dcjinggong" && event.targets.length > 0; }, - content:function(){ - trigger.baseDamage=Math.min(5,get.distance(player,trigger.targets[0])); + content: function () { + trigger.baseDamage = Math.min(5, get.distance(player, trigger.targets[0])); }, }, }, }, - dcxiaojuan:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - logTarget:'target', - filter:function(event,player){ - return event.targets.length==1&&player!=event.target&&event.target.countCards('h')>1; + dcxiaojuan: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + logTarget: "target", + filter: function (event, player) { + return ( + event.targets.length == 1 && + player != event.target && + event.target.countCards("h") > 1 + ); }, - check:function(event,player){ - var target=event.target; - if(get.attitude(player,target)>=0) return false; - if(get.color(event.card)=='none') return true; - return Math.floor(target.countCards('h')/2)>=Math.floor(player.countCards('h')/2); + check: function (event, player) { + var target = event.target; + if (get.attitude(player, target) >= 0) return false; + if (get.color(event.card) == "none") return true; + return Math.floor(target.countCards("h") / 2) >= Math.floor(player.countCards("h") / 2); }, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - var num=Math.floor(target.countCards('h')/2); - if(num>0) player.discardPlayerCard(target,'h',num,true); + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + var num = Math.floor(target.countCards("h") / 2); + if (num > 0) player.discardPlayerCard(target, "h", num, true); else event.finish(); - 'step 1' - var suit=get.suit(trigger.card); - if(result.bool&&lib.suit.includes(suit)&&player.countCards('h')>1){ - var bool=false; - for(var i of result.cards){ - if(get.suit(i,target)==suit){ - bool=true; + "step 1"; + var suit = get.suit(trigger.card); + if (result.bool && lib.suit.includes(suit) && player.countCards("h") > 1) { + var bool = false; + for (var i of result.cards) { + if (get.suit(i, target) == suit) { + bool = true; break; } } - if(!bool) event.finish(); - } - else event.finish(); - 'step 2' - if(player.countCards('h')>0) player.chooseToDiscard('h',1,true); + if (!bool) event.finish(); + } else event.finish(); + "step 2"; + if (player.countCards("h") > 0) player.chooseToDiscard("h", 1, true); }, }, //来莺儿 - xiaowu:{ - audio:2, - enable:'phaseUse', - usable:1, - selectTarget:function(){ - return [1,game.countPlayer()-1]; + xiaowu: { + audio: 2, + enable: "phaseUse", + usable: 1, + selectTarget: function () { + return [1, game.countPlayer() - 1]; }, - complexSelect:true, - complexTarget:true, - filterTarget:function(card,player,target){ - if(player==target) return false; - var next=player.getNext(),prev=player.getPrevious(); - var selected=ui.selected.targets; - if(!selected.includes(next)&&!selected.includes(prev)) return (target==next||target==prev); - for(var i of selected){ - if(i.getNext()==target||i.getPrevious()==target) return true; + complexSelect: true, + complexTarget: true, + filterTarget: function (card, player, target) { + if (player == target) return false; + var next = player.getNext(), + prev = player.getPrevious(); + var selected = ui.selected.targets; + if (!selected.includes(next) && !selected.includes(prev)) + return target == next || target == prev; + for (var i of selected) { + if (i.getNext() == target || i.getPrevious() == target) return true; } return false; }, - contentBefore:function(){ - event.getParent()._xiaowu_targets=[]; + contentBefore: function () { + event.getParent()._xiaowu_targets = []; }, - content:function(){ - 'step 0' - if(!target.isIn()){ + content: function () { + "step 0"; + if (!target.isIn()) { event.finish(); return; } - target.chooseControl().set('choiceList',[ - '令'+get.translation(player)+'摸一张牌', - '令自己摸一张牌', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().player; - var all=_status.event.getParent().targets.length,dam=_status.event.getParent(2)._xiaowu_targets.length; - if(get.attitude(player,target)>0||dam>=Math.floor(all/2)) return 0; - return 1; - }); - 'step 1' - if(result.index==0){ + target + .chooseControl() + .set("choiceList", ["令" + get.translation(player) + "摸一张牌", "令自己摸一张牌"]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().player; + var all = _status.event.getParent().targets.length, + dam = _status.event.getParent(2)._xiaowu_targets.length; + if (get.attitude(player, target) > 0 || dam >= Math.floor(all / 2)) return 0; + return 1; + }); + "step 1"; + if (result.index == 0) { player.draw(); - } - else{ + } else { target.draw(); event.getParent()._xiaowu_targets.push(target); } }, - contentAfter:function(){ - var targetsx=event.getParent()._xiaowu_targets; - var num=(targets.length-targetsx.length-targetsx.length); - if(num>0) player.addMark('shawu',1); - else if(num<0){ - player.line(targetsx,'fire'); - for(var i of targetsx) i.damage(); + contentAfter: function () { + var targetsx = event.getParent()._xiaowu_targets; + var num = targets.length - targetsx.length - targetsx.length; + if (num > 0) player.addMark("shawu", 1); + else if (num < 0) { + player.line(targetsx, "fire"); + for (var i of targetsx) i.damage(); } }, - ai:{ - order:8, - result:{player:1}, + ai: { + order: 8, + result: { player: 1 }, }, }, - huaping:{ - audio:2, - trigger:{global:'die'}, - limited:true, - skillAnimation:true, - animationColor:'fire', - filter:function(event,player){ - return player!=event.player; + huaping: { + audio: 2, + trigger: { global: "die" }, + limited: true, + skillAnimation: true, + animationColor: "fire", + filter: function (event, player) { + return player != event.player; }, - logTarget:'player', - check:function(event,player){ - return get.rank(event.player.name,true)>=5; + logTarget: "player", + check: function (event, player) { + return get.rank(event.player.name, true) >= 5; }, - content:function(){ - player.awakenSkill('huaping'); - var skills=trigger.player.getSkills(null,false,false).filter(function(i){ - var info=get.info(i); - return info&&!info.charlotte; + content: function () { + player.awakenSkill("huaping"); + var skills = trigger.player.getSkills(null, false, false).filter(function (i) { + var info = get.info(i); + return info && !info.charlotte; }); - if(skills.length){ + if (skills.length) { //for(var i of skills) player.addSkillLog(i); player.addSkills(skills); } - player.removeSkills('xiaowu'); - var num=player.countMark('shawu'); - if(num>0){ - player.removeMark('shawu',num); + player.removeSkills("xiaowu"); + var num = player.countMark("shawu"); + if (num > 0) { + player.removeMark("shawu", num); player.draw(num); } }, - group:'huaping_give', - subSkill:{ - give:{ - audio:'huaping', - trigger:{player:'die'}, - direct:true, - filter:function(event,player){ - return event.player==player; + group: "huaping_give", + subSkill: { + give: { + audio: "huaping", + trigger: { player: "die" }, + direct: true, + filter: function (event, player) { + return event.player == player; }, - forceDie:true, - skillAnimation:true, - animationColor:'gray', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('huaping'),'令一名其他角色获得〖沙舞〗',lib.filter.notMe).set('forceDie',true).set('ai',function(target){ - return get.attitude(_status.event.player,target)+100; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.awakenSkill('huaping'); - player.logSkill('huaping_give',target); - target.addSkills('shawu'); - var num=player.countMark('shawu'); - if(num>0){ - player.removeMark('shawu',num); - target.addMark('shawu',num); + forceDie: true, + skillAnimation: true, + animationColor: "gray", + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("huaping"), + "令一名其他角色获得〖沙舞〗", + lib.filter.notMe + ) + .set("forceDie", true) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) + 100; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.awakenSkill("huaping"); + player.logSkill("huaping_give", target); + target.addSkills("shawu"); + var num = player.countMark("shawu"); + if (num > 0) { + player.removeMark("shawu", num); + target.addMark("shawu", num); } } }, }, }, - derivation:'shawu', + derivation: "shawu", }, - shawu:{ - audio:2, - trigger:{player:'useCardToTargeted'}, - shaRelated:true, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&event.player.isIn()&&(player.hasMark('shawu')||player.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'shawu'); - })>1); + shawu: { + audio: 2, + trigger: { player: "useCardToTargeted" }, + shaRelated: true, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.player.isIn() && + (player.hasMark("shawu") || + player.countCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "shawu"); + }) > 1) + ); }, - content:function(){ - 'step 0' - var list=[]; - if(player.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'shawu'); - })>1) list.push('弃置手牌'); - if(player.hasMark('shawu')) list.push('移除标记'); - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('shawu',trigger.target)).set('prompt2','弃置两张手牌,或移去一枚“沙”并摸两张牌,然后对该角色造成1点伤害').set('ai',function(){ - var player=_status.event.player,target=_status.event.getTrigger().target; - if(get.damageEffect(target,player,player)<=0) return 'cancel2'; - if(player.hasMark('shawu')) return '移除标记'; - if(player.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'shawu')&&get.value(card)<=6.5; - })>1) return '弃置手牌'; - return 'cancel2'; - }); - 'step 1' - var target=trigger.target; - if(result.control=='cancel2'){ + content: function () { + "step 0"; + var list = []; + if ( + player.countCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "shawu"); + }) > 1 + ) + list.push("弃置手牌"); + if (player.hasMark("shawu")) list.push("移除标记"); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("shawu", trigger.target)) + .set("prompt2", "弃置两张手牌,或移去一枚“沙”并摸两张牌,然后对该角色造成1点伤害") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().target; + if (get.damageEffect(target, player, player) <= 0) return "cancel2"; + if (player.hasMark("shawu")) return "移除标记"; + if ( + player.countCards("h", function (card) { + return ( + lib.filter.cardDiscardable(card, player, "shawu") && + get.value(card) <= 6.5 + ); + }) > 1 + ) + return "弃置手牌"; + return "cancel2"; + }); + "step 1"; + var target = trigger.target; + if (result.control == "cancel2") { event.finish(); return; - } - else if(result.control=='移除标记'){ - player.logSkill('shawu',target); - player.removeMark('shawu',1); + } else if (result.control == "移除标记") { + player.logSkill("shawu", target); + player.removeMark("shawu", 1); player.draw(2); target.damage(); event.finish(); + } else { + player.chooseToDiscard("h", true, 2).logSkill = ["shawu", target]; } - else{ - player.chooseToDiscard('h',true,2).logSkill=['shawu',target]; - } - 'step 2' + "step 2"; trigger.target.damage(); }, - intro:{ - content:'mark', + intro: { + content: "mark", }, }, //曹髦 - qianlong:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - content:function(){ - 'step 0' - var cards=get.cards(3); - event.cards=cards; + qianlong: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + content: function () { + "step 0"; + var cards = get.cards(3); + event.cards = cards; game.cardsGotoOrdering(cards); //展示牌 - game.log(player,'展示了',event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards){ - if(player==game.me||player.isUnderControl()) return; - var str=get.translation(player)+'发动了【潜龙】'; - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards); - game.addVideo('showCards',player,[get.translation(player)+'发动了【潜龙】',get.cardsInfo(event.cards)]); - if(player!=game.me&&!player.isUnderControl()&&!player.isOnline()) game.delay(2); + game.log(player, "展示了", event.cards); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards) { + if (player == game.me || player.isUnderControl()) return; + var str = get.translation(player) + "发动了【潜龙】"; + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards + ); + game.addVideo("showCards", player, [ + get.translation(player) + "发动了【潜龙】", + get.cardsInfo(event.cards), + ]); + if (player != game.me && !player.isUnderControl() && !player.isOnline()) game.delay(2); //选牌 - var next=player.chooseToMove('潜龙:获得至多'+get.cnNumber(Math.min(3,player.getDamagedHp()))+'张牌并将其余牌置于牌堆底'); - next.set('list',[ - ['置于牌堆底',cards], - ['自己获得'], - ]) - next.set('filterMove',function(from,to,moved){ - if(moved[0].includes(from.link)){ - if(typeof to=='number'){ - if(to==1){ - if(moved[1].length>=_status.event.player.getDamagedHp()) return false; + var next = player.chooseToMove( + "潜龙:获得至多" + + get.cnNumber(Math.min(3, player.getDamagedHp())) + + "张牌并将其余牌置于牌堆底" + ); + next.set("list", [["置于牌堆底", cards], ["自己获得"]]); + next.set("filterMove", function (from, to, moved) { + if (moved[0].includes(from.link)) { + if (typeof to == "number") { + if (to == 1) { + if (moved[1].length >= _status.event.player.getDamagedHp()) return false; } return true; } } return true; }); - next.set('processAI',function(list){ - let cards=list[0][1].slice(0),player=_status.event.player; - cards.sort((a,b)=>{ - return get.value(b,player)-get.value(a,player); + next.set("processAI", function (list) { + let cards = list[0][1].slice(0), + player = _status.event.player; + cards.sort((a, b) => { + return get.value(b, player) - get.value(a, player); }); - if(!player.storage.juetao&&player.hasSkill('juetao')&&player.hasSha()){ - let gain,bottom,pai=cards.filter(card=>card.name!=='sha'); - pai.sort((a,b)=>{ - return get.value(b,player)-get.value(a,player); + if (!player.storage.juetao && player.hasSkill("juetao") && player.hasSha()) { + let gain, + bottom, + pai = cards.filter((card) => card.name !== "sha"); + pai.sort((a, b) => { + return get.value(b, player) - get.value(a, player); }); - gain = pai.splice(0,player.getDamagedHp()); + gain = pai.splice(0, player.getDamagedHp()); bottom = cards.slice(0); bottom.removeArray(gain); return [bottom, gain]; } - return [cards,cards.splice(0,player.getDamagedHp())]; + return [cards, cards.splice(0, player.getDamagedHp())]; }); - 'step 1' - game.broadcastAll('closeDialog',event.videoId); - game.addVideo('cardDialog',null,event.videoId); - var moved=result.moved; - if(moved[0].length>0){ - for(var i of moved[0]){ + "step 1"; + game.broadcastAll("closeDialog", event.videoId); + game.addVideo("cardDialog", null, event.videoId); + var moved = result.moved; + if (moved[0].length > 0) { + for (var i of moved[0]) { i.fix(); ui.cardPile.appendChild(i); } } - if(moved[1].length>0) player.gain(moved[1],'gain2'); + if (moved[1].length > 0) player.gain(moved[1], "gain2"); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(!target.hasFriend()) return; - var num=1; - if(!player.needsToDiscard()&&target.isDamaged()){ - num=0.7; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (!target.hasFriend()) return; + var num = 1; + if (!player.needsToDiscard() && target.isDamaged()) { + num = 0.7; + } else { + num = 0.5; } - else{ - num=0.5; - } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } - } - } - } + }, + }, + }, }, - fensi:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - content:function(){ - 'step 0' - if(!game.hasPlayer(function(current){ - return current!=player&¤t.hp>=player.hp; - })){ + fensi: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + content: function () { + "step 0"; + if ( + !game.hasPlayer(function (current) { + return current != player && current.hp >= player.hp; + }) + ) { player.damage(); event.finish(); return; + } else { + player + .chooseTarget( + true, + "忿肆:对一名体力值不小于你的角色造成1点伤害", + function (card, player, target) { + return target.hp >= player.hp; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); } - else{ - player.chooseTarget(true,'忿肆:对一名体力值不小于你的角色造成1点伤害',function(card,player,target){ - return target.hp>=player.hp; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); target.damage(); - } - else event.finish(); - 'step 2' - if(target.isIn()&&target.canUse('sha',player,false)) target.useCard({name:'sha',isCard:true},player,false,'noai'); + } else event.finish(); + "step 2"; + if (target.isIn() && target.canUse("sha", player, false)) + target.useCard({ name: "sha", isCard: true }, player, false, "noai"); }, }, - juetao:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - limited:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.hp==1; + juetao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + limited: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.hp == 1; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('juetao'),lib.filter.notMe).set('ai',function(target){ - let att=-get.attitude(_status.event.player,target); - if(att<=0) return att; - if(target.hasSkillTag('nodamage')||target.getEquip('qimenbagua')) return 0.01*att; - if(target.getEquip('tengjia')||target.getEquip('renwang')) return 0.3*att; - if(target.getEquip('rewrite_tengjia')||target.getEquip('rewrite_renwang')) return 0.2*att; - if(target.hasSkillTag('freeShan',false,{ - player:_status.event.player - },true)) return 0.3*att; - if(target.getEquip(2)) return att/2; - return 1.2*att; + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("juetao"), lib.filter.notMe).set("ai", function (target) { + let att = -get.attitude(_status.event.player, target); + if (att <= 0) return att; + if (target.hasSkillTag("nodamage") || target.getEquip("qimenbagua")) + return 0.01 * att; + if (target.getEquip("tengjia") || target.getEquip("renwang")) return 0.3 * att; + if (target.getEquip("rewrite_tengjia") || target.getEquip("rewrite_renwang")) + return 0.2 * att; + if ( + target.hasSkillTag( + "freeShan", + false, + { + player: _status.event.player, + }, + true + ) + ) + return 0.3 * att; + if (target.getEquip(2)) return att / 2; + return 1.2 * att; }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('juetao',target); - player.awakenSkill('juetao'); - } - else event.finish(); - 'step 2' - var card=get.bottomCards()[0]; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("juetao", target); + player.awakenSkill("juetao"); + } else event.finish(); + "step 2"; + var card = get.bottomCards()[0]; game.cardsGotoOrdering(card); player.showCards(card); - player.chooseUseTarget(card,true,false,'nodistance').set('filterTarget',function(card,player,target){ - var evt=_status.event; - if(_status.event.name=='chooseTarget') evt=evt.getParent(); - if(target!=player&&target!=evt.juetao_target) return false; - return lib.filter.targetEnabledx(card,player,target); - }).set('juetao_target',target); - 'step 3' - if(result.bool&&target.isIn()) event.goto(2); + player + .chooseUseTarget(card, true, false, "nodistance") + .set("filterTarget", function (card, player, target) { + var evt = _status.event; + if (_status.event.name == "chooseTarget") evt = evt.getParent(); + if (target != player && target != evt.juetao_target) return false; + return lib.filter.targetEnabledx(card, player, target); + }) + .set("juetao_target", target); + "step 3"; + if (result.bool && target.isIn()) event.goto(2); }, }, - zhushi:{ - audio:2, - usable:1, - trigger:{global:'recoverEnd'}, - direct:true, - zhuSkill:true, - filter:function(event,player){ - return player!=event.player&&event.player.group=='wei'&&event.player==_status.currentPhase&& - event.player.isIn()&&player.hasZhuSkill('zhushi',event.player); + zhushi: { + audio: 2, + usable: 1, + trigger: { global: "recoverEnd" }, + direct: true, + zhuSkill: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.group == "wei" && + event.player == _status.currentPhase && + event.player.isIn() && + player.hasZhuSkill("zhushi", event.player) + ); }, - content:function(){ - 'step 0' - var str=get.translation(player); - trigger.player.chooseBool('是否响应'+get.translation(player)+'的主公技【助势】?','令'+get.translation(player)+'摸一张牌').set('goon',get.attitude(trigger.player,player)>0).set('ai',()=>_status.event.goon); - 'step 1' - if(result.bool){ - player.logSkill('zhushi'); - trigger.player.line(player,'thunder'); + content: function () { + "step 0"; + var str = get.translation(player); + trigger.player + .chooseBool( + "是否响应" + get.translation(player) + "的主公技【助势】?", + "令" + get.translation(player) + "摸一张牌" + ) + .set("goon", get.attitude(trigger.player, player) > 0) + .set("ai", () => _status.event.goon); + "step 1"; + if (result.bool) { + player.logSkill("zhushi"); + trigger.player.line(player, "thunder"); player.draw(); - } - else player.storage.counttrigger.zhushi--; + } else player.storage.counttrigger.zhushi--; }, }, //骆统 - renzheng:{ - audio:2, - trigger:{global:['damageCancelled','damageZero','damageAfter']}, - forced:true, - filter:function(event,player,name){ - if(name=='damageCancelled') return true; - for(var i of event.change_history){ - if(i<0) return true; + renzheng: { + audio: 2, + trigger: { global: ["damageCancelled", "damageZero", "damageAfter"] }, + forced: true, + filter: function (event, player, name) { + if (name == "damageCancelled") return true; + for (var i of event.change_history) { + if (i < 0) return true; } return false; }, - content:function(){ + content: function () { player.draw(2); }, }, - jinjian:{ - audio:2, - trigger:{source:'damageBegin1'}, - logTarget:'player', - filter:function(event,player){ - return !event.jinjian_source2&&!player.hasSkill('jinjian_source2'); + jinjian: { + audio: 2, + trigger: { source: "damageBegin1" }, + logTarget: "player", + filter: function (event, player) { + return !event.jinjian_source2 && !player.hasSkill("jinjian_source2"); }, - prompt2:'令即将对其造成的伤害+1', - check:function(event,player){ - return get.attitude(player,event.player)<0&&!event.player.hasSkillTag('filterDamage',null,{ - player:player, - card:event.card, - }); + prompt2: "令即将对其造成的伤害+1", + check: function (event, player) { + return ( + get.attitude(player, event.player) < 0 && + !event.player.hasSkillTag("filterDamage", null, { + player: player, + card: event.card, + }) + ); }, - content:function(){ - trigger.jinjian_source=true; + content: function () { + trigger.jinjian_source = true; trigger.num++; - player.addTempSkill('jinjian_source2') + player.addTempSkill("jinjian_source2"); }, - group:'jinjian_player', - subSkill:{ - player:{ - audio:'jinjian', - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return !event.jinjian_player2&&!player.hasSkill('jinjian_player2'); + group: "jinjian_player", + subSkill: { + player: { + audio: "jinjian", + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return !event.jinjian_player2 && !player.hasSkill("jinjian_player2"); }, - prompt2:'令即将受到的伤害-1', - content:function(){ - trigger.jinjian_player=true; + prompt2: "令即将受到的伤害-1", + content: function () { + trigger.jinjian_player = true; trigger.num--; - player.addTempSkill('jinjian_player2') + player.addTempSkill("jinjian_player2"); }, }, - source2:{ - trigger:{source:'damageBegin1'}, - forced:true, - charlotte:true, - filter:function(event,player){ + source2: { + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + filter: function (event, player) { return !event.jinjian_source; }, - content:function(){ + content: function () { trigger.num--; - trigger.jinjian_source2=true; - player.removeSkill('jinjian_source2'); + trigger.jinjian_source2 = true; + player.removeSkill("jinjian_source2"); }, - marktext:' -1 ', - intro:{ - content:'下次造成的伤害-1', + marktext: " -1 ", + intro: { + content: "下次造成的伤害-1", }, }, - player2:{ - trigger:{player:'damageBegin3'}, - forced:true, - charlotte:true, - filter:function(event,player){ + player2: { + trigger: { player: "damageBegin3" }, + forced: true, + charlotte: true, + filter: function (event, player) { return !event.jinjian_player; }, - content:function(){ + content: function () { trigger.num++; - trigger.jinjian_player2=true; - player.removeSkill('jinjian_player2'); + trigger.jinjian_player2 = true; + player.removeSkill("jinjian_player2"); }, - marktext:' +1 ', - intro:{ - content:'下次受到的伤害+1', + marktext: " +1 ", + intro: { + content: "下次受到的伤害+1", }, }, }, - ai:{ - maixie_defend:true, - threaten:0.9, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing')) return; + ai: { + maixie_defend: true, + threaten: 0.9, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing")) return; //if(target.hujia) return; - if(player._jinjian_tmp) return; - if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; - if(get.tag(card,'damage')){ - if(target.hasSkill('jinjian_player2')){ - return [1,-2]; - } - else{ - if(get.attitude(player,target)>0){ - return [0,0.2]; + if (player._jinjian_tmp) return; + if ( + _status.event.getParent("useCard", true) || + _status.event.getParent("_wuxie", true) + ) + return; + if (get.tag(card, "damage")) { + if (target.hasSkill("jinjian_player2")) { + return [1, -2]; + } else { + if (get.attitude(player, target) > 0) { + return [0, 0.2]; } - if(get.attitude(player,target)<0&&!player.hasSkillTag('damageBonus')){ - var sha=player.getCardUsable({name:'sha'}); - player._jinjian_tmp=true; - var num=player.countCards('h',function(card){ - if(card.name=='sha'){ - if(sha==0){ + if ( + get.attitude(player, target) < 0 && + !player.hasSkillTag("damageBonus") + ) { + var sha = player.getCardUsable({ name: "sha" }); + player._jinjian_tmp = true; + var num = player.countCards("h", function (card) { + if (card.name == "sha") { + if (sha == 0) { return false; - } - else{ + } else { sha--; } } - return get.tag(card,'damage')&&player.canUse(card,target)&&get.effect(target,card,player,player)>0; + return ( + get.tag(card, "damage") && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); }); delete player._jinjian_tmp; - if(player.hasSkillTag('damage')){ + if (player.hasSkillTag("damage")) { num++; } - if(num<2){ - return [0,0.8]; + if (num < 2) { + return [0, 0.8]; } } } } - } - } - } - }, - //冯妤 - tiqi:{ - audio:2, - trigger:{global:['phaseDrawEnd','phaseDrawSkipped','phaseDrawCancelled']}, - filter:function(event,player){ - if(player==event.player) return false; - var num=0; - event.player.getHistory('gain',function(evt){ - if(evt.getParent().name=='draw'&&evt.getParent('phaseDraw')==event) num+=evt.cards.length; - }); - return num!=2; - }, - frequent:true, - logTarget:'player', - content:function(){ - 'step 0' - var num=0; - trigger.player.getHistory('gain',function(evt){ - if(evt.getParent().name=='draw'&&evt.getParent('phaseDraw')==trigger) num+=evt.cards.length; - }); - num=Math.abs(num-2); - event.num=num; - player.draw(num); - 'step 1' - if(trigger.player.isIn()){ - player.chooseControl(' +'+num+' ',' -'+num+' ','cancel2').set('prompt','是否改变'+get.translation(trigger.player)+'本回合的手牌上限?').set('ai',function(){ - var sgn=get.sgn(get.attitude(_status.event.player,_status.event.getTrigger().player)); - if(sgn==0) return 2; - if(sgn==1) return 0; - return 1; - }); - } - else event.finish(); - 'step 2' - if(result.index<2){ - var target=trigger.player; - player.line(target); - if(!target.storage.tiqi_effect) target.storage.tiqi_effect=0; - target.storage.tiqi_effect+=(num*get.sgn(0.5-result.index)); - target.addTempSkill('tiqi_effect'); - target.markSkill('tiqi_effect'); - } - }, - subSkill:{ - effect:{ - mod:{ - maxHandcard:function(player,num){ - if(typeof player.storage.tiqi_effect=='number') return num+player.storage.tiqi_effect; - }, - }, - charlotte:true, - onremove:true, - mark:true, - intro:{ - content:(num)=>('手牌上限'+(num<0?'':'+')+num), }, }, }, }, - baoshu:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return player.maxHp>0; - }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.maxHp],get.prompt('baoshu'),'令至多'+get.cnNumber(player.maxHp)+'名角色重置武将牌并获得“梳”').set('ai',function(target){ - var att=get.attitude(player,target); - if(att<=0) return 0; - //if(target.isTurnedOver()) return 3*att; - if(target.isLinked()&&get.effect(target,{name:'tiesuo'},player,player)>0) return 1.6*att; - if(ui.selected.targets.length>=Math.sqrt(1+player.maxHp)) return 0; - if(target!=player) return 1.3*att; - return att; + //冯妤 + tiqi: { + audio: 2, + trigger: { global: ["phaseDrawEnd", "phaseDrawSkipped", "phaseDrawCancelled"] }, + filter: function (event, player) { + if (player == event.player) return false; + var num = 0; + event.player.getHistory("gain", function (evt) { + if (evt.getParent().name == "draw" && evt.getParent("phaseDraw") == event) + num += evt.cards.length; }); - 'step 1' - if(result.bool){ - var targets=result.targets; - targets.sortBySeat(); - player.logSkill('baoshu',targets); - event.targets=targets; - event.num=0; - event.num2=(1+player.maxHp-targets.length); + return num != 2; + }, + frequent: true, + logTarget: "player", + content: function () { + "step 0"; + var num = 0; + trigger.player.getHistory("gain", function (evt) { + if (evt.getParent().name == "draw" && evt.getParent("phaseDraw") == trigger) + num += evt.cards.length; + }); + num = Math.abs(num - 2); + event.num = num; + player.draw(num); + "step 1"; + if (trigger.player.isIn()) { + player + .chooseControl(" +" + num + " ", " -" + num + " ", "cancel2") + .set( + "prompt", + "是否改变" + get.translation(trigger.player) + "本回合的手牌上限?" + ) + .set("ai", function () { + var sgn = get.sgn( + get.attitude(_status.event.player, _status.event.getTrigger().player) + ); + if (sgn == 0) return 2; + if (sgn == 1) return 0; + return 1; + }); + } else event.finish(); + "step 2"; + if (result.index < 2) { + var target = trigger.player; + player.line(target); + if (!target.storage.tiqi_effect) target.storage.tiqi_effect = 0; + target.storage.tiqi_effect += num * get.sgn(0.5 - result.index); + target.addTempSkill("tiqi_effect"); + target.markSkill("tiqi_effect"); } - else event.finish(); - 'step 2' - var target=targets[num]; - event.target=target; - if(!target.isIn()){ - if(num "手牌上限" + (num < 0 ? "" : "+") + num, + }, + }, + }, + }, + baoshu: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return player.maxHp > 0; + }, + content: function () { + "step 0"; + player + .chooseTarget( + [1, player.maxHp], + get.prompt("baoshu"), + "令至多" + get.cnNumber(player.maxHp) + "名角色重置武将牌并获得“梳”" + ) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att <= 0) return 0; + //if(target.isTurnedOver()) return 3*att; + if ( + target.isLinked() && + get.effect(target, { name: "tiesuo" }, player, player) > 0 + ) + return 1.6 * att; + if (ui.selected.targets.length >= Math.sqrt(1 + player.maxHp)) return 0; + if (target != player) return 1.3 * att; + return att; + }); + "step 1"; + if (result.bool) { + var targets = result.targets; + targets.sortBySeat(); + player.logSkill("baoshu", targets); + event.targets = targets; + event.num = 0; + event.num2 = 1 + player.maxHp - targets.length; + } else event.finish(); + "step 2"; + var target = targets[num]; + event.target = target; + if (!target.isIn()) { + if (num < targets.length - 1) { event.num++; event.goto(2); - } - else event.finish(); - } - else if(target.isLinked()) target.link(); - 'step 3' - if(target.isIn()) target.addMark('baoshu',event.num2); - if(num0; + tianyun: { + audio: 2, + trigger: { global: "phaseBegin" }, + frequent: true, + filter: function (event, player) { + return event.player.getSeatNum() == game.roundNumber && player.countCards("h") > 0; }, - content:function(){ - 'step 0' - var suits=[],hs=player.getCards('h'); - for(var i of hs){ - suits.add(get.suit(i,player)); + content: function () { + "step 0"; + var suits = [], + hs = player.getCards("h"); + for (var i of hs) { + suits.add(get.suit(i, player)); } - var num=suits.length; - event.num=num; - var cards=get.cards(num); + var num = suits.length; + event.num = num; + var cards = get.cards(num); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','天运:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1] - return [[],cards]; - } - 'step 1' - var top=result.moved[0]; - var bottom=result.moved[1]; + var next = player.chooseToMove(); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("prompt", "天运:点击将牌移动到牌堆顶或牌堆底"); + next.processAI = function (list) { + var cards = list[0][1]; + return [[], cards]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i1&&player.hp>5-num); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 2"; + player + .chooseTarget("是否令一名角色摸" + get.cnNumber(num) + "张牌,然后失去1点体力?") + .set("", function (target) { + if (!_status.event.goon || target.hasSkillTag("nogain")) return 0; + return ( + get.attitude(_status.event.player, target) * + Math.sqrt(Math.max(1, 5 - target.getCards("h"))) + ); + }) + .set("goon", num > 1 && player.hp > 5 - num); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(num); player.loseHp(); - } - else game.delayx(); + } else game.delayx(); }, - group:'tianyun_gain', - subSkill:{ - gain:{ - audio:'tianyun', - trigger:{ - global:'phaseBefore', - player:'enterGame', + group: "tianyun_gain", + subSkill: { + gain: { + audio: "tianyun", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - if(event.name=='phase'&&game.phaseNumber!=0) return false; - var suits=lib.suit.slice(0),hs=player.getCards('h'); - for(var i of hs){ - suits.remove(get.suit(i,player)); - if(!suits.length) return false; + forced: true, + locked: false, + filter: function (event, player) { + if (event.name == "phase" && game.phaseNumber != 0) return false; + var suits = lib.suit.slice(0), + hs = player.getCards("h"); + for (var i of hs) { + suits.remove(get.suit(i, player)); + if (!suits.length) return false; } return true; }, - content:function(){ - var suits=lib.suit.slice(0),hs=player.getCards('h'); - for(var i of hs){ - suits.remove(get.suit(i,player)); + content: function () { + var suits = lib.suit.slice(0), + hs = player.getCards("h"); + for (var i of hs) { + suits.remove(get.suit(i, player)); } - var cards=[]; - for(var i of suits){ - var card=get.cardPile(function(card){ - return get.suit(card,false)==i; + var cards = []; + for (var i of suits) { + var card = get.cardPile(function (card) { + return get.suit(card, false) == i; }); - if(card) cards.push(card); + if (card) cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, }, }, }, - wfyuyan:{ - audio:2, - derivation:'refenyin', - trigger:{global:'roundStart'}, - forced:true, - locked:false, - content:function(){ - 'step 0' - var next=player.chooseTarget('请选择【预言】的目标',true).set('animate',false).set('ai',function(){ - return Math.random(); - }); - 'step 1' - if(result.bool){ - player.storage.wfyuyan=result.targets[0]; - player.addSkill('wfyuyan_dying'); - player.addSkill('wfyuyan_damage'); + wfyuyan: { + audio: 2, + derivation: "refenyin", + trigger: { global: "roundStart" }, + forced: true, + locked: false, + content: function () { + "step 0"; + var next = player + .chooseTarget("请选择【预言】的目标", true) + .set("animate", false) + .set("ai", function () { + return Math.random(); + }); + "step 1"; + if (result.bool) { + player.storage.wfyuyan = result.targets[0]; + player.addSkill("wfyuyan_dying"); + player.addSkill("wfyuyan_damage"); } }, - subSkill:{ - dying:{ - trigger:{global:'dying'}, - forced:true, - charlotte:true, - popup:false, - content:function(){ - if(trigger.player==player.storage.wfyuyan){ - player.logSkill('wfyuyan',trigger.player); - player.addTempSkill('iwasawa_refenyin',{player:'phaseEnd'}); + subSkill: { + dying: { + trigger: { global: "dying" }, + forced: true, + charlotte: true, + popup: false, + content: function () { + if (trigger.player == player.storage.wfyuyan) { + player.logSkill("wfyuyan", trigger.player); + player.addTempSkill("iwasawa_refenyin", { player: "phaseEnd" }); } - player.removeSkill('wfyuyan_dying'); + player.removeSkill("wfyuyan_dying"); }, }, - damage:{ - trigger:{global:'damageSource'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return event.source&&event.source.isIn(); + damage: { + trigger: { global: "damageSource" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return event.source && event.source.isIn(); }, - content:function(){ - if(trigger.source==player.storage.wfyuyan){ - player.logSkill('wfyuyan',trigger.source); + content: function () { + if (trigger.source == player.storage.wfyuyan) { + player.logSkill("wfyuyan", trigger.source); player.draw(2); } - player.removeSkill('wfyuyan_damage'); + player.removeSkill("wfyuyan_damage"); }, }, }, }, //张宝 - xinzhoufu:{ - audio:'zhoufu', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0; + xinzhoufu: { + audio: "zhoufu", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player&&!target.getExpansions('xinzhoufu2').length; + filterCard: true, + filterTarget: function (card, player, target) { + return target != player && !target.getExpansions("xinzhoufu2").length; }, - check:function(card){ - return 6-get.value(card) + check: function (card) { + return 6 - get.value(card); }, - position:'he', - discard:false, - lose:false, - delay:false, - content:function(){ - target.addToExpansion(cards,player,'give').gaintag.add('xinzhoufu2'); - target.addSkill('xinzhoufu_judge'); + position: "he", + discard: false, + lose: false, + delay: false, + content: function () { + target.addToExpansion(cards, player, "give").gaintag.add("xinzhoufu2"); + target.addSkill("xinzhoufu_judge"); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(player.inRange(target)) return -1.3; + ai: { + order: 9, + result: { + target: function (player, target) { + if (player.inRange(target)) return -1.3; return -1; }, }, }, - subSkill:{ - judge:{ - audio:'zhoufu', - trigger:{player:'judgeBefore'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return !event.directresult&&player.getExpansions('xinzhoufu2').length; + subSkill: { + judge: { + audio: "zhoufu", + trigger: { player: "judgeBefore" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return !event.directresult && player.getExpansions("xinzhoufu2").length; }, - content:function(){ - var cards=[player.getExpansions('xinzhoufu2')[0]]; - trigger.directresult=cards[0]; + content: function () { + var cards = [player.getExpansions("xinzhoufu2")[0]]; + trigger.directresult = cards[0]; }, }, }, }, - xinzhoufu2:{ - intro:{ - content:'expansion', - markcount:'expansion', + xinzhoufu2: { + intro: { + content: "expansion", + markcount: "expansion", }, }, - xinyingbing:{ - audio:'yingbin', - trigger:{player:'useCardToPlayered'}, - forced:true, - logTarget:'target', - filter:function(event,player){ - return event.target.getExpansions('xinzhoufu2').length>0&&!player.hasHistory('gain',function(evt){ - var evtx=evt.getParent(2); - return evtx&&evtx.name=='xinyingbing'&&evtx._trigger.target==event.target; - }); + xinyingbing: { + audio: "yingbin", + trigger: { player: "useCardToPlayered" }, + forced: true, + logTarget: "target", + filter: function (event, player) { + return ( + event.target.getExpansions("xinzhoufu2").length > 0 && + !player.hasHistory("gain", function (evt) { + var evtx = evt.getParent(2); + return evtx && evtx.name == "xinyingbing" && evtx._trigger.target == event.target; + }) + ); }, - content:function(){ + content: function () { player.draw(2); }, - ai:{ - effect:{ - player:function(card,player,target){ - if(target&&target.getExpansions('xinzhoufu2').length>0&&!player.hasHistory('gain',function(evt){ - var evtx=evt.getParent(2); - return evtx&&evtx.name=='xinyingbing'&&evtx._trigger.target==target; - })) return [1,1]; + ai: { + effect: { + player: function (card, player, target) { + if ( + target && + target.getExpansions("xinzhoufu2").length > 0 && + !player.hasHistory("gain", function (evt) { + var evtx = evt.getParent(2); + return ( + evtx && evtx.name == "xinyingbing" && evtx._trigger.target == target + ); + }) + ) + return [1, 1]; }, }, + combo: "xinzhoufu", }, }, //孙翊 - syjiqiao:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - content:function(){ - var cards=get.cards(player.maxHp); - cards.sort(function(a,b){ - return get.color(b).length-get.color(a).length; + syjiqiao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + content: function () { + var cards = get.cards(player.maxHp); + cards.sort(function (a, b) { + return get.color(b).length - get.color(a).length; }); - player.addToExpansion(cards,'gain2').gaintag.add('syjiqiao'); - player.addTempSkill('syjiqiao_gain','phaseUseAfter'); + player.addToExpansion(cards, "gain2").gaintag.add("syjiqiao"); + player.addTempSkill("syjiqiao_gain", "phaseUseAfter"); }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - subSkill:{ - gain:{ - audio:'syjiqiao', - trigger:{player:'useCardAfter'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return player.hasCard((card)=>card.hasGaintag('syjiqiao'),'x'); + subSkill: { + gain: { + audio: "syjiqiao", + trigger: { player: "useCardAfter" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return player.hasCard((card) => card.hasGaintag("syjiqiao"), "x"); }, - content:function(){ - 'step 0' - var cards=player.getExpansions('syjiqiao') - var dialog=['激峭:选择获得一张牌'] - var reds=[],blacks=[]; - for(var i of cards) (get.color(i)=='red'?reds:blacks).push(i); - if(reds.length>0){ + content: function () { + "step 0"; + var cards = player.getExpansions("syjiqiao"); + var dialog = ["激峭:选择获得一张牌"]; + var reds = [], + blacks = []; + for (var i of cards) (get.color(i) == "red" ? reds : blacks).push(i); + if (reds.length > 0) { dialog.push('
              红色牌
              '); dialog.push(reds); } - if(blacks.length>0){ + if (blacks.length > 0) { dialog.push('
              黑色牌
              '); dialog.push(blacks); } - player.chooseButton(dialog,true).set('ai',function(button){ - var player=_status.event.player; - var color=get.color(button.link),cards=player.getExpansions('syjiqiao'); - var num1=cards.filter((card)=>get.color(card)==color).length,num2=cards.length-num1; - if(num1>=num2) return get.value(button.link); + player.chooseButton(dialog, true).set("ai", function (button) { + var player = _status.event.player; + var color = get.color(button.link), + cards = player.getExpansions("syjiqiao"); + var num1 = cards.filter((card) => get.color(card) == color).length, + num2 = cards.length - num1; + if (num1 >= num2) return get.value(button.link); return 0; }); - 'step 1' - if(result.bool){ - player.gain(result.links,'gain2'); + "step 1"; + if (result.bool) { + player.gain(result.links, "gain2"); + } else event.finish(); + "step 2"; + var map = { red: 0, black: 0 }, + cards = player.getExpansions("syjiqiao"); + for (var i of cards) { + var color = get.color(i, false); + if (map[color] != undefined) map[color]++; } - else event.finish(); - 'step 2' - var map={red:0,black:0},cards=player.getExpansions('syjiqiao') - for(var i of cards){ - var color=get.color(i,false); - if(map[color]!=undefined) map[color]++; - } - if(map.red==map.black) player.recover(); + if (map.red == map.black) player.recover(); else player.loseHp(); }, - onremove:function(player){ - var cards=player.getExpansions('syjiqiao') - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player) { + var cards = player.getExpansions("syjiqiao"); + if (cards.length) player.loseToDiscardpile(cards); }, }, }, }, - syxiongyi:{ - audio:2, - skillAnimation:true, - animationColor:'wood', - limited:true, - enable:'chooseToUse', - filter:function(event,player){ - if(event.type!='dying') return false; - if(player!=event.dying) return false; + syxiongyi: { + audio: 2, + skillAnimation: true, + animationColor: "wood", + limited: true, + enable: "chooseToUse", + filter: function (event, player) { + if (event.type != "dying") return false; + if (player != event.dying) return false; return true; }, - async content(event,trigger,player){ - 'step 0' - player.awakenSkill('syxiongyi'); - if(!_status.characterlist){ + async content(event, trigger, player) { + "step 0"; + player.awakenSkill("syxiongyi"); + if (!_status.characterlist) { lib.skill.pingjian.initList(); } - if(_status.characterlist.includes('xushi')){ - if (player.name2&&get.character(player.name2)[3].includes('syxiongyi')) { - await player.reinitCharacter(player.name2, 'xushi'); + if (_status.characterlist.includes("xushi")) { + if (player.name2 && get.character(player.name2)[3].includes("syxiongyi")) { + await player.reinitCharacter(player.name2, "xushi"); + } else { + await player.reinitCharacter(player.name1, "xushi"); } - else { - await player.reinitCharacter(player.name1, 'xushi'); - } - if(player.hp<3) await player.recover(3-player.hp); - } - else{ - await player.addSkills('olhunzi'); - if(player.hp<1) await player.recover(1-player.hp); + if (player.hp < 3) await player.recover(3 - player.hp); + } else { + await player.addSkills("olhunzi"); + if (player.hp < 1) await player.recover(1 - player.hp); } }, - ai:{ - order:1, - save:true, - skillTagFilter:function(player,arg,target){ - return player==target; + ai: { + order: 1, + save: true, + skillTagFilter: function (player, arg, target) { + return player == target; }, - result:{ - player:10 + result: { + player: 10, }, }, - derivation:['olhunzi','reyingzi','gzyinghun'], + derivation: ["olhunzi", "reyingzi", "gzyinghun"], }, - gzyinghun_re_sunyi:{audio:1}, - reyingzi_re_sunyi:{audio:1}, + gzyinghun_re_sunyi: { audio: 1 }, + reyingzi_re_sunyi: { audio: 1 }, //曹金玉 - yuqi:{ - audio:2, - trigger:{global:'damageEnd'}, - init:function(player){ - if(!player.storage.yuqi) player.storage.yuqi=[0,3,1,1]; + yuqi: { + audio: 2, + trigger: { global: "damageEnd" }, + init: function (player) { + if (!player.storage.yuqi) player.storage.yuqi = [0, 3, 1, 1]; }, - getInfo:function(player){ - if(!player.storage.yuqi) player.storage.yuqi=[0,3,1,1]; + getInfo: function (player) { + if (!player.storage.yuqi) player.storage.yuqi = [0, 3, 1, 1]; return player.storage.yuqi; }, - onremove:true, - usable:2, - filter:function(event,player){ - var list=lib.skill.yuqi.getInfo(player); - return event.player.isIn()&&get.distance(player,event.player)<=list[0]; + onremove: true, + usable: 2, + filter: function (event, player) { + var list = lib.skill.yuqi.getInfo(player); + return event.player.isIn() && get.distance(player, event.player) <= list[0]; }, - logTarget:'player', - content:function(){ - 'step 0' - event.list=lib.skill.yuqi.getInfo(player); - var cards=get.cards(event.list[1]); - event.cards=cards; + logTarget: "player", + content: function () { + "step 0"; + event.list = lib.skill.yuqi.getInfo(player); + var cards = get.cards(event.list[1]); + event.cards = cards; game.cardsGotoOrdering(cards); - var next=player.chooseToMove(true,'隅泣(若对话框显示不完整,可下滑操作)'); - next.set('list',[ - ['牌堆顶的牌',cards], - ['交给'+get.translation(trigger.player)+'(至少一张'+(event.list[2]>1?(',至多'+get.cnNumber(event.list[2])+'张'):'')+')'], - ['交给自己(至多'+get.cnNumber(event.list[3])+'张)'], + var next = player.chooseToMove(true, "隅泣(若对话框显示不完整,可下滑操作)"); + next.set("list", [ + ["牌堆顶的牌", cards], + [ + "交给" + + get.translation(trigger.player) + + "(至少一张" + + (event.list[2] > 1 ? ",至多" + get.cnNumber(event.list[2]) + "张" : "") + + ")", + ], + ["交给自己(至多" + get.cnNumber(event.list[3]) + "张)"], ]); - next.set('filterMove',function(from,to,moved){ - var info=lib.skill.yuqi.getInfo(_status.event.player); - if(to==1) return moved[1].length0) card2=cards.shift(); - else card2=cards.pop(); - return [cards,[card2],cards1]; + if (get.attitude(player, target) > 0) card2 = cards.shift(); + else card2 = cards.pop(); + return [cards, [card2], cards1]; }); - next.set('filterOk',function(moved){ - return moved[1].length>0; + next.set("filterOk", function (moved) { + return moved[1].length > 0; }); - 'step 1' - if(result.bool){ - var moved=result.moved; + "step 1"; + if (result.bool) { + var moved = result.moved; cards.removeArray(moved[1]); cards.removeArray(moved[2]); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); } - var list=[[trigger.player,moved[1]]]; - if(moved[2].length) list.push([player,moved[2]]); + var list = [[trigger.player, moved[1]]]; + if (moved[2].length) list.push([player, moved[2]]); game.loseAsync({ - gain_list:list, - giver:player, - animate:'gain2', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "gain2", + }).setContent("gaincardMultiple"); } }, - mark:true, - intro:{ - content:function(storage,player){ - var info=lib.skill.yuqi.getInfo(player); - return '
              蓝色:'+info[0]+' 红色:'+info[1]+'
              绿色:'+info[2]+' 黄色:'+info[3]+'
              ' + mark: true, + intro: { + content: function (storage, player) { + var info = lib.skill.yuqi.getInfo(player); + return ( + '
              蓝色:' + + info[0] + + " 红色:" + + info[1] + + "
              绿色:" + + info[2] + + " 黄色:" + + info[3] + + "
              " + ); }, }, - ai:{ - threaten:8.8, + ai: { + threaten: 8.8, }, }, - shanshen:{ - audio:2, - trigger:{global:'die'}, - direct:true, - content:function(){ - 'step 0' - event.goon=!player.hasAllHistory('sourceDamage',function(evt){ - return evt.player==trigger.player; + shanshen: { + audio: 2, + trigger: { global: "die" }, + direct: true, + content: function () { + "step 0"; + event.goon = !player.hasAllHistory("sourceDamage", function (evt) { + return evt.player == trigger.player; }); - var list=lib.skill.yuqi.getInfo(player); - player.chooseControl('蓝色('+list[0]+')','红色('+list[1]+')','绿色('+list[2]+')','黄色('+list[3]+')','cancel2').set('prompt',get.prompt('shanshen')).set('prompt2','令〖隅泣〗中的一个数字+2'+(event.goon?'并回复1点体力':'')).set('ai',function(){ - var player=_status.event.player,info=lib.skill.yuqi.getInfo(player); - if(info[0]info[0]; - })) return 0; - return 2; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('shanshen',trigger.player); - var list=lib.skill.yuqi.getInfo(player); - list[result.index]=Math.min(5,list[result.index]+2); - game.log(player,'将',result.control,'数字改为','#y'+list[result.index]) - player.markSkill('yuqi'); - if(event.goon) player.recover(); + var list = lib.skill.yuqi.getInfo(player); + player + .chooseControl( + "蓝色(" + list[0] + ")", + "红色(" + list[1] + ")", + "绿色(" + list[2] + ")", + "黄色(" + list[3] + ")", + "cancel2" + ) + .set("prompt", get.prompt("shanshen")) + .set("prompt2", "令〖隅泣〗中的一个数字+2" + (event.goon ? "并回复1点体力" : "")) + .set("ai", function () { + var player = _status.event.player, + info = lib.skill.yuqi.getInfo(player); + if ( + info[0] < info[3] && + game.countPlayer(function (current) { + return get.distance(player, current) <= info[0]; + }) < Math.min(3, game.countPlayer()) + ) + return 0; + if (info[3] < info[1] - 1) return 3; + if (info[1] < 5) return 1; + if ( + info[0] < 5 && + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) > info[0]; + }) + ) + return 0; + return 2; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("shanshen", trigger.player); + var list = lib.skill.yuqi.getInfo(player); + list[result.index] = Math.min(5, list[result.index] + 2); + game.log(player, "将", result.control, "数字改为", "#y" + list[result.index]); + player.markSkill("yuqi"); + if (event.goon) player.recover(); } }, + ai: { + combo: "yuqi" + }, }, - xianjing:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - var list=lib.skill.yuqi.getInfo(player); - player.chooseControl('蓝色('+list[0]+')','红色('+list[1]+')','绿色('+list[2]+')','黄色('+list[3]+')','cancel2').set('prompt',get.prompt('xianjing')).set('prompt2','令〖隅泣〗中的一个数字+1').set('ai',function(){ - var player=_status.event.player,info=lib.skill.yuqi.getInfo(player); - if(info[0]info[0]; - })) return 0; - return 2; - }); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xianjing'); - var list=lib.skill.yuqi.getInfo(player); - list[result.index]=Math.min(5,list[result.index]+1); - game.log(player,'将',result.control,'数字改为','#y'+list[result.index]) - player.markSkill('yuqi'); - if(player.isDamaged()) event.finish(); - } - else event.finish(); - 'step 2' - var list=lib.skill.yuqi.getInfo(player); - player.chooseControl('蓝色('+list[0]+')','红色('+list[1]+')','绿色('+list[2]+')','黄色('+list[3]+')','cancel2').set('prompt','是否令〖隅泣〗中的一个数字+1?').set('ai',function(){ - var player=_status.event.player,info=lib.skill.yuqi.getInfo(player); - if(info[0]info[0]; - })) return 0; - return 2; - }); - 'step 3' - if(result.control!='cancel2'){ - var list=lib.skill.yuqi.getInfo(player); - list[result.index]=Math.min(5,list[result.index]+1); - game.log(player,'将',result.control,'数字改为','#y'+list[result.index]) - player.markSkill('yuqi'); + xianjing: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + var list = lib.skill.yuqi.getInfo(player); + player + .chooseControl( + "蓝色(" + list[0] + ")", + "红色(" + list[1] + ")", + "绿色(" + list[2] + ")", + "黄色(" + list[3] + ")", + "cancel2" + ) + .set("prompt", get.prompt("xianjing")) + .set("prompt2", "令〖隅泣〗中的一个数字+1") + .set("ai", function () { + var player = _status.event.player, + info = lib.skill.yuqi.getInfo(player); + if ( + info[0] < info[3] && + game.countPlayer(function (current) { + return get.distance(player, current) <= info[0]; + }) < Math.min(3, game.countPlayer()) + ) + return 0; + if (info[3] < info[1] - 1) return 3; + if (info[1] < 5) return 1; + if ( + info[0] < 5 && + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) > info[0]; + }) + ) + return 0; + return 2; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xianjing"); + var list = lib.skill.yuqi.getInfo(player); + list[result.index] = Math.min(5, list[result.index] + 1); + game.log(player, "将", result.control, "数字改为", "#y" + list[result.index]); + player.markSkill("yuqi"); + if (player.isDamaged()) event.finish(); + } else event.finish(); + "step 2"; + var list = lib.skill.yuqi.getInfo(player); + player + .chooseControl( + "蓝色(" + list[0] + ")", + "红色(" + list[1] + ")", + "绿色(" + list[2] + ")", + "黄色(" + list[3] + ")", + "cancel2" + ) + .set("prompt", "是否令〖隅泣〗中的一个数字+1?") + .set("ai", function () { + var player = _status.event.player, + info = lib.skill.yuqi.getInfo(player); + if ( + info[0] < info[3] && + game.countPlayer(function (current) { + return get.distance(player, current) <= info[0]; + }) < Math.min(3, game.countPlayer()) + ) + return 0; + if (info[3] < info[1] - 1) return 3; + if (info[1] < 5) return 1; + if ( + info[0] < 5 && + game.hasPlayer(function (current) { + return current != player && get.distance(player, current) > info[0]; + }) + ) + return 0; + return 2; + }); + "step 3"; + if (result.control != "cancel2") { + var list = lib.skill.yuqi.getInfo(player); + list[result.index] = Math.min(5, list[result.index] + 1); + game.log(player, "将", result.control, "数字改为", "#y" + list[result.index]); + player.markSkill("yuqi"); } }, + ai: { + combo: "yuqi" + }, }, //周夷 - zhukou:{ - audio:2, - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(!player.getHistory('useCard').length) return false; - var evt=event.getParent('phaseUse'); - if(!evt||!evt.player) return false; - return player.getHistory('sourceDamage',function(evtx){ - return evtx.getParent('phaseUse')==evt; - }).indexOf(event)==0; + zhukou: { + audio: 2, + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (!player.getHistory("useCard").length) return false; + var evt = event.getParent("phaseUse"); + if (!evt || !evt.player) return false; + return ( + player + .getHistory("sourceDamage", function (evtx) { + return evtx.getParent("phaseUse") == evt; + }) + .indexOf(event) == 0 + ); }, - frequent:true, - content:function(){ - player.draw(player.getHistory('useCard').length); + frequent: true, + content: function () { + player.draw(player.getHistory("useCard").length); }, - group:'zhukou_all', - subSkill:{ - all:{ - audio:'zhukou', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return game.countPlayer((current)=>(current!=player))>1&&!player.getHistory('sourceDamage').length; + group: "zhukou_all", + subSkill: { + all: { + audio: "zhukou", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + game.countPlayer((current) => current != player) > 1 && + !player.getHistory("sourceDamage").length + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhukou'),'对两名其他角色各造成1点伤害',2,lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('zhukou',targets); - for(var i of targets) i.damage(); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhukou"), + "对两名其他角色各造成1点伤害", + 2, + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("zhukou", targets); + for (var i of targets) i.damage(); } }, }, }, }, - mengqing:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return game.countPlayer((current)=>current.isDamaged())>player.hp; + mengqing: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return game.countPlayer((current) => current.isDamaged()) > player.hp; }, - juexingji:true, - skillAnimation:true, - animationColor:'wood', - content:function(){ - player.awakenSkill('mengqing'); + juexingji: true, + skillAnimation: true, + animationColor: "wood", + content: function () { + player.awakenSkill("mengqing"); player.gainMaxHp(3); player.recover(3); //player.removeSkill('zhukou'); //player.addSkill('yuyun'); - player.changeSkills(['yuyun'],['zhukou']); + player.changeSkills(["yuyun"], ["zhukou"]); }, - derivation:'yuyun', + derivation: "yuyun", }, - yuyun:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - filter:function(event,player){ - return player.hp>0||player.maxHp>1; + yuyun: { + trigger: { player: "phaseUseBegin" }, + forced: true, + filter: function (event, player) { + return player.hp > 0 || player.maxHp > 1; }, - content:function(){ - 'step 0' - if(player.maxHp<=1) event._result={control:'失去体力',index:0}; - else if(player.hp<1) event._result={control:'减体力上限',index:1}; - else player.chooseControl('失去体力','减体力上限').set('prompt','玉陨:失去1点体力或减1点体力上限').set('ai',function(){ - var player=_status.event.player; - if(player.hp<2||player.getDamagedHp()>2) return 1; - return 0; - }); - 'step 1' - if(result.index==1) player.loseMaxHp(); + content: function () { + "step 0"; + if (player.maxHp <= 1) event._result = { control: "失去体力", index: 0 }; + else if (player.hp < 1) event._result = { control: "减体力上限", index: 1 }; + else + player + .chooseControl("失去体力", "减体力上限") + .set("prompt", "玉陨:失去1点体力或减1点体力上限") + .set("ai", function () { + var player = _status.event.player; + if (player.hp < 2 || player.getDamagedHp() > 2) return 1; + return 0; + }); + "step 1"; + if (result.index == 1) player.loseMaxHp(); else player.loseHp(); - 'step 2' - var list=[ - '选项一:摸两张牌', - '选项二:对一名其他角色造成1点伤害,且本回合对其使用【杀】无距离和次数限制', - '选项三:本回合手牌上限视为无限', - '选项四:获得一名其他角色区域内的一张牌', - '选项五:令一名其他角色将手牌数摸至体力上限(至多摸至五张)', + "step 2"; + var list = [ + "选项一:摸两张牌", + "选项二:对一名其他角色造成1点伤害,且本回合对其使用【杀】无距离和次数限制", + "选项三:本回合手牌上限视为无限", + "选项四:获得一名其他角色区域内的一张牌", + "选项五:令一名其他角色将手牌数摸至体力上限(至多摸至五张)", ]; - var next=player.chooseButton([ - '玉陨:请选择一'+(player.getDamagedHp()>0?('至'+get.cnNumber(player.getDamagedHp()+1)):'')+'项', - [list.map((item,i)=>{ - return [i,item]; - }),'textbutton'] + var next = player.chooseButton([ + "玉陨:请选择一" + + (player.getDamagedHp() > 0 + ? "至" + get.cnNumber(player.getDamagedHp() + 1) + : "") + + "项", + [ + list.map((item, i) => { + return [i, item]; + }), + "textbutton", + ], ]); - next.set('dialog',event.videoId); - next.set('forced',true); - next.set('ai',function(button){ - var player=_status.event.player; - switch(button.link){ + next.set("dialog", event.videoId); + next.set("forced", true); + next.set("ai", function (button) { + var player = _status.event.player; + switch (button.link) { case 0: return 2; case 1: - return Math.max(0.5,player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card); - })-player.getCardUsable({name:'sha'}))+Math.max.apply(Math,game.filterPlayer(function(current){ - return current!=player; - }).map(function(target){ - return get.damageEffect(target,player,player); - })); + return ( + Math.max( + 0.5, + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) - player.getCardUsable({ name: "sha" }) + ) + + Math.max.apply( + Math, + game + .filterPlayer(function (current) { + return current != player; + }) + .map(function (target) { + return get.damageEffect(target, player, player); + }) + ) + ); case 2: - return player.needsToDiscard()/4; + return player.needsToDiscard() / 4; case 3: - var num=0; - return 0.8*Math.max.apply(Math,game.filterPlayer(function(current){ - return current!=player&¤t.hasCard((card)=>lib.filter.canBeGained(card,current,player),'hej'); - }).map(function(target){ - return get.effect(target,{name:'shunshou_copy'},player,player); - })); + var num = 0; + return ( + 0.8 * + Math.max.apply( + Math, + game + .filterPlayer(function (current) { + return ( + current != player && + current.hasCard( + (card) => + lib.filter.canBeGained(card, current, player), + "hej" + ) + ); + }) + .map(function (target) { + return get.effect( + target, + { name: "shunshou_copy" }, + player, + player + ); + }) + ) + ); case 4: - var num=0; - game.countPlayer(function(current){ - if(current!=player&&get.attitude(player,current)>0){ - var num2=Math.min(5,current.maxHp)-current.countCards('h'); - if(num2>num) num=num2; + var num = 0; + game.countPlayer(function (current) { + if (current != player && get.attitude(player, current) > 0) { + var num2 = Math.min(5, current.maxHp) - current.countCards("h"); + if (num2 > num) num = num2; } }); - return num*0.8; + return num * 0.8; } }); - if(player.getDamagedHp()>0) next.set('selectButton',[1,1+player.getDamagedHp()]); - 'step 3' + if (player.getDamagedHp() > 0) next.set("selectButton", [1, 1 + player.getDamagedHp()]); + "step 3"; result.links.sort(); - for(var i of result.links) game.log(player,'选择了','#g【玉陨】','的','#y选项'+get.cnNumber(1+i,true)) - event.links=result.links; - if(result.links.includes(0)) player.draw(2); - if(result.links.includes(2)) player.addTempSkill('yuyun_114514'); - 'step 4' - if(event.links.includes(1)&&game.hasPlayer(function(current){ - return current!=player; - })) player.chooseTarget(lib.filter.notMe,true,'对一名其他角色造成1点伤害').set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - else if(event.links.includes(3)) event.goto(6); - else if(event.links.includes(4)) event.goto(8); + for (var i of result.links) + game.log(player, "选择了", "#g【玉陨】", "的", "#y选项" + get.cnNumber(1 + i, true)); + event.links = result.links; + if (result.links.includes(0)) player.draw(2); + if (result.links.includes(2)) player.addTempSkill("yuyun_114514"); + "step 4"; + if ( + event.links.includes(1) && + game.hasPlayer(function (current) { + return current != player; + }) + ) + player + .chooseTarget(lib.filter.notMe, true, "对一名其他角色造成1点伤害") + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + else if (event.links.includes(3)) event.goto(6); + else if (event.links.includes(4)) event.goto(8); else event.finish(); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.damage(); - player.markAuto('yuyun_sha',[target]); - player.addTempSkill('yuyun_sha'); + player.markAuto("yuyun_sha", [target]); + player.addTempSkill("yuyun_sha"); } - if(event.links.includes(3)) event.goto(6); - else if(event.links.includes(4)) event.goto(8); + if (event.links.includes(3)) event.goto(6); + else if (event.links.includes(4)) event.goto(8); else event.finish(); - 'step 6' - if(event.links.includes(3)&&game.hasPlayer(function(current){ - return current!=player&¤t.hasCard((card)=>lib.filter.canBeGained(card,current,player),'hej'); - })){ - player.chooseTarget(true,'获得一名其他角色区域内的一张牌',function(card,player,current){ - return current!=player&¤t.hasCard((card)=>lib.filter.canBeGained(card,current,player),'hej'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'shunshou_copy'},player,player); - }); - } - else if(event.links.includes(4)) event.goto(8); + "step 6"; + if ( + event.links.includes(3) && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasCard( + (card) => lib.filter.canBeGained(card, current, player), + "hej" + ) + ); + }) + ) { + player + .chooseTarget( + true, + "获得一名其他角色区域内的一张牌", + function (card, player, current) { + return ( + current != player && + current.hasCard( + (card) => lib.filter.canBeGained(card, current, player), + "hej" + ) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "shunshou_copy" }, player, player); + }); + } else if (event.links.includes(4)) event.goto(8); else event.finish(); - 'step 7' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.gainPlayerCard(target,'hej',true); + "step 7"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.gainPlayerCard(target, "hej", true); } - if(!event.links.includes(4)) event.finish(); - 'step 8' - if(event.links.includes(4)&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')2){ - return Math.min(5,target.maxHp)-target.countCards('h'); - } - return att/3; - }); - } - else event.finish(); - 'step 9' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.drawTo(Math.min(5,target.maxHp)); + if (!event.links.includes(4)) event.finish(); + "step 8"; + if ( + event.links.includes(4) && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") < Math.min(5, current.maxHp); + }) + ) { + player + .chooseTarget( + true, + "令一名其他角色将手牌数摸至体力上限", + function (card, player, current) { + return ( + current != player && + current.countCards("h") < Math.min(5, current.maxHp) + ); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 6; + if (att > 2) { + return Math.min(5, target.maxHp) - target.countCards("h"); + } + return att / 3; + }); + } else event.finish(); + "step 9"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.drawTo(Math.min(5, target.maxHp)); } }, - subSkill:{ - '114514':{ - mod:{ - maxHandcardFinal:function(player,num){ + subSkill: { + 114514: { + mod: { + maxHandcardFinal: function (player, num) { return 114514; }, }, - charlotte:true, + charlotte: true, }, - sha:{ - mod:{ - cardUsableTarget:function(card,player,target){ - if(card.name=='sha'&&player.getStorage('yuyun_sha').includes(target)) return Infinity; + sha: { + mod: { + cardUsableTarget: function (card, player, target) { + if (card.name == "sha" && player.getStorage("yuyun_sha").includes(target)) + return Infinity; }, - targetInRange:function(card,player,target){ - if(card.name=='sha'&&player.getStorage('yuyun_sha').includes(target)) return true; + targetInRange: function (card, player, target) { + if (card.name == "sha" && player.getStorage("yuyun_sha").includes(target)) + return true; }, }, - charlotte:true, - onremove:true, + charlotte: true, + onremove: true, }, }, }, //潘淑 - zhiren:{ - audio:2, - trigger:{player:'useCard'}, - filter:function(event,player){ - return (player==_status.currentPhase||player.hasSkill('yaner_zhiren'))&&event.card.isCard&&player.getHistory('useCard',function(evt){ - return evt.card.isCard; - }).indexOf(event)==0; + zhiren: { + audio: 2, + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + (player == _status.currentPhase || player.hasSkill("yaner_zhiren")) && + event.card.isCard && + player + .getHistory("useCard", function (evt) { + return evt.card.isCard; + }) + .indexOf(event) == 0 + ); }, - frequent:true, - locked:false, - content:function(){ - 'step 0' - event.num=get.translation(trigger.card.name).length; + frequent: true, + locked: false, + content: function () { + "step 0"; + event.num = get.translation(trigger.card.name).length; player.chooseToGuanxing(event.num); - if(event.num<2) event.finish(); - 'step 1' - if(!game.hasPlayer(function(current){ - return current.countDiscardableCards(player,'e')>0; - })){ + if (event.num < 2) event.finish(); + "step 1"; + if ( + !game.hasPlayer(function (current) { + return current.countDiscardableCards(player, "e") > 0; + }) + ) { event.goto(3); - } - else player.chooseTarget('织纴:是否弃置一名角色装备区内的一张牌?',function(card,player,target){ - return target.countDiscardableCards(player,'e')>0; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target),es=target.getCards('e'),val=0; - for(var i of es){ - var eff=-(get.value(i,target)-0.1)*att; - if(eff>val) val=eff; - } - return eff; - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; + } else + player + .chooseTarget( + "织纴:是否弃置一名角色装备区内的一张牌?", + function (card, player, target) { + return target.countDiscardableCards(player, "e") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target), + es = target.getCards("e"), + val = 0; + for (var i of es) { + var eff = -(get.value(i, target) - 0.1) * att; + if (eff > val) val = eff; + } + return eff; + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.addExpose(0.15); - player.line(target,'green'); - player.discardPlayerCard(target,'e',true); - } - else event.goto(5); - if(event.num<3) event.finish(); - 'step 3' - if(!game.hasPlayer(function(current){ - return current.countDiscardableCards(player,'j')>0; - })){ - if(event.num<3) event.finish(); + player.line(target, "green"); + player.discardPlayerCard(target, "e", true); + } else event.goto(5); + if (event.num < 3) event.finish(); + "step 3"; + if ( + !game.hasPlayer(function (current) { + return current.countDiscardableCards(player, "j") > 0; + }) + ) { + if (event.num < 3) event.finish(); else event.goto(5); - } - else player.chooseTarget('织纴:是否弃置一名角色判定区内的一张牌?',function(card,player,target){ - return target.countDiscardableCards(player,'j')>0; - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target),es=target.getCards('j'),val=0; - for(var i of es){ - var eff=-(get.effect(target,i,target,player)) - if(eff>val) val=eff; - } - return eff; - }); - 'step 4' - if(result.bool){ - var target=result.targets[0]; + } else + player + .chooseTarget( + "织纴:是否弃置一名角色判定区内的一张牌?", + function (card, player, target) { + return target.countDiscardableCards(player, "j") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target), + es = target.getCards("j"), + val = 0; + for (var i of es) { + var eff = -get.effect(target, i, target, player); + if (eff > val) val = eff; + } + return eff; + }); + "step 4"; + if (result.bool) { + var target = result.targets[0]; player.addExpose(0.15); - player.line(target,'green'); - player.discardPlayerCard(target,'j',true); + player.line(target, "green"); + player.discardPlayerCard(target, "j", true); } - if(event.num<3) event.finish(); - 'step 5' + if (event.num < 3) event.finish(); + "step 5"; player.recover(); - if(event.num<4) event.finish(); - 'step 6' + if (event.num < 4) event.finish(); + "step 6"; player.draw(3); }, - mod:{ - aiOrder:function(player,card,num){ - if(player==_status.currentPhase&&!player.getHistory('useCard',function(evt){ - return evt.card.isCard; - }).length) return num+Math.pow(get.translation(card.name).length,2); + mod: { + aiOrder: function (player, card, num) { + if ( + player == _status.currentPhase && + !player.getHistory("useCard", function (evt) { + return evt.card.isCard; + }).length + ) + return num + Math.pow(get.translation(card.name).length, 2); }, }, }, - yaner:{ - audio:2, - trigger:{ - global:['equipAfter','addJudgeAfter','loseAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + yaner: { + audio: 2, + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "loseAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var current=_status.currentPhase; - if(!current||current==player||!current.isIn()||!current.isPhaseUsing()) return false; - var evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length&¤t.countCards('h')==0; + filter: function (event, player) { + var current = _status.currentPhase; + if (!current || current == player || !current.isIn() || !current.isPhaseUsing()) + return false; + var evt = event.getl(current); + return evt && evt.hs && evt.hs.length && current.countCards("h") == 0; }, - usable:1, - logTarget:function(){ + usable: 1, + logTarget: function () { return _status.currentPhase; }, - prompt2:'与该角色各摸两张牌', - check:function(event,player){ - return get.attitude(player,_status.currentPhase)>0; + prompt2: "与该角色各摸两张牌", + check: function (event, player) { + return get.attitude(player, _status.currentPhase) > 0; }, - content:function(){ - 'step 0' - game.asyncDraw([_status.currentPhase,player],2); - 'step 1' - var e1=player.getHistory('gain',function(evt){ - return evt.getParent(2)==event; + content: function () { + "step 0"; + game.asyncDraw([_status.currentPhase, player], 2); + "step 1"; + var e1 = player.getHistory("gain", function (evt) { + return evt.getParent(2) == event; })[0]; - if(e1&&e1.cards&&e1.cards.length==2&&get.type(e1.cards[0])==get.type(e1.cards[1])){ - player.addTempSkill('yaner_zhiren',{player:'phaseBegin'}); - game.log(player,'修改了技能','#g【织纴】'); + if ( + e1 && + e1.cards && + e1.cards.length == 2 && + get.type(e1.cards[0]) == get.type(e1.cards[1]) + ) { + player.addTempSkill("yaner_zhiren", { player: "phaseBegin" }); + game.log(player, "修改了技能", "#g【织纴】"); } - var target=_status.currentPhase; - if(target.isIn()&&target.isDamaged()){ - var e2=target.getHistory('gain',function(evt){ - return evt.getParent(2)==event; + var target = _status.currentPhase; + if (target.isIn() && target.isDamaged()) { + var e2 = target.getHistory("gain", function (evt) { + return evt.getParent(2) == event; })[0]; - if(e2&&e2.cards&&e2.cards.length==2&&get.type(e2.cards[0])==get.type(e2.cards[1])) target.recover(); + if ( + e2 && + e2.cards && + e2.cards.length == 2 && + get.type(e2.cards[0]) == get.type(e2.cards[1]) + ) + target.recover(); } - 'step 2' + "step 2"; game.delayx(); }, - subSkill:{ - zhiren:{charlotte:true}, + subSkill: { + zhiren: { charlotte: true }, }, - ai:{ - expose:0.5, + ai: { + expose: 0.5, }, }, //杨婉 - youyan:{ - audio:2, + youyan: { + audio: 2, // trigger:{ // player:'loseAfter', // global:'loseAsyncAfter', // }, - trigger:{ - player:['loseAfter','equipAfter'], - global:['loseAsyncAfter','cardsDiscardAfter'], + trigger: { + player: ["loseAfter", "equipAfter"], + global: ["loseAsyncAfter", "cardsDiscardAfter"], }, //usable:1, - prompt2:function(event,player){ - var cards2=[]; - if(event.name=='cardsDiscard'){ - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evtx2=(evtx.relatedEvent||evtx.getParent()); - if(evtx2.name=='useCard'||evtx2.name=='respond') return false; - player.getHistory('lose',evtx3=>{ - var evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evtx2!=evtx4) return false; - if(!evtx3.cards2||!evtx3.cards2.length) return false; - cards2.addArray(evtx3.cards2.filterInD('d')); + prompt2: function (event, player) { + var cards2 = []; + if (event.name == "cardsDiscard") { + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evtx2 = evtx.relatedEvent || evtx.getParent(); + if (evtx2.name == "useCard" || evtx2.name == "respond") return false; + player.getHistory("lose", (evtx3) => { + var evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evtx2 != evtx4) return false; + if (!evtx3.cards2 || !evtx3.cards2.length) return false; + cards2.addArray(evtx3.cards2.filterInD("d")); }); - } - else if(event.name=='loseAsync'){ - player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event||evt.position!=ui.discardPile) return false; - cards2.addArray(evt.cards2.filterInD('d')); + } else if (event.name == "loseAsync") { + player.hasHistory("lose", (evt) => { + if (evt.getParent() != event || evt.position != ui.discardPile) return false; + cards2.addArray(evt.cards2.filterInD("d")); }); + } else { + cards2.addArray(event.getd(player).filterInD("d")); } - else{ - cards2.addArray(event.getd(player).filterInD('d')); - } - return '获得与'+get.translation(cards2)+'花色'+(cards2.length>1?'各':'')+'不相同的牌各一张'; + return ( + "获得与" + + get.translation(cards2) + + "花色" + + (cards2.length > 1 ? "各" : "") + + "不相同的牌各一张" + ); }, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - var cards2=[]; - if(event.name=='cardsDiscard'){ - var evtx=event.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evtx2=(evtx.relatedEvent||evtx.getParent()); - if(evtx2.name=='useCard'||evtx2.name=='respond') return false; - player.getHistory('lose',evtx3=>{ - var evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evtx2!=evtx4) return false; - if(!evtx3.cards2||!evtx3.cards2.length) return false; - cards2.addArray(evtx3.cards2.filterInD('d')); + filter: function (event, player) { + if (player != _status.currentPhase) return false; + var cards2 = []; + if (event.name == "cardsDiscard") { + var evtx = event.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evtx2 = evtx.relatedEvent || evtx.getParent(); + if (evtx2.name == "useCard" || evtx2.name == "respond") return false; + player.getHistory("lose", (evtx3) => { + var evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evtx2 != evtx4) return false; + if (!evtx3.cards2 || !evtx3.cards2.length) return false; + cards2.addArray(evtx3.cards2.filterInD("d")); }); - } - else if(event.name=='loseAsync'){ - player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event||evt.position!=ui.discardPile) return false; - cards2.addArray(evt.cards2.filterInD('d')); + } else if (event.name == "loseAsync") { + player.hasHistory("lose", (evt) => { + if (evt.getParent() != event || evt.position != ui.discardPile) return false; + cards2.addArray(evt.cards2.filterInD("d")); }); + } else { + cards2.addArray(event.getd(player).filterInD("d")); } - else{ - cards2.addArray(event.getd(player).filterInD('d')); + if (!cards2.length) return false; + var list = []; + for (var i of cards2) { + list.add(get.suit(i, player)); + if (list.length >= lib.suit.length) return false; } - if(!cards2.length) return false; - var list=[]; - for(var i of cards2){ - list.add(get.suit(i,player)); - if(list.length>=lib.suit.length) return false; - } - var evt=event.getParent('phaseUse'); - if(evt&&evt.player==player&&!evt.youyaned) return true; - var evt=event.getParent('phaseDiscard'); - if(evt&&evt.player==player&&!evt.youyaned) return true; + var evt = event.getParent("phaseUse"); + if (evt && evt.player == player && !evt.youyaned) return true; + var evt = event.getParent("phaseDiscard"); + if (evt && evt.player == player && !evt.youyaned) return true; return false; }, - content:function(){ - var evt=trigger.getParent('phaseUse'); - if(evt&&evt.player==player) evt.youyaned=true; - else{ - var evt=trigger.getParent('phaseDiscard'); - if(evt) evt.youyaned=true; + content: function () { + var evt = trigger.getParent("phaseUse"); + if (evt && evt.player == player) evt.youyaned = true; + else { + var evt = trigger.getParent("phaseDiscard"); + if (evt) evt.youyaned = true; } - var list=[],cards=[]; - var cards2=[]; - if(trigger.name=='cardsDiscard'){ - var evtx=trigger.getParent(); - if(evtx.name!='orderingDiscard') return false; - var evtx2=(evtx.relatedEvent||evtx.getParent()); - if(evtx2.name=='useCard'||evtx2.name=='respond') return false; - player.getHistory('lose',evtx3=>{ - var evtx4=evtx3.relatedEvent||evtx3.getParent(); - if(evtx2!=evtx4) return false; - if(!evtx3.cards2||!evtx3.cards2.length) return false; - cards2.addArray(evtx3.cards2.filterInD('d')); + var list = [], + cards = []; + var cards2 = []; + if (trigger.name == "cardsDiscard") { + var evtx = trigger.getParent(); + if (evtx.name != "orderingDiscard") return false; + var evtx2 = evtx.relatedEvent || evtx.getParent(); + if (evtx2.name == "useCard" || evtx2.name == "respond") return false; + player.getHistory("lose", (evtx3) => { + var evtx4 = evtx3.relatedEvent || evtx3.getParent(); + if (evtx2 != evtx4) return false; + if (!evtx3.cards2 || !evtx3.cards2.length) return false; + cards2.addArray(evtx3.cards2.filterInD("d")); }); - } - else if(trigger.name=='loseAsync'){ - player.hasHistory('lose',evt=>{ - if(evt.getParent()!=trigger||evt.position!=ui.discardPile) return false; - cards2.addArray(evt.cards2.filterInD('d')); + } else if (trigger.name == "loseAsync") { + player.hasHistory("lose", (evt) => { + if (evt.getParent() != trigger || evt.position != ui.discardPile) return false; + cards2.addArray(evt.cards2.filterInD("d")); }); + } else { + cards2.addArray(trigger.getd(player).filterInD("d")); } - else{ - cards2.addArray(trigger.getd(player).filterInD('d')); + for (var i of cards2) { + list.add(get.suit(i, player)); } - for(var i of cards2){ - list.add(get.suit(i,player)); + for (var i of lib.suit) { + if (list.includes(i)) continue; + var card = get.cardPile2(function (card) { + return get.suit(card, false) == i; + }); + if (card) cards.push(card); } - for(var i of lib.suit){ - if(list.includes(i)) continue; - var card=get.cardPile2(function(card){ - return get.suit(card,false)==i; - }) - if(card) cards.push(card); - } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card=='object'&&player==_status.currentPhase&& - //(!player.storage.counttrigger||!player.storage.counttrigger.youyan)&& - player.needsToDiscard()==1&&card.cards&&card.cards.filter(function(i){ - return get.position(i)=='h'; - }).length>0&&!get.tag(card,'draw')&&!get.tag(card,'gain')&&!get.tag(card,'discard')) return 'zeroplayertarget'; + ai: { + effect: { + player_use: function (card, player, target) { + if ( + typeof card == "object" && + player == _status.currentPhase && + //(!player.storage.counttrigger||!player.storage.counttrigger.youyan)&& + player.needsToDiscard() == 1 && + card.cards && + card.cards.filter(function (i) { + return get.position(i) == "h"; + }).length > 0 && + !get.tag(card, "draw") && + !get.tag(card, "gain") && + !get.tag(card, "discard") + ) + return "zeroplayertarget"; }, }, }, }, - zhuihuan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return !current.hasSkill('zhuihuan2_new'); + zhuihuan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return !current.hasSkill("zhuihuan2_new"); }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhuihuan'),'令一名角色获得“追还”效果',function(card,player,target){ - return !target.hasSkill('zhuihuan2_new'); - }).set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(target.hasSkill('maixie')||target.hasSkill('maixie_defend')) att/=3; - if(target!=player) att/=Math.pow(game.players.length-get.distance(player,target,'absolute'),0.7); - return att; - }).set('animate',false); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('zhuihuan'); - target.addTempSkill('zhuihuan2_new',{player:'phaseZhunbei'}); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhuihuan"), + "令一名角色获得“追还”效果", + function (card, player, target) { + return !target.hasSkill("zhuihuan2_new"); + } + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (target.hasSkill("maixie") || target.hasSkill("maixie_defend")) att /= 3; + if (target != player) + att /= Math.pow( + game.players.length - get.distance(player, target, "absolute"), + 0.7 + ); + return att; + }) + .set("animate", false); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("zhuihuan"); + target.addTempSkill("zhuihuan2_new", { player: "phaseZhunbei" }); game.delayx(); } }, }, - zhuihuan2_new:{ - trigger:{player:'phaseZhunbeiBegin'}, - charlotte:true, - forced:true, - onremove:true, - filter:function(event,player){ - if(player.storage.zhuihuan2_new){ - for(var source of player.storage.zhuihuan2_new){ - if(!source.isIn()) continue; - if(source.hp>player.hp) return true; - return source.countCards('h')>0; + zhuihuan2_new: { + trigger: { player: "phaseZhunbeiBegin" }, + charlotte: true, + forced: true, + onremove: true, + filter: function (event, player) { + if (player.storage.zhuihuan2_new) { + for (var source of player.storage.zhuihuan2_new) { + if (!source.isIn()) continue; + if (source.hp > player.hp) return true; + return source.countCards("h") > 0; } } }, - logTarget:function(event,player){ - return player.storage.zhuihuan2_new.filter(function(target){ + logTarget: function (event, player) { + return player.storage.zhuihuan2_new.filter(function (target) { return target.isIn(); }); }, - content:function(){ - 'step 0' - event.targets=player.storage.zhuihuan2_new; - player.removeSkill('zhuihuan2_new'); - 'step 1' - var target=targets.shift(); - if(target.isIn()){ - if(target.hp>player.hp) target.damage(2); - else{ - var hs=target.getCards('h'); - if(hs.length) target.discard(hs.randomGets(2)); + content: function () { + "step 0"; + event.targets = player.storage.zhuihuan2_new; + player.removeSkill("zhuihuan2_new"); + "step 1"; + var target = targets.shift(); + if (target.isIn()) { + if (target.hp > player.hp) target.damage(2); + else { + var hs = target.getCards("h"); + if (hs.length) target.discard(hs.randomGets(2)); } } - if(targets.length) event.redo(); + if (targets.length) event.redo(); }, - group:'zhuihuan2_new_count', - subSkill:{ - count:{ - trigger:{player:'damage'}, - forced:true, - silent:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return get.itemtype(event.source)=='player'; + group: "zhuihuan2_new_count", + subSkill: { + count: { + trigger: { player: "damage" }, + forced: true, + silent: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return get.itemtype(event.source) == "player"; }, - content:function(){ - player.markAuto('zhuihuan2_new',[trigger.source]); + content: function () { + player.markAuto("zhuihuan2_new", [trigger.source]); }, }, }, }, - zhuihuan2:{ - trigger:{player:'damageEnd'}, - forced:true, - charlotte:true, - logTarget:'source', - filter:function(event,player){ - var source=event.source; - if(source.hp>player.hp) return true; - return source.countCards('h')>0; + zhuihuan2: { + trigger: { player: "damageEnd" }, + forced: true, + charlotte: true, + logTarget: "source", + filter: function (event, player) { + var source = event.source; + if (source.hp > player.hp) return true; + return source.countCards("h") > 0; }, - content:function(){ - if(player.hp1){ - allcards=allcards.concat(list[1][1]); + next.set("list", list); + next.set("processAI", function (list) { + var allcards = list[0][1].slice(0), + cards = []; + if (list.length > 1) { + allcards = allcards.concat(list[1][1]); } - var canchoose=allcards.slice(0); - var player=_status.event.player; - var getv=function(button){ - if(button.name=='sha'&&allcards.filter(function(card){ - return card.name=='sha'&&!cards.filter(function(){ - return button==card; - }).length; - }).length>player.getCardUsable({name:'sha'})) return 10; - return -player.getUseValue(button,player); + var canchoose = allcards.slice(0); + var player = _status.event.player; + var getv = function (button) { + if ( + button.name == "sha" && + allcards.filter(function (card) { + return ( + card.name == "sha" && + !cards.filter(function () { + return button == card; + }).length + ); + }).length > player.getCardUsable({ name: "sha" }) + ) + return 10; + return -player.getUseValue(button, player); }; - while(cards.length<3){ - canchoose.sort(function(a,b){ - return getv(b)-getv(a); + while (cards.length < 3) { + canchoose.sort(function (a, b) { + return getv(b) - getv(a); }); cards.push(canchoose.shift()); } - return [cards,canchoose]; - }) - 'step 1' - if(result.bool){ - event.forceDie=true; - var cards=result.moved[0]; - event.cards=cards; - player.storage.xingzuo2=cards; - var hs=player.getCards('h'); - var lose=[],gain=event.cards2; - for(var i of cards){ - if(hs.includes(i)) lose.push(i); + return [cards, canchoose]; + }); + "step 1"; + if (result.bool) { + event.forceDie = true; + var cards = result.moved[0]; + event.cards = cards; + player.storage.xingzuo2 = cards; + var hs = player.getCards("h"); + var lose = [], + gain = event.cards2; + for (var i of cards) { + if (hs.includes(i)) lose.push(i); else gain.remove(i); } - if(lose.length) player.lose(lose,ui.cardPile); - if(gain.length) player.gain(gain,'draw'); - } - else event.finish(); - 'step 2' - for(var i of cards){ - if(!(('hejsdx').includes(get.position(i,true)))){ + if (lose.length) player.lose(lose, ui.cardPile); + if (gain.length) player.gain(gain, "draw"); + } else event.finish(); + "step 2"; + for (var i of cards) { + if (!"hejsdx".includes(get.position(i, true))) { i.fix(); ui.cardPile.appendChild(i); } @@ -11926,251 +15604,317 @@ game.import('character',function(lib,game,ui,get,ai,_status){ game.updateRoundNumber(); }, }, - xingzuo2:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return game.hasPlayer(function(target){ - return target.countCards('h')>0; + xingzuo2: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return game.hasPlayer(function (target) { + return target.countCards("h") > 0; }); }, - content:function(){ - 'step 0' - player.chooseTarget(function(card,player,target){ - return target.countCards('h')>0; - },'兴作:是否令一名角色将其手牌与牌堆底的三张牌替换?').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target),hs=target.getCards('h'),num=hs.length; - var getv=function(list,target){ - var num=0; - for(var i of list) num+=get.value(i,target); - return num; - },val=getv(hs,target)-getv(player.storage.xingzuo2,target); - if(num<3) return att*Math.sqrt(Math.max(0,-val))*1.5; - if(num==3) return -att*Math.sqrt(Math.max(0,val)); - if(player.hp<(num>4?3:2)) return 0; - return -att*Math.sqrt(Math.max(0,val)); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('xingzuo',target); - var cards=get.bottomCards(3); + content: function () { + "step 0"; + player + .chooseTarget(function (card, player, target) { + return target.countCards("h") > 0; + }, "兴作:是否令一名角色将其手牌与牌堆底的三张牌替换?") + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target), + hs = target.getCards("h"), + num = hs.length; + var getv = function (list, target) { + var num = 0; + for (var i of list) num += get.value(i, target); + return num; + }, + val = getv(hs, target) - getv(player.storage.xingzuo2, target); + if (num < 3) return att * Math.sqrt(Math.max(0, -val)) * 1.5; + if (num == 3) return -att * Math.sqrt(Math.max(0, val)); + if (player.hp < (num > 4 ? 3 : 2)) return 0; + return -att * Math.sqrt(Math.max(0, val)); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("xingzuo", target); + var cards = get.bottomCards(3); game.cardsGotoOrdering(cards); - var hs=target.getCards('h'); - target.lose(hs,ui.cardPile); - target.gain(cards,'draw'); - if(hs.length>3) player.loseHp(); - } - else event.finish(); - 'step 2' + var hs = target.getCards("h"); + target.lose(hs, ui.cardPile); + target.gain(cards, "draw"); + if (hs.length > 3) player.loseHp(); + } else event.finish(); + "step 2"; game.updateRoundNumber(); }, }, - miaoxian:{ - hiddenCard:function(player,name){ - return get.type(name)=='trick'&&!player.hasSkill('miaoxian2')&&player.countCards('h',{color:'black'})==1; + miaoxian: { + hiddenCard: function (player, name) { + return ( + get.type(name) == "trick" && + !player.hasSkill("miaoxian2") && + player.countCards("h", { color: "black" }) == 1 + ); }, - enable:'chooseToUse', - filter:function(event,player){ - if(player.hasSkill('miaoxian2')) return false; - var cards=player.getCards('h',{color:'black'}); - if(cards.length!=1) return false; - var mod2=game.checkMod(cards[0],player,'unchanged','cardEnabled2',player); - if(mod2===false) return false; - for(var i of lib.inpile){ - if(get.type(i)=='trick'&&event.filterCard({ - name:i, - cards:cards, - },player,event)) return true; + enable: "chooseToUse", + filter: function (event, player) { + if (player.hasSkill("miaoxian2")) return false; + var cards = player.getCards("h", { color: "black" }); + if (cards.length != 1) return false; + var mod2 = game.checkMod(cards[0], player, "unchanged", "cardEnabled2", player); + if (mod2 === false) return false; + for (var i of lib.inpile) { + if ( + get.type(i) == "trick" && + event.filterCard( + { + name: i, + cards: cards, + }, + player, + event + ) + ) + return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var cards=player.getCards('h',{color:'black'}); - var list=[]; - for(var i of lib.inpile){ - if(get.type(i)=='trick'&&event.filterCard({ - name:i, - cards:cards, - },player,event)){ - list.push(['锦囊','',i]); + chooseButton: { + dialog: function (event, player) { + var cards = player.getCards("h", { color: "black" }); + var list = []; + for (var i of lib.inpile) { + if ( + get.type(i) == "trick" && + event.filterCard( + { + name: i, + cards: cards, + }, + player, + event + ) + ) { + list.push(["锦囊", "", i]); } } - return ui.create.dialog('妙弦',[list,'vcard'],'hidden'); + return ui.create.dialog("妙弦", [list, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - return player.getUseValue({name:button.link[2]})+1; + check: function (button) { + var player = _status.event.player; + return player.getUseValue({ name: button.link[2] }) + 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'miaoxian', - popname:true, - filterCard:{color:'black'}, - selectCard:-1, - position:'h', - viewAs:{ - name:links[0][2], + audio: "miaoxian", + popname: true, + filterCard: { color: "black" }, + selectCard: -1, + position: "h", + viewAs: { + name: links[0][2], }, - onuse:function(links,player){ - player.addTempSkill('miaoxian2'); + onuse: function (links, player) { + player.addTempSkill("miaoxian2"); }, - } + }; }, - prompt:function(links,player){ - return '将'+get.translation(player.getCards('h',{color:'black'})[0])+'当做'+get.translation(links[0][2])+'使用'; + prompt: function (links, player) { + return ( + "将" + + get.translation(player.getCards("h", { color: "black" })[0]) + + "当做" + + get.translation(links[0][2]) + + "使用" + ); }, }, - group:'miaoxian_use', - subfrequent:['use'], - subSkill:{ - use:{ - audio:'miaoxian', - trigger:{player:'loseAfter'}, - frequent:true, - prompt:'是否发动【妙弦】摸一张牌?', - filter:function(event,player){ - var evt=event.getParent(); - if(evt.name!='useCard') return false; - return event.hs&&event.hs.length==1&&event.cards&&event.cards.length==1 - &&get.color(event.hs[0],player)=='red'&&!player.countCards('h',{color:'red'}); + group: "miaoxian_use", + subfrequent: ["use"], + subSkill: { + use: { + audio: "miaoxian", + trigger: { player: "loseAfter" }, + frequent: true, + prompt: "是否发动【妙弦】摸一张牌?", + filter: function (event, player) { + var evt = event.getParent(); + if (evt.name != "useCard") return false; + return ( + event.hs && + event.hs.length == 1 && + event.cards && + event.cards.length == 1 && + get.color(event.hs[0], player) == "red" && + !player.countCards("h", { color: "red" }) + ); }, - content:function(){ + content: function () { player.draw(); }, }, - backup:{ - audio:'miaoxian', + backup: { + audio: "miaoxian", }, }, - ai:{ - order:12, - result:{ - player:1, + ai: { + order: 12, + result: { + player: 1, }, }, }, - miaoxian2:{ - charlotte:true, + miaoxian2: { + charlotte: true, }, //樊玉凤 - bazhan:{ - audio:2, - enable:'phaseUse', - usable:1, - zhuanhuanji:true, - marktext:'☯', - mark:true, - intro:{ - content:function(storage,player){ - return '出牌阶段限一次,'+(storage?'你可以获得一名其他角色的至多两张手牌。':'你可以将至多两张手牌交给一名其他角色。')+'若以此法移动的牌包含【酒】或♥牌,则你可令得到牌的角色执行一项:①回复1点体力。②复原武将牌。' + bazhan: { + audio: 2, + enable: "phaseUse", + usable: 1, + zhuanhuanji: true, + marktext: "☯", + mark: true, + intro: { + content: function (storage, player) { + return ( + "出牌阶段限一次," + + (storage + ? "你可以获得一名其他角色的至多两张手牌。" + : "你可以将至多两张手牌交给一名其他角色。") + + "若以此法移动的牌包含【酒】或♥牌,则你可令得到牌的角色执行一项:①回复1点体力。②复原武将牌。" + ); }, }, - filter:function(event,player){ - if(player.storage.bazhan){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countGainableCards(player,'h')>0; - }) + filter: function (event, player) { + if (player.storage.bazhan) { + return game.hasPlayer(function (current) { + return current != player && current.countGainableCards(player, "h") > 0; + }); } - return player.countCards('h')>0; + return player.countCards("h") > 0; }, - filterCard:true, - discard:false, - lose:false, - selectCard:function(){ - if(_status.event.player.storage.bazhan) return 0; - return [1,2]; + filterCard: true, + discard: false, + lose: false, + selectCard: function () { + if (_status.event.player.storage.bazhan) return 0; + return [1, 2]; }, - filterTarget:function(card,player,target){ - if(player==target) return false; - if(player.storage.bazhan) return target.countGainableCards(player,'h')>0; + filterTarget: function (card, player, target) { + if (player == target) return false; + if (player.storage.bazhan) return target.countGainableCards(player, "h") > 0; return true; }, - prompt:function(){ - if(_status.event.player.storage.bazhan) return '获得一名其他角色的至多两张手牌'; - return '将至多两张手牌交给一名其他角色'; + prompt: function () { + if (_status.event.player.storage.bazhan) return "获得一名其他角色的至多两张手牌"; + return "将至多两张手牌交给一名其他角色"; }, - delay:false, - check:function(card){ - var player=_status.event.player; - var bool1=false,bool2=false; - for(var i of game.players){ - if(get.attitude(player,i)<=0||player==i) continue; - bool1=true; - if(i.isDamaged()||i.isTurnedOver()){ - bool2=true; + delay: false, + check: function (card) { + var player = _status.event.player; + var bool1 = false, + bool2 = false; + for (var i of game.players) { + if (get.attitude(player, i) <= 0 || player == i) continue; + bool1 = true; + if (i.isDamaged() || i.isTurnedOver()) { + bool2 = true; break; } } - if(bool2&&!ui.selected.cards.length&&(get.suit(card,player)=='heart'||get.name(card,player)=='jiu')) return 10; - if(bool1) return 9-get.value(card); - if(get.color(card)=='red') return 5-get.value(card); + if ( + bool2 && + !ui.selected.cards.length && + (get.suit(card, player) == "heart" || get.name(card, player) == "jiu") + ) + return 10; + if (bool1) return 9 - get.value(card); + if (get.color(card) == "red") return 5 - get.value(card); return 0; }, - content:function(){ - 'step 0' - if(player.storage.bazhan){ - event.recover=player; - player.gainPlayerCard(target,'h',true,'visibleMove',[1,2]); + content: function () { + "step 0"; + if (player.storage.bazhan) { + event.recover = player; + player.gainPlayerCard(target, "h", true, "visibleMove", [1, 2]); + } else { + event.recover = target; + player.give(cards, target); } - else{ - event.recover=target; - player.give(cards,target); + player.changeZhuanhuanji("bazhan"); + "step 1"; + var target = event.recover; + if (result.bool && result.cards && result.cards.length) { + cards = result.cards; } - player.changeZhuanhuanji('bazhan'); - 'step 1' - var target=event.recover; - if(result.bool&&result.cards&&result.cards.length){ - cards=result.cards; - } - if(!cards||!target||!target.getCards('h').filter(function(i){ - return cards.includes(i); - }).length||function(){ - for(var card of cards){ - if(get.suit(card,target)=='heart'||get.name(card,target)=='jiu') return false; - } - return true; - }()){ + if ( + !cards || + !target || + !target.getCards("h").filter(function (i) { + return cards.includes(i); + }).length || + (function () { + for (var card of cards) { + if (get.suit(card, target) == "heart" || get.name(card, target) == "jiu") + return false; + } + return true; + })() + ) { event.finish(); return; } - var list=[]; - event.addIndex=0; - var str=get.translation(target); - if(target.isDamaged()) list.push('令'+str+'回复1点体力'); + var list = []; + event.addIndex = 0; + var str = get.translation(target); + if (target.isDamaged()) list.push("令" + str + "回复1点体力"); else event.addIndex++; - if(target.isLinked()||target.isTurnedOver()) list.push('令'+get.translation(target)+'复原武将牌'); - if(!list.length) event.finish(); - else player.chooseControl('cancel2').set('choiceList',list).set('ai',function(){ - var evt=_status.event.getParent(); - if(get.attitude(evt.player,evt.target)<0) return 'cancel2'; - if(target.hp>1&&target.isTurnedOver()) return 1-evt.addIndex; - return 0; - }); - 'step 2' - if(result.control=='cancel2') event.finish(); - else if(result.index+event.addIndex==0){ + if (target.isLinked() || target.isTurnedOver()) + list.push("令" + get.translation(target) + "复原武将牌"); + if (!list.length) event.finish(); + else + player + .chooseControl("cancel2") + .set("choiceList", list) + .set("ai", function () { + var evt = _status.event.getParent(); + if (get.attitude(evt.player, evt.target) < 0) return "cancel2"; + if (target.hp > 1 && target.isTurnedOver()) return 1 - evt.addIndex; + return 0; + }); + "step 2"; + if (result.control == "cancel2") event.finish(); + else if (result.index + event.addIndex == 0) { event.recover.recover(); event.finish(); - } - else if(event.recover.isLinked()) event.recover.link(); - 'step 3' - if(event.recover.isTurnedOver()) event.recover.turnOver(); + } else if (event.recover.isLinked()) event.recover.link(); + "step 3"; + if (event.recover.isTurnedOver()) event.recover.turnOver(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(player.storage.bazhan) return -1; - if(ui.selected.cards.length){ - var cards=ui.selected.cards,card=cards[0]; - if(get.value(cards,target)<0) return -0.5; - if(get.attitude(player,target)>0){ - if((target.isDamaged()||target.isTurnedOver())&&(get.suit(card,target)=='heart'||get.name(card,target)=='jiu')) return 3; - if(target.hasUseTarget(card)&&target.getUseValue(card)>player.getUseValue(card,null,true)) return 1.4; + ai: { + order: 7, + result: { + target: function (player, target) { + if (player.storage.bazhan) return -1; + if (ui.selected.cards.length) { + var cards = ui.selected.cards, + card = cards[0]; + if (get.value(cards, target) < 0) return -0.5; + if (get.attitude(player, target) > 0) { + if ( + (target.isDamaged() || target.isTurnedOver()) && + (get.suit(card, target) == "heart" || get.name(card, target) == "jiu") + ) + return 3; + if ( + target.hasUseTarget(card) && + target.getUseValue(card) > player.getUseValue(card, null, true) + ) + return 1.4; return 1; } } @@ -12179,1434 +15923,1737 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - jiaoying:{ - audio:2, - trigger:{source:'gainEnd'}, - forced:true, - filter:function(event,player){ - if(player==event.player) return false; - var evt=event.getl(player); - return evt&&evt.hs&&evt.hs.length; + jiaoying: { + audio: 2, + trigger: { source: "gainEnd" }, + forced: true, + filter: function (event, player) { + if (player == event.player) return false; + var evt = event.getl(player); + return evt && evt.hs && evt.hs.length; }, - logTarget:'player', - content:function(){ - var target=trigger.player; - if(!target.storage.jiaoying2) target.storage.jiaoying2=[]; - var cs=trigger.getl(player).hs; - for(var i of cs) target.storage.jiaoying2.add(get.color(i,player)); - target.addTempSkill('jiaoying2'); - target.markSkill('jiaoying2'); - player.addTempSkill('jiaoying3'); - if(!player.storage.jiaoying3) player.storage.jiaoying3=[]; + logTarget: "player", + content: function () { + var target = trigger.player; + if (!target.storage.jiaoying2) target.storage.jiaoying2 = []; + var cs = trigger.getl(player).hs; + for (var i of cs) target.storage.jiaoying2.add(get.color(i, player)); + target.addTempSkill("jiaoying2"); + target.markSkill("jiaoying2"); + player.addTempSkill("jiaoying3"); + if (!player.storage.jiaoying3) player.storage.jiaoying3 = []; player.storage.jiaoying3.add(target); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - var target=arg.target; - if(target.getStorage('jiaoying2').includes('red')&&get.tag(arg.card,'respondShan')&&!target.hasSkillTag('respondShan',true,null,true)) return true; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + var target = arg.target; + if ( + target.getStorage("jiaoying2").includes("red") && + get.tag(arg.card, "respondShan") && + !target.hasSkillTag("respondShan", true, null, true) + ) + return true; return false; }, - } + }, }, - jiaoying2:{ - onremove:true, - charlotte:true, - mod:{ - cardEnabled2:function(card,player){ - if(player.getStorage('jiaoying2').includes(get.color(card))) return false; + jiaoying2: { + onremove: true, + charlotte: true, + mod: { + cardEnabled2: function (card, player) { + if (player.getStorage("jiaoying2").includes(get.color(card))) return false; }, }, - intro:{ - content:'本回合内不能使用或打出$牌', + intro: { + content: "本回合内不能使用或打出$牌", }, }, - jiaoying3:{ - onremove:true, - trigger:{global:'useCard1'}, - silent:true, - firstDo:true, - charlotte:true, - filter:function(event,player){ + jiaoying3: { + onremove: true, + trigger: { global: "useCard1" }, + silent: true, + firstDo: true, + charlotte: true, + filter: function (event, player) { return player.storage.jiaoying3.includes(event.player); }, - content:function(){ - while(player.storage.jiaoying3.includes(trigger.player)) player.storage.jiaoying3.remove(trigger.player); - if(!player.storage.jiaoying3.length) player.removeSkill('jiaoying3'); + content: function () { + while (player.storage.jiaoying3.includes(trigger.player)) + player.storage.jiaoying3.remove(trigger.player); + if (!player.storage.jiaoying3.length) player.removeSkill("jiaoying3"); }, - group:'jiaoying3_draw', + group: "jiaoying3_draw", }, - jiaoying3_draw:{ - trigger:{global:'phaseEnd'}, - direct:true, - charlotte:true, - filter:function(event,player){ - return player.getStorage('jiaoying3').length>0&&game.hasPlayer(function(current){ - return current.countCards('h')<5; - }) + jiaoying3_draw: { + trigger: { global: "phaseEnd" }, + direct: true, + charlotte: true, + filter: function (event, player) { + return ( + player.getStorage("jiaoying3").length > 0 && + game.hasPlayer(function (current) { + return current.countCards("h") < 5; + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.storage.jiaoying3.shift(); - player.chooseTarget('醮影:令一名角色将手牌摸至五张',function(card,player,target){ - return target.countCards('h')<5; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>2){ - return 5-target.countCards('h'); - } - return att/3; - }); - 'step 1' - if(result.bool){ - player.logSkill('jiaoying',result.targets); - for(var i=0;i 2) { + return 5 - target.countCards("h"); + } + return att / 3; + }); + "step 1"; + if (result.bool) { + player.logSkill("jiaoying", result.targets); + for (var i = 0; i < result.targets.length; i++) { result.targets[i].drawTo(5); } - if(lib.skill.jiaoying3_draw.filter(null,player)) event.goto(0); + if (lib.skill.jiaoying3_draw.filter(null, player)) event.goto(0); } }, }, //郭照 - pianchong:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ + pianchong: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - var cards=[]; - var card1=get.cardPile2(function(card){ - return get.color(card,false)=='red'; + var cards = []; + var card1 = get.cardPile2(function (card) { + return get.color(card, false) == "red"; }); - if(card1) cards.push(card1); - var card2=get.cardPile2(function(card){ - return get.color(card,false)=='black'; + if (card1) cards.push(card1); + var card2 = get.cardPile2(function (card) { + return get.color(card, false) == "black"; }); - if(card2) cards.push(card2); - if(cards.length) player.gain(cards,'gain2'); - 'step 1' - player.chooseControl('red','black').set('prompt','偏宠:请选择一种颜色。直至你的下回合开始时,失去该颜色的一张牌后,从牌堆获得另一种颜色的一张牌。').set('ai',function(){ - var red=0,black=0; - var player=_status.event.player; - var cards=player.getCards('he'); - for(var i of cards){ - var add=1; - var color=get.color(i,player); - if(get.position(i)=='e') add=0.5; - else if(get.name(i,player)!='sha'&&player.hasValueTarget(i)) add=1.5; - if(color=='red') red+=add; - else black+=add; - } - if(black>red) return 'black'; - return 'red'; - }); - 'step 2' - player.storage.pianchong2=result.control; - player.addTempSkill('pianchong2',{player:'phaseBeginStart'}); - player.popup(result.control,result.control=='red'?'fire':'thunder'); - game.log(player,'声明了','#y'+get.translation(result.control)); + if (card2) cards.push(card2); + if (cards.length) player.gain(cards, "gain2"); + "step 1"; + player + .chooseControl("red", "black") + .set( + "prompt", + "偏宠:请选择一种颜色。直至你的下回合开始时,失去该颜色的一张牌后,从牌堆获得另一种颜色的一张牌。" + ) + .set("ai", function () { + var red = 0, + black = 0; + var player = _status.event.player; + var cards = player.getCards("he"); + for (var i of cards) { + var add = 1; + var color = get.color(i, player); + if (get.position(i) == "e") add = 0.5; + else if (get.name(i, player) != "sha" && player.hasValueTarget(i)) add = 1.5; + if (color == "red") red += add; + else black += add; + } + if (black > red) return "black"; + return "red"; + }); + "step 2"; + player.storage.pianchong2 = result.control; + player.addTempSkill("pianchong2", { player: "phaseBeginStart" }); + player.popup(result.control, result.control == "red" ? "fire" : "thunder"); + game.log(player, "声明了", "#y" + get.translation(result.control)); }, - ai:{ - threaten:4.8, + ai: { + threaten: 4.8, }, }, - pianchong2:{ - audio:'pianchong', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + pianchong2: { + audio: "pianchong", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - for(var i of evt.cards2){ - if(get.color(i,player)==player.storage.pianchong2) return true; + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + for (var i of evt.cards2) { + if (get.color(i, player) == player.storage.pianchong2) return true; } return false; }, - content:function(){ - 'step 0' - var num=trigger.getl(player).cards2.filter(function(card){ - return get.color(card,player)==player.storage.pianchong2; + content: function () { + "step 0"; + var num = trigger.getl(player).cards2.filter(function (card) { + return get.color(card, player) == player.storage.pianchong2; }).length; - var cards=[]; - while(num--){ - var card=get.cardPile2(function(card){ - return !cards.includes(card)&&get.color(card,false)!=player.storage.pianchong2; + var cards = []; + while (num--) { + var card = get.cardPile2(function (card) { + return ( + !cards.includes(card) && get.color(card, false) != player.storage.pianchong2 + ); }); - if(card) cards.push(card); + if (card) cards.push(card); else break; } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, - mark:true, - intro:{ - content:'失去一张$牌后,从牌堆中获得一张与此牌颜色不同的牌', + mark: true, + intro: { + content: "失去一张$牌后,从牌堆中获得一张与此牌颜色不同的牌", }, }, - zunwei:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - let storage=player.getStorage('zunwei'); - return storage.length<3&&game.hasPlayer(current=>{ - return player.isDamaged()&¤t.getHp()>player.getHp()&&!storage.includes(0)|| - current.countCards('h')>player.countCards('h')&&!storage.includes(1)|| - current.countCards('e')>player.countCards('e')&&!storage.includes(2); - }); + zunwei: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + let storage = player.getStorage("zunwei"); + return ( + storage.length < 3 && + game.hasPlayer((current) => { + return ( + (player.isDamaged() && + current.getHp() > player.getHp() && + !storage.includes(0)) || + (current.countCards("h") > player.countCards("h") && !storage.includes(1)) || + (current.countCards("e") > player.countCards("e") && !storage.includes(2)) + ); + }) + ); }, - chooseButton:{ - dialog:function(event,player){ - var list=[ - '选择体力值大于你的一名角色', - '选择手牌数大于你的一名角色', - '选择装备数大于你的一名角色', + chooseButton: { + dialog: function (event, player) { + var list = [ + "选择体力值大于你的一名角色", + "选择手牌数大于你的一名角色", + "选择装备数大于你的一名角色", ]; - var choiceList=ui.create.dialog('尊位:请选择一项','forcebutton','hidden'); - choiceList.add([list.map((item,i)=>{ - if(player.getStorage('zunwei').includes(i)) item=`${item}`; - return [i,item]; - }),'textbutton']) + var choiceList = ui.create.dialog("尊位:请选择一项", "forcebutton", "hidden"); + choiceList.add([ + list.map((item, i) => { + if (player.getStorage("zunwei").includes(i)) + item = `${item}`; + return [i, item]; + }), + "textbutton", + ]); return choiceList; }, - filter:function(button){ - const player=get.player(); - if(player.getStorage('zunwei').includes(button.link)) return false; - if(button.link==0){ - if(!player.isDamaged()) return false; - return game.hasPlayer(current=>{ - return current.getHp()>player.getHp(); + filter: function (button) { + const player = get.player(); + if (player.getStorage("zunwei").includes(button.link)) return false; + if (button.link == 0) { + if (!player.isDamaged()) return false; + return game.hasPlayer((current) => { + return current.getHp() > player.getHp(); }); } - if(button.link==1){ - return game.hasPlayer(current=>{ - return current.countCards('h')>player.countCards('h'); + if (button.link == 1) { + return game.hasPlayer((current) => { + return current.countCards("h") > player.countCards("h"); }); } - if(button.link==2){ - return game.hasPlayer(current=>{ - return current.countCards('e')>player.countCards('e'); + if (button.link == 2) { + return game.hasPlayer((current) => { + return current.countCards("e") > player.countCards("e"); }); } }, - backup:function(links){ - var next=get.copy(lib.skill.zunwei.backups[links[0]]); - next.audio='zunwei'; - next.filterCard=function(){return false}; - next.selectCard=-1; + backup: function (links) { + var next = get.copy(lib.skill.zunwei.backups[links[0]]); + next.audio = "zunwei"; + next.filterCard = function () { + return false; + }; + next.selectCard = -1; return next; }, - check:function(button){ - var player=_status.event.player; - switch(button.link){ - case 0:{ - var target=game.findPlayer(function(current){ + check: function (button) { + var player = _status.event.player; + switch (button.link) { + case 0: { + var target = game.findPlayer(function (current) { return current.isMaxHp(); }); - return (Math.min(target.hp,player.maxHp)-player.hp)*2; + return (Math.min(target.hp, player.maxHp) - player.hp) * 2; } - case 1:{ - var target=game.findPlayer(function(current){ + case 1: { + var target = game.findPlayer(function (current) { return current.isMaxHandcard(); }); - return Math.min(5,target.countCards('h')-player.countCards('h'))*0.8; + return Math.min(5, target.countCards("h") - player.countCards("h")) * 0.8; } - case 2:{ - var target=game.findPlayer(function(current){ - return current.isMaxEquip(); + case 2: { + var target = game.findPlayer(function (current) { + return current.isMaxEquip(); }); - return (target.countCards('e')-player.countCards('e'))*1.4; + return (target.countCards("e") - player.countCards("e")) * 1.4; } } }, - prompt:function(links){ + prompt: function (links) { return [ - '选择一名体力值大于你的其他角色,将体力值回复至与其相同', - '选择一名手牌数大于你的其他角色,将手牌数摸至与其相同', - '选择一名装备区内牌数大于你的其他角色,依次使用牌堆中的装备牌,直到装备数与其相同', + "选择一名体力值大于你的其他角色,将体力值回复至与其相同", + "选择一名手牌数大于你的其他角色,将手牌数摸至与其相同", + "选择一名装备区内牌数大于你的其他角色,依次使用牌堆中的装备牌,直到装备数与其相同", ][links[0]]; }, }, - backups:[ - { - filterTarget:function(card,player,target){ - if(player.isHealthy()) return false; - return target.hp>player.hp; - }, - content:function(){ - player.recover(target.hp-player.hp); - if(!player.storage.zunwei) player.storage.zunwei=[]; - player.storage.zunwei.add(0); - }, - ai:{ - order:10, - result:{ - player:function(player,target){ - return (Math.min(target.hp,player.maxHp)-player.hp); + backups: [ + { + filterTarget: function (card, player, target) { + if (player.isHealthy()) return false; + return target.hp > player.hp; + }, + content: function () { + player.recover(target.hp - player.hp); + if (!player.storage.zunwei) player.storage.zunwei = []; + player.storage.zunwei.add(0); + }, + ai: { + order: 10, + result: { + player: function (player, target) { + return Math.min(target.hp, player.maxHp) - player.hp; + }, }, }, }, - }, - { - filterTarget:function(card,player,target){ - return target.countCards('h')>player.countCards('h'); - }, - content:function(){ - player.draw(Math.min(5,target.countCards('h')-player.countCards('h'))); - if(!player.storage.zunwei) player.storage.zunwei=[]; - player.storage.zunwei.add(1); - }, - ai:{ - order:10, - result:{ - player:function(player,target){ - return Math.min(5,target.countCards('h')-player.countCards('h')); + { + filterTarget: function (card, player, target) { + return target.countCards("h") > player.countCards("h"); + }, + content: function () { + player.draw(Math.min(5, target.countCards("h") - player.countCards("h"))); + if (!player.storage.zunwei) player.storage.zunwei = []; + player.storage.zunwei.add(1); + }, + ai: { + order: 10, + result: { + player: function (player, target) { + return Math.min(5, target.countCards("h") - player.countCards("h")); + }, }, }, }, - }, - { - filterTarget:function(card,player,target){ - return target.countCards('e')>player.countCards('e'); - }, - content:function(){ - 'step 0' - if(!player.storage.zunwei) player.storage.zunwei=[]; - player.storage.zunwei.add(2); - event.num=1; - 'step 1' - var type='equip'+num; - if(!player.hasEmptySlot(type)) return; - var card=get.cardPile2(function(card){ - return get.subtype(card,false)==type&&player.canUse(card,player); - }); - if(card) player.chooseUseTarget(card,true).nopopup=true; - 'step 2' - event.num++; - if(event.num<=5&&target.isIn()&&player.countCards('e') player.countCards("e"); + }, + content: function () { + "step 0"; + if (!player.storage.zunwei) player.storage.zunwei = []; + player.storage.zunwei.add(2); + event.num = 1; + "step 1"; + var type = "equip" + num; + if (!player.hasEmptySlot(type)) return; + var card = get.cardPile2(function (card) { + return get.subtype(card, false) == type && player.canUse(card, player); + }); + if (card) player.chooseUseTarget(card, true).nopopup = true; + "step 2"; + event.num++; + if ( + event.num <= 5 && + target.isIn() && + player.countCards("e") < target.countCards("e") + ) + event.goto(1); + }, + ai: { + order: 10, + result: { + player: function (player, target) { + return target.countCards("e") - player.countCards("e"); + }, }, }, }, - }, ], - ai:{ - order:10, - result:{ - player:1, + ai: { + order: 10, + result: { + player: 1, }, }, }, //辛宪英 - rezhongjian:{ - enable:'phaseUse', - audio:'zhongjian', - usable:2, - filter:function(event,player){ - if(player.getStat().skill.rezhongjian&&!player.hasSkill('recaishi2')) return false; - return game.hasPlayer(function(current){ - return lib.skill.rezhongjian.filterTarget(null,player,current); + rezhongjian: { + enable: "phaseUse", + audio: "zhongjian", + usable: 2, + filter: function (event, player) { + if (player.getStat().skill.rezhongjian && !player.hasSkill("recaishi2")) return false; + return game.hasPlayer(function (current) { + return lib.skill.rezhongjian.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - if(!player.storage.rezhongjian2) return true; - return !player.storage.rezhongjian2[0].includes(target)&&!player.storage.rezhongjian2[1].includes(target); + filterTarget: function (card, player, target) { + if (!player.storage.rezhongjian2) return true; + return ( + !player.storage.rezhongjian2[0].includes(target) && + !player.storage.rezhongjian2[1].includes(target) + ); }, - content:function(){ - 'step 0' - player.chooseControl().set('prompt','忠鉴:为'+get.translation(target)+'选择获得一项效果').set('choiceList',[ - '令其于下回合开始前首次造成伤害后弃置两张牌', - '令其于下回合开始前首次受到伤害后摸两张牌', - ]).set('ai',function(){ - return get.attitude(_status.event.player,_status.event.getParent().target)>0?1:0; - }); - 'step 1' - player.addTempSkill('rezhongjian2',{player:'phaseBeginStart'}); + content: function () { + "step 0"; + player + .chooseControl() + .set("prompt", "忠鉴:为" + get.translation(target) + "选择获得一项效果") + .set("choiceList", [ + "令其于下回合开始前首次造成伤害后弃置两张牌", + "令其于下回合开始前首次受到伤害后摸两张牌", + ]) + .set("ai", function () { + return get.attitude(_status.event.player, _status.event.getParent().target) > 0 + ? 1 + : 0; + }); + "step 1"; + player.addTempSkill("rezhongjian2", { player: "phaseBeginStart" }); //var str=['造成伤害弃牌','受到伤害摸牌'][result.index]; //player.popup(str,['fire','wood'][result.index]); //game.log(player,'选择了','#y'+str) player.storage.rezhongjian2[result.index].push(target); - player.markSkill('rezhongjian2'); + player.markSkill("rezhongjian2"); }, - ai:{ - order:10, - expose:0, - result:{ - player:function(player,target){ - if(get.attitude(player,target)==0) return false; - var sgn=get.sgn((get.realAttitude||get.attitude)(player,target)); - if(game.countPlayer(function(current){ - return get.sgn((get.realAttitude||get.attitude)(player,current))==sgn; - })<=game.countPlayer(function(current){ - return get.sgn((get.realAttitude||get.attitude)(player,current))!=sgn; - })) return 1; + ai: { + order: 10, + expose: 0, + result: { + player: function (player, target) { + if (get.attitude(player, target) == 0) return false; + var sgn = get.sgn((get.realAttitude || get.attitude)(player, target)); + if ( + game.countPlayer(function (current) { + return ( + get.sgn((get.realAttitude || get.attitude)(player, current)) == sgn + ); + }) <= + game.countPlayer(function (current) { + return ( + get.sgn((get.realAttitude || get.attitude)(player, current)) != sgn + ); + }) + ) + return 1; return 0.9; }, }, }, }, - rezhongjian2:{ - trigger:{ - global:['damageSource','damageEnd'], + rezhongjian2: { + trigger: { + global: ["damageSource", "damageEnd"], }, - forced:true, - filter:function(event,player,name){ - var num=(name=='damageSource'?0:1); - var logTarget=(name=='damageSource'?event.source:event.player); - return logTarget&&logTarget.isIn()&&player.storage.rezhongjian2[num].includes(logTarget); + forced: true, + filter: function (event, player, name) { + var num = name == "damageSource" ? 0 : 1; + var logTarget = name == "damageSource" ? event.source : event.player; + return ( + logTarget && logTarget.isIn() && player.storage.rezhongjian2[num].includes(logTarget) + ); }, - logTarget:function(event,player,name){ - return (name=='damageSource'?event.source:event.player); + logTarget: function (event, player, name) { + return name == "damageSource" ? event.source : event.player; }, - content:function(){ - var num=(event.triggername=='damageSource'?0:1); - var target=(event.triggername=='damageSource'?trigger.source:trigger.player); - var storage=player.storage.rezhongjian2; + content: function () { + var num = event.triggername == "damageSource" ? 0 : 1; + var target = event.triggername == "damageSource" ? trigger.source : trigger.player; + var storage = player.storage.rezhongjian2; storage[num].remove(target); - if(storage[0].length+storage[1].length) player.markSkill('rezhongjian2'); - else player.removeSkill('rezhongjian2'); - target[event.triggername=='damageSource'?'chooseToDiscard':'draw'](2,true,'he'); + if (storage[0].length + storage[1].length) player.markSkill("rezhongjian2"); + else player.removeSkill("rezhongjian2"); + target[event.triggername == "damageSource" ? "chooseToDiscard" : "draw"](2, true, "he"); player.draw(); }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[[],[]]; + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = [[], []]; }, - onremove:true, - intro:{ - markcount:function(storage){ - return storage[0].length+storage[1].length; + onremove: true, + intro: { + markcount: function (storage) { + return storage[0].length + storage[1].length; }, - mark:function(dialog,storage,player){ - if(player==game.me||player.isUnderControl()){ - if(storage[0].length){ - dialog.addText('弃牌'); - dialog.add([storage[0],'player']); + mark: function (dialog, storage, player) { + if (player == game.me || player.isUnderControl()) { + if (storage[0].length) { + dialog.addText("弃牌"); + dialog.add([storage[0], "player"]); } - if(storage[1].length){ - dialog.addText('摸牌'); - dialog.add([storage[1],'player']); + if (storage[1].length) { + dialog.addText("摸牌"); + dialog.add([storage[1], "player"]); } - } - else{ - var list=storage[0].concat(storage[1]).sortBySeat(player); - dialog.add([list,'player']); + } else { + var list = storage[0].concat(storage[1]).sortBySeat(player); + dialog.add([list, "player"]); } }, }, }, - recaishi:{ - trigger:{player:'phaseDrawEnd'}, - direct:true, - audio:'caishi', - isSame:function(event){ - var cards=[]; - event.player.getHistory('gain',function(evt){ - if(evt.getParent().name=='draw'&&evt.getParent('phaseDraw')==event) cards.addArray(evt.cards); + recaishi: { + trigger: { player: "phaseDrawEnd" }, + direct: true, + audio: "caishi", + isSame: function (event) { + var cards = []; + event.player.getHistory("gain", function (evt) { + if (evt.getParent().name == "draw" && evt.getParent("phaseDraw") == event) + cards.addArray(evt.cards); }); - if(!cards.length) return 'nogain'; - var list=[]; - for(var i=0;i0; - })==0; - }); - 'step 1' - if(result.bool){ - player.logSkill('recaishi'); + player + .chooseBool(get.prompt("recaishi"), "回复1点体力,然后本回合内不能对自己使用牌") + .set("ai", function () { + if (player.countCards("h", "tao")) return false; + if (player.hp < 2) return true; + return ( + player.countCards("h", function (card) { + var info = get.info(card); + return ( + info && + (info.toself || info.selectTarget == -1) && + player.canUse(card, player) && + player.getUseValue(card) > 0 + ); + }) == 0 + ); + }); + "step 1"; + if (result.bool) { + player.logSkill("recaishi"); player.recover(); - player.addTempSkill('recaishi3'); + player.addTempSkill("recaishi3"); } }, }, - recaishi2:{}, - recaishi3:{ - mod:{ - targetEnabled:function(card,player,target){ - if(player==target) return false; + recaishi2: {}, + recaishi3: { + mod: { + targetEnabled: function (card, player, target) { + if (player == target) return false; }, }, - mark:true, - intro:{content:'本回合内不能对自己使用牌'}, + mark: true, + intro: { content: "本回合内不能对自己使用牌" }, }, //刘辩 - shiyuan:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - frequent:true, - filter:function(event,player){ - var num=1; - if(_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.group=='qun'&&player.hasZhuSkill('yuwei',_status.currentPhase)) num=2; - return player!=event.player&&player.getHistory('gain',function(evt){ - return evt.getParent(2).name=='shiyuan'&&evt.cards.length==(2+get.sgn(event.player.hp-player.hp)); - }).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, - global:'dushi2', - locked:true, - trigger:{player:'die'}, - forceDie:true, - direct:true, - skillAnimation:true, - animationColor:'gray', - filter:function(event,player){ - return game.hasPlayer(current=>current!=player); - }, - content:function(){ - 'step 0' - player.chooseTarget('请选择【毒逝】的目标','选择一名其他角色,令其获得技能【毒逝】',true,lib.filter.notMe).set('forceDie',true).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('dushi',target); - target.markSkill('dushi'); - target.addSkills('dushi'); - } - }, - intro:{content:'您已经获得弘农王的诅咒'}, - }, - dushi2:{ - mod:{ - cardSavable:function(card,player,target){ - if(card.name=='tao'&&target!=player&&target.hasSkill('dushi')) return false; + 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]; + }, }, }, }, - yuwei:{ - audio:2, - trigger:{player:'shiyuanBegin'}, - filter:function(event,player){ - return _status.currentPhase.group=='qun'; + dushi: { + audio: 2, + global: "dushi2", + locked: true, + trigger: { player: "die" }, + forceDie: true, + direct: true, + skillAnimation: true, + animationColor: "gray", + filter: function (event, player) { + return game.hasPlayer((current) => current != player); }, - zhuSkill:true, - forced:true, - content:function(){}, - ai:{combo:'shiyuan'}, + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【毒逝】的目标", + "选择一名其他角色,令其获得技能【毒逝】", + true, + lib.filter.notMe + ) + .set("forceDie", true) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("dushi", target); + target.markSkill("dushi"); + target.addSkills("dushi"); + } + }, + intro: { content: "您已经获得弘农王的诅咒" }, + }, + dushi2: { + mod: { + cardSavable: function (card, player, target) { + if (card.name == "tao" && target != player && target.hasSkill("dushi")) return false; + }, + }, + }, + yuwei: { + audio: 2, + trigger: { player: "shiyuanBegin" }, + filter: function (event, player) { + return _status.currentPhase.group == "qun"; + }, + zhuSkill: true, + forced: true, + content: function () {}, + ai: { combo: "shiyuan" }, }, //新岩泽(划掉)留赞 - refenyin:{ - audio:2, - audioname:['wufan'], - trigger:{global:['loseAfter','cardsDiscardAfter','loseAsyncAfter','equipAfter']}, - forced:true, - filter:function(event,player){ - if(player!=_status.currentPhase) return false; - var cards=event.getd(); - if(!cards.length) return false; - var list=[]; - var num=cards.length; - for(var i=0;i0; + player.storage.refenyin_mark2 = num; + return list.length > 0; }, - content:function(){ - var list=[]; - var list2=[]; - var cards=trigger.getd(); - for(var i=0;i4?8:4); - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name=='cardsDiscard'||(evt.name=='lose'&&evt.position==ui.discardPile)) num+=evt.cards.length; + onChooseToUse: function (event) { + if (game.online) return; + var num = 0; + var evt2 = event.getParent(); + if (!evt2.liji_all) evt2.liji_all = game.players.length > 4 ? 8 : 4; + game.getGlobalHistory("cardMove", function (evt) { + if ( + evt.name == "cardsDiscard" || + (evt.name == "lose" && evt.position == ui.discardPile) + ) + num += evt.cards.length; }); - event.set('liji_num',Math.floor(num/evt2.liji_all)); + event.set("liji_num", Math.floor(num / evt2.liji_all)); }, - filterCard:true, - position:'he', - check:function(card){ - var val=get.value(card); - if(!_status.event.player.getStorage('refenyin_mark').includes(get.suit(card))) return 12-val; - return 8-val; + filterCard: true, + position: "he", + check: function (card) { + var val = get.value(card); + if (!_status.event.player.getStorage("refenyin_mark").includes(get.suit(card))) + return 12 - val; + return 8 - val; }, - filterTarget:lib.filter.notMe, - content:function(){ - target.damage('nocard'); + filterTarget: lib.filter.notMe, + content: function () { + target.damage("nocard"); }, - ai:{ - order:1, - result:{ - target:-1.5 + ai: { + order: 1, + result: { + target: -1.5, }, - tag:{ - damage:1 + tag: { + damage: 1, }, }, }, //文鸯 - xinlvli:{ - audio:'lvli', - trigger:{player:'damageEnd',source:'damageSource'}, - filter:function(event,player,name){ - var stat=player.getStat().skill; - if(!stat.xinlvli) stat.xinlvli=0; - if(name=='damageEnd'&&!player.storage.beishui) return false; - if(stat.xinlvli>1) return false; - if(stat.xinlvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; - if(player.hp==player.countCards('h')) return false; - if(player.hp 1) return false; + if (stat.xinlvli > 0 && (player != _status.currentPhase || !player.storage.choujue)) + return false; + if (player.hp == player.countCards("h")) return false; + if (player.hp < player.countCards("h") && player.isHealthy()) return false; return true; }, - content:function(){ - var stat=player.getStat().skill; + content: function () { + var stat = player.getStat().skill; stat.xinlvli++; - var num=player.hp-player.countCards('h'); - if(num>0) player.draw(num); + var num = player.hp - player.countCards("h"); + if (num > 0) player.draw(num); else player.recover(-num); }, //group:'lvli3', }, - lvli:{ - audio:2, - init:function(player,skill){ - player.storage[skill]=0; + lvli: { + audio: 2, + init: function (player, skill) { + player.storage[skill] = 0; }, - enable:'chooseToUse', - filter:function(event,player){ - if(player.storage.lvli>1) return false; - if(player.storage.lvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; - return event.type!='wuxie'&&event.type!='respondShan'; + enable: "chooseToUse", + filter: function (event, player) { + if (player.storage.lvli > 1) return false; + if ( + player.storage.lvli > 0 && + (player != _status.currentPhase || !player.storage.choujue) + ) + return false; + return event.type != "wuxie" && event.type != "respondShan"; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i=0;i=Math.random()){ - player.popup('洗具'); - } - else{ - player.popup('杯具'); + player.popup(trigger.card.name, trigger.name == "useCard" ? "metal" : "wood"); + "step 1"; + var random = 0.5 + player.countCards("e") * 0.1; + if (get.isLuckyStar(player)) random = 1; + if (random >= Math.random()) { + player.popup("洗具"); + } else { + player.popup("杯具"); trigger.cancel(); - if(!trigger.getParent().lvli6){ + if (!trigger.getParent().lvli6) { trigger.getParent().goto(0); } - game.broadcastAll(function(str){ - var dialog=ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function(){ + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { dialog.close(); - },1000); - },get.translation(player)+'声明的'+get.translation(trigger.card.name)+'并没有生效'); - game.log('然而什么都没有发生'); + }, 1000); + }, get.translation(player) + + "声明的" + + get.translation(trigger.card.name) + + "并没有生效"); + game.log("然而什么都没有发生"); game.delay(2); } }, }, - lvli3:{ - trigger:{global:'phaseBefore'}, - forced:true, - silent:true, - popup:false, - content:function(){ - player.storage.lvli=0; + lvli3: { + trigger: { global: "phaseBefore" }, + forced: true, + silent: true, + popup: false, + content: function () { + player.storage.lvli = 0; }, }, - lvli4:{ - log:false, - enable:'chooseToUse', - viewAsFilter:function(player){ - if(player.storage.lvli>1) return false; - if(player.storage.lvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; + lvli4: { + log: false, + enable: "chooseToUse", + viewAsFilter: function (player) { + if (player.storage.lvli > 1) return false; + if ( + player.storage.lvli > 0 && + (player != _status.currentPhase || !player.storage.choujue) + ) + return false; return true; }, - filterCard:function(){return false}, - selectCard:-1, - viewAs:{name:'shan'}, - ai:{ - skillTagFilter:function(player){ - if(player.storage.lvli>1) return false; - if(player.storage.lvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; + filterCard: function () { + return false; + }, + selectCard: -1, + viewAs: { name: "shan" }, + ai: { + skillTagFilter: function (player) { + if (player.storage.lvli > 1) return false; + if ( + player.storage.lvli > 0 && + (player != _status.currentPhase || !player.storage.choujue) + ) + return false; return true; }, - threaten:1.5, - respondShan:true, - } + threaten: 1.5, + respondShan: true, + }, }, - lvli5:{ - log:false, - enable:'chooseToUse', - viewAsFilter:function(player){ - if(player.storage.lvli>1) return false; - if(player.storage.lvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; + lvli5: { + log: false, + enable: "chooseToUse", + viewAsFilter: function (player) { + if (player.storage.lvli > 1) return false; + if ( + player.storage.lvli > 0 && + (player != _status.currentPhase || !player.storage.choujue) + ) + return false; return true; }, - filterCard:function(){return false}, - selectCard:-1, - viewAs:{name:'wuxie'}, + filterCard: function () { + return false; + }, + selectCard: -1, + viewAs: { name: "wuxie" }, }, - lvli6:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - if(!player.storage.beishui) return false; - if(player.storage.lvli>1) return false; - if(player.storage.lvli>0&&(player!=_status.currentPhase||!player.storage.choujue)) return false; + lvli6: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + if (!player.storage.beishui) return false; + if (player.storage.lvli > 1) return false; + if ( + player.storage.lvli > 0 && + (player != _status.currentPhase || !player.storage.choujue) + ) + return false; return true; }, - content:function(){ - var next=player.chooseToUse(); - next.set('norestore',true); - next.set('_backupevent','lvli'); - next.backup('lvli'); - next.set('lvli6',true); + content: function () { + var next = player.chooseToUse(); + next.set("norestore", true); + next.set("_backupevent", "lvli"); + next.backup("lvli"); + next.set("lvli6", true); }, }, - choujue:{ - derivation:['beishui','qingjiao'], - trigger:{global:'phaseAfter'}, - audio:2, - skillAnimation:true, - animationColor:'water', - unique:true, - juexingji:true, - forced:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=false; + choujue: { + derivation: ["beishui", "qingjiao"], + trigger: { global: "phaseAfter" }, + audio: 2, + skillAnimation: true, + animationColor: "water", + unique: true, + juexingji: true, + forced: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = false; }, - filter:function(event,player){ - if(player.storage.choujue) return false; - return Math.abs(player.hp-player.countCards('h'))>=3; + filter: function (event, player) { + if (player.storage.choujue) return false; + return Math.abs(player.hp - player.countCards("h")) >= 3; }, - content:function(){ - player.awakenSkill('choujue'); - player.storage.choujue=true; + content: function () { + player.awakenSkill("choujue"); + player.storage.choujue = true; player.loseMaxHp(); - player.addSkills('beishui'); + player.addSkills("beishui"); }, }, - beishui:{ - trigger:{player:'phaseZhunbeiBegin'}, - audio:2, - skillAnimation:'epic', - animationColor:'thunder', - unique:true, - juexingji:true, - forced:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=false; + beishui: { + trigger: { player: "phaseZhunbeiBegin" }, + audio: 2, + skillAnimation: "epic", + animationColor: "thunder", + unique: true, + juexingji: true, + forced: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = false; }, - filter:function(event,player){ - if(player.storage.beishui) return false; - return Math.min(player.hp,player.countCards('h'))<2; + filter: function (event, player) { + if (player.storage.beishui) return false; + return Math.min(player.hp, player.countCards("h")) < 2; }, - content:function(){ - player.awakenSkill('beishui'); - player.storage.beishui=true; + content: function () { + player.awakenSkill("beishui"); + player.storage.beishui = true; player.loseMaxHp(); - player.addSkills('qingjiao'); + player.addSkills("qingjiao"); }, }, - qingjiao:{ - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - if(!ui.cardPile.hasChildNodes()&&!ui.discardPile.hasChildNodes()); - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i of hs){ - if(!lib.filter.cardDiscardable(i,player,'qingjiao')) return false; + qingjiao: { + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + if (!ui.cardPile.hasChildNodes() && !ui.discardPile.hasChildNodes()); + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i of hs) { + if (!lib.filter.cardDiscardable(i, player, "qingjiao")) return false; } return true; }, //check:function(event,player){ // return player.countCards('h')<=player.hp; //}, - content:function(){ - 'step 0' - player.chooseToDiscard(true,'h',player.countCards('h')); - 'step 1' - var evt=trigger.getParent(); - if(evt&&evt.getParent&&!evt.qingjiao){ - evt.qingjiao=true; - var next=game.createEvent('qingjiao_discard',false,evt.getParent()); - next.player=player; - next.setContent(function(){ - var hs=player.getCards('he'); - if(hs.length) player.discard(hs); + content: function () { + "step 0"; + player.chooseToDiscard(true, "h", player.countCards("h")); + "step 1"; + var evt = trigger.getParent(); + if (evt && evt.getParent && !evt.qingjiao) { + evt.qingjiao = true; + var next = game.createEvent("qingjiao_discard", false, evt.getParent()); + next.player = player; + next.setContent(function () { + var hs = player.getCards("he"); + if (hs.length) player.discard(hs); }); } - 'step 2' - var list=[]; - var typelist=[]; - var getType=function(card){ - var sub=get.subtype(card); - if(sub) return sub; + "step 2"; + var list = []; + var typelist = []; + var getType = function (card) { + var sub = get.subtype(card); + if (sub) return sub; return card.name; }; - for(var i=0;i=8) break; + if (list.length >= 8) break; } } - if(list.length<8){ - for(var i=0;i=8) break; + if (list.length >= 8) break; } } } - player.gain(list,'gain2'); + player.gain(list, "gain2"); }, }, //王双 - spzhuilie:{ - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; + spzhuilie: { + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; }, }, - trigger:{player:'useCardToTargeted'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&!player.inRange(event.target); + trigger: { player: "useCardToTargeted" }, + filter: function (event, player) { + return event.card && event.card.name == "sha" && !player.inRange(event.target); }, - forced:true, - logTarget:'target', - content:function(){ - 'step 0' - player.judge(function(card){ - var type=get.subtype(card); - return ['equip1','equip4','equip3','equip6'].includes(type)?6:-6; + forced: true, + logTarget: "target", + content: function () { + "step 0"; + player.judge(function (card) { + var type = get.subtype(card); + return ["equip1", "equip4", "equip3", "equip6"].includes(type) ? 6 : -6; // switch(type){ // case 'equip':return 4; // case 'trick':return -4; // default:return 0; // } - }).judge2=function(result){ + }).judge2 = function (result) { return result.bool; }; - 'step 1' - if(trigger.getParent().addCount!==false){ - trigger.getParent().addCount=false; - var stat=player.getStat(); - if(stat&&stat.card&&stat.card.sha) stat.card.sha--; + "step 1"; + if (trigger.getParent().addCount !== false) { + trigger.getParent().addCount = false; + var stat = player.getStat(); + if (stat && stat.card && stat.card.sha) stat.card.sha--; } - if(result.bool===true){ - var map=trigger.customArgs; - var id=trigger.target.playerid; - if(!map[id]) map[id]={}; - if(typeof map[id].extraDamage!='number') map[id].extraDamage=0; - map[id].extraDamage+=trigger.target.hp-1; - } - else if(result.bool===false) player.loseHp(); + if (result.bool === true) { + var map = trigger.customArgs; + var id = trigger.target.playerid; + if (!map[id]) map[id] = {}; + if (typeof map[id].extraDamage != "number") map[id].extraDamage = 0; + map[id].extraDamage += trigger.target.hp - 1; + } else if (result.bool === false) player.loseHp(); }, }, - spzhuilie2:{ - onremove:true, - intro:{ - content:'使用【杀】的次数上限+#', + spzhuilie2: { + onremove: true, + intro: { + content: "使用【杀】的次数上限+#", }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('spzhuilie2'); + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("spzhuilie2"); }, }, }, //花鬘 - manyi:{ - audio:2, - audioname:['mengyou','menghuo','zhurong'], - trigger:{target:'useCardToBefore'}, - filter:function(event,player){ - return event.card.name=='nanman'; + manyi: { + audio: 2, + audioname: ["mengyou", "menghuo", "zhurong"], + trigger: { target: "useCardToBefore" }, + filter: function (event, player) { + return event.card.name == "nanman"; }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='nanman') return 'zerotarget'; + ai: { + effect: { + target: function (card) { + if (card.name == "nanman") return "zerotarget"; }, }, }, - group:'manyi_single', - subSkill:{ - single:{ - trigger:{ - player:'enterGame', - global:'gameDrawAfter', + group: "manyi_single", + subSkill: { + single: { + trigger: { + player: "enterGame", + global: "gameDrawAfter", }, - filter:function(event,player){ - return get.mode()=='single'&&_status.mode=='normal'; + filter: function (event, player) { + return get.mode() == "single" && _status.mode == "normal"; }, - direct:true, - content:function(){ - player.chooseUseTarget('nanman',get.prompt('manyi'),'视为使用一张【南蛮入侵】').logSkill='manyi'; + direct: true, + content: function () { + player.chooseUseTarget( + "nanman", + get.prompt("manyi"), + "视为使用一张【南蛮入侵】" + ).logSkill = "manyi"; }, }, }, }, - mansi:{ - audio:2, - group:'mansi_viewas', - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return event.card&&event.card.name=='nanman'; + mansi: { + audio: 2, + group: "mansi_viewas", + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return event.card && event.card.name == "nanman"; }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); - player.addMark('mansi',1,false); + player.addMark("mansi", 1, false); }, - intro:{content:'已因此技能得到了#张牌'}, + intro: { content: "已因此技能得到了#张牌" }, }, - mansi_viewas:{ - audio:'mansi', - position:'h', - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:-1, - filter:function(event,player){ - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i=0;iget.name(card)!=='tao','h'); - } + viewAs: { name: "nanman" }, + 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, - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + souying: { + audio: 2, + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - direct:true, - filter:function(event,player,name){ - if(!player.countCards('he')||player.hasSkill('souying2')) return false; - if(!event.targets||event.targets.length!=1||event.player==event.target) return false; - if(event.card.name!='sha'&&get.type(event.card)!='trick') return false; - if(name=='useCardToPlayered'){ - if(!event.cards.filterInD().length) return false; - var target=event.target; - return player.getHistory('useCard',function(evt){ - return evt.targets&&evt.targets.includes(target); - }).indexOf(event.getParent())>0; - } - else{ - var source=event.player; - return source.getHistory('useCard',function(evt){ - return evt.targets&&evt.targets.includes(player); - }).indexOf(event.getParent())>0; + direct: true, + filter: function (event, player, name) { + if (!player.countCards("he") || player.hasSkill("souying2")) return false; + if (!event.targets || event.targets.length != 1 || event.player == event.target) + return false; + if (event.card.name != "sha" && get.type(event.card) != "trick") return false; + if (name == "useCardToPlayered") { + if (!event.cards.filterInD().length) return false; + var target = event.target; + return ( + player + .getHistory("useCard", function (evt) { + return evt.targets && evt.targets.includes(target); + }) + .indexOf(event.getParent()) > 0 + ); + } else { + var source = event.player; + return ( + source + .getHistory("useCard", function (evt) { + return evt.targets && evt.targets.includes(player); + }) + .indexOf(event.getParent()) > 0 + ); } }, - content:function(){ - 'step 0' - var next=player.chooseToDiscard('he'); + content: function () { + "step 0"; + var next = player.chooseToDiscard("he"); var prompt; - if(event.triggername=='useCardToTargeted'){ - event.target=trigger.player; - prompt='令'+get.translation(trigger.card)+'对你无效'; - next.set('goon',-get.effect(player,trigger.card,trigger.player,player)); + if (event.triggername == "useCardToTargeted") { + event.target = trigger.player; + prompt = "令" + get.translation(trigger.card) + "对你无效"; + next.set("goon", -get.effect(player, trigger.card, trigger.player, player)); + } else { + event.target = trigger.targets[0]; + prompt = "弃置一张牌,并获得" + get.translation(trigger.cards.filterInD()); + next.set("goon", get.value(trigger.cards.filterInD())); } - else{ - event.target=trigger.targets[0]; - prompt='弃置一张牌,并获得'+get.translation(trigger.cards.filterInD()); - next.set('goon',get.value(trigger.cards.filterInD())); - } - next.set('prompt',get.prompt('souying',event.target)); - next.set('prompt2',prompt) - next.set('ai',function(card){ - return _status.event.goon-get.value(card); + next.set("prompt", get.prompt("souying", event.target)); + next.set("prompt2", prompt); + next.set("ai", function (card) { + return _status.event.goon - get.value(card); }); - next.set('logSkill',['souying',event.target]); - 'step 1' - if(result.bool){ - player.addTempSkill('souying2'); - if(event.triggername=='useCardToPlayered') player.gain(trigger.cards.filterInD(),'gain2'); + next.set("logSkill", ["souying", event.target]); + "step 1"; + if (result.bool) { + player.addTempSkill("souying2"); + if (event.triggername == "useCardToPlayered") + player.gain(trigger.cards.filterInD(), "gain2"); else trigger.excluded.add(player); } }, - ai:{ - expose:0.25, + ai: { + expose: 0.25, }, }, - souying2:{}, - zhanyuan:{ - unique:true, - audio:2, - derivation:'hmxili', - skillAnimation:true, - animationColor:'soil', - juexingji:true, - forced:true, - filter:function(event,player){ - return player.countMark('mansi')>7; + souying2: {}, + zhanyuan: { + unique: true, + audio: 2, + derivation: "hmxili", + skillAnimation: true, + animationColor: "soil", + juexingji: true, + forced: true, + filter: function (event, player) { + return player.countMark("mansi") > 7; }, - trigger:{player:'phaseZhunbeiBegin'}, - content:function(){ - 'step 0' - player.awakenSkill('zhanyuan'); + trigger: { player: "phaseZhunbeiBegin" }, + content: function () { + "step 0"; + player.awakenSkill("zhanyuan"); player.gainMaxHp(); player.recover(); - 'step 1' - player.chooseTarget('是否失去〖蛮嗣〗,令一名其他男性角色和自己一同获得技能〖系力〗?',function(card,player,target){ - return target!=player&&target.hasSex('male'); - }).ai=function(target){ - return get.attitude(_status.event.player,target); + "step 1"; + player.chooseTarget( + "是否失去〖蛮嗣〗,令一名其他男性角色和自己一同获得技能〖系力〗?", + function (card, player, target) { + return target != player && target.hasSex("male"); + } + ).ai = function (target) { + return get.attitude(_status.event.player, target); }; - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'fire'); - player.changeSkills(['hmxili'],['mansi']); - target.addSkills('hmxili'); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "fire"); + player.changeSkills(["hmxili"], ["mansi"]); + target.addSkills("hmxili"); } }, + ai: { + combo: "mansi" + }, }, - hmxili:{ - trigger:{global:'damageBegin1'}, - direct:true, - audio:2, - filter:function(event,player){ - return event.source&&event.source!=player&&event.source==_status.currentPhase&&event.source.hasSkill('hmxili')&&!event.player.hasSkill('hmxili')&&player.countCards('he')>0&&!player.hasSkill('hmxili2'); + hmxili: { + trigger: { global: "damageBegin1" }, + direct: true, + audio: 2, + filter: function (event, player) { + return ( + event.source && + event.source != player && + event.source == _status.currentPhase && + event.source.hasSkill("hmxili") && + !event.player.hasSkill("hmxili") && + player.countCards("he") > 0 && + !player.hasSkill("hmxili2") + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('是否弃置一张牌,令'+get.translation(trigger.source)+'对'+get.translation(trigger.player)+'的伤害+1,且你与其各摸两张牌?','he').set('logSkill',['hmxili',trigger.player]).ai=function(card){ - return 9-get.value(card); + content: function () { + "step 0"; + player + .chooseToDiscard( + "是否弃置一张牌,令" + + get.translation(trigger.source) + + "对" + + get.translation(trigger.player) + + "的伤害+1,且你与其各摸两张牌?", + "he" + ) + .set("logSkill", ["hmxili", trigger.player]).ai = function (card) { + return 9 - get.value(card); }; - 'step 1' - if(result.bool){ - game.asyncDraw([trigger.source,player],2); + "step 1"; + if (result.bool) { + game.asyncDraw([trigger.source, player], 2); trigger.num++; - player.addTempSkill('hmxili2'); - } - else event.finish(); - 'step 2' + player.addTempSkill("hmxili2"); + } else event.finish(); + "step 2"; game.delayx(); }, }, - hmxili2:{}, + hmxili2: {}, //吴兰雷铜 - wlcuorui:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - if(!['identity','guozhan'].includes(get.mode())){ - return game.hasPlayer(function(current){ - return current.isFriendOf(player)&¤t.countDiscardableCards(player,'hej')>0; + wlcuorui: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + if (!["identity", "guozhan"].includes(get.mode())) { + return game.hasPlayer(function (current) { + return ( + current.isFriendOf(player) && current.countDiscardableCards(player, "hej") > 0 + ); }); } - return game.hasPlayer(current=>{ - return get.distance(player,current)<=1&¤t.countDiscardableCards(player,'hej')>0; + return game.hasPlayer((current) => { + return ( + get.distance(player, current) <= 1 && + current.countDiscardableCards(player, "hej") > 0 + ); }); }, - content:function(){ - 'step 0' - if(!['identity','guozhan'].includes(get.mode())){ - player.chooseTarget(function(card,player,target){ - return target.isFriendOf(player)&&target.countDiscardableCards(player,'hej')>0; - },get.prompt2('wlcuorui')).set('ai',function(target){ - if(target.countCards('e',function(card){ - return card.name!='tengjia'&&get.value(card,target)<=0; - })) return 10; - if(target.countCards('j',function(card){ - return get.effect(target,{name:card.viewAs||card.name},target,target)<0; - })) return 10; - return Math.random()+0.2-1/target.countCards('hej'); - }); - } - else{ - player.chooseTarget(function(card,player,target){ - return get.distance(player,target)<=1&&target.countDiscardableCards(player,'hej')>0; - },get.prompt2('wlcuorui')).set('ai',function(target){ - if(game.hasPlayer(current=>{ - return current!=target&&get.attitude(_status.event.player,current)<0; - })) return get.effect(target,{name:'guohe'},player,player)+10; - return 0; - }); - } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('wlcuorui',target); - player.discardPlayerCard(target,'hej',true); - if(['identity','guozhan'].includes(get.mode())) event.goto(7); - } - else event.finish(); - 'step 2' - if(!result.cards||!result.cards.length){ - event.finish(); - return; - } - var color=get.color(result.cards[0],result.cards[0].original=='j'?false:target); - event.color=color; - var list=[]; - if(game.hasPlayer(function(current){ - return (get.mode()=='versus'?current.isEnemyOf(player):current!=player&¤t!=target)&¤t.countCards('h'); - })) list.push('展示手牌'); - if(game.hasPlayer(function(current){ - return (get.mode()=='versus'?current.isEnemyOf(player):current!=player&¤t!=target)&¤t.countCards('e',{color:color}); - })) list.push('弃置装备'); - if(!list.length){ - event.finish(); - return; - } - if(list.length==1) event._result={control:list[0]}; - else player.chooseControl(list).set('prompt','挫锐:展示对手的至多两张手牌,或弃置对手装备区内至多两张'+get.translation(color)+'牌').set('ai',function(){ - var player=_status.event.player; - var color=_status.event.getParent().color; - if(game.countPlayer(function(current){ - if(!current.isEnemyOf(player)) return false; - return current.countCards('e',function(card){ - return get.color(card)==color&&get.value(card)>0; + content: function () { + "step 0"; + if (!["identity", "guozhan"].includes(get.mode())) { + player + .chooseTarget(function (card, player, target) { + return ( + target.isFriendOf(player) && + target.countDiscardableCards(player, "hej") > 0 + ); + }, get.prompt2("wlcuorui")) + .set("ai", function (target) { + if ( + target.countCards("e", function (card) { + return card.name != "tengjia" && get.value(card, target) <= 0; + }) + ) + return 10; + if ( + target.countCards("j", function (card) { + return ( + get.effect( + target, + { name: card.viewAs || card.name }, + target, + target + ) < 0 + ); + }) + ) + return 10; + return Math.random() + 0.2 - 1 / target.countCards("hej"); + }); + } else { + player + .chooseTarget(function (card, player, target) { + return ( + get.distance(player, target) <= 1 && + target.countDiscardableCards(player, "hej") > 0 + ); + }, get.prompt2("wlcuorui")) + .set("ai", function (target) { + if ( + game.hasPlayer((current) => { + return ( + current != target && + get.attitude(_status.event.player, current) < 0 + ); + }) + ) + return get.effect(target, { name: "guohe" }, player, player) + 10; + return 0; }); - })>1) return 1; - return 0; - }); - 'step 3' - if(result.control=='弃置装备') event.goto(5); - else{ - var dialog=['请选择要展示的牌']; - var list=game.filterPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('h'); - }).sortBySeat(); - for(var i of list){ - dialog.push('
              '+get.translation(i)+'
              '); - if(player.hasSkillTag('viewHandcard',null,i,true)) dialog.push(i.getCards('h')); - else dialog.push([i.getCards('h'),'blank']); - } - player.chooseButton([1,2],true).set('createDialog',dialog).set('ai',function(button){ - var color=(get.color(button.link)==_status.event.getParent().color); - return color?Math.random():0.35; - }); } - 'step 4' + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("wlcuorui", target); + player.discardPlayerCard(target, "hej", true); + if (["identity", "guozhan"].includes(get.mode())) event.goto(7); + } else event.finish(); + "step 2"; + if (!result.cards || !result.cards.length) { + event.finish(); + return; + } + var color = get.color(result.cards[0], result.cards[0].original == "j" ? false : target); + event.color = color; + var list = []; + if ( + game.hasPlayer(function (current) { + return ( + (get.mode() == "versus" + ? current.isEnemyOf(player) + : current != player && current != target) && current.countCards("h") + ); + }) + ) + list.push("展示手牌"); + if ( + game.hasPlayer(function (current) { + return ( + (get.mode() == "versus" + ? current.isEnemyOf(player) + : current != player && current != target) && + current.countCards("e", { color: color }) + ); + }) + ) + list.push("弃置装备"); + if (!list.length) { + event.finish(); + return; + } + if (list.length == 1) event._result = { control: list[0] }; + else + player + .chooseControl(list) + .set( + "prompt", + "挫锐:展示对手的至多两张手牌,或弃置对手装备区内至多两张" + + get.translation(color) + + "牌" + ) + .set("ai", function () { + var player = _status.event.player; + var color = _status.event.getParent().color; + if ( + game.countPlayer(function (current) { + if (!current.isEnemyOf(player)) return false; + return current.countCards("e", function (card) { + return get.color(card) == color && get.value(card) > 0; + }); + }) > 1 + ) + return 1; + return 0; + }); + "step 3"; + if (result.control == "弃置装备") event.goto(5); + else { + var dialog = ["请选择要展示的牌"]; + var list = game + .filterPlayer(function (current) { + return current.isEnemyOf(player) && current.countCards("h"); + }) + .sortBySeat(); + for (var i of list) { + dialog.push('
              ' + get.translation(i) + "
              "); + if (player.hasSkillTag("viewHandcard", null, i, true)) + dialog.push(i.getCards("h")); + else dialog.push([i.getCards("h"), "blank"]); + } + player + .chooseButton([1, 2], true) + .set("createDialog", dialog) + .set("ai", function (button) { + var color = get.color(button.link) == _status.event.getParent().color; + return color ? Math.random() : 0.35; + }); + } + "step 4"; player.showCards(result.links); - var map={}; - var map2={}; - for(var i of result.links){ - var id=get.owner(i).playerid; - if(!map[id]) map[id]=[]; + var map = {}; + var map2 = {}; + for (var i of result.links) { + var id = get.owner(i).playerid; + if (!map[id]) map[id] = []; map[id].push(i); - if(get.color(i)!=event.color) continue; - if(!map2[id]) map2[id]=[]; + if (get.color(i) != event.color) continue; + if (!map2[id]) map2[id] = []; map2[id].push(i); } - for(var i in map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - if(map2[i]) player.gain(map2[i],source,'bySelf','give'); + for (var i in map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (map2[i]) player.gain(map2[i], source, "bySelf", "give"); player.line(source); - game.log(player,'展示了',source,'的',map[i]); + game.log(player, "展示了", source, "的", map[i]); } - event.next.sort(function(a,b){ - return lib.sort.seat(a.source||a.player,b.source||b.player); + event.next.sort(function (a, b) { + return lib.sort.seat(a.source || a.player, b.source || b.player); }); event.finish(); - 'step 5' - var dialog=['请选择要弃置的牌']; - var list=game.filterPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('e',function(card){ - return get.color(card)==event.color; - }); - }).sortBySeat(); - for(var i of list){ - dialog.push('
              '+get.translation(i)+'
              '); - dialog.push(i.getCards('e',function(card){ - return get.color(card)==event.color; - })); + "step 5"; + var dialog = ["请选择要弃置的牌"]; + var list = game + .filterPlayer(function (current) { + return ( + current.isEnemyOf(player) && + current.countCards("e", function (card) { + return get.color(card) == event.color; + }) + ); + }) + .sortBySeat(); + for (var i of list) { + dialog.push('
              ' + get.translation(i) + "
              "); + dialog.push( + i.getCards("e", function (card) { + return get.color(card) == event.color; + }) + ); } - player.chooseButton([1,2],true).set('createDialog',dialog).set('ai',function(button){ - var owner=get.owner(button.link); - return get.value(button.link,owner) - }); - 'step 6' - var map={}; - for(var i of result.links){ - if(get.color(i)!=event.color) continue; - var id=get.owner(i).playerid; - if(!map[id]) map[id]=[]; + player + .chooseButton([1, 2], true) + .set("createDialog", dialog) + .set("ai", function (button) { + var owner = get.owner(button.link); + return get.value(button.link, owner); + }); + "step 6"; + var map = {}; + for (var i of result.links) { + if (get.color(i) != event.color) continue; + var id = get.owner(i).playerid; + if (!map[id]) map[id] = []; map[id].push(i); } - for(var i in map){ - (_status.connectMode?lib.playerOL:game.playerMap)[i].discard(map[i],'notBySelf').discarder=player; + for (var i in map) { + (_status.connectMode ? lib.playerOL : game.playerMap)[i].discard( + map[i], + "notBySelf" + ).discarder = player; } - event.next.sort(function(a,b){ - return lib.sort.seat(a.player,b.player); + event.next.sort(function (a, b) { + return lib.sort.seat(a.player, b.player); }); event.finish(); - 'step 7' - if(!result.cards||!result.cards.length){ + "step 7"; + if (!result.cards || !result.cards.length) { event.finish(); return; } - if(game.hasPlayer(current=>{ - return current.countCards('he')>0&¤t!=player&¤t!=target; - })){ - var color=get.color(result.cards[0],result.cards[0].original=='j'?false:target); - event.color=color; - var next=player.chooseTarget(true,'挫锐:选择另一名其他角色','弃置该角色装备区里至多两张'+get.translation(event.color)+'牌;或展示该角色的至多两张手牌,然后获得其中的'+get.translation(event.color)+'牌'); - next.set('filterTarget',(card,player,target)=>{ - return target.countCards('he')>0&&target!=player&&target!=_status.event.getParent().target; + if ( + game.hasPlayer((current) => { + return current.countCards("he") > 0 && current != player && current != target; + }) + ) { + var color = get.color( + result.cards[0], + result.cards[0].original == "j" ? false : target + ); + event.color = color; + var next = player.chooseTarget( + true, + "挫锐:选择另一名其他角色", + "弃置该角色装备区里至多两张" + + get.translation(event.color) + + "牌;或展示该角色的至多两张手牌,然后获得其中的" + + get.translation(event.color) + + "牌" + ); + next.set("filterTarget", (card, player, target) => { + return ( + target.countCards("he") > 0 && + target != player && + target != _status.event.getParent().target + ); }); - next.set('ai',target=>{ - return -get.attitude(_status.event.player,target)*target.countCards('he')+0.1; + next.set("ai", (target) => { + return ( + -get.attitude(_status.event.player, target) * target.countCards("he") + 0.1 + ); }); - } - else event.finish(); - 'step 8' - if(result.bool){ - var targetx=result.targets[0]; - event.targetx=targetx; + } else event.finish(); + "step 8"; + if (result.bool) { + var targetx = result.targets[0]; + event.targetx = targetx; player.line(targetx); - player.choosePlayerCard(targetx,'he',true,[1,2]).set('prompt','展示至多两张手牌,或弃置至多两张'+get.translation(event.color)+'装备').set('filterButton',button=>{ - if(ui.selected.buttons.length){ - var linkx=ui.selected.buttons[0].link; - if(get.position(button.link)!=get.position(linkx)) return false; - } - if(get.position(button.link)=='e') return get.color(button.link,_status.event.target)==_status.event.getParent().color; - return true; - }).set('target',targetx); - } - else event.finish(); - 'step 9' - if(result.bool){ - var cards=result.links; - if(get.position(cards[0])=='e'){ - event.targetx.discard(cards,'notBySelf').discarder=player; + player + .choosePlayerCard(targetx, "he", true, [1, 2]) + .set( + "prompt", + "展示至多两张手牌,或弃置至多两张" + get.translation(event.color) + "装备" + ) + .set("filterButton", (button) => { + if (ui.selected.buttons.length) { + var linkx = ui.selected.buttons[0].link; + if (get.position(button.link) != get.position(linkx)) return false; + } + if (get.position(button.link) == "e") + return ( + get.color(button.link, _status.event.target) == + _status.event.getParent().color + ); + return true; + }) + .set("target", targetx); + } else event.finish(); + "step 9"; + if (result.bool) { + var cards = result.links; + if (get.position(cards[0]) == "e") { + event.targetx.discard(cards, "notBySelf").discarder = player; event.finish(); - } - else{ - player.showCards(cards,get.translation(event.targetx)+'因【挫锐】展示的牌'); - var cards2=cards.filter(card=>{ - return get.color(card)==event.color; + } else { + player.showCards(cards, get.translation(event.targetx) + "因【挫锐】展示的牌"); + var cards2 = cards.filter((card) => { + return get.color(card) == event.color; }); - if(cards2.length) player.gain(cards2,event.targetx,'give'); + if (cards2.length) player.gain(cards2, event.targetx, "give"); } } }, }, - kuiji:{ - audio:2, - usable:1, - enable:"phaseUse", - filter:function(event,player){ - if(player.hasJudge('bingliang')) return false; - return player.countCards('hes',function(card){ - return get.color(card)=='black'&&get.type(card)=='basic'; - })>0; + kuiji: { + audio: 2, + usable: 1, + enable: "phaseUse", + filter: function (event, player) { + if (player.hasJudge("bingliang")) return false; + return ( + player.countCards("hes", function (card) { + return get.color(card) == "black" && get.type(card) == "basic"; + }) > 0 + ); }, - position:'hes', - discard:false, - lose:false, - delay:false, - prepare:function(cards,player){ - player.$give(cards,player,false); + position: "hes", + discard: false, + lose: false, + delay: false, + prepare: function (cards, player) { + player.$give(cards, player, false); }, - filterCard:function(card,player,event){ - return get.color(card)=='black'&&get.type(card)=='basic'&&player.canAddJudge({name:'bingliang',cards:[card]}); + filterCard: function (card, player, event) { + return ( + get.color(card) == "black" && + get.type(card) == "basic" && + player.canAddJudge({ name: "bingliang", cards: [card] }) + ); }, - selectTarget:-1, - filterTarget:function(card,player,target){ - return player==target; + selectTarget: -1, + filterTarget: function (card, player, target) { + return player == target; }, - check:function(card){ - return 9-get.value(card); + check: function (card) { + return 9 - get.value(card); }, // onuse:function(links,player){ // var next=game.createEvent('kuiji_content',false,_status.event.getParent()); @@ -13614,95 +17661,138 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // next.setContent(lib.skill.kuiji.kuiji_content); // }, // kuiji_content:function(){ - content:function(){ - 'step 0' - player.addJudge({name:'bingliang'},cards); + content: function () { + "step 0"; + player.addJudge({ name: "bingliang" }, cards); player.draw(); - 'step 1' - var next=player.chooseTarget().set('ai',function(target){ - let player=_status.event.player; - if(target.hasSkillTag('filterDamage',null,{ - player:player - },true)) return get.damageEffect(target,player,player); - return 2*get.damageEffect(target,player,player); + "step 1"; + var next = player.chooseTarget().set("ai", function (target) { + let player = _status.event.player; + if ( + target.hasSkillTag( + "filterDamage", + null, + { + player: player, + }, + true + ) + ) + return get.damageEffect(target, player, player); + return 2 * get.damageEffect(target, player, player); }); - if(!['identity','guozhan'].includes(get.mode())){ - next.set('prompt','选择一名体力值最大的敌方角色,对其造成2点伤害'); - next.set('filterTarget',function(card,player,target){ - return target.isEnemyOf(player)&&!game.hasPlayer(function(current){ - return current.isEnemyOf(player)&¤t.hp>target.hp; - }); + if (!["identity", "guozhan"].includes(get.mode())) { + next.set("prompt", "选择一名体力值最大的敌方角色,对其造成2点伤害"); + next.set("filterTarget", function (card, player, target) { + return ( + target.isEnemyOf(player) && + !game.hasPlayer(function (current) { + return current.isEnemyOf(player) && current.hp > target.hp; + }) + ); + }); + } else { + next.set("prompt", "选择一名除你外体力值最大的角色,对其造成2点伤害"); + next.set("filterTarget", function (card, player, target) { + return ( + player != target && + !game.hasPlayer(function (current) { + return current != player && current.hp > target.hp; + }) + ); }); } - else{ - next.set('prompt','选择一名除你外体力值最大的角色,对其造成2点伤害'); - next.set('filterTarget',function(card,player,target){ - return player!=target&&!game.hasPlayer(function(current){ - return current!=player&¤t.hp>target.hp; - }); - }); - } - 'step 2' - if(result.bool){ - var target=result.targets[0]; + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); target.damage(2); } }, - ai:{ - result:{ - target:function(player,target){ + ai: { + result: { + target: function (player, target) { let es; - if(['identity','guozhan'].includes(get.mode())) es=game.hasPlayer(i=>{ - return i!=player&&!game.hasPlayer(j=>{ - return player!==j&&j.hp>i.hp; - })&&get.attitude(player,i)<0; - }); - else es=game.hasPlayer(i=>{ - return i.isEnemyOf(player)&&!game.hasPlayer(j=>{ - return j.hp>i.hp&&j.isEnemyOf(player); - })&&get.attitude(player,i)<0; - }); - if(es) return 2; + if (["identity", "guozhan"].includes(get.mode())) + es = game.hasPlayer((i) => { + return ( + i != player && + !game.hasPlayer((j) => { + return player !== j && j.hp > i.hp; + }) && + get.attitude(player, i) < 0 + ); + }); + else + es = game.hasPlayer((i) => { + return ( + i.isEnemyOf(player) && + !game.hasPlayer((j) => { + return j.hp > i.hp && j.isEnemyOf(player); + }) && + get.attitude(player, i) < 0 + ); + }); + if (es) return 2; return -1.5; }, }, - order:12, + order: 12, }, - group:'kuiji_dying', - subSkill:{ - dying:{ - trigger:{global:'dying'}, - filter:function(event,player){ - let evt=event.getParent(2); - return evt&&evt.name=='kuiji'; + group: "kuiji_dying", + subSkill: { + dying: { + trigger: { global: "dying" }, + filter: function (event, player) { + let evt = event.getParent(2); + return evt && evt.name == "kuiji"; }, - locked:true, - direct:true, - content:function(){ - 'step 0' + locked: true, + direct: true, + content: function () { + "step 0"; var list; - if(['identity','guozhan'].includes(get.mode())) list=game.filterPlayer(current=>{ - return current!==trigger.player&&!game.hasPlayer(i=>{ - return trigger.player!==i&&i.hpi.isDamaged()); - else list=game.filterPlayer(current=>{ - return current.isFriendOf(player)&&!game.hasPlayer(i=>{ - return i.hpi.isDamaged()); - if(list.length>1) player.chooseTarget('溃击:选择一名角色回复1点体力',(card,player,target)=>{ - return _status.event.list.includes(target); - },true).set('list',list).set('ai',target=>{ - return get.recoverEffect(target,player,_status.event.player); - }); - else if(list.length) event._result={bool:true,targets:list}; - else event._result={bool:false}; - 'step 1' - if(result.bool){ - let target=result.targets[0]; - player.logSkill('kuiji',target); + if (["identity", "guozhan"].includes(get.mode())) + list = game + .filterPlayer((current) => { + return ( + current !== trigger.player && + !game.hasPlayer((i) => { + return trigger.player !== i && i.hp < current.hp; + }) + ); + }) + .filter((i) => i.isDamaged()); + else + list = game + .filterPlayer((current) => { + return ( + current.isFriendOf(player) && + !game.hasPlayer((i) => { + return i.hp < current.hp && i.isFriendOf(player); + }) + ); + }) + .filter((i) => i.isDamaged()); + if (list.length > 1) + player + .chooseTarget( + "溃击:选择一名角色回复1点体力", + (card, player, target) => { + return _status.event.list.includes(target); + }, + true + ) + .set("list", list) + .set("ai", (target) => { + return get.recoverEffect(target, player, _status.event.player); + }); + else if (list.length) event._result = { bool: true, targets: list }; + else event._result = { bool: false }; + "step 1"; + if (result.bool) { + let target = result.targets[0]; + player.logSkill("kuiji", target); target.recover(); } }, @@ -13710,86 +17800,95 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //蒲元 - pytianjiang:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + pytianjiang: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + locked: false, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var i=0; - var list=[]; - while(i++<2){ - var card=get.cardPile(function(card){ - if(get.type(card)!='equip') return false; - return list.length==0||get.subtype(card)!=get.subtype(list[0]); + content: function () { + "step 0"; + var i = 0; + var list = []; + while (i++ < 2) { + var card = get.cardPile(function (card) { + if (get.type(card) != "equip") return false; + return list.length == 0 || get.subtype(card) != get.subtype(list[0]); }); - if(card) list.push(card); + if (card) list.push(card); } - if(!list.length){event.finish();return;} - event.list=list; - player.gain(event.list,'gain2'); - 'step 1' + if (!list.length) { + event.finish(); + return; + } + event.list = list; + player.gain(event.list, "gain2"); + "step 1"; game.delay(1); - var card=event.list.shift(); - if(player.getCards('h').includes(card)){ - player.$give(card,player,false) + var card = event.list.shift(); + if (player.getCards("h").includes(card)) { + player.$give(card, player, false); player.equip(card); } - if(event.list.length) event.redo(); + if (event.list.length) event.redo(); }, - group:'pytianjiang_move', + group: "pytianjiang_move", }, - pytianjiang_move:{ - audio:'pytianjiang', - prompt:'将装备区里的一张牌移动至其他角色的装备区', - enable:'phaseUse', - position:'e', - filter:function(event,player){ - return player.countCards('e')>0; + pytianjiang_move: { + audio: "pytianjiang", + prompt: "将装备区里的一张牌移动至其他角色的装备区", + enable: "phaseUse", + position: "e", + filter: function (event, player) { + return player.countCards("e") > 0; }, - check:function(){return 1}, - filterCard:true, - filterTarget:function(event,player,target){ - return target!=player&&target.canEquip(ui.selected.cards[0],true); + check: function () { + return 1; }, - prepare:'give', - discard:false, - lose:false, - content:function(){ - 'step 0' + filterCard: true, + filterTarget: function (event, player, target) { + return target != player && target.canEquip(ui.selected.cards[0], true); + }, + prepare: "give", + discard: false, + lose: false, + content: function () { + "step 0"; target.equip(cards[0]); - 'step 1' - if(cards[0].name.indexOf('pyzhuren_')==0&&!player.getCards('e').includes(cards[0])) player.draw(2); + "step 1"; + if (cards[0].name.indexOf("pyzhuren_") == 0 && !player.getCards("e").includes(cards[0])) + player.draw(2); }, - ai:{ - order:(item,player)=>{ - if(player.hasCard(i=>get.subtype(i)==='equip1','h')) return 11; + ai: { + order: (item, player) => { + if (player.hasCard((i) => get.subtype(i) === "equip1", "h")) return 11; return 1; }, - expose:0.2, - result:{ - target:function(player,target){ - if(ui.selected.cards.length){ - let card=ui.selected.cards[0],tv=get.value(card,target),sub=get.subtype(card); - if(sub==='equip1'){ - let ev=Infinity,te=target.getEquips(1); - if(!te.length) return tv; - te.forEach(i=>{ - ev=Math.min(ev,get.value(i)); + expose: 0.2, + result: { + target: function (player, target) { + if (ui.selected.cards.length) { + let card = ui.selected.cards[0], + tv = get.value(card, target), + sub = get.subtype(card); + if (sub === "equip1") { + let ev = Infinity, + te = target.getEquips(1); + if (!te.length) return tv; + te.forEach((i) => { + ev = Math.min(ev, get.value(i)); }); - if(card.name.indexOf('pyzhuren_')==0) return 2+tv-ev; - return tv-ev; + if (card.name.indexOf("pyzhuren_") == 0) return 2 + tv - ev; + return tv - ev; } - if(target.hasCard(i=>get.subtype(i)===sub,'he')) return 0; - let pv=get.value(card,player); - if(pv>0&&Math.abs(tv)<=pv) return 0; + if (target.hasCard((i) => get.subtype(i) === sub, "he")) return 0; + let pv = get.value(card, player); + if (pv > 0 && Math.abs(tv) <= pv) return 0; return tv; } return 0; @@ -13797,730 +17896,862 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - pyzhuren:{ - audio:2, - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:1, - check:function(card){ - var player=_status.event.player; - var name='pyzhuren_'+(card[card.name=='shandian'?'name':'suit']); - if(!lib.card[name]||_status.pyzhuren&&_status.pyzhuren[name]){ - if(!player.countCards('h','sha')) return 4-get.value(card); + pyzhuren: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 1, + check: function (card) { + var player = _status.event.player; + var name = "pyzhuren_" + card[card.name == "shandian" ? "name" : "suit"]; + if (!lib.card[name] || (_status.pyzhuren && _status.pyzhuren[name])) { + if (!player.countCards("h", "sha")) return 4 - get.value(card); return 0; } - return 7-get.value(card); + return 7 - get.value(card); }, - content:function(){ + content: function () { //player.addSkill('pyzhuren_destroy'); - if(!_status.pyzhuren) _status.pyzhuren={}; - var rand=0.85; - var num=get.number(cards[0]); - if(num>4) rand=0.9; - if(num>8) rand=0.95; - if(num>12||cards[0].name=='shandian'||get.isLuckyStar(player)) rand=1; - var name='pyzhuren_'+(cards[0][cards[0].name=='shandian'?'name':'suit']); - if(!lib.card[name]||_status.pyzhuren[name]||Math.random()>rand){ - player.popup('杯具'); - game.log(player,'锻造失败'); - var card=get.cardPile(function(card){ - return card.name=='sha'; + if (!_status.pyzhuren) _status.pyzhuren = {}; + var rand = 0.85; + var num = get.number(cards[0]); + if (num > 4) rand = 0.9; + if (num > 8) rand = 0.95; + if (num > 12 || cards[0].name == "shandian" || get.isLuckyStar(player)) rand = 1; + var name = "pyzhuren_" + cards[0][cards[0].name == "shandian" ? "name" : "suit"]; + if (!lib.card[name] || _status.pyzhuren[name] || Math.random() > rand) { + player.popup("杯具"); + game.log(player, "锻造失败"); + var card = get.cardPile(function (card) { + return card.name == "sha"; }); - if(card) player.gain(card,'gain2'); - } - else{ - _status.pyzhuren[name]=true; - var card=game.createCard(name,cards[0].name=='shandian'?'spade':cards[0].suit,1); - card.destroyed='discardPile'; - player.gain(card,'gain2') + if (card) player.gain(card, "gain2"); + } else { + _status.pyzhuren[name] = true; + var card = game.createCard( + name, + cards[0].name == "shandian" ? "spade" : cards[0].suit, + 1 + ); + card.destroyed = "discardPile"; + player.gain(card, "gain2"); } }, - ai:{ - order:10, - result:{ - player:1, + ai: { + order: 10, + result: { + player: 1, }, }, }, - pyzhuren_heart:{ - audio:true, - trigger:{source:'damageSource'}, - usable:1, - equipSkill:true, - filter:function(event,player){ - return event.getParent().name=='sha'; + pyzhuren_heart: { + audio: true, + trigger: { source: "damageSource" }, + usable: 1, + equipSkill: true, + filter: function (event, player) { + return event.getParent().name == "sha"; }, - content:function(){ - 'step 0' - player.judge(function(card){ - var player=_status.event.getParent('pyzhuren_heart').player; - if(player.isHealthy()&&get.color(card)=='red') return 0; + content: function () { + "step 0"; + player.judge(function (card) { + var player = _status.event.getParent("pyzhuren_heart").player; + if (player.isHealthy() && get.color(card) == "red") return 0; return 2; }); - 'step 1' - if(result.color=='red') player.recover(); + "step 1"; + if (result.color == "red") player.recover(); else player.draw(2); }, - ai:{ - equipValue:function(card,player){ - if(player.isDamaged()) return 4.5; + ai: { + equipValue: function (card, player) { + if (player.isDamaged()) return 4.5; return 6; }, - basic:{ - equipValue:4.5 - } - } + basic: { + equipValue: 4.5, + }, + }, }, - pyzhuren_diamond:{ - audio:true, - trigger:{source:'damageBegin1'}, - direct:true, - usable:2, - equipSkill:true, - mod:{ - cardUsable:function(card,player,num){ - var cardx=player.getEquip('pyzhuren_diamond'); - if(card.name=='sha'&&(!cardx||player.hasSkill('pyzhuren_diamond',null,false)||(!_status.pyzhuren_diamond_temp&&!ui.selected.cards.includes(cardx)))){ - return num+1; + pyzhuren_diamond: { + audio: true, + trigger: { source: "damageBegin1" }, + direct: true, + usable: 2, + equipSkill: true, + mod: { + cardUsable: function (card, player, num) { + var cardx = player.getEquip("pyzhuren_diamond"); + if ( + card.name == "sha" && + (!cardx || + player.hasSkill("pyzhuren_diamond", null, false) || + (!_status.pyzhuren_diamond_temp && !ui.selected.cards.includes(cardx))) + ) { + return num + 1; } }, - cardEnabled2:function(card,player){ - if(!_status.event.addCount_extra||player.hasSkill('pyzhuren_diamond',null,false)) return; - if(card&&card==player.getEquip('pyzhuren_diamond')){ - _status.pyzhuren_diamond_temp=true; - var bool=lib.filter.cardUsable(get.autoViewAs({name:'sha'},ui.selected.cards.concat([card])),player); + cardEnabled2: function (card, player) { + if (!_status.event.addCount_extra || player.hasSkill("pyzhuren_diamond", null, false)) + return; + if (card && card == player.getEquip("pyzhuren_diamond")) { + _status.pyzhuren_diamond_temp = true; + var bool = lib.filter.cardUsable( + get.autoViewAs({ name: "sha" }, ui.selected.cards.concat([card])), + player + ); delete _status.pyzhuren_diamond_temp; - if(!bool) return false; + if (!bool) return false; } }, }, - filter:function(event,player){ - if(event.getParent().name!='sha') return false; - return player.countCards('he',function(card){ - return card!=player.getEquip('pyzhuren_diamond'); - })>0; + filter: function (event, player) { + if (event.getParent().name != "sha") return false; + return ( + player.countCards("he", function (card) { + return card != player.getEquip("pyzhuren_diamond"); + }) > 0 + ); }, - content:function(){ - 'step 0' - var next=player.chooseToDiscard('he',function(card,player){ - return card!=player.getEquip('pyzhuren_diamond'); - },get.prompt(event.name,trigger.player),'弃置一张牌,令即将对其造成的伤害+1'); - next.set('target',trigger.player); - next.ai=function(card){ - if(_status.event.goon) return 30/(1+_status.event.target.hp)-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + function (card, player) { + return card != player.getEquip("pyzhuren_diamond"); + }, + get.prompt(event.name, trigger.player), + "弃置一张牌,令即将对其造成的伤害+1" + ); + next.set("target", trigger.player); + next.ai = function (card) { + if (_status.event.goon) return 30 / (1 + _status.event.target.hp) - get.value(card); return -1; }; - next.set('goon',get.attitude(player,trigger.player)<0&&!trigger.player.hasSkillTag('filterDamage',null,{ - player:player, - card:trigger.card, - })&&get.damageEffect(trigger.player,player,player,get.natureList(trigger))>0); - next.logSkill=[event.name,trigger.player]; - 'step 1' - if(result.bool) trigger.num++; + next.set( + "goon", + get.attitude(player, trigger.player) < 0 && + !trigger.player.hasSkillTag("filterDamage", null, { + player: player, + card: trigger.card, + }) && + get.damageEffect(trigger.player, player, player, get.natureList(trigger)) > 0 + ); + next.logSkill = [event.name, trigger.player]; + "step 1"; + if (result.bool) trigger.num++; else player.storage.counttrigger.pyzhuren_diamond--; }, - ai:{ - expose:0.25, - equipValue:function(card,player){ - return Math.min(7,3.6+player.countCards('h')/2); + ai: { + expose: 0.25, + equipValue: function (card, player) { + return Math.min(7, 3.6 + player.countCards("h") / 2); }, - basic:{ - equipValue:4.5 - } - } + basic: { + equipValue: 4.5, + }, + }, }, - pyzhuren_club:{ - audio:true, - trigger:{player:'useCard2'}, - direct:true, - equipSkill:true, - filter:function(event,player){ - if(event.card.name!='sha'&&get.type(event.card)!='trick') return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - var num=player.getHistory('useSkill',function(evt){ - return evt.skill=='pyzhuren_club'; + pyzhuren_club: { + audio: true, + trigger: { player: "useCard2" }, + direct: true, + equipSkill: true, + filter: function (event, player) { + if (event.card.name != "sha" && get.type(event.card) != "trick") return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + var num = player.getHistory("useSkill", function (evt) { + return evt.skill == "pyzhuren_club"; }).length; - if(num>=2) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return lib.filter.targetEnabled2(event.card,player,current)&&!event.targets.includes(current); - })){ + if (num >= 2) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + lib.filter.targetEnabled2(event.card, player, current) && + !event.targets.includes(current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'额外指定一个目标'; - player.chooseTarget([1,player.storage.fumian_red],get.prompt(event.name),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "额外指定一个目标"; + player + .chooseTarget( + [1, player.storage.fumian_red], + get.prompt(event.name), + function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return lib.filter.targetEnabled2(_status.event.card, player, target); + } + ) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; } - 'step 2' - if(event.targets){ - player.logSkill(event.name,event.targets); + "step 2"; + if (event.targets) { + player.logSkill(event.name, event.targets); trigger.targets.addArray(event.targets); } }, - ai:{ - equipValue:function(card,player){ - if(player.getEnemies().length<2){ - if(player.isDamaged()) return 0; + ai: { + equipValue: function (card, player) { + if (player.getEnemies().length < 2) { + if (player.isDamaged()) return 0; return 1; } return 4.5; }, - basic:{ - equipValue:4.5 - } - } + basic: { + equipValue: 4.5, + }, + }, }, - pyzhuren_spade:{ - audio:true, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha';//&&event.targets.length==1&&get.color(event.card)=='black'; + pyzhuren_spade: { + audio: true, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha"; //&&event.targets.length==1&&get.color(event.card)=='black'; }, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - equipSkill:true, - logTarget:'target', - content:function(){ - var num=player.getHistory('useSkill',function(evt){ - return evt.skill=='pyzhuren_spade'; + equipSkill: true, + logTarget: "target", + content: function () { + var num = player.getHistory("useSkill", function (evt) { + return evt.skill == "pyzhuren_spade"; }).length; - trigger.target.loseHp(Math.min(num,5));//.set('source',player); + trigger.target.loseHp(Math.min(num, 5)); //.set('source',player); }, - ai:{ - equipValue:function(card,player){ - return 1+4*Math.min(5,player.getCardUsable('sha')); + ai: { + equipValue: function (card, player) { + return 1 + 4 * Math.min(5, player.getCardUsable("sha")); }, - basic:{ - equipValue:5 + basic: { + equipValue: 5, + }, + jueqing: true, + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "unequip_ai") return arg && arg.name === "sha"; }, - jueqing:true, - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='unequip_ai') return arg&&arg.name==='sha'; - } }, }, - pyzhuren_shandian:{ - audio:true, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha';//&&event.targets.length==1; + pyzhuren_shandian: { + audio: true, + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + return event.card.name == "sha"; //&&event.targets.length==1; }, - check:function(event,player){ - return get.attitude(player,event.target)<=0; + check: function (event, player) { + return get.attitude(player, event.target) <= 0; }, - equipSkill:true, - logTarget:'target', - content:function(){ - 'step 0' - trigger.target.judge(function(card){ - var suit=get.suit(card); - if(suit=='spade') return -10; - if(suit=='club') return -5; + equipSkill: true, + logTarget: "target", + content: function () { + "step 0"; + trigger.target.judge(function (card) { + var suit = get.suit(card); + if (suit == "spade") return -10; + if (suit == "club") return -5; return 0; - }).judge2=function(result){ - return result.color=='black'?true:false; + }).judge2 = function (result) { + return result.color == "black" ? true : false; }; - 'step 1' - if(result.suit=='spade'){ - trigger.target.damage(3,'thunder'); + "step 1"; + if (result.suit == "spade") { + trigger.target.damage(3, "thunder"); //trigger.getParent().excluded.add(trigger.target); - } - else if(result.suit=='club'){ - trigger.target.damage('thunder'); + } else if (result.suit == "club") { + trigger.target.damage("thunder"); player.recover(); player.draw(); } }, - ai:{ - equipValue:function(card,player){ - if(player.isDamaged()) return 6; + ai: { + equipValue: function (card, player) { + if (player.isDamaged()) return 6; return 4.8; }, - basic:{ - equipValue:5 - } - } + basic: { + equipValue: 5, + }, + }, }, //管辂和葛玄 - gxlianhua:{ - derivation:['reyingzi','reguanxing','xinzhiyan','gongxin'], - audio:2, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]={ - red:0,black:0, - } + gxlianhua: { + derivation: ["reyingzi", "reguanxing", "xinzhiyan", "gongxin"], + audio: 2, + init: function (player, skill) { + if (!player.storage[skill]) + player.storage[skill] = { + red: 0, + black: 0, + }; }, - marktext:'丹', - intro:{ - name:'丹血', - markcount:function(storage){ - return storage.red+storage.black; + marktext: "丹", + intro: { + name: "丹血", + markcount: function (storage) { + return storage.red + storage.black; }, - content:function(storage){ - return '共有'+(storage.red+storage.black)+'个标记'; + content: function (storage) { + return "共有" + (storage.red + storage.black) + "个标记"; }, }, - trigger:{global:'damageEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.player!=player&&event.player.isIn()&&_status.currentPhase!=player; + trigger: { global: "damageEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + return event.player != player && event.player.isIn() && _status.currentPhase != player; }, - content:function(){ - player.storage.gxlianhua[player.getFriends().includes(trigger.player)?'red':'black']++; - player.markSkill('gxlianhua'); + content: function () { + player.storage.gxlianhua[ + player.getFriends().includes(trigger.player) ? "red" : "black" + ]++; + player.markSkill("gxlianhua"); }, - group:'gxlianhua_harmonia', - subSkill:{ - harmonia:{ - forced:true, - audio:'gxlianhua', - sub:true, - trigger:{player:'phaseZhunbeiBegin'}, + group: "gxlianhua_harmonia", + subSkill: { + harmonia: { + forced: true, + audio: "gxlianhua", + sub: true, + trigger: { player: "phaseZhunbeiBegin" }, //filter:function(event,player){ // return player.storage.gxlianhua&&player.storage.gxlianhua.red+player.storage.gxlianhua.black>0; //}, - content:function(){ - var cards=[]; - var cards2=[]; - var skill=''; - var red=player.storage.gxlianhua.red; - var black=player.storage.gxlianhua.black; - player.storage.gxlianhua={red:0,black:0}; - player.unmarkSkill('gxlianhua'); - if(red+black<4){ - cards=['tao']; - skill='reyingzi'; + content: function () { + var cards = []; + var cards2 = []; + var skill = ""; + var red = player.storage.gxlianhua.red; + var black = player.storage.gxlianhua.black; + player.storage.gxlianhua = { red: 0, black: 0 }; + player.unmarkSkill("gxlianhua"); + if (red + black < 4) { + cards = ["tao"]; + skill = "reyingzi"; + } else if (red > black) { + cards = ["wuzhong"]; + skill = "reguanxing"; + } else if (red < black) { + cards = ["shunshou"]; + skill = "xinzhiyan"; + } else { + cards = ["sha", "juedou"]; + skill = "gongxin"; } - else if(red>black){ - cards=['wuzhong']; - skill='reguanxing'; - } - else if(red{ - if(get.attitude(target,current)>0) return 0.3; - if(target.hasJudge('lebu')) return 0.6; - if(target.inRange(current)) return 1.5; - return 1; - })); + ai: { + order: 1, + result: { + player: function (player, target) { + return Math.max( + 0, + 1 + + target.countCards("h") - + game.countPlayer((current) => { + if (get.attitude(target, current) > 0) return 0.3; + if (target.hasJudge("lebu")) return 0.6; + if (target.inRange(current)) return 1.5; + return 1; + }) + ); }, - target:function(player,target){ - return -Math.max(0,1+target.countCards('h')-game.countPlayer(current=>{ - if(get.attitude(target,current)>0) return 0.3; - if(target.hasJudge('lebu')) return 0.6; - if(target.inRange(current)) return 1.5; - return 1; - })); - } - } + target: function (player, target) { + return -Math.max( + 0, + 1 + + target.countCards("h") - + game.countPlayer((current) => { + if (get.attitude(target, current) > 0) return 0.3; + if (target.hasJudge("lebu")) return 0.6; + if (target.inRange(current)) return 1.5; + return 1; + }) + ); + }, + }, }, - subSkill:{ - hf:{ - trigger:{ - global:'phaseDiscardBegin' + subSkill: { + hf: { + trigger: { + global: "phaseDiscardBegin", }, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player!=player&&event.player.hasMark('zhafu_hf'); + forced: true, + charlotte: true, + filter: function (event, player) { + return event.player != player && event.player.hasMark("zhafu_hf"); }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - target.removeMark('zhafu_hf',1); - if(target.countCards('h')<=1) event.finish() - 'step 1' - target.chooseCard('h',true,'选择保留一张手牌,将其余的手牌交给'+get.translation(player)).set('ai',get.value); - 'step 2' - var cards=target.getCards('h'); + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + target.removeMark("zhafu_hf", 1); + if (target.countCards("h") <= 1) event.finish(); + "step 1"; + target + .chooseCard( + "h", + true, + "选择保留一张手牌,将其余的手牌交给" + get.translation(player) + ) + .set("ai", get.value); + "step 2"; + var cards = target.getCards("h"); cards.remove(result.cards[0]); - target.give(cards,player); + target.give(cards, player); }, - intro:{ - content:'mark', - onunmark:true, + intro: { + content: "mark", + onunmark: true, }, }, }, }, - tuiyan:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - frequent:true, - content:function(){ - 'step 0' - var cards=get.cards(3); - event.cards=cards; - game.log(player,'观看了牌堆顶的'+get.cnNumber(cards.length)+'张牌'); - player.chooseControl('ok').set('dialog',['推演',cards]); - 'step 1' - while(cards.length){ - ui.cardPile.insertBefore(cards.pop(),ui.cardPile.firstChild); + tuiyan: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + frequent: true, + content: function () { + "step 0"; + var cards = get.cards(3); + event.cards = cards; + game.log(player, "观看了牌堆顶的" + get.cnNumber(cards.length) + "张牌"); + player.chooseControl("ok").set("dialog", ["推演", cards]); + "step 1"; + while (cards.length) { + ui.cardPile.insertBefore(cards.pop(), ui.cardPile.firstChild); } game.updateRoundNumber(); }, }, - busuan:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - var list=[]; - for(var i=0;i0) return 1 - return -5/(target.countCards('h')+1); + ai: { + order: 1, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if (att > 0) return 1; + return -5 / (target.countCards("h") + 1); }, }, }, }, - busuan_angelbeats:{ - mark:true, - intro:{ - mark:function(dialog,content,player){ - if(content&&content.length) dialog.add([content,'vcard']); + busuan_angelbeats: { + mark: true, + intro: { + mark: function (dialog, content, player) { + if (content && content.length) dialog.add([content, "vcard"]); }, }, - trigger:{player:'drawBefore'}, - forced:true, - filter:function(event,player){ - return event.getParent().name=='phaseDraw'; + trigger: { player: "drawBefore" }, + forced: true, + filter: function (event, player) { + return event.getParent().name == "phaseDraw"; }, - onremove:true, - content:function(){ - 'step 0' - var list=player.storage['busuan_angelbeats']; - var cards=[]; - for(var i=0;i1) player.loseHp(); + content: function () { + "step 0"; + event.count = 0; + "step 1"; + player.draw("visible"); + "step 2"; + if (Array.isArray(result)) { + event.count += result.length; + if (get.color(result) != "red") { + if (player.hp > 1) player.loseHp(); event.finish(); - } - else if(event.count<3) player.chooseBool('是否继续发动【命戒】?').ai=function(){ - if(event.count==2) return Math.random()<0.5; - return lib.skill.mingjie.check(); - }; - } - else event.finish(); - 'step 3' - if(result.bool) event.goto(1); + } else if (event.count < 3) + player.chooseBool("是否继续发动【命戒】?").ai = function () { + if (event.count == 2) return Math.random() < 0.5; + return lib.skill.mingjie.check(); + }; + } else event.finish(); + "step 3"; + if (result.bool) event.goto(1); }, }, }, - card:{ - pyzhuren_heart:{ - fullskin:true, - derivation:'puyuan', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-2}, - skills:['pyzhuren_heart'], - onDestroy(card){ - if(_status.pyzhuren&&_status.pyzhuren[card.name]){ - delete _status.pyzhuren[card.name]; - } + card: { + //武关羽的兵临城下水淹七军 + shuiyanqijuny: { + audio: "shuiyanqijun", + fullskin: true, + cardimage: "shuiyanqijunx", + enable: true, + filterTarget: true, + type: "trick", + selectTarget: [1, 2], + targetprompt: ["受伤弃牌", "受伤摸牌"], + contentBefore() { + var evt = event.getParent(), + target = evt.stocktargets[0]; + evt.shuiyanqijun_target = target; }, - ai:{ - basic:{ - equipValue:4 - } + content() { + target.damage("thunder"); + if (target != event.getParent().shuiyanqijun_target) target.draw(); + else target.chooseToDiscard("he", true); + }, + ai: { + order: 6, + value: 4, + useful: 2, + tag: { + damage: 1, + thunderDamage: 1, + natureDamage: 1, + loseCard: 1, + }, + result: { + target: function (player, target) { + if (!ui.selected.targets.length) return -1.5; + return -0.5; + }, + }, }, }, - pyzhuren_diamond:{ - fullskin:true, - derivation:'puyuan', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - skills:['pyzhuren_diamond'], - onDestroy(card){ - if(_status.pyzhuren&&_status.pyzhuren[card.name]){ + pyzhuren_heart: { + fullskin: true, + derivation: "puyuan", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -2 }, + skills: ["pyzhuren_heart"], + onDestroy(card) { + if (_status.pyzhuren && _status.pyzhuren[card.name]) { delete _status.pyzhuren[card.name]; } }, - ai:{ - basic:{ - equipValue:3 - } + ai: { + basic: { + equipValue: 4, + }, }, }, - pyzhuren_club:{ - fullskin:true, - derivation:'puyuan', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-1}, - skills:['pyzhuren_club'], - onDestroy(card){ - if(_status.pyzhuren&&_status.pyzhuren[card.name]){ + pyzhuren_diamond: { + fullskin: true, + derivation: "puyuan", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["pyzhuren_diamond"], + onDestroy(card) { + if (_status.pyzhuren && _status.pyzhuren[card.name]) { delete _status.pyzhuren[card.name]; } }, - ai:{ - basic:{ - equipValue:5 + ai: { + basic: { + equipValue: 3, + }, + }, + }, + pyzhuren_club: { + fullskin: true, + derivation: "puyuan", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -1 }, + skills: ["pyzhuren_club"], + onDestroy(card) { + if (_status.pyzhuren && _status.pyzhuren[card.name]) { + delete _status.pyzhuren[card.name]; } }, - loseDelay:false, - onLose:function(){ - var next=game.createEvent('baiyin_recover'); + ai: { + basic: { + equipValue: 5, + }, + }, + loseDelay: false, + onLose: function () { + var next = game.createEvent("baiyin_recover"); event.next.remove(next); - var evt=event.getParent(); - if(evt.getlx===false) evt=evt.getParent(); + var evt = event.getParent(); + if (evt.getlx === false) evt = evt.getParent(); evt.after.push(next); - next.player=player; - next.setContent(function(){ - if(player.isDamaged()) player.logSkill('pyzhuren_club'); + next.player = player; + next.setContent(function () { + if (player.isDamaged()) player.logSkill("pyzhuren_club"); player.recover(); }); }, }, - pyzhuren_spade:{ - fullskin:true, - derivation:'puyuan', - type:'equip', - subtype:'equip1', - skills:['pyzhuren_spade'], - onDestroy(card){ - if(_status.pyzhuren&&_status.pyzhuren[card.name]){ + pyzhuren_spade: { + fullskin: true, + derivation: "puyuan", + type: "equip", + subtype: "equip1", + skills: ["pyzhuren_spade"], + onDestroy(card) { + if (_status.pyzhuren && _status.pyzhuren[card.name]) { delete _status.pyzhuren[card.name]; } }, - ai:{ - basic:{ - equipValue:3 - } + ai: { + basic: { + equipValue: 3, + }, }, }, - pyzhuren_shandian:{ - fullskin:true, - derivation:'puyuan', - type:'equip', - subtype:'equip1', - distance:{attackFrom:-3}, - skills:['pyzhuren_shandian'], - onDestroy(card){ - if(_status.pyzhuren&&_status.pyzhuren[card.name]){ + pyzhuren_shandian: { + fullskin: true, + derivation: "puyuan", + type: "equip", + subtype: "equip1", + distance: { attackFrom: -3 }, + skills: ["pyzhuren_shandian"], + onDestroy(card) { + if (_status.pyzhuren && _status.pyzhuren[card.name]) { delete _status.pyzhuren[card.name]; } }, - ai:{ - basic:{ - equipValue:3 - } + ai: { + basic: { + equipValue: 3, + }, }, }, - dagongche:{ - fullskin:true, - derivation:'zhangfen', - type:'equip', - subtype:'equip5', - skills:['dagongche_skill'], - cardPrompt:function(card){ - if(!card.storage) return '出牌阶段开始时,你可以视为使用一张【杀】,且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其一张牌。若此【大攻车】未被强化,则其他角色无法弃置你装备区内的【大攻车】。当此牌离开你的装备区后,销毁之。'; - var str='出牌阶段开始时,你可以视为使用一张'; - if(card.storage.大攻车选项一) str+='无距离限制且无视防具的'; - str+='【杀】'; - if(card.storage.大攻车选项二) str+=('(此【杀】的目标上限+'+card.storage.大攻车选项二+')'); - str+=',且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其'; - var num=1; - if(card.storage.大攻车选项三) num+=card.storage.大攻车选项三; - str+=get.cnNumber(num); - str+='张牌。当此牌离开你的装备区后,销毁之。'; + dagongche: { + fullskin: true, + derivation: "zhangfen", + type: "equip", + subtype: "equip5", + skills: ["dagongche_skill"], + cardPrompt: function (card) { + if (!card.storage) + return "出牌阶段开始时,你可以视为使用一张【杀】,且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其一张牌。若此【大攻车】未被强化,则其他角色无法弃置你装备区内的【大攻车】。当此牌离开你的装备区后,销毁之。"; + var str = "出牌阶段开始时,你可以视为使用一张"; + if (card.storage.大攻车选项一) str += "无距离限制且无视防具的"; + str += "【杀】"; + if (card.storage.大攻车选项二) + str += "(此【杀】的目标上限+" + card.storage.大攻车选项二 + ")"; + str += ",且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其"; + var num = 1; + if (card.storage.大攻车选项三) num += card.storage.大攻车选项三; + str += get.cnNumber(num); + str += "张牌。当此牌离开你的装备区后,销毁之。"; return str; }, - destroy:true, - ai:{ - basic:{ - equipValue:3 - } + destroy: true, + ai: { + basic: { + equipValue: 3, + }, }, }, - pilitoushiche:{ - fullskin:true, - derivation:'dc_liuye', - cardimage:'ly_piliche', - type:'equip', - subtype:'equip5', - skills:['pilitoushiche'], - destroy:true, - ai:{ - basic:{ - equipValue:3 - } + pilitoushiche: { + fullskin: true, + derivation: "dc_liuye", + cardimage: "ly_piliche", + type: "equip", + subtype: "equip5", + skills: ["pilitoushiche"], + destroy: true, + ai: { + basic: { + equipValue: 3, + }, }, }, }, - characterIntro:{ - cuimao:'请分别查看「崔琰」和「毛玠」的武将介绍。', - bailingyun:'柏灵筠,女,是电视剧《大军师司马懿之军师联盟》、《虎啸龙吟》中的主要角色之一,由张钧甯饰演。20岁,是曹丕赏赐司马懿的美人,也是曹丕的眼线,被送入司马府中为妾室。柔弱美貌、心机极深。', - caoxian:'曹宪(生卒年不详),女,沛国谯县(今安徽省亳州市)人。东汉末年历史人物,汉献帝刘协嫔妃,魏武帝曹操女儿。建安十八年,嫁给汉献帝刘协,受封为贵人。黄初元年(220年),兄弟曹丕称帝后,汉献帝成为山阳公,不知所终。', - zhangjian:'张臶(136年-240年),字子明,钜鹿人。汉末三国时期隐士、音乐家,精通谶纬之学。张臶生活的年代从东汉一直到曹魏齐王时期,受到朝廷多次征召,一直回避,不愿做官。他活了一百零五岁,是三国时期有可靠记载的最长寿的人之一。', - puyuan:'蒲元是三国时蜀汉杰出的工匠。为诸葛亮造刀三千口,并且制作木牛流马。后来姜维为他写过两部传记《蒲元传》《蒲元别传》。', - guanlu:"管辂(209年-256年),字公明,平原(今山东德州平原县)人。三国时期曹魏术士。年八九岁,便喜仰观星辰。成人后,精通《周易》,善于卜筮、相术,习鸟语,相传每言辄中,出神入化。体性宽大,常以德报怨。正元初,为少府丞。北宋时被追封为平原子。管辂是历史上著名的术士,被后世奉为卜卦观相的祖师。", - gexuan:"葛玄(164年-244年),汉族,吴丹阳郡句容县都乡吉阳里人(今句容市),祖籍山东琅琊,三国著名高道,道教灵宝派祖师。字孝先,号仙翁,被尊称为“葛天师”。道教尊为葛仙翁,又称太极仙翁,与张道陵、许逊、萨守坚共为四大天师。为汉下邳僮侯葛艾后裔,祖葛矩,安平太守,黄门郎;从祖葛弥,豫章第五郡太守。父葛焉,字德儒,州主簿,山阴令,散骑常侍,大尚书。随左慈学道,得《太清丹经》、《黄帝九鼎神丹经》、《金液丹经》等道经。曾采药海山,吴嘉禾二年(233年),在閤皂山修道建庵,筑坛立炉,修炼九转金丹。喜好遨游山川,去过括苍山、南岳山、罗浮山。编撰《灵宝经诰》,精研上清、灵宝等道家真经,并嘱弟子世世箓传。", - wulan:'吴兰(?~218年),青州(今山东潍坊市)人。东汉末年将领。初为益州牧刘璋部将,后来归降刘备。汉中之战中,与马超、张飞各领一军,驻扎于下辩。建安二十三年,为曹操将领曹洪、张郃所败,退回汉中。途中,为阴平氐族首领强端所杀。', - leitong:'雷铜(?-218年),阴平(今甘肃文县)人,氐族,东汉末年益州名将。本属益州牧刘璋麾下。刘备攻取益州后,归刘备麾下。参加汉中之战,为魏将张郃所杀。', - huaman:'花鬘,古典戏曲《龙凤巾》(一名《化外奇缘》)中的人物,身份为三国时期南蛮王孟获与祝融夫人的女儿,关索的夫人之一。在关于关三小姐·关银屏的民间传说中,其名字为“花中秀”,与关索其他几位夫人鲍三娘、王桃、王悦都被关索之姐关银屏编入自己的女兵营中。花鬘在《三国志》,《三国演义》均未有提及,只是戏曲中的虚构人物。其形象并非一般君主家中闺秀,而是与其母祝融相似,是一个可以披甲上阵,善于刀枪作战的女武将。戏曲中在诸葛亮平定南蛮时,花鬘曾与关索作战,失败被俘,两人互生爱意,南蛮王孟获降服后二人成婚。近些年,花鬘接连在各类三国题材的游戏中登场,更广被人知晓。', - wangshuang:'王双(?-228年),三国时期曹魏将领。蜀汉建兴六年(228年)冬,诸葛亮出散关,攻陈仓,后粮尽而退。王双率领骑兵追击蜀军,但在与蜀军的交战中被击败,王双也被蜀军所斩。在《三国演义》中,王双字子全,是陇西郡狄道县(今甘肃临洮县)人,有万夫不当之勇。在诸葛亮北伐期间,被魏延所斩。', - wenyang:"文俶(238年—291年),一作文淑,字次骞,小名阿鸯,世称文鸯,谯郡(今安徽亳州市)人。魏末晋初名将,曹魏扬州刺史文钦之子。骁勇善战,依附大将军曹爽,效忠于王室。司马师废黜皇帝曹芳后,随父联合毌丘俭于淮南起兵勤王。兵败之后,向南投奔吴国。诸葛诞发动淮南叛乱,奉命率军驰援。双方发生内讧,父亲为诸葛诞所害,遂降于司马昭,封关内侯。西晋建立后,任平虏护军。咸宁三年(277年),拜平西将军、都督凉秦雍州三州军事,大破鲜卑首领秃发树机能,名震天下,迁使持节、护东夷校尉、监辽东军事。八王之乱中,为诸葛诞外孙、东安王司马繇所诬杀,惨遭灭族,时年五十四岁。", - liubian:'刘辩(176年-190年3月6日),是汉灵帝刘宏与何皇后的嫡长子。刘辩在灵帝驾崩后继位为帝,史称少帝,由于年幼,实权掌握在临朝称制的母亲何太后和母舅大将军何进手中。少帝在位时期,东汉政权已经名存实亡,他即位后不久即遭遇以何进为首的外戚集团和以十常侍为首的内廷宦官集团这两大敌对政治集团的火并,被迫出宫,回宫后又受制于以“勤王”为名进京的凉州军阀董卓,终于被废为弘农王,成为东汉唯一被废黜的皇帝,其同父异母弟陈留王刘协继位为帝,是为汉献帝。被废黜一年之后,刘辩在董卓胁迫下自尽,时年仅十五岁(一说十八岁),其弟献帝追谥他为怀王。中国古代的史书中称刘辩为皇子辩、少帝和弘农王等。因为在位不逾年,传统上称东汉共十二帝,刘辩与东汉另一位少帝刘懿都不在其中,亦皆无本纪;不过,现代史学界也有观点承认两位少帝均是汉朝皇帝,则刘辩为东汉第十三位皇帝。', - guozhao:'郭照,电视剧《军师联盟》中的女主角之一,由唐艺昕饰演。原型为文德皇后郭氏(字女王),魏国皇后,张春华的义妹,深爱曹丕,替甄宓抚育曹叡,因甄宓之死被曹叡记恨,曹丕死后,成为皇太后,被曹叡逼上死路。自尽身亡。', - fanyufeng:'樊夫人,东汉末年人物,昔桂阳太守赵范寡嫂。赵云随刘备平定江南四郡后,刘备以赵云为桂阳太守。赵范居心叵测,要将自己的嫂嫂樊氏嫁给赵云,但遭到赵云的拒绝。后来,赵范逃走,樊氏也下落不明。2001年,应日本日中青少年文化中心成立50周年之邀,北京京剧院赴日进行40场巡回演出,这次访日的剧目都不同程度地进行了加工改编,以符合日本观众的需求。《取桂阳》是根据老本重新排演的,叶金援饰赵云,王怡饰樊玉凤。剧中的樊玉凤成为文武双全的巾帼英雄,被赵云收降,后来在《龙凤呈祥》中也参与堵截东吴的追兵。', - ruanyu:'阮瑀(约165—212年),字元瑜,陈留尉氏(今河南开封市尉氏县)人,是东汉末年文学家,建安七子之一。阮瑀所作章表书记很出色,当时军国书檄文字,多为阮瑀与陈琳所拟。名作有《为曹公作书与孙权》。诗有《驾出北郭门行》,描写孤儿受后母虐待的苦难遭遇,比较生动形象。年轻时曾受学于蔡邕,蔡邕称他为“奇才”。后徙为丞相仓曹掾属。诗歌语言朴素,往往能反映出一般的社会问题。阮瑀的音乐修养颇高,他的儿子阮籍,孙子阮咸皆当时名人,位列“竹林七贤”,妙于音律。明人辑有《阮元瑜集》。', - yangwan:'杨氏(婉字出自小说,史书无记载),生卒年不详,东汉末年凉州人。早年嫁于东汉前将军、槐里侯马腾之子马超,追随马超转战并州、雍州、凉州,为马超生下子嗣。公元212年,马超联军在渭南战败后,杨婉随马超逃亡凉州,很快马超反攻吞并陇上诸郡县。公元213年,杨婉为了帮助马超,结识王异,了解马超这些投降部下。可惜被王异蛊惑,遭致马超大败。自己和孩子都被赵衢、梁宽杀害。', - zhouyi:'周夷,游卡桌游旗下产品《三国杀》自行杜撰的人物。设定为周瑜的妹妹,和周瑜一同征战。', - caojinyu:'金乡公主,本姓曹氏,名字不详,沛国谯县(今安徽省亳州市)人。魏武帝曹操的女儿,母为杜夫人。适婚的时候,嫁给曹操的养子何晏。高平陵之变,何晏作为大将军曹爽的党羽,遭到太傅司马懿处死。在何晏母亲尹夫人苦苦哀求下,何晏的儿子得以保全。', - wufan:'吴范(?-226年),字文则,会稽上虞(今浙江绍兴上虞区)人。三国时期孙吴官员,擅长术数。与刘惇、赵达、严武、曹不兴、皇象、宋寿和郑妪合称“吴中八绝”。吴范以推算天象节气和观察气候闻名于郡中。孙权起于东南,他委身事奉,每推算灾祥多应验,遂显名。孙权委以骑都尉,领太史令。初,孙权为将军时,他曾说江南有王气。及孙权立为吴王,论功行封,欲以为都亭侯,但因不愿将其术要诀告知孙权,为权所怨恨,被除名。黄武中,病死。', - caomao:'曹髦(241年11月15日-260年6月2日),字彦士,沛国谯县(今安徽省亳州市)人,魏文帝曹丕之孙,东海王曹霖之子,曹魏第四位皇帝(254年11月1日-260年6月2日)。正始二年(241年),生于东海王宫,自幼聪明好学,才慧早成,正始五年(244年),封为高贵乡公,嘉平六年(254年),大将军司马师废除齐王曹芳后,拥立为帝,年号正元,曹髦文才武略,崇拜少康,不满司马氏专权秉政,甘露五年(260年),亲自讨伐司马昭,为太子舍人成济所弑,年仅十九岁,以王礼葬于洛阳西北。曹髦擅长诗文,创制了九言诗,传世文章有《伤魂赋并序》《颜子论》等。爱好儒学,亲赴太学论道,著有《春秋左氏传音》(失传)。精通绘画,一说为中国第一位成为画家的皇帝,唐张彦远《历代名画记》目曹髦为中品。', - laiyinger:'来莺儿,是个传说中的人物,正史及古代典籍并无记载。相传来莺儿是东汉歌妓,建安年间洛阳名妓,后爱上曹操的侍卫王图,王图因延误军机而押赴刑场,当时来莺儿奋不顾身以己命换王图一死。新编古装潮剧《曹营恋歌》,秦腔《雀台歌女》讲述了歌女来莺儿与情人王图及曹操三人之间催人泪下的故事。', - caohua:'曹华,东汉末年人物,曹操之女,为汉献帝妃嫔。建安十八年(213年),曹操进为魏公,把曹宪、曹节、曹华三个女儿,一齐都送给汉献帝刘协做了妃子,皆封为夫人,聘以束帛五万匹,年龄尚小者在魏公国待年长而聘。', - zhaoang:'赵昂,字伟章(一作伟璋),天水冀人。汉末时曹操部下。初为羌道令,建安中转参军事徒居州治冀城。建安十八年,马超围冀城多天,城中饥困,凉州刺史韦康不愿百姓再受苦而打算投降,赵昂进劝但不为所纳。后马超背信弃义杀韦康并劫其子赵月为人质,把他送至南郑。欲以此要迫使赵昂为己所用。后与梁宽、赵衢、庞恭、杨阜等结谋为康报仇,并举兵讨伐马超。马超兵败遂弃城,投奔张鲁。得张鲁之援后马超于建安十九年复寇,赵昂与妻子王异坚守祁山三十天至夏侯渊的救兵解围,其子赵月终为马超斩杀。自冀城之难,至于祁山,赵昂出九奇策。', - liuhui:'刘徽(约225年—约295年),汉族,山东滨州邹平市人,魏晋期间伟大的数学家,中国古典数学理论的奠基人之一。在中国数学史上作出了极大的贡献,他的杰作《九章算术注》和《海岛算经》,是中国最宝贵的数学遗产。刘徽思想敏捷,方法灵活,既提倡推理又主张直观。他是中国最早明确主张用逻辑推理的方式来论证数学命题的人。刘徽的一生是为数学刻苦探求的一生。他虽然地位低下,但人格高尚。他不是沽名钓誉的庸人,而是学而不厌的伟人,他给我们中华民族留下了宝贵的财富。2021年5月,国际天文学联合会(IAU)批准中国在嫦娥五号降落地点附近月球地貌的命名,刘徽(liuhui)为八个地貌地名之一。', - zhangfen:'张奋,徐州彭城(今江苏徐州)人。三国时期孙吴将领,辅吴将军张昭的侄子。善于制作攻城器械。在步骘举荐下,担任将军,累迁平州都督,册封乐乡亭侯,病逝于任上。', - dukui:'杜夔,字公良,河南人,擅长音律,聪明过人。管弦等各种乐器,他无所不能。他长期总管歌舞音乐,精心研究,继承复兴了前代古乐,并有所创新。仕于曹操、曹丕之世,以通晓音乐称于世。早年任雅乐郎,汉中平五年(188年),因病离职。州郡的司徒以礼相请,他因时世混乱而奔荆州。荆州牧刘表的儿子刘琮投降曹操后,曹操以杜夔为军谋祭酒 ,参与太乐署之事,令他创制雅乐。魏文帝曹丕黄初年间,任太乐令、协律都尉。', - quanhuijie:'全皇后(244年-301年),吴郡钱塘(今浙江杭州)人,吴废帝孙亮的皇后,全尚之女,母孙恭之女。吴大帝长女全公主的侄孙女。赤乌十三年(250年),因全公主推荐全氏被册为孙亮的太子妃,建兴二年(253年),全氏被立为皇后。太平三年(258年),孙亮被权臣孙綝贬为会稽王,全皇后也一同贬为会稽王夫人。永安三年(260年),全皇后随夫到侯官,孙亮在途中死去,全皇后在侯官居住二十余年,吴亡后返回吴郡,永宁元年(301年)去世。', - dingshangwan:'丁尚涴,又名丁夫人。东汉末年权臣曹操的原配夫人。丁尚涴嫁给曹操时,曹操另有刘夫人,生长子曹昂和清河长公主。后刘夫人早亡,曹昂便由丁尚涴抚养,丁尚涴视其为己出。
              建安二年(公元197年),曹昂随军出征宛城,战死沙场。丁尚涴悲痛欲绝,口出怨言数落曹操,又悲啼不止。曹操恼羞成怒,将其打发回了娘家。不久之后,心生悔意的曹操亲自前往丁家,打算将丁尚涴接回。然而丁尚涴却只是闷头织布。曹操手抚其背,说:“顾我共载归乎!”丁尚涴依旧不理不睬。曹操走到门口,又回过头:“得无尚可邪!”然而依旧得不到回应,只得感叹:“真诀矣。”于是与之和离,并让丁家允许她改嫁,丁家不敢为之。
              丁尚涴去世后,卞夫人请求曹操安葬她,于是葬在许城以南。后来曹操病重,知道自己时日无多,临终前叹道:“我前后行意,于心未曾有所负也。假令死而有灵,子修若问‘我母所在’,我将何辞以答!”', - luyi:'卢弈,游卡桌游《三国杀》中虚构的人物。设定为卢植之女。至情至孝。其人虽体弱多病,然而却天资聪颖,有过目不忘、出口成章之才。先后拜蔡邕、王允等人为师,纳诸家之长融会贯通。又善弈棋,曾与当时国手山子道、王九真、郭凯对弈,不分胜负,一时之间名动京华,被太学征辟为女博士,世人皆称其为“女先生”。董卓之乱后,卢弈随父亲隐居乡野,创办上谷学宫,邀天下士子论道。相传诸葛亮、曹植、荀彧、张昭等人都参加过。各学派在卢弈主持下论道,成为一时佳话。后上谷学宫遭曹魏所忌,卢弈为请求曹叡赦免学宫,与司马懿对无棋之弈。卢弈破指凝血,以血为棋,终胜司马懿半子。但却旧伤复发,局终而陨。', - zhaozhi:'赵直,豫章人,生于公元175年左右,死年不详,字不详。为蜀汉官方占梦者。曾预言蒋琬位极人臣、何祗48岁去世、魏延离死期不远,后果一一应验。', - dongguiren:'董贵人(?—200年),父董承,汉献帝刘协妃嫔之一。董贵人父亲被曹操所杀,自己也受牵连。董贵人虽有身孕,汉献帝数次为她向曹操求情,仍被杀。', - zhujianping: '朱建平(生卒年不详),汉末三国时期沛国(今安徽省)人。精通相术,于街巷之间为人相面,效果非常灵验。三国时,他在街头巷尾给人们看相。曹丕做五官将时,请他看相,朱建平说:将军寿命80,40会有小难,愿您多多保护。 又说曹彪:您居于自己的封国,到57当遭兵灾,要好好提防此事。 结果曹丕40去世,曹彪57岁时,犯了与王凌合谋罪,被赐死。他的妙算,都这么准确,即使是唐举,许负也比不上。时人将他与平原郡相士管公明并称为“朱”、“管”。', - yuanji:'袁氏(生卒年不详),汝南郡汝阳县(今河南商水)人,袁术之女,孙权妃嫔。袁夫人出身世家大族汝南袁氏,其父袁术败亡后,入吴宫拜为夫人,以节操品行着称。', - chengbing:'程秉(生卒年不详),字德枢,汝南南顿(今河南项城西)人。三国时期吴国官员、儒学家。起初跟随郑玄,后来北方荒乱而到交州避难,期间与刘熙考究五经大义,因此通绕五经。后来交趾太守士燮任命程秉为长史。吴大帝孙权听闻程秉的名声,于是以礼征召他,程秉到后,被任命为太子太傅。黄武四年(225年),孙权为太子孙登娶周瑜之女为妃,程秉以太常身份于吴郡迎候,孙权亲身上程秉的船,可见孙权对他的极为礼待。程秉又教诲孙登对婚后相处要尊重儒家礼教。后来因病在任职期间逝世。著有《周易摘》、《尚书驳》、《论语弼》,凡三万余言。', - dc_zhouxuān:'周宣,生卒年不详,字孔和,乐安(治今山东高苑西北)人,擅长解梦,在郡做官时曾为太守解过梦,后又给曹丕解梦,都灵验。官至中郎,死于魏明帝末年。', - xuelingyun:'薛灵芸,东晋王嘉志怪小说《拾遗记》中的人物,魏文帝曹丕的宫人,妙于针工,虽处于深帷之内,不用灯烛之光,裁制立成。凡不是薛灵芸缝制的衣服,文帝一概不穿,宫中号为针神。薛灵芸的故事在正史中虽无记载,却由于许多野史笔记偶尔提及,如《拾遗记》、《太平广记》、《艳异编》等,渐于后世成为中国古代著名美女形象。', - yanghong:'杨弘,东汉末年袁术部将。袁术死后,杨弘等将其众欲归孙策,后庐江太守刘勋截击,转归于勋。', - xielingyu:'谢夫人,会稽山阴(今浙江省绍兴市)人,东汉尚书郎、徐令谢煚之女,吴大帝孙权的原配发妻,又称谢妃。深受孙权宠爱,爱幸有宠。后来孙权为了巩固江东政权,又纳徐氏,欲让谢夫人屈居其下。谢夫人不同意,失志早卒。谢夫人的弟弟是三国著名史学家、武陵太守谢承。豫章太守谢斐与谢夫人同宗同族。', - zerong:'笮融(?—195年),丹杨(治今安徽宣城)人,东汉末年豪强,生性残暴却笃信佛教,为佛教在中国的发展做出了很大贡献。东汉末年投奔徐州刺史陶谦,督管下邳、彭城、广陵三郡运粮。将其中大量物资占为己有累积财力,遂在徐州一带大规模崇佛,修建豪华佛寺,铸造金铜大佛,衣以锦彩,并举行浴佛节,招揽信徒万余人。其崇佛活动奠定了中国大型佛事活动的基础。后又投奔赵昱、薛礼、朱皓并将他们杀害,扬州牧刘繇因此兴兵讨伐笮融。笮融兵败后逃入深山,由于当地山民同样对他恨之入骨,便联手搜捕、杀死笮融,并将他的首级献给刘繇。', - huanfan:'桓范(?~249年),字元则,沛郡龙亢县(今安徽省怀远县龙亢镇)人。三国时期曹魏大臣、文学家、画家。建安末年,担任丞相府掾,联合王象等共同撰写《皇览》。延康元年,担任羽林左监。魏明帝时,历任中领军、尚书,出任征虏将军、东中郎将、兖州刺史等。正始年间,授大司农,为大将军曹爽出谋划策,号称“智囊 ”。高平陵政变(249年)发生后,力劝曹爽挟带皇帝曹芳进入许昌,没有得到采纳,最终被太傅司马懿诛杀。桓范颇有文才,著有《世要论》(《桓范新书》)。善于画画,唐朝张彦远《历代名画记》目为中品。', - sunyu:'孙瑜(177年-215年),字仲异,吴郡富春(今浙江富阳)人,孙坚之弟孙静的次子,孙权的堂兄。官至奋威将军、丹杨太守。孙瑜初以恭义校尉的身份统领士兵,曾跟随周瑜、孙权等人征战,擅于安抚部下、招降纳顺。孙瑜爱读古籍,又请学者马普来为将领官员的子弟讲学,于是东吴开始设立学官。215年,孙瑜去世,时年三十九岁。', - xizheng:'郤正(?-278年),本名郤纂,字令先,司州河南郡偃师县(今河南省偃师市)人,三国蜀汉至西晋时期学者、官员。少好学,广读古籍。弱冠即善写文章,为蜀汉朝廷征为秘书吏,官至秘书令。公元263年(景耀六年),曹魏攻伐蜀汉,后主刘禅投降,郤正为之撰写投降书。后随刘禅前往洛阳,受封关内侯,又得到晋武帝司马炎赏识,任巴西郡太守,公元278年(咸宁四年)去世。郤正为人不重名利,曾作《释讥》,表明自己淡泊之心境;又醉心于文学,共作诗歌、论著、辞赋等近百篇,但多散佚于后世。', - zhangjinyun:'张瑾云,张星彩的妹妹,刘禅的第二任皇后,238年正月立为皇后。景耀六年(263年),蜀汉灭亡,刘禅被俘,此后,受封为安乐公。张皇后也随之成为安乐公夫人,咸熙元年(264年),随刘禅到洛阳。', - duanqiaoxiao:'段巧笑,三国时代魏国魏文帝时的宫人,甚受到魏文帝的宠爱。传说她以原有的化妆品中的米粉和胡粉,再加入葵花子汁,发明了女性化妆用的脂粉。', - ruanji:'阮籍(公元210年~263年),字嗣宗,陈留尉氏(今河南省开封市)人,三国时期魏国诗人、竹林七贤之一。阮瑀之子,门荫入仕,累迁步兵校尉,世称阮步兵。崇奉老庄之学,政治上则采取谨慎避祸的态度。景元四年(公元263年),阮籍去世,享年五十三岁。作为“正始之音”的代表,著有《咏怀八十二首》、《大人先生传》等,其著作收录在《阮籍集》中。', - ganfurenmifuren:'甘夫人,刘备起兵后于沛城娶之为妾。后来,甘夫人随刘备到荆州,生了阿斗(也就是后主刘禅)。223年四月,刘备病死于白帝城,追谥甘夫人为“昭烈皇后”。
              糜夫人,刘备夫人。徐州别驾糜竺之妹。长坂兵败,她怀抱年仅两岁的刘禅在乱军中走散,被赵云发现;但麋夫人因为赵云只有一匹马,不肯上马,在将阿斗托付给赵云后投井而亡。', - sunlingluan:'孙翎鸾,孙坚与妾室丁氏的女儿,孙策的妹妹,孙权、孙尚香的姐姐。孙翎年幼时曾得杜夔点化,窥得音律玄妙,丝竹八音,擅长琵琶,每次弹奏琵琶时,经常引来百鸟,称为奇观。早年孙翎鸾出游,山林巧遇葛玄,葛玄观其面相为吉,特传授修行辟谷之法,可令其身心洗涤,容颜久存。孙翎鸾有恋人名张奋,两人情投意合,可惜造化弄人,张奋病死外域,孙翎鸾倚楼盼归,日复一日、年复一年。后有五彩孔雀自东南而来,绕楼而鸣,其声如慕,孙翎鸾泪染笑靥,与孔雀耳语几句后乘翎而去。', - zhoubuyi:'周不疑(192年—208年),字元直(或作“文直”),零陵重安(今湖南衡阳县)人,刘表别驾刘先的外甥,少有异才,聪明敏达,在十七岁时就著有文论四首。曹冲死后,曹操怀疑曹丕无法驾驭周不疑,于是派人杀了周不疑。', - tianshangyi:'田尚衣,一作陈尚衣,魏文帝曹丕宫中著名宫人。能歌善舞,一时冠绝于世,私以为比之汉宫飞燕也不遑多让。', - malingli:'马伶俐,游卡桌游原创角色,设定上为,马超之女,其身形虽娇小,却继承了马超英勇略带冲动的个性,活泼阳光,调皮伶俐,爱摆弄爆竹烟花一类的小器具,包包里经常放置用五色彩纸包装的小炸弹球。马伶俐从小跟随马超和马云騄学习战斗技巧,战斗力超强,坚强的意志和勇气也得到了提升,同时擅长马术,有一匹可爱的小白马伴随其身边。后马伶俐成年,嫁与刘备之子刘理,获封梁王妃。两人琴瑟相和,极为恩爱,常结伴出游,被人誉为天作之合。', - zhugeruoxue:'诸葛氏(“若雪”为网络小说虚构),诸葛亮的二姐,庞山民之妻。', - zhugemengxue:'诸葛氏(“梦雪”为网络小说虚构),诸葛亮的大姐。', - caoyi:'曹轶,游卡桌游旗下产品《三国杀》原创角色。设定上为曹纯所收养的孙女,从小受到曹纯的教导,在军营中长大,性情坚毅有担当,军事谋略丰富,战斗能力超强。曹轶喜欢美食,特别是甜食,并且擅长制作各种点心。她身边跟随的雪白小老虎是曹纯在她及笄时送的生辰礼物,希望她如小老虎一样,英勇无畏。曹轶与曹婴交好,两人以姐妹相称。曹轶成年后继承祖父衣钵,接手精锐部队“虎豹骑”,成为新的虎豹骑的统领者。', - huzun:'胡遵(?~256年),安定临泾(今甘肃省镇原县)人,三国时期曹魏大臣,官至卫将军,封阴密侯。出身安定胡氏。历任征东将军、征东大将军、卫将军等职。早年由张既征辟。后追随司马懿,参与平定匈奴胡薄居姿职叛乱、抵御诸葛亮北伐、平定公孙渊叛乱。嘉平四年(252年),作为曹魏三征之一的征东将军,主持征讨东吴,被诸葛恪击败。正元元年(255年)参与平定淮南三叛的第二叛毌丘俭、文钦之乱,事后升任卫将军。甘露元年(256年)秋七月己卯去世,追赠车骑将军。', + characterIntro: { + cuimao: "请分别查看「崔琰」和「毛玠」的武将介绍。", + bailingyun: + "柏灵筠,女,是电视剧《大军师司马懿之军师联盟》、《虎啸龙吟》中的主要角色之一,由张钧甯饰演。20岁,是曹丕赏赐司马懿的美人,也是曹丕的眼线,被送入司马府中为妾室。柔弱美貌、心机极深。", + caoxian: + "曹宪(生卒年不详),女,沛国谯县(今安徽省亳州市)人。东汉末年历史人物,汉献帝刘协嫔妃,魏武帝曹操女儿。建安十八年,嫁给汉献帝刘协,受封为贵人。黄初元年(220年),兄弟曹丕称帝后,汉献帝成为山阳公,不知所终。", + zhangjian: + "张臶(136年-240年),字子明,钜鹿人。汉末三国时期隐士、音乐家,精通谶纬之学。张臶生活的年代从东汉一直到曹魏齐王时期,受到朝廷多次征召,一直回避,不愿做官。他活了一百零五岁,是三国时期有可靠记载的最长寿的人之一。", + puyuan: "蒲元是三国时蜀汉杰出的工匠。为诸葛亮造刀三千口,并且制作木牛流马。后来姜维为他写过两部传记《蒲元传》《蒲元别传》。", + guanlu: "管辂(209年-256年),字公明,平原(今山东德州平原县)人。三国时期曹魏术士。年八九岁,便喜仰观星辰。成人后,精通《周易》,善于卜筮、相术,习鸟语,相传每言辄中,出神入化。体性宽大,常以德报怨。正元初,为少府丞。北宋时被追封为平原子。管辂是历史上著名的术士,被后世奉为卜卦观相的祖师。", + gexuan: "葛玄(164年-244年),汉族,吴丹阳郡句容县都乡吉阳里人(今句容市),祖籍山东琅琊,三国著名高道,道教灵宝派祖师。字孝先,号仙翁,被尊称为“葛天师”。道教尊为葛仙翁,又称太极仙翁,与张道陵、许逊、萨守坚共为四大天师。为汉下邳僮侯葛艾后裔,祖葛矩,安平太守,黄门郎;从祖葛弥,豫章第五郡太守。父葛焉,字德儒,州主簿,山阴令,散骑常侍,大尚书。随左慈学道,得《太清丹经》、《黄帝九鼎神丹经》、《金液丹经》等道经。曾采药海山,吴嘉禾二年(233年),在閤皂山修道建庵,筑坛立炉,修炼九转金丹。喜好遨游山川,去过括苍山、南岳山、罗浮山。编撰《灵宝经诰》,精研上清、灵宝等道家真经,并嘱弟子世世箓传。", + wulan: "吴兰(?~218年),青州(今山东潍坊市)人。东汉末年将领。初为益州牧刘璋部将,后来归降刘备。汉中之战中,与马超、张飞各领一军,驻扎于下辩。建安二十三年,为曹操将领曹洪、张郃所败,退回汉中。途中,为阴平氐族首领强端所杀。", + leitong: + "雷铜(?-218年),阴平(今甘肃文县)人,氐族,东汉末年益州名将。本属益州牧刘璋麾下。刘备攻取益州后,归刘备麾下。参加汉中之战,为魏将张郃所杀。", + huaman: "花鬘,古典戏曲《龙凤巾》(一名《化外奇缘》)中的人物,身份为三国时期南蛮王孟获与祝融夫人的女儿,关索的夫人之一。在关于关三小姐·关银屏的民间传说中,其名字为“花中秀”,与关索其他几位夫人鲍三娘、王桃、王悦都被关索之姐关银屏编入自己的女兵营中。花鬘在《三国志》,《三国演义》均未有提及,只是戏曲中的虚构人物。其形象并非一般君主家中闺秀,而是与其母祝融相似,是一个可以披甲上阵,善于刀枪作战的女武将。戏曲中在诸葛亮平定南蛮时,花鬘曾与关索作战,失败被俘,两人互生爱意,南蛮王孟获降服后二人成婚。近些年,花鬘接连在各类三国题材的游戏中登场,更广被人知晓。", + wangshuang: + "王双(?-228年),三国时期曹魏将领。蜀汉建兴六年(228年)冬,诸葛亮出散关,攻陈仓,后粮尽而退。王双率领骑兵追击蜀军,但在与蜀军的交战中被击败,王双也被蜀军所斩。在《三国演义》中,王双字子全,是陇西郡狄道县(今甘肃临洮县)人,有万夫不当之勇。在诸葛亮北伐期间,被魏延所斩。", + wenyang: + "文俶(238年—291年),一作文淑,字次骞,小名阿鸯,世称文鸯,谯郡(今安徽亳州市)人。魏末晋初名将,曹魏扬州刺史文钦之子。骁勇善战,依附大将军曹爽,效忠于王室。司马师废黜皇帝曹芳后,随父联合毌丘俭于淮南起兵勤王。兵败之后,向南投奔吴国。诸葛诞发动淮南叛乱,奉命率军驰援。双方发生内讧,父亲为诸葛诞所害,遂降于司马昭,封关内侯。西晋建立后,任平虏护军。咸宁三年(277年),拜平西将军、都督凉秦雍州三州军事,大破鲜卑首领秃发树机能,名震天下,迁使持节、护东夷校尉、监辽东军事。八王之乱中,为诸葛诞外孙、东安王司马繇所诬杀,惨遭灭族,时年五十四岁。", + liubian: + "刘辩(176年-190年3月6日),是汉灵帝刘宏与何皇后的嫡长子。刘辩在灵帝驾崩后继位为帝,史称少帝,由于年幼,实权掌握在临朝称制的母亲何太后和母舅大将军何进手中。少帝在位时期,东汉政权已经名存实亡,他即位后不久即遭遇以何进为首的外戚集团和以十常侍为首的内廷宦官集团这两大敌对政治集团的火并,被迫出宫,回宫后又受制于以“勤王”为名进京的凉州军阀董卓,终于被废为弘农王,成为东汉唯一被废黜的皇帝,其同父异母弟陈留王刘协继位为帝,是为汉献帝。被废黜一年之后,刘辩在董卓胁迫下自尽,时年仅十五岁(一说十八岁),其弟献帝追谥他为怀王。中国古代的史书中称刘辩为皇子辩、少帝和弘农王等。因为在位不逾年,传统上称东汉共十二帝,刘辩与东汉另一位少帝刘懿都不在其中,亦皆无本纪;不过,现代史学界也有观点承认两位少帝均是汉朝皇帝,则刘辩为东汉第十三位皇帝。", + guozhao: + "郭照,电视剧《军师联盟》中的女主角之一,由唐艺昕饰演。原型为文德皇后郭氏(字女王),魏国皇后,张春华的义妹,深爱曹丕,替甄宓抚育曹叡,因甄宓之死被曹叡记恨,曹丕死后,成为皇太后,被曹叡逼上死路。自尽身亡。", + fanyufeng: + "樊夫人,东汉末年人物,昔桂阳太守赵范寡嫂。赵云随刘备平定江南四郡后,刘备以赵云为桂阳太守。赵范居心叵测,要将自己的嫂嫂樊氏嫁给赵云,但遭到赵云的拒绝。后来,赵范逃走,樊氏也下落不明。2001年,应日本日中青少年文化中心成立50周年之邀,北京京剧院赴日进行40场巡回演出,这次访日的剧目都不同程度地进行了加工改编,以符合日本观众的需求。《取桂阳》是根据老本重新排演的,叶金援饰赵云,王怡饰樊玉凤。剧中的樊玉凤成为文武双全的巾帼英雄,被赵云收降,后来在《龙凤呈祥》中也参与堵截东吴的追兵。", + ruanyu: "阮瑀(约165—212年),字元瑜,陈留尉氏(今河南开封市尉氏县)人,是东汉末年文学家,建安七子之一。阮瑀所作章表书记很出色,当时军国书檄文字,多为阮瑀与陈琳所拟。名作有《为曹公作书与孙权》。诗有《驾出北郭门行》,描写孤儿受后母虐待的苦难遭遇,比较生动形象。年轻时曾受学于蔡邕,蔡邕称他为“奇才”。后徙为丞相仓曹掾属。诗歌语言朴素,往往能反映出一般的社会问题。阮瑀的音乐修养颇高,他的儿子阮籍,孙子阮咸皆当时名人,位列“竹林七贤”,妙于音律。明人辑有《阮元瑜集》。", + yangwan: + "杨氏(婉字出自小说,史书无记载),生卒年不详,东汉末年凉州人。早年嫁于东汉前将军、槐里侯马腾之子马超,追随马超转战并州、雍州、凉州,为马超生下子嗣。公元212年,马超联军在渭南战败后,杨婉随马超逃亡凉州,很快马超反攻吞并陇上诸郡县。公元213年,杨婉为了帮助马超,结识王异,了解马超这些投降部下。可惜被王异蛊惑,遭致马超大败。自己和孩子都被赵衢、梁宽杀害。", + zhouyi: "周夷,游卡桌游旗下产品《三国杀》自行杜撰的人物。设定为周瑜的妹妹,和周瑜一同征战。", + caojinyu: + "金乡公主,本姓曹氏,名字不详,沛国谯县(今安徽省亳州市)人。魏武帝曹操的女儿,母为杜夫人。适婚的时候,嫁给曹操的养子何晏。高平陵之变,何晏作为大将军曹爽的党羽,遭到太傅司马懿处死。在何晏母亲尹夫人苦苦哀求下,何晏的儿子得以保全。", + wufan: "吴范(?-226年),字文则,会稽上虞(今浙江绍兴上虞区)人。三国时期孙吴官员,擅长术数。与刘惇、赵达、严武、曹不兴、皇象、宋寿和郑妪合称“吴中八绝”。吴范以推算天象节气和观察气候闻名于郡中。孙权起于东南,他委身事奉,每推算灾祥多应验,遂显名。孙权委以骑都尉,领太史令。初,孙权为将军时,他曾说江南有王气。及孙权立为吴王,论功行封,欲以为都亭侯,但因不愿将其术要诀告知孙权,为权所怨恨,被除名。黄武中,病死。", + caomao: "曹髦(241年11月15日-260年6月2日),字彦士,沛国谯县(今安徽省亳州市)人,魏文帝曹丕之孙,东海王曹霖之子,曹魏第四位皇帝(254年11月1日-260年6月2日)。正始二年(241年),生于东海王宫,自幼聪明好学,才慧早成,正始五年(244年),封为高贵乡公,嘉平六年(254年),大将军司马师废除齐王曹芳后,拥立为帝,年号正元,曹髦文才武略,崇拜少康,不满司马氏专权秉政,甘露五年(260年),亲自讨伐司马昭,为太子舍人成济所弑,年仅十九岁,以王礼葬于洛阳西北。曹髦擅长诗文,创制了九言诗,传世文章有《伤魂赋并序》《颜子论》等。爱好儒学,亲赴太学论道,著有《春秋左氏传音》(失传)。精通绘画,一说为中国第一位成为画家的皇帝,唐张彦远《历代名画记》目曹髦为中品。", + laiyinger: + "来莺儿,是个传说中的人物,正史及古代典籍并无记载。相传来莺儿是东汉歌妓,建安年间洛阳名妓,后爱上曹操的侍卫王图,王图因延误军机而押赴刑场,当时来莺儿奋不顾身以己命换王图一死。新编古装潮剧《曹营恋歌》,秦腔《雀台歌女》讲述了歌女来莺儿与情人王图及曹操三人之间催人泪下的故事。", + caohua: "曹华,东汉末年人物,曹操之女,为汉献帝妃嫔。建安十八年(213年),曹操进为魏公,把曹宪、曹节、曹华三个女儿,一齐都送给汉献帝刘协做了妃子,皆封为夫人,聘以束帛五万匹,年龄尚小者在魏公国待年长而聘。", + zhaoang: + "赵昂,字伟章(一作伟璋),天水冀人。汉末时曹操部下。初为羌道令,建安中转参军事徒居州治冀城。建安十八年,马超围冀城多天,城中饥困,凉州刺史韦康不愿百姓再受苦而打算投降,赵昂进劝但不为所纳。后马超背信弃义杀韦康并劫其子赵月为人质,把他送至南郑。欲以此要迫使赵昂为己所用。后与梁宽、赵衢、庞恭、杨阜等结谋为康报仇,并举兵讨伐马超。马超兵败遂弃城,投奔张鲁。得张鲁之援后马超于建安十九年复寇,赵昂与妻子王异坚守祁山三十天至夏侯渊的救兵解围,其子赵月终为马超斩杀。自冀城之难,至于祁山,赵昂出九奇策。", + liuhui: "刘徽(约225年—约295年),汉族,山东滨州邹平市人,魏晋期间伟大的数学家,中国古典数学理论的奠基人之一。在中国数学史上作出了极大的贡献,他的杰作《九章算术注》和《海岛算经》,是中国最宝贵的数学遗产。刘徽思想敏捷,方法灵活,既提倡推理又主张直观。他是中国最早明确主张用逻辑推理的方式来论证数学命题的人。刘徽的一生是为数学刻苦探求的一生。他虽然地位低下,但人格高尚。他不是沽名钓誉的庸人,而是学而不厌的伟人,他给我们中华民族留下了宝贵的财富。2021年5月,国际天文学联合会(IAU)批准中国在嫦娥五号降落地点附近月球地貌的命名,刘徽(liuhui)为八个地貌地名之一。", + zhangfen: + "张奋,徐州彭城(今江苏徐州)人。三国时期孙吴将领,辅吴将军张昭的侄子。善于制作攻城器械。在步骘举荐下,担任将军,累迁平州都督,册封乐乡亭侯,病逝于任上。", + dukui: "杜夔,字公良,河南人,擅长音律,聪明过人。管弦等各种乐器,他无所不能。他长期总管歌舞音乐,精心研究,继承复兴了前代古乐,并有所创新。仕于曹操、曹丕之世,以通晓音乐称于世。早年任雅乐郎,汉中平五年(188年),因病离职。州郡的司徒以礼相请,他因时世混乱而奔荆州。荆州牧刘表的儿子刘琮投降曹操后,曹操以杜夔为军谋祭酒 ,参与太乐署之事,令他创制雅乐。魏文帝曹丕黄初年间,任太乐令、协律都尉。", + quanhuijie: + "全皇后(244年-301年),吴郡钱塘(今浙江杭州)人,吴废帝孙亮的皇后,全尚之女,母孙恭之女。吴大帝长女全公主的侄孙女。赤乌十三年(250年),因全公主推荐全氏被册为孙亮的太子妃,建兴二年(253年),全氏被立为皇后。太平三年(258年),孙亮被权臣孙綝贬为会稽王,全皇后也一同贬为会稽王夫人。永安三年(260年),全皇后随夫到侯官,孙亮在途中死去,全皇后在侯官居住二十余年,吴亡后返回吴郡,永宁元年(301年)去世。", + dingshangwan: + "丁尚涴,又名丁夫人。东汉末年权臣曹操的原配夫人。丁尚涴嫁给曹操时,曹操另有刘夫人,生长子曹昂和清河长公主。后刘夫人早亡,曹昂便由丁尚涴抚养,丁尚涴视其为己出。
              建安二年(公元197年),曹昂随军出征宛城,战死沙场。丁尚涴悲痛欲绝,口出怨言数落曹操,又悲啼不止。曹操恼羞成怒,将其打发回了娘家。不久之后,心生悔意的曹操亲自前往丁家,打算将丁尚涴接回。然而丁尚涴却只是闷头织布。曹操手抚其背,说:“顾我共载归乎!”丁尚涴依旧不理不睬。曹操走到门口,又回过头:“得无尚可邪!”然而依旧得不到回应,只得感叹:“真诀矣。”于是与之和离,并让丁家允许她改嫁,丁家不敢为之。
              丁尚涴去世后,卞夫人请求曹操安葬她,于是葬在许城以南。后来曹操病重,知道自己时日无多,临终前叹道:“我前后行意,于心未曾有所负也。假令死而有灵,子修若问‘我母所在’,我将何辞以答!”", + luyi: "卢弈,游卡桌游《三国杀》中虚构的人物。设定为卢植之女。至情至孝。其人虽体弱多病,然而却天资聪颖,有过目不忘、出口成章之才。先后拜蔡邕、王允等人为师,纳诸家之长融会贯通。又善弈棋,曾与当时国手山子道、王九真、郭凯对弈,不分胜负,一时之间名动京华,被太学征辟为女博士,世人皆称其为“女先生”。董卓之乱后,卢弈随父亲隐居乡野,创办上谷学宫,邀天下士子论道。相传诸葛亮、曹植、荀彧、张昭等人都参加过。各学派在卢弈主持下论道,成为一时佳话。后上谷学宫遭曹魏所忌,卢弈为请求曹叡赦免学宫,与司马懿对无棋之弈。卢弈破指凝血,以血为棋,终胜司马懿半子。但却旧伤复发,局终而陨。", + zhaozhi: + "赵直,豫章人,生于公元175年左右,死年不详,字不详。为蜀汉官方占梦者。曾预言蒋琬位极人臣、何祗48岁去世、魏延离死期不远,后果一一应验。", + dongguiren: + "董贵人(?—200年),父董承,汉献帝刘协妃嫔之一。董贵人父亲被曹操所杀,自己也受牵连。董贵人虽有身孕,汉献帝数次为她向曹操求情,仍被杀。", + zhujianping: + "朱建平(生卒年不详),汉末三国时期沛国(今安徽省)人。精通相术,于街巷之间为人相面,效果非常灵验。三国时,他在街头巷尾给人们看相。曹丕做五官将时,请他看相,朱建平说:将军寿命80,40会有小难,愿您多多保护。 又说曹彪:您居于自己的封国,到57当遭兵灾,要好好提防此事。 结果曹丕40去世,曹彪57岁时,犯了与王凌合谋罪,被赐死。他的妙算,都这么准确,即使是唐举,许负也比不上。时人将他与平原郡相士管公明并称为“朱”、“管”。", + yuanji: "袁氏(生卒年不详),汝南郡汝阳县(今河南商水)人,袁术之女,孙权妃嫔。袁夫人出身世家大族汝南袁氏,其父袁术败亡后,入吴宫拜为夫人,以节操品行着称。", + chengbing: + "程秉(生卒年不详),字德枢,汝南南顿(今河南项城西)人。三国时期吴国官员、儒学家。起初跟随郑玄,后来北方荒乱而到交州避难,期间与刘熙考究五经大义,因此通绕五经。后来交趾太守士燮任命程秉为长史。吴大帝孙权听闻程秉的名声,于是以礼征召他,程秉到后,被任命为太子太傅。黄武四年(225年),孙权为太子孙登娶周瑜之女为妃,程秉以太常身份于吴郡迎候,孙权亲身上程秉的船,可见孙权对他的极为礼待。程秉又教诲孙登对婚后相处要尊重儒家礼教。后来因病在任职期间逝世。著有《周易摘》、《尚书驳》、《论语弼》,凡三万余言。", + dc_zhouxuān: + "周宣,生卒年不详,字孔和,乐安(治今山东高苑西北)人,擅长解梦,在郡做官时曾为太守解过梦,后又给曹丕解梦,都灵验。官至中郎,死于魏明帝末年。", + xuelingyun: + "薛灵芸,东晋王嘉志怪小说《拾遗记》中的人物,魏文帝曹丕的宫人,妙于针工,虽处于深帷之内,不用灯烛之光,裁制立成。凡不是薛灵芸缝制的衣服,文帝一概不穿,宫中号为针神。薛灵芸的故事在正史中虽无记载,却由于许多野史笔记偶尔提及,如《拾遗记》、《太平广记》、《艳异编》等,渐于后世成为中国古代著名美女形象。", + yanghong: + "杨弘,东汉末年袁术部将。袁术死后,杨弘等将其众欲归孙策,后庐江太守刘勋截击,转归于勋。", + xielingyu: + "谢夫人,会稽山阴(今浙江省绍兴市)人,东汉尚书郎、徐令谢煚之女,吴大帝孙权的原配发妻,又称谢妃。深受孙权宠爱,爱幸有宠。后来孙权为了巩固江东政权,又纳徐氏,欲让谢夫人屈居其下。谢夫人不同意,失志早卒。谢夫人的弟弟是三国著名史学家、武陵太守谢承。豫章太守谢斐与谢夫人同宗同族。", + zerong: "笮融(?—195年),丹杨(治今安徽宣城)人,东汉末年豪强,生性残暴却笃信佛教,为佛教在中国的发展做出了很大贡献。东汉末年投奔徐州刺史陶谦,督管下邳、彭城、广陵三郡运粮。将其中大量物资占为己有累积财力,遂在徐州一带大规模崇佛,修建豪华佛寺,铸造金铜大佛,衣以锦彩,并举行浴佛节,招揽信徒万余人。其崇佛活动奠定了中国大型佛事活动的基础。后又投奔赵昱、薛礼、朱皓并将他们杀害,扬州牧刘繇因此兴兵讨伐笮融。笮融兵败后逃入深山,由于当地山民同样对他恨之入骨,便联手搜捕、杀死笮融,并将他的首级献给刘繇。", + huanfan: + "桓范(?~249年),字元则,沛郡龙亢县(今安徽省怀远县龙亢镇)人。三国时期曹魏大臣、文学家、画家。建安末年,担任丞相府掾,联合王象等共同撰写《皇览》。延康元年,担任羽林左监。魏明帝时,历任中领军、尚书,出任征虏将军、东中郎将、兖州刺史等。正始年间,授大司农,为大将军曹爽出谋划策,号称“智囊 ”。高平陵政变(249年)发生后,力劝曹爽挟带皇帝曹芳进入许昌,没有得到采纳,最终被太傅司马懿诛杀。桓范颇有文才,著有《世要论》(《桓范新书》)。善于画画,唐朝张彦远《历代名画记》目为中品。", + sunyu: "孙瑜(177年-215年),字仲异,吴郡富春(今浙江富阳)人,孙坚之弟孙静的次子,孙权的堂兄。官至奋威将军、丹杨太守。孙瑜初以恭义校尉的身份统领士兵,曾跟随周瑜、孙权等人征战,擅于安抚部下、招降纳顺。孙瑜爱读古籍,又请学者马普来为将领官员的子弟讲学,于是东吴开始设立学官。215年,孙瑜去世,时年三十九岁。", + xizheng: + "郤正(?-278年),本名郤纂,字令先,司州河南郡偃师县(今河南省偃师市)人,三国蜀汉至西晋时期学者、官员。少好学,广读古籍。弱冠即善写文章,为蜀汉朝廷征为秘书吏,官至秘书令。公元263年(景耀六年),曹魏攻伐蜀汉,后主刘禅投降,郤正为之撰写投降书。后随刘禅前往洛阳,受封关内侯,又得到晋武帝司马炎赏识,任巴西郡太守,公元278年(咸宁四年)去世。郤正为人不重名利,曾作《释讥》,表明自己淡泊之心境;又醉心于文学,共作诗歌、论著、辞赋等近百篇,但多散佚于后世。", + zhangjinyun: + "张瑾云,张星彩的妹妹,刘禅的第二任皇后,238年正月立为皇后。景耀六年(263年),蜀汉灭亡,刘禅被俘,此后,受封为安乐公。张皇后也随之成为安乐公夫人,咸熙元年(264年),随刘禅到洛阳。", + duanqiaoxiao: + "段巧笑,三国时代魏国魏文帝时的宫人,甚受到魏文帝的宠爱。传说她以原有的化妆品中的米粉和胡粉,再加入葵花子汁,发明了女性化妆用的脂粉。", + ruanji: "阮籍(公元210年~263年),字嗣宗,陈留尉氏(今河南省开封市)人,三国时期魏国诗人、竹林七贤之一。阮瑀之子,门荫入仕,累迁步兵校尉,世称阮步兵。崇奉老庄之学,政治上则采取谨慎避祸的态度。景元四年(公元263年),阮籍去世,享年五十三岁。作为“正始之音”的代表,著有《咏怀八十二首》、《大人先生传》等,其著作收录在《阮籍集》中。", + ganfurenmifuren: + "甘夫人,刘备起兵后于沛城娶之为妾。后来,甘夫人随刘备到荆州,生了阿斗(也就是后主刘禅)。223年四月,刘备病死于白帝城,追谥甘夫人为“昭烈皇后”。
              糜夫人,刘备夫人。徐州别驾糜竺之妹。长坂兵败,她怀抱年仅两岁的刘禅在乱军中走散,被赵云发现;但麋夫人因为赵云只有一匹马,不肯上马,在将阿斗托付给赵云后投井而亡。", + sunlingluan: + "孙翎鸾,孙坚与妾室丁氏的女儿,孙策的妹妹,孙权、孙尚香的姐姐。孙翎年幼时曾得杜夔点化,窥得音律玄妙,丝竹八音,擅长琵琶,每次弹奏琵琶时,经常引来百鸟,称为奇观。早年孙翎鸾出游,山林巧遇葛玄,葛玄观其面相为吉,特传授修行辟谷之法,可令其身心洗涤,容颜久存。孙翎鸾有恋人名张奋,两人情投意合,可惜造化弄人,张奋病死外域,孙翎鸾倚楼盼归,日复一日、年复一年。后有五彩孔雀自东南而来,绕楼而鸣,其声如慕,孙翎鸾泪染笑靥,与孔雀耳语几句后乘翎而去。", + zhoubuyi: + "周不疑(192年—208年),字元直(或作“文直”),零陵重安(今湖南衡阳县)人,刘表别驾刘先的外甥,少有异才,聪明敏达,在十七岁时就著有文论四首。曹冲死后,曹操怀疑曹丕无法驾驭周不疑,于是派人杀了周不疑。", + tianshangyi: + "田尚衣,一作陈尚衣,魏文帝曹丕宫中著名宫人。能歌善舞,一时冠绝于世,私以为比之汉宫飞燕也不遑多让。", + malingli: + "马伶俐,游卡桌游原创角色,设定上为,马超之女,其身形虽娇小,却继承了马超英勇略带冲动的个性,活泼阳光,调皮伶俐,爱摆弄爆竹烟花一类的小器具,包包里经常放置用五色彩纸包装的小炸弹球。马伶俐从小跟随马超和马云騄学习战斗技巧,战斗力超强,坚强的意志和勇气也得到了提升,同时擅长马术,有一匹可爱的小白马伴随其身边。后马伶俐成年,嫁与刘备之子刘理,获封梁王妃。两人琴瑟相和,极为恩爱,常结伴出游,被人誉为天作之合。", + zhugeruoxue: "诸葛氏(“若雪”为网络小说虚构),诸葛亮的二姐,庞山民之妻。", + zhugemengxue: "诸葛氏(“梦雪”为网络小说虚构),诸葛亮的大姐。", + caoyi: "曹轶,游卡桌游旗下产品《三国杀》原创角色。设定上为曹纯所收养的孙女,从小受到曹纯的教导,在军营中长大,性情坚毅有担当,军事谋略丰富,战斗能力超强。曹轶喜欢美食,特别是甜食,并且擅长制作各种点心。她身边跟随的雪白小老虎是曹纯在她及笄时送的生辰礼物,希望她如小老虎一样,英勇无畏。曹轶与曹婴交好,两人以姐妹相称。曹轶成年后继承祖父衣钵,接手精锐部队“虎豹骑”,成为新的虎豹骑的统领者。", + huzun: "胡遵(?~256年),安定临泾(今甘肃省镇原县)人,三国时期曹魏大臣,官至卫将军,封阴密侯。出身安定胡氏。历任征东将军、征东大将军、卫将军等职。早年由张既征辟。后追随司马懿,参与平定匈奴胡薄居姿职叛乱、抵御诸葛亮北伐、平定公孙渊叛乱。嘉平四年(252年),作为曹魏三征之一的征东将军,主持征讨东吴,被诸葛恪击败。正元元年(255年)参与平定淮南三叛的第二叛毌丘俭、文钦之乱,事后升任卫将军。甘露元年(256年)秋七月己卯去世,追赠车骑将军。", }, - characterTitle:{ + characterTitle: { // wulan:'#b对决限定武将', // leitong:'#b对决限定武将', }, - perfectPair:{}, - characterFilter:{ + perfectPair: {}, + characterFilter: { // leitong:function(mode){ // return mode!='identity'&&mode!='guozhan'; // }, @@ -14528,687 +18759,964 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // return mode!='identity'&&mode!='guozhan'; // }, }, - dynamicTranslate:{ - xinlvli:function(player){ - var str='每回合限一次'; - if(player.storage.choujue) str+='(自己的回合内则改为限两次)'; - str+=',当你造成'; - if(player.storage.beishui) str+='或受到'; - str+='伤害后,你可选择:1,若你的体力值大于你的手牌数,你摸X张牌;2,若你的手牌数大于你的体力值且你已受伤,你回复X点体力(X为你的手牌数与体力值之差)。'; + dynamicTranslate: { + xinlvli: function (player) { + var str = "每回合限一次"; + if (player.storage.choujue) str += "(自己的回合内则改为限两次)"; + str += ",当你造成"; + if (player.storage.beishui) str += "或受到"; + str += + "伤害后,你可选择:1,若你的体力值大于你的手牌数,你摸X张牌;2,若你的手牌数大于你的体力值且你已受伤,你回复X点体力(X为你的手牌数与体力值之差)。"; return str; }, - lvli:function(player){ - var str='每名角色的回合限一次'; - if(player.storage.choujue) str+='(自己的回合内则改为限两次)'; - str+=',你可以声明一个基本牌或普通锦囊牌的牌名,有随机概率视为使用之(装备区里的牌数越多,成功概率越大)'; - if(player.storage.beishui) str+='。当你受到伤害后,你也可以以此法使用一张牌。'; + lvli: function (player) { + var str = "每名角色的回合限一次"; + if (player.storage.choujue) str += "(自己的回合内则改为限两次)"; + str += + ",你可以声明一个基本牌或普通锦囊牌的牌名,有随机概率视为使用之(装备区里的牌数越多,成功概率越大)"; + if (player.storage.beishui) str += "。当你受到伤害后,你也可以以此法使用一张牌。"; return str; }, - rezhongjian:function(player){ - return '出牌阶段限'+(player.hasSkill('recaishi2')?'两':'一')+'次,你可以选择一名本回合内未选择过的角色。你令其获得一项效果直至你的下回合开始:①其下次造成伤害后弃置两张牌,然后你摸一张牌。②其下次受到伤害后摸两张牌,然后你摸一张牌。' + rezhongjian: function (player) { + return ( + "出牌阶段限" + + (player.hasSkill("recaishi2") ? "两" : "一") + + "次,你可以选择一名本回合内未选择过的角色。你令其获得一项效果直至你的下回合开始:①其下次造成伤害后弃置两张牌,然后你摸一张牌。②其下次受到伤害后摸两张牌,然后你摸一张牌。" + ); }, - bazhan:function(player){ - if(player.storage.bazhan) return '转换技,出牌阶段限一次,阴:你可以将至多两张手牌交给一名其他角色。阳:你可以获得一名其他角色的至多两张手牌。若以此法移动的牌包含【酒】或♥牌,则你可令得到此牌的角色执行一项:①回复1点体力。②复原武将牌。'; + bazhan: function (player) { + if (player.storage.bazhan) + return '转换技,出牌阶段限一次,阴:你可以将至多两张手牌交给一名其他角色。阳:你可以获得一名其他角色的至多两张手牌。若以此法移动的牌包含【酒】或♥牌,则你可令得到此牌的角色执行一项:①回复1点体力。②复原武将牌。'; return '转换技,出牌阶段限一次,阴:你可以将至多两张手牌交给一名其他角色。阳:你可以获得一名其他角色的至多两张手牌。若以此法移动的牌包含【酒】或♥牌,则你可令得到此牌的角色执行一项:①回复1点体力。②复原武将牌。'; }, - zhiren:function(player){ - return '当你于'+(player.hasSkill('yaner_zhiren')?'一':'你的')+'回合内使用第一张非转化牌时,你可依次执行以下选项中的前X项:①卜算X。②可弃置场上的一张装备牌和延时锦囊牌。③回复1点体力。④摸三张牌。(X为此牌的名称的字数)'; + zhiren: function (player) { + return ( + "当你于" + + (player.hasSkill("yaner_zhiren") ? "一" : "你的") + + "回合内使用第一张非转化牌时,你可依次执行以下选项中的前X项:①卜算X。②可弃置场上的一张装备牌和延时锦囊牌。③回复1点体力。④摸三张牌。(X为此牌的名称的字数)" + ); }, - yuqi:function(player){ - var info=lib.skill.yuqi.getInfo(player); - return '每回合限两次。当有角色受到伤害后,若你至其的距离不大于'+info[0]+',则你可以观看牌堆顶的'+info[1]+'张牌。你将其中至多'+info[2]+'张牌交给受伤角色,然后可以获得剩余牌中的至多'+info[3]+'张牌,并将其余牌以原顺序放回牌堆顶。(所有具有颜色的数字至多为5)'; + yuqi: function (player) { + var info = lib.skill.yuqi.getInfo(player); + return ( + "每回合限两次。当有角色受到伤害后,若你至其的距离不大于" + + info[0] + + ",则你可以观看牌堆顶的" + + info[1] + + "张牌。你将其中至多" + + info[2] + + "张牌交给受伤角色,然后可以获得剩余牌中的至多" + + info[3] + + "张牌,并将其余牌以原顺序放回牌堆顶。(所有具有颜色的数字至多为5)" + ); }, - caiyi:function(player){ - var current=player.storage.caiyi,list=player.storage.caiyi_info||[[],[]]; - var str='转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项。'; - var list1=['⒈回复X点体力。','⒉摸X张牌。','⒊复原武将牌。','⒋随机执行一个已经移除过的阴选项;'],list2=['⒈受到X点伤害。','⒉弃置X张牌。','⒊翻面并横置。','⒋随机执行一个已经移除过的阳选项。'],str1='阴:',str2='阳:'; - for(var i=0;i<4;i++){ - var clip1=list1[i],clip2=list2[i]; - if(list[0].includes(i)) clip1=(''+clip1+''); - if(list[1].includes(i)) clip2=(''+clip2+''); - str1+=clip1; - str2+=clip2; + caiyi: function (player) { + var current = player.storage.caiyi, + list = player.storage.caiyi_info || [[], []]; + var str = "转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项。"; + var list1 = [ + "⒈回复X点体力。", + "⒉摸X张牌。", + "⒊复原武将牌。", + "⒋随机执行一个已经移除过的阴选项;", + ], + list2 = [ + "⒈受到X点伤害。", + "⒉弃置X张牌。", + "⒊翻面并横置。", + "⒋随机执行一个已经移除过的阳选项。", + ], + str1 = "阴:", + str2 = "阳:"; + for (var i = 0; i < 4; i++) { + var clip1 = list1[i], + clip2 = list2[i]; + if (list[0].includes(i)) + clip1 = '' + clip1 + ""; + if (list[1].includes(i)) + clip2 = '' + clip2 + ""; + str1 += clip1; + str2 += clip2; } - if(current) str2=(''+str2+''); - else str1=(''+str1+''); - return str+str1+str2+'(X为该阴阳态剩余选项的数量)。'; + if (current) str2 = '' + str2 + ""; + else str1 = '' + str1 + ""; + return str + str1 + str2 + "(X为该阴阳态剩余选项的数量)。"; }, - dchuishu:function(player){ - var list=lib.skill.dchuishu.getList(player); - return '摸牌阶段结束时,你可以摸['+list[0]+']张牌。若如此做:你弃置['+list[1]+']张手牌,且当你于本回合内弃置第['+list[2]+']+1张牌后,你从弃牌堆中随机获得〖慧淑〗第三个括号数字张非基本牌。'; + dchuishu: function (player) { + var list = lib.skill.dchuishu.getList(player); + return ( + "摸牌阶段结束时,你可以摸[" + + list[0] + + "]张牌。若如此做:你弃置[" + + list[1] + + "]张手牌,且当你于本回合内弃置第[" + + list[2] + + "]+1张牌后,你从弃牌堆中随机获得〖慧淑〗第三个括号数字张非基本牌。" + ); }, - dcshoutan:function(player){ - if(player.storage.dcshoutan) return '转换技。出牌阶段限一次,阴:你可以弃置一张不为黑色的手牌。阳:你可以弃置一张黑色手牌。'; + dcshoutan: function (player) { + if (player.storage.dcshoutan) + return '转换技。出牌阶段限一次,阴:你可以弃置一张不为黑色的手牌。阳:你可以弃置一张黑色手牌。'; return '转换技。出牌阶段限一次,阴:你可以弃置一张不为黑色的手牌。阳:你可以弃置一张黑色手牌。'; }, - dcluochong:function(player){ - return '一轮游戏开始时,你可以弃置任意名角色区域里的共计至多['+(4-player.countMark('dcluochong'))+']张牌,然后若你以此法弃置了一名角色的至少三张牌,则你方括号内的数字-1。'; + dcluochong: function (player) { + return ( + "一轮游戏开始时,你可以弃置任意名角色区域里的共计至多[" + + (4 - player.countMark("dcluochong")) + + "]张牌,然后若你以此法弃置了一名角色的至少三张牌,则你方括号内的数字-1。" + ); }, - dczhangcai:function(player){ - return '当你使用或打出'+(player.hasSkill('dczhangcai_all')?'':'点数为8的')+'牌时,你可以摸X张牌(X为你手牌区里'+(player.hasSkill('dczhangcai_all')?'与此牌点数相同':'点数为8')+'的牌数且至少为1)。'; + dczhangcai: function (player) { + return ( + "当你使用或打出" + + (player.hasSkill("dczhangcai_all") ? "" : "点数为8的") + + "牌时,你可以摸X张牌(X为你手牌区里" + + (player.hasSkill("dczhangcai_all") ? "与此牌点数相同" : "点数为8") + + "的牌数且至少为1)。" + ); }, - dcsbmengmou:function(player){ - var storage=player.storage.dcsbmengmou; - var str='转换技,每回合每项各限一次,当你得到其他角色的牌后,或其他角色得到你的牌后:'; - if(!storage) str+=''; - str+='阴,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力;'; - if(!storage) str+=''; - if(storage) str+=''; - str+='阳,你可令该角色打出至多X张【杀】,然后其失去Y点体力。'; - if(storage) str+=''; - str+='(X为你的体力上限,Y为X-其打出【杀】数)'; + dcsbmengmou: function (player) { + var storage = player.storage.dcsbmengmou; + var str = "转换技,每回合每项各限一次,当你得到其他角色的牌后,或其他角色得到你的牌后:"; + if (!storage) str += ''; + str += "阴,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力;"; + if (!storage) str += ""; + if (storage) str += ''; + str += "阳,你可令该角色打出至多X张【杀】,然后其失去Y点体力。"; + if (storage) str += ""; + str += "(X为你的体力上限,Y为X-其打出【杀】数)"; return str; }, - dcsbyingmou:function(player){ - var storage=player.storage.dcsbyingmou; - var str='转换技,每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色:'; - if(!storage) str+=''; - str+='阴,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】;'; - if(!storage) str+=''; - if(storage) str+=''; - str+='阳,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。'; - if(storage) str+=''; + dcsbyingmou: function (player) { + var storage = player.storage.dcsbyingmou; + var str = "转换技,每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色:"; + if (!storage) str += ''; + str += "阴,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】;"; + if (!storage) str += ""; + if (storage) str += ''; + str += + "阳,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。"; + if (storage) str += ""; return str; }, - dcsbquanmou:function(player){ - if(player.storage.dcsbquanmou) return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。阴:当你于本阶段内下次对其造成伤害时,取消之;阳:当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。'; + dcsbquanmou: function (player) { + if (player.storage.dcsbquanmou) + return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。阴:当你于本阶段内下次对其造成伤害时,取消之;阳:当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。'; return '转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。阴:当你于本阶段内下次对其造成伤害时,取消之;阳:当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。'; - } + }, }, - characterReplace:{ - wenyang:['wenyang','db_wenyang','diy_wenyang'], - gexuan:['gexuan','tw_gexuan'], - panshu:['panshu','re_panshu'], - yangwan:['yangwan','sp_yangwan'], - sunyi:['re_sunyi','sunyi','tw_sunyi'], - fengfangnv:['fengfangnv','re_fengfangnv'], - luotong:['dc_luotong','luotong'], - dc_wangchang:['dc_wangchang','tw_wangchang'], - guozhao:['guozhao','xin_guozhao','jsrg_guozhao'], - dingshangwan:['dingshangwan','ol_dingshangwan'], - qinghegongzhu:['qinghegongzhu','dc_qinghegongzhu'], - caofang:['caofang','jsrg_caofang'], - caomao:['caomao','mb_caomao'], + characterReplace: { + wenyang: ["wenyang", "db_wenyang", "diy_wenyang"], + gexuan: ["gexuan", "tw_gexuan"], + panshu: ["panshu", "re_panshu"], + yangwan: ["yangwan", "sp_yangwan"], + sunyi: ["re_sunyi", "sunyi", "tw_sunyi"], + fengfangnv: ["fengfangnv", "re_fengfangnv"], + luotong: ["dc_luotong", "luotong"], + dc_wangchang: ["dc_wangchang", "tw_wangchang"], + guozhao: ["guozhao", "xin_guozhao", "jsrg_guozhao"], + dingshangwan: ["dingshangwan", "ol_dingshangwan"], + qinghegongzhu: ["qinghegongzhu", "dc_qinghegongzhu"], + caofang: ["caofang", "jsrg_caofang"], + caomao: ["caomao", "mb_caomao"], + sp_zhenji: ["sp_zhenji", "jsrg_zhenji"], }, - translate:{ - puyuan:'蒲元', - pytianjiang:'天匠', - pytianjiang_info:'游戏开始时,你随机获得两张不同副类别的装备牌,并置入你的装备区。出牌阶段,你可以将装备区的牌移动至其他角色的装备区(可替换原装备)。若你以此法移动了〖铸刃〗的衍生装备,你摸两张牌。', - pytianjiang_move:'天匠', - pyzhuren:'铸刃', - pyzhuren_info:'出牌阶段限一次,你可以弃置一张手牌。根据此牌的花色点数,你有一定概率打造成功并获得一张武器牌(若打造失败或武器已有则改为摸一张【杀】,花色决定武器名称,点数决定成功率)。此武器牌进入弃牌堆时,将其移出游戏。', - pyzhuren_destroy:'铸刃', - pyzhuren_heart:'红缎枪', - pyzhuren_heart_info:'每回合限一次,当你使用【杀】造成伤害后,你可以进行判定,若结果为:红色,你回复1点体力;黑色:你摸两张牌。', - pyzhuren_diamond:'烈淬刀', - pyzhuren_diamond_info:'每回合限两次,当你使用【杀】对目标角色造成伤害时,你可以弃置一张牌,令此伤害+1。你使用【杀】的次数上限+1。', - pyzhuren_club:'水波剑', - pyzhuren_club_info:'每回合限两次,当你使用普通锦囊牌或【杀】时,你可以为此牌增加一个目标。当你失去装备区里的【水波剑】后,你回复1点体力。', - pyzhuren_spade:'混毒弯匕', - pyzhuren_spade_info:'当你使用【杀】指定目标后,你可令其失去X点体力(X为此技能本回合内发动过的次数且至多为5)。', - pyzhuren_shandian:'天雷刃', - pyzhuren_shandian_info:'当你使用【杀】指定目标后,可令其进行判定,若结果为:黑桃,其受到3点雷属性伤害;梅花,其受到1点雷属性伤害,你回复1点体力并摸一张牌。', - guanlu:'管辂', - tuiyan:'推演', - tuiyan_info:'出牌阶段开始时,你可以观看牌堆顶的三张牌。', - busuan:'卜算', - busuan_info:'出牌阶段限一次,你可以选择一名其他角色,然后选择至多两张不同的卡牌名称(限基本牌或锦囊牌)。该角色下次摸牌阶段摸牌时,改为从牌堆或弃牌堆中获得你选择的牌。', - busuan_angelbeats:'卜算', - mingjie:'命戒', - mingjie_info:'结束阶段,你可以摸一张牌,若此牌为红色,你可以重复此流程直到摸到黑色牌或摸到第三张牌。当你以此法摸到黑色牌时,若你的体力值大于1,则你失去1点体力。', - gexuan:'葛玄', - gxlianhua:'炼化', - gxlianhua_info:'你的回合外,每当有其他角色受到伤害后,你获得一个“丹血”标记(该角色与你阵营一致时为红色,不一致为黑色,此颜色对所有玩家均不可见)直到你的准备阶段开始。准备阶段,根据你获得的“丹血”标记的数量和颜色,你从牌堆/弃牌堆中获得相应的牌以及相应技能直到回合结束。3枚或以下:〖英姿〗和【桃】;超过3枚且红色“丹血”较多:〖观星〗和【无中生有】;超过3枚且黑色“丹血”较多:〖直言〗和【顺手牵羊】;超过3枚且红色和黑色一样多:【杀】、【决斗】和〖攻心〗。', - zhafu:'札符', - zhafu_info:'限定技,出牌阶段,你可以选择一名其他角色,令其获得一枚「札」。有「札」的角色弃牌阶段开始时,若其手牌数大于1,其移去「札」并选择保留一张手牌,然后将其余的手牌交给你。', - leitong:'雷铜', - kuiji:'溃击', - kuiji_info:'出牌阶段限一次。你可以将一张黑色基本牌当作【兵粮寸断】置于你的判定区,然后摸一张牌。若如此做,你可以对体力值最多的一名对手造成2点伤害。对手因此进入濒死状态时,你或队友体力值最少的一方回复1点体力。', - kuiji_info_identity:'出牌阶段限一次。你可以将一张黑色基本牌当做【兵粮寸断】置于你的判定区,摸一张牌,然后你可以对体力值最多的一名其他角色造成2点伤害。该角色因此进入濒死状态时,你可令一名除其外体力值最少的角色回复1点体力。', - kuiji_info_guozhan:'出牌阶段限一次。你可以将一张黑色基本牌当做【兵粮寸断】置于你的判定区,摸一张牌,然后你可以对体力值最多的一名其他角色造成2点伤害。该角色因此进入濒死状态时,你可令一名除其外体力值最少的角色回复1点体力。', - wulan:'吴兰', - wlcuorui:'挫锐', - wlcuorui_info:'出牌阶段开始时,你可以弃置你或队友区域里的一张牌。若如此做,你选择一项:1.弃置对手装备区里至多两张与此牌颜色相同的牌;2.展示对手的共计两张手牌,然后获得其中与此牌颜色相同的牌。', - wlcuorui_info_identity:'出牌阶段开始时,你可以弃置一名你至其的距离不大于1的角色区域里的一张牌,然后你选择一项:1.弃置另一名其他角色装备区里至多两张与此牌颜色相同的牌;2.展示另一名其他角色的至多两张手牌,然后获得其中与此牌颜色相同的牌。', - wlcuorui_info_guozhan:'出牌阶段开始时,你可以弃置一名你至其的距离不大于1的角色区域里的一张牌,然后你选择一项:1.弃置另一名其他角色装备区里至多两张与此牌颜色相同的牌;2.展示另一名其他角色的至多两张手牌,然后获得其中与此牌颜色相同的牌。', - huaman:'花鬘', - manyi:'蛮裔', - manyi_info:'锁定技,【南蛮入侵】对你无效。', - manyi_info_single_normal:'锁定技,【南蛮入侵】对你无效。当你登场时,你可以视为使用一张【南蛮入侵】。', - mansi_viewas:'蛮嗣', - mansi:'蛮嗣', - mansi_info:'出牌阶段限一次,你可以将所有手牌当做【南蛮入侵】使用;当有角色受到【南蛮入侵】的伤害后,你摸一张牌。', - souying:'薮影', - souying_info:'每回合限一次,当你对其他角色(或其他角色对你)使用【杀】或普通锦囊牌指定唯一目标后,若此牌不是本回合你对其(或其对你)使用的第一张【杀】或普通锦囊牌,你可以弃置一张牌,获得此牌对应的所有实体牌(或令此牌对你无效)。', - zhanyuan:'战缘', - zhanyuan_info:'觉醒技,准备阶段,若你已因蛮嗣累计获得超过七张牌,你加1点体力上限并回复1点体力,并可以选择一名男性角色,你与其获得技能〖系力〗,然后你失去技能〖蛮嗣〗。', - hmxili:'系力', - hmxili_info:'每回合限一次,你的回合外,当其他拥有【系力】技能的角色在其回合内对没有【系力】技能的角色造成伤害时,你可以弃置一张牌,令此伤害+1,然后你与其各摸两张牌。', - wangshuang:'王双', - spzhuilie:'追猎', - spzhuilie2:'追猎', - spzhuilie_info:'锁定技,你使用【杀】无距离限制;当你使用【杀】指定目标后,若其不在你的攻击范围内,此【杀】不计入使用次数限制且你判定。若判定结果为武器牌或坐骑牌,此【杀】的伤害基数改为X(X为其体力值)。否则你失去1点体力。', - wenyang:'文鸯', - xinlvli:'膂力', - xinlvli_info:'每回合限一次,当你造成伤害后,你可选择:1,若你的体力值大于你的手牌数,你摸X张牌;2,若你的手牌数大于你的体力值且你已受伤,你回复X点体力(X为你的手牌数与体力值之差)。', - lvli:'膂力', - lvli4:'膂力', - lvli5:'膂力', - lvli_info:'每名角色的回合限一次,你可以声明一个基本牌或普通锦囊牌的牌名,有随机概率视为使用之(装备区里的牌数越多,成功概率越大)。', - choujue:'仇决', - choujue_info:'觉醒技,一名角色的回合结束时,若你的手牌数和体力值相差3或更多,你减1点体力上限并获得技能〖背水〗,然后将〖膂力〗改为“在自己的回合时每回合限两次”。', - beishui:'背水', - beishui_info:'觉醒技,准备阶段,若你的手牌数或体力值小于2,你减1点体力上限并获得技能〖清剿〗,然后将〖膂力〗改为受到伤害后也可以发动。', - qingjiao:'清剿', - qingjiao_info:'出牌阶段开始时,你可以弃置所有手牌,然后从牌堆或弃牌堆中随机获得八张牌名各不相同且副类别不同的牌。若如此做,结束阶段,你弃置所有牌。', - re_liuzan:'留赞', - refenyin:'奋音', - refenyin_info:'锁定技,你的回合内,当一张牌进入弃牌堆后,若本回合内没有过与此牌花色相同的卡牌进入过弃牌堆,则你摸一张牌。', - liji:'力激', - liji_info:'出牌阶段限X次,你可以弃置一张牌并对一名其他角色造成1点伤害。(X为本回合内进入过弃牌堆的卡牌数除以8,若场上人数小于5则改为除以4,向下取整)', - liubian:'刘辩', - shiyuan:'诗怨', - shiyuan_info:'每回合每项限一次,当你成为其他角色使用牌的目标后:①若其体力值大于你,你摸三张牌。②若其体力值等于你,你摸两张牌。③若其体力值小于你,你摸一张牌。', - dushi:'毒逝', - dushi_info:'锁定技,你处于濒死状态时,其他角色不能对你使用【桃】。你死亡时,你选择一名其他角色获得〖毒逝〗。', - yuwei:'余威', - yuwei_info:'主公技,锁定技,其他群雄角色的回合内,你将〖诗怨〗改为“每回合每项限两次”。', - re_xinxianying:'新杀辛宪英', - re_xinxianying_prefix:'新杀', - rezhongjian:'忠鉴', - rezhongjian2:'忠鉴', - rezhongjian_info:'出牌阶段限一次,你可以选择一名本回合内未选择过的角色。你令其获得一项效果直至你的下回合开始:①其下次造成伤害后弃置两张牌,然后你摸一张牌。②其下次受到伤害后摸两张牌,然后你摸一张牌。', - recaishi:'才识', - recaishi3:'才识', - recaishi_info:'摸牌阶段结束时,若你于本阶段内因摸牌而获得的所有的牌:花色均相同,你将〖忠鉴〗于本回合内改为“出牌阶段限两次”。不均相同,你可回复1点体力。若如此做,你本回合内不能对自己使用牌。', - guozhao:'郭照', - pianchong:'偏宠', - pianchong2:'偏宠', - pianchong_info:'摸牌阶段开始时,你可放弃摸牌。若如此做,你从牌堆中获得一张红色牌和一张黑色牌。然后你选择一种颜色。你的下回合开始前,当你失去该颜色的一张牌后,你从牌堆中获得另一种颜色的一张牌。', - zunwei:'尊位', - zunwei_backup:'尊位', - zunwei_info:"出牌阶段限一次,你可选择本局游戏内未选择过的一项:①若你已受伤,则你可以选择一名体力值大于你的其他角色,你将体力值回复至X(X为你的体力上限与其体力值中的较小值)②选择一名手牌数大于你的其他角色,你将手牌数摸至与其相同(至多摸五张)③选择一名装备区内牌数大于你的其他角色。你令X=1。若你装备区内的('equip'+X)栏为空,则你使用牌堆中的一张副类别为('equip'+X),且能对自己使用的装备牌。你令X+1。若X不大于5,且你装备区内的牌数仍小于目标角色,则你重复此流程。", - fanyufeng:'樊玉凤', - bazhan:'把盏', - bazhan_info:'转换技,出牌阶段限一次,阴:你可以将至多两张手牌交给一名其他角色。阳:你可以获得一名其他角色的至多两张手牌。若以此法移动的牌包含【酒】或♥牌,则你可令得到牌的角色执行一项:①回复1点体力。②复原武将牌。', - jiaoying:'醮影', - jiaoying2:'醮影', - jiaoying3:'醮影', - jiaoying3_draw:'醮影', - jiaoying_info:'锁定技,其他角色得到你的手牌后,该角色本回合不能使用或打出与此牌颜色相同的牌。然后此回合结束时,若其本回合没有再使用牌,你令一名角色将手牌摸至五张。', - ruanyu:'阮瑀', - xingzuo:'兴作', - xingzuo2:'兴作', - xingzuo_info:'出牌阶段开始时,你可观看牌堆底的三张牌并用任意张手牌替换其中等量的牌。若如此做,结束阶段,你可令一名有手牌的角色用所有手牌替换牌堆底的三张牌。若其因此法失去的牌多于三张,则你失去1点体力。', - miaoxian:'妙弦', - miaoxian_info:'若你的手牌中仅有一张黑色牌,你可将此牌当作任意一张普通锦囊牌使用(每回合限一次);若你的手牌中仅有一张红色牌,你使用此牌时摸一张牌。', - yangwan:'杨婉', - youyan:'诱言', - youyan_info:'出牌阶段/弃牌阶段各限一次。当有牌进入弃牌堆后,若其中有你不因使用或打出而失去的牌,你可以从牌堆中获得你本次失去的牌中没有的花色的牌各一张。', - zhuihuan:'追还', - zhuihuan2:'追还', - zhuihuan2_new:'追还', - zhuihuan_info:'结束阶段开始时,你可以选择一名角色(对其他角色不可见)。记录所有对该角色造成过伤害的角色。该角色的下个准备阶段开始时停止记录,且所有记录过的角色:若体力值大于该角色,则受到其造成的2点伤害;若体力值小于等于该角色,则随机弃置两张手牌。', - re_panshu:'潘淑', - zhiren:'织纴', - zhiren_info:'当你于你的回合内使用第一张非转化牌时,你可依次执行以下选项中的前X项:①卜算X。②可弃置场上的一张装备牌和延时锦囊牌。③回复1点体力。④摸三张牌。(X为此牌的名称的字数)', - yaner:'燕尔', - yaner_info:'每回合限一次。当有其他角色于其出牌阶段内失去手牌后,若其没有手牌,则你可以与其各摸两张牌。若其以此法摸得的两张牌类型相同,则其回复1点体力。若你以此法摸得的两张牌类型相同,则你将〖织纴〗中的“你的回合内”改为“一回合内”直至你下回合开始。', - zhouyi:'周夷', - zhukou:'逐寇', - zhukou_info:'①当你于一名角色的出牌阶段第一次造成伤害后,你可以摸X张牌(X为本回合你已使用的牌数)。②你的结束阶段,若你本回合没有造成伤害,你可以对两名其他角色各造成1点伤害。', - mengqing:'氓情', - mengqing_info:'觉醒技。准备阶段,若场上已受伤的角色数大于你的体力值,你加3点体力上限并回复3点体力,失去〖逐寇〗,获得〖玉殒〗。', - yuyun:'玉殒', - yuyun_info:'锁定技,出牌阶段开始时,你失去1点体力或体力上限(不能减至1以下),然后选择X+1项(X为你已损失的体力值):①摸两张牌;②对一名其他角色造成1点伤害,然后本回合对其使用【杀】无距离和次数限制;③本回合的手牌上限视为无限;④获得一名其他角色区域内的一张牌;⑤令一名其他角色将手牌摸至体力上限(最多摸至5)。', - caojinyu:'曹金玉', - yuqi:'隅泣', - yuqi_info:'每回合限两次。当有角色受到伤害后,若你至其的距离不大于0,则你可以观看牌堆顶的3张牌。你将其中至多1张牌交给受伤角色,然后可以获得剩余牌中的至多1张牌,并将其余牌以原顺序放回牌堆顶。(所有具有颜色的数字至多为5)', - shanshen:'善身', - shanshen_info:'当有角色死亡时,你可令你的〖隅泣〗中的一个具有颜色的数字+2。然后若你未对该角色造成过伤害,则你回复1点体力。', - xianjing:'娴静', - xianjing_info:'准备阶段,你可令你的〖隅泣〗中的一个具有颜色的数字+1。若你的体力值等于体力上限,则你可以重复一次此流程。', - re_sunyi:'孙翊', - syjiqiao:'激峭', - syjiqiao_info:'出牌阶段开始时,你可将牌堆顶的X张牌置于你的武将牌上(X为你的体力上限)。当你于此出牌阶段内使用的牌结算结束后,你可以获得其中的一张牌,然后若剩余牌中红色牌和黑色牌的数量:不相等,你失去1点体力;相等,你回复1点体力。出牌阶段结束时,你将这些牌置入弃牌堆。', - syxiongyi:'凶疑', - syxiongyi_info:'限定技。当你处于濒死状态时,若剩余武将牌堆中:有“徐氏”,则你可以将体力值回复至3点,并将此武将牌替换为“徐氏”;没有“徐氏”,则你可以将体力值回复至1点并获得〖魂姿〗。', - re_zhangbao:'新杀张宝', - re_zhangbao_prefix:'新杀', - xinzhoufu:'咒缚', - xinzhoufu2:'咒缚', - xinzhoufu_info:'出牌阶段限一次。你可以将一张手牌置于一名其他角色的武将牌上并称为“咒”,且当其判定时,将其“咒”作为判定牌。', - xinyingbing:'影兵', - xinyingbing_info:'锁定技。每回合每名角色限一次,当你使用牌指定有“咒”的角色为目标后,你摸两张牌。', - wufan:'吴范', - tianyun:'天运', - tianyun_info:'①游戏的第一个回合开始前,你从牌堆中获得手牌区内没有的花色的各一张牌。②一名角色的回合开始时,若其座位号等于游戏轮数,则你可观看牌堆顶的X张牌并以任意顺序置于牌堆顶或牌堆底。若你将所有的牌均置于了牌堆底,则你可以令一名角色摸X张牌,然后失去1点体力。(X为你手牌中包含的花色数)', - wfyuyan:'预言', - wfyuyan_info:'一轮游戏开始时,你选择一名角色(对其他角色不可见):当第一次有角色于本轮内进入濒死状态时,若其是你选择的角色,则你获得〖奋音〗直到你的回合结束;当第一次有角色于本轮内造成伤害后,若其是你选择的角色,则你摸两张牌。', - re_fengfangnv:'冯妤', - tiqi:'涕泣', - tiqi_info:'其他角色的摸牌阶段结束时/被跳过时,若其于本阶段内因摸牌而得到的牌数X不等于2,则你可以摸|X-2|张牌,并可令其本回合的手牌上限±|X-2|。', - baoshu:'宝梳', - baoshu_info:'①准备阶段,你可选择Y名角色,这些角色重置武将牌并获得(X-Y+1)个“梳”(X为你的体力上限,Y∈[1, X])。②一名角色的摸牌阶段开始时,若其有“梳”,则其本阶段的额定摸牌数+Z且移去Z个“梳”(Z为其“梳”的数量)。', - dc_luotong:'骆统', - renzheng:'仁政', - renzheng_info:'锁定技。当有伤害被防止时,或伤害值发生过减少的伤害事件结算结束后,你摸两张牌。', - jinjian:'进谏', - jinjian_info:'①当你造成伤害时,你可令此伤害+1,然后你本回合内下一次造成的伤害-1且不触发〖进谏①〗。②当你受到伤害时,你可令此伤害-1。然后你于本回合内下一次受到的伤害+1且不触发〖进谏②〗。', - caomao:'曹髦', - qianlong:'潜龙', - qianlong_info:'当你受到伤害后,你可以展示牌堆顶的三张牌并获得其中的至多X张牌(X为你已损失的体力值),然后将剩余的牌置于牌堆底。', - fensi:'忿肆', - fensi_info:'锁定技。准备阶段,你须选择一名体力值不小于你的角色并对其造成1点伤害,然后若你选择的角色不为你自己,则其视为对你使用一张【杀】。', - juetao:'决讨', - juetao_info:'限定技。出牌阶段开始时,若你的体力值为1,则你可以选择一名其他角色。你展示牌堆底的一张牌,若此牌能被你使用,则你使用此牌并重复此流程直到出现不可使用的牌或其死亡(你与其以外的角色不是此牌的合法目标)。', - zhushi:'助势', - zhushi_info:'主公技。每回合限一次,其他魏势力角色于回合内回复体力时,其可令你摸一张牌。', - laiyinger:'来莺儿', - xiaowu:'绡舞', - xiaowu_info:'出牌阶段限一次,你可以选择任意名座位连续且包含你的上家/下家的角色。这些角色依次选择一项:⒈令你摸一张牌;⒉其摸一张牌。然后若选择选项一的角色数大于选项二的角色数,则你获得一枚“沙”;若选择选项二的角色数大于选项一的角色数,则你对这些角色依次造成1点伤害。', - huaping:'化萍', - huaping_info:'限定技。①一名其他角色死亡时,你可获得其当前拥有的所有不带有「Charlotte」标签的技能,然后你失去〖绡舞〗,移去所有“沙”并摸等量的牌。②当你死亡时,你可令一名其他角色获得〖沙舞〗和你的所有“沙”。', - shawu:'沙舞', - shawu_info:'当你使用【杀】指定目标后,你可选择一项:⒈弃置两张手牌;⒉移去一枚“沙”并摸两张牌。然后你对目标角色造成1点伤害。', - dc_huangzu:'黄祖', - dcjinggong:'精弓', - dcjinggong_info:'你可以将一张装备牌当做无距离限制的【杀】使用。当你声明使用此【杀】后,你将此杀的伤害值基数改为X(X为你至此【杀】第一个目标角色的距离且至多为5)。', - dcxiaojuan:'骁隽', - dcxiaojuan_info:'当你使用牌指定其他角色为唯一目标后,你可以弃置其一半的手牌(向下取整)。若这些牌中有与你使用牌花色相同的牌,则你弃置一张手牌。', - dc_liuyu:'新杀刘虞', - dc_liuyu_prefix:'新杀', - dcsuifu:'绥抚', - dcsuifu_info:'其他角色的结束阶段开始时,若你和一号位本回合内累计受到过的伤害值大于1,则你可以将该角色的所有手牌置于牌堆顶,然后视为使用一张【五谷丰登】。', - dcpijing:'辟境', - dcpijing_info:'结束阶段开始时,你可以选择任意名角色。你令所有未选择的角色失去〖自牧〗,然后你和这些角色获得〖自牧〗。', - dczimu:'自牧', - dczimu_info:'锁定技。当你受到伤害后,你令所有拥有〖自牧〗的角色各摸一张牌,然后你失去〖自牧〗。', - caohua:'曹华', - caiyi:'彩翼', - caiyi_info:'转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项。阴:⒈回复X点体力。⒉摸X张牌,⒊复原武将牌。⒋随机执行一个已经移除过的阴选项;阳:⒈受到X点伤害。⒉弃置X张牌。⒊翻面并横置。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。', - guili:'归离', - guili_info:'你的第一个回合开始时,你须选择一名其他角色。该角色每轮的第一个回合结束后,若其本回合内未造成过伤害,则你执行一个额外的回合。', - zhaoang:'赵昂', - dczhongjie:'忠节', - dczhongjie_info:'每轮限一次。当有角色因失去体力而进入濒死状态时,你可令其回复1点体力并摸一张牌。', - dcsushou:'夙守', - dcsushou_tag:'对方手牌', - dcsushou_info:'一名角色的出牌阶段开始时,若其手牌数为全场唯一最多,则你可以失去1点体力并摸X张牌。然后若该角色不是你,则你可以观看其一半的手牌(向下取整),且用至多X张手牌替换其中等量的牌。(X为你已损失的体力值)', - dc_wangchang:'王昶', - dckaiji:'开济', - dckaiji_info:'转换技。出牌阶段限一次,你可以:阴:摸X张牌;阳:弃置至多X张牌(X为你的体力上限且至多为5)。', - dcpingxi:'平袭', - dcpingxi_info:'结束阶段,若X大于0,则你可以选择至多X名其他角色(X为本回合内因弃置而进入弃牌堆的牌数)。你依次弃置这些角色的各一张牌,然后视为对这些角色使用一张【杀】。', - liuhui:'刘徽', - dcgeyuan:'割圆', - dcgeyuan_info:'锁定技。①游戏开始时,你将从A至K的所有整数排列为一个环形链表,称为“圆环之理”。②当有一张牌进入弃牌堆后,若此牌的点数在“圆环之理”内,且“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你将此牌的点数记录进“圆环之弧”;然后若“圆环之弧”与“圆环之理”长度相同,则你从“圆环之理”中移除“圆环之弧”记录的第一个和最后一个数字A和B(当“圆环之理”长度不大于3时则不移除),清空“圆环之弧”,获得场上和牌堆中所有点数为A和B的牌。', - dcjieshu:'解术', - dcjieshu_info:'锁定技。①所有点数不在“圆环之理”中的牌不计入你的手牌上限。②当你使用牌时,若“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你摸一张牌。', - dcgusuan:'股算', - dcgusuan_info:'觉醒技。一名角色的回合结束时,若你的“圆环之理”长度为3,则你减1点体力上限并修改〖割圆〗。', - dcgeyuan_magica:'割圆·改', - dcgeyuan_magica_info:'锁定技。当有一张牌进入弃牌堆后,若此牌的点数在“圆环之理”内,且“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你将此牌的点数记录进“圆环之弧”;然后若“圆环之弧”与“圆环之理”长度相同,则你清空“圆环之弧”并选择至多三名角色,这些角色中的第一名角色摸三张牌,第二名角色弃置四张牌,第三名角色将其手牌与牌堆底的五张牌交换。', - zhangfen:'张奋', - dcwanglu:'望橹', - dcwanglu_info:'锁定技。准备阶段开始时,若你的装备区内:有【大攻车】,则你获得一个额外的出牌阶段;没有【大攻车】,则你将一张【大攻车】置入装备区。', - dcxianzhu:'陷筑', - dcxianzhu_info:'当你造成渠道为【杀】伤害后,你可以为你装备区内的【大攻车】选择一项强化(每张【大攻车】最多被强化五次):⒈通过【大攻车】使用【杀】无视距离和防具;⒉通过此【大攻车】使用的【杀】可以额外选择1个目标(可叠加);⒊通过此【大攻车】使用的【杀】造成伤害后的弃置牌数+1(可叠加)。', - dcchaixie:'拆械', - dcchaixie_info:'锁定技。当你的【大攻车】被销毁后,你摸X张牌(X为此【大攻车】被强化过的次数)。', - dagongche:'大攻车', - dagongche_skill:'大攻车', - dagongche_info:'出牌阶段开始时,你可以视为使用一张【杀】,且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其一张牌。若此【大攻车】未被强化,则其他角色无法弃置你装备区内的【大攻车】。当此牌离开你的装备区后,销毁之。', - dukui:'杜夔', - dcfanyin:'泛音', - dcfanyin_info:'出牌阶段开始时,你可以亮出牌堆中点数最小的一张牌。然后你选择一项,并可以亮出一张点数为此牌二倍的牌且重复此流程:⒈使用此牌(无距离限制);⒉你于本回合内使用的下一张基本牌或普通锦囊牌选择目标后,可以增加一个目标。', - dcpeiqi:'配器', - dcpeiqi_info:'当你受到伤害后,你可以移动场上的一张牌。然后若场上所有角色均在彼此的攻击范围内,则你可以再移动场上的一张牌。', - quanhuijie:'全惠解', - dchuishu:'慧淑', - dchuishu_info:'摸牌阶段结束时,你可以摸[3]张牌。若如此做:你弃置[1]张手牌,且当你于本回合内弃置第[2]+1张牌后,你从弃牌堆中随机获得〖慧淑〗第三个括号数字张非基本牌。', - dcyishu:'易数', - dcyishu_info:'锁定技。当你不因出牌阶段而失去牌后,你同时令{〖慧淑〗的中括号内最小的一个数字+2}且{〖慧淑〗的中括号内最大的一个数字-1}。', - dcligong:'离宫', - dcligong_info:'觉醒技。准备阶段,若〖慧淑〗的中括号内有不小于5的数字,则你加1点体力上限,回复1点体力并失去〖易数〗。系统随机检索四张吴势力的女性武将牌,然后你选择一项:⒈摸三张牌。⒉失去〖慧淑〗,然后获得这些武将牌上的任意两个非Charlotte技能。', - dingshangwan:'丁尚涴', - dcfengyan:'讽言', - dcfengyan_info:'出牌阶段每项各限一次。你可以:⒈令一名体力值不大于你的其他角色交给你一张手牌。⒉视为对一名手牌数不大于你的角色使用一张【杀】(无距离和次数限制)。', - dcfudao:'抚悼', - dcfudao_info:'游戏开始时,你选择一名其他角色,称为“继子”角色。当你或“继子”每回合首次使用牌指定对方为目标后,你与其各摸两张牌。当有角色杀死你或“继子”后,该角色称为“决裂”角色。当你或“继子”对“决裂”造成伤害时,此伤害+1。当你成为“决裂”角色使用牌的目标后,其本回合内不能再使用牌。', - luyi:'卢弈', - dcyaoyi:'邀弈', - dcyaoyi_info:'锁定技。①游戏开始时,你令所有存活且未拥有转换技的角色获得〖手谈〗。②你发动〖手谈〗时无需弃置牌,且无次数限制。③所有拥有转换技的角色不能使用牌指定其他拥有转换技且双方所有转换技状态均相同的角色为目标。', - dcfuxue:'复学', - dcfuxue_info:'①准备阶段,你可以从弃牌堆中选择获得至多X张不因使用而进入弃牌堆的牌。②结束阶段,若你的手牌区中没有因〖复学①〗得到的牌,则你摸X张牌(X为你的体力值)。', - dcshoutan:'手谈', - dcshoutan_info:'转换技。出牌阶段限一次,阴:你可以弃置一张不为黑色的手牌。阳:你可以弃置一张黑色手牌。', - dc_liuye:'刘晔', - dcpoyuan:'破垣', - dcpoyuan_info:'游戏开始时或准备阶段开始时,若你的装备区内:没有【霹雳投石车】,则你可以将一张【霹雳投石车】置入装备区;有【霹雳投石车】,则你可以弃置一名其他角色至多两张牌。', - dchuace:'画策', - dchuace_info:'出牌阶段限一次。你可以将一张手牌当做上一轮内未被使用过的普通锦囊牌使用。', - pilitoushiche:'霹雳投石车', - pilitoushiche_info:'锁定技。①你于回合内使用基本牌无距离限制,且当你于回合内使用基本牌时,你令此牌的牌面数值+1。②当你于回合外使用或打出基本牌时,你摸一张牌。③当此牌离开你的装备区时,销毁之。', - zhaozhi:'赵直', - dctongguan:'统观', - dctongguan_info:'一名角色的第一个回合开始时,你为其选择一项属性(每个属性至多选两次,且仅对你可见)。', - dcmengjie:'梦解', - dcmengjie_info:'一名角色的回合结束时,若其本回合完成了其〖统观〗属性,你执行对应效果:
            • 「武勇」造成伤害:对一名其他角色造成1点伤害;
            • 「刚硬」回复体力,或于得到牌后手牌数大于体力值:令一名角色回复1点体力;
            • 「多谋」于摸牌阶段外摸牌:摸两张牌;
            • 「果决」弃置或获得其他角色的牌:弃置一名角色区域内至多两张牌;
            • 「仁智」交给其他角色牌:令一名其他角色将手牌补至体力上限(至多摸五张)。', - dctongguan_wuyong:'武勇', - dctongguan_wuyong_info:'任务目标:造成伤害。', - dctongguan_gangying:'刚硬', - dctongguan_gangying_info:'任务目标:回复体力,或于得到牌后手牌数大于体力值。', - dctongguan_duomou:'多谋', - dctongguan_duomou_info:'任务目标:于摸牌阶段外摸牌。', - dctongguan_guojue:'果决', - dctongguan_guojue_info:'任务目标:弃置或获得其他角色的牌。', - dctongguan_renzhi:'仁智', - dctongguan_renzhi_info:'任务目标:交给其他角色牌。', - zhujianping:'朱建平', - olddcxiangmian:'相面', - olddcxiangmian_info:'其他角色的结束阶段,你可以判定。然后你不能再对其发动此技能,其获得以下效果:当其使用第X张结果的花色的牌后(X为结果的点数),其失去等同于其体力值的体力。', - dcxiangmian:'相面', - dcxiangmian_info:'出牌阶段限一次。你可以令一名其他角色判定,然后你不能再对其发动此技能,其获得以下效果:当其使用结果的花色的牌后,或当其使用X张牌后(X为结果的点数),其失去等同于其体力值的体力。', - dctianji:'天机', - dctianji_info:'锁定技。当判定牌进入弃牌堆后,你从牌堆随机获得分别与该牌类型、花色和点数相同的牌各一张。', - yuanji:'袁姬', - dcmengchi:'蒙斥', - dcmengchi_info:'锁定技。若你未于当前回合得到过牌:你不能使用牌;当你横置前,取消之;当你受到无属性伤害后,回复1点体力。', - dcfangdu:'芳妒', - dcfangdu_info:'锁定技。当你于回合外受到伤害后,若此次伤害为你于本回合受到的:第一次无属性伤害,你回复1点体力;第一次属性伤害,你随机获得伤害来源的一张牌。', - dcjiexing:'节行', - dcjiexing_info:'当你受到伤害后、失去体力后或回复体力后,你可以摸一张牌,且此牌不计入本回合的手牌上限。', - dongguiren:'董贵人', - dclianzhi:'连枝', - dclianzhi_info:'①游戏开始时,你选择一名其他角色(仅你可见)。②每回合限一次。当你进入濒死状态时,若〖连枝①〗角色存活,你回复1点体力并与其各摸一张牌。③当〖连枝①〗角色死亡后,你可以与一名其他角色各获得〖受责〗,且其获得与你拥有的等量枚“绞”标记(至少获得1枚)。', - dclingfang:'凌芳', - dclingfang_info:'锁定技。准备阶段,或当其他角色使用黑色牌结算结束后,若你是此牌的目标,或你使用黑色牌结算结束后,若你不是此牌目标,你获得1枚“绞”。', - dcfengying:'风影', - dcfengying_info:'①一名角色的回合开始时,你记录弃牌堆中所有黑色基本牌或黑色普通锦囊牌的牌名。②每回合每种牌名各限一次。你可以将一张点数不大于“绞”数的手牌当做任意一张〖风影①〗记录中的牌使用(无距离和次数限制)。', - dcshouze:'受责', - dcshouze_info:'锁定技。结束阶段,若你有“绞”,你弃1枚“绞”,随机获得弃牌堆中的一张黑色牌,失去1点体力。', - chengbing:'程秉', - dcjingzao:'经造', - dcjingzao_info:'出牌阶段每名角色限一次,你可以选择一名其他角色并亮出牌堆顶三张牌,其选择一项:1.弃置一张牌名与这些牌的其中一张牌名相同的牌,然后你本回合发动〖经造〗亮出的牌数+1;2.令你随机获得这些牌中每种牌名的牌各一张,然后你本回合发动〖经造〗亮出的牌数-X(X为你获得的牌数)。', - dcenyu:'恩遇', - dcenyu_info:'锁定技。当你成为其他角色使用【杀】或普通锦囊牌的目标后,若你本回合成为过此牌名的牌的目标,此牌对你无效。', - dc_zhouxuān:'周宣', - dcwumei:'寤寐', - dcwumei_info:'每轮限一次。回合开始时,你可以令一名角色记录场上所有角色的体力值并进行一个额外的回合,并将你的回合移至该回合后进行。该角色以此法进行的回合的结束阶段,将场上所有角色的体力值改为记录内的对应数值。', - dczhanmeng:'占梦', - dczhanmeng_info:'当你使用牌时,你可以选择本回合未选择过的一项:1.上一回合内,若没有同名牌被使用过,你获得一张非伤害牌;2.下一回合内,当同名牌首次被使用后,你获得一张伤害牌;3.令一名其他角色弃置两张牌,若点数之和大于10,你对其造成1点火焰伤害。', - dc_wangyun:'新杀王允', - dc_wangyun_prefix:'新杀', - dclianji:'连计', - dclianji_info:'出牌阶段限一次。你可以弃置一张手牌并选择一名其他角色,其随机使用牌堆中的一张武器牌,然后其选择一项:1.对另一名其他角色使用一张【杀】,并将武器牌交给其中一个目标;2.令你视为对其使用一张【杀】,并将武器牌交给你。', - dcmoucheng:'谋逞', - dcmoucheng_info:'觉醒技。准备阶段,若你发动过〖连计〗且两个选项均被选择过,你失去〖连计〗,然后获得〖矜功〗。', - xuelingyun:'薛灵芸', - dcxialei:'霞泪', - dcxialei_info:'当你的红色牌进入弃牌堆后,或当你使用或打出的红色牌经由处理区进入弃牌堆后,你可以观看牌堆顶的三张牌,获得其中的一张牌,且可以将其余牌置于牌堆底。然后你本回合以此法观看的牌数-1。', - dcanzhi:'暗织', - dcanzhi_info:'出牌阶段或当你受到伤害后,你可以判定,若结果为红色,你重置〖霞泪〗的观看牌数;若结果为黑色,〖暗织〗于本回合失效,然后你可以令一名非当前回合角色获得本回合进入弃牌堆的两张牌。', - yanghong:'杨弘', - dcjianji:'间计', - dcjianji_info:'出牌阶段限一次。你可以令至多X名座位连续的角色依次弃置一张牌。然后其中手牌数最多的角色可以视为对一名其他以此法弃置过牌的角色使用一张【杀】(X为你的攻击范围)。', - dcyuanmo:'远谟', - dcyuanmo_info:'①准备阶段或当你受到伤害后,你可以选择一项:1.攻击范围+1,然后若你攻击范围内的角色数因此增加,你可以获得任意名本次进入你攻击范围的角色各一张牌;2.攻击范围-1,然后摸两张牌。②结束阶段,若你的攻击范围内没有角色,你可以令你的攻击范围+1。', - dc_yangbiao:'杨彪', - dczhaohan:'昭汉', - dczhaohan_info:'摸牌阶段,你可以多摸两张牌,然后你于得到牌后选择一项:1.将两张手牌交给一名没有手牌的角色;2.弃置两张手牌。', - dcjinjie:'尽节', - dcjinjie_info:'当一名角色进入濒死状态时,可以令其摸一张牌。然后若你本轮未进行过回合,你可以弃置X张手牌令其回复1点体力(X为本轮你发动过〖尽节〗的次数)。', - dcjue:'举讹', - dcjue_info:'准备阶段,你可以视为对一名体力值或手牌数大于你的角色使用一张【杀】。', - dc_tengfanglan:'滕芳兰', - dcluochong:'落宠', - dcluochong_info:'一轮游戏开始时,你可以弃置任意名角色区域里的共计至多[4]张牌,然后若你以此法弃置了一名角色的至少三张牌,则你方括号内的数字-1。', - dcaichen:'哀尘', - dcaichen_info:'锁定技。若牌堆剩余数:大于80,当你因〖落宠〗弃置你区域内的牌后,你摸两张牌;大于40,你跳过弃牌阶段;小于40,你不能响应♠牌。', - xielingyu:'谢灵毓', - dcyuandi:'元嫡', - dcyuandi_info:'当其他角色于其出牌阶段使用第一张牌时,若此牌仅指定其为目标,你可以选择一项:1.弃置其一张手牌;2.你与其各摸一张牌。', - dcxinyou:'心幽', - dcxinyou_info:'出牌阶段限一次。你可以将体力回复至上限并将手牌补至体力上限。若你以此法:获得了至少三张牌,你于结束阶段失去1点体力;回复了体力,你于结束阶段弃置一张牌。', - zerong:'笮融', - dccansi:'残肆', - dccansi_info:'锁定技。准备阶段,你回复1点体力,然后选择一名其他角色,其回复1点体力,你视为对其依次使用以下能使用的牌:【杀】(无距离限制)、【决斗】、【火攻】。当其以此法受到1点伤害后,你摸两张牌。', - dcfozong:'佛宗', - dcfozong_info:'锁定技。出牌阶段开始时,若你的手牌数大于7,你将X张手牌置于武将牌上(X为你的手牌数-7)。然后若你的武将牌上有至少七张牌,其他角色依次选择一项:1.获得其中的一张牌并令你回复1点体力;2.令你失去1点体力。', - dc_ruiji:'芮姬', - dcwangyuan:'妄缘', - dcwangyuan_info:'当你于回合外失去牌后,或于回合内发动〖俐影〗后,你可以随机将牌堆里的一张与你所有“妄”牌名均不同的基本牌或锦囊牌置于武将牌上,称为“妄”(不超过游戏人数)。', - dclingyin:'铃音', + translate: { + puyuan: "蒲元", + pytianjiang: "天匠", + pytianjiang_info: + "游戏开始时,你随机获得两张不同副类别的装备牌,并置入你的装备区。出牌阶段,你可以将装备区的牌移动至其他角色的装备区(可替换原装备)。若你以此法移动了〖铸刃〗的衍生装备,你摸两张牌。", + pytianjiang_move: "天匠", + pyzhuren: "铸刃", + pyzhuren_info: + "出牌阶段限一次,你可以弃置一张手牌。根据此牌的花色点数,你有一定概率打造成功并获得一张武器牌(若打造失败或武器已有则改为摸一张【杀】,花色决定武器名称,点数决定成功率)。此武器牌进入弃牌堆时,将其移出游戏。", + pyzhuren_destroy: "铸刃", + pyzhuren_heart: "红缎枪", + pyzhuren_heart_info: + "每回合限一次,当你使用【杀】造成伤害后,你可以进行判定,若结果为:红色,你回复1点体力;黑色:你摸两张牌。", + pyzhuren_diamond: "烈淬刀", + pyzhuren_diamond_info: + "每回合限两次,当你使用【杀】对目标角色造成伤害时,你可以弃置一张牌,令此伤害+1。你使用【杀】的次数上限+1。", + pyzhuren_club: "水波剑", + pyzhuren_club_info: + "每回合限两次,当你使用普通锦囊牌或【杀】时,你可以为此牌增加一个目标。当你失去装备区里的【水波剑】后,你回复1点体力。", + pyzhuren_spade: "混毒弯匕", + pyzhuren_spade_info: + "当你使用【杀】指定目标后,你可令其失去X点体力(X为此技能本回合内发动过的次数且至多为5)。", + pyzhuren_shandian: "天雷刃", + pyzhuren_shandian_info: + "当你使用【杀】指定目标后,可令其进行判定,若结果为:黑桃,其受到3点雷属性伤害;梅花,其受到1点雷属性伤害,你回复1点体力并摸一张牌。", + guanlu: "管辂", + tuiyan: "推演", + tuiyan_info: "出牌阶段开始时,你可以观看牌堆顶的三张牌。", + busuan: "卜算", + busuan_info: + "出牌阶段限一次,你可以选择一名其他角色,然后选择至多两张不同的卡牌名称(限基本牌或锦囊牌)。该角色下次摸牌阶段摸牌时,改为从牌堆或弃牌堆中获得你选择的牌。", + busuan_angelbeats: "卜算", + mingjie: "命戒", + mingjie_info: + "结束阶段,你可以摸一张牌,若此牌为红色,你可以重复此流程直到摸到黑色牌或摸到第三张牌。当你以此法摸到黑色牌时,若你的体力值大于1,则你失去1点体力。", + gexuan: "葛玄", + gxlianhua: "炼化", + gxlianhua_info: + "你的回合外,每当有其他角色受到伤害后,你获得一个“丹血”标记(该角色与你阵营一致时为红色,不一致为黑色,此颜色对所有玩家均不可见)直到你的准备阶段开始。准备阶段,根据你获得的“丹血”标记的数量和颜色,你从牌堆/弃牌堆中获得相应的牌以及相应技能直到回合结束。3枚或以下:〖英姿〗和【桃】;超过3枚且红色“丹血”较多:〖观星〗和【无中生有】;超过3枚且黑色“丹血”较多:〖直言〗和【顺手牵羊】;超过3枚且红色和黑色一样多:【杀】、【决斗】和〖攻心〗。", + zhafu: "札符", + zhafu_info: + "限定技,出牌阶段,你可以选择一名其他角色,令其获得一枚「札」。有「札」的角色弃牌阶段开始时,若其手牌数大于1,其移去「札」并选择保留一张手牌,然后将其余的手牌交给你。", + leitong: "雷铜", + kuiji: "溃击", + kuiji_info: + "出牌阶段限一次。你可以将一张黑色基本牌当作【兵粮寸断】置于你的判定区,然后摸一张牌。若如此做,你可以对体力值最多的一名对手造成2点伤害。对手因此进入濒死状态时,你或队友体力值最少的一方回复1点体力。", + kuiji_info_identity: + "出牌阶段限一次。你可以将一张黑色基本牌当做【兵粮寸断】置于你的判定区,摸一张牌,然后你可以对体力值最多的一名其他角色造成2点伤害。该角色因此进入濒死状态时,你可令一名除其外体力值最少的角色回复1点体力。", + kuiji_info_guozhan: + "出牌阶段限一次。你可以将一张黑色基本牌当做【兵粮寸断】置于你的判定区,摸一张牌,然后你可以对体力值最多的一名其他角色造成2点伤害。该角色因此进入濒死状态时,你可令一名除其外体力值最少的角色回复1点体力。", + wulan: "吴兰", + wlcuorui: "挫锐", + wlcuorui_info: + "出牌阶段开始时,你可以弃置你或队友区域里的一张牌。若如此做,你选择一项:1.弃置对手装备区里至多两张与此牌颜色相同的牌;2.展示对手的共计两张手牌,然后获得其中与此牌颜色相同的牌。", + wlcuorui_info_identity: + "出牌阶段开始时,你可以弃置一名你至其的距离不大于1的角色区域里的一张牌,然后你选择一项:1.弃置另一名其他角色装备区里至多两张与此牌颜色相同的牌;2.展示另一名其他角色的至多两张手牌,然后获得其中与此牌颜色相同的牌。", + wlcuorui_info_guozhan: + "出牌阶段开始时,你可以弃置一名你至其的距离不大于1的角色区域里的一张牌,然后你选择一项:1.弃置另一名其他角色装备区里至多两张与此牌颜色相同的牌;2.展示另一名其他角色的至多两张手牌,然后获得其中与此牌颜色相同的牌。", + huaman: "花鬘", + manyi: "蛮裔", + manyi_info: "锁定技,【南蛮入侵】对你无效。", + manyi_info_single_normal: + "锁定技,【南蛮入侵】对你无效。当你登场时,你可以视为使用一张【南蛮入侵】。", + mansi_viewas: "蛮嗣", + mansi: "蛮嗣", + mansi_info: + "出牌阶段限一次,你可以将所有手牌当做【南蛮入侵】使用;当有角色受到【南蛮入侵】的伤害后,你摸一张牌。", + souying: "薮影", + souying_info: + "每回合限一次,当你对其他角色(或其他角色对你)使用【杀】或普通锦囊牌指定唯一目标后,若此牌不是本回合你对其(或其对你)使用的第一张【杀】或普通锦囊牌,你可以弃置一张牌,获得此牌对应的所有实体牌(或令此牌对你无效)。", + zhanyuan: "战缘", + zhanyuan_info: + "觉醒技,准备阶段,若你已因蛮嗣累计获得超过七张牌,你加1点体力上限并回复1点体力,并可以选择一名男性角色,你与其获得技能〖系力〗,然后你失去技能〖蛮嗣〗。", + hmxili: "系力", + hmxili_info: + "每回合限一次,你的回合外,当其他拥有【系力】技能的角色在其回合内对没有【系力】技能的角色造成伤害时,你可以弃置一张牌,令此伤害+1,然后你与其各摸两张牌。", + wangshuang: "王双", + spzhuilie: "追猎", + spzhuilie2: "追猎", + spzhuilie_info: + "锁定技,你使用【杀】无距离限制;当你使用【杀】指定目标后,若其不在你的攻击范围内,此【杀】不计入使用次数限制且你判定。若判定结果为武器牌或坐骑牌,此【杀】的伤害基数改为X(X为其体力值)。否则你失去1点体力。", + wenyang: "文鸯", + xinlvli: "膂力", + xinlvli_info: + "每回合限一次,当你造成伤害后,你可选择:1,若你的体力值大于你的手牌数,你摸X张牌;2,若你的手牌数大于你的体力值且你已受伤,你回复X点体力(X为你的手牌数与体力值之差)。", + lvli: "膂力", + lvli4: "膂力", + lvli5: "膂力", + lvli_info: + "每名角色的回合限一次,你可以声明一个基本牌或普通锦囊牌的牌名,有随机概率视为使用之(装备区里的牌数越多,成功概率越大)。", + choujue: "仇决", + choujue_info: + "觉醒技,一名角色的回合结束时,若你的手牌数和体力值相差3或更多,你减1点体力上限并获得技能〖背水〗,然后将〖膂力〗改为“在自己的回合时每回合限两次”。", + beishui: "背水", + beishui_info: + "觉醒技,准备阶段,若你的手牌数或体力值小于2,你减1点体力上限并获得技能〖清剿〗,然后将〖膂力〗改为受到伤害后也可以发动。", + qingjiao: "清剿", + qingjiao_info: + "出牌阶段开始时,你可以弃置所有手牌,然后从牌堆或弃牌堆中随机获得八张牌名各不相同且副类别不同的牌。若如此做,结束阶段,你弃置所有牌。", + re_liuzan: "留赞", + refenyin: "奋音", + refenyin_info: + "锁定技,你的回合内,当一张牌进入弃牌堆后,若本回合内没有过与此牌花色相同的卡牌进入过弃牌堆,则你摸一张牌。", + liji: "力激", + liji_info: + "出牌阶段限X次,你可以弃置一张牌并对一名其他角色造成1点伤害。(X为本回合内进入过弃牌堆的卡牌数除以8,若场上人数小于5则改为除以4,向下取整)", + liubian: "刘辩", + shiyuan: "诗怨", + shiyuan_info: + "每回合每项限一次,当你成为其他角色使用牌的目标后:①若其体力值大于你,你摸三张牌。②若其体力值等于你,你摸两张牌。③若其体力值小于你,你摸一张牌。", + dushi: "毒逝", + dushi_info: + "锁定技,你处于濒死状态时,其他角色不能对你使用【桃】。你死亡时,你选择一名其他角色获得〖毒逝〗。", + yuwei: "余威", + yuwei_info: "主公技,锁定技,其他群雄角色的回合内,你将〖诗怨〗改为“每回合每项限两次”。", + re_xinxianying: "新杀辛宪英", + re_xinxianying_prefix: "新杀", + rezhongjian: "忠鉴", + rezhongjian2: "忠鉴", + rezhongjian_info: + "出牌阶段限一次,你可以选择一名本回合内未选择过的角色。你令其获得一项效果直至你的下回合开始:①其下次造成伤害后弃置两张牌,然后你摸一张牌。②其下次受到伤害后摸两张牌,然后你摸一张牌。", + recaishi: "才识", + recaishi3: "才识", + recaishi_info: + "摸牌阶段结束时,若你于本阶段内因摸牌而获得的所有的牌:花色均相同,你将〖忠鉴〗于本回合内改为“出牌阶段限两次”。不均相同,你可回复1点体力。若如此做,你本回合内不能对自己使用牌。", + guozhao: "郭照", + pianchong: "偏宠", + pianchong2: "偏宠", + pianchong_info: + "摸牌阶段开始时,你可放弃摸牌。若如此做,你从牌堆中获得一张红色牌和一张黑色牌。然后你选择一种颜色。你的下回合开始前,当你失去该颜色的一张牌后,你从牌堆中获得另一种颜色的一张牌。", + zunwei: "尊位", + zunwei_backup: "尊位", + zunwei_info: + "出牌阶段限一次,你可选择本局游戏内未选择过的一项:①若你已受伤,则你可以选择一名体力值大于你的其他角色,你将体力值回复至X(X为你的体力上限与其体力值中的较小值)②选择一名手牌数大于你的其他角色,你将手牌数摸至与其相同(至多摸五张)③选择一名装备区内牌数大于你的其他角色。你令X=1。若你装备区内的('equip'+X)栏为空,则你使用牌堆中的一张副类别为('equip'+X),且能对自己使用的装备牌。你令X+1。若X不大于5,且你装备区内的牌数仍小于目标角色,则你重复此流程。", + fanyufeng: "樊玉凤", + bazhan: "把盏", + bazhan_info: + "转换技,出牌阶段限一次,阴:你可以将至多两张手牌交给一名其他角色。阳:你可以获得一名其他角色的至多两张手牌。若以此法移动的牌包含【酒】或♥牌,则你可令得到牌的角色执行一项:①回复1点体力。②复原武将牌。", + jiaoying: "醮影", + jiaoying2: "醮影", + jiaoying3: "醮影", + jiaoying3_draw: "醮影", + jiaoying_info: + "锁定技,其他角色得到你的手牌后,该角色本回合不能使用或打出与此牌颜色相同的牌。然后此回合结束时,若其本回合没有再使用牌,你令一名角色将手牌摸至五张。", + ruanyu: "阮瑀", + xingzuo: "兴作", + xingzuo2: "兴作", + xingzuo_info: + "出牌阶段开始时,你可观看牌堆底的三张牌并用任意张手牌替换其中等量的牌。若如此做,结束阶段,你可令一名有手牌的角色用所有手牌替换牌堆底的三张牌。若其因此法失去的牌多于三张,则你失去1点体力。", + miaoxian: "妙弦", + miaoxian_info: + "若你的手牌中仅有一张黑色牌,你可将此牌当作任意一张普通锦囊牌使用(每回合限一次);若你的手牌中仅有一张红色牌,你使用此牌时摸一张牌。", + yangwan: "杨婉", + youyan: "诱言", + youyan_info: + "出牌阶段/弃牌阶段各限一次。当有牌进入弃牌堆后,若其中有你不因使用或打出而失去的牌,你可以从牌堆中获得你本次失去的牌中没有的花色的牌各一张。", + zhuihuan: "追还", + zhuihuan2: "追还", + zhuihuan2_new: "追还", + zhuihuan_info: + "结束阶段开始时,你可以选择一名角色(对其他角色不可见)。记录所有对该角色造成过伤害的角色。该角色的下个准备阶段开始时停止记录,且所有记录过的角色:若体力值大于该角色,则受到其造成的2点伤害;若体力值小于等于该角色,则随机弃置两张手牌。", + re_panshu: "潘淑", + zhiren: "织纴", + zhiren_info: + "当你于你的回合内使用第一张非转化牌时,你可依次执行以下选项中的前X项:①卜算X。②可弃置场上的一张装备牌和延时锦囊牌。③回复1点体力。④摸三张牌。(X为此牌的名称的字数)", + yaner: "燕尔", + yaner_info: + "每回合限一次。当有其他角色于其出牌阶段内失去手牌后,若其没有手牌,则你可以与其各摸两张牌。若其以此法摸得的两张牌类型相同,则其回复1点体力。若你以此法摸得的两张牌类型相同,则你将〖织纴〗中的“你的回合内”改为“一回合内”直至你下回合开始。", + zhouyi: "周夷", + zhukou: "逐寇", + zhukou_info: + "①当你于一名角色的出牌阶段第一次造成伤害后,你可以摸X张牌(X为本回合你已使用的牌数)。②你的结束阶段,若你本回合没有造成伤害,你可以对两名其他角色各造成1点伤害。", + mengqing: "氓情", + mengqing_info: + "觉醒技。准备阶段,若场上已受伤的角色数大于你的体力值,你加3点体力上限并回复3点体力,失去〖逐寇〗,获得〖玉殒〗。", + yuyun: "玉殒", + yuyun_info: + "锁定技,出牌阶段开始时,你失去1点体力或体力上限(不能减至1以下),然后选择X+1项(X为你已损失的体力值):①摸两张牌;②对一名其他角色造成1点伤害,然后本回合对其使用【杀】无距离和次数限制;③本回合的手牌上限视为无限;④获得一名其他角色区域内的一张牌;⑤令一名其他角色将手牌摸至体力上限(最多摸至5)。", + caojinyu: "曹金玉", + yuqi: "隅泣", + yuqi_info: + "每回合限两次。当有角色受到伤害后,若你至其的距离不大于0,则你可以观看牌堆顶的3张牌。你将其中至多1张牌交给受伤角色,然后可以获得剩余牌中的至多1张牌,并将其余牌以原顺序放回牌堆顶。(所有具有颜色的数字至多为5)", + shanshen: "善身", + shanshen_info: + "当有角色死亡时,你可令你的〖隅泣〗中的一个具有颜色的数字+2。然后若你未对该角色造成过伤害,则你回复1点体力。", + xianjing: "娴静", + xianjing_info: + "准备阶段,你可令你的〖隅泣〗中的一个具有颜色的数字+1。若你的体力值等于体力上限,则你可以重复一次此流程。", + re_sunyi: "孙翊", + syjiqiao: "激峭", + syjiqiao_info: + "出牌阶段开始时,你可将牌堆顶的X张牌置于你的武将牌上(X为你的体力上限)。当你于此出牌阶段内使用的牌结算结束后,你可以获得其中的一张牌,然后若剩余牌中红色牌和黑色牌的数量:不相等,你失去1点体力;相等,你回复1点体力。出牌阶段结束时,你将这些牌置入弃牌堆。", + syxiongyi: "凶疑", + syxiongyi_info: + "限定技。当你处于濒死状态时,若剩余武将牌堆中:有“徐氏”,则你可以将体力值回复至3点,并将此武将牌替换为“徐氏”;没有“徐氏”,则你可以将体力值回复至1点并获得〖魂姿〗。", + re_zhangbao: "新杀张宝", + re_zhangbao_prefix: "新杀", + xinzhoufu: "咒缚", + xinzhoufu2: "咒缚", + xinzhoufu_info: + "出牌阶段限一次。你可以将一张手牌置于一名其他角色的武将牌上并称为“咒”,且当其判定时,将其“咒”作为判定牌。", + xinyingbing: "影兵", + xinyingbing_info: + "锁定技。每回合每名角色限一次,当你使用牌指定有“咒”的角色为目标后,你摸两张牌。", + wufan: "吴范", + tianyun: "天运", + tianyun_info: + "①游戏的第一个回合开始前,你从牌堆中获得手牌区内没有的花色的各一张牌。②一名角色的回合开始时,若其座位号等于游戏轮数,则你可观看牌堆顶的X张牌并以任意顺序置于牌堆顶或牌堆底。若你将所有的牌均置于了牌堆底,则你可以令一名角色摸X张牌,然后失去1点体力。(X为你手牌中包含的花色数)", + wfyuyan: "预言", + wfyuyan_info: + "一轮游戏开始时,你选择一名角色(对其他角色不可见):当第一次有角色于本轮内进入濒死状态时,若其是你选择的角色,则你获得〖奋音〗直到你的回合结束;当第一次有角色于本轮内造成伤害后,若其是你选择的角色,则你摸两张牌。", + re_fengfangnv: "冯妤", + tiqi: "涕泣", + tiqi_info: + "其他角色的摸牌阶段结束时/被跳过时,若其于本阶段内因摸牌而得到的牌数X不等于2,则你可以摸|X-2|张牌,并可令其本回合的手牌上限±|X-2|。", + baoshu: "宝梳", + baoshu_info: + "①准备阶段,你可选择Y名角色,这些角色重置武将牌并获得(X-Y+1)个“梳”(X为你的体力上限,Y∈[1, X])。②一名角色的摸牌阶段开始时,若其有“梳”,则其本阶段的额定摸牌数+Z且移去Z个“梳”(Z为其“梳”的数量)。", + dc_luotong: "骆统", + renzheng: "仁政", + renzheng_info: "锁定技。当有伤害被防止时,或伤害值发生过减少的伤害事件结算结束后,你摸两张牌。", + jinjian: "进谏", + jinjian_info: + "①当你造成伤害时,你可令此伤害+1,然后你本回合内下一次造成的伤害-1且不触发〖进谏①〗。②当你受到伤害时,你可令此伤害-1。然后你于本回合内下一次受到的伤害+1且不触发〖进谏②〗。", + caomao: "曹髦", + qianlong: "潜龙", + qianlong_info: + "当你受到伤害后,你可以亮出牌堆顶的三张牌并获得其中的至多X张牌(X为你已损失的体力值),然后将剩余的牌置于牌堆底。", + fensi: "忿肆", + fensi_info: + "锁定技。准备阶段,你须选择一名体力值不小于你的角色并对其造成1点伤害,然后若你选择的角色不为你自己,则其视为对你使用一张【杀】。", + juetao: "决讨", + juetao_info: + "限定技。出牌阶段开始时,若你的体力值为1,则你可以选择一名其他角色。你亮出牌堆底的一张牌,若此牌能被你使用,则你使用此牌并重复此流程直到出现不可使用的牌或其死亡(你与其以外的角色不是此牌的合法目标)。", + zhushi: "助势", + zhushi_info: "主公技。每回合限一次,其他魏势力角色于回合内回复体力时,其可令你摸一张牌。", + laiyinger: "来莺儿", + xiaowu: "绡舞", + xiaowu_info: + "出牌阶段限一次,你可以选择任意名座位连续且包含你的上家/下家的其他角色。这些角色依次选择一项:⒈令你摸一张牌;⒉其摸一张牌。然后若选择选项一的角色数大于选项二的角色数,则你获得一枚“沙”;若选择选项二的角色数大于选项一的角色数,则你对这些角色依次造成1点伤害。", + huaping: "化萍", + huaping_info: + "限定技。①一名其他角色死亡时,你可获得其当前拥有的所有不带有「Charlotte」标签的技能,然后你失去〖绡舞〗,移去所有“沙”并摸等量的牌。②当你死亡时,你可令一名其他角色获得〖沙舞〗和你的所有“沙”。", + shawu: "沙舞", + shawu_info: + "当你使用【杀】指定目标后,你可选择一项:⒈弃置两张手牌;⒉移去一枚“沙”并摸两张牌。然后你对目标角色造成1点伤害。", + dc_huangzu: "黄祖", + dcjinggong: "精弓", + dcjinggong_info: + "你可以将一张装备牌当做无距离限制的【杀】使用。当你声明使用此【杀】后,你将此杀的伤害值基数改为X(X为你至此【杀】第一个目标角色的距离且至多为5)。", + dcxiaojuan: "骁隽", + dcxiaojuan_info: + "当你使用牌指定其他角色为唯一目标后,你可以弃置其一半的手牌(向下取整)。若这些牌中有与你使用牌花色相同的牌,则你弃置一张手牌。", + dc_liuyu: "新杀刘虞", + dc_liuyu_prefix: "新杀", + dcsuifu: "绥抚", + dcsuifu_info: + "其他角色的结束阶段开始时,若你和一号位本回合内累计受到过的伤害值大于1,则你可以将该角色的所有手牌置于牌堆顶,然后视为使用一张【五谷丰登】。", + dcpijing: "辟境", + dcpijing_info: + "结束阶段开始时,你可以选择任意名角色。你令所有未选择的角色失去〖自牧〗,然后你和这些角色获得〖自牧〗。", + dczimu: "自牧", + dczimu_info: "锁定技。当你受到伤害后,你令所有拥有〖自牧〗的角色各摸一张牌,然后你失去〖自牧〗。", + caohua: "曹华", + caiyi: "彩翼", + caiyi_info: + "转换技。结束阶段,你可令一名角色选择并执行一项,然后移除此选项。阴:⒈回复X点体力。⒉摸X张牌,⒊复原武将牌。⒋随机执行一个已经移除过的阴选项;阳:⒈受到X点伤害。⒉弃置X张牌。⒊翻面并横置。⒋随机执行一个已经移除过的阳选项。(X为该阴阳态剩余选项的数量)。", + guili: "归离", + guili_info: + "你的第一个回合开始时,你须选择一名其他角色。该角色每轮的第一个回合结束后,若其本回合内未造成过伤害,则你执行一个额外的回合。", + zhaoang: "赵昂", + dczhongjie: "忠节", + dczhongjie_info: + "每轮限一次。当有角色因失去体力而进入濒死状态时,你可令其回复1点体力并摸一张牌。", + dcsushou: "夙守", + dcsushou_tag: "对方手牌", + dcsushou_info: + "一名角色的出牌阶段开始时,若其手牌数为全场唯一最多,则你可以失去1点体力并摸X张牌。然后若该角色不是你,则你可以观看其一半的手牌(向下取整),且用至多X张手牌替换其中等量的牌。(X为你已损失的体力值)", + dc_wangchang: "王昶", + dckaiji: "开济", + dckaiji_info: + "转换技。出牌阶段限一次,你可以:阴:摸X张牌;阳:弃置至多X张牌(X为你的体力上限且至多为5)。", + dcpingxi: "平袭", + dcpingxi_info: + "结束阶段,若X大于0,则你可以选择至多X名其他角色(X为本回合内因弃置而进入弃牌堆的牌数)。你依次弃置这些角色的各一张牌,然后视为对这些角色使用一张【杀】。", + liuhui: "刘徽", + dcgeyuan: "割圆", + dcgeyuan_info: + "锁定技。①游戏开始时,你将从A至K的所有整数排列为一个环形链表,称为“圆环之理”。②当有一张牌进入弃牌堆后,若此牌的点数在“圆环之理”内,且“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你将此牌的点数记录进“圆环之弧”;然后若“圆环之弧”与“圆环之理”长度相同,则你从“圆环之理”中移除“圆环之弧”记录的第一个和最后一个数字A和B(当“圆环之理”长度不大于3时则不移除),清空“圆环之弧”,获得场上和牌堆中所有点数为A和B的牌。", + dcjieshu: "解术", + dcjieshu_info: + "锁定技。①所有点数不在“圆环之理”中的牌不计入你的手牌上限。②当你使用牌时,若“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你摸一张牌。", + dcgusuan: "股算", + dcgusuan_info: + "觉醒技。一名角色的回合结束时,若你的“圆环之理”长度为3,则你减1点体力上限并修改〖割圆〗。", + dcgeyuan_magica: "割圆·改", + dcgeyuan_magica_info: + "锁定技。当有一张牌进入弃牌堆后,若此牌的点数在“圆环之理”内,且“圆环之弧”为空或此牌的点数与“圆环之弧”两端的点数相邻,则你将此牌的点数记录进“圆环之弧”;然后若“圆环之弧”与“圆环之理”长度相同,则你清空“圆环之弧”并选择至多三名角色,这些角色中的第一名角色摸三张牌,第二名角色弃置四张牌,第三名角色将其手牌与牌堆底的五张牌交换。", + zhangfen: "张奋", + dcwanglu: "望橹", + dcwanglu_info: + "锁定技。准备阶段开始时,若你的装备区内:有【大攻车】,则你获得一个额外的出牌阶段;没有【大攻车】,则你将一张【大攻车】置入装备区。", + dcxianzhu: "陷筑", + dcxianzhu_info: + "当你造成渠道为【杀】伤害后,你可以为你装备区内的【大攻车】选择一项强化(每张【大攻车】最多被强化五次):⒈通过【大攻车】使用【杀】无视距离和防具;⒉通过此【大攻车】使用的【杀】可以额外选择1个目标(可叠加);⒊通过此【大攻车】使用的【杀】造成伤害后的弃置牌数+1(可叠加)。", + dcchaixie: "拆械", + dcchaixie_info: "锁定技。当你的【大攻车】被销毁后,你摸X张牌(X为此【大攻车】被强化过的次数)。", + dagongche: "大攻车", + dagongche_skill: "大攻车", + dagongche_info: + "出牌阶段开始时,你可以视为使用一张【杀】,且当此【杀】因执行效果而对目标角色造成伤害后,你弃置其一张牌。若此【大攻车】未被强化,则其他角色无法弃置你装备区内的【大攻车】。当此牌离开你的装备区后,销毁之。", + dukui: "杜夔", + dcfanyin: "泛音", + dcfanyin_info: + "出牌阶段开始时,你可以亮出牌堆中点数最小的一张牌。然后你选择一项,并可以亮出一张点数为此牌二倍的牌且重复此流程:⒈使用此牌(无距离限制);⒉你于本回合内使用的下一张基本牌或普通锦囊牌选择目标后,可以增加一个目标。", + dcpeiqi: "配器", + dcpeiqi_info: + "当你受到伤害后,你可以移动场上的一张牌。然后若场上所有角色均在彼此的攻击范围内,则你可以再移动场上的一张牌。", + quanhuijie: "全惠解", + dchuishu: "慧淑", + dchuishu_info: + "摸牌阶段结束时,你可以摸[3]张牌。若如此做:你弃置[1]张手牌,且当你于本回合内弃置第[2]+1张牌后,你从弃牌堆中随机获得〖慧淑〗第三个括号数字张非基本牌。", + dcyishu: "易数", + dcyishu_info: + "锁定技。当你不因出牌阶段而失去牌后,你同时令{〖慧淑〗的中括号内最小的一个数字+2}且{〖慧淑〗的中括号内最大的一个数字-1}。", + dcligong: "离宫", + dcligong_info: + "觉醒技。准备阶段,若〖慧淑〗的中括号内有不小于5的数字,则你加1点体力上限,回复1点体力并失去〖易数〗。系统随机检索四张吴势力的女性武将牌,然后你选择一项:⒈摸三张牌。⒉失去〖慧淑〗,然后获得这些武将牌上的任意两个非Charlotte技能。", + dingshangwan: "丁尚涴", + dcfengyan: "讽言", + dcfengyan_info: + "出牌阶段每项各限一次。你可以:⒈令一名体力值不大于你的其他角色交给你一张手牌。⒉视为对一名手牌数不大于你的角色使用一张【杀】(无距离和次数限制)。", + dcfudao: "抚悼", + dcfudao_info: + "游戏开始时,你选择一名其他角色,称为“继子”角色。当你或“继子”每回合首次使用牌指定对方为目标后,你与其各摸两张牌。当有角色杀死你或“继子”后,该角色称为“决裂”角色。当你或“继子”对“决裂”造成伤害时,此伤害+1。当你成为“决裂”角色使用牌的目标后,其本回合内不能再使用牌。", + luyi: "卢弈", + dcyaoyi: "邀弈", + dcyaoyi_info: + "锁定技。①游戏开始时,你令所有存活且未拥有转换技的角色获得〖手谈〗。②你发动〖手谈〗时无需弃置牌,且无次数限制。③所有拥有转换技的角色不能使用牌指定其他拥有转换技且双方所有转换技状态均相同的角色为目标。", + dcfuxue: "复学", + dcfuxue_info: + "①准备阶段,你可以从弃牌堆中选择获得至多X张不因使用而进入弃牌堆的牌。②结束阶段,若你的手牌区中没有因〖复学①〗得到的牌,则你摸X张牌(X为你的体力值)。", + dcshoutan: "手谈", + dcshoutan_info: + "转换技。出牌阶段限一次,阴:你可以弃置一张不为黑色的手牌。阳:你可以弃置一张黑色手牌。", + dc_liuye: "刘晔", + dcpoyuan: "破垣", + dcpoyuan_info: + "游戏开始时或准备阶段开始时,若你的装备区内:没有【霹雳投石车】,则你可以将一张【霹雳投石车】置入装备区;有【霹雳投石车】,则你可以弃置一名其他角色至多两张牌。", + dchuace: "画策", + dchuace_info: "出牌阶段限一次。你可以将一张手牌当做上一轮内未被使用过的普通锦囊牌使用。", + pilitoushiche: "霹雳投石车", + pilitoushiche_info: + "锁定技。①你于回合内使用基本牌无距离限制,且当你于回合内使用基本牌时,你令此牌的牌面数值+1。②当你于回合外使用或打出基本牌时,你摸一张牌。③当此牌离开你的装备区时,销毁之。", + zhaozhi: "赵直", + dctongguan: "统观", + dctongguan_info: + "一名角色的第一个回合开始时,你为其选择一项属性(每个属性至多选两次,且仅对你可见)。", + dcmengjie: "梦解", + dcmengjie_info: + "一名角色的回合结束时,若其本回合完成了其〖统观〗属性,你执行对应效果:
            • 「武勇」造成伤害:对一名其他角色造成1点伤害;
            • 「刚硬」回复体力,或于得到牌后手牌数大于体力值:令一名角色回复1点体力;
            • 「多谋」于摸牌阶段外摸牌:摸两张牌;
            • 「果决」弃置或获得其他角色的牌:弃置一名角色区域内至多两张牌;
            • 「仁智」交给其他角色牌:令一名其他角色将手牌补至体力上限(至多摸五张)。", + dctongguan_wuyong: "武勇", + dctongguan_wuyong_info: "任务目标:造成伤害。", + dctongguan_gangying: "刚硬", + dctongguan_gangying_info: "任务目标:回复体力,或于得到牌后手牌数大于体力值。", + dctongguan_duomou: "多谋", + dctongguan_duomou_info: "任务目标:于摸牌阶段外摸牌。", + dctongguan_guojue: "果决", + dctongguan_guojue_info: "任务目标:弃置或获得其他角色的牌。", + dctongguan_renzhi: "仁智", + dctongguan_renzhi_info: "任务目标:交给其他角色牌。", + zhujianping: "朱建平", + olddcxiangmian: "相面", + olddcxiangmian_info: + "其他角色的结束阶段,你可以判定。然后你不能再对其发动此技能,其获得以下效果:当其使用第X张结果的花色的牌后(X为结果的点数),其失去等同于其体力值的体力。", + dcxiangmian: "相面", + dcxiangmian_info: + "出牌阶段限一次。你可以令一名其他角色判定,然后你不能再对其发动此技能,其获得以下效果:当其使用结果的花色的牌后,或当其使用X张牌后(X为结果的点数),其失去等同于其体力值的体力。", + dctianji: "天机", + dctianji_info: + "锁定技。当判定牌进入弃牌堆后,你从牌堆随机获得分别与该牌类型、花色和点数相同的牌各一张。", + yuanji: "袁姬", + dcmengchi: "蒙斥", + dcmengchi_info: + "锁定技。若你未于当前回合得到过牌:你不能使用牌;当你横置前,取消之;当你受到无属性伤害后,回复1点体力。", + dcfangdu: "芳妒", + dcfangdu_info: + "锁定技。当你于回合外受到伤害后,若此次伤害为你于本回合受到的:第一次无属性伤害,你回复1点体力;第一次属性伤害,你随机获得伤害来源的一张手牌。", + dcjiexing: "节行", + dcjiexing_info: + "当你受到伤害后、失去体力后或回复体力后,你可以摸一张牌,且此牌不计入本回合的手牌上限。", + dongguiren: "董贵人", + dclianzhi: "连枝", + dclianzhi_info: + "①游戏开始时,你选择一名其他角色(仅你可见)。②每回合限一次。当你进入濒死状态时,若〖连枝①〗角色存活,你回复1点体力并与其各摸一张牌。③当〖连枝①〗角色死亡后,你可以与一名其他角色各获得〖受责〗,且其获得与你拥有的等量枚“绞”标记(至少获得1枚)。", + dclingfang: "凌芳", + dclingfang_info: + "锁定技。准备阶段,或当其他角色使用黑色牌结算结束后,若你是此牌的目标,或你使用黑色牌结算结束后,若你不是此牌目标,你获得1枚“绞”。", + dcfengying: "风影", + dcfengying_info: + "①一名角色的回合开始时,你记录弃牌堆中所有黑色基本牌或黑色普通锦囊牌的牌名。②每回合每种牌名各限一次。你可以将一张点数不大于“绞”数的手牌当做任意一张〖风影①〗记录中的牌使用(无距离和次数限制)。", + dcshouze: "受责", + dcshouze_info: + "锁定技。结束阶段,若你有“绞”,你弃1枚“绞”,随机获得弃牌堆中的一张黑色牌,失去1点体力。", + chengbing: "程秉", + dcjingzao: "经造", + dcjingzao_info: + "出牌阶段每名角色限一次,你可以选择一名其他角色并亮出牌堆顶三张牌,其选择一项:1.弃置一张牌名与这些牌的其中一张牌名相同的牌,然后你本回合发动〖经造〗亮出的牌数+1;2.令你随机获得这些牌中每种牌名的牌各一张,然后你本回合发动〖经造〗亮出的牌数-X(X为你获得的牌数)。", + dcenyu: "恩遇", + dcenyu_info: + "锁定技。当你成为其他角色使用【杀】或普通锦囊牌的目标后,若你本回合成为过此牌名的牌的目标,此牌对你无效。", + dc_zhouxuān: "周宣", + dcwumei: "寤寐", + dcwumei_info: + "每轮限一次。回合开始时,你可以令一名角色记录场上所有角色的体力值并进行一个额外的回合,并将你的回合移至该回合后进行。该角色以此法进行的回合的结束阶段,将场上所有角色的体力值改为记录内的对应数值。", + dczhanmeng: "占梦", + dczhanmeng_info: + "当你使用牌时,你可以选择本回合未选择过的一项:1.上一回合内,若没有同名牌被使用过,你获得一张非伤害牌;2.下一回合内,当同名牌首次被使用后,你获得一张伤害牌;3.令一名其他角色弃置两张牌,若点数之和大于10,你对其造成1点火焰伤害。", + dc_wangyun: "新杀王允", + dc_wangyun_prefix: "新杀", + dclianji: "连计", + dclianji_info: + "出牌阶段限一次。你可以弃置一张手牌并选择一名其他角色,其随机使用牌堆中的一张武器牌,然后其选择一项:1.对另一名其他角色使用一张【杀】,并将武器牌交给其中一个目标;2.令你视为对其使用一张【杀】,并将武器牌交给你。", + dcmoucheng: "谋逞", + dcmoucheng_info: + "觉醒技。准备阶段,若你发动过〖连计〗且两个选项均被选择过,你失去〖连计〗,然后获得〖矜功〗。", + xuelingyun: "薛灵芸", + dcxialei: "霞泪", + dcxialei_info: + "当你的红色牌进入弃牌堆后,或当你使用或打出的红色牌经由处理区进入弃牌堆后,你可以观看牌堆顶的三张牌,获得其中的一张牌,且可以将其余牌置于牌堆底。然后你本回合以此法观看的牌数-1。", + dcanzhi: "暗织", + dcanzhi_info: + "出牌阶段或当你受到伤害后,你可以判定,若结果为红色,你重置〖霞泪〗的观看牌数;若结果为黑色,〖暗织〗于本回合失效,然后你可以令一名非当前回合角色获得本回合进入弃牌堆的两张牌。", + yanghong: "杨弘", + dcjianji: "间计", + dcjianji_info: + "出牌阶段限一次。你可以令至多X名座位连续的角色依次弃置一张牌。然后其中手牌数最多的角色可以视为对一名其他以此法弃置过牌的角色使用一张【杀】(X为你的攻击范围)。", + dcyuanmo: "远谟", + dcyuanmo_info: + "①准备阶段或当你受到伤害后,你可以选择一项:1.攻击范围+1,然后若你攻击范围内的角色数因此增加,你可以获得任意名本次进入你攻击范围的角色各一张牌;2.攻击范围-1,然后摸两张牌。②结束阶段,若你的攻击范围内没有角色,你可以令你的攻击范围+1。", + dc_yangbiao: "杨彪", + dczhaohan: "昭汉", + dczhaohan_info: + "摸牌阶段,你可以多摸两张牌,然后你于得到牌后选择一项:1.将两张手牌交给一名没有手牌的角色;2.弃置两张手牌。", + dcjinjie: "尽节", + dcjinjie_info: + "当一名角色进入濒死状态时,可以令其摸一张牌。然后若你本轮未进行过回合,你可以弃置X张手牌令其回复1点体力(X为本轮你发动过〖尽节〗的次数)。", + dcjue: "举讹", + dcjue_info: "准备阶段,你可以视为对一名体力值或手牌数大于你的角色使用一张【杀】。", + dc_tengfanglan: "滕芳兰", + dcluochong: "落宠", + dcluochong_info: + "一轮游戏开始时,你可以弃置任意名角色区域里的共计至多[4]张牌,然后若你以此法弃置了一名角色的至少三张牌,则你方括号内的数字-1。", + dcaichen: "哀尘", + dcaichen_info: + "锁定技。若牌堆剩余数:大于80,当你因〖落宠〗弃置你区域内的牌后,你摸两张牌;大于40,你跳过弃牌阶段;小于40,你不能响应♠牌。", + xielingyu: "谢灵毓", + dcyuandi: "元嫡", + dcyuandi_info: + "当其他角色于其出牌阶段使用第一张牌时,若此牌仅指定其为目标,你可以选择一项:1.弃置其一张手牌;2.你与其各摸一张牌。", + dcxinyou: "心幽", + dcxinyou_info: + "出牌阶段限一次。你可以将体力回复至上限并将手牌补至体力上限。若你以此法:获得了至少三张牌,你于结束阶段失去1点体力;回复了体力,你于结束阶段弃置一张牌。", + zerong: "笮融", + dccansi: "残肆", + dccansi_info: + "锁定技。准备阶段,你回复1点体力,然后选择一名其他角色,其回复1点体力,你视为对其依次使用以下能使用的牌:【杀】(无距离限制)、【决斗】、【火攻】。当其以此法受到1点伤害后,你摸两张牌。", + dcfozong: "佛宗", + dcfozong_info: + "锁定技。出牌阶段开始时,若你的手牌数大于7,你将X张手牌置于武将牌上(X为你的手牌数-7)。然后若你的武将牌上有至少七张牌,其他角色依次选择一项:1.获得其中的一张牌并令你回复1点体力;2.令你失去1点体力。", + dc_ruiji: "芮姬", + dcwangyuan: "妄缘", + dcwangyuan_info: + "当你于回合外失去牌后,或于回合内发动〖俐影〗后,你可以随机将牌堆里的一张与你所有“妄”牌名均不同的基本牌或锦囊牌置于武将牌上,称为“妄”(不超过游戏人数)。", + dclingyin: "铃音", // dclingyin_info:'出牌阶段开始时,你可以获得至多X张“妄”(X为游戏轮数)然后若你的“妄”颜色均相同,你于本回合对其他角色造成的伤害+1,且可以将一张武器牌或防具牌当【决斗】使用。', - dclingyin_info:'出牌阶段开始时,你可以选择至多X张“妄”(X为游戏轮数),若这些牌以外的“妄”中不存在颜色不同的牌,则你于本回合对其他角色造成的伤害+1,且可以将一张武器牌或防具牌当【决斗】使用。你获得这些牌。', - dcliying:'俐影', - dcliying_info:'每回合限一次。当你于摸牌阶段外得到牌后,你可以将这些牌中的任意张交给一名其他角色,然后摸一张牌。', - huanfan:'桓范', - dcjianzheng:'谏诤', - dcjianzheng_info:'出牌阶段限一次。你可以观看一名其他角色的手牌,然后若其中有你可以使用的手牌,你获得并使用其中一张。若你以此法使用牌指定了其为目标,你令你与其横置,然后其观看你的手牌。', - dcfumou:'腹谋', - dcfumou_info:'当你受到伤害后,你可以令至多X名角色从你开始逆时针依次选择一项:1.移动场上的一张牌;2.弃置所有手牌并摸两张牌;3.弃置装备区里的所有牌并回复1点体力(X为你已损失的体力值)。', - chentai:'陈泰', - dcctjiuxian:'救陷', - dcctjiuxian_info:'出牌阶段限一次。你可以重铸一半数量的手牌(向上取整),然后视为使用一张【决斗】。当此牌对目标角色造成伤害后,你可以令其攻击范围内的一名其他角色回复1点体力。', - dcchenyong:'沉勇', - dcchenyong_info:'结束阶段,你可以摸X张牌(X为本回合你使用过的牌的类型数)。', - sunyu:'孙瑜', - dcquanshou:'劝守', - dcquanshou_info:'一名角色的回合开始时,若其手牌数不大于其体力上限,你可以令其选择一项:1.将手牌摸至体力上限,然后本回合使用【杀】的次数上限-1(至多摸五张);2.其本回合使用牌被抵消后,你摸一张牌。', - dcshexue:'设学', - dcshexue_info:'①出牌阶段开始时,你可以将一张牌当做上回合的角色于其出牌阶段内使用的一张基本牌或普通锦囊牌使用。②出牌阶段结束时,你可以令下回合的角色于其出牌阶段开始时可以将一张牌当做你于此阶段内使用的一张基本牌或普通锦囊牌使用(一名角色因〖设学〗使用的牌均无距离和次数限制)。', - xizheng:'郤正', - dcdanyi:'耽意', - dcdanyi_info:'当你使用牌指定第一个目标后,你可以摸X张牌(X为此牌目标数与你使用的上一张牌相同的目标数)。', - dcwencan:'文灿', - dcwencan_info:'出牌阶段限一次。你可以选择至多两名体力值不同的其他角色,这些角色依次选择一项:1.弃置两张花色不同的牌;2.本回合你对其使用牌无距离和次数限制。', - zhangjinyun:'张瑾云', - dchuizhi:'蕙质', - dchuizhi_info:'准备阶段,你可以选择是否弃置任意张手牌,然后将手牌摸至与全场手牌数最多的角色相同(至少摸一张,至多摸五张)。', - dcjijiao:'继椒', - dcjijiao_info:'限定技。出牌阶段,你可以令一名角色获得所有弃牌堆中你于本局游戏内使用或弃置过的普通锦囊牌,且这些牌不能被【无懈可击】响应。一名角色的回合结束后,若本回合牌堆洗过牌或有角色死亡,你重置〖继椒〗。', - duanqiaoxiao:'段巧笑', - dccaizhuang:'彩妆', - dccaizhuang_info:'出牌阶段限一次,你可以弃置任意张牌。然后若你手牌中的花色数小于你以此法弃置的牌的花色数,你摸一张牌并重复此流程。', - dchuayi:'华衣', - dchuayi_info:'结束阶段,你可以判定,然后你获得如下效果直到你下回合开始时:红色,一名角色的回合结束时,你摸一张牌;黑色,当你受到伤害后,你摸两张牌。', - wu_zhugeliang:'武诸葛亮', - wu_zhugeliang_prefix:'武', - dcjincui:'尽瘁', - dcjincui_info:'锁定技。①游戏开始时,你将手牌摸至七张。②准备阶段,你将体力值回复或失去至等同于牌堆中点数为7的牌数(你的体力值最低因此调整至1)。然后你观看牌堆顶X张牌,将这些牌以任意顺序置于牌堆顶或牌堆底(X为你的体力值)。', - dcqingshi:'情势', - dcqingshi_info:'当你于出牌阶段使用牌时,若你手牌中有同名牌且你本回合未因此牌名的牌发动过该技能,你可以选择一项:1.令此牌对其中一个目标角色造成的伤害+1;2.令任意名其他角色各摸一张牌;3.摸三张牌,然后〖情势〗于本回合无效。', - dczhizhe:'智哲', - dczhizhe_clear:'invisible', - dczhizhe_info:'限定技。出牌阶段,你可以选择一张手牌并复制之。当你使用或打出此复制牌结算结束后,你获得之,然后你本回合不能再使用或打出此牌。', - ruanji:'阮籍', - dczhaowen:'昭文', - dczhaowen_tag:'昭文', - dczhaowen_info:'出牌阶段开始时,你可以展示所有手牌。然后你于本回合获得如下效果:1.你可以将其中一张黑色牌当做任意一张普通锦囊牌使用(每回合每种牌名限一次);2.当你使用其中的一张红色牌时,你摸一张牌。', - dcjiudun:'酒遁', - dcjiudun_info:'①以你为目标的【酒】(使用方法①)的作用效果改为“目标对应的角色使用的下一张【杀】的伤害基数+1”。②当你成为其他角色使用黑色牌的目标后,若你:未处于【酒】状态,你可以摸一张牌并视为使用一张【酒】;处于【酒】状态,你可以弃置一张手牌令此牌对你无效。', - ganfurenmifuren:'甘夫人糜夫人', - dcchanjuan:'婵娟', - dcchanjuan_info:'每种牌名限两次。当你使用手牌中仅指定单一目标的【杀】或普通锦囊牌结算结束后,你可以视为使用一张名称和属性均相同的牌。若这两张牌指定的目标完全相同,你摸一张牌。', - dcxunbie:'殉别', - dcxunbie_info:'限定技。当你进入濒死状态时,你可以将此武将牌替换为“甘夫人”或“糜夫人”(不能选择已在场上的武将)。然后回复至1点体力并防止所有伤害直到你的下一个回合结束。', - dc_mifuren:'糜夫人', - dcguixiu:'闺秀', - dcguixiu_info:'锁定技。①回合开始时,若你于本局游戏未发动过〖闺秀①〗,你摸两张牌。②当你发动〖存嗣〗后,你回复1点体力。', - dccunsi:'存嗣', - dccunsi_info:'限定技。出牌阶段,你可以令一名角色获得〖勇决〗。若该角色不为你,你摸两张牌。', - dcyongjue:'勇决', - dcyongjue_info:'当你于出牌阶段使用第一张【杀】时,你可以选择一项:1.令此【杀】不计入次数;2.获得此牌。', - dc_ganfuren:'甘夫人', - dcshushen:'淑慎', - dcshushen_info:'当你回复1点体力后,你可以选择一名其他角色并选择一项:1.令其回复1点体力;2.你与其各摸一张牌。', - dcshenzhi:'神智', - dcshenzhi_info:'准备阶段,若你的手牌数大于体力值,你可以弃置一张手牌,然后回复1点体力。', - dc_duyu:'杜预', - dcjianguo:'谏国', - dcjianguo_info:'出牌阶段各限一次。你可以选择一名角色并选择一项:1.令其摸一张牌,然后其弃置一半的手牌;2.令其弃置一张牌,然后其摸等同于手牌数一半的牌(均向上取整)。', - dcdyqingshi:'倾势', - dcdyqingshi_info:'当你于回合内使用【杀】或普通锦囊牌指定第一个目标后,若目标角色包括其他角色且此牌为你本回合使用的第X张牌,你可以对其中一名不为你的目标角色造成1点伤害(X为你的手牌数)。', - sunlingluan:'孙翎鸾', - dclingyue:'聆乐', - dclingyue_info:'锁定技。一名角色于一轮内首次造成伤害后,你摸一张牌。若此时是该角色回合外,则改为摸X张牌(X为本回合全场造成的伤害值)。', - dcpandi:'盻睇', - dcpandi_info:'出牌阶段,你可以选择一名本回合内未造成过伤害的角色。你本阶段内使用的下一张牌改为以该角色为基准判断使用目标合法性,且使用者改为该角色。', - zhoubuyi:'周不疑', - dcshiji:'十计', - dcshiji_info:'一名角色的结束阶段,若其本回合未造成过伤害,你可以声明一种本轮未以此法声明过的普通锦囊牌,然后其可以将一张牌当你声明的牌使用(其不是此牌的合法目标)。', - dcsilun:'四论', - dcsilun_info:'准备阶段或当你受到伤害后,你可以摸四张牌,然后将四张牌依次置于场上或牌堆两端(对所有角色可见)。装备区牌数因此变化的角色复原其武将牌。', - dc_wangjun:'王濬', - dcmianyao:'免徭', - dcmianyao_info:'摸牌阶段结束时,你可以展示手牌中点数最小的一张牌并将此牌随机插入牌堆中。然后你于此回合结束时摸等同于此牌点数的牌。', - dcchangqu:'长驱', - dcchangqu_info:'出牌阶段限一次。你可以开一艘战舰(你从你的上家或下家开始选择任意名座位连续的其他角色,且起点角色获得“战舰”标记)。这些角色按照你选择的顺序依次执行:{若其有本次获得的“战舰”,其选择一项:1.交给你X张手牌,然后将“战舰”移动给你选择的下一名目标角色;2.令其下次受到的属性伤害值+X,然后横置(X为本次〖长驱〗中选项一被选择过的次数且至少为1)。}。', - dctongye:'统业', - dctongye_info:'锁定技。游戏开始时或一名角色死亡后,若场上势力数:不大于4,你的手牌上限+3;不大于3,你的攻击范围+3;不大于2,你使用【杀】的次数上限+3;不大于1,你摸牌阶段额定摸牌数+3。', - tianshangyi:'田尚衣', - dcposuo:'婆娑', - dcposuo_info:'出牌阶段,若你本阶段未对其他角色造成过伤害,则你可以将一张你本阶段未以此法使用过的花色的手牌当作任意一张存在于游戏的同花色伤害牌使用。', - dcxiaoren:'绡刃', - dcxiaoren_info:'每回合限一次,当你造成伤害后,你可以进行判定,若结果为:红色,你可以令一名角色回复1点体力,然后若其满体力,其摸一张牌;黑色,你对受伤角色的上家或下家造成1点伤害,然后你可以重复此流程直到未能执行此项或有角色进入濒死状态。', - dc_daxiaoqiao:'新杀大乔小乔', - dc_daxiaoqiao_prefix:'新杀', - dcxingwu:'星舞', - dcxingwu_info:'弃牌阶段开始时,你可以将一张手牌置于武将牌上,称为“星舞”。若你的“星舞”牌达到三张,则你可移去三张“星舞”,弃置一名其他角色装备区里的所有牌,然后对其造成X点伤害(X为移去的“星舞”牌的花色数,若为女性角色则改为1点伤害)。', - dcluoyan:'落雁', - dcluoyan_info:'锁定技,若你有“星舞”牌,你视为拥有技能〖天香〗和〖流离〗。', - dc_xiahouba:'新杀夏侯霸', - dc_xiahouba_prefix:'新杀', - old_huangfusong:'新杀皇甫嵩', - old_huangfusong_prefix:'新杀', - dc_sp_machao:'群马超', - dc_sp_machao_prefix:'群', - dc_shixie:'新杀士燮', - dc_shixie_prefix:'新杀', - dc_guansuo:'新杀关索', - dc_guansuo_prefix:'新杀', - dc_zhaoxiang:'新杀赵襄', - dc_zhaoxiang_prefix:'新杀', - dc_xujing:'许靖', - dcshangyu:'赏誉', - dcshangyu_tag:'赏誉', - dcshangyu_info:'锁定技。游戏开始时,你获得一张【杀】并记录之,并可以将此牌交给一名角色。然后你获得如下效果:1.当一名角色使用此牌造成伤害后,你与其各摸一张牌;2.当此牌进入弃牌堆后,你将此牌交给一名本回合未以此法得到过此牌的角色。', - dccaixia:'才瑕', - dccaixia_info:'当你造成或受到伤害后,若你没有“瑕”,你可以摸至多X张牌并获得X枚“瑕”,然后当你使用牌时,移去1枚“瑕”(X为本局游戏总角色数且至多为5)。', - wu_luxun:'武陆逊', - wu_luxun_prefix:'武', - dcxiongmu:'雄幕', - dcxiongmu_tag:'雄幕', - dcxiongmu_info:'①一轮游戏开始时,你可以将手牌摸至体力上限(若手牌数不小于体力上限则跳过),然后将任意张牌随机置入牌堆,从牌堆或弃牌堆中获得等量的点数为8的牌,且这些牌不计入手牌上限。②当你于一回合首次受到伤害时,若你的手牌数不大于你的体力值,此伤害-1。', - dczhangcai:'彰才', - dczhangcai_info:'当你使用或打出点数为8的牌时,你可以摸X张牌(X为你手牌区里点数为8的牌数且至少为1)。', - dcruxian:'儒贤', - dcruxian_info:'限定技。出牌阶段,你可以令你〖彰才〗的点数限制取消,且摸牌数改为等同于你手牌区内与此牌点数相同的牌数且至少为1,直到你的下回合开始。', - malingli:'马伶俐', - dclima:'骊马', - dclima_info:'锁定技。你计算至其他角色的距离-X(X为场上的坐骑牌数且至少为1)。', - dcxiaoyin:'硝引', - dcxiaoyin_info:'①准备阶段,你可以亮出牌堆顶的Y张牌(Y为你距离1以内的角色数),获得其中的红色牌,将其中任意张黑色牌置于等量名座次连续的其他角色的武将牌上,称为“硝引”。②当一名有“硝引”牌的角色受到伤害时,若此伤害为:火焰伤害,来源可以弃置一张其“硝引”牌包含的类型的牌,将其“硝引”置入弃牌堆,令此伤害+1;非火焰伤害,来源可以获得其“硝引”牌,将此伤害改为火焰伤害。', - dchuahuo:'花火', - dchuahuo_info:'出牌阶段限一次。你可以将一张红色手牌当不计入次数的火【杀】使用。然后当你使用此牌指定第一个目标后,若目标角色有“硝引”牌,你可以将此【杀】的目标改为所有有“硝引”牌的角色。', - caoyi:'曹轶', - dcmiyi:'蜜饴', - dcmiyi_info:'准备阶段,你可以选择一项:1.回复1点体力;2.受到你造成的1点伤害。然后你令任意名角色执行该项。若如此做,这些角色于结束阶段执行另一项。', - dcyinjun:'寅君', - dcyinjun_info:'当你使用对应实体牌均为你的手牌的【杀】或锦囊牌结算结束后,若此牌目标为1,你可以视为对该目标使用一张无伤害来源的【杀】。然后若你本回合发动〖寅君〗的次数大于你的体力值,〖寅君〗失效直到回合结束。', - zhugeruoxue:'诸葛若雪', - dcqiongying:'琼英', - dcqiongying_info:'出牌阶段限一次。你可以移动场上的一张牌,然后你弃置一张与此牌花色相同的手牌(若没有该花色的手牌则改为展示所有手牌)。', - dcnuanhui:'暖惠', - dcnuanhui_info:'结束阶段,你可以选择一名装备区有牌的角色,其可以视为依次使用X张基本牌(X为其装备区牌数且至少为1)。若其此次以此法使用了同名牌,其弃置装备区里的所有牌。', - zhangjian:'张臶', - dc_zj_a:'技能', - dc_zj_a_info:'锁定技。当你受到牌造成的伤害时,若此牌有点数,则你将此伤害值改为此牌点数,否则你防止此伤害。', - dc_zj_b:'技能', - dc_zj_b_info:'结束阶段,你可以弃置所有牌并令一名其他角色获得〖技能〗直到你的下个回合开始。', - dc_sb_lusu:'新杀谋鲁肃', - dc_sb_lusu_prefix:'新杀谋', - dcsbmingshi:'明势', - dcsbmingshi_info:'摸牌阶段,你可以多摸两张牌,然后展示三张牌并令一名其他角色选择获得其中的一张牌。', - dcsbmengmou:'盟谋', - dcsbmengmou_info:'转换技,每回合每项各限一次,当你得到其他角色的牌后,或其他角色得到你的牌后:阴,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力;阳,你可令该角色打出至多X张【杀】,然后其失去Y点体力。(X为你的体力上限,Y为X-其打出【杀】数)', - dc_sb_zhouyu:'新杀谋周瑜', - dc_sb_zhouyu_prefix:'新杀谋', - dcsbronghuo:'融火', - dcsbronghuo_info:'锁定技,当你使用火【杀】或【火攻】时,此牌伤害基值改为场上势力数。', - dcsbyingmou:'英谋', - dcsbyingmou_info:'转换技,每回合限一次,当你使用牌指定第一个目标后,你可以选择一名目标角色:阴,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】;阳,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。', - caoxian:'曹宪', - dclingxi:'灵犀', - dclingxi_info:'出牌阶段开始和结束时,你可以将至多X张牌称为“翼”置于你的武将牌上(X为你的体力上限)。当你失去武将牌上的“翼”时,你将手牌数调整至Y张(Y为你武将牌上的“翼”所含有的花色数的两倍)。', - dczhifou:'知否', - dczhifou_info:'当你使用牌结算完毕后,你可以移去至少X张武将牌上的“翼”(X为本回合此前发动此技能的次数+1),然后选择一名角色并选择一项令其执行(每个选项每回合限选择一次):①将一张牌称为“翼”置于你的武将牌上;②弃置两张牌;③失去1点体力。', - dc_qinghegongzhu:'新杀清河公主', - dc_qinghegongzhu_prefix:'新杀', - dczhangji:'长姬', - dczhangji_info:'锁定技,一名角色使用多目标牌时,若你是此牌的目标之一,则你先结算此牌的效果,然后你摸X张牌(X为此牌的其他目标数)。', - dczengou:'谮构', - dczengou_info:'出牌阶段限一次,你可以将至多体力上限张牌称为“谮构”交给一名其他角色并摸等量张牌。若如此做,其下次体力值增加或使用牌结算完毕后,其展示所有手牌,然后失去Y点体力(Y为其手牌中的“谮构”牌数)。', - bailingyun:'柏灵筠', - dclinghui:'灵慧', - dclinghui_info:'一名角色的结束阶段,若当前回合角色为你或本回合有角色进入过濒死状态,则你可以观看牌堆顶的三张牌,然后你可以使用其中一张牌并随机获得其中一张剩余牌。', - dcxiace:'黠策', - dcxiace_info:'每回合每项各限一次。当你造成/受到伤害后,你可以弃置一张牌并回复1点体力/令一名其他角色的非锁定技于本回合失效。', - dcyuxin:'御心', - dcyuxin_info:'限定技,一名角色进入濒死状态时,你可以令其将体力回复至X点(X为1,若该角色不为你则X为你的体力值)。', - zhugemengxue:'诸葛梦雪', - dcjichun:'寄春', - dcjichun_info:'出牌阶段限一次,你可以展示一张手牌并选择一项:①将此牌交给一名手牌数小于你的角色,然后摸X张牌。②弃置此牌并弃置一名手牌数大于你的角色区域里至多X张牌。(X为此牌牌名字数)', - dchanying:'寒英', - dchanying_info:'准备阶段,你可以展示牌堆里的一张非赠物装备牌,然后令一名手牌数等于你的角色使用此牌。', - huzun:'胡遵', - dczhantao:'斩涛', - dczhantao_info:'当你或你攻击范围内的角色受到伤害后,若你不为伤害来源,你可以判定,若造成此伤害的渠道为牌且此牌有点数且判定结果点数大于此牌的点数,你视为对来源使用一张【杀】。', - dcanjing:'安境', - dcanjing_info:'每回合限一次。当你造成伤害后,你可以令至多X名已受伤的角色各摸一张牌,然后其中体力值最少的角色回复1点体力(X为你本局游戏发动〖安境〗的次数)。', - cuimao:'崔琰毛玠', - zhengbi:'征辟', - zhengbi_info:'出牌阶段开始时,你可以选择一名其他角色并选择一项:①本阶段结束时,若其本阶段得到过牌,则你获得其手牌区和装备区各一张牌;②将一张基本牌交给该角色,然后其交给你一张非基本牌或两张基本牌。', - fengying:'奉迎', - fengying_info:'限定技,出牌阶段,你可以弃置所有手牌。若如此做,你于本回合结束后进行一个额外回合,此额外回合开始时,若你的体力值为全场最低,则你将手牌数摸至体力上限。', - lvfan:'吕范', - diaodu:'调度', - diaodu_info:'出牌阶段开始时,或当你发动〖典财〗后,你可以获得一名距离不大于1的一名角色A装备区里的一张牌,然后你将此牌交给另一名角色B,然后B选择是否使用此牌,若B使用/不使用,则你/B摸一张牌。', - diancai:'典财', - diancai_info:'其他角色的出牌阶段结束时,若你于此阶段失去了至少X张牌,则你可以将手牌摸至体力上限(X为你的体力值且X至多为5)。', - chendong:'陈武董袭', - dcduanxie:'断绁', - dcduanxie_info:'出牌阶段限一次,你可以令一名其他角色横置,然后你横置。', - dc_sb_simayi:'新杀谋司马懿', - dc_sb_simayi_prefix:'新杀谋', - dcsbquanmou:'权谋', - dcsbquanmou_info:'转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。阴:当你于本阶段内下次对其造成伤害时,取消之;阳:当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。', - dcsbpingliao:'平辽', - dcsbpingliao_info:'锁定技。当你声明使用【杀】时,你令此【杀】的目标对其他角色不可见,且你令攻击范围内的其他角色依次选择是否打出一张红色基本牌。所有角色选择完成后,此牌的目标角色中没有以此法打出牌的角色本回合内无法使用或打出手牌;若有不为此牌目标的角色以此法打出了牌,则你摸两张牌,且你本回合使用【杀】的次数上限+1。', - caofang:'曹芳', - dczhimin:'置民', - dczhimin_tag:'民', - dczhimin_info:'锁定技。①一轮游戏开始时,你选择至多X名其他角色(X为你的体力值),获得这些角色各自手牌中的随机一张点数最小的牌。②当你于你的回合外得到牌后,你将这些牌标记为“民”。③当你失去“民”后,你将手牌补至体力上限。', - dcjujian:'拒谏', - dcjujian_info:'主公技。出牌阶段限一次,你可以令一名其他魏势力角色摸一张牌,然后你令其于本轮内使用的普通锦囊牌对你无效。', + dclingyin_info: + "出牌阶段开始时,你可以选择至多X张“妄”(X为游戏轮数),若这些牌以外的“妄”中不存在颜色不同的牌,则你于本回合对其他角色造成的伤害+1,且可以将一张武器牌或防具牌当【决斗】使用。你获得这些牌。", + dcliying: "俐影", + dcliying_info: + "每回合限一次。当你于摸牌阶段外得到牌后,你可以将这些牌中的任意张交给一名其他角色,然后摸一张牌。", + huanfan: "桓范", + dcjianzheng: "谏诤", + dcjianzheng_info: + "出牌阶段限一次。你可以观看一名其他角色的手牌,然后若其中有你可以使用的手牌,你获得并使用其中一张。若你以此法使用牌指定了其为目标,你令你与其横置,然后其观看你的手牌。", + dcfumou: "腹谋", + dcfumou_info: + "当你受到伤害后,你可以令至多X名角色从你开始逆时针依次选择一项:1.移动场上的一张牌;2.弃置所有手牌并摸两张牌;3.弃置装备区里的所有牌并回复1点体力(X为你已损失的体力值)。", + chentai: "陈泰", + dcctjiuxian: "救陷", + dcctjiuxian_info: + "出牌阶段限一次。你可以重铸一半数量的手牌(向上取整),然后视为使用一张【决斗】。当此牌对目标角色造成伤害后,你可以令其攻击范围内的一名其他角色回复1点体力。", + dcchenyong: "沉勇", + dcchenyong_info: "结束阶段,你可以摸X张牌(X为本回合你使用过的牌的类型数)。", + sunyu: "孙瑜", + dcquanshou: "劝守", + dcquanshou_info: + "一名角色的回合开始时,若其手牌数不大于其体力上限,你可以令其选择一项:1.将手牌摸至体力上限,然后本回合使用【杀】的次数上限-1(至多摸五张);2.其本回合使用牌被抵消后,你摸一张牌。", + dcshexue: "设学", + dcshexue_info: + "①出牌阶段开始时,你可以将一张牌当做上回合的角色于其出牌阶段内使用的一张基本牌或普通锦囊牌使用。②出牌阶段结束时,你可以令下回合的角色于其出牌阶段开始时可以将一张牌当做你于此阶段内使用的一张基本牌或普通锦囊牌使用(一名角色因〖设学〗使用的牌均无距离和次数限制)。", + xizheng: "郤正", + dcdanyi: "耽意", + dcdanyi_info: + "当你使用牌指定第一个目标后,你可以摸X张牌(X为此牌目标数与你使用的上一张牌相同的目标数)。", + dcwencan: "文灿", + dcwencan_info: + "出牌阶段限一次。你可以选择至多两名体力值不同的其他角色,这些角色依次选择一项:1.弃置两张花色不同的牌;2.本回合你对其使用牌无距离和次数限制。", + zhangjinyun: "张瑾云", + dchuizhi: "蕙质", + dchuizhi_info: + "准备阶段,你可以选择是否弃置任意张手牌,然后将手牌摸至与全场手牌数最多的角色相同(至少摸一张,至多摸五张)。", + dcjijiao: "继椒", + dcjijiao_info: + "限定技。出牌阶段,你可以令一名角色获得所有弃牌堆中你于本局游戏内使用或弃置过的普通锦囊牌,且这些牌不能被【无懈可击】响应。一名角色的回合结束后,若本回合牌堆洗过牌或有角色死亡,你重置〖继椒〗。", + duanqiaoxiao: "段巧笑", + dccaizhuang: "彩妆", + dccaizhuang_info: + "出牌阶段限一次,你可以弃置任意张牌。然后若你手牌中的花色数小于你以此法弃置的牌的花色数,你摸一张牌并重复此流程。", + dchuayi: "华衣", + dchuayi_info: + "结束阶段,你可以判定,然后你获得如下效果直到你下回合开始时:红色,一名角色的回合结束时,你摸一张牌;黑色,当你受到伤害后,你摸两张牌。", + wu_zhugeliang: "武诸葛亮", + wu_zhugeliang_prefix: "武", + dcjincui: "尽瘁", + dcjincui_info: + "锁定技。①游戏开始时,你将手牌摸至七张。②准备阶段,你将体力值回复或失去至等同于牌堆中点数为7的牌数(你的体力值最低因此调整至1)。然后你观看牌堆顶X张牌,将这些牌以任意顺序置于牌堆顶或牌堆底(X为你的体力值)。", + dcqingshi: "情势", + dcqingshi_info: + "当你于出牌阶段使用牌时,若你手牌中有同名牌且你本回合未因此牌名的牌发动过该技能,你可以选择一项:1.令此牌对其中一个目标角色造成的伤害+1;2.令任意名其他角色各摸一张牌;3.摸三张牌,然后〖情势〗于本回合无效。", + dczhizhe: "智哲", + dczhizhe_clear: "invisible", + dczhizhe_info: + "限定技。出牌阶段,你可以选择一张手牌并复制之。当你使用或打出此复制牌结算结束后,你获得之,然后你本回合不能再使用或打出此牌。", + ruanji: "阮籍", + dczhaowen: "昭文", + dczhaowen_tag: "昭文", + dczhaowen_info: + "出牌阶段开始时,你可以展示所有手牌。然后你于本回合获得如下效果:1.你可以将其中一张黑色牌当做任意一张普通锦囊牌使用(每回合每种牌名限一次);2.当你使用其中的一张红色牌时,你摸一张牌。", + dcjiudun: "酒遁", + dcjiudun_info: + "①以你为目标的【酒】(使用方法①)的作用效果改为“目标对应的角色使用的下一张【杀】的伤害基数+1”。②当你成为其他角色使用黑色牌的目标后,若你:未处于【酒】状态,你可以摸一张牌并视为使用一张【酒】;处于【酒】状态,你可以弃置一张手牌令此牌对你无效。", + ganfurenmifuren: "甘夫人糜夫人", + dcchanjuan: "婵娟", + dcchanjuan_info: + "每种牌名限两次。当你使用手牌中仅指定单一目标的【杀】或普通锦囊牌结算结束后,你可以视为使用一张名称和属性均相同的牌。若这两张牌指定的目标完全相同,你摸一张牌。", + dcxunbie: "殉别", + dcxunbie_info: + "限定技。当你进入濒死状态时,你可以将此武将牌替换为“甘夫人”或“糜夫人”(不能选择已在场上的武将)。然后回复至1点体力并防止所有伤害直到你的下一个回合结束。", + dc_mifuren: "糜夫人", + dcguixiu: "闺秀", + dcguixiu_info: + "锁定技。①回合开始时,若你于本局游戏未发动过〖闺秀①〗,你摸两张牌。②当你发动〖存嗣〗后,你回复1点体力。", + dccunsi: "存嗣", + dccunsi_info: "限定技。出牌阶段,你可以令一名角色获得〖勇决〗。若该角色不为你,你摸两张牌。", + dcyongjue: "勇决", + dcyongjue_info: + "当你于出牌阶段使用第一张【杀】时,你可以选择一项:1.令此【杀】不计入次数;2.获得此牌。", + dc_ganfuren: "甘夫人", + dcshushen: "淑慎", + dcshushen_info: + "当你回复1点体力后,你可以选择一名其他角色并选择一项:1.令其回复1点体力;2.你与其各摸一张牌。", + dcshenzhi: "神智", + dcshenzhi_info: "准备阶段,若你的手牌数大于体力值,你可以弃置一张手牌,然后回复1点体力。", + dc_duyu: "杜预", + dcjianguo: "谏国", + dcjianguo_info: + "出牌阶段各限一次。你可以选择一名角色并选择一项:1.令其摸一张牌,然后其弃置一半的手牌;2.令其弃置一张牌,然后其摸等同于手牌数一半的牌(均向上取整)。", + dcdyqingshi: "倾势", + dcdyqingshi_info: + "当你于回合内使用【杀】或普通锦囊牌指定第一个目标后,若目标角色包括其他角色且此牌为你本回合使用的第X张牌,你可以对其中一名不为你的目标角色造成1点伤害(X为你的手牌数)。", + sunlingluan: "孙翎鸾", + dclingyue: "聆乐", + dclingyue_info: + "锁定技。一名角色于一轮内首次造成伤害后,你摸一张牌。若此时是该角色回合外,则改为摸X张牌(X为本回合全场造成的伤害值)。", + dcpandi: "盻睇", + dcpandi_info: + "出牌阶段,你可以选择一名本回合内未造成过伤害的角色。你本阶段内使用的下一张牌改为以该角色为基准判断使用目标合法性,且使用者改为该角色。", + zhoubuyi: "周不疑", + dcshiji: "十计", + dcshiji_info: + "一名角色的结束阶段,若其本回合未造成过伤害,你可以声明一种本轮未以此法声明过的普通锦囊牌,然后其可以将一张牌当你声明的牌使用(其不是此牌的合法目标)。", + dcsilun: "四论", + dcsilun_info: + "准备阶段或当你受到伤害后,你可以摸四张牌,然后将四张牌依次置于场上或牌堆两端(对所有角色可见)。装备区牌数因此变化的角色复原其武将牌。", + dc_wangjun: "王濬", + dcmianyao: "免徭", + dcmianyao_info: + "摸牌阶段结束时,你可以展示手牌中点数最小的一张牌并将此牌随机插入牌堆中。然后你于此回合结束时摸等同于此牌点数的牌。", + dcchangqu: "长驱", + dcchangqu_info: + "出牌阶段限一次。你可以开一艘战舰(你从你的上家或下家开始选择任意名座位连续的其他角色,且起点角色获得“战舰”标记)。这些角色按照你选择的顺序依次执行:{若其有本次获得的“战舰”,其选择一项:1.交给你X张手牌,然后将“战舰”移动给你选择的下一名目标角色;2.令其下次受到的属性伤害值+X,然后横置(X为本次〖长驱〗中选项一被选择过的次数且至少为1)。}。", + dctongye: "统业", + dctongye_info: + "锁定技。游戏开始时或一名角色死亡后,若场上势力数:不大于4,你的手牌上限+3;不大于3,你的攻击范围+3;不大于2,你使用【杀】的次数上限+3;不大于1,你摸牌阶段额定摸牌数+3。", + tianshangyi: "田尚衣", + dcposuo: "婆娑", + dcposuo_info: + "出牌阶段,若你本阶段未对其他角色造成过伤害,则你可以将一张你本阶段未以此法使用过的花色的手牌当作任意一张存在于游戏的同花色伤害牌使用。", + dcxiaoren: "绡刃", + dcxiaoren_info: + "每回合限一次,当你造成伤害后,你可以进行判定,若结果为:红色,你可以令一名角色回复1点体力,然后若其满体力,其摸一张牌;黑色,你对受伤角色的上家或下家造成1点伤害,然后你可以重复此流程直到未能执行此项或有角色进入濒死状态。", + dc_daxiaoqiao: "新杀大乔小乔", + dc_daxiaoqiao_prefix: "新杀", + dcxingwu: "星舞", + dcxingwu_info: + "弃牌阶段开始时,你可以将一张手牌置于武将牌上,称为“星舞”。若你的“星舞”牌达到三张,则你可移去三张“星舞”,弃置一名其他角色装备区里的所有牌,然后对其造成X点伤害(X为移去的“星舞”牌的花色数,若为女性角色则改为1点伤害)。", + dcluoyan: "落雁", + dcluoyan_info: "锁定技,若你有“星舞”牌,你视为拥有技能〖天香〗和〖流离〗。", + dc_xiahouba: "新杀夏侯霸", + dc_xiahouba_prefix: "新杀", + old_huangfusong: "新杀皇甫嵩", + old_huangfusong_prefix: "新杀", + dc_sp_machao: "群马超", + dc_sp_machao_prefix: "群", + dc_shixie: "新杀士燮", + dc_shixie_prefix: "新杀", + dc_guansuo: "新杀关索", + dc_guansuo_prefix: "新杀", + dc_zhaoxiang: "新杀赵襄", + dc_zhaoxiang_prefix: "新杀", + dc_xujing: "许靖", + dcshangyu: "赏誉", + dcshangyu_tag: "赏誉", + dcshangyu_info: + "锁定技。游戏开始时,你获得一张【杀】并记录之,并可以将此牌交给一名角色。然后你获得如下效果:1.当一名角色使用此牌造成伤害后,你与其各摸一张牌;2.当此牌进入弃牌堆后,你将此牌交给一名本回合未以此法得到过此牌的角色。", + dccaixia: "才瑕", + dccaixia_info: + "当你造成或受到伤害后,若你没有“瑕”,你可以摸至多X张牌并获得X枚“瑕”,然后当你使用牌时,移去1枚“瑕”(X为本局游戏总角色数且至多为5)。", + wu_luxun: "武陆逊", + wu_luxun_prefix: "武", + dcxiongmu: "雄幕", + dcxiongmu_tag: "雄幕", + dcxiongmu_info: + "①一轮游戏开始时,你可以将手牌摸至体力上限(若手牌数不小于体力上限则跳过),然后将任意张牌随机置入牌堆,从牌堆或弃牌堆中获得等量的点数为8的牌,且这些牌不计入手牌上限。②当你于一回合首次受到伤害时,若你的手牌数不大于你的体力值,此伤害-1。", + dczhangcai: "彰才", + dczhangcai_info: + "当你使用或打出点数为8的牌时,你可以摸X张牌(X为你手牌区里点数为8的牌数且至少为1)。", + dcruxian: "儒贤", + dcruxian_info: + "限定技。出牌阶段,你可以令你〖彰才〗的点数限制取消,且摸牌数改为等同于你手牌区内与此牌点数相同的牌数且至少为1,直到你的下回合开始。", + malingli: "马伶俐", + dclima: "骊马", + dclima_info: "锁定技。你计算至其他角色的距离-X(X为场上的坐骑牌数且至少为1)。", + dcxiaoyin: "硝引", + dcxiaoyin_info: + "①准备阶段,你可以亮出牌堆顶的Y张牌(Y为你距离1以内的角色数),获得其中的红色牌,将其中任意张黑色牌置于等量名座次连续的其他角色的武将牌上,称为“硝引”。②当一名有“硝引”牌的角色受到伤害时,若此伤害为:火焰伤害,来源可以弃置其“硝引”牌包含的类型的牌,将一张对应的“硝引”置入弃牌堆,令此伤害+1;非火焰伤害,来源可以获得一张“硝引”牌,将此伤害改为火焰伤害。", + dchuahuo: "花火", + dchuahuo_info: + "出牌阶段限一次。你可以将一张红色手牌当不计入次数的火【杀】使用。然后当你使用此牌指定第一个目标后,若目标角色有“硝引”牌,你可以将此【杀】的目标改为所有有“硝引”牌的角色。", + caoyi: "曹轶", + dcmiyi: "蜜饴", + dcmiyi_info: + "准备阶段,你可以选择一项:1.回复1点体力;2.受到你造成的1点伤害。然后你令任意名角色执行该项。若如此做,这些角色于结束阶段执行另一项。", + dcyinjun: "寅君", + dcyinjun_info: + "当你使用对应实体牌均为你的手牌的【杀】或锦囊牌结算结束后,若此牌目标为1,你可以视为对该目标使用一张无伤害来源的【杀】。然后若你本回合发动〖寅君〗的次数大于你的体力值,〖寅君〗失效直到回合结束。", + zhugeruoxue: "诸葛若雪", + dcqiongying: "琼英", + dcqiongying_info: + "出牌阶段限一次。你可以移动场上的一张牌,然后你弃置一张与此牌花色相同的手牌(若没有该花色的手牌则改为展示所有手牌)。", + dcnuanhui: "暖惠", + dcnuanhui_info: + "结束阶段,你可以选择一名装备区有牌的角色,其可以视为依次使用X张基本牌(X为其装备区牌数且至少为1)。若其此次以此法使用了同名牌,其弃置装备区里的所有牌。", + zhangjian: "张臶", + dc_zj_a: "技能", + dc_zj_a_info: + "锁定技。当你受到牌造成的伤害时,若此牌有点数,则你将此伤害值改为此牌点数,否则你防止此伤害。", + dc_zj_b: "技能", + dc_zj_b_info: "结束阶段,你可以弃置所有牌并令一名其他角色获得〖技能〗直到你的下个回合开始。", + dc_sb_lusu: "新杀谋鲁肃", + dc_sb_lusu_prefix: "新杀谋", + dcsbmingshi: "明势", + dcsbmingshi_info: + "摸牌阶段,你可以多摸两张牌,然后展示三张牌并令一名其他角色选择获得其中的一张牌。", + dcsbmengmou: "盟谋", + dcsbmengmou_info: + "转换技,每回合每项各限一次,当你得到其他角色的牌后,或其他角色得到你的牌后:阴,你可以令该角色使用至多X张【杀】,且其每以此法造成1点伤害,其回复1点体力;阳,你可令该角色打出至多X张【杀】,然后其失去Y点体力。(X为你的体力上限,Y为X-其打出【杀】数)", + dc_sb_zhouyu: "新杀谋周瑜", + dc_sb_zhouyu_prefix: "新杀谋", + dcsbronghuo: "融火", + dcsbronghuo_info: "锁定技,当你使用火【杀】或【火攻】时,此牌伤害基值改为场上势力数。", + dcsbyingmou: "英谋", + dcsbyingmou_info: + "转换技,每回合限一次,当你使用牌指定其他角色为目标后,你可以选择一名目标角色:阴,你将手牌数摸至与其相同(至多摸五张),然后视为对其使用一张【火攻】;阳,令一名手牌数为全场最大的角色对其使用手牌中所有的【杀】和伤害类锦囊牌(若其没有可使用的牌则将手牌数弃至与你相同)。", + caoxian: "曹宪", + dclingxi: "灵犀", + dclingxi_info: + "出牌阶段开始和结束时,你可以将至多X张牌称为“翼”置于你的武将牌上(X为你的体力上限)。当你失去武将牌上的“翼”时,你将手牌数调整至Y张(Y为你武将牌上的“翼”所含有的花色数的两倍)。", + dczhifou: "知否", + dczhifou_info: + "当你使用牌结算完毕后,你可以移去至少X张武将牌上的“翼”(X为本回合此前发动此技能的次数+1),然后选择一名角色并选择一项令其执行(每个选项每回合限选择一次):①将一张牌称为“翼”置于你的武将牌上;②弃置两张牌;③失去1点体力。", + dc_qinghegongzhu: "新杀清河公主", + dc_qinghegongzhu_prefix: "新杀", + dczhangji: "长姬", + dczhangji_info: + "锁定技,一名角色使用多目标牌时,若你是此牌的目标之一,则你先结算此牌的效果,然后你摸X张牌(X为此牌的其他目标数)。", + dczengou: "谮构", + dczengou_info: + "出牌阶段限一次,你可以将至多体力上限张牌称为“谮构”交给一名其他角色并摸等量张牌。若如此做,其下次体力值增加或使用牌结算完毕后,其展示所有手牌,然后失去Y点体力(Y为其手牌中的“谮构”牌数)。", + bailingyun: "柏灵筠", + dclinghui: "灵慧", + dclinghui_info: + "一名角色的结束阶段,若当前回合角色为你或本回合有角色进入过濒死状态,则你可以观看牌堆顶的三张牌,然后你可以使用其中一张牌并随机获得其中一张剩余牌。", + dcxiace: "黠策", + dcxiace_info: + "每回合每项各限一次。当你造成/受到伤害后,你可以弃置一张牌并回复1点体力/令一名其他角色的非锁定技于本回合失效。", + dcyuxin: "御心", + dcyuxin_info: + "限定技,一名角色进入濒死状态时,你可以令其将体力回复至X点(X为1,若该角色不为你则X为你的体力值)。", + zhugemengxue: "诸葛梦雪", + dcjichun: "寄春", + dcjichun_info: + "出牌阶段限一次,你可以展示一张牌并选择一项:①将此牌交给一名手牌数小于你的角色,然后摸X张牌。②弃置此牌并弃置一名手牌数大于你的角色区域里至多X张牌。(X为此牌牌名字数)", + dchanying: "寒英", + dchanying_info: + "准备阶段,你可以亮出牌堆里的一张非赠物装备牌,然后令一名手牌数等于你的角色使用此牌。", + huzun: "胡遵", + dczhantao: "斩涛", + dczhantao_info: + "当你或你攻击范围内的角色受到伤害后,若你不为伤害来源,你可以判定,若造成此伤害的渠道为牌且此牌有点数且判定结果点数大于此牌的点数,你视为对来源使用一张【杀】。", + dcanjing: "安境", + dcanjing_info: + "每回合限一次。当你造成伤害后,你可以令至多X名已受伤的角色各摸一张牌,然后其中体力值最少的角色回复1点体力(X为你本局游戏发动〖安境〗的次数)。", + cuimao: "崔琰毛玠", + zhengbi: "征辟", + zhengbi_info: + "出牌阶段开始时,你可以选择一名其他角色并选择一项:①本阶段结束时,若其本阶段得到过牌,则你获得其手牌区和装备区各一张牌;②将一张基本牌交给该角色,然后其交给你一张非基本牌或两张基本牌。", + fengying: "奉迎", + fengying_info: + "限定技,出牌阶段,你可以弃置所有手牌。若如此做,你于本回合结束后进行一个额外回合,此额外回合开始时,若你的体力值为全场最低,则你将手牌数摸至体力上限。", + lvfan: "吕范", + diaodu: "调度", + diaodu_info: + "出牌阶段开始时,或当你发动〖典财〗后,你可以获得一名距离不大于1的一名角色A装备区里的一张牌,然后你将此牌交给另一名角色B,然后B选择是否使用此牌,若B使用/不使用,则你/B摸一张牌。", + diancai: "典财", + diancai_info: + "其他角色的出牌阶段结束时,若你于此阶段失去了至少X张牌,则你可以将手牌摸至体力上限(X为你的体力值且X至多为5)。", + chendong: "陈武董袭", + dcduanxie: "断绁", + dcduanxie_info: "出牌阶段限一次,你可以令一名其他角色横置,然后你横置。", + dc_sb_simayi: "新杀谋司马懿", + dc_sb_simayi_prefix: "新杀谋", + dcsbquanmou: "权谋", + dcsbquanmou_info: + "转换技。出牌阶段每名角色限一次,你可以令一名攻击范围内的其他角色交给你一张牌。阴:当你于本阶段内下次对其造成伤害时,取消之;阳:当你于本阶段内下次对其造成伤害后,你可以选择除其外的至多三名其他角色,对这些角色依次造成1点伤害。", + dcsbpingliao: "平辽", + dcsbpingliao_info: + "锁定技。当你声明使用【杀】时,你令此【杀】的目标对其他角色不可见,且你令攻击范围内的其他角色依次选择是否打出一张红色基本牌。所有角色选择完成后,此牌的目标角色中没有以此法打出牌的角色本回合内无法使用或打出手牌;若有不为此牌目标的角色以此法打出了牌,则你摸两张牌,且你本回合使用【杀】的次数上限+1。", + caofang: "曹芳", + dczhimin: "置民", + dczhimin_tag: "民", + dczhimin_info: + "锁定技。①一轮游戏开始时,你选择至多X名其他角色(X为你的体力值),获得这些角色各自手牌中的随机一张点数最小的牌。②当你于你的回合外得到牌后,你将这些牌标记为“民”。③当你失去“民”后,你将手牌补至体力上限。", + dcjujian: "拒谏", + dcjujian_info: + "主公技。出牌阶段限一次,你可以令一名其他魏势力角色摸一张牌,然后你令其于本轮内使用的普通锦囊牌对你无效。", + wu_guanyu: "武关羽", + wu_guanyu_prefix: "武", + dcjuewu: "绝武", + dcjuewu_two: "2点", + dcjuewu_info: + "①每回合每种牌名限一次。你可以将一张点数为2的牌当任意伤害类牌使用(包括【水淹七军】)。②当你得到其他角色区域内的牌后,你令这些牌的点数均视为2直到你失去这些牌。", + dcwuyou: "武佑", + dcwuyou_info: + "①出牌阶段限一次。你可以选择一张手牌,从系统随机生成的五个非装备牌牌名中选择一个,令此牌的牌名与属性视为与你选择的相同。②其他角色的出牌阶段限一次。其可以交给你一张手牌,你从系统随机生成的五个非装备牌牌名中选择一个,然后交给其一张手牌,令此牌的牌名与属性视为与你选择的相同(一名角色使用〖武佑〗转化的牌无距离且无任何次数限制)。", + dcyixian: "义贤", + dcyixian_info: + "限定技。出牌阶段,你可以选择一项:⒈获得场上的所有装备牌;⒉获得弃牌堆中的所有装备牌。然后你依次选择是否令被你以此法获得牌的角色摸X张牌并回复1点体力(X为其以此法失去的牌数)。", + shuiyanqijuny: "水淹七军", + shuiyanqijuny_info: + "出牌阶段,对至多两名角色使用。目标角色受到1点雷属性伤害,然后若其:是此牌的使用者选择的第一个目标,其弃置一张牌;不是第一个目标,其摸一张牌。", + sp_zhenji: "SP甄宓", + sp_zhenji_prefix: "SP", + dcjijie: "己诫", + dcjijie_info: + "锁定技。每回合每项各限一次,其他角色于其回合外得到牌后/回复体力后,你摸等量的牌/回复等量的体力。", + dchuiji: "惠济", + dchuiji_info: + "出牌阶段限一次。你可以令一名角色摸两张牌或从牌堆中随机使用一张不为赠物的装备牌,然后若其手牌数不小于存活角色数,其视为使用一张【五谷丰登】。系统不于此牌使用准备工作结束时执行亮出牌堆顶的牌的动作,改为你令其将所有手牌置于处理区,然后令所有目标角色依次获得其中一张牌。当这些牌因执行【五谷丰登】的执行动作而置于弃牌堆后,你令其获得这些牌。", - sp2_yinyu:'隐山之玉', - sp2_huben:'百战虎贲', - sp2_shengun:'奇人异士', - sp2_huangjia:'皇家贵胄', - sp2_zhangtai:'章台春望', - sp2_jinse:'锦瑟良缘', - sp2_bizhe:'笔舌如椽', - sp2_wangzhe:'往者可荐', - sp2_doukou:'豆蔻梢头', - sp2_jichu:'计将安出', - sp2_yuxiu:'钟灵毓秀', - sp2_wumiao:'武庙', - sp2_gaoshan:'高山仰止', - sp2_qifu:'祈福', - sp2_mouding:'谋定天下', + sp2_yinyu: "隐山之玉", + sp2_huben: "百战虎贲", + sp2_shengun: "奇人异士", + sp2_huangjia: "皇家贵胄", + sp2_zhangtai: "章台春望", + sp2_jinse: "锦瑟良缘", + sp2_bizhe: "笔舌如椽", + sp2_wangzhe: "往者可荐", + sp2_doukou: "豆蔻梢头", + sp2_jichu: "计将安出", + sp2_yuxiu: "钟灵毓秀", + sp2_wumiao: "武庙", + sp2_gaoshan: "高山仰止", + sp2_qifu: "祈福", + sp2_mouding: "谋定天下", }, }; }); diff --git a/character/xianjian.js b/character/xianjian.js index e4aca3408..0df2f9431 100644 --- a/character/xianjian.js +++ b/character/xianjian.js @@ -1,4376 +1,4665 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ - return { - name:'xianjian', - character:{ - pal_lixiaoyao:['male','qun',4,['tianjian','xjyufeng']], - pal_zhaoliner:['female','wei',3,['huimeng','tianshe']], - pal_linyueru:['female','wei',3,['guiyuan','qijian']], - pal_anu:['female','wu',3,['lingdi','anwugu']], - - pal_wangxiaohu:['male','qun',4,['husha']], - pal_sumei:['female','shu',3,['sheying','dujiang','huahu']], - pal_shenqishuang:['female','wei',3,['qixia','jianzhen','binxin']], - - pal_jingtian:['male','wu',3,['sajin','jtjubao']], - pal_xuejian:['female','shu',3,['xshuangren','shenmu','duci']], - pal_longkui:['female','qun',3,['fenxing','diewu','lingyu']], - pal_zixuan:['female','wei',3,['shuiyun','wangyou','changnian']], - pal_changqing:['male','wei',4,['luanjian','ctianfu']], - - pal_nangonghuang:['male','wei',3,['zhaoyao','sheling','zhangmu']], - pal_wenhui:['female','shu',4,['huxi','longxiang']], - pal_wangpengxu:['female','shu',3,['duxinshu','feixu']], - pal_xingxuan:['male','wei',3,['feizhua','leiyu','lingxue']], - pal_leiyuange:['male','shu',4,['feng','ya','song']], - - pal_yuntianhe:['male','wu',4,['longxi','zhuyue','guanri']], - pal_hanlingsha:['female','shu',3,['tannang','tuoqiao']], - pal_liumengli:['female','wei',3,['tianxian','runxin','xjzhimeng']], - pal_murongziying:['male','wei',4,['xuanning','poyun','qianfang']], - pal_xuanxiao:['male','wei',4,['xuanyan','ningbin','xfenxin']], - - pal_jiangyunfan:['male','wei',4,['xunying','liefeng']], - pal_tangyurou:['female','shu',3,['txianqu','qiongguang']], - pal_longyou:['male','wei',4,['yuexing','minsha']], - pal_xiaoman:['female','shu',3,['anwugu','lingquan','shenwu']], - - pal_xiahoujinxuan:['male','shu',3,['xuanmo','danqing']], - pal_muchanglan:['female','wu',3,['feixia','lueying']], - pal_xia:['female','shu',3,['xjzongyu','fanling']], - pal_jiangcheng:['male','qun',4,['yanzhan','fenshi']], - - pal_yuejinzhao:['male','wei',4,['ywuhun','xjyingfeng']], - pal_yueqi:['female','wei',3,['tianwu','liguang','shiying']], - pal_mingxiu:['female','shu',3,['linghuo','guijin','chengxin']], - pal_xianqing:['male','qun',4,['xtanxi','xiaoyue']], - pal_luozhaoyan:['female','shu',4,['fenglue','tanhua']], - pal_jushifang:['male','shu',3,['yujia','xiepan','yanshi']], - }, - characterIntro:{ - pal_lixiaoyao:'一个天资聪颖的乡下客栈店小二,因一壶酒被酒剑仙传授了蜀山仙剑派剑术,在仙灵岛与赵灵儿相遇,自此经历重重磨难成长为一代旷世奇侠。灵儿牺牲以后他悲痛欲绝。后出任蜀山掌门,取道号一贫,从此御剑行遍天下,行侠仗义、斩妖除魔。多年后因魔教之乱,故引咎卸职,成为蜀山七圣之一。而后虽心力交瘁,但仍竭力保护天下苍生。', - pal_zhaoliner:'林青儿与巫王之女,亦是女娲族人。自幼与世隔绝,跟随姥姥隐居仙灵岛修炼,躲避仇人的追杀。难以告人的神秘身世,让她逃不过命运的捉弄,注定在滚滚红尘中历尽千灾万劫。在最终,赵灵儿为了消灭拜月水魔兽,与其同归于尽。但在王小虎、李忆如决战大魔头千叶禅师的结尾,出现了她的声音。', - pal_linyueru:'天资灵秀,聪敏慧黠,情深义重。身为江南武林魁首林家堡之武门千金,与李逍遥不打不相识,并在此后的寻人旅途中相知相恋。在经历过重重艰辛和生离死别后,遥月二人终于携手而共结连理,与高堂娇儿共享天伦。', - - pal_wangxiaohu:'李逍遥的同乡,自小仰慕李逍遥,想要拜在他门下,得知拜师无望之后,遂跟随李大婶学习排云掌法。之后前往杭州拜“三大神捕”之一的”神眼魔刀”盛尊武为师,并习得魔刀刀法。热血少年,敢作敢当,嫉恶如仇,相信人定胜天。他最后发现千叶禅师的阴谋,与众人合力击败千叶禅师。', - pal_sumei:'蛇妖和狐精之女,其父母当年被李逍遥和林月如所杀,因此她一直想要报仇,可以说是为报仇而活着。爱上王小虎,认识李忆如之后,苏媚学会了宽恕,最后甚至为了朋友和爱人牺牲自己。', - pal_shenqishuang:'乳名沈七七,峨嵋山仙霞派掌门清柔师太座下弟子,与四位师姊妹合称“仙霞五奇”,排行第四,个性拘谨温婉,对小虎心怀爱意却不敢开口表达。', - - pal_jingtian:'永安当的小伙计,司“管饰”一职,专门保管当铺收押的首饰珠宝类贵重物品。景天不但有鉴别古董珠宝的天赋,而且对买卖、帐目能很精通,对保管的当品更有过目不忘的本事。每日幻想有朝一日能富甲天下或成为人人景仰的蜀山剑仙。', - pal_xuejian:'出身唐门,虽为大小姐,却备受家族内部排挤欺凌。后离开唐家堡,与景天等人一同浪迹江湖并探寻自己的身世秘密。经历各种事件后,与景天结为连理,并育有一子名为景小楼。', - pal_longkui:'古时的姜国公主,景天前世龙阳的妹妹。因国破家亡而跳入铸剑炉,成为魔剑剑灵。龙葵拥有两种性格形态:蓝色龙葵温柔娴淑,红色龙葵火辣张扬。', - pal_zixuan:'女娲族后裔,饱受情爱煎熬三生三世之苦。在面对为了天下苍生而牺牲生命的女娲族宿命时,她坦然接受,把自己用水灵珠修炼的内丹渡给徐长卿使他成为上仙,最后献出自己的生命封印锁妖塔。', - pal_changqing:'蜀山仙剑派俗家弟子。自幼被蜀山掌门清微收为入室弟子,武学天赋极高。与紫萱相恋三世,最终紫萱为修复锁妖塔而牺牲了自己并把自己用水灵珠修炼的内丹渡给徐长卿,使徐长卿迅速成仙并继任蜀山派第二十三代掌门,最后辞去了掌门职务归隐。', - - pal_nangonghuang:'出生不久后父母被为了追寻记忆而来燎日所误杀,后来被常纪带到蜀山抚养长大,视同己出。从小希望得到尊敬。后来奉蜀山掌门徐长卿之命开启地脉入口,疏通五灵,从而使蜀山"否极泰来"、回复混沌状态。', - pal_wenhui:'爽朗大方,性情如同男子,极富正义感;内心却是天真少女般剔透明净。因为不愿嫁去室韦而逃出家里,后与南宫煌相遇,并随其完成地脉任务。', - pal_wangpengxu:'原形是一只娇小可爱的五毒兽。擅长读心术,可以看透人的心思。多次被南宫煌无意中救下,后跟随其恢复地脉。', - pal_xingxuan:'南宫煌之兄,幼时被燎日带走并由其抚养长大。身体其实是一具尸体(尸体是其父赤炎的),不仅残缺而且带有剧毒。初,灵肉分离,身体毫无感觉,后经重楼相助灵肉合一。为使尸身不坏,使用剧毒保存,故无法进入人界,绝大多数时间身在里蜀山。有领导才能,凭借自身上位者的气质和才干,在里蜀山妖界占据了一定势力。', - pal_leiyuange:'是个来历成谜的木讷男子,擅长使用弩、单手斧,有三只名为风雅颂的怪鸟时常出现在他的头顶代替其言语。生前为室韦族族长,死后尸体被鬼差附身。在胜洲与南宫煌与温慧等人结识,并成为好友。', - - pal_yuntianhe:'自幼孤身一人在黄山青鸾峰长大,从未下过山,对外界事物一无所知。一次偶然的机会与闯入父亲的墓室寻找宝藏的少女韩菱纱相遇。为了更多地了解父亲的过去、也为了成为剑仙,云天河与韩菱纱和柳梦璃一同拜入昆仑琼华派成为门下弟子。下山后云天河虽经历种种,但从未改变过“我命由我不由天”的想法。', - pal_hanlingsha:'背负着家族命运而四处奔走的少女,自称是独行千里的陵墓大盗。年纪不大,却对辨识墓穴位置、破解奇诡机关、地脉风水之学颇有研究。', - pal_liumengli:'妖界婵幽之女,因19年前妖界大战而失散,被云天青行侠救下后送至寿阳城县家抚养。', - pal_murongziying:'昆仑琼华派弟子。很小就被家人送至琼华派修行,天赋极高,在同辈弟子中修为较深,已臻“以气御剑”的境界。性格外冷内热,稳重内敛;看似不易相处,实则是一个恩怨分明、极重情义的热血男儿。', - pal_xuanxiao:'天赋异禀,资质极佳,是万中无一的修仙奇才,和夙玉用双剑束缚幻瞑界吸取灵力并引发琼华派与妖界之战。因夙玉离开昆仑,修炼双剑中断,他被邪火入侵而走火入魔,打伤数名师兄弟,被夙瑶联合青阳、重光与宗炼长老冰封19年,因此逢缘与云天河结拜。', - - // pal_jiangyunfan:'', - // pal_tangyurou:'', - // pal_longyou:'', - // pal_xiaoman:'', - - pal_xiahoujinxuan:'夏侯世家的少主。因不喜舞枪弄剑,专爱趣闻逸史,让父亲深感恨铁不成钢;好在他对于仙术符法也有所涉略,没沦落到手无缚鸡之力的境地。', - pal_muchanglan:'行走江湖买卖消息的佣兵,冷艳霸气,洞察力强。受人雇佣而加入夏侯瑾轩等一行人,虽然目的不纯,但通过相处,渐渐地被改变;同时通过夏侯瑾轩等人的帮助,完成了救治暮蔼村村民的心愿。', - pal_xia:'走江湖卖艺为生的孤女,性格倔强,自尊心强,不喜欢被人小看,更不爱占别人的便宜。卖艺的艰辛让她深知人间冷暖,却仍保持善良天性。', - pal_jiangcheng:'折剑山庄庄主欧阳英的得意门生,但因其蚩尤后人魔族的身份,令他无法被容于人界;再加上人界半魔同族饱受人类迫害,故最终成为净天教教主魔君“姜世离”,毅然肩负起保护同族的重任。', - }, - skill:{ - lingquan:{ - trigger:{player:'phaseEnd'}, - forced:true, - skillAnimation:true, - animationColor:'water', - unique:true, - filter:function(event,player){ - return game.roundNumber>=3&&player.getHistory('useCard').length>player.hp; - }, - content:function(){ - 'step 0' - player.awakenSkill('lingquan'); - player.draw(3); - player.addSkill('shuiyun'); - 'step 1' - if(lib.filter.filterTrigger(trigger,player,'phaseEnd','shuiyun')) game.createTrigger('phaseEnd','shuiyun',player,trigger); - }, - }, - shenwu:{ - trigger:{global:'phaseEnd'}, - forced:true, - skillAnimation:true, - animationColor:'water', - unique:true, - filter:function(event,player){ - return player.storage.shuiyun_count>=3; - }, - content:function(){ - player.awakenSkill('shenwu'); - player.gainMaxHp(); - player.recover(); - player.addSkill('huimeng'); - } - }, - qiongguang:{ - trigger:{player:'phaseDiscardEnd'}, - filter:function(event,player){ - return event.cards&&event.cards.length>1 - }, - content:function(){ - 'step 0' - event.targets=player.getEnemies().sortBySeat(); - 'step 1' - if(event.targets.length){ - player.line(event.targets.shift().getDebuff(false).addExpose(0.1),'green'); - event.redo(); - } - 'step 2' - game.delay(); - }, - ai:{ - threaten:2, - expose:0.2, - effect:{ - player:function(card,player){ - if(_status.currentPhase!=player) return; - if(_status.event.name!='chooseToUse'||_status.event.player!=player) return; - var num=player.needsToDiscard(); - if(num>2||num==1) return; - if(get.type(card)=='basic'&&num!=2) return; - if(get.tag(card,'gain')) return; - if(get.value(card,player,'raw')>=7) return; - if(player.hp<=2) return; - if(!player.hasSkill('jilue')||player.storage.renjie==0){ - return 'zeroplayertarget'; - } - } - } - } - }, - txianqu:{ - trigger:{source:'damageBefore'}, - logTarget:'player', - filter:function(event,player){ - if(player.hasSkill('txianqu2')) return false; - var evt=event.getParent('phaseUse'); - if(evt&&evt.player==player) return true; - return false; - }, - check:function(event,player){ - var target=event.player; - if(get.attitude(player,target)>=0||get.damageEffect(target,player,player)<=0) return true; - if(target.hp>player.hp&&player.isDamaged()) return true; - return false; - }, - content:function(){ - trigger.cancel(); - player.draw(2); - player.recover(); - player.addTempSkill('txianqu2'); - }, - ai:{ - jueqing:true, - skillTagFilter:function(player,tag,arg){ - if(!arg) return false; - if(player.hasSkill('txianqu2')) return false; - if(get.attitude(player,arg)>0) return false; - var evt=_status.event.getParent('phaseUse'); - if(evt&&evt.player==player) return true; - return false; - }, - effect:{ - player:function(card,player,target){ - if(get.tag(card,'damage')&&get.attitude(player,target)>0){ - if(player.hp==player.maxHp||get.recoverEffect(player,player,player)<=0) return 'zeroplayertarget'; - return [0,0,0,0.5]; - } - } - } - } - }, - txianqu2:{}, - xunying:{ - trigger:{player:'shaAfter'}, - direct:true, - filter:function(event,player){ - return player.canUse('sha',event.target)&&player.hasSha()&&event.target.isIn(); - }, - content:function(){ - "step 0" - if(player.hasSkill('jiu')){ - player.removeSkill('jiu'); - event.jiu=true; - } - player.chooseToUse(get.prompt('xunying'),{name:'sha'},trigger.target,-1).logSkill='xunying'; - "step 1" - if(result.bool); - else if(event.jiu){ - player.addSkill('jiu'); - } - } - }, - liefeng:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter:function(event,player){ - return _status.currentPhase==player&&[2,3,4].includes(player.countUsed()); - }, - content:function(){ - var skill; - switch(player.countUsed()){ - case 2:skill='yanzhan';break; - case 3:skill='tianjian';break; - case 4:skill='xjyufeng';break; - } - if(skill&&!player.hasSkill(skill)){ - player.addTempSkill(skill); - player.popup(skill); - game.log(player,'获得了','【'+get.translation(skill)+'】'); - if(skill=='xjyufeng'){ - var nh=player.countCards('h'); - if(nh<2){ - player.draw(2-nh); - player.addSkill('counttrigger'); - if(!player.storage.counttrigger){ - player.storage.counttrigger={}; - } - player.storage.counttrigger.xjyufeng=1; - } - } - } - }, - ai:{ - effect:{ - player:function(card,player){ - if(_status.currentPhase!=player) return; - if(get.type(card)=='basic') return; - if(get.tag(card,'gain')) return; - if(get.value(card,player,'raw')>=7) return; - if(player.hp<=2) return; - if(player.needsToDiscard()) return; - if(player.countUsed()>=2) return; - return 'zeroplayertarget'; - } - } - } - }, - yuexing:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player; - }, - content:function(){ - player.storage.yuexing2=target; - player.addTempSkill('yuexing2'); - target.storage.yuexing2=player; - target.addTempSkill('yuexing2'); - }, - ai:{ - order:function(){ - var player=_status.event.player; - if(player.hasSkill('minsha')) return 6.5; - return 2; - }, - result:{ - target:function(player,target){ - if(player.hasSkill('minsha')&&player.countCards('he')>=3&& - target.hp>1&&get.damageEffect(target,player,player,'thunder')>0){ - var num1=game.countPlayer(function(current){ - if(get.distance(target,current)<=1&¤t!=player&¤t!=target){ - return -get.sgn(get.attitude(player,current)); - } - }); - var num2=game.countPlayer(function(current){ - if(get.distance(player,current)<=1&¤t!=player&¤t!=target){ - return -get.sgn(get.attitude(player,current)); - } - }); - if(num2>=num1) return 0; - return 2*(num2-num1); - } - return -_status.event.getRand(); - } - } - } - }, - yuexing2:{ - mark:'character', - intro:{ - content:'到其他角色的距离基数与$交换' - }, - onremove:true, - mod:{ - globalFrom:function(from,to,distance){ - if(from.storage.yuexing2){ - var dist1=get.distance(from,to,'pure'); - var dist2=get.distance(from.storage.yuexing2,to,'pure'); - return distance-dist1+dist2; - } - } - } - }, - minsha:{ - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:2, - position:'he', - filter:function(event,player){ - return player.countCards('he')>=2; - }, - filterTarget:function(card,player,target){ - return target!=player&&target.hp>1; - }, - line:'thunder', - check:function(card){ - return 8-get.value(card); - }, - content:function(){ - 'step 0' - target.damage('thunder'); - 'step 1' - event.targets=game.filterPlayer(function(current){ - return get.distance(target,current)<=1&¤t!=target&¤t!=player; - }).sortBySeat(target); - 'step 2' - if(event.targets.length){ - event.targets.shift().randomDiscard(false); - event.redo(); - } - }, - ai:{ - order:6, - result:{ - player:function(player,target){ - if(get.damageEffect(target,player,player,'thunder')>0){ - if(target==player.storage.yuexing2){ - return 10; - } - var num=1+game.countPlayer(function(current){ - if(get.distance(target,current)<=1&¤t!=player&¤t!=target){ - return -get.sgn(get.attitude(player,current)); - } - }); - if(target.hp==1){ - num+=2; - } - if(target.hp1&&player.countCards('h','sha')==1){ - return 'zeroplayertarget'; - } - } - }, - } - }, - xiaoyue2:{ - mod:{ - cardRespondable:function(card,player){ - if(_status.event.getParent(4).name=='xiaoyue'&&get.suit(card)!='heart') return false; - } - } - }, - huanlei:{ - trigger:{player:'damageEnd'}, - check:function(event,player){ - return get.damageEffect(event.source,player,player,'thunder')>0; - }, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source.hp>player.hp; - }, - logTarget:'source', - content:function(){ - 'step 0' - trigger.source.damage('thunder'); - 'step 1' - trigger.source.draw(); - } - }, - anwugu:{ - trigger:{source:'damageEnd'}, - check:function(event,player){ - return get.attitude(player,event.player)<0; - }, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player!=player&&event.player.isIn()&&!event.player.hasSkill('anwugu2'); - }, - logTarget:'player', - content:function(){ - trigger.player.addSkill('anwugu2'); - } - }, - anwugu2:{ - mod:{ - cardEnabled:function(card,player){ - if(_status.currentPhase!=player) return; - if(player.countUsed()>=player.storage.anwugu2) return false; - }, - maxHandcard:function(player,num){ - return num-1; - } - }, - mark:true, - intro:{ - content:'手牌上限-1,每回合最多使用$张牌(剩余$回合)' - }, - init:function(player){ - player.storage.anwugu2=3; - }, - trigger:{player:'phaseAfter'}, - silent:true, - onremove:true, - content:function(){ - player.storage.anwugu2--; - if(player.storage.anwugu2<=0){ - // player.loseHp(); - player.removeSkill('anwugu2'); - } - else{ - player.updateMarks(); - } - } - }, - xtanxi:{ - enable:'phaseUse', - usable:1, - filterCard:true, - check:function(card){ - var enemies=_status.event.player.getEnemies(); - var num1=0,num2=0; - for(var i=0;i=3) {num1+=0.5;num2+=0.5;} - } - var rand=_status.event.getRand(); - if(num1>=1&&num2>=1){ - if(card.name=='shan') return rand+=0.4; - if(card.name=='sha') return rand; - } - else if(num1>=1){ - if(card.name=='sha') return rand; - } - else if(num2>=1){ - if(card.name=='shan') return rand; - } - return 0; - }, - content:function(){ - player.addExpose(0.1); - var targets=player.getEnemies(); - for(var i=0;i0; - }, - logTarget:'player', - line:'fire', - ai:{ - expose:0.2, - threaten:1.3, - }, - content:function(){ - trigger.player.damage('fire'); - }, - }, - guijin:{ - round:3, - enable:'phaseUse', - delay:0, - content:function(){ - 'step 0' - event.cards=get.cards(4); - 'step 1' - if(event.cards.length){ - var more=false,remain=false,nomore=false; - if(event.cards.length>=3){ - for(var i=0;i=8){ - more=true; - } - if(event.cards.length>=4&&value<6){ - if(remain===false){ - remain=value; - } - else{ - remain=Math.min(remain,value); - } - } - } - } - if(remain===false){ - remain=0; - } - if(!more&&!game.hasPlayer(function(current){ - return get.attitude(player,current)<0&&!current.skipList.includes('phaseDraw'); - })){ - var num=0; - for(var i=0;i=12){ - more=true; - } - else{ - nomore=true; - } - } - player.chooseCardButton('归烬',event.cards,[1,event.cards.length]).ai=function(button){ - if(nomore) return 0; - if(more){ - return get.value(button.link,player,'raw')-remain; - } - else{ - if(ui.selected.buttons.length) return 0; - return 8-get.value(button.link,player,'raw'); - } - } - } - else{ - event.goto(4); - } - 'step 2' - if(result.bool){ - for(var i=0;i1){ - if(target==player&&target.needsToDiscard(result.links)>1) return att/5; - return att; - } - else{ - if(target.skipList.includes('phaseDraw')) return att/5; - return -att; - } - } - } - else{ - event.goto(4); - } - 'step 3' - if(result.targets.length){ - result.targets[0].gain(event.togive,'draw'); - result.targets[0].skip('phaseDraw'); - result.targets[0].addTempSkill('guijin2',{player:'phaseBegin'}); - game.log(result.targets[0],'获得了'+get.cnNumber(event.togive.length)+'张','#g“归烬”牌'); - player.line(result.targets[0],'green'); - event.goto(1); - } - 'step 4' - while(event.cards.length){ - ui.cardPile.insertBefore(event.cards.pop(),ui.cardPile.firstChild); - } - }, - ai:{ - order:1, - result:{ - player:function(player){ - if(game.roundNumber==1&&player.hasUnknown()) return 0; - return 1; - } - } - } - }, - guijin2:{ - mark:true, - intro:{ - content:'跳过下一个摸牌阶段' - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='bingliang'||card.name=='caomu') return 0; - } - } - } - }, - chengxin:{ - round:4, - enable:'chooseToUse', - filter:function(event,player){ - return event.type=='dying'; - }, - filterTarget:function(card,player,target){ - return target==_status.event.dying; - }, - selectTarget:-1, - content:function(){ - target.recover(1-target.hp); - target.addTempSkill('chengxin2',{player:'phaseAfter'}); - }, - ai:{ - order:6, - threaten:1.4, - skillTagFilter:function(player){ - if(4-(game.roundNumber-player.storage.chengxin_roundcount)>0) return false; - if(!_status.event.dying) return false; - }, - save:true, - result:{ - target:3 - }, - } - }, - chengxin2:{ - trigger:{player:'damageBefore'}, - mark:true, - forced:true, - content:function(){ - trigger.cancel(); - }, - ai:{ - nofire:true, - nothunder:true, - nodamage:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')) return [0,0]; - } - }, - }, - intro:{ - content:'防止一切伤害' - } - }, - tianwu:{ - trigger:{player:'useCardToBegin'}, - filter:function(event,player){ - if(get.is.altered('tianwu')&&player.hasSkill('tianwu2')) return false; - return event.targets&&event.targets.length==1&&player.getEnemies().includes(event.target); - }, - // alter:true, - frequent:true, - content:function(){ - trigger.target.getDebuff(); - player.addTempSkill('tianwu2'); - } - }, - tianwu2:{}, - shiying:{ - trigger:{global:'dieBefore'}, - skillAnimation:'epic', - animationColor:'water', - unique:true, - init:function(player){ - player.storage.shiying=false; - }, - mark:true, - intro:{ - content:'limited' - }, - check:function(event,player){ - return get.attitude(player,event.player)>=3; - }, - filter:function(event,player){ - return !player.storage.shiying&&event.player!=player; - }, - logTarget:'player', - content:function(){ - 'step 0' - trigger.cancel(); - player.awakenSkill('shiying'); - player.storage.shiying=true; - - player.maxHp=3; - player.hp=3; - trigger.player.maxHp=3; - trigger.player.hp=3; - - player.clearSkills(); - trigger.player.clearSkills(); - 'step 1' - var hs=player.getCards('hej'); - player.$throw(hs); - player.lose(player.getCards('hej'))._triggered=null; - 'step 2' - var hs=trigger.player.getCards('hej'); - trigger.player.$throw(hs); - trigger.player.lose(trigger.player.getCards('hej'))._triggered=null; - 'step 3' - game.asyncDraw([player,trigger.player],3); - }, - ai:{ - threaten:1.5 - } - }, - liguang:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - if(!player.canMoveCard()) return false; - if(!game.hasPlayer(function(current){ - return current.countCards('ej'); - })){ - return false; - } - return player.countCards('h')>0; - }, - direct:true, - content:function(){ - "step 0" - player.chooseToDiscard(get.prompt('liguang'),'弃置一张手牌并移动场上的一张牌',lib.filter.cardDiscardable).set('ai',function(card){ - if(!_status.event.check) return 0; - return 7-get.useful(card); - }).set('check',player.canMoveCard(true)).set('logSkill','liguang'); - "step 1" - if(result.bool){ - player.moveCard(true); - } - else{ - event.finish(); - } - }, - ai:{ - expose:0.2, - threaten:1.3 - } - }, - xiepan:{ - trigger:{player:'loseEnd'}, - direct:true, - filter:function(event,player){ - if(player.countCards('h',{type:'basic'})) return false; - if(!player.countCards('h')) return false; - for(var i=0;i1){ - list=list.randomGets(player.storage.yujia); - for(var i=0;i0&&event.num>0; - }, - content:function(){ - trigger.cancel(); - player.draw(2*trigger.num); - }, - group:'tanhua_remove', - subSkill:{ - remove:{ - trigger:{player:'dying'}, - priority:10, - forced:true, - content:function(){ - player.recover(); - player.removeSkill('tanhua'); - } - } - } - }, - xjyingfeng:{ - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.parent.name=='xjyingfeng') return false; - var enemies=player.getEnemies(); - return game.hasPlayer(function(current){ - return enemies.includes(current)&&!event.targets.includes(current)&&player.canUse('sha',current,false); - }); - }, - forced:true, - content:function(){ - var enemies=player.getEnemies(); - enemies.remove(trigger.targets); - if(enemies.length){ - player.useCard({name:'sha'},enemies.randomGet().addExpose(0.2)); - } - }, - }, - ywuhun:{ - trigger:{player:'phaseBefore'}, - forced:true, - // alter:true, - filter:function(event){ - return event.parent.name!='ywuhun'; - }, - intro:{ - content:'回合结束后,场上及牌堆中的牌将恢复到回合前的状态' - }, - video:function(player,data){ - for(var i in data){ - var current=game.playerMap[i]; - current.node.handcards1.innerHTML=''; - current.node.handcards2.innerHTML=''; - current.node.equips.innerHTML=''; - current.node.judges.innerHTML=''; - current.directgain(get.infoCards(data[i].h)); - var es=get.infoCards(data[i].e); - for(var j=0;j0){ - use.push(hs[i]); - if(get.attitude(player,target)>0){ - hef/=1.5; - if(get.tag(hs[i],'damage')){ - damaged=true; - } - } - eff+=hef; - } - } - if(!player.needsToDiscard(0,(i,player)=>{ - return !use.includes(i)&&!player.canIgnoreHandcard(i); - })) return eff; - return 0; - }; - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - var num=0; - player.chooseCard([1,Infinity],'按顺序选择对'+get.translation(result.targets)+'使用的牌',function(card){ - return lib.filter.targetEnabled2(card,player,event.target); - }).ai=function(card){ - if(get.effect(event.target,card,player,player)>0){ - if(get.attitude(player,event.target)>0&&get.tag(card,'damage')){ - for(var i=0;i2&& - get.recoverEffect(players[i],player,player)>0){ - if(players[i].hp==1){ - if(player.hp=3) return 1; - return 0; - } - }, - }, - intro:{ - content:'limited' - } - }, - binxin:{ - trigger:{global:'phaseEnd'}, - check:function(event,player){ - return get.attitude(player,event.player)>0; - }, - filter:function(event,player){ - return event.player.hp==1; - }, - logTarget:'player', - content:function(){ - trigger.player.changeHujia(); - }, - ai:{ - expose:0.1 - } - }, - qixia:{ - trigger:{player:['useCardAfter','respondAfter']}, - silent:true, - init:function(player){ - player.storage.qixia=[]; - }, - // mark:true, - intro:{ - content:function(storage){ - if(!storage.length){ - return '未使用或打出过有花色的牌'; - } - else{ - var str='已使用过'+get.translation(storage[0]+'2'); - for(var i=1;i=4; - }, - content:function(){ - player.insertPhase(); - player.storage.qixia.length=0; - player.syncStorage('qixia'); - player.unmarkSkill('qixia'); - } - } - } - }, - qixia_old:{ - trigger:{global:'damageAfter'}, - direct:true, - filter:function(event,player){ - return !player.hasSkill('qixia2')&&event.source!=player&&event.player.isIn()&&player.countCards('he',{color:'red'}); - }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('qixia',trigger.player),{color:'red'}).set('logSkill',['qixia',trigger.player]).ai=function(card){ - if(get.attitude(player,trigger.player)>0){ - if(trigger.player.hp==1){ - return 10-get.value(card); - } - return 8-get.value(card); - } - } - 'step 1' - if(result.bool){ - player.addTempSkill('qixia2'); - trigger.player.draw(2); - if(trigger.player.hp==1&&!trigger.player.hujia){ - trigger.player.changeHujia(); - } - } - }, - ai:{ - threaten:1.8 - } - }, - qixia2:{}, - jianzhen:{ - trigger:{player:'shaAfter'}, - forced:true, - filter:function(event,player){ - return event.target.isIn()&&game.hasPlayer(function(current){ - return current.canUse('sha',event.target,false)&¤t!=player; - }); - }, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current.canUse('sha',trigger.target,false)&¤t!=player; - }); - event.targets.sortBySeat(trigger.player); - 'step 1' - if(event.targets.length){ - event.current=event.targets.shift(); - if(event.current.hasSha()){ - event.current.chooseToUse({name:'sha'},'是否对'+get.translation(trigger.target)+'使用一张杀?',trigger.target,-1); - } - else{ - event.redo(); - } - } - else{ - event.finish(); - } - 'step 2' - if (!result.bool){ - event.goto(1); - } - }, - ai:{ - expose:0.2, - threaten:1.4 - }, - }, - husha:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - if(player.storage.husha==1){ - return game.hasPlayer(function(current){ - return player.canUse('sha',current,false); - }) - } - else{ - return player.storage.husha>0; - } - }, - content:function(){ - 'step 0' - var list=[]; - if(game.hasPlayer(function(current){ - return player.canUse('sha',current,false); - })){ - list.push('移去1枚虎煞标记,视为使用一张杀'); - } - if(player.storage.husha>1){ - list.push('移去2枚虎煞标记,视为使用一张南蛮入侵'); - if(player.storage.husha>2){ - list.push('移去3枚虎煞标记,视为对除你之外的角色使用一张元素毁灭'); - } - } - player.chooseControl('cancel2',function(){ - if(player.storage.husha>2){ - var num1=game.countPlayer(function(current){ - if(current!=player&&player.canUse('yuansuhuimie',current)){ - return get.sgn(get.effect(current,{name:'yuansuhuimie'},player,player)); - } - }); - var num2=game.countPlayer(function(current){ - if(current!=player&&player.canUse('yuansuhuimie',current)){ - return get.effect(current,{name:'yuansuhuimie'},player,player); - } - }); - if(num1>0&&num2>0) return '选项三'; - } - if(player.storage.husha>1){ - var num=game.countPlayer(function(current){ - if(current!=player&&player.canUse('nanman',current)){ - return get.sgn(get.effect(current,{name:'nanman'},player,player)); - } - }); - if(num>0) return '选项二'; - } - if(game.hasPlayer(function(current){ - return player.canUse('sha',current,false)&&get.effect(current,{name:'sha'},player,player)>0; - })){ - return '选项一'; - } - return 'cancel2'; - }).set('prompt',get.prompt('husha')).set('choiceList',list); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('husha'); - if(result.control=='选项一'){ - event.sha=true; - player.storage.husha--; - player.chooseTarget('选择出杀的目标',true,function(card,player,target){ - return player.canUse('sha',target,false); - }).ai=function(target){ - return get.effect(target,{name:'sha'},player,player); - } - } - else if(result.control=='选项二'){ - var list=game.filterPlayer(function(current){ - return player.canUse('nanman',current); - }); - player.storage.husha-=2; - list.sortBySeat(); - player.useCard({name:'nanman'},list); - } - else{ - var list=game.filterPlayer(function(current){ - return player.canUse('yuansuhuimie',current); - }); - player.storage.husha-=3; - list.remove(player); - list.sortBySeat(); - player.useCard({name:'yuansuhuimie'},list); - } - if(!player.storage.husha){ - player.unmarkSkill('husha'); - } - else{ - player.syncStorage('husha'); - player.updateMarks(); - } - } - 'step 2' - if(event.sha&&result.targets&&result.targets.length){ - player.useCard({name:'sha'},result.targets[0]); - } - }, - init:function(player){ - player.storage.husha=0; - }, - intro:{ - content:'mark' - }, - group:'husha_count', - subSkill:{ - count:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - if(player.storage.husha<3){ - var evt=event.getParent('phaseUse'); - return evt&&evt.player==player; - } - return false; - }, - content:function(){ - player.storage.husha+=trigger.num; - if(player.storage.husha>3){ - player.storage.husha=3; - } - player.markSkill('husha'); - player.syncStorage('husha'); - player.updateMarks(); - } - } - } - }, - fenshi:{ - unique:true, - skillAnimation:true, - animationColor:'fire', - trigger:{player:'dyingAfter'}, - forced:true, - mark:true, - derivation:'longhuo', - intro:{ - content:'limited' - }, - content:function(){ - player.awakenSkill('fenshi'); - player.changeHujia(2); - player.draw(2); - player.addSkill('longhuo'); - }, - }, - longhuo:{ - unique:true, - trigger:{player:'phaseEnd'}, - check:function(event,player){ - if(player.hp==1&&player.hujia==0) return false; - var num=game.countPlayer(function(current){ - var eff=get.sgn(get.damageEffect(current,player,player,'fire')); - if(current.hp==1&¤t.hujia==0) eff*=1.5; - return eff; - }); - return num>0; - }, - content:function(){ - 'step 0' - event.targets=get.players(lib.sort.seat); - 'step 1' - if(event.targets.length){ - var current=event.targets.shift(); - if(current.isIn()){ - player.line(current,'fire'); - current.damage('fire'); - event.redo(); - } - } - } - }, - yanzhan:{ - enable:'phaseUse', - viewAs:{name:'sha',nature:'fire'}, - usable:1, - position:'he', - viewAsFilter:function(player){ - if(!player.countCards('he',{color:'red'})) return false; - }, - filterCard:{color:'red'}, - check:function(card){ - if(get.suit(card)=='heart') return 7-get.value(card); - return 5-get.value(card); - }, - onuse:function(result){ - if(result.targets){ - for(var i=0;i2||nh==0)){ - return false; - } - } - } - }, - feixia:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'red'}, - position:'he', - filter:function(event,player){ - return player.countCards('he',{color:'red'})>0; - }, - check:function(card){ - return 7-get.value(card); - }, - content:function(){ - var targets=player.getEnemies(); - if(targets.length){ - var target=targets.randomGet(); - target.addExpose(0.2); - player.useCard({name:'sha'},target,false); - } - }, - ai:{ - order:2.9, - result:{ - player:1 - } - } - }, - lueying:{ - trigger:{player:'shaBegin'}, - filter:function(event,player){ - if(event.target.countCards('he')>0){ - return game.hasPlayer(function(current){ - return current!=player&¤t!=event.target&¤t.countCards('he'); - }); - } - return false; - }, - logTarget:'target', - usable:1, - content:function(){ - 'step 0' - var card=trigger.target.getCards('he').randomGet(); - player.gain(card,trigger.target); - if(get.position(card)=='e'){ - trigger.target.$give(card,player); - } - else{ - trigger.target.$giveAuto(card,player); - } - 'step 1' - if(game.hasPlayer(function(current){ - return current!=player&¤t!=trigger.target&¤t.countCards('he'); - })){ - trigger.target.chooseTarget(function(card,player,target){ - return target!=player&&target!=_status.event.parent.player&&target.countCards('he')>0; - },'选择一名角色并令'+get.translation(player)+'弃置其一张牌').ai=function(target){ - return -get.attitude(_status.event.player,target); - }; - } - else{ - event.finish(); - } - 'step 2' - if(result.bool){ - trigger.target.line(result.targets[0],'green'); - player.discardPlayerCard(result.targets[0],true,'he'); - } - }, - ai:{ - threaten:1.5, - expose:0.2, - } - }, - tianjian:{ - enable:'phaseUse', - viewAs:{name:'wanjian'}, - filterCard:{name:'sha'}, - filter:function(event,player){ - return player.countCards('h','sha')>0; - }, - // alter:true, - usable:1, - group:'tianjian_discard', - subSkill:{ - discard:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - if(get.is.altered('tianjian')) return false; - return event.parent.skill=='tianjian'&&event.player.countCards('he'); - }, - popup:false, - content:function(){ - trigger.player.discard(trigger.player.getCards('he').randomGet()); - } - } - } - }, - feng:{ - unique:true, - init:function(player){ - player.storage.feng=0; - }, - mark:true, - intro:{ - content:'已累计摸#次牌' - }, - trigger:{player:'drawBegin'}, - forced:true, - popup:false, - priority:5, - content:function(){ - if(player.storage.feng<2){ - player.storage.feng++; - } - else{ - trigger.num++; - player.storage.feng=0; - player.logSkill('feng'); - } - player.updateMarks(); - } - }, - ya:{ - unique:true, - init:function(player){ - player.storage.ya=0; - }, - mark:true, - intro:{ - content:'已累计受到#次伤害' - }, - trigger:{player:'damageBegin'}, - filter:function(event,player){ - if(player.storage.ya==2) return event.num>0; - return true; - }, - forced:true, - popup:false, - content:function(){ - if(player.storage.ya<2){ - player.storage.ya++; - } - else if(trigger.num>0){ - trigger.num--; - player.storage.ya=0; - player.logSkill('ya'); - } - player.updateMarks(); - } - }, - song:{ - unique:true, - init:function(player){ - player.storage.song=0; - }, - mark:true, - intro:{ - content:'已累计造成#次伤害' - }, - trigger:{source:'damageBegin'}, - forced:true, - popup:false, - content:function(){ - if(player.storage.song<2){ - player.storage.song++; - } - else{ - trigger.num++; - player.storage.song=0; - player.logSkill('song'); - } - player.updateMarks(); - } - }, - longxiang:{ - trigger:{player:'shaBegin'}, - filter:function(event,player){ - return event.target.countCards('h')>player.countCards('h'); - }, - check:function(event,player){ - return get.attitude(player,event.target)<0; - }, - logTarget:'target', - content:function(){ - var hs=trigger.target.getCards('h'); - trigger.target.discard(hs.randomGets(hs.length-player.countCards('h'))); - } - }, - huxi:{ - enable:'chooseToUse', - viewAs:{name:'sha'}, - precontent:function(){ - 'step 0' - player.loseHp(); - 'step 1' - player.changeHujia(); - }, - filterCard:function(){return false}, - selectCard:-1, - prompt:'失去1点体力并获得1点护甲,视为使用一张杀', - ai:{ - order:function(){ - var player=_status.event.player; - if(player.hp<=2) return 0; - return 2; - }, - skillTagFilter:function(player,tag,arg){ - if(arg!='use') return false; - }, - respondSha:true, - } - }, - xuanmo:{ - enable:'phaseUse', - usable:1, - filterCard:function(card){ - var type=get.type(card,'trick'); - return type=='basic'||type=='equip'||type=='trick'; - }, - check:function(card){ - return 8-get.value(card); - }, - filter:function(event,player){ - return player.countCards('h')>0; - }, - discard:false, - prepare:'throw', - content:function(){ - game.log(player,'将',cards,'置于牌堆顶'); - ui.cardPile.insertBefore(cards[0],ui.cardPile.firstChild); - var list=get.inpile(get.type(cards[0],'trick'),'trick').randomGets(2); - for(var i=0;i0){ - return att+1/Math.sqrt(1+target.countCards('h')); - } - return 0; - }; - 'step 2' - if(result.bool){ - player.line(result.targets[0],'green'); - result.targets[0].draw(); - event.targets.push(result.targets[0]); - if(event.targets.length==game.players.length){ - event.finish(); - } - else{ - player.chooseTarget('令一名角色获得1点护甲',function(card,player,target){ - return !event.targets.includes(target); - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>0){ - return att+1/Math.sqrt(1+target.hp); - } - return 0; - }; - } - } - else{ - event.finish(); - } - 'step 3' - if(result.bool){ - player.line(result.targets[0],'green'); - result.targets[0].changeHujia(); - game.delay(); - event.targets.push(result.targets[0]); - if(event.targets.length==game.players.length){ - event.finish(); - } - else{ - player.chooseTarget('令一名角色装备一件随机装备',function(card,player,target){ - return !event.targets.includes(target); - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>0&&!target.getEquip(5)){ - return att; - } - return 0; - }; - } - } - else{ - event.finish(); - } - 'step 4' - if(result.bool){ - player.line(result.targets[0],'green'); - game.delay(); - var list=[]; - for(var i=0;i0){ - return att+1/Math.sqrt(1+target.hp); - } - return 0; - }; - } - } - else{ - event.finish(); - } - 'step 5' - if(result.bool){ - player.line(result.targets[0],'green'); - game.delay(); - result.targets[0].tempHide(); - } - } - }, - sheling:{ - trigger:{global:['useCardAfter','respondAfter','discardAfter']}, - filter:function(event,player){ - if(player!=_status.currentPhase||player==event.player) return false; - if(event.cards){ - for(var i=0;i0&&player.countCards('h')>0; - }, - check:function(event,player){ - if(player.isUnseen()) return false; - if(get.attitude(player,event.player)>=0) return false; - var hs=player.getCards('h'); - if(hs.length=10&&val<=6) return true; - if(hs[i].number>=8&&val<=3) return true; - } - return false; - }, - logTarget:'player', - content:function(){ - 'step 0' - player.chooseToCompare(trigger.player); - 'step 1' - if(result.bool){ - player.draw(2); - } - else{ - event.finish(); - } - 'step 2' - player.chooseCard('将两张牌置于牌堆顶(先选择的在上)',2,'he',true); - 'step 3' - if(result.bool){ - player.lose(result.cards,ui.special); - event.cards=result.cards; - } - else{ - event.finish(); - } - 'step 4' - game.delay(); - var nodes=[]; - for(var i=0;i=0;i--){ - ui.cardPile.insertBefore(event.cards[i],ui.cardPile.firstChild); - } - }, - ai:{ - mingzhi:false, - expose:0.2 - } - }, - zhangmu:{ - trigger:{player:['chooseToRespondBegin','chooseToUseBegin']}, - filter:function(event,player){ - if(event.responded) return false; - if(!event.filterCard({name:'shan'},player,event)) return false; - return player.countCards('h','shan')>0; - }, - direct:true, - usable:1, - content:function(){ - "step 0" - var goon=(get.damageEffect(player,trigger.player,player)<=0); - player.chooseCard(get.prompt('zhangmu'),{name:'shan'}).ai=function(){ - return goon?1:0; - } - "step 1" - if(result.bool){ - player.logSkill('zhangmu'); - player.showCards(result.cards); - trigger.untrigger(); - trigger.responded=true; - trigger.result={bool:true,card:{name:'shan'}} - player.addSkill('zhangmu_ai'); - } - else{ - player.storage.counttrigger.zhangmu--; - } - }, - ai:{ - respondShan:true, - effect:{ - target:function(card,player,target,effect){ - if(get.tag(card,'respondShan')&&effect<0){ - if(target.hasSkill('zhangmu_ai')) return 0; - if(target.countCards('h')>=2) return 0.5; - } - } - } - } - }, - zhangmu_ai:{ - trigger:{player:'loseAfter'}, - silent:true, - filter:function(event,player){ - return player.countCards('h','shan')==0; - }, - content:function(){ - player.removeSkill('zhangmu_ai'); - } - }, - leiyu:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - if(!player.countCards('h',{color:'black'})) return false; - if(player.storage.leiyu){ - for(var i=0;i0){ - num2++; - } - else if(eff<0){ - num2--; - } - } - var next=player.chooseToDiscard(get.prompt('leiyu',player.storage.leiyu),{color:'black'}); - next.ai=function(card){ - if(num>0&&num2>=2){ - return 7-get.value(card); - } - return 0; - }; - next.logSkill=['leiyu',player.storage.leiyu]; - 'step 1' - if(result.bool){ - player.storage.leiyu.sort(lib.sort.seat); - player.useCard({name:'jingleishan',nature:'thunder'},player.storage.leiyu).animate=false; - } - }, - group:['leiyu2','leiyu4'], - ai:{ - threaten:1.3 - } - }, - leiyu2:{ - trigger:{player:'phaseUseBegin'}, - silent:true, - content:function(){ - player.storage.leiyu=[]; - } - }, - leiyu3:{ - trigger:{source:'dieAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.leiyu2?true:false; - }, - content:function(){ - player.recover(); - delete player.storage.leiyu2; - } - }, - leiyu4:{ - trigger:{player:'useCardToBegin'}, - silent:true, - filter:function(event,player){ - return _status.currentPhase==player&&Array.isArray(player.storage.leiyu)&&event.target&&event.target!=player; - }, - content:function(){ - player.storage.leiyu.add(trigger.target); - } - }, - feizhua:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.targets.length!=1) return false; - var target=event.targets[0]; - var players=game.filterPlayer(function(current){ - return get.distance(target,current,'pure')==1; - }); - for(var i=0;i0; - }, - content:function(){ - "step 0" - var target=trigger.targets[0]; - var players=game.filterPlayer(function(current){ - return get.distance(target,current,'pure')==1; - }); - for(var i=0;i0; - }, - filterCard:{name:'sha'}, - filterTarget:function(card,player,target){ - return target!=player; - }, - prepare:'give', - discard:false, - content:function(){ - target.gain(cards,player); - if(!player.hasSkill('diewu2')){ - player.draw(); - player.addTempSkill('diewu2'); - } - }, - ai:{ - order:2, - expose:0.2, - result:{ - target:function(player,target){ - if(!player.hasSkill('diewu2')) return 1; - return 0; - } - } - } - }, - diewu2:{}, - lingyu:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isDamaged(); - }); - }, - content:function(){ - 'step 0' - player.chooseTarget('灵愈:令一名其他角色回复1点体力',function(card,player,target){ - return target!=player&&target.hp0; - }, - logTarget:'player', - content:function(){ - trigger.player.draw(); - }, - ai:{ - mingzhi:false, - threaten:2, - expose:0.2, - } - }, - xuanyan:{ - // trigger:{source:'damageBefore'}, - // forced:true, - // priority:5, - // check:function(event,player){ - // return player.hp>3; - // }, - // filter:function(event){ - // return event.card&&get.color(event.card)=='red'; - // }, - // content:function(){ - // trigger.nature='fire'; - // }, - group:['xuanyan2','xuanyan3'] - }, - xuanyan2:{ - trigger:{source:'damageBegin'}, - forced:true, - filter:function(event){ - return event.hasNature('fire')&&event.notLink(); - }, - content:function(){ - trigger.num++; - } - }, - xuanyan3:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - filter:function(event){ - return event.hasNature('fire'); - }, - content:function(){ - player.loseHp(); - } - }, - ningbin:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event){ - return event.hasNature('thunder'); - }, - content:function(){ - player.recover(); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'thunderDamage')){ - if(target.hp<=1||!target.hasSkill('xfenxin')) return [0,0]; - return [0,1.5]; - } - } - } - }, - }, - xfenxin:{ - trigger:{player:'changeHp'}, - forced:true, - filter:function(event){ - return event.num!=0; - }, - // alter:true, - content:function(){ - if(get.is.altered('xfenxin')){ - player.draw(); - } - else{ - player.draw(Math.abs(trigger.num)); - } - }, - ai:{ - effect:{ - target:function(card){ - if(get.tag(card,'thunderDamage')) return; - if(get.tag(card,'damage')||get.tag(card,'recover')){ - return [1,0.2]; - } - } - } - }, - group:'xfenxin2' - }, - xfenxin2:{ - trigger:{source:'dieAfter'}, - forced:true, - filter:function(){ - return !get.is.altered('xfenxin'); - }, - content:function(){ - player.gainMaxHp(); - player.recover(); - } - }, - luanjian:{ - enable:'phaseUse', - filterCard:{name:'sha'}, - selectCard:2, - check:function(card){ - var num=0; - var player=_status.event.player; - var players=game.filterPlayer(); - for(var i=0;i0){ - num++; - if(num>1) return 8-get.value(card); - } - } - return 0; - }, - viewAs:{name:'sha'}, - selectTarget:[1,Infinity], - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target); - }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; - }, - effect:{ - player:function(card,player){ - if(_status.currentPhase!=player) return; - if(card.name=='sha'&&player.countCards('h','sha')<2&&!player.needsToDiscard()){ - var num=0; - var player=_status.event.player; - var players=game.filterPlayer(); - for(var i=0;i1) return 'zeroplayertarget'; - } - } - } - } - }, - }, - group:'luanjian2' - }, - luanjian2:{ - trigger:{source:'damageBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.parent.skill=='luanjian'; - }, - content:function(){ - if(Math.random()<0.5) trigger.num++; - } - }, - ctianfu:{ - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h','shan')>0; - }, - usable:1, - filterCard:{name:'shan'}, - discard:false, - prepare:'give', - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('ctianfu2'); - }, - check:function(card){ - if(_status.event.player.hp>=3) return 8-get.value(card); - return 7-get.value(card); - }, - content:function(){ - target.storage.ctianfu2=cards[0]; - target.storage.ctianfu3=player; - game.addVideo('storage',target,['ctianfu2',get.cardInfo(cards[0]),'card']); - target.addSkill('ctianfu2'); - }, - ai:{ - order:2, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - return get.damageEffect(target,player,target,'thunder'); - } - }, - expose:0.2 - } - }, - ctianfu2:{ - trigger:{source:'damageAfter'}, - forced:true, - mark:'card', - filter:function(event,player){ - return player.storage.ctianfu2&&player.storage.ctianfu3; - }, - content:function(){ - "step 0" - if(player.storage.ctianfu3&&player.storage.ctianfu3.isAlive()){ - player.damage(player.storage.ctianfu3); - player.storage.ctianfu3.line(player,'thunder'); - } - else{ - player.damage('nosource'); - } - "step 1" - var he=player.getCards('he'); - if(he.length){ - player.discard(he.randomGet()); - } - "step 2" - player.$throw(player.storage.ctianfu2); - player.storage.ctianfu2.discard(); - delete player.storage.ctianfu2; - delete player.storage.ctianfu3; - player.removeSkill('ctianfu2'); - }, - group:'ctianfu3', - intro:{ - content:'card' - } - }, - ctianfu3:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content:function(){ - player.storage.ctianfu2.discard(); - delete player.storage.ctianfu2; - delete player.storage.ctianfu3; - player.removeSkill('ctianfu2'); - } - }, - shuiyun:{ - trigger:{player:'phaseEnd'}, - direct:true, - init:function(player){ - player.storage.shuiyun=[]; - player.storage.shuiyun_count=0; - }, - // alter:true, - filter:function(event,player){ - if(player.storage.shuiyun.length>=3) return false; - if(player.storage.shuiyun.length>=2&&get.is.altered('shuiyun')) return false; - var types=[]; - for(var i=0;i0; - }, - filterTarget:function(card,player,target){ - return target==_status.event.dying; - }, - delay:0, - selectTarget:-1, - content:function(){ - "step 0" - player.chooseCardButton(get.translation('shuiyun'),player.storage.shuiyun,true); - "step 1" - if(result.bool){ - player.storage.shuiyun.remove(result.links[0]); - if(!player.storage.shuiyun.length){ - player.unmarkSkill('shuiyun'); - } - player.$throw(result.links); - result.links[0].discard(); - target.recover(); - if(typeof player.storage.shuiyun_count=='number'){ - player.storage.shuiyun_count++; - } - player.syncStorage('shuiyun'); - } - else{ - event.finish(); - } - }, - ai:{ - order:6, - skillTagFilter:function(player){ - return player.storage.shuiyun.length>0; - }, - save:true, - result:{ - target:3 - }, - threaten:1.6 - } - }, - wangyou:{ - trigger:{global:'phaseEnd'}, - unique:true, - gainable:true, - direct:true, - filter:function(event,player){ - if(!player.countCards('he')) return false; - if(player==event.player) return false; - return game.hasPlayer(function(current){ - return current.hasSkill('wangyou3'); - }); - }, - content:function(){ - "step 0" - var targets=[]; - var num=0; - var players=game.filterPlayer(); - for(var i=0;i0) num++; - else if(att<0) num--; - targets.push(players[i]); - } - } - event.targets=targets; - var next=player.chooseToDiscard(get.prompt('wangyou',targets),'he'); - next.logSkill=['wangyou',event.targets]; - next.ai=function(card){ - if(num<=0) return 0; - switch(num){ - case 1:return 5-get.value(card); - case 2:return 7-get.value(card); - default:return 8-get.value(card); - } - } - "step 1" - if(result.bool){ - event.targets.sort(lib.sort.seat); - game.asyncDraw(event.targets); - } - else{ - event.finish(); - } - }, - ai:{ - expose:0.1, - threaten:1.2 - }, - group:'wangyou2' - }, - wangyou2:{ - trigger:{global:'damageEnd'}, - silent:true, - filter:function(event){ - return event.player.isAlive(); - }, - content:function(){ - trigger.player.addTempSkill('wangyou3'); - } - }, - wangyou3:{}, - changnian:{ - forbid:['boss'], - trigger:{player:'dieBegin'}, - direct:true, - unique:true, - derivation:'changnian2', - content:function(){ - "step 0" - player.chooseTarget(get.prompt('changnian'),function(card,player,target){ - return player!=target; - }).ai=function(target){ - return get.attitude(player,target); - }; - "step 1" - if(result.bool){ - var cards=player.getCards('hej'); - var target=result.targets[0]; - // if(player.storage.shuiyun&&player.storage.shuiyun.length){ - // target.gainMaxHp(); - // target.recover(player.storage.shuiyun.length); - // cards=cards.concat(player.storage.shuiyun); - // player.storage.shuiyun.length=0; - // } - player.$give(cards,target); - target.gain(cards); - target.addSkill('changnian2'); - player.logSkill('changnian',target); - target.marks.changnian=target.markCharacter(player,{ - name:'长念', - content:'
              【追思】
              锁定技,结束阶段,你摸一张牌
              ' - }); - game.addVideo('markCharacter',target,{ - name:'长念', - content:'
              【追思】
              锁定技,结束阶段,你摸一张牌
              ', - id:'changnian', - target:player.dataset.position - }); - } - }, - ai:{ - threaten:0.8 - } - }, - changnian2:{ - trigger:{player:'phaseEnd'}, - forced:true, - nopop:true, - content:function(){ - player.draw(); - }, - }, - sajin:{ - enable:'phaseUse', - filterTarget:function(card,player,target){ - return target.hpplayer.hp){ - return 7-get.value(card); - } - return 4-get.value(card); - }, - content:function(){ - "step 0" - var color=get.color(cards[0]); - target.judge(function(card){ - return get.color(card)==color?1:0; - }); - "step 1" - if(result.bool){ - target.recover(); - } - }, - ai:{ - order:3, - result:{ - target:function(player,target){ - return get.recoverEffect(target); - } - }, - threaten:1.5 - } - }, - jtjubao:{ - trigger:{global:'discardAfter'}, - filter:function(event,player){ - if(player.hasSkill('jtjubao2')) return false; - if(event.player==player) return false; - if(_status.currentPhase==player) return false; - for(var i=0;i0){ - return [1,3]; - } - } - } - } - } - } - }, - xshuangren:{ - trigger:{player:['loseEnd']}, - filter:function(event,player){ - if(!player.equiping) return false; - for(var i=0;i0; - }, - content:function(){ - "step 0" - player.chooseTarget([1,trigger.cards.length],get.prompt('qijian'),function(card,player,target){ - return player.canUse({name:'sha'},target,false); - }).ai=function(target){ - return get.effect(target,{name:'sha'},player); - }; - "step 1" - if(result.bool){ - player.logSkill('qijian'); - player.useCard({name:'sha'},result.targets); - } - }, - }, - shenmu:{ - trigger:{global:'dying'}, - priority:6, - filter:function(event,player){ - return event.player.hp<=0&&player.countCards('h',{color:'red'}); - }, - check:function(event,player){ - if(get.attitude(player,event.player)<=0) return false; - var cards=player.getCards('h',{color:'red'}); - for(var i=0;i7&&cards.length>2) return false; - } - }, - content:function(){ - "step 0" - player.showHandcards(); - "step 1" - var cards=player.getCards('h',{color:'red'}); - event.num=cards.length; - player.discard(cards); - "step 2" - trigger.player.recover(); - trigger.player.draw(event.num); - }, - ai:{ - threaten:1.6, - expose:0.2 - } - }, - qianfang:{ - trigger:{player:'phaseBegin'}, - direct:true, - filter:function(event,player){ - return player.storage.xuanning&&player.countCards('he')+player.storage.xuanning>=3; - }, - // alter:true, - content:function(){ - "step 0" - // trigger.cancel(); - var ainum=0; - var num=3-player.storage.xuanning; - var players=game.filterPlayer(); - event.targets=[]; - for(var i=0;i=0){ - switch(num){ - case 1:return 8-get.value(card); - case 2:return 6-get.value(card); - case 3:return 4-get.value(card); - } - } - return -1; - } - next.logSkill='qianfang'; - event.logged=true; - } - else{ - player.chooseBool(get.prompt2('qianfang')).ai=function(){ - return ainum>=0; - } - } - "step 1" - if(result.bool){ - player.storage.xuanning=0; - player.unmarkSkill('xuanning'); - if(!event.logged){ - player.logSkill('qianfang'); - } - player.useCard({name:'wanjian'},'qianfang',event.targets); - } - else{ - event.finish(); - } - }, - ai:{ - expose:0.1, - threaten:1.5 - }, - group:'qianfang_draw', - subSkill:{ - draw:{ - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - if(!event.player.isEnemiesOf(player)) return false; - return event.parent.skill=='qianfang'; - }, - popup:false, - content:function(){ - player.draw(); - } - } - } - }, - qianfang2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - popup:false, - content:function(){ - trigger.num++; - } - }, - poyun:{ - trigger:{source:'damageEnd'}, - // alter:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return player.storage.xuanning>0&&event.player.countCards('he')>0; - }, - direct:true, - content:function(){ - "step 0" - player.discardPlayerCard(trigger.player,'he',get.prompt('poyun',trigger.player),[1,get.is.altered('poyun')?1:2]).logSkill=['poyun',trigger.player]; - "step 1" - if(result.bool){ - player.storage.xuanning--; - if(!player.storage.xuanning){ - player.unmarkSkill('xuanning'); - } - player.syncStorage('xuanning'); - } - }, - ai:{ - threaten:1.3 - } - }, - poyun2:{ - trigger:{source:'damageEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.poyun?true:false; - }, - content:function(){ - player.draw(); - player.storage.poyun=false; - player.removeSkill('poyun2'); - } - }, - poyun3:{}, - zhuyue:{ - enable:'phaseUse', - // alter:true, - filter:function(event,player){ - if(get.is.altered('zhuyue')){ - return player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - }); - } - return player.countCards('h',{type:'basic'})0; - }, - usable:1, - locked:false, - check:function(card){ - return 7-get.value(card); - }, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - targets.sort(lib.sort.seat); - var target=targets[0]; - var cs=target.getCards('he'); - if(cs.length){ - target.discard(cs.randomGet()); - } - player.storage.zhuyue.add(target); - if(targets.length<2){ - event.finish(); - } - 'step 1' - var target=targets[1]; - var cs=target.getCards('he'); - if(cs.length){ - target.discard(cs.randomGet()); - } - player.storage.zhuyue.add(target); - }, - ai:{ - result:{ - target:function(player,target){ - if(!target.countCards('he')) return -0.2; - return -1; - } - }, - order:10, - threaten:1.2, - exoise:0.2 - }, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&player.storage.zhuyue&&player.storage.zhuyue.includes(target)){ - return true; - } - }, - selectTarget:function(card,player,range){ - if(card.name=='sha'&&player.storage.zhuyue&&player.storage.zhuyue.length){ - range[1]=-1; - range[0]=-1; - } - }, - playerEnabled:function(card,player,target){ - if(card.name=='sha'&&player.storage.zhuyue&&player.storage.zhuyue.length&&!player.storage.zhuyue.includes(target)){ - return false; - } - } - }, - intro:{ - content:'players' - }, - group:'zhuyue2' - }, - zhuyue2:{ - trigger:{player:'phaseUseEnd'}, - silent:true, - content:function(){ - player.storage.zhuyue.length=0; - } - }, - longxi:{ - trigger:{player:['chooseToRespondBegin','chooseToUseBegin']}, - forced:true, - popup:false, - max:2, - filter:function(event,player){ - return _status.currentPhase!=player; - }, - priority:101, - content:function(){ - var cards=[]; - var max=Math.min(ui.cardPile.childNodes.length,lib.skill.longxi.max); - for(var i=0;i=2; - }, - check:function(card){ - return 8-get.value(card); - }, - filterCard:function(card){ - return get.color(card)=='red'; - }, - selectCard:2, - filterTarget:function(card,player,target){ - return player!=target&&target.hp>=player.hp; - }, - intro:{ - content:'limited' - }, - line:'fire', - content:function(){ - "step 0" - player.storage.guanri=true; - player.loseHp(); - "step 1" - target.damage(2,'fire'); - "step 2" - if(target.isAlive()){ - target.discard(target.getCards('e')); - } - }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var eff=get.damageEffect(target,player,target,'fire'); - if(player.hp>2) return eff; - if(player.hp==2&&target.hp==2) return eff; - return 0; - } - }, - expose:0.5 - } - }, - tianxian:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(card.name=='sha') return true; - }, - selectTarget:function(card,player,range){ - if(card.name=='sha'&&range[1]!=-1) range[1]=Infinity; - } - }, - priority:5.5, - trigger:{player:'useCardToBefore'}, - filter:function(event){ - return event.card.name=='sha'; - }, - forced:true, - check:function(){ - return false; - }, - content:function(){ - "step 0" - trigger.target.judge(function(card){ - return get.color(card)=='black'?1:0; - }); - "step 1" - if(result.bool){ - trigger.cancel(); - } - } - }, - runxin:{ - trigger:{player:['useCard','respondEnd']}, - direct:true, - filter:function(event){ - if(get.suit(event.card)=='heart'){ - return game.hasPlayer(function(current){ - return current.isDamaged(); - }); - } - return false; - }, - content:function(){ - "step 0" - var noneed=(trigger.card.name=='tao'&&trigger.targets[0]==player&&player.hp==player.maxHp-1); - player.chooseTarget(get.prompt('runxin'),function(card,player,target){ - return target.hp0){ - if(noneed&&player==target){ - num=0.5; - } - else if(target.hp==1){ - num+=3; - } - else if(target.hp==2){ - num+=1; - } - } - return num; - } - "step 1" - if(result.bool){ - player.logSkill('runxin',result.targets); - result.targets[0].recover(); - } - }, - ai:{ - expose:0.3, - threaten:1.5 - } - }, - xjzhimeng:{ - trigger:{player:'phaseEnd'}, - direct:true, - locked:true, - unique:true, - gainable:true, - // alter:true, - group:'xjzhimeng3', - content:function(){ - "step 0" - player.chooseTarget(get.prompt('xjzhimeng'),function(card,player,target){ - return player!=target; - }).ai=function(target){ - var num=get.attitude(player,target); - if(num>0){ - if(player==target){ - num++; - } - if(target.hp==1){ - num+=3; - } - if(target.hp==2){ - num+=1; - } - } - return num; - } - "step 1" - if(result.bool){ - var target=result.targets[0]; - if(get.is.altered('xjzhimeng')){ - target.draw(); - } - else{ - var card=get.cards()[0]; - target.$draw(card); - target.storage.xjzhimeng2=card; - game.addVideo('storage',target,['xjzhimeng2',get.cardInfo(card),'card']); - target.addSkill('xjzhimeng2'); - } - player.logSkill('xjzhimeng',target); - } - }, - ai:{ - expose:0.2 - } - }, - xjzhimeng2:{ - intro:{ - content:'card', - onunmark:function(storage,player){ - delete player.storage.xjzhimeng2; - } - }, - mark:'card', - trigger:{target:'useCardToBegin'}, - frequent:true, - filter:function(event,player){ - return player.storage.xjzhimeng2&&get.type(event.card,'trick')==get.type(player.storage.xjzhimeng2,'trick'); - }, - content:function(){ - player.draw(); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target.storage.xjzhimeng2&&get.type(card,'trick')==get.type(target.storage.xjzhimeng2,'trick')){ - return [1,0.5]; - } - } - } - } - }, - xjzhimeng3:{ - trigger:{player:['phaseBegin','dieBegin']}, - silent:true, - content:function(){ - "step 0" - event.players=game.filterPlayer(); - event.num=0; - "step 1" - if(event.num1){ - return 11-get.equipValue(card); - } - if(player.countCards('h')0; - }, - ai:{ - shihuifen:true, - skillTagFilter:function(player){ - return player.countCards('he',{color:'black'})>0; - } - } - }, - tuoqiao_old:{ - filter:function(event,player){ - return game.players.length>3&&(event.player==player.next||event.player==player.previous); - }, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)<0 - }, - changeSeat:true, - trigger:{target:'useCardToBefore'}, - content:function(){ - if(trigger.player==player.next){ - game.swapSeat(player,player.previous); - } - else if(trigger.player==player.previous){ - game.swapSeat(player,player.next); - } - else{ - return; - } - trigger.cancel(); - // player.popup('xiaoyao'); - }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target==player.next||target==player.previous) return 0.1; - } - } - } - }, - tianjian_old:{ - enable:'phaseUse', - usable:1, - changeSeat:true, - filterTarget:function(card,player,target){ - return player!=target&&player.next!=target; - }, - filterCard:true, - check:function(card){ - return 4-get.value(card); - }, - content:function(){ - while(player.next!=target){ - game.swapSeat(player,player.next); - } - }, - ai:{ - order:5, - result:{ - player:function(player,target){ - var att=get.attitude(player,target); - if(target==player.previous&&att>0) return 1; - if(target==player.next.next&&get.attitude(player,player.next)<0) return 1; - return 0; - } - } - } - }, - huimeng:{ - trigger:{player:'recoverAfter'}, - frequent:true, - content:function(){ - player.draw(2); - }, - ai:{ - threaten:0.8 - } - }, - tianshe:{ - group:['tianshe2'], - trigger:{player:'damageBefore'}, - filter:function(event){ - if(event.hasNature()) return true; - return false; - }, - forced:true, - content:function(){ - trigger.cancel(); - }, - ai:{ - nofire:true, - nothunder:true, - effect:{ - target:function(card,player,target,current){ - if(card.name=='tiesuo') return 0; - if(get.tag(card,'fireDamage')) return 0; - if(get.tag(card,'thunderDamage')) return 0; - } - } - } - }, - tianshe2:{ - trigger:{source:'damageAfter'}, - filter:function(event,player){ - if(event.hasNature()&&player.hp= 3 && player.getHistory("useCard").length > player.hp; + }, + content: function () { + "step 0"; + player.awakenSkill("lingquan"); + player.draw(3); + player.addSkill("shuiyun"); + "step 1"; + if (lib.filter.filterTrigger(trigger, player, "phaseEnd", "shuiyun")) + game.createTrigger("phaseEnd", "shuiyun", player, trigger); + }, + }, + shenwu: { + trigger: { global: "phaseEnd" }, + forced: true, + skillAnimation: true, + animationColor: "water", + unique: true, + filter: function (event, player) { + return player.storage.shuiyun_count >= 3; + }, + content: function () { + player.awakenSkill("shenwu"); + player.gainMaxHp(); + player.recover(); + player.addSkill("huimeng"); + }, + }, + qiongguang: { + trigger: { player: "phaseDiscardEnd" }, + filter: function (event, player) { + return event.cards && event.cards.length > 1; + }, + content: function () { + "step 0"; + event.targets = player.getEnemies().sortBySeat(); + "step 1"; + if (event.targets.length) { + player.line(event.targets.shift().getDebuff(false).addExpose(0.1), "green"); + event.redo(); + } + "step 2"; + game.delay(); + }, + ai: { + threaten: 2, + expose: 0.2, + effect: { + player: function (card, player) { + if (_status.currentPhase != player) return; + if (_status.event.name != "chooseToUse" || _status.event.player != player) return; + var num = player.needsToDiscard(); + if (num > 2 || num == 1) return; + if (get.type(card) == "basic" && num != 2) return; + if (get.tag(card, "gain")) return; + if (get.value(card, player, "raw") >= 7) return; + if (player.hp <= 2) return; + if (!player.hasSkill("jilue") || player.storage.renjie == 0) { + return "zeroplayertarget"; + } + }, + }, + }, + }, + txianqu: { + trigger: { source: "damageBefore" }, + logTarget: "player", + filter: function (event, player) { + if (player.hasSkill("txianqu2")) return false; + var evt = event.getParent("phaseUse"); + if (evt && evt.player == player) return true; + return false; + }, + check: function (event, player) { + var target = event.player; + if (get.attitude(player, target) >= 0 || get.damageEffect(target, player, player) <= 0) + return true; + if (target.hp > player.hp && player.isDamaged()) return true; + return false; + }, + content: function () { + trigger.cancel(); + player.draw(2); + player.recover(); + player.addTempSkill("txianqu2"); + }, + ai: { + jueqing: true, + skillTagFilter: function (player, tag, arg) { + if (!arg) return false; + if (player.hasSkill("txianqu2")) return false; + if (get.attitude(player, arg) > 0) return false; + var evt = _status.event.getParent("phaseUse"); + if (evt && evt.player == player) return true; + return false; + }, + effect: { + player: function (card, player, target) { + if (get.tag(card, "damage") && get.attitude(player, target) > 0) { + if ( + player.hp == player.maxHp || + get.recoverEffect(player, player, player) <= 0 + ) + return "zeroplayertarget"; + return [0, 0, 0, 0.5]; + } + }, + }, + }, + }, + txianqu2: {}, + xunying: { + trigger: { player: "shaAfter" }, + direct: true, + filter: function (event, player) { + return player.canUse("sha", event.target) && player.hasSha() && event.target.isIn(); + }, + content: function () { + "step 0"; + if (player.hasSkill("jiu")) { + player.removeSkill("jiu"); + event.jiu = true; + } + player.chooseToUse(get.prompt("xunying"), { name: "sha" }, trigger.target, -1).logSkill = + "xunying"; + "step 1"; + if (result.bool); + else if (event.jiu) { + player.addSkill("jiu"); + } + }, + }, + liefeng: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter: function (event, player) { + return _status.currentPhase == player && [2, 3, 4].includes(player.countUsed()); + }, + content: function () { + var skill; + switch (player.countUsed()) { + case 2: + skill = "yanzhan"; + break; + case 3: + skill = "tianjian"; + break; + case 4: + skill = "xjyufeng"; + break; + } + if (skill && !player.hasSkill(skill)) { + player.addTempSkill(skill); + player.popup(skill); + game.log(player, "获得了", "【" + get.translation(skill) + "】"); + if (skill == "xjyufeng") { + var nh = player.countCards("h"); + if (nh < 2) { + player.draw(2 - nh); + player.addSkill("counttrigger"); + if (!player.storage.counttrigger) { + player.storage.counttrigger = {}; + } + player.storage.counttrigger.xjyufeng = 1; + } + } + } + }, + ai: { + effect: { + player: function (card, player) { + if (_status.currentPhase != player) return; + if (get.type(card) == "basic") return; + if (get.tag(card, "gain")) return; + if (get.value(card, player, "raw") >= 7) return; + if (player.hp <= 2) return; + if (player.needsToDiscard()) return; + if (player.countUsed() >= 2) return; + return "zeroplayertarget"; + }, + }, + }, + }, + yuexing: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player; + }, + content: function () { + player.storage.yuexing2 = target; + player.addTempSkill("yuexing2"); + target.storage.yuexing2 = player; + target.addTempSkill("yuexing2"); + }, + ai: { + order: function () { + var player = _status.event.player; + if (player.hasSkill("minsha")) return 6.5; + return 2; + }, + result: { + target: function (player, target) { + if ( + player.hasSkill("minsha") && + player.countCards("he") >= 3 && + target.hp > 1 && + get.damageEffect(target, player, player, "thunder") > 0 + ) { + var num1 = game.countPlayer(function (current) { + if ( + get.distance(target, current) <= 1 && + current != player && + current != target + ) { + return -get.sgn(get.attitude(player, current)); + } + }); + var num2 = game.countPlayer(function (current) { + if ( + get.distance(player, current) <= 1 && + current != player && + current != target + ) { + return -get.sgn(get.attitude(player, current)); + } + }); + if (num2 >= num1) return 0; + return 2 * (num2 - num1); + } + return -_status.event.getRand(); + }, + }, + }, + }, + yuexing2: { + mark: "character", + intro: { + content: "到其他角色的距离基数与$交换", + }, + onremove: true, + mod: { + globalFrom: function (from, to, distance) { + if (from.storage.yuexing2) { + var dist1 = get.distance(from, to, "pure"); + var dist2 = get.distance(from.storage.yuexing2, to, "pure"); + return distance - dist1 + dist2; + } + }, + }, + }, + minsha: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 2, + position: "he", + filter: function (event, player) { + return player.countCards("he") >= 2; + }, + filterTarget: function (card, player, target) { + return target != player && target.hp > 1; + }, + line: "thunder", + check: function (card) { + return 8 - get.value(card); + }, + content: function () { + "step 0"; + target.damage("thunder"); + "step 1"; + event.targets = game + .filterPlayer(function (current) { + return ( + get.distance(target, current) <= 1 && current != target && current != player + ); + }) + .sortBySeat(target); + "step 2"; + if (event.targets.length) { + event.targets.shift().randomDiscard(false); + event.redo(); + } + }, + ai: { + order: 6, + result: { + player: function (player, target) { + if (get.damageEffect(target, player, player, "thunder") > 0) { + if (target == player.storage.yuexing2) { + return 10; + } + var num = + 1 + + game.countPlayer(function (current) { + if ( + get.distance(target, current) <= 1 && + current != player && + current != target + ) { + return -get.sgn(get.attitude(player, current)); + } + }); + if (target.hp == 1) { + num += 2; + } + if (target.hp < player.hp) { + num += 0.5; + } + if (player.needsToDiscard()) num += 0.1; + return num; + } + }, + }, + }, + }, + lingdi: { + enable: "phaseUse", + filter: function (event, player) { + var num = 1 + (player.getStat().skill.lingdi || 0); + if ( + game.hasPlayer(function (current) { + return current != player && Math.max(1, get.distance(player, current)) == num; + }) + ) { + var hs = player.getCards("h"); + var suits = player.storage.lingdi || []; + for (var i = 0; i < hs.length; i++) { + if (!suits.includes(get.suit(hs[i]))) { + return true; + } + } + } + return false; + }, + filterTarget: function (card, player, target) { + return ( + target != player && + Math.max(1, get.distance(player, target)) == 1 + (player.getStat().skill.lingdi || 0) + ); + }, + filterCard: function (card, player) { + return !(player.storage.lingdi || []).includes(get.suit(card)); + }, + check: function (card) { + return 8 - get.value(card); + }, + content: function () { + game.asyncDraw([player, target]); + if (!player.storage.lingdi) { + player.storage.lingdi = []; + } + player.storage.lingdi.add(get.suit(cards[0])); + }, + ai: { + threaten: 1.2, + order: 7, + result: { + target: 1, + }, + }, + group: "lingdi_clear", + subSkill: { + clear: { + trigger: { player: "phaseAfter" }, + silent: true, + content: function () { + delete player.storage.lingdi; + }, + }, + }, + }, + xiaoyue: { + trigger: { global: "roundStart" }, + forced: true, + filter: function (event, player) { + return player.countCards("h", "sha"); + }, + content: function () { + var card = player.getCards("h", "sha").randomGet(); + var target = player.getEnemies().randomGet(); + if (card && target) { + target.addExpose(0.1); + player.useCard(card, target, false); + player.changeHujia(); + } + }, + ai: { + effect: { + player: function (card, player, target) { + if (_status.currentPhase != player) return; + if ( + card.name == "sha" && + get.itemtype(card) == "card" && + !player.needsToDiscard() && + target.hp > 1 && + player.countCards("h", "sha") == 1 + ) { + return "zeroplayertarget"; + } + }, + }, + }, + }, + xiaoyue2: { + mod: { + cardRespondable: function (card, player) { + if (_status.event.getParent(4).name == "xiaoyue" && get.suit(card) != "heart") + return false; + }, + }, + }, + huanlei: { + trigger: { player: "damageEnd" }, + check: function (event, player) { + return get.damageEffect(event.source, player, player, "thunder") > 0; + }, + filter: function (event, player) { + return event.source && event.source.isIn() && event.source.hp > player.hp; + }, + logTarget: "source", + content: function () { + "step 0"; + trigger.source.damage("thunder"); + "step 1"; + trigger.source.draw(); + }, + }, + anwugu: { + trigger: { source: "damageEnd" }, + check: function (event, player) { + return get.attitude(player, event.player) < 0; + }, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player != player && event.player.isIn() && !event.player.hasSkill("anwugu2"); + }, + logTarget: "player", + content: function () { + trigger.player.addSkill("anwugu2"); + }, + }, + anwugu2: { + mod: { + cardEnabled: function (card, player) { + if (_status.currentPhase != player) return; + if (player.countUsed() >= player.storage.anwugu2) return false; + }, + maxHandcard: function (player, num) { + return num - 1; + }, + }, + mark: true, + intro: { + content: "手牌上限-1,每回合最多使用$张牌(剩余$回合)", + }, + init: function (player) { + player.storage.anwugu2 = 3; + }, + trigger: { player: "phaseAfter" }, + silent: true, + onremove: true, + content: function () { + player.storage.anwugu2--; + if (player.storage.anwugu2 <= 0) { + // player.loseHp(); + player.removeSkill("anwugu2"); + } else { + player.updateMarks(); + } + }, + }, + xtanxi: { + enable: "phaseUse", + usable: 1, + filterCard: true, + check: function (card) { + var enemies = _status.event.player.getEnemies(); + var num1 = 0, + num2 = 0; + for (var i = 0; i < enemies.length; i++) { + if (enemies[i].countCards("h", "sha")) num1++; + if (enemies[i].countCards("h", "shan")) num2++; + if (enemies[i].countCards("h") >= 3) { + num1 += 0.5; + num2 += 0.5; + } + } + var rand = _status.event.getRand(); + if (num1 >= 1 && num2 >= 1) { + if (card.name == "shan") return (rand += 0.4); + if (card.name == "sha") return rand; + } else if (num1 >= 1) { + if (card.name == "sha") return rand; + } else if (num2 >= 1) { + if (card.name == "shan") return rand; + } + return 0; + }, + content: function () { + player.addExpose(0.1); + var targets = player.getEnemies(); + for (var i = 0; i < targets.length; i++) { + if (!targets[i].countCards("h", cards[0].name)) { + targets.splice(i--, 1); + } + } + if (targets.length) { + var target = targets.randomGet(); + player.line(target, "green"); + target.addExpose(0.1); + player.gainPlayerCard(target, "h", "visible"); + } + }, + ai: { + order: 4, + result: { + player: 1, + }, + }, + }, + linghuo: { + round: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + return event.player.getStat("damage") && event.player != player; + }, + check: function (event, player) { + return get.damageEffect(event.player, player, player, "fire") > 0; + }, + logTarget: "player", + line: "fire", + ai: { + expose: 0.2, + threaten: 1.3, + }, + content: function () { + trigger.player.damage("fire"); + }, + }, + guijin: { + round: 3, + enable: "phaseUse", + delay: 0, + content: function () { + "step 0"; + event.cards = get.cards(4); + "step 1"; + if (event.cards.length) { + var more = false, + remain = false, + nomore = false; + if (event.cards.length >= 3) { + for (var i = 0; i < event.cards.length; i++) { + var value = get.value(event.cards[i], player, "raw"); + if (value >= 8) { + more = true; + } + if (event.cards.length >= 4 && value < 6) { + if (remain === false) { + remain = value; + } else { + remain = Math.min(remain, value); + } + } + } + } + if (remain === false) { + remain = 0; + } + if ( + !more && + !game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + !current.skipList.includes("phaseDraw") + ); + }) + ) { + var num = 0; + for (var i = 0; i < event.cards.length; i++) { + num += Math.max(0, get.value(event.cards[i], player, "raw")); + } + if (num >= 12) { + more = true; + } else { + nomore = true; + } + } + player.chooseCardButton("归烬", event.cards, [1, event.cards.length]).ai = function ( + button + ) { + if (nomore) return 0; + if (more) { + return get.value(button.link, player, "raw") - remain; + } else { + if (ui.selected.buttons.length) return 0; + return 8 - get.value(button.link, player, "raw"); + } + }; + } else { + event.goto(4); + } + "step 2"; + if (result.bool) { + for (var i = 0; i < result.links.length; i++) { + event.cards.remove(result.links[i]); + } + event.togive = result.links.slice(0); + player.chooseTarget("将" + get.translation(result.links) + "交给一名角色", true).ai = + function (target) { + var att = + get.attitude(player, target) / Math.sqrt(target.countCards("h") + 1); + if (result.links.length > 1) { + if (target == player && target.needsToDiscard(result.links) > 1) + return att / 5; + return att; + } else { + if (target.skipList.includes("phaseDraw")) return att / 5; + return -att; + } + }; + } else { + event.goto(4); + } + "step 3"; + if (result.targets.length) { + result.targets[0].gain(event.togive, "draw"); + result.targets[0].skip("phaseDraw"); + result.targets[0].addTempSkill("guijin2", { player: "phaseBegin" }); + game.log( + result.targets[0], + "获得了" + get.cnNumber(event.togive.length) + "张", + "#g“归烬”牌" + ); + player.line(result.targets[0], "green"); + event.goto(1); + } + "step 4"; + while (event.cards.length) { + ui.cardPile.insertBefore(event.cards.pop(), ui.cardPile.firstChild); + } + }, + ai: { + order: 1, + result: { + player: function (player) { + if (game.roundNumber == 1 && player.hasUnknown()) return 0; + return 1; + }, + }, + }, + }, + guijin2: { + mark: true, + intro: { + content: "跳过下一个摸牌阶段", + }, + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "bingliang" || card.name == "caomu") return 0; + }, + }, + }, + }, + chengxin: { + round: 4, + enable: "chooseToUse", + filter: function (event, player) { + return event.type == "dying"; + }, + filterTarget: function (card, player, target) { + return target == _status.event.dying; + }, + selectTarget: -1, + content: function () { + target.recover(1 - target.hp); + target.addTempSkill("chengxin2", { player: "phaseAfter" }); + }, + ai: { + order: 6, + threaten: 1.4, + skillTagFilter: function (player) { + if (4 - (game.roundNumber - player.storage.chengxin_roundcount) > 0) return false; + if (!_status.event.dying) return false; + }, + save: true, + result: { + target: 3, + }, + }, + }, + chengxin2: { + trigger: { player: "damageBefore" }, + mark: true, + forced: true, + content: function () { + trigger.cancel(); + }, + ai: { + nofire: true, + nothunder: true, + nodamage: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage")) return [0, 0]; + }, + }, + }, + intro: { + content: "防止一切伤害", + }, + }, + tianwu: { + trigger: { player: "useCardToBegin" }, + filter: function (event, player) { + if (get.is.altered("tianwu") && player.hasSkill("tianwu2")) return false; + return ( + event.targets && + event.targets.length == 1 && + player.getEnemies().includes(event.target) + ); + }, + // alter:true, + frequent: true, + content: function () { + trigger.target.getDebuff(); + player.addTempSkill("tianwu2"); + }, + }, + tianwu2: {}, + shiying: { + trigger: { global: "dieBefore" }, + skillAnimation: "epic", + animationColor: "water", + unique: true, + init: function (player) { + player.storage.shiying = false; + }, + mark: true, + intro: { + content: "limited", + }, + check: function (event, player) { + return get.attitude(player, event.player) >= 3; + }, + filter: function (event, player) { + return !player.storage.shiying && event.player != player; + }, + logTarget: "player", + content: function () { + "step 0"; + trigger.cancel(); + player.awakenSkill("shiying"); + player.storage.shiying = true; + + player.maxHp = 3; + player.hp = 3; + trigger.player.maxHp = 3; + trigger.player.hp = 3; + + player.clearSkills(); + trigger.player.clearSkills(); + "step 1"; + var hs = player.getCards("hej"); + player.$throw(hs); + player.lose(player.getCards("hej"))._triggered = null; + "step 2"; + var hs = trigger.player.getCards("hej"); + trigger.player.$throw(hs); + trigger.player.lose(trigger.player.getCards("hej"))._triggered = null; + "step 3"; + game.asyncDraw([player, trigger.player], 3); + }, + ai: { + threaten: 1.5, + }, + }, + liguang: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + if (!player.canMoveCard()) return false; + if ( + !game.hasPlayer(function (current) { + return current.countCards("ej"); + }) + ) { + return false; + } + return player.countCards("h") > 0; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseToDiscard( + get.prompt("liguang"), + "弃置一张手牌并移动场上的一张牌", + lib.filter.cardDiscardable + ) + .set("ai", function (card) { + if (!_status.event.check) return 0; + return 7 - get.useful(card); + }) + .set("check", player.canMoveCard(true)) + .set("logSkill", "liguang"); + "step 1"; + if (result.bool) { + player.moveCard(true); + } else { + event.finish(); + } + }, + ai: { + expose: 0.2, + threaten: 1.3, + }, + }, + xiepan: { + trigger: { player: "loseEnd" }, + direct: true, + filter: function (event, player) { + if (player.countCards("h", { type: "basic" })) return false; + if (!player.countCards("h")) return false; + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].original == "h" && get.type(event.cards[i]) == "basic") + return true; + } + return false; + }, + content: function () { + "step 0"; + player + .chooseToDiscard("h", get.prompt("xiepan")) + .set("prompt2", "弃置一张手牌并获一件随机装备") + .set("logSkill", "xiepan").ai = function (card) { + return 8 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.gain(game.createCard(get.inpile("equip").randomGet()), "draw"); + } + }, + }, + yujia: { + trigger: { player: "useCardAfter" }, + frequent: true, + filter: function (event) { + return get.type(event.card) == "equip" && lib.inpile.includes(event.card.name); + }, + init: function (player) { + player.storage.yujia = 0; + }, + content: function () { + "step 0"; + if (!player.storage.yujia) { + player.storage.yujia = []; + } + var list = []; + for (var i in lib.card) { + if (lib.card[i].type == "jiguan") { + list.push(i); + } + } + if (list.length) { + if (player.storage.yujia > 1) { + list = list.randomGets(player.storage.yujia); + for (var i = 0; i < list.length; i++) { + list[i] = ["机关", "", list[i]]; + } + player.chooseButton(true, ["御甲:选择一张机关牌获得之", [list, "vcard"]]).ai = + function (button) { + if ( + player.hasSkill("jiguanyaoshu_skill") && + button.link[2] == "jiguanyaoshu" + ) + return 0; + return get.value({ name: button.link[2] }); + }; + } else { + var name = list.randomGet(); + player.gain(game.createCard(name), "draw"); + event.finish(); + } + } + "step 1"; + if (result.bool && result.links && result.links.length) { + var list = []; + for (var i = 0; i < result.links.length; i++) { + list.push(game.createCard(result.links[i][2])); + } + player.gain(list, "draw"); + } + }, + group: "yujia_count", + subSkill: { + count: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return get.type(event.card) == "jiguan"; + }, + silent: true, + content: function () { + player.storage.yujia++; + }, + }, + }, + ai: { + reverseEquip: true, + threaten: 1.5, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") return [1, 3]; + }, + }, + }, + }, + yanshi: { + trigger: { player: "phaseAfter" }, + forced: true, + skillAnimation: true, + init: function (player) { + player.storage.yanshi = 0; + }, + filter: function (event, player) { + return player.storage.yanshi == 4; + }, + intro: { + content: "累计#个回合使用过机关牌", + }, + content: function () { + "step 0"; + player.awakenSkill("yanshi"); + player.gainMaxHp(); + "step 1"; + player.recover(); + var list = []; + for (var i = 1; i <= 5; i++) { + if (!player.getEquip(i)) { + var name = get.inpile("equip" + i).randomGet(); + if (name) { + var card = game.createCard(name); + list.push(card); + player.equip(card); + } + } + } + if (list.length) { + player.$draw(list); + } + }, + group: "yanshi_count", + subSkill: { + count: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return get.type(event.card) == "jiguan" && !player.hasSkill("yanshi2"); + }, + silent: true, + content: function () { + player.storage.yanshi++; + if (player.hasSkill("yanshi")) { + player.markSkill("yanshi"); + player.updateMarks(); + } + player.addTempSkill("yanshi2"); + }, + }, + }, + }, + yanshi2: {}, + tanhua: { + trigger: { player: "recoverBefore" }, + forced: true, + filter: function (event, player) { + return player.hp > 0 && event.num > 0; + }, + content: function () { + trigger.cancel(); + player.draw(2 * trigger.num); + }, + group: "tanhua_remove", + subSkill: { + remove: { + trigger: { player: "dying" }, + priority: 10, + forced: true, + content: function () { + player.recover(); + player.removeSkill("tanhua"); + }, + }, + }, + }, + xjyingfeng: { + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.parent.name == "xjyingfeng") return false; + var enemies = player.getEnemies(); + return game.hasPlayer(function (current) { + return ( + enemies.includes(current) && + !event.targets.includes(current) && + player.canUse("sha", current, false) + ); + }); + }, + forced: true, + content: function () { + var enemies = player.getEnemies(); + enemies.remove(trigger.targets); + if (enemies.length) { + player.useCard({ name: "sha" }, enemies.randomGet().addExpose(0.2)); + } + }, + }, + ywuhun: { + trigger: { player: "phaseBefore" }, + forced: true, + // alter:true, + filter: function (event) { + return event.parent.name != "ywuhun"; + }, + intro: { + content: "回合结束后,场上及牌堆中的牌将恢复到回合前的状态", + }, + video: function (player, data) { + for (var i in data) { + var current = game.playerMap[i]; + current.node.handcards1.innerHTML = ""; + current.node.handcards2.innerHTML = ""; + current.node.equips.innerHTML = ""; + current.node.judges.innerHTML = ""; + current.directgain(get.infoCards(data[i].h)); + var es = get.infoCards(data[i].e); + for (var j = 0; j < es.length; j++) { + current.$equip(es[j]); + } + var js = get.infoCards(data[i].j); + for (var j = 0; j < js.length; j++) { + current.node.judges.appendChild(js[j]); + } + } + }, + content: function () { + "step 0"; + var handcards1, handcards2, judges, equips, viewAs, i, j; + event.data = []; + event.cardPile = []; + + for (i = 0; i < game.players.length; i++) { + viewAs = []; + handcards1 = []; + handcards2 = []; + judges = []; + equips = []; + + for (j = 0; j < game.players[i].node.handcards1.childNodes.length; j++) + handcards1.push(game.players[i].node.handcards1.childNodes[j]); + + for (j = 0; j < game.players[i].node.handcards2.childNodes.length; j++) + handcards2.push(game.players[i].node.handcards2.childNodes[j]); + + for (j = 0; j < game.players[i].node.judges.childNodes.length; j++) { + viewAs.push(game.players[i].node.judges.childNodes[j].viewAs); + judges.push(game.players[i].node.judges.childNodes[j]); + } + + for (j = 0; j < game.players[i].node.equips.childNodes.length; j++) + equips.push(game.players[i].node.equips.childNodes[j]); + + event.data.push({ + player: game.players[i], + handcards1: handcards1, + handcards2: handcards2, + judges: judges, + equips: equips, + viewAs: viewAs, + value: handcards1.length + handcards2.length + equips.length - judges.length, + }); + } + for (var i = 0; i < ui.cardPile.childElementCount; i++) { + event.cardPile.push(ui.cardPile.childNodes[i]); + } + "step 1"; + player.markSkill("ywuhun"); + player.addSkill("ywuhun_end"); + player.phase("ywuhun"); + "step 2"; + player.removeSkill("ywuhun_end"); + game.delay(0.5); + "step 3"; + game.animate.window(1); + "step 4"; + player.unmarkSkill("ywuhun"); + var storage = event.data; + for (var i = 0; i < storage.length; i++) { + var current = storage[i].player; + if (current.isAlive()) { + current.removeEquipTrigger(); + var cards = current.getCards("hej"); + for (var j = 0; j < cards.length; j++) { + cards[j].discard(); + } + } + } + "step 5"; + var storage = event.data; + var current; + var i, j; + for (i = 0; i < storage.length; i++) { + current = storage[i].player; + if (current.isAlive()) { + for (j = 0; j < storage[i].handcards1.length; j++) { + if ( + storage[i].handcards1[j].parentNode == ui.discardPile || + storage[i].handcards1[j].parentNode == ui.cardPile + ) { + current.node.handcards1.appendChild(storage[i].handcards1[j]); + } else { + current.node.handcards1.appendChild( + game.createCard(storage[i].handcards1[j]) + ); + } + } + for (j = 0; j < storage[i].handcards2.length; j++) { + if ( + storage[i].handcards2[j].parentNode == ui.discardPile || + storage[i].handcards2[j].parentNode == ui.cardPile + ) { + current.node.handcards2.appendChild(storage[i].handcards2[j]); + } else { + current.node.handcards2.appendChild( + game.createCard(storage[i].handcards2[j]) + ); + } + } + for (j = 0; j < storage[i].equips.length; j++) { + if ( + storage[i].equips[j].parentNode == ui.discardPile || + storage[i].equips[j].parentNode == ui.cardPile + ) { + storage[i].equips[j].style.transform = ""; + current.$equip(storage[i].equips[j]); + } else { + current.$equip(game.createCard(storage[i].equips[j])); + } + } + for (j = 0; j < storage[i].judges.length; j++) { + if ( + storage[i].judges[j].parentNode == ui.discardPile || + storage[i].judges[j].parentNode == ui.cardPile + ) { + storage[i].judges[j].style.transform = ""; + storage[i].judges[j].viewAs = storage[i].viewAs[j]; + if ( + storage[i].judges[j].viewAs && + storage[i].judges[j].viewAs != storage[i].judges[j].name && + storage[i].judges[j].classList.contains("fullskin") + ) { + storage[i].judges[j].classList.add("fakejudge"); + storage[i].judges[j].node.background.innerHTML = + lib.translate[storage[i].judges[j].viewAs + "_bg"] || + get.translation(storage[i].judges[j].viewAs)[0]; + } + current.node.judges.appendChild(storage[i].judges[j]); + } + } + current.update(); + } + } + var data = {}; + for (var i = 0; i < game.players.length; i++) { + data[game.players[i].dataset.position] = { + h: get.cardsInfo(game.players[i].getCards("h")), + e: get.cardsInfo(game.players[i].getCards("e")), + j: get.cardsInfo(game.players[i].getCards("j")), + }; + } + game.addVideo("skill", event.player, ["ywuhun", data]); + game.animate.window(2); + while (ui.cardPile.childElementCount) { + ui.cardPile.firstChild.discard(); + } + for (var i = 0; i < event.cardPile.length; i++) { + if (event.cardPile[i].parentNode == ui.discardPile) { + ui.cardPile.appendChild(event.cardPile[i]); + } else { + ui.cardPile.appendChild(game.createCard(event.cardPile[i])); + } + } + ui.updatehl(); + }, + subSkill: { + end: { + trigger: { source: "damageEnd" }, + priority: 9, + silent: true, + content: function () { + var evt = _status.event.getParent("ywuhun"); + if (evt) { + _status.event = evt; + game.resetSkills(); + } + }, + ai: { + jueqing: true, + }, + }, + }, + }, + fenglue: { + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + var hs = player.getCards("h"); + return game.hasPlayer(function (current) { + if (current != player) { + for (var i = 0; i < hs.length; i++) { + if (get.info(hs[i]).multitarget) continue; + if (lib.filter.targetEnabled2(hs[i], player, current)) { + return true; + } + } + } + }); + }, + content: function () { + "step 0"; + var hs = player.getCards("h"); + player.chooseTarget(get.prompt("fenglue"), function (card, player, target) { + if (player == target) return false; + for (var i = 0; i < hs.length; i++) { + if (get.info(hs[i]).multitarget) continue; + if (lib.filter.targetEnabled2(hs[i], player, target)) { + return true; + } + } + return false; + }).ai = function (target) { + var use = [], + eff = 0, + damaged = false; + for (var i = 0; i < hs.length; i++) { + if (get.info(hs[i]).multitarget) continue; + var hef; + if (get.tag(hs[i], "damage") && damaged) { + hef = -1; + } else { + hef = get.effect(target, hs[i], player, player); + } + if (lib.filter.targetEnabled2(hs[i], player, target) && hef > 0) { + use.push(hs[i]); + if (get.attitude(player, target) > 0) { + hef /= 1.5; + if (get.tag(hs[i], "damage")) { + damaged = true; + } + } + eff += hef; + } + } + if ( + !player.needsToDiscard(0, (i, player) => { + return !use.includes(i) && !player.canIgnoreHandcard(i); + }) + ) + return eff; + return 0; + }; + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + var num = 0; + player.chooseCard( + [1, Infinity], + "按顺序选择对" + get.translation(result.targets) + "使用的牌", + function (card) { + return lib.filter.targetEnabled2(card, player, event.target); + } + ).ai = function (card) { + if (get.effect(event.target, card, player, player) > 0) { + if (get.attitude(player, event.target) > 0 && get.tag(card, "damage")) { + for (var i = 0; i < ui.selected.cards.length; i++) { + if (get.tag(ui.selected.cards[i], "damage")) { + return 0; + } + } + } + return get.order(card); + } + return 0; + }; + } else { + event.finish(); + } + "step 2"; + if (result.bool) { + player.logSkill("fenglue", event.target); + player.addSkill("fenglue_draw"); + player.storage.fenglue_draw_num = 0; + player.storage.fenglue_draw = event.target; + trigger.cancel(); + event.cards = result.cards.slice(0); + player.lose(event.cards, ui.special); + } else { + event.finish(); + } + "step 3"; + if (event.cards.length) { + if (event.target.isIn()) { + player.useCard(event.cards.shift(), event.target); + } else { + event.cards.shift().discard(); + } + event.redo(); + } + "step 4"; + if (player.storage.fenglue_draw_num) { + player.draw(player.storage.fenglue_draw_num); + } + player.removeSkill("fenglue_draw"); + delete player.storage.fenglue_draw; + delete player.storage.fenglue_draw_num; + }, + subSkill: { + draw: { + trigger: { global: "damageEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.fenglue_draw; + }, + content: function () { + player.storage.fenglue_draw_num++; + }, + }, + }, + ai: { + threaten: 1.3, + }, + }, + xjzongyu: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "black" }, + filter: function (event, player) { + return lib.card.feibiao && player.countCards("he", { color: "black" }); + }, + check: function (card) { + return 8 - get.value(card); + }, + content: function () { + var list = player.getEnemies(); + if (list.length) { + player.useCard({ name: "feibiao" }, list.randomGets(2)); + } + }, + ai: { + threaten: 1.5, + order: 6, + result: { + player: 1, + }, + }, + }, + fanling: { + trigger: { global: "loseHpAfter" }, + forced: true, + usable: 1, + filter: function (event, player) { + return event.player != player && player.isDamaged(); + }, + content: function () { + player.recover(); + }, + ai: { + threaten: 1.5, + }, + }, + dujiang: { + enable: "phaseUse", + usable: 1, + position: "he", + filterCard: { color: "black" }, + check: function (card) { + return 6 - get.value(card); + }, + content: function () { + var list = player.getEnemies(); + if (list.length) { + var target = list.randomGet(); + player.line(target, "green"); + target.gain(game.createCard("du"), "gain2"); + } + }, + ai: { + order: 1, + result: { + player: 1, + }, + threaten: 1.5, + }, + }, + sheying: { + trigger: { source: "damageAfter" }, + filter: function (event, player) { + return get.itemtype(event.cards) == "cards" && get.position(event.cards[0]) == "d"; + }, + usable: 1, + prompt2: function (event) { + return "进行一次判定,若结果为黑色,你获得" + get.translation(event.cards); + }, + content: function () { + "step 0"; + player.judge(function (card) { + return get.color(card) == "black" ? 1 : -1; + }); + "step 1"; + if (result.color == "black") { + player.gain(trigger.cards); + player.$gain2(trigger.cards); + } + }, + }, + huahu: { + enable: "phaseUse", + unique: true, + mark: true, + skillAnimation: true, + animationColor: "metal", + init: function (player) { + player.storage.huahu = false; + }, + filter: function (event, player) { + if (player.storage.huahu) return false; + return true; + }, + filterTarget: function (card, player, target) { + return target != player; + }, + selectTarget: [1, Infinity], + contentBefore: function () { + player.awakenSkill("huahu"); + player.storage.huahu = true; + player.loseMaxHp(true); + player.clearSkills(); + }, + content: function () { + target.recover(); + target.changeHujia(); + target.draw(false); + target.$draw(); + }, + ai: { + order: 1, + result: { + target: function (player, target) { + if (player.hasUnknown()) return 0; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + get.attitude(player, players[i]) > 2 && + get.recoverEffect(players[i], player, player) > 0 + ) { + if (players[i].hp == 1) { + if (player.hp < player.maxHp) { + return 1; + } else { + num += 2; + } + } else if (players[i].hp <= 2) { + num++; + } + } + } + if (num >= 3) return 1; + return 0; + }, + }, + }, + intro: { + content: "limited", + }, + }, + binxin: { + trigger: { global: "phaseEnd" }, + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + filter: function (event, player) { + return event.player.hp == 1; + }, + logTarget: "player", + content: function () { + trigger.player.changeHujia(); + }, + ai: { + expose: 0.1, + }, + }, + qixia: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + silent: true, + init: function (player) { + player.storage.qixia = []; + }, + // mark:true, + intro: { + content: function (storage) { + if (!storage.length) { + return "未使用或打出过有花色的牌"; + } else { + var str = "已使用过" + get.translation(storage[0] + "2"); + for (var i = 1; i < storage.length; i++) { + str += "、" + get.translation(storage[i] + "2"); + } + str += "牌"; + return str; + } + }, + }, + content: function () { + var suit = get.suit(trigger.card); + if (suit) { + player.storage.qixia.add(suit); + player.syncStorage("qixia"); + player.markSkill("qixia"); + } + }, + group: "qixia_phase", + subSkill: { + phase: { + trigger: { global: "phaseAfter" }, + priority: -50, + forced: true, + filter: function (event, player) { + return player.storage.qixia.length >= 4; + }, + content: function () { + player.insertPhase(); + player.storage.qixia.length = 0; + player.syncStorage("qixia"); + player.unmarkSkill("qixia"); + }, + }, + }, + }, + qixia_old: { + trigger: { global: "damageAfter" }, + direct: true, + filter: function (event, player) { + return ( + !player.hasSkill("qixia2") && + event.source != player && + event.player.isIn() && + player.countCards("he", { color: "red" }) + ); + }, + content: function () { + "step 0"; + player + .chooseToDiscard("he", get.prompt("qixia", trigger.player), { color: "red" }) + .set("logSkill", ["qixia", trigger.player]).ai = function (card) { + if (get.attitude(player, trigger.player) > 0) { + if (trigger.player.hp == 1) { + return 10 - get.value(card); + } + return 8 - get.value(card); + } + }; + "step 1"; + if (result.bool) { + player.addTempSkill("qixia2"); + trigger.player.draw(2); + if (trigger.player.hp == 1 && !trigger.player.hujia) { + trigger.player.changeHujia(); + } + } + }, + ai: { + threaten: 1.8, + }, + }, + qixia2: {}, + jianzhen: { + trigger: { player: "shaAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.target.isIn() && + game.hasPlayer(function (current) { + return current.canUse("sha", event.target, false) && current != player; + }) + ); + }, + content: function () { + "step 0"; + event.targets = game.filterPlayer(function (current) { + return current.canUse("sha", trigger.target, false) && current != player; + }); + event.targets.sortBySeat(trigger.player); + "step 1"; + if (event.targets.length) { + event.current = event.targets.shift(); + if (event.current.hasSha()) { + event.current.chooseToUse( + { name: "sha" }, + "是否对" + get.translation(trigger.target) + "使用一张杀?", + trigger.target, + -1 + ); + } else { + event.redo(); + } + } else { + event.finish(); + } + "step 2"; + if (!result.bool) { + event.goto(1); + } + }, + ai: { + expose: 0.2, + threaten: 1.4, + }, + }, + husha: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + if (player.storage.husha == 1) { + return game.hasPlayer(function (current) { + return player.canUse("sha", current, false); + }); + } else { + return player.storage.husha > 0; + } + }, + content: function () { + "step 0"; + var list = []; + if ( + game.hasPlayer(function (current) { + return player.canUse("sha", current, false); + }) + ) { + list.push("移去1枚虎煞标记,视为使用一张杀"); + } + if (player.storage.husha > 1) { + list.push("移去2枚虎煞标记,视为使用一张南蛮入侵"); + if (player.storage.husha > 2) { + list.push("移去3枚虎煞标记,视为对除你之外的角色使用一张元素毁灭"); + } + } + player + .chooseControl("cancel2", function () { + if (player.storage.husha > 2) { + var num1 = game.countPlayer(function (current) { + if (current != player && player.canUse("yuansuhuimie", current)) { + return get.sgn( + get.effect(current, { name: "yuansuhuimie" }, player, player) + ); + } + }); + var num2 = game.countPlayer(function (current) { + if (current != player && player.canUse("yuansuhuimie", current)) { + return get.effect(current, { name: "yuansuhuimie" }, player, player); + } + }); + if (num1 > 0 && num2 > 0) return "选项三"; + } + if (player.storage.husha > 1) { + var num = game.countPlayer(function (current) { + if (current != player && player.canUse("nanman", current)) { + return get.sgn( + get.effect(current, { name: "nanman" }, player, player) + ); + } + }); + if (num > 0) return "选项二"; + } + if ( + game.hasPlayer(function (current) { + return ( + player.canUse("sha", current, false) && + get.effect(current, { name: "sha" }, player, player) > 0 + ); + }) + ) { + return "选项一"; + } + return "cancel2"; + }) + .set("prompt", get.prompt("husha")) + .set("choiceList", list); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("husha"); + if (result.control == "选项一") { + event.sha = true; + player.storage.husha--; + player.chooseTarget("选择出杀的目标", true, function (card, player, target) { + return player.canUse("sha", target, false); + }).ai = function (target) { + return get.effect(target, { name: "sha" }, player, player); + }; + } else if (result.control == "选项二") { + var list = game.filterPlayer(function (current) { + return player.canUse("nanman", current); + }); + player.storage.husha -= 2; + list.sortBySeat(); + player.useCard({ name: "nanman" }, list); + } else { + var list = game.filterPlayer(function (current) { + return player.canUse("yuansuhuimie", current); + }); + player.storage.husha -= 3; + list.remove(player); + list.sortBySeat(); + player.useCard({ name: "yuansuhuimie" }, list); + } + if (!player.storage.husha) { + player.unmarkSkill("husha"); + } else { + player.syncStorage("husha"); + player.updateMarks(); + } + } + "step 2"; + if (event.sha && result.targets && result.targets.length) { + player.useCard({ name: "sha" }, result.targets[0]); + } + }, + init: function (player) { + player.storage.husha = 0; + }, + intro: { + content: "mark", + }, + group: "husha_count", + subSkill: { + count: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + if (player.storage.husha < 3) { + var evt = event.getParent("phaseUse"); + return evt && evt.player == player; + } + return false; + }, + content: function () { + player.storage.husha += trigger.num; + if (player.storage.husha > 3) { + player.storage.husha = 3; + } + player.markSkill("husha"); + player.syncStorage("husha"); + player.updateMarks(); + }, + }, + }, + }, + fenshi: { + unique: true, + skillAnimation: true, + animationColor: "fire", + trigger: { player: "dyingAfter" }, + forced: true, + mark: true, + derivation: "longhuo", + intro: { + content: "limited", + }, + content: function () { + player.awakenSkill("fenshi"); + player.changeHujia(2); + player.draw(2); + player.addSkill("longhuo"); + }, + }, + longhuo: { + unique: true, + trigger: { player: "phaseEnd" }, + check: function (event, player) { + if (player.hp == 1 && player.hujia == 0) return false; + var num = game.countPlayer(function (current) { + var eff = get.sgn(get.damageEffect(current, player, player, "fire")); + if (current.hp == 1 && current.hujia == 0) eff *= 1.5; + return eff; + }); + return num > 0; + }, + content: function () { + "step 0"; + event.targets = get.players(lib.sort.seat); + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); + if (current.isIn()) { + player.line(current, "fire"); + current.damage("fire"); + event.redo(); + } + } + }, + }, + yanzhan: { + enable: "phaseUse", + viewAs: { name: "sha", nature: "fire" }, + usable: 1, + position: "he", + viewAsFilter: function (player) { + if (!player.countCards("he", { color: "red" })) return false; + }, + filterCard: { color: "red" }, + check: function (card) { + if (get.suit(card) == "heart") return 7 - get.value(card); + return 5 - get.value(card); + }, + onuse: function (result) { + if (result.targets) { + for (var i = 0; i < result.targets.length; i++) { + result.targets[i].addTempSkill("yanzhan3"); + } + } + }, + group: "yanzhan2", + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.15; + }, + }, + }, + yanzhan2: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + filter: function (event) { + return event.parent.skill == "yanzhan"; + }, + content: function () { + player.addTempSkill("yanzhan4"); + }, + }, + yanzhan3: { + mod: { + cardRespondable: function (card, player) { + if ( + _status.event.parent.skill == "yanzhan" && + get.suit(card) != get.suit(_status.event.parent.cards[0]) + ) + return false; + }, + }, + }, + yanzhan4: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + }, + xjyufeng: { + trigger: { player: "loseEnd" }, + forced: true, + usable: 2, + filter: function (event, player) { + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].original == "h") return player.countCards("h") < 2; + } + return false; + }, + content: function () { + player.draw(2 - player.countCards("h")); + }, + ai: { + noh: true, + skillTagFilter: function (player, tag) { + var nh = player.countCards("h"); + if (tag == "noh" && (nh > 2 || nh == 0)) { + return false; + } + }, + }, + }, + feixia: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "red" }, + position: "he", + filter: function (event, player) { + return player.countCards("he", { color: "red" }) > 0; + }, + check: function (card) { + return 7 - get.value(card); + }, + content: function () { + var targets = player.getEnemies(); + if (targets.length) { + var target = targets.randomGet(); + target.addExpose(0.2); + player.useCard({ name: "sha" }, target, false); + } + }, + ai: { + order: 2.9, + result: { + player: 1, + }, + }, + }, + lueying: { + trigger: { player: "shaBegin" }, + filter: function (event, player) { + if (event.target.countCards("he") > 0) { + return game.hasPlayer(function (current) { + return current != player && current != event.target && current.countCards("he"); + }); + } + return false; + }, + logTarget: "target", + usable: 1, + content: function () { + "step 0"; + var card = trigger.target.getCards("he").randomGet(); + player.gain(card, trigger.target); + if (get.position(card) == "e") { + trigger.target.$give(card, player); + } else { + trigger.target.$giveAuto(card, player); + } + "step 1"; + if ( + game.hasPlayer(function (current) { + return current != player && current != trigger.target && current.countCards("he"); + }) + ) { + trigger.target.chooseTarget(function (card, player, target) { + return ( + target != player && + target != _status.event.parent.player && + target.countCards("he") > 0 + ); + }, "选择一名角色并令" + get.translation(player) + "弃置其一张牌").ai = function ( + target + ) { + return -get.attitude(_status.event.player, target); + }; + } else { + event.finish(); + } + "step 2"; + if (result.bool) { + trigger.target.line(result.targets[0], "green"); + player.discardPlayerCard(result.targets[0], true, "he"); + } + }, + ai: { + threaten: 1.5, + expose: 0.2, + }, + }, + tianjian: { + enable: "phaseUse", + viewAs: { name: "wanjian" }, + filterCard: { name: "sha" }, + filter: function (event, player) { + return player.countCards("h", "sha") > 0; + }, + // alter:true, + usable: 1, + group: "tianjian_discard", + subSkill: { + discard: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + if (get.is.altered("tianjian")) return false; + return event.parent.skill == "tianjian" && event.player.countCards("he"); + }, + popup: false, + content: function () { + trigger.player.discard(trigger.player.getCards("he").randomGet()); + }, + }, + }, + }, + feng: { + unique: true, + init: function (player) { + player.storage.feng = 0; + }, + mark: true, + intro: { + content: "已累计摸#次牌", + }, + trigger: { player: "drawBegin" }, + forced: true, + popup: false, + priority: 5, + content: function () { + if (player.storage.feng < 2) { + player.storage.feng++; + } else { + trigger.num++; + player.storage.feng = 0; + player.logSkill("feng"); + } + player.updateMarks(); + }, + }, + ya: { + unique: true, + init: function (player) { + player.storage.ya = 0; + }, + mark: true, + intro: { + content: "已累计受到#次伤害", + }, + trigger: { player: "damageBegin" }, + filter: function (event, player) { + if (player.storage.ya == 2) return event.num > 0; + return true; + }, + forced: true, + popup: false, + content: function () { + if (player.storage.ya < 2) { + player.storage.ya++; + } else if (trigger.num > 0) { + trigger.num--; + player.storage.ya = 0; + player.logSkill("ya"); + } + player.updateMarks(); + }, + }, + song: { + unique: true, + init: function (player) { + player.storage.song = 0; + }, + mark: true, + intro: { + content: "已累计造成#次伤害", + }, + trigger: { source: "damageBegin" }, + forced: true, + popup: false, + content: function () { + if (player.storage.song < 2) { + player.storage.song++; + } else { + trigger.num++; + player.storage.song = 0; + player.logSkill("song"); + } + player.updateMarks(); + }, + }, + longxiang: { + trigger: { player: "shaBegin" }, + filter: function (event, player) { + return event.target.countCards("h") > player.countCards("h"); + }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + logTarget: "target", + content: function () { + var hs = trigger.target.getCards("h"); + trigger.target.discard(hs.randomGets(hs.length - player.countCards("h"))); + }, + }, + huxi: { + enable: "chooseToUse", + viewAs: { name: "sha" }, + precontent: function () { + "step 0"; + player.loseHp(); + "step 1"; + player.changeHujia(); + }, + filterCard: function () { + return false; + }, + selectCard: -1, + prompt: "失去1点体力并获得1点护甲,视为使用一张杀", + ai: { + order: function () { + var player = _status.event.player; + if (player.hp <= 2) return 0; + return 2; + }, + skillTagFilter: function (player, tag, arg) { + if (arg != "use") return false; + }, + respondSha: true, + }, + }, + xuanmo: { + enable: "phaseUse", + usable: 1, + filterCard: function (card) { + var type = get.type(card, "trick"); + return type == "basic" || type == "equip" || type == "trick"; + }, + check: function (card) { + return 8 - get.value(card); + }, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + discard: false, + prepare: "throw", + content: function () { + game.log(player, "将", cards, "置于牌堆顶"); + ui.cardPile.insertBefore(cards[0], ui.cardPile.firstChild); + var list = get.inpile(get.type(cards[0], "trick"), "trick").randomGets(2); + for (var i = 0; i < list.length; i++) { + list[i] = game.createCard(list[i]); + } + player.gain(list, "draw"); + }, + ai: { + threaten: 1.5, + order: 5, + result: { + player: 1, + }, + }, + }, + danqing: { + trigger: { player: "phaseEnd" }, + init: function (player) { + player.storage.danqing = []; + }, + mark: true, + direct: true, + intro: { + content: function (storage) { + if (!storage.length) { + return "未使用或打出过有花色的牌"; + } else { + var str = "已使用过" + get.translation(storage[0] + "2"); + for (var i = 1; i < storage.length; i++) { + str += "、" + get.translation(storage[i] + "2"); + } + str += "牌"; + return str; + } + }, + }, + filter: function (event, player) { + return player.storage.danqing.length == 4; + }, + ai: { + threaten: 1.2, + }, + // alter:true, + content: function () { + "step 0"; + player.storage.danqing.length = 0; + player.updateMarks(); + player.chooseTarget(get.prompt("danqing"), [1, get.is.altered("danqing") ? 2 : 4]).ai = + function (target) { + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("danqing", result.targets); + for (var i = 0; i < result.targets.length; i++) { + result.targets[i].getBuff(false); + } + } else { + event.finish(); + } + "step 2"; + game.delay(); + }, + group: "danqing_count", + }, + danqing_count: { + trigger: { player: "useCard" }, + silent: true, + content: function () { + var suit = get.suit(trigger.card); + if (suit) { + player.storage.danqing.add(suit); + player.updateMarks(); + } + }, + }, + danqing_old: { + content: function () { + "step 0"; + player.storage.danqing.length = 0; + player.updateMarks(); + event.targets = []; + "step 1"; + player.chooseTarget("令一名角色摸一张牌", function (card, player, target) { + return !event.targets.includes(target); + }).ai = function (target) { + var att = get.attitude(player, target); + if (att > 0) { + return att + 1 / Math.sqrt(1 + target.countCards("h")); + } + return 0; + }; + "step 2"; + if (result.bool) { + player.line(result.targets[0], "green"); + result.targets[0].draw(); + event.targets.push(result.targets[0]); + if (event.targets.length == game.players.length) { + event.finish(); + } else { + player.chooseTarget("令一名角色获得1点护甲", function (card, player, target) { + return !event.targets.includes(target); + }).ai = function (target) { + var att = get.attitude(player, target); + if (att > 0) { + return att + 1 / Math.sqrt(1 + target.hp); + } + return 0; + }; + } + } else { + event.finish(); + } + "step 3"; + if (result.bool) { + player.line(result.targets[0], "green"); + result.targets[0].changeHujia(); + game.delay(); + event.targets.push(result.targets[0]); + if (event.targets.length == game.players.length) { + event.finish(); + } else { + player.chooseTarget( + "令一名角色装备一件随机装备", + function (card, player, target) { + return !event.targets.includes(target); + } + ).ai = function (target) { + var att = get.attitude(player, target); + if (att > 0 && !target.getEquip(5)) { + return att; + } + return 0; + }; + } + } else { + event.finish(); + } + "step 4"; + if (result.bool) { + player.line(result.targets[0], "green"); + game.delay(); + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + if (lib.card[lib.inpile[i]].type == "equip") { + list.push(lib.inpile[i]); + } + } + var card = game.createCard(list.randomGet()); + result.targets[0].equip(card); + result.targets[0].$draw(card); + event.targets.push(result.targets[0]); + if (event.targets.length == game.players.length) { + event.finish(); + } else { + player.chooseTarget("令一名角色获得潜行", function (card, player, target) { + return !event.targets.includes(target); + }).ai = function (target) { + var att = get.attitude(player, target); + if (att > 0) { + return att + 1 / Math.sqrt(1 + target.hp); + } + return 0; + }; + } + } else { + event.finish(); + } + "step 5"; + if (result.bool) { + player.line(result.targets[0], "green"); + game.delay(); + result.targets[0].tempHide(); + } + }, + }, + sheling: { + trigger: { global: ["useCardAfter", "respondAfter", "discardAfter"] }, + filter: function (event, player) { + if (player != _status.currentPhase || player == event.player) return false; + if (event.cards) { + for (var i = 0; i < event.cards.length; i++) { + if (get.position(event.cards[i]) == "d") return true; + } + } + return false; + }, + frequent: "check", + check: function (event) { + for (var i = 0; i < event.cards.length; i++) { + if (get.position(event.cards[i]) == "d" && event.cards[i].name == "du") return false; + } + return true; + }, + usable: 3, + content: function () { + var cards = []; + for (var i = 0; i < trigger.cards.length; i++) { + if (get.position(trigger.cards[i]) == "d") { + cards.push(trigger.cards[i]); + } + } + player.gain(cards, "gain2"); + }, + }, + zhaoyao: { + trigger: { global: "phaseDrawBegin" }, + filter: function (event, player) { + return ( + event.player != player && + event.player.countCards("h") > 0 && + player.countCards("h") > 0 + ); + }, + check: function (event, player) { + if (player.isUnseen()) return false; + if (get.attitude(player, event.player) >= 0) return false; + var hs = player.getCards("h"); + if (hs.length < event.player.countCards("h")) return false; + for (var i = 0; i < hs.length; i++) { + var val = get.value(hs[0]); + if (hs[i].number >= 10 && val <= 6) return true; + if (hs[i].number >= 8 && val <= 3) return true; + } + return false; + }, + logTarget: "player", + content: function () { + "step 0"; + player.chooseToCompare(trigger.player); + "step 1"; + if (result.bool) { + player.draw(2); + } else { + event.finish(); + } + "step 2"; + player.chooseCard("将两张牌置于牌堆顶(先选择的在上)", 2, "he", true); + "step 3"; + if (result.bool) { + player.lose(result.cards, ui.special); + event.cards = result.cards; + } else { + event.finish(); + } + "step 4"; + game.delay(); + var nodes = []; + for (var i = 0; i < event.cards.length; i++) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + nodes.push(cardx); + } + player.$throw(nodes, 700, "nobroadcast"); + game.log(player, "将" + get.cnNumber(event.cards.length) + "张牌置于牌堆顶"); + "step 5"; + for (var i = event.cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(event.cards[i], ui.cardPile.firstChild); + } + }, + ai: { + mingzhi: false, + expose: 0.2, + }, + }, + zhangmu: { + trigger: { player: ["chooseToRespondBegin", "chooseToUseBegin"] }, + filter: function (event, player) { + if (event.responded) return false; + if (!event.filterCard({ name: "shan" }, player, event)) return false; + return player.countCards("h", "shan") > 0; + }, + direct: true, + usable: 1, + content: function () { + "step 0"; + var goon = get.damageEffect(player, trigger.player, player) <= 0; + player.chooseCard(get.prompt("zhangmu"), { name: "shan" }).ai = function () { + return goon ? 1 : 0; + }; + "step 1"; + if (result.bool) { + player.logSkill("zhangmu"); + player.showCards(result.cards); + trigger.untrigger(); + trigger.responded = true; + trigger.result = { bool: true, card: { name: "shan" } }; + player.addSkill("zhangmu_ai"); + } else { + player.storage.counttrigger.zhangmu--; + } + }, + ai: { + respondShan: true, + effect: { + target: function (card, player, target, effect) { + if (get.tag(card, "respondShan") && effect < 0) { + if (target.hasSkill("zhangmu_ai")) return 0; + if (target.countCards("h") >= 2) return 0.5; + } + }, + }, + }, + }, + zhangmu_ai: { + trigger: { player: "loseAfter" }, + silent: true, + filter: function (event, player) { + return player.countCards("h", "shan") == 0; + }, + content: function () { + player.removeSkill("zhangmu_ai"); + }, + }, + leiyu: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + if (!player.countCards("h", { color: "black" })) return false; + if (player.storage.leiyu) { + for (var i = 0; i < player.storage.leiyu.length; i++) { + if (player.storage.leiyu[i].isAlive()) return true; + } + } + return false; + }, + content: function () { + "step 0"; + for (var i = 0; i < player.storage.leiyu.length; i++) { + if (player.storage.leiyu[i].isDead()) { + player.storage.leiyu.splice(i--, 1); + } + } + var num = 0; + var num2 = 0; + for (var i = 0; i < player.storage.leiyu.length; i++) { + if (!player.storage.leiyu[i].isIn()) continue; + var eff = get.effect( + player.storage.leiyu[i], + { name: "jingleishan", nature: "thunder" }, + player, + player + ); + num += eff; + if (eff > 0) { + num2++; + } else if (eff < 0) { + num2--; + } + } + var next = player.chooseToDiscard(get.prompt("leiyu", player.storage.leiyu), { + color: "black", + }); + next.ai = function (card) { + if (num > 0 && num2 >= 2) { + return 7 - get.value(card); + } + return 0; + }; + next.logSkill = ["leiyu", player.storage.leiyu]; + "step 1"; + if (result.bool) { + player.storage.leiyu.sort(lib.sort.seat); + player.useCard( + { name: "jingleishan", nature: "thunder" }, + player.storage.leiyu + ).animate = false; + } + }, + group: ["leiyu2", "leiyu4"], + ai: { + threaten: 1.3, + }, + }, + leiyu2: { + trigger: { player: "phaseUseBegin" }, + silent: true, + content: function () { + player.storage.leiyu = []; + }, + }, + leiyu3: { + trigger: { source: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.leiyu2 ? true : false; + }, + content: function () { + player.recover(); + delete player.storage.leiyu2; + }, + }, + leiyu4: { + trigger: { player: "useCardToBegin" }, + silent: true, + filter: function (event, player) { + return ( + _status.currentPhase == player && + Array.isArray(player.storage.leiyu) && + event.target && + event.target != player + ); + }, + content: function () { + player.storage.leiyu.add(trigger.target); + }, + }, + feizhua: { + trigger: { player: "useCard" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.targets.length != 1) return false; + var target = event.targets[0]; + var players = game.filterPlayer(function (current) { + return get.distance(target, current, "pure") == 1; + }); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + target != players[i] && + player.canUse("sha", players[i], false) + ) { + return true; + } + } + return false; + }, + prompt: function (event, player) { + var targets = []; + var target = event.targets[0]; + var players = game.filterPlayer(function (current) { + return get.distance(target, current, "pure") == 1; + }); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + target != players[i] && + player.canUse("sha", players[i], false) + ) { + targets.push(players[i]); + } + } + return get.prompt("feizhua", targets); + }, + check: function (event, player) { + var target = event.targets[0]; + var num = 0; + var players = game.filterPlayer(function (current) { + return get.distance(target, current, "pure") == 1; + }); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + target != players[i] && + player.canUse("sha", players[i], false) + ) { + num += get.effect(players[i], { name: "sha" }, player, player); + } + } + return num > 0; + }, + content: function () { + "step 0"; + var target = trigger.targets[0]; + var players = game.filterPlayer(function (current) { + return get.distance(target, current, "pure") == 1; + }); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + target != players[i] && + player.canUse("sha", players[i], false) + ) { + trigger.targets.push(players[i]); + player.line(players[i], "green"); + } + } + }, + }, + lingxue: { + trigger: { player: "recoverEnd" }, + forced: true, + content: function () { + player.changeHujia(); + }, + }, + diesha: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.player.isAlive() && event.card && event.card.name == "sha"; + }, + content: function () { + trigger.player.loseHp(); + player.recover(); + }, + ai: { + threaten: 1.5, + }, + }, + guijiang: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("guijiang2"); + }, + filterCard: { color: "black" }, + filter: function (event, player) { + return player.countCards("h", { color: "black" }); + }, + check: function (card) { + return 5 - get.value(card); + }, + content: function () { + target.addSkill("guijiang2"); + target.storage.guijiang2 = player; + }, + ai: { + order: 4, + threaten: 1.2, + expose: 0.2, + result: { + target: function (player, target) { + if (target.hp == 1) return -1; + if (target.hp == 2) return -0.5; + return 0; + }, + }, + }, + }, + guijiang2: { + mark: true, + intro: { + content: "不能成为回复牌的目标", + }, + trigger: { global: ["dieBegin", "phaseBegin"] }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.storage.guijiang2; + }, + content: function () { + player.removeSkill("guijiang2"); + }, + mod: { + targetEnabled: function (card) { + if (get.tag(card, "recover")) return false; + }, + }, + global: "guijiang3", + }, + guijiang3: { + mod: { + cardSavable: function (card, player) { + if (_status.event.dying && _status.event.dying.hasSkill("guijiang2")) return false; + }, + }, + }, + fenxing: { + trigger: { player: "phaseBegin" }, + forced: true, + unique: true, + forceunique: true, + filter: function () { + return Math.random() < 0.5; + }, + derivation: ["diesha", "guijiang"], + content: function () { + if (player.storage.fenxing) { + player.storage.fenxing = false; + player.removeSkill("guijiang"); + player.removeSkill("diesha"); + player.addSkill("diewu"); + player.addSkill("lingyu"); + player.setAvatar("pal_longkui", "pal_longkui"); + } else { + player.storage.fenxing = true; + player.removeSkill("diewu"); + player.removeSkill("lingyu"); + player.addSkill("guijiang"); + player.addSkill("diesha"); + player.setAvatar("pal_longkui", "pal_longkuigui"); + } + }, + }, + diewu: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", "sha") > 0; + }, + filterCard: { name: "sha" }, + filterTarget: function (card, player, target) { + return target != player; + }, + prepare: "give", + discard: false, + content: function () { + target.gain(cards, player); + if (!player.hasSkill("diewu2")) { + player.draw(); + player.addTempSkill("diewu2"); + } + }, + ai: { + order: 2, + expose: 0.2, + result: { + target: function (player, target) { + if (!player.hasSkill("diewu2")) return 1; + return 0; + }, + }, + }, + }, + diewu2: {}, + lingyu: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isDamaged(); + }); + }, + content: function () { + "step 0"; + player.chooseTarget("灵愈:令一名其他角色回复1点体力", function (card, player, target) { + return target != player && target.hp < target.maxHp; + }).ai = function (target) { + return get.recoverEffect(target, player, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("lingyu", result.targets[0]); + result.targets[0].recover(); + } + }, + ai: { + threaten: 1.5, + expose: 0.2, + }, + }, + duxinshu: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); + }, + content: function () { + "step 0"; + if (player.countCards("h")) { + player.chooseCardButton("读心", target.getCards("h")).ai = function (button) { + return get.value(button.link) - 5; + }; + } else { + player.viewHandcards(target); + event.finish(); + } + "step 1"; + if (result.bool) { + event.card = result.links[[0]]; + player.chooseCard("h", true, "用一张手牌替换" + get.translation(event.card)).ai = + function (card) { + return -get.value(card); + }; + } else { + event.finish(); + } + "step 2"; + if (result.bool) { + player.gain(event.card, target); + target.gain(result.cards, player); + player.$giveAuto(result.cards, target); + target.$giveAuto(event.card, player); + game.log(player, "与", target, "交换了一张手牌"); + } + }, + ai: { + threaten: 1.3, + result: { + target: function (player, target) { + return -target.countCards("h"); + }, + }, + order: 10, + expose: 0.2, + }, + }, + feixu: { + trigger: { global: ["useCard", "respond"] }, + filter: function (event, player) { + return event.card && event.card.name == "shan"; + }, + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + logTarget: "player", + content: function () { + trigger.player.draw(); + }, + ai: { + mingzhi: false, + threaten: 2, + expose: 0.2, + }, + }, + xuanyan: { + // trigger:{source:'damageBefore'}, + // forced:true, + // priority:5, + // check:function(event,player){ + // return player.hp>3; + // }, + // filter:function(event){ + // return event.card&&get.color(event.card)=='red'; + // }, + // content:function(){ + // trigger.nature='fire'; + // }, + group: ["xuanyan2", "xuanyan3"], + }, + xuanyan2: { + trigger: { source: "damageBegin" }, + forced: true, + filter: function (event) { + return event.hasNature("fire") && event.notLink(); + }, + content: function () { + trigger.num++; + }, + }, + xuanyan3: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + filter: function (event) { + return event.hasNature("fire"); + }, + content: function () { + player.loseHp(); + }, + }, + ningbin: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event) { + return event.hasNature("thunder"); + }, + content: function () { + player.recover(); + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "thunderDamage")) { + if (target.hp <= 1 || !target.hasSkill("xfenxin")) return [0, 0]; + return [0, 1.5]; + } + }, + }, + }, + }, + xfenxin: { + trigger: { player: "changeHp" }, + forced: true, + filter: function (event) { + return event.num != 0; + }, + // alter:true, + content: function () { + if (get.is.altered("xfenxin")) { + player.draw(); + } else { + player.draw(Math.abs(trigger.num)); + } + }, + ai: { + effect: { + target: function (card) { + if (get.tag(card, "thunderDamage")) return; + if (get.tag(card, "damage") || get.tag(card, "recover")) { + return [1, 0.2]; + } + }, + }, + }, + group: "xfenxin2", + }, + xfenxin2: { + trigger: { source: "dieAfter" }, + forced: true, + filter: function () { + return !get.is.altered("xfenxin"); + }, + content: function () { + player.gainMaxHp(); + player.recover(); + }, + }, + luanjian: { + enable: "phaseUse", + filterCard: { name: "sha" }, + selectCard: 2, + check: function (card) { + var num = 0; + var player = _status.event.player; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + lib.filter.targetEnabled({ name: "sha" }, player, players[i]) && + get.effect(players[i], { name: "sha" }, player) > 0 + ) { + num++; + if (num > 1) return 8 - get.value(card); + } + } + return 0; + }, + viewAs: { name: "sha" }, + selectTarget: [1, Infinity], + filterTarget: function (card, player, target) { + return lib.filter.targetEnabled({ name: "sha" }, player, target); + }, + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.1; + }, + effect: { + player: function (card, player) { + if (_status.currentPhase != player) return; + if ( + card.name == "sha" && + player.countCards("h", "sha") < 2 && + !player.needsToDiscard() + ) { + var num = 0; + var player = _status.event.player; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + lib.filter.targetEnabled({ name: "sha" }, player, players[i]) && + get.attitude(player, players[i]) < 0 + ) { + num++; + if (num > 1) return "zeroplayertarget"; + } + } + } + }, + }, + }, + group: "luanjian2", + }, + luanjian2: { + trigger: { source: "damageBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card && event.card.name == "sha" && event.parent.skill == "luanjian"; + }, + content: function () { + if (Math.random() < 0.5) trigger.num++; + }, + }, + ctianfu: { + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h", "shan") > 0; + }, + usable: 1, + filterCard: { name: "shan" }, + discard: false, + prepare: "give", + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("ctianfu2"); + }, + check: function (card) { + if (_status.event.player.hp >= 3) return 8 - get.value(card); + return 7 - get.value(card); + }, + content: function () { + target.storage.ctianfu2 = cards[0]; + target.storage.ctianfu3 = player; + game.addVideo("storage", target, ["ctianfu2", get.cardInfo(cards[0]), "card"]); + target.addSkill("ctianfu2"); + }, + ai: { + order: 2, + result: { + target: function (player, target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + return get.damageEffect(target, player, target, "thunder"); + }, + }, + expose: 0.2, + }, + }, + ctianfu2: { + trigger: { source: "damageAfter" }, + forced: true, + mark: "card", + filter: function (event, player) { + return player.storage.ctianfu2 && player.storage.ctianfu3; + }, + content: function () { + "step 0"; + if (player.storage.ctianfu3 && player.storage.ctianfu3.isAlive()) { + player.damage(player.storage.ctianfu3); + player.storage.ctianfu3.line(player, "thunder"); + } else { + player.damage("nosource"); + } + "step 1"; + var he = player.getCards("he"); + if (he.length) { + player.discard(he.randomGet()); + } + "step 2"; + player.$throw(player.storage.ctianfu2); + player.storage.ctianfu2.discard(); + delete player.storage.ctianfu2; + delete player.storage.ctianfu3; + player.removeSkill("ctianfu2"); + }, + group: "ctianfu3", + intro: { + content: "card", + }, + }, + ctianfu3: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + content: function () { + player.storage.ctianfu2.discard(); + delete player.storage.ctianfu2; + delete player.storage.ctianfu3; + player.removeSkill("ctianfu2"); + }, + }, + shuiyun: { + trigger: { player: "phaseEnd" }, + direct: true, + init: function (player) { + player.storage.shuiyun = []; + player.storage.shuiyun_count = 0; + }, + // alter:true, + filter: function (event, player) { + if (player.storage.shuiyun.length >= 3) return false; + if (player.storage.shuiyun.length >= 2 && get.is.altered("shuiyun")) return false; + var types = []; + for (var i = 0; i < player.storage.shuiyun.length; i++) { + types.add(get.type(player.storage.shuiyun[i], "trick")); + } + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { + if (!types.includes(get.type(cards[i], "trick"))) { + return true; + } + } + return false; + }, + content: function () { + "step 0"; + var types = []; + var num = player.countCards("h"); + for (var i = 0; i < player.storage.shuiyun.length; i++) { + types.add(get.type(player.storage.shuiyun[i], "trick")); + } + player.chooseCard(get.prompt2("shuiyun"), function (card) { + return !types.includes(get.type(card, "trick")); + }).ai = function (card) { + return 11 - get.value(card); + }; + "step 1"; + if (result.bool) { + player.$throw(result.cards); + var clone = result.cards[0].clone; + setTimeout(function () { + clone.moveDelete(player); + game.addVideo("gain2", player, get.cardsInfo([clone])); + }, 500); + player.logSkill("shuiyun"); + player.storage.shuiyun.push(result.cards[0]); + player.lose(result.cards, ui.special); + player.markSkill("shuiyun"); + game.addVideo("storage", player, [ + "shuiyun", + get.cardsInfo(player.storage.shuiyun), + "cards", + ]); + } + }, + intro: { + content: "cards", + onunmark: function (storage, player) { + if (storage && storage.length) { + for (var i = 0; i < storage.length; i++) { + storage[i].discard(); + } + player.$throw(storage); + delete player.storage.shuiyun; + } + }, + }, + ai: { + effect: { + player: function (card, player) { + if (_status.currentPhase != player) return; + if (get.is.altered("shuiyun")) return; + if ( + card.name == "wuzhong" || + card.name == "yiyi" || + card.name == "yuanjiao" || + card.name == "shunshou" + ) + return; + if (!player.needsToDiscard()) { + var types = []; + for (var i = 0; i < player.storage.shuiyun.length; i++) { + types.add(get.type(player.storage.shuiyun[i], "trick")); + } + if (!types.includes(get.type(card, "trick"))) { + return "zeroplayertarget"; + } + } + }, + }, + threaten: 2.2, + }, + group: ["shuiyun5"], + }, + shuiyun5: { + enable: "chooseToUse", + filter: function (event, player) { + return ( + event.type == "dying" && + event.dying && + event.dying.hp <= 0 && + player.storage.shuiyun.length > 0 + ); + }, + filterTarget: function (card, player, target) { + return target == _status.event.dying; + }, + delay: 0, + selectTarget: -1, + content: function () { + "step 0"; + player.chooseCardButton(get.translation("shuiyun"), player.storage.shuiyun, true); + "step 1"; + if (result.bool) { + player.storage.shuiyun.remove(result.links[0]); + if (!player.storage.shuiyun.length) { + player.unmarkSkill("shuiyun"); + } + player.$throw(result.links); + result.links[0].discard(); + target.recover(); + if (typeof player.storage.shuiyun_count == "number") { + player.storage.shuiyun_count++; + } + player.syncStorage("shuiyun"); + } else { + event.finish(); + } + }, + ai: { + order: 6, + skillTagFilter: function (player) { + return player.storage.shuiyun.length > 0; + }, + save: true, + result: { + target: 3, + }, + threaten: 1.6, + }, + }, + wangyou: { + trigger: { global: "phaseEnd" }, + unique: true, + gainable: true, + direct: true, + filter: function (event, player) { + if (!player.countCards("he")) return false; + if (player == event.player) return false; + return game.hasPlayer(function (current) { + return current.hasSkill("wangyou3"); + }); + }, + content: function () { + "step 0"; + var targets = []; + var num = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].hasSkill("wangyou3")) { + var att = get.attitude(player, players[i]); + if (att > 0) num++; + else if (att < 0) num--; + targets.push(players[i]); + } + } + event.targets = targets; + var next = player.chooseToDiscard(get.prompt("wangyou", targets), "he"); + next.logSkill = ["wangyou", event.targets]; + next.ai = function (card) { + if (num <= 0) return 0; + switch (num) { + case 1: + return 5 - get.value(card); + case 2: + return 7 - get.value(card); + default: + return 8 - get.value(card); + } + }; + "step 1"; + if (result.bool) { + event.targets.sort(lib.sort.seat); + game.asyncDraw(event.targets); + } else { + event.finish(); + } + }, + ai: { + expose: 0.1, + threaten: 1.2, + }, + group: "wangyou2", + }, + wangyou2: { + trigger: { global: "damageEnd" }, + silent: true, + filter: function (event) { + return event.player.isAlive(); + }, + content: function () { + trigger.player.addTempSkill("wangyou3"); + }, + }, + wangyou3: {}, + changnian: { + forbid: ["boss"], + trigger: { player: "dieBegin" }, + direct: true, + unique: true, + derivation: "changnian2", + content: function () { + "step 0"; + player.chooseTarget(get.prompt("changnian"), function (card, player, target) { + return player != target; + }).ai = function (target) { + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + var cards = player.getCards("hej"); + var target = result.targets[0]; + // if(player.storage.shuiyun&&player.storage.shuiyun.length){ + // target.gainMaxHp(); + // target.recover(player.storage.shuiyun.length); + // cards=cards.concat(player.storage.shuiyun); + // player.storage.shuiyun.length=0; + // } + player.$give(cards, target); + target.gain(cards); + target.addSkill("changnian2"); + player.logSkill("changnian", target); + target.marks.changnian = target.markCharacter(player, { + name: "长念", + content: + '
              【追思】
              锁定技,结束阶段,你摸一张牌
              ', + }); + game.addVideo("markCharacter", target, { + name: "长念", + content: + '
              【追思】
              锁定技,结束阶段,你摸一张牌
              ', + id: "changnian", + target: player.dataset.position, + }); + } + }, + ai: { + threaten: 0.8, + }, + }, + changnian2: { + trigger: { player: "phaseEnd" }, + forced: true, + nopop: true, + content: function () { + player.draw(); + }, + }, + sajin: { + enable: "phaseUse", + filterTarget: function (card, player, target) { + return target.hp < target.maxHp; + }, + selectTarget: [1, Infinity], + filterCard: true, + usable: 1, + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("h") > player.hp) { + return 7 - get.value(card); + } + return 4 - get.value(card); + }, + content: function () { + "step 0"; + var color = get.color(cards[0]); + target.judge(function (card) { + return get.color(card) == color ? 1 : 0; + }); + "step 1"; + if (result.bool) { + target.recover(); + } + }, + ai: { + order: 3, + result: { + target: function (player, target) { + return get.recoverEffect(target); + }, + }, + threaten: 1.5, + }, + }, + jtjubao: { + trigger: { global: "discardAfter" }, + filter: function (event, player) { + if (player.hasSkill("jtjubao2")) return false; + if (event.player == player) return false; + if (_status.currentPhase == player) return false; + for (var i = 0; i < event.cards.length; i++) { + if (get.type(event.cards[i]) != "basic" && get.position(event.cards[i]) == "d") { + return true; + } + } + return false; + }, + frequent: true, + content: function () { + "step 0"; + if (trigger.delay == false) game.delay(); + "step 1"; + var cards = []; + for (var i = 0; i < trigger.cards.length; i++) { + if (get.type(trigger.cards[i]) != "basic" && get.position(trigger.cards[i]) == "d") { + cards.push(trigger.cards[i]); + } + } + if (cards.length) { + var card = cards.randomGet(); + player.gain(card, "log"); + player.$gain2(card); + player.addTempSkill("jtjubao2"); + } + }, + ai: { + threaten: 1.5, + }, + }, + jtjubao2: {}, + duci: { + trigger: { player: "loseEnd" }, + direct: true, + filter: function (event, player) { + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].original == "e") return true; + } + return false; + }, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("duci"), function (card, player, target) { + return player != target && get.distance(player, target) <= 1; + }).ai = function (target) { + return get.damageEffect(target, player, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("duci", result.targets); + result.targets[0].damage(); + } + }, + ai: { + expose: 0.2, + threaten: 1.5, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + get.distance(player, players[i]) <= 1 && + get.damageEffect(players[i], player, player) > 0 + ) { + return [1, 3]; + } + } + } + }, + }, + }, + }, + xshuangren: { + trigger: { player: ["loseEnd"] }, + filter: function (event, player) { + if (!player.equiping) return false; + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].original == "e" && get.subtype(event.cards[i]) == "equip1") + return true; + } + return false; + }, + content: function () { + var card; + for (var i = 0; i < trigger.cards.length; i++) { + if (trigger.cards[i].original == "e" && get.subtype(trigger.cards[i]) == "equip1") { + card = trigger.cards[i]; + } + } + if (card) { + if (player.storage.xshuangren) { + player.unmark(player.storage.xshuangren, "xshuangren"); + player.discard(player.storage.xshuangren); + game.addVideo("unmarkId", player, [ + get.cardInfo(player.storage.xshuangren), + "xshuangren", + ]); + } + if (card.clone) { + card.clone.moveDelete(player); + game.addVideo("gain2", player, get.cardsInfo([card.clone])); + player.mark(card, "xshuangren"); + game.addVideo("markId", player, [get.cardInfo(card), "xshuangren"]); + } + ui.special.appendChild(card); + player.storage.xshuangren = card; + var info = get.info(card); + if (info.skills) { + player.addAdditionalSkill("xshuangren", info.skills); + } else { + player.removeAdditionalSkill("xshuangren"); + } + } + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.subtype(card) == "equip1") return [1, 3]; + }, + }, + }, + intro: { + content: "card", + }, + group: "xshuangren2", + }, + xshuangren2: { + trigger: { player: "dieBegin" }, + silent: true, + filter: function (event, player) { + return player.storage.xshuangren ? true : false; + }, + content: function () { + if (player.storage.xshuangren) { + player.storage.xshuangren.discard(); + player.$throw(player.storage.xshuangren); + } + }, + }, + guiyuan: { + enable: "phaseUse", + usable: 1, + filterCard: { name: "sha" }, + filter: function (event, player) { + return player.hp < player.maxHp; + }, + content: function () { + player.recover(); + player.draw(); + }, + ai: { + order: 5, + result: { + player: 1, + }, + }, + }, + qijian: { + trigger: { player: "phaseDiscardEnd" }, + direct: true, + filter: function (event, player) { + return event.cards && event.cards.length > 0; + }, + content: function () { + "step 0"; + player.chooseTarget( + [1, trigger.cards.length], + get.prompt("qijian"), + function (card, player, target) { + return player.canUse({ name: "sha" }, target, false); + } + ).ai = function (target) { + return get.effect(target, { name: "sha" }, player); + }; + "step 1"; + if (result.bool) { + player.logSkill("qijian"); + player.useCard({ name: "sha" }, result.targets); + } + }, + }, + shenmu: { + trigger: { global: "dying" }, + priority: 6, + filter: function (event, player) { + return event.player.hp <= 0 && player.countCards("h", { color: "red" }); + }, + check: function (event, player) { + if (get.attitude(player, event.player) <= 0) return false; + var cards = player.getCards("h", { color: "red" }); + for (var i = 0; i < cards.length; i++) { + if (cards[i].name == "tao") return false; + if (get.value(cards[i]) > 7 && cards.length > 2) return false; + } + }, + content: function () { + "step 0"; + player.showHandcards(); + "step 1"; + var cards = player.getCards("h", { color: "red" }); + event.num = cards.length; + player.discard(cards); + "step 2"; + trigger.player.recover(); + trigger.player.draw(event.num); + }, + ai: { + threaten: 1.6, + expose: 0.2, + }, + }, + qianfang: { + trigger: { player: "phaseBegin" }, + direct: true, + filter: function (event, player) { + return player.storage.xuanning && player.countCards("he") + player.storage.xuanning >= 3; + }, + // alter:true, + content: function () { + "step 0"; + // trigger.cancel(); + var ainum = 0; + var num = 3 - player.storage.xuanning; + var players = game.filterPlayer(); + event.targets = []; + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + !players[i].isOut() && + lib.filter.targetEnabled({ name: "wanjian" }, player, players[i]) + ) { + ainum += get.effect(players[i], { name: "wanjian" }); + event.targets.push(players[i]); + } + } + if (num) { + var next = player.chooseToDiscard(num, get.prompt2("qianfang"), "he"); + next.ai = function (card) { + if (ainum >= 0) { + switch (num) { + case 1: + return 8 - get.value(card); + case 2: + return 6 - get.value(card); + case 3: + return 4 - get.value(card); + } + } + return -1; + }; + next.logSkill = "qianfang"; + event.logged = true; + } else { + player.chooseBool(get.prompt2("qianfang")).ai = function () { + return ainum >= 0; + }; + } + "step 1"; + if (result.bool) { + player.storage.xuanning = 0; + player.unmarkSkill("xuanning"); + if (!event.logged) { + player.logSkill("qianfang"); + } + player.useCard({ name: "wanjian" }, "qianfang", event.targets); + } else { + event.finish(); + } + }, + ai: { + expose: 0.1, + threaten: 1.5, + }, + group: "qianfang_draw", + subSkill: { + draw: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + if (!event.player.isEnemiesOf(player)) return false; + return event.parent.skill == "qianfang"; + }, + popup: false, + content: function () { + player.draw(); + }, + }, + }, + }, + qianfang2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + popup: false, + content: function () { + trigger.num++; + }, + }, + poyun: { + trigger: { source: "damageEnd" }, + // alter:true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return player.storage.xuanning > 0 && event.player.countCards("he") > 0; + }, + direct: true, + content: function () { + "step 0"; + player.discardPlayerCard(trigger.player, "he", get.prompt("poyun", trigger.player), [ + 1, + get.is.altered("poyun") ? 1 : 2, + ]).logSkill = ["poyun", trigger.player]; + "step 1"; + if (result.bool) { + player.storage.xuanning--; + if (!player.storage.xuanning) { + player.unmarkSkill("xuanning"); + } + player.syncStorage("xuanning"); + } + }, + ai: { + threaten: 1.3, + }, + }, + poyun2: { + trigger: { source: "damageEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.poyun ? true : false; + }, + content: function () { + player.draw(); + player.storage.poyun = false; + player.removeSkill("poyun2"); + }, + }, + poyun3: {}, + zhuyue: { + enable: "phaseUse", + // alter:true, + filter: function (event, player) { + if (get.is.altered("zhuyue")) { + return player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }); + } + return player.countCards("h", { type: "basic" }) < player.countCards("he"); + }, + init: function (player) { + player.storage.zhuyue = []; + }, + filterCard: function (card) { + if (get.is.altered("zhuyue")) { + return get.type(card) != "basic" && get.color(card) == "black"; + } else { + return get.type(card) != "basic"; + } + }, + selectTarget: [1, 2], + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; + }, + usable: 1, + locked: false, + check: function (card) { + return 7 - get.value(card); + }, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + targets.sort(lib.sort.seat); + var target = targets[0]; + var cs = target.getCards("he"); + if (cs.length) { + target.discard(cs.randomGet()); + } + player.storage.zhuyue.add(target); + if (targets.length < 2) { + event.finish(); + } + "step 1"; + var target = targets[1]; + var cs = target.getCards("he"); + if (cs.length) { + target.discard(cs.randomGet()); + } + player.storage.zhuyue.add(target); + }, + ai: { + result: { + target: function (player, target) { + if (!target.countCards("he")) return -0.2; + return -1; + }, + }, + order: 10, + threaten: 1.2, + exoise: 0.2, + }, + mod: { + targetInRange: function (card, player, target) { + if ( + card.name == "sha" && + player.storage.zhuyue && + player.storage.zhuyue.includes(target) + ) { + return true; + } + }, + selectTarget: function (card, player, range) { + if (card.name == "sha" && player.storage.zhuyue && player.storage.zhuyue.length) { + range[1] = -1; + range[0] = -1; + } + }, + playerEnabled: function (card, player, target) { + if ( + card.name == "sha" && + player.storage.zhuyue && + player.storage.zhuyue.length && + !player.storage.zhuyue.includes(target) + ) { + return false; + } + }, + }, + intro: { + content: "players", + }, + group: "zhuyue2", + }, + zhuyue2: { + trigger: { player: "phaseUseEnd" }, + silent: true, + content: function () { + player.storage.zhuyue.length = 0; + }, + }, + longxi: { + trigger: { player: ["chooseToRespondBegin", "chooseToUseBegin"] }, + forced: true, + popup: false, + max: 2, + filter: function (event, player) { + return _status.currentPhase != player; + }, + priority: 101, + content: function () { + var cards = []; + var max = Math.min(ui.cardPile.childNodes.length, lib.skill.longxi.max); + for (var i = 0; i < max; i++) { + var card = ui.cardPile.childNodes[i]; + if (trigger.filterCard(card, player, trigger)) { + cards.push(card); + } + } + if (cards.length) { + player.gain(cards, "draw"); + player.logSkill("longxi"); + game.log(player, "获得了" + get.cnNumber(cards.length) + "张牌"); + } + }, + ai: { + respondSha: true, + respondShan: true, + effect: { + target: function (card, player, target, effect) { + if (get.tag(card, "respondShan")) return 0.7; + if (get.tag(card, "respondSha")) return 0.7; + }, + }, + }, + hiddenCard: function (player, name) { + if (_status.currentPhase == player) return false; + var max = Math.min(ui.cardPile.childNodes.length, lib.skill.longxi.max); + for (var i = 0; i < max; i++) { + var card = ui.cardPile.childNodes[i]; + if (card.name == name) return true; + } + return false; + }, + }, + guanri: { + unique: true, + enable: "phaseUse", + filter: function (event, player) { + return !player.storage.guanri && player.countCards("h", { color: "red" }) >= 2; + }, + check: function (card) { + return 8 - get.value(card); + }, + filterCard: function (card) { + return get.color(card) == "red"; + }, + selectCard: 2, + filterTarget: function (card, player, target) { + return player != target && target.hp >= player.hp; + }, + intro: { + content: "limited", + }, + line: "fire", + content: function () { + "step 0"; + player.storage.guanri = true; + player.loseHp(); + "step 1"; + target.damage(2, "fire"); + "step 2"; + if (target.isAlive()) { + target.discard(target.getCards("e")); + } + }, + ai: { + order: 1, + result: { + target: function (player, target) { + var eff = get.damageEffect(target, player, target, "fire"); + if (player.hp > 2) return eff; + if (player.hp == 2 && target.hp == 2) return eff; + return 0; + }, + }, + expose: 0.5, + }, + }, + tianxian: { + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "sha") return true; + }, + selectTarget: function (card, player, range) { + if (card.name == "sha" && range[1] != -1) range[1] = Infinity; + }, + }, + priority: 5.5, + trigger: { player: "useCardToBefore" }, + filter: function (event) { + return event.card.name == "sha"; + }, + forced: true, + check: function () { + return false; + }, + content: function () { + "step 0"; + trigger.target.judge(function (card) { + return get.color(card) == "black" ? 1 : 0; + }); + "step 1"; + if (result.bool) { + trigger.cancel(); + } + }, + }, + runxin: { + trigger: { player: ["useCard", "respondEnd"] }, + direct: true, + filter: function (event) { + if (get.suit(event.card) == "heart") { + return game.hasPlayer(function (current) { + return current.isDamaged(); + }); + } + return false; + }, + content: function () { + "step 0"; + var noneed = + trigger.card.name == "tao" && + trigger.targets[0] == player && + player.hp == player.maxHp - 1; + player + .chooseTarget(get.prompt("runxin"), function (card, player, target) { + return target.hp < target.maxHp; + }) + .set("autodelay", true).ai = function (target) { + var num = get.attitude(player, target); + if (num > 0) { + if (noneed && player == target) { + num = 0.5; + } else if (target.hp == 1) { + num += 3; + } else if (target.hp == 2) { + num += 1; + } + } + return num; + }; + "step 1"; + if (result.bool) { + player.logSkill("runxin", result.targets); + result.targets[0].recover(); + } + }, + ai: { + expose: 0.3, + threaten: 1.5, + }, + }, + xjzhimeng: { + trigger: { player: "phaseEnd" }, + direct: true, + locked: true, + unique: true, + gainable: true, + // alter:true, + group: "xjzhimeng3", + content: function () { + "step 0"; + player.chooseTarget(get.prompt("xjzhimeng"), function (card, player, target) { + return player != target; + }).ai = function (target) { + var num = get.attitude(player, target); + if (num > 0) { + if (player == target) { + num++; + } + if (target.hp == 1) { + num += 3; + } + if (target.hp == 2) { + num += 1; + } + } + return num; + }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + if (get.is.altered("xjzhimeng")) { + target.draw(); + } else { + var card = get.cards()[0]; + target.$draw(card); + target.storage.xjzhimeng2 = card; + game.addVideo("storage", target, ["xjzhimeng2", get.cardInfo(card), "card"]); + target.addSkill("xjzhimeng2"); + } + player.logSkill("xjzhimeng", target); + } + }, + ai: { + expose: 0.2, + }, + }, + xjzhimeng2: { + intro: { + content: "card", + onunmark: function (storage, player) { + delete player.storage.xjzhimeng2; + }, + }, + mark: "card", + trigger: { target: "useCardToBegin" }, + frequent: true, + filter: function (event, player) { + return ( + player.storage.xjzhimeng2 && + get.type(event.card, "trick") == get.type(player.storage.xjzhimeng2, "trick") + ); + }, + content: function () { + player.draw(); + }, + ai: { + effect: { + target: function (card, player, target) { + if ( + target.storage.xjzhimeng2 && + get.type(card, "trick") == get.type(target.storage.xjzhimeng2, "trick") + ) { + return [1, 0.5]; + } + }, + }, + }, + }, + xjzhimeng3: { + trigger: { player: ["phaseBegin", "dieBegin"] }, + silent: true, + content: function () { + "step 0"; + event.players = game.filterPlayer(); + event.num = 0; + "step 1"; + if (event.num < event.players.length) { + var player = event.players[event.num]; + if (player.storage.xjzhimeng2) { + if (trigger.name == "die" && player == trigger.player) { + player.storage.xjzhimeng2.discard(); + } else { + game.log(player, "发动织梦,获得了", player.storage.xjzhimeng2); + player.gain(player.storage.xjzhimeng2, "gain2"); + player.popup("xjzhimeng"); + } + player.removeSkill("xjzhimeng2"); + } + event.num++; + event.redo(); + } + }, + }, + tannang: { + enable: "chooseToUse", + usable: 1, + locked: false, + filterCard: function (card) { + return get.suit(card) == "club"; + }, + filter: function (event, player) { + return player.countCards("h", { suit: "club" }); + }, + viewAs: { name: "shunshou" }, + viewAsFilter: function (player) { + if (!player.countCards("h", { suit: "club" })) return false; + }, + prompt: "将一张装备牌当顺手牵羊使用", + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("h", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); + } + if (player.countCards("h") < player.hp) { + return 6 - get.value(card); + } + return 2 - get.equipValue(card); + }, + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "shunshou") return true; + }, + }, + ai: { + order: 9.5, + threaten: 1.5, + }, + }, + tuoqiao: { + enable: "chooseToUse", + filterCard: { color: "black" }, + position: "he", + viewAs: { name: "shihuifen" }, + viewAsFilter: function (player) { + return player.countCards("he", { color: "black" }) > 0; + }, + ai: { + shihuifen: true, + skillTagFilter: function (player) { + return player.countCards("he", { color: "black" }) > 0; + }, + }, + }, + tuoqiao_old: { + filter: function (event, player) { + return ( + game.players.length > 3 && + (event.player == player.next || event.player == player.previous) + ); + }, + check: function (event, player) { + return get.effect(player, event.card, event.player, player) < 0; + }, + changeSeat: true, + trigger: { target: "useCardToBefore" }, + content: function () { + if (trigger.player == player.next) { + game.swapSeat(player, player.previous); + } else if (trigger.player == player.previous) { + game.swapSeat(player, player.next); + } else { + return; + } + trigger.cancel(); + // player.popup('xiaoyao'); + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (target == player.next || target == player.previous) return 0.1; + }, + }, + }, + }, + tianjian_old: { + enable: "phaseUse", + usable: 1, + changeSeat: true, + filterTarget: function (card, player, target) { + return player != target && player.next != target; + }, + filterCard: true, + check: function (card) { + return 4 - get.value(card); + }, + content: function () { + while (player.next != target) { + game.swapSeat(player, player.next); + } + }, + ai: { + order: 5, + result: { + player: function (player, target) { + var att = get.attitude(player, target); + if (target == player.previous && att > 0) return 1; + if (target == player.next.next && get.attitude(player, player.next) < 0) return 1; + return 0; + }, + }, + }, + }, + huimeng: { + trigger: { player: "recoverAfter" }, + frequent: true, + content: function () { + player.draw(2); + }, + ai: { + threaten: 0.8, + }, + }, + tianshe: { + group: ["tianshe2"], + trigger: { player: "damageBefore" }, + filter: function (event) { + if (event.hasNature()) return true; + return false; + }, + forced: true, + content: function () { + trigger.cancel(); + }, + ai: { + nofire: true, + nothunder: true, + effect: { + target: function (card, player, target, current) { + if (card.name == "tiesuo") return 0; + if (get.tag(card, "fireDamage")) return 0; + if (get.tag(card, "thunderDamage")) return 0; + }, + }, + }, + }, + tianshe2: { + trigger: { source: "damageAfter" }, + filter: function (event, player) { + if (event.hasNature() && player.hp < player.maxHp) return true; + }, + forced: true, + content: function () { + player.recover(); + }, + }, + }, + translate: { + pal_xiahoujinxuan: "夏侯瑾轩", + pal_muchanglan: "暮菖兰", + pal_xia: "瑕", + pal_jiangcheng: "姜承", + + pal_jiangyunfan: "姜云凡", + pal_tangyurou: "唐雨柔", + pal_longyou: "龙幽", + pal_xiaoman: "小蛮", + + pal_wangxiaohu: "王小虎", + pal_sumei: "苏媚", + pal_shenqishuang: "沈欺霜", + pal_longkui: "龙葵", + pal_nangonghuang: "南宫煌", + pal_wenhui: "温慧", + pal_wangpengxu: "王蓬絮", + pal_xingxuan: "星璇", + pal_leiyuange: "雷元戈", + + pal_zhaoliner: "赵灵儿", + pal_linyueru: "林月如", + pal_lixiaoyao: "李逍遥", + + pal_xuejian: "雪见", + pal_jingtian: "景天", + pal_zixuan: "紫萱", + pal_anu: "阿奴", + + pal_yuntianhe: "云天河", + pal_hanlingsha: "韩菱纱", + pal_liumengli: "柳梦璃", + pal_murongziying: "慕容紫英", + pal_changqing: "长卿", + pal_xuanxiao: "玄霄", + + pal_yuejinzhao: "越今朝", + pal_yueqi: "越祈", + pal_luozhaoyan: "洛昭言", + pal_xianqing: "闲卿", + pal_mingxiu: "明绣", + pal_jushifang: "居十方", + + xyufeng: "御蜂", + xyufeng_info: "出牌阶段限一次,可以将一张黑桃牌当作机关蜂使用。", + lingquan: "灵泉", + lingquan_info: + "觉醒技,结束阶段,若游戏轮数不小于3且你本回合使用的牌数大于你的体力值,你摸三张牌,然后获得技能【水蕴】。", + shenwu: "神舞", + shenwu_info: + "觉醒技,在一名角色的结束阶段,若你本局至少发动过3次【水蕴】,你增加1点体力和体力上限并获得2点护甲,然后获得技能【回梦】。", + txianqu: "仙音", + txianqu_info: "出牌阶段限一次,当你即将造成伤害时,你可以防止之,然后摸两张牌并回复1点体力。", + qiongguang: "穹光", + qiongguang_info: + "弃牌阶段结束时,若你弃置了至少两张牌,你可以对所有敌方角色施加一个随机的负面效果。", + xunying: "迅影", + xunying_info: "每当你使用杀对一名目标结算完毕后,你可以继续对目标使用杀。", + liefeng: "冽风", + liefeng_info: + "锁定技,当你在回合内使用第二张牌时,你本回合获得【炎斩】;当你在回合内使用第三张牌时,你本回合获得【天剑】;当你在回合内使用第四张牌时,你本回合获得【御风】。", + yuexing: "越行", + yuexing2: "越行", + yuexing_info: + "出牌阶段限一次,你可以指定一名角色,本阶段内将你与该角色到其他角色的距离基数互换。", + lingdi: "灵笛", + lingdi_info: + "出牌阶段,你可以弃置一张本回合与此法弃置的牌花色均不同的手牌,然后选择一名与你距离为X的角色与其各摸一张牌,X为本回合发动灵笛的次数(含此次)。", + xiaoyue: "啸月", + xiaoyue_info: + "锁定技,每轮开始时,若你手牌中有杀,你将手牌中的一张随机杀对一名随机敌方角色使用,然后获得1点护甲。", + minsha: "冥煞", + minsha_info: + "出牌阶段限一次,你可以弃置两张牌,对一名体力值大于1的其他角色造成1点雷属性伤害,然后距离目标1以内的所有其他角色随机弃置一张牌。", + xhuanlei: "唤雷", + xhuanlei_info: + "每当你受到一次伤害,若伤害来源体力值大于你,你可以对其造成1点雷属性伤害,然后其摸一张牌。", + anwugu: "巫蛊", + anwugu2: "蛊", + anwugu_info: + "每当你对其他角色造成一次伤害,你可以令目标获得三枚蛊标记;拥有蛊标记的角色手牌上限-1,每回合最多使用X张牌(X为蛊标记数),每个结束阶段失去一枚蛊标记。", + xtanxi: "探息", + xtanxi_info: + "出牌阶段限一次,你可以弃置一张手牌,然后随机选择一名手牌中有与之同名的牌的敌方角色,观看其手牌并获得任意一张。", + linghuo: "灵火", + linghuo_info: + "每两轮限一次,在一名其他角色的结束阶段,若其本回合内造成过伤害,你可以对其造成1点火属性伤害。", + guijin: "归烬", + guijin2: "归烬", + guijin2_bg: "烬", + guijin_info: + "每三轮限一次,出牌阶段,你可以观看牌堆顶的四张牌,然后可以将其中任意张牌分配给任意角色,被分到牌的角色跳过下一摸牌阶段,然后将剩余牌以原顺序放回牌堆顶。", + chengxin: "澄心", + chengxin2: "澄心", + chengxin2_bg: "心", + chengxin_info: + "每四轮限一次,当一名角色进入濒死状态时,你可以令其将体力值回复至1,然后该角色防止一切伤害直到下一回合结束。", + tianwu: "天舞", + tianwu_info: "每当你使用卡牌指定一名敌方角色为唯一目标,你可以对其施加一个随机的负面效果。", + tianwu_info_alter: + "每当你使用卡牌指定一名敌方角色为唯一目标,你可以对其施加一个随机的负面效果,每回合限发动一次。", + liguang: "离光", + liguang_info: "结束阶段,你可以弃置一张手牌并将场上的一张牌移动到另一个合理的位置。", + shiying: "逝影", + shiying_info: + "限定技,在一名其他角色死亡前,你可以防止其死亡,然后你与该角色失去全部技能、将体力和体力上限变为3、移去所有牌并摸三张牌。", + yujia: "御甲", + yujia_info: + "每当你使用一张未强化的装备牌,你可以随机观看X张机关牌,并选择一张获得之,X为你本局使用过的机关牌数且至少为1。", + xiepan: "械磐", + xiepan_info: "每当你失去最后一张基本牌,你可以弃置一张手牌,然后获得一张随机装备牌。", + yanshi: "偃师", + yanshi_info: + "觉醒技,结束阶段,若你累计有4个回合使用过机关牌,你增加1点体力和体力上限,然后用随机装备填满你的装备区。", + ywuhun: "雾魂", + ywuhun_bg: "魂", + ywuhun_info: + "锁定技,回合开始前,你获得一个额外的回合,并在此回合结束后复原场上及牌堆中的所有牌;当你在此回合中造成伤害后,终止所有结算并结束此回合。", + // ywuhun_info_alter:'锁定技,回合开始前,你获得一个额外的回合,并在此回合结束后复原场上及牌堆中的所有牌;当你在此回合中造成伤害后,终止所有结算并结束此回合。', + feichen: "飞尘", + feichen_info: "", + tanhua: "昙华", + tanhua_info: + "锁定技,你回复体力的效果改为摸两张牌;当你进入濒死状态时,你回复1点体力并失去此技能。", + xjyingfeng: "影锋", + xjyingfeng_info: + "锁定技,每当你使用一张杀结算完毕后,你随机对一名不是此杀目标的敌方角色使用一张杀。", + fenglue: "风掠", + fenglue_info: + "你可以放弃出牌阶段,改为指定一名其他角色并选择任意张手牌,依次对该角色使用,若如此做,此阶段内该角色每受到1点伤害,你在结算后摸一张牌。", + xjzongyu: "纵雨", + xjzongyu_info: + "出牌阶段限一次,你可以弃置一张黑色手牌,视为使用一张飞镖,随机指定两名敌方角色为目标。", + fanling: "返灵", + fanling_info: "锁定技,每当一名角色失去体力,你回复1点体力,每回合只能发动一次。", + huahu: "化狐", + huahu_bg: "狐", + huahu_info: + "限定技,你可以失去所有技能和1点体力上限,然后令任意名其他角色回复1点体力、获得1点护甲并摸一张牌。", + sheying: "蛇影", + sheying_info: + "每回合限一次,当你使用卡牌造成一次伤害后,你可以进行一次判定,若结果为黑色,你收回此牌。", + dujiang: "毒降", + dujiang_info: "出牌阶段限一次,你可以弃置一张黑色牌令一名随机敌人获得一张毒。", + binxin: "冰心", + binxin_info: "在一名角色的结束阶段,若其体力值为1,你可以令其获得1点护甲。", + qixia: "绮霞", + qixia_info: "锁定技,当你累计使用或打出了4种不同花色的牌后,你于本回合结束后获得一个额外回合。", + jianzhen: "剑阵", + jianzhen_info: + "锁定技,当你使用杀对目标结算完毕后,其他角色可以对该目标使用一张杀,当有人选择出杀后终止此结算。", + husha: "虎煞", + husha_bg: "煞", + husha_info: + "每当你于出牌阶段造成1点伤害,你获得一枚虎煞标记(标记数不超过3);结束阶段,你可以选择一项:1. 移去一枚虎煞标记,视为对任意角色使用一张杀;2. 移去两枚虎煞标记,视为使用一张南蛮入侵;3. 移去三枚虎煞标记,视为对除你之外的角色使用一张元素毁灭。", + longhuo: "龙火", + longhuo_info: "结束阶段,你可以对所有角色各造成1点火焰伤害。", + fenshi: "焚世", + fenshi_info: "觉醒技,当你解除濒死状态时,你获得2点护甲,摸两张牌,然后获得技能龙火。", + yanzhan: "炎斩", + yanzhan_info: + "出牌阶段限一次,你可以将一张红色牌当作火杀使用,此杀只能用与之花色相同的闪响应;若此杀造成了伤害,你本回合可以额外使用一张杀。", + feixia: "飞霞", + feixia_info: "出牌阶段限一次,你可以弃置一张红色牌视为对一名随机敌人使用一张不计入出杀次数的杀。", + lueying: "掠影", + lueying_info: + "每当你使用一张杀,你可以随机获得目标的一张牌,然后目标可以指定一名其他角色,你弃置该角色一张牌(每回合限发动一次,没有弃牌目标时无法发动)。", + feng: "风", + feng_info: "锁定技,当你累计摸2次牌后,你下一次摸牌时摸牌数+1。", + ya: "雅", + ya_info: "锁定技,当你累计受到2次伤害后,你下一次受到的伤害-1。", + song: "颂", + song_info: "锁定技,当你累计造成2次伤害后,你下一次造成的伤害+1。", + longxiang: "龙翔", + longxiang_info: "当你使用杀指定目标后,你可以弃置目标若干张手牌直到其手牌数与你相同。", + huxi: "虎袭", + huxi_info: "你可以失去1点体力并获得1点护甲,视为使用一张杀。", + xuanmo: "玄墨", + xuanmo_info: "出牌阶段限一次,你可以将一张手牌置于牌堆顶并随机获得两张与之类别相同的牌。", + danqing: "丹青", + danqing_info: + "结束阶段,若你累计使用了4张花色不同的牌,你可以选择至多4名角色随机获得一个正面效果。", + danqing_info_alter: + "结束阶段,若你累计使用了4张花色不同的牌,你可以选择至多2名角色随机获得一个正面效果。", + zhangmu: "障目", + zhangmu_info: + "每回合限一次,当你需要使用或打出一张闪时,你可以展示一张闪,视为使用或打出了此闪。", + feizhua: "飞爪", + feizhua_info: "当你使用一张杀时,你可以将与目标相邻的角色追加为额外目标。", + leiyu: "雷狱", + leiyu_info: + "结束阶段,你可以弃置一张黑色手牌,视为对本回合内所有成为过你的卡牌目标的角色使用一张惊雷闪。", + lingxue: "灵血", + lingxue_info: "锁定技,每当你回复1点体力,你获得1点护甲。", + zhaoyao: "招摇", + zhaoyao_info: + "其他角色的摸牌阶段开始时,你可以与其拼点,若你赢,你摸两张牌,然后将两张牌置于牌堆顶。", + sheling: "摄灵", + sheling_info: + "其他角色于你的回合内因使用、打出或弃置而失去牌时,你可以获得之(每回合最多发动三次)。", + fenxing: "分形", + fenxing_info: "锁定技,准备阶段,你有50%概率变身为另一形态。", + guijiang: "鬼降", + guijiang2: "鬼降", + guijiang_info: + "出牌阶段限一次,你可以弃置一张黑色牌,令一名其他角色无法成为回复牌的目标直到你下一回合开始。", + diesha: "叠杀", + diesha_info: "锁定技,每当你使用杀造成伤害,受伤害角色失去1点体力,你回复1点体力。", + lingyu: "灵愈", + lingyu_info: "结束阶段,你可以令一名其他角色回复1点体力。", + diewu: "蝶舞", + diewu_info: "出牌阶段,你可以将一张【杀】交给一名角色,若你于此阶段内首次如此做,你摸一张牌。", + duxinshu: "读心", + duxinshu_info: "出牌阶段限一次,你可以观看一名其他角色的手牌,然后可以用一张手牌替换其中的一张。", + feixu: "飞絮", + feixu_info: "每当一名角色使用或打出一张闪,你可以令其摸一张牌。", + xuanyan: "玄炎", + xuanyan2: "玄炎", + xuanyan_info: "锁定技,你的火属性伤害+1;你造成火属性伤害后失去1点体力。", + ningbin: "凝冰", + ningbin_info: "锁定技,每当你受到1次雷属性伤害,你回复1点体力。", + xfenxin: "焚心", + xfenxin2: "焚心", + xfenxin_info: + "锁定技,每当你的体力值发生改变,你摸等量的牌;每当你杀死一名角色,你增加1点体力上限并回复1点体力。", + xfenxin_info_alter: "锁定技,每当你的体力值发生改变,你摸一张牌。", + luanjian: "乱剑", + luanjian_info: + "出牌阶段,你可以将两张杀当杀使用,此杀无视距离,可以指定任意名目标且有50%的机率伤害+1。", + ctianfu: "天符", + ctianfu2: "天符", + ctianfu3: "天符", + ctianfu_info: + "出牌阶段,你可以将一张闪置于一名其他角色的武将牌上,该角色在下一次造成伤害时受到来自你的1点雷属性伤害并随机弃置一张牌,然后移去此牌。", + shuiyun: "水蕴", + shuiyun_bg: "蕴", + shuiyun2: "水蕴", + shuiyun5: "水蕴", + shuiyun3: "水蕴", + shuiyun_info: + "结束阶段,你可以将一张与武将牌上的牌类别均不相同的手牌置于武将牌上称为“蕴”;任意一名角色处于濒死状态时,你可以弃置一张“蕴”令其回复1点体力。", + shuiyun_info_alter: + "结束阶段,你可以将一张与武将牌上的牌类别均不相同的手牌置于武将牌上称为“蕴”(不能超过2张);任意一名角色处于濒死状态时,你可以弃置一张“蕴”令其回复1点体力。", + wangyou: "忘忧", + wangyou_info: "其他角色的结束阶段,你可以弃置一张牌,令此回合内受过伤害的所有角色各摸一张牌。", + changnian: "长念", + changnian2: "追思", + changnian2_info: "锁定技,结束阶段,你摸一张牌。", + changnian_info: "你死亡时,可以将所有牌交给一名其他角色,令其获得技能〖追思〗。", + sajin: "洒金", + sajin_info: + "出牌阶段限一次,你可以弃置一张手牌并指定任意名角色进行判定,若判定颜色与你弃置的牌相同,该角色回复1点体力。", + jtjubao: "聚宝", + jtjubao_info: "当其他角色于你的回合外首次弃置非基本牌时,你可以获得其中的随机一张。", + guiyuan: "归元", + guiyuan_info: "出牌阶段限一次,你可以弃置一张杀,然后回复1点体力并摸一张牌。", + xshuangren: "双刃", + xshuangren_info: + "当你的武器牌被替换时,你可以将其置于你的武将牌上,并获得此装备的武器效果(不含距离)。", + duci: "毒刺", + duci_info: "每当你失去一次装备牌,可以对距离1以内的一名其他角色造成1点伤害。", + shenmu: "神木", + shenmu_info: + "任意一名角色濒死时,你可以展示你的手牌并弃置其中的所有红色牌(至少一张),若如此做,该角色回复1点体力,然后摸X张牌,X为你弃置的手牌数。", + qijian: "气剑", + qijian_info: "弃牌阶段结束时,你可以指定至多X名目标视为使用一张杀,X为你于此阶段弃置的卡牌数。", + poyun: "破云", + poyun_info: "每当你造成一次伤害,你可以弃置一枚玄凝标记,然后弃置对方两张牌。", + poyun_info_alter: "每当你造成一次伤害,你可以弃置一枚玄凝标记,然后弃置对方一张牌。", + qianfang: "千方", + qianfang_info: + "准备阶段,若你有玄凝标记,你可以弃置3-X张牌和所有玄凝标记,视为使用了一张【万箭齐发】,每当一名敌方角色因此牌受到伤害,你摸一张牌。X为你的玄凝标记数。", + qianfang_info_alter: + "准备阶段,若你有玄凝标记,可以弃置3-X张牌和所有玄凝标记,视为使用了一张【万箭齐发】,X为你的玄凝标记数。", + longxi: "龙息", + longxi2: "龙息", + longxi_info: + "锁定技,在回合外每当你需要使用或打出一张卡牌时,若牌堆顶的前两张中有可使用或打出的牌,你立即获得之。", + zhuyue: "逐月", + zhuyue_info: + "出牌阶段限一次,你可以弃置一张非基本牌并指定至多两个目标各随机弃置一张牌,若如此做,你本回合使用的杀须指定选中角色为目标。", + zhuyue_info_alter: + "出牌阶段限一次,你可以弃置一张黑色非基本牌并指定至多两个目标各随机弃置一张牌,若如此做,你本回合使用的杀须指定选中角色为目标。", + guanri: "贯日", + guanri_info: + "限制技,你可以弃置两张红色手牌并失去1点体力,然后对一名体力值不少于你的其他角色造成2点火焰伤害并弃置其所有装备牌。", + tianxian: "天弦", + tianxian_info: + "锁定技,你的杀无视距离且可指定任意多个目标,目标须进行一次判定,若结果为黑色则取消之。", + xjzhimeng: "织梦", + xjzhimeng2: "织梦", + xjzhimeng3: "织梦", + xjzhimeng_info: + "结束阶段,你可以选择一名其他角色将牌堆顶的一张牌置于该角色的武将牌上,直到你的下个准备阶段将其收入手牌。当一名角色武将牌上有织梦牌时,每当其成为与此牌类型相同的卡牌的目标,可以摸一张牌。", + xjzhimeng_info_alter: "结束阶段,你可以令一名其他角色摸一张牌。", + runxin: "润心", + runxin_info: "每当你使用或打出一张红桃牌,你可以令一名角色回复1点体力。", + tannang: "探囊", + tannang_info: "出牌阶段限一次,你可以将一张梅花手牌当顺手牵羊使用;你的顺手牵羊无距离限制。", + tuoqiao: "烟瘴", + tuoqiao_info: "你可以将一张黑色牌当作石灰粉使用。", + xiaoyao: "逍遥", + xiaoyao_info: "每当你成为其他角色的卡牌目标,你可以弃置一张与之花色相同的手牌取消之。", + tianjian: "天剑", + tianjian_info: "出牌阶段限一次,你可以将一张杀当作万箭齐发使用,受到伤害的角色随机弃置一张牌。", + tianjian_info_alter: "出牌阶段限一次,你可以将一张杀当作万箭齐发使用。", + xjyufeng: "御风", + xjyufeng_info: "锁定技,当你失去手牌后,若手牌数少于2,你将手牌数补至2(每回合最多发动两次)。", + huimeng: "回梦", + huimeng_info: "每当你回复1点体力,可以摸两张牌。", + tianshe: "天蛇", + tianshe2: "天蛇", + tianshe_info: "锁定技,你防止即将受到的属性伤害,每当你造成一次属性伤害,你回复1点体力。", + }, + }; +}); diff --git a/character/xinghuoliaoyuan.js b/character/xinghuoliaoyuan.js index 2ba3a9168..da8ac9125 100755 --- a/character/xinghuoliaoyuan.js +++ b/character/xinghuoliaoyuan.js @@ -1,1749 +1,1998 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'xinghuoliaoyuan', - connect:true, - character:{ - wangcan:["male","qun",3,["xinfu_sanwen","xinfu_qiai","xinfu_denglou"]], - sp_taishici:["male","qun",4,["xinfu_jixu"]], - re_jsp_pangtong:["male","wu",3,["xinfu_guolun","xinfu_songsang"]], - lvdai:["male","wu",4,["xinfu_qinguo"]], - re_zhangliang:["male","qun",4,["xinfu_jijun","xinfu_fangtong"]], - lvqian:["male","wei",4,["xinfu_weilu","xinfu_zengdao"]], - panjun:["male","wu",3,["xinfu_guanwei","xinfu_gongqing"]], - duji:["male","wei",3,["xinfu_andong","xinfu_yingshi"]], - zhoufang:["male","wu",3,["xinfu_duanfa","xinfu_youdi"]], - yanjun:["male","wu",3,["xinfu_guanchao","xinfu_xunxian"]], - liuyao:["male","qun",4,["xinfu_kannan",'twniju'],['zhu']], - liuyan:["male","qun",3,["xinfu_tushe","xinfu_limu"]], + name: "xinghuoliaoyuan", + connect: true, + character: { + wangcan: ["male", "qun", 3, ["xinfu_sanwen", "xinfu_qiai", "xinfu_denglou"]], + sp_taishici: ["male", "qun", 4, ["xinfu_jixu"]], + re_jsp_pangtong: ["male", "wu", 3, ["xinfu_guolun", "xinfu_songsang"]], + lvdai: ["male", "wu", 4, ["xinfu_qinguo"]], + re_zhangliang: ["male", "qun", 4, ["xinfu_jijun", "xinfu_fangtong"]], + lvqian: ["male", "wei", 4, ["xinfu_weilu", "xinfu_zengdao"]], + panjun: ["male", "wu", 3, ["xinfu_guanwei", "xinfu_gongqing"]], + duji: ["male", "wei", 3, ["xinfu_andong", "xinfu_yingshi"]], + zhoufang: ["male", "wu", 3, ["xinfu_duanfa", "xinfu_youdi"]], + yanjun: ["male", "wu", 3, ["xinfu_guanchao", "xinfu_xunxian"]], + liuyao: ["male", "qun", 4, ["xinfu_kannan", "twniju"], ["zhu"]], + liuyan: ["male", "qun", 3, ["xinfu_tushe", "xinfu_limu"]], }, - characterSort:{ - xinghuoliaoyuan:{ + characterSort: { + xinghuoliaoyuan: { // xinghuoliaoyuan_tianfu:[], - xinghuoliaoyuan_tianliang:['duji','liuyan','yanjun'], - xinghuoliaoyuan_tianji:['panjun','wangcan'], - xinghuoliaoyuan_tiantong:['re_jsp_pangtong','sp_taishici'], - xinghuoliaoyuan_tianxiang:['lvdai','zhoufang','liuyao'], - xinghuoliaoyuan_qisha:['lvqian','re_zhangliang'], + xinghuoliaoyuan_tianliang: ["duji", "liuyan", "yanjun"], + xinghuoliaoyuan_tianji: ["panjun", "wangcan"], + xinghuoliaoyuan_tiantong: ["re_jsp_pangtong", "sp_taishici"], + xinghuoliaoyuan_tianxiang: ["lvdai", "zhoufang", "liuyao"], + xinghuoliaoyuan_qisha: ["lvqian", "re_zhangliang"], }, }, - characterIntro:{ - wangcan:"王粲(177年-217年2月17日),字仲宣。山阳郡高平县(今山东微山两城镇)人。东汉末年文学家,“建安七子”之一,太尉王龚曾孙、司空王畅之孙。", - re_jsp_pangtong:"庞统,字士元,襄阳(治今湖北襄阳)人。三国时刘备帐下谋士,官拜军师中郎将。才智与诸葛亮齐名,人称“凤雏”。在进围雒县时,统率众攻城,不幸被流矢击中去世,时年三十六岁。追赐统为关内侯,谥曰靖侯。庞统死后,葬于落凤庞统墓坡。", - lvdai:"吕岱(161年-256年),字定公,广陵海陵(今江苏如皋)人。三国时期吴国重臣、将领。吕岱一生戮力奉公,为孙吴开疆拓土,功勋赫赫。太平元年(256年),吕岱去世,年九十六。", - lvqian:"吕虔(生卒年不详),字子恪。任城国(今山东济宁东南)人。汉末至三国曹魏时期将领。 吕虔有勇有谋,曹操在兖州时,任命他为从事,率领家丁驻守湖陆。后升任泰山太守,与夏侯渊共同镇压济南等地的黄巾军。被推举为秀才,加任骑都尉,仍管辖泰山郡。 曹丕继任魏王后,加吕虔为裨将军,封益寿亭侯。再升任徐州刺史,加任威虏将军。任用王祥为别驾,将民政事务都委托于他,为世人所称赞。曹叡继位后,改封万年亭侯。吕虔死后,其子吕翻世袭万年亭侯。", - panjun:"潘濬(一作潘浚)(?-239年),字承明。武陵郡汉寿县(今湖南汉寿)人。三国时期吴国重臣,蜀汉大司马蒋琬的表弟。 潘濬为人聪察,对问有机理,拜大儒宋忠为师,得到“建安七子”之一的王粲赏识。不到三十,即被荆州牧刘表任命为江夏从事,因按杀贪污的沙羡长而闻名。建安十六年(211年),被刘备任命为荆州治中从事,与守臣关羽不睦。建安二十四年(219年),孙权得荆州,拜潘濬为辅军中郎将。又迁奋威将军,封常迁亭侯。孙权称帝后,拜少府,进封刘阳侯,又改太常。黄龙三年(231年),授假节,与吕岱率军五万平五溪蛮夷叛乱,经三年而斩获数万,使得一方宁静。潘濬为人刚正不阿,在吕壹弄权时,屡请孙权将其诛杀。甚至想亲手击杀吕壹,使吕壹对他非常畏惧。 赤乌二年(239年),潘濬去世。", - duji:"杜畿(163年—224年),字伯侯,京兆杜陵(今陕西西安东南)人。东汉末及三国时曹魏官吏及将领。西汉御史大夫杜延年的后代。历官郡功曹、守郑县令,善于断案。荀彧将他举荐给曹操,曹操任命他为司空司直,调任护羌校尉,使持节领西平太守。 曹丕受禅登基后,封杜畿为丰乐亭侯。官至尚书仆射。后在陶河试航时遇上大风沉没,杜畿淹死,死时六十二岁,曹丕为之涕泣,追赠其为太仆,谥戴侯。", - zhoufang:"周鲂(生卒年不详),字子鱼。吴郡阳羡县(今江苏宜兴)人。三国时期吴国将领。周鲂年少时好学,被举为孝廉。历任宁国县长、怀安县长、钱塘侯相,一月之内,便斩杀作乱的彭式及其党羽,因而升任丹阳西部都尉。彭绮率数万人反叛时,周鲂被任命为鄱阳太守,与胡综共同将其生擒,因功加职昭义校尉。后诈降曹休,诱其率军接应,使曹休在石亭之战中一败涂地,战后因功被加职为裨将军,封关内侯。贼帅董嗣凭险骚扰豫章等郡,周鲂派间谍将其诱杀,不费兵卒即安定数郡。周鲂在鄱阳赏罚分明、恩威并施,于任职十三年后去世。", - yanjun:"严畯(生卒年不详),字曼才,彭城(治今江苏徐州)人,三国时期孙吴官员、学者。性情忠厚,待人以诚。少好学,精通《诗》、《书》、《三礼》,又好《说文》。避乱江东,与诸葛瑾、步骘是好朋友,被张昭推荐给孙权作骑都尉、从事中郎。建安二十二年(217年),横江将军鲁肃去世,孙权打算让严畯接替其位。严畯很有自知之明,知道自己没有能力对抗在荆州的关羽和北面的曹魏,便坚决不接受此任命。后来担任尚书令。严畯享年七十八岁。著有《孝经传》、《潮水论》。", - liuyao:"刘繇(一读yóu)(156年-197年),字正礼。东莱牟平(今山东牟平)人。东汉末年宗室、大臣,汉末群雄之一,齐悼惠王刘肥之后,太尉刘宠之侄。
              刘繇最初被推举为孝廉,授郎中。任下邑县长时,因拒郡守请托而弃官。后被征辟为司空掾属,除授侍御史,因战乱而不到任,避居淮浦。兴平元年(194年),被任命为扬州刺史。他先后与袁术、孙策交战,一度被朝廷加授为扬州牧、振武将军,但最终还是败归丹徒。此后,刘繇又击破反叛的笮融,旋即病逝,年四十二。", - liuyan:"刘焉(?-194年),字君郎(《华阳国志》又作君朗)。江夏郡竟陵县(今湖北省天门市)人。东汉末年宗室、军阀,汉末群雄之一,西汉鲁恭王刘余之后。
              刘焉初以汉朝宗室身份,拜为中郎,历任雒阳令、冀州刺史、南阳太守、宗正、太常等官。因益州刺史郄俭在益州大肆聚敛,贪婪成风,加上当时天下大乱。刘焉欲取得一安身立命之所,割据一方,于是向朝廷求为益州牧,封阳城侯,前往益州整饬吏治。郄俭为黄巾军所杀,刘焉进入益州,派张鲁盘踞汉中,张鲁截断交通,斩杀汉使,从此益州与中央道路不通。刘焉进一步对内打击地方豪强,巩固自身势力,益州因而处于半独立的状态。兴平元年(194年),刘焉因背疮迸发而逝世,其子刘璋继领益州牧。", + characterIntro: { + wangcan: + "王粲(177年-217年2月17日),字仲宣。山阳郡高平县(今山东微山两城镇)人。东汉末年文学家,“建安七子”之一,太尉王龚曾孙、司空王畅之孙。", + re_jsp_pangtong: + "庞统,字士元,襄阳(治今湖北襄阳)人。三国时刘备帐下谋士,官拜军师中郎将。才智与诸葛亮齐名,人称“凤雏”。在进围雒县时,统率众攻城,不幸被流矢击中去世,时年三十六岁。追赐统为关内侯,谥曰靖侯。庞统死后,葬于落凤庞统墓坡。", + lvdai: "吕岱(161年-256年),字定公,广陵海陵(今江苏如皋)人。三国时期吴国重臣、将领。吕岱一生戮力奉公,为孙吴开疆拓土,功勋赫赫。太平元年(256年),吕岱去世,年九十六。", + lvqian: "吕虔(生卒年不详),字子恪。任城国(今山东济宁东南)人。汉末至三国曹魏时期将领。 吕虔有勇有谋,曹操在兖州时,任命他为从事,率领家丁驻守湖陆。后升任泰山太守,与夏侯渊共同镇压济南等地的黄巾军。被推举为秀才,加任骑都尉,仍管辖泰山郡。 曹丕继任魏王后,加吕虔为裨将军,封益寿亭侯。再升任徐州刺史,加任威虏将军。任用王祥为别驾,将民政事务都委托于他,为世人所称赞。曹叡继位后,改封万年亭侯。吕虔死后,其子吕翻世袭万年亭侯。", + panjun: "潘濬(一作潘浚)(?-239年),字承明。武陵郡汉寿县(今湖南汉寿)人。三国时期吴国重臣,蜀汉大司马蒋琬的表弟。 潘濬为人聪察,对问有机理,拜大儒宋忠为师,得到“建安七子”之一的王粲赏识。不到三十,即被荆州牧刘表任命为江夏从事,因按杀贪污的沙羡长而闻名。建安十六年(211年),被刘备任命为荆州治中从事,与守臣关羽不睦。建安二十四年(219年),孙权得荆州,拜潘濬为辅军中郎将。又迁奋威将军,封常迁亭侯。孙权称帝后,拜少府,进封刘阳侯,又改太常。黄龙三年(231年),授假节,与吕岱率军五万平五溪蛮夷叛乱,经三年而斩获数万,使得一方宁静。潘濬为人刚正不阿,在吕壹弄权时,屡请孙权将其诛杀。甚至想亲手击杀吕壹,使吕壹对他非常畏惧。 赤乌二年(239年),潘濬去世。", + duji: "杜畿(163年—224年),字伯侯,京兆杜陵(今陕西西安东南)人。东汉末及三国时曹魏官吏及将领。西汉御史大夫杜延年的后代。历官郡功曹、守郑县令,善于断案。荀彧将他举荐给曹操,曹操任命他为司空司直,调任护羌校尉,使持节领西平太守。 曹丕受禅登基后,封杜畿为丰乐亭侯。官至尚书仆射。后在陶河试航时遇上大风沉没,杜畿淹死,死时六十二岁,曹丕为之涕泣,追赠其为太仆,谥戴侯。", + zhoufang: + "周鲂(生卒年不详),字子鱼。吴郡阳羡县(今江苏宜兴)人。三国时期吴国将领。周鲂年少时好学,被举为孝廉。历任宁国县长、怀安县长、钱塘侯相,一月之内,便斩杀作乱的彭式及其党羽,因而升任丹阳西部都尉。彭绮率数万人反叛时,周鲂被任命为鄱阳太守,与胡综共同将其生擒,因功加职昭义校尉。后诈降曹休,诱其率军接应,使曹休在石亭之战中一败涂地,战后因功被加职为裨将军,封关内侯。贼帅董嗣凭险骚扰豫章等郡,周鲂派间谍将其诱杀,不费兵卒即安定数郡。周鲂在鄱阳赏罚分明、恩威并施,于任职十三年后去世。", + yanjun: "严畯(生卒年不详),字曼才,彭城(治今江苏徐州)人,三国时期孙吴官员、学者。性情忠厚,待人以诚。少好学,精通《诗》、《书》、《三礼》,又好《说文》。避乱江东,与诸葛瑾、步骘是好朋友,被张昭推荐给孙权作骑都尉、从事中郎。建安二十二年(217年),横江将军鲁肃去世,孙权打算让严畯接替其位。严畯很有自知之明,知道自己没有能力对抗在荆州的关羽和北面的曹魏,便坚决不接受此任命。后来担任尚书令。严畯享年七十八岁。著有《孝经传》、《潮水论》。", + liuyao: "刘繇(一读yóu)(156年-197年),字正礼。东莱牟平(今山东牟平)人。东汉末年宗室、大臣,汉末群雄之一,齐悼惠王刘肥之后,太尉刘宠之侄。
              刘繇最初被推举为孝廉,授郎中。任下邑县长时,因拒郡守请托而弃官。后被征辟为司空掾属,除授侍御史,因战乱而不到任,避居淮浦。兴平元年(194年),被任命为扬州刺史。他先后与袁术、孙策交战,一度被朝廷加授为扬州牧、振武将军,但最终还是败归丹徒。此后,刘繇又击破反叛的笮融,旋即病逝,年四十二。", + liuyan: "刘焉(?-194年),字君郎(《华阳国志》又作君朗)。江夏郡竟陵县(今湖北省天门市)人。东汉末年宗室、军阀,汉末群雄之一,西汉鲁恭王刘余之后。
              刘焉初以汉朝宗室身份,拜为中郎,历任雒阳令、冀州刺史、南阳太守、宗正、太常等官。因益州刺史郄俭在益州大肆聚敛,贪婪成风,加上当时天下大乱。刘焉欲取得一安身立命之所,割据一方,于是向朝廷求为益州牧,封阳城侯,前往益州整饬吏治。郄俭为黄巾军所杀,刘焉进入益州,派张鲁盘踞汉中,张鲁截断交通,斩杀汉使,从此益州与中央道路不通。刘焉进一步对内打击地方豪强,巩固自身势力,益州因而处于半独立的状态。兴平元年(194年),刘焉因背疮迸发而逝世,其子刘璋继领益州牧。", }, - characterTitle:{}, - perfectPair:{ - lijue:['guosi','jiaxu'], - zhangji:['zhangxiu','drlt_zhangxiu','zoushi'], - xf_sufei:['ganning'], + characterTitle: {}, + perfectPair: { + lijue: ["guosi", "jiaxu"], + zhangji: ["zhangxiu", "drlt_zhangxiu", "zoushi"], + xf_sufei: ["ganning"], //baosanniang:['guansuo'], - simahui:['pangdegong'], - zhangqiying:['zhanglu'], - pangtong:['zhugejin'], - taishici:['liuyao','kongrong'], + simahui: ["pangdegong"], + zhangqiying: ["zhanglu"], + pangtong: ["zhugejin"], + taishici: ["liuyao", "kongrong"], //zhaotongzhaoguang:['zhaoyun','mayunlu'], }, - skill:{ - xinyingshi:{ - audio:'xinfu_yingshi', - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0&&!game.hasPlayer(function(current){ - return current.getExpansions('xinyingshi_cards').length>0; - }); + skill: { + xinyingshi: { + audio: "xinfu_yingshi", + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + !game.hasPlayer(function (current) { + return current.getExpansions("xinyingshi_cards").length > 0; + }) + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - filterCard:true, - filterTarget:lib.filter.notMe, - selectCard:[1,player.countCards('he')], - position:'he', - prompt:get.prompt('xinyingshi'), - prompt2:'将任意张牌置于一名其他角色的武将牌上作为“酬”', - ai1:function(card){ - return 1-player.getUseValue(card); + filterCard: true, + filterTarget: lib.filter.notMe, + selectCard: [1, player.countCards("he")], + position: "he", + prompt: get.prompt("xinyingshi"), + prompt2: "将任意张牌置于一名其他角色的武将牌上作为“酬”", + ai1: function (card) { + return 1 - player.getUseValue(card); }, - ai2:function(target){ - var player=_status.event.player; - return (1+game.countPlayer(function(current){ - return get.attitude(player,current)>0&¤t.inRange(target)&&get.damageEffect(target,current,player)>0; - }))*-get.attitude(player,target); + ai2: function (target) { + var player = _status.event.player; + return ( + (1 + + game.countPlayer(function (current) { + return ( + get.attitude(player, current) > 0 && + current.inRange(target) && + get.damageEffect(target, current, player) > 0 + ); + })) * + -get.attitude(player, target) + ); }, }); - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.logSkill('xinyingshi',target); - target.addSkill('xinyingshi_cards'); - target.addToExpansion(player,'give',cards).gaintag.add('xinyingshi_cards'); - target.storage.xinyingshi_source=player; + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.logSkill("xinyingshi", target); + target.addSkill("xinyingshi_cards"); + target.addToExpansion(player, "give", cards).gaintag.add("xinyingshi_cards"); + target.storage.xinyingshi_source = player; } }, - subSkill:{ - cards:{ - trigger:{player:'damageSource'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.card&&event.getParent().type=='card'&& - player.getExpansions('xinyingshi_cards').length; + subSkill: { + cards: { + trigger: { player: "damageSource" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.card && + event.getParent().type == "card" && + player.getExpansions("xinyingshi_cards").length + ); }, - logTarget:'source', - content:function(){ - 'step 0' - event.target=trigger.source; - event.target.chooseButton(['应势:请选择你的赏金',player.getExpansions('xinyingshi_cards')]); - 'step 1' - if(result.bool){ - var cards=[result.links[0]]; - for(var i=0;i1){ - setTimeout(function(){ + player.$give(cards[0], target); + if (cards.length > 1) { + setTimeout(function () { target.$gain2(cards.slice(1)); - },get.delayx(200,200)); - game.log(target,'从牌堆获得了',cards.slice(1)) + }, get.delayx(200, 200)); + game.log(target, "从牌堆获得了", cards.slice(1)); } - game.delay(0,get.delayx(500,500)); + game.delay(0, get.delayx(500, 500)); target.gain(cards); } - 'step 2' - if(!player.getExpansions('xinyingshi_cards').length) player.removeSkill('xinyingshi_cards'); + "step 2"; + if (!player.getExpansions("xinyingshi_cards").length) + player.removeSkill("xinyingshi_cards"); }, - marktext:'酬', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "酬", + intro: { + content: "expansion", + markcount: "expansion", }, - ai:{threaten:3}, - group:'xinyingshi_regain', - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + ai: { threaten: 3 }, + group: "xinyingshi_regain", + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage.xinyingshi_source; }, }, - regain:{ - trigger:{player:'die'}, - forced:true, - charlotte:true, - forceDie:true, - filter:function(event,player){ - return player.storage.xinyingshi_source&&player.storage.xinyingshi_source.isIn()&&player.getExpansions('xinyingshi_cards').length>0; + regain: { + trigger: { player: "die" }, + forced: true, + charlotte: true, + forceDie: true, + filter: function (event, player) { + return ( + player.storage.xinyingshi_source && + player.storage.xinyingshi_source.isIn() && + player.getExpansions("xinyingshi_cards").length > 0 + ); }, - content:function(){ - player.storage.xinyingshi_source.gain(player.getExpansions('xinyingshi_cards'),player,'give','bySelf'); + content: function () { + player.storage.xinyingshi_source.gain( + player.getExpansions("xinyingshi_cards"), + player, + "give", + "bySelf" + ); }, }, }, }, - xinfu_guolun:{ - audio:2, - enable:"phaseUse", - usable:1, - filter:function (event,player){ - return player.countCards('h')>0; + xinfu_guolun: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function (card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - content:function (){ - 'step 0' - player.choosePlayerCard(target,true,'h'); - 'step 1' - event.cardt=result.cards[0]; + content: function () { + "step 0"; + player.choosePlayerCard(target, true, "h"); + "step 1"; + event.cardt = result.cards[0]; target.showCards(event.cardt); - player.chooseCard('he').set('ai',function(card){ - var event=_status.event.getParent(),player=event.player; - var numt=get.number(event.cardt); - var att=get.attitude(player,target); - var value=get.value(event.cardt); - var num=get.number(card); - if(num2) return value+6-get.value(card); - else if(num==numt) return value-get.value(card); + player.chooseCard("he").set("ai", function (card) { + var event = _status.event.getParent(), + player = event.player; + var numt = get.number(event.cardt); + var att = get.attitude(player, target); + var value = get.value(event.cardt); + var num = get.number(card); + if (num < numt || att > 2) return value + 6 - get.value(card); + else if (num == numt) return value - get.value(card); return -1; }); - 'step 2' - if(!result.bool) event.finish(); - else{ + "step 2"; + if (!result.bool) event.finish(); + else { player.showCards(result.cards); - event.cardp=result.cards[0]; + event.cardp = result.cards[0]; } - 'step 3' - player.swapHandcards(target,[event.cardp],[event.cardt]); - 'step 4' - var nump=get.number(event.cardp,player); - var numt=get.number(event.cardt,target); - if(numpnumt){ + } else if (nump > numt) { target.draw(); } }, - ai:{ - threaten:1.5, - order:8, - result:{ - player:function (player,target){ - if(get.attitude(player,target)>0) return 1.5; + ai: { + threaten: 1.5, + order: 8, + result: { + player: function (player, target) { + if (get.attitude(player, target) > 0) return 1.5; return 0.5; }, }, }, }, - "xinfu_zhanji":{ - audio:2, - trigger:{ - player:"gainAfter", + xinfu_zhanji: { + audio: 2, + trigger: { + player: "gainAfter", }, - forced:true, - filter:function (event,player){ - if(!player.isPhaseUsing()) return false; - return event.getParent().name=='draw'&&event.getParent(2).name!='xinfu_zhanji'; + forced: true, + filter: function (event, player) { + if (!player.isPhaseUsing()) return false; + return event.getParent().name == "draw" && event.getParent(2).name != "xinfu_zhanji"; }, - content:function (){ - player.draw('nodelay'); + content: function () { + player.draw("nodelay"); }, }, - "xinfu_songsang":{ - limited:true, - skillAnimation:true, - animationColor:'wood', - audio:2, - derivation:"xinfu_zhanji", - trigger:{global:"dieAfter"}, - logTarget:'player', - async content(e,t,player){ - player.awakenSkill('xinfu_songsang'); - if(player.isDamaged()){ + xinfu_songsang: { + limited: true, + skillAnimation: true, + animationColor: "wood", + audio: 2, + derivation: "xinfu_zhanji", + trigger: { global: "dieAfter" }, + logTarget: "player", + async content(e, t, player) { + player.awakenSkill("xinfu_songsang"); + if (player.isDamaged()) { player.recover(); - } - else player.gainMaxHp(); - player.addSkills('xinfu_zhanji'); + } else player.gainMaxHp(); + player.addSkills("xinfu_zhanji"); }, }, - "xinfu_jixu":{ - audio:2, - enable:"phaseUse", - usable:1, - filter:function (event,player){ - return player.countCards('h')>0; + xinfu_jixu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function (card,player,target){ - if(player==target) return false; - if(ui.selected.targets.length){ - return target.hp==ui.selected.targets[0].hp; + filterTarget: function (card, player, target) { + if (player == target) return false; + if (ui.selected.targets.length) { + return target.hp == ui.selected.targets[0].hp; } return true; }, - selectTarget:[1,Infinity], - multitarget:true, - multiline:true, - content:function (){ - "step 0" + selectTarget: [1, Infinity], + multitarget: true, + multiline: true, + content: function () { + "step 0"; targets.sort(lib.sort.seat); - "step 1" - if(!event.num) event.num=0; - if(!event.caicuolist) event.caicuolist=[]; - targets[event.num].chooseBool("是否押杀?").ai=function(event,player){ - var evt=_status.event.getParent(); - if(get.attitude(targets[event.num],evt.player)>0) return evt.player.countCards('h','sha')?false:true; - return Math.random()<0.5; + "step 1"; + if (!event.num) event.num = 0; + if (!event.caicuolist) event.caicuolist = []; + targets[event.num].chooseBool("是否押杀?").ai = function (event, player) { + var evt = _status.event.getParent(); + if (get.attitude(targets[event.num], evt.player) > 0) + return evt.player.countCards("h", "sha") ? false : true; + return Math.random() < 0.5; }; - "step 2" - if(result.bool){ - targets[event.num].chat('有杀'); - game.log(targets[event.num],'认为',player,'#g有杀'); - if(!player.countCards('h','sha')) event.caicuolist.add(targets[event.num]); - }else{ - targets[event.num].chat('没杀'); - game.log(targets[event.num],'认为',player,'#y没有杀'); - if(player.countCards('h','sha')) event.caicuolist.add(targets[event.num]); + "step 2"; + if (result.bool) { + targets[event.num].chat("有杀"); + game.log(targets[event.num], "认为", player, "#g有杀"); + if (!player.countCards("h", "sha")) event.caicuolist.add(targets[event.num]); + } else { + targets[event.num].chat("没杀"); + game.log(targets[event.num], "认为", player, "#y没有杀"); + if (player.countCards("h", "sha")) event.caicuolist.add(targets[event.num]); } event.num++; game.delay(); - if(event.num0){ - if(target.getEquip('baiyin')&&target.isDamaged()&& - get.recoverEffect(target,player,player)>0){ - if(target.hp==1&&!target.hujia) return 1.6; - if(target.hp==2) return 0.01; + result: { + target: function (player, target) { + var raweffect = function (player, target) { + if (player.countCards("h", "sha")) { + return get.effect(target, { name: "sha" }, player, target); + } else { + var att = get.attitude(player, target); + var nh = target.countCards("h"); + if (att > 0) { + if ( + target.getEquip("baiyin") && + target.isDamaged() && + get.recoverEffect(target, player, player) > 0 + ) { + if (target.hp == 1 && !target.hujia) return 1.6; + if (target.hp == 2) return 0.01; return 0; } } - var es=target.getCards('e'); - var noe=(es.length==0||target.hasSkillTag('noe')); - var noe2=(es.length==1&&es[0].name=='baiyin'&&target.isDamaged()); - var noh=(nh==0||target.hasSkillTag('noh')); - if(noh&&(noe||noe2)) return 0; - if(att<=0&&!target.countCards('he')) return 1.5; + var es = target.getCards("e"); + var noe = es.length == 0 || target.hasSkillTag("noe"); + var noe2 = es.length == 1 && es[0].name == "baiyin" && target.isDamaged(); + var noh = nh == 0 || target.hasSkillTag("noh"); + if (noh && (noe || noe2)) return 0; + if (att <= 0 && !target.countCards("he")) return 1.5; return -1.5; } - } - var num=game.countPlayer(function(current){ - return current!=player&¤t.hp==target.hp&&(raweffect(player,current)*get.attitude(player,current))>0 + }; + var num = game.countPlayer(function (current) { + return ( + current != player && + current.hp == target.hp && + raweffect(player, current) * get.attitude(player, current) > 0 + ); }); - return raweffect(player,target)*Math.max(0,num-1); + return raweffect(player, target) * Math.max(0, num - 1); }, }, - expose:0.4, + expose: 0.4, }, }, - "jixu_sha":{ - audio:"xinfu_jixu", - trigger:{ - player:"useCard", + jixu_sha: { + audio: "xinfu_jixu", + trigger: { + player: "useCard", }, - onremove:function (player){ + onremove: function (player) { delete player.storage.jixu_sha; }, - filter:function (event,player){ - if(event.card.name=='sha'){ - return game.hasPlayer(function(current){ - return current!=player&&player.storage.jixu_sha.includes(current)&&!event.targets.includes(current); + filter: function (event, player) { + if (event.card.name == "sha") { + return game.hasPlayer(function (current) { + return ( + current != player && + player.storage.jixu_sha.includes(current) && + !event.targets.includes(current) + ); }); } return false; }, - forced:true, - silent:true, - popup:false, - content:function (){ + forced: true, + silent: true, + popup: false, + content: function () { player.logSkill("xinfu_jixu"); - for(var i=0;i2){ - if(card.name=='jiu') return 120; - if(card.name=='tao') return 110; - } - return 100-get.value(card); - }); - "step 2" - if(result.bool&&result.cards&&result.cards.length){ - event.current.give(result.cards,player); + xinfu_qiai: { + skillAnimation: true, + animationColor: "gray", + trigger: { player: "dying" }, + limited: true, + audio: 2, + content: function () { + "step 0"; + player.awakenSkill("xinfu_qiai"); + event.targets = game + .filterPlayer(function (current) { + return current != player; + }) + .sortBySeat(); + if (!event.targets.length) event.finish(); + "step 1"; + event.current = event.targets.shift(); + if (!event.current.countCards("he")) event.goto(3); + else + event.current + .chooseCard("交给" + get.translation(player) + "一张牌", "he", true) + .set("ai", function (card) { + var evt = _status.event.getParent(); + if (get.attitude(_status.event.player, evt.player) > 2) { + if (card.name == "jiu") return 120; + if (card.name == "tao") return 110; + } + return 100 - get.value(card); + }); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + event.current.give(result.cards, player); } - "step 3" - if(event.targets.length>0) event.goto(1); + "step 3"; + if (event.targets.length > 0) event.goto(1); }, }, - "xinfu_denglou":{ - audio:2, - trigger:{ - player:"phaseJieshuBegin", + xinfu_denglou: { + audio: 2, + trigger: { + player: "phaseJieshuBegin", }, - limited:true, - filter:function (event,player){ - return player.countCards('h')==0; + limited: true, + filter: function (event, player) { + return player.countCards("h") == 0; }, - skillAnimation:true, - animationColor:'gray', - content:function (){ - "step 0" - player.awakenSkill('xinfu_denglou'); - event.cards=get.cards(4); - event.gains=[] - event.discards=[] - var content=['牌堆顶的四张牌',event.cards]; - game.log(player,'观看了','#y牌堆顶的四张牌'); - player.chooseControl('ok').set('dialog',content); - "step 1" - if(get.type(event.cards[0])!="basic"){ + skillAnimation: true, + animationColor: "gray", + content: function () { + "step 0"; + player.awakenSkill("xinfu_denglou"); + event.cards = get.cards(4); + event.gains = []; + event.discards = []; + var content = ["牌堆顶的四张牌", event.cards]; + game.log(player, "观看了", "#y牌堆顶的四张牌"); + player.chooseControl("ok").set("dialog", content); + "step 1"; + if (get.type(event.cards[0]) != "basic") { event.gains.push(event.cards[0]); event.cards.remove(event.cards[0]); - } - else{ - var bool=game.hasPlayer(function(current){ - return player.canUse(event.cards[0],current); + } else { + var bool = game.hasPlayer(function (current) { + return player.canUse(event.cards[0], current); }); - if(bool){ - player.chooseUseTarget(event.cards[0],true,false); - } - else event.discards.push(event.cards[0]); + if (bool) { + player.chooseUseTarget(event.cards[0], true, false); + } else event.discards.push(event.cards[0]); event.cards.remove(event.cards[0]); } - "step 2" - if(event.cards.length) event.goto(1); - else{ - if(event.gains.length) player.gain(event.gains,'gain2'); - if(event.discards.length){ + "step 2"; + if (event.cards.length) event.goto(1); + else { + if (event.gains.length) player.gain(event.gains, "gain2"); + if (event.discards.length) { player.$throw(event.discards); game.cardsDiscard(event.discards); } } }, }, - qinguo_use:{audio:2}, - "xinfu_qinguo":{ - group:"xinfu_qinguo_recover", - audio:'qinguo_use', - subfrequent:['recover'], - trigger:{ - player:"useCardEnd", + qinguo_use: { audio: 2 }, + xinfu_qinguo: { + group: "xinfu_qinguo_recover", + audio: "qinguo_use", + subfrequent: ["recover"], + trigger: { + player: "useCardEnd", }, - filter:function (event,player){ - return get.type(event.card)=='equip'; + filter: function (event, player) { + return get.type(event.card) == "equip"; }, - direct:true, - content:function(){ - player.chooseUseTarget({name:'sha'},get.prompt('xinfu_qinguo'),'视为使用一张【杀】',false).logSkill='xinfu_qinguo'; + direct: true, + content: function () { + player.chooseUseTarget( + { name: "sha" }, + get.prompt("xinfu_qinguo"), + "视为使用一张【杀】", + false + ).logSkill = "xinfu_qinguo"; }, - subSkill:{ - recover:{ - audio:'qinguo_use', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + subSkill: { + recover: { + audio: "qinguo_use", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - prompt:'是否发动【勤国】回复1点体力?', - filter:function (event,player){ - if(player.isHealthy()||player.countCards('e')!=player.hp) return false; - var evt=event.getl(player); - if(event.name=='equip'&&event.player==player) return !evt||evt.cards.length!=1; - return evt&&evt.es.length; + prompt: "是否发动【勤国】回复1点体力?", + filter: function (event, player) { + if (player.isHealthy() || player.countCards("e") != player.hp) return false; + var evt = event.getl(player); + if (event.name == "equip" && event.player == player) + return !evt || evt.cards.length != 1; + return evt && evt.es.length; }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.recover(); }, }, }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')&&game.hasPlayer(function(current){ - return target.canUse('sha',current); - })) return [1,1.5]; - } - }, - noe:true, - reverseEquip:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='noe') return player.countCards('e')==player.hp+1; - return game.hasPlayer(function(current){ - return player.canUse('sha',current); - }); - } - } - }, - xinfu_jijun:{ - ai:{ - reverseEquip:true, - effect:{ - target:function (card,player,target,current){ - if(get.type(card)=='equip'&&player==target&&player==_status.currentPhase&&get.subtype(card)=='equip1') return [1,3]; + ai: { + effect: { + target: function (card, player, target, current) { + if ( + get.type(card) == "equip" && + !get.cardtag(card, "gifts") && + game.hasPlayer(function (current) { + return target.canUse("sha", current); + }) + ) + return [1, 1.5]; }, }, + noe: true, + reverseEquip: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "noe") return player.countCards("e") == player.hp + 1; + return game.hasPlayer(function (current) { + return player.canUse("sha", current); + }); + }, }, - audio:2, - trigger:{ - player:"useCardToPlayered", + }, + xinfu_jijun: { + ai: { + reverseEquip: true, + effect: { + target: function (card, player, target, current) { + if ( + get.type(card) == "equip" && + player == target && + player == _status.currentPhase && + get.subtype(card) == "equip1" + ) + return [1, 3]; + }, + }, + combo: "xinfu_fangtong", }, - frequent:true, - filter:function (event,player){ - if(player!=_status.currentPhase) return false; - if(event.getParent().triggeredTargets3.length>1) return false; - if(get.type(event.card)=='equip'&&get.subtype(event.card)!='equip1') return false; - if(event.targets.includes(player)) return true; + audio: 2, + trigger: { + player: "useCardToPlayered", + }, + frequent: true, + filter: function (event, player) { + if (player != _status.currentPhase) return false; + if (event.getParent().triggeredTargets3.length > 1) return false; + if (get.type(event.card) == "equip" && get.subtype(event.card) != "equip1") return false; + if (event.targets.includes(player)) return true; return false; }, - callback:function(){ - player.addToExpansion(card,'gain2').gaintag.add('xinfu_jijun'); + callback: function () { + player.addToExpansion(card, "gain2").gaintag.add("xinfu_jijun"); }, - content:function (){ - player.judge(function(card){ + content: function () { + player.judge(function (card) { return 1; - }).callback=lib.skill.xinfu_jijun.callback; + }).callback = lib.skill.xinfu_jijun.callback; }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', - mark:function(dialog,content,player){ - var content=player.getExpansions('xinfu_jijun'); - if(content&&content.length){ + intro: { + content: "expansion", + markcount: "expansion", + mark: function (dialog, content, player) { + var content = player.getExpansions("xinfu_jijun"); + if (content && content.length) { dialog.addAuto(content); - if(player==game.me||player.isUnderControl()){ - var list=lib.skill.xinfu_fangtong.getAuto(player); - if(list.length>0){ - dialog.addText('
            • 推荐方案:'+get.translation(list[0])+'+ '+get.translation(list.slice(1))); + if (player == game.me || player.isUnderControl()) { + var list = lib.skill.xinfu_fangtong.getAuto(player); + if (list.length > 0) { + dialog.addText( + "
            • 推荐方案:" + + get.translation(list[0]) + + "+ " + + get.translation(list.slice(1)) + ); } } } }, }, - marktext:"方", + marktext: "方", }, - xinfu_fangtong:{ - getAuto:function(player){ - var hs=player.getCards('he'); - var ss=player.getExpansions('xinfu_jijun'); - var bool=false,max=Math.pow(2,ss.length),index,i; - for(i=0;i0&&player.getExpansions('xinfu_jijun').length>0; + filter: function (event, player) { + return player.countCards("he") > 0 && player.getExpansions("xinfu_jijun").length > 0; }, - direct:true, - skillAnimation:true, - animationColor:'metal', - content:function (){ - 'step 0' - var info=['是否发动【方统】?']; - info.push('
              '+get.translation(player)+'的“方”
              '); - info.push(player.getExpansions('xinfu_jijun')); - if(player.countCards('h')){ - info.push('
              '+get.translation(player)+'的手牌区
              '); - info.push(player.getCards('h')); + direct: true, + skillAnimation: true, + animationColor: "metal", + content: function () { + "step 0"; + var info = ["是否发动【方统】?"]; + info.push('
              ' + get.translation(player) + "的“方”
              "); + info.push(player.getExpansions("xinfu_jijun")); + if (player.countCards("h")) { + info.push('
              ' + get.translation(player) + "的手牌区
              "); + info.push(player.getCards("h")); } - if(player.countCards('e')){ - info.push('
              '+get.translation(player)+'的装备区
              '); - info.push(player.getCards('e')); + if (player.countCards("e")) { + info.push('
              ' + get.translation(player) + "的装备区
              "); + info.push(player.getCards("e")); } - var next=player.chooseButton(); - next.set('createDialog',info); - next.set('selectButton',function(){ - var num=0; - for(var i=0;i0){ + next.set("autolist", lib.skill.xinfu_fangtong.getAuto(player)); + next.set("processAI", function () { + if (_status.event.autolist && _status.event.autolist.length > 0) { return { - bool:true, - links:_status.event.autolist, - } + bool: true, + links: _status.event.autolist, + }; } - return {bool:false}; + return { bool: false }; }); - next.set('complexSelect',true); - 'step 1' - if(result.bool){ - player.logSkill('xinfu_fangtong'); - var tothrow=[]; - var cards=result.links.slice(0); - for(var i=0;i=0; + check: function (event, player) { + return get.effect(event.source, { name: "losehp" }, player, player) >= 0; }, - forced:true, - logTarget:"source", - content:function(){ - player.addTempSkill('xinfu_weilu_effect',{player:'die'}); - player.markAuto('xinfu_weilu_effect',[trigger.source]); + forced: true, + logTarget: "source", + content: function () { + player.addTempSkill("xinfu_weilu_effect", { player: "die" }); + player.markAuto("xinfu_weilu_effect", [trigger.source]); game.delayx(); }, - ai:{ - maixie_defend:true, - threaten:0.85, - effect:{ - target:function (card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; + ai: { + maixie_defend: true, + threaten: 0.85, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; return 0.9; }, }, }, - subSkill:{ - effect:{ - audio:'xinfu_weilu', - trigger:{player:'phaseUseBegin'}, - charlotte:true, - forced:true, - logTarget:function(event,player){ - return player.getStorage('xinfu_weilu_effect').filter(function(current){ - return current.isIn()&¤t.hp>1; + subSkill: { + effect: { + audio: "xinfu_weilu", + trigger: { player: "phaseUseBegin" }, + charlotte: true, + forced: true, + logTarget: function (event, player) { + return player.getStorage("xinfu_weilu_effect").filter(function (current) { + return current.isIn() && current.hp > 1; }); }, - content:function(){ - 'step 0' - var targets=player.getStorage('xinfu_weilu_effect'); - player.removeSkill('xinfu_weilu_effect'); - event.targets=targets.sortBySeat(); - 'step 1' - var target=targets.shift(); - if(target.isIn()&&target.hp>1){ - event._delay=true; - var num=target.hp-1; - player.markAuto('xinfu_weilu_recover',[[target,num]]); + content: function () { + "step 0"; + var targets = player.getStorage("xinfu_weilu_effect"); + player.removeSkill("xinfu_weilu_effect"); + event.targets = targets.sortBySeat(); + "step 1"; + var target = targets.shift(); + if (target.isIn() && target.hp > 1) { + event._delay = true; + var num = target.hp - 1; + player.markAuto("xinfu_weilu_recover", [[target, num]]); target.loseHp(num); } - if(targets.length>0) event.redo(); - else if(!event._delay) event.finish(); - 'step 2' - player.addTempSkill('xinfu_weilu_recover',{player:['phaseUseAfter','phaseAfter']}); + if (targets.length > 0) event.redo(); + else if (!event._delay) event.finish(); + "step 2"; + player.addTempSkill("xinfu_weilu_recover", { + player: ["phaseUseAfter", "phaseAfter"], + }); game.delayx(); }, - onremove:true, - intro:{content:'已将$列入“威虏”战略打击目标'}, + onremove: true, + intro: { content: "已将$列入“威虏”战略打击目标" }, }, - recover:{ - audio:'xinfu_weilu', - charlotte:true, - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - var targets=player.getStorage('xinfu_weilu_recover'); - for(var i of targets){ - if(i[0].isIn()&&i[0].isDamaged()) return true; + recover: { + audio: "xinfu_weilu", + charlotte: true, + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + var targets = player.getStorage("xinfu_weilu_recover"); + for (var i of targets) { + if (i[0].isIn() && i[0].isDamaged()) return true; } return false; }, - onremove:true, - logTarget:function(event,player){ - var logs=[],targets=player.getStorage('xinfu_weilu_recover'); - for(var i of targets){ - if(i[0].isIn()&&i[0].isDamaged()) logs.add(i[0]); + onremove: true, + logTarget: function (event, player) { + var logs = [], + targets = player.getStorage("xinfu_weilu_recover"); + for (var i of targets) { + if (i[0].isIn() && i[0].isDamaged()) logs.add(i[0]); } return logs; }, - content:function(){ - 'step 0' - event.list=player.getStorage('xinfu_weilu_recover').slice(0); - event.list.sort(function(a,b){ - return lib.sort.seat(a[0],b[0]); + content: function () { + "step 0"; + event.list = player.getStorage("xinfu_weilu_recover").slice(0); + event.list.sort(function (a, b) { + return lib.sort.seat(a[0], b[0]); }); - 'step 1' - var group=event.list.shift(); - if(group[0].isIn()&&group[0].isDamaged()){ + "step 1"; + var group = event.list.shift(); + if (group[0].isIn() && group[0].isDamaged()) { group[0].recover(group[1]); - event._delay=true; + event._delay = true; } - if(event.list.length>0) event.redo(); - else if(!event._delay) event.finish(); - 'step 2' + if (event.list.length > 0) event.redo(); + else if (!event._delay) event.finish(); + "step 2"; game.delayx(); }, }, }, }, - xinfu_zengdao:{ - audio:2, - limited:true, - enable:"phaseUse", - filter:function(event,player){ - return player.countCards('e')>0; + xinfu_zengdao: { + audio: 2, + limited: true, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("e") > 0; }, - filterTarget:lib.filter.notMe, - skillAnimation:true, - animationColor:'thunder', - position:"e", - filterCard:true, - selectCard:[1,Infinity], - discard:false, - lose:false, - content:function(){ - player.awakenSkill('xinfu_zengdao'); - target.addToExpansion(cards,player,'give').gaintag.add('xinfu_zengdao2'); - target.addSkill('xinfu_zengdao2'); + filterTarget: lib.filter.notMe, + skillAnimation: true, + animationColor: "thunder", + position: "e", + filterCard: true, + selectCard: [1, Infinity], + discard: false, + lose: false, + content: function () { + player.awakenSkill("xinfu_zengdao"); + target.addToExpansion(cards, player, "give").gaintag.add("xinfu_zengdao2"); + target.addSkill("xinfu_zengdao2"); }, - ai:{ - order:function(){ - var player=_status.event.player,num=0; - if(player.hasCard((card)=>get.value(card,player)<0,'e')) return 9; - for(var i=1;i<6;i++){ - num+=player.countEquipableSlot(i); + ai: { + order: function () { + var player = _status.event.player, + num = 0; + if (player.hasCard((card) => get.value(card, player) < 0, "e")) return 9; + for (var i = 1; i < 6; i++) { + num += player.countEquipableSlot(i); } - if(num<=2) return 9; - var targets=player.getStorage('xinfu_weilu_recover'),num=0; - if(player.hp<=2||!game.hasPlayer((current)=>{ - if(player==current||get.attitude(player,current)<0||current.hp<=1) return false; - for(var arr of targets){ - if(current==arr[0]) break; - } - return current.hp>2||current.countCards('hs')>2; - })) return 1; + if (num <= 2) return 9; + var targets = player.getStorage("xinfu_weilu_recover"), + num = 0; + if ( + player.hp <= 2 || + !game.hasPlayer((current) => { + if (player == current || get.attitude(player, current) < 0 || current.hp <= 1) + return false; + for (var arr of targets) { + if (current == arr[0]) break; + } + return current.hp > 2 || current.countCards("hs") > 2; + }) + ) + return 1; return 0; }, - result:{ - target:function(player,target){ - if(target.hasValueTarget({name:'sha',isCard:true})) return ui.selected.cards.length; + result: { + target: function (player, target) { + if (target.hasValueTarget({ name: "sha", isCard: true })) + return ui.selected.cards.length; return 0; - } - } - } - }, - xinfu_zengdao2:{ - trigger:{source:'damageBegin1'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('xinfu_zengdao2').length>0; + }, + }, }, - content:function(){ - 'step 0' - player.chooseCardButton('将一张“刀”置入弃牌堆',player.getExpansions('xinfu_zengdao2'),true); - 'step 1' - if(result.bool){ + }, + xinfu_zengdao2: { + trigger: { source: "damageBegin1" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("xinfu_zengdao2").length > 0; + }, + content: function () { + "step 0"; + player.chooseCardButton( + "将一张“刀”置入弃牌堆", + player.getExpansions("xinfu_zengdao2"), + true + ); + "step 1"; + if (result.bool) { trigger.num++; player.loseToDiscardpile(result.links); } }, - marktext:"刀", - intro:{ - content:'expansion', - markcount:'expansion', - onunmark:function(storage,player){ - player.removeSkill('xinfu_zengdao2'); + marktext: "刀", + intro: { + content: "expansion", + markcount: "expansion", + onunmark: function (storage, player) { + player.removeSkill("xinfu_zengdao2"); }, }, }, - xinfu_guanwei:{ - audio:2, - usable:1, - init:()=>{ - game.addGlobalSkill('xinfu_guanwei_ai'); + xinfu_guanwei: { + audio: 2, + usable: 1, + init: () => { + game.addGlobalSkill("xinfu_guanwei_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('xinfu_guanwei'),true)) game.removeGlobalSkill('xinfu_guanwei_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("xinfu_guanwei"), true)) + game.removeGlobalSkill("xinfu_guanwei_ai"); }, - trigger:{ - global:"phaseUseEnd", + trigger: { + global: "phaseUseEnd", }, - filter:function (event,player){ - var history=event.player.getHistory('useCard'); - var num=0; - var suit=false; - for(var i=0;i1; + return num > 1; }, - direct:true, - content:function (){ - 'step 0' - var target=trigger.player; - player.chooseToDiscard('he',get.prompt('xinfu_guanwei',trigger.player),'弃置一张牌,令其摸两张牌并进行一个额外的出牌阶段。').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.targetx)<1) return 0; - return 9-get.value(card); - }).set('logSkill',['xinfu_guanwei',target]).set('targetx',target); - 'step 1' - if(result.bool){ - player.line(trigger.player,'green'); + direct: true, + content: function () { + "step 0"; + var target = trigger.player; + player + .chooseToDiscard( + "he", + get.prompt("xinfu_guanwei", trigger.player), + "弃置一张牌,令其摸两张牌并进行一个额外的出牌阶段。" + ) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.targetx) < 1) return 0; + return 9 - get.value(card); + }) + .set("logSkill", ["xinfu_guanwei", target]) + .set("targetx", target); + "step 1"; + if (result.bool) { + player.line(trigger.player, "green"); trigger.player.draw(2); - } - else{ + } else { player.storage.counttrigger.xinfu_guanwei--; event.finish(); } - 'step 2' - var next=trigger.player.phaseUse(); + "step 2"; + var next = trigger.player.phaseUse(); event.next.remove(next); - trigger.getParent('phase').next.push(next); + trigger.getParent("phase").next.push(next); }, - ai:{ - expose:0.5, + ai: { + expose: 0.5, }, - subSkill:{ - ai:{ - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('xinfu_guanwei'),true); + subSkill: { + ai: { + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("xinfu_guanwei"), true); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('xinfu_guanwei_ai'); + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("xinfu_guanwei_ai"); }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card!='object'||!player.isPhaseUsing()) return; - var hasPanjun=game.hasPlayer(function(current){ - return current.hasSkill('xinfu_guanwei')&&(!current.storage.counttrigger||!current.storage.counttrigger.xinfu_guanwei)&& - get.attitude(current,player)>=1&¤t.hasCard(function(card){ - return get.value(card)<7||(current!=game.me&&!current.isUnderControl()&&!current.isOnline())&&get.value(card)<9; - },'he'); + ai: { + effect: { + player_use: function (card, player, target) { + if (typeof card != "object" || !player.isPhaseUsing()) return; + var hasPanjun = game.hasPlayer(function (current) { + return ( + current.hasSkill("xinfu_guanwei") && + (!current.storage.counttrigger || + !current.storage.counttrigger.xinfu_guanwei) && + get.attitude(current, player) >= 1 && + current.hasCard(function (card) { + return ( + get.value(card) < 7 || + (current != game.me && + !current.isUnderControl() && + !current.isOnline() && + get.value(card) < 9) + ); + }, "he") + ); }); - if(!hasPanjun) return; - var suitx=get.suit(card); - var history=player.getHistory('useCard'); - if(!history.length){ - var val=0; - if(player.hasCard(function(cardx){ - return get.suit(cardx)==suitx&&card!=cardx&&(!card.cards||!card.cards.includes(cardx))&&player.hasValueTarget(cardx); - },'hs')) val=[2,0.1]; - if(val) return val; + if (!hasPanjun) return; + var suitx = get.suit(card); + var history = player.getHistory("useCard"); + if (!history.length) { + var val = 0; + if ( + player.hasCard(function (cardx) { + return ( + get.suit(cardx) == suitx && + card != cardx && + (!card.cards || !card.cards.includes(cardx)) && + player.hasValueTarget(cardx) + ); + }, "hs") + ) + val = [2, 0.1]; + if (val) return val; return; } - var num=0; - var suit=false; - for(var i=0;i1||num<=1&&player.hasCard(function(cardx){ - return get.suit(cardx)==suit&&player.hasValueTarget(cardx); - },'hs'))) return 'zeroplayertarget'; + if (suitx == suit && num == 1) return [1, 0.1]; + if ( + suitx != suit && + (num > 1 || + (num <= 1 && + player.hasCard(function (cardx) { + return ( + get.suit(cardx) == suit && + player.hasValueTarget(cardx) + ); + }, "hs"))) + ) + return "zeroplayertarget"; }, }, }, - } + }, }, }, - xinfu_gongqing_gz_panjun:{audio:2}, - "xinfu_gongqing":{ - audio:2, - audioname2:{gz_panjun:'xinfu_gongqing_gz_panjun'}, - trigger:{ - player:["damageBegin3","damageBegin4"], + xinfu_gongqing_gz_panjun: { audio: 2 }, + xinfu_gongqing: { + audio: 2, + audioname2: { gz_panjun: "xinfu_gongqing_gz_panjun" }, + trigger: { + player: ["damageBegin3", "damageBegin4"], }, - forced:true, - filter:function (event,player,name){ - if(!event.source) return false; - var range=event.source.getAttackRange(); - if(name=='damageBegin3') return range>3; - return event.num>1&&range<3; + forced: true, + filter: function (event, player, name) { + if (!event.source) return false; + var range = event.source.getAttackRange(); + if (name == "damageBegin3") return range > 3; + return event.num > 1 && range < 3; }, - preHidden:true, - content:function (){ - trigger.num=event.triggername=='damageBegin4'?1:trigger.num+1; + preHidden: true, + content: function () { + trigger.num = event.triggername == "damageBegin4" ? 1 : trigger.num + 1; }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; - if(arg.player.getAttackRange()<3) return true; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; + if (arg.player.getAttackRange() < 3) return true; } return false; - } + }, }, }, - "xinfu_andong":{ - subSkill:{ - add:{ - sub:true, - mod:{ - ignoredHandcard:function (card,player){ - if(get.suit(card)=='heart'){ + xinfu_andong: { + subSkill: { + add: { + sub: true, + mod: { + ignoredHandcard: function (card, player) { + if (get.suit(card) == "heart") { return true; } }, - cardDiscardable:function (card,player,name){ - if(name=='phaseDiscard'&&get.suit(card)=='heart') return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.suit(card) == "heart") return false; }, }, }, }, - audio:2, - trigger:{ - player:"damageBegin4", + audio: 2, + trigger: { + player: "damageBegin4", }, - filter:function (event,player){ - return get.itemtype(event.source)=='player'; + filter: function (event, player) { + return get.itemtype(event.source) == "player"; }, - logTarget:"source", - content:function (){ - "step 0" - if(!trigger.source.countCards('h')) event._result={index:1}; - else trigger.source.chooseControlList( - ['令'+get.translation(player)+'观看你的手牌,并获得其中所有的红桃牌。', - '防止即将对'+get.translation(player)+'造成的伤害,并使自己本回合内的红桃手牌不计入手牌上限。'], - true).set('ai',function(event,player){ - var target=_status.event.getParent().player; - var player=_status.event.player; - if(get.attitude(player,target)>0) return 1; - return 0; - }); - "step 1" - if(result.index==1){ + logTarget: "source", + content: function () { + "step 0"; + if (!trigger.source.countCards("h")) event._result = { index: 1 }; + else + trigger.source + .chooseControlList( + [ + "令" + get.translation(player) + "观看你的手牌,并获得其中所有的红桃牌。", + "防止即将对" + + get.translation(player) + + "造成的伤害,并使自己本回合内的红桃手牌不计入手牌上限。", + ], + true + ) + .set("ai", function (event, player) { + var target = _status.event.getParent().player; + var player = _status.event.player; + if (get.attitude(player, target) > 0) return 1; + return 0; + }); + "step 1"; + if (result.index == 1) { trigger.cancel(); - trigger.source.addTempSkill('xinfu_andong_add'); + trigger.source.addTempSkill("xinfu_andong_add"); event.finish(); - }else{ + } else { player.viewHandcards(trigger.source); } - "step 2" - var cards=trigger.source.getCards('h'); - var togain=[] - for(var i=0;i0&&!game.hasPlayer(function(current){ - return current.hasSkill('yingshi_heart'); - }); + direct: true, + filter: function (event, player) { + return ( + player.countCards("he", { suit: "heart" }) > 0 && + !game.hasPlayer(function (current) { + return current.hasSkill("yingshi_heart"); + }) + ); }, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt2('xinfu_yingshi'),function(card,player,target){ - return target!=player; - }).set('ai',function(){ - return -1; - }); - 'step 1' - if(result.bool){ - var cards=player.getCards('he',{suit:'heart'}); - var target=result.targets[0]; - player.logSkill('xinfu_yingshi',target); - target.addSkill('yingshi_heart'); - target.addToExpansion(cards,player,'give').gaintag.add('xinfu_yingshi'); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("xinfu_yingshi"), function (card, player, target) { + return target != player; + }) + .set("ai", function () { + return -1; + }); + "step 1"; + if (result.bool) { + var cards = player.getCards("he", { suit: "heart" }); + var target = result.targets[0]; + player.logSkill("xinfu_yingshi", target); + target.addSkill("yingshi_heart"); + target.addToExpansion(cards, player, "give").gaintag.add("xinfu_yingshi"); } }, - marktext:'酬', - intro:{ - markcount:'expansion', - content:'expansion', - onunmark:function(storage,player){ - player.removeSkill('yingshi_heart'); + marktext: "酬", + intro: { + markcount: "expansion", + content: "expansion", + onunmark: function (storage, player) { + player.removeSkill("yingshi_heart"); }, - } - }, - yingshi_heart:{ - charlotte:true, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn() - &&event.card&&event.card.name=='sha' - &&player.getExpansions('xinfu_yingshi').length>0; }, - forced:true, - logTarget:'source', - content:function(){ - 'step 0' - trigger.source.chooseCardButton('应势:选择获得一张“酬”',player.getExpansions('xinfu_yingshi'),true); - 'step 1' - if(result.bool){ - trigger.source.gain(result.links,player,'give'); + }, + yingshi_heart: { + charlotte: true, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.card && + event.card.name == "sha" && + player.getExpansions("xinfu_yingshi").length > 0 + ); + }, + forced: true, + logTarget: "source", + content: function () { + "step 0"; + trigger.source.chooseCardButton( + "应势:选择获得一张“酬”", + player.getExpansions("xinfu_yingshi"), + true + ); + "step 1"; + if (result.bool) { + trigger.source.gain(result.links, player, "give"); } }, }, - yingshi_die:{ - audio:'xinfu_yingshi', - forced:true, - trigger:{global:'die'}, - logTarget:'player', - filter:function(event,player){ - return event.player.getExpansions('xinfu_yingshi').length>0; + yingshi_die: { + audio: "xinfu_yingshi", + forced: true, + trigger: { global: "die" }, + logTarget: "player", + filter: function (event, player) { + return event.player.getExpansions("xinfu_yingshi").length > 0; }, - content:function(){ - var target=trigger.player; - player.gain(target.getExpansions('xinfu_yingshi'),target,'give','bySelf'); + content: function () { + var target = trigger.player; + player.gain(target.getExpansions("xinfu_yingshi"), target, "give", "bySelf"); }, }, - "xinfu_duanfa":{ - init:function (player){ - player.storage.xinfu_duanfa=0; + xinfu_duanfa: { + init: function (player) { + player.storage.xinfu_duanfa = 0; }, - audio:2, - enable:"phaseUse", - position:"he", - filter:function (card,player){ - return player.storage.xinfu_duanfa0; + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function (){ - "step 0" - player.chooseTarget(get.prompt2('xinfu_youdi'),function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - var player=_status.event.player; - if(player.countCards('h','sha')>player.countCards('h')/3&&player.countCards('h',{color:'red'})>player.countCards('h')/2) return 0; - if(target.countCards('he')==0) return 0.1; - return -get.attitude(_status.event.player,target); - }); - "step 1" - if(result.bool){ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("xinfu_youdi"), function (card, player, target) { + return player != target; + }) + .set("ai", function (target) { + var player = _status.event.player; + if ( + player.countCards("h", "sha") > player.countCards("h") / 3 && + player.countCards("h", { color: "red" }) > player.countCards("h") / 2 + ) + return 0; + if (target.countCards("he") == 0) return 0.1; + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { game.delay(); - player.logSkill('xinfu_youdi',result.targets); - event.target=result.targets[0]; - event.target.discardPlayerCard(player,'h',true); - } - else{ + player.logSkill("xinfu_youdi", result.targets); + event.target = result.targets[0]; + event.target.discardPlayerCard(player, "h", true); + } else { event.finish(); } - "step 2" - if(get.color(result.links[0])!='black') player.draw('nodelay'); - if(result.links[0].name!='sha'&&event.target.countCards('he')){ - player.gainPlayerCard('he',event.target,true); + "step 2"; + if (get.color(result.links[0]) != "black") player.draw("nodelay"); + if (result.links[0].name != "sha" && event.target.countCards("he")) { + player.gainPlayerCard("he", event.target, true); } }, - ai:{ - expose:0.3, - threaten:1.4, + ai: { + expose: 0.3, + threaten: 1.4, }, }, - "xinfu_guanchao":{ - subSkill:{ - dizeng:{ - mark:true, - marktext:"增", - intro:{ - content:"单调递增", + xinfu_guanchao: { + subSkill: { + dizeng: { + mark: true, + marktext: "增", + intro: { + content: "单调递增", }, - trigger:{ - player:"useCard", + trigger: { + player: "useCard", }, - audio:"xinfu_guanchao", - forced:true, - mod:{ - aiOrder:function(player,card,num){ - if(typeof card.number!='number') return; - var history=player.getHistory('useCard',function(evt){ + audio: "xinfu_guanchao", + forced: true, + mod: { + aiOrder: function (player, card, num) { + if (typeof card.number != "number") return; + var history = player.getHistory("useCard", function (evt) { return evt.isPhaseUsing(); }); - if(history.length==0) return num+10*(14-card.number); - var num=get.number(history[0].card); - if(!num) return; - for(var i=1;inum) return num+10*(14-card.number); + if (card.number > num) return num + 10 * (14 - card.number); }, }, - filter:function (event,player){ - var history=player.getHistory('useCard',function(evt){ + filter: function (event, player) { + var history = player.getHistory("useCard", function (evt) { return evt.isPhaseUsing(); }); - if(history.length<2) return false; - var num=get.number(history[0].card); - if(!num) return false; - for(var i=1;i=num) return; - num=num2; + if (history.length == 0) return num + 10 * card.number; + var num = get.number(history[0].card); + if (!num) return; + for (var i = 1; i < history.length; i++) { + var num2 = get.number(history[i].card); + if (!num2 || num2 >= num) return; + num = num2; } - if(card.number=num) return false; - num=num2; + if (history.length < 2) return false; + var num = get.number(history[0].card); + if (!num) return false; + for (var i = 1; i < history.length; i++) { + var num2 = get.number(history[i].card); + if (!num2 || num2 >= num) return false; + num = num2; } return true; }, - content:function (){ + content: function () { player.draw(); }, - sub:true, + sub: true, }, }, - audio:2, - trigger:{ - player:"phaseUseBegin", + audio: 2, + trigger: { + player: "phaseUseBegin", }, - direct:true, - content:function (){ - 'step 0' - var list=['递增','递减','取消']; - player.chooseControl(list).set('prompt',get.prompt2('xinfu_guanchao')).set('ai',function(){ - return [0,1].randomGet(); - }); - 'step 1' - switch(result.control){ - case '递增':{ - player.logSkill('xinfu_guanchao'); - player.addTempSkill('xinfu_guanchao_dizeng','phaseUseEnd'); + direct: true, + content: function () { + "step 0"; + var list = ["递增", "递减", "取消"]; + player + .chooseControl(list) + .set("prompt", get.prompt2("xinfu_guanchao")) + .set("ai", function () { + return [0, 1].randomGet(); + }); + "step 1"; + switch (result.control) { + case "递增": { + player.logSkill("xinfu_guanchao"); + player.addTempSkill("xinfu_guanchao_dizeng", "phaseUseEnd"); break; } - case '递减':{ - player.logSkill('xinfu_guanchao'); - player.addTempSkill('xinfu_guanchao_dijian','phaseUseEnd'); + case "递减": { + player.logSkill("xinfu_guanchao"); + player.addTempSkill("xinfu_guanchao_dijian", "phaseUseEnd"); break; } - case '取消':{ + case "取消": { break; } } }, }, - "xinfu_xunxian":{ - usable:1, - audio:2, - trigger:{ - player:["useCardAfter","respond"], + xinfu_xunxian: { + usable: 1, + audio: 2, + trigger: { + player: ["useCardAfter", "respond"], }, - filter:function (event,player){ - if(get.itemtype(event.cards)!=='cards'||!game.hasPlayer(current=>{ - if(current===player) return false; - return current.getHp()>player.getHp()||current.countCards('h')>player.countCards('h'); - })) return false; - for(var i=0;i { + if (current === player) return false; + return ( + current.getHp() > player.getHp() || + current.countCards("h") > player.countCards("h") + ); + }) + ) + return false; + for (var i = 0; i < event.cards.length; i++) { + if (event.cards[i].isInPile()) { return true; } } return false; }, - async cost(event, trigger, player){ - event.result = await player.chooseTarget(get.prompt2('xinfu_xunxian'),(card,player,target)=>{ - if(target===player) return false; - return target.getHp()>player.getHp()||target.countCards('h')>player.countCards('h'); - }).set('ai',(target)=>{ - let att=get.attitude(_status.event.player,target),name=_status.event.cards[0].name; - if(att<3) return 0; - if(target.hasJudge('lebu')) att/=5; - if(name==='sha'&&target.hasSha()) att/=5; - if(name==='wuxie'&&target.needsToDiscard(_status.event.cards)) att/=5; - return att/(1+get.distance(player,target,'absolute')); - }).set('cards',trigger.cards).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("xinfu_xunxian"), (card, player, target) => { + if (target === player) return false; + return ( + target.getHp() > player.getHp() || + target.countCards("h") > player.countCards("h") + ); + }) + .set("ai", (target) => { + let att = get.attitude(_status.event.player, target), + name = _status.event.cards[0].name; + if (att < 3) return 0; + if (target.hasJudge("lebu")) att /= 5; + if (name === "sha" && target.hasSha()) att /= 5; + if (name === "wuxie" && target.needsToDiscard(_status.event.cards)) att /= 5; + return att / (1 + get.distance(player, target, "absolute")); + }) + .set("cards", trigger.cards) + .forResult(); }, - async content(event, trigger, player){ - let list=[]; - for(let i=0;i=player.hp) return false; - return player.countCards('h')>0; + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("xinfu_kannan_phase")) return false; + if (player.getStat().skill.xinfu_kannan >= player.hp) return false; + return player.countCards("h") > 0; }, - filterTarget:function (card,player,target){ - if(target.hasSkill('xinfu_kannan_phase')) return false; + filterTarget: function (card, player, target) { + if (target.hasSkill("xinfu_kannan_phase")) return false; return player.canCompare(target); }, - ai:{ - order:function (){ - return get.order({name:'sha'})+0.4; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.4; }, - result:{ - target:function (player,target){ - if(player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=12; - } - if(val<=6){ - return card.number>=13; - } - return false; - })) return -1; + result: { + target: function (player, target) { + if ( + player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 12; + } + if (val <= 6) { + return card.number >= 13; + } + return false; + }) + ) + return -1; return 0; }, }, }, - content:function (){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - player.addTempSkill('xinfu_kannan_phase'); - if(!player.hasSkill('kannan_eff')){ - player.addSkill('kannan_eff'); - }else{ - if(!player.storage.kannan_eff) player.storage.kannan_eff=0; + "step 1"; + if (result.bool) { + player.addTempSkill("xinfu_kannan_phase"); + if (!player.hasSkill("kannan_eff")) { + player.addSkill("kannan_eff"); + } else { + if (!player.storage.kannan_eff) player.storage.kannan_eff = 0; } player.storage.kannan_eff++; - player.markSkill('kannan_eff'); - } - else{ - target.addTempSkill('xinfu_kannan_phase'); - if(!target.hasSkill('kannan_eff')){ - target.addSkill('kannan_eff'); - } - else{ - if(!target.storage.kannan_eff) player.storage.kannan_eff=0; + player.markSkill("kannan_eff"); + } else { + target.addTempSkill("xinfu_kannan_phase"); + if (!target.hasSkill("kannan_eff")) { + target.addSkill("kannan_eff"); + } else { + if (!target.storage.kannan_eff) player.storage.kannan_eff = 0; //target.storage.kannan_eff++; //target.markSkill('kannan_eff'); } target.storage.kannan_eff++; - target.markSkill('kannan_eff'); + target.markSkill("kannan_eff"); } }, }, - "kannan_eff":{ - mark:true, - intro:{ - content:"下一张杀的伤害基数+#", + kannan_eff: { + mark: true, + intro: { + content: "下一张杀的伤害基数+#", }, - trigger:{ - player:"useCard", + trigger: { + player: "useCard", }, - filter:function (event){ - return event.card&&event.card.name=='sha'; + filter: function (event) { + return event.card && event.card.name == "sha"; }, - forced:true, - content:function (){ - if(!trigger.baseDamage) trigger.baseDamage=1; - trigger.baseDamage+=player.storage.kannan_eff; - player.removeSkill('kannan_eff'); + forced: true, + content: function () { + if (!trigger.baseDamage) trigger.baseDamage = 1; + trigger.baseDamage += player.storage.kannan_eff; + player.removeSkill("kannan_eff"); }, - init:function (player){ - player.storage.kannan_eff=0; + init: function (player) { + player.storage.kannan_eff = 0; }, - onremove:function (player){ + onremove: function (player) { delete player.storage.kannan_eff; }, - ai:{ - damageBonus:true, + ai: { + damageBonus: true, }, }, - "xinfu_tushe":{ - audio:2, + xinfu_tushe: { + audio: 2, mod: { aiOrder(player, card, num) { - if (get.tag(card, 'multitarget')) { - if (player.countCards('h', { type: 'basic' })) return num / 10; + if (get.tag(card, "multitarget")) { + if (player.countCards("h", { type: "basic" })) return num / 10; return num * 10; } - if (get.type(card) === 'basic') return num + 10; + if (get.type(card) === "basic") return num + 10; }, aiValue(player, card, num) { - if (card.name === 'zhangba') { + if (card.name === "zhangba") { let fact = (n) => { - if (n > 1) return n * fact(n - 1); - return 1; - }, basic = 0; - return fact(Math.min(player.countCards('hs', i => { - if (get.tag(i, 'multitarget')) return 2; - if (!['shan', 'tao', 'jiu'].includes(card.name)) return 1; - basic++; - }) / (1 + basic), player.getCardUsable('sha'))); + if (n > 1) return n * fact(n - 1); + return 1; + }, + basic = 0; + return fact( + Math.min( + player.countCards("hs", (i) => { + if (get.tag(i, "multitarget")) return 2; + if (!["shan", "tao", "jiu"].includes(card.name)) return 1; + basic++; + }) / + (1 + basic), + player.getCardUsable("sha") + ) + ); } - if (['shan', 'tao', 'jiu'].includes(card.name)) { - if (player.getEquip('zhangba') && player.countCards('hs') > 1) return 0.01; + if (["shan", "tao", "jiu"].includes(card.name)) { + if (player.getEquip("zhangba") && player.countCards("hs") > 1) return 0.01; return num / 2; } - if (get.tag(card, 'multitarget')) return num + game.players.length; + if (get.tag(card, "multitarget")) return num + game.players.length; }, aiUseful(player, card, num) { - if (get.name(card, player) === 'shan') { - if (player.countCards('hs', i => { - if (card === i || card.cards && card.cards.includes(i)) return false; - return get.name(i, player) === 'shan'; - })) return -1; + if (get.name(card, player) === "shan") { + if ( + player.countCards("hs", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) return false; + return get.name(i, player) === "shan"; + }) + ) + return -1; return num / Math.pow(Math.max(1, player.hp), 2); } - } + }, }, - trigger:{ - player:"useCardToPlayered", + trigger: { + player: "useCardToPlayered", }, locked: false, - frequent:true, - filter:function (event,player){ - if(get.type(event.card)=='equip') return false; - if(event.getParent().triggeredTargets3.length>1) return false; - return event.targets.length>0&&!player.countCards('h',{type:'basic',}); + frequent: true, + filter: function (event, player) { + if (get.type(event.card) == "equip") return false; + if (event.getParent().triggeredTargets3.length > 1) return false; + return event.targets.length > 0 && !player.countCards("h", { type: "basic" }); }, - content:function (){ + content: function () { player.draw(trigger.targets.length); }, - ai:{ - presha:true, - pretao:true, - threaten:1.8, + ai: { + presha: true, + pretao: true, + threaten: 1.8, effect: { player(card, player, target) { - if (typeof card === 'object' && card.name !== 'shan' && get.type(card) !== 'equip' && !player.countCards('h', i => { - if (card === i || card.cards && card.cards.includes(i)) return false; - return get.type(i) === 'basic'; - })) { - let targets = [], evt = _status.event.getParent('useCard'); + if ( + typeof card === "object" && + card.name !== "shan" && + get.type(card) !== "equip" && + !player.countCards("h", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) return false; + return get.type(i) === "basic"; + }) + ) { + let targets = [], + evt = _status.event.getParent("useCard"); targets.addArray(ui.selected.targets); if (evt && evt.card == card) targets.addArray(evt.targets); if (targets.length) return [1, targets.length]; - if (get.tag(card, 'multitarget')) return [1, game.players.length - 1]; + if (get.tag(card, "multitarget")) return [1, game.players.length - 1]; return [1, 1]; } - } - } - } + }, + }, + }, }, - "xinfu_limu":{ - mod:{ - targetInRange:function (card,player,target){ - if(player.countCards('j')&&player.inRange(target)){ + xinfu_limu: { + mod: { + targetInRange: function (card, player, target) { + if (player.countCards("j") && player.inRange(target)) { return true; } }, - cardUsableTarget:function(card,player,target){ - if(player.countCards('j')&&player.inRange(target)) return true; + cardUsableTarget: function (card, player, target) { + if (player.countCards("j") && player.inRange(target)) return true; }, aiOrder(player, card, num) { - if (get.type(card, 'delay') && player.canUse(card, player) && player.canAddJudge(card)) return 15; - } + if ( + get.type(card, "delay") && + player.canUse(card, player) && + player.canAddJudge(card) + ) + return 15; + }, }, - locked:false, - audio:2, - enable:"phaseUse", - discard:false, - filter:function (event,player){ - if(player.hasJudge('lebu')) return false; - return player.countCards('hes',{suit:'diamond'})>0; + locked: false, + audio: 2, + enable: "phaseUse", + discard: false, + filter: function (event, player) { + if (player.hasJudge("lebu")) return false; + return player.countCards("hes", { suit: "diamond" }) > 0; }, - viewAs:{name:'lebu'}, + viewAs: { name: "lebu" }, //prepare:"throw", - position:"hes", - filterCard:function(card,player,event){ - return get.suit(card)=='diamond'&&player.canAddJudge({name:'lebu',cards:[card]}); + position: "hes", + filterCard: function (card, player, event) { + return get.suit(card) == "diamond" && player.canAddJudge({ name: "lebu", cards: [card] }); }, - selectTarget:-1, - filterTarget:function (card,player,target){ - return player==target; + selectTarget: -1, + filterTarget: function (card, player, target) { + return player == target; }, check(card) { var player = _status.event.player; - if (!player.getEquip('zhangba')) { + if (!player.getEquip("zhangba")) { let damaged = player.maxHp - player.hp - 1; - if (player.countCards('h', function (cardx) { - if (cardx == card) return false; - if (cardx.name == 'tao') { - if (damaged < 1) return true; - damaged--; - } - return ['shan', 'jiu'].includes(cardx.name); - }) > 0) return 0; + if ( + player.countCards("h", function (cardx) { + if (cardx == card) return false; + if (cardx.name == "tao") { + if (damaged < 1) return true; + damaged--; + } + return ["shan", "jiu"].includes(cardx.name); + }) > 0 + ) + return 0; } - if (card.name == 'shan') return 15; - if (card.name == 'tao' || card.name == 'jiu') return 10; + if (card.name == "shan") return 15; + if (card.name == "tao" || card.name == "jiu") return 10; return 9 - get.value(card); }, - onuse:function (links,player){ - var next=game.createEvent('limu_recover',false,_status.event.getParent()); - next.player=player; - next.setContent(function(){player.recover()}); + onuse: function (links, player) { + var next = game.createEvent("limu_recover", false, _status.event.getParent()); + next.player = player; + next.setContent(function () { + player.recover(); + }); }, - ai:{ + ai: { result: { target(player, target) { let res = lib.card.lebu.ai.result.target(player, target); - if (target.isDamaged()) return res + 2 * Math.abs(get.recoverEffect(target, player, target)); + if (target.isDamaged()) + return res + 2 * Math.abs(get.recoverEffect(target, player, target)); return res; }, - ignoreStatus: true + ignoreStatus: true, }, order(item, player) { - if (player.hp > 1 && player.countCards('j')) return 0; + if (player.hp > 1 && player.countCards("j")) return 0; return 12; }, effect: { target(card, player, target) { - if (target.isPhaseUsing() && typeof card === 'object' && get.type(card, target) === 'delay' && !target.countCards('j')) { - let shas = target.getCards('hs', i => { - if (card === i || card.cards && card.cards.includes(i)) return false; - return get.name(i, target) === 'sha' && target.getUseValue(i) > 0; - }) - target.getCardUsable('sha'); + if ( + target.isPhaseUsing() && + typeof card === "object" && + get.type(card, target) === "delay" && + !target.countCards("j") + ) { + let shas = + target.getCards("hs", (i) => { + if (card === i || (card.cards && card.cards.includes(i))) + return false; + return get.name(i, target) === "sha" && target.getUseValue(i) > 0; + }) - target.getCardUsable("sha"); if (shas > 0) return [1, 1.5 * shas]; } - } - } + }, + }, }, }, }, - characterReplace:{ - duji:['duji','re_duji','ns_duji'], - sp_taishici:['sp_taishici','re_sp_taishici'], - mazhong:['mazhong','re_mazhong'], - wenpin:['wenpin','re_wenpin'], - liuyan:['liuyan','jsrg_liuyan','ol_liuyan'], + characterReplace: { + duji: ["duji", "re_duji", "ns_duji"], + sp_taishici: ["sp_taishici", "re_sp_taishici"], + mazhong: ["mazhong", "re_mazhong"], + wenpin: ["wenpin", "re_wenpin"], + liuyan: ["liuyan", "jsrg_liuyan", "ol_liuyan"], }, - translate:{ - xinghuoliaoyuan:'星火燎原', - "sp_taishici":"SP太史慈", - sp_taishici_prefix:'SP', - wangcan:"王粲", - "re_jsp_pangtong":"SP庞统", - re_jsp_pangtong_prefix:'SP', - lvdai:"吕岱", - "re_zhangliang":"张梁", - lvqian:"吕虔", - panjun:"潘濬", - duji:"杜畿", - zhoufang:"周鲂", - yanjun:"严畯", - liuyao:"刘繇", - liuyan:"刘焉", - "xinfu_guolun":"过论", - "xinfu_guolun_info":"出牌阶段限一次,你可以展示一名其他角色的手牌,然后展示你的一张牌。你与其交换这两张牌,然后展示的牌点数较小的角色摸一张牌。", - "xinfu_zhanji":"展骥", - "xinfu_zhanji_info":"锁定技。你的出牌阶段内,当你因摸牌且不是因为此技能效果而得到牌后,你摸一张牌。", - "xinfu_songsang":"送丧", - "xinfu_songsang_info":"限定技,其他角色死亡时,你可以回复1点体力(若你未受伤,则改为加1点体力上限);然后获得技能〖展骥〗。", - "xinfu_jixu":"击虚", - "xinfu_jixu_info":"出牌阶段限一次,若你有手牌,你可以令任意名体力值相等的其他角色猜测你的手牌中是否有【杀】。然后,你摸X张牌(X为猜错的角色数)。若你有【杀】,则你本回合内使用【杀】时,所有这些角色均成为【杀】的目标;若你没有【杀】,则你弃置所有这些角色的各一张牌。若X为零,你结束出牌阶段。", - "jixu_sha":"击虚", - "jixu_sha_info":"", - "xinfu_sanwen":"散文", - "xinfu_sanwen_info":"每回合限一次。当你得到牌后,若你的原手牌中有与这些牌名称相同的牌,则你可以展示这些牌,弃置新得到的同名牌并摸两倍的牌。", - "xinfu_qiai":"七哀", - "xinfu_qiai_info":"限定技,当你进入濒死状态时,你可以令所有其他角色依次交给你一张牌。", - "xinfu_denglou":"登楼", - "xinfu_denglou_info":"限定技,结束阶段,若你没有手牌,则你可以观看牌堆顶的四张牌,依次使用其中的所有基本牌(不能使用则弃置),然后获得其余的牌。", - "qinguo_use":"勤国", - "qinguo_use_info":"", - "xinfu_qinguo":"勤国", - "xinfu_qinguo_info":"当你使用的装备牌结算完成时,你可以视为使用一张【杀】;当你因使用或失去装备牌导致装备区内牌的数量发生变化后,若你装备区内牌的数量等于你的体力值,则你回复1点体力。", - "qinguo_lose":"勤国", - "qinguo_lose_info":"", - "xinfu_jijun":"集军", - "xinfu_jijun_info":"当你于回合内使用非装备牌或武器牌指定目标后,若你是此牌的目标,你可以进行一次判定。然后,你将判定牌置于自己的武将牌上,称之为「方」。", - "xinfu_fangtong":"方统", - "xinfu_fangtong_info":"结束阶段,你可以弃置总点数之和为36的一张牌与任意张「方」,并对一名其他角色造成3点雷电伤害。", - "xinfu_weilu":"威虏", - "xinfu_weilu_info":"锁定技,当你受到伤害后,伤害来源获得一枚「虏」。你的下个出牌阶段开始时,所有有「虏」的角色将体力失去至1点。此阶段结束后,这些角色回复以此法失去的体力。", - "weilu_effect":"威虏", - "weilu_effect_info":"", - "weilu_effect2":"威虏", - "weilu_effect2_info":"", - "xinfu_zengdao":"赠刀", - "xinfu_zengdao_info":"限定技,出牌阶段,你可以将装备区内的任意张牌置于一名其他角色的武将牌旁,称之为“刀”。该角色造成伤害时,其须移去一张“刀”,然后此伤害+1。", - "xinfu_zengdao2":"赠刀", - "xinfu_zengdao2_info":"", - "xinfu_guanwei":"观微", - "xinfu_guanwei_info":"每回合限一次。一名角色的出牌阶段结束时,若其本回合使用过两张以上的牌且这些牌均有花色且花色均相同,则你可以弃置一张牌,令其摸两张牌并进行一个额外的出牌阶段。", - "xinfu_gongqing":"公清", - "xinfu_gongqing_info":"锁定技。当你受到伤害时,若伤害来源的攻击范围:<3,则你令此伤害的数值减为1。>3,你令此伤害+1。", - "xinfu_andong":"安东", - "xinfu_andong_info":"当你受到伤害时,你可以令伤害来源选择一项:1.令你观看其的手牌并获得其中的所有红桃牌;2.防止此伤害,然后其本回合内的红桃手牌不计入手牌上限。", - "xinfu_yingshi":"应势", - "xinfu_yingshi_info":"出牌阶段开始时,若场上的所有角色均没有「酬」,则你可以将所有的红桃牌置于一名其他角色的武将牌旁,称之为「酬」。有「酬」的角色受到【杀】的伤害后/死亡时,伤害来源/你获得其中的一张/所有的「酬」。", - "yingshi_heart":"应势", - "yingshi_heart_info":"", - "yingshi_die":"应势", - "yingshi_die_info":"", - "xinfu_duanfa":"断发", - "xinfu_duanfa_info":"出牌阶段,你可以弃置任意张黑色牌,然后摸等量的牌。(每回合内限X张,X为你的体力上限)", - "xinfu_youdi":"诱敌", - "xinfu_youdi_info":"结束阶段开始时,你可以令一名其他角色弃置你的一张手牌,若此牌:不为黑色,你摸一张牌。不为【杀】,你获得该角色的一张牌。", - "xinfu_guanchao":"观潮", - "xinfu_guanchao_info":"出牌阶段开始时,你可以选择获得一项效果直到回合结束:1.当你使用牌时,若你此阶段使用过的所有牌的点数为递增,你摸一张牌;2.当你使用牌时,若你此阶段使用过的所有牌的点数为递减,你摸一张牌。", - "xinfu_xunxian":"逊贤", - "xinfu_xunxian_info":"每回合限一次。当你使用或打出的牌结算完成后,你可以将其对应的所有实体牌交给一名手牌数或体力值大于你的角色。", - "xinfu_kannan":"戡难", - "xinfu_kannan_info":"出牌阶段限X次,你可以与一名本回合内未成为过〖戡难〗目标的角色拼点。若你赢,你使用的下一张【杀】的伤害值基数+1,且你本回合内不能再发动〖戡难〗。若你没赢,其使用的下一张【杀】的伤害值基数+1。(X为你的体力值)。", - "kannan_eff":"戡难", - "kannan_eff_info":"", - "xinfu_tushe":"图射", - "xinfu_tushe_info":"当你使用非装备牌指定目标后,若你没有基本牌,则你可以摸X张牌。(X为此牌指定的目标数)", - "xinfu_limu":"立牧", - "xinfu_limu_info":"出牌阶段,你可以将一张♦牌当做【乐不思蜀】对自己使用,然后回复1点体力。只要你的判定区内有牌,你对攻击范围内的其他角色使用牌便没有次数和距离限制。", - xinyingshi:'应势', - xinyingshi_info:'出牌阶段开始时,若场上所有角色的武将牌上均没有“酬”,则你可以将任意张牌置于一名角色的武将牌上,称为“酬”。若如此做:当有角色使用牌对有“酬”的角色造成伤害后,其可以获得一张“酬”,并获得牌堆中所有与“酬”花色点数均相同的牌;有“酬”的角色死亡时,你获得其所有“酬”。', + translate: { + xinghuoliaoyuan: "星火燎原", + sp_taishici: "SP太史慈", + sp_taishici_prefix: "SP", + wangcan: "王粲", + re_jsp_pangtong: "SP庞统", + re_jsp_pangtong_prefix: "SP", + lvdai: "吕岱", + re_zhangliang: "张梁", + lvqian: "吕虔", + panjun: "潘濬", + duji: "杜畿", + zhoufang: "周鲂", + yanjun: "严畯", + liuyao: "刘繇", + liuyan: "刘焉", + xinfu_guolun: "过论", + xinfu_guolun_info: + "出牌阶段限一次,你可以展示一名其他角色的手牌,然后展示你的一张牌。你与其交换这两张牌,然后展示的牌点数较小的角色摸一张牌。", + xinfu_zhanji: "展骥", + xinfu_zhanji_info: + "锁定技。你的出牌阶段内,当你因摸牌且不是因为此技能效果而得到牌后,你摸一张牌。", + xinfu_songsang: "送丧", + xinfu_songsang_info: + "限定技,其他角色死亡时,你可以回复1点体力(若你未受伤,则改为加1点体力上限);然后获得技能〖展骥〗。", + xinfu_jixu: "击虚", + xinfu_jixu_info: + "出牌阶段限一次,若你有手牌,你可以令任意名体力值相等的其他角色猜测你的手牌中是否有【杀】。然后,你摸X张牌(X为猜错的角色数)。若你有【杀】,则你本回合内使用【杀】时,所有这些角色均成为【杀】的目标;若你没有【杀】,则你弃置所有这些角色的各一张牌。若X为零,你结束出牌阶段。", + jixu_sha: "击虚", + jixu_sha_info: "", + xinfu_sanwen: "散文", + xinfu_sanwen_info: + "每回合限一次。当你得到牌后,若你的原手牌中有与这些牌名称相同的牌,则你可以展示这些牌,弃置新得到的同名牌并摸两倍的牌。", + xinfu_qiai: "七哀", + xinfu_qiai_info: "限定技,当你进入濒死状态时,你可以令所有其他角色依次交给你一张牌。", + xinfu_denglou: "登楼", + xinfu_denglou_info: + "限定技,结束阶段,若你没有手牌,则你可以观看牌堆顶的四张牌,依次使用其中的所有基本牌(不能使用则弃置),然后获得其余的牌。", + qinguo_use: "勤国", + qinguo_use_info: "", + xinfu_qinguo: "勤国", + xinfu_qinguo_info: + "当你使用的装备牌结算完成时,你可以视为使用一张【杀】;当你因使用或失去装备牌导致装备区内牌的数量发生变化后,若你装备区内牌的数量等于你的体力值,则你回复1点体力。", + qinguo_lose: "勤国", + qinguo_lose_info: "", + xinfu_jijun: "集军", + xinfu_jijun_info: + "当你于回合内使用非装备牌或武器牌指定目标后,若你是此牌的目标,你可以进行一次判定。然后,你将判定牌置于自己的武将牌上,称之为「方」。", + xinfu_fangtong: "方统", + xinfu_fangtong_info: + "结束阶段,你可以弃置总点数之和为36的一张牌与任意张「方」,并对一名其他角色造成3点雷电伤害。", + xinfu_weilu: "威虏", + xinfu_weilu_info: + "锁定技,当你受到伤害后,伤害来源获得一枚「虏」。你的下个出牌阶段开始时,所有有「虏」的角色将体力失去至1点。此阶段结束后,这些角色回复以此法失去的体力。", + weilu_effect: "威虏", + weilu_effect_info: "", + weilu_effect2: "威虏", + weilu_effect2_info: "", + xinfu_zengdao: "赠刀", + xinfu_zengdao_info: + "限定技,出牌阶段,你可以将装备区内的任意张牌置于一名其他角色的武将牌旁,称之为“刀”。该角色造成伤害时,其须移去一张“刀”,然后此伤害+1。", + xinfu_zengdao2: "赠刀", + xinfu_zengdao2_info: "", + xinfu_guanwei: "观微", + xinfu_guanwei_info: + "每回合限一次。一名角色的出牌阶段结束时,若其本回合使用过两张以上的牌且这些牌均有花色且花色均相同,则你可以弃置一张牌,令其摸两张牌并进行一个额外的出牌阶段。", + xinfu_gongqing: "公清", + xinfu_gongqing_info: + "锁定技。当你受到伤害时,若伤害来源的攻击范围:<3,则你令此伤害的数值减为1。>3,你令此伤害+1。", + xinfu_andong: "安东", + xinfu_andong_info: + "当你受到伤害时,你可以令伤害来源选择一项:1.令你观看其的手牌并获得其中的所有红桃牌;2.防止此伤害,然后其本回合内的红桃手牌不计入手牌上限。", + xinfu_yingshi: "应势", + xinfu_yingshi_info: + "出牌阶段开始时,若场上的所有角色均没有「酬」,则你可以将所有的红桃牌置于一名其他角色的武将牌旁,称之为「酬」。有「酬」的角色受到【杀】的伤害后/死亡时,伤害来源/你获得其中的一张/所有的「酬」。", + yingshi_heart: "应势", + yingshi_heart_info: "", + yingshi_die: "应势", + yingshi_die_info: "", + xinfu_duanfa: "断发", + xinfu_duanfa_info: + "出牌阶段,你可以弃置任意张黑色牌,然后摸等量的牌。(每回合内限X张,X为你的体力上限)", + xinfu_youdi: "诱敌", + xinfu_youdi_info: + "结束阶段开始时,你可以令一名其他角色弃置你的一张手牌,若此牌:不为黑色,你摸一张牌。不为【杀】,你获得该角色的一张牌。", + xinfu_guanchao: "观潮", + xinfu_guanchao_info: + "出牌阶段开始时,你可以选择获得一项效果直到回合结束:1.当你使用牌时,若你此阶段使用过的所有牌的点数为递增,你摸一张牌;2.当你使用牌时,若你此阶段使用过的所有牌的点数为递减,你摸一张牌。", + xinfu_xunxian: "逊贤", + xinfu_xunxian_info: + "每回合限一次。当你使用或打出的牌结算完成后,你可以将其对应的所有实体牌交给一名手牌数或体力值大于你的角色。", + xinfu_kannan: "戡难", + xinfu_kannan_info: + "出牌阶段限X次,你可以与一名本回合内未成为过〖戡难〗目标的角色拼点。若你赢,你使用的下一张【杀】的伤害值基数+1,且你本回合内不能再发动〖戡难〗。若你没赢,其使用的下一张【杀】的伤害值基数+1。(X为你的体力值)。", + kannan_eff: "戡难", + kannan_eff_info: "", + xinfu_tushe: "图射", + xinfu_tushe_info: + "当你使用非装备牌指定目标后,若你没有基本牌,则你可以摸X张牌。(X为此牌指定的目标数)", + xinfu_limu: "立牧", + xinfu_limu_info: + "出牌阶段,你可以将一张♦牌当做【乐不思蜀】对自己使用,然后回复1点体力。只要你的判定区内有牌,你对攻击范围内的其他角色使用牌便没有次数和距离限制。", + xinyingshi: "应势", + xinyingshi_info: + "出牌阶段开始时,若场上所有角色的武将牌上均没有“酬”,则你可以将任意张牌置于一名角色的武将牌上,称为“酬”。若如此做:当有角色使用牌对有“酬”的角色造成伤害后,其可以获得一张“酬”,并获得牌堆中所有与“酬”花色点数均相同的牌;有“酬”的角色死亡时,你获得其所有“酬”。", - xinghuoliaoyuan_tianfu:'天府', - xinghuoliaoyuan_tianliang:'天梁', - xinghuoliaoyuan_tianji:'天机', - xinghuoliaoyuan_tiantong:'天同', - xinghuoliaoyuan_tianxiang:'天相', - xinghuoliaoyuan_qisha:'七杀', + xinghuoliaoyuan_tianfu: "天府", + xinghuoliaoyuan_tianliang: "天梁", + xinghuoliaoyuan_tianji: "天机", + xinghuoliaoyuan_tiantong: "天同", + xinghuoliaoyuan_tianxiang: "天相", + xinghuoliaoyuan_qisha: "七杀", }, }; }); diff --git a/character/yijiang.js b/character/yijiang.js index 1d1c20aea..362d323c9 100755 --- a/character/yijiang.js +++ b/character/yijiang.js @@ -1,1603 +1,2115 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'yijiang', - connect:true, + name: "yijiang", + connect: true, //connectBanned:['qinmi'], - characterSort:{ - yijiang:{ - yijiang_2011:['caozhi','yujin','zhangchunhua','xin_fazheng','xin_masu','xin_xushu','xusheng','lingtong','wuguotai','chengong','gaoshun'], - yijiang_2012:['wangyi','xunyou','zhonghui','old_madai','liaohua','guanzhang','bulianshi','handang','chengpu','liubiao','old_huaxiong','caozhang'], - yijiang_2013:['manchong','guohuai','caochong','guanping','liufeng','jianyong','yufan','panzhangmazhong','zhuran','xin_liru','fuhuanghou'], - yijiang_2014:['hanhaoshihuan','chenqun','caozhen','zhangsong','wuyi','zhoucang','zhuhuan','guyong','sunluban','yj_jushou','caifuren'], - yijiang_2015:['caoxiu','caorui','zhongyao','xiahoushi','liuchen','zhangyi','zhuzhi','quancong','sunxiu','gongsunyuan','guotufengji'], - yijiang_2016:['guohuanghou','sunziliufang','huanghao','liyan','sundeng','cenhun','zhangrang','liuyu'], - yijiang_2017:['xinxianying','jikang','wuxian','qinmi','xuezong','xushi','caiyong','caojie'], - yijiang_2022:['lukai','kebineng','zhugeshang','liwan','wuanguo','hanlong','yj_sufei','yj_qiaozhou'], - yijiang_2023:['xiahoumao','chenshi','sunli','feiyao'], + characterSort: { + yijiang: { + yijiang_2011: [ + "caozhi", + "yujin", + "zhangchunhua", + "xin_fazheng", + "xin_masu", + "xin_xushu", + "xusheng", + "lingtong", + "wuguotai", + "chengong", + "gaoshun", + ], + yijiang_2012: [ + "wangyi", + "xunyou", + "zhonghui", + "old_madai", + "liaohua", + "guanzhang", + "bulianshi", + "handang", + "chengpu", + "liubiao", + "old_huaxiong", + "caozhang", + ], + yijiang_2013: [ + "manchong", + "guohuai", + "caochong", + "guanping", + "liufeng", + "jianyong", + "yufan", + "panzhangmazhong", + "zhuran", + "xin_liru", + "fuhuanghou", + ], + yijiang_2014: [ + "hanhaoshihuan", + "chenqun", + "caozhen", + "zhangsong", + "wuyi", + "zhoucang", + "zhuhuan", + "guyong", + "sunluban", + "yj_jushou", + "caifuren", + ], + yijiang_2015: [ + "caoxiu", + "caorui", + "zhongyao", + "xiahoushi", + "liuchen", + "zhangyi", + "zhuzhi", + "quancong", + "sunxiu", + "gongsunyuan", + "guotufengji", + ], + yijiang_2016: [ + "guohuanghou", + "sunziliufang", + "huanghao", + "liyan", + "sundeng", + "cenhun", + "zhangrang", + "liuyu", + ], + yijiang_2017: [ + "xinxianying", + "jikang", + "wuxian", + "qinmi", + "xuezong", + "xushi", + "caiyong", + "caojie", + ], + yijiang_2022: [ + "lukai", + "kebineng", + "zhugeshang", + "liwan", + "wuanguo", + "hanlong", + "yj_sufei", + "yj_qiaozhou", + ], + yijiang_2023: ["xiahoumao", "chenshi", "sunli", "feiyao"], }, }, - character:{ - xiahoumao:['male','wei',4,['tongwei','cuguo']], - chenshi:['male','shu',4,['qingbei']], - sunli:['male','wei',4,['kangli']], - feiyao:['male','wei',4,['zhenfeng']], - wuanguo:['male','qun',4,['diezhang','duanwan']], - hanlong:['male','wei',4,['duwang','cibei']], - yj_qiaozhou:['male','shu',3,['shiming','jiangxi']], - yj_sufei:['male','wu',4,['shuojian']], - liwan:['female','wei',3,['liandui','biejun']], - zhugeshang:['male','shu',3,['sangu','yizu']], - kebineng:['male','qun',4,['kousheng']], - lukai:['male','wu',4,['lkbushi','lkzhongzhuang']], - xin_fazheng:['male','shu',3,['xinxuanhuo','xinenyuan']], - guanzhang:['male','shu',4,['fuhun']], - wangyi:['female','wei',3,['zhenlie','miji']], - caozhang:['male','wei',4,['new_jiangchi']], - guohuai:['male','wei',4,['rejingce']], - zhangchunhua:['female','wei',3,['jueqing','shangshi']], - caozhi:['male','wei',3,['luoying','jiushi']], - caochong:['male','wei',3,['chengxiang','renxin']], - xunyou:['male','wei',3,['qice','zhiyu'],['clan:颍川荀氏']], - xin_xushu:['male','shu',3,['xinwuyan','xinjujian'],['border:wei']], - xin_masu:['male','shu',3,['olsanyao','rezhiman']], - zhuran:['male','wu',4,['danshou']], - xusheng:['male','wu',4,['xinpojun']], - wuguotai:['female','wu',3,['ganlu','buyi']], - lingtong:['male','wu',4,['xuanfeng']], - liubiao:['male','qun',3,['rezishou','zongshi']], - yufan:['male','wu',3,['zhiyan','zongxuan']], - chengong:['male','qun',3,['mingce','zhichi']], - bulianshi:['female','wu',3,['old_anxu','zhuiyi']], - handang:['male','wu',4,['gongji','jiefan']], - fuhuanghou:['female','qun',3,['qiuyuan','zhuikong']], - zhonghui:['male','wei',4,['quanji','zili'],['clan:颍川钟氏']], - jianyong:['male','shu',3,['qiaoshui','jyzongshi']], - old_madai:['male','shu',4,['mashu','qianxi']], - liufeng:['male','shu',4,['xiansi']], - manchong:['male','wei',3,['junxing','yuce']], - chenqun:['male','wei',3,['pindi','faen']], - sunluban:['female','wu',3,['chanhui','jiaojin']], - guyong:['male','wu',3,['shenxing','olbingyi']], - caifuren:['female','qun',3,['qieting','xianzhou']], - yj_jushou:['male','qun',3,['jianying','shibei']], - zhangsong:['male','shu',3,['qiangzhi','xiantu']], - zhuhuan:['male','wu',4,['fenli','pingkou']], - xiahoushi:['female','shu',3,['qiaoshi','yanyu']], + character: { + xiahoumao: ["male", "wei", 4, ["tongwei", "cuguo"]], + chenshi: ["male", "shu", 4, ["qingbei"]], + sunli: ["male", "wei", 4, ["kangli"]], + feiyao: ["male", "wei", 4, ["zhenfeng"]], + wuanguo: ["male", "qun", 4, ["diezhang", "duanwan"]], + hanlong: ["male", "wei", 4, ["duwang", "cibei"]], + yj_qiaozhou: ["male", "shu", 3, ["shiming", "jiangxi"]], + yj_sufei: ["male", "wu", 4, ["shuojian"]], + liwan: ["female", "wei", 3, ["liandui", "biejun"]], + zhugeshang: ["male", "shu", 3, ["sangu", "yizu"]], + kebineng: ["male", "qun", 4, ["kousheng"]], + lukai: ["male", "wu", 4, ["lkbushi", "lkzhongzhuang"]], + xin_fazheng: ["male", "shu", 3, ["xinxuanhuo", "xinenyuan"]], + guanzhang: ["male", "shu", 4, ["fuhun"]], + wangyi: ["female", "wei", 3, ["zhenlie", "miji"]], + caozhang: ["male", "wei", 4, ["new_jiangchi"]], + guohuai: ["male", "wei", 4, ["rejingce"]], + zhangchunhua: ["female", "wei", 3, ["jueqing", "shangshi"]], + caozhi: ["male", "wei", 3, ["luoying", "jiushi"]], + caochong: ["male", "wei", 3, ["chengxiang", "renxin"]], + xunyou: ["male", "wei", 3, ["qice", "zhiyu"], ["clan:颍川荀氏"]], + xin_xushu: ["male", "shu", 3, ["xinwuyan", "xinjujian"], ["border:wei"]], + xin_masu: ["male", "shu", 3, ["olsanyao", "rezhiman"]], + zhuran: ["male", "wu", 4, ["danshou"]], + xusheng: ["male", "wu", 4, ["xinpojun"]], + wuguotai: ["female", "wu", 3, ["ganlu", "buyi"]], + lingtong: ["male", "wu", 4, ["xuanfeng"]], + liubiao: ["male", "qun", 3, ["rezishou", "zongshi"]], + yufan: ["male", "wu", 3, ["zhiyan", "zongxuan"]], + chengong: ["male", "qun", 3, ["mingce", "zhichi"]], + bulianshi: ["female", "wu", 3, ["old_anxu", "zhuiyi"]], + handang: ["male", "wu", 4, ["gongji", "jiefan"]], + fuhuanghou: ["female", "qun", 3, ["qiuyuan", "zhuikong"]], + zhonghui: ["male", "wei", 4, ["quanji", "zili"], ["clan:颍川钟氏"]], + jianyong: ["male", "shu", 3, ["qiaoshui", "jyzongshi"]], + old_madai: ["male", "shu", 4, ["mashu", "qianxi"]], + liufeng: ["male", "shu", 4, ["xiansi"]], + manchong: ["male", "wei", 3, ["junxing", "yuce"]], + chenqun: ["male", "wei", 3, ["pindi", "faen"]], + sunluban: ["female", "wu", 3, ["chanhui", "jiaojin"]], + guyong: ["male", "wu", 3, ["shenxing", "olbingyi"]], + caifuren: ["female", "qun", 3, ["qieting", "xianzhou"]], + yj_jushou: ["male", "qun", 3, ["jianying", "shibei"]], + zhangsong: ["male", "shu", 3, ["qiangzhi", "xiantu"]], + zhuhuan: ["male", "wu", 4, ["fenli", "pingkou"]], + xiahoushi: ["female", "shu", 3, ["qiaoshi", "yanyu"]], - panzhangmazhong:['male','wu',4,['duodao','anjian']], - zhoucang:['male','shu',4,['xinzhongyong']], - guanping:['male','shu',4,['longyin']], - liaohua:['male','shu',4,['dangxian','fuli']], - chengpu:['male','wu',4,['lihuo','chunlao']], - gaoshun:['male','qun',4,['xinxianzhen','jinjiu']], - caozhen:['male','wei',4,['xinsidi']], - wuyi:['male','shu',4,['benxi'],['clan:陈留吴氏']], - hanhaoshihuan:['male','wei',4,['shenduan','yonglve']], + panzhangmazhong: ["male", "wu", 4, ["duodao", "anjian"]], + zhoucang: ["male", "shu", 4, ["xinzhongyong"]], + guanping: ["male", "shu", 4, ["longyin"]], + liaohua: ["male", "shu", 4, ["dangxian", "fuli"]], + chengpu: ["male", "wu", 4, ["lihuo", "chunlao"]], + gaoshun: ["male", "qun", 4, ["xinxianzhen", "jinjiu"]], + caozhen: ["male", "wei", 4, ["xinsidi"]], + wuyi: ["male", "shu", 4, ["benxi"], ["clan:陈留吴氏"]], + hanhaoshihuan: ["male", "wei", 4, ["shenduan", "yonglve"]], - caorui:['male','wei',3,['huituo','mingjian','xingshuai'],['zhu']], - caoxiu:['male','wei',4,['qianju','qingxi']], - zhongyao:['male','wei',3,['huomo','zuoding'],['clan:颍川钟氏']], - liuchen:['male','shu',4,['zhanjue','qinwang'],['zhu']], - zhangyi:['male','shu',4,['wurong','shizhi']], - sunxiu:['male','wu',3,['yanzhu','xingxue','xinzhaofu'],['zhu']], - zhuzhi:['male','wu',4,['xinanguo']], - quancong:['male','wu',4,['yaoming']], - gongsunyuan:['male','qun',4,['huaiyi']], - guotufengji:['male','qun',3,['jigong','shifei']], + caorui: ["male", "wei", 3, ["huituo", "mingjian", "xingshuai"], ["zhu"]], + caoxiu: ["male", "wei", 4, ["qianju", "qingxi"]], + zhongyao: ["male", "wei", 3, ["huomo", "zuoding"], ["clan:颍川钟氏"]], + liuchen: ["male", "shu", 4, ["zhanjue", "qinwang"], ["zhu"]], + zhangyi: ["male", "shu", 4, ["wurong", "shizhi"]], + sunxiu: ["male", "wu", 3, ["yanzhu", "xingxue", "xinzhaofu"], ["zhu"]], + zhuzhi: ["male", "wu", 4, ["xinanguo"]], + quancong: ["male", "wu", 4, ["yaoming"]], + gongsunyuan: ["male", "qun", 4, ["huaiyi"]], + guotufengji: ["male", "qun", 3, ["jigong", "shifei"]], - xin_liru:['male','qun',3,['xinjuece','xinmieji','xinfencheng']], + xin_liru: ["male", "qun", 3, ["xinjuece", "xinmieji", "xinfencheng"]], - guohuanghou:['female','wei',3,['jiaozhao','danxin']], - liuyu:['male','qun',2,['xinzhige','xinzongzuo']], - liyan:['male','shu',3,['dcduliang','fulin']], - sundeng:['male','wu',4,['kuangbi']], + guohuanghou: ["female", "wei", 3, ["jiaozhao", "danxin"]], + liuyu: ["male", "qun", 2, ["xinzhige", "xinzongzuo"]], + liyan: ["male", "shu", 3, ["dcduliang", "fulin"]], + sundeng: ["male", "wu", 4, ["kuangbi"]], - cenhun:['male','wu',4,['jishe','lianhuo']], - huanghao:['male','shu',3,['qinqing','huisheng']], - zhangrang:['male','qun',3,['taoluan'],['sex:male_castrated']], - sunziliufang:['male','wei',3,['guizao','jiyu']], + cenhun: ["male", "wu", 4, ["jishe", "lianhuo"]], + huanghao: ["male", "shu", 3, ["qinqing", "huisheng"]], + zhangrang: ["male", "qun", 3, ["taoluan"], ["sex:male_castrated"]], + sunziliufang: ["male", "wei", 3, ["guizao", "jiyu"]], - xinxianying:['female','wei',3,['zhongjian','caishi']], - wuxian:['female','shu',3,['fumian','daiyan'],['clan:陈留吴氏']], - xushi:['female','wu',3,['wengua','fuzhu']], - caojie:['female','qun',3,['shouxi','huimin']], + xinxianying: ["female", "wei", 3, ["zhongjian", "caishi"]], + wuxian: ["female", "shu", 3, ["fumian", "daiyan"], ["clan:陈留吴氏"]], + xushi: ["female", "wu", 3, ["wengua", "fuzhu"]], + caojie: ["female", "qun", 3, ["shouxi", "huimin"]], - caiyong:['male','qun',3,['bizhuan','tongbo']], - jikang:['male','wei',3,['qingxian','juexiang']], - qinmi:['male','shu',3,['jianzheng','zhuandui','tianbian']], - xuezong:['male','wu',3,['funan','xinjiexun']], + caiyong: ["male", "qun", 3, ["bizhuan", "tongbo"]], + jikang: ["male", "wei", 3, ["qingxian", "juexiang"]], + qinmi: ["male", "shu", 3, ["jianzheng", "zhuandui", "tianbian"]], + xuezong: ["male", "wu", 3, ["funan", "xinjiexun"]], - old_huaxiong:['male','qun',6,['shiyong']], + old_huaxiong: ["male", "qun", 6, ["shiyong"]], - yujin:["male","wei",4,["rezhenjun"],[]], + yujin: ["male", "wei", 4, ["rezhenjun"], []], }, - characterIntro:{ - sunli:'孙礼(?—250年),字德达,涿郡容城县人。三国时期曹魏名将。曹操平定幽州后,孙礼被征召为司空军谋掾。后被任命为河间郡丞,升至荥阳都尉。后孙礼被调为鲁国相。历任山阳、平原、平昌、琅邪郡太守。从大司马曹休在夹石征吴,孙礼谏其不可深入作战,曹休不听遂战败。后孙礼调任阳平郡太守。明帝时入为尚书,受遗诏拜大将军长史,加散骑常侍。曹爽令孙礼出任扬州刺史,加管伏波将军,赐爵关内侯。孙礼率兵御东吴军队,奋不顾身,贼众乃退。朝廷赐绢七百匹,孙礼皆以绢付亡者家,无以入身。后征拜少府,出为荆州刺史,迁冀州牧。爽见礼奏,大怒,劾礼怨望,结刑五岁。在家期年,众人多以为言,除城门校尉。出为并州刺史,加振武将军,使持节,护匈奴中郎将。爽诛后,入为司隶校尉。迁司空,封大利亭侯,邑一百户。嘉平二年(250年),孙礼去世,谥号景侯。其孙孙元继承爵位。《全三国文》录有孙礼文一篇《清河平原争界案图宜属平原疏》。陈寿评曰“孙礼刚断伉厉”。', - xiahoumao:'夏侯楙,字子林,沛国谯县(今安徽省亳州市)人,曹魏名将夏侯惇之子,三国时期魏国官员、将领,其妻为曹操之女清河公主。在魏国历任侍中、尚书、安西将军、镇东将军,假节,封列侯。曾一度驻守曹魏都城长安,但蜀汉北伐后就被调离。', - chenshi:'陈式,生卒年不详,三国时期蜀汉将领。最初为刘备军中重要的基层指挥官,后成长为高级将领。在诸葛亮第三次北伐期间,在诸葛亮的军事指挥下攻克了魏国的武都、阴平二郡。', - feiyao:'费曜(生卒年不详),又作费瑶、费繇,三国时期曹魏将领。魏初,参与平河西之乱。明帝时官任后将军,跟随曹真、司马懿多次对抗蜀汉。《三国演义》中作“费耀”,随曹真和诸葛亮的第二次北伐军作战。怀疑姜维作内应是假,自告奋勇替曹真出征,结果被事先埋伏的姜维包围,自尽而死。', - wuanguo:'武安国,历史小说《三国演义》中人物,是北海太守孔融的部将,兵器为一把长柄铁锤,重五十余斤。诸侯伐董时,双方于虎牢关相峙,吕布撰战,一合而斩穆顺,关东军大惊。北海太守孔融部将武安国,使铁锤飞马而出,吕布挥戟拍马来迎,战到十余合,一戟砍断安国手腕,安国弃锤于地而走,八路军兵齐出,这才救了他性命。', - hanlong:'韩龙,汉末三国时期刺客。韩龙使得魏国北方边得到数十年的安宁,减少魏国的军政压力,得以休养生息。太和二年,豫遣译夏舍诣比能女婿郁筑鞬部,舍为鞬所杀。其秋,豫将西部鲜卑蒲头、泄归泥出塞讨郁筑鞬,大破之。还至马城,比能自将三万骑围豫七日。上谷太守阎志,阎柔之弟也,素为鲜卑所信。志往解喻,即解围去。后幽州刺史王雄并领校尉,抚以恩信。比能数款塞,诣州奉贡献。至青龙元年,比能诱纳步度根,使叛并州,与结和亲,自勒万骑迎其累重於陉北。并州刺史毕轨遣将军苏尚、董弼等击之,比能遣子将骑与尚等会战於楼烦,临陈害尚、弼。至三年中,雄遣勇士韩龙刺杀比能,更立其弟。', - liwan:'李婉(生卒年不详),字淑文,里居不详,贾充之妻,魏晋时期才女,约景元年间(260年前后)在世。著有《典戒》。《隋书·经籍志》载李婉有文集一卷,今失传。', - zhugeshang:'诸葛尚(244年2月-263年11月),琅琊阳都(今山东沂南)人,诸葛瞻长子,诸葛亮之孙。诸葛尚博览兵书且精通武艺。炎兴元年(公元263年),出任先锋,抗拒魏国大将邓艾,与其父诸葛瞻同战死于绵竹,时年十九岁。', - kebineng:'轲比能(?~235年),为中国三国时期的鲜卑首领之一。轲比能出身鲜卑支部,因他作战勇敢,执法公平,不贪财物,所以被鲜卑民众推举为大人。轲比能因其部落近塞,所以他抓住有利条件积极学习汉族先进技术和文化,促进了鲜卑族的进步和北方的民族融合。轲比能统率下的部众,战守有法,战斗力相当强大。自曹操北征后向曹氏进贡表示效忠。魏文帝时,轲比能受封附义王。轲比能在进行部落统一战争时,受魏国干涉,受沉重打击,于是对魏怀贰,献书魏帝表忠,以麻痹魏庭,使之放松警惕。此后,轲比能的部众变得强盛,控弦十余万骑,为害魏国边境。每次钞略得财物,轲比能都公开透明地均平分配,所以得部众死力,各部大人都敬畏之。实力强大后,他继续部落统一战争,于是威行诸部落,建立起强大的鲜卑族政权。深感威胁的魏国幽州刺史王雄派刺客韩龙将其刺杀,其政权立刻崩溃,鲜卑民族再次陷入混战。', - lukai:'陆凯(198-269年),字敬风,吴郡吴县(今江苏省苏州市)人。三国时期吴国重臣,丞相陆逊的族侄,大司马陆抗的族兄。黄武年间,举孝廉出身,曾任永兴县长、诸暨县长,颇有治绩。拜建武都尉、儋耳太守,与聂友率军讨伐朱崖和儋耳,迁建武校尉。五凤二年(255年),讨斩零陵山贼陈毖,拜偏将军、巴丘督,册封都乡侯。迁武昌右部督,随军进入寿春。后拜荡魏将军,加号绥远将军。吴景帝孙休继位,拜征北将军、假节、领豫州牧。孙皓即位,迁任镇西大将军,都督巴丘,又领荆州牧,进封嘉兴侯。宝鼎元年(266年),迁左丞相。以正直及屡次劝谏孙皓而闻名。建衡元年(269年),去世,时年七十二。', - caozhi:'字子建,沛国谯人,三国曹魏著名文学家,建安文学代表人物。魏武帝曹操之子,魏文帝曹丕之弟,生前曾为陈王,去世后谥号“思”,因此又称陈思王。南朝宋文学家谢灵运更有“天下才有一石,曹子建独占八斗”的评价。王士祯尝论汉魏以来二千年间诗家堪称“仙才”者,曹植、李白、苏轼三人耳。', - gaoshun:'中国东汉末年将领,吕布帐下中郎将。史载高顺为人清白有威严,不好饮酒,所统率的部队精锐非常,号称“陷阵营”。屡进忠言于吕布,吕布虽知其忠而不能用。曹操击破吕布后,高顺被曹操所杀。', - chengong:'字公台,东汉末年吕布帐下谋士,东郡东武阳人。性情刚直,足智多谋,年少时与海内知名之士相互结交。192年,陈宫等人主张曹操接任兖州牧。但此后陈宫因曹操杀害边让而与曹操反目,并游说张邈等人背叛曹操迎吕布入兖州,辅助吕布攻打曹操。吕布战败后,随吕布等一同被曹操所擒,决意赴死。', - lingtong:'字公绩,吴郡馀杭人,三国时期吴国名将。凌操之子,官至偏将军。', - masu:'字幼常,襄阳宜城人,三国时期蜀汉大臣,侍中马良之弟。初以荆州从事跟随刘备取蜀入川,曾任绵竹、成都令、越嶲太守。诸葛亮北伐时因作战失误而失守街亭,因而被诸葛亮所斩。', - wuguotai:'吴国太,小说《三国演义》中的人物,不见于正史记载。在小说中,吴国太被描述为孙坚的次妻,孙坚正妻武烈皇后(小说中写作吴太夫人)的妹妹,孙朗、孙仁(孙尚香)的母亲。', - xusheng:'字文向,琅邪莒县人。三国时期吴将。徐盛最初因讨伐山贼有功而被加为中郎将,后于濡须口之战中表现出色,得到孙权的赞赏。魏文帝曹丕伐吴时,徐盛以疑城之计退去魏军。', - yujin:'字文则,泰山钜平人。三国时期曹魏武将。本为鲍信部将,后属曹操,曹操称赞他可与古代名将相比。然而在建安二十四年的襄樊之战中,于禁在败给关羽后投降,致使一代名将晚节不保。', - zhangchunhua:'西晋宣穆皇后张春华(189-247),河内平皋(今河南温县)人。她是晋宣帝司马懿之妻,晋景帝司马师、晋文帝司马昭的母亲。后被追尊为皇后。', - fazheng:'字孝直,本为刘璋部下,刘备围成都时劝说刘璋投降,而后又与刘备进取汉中,献计将曹操大将夏侯渊斩首。法正善奇谋,深受刘备信任和敬重。', - xushu:'字元直,与司马徽、诸葛亮等人为友。先化名单福仕官于新野的刘备,后因曹操囚禁其母而不得不弃备投操,临行前向刘备推荐诸葛亮之才。入曹营后,一言不发,不曾为曹操进献过一计半策。后人形容徐庶“身在曹营心在汉”。', - caozhang:'字子文,是曹操与武宣卞皇后所生第二子,曹丕之弟,曹植之兄,曹魏任城王。曹彰武艺过人,曹操问诸子志向时自言“好为将”,因此得到曹操的赞赏。其胡须黄色,被曹操称为“黄须儿”。', - xunyou:'字公达,颍川颍阴人。东汉末年曹操的五谋臣之一,荀彧从子,被曹操称为“谋主”。官至尚书令。正始五年被追谥为敬侯。', - liaohua:'本名淳,字元俭,襄阳中卢(今湖北襄樊)人。三国时期蜀国后期将领,以勇敢果断著称。廖化是三国时代中经历了魏、蜀、吴整个兴衰过程极少数人中的一个,与严颜、黄忠共称为蜀汉三老将。', - bulianshi:'步夫人(?-238),讳练师,临淮淮阴人。东吴丞相步骘同族,吴大帝孙权之妃,在孙权众夫人中最受孙权的宠爱(宠冠后庭),生有二女:孙鲁班、孙鲁育。赤乌元年卒,追封为皇后,葬于蒋陵。', - chengpu:'字德谋,右北平土垠人。历仕孙坚、孙策、孙权三任君主。孙策死后,他与张昭等人共同辅佐孙权,并讨伐江东境内的山贼,功勋卓著。被人们尊称为“程公”。', - handang:'字义公,辽西令支(今河北迁安)人,吴国将领。韩当因为长于弓箭、骑术并且膂力过人而被孙坚赏识,追随他四处征伐周旋,数次冒险犯难,攻陷敌人、擒拿俘虏。对江东基业的逐渐稳固和吴国的建立有着重要影响。', - liubiao:'刘表,字景升,山阳郡高平(今山东微山)人。东汉末年名士,汉室宗亲,荆州牧,汉末群雄之一。', - zhonghui:'字士季。魏名将,太傅钟繇之子。公元263年,他与邓艾带兵攻打蜀国,最终导致蜀国灭亡。之后钟会设计害死邓艾,联合姜维准备自立,最终因部下反叛失败,与姜维一同死于兵变。', - wangyi:'益州刺史赵昂之妻,赵英、赵月之母。马超作乱凉州时,王异协助丈夫守城,多有功勋,自马超攻冀城至祁山坚守,赵昂曾出奇计九条,王异皆有参与。', - guanzhang:'关兴,名将关羽之子,继承了父亲汉寿亭侯的爵位。年少时即受诸葛亮器重,在蜀汉担任侍中、中监军之职,后在夷陵之战中报了杀父之仇。张苞,张飞的长子,使用父亲的家传蛇矛为兵器,勇猛剽悍不弱其父。', - madai:'名将马超的从弟。早年他曾经从曹操手中死里逃生,后跟随马超大战曹操。后在诸葛亮病逝后受杨仪派遣斩杀了蜀将魏延。曾率领军队出师北伐,被魏将牛金击败而退还。', - caochong:'字仓舒,曹操之子。从小聪明仁爱,与众不同,深受曹操喜爱。留有“曹冲称象”的典故。曹操几次对群臣夸耀他,有让他继嗣之意。可惜曹冲在建安十三病逝,年仅13岁。', - guohuai:'魏国名将,夏侯渊战死时郭淮收集残兵,与杜袭共推张郃为主将而得以稳定局势。曹丕称帝后,赐郭淮爵关内侯,又任镇西长史。诸葛亮伐魏时,郭淮料敌准确,多立战功,而后亦曾击退姜维。', - manchong:'初在曹操手下任许县县令,掌管司法,以执法严格著称;转任汝南太守,开始参与军事,曾参与赤壁之战。后关羽围攻樊城,满宠协助曹仁守城,劝阻了弃城而逃的计划,成功坚持到援军到来。曹丕在位期间,满宠驻扎在新野,负责荆州侧的对吴作战。曹叡在位期间,满宠转任到扬州,接替曹休负责东侧对吴作战,屡有功劳。', - guanping:'关平是关羽在战乱中所收之义子。关羽脱离曹军后,与刘备于关定家中重逢,关定欲使年仅十八岁的关平随关羽同行,刘备便主张让关羽与关平结为义父子。自此后关平随侍在关羽身边,一生东征西讨。他武勇过人,不逊乃父,曾跟随刘备出征西川,立下战功,后来又与曹魏猛将庞德大战三十回合,不分胜负。', - jianyong:'简雍为刘备同乡,年少时与刘备相识。黄巾之乱时,刘备加入对抗黄巾军的战争,简雍便跟随他奔走。常作为谈客,往来使命,刘备围成都时简雍作为刘备使臣成功劝说刘璋投降。简雍擅于辩论、议事。性情简单直接、不拘小节。', - liufeng:'刘备义子。性格刚猛,气力过人。随赵云、张飞等扫荡西川,颇有战功,而后又统领孟达攻取上庸,深为刘备信任。但是后来关羽北伐曹魏,多次要求刘封起兵相助,刘封不从。而后又侵凌孟达,迫其降魏。孟达与魏徐晃共袭刘封,并劝刘封投降,刘封不降,又遭部下叛变,败归成都。刘备在诸葛亮的建议下赐死刘封,刘封自裁,刘备深表痛惜。', - panzhangmazhong:'马忠为潘璋部将。于麦城之战中设伏擒获关羽及关平。刘备伐吴时,马忠随潘璋等往拒,突袭射伤蜀将黄忠,导致黄忠阵亡。不久,潘璋为关兴所杀,马忠领兵围击,击退张苞援军。后降将糜、傅发动兵变,刺杀了马忠,将首级献于刘备。', - yufan:'虞翻初在会稽被太守王朗任命为功曹,曾劝谏王朗躲开孙策未果。后孙策占江东仍任命他为功曹。吕蒙袭取荆州时,虞翻提醒其躲过了埋伏,成功占领城池。后因为直言进谏被孙权发配到交州。', - zhuran:'吴国著名将领,吕蒙白衣渡江取荆州,朱然协助潘璋捉住了关羽。黄武元年,刘备兵伐东吴,朱然与孙桓抵抗刘备大军。后又参加夷陵之战,追击刘备,被前来接应的赵云一枪刺死。', - fuhuanghou:'执金吾伏完之女,汉献帝的皇后,后因怨恨曹操诛董承,与父伏完密谋曹操,事情泄漏,曹将伏皇后禁闭冷宫逼其自缢,所生二位皇子亦被鸩杀。', - liru:'董卓的首席谋士,为董卓所亲信,大小事宜皆与其商议。董卓趁乱进京、说降吕布、废立皇帝、迁都长安等举动,均离不开李儒的参谋之功,并奉命毒杀皇帝刘辩。李傕被曹操击败后,李儒从此不知所踪,消失在历史长河中。', - caozhen:'曹操族子,官至大将军、大司马。其父为曹操招募人马时被州郡所杀,曹操因怜悯曹真少年丧父而待其如亲子一般,因赞赏曹真的勇猛而让他率领虎豹骑。曹真在镇守曹魏西北边境时表现突出,魏文帝时期督众将大破羌胡联军,平定河西;魏明帝时期屡次对抗诸葛亮的北伐。', - hanhaoshihuan:'韩浩和史涣都以忠勇著称,两人皆是曹操心腹将领,共同掌管禁兵。', - chenqun:'陈群一直位居要职,先后受曹操、曹丕托孤,成为魏国重臣,官至司空。其子陈泰,亦是魏国后期名将。最大的贡献为创立了九品中正制,为后期的人才选拔和管理打好了基础。', - wuyi:'初为益州牧刘璋的部将,刘备进攻益州时,泠苞在雒城大败,吴懿自告奋勇,领兵前往救援。不料被赵云和张飞生擒,吴懿于是归降。刘备自称汉中王,迎娶吴懿之妹。诸葛亮出师北伐,吴懿以左将军、高阳侯的身份跟随出征,屡立战功。诸葛亮逝世后,吴懿随姜维一并镇守汉中。', - zhoucang:'原为张宝部将。关羽千里走单骑时,周仓投降关羽,成为了关羽的贴身护卫。建安十六年(公元211年),刘备攻打成都时,周仓跟随关羽镇守荆州。关羽水淹七军时,周仓曾生擒魏军的立义将军庞德,关羽被孙权斩首之后,周仓在麦城大哭失声,拔剑自刎而死。', - zhangsong:'刘璋的部下,长相丑陋但有过目不忘的本领。张松奉命出使许都被曹操赶出,归蜀时为刘备所厚待,于是将西川地理图献予刘备,劝刘备取益州,愿为内应,并派好友孟达、法正帮助刘备。', - sunluban:'孙权之女。孙鲁班与孙权二子孙和不睦。孙权长子孙登死后,孙和被立为太子。孙鲁班向孙权进谗言废孙和太子之位,孙和被废后忧愤而死。', - zhuhuan:'字休穆,吴郡吴县(今江苏苏州)人,吴国名将,官至前将军、青州牧,假节,封为嘉兴侯。有一子朱异。', - guyong:'为蔡邕之徒。其为人少言语,不饮酒,严厉正大,被张纮推荐仕于孙权。孙权任命他为会稽郡丞,行太守事,后不断升迁,官至吴国丞相。顾雍为官,多进良言,有功于吴。', - jushou:'袁绍帐下谋士。史载他“少有大志,擅于谋略”。曾为冀州别驾,举茂才,并当过两次县令。后来又当韩馥别驾,被韩馥表为骑都尉。袁绍占据冀州后任用沮授为从事。经常对袁绍提出良策,但很多时候袁绍并不听从。官渡之战时袁绍大败,沮授未及逃走,被曹操所获,因拒降被曹操处死。', - caifuren:'原是刘表的小妾,正室死后,成为了刘表的后妻。因刘琮娶了自己的侄女所以对其偏爱有加。刘备客居荆州时险些受其所害。刘表死后为了让刘琮即位不惜献州于曹操。', - caorui:'魏文帝曹丕长子,曹魏第二位皇帝。在位期间指挥曹真、司马懿等人成功防御了吴、蜀的多次攻伐,并且平定鲜卑,攻灭公孙渊,颇有建树。', - caoxiu:'曹操族子,曹操大宴铜雀台之时,射箭夺袍。曹休随曹操四处征伐,在攻蜀汉中之战,伐吴濡须口之战均有登场,曾放冷箭射倒凌统的马匹,后又协助夏侯惇平息洛阳纵火叛乱,总管御林兵马,协助曹丕代汉。', - zhongyao:'初为长安郡守,马超反叛时,引军攻打长安,钟繇率军防卫。后城破,钟繇从东门弃城而走,退守潼关。后奉献帝令繇草拟诏令,册立曹操为魏王,曹操以钟繇为相国。明帝即位时,钟繇为太傅。诸葛亮北伐,钟繇举荐司马懿前往抵御。', - liuchen:'刘禅第五子,自幼聪明,英敏过人。魏军兵临城下时,刘禅准备投降,刘谌劝阻刘禅投降不成后悲愤不已,遂自杀于昭烈庙。', - xiahoushi:'夏侯渊从女,夏侯霸从妹,出城拾柴时被张飞所得,取其为妻。后生有二女,其中一人为星彩。', - zhangyi:'曾随诸葛亮南征孟获,七擒孟获的战斗中立下赫赫战功,与祝融夫人单挑。诸葛亮病死五丈原,告诉姜维张嶷忠贞勇猛,经验丰富,是可以依靠的武将,后于征伐魏国时为掩护姜维撤退阵亡。', - sunxiu:'孙权第六子,孙綝发动政变罢黜孙亮后,迎立孙休为帝。后孙綝专权,孙休遣使丁奉等人将其诛杀。孙休在位期间,颁布良制,嘉惠百姓,促进了东吴的繁荣。', - zhuzhi:'孙坚旧将,朱然嗣父,孙坚阵亡后,孙策附袁术,朱治、吕范为之定计,用玉玺向袁术借兵夺取江东。孙策平定东路后,任命朱治为吴郡太守,收军返回江东。后来赤壁之战,大都督周瑜令朱治、吕范为四方巡警使,催督六郡官军。', - quancong:'吴国名将,孙策进兵江东时归顺之,深得孙权赏识,孙权甚至将孙鲁班许配之。', - gongsunyuan:'辽东太守公孙度之孙,辽东割据首领。趁魏、吴骚乱之际自称燕王,发动叛乱,与魏对抗。败给司马懿率领的讨伐大军,被围困后乞降不被接受,与子修在欲出城逃跑时被斩杀。', - guotufengji:'两人均是袁绍帐下谋士。曾联手献计,利用公孙瓒攻击韩馥,又劝说韩馥请袁绍抵挡公孙瓒,终替袁绍拿下冀州。官渡之战期间,两人进谗逼反张郃高览,逼死田丰。使得袁绍的实力大损。', - guohuanghou:'明元郭皇后(并非郭女王),在三国志有正传。曹叡夫人,曹丕的儿媳妇,曹芳,曹髦,曹奂三朝太后,是唯一经历了曹魏全部皇帝时代的贵族女性。曹魏后三帝时期,由于皇帝年少,太后与重臣一同处理政务。史书上对郭皇后有两种截然不同的记载,一种是曹芳被废和曹髦死后郭太后发诏书斥责他们不配人君,另一种却提及曹芳被夺权期间,太后与曹芳相拥而泣,曹髦讨伐司马昭前,曾向太后禀报。', - liyan:'字正方,蜀汉重臣。初为刘表部下,曹操入主荆州时,李严西奔入蜀。刘备入川,李严率众投降,深得刘备器重,受命与诸葛亮、法正等人一同编制《蜀科》,又率军平定了蜀中盗贼。白帝城托孤,与诸葛亮共受遗诏同扶幼主。其人性格矜高难近,终因督粮不利且谎报实情而被流放,后在当地去世。', - sundeng:'字子高,孙权长子。孙权称帝后其被立为太子,受诸葛恪等人辅佐。其人性情温和而能礼贤下士,加之爱民如子,因此深受爱戴。曾劝服孙权在孙虑之死时节哀,并劝谏孙权勿用吕壹苛政。后不幸早逝,临终前上书建言,推荐了多位良臣。其亡故令孙权极为悲伤,也为南鲁党争的祸乱埋下了伏笔。', - liuyu:'伯安,幽州牧,汉室宗亲。在幽州两度任职,颇有威望。张纯、张举叛乱,刘虞恩威并施将其平定,又鼓励农商,大大改善了当地经济民生,青徐二州流民纷纷前来避难。后坚拒袁绍等人立其为帝的请求,派兵迎接献帝,却为袁术所扣,并因此事激化了与公孙瓒的矛盾,最终被击败,为其所害。', - cenhun:'岑昏为宦官,官列中常侍,孙皓即位后得到宠幸。280年,晋龙骧将军王濬率军伐吴,岑昏建议以铁锁链封锁长江,阻挡晋军进攻。王濬以火船烧锁链破其计,沿途东吴将士或死或降。群臣上奏东吴衰败之因在于岑昏,将他与蜀汉的黄皓并列为误国之奸臣。', - sunziliufang:'孙资在曹操手下历任县令,参丞相军事;刘放曾有劝王松归顺曹操之举,为曹操所欣赏,遂招为司空府官,又外放历任几处县令。魏国初建之际,孙资与刘放俱任秘书郎。曹丕继位后,二人一同掌握机密。曹睿病危时,二人力荐曹爽,又推荐招回司马懿辅政。最后,曹睿独召曹爽、司马懿、刘放、孙资同受诏命,而免去曹宇、夏侯献、曹肇、秦朗的官职。', - huanghao:'宦官。为后主刘禅所宠,专秉朝政。黄皓与大将军姜维不睦,维启后主杀之,后主不从。皓阴以心腹阎宇替维。景耀六年,蜀亡,邓艾预欲杀之,皓贿赂左右得免。及后主迁洛阳,皓为司马昭凌迟处死。', - zhangrang:'汉中常侍。同赵忠、曹节、段珪等为“十常侍”,为灵帝所宠。让等专权乱政、卖官索财,朝野皆痛恨之。郎中张钧上书奏请诛杀十常侍,帝不允,让等阴杀钧。及灵帝崩,大将军何进欲杀让等,让阴结何太后,招进入宫,斩杀之。部将袁绍引兵攻让,让等劫帝走河上。追急,让投水自尽。', - jikang:'嵇康(224年-263年,一作223年-262年),字叔夜。谯国铚县(今安徽省濉溪县)人。三国时期曹魏思想家、音乐家、文学家。
              嵇康幼年聪颖,博览群书,广习诸艺,又喜爱老庄学说。身长七尺八寸,容止出众。后娶魏武帝曹操曾孙女长乐亭主为妻,拜郎中,调中散大夫,世称“嵇中散”。后隐居不仕,屡拒为官。因得罪司隶校尉钟会,遭其构陷,而被掌权的大将军司马昭处死,时年四十岁。', - xinxianying:'辛氏(191年—269年),字宪英,祖籍陇西,颍川阳翟(今河南禹州)人。魏晋时期著名才女,曹魏侍中辛毗之女,卫尉羊耽之妻。辛宪英聪朗有才鉴,曾劝弟辛敞尽忠职守,预言钟会将会叛乱。泰始五年(公元269年),辛宪英逝世,享年七十九岁。', - wuxian:'穆皇后吴氏(?—245年),陈留(今河南开封)人,车骑将军吴懿之妹,三国时期蜀汉昭烈帝刘备的皇后。
              吴氏早年丧父,其父生前与刘焉交情深厚,所以全家跟随刘焉来到蜀地。后刘焉听相面者说吴氏有大贵之相,于是为儿子刘瑁迎娶吴氏。刘瑁死后,吴氏成为寡妇。
              建安十九年(214年),刘备平定益州,纳吴氏为夫人。建安二十四年(219年),刘备自称汉中王,立吴氏为汉中王后。章武元年(221年),刘备称帝,建立蜀汉,立吴氏为皇后。章武三年(223年),刘备去世,太子刘禅即位,尊嫡母吴氏为皇太后。延熙八年(245年),吴氏去世,谥号穆皇后,葬入刘备的惠陵。', - qinmi:'秦宓(?-226年),字子敕。广汉郡绵竹县(今四川德阳北)人。三国蜀汉时大臣、学者。秦宓善舌辩。早年仕于益州牧刘璋麾下,后降刘备。刘备伐吴时,秦宓劝阻,刘备大怒,欲杀秦宓。因诸葛亮及时求情,才保住性命,仅被下狱,后被释放,拜左中郎将、长水校尉。吴蜀同盟后,孙权派张温至成都回访。酒宴之上,秦宓与张温舌战,说得张温无言以对。后官至大司农。建兴四年(226年),秦宓病逝。', - xushi:'徐氏,孙权之弟孙翊的妻子,著名烈女。孙翊的部下妫览、戴员买通家将边鸿将孙翊杀死,并将全部罪责推给边鸿,又谋杀了前来查问的太守孙河。徐夫人一面用美人计色诱妫览、戴员,令其放松警惕;一面对孙翊生前亲信孙高、傅婴说明真相并晓以大义,最终成功地在内室中将杀夫凶手妫览、戴员诛杀。', - xuezong:'薛综(?―243年),字敬文,沛郡竹邑(今安徽濉溪)人,三国时期吴国名臣。少时避乱至交州,师从刘熙。士燮归附孙权,召其为五官中郎将,出任合浦、交阯太守。后从征至九真,回朝任谒者仆射。232年,升任尚书仆射。240年,改任选曹尚书。242年,担任太子少傅,兼任选部职任。243年,薛综去世。薛综是当时名儒,著有诗赋难论数万言,集为《私载》,并著有《五宗图述》、《二京解》。', - caiyong:'蔡邕(133年-192年),字伯喈。陈留郡圉县(今河南杞县南)人。东汉时期名臣,文学家、书法家,才女蔡文姬之父。蔡邕早年拒朝廷征召之命,后被征辟为司徒掾属,任河平长、郎中、议郎等职,曾参与续写《东观汉记》及刻印熹平石经。后因罪被流放朔方,几经周折,避难江南十二年。董卓掌权时,强召蔡邕为祭酒。三日之内,历任侍御史、治书侍御史、尚书、侍中、左中郎将等职,封高阳乡侯,世称“蔡中郎”。董卓被诛杀后,蔡邕因在王允座上感叹而被下狱,不久便死于狱中,年六十。', - caojie:'曹节(196年―260年),沛国谯县(今安徽亳州)人,汉献帝刘协第二任皇后,魏武帝曹操的女儿。建安十八年(213年),曹操将女儿曹宪、曹节、曹华三姐妹同时入宫中,封为夫人。建安十九年(214年),并封为贵人。曹操废掉汉献帝第一位皇后伏寿,将她囚禁而死。曹操要汉献帝立曹节为皇后,汉献帝只得依从。建安二十五年(220年),曹操去世,曹丕袭封魏王位。曹丕授意华歆去逼汉献帝让位。曹节怒斥华歆,华歆只好退出宫去。第二天又逼汉献帝将帝位禅让给曹丕。并以武力威胁,向曹节索要玺印,曹节无奈,将玺印掷于栏板之下。面对曹丕篡位,她极为愤怒,高喊:“老天有眼,决不让你长久!”汉献帝被废为山阳公,曹节为山阳公夫人。景元元年(260年),曹节病逝,仍以汉朝礼仪合葬于献帝的禅陵,谥号献穆皇后。', + characterIntro: { + sunli: "孙礼(?—250年),字德达,涿郡容城县人。三国时期曹魏名将。曹操平定幽州后,孙礼被征召为司空军谋掾。后被任命为河间郡丞,升至荥阳都尉。后孙礼被调为鲁国相。历任山阳、平原、平昌、琅邪郡太守。从大司马曹休在夹石征吴,孙礼谏其不可深入作战,曹休不听遂战败。后孙礼调任阳平郡太守。明帝时入为尚书,受遗诏拜大将军长史,加散骑常侍。曹爽令孙礼出任扬州刺史,加管伏波将军,赐爵关内侯。孙礼率兵御东吴军队,奋不顾身,贼众乃退。朝廷赐绢七百匹,孙礼皆以绢付亡者家,无以入身。后征拜少府,出为荆州刺史,迁冀州牧。爽见礼奏,大怒,劾礼怨望,结刑五岁。在家期年,众人多以为言,除城门校尉。出为并州刺史,加振武将军,使持节,护匈奴中郎将。爽诛后,入为司隶校尉。迁司空,封大利亭侯,邑一百户。嘉平二年(250年),孙礼去世,谥号景侯。其孙孙元继承爵位。《全三国文》录有孙礼文一篇《清河平原争界案图宜属平原疏》。陈寿评曰“孙礼刚断伉厉”。", + xiahoumao: + "夏侯楙,字子林,沛国谯县(今安徽省亳州市)人,曹魏名将夏侯惇之子,三国时期魏国官员、将领,其妻为曹操之女清河公主。在魏国历任侍中、尚书、安西将军、镇东将军,假节,封列侯。曾一度驻守曹魏都城长安,但蜀汉北伐后就被调离。", + chenshi: + "陈式,生卒年不详,三国时期蜀汉将领。最初为刘备军中重要的基层指挥官,后成长为高级将领。在诸葛亮第三次北伐期间,在诸葛亮的军事指挥下攻克了魏国的武都、阴平二郡。", + feiyao: "费曜(生卒年不详),又作费瑶、费繇,三国时期曹魏将领。魏初,参与平河西之乱。明帝时官任后将军,跟随曹真、司马懿多次对抗蜀汉。《三国演义》中作“费耀”,随曹真和诸葛亮的第二次北伐军作战。怀疑姜维作内应是假,自告奋勇替曹真出征,结果被事先埋伏的姜维包围,自尽而死。", + wuanguo: + "武安国,历史小说《三国演义》中人物,是北海太守孔融的部将,兵器为一把长柄铁锤,重五十余斤。诸侯伐董时,双方于虎牢关相峙,吕布撰战,一合而斩穆顺,关东军大惊。北海太守孔融部将武安国,使铁锤飞马而出,吕布挥戟拍马来迎,战到十余合,一戟砍断安国手腕,安国弃锤于地而走,八路军兵齐出,这才救了他性命。", + hanlong: + "韩龙,汉末三国时期刺客。韩龙使得魏国北方边得到数十年的安宁,减少魏国的军政压力,得以休养生息。太和二年,豫遣译夏舍诣比能女婿郁筑鞬部,舍为鞬所杀。其秋,豫将西部鲜卑蒲头、泄归泥出塞讨郁筑鞬,大破之。还至马城,比能自将三万骑围豫七日。上谷太守阎志,阎柔之弟也,素为鲜卑所信。志往解喻,即解围去。后幽州刺史王雄并领校尉,抚以恩信。比能数款塞,诣州奉贡献。至青龙元年,比能诱纳步度根,使叛并州,与结和亲,自勒万骑迎其累重於陉北。并州刺史毕轨遣将军苏尚、董弼等击之,比能遣子将骑与尚等会战於楼烦,临陈害尚、弼。至三年中,雄遣勇士韩龙刺杀比能,更立其弟。", + liwan: "李婉(生卒年不详),字淑文,里居不详,贾充之妻,魏晋时期才女,约景元年间(260年前后)在世。著有《典戒》。《隋书·经籍志》载李婉有文集一卷,今失传。", + zhugeshang: + "诸葛尚(244年2月-263年11月),琅琊阳都(今山东沂南)人,诸葛瞻长子,诸葛亮之孙。诸葛尚博览兵书且精通武艺。炎兴元年(公元263年),出任先锋,抗拒魏国大将邓艾,与其父诸葛瞻同战死于绵竹,时年十九岁。", + kebineng: + "轲比能(?~235年),为中国三国时期的鲜卑首领之一。轲比能出身鲜卑支部,因他作战勇敢,执法公平,不贪财物,所以被鲜卑民众推举为大人。轲比能因其部落近塞,所以他抓住有利条件积极学习汉族先进技术和文化,促进了鲜卑族的进步和北方的民族融合。轲比能统率下的部众,战守有法,战斗力相当强大。自曹操北征后向曹氏进贡表示效忠。魏文帝时,轲比能受封附义王。轲比能在进行部落统一战争时,受魏国干涉,受沉重打击,于是对魏怀贰,献书魏帝表忠,以麻痹魏庭,使之放松警惕。此后,轲比能的部众变得强盛,控弦十余万骑,为害魏国边境。每次钞略得财物,轲比能都公开透明地均平分配,所以得部众死力,各部大人都敬畏之。实力强大后,他继续部落统一战争,于是威行诸部落,建立起强大的鲜卑族政权。深感威胁的魏国幽州刺史王雄派刺客韩龙将其刺杀,其政权立刻崩溃,鲜卑民族再次陷入混战。", + lukai: "陆凯(198-269年),字敬风,吴郡吴县(今江苏省苏州市)人。三国时期吴国重臣,丞相陆逊的族侄,大司马陆抗的族兄。黄武年间,举孝廉出身,曾任永兴县长、诸暨县长,颇有治绩。拜建武都尉、儋耳太守,与聂友率军讨伐朱崖和儋耳,迁建武校尉。五凤二年(255年),讨斩零陵山贼陈毖,拜偏将军、巴丘督,册封都乡侯。迁武昌右部督,随军进入寿春。后拜荡魏将军,加号绥远将军。吴景帝孙休继位,拜征北将军、假节、领豫州牧。孙皓即位,迁任镇西大将军,都督巴丘,又领荆州牧,进封嘉兴侯。宝鼎元年(266年),迁左丞相。以正直及屡次劝谏孙皓而闻名。建衡元年(269年),去世,时年七十二。", + caozhi: "字子建,沛国谯人,三国曹魏著名文学家,建安文学代表人物。魏武帝曹操之子,魏文帝曹丕之弟,生前曾为陈王,去世后谥号“思”,因此又称陈思王。南朝宋文学家谢灵运更有“天下才有一石,曹子建独占八斗”的评价。王士祯尝论汉魏以来二千年间诗家堪称“仙才”者,曹植、李白、苏轼三人耳。", + gaoshun: + "中国东汉末年将领,吕布帐下中郎将。史载高顺为人清白有威严,不好饮酒,所统率的部队精锐非常,号称“陷阵营”。屡进忠言于吕布,吕布虽知其忠而不能用。曹操击破吕布后,高顺被曹操所杀。", + chengong: + "字公台,东汉末年吕布帐下谋士,东郡东武阳人。性情刚直,足智多谋,年少时与海内知名之士相互结交。192年,陈宫等人主张曹操接任兖州牧。但此后陈宫因曹操杀害边让而与曹操反目,并游说张邈等人背叛曹操迎吕布入兖州,辅助吕布攻打曹操。吕布战败后,随吕布等一同被曹操所擒,决意赴死。", + lingtong: "字公绩,吴郡馀杭人,三国时期吴国名将。凌操之子,官至偏将军。", + masu: "字幼常,襄阳宜城人,三国时期蜀汉大臣,侍中马良之弟。初以荆州从事跟随刘备取蜀入川,曾任绵竹、成都令、越嶲太守。诸葛亮北伐时因作战失误而失守街亭,因而被诸葛亮所斩。", + wuguotai: + "吴国太,小说《三国演义》中的人物,不见于正史记载。在小说中,吴国太被描述为孙坚的次妻,孙坚正妻武烈皇后(小说中写作吴太夫人)的妹妹,孙朗、孙仁(孙尚香)的母亲。", + xusheng: + "字文向,琅邪莒县人。三国时期吴将。徐盛最初因讨伐山贼有功而被加为中郎将,后于濡须口之战中表现出色,得到孙权的赞赏。魏文帝曹丕伐吴时,徐盛以疑城之计退去魏军。", + yujin: "字文则,泰山钜平人。三国时期曹魏武将。本为鲍信部将,后属曹操,曹操称赞他可与古代名将相比。然而在建安二十四年的襄樊之战中,于禁在败给关羽后投降,致使一代名将晚节不保。", + zhangchunhua: + "西晋宣穆皇后张春华(189-247),河内平皋(今河南温县)人。她是晋宣帝司马懿之妻,晋景帝司马师、晋文帝司马昭的母亲。后被追尊为皇后。", + fazheng: + "字孝直,本为刘璋部下,刘备围成都时劝说刘璋投降,而后又与刘备进取汉中,献计将曹操大将夏侯渊斩首。法正善奇谋,深受刘备信任和敬重。", + xushu: "字元直,与司马徽、诸葛亮等人为友。先化名单福仕官于新野的刘备,后因曹操囚禁其母而不得不弃备投操,临行前向刘备推荐诸葛亮之才。入曹营后,一言不发,不曾为曹操进献过一计半策。后人形容徐庶“身在曹营心在汉”。", + caozhang: + "字子文,是曹操与武宣卞皇后所生第二子,曹丕之弟,曹植之兄,曹魏任城王。曹彰武艺过人,曹操问诸子志向时自言“好为将”,因此得到曹操的赞赏。其胡须黄色,被曹操称为“黄须儿”。", + xunyou: "字公达,颍川颍阴人。东汉末年曹操的五谋臣之一,荀彧从子,被曹操称为“谋主”。官至尚书令。正始五年被追谥为敬侯。", + liaohua: + "本名淳,字元俭,襄阳中卢(今湖北襄樊)人。三国时期蜀国后期将领,以勇敢果断著称。廖化是三国时代中经历了魏、蜀、吴整个兴衰过程极少数人中的一个,与严颜、黄忠共称为蜀汉三老将。", + bulianshi: + "步夫人(?-238),讳练师,临淮淮阴人。东吴丞相步骘同族,吴大帝孙权之妃,在孙权众夫人中最受孙权的宠爱(宠冠后庭),生有二女:孙鲁班、孙鲁育。赤乌元年卒,追封为皇后,葬于蒋陵。", + chengpu: + "字德谋,右北平土垠人。历仕孙坚、孙策、孙权三任君主。孙策死后,他与张昭等人共同辅佐孙权,并讨伐江东境内的山贼,功勋卓著。被人们尊称为“程公”。", + handang: + "字义公,辽西令支(今河北迁安)人,吴国将领。韩当因为长于弓箭、骑术并且膂力过人而被孙坚赏识,追随他四处征伐周旋,数次冒险犯难,攻陷敌人、擒拿俘虏。对江东基业的逐渐稳固和吴国的建立有着重要影响。", + liubiao: + "刘表,字景升,山阳郡高平(今山东微山)人。东汉末年名士,汉室宗亲,荆州牧,汉末群雄之一。", + zhonghui: + "字士季。魏名将,太傅钟繇之子。公元263年,他与邓艾带兵攻打蜀国,最终导致蜀国灭亡。之后钟会设计害死邓艾,联合姜维准备自立,最终因部下反叛失败,与姜维一同死于兵变。", + wangyi: "益州刺史赵昂之妻,赵英、赵月之母。马超作乱凉州时,王异协助丈夫守城,多有功勋,自马超攻冀城至祁山坚守,赵昂曾出奇计九条,王异皆有参与。", + guanzhang: + "关兴,名将关羽之子,继承了父亲汉寿亭侯的爵位。年少时即受诸葛亮器重,在蜀汉担任侍中、中监军之职,后在夷陵之战中报了杀父之仇。张苞,张飞的长子,使用父亲的家传蛇矛为兵器,勇猛剽悍不弱其父。", + madai: "名将马超的从弟。早年他曾经从曹操手中死里逃生,后跟随马超大战曹操。后在诸葛亮病逝后受杨仪派遣斩杀了蜀将魏延。曾率领军队出师北伐,被魏将牛金击败而退还。", + caochong: + "字仓舒,曹操之子。从小聪明仁爱,与众不同,深受曹操喜爱。留有“曹冲称象”的典故。曹操几次对群臣夸耀他,有让他继嗣之意。可惜曹冲在建安十三病逝,年仅13岁。", + guohuai: + "魏国名将,夏侯渊战死时郭淮收集残兵,与杜袭共推张郃为主将而得以稳定局势。曹丕称帝后,赐郭淮爵关内侯,又任镇西长史。诸葛亮伐魏时,郭淮料敌准确,多立战功,而后亦曾击退姜维。", + manchong: + "初在曹操手下任许县县令,掌管司法,以执法严格著称;转任汝南太守,开始参与军事,曾参与赤壁之战。后关羽围攻樊城,满宠协助曹仁守城,劝阻了弃城而逃的计划,成功坚持到援军到来。曹丕在位期间,满宠驻扎在新野,负责荆州侧的对吴作战。曹叡在位期间,满宠转任到扬州,接替曹休负责东侧对吴作战,屡有功劳。", + guanping: + "关平是关羽在战乱中所收之义子。关羽脱离曹军后,与刘备于关定家中重逢,关定欲使年仅十八岁的关平随关羽同行,刘备便主张让关羽与关平结为义父子。自此后关平随侍在关羽身边,一生东征西讨。他武勇过人,不逊乃父,曾跟随刘备出征西川,立下战功,后来又与曹魏猛将庞德大战三十回合,不分胜负。", + jianyong: + "简雍为刘备同乡,年少时与刘备相识。黄巾之乱时,刘备加入对抗黄巾军的战争,简雍便跟随他奔走。常作为谈客,往来使命,刘备围成都时简雍作为刘备使臣成功劝说刘璋投降。简雍擅于辩论、议事。性情简单直接、不拘小节。", + liufeng: + "刘备义子。性格刚猛,气力过人。随赵云、张飞等扫荡西川,颇有战功,而后又统领孟达攻取上庸,深为刘备信任。但是后来关羽北伐曹魏,多次要求刘封起兵相助,刘封不从。而后又侵凌孟达,迫其降魏。孟达与魏徐晃共袭刘封,并劝刘封投降,刘封不降,又遭部下叛变,败归成都。刘备在诸葛亮的建议下赐死刘封,刘封自裁,刘备深表痛惜。", + panzhangmazhong: + "马忠为潘璋部将。于麦城之战中设伏擒获关羽及关平。刘备伐吴时,马忠随潘璋等往拒,突袭射伤蜀将黄忠,导致黄忠阵亡。不久,潘璋为关兴所杀,马忠领兵围击,击退张苞援军。后降将糜、傅发动兵变,刺杀了马忠,将首级献于刘备。", + yufan: "虞翻初在会稽被太守王朗任命为功曹,曾劝谏王朗躲开孙策未果。后孙策占江东仍任命他为功曹。吕蒙袭取荆州时,虞翻提醒其躲过了埋伏,成功占领城池。后因为直言进谏被孙权发配到交州。", + zhuran: "吴国著名将领,吕蒙白衣渡江取荆州,朱然协助潘璋捉住了关羽。黄武元年,刘备兵伐东吴,朱然与孙桓抵抗刘备大军。后又参加夷陵之战,追击刘备,被前来接应的赵云一枪刺死。", + fuhuanghou: + "执金吾伏完之女,汉献帝的皇后,后因怨恨曹操诛董承,与父伏完密谋曹操,事情泄漏,曹将伏皇后禁闭冷宫逼其自缢,所生二位皇子亦被鸩杀。", + liru: "董卓的首席谋士,为董卓所亲信,大小事宜皆与其商议。董卓趁乱进京、说降吕布、废立皇帝、迁都长安等举动,均离不开李儒的参谋之功,并奉命毒杀皇帝刘辩。李傕被曹操击败后,李儒从此不知所踪,消失在历史长河中。", + caozhen: + "曹操族子,官至大将军、大司马。其父为曹操招募人马时被州郡所杀,曹操因怜悯曹真少年丧父而待其如亲子一般,因赞赏曹真的勇猛而让他率领虎豹骑。曹真在镇守曹魏西北边境时表现突出,魏文帝时期督众将大破羌胡联军,平定河西;魏明帝时期屡次对抗诸葛亮的北伐。", + hanhaoshihuan: "韩浩和史涣都以忠勇著称,两人皆是曹操心腹将领,共同掌管禁兵。", + chenqun: + "陈群一直位居要职,先后受曹操、曹丕托孤,成为魏国重臣,官至司空。其子陈泰,亦是魏国后期名将。最大的贡献为创立了九品中正制,为后期的人才选拔和管理打好了基础。", + wuyi: "初为益州牧刘璋的部将,刘备进攻益州时,泠苞在雒城大败,吴懿自告奋勇,领兵前往救援。不料被赵云和张飞生擒,吴懿于是归降。刘备自称汉中王,迎娶吴懿之妹。诸葛亮出师北伐,吴懿以左将军、高阳侯的身份跟随出征,屡立战功。诸葛亮逝世后,吴懿随姜维一并镇守汉中。", + zhoucang: + "原为张宝部将。关羽千里走单骑时,周仓投降关羽,成为了关羽的贴身护卫。建安十六年(公元211年),刘备攻打成都时,周仓跟随关羽镇守荆州。关羽水淹七军时,周仓曾生擒魏军的立义将军庞德,关羽被孙权斩首之后,周仓在麦城大哭失声,拔剑自刎而死。", + zhangsong: + "刘璋的部下,长相丑陋但有过目不忘的本领。张松奉命出使许都被曹操赶出,归蜀时为刘备所厚待,于是将西川地理图献予刘备,劝刘备取益州,愿为内应,并派好友孟达、法正帮助刘备。", + sunluban: + "孙权之女。孙鲁班与孙权二子孙和不睦。孙权长子孙登死后,孙和被立为太子。孙鲁班向孙权进谗言废孙和太子之位,孙和被废后忧愤而死。", + zhuhuan: + "字休穆,吴郡吴县(今江苏苏州)人,吴国名将,官至前将军、青州牧,假节,封为嘉兴侯。有一子朱异。", + guyong: "为蔡邕之徒。其为人少言语,不饮酒,严厉正大,被张纮推荐仕于孙权。孙权任命他为会稽郡丞,行太守事,后不断升迁,官至吴国丞相。顾雍为官,多进良言,有功于吴。", + jushou: "袁绍帐下谋士。史载他“少有大志,擅于谋略”。曾为冀州别驾,举茂才,并当过两次县令。后来又当韩馥别驾,被韩馥表为骑都尉。袁绍占据冀州后任用沮授为从事。经常对袁绍提出良策,但很多时候袁绍并不听从。官渡之战时袁绍大败,沮授未及逃走,被曹操所获,因拒降被曹操处死。", + caifuren: + "原是刘表的小妾,正室死后,成为了刘表的后妻。因刘琮娶了自己的侄女所以对其偏爱有加。刘备客居荆州时险些受其所害。刘表死后为了让刘琮即位不惜献州于曹操。", + caorui: "魏文帝曹丕长子,曹魏第二位皇帝。在位期间指挥曹真、司马懿等人成功防御了吴、蜀的多次攻伐,并且平定鲜卑,攻灭公孙渊,颇有建树。", + caoxiu: "曹操族子,曹操大宴铜雀台之时,射箭夺袍。曹休随曹操四处征伐,在攻蜀汉中之战,伐吴濡须口之战均有登场,曾放冷箭射倒凌统的马匹,后又协助夏侯惇平息洛阳纵火叛乱,总管御林兵马,协助曹丕代汉。", + zhongyao: + "初为长安郡守,马超反叛时,引军攻打长安,钟繇率军防卫。后城破,钟繇从东门弃城而走,退守潼关。后奉献帝令繇草拟诏令,册立曹操为魏王,曹操以钟繇为相国。明帝即位时,钟繇为太傅。诸葛亮北伐,钟繇举荐司马懿前往抵御。", + liuchen: + "刘禅第五子,自幼聪明,英敏过人。魏军兵临城下时,刘禅准备投降,刘谌劝阻刘禅投降不成后悲愤不已,遂自杀于昭烈庙。", + xiahoushi: "夏侯渊从女,夏侯霸从妹,出城拾柴时被张飞所得,取其为妻。后生有二女,其中一人为星彩。", + zhangyi: + "曾随诸葛亮南征孟获,七擒孟获的战斗中立下赫赫战功,与祝融夫人单挑。诸葛亮病死五丈原,告诉姜维张嶷忠贞勇猛,经验丰富,是可以依靠的武将,后于征伐魏国时为掩护姜维撤退阵亡。", + sunxiu: "孙权第六子,孙綝发动政变罢黜孙亮后,迎立孙休为帝。后孙綝专权,孙休遣使丁奉等人将其诛杀。孙休在位期间,颁布良制,嘉惠百姓,促进了东吴的繁荣。", + zhuzhi: "孙坚旧将,朱然嗣父,孙坚阵亡后,孙策附袁术,朱治、吕范为之定计,用玉玺向袁术借兵夺取江东。孙策平定东路后,任命朱治为吴郡太守,收军返回江东。后来赤壁之战,大都督周瑜令朱治、吕范为四方巡警使,催督六郡官军。", + quancong: "吴国名将,孙策进兵江东时归顺之,深得孙权赏识,孙权甚至将孙鲁班许配之。", + gongsunyuan: + "辽东太守公孙度之孙,辽东割据首领。趁魏、吴骚乱之际自称燕王,发动叛乱,与魏对抗。败给司马懿率领的讨伐大军,被围困后乞降不被接受,与子修在欲出城逃跑时被斩杀。", + guotufengji: + "两人均是袁绍帐下谋士。曾联手献计,利用公孙瓒攻击韩馥,又劝说韩馥请袁绍抵挡公孙瓒,终替袁绍拿下冀州。官渡之战期间,两人进谗逼反张郃高览,逼死田丰。使得袁绍的实力大损。", + guohuanghou: + "明元郭皇后(并非郭女王),在三国志有正传。曹叡夫人,曹丕的儿媳妇,曹芳,曹髦,曹奂三朝太后,是唯一经历了曹魏全部皇帝时代的贵族女性。曹魏后三帝时期,由于皇帝年少,太后与重臣一同处理政务。史书上对郭皇后有两种截然不同的记载,一种是曹芳被废和曹髦死后郭太后发诏书斥责他们不配人君,另一种却提及曹芳被夺权期间,太后与曹芳相拥而泣,曹髦讨伐司马昭前,曾向太后禀报。", + liyan: "字正方,蜀汉重臣。初为刘表部下,曹操入主荆州时,李严西奔入蜀。刘备入川,李严率众投降,深得刘备器重,受命与诸葛亮、法正等人一同编制《蜀科》,又率军平定了蜀中盗贼。白帝城托孤,与诸葛亮共受遗诏同扶幼主。其人性格矜高难近,终因督粮不利且谎报实情而被流放,后在当地去世。", + sundeng: + "字子高,孙权长子。孙权称帝后其被立为太子,受诸葛恪等人辅佐。其人性情温和而能礼贤下士,加之爱民如子,因此深受爱戴。曾劝服孙权在孙虑之死时节哀,并劝谏孙权勿用吕壹苛政。后不幸早逝,临终前上书建言,推荐了多位良臣。其亡故令孙权极为悲伤,也为南鲁党争的祸乱埋下了伏笔。", + liuyu: "伯安,幽州牧,汉室宗亲。在幽州两度任职,颇有威望。张纯、张举叛乱,刘虞恩威并施将其平定,又鼓励农商,大大改善了当地经济民生,青徐二州流民纷纷前来避难。后坚拒袁绍等人立其为帝的请求,派兵迎接献帝,却为袁术所扣,并因此事激化了与公孙瓒的矛盾,最终被击败,为其所害。", + cenhun: "岑昏为宦官,官列中常侍,孙皓即位后得到宠幸。280年,晋龙骧将军王濬率军伐吴,岑昏建议以铁锁链封锁长江,阻挡晋军进攻。王濬以火船烧锁链破其计,沿途东吴将士或死或降。群臣上奏东吴衰败之因在于岑昏,将他与蜀汉的黄皓并列为误国之奸臣。", + sunziliufang: + "孙资在曹操手下历任县令,参丞相军事;刘放曾有劝王松归顺曹操之举,为曹操所欣赏,遂招为司空府官,又外放历任几处县令。魏国初建之际,孙资与刘放俱任秘书郎。曹丕继位后,二人一同掌握机密。曹睿病危时,二人力荐曹爽,又推荐招回司马懿辅政。最后,曹睿独召曹爽、司马懿、刘放、孙资同受诏命,而免去曹宇、夏侯献、曹肇、秦朗的官职。", + huanghao: + "宦官。为后主刘禅所宠,专秉朝政。黄皓与大将军姜维不睦,维启后主杀之,后主不从。皓阴以心腹阎宇替维。景耀六年,蜀亡,邓艾预欲杀之,皓贿赂左右得免。及后主迁洛阳,皓为司马昭凌迟处死。", + zhangrang: + "汉中常侍。同赵忠、曹节、段珪等为“十常侍”,为灵帝所宠。让等专权乱政、卖官索财,朝野皆痛恨之。郎中张钧上书奏请诛杀十常侍,帝不允,让等阴杀钧。及灵帝崩,大将军何进欲杀让等,让阴结何太后,招进入宫,斩杀之。部将袁绍引兵攻让,让等劫帝走河上。追急,让投水自尽。", + jikang: "嵇康(224年-263年,一作223年-262年),字叔夜。谯国铚县(今安徽省濉溪县)人。三国时期曹魏思想家、音乐家、文学家。
              嵇康幼年聪颖,博览群书,广习诸艺,又喜爱老庄学说。身长七尺八寸,容止出众。后娶魏武帝曹操曾孙女长乐亭主为妻,拜郎中,调中散大夫,世称“嵇中散”。后隐居不仕,屡拒为官。因得罪司隶校尉钟会,遭其构陷,而被掌权的大将军司马昭处死,时年四十岁。", + xinxianying: + "辛氏(191年—269年),字宪英,祖籍陇西,颍川阳翟(今河南禹州)人。魏晋时期著名才女,曹魏侍中辛毗之女,卫尉羊耽之妻。辛宪英聪朗有才鉴,曾劝弟辛敞尽忠职守,预言钟会将会叛乱。泰始五年(公元269年),辛宪英逝世,享年七十九岁。", + wuxian: "穆皇后吴氏(?—245年),陈留(今河南开封)人,车骑将军吴懿之妹,三国时期蜀汉昭烈帝刘备的皇后。
              吴氏早年丧父,其父生前与刘焉交情深厚,所以全家跟随刘焉来到蜀地。后刘焉听相面者说吴氏有大贵之相,于是为儿子刘瑁迎娶吴氏。刘瑁死后,吴氏成为寡妇。
              建安十九年(214年),刘备平定益州,纳吴氏为夫人。建安二十四年(219年),刘备自称汉中王,立吴氏为汉中王后。章武元年(221年),刘备称帝,建立蜀汉,立吴氏为皇后。章武三年(223年),刘备去世,太子刘禅即位,尊嫡母吴氏为皇太后。延熙八年(245年),吴氏去世,谥号穆皇后,葬入刘备的惠陵。", + qinmi: "秦宓(?-226年),字子敕。广汉郡绵竹县(今四川德阳北)人。三国蜀汉时大臣、学者。秦宓善舌辩。早年仕于益州牧刘璋麾下,后降刘备。刘备伐吴时,秦宓劝阻,刘备大怒,欲杀秦宓。因诸葛亮及时求情,才保住性命,仅被下狱,后被释放,拜左中郎将、长水校尉。吴蜀同盟后,孙权派张温至成都回访。酒宴之上,秦宓与张温舌战,说得张温无言以对。后官至大司农。建兴四年(226年),秦宓病逝。", + xushi: "徐氏,孙权之弟孙翊的妻子,著名烈女。孙翊的部下妫览、戴员买通家将边鸿将孙翊杀死,并将全部罪责推给边鸿,又谋杀了前来查问的太守孙河。徐夫人一面用美人计色诱妫览、戴员,令其放松警惕;一面对孙翊生前亲信孙高、傅婴说明真相并晓以大义,最终成功地在内室中将杀夫凶手妫览、戴员诛杀。", + xuezong: + "薛综(?―243年),字敬文,沛郡竹邑(今安徽濉溪)人,三国时期吴国名臣。少时避乱至交州,师从刘熙。士燮归附孙权,召其为五官中郎将,出任合浦、交阯太守。后从征至九真,回朝任谒者仆射。232年,升任尚书仆射。240年,改任选曹尚书。242年,担任太子少傅,兼任选部职任。243年,薛综去世。薛综是当时名儒,著有诗赋难论数万言,集为《私载》,并著有《五宗图述》、《二京解》。", + caiyong: + "蔡邕(133年-192年),字伯喈。陈留郡圉县(今河南杞县南)人。东汉时期名臣,文学家、书法家,才女蔡文姬之父。蔡邕早年拒朝廷征召之命,后被征辟为司徒掾属,任河平长、郎中、议郎等职,曾参与续写《东观汉记》及刻印熹平石经。后因罪被流放朔方,几经周折,避难江南十二年。董卓掌权时,强召蔡邕为祭酒。三日之内,历任侍御史、治书侍御史、尚书、侍中、左中郎将等职,封高阳乡侯,世称“蔡中郎”。董卓被诛杀后,蔡邕因在王允座上感叹而被下狱,不久便死于狱中,年六十。", + caojie: "曹节(196年―260年),沛国谯县(今安徽亳州)人,汉献帝刘协第二任皇后,魏武帝曹操的女儿。建安十八年(213年),曹操将女儿曹宪、曹节、曹华三姐妹同时入宫中,封为夫人。建安十九年(214年),并封为贵人。曹操废掉汉献帝第一位皇后伏寿,将她囚禁而死。曹操要汉献帝立曹节为皇后,汉献帝只得依从。建安二十五年(220年),曹操去世,曹丕袭封魏王位。曹丕授意华歆去逼汉献帝让位。曹节怒斥华歆,华歆只好退出宫去。第二天又逼汉献帝将帝位禅让给曹丕。并以武力威胁,向曹节索要玺印,曹节无奈,将玺印掷于栏板之下。面对曹丕篡位,她极为愤怒,高喊:“老天有眼,决不让你长久!”汉献帝被废为山阳公,曹节为山阳公夫人。景元元年(260年),曹节病逝,仍以汉朝礼仪合葬于献帝的禅陵,谥号献穆皇后。", }, - perfectPair:{ - wuguotai:['sunjian','sunshangxiang'], - zhangchunhua:['simayi'], - caozhi:['zhenji'], - xunyou:['xunyu'], - xushu:['liubei'], - lingtong:['ganning'], - chengong:['lvbu'], - bulianshi:['sunquan'], - fuhuanghou:['liuxie'], - sunluban:['quancong'], - caifuren:['liubiao'], - xiahoushi:['zhangfei'], - zhoucang:['guanyu'], - guanping:['guanyu'], - sundeng:['sunquan','zhoufei'], - liru:['dongzhuo'], - liuchen:['liushan'], - yujin:['xiahoudun'], - fazheng:['liubei'], - zhonghui:['jiangwei'], + perfectPair: { + wuguotai: ["sunjian", "sunshangxiang"], + zhangchunhua: ["simayi"], + caozhi: ["zhenji"], + xunyou: ["xunyu"], + xushu: ["liubei"], + lingtong: ["ganning"], + chengong: ["lvbu"], + bulianshi: ["sunquan"], + fuhuanghou: ["liuxie"], + sunluban: ["quancong"], + caifuren: ["liubiao"], + xiahoushi: ["zhangfei"], + zhoucang: ["guanyu"], + guanping: ["guanyu"], + sundeng: ["sunquan", "zhoufei"], + liru: ["dongzhuo"], + liuchen: ["liushan"], + yujin: ["xiahoudun"], + fazheng: ["liubei"], + zhonghui: ["jiangwei"], }, - skill:{ + skill: { //一将2023 //孙礼 - kangli:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + kangli: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - locked:false, - content:function(){ - player.draw(2).gaintag=['kangli']; - player.when({source:'damageBegin1'}) - .then(()=>{ - var cards=player.getCards('h',card=>card.hasGaintag('kangli')&&lib.filter.cardDiscardable(card,player,'kangli')); - if(cards.length) player.discard(cards); - }) + forced: true, + locked: false, + content: function () { + player.draw(2).gaintag = ["kangli"]; + player.when({ source: "damageBegin1" }).then(() => { + var cards = player.getCards( + "h", + (card) => + card.hasGaintag("kangli") && + lib.filter.cardDiscardable(card, player, "kangli") + ); + if (cards.length) player.discard(cards); + }); + }, + ai: { + maixie: true, }, - ai:{ - maixie:true, - } }, //夏侯楙 - tongwei:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he',card=>lib.skill.tongwei.filterCard(card,player))>1&&game.hasPlayer(i=>i!=player); + tongwei: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he", (card) => lib.skill.tongwei.filterCard(card, player)) > 1 && + game.hasPlayer((i) => i != player) + ); }, - filterTarget:lib.filter.notMe, - filterCard:lib.filter.cardRecastable, - selectCard:2, - position:'he', - discard:false, - lose:false, - delay:false, - popname:true, - check:function(card){ - var num=6.5; - if(ui.selected.cards.length){ - var cardx=ui.selected.cards[0]; - num=get.number(cardx); + filterTarget: lib.filter.notMe, + filterCard: lib.filter.cardRecastable, + selectCard: 2, + position: "he", + discard: false, + lose: false, + delay: false, + popname: true, + check: function (card) { + var num = 6.5; + if (ui.selected.cards.length) { + var cardx = ui.selected.cards[0]; + num = get.number(cardx); } - var del=Math.abs(get.number(card)-num); - return 5+del/5-get.value(card); + var del = Math.abs(get.number(card) - num); + return 5 + del / 5 - get.value(card); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.recast(cards); - 'step 1' - var numbers=cards.map(c=>get.number(c,player)).sort((a,b)=>a-b); - target.when('useCard1') - .then(()=>{ - trigger._tongwei_checked=true; - }) - target.when('useCardAfter') + "step 1"; + var numbers = cards.map((c) => get.number(c, player)).sort((a, b) => a - b); + target.when("useCard1").then(() => { + trigger._tongwei_checked = true; + }); + target + .when("useCardAfter") .assign({ - numbers:numbers, - playerx:player, - mod:{ - aiOrder:function(player,card,num){ - var number=get.number(card); - if(typeof number!='number'||number<=numbers[0]||number>=numbers[1]) return num+10; + numbers: numbers, + playerx: player, + mod: { + aiOrder: function (player, card, num) { + var number = get.number(card); + if ( + typeof number != "number" || + number <= numbers[0] || + number >= numbers[1] + ) + return num + 10; }, }, }) - .filter((event,player)=>{ + .filter((event, player) => { return event._tongwei_checked; }) - .then(()=>{ - var number=get.number(trigger.card); - var numbers=get.info(event.name).numbers; - event.playerx=get.info(event.name).playerx; - if(typeof number!='number'||number<=numbers[0]||number>=numbers[1]) event.finish(); + .then(() => { + var number = get.number(trigger.card); + var numbers = get.info(event.name).numbers; + event.playerx = get.info(event.name).playerx; + if (typeof number != "number" || number <= numbers[0] || number >= numbers[1]) + event.finish(); }) - .then(()=>{ - var playerx=event.playerx; - var names=['sha','guohe'].filter(name=>playerx.canUse({name:name,isCard:true},player,false)); - if(!names.length) event.finish(); - else if(names.length==1) event._result={links:[[null,null,names[0]]]}; - else playerx.chooseButton([ - `请选择要视为对${get.translation(player)}使用的牌`, - [names,'vcard'], - ],true).set('ai',(button)=>{ - return button.link[0][2]==_status.event.choice; - }).set('choice',function(){ - var list=names.map(name=>{ - return [name,get.effect(player,{name:name,isCard:true},playerx,playerx)]; - }).sort((a,b)=>{ - return b[1]-a[1]; - }); - return list[0][0]; - }()); - }) - .then(()=>{ - var name=result.links[0][2]; - var card={name:name,isCard:true},playerx=event.playerx; - if(playerx.canUse(card,player,false)) playerx.useCard(card,player,'tongwei'); + .then(() => { + var playerx = event.playerx; + var names = ["sha", "guohe"].filter((name) => + playerx.canUse({ name: name, isCard: true }, player, false) + ); + if (!names.length) event.finish(); + else if (names.length == 1) event._result = { links: [[null, null, names[0]]] }; + else + playerx + .chooseButton( + [ + `请选择要视为对${get.translation(player)}使用的牌`, + [names, "vcard"], + ], + true + ) + .set("ai", (button) => { + return button.link[0][2] == _status.event.choice; + }) + .set( + "choice", + (function () { + var list = names + .map((name) => { + return [ + name, + get.effect( + player, + { name: name, isCard: true }, + playerx, + playerx + ), + ]; + }) + .sort((a, b) => { + return b[1] - a[1]; + }); + return list[0][0]; + })() + ); }) + .then(() => { + var name = result.links[0][2]; + var card = { name: name, isCard: true }, + playerx = event.playerx; + if (playerx.canUse(card, player, false)) playerx.useCard(card, player, "tongwei"); + }); }, - ai:{ - expose:0.2, - order:7, - threaten:2.2, - result:{ - target:-1, + ai: { + expose: 0.2, + order: 7, + threaten: 2.2, + result: { + target: -1, }, }, }, - cuguo:{ - audio:2, - trigger:{player:['shaMiss','eventNeutralized']}, - filter:function(event,player){ - if(event.type!='card'&&event.name!='_wuxie') return false; - if(!event.target||!event.target.isIn()||!player.canUse({ - name:event.card.name, - nature:event.card.nature, - isCard:true, - },event.target,false)) return false; - if(!player.hasCard(card=>lib.filter.cardDiscardable(card,player),'he')) return false; - var history=game.getGlobalHistory('everything'); - for(var evt of history){ - if(evt._neutralized||evt.responded&&(!evt.result||!evt.result.bool)){ - var evtx=evt.getParent(); - return evtx.name=='useCard'&&evtx.player==player&&evt==event; + cuguo: { + audio: 2, + trigger: { player: ["shaMiss", "eventNeutralized"] }, + filter: function (event, player) { + if (event.type != "card" && event.name != "_wuxie") return false; + if ( + !event.target || + !event.target.isIn() || + !player.canUse( + { + name: event.card.name, + nature: event.card.nature, + isCard: true, + }, + event.target, + false + ) + ) + return false; + if (!player.hasCard((card) => lib.filter.cardDiscardable(card, player), "he")) + return false; + var history = game.getGlobalHistory("everything"); + for (var evt of history) { + if (evt._neutralized || (evt.responded && (!evt.result || !evt.result.bool))) { + var evtx = evt.getParent(); + return evtx.name == "useCard" && evtx.player == player && evt == event; } } return false; }, - forced:true, - direct:true, - content:function(){ - 'step 0' - var card={ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - storage:{cuguo:true}, + forced: true, + direct: true, + content: function () { + "step 0"; + var card = { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, + storage: { cuguo: true }, }; - event.card=card; - player.chooseToDiscard('蹙国:请弃置一张牌',`视为你对${get.translation(trigger.target)}使用一张${get.translation(card.nature||'')}【${get.translation(card.name)}】`,'he',true).set('logSkill',['cuguo',trigger.target]); - 'step 1' - if(player.canUse(card,trigger.target,false)){ - player.useCard(card,trigger.target); - player.when('useCardAfter') - .filter(event=>{ - return event.card.storage&&event.card.storage.cuguo; + event.card = card; + player + .chooseToDiscard( + "蹙国:请弃置一张牌", + `视为你对${get.translation(trigger.target)}使用一张${get.translation( + card.nature || "" + )}【${get.translation(card.name)}】`, + "he", + true + ) + .set("logSkill", ["cuguo", trigger.target]); + "step 1"; + if (player.canUse(card, trigger.target, false)) { + player.useCard(card, trigger.target); + player + .when("useCardAfter") + .filter((event) => { + return event.card.storage && event.card.storage.cuguo; }) - .then(()=>{ - if(game.hasGlobalHistory('everything',evt=>{ - if(evt._neutralized||evt.responded&&(!evt.result||!evt.result.bool)){ - if(evt.getParent()==trigger) return true; - } - return false; - })){ + .then(() => { + if ( + game.hasGlobalHistory("everything", (evt) => { + if ( + evt._neutralized || + (evt.responded && (!evt.result || !evt.result.bool)) + ) { + if (evt.getParent() == trigger) return true; + } + return false; + }) + ) { player.loseHp(); } - }) + }); } - } + }, }, //陈式 - qingbei:{ - audio:2, - trigger:{global:'roundStart'}, - direct:true, - content:function(){ - 'step 0' - var next=player.chooseButton(['###擎北:是否选择任意种花色?###
              你不能于本轮能使用这些花色,且使用牌后摸等同于选择花色数的牌
              ',[lib.suit.map(i=>['','','lukai_'+i]),'vcard']],[1,4]); - next.set('ai',button=>{ - var player=_status.event.player; - var suit=button.link[2].slice(6); - var val=player.getCards('hs',{suit:suit}).map(card=>{ - return get.value(card)+player.getUseValue(card)/3; - }).reduce((p,c)=>{ - return p+c; - },0); - if(val>10&&ui.selected.buttons.length>0) return -1; - if(val>6&&ui.selected.buttons.length==2) return -1; - if(ui.selected.buttons.length==3) return -1; - return 1+1/val; + qingbei: { + audio: 2, + trigger: { global: "roundStart" }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseButton( + [ + '###擎北:是否选择任意种花色?###
              你不能于本轮能使用这些花色,且使用牌后摸等同于选择花色数的牌
              ', + [lib.suit.map((i) => ["", "", "lukai_" + i]), "vcard"], + ], + [1, 4] + ); + next.set("ai", (button) => { + var player = _status.event.player; + var suit = button.link[2].slice(6); + var val = player + .getCards("hs", { suit: suit }) + .map((card) => { + return get.value(card) + player.getUseValue(card) / 3; + }) + .reduce((p, c) => { + return p + c; + }, 0); + if (val > 10 && ui.selected.buttons.length > 0) return -1; + if (val > 6 && ui.selected.buttons.length == 2) return -1; + if (ui.selected.buttons.length == 3) return -1; + return 1 + 1 / val; }); - 'step 1' - if(result.bool){ - var suits=result.links.map(i=>i[2].slice(6)); - player.logSkill('qingbei'); - player.addTempSkill('qingbei_effect','roundStart'); - player.setStorage('qingbei_effect',suits); - player.markSkill('qingbei_effect'); + "step 1"; + if (result.bool) { + var suits = result.links.map((i) => i[2].slice(6)); + player.logSkill("qingbei"); + player.addTempSkill("qingbei_effect", "roundStart"); + player.setStorage("qingbei_effect", suits); + player.markSkill("qingbei_effect"); } }, - ai:{ - threaten:2.3, + ai: { + threaten: 2.3, }, - subSkill:{ - effect:{ - audio:'qingbei', - trigger:{player:'useCardAfter'}, - charlotte:true, - onremove:true, - forced:true, - filter:function(event,player){ - if(!lib.suit.includes(get.suit(event.card))) return false; - return player.getStorage('qingbei_effect').length; + subSkill: { + effect: { + audio: "qingbei", + trigger: { player: "useCardAfter" }, + charlotte: true, + onremove: true, + forced: true, + filter: function (event, player) { + if (!lib.suit.includes(get.suit(event.card))) return false; + return player.getStorage("qingbei_effect").length; }, - content:function(){ - player.draw(player.getStorage('qingbei_effect').length); + content: function () { + player.draw(player.getStorage("qingbei_effect").length); }, - mark:true, - intro:{ - content:(storage)=>`本轮内不能使用${get.translation(storage)}花色的牌,且使用一张有花色的牌后摸${get.cnNumber(storage.length)}张牌`, + mark: true, + intro: { + content: (storage) => + `本轮内不能使用${get.translation( + storage + )}花色的牌,且使用一张有花色的牌后摸${get.cnNumber(storage.length)}张牌`, }, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('qingbei_effect').includes(get.suit(card))) return false; + mod: { + cardEnabled: function (card, player) { + if (player.getStorage("qingbei_effect").includes(get.suit(card))) + return false; }, - cardSavable:function(card,player){ - if(player.getStorage('qingbei_effect').includes(get.suit(card))) return false; + cardSavable: function (card, player) { + if (player.getStorage("qingbei_effect").includes(get.suit(card))) + return false; }, }, - } - } + }, + }, }, //费曜 - zhenfeng:{ - audio:2, - trigger:{global:'useCard'}, - usable:1, - filter:function(event,player){ - return event.player!=player&&event.player==_status.currentPhase&&event.player.countCards('h')<=event.player.getHp(); + zhenfeng: { + audio: 2, + trigger: { global: "useCard" }, + usable: 1, + filter: function (event, player) { + return ( + event.player != player && + event.player == _status.currentPhase && + event.player.countCards("h") <= event.player.getHp() + ); }, - check:function(event,player){ - var type=get.type2(event.card,event.player); - if(type=='equip'&&event.player.hasCard(card=>event.player.hasValueTarget(card))) return false; - if(get.attitude(player,event.player)>0&&event.player.getHp()+event.player.countCards('hs',['shan','caochuan'])<=3) return false; + check: function (event, player) { + var type = get.type2(event.card, event.player); + if (type == "equip" && event.player.hasCard((card) => event.player.hasValueTarget(card))) + return false; + if ( + get.attitude(player, event.player) > 0 && + event.player.getHp() + event.player.countCards("hs", ["shan", "caochuan"]) <= 3 + ) + return false; return true; }, - onremove:true, - logTarget:'player', - content:function(){ - 'step 0' - var choices=Array.from({length:trigger.player.countCards('h')+1}).map((_,i)=>get.cnNumber(i,true)); - var type=get.type2(trigger.card,trigger.player); - player.chooseControl(choices).set('prompt','镇锋:猜测其手牌中的'+get.translation(type)+'牌数').set('ai',()=>{ - return _status.event.choice; - }).set('choice',function(){ - var num=trigger.player.countCards('h',card=>get.type2(card)==type); - var knownNum = trigger.player.countKnownCards(_status.event.player,card=>get.type2(card)==type); - if(trigger.player.isAllCardsKnown(_status.event.player)){ - return knownNum; - } - var restNum = num - knownNum; - var numx; - if(type=='basic') numx=num+Math.floor(Math.random()*restNum+1); - else if(type=='trick'){ - if(num>2) numx=2; - else numx=1; - if(Math.random()<0.5){ - numx+=Math.random()>0.5?1:-1; - } - } - else{ - numx=[0,1].randomGet(); - } - if(numx=choices.length) numx=choices.length-1; - return numx; - }()); - 'step 1' - var guessedNum=result.index; - player.chat('我猜'+get.cnNumber(guessedNum)+'张'); - game.log(player,'猜测',trigger.player,'有',get.cnNumber(guessedNum)+'张'+get.translation(type)+'牌'); - event.guessedNum=guessedNum; + onremove: true, + logTarget: "player", + content: function () { + "step 0"; + var choices = Array.from({ length: trigger.player.countCards("h") + 1 }).map((_, i) => + get.cnNumber(i, true) + ); + var type = get.type2(trigger.card, trigger.player); + player + .chooseControl(choices) + .set("prompt", "镇锋:猜测其手牌中的" + get.translation(type) + "牌数") + .set("ai", () => { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var num = trigger.player.countCards("h", (card) => get.type2(card) == type); + var knownNum = trigger.player.countKnownCards( + _status.event.player, + (card) => get.type2(card) == type + ); + if (trigger.player.isAllCardsKnown(_status.event.player)) { + return knownNum; + } + var restNum = num - knownNum; + var numx; + if (type == "basic") numx = num + Math.floor(Math.random() * restNum + 1); + else if (type == "trick") { + if (num > 2) numx = 2; + else numx = 1; + if (Math.random() < 0.5) { + numx += Math.random() > 0.5 ? 1 : -1; + } + } else { + numx = [0, 1].randomGet(); + } + if (numx < knownNum) numx = knownNum; + else if (numx >= choices.length) numx = choices.length - 1; + return numx; + })() + ); + "step 1"; + var guessedNum = result.index; + player.chat("我猜" + get.cnNumber(guessedNum) + "张"); + game.log( + player, + "猜测", + trigger.player, + "有", + get.cnNumber(guessedNum) + "张" + get.translation(type) + "牌" + ); + event.guessedNum = guessedNum; game.delay(); - 'step 2' - var type=get.type2(trigger.card,trigger.player); - var count=trigger.player.countCards('h',card=>get.type2(card)==type); - var guessedNum=event.guessedNum; - if(count==guessedNum){ - player.popup('洗具'); - game.log(player,'猜测','#g正确'); - if(player.countMark('zhenfeng')<5) player.addMark('zhenfeng',1,false); - player.draw(player.countMark('zhenfeng')); - if(player.canUse('sha',trigger.player,false)) player.useCard({name:'sha',isCard:true},trigger.player); - } - else{ - player.popup('杯具'); - game.log(player,'猜测','#y错误'); - player.clearMark('zhenfeng'); - if(Math.abs(count-guessedNum)>1&&trigger.player.canUse('sha',player,false)){ - trigger.player.useCard({name:'sha',isCard:true},player,false,'noai'); + "step 2"; + var type = get.type2(trigger.card, trigger.player); + var count = trigger.player.countCards("h", (card) => get.type2(card) == type); + var guessedNum = event.guessedNum; + if (count == guessedNum) { + player.popup("洗具"); + game.log(player, "猜测", "#g正确"); + if (player.countMark("zhenfeng") < 5) player.addMark("zhenfeng", 1, false); + player.draw(player.countMark("zhenfeng")); + if (player.canUse("sha", trigger.player, false)) + player.useCard({ name: "sha", isCard: true }, trigger.player); + } else { + player.popup("杯具"); + game.log(player, "猜测", "#y错误"); + player.clearMark("zhenfeng"); + if (Math.abs(count - guessedNum) > 1 && trigger.player.canUse("sha", player, false)) { + trigger.player.useCard({ name: "sha", isCard: true }, player, false, "noai"); } } }, - intro:{ - content:'已连续猜对#次', + intro: { + content: "已连续猜对#次", }, }, //新杀小加强 李严 - dcduliang:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('he')>0; + dcduliang: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("he") > 0; }, - audio:'duliang', - content:function(){ - 'step 0' - player.gainPlayerCard(target,'he',true); - 'step 1' - var name=get.translation(target); - player.chooseControl(function(){ - return Math.random()<0.5?'选项一':'选项二'; - }).set('prompt','督粮:请选择一项').set('choiceList',['你观看牌堆顶的两张牌,然后令'+name+'获得其中的一或两张基本牌','令'+name+'于下回合的摸牌阶段额外摸一张牌']); - 'step 2' - if(result.control=='选项一'){ - var cards=get.cards(2),bool=false; - event.cards=cards; + audio: "duliang", + content: function () { + "step 0"; + player.gainPlayerCard(target, "he", true); + "step 1"; + var name = get.translation(target); + player + .chooseControl(function () { + return Math.random() < 0.5 ? "选项一" : "选项二"; + }) + .set("prompt", "督粮:请选择一项") + .set("choiceList", [ + "你观看牌堆顶的两张牌,然后令" + name + "获得其中的一或两张基本牌", + "令" + name + "于下回合的摸牌阶段额外摸一张牌", + ]); + "step 2"; + if (result.control == "选项一") { + var cards = get.cards(2), + bool = false; + event.cards = cards; game.cardsGotoOrdering(cards); - for(var card of cards){ - if(get.type(card)=='basic'){ - bool=true; + for (var card of cards) { + if (get.type(card) == "basic") { + bool = true; break; } } - player.chooseButton(['督粮:选择令'+get.translation(target)+'获得的牌',cards],[1,2],bool).set('filterButton',button=>{ - return get.type(button.link)=='basic'; - }).set('ai',button=>{ - return _status.event.sgn*get.value(button.link); - }).set('sgn',get.sgnAttitude(player,target)>0); - } - else{ - target.addTempSkill('dcduliang2',{player:'phaseAfter'}); - target.addMark('dcduliang2',1,false); + player + .chooseButton( + ["督粮:选择令" + get.translation(target) + "获得的牌", cards], + [1, 2], + bool + ) + .set("filterButton", (button) => { + return get.type(button.link) == "basic"; + }) + .set("ai", (button) => { + return _status.event.sgn * get.value(button.link); + }) + .set("sgn", get.sgnAttitude(player, target) > 0); + } else { + target.addTempSkill("dcduliang2", { player: "phaseAfter" }); + target.addMark("dcduliang2", 1, false); event.finish(); } - 'step 3' - if(result.bool){ - var cardsx=result.links; - target.gain(cardsx,'draw'); - game.log(target,'获得了'+get.cnNumber(cardsx.length)+'张牌'); + "step 3"; + if (result.bool) { + var cardsx = result.links; + target.gain(cardsx, "draw"); + game.log(target, "获得了" + get.cnNumber(cardsx.length) + "张牌"); cards.removeArray(cardsx); cards.reverse(); } - for(var i=0;iget.sgnAttitude(target,player)*player.getUseValue({name:'wuzhong'})/(2-num*0.4)); - 'step 3' - if(!result.bool){ + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + var num = 3 - get.skillCount("shuojian") + 1; + event.num = num; + event.num2 = num; + if (event.num == 0) event.finish(); + "step 2"; + var forced = num != event.num2; + var prompt = + "###" + + get.translation(player) + + "对你发动了【数谏】###视为使用" + + get.cnNumber(num) + + "张【过河拆桥】" + + (forced + ? "" + : "且" + + get.translation(player) + + "此技能本回合失效,或点击“取消”令其摸" + + get.cnNumber(num) + + "张牌"); + if (!target.hasUseTarget({ name: "guohe" })) event._result = { bool: false }; + else + target + .chooseUseTarget(prompt, "guohe", forced) + .set("ai", function () { + var evt = _status.event; + if (evt.name == "chooseTarget") evt = evt.getParent(); + if (!evt.goon) return 0; + return get.effect_use.apply(this, arguments); + }) + .set( + "goon", + target.getUseValue({ name: "guohe" }) > + (get.sgnAttitude(target, player) * + player.getUseValue({ name: "wuzhong" })) / + (2 - num * 0.4) + ); + "step 3"; + if (!result.bool) { player.draw(num); - if(num>1) player.chooseToDiscard('he',num-1,true); + if (num > 1) player.chooseToDiscard("he", num - 1, true); event.finish(); } - 'step 4' - if(--event.num2>0){ + "step 4"; + if (--event.num2 > 0) { event.goto(2); - } - else player.tempBanSkill('shuojian'); + } else player.tempBanSkill("shuojian"); + }, + ai: { + expose: 0.15, + order: 8, + result: { target: 1 }, }, - ai:{ - expose:0.15, - order:8, - result:{target:1} - } }, //谯周 - shiming:{ - audio:2, - trigger:{global:'phaseDrawBegin1'}, - filter:function(event,player){ - return !player.hasSkill('shiming_round'); + shiming: { + audio: 2, + trigger: { global: "phaseDrawBegin1" }, + filter: function (event, player) { + return !player.hasSkill("shiming_round"); }, - check:function(event,player){ - return true;//get.attitude(player,event.player)<0||get.damageEffect(event.player,event.player,player)>0; + check: function (event, player) { + return true; //get.attitude(player,event.player)<0||get.damageEffect(event.player,event.player,player)>0; }, - logTarget:'player', - content:function(){ - 'step 0' - player.addTempSkill('shiming_round','roundStart'); - var cards=get.cards(3); - player.chooseButton(['识命:是否将其中一张置于牌堆底?',cards.slice(0)]).set('ai',button=>{ - var att=_status.event.att,damage=_status.event.damage,val=get.value(button.link,_status.event.player); - if(att>0&&damage<0||att<=0&&damage>0) return 6-val; - return val-5.99; - }).set('att',get.attitude(player,trigger.player)).set('damage',get.damageEffect(trigger.player,trigger.player,player)>0&&trigger.player.hp<=3?1:-1); - while(cards.length) ui.cardPile.insertBefore(cards.pop(),ui.cardPile.firstChild); - 'step 1' - if(result.bool){ - var card=result.links[0]; + logTarget: "player", + content: function () { + "step 0"; + player.addTempSkill("shiming_round", "roundStart"); + var cards = get.cards(3); + player + .chooseButton(["识命:是否将其中一张置于牌堆底?", cards.slice(0)]) + .set("ai", (button) => { + var att = _status.event.att, + damage = _status.event.damage, + val = get.value(button.link, _status.event.player); + if ((att > 0 && damage < 0) || (att <= 0 && damage > 0)) return 6 - val; + return val - 5.99; + }) + .set("att", get.attitude(player, trigger.player)) + .set( + "damage", + get.damageEffect(trigger.player, trigger.player, player) > 0 && + trigger.player.hp <= 3 + ? 1 + : -1 + ); + while (cards.length) ui.cardPile.insertBefore(cards.pop(), ui.cardPile.firstChild); + "step 1"; + if (result.bool) { + var card = result.links[0]; card.fix(); ui.cardPile.appendChild(card); - player.popup('一下','wood'); - game.log(player,'将一张牌置于了牌堆底'); + player.popup("一下", "wood"); + game.log(player, "将一张牌置于了牌堆底"); } - 'step 2' - trigger.player.chooseBool('是否跳过摸牌阶段并对自己造成1点伤害,然后从牌堆底摸三张牌?').set('ai',()=>_status.event.bool).set('bool',get.damageEffect(trigger.player,trigger.player)>=-6||trigger.player.hp>3); - 'step 3' - if(result.bool){ + "step 2"; + trigger.player + .chooseBool("是否跳过摸牌阶段并对自己造成1点伤害,然后从牌堆底摸三张牌?") + .set("ai", () => _status.event.bool) + .set( + "bool", + get.damageEffect(trigger.player, trigger.player) >= -6 || trigger.player.hp > 3 + ); + "step 3"; + if (result.bool) { trigger.cancel(); trigger.player.damage(trigger.player); - } - else event.finish(); - 'step 4' - trigger.player.draw(3,'bottom'); + } else event.finish(); + "step 4"; + trigger.player.draw(3, "bottom"); + }, + subSkill: { + round: { + mark: true, + intro: { content: "本轮已发动〖识命〗" }, + }, }, - subSkill:{ - round:{ - mark:true, - intro:{content:'本轮已发动〖识命〗'} - } - } }, - jiangxi:{ - audio:2, - trigger:{global:'phaseEnd'}, - filter:function(event,player){ - var zhu=game.findPlayer(i=>i.getSeatNum()==1); - return zhu&&player.hasSkill('shiming_round')&&(game.getGlobalHistory('changeHp',evt=>{ - return evt.player==zhu&&evt._dyinged; - }).length>0||zhu.getHistory('damage').length==0)||!game.hasPlayer2(current=>current.getHistory('damage').length>0); + jiangxi: { + audio: 2, + trigger: { global: "phaseEnd" }, + filter: function (event, player) { + var zhu = game.findPlayer((i) => i.getSeatNum() == 1); + return ( + (zhu && + player.hasSkill("shiming_round") && + (game.getGlobalHistory("changeHp", (evt) => { + return evt.player == zhu && evt._dyinged; + }).length > 0 || + zhu.getHistory("damage").length == 0)) || + !game.hasPlayer2((current) => current.getHistory("damage").length > 0) + ); }, - direct:true, - content:function(){ - 'step 0' - if(player.hasSkill('shiming_round')){ - var zhu=game.findPlayer(i=>i.getSeatNum()==1); - if(game.getGlobalHistory('changeHp',evt=>{ - return evt.player==zhu&&evt._dyinged; - }).length>0||zhu.getHistory('damage').length==0){ - player.chooseBool(get.prompt('jiangxi'),'重置〖识命〗'); + direct: true, + content: function () { + "step 0"; + if (player.hasSkill("shiming_round")) { + var zhu = game.findPlayer((i) => i.getSeatNum() == 1); + if ( + game.getGlobalHistory("changeHp", (evt) => { + return evt.player == zhu && evt._dyinged; + }).length > 0 || + zhu.getHistory("damage").length == 0 + ) { + player.chooseBool(get.prompt("jiangxi"), "重置〖识命〗"); } - } - else event.goto(2); - 'step 1' - if(result.bool){ - player.logSkill('jiangxi'); - event.logged=true; - player.removeSkill('shiming_round'); + } else event.goto(2); + "step 1"; + if (result.bool) { + player.logSkill("jiangxi"); + event.logged = true; + player.removeSkill("shiming_round"); player.draw(); } - 'step 2' - if(!game.hasPlayer2(current=>current.getHistory('damage').length>0)){ - player.chooseBool(get.prompt('jiangxi'),'与'+get.translation(trigger.player)+'各摸一张牌').set('ai',()=>_status.event.bool).set('bool',trigger.player.getUseValue({name:'wuzhong'})+player.getUseValue({name:'wuzhong'})>0); - } - else event.finish(); - 'step 3' - if(result.bool){ - if(!event.logged) player.logSkill('jiangxi'); - trigger.player.draw('nodelay'); + "step 2"; + if (!game.hasPlayer2((current) => current.getHistory("damage").length > 0)) { + player + .chooseBool( + get.prompt("jiangxi"), + "与" + get.translation(trigger.player) + "各摸一张牌" + ) + .set("ai", () => _status.event.bool) + .set( + "bool", + trigger.player.getUseValue({ name: "wuzhong" }) + + player.getUseValue({ name: "wuzhong" }) > + 0 + ); + } else event.finish(); + "step 3"; + if (result.bool) { + if (!event.logged) player.logSkill("jiangxi"); + trigger.player.draw("nodelay"); player.draw(); } - } + }, }, //韩龙 - duwang:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + duwang: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - var cards=[]; - for(var i=0;i=5) break; + content: function () { + var cards = []; + for (var i = 0; i < ui.cardPile.childNodes.length; i++) { + var card = ui.cardPile.childNodes[i]; + if (card.name != "sha") cards.push(card); + if (cards.length >= 5) break; } - if(cards.length) player.addToExpansion(cards,'gain2').gaintag.add('duwang'); + if (cards.length) player.addToExpansion(cards, "gain2").gaintag.add("duwang"); }, - marktext:'刺', - intro:{ - name:'刺', - name2:'刺', - content:'expansion', - markcount:'expansion', + marktext: "刺", + intro: { + name: "刺", + name2: "刺", + content: "expansion", + markcount: "expansion", }, - mod:{ - globalFrom:function(from,to,distance){ - return distance+Math.min(1,from.getExpansions('duwang').filter(i=>i.name!='sha').length); + mod: { + globalFrom: function (from, to, distance) { + return ( + distance + + Math.min(1, from.getExpansions("duwang").filter((i) => i.name != "sha").length) + ); }, - globalTo:function(from,to,distance){ - return distance+Math.min(1,to.getExpansions('duwang').filter(i=>i.name!='sha').length); + globalTo: function (from, to, distance) { + return ( + distance + + Math.min(1, to.getExpansions("duwang").filter((i) => i.name != "sha").length) + ); }, }, }, - cibei:{ - audio:2, - trigger:{global:'cardsDiscardAfter'}, - filter:function(event,player){ - if(!player.getExpansions('duwang').filter(i=>i.name!='sha').length) return false; - var evt=event.getParent(); - if(evt.name!='orderingDiscard') return false; - var evtx=evt.relatedEvent||evt.getParent(); - return evtx.name=='useCard'&&evtx.card.name=='sha'&&event.cards.filterInD('d').length&&game.hasPlayer2(current=>current.hasHistory('sourceDamage',evtxx=>{ - return evtxx.card==evtx.card; - })); + cibei: { + audio: 2, + trigger: { global: "cardsDiscardAfter" }, + filter: function (event, player) { + if (!player.getExpansions("duwang").filter((i) => i.name != "sha").length) return false; + var evt = event.getParent(); + if (evt.name != "orderingDiscard") return false; + var evtx = evt.relatedEvent || evt.getParent(); + return ( + evtx.name == "useCard" && + evtx.card.name == "sha" && + event.cards.filterInD("d").length && + game.hasPlayer2((current) => + current.hasHistory("sourceDamage", (evtxx) => { + return evtxx.card == evtx.card; + }) + ) + ); }, - direct:true, - group:'cibei_fullyReady', - content:function(){ - 'step 0' - player.chooseButton([ - '###'+get.prompt('cibei')+'###
              将一张“刺”置入弃牌堆,并将'+get.translation(trigger.cards.filterInD('d'))+'置入“刺”
              ', - player.getExpansions('duwang') - ]).set('filterButton',button=>{ - return button.link.name!='sha'; - }); - 'step 1' - if(result.bool){ - player.logSkill('cibei'); - player.loseToDiscardpile(result.links); - player.addToExpansion(trigger.cards.filterInD('d'),'gain2').gaintag.add('duwang'); - if(game.hasPlayer(current=>current.countDiscardableCards(player,'hej')>0)) player.chooseTarget('刺北:弃置一名角色区域内的一张牌',true,(card,player,target)=>{ - return target.countDiscardableCards(player,'hej')>0; - }).set('ai',target=>{ - return get.effect(target,{name:'guohe'},_status.event.player); + direct: true, + group: "cibei_fullyReady", + content: function () { + "step 0"; + player + .chooseButton([ + "###" + + get.prompt("cibei") + + '###
              将一张“刺”置入弃牌堆,并将' + + get.translation(trigger.cards.filterInD("d")) + + "置入“刺”
              ", + player.getExpansions("duwang"), + ]) + .set("filterButton", (button) => { + return button.link.name != "sha"; }); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; + "step 1"; + if (result.bool) { + player.logSkill("cibei"); + player.loseToDiscardpile(result.links); + player.addToExpansion(trigger.cards.filterInD("d"), "gain2").gaintag.add("duwang"); + if (game.hasPlayer((current) => current.countDiscardableCards(player, "hej") > 0)) + player + .chooseTarget( + "刺北:弃置一名角色区域内的一张牌", + true, + (card, player, target) => { + return target.countDiscardableCards(player, "hej") > 0; + } + ) + .set("ai", (target) => { + return get.effect(target, { name: "guohe" }, _status.event.player); + }); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; player.line(target); - player.discardPlayerCard(target,'hej',true); + player.discardPlayerCard(target, "hej", true); player.addExpose(0.1); } }, - subSkill:{ - fullyReady:{ - trigger:{global:'phaseEnd'}, - forced:true, - locked:false, - filter:function(event,player){ - var storage=player.getExpansions('duwang'); - return storage.length>0&&storage.every(i=>i.name=='sha'); + ai: { + combo: "duwang", + }, + subSkill: { + fullyReady: { + trigger: { global: "phaseEnd" }, + forced: true, + locked: false, + filter: function (event, player) { + var storage = player.getExpansions("duwang"); + return storage.length > 0 && storage.every((i) => i.name == "sha"); }, - content:function(){ - player.gain(player.getExpansions('duwang'),'gain2').gaintag.add('cibei_mark'); - player.addSkill('cibei_mark'); + content: function () { + player.gain(player.getExpansions("duwang"), "gain2").gaintag.add("cibei_mark"); + player.addSkill("cibei_mark"); }, }, - mark:{ - trigger:{player:'useCard1'}, - onremove:true, - charlotte:true, - silent:true, - firstDo:true, - filter:function(event,player){ - return player.hasHistory('lose',evt=>{ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('cibei_mark')) return true; + mark: { + trigger: { player: "useCard1" }, + onremove: true, + charlotte: true, + silent: true, + firstDo: true, + filter: function (event, player) { + return player.hasHistory("lose", (evt) => { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("cibei_mark")) return true; } return false; }); }, - content:function(){ - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(typeof stat[name]=='number') stat[name]--; + content: function () { + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (typeof stat[name] == "number") stat[name]--; } }, - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('cibei_mark')) return true; + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("cibei_mark")) return true; }, - cardDiscardable:function(card,player,name){ - if(card.hasGaintag('cibei_mark')) return false; + cardDiscardable: function (card, player, name) { + if (card.hasGaintag("cibei_mark")) return false; }, - canBeDiscarded:function(card){ - if(card.hasGaintag('cibei_mark')) return false; + canBeDiscarded: function (card) { + if (card.hasGaintag("cibei_mark")) return false; }, - targetInRange:function(card,player,target){ - if(!card.cards) return; - for(var i of card.cards){ - if(i.hasGaintag('cibei_mark')) return true; + targetInRange: function (card, player, target) { + if (!card.cards) return; + for (var i of card.cards) { + if (i.hasGaintag("cibei_mark")) return true; } }, - cardUsable:function(card,player){ - if(!card.cards) return; - for(var i of card.cards){ - if(i.hasGaintag('cibei_mark')) return true; + cardUsable: function (card, player) { + if (!card.cards) return; + for (var i of card.cards) { + if (i.hasGaintag("cibei_mark")) return true; } - } - } + }, + }, }, - } + }, }, //武安国 - diezhang:{ - audio:2, - locked:false, - zhuanhuanji:function(player,skill){ - if(!player.storage.duanwan) player.storage[skill]=!player.storage[skill]; + diezhang: { + audio: 2, + locked: false, + zhuanhuanji: function (player, skill) { + if (!player.storage.duanwan) player.storage[skill] = !player.storage[skill]; }, - trigger:{global:['eventNeutralized','shaMiss']}, - filter:function(event,player){ - if(player.hasSkill('diezhang_used')) return false; - if(event.type!='card') return false; - var evt=event._neutralize_event; - var user,responder; - if(event.name=='sha'){ - user=event.player;responder=event.target; + trigger: { global: ["eventNeutralized", "shaMiss"] }, + filter: function (event, player) { + if (player.hasSkill("diezhang_used")) return false; + if (event.type != "card") return false; + var evt = event._neutralize_event; + var user, responder; + if (event.name == "sha") { + user = event.player; + responder = event.target; + } else { + if (evt.type != "card") return false; + user = event.player; + responder = evt.player; } - else{ - if(evt.type!='card') return false; - user=event.player; - responder=evt.player; - } - if(!player.storage.diezhang){ - if(user!=player||responder==player) return false; - return player.countDiscardableCards(player,'he')>0&&player.canUse('sha',responder,false); - } - else{ - if(user==player||responder!=player) return false; - return player.canUse('sha',user,false); + if (!player.storage.diezhang) { + if (user != player || responder == player) return false; + return ( + player.countDiscardableCards(player, "he") > 0 && + player.canUse("sha", responder, false) + ); + } else { + if (user == player || responder != player) return false; + return player.canUse("sha", user, false); } }, - direct:true, - content:function(){ - 'step 0' - var evt=trigger._neutralize_event; - var user,responder; - if(trigger.name=='sha'){ - user=trigger.player;responder=trigger.target; + direct: true, + content: function () { + "step 0"; + var evt = trigger._neutralize_event; + var user, responder; + if (trigger.name == "sha") { + user = trigger.player; + responder = trigger.target; + } else { + user = trigger.player; + responder = evt.player; } - else{ - user=trigger.player; - responder=evt.player; + var num = player.storage.duanwan ? 2 : 1; + event.num = num; + if (!player.storage.diezhang) { + var target = responder; + event.target = target; + var next = player + .chooseToDiscard( + get.prompt("diezhang", target), + "弃置一张牌,视为对其使用" + get.cnNumber(num) + "张【杀】", + "he" + ) + .set("ai", (card) => { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set("logSkill", ["diezhang", target]); + } else { + var target = user; + event.target = target; + var next = player + .chooseBool( + get.prompt("diezhang", target), + "摸" + get.cnNumber(num) + "张牌,视为对其使用一张【杀】" + ) + .set("ai", () => _status.event.goon); } - var num=player.storage.duanwan?2:1; - event.num=num; - if(!player.storage.diezhang){ - var target=responder; - event.target=target; - var next=player.chooseToDiscard(get.prompt('diezhang',target),'弃置一张牌,视为对其使用'+get.cnNumber(num)+'张【杀】','he').set('ai',card=>{ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('logSkill',['diezhang',target]); - } - else{ - var target=user; - event.target=target; - var next=player.chooseBool(get.prompt('diezhang',target),'摸'+get.cnNumber(num)+'张牌,视为对其使用一张【杀】').set('ai',()=>_status.event.goon); - } - next.set('goon',get.effect(target,{name:'sha'},player,player)>0); - 'step 1' - if(result.bool){ - if(player.storage.duanwan) player.addTempSkill('diezhang_used'); - player.changeZhuanhuanji('diezhang'); - if(!result.cards||!result.cards.length){ - player.logSkill('diezhang',target); - player.draw(num,'nodelay'); - player.useCard({name:'sha',isCard:true},target,false); - } - else while(num--) player.useCard({name:'sha',isCard:true},target,false); + next.set("goon", get.effect(target, { name: "sha" }, player, player) > 0); + "step 1"; + if (result.bool) { + if (player.storage.duanwan) player.addTempSkill("diezhang_used"); + player.changeZhuanhuanji("diezhang"); + if (!result.cards || !result.cards.length) { + player.logSkill("diezhang", target); + player.draw(num, "nodelay"); + player.useCard({ name: "sha", isCard: true }, target, false); + } else while (num--) player.useCard({ name: "sha", isCard: true }, target, false); } }, - marktext:'☯', - mark:true, - intro:{ - content:function(storage,player){ - var cnNum=get.cnNumber(player.storage.duanwan?2:1); - if(storage) return '当其他角色使用牌被你抵消后,你可以摸'+cnNum+'张牌,视为对其使用一张【杀】。'; - return '当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用'+cnNum+'张【杀】。'; + marktext: "☯", + mark: true, + intro: { + content: function (storage, player) { + var cnNum = get.cnNumber(player.storage.duanwan ? 2 : 1); + if (storage) + return ( + "当其他角色使用牌被你抵消后,你可以摸" + + cnNum + + "张牌,视为对其使用一张【杀】。" + ); + return ( + "当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用" + + cnNum + + "张【杀】。" + ); }, }, - mod:{ - cardUsable:function(card,player,num){ - if(!player.storage.duanwan&&card.name=='sha') return num+1; + mod: { + cardUsable: function (card, player, num) { + if (!player.storage.duanwan && card.name == "sha") return num + 1; }, }, - subSkill:{used:{charlotte:true}} + subSkill: { used: { charlotte: true } }, }, - duanwan:{ - audio:2, - enable:'chooseToUse', - skillAnimation:true, - animationColor:'soil', - limited:true, - filter:function(event,player){ - return event.type=='dying'&&player==event.dying; + duanwan: { + audio: 2, + enable: "chooseToUse", + skillAnimation: true, + animationColor: "soil", + limited: true, + filter: function (event, player) { + return event.type == "dying" && player == event.dying; }, - content:function(){ - player.changeZhuanhuanji('diezhang'); - player.awakenSkill('duanwan'); - var num=2-player.hp; - if(num>0) player.recover(num); + content: function () { + player.changeZhuanhuanji("diezhang"); + player.awakenSkill("duanwan"); + var num = 2 - player.hp; + if (num > 0) player.recover(num); }, - ai:{ - save:true, - skillTagFilter:function(player,tag,target){ - return player==target; + ai: { + save: true, + skillTagFilter: function (player, tag, target) { + return player == target; }, - result:{player:1}, - } + result: { player: 1 }, + }, }, //李婉 - liandui:{ - audio:2, - trigger:{global:'useCard'}, - filter:function(event,player){ - var history=game.getAllGlobalHistory('useCard'); - var index=history.indexOf(event); - if(index<=0) return false; - var previous=history[index-1].player; - if(event.player==player&&previous!=player&&previous.isIn()) return true; - if(event.player!=player&&previous==player) return true; + liandui: { + audio: 2, + trigger: { global: "useCard" }, + filter: function (event, player) { + var history = game.getAllGlobalHistory("useCard"); + var index = history.indexOf(event); + if (index <= 0) return false; + var previous = history[index - 1].player; + if (event.player == player && previous != player && previous.isIn()) return true; + if (event.player != player && previous == player) return true; return false; }, - direct:true, - content:function(){ - 'step 0' - var history=game.getAllGlobalHistory('useCard'); - var index=history.indexOf(trigger); - var previous=history[index-1].player; - var user=trigger.player,target=previous; - event.user=user;event.target=target; - if(user){ - user.chooseBool('是否对'+get.translation(target)+'发动【联对】?','令'+get.translation(target)+'摸两张牌').set('ai',()=>_status.event.bool).set('bool',get.effect(target,{name:'draw'},user,user)>0); + direct: true, + content: function () { + "step 0"; + var history = game.getAllGlobalHistory("useCard"); + var index = history.indexOf(trigger); + var previous = history[index - 1].player; + var user = trigger.player, + target = previous; + event.user = user; + event.target = target; + if (user) { + user.chooseBool( + "是否对" + get.translation(target) + "发动【联对】?", + "令" + get.translation(target) + "摸两张牌" + ) + .set("ai", () => _status.event.bool) + .set("bool", get.effect(target, { name: "draw" }, user, user) > 0); } - 'step 1' - if(result.bool){ - event.user.logSkill('liandui',target); + "step 1"; + if (result.bool) { + event.user.logSkill("liandui", target); target.draw(2); } - } + }, }, - biejun:{ - audio:2, - global:'biejun_give', - trigger:{player:'damageBegin4'}, - filter:function(event,player){ - return !player.hasSkill('biejun_used')&&player.countCards('h',card=>{ - return card.hasGaintag('biejun'); - })==0; + biejun: { + audio: 2, + global: "biejun_give", + trigger: { player: "damageBegin4" }, + filter: function (event, player) { + return ( + !player.hasSkill("biejun_used") && + player.countCards("h", (card) => { + return card.hasGaintag("biejun"); + }) == 0 + ); }, - prompt2:'翻面并防止此伤害', - check:function(event,player){ - return player.isTurnedOver()||event.num>=player.hp||get.distance(_status.currentPhase,player,'absolute')>=3; + prompt2: "翻面并防止此伤害", + check: function (event, player) { + return ( + player.isTurnedOver() || + event.num >= player.hp || + get.distance(_status.currentPhase, player, "absolute") >= 3 + ); }, - content:function(){ - player.addTempSkill('biejun_used'); + content: function () { + player.addTempSkill("biejun_used"); player.turnOver(); trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(get.tag(card,'damage')){ - if(player.getNext()==target&&lib.skill.biejun.filter(null,target)&&target.isTurnedOver()) return [0,1]; + ai: { + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (get.tag(card, "damage")) { + if ( + player.getNext() == target && + lib.skill.biejun.filter(null, target) && + target.isTurnedOver() + ) + return [0, 1]; } - } - } + }, + }, }, - subSkill:{ - used:{charlotte:true}, - give:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(!player.countCards('h')) return false; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('biejun'); + subSkill: { + used: { charlotte: true }, + give: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if (!player.countCards("h")) return false; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("biejun"); }); - if(!targets.length) return false; + if (!targets.length) return false; return true; }, - selectCard:1, - filterCard:true, - filterTarget:function(card,player,target){ - return target.hasSkill('biejun'); + selectCard: 1, + filterCard: true, + filterTarget: function (card, player, target) { + return target.hasSkill("biejun"); }, - selectTarget:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('biejun'); + selectTarget: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("biejun"); }); - return targets.length>1?1:-1; + return targets.length > 1 ? 1 : -1; }, - complexSelect:true, - prompt:function(){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return current!=player&¤t.hasSkill('biejun'); + complexSelect: true, + prompt: function () { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return current != player && current.hasSkill("biejun"); }); - return '将一张手牌交给'+get.translation(targets)+(targets.length>1?'中的一人':''); + return ( + "将一张手牌交给" + + get.translation(targets) + + (targets.length > 1 ? "中的一人" : "") + ); }, - position:'h', - discard:false, - lose:false, - delay:false, - check:function(card){ - var player=_status.event.player; - if(game.hasPlayer(function(current){ - return lib.skill.biejun_give.filterTarget(null,player,current)&&get.attitude(player,current)>0; - })){ - return 5-get.value(card); + position: "h", + discard: false, + lose: false, + delay: false, + check: function (card) { + var player = _status.event.player; + if ( + game.hasPlayer(function (current) { + return ( + lib.skill.biejun_give.filterTarget(null, player, current) && + get.attitude(player, current) > 0 + ); + }) + ) { + return 5 - get.value(card); } return -get.value(card); }, - content:function(){ - game.trySkillAudio('biejun',target); - player.give(cards,target).gaintag.add('biejun'); - target.addTempSkill('biejun_tag'); + content: function () { + game.trySkillAudio("biejun", target); + player.give(cards, target).gaintag.add("biejun"); + target.addTempSkill("biejun_tag"); }, - ai:{ - order:2, - result:{target:1}, + ai: { + order: 2, + result: { target: 1 }, }, }, - tag:{ - charlotte:true, - forced:true, - onremove:function(player){ - player.removeGaintag('biejun'); - } - } - } + tag: { + charlotte: true, + forced: true, + onremove: function (player) { + player.removeGaintag("biejun"); + }, + }, + }, }, //诸葛尚 - sangu:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - getEffect:function(player,target,event,list1,list2){ - let att=get.attitude(player,target); - if(att===0) return 0; - let getv=function(name,player,arg){ - let v=event.getTempCache('sangu',player.id+name); - if(typeof v==='number') return v; - v=player.getUseValue({name:name,storage:{sangu:true}},arg); - event.putTempCache('sangu',player.id+name,v); + sangu: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + getEffect: function (player, target, event, list1, list2) { + let att = get.attitude(player, target); + if (att === 0) return 0; + let getv = function (name, player, arg) { + let v = event.getTempCache("sangu", player.id + name); + if (typeof v === "number") return v; + v = player.getUseValue({ name: name, storage: { sangu: true } }, arg); + event.putTempCache("sangu", player.id + name, v); return v; }; - if(att<0){ - for(let i of list1){ - if(getv(i,target)<=0||getv(i,target)<=0) return -att*Math.sqrt(get.threaten(target))*2; + if (att < 0) { + for (let i of list1) { + if (getv(i, target) <= 0 || getv(i, target) <= 0) + return -att * Math.sqrt(get.threaten(target)) * 2; } return 0; - } - else{ - let list=list1.concat(player.hp>1?list2:[]),eff=0; - list.sort(function(a,b){ - return getv(b,target)-getv(a,target); + } else { + let list = list1.concat(player.hp > 1 ? list2 : []), + eff = 0; + list.sort(function (a, b) { + return getv(b, target) - getv(a, target); }); - list=list.slice(3); - for(let i of list){ - let res=getv(i,target); - if(res<=5) break; - else eff+=res; + list = list.slice(3); + for (let i of list) { + let res = getv(i, target); + if (res <= 5) break; + else eff += res; } - return Math.sqrt(eff/1.5)*att; + return Math.sqrt(eff / 1.5) * att; } }, - content:function(){ - 'step 0' - event.list1=[]; - event.list2=[]; - event.used=[]; - player.getHistory('useCard',function(evt){ + content: function () { + "step 0"; + event.list1 = []; + event.list2 = []; + event.used = []; + player.getHistory("useCard", function (evt) { event.used.add(evt.card.name); }); - for(let name of lib.inpile){ - let add=false,type=get.type(name); - if(name==='sha') add=true; - else if(type==='trick'){ - let info=lib.card[name]; - if(info&&!info.singleCard&&!info.notarget) add=true; + for (let name of lib.inpile) { + let add = false, + type = get.type(name); + if (name === "sha") add = true; + else if (type === "trick") { + let info = lib.card[name]; + if (info && !info.singleCard && !info.notarget) add = true; } - if(!add) continue; - if(event.used.includes(name)) event.list1.push(name); + if (!add) continue; + if (event.used.includes(name)) event.list1.push(name); else event.list2.push(name); } - if(!event.list1.length&&!event.list2.length) event.finish(); - else player.chooseTarget(get.prompt2('sangu'),lib.filter.notMe).set('ai',function(target){ - return lib.skill.sangu.getEffect(_status.event.player,target,_status.event.getTrigger(),_status.event.list1,_status.event.list2); - }).set('list1',event.list1).set('list2',event.list2); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('sangu',target); - event.target=target; - } - else event.finish(); - 'step 2' - var dialog=['为'+get.translation(target)+'选择至多三个牌名']; - if(event.list1.length){ + if (!event.list1.length && !event.list2.length) event.finish(); + else + player + .chooseTarget(get.prompt2("sangu"), lib.filter.notMe) + .set("ai", function (target) { + return lib.skill.sangu.getEffect( + _status.event.player, + target, + _status.event.getTrigger(), + _status.event.list1, + _status.event.list2 + ); + }) + .set("list1", event.list1) + .set("list2", event.list2); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("sangu", target); + event.target = target; + } else event.finish(); + "step 2"; + var dialog = ["为" + get.translation(target) + "选择至多三个牌名"]; + if (event.list1.length) { dialog.push('
              本回合已使用过的牌
              '); - dialog.push([event.list1.map(i=>[get.type(i),'',i]),'vcard']); + dialog.push([event.list1.map((i) => [get.type(i), "", i]), "vcard"]); } - if(event.list2.length){ + if (event.list2.length) { dialog.push('
              本回合未使用过的牌
              '); - dialog.push([event.list2.map(i=>[get.type(i),'',i]),'vcard']); + dialog.push([event.list2.map((i) => [get.type(i), "", i]), "vcard"]); } - player.chooseButton(dialog,true,[1,3]).set('ai',function(button){ - let name=button.link[2], - list=_status.event.list, - player=_status.event.player, - target=_status.event.getParent().target, - trigger=_status.event.getTrigger(), - getv=(name,player)=>{ - let v=trigger.getTempCache('sangu',player.id+name); - if(typeof v==='number') return v; - v=player.getUseValue({name:name,storage:{sangu:true}}); - trigger.putTempCache('sangu',player.id+name,v); - return v; - }; - if(get.attitude(player,target)<0){ - if(!list.includes(name)) return 0; - return -getv(name,target); - } - else{ - if(player.hp<2&&!list.includes(name)) return 0; - let val=getv(name,target),base=5; - val=Math.min(15,val-base); - if(name==='wuzhong'||name==='dongzhuxianji') val+=15; - else if(name==='shunshou') val+=6; - return val; - } - }).set('list',event.list1); - 'step 3' - if(result.bool){ - var names=result.links.map((i)=>i[2]); - if(!target.storage.sangu_effect) target.storage.sangu_effect=[]; - target.storage.sangu_effect=target.storage.sangu_effect.concat(names); - game.log(player,'为',target,'选择了','#y'+get.translation(names)); - target.addTempSkill('sangu_effect',{player:'phaseUseAfter'}); - target.markSkill('sangu_effect'); - var bool=true; - for(var i of names){ - if(!event.used.includes(i)){ - bool=false; + player + .chooseButton(dialog, true, [1, 3]) + .set("ai", function (button) { + let name = button.link[2], + list = _status.event.list, + player = _status.event.player, + target = _status.event.getParent().target, + trigger = _status.event.getTrigger(), + getv = (name, player) => { + let v = trigger.getTempCache("sangu", player.id + name); + if (typeof v === "number") return v; + v = player.getUseValue({ name: name, storage: { sangu: true } }); + trigger.putTempCache("sangu", player.id + name, v); + return v; + }; + if (get.attitude(player, target) < 0) { + if (!list.includes(name)) return 0; + return -getv(name, target); + } else { + if (player.hp < 2 && !list.includes(name)) return 0; + let val = getv(name, target), + base = 5; + val = Math.min(15, val - base); + if (name === "wuzhong" || name === "dongzhuxianji") val += 15; + else if (name === "shunshou") val += 6; + return val; + } + }) + .set("list", event.list1); + "step 3"; + if (result.bool) { + var names = result.links.map((i) => i[2]); + if (!target.storage.sangu_effect) target.storage.sangu_effect = []; + target.storage.sangu_effect = target.storage.sangu_effect.concat(names); + game.log(player, "为", target, "选择了", "#y" + get.translation(names)); + target.addTempSkill("sangu_effect", { player: "phaseUseAfter" }); + target.markSkill("sangu_effect"); + var bool = true; + for (var i of names) { + if (!event.used.includes(i)) { + bool = false; break; } } - if(bool){ - target.addTempSkill('sangu_prevent',{player:'phaseUseAfter'}); - target.markAuto('sangu_prevent',[player]); + if (bool) { + target.addTempSkill("sangu_prevent", { player: "phaseUseAfter" }); + target.markAuto("sangu_prevent", [player]); } } }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&card.storage&&card.storage.sangu) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && card.storage && card.storage.sangu) + return "zeroplayertarget"; }, - } + }, }, - subSkill:{ - effect:{ - trigger:{player:'phaseUseBegin'}, - charlotte:true, - forced:true, - popup:false, - content:function(){ - player.addTempSkill('sangu_viewas'); + subSkill: { + effect: { + trigger: { player: "phaseUseBegin" }, + charlotte: true, + forced: true, + popup: false, + content: function () { + player.addTempSkill("sangu_viewas"); }, - onremove:true, - intro:{ - mark:function(dialog,storage,player){ - if(!storage||!storage.length) return '当前无可用牌'; - dialog.add([[storage[0]],'vcard']); - if(storage.length>1) dialog.addSmall([storage.slice(1),'vcard']) + onremove: true, + intro: { + mark: function (dialog, storage, player) { + if (!storage || !storage.length) return "当前无可用牌"; + dialog.add([[storage[0]], "vcard"]); + if (storage.length > 1) dialog.addSmall([storage.slice(1), "vcard"]); }, - content:'$', + content: "$", }, }, - viewas:{ - mod:{ - hiddenCard:function(player,name){ - var storage=player.getStorage('sangu_effect'); - if(storage.length) return name==storage[0]; + viewas: { + mod: { + hiddenCard: function (player, name) { + var storage = player.getStorage("sangu_effect"); + if (storage.length) return name == storage[0]; }, - cardname:function(card,player){ - if(_status.event.name!='chooseToUse'||_status.event.skill) return; - var storage=player.getStorage('sangu_effect'); - if(storage.length) return storage[0]; + cardname: function (card, player) { + if (_status.event.name != "chooseToUse" || _status.event.skill) return; + var storage = player.getStorage("sangu_effect"); + if (storage.length) return storage[0]; }, - cardnature:function(card,player){ - if(_status.event.name!='chooseToUse'||_status.event.skill) return; - var storage=player.getStorage('sangu_effect'); - if(storage.length) return false; + cardnature: function (card, player) { + if (_status.event.name != "chooseToUse" || _status.event.skill) return; + var storage = player.getStorage("sangu_effect"); + if (storage.length) return false; }, }, - trigger:{player:['useCard','respond']}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.cards.length>0&&player.getStorage('sangu_effect').length>0; + trigger: { player: ["useCard", "respond"] }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.cards.length > 0 && player.getStorage("sangu_effect").length > 0; }, - content:function(){ - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.sangu=true; - player.unmarkAuto('sangu_effect',[player.getStorage('sangu_effect')[0]]); + content: function () { + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.sangu = true; + player.unmarkAuto("sangu_effect", [player.getStorage("sangu_effect")[0]]); }, }, - prevent:{ - trigger:{source:'damageBegin2'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.card&&event.card.storage&&event.card.storage.sangu&&player.getStorage('sangu_prevent').includes(event.player); + prevent: { + trigger: { source: "damageBegin2" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return ( + event.card && + event.card.storage && + event.card.storage.sangu && + player.getStorage("sangu_prevent").includes(event.player) + ); }, - content:function(){ + content: function () { trigger.cancel(); - } - } + }, + }, }, }, - yizu:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - usable:1, - filter:function(event,player){ - return player.isDamaged()&&player.hp<=event.player.hp&&(event.card.name=='sha'||event.card.name=='juedou'); + yizu: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + usable: 1, + filter: function (event, player) { + return ( + player.isDamaged() && + player.hp <= event.player.hp && + (event.card.name == "sha" || event.card.name == "juedou") + ); }, - content:function(){ + content: function () { player.recover(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target.isHealthy()||(card.name!='sha'&&card.name!='juedou')) return; - if((target.storage.counttrigger&&target.storage.counttrigger.yizu)&¤t<0) return 5; - if(player.hp0) return 1.2; - if(get.attitude(player,target)>=0) return; - var copy=get.effect(target,{name:'shacopy'},player,player); - if(copy>0&&player.isPhaseUsing()&&Math.min(player.getCardUsable('sha'),player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.canUse(card,target,null,true); - }))>=2) return; - return [0,2]; + ai: { + effect: { + target: function (card, player, target, current) { + if (target.isHealthy() || (card.name != "sha" && card.name != "juedou")) return; + if ( + target.storage.counttrigger && + target.storage.counttrigger.yizu && + current < 0 + ) + return 5; + if (player.hp < target.hp) return; + if (current > 0) return 1.2; + if (get.attitude(player, target) >= 0) return; + var copy = get.effect(target, { name: "shacopy" }, player, player); + if ( + copy > 0 && + player.isPhaseUsing() && + Math.min( + player.getCardUsable("sha"), + player.countCards("hs", function (card) { + return ( + get.name(card) == "sha" && player.canUse(card, target, null, true) + ); + }) + ) >= 2 + ) + return; + return [0, 2]; }, }, }, }, //轲比能 - kousheng:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + kousheng: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.chooseCard('h',[1,player.countCards('h')],get.prompt('kousheng'),'你可以选择任意张手牌,这些手牌于本回合内视为无次数限制的【杀】。但当有角色受到这些【杀】的伤害后,其可以用所有手牌交换剩余的牌。').set('standard',player.getUseValue({name:'sha'},null,true)).set('ai',function(card){ - var player=_status.event.player,standard=_status.event.standard; - if(standard<=0) return 0; - var eff=player.getUseValue(card,null,true); - if(eff<=standard) return standard-eff+0.1; - return 0; - }); - 'step 1' - if(result.bool){ - player.logSkill('kousheng'); - player.addGaintag(result.cards,'kousheng'); - player.addTempSkill('kousheng_effect'); + content: function () { + "step 0"; + player + .chooseCard( + "h", + [1, player.countCards("h")], + get.prompt("kousheng"), + "你可以选择任意张手牌,这些手牌于本回合内视为无次数限制的【杀】。但当有角色受到这些【杀】的伤害后,其可以用所有手牌交换剩余的牌。" + ) + .set("standard", player.getUseValue({ name: "sha" }, null, true)) + .set("ai", function (card) { + var player = _status.event.player, + standard = _status.event.standard; + if (standard <= 0) return 0; + var eff = player.getUseValue(card, null, true); + if (eff <= standard) return standard - eff + 0.1; + return 0; + }); + "step 1"; + if (result.bool) { + player.logSkill("kousheng"); + player.addGaintag(result.cards, "kousheng"); + player.addTempSkill("kousheng_effect"); game.delayx(); } }, - subSkill:{ - effect:{ - audio:'kousheng', - trigger:{player:'useCard1'}, - forced:true, - charlotte:true, - firstDo:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - return player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('kousheng')) return true; + subSkill: { + effect: { + audio: "kousheng", + trigger: { player: "useCard1" }, + forced: true, + charlotte: true, + firstDo: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + return player.hasHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("kousheng")) return true; } return false; }); }, - content:function(){ - if(!trigger.card.storage) trigger.card.storage={}; - trigger.card.storage.kousheng=true; - if(trigger.addCount!==false){ - trigger.addCount=false; - player.getStat('card').sha--; + content: function () { + if (!trigger.card.storage) trigger.card.storage = {}; + trigger.card.storage.kousheng = true; + if (trigger.addCount !== false) { + trigger.addCount = false; + player.getStat("card").sha--; } }, - onremove:function(player){ - player.removeGaintag('kousheng'); + onremove: function (player) { + player.removeGaintag("kousheng"); }, - mod:{ - cardUsable:function(card,player,target){ - if(card.name!='sha'||!card.cards) return; - for(var i of card.cards){ - if(i.hasGaintag('kousheng')) return Infinity; + mod: { + cardUsable: function (card, player, target) { + if (card.name != "sha" || !card.cards) return; + for (var i of card.cards) { + if (i.hasGaintag("kousheng")) return Infinity; } }, - cardname:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('kousheng')) return 'sha'; + cardname: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("kousheng")) return "sha"; }, - cardnature:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('kousheng')) return false; + cardnature: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("kousheng")) return false; }, }, - group:'kousheng_damage', + group: "kousheng_damage", }, - damage:{ - audio:'kousheng', - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - if(!event.card||!event.card.storage||!event.card.storage.kousheng||event.getParent().type!='card') return false; - var target=event.player; - return target.isIn()&&player.hasCard(function(card){ - return card.hasGaintag('kousheng'); - },'h'); + damage: { + audio: "kousheng", + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + if ( + !event.card || + !event.card.storage || + !event.card.storage.kousheng || + event.getParent().type != "card" + ) + return false; + var target = event.player; + return ( + target.isIn() && + player.hasCard(function (card) { + return card.hasGaintag("kousheng"); + }, "h") + ); }, - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - var cards=player.getCards('h',function(card){ - return card.hasGaintag('kousheng'); - }); - event.cards=cards; - var str=get.translation(player); - player.showCards(cards,str+'的【寇旌】牌'); - if(target.countCards('h')>0) target.chooseBool('是否交换“寇旌”牌?','用你的所有手牌交换'+str+'的下列“寇旌”牌:'+get.translation(cards)).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().player; - if(player.hasShan()||player.countCards('hs',{name:['tao','jiu']})>0||get.attitude(player,target)>=0) return false; - var hs1=player.getCards('h'),hs2=_status.event.getParent().cards; - if(hs2.length>=player.hp) return true; - if(get.value(hs1,player)>=get.value(hs2,target)) return false; - return true; + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + var cards = player.getCards("h", function (card) { + return card.hasGaintag("kousheng"); }); + event.cards = cards; + var str = get.translation(player); + player.showCards(cards, str + "的【寇旌】牌"); + if (target.countCards("h") > 0) + target + .chooseBool( + "是否交换“寇旌”牌?", + "用你的所有手牌交换" + + str + + "的下列“寇旌”牌:" + + get.translation(cards) + ) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().player; + if ( + player.hasShan() || + player.countCards("hs", { name: ["tao", "jiu"] }) > 0 || + get.attitude(player, target) >= 0 + ) + return false; + var hs1 = player.getCards("h"), + hs2 = _status.event.getParent().cards; + if (hs2.length >= player.hp) return true; + if (get.value(hs1, player) >= get.value(hs2, target)) return false; + return true; + }); else event.finish(); - 'step 1' - if(result.bool){ - player.swapHandcards(target,cards,target.getCards('h')); + "step 1"; + if (result.bool) { + player.swapHandcards(target, cards, target.getCards("h")); } }, }, }, }, //陆凯 - lkbushi:{ - audio:2, - getBushi:function(player){ - if(!player.storage.lkbushi) return ['spade','heart','club','diamond']; + lkbushi: { + audio: 2, + getBushi: function (player) { + if (!player.storage.lkbushi) return ["spade", "heart", "club", "diamond"]; return player.storage.lkbushi; }, - onremove:true, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - locked:false, - content:function(){ - 'step 0' - var list=lib.skill.lkbushi.getBushi(player); - list=list.map(function(i){ - return ['','','lukai_'+i]; + onremove: true, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + locked: false, + content: function () { + "step 0"; + var list = lib.skill.lkbushi.getBushi(player); + list = list.map(function (i) { + return ["", "", "lukai_" + i]; }); - var next=player.chooseToMove('卜筮:是否调整〖卜筮〗的花色顺序?'); - next.set('list',[ - ['无次数限制/使用打出摸牌
              可弃牌无效/结束阶段获得',[list,'vcard'],function(list){ - var list2=list.map(function(i){ - return get.translation(i[2].slice(6)); - }); - return '你使用'+list2[0]+'牌时无次数限制;使用或打出'+list2[1]+'时,摸一张牌;
              成为'+list2[2]+'牌目标后可弃一张牌无效;结束阶段获得一张'+list2[3]+'牌'; - }], + var next = player.chooseToMove("卜筮:是否调整〖卜筮〗的花色顺序?"); + next.set("list", [ + [ + "无次数限制/使用打出摸牌
              可弃牌无效/结束阶段获得", + [list, "vcard"], + function (list) { + var list2 = list.map(function (i) { + return get.translation(i[2].slice(6)); + }); + return ( + "你使用" + + list2[0] + + "牌时无次数限制;使用或打出" + + list2[1] + + "时,摸一张牌;
              成为" + + list2[2] + + "牌目标后可弃一张牌无效;结束阶段获得一张" + + list2[3] + + "牌" + ); + }, + ], ]); - next.set('processAI',function(){ - var player=_status.event.player; - var list=lib.skill.lkbushi.getBushi(player); - var list2=[]; - var hs=player.getCards('hs',function(card){ + next.set("processAI", function () { + var player = _status.event.player; + var list = lib.skill.lkbushi.getBushi(player); + var list2 = []; + var hs = player.getCards("hs", function (card) { return player.hasValueTarget(card); }); - list.sort(function(a,b){ - return hs.filter((i)=>get.suit(i)==b).length-hs.filter((i)=>get.suit(i)==a).length; + list.sort(function (a, b) { + return ( + hs.filter((i) => get.suit(i) == b).length - + hs.filter((i) => get.suit(i) == a).length + ); }); list2.push(list.shift()); - hs=player.getCards('hs','sha'); - list.sort(function(a,b){ - return hs.filter((i)=>get.suit(i)==b).length-hs.filter((i)=>get.suit(i)==a).length; + hs = player.getCards("hs", "sha"); + list.sort(function (a, b) { + return ( + hs.filter((i) => get.suit(i) == b).length - + hs.filter((i) => get.suit(i) == a).length + ); }); list2.unshift(list.shift()); list.randomSort(); list2.addArray(list); - return [list2.map((i)=>['','','lukai_'+i])] + return [list2.map((i) => ["", "", "lukai_" + i])]; }); - 'step 1' - if(result.bool){ - var list=lib.skill.lkbushi.getBushi(player),list2=result.moved[0].map(function(i){ - return i[2].slice(6); - }); - for(var i=0;i<4;i++){ - if(list[i]!=list2[i]){ - player.logSkill('lkbushi'); - player.storage.lkbushi=list2; - var str='#g'; - for(var j=0;j<4;j++){ - str+=get.translation(list2[j]); - if(j!=3) str+='/'; + "step 1"; + if (result.bool) { + var list = lib.skill.lkbushi.getBushi(player), + list2 = result.moved[0].map(function (i) { + return i[2].slice(6); + }); + for (var i = 0; i < 4; i++) { + if (list[i] != list2[i]) { + player.logSkill("lkbushi"); + player.storage.lkbushi = list2; + var str = "#g"; + for (var j = 0; j < 4; j++) { + str += get.translation(list2[j]); + if (j != 3) str += "/"; } - game.log(player,'将','#g【卜筮】','的花色序列改为',str); + game.log(player, "将", "#g【卜筮】", "的花色序列改为", str); game.delayx(); break; } } } }, - mark:true, - marktext:'筮', - intro:{ - content:function(storage,player){ - var list=lib.skill.lkbushi.getBushi(player).map((i)=>get.translation(i)); - return '①你使用'+list[0]+'牌无次数限制。②当你使用或打出'+list[1]+'牌后,你摸一张牌。③当你成为'+list[2]+'牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张'+list[3]+'牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。'; + mark: true, + marktext: "筮", + intro: { + content: function (storage, player) { + var list = lib.skill.lkbushi.getBushi(player).map((i) => get.translation(i)); + return ( + "①你使用" + + list[0] + + "牌无次数限制。②当你使用或打出" + + list[1] + + "牌后,你摸一张牌。③当你成为" + + list[2] + + "牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张" + + list[3] + + "牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。" + ); }, }, - group:['lkbushi_unlimit','lkbushi_draw','lkbushi_defend','lkbushi_gain'], - subSkill:{ - unlimit:{ - mod:{ - cardUsable:function(card,player){ - const list = lib.skill.lkbushi.getBushi(player), suit = get.suit(card); - if (suit === 'unsure' || list[0] === suit) return Infinity; + group: ["lkbushi_unlimit", "lkbushi_draw", "lkbushi_defend", "lkbushi_gain"], + subSkill: { + unlimit: { + mod: { + cardUsable: function (card, player) { + const list = lib.skill.lkbushi.getBushi(player), + suit = get.suit(card); + if (suit === "unsure" || list[0] === suit) return Infinity; }, }, - trigger:{player:'useCard1'}, - forced:true, - popup:false, - silent:true, - firstDo:true, - filter:function(event,player){ - if(event.addCount===false) return true; - var list=lib.skill.lkbushi.getBushi(player); - return (list[0]==get.suit(event.card)); + trigger: { player: "useCard1" }, + forced: true, + popup: false, + silent: true, + firstDo: true, + filter: function (event, player) { + if (event.addCount === false) return true; + var list = lib.skill.lkbushi.getBushi(player); + return list[0] == get.suit(event.card); }, - content:function(){ - trigger.addCount=false; - var stat=player.getStat().card,name=trigger.card.name; - if(stat[name]&&typeof stat[name]=='number') stat[name]--; + content: function () { + trigger.addCount = false; + var stat = player.getStat().card, + name = trigger.card.name; + if (stat[name] && typeof stat[name] == "number") stat[name]--; }, }, - draw:{ - audio:'lkbushi', - trigger:{player:['useCard','respond']}, - forced:true, - locked:false, - filter:function(event,player){ - var list=lib.skill.lkbushi.getBushi(player); - return list[1]==get.suit(event.card); + draw: { + audio: "lkbushi", + trigger: { player: ["useCard", "respond"] }, + forced: true, + locked: false, + filter: function (event, player) { + var list = lib.skill.lkbushi.getBushi(player); + return list[1] == get.suit(event.card); }, - content:function(){ + content: function () { player.draw(); }, }, - defend:{ - audio:'lkbushi', - trigger:{target:'useCardToTargeted'}, - direct:true, - filter:function(event,player){ - var list=lib.skill.lkbushi.getBushi(player); - return list[2]==get.suit(event.card)&&!event.excluded.includes(player)&&player.countCards('he')>0; + defend: { + audio: "lkbushi", + trigger: { target: "useCardToTargeted" }, + direct: true, + filter: function (event, player) { + var list = lib.skill.lkbushi.getBushi(player); + return ( + list[2] == get.suit(event.card) && + !event.excluded.includes(player) && + player.countCards("he") > 0 + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt('lkbushi'),'弃置一张牌,令'+get.translation(trigger.card)+'对你无效').set('ai',function(card){ - if(_status.event.eff>=0) return false; - return -_status.event.eff*1.1-get.value(card); - }).set('eff',get.effect(player,trigger.card,trigger.player,player)).logSkill=['lkbushi_defend',trigger.player]; - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard( + "he", + get.prompt("lkbushi"), + "弃置一张牌,令" + get.translation(trigger.card) + "对你无效" + ) + .set("ai", function (card) { + if (_status.event.eff >= 0) return false; + return -_status.event.eff * 1.1 - get.value(card); + }) + .set( + "eff", + get.effect(player, trigger.card, trigger.player, player) + ).logSkill = ["lkbushi_defend", trigger.player]; + "step 1"; + if (result.bool) { trigger.excluded.add(player); } }, }, - gain:{ - audio:'lkbushi', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - locked:false, - content:function(){ - var list=lib.skill.lkbushi.getBushi(player); - var card=get.cardPile(function(card){ - return get.suit(card,false)==list[3]; + gain: { + audio: "lkbushi", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + locked: false, + content: function () { + var list = lib.skill.lkbushi.getBushi(player); + var card = get.cardPile(function (card) { + return get.suit(card, false) == list[3]; }); - if(card) player.gain(card,'gain2'); + if (card) player.gain(card, "gain2"); }, }, }, }, - lkzhongzhuang:{ - audio:2, - trigger:{source:['damageBegin1','damageBegin4']}, - forced:true, - filter:function(event,player,name){ - if(!event.card||event.card.name!='sha'||event.getParent().type!='card') return false; - var range=player.getAttackRange(); - if(name=='damageBegin1') return range>3; - return range<3&&event.num>1; + lkzhongzhuang: { + audio: 2, + trigger: { source: ["damageBegin1", "damageBegin4"] }, + forced: true, + filter: function (event, player, name) { + if (!event.card || event.card.name != "sha" || event.getParent().type != "card") + return false; + var range = player.getAttackRange(); + if (name == "damageBegin1") return range > 3; + return range < 3 && event.num > 1; }, - content:function(){ - if(event.triggername=='damageBegin1') trigger.num++; - else trigger.num=1; + content: function () { + if (event.triggername == "damageBegin1") trigger.num++; + else trigger.num = 1; }, - global:'lkzhongzhuang_ai', - subSkill:{ - ai:{ - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.card&&arg.card.name=='sha'){ - if(arg.player&&arg.player.hasSkill('lkzhongzhuang')&&arg.player.getAttackRange()<3) return true; + global: "lkzhongzhuang_ai", + subSkill: { + ai: { + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.card && arg.card.name == "sha") { + if ( + arg.player && + arg.player.hasSkill("lkzhongzhuang") && + arg.player.getAttackRange() < 3 + ) + return true; } return false; }, @@ -1606,731 +2118,935 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, //顾雍 - olbingyi:{ - audio:'bingyi', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + olbingyi: { + audio: "bingyi", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - return event.type=='discard'&&event.getl(player).cards2.length>0&&player.countCards('h')>0&&!player.hasSkill('olbingyi_blocker',null,null,false); + filter: function (event, player) { + return ( + event.type == "discard" && + event.getl(player).cards2.length > 0 && + player.countCards("h") > 0 && + !player.hasSkill("olbingyi_blocker", null, null, false) + ); }, - prompt2:function(event,player){ - var str='展示所有手牌,然后',hs=player.getCards('h'); - var color=get.color(hs); - if(color=='none') return str+'无事发生'; - str+=('令至多'+get.cnNumber(hs.length)+'名其他角色和自己各摸一张牌'); + prompt2: function (event, player) { + var str = "展示所有手牌,然后", + hs = player.getCards("h"); + var color = get.color(hs); + if (color == "none") return str + "无事发生"; + str += "令至多" + get.cnNumber(hs.length) + "名其他角色和自己各摸一张牌"; return str; }, - check:function(event,player){ - var color=get.color(player.getCards('h')); - return color!='none'; + check: function (event, player) { + var color = get.color(player.getCards("h")); + return color != "none"; }, - content:function(){ - 'step 0' - player.addTempSkill('olbingyi_blocker',['phaseZhunbeiAfter','phaseJudgeAfter','phaseDrawAfter','phaseUseAfter','phaseDiscardAfter','phaseJieshuAfter']); - player.showHandcards(get.translation(player)+'发动了【秉壹】'); - if(get.color(player.getCards('h'))=='none') event.finish(); - 'step 1' - var num=player.countCards('h'); - player.chooseTarget([1,num],'令至多'+get.cnNumber(num)+'名角色也各摸一张牌',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - if(target.hasSkillTag('nogain')) att/=10; - return att; - }); - 'step 2' - var targets=[player]; - if(result.bool){ + content: function () { + "step 0"; + player.addTempSkill("olbingyi_blocker", [ + "phaseZhunbeiAfter", + "phaseJudgeAfter", + "phaseDrawAfter", + "phaseUseAfter", + "phaseDiscardAfter", + "phaseJieshuAfter", + ]); + player.showHandcards(get.translation(player) + "发动了【秉壹】"); + if (get.color(player.getCards("h")) == "none") event.finish(); + "step 1"; + var num = player.countCards("h"); + player + .chooseTarget( + [1, num], + "令至多" + get.cnNumber(num) + "名角色也各摸一张牌", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + if (target.hasSkillTag("nogain")) att /= 10; + return att; + }); + "step 2"; + var targets = [player]; + if (result.bool) { targets.addArray(result.targets); - player.line(targets,'green'); + player.line(targets, "green"); game.asyncDraw(targets.sortBySeat()); - } - else{ + } else { player.draw(); event.finish(); } - 'step 3' + "step 3"; game.delayx(); }, - subSkill:{blocker:{charlotte:true}}, + subSkill: { blocker: { charlotte: true } }, }, //孙体 - xinzhaofu:{ - audio:'zhaofu', - enable:'phaseUse', - usable:1, - mark:true, - limited:true, - skillAnimation:true, - animationColor:'wood', - selectTarget:[1,2], - filterTarget:lib.filter.notMe, - zhuSkill:true, - contentBefore:function(){ - player.awakenSkill('xinzhaofu'); + xinzhaofu: { + audio: "zhaofu", + enable: "phaseUse", + usable: 1, + mark: true, + limited: true, + skillAnimation: true, + animationColor: "wood", + selectTarget: [1, 2], + filterTarget: lib.filter.notMe, + zhuSkill: true, + contentBefore: function () { + player.awakenSkill("xinzhaofu"); }, - content:function(){ - target.addSkill('xinzhaofu_effect'); - target.markAuto('xinzhaofu_effect',[player]); + content: function () { + target.addSkill("xinzhaofu_effect"); + target.markAuto("xinzhaofu_effect", [player]); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - var targets=game.filterPlayer(function(current){ - return current.group=='wu'&&get.attitude(player,current)>0; + ai: { + order: 9, + result: { + target: function (player, target) { + var targets = game.filterPlayer(function (current) { + return current.group == "wu" && get.attitude(player, current) > 0; }); - if(targets.length){ - for(var targetx of targets){ - if(!targetx.inRange(target)) return -1; + if (targets.length) { + for (var targetx of targets) { + if (!targetx.inRange(target)) return -1; } return -0.5; } return 0; - } - } + }, + }, }, - subSkill:{ - effect:{ - charlotte:true, - mark:true, - intro:{content:'已视为在其他吴势力角色的攻击范围内'}, - mod:{ - inRangeOf:function(from,to){ - if(from.group!='wu') return; - var list=to.getStorage('xinzhaofu_effect'); - for(var i of list){ - if(i!=from) return true; + subSkill: { + effect: { + charlotte: true, + mark: true, + intro: { content: "已视为在其他吴势力角色的攻击范围内" }, + mod: { + inRangeOf: function (from, to) { + if (from.group != "wu") return; + var list = to.getStorage("xinzhaofu_effect"); + for (var i of list) { + if (i != from) return true; } }, }, }, }, }, - xinkuangbi:{ - audio:'kuangbi', - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + xinkuangbi: { + audio: "kuangbi", + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - content:function(){ - 'step 0' - target.chooseCard('he',[1,3],'匡弼:交给'+get.translation(player)+'一至三张牌',true).set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - return 7-get.value(card); - } - return -get.value(card); - }); - 'step 1' - if(result.bool){ - target.give(result.cards,player,'giveAuto').gaintag.add('xinkuangbi_keep'); - player.addTempSkill('xinkuangbi_keep'); - target.addSkill('xinkuangbi_draw'); - target.addMark('xinkuangbi_draw',result.cards.length,false); + content: function () { + "step 0"; + target + .chooseCard("he", [1, 3], "匡弼:交给" + get.translation(player) + "一至三张牌", true) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) { + return 7 - get.value(card); + } + return -get.value(card); + }); + "step 1"; + if (result.bool) { + target.give(result.cards, player, "giveAuto").gaintag.add("xinkuangbi_keep"); + player.addTempSkill("xinkuangbi_keep"); + target.addSkill("xinkuangbi_draw"); + target.addMark("xinkuangbi_draw", result.cards.length, false); } }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0){ - return Math.sqrt(target.countCards('he')); + ai: { + order: 1, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) { + return Math.sqrt(target.countCards("he")); } return 0; }, - player:1 - } + player: 1, + }, }, - subSkill:{ - keep:{ - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('xinkuangbi_keep')) return true; + subSkill: { + keep: { + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("xinkuangbi_keep")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('xinkuangbi_keep')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("xinkuangbi_keep")) + return false; }, }, - charlotte:true, - onremove:function(player){ - player.removeGaintag('xinkuangbi_keep'); + charlotte: true, + onremove: function (player) { + player.removeGaintag("xinkuangbi_keep"); }, }, - draw:{ - trigger:{player:'phaseBegin'}, - forced:true, - charlotte:true, - onremove:true, - intro:{ - content:'下回合开始时摸#张牌', + draw: { + trigger: { player: "phaseBegin" }, + forced: true, + charlotte: true, + onremove: true, + intro: { + content: "下回合开始时摸#张牌", }, - content:function(){ - player.draw(player.countMark('xinkuangbi_draw')); - player.removeSkill('xinkuangbi_draw'); + content: function () { + player.draw(player.countMark("xinkuangbi_draw")); + player.removeSkill("xinkuangbi_draw"); }, - } - } - }, - rejingce:{ - audio:'jingce', - trigger:{player:'phaseUseEnd'}, - frequent:true, - filter:function(event,player){ - return player.getHistory('useCard',function(evt){ - return evt.getParent('phaseUse')==event; - }).length>0; + }, }, - content:function(){ - var list=[]; - player.getHistory('useCard',function(evt){ - if(evt.getParent('phaseUse')==trigger) list.add(get.type2(evt.card)); + }, + rejingce: { + audio: "jingce", + trigger: { player: "phaseUseEnd" }, + frequent: true, + filter: function (event, player) { + return ( + player.getHistory("useCard", function (evt) { + return evt.getParent("phaseUse") == event; + }).length > 0 + ); + }, + content: function () { + var list = []; + player.getHistory("useCard", function (evt) { + if (evt.getParent("phaseUse") == trigger) list.add(get.type2(evt.card)); }); player.draw(list.length); }, - group:'rejingce_add', + group: "rejingce_add", }, - rejingce_add:{ - trigger:{player:'loseEnd'}, - silent:true, - firstDo:true, - filter:function(event,player){ - if(event.getParent().name!='useCard'||player!=_status.currentPhase) return false; - var list=player.getStorage('rejingce2'); - for(var i of event.cards){ - if(!list.includes(get.suit(i,player))) return true; + rejingce_add: { + trigger: { player: "loseEnd" }, + silent: true, + firstDo: true, + filter: function (event, player) { + if (event.getParent().name != "useCard" || player != _status.currentPhase) return false; + var list = player.getStorage("rejingce2"); + for (var i of event.cards) { + if (!list.includes(get.suit(i, player))) return true; } return false; }, - content:function(){ - if(!player.storage.rejingce2) player.storage.rejingce2=[]; - for(var i of trigger.cards) player.storage.rejingce2.add(get.suit(i,player)); + content: function () { + if (!player.storage.rejingce2) player.storage.rejingce2 = []; + for (var i of trigger.cards) player.storage.rejingce2.add(get.suit(i, player)); player.storage.rejingce2.sort(); - player.addTempSkill('rejingce2'); - player.markSkill('rejingce2'); + player.addTempSkill("rejingce2"); + player.markSkill("rejingce2"); }, }, - rejingce2:{ - onremove:true, - intro:{ - content:'当前已使用花色:$', + rejingce2: { + onremove: true, + intro: { + content: "当前已使用花色:$", }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getStorage('rejingce2').length; + mod: { + maxHandcard: function (player, num) { + return num + player.getStorage("rejingce2").length; }, }, }, - rejueqing:{ - audio:2, - trigger:{source:'damageBegin2'}, - skillAnimation:true, - animationColor:'water', - filter:function(event,player){ - return player!=event.player&&!player.storage.rejueqing_rewrite; + rejueqing: { + audio: 2, + trigger: { source: "damageBegin2" }, + skillAnimation: true, + animationColor: "water", + filter: function (event, player) { + return player != event.player && !player.storage.rejueqing_rewrite; }, - prompt2:function(event,player){ - var num=get.cnNumber(2*event.num,true); - return '令即将对其造成的伤害翻倍至'+num+'点,并令自己失去'+get.cnNumber(event.num)+'点体力'; + prompt2: function (event, player) { + var num = get.cnNumber(2 * event.num, true); + return ( + "令即将对其造成的伤害翻倍至" + + num + + "点,并令自己失去" + + get.cnNumber(event.num) + + "点体力" + ); }, - check:function(event,player){ - return player.hp>event.num&&event.player.hp>event.num&&!event.player.hasSkillTag('filterDamage',null,{ - player:player, - card:event.card, - })&&get.attitude(player,event.player)<0; + check: function (event, player) { + return ( + player.hp > event.num && + event.player.hp > event.num && + !event.player.hasSkillTag("filterDamage", null, { + player: player, + card: event.card, + }) && + get.attitude(player, event.player) < 0 + ); }, - locked:function(skill,player){ - return player&&player.storage.rejueqing_rewrite; + locked: function (skill, player) { + return player && player.storage.rejueqing_rewrite; }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { player.loseHp(trigger.num); - trigger.num*=2; - player.storage.rejueqing_rewrite=true; + trigger.num *= 2; + player.storage.rejueqing_rewrite = true; }, - derivation:'rejueqing_rewrite', - group:'rejueqing_rewrite', - subSkill:{ - rewrite:{ - trigger:{source:'damageBefore'}, - forced:true, - charlotte:true, - audio:'rejueqing', - filter:function(event,player){ - return player.storage.rejueqing_rewrite==true; + derivation: "rejueqing_rewrite", + group: "rejueqing_rewrite", + subSkill: { + rewrite: { + trigger: { source: "damageBefore" }, + forced: true, + charlotte: true, + audio: "rejueqing", + filter: function (event, player) { + return player.storage.rejueqing_rewrite == true; }, - check:function(){return false;}, - content:function(){ + check: function () { + return false; + }, + content: function () { trigger.cancel(); trigger.player.loseHp(trigger.num); }, - ai:{ - jueqing:true, - skillTagFilter:function(player){ - return player.storage.rejueqing_rewrite==true; + ai: { + jueqing: true, + skillTagFilter: function (player) { + return player.storage.rejueqing_rewrite == true; }, - } - } - }, - }, - reshangshi:{ - audio:2, - trigger:{ - player:['loseAfter','changeHp','gainMaxHpAfter','loseMaxHpAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], - }, - frequent:true, - prompt:function(event,player){ - return '是否发动【伤逝】将手牌摸至'+get.cnNumber(player.getDamagedHp())+'张?' - }, - prompt2:false, - filter:function(event,player){ - if(event.getl&&!event.getl(player)) return false; - return player.countCards('h')0; - }, - content:function(){ - player.chooseToDiscard('是否发动【伤逝】弃置一张牌?','he').set('logSkill','reshangshi').set('ai',function(card){ - var player=_status.event.player; - if(player.countCards('h')>player.getDamagedHp()+_status.event.getTrigger().num) return 1; - if(player.isPhaseUsing()) return 0.1-player.getUseValue(card,null,true)/Math.max(0.1,get.value(card)); - return (get.position(card)=='h'?5:0.1)-get.value(card); - }); - }, - }, - oldzhenlie:{ - audio:2, - trigger:{player:'judge'}, - check:function(event,player){ - return event.judge(player.judging[0])<0; - }, - content:function(){ - "step 0" - var card=get.cards()[0]; - event.card=card; - game.cardsGotoOrdering(card).relatedEvent=trigger; - "step 1" - player.$throw(card); - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); - } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); - } - game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=card; - game.log(trigger.player,'的判定牌改为',card); - game.delay(2); - }, - }, - oldmiji:{ - trigger:{player:['phaseZhunbeiBegin','phaseJieshuBegin']}, - audio:2, - filter:function(event,player){ - return player.isDamaged(); - }, - content:function(){ - 'step 0' - player.judge(function(card){ - return get.color(card)=='black'?1:-1; - }).judge2=function(result){ - return result.bool; - }; - 'step 1' - if(result.bool&&player.maxHp>player.hp){ - var cards=get.cards(player.maxHp-player.hp); - event.cards=cards; - player.chooseTarget(true).set('ai',function(target){ - return get.attitude(player,target)/Math.sqrt(1+target.countCards('h')); - }).set('createDialog',['请选择一名角色获得这些牌',event.cards]); - } - else{ - event.finish(); - } - 'step 2' - player.line(result.targets); - result.targets[0].gain(event.cards,'draw'); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'recover')&&target.hp==target.maxHp-1) return [0,0]; - if(target.hasFriend()){ - if((get.tag(card,'damage')==1||get.tag(card,'loseHp'))&&target.hp==target.maxHp) return [0,1]; - } - } - }, - threaten:function(player,target){ - if(target.hp==1) return 3; - if(target.hp==2) return 2; - return 1; - }, - } - }, - oldqianxi:{ - audio:2, - trigger:{source:'damageBegin2'}, - check:function(event,player){ - var att=get.attitude(player,event.player); - if(event.player.hp==event.player.maxHp) return att<0; - if(event.player.hp==event.player.maxHp-1&& - (event.player.maxHp<=3||event.player.hasSkillTag('maixie'))) return att<0; - return att>0; - }, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&get.distance(player,event.player)<=1; - }, - logTarget:'player', - content:function(){ - 'step 0' - player.judge(function(card){ - return get.suit(card)!='heart'?1:-1; - }).judge2=function(result){ - return result.bool; - }; - 'step 1' - if(result.bool){ - trigger.cancel(); - trigger.player.loseMaxHp(true); - } - } - }, - old_fuhun:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ - return !event.numFixed; - }, - content:function(){ - 'step 0' - trigger.changeToZero(); - 'step 1' - var cards=get.cards(2); - event.cards=cards; - player.showCards(cards,get.translation(player)+'发动了【父魂】'); - 'step 2' - player.gain(cards,'gain2'); - if(get.color(cards[0])!=get.color(cards[1])){ - player.addTempSkills(['wusheng','paoxiao']); - } - }, - derivation:['wusheng','paoxiao'], - }, - shiyong:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - check:function(){ - return false; - }, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&(get.color(event.card)=='red'||event.getParent(2).jiu==true); - }, - content:function(){ - player.loseMaxHp(); - } - }, - xindanshou:{ - audio:2, - trigger:{ - global:'phaseJieshuBegin', - target:'useCardToTargeted', - }, - direct:true, - filter:function(event,player,name){ - return ((name=='phaseJieshuBegin'&&event.player!=player&&player.countCards('he')>=event.player.countCards('h'))|| - (event.targets&&event.targets.includes(player)&&['basic','trick'].includes(get.type(event.card,'trick')))) - &&!player.hasSkill('xindanshou_as'); - }, - content:function(){ - 'step 0' - if(event.triggername=='phaseJieshuBegin'){ - var num=trigger.player.countCards('h'); - if(num>0) player.chooseToDiscard(get.prompt('xindanshou',trigger.player),num,'弃置'+get.cnNumber(num)+'张牌并对'+get.translation(trigger.player)+'造成1点伤害','he').set('logSkill',['xindanshou',trigger.player]).set('ai',function(card){ - if(get.damageEffect(_status.event.getTrigger().player,_status.event.player,_status.event.player)>0) return Math.max(5.5,8-_status.event.selectTarget)-get.value(card); - return -1; - }); - else player.chooseBool(get.prompt('xindanshou',trigger.player),'对'+get.translation(trigger.player)+'造成1点伤害').ai=function(){ - return get.damageEffect(trigger.player,player,player)>0 - }; - } - else{ - var num=0; - game.countPlayer2(function(current){ - var history=current.getHistory('useCard'); - for(var j=0;j0&&player.getUseValue(card,null,true)>0; - })) return false; - return true; - } - if(num>2) return true; - var card=trigger.card; - if(get.tag(card,'damage')&&player.hp<=trigger.getParent().baseDamage&&(!get.tag(card,'respondShan')||!player.hasShan())&&(!get.tag(card,'respondSha')||!player.hasSha())) return true; - var source=_status.currentPhase,todis=source.countCards('h')-source.needsToDiscard(); - if(todis<=Math.max(Math.min(2+(source.hp<=1?1:0),player.countCards('he',function(card){ - return get.value(card,player)0) return false; - if(!source.isPhaseUsing()||get.attitude(player,source)>0) return true; - if(card.name=='sha'&&!source.getCardUsable('sha')) return true; - return Math.random()0) return [1.1,num]; - return [0.9,num]; }, }, }, }, - xinbenxi:{ - group:['xinbenxi_summer','xinbenxi_damage'], - audio:2, - trigger:{ - player:'useCard2', + reshangshi: { + audio: 2, + trigger: { + player: ["loseAfter", "changeHp", "gainMaxHpAfter", "loseMaxHpAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - mod:{ - globalFrom:function(from,to,distance){ - if(_status.currentPhase==from){ - return distance-from.storage.xinbenxi; - } - }, - wuxieRespondable:function(card,player,target,current){ - if(player!=current&&player.storage.xinbenxi_directHit.includes(card)){ + frequent: true, + prompt: function (event, player) { + return "是否发动【伤逝】将手牌摸至" + get.cnNumber(player.getDamagedHp()) + "张?"; + }, + prompt2: false, + filter: function (event, player) { + if (event.getl && !event.getl(player)) return false; + return player.countCards("h") < player.getDamagedHp(); + }, + content: function () { + player.draw(player.getDamagedHp() - player.countCards("h")); + }, + ai: { + noh: true, + skillTagFilter: function (player, tag) { + if (tag == "noh" && player.maxHp - player.hp < player.countCards("h")) { return false; } }, }, - init:function(player){ - player.storage.xinbenxi_directHit=[]; - player.storage.xinbenxi_damage=[]; - player.storage.xinbenxi_unequip=[]; - player.storage.xinbenxi=0; + group: "reshangshi_2nd", + }, + reshangshi_2nd: { + trigger: { player: "damageBegin3" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - filter:function(trigger,player){ - return _status.currentPhase==player&&trigger.targets&&trigger.targets.length==1&&(get.name(trigger.card)=='sha'||get.type(trigger.card)=='trick')&&!game.hasPlayer(function(current){ - return get.distance(player,current)>1; - }); + content: function () { + player + .chooseToDiscard("是否发动【伤逝】弃置一张牌?", "he") + .set("logSkill", "reshangshi") + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.countCards("h") > + player.getDamagedHp() + _status.event.getTrigger().num + ) + return 1; + if (player.isPhaseUsing()) + return ( + 0.1 - + player.getUseValue(card, null, true) / Math.max(0.1, get.value(card)) + ); + return (get.position(card) == "h" ? 5 : 0.1) - get.value(card); + }); }, - filterx:function(event,player){ - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return lib.filter.targetEnabled2(event.card,player,current)&&!event.targets.includes(current); - })){ + }, + oldzhenlie: { + audio: 2, + trigger: { player: "judge" }, + check: function (event, player) { + return event.judge(player.judging[0]) < 0; + }, + content: function () { + "step 0"; + var card = get.cards()[0]; + event.card = card; + game.cardsGotoOrdering(card).relatedEvent = trigger; + "step 1"; + player.$throw(card); + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); + } + }, trigger.player.judging[0]); + game.addVideo("deletenode", player, get.cardsInfo([trigger.player.judging[0].clone])); + } + game.cardsDiscard(trigger.player.judging[0]); + trigger.player.judging[0] = card; + game.log(trigger.player, "的判定牌改为", card); + game.delay(2); + }, + }, + oldmiji: { + trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, + audio: 2, + filter: function (event, player) { + return player.isDamaged(); + }, + content: function () { + "step 0"; + player.judge(function (card) { + return get.color(card) == "black" ? 1 : -1; + }).judge2 = function (result) { + return result.bool; + }; + "step 1"; + if (result.bool && player.maxHp > player.hp) { + var cards = get.cards(player.maxHp - player.hp); + event.cards = cards; + player + .chooseTarget(true) + .set("ai", function (target) { + return get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); + }) + .set("createDialog", ["请选择一名角色获得这些牌", event.cards]); + } else { + event.finish(); + } + "step 2"; + player.line(result.targets); + result.targets[0].gain(event.cards, "draw"); + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "recover") && target.hp == target.maxHp - 1) return [0, 0]; + if (target.hasFriend()) { + if ( + (get.tag(card, "damage") == 1 || get.tag(card, "loseHp")) && + target.hp == target.maxHp + ) + return [0, 1]; + } + }, + }, + threaten: function (player, target) { + if (target.hp == 1) return 3; + if (target.hp == 2) return 2; + return 1; + }, + }, + }, + oldqianxi: { + audio: 2, + trigger: { source: "damageBegin2" }, + check: function (event, player) { + var att = get.attitude(player, event.player); + if (event.player.hp == event.player.maxHp) return att < 0; + if ( + event.player.hp == event.player.maxHp - 1 && + (event.player.maxHp <= 3 || event.player.hasSkillTag("maixie")) + ) + return att < 0; + return att > 0; + }, + filter: function (event, player) { + return event.card && event.card.name == "sha" && get.distance(player, event.player) <= 1; + }, + logTarget: "player", + content: function () { + "step 0"; + player.judge(function (card) { + return get.suit(card) != "heart" ? 1 : -1; + }).judge2 = function (result) { + return result.bool; + }; + "step 1"; + if (result.bool) { + trigger.cancel(); + trigger.player.loseMaxHp(true); + } + }, + }, + old_fuhun: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { + return !event.numFixed; + }, + content: function () { + "step 0"; + trigger.changeToZero(); + "step 1"; + var cards = get.cards(2); + event.cards = cards; + player.showCards(cards, get.translation(player) + "发动了【父魂】"); + "step 2"; + player.gain(cards, "gain2"); + if (get.color(cards[0]) != get.color(cards[1])) { + player.addTempSkills(["wusheng", "paoxiao"]); + } + }, + derivation: ["wusheng", "paoxiao"], + }, + shiyong: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + check: function () { + return false; + }, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + (get.color(event.card) == "red" || event.getParent(2).jiu == true) + ); + }, + content: function () { + player.loseMaxHp(); + }, + ai: { + neg: true + }, + }, + xindanshou: { + audio: 2, + trigger: { + global: "phaseJieshuBegin", + target: "useCardToTargeted", + }, + direct: true, + filter: function (event, player, name) { + return ( + ((name == "phaseJieshuBegin" && + event.player != player && + player.countCards("he") >= event.player.countCards("h")) || + (event.targets && + event.targets.includes(player) && + ["basic", "trick"].includes(get.type(event.card, "trick")))) && + !player.hasSkill("xindanshou_as") + ); + }, + content: function () { + "step 0"; + if (event.triggername == "phaseJieshuBegin") { + var num = trigger.player.countCards("h"); + if (num > 0) + player + .chooseToDiscard( + get.prompt("xindanshou", trigger.player), + num, + "弃置" + + get.cnNumber(num) + + "张牌并对" + + get.translation(trigger.player) + + "造成1点伤害", + "he" + ) + .set("logSkill", ["xindanshou", trigger.player]) + .set("ai", function (card) { + if ( + get.damageEffect( + _status.event.getTrigger().player, + _status.event.player, + _status.event.player + ) > 0 + ) + return ( + Math.max(5.5, 8 - _status.event.selectTarget) - get.value(card) + ); + return -1; + }); + else + player.chooseBool( + get.prompt("xindanshou", trigger.player), + "对" + get.translation(trigger.player) + "造成1点伤害" + ).ai = function () { + return get.damageEffect(trigger.player, player, player) > 0; + }; + } else { + var num = 0; + game.countPlayer2(function (current) { + var history = current.getHistory("useCard"); + for (var j = 0; j < history.length; j++) { + if ( + ["basic", "trick"].includes(get.type(history[j].card, "trick")) && + history[j].targets && + history[j].targets.includes(player) + ) + num++; + } + }); + event.num = num; + player + .chooseBool( + get.prompt("xindanshou") + "(可摸" + get.cnNumber(num) + "张牌)", + get.translation("xindanshou_info") + ) + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (player.isPhaseUsing()) { + if ( + player.countCards("h", function (card) { + return ( + ["basic", "trick"].includes(get.type(card, "trick")) && + player.canUse(card, player, null, true) && + get.effect(player, card, player) > 0 && + player.getUseValue(card, null, true) > 0 + ); + }) + ) + return false; + return true; + } + if (num > 2) return true; + var card = trigger.card; + if ( + get.tag(card, "damage") && + player.hp <= trigger.getParent().baseDamage && + (!get.tag(card, "respondShan") || !player.hasShan()) && + (!get.tag(card, "respondSha") || !player.hasSha()) + ) + return true; + var source = _status.currentPhase, + todis = source.countCards("h") - source.needsToDiscard(); + if ( + todis <= + Math.max( + Math.min( + 2 + (source.hp <= 1 ? 1 : 0), + player.countCards("he", function (card) { + return ( + get.value(card, player) < Math.max(5.5, 8 - todis) + ); + }) + ), + player.countCards("he", function (card) { + return get.value(card, player) <= 0; + }) + ) && + get.damageEffect(source, player, player) > 0 + ) + return false; + if (!source.isPhaseUsing() || get.attitude(player, source) > 0) + return true; + if (card.name == "sha" && !source.getCardUsable("sha")) return true; + return Math.random() < num / 3; + })() + ); + } + "step 1"; + if (result.bool) { + if (!result.cards || !result.cards.length) { + player.logSkill("xindanshou", trigger.player); + } + if (event.triggername == "useCardToTargeted") { + player.draw(num); + player.addTempSkill("xindanshou_as"); + } else { + trigger.player.damage("nocard"); + } + } + }, + subSkill: { as: { sub: true } }, + ai: { + threaten: 0.6, + effect: { + target: function (card, player, target, current) { + if ( + typeof card != "object" || + target.hasSkill("xindanshou_as") || + !["basic", "trick"].includes(get.type(card, "trick")) + ) + return; + var num = 0; + game.countPlayer2(function (current) { + var history = current.getHistory("useCard"); + for (var j = 0; j < history.length; j++) { + if ( + ["basic", "trick"].includes(get.type(history[j].card, "trick")) && + history[j].targets && + history[j].targets.includes(player) + ) + num++; + } + }); + if (player == target && current > 0) return [1.1, num]; + return [0.9, num]; + }, + }, + }, + }, + xinbenxi: { + group: ["xinbenxi_summer", "xinbenxi_damage"], + audio: 2, + trigger: { + player: "useCard2", + }, + forced: true, + mod: { + globalFrom: function (from, to, distance) { + if (_status.currentPhase == from) { + return distance - from.storage.xinbenxi; + } + }, + wuxieRespondable: function (card, player, target, current) { + if (player != current && player.storage.xinbenxi_directHit.includes(card)) { + return false; + } + }, + }, + init: function (player) { + player.storage.xinbenxi_directHit = []; + player.storage.xinbenxi_damage = []; + player.storage.xinbenxi_unequip = []; + player.storage.xinbenxi = 0; + }, + filter: function (trigger, player) { + return ( + _status.currentPhase == player && + trigger.targets && + trigger.targets.length == 1 && + (get.name(trigger.card) == "sha" || get.type(trigger.card) == "trick") && + !game.hasPlayer(function (current) { + return get.distance(player, current) > 1; + }) + ); + }, + filterx: function (event, player) { + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + lib.filter.targetEnabled2(event.card, player, current) && + !event.targets.includes(current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - "step 0" - var list=[ - '为XXX多选择一个目标', - ' 令XXX无视防具牌 ', - ' 令XXX不可被抵消 ', - '当XXX造成伤害时摸牌', - ],card=get.translation(trigger.card); - for(var i=0;i0; - })) return 1.6+Math.random(); + next.set("bool1", lib.skill.xinbenxi.filterx(trigger, player)); + next.set("ai", function (button) { + var player = _status.event.player; + var event = _status.event.getTrigger(); + switch (button.link) { + case 0: { + if ( + game.hasPlayer(function (current) { + return ( + lib.filter.targetEnabled2(event.card, player, current) && + !event.targets.includes(current) && + get.effect(current, event.card, player, player) > 0 + ); + }) + ) + return 1.6 + Math.random(); return 0; } - case 1:{ - if(event.targets.filter(function(current){ - var eff1=get.effect(current,event.card,player,player); - player._xinbenxi_ai=true; - var eff2=get.effect(current,event.card,player,player); - delete player._xinbenxi_ai; - return eff1>eff2; - }).length) return 1.9+Math.random(); + case 1: { + if ( + event.targets.filter(function (current) { + var eff1 = get.effect(current, event.card, player, player); + player._xinbenxi_ai = true; + var eff2 = get.effect(current, event.card, player, player); + delete player._xinbenxi_ai; + return eff1 > eff2; + }).length + ) + return 1.9 + Math.random(); return Math.random(); } - case 2:{ - var num=1.3; - if(event.card.name=='sha'&&event.targets.filter(function(current){ - if(current.mayHaveShan(player,'use',current.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))&&get.attitude(player,current)<=0){ - if(current.hasSkillTag('useShan')) num=1.9; - return true; - } - return false; - }).length) return num+Math.random(); - return 0.5+Math.random(); + case 2: { + var num = 1.3; + if ( + event.card.name == "sha" && + event.targets.filter(function (current) { + if ( + current.mayHaveShan( + player, + "use", + current.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + get.attitude(player, current) <= 0 + ) { + if (current.hasSkillTag("useShan")) num = 1.9; + return true; + } + return false; + }).length + ) + return num + Math.random(); + return 0.5 + Math.random(); } - case 3:{ - return (get.tag(event.card,'damage')||0)+Math.random(); + case 3: { + return (get.tag(event.card, "damage") || 0) + Math.random(); } } }); - "step 1" - var map=[ - function(trigger,player,event){ - player.chooseTarget('请选择'+get.translation(trigger.card)+'的额外目标',true,function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target); - }).set('targets',trigger.targets).set('card',trigger.card).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }); + "step 1"; + var map = [ + function (trigger, player, event) { + player + .chooseTarget( + "请选择" + get.translation(trigger.card) + "的额外目标", + true, + function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return lib.filter.targetEnabled2(_status.event.card, player, target); + } + ) + .set("targets", trigger.targets) + .set("card", trigger.card) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }); }, - function(trigger,player,event){ + function (trigger, player, event) { player.storage.xinbenxi_unequip.add(trigger.card); }, - function(trigger,player,event){ + function (trigger, player, event) { player.storage.xinbenxi_directHit.add(trigger.card); - trigger.nowuxie=true; - trigger.customArgs.default.directHit2=true; + trigger.nowuxie = true; + trigger.customArgs.default.directHit2 = true; }, - function(trigger,player,event){ + function (trigger, player, event) { player.storage.xinbenxi_damage.add(trigger.card); - } + }, ]; - for(var i=0;i1; - })) return false; - if(tag=='directHit_ai') return arg.card.name=='sha'; - if(!arg||!arg.card||arg.card.name!='sha'&&arg.card.name!='chuqibuyi') return false; - var card=arg.target.getEquip(2); - if(card&&card.name.indexOf('bagua')!=-1) return true; - if(player._xinbenxi_ai) return false; + if ( + _status.currentPhase != player || + game.hasPlayer(function (current) { + return get.distance(player, current) > 1; + }) + ) + return false; + if (tag == "directHit_ai") return arg.card.name == "sha"; + if (!arg || !arg.card || (arg.card.name != "sha" && arg.card.name != "chuqibuyi")) + return false; + var card = arg.target.getEquip(2); + if (card && card.name.indexOf("bagua") != -1) return true; + if (player._xinbenxi_ai) return false; }, }, - subSkill:{ - damage:{ - sub:true, - trigger:{global:'damageBegin1'}, - audio:2, - forced:true, - filter:function(event,player){ - return event.card&&player.storage.xinbenxi_damage.includes(event.card); + subSkill: { + damage: { + sub: true, + trigger: { global: "damageBegin1" }, + audio: 2, + forced: true, + filter: function (event, player) { + return event.card && player.storage.xinbenxi_damage.includes(event.card); + }, + content: function () { + player.draw(); }, - content:function(){player.draw()}, }, - summer:{ - sub:true, - trigger:{player:['phaseAfter','useCardAfter','useCard']}, - silent:true, - filter:function(event,player){ - return player==_status.currentPhase; + summer: { + sub: true, + trigger: { player: ["phaseAfter", "useCardAfter", "useCard"] }, + silent: true, + filter: function (event, player) { + return player == _status.currentPhase; }, - content:function(){ - if(trigger.name=='phase'){ - player.storage.xinbenxi=0; + content: function () { + if (trigger.name == "phase") { + player.storage.xinbenxi = 0; return; - } - else if(event.triggername=='useCard'){ - player.logSkill('xinbenxi'); + } else if (event.triggername == "useCard") { + player.logSkill("xinbenxi"); player.storage.xinbenxi++; - player.syncStorage('xinbenxi'); + player.syncStorage("xinbenxi"); return; - } - else{ + } else { player.storage.xinbenxi_unequip.remove(event.card); player.storage.xinbenxi_directHit.remove(event.card); player.storage.xinbenxi_damage.remove(event.card); @@ -2339,3325 +3055,3745 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - xinyaoming:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + xinyaoming: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - filter:function(event,player){ - return game.hasPlayer(function(target){ - return ['摸牌','弃牌','制衡'].some(function(control){ - var storage=player.getStorage('xinyaoming_kanon'); - if(storage.includes(control)) return false; - if(control=='摸牌'&&target!=player) return true; - if(control=='弃牌'&&target!=player&&target.countCards('h')) return true; - if(control=='制衡') return true; + filter: function (event, player) { + return game.hasPlayer(function (target) { + return ["摸牌", "弃牌", "制衡"].some(function (control) { + var storage = player.getStorage("xinyaoming_kanon"); + if (storage.includes(control)) return false; + if (control == "摸牌" && target != player) return true; + if (control == "弃牌" && target != player && target.countCards("h")) return true; + if (control == "制衡") return true; return false; }); }); }, - direct:true, - content:function(){ - 'step 0' - var func=function(){ - game.countPlayer(function(target){ - var list=['摸牌','弃牌','制衡'].filter(function(control){ - var storage=player.getStorage('xinyaoming_kanon'); - if(storage.includes(control)) return false; - if(control=='摸牌'&&target!=player) return true; - if(control=='弃牌'&&target!=player&&target.countCards('h')) return true; - if(control=='制衡') return true; - return false; - }),str=''; - for(var i of list) str+=(i+'
              '); - str=str.slice(0,-4); + direct: true, + content: function () { + "step 0"; + var func = function () { + game.countPlayer(function (target) { + var list = ["摸牌", "弃牌", "制衡"].filter(function (control) { + var storage = player.getStorage("xinyaoming_kanon"); + if (storage.includes(control)) return false; + if (control == "摸牌" && target != player) return true; + if (control == "弃牌" && target != player && target.countCards("h")) + return true; + if (control == "制衡") return true; + return false; + }), + str = ""; + for (var i of list) str += i + "
              "; + str = str.slice(0, -4); target.prompt(str); }); }; - if(event.player==game.me) func(); - else if(event.isOnline()) player.send(func); - player.chooseTarget(get.prompt2('xinyaoming'),function(card,player,target){ - var storage=player.getStorage('xinyaoming_kanon'); - if(!storage.includes('制衡')) return true; - if(target==player) return false; - return !storage.includes('摸牌')||target.countCards('h'); - }).set('ai',function(target){ - var player=_status.event.player; - var storage=player.getStorage('xinyaoming_kanon'); - if(get.attitude(player,target)>0&&!storage.includes('摸牌')&&target!=player) return get.effect(target,{name:'draw'},player,player); - if(get.attitude(player,target)<0&&!storage.includes('弃牌')&&target!=player&&target.countCards('h')) return get.effect(target,{name:'guohe_copy2'},player,player); - if(get.attitude(player,target)>0&&!storage.includes('制衡')) return get.effect(target,{name:'kaihua'},player,player); - return 0; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xinyaoming',target); - var controls=['摸牌','弃牌','制衡'].filter(function(control){ - var storage=player.getStorage('xinyaoming_kanon'); - if(storage.includes(control)) return false; - if(control=='摸牌'&&target!=player) return true; - if(control=='弃牌'&&target!=player&&target.countCards('h')) return true; - if(control=='制衡') return true; + if (event.player == game.me) func(); + else if (event.isOnline()) player.send(func); + player + .chooseTarget(get.prompt2("xinyaoming"), function (card, player, target) { + var storage = player.getStorage("xinyaoming_kanon"); + if (!storage.includes("制衡")) return true; + if (target == player) return false; + return !storage.includes("摸牌") || target.countCards("h"); + }) + .set("ai", function (target) { + var player = _status.event.player; + var storage = player.getStorage("xinyaoming_kanon"); + if ( + get.attitude(player, target) > 0 && + !storage.includes("摸牌") && + target != player + ) + return get.effect(target, { name: "draw" }, player, player); + if ( + get.attitude(player, target) < 0 && + !storage.includes("弃牌") && + target != player && + target.countCards("h") + ) + return get.effect(target, { name: "guohe_copy2" }, player, player); + if (get.attitude(player, target) > 0 && !storage.includes("制衡")) + return get.effect(target, { name: "kaihua" }, player, player); + return 0; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xinyaoming", target); + var controls = ["摸牌", "弃牌", "制衡"].filter(function (control) { + var storage = player.getStorage("xinyaoming_kanon"); + if (storage.includes(control)) return false; + if (control == "摸牌" && target != player) return true; + if (control == "弃牌" && target != player && target.countCards("h")) return true; + if (control == "制衡") return true; return false; }); - if(controls.length==1) event._result={control:controls[0]}; - else{ - var str=get.translation(target); - var choiceList=[ - '令'+str+'摸一张牌', - '弃置'+str+'一张手牌', - '令'+str+'弃置至多两张牌,然后其摸等量的牌', + if (controls.length == 1) event._result = { control: controls[0] }; + else { + var str = get.translation(target); + var choiceList = [ + "令" + str + "摸一张牌", + "弃置" + str + "一张手牌", + "令" + str + "弃置至多两张牌,然后其摸等量的牌", ]; - var list=['摸牌','弃牌','制衡']; - for(var i=0;i<3;i++){ - if(!controls.includes(list[i])){ - choiceList[i]=''+choiceList[i]+''; + var list = ["摸牌", "弃牌", "制衡"]; + for (var i = 0; i < 3; i++) { + if (!controls.includes(list[i])) { + choiceList[i] = '' + choiceList[i] + ""; } } - player.chooseControl(controls).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player; - var target=_status.event.target; - var controls=_status.event.controls.slice(); - var map={ - '摸牌':get.effect(target,{name:'draw'},player,player), - '弃牌':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); + player + .chooseControl(controls) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player; + var target = _status.event.target; + var controls = _status.event.controls.slice(); + var map = { + 摸牌: get.effect(target, { name: "draw" }, player, player), + 弃牌: 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); } - } - else event.finish(); - 'step 2' - player.addTempSkill('xinyaoming_kanon'); - player.markAuto('xinyaoming_kanon',[result.control]); - switch(result.control){ - case '摸牌': + } else event.finish(); + "step 2"; + player.addTempSkill("xinyaoming_kanon"); + player.markAuto("xinyaoming_kanon", [result.control]); + switch (result.control) { + case "摸牌": target.draw(); break; - case '弃牌': - player.discardPlayerCard(target,'h',true); + case "弃牌": + player.discardPlayerCard(target, "h", true); break; - case '制衡': - target.chooseToDiscard([1,2],'he','邀名:弃置至多两张牌,然后摸等量的牌',true).set('ai',card=>lib.skill.zhiheng.check(card)); + case "制衡": + target + .chooseToDiscard([1, 2], "he", "邀名:弃置至多两张牌,然后摸等量的牌", true) + .set("ai", (card) => lib.skill.zhiheng.check(card)); break; } - if(result.control!='制衡') event.finish(); - 'step 3' - if(result.bool){ + if (result.control != "制衡") event.finish(); + "step 3"; + if (result.bool) { target.draw(result.cards.length); } }, - subSkill:{ - kanon:{ - charlotte:true, - onremove:true, + subSkill: { + kanon: { + charlotte: true, + onremove: true, }, }, }, - xinfuli:{ - audio:2, - skillAnimation:true, - animationColor:'soil', - unique:true, - limited:true, - enable:'chooseToUse', - mark:true, - filter:function(event,player){ - if(event.type!='dying') return false; - if(player!=event.dying) return false; + xinfuli: { + audio: 2, + skillAnimation: true, + animationColor: "soil", + unique: true, + limited: true, + enable: "chooseToUse", + mark: true, + filter: function (event, player) { + if (event.type != "dying") return false; + if (player != event.dying) return false; return true; }, - content:function(){ - "step 0" - player.awakenSkill('xinfuli'); - event.num=game.countGroup(); - player.recover(event.num-player.hp); - "step 1" - var num2=num-player.countCards('h'); - if(num2) player.draw(num2); - "step 2" - if(num>2) player.turnOver(); - player.storage.xinfuli=true; + content: function () { + "step 0"; + player.awakenSkill("xinfuli"); + event.num = game.countGroup(); + player.recover(event.num - player.hp); + "step 1"; + var num2 = num - player.countCards("h"); + if (num2) player.draw(num2); + "step 2"; + if (num > 2) player.turnOver(); + player.storage.xinfuli = true; }, - ai:{ - save:true, - skillTagFilter:function(player,arg,target){ - return player==target; + ai: { + save: true, + skillTagFilter: function (player, arg, target) { + return player == target; }, - result:{ - player:10 + result: { + player: 10, + }, + threaten: function (player, target) { + if (!target.storage.xinfuli) return 0.9; }, - threaten:function(player,target){ - if(!target.storage.xinfuli) return 0.9; - } }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - xindangxian:{ - trigger:{player:'phaseBegin'}, - forced:true, - audio:'dangxian', - audioname:['guansuo','xin_liaohua','re_liaohua'], - audioname2:{ - dc_guansuo:'dangxian_guansuo', + xindangxian: { + trigger: { player: "phaseBegin" }, + forced: true, + audio: "dangxian", + audioname: ["guansuo", "xin_liaohua", "re_liaohua"], + audioname2: { + dc_guansuo: "dangxian_guansuo", }, - content:function(){ - trigger.phaseList.splice(trigger.num,0,'phaseUse|xindangxian'); + content: function () { + trigger.phaseList.splice(trigger.num, 0, "phaseUse|xindangxian"); }, - group:'xindangxian_rewrite', - subSkill:{ - rewrite:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - popup:false, - filter:function(kagari){ - return kagari._extraPhaseReason=='xindangxian'; + group: "xindangxian_rewrite", + subSkill: { + rewrite: { + trigger: { player: "phaseUseBegin" }, + forced: true, + popup: false, + filter: function (kagari) { + return kagari._extraPhaseReason == "xindangxian"; }, - content:function(){ - 'step 0' - if(player.storage.xinfuli){ - player.chooseBool('是否失去1点体力并获得一张【杀】?').ai=function(){ - return player.hp>2&&!player.hasSha(); + content: function () { + "step 0"; + if (player.storage.xinfuli) { + player.chooseBool("是否失去1点体力并获得一张【杀】?").ai = function () { + return player.hp > 2 && !player.hasSha(); }; - } - else event._result={bool:true}; - 'step 1' - if(!result.bool){ + } else event._result = { bool: true }; + "step 1"; + if (!result.bool) { event.finish(); return; } player.loseHp(); - 'step 2' - var card=get.cardPile(function(card){ - return card.name=='sha'; + "step 2"; + var card = get.cardPile(function (card) { + return card.name == "sha"; }); - if(card) player.gain(card,'gain2'); - 'step 3' + if (card) player.gain(card, "gain2"); + "step 3"; game.updateRoundNumber(); }, }, }, }, - dangxian_guansuo:{audio:2}, - xinjunxing:{ - inherit:'junxing', - audio:'junxing', - content:function(){ - "step 0" - var types=[]; - for(var i=0;i=0?-1:(9-get.value(card)); + content: function () { + "step 0"; + targets[0].chooseCard( + "交给" + + get.translation(player) + + "一张【杀】或武器牌,否则视为对" + + get.translation(targets[1]) + + "使用一张【杀】", + "he", + function (card) { + return get.name(card) == "sha" || get.subtype(card) == "equip1"; + } + ).ai = function (card) { + var player = _status.event.player; + var target = _status.event.getParent("xinzhige").targets[1]; + return get.effect(target, { name: "sha" }, player, player) >= 0 + ? -1 + : 9 - get.value(card); }; - "step 1" - if(result.bool){ - targets[0].give(result.cards,player,'give'); - } - else{ - if(targets[0].canUse('sha',targets[1])) targets[0].useCard({name:'sha',isCard:true},targets[1]); + "step 1"; + if (result.bool) { + targets[0].give(result.cards, player, "give"); + } else { + if (targets[0].canUse("sha", targets[1])) + targets[0].useCard({ name: "sha", isCard: true }, targets[1]); } }, - ai:{ - result:{ - target:function(player,target){ - if(ui.selected.targets.length){ - var from=ui.selected.targets[0]; - return get.effect(target,{name:'sha'},from,target); + ai: { + result: { + target: function (player, target) { + if (ui.selected.targets.length) { + var from = ui.selected.targets[0]; + return get.effect(target, { name: "sha" }, from, target); } - var effs=[0,0]; - game.countPlayer(function(current){ - if(current!=target&&target.canUse('sha',current)){ - var eff=get.effect(current,{name:'sha'},target,target); - if(eff>effs[0]) effs[0]=eff; - if(eff effs[0]) effs[0] = eff; + if (eff < effs[1]) effs[1] = eff; } }); - return effs[get.attitude(player,target)>0?0:1]; - } + return effs[get.attitude(player, target) > 0 ? 0 : 1]; + }, }, - order:8.5, - expose:0.2 - } + order: 8.5, + expose: 0.2, + }, }, - xinzongzuo:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + xinzongzuo: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - audio:'zongzuo', - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + audio: "zongzuo", + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var num=game.countGroup(); + content: function () { + "step 0"; + var num = game.countGroup(); player.gainMaxHp(num); - event.num=num; - 'step 1' + event.num = num; + "step 1"; player.recover(event.num); //player.update(); }, - group:'xinzongzuo_lose', - subSkill:{ - lose:{ - trigger:{global:'dieAfter'}, - forced:true, - audio:'zongzuo', - filter:function(event,player){ - if(!lib.group.includes(event.player.group)) return false; - if(game.hasPlayer(function(current){ - return current.group==event.player.group; - })){ + group: "xinzongzuo_lose", + subSkill: { + lose: { + trigger: { global: "dieAfter" }, + forced: true, + audio: "zongzuo", + filter: function (event, player) { + if (!lib.group.includes(event.player.group)) return false; + if ( + game.hasPlayer(function (current) { + return current.group == event.player.group; + }) + ) { return false; } return true; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseMaxHp(); - 'step 1' + "step 1"; player.draw(2); - } - } - } + }, + }, + }, }, - xintaoluan:{ - hiddenCard:function(player,name){ - return !player.getStorage('xintaoluan').includes(name)&&player.countCards('hes')>0&&!player.hasSkill('xintaoluan3')&&lib.inpile.includes(name); + xintaoluan: { + hiddenCard: function (player, name) { + return ( + !player.getStorage("xintaoluan").includes(name) && + player.countCards("hes") > 0 && + !player.hasSkill("xintaoluan3") && + lib.inpile.includes(name) + ); }, - audio:'taoluan', - enable:'chooseToUse', - filter:function(event,player){ - return !player.hasSkill('xintaoluan3')&&player.hasCard(card=>lib.inpile.some(name=>{ - if(player.getStorage('xintaoluan').includes(name)) return false; - if(get.type(name)!='basic'&&get.type(name)!='trick') return false; - if(event.filterCard({name:name,isCard:true,cards:[card]},player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard({name:name,nature:nature,isCard:true,cards:[card]},player,event)) return true; - } - } - return false; - },'hes'))>0&&!_status.dying.length; + audio: "taoluan", + enable: "chooseToUse", + filter: function (event, player) { + return ( + !player.hasSkill("xintaoluan3") && + player.hasCard((card) => + lib.inpile.some((name) => { + if (player.getStorage("xintaoluan").includes(name)) return false; + if (get.type(name) != "basic" && get.type(name) != "trick") return false; + if ( + event.filterCard( + { name: name, isCard: true, cards: [card] }, + player, + event + ) + ) + return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + { name: name, nature: nature, isCard: true, cards: [card] }, + player, + event + ) + ) + return true; + } + } + return false; + }, "hes") + ) > 0 && + !_status.dying.length + ); }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)=='basic'||get.type(name)=='trick'){ - if(player.getStorage('xintaoluan').includes(name)) continue; - list.push([get.translation(get.type(name)),'',name]); - if(name=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) == "basic" || get.type(name) == "trick") { + if (player.getStorage("xintaoluan").includes(name)) continue; + list.push([get.translation(get.type(name)), "", name]); + if (name == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } } - return ui.create.dialog('滔乱',[list,'vcard']); + return ui.create.dialog("滔乱", [list, "vcard"]); }, - filter:function(button,player){ - return _status.event.getParent().filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return _status.event + .getParent() + .filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(player.countCards('hes',cardx=>cardx.name==card.name)) return 0; - return _status.event.getParent().type=='phase'?player.getUseValue(card):1; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if (player.countCards("hes", (cardx) => cardx.name == card.name)) return 0; + return _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:true, - audio:'taoluan', - popname:true, - check:function(card){ - return 7-get.value(card); + filterCard: true, + audio: "taoluan", + popname: true, + check: function (card) { + return 7 - get.value(card); }, - position:'hes', - viewAs:{name:links[0][2],nature:links[0][3]}, - onuse:function(result,player){ - var evt=_status.event.getParent('phase'); - if(evt&&evt.name=='phase'&&!evt.xintaoluan){ - evt.xintaoluan=true; - var next=game.createEvent('xintaoluan_clear'); + position: "hes", + viewAs: { name: links[0][2], nature: links[0][3] }, + onuse: function (result, player) { + var evt = _status.event.getParent("phase"); + if (evt && evt.name == "phase" && !evt.xintaoluan) { + evt.xintaoluan = true; + var next = game.createEvent("xintaoluan_clear"); _status.event.next.remove(next); evt.after.push(next); - next.player=player; - next.setContent(function(){ + next.player = player; + next.setContent(function () { delete player.storage.xintaoluan; delete player.storage.xintaoluan2; }); } - player.markAuto('xintaoluan',[result.card.name]); + player.markAuto("xintaoluan", [result.card.name]); }, - } + }; + }, + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt:function(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order:4, - save:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(!player.countCards('hes')||player.hasSkill('taoluan3')) return false; - if(tag=='respondSha'||tag=='respondShan'){ - if(arg=='respond') return false; - return !player.getStorage('taoluan').includes(tag=='respondSha'?'sha':'shan'); + ai: { + order: 4, + save: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (!player.countCards("hes") || player.hasSkill("taoluan3")) return false; + if (tag == "respondSha" || tag == "respondShan") { + if (arg == "respond") return false; + return !player + .getStorage("taoluan") + .includes(tag == "respondSha" ? "sha" : "shan"); } - return !player.getStorage('taoluan').includes('tao')||(!player.getStorage('taoluan').includes('jiu')&&arg==player); + return ( + !player.getStorage("taoluan").includes("tao") || + (!player.getStorage("taoluan").includes("jiu") && arg == player) + ); }, - result:{ - player:function(player){ - var num=player.countMark('xintaoluan2'); - var players=game.filterPlayer(); - for(var i=0;i((num+1)*2)&&get.attitude(player,players[i])>0){ + result: { + player: function (player) { + var num = player.countMark("xintaoluan2"); + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + players[i].countCards("he") > (num + 1) * 2 && + get.attitude(player, players[i]) > 0 + ) { return 1; } } return 0; - } + }, }, - threaten:1.9, + threaten: 1.9, }, - group:'xintaoluan2', + group: "xintaoluan2", }, - xintaoluan2:{ - trigger:{player:['useCardAfter','respondAfter']}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; - return event.skill=='xintaoluan_backup'; + xintaoluan2: { + trigger: { player: ["useCardAfter", "respondAfter"] }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + if (!game.hasPlayer((current) => current != player)) return false; + return event.skill == "xintaoluan_backup"; }, - content:function(){ - 'step 0' - player.addMark('xintaoluan2',1,false); - event.num=player.countMark('xintaoluan2'); - player.chooseTarget(true,function(card,player,target){ - return target!=player; - },'滔乱

              令一名其他角色选择一项:1.交给你'+get.cnNumber(event.num)+'张与你以此法使用的牌类别不同的牌;2.你失去'+get.cnNumber(event.num)+'点体力').set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0){ - if(get.attitude(target,player)>0){ - return target.countCards('h'); + content: function () { + "step 0"; + player.addMark("xintaoluan2", 1, false); + event.num = player.countMark("xintaoluan2"); + player + .chooseTarget( + true, + function (card, player, target) { + return target != player; + }, + '滔乱

              令一名其他角色选择一项:1.交给你' + + get.cnNumber(event.num) + + "张与你以此法使用的牌类别不同的牌;2.你失去" + + get.cnNumber(event.num) + + "点体力" + ) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) { + if (get.attitude(target, player) > 0) { + return target.countCards("h"); + } + return target.countCards("h") / 2; } - return target.countCards('h')/2; - } - return 0; - }); - 'step 1' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var type=get.type(trigger.card,'trick'); - target.chooseCard('滔乱

              交给'+get.translation(player)+get.cnNumber(num)+'张不为'+get.translation(type)+'牌的牌,或令其失去'+get.cnNumber(num)+'点体力且滔乱无效直到回合结束','he',num,function(card,player,target){ - return get.type(card,'trick')!=_status.event.cardType; - }).set('cardType',type).set('ai',function(card){ - if(_status.event.att){ - return 11-get.value(card); - } - return 0; - }).set('att',get.attitude(target,player)>0); - 'step 2' - var target=event.target; - if(result.bool){ - target.give(result.cards,player,'give'); - } - else{ - player.addTempSkill('xintaoluan3'); + return 0; + }); + "step 1"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var type = get.type(trigger.card, "trick"); + target + .chooseCard( + '滔乱

              交给' + + get.translation(player) + + get.cnNumber(num) + + "张不为" + + get.translation(type) + + "牌的牌,或令其失去" + + get.cnNumber(num) + + "点体力且滔乱无效直到回合结束", + "he", + num, + function (card, player, target) { + return get.type(card, "trick") != _status.event.cardType; + } + ) + .set("cardType", type) + .set("ai", function (card) { + if (_status.event.att) { + return 11 - get.value(card); + } + return 0; + }) + .set("att", get.attitude(target, player) > 0); + "step 2"; + var target = event.target; + if (result.bool) { + target.give(result.cards, player, "give"); + } else { + player.addTempSkill("xintaoluan3"); player.loseHp(num); } - } - }, - xintaoluan3:{charlotte:true}, - xintaoluan_backup:{}, - xincaishi:{ - trigger:{ - player:'phaseDrawBegin2' }, - audio:'caishi', - direct:true, - content:function(){ - 'step 0' - var choiceList=[ - '手牌上限-1且发动【忠鉴】时可以多展示对方的一张牌' - ]; - if(!trigger.numFixed){ - choiceList.push('摸牌阶段多摸两张牌,然后本回合内不能发动【忠鉴】'); - if(trigger.num>0){ - choiceList.unshift('摸牌阶段少摸一张牌,发动【忠鉴】时可以多展示自己的一张牌直到回合结束'); - event.first=true; + }, + xintaoluan3: { charlotte: true }, + xintaoluan_backup: {}, + xincaishi: { + trigger: { + player: "phaseDrawBegin2", + }, + audio: "caishi", + direct: true, + content: function () { + "step 0"; + var choiceList = ["手牌上限-1且发动【忠鉴】时可以多展示对方的一张牌"]; + if (!trigger.numFixed) { + choiceList.push("摸牌阶段多摸两张牌,然后本回合内不能发动【忠鉴】"); + if (trigger.num > 0) { + choiceList.unshift( + "摸牌阶段少摸一张牌,发动【忠鉴】时可以多展示自己的一张牌直到回合结束" + ); + event.first = true; } } - var next=player.chooseControl('cancel2'); - next.set('choiceList',choiceList); - next.set('prompt',get.prompt('xincaishi')); - next.set('ai',function(){return 2}); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('xincaishi'); - if(!event.first) result.index++; - trigger.num+=(result.index>1?2:(result.index-1)); - player.addTempSkill('xincaishi_'+result.index); + var next = player.chooseControl("cancel2"); + next.set("choiceList", choiceList); + next.set("prompt", get.prompt("xincaishi")); + next.set("ai", function () { + return 2; + }); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("xincaishi"); + if (!event.first) result.index++; + trigger.num += result.index > 1 ? 2 : result.index - 1; + player.addTempSkill("xincaishi_" + result.index); } }, - subSkill:{ - '0':{ - mark:true, - intro:{ - content:'发动【忠鉴】时可以多展示自己的一张牌', + subSkill: { + 0: { + mark: true, + intro: { + content: "发动【忠鉴】时可以多展示自己的一张牌", }, }, - '1':{ - mark:true, - intro:{ - content:'发动【忠鉴】时可以多展示目标角色的一张牌', + 1: { + mark: true, + intro: { + content: "发动【忠鉴】时可以多展示目标角色的一张牌", }, - mod:{ - maxHandcard:function(player,num){ - return num-1; + mod: { + maxHandcard: function (player, num) { + return num - 1; }, }, }, - '2':{ - mark:true, - intro:{ - content:'不能发动【忠鉴】直到回合结束', + 2: { + mark: true, + intro: { + content: "不能发动【忠鉴】直到回合结束", }, }, }, }, - xinzhongjian:{ - audio:'zhongjian', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return (!player.hasSkill('xincaishi_2'))&&player.countCards('h')>0; + xinzhongjian: { + audio: "zhongjian", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return !player.hasSkill("xincaishi_2") && player.countCards("h") > 0; }, - filterTarget:function(event,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (event, player, target) { + return target != player && target.countCards("h") > 0; }, - filterCard:true, - selectCard:function(){ - return _status.event.player.hasSkill('xincaishi_0')?[1,2]:[1,1]; + filterCard: true, + selectCard: function () { + return _status.event.player.hasSkill("xincaishi_0") ? [1, 2] : [1, 1]; }, - check:function(){return 1}, - discard:false, - lose:false, - content:function(){ - 'step 0' - event.suits=[]; - event.nums=[]; - for(var i=0;ite&&target.isDamaged()&&get.attitude(player,target)>2) return true; - else if(pe==te&&get.attitude(player,target)>2) return true; - else if(pe te && target.isDamaged() && get.attitude(player, target) > 2) return true; + else if (pe == te && get.attitude(player, target) > 2) return true; + else if (pe < te && get.attitude(player, target) < 0) return true; return false; }); - if(ui.selected.cards.lengthte) return "回复体力"; - else if(pe==te) return "摸一张牌"; - else if(pe te) return "回复体力"; + else if (pe == te) return "摸一张牌"; + else if (pe < te) return "失去体力"; }, - line:"thunder", - content:function (){ - var pe=player.countCards('e'); - var te=target.countCards('e'); - if(pe>te) target.recover(); - else if(pe==te) target.draw(); - else if(pe te) target.recover(); + else if (pe == te) target.draw(); + else if (pe < te) target.loseHp(); }, - ai:{ - order:10, - result:{ - target:function (player,target){ - var pe=player.countCards('e',function(card){ - return ui.selected.cards.includes(card)==false; + ai: { + order: 10, + result: { + target: function (player, target) { + var pe = player.countCards("e", function (card) { + return ui.selected.cards.includes(card) == false; }); - var te=target.countCards('e'); - if(pe>te&&target.isDamaged()) return 2; - else if(pe==te) return 1; - else if(pe te && target.isDamaged()) return 2; + else if (pe == te) return 1; + else if (pe < te) return -2.5; else return 0; }, }, }, }, - "new_juexiang":{ - audio:"qingxian_jilie", - trigger:{ - player:"die", + new_juexiang: { + audio: "qingxian_jilie", + trigger: { + player: "die", }, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'water', - derivation:["new_canyun"], - content:function (){ - "step 0" - if(trigger.source){ - trigger.source.discard(trigger.source.getCards('e')); + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "water", + derivation: ["new_canyun"], + content: function () { + "step 0"; + if (trigger.source) { + trigger.source.discard(trigger.source.getCards("e")); trigger.source.loseHp(); } - "step 1" - player.chooseTarget('【绝响】:是否令一名其他角色获得技能〖残韵〗?',function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countCards('ej',{suit:'club'})) att=att*2; - return 10+att; - }).set('forceDie',true); - "step 2" - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'thunder'); - target.addSkills('new_canyun'); - target.discardPlayerCard('是否弃置自己区域内的一张梅花牌,获得技能〖绝响〗?',target,'hej').set('ai',function(card){ - if(get.position(card)=='j') return 100+get.value(card); - return 100-get.value(card); - }).set('visible',true).set('filterButton',function(card){ - return get.suit(card.link)=='club'; - }); - } - else event.finish(); - "step 3" - if(result.bool) target.addSkills('new_juexiang'); + "step 1"; + player + .chooseTarget( + "【绝响】:是否令一名其他角色获得技能〖残韵〗?", + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.countCards("ej", { suit: "club" })) att = att * 2; + return 10 + att; + }) + .set("forceDie", true); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "thunder"); + target.addSkills("new_canyun"); + target + .discardPlayerCard( + "是否弃置自己区域内的一张梅花牌,获得技能〖绝响〗?", + target, + "hej" + ) + .set("ai", function (card) { + if (get.position(card) == "j") return 100 + get.value(card); + return 100 - get.value(card); + }) + .set("visible", true) + .set("filterButton", function (card) { + return get.suit(card.link) == "club"; + }); + } else event.finish(); + "step 3"; + if (result.bool) target.addSkills("new_juexiang"); }, }, - "new_canyun":{ - group:["qingxian_draw"], - complexCard:true, - complexSelect:true, - marktext:"韵", - init:function (player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + new_canyun: { + group: ["qingxian_draw"], + complexCard: true, + complexSelect: true, + marktext: "韵", + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - intro:{ - content:function (storage){ - var str=''; - var str2='
            • 出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色(不能选择已经成为过〖残韵〗目标的角色)。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)'; - if(storage.length>0){ - for(var i=0;i出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色(不能选择已经成为过〖残韵〗目标的角色)。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)"; + if (storage.length > 0) { + for (var i = 0; i < storage.length; i++) { + str += "、"; + str += get.translation(storage[i]); } - str=str.slice(1); - str2+=('
            • 已对'+str+'发动过〖残韵〗'); + str = str.slice(1); + str2 += "
            • 已对" + str + "发动过〖残韵〗"; } return str2; }, }, - mark:true, - enable:"phaseUse", - usable:1, - check:function (cardx){ - var player=_status.event.player; - var number=game.countPlayer(function(target){ - if(player==target) return false; - var pe=player.countCards('e',function(card){ - return card!=cardx&&ui.selected.cards.includes(card)==false; - }); - var te=target.countCards('e'); - if(pe>te&&target.isDamaged()&&get.attitude(player,target)>2) return true; - else if(pe te && target.isDamaged() && get.attitude(player, target) > 2) return true; + else if (pe < te && get.attitude(player, target) < 0) return true; return false; }); - if(ui.selected.cards.lengthte) return "回复体力"; - else if(pe==te) return "摸一张牌"; - else if(pe te) return "回复体力"; + else if (pe == te) return "摸一张牌"; + else if (pe < te) return "失去体力"; }, - line:"thunder", - position:"he", - content:function (){ + line: "thunder", + position: "he", + content: function () { player.storage.new_canyun.push(target); - var pe=player.countCards('e'); - var te=target.countCards('e'); - if(pe>te) target.recover(); - else if(pe==te) target.draw(); - else if(pe te) target.recover(); + else if (pe == te) target.draw(); + else if (pe < te) target.loseHp(); }, - ai:{ - order:10, - result:{ - target:function (player,target){ - var pe=player.countCards('e'); - var te=target.countCards('e'); - if(pe>te&&target.isDamaged()) return 2; - else if(pe==te) return 1; - else if(pe te && target.isDamaged()) return 2; + else if (pe == te) return 1; + else if (pe < te) return -2.5; else return 0; }, }, }, }, - "qingxian_draw":{ - trigger:{ - player:["new_qingxianAfter","new_canyunAfter"], + qingxian_draw: { + trigger: { + player: ["new_qingxianAfter", "new_canyunAfter"], }, - forced:true, - popup:false, - silent:false, - filter:function (event,player){ - return event.target==event.targets[event.targets.length-1]&&event.targets.length==player.hp; + forced: true, + popup: false, + silent: false, + filter: function (event, player) { + return ( + event.target == event.targets[event.targets.length - 1] && + event.targets.length == player.hp + ); }, - content:function (){ + content: function () { player.draw(); }, }, - zhenjun:{ - audio:"jieyue", - trigger:{ - player:"phaseZhunbeiBegin", + zhenjun: { + audio: "jieyue", + trigger: { + player: "phaseZhunbeiBegin", }, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>current.hp; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") > current.hp; }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('zhenjun'),function(card,player,target){ - return target.countCards('h')>target.hp; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)*(target.countCards('e')+1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var num=target.countCards('h')-target.hp; - player.line(target,'thunder'); - player.logSkill('zhenjun',target); - player.discardPlayerCard(num,target,true); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("zhenjun"), function (card, player, target) { + return target.countCards("h") > target.hp; + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) * (target.countCards("e") + 1); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var num = target.countCards("h") - target.hp; + player.line(target, "thunder"); + player.logSkill("zhenjun", target); + player.discardPlayerCard(num, target, true); } - 'step 2' - if(result.cards&&result.cards.length){ - event.num=0; - event.num2=result.cards.length; - for(var i=0;i0){ - var prompt='弃置'+get.cnNumber(event.num)+'张牌,或令'+get.translation(event.target)+'摸'+get.cnNumber(event.num2)+'张牌'; - player.chooseToDiscard(event.num,prompt,'he').ai=function(card){ - return 5-get.value(card); - } - } - else event.finish(); - } - else event.finish(); - 'step 3' - if(!result.bool){ + if (event.num > 0) { + var prompt = + "弃置" + + get.cnNumber(event.num) + + "张牌,或令" + + get.translation(event.target) + + "摸" + + get.cnNumber(event.num2) + + "张牌"; + player.chooseToDiscard(event.num, prompt, "he").ai = function (card) { + return 5 - get.value(card); + }; + } else event.finish(); + } else event.finish(); + "step 3"; + if (!result.bool) { event.target.draw(event.num2); } }, }, - rezhenjun:{ - audio:"jieyue", - trigger:{ - player:"phaseZhunbeiBegin", + rezhenjun: { + audio: "jieyue", + trigger: { + player: "phaseZhunbeiBegin", }, - filter:function (event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')>0; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") > 0; }); }, - direct:true, - content:function (){ - 'step 0' - player.chooseTarget(get.prompt2('rezhenjun'),(card,player,target)=>{ - return target.countCards('he'); - }).ai=function(target){ - return -get.attitude(_status.event.player,target)*(target.countCards('e')+1); + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt2("rezhenjun"), (card, player, target) => { + return target.countCards("he"); + }).ai = function (target) { + return -get.attitude(_status.event.player, target) * (target.countCards("e") + 1); }; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - var num=Math.max(target.countCards('h')-target.hp,1); - player.logSkill('rezhenjun',target); - player.discardPlayerCard(num,target,true); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + var num = Math.max(target.countCards("h") - target.hp, 1); + player.logSkill("rezhenjun", target); + player.discardPlayerCard(num, target, true); } - 'step 2' - if(result.cards&&result.cards.length){ - event.num=0; - for(var i=0;i0){ - var prompt='弃置'+get.cnNumber(event.num)+'张牌,或令'+get.translation(event.target)+'摸'+get.cnNumber(event.num)+'张牌'; - player.chooseToDiscard(event.num,prompt,'he').ai=function(card){ - return 5-get.value(card); - } - } - else event.finish(); - } - else event.finish(); - 'step 3' - if(!result.bool){ + if (event.num > 0) { + var prompt = + "弃置" + + get.cnNumber(event.num) + + "张牌,或令" + + get.translation(event.target) + + "摸" + + get.cnNumber(event.num) + + "张牌"; + player.chooseToDiscard(event.num, prompt, "he").ai = function (card) { + return 5 - get.value(card); + }; + } else event.finish(); + } else event.finish(); + "step 3"; + if (!result.bool) { event.target.draw(event.num); } }, }, - fenli:{ - audio:2, - audioname:['xin_zhuhuan'], - group:['fenli_draw','fenli_use','fenli_discard'], - subfrequent:['discard'], - subSkill:{ - draw:{ - audio:'fenli', - audioname:['xin_zhuhuan'], - trigger:{player:'phaseDrawBefore'}, - prompt:'是否发动【奋励】跳过摸牌阶段?', - filter:function(event,player){ + fenli: { + audio: 2, + audioname: ["xin_zhuhuan"], + group: ["fenli_draw", "fenli_use", "fenli_discard"], + subfrequent: ["discard"], + subSkill: { + draw: { + audio: "fenli", + audioname: ["xin_zhuhuan"], + trigger: { player: "phaseDrawBefore" }, + prompt: "是否发动【奋励】跳过摸牌阶段?", + filter: function (event, player) { return player.isMaxHandcard(); }, - check:function(event,player){ - if(player.getHistory('skipped').length>0) return false; - return game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.hp==1&&get.damageEffect(current,player,player)>0; + check: function (event, player) { + if (player.getHistory("skipped").length > 0) return false; + return game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.hp == 1 && + get.damageEffect(current, player, player) > 0 + ); }); }, - content:function(){ + content: function () { trigger.cancel(); - } + }, }, - use:{ - audio:'fenli', - audioname:['xin_zhuhuan'], - trigger:{player:'phaseUseBefore'}, - prompt:'是否发动【奋励】跳过出牌阶段?', - filter:function(event,player){ + use: { + audio: "fenli", + audioname: ["xin_zhuhuan"], + trigger: { player: "phaseUseBefore" }, + prompt: "是否发动【奋励】跳过出牌阶段?", + filter: function (event, player) { return player.isMaxHp(); }, - check:function(event,player){ - if(!player.needsToDiscard()||(player.countCards('e')&&player.isMaxEquip())) return true; - if(player.getHistory('skipped').length>0) return false; - return game.hasPlayer(function(current){ - return get.attitude(player,current)<0&¤t.hp==1&&get.damageEffect(current,player,player)>0; + check: function (event, player) { + if (!player.needsToDiscard() || (player.countCards("e") && player.isMaxEquip())) + return true; + if (player.getHistory("skipped").length > 0) return false; + return game.hasPlayer(function (current) { + return ( + get.attitude(player, current) < 0 && + current.hp == 1 && + get.damageEffect(current, player, player) > 0 + ); }); }, - content:function(){ + content: function () { trigger.cancel(); - } - }, - discard:{ - audio:'fenli', - audioname:['xin_zhuhuan'], - trigger:{player:'phaseDiscardBefore'}, - prompt:'是否发动【奋励】跳过弃牌阶段?', - frequent:true, - filter:function(event,player){ - return player.isMaxEquip()&&player.countCards('e'); }, - content:function(){ + }, + discard: { + audio: "fenli", + audioname: ["xin_zhuhuan"], + trigger: { player: "phaseDiscardBefore" }, + prompt: "是否发动【奋励】跳过弃牌阶段?", + frequent: true, + filter: function (event, player) { + return player.isMaxEquip() && player.countCards("e"); + }, + content: function () { trigger.cancel(); - } - } + }, + }, + }, + ai: { + combo: "pingkou", }, - ai:{ - combo:'pingkou' - } }, - pingkou:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return player.getHistory('skipped').length>0; + pingkou: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return player.getHistory("skipped").length > 0; }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.getHistory('skipped').length],get.prompt2('pingkou'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - player.logSkill('pingkou',result.targets); - event.targets=result.targets.slice(0).sortBySeat(); - } - else{ + content: function () { + "step 0"; + player + .chooseTarget( + [1, player.getHistory("skipped").length], + get.prompt2("pingkou"), + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("pingkou", result.targets); + event.targets = result.targets.slice(0).sortBySeat(); + } else { event.finish(); } - 'step 2' - if(event.targets&&event.targets.length){ + "step 2"; + if (event.targets && event.targets.length) { event.targets.shift().damage(); event.redo(); } }, - ai:{ - combo:'fenli', - effect:{ - target:function(card){ - if(card.name=='lebu'||card.name=='bingliang') return 0.5; - } - } - } + ai: { + combo: "fenli", + effect: { + target: function (card) { + if (card.name == "lebu" || card.name == "bingliang") return 0.5; + }, + }, + }, }, - xinanguo:{ - audio:'anguo', - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - if(target.isMinHandcard()){ + xinanguo: { + audio: "anguo", + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + if (target.isMinHandcard()) { target.draw(); - event.h=true; + event.h = true; } - 'step 1' - if(target.isMinHp()&&target.isDamaged()){ + "step 1"; + if (target.isMinHp() && target.isDamaged()) { target.recover(); - event.hp=true; + event.hp = true; } - 'step 2' - var equip=get.cardPile(function(card){ - return get.type(card)=='equip'&&target.hasUseTarget(card); + "step 2"; + var equip = get.cardPile(function (card) { + return get.type(card) == "equip" && target.hasUseTarget(card); }); - if(target.isMinEquip()&&equip){ - target.chooseUseTarget(equip,'nothrow','nopopup',true); - event.e=true; + if (target.isMinEquip() && equip) { + target.chooseUseTarget(equip, "nothrow", "nopopup", true); + event.e = true; } - 'step 3' + "step 3"; game.updateRoundNumber(); - if(!event.h&&player.isMinHandcard()){ + if (!event.h && player.isMinHandcard()) { player.draw(); } - 'step 4' - if(!event.hp&&player.isMinHp()&&player.isDamaged()){ + "step 4"; + if (!event.hp && player.isMinHp() && player.isDamaged()) { player.recover(); } - 'step 5' - if(!event.e&&player.isMinEquip()){ - var equip=get.cardPile(function(card){ - return get.type(card)=='equip'&&player.hasUseTarget(card); + "step 5"; + if (!event.e && player.isMinEquip()) { + var equip = get.cardPile(function (card) { + return get.type(card) == "equip" && player.hasUseTarget(card); }); - if(equip) player.chooseUseTarget(equip,'nothrow','nopopup',true); + if (equip) player.chooseUseTarget(equip, "nothrow", "nopopup", true); } - 'step 6' + "step 6"; game.updateRoundNumber(); }, - ai:{ - threaten:1.6, - order:9, - result:{ - player:function(player,target){ - if(get.attitude(player,target)<=0){ - if(target.isMinHandcard()||target.isMinEquip()||target.isMinHp()) return -1; + ai: { + threaten: 1.6, + order: 9, + result: { + player: function (player, target) { + if (get.attitude(player, target) <= 0) { + if (target.isMinHandcard() || target.isMinEquip() || target.isMinHp()) + return -1; } - var num=0; - if(player.isMinHandcard()||target.isMinHandcard()) num++; - if(player.isMinEquip()||target.isMinEquip()) num++; - if((player.isMinHp()&&player.isDamaged())||(target.isMinHp()&&target.isDamaged())) num+=2.1; + var num = 0; + if (player.isMinHandcard() || target.isMinHandcard()) num++; + if (player.isMinEquip() || target.isMinEquip()) num++; + if ( + (player.isMinHp() && player.isDamaged()) || + (target.isMinHp() && target.isDamaged()) + ) + num += 2.1; return num; - } - } - } + }, + }, + }, }, - pindi:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ - if(player==target) return false; - if(player.storage.pindi_target&& - player.storage.pindi_target.includes(target)){ + pindi: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { + if (player == target) return false; + if (player.storage.pindi_target && player.storage.pindi_target.includes(target)) { return false; } return true; }, - filterCard:function(card,player){ - if(player.storage.pindi_type&& - player.storage.pindi_type.includes(get.type2(card))){ + filterCard: function (card, player) { + if (player.storage.pindi_type && player.storage.pindi_type.includes(get.type2(card))) { return false; } return true; }, - subSkill:{ - clear:{ - trigger:{player:'phaseAfter'}, - silent:true, - content:function(){ + subSkill: { + clear: { + trigger: { player: "phaseAfter" }, + silent: true, + content: function () { delete player.storage.pindi_target; delete player.storage.pindi_type; - } - } + }, + }, }, //group:'pindi_clear', - check:function(card){ - var num=_status.event.player.getStat('skill').pindi||0; - return 6+num-get.value(card); + check: function (card) { + var num = _status.event.player.getStat("skill").pindi || 0; + return 6 + num - get.value(card); }, - position:'he', - content:function(){ - 'step 0' - if(!player.storage.pindi_target){ - player.storage.pindi_target=[]; + position: "he", + content: function () { + "step 0"; + if (!player.storage.pindi_target) { + player.storage.pindi_target = []; } - if(!player.storage.pindi_type){ - player.storage.pindi_type=[]; + if (!player.storage.pindi_type) { + player.storage.pindi_type = []; } player.storage.pindi_target.push(target); - player.storage.pindi_type.push(get.type2(cards[0],cards[0].original=='h'?player:false)); - event.num=player.getStat('skill').pindi; - var evt=_status.event.getParent('phase'); - if(evt&&evt.name=='phase'&&!evt.pindi){ - var next=game.createEvent('rerende_clear'); + player.storage.pindi_type.push( + get.type2(cards[0], cards[0].original == "h" ? player : false) + ); + event.num = player.getStat("skill").pindi; + var evt = _status.event.getParent("phase"); + if (evt && evt.name == "phase" && !evt.pindi) { + var next = game.createEvent("rerende_clear"); _status.event.next.remove(next); evt.after.push(next); - evt.pindi=true; - next.player=player; + evt.pindi = true; + next.player = player; next.setContent(lib.skill.pindi_clear.content); } player.syncStorage(); - if(target.countCards('he')==0) event._result={index:0}; - else{ - player.chooseControlList([ - '令'+get.translation(target)+'摸'+get.cnNumber(event.num)+'张牌', - '令'+get.translation(target)+'弃置'+get.cnNumber(event.num)+'张牌' - ],function(){ - return _status.event.choice; - }).set('choice',get.attitude(player,target)>0?0:1); + if (target.countCards("he") == 0) event._result = { index: 0 }; + else { + player + .chooseControlList( + [ + "令" + get.translation(target) + "摸" + get.cnNumber(event.num) + "张牌", + "令" + + get.translation(target) + + "弃置" + + get.cnNumber(event.num) + + "张牌", + ], + function () { + return _status.event.choice; + } + ) + .set("choice", get.attitude(player, target) > 0 ? 0 : 1); } - 'step 1' - if(result.index==0){ + "step 1"; + if (result.index == 0) { target.draw(event.num); + } else { + target.chooseToDiscard(event.num, "he", true); } - else{ - target.chooseToDiscard(event.num,'he',true); - } - 'step 2' - if(target.isDamaged()){ + "step 2"; + if (target.isDamaged()) { player.link(true); } }, - ai:{ - order:8, - threaten:1.8, - result:{ - target:function(player,target){ - var att=get.attitude(player,target); - var num=(player.getStat('skill').pindi||0)+1; - if(att<=0&&target.countCards('he')0; - } - else return event.cards.filterInD('od').length>0; - }, - logTarget:'player', - content:function(){ - 'step 0' - if(!player.hasSkill('funan_jiexun')){ - var cards=[] - if(get.itemtype(trigger.respondTo[1])=='card') cards.push(trigger.respondTo[1]); - else if(trigger.respondTo[1].cards) cards.addArray(trigger.respondTo[1].cards); - cards=cards.filterInD('od'); - trigger.player.gain(cards,'gain2','log').gaintag.add('funan'); - trigger.player.addTempSkill('funan_use'); - } - 'step 1' - var cards=trigger.cards.filterInD('od'); - player.gain(cards,'log','gain2'); - }, - subSkill:{ - jiexun:{ - charlotte:true, - mark:true, - marktext:'复', - intro:{ - content:'你发动“复难”时,无须令其他角色获得你使用的牌' }, }, - use:{ - onremove:function(player){ - player.removeGaintag('funan'); + }, + }, + funan: { + audio: 2, + trigger: { global: ["respond", "useCard"] }, + filter: function (event, player) { + if (!event.respondTo) return false; + if (event.player == player) return false; + if (player != event.respondTo[0]) return false; + if (!player.hasSkill("funan_jiexun")) { + var cards = []; + if (get.itemtype(event.respondTo[1]) == "card") cards.push(event.respondTo[1]); + else if (event.respondTo[1].cards) cards.addArray(event.respondTo[1].cards); + return cards.filterInD("od").length > 0; + } else return event.cards.filterInD("od").length > 0; + }, + logTarget: "player", + content: function () { + "step 0"; + if (!player.hasSkill("funan_jiexun")) { + var cards = []; + if (get.itemtype(trigger.respondTo[1]) == "card") cards.push(trigger.respondTo[1]); + else if (trigger.respondTo[1].cards) cards.addArray(trigger.respondTo[1].cards); + cards = cards.filterInD("od"); + trigger.player.gain(cards, "gain2", "log").gaintag.add("funan"); + trigger.player.addTempSkill("funan_use"); + } + "step 1"; + var cards = trigger.cards.filterInD("od"); + player.gain(cards, "log", "gain2"); + }, + subSkill: { + jiexun: { + charlotte: true, + mark: true, + marktext: "复", + intro: { + content: "你发动“复难”时,无须令其他角色获得你使用的牌", }, - charlotte:true, - mod:{ - cardEnabled2:function(card,player){ - if(get.itemtype(card)=='card'&&card.hasGaintag('funan')){ + }, + use: { + onremove: function (player) { + player.removeGaintag("funan"); + }, + charlotte: true, + mod: { + cardEnabled2: function (card, player) { + if (get.itemtype(card) == "card" && card.hasGaintag("funan")) { return false; } - } - } - } - } + }, + }, + }, + }, }, - jiexun:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - onremove:true, - direct:true, - content:function(){ - 'step 0' - var num1=game.countPlayer(function(current){ - return current.countCards('ej',{suit:'diamond'}); + jiexun: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + onremove: true, + direct: true, + content: function () { + "step 0"; + var num1 = game.countPlayer(function (current) { + return current.countCards("ej", { suit: "diamond" }); }); - var num2=player.countMark('jiexun'); - event.num1=num1; - event.num2=num2; - var str='令目标摸'+get.cnNumber(num1)+'张牌'; - if(num2){ - str+=',然后弃置'+get.cnNumber(num2)+'张牌;若目标因此法弃置了所有牌,则你失去“诫训”,然后你发动“复难”时,无须令其获得你使用的牌'; + var num2 = player.countMark("jiexun"); + event.num1 = num1; + event.num2 = num2; + var str = "令目标摸" + get.cnNumber(num1) + "张牌"; + if (num2) { + str += + ",然后弃置" + + get.cnNumber(num2) + + "张牌;若目标因此法弃置了所有牌,则你失去“诫训”,然后你发动“复难”时,无须令其获得你使用的牌"; } - player.chooseTarget(get.prompt('jiexun'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return _status.event.coeff*get.attitude(_status.event.player,target); - }).set('coeff',num1>=num2?1:-1).set('prompt2',str); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('jiexun',target); - if(event.num1){ + player + .chooseTarget(get.prompt("jiexun"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + return _status.event.coeff * get.attitude(_status.event.player, target); + }) + .set("coeff", num1 >= num2 ? 1 : -1) + .set("prompt2", str); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("jiexun", target); + if (event.num1) { target.draw(event.num1); } - player.addMark('jiexun',1,false); - } - else{ + player.addMark("jiexun", 1, false); + } else { event.finish(); } - 'step 2' - if(event.num2){ - event.target.chooseToDiscard(event.num2,true,'he'); - } - else{ + "step 2"; + if (event.num2) { + event.target.chooseToDiscard(event.num2, true, "he"); + } else { event.finish(); } - 'step 3' - if(result.bool&&result.autochoose&&result.cards.length==result.rawcards.length){ - player.removeSkills('jiexun'); - player.addSkill('funan_jiexun'); - } - } - }, - xinjiexun:{ - audio:'jiexun', - trigger:{player:'phaseJieshuBegin'}, - onremove:true, - direct:true, - content:function(){ - 'step 0' - var num1=game.countPlayer(function(current){ - return current.countCards('ej',{suit:'diamond'}); - }); - var num2=player.countMark('xinjiexun'); - event.num1=num1; - event.num2=num2; - var str='令目标摸'+get.cnNumber(num1)+'张牌'; - if(num2){ - str+=',然后弃置'+get.cnNumber(num2)+'张牌'; - } - player.chooseTarget(get.prompt('xinjiexun'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return _status.event.coeff*get.attitude(_status.event.player,target); - }).set('coeff',num1>=num2?1:-1).set('prompt2',str); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xinjiexun',target); - if(event.num1){ - target.draw(event.num1); - } - player.addMark('xinjiexun',1,false); - } - else{ - event.finish(); - } - 'step 2' - if(event.num2){ - event.target.chooseToDiscard(event.num2,true,'he'); - } - else{ - event.finish(); - } - 'step 3' - if(result.bool&&result.autochoose&&result.cards.length==result.rawcards.length){ - player.removeMark('xinjiexun',player.countMark('xinjiexun'),false); - player.addSkill('funan_jiexun'); + "step 3"; + if (result.bool && result.autochoose && result.cards.length == result.rawcards.length) { + player.removeSkills("jiexun"); + player.addSkill("funan_jiexun"); } }, - intro:{content:'已经发动过了#次'}, }, - zhuandui:{ - shaRelated:true, - audio:2, - group:['zhuandui_respond','zhuandui_use'], - subSkill:{ - use:{ - audio:"zhuandui", - trigger:{player:'useCardToPlayered'}, - check:function(event,player){ - return get.attitude(player,event.target)<0; + xinjiexun: { + audio: "jiexun", + trigger: { player: "phaseJieshuBegin" }, + onremove: true, + direct: true, + content: function () { + "step 0"; + var num1 = game.countPlayer(function (current) { + return current.countCards("ej", { suit: "diamond" }); + }); + var num2 = player.countMark("xinjiexun"); + event.num1 = num1; + event.num2 = num2; + var str = "令目标摸" + get.cnNumber(num1) + "张牌"; + if (num2) { + str += ",然后弃置" + get.cnNumber(num2) + "张牌"; + } + player + .chooseTarget(get.prompt("xinjiexun"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + return _status.event.coeff * get.attitude(_status.event.player, target); + }) + .set("coeff", num1 >= num2 ? 1 : -1) + .set("prompt2", str); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xinjiexun", target); + if (event.num1) { + target.draw(event.num1); + } + player.addMark("xinjiexun", 1, false); + } else { + event.finish(); + } + "step 2"; + if (event.num2) { + event.target.chooseToDiscard(event.num2, true, "he"); + } else { + event.finish(); + } + "step 3"; + if (result.bool && result.autochoose && result.cards.length == result.rawcards.length) { + player.removeMark("xinjiexun", player.countMark("xinjiexun"), false); + player.addSkill("funan_jiexun"); + } + }, + intro: { content: "已经发动过了#次" }, + }, + zhuandui: { + shaRelated: true, + audio: 2, + group: ["zhuandui_respond", "zhuandui_use"], + subSkill: { + use: { + audio: "zhuandui", + trigger: { player: "useCardToPlayered" }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - filter:function(event,player){ - return event.card.name=='sha'&&player.canCompare(event.target); + filter: function (event, player) { + return event.card.name == "sha" && player.canCompare(event.target); }, - logTarget:'target', - content:function(){ - 'step 0' + logTarget: "target", + content: function () { + "step 0"; player.chooseToCompare(trigger.target); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.getParent().directHit.add(trigger.target); } - } + }, }, - respond:{ - audio:"zhuandui", - trigger:{target:'useCardToTargeted'}, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)<0; + respond: { + audio: "zhuandui", + trigger: { target: "useCardToTargeted" }, + check: function (event, player) { + return get.effect(player, event.card, event.player, player) < 0; }, - filter:function(event,player){ - return event.card.name=='sha'&&player.canCompare(event.player); + filter: function (event, player) { + return event.card.name == "sha" && player.canCompare(event.player); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; player.chooseToCompare(trigger.player); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { trigger.getParent().excluded.add(player); } - } - } + }, + }, }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(player._zhuandui_temp||tag!=='directHit_ai') return false; - player._zhuandui_temp=true; - var bool=function(){ - if(arg.card.name!='sha'||get.attitude(player,arg.target)>=0||!arg.target.countCards('h')) return false; - if(arg.target.countCards('h')==1&&(!arg.target.hasSkillTag('freeShan',false,{ - player:player, - card:arg.card - },true)||player.hasSkillTag('unequip',false,{ - name:arg.card?arg.card.name:null, - target:arg.target, - card:arg.card - })||player.hasSkillTag('unequip_ai',false,{ - name:arg.card?arg.card.name:null, - target:arg.target, - card:arg.card - }))) return true; - return player.countCards('h',function(card){ - return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card))&&get.value(card)<=4&&(get.number(card)>=(11+arg.target.countCards('h')/2)||get.suit(card,player)=='heart'); - })>0; - }(); + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (player._zhuandui_temp || tag !== "directHit_ai") return false; + player._zhuandui_temp = true; + var bool = (function () { + if ( + arg.card.name != "sha" || + get.attitude(player, arg.target) >= 0 || + !arg.target.countCards("h") + ) + return false; + if ( + arg.target.countCards("h") == 1 && + (!arg.target.hasSkillTag( + "freeShan", + false, + { + player: player, + card: arg.card, + }, + true + ) || + player.hasSkillTag("unequip", false, { + name: arg.card ? arg.card.name : null, + target: arg.target, + card: arg.card, + }) || + player.hasSkillTag("unequip_ai", false, { + name: arg.card ? arg.card.name : null, + target: arg.target, + card: arg.card, + })) + ) + return true; + return ( + player.countCards("h", function (card) { + return ( + card != arg.card && + (!arg.card.cards || !arg.card.cards.includes(card)) && + get.value(card) <= 4 && + (get.number(card) >= 11 + arg.target.countCards("h") / 2 || + get.suit(card, player) == "heart") + ); + }) > 0 + ); + })(); delete player._zhuandui_temp; return bool; }, - effect:{ - target:function(card,player,target,current){ - if(card.name=='sha'&¤t<0) return 0.7; - } - } - } + effect: { + target: function (card, player, target, current) { + if (card.name == "sha" && current < 0) return 0.7; + }, + }, + }, }, - tianbian:{ - audio:2, - enable:"chooseCard", - check:function(event,player){ - var player=_status.event.player; - return (!player.hasCard(function(card){ - var val=get.value(card); - return val<0||(val<=4&&(get.number(card)>=11||get.suit(card)=='heart')); - },'h'))?20:0; + tianbian: { + audio: 2, + enable: "chooseCard", + check: function (event, player) { + var player = _status.event.player; + return !player.hasCard(function (card) { + var val = get.value(card); + return val < 0 || (val <= 4 && (get.number(card) >= 11 || get.suit(card) == "heart")); + }, "h") + ? 20 + : 0; }, - filter:function(event){ - return event.type=='compare'&&!event.directresult; + filter: function (event) { + return event.type == "compare" && !event.directresult; }, - onCompare:function(player){ + onCompare: function (player) { return game.cardsGotoOrdering(get.cards()).cards; }, - group:'tianbian_number', - subSkill:{ - number:{ - trigger:{player:'compare',target:'compare'}, - filter:function(event,player){ - if(event.player==player){ - return !event.iwhile&&get.suit(event.card1)=='heart';//&&event.card1.vanishtag.includes('tianbian'); - } - else{ - return get.suit(event.card2)=='heart';//&&event.card2.vanishtag.includes('tianbian'); + group: "tianbian_number", + subSkill: { + number: { + trigger: { player: "compare", target: "compare" }, + filter: function (event, player) { + if (event.player == player) { + return !event.iwhile && get.suit(event.card1) == "heart"; //&&event.card1.vanishtag.includes('tianbian'); + } else { + return get.suit(event.card2) == "heart"; //&&event.card2.vanishtag.includes('tianbian'); } }, - silent:true, - content:function(){ - game.log(player,'拼点牌点数视为','#yK'); - if(player==trigger.player){ - trigger.num1=13; + silent: true, + content: function () { + game.log(player, "拼点牌点数视为", "#yK"); + if (player == trigger.player) { + trigger.num1 = 13; + } else { + trigger.num2 = 13; } - else{ - trigger.num2=13; - } - } - } - } - }, - jianzheng:{ - audio:2, - trigger:{global:'useCardToPlayer'}, - filter:function(event,player){ - if(!player.countCards('h')) return false; - return event.player!=player&&event.card.name=='sha'&&!event.targets.includes(player)&& - event.player.inRange(player); + }, + }, }, - direct:true, - content:function(){ - "step 0" - var effect=0; - for(var i=0;i0){ - if(get.color(trigger.card)!='black'){ - effect=0; + if (effect > 0) { + if (get.color(trigger.card) != "black") { + effect = 0; + } else { + effect = 1; } - else{ - effect=1; - } - if(trigger.targets.length==1){ - if(trigger.targets[0].hp==1){ + if (trigger.targets.length == 1) { + if (trigger.targets[0].hp == 1) { effect++; } - if(effect>0&&trigger.targets[0].countCards('h') 0 && trigger.targets[0].countCards("h") < player.countCards("h")) { effect++; } } - if(effect>0){ - effect+=6; + if (effect > 0) { + effect += 6; } } - player.chooseCard('h',get.prompt2('jianzheng',trigger.player)).set('ai',function(card){ - if(_status.event.effect>=0){ - var val=get.value(card); - if(val<0) return 10-val; - return _status.event.effect-val; - } - return 0; - }).set('effect',effect).set('logSkill',['jianzheng',trigger.player]); - "step 1" - if(result.bool&&result.cards){ - event.card=result.cards[0]; - trigger.targets.length=0; - trigger.getParent().triggeredTargets1.length=0; - } - else{ + player + .chooseCard("h", get.prompt2("jianzheng", trigger.player)) + .set("ai", function (card) { + if (_status.event.effect >= 0) { + var val = get.value(card); + if (val < 0) return 10 - val; + return _status.event.effect - val; + } + return 0; + }) + .set("effect", effect) + .set("logSkill", ["jianzheng", trigger.player]); + "step 1"; + if (result.bool && result.cards) { + event.card = result.cards[0]; + trigger.targets.length = 0; + trigger.getParent().triggeredTargets1.length = 0; + } else { event.finish(); } - "step 2" - if(!event.isMine()) game.delayx(); - "step 3" - if(event.card){ - player.logSkill('jianzheng',trigger.player); - player.lose(event.card,ui.cardPile,'visible','insert'); - player.$throw(event.card,1000); - game.log(player,'将',card,'置于牌堆顶'); + "step 2"; + if (!event.isMine()) game.delayx(); + "step 3"; + if (event.card) { + player.logSkill("jianzheng", trigger.player); + player.lose(event.card, ui.cardPile, "visible", "insert"); + player.$throw(event.card, 1000); + game.log(player, "将", card, "置于牌堆顶"); } - "step 4" - if(get.color(trigger.card)!='black'){ + "step 4"; + if (get.color(trigger.card) != "black") { trigger.getParent().targets.push(player); trigger.player.line(player); game.delay(); } }, - ai:{ - threaten:1.1, - expose:0.25, + ai: { + threaten: 1.1, + expose: 0.25, }, }, - qingxian:{ - audio:2, - group:['qingxian_jilie','qingxian_rouhe','qingxian_dying'], - ai:{ - threaten:0.8, - maixie:true, - maixie_hp:true, - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(target.hp>1&&target.hasFriend()) return 0.4; + qingxian: { + audio: 2, + group: ["qingxian_jilie", "qingxian_rouhe", "qingxian_dying"], + ai: { + threaten: 0.8, + maixie: true, + maixie_hp: true, + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (target.hp > 1 && target.hasFriend()) return 0.4; } - } - } - }, - subSkill:{ - dying:{ - audio:'qingxian', - trigger:{global:'dyingAfter'}, - filter:function(event,player){ - return player.storage.qingxian&&player.storage.qingxian>0&&!_status.dying.length; }, - direct:true, - content:function(){ - 'step 0' - player.storage.qingxian--; - player.chooseTarget(get.prompt('qingxian'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.isHealthy()&&att>0) return 0; - if(target.hp==1&&att!=0){ - if(att>0) return 9; - else return 10; - } - else{ - return Math.sqrt(Math.abs(att)); - } - }).set('prompt2','当你回复体力后,你可以令一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qingxian',target); - event.insert(lib.skill.qingxian.content_choose,{target:target,player:player}); - } - 'step 2' - if(lib.skill.qingxian_dying.filter(trigger,player)) event.goto(0); - } }, - rouhe:{ - audio:'qingxian', - trigger:{player:'recoverEnd'}, - direct:true, - content:function(){ - 'step 0' - if(_status.dying.length){ - if(!player.storage.qingxian) player.storage.qingxian=0; + }, + subSkill: { + dying: { + audio: "qingxian", + trigger: { global: "dyingAfter" }, + filter: function (event, player) { + return ( + player.storage.qingxian && + player.storage.qingxian > 0 && + !_status.dying.length + ); + }, + direct: true, + content: function () { + "step 0"; + player.storage.qingxian--; + player + .chooseTarget(get.prompt("qingxian"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.isHealthy() && att > 0) return 0; + if (target.hp == 1 && att != 0) { + if (att > 0) return 9; + else return 10; + } else { + return Math.sqrt(Math.abs(att)); + } + }) + .set( + "prompt2", + "当你回复体力后,你可以令一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力" + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qingxian", target); + event.insert(lib.skill.qingxian.content_choose, { + target: target, + player: player, + }); + } + "step 2"; + if (lib.skill.qingxian_dying.filter(trigger, player)) event.goto(0); + }, + }, + rouhe: { + audio: "qingxian", + trigger: { player: "recoverEnd" }, + direct: true, + content: function () { + "step 0"; + if (_status.dying.length) { + if (!player.storage.qingxian) player.storage.qingxian = 0; player.storage.qingxian++; event.finish(); return; } - player.chooseTarget(get.prompt('qingxian'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.isHealthy()&&att>0) return 0; - if(target.hp==1&&att!=0){ - if(att>0) return 9; - else return 10; - } - else{ - return Math.sqrt(Math.abs(att)); - } - }).set('prompt2','当你回复体力后,你可以令一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qingxian',target); - event.insert(lib.skill.qingxian.content_choose,{target:target,player:player}); + player + .chooseTarget(get.prompt("qingxian"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.isHealthy() && att > 0) return 0; + if (target.hp == 1 && att != 0) { + if (att > 0) return 9; + else return 10; + } else { + return Math.sqrt(Math.abs(att)); + } + }) + .set( + "prompt2", + "当你回复体力后,你可以令一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力" + ); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qingxian", target); + event.insert(lib.skill.qingxian.content_choose, { + target: target, + player: player, + }); } - } - }, - jilie:{ - audio:'qingxian', - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn(); }, - check:function(event,player){ - if(get.attitude(player,event.source)>0&&event.source.isHealthy()){ + }, + jilie: { + audio: "qingxian", + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.source && event.source.isIn(); + }, + check: function (event, player) { + if (get.attitude(player, event.source) > 0 && event.source.isHealthy()) { return false; } return true; }, - logTarget:'source', - prompt2:'当你受到伤害后,你可以令伤害来源执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力', - content:function(){ - event.insert(lib.skill.qingxian.content_choose,{target:trigger.source,player:player}); - } - } + logTarget: "source", + prompt2: + "当你受到伤害后,你可以令伤害来源执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你回复1点体力", + content: function () { + event.insert(lib.skill.qingxian.content_choose, { + target: trigger.source, + player: player, + }); + }, + }, }, - content_choose:function(){ - 'step 0' - if(target.isHealthy()){ - event._result={index:0} - } - else{ + content_choose: function () { + "step 0"; + if (target.isHealthy()) { + event._result = { index: 0 }; + } else { var index; - if(get.attitude(player,target)>0){ - index=1; + if (get.attitude(player, target) > 0) { + index = 1; + } else { + index = 0; } - else{ - index=0; - } - player.chooseControlList( - ['令'+get.translation(target)+'失去1点体力,随机使用一张装备牌', - '令'+get.translation(target)+'回复1点体力,弃置一张装备牌'], - true,function(event,player){ - return _status.event.index; - }).set('index',index); - } - 'step 1' - if(result.index==0){ - target.loseHp(); - event.card=get.cardPile(function(card){ - return get.type(card)=='equip'&&target.canUse(card,target); - }); - if(event.card){ - target.chooseUseTarget(event.card,'nothrow','nopopup',true); - event.goto(3); - } - else{ - event.finish(); - } - } - else{ - target.recover(); - if(target.countCards('he',{type:'equip'})){ - target.chooseToDiscard('he',true,'弃置一张装备牌',function(card){ - return get.type(card)=='equip'; - }).set('ai',function(card){ - var val=-get.value(card); - if(get.suit(card)=='club'){ - val+=_status.event.att*10; + player + .chooseControlList( + [ + "令" + get.translation(target) + "失去1点体力,随机使用一张装备牌", + "令" + get.translation(target) + "回复1点体力,弃置一张装备牌", + ], + true, + function (event, player) { + return _status.event.index; } - return val; - }).set('att',get.sgnAttitude(target,player)); + ) + .set("index", index); + } + "step 1"; + if (result.index == 0) { + target.loseHp(); + event.card = get.cardPile(function (card) { + return get.type(card) == "equip" && target.canUse(card, target); + }); + if (event.card) { + target.chooseUseTarget(event.card, "nothrow", "nopopup", true); + event.goto(3); + } else { + event.finish(); } - else{ + } else { + target.recover(); + if (target.countCards("he", { type: "equip" })) { + target + .chooseToDiscard("he", true, "弃置一张装备牌", function (card) { + return get.type(card) == "equip"; + }) + .set("ai", function (card) { + var val = -get.value(card); + if (get.suit(card) == "club") { + val += _status.event.att * 10; + } + return val; + }) + .set("att", get.sgnAttitude(target, player)); + } else { event.finish(); } } - 'step 2' - if(result&&result.cards){ - event.card=result.cards[0]; + "step 2"; + if (result && result.cards) { + event.card = result.cards[0]; } - 'step 3' - if(event.card&&get.suit(event.card)=='club'){ + "step 3"; + if (event.card && get.suit(event.card) == "club") { player.draw(); } - } + }, }, - juexiang:{ - audio:2, - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('juexiang'),function(card,player,target){ - return target!=player; - }).set('forceDie',true).set('ai',function(target){ - return get.attitude(_status.event.player,target)/Math.sqrt(target.hp+1); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0] - player.logSkill('juexiang',target); + juexiang: { + audio: 2, + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("juexiang"), function (card, player, target) { + return target != player; + }) + .set("forceDie", true) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) / Math.sqrt(target.hp + 1); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("juexiang", target); target.addSkills(lib.skill.juexiang.derivation.randomGet()); - target.addTempSkill('juexiang_club',{player:'phaseZhunbeiBegin'}); + target.addTempSkill("juexiang_club", { player: "phaseZhunbeiBegin" }); } }, - derivation:['juexiang_ji','juexiang_lie','juexiang_rou','juexiang_he'], - subSkill:{ - ji:{ - audio:1, - mark:true, - nopop:true, - intro:{ - content:'info' + derivation: ["juexiang_ji", "juexiang_lie", "juexiang_rou", "juexiang_he"], + subSkill: { + ji: { + audio: 1, + mark: true, + nopop: true, + intro: { + content: "info", }, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source!=player; + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.source && event.source.isIn() && event.source != player; }, - check:function(event,player){ - return get.attitude(player,event.source)<0; + check: function (event, player) { + return get.attitude(player, event.source) < 0; }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { trigger.source.loseHp(); - var card=get.cardPile(function(card){ - return get.type(card)=='equip'&&trigger.source.canUse(card,trigger.source); + var card = get.cardPile(function (card) { + return ( + get.type(card) == "equip" && trigger.source.canUse(card, trigger.source) + ); }); - if(card){ - trigger.source.chooseUseTarget(card,'nothrow','nopopup',true); + if (card) { + trigger.source.chooseUseTarget(card, "nothrow", "nopopup", true); } }, - ai:{ - maixie_defend:true, - } + ai: { + maixie_defend: true, + }, }, - lie:{ - audio:1, - mark:true, - nopop:true, - intro:{ - content:'info' + lie: { + audio: 1, + mark: true, + nopop: true, + intro: { + content: "info", }, - trigger:{ - player:'recoverEnd', - global:'dyingAfter', + trigger: { + player: "recoverEnd", + global: "dyingAfter", }, - direct:true, - content:function(){ - 'step 0' - if(_status.dying.length){ - if(event.triggername=='recoverEnd'){ - if(!player.storage.juexiang_lie) player.storage.juexiang_lie=0; + direct: true, + content: function () { + "step 0"; + if (_status.dying.length) { + if (event.triggername == "recoverEnd") { + if (!player.storage.juexiang_lie) player.storage.juexiang_lie = 0; player.storage.juexiang_lie++; } event.finish(); return; } - if(event.triggername=='dyingAfter'){ - if(!player.storage.juexiang_lie){ + if (event.triggername == "dyingAfter") { + if (!player.storage.juexiang_lie) { event.finish(); return; } player.storage.juexiang_lie--; } - player.chooseTarget(get.prompt2('juexiang_lie'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return -get.attitude(player,target)/(1+target.hp); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('juexiang_lie',target); + player + .chooseTarget(get.prompt2("juexiang_lie"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + return -get.attitude(player, target) / (1 + target.hp); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("juexiang_lie", target); target.loseHp(); - var card=get.cardPile(function(card){ - return get.type(card)=='equip'&&target.canUse(card,target); + var card = get.cardPile(function (card) { + return get.type(card) == "equip" && target.canUse(card, target); }); - if(card){ - target.chooseUseTarget(card,true,'nothrow','nopopup',true); + if (card) { + target.chooseUseTarget(card, true, "nothrow", "nopopup", true); } } - if(event.triggername=='dyingAfter'&&player.storage.juexiang_lie>0) event.goto(0); - } + if (event.triggername == "dyingAfter" && player.storage.juexiang_lie > 0) + event.goto(0); + }, }, - rou:{ - audio:1, - mark:true, - nopop:true, - intro:{ - content:'info' + rou: { + audio: 1, + mark: true, + nopop: true, + intro: { + content: "info", }, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source!=player; + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.source && event.source.isIn() && event.source != player; }, - check:function(event,player){ - var att=get.attitude(player,event.source); - if(player.isHealthy()){ - return att<0; - } - else{ - return att>0 + check: function (event, player) { + var att = get.attitude(player, event.source); + if (player.isHealthy()) { + return att < 0; + } else { + return att > 0; } }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { trigger.source.recover(); - if(trigger.source.countCards('he',{type:'equip'})){ - trigger.source.chooseToDiscard('he',true,'弃置一张装备牌',function(card){ - return get.type(card)=='equip'; + if (trigger.source.countCards("he", { type: "equip" })) { + trigger.source.chooseToDiscard("he", true, "弃置一张装备牌", function (card) { + return get.type(card) == "equip"; }); } }, - ai:{ - maixie_defend:true, - } - }, - he:{ - audio:1, - mark:true, - nopop:true, - intro:{ - content:'info' + ai: { + maixie_defend: true, }, - trigger:{player:'recoverEnd'}, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('juexiang_he'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.isHealthy()&&target.countCards('he')){ - return -att; - } - else{ - return 10*att/(1+target.hp); - } - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('juexiang_he',target); + }, + he: { + audio: 1, + mark: true, + nopop: true, + intro: { + content: "info", + }, + trigger: { player: "recoverEnd" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("juexiang_he"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.isHealthy() && target.countCards("he")) { + return -att; + } else { + return (10 * att) / (1 + target.hp); + } + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("juexiang_he", target); target.recover(); - if(target.countCards('he',{type:'equip'})){ - target.chooseToDiscard('he',true,'弃置一张装备牌',function(card){ - return get.type(card)=='equip'; + if (target.countCards("he", { type: "equip" })) { + target.chooseToDiscard("he", true, "弃置一张装备牌", function (card) { + return get.type(card) == "equip"; }); } } - } - }, - club:{ - mark:true, - nopop:true, - intro:{ - content:'info' }, - mod:{ - targetEnabled:function(card,player,target){ - if(get.suit(card)=='club'&&player!=target){ + }, + club: { + mark: true, + nopop: true, + intro: { + content: "info", + }, + mod: { + targetEnabled: function (card, player, target) { + if (get.suit(card) == "club" && player != target) { return false; } - } - } - } - } + }, + }, + }, + }, }, - bizhuan:{ - audio:2, - trigger:{ - player:'useCard', - target:'useCardToTargeted', + bizhuan: { + audio: 2, + trigger: { + player: "useCard", + target: "useCardToTargeted", }, - filter:function(event,player){ - if(event.name!='useCard'&&event.player==event.target) return false; - if(player.getExpansions('bizhuan').length>=4) return false; - return get.suit(event.card)=='spade'; + filter: function (event, player) { + if (event.name != "useCard" && event.player == event.target) return false; + if (player.getExpansions("bizhuan").length >= 4) return false; + return get.suit(event.card) == "spade"; }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - frequent:true, - locked:false, - content:function(){ - player.addToExpansion(get.cards(),'gain2').gaintag.add('bizhuan'); + frequent: true, + locked: false, + content: function () { + player.addToExpansion(get.cards(), "gain2").gaintag.add("bizhuan"); + }, + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("bizhuan").length; + }, }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('bizhuan').length; - } - } }, - tongbo:{ - trigger:{player:'phaseDrawAfter'}, - direct:true, - filter:function(event,player){ - return player.getExpansions('bizhuan').length>0&&player.countCards('he')>0; + tongbo: { + trigger: { player: "phaseDrawAfter" }, + direct: true, + filter: function (event, player) { + return player.getExpansions("bizhuan").length > 0 && player.countCards("he") > 0; }, - content:function(){ - "step 0" - var four=false; - var nofour=!player.hasFriend(); - var expansions=player.getExpansions('bizhuan'); - if(expansions.length==4){ - var suits=['club','spade','heart','diamond']; - var list=player.getCards('he').concat(expansions); - for(var i=0;i0){ + if (suits2.length > 0) { event.finish(); } - "step 3" - event.cards=player.getExpansions('bizhuan').slice(0); - if(event.cards.length>1){ - player.chooseCardButton('将所有“书”交给任意名其他角色',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return 1; - return 0; - }); - } - else if(event.cards.length==1){ - event._result={links:event.cards.slice(0),bool:true}; - } - else{ + "step 3"; + event.cards = player.getExpansions("bizhuan").slice(0); + if (event.cards.length > 1) { + player + .chooseCardButton("将所有“书”交给任意名其他角色", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + } else if (event.cards.length == 1) { + event._result = { links: event.cards.slice(0), bool: true }; + } else { event.finish(); } - "step 4" - if(result.bool){ - for(var i=0;i0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); - } - else{ + event.togive = result.links.slice(0); + player + .chooseTarget( + "将" + get.translation(result.links) + "交给一名其他角色", + true, + function (card, player, target) { + return target != player; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); + } else { event.finish(); } - "step 5" - if(result.targets.length){ - result.targets[0].gain(event.togive,'draw').giver=player; - player.line(result.targets[0],'green'); - game.log(result.targets[0],'获得了'+get.cnNumber(event.togive.length)+'张','#g“书”'); - if(event.cards.length) event.goto(3); + "step 5"; + if (result.targets.length) { + result.targets[0].gain(event.togive, "draw").giver = player; + player.line(result.targets[0], "green"); + game.log( + result.targets[0], + "获得了" + get.cnNumber(event.togive.length) + "张", + "#g“书”" + ); + if (event.cards.length) event.goto(3); } }, - ai:{ - combo:'bizhuan', - } + ai: { + combo: "bizhuan", + }, }, - shouxi:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - direct:true, - init:function(player){ - if(!player.storage.shouxi) player.storage.shouxi=[]; + shouxi: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + direct: true, + init: function (player) { + if (!player.storage.shouxi) player.storage.shouxi = []; }, - filter:function(event,player){ - return event.card.name=='sha'&&event.player.isIn(); + filter: function (event, player) { + return event.card.name == "sha" && event.player.isIn(); }, - content:function(){ - 'step 0' - var list=lib.inpile.filter(function(i){ - if(player.storage.shouxi.includes(i)) return false; - var type=get.type2(i); - if(type=='basic'||type=='trick') return true; + content: function () { + "step 0"; + var list = lib.inpile.filter(function (i) { + if (player.storage.shouxi.includes(i)) return false; + var type = get.type2(i); + if (type == "basic" || type == "trick") return true; return false; }); - for(var i=0;i=0; + }, + }, }, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.countCards('h')= 0 + ); + }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.countCards("h") < current.hp; }); }, - content:function(){ - 'step 0' - event.list=game.filterPlayer(function(current){ - return current.countCards('h')0; + check: function (event, player) { + return ( + get.attitude(player, event.player) < 0 && + get.effect(event.player, { name: "sha" }, player, player) > 0 + ); }, - logTarget:'player', - skillAnimation:true, - animationColor:'wood', - onWash:function(){ - _status.event.getParent('fuzhu').washed=true; - return 'remove'; + logTarget: "player", + skillAnimation: true, + animationColor: "wood", + onWash: function () { + _status.event.getParent("fuzhu").washed = true; + return "remove"; }, - content:function(){ - 'step 0' - event.washed=false; + content: function () { + "step 0"; + event.washed = false; lib.onwash.push(lib.skill.fuzhu.onWash); - event.total=game.players.length+game.dead.length; - 'step 1' + event.total = game.players.length + game.dead.length; + "step 1"; event.total--; - var card=get.cardPile2(function(card){ - return card.name=='sha'&&player.canUse(card,trigger.player,false); + var card = get.cardPile2(function (card) { + return card.name == "sha" && player.canUse(card, trigger.player, false); }); - if(card){ - player.useCard(card,trigger.player,false); + if (card) { + player.useCard(card, trigger.player, false); } - 'step 2' - if(event.total>0&&!event.washed&&ui.cardPile.childElementCount<=player.hp*10&&trigger.player.isIn()) event.goto(1); - 'step 3' + "step 2"; + if ( + event.total > 0 && + !event.washed && + ui.cardPile.childElementCount <= player.hp * 10 && + trigger.player.isIn() + ) + event.goto(1); + "step 3"; lib.onwash.remove(lib.skill.fuzhu.onWash); game.washCard(); }, - ai:{ - threaten:1.5 - } - }, - wengua:{ - global:'wengua2', - audio:2, - }, - wengua2:{ - audio:'wengua', - enable:'phaseUse', - filter:function(event,player){ - if(player.hasSkill('wengua3')) return false; - return player.countCards('he')&&game.hasPlayer(function(current){ - return current.hasSkill('wengua'); - }); + ai: { + threaten: 1.5, }, - log:false, - delay:false, - filterCard:true, - discard:false, - lose:false, - position:'he', - prompt:function(){ - var player=_status.event.player; - var list=game.filterPlayer(function(current){ - return current.hasSkill('wengua'); + }, + wengua: { + global: "wengua2", + audio: 2, + }, + wengua2: { + audio: "wengua", + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("wengua3")) return false; + return ( + player.countCards("he") && + game.hasPlayer(function (current) { + return current.hasSkill("wengua"); + }) + ); + }, + log: false, + delay: false, + filterCard: true, + discard: false, + lose: false, + position: "he", + prompt: function () { + var player = _status.event.player; + var list = game.filterPlayer(function (current) { + return current.hasSkill("wengua"); }); - if(list.length==1&&list[0]==player) return '将一张牌置于牌堆顶或是牌堆底'; - var str='将一张牌交给'+get.translation(list); - if(list.length>1) str+='中的一人'; + if (list.length == 1 && list[0] == player) return "将一张牌置于牌堆顶或是牌堆底"; + var str = "将一张牌交给" + get.translation(list); + if (list.length > 1) str += "中的一人"; return str; }, - check:function(card){ - if(card.name=='sha') return 5; - return 8-get.value(card); + check: function (card) { + if (card.name == "sha") return 5; + return 8 - get.value(card); }, - content:function(){ - "step 0" - var targets=game.filterPlayer(function(current){ - return current.hasSkill('wengua'); + content: function () { + "step 0"; + var targets = game.filterPlayer(function (current) { + return current.hasSkill("wengua"); }); - if(targets.length==1){ - event.target=targets[0]; + if (targets.length == 1) { + event.target = targets[0]; event.goto(2); - } - else if(targets.length>0){ - player.chooseTarget(true,'选择【问卦】的目标',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',targets).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target); - }); - } - else{ + } else if (targets.length > 0) { + player + .chooseTarget(true, "选择【问卦】的目标", function (card, player, target) { + return _status.event.list.includes(target); + }) + .set("list", targets) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }); + } else { event.finish(); } - "step 1" - if(result.bool&&result.targets.length){ - event.target=result.targets[0]; - } - else{ + "step 1"; + if (result.bool && result.targets.length) { + event.target = result.targets[0]; + } else { event.finish(); } - "step 2" - if(event.target){ - player.logSkill('wengua',event.target); - player.addTempSkill('wengua3','phaseUseEnd'); - event.card=cards[0]; - if(event.target!=player){ - player.give(cards,event.target); + "step 2"; + if (event.target) { + player.logSkill("wengua", event.target); + player.addTempSkill("wengua3", "phaseUseEnd"); + event.card = cards[0]; + if (event.target != player) { + player.give(cards, event.target); } - } - else{ + } else { event.finish(); } delete _status.noclearcountdown; game.stopCountChoose(); - "step 3" - if(event.target.getCards('he').includes(event.card)){ - event.target.chooseControlList('问卦','将'+get.translation(event.card)+'置于牌堆顶','将'+get.translation(event.card)+'置于牌堆底',event.target==player,function(){ - if(get.attitude(event.target,player)<0) return 2; - return 1; - }); - } - else{ + "step 3"; + if (event.target.getCards("he").includes(event.card)) { + event.target.chooseControlList( + "问卦", + "将" + get.translation(event.card) + "置于牌堆顶", + "将" + get.translation(event.card) + "置于牌堆底", + event.target == player, + function () { + if (get.attitude(event.target, player) < 0) return 2; + return 1; + } + ); + } else { event.finish(); } - "step 4" - event.index=result.index; - if(event.index==0||event.index==1){ - var next=event.target.lose(event.card,ui.cardPile); - if(event.index==0) next.insert_card=true; - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },event.target); - } - else event.finish(); - "step 5" + "step 4"; + event.index = result.index; + if (event.index == 0 || event.index == 1) { + var next = event.target.lose(event.card, ui.cardPile); + if (event.index == 0) next.insert_card = true; + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, event.target); + } else event.finish(); + "step 5"; game.delay(); - "step 6" - if(event.index==1){ - game.log(event.target,'将得到的牌置于牌堆底'); - if(ui.cardPile.childElementCount==1||player==event.target){ + "step 6"; + if (event.index == 1) { + game.log(event.target, "将得到的牌置于牌堆底"); + if (ui.cardPile.childElementCount == 1 || player == event.target) { player.draw(); + } else { + game.asyncDraw([player, target], null, null); } - else{ - game.asyncDraw([player,target],null,null); - } - } - else if(event.index==0){ - game.log(player,'将获得的牌置于牌堆顶'); - if(ui.cardPile.childElementCount==1||player==event.target){ - player.draw('bottom'); - } - else{ - game.asyncDraw([player,target],null,null,true); + } else if (event.index == 0) { + game.log(player, "将获得的牌置于牌堆顶"); + if (ui.cardPile.childElementCount == 1 || player == event.target) { + player.draw("bottom"); + } else { + game.asyncDraw([player, target], null, null, true); } } }, - ai:{ - order:2, - threaten:1.5, - result:{ - player:function(player,target){ - var target=game.findPlayer(function(current){ - return current.hasSkill('wengua'); + ai: { + order: 2, + threaten: 1.5, + result: { + player: function (player, target) { + var target = game.findPlayer(function (current) { + return current.hasSkill("wengua"); }); - if(target){ - return get.attitude(player,target); + if (target) { + return get.attitude(player, target); } - } - } - } + }, + }, + }, }, - wengua3:{charlotte:true}, - daiyan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - init:function(){ - lib.onwash.push(function(){ + wengua3: { charlotte: true }, + daiyan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + init: function () { + lib.onwash.push(function () { delete _status.daiyan_notao; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('daiyan'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0){ - if(_status.daiyan_notao){ - return 0; + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("daiyan"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) { + if (_status.daiyan_notao) { + return 0; + } else { + if (target == player.storage.daiyan) return 0; + return (2 * att) / Math.sqrt(1 + target.hp); + } + } else { + if (_status.daiyan_notao) { + if (target == player.storage.daiyan) return -3 * att; + return -att; + } else { + return 0; + } } - else{ - if(target==player.storage.daiyan) return 0; - return 2*att/Math.sqrt(1+target.hp); - } - } - else{ - if(_status.daiyan_notao){ - if(target==player.storage.daiyan) return -3*att; - return -att; - } - else{ - return 0; - } - } - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('daiyan',target); - var tao=get.cardPile2(function(card){ - return get.suit(card)=='heart'&&get.type(card)=='basic'; }); - if(tao){ - target.gain(tao,'gain2'); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("daiyan", target); + var tao = get.cardPile2(function (card) { + return get.suit(card) == "heart" && get.type(card) == "basic"; + }); + if (tao) { + target.gain(tao, "gain2"); + } else { + _status.daiyan_notao = true; } - else{ - _status.daiyan_notao=true; - } - if(target==player.storage.daiyan){ + if (target == player.storage.daiyan) { target.loseHp(); } - player.storage.daiyan=target; - } - else{ + player.storage.daiyan = target; + } else { delete player.storage.daiyan; } }, - ai:{ - threaten:1.5, - expose:0.2 - } + ai: { + threaten: 1.5, + expose: 0.2, + }, }, - fumian:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - 'step 0' - if(player.storage.fumian_choice=='draw'){ - player.chooseControlList(get.prompt('fumian'),'摸牌阶段多摸一张牌','使用红色牌可以多选择两个目标(限一次)',function(event,player){ - if(player.hp==1||player.countCards('h')<=1) return 0; - return 1; - }); + fumian: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + if (player.storage.fumian_choice == "draw") { + player.chooseControlList( + get.prompt("fumian"), + "摸牌阶段多摸一张牌", + "使用红色牌可以多选择两个目标(限一次)", + function (event, player) { + if (player.hp == 1 || player.countCards("h") <= 1) return 0; + return 1; + } + ); + } else if (player.storage.fumian_choice == "red") { + player.chooseControlList( + get.prompt("fumian"), + "摸牌阶段多摸两张牌", + "使用红色牌可以多选择一个目标(限一次)", + function (event, player) { + return 0; + } + ); + } else { + player.chooseControlList( + get.prompt("fumian"), + "摸牌阶段多摸一张牌", + "使用红色牌可以多选择一个目标(限一次)", + function (event, player) { + if (player.hp == 1 || player.countCards("h") < player.hp) return 0; + return 1; + } + ); } - else if(player.storage.fumian_choice=='red'){ - player.chooseControlList(get.prompt('fumian'),'摸牌阶段多摸两张牌','使用红色牌可以多选择一个目标(限一次)',function(event,player){ - return 0; - }); - } - else{ - player.chooseControlList(get.prompt('fumian'),'摸牌阶段多摸一张牌','使用红色牌可以多选择一个目标(限一次)',function(event,player){ - if(player.hp==1||player.countCards('h')0; + zhongjian: { + audio: 2, + enable: "phaseUse", + usable: 2, + filter: function (event, player) { + if (!player.countCards("h")) return false; + if (player.getStat("skill").zhongjian && !player.hasSkill("zhongjian2")) return false; + return game.hasPlayer(function (current) { + return current != player && Math.min(current.hp, current.countCards("h")) > 0; }); }, - filterCard:true, - check:function(){ + filterCard: true, + check: function () { return Math.random(); }, - discard:false, - lose:false, - delay:false, - filterTarget:function(card,player,target){ - return target!=player&&target.hp>0&&target.countCards('h')>0; + discard: false, + lose: false, + delay: false, + filterTarget: function (card, player, target) { + return target != player && target.hp > 0 && target.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - player.choosePlayerCard(target,'h',Math.min(target.countCards('h'),target.hp),true); - 'step 2' - var hs=result.cards; + "step 1"; + player.choosePlayerCard(target, "h", Math.min(target.countCards("h"), target.hp), true); + "step 2"; + var hs = result.cards; target.showCards(hs); - var colors=[]; - var numbers=[]; - for(var i=0;i0; - } - if(!game.hasPlayer(function(current){ - return filterTarget(null,player,current); - })) event._result={bool:false}; - else player.chooseTarget(filterTarget,'弃置一名其他角色的一张牌或摸一张牌').set('ai',function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - return 0; - }); - } - else{ + "step 3"; + if (event.bool1) { + var filterTarget = function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; + }; + if ( + !game.hasPlayer(function (current) { + return filterTarget(null, player, current); + }) + ) + event._result = { bool: false }; + else + player + .chooseTarget(filterTarget, "弃置一名其他角色的一张牌或摸一张牌") + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + return 0; + }); + } else { event.goto(5); } - 'step 4' - if(!result.bool) player.draw(); - else{ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,true,'he'); + "step 4"; + if (!result.bool) player.draw(); + else { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, true, "he"); } - 'step 5' - if(event.bool2){ - player.addTempSkill('zhongjian2'); + "step 5"; + if (event.bool2) { + player.addTempSkill("zhongjian2"); } - if(!event.bool1&&!event.bool2){ - player.addSkill('caishix'); - if(typeof player.storage.caishix!='number') player.storage.caishix=0; + if (!event.bool1 && !event.bool2) { + player.addSkill("caishix"); + if (typeof player.storage.caishix != "number") player.storage.caishix = 0; player.storage.caishix--; - player.markSkill('caishix'); - player.popup('杯具'); + player.markSkill("caishix"); + player.popup("杯具"); } }, - ai:{ - order:8, - result:{ - player:function(player,target){ - return Math.min(target.hp,target.countCards('h')); - } - } - } + ai: { + order: 8, + result: { + player: function (player, target) { + return Math.min(target.hp, target.countCards("h")); + }, + }, + }, }, - zhongjian2:{}, - caishi:{ - audio:2, - trigger:{player:'phaseDrawBegin'}, - direct:true, - content:function(){ - 'step 0' - if(player.isHealthy()){ - event.type=0; - player.chooseBool(get.prompt('caishi'),'令自己的手牌上限+1',function(){ + zhongjian2: {}, + caishi: { + audio: 2, + trigger: { player: "phaseDrawBegin" }, + direct: true, + content: function () { + "step 0"; + if (player.isHealthy()) { + event.type = 0; + player.chooseBool(get.prompt("caishi"), "令自己的手牌上限+1", function () { return true; }); + } else { + event.type = 1; + player.chooseControlList( + get.prompt("caishi"), + "令自己的手牌上限+1", + "回复1点体力,然后本回合你的牌不能对自己使用", + function () { + return 1; + } + ); } - else{ - event.type=1; - player.chooseControlList(get.prompt('caishi'),'令自己的手牌上限+1','回复1点体力,然后本回合你的牌不能对自己使用',function(){ - return 1; - }); - } - 'step 1' - if(event.type){ - if(result.control!='cancel2'){ - player.logSkill('caishi'); - if(result.index==0){ - player.addSkill('caishix'); - if(typeof player.storage.caishix!='number') player.storage.caishix=0; + "step 1"; + if (event.type) { + if (result.control != "cancel2") { + player.logSkill("caishi"); + if (result.index == 0) { + player.addSkill("caishix"); + if (typeof player.storage.caishix != "number") player.storage.caishix = 0; player.storage.caishix++; - player.markSkill('caishix'); - } - else if(result.index==1){ + player.markSkill("caishix"); + } else if (result.index == 1) { player.recover(); - player.addTempSkill('caishi3'); + player.addTempSkill("caishi3"); } } - } - else{ - if(result.bool){ - player.logSkill('caishi'); - player.addSkill('caishix'); - if(typeof player.storage.caishix!='number') player.storage.caishix=0; + } else { + if (result.bool) { + player.logSkill("caishi"); + player.addSkill("caishix"); + if (typeof player.storage.caishix != "number") player.storage.caishix = 0; player.storage.caishix++; - player.markSkill('caishix'); + player.markSkill("caishix"); } } }, }, - caishix:{ - intro:{ - content:function(storage){ - if(storage>0) return '手牌上限+'+storage; - if(storage<0) return '手牌上限'+storage; - return '手牌上限无变化'; + caishix: { + intro: { + content: function (storage) { + if (storage > 0) return "手牌上限+" + storage; + if (storage < 0) return "手牌上限" + storage; + return "手牌上限无变化"; }, }, - mod:{ - maxHandcard:function(player,num){ - if(typeof player.storage.caishix=='number') return num+player.storage.caishix; + mod: { + maxHandcard: function (player, num) { + if (typeof player.storage.caishix == "number") return num + player.storage.caishix; }, }, - charlotte:true, - onremove:true, + charlotte: true, + onremove: true, }, - caishi2:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; - } - } + caishi2: { + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; + }, + }, }, - caishi3:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player==target) return false; - } - } + caishi3: { + mod: { + playerEnabled: function (card, player, target) { + if (player == target) return false; + }, + }, }, - ttt:{ - mod:{ - targetEnabled:function(card){ - if(card.name=='tao') return false; - } - } + ttt: { + mod: { + targetEnabled: function (card) { + if (card.name == "tao") return false; + }, + }, }, - jyzongshi:{ - audio:2, - audioname:['re_jianyong'], - trigger:{player:['chooseToCompareAfter','compareMultipleAfter'],target:['chooseToCompareAfter','compareMultipleAfter']}, - filter:function(event,player){ - if(event.preserve) return false; - if(player==event.player){ - if(event.num1>event.num2){ + jyzongshi: { + audio: 2, + audioname: ["re_jianyong"], + trigger: { + player: ["chooseToCompareAfter", "compareMultipleAfter"], + target: ["chooseToCompareAfter", "compareMultipleAfter"], + }, + filter: function (event, player) { + if (event.preserve) return false; + if (player == event.player) { + if (event.num1 > event.num2) { return !get.owner(event.card2); - } - else{ + } else { return !get.owner(event.card1); } - } - else{ - if(event.num1event.num2){ - return event.card2.name!='du'; + check: function (event, player) { + if (player == event.player) { + if (event.num1 > event.num2) { + return event.card2.name != "du"; + } else { + return event.card1.name != "du"; } - else{ - return event.card1.name!='du'; - } - } - else{ - if(event.num1trigger.num2){ - player.gain(trigger.card2,'gain2','log'); + content: function () { + if (player == trigger.player) { + if (trigger.num1 > trigger.num2) { + player.gain(trigger.card2, "gain2", "log"); + } else { + player.gain(trigger.card1, "gain2", "log"); } - else{ - player.gain(trigger.card1,'gain2','log'); + } else { + if (trigger.num1 < trigger.num2) { + player.gain(trigger.card1, "gain2", "log"); + } else { + player.gain(trigger.card2, "gain2", "log"); } } - else{ - if(trigger.num10; + xinsidi: { + audio: "sidi", + trigger: { global: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + if (event.player == player || event.player.isDead()) return false; + return player.countCards("e") > 0; }, - content:function(){ - 'step 0' - var goon=true; - if(get.attitude(player,trigger.player)>=-0.8) goon=false; - else if(trigger.player.countCards('h')<=3) goon=false; - else if(player.countCards('h','shan')==0) goon=false; - var es=player.getCards('e'); - var color=[]; - for(var i=0;i= -0.8) goon = false; + else if (trigger.player.countCards("h") <= 3) goon = false; + else if (player.countCards("h", "shan") == 0) goon = false; + var es = player.getCards("e"); + var color = []; + for (var i = 0; i < es.length; i++) { color.add(get.color(es[i])); } - if(color.length==2) color='all'; - else color=color[0]; - player.chooseToDiscard(get.prompt2('xinsidi',trigger.player),'he',function(card){ - if(get.type(card)=='basic') return false; - if(_status.event.color=='all') return true; - return get.color(card)==_status.event.color; - }).set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',goon).set('color',color).set('logSkill',['xinsidi',trigger.player]); - 'step 1' - if(result.bool){ - trigger.player.addSkill('xinsidi2'); - trigger.player.markAuto('xinsidi2',[get.color(result.cards[0],result.cards[0].original=='h'?player:false)]); - trigger.player.storage.xinsidi4=player; - trigger.player.syncStorage('xinsidi2'); + if (color.length == 2) color = "all"; + else color = color[0]; + player + .chooseToDiscard(get.prompt2("xinsidi", trigger.player), "he", function (card) { + if (get.type(card) == "basic") return false; + if (_status.event.color == "all") return true; + return get.color(card) == _status.event.color; + }) + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set("goon", goon) + .set("color", color) + .set("logSkill", ["xinsidi", trigger.player]); + "step 1"; + if (result.bool) { + trigger.player.addSkill("xinsidi2"); + trigger.player.markAuto("xinsidi2", [ + get.color(result.cards[0], result.cards[0].original == "h" ? player : false), + ]); + trigger.player.storage.xinsidi4 = player; + trigger.player.syncStorage("xinsidi2"); } }, - ai:{ - threaten:1.5 + ai: { + threaten: 1.5, }, }, - xinsidi2:{ - mark:true, - group:['xinsidi2_end'], - subSkill:{ - end:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - popup:false, - audio:false, - content:function(){ - "step 0" - if(player.storage.xinsidi4.isIn()&&!player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; - }).length&&player.storage.xinsidi4.canUse({name:'sha',isCard:true},player,false)){ - player.storage.xinsidi4.logSkill('xinsidi',player); - player.storage.xinsidi4.useCard({name:'sha',isCard:true},player); + xinsidi2: { + mark: true, + group: ["xinsidi2_end"], + subSkill: { + end: { + trigger: { player: "phaseUseEnd" }, + forced: true, + popup: false, + audio: false, + content: function () { + "step 0"; + if ( + player.storage.xinsidi4.isIn() && + !player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; + }).length && + player.storage.xinsidi4.canUse({ name: "sha", isCard: true }, player, false) + ) { + player.storage.xinsidi4.logSkill("xinsidi", player); + player.storage.xinsidi4.useCard({ name: "sha", isCard: true }, player); } - "step 1" + "step 1"; delete player.storage.xinsidi2; delete player.storage.xinsidi3; delete player.storage.xinsidi4; - player.removeSkill('xinsidi2'); - } - } - }, - mod:{ - cardEnabled:function(card,player){ - if(player.getStorage('xinsidi2').includes(get.color(card))) return false; - }, - cardRespondable:function(card,player){ - if(player.getStorage('xinsidi2').includes(get.color(card))) return false; - }, - cardSavable:function(card,player){ - if(player.getStorage('xinsidi2').includes(get.color(card))) return false; + player.removeSkill("xinsidi2"); + }, }, }, - intro:{ - content:'不能使用或打出$的牌' - } + mod: { + cardEnabled: function (card, player) { + if (player.getStorage("xinsidi2").includes(get.color(card))) return false; + }, + cardRespondable: function (card, player) { + if (player.getStorage("xinsidi2").includes(get.color(card))) return false; + }, + cardSavable: function (card, player) { + if (player.getStorage("xinsidi2").includes(get.color(card))) return false; + }, + }, + intro: { + content: "不能使用或打出$的牌", + }, }, - taoluan:{ - hiddenCard:function(player,name){ - return !player.getStorage('taoluan').includes(name)&&player.countCards('hes')>0&&!player.hasSkill('taoluan3')&&lib.inpile.includes(name); + taoluan: { + hiddenCard: function (player, name) { + return ( + !player.getStorage("taoluan").includes(name) && + player.countCards("hes") > 0 && + !player.hasSkill("taoluan3") && + lib.inpile.includes(name) + ); }, - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - return !player.hasSkill('taoluan3')&&player.hasCard(card=>lib.inpile.some(name=>{ - if(player.getStorage('taoluan').includes(name)) return false; - if(get.type(name)!='basic'&&get.type(name)!='trick') return false; - if(event.filterCard({name:name,isCard:true,cards:[card]},player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - if(event.filterCard({name:name,nature:nature,isCard:true,cards:[card]},player,event)) return true; - } - } - return false; - },'hes'))>0; + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + return ( + !player.hasSkill("taoluan3") && + player.hasCard((card) => + lib.inpile.some((name) => { + if (player.getStorage("taoluan").includes(name)) return false; + if (get.type(name) != "basic" && get.type(name) != "trick") return false; + if ( + event.filterCard( + { name: name, isCard: true, cards: [card] }, + player, + event + ) + ) + return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + if ( + event.filterCard( + { name: name, nature: nature, isCard: true, cards: [card] }, + player, + event + ) + ) + return true; + } + } + return false; + }, "hes") + ) > 0 + ); }, - onremove:true, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var name of lib.inpile){ - if(get.type(name)=='basic'||get.type(name)=='trick'){ - if(player.getStorage('taoluan').includes(name)) continue; - list.push([get.translation(get.type(name)),'',name]); - if(name=='sha'){ - for(var j of lib.inpile_nature) list.push(['基本','','sha',j]); + onremove: true, + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var name of lib.inpile) { + if (get.type(name) == "basic" || get.type(name) == "trick") { + if (player.getStorage("taoluan").includes(name)) continue; + list.push([get.translation(get.type(name)), "", name]); + if (name == "sha") { + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } } } - return ui.create.dialog('滔乱',[list,'vcard']); + return ui.create.dialog("滔乱", [list, "vcard"]); }, - filter:function(button,player){ - return _status.event.getParent().filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return _status.event + .getParent() + .filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(player.countCards('hes',cardx=>cardx.name==card.name)) return 0; - return _status.event.getParent().type=='phase'?player.getUseValue(card):1; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if (player.countCards("hes", (cardx) => cardx.name == card.name)) return 0; + return _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'taoluan', - filterCard:true, - popname:true, - check:function(card){ - return 7-get.value(card); + audio: "taoluan", + filterCard: true, + popname: true, + check: function (card) { + return 7 - get.value(card); }, - position:'hes', - viewAs:{name:links[0][2],nature:links[0][3]}, - onuse:function(result,player){ - player.markAuto('taoluan',[result.card.name]); + position: "hes", + viewAs: { name: links[0][2], nature: links[0][3] }, + onuse: function (result, player) { + player.markAuto("taoluan", [result.card.name]); }, - } + }; + }, + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, - prompt:function(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; - } }, - ai:{ - save:true, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(!player.countCards('hes')||player.hasSkill('taoluan3')) return false; - if(tag=='respondSha'||tag=='respondShan'){ - if(arg=='respond') return false; - return !player.getStorage('taoluan').includes(tag=='respondSha'?'sha':'shan'); + ai: { + save: true, + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (!player.countCards("hes") || player.hasSkill("taoluan3")) return false; + if (tag == "respondSha" || tag == "respondShan") { + if (arg == "respond") return false; + return !player + .getStorage("taoluan") + .includes(tag == "respondSha" ? "sha" : "shan"); } - return !player.getStorage('taoluan').includes('tao')||(!player.getStorage('taoluan').includes('jiu')&&arg==player); + return ( + !player.getStorage("taoluan").includes("tao") || + (!player.getStorage("taoluan").includes("jiu") && arg == player) + ); }, - order:4, - result:{ - player:function(player){ - var allshown=true,players=game.filterPlayer(); - for(var i=0;i0){ + if ( + players[i] != player && + players[i].countCards("h") && + get.attitude(player, players[i]) > 0 + ) { return 1; } } - if(allshown) return 1; + if (allshown) return 1; return 0; - } + }, }, - threaten:1.9, + threaten: 1.9, }, - group:'taoluan2', + group: "taoluan2", }, - taoluan2:{ - charlotte:true, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - if(!game.hasPlayer(current=>current!=player)) return false; - return event.skill=='taoluan_backup'; + taoluan2: { + charlotte: true, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + if (!game.hasPlayer((current) => current != player)) return false; + return event.skill == "taoluan_backup"; }, - forced:true, - popup:false, - content:function(){ - 'step 0' - player.chooseTarget(true,function(card,player,target){ - return target!=player; - },'滔乱

              令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力').set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0){ - if(get.attitude(target,player)>0){ - return target.countCards('he'); + forced: true, + popup: false, + content: function () { + "step 0"; + player + .chooseTarget( + true, + function (card, player, target) { + return target != player; + }, + '滔乱

              令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力' + ) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) { + if (get.attitude(target, player) > 0) { + return target.countCards("he"); + } + return target.countCards("he") / 2; } - return target.countCards('he')/2; - } - return 0; - }); - 'step 1' - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var type=get.type(trigger.card,'trick'); - target.chooseCard('滔乱

              交给'+get.translation(player)+'一张不为'+get.translation(type)+'牌的牌,或令其失去1点体力且滔乱无效直到回合结束','he',function(card,player,target){ - return get.type(card,'trick')!=_status.event.cardType; - }).set('cardType',type).set('ai',function(card){ - if(_status.event.att){ - return 11-get.value(card); - } - return 0; - }).set('att',get.attitude(target,player)>0); - 'step 2' - var target=event.target; - if(result.bool){ - target.give(result.cards,player); - } - else{ - player.addTempSkill('taoluan3'); + return 0; + }); + "step 1"; + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var type = get.type(trigger.card, "trick"); + target + .chooseCard( + '滔乱

              交给' + + get.translation(player) + + "一张不为" + + get.translation(type) + + "牌的牌,或令其失去1点体力且滔乱无效直到回合结束", + "he", + function (card, player, target) { + return get.type(card, "trick") != _status.event.cardType; + } + ) + .set("cardType", type) + .set("ai", function (card) { + if (_status.event.att) { + return 11 - get.value(card); + } + return 0; + }) + .set("att", get.attitude(target, player) > 0); + "step 2"; + var target = event.target; + if (result.bool) { + target.give(result.cards, player); + } else { + player.addTempSkill("taoluan3"); player.loseHp(); } - } + }, }, - taoluan3:{charlotte:true}, - taoluan_backup:{}, - jishe:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.getHandcardLimit()>0; + taoluan3: { charlotte: true }, + taoluan_backup: {}, + jishe: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.getHandcardLimit() > 0; }, - usable:20, - locked:false, - content:function(){ + usable: 20, + locked: false, + content: function () { player.draw(); - player.addTempSkill('jishe2'); - player.addMark('jishe2',1,false); + player.addTempSkill("jishe2"); + player.addMark("jishe2", 1, false); }, - ai:{ - order:10, - result:{ - player:function(player){ - if(!player.needsToDiscard(1)){ + ai: { + order: 10, + result: { + player: function (player) { + if (!player.needsToDiscard(1)) { return 1; } return 0; - } - } + }, + }, }, - group:['jishe3'] + group: ["jishe3"], }, - jishe2:{ - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('jishe2'); - } + jishe2: { + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("jishe2"); + }, }, - onremove:true, - charlotte:true, - marktext:'奢', - intro:{content:'手牌上限-#'}, + onremove: true, + charlotte: true, + marktext: "奢", + intro: { content: "手牌上限-#" }, }, - jishe3:{ - audio:'jishe', - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - return game.hasPlayer(function(current){ + jishe3: { + audio: "jishe", + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + if (player.countCards("h")) return false; + return game.hasPlayer(function (current) { return !current.isLinked(); }); }, - content:function(){ - "step 0" - var num=game.countPlayer(function(current){ + content: function () { + "step 0"; + var num = game.countPlayer(function (current) { return !current.isLinked(); }); - player.chooseTarget(get.prompt('jishe'),'横置至多'+get.cnNumber(Math.min(num,player.hp))+'名未横置的角色',[1,Math.min(num,player.hp)],function(card,player,target){ - return !target.isLinked(); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 1" - if(result.bool){ - player.logSkill('jishe',result.targets); - event.targets=result.targets; - event.num=0; - } - else{ + player + .chooseTarget( + get.prompt("jishe"), + "横置至多" + get.cnNumber(Math.min(num, player.hp)) + "名未横置的角色", + [1, Math.min(num, player.hp)], + function (card, player, target) { + return !target.isLinked(); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("jishe", result.targets); + event.targets = result.targets; + event.num = 0; + } else { event.finish(); } - "step 2" - if(event.num0); - var goon=false; - if(player.hp==1){ - goon=true; - } - else{ - var he=player.getCards('he'); - var num=0; - for(var i=0;i 0; + var goon = false; + if (player.hp == 1) { + goon = true; + } else { + var he = player.getCards("he"); + var num = 0; + for (var i = 0; i < he.length; i++) { + if (get.value(he[i]) < 8) { num++; - if(num>=2){ - goon=true;break; + if (num >= 2) { + goon = true; + break; } } } } - player.chooseCard('he',[1,player.countCards('he')],get.prompt2('huisheng',trigger.source)).set('ai',function(card){ - if(_status.event.att){ - return 10-get.value(card); - } - if(_status.event.goon){ - return 8-get.value(card); - } - if(!ui.selected.cards.length){ - return 7-get.value(card); - } - return 0; - }).set('goon',goon).set('att',att); - 'step 1' - if(result.bool){ - player.logSkill('huisheng',trigger.source); - game.delay(); - event.num=result.cards.length; - var goon=false; - if(event.num>2||get.attitude(trigger.source,player)>=0){ - goon=true; - } - var forced=false; - var str='获得其中一张牌并防止伤害'; - if(trigger.source.countCards('he') 2 || get.attitude(trigger.source, player) >= 0) { + goon = true; + } + var forced = false; + var str = "获得其中一张牌并防止伤害"; + if (trigger.source.countCards("he") < event.num) { + forced = true; + } else { + str += ",或取消并弃置" + get.cnNumber(result.cards.length) + "张牌"; + } + trigger.source + .chooseButton([str, result.cards], forced) + .set("ai", function (button) { + if (_status.event.goon) { + return get.value(button.link); + } + return get.value(button.link) - 8; + }) + .set("goon", goon); + } else { event.finish(); } - 'step 2' - if(result.bool){ - var card=result.links[0]; - trigger.source.gain(card,player,'giveAuto','bySelf'); + "step 2"; + if (result.bool) { + var card = result.links[0]; + trigger.source.gain(card, player, "giveAuto", "bySelf"); trigger.cancel(); - if(!player.storage.huisheng) player.storage.huisheng=[]; + if (!player.storage.huisheng) player.storage.huisheng = []; player.storage.huisheng.push(trigger.source); + } else { + trigger.source.chooseToDiscard(event.num, true, "he"); } - else{ - trigger.source.chooseToDiscard(event.num,true,'he'); - } - } - }, - qinqing:{ - audio:2, - mode:['identity','versus','doudizhu'], - available:function(mode){ - if(mode=='versus'&&_status.mode!='four') return false; - if(mode=='identity'&&_status.mode=='purple') return false; }, - getZhu:(player)=>{ - if(get.mode=='doudizhu') return game.findPlayer(i=>i.identity=='zhu'); + }, + qinqing: { + audio: 2, + mode: ["identity", "versus", "doudizhu"], + available: function (mode) { + if (mode == "versus" && _status.mode != "four") return false; + if (mode == "identity" && _status.mode == "purple") return false; + }, + getZhu: (player) => { + if (get.mode == "doudizhu") return game.findPlayer((i) => i.identity == "zhu"); return get.zhu(player); }, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - var zhu=get.info('qinqing').getZhu(player); - if(!zhu||(get.mode!='doudizhu'&&!zhu.isZhu)) return false; - return game.hasPlayer(function(current){ - return current!=zhu&¤t.inRange(zhu); + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + var zhu = get.info("qinqing").getZhu(player); + if (!zhu || (get.mode != "doudizhu" && !zhu.isZhu)) return false; + return game.hasPlayer(function (current) { + return current != zhu && current.inRange(zhu); }); }, - content:function(){ - 'step 0' - event.zhu=get.info('qinqing').getZhu(player); - player.chooseTarget(get.prompt2('qinqing'),[1,Infinity],function(card,player,target){ - var zhu=get.event('zhu'); - if(target==zhu) return false; - return target.inRange(zhu); - }).set('ai',function(target){ - var he=target.countCards('he'); - var zhu=get.event('zhu'); - if(get.attitude(_status.event.player,target)>0){ - if(he==0) return 1; - if(target.countCards('h')>zhu.countCards('h')) return 1; - } - else{ - if(he>0) return 1; - } - return 0; - }).set('zhu',event.zhu); - 'step 1' - if(result.bool){ - event.targets=result.targets.slice(0).sortBySeat(); - event.list=event.targets.slice(0); - player.logSkill('qinqing',event.targets); - } - else{ + content: function () { + "step 0"; + event.zhu = get.info("qinqing").getZhu(player); + player + .chooseTarget(get.prompt2("qinqing"), [1, Infinity], function (card, player, target) { + var zhu = get.event("zhu"); + if (target == zhu) return false; + return target.inRange(zhu); + }) + .set("ai", function (target) { + var he = target.countCards("he"); + var zhu = get.event("zhu"); + if (get.attitude(_status.event.player, target) > 0) { + if (he == 0) return 1; + if (target.countCards("h") > zhu.countCards("h")) return 1; + } else { + if (he > 0) return 1; + } + return 0; + }) + .set("zhu", event.zhu); + "step 1"; + if (result.bool) { + event.targets = result.targets.slice(0).sortBySeat(); + event.list = event.targets.slice(0); + player.logSkill("qinqing", event.targets); + } else { event.finish(); } - 'step 2' - if(event.targets.length){ - var target=event.targets.shift(); - if(target.countCards('he')){ - player.discardPlayerCard(target,'he',true); + "step 2"; + if (event.targets.length) { + var target = event.targets.shift(); + if (target.countCards("he")) { + player.discardPlayerCard(target, "he", true); } target.draw(); event.redo(); } - 'step 3' - var num=0; - if(event.zhu){ - var nh=event.zhu.countCards('h'); - for(var i=0;inh){ + "step 3"; + var num = 0; + if (event.zhu) { + var nh = event.zhu.countCards("h"); + for (var i = 0; i < event.list.length; i++) { + if (event.list[i].countCards("h") > nh) { num++; } } - if(num){ + if (num) { player.draw(num); } } }, - ai:{ - threaten:1.2 - } + ai: { + threaten: 1.2, + }, }, - guizao:{ - audio:2, - trigger:{player:'phaseDiscardEnd'}, - direct:true, - filter:function(event,player){ - if(event.cards&&event.cards.length>1){ - var suits=[]; - for(var i=0;i 1) { + var suits = []; + for (var i = 0; i < event.cards.length; i++) { + var suit = get.suit(event.cards[i]); + if (suits.includes(suit)) { return false; - } - else{ + } else { suits.push(suit); } } @@ -5665,3089 +6801,3551 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return false; }, - content:function(){ - player.chooseDrawRecover(get.prompt('guizao'),'摸一张牌或回复1点体力').logSkill='guizao'; + content: function () { + player.chooseDrawRecover(get.prompt("guizao"), "摸一张牌或回复1点体力").logSkill = + "guizao"; }, }, - jiyu:{ - audio:2, - enable:'phaseUse', - locked:false, - filter:function(event,player){ - if(!player.getStat().skill.jiyu||!player.storage.jiyu2) return true; - var hs=player.getCards('h'); - for(var i=0;i0||target.hp<=2){ - spade=false; + var spade = true; + if (player.isTurnedOver() || get.attitude(target, player) > 0 || target.hp <= 2) { + spade = false; } - target.chooseToDiscard('h',true).set('ai',function(card){ - if(get.suit(card)=='spade'){ - if(_status.event.spade){ - return 10-get.value(card); + target + .chooseToDiscard("h", true) + .set("ai", function (card) { + if (get.suit(card) == "spade") { + if (_status.event.spade) { + return 10 - get.value(card); + } else { + return -10 - get.value(card); + } } - else{ - return -10-get.value(card); + if ( + _status.event.getParent().player.storage.jiyu2 && + _status.event.getParent().player.storage.jiyu2.includes(get.suit(card)) + ) { + return -3 - get.value(card); } - } - if(_status.event.getParent().player.storage.jiyu2&&_status.event.getParent().player.storage.jiyu2.includes(get.suit(card))){ - return -3-get.value(card); - } - return -get.value(card); - }).set('spade',spade); - 'step 1' - if(!result.cards||!result.cards.length) return; - var card=result.cards[0]; - if(get.suit(card,target)=='spade'){ + return -get.value(card); + }) + .set("spade", spade); + "step 1"; + if (!result.cards || !result.cards.length) return; + var card = result.cards[0]; + if (get.suit(card, target) == "spade") { player.turnOver(); target.loseHp(); } - if(!player.storage.jiyu2) player.storage.jiyu2=[]; + if (!player.storage.jiyu2) player.storage.jiyu2 = []; player.storage.jiyu2.add(get.suit(card)); }, - onremove:['jiyu','jiyu2'], - ai:{ - order:9, - result:{ - target:function(player,target){ - if(player.isTurnedOver()||target.countCards('h')<=3) return -1; + onremove: ["jiyu", "jiyu2"], + ai: { + order: 9, + result: { + target: function (player, target) { + if (player.isTurnedOver() || target.countCards("h") <= 3) return -1; return 0; - } - } + }, + }, }, - mod:{ - cardEnabled:function(card,player){ - if(player.storage.jiyu2&&player.storage.jiyu2.includes(get.suit(card))) return false; + mod: { + cardEnabled: function (card, player) { + if (player.storage.jiyu2 && player.storage.jiyu2.includes(get.suit(card))) + return false; }, - cardSavable:function(card,player){ - if(player.storage.jiyu2&&player.storage.jiyu2.includes(get.suit(card))) return false; + cardSavable: function (card, player) { + if (player.storage.jiyu2 && player.storage.jiyu2.includes(get.suit(card))) + return false; }, - } + }, }, - jiyu2:{ - trigger:{player:['phaseUseBegin','phaseUseAfter']}, - silent:true, - content:function(){ - player.storage.jiyu=[]; - player.storage.jiyu2=[]; - } + jiyu2: { + trigger: { player: ["phaseUseBegin", "phaseUseAfter"] }, + silent: true, + content: function () { + player.storage.jiyu = []; + player.storage.jiyu2 = []; + }, }, - jiaozhao:{ - mod:{ - targetEnabled:function(card,player,target){ - if(card.storage&&card.storage.jiaozhao&&card.storage.jiaozhao==target) return false; + jiaozhao: { + mod: { + targetEnabled: function (card, player, target) { + if (card.storage && card.storage.jiaozhao && card.storage.jiaozhao == target) + return false; }, }, - enable:'phaseUse', - usable:1, - audio:2, - check:function(card){ - return 8-get.value(card); + enable: "phaseUse", + usable: 1, + audio: 2, + check: function (card) { + return 8 - get.value(card); }, - filter:function(event,player){ - return player.countMark('xindanxin')<2&&player.countCards('h')>0; + filter: function (event, player) { + return player.countMark("xindanxin") < 2 && player.countCards("h") > 0; }, - filterCard:true, - discard:false, - lose:false, - delay:false, - locked:false, - content:function(){ - 'step 0' + filterCard: true, + discard: false, + lose: false, + delay: false, + locked: false, + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - if(player.countMark('xindanxin')>1){ - event.target=player; - } - else{ - var targets=game.filterPlayer(); + "step 1"; + if (player.countMark("xindanxin") > 1) { + event.target = player; + } else { + var targets = game.filterPlayer(); targets.remove(player); - targets.sort(function(a,b){ - return Math.max(1,get.distance(player,a))-Math.max(1,get.distance(player,b)); + targets.sort(function (a, b) { + return ( + Math.max(1, get.distance(player, a)) - Math.max(1, get.distance(player, b)) + ); }); - var distance=Math.max(1,get.distance(player,targets[0])); - for(var i=1;idistance){ - targets.splice(i);break; + var distance = Math.max(1, get.distance(player, targets[0])); + for (var i = 1; i < targets.length; i++) { + if (Math.max(1, get.distance(player, targets[i])) > distance) { + targets.splice(i); + break; } } - player.chooseTarget('请选择【矫诏】的目标',true,function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('targets',targets); + player + .chooseTarget("请选择【矫诏】的目标", true, function (card, player, target) { + return _status.event.targets.includes(target); + }) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("targets", targets); } - 'step 2' - if(!event.target){ - event.target=result.targets[0]; - player.line(result.targets,'green'); + "step 2"; + if (!event.target) { + event.target = result.targets[0]; + player.line(result.targets, "green"); } - if(!event.target){ + if (!event.target) { event.finish(); return; } - var list=[]; - for(var i=0;i0&&get.type(name)=='trick') list.push(['锦囊','',name]); + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + var name = lib.inpile[i]; + if (name == "sha") { + list.push(["基本", "", "sha"]); + for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); + } else if (get.type(name) == "basic") list.push(["基本", "", name]); + else if (player.countMark("xindanxin") > 0 && get.type(name) == "trick") + list.push(["锦囊", "", name]); } - event.target.chooseButton(['矫诏',[list,'vcard']],true).set('ai',function(button){ - var player=_status.event.getParent().player,card={ - name:button.link[2], - nature:button.link[3], - storage:{ - jiaozhao:player, - } - }; - return player.getUseValue(card,null,true)*_status.event.att; - }).set('att',get.attitude(event.target,player)>0?1:-1); - 'step 3' - var chosen=result.links[0][2]; - var nature=result.links[0][3]; - var fakecard={ - name:chosen, - storage:{jiaozhao:player}, + event.target + .chooseButton(["矫诏", [list, "vcard"]], true) + .set("ai", function (button) { + var player = _status.event.getParent().player, + card = { + name: button.link[2], + nature: button.link[3], + storage: { + jiaozhao: player, + }, + }; + return player.getUseValue(card, null, true) * _status.event.att; + }) + .set("att", get.attitude(event.target, player) > 0 ? 1 : -1); + "step 3"; + var chosen = result.links[0][2]; + var nature = result.links[0][3]; + var fakecard = { + name: chosen, + storage: { jiaozhao: player }, }; - if(nature) fakecard.nature=nature; - event.target.showCards(game.createCard({ - name:chosen, - nature:nature, - suit:cards[0].suit, - number:cards[0].number, - }),get.translation(event.target)+'声明了'+get.translation(chosen)); - player.storage.jiaozhao=cards[0]; - player.storage.jiaozhao_card=fakecard; - game.broadcastAll(function(name,card){ - lib.skill.jiaozhao2.viewAs=fakecard; - card.addGaintag('jiaozhao'); - },fakecard,cards[0]); - player.addTempSkill('jiaozhao2','phaseUseEnd'); + if (nature) fakecard.nature = nature; + event.target.showCards( + game.createCard({ + name: chosen, + nature: nature, + suit: cards[0].suit, + number: cards[0].number, + }), + get.translation(event.target) + "声明了" + get.translation(chosen) + ); + player.storage.jiaozhao = cards[0]; + player.storage.jiaozhao_card = fakecard; + game.broadcastAll( + function (name, card) { + lib.skill.jiaozhao2.viewAs = fakecard; + card.addGaintag("jiaozhao"); + }, + fakecard, + cards[0] + ); + player.addTempSkill("jiaozhao2", "phaseUseEnd"); }, - ai:{ - order:9, - result:{ - player:1 - } + ai: { + order: 9, + result: { + player: 1, + }, }, - group:'jiaozhao3', + group: "jiaozhao3", }, - jiaozhao2:{ - enable:'phaseUse', - audio:'jiaozhao', - charlotte:true, - filter:function(event,player){ - if(!player.storage.jiaozhao||!lib.skill.jiaozhao2.viewAs) return false; - var name=lib.skill.jiaozhao2.viewAs.name; - return player.getCards('h').includes(player.storage.jiaozhao)&&player.storage.jiaozhao.hasGaintag('jiaozhao')&&game.checkMod(player.storage.jiaozhao,player,'unchanged','cardEnabled2',player)!==false; + jiaozhao2: { + enable: "phaseUse", + audio: "jiaozhao", + charlotte: true, + filter: function (event, player) { + if (!player.storage.jiaozhao || !lib.skill.jiaozhao2.viewAs) return false; + var name = lib.skill.jiaozhao2.viewAs.name; + return ( + player.getCards("h").includes(player.storage.jiaozhao) && + player.storage.jiaozhao.hasGaintag("jiaozhao") && + game.checkMod( + player.storage.jiaozhao, + player, + "unchanged", + "cardEnabled2", + player + ) !== false + ); }, - filterCard:function(card,player){ - return card==player.storage.jiaozhao; + filterCard: function (card, player) { + return card == player.storage.jiaozhao; }, - selectCard:-1, - popname:true, - prompt:function(){ - return '选择'+get.translation(lib.skill.jiaozhao2.viewAs)+'的目标'; + selectCard: -1, + popname: true, + prompt: function () { + return "选择" + get.translation(lib.skill.jiaozhao2.viewAs) + "的目标"; }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - ai:{ - order:6 + ai: { + order: 6, }, - onremove:function(player){ - player.removeGaintag('jiaozhao'); + onremove: function (player) { + player.removeGaintag("jiaozhao"); delete player.storage.jiaozhao; delete player.storage.jiaozhao_card; }, }, - jiaozhao3:{ - audio:'jiaozhao', - enable:'phaseUse', - filter:function(event,player){ - return (player.getStat('skill').jiaozhao||0)+(player.getStat('skill').jiaozhao3||0)<(player.countMark('xindanxin')-1)&&player.countCards('h')>0; + jiaozhao3: { + audio: "jiaozhao", + enable: "phaseUse", + filter: function (event, player) { + return ( + (player.getStat("skill").jiaozhao || 0) + (player.getStat("skill").jiaozhao3 || 0) < + player.countMark("xindanxin") - 1 && player.countCards("h") > 0 + ); }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - for(var i of lib.inpile){ - var type=get.type(i,false); - if(type=='basic'||type=='trick'){ - var card={name:i,storage:{ - jiaozhao:player, - }}; - if(event.filterCard(card,player,event)) list.push([type,'',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - card.nature=j; - if(event.filterCard(card,player,event)) list.push([type,'',i,j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + for (var i of lib.inpile) { + var type = get.type(i, false); + if (type == "basic" || type == "trick") { + var card = { + name: i, + storage: { + jiaozhao: player, + }, + }; + if (event.filterCard(card, player, event)) list.push([type, "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + card.nature = j; + if (event.filterCard(card, player, event)) + list.push([type, "", i, j]); } } } } - if(list.length) return ui.create.dialog('矫诏',[list,'vcard']); - return ui.create.dialog('矫诏:当前没有可用牌'); + if (list.length) return ui.create.dialog("矫诏", [list, "vcard"]); + return ui.create.dialog("矫诏:当前没有可用牌"); }, - check:function(button){ - var player=_status.event.player,card={ - name:button.link[2], - nature:button.link[3], - storage:{ - jiaozhao:player, - } - }; + check: function (button) { + var player = _status.event.player, + card = { + name: button.link[2], + nature: button.link[3], + storage: { + jiaozhao: player, + }, + }; return player.getUseValue(card); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'jiaozhao', - filterCard:true, - position:'h', - popname:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], - storage:{ - jiaozhao:player, + audio: "jiaozhao", + filterCard: true, + position: "h", + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], + storage: { + jiaozhao: player, }, }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, }; }, - prompt:function(links,player){ - return '将一张牌当做'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt: function (links, player) { + return ( + "将一张牌当做" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, - ai:{ - order:9, - result:{ - player:1 - } + ai: { + order: 9, + result: { + player: 1, + }, }, }, - jiaozhao3_backup:{audio:'jiaozhao'}, - xindanxin:{ - trigger:{player:'damageEnd'}, - frequent:true, - audio:'danxin', - content:function(){ + jiaozhao3_backup: { audio: "jiaozhao" }, + xindanxin: { + trigger: { player: "damageEnd" }, + frequent: true, + audio: "danxin", + content: function () { player.draw(); - if(player.countMark('xindanxin')<3){ - player.addMark('xindanxin',1,false); - game.log(player,'修改了技能','#g【矫诏】'); + if (player.countMark("xindanxin") < 3) { + player.addMark("xindanxin", 1, false); + game.log(player, "修改了技能", "#g【矫诏】"); } }, - intro:{content:'【矫诏】加成等级:Lv.#'}, - ai:{ - maixie:true, - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')) return; - if(target.hp+target.hujia<2||player.hasSkillTag('jueqing',false,target)) return 1.8; - if(target.countMark('xindanxin')>1) return [1,1]; - return [1,0.8*target.hp-0.5]; - } - } - } + intro: { content: "【矫诏】加成等级:Lv.#" }, + ai: { + maixie: true, + effect: { + target: (card, player, target) => { + if (!get.tag(card, "damage")) return; + if (target.hp + target.hujia < 2 || player.hasSkillTag("jueqing", false, target)) + return 1.8; + if (target.countMark("xindanxin") > 1) return [1, 1]; + return [1, 0.8 * target.hp - 0.5]; + }, + }, + }, }, - danxin:{ - trigger:{player:'damageEnd'}, - frequent:true, - audio:2, - content:function(){ - 'step 0' - if(player.countMark('xindanxin')>=2){ + danxin: { + trigger: { player: "damageEnd" }, + frequent: true, + audio: 2, + content: function () { + "step 0"; + if (player.countMark("xindanxin") >= 2) { player.draw(); event.finish(); - } - else{ - var list=['draw_card','更改描述']; + } else { + var list = ["draw_card", "更改描述"]; var prompt; - if(player.countMark('xindanxin')==0){ - prompt='摸一张牌或更改矫诏的描述

              更改描述:将“选择距离最近的一名其他角色,该角色”改为“你”'; + if (player.countMark("xindanxin") == 0) { + prompt = + '摸一张牌或更改矫诏的描述

              更改描述:将“选择距离最近的一名其他角色,该角色”改为“你”'; + } else { + prompt = + '摸一张牌或更改矫诏的描述

              更改描述:将“基本牌”改为“基本牌或普通锦囊牌”'; } - else{ - prompt='摸一张牌或更改矫诏的描述

              更改描述:将“基本牌”改为“基本牌或普通锦囊牌”'; - } - player.chooseControl(list,function(){ - if(!_status.event.player.hasSkill('jiaozhao')) return 'draw_card'; - return '更改描述'; - }).set('prompt',prompt); + player + .chooseControl(list, function () { + if (!_status.event.player.hasSkill("jiaozhao")) return "draw_card"; + return "更改描述"; + }) + .set("prompt", prompt); } - 'step 1' - if(result.control=='draw_card'){ + "step 1"; + if (result.control == "draw_card") { player.draw(); - } - else{ - game.log(player,'更改了','【矫诏】','的描述'); - player.popup('更改描述'); - player.addMark('xindanxin',1,false); + } else { + game.log(player, "更改了", "【矫诏】", "的描述"); + player.popup("更改描述"); + player.addMark("xindanxin", 1, false); } }, - ai:{ - maixie:true, - effect:{ - target:(card,player,target)=>{ - if(!get.tag(card,'damage')) return; - if(target.hp<2||player.hasSkillTag('jueqing',false,target)) return 1.5; - return [1,1]; - } - } - } + ai: { + maixie: true, + effect: { + target: (card, player, target) => { + if (!get.tag(card, "damage")) return; + if (target.hp < 2 || player.hasSkillTag("jueqing", false, target)) return 1.5; + return [1, 1]; + }, + }, + }, }, - zongzuo:{ - trigger:{ - global:'phaseBefore', - player:'enterGame', + zongzuo: { + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - audio:2, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + forced: true, + audio: 2, + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - content:function(){ - 'step 0' - var num=game.countGroup(); + content: function () { + "step 0"; + var num = game.countGroup(); player.gainMaxHp(num); - event.num=num; - 'step 1' + event.num = num; + "step 1"; player.recover(event.num); //player.update(); }, - group:'zongzuo_lose', - subSkill:{ - lose:{ - trigger:{global:'dieAfter'}, - forced:true, - audio:'zongzuo', - filter:function(event,player){ - if(!lib.group.includes(event.player.group)) return false; - if(game.hasPlayer(function(current){ - return current.group==event.player.group; - })){ + group: "zongzuo_lose", + subSkill: { + lose: { + trigger: { global: "dieAfter" }, + forced: true, + audio: "zongzuo", + filter: function (event, player) { + if (!lib.group.includes(event.player.group)) return false; + if ( + game.hasPlayer(function (current) { + return current.group == event.player.group; + }) + ) { return false; } return true; }, - content:function(){ + content: function () { player.loseMaxHp(); - } - } - } + }, + }, + }, }, - zhige:{ - enable:'phaseUse', - usable:1, - audio:2, - filter:function(event,player){ - return player.countCards('h')>player.hp; + zhige: { + enable: "phaseUse", + usable: 1, + audio: 2, + filter: function (event, player) { + return player.countCards("h") > player.hp; }, - filterTarget:function(card,player,target){ - return get.distance(target,player,'attack')<=1&&target.countCards('e')>0; + filterTarget: function (card, player, target) { + return get.distance(target, player, "attack") <= 1 && target.countCards("e") > 0; }, - content:function(){ - 'step 0' - target.chooseToUse({name:'sha'},'止戈:使用一张杀,或将其装备区里的一张牌交给'+get.translation(player)); - 'step 1' - if(!result.bool&&target.countCards('e')){ - target.chooseCard('e',true,'将其装备区里的一张牌交给'+get.translation(player)); - } - else{ + content: function () { + "step 0"; + target.chooseToUse( + { name: "sha" }, + "止戈:使用一张杀,或将其装备区里的一张牌交给" + get.translation(player) + ); + "step 1"; + if (!result.bool && target.countCards("e")) { + target.chooseCard("e", true, "将其装备区里的一张牌交给" + get.translation(player)); + } else { event.finish(); } - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - target.give(result.cards,player); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + target.give(result.cards, player); } }, - ai:{ - expose:0.2, - order:5, - result:{ - target:-1, - player:function(player,target){ - if(target.countCards('h')==0) return 0; - if(target.countCards('h')==1) return -0.1; - if(player.hp<=2) return -2; - if(player.countCards('h','shan')==0) return -1; + ai: { + expose: 0.2, + order: 5, + result: { + target: -1, + player: function (player, target) { + if (target.countCards("h") == 0) return 0; + if (target.countCards("h") == 1) return -0.1; + if (player.hp <= 2) return -2; + if (player.countCards("h", "shan") == 0) return -1; return -0.5; - } - } - } - }, - kuangbi:{ - enable:'phaseUse', - usable:1, - audio:2, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + }, + }, }, - content:function(){ - 'step 0' - target.chooseCard('he',[1,3],'匡弼:将至多三张牌置于'+get.translation(player)+'的武将牌上',true).set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0){ - return 7-get.value(card); - } - return -get.value(card); - }); - 'step 1' - if(result.bool){ - player.addToExpansion(result.cards,target,'give').gaintag.add('kuangbi'); - if(!player.storage.kuangbi_draw) player.storage.kuangbi_draw=[[],[]]; + }, + kuangbi: { + enable: "phaseUse", + usable: 1, + audio: 2, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; + }, + content: function () { + "step 0"; + target + .chooseCard( + "he", + [1, 3], + "匡弼:将至多三张牌置于" + get.translation(player) + "的武将牌上", + true + ) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) { + return 7 - get.value(card); + } + return -get.value(card); + }); + "step 1"; + if (result.bool) { + player.addToExpansion(result.cards, target, "give").gaintag.add("kuangbi"); + if (!player.storage.kuangbi_draw) player.storage.kuangbi_draw = [[], []]; player.storage.kuangbi_draw[0].push(target); player.storage.kuangbi_draw[1].push(result.cards.length); - player.addSkill('kuangbi_draw'); - player.syncStorage('kuangbi_draw'); - player.updateMarks('kuangbi_draw'); + player.addSkill("kuangbi_draw"); + player.syncStorage("kuangbi_draw"); + player.updateMarks("kuangbi_draw"); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); delete player.storage[skill]; }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0){ - return Math.sqrt(target.countCards('he')); + ai: { + order: 1, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) { + return Math.sqrt(target.countCards("he")); } return 0; }, - player:1 - } + player: 1, + }, }, - subSkill:{ - draw:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - mark:true, - charlotte:true, - audio:'kuangbi', - onremove:true, - filter:function(event,player){ - return player.getExpansions('kuangbi').length; + subSkill: { + draw: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + mark: true, + charlotte: true, + audio: "kuangbi", + onremove: true, + filter: function (event, player) { + return player.getExpansions("kuangbi").length; }, - content:function(){ - player.gain(player.getExpansions('kuangbi'),'gain2'); - var storage=player.storage.kuangbi_draw; - if(storage.length){ - for(var i=0;i0; + duliang: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("h") > 0; }, - audio:2, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'h',true); - 'step 1' - var name=get.translation(target); - player.chooseControl(function(){ - return Math.random()<0.5?'选项一':'选项二'; - }).set('prompt','督粮').set('choiceList',['令'+name+'观看牌堆顶的两张牌,然后获得其中的基本牌','令'+name+'于下个摸牌阶段额外摸一张牌']); - 'step 2' - if(result.control=='选项一'){ - var cards=get.cards(2); - target.viewCards('督粮',cards); - event.cards2=[]; - event.tothrow=[]; - for(var i=0;i=_status.event.getParent().num) return -1; - if(_status.event.player.hasSkillTag('nofire')) return -1; - if(_status.event.res>=0) return 6-get.value(card); - if(get.type(card)!='basic'){ - return 10-get.value(card); - } - return 8-get.value(card); - }).set('res',res); - } - else{ + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + event.target = target; + var res = get.damageEffect(target, player, target, "fire"); + target + .chooseToDiscard( + "he", + "弃置至少" + get.cnNumber(event.num) + "张牌或受到2点火焰伤害", + [num, Infinity] + ) + .set("ai", function (card) { + if (ui.selected.cards.length >= _status.event.getParent().num) return -1; + if (_status.event.player.hasSkillTag("nofire")) return -1; + if (_status.event.res >= 0) return 6 - get.value(card); + if (get.type(card) != "basic") { + return 10 - get.value(card); + } + return 8 - get.value(card); + }) + .set("res", res); + } else { event.finish(); } - "step 2" - if(!result.bool){ - event.target.damage(2,'fire'); - event.num=1; - } - else{ - event.num=result.cards.length+1; + "step 2"; + if (!result.bool) { + event.target.damage(2, "fire"); + event.num = 1; + } else { + event.num = result.cards.length + 1; } event.goto(1); }, - ai:{ - order:1, - result:{ - player:function(player){ - var num=0,eff=0,players=game.filterPlayer(function(current){ - return current!=player; - }).sortBySeat(player); - for(var target of players){ - if(get.damageEffect(target,player,target,'fire')>=0){num=0;continue} - var shao=false; - num++; - if(target.countCards('he',function(card){ - if(get.type(card)!='basic'){ - return get.value(card)<10; - } - return get.value(card)<8; - })= 0) { + num = 0; + continue; } - else eff-=num*(get.realAttitude||get.attitude)(player,target)/4; + var shao = false; + num++; + if ( + target.countCards("he", function (card) { + if (get.type(card) != "basic") { + return get.value(card) < 10; + } + return get.value(card) < 8; + }) < num + ) + shao = true; + if (shao) { + eff -= 4 * (get.realAttitude || get.attitude)(player, target); + num = 0; + } else eff -= (num * (get.realAttitude || get.attitude)(player, target)) / 4; } - if(eff<4) return 0; + if (eff < 4) return 0; return eff; - } - } + }, + }, }, - init:function(player){ - player.storage.xinfencheng=false; + init: function (player) { + player.storage.xinfencheng = false; + }, + intro: { + content: "limited", }, - intro:{ - content:'limited' - } }, - xinjuece:{ - audio:'juece', - audioname:['dc_liru'], - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(player){ - return player.countCards('h')==0; + xinjuece: { + audio: "juece", + audioname: ["dc_liru"], + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (player) { + return player.countCards("h") == 0; }); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('xinjuece'),'对一名没有手牌的角色造成1点伤害',function(card,player,target){ - return target.countCards('h')==0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - player.logSkill('xinjuece',result.targets); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xinjuece"), + "对一名没有手牌的角色造成1点伤害", + function (card, player, target) { + return target.countCards("h") == 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + player.logSkill("xinjuece", result.targets); result.targets[0].damage(); } - } + }, }, - xinmieji:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h',{type:['trick','delay'],color:'black'}); + xinmieji: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h", { type: ["trick", "delay"], color: "black" }); }, - filterCard:function(card){ - return get.color(card)=='black'&&get.type(card,'trick')=='trick'; + filterCard: function (card) { + return get.color(card) == "black" && get.type(card, "trick") == "trick"; }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - discard:false, - delay:false, - check:function(card){ - return 8-get.value(card); + discard: false, + delay: false, + check: function (card) { + return 8 - get.value(card); }, - loseTo:'cardPile', - insert:true, - visible:true, - content:function(){ - 'step 0' + loseTo: "cardPile", + insert: true, + visible: true, + content: function () { + "step 0"; player.showCards(cards); - 'step 1' - target.chooseToDiscard('he',true).set('prompt','请弃置一张锦囊牌,或依次弃置两张非锦囊牌。'); - 'step 2' - if((!result.cards||get.type(result.cards[0],'trick',result.cards[0].original=='h'?target:false)!='trick')&&target.countCards('he',function(card){ - return get.type(card,'trick')!='trick'; - })){ - target.chooseToDiscard('he',true,function(card){ - return get.type(card,'trick')!='trick'; - }).set('prompt','请弃置第二张非锦囊牌'); + "step 1"; + target + .chooseToDiscard("he", true) + .set("prompt", "请弃置一张锦囊牌,或依次弃置两张非锦囊牌。"); + "step 2"; + if ( + (!result.cards || + get.type( + result.cards[0], + "trick", + result.cards[0].original == "h" ? target : false + ) != "trick") && + target.countCards("he", function (card) { + return get.type(card, "trick") != "trick"; + }) + ) { + target + .chooseToDiscard("he", true, function (card) { + return get.type(card, "trick") != "trick"; + }) + .set("prompt", "请弃置第二张非锦囊牌"); } }, - ai:{ - order:9, - result:{ - target:-1 - } - } - }, - qianju:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance-(from.getDamagedHp()); - } - } - }, - reqianju:{ - mod:{ - globalFrom:function(from,to,distance){ - return distance-(Math.max(1,from.getDamagedHp())); - } - } - }, - reqingxi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - return event.card.name=='sha'||event.card.name=='juedou'; + ai: { + order: 9, + result: { + target: -1, + }, }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + }, + qianju: { + mod: { + globalFrom: function (from, to, distance) { + return distance - from.getDamagedHp(); + }, }, - logTarget:'target', - content:function(){ - 'step 0' - var num=Math.min(game.countPlayer(function(current){ - return player.inRange(current); - }),player.getEquips(1).length?4:2); - if(trigger.target.countCards('h') 2) { + return 0; + } + return 8 - get.value(card); + } + }); } - else{ - trigger.target.chooseToDiscard(num,'弃置'+get.cnNumber(num)+'张手牌,或令'+get.translation(trigger.card)+'的伤害+1').set('ai',function(card){ - var player=_status.event.player; - if(player.hp==1){ - if(get.type(card)=='basic'){ - return 8-get.value(card); - } - else{ - return 10-get.value(card); - } - } - else{ - if(num>2){ - return 0; - } - return 8-get.value(card); - } - }); - } - 'step 1' - if(!event.directfalse&&result.bool){ - var e1=player.getEquips(1); - if(e1.length){ - player.discard(e1,'notBySelf'); + "step 1"; + if (!event.directfalse && result.bool) { + var e1 = player.getEquips(1); + if (e1.length) { + player.discard(e1, "notBySelf"); } event.finish(); - } - else{ - var id=trigger.target.playerid; - var map=trigger.customArgs; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + } else { + var id = trigger.target.playerid; + var map = trigger.customArgs; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; - player.judge(function(card){ - if(get.color(card)=='red') return 1; + player.judge(function (card) { + if (get.color(card) == "red") return 1; return 0; - }).judge2=function(result){ + }).judge2 = function (result) { return result.bool; }; } - 'step 2' - if(result.color=='red') trigger.directHit.add(trigger.target); - } + "step 2"; + if (result.color == "red") trigger.directHit.add(trigger.target); + }, }, - reqingxi2:{ - mod:{ - cardEnabled:function(card,player){ - if(player.storage.reqingxi2&&player.storage.reqingxi2.filter(function(cd){ - return get.color(cd)==get.color(card); - }).length) return false; + reqingxi2: { + mod: { + cardEnabled: function (card, player) { + if ( + player.storage.reqingxi2 && + player.storage.reqingxi2.filter(function (cd) { + return get.color(cd) == get.color(card); + }).length + ) + return false; }, - cardRespondable:function(card,player){ - if(player.storage.reqingxi2&&player.storage.reqingxi2.filter(function(cd){ - return get.color(cd)==get.color(card); - }).length) return false; + cardRespondable: function (card, player) { + if ( + player.storage.reqingxi2 && + player.storage.reqingxi2.filter(function (cd) { + return get.color(cd) == get.color(card); + }).length + ) + return false; }, }, - firstDo:true, - onremove:true, - trigger:{ - player:['damage','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded'], + firstDo: true, + onremove: true, + trigger: { + player: ["damage", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded"], }, - charlotte:true, - filter:function(event,player){ - return player.storage.reqingxi2&&event.card&&player.storage.reqingxi2.includes(event.card); + charlotte: true, + filter: function (event, player) { + return ( + player.storage.reqingxi2 && + event.card && + player.storage.reqingxi2.includes(event.card) + ); }, - silent:true, - forced:true, - popup:false, - priority:12, - content:function(){ + silent: true, + forced: true, + popup: false, + priority: 12, + content: function () { player.storage.reqingxi2.remove(trigger.card); - if(!player.storage.reqingxi2.length) player.removeSkill('reqingxi2'); + if (!player.storage.reqingxi2.length) player.removeSkill("reqingxi2"); }, }, - qingxi:{ - audio:2, - trigger:{source:'damageBegin1'}, - check:function(event,player){ - return get.attitude(player,event.player)<0; + qingxi: { + audio: 2, + trigger: { source: "damageBegin1" }, + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - filter:function(event,player){ - return event.getParent().name=='sha'&&player.getEquips(1).length>0; + filter: function (event, player) { + return event.getParent().name == "sha" && player.getEquips(1).length > 0; }, - content:function(){ - 'step 0' - var num=player.getEquipRange(); - if(trigger.player.countCards('h') 2) { + return 0; + } + return 8 - get.value(card); + } + }); } - else{ - trigger.player.chooseToDiscard(num,'弃置'+get.cnNumber(num)+'张手牌,或令杀的伤害+1').set('ai',function(card){ - var player=_status.event.player; - if(player.hp==1){ - if(get.type(card)=='basic'){ - return 8-get.value(card); - } - else{ - return 10-get.value(card); - } - } - else{ - if(num>2){ - return 0; - } - return 8-get.value(card); - } - }); - } - 'step 1' - if(!event.directfalse&&result.bool){ - var e1=player.getEquips(1); - if(e1.length){ - player.discard(e1,'notBySelf'); + "step 1"; + if (!event.directfalse && result.bool) { + var e1 = player.getEquips(1); + if (e1.length) { + player.discard(e1, "notBySelf"); } - } - else{ + } else { trigger.num++; } - } + }, }, - jieyue:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - 'step 0' + jieyue: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; player.chooseCardTarget({ - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - filterCard:lib.filter.cardDiscardable, - ai1:function(card){ - return 7-get.useful(card); + filterCard: lib.filter.cardDiscardable, + ai1: function (card) { + return 7 - get.useful(card); }, - ai2:function(target){ - return 1-get.attitude(_status.event.player,target); + ai2: function (target) { + return 1 - get.attitude(_status.event.player, target); }, - prompt:get.prompt2('jieyue') + prompt: get.prompt2("jieyue"), }); - 'step 1' - if(result.bool){ - player.logSkill('jieyue',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("jieyue", result.targets); player.discard(result.cards); - var target=result.targets[0]; - event.target=target; - target.chooseCard('将一张牌置于'+get.translation(player)+'的武将牌上,或令其弃置你的一张牌','he').set('ai',function(card){ - if(card.name=='du') return 20; - var player=_status.event.player; - if(get.attitude(player,_status.event.getParent().player)>0){ - return 8-get.value(card); - } - var nh=player.countCards('h'); - if(nh<=2){ - return 6-get.value(card); - } - if(nh<=3){ - return 2-get.value(card); - } - return 0; - }); - } - else{ + var target = result.targets[0]; + event.target = target; + target + .chooseCard( + "将一张牌置于" + get.translation(player) + "的武将牌上,或令其弃置你的一张牌", + "he" + ) + .set("ai", function (card) { + if (card.name == "du") return 20; + var player = _status.event.player; + if (get.attitude(player, _status.event.getParent().player) > 0) { + return 8 - get.value(card); + } + var nh = player.countCards("h"); + if (nh <= 2) { + return 6 - get.value(card); + } + if (nh <= 3) { + return 2 - get.value(card); + } + return 0; + }); + } else { event.finish(); } - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - player.addToExpansion(result.cards,'give',target).gaintag.add('jieyue'); - } - else if(event.target.countCards('he')){ - player.discardPlayerCard(event.target,true); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + player.addToExpansion(result.cards, "give", target).gaintag.add("jieyue"); + } else if (event.target.countCards("he")) { + player.discardPlayerCard(event.target, true); } }, - ai:{expose:0.1}, - marktext:'节', - intro:{ - content:'expansion', - markcount:'expansion', + ai: { expose: 0.1 }, + marktext: "节", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:['jieyue_wuxie','jieyue_shan','jieyue_gain'], - subSkill:{ - wuxie:{ - audio:true, - enable:'chooseToUse', - filterCard:function(card){ - return get.color(card)=='black'; + group: ["jieyue_wuxie", "jieyue_shan", "jieyue_gain"], + subSkill: { + wuxie: { + audio: true, + enable: "chooseToUse", + filterCard: function (card) { + return get.color(card) == "black"; }, - viewAsFilter:function(player){ - return player.getExpansions('jieyue').length&&player.countCards('hs',{color:'black'})>0; + viewAsFilter: function (player) { + return ( + player.getExpansions("jieyue").length && + player.countCards("hs", { color: "black" }) > 0 + ); }, - position:'hs', - viewAs:{name:'wuxie'}, - prompt:'将一张黑色手牌当无懈可击使用', - check:function(card){ - return 8-get.value(card); + position: "hs", + viewAs: { name: "wuxie" }, + prompt: "将一张黑色手牌当无懈可击使用", + check: function (card) { + return 8 - get.value(card); }, }, - shan:{ - audio:true, - enable:['chooseToRespond','chooseToUse'], - filterCard:function(card){ - return get.color(card)=='red'; + shan: { + audio: true, + enable: ["chooseToRespond", "chooseToUse"], + filterCard: function (card) { + return get.color(card) == "red"; }, - position:'hs', - viewAs:{name:'shan'}, - viewAsFilter:function(player){ - return player.getExpansions('jieyue').length&&player.countCards('hs',{color:'red'})>0; + position: "hs", + viewAs: { name: "shan" }, + viewAsFilter: function (player) { + return ( + player.getExpansions("jieyue").length && + player.countCards("hs", { color: "red" }) > 0 + ); }, - prompt:'将一张红色手牌当闪使用或打出', - check:()=>1, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(!player.getExpansions('jieyue').length||!player.countCards('hs',{color:'red'})) return false; + prompt: "将一张红色手牌当闪使用或打出", + check: () => 1, + ai: { + respondShan: true, + skillTagFilter: function (player) { + if ( + !player.getExpansions("jieyue").length || + !player.countCards("hs", { color: "red" }) + ) + return false; }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.8 + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.8; }, }, }, }, - gain:{ - audio:'jieyue', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getExpansions('jieyue').length; + gain: { + audio: "jieyue", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getExpansions("jieyue").length; }, - forced:true, - content:function(){ - var cards=player.getExpansions('jieyue'); - if(cards.length) player.gain(cards,'gain2'); + forced: true, + content: function () { + var cards = player.getExpansions("jieyue"); + if (cards.length) player.gain(cards, "gain2"); }, }, }, }, - jinjiu:{ - mod:{ - cardname:function(card,player){ - if(card.name=='jiu') return 'sha'; + jinjiu: { + mod: { + cardname: function (card, player) { + if (card.name == "jiu") return "sha"; }, }, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('h','jiu')) return false; + ai: { + skillTagFilter: function (player) { + if (!player.countCards("h", "jiu")) return false; }, - respondSha:true, + respondSha: true, }, - audio:2, - trigger:{player:['useCard1','respond']}, - firstDo:true, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.skill&& - event.cards.length==1&&event.cards[0].name=='jiu'; + audio: 2, + trigger: { player: ["useCard1", "respond"] }, + firstDo: true, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !event.skill && + event.cards.length == 1 && + event.cards[0].name == "jiu" + ); }, - content:function(){}, + content: function () {}, }, - xinxianzhen:{ - audio:'xianzhen', - inherit:'xianzhen', + xinxianzhen: { + audio: "xianzhen", + inherit: "xianzhen", }, - xinxianzhen2:{ - audio:'xianzhen', - audioname2:{ - ol_gaoshun:'rexianzhen', + xinxianzhen2: { + audio: "xianzhen", + audioname2: { + ol_gaoshun: "rexianzhen", }, - mod:{ - targetInRange:function(card,player,target){ - if(target==player.storage.xinxianzhen) return true; + mod: { + targetInRange: function (card, player, target) { + if (target == player.storage.xinxianzhen) return true; }, - cardUsableTarget:function(card,player,target){ - if(target==player.storage.xinxianzhen) return true; + cardUsableTarget: function (card, player, target) { + if (target == player.storage.xinxianzhen) return true; }, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(arg.target!=player.storage.xinxianzhen) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (arg.target != player.storage.xinxianzhen) return false; }, - effect:{ - player:function(card,player,target,current,isLink){ - if(isLink||!player.storage.xinxianzhen) return; - if(target!=player.storage.xinxianzhen&&['sha','guohe','shunshou','huogong','juedou'].includes(card.name)){ - if(get.effect(player.storage.xinxianzhen,card,player,player)>0){ - return [1,2]; + effect: { + player: function (card, player, target, current, isLink) { + if (isLink || !player.storage.xinxianzhen) return; + if ( + target != player.storage.xinxianzhen && + ["sha", "guohe", "shunshou", "huogong", "juedou"].includes(card.name) + ) { + if (get.effect(player.storage.xinxianzhen, card, player, player) > 0) { + return [1, 2]; } } - } - } + }, + }, }, - trigger:{player:'useCard2'}, - filter:function(event,player){ - return player.storage.xinxianzhen&&player.storage.xinxianzhen.isIn()&& - (event.card.name=='sha'||get.type(event.card)=='trick')&& - event.targets&&event.targets.length==1&&!event.targets.includes(player.storage.xinxianzhen); + trigger: { player: "useCard2" }, + filter: function (event, player) { + return ( + player.storage.xinxianzhen && + player.storage.xinxianzhen.isIn() && + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.targets && + event.targets.length == 1 && + !event.targets.includes(player.storage.xinxianzhen) + ); }, - check:function(event,player){ - return get.effect(player.storage.xinxianzhen,event.card,player,player)>0; + check: function (event, player) { + return get.effect(player.storage.xinxianzhen, event.card, player, player) > 0; }, - logTarget:function(event,player){ + logTarget: function (event, player) { return player.storage.xinxianzhen; }, - prompt2:(event,player)=>('令'+get.translation(player.storage.decadexianzhen2)+'也成为'+get.translation(event.card)+'的目标'), - content:function(){ - var target=player.storage.xinxianzhen; + prompt2: (event, player) => + "令" + + get.translation(player.storage.decadexianzhen2) + + "也成为" + + get.translation(event.card) + + "的目标", + content: function () { + var target = player.storage.xinxianzhen; trigger.targets.push(target); - game.log(target,'成为了',trigger.card,'的额外目标'); + game.log(target, "成为了", trigger.card, "的额外目标"); }, }, - xinxianzhen3:{ - charlotte:true, - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; + xinxianzhen3: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; }, - ignoredHandcard:function(card,player){ - if(get.name(card)=='sha'){ + ignoredHandcard: function (card, player) { + if (get.name(card) == "sha") { return true; } }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&get.name(card)=='sha'){ + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && get.name(card) == "sha") { return false; } }, }, }, - xianzhen:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + xianzhen: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(target); - "step 1" - if(result.bool){ - player.storage[event.name]=target; - player.addTempSkill(event.name+2); - } - else{ - player.addTempSkill(event.name+3); + "step 1"; + if (result.bool) { + player.storage[event.name] = target; + player.addTempSkill(event.name + 2); + } else { + player.addTempSkill(event.name + 3); } }, - ai:{ - order:function(name,player){ - var cards=player.getCards('h'); - if(player.countCards('h','sha')==0){ + ai: { + order: function (name, player) { + var cards = player.getCards("h"); + if (player.countCards("h", "sha") == 0) { return 1; } - for(var i=0;i11&&get.value(cards[i])<7){ + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].name != "sha" && + get.number(cards[i]) > 11 && + get.value(cards[i]) < 7 + ) { return 9; } } - return get.order({name:'sha'})-1; + return get.order({ name: "sha" }) - 1; }, - result:{ - player:function(player){ - if(player.countCards('h','sha')>0) return 0; - var num=player.countCards('h'); - if(num>player.hp) return 0; - if(num==1) return -2; - if(num==2) return -1; + result: { + player: function (player) { + if (player.countCards("h", "sha") > 0) return 0; + var num = player.countCards("h"); + if (num > player.hp) return 0; + if (num == 1) return -2; + if (num == 2) return -1; return -0.7; }, - target:function(player,target){ - var num=target.countCards('h'); - if(num==1) return -1; - if(num==2) return -0.7; - return -0.5 + target: function (player, target) { + var num = target.countCards("h"); + if (num == 1) return -1; + if (num == 2) return -0.7; + return -0.5; }, }, - threaten:1.3 - } + threaten: 1.3, + }, }, - xianzhen2:{ - charlotte:true, - mod:{ - targetInRange:function(card,player,target){ - if(target==player.storage.xianzhen) return true; + xianzhen2: { + charlotte: true, + mod: { + targetInRange: function (card, player, target) { + if (target == player.storage.xianzhen) return true; }, - cardUsableTarget:function(card,player,target){ - if(target==player.storage.xianzhen) return true; + cardUsableTarget: function (card, player, target) { + if (target == player.storage.xianzhen) return true; }, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(arg.target!=player.storage.xianzhen) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (arg.target != player.storage.xianzhen) return false; }, - } + }, }, - xianzhen3:{ - charlotte:true, - mod:{ - cardEnabled:function(card){if(card.name=='sha') return false} - } + xianzhen3: { + charlotte: true, + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, }, - lihuo:{ - trigger:{player:'useCard1'}, - filter:function(event,player){ - if(event.card.name=='sha'&&!game.hasNature(event.card)) return true; + lihuo: { + trigger: { player: "useCard1" }, + filter: function (event, player) { + if (event.card.name == "sha" && !game.hasNature(event.card)) return true; return false; }, - audio:2, - audioname:['re_chengpu'], - check:function(event,player){ + audio: 2, + audioname: ["re_chengpu"], + check: function (event, player) { return false; }, - content:function(){ - game.setNature(trigger.card,'fire'); - var next=game.createEvent('lihuo_clear'); - next.player=player; - next.card=trigger.card; + content: function () { + game.setNature(trigger.card, "fire"); + var next = game.createEvent("lihuo_clear"); + next.player = player; + next.card = trigger.card; event.next.remove(next); - next.forceDie=true; + next.forceDie = true; trigger.after.push(next); - next.setContent(function(){ - if(player.isIn()&&player.getHistory('sourceDamage',function(evt){ - return evt.getParent(2)==event.parent; - }).length>0) player.loseHp(); - game.setNature(card,[],true); + next.setContent(function () { + if ( + player.isIn() && + player.getHistory("sourceDamage", function (evt) { + return evt.getParent(2) == event.parent; + }).length > 0 + ) + player.loseHp(); + game.setNature(card, [], true); }); }, - group:'lihuo2' + group: "lihuo2", }, - lihuo2:{ - trigger:{player:'useCard2'}, - filter:function(event,player){ - if(event.card.name!='sha'||!game.hasNature(event.card,'fire')) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&player.canUse(event.card,current); + lihuo2: { + trigger: { player: "useCard2" }, + filter: function (event, player) { + if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; + return game.hasPlayer(function (current) { + return !event.targets.includes(current) && player.canUse(event.card, current); }); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('lihuo'),'为'+get.translation(trigger.card)+'增加一个目标',function(card,player,target){ - return !_status.event.sourcex.includes(target)&&player.canUse(_status.event.card,target); - }).set('sourcex',trigger.targets).set('card',trigger.card).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!_status.connectMode) game.delayx(); - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("lihuo"), + "为" + get.translation(trigger.card) + "增加一个目标", + function (card, player, target) { + return ( + !_status.event.sourcex.includes(target) && + player.canUse(_status.event.card, target) + ); + } + ) + .set("sourcex", trigger.targets) + .set("card", trigger.card) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }); + "step 1"; + if (result.bool) { + if (!event.isMine() && !_status.connectMode) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - player.logSkill('lihuo',event.target); + "step 2"; + player.logSkill("lihuo", event.target); trigger.targets.push(event.target); }, }, - lihuo3:{ - trigger:{player:'useCardAfter'}, - vanish:true, - filter:function(event,player){ - return event.card.name=='sha'; + lihuo3: { + trigger: { player: "useCardAfter" }, + vanish: true, + filter: function (event, player) { + return event.card.name == "sha"; }, - forced:true, - audio:false, - content:function(){ + forced: true, + audio: false, + content: function () { player.loseHp(); - player.removeSkill('lihuo3'); - } + player.removeSkill("lihuo3"); + }, }, - chunlao:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - audioname:['xin_chengpu'], - filter:function(event,player){ - return player.countCards('h')>0&&(_status.connectMode||player.countCards('h','sha')>0)&&!player.getExpansions('chunlao').length; + chunlao: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + audioname: ["xin_chengpu"], + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + (_status.connectMode || player.countCards("h", "sha") > 0) && + !player.getExpansions("chunlao").length + ); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - content:function(){ - 'step 0' - player.chooseCard([1,Math.max(1,player.countCards('h','sha'))],get.prompt('chunlao'),{name:'sha'}).set('ai',function(){ - return 1; - }); - 'step 1' - if(result.bool){ - player.logSkill('chunlao'); - player.addToExpansion(result.cards,player,'giveAuto').gaintag.add('chunlao'); + content: function () { + "step 0"; + player + .chooseCard([1, Math.max(1, player.countCards("h", "sha"))], get.prompt("chunlao"), { + name: "sha", + }) + .set("ai", function () { + return 1; + }); + "step 1"; + if (result.bool) { + player.logSkill("chunlao"); + player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("chunlao"); } }, - ai:{ - effect:{ - player:function(card,player,target){ - if(_status.currentPhase!=player) return; - if(card.name=='sha'&&!player.needsToDiscard()&&!player.getExpansions('chunlao').length&&target.hp>1){ - return 'zeroplayertarget'; + ai: { + effect: { + player: function (card, player, target) { + if (_status.currentPhase != player) return; + if ( + card.name == "sha" && + !player.needsToDiscard() && + !player.getExpansions("chunlao").length && + target.hp > 1 + ) { + return "zeroplayertarget"; } - } + }, }, - threaten:1.4 + threaten: 1.4, }, - group:'chunlao2' + group: "chunlao2", }, - chunlao2:{ - enable:'chooseToUse', - filter:function(event,player){ - return event.type=='dying'&&event.dying&&event.dying.hp<=0&&player.getExpansions('chunlao').length>0; + chunlao2: { + enable: "chooseToUse", + filter: function (event, player) { + return ( + event.type == "dying" && + event.dying && + event.dying.hp <= 0 && + player.getExpansions("chunlao").length > 0 + ); }, - filterTarget:function(card,player,target){ - return target==_status.event.dying; + filterTarget: function (card, player, target) { + return target == _status.event.dying; }, - direct:true, - clearTime:true, - delay:false, - selectTarget:-1, - content:function(){ - "step 0" - player.chooseCardButton(get.translation('chunlao'),player.getExpansions('chunlao'),true); - "step 1" - if(result.bool){ - player.logSkill('chunlao',target); + direct: true, + clearTime: true, + delay: false, + selectTarget: -1, + content: function () { + "step 0"; + player.chooseCardButton( + get.translation("chunlao"), + player.getExpansions("chunlao"), + true + ); + "step 1"; + if (result.bool) { + player.logSkill("chunlao", target); player.loseToDiscardpile(result.links); - event.type='dying'; - target.useCard({name:'jiu',isCard:true},target); + event.type = "dying"; + target.useCard({ name: "jiu", isCard: true }, target); } }, - ai:{ - order:6, - skillTagFilter:function(player){ - return player.getExpansions('chunlao').length>0; + ai: { + order: 6, + skillTagFilter: function (player) { + return player.getExpansions("chunlao").length > 0; }, - save:true, - result:{ - target:3 + save: true, + result: { + target: 3, }, - threaten:1.6 + threaten: 1.6, }, }, - chunlao2_old:{ - trigger:{global:'dying'}, + chunlao2_old: { + trigger: { global: "dying" }, //priority:6, - filter:function(event,player){ - return event.player.hp<=0&&player.storage.chunlao.length>0; + filter: function (event, player) { + return event.player.hp <= 0 && player.storage.chunlao.length > 0; }, - direct:true, - content:function(){ - "step 0" - var att=get.attitude(player,trigger.player); - player.chooseCardButton(get.prompt('chunlao',trigger.player),player.storage.chunlao).set('ai',function(button){ - if(_status.event.att>0) return 1; - return 0; - }).set('att',att); - "step 1" - if(result.bool){ - player.logSkill('chunlao',trigger.player); + direct: true, + content: function () { + "step 0"; + var att = get.attitude(player, trigger.player); + player + .chooseCardButton(get.prompt("chunlao", trigger.player), player.storage.chunlao) + .set("ai", function (button) { + if (_status.event.att > 0) return 1; + return 0; + }) + .set("att", att); + "step 1"; + if (result.bool) { + player.logSkill("chunlao", trigger.player); player.$throw(result.links); player.storage.chunlao.remove(result.links[0]); result.links[0].discard(); - player.syncStorage('chunlao'); - trigger.player.useCard({name:'jiu',isCard:true},trigger.player); - if(!player.storage.chunlao.length){ - player.unmarkSkill('chunlao'); - } - else{ - player.markSkill('chunlao'); + player.syncStorage("chunlao"); + trigger.player.useCard({ name: "jiu", isCard: true }, trigger.player); + if (!player.storage.chunlao.length) { + player.unmarkSkill("chunlao"); + } else { + player.markSkill("chunlao"); } } }, - ai:{ - expose:0.2 - } - }, - shenduan:{ - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + ai: { + expose: 0.2, }, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false) return; - var evt=event.getl(player); - for(var i=0;i 1 ? "中的一张牌" : "") + + "当做【兵粮寸断】对一名其他角色使用", + function (card, player, target) { + var cs = _status.event.cards; + for (var i = 0; i < cs.length; i++) { + if ( + player.canUse( + { name: "bingliang", cards: [cs[i]] }, + target, + false + ) + ) + return true; + } + return false; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "bingliang" }, player, player); + }) + .set("cards", cards); + } else { event.finish(); } - else{ - event.cards=cards; - } - 'step 1' - if(event.cards.length){ - player.chooseTarget(get.prompt('shenduan'),'将'+get.translation(event.cards)+(event.cards.length>1?'中的一张牌':'')+'当做【兵粮寸断】对一名其他角色使用',function(card,player,target){ - var cs=_status.event.cards; - for(var i=0;i 1 ? "中的一张牌" : "") + + "当做【兵粮寸断】对一名其他角色使用", + function (card, player, target) { + var cs = _status.event.cards; + for (var i = 0; i < cs.length; i++) { + if ( + player.canUse( + { name: "bingliang", cards: [cs[i]] }, + target, + false + ) + ) + return true; + } + return false; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "bingliang" }, player, player); + }) + .set("cards", cards); + } else { event.finish(); } - else{ - event.cards=cards; - } - 'step 1' - if(event.cards.length){ - player.chooseTarget(get.prompt('shenduan'),'将'+get.translation(event.cards)+(event.cards.length>1?'中的一张牌':'')+'当做【兵粮寸断】对一名其他角色使用',function(card,player,target){ - var cs=_status.event.cards; - for(var i=0;i0; }, - content:function(){ - 'step 0' - var att=get.attitude(player,trigger.player); - var nh=trigger.player.countCards('h'); - var eff=get.effect(trigger.player,{name:'sha',isCard:true},player,player); - if(player.inRange(trigger.player)||!player.canUse({name:'sha',isCard:true},trigger.player,false)) eff=0; - player.discardPlayerCard(get.prompt('yonglve',trigger.player),trigger.player,'j').set('ai',function(button){ - var name=button.link.viewAs||button.link.name; - var att=_status.event.att; - var nh=_status.event.nh; - var eff=_status.event.eff; - var trigger=_status.event.getTrigger(); - if(att>0&&eff>=0) return 1; - if(att>=0&&eff>0) return 1; - if(att>0&&(trigger.player.hp>=3||trigger.player.hasSkillTag('freeShan',false,{ - player:_status.event.player, - card:new lib.element.VCard({name:'sha',isCard:true}) - })||trigger.player.countCards('h','shan'))){ - if(name=='lebu'&&nh>trigger.player.hp) return 1; - if(name=='bingliang'&&nh 0; + }, + content: function () { + "step 0"; + var att = get.attitude(player, trigger.player); + var nh = trigger.player.countCards("h"); + var eff = get.effect(trigger.player, { name: "sha", isCard: true }, player, player); + if ( + player.inRange(trigger.player) || + !player.canUse({ name: "sha", isCard: true }, trigger.player, false) + ) + eff = 0; + player + .discardPlayerCard(get.prompt("yonglve", trigger.player), trigger.player, "j") + .set("ai", function (button) { + var name = button.link.viewAs || button.link.name; + var att = _status.event.att; + var nh = _status.event.nh; + var eff = _status.event.eff; + var trigger = _status.event.getTrigger(); + if (att > 0 && eff >= 0) return 1; + if (att >= 0 && eff > 0) return 1; + if ( + att > 0 && + (trigger.player.hp >= 3 || + trigger.player.hasSkillTag("freeShan", false, { + player: _status.event.player, + card: new lib.element.VCard({ name: "sha", isCard: true }), + }) || + trigger.player.countCards("h", "shan")) + ) { + if (name == "lebu" && nh > trigger.player.hp) return 1; + if (name == "bingliang" && nh < trigger.player.hp) return 1; + } + return 0; + }) + .set("att", att) + .set("nh", nh) + .set("eff", eff) + .set("logSkill", ["reyonglve", trigger.player]); + "step 1"; + if (result.bool) { + if ( + !player.inRange(trigger.player) && + player.canUse({ name: "sha", isCard: true }, trigger.player, false) + ) { + player.useCard({ name: "sha", isCard: true }, trigger.player); + } else player.draw(); } }, }, - yonglve:{ - trigger:{global:'phaseJudgeBegin'}, - direct:true, - audio:2, - filter:function(event,player){ - return event.player!=player&&event.player.countCards('j')>0&&player.inRange(event.player); + yonglve: { + trigger: { global: "phaseJudgeBegin" }, + direct: true, + audio: 2, + filter: function (event, player) { + return ( + event.player != player && + event.player.countCards("j") > 0 && + player.inRange(event.player) + ); }, - content:function(){ - 'step 0' - var att=get.attitude(player,trigger.player); - var nh=trigger.player.countCards('h'); - var eff=get.effect(trigger.player,{name:'sha',isCard:true},player,player); - if(!player.canUse({name:'sha',isCard:true},trigger.player)) eff=0; - player.discardPlayerCard(get.prompt('yonglve',trigger.player),trigger.player,'j').set('ai',function(button){ - var name=button.link.viewAs||button.link.name; - var att=_status.event.att; - var nh=_status.event.nh; - var eff=_status.event.eff; - var trigger=_status.event.getTrigger(); - if(att>0&&eff>=0) return 1; - if(att>=0&&eff>0) return 1; - if(att>0&&(trigger.player.hp>=3||trigger.player.hasSkillTag('freeShan',false,{ - player:_status.event.player, - card:new lib.element.VCard({name:'sha',isCard:true}) - })||trigger.player.countCards('h','shan'))){ - if(name=='lebu'&&nh>trigger.player.hp) return 1; - if(name=='bingliang'&&nh 0 && eff >= 0) return 1; + if (att >= 0 && eff > 0) return 1; + if ( + att > 0 && + (trigger.player.hp >= 3 || + trigger.player.hasSkillTag("freeShan", false, { + player: _status.event.player, + card: new lib.element.VCard({ name: "sha", isCard: true }), + }) || + trigger.player.countCards("h", "shan")) + ) { + if (name == "lebu" && nh > trigger.player.hp) return 1; + if (name == "bingliang" && nh < trigger.player.hp) return 1; + } + return 0; + }) + .set("att", att) + .set("nh", nh) + .set("eff", eff) + .set("logSkill", ["yonglve", trigger.player]); + "step 1"; + if (result.bool) { + if (player.canUse({ name: "sha", isCard: true }, trigger.player)) { + event.related = player.useCard({ name: "sha", isCard: true }, trigger.player); } - return 0; - }).set('att',att).set('nh',nh).set('eff',eff).set('logSkill',['yonglve',trigger.player]); - 'step 1' - if(result.bool){ - if(player.canUse({name:'sha',isCard:true},trigger.player)){ - event.related=player.useCard({name:'sha',isCard:true},trigger.player); - } - } - else{ + } else { event.finish(); } - 'step 2' - if(!event.related||!game.hasPlayer2(function(current){ - return current.getHistory('damage',function(evt){ - return evt.getParent(2)==event.related; - }).length>0; - })){ + "step 2"; + if ( + !event.related || + !game.hasPlayer2(function (current) { + return ( + current.getHistory("damage", function (evt) { + return evt.getParent(2) == event.related; + }).length > 0 + ); + }) + ) { player.draw(); } }, //group:'yonglve2' }, - yonglve2:{ - trigger:{source:'damage'}, - forced:true, - popup:false, - filter:function(event){ - return event.parent.skill=='yonglve'; + yonglve2: { + trigger: { source: "damage" }, + forced: true, + popup: false, + filter: function (event) { + return event.parent.skill == "yonglve"; + }, + content: function () { + player.storage.yonglve = true; }, - content:function(){ - player.storage.yonglve=true; - } }, - benxi:{ - audio:2, - trigger:{player:'useCard2'}, - forced:true, - filter:function(event,player){ + benxi: { + audio: 2, + trigger: { player: "useCard2" }, + forced: true, + filter: function (event, player) { return player.isPhaseUsing(); }, - content:function(){}, - mod:{ - globalFrom:function(from,to,distance){ - if(_status.currentPhase==from){ - return distance-from.countUsed(); + content: function () {}, + mod: { + globalFrom: function (from, to, distance) { + if (_status.currentPhase == from) { + return distance - from.countUsed(); } }, - selectTarget:function(card,player,range){ - if(_status.currentPhase==player){ - if(card.name=='sha'&&range[1]!=-1){ - if(!game.hasPlayer(function(current){ - return get.distance(player,current)>1; - })){ + selectTarget: function (card, player, range) { + if (_status.currentPhase == player) { + if (card.name == "sha" && range[1] != -1) { + if ( + !game.hasPlayer(function (current) { + return get.distance(player, current) > 1; + }) + ) { range[1]++; } } } - } + }, }, - ai:{ - unequip:true, - skillTagFilter:function(player){ - if(game.hasPlayer(function(current){ - return get.distance(player,current)>1; - })){ + ai: { + unequip: true, + skillTagFilter: function (player) { + if ( + game.hasPlayer(function (current) { + return get.distance(player, current) > 1; + }) + ) { return false; } - } - } + }, + }, }, - sidi:{ - audio:2, - trigger:{global:'useCard'}, - filter:function(event,player){ - if(event.card.name!='shan') return false; - if(event.player==player) return true; - return _status.currentPhase==player; + sidi: { + audio: 2, + trigger: { global: "useCard" }, + filter: function (event, player) { + if (event.card.name != "shan") return false; + if (event.player == player) return true; + return _status.currentPhase == player; }, - frequent:true, - intro:{ - content:'expansion', - markcount:'expansion', + frequent: true, + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - player.addToExpansion(get.cards(),'gain2').gaintag.add('sidi'); + content: function () { + player.addToExpansion(get.cards(), "gain2").gaintag.add("sidi"); }, - group:'sidi2' + group: "sidi2", }, - sidi2:{ - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - if(event.player==player||event.player.isDead()) return false; - if(!player.getExpansions('sidi').length) return false; + sidi2: { + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + if (event.player == player || event.player.isDead()) return false; + if (!player.getExpansions("sidi").length) return false; return true; }, - check:function(event,player){ - if(get.attitude(player,event.player)>=0) return false; - if(event.player.getEquip('zhuge')) return false; - if(event.player.hasSkill('paoxiao')) return false; - var players=game.filterPlayer(); - for(var i=0;i0) break; + check: function (event, player) { + if (get.attitude(player, event.player) >= 0) return false; + if (event.player.getEquip("zhuge")) return false; + if (event.player.hasSkill("paoxiao")) return false; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (event.player.canUse("sha", players[i]) && get.attitude(player, players[i]) > 0) + break; } - if(i==players.length) return false; - var nh=event.player.countCards('h'); - var nsha=event.player.countCards('h','sha'); - if(nh<2) return false; - switch(nh){ + if (i == players.length) return false; + var nh = event.player.countCards("h"); + var nsha = event.player.countCards("h", "sha"); + if (nh < 2) return false; + switch (nh) { case 2: - if(nsha) return Math.random()<0.4; - return Math.random()<0.2; + if (nsha) return Math.random() < 0.4; + return Math.random() < 0.2; case 3: - if(nsha) return Math.random()<0.8; - return Math.random()<0.3; + if (nsha) return Math.random() < 0.8; + return Math.random() < 0.3; case 4: - if(nsha>1) return true; - if(nsha) return Math.random()<0.9; - return Math.random()<0.5; - default:return true; + if (nsha > 1) return true; + if (nsha) return Math.random() < 0.9; + return Math.random() < 0.5; + default: + return true; } }, - logTarget:'player', - content:function(){ - 'step 0' - var cards=player.getExpansions('sidi'); - if(cards.length==1){ - event.directbutton=cards[0]; + logTarget: "player", + content: function () { + "step 0"; + var cards = player.getExpansions("sidi"); + if (cards.length == 1) { + event.directbutton = cards[0]; + } else { + player.chooseCardButton("弃置一张“司敌”牌", cards, true); } - else{ - player.chooseCardButton('弃置一张“司敌”牌',cards,true); - } - 'step 1' + "step 1"; var button; - if(event.directbutton){ - button=event.directbutton; + if (event.directbutton) { + button = event.directbutton; + } else if (result.bool && result.links && result.links.length) { + button = result.links[0]; } - else if(result.bool&&result.links&&result.links.length){ - button=result.links[0]; - } - if(button){ + if (button) { player.loseToDiscardpile(button); - trigger.player.addTempSkill('sidi3','phaseUseAfter'); - trigger.player.addMark('sidi3',1,false); - } - } - }, - sidi3:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num-player.countMark('sidi3'); + trigger.player.addTempSkill("sidi3", "phaseUseAfter"); + trigger.player.addMark("sidi3", 1, false); } }, - onremove:true, }, - zhongyong:{ - audio:2, - trigger:{player:'shaMiss'}, - direct:true, - filter:function(event,player){ - return event.responded&&get.itemtype(event.responded.cards)=='cards'; + sidi3: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num - player.countMark("sidi3"); + }, }, - content:function(){ - "step 0" - var cards=trigger.responded.cards; - event.cards=cards; - player.chooseTarget('忠勇:将'+get.translation(trigger.responded.cards)+'交给一名角色',function(card,player,target){ - return target!=_status.event.source; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countCards('h','shan')&&target.countCards('h')>=2){ - att/=1.5; - } - return att; - }).set('source',trigger.target); - "step 1" - if(result.bool){ - player.logSkill('zhongyong',result.targets); - result.targets[0].gain(event.cards,'gain2'); - if(result.targets[0]==player){ + onremove: true, + }, + zhongyong: { + audio: 2, + trigger: { player: "shaMiss" }, + direct: true, + filter: function (event, player) { + return event.responded && get.itemtype(event.responded.cards) == "cards"; + }, + content: function () { + "step 0"; + var cards = trigger.responded.cards; + event.cards = cards; + player + .chooseTarget( + "忠勇:将" + get.translation(trigger.responded.cards) + "交给一名角色", + function (card, player, target) { + return target != _status.event.source; + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.countCards("h", "shan") && target.countCards("h") >= 2) { + att /= 1.5; + } + return att; + }) + .set("source", trigger.target); + "step 1"; + if (result.bool) { + player.logSkill("zhongyong", result.targets); + result.targets[0].gain(event.cards, "gain2"); + if (result.targets[0] == player) { event.finish(); } - } - else{ + } else { event.finish(); } - "step 2" - player.chooseToUse('是否对'+get.translation(trigger.target)+'再使用一张杀?', - {name:'sha'},trigger.target,-1).set('addCount',false); - } - }, - xinzhongyong:{ - trigger:{player:'useCardAfter'}, - audio:'zhongyong', - direct:true, - filter:function(event,player){ - return event.card.name=='sha'; + "step 2"; + player + .chooseToUse( + "是否对" + get.translation(trigger.target) + "再使用一张杀?", + { name: "sha" }, + trigger.target, + -1 + ) + .set("addCount", false); }, - content:function(){ - "step 0" - event.sha=trigger.cards.slice(0).filterInD(); - event.shan=[]; - game.countPlayer2(function(current){ - current.getHistory('useCard',function(evt){ - if(evt.card.name=='shan'&&evt.getParent(3)==trigger) event.shan.addArray(evt.cards); + }, + xinzhongyong: { + trigger: { player: "useCardAfter" }, + audio: "zhongyong", + direct: true, + filter: function (event, player) { + return event.card.name == "sha"; + }, + content: function () { + "step 0"; + event.sha = trigger.cards.slice(0).filterInD(); + event.shan = []; + game.countPlayer2(function (current) { + current.getHistory("useCard", function (evt) { + if (evt.card.name == "shan" && evt.getParent(3) == trigger) + event.shan.addArray(evt.cards); }); }); - event.shan.filterInD('d'); - if(!event.sha.length&&!event.shan.length) event.finish(); - player.chooseTarget(get.prompt2('xinzhongyong'),function(card,player,target){ - return !_status.event.source.includes(target)&&target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('source',trigger.targets); - "step 1" - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xinzhongyong',target); - if(event.sha.length&&event.shan.length){ - player.chooseControl().set('choiceList',[ - '将'+get.translation(event.sha)+'交给'+get.translation(target), - '将'+get.translation(event.shan)+'交给'+get.translation(target), - ]).set('ai',function(){ - return _status.event.choice; - }).set('choice',function(){ - if(get.color(event.sha)!='black') return 0; - return 1; - }()); - } - else event._result={index:event.sha.length?0:1}; - } - else{ + event.shan.filterInD("d"); + if (!event.sha.length && !event.shan.length) event.finish(); + player + .chooseTarget(get.prompt2("xinzhongyong"), function (card, player, target) { + return !_status.event.source.includes(target) && target != player; + }) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("source", trigger.targets); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xinzhongyong", target); + if (event.sha.length && event.shan.length) { + player + .chooseControl() + .set("choiceList", [ + "将" + get.translation(event.sha) + "交给" + get.translation(target), + "将" + get.translation(event.shan) + "交给" + get.translation(target), + ]) + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + if (get.color(event.sha) != "black") return 0; + return 1; + })() + ); + } else event._result = { index: event.sha.length ? 0 : 1 }; + } else { event.finish(); } - "step 2" - var cards=result.index==0?event.sha:event.shan; - event.useSha=false; - target.gain(cards,'gain2'); - for(var i=0;i{ - game.addGlobalSkill('longyin_order'); + longyin: { + audio: 2, + shaRelated: true, + init: (player) => { + game.addGlobalSkill("longyin_order"); }, - onremove:(player)=>{ - if(!game.hasPlayer(current=>current.hasSkill('longyin'),true)) game.removeGlobalSkill('longyin_order'); + onremove: (player) => { + if (!game.hasPlayer((current) => current.hasSkill("longyin"), true)) + game.removeGlobalSkill("longyin_order"); }, - trigger:{global:'useCard'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.countCards('he')>0&&event.player.isPhaseUsing(); + trigger: { global: "useCard" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && player.countCards("he") > 0 && event.player.isPhaseUsing() + ); }, - content:function(){ - 'step 0' - var go=false; - if(get.attitude(player,trigger.player)>0){ - if(get.color(trigger.card)=='red'){ - go=true; - } - else if(trigger.addCount===false||!trigger.player.isPhaseUsing()) go=false; - else if(!trigger.player.hasSkill('paoxiao')&& - !trigger.player.hasSkill('tanlin3')&& - !trigger.player.hasSkill('zhaxiang2')&& - !trigger.player.hasSkill('fengnu')&& - !trigger.player.getEquip('zhuge')){ - var nh=trigger.player.countCards('h'); - if(player==trigger.player){ - go=(player.countCards('h','sha')>0); - } - else if(nh>=4){ - go=true; - } - else if(player.countCards('h','sha')){ - if(nh==3){ - go=Math.random()<0.8; + content: function () { + "step 0"; + var go = false; + if (get.attitude(player, trigger.player) > 0) { + if (get.color(trigger.card) == "red") { + go = true; + } else if (trigger.addCount === false || !trigger.player.isPhaseUsing()) go = false; + else if ( + !trigger.player.hasSkill("paoxiao") && + !trigger.player.hasSkill("tanlin3") && + !trigger.player.hasSkill("zhaxiang2") && + !trigger.player.hasSkill("fengnu") && + !trigger.player.getEquip("zhuge") + ) { + var nh = trigger.player.countCards("h"); + if (player == trigger.player) { + go = player.countCards("h", "sha") > 0; + } else if (nh >= 4) { + go = true; + } else if (player.countCards("h", "sha")) { + if (nh == 3) { + go = Math.random() < 0.8; + } else if (nh == 2) { + go = Math.random() < 0.5; } - else if(nh==2){ - go=Math.random()<0.5; - } - } - else if(nh>=3){ - if(nh==3){ - go=Math.random()<0.5; - } - else if(nh==2){ - go=Math.random()<0.2; + } else if (nh >= 3) { + if (nh == 3) { + go = Math.random() < 0.5; + } else if (nh == 2) { + go = Math.random() < 0.2; } } } } //AI停顿 - if(go&&!event.isMine()&&!event.isOnline()&&player.hasCard(function(card){ - return get.value(card)<6&&lib.filter.cardDiscardable(card,player,event.name); - },'he')){ + if ( + go && + !event.isMine() && + !event.isOnline() && + player.hasCard(function (card) { + return ( + get.value(card) < 6 && lib.filter.cardDiscardable(card, player, event.name) + ); + }, "he") + ) { game.delayx(); } - var next=player.chooseToDiscard(get.prompt('longyin'),'弃置一张牌'+(get.color(trigger.card)=='red'?'并摸一张牌':'')+',令'+get.translation(trigger.player)+'本次使用的【杀】不计入使用次数','he'); - next.logSkill=['longyin',trigger.player]; - next.set('ai',function(card){ - if(_status.event.go){ - return 6-get.value(card); + var next = player.chooseToDiscard( + get.prompt("longyin"), + "弃置一张牌" + + (get.color(trigger.card) == "red" ? "并摸一张牌" : "") + + ",令" + + get.translation(trigger.player) + + "本次使用的【杀】不计入使用次数", + "he" + ); + next.logSkill = ["longyin", trigger.player]; + next.set("ai", function (card) { + if (_status.event.go) { + return 6 - get.value(card); } return 0; }); - next.set('go',go); - 'step 1' - if(result.bool){ - if(trigger.addCount!==false){ - trigger.addCount=false; + next.set("go", go); + "step 1"; + if (result.bool) { + if (trigger.addCount !== false) { + trigger.addCount = false; trigger.player.getStat().card.sha--; } - if(get.color(trigger.card)=='red'){ + if (get.color(trigger.card) == "red") { player.draw(); } // player.logSkill('longyin',trigger.player); } }, - ai:{ - expose:0.2 + ai: { + expose: 0.2, }, - subSkill:{ - order:{ - mod:{ - aiOrder:(player,card,num)=>{ - if(num&&card.name==='sha'&&get.color(card)==='red'){ - let gp=game.findPlayer(current=>{ - return current.hasSkill('longyin')&¤t.hasCard(i=>true,'he'); + subSkill: { + order: { + mod: { + aiOrder: (player, card, num) => { + if (num && card.name === "sha" && get.color(card) === "red") { + let gp = game.findPlayer((current) => { + return ( + current.hasSkill("longyin") && current.hasCard((i) => true, "he") + ); }); - if(gp) return num+0.15*Math.sign(get.attitude(player,gp)); + if (gp) return num + 0.15 * Math.sign(get.attitude(player, gp)); } - } + }, }, - trigger:{player:'dieAfter'}, - filter:(event,player)=>{ - return !game.hasPlayer(current=>current.hasSkill('longyin'),true); + trigger: { player: "dieAfter" }, + filter: (event, player) => { + return !game.hasPlayer((current) => current.hasSkill("longyin"), true); }, - silent:true, - forceDie:true, - charlotte:true, - content:()=>{ - game.removeGlobalSkill('longyin_order'); - } - } - } + silent: true, + forceDie: true, + charlotte: true, + content: () => { + game.removeGlobalSkill("longyin_order"); + }, + }, + }, }, - jigong:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - check:function(event,player){ - var nh=player.countCards('h')-player.countCards('h',{type:'equip'}); - if(nh<=1) return true; - if(player.countCards('h','tao')) return false; - if(nh<=2) return Math.random()<0.7; - if(nh<=3) return Math.random()<0.4; + jigong: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + check: function (event, player) { + var nh = player.countCards("h") - player.countCards("h", { type: "equip" }); + if (nh <= 1) return true; + if (player.countCards("h", "tao")) return false; + if (nh <= 2) return Math.random() < 0.7; + if (nh <= 3) return Math.random() < 0.4; return false; }, - content:function(){ + content: function () { player.draw(2); - player.addTempSkill('jigong2'); - } + player.addTempSkill("jigong2"); + }, }, - jigong2:{ - mod:{ - maxHandcardBase:function(player,num){ - var damage=player.getStat().damage; - if(typeof damage=='number') return damage; + jigong2: { + mod: { + maxHandcardBase: function (player, num) { + var damage = player.getStat().damage; + if (typeof damage == "number") return damage; return 0; - } - } + }, + }, }, - shifei:{ - audio:2, - audioname:['re_guotufengji'], - enable:['chooseToRespond','chooseToUse'], - filter:function(event,player){ - if(!_status.currentPhase||event.shifei) return false; - if(!event.filterCard({name:'shan',isCard:true},player,event)) return false; - if(event.name!='chooseToUse'&&!lib.filter.cardRespondable({name:'shan',isCard:true},player,event)) return false; + shifei: { + audio: 2, + audioname: ["re_guotufengji"], + enable: ["chooseToRespond", "chooseToUse"], + filter: function (event, player) { + if (!_status.currentPhase || event.shifei) return false; + if (!event.filterCard({ name: "shan", isCard: true }, player, event)) return false; + if ( + event.name != "chooseToUse" && + !lib.filter.cardRespondable({ name: "shan", isCard: true }, player, event) + ) + return false; return true; }, - delay:false, - checkx:function(player){ - if(get.attitude(player,_status.currentPhase)>0) return true; - var nh=_status.currentPhase.countCards('h')+1; - var players=game.filterPlayer(); - for(var i=0;i=nh){ - if(!player.countCards('h','shan')||get.attitude(player,players[i])<=0) return true; + delay: false, + checkx: function (player) { + if (get.attitude(player, _status.currentPhase) > 0) return true; + var nh = _status.currentPhase.countCards("h") + 1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].countCards("h") >= nh) { + if (!player.countCards("h", "shan") || get.attitude(player, players[i]) <= 0) + return true; } } return false; }, - content:function(){ - 'step 0' - player.line(_status.currentPhase,'green'); + content: function () { + "step 0"; + player.line(_status.currentPhase, "green"); _status.currentPhase.draw(); - 'step 1' - if(_status.currentPhase.isMaxHandcard(true)){ + "step 1"; + if (_status.currentPhase.isMaxHandcard(true)) { event.finish(); - var evt=event.getParent(2); - evt.set('shifei',true); + var evt = event.getParent(2); + evt.set("shifei", true); evt.goto(0); return; } - var targets=game.filterPlayer(function(current){ + var targets = game.filterPlayer(function (current) { return current.isMaxHandcard(); - }) - if(targets.length==1){ - event.onlytarget=targets[0]; - } - else if(targets.length){ - player.chooseTarget('选择一名角色弃置其一张牌',true,function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }).set('targets',targets); - } - else{ + }); + if (targets.length == 1) { + event.onlytarget = targets[0]; + } else if (targets.length) { + player + .chooseTarget("选择一名角色弃置其一张牌", true, function (card, player, target) { + return _status.event.targets.includes(target); + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }) + .set("targets", targets); + } else { event.finish(); } - 'step 2' - var evt=event.getParent(2); + "step 2"; + var evt = event.getParent(2); var target; - if(event.onlytarget){ - target=event.onlytarget; + if (event.onlytarget) { + target = event.onlytarget; + } else if (result.targets && result.targets.length) { + target = result.targets[0]; } - else if(result.targets&&result.targets.length){ - target=result.targets[0]; - } - if(target){ - player.line(target,'green'); - player.discardPlayerCard(target,'he',true); - evt.result={bool:true,card:{name:'shan',isCard:true},cards:[]}; + if (target) { + player.line(target, "green"); + player.discardPlayerCard(target, "he", true); + evt.result = { bool: true, card: { name: "shan", isCard: true }, cards: [] }; evt.redo(); - } - else{ - evt.set('shifei',true); + } else { + evt.set("shifei", true); evt.goto(0); } }, - ai:{ - respondShan:true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0){ - var nh=player.countCards('h'); - var players=game.filterPlayer(); - for(var i=0;inh) return 0.4; + ai: { + respondShan: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) { + var nh = player.countCards("h"); + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i].countCards("h") > nh) return 0.4; } } - } - }, - order:8, - result:{ - player:function(player){ - return lib.skill.shifei.checkx(player)?1:0; }, }, - } - }, - huaiyi:{ - audio:2, - enable:'phaseUse', - usable:1, - delay:false, - filter:function(event,player){ - return player.countCards('h',{color:'red'})&&player.countCards('h',{color:'black'}); + order: 8, + result: { + player: function (player) { + return lib.skill.shifei.checkx(player) ? 1 : 0; + }, + }, }, - content:function(){ - 'step 0' + }, + huaiyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + delay: false, + filter: function (event, player) { + return ( + player.countCards("h", { color: "red" }) && player.countCards("h", { color: "black" }) + ); + }, + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - player.chooseControl('红色','黑色').set('ai',function(){ - var player=_status.event.player; - if(player.countCards('h',{color:'red'})==1&& - player.countCards('h',{color:'black'})>1) return '红色'; - return '黑色'; + "step 1"; + player.chooseControl("红色", "黑色").set("ai", function () { + var player = _status.event.player; + if ( + player.countCards("h", { color: "red" }) == 1 && + player.countCards("h", { color: "black" }) > 1 + ) + return "红色"; + return "黑色"; }); - 'step 2' - event.control=result.control; + "step 2"; + event.control = result.control; var cards; - if(event.control=='红色'){ - cards=player.getCards('h',{color:'red'}); - } - else{ - cards=player.getCards('h',{color:'black'}); + if (event.control == "红色") { + cards = player.getCards("h", { color: "red" }); + } else { + cards = player.getCards("h", { color: "black" }); } player.discard(cards); - event.num=cards.length; - 'step 3' - player.chooseTarget('请选择至多'+get.cnNumber(event.num)+'名有牌的其他角色,获得这些角色的各一张牌。',[1,event.num],function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)+0.5; - }); - 'step 4' - if(result.bool&&result.targets){ - player.line(result.targets,'green'); - event.targets=result.targets; + event.num = cards.length; + "step 3"; + player + .chooseTarget( + "请选择至多" + + get.cnNumber(event.num) + + "名有牌的其他角色,获得这些角色的各一张牌。", + [1, event.num], + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) + 0.5; + }); + "step 4"; + if (result.bool && result.targets) { + player.line(result.targets, "green"); + event.targets = result.targets; event.targets.sort(lib.sort.seat); - event.gained=0; - } - else{ + event.gained = 0; + } else { event.finish(); } - 'step 5' - if(player.isIn()&&event.targets.length){ - player.gainPlayerCard(event.targets.shift(),'he',true); + "step 5"; + if (player.isIn() && event.targets.length) { + player.gainPlayerCard(event.targets.shift(), "he", true); + } else event.finish(); + "step 6"; + if (result.bool) { + event.gained += result.cards.length; } - else event.finish(); - 'step 6' - if(result.bool){ - event.gained+=result.cards.length; - } - if(event.targets.length) event.goto(5); - 'step 7' - if(event.gained>1) player.loseHp(); + if (event.targets.length) event.goto(5); + "step 7"; + if (event.gained > 1) player.loseHp(); }, - ai:{ - order:function(item,player){ - if(player.countCards('h',{color:'red'})==1) return 10; - if(player.countCards('h',{color:'black'})==1) return 10; + ai: { + order: function (item, player) { + if (player.countCards("h", { color: "red" }) == 1) return 10; + if (player.countCards("h", { color: "black" }) == 1) return 10; return 1; }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, - yaoming:{ - audio:2, - trigger:{player:'damageEnd',source:'damageSource'}, - direct:true, - filter:function(event,player){ - if(player.hasSkill('yaoming2')) return false; - var nh=player.countCards('h'); - return game.hasPlayer(function(current){ - return current.countCards('h')!=nh; + yaoming: { + audio: 2, + trigger: { player: "damageEnd", source: "damageSource" }, + direct: true, + filter: function (event, player) { + if (player.hasSkill("yaoming2")) return false; + var nh = player.countCards("h"); + return game.hasPlayer(function (current) { + return current.countCards("h") != nh; }); }, - content:function(){ - 'step 0' - var nh=player.countCards('h'); - player.chooseTarget(get.prompt2('yaoming'),function(card,player,target){ - return _status.event.nh!=target.countCards('h'); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.countCards('h')>_status.event.nh) return -att; - return att; - }).set('nh',nh); - 'step 1' - if(result.bool){ - player.logSkill('yaoming',result.targets); - player.addTempSkill('yaoming2'); - var target=result.targets[0]; - if(target.countCards('h') _status.event.nh) return -att; + return att; + }) + .set("nh", nh); + "step 1"; + if (result.bool) { + player.logSkill("yaoming", result.targets); + player.addTempSkill("yaoming2"); + var target = result.targets[0]; + if (target.countCards("h") < player.countCards("h")) { target.draw(); - } - else{ - target.discard(target.getCards('h').randomGet()); + } else { + target.discard(target.getCards("h").randomGet()); } } }, - ai:{ - expose:0.2 - } - }, - yaoming2:{}, - anguo:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('e')>0; + ai: { + expose: 0.2, }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'e',true); - 'step 1' - if(result.links){ - var num=0,players=game.filterPlayer(); - for(var i=0;i 0; + }, + content: function () { + "step 0"; + player.choosePlayerCard(target, "e", true); + "step 1"; + if (result.links) { + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (target.inRange(players[i])) { num++; } } - event.num=num; - target.gain(result.links,'gain2'); - } - else{ + event.num = num; + target.gain(result.links, "gain2"); + } else { event.finish(); } - 'step 2' - var num2=0,players=game.filterPlayer(); - for(var i=0;inum2){ + if (event.num > num2) { player.draw(); } }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(target.hasSkillTag('noe')) return 1; - if(target.getEquip(1)||target.getEquip(4)) return -1; - if(target.getEquip(2)) return -0.7; + ai: { + order: 7, + result: { + target: function (player, target) { + if (target.hasSkillTag("noe")) return 1; + if (target.getEquip(1) || target.getEquip(4)) return -1; + if (target.getEquip(2)) return -0.7; return -0.5; - } - } - } + }, + }, + }, }, - reyanzhu:{ - enable:'phaseUse', - audio:2, - usable:1, - filterTarget:lib.filter.notMe, - derivation:['reyanzhu_rewrite','rexingxue_rewrite'], - prompt:function(){ - return lib.translate[(_status.event.player.storage.reyanzhu?'reyanzhu_rewrite':'reyanzhu')+'_info']; + reyanzhu: { + enable: "phaseUse", + audio: 2, + usable: 1, + filterTarget: lib.filter.notMe, + derivation: ["reyanzhu_rewrite", "rexingxue_rewrite"], + prompt: function () { + return lib.translate[ + (_status.event.player.storage.reyanzhu ? "reyanzhu_rewrite" : "reyanzhu") + "_info" + ]; }, - content:function(){ - 'step 0' - if(player.storage.reyanzhu||!target.countCards('e')) event._result={index:1}; - else target.chooseControl().set('prompt',get.translation(player)+'发动了【宴诛】,请选择一项').set('choiceList',[ - '将装备区内的所有牌交给'+get.translation(player)+'并令其修改技能', - '弃置一张牌,并令下次受到的伤害+1直到下回合开始', - ]).set('ai',function(){ - if(_status.event.player.countCards('e')>=3) return 1; - return 0; - }); - 'step 1' - if(result.index==0){ - target.give(target.getCards('e'),player); - player.storage.reyanzhu=true; - } - else{ - target.addTempSkill('reyanzhu2',{player:'phaseBegin'}); - target.addMark('reyanzhu2',1,false); - if(!player.storage.reyanzhu&&target.countCards('he')>0) target.chooseToDiscard('he',true); + content: function () { + "step 0"; + if (player.storage.reyanzhu || !target.countCards("e")) event._result = { index: 1 }; + else + target + .chooseControl() + .set("prompt", get.translation(player) + "发动了【宴诛】,请选择一项") + .set("choiceList", [ + "将装备区内的所有牌交给" + get.translation(player) + "并令其修改技能", + "弃置一张牌,并令下次受到的伤害+1直到下回合开始", + ]) + .set("ai", function () { + if (_status.event.player.countCards("e") >= 3) return 1; + return 0; + }); + "step 1"; + if (result.index == 0) { + target.give(target.getCards("e"), player); + player.storage.reyanzhu = true; + } else { + target.addTempSkill("reyanzhu2", { player: "phaseBegin" }); + target.addMark("reyanzhu2", 1, false); + if (!player.storage.reyanzhu && target.countCards("he") > 0) + target.chooseToDiscard("he", true); } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - if(player.storage.reyanzhu) return -1; - var ne=target.countCards('e'); - if(!ne) return -2; - if(ne>=2) return -ne; + ai: { + order: 6, + result: { + target: function (player, target) { + if (player.storage.reyanzhu) return -1; + var ne = target.countCards("e"); + if (!ne) return -2; + if (ne >= 2) return -ne; return 0; - } - } + }, + }, }, }, - reyanzhu2:{ - trigger:{player:'damageBegin3'}, - forced:true, - onremove:true, - content:function(){ - trigger.num+=player.countMark('reyanzhu2'); - game.log(player,'受到的伤害+'+player.countMark('reyanzhu2')); - player.removeSkill('reyanzhu2'); + reyanzhu2: { + trigger: { player: "damageBegin3" }, + forced: true, + onremove: true, + content: function () { + trigger.num += player.countMark("reyanzhu2"); + game.log(player, "受到的伤害+" + player.countMark("reyanzhu2")); + player.removeSkill("reyanzhu2"); }, - intro:{ - content:'下次受到的伤害+#直到下回合开始', + intro: { + content: "下次受到的伤害+#直到下回合开始", }, }, - rexingxue:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - filter:function(event,player){ - return (player.storage.reyanzhu?player.maxHp:player.hp)>0; + rexingxue: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + filter: function (event, player) { + return (player.storage.reyanzhu ? player.maxHp : player.hp) > 0; }, - content:function(){ - 'step 0' - player.chooseTarget([1,player.storage.reyanzhu?player.maxHp:player.hp],get.prompt('rexingxue'),'令所有目标角色依次摸一张牌,然后所有手牌数大于体力值的目标角色依次将一张牌置于牌堆顶').set('ai',function(target){ - var att=get.attitude(player,target); - if(target.countCards('h')==target.hp-1) att*=2; - return att; - }); - 'step 1' - if(result.bool){ - event.targets=result.targets.sortBySeat(); - player.logSkill('rexingxue',event.targets); + content: function () { + "step 0"; + player + .chooseTarget( + [1, player.storage.reyanzhu ? player.maxHp : player.hp], + get.prompt("rexingxue"), + "令所有目标角色依次摸一张牌,然后所有手牌数大于体力值的目标角色依次将一张牌置于牌堆顶" + ) + .set("ai", function (target) { + var att = get.attitude(player, target); + if (target.countCards("h") == target.hp - 1) att *= 2; + return att; + }); + "step 1"; + if (result.bool) { + event.targets = result.targets.sortBySeat(); + player.logSkill("rexingxue", event.targets); game.asyncDraw(result.targets); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; game.delay(); - 'step 3' - if(event.targets.length){ - event.target=event.targets.shift(); - if(event.target.isDead()) event.redo(); - } - else event.finish(); - 'step 4' - if(target.isIn()&&target.countCards('h')&&target.countCards('h')>target.hp) target.chooseCard('he',true,'将一张牌置于牌堆顶'); + "step 3"; + if (event.targets.length) { + event.target = event.targets.shift(); + if (event.target.isDead()) event.redo(); + } else event.finish(); + "step 4"; + if (target.isIn() && target.countCards("h") && target.countCards("h") > target.hp) + target.chooseCard("he", true, "将一张牌置于牌堆顶"); else event.goto(3); - 'step 5' - if(result&&result.cards){ - event.card=result.cards[0]; - target.lose(result.cards,ui.cardPile,'insert'); - game.log(target,'将',(get.position(event.card)=='h'?'一张牌':event.card),'置于牌堆顶'); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },target); + "step 5"; + if (result && result.cards) { + event.card = result.cards[0]; + target.lose(result.cards, ui.cardPile, "insert"); + game.log( + target, + "将", + get.position(event.card) == "h" ? "一张牌" : event.card, + "置于牌堆顶" + ); + game.broadcastAll(function (player) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + player.$throw(cardx, 1000, "nobroadcast"); + }, target); } event.goto(3); }, }, - rezhaofu:{ - unique:true, - global:'rezhaofu2', - zhuSkill:true + rezhaofu: { + unique: true, + global: "rezhaofu2", + zhuSkill: true, }, - rezhaofu2:{ - mod:{ - inRangeOf:function(from,to){ - if(from.group!='wu') return; - var players=game.filterPlayer(); - for(var i=0;i0&&target!=player; + yanzhu: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.countCards("he") > 0 && target != player; }, - content:function(){ - 'step 0' - if(target.countCards('e')){ - target.chooseBool('是否将装备区内的所有牌交给'+get.translation(player)+'?').set('ai',function(){ - if(_status.event.player.countCards('e')>=3) return false; - return true; - }); - } - else{ - target.chooseToDiscard(true,'he'); + content: function () { + "step 0"; + if (target.countCards("e")) { + target + .chooseBool("是否将装备区内的所有牌交给" + get.translation(player) + "?") + .set("ai", function () { + if (_status.event.player.countCards("e") >= 3) return false; + return true; + }); + } else { + target.chooseToDiscard(true, "he"); event.finish(); } - 'step 1' - if(result.bool){ - var es=target.getCards('e'); - target.give(es,player,'give'); - player.removeSkills('yanzhu'); - } - else{ - target.chooseToDiscard(true,'he'); + "step 1"; + if (result.bool) { + var es = target.getCards("e"); + target.give(es, player, "give"); + player.removeSkills("yanzhu"); + } else { + target.chooseToDiscard(true, "he"); } }, - ai:{ - order:6, - result:{ - target:function(player,target){ - var ne=target.countCards('e'); - if(!ne) return -2; - if(ne>=2) return -ne; + ai: { + order: 6, + result: { + target: function (player, target) { + var ne = target.countCards("e"); + if (!ne) return -2; + if (ne >= 2) return -ne; return 0; - } - } - } - }, - shizhi:{ - mod:{ - cardname:function(card,player,name){ - if(card.name=='shan'&&player.hp==1) return 'sha'; + }, }, }, - ai:{ - skillTagFilter:function(player){ - if(!player.countCards('h','shan')) return false; - if(player.hp!=1) return false; - }, - respondSha:true, - }, - audio:2, - audioname:['xin_zhangyi'], - trigger:{player:['useCard1','respond']}, - firstDo:true, - forced:true, - filter:function(event,player){ - return event.card.name=='sha'&&!event.skill&& - event.cards.length==1&&event.cards[0].name=='shan'; - }, - content:function(){}, }, - wurong:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + shizhi: { + mod: { + cardname: function (card, player, name) { + if (card.name == "shan" && player.hp == 1) return "sha"; + }, }, - filterTarget:function(card,player,target){ - return target.countCards('h')>0&&target!=player; + ai: { + skillTagFilter: function (player) { + if (!player.countCards("h", "shan")) return false; + if (player.hp != 1) return false; + }, + respondSha: true, }, - content:function(){ - "step 0" - if(target.countCards('h')==0||player.countCards('h')==0){ + audio: 2, + audioname: ["xin_zhangyi"], + trigger: { player: ["useCard1", "respond"] }, + firstDo: true, + forced: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + !event.skill && + event.cards.length == 1 && + event.cards[0].name == "shan" + ); + }, + content: function () {}, + }, + wurong: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0 && target != player; + }, + content: function () { + "step 0"; + if (target.countCards("h") == 0 || player.countCards("h") == 0) { event.finish(); return; } - "step 1" - var sendback=function(){ - if(_status.event!=event){ - return function(){ - event.resultOL=_status.event.resultOL; + "step 1"; + var sendback = function () { + if (_status.event != event) { + return function () { + event.resultOL = _status.event.resultOL; }; } }; - if(player.isOnline()){ + if (player.isOnline()) { player.wait(sendback); - event.ol=true; - player.send(function(){ - game.me.chooseCard(true).set('glow_result',true).ai=function(){ + event.ol = true; + player.send(function () { + game.me.chooseCard(true).set("glow_result", true).ai = function () { return Math.random(); }; game.resume(); }); - } - else{ - event.localPlayer=true; - player.chooseCard(true).set('glow_result',true).ai=function(){ + } else { + event.localPlayer = true; + player.chooseCard(true).set("glow_result", true).ai = function () { return Math.random(); }; } - if(target.isOnline()){ + if (target.isOnline()) { target.wait(sendback); - event.ol=true; - target.send(function(){ - var rand=Math.random()<0.4; - game.me.chooseCard(true).set('glow_result',true).ai=function(card){ - if(rand) return card.name=='shan'?1:0; - return card.name=='shan'?0:1; + event.ol = true; + target.send(function () { + var rand = Math.random() < 0.4; + game.me.chooseCard(true).set("glow_result", true).ai = function (card) { + if (rand) return card.name == "shan" ? 1 : 0; + return card.name == "shan" ? 0 : 1; }; game.resume(); }); + } else { + event.localTarget = true; } - else{ - event.localTarget=true; + "step 2"; + if (event.localPlayer) { + event.card1 = result.cards[0]; } - "step 2" - if(event.localPlayer){ - event.card1=result.cards[0]; - } - if(event.localTarget){ - var rand=Math.random()<0.4; - target.chooseCard(true).set('glow_result',true).ai=function(card){ - if(rand) return card.name=='shan'?1:0; - return card.name=='shan'?0:1; + if (event.localTarget) { + var rand = Math.random() < 0.4; + target.chooseCard(true).set("glow_result", true).ai = function (card) { + if (rand) return card.name == "shan" ? 1 : 0; + return card.name == "shan" ? 0 : 1; }; } - "step 3" - if(event.localTarget){ - event.card2=result.cards[0]; + "step 3"; + if (event.localTarget) { + event.card2 = result.cards[0]; } - if(!event.resultOL&&event.ol){ + if (!event.resultOL && event.ol) { game.pause(); } - "step 4" - try{ - if(!event.card1) event.card1=event.resultOL[player.playerid].cards[0]; - if(!event.card2) event.card2=event.resultOL[target.playerid].cards[0]; - if(!event.card1||!event.card2){ - throw('err'); + "step 4"; + try { + if (!event.card1) event.card1 = event.resultOL[player.playerid].cards[0]; + if (!event.card2) event.card2 = event.resultOL[target.playerid].cards[0]; + if (!event.card1 || !event.card2) { + throw "err"; } - } - catch(e){ + } catch (e) { console.log(e); event.finish(); return; } - game.broadcastAll(function(card1,card2){ - card1.classList.remove('glow'); - card2.classList.remove('glow'); - },event.card1,event.card2); - "step 5" - game.broadcastAll(function(){ - ui.arena.classList.add('thrownhighlight'); + game.broadcastAll( + function (card1, card2) { + card1.classList.remove("glow"); + card2.classList.remove("glow"); + }, + event.card1, + event.card2 + ); + "step 5"; + game.broadcastAll(function () { + ui.arena.classList.add("thrownhighlight"); }); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1,target,event.card2); + game.addVideo("thrownhighlight1"); + player.$compare(event.card1, target, event.card2); game.delay(4); - "step 6" - var next=game.createEvent('showCards'); - next.player=player; - next.cards=[event.card1]; - next.setContent('emptyEvent'); - game.log(player,'展示了',event.card1); - "step 7" - var next=game.createEvent('showCards'); - next.player=target; - next.cards=[event.card2]; - next.setContent('emptyEvent'); - game.log(target,'展示了',event.card2); - "step 8" - var name1=get.name(event.card1); - var name2=get.name(event.card2); - if(name1=='sha'&&name2!='shan'){ - player.discard(event.card1).set('animate',false); + "step 6"; + var next = game.createEvent("showCards"); + next.player = player; + next.cards = [event.card1]; + next.setContent("emptyEvent"); + game.log(player, "展示了", event.card1); + "step 7"; + var next = game.createEvent("showCards"); + next.player = target; + next.cards = [event.card2]; + next.setContent("emptyEvent"); + game.log(target, "展示了", event.card2); + "step 8"; + var name1 = get.name(event.card1); + var name2 = get.name(event.card2); + if (name1 == "sha" && name2 != "shan") { + player.discard(event.card1).set("animate", false); target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } - game.broadcast(function(card){ - var clone=card.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + game.broadcast(function (card) { + var clone = card.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); } - },event.card1); - target.damage('nocard'); - } - else if(name1!='sha'&&name2=='shan'){ - player.discard(event.card1).set('animate',false); + }, event.card1); + target.damage("nocard"); + } else if (name1 != "sha" && name2 == "shan") { + player.discard(event.card1).set("animate", false); target.$gain2(event.card2); - var clone=event.card1.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + var clone = event.card1.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); - game.addVideo('deletenode',player,get.cardsInfo([clone])); + game.addVideo("deletenode", player, get.cardsInfo([clone])); } - game.broadcast(function(card){ - var clone=card.clone; - if(clone){ - clone.style.transition='all 0.5s'; - clone.style.transform='scale(1.2)'; + game.broadcast(function (card) { + var clone = card.clone; + if (clone) { + clone.style.transition = "all 0.5s"; + clone.style.transform = "scale(1.2)"; clone.delete(); } - },event.card1); - player.gainPlayerCard(target,true,'he'); - } - else{ + }, event.card1); + player.gainPlayerCard(target, true, "he"); + } else { player.$gain2(event.card1); target.$gain2(event.card2); } - game.broadcastAll(function(){ - ui.arena.classList.remove('thrownhighlight'); + game.broadcastAll(function () { + ui.arena.classList.remove("thrownhighlight"); }); - game.addVideo('thrownhighlight2'); + game.addVideo("thrownhighlight2"); + }, + ai: { + order: 6, + result: { + target: -1, + }, }, - ai:{ - order:6, - result:{ - target:-1, - } - } }, - zhanjue:{ - audio:2, - enable:'phaseUse', - filterCard:true, - selectCard:-1, - position:'h', - filter:function(event,player){ - if(player.getStat().skill.zhanjue_draw&&player.getStat().skill.zhanjue_draw>=2) return false; - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i=0;i= 2) + return false; + var hs = player.getCards("h"); + if (!hs.length) return false; + for (var i = 0; i < hs.length; i++) { + var mod2 = game.checkMod(hs[i], player, "unchanged", "cardEnabled2", player); + if (mod2 === false) return false; } return true; }, - viewAs:{name:'juedou'}, - group:['zhanjue4'], - ai:{ - damage:true, - order:1, - effect:{ - player:function(card,player,target){ - if(_status.event.skill=='zhanjue'){ - if(player.hasSkillTag('directHit_ai',true,{ - target:target, - card:card, - },true)) return; - if(player.countCards('h')>=3||target.countCards('h')>=3) return 'zeroplayertarget'; - if(player.countCards('h','tao')) return 'zeroplayertarget'; - if(target.countCards('h','sha')>1) return 'zeroplayertarget'; + viewAs: { name: "juedou" }, + group: ["zhanjue4"], + ai: { + damage: true, + order: 1, + effect: { + player: function (card, player, target) { + if (_status.event.skill == "zhanjue") { + if ( + player.hasSkillTag( + "directHit_ai", + true, + { + target: target, + card: card, + }, + true + ) + ) + return; + if (player.countCards("h") >= 3 || target.countCards("h") >= 3) + return "zeroplayertarget"; + if (player.countCards("h", "tao")) return "zeroplayertarget"; + 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") + ); }, - 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'); - } - } - }, - zhanjue2:{ - audio:false, - trigger:{player:'phaseBefore'}, - silent:true, - content:function(){ - player.storage.zhanjue=0; - } - }, - zhanjue3:{ - audio:false, - trigger:{player:'damageAfter',source:'damageAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.parent.skill=='zhanjue'; }, - content:function(){ - trigger.player.addTempSkill('zhanjue5'); - } }, - zhanjue4:{ - audio:false, - trigger:{player:'useCardAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.skill=='zhanjue'; + zhanjue2: { + audio: false, + trigger: { player: "phaseBefore" }, + silent: true, + content: function () { + player.storage.zhanjue = 0; }, - content:function(){ - "step 0" - var stat=player.getStat().skill; - if(!stat.zhanjue_draw) stat.zhanjue_draw=0; + }, + zhanjue3: { + audio: false, + trigger: { player: "damageAfter", source: "damageAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.parent.skill == "zhanjue"; + }, + content: function () { + trigger.player.addTempSkill("zhanjue5"); + }, + }, + zhanjue4: { + audio: false, + trigger: { player: "useCardAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.skill == "zhanjue"; + }, + content: function () { + "step 0"; + var stat = player.getStat().skill; + if (!stat.zhanjue_draw) stat.zhanjue_draw = 0; stat.zhanjue_draw++; - player.draw('nodelay'); - var list=game.filterPlayer(function(current){ - if(current.getHistory('damage',function(evt){ - return evt.card==trigger.card; - }).length>0){ - if(current==player){ + player.draw("nodelay"); + var list = game.filterPlayer(function (current) { + if ( + current.getHistory("damage", function (evt) { + return evt.card == trigger.card; + }).length > 0 + ) { + if (current == player) { stat.zhanjue_draw++; } return true; } return false; }); - if(list.length){ + if (list.length) { list.sortBySeat(); game.asyncDraw(list); } - "step 1" + "step 1"; game.delay(); - } + }, }, - zhanjue5:{}, - qinwang:{ - audio:'qinwang1', - unique:true, - group:['qinwang1'], - zhuSkill:true, - filter:function(event,player){ - if(!player.hasZhuSkill('qinwang')||!game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'; - })||!player.countCards('he')) return false; - return !event.jijiang&&(event.type!='phase'||!player.hasSkill('jijiang3')); + zhanjue5: {}, + qinwang: { + audio: "qinwang1", + unique: true, + group: ["qinwang1"], + zhuSkill: true, + filter: function (event, player) { + if ( + !player.hasZhuSkill("qinwang") || + !game.hasPlayer(function (current) { + return current != player && current.group == "shu"; + }) || + !player.countCards("he") + ) + return false; + return !event.jijiang && (event.type != "phase" || !player.hasSkill("jijiang3")); }, - enable:['chooseToUse','chooseToRespond'], - viewAs:{ - name:'sha', - cards:[], - suit:'none', - number:null, - isCard:true, + enable: ["chooseToUse", "chooseToRespond"], + viewAs: { + name: "sha", + cards: [], + suit: "none", + number: null, + isCard: true, }, - filterCard:lib.filter.cardDiscardable, - position:'he', - check:function(card){ - var player=_status.event.player,players=game.filterPlayer(); - if(player.hasSkill('qinwang_ai')) return false; - for(var i=0;i2&&(nh>=3&&players[i].countCards('h','sha'))){ - return 5-get.value(card); + filterCard: lib.filter.cardDiscardable, + position: "he", + check: function (card) { + var player = _status.event.player, + players = game.filterPlayer(); + if (player.hasSkill("qinwang_ai")) return false; + for (var i = 0; i < players.length; i++) { + var nh = players[i].countCards("h"); + if ( + players[i] != player && + players[i].group == "shu" && + get.attitude(players[i], player) > 2 && + nh >= 3 && + players[i].countCards("h", "sha") + ) { + return 5 - get.value(card); } } return 0; }, - ai:{ - order:function(){ - return get.order({name:'sha'})-0.3; + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.3; }, - respondSha:true, - skillTagFilter:function(player){ - if(!player.hasZhuSkill('qinwang')||!game.hasPlayer(function(current){ - return current!=player&¤t.group=='shu'; - })||!player.countCards('he')) return false; + respondSha: true, + skillTagFilter: function (player) { + if ( + !player.hasZhuSkill("qinwang") || + !game.hasPlayer(function (current) { + return current != player && current.group == "shu"; + }) || + !player.countCards("he") + ) + return false; }, }, }, - qinwang1:{ - audio:2, - trigger:{player:['useCardBegin','respondBegin']}, - logTarget:'targets', - filter:function(event,player){ - return event.skill=='qinwang'; + qinwang1: { + audio: 2, + trigger: { player: ["useCardBegin", "respondBegin"] }, + logTarget: "targets", + filter: function (event, player) { + return event.skill == "qinwang"; }, - forced:true, - content:function(){ - "step 0" + forced: true, + content: function () { + "step 0"; delete trigger.skill; delete trigger.card.cards; player.discard(trigger.cards); delete trigger.cards; - trigger.getParent().set('jijiang',true); - "step 1" - if(event.current==undefined) event.current=player.next; - if(event.current==player){ - player.addTempSkill('jijiang3'); - player.addTempSkill('qinwang_ai'); + trigger.getParent().set("jijiang", true); + "step 1"; + if (event.current == undefined) event.current = player.next; + if (event.current == player) { + player.addTempSkill("jijiang3"); + player.addTempSkill("qinwang_ai"); event.finish(); trigger.cancel(); trigger.getParent().goto(0); - } - else if(event.current.group=='shu'){ - var next=event.current.chooseToRespond('是否替'+get.translation(player)+'打出一张杀?',{name:'sha'}); - next.set('ai',function(){ - var event=_status.event; - return (get.attitude(event.player,event.source)-2); + } else if (event.current.group == "shu") { + var next = event.current.chooseToRespond( + "是否替" + get.translation(player) + "打出一张杀?", + { name: "sha" } + ); + next.set("ai", function () { + var event = _status.event; + return get.attitude(event.player, event.source) - 2; }); - next.set('source',player); - next.set('jijiang',true); - next.set('skillwarn','替'+get.translation(player)+'打出一张杀'); - next.noOrdering=true; - next.autochoose=lib.filter.autoRespondSha; - } - else{ - event.current=event.current.next; + next.set("source", player); + next.set("jijiang", true); + next.set("skillwarn", "替" + get.translation(player) + "打出一张杀"); + next.noOrdering = true; + next.autochoose = lib.filter.autoRespondSha; + } else { + event.current = event.current.next; event.redo(); } - "step 2" - if(result.bool){ + "step 2"; + if (result.bool) { event.current.draw(); event.finish(); - trigger.card=result.card; - trigger.cards=result.cards; - trigger.throw=false; - if(typeof event.current.ai.shown=='number'&&event.current.ai.shown<0.95){ - event.current.ai.shown+=0.3; - if(event.current.ai.shown>0.95) event.current.ai.shown=0.95; + trigger.card = result.card; + trigger.cards = result.cards; + trigger.throw = false; + if (typeof event.current.ai.shown == "number" && event.current.ai.shown < 0.95) { + event.current.ai.shown += 0.3; + if (event.current.ai.shown > 0.95) event.current.ai.shown = 0.95; } - } - else{ - event.current=event.current.next; + } else { + event.current = event.current.next; event.goto(1); } - } - }, - qinwang_ai:{}, - zuoding:{ - audio:2, - audioname:['re_zhongyao'], - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(event.getParent().triggeredTargets3.length>1) return false; - return get.suit(event.card)=='spade'&& - _status.currentPhase==event.player&&event.targets&&event.targets.length&& - event.player!=player&&game.countPlayer2(function(current){ - return current.getHistory('damage').length>0; - })==0; }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zuoding'),'令一名目标角色摸一张牌',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('targets',trigger.targets); - 'step 1' - if(result.bool){ - player.logSkill('zuoding',result.targets); + }, + qinwang_ai: {}, + zuoding: { + audio: 2, + audioname: ["re_zhongyao"], + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (event.getParent().triggeredTargets3.length > 1) return false; + return ( + get.suit(event.card) == "spade" && + _status.currentPhase == event.player && + event.targets && + event.targets.length && + event.player != player && + game.countPlayer2(function (current) { + return current.getHistory("damage").length > 0; + }) == 0 + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zuoding"), + "令一名目标角色摸一张牌", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("targets", trigger.targets); + "step 1"; + if (result.bool) { + player.logSkill("zuoding", result.targets); result.targets[0].draw(); } }, - ai:{ - expose:0.2 + ai: { + expose: 0.2, }, //group:'zuoding3' }, - zuoding2:{}, - zuoding3:{ - trigger:{global:'damage'}, - silent:true, - content:function(){ - player.addTempSkill('zuoding2'); - } - }, - huomo:{ - audio:2, - audioname:['huzhao','re_zhongyao'], - enable:'chooseToUse', - onChooseToUse:function(event){ - if(game.online||event.huomo_list) return; - var list=lib.skill.huomo.getUsed(event.player); - event.set('huomo_list',list); + zuoding2: {}, + zuoding3: { + trigger: { global: "damage" }, + silent: true, + content: function () { + player.addTempSkill("zuoding2"); }, - getUsed:function(player){ - var list=[]; - player.getHistory('useCard',function(evt){ - if(get.type(evt.card,null,false)=='basic') list.add(evt.card.name); + }, + huomo: { + audio: 2, + audioname: ["huzhao", "re_zhongyao"], + enable: "chooseToUse", + onChooseToUse: function (event) { + if (game.online || event.huomo_list) return; + var list = lib.skill.huomo.getUsed(event.player); + event.set("huomo_list", list); + }, + getUsed: function (player) { + var list = []; + player.getHistory("useCard", function (evt) { + if (get.type(evt.card, null, false) == "basic") list.add(evt.card.name); }); return list; }, - hiddenCard:function(player,name){ - if(get.type(name)!='basic') return false; - var list=lib.skill.huomo.getUsed(player); - if(list.includes(name)) return false; - return player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'eh'); + hiddenCard: function (player, name) { + if (get.type(name) != "basic") return false; + var list = lib.skill.huomo.getUsed(player); + if (list.includes(name)) return false; + return player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "eh"); }, - filter:function(event,player){ - if(event.type=='wuxie'||!player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'eh')) return false; - var list=event.huomo_list||lib.skill.huomo.getUsed(player); - for(var name of lib.inpile){ - if(get.type(name)!='basic'||list.includes(name)) continue; - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) return true; - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) return true; + filter: function (event, player) { + if ( + event.type == "wuxie" || + !player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "eh") + ) + return false; + var list = event.huomo_list || lib.skill.huomo.getUsed(player); + for (var name of lib.inpile) { + if (get.type(name) != "basic" || list.includes(name)) continue; + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) return true; + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var vcards=[]; - var list=event.huomo_list||lib.skill.huomo.getUsed(player); - for(var name of lib.inpile){ - if(get.type(name)!='basic'||list.includes(name)) continue; - var card={name:name,isCard:true}; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name]); - if(name=='sha'){ - for(var nature of lib.inpile_nature){ - card.nature=nature; - if(event.filterCard(card,player,event)) vcards.push(['基本','',name,nature]); + chooseButton: { + dialog: function (event, player) { + var vcards = []; + var list = event.huomo_list || lib.skill.huomo.getUsed(player); + for (var name of lib.inpile) { + if (get.type(name) != "basic" || list.includes(name)) continue; + var card = { name: name, isCard: true }; + if (event.filterCard(card, player, event)) vcards.push(["基本", "", name]); + if (name == "sha") { + for (var nature of lib.inpile_nature) { + card.nature = nature; + if (event.filterCard(card, player, event)) + vcards.push(["基本", "", name, nature]); } } } - return ui.create.dialog('活墨',[vcards,'vcard'],'hidden'); + return ui.create.dialog("活墨", [vcards, "vcard"], "hidden"); }, - check:function(button){ - var player=_status.event.player; - var card={name:button.link[2],nature:button.link[3]}; - if(game.hasPlayer(function(current){ - return player.canUse(card,current)&&get.effect(current,card,player,player)>0; - })){ - switch(button.link[2]){ - case 'tao':return 5; - case 'jiu':return 3.01; - case 'sha': - if(button.link[3]=='fire') return 2.95; - else if(button.link[3]=='thunder') return 2.92; + check: function (button) { + var player = _status.event.player; + var card = { name: button.link[2], nature: button.link[3] }; + if ( + game.hasPlayer(function (current) { + return ( + player.canUse(card, current) && + get.effect(current, card, player, player) > 0 + ); + }) + ) { + switch (button.link[2]) { + case "tao": + return 5; + case "jiu": + return 3.01; + case "sha": + if (button.link[3] == "fire") return 2.95; + else if (button.link[3] == "thunder") return 2.92; else return 2.9; - case 'shan':return 1; + case "shan": + return 1; } } return 0; }, - backup:function(links,player){ + backup: function (links, player) { return { - check:function(card){ - return 1/Math.max(0.1,get.value(card)); + check: function (card) { + return 1 / Math.max(0.1, get.value(card)); }, - filterCard:function(card){ - return get.type(card)!='basic'&&get.color(card)=='black'; + filterCard: function (card) { + return get.type(card) != "basic" && get.color(card) == "black"; }, - viewAs:{ - name:links[0][2], - nature:links[0][3], - suit:'none', - number:null, - isCard:true, + viewAs: { + name: links[0][2], + nature: links[0][3], + suit: "none", + number: null, + isCard: true, }, - position:'he', - popname:true, - ignoreMod:true, - precontent:function(){ - player.logSkill('huomo'); - var card=event.result.cards[0]; - game.log(player,'将',card,'置于牌堆顶'); - event.result.card={name:event.result.card.name,nature:event.result.card.nature}; - event.result.cards=[]; - player.loseToDiscardpile(card,ui.cardPile,'visible','insert').log=false; + position: "he", + popname: true, + ignoreMod: true, + precontent: function () { + player.logSkill("huomo"); + var card = event.result.cards[0]; + game.log(player, "将", card, "置于牌堆顶"); + event.result.card = { + name: event.result.card.name, + nature: event.result.card.nature, + }; + event.result.cards = []; + player.loseToDiscardpile(card, ui.cardPile, "visible", "insert").log = false; }, - } + }; + }, + prompt: function (links, player) { + return ( + "将一张黑色非基本牌置于牌堆顶并视为使用一张" + + get.translation(links[0][3] || "") + + get.translation(links[0][2]) + ); }, - prompt:function(links,player){ - return '将一张黑色非基本牌置于牌堆顶并视为使用一张'+get.translation(links[0][3]||'')+get.translation(links[0][2]); - } }, - ai:{ - order:function(){ - var player=_status.event.player; - var event=_status.event; - var list=lib.skill.huomo.getUsed(player); - if(!list.includes('jiu')&&event.filterCard({name:'jiu'},player,event)&&get.effect(player,{name:'jiu'})>0){ + ai: { + order: function () { + var player = _status.event.player; + var event = _status.event; + var list = lib.skill.huomo.getUsed(player); + if ( + !list.includes("jiu") && + event.filterCard({ name: "jiu" }, player, event) && + get.effect(player, { name: "jiu" }) > 0 + ) { return 3.1; } return 2.9; }, - respondSha:true, - fireAttack:true, - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(tag=='fireAttack') return true; - if(player.hasCard(function(card){ - return get.color(card)=='black'&&get.type(card)!='basic'; - },'he')){ - var list=lib.skill.huomo.getUsed(player); - if(tag=='respondSha'){ - if(arg!='use') return false; - if(list.includes('sha')) return false; + respondSha: true, + fireAttack: true, + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (tag == "fireAttack") return true; + if ( + player.hasCard(function (card) { + return get.color(card) == "black" && get.type(card) != "basic"; + }, "he") + ) { + var list = lib.skill.huomo.getUsed(player); + if (tag == "respondSha") { + if (arg != "use") return false; + if (list.includes("sha")) return false; + } else if (tag == "respondShan") { + if (list.includes("shan")) return false; } - else if(tag=='respondShan'){ - if(list.includes('shan')) return false; - } - } - else{ + } else { return false; } }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, // taoxi:{ // audio:2, @@ -8840,1390 +10438,1616 @@ game.import('character',function(lib,game,ui,get,ai,_status){ // } // }, // taoxi4:{}, - taoxi:{ - audio:2, - trigger:{player:'useCardToPlayered'}, - check:function(event,player){ - if(get.attitude(player,event.target)>=0) return false; - var cards=event.target.getCards('h'); - if(cards.filter(card=>player.hasUseTarget(card)).length>=cards.length/2) return true; + taoxi: { + audio: 2, + trigger: { player: "useCardToPlayered" }, + check: function (event, player) { + if (get.attitude(player, event.target) >= 0) return false; + var cards = event.target.getCards("h"); + if (cards.filter((card) => player.hasUseTarget(card)).length >= cards.length / 2) + return true; return false; }, - filter:function(event,player){ - return player.isPhaseUsing()&&event.targets.length==1&&event.target.countCards('h')>0&&player!=event.target&&!player.hasSkill('taoxi_used'); + filter: function (event, player) { + return ( + player.isPhaseUsing() && + event.targets.length == 1 && + event.target.countCards("h") > 0 && + player != event.target && + !player.hasSkill("taoxi_used") + ); }, - logTarget:'target', - content:function(){ - 'step 0' - player.choosePlayerCard(trigger.target,'h',true); - 'step 1' - if(result.bool){ - var card=result.links[0]; - player.showCards(card,get.translation(player)+'对'+get.translation(trigger.target)+'发动了【讨袭】'); - if(!player.storage.taoxi_list) player.storage.taoxi_list=[[],[]]; - if(!player.storage.taoxi_list[1].some(i=>i._cardid==card.cardid)){ - var cardx=ui.create.card(); + logTarget: "target", + content: function () { + "step 0"; + player.choosePlayerCard(trigger.target, "h", true); + "step 1"; + if (result.bool) { + var card = result.links[0]; + player.showCards( + card, + get.translation(player) + + "对" + + get.translation(trigger.target) + + "发动了【讨袭】" + ); + if (!player.storage.taoxi_list) player.storage.taoxi_list = [[], []]; + if (!player.storage.taoxi_list[1].some((i) => i._cardid == card.cardid)) { + var cardx = ui.create.card(); cardx.init(get.cardInfo(card)); - cardx._cardid=card.cardid; - player.directgains([cardx],null,'taoxi'); + cardx._cardid = card.cardid; + player.directgains([cardx], null, "taoxi"); player.storage.taoxi_list[0].push(trigger.target); player.storage.taoxi_list[1].push(cardx); - player.markSkill('taoxi_list'); - player.addTempSkill('taoxi_list'); - player.addTempSkill('taoxi_use'); - player.addTempSkill('taoxi_used','phaseUseAfter'); + player.markSkill("taoxi_list"); + player.addTempSkill("taoxi_list"); + player.addTempSkill("taoxi_use"); + player.addTempSkill("taoxi_used", "phaseUseAfter"); } } }, - subSkill:{ - used:{}, - use:{ - trigger:{player:'useCardBefore'}, - charlotte:true, - forced:true, - popup:false, - firstDo:true, - group:'taoxi_lose', - filter:function(event,player){ - if(!player.storage.taoxi_list||!player.storage.taoxi_list.length) return false; - var list=player.storage.taoxi_list[1]; - return event.cards&&event.cards.some(card=>{ - return list.includes(card); - }) + subSkill: { + used: {}, + use: { + trigger: { player: "useCardBefore" }, + charlotte: true, + forced: true, + popup: false, + firstDo: true, + group: "taoxi_lose", + filter: function (event, player) { + if (!player.storage.taoxi_list || !player.storage.taoxi_list.length) return false; + var list = player.storage.taoxi_list[1]; + return ( + event.cards && + event.cards.some((card) => { + return list.includes(card); + }) + ); }, - content:function(){ - var cards=[],list=player.storage.taoxi_list; - for(var card of trigger.cards){ - var bool=false; - for(var i=0;icardxx.cardid==cardid)[0]; - if(cardx&&get.position(cardx)=='h'){ + content: function () { + var cards = [], + list = player.storage.taoxi_list; + for (var card of trigger.cards) { + var bool = false; + for (var i = 0; i < list[0].length; i++) { + if (list[1][i] == card) { + var cardid = card._cardid; + var cardx = list[0][i].getCards( + "h", + (cardxx) => cardxx.cardid == cardid + )[0]; + if (cardx && get.position(cardx) == "h") { cards.push(cardx); list[0][i].$throw(cardx); - bool=true; + bool = true; break; } } } - if(!bool) cards.push(card); + if (!bool) cards.push(card); } - trigger.cards=cards; - trigger.card.cards=cards; - trigger.throw=false; + trigger.cards = cards; + trigger.card.cards = cards; + trigger.throw = false; }, - mod:{ - aiOrder:function(player,card,num){ - var list=player.storage.taoxi_list; - if(!list||!list[1]) return; - if(list[1].includes(card)) return num+0.5; + mod: { + aiOrder: function (player, card, num) { + var list = player.storage.taoxi_list; + if (!list || !list[1]) return; + if (list[1].includes(card)) return num + 0.5; }, - cardEnabled2:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('taoxi')&&_status.event.name=='chooseToRespond') return false; + cardEnabled2: function (card) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("taoxi") && + _status.event.name == "chooseToRespond" + ) + return false; + }, + }, + ai: { + effect: { + player_use: function (card, player, target) { + var list = player.storage.taoxi_list; + if (!list || !list[1]) return; + if (list[1].includes(card)) return [1, 1]; + }, }, }, - ai:{ - effect:{ - player_use:function(card,player,target){ - var list=player.storage.taoxi_list; - if(!list||!list[1]) return; - if(list[1].includes(card)) return [1,1]; - } - } - } }, - lose:{ - trigger:{ - global:['loseEnd','equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], + lose: { + trigger: { + global: [ + "loseEnd", + "equipEnd", + "addJudgeEnd", + "gainEnd", + "loseAsyncEnd", + "addToExpansionEnd", + ], }, - charlotte:true, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - var list=player.storage.taoxi_list; - if(!list||!list[0].length) return false; - return game.hasPlayer(function(current){ - if(!list[0].includes(current)) return; - var evt=event.getl(current); - if(evt&&evt.hs&&evt.hs.some(card=>{ - return list[1].some(i=>i._cardid==card.cardid); - })) return true; + charlotte: true, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + var list = player.storage.taoxi_list; + if (!list || !list[0].length) return false; + return game.hasPlayer(function (current) { + if (!list[0].includes(current)) return; + var evt = event.getl(current); + if ( + evt && + evt.hs && + evt.hs.some((card) => { + return list[1].some((i) => i._cardid == card.cardid); + }) + ) + return true; return false; }); }, - content:function(){ - var list=player.storage.taoxi_list; - var targets=game.filterPlayer(function(current){ - if(!list[0].includes(current)) return; - var evt=trigger.getl(current); - if(evt&&evt.hs&&evt.hs.some(card=>{ - return list[1].some(i=>i._cardid==card.cardid); - })) return true; + content: function () { + var list = player.storage.taoxi_list; + var targets = game.filterPlayer(function (current) { + if (!list[0].includes(current)) return; + var evt = trigger.getl(current); + if ( + evt && + evt.hs && + evt.hs.some((card) => { + return list[1].some((i) => i._cardid == card.cardid); + }) + ) + return true; return false; }); - for(var target of targets){ - var hs=trigger.getl(target).hs; - for(var i=0;ij.cardid==list[1][i]._cardid)){ - if(player.isOnline2()){ - player.send(function(list,i){ - game.me.storage.taoxi_list=list; - list[1][i].delete(); - list[0].splice(i,1);list[1].splice(i,1); - },player.storage.taoxi_list,i); + for (var target of targets) { + var hs = trigger.getl(target).hs; + for (var i = 0; i < list[0].length; i++) { + if (hs.some((j) => j.cardid == list[1][i]._cardid)) { + if (player.isOnline2()) { + player.send( + function (list, i) { + game.me.storage.taoxi_list = list; + list[1][i].delete(); + list[0].splice(i, 1); + list[1].splice(i, 1); + }, + player.storage.taoxi_list, + i + ); } list[1][i].delete(); - list[0].splice(i,1);list[1].splice(i,1); + list[0].splice(i, 1); + list[1].splice(i, 1); i--; } } } - } + }, }, - list:{ - trigger:{player:'phaseEnd'}, - charlotte:true, - forced:true, - onremove:function(player){ - game.broadcastAll(function(player){ - player.storage.taoxi_list[1].forEach(i=>i.delete()); + list: { + trigger: { player: "phaseEnd" }, + charlotte: true, + forced: true, + onremove: function (player) { + game.broadcastAll(function (player) { + player.storage.taoxi_list[1].forEach((i) => i.delete()); delete player.storage.taoxi_list; - },player); + }, player); }, - filter:function(event,player){ - return player.storage.taoxi_list&&player.storage.taoxi_list[0].length>0; + filter: function (event, player) { + return player.storage.taoxi_list && player.storage.taoxi_list[0].length > 0; }, - content:function(){ + content: function () { player.loseHp(); - } - } - } + }, + }, + }, }, - xingshuai:{ - skillAnimation:true, - animationColor:'thunder', - audio:2, - trigger:{player:'dying'}, + xingshuai: { + skillAnimation: true, + animationColor: "thunder", + audio: 2, + trigger: { player: "dying" }, //priority:6, - zhuSkill:true, - filter:function(event,player){ - if(player.hp>0) return false; - if(!player.hasZhuSkill('xingshuai')) return false; - return game.hasPlayer(function(current){ - return current!=player&¤t.group=='wei'; + zhuSkill: true, + filter: function (event, player) { + if (player.hp > 0) return false; + if (!player.hasZhuSkill("xingshuai")) return false; + return game.hasPlayer(function (current) { + return current != player && current.group == "wei"; }); }, - mark:true, - unique:true, - limited:true, - content:function(){ - 'step 0' - player.awakenSkill('xingshuai'); - var targets=game.filterPlayer(); + mark: true, + unique: true, + limited: true, + content: function () { + "step 0"; + player.awakenSkill("xingshuai"); + var targets = game.filterPlayer(); targets.remove(player); - event.targets=targets; - event.damages=[]; - 'step 1' - if(event.targets.length){ - var current=event.targets.shift(); - if(current.group=='wei'){ - current.chooseBool('是否令'+get.translation(player)+'回复1点体力?').set('ai',function(){ - return get.attitude(_status.event.player,_status.event.target)>2; - }).set('target',player); - event.current=current; - } - else{ + event.targets = targets; + event.damages = []; + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); + if (current.group == "wei") { + current + .chooseBool("是否令" + get.translation(player) + "回复1点体力?") + .set("ai", function () { + return get.attitude(_status.event.player, _status.event.target) > 2; + }) + .set("target", player); + event.current = current; + } else { event.redo(); } - } - else{ + } else { event.goto(3); } - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event.damages.push(event.current); - event.current.line(player,'green'); - game.log(event.current,'令',player,'回复1点体力'); + event.current.line(player, "green"); + game.log(event.current, "令", player, "回复1点体力"); player.recover(); } - if(event.targets.length){ + if (event.targets.length) { event.goto(1); } - 'step 3' - if(event.damages.length){ - var next=game.createEvent('xingshuaI_next'); + "step 3"; + if (event.damages.length) { + var next = game.createEvent("xingshuaI_next"); event.next.remove(next); trigger.after.push(next); - next.targets=event.damages; - next.setContent(function(){ + next.targets = event.damages; + next.setContent(function () { targets.shift().damage(); - if(targets.length) event.redo(); + if (targets.length) event.redo(); }); } - } + }, }, - mingjian:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target; + mingjian: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target; }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterCard:true, - selectCard:-1, - discard:false, - lose:false, - delay:false, - content:function(){ - player.give(cards,target); - target.addTempSkill('mingjian2',{player:'phaseAfter'}); + filterCard: true, + selectCard: -1, + discard: false, + lose: false, + delay: false, + content: function () { + player.give(cards, target); + target.addTempSkill("mingjian2", { player: "phaseAfter" }); target.storage.mingjian2++; - target.updateMarks('mingjian2'); + target.updateMarks("mingjian2"); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0; - if(player.countCards('h')==player.countCards('h','du')) return -1; - if(target.hasJudge('lebu')) return 0; - if(get.attitude(player,target)>3){ - var basis=get.threaten(target); - if(player==get.zhu(player)&&player.hp<=2&&player.countCards('h','shan')&&!game.hasPlayer(function(current){ - return get.attitude(current,player)>3&¤t.countCards('h','tao')>0; - })) return 0; - if(target.countCards('h')+player.countCards('h')>target.hp+2) return basis*0.8; + ai: { + order: 1, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0; + if (player.countCards("h") == player.countCards("h", "du")) return -1; + if (target.hasJudge("lebu")) return 0; + if (get.attitude(player, target) > 3) { + var basis = get.threaten(target); + if ( + player == get.zhu(player) && + player.hp <= 2 && + player.countCards("h", "shan") && + !game.hasPlayer(function (current) { + return ( + get.attitude(current, player) > 3 && + current.countCards("h", "tao") > 0 + ); + }) + ) + return 0; + if (target.countCards("h") + player.countCards("h") > target.hp + 2) + return basis * 0.8; return basis; } return 0; - } - } - } - }, - mingjian2:{ - charlotte:true, - mark:true, - intro:{ - content:'手牌上限+#,出杀次数+#' - }, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=0; - }, - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.storage.mingjian2; + }, }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.storage.mingjian2; - } }, }, - mingjian_old:{ - audio:2, - trigger:{player:'phaseUseBefore'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + mingjian2: { + charlotte: true, + mark: true, + intro: { + content: "手牌上限+#,出杀次数+#", }, - content:function(){ - 'step 0' - var go=Math.random()<0.5; - player.chooseTarget(get.prompt('mingjian_old'),function(card,player,target){ - return player!=target - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>3){ - if(player.countCards('h')>player.hp) return att; - if(go) return att; + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = 0; + }, + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + player.storage.mingjian2; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.storage.mingjian2; + }, + }, + }, + mingjian_old: { + audio: 2, + trigger: { player: "phaseUseBefore" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; + }, + content: function () { + "step 0"; + var go = Math.random() < 0.5; + player.chooseTarget(get.prompt("mingjian_old"), function (card, player, target) { + return player != target; + }).ai = function (target) { + var att = get.attitude(player, target); + if (att > 3) { + if (player.countCards("h") > player.hp) return att; + if (go) return att; } return 0; - } - 'step 1' - if(result.bool){ - player.logSkill('mingjian_old',result.targets); + }; + "step 1"; + if (result.bool) { + player.logSkill("mingjian_old", result.targets); trigger.cancel(); - var target=result.targets[0]; - target.addSkill('mingjian2_old'); - var hs=player.getCards('h'); - player.give(hs,target); + var target = result.targets[0]; + target.addSkill("mingjian2_old"); + var hs = player.getCards("h"); + player.give(hs, target); } - } + }, }, - mingjian2_old:{ - audio:false, - trigger:{global:'phaseAfter'}, - forced:true, - popup:false, - charlotte:true, - content:function(){ - if(lib.config.glow_phase){ - if(_status.currentPhase){ - _status.currentPhase.classList.remove('glow_phase'); + mingjian2_old: { + audio: false, + trigger: { global: "phaseAfter" }, + forced: true, + popup: false, + charlotte: true, + content: function () { + if (lib.config.glow_phase) { + if (_status.currentPhase) { + _status.currentPhase.classList.remove("glow_phase"); } - player.classList.add('glow_phase'); + player.classList.add("glow_phase"); } - game.addVideo('phaseChange',player); - _status.currentPhase=player; - player.ai.tempIgnore=[]; - player.stat.push({card:{},skill:{}}); + game.addVideo("phaseChange", player); + _status.currentPhase = player; + player.ai.tempIgnore = []; + player.stat.push({ card: {}, skill: {} }); player.phaseUse(); - player.removeSkill('mingjian2_old'); - } + player.removeSkill("mingjian2_old"); + }, }, - huituo:{ - audio:2, - audioname:['re_caorui'], - trigger:{player:'damageEnd'}, - direct:true, - content:function(){ - 'step 0' - var forced=event.forced===undefined?false:event.forced; - var info=get.skillInfoTranslation('huituo',player); - var str=`###${forced?'恢拓:请选择一名角色':get.prompt('huituo')}###令一名角色判定。若结果为红色,其回复1点体力;若结果为黑色,其摸${get.cnNumber(trigger.num)}张牌`; - player.chooseTarget(str,event.forced).set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)>0){ - return get.recoverEffect(target,player,player)+1; + huituo: { + audio: 2, + audioname: ["re_caorui"], + trigger: { player: "damageEnd" }, + direct: true, + content: function () { + "step 0"; + var forced = event.forced === undefined ? false : event.forced; + var info = get.skillInfoTranslation("huituo", player); + var str = `###${ + forced ? "恢拓:请选择一名角色" : get.prompt("huituo") + }###令一名角色判定。若结果为红色,其回复1点体力;若结果为黑色,其摸${get.cnNumber( + trigger.num + )}张牌`; + player.chooseTarget(str, event.forced).set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) > 0) { + return get.recoverEffect(target, player, player) + 1; } return 0; }); - 'step 1' - if(result.bool){ - player.logSkill('huituo',result.targets); - var target=result.targets[0]; - event.target=target; - target.judge(function(card){ - if(target.hp==target.maxHp){ - if(get.color(card)=='red') return -1; + "step 1"; + if (result.bool) { + player.logSkill("huituo", result.targets); + var target = result.targets[0]; + event.target = target; + target.judge(function (card) { + if (target.hp == target.maxHp) { + if (get.color(card) == "red") return -1; } - if(get.color(card)=='red') return 1; + if (get.color(card) == "red") return 1; return 0; }); - } - else{ + } else { event.finish(); } - 'step 2' - if(result.color){ - if(result.color=='red'){ - if(event.target.hp0&&event.source&& - event.card&&event.card.name=='sha'; + ai: { + maixie: true, + maixie_hp: true, }, - direct:true, + }, + duodao: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && event.source && event.card && event.card.name == "sha" + ); + }, + direct: true, //priority:5, - audio:2, - content:function(){ - 'step 0' - var prompt='弃置一张牌' - if(trigger.source.getEquips(1).length) prompt+=(',然后获得'+get.translation(trigger.source)+'装备区中的'+get.translation(trigger.source.getEquips(1))); - var next=player.chooseToDiscard('he',get.prompt('duodao',trigger.source),prompt); - next.logSkill=['duodao',trigger.source]; - next.set('ai',function(card){ - if(!_status.event.getTrigger().source.getEquip(1)) return 0; - if(get.attitude(_status.event.player,_status.event.getTrigger().source)<=0){ - return 6-get.value(card); + audio: 2, + content: function () { + "step 0"; + var prompt = "弃置一张牌"; + if (trigger.source.getEquips(1).length) + prompt += + ",然后获得" + + get.translation(trigger.source) + + "装备区中的" + + get.translation(trigger.source.getEquips(1)); + var next = player.chooseToDiscard("he", get.prompt("duodao", trigger.source), prompt); + next.logSkill = ["duodao", trigger.source]; + next.set("ai", function (card) { + if (!_status.event.getTrigger().source.getEquip(1)) return 0; + if (get.attitude(_status.event.player, _status.event.getTrigger().source) <= 0) { + return 6 - get.value(card); } return 0; }); - 'step 1' - if(result.bool&&trigger.source.getEquips(1).length){ - player.gain(trigger.source.getEquips(1),trigger.source,'give','bySelf'); + "step 1"; + if (result.bool && trigger.source.getEquips(1).length) { + player.gain(trigger.source.getEquips(1), trigger.source, "give", "bySelf"); } }, - ai:{ - maixie_defend:true, - } - }, - reanjian:{ - trigger:{player:'useCardToPlayered'}, - forced:true, - audio:2, - filter:function(event,player){ - return event.card.name=='sha'&&!event.target.inRange(player); + ai: { + maixie_defend: true, }, - logTarget:'target', - content:function(){ - trigger.getParent().reanjian_buffed=true; - var map=trigger.customArgs; - var id=trigger.target.playerid; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + }, + reanjian: { + trigger: { player: "useCardToPlayered" }, + forced: true, + audio: 2, + filter: function (event, player) { + return event.card.name == "sha" && !event.target.inRange(player); + }, + logTarget: "target", + content: function () { + trigger.getParent().reanjian_buffed = true; + var map = trigger.customArgs; + var id = trigger.target.playerid; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; - trigger.target.addTempSkill('reanjian2'); - trigger.target.addTempSkill('reanjian4'); + trigger.target.addTempSkill("reanjian2"); + trigger.target.addTempSkill("reanjian4"); trigger.target.storage.reanjian2.add(trigger.card); }, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.name=='sha'&&arg.target&&!arg.target.inRange(player)) return true; + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.name == "sha" && arg.target && !arg.target.inRange(player)) + return true; return false; - } - }, - }, - reanjian2:{ - firstDo:true, - ai:{unequip2:true}, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; - }, - onremove:true, - trigger:{ - player:['damage','damageCancelled','damageZero'], - target:['shaMiss','useCardToExcluded'], - }, - charlotte:true, - filter:function(event,player){ - return player.storage.reanjian2&&event.card&&player.storage.reanjian2.includes(event.card); - }, - silent:true, - forced:true, - popup:false, - priority:12, - content:function(){ - player.storage.reanjian2.remove(trigger.card); - if(!player.storage.reanjian2.length) player.removeSkill('reanjian2'); - }, - }, - reanjian3:{ - mod:{ - cardSavable:function(card){ - if(card.name=='tao') return false; }, }, }, - reanjian4:{ - trigger:{player:'dyingBegin'}, - forced:true, - silent:true, - firstDo:true, - filter:function(event,player){ - return event.getParent(2).reanjian_buffed=true; + reanjian2: { + firstDo: true, + ai: { unequip2: true }, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - content:function(){ - player.addTempSkill('reanjian3',{global:['dyingEnd','phaseEnd']}); + onremove: true, + trigger: { + player: ["damage", "damageCancelled", "damageZero"], + target: ["shaMiss", "useCardToExcluded"], + }, + charlotte: true, + filter: function (event, player) { + return ( + player.storage.reanjian2 && + event.card && + player.storage.reanjian2.includes(event.card) + ); + }, + silent: true, + forced: true, + popup: false, + priority: 12, + content: function () { + player.storage.reanjian2.remove(trigger.card); + if (!player.storage.reanjian2.length) player.removeSkill("reanjian2"); }, }, - reduodao:{ - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.card.name=='sha'&&(get.color(event.card)=='red'?event.player.getEquips(1).length>0:player.countCards('he')>0); + reanjian3: { + mod: { + cardSavable: function (card) { + if (card.name == "tao") return false; + }, }, - direct:true, - audio:2, - content:function(){ - 'step 0' - var prompt='弃置一张牌' - if(trigger.player.getEquips(1).length) prompt+=(',然后获得'+get.translation(trigger.player)+'装备区中的'+get.translation(trigger.player.getEquips(1))); - var next=player.chooseToDiscard('he',get.prompt('reduodao',trigger.player),prompt); - next.logSkill=['reduodao',trigger.player]; - next.set('ai',function(card){ - if(!_status.event.getTrigger().player.getEquips(1).length) return 0; - if(get.attitude(_status.event.player,_status.event.getTrigger().player)*get.value(_status.event.getTrigger().player.getEquips(1))<=0){ - return 6-get.value(card); + }, + reanjian4: { + trigger: { player: "dyingBegin" }, + forced: true, + silent: true, + firstDo: true, + filter: function (event, player) { + return (event.getParent(2).reanjian_buffed = true); + }, + content: function () { + player.addTempSkill("reanjian3", { global: ["dyingEnd", "phaseEnd"] }); + }, + }, + reduodao: { + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return ( + event.card.name == "sha" && + (get.color(event.card) == "red" + ? event.player.getEquips(1).length > 0 + : player.countCards("he") > 0) + ); + }, + direct: true, + audio: 2, + content: function () { + "step 0"; + var prompt = "弃置一张牌"; + if (trigger.player.getEquips(1).length) + prompt += + ",然后获得" + + get.translation(trigger.player) + + "装备区中的" + + get.translation(trigger.player.getEquips(1)); + var next = player.chooseToDiscard("he", get.prompt("reduodao", trigger.player), prompt); + next.logSkill = ["reduodao", trigger.player]; + next.set("ai", function (card) { + if (!_status.event.getTrigger().player.getEquips(1).length) return 0; + if ( + get.attitude(_status.event.player, _status.event.getTrigger().player) * + get.value(_status.event.getTrigger().player.getEquips(1)) <= + 0 + ) { + return 6 - get.value(card); } return 0; }); - 'step 1' - if(result.bool&&trigger.player.getEquips(1).length){ - if(!result.cards||!result.cards.length) player.logSkill('reduodao',trigger.player); - player.gain(trigger.player.getEquips(1),trigger.player,'give','bySelf'); + "step 1"; + if (result.bool && trigger.player.getEquips(1).length) { + if (!result.cards || !result.cards.length) + player.logSkill("reduodao", trigger.player); + player.gain(trigger.player.getEquips(1), trigger.player, "give", "bySelf"); } }, }, - anjian:{ - audio:2, - trigger:{source:'damageBegin1'}, - check:function(event,player){ - return get.attitude(player,event.player)<=0; + anjian: { + audio: 2, + trigger: { source: "damageBegin1" }, + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - forced:true, - filter:function(event,player){ - return event.getParent().name=='sha'&&!event.player.inRange(player); + forced: true, + filter: function (event, player) { + return event.getParent().name == "sha" && !event.player.inRange(player); }, - content:function(){ + content: function () { trigger.num++; - } - }, - xinpojun:{ - shaRelated:true, - trigger:{player:'useCardToPlayered'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&player.isPhaseUsing()&&event.target.hp>0&&event.target.countCards('he')>0; }, - audio:2, - content:function(){ - 'step 0' - player.choosePlayerCard(trigger.target,'he', - [1,Math.min(trigger.target.countCards('he'),trigger.target.hp)],get.prompt('xinpojun',trigger.target)).set('forceAuto',true); - 'step 1' - if(result.bool&&result.links.length){ - var target=trigger.target; - player.logSkill('xinpojun',target); - target.addToExpansion(result.cards,'giveAuto',target).gaintag.add('xinpojun2'); - target.addSkill('xinpojun2'); + }, + xinpojun: { + shaRelated: true, + trigger: { player: "useCardToPlayered" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.isPhaseUsing() && + event.target.hp > 0 && + event.target.countCards("he") > 0 + ); + }, + audio: 2, + content: function () { + "step 0"; + player + .choosePlayerCard( + trigger.target, + "he", + [1, Math.min(trigger.target.countCards("he"), trigger.target.hp)], + get.prompt("xinpojun", trigger.target) + ) + .set("forceAuto", true); + "step 1"; + if (result.bool && result.links.length) { + var target = trigger.target; + player.logSkill("xinpojun", target); + target.addToExpansion(result.cards, "giveAuto", target).gaintag.add("xinpojun2"); + target.addSkill("xinpojun2"); } }, - ai:{ - unequip_ai:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(get.attitude(player,arg.target)>0||!player.isPhaseUsing()) return false; - if(tag=='directHit_ai') return arg.target.hp>=Math.max(1,arg.target.countCards('h')-1); - if(arg&&arg.name=='sha'&&arg.target.getEquip(2)) return true; + ai: { + unequip_ai: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (get.attitude(player, arg.target) > 0 || !player.isPhaseUsing()) return false; + if (tag == "directHit_ai") + return arg.target.hp >= Math.max(1, arg.target.countCards("h") - 1); + if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; - } - }, - }, - xinpojun2:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('xinpojun2').length>0; - }, - content:function(){ - 'step 0' - var cards=player.getExpansions('xinpojun2'); - player.gain(cards,'draw'); - game.log(player,'收回了'+get.cnNumber(cards.length)+'张“破军”牌'); - 'step 1' - player.removeSkill('xinpojun2'); - }, - intro:{ - markcount:'expansion', - mark:function(dialog,storage,player){ - var cards=player.getExpansions('xinpojun2'); - if(player.isUnderControl(true)) dialog.addAuto(cards); - else return '共有'+get.cnNumber(cards.length)+'张牌'; }, }, }, - qiaoshi:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return event.player!=player&&event.player.countCards('h')==player.countCards('h')&&event.player.isIn(); + xinpojun2: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("xinpojun2").length > 0; }, - check:function(event,player){ - return get.attitude(player,event.player)>=0; + content: function () { + "step 0"; + var cards = player.getExpansions("xinpojun2"); + player.gain(cards, "draw"); + game.log(player, "收回了" + get.cnNumber(cards.length) + "张“破军”牌"); + "step 1"; + player.removeSkill("xinpojun2"); }, - logTarget:'player', - content:function(){ - game.asyncDraw([trigger.player,player]); + intro: { + markcount: "expansion", + mark: function (dialog, storage, player) { + var cards = player.getExpansions("xinpojun2"); + if (player.isUnderControl(true)) dialog.addAuto(cards); + else return "共有" + get.cnNumber(cards.length) + "张牌"; + }, }, }, - yanyu:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.hasCard(card=>lib.skill.yanyu.filterCard(card,player),'h'); + qiaoshi: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + event.player != player && + event.player.countCards("h") == player.countCards("h") && + event.player.isIn() + ); }, - filterCard:(card,player)=>get.name(card)=='sha'&&player.canRecast(card), - discard:false, - lose:false, - delay:false, - content:function(){ + check: function (event, player) { + return get.attitude(player, event.player) >= 0; + }, + logTarget: "player", + content: function () { + game.asyncDraw([trigger.player, player]); + }, + }, + yanyu: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.hasCard((card) => lib.skill.yanyu.filterCard(card, player), "h"); + }, + filterCard: (card, player) => get.name(card) == "sha" && player.canRecast(card), + discard: false, + lose: false, + delay: false, + content: function () { player.recast(cards); }, - ai:{ - basic:{ - order:1 + ai: { + basic: { + order: 1, + }, + result: { + player: 1, }, - result:{ - player:1 - } }, - group:'yanyu2' + group: "yanyu2", }, - yanyu2:{ - trigger:{player:'phaseUseEnd'}, - filter:function(event,player){ - return player.getHistory('useSkill',function(evt){ - return evt.event.getParent('phaseUse')==event&&evt.skill=='yanyu'; - }).length>=2; + yanyu2: { + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + return ( + player.getHistory("useSkill", function (evt) { + return evt.event.getParent("phaseUse") == event && evt.skill == "yanyu"; + }).length >= 2 + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yanyu'),'令一名男性角色摸两张牌',function(card,player,target){ - return target.hasSex('male')&&target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - player.logSkill('yanyu',result.targets); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("yanyu"), + "令一名男性角色摸两张牌", + function (card, player, target) { + return target.hasSex("male") && target != player; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("yanyu", result.targets); result.targets[0].draw(2); } - } - }, - youdi:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('he')>0; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('youdi'),function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - if(!_status.event.goon) return 0; - if(target.countCards('he')==0) return 0; - return -get.attitude(_status.event.player,target); - }).set('goon',player.countCards('h','sha')<=player.countCards('h')/3); - "step 1" - if(result.bool){ + }, + youdi: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("youdi"), function (card, player, target) { + return player != target; + }) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + if (target.countCards("he") == 0) return 0; + return -get.attitude(_status.event.player, target); + }) + .set("goon", player.countCards("h", "sha") <= player.countCards("h") / 3); + "step 1"; + if (result.bool) { game.delay(); - player.logSkill('youdi',result.targets); - event.target=result.targets[0]; - event.target.discardPlayerCard(player,'he',true); - } - else{ + player.logSkill("youdi", result.targets); + event.target = result.targets[0]; + event.target.discardPlayerCard(player, "he", true); + } else { event.finish(); } - "step 2" - if(result.links[0].name!='sha'&&event.target.countGainableCards(player,'he')){ - player.gainPlayerCard('he',event.target,true); + "step 2"; + if (result.links[0].name != "sha" && event.target.countGainableCards(player, "he")) { + player.gainPlayerCard("he", event.target, true); } }, - ai:{ - expose:0.2, - } + ai: { + expose: 0.2, + }, }, - fuhun:{ - enable:['chooseToUse','chooseToRespond'], - filterCard:true, - selectCard:2, - position:'hs', - audio:2, - audioname:['re_guanzhang'], - derivation:['new_rewusheng','olpaoxiao'], - viewAs:{name:'sha'}, - prompt:'将两张手牌当杀使用或打出', - viewAsFilter:function(player){ - return player.countCards('hs')>1; + fuhun: { + enable: ["chooseToUse", "chooseToRespond"], + filterCard: true, + selectCard: 2, + position: "hs", + audio: 2, + audioname: ["re_guanzhang"], + derivation: ["new_rewusheng", "olpaoxiao"], + viewAs: { name: "sha" }, + prompt: "将两张手牌当杀使用或打出", + viewAsFilter: function (player) { + return player.countCards("hs") > 1; }, - check:function(card){ - if(_status.event.player.hasSkill('new_rewusheng')&&get.color(card)=='red') return 0; - if(_status.event.name=='chooseToRespond'){ - if(card.name=='sha') return 0; - return 6-get.useful(card); + check: function (card) { + if (_status.event.player.hasSkill("new_rewusheng") && get.color(card) == "red") return 0; + if (_status.event.name == "chooseToRespond") { + if (card.name == "sha") return 0; + return 6 - get.useful(card); } - if(_status.event.player.countCards('hs')<4) return 6-get.useful(card); - return 7-get.useful(card); + if (_status.event.player.countCards("hs") < 4) return 6 - get.useful(card); + return 7 - get.useful(card); }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - if(player.countCards('hs')<2) return false; + ai: { + respondSha: true, + skillTagFilter: function (player) { + if (player.countCards("hs") < 2) return false; }, - order:function(item,player){ - if(player.hasSkill('new_rewusheng')&&player.hasSkill('olpaoxiao')){ + order: function (item, player) { + if (player.hasSkill("new_rewusheng") && player.hasSkill("olpaoxiao")) { return 1; } - if(player.countCards('hs')<4){ + if (player.countCards("hs") < 4) { return 1; } return 4; }, }, - group:'fuhun2' + group: "fuhun2", }, - fuhun2:{ - audio:'fuhun', - audioname:['re_guanzhang'], - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ - if(['new_rewusheng','olpaoxiao'].every(skill=>player.hasSkill(skill,null,false,false))) return false; - return event.getParent().skill=='fuhun'; + fuhun2: { + audio: "fuhun", + audioname: ["re_guanzhang"], + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { + if ( + ["new_rewusheng", "olpaoxiao"].every((skill) => + player.hasSkill(skill, null, false, false) + ) + ) + return false; + return event.getParent().skill == "fuhun"; }, - content:function(){ - player.addTempSkills(['new_rewusheng','olpaoxiao']); + content: function () { + player.addTempSkills(["new_rewusheng", "olpaoxiao"]); // player.addTempSkill('fuhun3'); - } + }, }, - fuhun3:{}, - fencheng:{ - skillAnimation:'epic', - animationColor:'gray', - audio:2, - enable:'phaseUse', - filter:function(event,player){ + fuhun3: {}, + fencheng: { + skillAnimation: "epic", + animationColor: "gray", + audio: 2, + enable: "phaseUse", + filter: function (event, player) { return !player.storage.fencheng; }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - unique:true, - limited:true, - selectTarget:-1, - mark:true, - line:'fire', - content:function(){ - "step 0" - player.storage.fencheng=true; - player.awakenSkill('fencheng'); - var res=get.damageEffect(target,player,target,'fire'); - var num=Math.max(1,target.countCards('e')); - target.chooseToDiscard(num,'he','弃置'+get.cnNumber(num)+'张牌或受到1点火焰伤害').set('ai',function(card){ - var res=_status.event.res; - var num=_status.event.num; - var player=_status.event.player; - if(res>=0) return -1; - if(num>2&&player.hp>1) return -1; - if(num>1&&player.hp>2) return -1; - if(get.position(card)=='e'){ - return 10-get.value(card); - } - return 6-get.value(card); - }).set('res',res).set('num',num); - "step 1" - if(!result.bool){ - target.damage('fire'); + unique: true, + limited: true, + selectTarget: -1, + mark: true, + line: "fire", + content: function () { + "step 0"; + player.storage.fencheng = true; + player.awakenSkill("fencheng"); + var res = get.damageEffect(target, player, target, "fire"); + var num = Math.max(1, target.countCards("e")); + target + .chooseToDiscard(num, "he", "弃置" + get.cnNumber(num) + "张牌或受到1点火焰伤害") + .set("ai", function (card) { + var res = _status.event.res; + var num = _status.event.num; + var player = _status.event.player; + if (res >= 0) return -1; + if (num > 2 && player.hp > 1) return -1; + if (num > 1 && player.hp > 2) return -1; + if (get.position(card) == "e") { + return 10 - get.value(card); + } + return 6 - get.value(card); + }) + .set("res", res) + .set("num", num); + "step 1"; + if (!result.bool) { + target.damage("fire"); } }, - ai:{ - order:1, - result:{ - player:function(player){ - var num=0,players=game.filterPlayer(); - for(var i=0;i0){ - num-=Math.max(1,players[i].countCards('e')); - } - else if(att<0){ - num+=Math.max(1,players[i].countCards('e')); + ai: { + order: 1, + result: { + player: function (player) { + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + player != players[i] && + get.damageEffect(players[i], player, players[i], "fire") < 0 + ) { + var att = get.attitude(player, players[i]); + if (att > 0) { + num -= Math.max(1, players[i].countCards("e")); + } else if (att < 0) { + num += Math.max(1, players[i].countCards("e")); } } } - if(players.length<5){ - return num-1; + if (players.length < 5) { + return num - 1; + } else { + return num - 2; } - else{ - return num-2; - } - } - } + }, + }, }, - init:function(player){ - player.storage.fencheng=false; + init: function (player) { + player.storage.fencheng = false; + }, + intro: { + content: "limited", }, - intro:{ - content:'limited' - } }, - mieji:{ - trigger:{player:'useCard2'}, - direct:true, - audio:2, - filter:function(event,player){ - if(get.type(event.card)!='trick'||get.color(event.card)!='black') return false; - if(!event.targets||event.targets.length!=1) return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + mieji: { + trigger: { player: "useCard2" }, + direct: true, + audio: 2, + filter: function (event, player) { + if (get.type(event.card) != "trick" || get.color(event.card) != "black") return false; + if (!event.targets || event.targets.length != 1) return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - position:'he', - content:function(){ - "step 0" - player.chooseTarget(get.prompt('mieji'),'为'+get.translation(trigger.card)+'增加一个额外目标',function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('autodelay',true).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); - }).set('targets',trigger.targets).set('card',trigger.card); - "step 1" - if(result.bool){ - player.logSkill('mieji',result.targets); + position: "he", + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("mieji"), + "为" + get.translation(trigger.card) + "增加一个额外目标", + function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + } + ) + .set("autodelay", true) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + player.logSkill("mieji", result.targets); trigger.targets.push(result.targets[0]); } - } + }, }, - junxing:{ - enable:'phaseUse', - audio:2, - usable:1, - filterCard:true, - selectCard:[1,Infinity], - filter:function(event,player){ - return player.countCards('h')>0; + junxing: { + enable: "phaseUse", + audio: 2, + usable: 1, + filterCard: true, + selectCard: [1, Infinity], + filter: function (event, player) { + return player.countCards("h") > 0; }, - check:function(card){ - if(ui.selected.cards.length) return -1; - var val=get.value(card); - if(get.type(card)=='basic') return 8-get.value(card); - return 5-get.value(card); + check: function (card) { + if (ui.selected.cards.length) return -1; + var val = get.value(card); + if (get.type(card) == "basic") return 8 - get.value(card); + return 5 - get.value(card); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - content:function(){ - "step 0" - var types=[]; - for(var i=0;i{ - if(current==player||current.countCards('h')) return false; - var evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length; + direct: true, + filter: function (event, player) { + if (_status.currentPhase != player) return false; + return game.hasPlayer((current) => { + if (current == player || current.countCards("h")) return false; + var evt = event.getl(current); + return evt && evt.hs && evt.hs.length; }); }, - check:function(event,player){ - return get.damageEffect(event.player,player,player)>0; + check: function (event, player) { + return get.damageEffect(event.player, player, player) > 0; }, - content:function(){ - 'step 0' - var targets=game.filterPlayer(current=>{ - if(current==player||current.countCards('h')) return false; - var evt=trigger.getl(current); - return evt&&evt.hs&&evt.hs.length; + content: function () { + "step 0"; + var targets = game.filterPlayer((current) => { + if (current == player || current.countCards("h")) return false; + var evt = trigger.getl(current); + return evt && evt.hs && evt.hs.length; }); - event.targets=targets; - 'step 1' - var target=event.targets.shift(); - event.target=target; - player.chooseBool(get.prompt2('juece',target)).set('ai',()=>{ - return get.damageEffect(_status.event.getParent().target,_status.event.player,_status.event.player)>=0; + event.targets = targets; + "step 1"; + var target = event.targets.shift(); + event.target = target; + player.chooseBool(get.prompt2("juece", target)).set("ai", () => { + return ( + get.damageEffect( + _status.event.getParent().target, + _status.event.player, + _status.event.player + ) >= 0 + ); }); - 'step 2' - if(result.bool){ - player.logSkill('juece',target); + "step 2"; + if (result.bool) { + player.logSkill("juece", target); target.damage(); } - 'step 3' - if(targets.length) event.goto(1); + "step 3"; + if (targets.length) event.goto(1); + }, + ai: { + threaten: 1.1, }, - ai:{ - threaten:1.1 - } }, - jiefan:{ - skillAnimation:true, - animationColor:'wood', - audio:2, - audioname:['re_handang'], - unique:true, - limited:true, - mark:true, - init:function(player){ - player.storage.jiefan=false; + jiefan: { + skillAnimation: true, + animationColor: "wood", + audio: 2, + audioname: ["re_handang"], + unique: true, + limited: true, + mark: true, + init: function (player) { + player.storage.jiefan = false; }, - enable:'phaseUse', - filter:function(event,player){ + enable: "phaseUse", + filter: function (event, player) { return !player.storage.jiefan; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - filterTarget:true, - content:function(){ - "step 0" - player.awakenSkill('jiefan'); - player.storage.jiefan=true; - event.players=game.filterPlayer(function(current){ - return current!=target&¤t.inRange(target); + filterTarget: true, + content: function () { + "step 0"; + player.awakenSkill("jiefan"); + player.storage.jiefan = true; + event.players = game.filterPlayer(function (current) { + return current != target && current.inRange(target); }); event.players.sortBySeat(target); - "step 1" - if(event.players.length){ - event.current=event.players.shift(); - event.current.addTempClass('target'); - player.line(event.current,'green'); - if(event.current.countCards('he')&&target.isIn()){ - event.current.chooseToDiscard({subtype:'equip1'},'he','弃置一张武器牌或让'+ - get.translation(target)+'摸一张牌').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.target)<0) return 7-get.value(card); - return -1; - }).set('target',target); - event.tempbool=false; + "step 1"; + if (event.players.length) { + event.current = event.players.shift(); + event.current.addTempClass("target"); + player.line(event.current, "green"); + if (event.current.countCards("he") && target.isIn()) { + event.current + .chooseToDiscard( + { subtype: "equip1" }, + "he", + "弃置一张武器牌或让" + get.translation(target) + "摸一张牌" + ) + .set("ai", function (card) { + if (get.attitude(_status.event.player, _status.event.target) < 0) + return 7 - get.value(card); + return -1; + }) + .set("target", target); + event.tempbool = false; + } else { + event.tempbool = true; } - else{ - event.tempbool=true; - } - } - else{ + } else { event.finish(); } - "step 2" - if(event.tempbool||result.bool==false){ + "step 2"; + if (event.tempbool || result.bool == false) { target.draw(); } event.goto(1); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - if(player.hp>2){ - if(game.phaseNumber 2) { + if (game.phaseNumber < game.players.length * 2) return 0; } - var num=0,players=game.filterPlayer(); - for(var i=0;i0&&event.player.countCards('j')) return true; - if(event.num>1){ - if(att<0) return false; - if(att>0) return true; + zhiman: { + audio: 2, + audioname: ["guansuo"], + trigger: { source: "damageBegin2" }, + check: function (event, player) { + if (get.damageEffect(event.player, player, player) < 0) return true; + var att = get.attitude(player, event.player); + if (att > 0 && event.player.countCards("j")) return true; + if (event.num > 1) { + if (att < 0) return false; + if (att > 0) return true; } - var cards=event.player.getGainableCards(player,'e'); - for(var i=0;i=6) return true; + var cards = event.player.getGainableCards(player, "e"); + for (var i = 0; i < cards.length; i++) { + if (get.equipValue(cards[i]) >= 6) return true; } return false; }, - filter:function(event,player){ - return player!=event.player; + filter: function (event, player) { + return player != event.player; }, - logTarget:'player', - content:function(){ - if(trigger.player.countGainableCards(player,'ej')){ - player.gainPlayerCard(trigger.player,'ej',true); + logTarget: "player", + content: function () { + if (trigger.player.countGainableCards(player, "ej")) { + player.gainPlayerCard(trigger.player, "ej", true); } trigger.cancel(); - } + }, }, - sanyao:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ + sanyao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { return target.isMaxHp(); }, - filter:function(event,player){ - return player.countCards('he')>0; + filter: function (event, player) { + return player.countCards("he") > 0; }, - check:function(card){return 7-get.value(card);}, - position:'he', - filterCard:true, - content:function(){ - target.damage('nocard'); + check: function (card) { + return 7 - get.value(card); }, - ai:{ - result:{ - target:function(player,target){ - if(target.countCards('j')&&get.attitude(player,target)>0){ + position: "he", + filterCard: true, + content: function () { + target.damage("nocard"); + }, + ai: { + result: { + target: function (player, target) { + if (target.countCards("j") && get.attitude(player, target) > 0) { return 1; } - if(target.countCards('e')){ + if (target.countCards("e")) { return -1; } - return get.damageEffect(target,player); + return get.damageEffect(target, player); }, }, - order:7 - } - }, - olsanyao:{ - enable:'phaseUse', - audio:'sanyao', - filter:function(event,player){ - return player.countCards('he')>0&&(!player.hasSkill('olsanyao0')||!player.hasSkill('olsanyao1')); + order: 7, }, - chooseButton:{ - dialog:function(event,player){ - var list=[ - '选择手牌数最多的一名角色', - '选择体力值最大的一名角色', - ]; - var choiceList=ui.create.dialog('散谣:请选择一项','forcebutton','hidden'); - choiceList.add([list.map((item,i)=>{ - return [i,item]; - }),'textbutton']); + }, + olsanyao: { + enable: "phaseUse", + audio: "sanyao", + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + (!player.hasSkill("olsanyao0") || !player.hasSkill("olsanyao1")) + ); + }, + chooseButton: { + dialog: function (event, player) { + var list = ["选择手牌数最多的一名角色", "选择体力值最大的一名角色"]; + var choiceList = ui.create.dialog("散谣:请选择一项", "forcebutton", "hidden"); + choiceList.add([ + list.map((item, i) => { + return [i, item]; + }), + "textbutton", + ]); return choiceList; }, - filter:function(button,player){ - return !player.hasSkill('olsanyao'+button.link); + filter: function (button, player) { + return !player.hasSkill("olsanyao" + button.link); }, - check:function(button){ - var player=_status.event.player; - if(game.hasPlayer([ - function(target){ - var num=target.countCards('h'); - return !game.hasPlayer(function(current){ - return current!=target&¤t.countCards('h')>num; - })&&get.effect(target,'sanyao',player,player)>0; - }, - function(target){ - var num=target.hp; - return !game.hasPlayer(function(current){ - return current!=target&¤t.hp>num; - })&&get.effect(target,'sanyao',player,player)>0; - }, - ][button.link])) return 1+button.link; + check: function (button) { + var player = _status.event.player; + if ( + game.hasPlayer( + [ + function (target) { + var num = target.countCards("h"); + return ( + !game.hasPlayer(function (current) { + return current != target && current.countCards("h") > num; + }) && get.effect(target, "sanyao", player, player) > 0 + ); + }, + function (target) { + var num = target.hp; + return ( + !game.hasPlayer(function (current) { + return current != target && current.hp > num; + }) && get.effect(target, "sanyao", player, player) > 0 + ); + }, + ][button.link] + ) + ) + return 1 + button.link; return 0; }, - backup:function(links){ + backup: function (links) { return { - audio:'sanyao', - filterTarget:[ - function(card,player,target){ - var num=target.countCards('h'); - return !game.hasPlayer(function(current){ - return current!=target&¤t.countCards('h')>num; + audio: "sanyao", + filterTarget: [ + function (card, player, target) { + var num = target.countCards("h"); + return !game.hasPlayer(function (current) { + return current != target && current.countCards("h") > num; }); }, - function(card,player,target){ - return !game.hasPlayer(function(current){ - return current!=target&¤t.hp>target.hp; + function (card, player, target) { + return !game.hasPlayer(function (current) { + return current != target && current.hp > target.hp; }); - } + }, ][links[0]], - index:links[0], - filterCard:true, - check:function(card){ - return 7-get.value(card); + index: links[0], + filterCard: true, + check: function (card) { + return 7 - get.value(card); }, - position:'he', - content:function(){ - player.addTempSkill('olsanyao'+lib.skill[event.name].index) - target.damage('nocard'); + position: "he", + content: function () { + player.addTempSkill("olsanyao" + lib.skill[event.name].index); + target.damage("nocard"); }, - ai:lib.skill.sanyao.ai, - } + ai: lib.skill.sanyao.ai, + }; }, - prompt:function(){ - return '请选择【散谣】的目标' + prompt: function () { + return "请选择【散谣】的目标"; }, }, - ai:{ - order:7, - result:{ - player:1, + ai: { + order: 7, + result: { + player: 1, }, }, }, - olsanyao0:{}, - olsanyao1:{}, - rezhiman:{ - audio:'zhiman', - audioname:['guansuo','re_masu'], - audioname2:{ - dc_guansuo:'zhiman_guansuo', + olsanyao0: {}, + olsanyao1: {}, + rezhiman: { + audio: "zhiman", + audioname: ["guansuo", "re_masu"], + audioname2: { + dc_guansuo: "zhiman_guansuo", }, - trigger:{source:'damageBegin2'}, - filter:function(event,player){ - return player!=event.player; + trigger: { source: "damageBegin2" }, + filter: function (event, player) { + return player != event.player; }, - check:function(event,player){ - if(get.damageEffect(event.player,player,player)<0) return true; - var att=get.attitude(player,event.player); - if(att>0&&event.player.countCards('j')) return true; - if(event.num>1){ - if(att<0) return false; - if(att>0) return true; + check: function (event, player) { + if (get.damageEffect(event.player, player, player) < 0) return true; + var att = get.attitude(player, event.player); + if (att > 0 && event.player.countCards("j")) return true; + if (event.num > 1) { + if (att < 0) return false; + if (att > 0) return true; } - var cards=event.player.getGainableCards(player,'he'); - for(var i=0;i=6) return true; + var cards = event.player.getGainableCards(player, "he"); + for (var i = 0; i < cards.length; i++) { + if (get.equipValue(cards[i]) >= 6) return true; } return false; }, - logTarget:'player', - content:function(){ - if(trigger.player.countGainableCards(player,'hej')){ - player.gainPlayerCard(trigger.player,'hej',true); + logTarget: "player", + content: function () { + if (trigger.player.countGainableCards(player, "hej")) { + player.gainPlayerCard(trigger.player, "hej", true); } trigger.cancel(); - } - }, - zhiman_guansuo:{audio:2}, - resanyao:{ - audio:2, - enable:'phaseUse', - usable:1, - selectCard:function(){ - var player=_status.event.player; - return [Math.max(1,ui.selected.targets.length),game.countPlayer(function(target){ - return target!=player&&!game.hasPlayer(function(current){ - return current!=player&¤t.hp>target.hp - }); - })]; }, - selectTarget:function(){ + }, + zhiman_guansuo: { audio: 2 }, + resanyao: { + audio: 2, + enable: "phaseUse", + usable: 1, + selectCard: function () { + var player = _status.event.player; + return [ + Math.max(1, ui.selected.targets.length), + game.countPlayer(function (target) { + return ( + target != player && + !game.hasPlayer(function (current) { + return current != player && current.hp > target.hp; + }) + ); + }), + ]; + }, + selectTarget: function () { return ui.selected.cards.length; }, - filterTarget:function(card,player,target){ - return target!=player&&!game.hasPlayer(function(current){ - return current!=player&¤t.hp>target.hp - }); + filterTarget: function (card, player, target) { + return ( + target != player && + !game.hasPlayer(function (current) { + return current != player && current.hp > target.hp; + }) + ); }, - check:function(card){ - var player=_status.event.player; - if(game.countPlayer(function(target){ - return target!=player&&!game.hasPlayer(function(current){ - return current!=player&¤t.hp>target.hp - })&&get.effect(target,'sanyao',player,player)>0; - })<=ui.selected.cards.length) return 0; - return 7-get.value(card); + check: function (card) { + var player = _status.event.player; + if ( + game.countPlayer(function (target) { + return ( + target != player && + !game.hasPlayer(function (current) { + return current != player && current.hp > target.hp; + }) && + get.effect(target, "sanyao", player, player) > 0 + ); + }) <= ui.selected.cards.length + ) + return 0; + return 7 - get.value(card); }, - position:'he', - filterCard:true, - content:function(){ - target.damage('nocard'); + position: "he", + filterCard: true, + content: function () { + target.damage("nocard"); }, - ai:{ - result:{ - target:function(player,target){ - var disbool=false; - if(player.hasSkill('rezhiman')){ - if(target.countCards('j')&&get.attitude(player,target)>0){ + ai: { + result: { + target: function (player, target) { + var disbool = false; + if (player.hasSkill("rezhiman")) { + if (target.countCards("j") && get.attitude(player, target) > 0) { return 1; } - if(target.countCards('he',function(card){ - return card.name=='tengjia'||get.value(card)>0; - })){ - disbool=true; + if ( + target.countCards("he", function (card) { + return card.name == "tengjia" || get.value(card) > 0; + }) + ) { + disbool = true; } } - var damage=get.damageEffect(target,player); - if(disbool&&get.attitude(player,target)<0) return Math.min(-1,damage); + var damage = get.damageEffect(target, player); + if (disbool && get.attitude(player, target) < 0) return Math.min(-1, damage); return damage; }, }, - order:7 - } + order: 7, + }, }, - reqiaoshui:{ - audio:2, - enable:'phaseUse', - filterTarget:function(card,player,target){ + reqiaoshui: { + audio: 2, + enable: "phaseUse", + filterTarget: function (card, player, target) { return player.canCompare(target); }, - filter:function(event,player){ - return player.countCards('h')>0; + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool) player.addTempSkill('qiaoshui3','phaseUseEnd'); - else{ - player.addTempSkill('qiaoshui4'); - event.getParent(3).skipped=true; + "step 1"; + if (result.bool) player.addTempSkill("qiaoshui3", "phaseUseEnd"); + else { + player.addTempSkill("qiaoshui4"); + event.getParent(3).skipped = true; } }, - ai:{ - order:function(item,player){ - if(player.countCards('h',function(card){ - return player.hasValueTarget(card); - })) return 10; + ai: { + order: function (item, player) { + if ( + player.countCards("h", function (card) { + return player.hasValueTarget(card); + }) + ) + return 10; return 1; }, - result:{ - target:function(player,target){ - if(player.countCards('h',function(card){ - return player.hasValueTarget(card); - })){ - if(player.hasSkill('qiaoshui3')) return 0; - var nd=!player.needsToDiscard(); - if(player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card) - if(nd&&val<0) return true; - if(val<=5){ - return get.number(card)>=12; - } - if(val<=6){ - return get.number(card)>=13; - } - return false; - })) return -1; + result: { + target: function (player, target) { + if ( + player.countCards("h", function (card) { + return player.hasValueTarget(card); + }) + ) { + if (player.hasSkill("qiaoshui3")) return 0; + var nd = !player.needsToDiscard(); + if ( + player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (nd && val < 0) return true; + if (val <= 5) { + return get.number(card) >= 12; + } + if (val <= 6) { + return get.number(card) >= 13; + } + return false; + }) + ) + return -1; return 0; } return -1; @@ -10231,1620 +12055,1883 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - qiaoshui:{ - audio:2, - audioname2:{ - re_jianyong:'reqiaoshui', - xin_jianyong:'xinqiaoshui', + qiaoshui: { + audio: 2, + audioname2: { + re_jianyong: "reqiaoshui", + xin_jianyong: "xinqiaoshui", }, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0; + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('qiaoshui'),function(card,player,target){ - return player.canCompare(target); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)/target.countCards('h'); - }); - "step 1" - if(result.bool){ - player.logSkill('qiaoshui',result.targets[0]); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("qiaoshui"), function (card, player, target) { + return player.canCompare(target); + }) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) / target.countCards("h"); + }); + "step 1"; + if (result.bool) { + player.logSkill("qiaoshui", result.targets[0]); player.chooseToCompare(result.targets[0]); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ - player.addTempSkill('qiaoshui3'); - } - else{ - player.addTempSkill('qiaoshui2'); + "step 2"; + if (result.bool) { + player.addTempSkill("qiaoshui3"); + } else { + player.addTempSkill("qiaoshui2"); } }, - ai:{ - expose:0.1 - } + ai: { + expose: 0.1, + }, }, - qiaoshui2:{ - mod:{ - cardEnabled:function(card){ - if(get.type(card,'trick')=='trick') return false; - } - } + qiaoshui2: { + mod: { + cardEnabled: function (card) { + if (get.type(card, "trick") == "trick") return false; + }, + }, }, - qiaoshui3:{ - charlotte:true, - audio:'qiaoshui', - audioname2:{ - re_jianyong:'reqiaoshui', - xin_jianyong:'xinqiaoshui', - ol_jianyong:'olqiaoshui', + qiaoshui3: { + charlotte: true, + audio: "qiaoshui", + audioname2: { + re_jianyong: "reqiaoshui", + xin_jianyong: "xinqiaoshui", + ol_jianyong: "olqiaoshui", }, - trigger:{player:'useCard2'}, - filter:function(event,player){ - var type=get.type(event.card); - return type=='basic'||type=='trick'; + trigger: { player: "useCard2" }, + filter: function (event, player) { + var type = get.type(event.card); + return type == "basic" || type == "trick"; }, - direct:true, - content:function(){ - 'step 0' - player.removeSkill('qiaoshui3'); - var goon=false; - var info=get.info(trigger.card); - if(trigger.targets&&!info.multitarget){ - var players=game.filterPlayer(); - for(var i=0;i1){ + if (goon) { + player + .chooseTarget( + "巧说:是否额外指定一名" + get.translation(trigger.card) + "的目标?", + function (card, player, target) { + var trigger = _status.event; + if (trigger.targets.includes(target)) return false; + return lib.filter.targetEnabled2( + trigger.card, + _status.event.player, + target + ); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + } else { + if (!info.multitarget && trigger.targets && trigger.targets.length > 1) { event.goto(3); } } - 'step 1' - if(result.bool){ - if(!event.isMine()) game.delayx(); - event.target=result.targets[0]; - } - else{ + "step 1"; + if (result.bool) { + if (!event.isMine()) game.delayx(); + event.target = result.targets[0]; + } else { event.finish(); } - 'step 2' - if(event.target){ - player.logSkill('qiaoshui3',event.target); + "step 2"; + if (event.target) { + player.logSkill("qiaoshui3", event.target); trigger.targets.add(event.target); } event.finish(); - 'step 3' - player.chooseTarget('巧说:是否减少一名'+get.translation(trigger.card)+'的目标?',function(card,player,target){ - return _status.event.targets.includes(target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - return -get.effect(target,trigger.card,trigger.player,_status.event.player); - }).set('targets',trigger.targets); - 'step 4' - if(result.bool){ - event.targets=result.targets; - if(event.isMine()){ - player.logSkill('qiaoshui3',event.targets); + "step 3"; + player + .chooseTarget( + "巧说:是否减少一名" + get.translation(trigger.card) + "的目标?", + function (card, player, target) { + return _status.event.targets.includes(target); + } + ) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + return -get.effect(target, trigger.card, trigger.player, _status.event.player); + }) + .set("targets", trigger.targets); + "step 4"; + if (result.bool) { + event.targets = result.targets; + if (event.isMine()) { + player.logSkill("qiaoshui3", event.targets); event.finish(); } - for(var i=0;i1) return false; - return event.card&&get.type(event.card)=='trick'&&event.player!=player; + jyzongshi_old: { + audio: 2, + trigger: { target: "useCardToBegin" }, + filter: function (event, player) { + if (event.targets && event.targets.length > 1) return false; + return event.card && get.type(event.card) == "trick" && event.player != player; }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); }, - ai:{ - effect:function(card,player,target){ - if(get.type(card)=='trick') return [1,1]; + ai: { + effect: function (card, player, target) { + if (get.type(card) == "trick") return [1, 1]; }, - } - }, - shenxing:{ - audio:2, - enable:'phaseUse', - position:'he', - filterCard:true, - selectCard:2, - prompt:'弃置两张牌并摸一张牌', - check:function(card){ - var player=_status.event.player; - if(!player.hasSkill('olbingyi')||player.hasSkill('olbingyi_blocker',null,null,false)) return 4-get.value(card); - var red=0,black=0,hs=player.getCards('h'); - for(var i of hs){ - if(ui.selected.cards.includes(i)) continue; - var color=get.color(i,player); - if(color=='red') red++; - if(color=='black') black++; - } - if(red>2&&black>2) return 4-get.value(card); - if(red==0||black==0) return 8-get.value(card); - var color=get.color(card); - if(black<=red) return ((color=='black'&&get.position(card)=='h')?8:4)-get.value(card); - return (color=='red'&&get.position(card)=='h'?8:4)-get.value(card); }, - content:function(){ + }, + shenxing: { + audio: 2, + enable: "phaseUse", + position: "he", + filterCard: true, + selectCard: 2, + prompt: "弃置两张牌并摸一张牌", + check: function (card) { + var player = _status.event.player; + if ( + !player.hasSkill("olbingyi") || + player.hasSkill("olbingyi_blocker", null, null, false) + ) + return 4 - get.value(card); + var red = 0, + black = 0, + hs = player.getCards("h"); + for (var i of hs) { + if (ui.selected.cards.includes(i)) continue; + var color = get.color(i, player); + if (color == "red") red++; + if (color == "black") black++; + } + if (red > 2 && black > 2) return 4 - get.value(card); + if (red == 0 || black == 0) return 8 - get.value(card); + var color = get.color(card); + if (black <= red) + return (color == "black" && get.position(card) == "h" ? 8 : 4) - get.value(card); + return (color == "red" && get.position(card) == "h" ? 8 : 4) - get.value(card); + }, + content: function () { player.draw(); }, - ai:{ - order:9, - result:{ - player:function(player,target){ - if(!ui.selected.cards.length) return 1; - if(!player.hasSkill('olbingyi')||player.hasSkill('olbingyi_blocker',null,null,false)) return 1; - var red=0,black=0,hs=player.getCards('h'); - for(var i of hs){ - if(ui.selected.cards.includes(i)) continue; - var color=get.color(i); - if(color=='red') red++; - if(color=='black') black++; + ai: { + order: 9, + result: { + player: function (player, target) { + if (!ui.selected.cards.length) return 1; + if ( + !player.hasSkill("olbingyi") || + player.hasSkill("olbingyi_blocker", null, null, false) + ) + return 1; + var red = 0, + black = 0, + hs = player.getCards("h"); + for (var i of hs) { + if (ui.selected.cards.includes(i)) continue; + var color = get.color(i); + if (color == "red") red++; + if (color == "black") black++; } - var val=0; - for(var i of ui.selected.cards) val+=get.value(i,player); - if(red==0||black==0){ - if(red+black==0) return 0; - var num=Math.min(red+black,game.countPlayer(function(current){ - return current!=player&&get.attitude(player,current)>0&&!current.hasSkillTag('nogain'); - }))+1; - if(num*7>val) return 1; + var val = 0; + for (var i of ui.selected.cards) val += get.value(i, player); + if (red == 0 || black == 0) { + if (red + black == 0) return 0; + var num = + Math.min( + red + black, + game.countPlayer(function (current) { + return ( + current != player && + get.attitude(player, current) > 0 && + !current.hasSkillTag("nogain") + ); + }) + ) + 1; + if (num * 7 > val) return 1; } - if(val<8) return 1; + if (val < 8) return 1; return 0; }, }, }, }, - bingyi:{ - audio:2, - audioname:['xin_guyong'], - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('h')>0; + bingyi: { + audio: 2, + audioname: ["xin_guyong"], + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterx:function(event,player){ - var cards=player.getCards('h'); - if(cards.length<1) return false; - var color=get.color(cards[0]); - for(var i=1;i=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; + 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; }, - content:function(){ - "step 0" - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.2); + 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){ - if(ui.selected.cards.length&&card.name==ui.selected.cards[0].name) return -1; - if(get.tag(card,'damage')) return 1; - if(get.type(card)=='equip') return 1; - return 0; - }); - "step 2" - player.give(result.cards,trigger.player); - trigger.player.addSkill('xiantu4'); + "step 1"; + player + .chooseCard(2, "he", true, "交给" + get.translation(trigger.player) + "两张牌") + .set("ai", function (card) { + if (ui.selected.cards.length && card.name == ui.selected.cards[0].name) return -1; + if (get.tag(card, "damage")) return 1; + if (get.type(card) == "equip") return 1; + return 0; + }); + "step 2"; + player.give(result.cards, trigger.player); + trigger.player.addSkill("xiantu4"); trigger.player.storage.xiantu4.push(player); }, - ai:{ - threaten:1.1 - } - }, - xiantu1:{audio:true}, - xiantu2:{audio:true}, - xiantu4:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - audio:false, - onremove:true, - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + ai: { + threaten: 1.1, }, - charlotte:true, - content:function(){ - while(player.storage.xiantu4.length){ - var current=player.storage.xiantu4.shift(); - if(current.isDead()) continue; - current.logSkill('xiantu2'); + }, + xiantu1: { audio: true }, + xiantu2: { audio: true }, + xiantu4: { + trigger: { player: "phaseUseEnd" }, + forced: true, + audio: false, + onremove: true, + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; + }, + charlotte: true, + content: function () { + while (player.storage.xiantu4.length) { + var current = player.storage.xiantu4.shift(); + if (current.isDead()) continue; + current.logSkill("xiantu2"); current.loseHp(); } - player.removeSkill('xiantu4'); + player.removeSkill("xiantu4"); }, - group:'xiantu3' + group: "xiantu3", }, - xiantu3:{ - trigger:{source:'dieAfter'}, - forced:true, - audio:false, - content:function(){ - player.removeSkill('xiantu4'); - } + xiantu3: { + trigger: { source: "dieAfter" }, + forced: true, + audio: false, + content: function () { + player.removeSkill("xiantu4"); + }, }, - qiangzhi:{ - audio:2, - audioname:['re_zhangsong'], - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; + qiangzhi: { + audio: 2, + audioname: ["re_zhangsong"], + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; }); }, - subfrequent:['draw'], - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('qiangzhi'),function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).set('ai',function(){ - return Math.random(); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('qiangzhi',target); - player.choosePlayerCard(target,'h',true); - } - else event.finish(); - 'step 2' - var card=result.cards[0]; - target.showCards(card,get.translation(target)+'因【强识】展示'); - player.storage.qiangzhi_draw=get.type(card,'trick'); - game.addVideo('storage',player,['qiangzhi_draw',player.storage.qiangzhi_draw]); - player.addTempSkill('qiangzhi_draw','phaseUseEnd'); + subfrequent: ["draw"], + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("qiangzhi"), function (card, player, target) { + return target != player && target.countCards("h") > 0; + }) + .set("ai", function () { + return Math.random(); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("qiangzhi", target); + player.choosePlayerCard(target, "h", true); + } else event.finish(); + "step 2"; + var card = result.cards[0]; + target.showCards(card, get.translation(target) + "因【强识】展示"); + player.storage.qiangzhi_draw = get.type(card, "trick"); + game.addVideo("storage", player, ["qiangzhi_draw", player.storage.qiangzhi_draw]); + player.addTempSkill("qiangzhi_draw", "phaseUseEnd"); }, }, - qiangzhi_draw:{ - trigger:{player:'useCard'}, - frequent:true, - popup:false, - charlotte:true, - prompt:'是否执行【强识】的效果摸一张牌?', - filter:function(event,player){ - return get.type(event.card,'trick')==player.storage.qiangzhi_draw; + qiangzhi_draw: { + trigger: { player: "useCard" }, + frequent: true, + popup: false, + charlotte: true, + prompt: "是否执行【强识】的效果摸一张牌?", + filter: function (event, player) { + return get.type(event.card, "trick") == player.storage.qiangzhi_draw; }, - content:function(){ + content: function () { player.draw(); }, - onremove:true, - mark:true, - intro:{ - content:function(type){ - return get.translation(type)+'牌'; - } + onremove: true, + mark: true, + intro: { + content: function (type) { + return get.translation(type) + "牌"; + }, }, }, - dingpin:{ - audio:2, - enable:'phaseUse', - onChooseToUse:function(event){ - if(event.type!='phase'||game.online) return; - var list=[],player=event.player; - player.getHistory('useCard',function(evt){ + dingpin: { + audio: 2, + enable: "phaseUse", + onChooseToUse: function (event) { + if (event.type != "phase" || game.online) return; + var list = [], + player = event.player; + player.getHistory("useCard", function (evt) { list.add(get.type2(evt.card)); }); - player.getHistory('lose',function(evt){ - if(evt.type!='discard') return; - for(var i of evt.cards2){ - list.add(get.type2(i,evt.hs.includes(i)?player:false)); + player.getHistory("lose", function (evt) { + if (evt.type != "discard") return; + for (var i of evt.cards2) { + list.add(get.type2(i, evt.hs.includes(i) ? player : false)); } - }) - event.set('dingpin_types',list); + }); + event.set("dingpin_types", list); }, - filter:function(event,player){ - var list=event.dingpin_types||[]; - return player.countCards('he',function(card){ - return !list.includes(get.type2(card)); - })>0; + filter: function (event, player) { + var list = event.dingpin_types || []; + return ( + player.countCards("he", function (card) { + return !list.includes(get.type2(card)); + }) > 0 + ); }, - filterCard:function(card){ - var list=_status.event.dingpin_types||[]; + filterCard: function (card) { + var list = _status.event.dingpin_types || []; return !list.includes(get.type2(card)); }, - position:'he', - filterTarget:function(card,player,target){ - return !target.hasSkill('dingpin2'); + position: "he", + filterTarget: function (card, player, target) { + return !target.hasSkill("dingpin2"); }, - content:function(){ - 'step 0' - target.judge(function(card){ - var evt=_status.event.getParent('dingpin'),color=get.color(card); - switch(color){ - case 'black':return evt.target.getDamagedHp(); - case 'red':return get.sgn(get.attitude(evt.target,evt.player))*-3; + content: function () { + "step 0"; + target.judge(function (card) { + var evt = _status.event.getParent("dingpin"), + color = get.color(card); + switch (color) { + case "black": + return evt.target.getDamagedHp(); + case "red": + return get.sgn(get.attitude(evt.target, evt.player)) * -3; } return 0; - }).judge2=function(result){ - if(result.color=='black') return true; + }).judge2 = function (result) { + if (result.color == "black") return true; return false; }; - 'step 1' - switch(result.color){ - case 'black': - if(target.getDamagedHp()>0) target.draw(target.getDamagedHp()); - target.addTempSkill('dingpin2'); + "step 1"; + switch (result.color) { + case "black": + if (target.getDamagedHp() > 0) target.draw(target.getDamagedHp()); + target.addTempSkill("dingpin2"); break; - case 'red': + case "red": player.turnOver(); break; } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(player.isTurnedOver()) return target.getDamagedHp(); - var card=ui.cardPile.firstChild; - if(!card) return; - if(get.color(card)=='black') return target.getDamagedHp(); + ai: { + order: 9, + result: { + target: function (player, target) { + if (player.isTurnedOver()) return target.getDamagedHp(); + var card = ui.cardPile.firstChild; + if (!card) return; + if (get.color(card) == "black") return target.getDamagedHp(); return 0; }, }, }, }, - dingpin2:{charlotte:true}, - faen:{ - audio:2, - trigger:{global:['turnOverAfter','linkAfter']}, - filter:function(event,player){ - if(event.name=='link') return event.player.isLinked(); + dingpin2: { charlotte: true }, + faen: { + audio: 2, + trigger: { global: ["turnOverAfter", "linkAfter"] }, + filter: function (event, player) { + if (event.name == "link") return event.player.isLinked(); return !event.player.isTurnedOver(); }, - check:function(event,player){ - return get.attitude(player,event.player)>0; + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.player.draw(); }, - ai:{ - expose:0.2 - } - }, - jiaojin:{ - audio:2, - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})&&event.source&&event.source.hasSex('male'); + ai: { + expose: 0.2, }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he','骄矜:是否弃置一张装备牌令伤害-1?',function(card,player){ - return get.type(card)=='equip'; - }); - next.set('ai',function(card){ - var player=_status.event.player; - if(player.hp==1||_status.event.getTrigger().num>1){ - return 9-get.value(card); + }, + jiaojin: { + audio: 2, + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + return ( + player.countCards("he", { type: "equip" }) && + event.source && + event.source.hasSex("male") + ); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "骄矜:是否弃置一张装备牌令伤害-1?", + function (card, player) { + return get.type(card) == "equip"; } - if(player.hp==2){ - return 8-get.value(card); + ); + next.set("ai", function (card) { + var player = _status.event.player; + if (player.hp == 1 || _status.event.getTrigger().num > 1) { + return 9 - get.value(card); } - return 7-get.value(card); + if (player.hp == 2) { + return 8 - get.value(card); + } + return 7 - get.value(card); }); - next.logSkill='jiaojin'; - "step 1" - if(result.bool){ + next.logSkill = "jiaojin"; + "step 1"; + if (result.bool) { game.delay(0.5); trigger.num--; } - } + }, }, - chanhui:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - if(player.hasSkill('chanhui2')) return false; - if(event.targets.length>1) return false; - var card=event.card; - if(card.name=='sha') return true; - if(get.color(card)=='black'&&get.type(card)=='trick') return true; + chanhui: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + if (_status.currentPhase != player) return false; + if (player.hasSkill("chanhui2")) return false; + if (event.targets.length > 1) return false; + var card = event.card; + if (card.name == "sha") return true; + if (get.color(card) == "black" && get.type(card) == "trick") return true; return false; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('chanhui'),function(card,player,target){ - if(player==target) return false; - var evt=_status.event.getTrigger(); - return !evt.targets.includes(target)&&lib.filter.targetEnabled2(evt.card,player,target)&&lib.filter.targetInRange(evt.card,player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)+0.01; - }); - "step 1" - if(result.bool){ - event.target=result.targets[0]; - } - else{ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("chanhui"), function (card, player, target) { + if (player == target) return false; + var evt = _status.event.getTrigger(); + return ( + !evt.targets.includes(target) && + lib.filter.targetEnabled2(evt.card, player, target) && + lib.filter.targetInRange(evt.card, player, target) + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player) + 0.01; + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + } else { event.finish(); } - "step 2" - player.addTempSkill('chanhui2'); - player.logSkill('chanhui',event.target); - event.target.chooseCard('交给'+get.translation(player)+'一张手牌,或成为'+ - get.translation(trigger.card)+'的额外目标').set('ai',function(card){ - return 5-get.value(card); - }); - "step 3" - if(result.bool){ - target.give(result.cards,player); + "step 2"; + player.addTempSkill("chanhui2"); + player.logSkill("chanhui", event.target); + event.target + .chooseCard( + "交给" + + get.translation(player) + + "一张手牌,或成为" + + get.translation(trigger.card) + + "的额外目标" + ) + .set("ai", function (card) { + return 5 - get.value(card); + }); + "step 3"; + if (result.bool) { + target.give(result.cards, player); trigger.untrigger(); - trigger.getParent().player=event.target; - game.log(event.target,'成为了',trigger.card,'的使用者'); - } - else{ - game.log(event.target,'成为了',trigger.card,'的额外目标'); + trigger.getParent().player = event.target; + game.log(event.target, "成为了", trigger.card, "的使用者"); + } else { + game.log(event.target, "成为了", trigger.card, "的额外目标"); trigger.getParent().targets.push(event.target); } - } + }, }, - rechanhui:{ - audio:2, - trigger:{player:'useCardToPlayer'}, - filter:function(event,player){ - if(player.hasSkill('rechanhui2')) return false; - if(event.targets.length>1) return false; - var card=event.card; - if(card.name=='sha'||get.type(card)=='trick') return true; + rechanhui: { + audio: 2, + trigger: { player: "useCardToPlayer" }, + filter: function (event, player) { + if (player.hasSkill("rechanhui2")) return false; + if (event.targets.length > 1) return false; + var card = event.card; + if (card.name == "sha" || get.type(card) == "trick") return true; return false; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('rechanhui'),function(card,player,target){ - if(player==target) return false; - var trigger=_status.event; - return player.canUse(trigger.card,target,false)&&trigger.targets.includes(target)==false; - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)+0.01; - }).set('targets',trigger.targets).set('card',trigger.card); - "step 1" - if(result.bool){ + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("rechanhui"), function (card, player, target) { + if (player == target) return false; + var trigger = _status.event; + return ( + player.canUse(trigger.card, target, false) && + trigger.targets.includes(target) == false + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player) + 0.01; + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { //game.delay(0,200); - event.target=result.targets[0]; - } - else{ + event.target = result.targets[0]; + } else { event.finish(); } - "step 2" - player.logSkill('rechanhui',event.target); - event.target.chooseCard('交给'+get.translation(player)+'一张牌,或成为'+ - get.translation(trigger.card)+'的额外目标','he').set('ai',function(card){ - return 5-get.value(card); - }); - "step 3" - if(result.bool){ - target.give(result.cards,player); + "step 2"; + player.logSkill("rechanhui", event.target); + event.target + .chooseCard( + "交给" + + get.translation(player) + + "一张牌,或成为" + + get.translation(trigger.card) + + "的额外目标", + "he" + ) + .set("ai", function (card) { + return 5 - get.value(card); + }); + "step 3"; + if (result.bool) { + target.give(result.cards, player); trigger.untrigger(); - trigger.getParent().player=event.target; - game.log(event.target,'成为了',trigger.card,'的使用者'); - } - else{ - game.log(event.target,'成为了',trigger.card,'的额外目标'); + trigger.getParent().player = event.target; + game.log(event.target, "成为了", trigger.card, "的使用者"); + } else { + game.log(event.target, "成为了", trigger.card, "的额外目标"); trigger.getParent().targets.push(event.target); - player.addTempSkill('rechanhui2'); + player.addTempSkill("rechanhui2"); } - } - }, - rechanhui2:{charlotte:true}, - rejiaojin2:{charlotte:true}, - rejiaojin:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return (event.card.name=='sha'||get.type(event.card)=='trick')&&event.player!=player&&player.countCards('he',function(card){ - return _status.connectMode||get.type(card)=='equip'; - })&&!player.hasSkill('rejiaojin2'); }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he','骄矜:是否弃置一张装备牌令'+get.translation(trigger.card)+'对你无效?',function(card,player){ - return get.type(card)=='equip'; - }); - next.set('ai',function(card){ - if(_status.event.goon2){ - return 3+_status.event.val-get.value(card); + }, + rechanhui2: { charlotte: true }, + rejiaojin2: { charlotte: true }, + rejiaojin: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return ( + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.player != player && + player.countCards("he", function (card) { + return _status.connectMode || get.type(card) == "equip"; + }) && + !player.hasSkill("rejiaojin2") + ); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "骄矜:是否弃置一张装备牌令" + get.translation(trigger.card) + "对你无效?", + function (card, player) { + return get.type(card) == "equip"; + } + ); + next.set("ai", function (card) { + if (_status.event.goon2) { + return 3 + _status.event.val - get.value(card); } return 0; }); - next.set('val',get.value(trigger.cards.filterInD())); - next.set('goon2',get.effect(player,trigger.card,trigger.player,player)<0) - next.logSkill=['rejiaojin',trigger.player]; - "step 1" - if(result.bool){ - var cards=trigger.cards.filterInD(); - if(cards.length) player.gain(cards,'gain2','log'); + next.set("val", get.value(trigger.cards.filterInD())); + next.set("goon2", get.effect(player, trigger.card, trigger.player, player) < 0); + next.logSkill = ["rejiaojin", trigger.player]; + "step 1"; + if (result.bool) { + var cards = trigger.cards.filterInD(); + if (cards.length) player.gain(cards, "gain2", "log"); trigger.excluded.push(player); - if(trigger.player.hasSex('female')) player.addTempSkill('rejiaojin2') + if (trigger.player.hasSex("female")) player.addTempSkill("rejiaojin2"); } - } - }, - chanhui2:{}, - quanji:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - locked:false, - notemp:true, - filter:function(event){ - return event.num>0; }, - content:function(){ - "step 0" - event.count=trigger.num; - "step 1" + }, + chanhui2: {}, + quanji: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + locked: false, + notemp: true, + filter: function (event) { + return event.num > 0; + }, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; player.draw(); - "step 2" - if(player.countCards('h')){ - player.chooseCard('将一张手牌置于武将牌上作为“权”',true); - } - else{ + "step 2"; + if (player.countCards("h")) { + player.chooseCard("将一张手牌置于武将牌上作为“权”", true); + } else { event.goto(4); } - "step 3" - if(result.cards&&result.cards.length){ - player.addToExpansion(result.cards,player,'giveAuto').gaintag.add('quanji'); + "step 3"; + if (result.cards && result.cards.length) { + player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("quanji"); } - "step 4" - if(event.count>0&&player.hasSkill(event.name)&&!get.is.blocked(event.name,player)){ - player.chooseBool(get.prompt2('quanji')).set('frequentSkill',event.name); - } - else event.finish(); - "step 5" - if(result.bool){ - player.logSkill('quanji'); + "step 4"; + if ( + event.count > 0 && + player.hasSkill(event.name) && + !get.is.blocked(event.name, player) + ) { + player.chooseBool(get.prompt2("quanji")).set("frequentSkill", event.name); + } else event.finish(); + "step 5"; + if (result.bool) { + player.logSkill("quanji"); event.goto(1); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - mod:{ - maxHandcard:function(player,num){ - return num+player.getExpansions('quanji').length; - } - }, - ai:{ - maixie:true, - maixie_hp:true, - threaten:0.8, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [0.5,get.tag(card,'damage')*2]; - if(!target.hasSkill('paiyi')&&target.hp>1) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==3) return [0.5,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; - } - } - } - } - }, - zili:{ - skillAnimation:true, - animationColor:'thunder', - audio:2, - audioname:['re_zhonghui'], - unique:true, - juexingji:true, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - derivation:'paiyi', - filter:function(event,player){ - return !player.hasSkill('paiyi')&&player.getExpansions('quanji').length>=3; - }, - content:function(){ - "step 0" - player.awakenSkill('zili'); - player.chooseDrawRecover(2,true,function(event,player){ - if(player.hp==1&&player.isDamaged()) return 'recover_hp'; - return 'draw_card'; - }); - "step 1" - player.loseMaxHp(); - player.addSkills('paiyi'); - } - }, - paiyi:{ - enable:'phaseUse', - usable:1, - audio:2, - audioname:['re_zhonghui'], - filter:function(event,player){ - return player.getExpansions('quanji').length>0; - }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('排异',player.getExpansions('quanji'),'hidden') + mod: { + maxHandcard: function (player, num) { + return num + player.getExpansions("quanji").length; }, - backup:function(links,player){ + }, + ai: { + maixie: true, + maixie_hp: true, + threaten: 0.8, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [0.5, get.tag(card, "damage") * 2]; + if (!target.hasSkill("paiyi") && target.hp > 1) + return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 3) return [0.5, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; + } + }, + }, + }, + }, + zili: { + skillAnimation: true, + animationColor: "thunder", + audio: 2, + audioname: ["re_zhonghui"], + unique: true, + juexingji: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + derivation: "paiyi", + filter: function (event, player) { + return !player.hasSkill("paiyi") && player.getExpansions("quanji").length >= 3; + }, + content: function () { + "step 0"; + player.awakenSkill("zili"); + player.chooseDrawRecover(2, true, function (event, player) { + if (player.hp == 1 && player.isDamaged()) return "recover_hp"; + return "draw_card"; + }); + "step 1"; + player.loseMaxHp(); + player.addSkills("paiyi"); + }, + ai: { + combo: "quanji", + }, + }, + paiyi: { + enable: "phaseUse", + usable: 1, + audio: 2, + audioname: ["re_zhonghui"], + filter: function (event, player) { + return player.getExpansions("quanji").length > 0; + }, + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("排异", player.getExpansions("quanji"), "hidden"); + }, + backup: function (links, player) { return { - audio:'paiyi', - audioname:['re_zhonghui'], - filterTarget:true, - filterCard:function(){return false}, - selectCard:-1, - card:links[0], - delay:false, - content:lib.skill.paiyi.contentx, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(player!=target) return 0; - if(player.hasSkill('requanji')||(player.countCards('h')+2<=player.hp+player.getExpansions('quanji').length)) return 1; + audio: "paiyi", + audioname: ["re_zhonghui"], + filterTarget: true, + filterCard: function () { + return false; + }, + selectCard: -1, + card: links[0], + delay: false, + content: lib.skill.paiyi.contentx, + ai: { + order: 10, + result: { + target: function (player, target) { + if (player != target) return 0; + if ( + player.hasSkill("requanji") || + player.countCards("h") + 2 <= + player.hp + player.getExpansions("quanji").length + ) + return 1; return 0; - } + }, }, }, - } + }; + }, + prompt: function () { + return "请选择〖排异〗的目标"; }, - prompt:function(){return '请选择〖排异〗的目标'}, }, - contentx:function(){ - "step 0" - var card=lib.skill.paiyi_backup.card; + contentx: function () { + "step 0"; + var card = lib.skill.paiyi_backup.card; player.loseToDiscardpile(card); - "step 1" + "step 1"; target.draw(2); - "step 2" - if(target.countCards('h')>player.countCards('h')){ + "step 2"; + if (target.countCards("h") > player.countCards("h")) { target.damage(); } }, - ai:{ - order:1, - combo:'quanji', - result:{ - player:1, - } - } + ai: { + order: 1, + combo: "quanji", + result: { + player: 1, + }, + }, }, - xianzhou:{ - skillAnimation:true, - animationColor:'gray', - audio:2, - audioname:['xin_caifuren'], - unique:true, - limited:true, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('e')>0; + xianzhou: { + skillAnimation: true, + animationColor: "gray", + audio: 2, + audioname: ["xin_caifuren"], + unique: true, + limited: true, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("e") > 0; }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - mark:true, - delay:false, - content:function(){ - "step 0" - player.awakenSkill('xianzhou'); - var cards=player.getCards('e'); - player.give(cards,target); - event.num=cards.length; + mark: true, + delay: false, + content: function () { + "step 0"; + player.awakenSkill("xianzhou"); + var cards = player.getCards("e"); + player.give(cards, target); + event.num = cards.length; game.delay(); - "step 1" - target.chooseTarget([1,event.num],'令'+get.translation(player)+'回复'+ - event.num+'点体力,或对攻击范围内的'+event.num+'名角色造成1点伤害',function(card,player,target2){ - return _status.event.player.inRange(target2); - }).set('ai',function(target2){ - var target=_status.event.player; - var player=_status.event.getParent().player; - if(get.attitude(target,player)>0){ - if(player.hp+event.num<=player.maxHp||player.hp==1) return -1; - } - return get.damageEffect(target2,target,target); - }); - "step 2" - if(result.bool){ - target.line(result.targets,'green'); - event.targets=result.targets; - event.num2=0; - } - else{ + "step 1"; + target + .chooseTarget( + [1, event.num], + "令" + + get.translation(player) + + "回复" + + event.num + + "点体力,或对攻击范围内的" + + event.num + + "名角色造成1点伤害", + function (card, player, target2) { + return _status.event.player.inRange(target2); + } + ) + .set("ai", function (target2) { + var target = _status.event.player; + var player = _status.event.getParent().player; + if (get.attitude(target, player) > 0) { + if (player.hp + event.num <= player.maxHp || player.hp == 1) return -1; + } + return get.damageEffect(target2, target, target); + }); + "step 2"; + if (result.bool) { + target.line(result.targets, "green"); + event.targets = result.targets; + event.num2 = 0; + } else { player.recover(event.num); event.finish(); } - "step 3" - if(event.num22&&get.attitude(players[i],player)>2){ - bool=false;break; + ai: { + order: 1, + result: { + target: 1, + player: function (player) { + var bool = true, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + get.attitude(player, players[i]) > 2 && + get.attitude(players[i], player) > 2 + ) { + bool = false; + break; } } - if(bool) return -10; - if(player.hp==1) return 1; - if(game.phaseNumber0){ - return '移动装备'; + if ( + trigger.player.hasCard(function (card) { + return player.canEquip(card); + }, "e") + ) { + next = player + .chooseControl("移动装备", "draw_card", "cancel2", function (event, player) { + var source = _status.event.sourcex; + var att = get.attitude(player, source); + if (source.hasSkillTag("noe")) { + if (att > 0) { + return "移动装备"; + } + } else { + if ( + att <= 0 && + source.countCards("e", function (card) { + return ( + get.value(card, source) > 0 && + get.effect(player, card, player, player) > 0 + ); + }) + ) { + return "移动装备"; + } } - } - else{ - if(att<=0&&source.countCards('e',function(card){ - return get.value(card,source)>0&&get.effect(player,card,player,player)>0; - })){ - return '移动装备'; - } - } - return 'draw_card'; - }).set('sourcex',trigger.player); - } - else{ - next=player.chooseControl('draw_card','cancel2',function(){ - return 'draw_card'; + return "draw_card"; + }) + .set("sourcex", trigger.player); + } else { + next = player.chooseControl("draw_card", "cancel2", function () { + return "draw_card"; }); } - next.set('prompt',get.prompt('qieting',trigger.player)); - "step 1" - if(result.control=='移动装备'){ - player.logSkill('qieting',trigger.player); - player.choosePlayerCard(trigger.player,'e','将一张装备牌移至你的装备区',true).set('filterButton',function(button){ - return _status.event.player.canEquip(button.link); - }).set('ai',function(button){ - return get.effect(player,button.link,player,player); - }); - } - else{ - if(result.control=='draw_card'){ - player.logSkill('qieting'); + next.set("prompt", get.prompt("qieting", trigger.player)); + "step 1"; + if (result.control == "移动装备") { + player.logSkill("qieting", trigger.player); + player + .choosePlayerCard(trigger.player, "e", "将一张装备牌移至你的装备区", true) + .set("filterButton", function (button) { + return _status.event.player.canEquip(button.link); + }) + .set("ai", function (button) { + return get.effect(player, button.link, player, player); + }); + } else { + if (result.control == "draw_card") { + player.logSkill("qieting"); player.draw(); } event.finish(); } - "step 2" - if(result&&result.links&&result.links.length){ + "step 2"; + if (result && result.links && result.links.length) { game.delay(2); - trigger.player.$give(result.links[0],player,false); + trigger.player.$give(result.links[0], player, false); player.equip(result.links[0]); player.addExpose(0.2); } }, }, - oldzhuikong:{ - audio:'zhuikong', - inherit:'zhuikong', + oldzhuikong: { + audio: "zhuikong", + inherit: "zhuikong", }, - zhuikong:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - check:function(event,player){ - if(get.attitude(player,event.player)<-2){ - var cards=player.getCards('h'); - if(cards.length>player.hp) return true; - for(var i=0;i9&&useful<7) return true; + zhuikong: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + check: function (event, player) { + if (get.attitude(player, event.player) < -2) { + var cards = player.getCards("h"); + if (cards.length > player.hp) return true; + for (var i = 0; i < cards.length; i++) { + var useful = get.useful(cards[i]); + if (useful < 5) return true; + if (get.number(cards[i]) > 9 && useful < 7) return true; } } return false; }, - logTarget:'player', - filter:function(event,player){ - return player.hp0&&lib.filter.targetEnabled(event.card,event.player,current); - }); + oldqiuyuan: { + audio: "qiuyuan", + inherit: "qiuyuan", + filter: function (event, player) { + return ( + event.card.name == "sha" && + game.hasPlayer(function (current) { + return ( + current != player && + !event.targets.includes(current) && + current.countCards("h") > 0 && + lib.filter.targetEnabled(event.card, event.player, current) + ); + }) + ); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('oldqiuyuan'),function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&!evt.targets.includes(target)&&lib.filter.targetEnabled(evt.card,evt.player,target)&&target.countCards('h')>0; - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,trigger.player,player)+0.1; - }).set('targets',trigger.targets).set('playerx',trigger.player); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('oldqiuyuan',target); - event.target=target; - target.chooseCard('交给'+get.translation(player)+ - '一张牌,若此牌不为【闪】,则也成为此杀的额外目标',true).set('ai',function(card){ - return -get.value(card,player,'raw'); - }).set('sourcex',player); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("oldqiuyuan"), function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled(evt.card, evt.player, target) && + target.countCards("h") > 0 + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, trigger.player, player) + 0.1; + }) + .set("targets", trigger.targets) + .set("playerx", trigger.player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("oldqiuyuan", target); + event.target = target; + target + .chooseCard( + "交给" + + get.translation(player) + + "一张牌,若此牌不为【闪】,则也成为此杀的额外目标", + true + ) + .set("ai", function (card) { + return -get.value(card, player, "raw"); + }) + .set("sourcex", player); game.delay(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ - target.give(result.cards,player,'give'); - if(get.name(result.cards[0])!='shan'){ + "step 2"; + if (result.bool) { + target.give(result.cards, player, "give"); + if (get.name(result.cards[0]) != "shan") { trigger.getParent().targets.push(event.target); trigger.getParent().triggeredTargets2.push(event.target); - game.log(event.target,'成为了额外目标'); + game.log(event.target, "成为了额外目标"); } game.delay(); } }, }, - qiuyuan:{ - audio:2, - trigger:{target:'useCardToTarget'}, - direct:true, - filter:function(event,player){ - return event.card.name=='sha'&&game.hasPlayer(function(current){ - return current!=player&&!event.targets.includes(current)&&lib.filter.targetEnabled(event.card,event.player,current); - }); + qiuyuan: { + audio: 2, + trigger: { target: "useCardToTarget" }, + direct: true, + filter: function (event, player) { + return ( + event.card.name == "sha" && + game.hasPlayer(function (current) { + return ( + current != player && + !event.targets.includes(current) && + lib.filter.targetEnabled(event.card, event.player, current) + ); + }) + ); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('qiuyuan'),function(card,player,target){ - var evt=_status.event.getTrigger(); - return target!=player&&!evt.targets.includes(target)&&lib.filter.targetEnabled(evt.card,evt.player,target); - }).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,trigger.player,player)+0.1; - }).set('targets',trigger.targets).set('playerx',trigger.player); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qiuyuan',target); - event.target=target; - target.chooseCard({name:'shan'},'交给'+get.translation(player)+ - '一张闪,或成为此杀的额外目标').set('ai',function(card){ - return get.attitude(target,_status.event.sourcex)>=0?1:-1; - }).set('sourcex',player); + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("qiuyuan"), function (card, player, target) { + var evt = _status.event.getTrigger(); + return ( + target != player && + !evt.targets.includes(target) && + lib.filter.targetEnabled(evt.card, evt.player, target) + ); + }) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, trigger.player, player) + 0.1; + }) + .set("targets", trigger.targets) + .set("playerx", trigger.player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qiuyuan", target); + event.target = target; + target + .chooseCard( + { name: "shan" }, + "交给" + get.translation(player) + "一张闪,或成为此杀的额外目标" + ) + .set("ai", function (card) { + return get.attitude(target, _status.event.sourcex) >= 0 ? 1 : -1; + }) + .set("sourcex", player); game.delay(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.bool){ - target.give(result.cards,player); + "step 2"; + if (result.bool) { + target.give(result.cards, player); game.delay(); - } - else{ + } else { trigger.getParent().targets.push(event.target); trigger.getParent().triggeredTargets2.push(event.target); - game.log(event.target,'成为了额外目标'); + game.log(event.target, "成为了额外目标"); } }, - ai:{ - expose:0.2, - effect:{ - target:function(card,player,target){ - if(card.name!='sha') return; - var players=game.filterPlayer(); - if(get.attitude(player,target)<=0){ - for(var i=0;i0&& - get.effect(target2,{name:'shacopy',nature:card.nature,suit:card.suit},player,player)<0){ - if(target.hp==target.maxHp) return 0.3; + ai: { + expose: 0.2, + effect: { + target: function (card, player, target) { + if (card.name != "sha") return; + var players = game.filterPlayer(); + if (get.attitude(player, target) <= 0) { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + target + ) > 0 && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) < 0 + ) { + if (target.hp == target.maxHp) return 0.3; return 0.6; } } - } - else{ - for(var i=0;i0){ - if(player.canUse(card,target2)) return; - if(target.hp==target.maxHp) return [0,1]; - return [0,0]; + } else { + for (var i = 0; i < players.length; i++) { + var target2 = players[i]; + if ( + player != target2 && + target != target2 && + player.canUse(card, target2, false) && + get.effect( + target2, + { name: "shacopy", nature: card.nature, suit: card.suit }, + player, + player + ) > 0 + ) { + if (player.canUse(card, target2)) return; + if (target.hp == target.maxHp) return [0, 1]; + return [0, 0]; } } } - } - } - } - }, - gongji:{ - enable:'phaseUse', - usable:1, - audio:2, - position:'he', - filterCard:true, - check:function(card){ - if(get.type(card)!='equip') return 0; - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); - } - return 6-get.equipValue(card); + }, + }, }, - content:function(){ - "step 0" - player.addTempSkill('gongji2'); - "step 1" - if(get.type(cards[0],null,cards[0].original=='h'?player:false)=='equip'){ - player.chooseTarget('是否弃置一名角色的一张牌?',function(card,player,target){ - return player!=target&&target.countCards('he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - if(get.attitude(player,target)<0){ - return Math.max(0.5,get.effect(target,{name:'sha'},player,player)); - } - return 0; - }); + }, + gongji: { + enable: "phaseUse", + usable: 1, + audio: 2, + position: "he", + filterCard: true, + check: function (card) { + if (get.type(card) != "equip") return 0; + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); } - else{ + return 6 - get.equipValue(card); + }, + content: function () { + "step 0"; + player.addTempSkill("gongji2"); + "step 1"; + if (get.type(cards[0], null, cards[0].original == "h" ? player : false) == "equip") { + player + .chooseTarget("是否弃置一名角色的一张牌?", function (card, player, target) { + return player != target && target.countCards("he") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player; + if (get.attitude(player, target) < 0) { + return Math.max(0.5, get.effect(target, { name: "sha" }, player, player)); + } + return 0; + }); + } else { event.finish(); } - "step 2" - if(result.bool){ - player.line(result.targets,'green'); - event.target=result.targets[0]; - player.discardPlayerCard(event.target,'he',true).ai=get.buttonValue; + "step 2"; + if (result.bool) { + player.line(result.targets, "green"); + event.target = result.targets[0]; + player.discardPlayerCard(event.target, "he", true).ai = get.buttonValue; } }, - ai:{ - order:9, - result:{ - player:1 - } - } + ai: { + order: 9, + result: { + player: 1, + }, + }, }, - gongji2:{ - mod:{ - attackRangeBase:function(){ + gongji2: { + mod: { + attackRangeBase: function () { return Infinity; }, }, }, - zhuiyi:{ - audio:2, - audioname:['re_bulianshi'], - trigger:{player:'die'}, - direct:true, - skillAnimation:true, - animationColor:'wood', - forceDie:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('zhuiyi'),function(card,player,target){ - return player!=target&&_status.event.sourcex!=target; - }).set('forceDie',true).set('ai',function(target){ - var num=get.attitude(_status.event.player,target); - if(num>0){ - if(target.hp==1){ - num+=2; + zhuiyi: { + audio: 2, + audioname: ["re_bulianshi"], + trigger: { player: "die" }, + direct: true, + skillAnimation: true, + animationColor: "wood", + forceDie: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("zhuiyi"), function (card, player, target) { + return player != target && _status.event.sourcex != target; + }) + .set("forceDie", true) + .set("ai", function (target) { + var num = get.attitude(_status.event.player, target); + if (num > 0) { + if (target.hp == 1) { + num += 2; + } + if (target.hp < target.maxHp) { + num += 2; + } } - if(target.hpplayers[i].countCards('h')) return true; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (num > players[i].countCards("h")) return true; } return false; }, - selectTarget:2, - content:function(){ - 'step 0' - var gainner,giver; - if(targets[0].countCards('h')0) return -1; - var players=game.filterPlayer(); - for(var i=0;i0) return -3; + ai: { + order: 10.5, + threaten: 2.3, + result: { + target: function (player, target) { + var num = target.countCards("h"); + var att = get.attitude(player, target); + if (ui.selected.targets.length == 0) { + if (att > 0) return -1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var num2 = players[i].countCards("h"); + var att2 = get.attitude(player, players[i]); + if (num2 < num) { + if (att2 > 0) return -3; return -1; } } return 0; - } - else{ + } else { return 1; } }, - player:1, - } - } + player: 1, + }, + }, }, - anxu:{ - enable:'phaseUse', - usable:1, - multitarget:true, - audio:2, - filterTarget:function(card,player,target){ - if(player==target) return false; - var num=target.countCards('h'); - if(ui.selected.targets.length){ - return numplayers[i].countCards('h')) return true; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (num > players[i].countCards("h")) return true; } return false; }, - selectTarget:2, - content:function(){ - 'step 0' - var gainner,giver; - if(targets[0].countCards('h')0) return -1; - var players=game.filterPlayer(); - for(var i=0;i=0&&num2 0) return -1; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + var num2 = players[i].countCards("h"); + var att2 = get.attitude(player, players[i]); + if (att2 >= 0 && num2 < num) return -1; } return 0; - } - else{ + } else { return 1; } }, - player:0.1 - } - } + player: 0.1, + }, + }, }, - mingce:{ - enable:'phaseUse', - usable:1, - audio:2, - position:'he', - filterCard:function(card){ - return get.name(card)=='sha'||get.type(card)=='equip'; + mingce: { + enable: "phaseUse", + usable: 1, + audio: 2, + position: "he", + filterCard: function (card) { + return get.name(card) == "sha" || get.type(card) == "equip"; }, - filter:function(event,player){ - return player.countCards('h','sha')>0||player.countCards('he',{type:'equip'})>0; + filter: function (event, player) { + return ( + player.countCards("h", "sha") > 0 || player.countCards("he", { type: "equip" }) > 0 + ); }, - check:function(card){return 8-get.value(card)}, - selectTarget:2, - multitarget:true, - discard:false, - lose:false, - targetprompt:['得到牌','出杀目标'], - filterTarget:function(card,player,target){ - if(ui.selected.targets.length==0){ - return player!=target; - } - else{ + check: function (card) { + return 8 - get.value(card); + }, + selectTarget: 2, + multitarget: true, + discard: false, + lose: false, + targetprompt: ["得到牌", "出杀目标"], + filterTarget: function (card, player, target) { + if (ui.selected.targets.length == 0) { + return player != target; + } else { return ui.selected.targets[0].inRange(target); } }, - delay:false, - content:function(){ - "step 0" - player.give(cards,targets[0],'visible'); - "step 1" - if(!lib.filter.filterTarget({name:'sha',isCard:true},targets[0],targets[1])) event._result={control:'draw_card'}; - else targets[0].chooseControl('draw_card','出杀',function(){ - var player=_status.event.player; - var target=_status.event.target; - if(get.effect(_status.event.target,{name:'sha'},player,player)>0){ - return 1; - } - return 0; - }).set('target',targets[1]).set('prompt','对'+get.translation(targets[1])+'使用一张杀,或摸一张牌'); - "step 2" - if(result.control=='draw_card'){ + delay: false, + content: function () { + "step 0"; + player.give(cards, targets[0], "visible"); + "step 1"; + if (!lib.filter.filterTarget({ name: "sha", isCard: true }, targets[0], targets[1])) + event._result = { control: "draw_card" }; + else + targets[0] + .chooseControl("draw_card", "出杀", function () { + var player = _status.event.player; + var target = _status.event.target; + if (get.effect(_status.event.target, { name: "sha" }, player, player) > 0) { + return 1; + } + return 0; + }) + .set("target", targets[1]) + .set("prompt", "对" + get.translation(targets[1]) + "使用一张杀,或摸一张牌"); + "step 2"; + if (result.control == "draw_card") { targets[0].draw(); - } - else{ - targets[0].useCard({name:'sha',isCard:true},targets[1]); + } else { + targets[0].useCard({ name: "sha", isCard: true }, targets[1]); } }, - ai:{ - result:{ - player:function(player){ - var players=game.filterPlayer(); - for(var i=0;i1&&get.attitude(players[i],player)>1){ + ai: { + result: { + player: function (player) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + get.attitude(player, players[i]) > 1 && + get.attitude(players[i], player) > 1 + ) { return 1; } } return 0; }, - target:function(player,target){ - if(ui.selected.targets.length){ + target: function (player, target) { + if (ui.selected.targets.length) { return -0.1; } return 1; - } + }, }, - order:8.5, - expose:0.2 - } + order: 8.5, + expose: 0.2, + }, }, - xinxuanhuo:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - direct:true, - filter:function(event,player){ + xinxuanhuo: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + direct: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('xinxuanhuo'),function(card,player,target){ - return player!=target; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0){ - if(target.countCards('h') 0) { + if (target.countCards("h") < target.hp) att += 2; + return att - target.countCards("h") / 3; + } else { + return -1; + } + }); + "step 1"; + if (result.bool) { trigger.changeToZero(); - player.logSkill('xinxuanhuo',result.targets); - event.target=result.targets[0]; + player.logSkill("xinxuanhuo", result.targets); + event.target = result.targets[0]; event.target.draw(2); - } - else{ + } else { event.finish(); } - "step 2" - if(game.hasPlayer(function(current){ - return target.canUse('sha',current); - })) player.chooseTarget('选择出杀的目标',true,function(card,player,target){ - return _status.event.target.canUse('sha',target); - }).set('ai',function(target){ - return get.effect(target,{name:'sha'},_status.event.target,_status.event.player); - }).set('target',event.target); - "step 3" - if(result.bool&&result.targets.length){ - game.log(player,'指定的出杀目标为',result.targets); + "step 2"; + if ( + game.hasPlayer(function (current) { + return target.canUse("sha", current); + }) + ) + player + .chooseTarget("选择出杀的目标", true, function (card, player, target) { + return _status.event.target.canUse("sha", target); + }) + .set("ai", function (target) { + return get.effect( + target, + { name: "sha" }, + _status.event.target, + _status.event.player + ); + }) + .set("target", event.target); + "step 3"; + if (result.bool && result.targets.length) { + game.log(player, "指定的出杀目标为", result.targets); event.target.line(result.targets); - event.target.chooseToUse('对'+get.translation(result.targets)+'使用一张杀,或令'+get.translation(player)+'获得你的两张牌',{name:'sha'},result.targets[0],-1); + event.target.chooseToUse( + "对" + + get.translation(result.targets) + + "使用一张杀,或令" + + get.translation(player) + + "获得你的两张牌", + { name: "sha" }, + result.targets[0], + -1 + ); + } else { + event.bool = true; } - else{ - event.bool=true; - } - "step 4" - if(event.bool||result.bool==false){ - player.gainPlayerCard('he',event.target,Math.min(2,event.target.countCards('he')),true); + "step 4"; + if (event.bool || result.bool == false) { + player.gainPlayerCard( + "he", + event.target, + Math.min(2, event.target.countCards("he")), + true + ); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - zhichi:{ - audio:2, - trigger:{player:'damageEnd'}, - audioname:['re_chengong'], - forced:true, - filter:function(event,player){ - return _status.currentPhase!=player; + zhichi: { + audio: 2, + trigger: { player: "damageEnd" }, + audioname: ["re_chengong"], + forced: true, + filter: function (event, player) { + return _status.currentPhase != player; + }, + content: function () { + player.addTempSkill("zhichi2", ["phaseAfter", "phaseBefore"]); }, - content:function(){ - player.addTempSkill('zhichi2',['phaseAfter','phaseBefore']); - } }, - zhichi2:{ - trigger:{target:'useCardToBefore'}, - forced:true, - charlotte:true, - priority:15, - filter:function(event,player){ - return get.type(event.card)=='trick'||event.card.name=='sha'; + zhichi2: { + trigger: { target: "useCardToBefore" }, + forced: true, + charlotte: true, + priority: 15, + filter: function (event, player) { + return get.type(event.card) == "trick" || event.card.name == "sha"; }, - content:function(){ - game.log(player,'发动了智迟,',trigger.card,'对',trigger.target,'失效') + content: function () { + game.log(player, "发动了智迟,", trigger.card, "对", trigger.target, "失效"); trigger.cancel(); }, - mark:true, - intro:{ - content:'杀或普通锦囊牌对你无效' + mark: true, + intro: { + content: "杀或普通锦囊牌对你无效", + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "trick" || card.name == "sha") return "zeroplayertarget"; + }, + }, }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='trick'||card.name=='sha') return 'zeroplayertarget'; - } - } - } }, - zongxuan:{ - audio:2, - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + zongxuan: { + audio: 2, + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false) return; - var evt=event.getl(player); - for(var i=0;i0; - })) return false; - var evt=trigger.getl(player); - for(var i=0;i 0; + }) + ) + return false; + var evt = trigger.getl(player); + for (var i = 0; i < evt.cards2.length; i++) { + if ( + get.position(evt.cards2[i], true) == "d" && + get.type(evt.cards2[i], false) == "equip" + ) { return true; } } return false; }, - content:function(){ - "step 0" - var cards=[]; - var evt=trigger.getl(player); - for(var i=0;i0; + var next = player.chooseToMove("纵玄:将任意张牌置于牌堆顶", true); + next.set("list", [["本次弃置的牌", cards], ["牌堆顶"]]); + next.set("filterOk", function (moved) { + return moved[1].length > 0; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0),cards2=cards.filter(function(i){ - return get.type(i,false)=='equip'; - }),cards3; - if(cards2.length){ - cards3=cards2.randomGet(); - } - else cards3=cards.randomGet(); - return [[],[cards3]]; - }) - 'step 1' - if(result.bool){ - var cards=result.moved[1]; - game.log(player,'将',cards,'置于了牌堆顶'); - while(cards.length) ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild) + next.set("processAI", function (list) { + var cards = list[0][1].slice(0), + cards2 = cards.filter(function (i) { + return get.type(i, false) == "equip"; + }), + cards3; + if (cards2.length) { + cards3 = cards2.randomGet(); + } else cards3 = cards.randomGet(); + return [[], [cards3]]; + }); + "step 1"; + if (result.bool) { + var cards = result.moved[1]; + game.log(player, "将", cards, "置于了牌堆顶"); + while (cards.length) + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); } }, }, - zhiyan:{ - audio:2, - audioname:['gexuan','re_yufan'], - trigger:{player:'phaseJieshuBegin'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('zhiyan'),'令一名角色摸一张牌并展示之。若为装备牌,则其回复1点体力').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - "step 1" - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('zhiyan',result.targets); - event.bool=false; - event.target.draw('visible'); - } - else{ + zhiyan: { + audio: 2, + audioname: ["gexuan", "re_yufan"], + trigger: { player: "phaseJieshuBegin" }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhiyan"), + "令一名角色摸一张牌并展示之。若为装备牌,则其回复1点体力" + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("zhiyan", result.targets); + event.bool = false; + event.target.draw("visible"); + } else { event.finish(); } - "step 2" - var card=result[0]; - if(get.type(card)=='equip'){ - if(target.getCards('h').includes(card)&&target.hasUseTarget(card)){ - event.target.chooseUseTarget(card,true,'nopopup'); + "step 2"; + var card = result[0]; + if (get.type(card) == "equip") { + if (target.getCards("h").includes(card) && target.hasUseTarget(card)) { + event.target.chooseUseTarget(card, true, "nopopup"); game.delay(); } - event.bool=true; + event.bool = true; } - "step 3" - if(event.bool) target.recover(); + "step 3"; + if (event.bool) target.recover(); + }, + ai: { + expose: 0.2, + threaten: 1.2, }, - ai:{ - expose:0.2, - threaten:1.2 - } }, - miji:{ - audio:2, - audioname:['re_wangyi'], - locked:false, - 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; + miji: { + audio: 2, + audioname: ["re_wangyi"], + locked: false, + 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; } - } + }, }, - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hp player !== i); - cards.forEach(i => { - let o = get.value(i, player), max = o, temp, t; - tars.forEach(tar => { + bool: true, + cards: [], + }, + cards = player.getCards("he"), + tars = game.filterPlayer((i) => player !== i); + cards.forEach((i) => { + let o = get.value(i, player), + max = o, + temp, + t; + tars.forEach((tar) => { temp = get.value(i, tar); if (temp > max) { max = temp; @@ -11854,1737 +13941,1931 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if (t) res.cards.push([i, t, max - o]); }); if (res.cards.length < event.num) res.bool = false; - else if (res.cards.length > event.num) res.cards.sort((a, b) => { - return b[2] - a[2]; - }).slice(0, event.num); + else if (res.cards.length > event.num) + res.cards + .sort((a, b) => { + return b[2] - a[2]; + }) + .slice(0, event.num); return res; - }(); - 'step 1' + })(); + "step 1"; player.chooseCardTarget({ - filterCard(card){ - return get.itemtype(card)=='card'&&!card.hasGaintag('miji_tag'); + filterCard(card) { + return get.itemtype(card) == "card" && !card.hasGaintag("miji_tag"); }, filterTarget: lib.filter.notMe, - selectCard: [1,event.num], - prompt:'请选择要分配的卡牌和目标', + selectCard: [1, event.num], + prompt: "请选择要分配的卡牌和目标", forced: event._forcing, - ai1(card){ + ai1(card) { if (!_status.event.res.bool || ui.selected.cards.length) return 0; for (let arr of _status.event.res.cards) { if (arr[0] === card) return arr[2]; } return 0; }, - ai2(target){ + ai2(target) { let card = ui.selected.cards[0]; for (let arr of _status.event.res.cards) { if (arr[0] === card) return get.attitude(player, target); } - let val=target.getUseValue(card); - if(val>0) return val*get.attitude(player,target)*2; - return get.value(card,target)*get.attitude(player,target); + let val = target.getUseValue(card); + if (val > 0) return val * get.attitude(player, target) * 2; + return get.value(card, target) * get.attitude(player, target); }, - res: event.aicheck + res: event.aicheck, }); - 'step 2' - if(result.bool){ + "step 2"; + if (result.bool) { event._forcing = true; - var res=result.cards,target=result.targets[0].playerid; - player.addGaintag(res,'miji_tag'); - event.num-=res.length; - if(!event.given_map[target]) event.given_map[target]=[]; + var res = result.cards, + target = result.targets[0].playerid; + player.addGaintag(res, "miji_tag"); + event.num -= res.length; + if (!event.given_map[target]) event.given_map[target] = []; event.given_map[target].addArray(res); - if(event.num>0) event.goto(1); + if (event.num > 0) event.goto(1); } - 'step 3' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + "step 3"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var map=[],cards=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - if(player!==source&&(get.mode()!=='identity'||player.identity!=='nei')) player.addExpose(0.18); - map.push([source,event.given_map[i]]); + var map = [], + cards = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + if (player !== source && (get.mode() !== "identity" || player.identity !== "nei")) + player.addExpose(0.18); + map.push([source, event.given_map[i]]); cards.addArray(event.given_map[i]); } game.loseAsync({ - gain_list:map, - player:player, - cards:cards, - giver:player, - animate:'giveAuto', - }).setContent('gaincardMultiple'); + gain_list: map, + player: player, + cards: cards, + giver: player, + animate: "giveAuto", + }).setContent("gaincardMultiple"); }, - ai:{ - threaten:function(player,target){ - return 0.6+0.7*target.getDamagedHp(); + ai: { + threaten: function (player, target) { + return 0.6 + 0.7 * target.getDamagedHp(); }, - effect:{ - target:function(card,player,target){ - if(target.hp<=2&&get.tag(card,'damage')){ - var num=1; - if(get.itemtype(player)=='player'&&player.hasSkillTag('damageBonus',false,{ - target:target, - card:card - })&&!target.hasSkillTag('filterDamage',null,{ - player:player, - card:card - })) num=2; - if(target.hp>num) return [1,1]; + effect: { + target: function (card, player, target) { + if (target.hp <= 2 && get.tag(card, "damage")) { + var num = 1; + if ( + get.itemtype(player) == "player" && + player.hasSkillTag("damageBonus", false, { + target: target, + card: card, + }) && + !target.hasSkillTag("filterDamage", null, { + player: player, + card: card, + }) + ) + num = 2; + if (target.hp > num) return [1, 1]; } - } - } - } - }, - zhenlie:{ - audio:2, - audioname:['re_wangyi'], - filter:function(event,player){ - return event.player!=player&&event.card&&(event.card.name=='sha'||get.type(event.card)=='trick'); + }, + }, }, - logTarget:'player', - check:function(event,player){ - if(event.getParent().excluded.includes(player)) return false; - if(get.attitude(player,event.player)>0||player.hp<2&&!get.tag(event.card,'damage')) return false; - let evt=event.getParent(), - directHit=evt.nowuxie&&get.type(event.card,'trick')==='trick'||evt.directHit&&evt.directHit.includes(player)||evt.customArgs&&evt.customArgs.default&&evt.customArgs.default.directHit2; - if(get.tag(event.card,'respondSha')){ - if(directHit||player.countCards('h',{name:'sha'})===0) return true; - } - else if(get.tag(event.card,'respondShan')){ - if(directHit||player.countCards('h',{name:'shan'})===0) return true; - } - else if(get.tag(event.card,'damage')){ - if(event.card.name==='huogong') return event.player.countCards('h')>4-player.hp-player.hujia; - if(event.card.name==='shuiyanqijunx') return player.countCards('e')===0; + }, + zhenlie: { + audio: 2, + audioname: ["re_wangyi"], + filter: function (event, player) { + return ( + event.player != player && + event.card && + (event.card.name == "sha" || get.type(event.card) == "trick") + ); + }, + logTarget: "player", + check: function (event, player) { + if (event.getParent().excluded.includes(player)) return false; + if ( + get.attitude(player, event.player) > 0 || + (player.hp < 2 && !get.tag(event.card, "damage")) + ) + return false; + let evt = event.getParent(), + directHit = + (evt.nowuxie && get.type(event.card, "trick") === "trick") || + (evt.directHit && evt.directHit.includes(player)) || + (evt.customArgs && evt.customArgs.default && evt.customArgs.default.directHit2); + if (get.tag(event.card, "respondSha")) { + if (directHit || player.countCards("h", { name: "sha" }) === 0) return true; + } else if (get.tag(event.card, "respondShan")) { + if (directHit || player.countCards("h", { name: "shan" }) === 0) return true; + } else if (get.tag(event.card, "damage")) { + if (event.card.name === "huogong") + return event.player.countCards("h") > 4 - player.hp - player.hujia; + if (event.card.name === "shuiyanqijunx") return player.countCards("e") === 0; return true; - } - else if(player.hp>2){ - if(event.card.name==='shunshou'||(event.card.name==='zhujinqiyuan'&&(event.card.yingbian||get.distance(event.player,player)<0))) return true; + } else if (player.hp > 2) { + if ( + event.card.name === "shunshou" || + (event.card.name === "zhujinqiyuan" && + (event.card.yingbian || get.distance(event.player, player) < 0)) + ) + return true; } return false; }, - trigger:{target:'useCardToTargeted'}, - content:function(){ - "step 0" - if(get.attitude(player,trigger.player)<0&&trigger.player.countDiscardableCards(player,'he')) player.addTempSkill('zhenlie_lose'); + trigger: { target: "useCardToTargeted" }, + content: function () { + "step 0"; + if ( + get.attitude(player, trigger.player) < 0 && + trigger.player.countDiscardableCards(player, "he") + ) + player.addTempSkill("zhenlie_lose"); player.loseHp(); - "step 1" - player.removeSkill('zhenlie_lose'); + "step 1"; + player.removeSkill("zhenlie_lose"); trigger.getParent().excluded.add(player); - "step 2" - if(trigger.player.countCards('he')){ - if(get.mode()!=='identity'||player.identity!=='nei') player.addExpose(0.12); - player.discardPlayerCard(trigger.player,'he',true); + "step 2"; + if (trigger.player.countCards("he")) { + if (get.mode() !== "identity" || player.identity !== "nei") player.addExpose(0.12); + player.discardPlayerCard(trigger.player, "he", true); } }, - subSkill:{ - lose:{ - charlotte:true - } - }, - ai:{ - filterDamage:true, - skillTagFilter:(player,tag,arg)=>{ - return arg&&arg.jiu==true; + subSkill: { + lose: { + charlotte: true, }, - effect:{ - target:(card,player,target)=>{ - if(target.hp<=0&&target.hasSkill('zhenlie_lose')&&get.tag(card,'recover')) return [1,1.2]; - } - } - } + }, + ai: { + filterDamage: true, + skillTagFilter: (player, tag, arg) => { + return arg && arg.jiu == true; + }, + effect: { + target: (card, player, target) => { + if (target.hp <= 0 && target.hasSkill("zhenlie_lose") && get.tag(card, "recover")) + return [1, 1.2]; + }, + }, + }, }, //吾彦... - wuyan:{audio:2}, - xswuyan:{ - audio:'wuyan', - trigger:{target:'useCardToBefore',player:'useCardToBefore'}, - forced:true, - check:function(event,player){ - return get.effect(event.target,event.card,event.player,player)<0; + wuyan: { audio: 2 }, + xswuyan: { + audio: "wuyan", + trigger: { target: "useCardToBefore", player: "useCardToBefore" }, + forced: true, + check: function (event, player) { + return get.effect(event.target, event.card, event.player, player) < 0; }, - filter:function(event,player){ - if(!event.target) return false; - if(event.player==player&&event.target==player) return false; - return (get.type(event.card)=='trick'); + filter: function (event, player) { + if (!event.target) return false; + if (event.player == player && event.target == player) return false; + return get.type(event.card) == "trick"; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='trick'&&player!=target) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "trick" && player != target) return "zeroplayertarget"; }, - player:function(card,player,target,current){ - if(get.type(card)=='trick'&&player!=target) return 'zeroplayertarget'; + player: function (card, player, target, current) { + if (get.type(card) == "trick" && player != target) return "zeroplayertarget"; }, }, }, }, - xinwuyan:{ - audio:2, - trigger:{source:'damageBegin2',player:'damageBegin4'}, - forced:true, - check:function(event,player){ - if(player==event.player) return true; + xinwuyan: { + audio: 2, + trigger: { source: "damageBegin2", player: "damageBegin4" }, + forced: true, + check: function (event, player) { + if (player == event.player) return true; return false; }, - filter:function(event,player){ - return get.type(event.card,'trick')=='trick'; + filter: function (event, player) { + return get.type(event.card, "trick") == "trick"; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - notrick:true, - notricksource:true, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='trick'&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + ai: { + notrick: true, + notricksource: true, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "trick" && get.tag(card, "damage")) { + return "zeroplayertarget"; } }, - player:function(card,player,target,current){ - if(get.type(card)=='trick'&&get.tag(card,'damage')){ - return 'zeroplayertarget'; + player: function (card, player, target, current) { + if (get.type(card) == "trick" && get.tag(card, "damage")) { + return "zeroplayertarget"; } - } - } - } - }, - xinjujian:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - audio:2, - filter:function(event,player){ - return player.countCards('he')>player.countCards('he',{type:'basic'}); + }, + }, }, - content:function(){ - "step 0" + }, + xinjujian: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + audio: 2, + filter: function (event, player) { + return player.countCards("he") > player.countCards("he", { type: "basic" }); + }, + content: function () { + "step 0"; player.chooseCardTarget({ - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - filterCard:function(card,player){ - return get.type(card)!='basic'&&lib.filter.cardDiscardable(card,player); + filterCard: function (card, player) { + return get.type(card) != "basic" && lib.filter.cardDiscardable(card, player); }, - ai1:function(card){ - if(get.tag(card,'damage')&&get.type(card)=='trick'){ + ai1: function (card) { + if (get.tag(card, "damage") && get.type(card) == "trick") { return 20; } - return 9-get.value(card); + return 9 - get.value(card); }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(att>0){ - if(target.isTurnedOver()) att+=3; - if(target.hp==1) att+=3; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (att > 0) { + if (target.isTurnedOver()) att += 3; + if (target.hp == 1) att += 3; } return att; }, - position:'he', - prompt:get.prompt2('xinjujian') + position: "he", + prompt: get.prompt2("xinjujian"), }); - "step 1" - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('xinjujian',target); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("xinjujian", target); player.discard(result.cards); - if(target.hp==target.maxHp&& - !target.isTurnedOver()&& - !target.isLinked()){ + if (target.hp == target.maxHp && !target.isTurnedOver() && !target.isLinked()) { target.draw(2); event.finish(); + } else { + var controls = ["draw_card"]; + if (target.hp < target.maxHp) { + controls.push("recover_hp"); + } + if (target.isLinked() | target.isTurnedOver()) { + controls.push("reset_character"); + } + target.chooseControl(controls).ai = function () { + if (target.isTurnedOver()) { + return "reset_character"; + } else if (target.hp == 1 && target.maxHp > 2) { + return "recover_hp"; + } else if (target.hp == 2 && target.maxHp > 2 && target.countCards("h") > 1) { + return "recover_hp"; + } else { + return "draw_card"; + } + }; } - else{ - var controls=['draw_card']; - if(target.hp2){ - return 'recover_hp'; - } - else if(target.hp==2&&target.maxHp>2&&target.countCards('h')>1){ - return 'recover_hp'; - } - else{ - return 'draw_card'; - } - } - } - } - else{ + } else { event.finish(); } - "step 2" - event.control=result.control; - switch(event.control){ - case 'recover_hp':event.target.recover();event.finish();break; - case 'draw_card':event.target.draw(2);event.finish();break; - case 'reset_character':if(event.target.isTurnedOver()) event.target.turnOver();break; + "step 2"; + event.control = result.control; + switch (event.control) { + case "recover_hp": + event.target.recover(); + event.finish(); + break; + case "draw_card": + event.target.draw(2); + event.finish(); + break; + case "reset_character": + if (event.target.isTurnedOver()) event.target.turnOver(); + break; } - "step 3" - if(event.control=='reset_character'&&event.target.isLinked()){ + "step 3"; + if (event.control == "reset_character" && event.target.isLinked()) { event.target.link(); } }, - ai:{ - expose:0.2, - threaten:1.4 - } + ai: { + expose: 0.2, + threaten: 1.4, + }, }, - jujian:{ - enable:'phaseUse', - usable:1, - audio:2, - filterCard:true, - position:'he', - selectCard:[1,3], - check:function(card){ - var player=get.owner(card); - if(get.type(card)=='trick') return 10; - if(player.countCards('h')-player.hp-ui.selected.cards.length>0){ - return 8-get.value(card); + jujian: { + enable: "phaseUse", + usable: 1, + audio: 2, + filterCard: true, + position: "he", + selectCard: [1, 3], + check: function (card) { + var player = get.owner(card); + if (get.type(card) == "trick") return 10; + if (player.countCards("h") - player.hp - ui.selected.cards.length > 0) { + return 8 - get.value(card); } - return 4-get.value(card); + return 4 - get.value(card); }, - filterTarget:function(card,player,target){ - return player!=target; + filterTarget: function (card, player, target) { + return player != target; }, - content:function(){ + content: function () { target.draw(cards.length); - if(cards.length==3){ - if(get.type(cards[0],'trick')==get.type(cards[1],'trick')&& - get.type(cards[0],'trick')==get.type(cards[2],'trick')){ + if (cards.length == 3) { + if ( + get.type(cards[0], "trick") == get.type(cards[1], "trick") && + get.type(cards[0], "trick") == get.type(cards[2], "trick") + ) { player.recover(); } } }, - ai:{ - expose:0.2, - order:1, - result:{ - target:1 - } - } - }, - yizhong:{ - trigger:{target:'shaBefore'}, - forced:true, - audio:2, - filter:function(event,player){ - if(!player.hasEmptySlot(2)) return false; - return (event.card.name=='sha'&&get.color(event.card)=='black') + ai: { + expose: 0.2, + order: 1, + result: { + target: 1, + }, }, - content:function(){ + }, + yizhong: { + trigger: { target: "shaBefore" }, + forced: true, + audio: 2, + filter: function (event, player) { + if (!player.hasEmptySlot(2)) return false; + return event.card.name == "sha" && get.color(event.card) == "black"; + }, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player==target&&get.subtypes(card).includes('equip2')){ - if(get.equipValue(card)<=8) return 0; + ai: { + effect: { + target: function (card, player, target) { + if (player == target && get.subtypes(card).includes("equip2")) { + if (get.equipValue(card) <= 8) return 0; } - if(!player.hasEmptySlot(2)) return; - if(card.name=='sha'&&get.color(card)=='black') return 'zerotarget'; - } - } - } + if (!player.hasEmptySlot(2)) return; + if (card.name == "sha" && get.color(card) == "black") return "zerotarget"; + }, + }, + }, }, - jueqing:{ - trigger:{source:'damageBefore'}, - forced:true, - audio:2, + jueqing: { + trigger: { source: "damageBefore" }, + forced: true, + audio: 2, //priority:16, - check:function(){return false;}, - content:function(){ + check: function () { + return false; + }, + content: function () { trigger.cancel(); trigger.player.loseHp(trigger.num); }, - ai:{ - jueqing:true - } + ai: { + jueqing: true, + }, }, - shangshi:{ - audio:2, - trigger:{ - player:['loseAfter','changeHp','gainMaxHpAfter','loseMaxHpAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + shangshi: { + audio: 2, + trigger: { + player: ["loseAfter", "changeHp", "gainMaxHpAfter", "loseMaxHpAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - frequent:true, - filter:function(event,player){ - if(event.getl&&!event.getl(player)) return false; - return player.countCards('h')0) return 0; - if(player.getEquip('zhuge')&&player.countCards('h','sha')>1) return 0; - if(!player.countCards('h','sha')) return 0; - var targets=[]; + ai: { + order: 5, + result: { + player: function (player) { + if (_status.event.parent.name == "phaseUse") { + if (player.countCards("h", "jiu") > 0) return 0; + if (player.getEquip("zhuge") && player.countCards("h", "sha") > 1) return 0; + if (!player.countCards("h", "sha")) return 0; + var targets = []; var target; - var players=game.filterPlayer(); - for(var i=0;inum){ - target=targets[i]; - num=num2; + var num = get.effect(target, { name: "sha" }, player, player); + for (var i = 1; i < targets.length; i++) { + var num2 = get.effect(targets[i], { name: "sha" }, player, player); + if (num2 > num) { + target = targets[i]; + num = num2; } } - if(num<=0) return 0; - var e2=target.getEquip(2); - if(e2){ - if(e2.name=='tengjia'){ - if(!player.countCards('h',{name:'sha',nature:'fire'})&&!player.getEquip('zhuque')) return 0; + if (num <= 0) return 0; + var e2 = target.getEquip(2); + if (e2) { + if (e2.name == "tengjia") { + if ( + !player.countCards("h", { name: "sha", nature: "fire" }) && + !player.getEquip("zhuque") + ) + return 0; } - if(e2.name=='renwang'){ - if(!player.countCards('h',{name:'sha',color:'red'})) return 0; + if (e2.name == "renwang") { + if (!player.countCards("h", { name: "sha", color: "red" })) return 0; } - if(e2.name=='baiyin') return 0; + if (e2.name == "baiyin") return 0; } - if(player.getEquip('guanshi')&&player.countCards('he')>2) return 1; - return target.countCards('h')>3?0:1; + if (player.getEquip("guanshi") && player.countCards("he") > 2) return 1; + return target.countCards("h") > 3 ? 0 : 1; } - if(player==_status.event.dying||player.isTurnedOver()) return 3; - } + if (player == _status.event.dying || player.isTurnedOver()) return 3; + }, }, - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,0.5]; - if(target.isTurnedOver()){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp==1) return; - return [1,target.countCards('h')/2]; + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 0.5]; + if (target.isTurnedOver()) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (target.hp == 1) return; + return [1, target.countCards("h") / 2]; } } - } - } + }, + }, }, }, - jiushi2:{ - trigger:{player:'damageBegin3'}, - silent:true, - firstDo:true, - filter:function(event,player){ - return player.classList.contains('turnedover'); + jiushi2: { + trigger: { player: "damageBegin3" }, + silent: true, + firstDo: true, + filter: function (event, player) { + return player.classList.contains("turnedover"); + }, + content: function () { + trigger.jiushi = true; }, - content:function(){ - trigger.jiushi=true; - } }, - jiushi3:{ - audio:'jiushi1', - trigger:{player:'damageEnd'}, - check:function(event,player){ + jiushi3: { + audio: "jiushi1", + trigger: { player: "damageEnd" }, + check: function (event, player) { return player.isTurnedOver(); }, - prompt:'是否发动【酒诗】,将武将牌翻面?', - filter:function(event,player){ - if(event.jiushi){ + prompt: "是否发动【酒诗】,将武将牌翻面?", + filter: function (event, player) { + if (event.jiushi) { return true; } return false; }, - content:function(){ + content: function () { delete trigger.jiushi; player.turnOver(); - } - }, - zongshi:{ - audio:2, - mod:{ - maxHandcard:function(player,num){ - return num+game.countGroup(); - } - } - }, - zishou:{ - audio:2, - audioname:['re_liubiao'], - trigger:{player:'phaseDrawBegin2'}, - check:function(event,player){ - return player.countCards('h')<=(player.hasSkill('zongshi')?player.maxHp:(player.hp-2))||player.skipList.includes('phaseUse'); }, - filter:function(event,player){ + }, + zongshi: { + audio: 2, + mod: { + maxHandcard: function (player, num) { + return num + game.countGroup(); + }, + }, + }, + zishou: { + audio: 2, + audioname: ["re_liubiao"], + trigger: { player: "phaseDrawBegin2" }, + check: function (event, player) { + return ( + player.countCards("h") <= + (player.hasSkill("zongshi") ? player.maxHp : player.hp - 2) || + player.skipList.includes("phaseUse") + ); + }, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - trigger.num+=game.countGroup(); - player.addTempSkill('zishou2'); + content: function () { + trigger.num += game.countGroup(); + player.addTempSkill("zishou2"); + }, + ai: { + threaten: 1.5, }, - ai:{ - threaten:1.5 - } }, - zishou2:{ - mod:{ - playerEnabled:function(card,player,target){ - if(player!=target) return false; - } - } + zishou2: { + mod: { + playerEnabled: function (card, player, target) { + if (player != target) return false; + }, + }, }, - olddanshou:{ - audio:'danshou', - trigger:{source:'damageSource'}, + olddanshou: { + audio: "danshou", + trigger: { source: "damageSource" }, //priority:9, - check:function(event,player){ - return get.attitude(player,event.player)<=0; + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.draw(); - var cards=Array.from(ui.ordering.childNodes); - while(cards.length){ + var cards = Array.from(ui.ordering.childNodes); + while (cards.length) { cards.shift().discard(); } - "step 1" - var evt=_status.event.getParent('phase'); - if(evt){ + "step 1"; + var evt = _status.event.getParent("phase"); + if (evt) { game.resetSkills(); - _status.event=evt; + _status.event = evt; _status.event.finish(); _status.event.untrigger(true); } }, - ai:{ - jueqing:true - } + ai: { + jueqing: true, + }, }, - danshou:{ - enable:'phaseUse', - filterCard:true, - position:'he', - audio:2, - filter:function(event,player){ - var num=player.getStat().skill.danshou; - if(num){ + danshou: { + enable: "phaseUse", + filterCard: true, + position: "he", + audio: 2, + filter: function (event, player) { + var num = player.getStat().skill.danshou; + if (num) { num++; + } else { + num = 1; } - else{ - num=1; - } - return player.countCards('he')>=num; + return player.countCards("he") >= num; }, - check:function(card){ - if(ui.selected.cards.length>=2){ - return 4-get.value(card); + check: function (card) { + if (ui.selected.cards.length >= 2) { + return 4 - get.value(card); } - return 6-get.value(card); + return 6 - get.value(card); }, - selectCard:function(card){ - var num=_status.event.player.getStat().skill.danshou; - if(num) return num+1; + selectCard: function (card) { + var num = _status.event.player.getStat().skill.danshou; + if (num) return num + 1; return 1; }, - filterTarget:function(card,player,target){ - if(player==target) return false; - var num=player.getStat().skill.danshou; - if(num){ + filterTarget: function (card, player, target) { + if (player == target) return false; + var num = player.getStat().skill.danshou; + if (num) { num++; + } else { + num = 1; } - else{ - num=1; - } - if(num<=2&&!target.countCards('he')) return false; + if (num <= 2 && !target.countCards("he")) return false; return player.inRange(target); }, - content:function(){ - 'step 0' - var num=player.getStat().skill.danshou; - switch(num){ - case 1:player.discardPlayerCard(target,true);break; - case 2:target.chooseCard('选择一张牌交给'+get.translation(player),'he',true);break; - case 3:target.damage('nocard');break; - default:game.asyncDraw([player,target],2); + content: function () { + "step 0"; + var num = player.getStat().skill.danshou; + switch (num) { + case 1: + player.discardPlayerCard(target, true); + break; + case 2: + target.chooseCard("选择一张牌交给" + get.translation(player), "he", true); + break; + case 3: + target.damage("nocard"); + break; + default: + game.asyncDraw([player, target], 2); } - if(num!=2) event.finish(); - 'step 1' - if(result.cards){ - target.give(result.cards,player); + if (num != 2) event.finish(); + "step 1"; + if (result.cards) { + target.give(result.cards, player); } }, - ai:{ - order:8.6, - result:{ - target:function(player,target){ - var num=player.getStat().skill.danshou; - if(num){ + ai: { + order: 8.6, + result: { + target: function (player, target) { + var num = player.getStat().skill.danshou; + if (num) { num++; + } else { + num = 1; } - else{ - num=1; - } - if(num>3) return 0; - if(num==3) return get.damageEffect(target,player,target); + if (num > 3) return 0; + if (num == 3) return get.damageEffect(target, player, target); return -1; - } - } - } + }, + }, + }, }, - qice:{ - audio:2, - audioname:['clan_xunyou'], - enable:'phaseUse', - filter:function(event,player){ - const hs=player.getCards('h'); - if(!hs.length) return false; - if(hs.some(card=>{ - 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); + qice: { + audio: 2, + audioname: ["clan_xunyou"], + enable: "phaseUse", + filter: function (event, player) { + const hs = player.getCards("h"); + if (!hs.length) return false; + if ( + hs.some((card) => { + 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); }); }, - usable:1, - chooseButton:{ - dialog:function(player){ - var list=[]; - for(var i=0;i0&&!players[i].hasSha()){ - return (button.link[2]=='juedou')?2:-1; + check: function (button) { + var player = _status.event.player; + var recover = 0, + lose = 1, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hp == 1 && + get.damageEffect(players[i], player, player) > 0 && + !players[i].hasSha() + ) { + return button.link[2] == "juedou" ? 2 : -1; } - if(!players[i].isOut()){ - if(players[i].hp0){ - if(players[i].hp<2){ + if (!players[i].isOut()) { + if (players[i].hp < players[i].maxHp) { + if (get.attitude(player, players[i]) > 0) { + if (players[i].hp < 2) { lose--; - recover+=0.5; + recover += 0.5; } lose--; recover++; - } - else if(get.attitude(player,players[i])<0){ - if(players[i].hp<2){ + } else if (get.attitude(player, players[i]) < 0) { + if (players[i].hp < 2) { lose++; - recover-=0.5; + recover -= 0.5; } lose++; recover--; } - } - else{ - if(get.attitude(player,players[i])>0){ + } else { + if (get.attitude(player, players[i]) > 0) { lose--; - } - else if(get.attitude(player,players[i])<0){ + } else if (get.attitude(player, players[i]) < 0) { lose++; } } } } - if(lose>recover&&lose>0) return (button.link[2]=='nanman')?1:-1; - if(lose0) return (button.link[2]=='taoyuan')?1:-1; - return (button.link[2]=='wuzhong')?1:-1; + if (lose > recover && lose > 0) return button.link[2] == "nanman" ? 1 : -1; + if (lose < recover && recover > 0) return button.link[2] == "taoyuan" ? 1 : -1; + return button.link[2] == "wuzhong" ? 1 : -1; }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'qice', - audioname:['clan_xunyou'], - filterCard:true, - selectCard:-1, - position:'h', - popname:true, - viewAs:{name:links[0][2]}, - } + audio: "qice", + audioname: ["clan_xunyou"], + filterCard: true, + selectCard: -1, + position: "h", + popname: true, + viewAs: { name: links[0][2] }, + }; + }, + prompt: function (links, player) { + return "将全部手牌当作" + get.translation(links[0][2]) + "使用"; }, - prompt:function(links,player){ - return '将全部手牌当作'+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order:1, - result:{ - player:function(player){ - var num=0; - var cards=player.getCards('h'); - if(cards.length>=3&&player.hp>=3) return 0; - for(var i=0;i= 3 && player.hp >= 3) return 0; + for (var i = 0; i < cards.length; i++) { + num += Math.max(0, get.value(cards[i], player, "raw")); } - num/=cards.length; - num*=Math.min(cards.length,player.hp); - return 12-num; - } + num /= cards.length; + num *= Math.min(cards.length, player.hp); + 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'); + 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, - } + threaten: 1.6, + }, }, - zhiyu:{ - audio:2, - trigger:{player:'damageEnd'}, - preHidden:true, - content:function(){ - "step 0" + zhiyu: { + audio: 2, + trigger: { player: "damageEnd" }, + preHidden: true, + content: function () { + "step 0"; player.draw(); - "step 1" - if(!player.countCards('h')) event.finish(); + "step 1"; + if (!player.countCards("h")) event.finish(); else player.showHandcards(); - "step 2" - if(!trigger.source) return; - var cards=player.getCards('h'); - var color=get.color(cards[0],player); - for(var i=1;i1; - } - else{ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + return cards.length > 1; + } else { + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; } }, - content:function(){ - "step 0" - event.count=2; - event.logged=false; - "step 1" - player.chooseTarget(get.prompt('xuanfeng'),'弃置一名其他角色的一张牌',function(card,player,target){ - if(player==target) return false; - return target.countDiscardableCards(player,'he'); - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 2" - if(result.bool){ - if(!event.logged){ - player.logSkill('xuanfeng',result.targets); - event.logged=true; - } - else player.line(result.targets[0],'green'); - player.discardPlayerCard(result.targets[0],'he',true); + content: function () { + "step 0"; + event.count = 2; + event.logged = false; + "step 1"; + player + .chooseTarget( + get.prompt("xuanfeng"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + if (player == target) return false; + return target.countDiscardableCards(player, "he"); + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 2"; + if (result.bool) { + if (!event.logged) { + player.logSkill("xuanfeng", result.targets); + event.logged = true; + } else player.line(result.targets[0], "green"); + player.discardPlayerCard(result.targets[0], "he", true); event.count--; - } - else event.finish(); - "step 3" - if(event.count) event.goto(1); + } else event.finish(); + "step 3"; + if (event.count) event.goto(1); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3]; + }, }, - reverseEquip:true, - noe:true - } + reverseEquip: true, + noe: true, + }, }, - jiangchi:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - direct:true, - filter:function(event,player){ + jiangchi: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + direct: true, + filter: function (event, player) { return !event.numFixed; }, - content:function(){ - "step 0" - player.chooseControl('jiangchi_less','jiangchi_more','cancel2',function(){ - var player=_status.event.player; - if(player.countCards('h')>3&&player.countCards('h','sha')>1){ - return 'jiangchi_less'; + content: function () { + "step 0"; + player.chooseControl("jiangchi_less", "jiangchi_more", "cancel2", function () { + var player = _status.event.player; + if (player.countCards("h") > 3 && player.countCards("h", "sha") > 1) { + return "jiangchi_less"; } - if(player.countCards('h','sha')>2){ - return 'jiangchi_less'; + if (player.countCards("h", "sha") > 2) { + return "jiangchi_less"; } - if(player.hp-player.countCards('h')>1){ - return 'jiangchi_more'; + if (player.hp - player.countCards("h") > 1) { + return "jiangchi_more"; } - return 'cancel2'; + return "cancel2"; }); - "step 1" - if(result.control=='jiangchi_less'){ + "step 1"; + if (result.control == "jiangchi_less") { trigger.num--; - player.addTempSkill('jiangchi2','phaseUseEnd'); - player.logSkill('jiangchi'); - } - else if(result.control=='jiangchi_more'){ + player.addTempSkill("jiangchi2", "phaseUseEnd"); + player.logSkill("jiangchi"); + } else if (result.control == "jiangchi_more") { trigger.num++; - player.addTempSkill('jiangchi3','phaseUseEnd'); - player.logSkill('jiangchi'); + player.addTempSkill("jiangchi3", "phaseUseEnd"); + player.logSkill("jiangchi"); } - } - }, - jiangchi2:{ - mod:{ - targetInRange:function(card,player,target,now){ - if(card.name=='sha') return true; - }, - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; - } - } - }, - jiangchi3:{ - mod:{ - cardEnabled:function(card){if(card.name=='sha') return false} - } - }, - xinzhan:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>player.maxHp; }, - usable:1, - content:function(){ - "step 0" - var cards=get.cards(3); - event.cards=cards; - var next=player.chooseCardButton(cards,'选择获得的红桃牌',[1,Infinity]).set('filterButton',function(button){ - return get.suit(button.link)=='heart'; - }); - "step 1" - if(result.bool){ - player.gain(result.links,'draw'); + }, + jiangchi2: { + mod: { + targetInRange: function (card, player, target, now) { + if (card.name == "sha") return true; + }, + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + }, + jiangchi3: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, + }, + xinzhan: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h") > player.maxHp; + }, + usable: 1, + content: function () { + "step 0"; + var cards = get.cards(3); + event.cards = cards; + var next = player + .chooseCardButton(cards, "选择获得的红桃牌", [1, Infinity]) + .set("filterButton", function (button) { + return get.suit(button.link) == "heart"; + }); + "step 1"; + if (result.bool) { + player.gain(result.links, "draw"); } - for(var i=event.cards.length-1;i>=0;i--){ - if(!result.bool||!result.links.includes(event.cards[i])){ - ui.cardPile.insertBefore(event.cards[i],ui.cardPile.firstChild); + for (var i = event.cards.length - 1; i >= 0; i--) { + if (!result.bool || !result.links.includes(event.cards[i])) { + ui.cardPile.insertBefore(event.cards[i], ui.cardPile.firstChild); } } }, - ai:{ - order:11, - result:{ - player:1 - } - } + ai: { + order: 11, + result: { + player: 1, + }, + }, }, - huilei:{ - audio:2, - trigger:{player:'die'}, - forced:true, - forceDie:true, - filter:function(event){ - return event.source&&event.source.isIn(); + huilei: { + audio: 2, + trigger: { player: "die" }, + forced: true, + forceDie: true, + filter: function (event) { + return event.source && event.source.isIn(); }, - logTarget:'source', - skillAnimation:true, - animationColor:'thunder', - content:function(){ - trigger.source.discard(trigger.source.getCards('he')); + logTarget: "source", + skillAnimation: true, + animationColor: "thunder", + content: function () { + trigger.source.discard(trigger.source.getCards("he")); + }, + ai: { + threaten: 0.7, }, - ai:{ - threaten:0.7 - } }, - xinenyuan:{ - audio:2, - group:['xinenyuan1','xinenyuan2'], + xinenyuan: { + audio: 2, + group: ["xinenyuan1", "xinenyuan2"], }, - xinenyuan1:{ - audio:true, - trigger:{player:'gainEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source!=player&&event.cards.length>=2; + xinenyuan1: { + audio: true, + trigger: { player: "gainEnd" }, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.source != player && + event.cards.length >= 2 + ); }, - logTarget:'source', - check:function(event,player){ - return get.attitude(player,event.source)>0; + logTarget: "source", + check: function (event, player) { + return get.attitude(player, event.source) > 0; }, - prompt2:function(event,player){ - return '令'+get.translation(event.source)+'摸一张牌'; + prompt2: function (event, player) { + return "令" + get.translation(event.source) + "摸一张牌"; }, - content:function(){ + content: function () { trigger.source.draw(); }, }, - xinenyuan2:{ - audio:true, - trigger:{player:'damageEnd'}, - check:function(event,player){ - var att=get.attitude(player,event.source); - var num=event.source.countCards('h'); - if(att<=0) return true; - if(num>2) return true; - if(num) return att<4; + xinenyuan2: { + audio: true, + trigger: { player: "damageEnd" }, + check: function (event, player) { + var att = get.attitude(player, event.source); + var num = event.source.countCards("h"); + if (att <= 0) return true; + if (num > 2) return true; + if (num) return att < 4; return false; }, - filter:function(event,player){ - return event.source&&event.source!=player&&event.num>0&&event.source.isIn(); + filter: function (event, player) { + return event.source && event.source != player && event.num > 0 && event.source.isIn(); }, - logTarget:'source', - prompt2:function(event,player){ - return '令'+get.translation(event.source)+'交给你一张手牌或失去1点体力'; + logTarget: "source", + prompt2: function (event, player) { + return "令" + get.translation(event.source) + "交给你一张手牌或失去1点体力"; }, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - trigger.source.chooseCard('选择一张手牌交给'+get.translation(player)+',或点“取消”失去1点体力').set('ai',function(card){ - var player=_status.event.getParent().player,source=_status.event.player; - if(get.effect(source,{name:'losehp'},source,source)>=0) return 0; - if(get.attitude(player,source)>0) return 11-get.value(card); - return 7-get.value(card); - }); - 'step 2' - if(result.bool){ - trigger.source.give(result.cards,player); - } - else{ + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + trigger.source + .chooseCard("选择一张手牌交给" + get.translation(player) + ",或点“取消”失去1点体力") + .set("ai", function (card) { + var player = _status.event.getParent().player, + source = _status.event.player; + if (get.effect(source, { name: "losehp" }, source, source) >= 0) return 0; + if (get.attitude(player, source) > 0) return 11 - get.value(card); + return 7 - get.value(card); + }); + "step 2"; + if (result.bool) { + trigger.source.give(result.cards, player); + } else { trigger.source.loseHp(); } - if(event.num>1&&player.hasSkill('xinenyuan')&&trigger.source&&trigger.source.isIn()){ - player.logSkill('xinenyuan',trigger.source) + if ( + event.num > 1 && + player.hasSkill("xinenyuan") && + trigger.source && + trigger.source.isIn() + ) { + player.logSkill("xinenyuan", trigger.source); event.num--; event.goto(1); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - if(!target.hasFriend()) return; - if(get.tag(card,'damage')) return [1,0,0,-0.7]; + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + if (!target.hasFriend()) return; + if (get.tag(card, "damage")) return [1, 0, 0, -0.7]; }, }, }, }, - enyuan:{ - audio:2, - locked:true, - group:['enyuan1','enyuan2'], + enyuan: { + audio: 2, + locked: true, + group: ["enyuan1", "enyuan2"], }, - enyuan1:{ - audio:true, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.isIn(); + enyuan1: { + audio: true, + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return event.source && event.source != player && event.source.isIn(); }, - logTarget:'source', - content:function(){ - 'step 0' - trigger.source.chooseCard('选择一张红桃牌交给'+get.translation(player)+',或点“取消”失去1点体力',function(card){ - return get.suit(card)=='heart'; - }).set('ai',function(card){ - var player=_status.event.getParent().player,source=_status.event.player; - if(get.effect(source,{name:'losehp'},source,source)>=0) return 0; - if(get.attitude(player,source)>0) return 11-get.value(card); - return 7-get.value(card); - }); - 'step 1' - if(result.bool){ - trigger.source.give(result.cards,player); - } - else{ + logTarget: "source", + content: function () { + "step 0"; + trigger.source + .chooseCard( + "选择一张红桃牌交给" + get.translation(player) + ",或点“取消”失去1点体力", + function (card) { + return get.suit(card) == "heart"; + } + ) + .set("ai", function (card) { + var player = _status.event.getParent().player, + source = _status.event.player; + if (get.effect(source, { name: "losehp" }, source, source) >= 0) return 0; + if (get.attitude(player, source) > 0) return 11 - get.value(card); + return 7 - get.value(card); + }); + "step 1"; + if (result.bool) { + trigger.source.give(result.cards, player); + } else { trigger.source.loseHp(); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(get.tag(card,'damage')) return [1,0,0,-1]; + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (get.tag(card, "damage")) return [1, 0, 0, -1]; }, }, }, }, - enyuan2:{ - audio:true, - trigger:{player:'recoverEnd'}, - forced:true, - logTarget:'source', - filter:function(event,player){ - return event.source&&event.source!=player&&event.source.isIn(); + enyuan2: { + audio: true, + trigger: { player: "recoverEnd" }, + forced: true, + logTarget: "source", + filter: function (event, player) { + return event.source && event.source != player && event.source.isIn(); }, - content:function(){ - 'step 0' - event.num=trigger.num; - 'step 1' - if(event.num>0){ - player.logSkill('enyuan1',trigger.source); + content: function () { + "step 0"; + event.num = trigger.num; + "step 1"; + if (event.num > 0) { + player.logSkill("enyuan1", trigger.source); trigger.source.draw(); event.num--; event.redo(); } }, }, - xuanhuo:{ - audio:2, - enable:'phaseUse', - usable:1, - discard:false, - lose:false, - delay:0, - filter:function(event,player){ - return player.countCards('he',{suit:'heart'}); + xuanhuo: { + audio: 2, + enable: "phaseUse", + usable: 1, + discard: false, + lose: false, + delay: 0, + filter: function (event, player) { + return player.countCards("he", { suit: "heart" }); }, - filterCard:function(card){ - return get.suit(card)=='heart'; + filterCard: function (card) { + return get.suit(card) == "heart"; }, - filterTarget:function(card,player,target){ - if(game.countPlayer()==2) return false; - return player!=target; + filterTarget: function (card, player, target) { + if (game.countPlayer() == 2) return false; + return player != target; }, - check:function(card){ - var player=get.owner(card); - var players=game.filterPlayer(); - for(var i=0;i3) break; + check: function (card) { + var player = get.owner(card); + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && get.attitude(player, players[i]) > 3) break; } - if(i==players.length) return -1; - return 5-get.value(card); + if (i == players.length) return -1; + return 5 - get.value(card); }, - content:function(){ - "step 0" - player.give(cards,target); + content: function () { + "step 0"; + player.give(cards, target); // game.delay(); - "step 1" - player.gainPlayerCard(target,'he',true); - "step 2" - var source=target; - event.card=result.links[0]; - if(player.getCards('h').includes(event.card)) player.chooseTarget('将'+get.translation(event.card)+'交给另一名其他角色',function(card,player,target){ - return target!=_status.event.sourcex&&target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('sourcex',target); + "step 1"; + player.gainPlayerCard(target, "he", true); + "step 2"; + var source = target; + event.card = result.links[0]; + if (player.getCards("h").includes(event.card)) + player + .chooseTarget( + "将" + get.translation(event.card) + "交给另一名其他角色", + function (card, player, target) { + return target != _status.event.sourcex && target != player; + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("sourcex", target); else event.finish(); - "step 3" - if(result.bool){ - player.give(card,result.targets[0],'give'); + "step 3"; + if (result.bool) { + player.give(card, result.targets[0], "give"); game.delay(); } }, - ai:{ - result:{ - target:-0.5, + ai: { + result: { + target: -0.5, + }, + basic: { + order: 9, }, - basic:{ - order:9, - } - } - }, - ganlu:{ - enable:'phaseUse', - usable:1, - audio:2, - selectTarget:2, - filterTarget:function(card,player,target){ - if(target.isMin()) return false; - if(ui.selected.targets.length==0) return true; - if(ui.selected.targets[0].countCards('e')==0&&target.countCards('e')==0) return false; - return Math.abs(ui.selected.targets[0].countCards('e')-target.countCards('e'))<=player.maxHp-player.hp; }, - multitarget:true, - content:function(){ + }, + ganlu: { + enable: "phaseUse", + usable: 1, + audio: 2, + selectTarget: 2, + filterTarget: function (card, player, target) { + if (target.isMin()) return false; + if (ui.selected.targets.length == 0) return true; + if (ui.selected.targets[0].countCards("e") == 0 && target.countCards("e") == 0) + return false; + return ( + Math.abs(ui.selected.targets[0].countCards("e") - target.countCards("e")) <= + player.maxHp - player.hp + ); + }, + multitarget: true, + content: function () { targets[0].swapEquip(targets[1]); }, - ai:{ - order:10, - threaten:function(player,target){ - return 0.8*Math.max(1+target.maxHp-target.hp); + ai: { + order: 10, + threaten: function (player, target) { + return 0.8 * Math.max(1 + target.maxHp - target.hp); }, - result:{ - target:function(player,target){ - var list1=[]; - var list2=[]; - var num=player.maxHp-player.hp; - var players=game.filterPlayer(); - for(var i=0;i0) list1.push(players[i]); - else if(get.attitude(player,players[i])<0) list2.push(players[i]); + result: { + target: function (player, target) { + var list1 = []; + var list2 = []; + var num = player.maxHp - player.hp; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) list1.push(players[i]); + else if (get.attitude(player, players[i]) < 0) list2.push(players[i]); } - list1.sort(function(a,b){ - return a.countCards('e')-b.countCards('e'); + list1.sort(function (a, b) { + return a.countCards("e") - b.countCards("e"); }); - list2.sort(function(a,b){ - return b.countCards('e')-a.countCards('e'); + list2.sort(function (a, b) { + return b.countCards("e") - a.countCards("e"); }); var delta; - for(var i=0;i0; }, - direct:true, - content:function(){ - "step 0" + }, + buyi: { + trigger: { global: "dying" }, + //priority:6, + audio: 2, + audioname: ["re_wuguotai"], + filter: function (event, player) { + return event.player.hp <= 0 && event.player.countCards("h") > 0; + }, + direct: true, + content: function () { + "step 0"; var check; - if(trigger.player.isUnderControl(true,player)){ - check=player.hasCard(function(card){ - return get.type(card)!='basic'; + if (trigger.player.isUnderControl(true, player)) { + check = player.hasCard(function (card) { + return get.type(card) != "basic"; }); + } else { + check = get.attitude(player, trigger.player) > 0; } - else{ - check=(get.attitude(player,trigger.player)>0); - } - player.choosePlayerCard(trigger.player,get.prompt('buyi',trigger.player),'h').set('ai',function(button){ - if(!_status.event.check) return 0; - if(_status.event.target.isUnderControl(true,_status.event.player)){ - if(get.type(button.link)!='basic'){ - return 10-get.value(button.link); + player + .choosePlayerCard(trigger.player, get.prompt("buyi", trigger.player), "h") + .set("ai", function (button) { + if (!_status.event.check) return 0; + if (_status.event.target.isUnderControl(true, _status.event.player)) { + if (get.type(button.link) != "basic") { + return 10 - get.value(button.link); + } + return 0; + } else { + return Math.random(); } - return 0; - } - else{ - return Math.random(); - } - }).set('check',check).set('filterButton',function(button){ - if(_status.event.player==_status.event.target){ - return lib.filter.cardDiscardable(button.link,_status.event.player); - } - return true; - }); - "step 1" - if(result.bool){ - player.logSkill('buyi',trigger.player); - event.card=result.links[0]; - player.showCards([event.card],get.translation(player)+'展示的手牌'); - } - else{ + }) + .set("check", check) + .set("filterButton", function (button) { + if (_status.event.player == _status.event.target) { + return lib.filter.cardDiscardable(button.link, _status.event.player); + } + return true; + }); + "step 1"; + if (result.bool) { + player.logSkill("buyi", trigger.player); + event.card = result.links[0]; + player.showCards([event.card], get.translation(player) + "展示的手牌"); + } else { event.finish(); } - "step 2" - if(get.type(event.card)!='basic'){ + "step 2"; + if (get.type(event.card) != "basic") { trigger.player.recover(); trigger.player.discard(event.card); } }, - ai:{ - threaten:1.4 - } + ai: { + threaten: 1.4, + }, }, - pojun:{ - audio:2, - trigger:{source:'damageSource'}, - check:function(event,player){ - if(event.player.isTurnedOver()) return get.attitude(player,event.player)>0; - if(event.player.hp<3){ - return get.attitude(player,event.player)<0; + pojun: { + audio: 2, + trigger: { source: "damageSource" }, + check: function (event, player) { + if (event.player.isTurnedOver()) return get.attitude(player, event.player) > 0; + if (event.player.hp < 3) { + return get.attitude(player, event.player) < 0; } - return get.attitude(player,event.player)>0; + return get.attitude(player, event.player) > 0; }, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.card&&event.card.name=='sha'&&event.player.isIn(); + filter: function (event) { + if (event._notrigger.includes(event.player)) return false; + return event.card && event.card.name == "sha" && event.player.isIn(); }, - logTarget:'player', - content:function(){ - "step 0" - trigger.player.draw(Math.min(5,trigger.player.hp)); - "step 1" + logTarget: "player", + content: function () { + "step 0"; + trigger.player.draw(Math.min(5, trigger.player.hp)); + "step 1"; trigger.player.turnOver(); - } - }, - jingce:{ - trigger:{player:'phaseUseEnd'}, - frequent:true, - filter:function(event,player){ - return player.countUsed(null,true)>=player.hp; }, - content:function(){ + }, + jingce: { + trigger: { player: "phaseUseEnd" }, + frequent: true, + filter: function (event, player) { + return player.countUsed(null, true) >= player.hp; + }, + content: function () { player.draw(2); }, - audio:2, + audio: 2, }, - xinjingce:{ - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - filter:function(event,player){ - return player.countUsed(null,true)>=player.hp; + xinjingce: { + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + filter: function (event, player) { + return player.countUsed(null, true) >= player.hp; }, - content:function(){ + content: function () { player.draw(2); }, - audio:2, + audio: 2, }, - oldchengxiang:{ - audio:'chengxiang', - inherit:'chengxiang', + oldchengxiang: { + audio: "chengxiang", + inherit: "chengxiang", }, - chengxiang:{ - trigger:{player:'damageEnd'}, + chengxiang: { + trigger: { player: "damageEnd" }, //direct:true, - frequent:true, - audio:2, - content:function(){ - "step 0" - event.cards=get.cards(4); + frequent: true, + audio: 2, + content: function () { + "step 0"; + event.cards = get.cards(4); game.cardsGotoOrdering(event.cards); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,cards,num){ - var str; - if(player==game.me&&!_status.auto){ - str='称象:选择任意张点数不大于'+num+'的牌'; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, cards, num) { + var str; + if (player == game.me && !_status.auto) { + str = "称象:选择任意张点数不大于" + num + "的牌"; + } else { + str = "称象"; + } + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + player, + event.videoId, + event.cards, + event.name == "oldchengxiang" ? 12 : 13 + ); + event.time = get.utc(); + game.addVideo("showCards", player, ["称象", get.cardsInfo(event.cards)]); + game.addVideo("delay", null, 2); + "step 1"; + var next = player.chooseButton([0, 4]); + next.set("dialog", event.videoId); + next.set("filterButton", function (button) { + var num = 0; + for (var i = 0; i < ui.selected.buttons.length; i++) { + num += get.number(ui.selected.buttons[i].link); } - else{ - str='称象'; - } - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },player,event.videoId,event.cards,event.name=='oldchengxiang'?12:13); - event.time=get.utc(); - game.addVideo('showCards',player,['称象',get.cardsInfo(event.cards)]); - game.addVideo('delay',null,2); - "step 1" - var next=player.chooseButton([0,4]); - next.set('dialog',event.videoId); - next.set('filterButton',function(button){ - var num=0 - for(var i=0;i1&&player.hasSkill('renxin')&&player.hasFriend()&&get.type(button.link)==='equip') return val + 4; + next.set("maxNum", event.name == "oldchengxiang" ? 12 : 13); + next.set("ai", function (button) { + let player = _status.event.player, + name = get.name(button.link), + val = get.value(button.link, player); + if (name === "tao") return val + 2 * Math.min(3, 1 + player.getDamagedHp()); + if (name === "jiu" && player.hp < 3) return val + 2 * (2.8 - player.hp); + if (name === "wuxie" && player.countCards("j") && !player.hasWuxie()) return val + 5; + if ( + player.hp > 1 && + player.hasSkill("renxin") && + player.hasFriend() && + get.type(button.link) === "equip" + ) + return val + 4; return val; }); - "step 2" - if(result.bool&&result.links){ + "step 2"; + if (result.bool && result.links) { //player.logSkill('chengxiang'); - var cards2=[]; - for(var i=0;i0){ - game.delay(0,time); + var time = 1000 - (get.utc() - event.time); + if (time > 0) { + game.delay(0, time); } - "step 3" - game.broadcastAll('closeDialog',event.videoId); - var cards2=event.cards2; - player.gain(cards2,'log','gain2'); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var cards2 = event.cards2; + player.gain(cards2, "log", "gain2"); }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [1,2]; - if(target.hp==3) return [1,1.5]; - if(target.hp==2) return [1,0.5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [1, 2]; + if (target.hp == 3) return [1, 1.5]; + if (target.hp == 2) return [1, 0.5]; } - } - } - } - }, - oldrenxin:{ - audio:'renxin', - trigger:{global:'dying'}, - //priority:6, - filter:function(event,player){ - return event.player!=player&&event.player.hp<=0&&player.countCards('h')>0; + }, + }, }, - check:function(event,player){ - if(get.attitude(player,event.player)<=0) return false; - if(player.countCards('h',{name:['tao','jiu']})+event.player.hp<0) return false; + }, + oldrenxin: { + audio: "renxin", + trigger: { global: "dying" }, + //priority:6, + filter: function (event, player) { + return event.player != player && event.player.hp <= 0 && player.countCards("h") > 0; + }, + check: function (event, player) { + if (get.attitude(player, event.player) <= 0) return false; + if (player.countCards("h", { name: ["tao", "jiu"] }) + event.player.hp < 0) return false; return true; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.turnOver(); - 'step 1' - player.give(player.getCards('h'),trigger.player); - 'step 2' + "step 1"; + player.give(player.getCards("h"), trigger.player); + "step 2"; trigger.player.recover(); }, }, - renxin:{ - trigger:{global:'damageBegin4'}, - audio:2, - audioname:['re_caochong'], + renxin: { + trigger: { global: "damageBegin4" }, + audio: 2, + audioname: ["re_caochong"], //priority:6, - filter:function(event,player){ - return event.player!=player&&event.player.hp==1&&player.countCards('he',{type:'equip'})>0; + filter: function (event, player) { + return ( + event.player != player && + event.player.hp == 1 && + player.countCards("he", { type: "equip" }) > 0 + ); }, - direct:true, - content:function(){ - "step 0" - var next=player.chooseToDiscard(get.prompt('renxin',trigger.player),'弃置一张装备牌并将武将牌翻面,然后防止'+get.translation(trigger.player)+'受到的伤害',{type:'equip'},'he'); - next.logSkill=['renxin',trigger.player]; - next.set('ai',function(card){ - var player=_status.event.player; - if(get.attitude(player,_status.event.getTrigger().player)>3){ - return 11-get.value(card); + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + get.prompt("renxin", trigger.player), + "弃置一张装备牌并将武将牌翻面,然后防止" + + get.translation(trigger.player) + + "受到的伤害", + { type: "equip" }, + "he" + ); + next.logSkill = ["renxin", trigger.player]; + next.set("ai", function (card) { + var player = _status.event.player; + if (get.attitude(player, _status.event.getTrigger().player) > 3) { + return 11 - get.value(card); } return -1; }); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.turnOver(); - } - else{ + } else { event.finish(); } - "step 2" + "step 2"; trigger.cancel(); }, - ai:{ - expose:0.5 - } - }, - yuce:{ - audio:2, - audioname:['re_manchong'], - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return player.countCards('h')>0&&player.isDamaged(); + ai: { + expose: 0.5, }, - content:function(){ - "step 0" - var next=player.chooseCard(get.prompt2('yuce')); - next.set('ai',function(card){ - if(get.type(card)=='basic') return 1; - return Math.abs(get.value(card))+1; + }, + yuce: { + audio: 2, + audioname: ["re_manchong"], + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return player.countCards("h") > 0 && player.isDamaged(); + }, + content: function () { + "step 0"; + var next = player.chooseCard(get.prompt2("yuce")); + next.set("ai", function (card) { + if (get.type(card) == "basic") return 1; + return Math.abs(get.value(card)) + 1; }); - "step 1" - if(result.bool){ - player.logSkill('yuce'); + "step 1"; + if (result.bool) { + player.logSkill("yuce"); player.showCards(result.cards); - var type=get.type(result.cards[0],'trick'); - if(trigger.source){ - trigger.source.chooseToDiscard('弃置一张不为'+get.translation(type)+'牌的牌或令'+get.translation(player)+'回复1点体力',function(card){ - return get.type(card,'trick')!=_status.event.type; - }).set('ai',function(card){ - if(get.recoverEffect(_status.event.getParent().player,_status.event.player,_status.event.player)<0){ - return 7-get.value(card); - } - return 0; - }).set('type',type); + var type = get.type(result.cards[0], "trick"); + if (trigger.source) { + trigger.source + .chooseToDiscard( + "弃置一张不为" + + get.translation(type) + + "牌的牌或令" + + get.translation(player) + + "回复1点体力", + function (card) { + return get.type(card, "trick") != _status.event.type; + } + ) + .set("ai", function (card) { + if ( + get.recoverEffect( + _status.event.getParent().player, + _status.event.player, + _status.event.player + ) < 0 + ) { + return 7 - get.value(card); + } + return 0; + }) + .set("type", type); + } else { + event.recover = true; } - else{ - event.recover=true; - } - } - else{ + } else { event.finish(); } - "step 2" - if(event.recover){ + "step 2"; + if (event.recover) { player.recover(); - } - else if(result.bool){ + } else if (result.bool) { //player.draw(); - } - else{ + } else { player.recover(); } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage'&&target.countCards('h'))){ - return 0.8 + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage" && target.countCards("h"))) { + return 0.8; } - } - } - } + }, + }, + }, }, - xiansi:{ - audio:2, - audioname:['re_liufeng'], - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2(event.name),[1,2],function(card,player,target){ - return target.countCards('he')>0; - },function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 1" - if(result.bool){ + xiansi: { + audio: 2, + audioname: ["re_liufeng"], + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget( + get.prompt2(event.name), + [1, 2], + function (card, player, target) { + return target.countCards("he") > 0; + }, + function (target) { + return -get.attitude(_status.event.player, target); + } + ); + "step 1"; + if (result.bool) { result.targets.sortBySeat(); - player.logSkill(event.name,result.targets); - event.targets=result.targets; - } - else{ + player.logSkill(event.name, result.targets); + event.targets = result.targets; + } else { event.finish(); } - "step 2" - if(event.targets.length){ - var target=event.targets.shift(); - event.current=target; - player.choosePlayerCard(target,true); - } - else{ + "step 2"; + if (event.targets.length) { + var target = event.targets.shift(); + event.current = target; + player.choosePlayerCard(target, true); + } else { event.finish(); } - "step 3" - if(result.bool){ - player.addToExpansion(result.cards,event.current,'give').gaintag.add('xiansi'); + "step 3"; + if (result.bool) { + player.addToExpansion(result.cards, event.current, "give").gaintag.add("xiansi"); event.goto(2); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player){ - var cards=player.getExpansions('xiansi'); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player) { + var cards = player.getExpansions("xiansi"); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - threaten:2 + ai: { + threaten: 2, }, - global:'xiansi2', - group:'xiansix', + global: "xiansi2", + group: "xiansix", }, - xiansix:{}, - xiansi2:{ - enable:'chooseToUse', - audio:2, - audioname2:{re_liufeng:'rexiansi'}, - viewAs:{name:'sha',isCard:true}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hasSkill('xiansix')&¤t.getExpansions('xiansi').length>1&&event.filterTarget({name:'sha'},player,current); + xiansix: {}, + xiansi2: { + enable: "chooseToUse", + audio: 2, + audioname2: { re_liufeng: "rexiansi" }, + viewAs: { name: "sha", isCard: true }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + current.hasSkill("xiansix") && + current.getExpansions("xiansi").length > 1 && + event.filterTarget({ name: "sha" }, player, current) + ); }); }, - filterTarget:function(card,player,target){ - var bool=false; - var players=ui.selected.targets.slice(0); - for(var i=0;i1) bool=true;break; + filterTarget: function (card, player, target) { + var bool = false; + var players = ui.selected.targets.slice(0); + for (var i = 0; i < players.length; i++) { + if (players[i].hasSkill("xiansix") && players[i].getExpansions("xiansi").length > 1) + bool = true; + break; } - if(!bool&&(!target.hasSkill('xiansix')||target.getExpansions('xiansi').length<=1)) return false; - return _status.event._backup.filterTarget.apply(this,arguments); + if (!bool && (!target.hasSkill("xiansix") || target.getExpansions("xiansi").length <= 1)) + return false; + return _status.event._backup.filterTarget.apply(this, arguments); }, - complexSelect:true, - selectCard:-1, - filterCard:function(){ + complexSelect: true, + selectCard: -1, + filterCard: function () { return false; }, - forceaudio:true, - prompt:'弃置一名有【逆】的角色的两张【逆】,然后视为对包含其在内的角色使用【杀】。', - delay:false, - log:false, - precontent:function(){ - "step 0" - var targets=event.result.targets.filter(function(current){ - return current.getExpansions('xiansi').length>1&¤t.hasSkill('xiansix'); + forceaudio: true, + prompt: "弃置一名有【逆】的角色的两张【逆】,然后视为对包含其在内的角色使用【杀】。", + delay: false, + log: false, + precontent: function () { + "step 0"; + var targets = event.result.targets.filter(function (current) { + return current.getExpansions("xiansi").length > 1 && current.hasSkill("xiansix"); }); - if(targets.length==1){ - event.target=targets[0]; + if (targets.length == 1) { + event.target = targets[0]; event.goto(2); - } - else if(targets.length>0){ - player.chooseTarget(true,'选择弃置【陷嗣】牌的目标',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',targets).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target); - }); - } - else{ + } else if (targets.length > 0) { + player + .chooseTarget(true, "选择弃置【陷嗣】牌的目标", function (card, player, target) { + return _status.event.list.includes(target); + }) + .set("list", targets) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }); + } else { event.finish(); } - "step 1" - if(result.bool&&result.targets.length){ - event.target=result.targets[0]; - } - else{ + "step 1"; + if (result.bool && result.targets.length) { + event.target = result.targets[0]; + } else { event.finish(); } - "step 2" - if(event.target){ - if(event.target.getExpansions('xiansi').length==2){ - event.directresult=event.target.getExpansions('xiansi').slice(0); + "step 2"; + if (event.target) { + if (event.target.getExpansions("xiansi").length == 2) { + event.directresult = event.target.getExpansions("xiansi").slice(0); + } else { + player.chooseCardButton( + "移去两张“逆”", + 2, + event.target.getExpansions("xiansi"), + true + ); } - else{ - player.chooseCardButton('移去两张“逆”',2,event.target.getExpansions('xiansi'),true); - } - } - else{ + } else { event.finish(); } - "step 3" - if(event.directresult||result.bool){ - player.logSkill('xiansi2_log',event.target); - game.trySkillAudio('xiansi2',event.target,true); - var links=event.directresult||result.links; + "step 3"; + if (event.directresult || result.bool) { + player.logSkill("xiansi2_log", event.target); + game.trySkillAudio("xiansi2", event.target, true); + var links = event.directresult || result.links; target.loseToDiscardpile(links); } }, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.05; + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.05; }, }, - subSkill:{log:{}} + subSkill: { log: {} }, }, - shibei:{ - trigger:{player:'damageEnd'}, - forced:true, - audio:2, - audioname:['xin_jushou'], - check:function(event,player){ - return player.getHistory('damage').indexOf(event)==0; + shibei: { + trigger: { player: "damageEnd" }, + forced: true, + audio: 2, + audioname: ["xin_jushou"], + check: function (event, player) { + return player.getHistory("damage").indexOf(event) == 0; }, - content:function(){ - if(player.getHistory('damage').indexOf(trigger)>0){ + content: function () { + if (player.getHistory("damage").indexOf(trigger) > 0) { player.loseHp(); - } - else{ + } else { player.recover(); } }, - subSkill:{ - damaged:{}, - ai:{} + subSkill: { + damaged: {}, + ai: {}, }, - ai:{ - maixie_defend:true, - threaten:0.9, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing')) return; - if(target.hujia) return; - if(player._shibei_tmp) return; - if(target.hasSkill('shibei_ai')) return; - if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; - if(get.tag(card,'damage')){ - if(target.getHistory('damage').length>0){ - return [1,-2]; - } - else{ - if(get.attitude(player,target)>0&&target.hp>1){ + ai: { + maixie_defend: true, + threaten: 0.9, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing")) return; + if (target.hujia) return; + if (player._shibei_tmp) return; + if (target.hasSkill("shibei_ai")) return; + if ( + _status.event.getParent("useCard", true) || + _status.event.getParent("_wuxie", true) + ) + return; + if (get.tag(card, "damage")) { + if (target.getHistory("damage").length > 0) { + return [1, -2]; + } else { + if (get.attitude(player, target) > 0 && target.hp > 1) { return 0; } - if(get.attitude(player,target)<0&&!player.hasSkillTag('damageBonus')){ - if(card.name=='sha') return; - var sha=false; - player._shibei_tmp=true; - var num=player.countCards('h',function(card){ - if(card.name=='sha'){ - if(sha){ + if ( + get.attitude(player, target) < 0 && + !player.hasSkillTag("damageBonus") + ) { + if (card.name == "sha") return; + var sha = false; + player._shibei_tmp = true; + var num = player.countCards("h", function (card) { + if (card.name == "sha") { + if (sha) { return false; - } - else{ - sha=true; + } else { + sha = true; } } - return get.tag(card,'damage')&&player.canUse(card,target)&&get.effect(target,card,player,player)>0; + return ( + get.tag(card, "damage") && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); }); delete player._shibei_tmp; - if(player.hasSkillTag('damage')){ + if (player.hasSkillTag("damage")) { num++; } - if(num<2){ - var enemies=player.getEnemies(); - if(enemies.length==1&&enemies[0]==target&&player.needsToDiscard()){ + if (num < 2) { + var enemies = player.getEnemies(); + if ( + enemies.length == 1 && + enemies[0] == target && + player.needsToDiscard() + ) { return; } return 0; @@ -13592,1110 +15873,1361 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } } - } - } - } + }, + }, + }, }, - shibei_old:{ - audio:2, - trigger:{player:'damageAfter'}, - forced:true, - content:function(){ - "step 0" - player.judge(function(card){ - if(player.hasSkill('shibei2')){ - if(get.color(card)=='black') return -1; - } - else{ - if(get.color(card)=='red') return 1; + shibei_old: { + audio: 2, + trigger: { player: "damageAfter" }, + forced: true, + content: function () { + "step 0"; + player.judge(function (card) { + if (player.hasSkill("shibei2")) { + if (get.color(card) == "black") return -1; + } else { + if (get.color(card) == "red") return 1; } return 0; - }) - "step 1" - if(result.judge>0){ + }); + "step 1"; + if (result.judge > 0) { player.recover(); - } - else if(result.judge<0){ + } else if (result.judge < 0) { player.loseHp(); } - if(!player.hasSkill('shibei2')){ - player.addTempSkill('shibei2'); + if (!player.hasSkill("shibei2")) { + player.addTempSkill("shibei2"); } - } + }, }, - shibei2:{}, - jianying:{ - audio:2, - locked:false, - mod:{ - aiOrder:function(player,card,num){ - if(typeof card=='object'&&player.isPhaseUsing()){ - var evt=player.getLastUsed(); - if(evt&&evt.card&&(get.suit(evt.card)&&get.suit(evt.card)==get.suit(card)||evt.card.number&&evt.card.number==get.number(card))){ - return num+10; + shibei2: {}, + jianying: { + audio: 2, + locked: false, + mod: { + aiOrder: function (player, card, num) { + if (typeof card == "object" && player.isPhaseUsing()) { + var evt = player.getLastUsed(); + if ( + evt && + evt.card && + ((get.suit(evt.card) && get.suit(evt.card) == get.suit(card)) || + (evt.card.number && evt.card.number == get.number(card))) + ) { + return num + 10; } } }, }, - trigger:{player:'useCard'}, - frequent:true, - filter:function(event,player){ - var evt=player.getLastUsed(1); - if(!evt||!evt.card) return false; - if(!player.isPhaseUsing()) return false; - var evt2=evt.getParent('phaseUse'); - if(!evt2||evt2.name!='phaseUse'||evt2.player!=player) return false; - return get.suit(evt.card)!='none'&&get.suit(evt.card)==get.suit(event.card)|| - typeof get.number(evt.card,false)=='number'&&get.number(evt.card,false)==get.number(event.card); + trigger: { player: "useCard" }, + frequent: true, + filter: function (event, player) { + var evt = player.getLastUsed(1); + if (!evt || !evt.card) return false; + if (!player.isPhaseUsing()) return false; + var evt2 = evt.getParent("phaseUse"); + if (!evt2 || evt2.name != "phaseUse" || evt2.player != player) return false; + return ( + (get.suit(evt.card) != "none" && get.suit(evt.card) == get.suit(event.card)) || + (typeof get.number(evt.card, false) == "number" && + get.number(evt.card, false) == get.number(event.card)) + ); }, - content:function(){ + content: function () { player.draw(); }, - group:'jianying_mark', - init:function(player){ - if(player.isPhaseUsing()){ - var evt=_status.event.getParent('phaseUse'); - var history=player.getHistory('useCard',function(evt2){ - return evt2.getParent('phaseUse')==evt; + group: "jianying_mark", + init: function (player) { + if (player.isPhaseUsing()) { + var evt = _status.event.getParent("phaseUse"); + var history = player.getHistory("useCard", function (evt2) { + return evt2.getParent("phaseUse") == evt; }); - if(history.length){ - var trigger=history[history.length-1]; - if(get.suit(trigger.card,player)=='none'||typeof get.number(trigger.card,player)!='number') return; - player.storage.jianying_mark=trigger.card; - player.markSkill('jianying_mark'); - game.broadcastAll(function(player,suit){ - if(player.marks.jianying_mark) player.marks.jianying_mark.firstChild.innerHTML=get.translation(suit); - },player,get.suit(trigger.card,player)); - player.when('phaseUseAfter').then(()=>{ - player.unmarkSkill('jianying_mark'); + if (history.length) { + var trigger = history[history.length - 1]; + if ( + get.suit(trigger.card, player) == "none" || + typeof get.number(trigger.card, player) != "number" + ) + return; + player.storage.jianying_mark = trigger.card; + player.markSkill("jianying_mark"); + game.broadcastAll( + function (player, suit) { + if (player.marks.jianying_mark) + player.marks.jianying_mark.firstChild.innerHTML = + get.translation(suit); + }, + player, + get.suit(trigger.card, player) + ); + player.when("phaseUseAfter").then(() => { + player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }); } } }, - onremove:function(player){ - player.unmarkSkill('jianying_mark'); + onremove: function (player) { + player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }, - subSkill:{ - mark:{ - charlotte:true, - trigger:{player:'useCard1'}, - filter:function(event,player){ + subSkill: { + mark: { + charlotte: true, + trigger: { player: "useCard1" }, + filter: function (event, player) { return player.isPhaseUsing(); }, - forced:true, - popup:false, - firstDo:true, - content:function(){ - if(get.suit(trigger.card,player)=='none'||typeof get.number(trigger.card,player)!='number') player.unmarkSkill('jianying_mark'); - else{ - player.storage.jianying_mark=trigger.card; - player.markSkill('jianying_mark'); - game.broadcastAll(function(player,suit){ - if(player.marks.jianying_mark) player.marks.jianying_mark.firstChild.innerHTML=get.translation(suit); - },player,get.suit(trigger.card,player)); - player.when('phaseUseAfter').then(()=>{ - player.unmarkSkill('jianying_mark'); + forced: true, + popup: false, + firstDo: true, + content: function () { + if ( + get.suit(trigger.card, player) == "none" || + typeof get.number(trigger.card, player) != "number" + ) + player.unmarkSkill("jianying_mark"); + else { + player.storage.jianying_mark = trigger.card; + player.markSkill("jianying_mark"); + game.broadcastAll( + function (player, suit) { + if (player.marks.jianying_mark) + player.marks.jianying_mark.firstChild.innerHTML = + get.translation(suit); + }, + player, + get.suit(trigger.card, player) + ); + player.when("phaseUseAfter").then(() => { + player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }); } }, - intro:{ - markcount:function(card,player){ - var num=get.number(card,player); - var list=[1,11,12,13]; - if(list.includes(num)) return ['A','J','Q','K'][list.indexOf(num)]; + intro: { + markcount: function (card, player) { + var num = get.number(card, player); + var list = [1, 11, 12, 13]; + if (list.includes(num)) return ["A", "J", "Q", "K"][list.indexOf(num)]; return parseFloat(num); }, - content:function(card,player){ - var suit=get.suit(card,player); - var num=get.number(card,player); - var str='
            • 上一张牌的花色:'+get.translation(suit); - str+='
            • 上一张牌的点数:'; - var list=[1,11,12,13]; - if(list.includes(num)) str+=['A(1)','J(11)','Q(12)','K(13)'][list.indexOf(num)]; - else str+=parseFloat(num); + content: function (card, player) { + var suit = get.suit(card, player); + var num = get.number(card, player); + var str = "
            • 上一张牌的花色:" + get.translation(suit); + str += "
            • 上一张牌的点数:"; + var list = [1, 11, 12, 13]; + if (list.includes(num)) + str += ["A(1)", "J(11)", "Q(12)", "K(13)"][list.indexOf(num)]; + else str += parseFloat(num); return str; }, }, }, }, }, - zzhenggong:{ - trigger:{player:'damageEnd'}, - direct:true, - filter:function(event,player){ - return event.source&&event.source.countCards('e')>0; + zzhenggong: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + return event.source && event.source.countCards("e") > 0; }, - content:function(){ - "step 0" - var att=get.attitude(player,trigger.source); - player.gainPlayerCard('e',get.prompt('zzhenggong'),trigger.source).ai=function(button){ - if(att<=0){ + content: function () { + "step 0"; + var att = get.attitude(player, trigger.source); + player.gainPlayerCard("e", get.prompt("zzhenggong"), trigger.source).ai = function ( + button + ) { + if (att <= 0) { return get.equipValue(button.link); } return 0; - } - "step 1" - if(result.bool){ - player.logSkill('zzhenggong',trigger.source); - var card=result.links[0]; - if(player.getCards('h').includes(card)){ - player.$give(card,player,false); + }; + "step 1"; + if (result.bool) { + player.logSkill("zzhenggong", trigger.source); + var card = result.links[0]; + if (player.getCards("h").includes(card)) { + player.$give(card, player, false); player.equip(card); } } }, - ai:{ - maixie_defend:true, - } + ai: { + maixie_defend: true, + }, }, - zquanji:{ - trigger:{global:'phaseBegin'}, + zquanji: { + trigger: { global: "phaseBegin" }, //priority:15, - check:function(event,player){ - var att=get.attitude(player,event.player); - if(att<0){ - var nh1=event.player.countCards('h'); - var nh2=player.countCards('h'); - return nh1<=2&&nh2>nh1+1; + check: function (event, player) { + var att = get.attitude(player, event.player); + if (att < 0) { + var nh1 = event.player.countCards("h"); + var nh2 = player.countCards("h"); + return nh1 <= 2 && nh2 > nh1 + 1; } - if(att>0&&event.player.hasJudge('lebu')&&event.player.countCards('h')>event.player.hp+1) return true; + if ( + att > 0 && + event.player.hasJudge("lebu") && + event.player.countCards("h") > event.player.hp + 1 + ) + return true; return false; }, - logTarget:'player', - filter:function(event,player){ - return event.player!=player&&player.canCompare(event.player); + logTarget: "player", + filter: function (event, player) { + return event.player != player && player.canCompare(event.player); }, - content:function(){ - "step 0" + content: function () { + "step 0"; player.chooseToCompare(trigger.player); - "step 1" - if(result.bool){ - trigger.player.skip('phaseZhunbei'); - trigger.player.skip('phaseJudge'); + "step 1"; + if (result.bool) { + trigger.player.skip("phaseZhunbei"); + trigger.player.skip("phaseJudge"); } }, - ai:{ - expose:0.2 - } - }, - zbaijiang:{ - skillAnimation:true, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - unique:true, - derivation:['zyexin','zzili','zpaiyi'], - filter:function(event,player){ - return player.countCards('e')>=2; + ai: { + expose: 0.2, }, - content:function(){ - player.awakenSkill('zbaijiang'); + }, + zbaijiang: { + skillAnimation: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + unique: true, + derivation: ["zyexin", "zzili", "zpaiyi"], + filter: function (event, player) { + return player.countCards("e") >= 2; + }, + content: function () { + player.awakenSkill("zbaijiang"); player.gainMaxHp(); - player.changeSkills(['zyexin','zzili'],['zquanji','zzhenggong']); - } + player.changeSkills(["zyexin", "zzili"], ["zquanji", "zzhenggong"]); + }, }, - zyexin:{ - trigger:{player:'damageEnd',source:'damageSource'}, - marktext:'权', - frequent:true, - intro:{ - content:'expansion', - markcount:'expansion', + zyexin: { + trigger: { player: "damageEnd", source: "damageSource" }, + marktext: "权", + frequent: true, + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - content:function(){ - player.addToExpansion('zyexin',get.cards(),'gain2').gaintag.add('zyexin'); + content: function () { + player.addToExpansion("zyexin", get.cards(), "gain2").gaintag.add("zyexin"); }, - group:'zyexin2', + group: "zyexin2", }, - zyexin2:{ - enable:'phaseUse', - usable:1, - lose:false, - discard:false, - delay:false, - selectCard:[1,Infinity], - filterCard:true, - filter:function(event,player){ - return player.getExpansions('zyexin').length>0; + zyexin2: { + enable: "phaseUse", + usable: 1, + lose: false, + discard: false, + delay: false, + selectCard: [1, Infinity], + filterCard: true, + filter: function (event, player) { + return player.getExpansions("zyexin").length > 0; }, - prompt:'用任意数量的手牌与等量的“权”交换', - content:function(){ - 'step 0' - player.addToExpansion(cards,'give',player).gaintag.add('zyexin'); - 'step 1' - player.chooseCardButton(player.getExpansions('zyexin'),'选择'+get.cnNumber(cards.length)+'张牌作为手牌',cards.length,true).ai=function(button){ + prompt: "用任意数量的手牌与等量的“权”交换", + content: function () { + "step 0"; + player.addToExpansion(cards, "give", player).gaintag.add("zyexin"); + "step 1"; + player.chooseCardButton( + player.getExpansions("zyexin"), + "选择" + get.cnNumber(cards.length) + "张牌作为手牌", + cards.length, + true + ).ai = function (button) { return get.value(button.link); - } - 'step 2' - player.gain(result.links,'gain2'); + }; + "step 2"; + player.gain(result.links, "gain2"); + }, + ai: { + order: 5, + result: { + player: 1, + }, }, - ai:{ - order:5, - result:{ - player:1 - } - } }, - zzili:{ - skillAnimation:true, - unique:true, - derivation:'zpaiyi', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return player.getExpansions('zyexin').length>=4; + zzili: { + skillAnimation: true, + unique: true, + derivation: "zpaiyi", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getExpansions("zyexin").length >= 4; }, - forced:true, - async content(e,t,player){ - player.awakenSkill('zzili'); + forced: true, + async content(e, t, player) { + player.awakenSkill("zzili"); player.loseMaxHp(); - player.addSkills('zpaiyi'); + player.addSkills("zpaiyi"); }, // intro:{ // content:'limited' // } }, - zpaiyi:{ - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.getExpansions('zyexin').length; + zpaiyi: { + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return player.getExpansions("zyexin").length; }, - direct:true, - content:function(){ - 'step 0' - var next=player.chooseCardButton(get.prompt('zpaiyi'),player.getExpansions('zyexin')); - next.set('ai',function(button){ + direct: true, + content: function () { + "step 0"; + var next = player.chooseCardButton(get.prompt("zpaiyi"), player.getExpansions("zyexin")); + next.set("ai", function (button) { return get.value(button.link); }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - event.card=card; - player.chooseTarget(function(card,player,target){ - var card=_status.event.card; - var type=get.type(card); - switch(type){ - case 'basic': case 'trick': - return true; - case 'delay': - return target.canAddJudge(card); - case 'equip': - return target.canEquip(card,true); - } - return true; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,_status.event.card,player,player); - }).set('card',card); - } - else{ + "step 1"; + if (result.bool) { + var card = result.links[0]; + event.card = card; + player + .chooseTarget(function (card, player, target) { + var card = _status.event.card; + var type = get.type(card); + switch (type) { + case "basic": + case "trick": + return true; + case "delay": + return target.canAddJudge(card); + case "equip": + return target.canEquip(card, true); + } + return true; + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, _status.event.card, player, player); + }) + .set("card", card); + } else { event.finish(); } - 'step 2' - if(result.bool){ - var type=get.type(event.card),target=result.targets[0]; - player.logSkill('zpaiyi',target); - switch(type){ - case 'basic': case 'trick': - player.give(event.card,target,'give'); + "step 2"; + if (result.bool) { + var type = get.type(event.card), + target = result.targets[0]; + player.logSkill("zpaiyi", target); + switch (type) { + case "basic": + case "trick": + player.give(event.card, target, "give"); break; - case 'delay': - player.$give(event.card,target,false); + case "delay": + player.$give(event.card, target, false); target.addJudge(event.card); break; - case 'equip': - player.$give(event.card,target,false); + case "equip": + player.$give(event.card, target, false); target.equip(event.card); } - if(player!=result.targets[0]){ - player.chooseBool('是否摸一张牌?'); - } - else event.finish(); - } - else event.finish(); - 'step 3' - if(result.bool) player.draw(); + if (player != result.targets[0]) { + player.chooseBool("是否摸一张牌?"); + } else event.finish(); + } else event.finish(); + "step 3"; + if (result.bool) player.draw(); + }, + ai: { + combo: "zyexin", + }, + }, + }, + card: { + lukai_spade: { fullskin: true }, + lukai_heart: { fullskin: true }, + lukai_diamond: { fullskin: true }, + lukai_club: { fullskin: true }, + }, + dynamicTranslate: { + rejueqing: function (player) { + if (player.storage.rejueqing_rewrite) return "锁定技,你即将造成的伤害均视为失去体力。"; + return "当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。"; + }, + reyanzhu: function (player) { + if (!player.storage.reyanzhu) + return "出牌阶段限一次,你可以令一名其他角色选择一项:将装备区里的所有牌交给你并令你修改〖宴诛〗和〖兴学〗,或弃置一张牌并令下一次受到的伤害+1直到其下回合开始。"; + return "出牌阶段限一次,你可以选择一名其他角色。该角色下一次受到的伤害+1直到其下回合开始。"; + }, + rexingxue: function (player) { + if (player.storage.reyanzhu) + return "结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力上限)。"; + return "结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力值)。"; + }, + jiaozhao: function (player) { + var num = player.countMark("xindanxin"); + if (num > 2) + return "出牌阶段限两次,你可以将一张手牌当做任意基本牌或普通锦囊牌使用(你不能对自己使用此牌)。"; + if (num > 1) + return "出牌阶段限一次,你可以将一张手牌当做任意基本牌或普通锦囊牌使用(你不能对自己使用此牌)。"; + if (num > 0) + return "出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌或普通锦囊牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌,且此牌不可被【无懈可击】响应)。"; + return "出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌,且此牌不可被【无懈可击】响应)。"; + }, + funan: function (player) { + if (player.hasSkill("funan_jiexun")) + return "其他角色使用或打出牌响应你使用的牌时,你可获得其使用或打出的牌。"; + return "其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。"; + }, + lkbushi: function (player) { + var list = lib.skill.lkbushi.getBushi(player).map((i) => get.translation(i)); + return ( + "①你使用" + + list[0] + + "牌无次数限制。②当你使用或打出" + + list[1] + + "牌后,你摸一张牌。③当你成为" + + list[2] + + "牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张" + + list[3] + + "牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。" + ); + }, + diezhang: function (player) { + var str = ""; + str += player.storage.duanwan ? "" : "①出牌阶段,你使用杀的次数上限+1。②"; + str += "转换技" + (player.storage.duanwan ? ",每回合限一次" : "") + "。"; + var cnNum = get.cnNumber(player.storage.duanwan ? 2 : 1); + var yinStr = + "阴:当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用" + cnNum + "张【杀】"; + var yangStr = + "阳:当其他角色使用牌被你抵消后,你可以摸" + cnNum + "张牌,视为对其使用一张【杀】"; + if (player.storage.diezhang) { + if (player.storage.duanwan) + yinStr = '' + yinStr + ""; + yangStr = '' + yangStr + ""; + } else { + yinStr = '' + yinStr + ""; + if (player.storage.duanwan) + yangStr = '' + yangStr + ""; } - } - }, - card:{ - lukai_spade:{fullskin:true}, - lukai_heart:{fullskin:true}, - lukai_diamond:{fullskin:true}, - lukai_club:{fullskin:true}, - }, - dynamicTranslate:{ - rejueqing:function(player){ - if(player.storage.rejueqing_rewrite) return '锁定技,你即将造成的伤害均视为失去体力。'; - return '当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力,并于此伤害结算完成后修改〖绝情〗(X为伤害值)。'; - }, - reyanzhu:function(player){ - if(!player.storage.reyanzhu) return '出牌阶段限一次,你可以令一名其他角色选择一项:将装备区里的所有牌交给你并令你修改〖宴诛〗和〖兴学〗,或弃置一张牌并令下一次受到的伤害+1直到其下回合开始。'; - return '出牌阶段限一次,你可以选择一名其他角色。该角色下一次受到的伤害+1直到其下回合开始。'; - }, - rexingxue:function(player){ - if(player.storage.reyanzhu) return '结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力上限)。'; - return '结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力值)。'; - }, - jiaozhao:function(player){ - var num=player.countMark('xindanxin'); - if(num>2) return '出牌阶段限两次,你可以将一张手牌当做任意基本牌或普通锦囊牌使用(你不能对自己使用此牌)。'; - if(num>1) return '出牌阶段限一次,你可以将一张手牌当做任意基本牌或普通锦囊牌使用(你不能对自己使用此牌)。'; - if(num>0) return '出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌或普通锦囊牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌,且此牌不可被【无懈可击】响应)。'; - return '出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌,且此牌不可被【无懈可击】响应)。'; - }, - funan:function(player){ - if(player.hasSkill('funan_jiexun')) return '其他角色使用或打出牌响应你使用的牌时,你可获得其使用或打出的牌。'; - return '其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。'; - }, - lkbushi:function(player){ - var list=lib.skill.lkbushi.getBushi(player).map((i)=>get.translation(i)); - return '①你使用'+list[0]+'牌无次数限制。②当你使用或打出'+list[1]+'牌后,你摸一张牌。③当你成为'+list[2]+'牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张'+list[3]+'牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。'; - }, - diezhang:function(player){ - var str=''; - str+=player.storage.duanwan?'':'①出牌阶段,你使用杀的次数上限+1。②'; - str+='转换技'+(player.storage.duanwan?',每回合限一次':'')+'。'; - var cnNum=get.cnNumber(player.storage.duanwan?2:1); - var yinStr='阴:当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用'+cnNum+'张【杀】'; - var yangStr='阳:当其他角色使用牌被你抵消后,你可以摸'+cnNum+'张牌,视为对其使用一张【杀】'; - if(player.storage.diezhang){ - if(player.storage.duanwan) yinStr=''+yinStr+''; - yangStr=''+yangStr+''; - } - else{ - yinStr=''+yinStr+''; - if(player.storage.duanwan) yangStr=''+yangStr+''; - } - return str+yinStr+';'+yangStr+'。'; + return str + yinStr + ";" + yangStr + "。"; }, }, - characterReplace:{ - caozhi:['caozhi','dc_caozhi','re_caozhi','ps_caozhi'], - zhangchunhua:['zhangchunhua','re_zhangchunhua'], - yujin:['yujin','yujin_yujin','ol_yujin','sb_yujin','xin_yujin','re_yujin'], - dc_xushu:['re_xushu','dc_xushu'], - xushu:['xin_xushu','xushu'], - fazheng:['xin_fazheng','re_fazheng','sb_fazheng','tw_re_fazheng','fazheng'], - masu:['xin_masu','re_masu','masu'], - xusheng:['xusheng','xin_xusheng','re_xusheng','old_xusheng'], - wuguotai:['wuguotai','xin_wuguotai','re_wuguotai'], - lingtong:['lingtong','xin_lingtong','ol_lingtong','re_lingtong','old_lingtong'], - gaoshun:['gaoshun','xin_gaoshun','ol_gaoshun','re_gaoshun','sb_gaoshun','old_gaoshun'], - zhonghui:['zhonghui','xin_zhonghui','re_zhonghui','old_zhonghui','pe_zhonghui'], - wangyi:['wangyi','ol_wangyi','re_wangyi','old_wangyi'], - caozhang:['caozhang','ol_caozhang','re_caozhang','xin_caozhang'], - guanzhang:['guanzhang','re_guanzhang','old_guanzhang'], - madai:['old_madai','re_madai','tw_madai','madai'], - liaohua:['liaohua','re_liaohua','xin_liaohua'], - bulianshi:['bulianshi','dc_bulianshi','re_bulianshi','old_bulianshi'], - handang:['handang','xin_handang','re_handang','tw_handang','old_handang'], - chengpu:['chengpu','ol_chengpu','re_chengpu','xin_chengpu','tw_chengpu','ns_chengpu'], - liubiao:['liubiao','xin_liubiao','re_liubiao','sb_liubiao','oldre_liubiao','old_liubiao'], - manchong:['manchong','re_manchong'], - caochong:['caochong','re_caochong','old_caochong'], - guohuai:['guohuai','re_guohuai','xin_guohuai','tw_guohuai','ol_guohuai'], - jianyong:['jianyong','ol_jianyong','re_jianyong','xin_jianyong'], - panzhangmazhong:['panzhangmazhong','re_panzhangmazhong','xin_panzhangmazhong'], - yufan:['yufan','ol_yufan','xin_yufan','re_yufan'], - zhuran:['zhuran','re_zhuran','xin_zhuran','old_zhuran'], - liru:['xin_liru','dc_liru','re_liru','yj_liru','+liru'], - fuhuanghou:['fuhuanghou','re_fuhuanghou','xin_fuhuanghou','old_fuhuanghou'], - chenqun:['chenqun','dc_chenqun','re_chenqun','old_chenqun'], - hanhaoshihuan:['hanhaoshihuan','re_hanhaoshihuan'], - caozhen:['caozhen','re_caozhen','xin_caozhen','old_caozhen'], - wuyi:['wuyi','re_wuyi','xin_wuyi'], - sunluban:['re_sunluban','xin_sunluban','sunluban'], - zhuhuan:['re_zhuhuan','xin_zhuhuan','zhuhuan','old_zhuhuan'], - caoxiu:['caoxiu','re_caoxiu','xin_caoxiu','tw_caoxiu','old_caoxiu'], - xiahoushi:['xiahoushi','re_xiahoushi','sb_xiahoushi'], - zhangyi:['zhangyi','re_zhangyi','xin_zhangyi'], - quancong:['quancong','re_quancong','xin_quancong','old_quancong'], - sunxiu:['sunxiu','re_sunxiu','xin_sunxiu'], - zhuzhi:['zhuzhi','re_zhuzhi','xin_zhuzhi','old_zhuzhi'], - liuyu:['liuyu','dc_liuyu','ol_liuyu'], - zhangrang:['zhangrang','ol_zhangrang','junk_zhangrang'], - jikang:['jikang','re_jikang','dc_jikang'], - xinxianying:['xinxianying','re_xinxianying','ol_xinxianying','sp_xinxianying'], - gongsunyuan:['gongsunyuan','re_gongsunyuan'], - zhoucang:['zhoucang','re_zhoucang','xin_zhoucang'], - guotufengji:['guotufengji','re_guotufengji'], - guanping:['guanping','re_guanping'], - caifuren:['caifuren','re_caifuren','xin_caifuren'], - guyong:['guyong','re_guyong','xin_guyong','tw_guyong'], - yj_jushou:['yj_jushou','re_jushou','xin_jushou'], - guohuanghou:['guohuanghou','re_guohuanghou'], - liuchen:['liuchen','re_liuchen'], - liufeng:['liufeng','re_liufeng'], - sundeng:['sundeng','re_sundeng','ns_sundeng'], - caiyong:['caiyong','re_caiyong'], - chengong:['chengong','re_chengong','sb_chengong'], - xunyou:['xunyou','re_xunyou','clan_xunyou'], - xuezong:['xuezong','tw_xuezong'], - huanghao:['huanghao','dc_huanghao','old_huanghao'], - caorui:['caorui','re_caorui','old_caorui'], - sunziliufang:['sunziliufang','dc_sunziliufang'], - liyan:['liyan','old_liyan'], - zhangsong:['zhangsong','re_zhangsong'], - zhongyao:['zhongyao','re_zhongyao'], - liwan:['ol_liwan','liwan'], - wuxian:['wuxian','clan_wuxian'], + characterReplace: { + caozhi: ["caozhi", "dc_caozhi", "re_caozhi", "ps_caozhi"], + zhangchunhua: ["zhangchunhua", "re_zhangchunhua"], + yujin: ["yujin", "yujin_yujin", "ol_yujin", "sb_yujin", "xin_yujin", "re_yujin"], + dc_xushu: ["re_xushu", "dc_xushu"], + xushu: ["xin_xushu", "xushu"], + fazheng: ["xin_fazheng", "re_fazheng", "sb_fazheng", "tw_re_fazheng", "fazheng"], + masu: ["xin_masu", "re_masu", "masu"], + xusheng: ["xusheng", "xin_xusheng", "re_xusheng", "old_xusheng"], + wuguotai: ["wuguotai", "xin_wuguotai", "re_wuguotai"], + lingtong: ["lingtong", "xin_lingtong", "ol_lingtong", "re_lingtong", "old_lingtong"], + gaoshun: ["gaoshun", "xin_gaoshun", "ol_gaoshun", "re_gaoshun", "sb_gaoshun", "old_gaoshun"], + zhonghui: ["zhonghui", "xin_zhonghui", "re_zhonghui", "old_zhonghui", "pe_zhonghui"], + wangyi: ["wangyi", "ol_wangyi", "re_wangyi", "old_wangyi"], + caozhang: ["caozhang", "ol_caozhang", "re_caozhang", "xin_caozhang"], + guanzhang: ["guanzhang", "re_guanzhang", "old_guanzhang"], + madai: ["old_madai", "re_madai", "tw_madai", "madai"], + liaohua: ["liaohua", "re_liaohua", "xin_liaohua"], + bulianshi: ["bulianshi", "dc_bulianshi", "re_bulianshi", "old_bulianshi"], + handang: ["handang", "xin_handang", "re_handang", "tw_handang", "old_handang"], + chengpu: ["chengpu", "ol_chengpu", "re_chengpu", "xin_chengpu", "tw_chengpu", "ns_chengpu"], + liubiao: ["liubiao", "xin_liubiao", "re_liubiao", "sb_liubiao", "oldre_liubiao", "old_liubiao"], + manchong: ["manchong", "re_manchong"], + caochong: ["caochong", "re_caochong", "old_caochong"], + guohuai: ["guohuai", "re_guohuai", "xin_guohuai", "tw_guohuai", "ol_guohuai"], + jianyong: ["jianyong", "ol_jianyong", "re_jianyong", "xin_jianyong"], + panzhangmazhong: ["panzhangmazhong", "re_panzhangmazhong", "xin_panzhangmazhong"], + yufan: ["yufan", "ol_yufan", "xin_yufan", "re_yufan"], + zhuran: ["zhuran", "re_zhuran", "xin_zhuran", "old_zhuran"], + liru: ["xin_liru", "dc_liru", "re_liru", "yj_liru", "+liru"], + fuhuanghou: ["fuhuanghou", "re_fuhuanghou", "xin_fuhuanghou", "old_fuhuanghou"], + chenqun: ["chenqun", "dc_chenqun", "re_chenqun", "old_chenqun"], + hanhaoshihuan: ["hanhaoshihuan", "re_hanhaoshihuan"], + caozhen: ["caozhen", "re_caozhen", "xin_caozhen", "old_caozhen"], + wuyi: ["wuyi", "re_wuyi", "xin_wuyi"], + sunluban: ["re_sunluban", "xin_sunluban", "sunluban"], + zhuhuan: ["re_zhuhuan", "xin_zhuhuan", "zhuhuan", "old_zhuhuan"], + caoxiu: ["caoxiu", "re_caoxiu", "xin_caoxiu", "tw_caoxiu", "old_caoxiu"], + xiahoushi: ["xiahoushi", "re_xiahoushi", "sb_xiahoushi"], + zhangyi: ["zhangyi", "re_zhangyi", "xin_zhangyi"], + quancong: ["quancong", "re_quancong", "xin_quancong", "old_quancong"], + sunxiu: ["sunxiu", "re_sunxiu", "xin_sunxiu"], + zhuzhi: ["zhuzhi", "re_zhuzhi", "xin_zhuzhi", "old_zhuzhi"], + liuyu: ["liuyu", "dc_liuyu", "ol_liuyu"], + zhangrang: ["zhangrang", "ol_zhangrang", "junk_zhangrang"], + jikang: ["jikang", "re_jikang", "dc_jikang"], + xinxianying: ["xinxianying", "re_xinxianying", "ol_xinxianying", "sp_xinxianying"], + gongsunyuan: ["gongsunyuan", "re_gongsunyuan"], + zhoucang: ["zhoucang", "re_zhoucang", "xin_zhoucang"], + guotufengji: ["guotufengji", "re_guotufengji"], + guanping: ["guanping", "re_guanping"], + caifuren: ["caifuren", "re_caifuren", "xin_caifuren"], + guyong: ["guyong", "re_guyong", "xin_guyong", "tw_guyong"], + yj_jushou: ["yj_jushou", "re_jushou", "xin_jushou"], + guohuanghou: ["guohuanghou", "re_guohuanghou"], + liuchen: ["liuchen", "re_liuchen"], + liufeng: ["liufeng", "re_liufeng"], + sundeng: ["sundeng", "re_sundeng", "ns_sundeng"], + caiyong: ["caiyong", "re_caiyong"], + chengong: ["chengong", "re_chengong", "sb_chengong"], + xunyou: ["xunyou", "re_xunyou", "clan_xunyou"], + xuezong: ["xuezong", "tw_xuezong"], + huanghao: ["huanghao", "dc_huanghao", "old_huanghao"], + caorui: ["caorui", "re_caorui", "old_caorui"], + sunziliufang: ["sunziliufang", "dc_sunziliufang"], + liyan: ["liyan", "old_liyan"], + zhangsong: ["zhangsong", "re_zhangsong"], + zhongyao: ["zhongyao", "re_zhongyao"], + liwan: ["ol_liwan", "liwan"], + wuxian: ["wuxian", "clan_wuxian"], }, - translate:{ - old_huaxiong:'将华雄', - old_huaxiong_prefix:'将', - yufan:'虞翻', - xushu:'旧徐庶', - xushu_prefix:'旧', - caozhi:'曹植', - zhangchunhua:'张春华', - lingtong:'凌统', - xunyou:'荀攸', - liubiao:'刘表', - zhuran:'朱然', - yujin:'于禁', - masu:'旧马谡', - masu_prefix:'旧', - xin_masu:'马谡', - xin_fazheng:'法正', - wuguotai:'吴国太', - chengong:'陈宫', - xusheng:'徐盛', - guohuai:'郭淮', - caochong:'曹冲', - bulianshi:'步练师', - handang:'韩当', - fuhuanghou:'伏寿', - caifuren:'蔡夫人', - zhonghui:'钟会', - old_zhonghui:'旧钟会', - old_zhonghui_prefix:'旧', - sunluban:'孙鲁班', - chenqun:'陈群', - zhangsong:'张松', - guyong:'顾雍', - jianyong:'简雍', - old_madai:'马岱', - gz_madai:'马岱', - xin_xushu:'徐庶', - manchong:'满宠', - liufeng:'刘封', - liru:'旧李儒', - liru_prefix:'旧', - yj_jushou:'沮授', - zhuhuan:'朱桓', - xiahoushi:'夏侯氏', - panzhangmazhong:'潘璋马忠', - caorui:'曹叡', - caoxiu:'曹休', - zhongyao:'钟繇', - liuchen:'刘谌', - zhangyi:'张嶷', - sunxiu:'孙休', - zhuzhi:'朱治', - quancong:'全琮', - gongsunyuan:'公孙渊', - guotufengji:'郭图逢纪', - zhoucang:'周仓', - guanping:'关平', - liaohua:'廖化', - caozhen:'曹真', - wuyi:'吴懿', - hanhaoshihuan:'韩浩史涣', - chengpu:'程普', - gaoshun:'高顺', - xin_liru:'李儒', - guohuanghou:'郭皇后', - liuyu:'刘虞', - sundeng:'孙登', - liyan:'李严', - sunziliufang:'孙资刘放', - huanghao:'黄皓', - zhangrang:'张让', - cenhun:'岑昏', - xinxianying:'辛宪英', - wuxian:'吴苋', - xushi:'徐氏', - caojie:'曹节', - xuezong:'薛综', - jikang:'嵇康', - qinmi:'秦宓', - caiyong:'蔡邕', + translate: { + old_huaxiong: "将华雄", + old_huaxiong_prefix: "将", + yufan: "虞翻", + xushu: "旧徐庶", + xushu_prefix: "旧", + caozhi: "曹植", + zhangchunhua: "张春华", + lingtong: "凌统", + xunyou: "荀攸", + liubiao: "刘表", + zhuran: "朱然", + yujin: "于禁", + masu: "旧马谡", + masu_prefix: "旧", + xin_masu: "马谡", + xin_fazheng: "法正", + wuguotai: "吴国太", + chengong: "陈宫", + xusheng: "徐盛", + guohuai: "郭淮", + caochong: "曹冲", + bulianshi: "步练师", + handang: "韩当", + fuhuanghou: "伏寿", + caifuren: "蔡夫人", + zhonghui: "钟会", + old_zhonghui: "旧钟会", + old_zhonghui_prefix: "旧", + sunluban: "孙鲁班", + chenqun: "陈群", + zhangsong: "张松", + guyong: "顾雍", + jianyong: "简雍", + old_madai: "马岱", + gz_madai: "马岱", + xin_xushu: "徐庶", + manchong: "满宠", + liufeng: "刘封", + liru: "旧李儒", + liru_prefix: "旧", + yj_jushou: "沮授", + zhuhuan: "朱桓", + xiahoushi: "夏侯氏", + panzhangmazhong: "潘璋马忠", + caorui: "曹叡", + caoxiu: "曹休", + zhongyao: "钟繇", + liuchen: "刘谌", + zhangyi: "张嶷", + sunxiu: "孙休", + zhuzhi: "朱治", + quancong: "全琮", + gongsunyuan: "公孙渊", + guotufengji: "郭图逢纪", + zhoucang: "周仓", + guanping: "关平", + liaohua: "廖化", + caozhen: "曹真", + wuyi: "吴懿", + hanhaoshihuan: "韩浩史涣", + chengpu: "程普", + gaoshun: "高顺", + xin_liru: "李儒", + guohuanghou: "郭皇后", + liuyu: "刘虞", + sundeng: "孙登", + liyan: "李严", + sunziliufang: "孙资刘放", + huanghao: "黄皓", + zhangrang: "张让", + cenhun: "岑昏", + xinxianying: "辛宪英", + wuxian: "吴苋", + xushi: "徐氏", + caojie: "曹节", + xuezong: "薛综", + jikang: "嵇康", + qinmi: "秦宓", + caiyong: "蔡邕", - "new_qingxian":"清弦", - "new_qingxian_info":"出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)", - "new_juexiang":"绝响", - "new_juexiang_info":"锁定技,当你死亡后,杀死你的角色弃置装备区内的所有牌并失去1点体力。然后,你可以令一名其他角色获得技能〖残韵〗。若该角色区域内有梅花牌,则其可以弃置其中的一张,然后其获得技能〖绝响〗。", - "new_canyun":"残韵", - "new_canyun_info":"出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色(不能选择已经成为过〖残韵〗目标的角色)。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)", - "qingxian_draw":"清弦", - "qingxian_draw_info":"", - zhenjun:"镇军", - "zhenjun_info":"准备阶段,你可以弃置一名手牌数多于体力值的角色的X张牌(X为其手牌数和体力值之差),然后选择一项:1.你弃置等同于其中非装备牌数量的牌;2.其摸等量的牌。", - rezhenjun:"镇军", - rezhenjun_info:"准备阶段,你可以弃置一名角色的X张牌(X为其手牌数和体力值之差且至少为1),然后选择一项:1.你弃置X张牌;2.其摸X张牌。(X为其弃置的牌中非装备牌的数量)", - fenli:'奋励', - fenli_info:'若你的手牌数为全场最多,你可以跳过摸牌阶段;若你的体力值为全场最多,你可以跳过出牌阶段;若你的装备区里有牌且数量为全场最多,你可以跳过弃牌阶段。', - pingkou:'平寇', - pingkou_info:'回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。', - xinanguo:'安国', - xinanguo_info:'出牌阶段限一次,你可以选择一名其他角色,若其手牌数为全场最少,其摸一张牌;体力值为全场最低,回复1点体力;装备区内牌数为全场最少,随机使用一张装备牌。然后若该角色有未执行的效果且你满足条件,你执行之。', - pindi:'品第', - pindi_info:'出牌阶段,你可以弃置一张牌并选择一名其他角色(不能弃置相同类型牌且不能指定相同的角色),然后令其执行一项:摸X张牌;弃置X张牌(X为本回合此技能发动次数)。若其已受伤,你横置。', - funan_jiexun:'诫训', - bizhuan:'辟撰', - bizhuan_bg:'书', - bizhuan_info:'当你使用黑桃牌后,或你成为其他角色使用黑桃牌的目标后,你可以将牌堆顶的一张牌置于武将牌上,称为“书”;你至多拥有四张“书”,你每有一张“书” ,手牌上限+1。', - tongbo:'通博', - tongbo_info:'摸牌阶段摸牌后,你可以用任意张牌替换等量的“书”,然后若你的“书”包含四种花色,你将所有“书”交给任意名其他角色。', - qingxian:'清弦', - qingxian_info:'当你受到伤害/回复体力后,你可以令伤害来源/一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你摸一张牌。', - juexiang:'绝响', - juexiang_info:'当你死亡后,你可以令一名角色随机获得“清弦残谱”其中一个技能,然后直到其下回合开始,其不能被选择为其他角色使用梅花牌的目标。', - juexiang_ji:'激弦', - juexiang_ji_info:'当你受到伤害后,你可以令伤害来源失去1点体力,随机使用一张装备。', - juexiang_lie:'烈弦', - juexiang_lie_info:'当你回复体力后,你可以令一名其他角色失去1点体力,随机使用一张装备。', - juexiang_rou:'柔弦', - juexiang_rou_info:'当你受到伤害后,你可以令伤害来源回复1点体力,弃置一张装备。', - juexiang_he:'和弦', - juexiang_he_info:'当你回复体力后,你可以令一名其他角色回复1点体力,弃置一张装备。', - juexiang_club:'绝响', - juexiang_club_bg:'响', - juexiang_club_info:'直到下回合开始,不能被选择为其他角色使用梅花牌的目标。', - jianzheng:'谏征', - jianzheng_info:'当一名其他角色使用【杀】指定目标时,若你在其攻击范围内且你不是目标,则你可以将一张手牌置于牌堆顶,取消所有目标,然后若此【杀】不为黑色,你成为目标。', - zhuandui:'专对', - zhuandui_info:'当你使用【杀】指定目标/成为【杀】的目标后,你可以与目标角色/此【杀】使用者拼点,若你赢,此杀不能被【闪】响应/对你无效。', - zhuandui_use_info:'当你使用【杀】指定目标后,你可以与目标角色拼点,若你赢,此杀不能被【闪】响应。', - zhuandui_respond_info:'当你成为【杀】的目标后,你可以与此【杀】使用者拼点,若你赢,此杀对你无效。', - tianbian:'天辩', - tianbian_info:'你拼点时,可以改为用牌堆顶的一张牌进行拼点;当你拼点的牌亮出后,若此牌花色为红桃,则此牌的点数视为K。', - funan:'复难', - funan_info:'其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。', - jiexun:'诫训', - jiexun_info:'结束阶段,你可令一名其他角色摸等同于场上方块牌数的牌,然后弃置X张牌(X为此前该技能发动过的次数)。若有角色因此法弃置了所有牌,则你失去〖诫训〗,然后你发动〖复难〗时,无须令对方获得你使用的牌。', - xinjiexun:'诫训', - xinjiexun_info:'结束阶段,你可令一名其他角色摸等同于场上方块牌数的牌,然后弃置X张牌(X为此前该技能发动过的次数)。若有角色因此法弃置了所有牌,则你将X归零,然后你发动〖复难〗时,无须令对方获得你使用的牌。', - shouxi:'守玺', - shouxi_info:'当你成为【杀】的目标后,你可声明一种未以此法声明过的基本牌或锦囊牌的牌名。若使用者弃置一张你声明的牌,其获得你的一张牌;若否,则此【杀】对你无效。', - huimin:'惠民', - huimin_info:'结束阶段,你可以摸X张牌并展示等量手牌(X为手牌数小于其体力值的角色数),然后从你指定的一名角色开始这些角色依次选择并获得其中一张。', - wengua:'问卦', - wengua2:'问卦', - wengua_info:'其他角色/你的出牌阶段限一次,其可以交给你一张牌,(若当前回合角色为你,则跳过此步骤),你可以将此牌/一张牌置于牌堆顶或牌堆底,然后你与其/你从另一端摸一张牌。', - fuzhu:'伏诛', - fuzhu_info:'一名男性角色的结束阶段,若牌堆剩余牌数不大于你体力值的十倍,则你可以依次对其使用牌堆中所有的【杀】(不能超过游戏人数),然后洗牌。', - fumian:'福绵', - fumian_info:'准备阶段,你可以选择一项:1.摸牌阶段多摸一张牌;2.使用红色牌可以多选择一个目标(限一次)。若与你上回合选择的选项不同,则该选项数值+1并复原此技能。', - daiyan:'怠宴', - daiyan_info:'结束阶段,你可以令一名其他角色从牌堆中获得一张红桃基本牌,然后若其于上回合成为过该技能目标,则其失去1点体力。', - xinzhongjian:'忠鉴', - xinzhongjian_info:'出牌阶段限一次,你可以展示自己的一张手牌,然后展示一名其他角色的至多三张手牌。其展示的牌中:每有一张花色相同,你摸一张牌;点数相同,你对其造成1点伤害;均不同,你弃置一张手牌。', - zhongjian:'忠鉴', - zhongjian_bg:'鉴', - zhongjian3:'忠鉴', - zhongjian3_bg:'鉴', - zhongjian_info:'出牌阶段限一次,你可以展示一张手牌,然后展示一名其他角色的X张手牌(X为其体力值)。若以此法展示的牌与你展示的牌:有颜色相同的,你选择:①摸一张牌。②弃置一名其他角色的一张牌;有点数相同的,本回合此技能改为“出牌阶段限两次”;均不同,你的手牌上限-1。', - caishi:'才识', - caishix:'才识/忠鉴', - caishi_info:'摸牌阶段开始时,你可以选择一项:1.令手牌上限+1;2.回复1点体力,本回合内不能对自己使用牌。', - xincaishi:'才识', - xincaishi_info:'摸牌阶段,你可以选择一项:1.少摸一张牌,然后本回合发动〖忠鉴〗时可以多展示自己的一张牌;2.本回合手牌上限-1,然后本回合发动〖忠鉴〗时可以多展示对方的一张牌;3.多摸两张牌,本回合不能发动〖忠鉴〗。', - guizao:'瑰藻', - guizao_info:'弃牌阶段结束时,若你于此阶段弃置牌的数量不小于2且它们的花色各不相同,你可以回复1点体力或摸一张牌。', - jiyu:'讥谀', - jiyu_info:'出牌阶段限一次,你可以令一名角色弃置一张手牌。若如此做,你不能使用与之相同花色的牌,直到回合结束。若其以此法弃置的牌为黑桃,你翻面并令其失去1点体力。若你有未被〖讥谀〗限制的手牌,则你可以继续发动此技能,但不能选择本回合已经选择过的目标。', - qinqing:'寝情', - qinqing_info:'结束阶段,你可以选择任意名攻击范围内含有主公的角色,然后弃置这些角色各一张牌并令其摸一张牌(无牌则不弃),若如此做,你摸X张牌(X为其中手牌比主公多的角色数)。', - qinqing_info_doudizhu:'结束阶段,你可以选择任意名攻击范围内含有地主的角色,然后弃置这些角色各一张牌并令其摸一张牌(无牌则不弃),若如此做,你摸X张牌(X为其中手牌比地主多的角色数)。', - huisheng:'贿生', - huisheng_info:'当你受到其他角色对你造成的伤害时,你可以令其观看你任意数量的牌并令其选择一项:1.获得这些牌中的一张,防止此伤害,然后你不能再对其发动〖贿生〗;2.弃置等量的牌。', - jishe:'极奢', - jishe2:'极奢', - jishe_info:'①出牌阶段限20次,若你的手牌上限大于0,你可以摸一张牌,然后你本回合的手牌上限-1。②结束阶段开始时,若你没有手牌,则你可以横置至多X名角色的武将牌(X为你的体力值)。', - lianhuo:'链祸', - lianhuo_info:'锁定技,当你受到火焰伤害时,若你的武将牌处于横置状态且此伤害不为连环伤害,则此伤害+1。', - taoluan:'滔乱', - taoluan_backup:'滔乱', - taoluan_info:'你可以将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本局游戏你以此法使用过的牌),然后你令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力且〖滔乱〗无效直到回合结束。', - xintaoluan:'滔乱', - xintaoluan_backup:'滔乱', - xintaoluan_info:'若场上没有濒死的角色,则你可以将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本回合内你以此法使用过的牌),然后你令一名其他角色选择一项:1.交给你X张与你以此法使用的牌类别不同的牌;2.你失去X点体力且滔乱无效直到回合结束(X为你本回合内发动过〖滔乱〗的次数且至多为3)。', - jiaozhao:'矫诏', - jiaozhao3:'矫诏', - jiaozhao3_backup:'矫诏', - jiaozhao2:'矫诏', - jiaozhao_info:'出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌)。', - danxin:'殚心', - danxin_info:'当你受到伤害后,你可以摸一张牌,或对“矫诏”的描述依次执行下列一项修改:1.将“基本牌”改为“基本牌或普通锦囊牌”;2.将“选择距离最近的一名其他角色,该角色”改为“你”。', - xindanxin:'殚心', - xindanxin_info:'当你受到伤害后,你可以摸一张牌,并对“矫诏”的描述依次执行下列一项修改:1.将“基本牌”改为“基本牌或普通锦囊牌”;2.将“选择距离最近的一名其他角色,该角色”改为“你”。3.将“出牌阶段限一次”改为“出牌阶段限两次”。', - duliang:'督粮', - duliang2:'督粮', - duliang_info:'出牌阶段限一次,你可以获得一名其他角色的一张手牌,然后选择一项:1.令其观看牌堆顶的两张牌,然后获得其中的基本牌;2.令其于下个摸牌阶段额外摸一张牌。', - fulin:'腹鳞', - fulin_info:'锁定技,你于回合内得到的牌不计入你本回合的手牌上限。', - kuangbi:'匡弼', - kuangbi_info:'出牌阶段限一次,你可以选择一名有牌的其他角色,该角色将其的一至三张牌置于你的武将牌上。若如此做,你的下个准备阶段,你获得武将牌上的所有牌,然后其摸等量的牌。', - xinzhige:'止戈', - xinzhige_info:'出牌阶段限一次,你可以令一名攻击范围内含有你的其他角色交给你一张【杀】或武器牌,否则其视为对你指定的另一名其攻击范围内的角色使用了一张【杀】。', - zhige:'止戈', - zhige_info:'出牌阶段限一次,若你的手牌数大于你的体力值,你可以选择攻击范围内含有你的一名其他角色,其选择一项:1.使用一张【杀】;2.将装备区里的一张牌交给你。', - xinzongzuo:'宗祚', - xinzongzuo_info:'锁定技,游戏的第一个回合开始前,你加X点体力上限并回复X点体力(X为全场势力数);当一名角色死亡后,若没有与其势力相同的角色,你减1点体力上限并摸两张牌。', - zongzuo:'宗祚', - zongzuo_info:'锁定技,游戏的第一个回合开始前,你加X点体力上限并回复X点体力(X为全场势力数);当一名角色死亡后,若没有与其势力相同的角色,你减1点体力上限。', - xinjuece:'绝策', - xinjuece_info:'结束阶段,你可以对一名没有手牌的角色造成1点伤害。', - xinmieji:'灭计', - xinmieji_info:'出牌阶段限一次,你可以展示一张黑色锦囊牌并将之置于牌堆顶,然后令有手牌的一名其他角色选择一项:弃置一张锦囊牌;或依次弃置两张非锦囊牌。', - xinfencheng:'焚城', - xinfencheng_info:'限定技。出牌阶段,你可以令所有其他角色各选择一项:弃置至少X张牌(X为该角色的上家以此法弃置牌的数量+1);或受到你对其造成的2点火焰伤害。', - qianju:'千驹', - qianju_info:'锁定技,若你已受伤,你计算与其他角色的距离时-X(X为你已损失的体力值)。', - qingxi:'倾袭', - qingxi_info:'当你使用【杀】对目标角色造成伤害时,若你的装备区里有武器牌,你可以令其选择一项:1、弃置X张手牌(X为此武器牌的攻击范围),若如此做,其弃置你的此武器牌;2、令伤害值+1。', - reqianju:'千驹', - reqianju_info:'锁定技,若你已受伤,你计算与其他角色的距离时-X(X为你已损失的体力值且至少为1)。', - reqingxi:'倾袭', - reqingxi_info:'当你使用【杀】或【决斗】指定目标后,你可以令其选择一项:1、弃置X张手牌(X为你攻击范围内的角色数,且当你装备区内有武器牌/没有武器牌时至多为4/2),若如此做,其弃置你的此武器牌;2、令此牌的伤害值+1且你进行判定,若结果为红色,则其不能响应此牌。', - jieyue:'节钺', - jieyue_info:'①结束阶段,你可以弃置一张手牌,然后令一名其他角色选择一项:1.将一张牌置于你的武将牌上,称之为“节”;2.令你弃置其一张牌。②若你有“节”,你可以将红色/黑色手牌当作【闪】/【无懈可击】使用或打出。③准备阶段,若你有“节”,则你获得之。', - xianzhen:'陷阵', - xianzhen_info:'出牌阶段限一次,你可以与一名角色拼点。若你赢,你获得以下效果直到回合结束:无视与该角色的距离;无视该角色的防具且对其使用【杀】没有次数限制。若你没赢,你不能使用【杀】直到回合结束。', - xinxianzhen:'陷阵', - xinxianzhen_info:'出牌阶段限一次,你可以与一名角色拼点。若你赢,你获得以下效果直到回合结束:无视该角色的防具且对其使用牌没有次数和距离限制,且当你使用【杀】或普通锦囊牌指定其他角色为唯一目标时可以令该角色也成为此牌的目标。若你没赢,你不能使用【杀】且你的【杀】不计入手牌上限直到回合结束。', - xinxianzhen2:'陷阵', - jinjiu:'禁酒', - jinjiu_info:'锁定技,你的【酒】均视为【杀】。', - chunlao:'醇醪', - chunlao2:'醇醪', - chunlao_info:'结束阶段开始时,若你没有“醇”,你可以将至少一张【杀】置于你的武将牌上,称为“醇”。当一名角色处于濒死状态时,你可以移去一张“醇”,视为该角色使用一张【酒】。', - lihuo:'疠火', - lihuo_info:'当你声明使用普通【杀】后,你可以将此【杀】改为火【杀】。若以此法使用的【杀】造成了伤害,则此【杀】结算后你失去1点体力;你使用火【杀】选择目标后,可以额外指定一个目标。', - shenduan:'慎断', - shenduan_info:'当你的黑色基本牌因弃置而进入弃牌堆后,你可以将其当做【兵粮寸断】使用(无距离限制)。', - yonglve:'勇略', - yonglve_info:'一名其他角色的判定阶段开始时,若其在你攻击范围内,则你可以弃置其判定区里的一张牌,视为对该角色使用一张【杀】。若此【杀】未造成伤害,你摸一张牌。', - reshenduan:'慎断', - reshenduan_info:'当你的黑色基本牌或装备牌因弃置而进入弃牌堆后,你可以将其当做【兵粮寸断】使用(无距离限制)。', - reyonglve:'勇略', - reyonglve_info:'其他角色的判定阶段开始时,你可以弃置其判定区里的一张牌。然后若该角色在你攻击范围内,你摸一张牌。若其在你攻击范围外,视为你对其使用一张【杀】。', - benxi:'奔袭', - benxi_info:'锁定技,你的回合内,你每使用一次牌后,你的进攻距离+1直到回合结束;你的回合内,若你与所有角色的距离均为1,你无视其他角色的防具,且你使用的【杀】可额外指定一个目标。', - xinbenxi:'奔袭', - xinbenxi_info:'锁定技,当你于回合内使用牌时,你本回合计算与其他角色的距离-1。你的回合内,若你至场上所有其他角色的距离均不大于1,则当你使用【杀】或普通锦囊牌选择唯一目标后,你选择至多两项:1.为此牌多指定一个目标;2.令此牌无视防具;3.令此牌不可被抵消;4.此牌造成伤害时摸一张牌。', - sidi:'司敌', - sidi2:'司敌', - sidi3:'司敌', - sidi_info:'①当你使用或其他角色在你的回合内使用【闪】时,你可以将牌堆顶的牌置于你的武将牌上,称为“司敌”牌。②其他角色的出牌阶段开始时,你可以移去一张“司敌”牌,令其本阶段使用【杀】的次数上限-1。', - xinsidi:'司敌', - xinsidi2:'司敌', - xinsidi_info:'其他角色出牌阶段开始时,你可以弃置一张与你装备区里的牌颜色相同的非基本牌,然后该角色于此阶段内不能使用和打出与此牌颜色相同的牌。此阶段结束时,若其此阶段没有使用【杀】,视为你对其使用了【杀】。', - dangxian:'当先', - dangxian_info:'锁定技,回合开始时,你执行一个额外的出牌阶段。', - xindangxian:'当先', - xindangxian_info:'锁定技,回合开始时,你执行一个额外的出牌阶段。此阶段开始时,你失去1点体力并从牌堆/弃牌堆中获得一张【杀】(若你已发动过〖伏枥〗,则可以不发动此效果)。', - longyin:'龙吟', - longyin_info:'当一名角色于其出牌阶段内使用【杀】时,你可弃置一张牌令此【杀】不计入出牌阶段使用次数,若此【杀】为红色,你摸一张牌。', - zhongyong:'忠勇', - zhongyong_info:'当你于出牌阶段内使用的【杀】被目标角色使用的【闪】抵消时,你可以将此【闪】交给除该角色外的一名角色。若获得此【闪】的角色不是你,你可以对相同的目标再使用一张【杀】。', - xinzhongyong:'忠勇', - xinzhongyong_info:'当你使用的【杀】结算完毕后,你可以将此【杀】或目标角色使用的【闪】交给一名该角色以外的其他角色,以此法得到红色牌的角色可以对你攻击范围内的角色使用一张【杀】。', - jigong:'急攻', - jigong_info:'出牌阶段开始时,你可以摸两张牌。若如此做,你本回合的手牌上限改为X(X为你此阶段造成的伤害点数之和)。', - shifei:'饰非', - shifei_info:'当你需要使用或打出【闪】时,你可以令当前回合角色摸一张牌。然后若其手牌数不为全场唯一最多,则你弃置全场手牌数最多(或之一)角色的一张牌,视为你使用或打出了一张【闪】。', - huaiyi:'怀异', - huaiyi_info:'出牌阶段限一次,你可以展示所有手牌,若这些牌的颜色不全部相同,则你选择一种颜色并弃置该颜色的所有手牌,然后你可以获得至多X名角色的各一张牌(X为你以此法弃置的手牌数)。若你以此法得到的牌不少于两张,则你失去1点体力。', - yaoming:'邀名', - yaoming_info:'每回合限一次,当你造成或受到伤害后,你可以选择一项:1. 弃置手牌数大于你的一名角色的一张手牌;2. 令手牌数小于你的一名角色摸一张牌。', - xinyaoming:'邀名', - xinyaoming_info:'每回合每个选项限一次,当你造成或受到伤害后,你可以选择一项:1. 弃置一名其他角色的一张手牌;2. 令一名其他角色摸一张牌;3.令一名角色弃置至多两张牌,然后摸等量的牌。', - anguo:'安国', - anguo_info:'出牌阶段限一次,你可以选择一名其他角色装备区里的一张牌,令其获得此牌。然后若该角色攻击范围内的角色数因此减少,则你摸一张牌。', - yanzhu:'宴诛', - yanzhu_info:'出牌阶段限一次,你可以令一名有牌的其他角色选择一项:令你获得其装备区里所有的牌,然后你失去技能〖宴诛〗;或弃置一张牌。', - xingxue:'兴学', - xingxue_info:'结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶(X为你的体力值,若你已失去技能〖宴诛〗,则将X改为你的体力上限)。', - zhaofu:'诏缚', - zhaofu_info:'主公技,锁定技,你距离为1的角色视为在其他吴势力角色的攻击范围内。', - reyanzhu:'宴诛', - reyanzhu2:'宴诛', - reyanzhu_info:'出牌阶段限一次,你可以令一名其他角色选择一项:将装备区里的所有牌交给你并令你修改〖宴诛〗和〖兴学〗,或弃置一张牌并令下一次受到的伤害+1直到其下回合开始。', - reyanzhu_rewrite:'宴诛·改', - reyanzhu_rewrite_info:'出牌阶段限一次,你可以选择一名其他角色。该角色下一次受到的伤害+1直到其下回合开始。', - rexingxue:'兴学', - rexingxue_info:'结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力值)。', - rexingxue_rewrite:'兴学·改', - rexingxue_rewrite_info:'结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力上限)。', - rezhaofu:'诏缚', - rezhaofu_info:'主公技,锁定技,你攻击范围内的角色视为在其他吴势力角色的攻击范围内。', - wurong:'怃戎', - wurong_info:'出牌阶段限一次,你可以令一名其他角色与你同时展示一张手牌:若你展示的是【杀】且该角色展示的不是【闪】,则你弃置此【杀】并对其造成1点伤害;若你展示的不是【杀】且该角色展示的是【闪】,则你弃置你展示的牌并获得其一张牌。', - shizhi:'矢志', - shizhi_info:'锁定技,当你的体力值为1时,你的【闪】均视为【杀】。', - zhanjue:'战绝', - zhanjue_info:'出牌阶段,你可以将所有手牌当作【决斗】使用。此【决斗】结算后,你与以此法受到伤害的角色各摸一张牌。若你在同一阶段内以此法摸了两张或更多的牌,则此技能失效直到回合结束。', - qinwang:'勤王', - qinwang1:'勤王', - qinwang2:'勤王', - qinwang_info:'主公技,当你需要使用或打出一张【杀】时,你可以弃置一张牌,然后视为你发动了〖激将①〗。若有角色响应,则该角色打出【杀】时摸一张牌。', - huomo:'活墨', - huomo_info:'当你需要使用一张本回合内未使用过的基本牌时,你可以将一张黑色非基本牌置于牌堆顶,视为使用此基本牌。', - zuoding:'佐定', - zuoding_info:'当其他角色于其回合内使用♠牌指定目标后,若本回合内没有角色受到过伤害,则你可以令其中一名目标角色摸一张牌。', - taoxi:'讨袭', - taoxi2:'讨袭', - taoxi3:'讨袭', - taoxi_info:'出牌阶段限一次。当你使用牌指定一名其他角色为唯一目标后,你可以亮出其一张手牌直到回合结束,并且你于此回合内可以将此牌如手牌般使用。回合结束时,若此牌仍在该角色手牌区里,你失去1点体力。', - huituo:'恢拓', - huituo_info:'当你受到伤害后,你可以令一名角色进行一次判定,若结果为红色,该角色回复1点体力;若结果为黑色,该角色摸X张牌(X为此次伤害的伤害点数)。', - mingjian:'明鉴', - mingjian2:'明鉴', - mingjian_info:'出牌阶段限一次。你可以将所有手牌交给一名其他角色,然后该角色于其下个回合的手牌上限+1,且使用【杀】的次数上限+1。', - xingshuai:'兴衰', - xingshuai_info:'主公技,限定技,当你进入濒死状态时,其他魏势力角色可依次令你回复1点体力,然后这些角色依次受到1点伤害。', - reduodao:'夺刀', - reduodao_info:'当你成为【杀】的目标后,你可以弃置一张牌。然后你获得此【杀】使用者装备区里的武器牌。', - reanjian:'暗箭', - reanjian_info:'锁定技,当你使用【杀】指定目标后,若你不在其攻击范围内,则此杀伤害+1且无视其防具。若其因执行此【杀】的效果受到伤害而进入濒死状态,则其不能使用【桃】直到此濒死事件结算结束。', - duodao:'夺刀', - duodao_info:'当你受到【杀】造成的伤害后,你可以弃置一张牌,然后获得伤害来源装备区里的武器牌。', - anjian:'暗箭', - anjian_info:'锁定技,当你使用【杀】对目标角色造成伤害时,若你不在其攻击范围内,则此杀伤害+1。', - xinpojun:'破军', - xinpojun2:'破军', - xinpojun_info:'当你于出牌阶段内使用【杀】指定一个目标后,你可以将其至多X张牌扣置于该角色的武将牌旁(X为其体力值)。若如此做,当前回合结束后,该角色获得其武将牌旁的所有牌。', + new_qingxian: "清弦", + new_qingxian_info: + "出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)", + new_juexiang: "绝响", + new_juexiang_info: + "锁定技,当你死亡后,杀死你的角色弃置装备区内的所有牌并失去1点体力。然后,你可以令一名其他角色获得技能〖残韵〗。若该角色区域内有梅花牌,则其可以弃置其中的一张,然后其获得技能〖绝响〗。", + new_canyun: "残韵", + new_canyun_info: + "出牌阶段限一次,你可以弃置至多X张牌并选择等量的其他角色(不能选择已经成为过〖残韵〗目标的角色)。这些角色中,装备区内牌数少于你的回复1点体力,等于你的摸一张牌,多于你的失去1点体力。若你以此法指定的角色数等于X,则你摸一张牌。(X为你的体力值)", + qingxian_draw: "清弦", + qingxian_draw_info: "", + zhenjun: "镇军", + zhenjun_info: + "准备阶段,你可以弃置一名手牌数多于体力值的角色的X张牌(X为其手牌数和体力值之差),然后选择一项:1.你弃置等同于其中非装备牌数量的牌;2.其摸等量的牌。", + rezhenjun: "镇军", + rezhenjun_info: + "准备阶段,你可以弃置一名角色的X张牌(X为其手牌数和体力值之差且至少为1),然后选择一项:1.你弃置X张牌;2.其摸X张牌。(X为其弃置的牌中非装备牌的数量)", + fenli: "奋励", + fenli_info: + "若你的手牌数为全场最多,你可以跳过摸牌阶段;若你的体力值为全场最多,你可以跳过出牌阶段;若你的装备区里有牌且数量为全场最多,你可以跳过弃牌阶段。", + pingkou: "平寇", + pingkou_info: "回合结束时,你可以对至多X名其他角色各造成1点伤害(X为你本回合跳过的阶段数)。", + xinanguo: "安国", + xinanguo_info: + "出牌阶段限一次,你可以选择一名其他角色,若其手牌数为全场最少,其摸一张牌;体力值为全场最低,回复1点体力;装备区内牌数为全场最少,随机使用一张装备牌。然后若该角色有未执行的效果且你满足条件,你执行之。", + pindi: "品第", + pindi_info: + "出牌阶段,你可以弃置一张牌并选择一名其他角色(不能弃置相同类型牌且不能指定相同的角色),然后令其执行一项:摸X张牌;弃置X张牌(X为本回合此技能发动次数)。若其已受伤,你横置。", + funan_jiexun: "诫训", + bizhuan: "辟撰", + bizhuan_bg: "书", + bizhuan_info: + "当你使用黑桃牌后,或你成为其他角色使用黑桃牌的目标后,你可以将牌堆顶的一张牌置于武将牌上,称为“书”;你至多拥有四张“书”,你每有一张“书” ,手牌上限+1。", + tongbo: "通博", + tongbo_info: + "摸牌阶段摸牌后,你可以用任意张牌替换等量的“书”,然后若你的“书”包含四种花色,你将所有“书”交给任意名其他角色。", + qingxian: "清弦", + qingxian_info: + "当你受到伤害/回复体力后,你可以令伤害来源/一名其他角色执行一项:失去1点体力,随机使用一张装备牌;回复1点体力,弃置一张装备牌。若其以此法使用或弃置的牌为梅花,你摸一张牌。", + juexiang: "绝响", + juexiang_info: + "当你死亡后,你可以令一名角色随机获得“清弦残谱”其中一个技能,然后直到其下回合开始,其不能被选择为其他角色使用梅花牌的目标。", + juexiang_ji: "激弦", + juexiang_ji_info: "当你受到伤害后,你可以令伤害来源失去1点体力,随机使用一张装备。", + juexiang_lie: "烈弦", + juexiang_lie_info: "当你回复体力后,你可以令一名其他角色失去1点体力,随机使用一张装备。", + juexiang_rou: "柔弦", + juexiang_rou_info: "当你受到伤害后,你可以令伤害来源回复1点体力,弃置一张装备。", + juexiang_he: "和弦", + juexiang_he_info: "当你回复体力后,你可以令一名其他角色回复1点体力,弃置一张装备。", + juexiang_club: "绝响", + juexiang_club_bg: "响", + juexiang_club_info: "直到下回合开始,不能被选择为其他角色使用梅花牌的目标。", + jianzheng: "谏征", + jianzheng_info: + "当一名其他角色使用【杀】指定目标时,若你在其攻击范围内且你不是目标,则你可以将一张手牌置于牌堆顶,取消所有目标,然后若此【杀】不为黑色,你成为目标。", + zhuandui: "专对", + zhuandui_info: + "当你使用【杀】指定目标/成为【杀】的目标后,你可以与目标角色/此【杀】使用者拼点,若你赢,此杀不能被【闪】响应/对你无效。", + zhuandui_use_info: + "当你使用【杀】指定目标后,你可以与目标角色拼点,若你赢,此杀不能被【闪】响应。", + zhuandui_respond_info: + "当你成为【杀】的目标后,你可以与此【杀】使用者拼点,若你赢,此杀对你无效。", + tianbian: "天辩", + tianbian_info: + "你拼点时,可以改为用牌堆顶的一张牌进行拼点;当你拼点的牌亮出后,若此牌花色为红桃,则此牌的点数视为K。", + funan: "复难", + funan_info: + "其他角色使用或打出牌响应你使用的牌时,你可令其获得你使用的牌(其本回合不能使用或打出这些牌),然后你获得其使用或打出的牌。", + jiexun: "诫训", + jiexun_info: + "结束阶段,你可令一名其他角色摸等同于场上方块牌数的牌,然后弃置X张牌(X为此前该技能发动过的次数)。若有角色因此法弃置了所有牌,则你失去〖诫训〗,然后你发动〖复难〗时,无须令对方获得你使用的牌。", + xinjiexun: "诫训", + xinjiexun_info: + "结束阶段,你可令一名其他角色摸等同于场上方块牌数的牌,然后弃置X张牌(X为此前该技能发动过的次数)。若有角色因此法弃置了所有牌,则你将X归零,然后你发动〖复难〗时,无须令对方获得你使用的牌。", + shouxi: "守玺", + shouxi_info: + "当你成为【杀】的目标后,你可声明一种未以此法声明过的基本牌或锦囊牌的牌名。若使用者弃置一张你声明的牌,其获得你的一张牌;若否,则此【杀】对你无效。", + huimin: "惠民", + huimin_info: + "结束阶段,你可以摸X张牌并展示等量手牌(X为手牌数小于其体力值的角色数),然后从你指定的一名角色开始这些角色依次选择并获得其中一张。", + wengua: "问卦", + wengua2: "问卦", + wengua_info: + "其他角色/你的出牌阶段限一次,其可以交给你一张牌,(若当前回合角色为你,则跳过此步骤),你可以将此牌/一张牌置于牌堆顶或牌堆底,然后你与其/你从另一端摸一张牌。", + fuzhu: "伏诛", + fuzhu_info: + "一名男性角色的结束阶段,若牌堆剩余牌数不大于你体力值的十倍,则你可以依次对其使用牌堆中所有的【杀】(不能超过游戏人数),然后洗牌。", + fumian: "福绵", + fumian_info: + "准备阶段,你可以选择一项:1.摸牌阶段多摸一张牌;2.使用红色牌可以多选择一个目标(限一次)。若与你上回合选择的选项不同,则该选项数值+1并复原此技能。", + daiyan: "怠宴", + daiyan_info: + "结束阶段,你可以令一名其他角色从牌堆中获得一张红桃基本牌,然后若其于上回合成为过该技能目标,则其失去1点体力。", + xinzhongjian: "忠鉴", + xinzhongjian_info: + "出牌阶段限一次,你可以展示自己的一张手牌,然后展示一名其他角色的至多三张手牌。其展示的牌中:每有一张花色相同,你摸一张牌;点数相同,你对其造成1点伤害;均不同,你弃置一张手牌。", + zhongjian: "忠鉴", + zhongjian_bg: "鉴", + zhongjian3: "忠鉴", + zhongjian3_bg: "鉴", + zhongjian_info: + "出牌阶段限一次,你可以展示一张手牌,然后展示一名其他角色的X张手牌(X为其体力值)。若以此法展示的牌与你展示的牌:有颜色相同的,你选择:①摸一张牌。②弃置一名其他角色的一张牌;有点数相同的,本回合此技能改为“出牌阶段限两次”;均不同,你的手牌上限-1。", + caishi: "才识", + caishix: "才识/忠鉴", + caishi_info: + "摸牌阶段开始时,你可以选择一项:1.令手牌上限+1;2.回复1点体力,本回合内不能对自己使用牌。", + xincaishi: "才识", + xincaishi_info: + "摸牌阶段,你可以选择一项:1.少摸一张牌,然后本回合发动〖忠鉴〗时可以多展示自己的一张牌;2.本回合手牌上限-1,然后本回合发动〖忠鉴〗时可以多展示对方的一张牌;3.多摸两张牌,本回合不能发动〖忠鉴〗。", + guizao: "瑰藻", + guizao_info: + "弃牌阶段结束时,若你于此阶段弃置牌的数量不小于2且它们的花色各不相同,你可以回复1点体力或摸一张牌。", + jiyu: "讥谀", + jiyu_info: + "出牌阶段限一次,你可以令一名角色弃置一张手牌。若如此做,你不能使用与之相同花色的牌,直到回合结束。若其以此法弃置的牌为黑桃,你翻面并令其失去1点体力。若你有未被〖讥谀〗限制的手牌,则你可以继续发动此技能,但不能选择本回合已经选择过的目标。", + qinqing: "寝情", + qinqing_info: + "结束阶段,你可以选择任意名攻击范围内含有主公的角色,然后弃置这些角色各一张牌并令其摸一张牌(无牌则不弃),若如此做,你摸X张牌(X为其中手牌比主公多的角色数)。", + qinqing_info_doudizhu: + "结束阶段,你可以选择任意名攻击范围内含有地主的角色,然后弃置这些角色各一张牌并令其摸一张牌(无牌则不弃),若如此做,你摸X张牌(X为其中手牌比地主多的角色数)。", + huisheng: "贿生", + huisheng_info: + "当你受到其他角色对你造成的伤害时,你可以令其观看你任意数量的牌并令其选择一项:1.获得这些牌中的一张,防止此伤害,然后你不能再对其发动〖贿生〗;2.弃置等量的牌。", + jishe: "极奢", + jishe2: "极奢", + jishe_info: + "①出牌阶段限20次,若你的手牌上限大于0,你可以摸一张牌,然后你本回合的手牌上限-1。②结束阶段开始时,若你没有手牌,则你可以横置至多X名角色的武将牌(X为你的体力值)。", + lianhuo: "链祸", + lianhuo_info: + "锁定技,当你受到火焰伤害时,若你的武将牌处于横置状态且此伤害不为连环伤害,则此伤害+1。", + taoluan: "滔乱", + taoluan_backup: "滔乱", + taoluan_info: + "你可以将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本局游戏你以此法使用过的牌),然后你令一名其他角色选择一项:1.交给你一张与你以此法使用的牌类别不同的牌;2.你失去1点体力且〖滔乱〗无效直到回合结束。", + xintaoluan: "滔乱", + xintaoluan_backup: "滔乱", + xintaoluan_info: + "若场上没有濒死的角色,则你可以将一张牌当做任意一张基本牌或普通锦囊牌使用(此牌不得是本回合内你以此法使用过的牌),然后你令一名其他角色选择一项:1.交给你X张与你以此法使用的牌类别不同的牌;2.你失去X点体力且滔乱无效直到回合结束(X为你本回合内发动过〖滔乱〗的次数且至多为3)。", + jiaozhao: "矫诏", + jiaozhao3: "矫诏", + jiaozhao3_backup: "矫诏", + jiaozhao2: "矫诏", + jiaozhao_info: + "出牌阶段限一次,你可以展示一张手牌,然后选择距离最近的一名其他角色,该角色声明一张基本牌的牌名。在此出牌阶段内,你可以将此手牌当声明的牌使用(你不能对自己使用此牌)。", + danxin: "殚心", + danxin_info: + "当你受到伤害后,你可以摸一张牌,或对“矫诏”的描述依次执行下列一项修改:1.将“基本牌”改为“基本牌或普通锦囊牌”;2.将“选择距离最近的一名其他角色,该角色”改为“你”。", + xindanxin: "殚心", + xindanxin_info: + "当你受到伤害后,你可以摸一张牌,并对“矫诏”的描述依次执行下列一项修改:1.将“基本牌”改为“基本牌或普通锦囊牌”;2.将“选择距离最近的一名其他角色,该角色”改为“你”。3.将“出牌阶段限一次”改为“出牌阶段限两次”。", + duliang: "督粮", + duliang2: "督粮", + duliang_info: + "出牌阶段限一次,你可以获得一名其他角色的一张手牌,然后选择一项:1.令其观看牌堆顶的两张牌,然后获得其中的基本牌;2.令其于下个摸牌阶段额外摸一张牌。", + fulin: "腹鳞", + fulin_info: "锁定技,你于回合内得到的牌不计入你本回合的手牌上限。", + kuangbi: "匡弼", + kuangbi_info: + "出牌阶段限一次,你可以选择一名有牌的其他角色,该角色将其的一至三张牌置于你的武将牌上。若如此做,你的下个准备阶段,你获得武将牌上的所有牌,然后其摸等量的牌。", + xinzhige: "止戈", + xinzhige_info: + "出牌阶段限一次,你可以令一名攻击范围内含有你的其他角色交给你一张【杀】或武器牌,否则其视为对你指定的另一名其攻击范围内的角色使用了一张【杀】。", + zhige: "止戈", + zhige_info: + "出牌阶段限一次,若你的手牌数大于你的体力值,你可以选择攻击范围内含有你的一名其他角色,其选择一项:1.使用一张【杀】;2.将装备区里的一张牌交给你。", + xinzongzuo: "宗祚", + xinzongzuo_info: + "锁定技,游戏的第一个回合开始前,你加X点体力上限并回复X点体力(X为全场势力数);当一名角色死亡后,若没有与其势力相同的角色,你减1点体力上限并摸两张牌。", + zongzuo: "宗祚", + zongzuo_info: + "锁定技,游戏的第一个回合开始前,你加X点体力上限并回复X点体力(X为全场势力数);当一名角色死亡后,若没有与其势力相同的角色,你减1点体力上限。", + xinjuece: "绝策", + xinjuece_info: "结束阶段,你可以对一名没有手牌的角色造成1点伤害。", + xinmieji: "灭计", + xinmieji_info: + "出牌阶段限一次,你可以展示一张黑色锦囊牌并将之置于牌堆顶,然后令有手牌的一名其他角色选择一项:弃置一张锦囊牌;或依次弃置两张非锦囊牌。", + xinfencheng: "焚城", + xinfencheng_info: + "限定技。出牌阶段,你可以令所有其他角色各选择一项:弃置至少X张牌(X为该角色的上家以此法弃置牌的数量+1);或受到你对其造成的2点火焰伤害。", + qianju: "千驹", + qianju_info: "锁定技,若你已受伤,你计算与其他角色的距离时-X(X为你已损失的体力值)。", + qingxi: "倾袭", + qingxi_info: + "当你使用【杀】对目标角色造成伤害时,若你的装备区里有武器牌,你可以令其选择一项:1、弃置X张手牌(X为此武器牌的攻击范围),若如此做,其弃置你的此武器牌;2、令伤害值+1。", + reqianju: "千驹", + reqianju_info: "锁定技,若你已受伤,你计算与其他角色的距离时-X(X为你已损失的体力值且至少为1)。", + reqingxi: "倾袭", + reqingxi_info: + "当你使用【杀】或【决斗】指定目标后,你可以令其选择一项:1、弃置X张手牌(X为你攻击范围内的角色数,且当你装备区内有武器牌/没有武器牌时至多为4/2),若如此做,其弃置你的此武器牌;2、令此牌的伤害值+1且你进行判定,若结果为红色,则其不能响应此牌。", + jieyue: "节钺", + jieyue_info: + "①结束阶段,你可以弃置一张手牌,然后令一名其他角色选择一项:1.将一张牌置于你的武将牌上,称之为“节”;2.令你弃置其一张牌。②若你有“节”,你可以将红色/黑色手牌当作【闪】/【无懈可击】使用或打出。③准备阶段,若你有“节”,则你获得之。", + xianzhen: "陷阵", + xianzhen_info: + "出牌阶段限一次,你可以与一名角色拼点。若你赢,你获得以下效果直到回合结束:无视与该角色的距离;无视该角色的防具且对其使用【杀】没有次数限制。若你没赢,你不能使用【杀】直到回合结束。", + xinxianzhen: "陷阵", + xinxianzhen_info: + "出牌阶段限一次,你可以与一名角色拼点。若你赢,你获得以下效果直到回合结束:无视该角色的防具且对其使用牌没有次数和距离限制,且当你使用【杀】或普通锦囊牌指定其他角色为唯一目标时可以令该角色也成为此牌的目标。若你没赢,你不能使用【杀】且你的【杀】不计入手牌上限直到回合结束。", + xinxianzhen2: "陷阵", + jinjiu: "禁酒", + jinjiu_info: "锁定技,你的【酒】均视为【杀】。", + chunlao: "醇醪", + chunlao2: "醇醪", + chunlao_info: + "结束阶段开始时,若你没有“醇”,你可以将至少一张【杀】置于你的武将牌上,称为“醇”。当一名角色处于濒死状态时,你可以移去一张“醇”,视为该角色使用一张【酒】。", + lihuo: "疠火", + lihuo_info: + "当你声明使用普通【杀】后,你可以将此【杀】改为火【杀】。若以此法使用的【杀】造成了伤害,则此【杀】结算后你失去1点体力;你使用火【杀】选择目标后,可以额外指定一个目标。", + shenduan: "慎断", + shenduan_info: + "当你的黑色基本牌因弃置而进入弃牌堆后,你可以将其当做【兵粮寸断】使用(无距离限制)。", + yonglve: "勇略", + yonglve_info: + "一名其他角色的判定阶段开始时,若其在你攻击范围内,则你可以弃置其判定区里的一张牌,视为对该角色使用一张【杀】。若此【杀】未造成伤害,你摸一张牌。", + reshenduan: "慎断", + reshenduan_info: + "当你的黑色基本牌或装备牌因弃置而进入弃牌堆后,你可以将其当做【兵粮寸断】使用(无距离限制)。", + reyonglve: "勇略", + reyonglve_info: + "其他角色的判定阶段开始时,你可以弃置其判定区里的一张牌。然后若该角色在你攻击范围内,你摸一张牌。若其在你攻击范围外,视为你对其使用一张【杀】。", + benxi: "奔袭", + benxi_info: + "锁定技,你的回合内,你每使用一次牌后,你的进攻距离+1直到回合结束;你的回合内,若你与所有角色的距离均为1,你无视其他角色的防具,且你使用的【杀】可额外指定一个目标。", + xinbenxi: "奔袭", + xinbenxi_info: + "锁定技,当你于回合内使用牌时,你本回合计算与其他角色的距离-1。你的回合内,若你至场上所有其他角色的距离均不大于1,则当你使用【杀】或普通锦囊牌选择唯一目标后,你选择至多两项:1.为此牌多指定一个目标;2.令此牌无视防具;3.令此牌不可被抵消;4.此牌造成伤害时摸一张牌。", + sidi: "司敌", + sidi2: "司敌", + sidi3: "司敌", + sidi_info: + "①当你使用或其他角色在你的回合内使用【闪】时,你可以将牌堆顶的牌置于你的武将牌上,称为“司敌”牌。②其他角色的出牌阶段开始时,你可以移去一张“司敌”牌,令其本阶段使用【杀】的次数上限-1。", + xinsidi: "司敌", + xinsidi2: "司敌", + xinsidi_info: + "其他角色出牌阶段开始时,你可以弃置一张与你装备区里的牌颜色相同的非基本牌,然后该角色于此阶段内不能使用和打出与此牌颜色相同的牌。此阶段结束时,若其此阶段没有使用【杀】,视为你对其使用了【杀】。", + dangxian: "当先", + dangxian_info: "锁定技,回合开始时,你执行一个额外的出牌阶段。", + xindangxian: "当先", + xindangxian_info: + "锁定技,回合开始时,你执行一个额外的出牌阶段。此阶段开始时,你失去1点体力并从牌堆/弃牌堆中获得一张【杀】(若你已发动过〖伏枥〗,则可以不发动此效果)。", + longyin: "龙吟", + longyin_info: + "当一名角色于其出牌阶段内使用【杀】时,你可弃置一张牌令此【杀】不计入出牌阶段使用次数,若此【杀】为红色,你摸一张牌。", + zhongyong: "忠勇", + zhongyong_info: + "当你于出牌阶段内使用的【杀】被目标角色使用的【闪】抵消时,你可以将此【闪】交给除该角色外的一名角色。若获得此【闪】的角色不是你,你可以对相同的目标再使用一张【杀】。", + xinzhongyong: "忠勇", + xinzhongyong_info: + "当你使用的【杀】结算完毕后,你可以将此【杀】或目标角色使用的【闪】交给一名该角色以外的其他角色,以此法得到红色牌的角色可以对你攻击范围内的角色使用一张【杀】。", + jigong: "急攻", + jigong_info: + "出牌阶段开始时,你可以摸两张牌。若如此做,你本回合的手牌上限改为X(X为你此阶段造成的伤害点数之和)。", + shifei: "饰非", + shifei_info: + "当你需要使用或打出【闪】时,你可以令当前回合角色摸一张牌。然后若其手牌数不为全场唯一最多,则你弃置全场手牌数最多(或之一)角色的一张牌,视为你使用或打出了一张【闪】。", + huaiyi: "怀异", + huaiyi_info: + "出牌阶段限一次,你可以展示所有手牌,若这些牌的颜色不全部相同,则你选择一种颜色并弃置该颜色的所有手牌,然后你可以获得至多X名角色的各一张牌(X为你以此法弃置的手牌数)。若你以此法得到的牌不少于两张,则你失去1点体力。", + yaoming: "邀名", + yaoming_info: + "每回合限一次,当你造成或受到伤害后,你可以选择一项:1. 弃置手牌数大于你的一名角色的一张手牌;2. 令手牌数小于你的一名角色摸一张牌。", + xinyaoming: "邀名", + xinyaoming_info: + "每回合每个选项限一次,当你造成或受到伤害后,你可以选择一项:1. 弃置一名其他角色的一张手牌;2. 令一名其他角色摸一张牌;3.令一名角色弃置至多两张牌,然后摸等量的牌。", + anguo: "安国", + anguo_info: + "出牌阶段限一次,你可以选择一名其他角色装备区里的一张牌,令其获得此牌。然后若该角色攻击范围内的角色数因此减少,则你摸一张牌。", + yanzhu: "宴诛", + yanzhu_info: + "出牌阶段限一次,你可以令一名有牌的其他角色选择一项:令你获得其装备区里所有的牌,然后你失去技能〖宴诛〗;或弃置一张牌。", + xingxue: "兴学", + xingxue_info: + "结束阶段开始时,你可以令至多X名角色依次摸一张牌并将一张牌置于牌堆顶(X为你的体力值,若你已失去技能〖宴诛〗,则将X改为你的体力上限)。", + zhaofu: "诏缚", + zhaofu_info: "主公技,锁定技,你距离为1的角色视为在其他吴势力角色的攻击范围内。", + reyanzhu: "宴诛", + reyanzhu2: "宴诛", + reyanzhu_info: + "出牌阶段限一次,你可以令一名其他角色选择一项:将装备区里的所有牌交给你并令你修改〖宴诛〗和〖兴学〗,或弃置一张牌并令下一次受到的伤害+1直到其下回合开始。", + reyanzhu_rewrite: "宴诛·改", + reyanzhu_rewrite_info: + "出牌阶段限一次,你可以选择一名其他角色。该角色下一次受到的伤害+1直到其下回合开始。", + rexingxue: "兴学", + rexingxue_info: + "结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力值)。", + rexingxue_rewrite: "兴学·改", + rexingxue_rewrite_info: + "结束阶段开始时,你可以令至多X名角色各摸一张牌。然后若有手牌数大于体力值的目标角色,则这些角色各将一张牌置于牌堆顶。(X为你的体力上限)。", + rezhaofu: "诏缚", + rezhaofu_info: "主公技,锁定技,你攻击范围内的角色视为在其他吴势力角色的攻击范围内。", + wurong: "怃戎", + wurong_info: + "出牌阶段限一次,你可以令一名其他角色与你同时展示一张手牌:若你展示的是【杀】且该角色展示的不是【闪】,则你弃置此【杀】并对其造成1点伤害;若你展示的不是【杀】且该角色展示的是【闪】,则你弃置你展示的牌并获得其一张牌。", + shizhi: "矢志", + shizhi_info: "锁定技,当你的体力值为1时,你的【闪】均视为【杀】。", + zhanjue: "战绝", + zhanjue_info: + "出牌阶段,你可以将所有手牌当作【决斗】使用。此【决斗】结算后,你与以此法受到伤害的角色各摸一张牌。若你在同一阶段内以此法摸了两张或更多的牌,则此技能失效直到回合结束。", + qinwang: "勤王", + qinwang1: "勤王", + qinwang2: "勤王", + qinwang_info: + "主公技,当你需要使用或打出一张【杀】时,你可以弃置一张牌,然后视为你发动了〖激将①〗。若有角色响应,则该角色打出【杀】时摸一张牌。", + huomo: "活墨", + huomo_info: + "当你需要使用一张本回合内未使用过的基本牌时,你可以将一张黑色非基本牌置于牌堆顶,视为使用此基本牌。", + zuoding: "佐定", + zuoding_info: + "当其他角色于其回合内使用♠牌指定目标后,若本回合内没有角色受到过伤害,则你可以令其中一名目标角色摸一张牌。", + taoxi: "讨袭", + taoxi2: "讨袭", + taoxi3: "讨袭", + taoxi_info: + "出牌阶段限一次。当你使用牌指定一名其他角色为唯一目标后,你可以亮出其一张手牌直到回合结束,并且你于此回合内可以将此牌如手牌般使用。回合结束时,若此牌仍在该角色手牌区里,你失去1点体力。", + huituo: "恢拓", + huituo_info: + "当你受到伤害后,你可以令一名角色进行一次判定,若结果为红色,该角色回复1点体力;若结果为黑色,该角色摸X张牌(X为此次伤害的伤害点数)。", + mingjian: "明鉴", + mingjian2: "明鉴", + mingjian_info: + "出牌阶段限一次。你可以将所有手牌交给一名其他角色,然后该角色于其下个回合的手牌上限+1,且使用【杀】的次数上限+1。", + xingshuai: "兴衰", + xingshuai_info: + "主公技,限定技,当你进入濒死状态时,其他魏势力角色可依次令你回复1点体力,然后这些角色依次受到1点伤害。", + reduodao: "夺刀", + reduodao_info: + "当你成为【杀】的目标后,你可以弃置一张牌。然后你获得此【杀】使用者装备区里的武器牌。", + reanjian: "暗箭", + reanjian_info: + "锁定技,当你使用【杀】指定目标后,若你不在其攻击范围内,则此杀伤害+1且无视其防具。若其因执行此【杀】的效果受到伤害而进入濒死状态,则其不能使用【桃】直到此濒死事件结算结束。", + duodao: "夺刀", + duodao_info: "当你受到【杀】造成的伤害后,你可以弃置一张牌,然后获得伤害来源装备区里的武器牌。", + anjian: "暗箭", + anjian_info: "锁定技,当你使用【杀】对目标角色造成伤害时,若你不在其攻击范围内,则此杀伤害+1。", + xinpojun: "破军", + xinpojun2: "破军", + xinpojun_info: + "当你于出牌阶段内使用【杀】指定一个目标后,你可以将其至多X张牌扣置于该角色的武将牌旁(X为其体力值)。若如此做,当前回合结束后,该角色获得其武将牌旁的所有牌。", - qiaoshi:'樵拾', - qiaoshi_info:'其他角色的结束阶段开始时,若你的手牌数与其相等,则你可以与其各摸一张牌。', - yanyu:'燕语', - yanyu2:'燕语', - yanyu_info:'出牌阶段,你可以重铸【杀】。出牌阶段结束时,若你于此阶段以此法重铸了至少两张【杀】,则你可以令一名男性角色摸两张牌。', + qiaoshi: "樵拾", + qiaoshi_info: "其他角色的结束阶段开始时,若你的手牌数与其相等,则你可以与其各摸一张牌。", + yanyu: "燕语", + yanyu2: "燕语", + yanyu_info: + "出牌阶段,你可以重铸【杀】。出牌阶段结束时,若你于此阶段以此法重铸了至少两张【杀】,则你可以令一名男性角色摸两张牌。", - zzhenggong:'争功', - zzhenggong_info:'当你受到伤害后,你可以获得伤害来源装备区里的一张牌并置入你的装备区。', - zquanji:'权计', - zquanji_info:'其他角色的回合开始时,你可以与该角色拼点。若你赢,该角色跳过准备阶段和判定阶段。', - zbaijiang:'拜将', - zbaijiang_info:'觉醒技。准备阶段,若你装备区里的牌数不少于两张,你加1点体力上限,失去〖权计〗和〖争功〗,获得〖野心〗和〖自立〗。', - zyexin:'野心', - zyexin2:'野心', - zyexin_info:'①当你造成或受到伤害后,你可以将牌堆顶的一张牌置于你的武将牌上,称为“权”。②出牌阶段限一次。你可以用任意数量的手牌与等量的“权”交换。', - zzili:'自立', - zzili_info:'觉醒技。准备阶段,若你的“权”数不小于4,你减1点体力上限并获得〖排异〗。', - zpaiyi:'排异', - zpaiyi_info:'结束阶段,你可以选择一张“权”,若此牌为:装备牌,你将此牌置入一名角色的装备区;延时类锦囊牌,你将此牌置入一名角色的判定区;基本牌或普通锦囊牌,你将此牌交给一名角色。然后若此牌的目标区域对应的角色不为你,你可以摸一张牌。', - shibei:'矢北', - shibei_info:'锁定技,当你受到伤害后:若此伤害是你本回合第一次受到的伤害,则你回复1点体力;否则你失去1点体力。', - jianying:'渐营', - jianying_info:'当你于出牌阶段内使用与此阶段你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。', - xinenyuan:'恩怨', - xinenyuan1:'恩怨', - xinenyuan2:'恩怨', - xinenyuan_info:'当你获得一名其他角色两张或更多的牌后,你可以令其摸一张牌;当你受到1点伤害后,你可以令伤害来源选择一项:1、将一张手牌交给你;2、失去1点体力。', - xinxuanhuo:'眩惑', - xinxuanhuo_info:'摸牌阶段开始时,你可以改为令一名其他角色摸两张牌,然后该角色需对其攻击范围内你选择的另一名角色使用一张【杀】,否则你获得其两张牌。', - fuhun:'父魂', - fuhun2:'父魂', - fuhun_info:'你可以将两张手牌当做【杀】使用或打出;当你于出牌阶段以此法使用的【杀】造成伤害后,你获得〖武圣〗和〖咆哮〗直到回合结束。', - yuce:'御策', - yuce_info:'当你受到伤害后,你可以展示一张手牌,并令伤害来源选择一项:弃置一张与此牌类型不同的手牌,或令你回复1点体力。', - xiansi:'陷嗣', - xiansix:'陷嗣', - xiansi_bg:'逆', - xiansi2:'陷嗣', - xiansi_info:'准备阶段开始时,你可以将一至两名角色的各一张牌置于你的武将牌上,称为“逆”;当一名角色需要对你使用【杀】时,其可以移去两张“逆”,然后视为对你使用了一张【杀】。', - chanhui:'谮毁', - chanhui_info:'出牌阶段限一次,当你使用【杀】或黑色普通锦囊牌指定唯一目标时,你可令可以成为此牌目标的另一名其他角色选择一项:交给你一张牌并成为此牌的使用者;或成为此牌的额外目标。', - rechanhui:'谮毁', - rechanhui_info:'当你使用【杀】或普通锦囊牌指定唯一目标时,你可令可以成为此牌目标(无距离限制)的另一名其他角色选择一项:交给你一张牌并成为此牌的使用者;或成为此牌的额外目标且你本回合内不能再次发动〖谮毁〗。', - jiaojin:'骄矜', - jiaojin_info:'当你受到男性角色造成的伤害时,你可以弃置一张装备牌,令此伤害-1。', - rejiaojin:'骄矜', - rejiaojin_info:'当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以弃置一张装备牌,令此牌对你无效并获得此牌对应的所有实体牌。若此牌的使用者为女性角色,则你令〖骄矜〗失效直到回合结束。', - shenxing:'慎行', - shenxing_info:'出牌阶段,你可以弃置两张牌,然后摸一张牌。', - bingyi:'秉壹', - bingyi_info:'结束阶段开始时,你可以展示所有手牌,若这些牌颜色均相同,则你令至多X名角色各摸一张牌(X为你的手牌数)。', - qiangzhi:'强识', - qiangzhi_draw:'强识', - qiangzhi_info:'出牌阶段开始时,你可以展示一名其他角色的一张手牌。若如此做,当你于此阶段内使用与此牌类别相同的牌时,你可以摸一张牌。', - xiantu:'献图', - xiantu2:'献图', - xiantu3:'献图', - xiantu_info:'一名其他角色的出牌阶段开始时,你可以摸两张牌,然后交给其两张牌。若如此做,此阶段结束时,若该角色未于此阶段内杀死过角色,则你失去1点体力。', - dingpin:'定品', - dingpin_info:'出牌阶段,你可以弃置一张手牌,然后令一名已受伤的角色判定,若结果为黑色,该角色摸X张牌(X为该角色已损失的体力值),然后你本回合不能再对其发动〖定品〗;若结果为红色,你翻面(你不能弃置本回合已弃置或使用过的类型的牌)。', - faen:'法恩', - faen_info:'当一名角色翻至正面或横置后,你可以令其摸一张牌。', - jyzongshi:'纵适', - jyzongshi_info:'当你拼点赢时,你可以获得对方此次拼点的牌;当你拼点没赢时,你可以收回你此次拼点的牌。', - qiaoshui:'巧说', - qiaoshui3:'巧说', - qiaoshui_info:'出牌阶段开始时,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,你不能使用锦囊牌直到回合结束。', - reqiaoshui:'巧说', - reqiaoshui_info:'出牌阶段,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,你结束出牌阶段且本回合内锦囊牌不计入手牌上限。', - junxing:'峻刑', - junxing_info:'出牌阶段限一次,你可以弃置至少一张手牌并选择一名其他角色,该角色需弃置一张与你弃置的牌类别均不同的手牌,否则其先将其武将牌翻面再摸X张牌(X为你以此法弃置的手牌数量)。', - xinjunxing:'峻刑', - xinjunxing_info:'出牌阶段限一次,你可以弃置至少一张手牌并选择一名其他角色,该角色需弃置一张与你弃置的牌类别均不同的手牌,否则其先将其武将牌翻面,然后将手牌摸至四张。', + zzhenggong: "争功", + zzhenggong_info: "当你受到伤害后,你可以获得伤害来源装备区里的一张牌并置入你的装备区。", + zquanji: "权计", + zquanji_info: "其他角色的回合开始时,你可以与该角色拼点。若你赢,该角色跳过准备阶段和判定阶段。", + zbaijiang: "拜将", + zbaijiang_info: + "觉醒技。准备阶段,若你装备区里的牌数不少于两张,你加1点体力上限,失去〖权计〗和〖争功〗,获得〖野心〗和〖自立〗。", + zyexin: "野心", + zyexin2: "野心", + zyexin_info: + "①当你造成或受到伤害后,你可以将牌堆顶的一张牌置于你的武将牌上,称为“权”。②出牌阶段限一次。你可以用任意数量的手牌与等量的“权”交换。", + zzili: "自立", + zzili_info: "觉醒技。准备阶段,若你的“权”数不小于4,你减1点体力上限并获得〖排异〗。", + zpaiyi: "排异", + zpaiyi_info: + "结束阶段,你可以选择一张“权”,若此牌为:装备牌,你将此牌置入一名角色的装备区;延时类锦囊牌,你将此牌置入一名角色的判定区;基本牌或普通锦囊牌,你将此牌交给一名角色。然后若此牌的目标区域对应的角色不为你,你可以摸一张牌。", + shibei: "矢北", + shibei_info: + "锁定技,当你受到伤害后:若此伤害是你本回合第一次受到的伤害,则你回复1点体力;否则你失去1点体力。", + jianying: "渐营", + jianying_info: + "当你于出牌阶段内使用与此阶段你使用的上一张牌点数或花色相同的牌时,你可以摸一张牌。", + xinenyuan: "恩怨", + xinenyuan1: "恩怨", + xinenyuan2: "恩怨", + xinenyuan_info: + "当你获得一名其他角色两张或更多的牌后,你可以令其摸一张牌;当你受到1点伤害后,你可以令伤害来源选择一项:1、将一张手牌交给你;2、失去1点体力。", + xinxuanhuo: "眩惑", + xinxuanhuo_info: + "摸牌阶段开始时,你可以改为令一名其他角色摸两张牌,然后该角色需对其攻击范围内你选择的另一名角色使用一张【杀】,否则你获得其两张牌。", + fuhun: "父魂", + fuhun2: "父魂", + fuhun_info: + "你可以将两张手牌当做【杀】使用或打出;当你于出牌阶段以此法使用的【杀】造成伤害后,你获得〖武圣〗和〖咆哮〗直到回合结束。", + yuce: "御策", + yuce_info: + "当你受到伤害后,你可以展示一张手牌,并令伤害来源选择一项:弃置一张与此牌类型不同的手牌,或令你回复1点体力。", + xiansi: "陷嗣", + xiansix: "陷嗣", + xiansi_bg: "逆", + xiansi2: "陷嗣", + xiansi_info: + "准备阶段开始时,你可以将一至两名角色的各一张牌置于你的武将牌上,称为“逆”;当一名角色需要对你使用【杀】时,其可以移去两张“逆”,然后视为对你使用了一张【杀】。", + chanhui: "谮毁", + chanhui_info: + "出牌阶段限一次,当你使用【杀】或黑色普通锦囊牌指定唯一目标时,你可令可以成为此牌目标的另一名其他角色选择一项:交给你一张牌并成为此牌的使用者;或成为此牌的额外目标。", + rechanhui: "谮毁", + rechanhui_info: + "当你使用【杀】或普通锦囊牌指定唯一目标时,你可令可以成为此牌目标(无距离限制)的另一名其他角色选择一项:交给你一张牌并成为此牌的使用者;或成为此牌的额外目标且你本回合内不能再次发动〖谮毁〗。", + jiaojin: "骄矜", + jiaojin_info: "当你受到男性角色造成的伤害时,你可以弃置一张装备牌,令此伤害-1。", + rejiaojin: "骄矜", + rejiaojin_info: + "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以弃置一张装备牌,令此牌对你无效并获得此牌对应的所有实体牌。若此牌的使用者为女性角色,则你令〖骄矜〗失效直到回合结束。", + shenxing: "慎行", + shenxing_info: "出牌阶段,你可以弃置两张牌,然后摸一张牌。", + bingyi: "秉壹", + bingyi_info: + "结束阶段开始时,你可以展示所有手牌,若这些牌颜色均相同,则你令至多X名角色各摸一张牌(X为你的手牌数)。", + qiangzhi: "强识", + qiangzhi_draw: "强识", + qiangzhi_info: + "出牌阶段开始时,你可以展示一名其他角色的一张手牌。若如此做,当你于此阶段内使用与此牌类别相同的牌时,你可以摸一张牌。", + xiantu: "献图", + xiantu2: "献图", + xiantu3: "献图", + xiantu_info: + "一名其他角色的出牌阶段开始时,你可以摸两张牌,然后交给其两张牌。若如此做,此阶段结束时,若该角色未于此阶段内杀死过角色,则你失去1点体力。", + dingpin: "定品", + dingpin_info: + "出牌阶段,你可以弃置一张手牌,然后令一名已受伤的角色判定,若结果为黑色,该角色摸X张牌(X为该角色已损失的体力值),然后你本回合不能再对其发动〖定品〗;若结果为红色,你翻面(你不能弃置本回合已弃置或使用过的类型的牌)。", + faen: "法恩", + faen_info: "当一名角色翻至正面或横置后,你可以令其摸一张牌。", + jyzongshi: "纵适", + jyzongshi_info: + "当你拼点赢时,你可以获得对方此次拼点的牌;当你拼点没赢时,你可以收回你此次拼点的牌。", + qiaoshui: "巧说", + qiaoshui3: "巧说", + qiaoshui_info: + "出牌阶段开始时,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,你不能使用锦囊牌直到回合结束。", + reqiaoshui: "巧说", + reqiaoshui_info: + "出牌阶段,你可与一名其他角色拼点。若你赢,你使用的下一张基本牌或普通锦囊牌可以额外指定任意一名其他角色为目标或减少指定一个目标;若你没赢,你结束出牌阶段且本回合内锦囊牌不计入手牌上限。", + junxing: "峻刑", + junxing_info: + "出牌阶段限一次,你可以弃置至少一张手牌并选择一名其他角色,该角色需弃置一张与你弃置的牌类别均不同的手牌,否则其先将其武将牌翻面再摸X张牌(X为你以此法弃置的手牌数量)。", + xinjunxing: "峻刑", + xinjunxing_info: + "出牌阶段限一次,你可以弃置至少一张手牌并选择一名其他角色,该角色需弃置一张与你弃置的牌类别均不同的手牌,否则其先将其武将牌翻面,然后将手牌摸至四张。", - xswuyan:'无言', - xinwuyan:'无言', - jujian:'举荐', - xinjujian:'举荐', - luoying:'落英', - luoying_discard:'落英', - luoying_judge:'落英', - luoying_judge_noconf:'落英·判定', - jiushi:'酒诗', - jiushi1:'酒诗', - jiushi2:'酒诗', - jiushi3:'酒诗', - jueqing:'绝情', - shangshi:'伤逝', - xuanfeng:'旋风', - zhiyu:'智愚', - qice:'奇策', - qice_backup:'奇策', - jiangchi:'将驰', - jiangchi_less:'少摸一张', - jiangchi_more:'多摸一张', - zishou:'自守', - zongshi:'宗室', - danshou:'胆守', - olddanshou:'胆守', - xindanshou:'胆守', - yizhong:'毅重', - xinzhan:'心战', - xinzhan_gain:'获得', - xinzhan_place:'牌堆顶', - huilei:'挥泪', - enyuan:'恩怨', - enyuan1:'恩怨', - enyuan2:'恩怨', - xuanhuo:'眩惑', - ganlu:'甘露', - buyi:'补益', - mingce:'明策', - zhichi:'智迟', - zhichi2:'智迟', - pojun:'破军', - jingce:'精策', - xinjingce:'精策', - chengxiang:'称象', - oldchengxiang:'称象', - renxin:'仁心', - oldrenxin:'仁心', - zhenlie:'贞烈', - miji:'秘计', - miji_tag:'已分配', - zhiyan:'直言', - zongxuan:'纵玄', - anxu:'安恤', - old_anxu:'安恤', - zhuiyi:'追忆', - gongji:'弓骑', - qiuyuan:'求援', - oldqiuyuan:'求援', - zhuikong:'惴恐', - oldzhuikong:'惴恐', - qieting:'窃听', - xianzhou:'献州', - quanji:'权计', - zili:'自立', - paiyi:'排异', - paiyi_backup:'排异', - sanyao:'散谣', - olsanyao:'散谣', - olsanyao_backup:'散谣', - zhiman:'制蛮', - resanyao:'散谣', - rezhiman:'制蛮', - qianxi:'潜袭', - qianxi2:'潜袭', - qianxi2_bg:'袭', - fuli:'伏枥', - xinfuli:'伏枥', - jiefan:'解烦', - juece:'绝策', - mieji:'灭计', - fencheng:'焚城', - youdi:'诱敌', - youdi_info:'结束阶段开始时,你可以令一名其他角色弃置你的一张牌,若此牌不为【杀】,你获得该角色的一张牌。', - fencheng_info:'限定技。出牌阶段,你可令所有其他角色依次选择一项:弃置X张牌;或受到1点火焰伤害。(X为该角色装备区里牌的数量且至少为1)', - mieji_info:'当你使用黑色普通锦囊牌选择目标后,若目标数为1,则你可以额外指定一个目标。', - juece_info:'当其他角色在你回合内失去最后的手牌后,你可以对其造成1点伤害。', - jiefan_info:'限定技,出牌阶段,你可以选择一名角色,令攻击范围内含有该角色的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。', - fuli_info:'限定技,当你处于濒死状态时,你可以将体力回复至与场上势力数相同,然后翻面。', - xinfuli_info:'限定技,当你处于濒死状态时,可以将体力回复至X点并将手牌摸至X张(X为场上势力数)。若X大于2,你翻面。', - qianxi_info:'准备阶段,你可以摸一张牌,并弃置一张牌,然后令一名距离为1的角色不能使用或打出与你弃置的牌颜色相同的手牌直到回合结束。', - zhiman_info:'当你对一名其他角色造成伤害时,你可以防止此伤害,然后获得其装备区或判定区的一张牌。', - sanyao_info:'出牌阶段限一次,你可以弃置一张牌并指定一名体力值最多(或之一)的角色,你对其造成1点伤害。', - olsanyao_info:'出牌阶段每项各限一次,你可以弃置一张牌并指定一名体力值或手牌数最多(或之一)的角色,并对其造成1点伤害。', - rezhiman_info:'当你对一名其他角色造成伤害时,你可以防止此伤害,然后获得其区域内的一张牌。', - resanyao_info:'出牌阶段限一次,你可以弃置任意张牌并指定等量除你外体力值最多(或之一)的其他角色。你对这些角色依次造成1点伤害。', - paiyi_info:'出牌阶段限一次,你可以移去一张“权”并选择一名角色,令其摸两张牌,然后若其手牌数大于你,你对其造成1伤害。', - zili_info:'觉醒技,准备阶段开始时,若“权”的数量不小于3,你减1点体力上限,然后选择一项:1、回复1点体力;2、摸两张牌。然后你获得技能“排异”。', - quanji_info:'当你受到1点伤害后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。', - xianzhou_info:'限定技。出牌阶段,你可以将装备区内的所有牌交给一名其他角色,然后该角色选择一项:令你回复X点体力;或对其攻击范围内的X名角色各造成1点伤害(X为你以此法交给该角色的牌的数量)。', - qieting_info:'其他角色的回合结束时,若其未于此回合内使用过指定其他角色为目标的牌,你可以选择一项:将其装备区里的一张牌移动至你装备区里的相应位置;或摸一张牌。', - zhuikong_info:'其他角色的准备阶段,若你已受伤,你可以与该角色拼点。若你赢,该角色本回合使用的牌不能指定除该角色外的角色为目标。若你没赢,其本回合至你的距离视为1。', - oldzhuikong_info:'其他角色的准备阶段,若你已受伤,你可以与该角色拼点。若你赢,该角色跳过本回合的出牌阶段。若你没赢,其本回合至你的距离视为1。', - qiuyuan_info:'当你成为【杀】的目标时,你可以令一名其他角色选择一项:①、交给你一张【闪】;②、成为此【杀】的额外目标。', - oldqiuyuan_info:'当你成为【杀】的目标时,你可以令一名有手牌的其他角色正面朝上交给你一张牌。若此牌不为【闪】,则该角色也成为此【杀】的额外目标。', - gongji_info:'出牌阶段限一次,你可以弃置一张牌,然后你的攻击范围视为无限直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。', - zhuiyi_info:'当你死亡时,你可以令一名其他角色(杀死你的角色除外)摸三张牌,然后其回复1点体力。', - anxu_info:'出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌多的角色将一张手牌交给手牌少的角色,然后若这两名角色手牌数相等,你摸一张牌或回复1点体力。', - old_anxu_info:'出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌少的角色获得手牌多的角色的一张手牌并展示之。然后若此牌不为黑桃,则你摸一张牌。', - zongxuan_info:'当你的牌因弃置而进入弃牌堆后,你可以将其按任意顺序置于牌堆顶。', - zhiyan_info:'结束阶段,你可以令一名角色摸一张牌并展示之,若为装备牌,其使用此牌并回复1点体力。', - miji_info:'结束阶段,若你已受伤,则可以摸X张牌,然后可以将等量的牌交给其他角色(X为你已损失的体力值)。', - zhenlie_info:'当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后弃置对方一张牌。', - chengxiang_info:'当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于13的牌。', - oldchengxiang_info:'当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于12的牌。', - renxin_info:'当体力值为1的一名其他角色受到伤害时,你可以将武将牌翻面并弃置一张装备牌,然后防止此伤害。', - oldrenxin_info:'其他角色进入濒死状态时,你可以将所有手牌交给该角色并翻面,然后该角色回复1点体力。', - jingce_info:'出牌阶段结束时,若你本回合使用的牌数量大于或等于你的当前体力值,你可以摸两张牌。', - xinjingce_info:'结束阶段,若你本回合使用的牌数量大于或等于你的当前体力值,你可以摸两张牌。', - xswuyan_info:'锁定技,你使用的普通锦囊牌对其他角色无效;其他角色使用的普通锦囊牌对你无效。', - xinwuyan_info:'锁定技,当你使用锦囊牌造成伤害时,你防止此伤害;锁定技,当你受到锦囊牌对你造成的伤害时,你防止此伤害。', - jujian_info:'出牌阶段限一次,你可以弃至多三张牌,然后令一名其他角色摸等量的牌。若你以此法弃牌不少于三张且均为同一类别,你回复1点体力。', - xinjujian_info:'结束阶段开始时,你可以弃置一张非基本牌并选择一名其他角色,令其选择一项:1.摸两张牌;2.回复1点体力;3.将其武将牌翻转至正面朝上并重置之。', - luoying_info:'当其他角色的梅花牌因弃置或判定而进入弃牌堆后,你可以获得之。', - jiushi_info:'当你需要使用一张【酒】时,若你的武将牌正面朝上,则你可以将武将牌翻面并视为使用了一张【酒】;当你受到伤害时,若你的武将牌背面朝上,则你可在此伤害结算后将武将牌翻回正面。', - jueqing_info:'锁定技,你即将造成的伤害均视为失去体力。', - shangshi_info:'当你的手牌数小于X时,你可以将手牌摸至X张(X为你已损失的体力值)。', - xuanfeng_info:'当你失去装备区内的牌时,或于弃牌阶段弃置了两张或更多的手牌后,你可以依次弃置一至两名其他角色的共计两张牌。', - zhiyu_info:'当你受到伤害后,你可以摸一张牌,然后展示所有手牌。若颜色均相同,你令伤害来源弃置一张手牌。', - qice_info:'出牌阶段限一次,你可以将所有的手牌(至少一张)当做任意一张普通锦囊牌使用。', - jiangchi_info:'摸牌阶段摸牌时,你可以选择一项:1、额外摸一张牌,若如此做,你不能使用或打出【杀】直到回合结束。 2、少摸一张牌,若如此做,你使用【杀】无距离限制且可以多使用一张【杀】直到回合结束。', - zishou_info:'摸牌阶段,你可以额外摸X张牌(X为场上势力数)。然后你于本回合的出牌阶段内使用的牌不能指定其他角色为目标。', - zongshi_info:'锁定技,你的手牌上限+X(X为场上现存势力数)。', - danshou_info:'出牌阶段,你可以选择你攻击范围内的一名其他角色,然后弃置X张牌(X为此前你于此阶段你发动“胆守”的次数+1)。若X:为1,你弃置该角色的一张牌;为2,令该角色交给你一张牌;为3,你对该角色造成1点伤害;不小于4,你与该角色各摸两张牌。', - olddanshou_info:'当你造成伤害后,你可以摸一张牌。若如此做,终止一切结算,当前回合结束。', - xindanshou_info:'①每回合限一次,当你成为基本牌或锦囊牌的目标后,你可以摸X张牌(X为你本回合内成为过基本牌或锦囊牌的目标的次数)。②一名其他角色的结束阶段,若你本回合内没有发动过〖胆守①〗,则你可以弃置X张牌并对其造成1点伤害(X为其手牌数,无牌则不弃)。', - yizhong_info:'锁定技,当你的防具栏为空时,黑色的【杀】对你无效。', - xinzhan_info:'出牌阶段限一次,若你的手牌数大于你的体力上限,你可以观看牌堆顶的三张牌,然后展示其中任意红桃牌并获得之。', - huilei_info:'锁定技,当你死亡时,杀死你的角色弃置所有的牌。', - enyuan_info:'锁定技。①当其他角色令你回复1点体力后,该角色摸一张牌。②当其他角色对你造成伤害后,其须交给你一张♥手牌,否则失去1点体力。', - xuanhuo_info:'出牌阶段限一次,你可以将一张红桃手牌交给一名其他角色,获得该角色的一张牌,然后交给除该角色外的一名其他角色。', - ganlu_info:'出牌阶段限一次,你可以选择两名装备区内装备数之差不大于X的角色,令其交换装备区内的牌(X为你已损失的体力值)。', - buyi_info:'当有角色进入濒死状态时,你可以展示该角色的一张手牌:若此牌不为基本牌,则该角色弃置此牌并回复1点体力。', - mingce_info:'出牌阶段,你可以交给一名其他角色一张装备牌或【杀】,然后令该角色选择一项:1. 视为对其攻击范围内的另一名由你指定的角色使用一张【杀】。2. 摸一张牌。每回合限一次。', - zhichi_info:'锁定技,当你于回合外受到伤害后,所有【杀】或普通锦囊牌对你无效直到回合结束。', - zhichi2_info:'智迟已发动', - pojun_info:'当你使用【杀】造成伤害后,你可以令受伤角色摸X张牌,然后其翻面(X为该角色的体力值且至多为5)。', - shiyong:'恃勇', - shiyong_info:'锁定技,当你受到一次红色【杀】或【酒】【杀】造成的伤害后,须减1点体力上限。', - old_guanzhang:'旧关兴张苞', - old_guanzhang_prefix:'旧', - wangyi:'王异', - oldqianxi:'潜袭', - oldqianxi_info:'当你使用【杀】对距离为1的目标角色造成伤害时,你可以进行一次判定,若判定结果不为红桃,你防止此伤害,令其减1点体力上限。', - oldzhenlie:'贞烈', - oldzhenlie_info:'在你的判定牌生效前,你可以亮出牌堆顶的一张牌代替之。', - oldmiji:'秘计', - oldmiji_info:'准备/结束阶段开始时,若你已受伤,你可以判定,若判定结果为黑色,你观看牌堆顶的X张牌(X为你已损失的体力值),然后将这些牌交给一名角色。', - old_fuhun:'父魂', - old_fuhun_info:'摸牌阶段开始时,你可以放弃摸牌,改为从牌堆顶亮出两张牌并获得之,若亮出的牌颜色不同,你获得〖武圣〗和〖咆哮〗直到回合结束。', - rejueqing:'绝情', - rejueqing_info:'当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力并修改〖绝情〗(X为伤害值)。', - rejueqing_1st:'绝情', - rejueqing_rewrite:'绝情·改', - rejueqing_rewrite_info:'锁定技,你即将造成的伤害均视为失去体力。', - reshangshi:'伤逝', - reshangshi_2nd:'伤逝', - reshangshi_info:'当你受到伤害时,你可以弃置一张牌。当你的手牌数小于X时,你可以将手牌摸至X张。(X为你已损失的体力值)', - rejingce:'精策', - rejingce2:'精策', - rejingce_add:'精策', - rejingce_info:'当你于一回合内首次使用某种花色的手牌时,你的手牌上限+1。出牌阶段结束时,你可以摸X张牌(X为你本阶段内使用过的牌的类型数)。', - xinkuangbi:'匡弼', - xinkuangbi_info:'出牌阶段限一次。你可以令一名其他角色交给你至多三张牌(不计入你本回合的手牌上限)。然后其于其的下回合开始时摸等量的牌。', - xinzhaofu:'诏缚', - xinzhaofu_info:'主公技,限定技。出牌阶段,你可选择至多两名其他角色。这两名角色视为在所有其他吴势力角色的攻击范围内。', - olbingyi:'秉壹', - olbingyi_info:'每阶段限一次。当你因弃置而失去牌后,你可以展示所有手牌。若这些牌的颜色均相同,则你可以与至多X名其他角色各摸一张牌(X为你的手牌数)。', - lukai:'陆凯', - lukai_spade:'♠', - lukai_spade_bg:'♠️', - lukai_heart:'♥', - lukai_heart_bg:'♥️', - lukai_club:'♣', - lukai_club_bg:'♣', - lukai_diamond:'♦', - lukai_diamond_bg:'♦️️', - lkbushi:'卜筮', - lkbushi_info:'①你使用♠牌无次数限制。②当你使用或打出♥牌后,你摸一张牌。③当你成为♣牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张♦牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。', - lkzhongzhuang:'忠壮', - lkzhongzhuang_info:'锁定技。①当你因执行【杀】的效果而造成伤害时,若你的攻击范围大于3,则此伤害+1。②当一名角色受到你因执行【杀】的效果而造成的伤害时,若你的攻击范围小于3,则此伤害改为1。', - kebineng:'轲比能', - kousheng:'寇旌', - kousheng_info:'①出牌阶段开始时,你可以选择任意张手牌,这些牌称为“寇旌”直到回合结束。②你的“寇旌”均视为【杀】且无次数限制。③当你因执行对应实体牌包含“寇旌”的【杀】的效果而造成伤害后,你展示所有“寇旌”牌,然后目标角色可以用所有手牌交换这些牌。', - zhugeshang:'诸葛尚', - sangu:'三顾', - sangu_info:'结束阶段,你可以选择至多三个{【杀】或不为notarget或singleCard的普通锦囊牌}中的牌名,然后令一名其他角色记录这些牌名。该角色的下个出牌阶段开始时,其的手牌于其需要使用牌时均视为其记录中的第一张牌直到此阶段结束,且当其使用或打出有对应实体牌的牌时,移除这些牌中的第一张牌。若你以此法选择过的牌名均为你本回合内使用过的牌名,则防止你因其以此法使用牌造成的伤害。', - yizu:'轶祖', - yizu_info:'锁定技。每回合限一次,当你成为【杀】或【决斗】的目标后,若你的体力值不大于使用者的体力值,则你回复1点体力。', - liwan:'李婉', - liandui:'联对', - liandui_info:'①当你使用牌时,若本局游戏内上一张被使用的牌的使用者不为你,你可以令其摸两张牌。②其他角色使用牌时,若本局游戏内上一张被使用的牌的使用者为你,其可以令你摸两张牌。', - biejun:'别君', - biejun_info:'①其他角色的出牌阶段限一次。其可以将一张手牌交给你。②每回合限一次。当你受到伤害时,若你手牌中没有本回合因〖别君①〗得到的牌,你可以翻面并防止此伤害。', - yj_sufei:'苏飞', - shuojian:'数谏', - shuojian_info:'出牌阶段限三次。你可以交给一名其他角色一张牌,其选择一项:1.令你摸X张牌并弃置X-1张牌;2.视为使用X张【过河拆桥】,然后此技能本回合失效(X为此技能本阶段剩余发动次数+1)。', - yj_qiaozhou:'谯周', - shiming:'识命', - shiming_info:'每轮限一次。一名角色的摸牌阶段,你可以观看牌堆顶的三张牌,并可以将其中一张置于牌堆底。然后该角色可以改为对自己造成1点伤害,然后从牌堆底摸三张牌。', - jiangxi:'将息', - jiangxi_info:'一名角色的回合结束时,若一号位于此回合内进入过濒死状态或未受到过伤害,你可以重置〖识命〗并摸一张牌;若所有角色均未受到过伤害,你可以与当前回合角色各摸一张牌。', - hanlong:'韩龙', - duwang:'独往', - duwang_info:'锁定技。①游戏开始时,你从牌堆顶将五张不为【杀】的牌置于武将牌上,称为“刺”。②若你有牌名不为【杀】“刺”,你至其他角色或其他角色至你的距离+1。', - cibei:'刺北', - cibei_info:'①当一名角色使用【杀】造成伤害且此牌对应的实体牌进入弃牌堆后,你可以将一张不为【杀】的“刺”置入弃牌堆,并将这些牌置入“刺”,然后弃置一名角色区域里的一张牌。②一名角色的回合结束时,若你的“刺”均为【杀】,你获得所有“刺”,且这些牌不能被弃置,不计入手牌上限,且当你使用对应实体牌包含这些牌的牌时无次数和距离限制。', - wuanguo:'武安国', - diezhang:'叠嶂', - diezhang_info:'转换技。①出牌阶段,你使用杀的次数上限+1。②阴:当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用X张【杀】;阳:当其他角色使用牌被你抵消后,你可以摸X张牌,视为对其使用一张【杀】(X为1)。', - duanwan:'断腕', - duanwan_info:'限定技。当你处于濒死状态时,你可以将体力回复至2点,然后删除〖叠嶂①〗和当前转换技状态的〖叠嶂②〗分支,并将〖叠嶂〗修改为“每回合限一次”且将X修改为2。', - dcduliang:'督粮', - dcduliang2:'督粮', - dcduliang_info:'出牌阶段限一次。你可以获得一名其他角色的一张牌,然后选择一项:1.你观看牌堆顶的两张牌,然后令其获得其中的一或两张基本牌;2.令其于下回合的摸牌阶段额外摸一张牌。', - sunli:'孙礼', - kangli:'伉厉', - kangli_info:'当你造成或受到伤害后,你摸两张牌。然后你下次造成伤害时弃置这些牌。', - xiahoumao:'夏侯楙', - tongwei:'统围', - tongwei_info:'出牌阶段限一次。你可以重铸两张牌并指定一名其他角色,当其使用的下一张牌结算结束后,若此牌点数在你上次以此法重铸的牌的点数之间,你视为对其使用一张【杀】或【过河拆桥】。', - cuguo:'蹙国', - cuguo_info:'锁定技。当你于一回合使用牌首次被抵消后,你弃置一张牌,视为对此牌的目标角色使用一张该被抵消的牌。此牌结算结束后,若此牌被抵消,你失去1点体力。', - chenshi:'陈式', - qingbei:'擎北', - qingbei_info:'一轮游戏开始时,你可以选择任意种花色,你不能于本轮内使用这些花色的牌。然后当你于本轮使用一张有花色的牌结算结束后,你摸等同于你上一次〖擎北〗选择过的花色数的牌。', - feiyao:'费曜', - zhenfeng:'镇锋', - zhenfeng_info:'每回合限一次。当其他角色于其回合内使用牌时,若其手牌数不大于其体力值,你可以猜测其手牌中与此牌类别相同的牌数。若你猜对,你摸X张牌并视为对其使用一张【杀】(X为你连续猜对的次数且至多为5);若你猜错且差值大于1,其视为对你使用一张【杀】。', + xswuyan: "无言", + xinwuyan: "无言", + jujian: "举荐", + xinjujian: "举荐", + luoying: "落英", + luoying_discard: "落英", + luoying_judge: "落英", + luoying_judge_noconf: "落英·判定", + jiushi: "酒诗", + jiushi1: "酒诗", + jiushi2: "酒诗", + jiushi3: "酒诗", + jueqing: "绝情", + shangshi: "伤逝", + xuanfeng: "旋风", + zhiyu: "智愚", + qice: "奇策", + qice_backup: "奇策", + jiangchi: "将驰", + jiangchi_less: "少摸一张", + jiangchi_more: "多摸一张", + zishou: "自守", + zongshi: "宗室", + danshou: "胆守", + olddanshou: "胆守", + xindanshou: "胆守", + yizhong: "毅重", + xinzhan: "心战", + xinzhan_gain: "获得", + xinzhan_place: "牌堆顶", + huilei: "挥泪", + enyuan: "恩怨", + enyuan1: "恩怨", + enyuan2: "恩怨", + xuanhuo: "眩惑", + ganlu: "甘露", + buyi: "补益", + mingce: "明策", + zhichi: "智迟", + zhichi2: "智迟", + pojun: "破军", + jingce: "精策", + xinjingce: "精策", + chengxiang: "称象", + oldchengxiang: "称象", + renxin: "仁心", + oldrenxin: "仁心", + zhenlie: "贞烈", + miji: "秘计", + miji_tag: "已分配", + zhiyan: "直言", + zongxuan: "纵玄", + anxu: "安恤", + old_anxu: "安恤", + zhuiyi: "追忆", + gongji: "弓骑", + qiuyuan: "求援", + oldqiuyuan: "求援", + zhuikong: "惴恐", + oldzhuikong: "惴恐", + qieting: "窃听", + xianzhou: "献州", + quanji: "权计", + zili: "自立", + paiyi: "排异", + paiyi_backup: "排异", + sanyao: "散谣", + olsanyao: "散谣", + olsanyao_backup: "散谣", + zhiman: "制蛮", + resanyao: "散谣", + rezhiman: "制蛮", + qianxi: "潜袭", + qianxi2: "潜袭", + qianxi2_bg: "袭", + fuli: "伏枥", + xinfuli: "伏枥", + jiefan: "解烦", + juece: "绝策", + mieji: "灭计", + fencheng: "焚城", + youdi: "诱敌", + youdi_info: + "结束阶段开始时,你可以令一名其他角色弃置你的一张牌,若此牌不为【杀】,你获得该角色的一张牌。", + fencheng_info: + "限定技。出牌阶段,你可令所有其他角色依次选择一项:弃置X张牌;或受到1点火焰伤害。(X为该角色装备区里牌的数量且至少为1)", + mieji_info: "当你使用黑色普通锦囊牌选择目标后,若目标数为1,则你可以额外指定一个目标。", + juece_info: "当其他角色在你回合内失去最后的手牌后,你可以对其造成1点伤害。", + jiefan_info: + "限定技,出牌阶段,你可以选择一名角色,令攻击范围内含有该角色的所有角色依次选择一项:1.弃置一张武器牌;2.令其摸一张牌。", + fuli_info: "限定技,当你处于濒死状态时,你可以将体力回复至与场上势力数相同,然后翻面。", + xinfuli_info: + "限定技,当你处于濒死状态时,可以将体力回复至X点并将手牌摸至X张(X为场上势力数)。若X大于2,你翻面。", + qianxi_info: + "准备阶段,你可以摸一张牌,并弃置一张牌,然后令一名距离为1的角色不能使用或打出与你弃置的牌颜色相同的手牌直到回合结束。", + zhiman_info: "当你对一名其他角色造成伤害时,你可以防止此伤害,然后获得其装备区或判定区的一张牌。", + sanyao_info: + "出牌阶段限一次,你可以弃置一张牌并指定一名体力值最多(或之一)的角色,你对其造成1点伤害。", + olsanyao_info: + "出牌阶段每项各限一次,你可以弃置一张牌并指定一名体力值或手牌数最多(或之一)的角色,并对其造成1点伤害。", + rezhiman_info: "当你对一名其他角色造成伤害时,你可以防止此伤害,然后获得其区域内的一张牌。", + resanyao_info: + "出牌阶段限一次,你可以弃置任意张牌并指定等量除你外体力值最多(或之一)的其他角色。你对这些角色依次造成1点伤害。", + paiyi_info: + "出牌阶段限一次,你可以移去一张“权”并选择一名角色,令其摸两张牌,然后若其手牌数大于你,你对其造成1点伤害。", + zili_info: + "觉醒技,准备阶段开始时,若“权”的数量不小于3,你减1点体力上限,然后选择一项:1、回复1点体力;2、摸两张牌。然后你获得技能“排异”。", + quanji_info: + "当你受到1点伤害后,你可以摸一张牌,然后将一张手牌置于武将牌上,称为“权”;你的手牌上限+X(X为“权”的数量)。", + xianzhou_info: + "限定技。出牌阶段,你可以将装备区内的所有牌交给一名其他角色,然后该角色选择一项:令你回复X点体力;或对其攻击范围内的X名角色各造成1点伤害(X为你以此法交给该角色的牌的数量)。", + qieting_info: + "其他角色的回合结束时,若其未于此回合内使用过指定其他角色为目标的牌,你可以选择一项:将其装备区里的一张牌移动至你装备区里的相应位置;或摸一张牌。", + zhuikong_info: + "其他角色的准备阶段,若你已受伤,你可以与该角色拼点。若你赢,该角色本回合使用的牌不能指定除该角色外的角色为目标。若你没赢,其本回合至你的距离视为1。", + oldzhuikong_info: + "其他角色的准备阶段,若你已受伤,你可以与该角色拼点。若你赢,该角色跳过本回合的出牌阶段。若你没赢,其本回合至你的距离视为1。", + qiuyuan_info: + "当你成为【杀】的目标时,你可以令一名其他角色选择一项:①、交给你一张【闪】;②、成为此【杀】的额外目标。", + oldqiuyuan_info: + "当你成为【杀】的目标时,你可以令一名有手牌的其他角色正面朝上交给你一张牌。若此牌不为【闪】,则该角色也成为此【杀】的额外目标。", + gongji_info: + "出牌阶段限一次,你可以弃置一张牌,然后你的攻击范围视为无限直到回合结束。若你以此法弃置的牌为装备牌,则你可以弃置一名其他角色的一张牌。", + zhuiyi_info: "当你死亡时,你可以令一名其他角色(杀死你的角色除外)摸三张牌,然后其回复1点体力。", + anxu_info: + "出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌多的角色将一张手牌交给手牌少的角色,然后若这两名角色手牌数相等,你摸一张牌或回复1点体力。", + old_anxu_info: + "出牌阶段限一次,你可以选择两名手牌数不同的其他角色,令其中手牌少的角色获得手牌多的角色的一张手牌并展示之。然后若此牌不为黑桃,则你摸一张牌。", + zongxuan_info: "当你的牌因弃置而进入弃牌堆后,你可以将其按任意顺序置于牌堆顶。", + zhiyan_info: "结束阶段,你可以令一名角色摸一张牌并展示之,若为装备牌,其使用此牌并回复1点体力。", + miji_info: + "结束阶段,若你已受伤,则可以摸X张牌,然后可以将等量的牌交给其他角色(X为你已损失的体力值)。", + zhenlie_info: + "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后弃置对方一张牌。", + chengxiang_info: + "当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于13的牌。", + oldchengxiang_info: + "当你受到伤害后,你可以亮出牌堆顶的四张牌。然后获得其中任意数量点数之和不大于12的牌。", + renxin_info: + "当体力值为1的一名其他角色受到伤害时,你可以将武将牌翻面并弃置一张装备牌,然后防止此伤害。", + oldrenxin_info: + "其他角色进入濒死状态时,你可以将所有手牌交给该角色并翻面,然后该角色回复1点体力。", + jingce_info: "出牌阶段结束时,若你本回合使用的牌数量大于或等于你的当前体力值,你可以摸两张牌。", + xinjingce_info: "结束阶段,若你本回合使用的牌数量大于或等于你的当前体力值,你可以摸两张牌。", + xswuyan_info: "锁定技,你使用的普通锦囊牌对其他角色无效;其他角色使用的普通锦囊牌对你无效。", + xinwuyan_info: + "锁定技,当你使用锦囊牌造成伤害时,你防止此伤害;锁定技,当你受到锦囊牌对你造成的伤害时,你防止此伤害。", + jujian_info: + "出牌阶段限一次,你可以弃至多三张牌,然后令一名其他角色摸等量的牌。若你以此法弃牌不少于三张且均为同一类别,你回复1点体力。", + xinjujian_info: + "结束阶段开始时,你可以弃置一张非基本牌并选择一名其他角色,令其选择一项:1.摸两张牌;2.回复1点体力;3.将其武将牌翻转至正面朝上并重置之。", + luoying_info: "当其他角色的梅花牌因弃置或判定而进入弃牌堆后,你可以获得之。", + jiushi_info: + "当你需要使用一张【酒】时,若你的武将牌正面朝上,则你可以将武将牌翻面并视为使用了一张【酒】;当你受到伤害时,若你的武将牌背面朝上,则你可在此伤害结算后将武将牌翻回正面。", + jueqing_info: "锁定技,你即将造成的伤害均视为失去体力。", + shangshi_info: "当你的手牌数小于X时,你可以将手牌摸至X张(X为你已损失的体力值)。", + xuanfeng_info: + "当你失去装备区内的牌时,或于弃牌阶段弃置了两张或更多的手牌后,你可以依次弃置一至两名其他角色的共计两张牌。", + zhiyu_info: + "当你受到伤害后,你可以摸一张牌,然后展示所有手牌。若颜色均相同,你令伤害来源弃置一张手牌。", + qice_info: "出牌阶段限一次,你可以将所有的手牌(至少一张)当做任意一张普通锦囊牌使用。", + jiangchi_info: + "摸牌阶段摸牌时,你可以选择一项:1、额外摸一张牌,若如此做,你不能使用或打出【杀】直到回合结束。 2、少摸一张牌,若如此做,你使用【杀】无距离限制且可以多使用一张【杀】直到回合结束。", + zishou_info: + "摸牌阶段,你可以额外摸X张牌(X为场上势力数)。然后你于本回合的出牌阶段内使用的牌不能指定其他角色为目标。", + zongshi_info: "锁定技,你的手牌上限+X(X为场上现存势力数)。", + danshou_info: + "出牌阶段,你可以选择你攻击范围内的一名其他角色,然后弃置X张牌(X为此前你于此阶段你发动“胆守”的次数+1)。若X:为1,你弃置该角色的一张牌;为2,令该角色交给你一张牌;为3,你对该角色造成1点伤害;不小于4,你与该角色各摸两张牌。", + olddanshou_info: "当你造成伤害后,你可以摸一张牌。若如此做,终止一切结算,当前回合结束。", + xindanshou_info: + "①每回合限一次,当你成为基本牌或锦囊牌的目标后,你可以摸X张牌(X为你本回合内成为过基本牌或锦囊牌的目标的次数)。②一名其他角色的结束阶段,若你本回合内没有发动过〖胆守①〗,则你可以弃置X张牌并对其造成1点伤害(X为其手牌数,无牌则不弃)。", + yizhong_info: "锁定技,当你的防具栏为空时,黑色的【杀】对你无效。", + xinzhan_info: + "出牌阶段限一次,若你的手牌数大于你的体力上限,你可以观看牌堆顶的三张牌,然后展示其中任意红桃牌并获得之。", + huilei_info: "锁定技,当你死亡时,杀死你的角色弃置所有的牌。", + enyuan_info: + "锁定技。①当其他角色令你回复1点体力后,该角色摸一张牌。②当其他角色对你造成伤害后,其须交给你一张♥手牌,否则失去1点体力。", + xuanhuo_info: + "出牌阶段限一次,你可以将一张红桃手牌交给一名其他角色,获得该角色的一张牌,然后交给除该角色外的一名其他角色。", + ganlu_info: + "出牌阶段限一次,你可以选择两名装备区内装备数之差不大于X的角色,令其交换装备区内的牌(X为你已损失的体力值)。", + buyi_info: + "当有角色进入濒死状态时,你可以展示该角色的一张手牌:若此牌不为基本牌,则该角色弃置此牌并回复1点体力。", + mingce_info: + "出牌阶段,你可以交给一名其他角色一张装备牌或【杀】,然后令该角色选择一项:1. 视为对其攻击范围内的另一名由你指定的角色使用一张【杀】。2. 摸一张牌。每回合限一次。", + zhichi_info: "锁定技,当你于回合外受到伤害后,所有【杀】或普通锦囊牌对你无效直到回合结束。", + zhichi2_info: "智迟已发动", + pojun_info: + "当你使用【杀】造成伤害后,你可以令受伤角色摸X张牌,然后其翻面(X为该角色的体力值且至多为5)。", + shiyong: "恃勇", + shiyong_info: "锁定技,当你受到一次红色【杀】或【酒】【杀】造成的伤害后,须减1点体力上限。", + old_guanzhang: "旧关兴张苞", + old_guanzhang_prefix: "旧", + wangyi: "王异", + oldqianxi: "潜袭", + oldqianxi_info: + "当你使用【杀】对距离为1的目标角色造成伤害时,你可以进行一次判定,若判定结果不为红桃,你防止此伤害,令其减1点体力上限。", + oldzhenlie: "贞烈", + oldzhenlie_info: "在你的判定牌生效前,你可以亮出牌堆顶的一张牌代替之。", + oldmiji: "秘计", + oldmiji_info: + "准备/结束阶段开始时,若你已受伤,你可以判定,若判定结果为黑色,你观看牌堆顶的X张牌(X为你已损失的体力值),然后将这些牌交给一名角色。", + old_fuhun: "父魂", + old_fuhun_info: + "摸牌阶段开始时,你可以放弃摸牌,改为从牌堆顶亮出两张牌并获得之,若亮出的牌颜色不同,你获得〖武圣〗和〖咆哮〗直到回合结束。", + rejueqing: "绝情", + rejueqing_info: + "当你对其他角色造成伤害时,你可以令此伤害值+X。若如此做,你失去X点体力并修改〖绝情〗(X为伤害值)。", + rejueqing_1st: "绝情", + rejueqing_rewrite: "绝情·改", + rejueqing_rewrite_info: "锁定技,你即将造成的伤害均视为失去体力。", + reshangshi: "伤逝", + reshangshi_2nd: "伤逝", + reshangshi_info: + "当你受到伤害时,你可以弃置一张牌。当你的手牌数小于X时,你可以将手牌摸至X张。(X为你已损失的体力值)", + rejingce: "精策", + rejingce2: "精策", + rejingce_add: "精策", + rejingce_info: + "当你于一回合内首次使用某种花色的手牌时,你的手牌上限+1。出牌阶段结束时,你可以摸X张牌(X为你本阶段内使用过的牌的类型数)。", + xinkuangbi: "匡弼", + xinkuangbi_info: + "出牌阶段限一次。你可以令一名其他角色交给你至多三张牌(不计入你本回合的手牌上限)。然后其于其的下回合开始时摸等量的牌。", + xinzhaofu: "诏缚", + xinzhaofu_info: + "主公技,限定技。出牌阶段,你可选择至多两名其他角色。这两名角色视为在所有其他吴势力角色的攻击范围内。", + olbingyi: "秉壹", + olbingyi_info: + "每阶段限一次。当你因弃置而失去牌后,你可以展示所有手牌。若这些牌的颜色均相同,则你可以与至多X名其他角色各摸一张牌(X为你的手牌数)。", + lukai: "陆凯", + lukai_spade: "♠", + lukai_spade_bg: "♠️", + lukai_heart: "♥", + lukai_heart_bg: "♥️", + lukai_club: "♣", + lukai_club_bg: "♣", + lukai_diamond: "♦", + lukai_diamond_bg: "♦️️", + lkbushi: "卜筮", + lkbushi_info: + "①你使用♠牌无次数限制。②当你使用或打出♥牌后,你摸一张牌。③当你成为♣牌的目标后,你可以弃置一张牌,令此牌对你无效。④结束阶段开始时,你从牌堆或弃牌堆获得一张♦牌。⑤准备阶段开始时,你可调整此技能中四种花色的对应顺序。", + lkzhongzhuang: "忠壮", + lkzhongzhuang_info: + "锁定技。①当你因执行【杀】的效果而造成伤害时,若你的攻击范围大于3,则此伤害+1。②当一名角色受到你因执行【杀】的效果而造成的伤害时,若你的攻击范围小于3,则此伤害改为1。", + kebineng: "轲比能", + kousheng: "寇旌", + kousheng_info: + "①出牌阶段开始时,你可以选择任意张手牌,这些牌称为“寇旌”直到回合结束。②你的“寇旌”均视为【杀】且无次数限制。③当你因执行对应实体牌包含“寇旌”的【杀】的效果而造成伤害后,你展示所有“寇旌”牌,然后目标角色可以用所有手牌交换这些牌。", + zhugeshang: "诸葛尚", + sangu: "三顾", + sangu_info: + "结束阶段,你可以选择至多三个{【杀】或不为notarget或singleCard的普通锦囊牌}中的牌名,然后令一名其他角色记录这些牌名。该角色的下个出牌阶段开始时,其的手牌于其需要使用牌时均视为其记录中的第一张牌直到此阶段结束,且当其使用或打出有对应实体牌的牌时,移除这些牌中的第一张牌。若你以此法选择过的牌名均为你本回合内使用过的牌名,则防止你因其以此法使用牌造成的伤害。", + yizu: "轶祖", + yizu_info: + "锁定技。每回合限一次,当你成为【杀】或【决斗】的目标后,若你的体力值不大于使用者的体力值,则你回复1点体力。", + liwan: "李婉", + liandui: "联对", + liandui_info: + "①当你使用牌时,若本局游戏内上一张被使用的牌的使用者不为你,你可以令其摸两张牌。②其他角色使用牌时,若本局游戏内上一张被使用的牌的使用者为你,其可以令你摸两张牌。", + biejun: "别君", + biejun_info: + "①其他角色的出牌阶段限一次。其可以将一张手牌交给你。②每回合限一次。当你受到伤害时,若你手牌中没有本回合因〖别君①〗得到的牌,你可以翻面并防止此伤害。", + yj_sufei: "苏飞", + shuojian: "数谏", + shuojian_info: + "出牌阶段限三次。你可以交给一名其他角色一张牌,其选择一项:1.令你摸X张牌并弃置X-1张牌;2.视为使用X张【过河拆桥】,然后此技能本回合失效(X为此技能本阶段剩余发动次数+1)。", + yj_qiaozhou: "谯周", + shiming: "识命", + shiming_info: + "每轮限一次。一名角色的摸牌阶段,你可以观看牌堆顶的三张牌,并可以将其中一张置于牌堆底。然后该角色可以改为对自己造成1点伤害,然后从牌堆底摸三张牌。", + jiangxi: "将息", + jiangxi_info: + "一名角色的回合结束时,若一号位于此回合内进入过濒死状态或未受到过伤害,你可以重置〖识命〗并摸一张牌;若所有角色均未受到过伤害,你可以与当前回合角色各摸一张牌。", + hanlong: "韩龙", + duwang: "独往", + duwang_info: + "锁定技。①游戏开始时,你从牌堆顶将五张不为【杀】的牌置于武将牌上,称为“刺”。②若你有牌名不为【杀】“刺”,你至其他角色或其他角色至你的距离+1。", + cibei: "刺北", + cibei_info: + "①当一名角色使用【杀】造成伤害且此牌对应的实体牌进入弃牌堆后,你可以将一张不为【杀】的“刺”置入弃牌堆,并将这些牌置入“刺”,然后弃置一名角色区域里的一张牌。②一名角色的回合结束时,若你的“刺”均为【杀】,你获得所有“刺”,且这些牌不能被弃置,不计入手牌上限,且当你使用对应实体牌包含这些牌的牌时无次数和距离限制。", + wuanguo: "武安国", + diezhang: "叠嶂", + diezhang_info: + "转换技。①出牌阶段,你使用杀的次数上限+1。②阴:当你使用牌被其他角色抵消后,你可以弃置一张牌,视为对其使用X张【杀】;阳:当其他角色使用牌被你抵消后,你可以摸X张牌,视为对其使用一张【杀】(X为1)。", + duanwan: "断腕", + duanwan_info: + "限定技。当你处于濒死状态时,你可以将体力回复至2点,然后删除〖叠嶂①〗和当前转换技状态的〖叠嶂②〗分支,并将〖叠嶂〗修改为“每回合限一次”且将X修改为2。", + dcduliang: "督粮", + dcduliang2: "督粮", + dcduliang_info: + "出牌阶段限一次。你可以获得一名其他角色的一张牌,然后选择一项:1.你观看牌堆顶的两张牌,然后令其获得其中的一或两张基本牌;2.令其于下回合的摸牌阶段额外摸一张牌。", + sunli: "孙礼", + kangli: "伉厉", + kangli_info: "当你造成或受到伤害后,你摸两张牌。然后你下次造成伤害时弃置这些牌。", + xiahoumao: "夏侯楙", + tongwei: "统围", + tongwei_info: + "出牌阶段限一次。你可以重铸两张牌并指定一名其他角色,当其使用的下一张牌结算结束后,若此牌点数在你上次以此法重铸的牌的点数之间,你视为对其使用一张【杀】或【过河拆桥】。", + cuguo: "蹙国", + cuguo_info: + "锁定技。当你于一回合使用牌首次被抵消后,你弃置一张牌,视为对此牌的目标角色使用一张该被抵消的牌。此牌结算结束后,若此牌被抵消,你失去1点体力。", + chenshi: "陈式", + qingbei: "擎北", + qingbei_info: + "一轮游戏开始时,你可以选择任意种花色,你不能于本轮内使用这些花色的牌。然后当你于本轮使用一张有花色的牌结算结束后,你摸等同于你上一次〖擎北〗选择过的花色数的牌。", + feiyao: "费曜", + zhenfeng: "镇锋", + zhenfeng_info: + "每回合限一次。当其他角色于其回合内使用牌时,若其手牌数不大于其体力值,你可以猜测其手牌中与此牌类别相同的牌数。若你猜对,你摸X张牌并视为对其使用一张【杀】(X为你连续猜对的次数且至多为5);若你猜错且差值大于1,其视为对你使用一张【杀】。", - yijiang_2011:'一将成名2011', - yijiang_2012:'一将成名2012', - yijiang_2013:'一将成名2013', - yijiang_2014:'一将成名2014', - yijiang_2015:'一将成名2015', - yijiang_2016:'原创设计2016', - yijiang_2017:'原创设计2017', - yijiang_2022:'原创设计2022', - yijiang_2023:'一将成名2023', + yijiang_2011: "一将成名2011", + yijiang_2012: "一将成名2012", + yijiang_2013: "一将成名2013", + yijiang_2014: "一将成名2014", + yijiang_2015: "一将成名2015", + yijiang_2016: "原创设计2016", + yijiang_2017: "原创设计2017", + yijiang_2022: "原创设计2022", + yijiang_2023: "一将成名2023", }, }; }); diff --git a/character/yingbian.js b/character/yingbian.js index 382e2aaf8..15a605753 100644 --- a/character/yingbian.js +++ b/character/yingbian.js @@ -1,4006 +1,5017 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'yingbian', - connect:true, - character:{ - chengjichengcui:['male','jin',6,['oltousui','olchuming']], - wangxiang:['male','jin',3,['bingxin']], - jin_jiachong:['male','jin',3,['xiongshu','jianhui']], - xuangongzhu:['female','jin',3,['gaoling','qimei','ybzhuiji'],['hiddenSkill']], - xinchang:['male','jin',3,['canmou','congjian']], - yangzhi:['female','jin',3,['xinwanyi','maihuo']], - yangyan:['female','jin',3,['xinxuanbei','xianwan']], - ol_huaxin:['male','wei',3,['caozhao','olxibing']], - zhongyan:['female','jin',3,['bolan','yifa'],['clan:颍川钟氏']], - weiguan:['male','jin',3,['zhongyun','shenpin']], - cheliji:['male','qun',4,['chexuan','qiangshou']], - simazhou:['male','jin',4,['recaiwang','naxiang']], - ol_lisu:['male','qun',3,['qiaoyan','xianzhu']], - jin_yanghuiyu:['female','jin',3,['huirong','ciwei','caiyuan'],['hiddenSkill']], - shibao:['male','jin',4,['zhuosheng']], - jin_zhangchunhua:['female','jin',3,['huishi','qingleng','xuanmu'],['hiddenSkill']], - jin_simayi:['male','jin',3,['buchen','smyyingshi','xiongzhi','xinquanbian'],['hiddenSkill']], - jin_wangyuanji:['female','jin',3,['shiren','yanxi'],['hiddenSkill']], - jin_simazhao:['male','jin',3,['tuishi','xinchoufa','zhaoran','chengwu'],['zhu','hiddenSkill']], - jin_xiahouhui:['female','jin',3,['baoqie','jyishi','shiduo'],['hiddenSkill']], - jin_simashi:['male','jin','3/4',['taoyin','yimie','ruilve','tairan'],['hiddenSkill','zhu']], - zhanghuyuechen:['male','jin',4,['xijue']], - duyu:['male','jin',4,['sanchen','zhaotao']], + name: "yingbian", + connect: true, + character: { + chengjichengcui: ["male", "jin", 6, ["oltousui", "olchuming"]], + wangxiang: ["male", "jin", 3, ["bingxin"]], + jin_jiachong: ["male", "jin", 3, ["xiongshu", "jianhui"]], + xuangongzhu: ["female", "jin", 3, ["gaoling", "qimei", "ybzhuiji"], ["hiddenSkill"]], + xinchang: ["male", "jin", 3, ["canmou", "congjian"]], + yangzhi: ["female", "jin", 3, ["xinwanyi", "maihuo"]], + yangyan: ["female", "jin", 3, ["xinxuanbei", "xianwan"]], + ol_huaxin: ["male", "wei", 3, ["caozhao", "olxibing"]], + zhongyan: ["female", "jin", 3, ["bolan", "yifa"], ["clan:颍川钟氏"]], + weiguan: ["male", "jin", 3, ["zhongyun", "shenpin"]], + cheliji: ["male", "qun", 4, ["chexuan", "qiangshou"]], + simazhou: ["male", "jin", 4, ["recaiwang", "naxiang"]], + ol_lisu: ["male", "qun", 3, ["qiaoyan", "xianzhu"]], + jin_yanghuiyu: ["female", "jin", 3, ["huirong", "ciwei", "caiyuan"], ["hiddenSkill"]], + shibao: ["male", "jin", 4, ["zhuosheng"]], + jin_zhangchunhua: ["female", "jin", 3, ["huishi", "qingleng", "xuanmu"], ["hiddenSkill"]], + jin_simayi: [ + "male", + "jin", + 3, + ["buchen", "smyyingshi", "xiongzhi", "xinquanbian"], + ["hiddenSkill"], + ], + jin_wangyuanji: ["female", "jin", 3, ["shiren", "yanxi"], ["hiddenSkill"]], + jin_simazhao: [ + "male", + "jin", + 3, + ["tuishi", "xinchoufa", "zhaoran", "chengwu"], + ["zhu", "hiddenSkill"], + ], + jin_xiahouhui: ["female", "jin", 3, ["baoqie", "jyishi", "shiduo"], ["hiddenSkill"]], + jin_simashi: [ + "male", + "jin", + "3/4", + ["taoyin", "yimie", "ruilve", "tairan"], + ["hiddenSkill", "zhu"], + ], + zhanghuyuechen: ["male", "jin", 4, ["xijue"]], + duyu: ["male", "jin", 4, ["sanchen", "zhaotao"]], }, - characterSort:{ - yingbian:{ - yingbian_pack1:['jin_simayi','jin_zhangchunhua','ol_lisu','simazhou','cheliji','ol_huaxin'], - yingbian_pack2:['jin_simashi','jin_xiahouhui','zhanghuyuechen','shibao','jin_yanghuiyu','chengjichengcui'], - yingbian_pack3:['jin_simazhao','jin_wangyuanji','duyu','weiguan','xuangongzhu'], - yingbian_pack4:['zhongyan','xinchang','jin_jiachong','wangxiang'], - yingbian_pack5:['yangyan','yangzhi'], + characterSort: { + yingbian: { + yingbian_pack1: [ + "jin_simayi", + "jin_zhangchunhua", + "ol_lisu", + "simazhou", + "cheliji", + "ol_huaxin", + ], + yingbian_pack2: [ + "jin_simashi", + "jin_xiahouhui", + "zhanghuyuechen", + "shibao", + "jin_yanghuiyu", + "chengjichengcui", + ], + yingbian_pack3: ["jin_simazhao", "jin_wangyuanji", "duyu", "weiguan", "xuangongzhu"], + yingbian_pack4: ["zhongyan", "xinchang", "jin_jiachong", "wangxiang"], + yingbian_pack5: ["yangyan", "yangzhi"], }, }, - skill:{ + skill: { //二成 - oltousui:{ - audio:2, - enable:'chooseToUse', - viewAsFilter:function(player){ - return player.countCards('he'); + oltousui: { + audio: 2, + enable: "chooseToUse", + viewAsFilter: function (player) { + return player.countCards("he"); }, - viewAs:{ - name:'sha', - suit:'none', - number:null, - isCard:true, + viewAs: { + name: "sha", + suit: "none", + number: null, + isCard: true, }, - filterCard:true, - selectCard:[1,Infinity], - position:'he', - check:function(card){ - const player=get.player(); - return 4.5+(player.hasSkill('olchuming')?1:0)-1.5*ui.selected.cards.length-get.value(card); + filterCard: true, + selectCard: [1, Infinity], + position: "he", + check: function (card) { + const player = get.player(); + return ( + 4.5 + + (player.hasSkill("olchuming") ? 1 : 0) - + 1.5 * ui.selected.cards.length - + get.value(card) + ); }, - popname:true, - ignoreMod:true, - precontent:function*(event,map){ - var player=map.player; - var evt=event.getParent(); - if(evt.dialog&&typeof evt.dialog=='object') evt.dialog.close(); - player.logSkill('oltousui'); + popname: true, + ignoreMod: true, + precontent: function* (event, map) { + var player = map.player; + var evt = event.getParent(); + if (evt.dialog && typeof evt.dialog == "object") evt.dialog.close(); + player.logSkill("oltousui"); delete event.result.skill; - var cards=event.result.cards; - player.loseToDiscardpile(cards,ui.cardPile,false,'blank').log=false; - var shownCards=cards.filter(i=>get.position(i)=='e'),handcardsLength=cards.length-shownCards.length; - if(shownCards.length){ - player.$throw(shownCards,null); - game.log(player,'将',shownCards,'置于了牌堆底'); + var cards = event.result.cards; + player.loseToDiscardpile(cards, ui.cardPile, false, "blank").log = false; + var shownCards = cards.filter((i) => get.position(i) == "e"), + handcardsLength = cards.length - shownCards.length; + if (shownCards.length) { + player.$throw(shownCards, null); + game.log(player, "将", shownCards, "置于了牌堆底"); } - if(handcardsLength>0){ - player.$throw(handcardsLength,null); - game.log(player,'将',get.cnNumber(handcardsLength),'张牌置于了牌堆底'); + if (handcardsLength > 0) { + player.$throw(handcardsLength, null); + game.log(player, "将", get.cnNumber(handcardsLength), "张牌置于了牌堆底"); } game.delayex(); - var viewAs=new lib.element.VCard({name:event.result.card.name,isCard:true}); - event.result.card=viewAs; - event.result.cards=[]; - event.result._apply_args={ - shanReq:cards.length, - oncard:()=>{ - var evt=get.event(); - for(var target of game.filterPlayer(null,null,true)){ - var id=target.playerid; - var map=evt.customArgs; - if(!map[id]) map[id]={}; - map[id].shanRequired=evt.shanReq; + var viewAs = new lib.element.VCard({ name: event.result.card.name, isCard: true }); + event.result.card = viewAs; + event.result.cards = []; + event.result._apply_args = { + shanReq: cards.length, + oncard: () => { + var evt = get.event(); + for (var target of game.filterPlayer(null, null, true)) { + var id = target.playerid; + var map = evt.customArgs; + if (!map[id]) map[id] = {}; + map[id].shanRequired = evt.shanReq; } - } + }, }; }, - ai:{ - order:function(item,player){ - return get.order({name:'sha'})+0.1; + ai: { + order: function (item, player) { + return get.order({ name: "sha" }) + 0.1; }, - result:{player:1}, - keepdu:true, - respondSha:true, - skillTagFilter:(player,tag,arg)=>{ - if(tag=='respondSha'&&arg!='use') return false; + result: { player: 1 }, + keepdu: true, + respondSha: true, + skillTagFilter: (player, tag, arg) => { + if (tag == "respondSha" && arg != "use") return false; }, }, }, - olchuming:{ - audio:2, - trigger:{ - source:'damageBegin1', - player:'damageBegin3', + olchuming: { + audio: 2, + trigger: { + source: "damageBegin1", + player: "damageBegin3", }, - filter:function(event,player){ - if(event.source===event.player) return false; - if(!event.card||!event.cards||!event.cards.length) return true; - let target=event[player===event.source?'player':'source']; - return target&&target.isIn(); + filter: function (event, player) { + if (event.source === event.player) return false; + if (!event.card || !event.cards || !event.cards.length) return true; + let target = event[player === event.source ? "player" : "source"]; + return target && target.isIn(); }, - forced:true, - content:function*(event,map){ - var player=map.player,trigger=map.trigger; - if(!trigger.card||!trigger.cards||!trigger.cards.length){ + forced: true, + content: function* (event, map) { + var player = map.player, + trigger = map.trigger; + if (!trigger.card || !trigger.cards || !trigger.cards.length) { trigger.num++; event.finish(); return; - } - else{ - var target=trigger[trigger.source==player?'player':'source']; - trigger._olchuming=true; - target.addTempSkill('olchuming_effect'); + } else { + var target = trigger[trigger.source == player ? "player" : "source"]; + trigger._olchuming = true; + target.addTempSkill("olchuming_effect"); } }, - ai:{ - effect:{ - player:function(card,player,target){ - if(!get.tag(card,'damage')) return; - if(!lib.card[card.name]||!card.cards||!card.cards.length) return [1,0,1,-1]; - return [1,-1]; + ai: { + effect: { + player: function (card, player, target) { + if (!get.tag(card, "damage")) return; + if (!lib.card[card.name] || !card.cards || !card.cards.length) + return [1, 0, 1, -1]; + return [1, -1]; }, }, }, - subSkill:{ - effect:{ - charlotte:true, - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - content:function*(event,map){ - var player=map.player; - var mapx={}; - var history=player.getHistory('damage').concat(player.getHistory('sourceDamage')); - history.forEach(evt=>{ - if(!evt._olchuming) return; - var target=evt[evt.source==player?'player':'source']; - if(!target.isIn()) return; - var cards=evt.cards.filterInD('d'); - if(!cards.length) return; - if(!mapx[target.playerid]) mapx[target.playerid]=[]; + subSkill: { + effect: { + charlotte: true, + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + content: function* (event, map) { + var player = map.player; + var mapx = {}; + var history = player + .getHistory("damage") + .concat(player.getHistory("sourceDamage")); + history.forEach((evt) => { + if (!evt._olchuming) return; + var target = evt[evt.source == player ? "player" : "source"]; + if (!target.isIn()) return; + var cards = evt.cards.filterInD("d"); + if (!cards.length) return; + if (!mapx[target.playerid]) mapx[target.playerid] = []; mapx[target.playerid].addArray(cards); }); - var entries=Object.entries(mapx).map(entry=>{ - return [(_status.connectMode?lib.playerOL:game.playerMap)[entry[0]],entry[1]]; + var entries = Object.entries(mapx).map((entry) => { + return [ + (_status.connectMode ? lib.playerOL : game.playerMap)[entry[0]], + entry[1], + ]; }); - if(!entries.length){ + if (!entries.length) { event.finish(); return; } - player.logSkill('olchuming_effect',entries.map(i=>i[0])); - entries.sort((a,b)=>lib.sort.seat(a[0],b[0])); - for(var entry of entries){ - var current=entry[0],cards=entry[1]; - var list=['jiedao','guohe'].filter(i=>player.canUse(new lib.element.VCard({name:i,cards:cards}),current,false)); - if(!list.length) return; - var result=({}); - if(list.length==1) result={bool:true,links:[['','',list[0]]]}; - else result=yield player.chooseButton([`畜鸣:请选择要对${get.translation(current)}使用的牌`,[list,'vcard']],true).set('ai',button=>{ - var player=get.player(); - return get.effect(get.event('currentTarget'),{name:button.link[2]},player,player); - }).set('currentTarget',current); - if(result.bool){ - var card=get.autoViewAs({name:result.links[0][2]},cards); - if(player.canUse(card,current,false)) player.useCard(card,cards,current,false); + player.logSkill( + "olchuming_effect", + entries.map((i) => i[0]) + ); + entries.sort((a, b) => lib.sort.seat(a[0], b[0])); + for (var entry of entries) { + var current = entry[0], + cards = entry[1]; + var list = ["jiedao", "guohe"].filter((i) => + player.canUse( + new lib.element.VCard({ name: i, cards: cards }), + current, + false + ) + ); + if (!list.length) return; + var result = {}; + if (list.length == 1) result = { bool: true, links: [["", "", list[0]]] }; + else + result = yield player + .chooseButton( + [ + `畜鸣:请选择要对${get.translation(current)}使用的牌`, + [list, "vcard"], + ], + true + ) + .set("ai", (button) => { + var player = get.player(); + return get.effect( + get.event("currentTarget"), + { name: button.link[2] }, + player, + player + ); + }) + .set("currentTarget", current); + if (result.bool) { + var card = get.autoViewAs({ name: result.links[0][2] }, cards); + if (player.canUse(card, current, false)) + player.useCard(card, cards, current, false); } } - } - } - } - }, - bingxin:{ - audio:2, - enable:'chooseToUse', - hiddenCard:function(player,name){ - if(get.type(name)=='basic'&&lib.inpile.includes(name)&&!player.getStorage('bingxin_count').includes(name)) return true; + }, + }, }, - filter:function(event,player){ - if(event.type=='wuxie') return false; - var hs=player.getCards('h'); - if(hs.length!=Math.max(0,player.hp)) return false; - if(hs.length>1){ - var color=get.color(hs[0],player); - for(var i=1;i 1) { + var color = get.color(hs[0], player); + for (var i = 1; i < hs.length; i++) { + if (get.color(hs[i], player) != color) return false; } } - var storage=player.storage.bingxin_count - for(var i of lib.inpile){ - if(get.type(i)!='basic') continue; - if(storage&&storage.includes(i)) continue; - var card={name:i,isCard:true}; - if(event.filterCard(card,player,event)) return true; - if(i=='sha'){ - for(var j of lib.inpile_nature){ - card.nature=j; - if(event.filterCard(card,player,event)) return true; + var storage = player.storage.bingxin_count; + for (var i of lib.inpile) { + if (get.type(i) != "basic") continue; + if (storage && storage.includes(i)) continue; + var card = { name: i, isCard: true }; + if (event.filterCard(card, player, event)) return true; + if (i == "sha") { + for (var j of lib.inpile_nature) { + card.nature = j; + if (event.filterCard(card, player, event)) return true; } } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - var storage=player.storage.bingxin_count; - for(var i of lib.inpile){ - if(get.type(i)!='basic') continue; - if(storage&&storage.includes(i)) continue; - var card={name:i,isCard:true}; - if(event.filterCard(card,player,event)) list.push(['基本','',i]); - if(i=='sha'){ - for(var j of lib.inpile_nature){ - card.nature=j; - if(event.filterCard(card,player,event)) list.push(['基本','',i,j]); + chooseButton: { + dialog: function (event, player) { + var list = []; + var storage = player.storage.bingxin_count; + for (var i of lib.inpile) { + if (get.type(i) != "basic") continue; + if (storage && storage.includes(i)) continue; + var card = { name: i, isCard: true }; + if (event.filterCard(card, player, event)) list.push(["基本", "", i]); + if (i == "sha") { + for (var j of lib.inpile_nature) { + card.nature = j; + if (event.filterCard(card, player, event)) list.push(["基本", "", i, j]); } } } - return ui.create.dialog('冰心',[list,'vcard'],'hidden') + return ui.create.dialog("冰心", [list, "vcard"], "hidden"); }, - check:function(button){ - if(button.link[2]=='shan') return 3; - var player=_status.event.player; - if(button.link[2]=='jiu'){ - if(player.getUseValue({name:'jiu'})<=0) return 0; - if(player.countCards('h','sha')) return player.getUseValue({name:'jiu'}); + check: function (button) { + if (button.link[2] == "shan") return 3; + var player = _status.event.player; + if (button.link[2] == "jiu") { + if (player.getUseValue({ name: "jiu" }) <= 0) return 0; + if (player.countCards("h", "sha")) return player.getUseValue({ name: "jiu" }); return 0; } - return player.getUseValue({name:button.link[2],nature:button.link[3]})/4; + return player.getUseValue({ name: button.link[2], nature: button.link[3] }) / 4; }, - backup:function(links,player){ + backup: function (links, player) { return { - selectCard:-1, - filterCard:()=>false, - viewAs:{ - name:links[0][2], - nature:links[0][3], - isCard:true, + selectCard: -1, + filterCard: () => false, + viewAs: { + name: links[0][2], + nature: links[0][3], + isCard: true, }, - precontent:function(){ - player.logSkill('bingxin'); + precontent: function () { + player.logSkill("bingxin"); player.draw(); delete event.result.skill; - var name=event.result.card.name; - player.addTempSkill('bingxin_count'); - player.markAuto('bingxin_count',[name]); + var name = event.result.card.name; + player.addTempSkill("bingxin_count"); + player.markAuto("bingxin_count", [name]); }, - } + }; }, - prompt:function(links,player){ - var name=links[0][2]; - var nature=links[0][3]; - return '摸一张并视为使用'+(get.translation(nature)||'')+get.translation(name); + prompt: function (links, player) { + var name = links[0][2]; + var nature = links[0][3]; + return "摸一张并视为使用" + (get.translation(nature) || "") + get.translation(name); }, }, - ai:{ - order:10, - respondShan:true, - respondSha:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond') return false; - var hs=player.getCards('h'); - if(hs.length!=Math.max(0,hs.length)) return false; - if(hs.length>1){ - var color=get.color(hs[0],player); - for(var i=1;i 1) { + var color = get.color(hs[0], player); + for (var i = 1; i < hs.length; i++) { + if (get.color(hs[i], player) != color) return false; } } - var storage=player.storage.bingxin_count; - if(storage&&storage.includes('s'+tag.slice(8))) return false; + var storage = player.storage.bingxin_count; + if (storage && storage.includes("s" + tag.slice(8))) return false; }, - result:{ - player:function(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player: function (player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; - } - } + }, + }, }, - subSkill:{count:{charlotte:true,onremove:true}}, + subSkill: { count: { charlotte: true, onremove: true } }, }, - zhefu:{ - audio:2, - trigger:{player:['useCard','respond']}, - direct:true, - filter:function(event,player){ - return player!=_status.currentPhase&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + zhefu: { + audio: 2, + trigger: { player: ["useCard", "respond"] }, + direct: true, + filter: function (event, player) { + return ( + player != _status.currentPhase && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('zhefu'),'令一名有手牌的其他角色弃置一张【'+get.translation(trigger.card.name)+'】,否则受到你造成的1点伤害。',function(card,player,target){ - return target!=player&&target.countCards('h')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player)/Math.sqrt(target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('zhefu',target); - var name=trigger.card.name; - target.chooseToDiscard('he',{name:name},'弃置一张【'+get.translation(name)+'】或受到1点伤害').set('ai',function(card){ - var player=_status.event.player; - if(_status.event.take||(get.name(card)=='tao'&&!player.hasJudge('lebu'))) return 0; - return 8-get.value(card); - }).set('take',get.damageEffect(target,player,target)>=0); - } - else event.finish(); - 'step 2' - if(!result.bool) target.damage(); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("zhefu"), + "令一名有手牌的其他角色弃置一张【" + + get.translation(trigger.card.name) + + "】,否则受到你造成的1点伤害。", + function (card, player, target) { + return target != player && target.countCards("h") > 0; + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.damageEffect(target, player, player) / Math.sqrt(target.countCards("h")) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("zhefu", target); + var name = trigger.card.name; + target + .chooseToDiscard( + "he", + { name: name }, + "弃置一张【" + get.translation(name) + "】或受到1点伤害" + ) + .set("ai", function (card) { + var player = _status.event.player; + if ( + _status.event.take || + (get.name(card) == "tao" && !player.hasJudge("lebu")) + ) + return 0; + return 8 - get.value(card); + }) + .set("take", get.damageEffect(target, player, target) >= 0); + } else event.finish(); + "step 2"; + if (!result.bool) target.damage(); }, }, - yidu:{ - audio:2, - trigger:{player:'useCardAfter'}, - filter:function(event,player){ - return (event.card.name=='sha'||(get.type(event.card,null,false)=='trick'&&get.tag(event.card,'damage')>0)) - &&event.targets.some(target=>{ - return target.countCards('h')>0&&!target.hasHistory('damage',function(evt){ - return evt.card==event.card; + yidu: { + audio: 2, + trigger: { player: "useCardAfter" }, + filter: function (event, player) { + return ( + (event.card.name == "sha" || + (get.type(event.card, null, false) == "trick" && + get.tag(event.card, "damage") > 0)) && + event.targets.some((target) => { + return ( + target.countCards("h") > 0 && + !target.hasHistory("damage", function (evt) { + return evt.card == event.card; + }) + ); + }) + ); + }, + direct: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("yidu"), (card, player, target) => { + return _status.event.targets.includes(target); + }) + .set( + "targets", + trigger.targets.filter((target) => { + return ( + target.countCards("h") > 0 && + !target.hasHistory("damage", function (evt) { + return evt.card == trigger.card; + }) + ); + }) + ) + .set("ai", (target) => { + if (target.hasSkillTag("noh")) return 0; + return -get.attitude(player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("yidu", target); + player + .choosePlayerCard( + target, + "遗毒:展示" + get.translation(target) + "的至多三张手牌", + true, + "h", + [1, Math.min(3, target.countCards("h"))] + ) + .set("forceAuto", true) + .set("ai", function (button) { + if (ui.selected.buttons.length) return 0; + return 1 + Math.random(); }); - }); - }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('yidu'),(card,player,target)=>{ - return _status.event.targets.includes(target); - }).set('targets',trigger.targets.filter(target=>{ - return target.countCards('h')>0&&!target.hasHistory('damage',function(evt){ - return evt.card==trigger.card; - }); - })).set('ai',target=>{ - if(target.hasSkillTag('noh')) return 0; - return -get.attitude(player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('yidu',target); - player.choosePlayerCard(target,'遗毒:展示'+get.translation(target)+'的至多三张手牌',true,'h',[1,Math.min(3,target.countCards('h'))]).set('forceAuto',true).set('ai',function(button){ - if(ui.selected.buttons.length) return 0; - return 1+Math.random(); - }); - } - else event.finish(); - 'step 2' - var cards=result.cards; - player.showCards(cards,get.translation(player)+'对'+get.translation(target)+'发动了【遗毒】'); - var color=get.color(cards[0],target); - var bool=true; - for(var i=1;i0; + xinwanyi: { + audio: "wanyi", + trigger: { player: "useCardToTargeted" }, + filter: function (event, player) { + return ( + player != event.target && + event.targets.length == 1 && + (event.card.name == "sha" || get.type(event.card, false) == "trick") && + event.target.countCards("he") > 0 + ); }, - locked:false, - logTarget:'target', - check:function(event,player){ - return get.effect(event.target,{name:'guohe_copy2'},player,player)>0; + locked: false, + logTarget: "target", + check: function (event, player) { + return get.effect(event.target, { name: "guohe_copy2" }, player, player) > 0; }, - prompt2:'将该角色的一张牌置于武将牌上作为“嫕”', - content:function(){ - 'step 0' - event.target=trigger.target; - player.choosePlayerCard(event.target,true,'he'); - 'step 1' - if(result.bool){ - var cards=result.cards; - player.addToExpansion(cards,target,'give').gaintag.add('xinwanyi'); + prompt2: "将该角色的一张牌置于武将牌上作为“嫕”", + content: function () { + "step 0"; + event.target = trigger.target; + player.choosePlayerCard(event.target, true, "he"); + "step 1"; + if (result.bool) { + var cards = result.cards; + player.addToExpansion(cards, target, "give").gaintag.add("xinwanyi"); } }, - mod:{ - cardEnabled:function(card,player){ - var cards=player.getExpansions('xinwanyi'); - if(cards.length){ - var suit=get.suit(card); - if(suit=='none') return; - for(var i of cards){ - if(get.suit(i,player)==suit) return false; + mod: { + cardEnabled: function (card, player) { + var cards = player.getExpansions("xinwanyi"); + if (cards.length) { + var suit = get.suit(card); + if (suit == "none") return; + for (var i of cards) { + if (get.suit(i, player) == suit) return false; } } }, - cardRespondable:function(card,player){ - var cards=player.getExpansions('xinwanyi'); - if(cards.length){ - var suit=get.suit(card); - if(suit=='none') return; - for(var i of cards){ - if(get.suit(i,player)==suit) return false; + cardRespondable: function (card, player) { + var cards = player.getExpansions("xinwanyi"); + if (cards.length) { + var suit = get.suit(card); + if (suit == "none") return; + for (var i of cards) { + if (get.suit(i, player) == suit) return false; } } }, - cardSavable:function(card,player){ - var cards=player.getExpansions('xinwanyi'); - if(cards.length){ - var suit=get.suit(card); - if(suit=='none') return; - for(var i of cards){ - if(get.suit(i,player)==suit) return false; + cardSavable: function (card, player) { + var cards = player.getExpansions("xinwanyi"); + if (cards.length) { + var suit = get.suit(card); + if (suit == "none") return; + for (var i of cards) { + if (get.suit(i, player) == suit) return false; } } }, - cardDiscardable:function(card,player){ - var cards=player.getExpansions('xinwanyi'); - if(cards.length){ - var suit=get.suit(card); - if(suit=='none') return; - for(var i of cards){ - if(get.suit(i,player)==suit) return false; + cardDiscardable: function (card, player) { + var cards = player.getExpansions("xinwanyi"); + if (cards.length) { + var suit = get.suit(card); + if (suit == "none") return; + for (var i of cards) { + if (get.suit(i, player) == suit) return false; } } }, }, - marktext:'嫕', - intro:{ - markcount:'expansion', - content:'expansion', + marktext: "嫕", + intro: { + markcount: "expansion", + content: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - group:'xinwanyi_give', - subSkill:{ - give:{ - audio:'wanyi', - trigger:{player:['phaseJieshuBegin','damageEnd']}, - forced:true, - locked:false, - filter:function(event,player){ - return player.getExpansions('xinwanyi').length>0; + group: "xinwanyi_give", + subSkill: { + give: { + audio: "wanyi", + trigger: { player: ["phaseJieshuBegin", "damageEnd"] }, + forced: true, + locked: false, + filter: function (event, player) { + return player.getExpansions("xinwanyi").length > 0; }, - content:function(){ - 'step 0' - player.chooseTarget(true,'婉嫕:令一名角色获得一张“嫕”').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var cards=player.getExpansions('xinwanyi'); - if(cards.length==1) event._result={bool:true,links:cards}; - else player.chooseButton(['令'+get.translation(target)+'获得一张“嫕”',cards],true); - } - else event.finish(); - 'step 2' - if(result.bool){ - target.gain(result.links,player,'give'); + content: function () { + "step 0"; + player + .chooseTarget(true, "婉嫕:令一名角色获得一张“嫕”") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var cards = player.getExpansions("xinwanyi"); + if (cards.length == 1) event._result = { bool: true, links: cards }; + else + player.chooseButton( + ["令" + get.translation(target) + "获得一张“嫕”", cards], + true + ); + } else event.finish(); + "step 2"; + if (result.bool) { + target.gain(result.links, player, "give"); } }, }, }, }, - xinxuanbei:{ - audio:'xuanbei', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((current)=>lib.skill.xinxuanbei.filterTarget(null,player,current)); + xinxuanbei: { + audio: "xuanbei", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((current) => + lib.skill.xinxuanbei.filterTarget(null, player, current) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('hej')>0; + filterTarget: function (card, player, target) { + return target != player && target.countCards("hej") > 0; }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'hej',true); - 'step 1' - if(result.bool){ - var card=result.cards[0]; - var cardx=get.autoViewAs({name:'sha'},[card]); - if((get.position(card)!='j'&&!game.checkMod(card,target,'unchanged','cardEnabled2',target))||!target.canUse(cardx,player,false)) event.finish(); - else{ - var next=target.useCard(cardx,[card],player,false); - event.card=next.card; + content: function () { + "step 0"; + player.choosePlayerCard(target, "hej", true); + "step 1"; + if (result.bool) { + var card = result.cards[0]; + var cardx = get.autoViewAs({ name: "sha" }, [card]); + if ( + (get.position(card) != "j" && + !game.checkMod(card, target, "unchanged", "cardEnabled2", target)) || + !target.canUse(cardx, player, false) + ) + event.finish(); + else { + var next = target.useCard(cardx, [card], player, false); + event.card = next.card; } - } - else event.finish(); - 'step 2' - var num=1; - if(player.hasHistory('damage',function(evt){ - return evt.card==event.card; - })) num++; + } else event.finish(); + "step 2"; + var num = 1; + if ( + player.hasHistory("damage", function (evt) { + return evt.card == event.card; + }) + ) + num++; player.draw(num); }, - ai:{ - order:7, - result:{ - player:function(player,target){ - return get.effect(target,{name:'guohe_copy'},player,player)+get.effect(player,{name:'sha'},target,player) + ai: { + order: 7, + result: { + player: function (player, target) { + return ( + get.effect(target, { name: "guohe_copy" }, player, player) + + get.effect(player, { name: "sha" }, target, player) + ); }, }, }, }, - xiongshu:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player!=event.player&&event.player.countCards('h')>0&&player.countCards('he')>=player.countMark('xiongshu_count'); + xiongshu: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.countCards("h") > 0 && + player.countCards("he") >= player.countMark("xiongshu_count") + ); }, - content:function(){ - 'step 0' - event.target=trigger.player; - var num=player.countMark('xiongshu_count'); - if(num>0) player.chooseToDiscard('he',num,get.prompt('xiongshu',trigger.player),'弃置'+get.cnNumber(num)+'张牌并展示其一张手牌').set('goon',get.attitude(player,event.target)<0).set('ai',function(card){ - if(!_status.event.goon) return 0; - return 6-_status.event.player.countMark('xiongshu_count')-get.value(card); - }).logSkill=['xiongshu',trigger.player]; - else player.chooseBool(get.prompt('xiongshu',trigger.player),'展示其一张牌').set('goon',get.attitude(player,event.target)<0).set('ai',function(card){ - return _status.event.goon; - }) - 'step 1' - if(result.bool){ - if(!result.cards||!result.cards.length) player.logSkill('xiongshu',target); - player.addTempSkill('xiongshu_count','roundStart'); - player.addMark('xiongshu_count',1,false); + content: function () { + "step 0"; + event.target = trigger.player; + var num = player.countMark("xiongshu_count"); + if (num > 0) + player + .chooseToDiscard( + "he", + num, + get.prompt("xiongshu", trigger.player), + "弃置" + get.cnNumber(num) + "张牌并展示其一张手牌" + ) + .set("goon", get.attitude(player, event.target) < 0) + .set("ai", function (card) { + if (!_status.event.goon) return 0; + return 6 - _status.event.player.countMark("xiongshu_count") - get.value(card); + }).logSkill = ["xiongshu", trigger.player]; + else + player + .chooseBool(get.prompt("xiongshu", trigger.player), "展示其一张牌") + .set("goon", get.attitude(player, event.target) < 0) + .set("ai", function (card) { + return _status.event.goon; + }); + "step 1"; + if (result.bool) { + if (!result.cards || !result.cards.length) player.logSkill("xiongshu", target); + player.addTempSkill("xiongshu_count", "roundStart"); + player.addMark("xiongshu_count", 1, false); } - if(result.bool&&target.countCards('h')>0){ - player.choosePlayerCard(target,true,'h'); + if (result.bool && target.countCards("h") > 0) { + player.choosePlayerCard(target, true, "h"); + } else event.finish(); + "step 2"; + var card = result.cards[0], + name = get.name(card), + str = get.translation(target); + player.showCards(card, get.translation(player) + "对" + str + "发动了【凶竖】"); + player.addTempSkill("xiongshu_effect", "phaseUseAfter"); + player.storage.xiongshu_effect = [card, name]; + if (Math.random() < 0.5) { + target.storage.xiongshu_ai = name; + target.addTempSkill("xiongshu_ai", "phaseUseAfter"); } - else event.finish(); - 'step 2' - var card=result.cards[0],name=get.name(card),str=get.translation(target); - player.showCards(card,get.translation(player)+'对'+str+'发动了【凶竖】'); - player.addTempSkill('xiongshu_effect','phaseUseAfter'); - player.storage.xiongshu_effect=[card,name]; - if(Math.random()<0.5){ - target.storage.xiongshu_ai=name; - target.addTempSkill('xiongshu_ai','phaseUseAfter'); - } - player.chooseControl('会使用','不会使用').set('prompt','预测:'+str+'是否会使用'+get.translation(name)+'?').set('choice',function(){ - if(!target.hasValueTarget(card)) return 1; - return Math.random()<0.5?0:1; - }()).set('ai',()=>_status.event.choice); - 'step 3' - player.storage.xiongshu_effect[2]=(result.index==0); + player + .chooseControl("会使用", "不会使用") + .set("prompt", "预测:" + str + "是否会使用" + get.translation(name) + "?") + .set( + "choice", + (function () { + if (!target.hasValueTarget(card)) return 1; + return Math.random() < 0.5 ? 0 : 1; + })() + ) + .set("ai", () => _status.event.choice); + "step 3"; + player.storage.xiongshu_effect[2] = result.index == 0; }, - ai:{expose:0.35}, - subSkill:{ - ai:{ - charlotte:true, - onremove:true, - ai:{ - effect:{ - player:function(card,player,target){ - if(card.name==player.storage.xiongshu_ai) return 'zeroplayertarget'; + ai: { expose: 0.35 }, + subSkill: { + ai: { + charlotte: true, + onremove: true, + ai: { + effect: { + player: function (card, player, target) { + if (card.name == player.storage.xiongshu_ai) return "zeroplayertarget"; }, }, }, }, - count:{ - charlotte:true, - onremove:true, + count: { + charlotte: true, + onremove: true, }, - effect:{ - trigger:{global:'phaseUseEnd'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - var info=player.storage.xiongshu_effect; - return Array.isArray(info)&&event.player.isIn(); + effect: { + trigger: { global: "phaseUseEnd" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + var info = player.storage.xiongshu_effect; + return Array.isArray(info) && event.player.isIn(); }, - logTarget:'player', - content:function(){ - var target=trigger.player; - var info=player.storage.xiongshu_effect; - var card=info[0]; - if(target.hasHistory('useCard',function(evt){ - return evt.card.name==info[1]&&evt.getParent('phaseUse')==trigger; - })==info[2]) target.damage(); - else{ - if(target.getCards('hej').includes(card)) player.gain(card,target,'give'); - else if(get.position(card,true)=='d') player.gain(card,'gain2'); + logTarget: "player", + content: function () { + var target = trigger.player; + var info = player.storage.xiongshu_effect; + var card = info[0]; + if ( + target.hasHistory("useCard", function (evt) { + return evt.card.name == info[1] && evt.getParent("phaseUse") == trigger; + }) == info[2] + ) + target.damage(); + else { + if (target.getCards("hej").includes(card)) player.gain(card, target, "give"); + else if (get.position(card, true) == "d") player.gain(card, "gain2"); } }, }, }, }, - jianhui:{ - audio:2, - getLastPlayer:function(evt,player){ - var history=player.getAllHistory('damage'); - if(!history.length) return null; - var i=history.indexOf(evt); - if(i==-1) i=history.length-1; + jianhui: { + audio: 2, + getLastPlayer: function (evt, player) { + var history = player.getAllHistory("damage"); + if (!history.length) return null; + var i = history.indexOf(evt); + if (i == -1) i = history.length - 1; else i--; - for(i;i>=0;i--){ - if(history[i].source) return history[i].source; + for (i; i >= 0; i--) { + if (history[i].source) return history[i].source; } return null; }, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source==lib.skill.jianhui.getLastPlayer(event,player)&&event.source.countCards('he')>0; + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.source == lib.skill.jianhui.getLastPlayer(event, player) && + event.source.countCards("he") > 0 + ); }, - content:function(){ - trigger.source.chooseToDiscard('he',true); + content: function () { + trigger.source.chooseToDiscard("he", true); }, - group:'jianhui_draw', - subSkill:{ - draw:{ - trigger:{source:'damageSource'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return event.player==lib.skill.jianhui.getLastPlayer(event,player); + group: "jianhui_draw", + subSkill: { + draw: { + trigger: { source: "damageSource" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return event.player == lib.skill.jianhui.getLastPlayer(event, player); }, - content:function(){ + content: function () { player.draw(); }, }, }, }, - huaiyuan:{ - audio:2, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + huaiyuan: { + audio: 2, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.length) return false; - if(event.name=='lose'){ - for(var i in event.gaintag_map){ - if(event.gaintag_map[i].includes('huaiyuanx')) return true; + filter: function (event, player) { + var evt = event.getl(player); + if (!evt || !evt.hs || !evt.hs.length) return false; + if (event.name == "lose") { + for (var i in event.gaintag_map) { + if (event.gaintag_map[i].includes("huaiyuanx")) return true; } return false; } - return player.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('huaiyuanx')) return true; + return player.hasHistory("lose", function (evt) { + if (event != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("huaiyuanx")) return true; } return false; }); }, - forced:true, - locked:false, - content:function(){ - 'step 0' - var num=0; - if(trigger.name=='lose'){ - for(var i in trigger.gaintag_map){ - if(trigger.gaintag_map[i].includes('huaiyuanx')) num++; + forced: true, + locked: false, + content: function () { + "step 0"; + var num = 0; + if (trigger.name == "lose") { + for (var i in trigger.gaintag_map) { + if (trigger.gaintag_map[i].includes("huaiyuanx")) num++; } - } - else player.getHistory('lose',function(evt){ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('huaiyuanx')) num++; - } - return false; - }); - event.count=num; - 'step 1' - event.count--; - player.chooseTarget(true,'请选择【怀远】的目标','令一名角色执行一项:⒈其的手牌上限+1。⒉其的攻击范围+1。⒊其摸一张牌。').set('ai',function(target){ - var player=_status.event.player,att=get.attitude(player,target); - if(att<=0) return 0; - if(target.hasValueTarget({name:'sha'},false)&&!target.hasValueTarget({name:'sha'})) att*=2.2; - if(target.needsToDiscard()) att*=1.3; - return att*Math.sqrt(Math.max(1,4-target.countCards('h'))); - }); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.line(target,'green'); - var str=get.translation(target) - player.chooseControl().set('choiceList',[ - '令'+str+'的手牌上限+1', - '令'+str+'的攻击范围+1', - '令'+str+'摸一张牌', - ]).set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target;if(target.hasValueTarget({name:'sha'},false)&&!target.hasValueTarget({name:'sha'})) return 1; - if(target.needsToDiscard()) return 0; - return 2; + } else + player.getHistory("lose", function (evt) { + if (trigger != evt.getParent()) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("huaiyuanx")) num++; + } + return false; }); - } - else event.finish(); - 'step 3' - if(result.index==2) target.draw(); - else{ - target.addSkill('huaiyuan_effect'+result.index); - target.addMark('huaiyuan_effect'+result.index,1,false); - game.log(target,'的','#g'+['手牌上限','攻击范围'][result.index],'+1') + event.count = num; + "step 1"; + event.count--; + player + .chooseTarget( + true, + "请选择【怀远】的目标", + "令一名角色执行一项:⒈其的手牌上限+1。⒉其的攻击范围+1。⒊其摸一张牌。" + ) + .set("ai", function (target) { + var player = _status.event.player, + att = get.attitude(player, target); + if (att <= 0) return 0; + if ( + target.hasValueTarget({ name: "sha" }, false) && + !target.hasValueTarget({ name: "sha" }) + ) + att *= 2.2; + if (target.needsToDiscard()) att *= 1.3; + return att * Math.sqrt(Math.max(1, 4 - target.countCards("h"))); + }); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.line(target, "green"); + var str = get.translation(target); + player + .chooseControl() + .set("choiceList", [ + "令" + str + "的手牌上限+1", + "令" + str + "的攻击范围+1", + "令" + str + "摸一张牌", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + if ( + target.hasValueTarget({ name: "sha" }, false) && + !target.hasValueTarget({ name: "sha" }) + ) + return 1; + if (target.needsToDiscard()) return 0; + return 2; + }); + } else event.finish(); + "step 3"; + if (result.index == 2) target.draw(); + else { + target.addSkill("huaiyuan_effect" + result.index); + target.addMark("huaiyuan_effect" + result.index, 1, false); + game.log(target, "的", "#g" + ["手牌上限", "攻击范围"][result.index], "+1"); game.delayx(); } - if(event.count>0) event.goto(1); + if (event.count > 0) event.goto(1); }, - group:['huaiyuan_init','huaiyuan_die'], - subSkill:{ - init:{ - audio:'huaiyuan', - trigger:{ - global:'phaseBefore', - player:'enterGame', + group: ["huaiyuan_init", "huaiyuan_die"], + subSkill: { + init: { + audio: "huaiyuan", + trigger: { + global: "phaseBefore", + player: "enterGame", }, - forced:true, - locked:false, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0)&&player.countCards('h')>0; + forced: true, + locked: false, + filter: function (event, player) { + return ( + (event.name != "phase" || game.phaseNumber == 0) && player.countCards("h") > 0 + ); }, - content:function(){ - var hs=player.getCards('h'); - if(hs.length) player.addGaintag(hs,'huaiyuanx'); + content: function () { + var hs = player.getCards("h"); + if (hs.length) player.addGaintag(hs, "huaiyuanx"); }, }, - die:{ - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'water', - filter:function(event,player){ - return player.hasMark('huaiyuan_effect0')||player.hasMark('huaiyuan_effect1'); + die: { + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "water", + filter: function (event, player) { + return player.hasMark("huaiyuan_effect0") || player.hasMark("huaiyuan_effect1"); }, - content:function(){ - 'step 0' - var str='令一名其他角色',num1=player.countMark('huaiyuan_effect0'),num2=player.countMark('huaiyuan_effect1'); - if(num1>0){ - str+='手牌上限+'; - str+=num1; - if(num2>0) str+='且'; + content: function () { + "step 0"; + var str = "令一名其他角色", + num1 = player.countMark("huaiyuan_effect0"), + num2 = player.countMark("huaiyuan_effect1"); + if (num1 > 0) { + str += "手牌上限+"; + str += num1; + if (num2 > 0) str += "且"; } - if(num2>0){ - str+='攻击范围+'; - str+=num2; + if (num2 > 0) { + str += "攻击范围+"; + str += num2; } - player.chooseTarget(lib.filter.notMe,get.prompt('huaiyuan'),str).set('forceDie',true).set('ai',function(target){ - return get.attitude(_status.event.player,target)+114514; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('huaiyuan_die',target); - var num1=player.countMark('huaiyuan_effect0'),num2=player.countMark('huaiyuan_effect1'); - if(num1>0){ - target.addSkill('huaiyuan_effect0'); - target.addMark('huaiyuan_effect0',num1,false); + player + .chooseTarget(lib.filter.notMe, get.prompt("huaiyuan"), str) + .set("forceDie", true) + .set("ai", function (target) { + return get.attitude(_status.event.player, target) + 114514; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("huaiyuan_die", target); + var num1 = player.countMark("huaiyuan_effect0"), + num2 = player.countMark("huaiyuan_effect1"); + if (num1 > 0) { + target.addSkill("huaiyuan_effect0"); + target.addMark("huaiyuan_effect0", num1, false); } - if(num2>0){ - target.addSkill('huaiyuan_effect1'); - target.addMark('huaiyuan_effect1',num2,false); + if (num2 > 0) { + target.addSkill("huaiyuan_effect1"); + target.addMark("huaiyuan_effect1", num2, false); } game.delayx(); } }, }, - effect0:{ - charlotte:true, - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('huaiyuan_effect0'); + effect0: { + charlotte: true, + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("huaiyuan_effect0"); }, }, - marktext:'怀', - intro:{content:'手牌上限+#'}, + marktext: "怀", + intro: { content: "手牌上限+#" }, }, - effect1:{ - charlotte:true, - onremove:true, - mod:{ - attackRange:function(player,num){ - return num+player.countMark('huaiyuan_effect1'); + effect1: { + charlotte: true, + onremove: true, + mod: { + attackRange: function (player, num) { + return num + player.countMark("huaiyuan_effect1"); }, }, - marktext:'远', - intro:{content:'攻击范围+#'}, + marktext: "远", + intro: { content: "攻击范围+#" }, }, }, }, - chongxin:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; - }); + chongxin: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; + }) + ); }, - filterCard:true, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + filterCard: true, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - discard:false, - lose:false, - delay:false, - position:'he', - content:function(){ - 'step 0' + discard: false, + lose: false, + delay: false, + position: "he", + content: function () { + "step 0"; player.recast(cards); - 'step 1' - if(target.countCards('he')>0){ - target.chooseCard('he',true,'请重铸一张牌',lib.filter.cardRecastable); - } - else event.finish(); - 'step 2' - if(result.bool){ + "step 1"; + if (target.countCards("he") > 0) { + target.chooseCard("he", true, "请重铸一张牌", lib.filter.cardRecastable); + } else event.finish(); + "step 2"; + if (result.bool) { target.recast(result.cards); } }, - ai:{ - order:6, - result:{ - player:1, - target:function(player,target){ - return 0.5*Math.sqrt(Math.min(3,target.countCards('h'))); + ai: { + order: 6, + result: { + player: 1, + target: function (player, target) { + return 0.5 * Math.sqrt(Math.min(3, target.countCards("h"))); }, }, }, }, - dezhang:{ - trigger:{player:'phaseZhunbeiBegin'}, - derivation:'weishu', - juexingji:true, - forced:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return !player.hasCard(function(card){ - return card.hasGaintag('huaiyuanx'); - },'h'); + dezhang: { + trigger: { player: "phaseZhunbeiBegin" }, + derivation: "weishu", + juexingji: true, + forced: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return !player.hasCard(function (card) { + return card.hasGaintag("huaiyuanx"); + }, "h"); }, - content:function(){ - player.awakenSkill('dezhang'); + content: function () { + player.awakenSkill("dezhang"); player.loseMaxHp(); - player.addSkills('weishu'); + player.addSkills("weishu"); }, }, - weishu:{ - audio:2, - trigger:{player:'gainAfter'}, - forced:true, - filter:function(event,player){ - return event.getParent().name=='draw'&&event.getParent(2).name!='weishu'&&event.getParent('phaseDraw').player!=player; + weishu: { + audio: 2, + trigger: { player: "gainAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.getParent().name == "draw" && + event.getParent(2).name != "weishu" && + event.getParent("phaseDraw").player != player + ); }, - content:function(){ - 'step 0' - player.chooseTarget(true,'请选择【卫戍】的目标','令一名角色摸一张牌').set('ai',function(target){ - return get.attitude(_status.event.player,target)*Math.sqrt(Math.max(1,4-target.countCards('h'))); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + content: function () { + "step 0"; + player + .chooseTarget(true, "请选择【卫戍】的目标", "令一名角色摸一张牌") + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) * + Math.sqrt(Math.max(1, 4 - target.countCards("h"))) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(); } }, - group:'weishu_discard', - subSkill:{ - discard:{ - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + group: "weishu_discard", + subSkill: { + discard: { + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - forced:true, - filter:function(event,player){ - return event.type=='discard'&&event.getParent(3).name!='weishu_discard'&&event.getParent('phaseDiscard').player!=player&&event.getl(player).cards2.length>0&&game.hasPlayer((target)=>(target!=player&&target.countDiscardableCards(player,'he')>0)); + forced: true, + filter: function (event, player) { + return ( + event.type == "discard" && + event.getParent(3).name != "weishu_discard" && + event.getParent("phaseDiscard").player != player && + event.getl(player).cards2.length > 0 && + game.hasPlayer( + (target) => + target != player && target.countDiscardableCards(player, "he") > 0 + ) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(true,'请选择【卫戍】的目标','弃置一名其他角色的一张牌',function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,'he',true); + content: function () { + "step 0"; + player + .chooseTarget( + true, + "请选择【卫戍】的目标", + "弃置一名其他角色的一张牌", + function (card, player, target) { + return ( + target != player && target.countDiscardableCards(player, "he") > 0 + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, "he", true); } }, }, }, }, - gaoling:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - hiddenSkill:true, - filter:function(event,player){ - return event.toShow.includes('xuangongzhu')&&player!=_status.currentPhase&&game.hasPlayer(function(current){ - return current.isDamaged(); - }); + gaoling: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + hiddenSkill: true, + filter: function (event, player) { + return ( + event.toShow.includes("xuangongzhu") && + player != _status.currentPhase && + game.hasPlayer(function (current) { + return current.isDamaged(); + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('gaoling'),'令一名角色回复1点体力',function(card,player,target){ - return target.isDamaged(); - }).set('ai',function(target){ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gaoling',target); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("gaoling"), + "令一名角色回复1点体力", + function (card, player, target) { + return target.isDamaged(); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.recoverEffect(target, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gaoling", target); target.recover(); } }, }, - qimei:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('qimei'),'选择一名其他角色并获得“齐眉”效果',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target)/(Math.abs(player.countCards('h')+2-target.countCards('h'))+1) - }).setHiddenSkill('qimei'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('qimei',target); - player.storage.qimei_draw=target; - player.addTempSkill('qimei_draw',{player:'phaseBegin'}); + qimei: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("qimei"), + "选择一名其他角色并获得“齐眉”效果", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + get.attitude(player, target) / + (Math.abs(player.countCards("h") + 2 - target.countCards("h")) + 1) + ); + }) + .setHiddenSkill("qimei"); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("qimei", target); + player.storage.qimei_draw = target; + player.addTempSkill("qimei_draw", { player: "phaseBegin" }); game.delayx(); } }, - subSkill:{ - draw:{ - audio:'qimei', - charlotte:true, - forced:true, - popup:false, - trigger:{global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','loseAfter','addToExpansionAfter']}, - usable:1, - filter:function(event,player){ - var target=player.storage.qimei_draw; - if(!target||!target.isIn()) return false; - if(player.countCards('h')!=target.countCards('h')) return false; - var hasChange=function(event,player){ - var gain=0,lose=0; - if(event.getg) gain=event.getg(player).length; - if(event.getl) lose=event.getl(player).hs.length; - return gain!=lose; - }; - return hasChange(event,player)||hasChange(event,target); + subSkill: { + draw: { + audio: "qimei", + charlotte: true, + forced: true, + popup: false, + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "loseAfter", + "addToExpansionAfter", + ], }, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - 'step 1' - var target=player.storage.qimei_draw; - player.logSkill('qimei_draw',target); - var drawer=[]; - var hasChange=function(event,player){ - var gain=0,lose=0; - if(event.getg) gain=event.getg(player).length; - if(event.getl) lose=event.getl(player).hs.length; - return gain!=lose; + usable: 1, + filter: function (event, player) { + var target = player.storage.qimei_draw; + if (!target || !target.isIn()) return false; + if (player.countCards("h") != target.countCards("h")) return false; + var hasChange = function (event, player) { + var gain = 0, + lose = 0; + if (event.getg) gain = event.getg(player).length; + if (event.getl) lose = event.getl(player).hs.length; + return gain != lose; }; - if(hasChange(trigger,player)) drawer.push(target); - if(hasChange(trigger,target)) drawer.push(player); - if(drawer.length==1) drawer[0].draw(); - else{ + return hasChange(event, player) || hasChange(event, target); + }, + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + "step 1"; + var target = player.storage.qimei_draw; + player.logSkill("qimei_draw", target); + var drawer = []; + var hasChange = function (event, player) { + var gain = 0, + lose = 0; + if (event.getg) gain = event.getg(player).length; + if (event.getl) lose = event.getl(player).hs.length; + return gain != lose; + }; + if (hasChange(trigger, player)) drawer.push(target); + if (hasChange(trigger, target)) drawer.push(player); + if (drawer.length == 1) drawer[0].draw(); + else { game.asyncDraw(drawer.sortBySeat()); game.delayex(); } }, - group:'qimei_hp', - onremove:true, - mark:'character', - intro:{content:'已和$组成齐眉组合'}, + group: "qimei_hp", + onremove: true, + mark: "character", + intro: { content: "已和$组成齐眉组合" }, }, - hp:{ - audio:'qimei', - trigger:{global:'changeHp'}, - charlotte:true, - forced:true, - logTarget:function(event,player){ + hp: { + audio: "qimei", + trigger: { global: "changeHp" }, + charlotte: true, + forced: true, + logTarget: function (event, player) { return player.storage.qimei_draw; }, - usable:1, - filter:function(event,player){ - var target=player.storage.qimei_draw; - if(!target||!target.isIn()) return false; - if(player!=event.player&&target!=event.player) return false; - return player.hp==target.hp; + usable: 1, + filter: function (event, player) { + var target = player.storage.qimei_draw; + if (!target || !target.isIn()) return false; + if (player != event.player && target != event.player) return false; + return player.hp == target.hp; }, - content:function(){ + content: function () { game.delayx(); - (player==trigger.player?player.storage.qimei_draw:player).draw(); + (player == trigger.player ? player.storage.qimei_draw : player).draw(); }, }, }, }, - ybzhuiji:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - var list=['摸两张牌,并于出牌阶段结束时失去1点体力']; - if(player.isDamaged()) list.push('回复1点体力,并于出牌阶段结束时弃置两张牌'); - player.chooseControl('cancel2').set('choiceList',list).set('prompt',get.prompt('ybzhuiji')).set('ai',function(){ - var player=_status.event.player; - if(player.isDamaged()&&player.countCards('h','tao')0; + check: function (event, player) { + return get.effect(player, event.card, event.player, player) > 0; }, - preHidden:true, - content:function(){ + preHidden: true, + content: function () { trigger.targets.push(player); - game.log(player,'也成为了',trigger.card,'的目标'); - var next=game.createEvent('congjian_draw',false); - next.player=player; + game.log(player, "也成为了", trigger.card, "的目标"); + var next = game.createEvent("congjian_draw", false); + next.player = player; event.next.remove(next); trigger.getParent().after.push(next); - next.setContent(function(){ - if(player.hasHistory('damage',function(evt){ - return evt.card==event.parent.card; - })) player.draw(2); + next.setContent(function () { + if ( + player.hasHistory("damage", function (evt) { + return evt.card == event.parent.card; + }) + ) + player.draw(2); }); }, }, - wanyi:{ - audio:2, - enable:'phaseUse', - filter:function(event,player){ - return player.getStorage('wanyi2').length<4&&player.hasCard(function(i){ - return get.is.yingbian(i); - },'hs'); + wanyi: { + audio: 2, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.getStorage("wanyi2").length < 4 && + player.hasCard(function (i) { + return get.is.yingbian(i); + }, "hs") + ); }, - chooseButton:{ - dialog:function(event,player){ - var list=['zhujinqiyuan','chuqibuyi','shuiyanqijunx','dongzhuxianji']; - list.removeArray(player.getStorage('wanyi2')) - return ui.create.dialog('婉嫕',[list,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + var list = ["zhujinqiyuan", "chuqibuyi", "shuiyanqijunx", "dongzhuxianji"]; + list.removeArray(player.getStorage("wanyi2")); + return ui.create.dialog("婉嫕", [list, "vcard"], "hidden"); }, - filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2]}); + check: function (button) { + return _status.event.player.getUseValue({ name: button.link[2] }); }, - backup:function(links){ + backup: function (links) { return { - audio:'wanyi', - popname:true, - viewAs:{ - name:links[0][2], + audio: "wanyi", + popname: true, + viewAs: { + name: links[0][2], }, - filterCard:function(card){ + filterCard: function (card) { return get.is.yingbian(card); }, - check:function(card){ - return 1/Math.max(1,get.value(card)); + check: function (card) { + return 1 / Math.max(1, get.value(card)); }, - position:'hs', - onuse:function(links,player){ - if(!player.storage.wanyi2) player.storage.wanyi2=[]; + position: "hs", + onuse: function (links, player) { + if (!player.storage.wanyi2) player.storage.wanyi2 = []; player.storage.wanyi2.add(links.card.name); - player.addTempSkill('wanyi2'); + player.addTempSkill("wanyi2"); }, - } + }; }, - prompt:function(links){ - return '将一张应变牌当做'+get.translation(links[0][2])+'使用'; + prompt: function (links) { + return "将一张应变牌当做" + get.translation(links[0][2]) + "使用"; }, }, - subSkill:{backup:{}}, - ai:{order:8,result:{player:1}}, + subSkill: { backup: {} }, + ai: { order: 8, result: { player: 1 } }, }, - wanyi2:{onremove:true}, - maihuo:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - logTarget:'player', - filter:function(event,player){ - return event.card.name=='sha'&&event.card.isCard&&event.getParent(2).name!='maihuo_effect'&& - event.cards.filterInD().length>0&&event.targets.length==1&& - event.player.isIn()&&(!event.player.getExpansions('maihuo_effect').length); + wanyi2: { onremove: true }, + maihuo: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + logTarget: "player", + filter: function (event, player) { + return ( + event.card.name == "sha" && + event.card.isCard && + event.getParent(2).name != "maihuo_effect" && + event.cards.filterInD().length > 0 && + event.targets.length == 1 && + event.player.isIn() && + !event.player.getExpansions("maihuo_effect").length + ); }, - prompt2:function(event){ - return '令'+get.translation(event.card)+'暂时对你无效'; + prompt2: function (event) { + return "令" + get.translation(event.card) + "暂时对你无效"; }, - check:function(event,player){ - return get.effect(player,event.card,event.player,player)<0; + check: function (event, player) { + return get.effect(player, event.card, event.player, player) < 0; }, - content:function(){ + content: function () { trigger.excluded.add(player); - var target=trigger.player,cards=trigger.cards.filterInD(); - target.addToExpansion('gain2',cards).gaintag.add('maihuo_effect'); - target.storage.maihuo_target=player; - target.addSkill('maihuo_effect') + var target = trigger.player, + cards = trigger.cards.filterInD(); + target.addToExpansion("gain2", cards).gaintag.add("maihuo_effect"); + target.storage.maihuo_target = player; + target.addSkill("maihuo_effect"); }, - group:'maihuo_damage', - subSkill:{ - effect:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return player.getExpansions('maihuo_effect').length>0; + group: "maihuo_damage", + subSkill: { + effect: { + trigger: { player: "phaseUseBegin" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return player.getExpansions("maihuo_effect").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('maihuo_effect'),card=cards[0]; - if(card.name!='sha') card=get.autoViewAs({ - name:'sha', - isCard:true, - },cards); - var target=player.storage.maihuo_target; - if(target.isIn()&&player.canUse(card,target,null,true)){ - player.useCard(card,target,cards); + content: function () { + "step 0"; + var cards = player.getExpansions("maihuo_effect"), + card = cards[0]; + if (card.name != "sha") + card = get.autoViewAs( + { + name: "sha", + isCard: true, + }, + cards + ); + var target = player.storage.maihuo_target; + if (target.isIn() && player.canUse(card, target, null, true)) { + player.useCard(card, target, cards); } - 'step 1' - player.removeSkill('maihuo_effect'); + "step 1"; + player.removeSkill("maihuo_effect"); }, - marktext:'祸', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "祸", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{threaten:1.05}, + ai: { threaten: 1.05 }, }, - damage:{ - trigger:{source:'damageSource'}, - forced:true, - locked:false, - filter:function(event,player){ - return event.player.hasSkill('maihuo_effect')&&event.player.getExpansions('maihuo_effect').length>0; + damage: { + trigger: { source: "damageSource" }, + forced: true, + locked: false, + filter: function (event, player) { + return ( + event.player.hasSkill("maihuo_effect") && + event.player.getExpansions("maihuo_effect").length > 0 + ); }, - content:function(){ - trigger.player.removeSkill('maihuo_effect'); + content: function () { + trigger.player.removeSkill("maihuo_effect"); }, }, }, }, - xuanbei:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:'enterGame', + xuanbei: { + audio: 2, + trigger: { + global: "phaseBefore", + player: "enterGame", }, - filter:function(event,player){ - return (event.name!='phase'||game.phaseNumber==0); + filter: function (event, player) { + return event.name != "phase" || game.phaseNumber == 0; }, - forced:true, - locked:false, - content:function(){ - var cards=[]; - while(cards.length<2){ - var card=get.cardPile2(function(i){ - return get.is.yingbian(i)&&!cards.includes(i); + forced: true, + locked: false, + content: function () { + var cards = []; + while (cards.length < 2) { + var card = get.cardPile2(function (i) { + return get.is.yingbian(i) && !cards.includes(i); }); - if(!card) break; + if (!card) break; else cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); + if (cards.length) player.gain(cards, "gain2"); }, - group:'xuanbei_give', - subSkill:{ - give:{ - trigger:{player:'useCardAfter'}, - usable:1, - filter:function(event,player){ - return (event.card.yingbian||get.is.yingbian(event.card))&&event.cards.filterInD().length>0; + group: "xuanbei_give", + subSkill: { + give: { + trigger: { player: "useCardAfter" }, + usable: 1, + filter: function (event, player) { + return ( + (event.card.yingbian || get.is.yingbian(event.card)) && + event.cards.filterInD().length > 0 + ); }, - direct:true, - content:function(){ - 'step 0' - event.cards=trigger.cards.filterInD(); - player.chooseTarget(get.prompt('xuanbei'),'令一名其他角色获得'+get.translation(event.cards),lib.filter.notMe).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(att<3) return 0; - if(target.hasJudge('lebu')) att/=2; - if(target.hasSkillTag('nogain')) att/=10; - return att/(1+get.distance(player,target,'absolute')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('xuanbei_give',target); - target.gain(cards,'gain2').giver=player; - } - else player.storage.counttrigger.xuanbei_give--; + direct: true, + content: function () { + "step 0"; + event.cards = trigger.cards.filterInD(); + player + .chooseTarget( + get.prompt("xuanbei"), + "令一名其他角色获得" + get.translation(event.cards), + lib.filter.notMe + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (att < 3) return 0; + if (target.hasJudge("lebu")) att /= 2; + if (target.hasSkillTag("nogain")) att /= 10; + return att / (1 + get.distance(player, target, "absolute")); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("xuanbei_give", target); + target.gain(cards, "gain2").giver = player; + } else player.storage.counttrigger.xuanbei_give--; }, - ai:{expose:0.1}, + ai: { expose: 0.1 }, }, }, }, - xianwan:{ - audio:2, - enable:'chooseToUse', - filter:function(event,player){ - return event.filterCard&&event.filterCard({ - name:'sha'+(player.isLinked()?'':'n'), - isCard:true, - },player,event); + xianwan: { + audio: 2, + enable: "chooseToUse", + filter: function (event, player) { + return ( + event.filterCard && + event.filterCard( + { + name: "sha" + (player.isLinked() ? "" : "n"), + isCard: true, + }, + player, + event + ) + ); }, - viewAs:function(cards,player){ + viewAs: function (cards, player) { return { - name:'sha'+(player.isLinked()?'':'n'), - isCard:true, + name: "sha" + (player.isLinked() ? "" : "n"), + isCard: true, }; }, - filterCard:()=>false, - selectCard:-1, - prompt:'将武将牌重置并视为使用【杀】', - log:false, - check:()=>1, - precontent:function(){ - player.logSkill('xianwan'); + filterCard: () => false, + selectCard: -1, + prompt: "将武将牌重置并视为使用【杀】", + log: false, + check: () => 1, + precontent: function () { + player.logSkill("xianwan"); player.link(); }, - ai:{ - order:3.4, - respondSha:true, - respondShan:true, - skillTagFilter:function(player,tag){ - return tag==('respondSha'+(player.isLinked()?'':'n')); + ai: { + order: 3.4, + respondSha: true, + respondShan: true, + skillTagFilter: function (player, tag) { + return tag == "respondSha" + (player.isLinked() ? "" : "n"); }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0&&!player.isLinked()) return 0.4; + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0 && !player.isLinked()) return 0.4; }, }, }, }, - recaiwang:{ - audio:'caiwang', - inherit:'caiwang', - group:['recaiwang_hand','recaiwang_equip','recaiwang_judge'], + recaiwang: { + audio: "caiwang", + inherit: "caiwang", + group: ["recaiwang_hand", "recaiwang_equip", "recaiwang_judge"], }, - recaiwang_hand:{ - audio:'caiwang', - enable:['chooseToUse','chooseToRespond'], - viewAsFilter:function(player){ - var js=player.getCards('h'); - return js.length==1&&game.checkMod(js[0],player,'unchanged','cardEnabled2',player); + recaiwang_hand: { + audio: "caiwang", + enable: ["chooseToUse", "chooseToRespond"], + viewAsFilter: function (player) { + var js = player.getCards("h"); + return ( + js.length == 1 && game.checkMod(js[0], player, "unchanged", "cardEnabled2", player) + ); }, - selectCard:-1, - filterCard:true, - position:'h', - prompt:'将全部手牌当做【闪】使用', - viewAs:{name:'shan'}, - check:(card)=>10-get.value(card), - ai:{ - order:1, - respondShan:true, - skillTagFilter:function(player){ - return player.countCards('h')==1; + selectCard: -1, + filterCard: true, + position: "h", + prompt: "将全部手牌当做【闪】使用", + viewAs: { name: "shan" }, + check: (card) => 10 - get.value(card), + ai: { + order: 1, + respondShan: true, + skillTagFilter: function (player) { + return player.countCards("h") == 1; }, }, }, - recaiwang_equip:{ - audio:'caiwang', - enable:['chooseToUse','chooseToRespond'], - viewAsFilter:function(player){ - var js=player.getCards('e'); - return js.length==1&&game.checkMod(js[0],player,'unchanged','cardEnabled2',player); + recaiwang_equip: { + audio: "caiwang", + enable: ["chooseToUse", "chooseToRespond"], + viewAsFilter: function (player) { + var js = player.getCards("e"); + return ( + js.length == 1 && game.checkMod(js[0], player, "unchanged", "cardEnabled2", player) + ); }, - selectCard:-1, - filterCard:true, - check:(card)=>9-get.value(card), - position:'e', - prompt:'将装备区的牌当做【无懈可击】使用', - viewAs:{name:'wuxie'}, - ai:{ - order:1, + selectCard: -1, + filterCard: true, + check: (card) => 9 - get.value(card), + position: "e", + prompt: "将装备区的牌当做【无懈可击】使用", + viewAs: { name: "wuxie" }, + ai: { + order: 1, }, }, - recaiwang_judge:{ - audio:'caiwang', - enable:['chooseToUse','chooseToRespond'], - viewAsFilter:function(player){ - var js=player.getCards('j'); - return js.length==1&&game.checkMod(js[0],player,'unchanged','cardEnabled2',player); + recaiwang_judge: { + audio: "caiwang", + enable: ["chooseToUse", "chooseToRespond"], + viewAsFilter: function (player) { + var js = player.getCards("j"); + return ( + js.length == 1 && game.checkMod(js[0], player, "unchanged", "cardEnabled2", player) + ); }, - selectCard:-1, - filterCard:true, - position:'j', - prompt:'将判定区的牌当做【杀】使用', - viewAs:{name:'sha'}, - check:(card)=>1, - locked:false, - ai:{ - order:10, - respondSha:true, - skillTagFilter:function(player){ - return player.countCards('j')==1; + selectCard: -1, + filterCard: true, + position: "j", + prompt: "将判定区的牌当做【杀】使用", + viewAs: { name: "sha" }, + check: (card) => 1, + locked: false, + ai: { + order: 10, + respondSha: true, + skillTagFilter: function (player) { + return player.countCards("j") == 1; }, - effect:{ - target:function(card,player,target,current){ - if(card&&(card.name=='shandian'||card.name=='fulei')&&player==target&&!target.countCards('j')&&target.isPhaseUsing()&&target.hasValueTarget({name:'sha'},null,true)) return [1,2]; + effect: { + target: function (card, player, target, current) { + if ( + card && + (card.name == "shandian" || card.name == "fulei") && + player == target && + !target.countCards("j") && + target.isPhaseUsing() && + target.hasValueTarget({ name: "sha" }, null, true) + ) + return [1, 2]; }, }, }, - mod:{ - aiOrder:function(player,card,num){ - if(card.name=='shandian'||card.name=='fulei') return num+3; + mod: { + aiOrder: function (player, card, num) { + if (card.name == "shandian" || card.name == "fulei") return num + 3; }, }, }, - caozhao:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - if(player.countCards('h')==0||!game.hasPlayer(function(current){ - return current!=player&¤t.hp<=player.hp; - })) return false; - var list=player.getStorage('caozhao'); - for(var i of lib.inpile){ - if(!list.includes(i)&&['basic','trick'].includes(get.type(i))) return true; + caozhao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + if ( + player.countCards("h") == 0 || + !game.hasPlayer(function (current) { + return current != player && current.hp <= player.hp; + }) + ) + return false; + var list = player.getStorage("caozhao"); + for (var i of lib.inpile) { + if (!list.includes(i) && ["basic", "trick"].includes(get.type(i))) return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=player.getStorage('caozhao'),vcards=[]; - for(var i of lib.inpile){ - if(!list.includes(i)){ - var type=get.type(i); - if(type=='basic'||type=='trick') vcards.push([type,'',i]); + chooseButton: { + dialog: function (event, player) { + var list = player.getStorage("caozhao"), + vcards = []; + for (var i of lib.inpile) { + if (!list.includes(i)) { + var type = get.type(i); + if (type == "basic" || type == "trick") vcards.push([type, "", i]); } } - return ui.create.dialog('草诏',[vcards,'vcard']); + return ui.create.dialog("草诏", [vcards, "vcard"]); }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2],isCard:true},null,true); + check: function (button) { + return _status.event.player.getUseValue( + { name: button.link[2], isCard: true }, + null, + true + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'caozhao', - cardname:links[0][2], - filterCard:true, - position:'h', - check:function(card){ - return player.getUseValue({name:lib.skill.caozhao_backup.cardname})-((player.getUseValue(card,null,true)+0.1)/(get.value(card)/6)); + audio: "caozhao", + cardname: links[0][2], + filterCard: true, + position: "h", + check: function (card) { + return ( + player.getUseValue({ name: lib.skill.caozhao_backup.cardname }) - + (player.getUseValue(card, null, true) + 0.1) / (get.value(card) / 6) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.hp<=player.hp; + filterTarget: function (card, player, target) { + return target != player && target.hp <= player.hp; }, - discard:false, - lose:false, - content:function(){ - 'step 0' - player.showCards(cards,get.translation(player)+'发动【草诏】,声明'+get.translation(lib.skill.caozhao_backup.cardname)); - if(!player.storage.caozhao) player.storage.caozhao=[]; + discard: false, + lose: false, + content: function () { + "step 0"; + player.showCards( + cards, + get.translation(player) + + "发动【草诏】,声明" + + get.translation(lib.skill.caozhao_backup.cardname) + ); + if (!player.storage.caozhao) player.storage.caozhao = []; player.storage.caozhao.push(lib.skill.caozhao_backup.cardname); - 'step 1' - target.chooseControl().set('choiceList',[ - '令'+get.translation(player)+'将'+get.translation(cards[0])+'的牌名改为'+get.translation(lib.skill.caozhao_backup.cardname), - '失去1点体力', - ]).set('ai',function(event,player){ - var target=_status.event.getParent().player; - if(get.attitude(player,target)>0) return 0; - if(player.hp>3||(player.hp>1&&player.hasSkill('zhaxiang'))) return 1; - if(player.hp>2) return Math.random()>0.5?0:1; - return 0; - }); - 'step 2' - if(result.index==1){ + "step 1"; + target + .chooseControl() + .set("choiceList", [ + "令" + + get.translation(player) + + "将" + + get.translation(cards[0]) + + "的牌名改为" + + get.translation(lib.skill.caozhao_backup.cardname), + "失去1点体力", + ]) + .set("ai", function (event, player) { + var target = _status.event.getParent().player; + if (get.attitude(player, target) > 0) return 0; + if (player.hp > 3 || (player.hp > 1 && player.hasSkill("zhaxiang"))) + return 1; + if (player.hp > 2) return Math.random() > 0.5 ? 0 : 1; + return 0; + }); + "step 2"; + if (result.index == 1) { target.addExpose(0.2); target.loseHp(); event.finish(); + } else { + player + .chooseTarget( + "是否将" + + get.translation(lib.skill.caozhao_backup.cardname) + + "(" + + get.translation(cards[0]) + + ")交给一名其他角色?", + lib.filter.notMe + ) + .set("ai", () => -1); } - else{ - player.chooseTarget('是否将'+get.translation(lib.skill.caozhao_backup.cardname)+'('+get.translation(cards[0])+')交给一名其他角色?',lib.filter.notMe).set('ai',()=>-1); - } - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - if(!target.storage.caozhao_info) target.storage.caozhao_info={}; - target.storage.caozhao_info[cards[0].cardid]=lib.skill.caozhao_backup.cardname; - target.addSkill('caozhao_info'); - player.give(cards,target,'give').gaintag.add('caozhao'); - } - else{ - if(!player.storage.caozhao_info) player.storage.caozhao_info={}; - player.storage.caozhao_info[cards[0].cardid]=lib.skill.caozhao_backup.cardname; - player.addGaintag(cards,'caozhao'); - player.addSkill('caozhao_info'); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + if (!target.storage.caozhao_info) target.storage.caozhao_info = {}; + target.storage.caozhao_info[cards[0].cardid] = + lib.skill.caozhao_backup.cardname; + target.addSkill("caozhao_info"); + player.give(cards, target, "give").gaintag.add("caozhao"); + } else { + if (!player.storage.caozhao_info) player.storage.caozhao_info = {}; + player.storage.caozhao_info[cards[0].cardid] = + lib.skill.caozhao_backup.cardname; + player.addGaintag(cards, "caozhao"); + player.addSkill("caozhao_info"); } }, - ai:{ - result:{ - player:2, - target:0.1, + ai: { + result: { + player: 2, + target: 0.1, }, }, - } + }; }, - prompt:function(links,player){ - return '将一张手牌声明为'+get.translation(links[0][2]); + prompt: function (links, player) { + return "将一张手牌声明为" + get.translation(links[0][2]); }, }, - ai:{ - order:1, - result:{ - player:1, + ai: { + order: 1, + result: { + player: 1, }, }, }, - caozhao_info:{ - charlotte:true, - mod:{ - cardname:function(card,player){ - var map=player.storage.caozhao_info; - if(map&&map[card.cardid]&&get.itemtype(card)=='card'&&card.hasGaintag('caozhao')) return map[card.cardid]; + caozhao_info: { + charlotte: true, + mod: { + cardname: function (card, player) { + var map = player.storage.caozhao_info; + if ( + map && + map[card.cardid] && + get.itemtype(card) == "card" && + card.hasGaintag("caozhao") + ) + return map[card.cardid]; }, - cardnature:function(card,player){ - var map=player.storage.caozhao_info; - if(map&&map[card.cardid]&&get.itemtype(card)=='card'&&card.hasGaintag('caozhao')) return false; + cardnature: function (card, player) { + var map = player.storage.caozhao_info; + if ( + map && + map[card.cardid] && + get.itemtype(card) == "card" && + card.hasGaintag("caozhao") + ) + return false; }, }, }, - olxibing:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.player&&event.source&&event.player!=event.source&&event.player.isAlive()&&event.source.isAlive()&&(event.player.countCards('he')>0||event.source.countCards('he')>0); + olxibing: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.player && + event.source && + event.player != event.source && + event.player.isAlive() && + event.source.isAlive() && + (event.player.countCards("he") > 0 || event.source.countCards("he") > 0) + ); }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.source; - event.target=target; - player.chooseTarget(get.prompt('olxibing'),'弃置自己或'+get.translation(target)+'的两张牌,然后手牌数较少的角色摸两张牌且不能对你使用牌直到回合结束',function(card,player,target){ - if(target!=player&&target!=_status.event.target) return false; - return target.countCards('he')>0; - }).set('target',target).set('ai',function(targetx){ - var player=_status.event.player,target=_status.event.target; - if(target==targetx){ - if(get.attitude(player,target)>0) return 0; - var cards=target.getCards('he',function(card){ - return lib.filter.canBeDiscarded(card,player,target); - }).sort(function(a,b){ - return get.buttonValue(b)-get.buttonValue(a); - }); - if((target.countCards('h')-player.countCards('h'))>=Math.max(0,Math.min(2,cards.length)-target.countCards('e',function(card){ - var index=cards.indexOf(card); - return index!=-1&&index<2; - }))) return 1; + direct: true, + content: function () { + "step 0"; + var target = trigger.source; + event.target = target; + player + .chooseTarget( + get.prompt("olxibing"), + "弃置自己或" + + get.translation(target) + + "的两张牌,然后手牌数较少的角色摸两张牌且不能对你使用牌直到回合结束", + function (card, player, target) { + if (target != player && target != _status.event.target) return false; + return target.countCards("he") > 0; + } + ) + .set("target", target) + .set("ai", function (targetx) { + var player = _status.event.player, + target = _status.event.target; + if (target == targetx) { + if (get.attitude(player, target) > 0) return 0; + var cards = target + .getCards("he", function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }) + .sort(function (a, b) { + return get.buttonValue(b) - get.buttonValue(a); + }); + if ( + target.countCards("h") - player.countCards("h") >= + Math.max( + 0, + Math.min(2, cards.length) - + target.countCards("e", function (card) { + var index = cards.indexOf(card); + return index != -1 && index < 2; + }) + ) + ) + return 1; + return 0; + } + var cards = player + .getCards("he", function (card) { + return lib.filter.cardDiscardable(card, player, "olxibing"); + }) + .sort(function (a, b) { + return get.useful(a) - get.useful(b); + }); + if ( + player.countCards("h") - target.countCards("h") < + Math.max( + 0, + Math.min(cards.length, 2) - + player.countCards("e", function (card) { + var index = cards.indexOf(card); + return index != -1 && index < 2; + }) + ) && + (cards.length < 2 || get.value(cards[1]) < 5.5) + ) + return 0.8; return 0; - } - var cards=player.getCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'olxibing') - }).sort(function(a,b){ - return get.useful(a)-get.useful(b); }); - if(player.countCards('h')-target.countCards('h')ts?target:player; + "step 1"; + if (result.bool) { + player.logSkill("olxibing", target); + var target = result.targets[0]; + if (target == player) player.chooseToDiscard("he", 2, true); + else player.discardPlayerCard(target, "he", true, 2); + } else event.finish(); + "step 2"; + if (player.isIn() && target.isIn()) { + var hs = player.countCards("h"), + ts = target.countCards("h"); + if (hs != ts) { + var drawer = hs > ts ? target : player; drawer.draw(2); - player.addTempSkill('olxibing2'); - player.markAuto('olxibing2',[drawer]); + player.addTempSkill("olxibing2"); + player.markAuto("olxibing2", [drawer]); } } }, }, - olxibing2:{ - mod:{ - targetEnabled:function(card,player,target){ - if(target.getStorage('olxibing2').includes(player)) return false; + olxibing2: { + mod: { + targetEnabled: function (card, player, target) { + if (target.getStorage("olxibing2").includes(player)) return false; }, - cardSavable:function(card,player,target){ - if(target.getStorage('olxibing2').includes(player)) return false; + cardSavable: function (card, player, target) { + if (target.getStorage("olxibing2").includes(player)) return false; }, }, - onremove:true, + onremove: true, }, - bolan:{ - audio:2, - banned:['kotomi_chuanxiang'], - global:'bolan_g', - initList:function(player){ - var list,skills=[]; - if(get.mode()=='guozhan'){ - list=[]; - for(var i in lib.characterPack.mode_guozhan){ - if(lib.character[i])list.push(i); + bolan: { + audio: 2, + banned: ["kotomi_chuanxiang"], + global: "bolan_g", + initList: function (player) { + var list, + skills = []; + if (get.mode() == "guozhan") { + list = []; + for (var i in lib.characterPack.mode_guozhan) { + if (lib.character[i]) list.push(i); } - } - else if(_status.connectMode) list=get.charactersOL(); + } else if (_status.connectMode) list = get.charactersOL(); else { - list=[]; - for(var i in lib.character){ - if(lib.filter.characterDisabled2(i)||lib.filter.characterDisabled(i)) continue; + list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled2(i) || lib.filter.characterDisabled(i)) continue; list.push(i); } } - for(var i of list){ - if(i.indexOf('gz_jun')==0) continue; - for(var j of lib.character[i][3]){ - if(j=='bolan') continue; - var skill=lib.skill[j]; - if(!skill||skill.juexingji||skill.hiddenSkill||skill.zhuSkill||skill.dutySkill||skill.chargeSkill||lib.skill.bolan.banned.includes(j)) continue; - if(skill.init||skill.ai&&(skill.ai.combo||skill.ai.notemp||skill.ai.neg)) continue; - var info=lib.translate[j+'_info']; - if(info&&info.indexOf('出牌阶段限一次')!=-1) skills.add(j); + for (var i of list) { + if (i.indexOf("gz_jun") == 0) continue; + for (var j of lib.character[i][3]) { + if (j == "bolan") continue; + var skill = lib.skill[j]; + if ( + !skill || + skill.juexingji || + skill.hiddenSkill || + skill.zhuSkill || + skill.dutySkill || + skill.chargeSkill || + lib.skill.bolan.banned.includes(j) + ) + continue; + if ( + skill.init || + (skill.ai && (skill.ai.combo || skill.ai.notemp || skill.ai.neg)) + ) + continue; + var info = lib.translate[j + "_info"]; + if (info && info.indexOf("出牌阶段限一次") != -1) skills.add(j); } } - player.storage.bolan=skills; + player.storage.bolan = skills; }, - check:function(event,player){ + check: function (event, player) { return true; }, - trigger:{player:'phaseUseBegin'}, - frequent:true, - preHidden:true, - content:function(){ - 'step 0' - if(player.isIn()){ - if(!player.storage.bolan) lib.skill.bolan.initList(player); - var list=player.storage.bolan.randomGets(3); - if(!list.length){ + trigger: { player: "phaseUseBegin" }, + frequent: true, + preHidden: true, + content: function () { + "step 0"; + if (player.isIn()) { + if (!player.storage.bolan) lib.skill.bolan.initList(player); + var list = player.storage.bolan.randomGets(3); + if (!list.length) { event.finish(); return; } - player.chooseControl(list).set('choiceList',list.map(function(i){ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','博览:请选择你要获得的技能').set('ai',()=>{ - var list=_status.event.controls.slice(); - return list.sort((a,b)=>{ - return get.skillRank(b,'in')-get.skillRank(a,'in'); - })[0]; - }); - } - else event.finish(); - 'step 1' - player.addTempSkills(result.control,'phaseUseEnd'); + player + .chooseControl(list) + .set( + "choiceList", + list.map(function (i) { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "博览:请选择你要获得的技能") + .set("ai", () => { + var list = _status.event.controls.slice(); + return list.sort((a, b) => { + return get.skillRank(b, "in") - get.skillRank(a, "in"); + })[0]; + }); + } else event.finish(); + "step 1"; + player.addTempSkills(result.control, "phaseUseEnd"); player.popup(result.control); // game.log(player,'获得了','#g【'+get.translation(result.control)+'】'); }, - ai:{threaten:0.9}, - subSkill:{ - g:{ - audio:'bolan', - forceaudio:true, - enable:'phaseUse', - usable:1, - prompt:'出牌阶段限一次。你可以令一名有〖博览〗的角色从三个描述中包含“出牌阶段限一次”的技能中选择一个,你获得此技能直到此阶段结束。', - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('bolan'); + ai: { threaten: 0.9 }, + subSkill: { + g: { + audio: "bolan", + forceaudio: true, + enable: "phaseUse", + usable: 1, + prompt: "出牌阶段限一次。你可以令一名有〖博览〗的角色从三个描述中包含“出牌阶段限一次”的技能中选择一个,你获得此技能直到此阶段结束。", + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.hasSkill("bolan"); }); }, - filterTarget:function(card,player,target){ - return player!=target&&target.hasSkill('bolan'); + filterTarget: function (card, player, target) { + return player != target && target.hasSkill("bolan"); }, - selectTarget:function(){ - if(game.countPlayer(current=>{ - return lib.skill.bolan_g.filterTarget(null,_status.event.player,current); - })==1) return -1; + selectTarget: function () { + if ( + game.countPlayer((current) => { + return lib.skill.bolan_g.filterTarget( + null, + _status.event.player, + current + ); + }) == 1 + ) + return -1; return 1; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.loseHp(); - 'step 1' - if(target.isIn()&&player.isIn()){ - if(!target.storage.bolan) lib.skill.bolan.initList(target); - var list=target.storage.bolan.randomGets(3); - if(!list.length){ + "step 1"; + if (target.isIn() && player.isIn()) { + if (!target.storage.bolan) lib.skill.bolan.initList(target); + var list = target.storage.bolan.randomGets(3); + if (!list.length) { event.finish(); return; } - target.chooseControl(list).set('choiceList',list.map(function(i){ - return '
              【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
              '+get.skillInfoTranslation(i,player)+'
              '; - })).set('displayIndex',false).set('prompt','博览:请选择令'+get.translation(player)+'获得的技能').set('ai',()=>{ - var list=_status.event.controls.slice(); - return list.sort((a,b)=>{ - return (get.skillRank(b,'in')-get.skillRank(a,'in'))*get.attitude(_status.event.player,_status.event.getParent().player); - })[0]; - }); - } - else event.finish(); - 'step 2' + target + .chooseControl(list) + .set( + "choiceList", + list.map(function (i) { + return ( + '
              【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
              " + + get.skillInfoTranslation(i, player) + + "
              " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "博览:请选择令" + get.translation(player) + "获得的技能") + .set("ai", () => { + var list = _status.event.controls.slice(); + return list.sort((a, b) => { + return ( + (get.skillRank(b, "in") - get.skillRank(a, "in")) * + get.attitude( + _status.event.player, + _status.event.getParent().player + ) + ); + })[0]; + }); + } else event.finish(); + "step 2"; target.line(player); - player.addTempSkills(result.control,'phaseUseEnd'); + player.addTempSkills(result.control, "phaseUseEnd"); player.popup(result.control); }, - ai:{ - order:function(item,player){ - if(player.hp>=5||player.countCards('h')>=10) return 10; - var list=game.filterPlayer(current=>lib.skill.bolan_g.filterTarget(null,player,current)); - for(var target of list){ - if(get.attitude(target,player)>0) return 10; + ai: { + order: function (item, player) { + if (player.hp >= 5 || player.countCards("h") >= 10) return 10; + var list = game.filterPlayer((current) => + lib.skill.bolan_g.filterTarget(null, player, current) + ); + for (var target of list) { + if (get.attitude(target, player) > 0) return 10; } return 4; }, - result:{ - player:function(player,target){ - if(player.hasUnknown()) return player.hp+player.countCards('h')/4-5>0?1:0; - var tao=player.countCards('h','tao'); - if(player.hp+tao>4) return 4+get.attitude(player,target); - if(player.hp+tao>3) return get.attitude(player,target)-2; + result: { + player: function (player, target) { + if (player.hasUnknown()) + return player.hp + player.countCards("h") / 4 - 5 > 0 ? 1 : 0; + var tao = player.countCards("h", "tao"); + if (player.hp + tao > 4) return 4 + get.attitude(player, target); + if (player.hp + tao > 3) return get.attitude(player, target) - 2; return 0; }, }, }, - } - } - }, - yifa:{ - audio:2, - trigger:{target:'useCardToTargeted'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - return player!=event.player&&(event.card.name=='sha'|| - get.color(event.card)=='black'&&get.type(event.card)=='trick'); - }, - content:function(){ - var target=trigger.player; - target.addTempSkill('yifa2',{player:'phaseEnd'}); - target.addMark('yifa2',1,false); - }, - ai:{threaten:0.8}, - }, - yifa2:{ - charlotte:true, - onremove:true, - intro:{content:'手牌上限-#'}, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('yifa2'); }, }, }, - buchen:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - hiddenSkill:true, - filter:function(event,player){ - var target=_status.currentPhase; - return event.toShow.includes('jin_simayi')&&target&&target!=player&&target.countGainableCards(player,'he')>0; + yifa: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + return ( + player != event.player && + (event.card.name == "sha" || + (get.color(event.card) == "black" && get.type(event.card) == "trick")) + ); }, - direct:true, - content:function(){ - var target=_status.currentPhase; - player.gainPlayerCard(target,'he',get.prompt('buchen',target)).set('logSkill',['buchen',target]); + content: function () { + var target = trigger.player; + target.addTempSkill("yifa2", { player: "phaseEnd" }); + target.addMark("yifa2", 1, false); + }, + ai: { threaten: 0.8 }, + }, + yifa2: { + charlotte: true, + onremove: true, + intro: { content: "手牌上限-#" }, + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("yifa2"); + }, }, }, - smyyingshi:{ - audio:2, - enable:'phaseUse', - locked:true, - filter:function(event,player){ + buchen: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + hiddenSkill: true, + filter: function (event, player) { + var target = _status.currentPhase; + return ( + event.toShow.includes("jin_simayi") && + target && + target != player && + target.countGainableCards(player, "he") > 0 + ); + }, + direct: true, + content: function () { + var target = _status.currentPhase; + player + .gainPlayerCard(target, "he", get.prompt("buchen", target)) + .set("logSkill", ["buchen", target]); + }, + }, + smyyingshi: { + audio: 2, + enable: "phaseUse", + locked: true, + filter: function (event, player) { return Array.isArray(event.smyyingshi); }, - onChooseToUse:function(event){ - if(game.online||!event.player.hasSkill('smyyingshi')) return; - var cards=[]; - for(var i=0;i0; + return evts && evts.length == 1 && evts[0].hs.length > 0; }, - filter:function(event,player){ - var phase=event.getParent('phaseUse'); - if(!phase||phase.player!=player) return false; - var suit=get.suit(event.card); - if(!lib.suit.includes(suit)||!lib.skill.quanbian.hasHand(event)) return false; - return player.getHistory('useCard',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length+player.getHistory('respond',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length==0; + filter: function (event, player) { + var phase = event.getParent("phaseUse"); + if (!phase || phase.player != player) return false; + var suit = get.suit(event.card); + if (!lib.suit.includes(suit) || !lib.skill.quanbian.hasHand(event)) return false; + return ( + player.getHistory("useCard", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length + + player.getHistory("respond", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length == + 0 + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('cancel2').set('prompt',get.prompt('quanbian')).set('choiceList',[ - '摸一张牌', - '观看牌堆顶的'+get.cnNumber(player.maxHp)+'张牌并将其中一张置于牌堆底', - ]).set('ai',function(){ - var player=_status.event.player; - var suit=get.suit(_status.event.getTrigger().card); - if(player.countCards('h',function(card){ - return get.suit(card)==suit&&player.hasValueTarget(card,null,true); - })) return 'cancel2'; - return 0; - }); - 'step 1' - if(result.control=='cancel2'){ + direct: true, + content: function () { + "step 0"; + player + .chooseControl("cancel2") + .set("prompt", get.prompt("quanbian")) + .set("choiceList", [ + "摸一张牌", + "观看牌堆顶的" + get.cnNumber(player.maxHp) + "张牌并将其中一张置于牌堆底", + ]) + .set("ai", function () { + var player = _status.event.player; + var suit = get.suit(_status.event.getTrigger().card); + if ( + player.countCards("h", function (card) { + return get.suit(card) == suit && player.hasValueTarget(card, null, true); + }) + ) + return "cancel2"; + return 0; + }); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - player.addTempSkill('quanbian2'); + player.addTempSkill("quanbian2"); player.storage.quanbian2.add(get.suit(trigger.card)); - player.markSkill('quanbian2'); - if(result.index==0){ + player.markSkill("quanbian2"); + if (result.index == 0) { player.draw(); event.finish(); return; } - event.cards=get.cards(player.maxHp); - player.chooseButton(['将一张牌置于牌堆底',event.cards],true); - 'step 2' - while(cards.length){ - var card=cards.pop(); + event.cards = get.cards(player.maxHp); + player.chooseButton(["将一张牌置于牌堆底", event.cards], true); + "step 2"; + while (cards.length) { + var card = cards.pop(); card.fix(); - if(card==result.links[0]) ui.cardPile.appendChild(card); - else ui.cardPile.insertBefore(card,ui.cardPile.firstChild); + if (card == result.links[0]) ui.cardPile.appendChild(card); + else ui.cardPile.insertBefore(card, ui.cardPile.firstChild); } game.updateRoundNumber(); }, }, - quanbian2:{ - init:function(player,skill){ - if(!player.storage[skill]) player.storage[skill]=[]; + quanbian2: { + init: function (player, skill) { + if (!player.storage[skill]) player.storage[skill] = []; }, - onremove:true, - mod:{ - cardEnabled2:function(card,player){ - if(get.position(card)=='h'&&player.storage.quanbian2.includes(get.suit(card))) return false; + onremove: true, + mod: { + cardEnabled2: function (card, player) { + if (get.position(card) == "h" && player.storage.quanbian2.includes(get.suit(card))) + return false; }, }, - intro:{ - content:'本回合内不能使用$花色的手牌', + intro: { + content: "本回合内不能使用$花色的手牌", }, }, //卫瓘 - zhongyun:{ - audio:2, - trigger:{player:['damageEnd','recoverEnd']}, - forced:true, - filter:function(event,player){ - return player.hp==player.countCards('h')&&(player.isDamaged()||game.hasPlayer(function(current){ - return player.inRange(current); - })); + zhongyun: { + audio: 2, + trigger: { player: ["damageEnd", "recoverEnd"] }, + forced: true, + filter: function (event, player) { + return ( + player.hp == player.countCards("h") && + (player.isDamaged() || + game.hasPlayer(function (current) { + return player.inRange(current); + })) + ); }, - usable:1, - preHidden:['zhongyun2'], - content:function(){ - 'step 0' - var filterTarget=function(card,player,target){ + usable: 1, + preHidden: ["zhongyun2"], + content: function () { + "step 0"; + var filterTarget = function (card, player, target) { return player.inRange(target); }; - if(game.hasPlayer((current)=>filterTarget('L∞pers',player,current))){ - var bool=player.isHealthy(); - player.chooseTarget('忠允:对攻击范围内的一名角色造成1点伤害'+(bool?'':',或点取消回复1点体力'),filterTarget,bool).set('ai',function(target){ - var player=_status.event.player; - return get.damageEffect(target,player,player); - }); - } - else event._result={bool:false}; - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + if (game.hasPlayer((current) => filterTarget("L∞pers", player, current))) { + var bool = player.isHealthy(); + player + .chooseTarget( + "忠允:对攻击范围内的一名角色造成1点伤害" + + (bool ? "" : ",或点取消回复1点体力"), + filterTarget, + bool + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.damageEffect(target, player, player); + }); + } else event._result = { bool: false }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.damage(); - } - else player.recover(); + } else player.recover(); }, - group:'zhongyun2', + group: "zhongyun2", }, - zhongyun2:{ - audio:'zhongyun', - trigger:{ - player:['loseAfter'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + zhongyun2: { + audio: "zhongyun", + trigger: { + player: ["loseAfter"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - filter:function(event,player){ - var cards1=event.getl(player).hs,cards2=[]; - if(event.getg) cards2=event.getg(player); - return (cards1.length>0||cards2.length>0)&&player.countCards('h')==player.hp; + forced: true, + filter: function (event, player) { + var cards1 = event.getl(player).hs, + cards2 = []; + if (event.getg) cards2 = event.getg(player); + return (cards1.length > 0 || cards2.length > 0) && player.countCards("h") == player.hp; }, - usable:1, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - var filterTarget=function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; - } - if(!game.hasPlayer((current)=>filterTarget('L∞pers',player,current))) event._result={bool:false}; - else player.chooseTarget(filterTarget,'忠允:弃置一名其他角色的一张牌,或点取消摸一张牌').set('ai',function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - return 0; - }); - 'step 1' - if(!result.bool) player.draw(); - else{ - var target=result.targets[0]; - player.line(target,'green'); - player.discardPlayerCard(target,true,'he'); + usable: 1, + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + var filterTarget = function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; + }; + if (!game.hasPlayer((current) => filterTarget("L∞pers", player, current))) + event._result = { bool: false }; + else + player + .chooseTarget(filterTarget, "忠允:弃置一名其他角色的一张牌,或点取消摸一张牌") + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + return 0; + }); + "step 1"; + if (!result.bool) player.draw(); + else { + var target = result.targets[0]; + player.line(target, "green"); + player.discardPlayerCard(target, true, "he"); } }, }, - shenpin:{ - audio:2, - trigger:{global:'judge'}, - filter:function(event,player){ - var color=get.color(event.player.judging[0],event.player); - return player.countCards('hes',function(card){ - if(_status.connectMode&&get.position(card)!='e') return true; - return get.color(card)!=color; - })>0; + shenpin: { + audio: 2, + trigger: { global: "judge" }, + filter: function (event, player) { + var color = get.color(event.player.judging[0], event.player); + return ( + player.countCards("hes", function (card) { + if (_status.connectMode && get.position(card) != "e") return true; + return get.color(card) != color; + }) > 0 + ); }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - var color=get.color(trigger.player.judging[0],trigger.player); - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('shenpin'),'hes',function(card){ - if(get.color(card)==_status.event.color) return false; - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result; - } - else{ - return -result; - } - }).set('judging',trigger.player.judging[0]).set('color',color).setHiddenSkill(event.name); - "step 1" - if(result.bool){ - player.respond(result.cards,'highlight','shenpin','noOrdering'); - } - else{ + direct: true, + preHidden: true, + content: function () { + "step 0"; + var color = get.color(trigger.player.judging[0], trigger.player); + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("shenpin"), + "hes", + function (card) { + if (get.color(card) == _status.event.color) return false; + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result; + } else { + return -result; + } + }) + .set("judging", trigger.player.judging[0]) + .set("color", color) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.respond(result.cards, "highlight", "shenpin", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1 - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, //彻里吉 - chexuan:{ - audio:2, - enable:'phaseUse', - derivation:['cheliji_sichengliangyu','cheliji_tiejixuanyu','cheliji_feilunzhanyu'], - filter:function(event,player){ - return !player.getEquips(5).length&&player.countCards('he',{color:'black'})>0; + chexuan: { + audio: 2, + enable: "phaseUse", + derivation: ["cheliji_sichengliangyu", "cheliji_tiejixuanyu", "cheliji_feilunzhanyu"], + filter: function (event, player) { + return !player.getEquips(5).length && player.countCards("he", { color: "black" }) > 0; }, - filterCard:{color:'black'}, - position:'he', - check:function(card){ - return 5-get.value(card); + filterCard: { color: "black" }, + position: "he", + check: function (card) { + return 5 - get.value(card); }, - content:function(){ - 'step 0' - player.chooseButton(['请选择要装备的宝物',[lib.skill.chexuan.derivation.map(function(i){ - return ['宝物','',i]; - }),'vcard']],true).set('ai',function(button){ - if(button.link[2]=='cheliji_sichengliangyu'&&player.countCards('h')0&&player.getEquip('cheliji_tiejixuanyu'); + cheliji_tiejixuanyu: { + trigger: { global: "phaseJieshuBegin" }, + equipSkill: true, + filter: function (event, player) { + return ( + player != event.player && + !event.player.getHistory("sourceDamage").length && + event.player.countCards("he") > 0 && + player.getEquip("cheliji_tiejixuanyu") + ); }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)<0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - content:function(){ - 'step 0' - trigger.player.chooseToDiscard('he',2,true); - 'step 1' - var card=player.getEquip('cheliji_tiejixuanyu'); - if(card) player.discard(card); + content: function () { + "step 0"; + trigger.player.chooseToDiscard("he", 2, true); + "step 1"; + var card = player.getEquip("cheliji_tiejixuanyu"); + if (card) player.discard(card); }, }, - cheliji_feilunzhanyu:{ - trigger:{global:'phaseJieshuBegin'}, - equipSkill:true, - filter:function(event,player){ - return player!=event.player&&event.player.getHistory('useCard',function(card){ - return get.type(card.card)!='basic'; - }).length>0&&event.player.countCards('he')>0&&player.getEquip('cheliji_feilunzhanyu'); + cheliji_feilunzhanyu: { + trigger: { global: "phaseJieshuBegin" }, + equipSkill: true, + filter: function (event, player) { + return ( + player != event.player && + event.player.getHistory("useCard", function (card) { + return get.type(card.card) != "basic"; + }).length > 0 && + event.player.countCards("he") > 0 && + player.getEquip("cheliji_feilunzhanyu") + ); }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)<=0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) <= 0; }, - content:function(){ - 'step 0' - trigger.player.chooseCard('he',true,'将一张牌交给'+get.translation(player)); - 'step 1' - if(result.bool) trigger.player.give(result.cards,player); - 'step 2' - var card=player.getEquip('cheliji_feilunzhanyu'); - if(card) player.discard(card); + content: function () { + "step 0"; + trigger.player.chooseCard("he", true, "将一张牌交给" + get.translation(player)); + "step 1"; + if (result.bool) trigger.player.give(result.cards, player); + "step 2"; + var card = player.getEquip("cheliji_feilunzhanyu"); + if (card) player.discard(card); }, }, //司马伷和黄祖 - caiwang:{ - audio:2, - trigger:{global:['useCard','respond']}, - preHidden:true, - filter:function(event,player){ - if(!Array.isArray(event.respondTo)||event.respondTo[0]==event.player||![event.respondTo[0],event.player].includes(player)) return false; - var color=get.color(event.card); - if(color=='none'||get.color(event.respondTo[1])!=color) return false; - var target=lib.skill.caiwang.logTarget(event,player); - return target[player.getStorage('naxiang2').includes(target)?'countGainableCards':'countDiscardableCards'](player,'he')>0 + caiwang: { + audio: 2, + trigger: { global: ["useCard", "respond"] }, + preHidden: true, + filter: function (event, player) { + if ( + !Array.isArray(event.respondTo) || + event.respondTo[0] == event.player || + ![event.respondTo[0], event.player].includes(player) + ) + return false; + var color = get.color(event.card); + if (color == "none" || get.color(event.respondTo[1]) != color) return false; + var target = lib.skill.caiwang.logTarget(event, player); + return ( + target[ + player.getStorage("naxiang2").includes(target) + ? "countGainableCards" + : "countDiscardableCards" + ](player, "he") > 0 + ); }, - logTarget:function(event,player){ - return (player==event.respondTo[0]?event.player:event.respondTo[0]); + logTarget: function (event, player) { + return player == event.respondTo[0] ? event.player : event.respondTo[0]; }, - prompt2:function(event,player){ - var target=lib.skill.caiwang.logTarget(event,player); - return (player.getStorage('naxiang2').includes(target)?'获得':'弃置')+'该角色的一张牌'; + prompt2: function (event, player) { + var target = lib.skill.caiwang.logTarget(event, player); + return ( + (player.getStorage("naxiang2").includes(target) ? "获得" : "弃置") + "该角色的一张牌" + ); }, - check:function(event,player){ - return get.attitude(player,lib.skill.caiwang.logTarget(event,player))<=0; + check: function (event, player) { + return get.attitude(player, lib.skill.caiwang.logTarget(event, player)) <= 0; }, - popup:false, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isOnline()) game.delayx(); - 'step 1' - var target=lib.skill.caiwang.logTarget(trigger,player); - player.logSkill(event.name,target); - player[player.getStorage('naxiang2').includes(target)?'gainPlayerCard':'discardPlayerCard'](target,'he',true); + popup: false, + content: function () { + "step 0"; + if (player != game.me && !player.isOnline()) game.delayx(); + "step 1"; + var target = lib.skill.caiwang.logTarget(trigger, player); + player.logSkill(event.name, target); + player[ + player.getStorage("naxiang2").includes(target) + ? "gainPlayerCard" + : "discardPlayerCard" + ](target, "he", true); }, }, - naxiang:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + naxiang: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - preHidden:true, - filter:function(event,player){ - var target=lib.skill.naxiang.logTarget(event,player); - return target&&target!=player&&target.isAlive(); + forced: true, + preHidden: true, + filter: function (event, player) { + var target = lib.skill.naxiang.logTarget(event, player); + return target && target != player && target.isAlive(); }, - logTarget:function(event,player){ - return player==event.player?event.source:event.player; + logTarget: function (event, player) { + return player == event.player ? event.source : event.player; }, - content:function(){ - player.addTempSkill('naxiang2',{player:'phaseBegin'}); - if(!player.storage.naxiang2) player.storage.naxiang2=[]; - player.storage.naxiang2.add(lib.skill.naxiang.logTarget(trigger,player)); - player.markSkill('naxiang2'); + content: function () { + player.addTempSkill("naxiang2", { player: "phaseBegin" }); + if (!player.storage.naxiang2) player.storage.naxiang2 = []; + player.storage.naxiang2.add(lib.skill.naxiang.logTarget(trigger, player)); + player.markSkill("naxiang2"); }, - ai:{ - combo:'caiwang', + ai: { + combo: "caiwang", }, }, - naxiang2:{ - onremove:true, - intro:{ - content:'已接受$的投降;对这些角色发动【才望】时将“弃置”改为“获得”', + naxiang2: { + onremove: true, + intro: { + content: "已接受$的投降;对这些角色发动【才望】时将“弃置”改为“获得”", }, }, //李肃 - qiaoyan:{ - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - return player!=_status.currentPhase&&event.source&&event.source!=player; + qiaoyan: { + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + return player != _status.currentPhase && event.source && event.source != player; }, - logTarget:'source', - content:function(){ - 'step 0' - var cards=player.getExpansions('qiaoyan'); - if(cards.length){ - var source=trigger.source; - source.gain(cards,player,'give','bySelf'); + logTarget: "source", + content: function () { + "step 0"; + var cards = player.getExpansions("qiaoyan"); + if (cards.length) { + var source = trigger.source; + source.gain(cards, player, "give", "bySelf"); event.finish(); - } - else{ + } else { trigger.cancel(); player.draw(); } - 'step 1' - var hs=player.getCards('he'); - if(!hs.length) event.finish(); - else if(hs.length==1) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'将一张牌作为“珠”置于武将牌上'); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - var cards=result.cards; - player.addToExpansion(cards,player,'give').gaintag.add('qiaoyan'); + "step 1"; + var hs = player.getCards("he"); + if (!hs.length) event.finish(); + else if (hs.length == 1) event._result = { bool: true, cards: hs }; + else player.chooseCard("he", true, "将一张牌作为“珠”置于武将牌上"); + "step 2"; + if (result.bool && result.cards && result.cards.length) { + var cards = result.cards; + player.addToExpansion(cards, player, "give").gaintag.add("qiaoyan"); } event.finish(); }, - marktext:'珠', - intro:{content:'expansion',markcount:'expansion'}, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "珠", + intro: { content: "expansion", markcount: "expansion" }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(!player.getExpansions('qiaoyan').length) return false; - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (!player.getExpansions("qiaoyan").length) return false; + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, - combo:'xianzhu', }, }, - xianzhu:{ - trigger:{player:'phaseUseBegin'}, - locked:true, - filter:function(event,player){ - return player.getExpansions('qiaoyan').length>0; + xianzhu: { + trigger: { player: "phaseUseBegin" }, + locked: true, + filter: function (event, player) { + return player.getExpansions("qiaoyan").length > 0; }, - async cost(event, trigger, player){ - event.cards = player.getExpansions('qiaoyan'); - event.result = await player.chooseTarget(true,'请选择【献珠】的目标','将'+get.translation(event.cards)+'交给一名角色。若该角色不为你自己,则你令其视为对其攻击范围内的另一名角色使用【杀】').set('ai',function(target){ - var player=_status.event.player; - var eff=get.sgn(get.attitude(player,target))*get.value(_status.event.getParent().cards[0],target); - if(player!=target) eff+=Math.max.apply(null,game.filterPlayer(function(current){ - if(current!=target&&player.inRange(current)&&target.canUse('sha',current,false)) return true; - }).map(function(current){ - return get.effect(current,{name:'sha'},target,player); - })); - return eff; - }).forResult(); + async cost(event, trigger, player) { + event.cards = player.getExpansions("qiaoyan"); + event.result = await player + .chooseTarget( + true, + "请选择【献珠】的目标", + "将" + + get.translation(event.cards) + + "交给一名角色。若该角色不为你自己,则你令其视为对其攻击范围内的另一名角色使用【杀】" + ) + .set("ai", function (target) { + var player = _status.event.player; + var eff = + get.sgn(get.attitude(player, target)) * + get.value(_status.event.getParent().cards[0], target); + if (player != target) + eff += Math.max.apply( + null, + game + .filterPlayer(function (current) { + if ( + current != target && + player.inRange(current) && + target.canUse("sha", current, false) + ) + return true; + }) + .map(function (current) { + return get.effect(current, { name: "sha" }, target, player); + }) + ); + return eff; + }) + .forResult(); }, - content:function(){ - 'step 0' - event.cards = player.getExpansions('qiaoyan'); - event.target = targets[0]; - 'step 1' - player.give(cards,target,'give'); - 'step 2' - if(player!=target&&target.isIn()&&player.isIn()&&game.hasPlayer(function(current){ - return current!=target&&player.inRange(current)&&target.canUse('sha',current,false); - })){ - var str=get.translation(target); - player.chooseTarget(true,'选择攻击范围内的一名角色,视为'+str+'对其使用【杀】',function(card,player,target){ - var source=_status.event.target; - return player.inRange(target)&&source.canUse('sha', target, false); - }).set('target',target).set('ai',function(target){ - var evt=_status.event; - return get.effect(target,{name:'sha'},evt.target,evt.player) + content: function () { + "step 0"; + event.cards = player.getExpansions("qiaoyan"); + event.target = targets[0]; + "step 1"; + player.give(cards, target, "give"); + "step 2"; + if ( + player != target && + target.isIn() && + player.isIn() && + game.hasPlayer(function (current) { + return ( + current != target && + player.inRange(current) && + target.canUse("sha", current, false) + ); + }) + ) { + var str = get.translation(target); + player + .chooseTarget( + true, + "选择攻击范围内的一名角色,视为" + str + "对其使用【杀】", + function (card, player, target) { + var source = _status.event.target; + return player.inRange(target) && source.canUse("sha", target, false); + } + ) + .set("target", target) + .set("ai", function (target) { + var evt = _status.event; + return get.effect(target, { name: "sha" }, evt.target, evt.player); + }); + } else event.finish(); + "step 3"; + if (result.bool) target.useCard({ name: "sha", isCard: true }, result.targets[0], false); + }, + ai: { combo: "qiaoyan" }, + }, + huirong: { + trigger: { player: "showCharacterAfter" }, + forced: true, + filter: function (event, player) { + return ( + event.toShow && + event.toShow.includes("jin_yanghuiyu") && + game.hasPlayer(function (target) { + var num = target.countCards("h"); + return num > target.hp || num < Math.min(5, target.hp); + }) + ); + }, + hiddenSkill: true, + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【慧容】的目标", + "令一名角色将手牌数摸至/弃置至与其体力值相同(至多摸至五张)", + true, + function (card, player, target) { + var num = target.countCards("h"); + return num > target.hp || num < Math.min(5, target.hp); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + var num = target.countCards("h"); + if (num > target.hp) return -att * (num - target.hp); + return att * Math.max(0, Math.min(5, target.hp) - target.countCards("h")); }); - } - else event.finish(); - 'step 3' - if(result.bool) target.useCard({name:'sha',isCard:true},result.targets[0],false); - }, - ai:{combo:'qiaoyan'}, - }, - huirong:{ - trigger:{player:'showCharacterAfter'}, - forced:true, - filter:function(event,player){ - return event.toShow&&event.toShow.includes('jin_yanghuiyu')&&game.hasPlayer(function(target){ - var num=target.countCards('h'); - return num>target.hp||numtarget.hp||numtarget.hp) return -att*(num-target.hp); - return att*Math.max(0,Math.min(5,target.hp)-target.countCards('h')); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - if(target.countCards('h'){ - game.addGlobalSkill('ciwei_ai'); + ciwei: { + init: () => { + game.addGlobalSkill("ciwei_ai"); }, - onremove:()=>{ - if(!game.hasPlayer(i=>i.hasSkill('ciwei'),true)) game.removeGlobalSkill('ciwei_ai'); + onremove: () => { + if (!game.hasPlayer((i) => i.hasSkill("ciwei"), true)) game.removeGlobalSkill("ciwei_ai"); }, - trigger:{global:'useCard'}, - direct:true, - preHidden:true, - filter:function(event,player){ - if(event.all_excluded||event.player==player||event.player!=_status.currentPhase||!player.countCards('he')) return false; - return event.player.getHistory('useCard').indexOf(event)==1&&['basic','trick'].includes(get.type(event.card)); + trigger: { global: "useCard" }, + direct: true, + preHidden: true, + filter: function (event, player) { + if ( + event.all_excluded || + event.player == player || + event.player != _status.currentPhase || + !player.countCards("he") + ) + return false; + return ( + event.player.getHistory("useCard").indexOf(event) == 1 && + ["basic", "trick"].includes(get.type(event.card)) + ); }, - content:function(){ - 'step 0' - if(player!=game.me&&!player.isOnline()) game.delayx(); - player.chooseToDiscard(get.prompt('ciwei',trigger.player),'弃置一张牌,取消'+get.translation(trigger.card)+'的所有目标','he').set('ai',function(card){ - return (_status.event.goon/1.4)-get.value(card); - }).set('goon',function(){ - if(!trigger.targets.length) return -get.attitude(player,trigger.player); - var num=0; - for(var i of trigger.targets){ - num-=get.effect(i,trigger.card,trigger.player,player) - } - return num; - }()).setHiddenSkill(event.name).logSkill=['ciwei',trigger.player]; - 'step 1' - if(result.bool){ - trigger.targets.length=0; - trigger.all_excluded=true; + content: function () { + "step 0"; + if (player != game.me && !player.isOnline()) game.delayx(); + player + .chooseToDiscard( + get.prompt("ciwei", trigger.player), + "弃置一张牌,取消" + get.translation(trigger.card) + "的所有目标", + "he" + ) + .set("ai", function (card) { + return _status.event.goon / 1.4 - get.value(card); + }) + .set( + "goon", + (function () { + if (!trigger.targets.length) return -get.attitude(player, trigger.player); + var num = 0; + for (var i of trigger.targets) { + num -= get.effect(i, trigger.card, trigger.player, player); + } + return num; + })() + ) + .setHiddenSkill(event.name).logSkill = ["ciwei", trigger.player]; + "step 1"; + if (result.bool) { + trigger.targets.length = 0; + trigger.all_excluded = true; } - } + }, }, - ciwei_ai:{ - mod:{ - aiOrder:function(player,card,num){ - if(player!=_status.currentPhase||player.getHistory('useCard').length>1||!game.hasPlayer(function(current){ - return current!=player&&(get.realAttitude||get.attitude)(current,player)<0&¤t.hasSkill('ciwei')&¤t.countCards('he')>0; - })) return; - if(player.getHistory('useCard').length==0){ - if(['basic','trick'].includes(get.type(card))) return num+10; + ciwei_ai: { + mod: { + aiOrder: function (player, card, num) { + if ( + player != _status.currentPhase || + player.getHistory("useCard").length > 1 || + !game.hasPlayer(function (current) { + return ( + current != player && + (get.realAttitude || get.attitude)(current, player) < 0 && + current.hasSkill("ciwei") && + current.countCards("he") > 0 + ); + }) + ) + return; + if (player.getHistory("useCard").length == 0) { + if (["basic", "trick"].includes(get.type(card))) return num + 10; return; } - if(!['basic','trick'].includes(get.type(card))) return num+10; - if(!player._ciwei_temp){ - player._ciwei_temp=true; - num/=Math.max(1,player.getUseValue(card)); + if (!["basic", "trick"].includes(get.type(card))) return num + 10; + if (!player._ciwei_temp) { + player._ciwei_temp = true; + num /= Math.max(1, player.getUseValue(card)); } delete player._ciwei_temp; return num; }, }, - trigger:{player:'dieAfter'}, - filter:()=>{ - return !game.hasPlayer(i=>i.hasSkill('ciwei'),true); + trigger: { player: "dieAfter" }, + filter: () => { + return !game.hasPlayer((i) => i.hasSkill("ciwei"), true); + }, + silent: true, + forceDie: true, + content: () => { + game.removeGlobalSkill("ciwei_ai"); }, - silent:true, - forceDie:true, - content:()=>{ - game.removeGlobalSkill('ciwei_ai'); - } }, - caiyuan:{ - trigger:{player:'phaseEnd'}, - forced:true, - preHidden:true, - filter:function(event,player){ - if(player.phaseNumber<=1) return false; - const history1=_status.globalHistory,history2=player.actionHistory; - for(let i=0;i0&&history2[i2].isMe) break; - if(history1[i1].changeHp.some(evt=>evt.player==player&&evt.num<0)) return false; + caiyuan: { + trigger: { player: "phaseEnd" }, + forced: true, + preHidden: true, + filter: function (event, player) { + if (player.phaseNumber <= 1) return false; + const history1 = _status.globalHistory, + history2 = player.actionHistory; + for (let i = 0; i < Math.min(history1.length, history2.length); i++) { + let i1 = history1.length - 1 - i, + i2 = history2.length - 1 - i; + if (i > 0 && history2[i2].isMe) break; + if (history1[i1].changeHp.some((evt) => evt.player == player && evt.num < 0)) + return false; } return true; }, - content:function(){ + content: function () { player.draw(2); }, }, - zhuosheng:{ - audio:2, - locked:false, - init:function(player){ - player.addSkill('zhuosheng_count'); - if(game.phaseNumber>0){ - var hs=player.getCards('h'),all=player.getAllHistory(),cards=[]; - for(var i=all.length-1;i>=0;i--){ - for(var j of all[i].gain){ + zhuosheng: { + audio: 2, + locked: false, + init: function (player) { + player.addSkill("zhuosheng_count"); + if (game.phaseNumber > 0) { + var hs = player.getCards("h"), + all = player.getAllHistory(), + cards = []; + for (var i = all.length - 1; i >= 0; i--) { + for (var j of all[i].gain) { cards.addArray(j.cards); } - if(all[i].isRound) break; + if (all[i].isRound) break; } - cards=cards.filter(function(i){ + cards = cards.filter(function (i) { return hs.includes(i); }); - if(cards.length) player.addGaintag(cards,'zhuosheng'); + if (cards.length) player.addGaintag(cards, "zhuosheng"); } }, - onremove:function(player){ - player.removeSkill('zhuosheng_count'); - player.removeGaintag('zhuosheng'); + onremove: function (player) { + player.removeSkill("zhuosheng_count"); + player.removeGaintag("zhuosheng"); }, - mod:{ - targetInRange:function(card,player,target){ - if(!card.cards||get.type(card)!='basic') return; - for(var i of card.cards){ - if(i.hasGaintag('zhuosheng')) return (game.online?player==_status.currentPhase:player.isPhaseUsing()); + mod: { + targetInRange: function (card, player, target) { + if (!card.cards || get.type(card) != "basic") return; + for (var i of card.cards) { + if (i.hasGaintag("zhuosheng")) + return game.online ? player == _status.currentPhase : player.isPhaseUsing(); } }, - cardUsable:function(card,player,target){ - if(!card.cards||get.mode()=='guozhan'||get.type(card)!='basic'||!(game.online?player==_status.currentPhase:player.isPhaseUsing())) return; - for(var i of card.cards){ - if(i.hasGaintag('zhuosheng')) return Infinity; + cardUsable: function (card, player, target) { + if ( + !card.cards || + get.mode() == "guozhan" || + get.type(card) != "basic" || + !(game.online ? player == _status.currentPhase : player.isPhaseUsing()) + ) + return; + for (var i of card.cards) { + if (i.hasGaintag("zhuosheng")) return Infinity; } }, - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('zhuosheng')&&get.type(card)=='basic') return num-0.1; + aiOrder: function (player, card, num) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("zhuosheng") && + get.type(card) == "basic" + ) + return num - 0.1; }, }, - trigger:{player:'useCard2'}, - direct:true, - filterx:function(event,player){ - if(!player.isPhaseUsing()) return false; - return player.getHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('zhuosheng')) return true; - } - return false; - }).length>0; + trigger: { player: "useCard2" }, + direct: true, + filterx: function (event, player) { + if (!player.isPhaseUsing()) return false; + return ( + player.getHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("zhuosheng")) return true; + } + return false; + }).length > 0 + ); }, - filter:function(event,player){ - if(!lib.skill.zhuosheng.filterx(event,player)) return false; - if(get.type(event.card)!='trick') return false; - if(event.targets&&event.targets.length>0) return true; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + filter: function (event, player) { + if (!lib.skill.zhuosheng.filterx(event, player)) return false; + if (get.type(event.card) != "trick") return false; + if (event.targets && event.targets.length > 0) return true; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加或减少一个目标' - player.chooseTarget(get.prompt('zhuosheng'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return true; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加或减少一个目标"; + player + .chooseTarget(get.prompt("zhuosheng"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return true; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('zhuosheng',event.targets); - if(trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets); + "step 2"; + if (event.targets) { + player.logSkill("zhuosheng", event.targets); + if (trigger.targets.includes(event.targets[0])) + trigger.targets.removeArray(event.targets); else trigger.targets.addArray(event.targets); } }, - group:['zhuosheng_equip','zhuosheng_silent'], - subfrequent:['equip'], - subSkill:{ - equip:{ - audio:'zhuosheng', - trigger:{player:'useCard'}, - filter:function(event,player){ - return get.type(event.card)=='equip'&&lib.skill.zhuosheng.filterx(event,player); + group: ["zhuosheng_equip", "zhuosheng_silent"], + subfrequent: ["equip"], + subSkill: { + equip: { + audio: "zhuosheng", + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + get.type(event.card) == "equip" && lib.skill.zhuosheng.filterx(event, player) + ); }, - frequent:true, - prompt:'是否发动【擢升】摸一张牌?', - content:function(){ + frequent: true, + prompt: "是否发动【擢升】摸一张牌?", + content: function () { player.draw(); }, }, - silent:{ - trigger:{ - player:'useCard1', + silent: { + trigger: { + player: "useCard1", }, - silent:true, - firstDo:true, - filter:function(event,player){ - return get.mode()!='guozhan'&&get.type(event.card)=='basic'&&lib.skill.zhuosheng.filterx(event,player)&&event.addCount!==false; + silent: true, + firstDo: true, + filter: function (event, player) { + return ( + get.mode() != "guozhan" && + get.type(event.card) == "basic" && + lib.skill.zhuosheng.filterx(event, player) && + event.addCount !== false + ); }, - content:function(){ - trigger.addCount=false; - var stat=player.getStat(); - if(stat&&stat.card&&stat.card[trigger.card.name]) stat.card[trigger.card.name]--; + content: function () { + trigger.addCount = false; + var stat = player.getStat(); + if (stat && stat.card && stat.card[trigger.card.name]) + stat.card[trigger.card.name]--; }, }, }, }, - zhuosheng_count:{ - trigger:{ - player:'gainBegin', - global:'roundStart', + zhuosheng_count: { + trigger: { + player: "gainBegin", + global: "roundStart", }, - silent:true, - filter:function(event,player){ - if(event.name=='gain') return event.getParent(2).name!='zhuosheng_equip'; - return game.roundNumber>1; + silent: true, + filter: function (event, player) { + if (event.name == "gain") return event.getParent(2).name != "zhuosheng_equip"; + return game.roundNumber > 1; }, - content:function(){ - if(trigger.name=='gain') trigger.gaintag.add('zhuosheng'); - else player.removeGaintag('zhuosheng'); + content: function () { + if (trigger.name == "gain") trigger.gaintag.add("zhuosheng"); + else player.removeGaintag("zhuosheng"); }, }, - xinquanbian:{ - audio:'quanbian', - preHidden:true, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - var phase=event.getParent('phaseUse'); - if(!phase||phase.player!=player) return false; - var suit=get.suit(event.card); - if(!lib.suit.includes(suit)||!lib.skill.quanbian.hasHand(event)) return false; - return player.getHistory('useCard',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length+player.getHistory('respond',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length==0; + xinquanbian: { + audio: "quanbian", + preHidden: true, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + var phase = event.getParent("phaseUse"); + if (!phase || phase.player != player) return false; + var suit = get.suit(event.card); + if (!lib.suit.includes(suit) || !lib.skill.quanbian.hasHand(event)) return false; + return ( + player.getHistory("useCard", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length + + player.getHistory("respond", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length == + 0 + ); }, - content:function(){ - 'step 0' - var cards=get.cards(Math.min(5,player.maxHp)); + content: function () { + "step 0"; + var cards = get.cards(Math.min(5, player.maxHp)); game.cardsGotoOrdering(cards); - var suit=get.suit(trigger.card); - var next=player.chooseToMove('权变:获得一张不为'+get.translation(suit)+'花色的牌并排列其他牌'); - next.set('suit',suit); - next.set('list',[ - ['牌堆顶',cards], - ['获得'], - ]) - next.set('filterMove',function(from,to,moved){ - var suit=_status.event.suit; - if(moved[0].includes(from.link)){ - if(typeof to=='number'){ - if(to==1){ - if(moved[1].length) return false; - return get.suit(from.link,false)!=suit; + var suit = get.suit(trigger.card); + var next = player.chooseToMove( + "权变:获得一张不为" + get.translation(suit) + "花色的牌并排列其他牌" + ); + next.set("suit", suit); + next.set("list", [["牌堆顶", cards], ["获得"]]); + next.set("filterMove", function (from, to, moved) { + var suit = _status.event.suit; + if (moved[0].includes(from.link)) { + if (typeof to == "number") { + if (to == 1) { + if (moved[1].length) return false; + return get.suit(from.link, false) != suit; } return true; } - if(moved[1].includes(to.link)) return get.suit(from.link,false)!=suit; + if (moved[1].includes(to.link)) return get.suit(from.link, false) != suit; return true; - } - else{ - if(typeof to=='number') return true; - return get.suit(to.link,false)!=suit; + } else { + if (typeof to == "number") return true; + return get.suit(to.link, false) != suit; } }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.value(a); - }),gains=[]; - for(var i of cards){ - if(get.suit(i,false)!=_status.event.suit){ + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.value(a); + }), + gains = []; + for (var i of cards) { + if (get.suit(i, false) != _status.event.suit) { cards.remove(i); gains.push(i); break; } } - return [cards,gains]; + return [cards, gains]; }); - 'step 1' - if(result.bool){ - var list=result.moved; - if(list[1].length) player.gain(list[1],'gain2'); - while(list[0].length){ - ui.cardPile.insertBefore(list[0].pop(),ui.cardPile.firstChild); + "step 1"; + if (result.bool) { + var list = result.moved; + if (list[1].length) player.gain(list[1], "gain2"); + while (list[0].length) { + ui.cardPile.insertBefore(list[0].pop(), ui.cardPile.firstChild); } game.updateRoundNumber(); } }, //group:'xinquanbian_count', - init:(player,skill)=>player.addSkill('xinquanbian_count'), - onremove:(player,skill)=>player.removeSkill('xinquanbian_count'), + init: (player, skill) => player.addSkill("xinquanbian_count"), + onremove: (player, skill) => player.removeSkill("xinquanbian_count"), }, - xinquanbian_count:{ - trigger:{ - player:['useCard0','phaseUseBefore','phaseUseAfter'] + xinquanbian_count: { + trigger: { + player: ["useCard0", "phaseUseBefore", "phaseUseAfter"], }, - silent:true, - firstDo:true, - charlotte:true, - filter:function(event,player){ - if (event.name === 'phaseUse') return true; - return player.isPhaseUsing()&&lib.skill.quanbian.hasHand(event)&&get.type(event.card)!='equip'; + silent: true, + firstDo: true, + charlotte: true, + filter: function (event, player) { + if (event.name === "phaseUse") return true; + return ( + player.isPhaseUsing() && + lib.skill.quanbian.hasHand(event) && + get.type(event.card) != "equip" + ); }, - content:function(){ - var stat=player.getStat('skill'); - if (this.trigger.name === 'phaseUse') { + content: function () { + var stat = player.getStat("skill"); + if (this.trigger.name === "phaseUse") { delete stat.xinquanbian; - } - else{ - if(!stat.xinquanbian) stat.xinquanbian=0; + } else { + if (!stat.xinquanbian) stat.xinquanbian = 0; stat.xinquanbian++; } }, - mod:{ - cardEnabled2:function(card,player){ - var stat=player.getStat('skill'); - if(stat.xinquanbian&&stat.xinquanbian>=player.maxHp&&get.position(card)=='h'&&get.type(card,player)!='equip') return false; + mod: { + cardEnabled2: function (card, player) { + var stat = player.getStat("skill"); + if ( + stat.xinquanbian && + stat.xinquanbian >= player.maxHp && + get.position(card) == "h" && + get.type(card, player) != "equip" + ) + return false; }, }, }, - taoyin:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - hiddenSkill:true, - logTarget:function(){ + taoyin: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + hiddenSkill: true, + logTarget: function () { return _status.currentPhase; }, - filter:function(event,player){ - var target=_status.currentPhase; - return target&&target!=player&&target.isAlive(); + filter: function (event, player) { + var target = _status.currentPhase; + return target && target != player && target.isAlive(); }, - check:function(event,player){ - return get.attitude(player,_status.currentPhase)<0; + check: function (event, player) { + return get.attitude(player, _status.currentPhase) < 0; }, - content:function(){ - _status.currentPhase.addTempSkill('taoyin2'); - _status.currentPhase.addMark('taoyin2',2,false); + content: function () { + _status.currentPhase.addTempSkill("taoyin2"); + _status.currentPhase.addMark("taoyin2", 2, false); }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, }, - taoyin2:{ - onremove:true, - charlotte:true, - intro:{ - content:'手牌上限-#', + taoyin2: { + onremove: true, + charlotte: true, + intro: { + content: "手牌上限-#", }, - mod:{ - maxHandcard:function(player,num){ - return num-player.countMark('taoyin2'); + mod: { + maxHandcard: function (player, num) { + return num - player.countMark("taoyin2"); }, }, }, - yimie:{ - audio:2, - usable:1, - preHidden:true, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return player!=event.player&&event.num= -2 || Math.abs(hp) <= 1) return false; - if(hp > 2 || eff > 0 && event.player.isLinked() && event.hasNature()) return true; - return !event.player.countCards('hs') || event.player.hp > 2 * event.num && !event.player.hasSkillTag('maixie'); + if (player.storage.tairan2) hp -= player.storage.tairan2; + if (eff <= 0 || fd || att >= -2 || Math.abs(hp) <= 1) return false; + if (hp > 2 || (eff > 0 && event.player.isLinked() && event.hasNature())) return true; + return ( + !event.player.countCards("hs") || + (event.player.hp > 2 * event.num && !event.player.hasSkillTag("maixie")) + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { player.loseHp(); - trigger.player.addTempSkill('yimie2'); - trigger.yimie_num=trigger.player.hp-trigger.num; - trigger.num=trigger.player.hp; + trigger.player.addTempSkill("yimie2"); + 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 + ); + }, }, - 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'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return typeof event.yimie_num=='number'; + yimie2: { + trigger: { player: "damageEnd" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return typeof event.yimie_num == "number"; }, - content:function(){ + content: function () { player.recover(trigger.yimie_num); }, }, - ruilve:{ - unique:true, - audio:2, - global:'ruilve2', - zhuSkill:true, + ruilve: { + unique: true, + audio: 2, + global: "ruilve2", + zhuSkill: true, }, - ruilve2:{ - enable:'phaseUse', - discard:false, - lose:false, - delay:false, - line:true, - log:false, - prepare:function(cards,player,targets){ - targets[0].logSkill('ruilve'); + ruilve2: { + enable: "phaseUse", + discard: false, + lose: false, + delay: false, + line: true, + log: false, + prepare: function (cards, player, targets) { + targets[0].logSkill("ruilve"); }, - prompt:function(){ - var player=_status.event.player; - var list=game.filterPlayer(function(target){ - return target!=player&&target.hasZhuSkill('ruilve',player); + prompt: function () { + var player = _status.event.player; + var list = game.filterPlayer(function (target) { + return target != player && target.hasZhuSkill("ruilve", player); }); - var str='将一张具有伤害标签的基本牌或锦囊牌交给'+get.translation(list); - if(list.length>1) str+='中的一人'; + var str = "将一张具有伤害标签的基本牌或锦囊牌交给" + get.translation(list); + if (list.length > 1) str += "中的一人"; return str; }, - filter:function(event,player){ - if(player.group!='jin') return false; - if(player.countCards('h',lib.skill.ruilve2.filterCard)==0) return false; - return game.hasPlayer(function(target){ - return target!=player&&target.hasZhuSkill('ruilve',player)&&!target.hasSkill('ruilve3'); + filter: function (event, player) { + if (player.group != "jin") return false; + if (player.countCards("h", lib.skill.ruilve2.filterCard) == 0) return false; + return game.hasPlayer(function (target) { + return ( + target != player && + target.hasZhuSkill("ruilve", player) && + !target.hasSkill("ruilve3") + ); }); }, - filterCard:function(card){ - if(!get.tag(card,'damage')) return false; - var type=get.type(card); - return (type=='basic'||type=='trick'); + filterCard: function (card) { + if (!get.tag(card, "damage")) return false; + var type = get.type(card); + return type == "basic" || type == "trick"; }, - visible:true, - filterTarget:function(card,player,target){ - return target!=player&&target.hasZhuSkill('ruilve',player)&&!target.hasSkill('ruilve3'); + visible: true, + filterTarget: function (card, player, target) { + return ( + target != player && + target.hasZhuSkill("ruilve", player) && + !target.hasSkill("ruilve3") + ); }, - content:function(){ - player.give(cards,target); - target.addTempSkill('ruilve3','phaseUseEnd'); + content: function () { + player.give(cards, target); + target.addTempSkill("ruilve3", "phaseUseEnd"); + }, + ai: { + expose: 0.3, + order: 1, + result: { + target: 5, + }, }, - ai:{ - expose:0.3, - order:1, - result:{ - target:5 - } - } }, - ruilve3:{}, - tairan:{ - audio:2, - trigger:{player:'phaseEnd'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return player.hp0){ - player.storage.tairan2=num; + content: function () { + "step 0"; + player.addSkill("tairan2"); + if (!player.storage.tairan2) player.storage.tairan2 = 0; + var num = player.maxHp - player.hp; + if (num > 0) { + player.storage.tairan2 = num; player.recover(num); } - 'step 1' - if(player.countCards('h')0) player.loseHp(map); - var hs=player.getCards('h',function(card){ - return card.hasGaintag('tairan'); + audio: "tairan", + trigger: { player: "phaseUseBegin" }, + charlotte: true, + forced: true, + onremove: true, + content: function () { + var map = player.storage.tairan2; + if (map > 0) player.loseHp(map); + var hs = player.getCards("h", function (card) { + return card.hasGaintag("tairan"); }); - if(hs.length) player.discard(hs); - player.removeSkill('tairan2'); + if (hs.length) player.discard(hs); + player.removeSkill("tairan2"); }, }, - baoqie:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - forced:true, - hiddenSkill:true, - filter:function(event,player){ - return event.toShow&&event.toShow.includes('jin_xiahouhui'); + baoqie: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + forced: true, + hiddenSkill: true, + filter: function (event, player) { + return event.toShow && event.toShow.includes("jin_xiahouhui"); }, - content:function(){ - 'step 0' - var card=get.cardPile(function(card){ - return get.subtype(card,false)=='equip5'&&!get.cardtag(card,'gifts'); + content: function () { + "step 0"; + var card = get.cardPile(function (card) { + return get.subtype(card, false) == "equip5" && !get.cardtag(card, "gifts"); }); - if(!card){ + if (!card) { event.finish(); return; } - event.card=card; - player.gain(card,'gain2'); - 'step 1' - if(player.getCards('h').includes(card)&&get.subtype(card)=='equip5') player.chooseUseTarget(card).nopopup=true; + event.card = card; + player.gain(card, "gain2"); + "step 1"; + if (player.getCards("h").includes(card) && get.subtype(card) == "equip5") + player.chooseUseTarget(card).nopopup = true; }, }, - jyishi:{ - audio:2, - trigger:{ - global:['loseAfter','loseAsyncAfter'], + jyishi: { + audio: 2, + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - usable:1, - direct:true, - preHidden:true, - filter:function(event,player){ - var target=_status.currentPhase; - if(!target||!target.isIn()||event.type!='discard'||!target.isPhaseUsing()) return false; - if(target==player) return false; - var evt=event.getl(target); - for(var i of evt.hs){ - if(get.position(i,true)=='d') return true; + usable: 1, + direct: true, + preHidden: true, + filter: function (event, player) { + var target = _status.currentPhase; + if (!target || !target.isIn() || event.type != "discard" || !target.isPhaseUsing()) + return false; + if (target == player) return false; + var evt = event.getl(target); + for (var i of evt.hs) { + if (get.position(i, true) == "d") return true; } return false; }, - content:function(){ - 'step 0' - event.target=_status.currentPhase; - event.cards=trigger.getl(event.target).hs.filterInD('d'); - var str='是否发动【宜室】令'+get.translation(event.target)+'获得一张牌'; - if(event.cards.length>1) str+=',然后获得其余的牌'; - str+='?'; - player.chooseButton([str,event.cards]).set('ai',function(button){ - var card=button.link; - var source=_status.event.source; - if(get.attitude(player,source)>0) return Math.max(1,source.getUseValue(card,null,true)); - var cards=_status.event.getParent().cards.slice(0); - if(cards.length==1) return -get.value(card); - cards.remove(card); - return (get.value(cards)-get.value(card)-2); - }).set('source',event.target).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.logSkill('jyishi',target); - if(cards.length>1){ + content: function () { + "step 0"; + event.target = _status.currentPhase; + event.cards = trigger.getl(event.target).hs.filterInD("d"); + var str = "是否发动【宜室】令" + get.translation(event.target) + "获得一张牌"; + if (event.cards.length > 1) str += ",然后获得其余的牌"; + str += "?"; + player + .chooseButton([str, event.cards]) + .set("ai", function (button) { + var card = button.link; + var source = _status.event.source; + if (get.attitude(player, source) > 0) + return Math.max(1, source.getUseValue(card, null, true)); + var cards = _status.event.getParent().cards.slice(0); + if (cards.length == 1) return -get.value(card); + cards.remove(card); + return get.value(cards) - get.value(card) - 2; + }) + .set("source", event.target) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("jyishi", target); + if (cards.length > 1) { target.$gain2(result.links[0]); - target.gain(result.links[0],'log'); - } - else trigger.player.gain(result.links[0],'gain2'); + target.gain(result.links[0], "log"); + } else trigger.player.gain(result.links[0], "gain2"); cards.remove(result.links[0]); - if(cards.length) player.gain(cards,'gain2'); - } - else player.storage.counttrigger.jyishi--; + if (cards.length) player.gain(cards, "gain2"); + } else player.storage.counttrigger.jyishi--; }, }, - jyishi2:{charlotte:true}, - shiduo:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(target){ - return player!=target&&player.canCompare(target); - }) + jyishi2: { charlotte: true }, + shiduo: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (target) { + return player != target && player.canCompare(target); + }); }, - filterTarget:function(card,player,target){ - return player!=target&&player.canCompare(target); + filterTarget: function (card, player, target) { + return player != target && player.canCompare(target); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool&&target.isAlive()){ - var num=target.countCards('h'); - if(num>0) player.gainPlayerCard(target,true,'h',num); - } + "step 1"; + if (result.bool && target.isAlive()) { + var num = target.countCards("h"); + if (num > 0) player.gainPlayerCard(target, true, "h", num); + } else event.finish(); + "step 2"; + var num = Math.floor(player.countCards("h") / 2); + if (num && target.isAlive()) + player.chooseCard( + "h", + num, + true, + "交给" + get.translation(target) + get.cnNumber(num) + "张牌" + ); else event.finish(); - 'step 2' - var num=Math.floor(player.countCards('h')/2); - if(num&&target.isAlive()) player.chooseCard('h',num,true,'交给'+get.translation(target)+get.cnNumber(num)+'张牌') - else event.finish(); - 'step 3' - if(result.bool&&result.cards&&result.cards.length) player.give(result.cards,target); + "step 3"; + if (result.bool && result.cards && result.cards.length) player.give(result.cards, target); }, - ai:{ - order:1, - result:{ - target:function(player,target){ - var delta=(target.countCards('h')-player.countCards('h')); - if(delta<0) return 0; - return -1-delta; + ai: { + order: 1, + result: { + target: function (player, target) { + var delta = target.countCards("h") - player.countCards("h"); + if (delta < 0) return 0; + return -1 - delta; }, }, }, }, - tuishi:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - forced:true, - locked:false, - hiddenSkill:true, - filter:function(event,player){ - var target=_status.currentPhase; - return player!=target&&target&&target.isAlive()&&event.toShow&&event.toShow.includes('jin_simazhao'); + tuishi: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + forced: true, + locked: false, + hiddenSkill: true, + filter: function (event, player) { + var target = _status.currentPhase; + return ( + player != target && + target && + target.isAlive() && + event.toShow && + event.toShow.includes("jin_simazhao") + ); }, - content:function(){ - player.addTempSkill('tuishi2'); + content: function () { + player.addTempSkill("tuishi2"); }, }, - tuishi2:{ - trigger:{global:'phaseEnd'}, - direct:true, - charlotte:true, - filter:function(event,player){ - var target=_status.currentPhase; - return target!=player&&target&&target.isAlive()&&game.hasPlayer(function(current){ - return current!=target&&target.inRange(current); - }); + tuishi2: { + trigger: { global: "phaseEnd" }, + direct: true, + charlotte: true, + filter: function (event, player) { + var target = _status.currentPhase; + return ( + target != player && + target && + target.isAlive() && + game.hasPlayer(function (current) { + return current != target && target.inRange(current); + }) + ); }, - content:function(){ - 'step 0' - var target=_status.currentPhase; - event.target=target; - player.chooseTarget(get.prompt2('tuishi',event.target),function(card,player,target){ - var source=_status.event.source; - return source!=target&&source.inRange(target); - }).set('source',target).set('goon',get.damageEffect(target,player,player)>0).set('ai',function(target){ - if(!_status.event.goon) return 0; - var evt=_status.event; - return get.effect(target,{name:'sha'},evt.source,evt.player) - }); - 'step 1' - if(result.bool){ - event.target2=result.targets[0]; - player.logSkill('tuishi'); - player.line2([target,event.target2]); + content: function () { + "step 0"; + var target = _status.currentPhase; + event.target = target; + player + .chooseTarget(get.prompt2("tuishi", event.target), function (card, player, target) { + var source = _status.event.source; + return source != target && source.inRange(target); + }) + .set("source", target) + .set("goon", get.damageEffect(target, player, player) > 0) + .set("ai", function (target) { + if (!_status.event.goon) return 0; + var evt = _status.event; + return get.effect(target, { name: "sha" }, evt.source, evt.player); + }); + "step 1"; + if (result.bool) { + event.target2 = result.targets[0]; + player.logSkill("tuishi"); + player.line2([target, event.target2]); game.delayx(); - } - else event.finish(); - 'step 2' + } else event.finish(); + "step 2"; target.chooseToUse({ - preTarget:event.target2, - prompt:'请对'+get.translation(event.target2)+'使用一张【杀】,或受到来自'+get.translation(player)+'的1点伤害', - filterCard:function(card,player){ - return get.name(card)=='sha'&&lib.filter.filterCard.apply(this,arguments); + preTarget: event.target2, + prompt: + "请对" + + get.translation(event.target2) + + "使用一张【杀】,或受到来自" + + get.translation(player) + + "的1点伤害", + filterCard: function (card, player) { + return get.name(card) == "sha" && lib.filter.filterCard.apply(this, arguments); }, - filterTarget:function(card,player,target){ - return target==_status.event.preTarget&&lib.filter.filterTarget.apply(this,arguments); + filterTarget: function (card, player, target) { + return ( + target == _status.event.preTarget && + lib.filter.filterTarget.apply(this, arguments) + ); }, - addCount:false, + addCount: false, }); - 'step 3' - if(!result.bool) target.damage(); + "step 3"; + if (!result.bool) target.damage(); }, }, - xinchoufa:{ - audio:'choufa', - inherit:'choufa', - content:function(){ - 'step 0' - player.choosePlayerCard(target,'h',true); - 'step 1' - player.showCards(result.cards,get.translation(player)+'对'+get.translation(target)+'发动了【筹伐】'); - var type=get.type2(result.cards[0],target),hs=target.getCards('h',function(card){ - return card!=result.cards[0]&&get.type2(card,target)!=type; - }); - if(hs.length){ - target.addGaintag(hs,'xinchoufa'); - target.addTempSkill('xinchoufa2',{player:'phaseAfter'}); + xinchoufa: { + audio: "choufa", + inherit: "choufa", + content: function () { + "step 0"; + player.choosePlayerCard(target, "h", true); + "step 1"; + player.showCards( + result.cards, + get.translation(player) + "对" + get.translation(target) + "发动了【筹伐】" + ); + var type = get.type2(result.cards[0], target), + hs = target.getCards("h", function (card) { + return card != result.cards[0] && get.type2(card, target) != type; + }); + if (hs.length) { + target.addGaintag(hs, "xinchoufa"); + target.addTempSkill("xinchoufa2", { player: "phaseAfter" }); } }, }, - xinchoufa2:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('xinchoufa'); + xinchoufa2: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("xinchoufa"); }, - mod:{ - cardname:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('xinchoufa')) return 'sha'; + mod: { + cardname: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("xinchoufa")) return "sha"; }, - cardnature:function(card){ - if(get.itemtype(card)=='card'&&card.hasGaintag('xinchoufa')) return false; + cardnature: function (card) { + if (get.itemtype(card) == "card" && card.hasGaintag("xinchoufa")) return false; }, }, }, - choufa:{ - enable:'phaseUse', - audio:2, - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.choufa.filterTarget(null,player,current); + choufa: { + enable: "phaseUse", + audio: 2, + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return lib.skill.choufa.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - return target!=player&&!target.hasSkill('choufa2')&&target.countCards('h')>0; + filterTarget: function (card, player, target) { + return target != player && !target.hasSkill("choufa2") && target.countCards("h") > 0; }, - content:function(){ - 'step 0' - player.choosePlayerCard(target,'h',true); - 'step 1' + content: function () { + "step 0"; + player.choosePlayerCard(target, "h", true); + "step 1"; player.showCards(result.cards); - var type=get.type2(result.cards[0],target); - target.storage.choufa2=type; - target.addTempSkill('choufa2',{player:'phaseAfter'}); + var type = get.type2(result.cards[0], target); + target.storage.choufa2 = type; + target.addTempSkill("choufa2", { player: "phaseAfter" }); }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return -target.countCards('h'); + ai: { + order: 9, + result: { + target: function (player, target) { + return -target.countCards("h"); }, }, }, }, - choufa2:{ - onremove:true, - charlotte:true, - mark:true, - intro:{content:'手牌中的非$牌均视为杀'}, - mod:{ - cardname:function(card,player){ - if(get.type2(card,false)!=player.storage.choufa2) return 'sha'; + choufa2: { + onremove: true, + charlotte: true, + mark: true, + intro: { content: "手牌中的非$牌均视为杀" }, + mod: { + cardname: function (card, player) { + if (get.type2(card, false) != player.storage.choufa2) return "sha"; }, - cardnature:function(card,player){ - if(get.type2(card,false)!=player.storage.choufa2) return false; + cardnature: function (card, player) { + if (get.type2(card, false) != player.storage.choufa2) return false; }, }, }, - zhaoran:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - preHidden:true, - content:function(){ - player.addTempSkill('zhaoran2','phaseUseAfter'); - var cards=player.getCards('h'); - if(cards.length>0) player.addShownCards(cards,'visible_zhaoran'); + zhaoran: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + preHidden: true, + content: function () { + player.addTempSkill("zhaoran2", "phaseUseAfter"); + var cards = player.getCards("h"); + if (cards.length > 0) player.addShownCards(cards, "visible_zhaoran"); }, }, - zhaoran2:{ - audio:'zhaoran', - group:'zhaoran3', - init:(player,skill)=>{ - if(!player.storage[skill]) player.storage[skill]=[]; + zhaoran2: { + audio: "zhaoran", + group: "zhaoran3", + init: (player, skill) => { + if (!player.storage[skill]) player.storage[skill] = []; }, - onremove:true, - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + onremove: true, + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player,name){ - if(name=='gainBegin') return true; - var evt=event.getl(player); - if(!evt||!evt.hs||!evt.hs.length) return false; - var list=player.getStorage('zhaoran2'); - for(var i of evt.hs){ - var suit=get.suit(i,player); - if(!list.includes(suit)&&!player.countCards('h',{suit:suit})) return true; + forced: true, + charlotte: true, + popup: false, + filter: function (event, player, name) { + if (name == "gainBegin") return true; + var evt = event.getl(player); + if (!evt || !evt.hs || !evt.hs.length) return false; + var list = player.getStorage("zhaoran2"); + for (var i of evt.hs) { + var suit = get.suit(i, player); + if (!list.includes(suit) && !player.countCards("h", { suit: suit })) return true; } return false; }, - content:function(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - 'step 1' - var list=[]; - var suits=get.copy(player.storage.zhaoran2); - suits.addArray(player.getCards('h').map(function(card){ - return get.suit(card); - })); - var evt=trigger.getl(player); - for(var i of evt.hs){ - var suit=get.suit(i,player); - if(!suits.includes(suit)) list.add(suit); + content: function () { + "step 0"; + if (trigger.delay === false) game.delayx(); + "step 1"; + var list = []; + var suits = get.copy(player.storage.zhaoran2); + suits.addArray( + player.getCards("h").map(function (card) { + return get.suit(card); + }) + ); + var evt = trigger.getl(player); + for (var i of evt.hs) { + var suit = get.suit(i, player); + if (!suits.includes(suit)) list.add(suit); } - event.count=list.length; - player.markAuto('zhaoran2',list); - 'step 1' + event.count = list.length; + player.markAuto("zhaoran2", list); + "step 1"; event.count--; - var filterTarget=function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he')>0; - } - if(!game.hasPlayer(function(current){ - return filterTarget(null,player,current); - })) event._result={bool:false}; - else player.chooseTarget(filterTarget,'弃置一名其他角色的一张牌或摸一张牌').set('ai',function(target){ - var att=get.attitude(player,target); - if(att>=0) return 0; - if(target.countCards('he',function(card){ - return get.value(card)>5; - })) return -att; - return 0; - }); - 'step 2' - if(!result.bool){ - player.logSkill('zhaoran2'); + var filterTarget = function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he") > 0; + }; + if ( + !game.hasPlayer(function (current) { + return filterTarget(null, player, current); + }) + ) + event._result = { bool: false }; + else + player + .chooseTarget(filterTarget, "弃置一名其他角色的一张牌或摸一张牌") + .set("ai", function (target) { + var att = get.attitude(player, target); + if (att >= 0) return 0; + if ( + target.countCards("he", function (card) { + return get.value(card) > 5; + }) + ) + return -att; + return 0; + }); + "step 2"; + if (!result.bool) { + player.logSkill("zhaoran2"); player.draw(); + } else { + var target = result.targets[0]; + player.logSkill("zhaoran2", target); + player.discardPlayerCard(target, true, "he"); } - else{ - var target=result.targets[0]; - player.logSkill('zhaoran2',target); - player.discardPlayerCard(target,true,'he'); - } - if(event.count>0) event.goto(1); + if (event.count > 0) event.goto(1); }, - intro:{ - content:'已因$牌触发过效果', + intro: { + content: "已因$牌触发过效果", }, }, - zhaoran3:{ - trigger:{player:['phaseUseEnd','gainBegin']}, - forced:true, - charlotte:true, - firstDo:true, - silent:true, - content:function(){ - if(event.triggername=='gainBegin'){ - trigger.gaintag.add('visible_zhaoran'); - } - else{ - player.hideShownCards(player.getCards('h'),'visible_zhaoran'); + zhaoran3: { + trigger: { player: ["phaseUseEnd", "gainBegin"] }, + forced: true, + charlotte: true, + firstDo: true, + silent: true, + content: function () { + if (event.triggername == "gainBegin") { + trigger.gaintag.add("visible_zhaoran"); + } else { + player.hideShownCards(player.getCards("h"), "visible_zhaoran"); } }, }, - chengwu:{ - zhuSkill:true, - mod:{ - inRange:function(from,to){ - if(!from.hasZhuSkill('chengwu')||from._chengwu) return; - from._chengwu=true; - var bool=game.hasPlayer(function(current){ - return current!=from&¤t!=to&¤t.group=='jin'&&from.hasZhuSkill('chengwu',current)&¤t.inRange(to); + chengwu: { + zhuSkill: true, + mod: { + inRange: function (from, to) { + if (!from.hasZhuSkill("chengwu") || from._chengwu) return; + from._chengwu = true; + var bool = game.hasPlayer(function (current) { + return ( + current != from && + current != to && + current.group == "jin" && + from.hasZhuSkill("chengwu", current) && + current.inRange(to) + ); }); delete from._chengwu; - if(bool) return true; + if (bool) return true; }, }, }, - shiren:{ - trigger:{player:'showCharacterAfter'}, - hiddenSkill:true, - logTarget:function(){ + shiren: { + trigger: { player: "showCharacterAfter" }, + hiddenSkill: true, + logTarget: function () { return _status.currentPhase; }, - filter:function(event,player){ - if(!event.toShow||!event.toShow.includes('jin_wangyuanji')) return false; - var target=_status.currentPhase; - return target&&target!=player&&target.isAlive()&&target.countCards('h')>0; + filter: function (event, player) { + if (!event.toShow || !event.toShow.includes("jin_wangyuanji")) return false; + var target = _status.currentPhase; + return target && target != player && target.isAlive() && target.countCards("h") > 0; }, - content:function(){ - var next=game.createEvent('yanxi',false); - next.player=player; - next.target=_status.currentPhase; + content: function () { + var next = game.createEvent("yanxi", false); + next.player = player; + next.target = _status.currentPhase; next.setContent(lib.skill.yanxi.content); }, }, - yanxi:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0; + yanxi: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; }, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0; + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("h") > 0; }); }, - content:function(){ - 'step 0' - event.card=target.getCards('h').randomGet(); + content: function () { + "step 0"; + event.card = target.getCards("h").randomGet(); var cards; - cards=get.cards(2); - event.cards=cards.concat([event.card]); - while(cards.length){ - ui.cardPile.insertBefore(cards.pop().fix(),ui.cardPile.firstChild); + cards = get.cards(2); + event.cards = cards.concat([event.card]); + while (cards.length) { + ui.cardPile.insertBefore(cards.pop().fix(), ui.cardPile.firstChild); } - if(get.mode()=='guozhan'){ - var num=ui.cardPile.childElementCount; - var num1=get.rand(1,num-1),num2=get.rand(1,num-1); - if(num1==num2){ - if(num1==0) num2++; + if (get.mode() == "guozhan") { + var num = ui.cardPile.childElementCount; + var num1 = get.rand(1, num - 1), + num2 = get.rand(1, num - 1); + if (num1 == num2) { + if (num1 == 0) num2++; else num1--; } - event.cards=[event.card,ui.cardPile.childNodes[num1],ui.cardPile.childNodes[num2]]; + event.cards = [ + event.card, + ui.cardPile.childNodes[num1], + ui.cardPile.childNodes[num2], + ]; } game.updateRoundNumber(); event.cards.randomSort(); - game.log(player,'展示了',event.cards); - event.videoId=lib.status.videoId++; - var str=get.translation(player)+'对'+get.translation(target)+'发动了【宴戏】'; - game.broadcastAll(function(str,id,cards){ - var dialog=ui.create.dialog(str,cards); - dialog.videoId=id; - },str,event.videoId,event.cards); - game.addVideo('showCards',player,[str,get.cardsInfo(event.cards)]); + game.log(player, "展示了", event.cards); + event.videoId = lib.status.videoId++; + var str = get.translation(player) + "对" + get.translation(target) + "发动了【宴戏】"; + game.broadcastAll( + function (str, id, cards) { + var dialog = ui.create.dialog(str, cards); + dialog.videoId = id; + }, + str, + event.videoId, + event.cards + ); + game.addVideo("showCards", player, [str, get.cardsInfo(event.cards)]); game.delay(2); - 'step 1' - var func=function(id,target){ - var dialog=get.idDialog(id); - if(dialog) dialog.content.firstChild.innerHTML='猜猜哪张是'+get.translation(target)+'的手牌?'; + "step 1"; + var func = function (id, target) { + var dialog = get.idDialog(id); + if (dialog) + dialog.content.firstChild.innerHTML = + "猜猜哪张是" + get.translation(target) + "的手牌?"; }; - if(player==game.me) func(event.videoId,target); - else if(player.isOnline()) player.send(func,event.videoId,target); - 'step 2' - var next=player.chooseButton(true); - next.set('dialog',event.videoId); - next.set('ai',function(button){ - if(_status.event.answer) return button.link==_status.event.answer?1:0; - return get.value(button.link,_status.event.player); + if (player == game.me) func(event.videoId, target); + else if (player.isOnline()) player.send(func, event.videoId, target); + "step 2"; + var next = player.chooseButton(true); + next.set("dialog", event.videoId); + next.set("ai", function (button) { + if (_status.event.answer) return button.link == _status.event.answer ? 1 : 0; + return get.value(button.link, _status.event.player); }); - if(player.hasSkillTag('viewHandcard',null,target,true)) next.set('answer',card); - 'step 3' - game.broadcastAll('closeDialog',event.videoId); - player.addTempSkill('yanxi2'); - var card2=result.links[0]; - if(card2==card){ - player.popup('洗具'); + if (player.hasSkillTag("viewHandcard", null, target, true)) next.set("answer", card); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + player.addTempSkill("yanxi2"); + var card2 = result.links[0]; + if (card2 == card) { + player.popup("洗具"); cards.remove(card2); player.$gain2(cards); - player.gain(cards,'log').gaintag.add('yanxi'); - player.gain(card,target,'bySelf','give').gaintag.add('yanxi'); - } - else{ - player.popup('杯具'); - player.gain(card2,'gain2').gaintag.add('yanxi'); + player.gain(cards, "log").gaintag.add("yanxi"); + player.gain(card, target, "bySelf", "give").gaintag.add("yanxi"); + } else { + player.popup("杯具"); + player.gain(card2, "gain2").gaintag.add("yanxi"); } }, - ai:{ - order:6, - result:{ - player:1, - target:-0.6, + ai: { + order: 6, + result: { + player: 1, + target: -0.6, }, }, }, - yanxi2:{ - mod:{ - ignoredHandcard:function(card,player){ - if(card.hasGaintag('yanxi')) return true; + yanxi2: { + mod: { + ignoredHandcard: function (card, player) { + if (card.hasGaintag("yanxi")) return true; }, - cardDiscardable:function(card,player,name){ - if(name=='phaseDiscard'&&card.hasGaintag('yanxi')) return false; + cardDiscardable: function (card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("yanxi")) return false; }, }, - onremove:function(player){ - player.removeGaintag('yanxi'); + onremove: function (player) { + player.removeGaintag("yanxi"); }, }, - sanchen:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var stat=player.getStat('sanchen'); - return game.hasPlayer(function(current){ - return (!stat||!stat.includes(current)); + sanchen: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var stat = player.getStat("sanchen"); + return game.hasPlayer(function (current) { + return !stat || !stat.includes(current); }); }, - filterTarget:function(card,player,target){ - var stat=player.getStat('sanchen'); - return (!stat||!stat.includes(target)); + filterTarget: function (card, player, target) { + var stat = player.getStat("sanchen"); + return !stat || !stat.includes(target); }, - content:function(){ - 'step 0' - var stat=player.getStat(); - if(!stat.sanchen) stat.sanchen=[]; + content: function () { + "step 0"; + var stat = player.getStat(); + if (!stat.sanchen) stat.sanchen = []; stat.sanchen.push(target); - if(get.mode()!='guozhan') player.addMark('sanchen',1,false); + if (get.mode() != "guozhan") player.addMark("sanchen", 1, false); target.draw(3); - 'step 1' - if(!target.countCards('he')) event._result={bool:false}; - else target.chooseToDiscard('he',true,3).set('ai',function(card){ - var list=ui.selected.cards.map(function(i){ - return get.type2(i); + "step 1"; + if (!target.countCards("he")) event._result = { bool: false }; + else + target.chooseToDiscard("he", true, 3).set("ai", function (card) { + var list = ui.selected.cards.map(function (i) { + return get.type2(i); + }); + if (!list.includes(get.type2(card))) return 7 - get.value(card); + return -get.value(card); }); - if(!list.includes(get.type2(card))) return 7-get.value(card); - return -get.value(card); - }); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - var list=[]; - for(var i of result.cards) list.add(get.type2(i)); - if(list.length==result.cards.length){ + "step 2"; + if (result.bool && result.cards && result.cards.length) { + var list = []; + for (var i of result.cards) list.add(get.type2(i)); + if (list.length == result.cards.length) { target.draw(); - player.getStat('skill').sanchen--; - if(get.mode()=='guozhan') player.addTempSkills('pozhu'); + player.getStat("skill").sanchen--; + if (get.mode() == "guozhan") player.addTempSkills("pozhu"); } - } - else{ + } else { target.draw(); - player.getStat('skill').sanchen--; - if(get.mode()=='guozhan') player.addTempSkills('pozhu'); + player.getStat("skill").sanchen--; + if (get.mode() == "guozhan") player.addTempSkills("pozhu"); } }, - ai:{ - order:9, - threaten:1.7, - result:{ - target:function(player,target){ - if(target.hasSkillTag('nogain')) return 0.1; - return Math.sqrt(target.countCards('he')); + ai: { + order: 9, + threaten: 1.7, + result: { + target: function (player, target) { + if (target.hasSkillTag("nogain")) return 0.1; + return Math.sqrt(target.countCards("he")); }, }, }, - intro:{ - content:'已发动过#次技能', + intro: { + content: "已发动过#次技能", }, - marktext:'陈', + marktext: "陈", }, - zhaotao:{ - forbid:['guozhan'], - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - juexingji:true, - skillAnimation:true, - animationColor:'thunder', - filter:function(event,player){ - return player.countMark('sanchen')>2; + zhaotao: { + forbid: ["guozhan"], + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + juexingji: true, + skillAnimation: true, + animationColor: "thunder", + filter: function (event, player) { + return player.countMark("sanchen") > 2; }, - content:function(){ - player.awakenSkill('zhaotao'); + content: function () { + player.awakenSkill("zhaotao"); player.loseMaxHp(); - player.addSkills('pozhu'); + player.addSkills("pozhu"); }, - derivation:'pozhu', - }, - pozhu:{ - enable:'phaseUse', - viewAsFilter:function(player){ - return !player.hasSkill('pozhu3',null,null,false)&&player.countCards('hs')>0; - }, - viewAs:{name:'chuqibuyi'}, - filterCard:true, - position:'hs', - check:function(card){ - return 7-get.value(card); - }, - group:'pozhu2', - }, - pozhu2:{ - trigger:{player:'useCardAfter'}, - silent:true, - filter:function(event,player){ - return event.skill=='pozhu'&&(get.mode()=='guozhan'||!player.getHistory('sourceDamage',function(evt){ - return evt.card==event.card; - }).length); - }, - content:function(){ - player.addTempSkill('pozhu3'); + derivation: "pozhu", + ai: { + combo: "sanchen", }, }, - pozhu3:{charlotte:true}, - xijue:{ - audio:2, - trigger:{ - global:'phaseBefore', - player:['enterGame','showCharacterAfter'], + pozhu: { + enable: "phaseUse", + viewAsFilter: function (player) { + return !player.hasSkill("pozhu3", null, null, false) && player.countCards("hs") > 0; }, - forced:true, - filter:function(event,player){ - if(player._xijue) return false; - if(get.mode()=='guozhan') return event.name=='showCharacter'&&event.toShow&&event.toShow.includes('gz_zhanghuyuechen'); - return (event.name!='showCharacter')&&(event.name!='phase'||game.phaseNumber==0); + viewAs: { name: "chuqibuyi" }, + filterCard: true, + position: "hs", + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - player.addMark('xijue',4); - player._xijue=true; - }, - intro:{ - name2:'爵', - content:'mark', - }, - derivation:['xijue_tuxi','xijue_xiaoguo'], - group:['xijue_gain','xijue_tuxi','xijue_xiaoguo'], + group: "pozhu2", }, - xijue_gain:{ - audio:'xijue', - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ - var stat=player.getStat(); - return stat.damage&&stat.damage>0; + pozhu2: { + trigger: { player: "useCardAfter" }, + silent: true, + filter: function (event, player) { + return ( + event.skill == "pozhu" && + (get.mode() == "guozhan" || + !player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length) + ); }, - content:function(){ - player.addMark('xijue',player.getStat().damage); + content: function () { + player.addTempSkill("pozhu3"); }, }, - xijue_tuxi:{ - audio:2, - trigger:{ - player:"phaseDrawBegin2", + pozhu3: { charlotte: true }, + xijue: { + audio: 2, + trigger: { + global: "phaseBefore", + player: ["enterGame", "showCharacterAfter"], }, - direct:true, - filter:function(event,player){ - return event.num>0&&!event.numFixed&&player.hasMark('xijue')&&game.hasPlayer(function(target){ - return player!=target&&target.countCards('h')>0; - }); + forced: true, + filter: function (event, player) { + if (player._xijue) return false; + if (get.mode() == "guozhan") + return ( + event.name == "showCharacter" && + event.toShow && + event.toShow.includes("gz_zhanghuyuechen") + ); + return event.name != "showCharacter" && (event.name != "phase" || game.phaseNumber == 0); }, - content:function (){ - "step 0" - var num=trigger.num; - if(get.mode()=='guozhan'&&num>2) num=2; - player.chooseTarget('是否弃置一枚“爵”发动【突袭】?','获得至多'+get.translation(num)+'名角色的各一张手牌,然后少摸等量的牌',[1,num],function(card,player,target){ - return target.countCards('h')>0&&player!=target; - },function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkill('tuntian')) return att/10; - return 1-att; - }); - "step 1" - if(result.bool){ + content: function () { + player.addMark("xijue", 4); + player._xijue = true; + }, + intro: { + name2: "爵", + content: "mark", + }, + derivation: ["xijue_tuxi", "xijue_xiaoguo"], + group: ["xijue_gain", "xijue_tuxi", "xijue_xiaoguo"], + }, + xijue_gain: { + audio: "xijue", + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { + var stat = player.getStat(); + return stat.damage && stat.damage > 0; + }, + content: function () { + player.addMark("xijue", player.getStat().damage); + }, + }, + xijue_tuxi: { + audio: 2, + trigger: { + player: "phaseDrawBegin2", + }, + direct: true, + filter: function (event, player) { + return ( + event.num > 0 && + !event.numFixed && + player.hasMark("xijue") && + game.hasPlayer(function (target) { + return player != target && target.countCards("h") > 0; + }) + ); + }, + content: function () { + "step 0"; + var num = trigger.num; + if (get.mode() == "guozhan" && num > 2) num = 2; + player.chooseTarget( + "是否弃置一枚“爵”发动【突袭】?", + "获得至多" + get.translation(num) + "名角色的各一张手牌,然后少摸等量的牌", + [1, num], + function (card, player, target) { + return target.countCards("h") > 0 && player != target; + }, + function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkill("tuntian")) return att / 10; + return 1 - att; + } + ); + "step 1"; + if (result.bool) { result.targets.sortBySeat(); - player.logSkill('xijue_tuxi',result.targets); - player.removeMark('xijue',1); + player.logSkill("xijue_tuxi", result.targets); + player.removeMark("xijue", 1); player.gainMultiple(result.targets); - trigger.num-=result.targets.length; - } - else{ + trigger.num -= result.targets.length; + } else { event.finish(); } - "step 2" - if(trigger.num<=0) game.delay(); + "step 2"; + if (trigger.num <= 0) game.delay(); }, - ai:{ - expose:0.2, + ai: { + expose: 0.2, }, }, - xijue_xiaoguo:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.hasMark('xijue')&&event.player.isAlive()&&event.player!=player&&player.countCards('h',function(card){ - if(_status.connectMode||get.mode()!='guozhan') return true; - return get.type(card)=='basic'; - }); + xijue_xiaoguo: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.hasMark("xijue") && + event.player.isAlive() && + event.player != player && + player.countCards("h", function (card) { + if (_status.connectMode || get.mode() != "guozhan") return true; + return get.type(card) == "basic"; + }) + ); }, - direct:true, - content:function(){ - "step 0" - var nono=(Math.abs(get.attitude(player,trigger.player))<3||trigger.player.hp>(player.countMark('xijue')*1.5)||trigger.player.countCards('e',function(card){ - return get.value(card,trigger.player)<=0; - })); - if(get.damageEffect(trigger.player,player,player)<=0){ - nono=true; + direct: true, + content: function () { + "step 0"; + var nono = + Math.abs(get.attitude(player, trigger.player)) < 3 || + trigger.player.hp > player.countMark("xijue") * 1.5 || + trigger.player.countCards("e", function (card) { + return get.value(card, trigger.player) <= 0; + }); + if (get.damageEffect(trigger.player, player, player) <= 0) { + nono = true; } - var next=player.chooseToDiscard(`是否弃置一枚“爵”和一张${get.mode()=='guozhan'?'基本':'手'}牌,对${get.translation(trigger.player)}发动【骁果】?`,'h',function(card,player){ - if(get.mode()!='guozhan') return true; - return get.type(card,player)=='basic'; + var next = player.chooseToDiscard( + `是否弃置一枚“爵”和一张${ + get.mode() == "guozhan" ? "基本" : "手" + }牌,对${get.translation(trigger.player)}发动【骁果】?`, + "h", + function (card, player) { + if (get.mode() != "guozhan") return true; + return get.type(card, player) == "basic"; + } + ); + next.set("ai", function (card) { + if (_status.event.nono) return 0; + return 8 - get.useful(card); }); - next.set('ai',function(card){ - if(_status.event.nono) return 0; - return 8-get.useful(card); - }); - next.set('logSkill',['xijue_xiaoguo',trigger.player]); - next.set('nono',nono); - "step 1" - if(result.bool){ - player.removeMark('xijue',1); - var nono=(get.damageEffect(trigger.player,player,trigger.player)>=0); - trigger.player.chooseToDiscard('he','弃置一张装备牌并令'+get.translation(player)+'摸一张牌,或受到1点伤害',{type:'equip'}).set('ai',function(card){ - if(_status.event.nono){ - return 0; - } - if(_status.event.player.hp==1) return 10-get.value(card); - return 9-get.value(card); - }).set('nono',nono); - } - else{ + next.set("logSkill", ["xijue_xiaoguo", trigger.player]); + next.set("nono", nono); + "step 1"; + if (result.bool) { + player.removeMark("xijue", 1); + var nono = get.damageEffect(trigger.player, player, trigger.player) >= 0; + trigger.player + .chooseToDiscard( + "he", + "弃置一张装备牌并令" + get.translation(player) + "摸一张牌,或受到1点伤害", + { type: "equip" } + ) + .set("ai", function (card) { + if (_status.event.nono) { + return 0; + } + if (_status.event.player.hp == 1) return 10 - get.value(card); + return 9 - get.value(card); + }) + .set("nono", nono); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(get.mode()!='guozhan') player.draw(); - } - else{ + "step 2"; + if (result.bool) { + if (get.mode() != "guozhan") player.draw(); + } else { trigger.player.damage(); } }, - ai:{ - expose:0.3, - threaten:1.3 - } + ai: { + expose: 0.3, + threaten: 1.3, + }, }, - huishi:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ - return ui.cardPile.childElementCount%10>0&&!event.numFixed; + huishi: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { + return ui.cardPile.childElementCount % 10 > 0 && !event.numFixed; }, - preHidden:true, - prompt:function(){ - return get.prompt('huishi')+'(当前牌堆尾数:'+ui.cardPile.childElementCount%10+')'; + preHidden: true, + prompt: function () { + return ( + get.prompt("huishi") + + "(当前牌堆尾数:" + + (ui.cardPile.childElementCount % 10) + + ")" + ); }, - check:function(event,player){ - return ui.cardPile.childElementCount%10>3; + check: function (event, player) { + return ui.cardPile.childElementCount % 10 > 3; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - var cards=game.cardsGotoOrdering(get.cards(ui.cardPile.childElementCount%10)).cards; - var num=Math.ceil(cards.length/2); - var next=player.chooseToMove('慧识:将'+get.cnNumber(num)+'张牌置于牌堆底并获得其余的牌',true); - next.set('list',[ - ['牌堆顶的展示牌',cards], - ['牌堆底'], - ]); - next.set('filterMove',function(from,to,moved){ - if(moved[0].includes(from)&&to==1) return moved[1].length<_status.event.num; + var cards = game.cardsGotoOrdering(get.cards(ui.cardPile.childElementCount % 10)).cards; + var num = Math.ceil(cards.length / 2); + var next = player.chooseToMove( + "慧识:将" + get.cnNumber(num) + "张牌置于牌堆底并获得其余的牌", + true + ); + next.set("list", [["牌堆顶的展示牌", cards], ["牌堆底"]]); + next.set("filterMove", function (from, to, moved) { + if (moved[0].includes(from) && to == 1) return moved[1].length < _status.event.num; return true; }); - next.set('filterOk',function(moved){ - return moved[1].length==_status.event.num; + next.set("filterOk", function (moved) { + return moved[1].length == _status.event.num; }); - next.set('num',num); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.useful(a); + next.set("num", num); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.useful(a); }); - return [cards,cards.splice(cards.length-_status.event.num)]; + return [cards, cards.splice(cards.length - _status.event.num)]; }); - 'step 1' - if(result.bool){ - var list=result.moved; - if(list[0].length) player.gain(list[0],'gain2'); - while(list[1].length) ui.cardPile.appendChild(list[1].shift().fix()); + "step 1"; + if (result.bool) { + var list = result.moved; + if (list[0].length) player.gain(list[0], "gain2"); + while (list[1].length) ui.cardPile.appendChild(list[1].shift().fix()); } }, }, - qingleng:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - preHidden:true, - filter:function(event,player){ - var target=event.player; - return target!=player&&target.isIn()&&!target.storage.nohp&&(target.hp+target.countCards('h'))>=(ui.cardPile.childElementCount%10)&&player.countCards('he')>0&&player.canUse({name:'sha',nature:'ice'},target,false); + qingleng: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + preHidden: true, + filter: function (event, player) { + var target = event.player; + return ( + target != player && + target.isIn() && + !target.storage.nohp && + target.hp + target.countCards("h") >= ui.cardPile.childElementCount % 10 && + player.countCards("he") > 0 && + player.canUse({ name: "sha", nature: "ice" }, target, false) + ); }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('qingleng',trigger.player),'将一张牌当做冰【杀】对其使用',function(card,player){ - return player.canUse(get.autoViewAs({name:'sha',nature:'ice'},[card]),_status.event.target,false); - }).set('target',trigger.player).set('ai',function(card){ - if(get.effect(_status.event.target,get.autoViewAs({name:'sha',nature:'ice'},[card]),player)<=0) return false; - return 6-get.value(card); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.useCard(get.autoViewAs({name:'sha',nature:'ice'},result.cards),result.cards,false,trigger.player,'qingleng'); - if(!player.storage.qingleng||!player.storage.qingleng.includes(trigger.player)){ + content: function () { + "step 0"; + player + .chooseCard( + "he", + get.prompt("qingleng", trigger.player), + "将一张牌当做冰【杀】对其使用", + function (card, player) { + return player.canUse( + get.autoViewAs({ name: "sha", nature: "ice" }, [card]), + _status.event.target, + false + ); + } + ) + .set("target", trigger.player) + .set("ai", function (card) { + if ( + get.effect( + _status.event.target, + get.autoViewAs({ name: "sha", nature: "ice" }, [card]), + player + ) <= 0 + ) + return false; + return 6 - get.value(card); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.useCard( + get.autoViewAs({ name: "sha", nature: "ice" }, result.cards), + result.cards, + false, + trigger.player, + "qingleng" + ); + if (!player.storage.qingleng || !player.storage.qingleng.includes(trigger.player)) { player.draw(); - player.markAuto('qingleng',[trigger.player]); + player.markAuto("qingleng", [trigger.player]); player.storage.qingleng.sortBySeat(); } } }, - intro:{ - content:'已对$发动过此技能', + intro: { + content: "已对$发动过此技能", }, }, - xuanmu:{ - audio:2, - trigger:{player:'showCharacterAfter'}, - forced:true, - hiddenSkill:true, - filter:function(event,player){ - return event.toShow.includes('jin_zhangchunhua')&&player!=_status.currentPhase; + xuanmu: { + audio: 2, + trigger: { player: "showCharacterAfter" }, + forced: true, + hiddenSkill: true, + filter: function (event, player) { + return event.toShow.includes("jin_zhangchunhua") && player != _status.currentPhase; }, - content:function(){ - player.addTempSkill('xuanmu2'); + content: function () { + player.addTempSkill("xuanmu2"); }, }, - xuanmu2:{ - trigger:{player:'damageBegin4'}, - forced:true, - popup:false, - content:function(){ + xuanmu2: { + trigger: { player: "damageBegin4" }, + forced: true, + popup: false, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&!player.hasSkillTag('jueqing',false,target)) return 'zerotarget'; + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target)) + return "zerotarget"; }, }, }, }, - g_hidden_ai:{ - charlotte:true, - ai:{ - threaten:function(player,target){ - if(get.mode()!='guozhan'&&target.isUnseen(2)) return 0.0001; + g_hidden_ai: { + charlotte: true, + ai: { + threaten: function (player, target) { + if (get.mode() != "guozhan" && target.isUnseen(2)) return 0.0001; return 1; }, }, }, }, - card:{ - cheliji_sichengliangyu:{ - fullskin:true, - vanish:true, - derivation:'cheliji', - destroy:'chexuan', - type:'equip', - subtype:'equip5', - skills:['cheliji_sichengliangyu'], + card: { + cheliji_sichengliangyu: { + fullskin: true, + vanish: true, + derivation: "cheliji", + destroy: "chexuan", + type: "equip", + subtype: "equip5", + skills: ["cheliji_sichengliangyu"], }, - cheliji_tiejixuanyu:{ - fullskin:true, - vanish:true, - derivation:'cheliji', - destroy:'chexuan', - type:'equip', - subtype:'equip5', - skills:['cheliji_tiejixuanyu'], + cheliji_tiejixuanyu: { + fullskin: true, + vanish: true, + derivation: "cheliji", + destroy: "chexuan", + type: "equip", + subtype: "equip5", + skills: ["cheliji_tiejixuanyu"], }, - cheliji_feilunzhanyu:{ - fullskin:true, - vanish:true, - derivation:'cheliji', - destroy:'chexuan', - type:'equip', - subtype:'equip5', - skills:['cheliji_feilunzhanyu'], + cheliji_feilunzhanyu: { + fullskin: true, + vanish: true, + derivation: "cheliji", + destroy: "chexuan", + type: "equip", + subtype: "equip5", + skills: ["cheliji_feilunzhanyu"], }, }, - characterIntro:{ - zhanghuyuechen:'张虎,生卒年不详,雁门马邑(今山西朔城区大夫庄)人。三国时期曹魏将领。名将张辽之子。官至偏将军,袭封晋阳侯,有一子张统。乐綝(195~257年),字号不详,阳平郡卫国县(今河南省清丰县)人。三国时期曹魏将领,右将军乐进的儿子。果毅坚毅,袭封广昌亭侯,累迁扬州刺史。甘露二年,为叛乱的征东大将军诸葛诞所杀,追赠卫尉。', - duyu:'杜预(222年-285年),字元凯,京兆郡杜陵县(今陕西西安)人,中国魏晋时期军事家、经学家、律学家,曹魏散骑常侍杜恕之子。杜预初仕曹魏,任尚书郎,后成为权臣司马昭的幕僚,封丰乐亭侯。西晋建立后,历任河南尹、安西军司、秦州刺史、度支尚书等职。咸宁四年(278年)接替羊祜出任镇南大将军,镇守荆州。他积极备战,支持晋武帝司马炎对孙吴作战,并在咸宁五年(279年)成为晋灭吴之战的统帅之一。战后因功进封当阳县侯,仍镇荆州。太康五年(285年),杜预被征入朝,拜司隶校尉,途中于邓县逝世,终年六十三岁。获赠征南大将军、开府仪同三司,谥号为成。杜预耽思经籍,博学多通,多有建树,时誉为“杜武库”。著有《春秋左氏传集解》及《春秋释例》等。为明朝之前唯一一个同时进入文庙和武庙之人。', - xiahouhui:'夏侯徽(211年-234年),字媛容,沛国谯县(今安徽亳州)人,司马师第一任妻子。征南大将军夏侯尚之女,母德阳乡主为大司马曹真之妹。夏侯徽与司马师之间,生有五个女儿。夏侯徽很有见识器度,每当司马师有什么想法时,都由她从旁策划协助。当时司马师之父司马懿位居上将重位,而他的儿子们都有雄才大略。夏侯徽深知司马师绝非曹魏忠臣,而司马师对出身曹魏家族的夏侯徽也非常顾忌。青龙二年(234年),正逢“大疫”、“大病”之年,夏侯徽被司马师毒杀,时年二十四岁,死后葬于峻平陵。西晋建国后,追谥夏侯徽为景怀皇后。', - shibao:'石苞(?~273年),字仲容,渤海南皮(今河北省南皮县)人。三国时曹魏至西晋重要将领,西晋开国功臣。西晋建立后,历任大司马、侍中、司徒等职,封乐陵郡公,卒后谥号为“武”。', - simazhou:'司马伷(227年~283年6月12日),字子将,河内郡温县(今河南省温县)人。西晋宗室、将领,晋宣帝司马懿第三子,伏太妃所生。晋景帝司马师、文帝司马昭的同父异母弟,晋武帝司马炎的叔父。司马伷少有才气,在曹魏历任宁朔将军、散骑常侍、征虏将军等职,先后受封南安亭侯、东武乡侯,五等爵制建立后,改封南皮伯。西晋建立后,获封东莞郡王,入朝任尚书右仆射、抚军将军,出外拜镇东大将军。后改封琅邪王,加开府仪同三司。西晋伐吴时,率军出涂中,孙皓向他投降并奉上玉玺。战后因功拜大将军,增邑三千户。太康四年(283年),司马伷去世,享年五十七岁。谥号为武,世称“琅邪武王”。著有《周官宁朔新书》八卷,今已亡佚。', - huangzu:'黄祖(?-208年),东汉末年将领。刘表任荆州牧时,黄祖出任江夏太守。初平二年(191年),黄祖在与长沙太守孙坚交战时,其部下将孙坚射死,因此与孙家结下仇怨。之后,黄祖多次率部与东吴军队交战,射杀凌操、徐琨等人。建安十三年(208年),在与孙权的交战中,兵败被杀。', - cheliji:'彻里吉是历史小说《三国演义》中的虚构人物,西羌国王。蜀相诸葛亮伐魏,魏都督曹真驰书赴羌,国王彻里吉即命雅丹丞相与越吉元帅起羌兵一十五万、并战车直扣西平关。后军大败,越吉亡,雅丹被俘,亮将所获羌兵及车马器械,尽给还雅丹,俱放回国。彻里吉感蜀恩义,与之结盟。正史中没有关于彻里吉的记载。', - weiguan:'卫瓘(220年-291年),字伯玉。河东郡安邑县(今山西省夏县)人。三国曹魏后期至西晋初年重臣、书法家,曹魏尚书卫觊之子。卫瓘出身官宦世家,年轻时仕官于曹魏,历任尚书郎、散骑常侍、侍中、廷尉等职。后以镇西军司、监军身份参与伐蜀战争。蜀汉亡后,与钟会一道逮捕邓艾;钟会谋反时,又成功平息叛乱,命田续杀邓艾父子。回师后转任督徐州诸军事、镇东将军,封菑阳侯。西晋建立后,历任青州、幽州刺史、征东大将军等职,成功化解北方边境威胁,因功进爵菑阳公。后入朝为尚书令、侍中,又升任司空,领太子少傅。后逊位,拜太保。晋惠帝即位后,与贾皇后对立,终在政变中满门遇害,享年七十二岁。卫瓘善隶书及章草。不仅兼工各体,还能学古人之长,是颇有创意的书法家。唐朝张怀瓘《书断》中评其章草为“神品”。', - zhongyan:' 钟琰 (?—?年)颍川人,王浑之妻。生卒年不详,约魏末晋初间前后在世。王浑的妻子钟琰,是颍川人,为魏太傅钟繇的曾孙女,父亲钟徽,为黄门郎。她平时广泛阅读各种书籍,因此几岁的时候就能撰写文章。她聪慧弘雅,善于啸咏,她的礼仪法度,为中表所推崇,她写有文集五卷。', - yangyan:'杨艳(238年-274年8月25日),字琼芝,弘农郡华阴县(今陕西省华阴市)人,晋武帝司马炎第一任皇后,曹魏通事郎杨炳之女。自幼父母双亡,为舅舅赵俊所养,跟随继母段氏生活。聪明贤慧,善于书法,天生丽质,娴熟女红,嫁给了世子司马炎。泰始元年(265年),晋武帝即位,建立西晋。泰始二年(266年),杨艳受册为皇后,深得晋武帝宠幸,生下三子三女,包括晋惠帝司马衷。泰始十年(274年),去世,时年三十七,陪葬于峻阳陵,谥号武元皇后。', - yangzhi:'杨芷(259年-292年3月6日),字季兰,小字男胤,弘农郡华阴县(今陕西省华阴市)人,晋武帝司马炎第二任皇后,东汉太尉杨震幼子杨奉后裔,东汉末年东莱太守、蓩亭侯杨众曾孙女,西晋太傅杨骏与嫡妻庞氏之女,武元皇后杨艳堂妹。咸宁二年(276年),立为皇后,史称“婉嫕有妇德, 美映椒房”,得宠于晋武帝。生渤海殇王,早薨,之后再无生育。其父杨骏擅权引起皇后贾南风忌恨,贾南风联络汝南王司马亮、楚王司马玮发动政变,杀死杨骏,并唆使大臣上书状告杨芷谋反,让晋惠帝司马衷将其贬为庶人,押到金墉城居住。元康二年(292年),杨芷冻饿而死,谥号武悼皇后。', - xinchang:'辛敞(生卒年不详),字泰雍,陇西人氏,是曹魏时代官员。卫尉辛毗之子,辛宪英之弟。', - xuangongzhu:'高陵宣公主(?—?)司马氏,晋宣帝司马懿第二女。司马氏下嫁杜预。其侄司马炎登基时,司马氏已经去世。泰始年间(265年—274年)追赠高陵公主。', - jin_guohuai:'郭槐(237年-296年),字媛韶,太原阳曲(今山西太原)人,魏晋权臣贾充的妻子。父亲是曹魏城阳郡太守郭配,伯父是曹魏名将郭淮。出身太原郭氏。二十一岁时,嫁贾充作继室,生二女二子,长女贾南风,次女贾午,一子贾黎民。贾南风是西晋惠帝司马衷皇后,干预国政,专权误国,直接导致“八王之乱”和西晋亡国。', - wangxiang:'王祥(184年,一作180年-268年4月30日),字休徵。琅邪临沂(今山东省临沂市西孝友村)人。三国曹魏及西晋时大臣。王祥于东汉末隐居二十年,在曹魏,先后任县令、大司农、司空、太尉等职,封爵睢陵侯。西晋建立,拜太保,进封睢陵公。泰始四年四月戊戌日(268年4月30日)去世,年八十五(一作八十九),谥号“元”。有《训子孙遗令》一文传世。王祥侍奉后母朱氏极孝,为传统文化中二十四孝之一“卧冰求鲤”的主人翁。', - chengjichengcui:'成倅、成济(?~260年6月21日),扬州丹阳(今安徽省宣城市)人。三国时期曹魏将领。依附于司马氏家族,得到司马昭的心腹贾充指使,刺死魏帝曹髦。司马昭为平息众怒,将成倅、成济兄弟二人杀死。据《魏氏春秋》记载,成济兄弟不服罪,光着身子跑到屋顶,大骂司马昭,被军士从下乱箭射杀。', + characterIntro: { + zhanghuyuechen: + "张虎,生卒年不详,雁门马邑(今山西朔城区大夫庄)人。三国时期曹魏将领。名将张辽之子。官至偏将军,袭封晋阳侯,有一子张统。乐綝(195~257年),字号不详,阳平郡卫国县(今河南省清丰县)人。三国时期曹魏将领,右将军乐进的儿子。果毅坚毅,袭封广昌亭侯,累迁扬州刺史。甘露二年,为叛乱的征东大将军诸葛诞所杀,追赠卫尉。", + duyu: "杜预(222年-285年),字元凯,京兆郡杜陵县(今陕西西安)人,中国魏晋时期军事家、经学家、律学家,曹魏散骑常侍杜恕之子。杜预初仕曹魏,任尚书郎,后成为权臣司马昭的幕僚,封丰乐亭侯。西晋建立后,历任河南尹、安西军司、秦州刺史、度支尚书等职。咸宁四年(278年)接替羊祜出任镇南大将军,镇守荆州。他积极备战,支持晋武帝司马炎对孙吴作战,并在咸宁五年(279年)成为晋灭吴之战的统帅之一。战后因功进封当阳县侯,仍镇荆州。太康五年(285年),杜预被征入朝,拜司隶校尉,途中于邓县逝世,终年六十三岁。获赠征南大将军、开府仪同三司,谥号为成。杜预耽思经籍,博学多通,多有建树,时誉为“杜武库”。著有《春秋左氏传集解》及《春秋释例》等。为明朝之前唯一一个同时进入文庙和武庙之人。", + xiahouhui: + "夏侯徽(211年-234年),字媛容,沛国谯县(今安徽亳州)人,司马师第一任妻子。征南大将军夏侯尚之女,母德阳乡主为大司马曹真之妹。夏侯徽与司马师之间,生有五个女儿。夏侯徽很有见识器度,每当司马师有什么想法时,都由她从旁策划协助。当时司马师之父司马懿位居上将重位,而他的儿子们都有雄才大略。夏侯徽深知司马师绝非曹魏忠臣,而司马师对出身曹魏家族的夏侯徽也非常顾忌。青龙二年(234年),正逢“大疫”、“大病”之年,夏侯徽被司马师毒杀,时年二十四岁,死后葬于峻平陵。西晋建国后,追谥夏侯徽为景怀皇后。", + shibao: "石苞(?~273年),字仲容,渤海南皮(今河北省南皮县)人。三国时曹魏至西晋重要将领,西晋开国功臣。西晋建立后,历任大司马、侍中、司徒等职,封乐陵郡公,卒后谥号为“武”。", + simazhou: + "司马伷(227年~283年6月12日),字子将,河内郡温县(今河南省温县)人。西晋宗室、将领,晋宣帝司马懿第三子,伏太妃所生。晋景帝司马师、文帝司马昭的同父异母弟,晋武帝司马炎的叔父。司马伷少有才气,在曹魏历任宁朔将军、散骑常侍、征虏将军等职,先后受封南安亭侯、东武乡侯,五等爵制建立后,改封南皮伯。西晋建立后,获封东莞郡王,入朝任尚书右仆射、抚军将军,出外拜镇东大将军。后改封琅邪王,加开府仪同三司。西晋伐吴时,率军出涂中,孙皓向他投降并奉上玉玺。战后因功拜大将军,增邑三千户。太康四年(283年),司马伷去世,享年五十七岁。谥号为武,世称“琅邪武王”。著有《周官宁朔新书》八卷,今已亡佚。", + huangzu: + "黄祖(?-208年),东汉末年将领。刘表任荆州牧时,黄祖出任江夏太守。初平二年(191年),黄祖在与长沙太守孙坚交战时,其部下将孙坚射死,因此与孙家结下仇怨。之后,黄祖多次率部与东吴军队交战,射杀凌操、徐琨等人。建安十三年(208年),在与孙权的交战中,兵败被杀。", + cheliji: + "彻里吉是历史小说《三国演义》中的虚构人物,西羌国王。蜀相诸葛亮伐魏,魏都督曹真驰书赴羌,国王彻里吉即命雅丹丞相与越吉元帅起羌兵一十五万、并战车直扣西平关。后军大败,越吉亡,雅丹被俘,亮将所获羌兵及车马器械,尽给还雅丹,俱放回国。彻里吉感蜀恩义,与之结盟。正史中没有关于彻里吉的记载。", + weiguan: + "卫瓘(220年-291年),字伯玉。河东郡安邑县(今山西省夏县)人。三国曹魏后期至西晋初年重臣、书法家,曹魏尚书卫觊之子。卫瓘出身官宦世家,年轻时仕官于曹魏,历任尚书郎、散骑常侍、侍中、廷尉等职。后以镇西军司、监军身份参与伐蜀战争。蜀汉亡后,与钟会一道逮捕邓艾;钟会谋反时,又成功平息叛乱,命田续杀邓艾父子。回师后转任督徐州诸军事、镇东将军,封菑阳侯。西晋建立后,历任青州、幽州刺史、征东大将军等职,成功化解北方边境威胁,因功进爵菑阳公。后入朝为尚书令、侍中,又升任司空,领太子少傅。后逊位,拜太保。晋惠帝即位后,与贾皇后对立,终在政变中满门遇害,享年七十二岁。卫瓘善隶书及章草。不仅兼工各体,还能学古人之长,是颇有创意的书法家。唐朝张怀瓘《书断》中评其章草为“神品”。", + zhongyan: + " 钟琰 (?—?年)颍川人,王浑之妻。生卒年不详,约魏末晋初间前后在世。王浑的妻子钟琰,是颍川人,为魏太傅钟繇的曾孙女,父亲钟徽,为黄门郎。她平时广泛阅读各种书籍,因此几岁的时候就能撰写文章。她聪慧弘雅,善于啸咏,她的礼仪法度,为中表所推崇,她写有文集五卷。", + yangyan: + "杨艳(238年-274年8月25日),字琼芝,弘农郡华阴县(今陕西省华阴市)人,晋武帝司马炎第一任皇后,曹魏通事郎杨炳之女。自幼父母双亡,为舅舅赵俊所养,跟随继母段氏生活。聪明贤慧,善于书法,天生丽质,娴熟女红,嫁给了世子司马炎。泰始元年(265年),晋武帝即位,建立西晋。泰始二年(266年),杨艳受册为皇后,深得晋武帝宠幸,生下三子三女,包括晋惠帝司马衷。泰始十年(274年),去世,时年三十七,陪葬于峻阳陵,谥号武元皇后。", + yangzhi: + "杨芷(259年-292年3月6日),字季兰,小字男胤,弘农郡华阴县(今陕西省华阴市)人,晋武帝司马炎第二任皇后,东汉太尉杨震幼子杨奉后裔,东汉末年东莱太守、蓩亭侯杨众曾孙女,西晋太傅杨骏与嫡妻庞氏之女,武元皇后杨艳堂妹。咸宁二年(276年),立为皇后,史称“婉嫕有妇德, 美映椒房”,得宠于晋武帝。生渤海殇王,早薨,之后再无生育。其父杨骏擅权引起皇后贾南风忌恨,贾南风联络汝南王司马亮、楚王司马玮发动政变,杀死杨骏,并唆使大臣上书状告杨芷谋反,让晋惠帝司马衷将其贬为庶人,押到金墉城居住。元康二年(292年),杨芷冻饿而死,谥号武悼皇后。", + xinchang: "辛敞(生卒年不详),字泰雍,陇西人氏,是曹魏时代官员。卫尉辛毗之子,辛宪英之弟。", + xuangongzhu: + "高陵宣公主(?—?)司马氏,晋宣帝司马懿第二女。司马氏下嫁杜预。其侄司马炎登基时,司马氏已经去世。泰始年间(265年—274年)追赠高陵公主。", + jin_guohuai: + "郭槐(237年-296年),字媛韶,太原阳曲(今山西太原)人,魏晋权臣贾充的妻子。父亲是曹魏城阳郡太守郭配,伯父是曹魏名将郭淮。出身太原郭氏。二十一岁时,嫁贾充作继室,生二女二子,长女贾南风,次女贾午,一子贾黎民。贾南风是西晋惠帝司马衷皇后,干预国政,专权误国,直接导致“八王之乱”和西晋亡国。", + wangxiang: + "王祥(184年,一作180年-268年4月30日),字休徵。琅邪临沂(今山东省临沂市西孝友村)人。三国曹魏及西晋时大臣。王祥于东汉末隐居二十年,在曹魏,先后任县令、大司农、司空、太尉等职,封爵睢陵侯。西晋建立,拜太保,进封睢陵公。泰始四年四月戊戌日(268年4月30日)去世,年八十五(一作八十九),谥号“元”。有《训子孙遗令》一文传世。王祥侍奉后母朱氏极孝,为传统文化中二十四孝之一“卧冰求鲤”的主人翁。", + chengjichengcui: + "成倅、成济(?~260年6月21日),扬州丹阳(今安徽省宣城市)人。三国时期曹魏将领。依附于司马氏家族,得到司马昭的心腹贾充指使,刺死魏帝曹髦。司马昭为平息众怒,将成倅、成济兄弟二人杀死。据《魏氏春秋》记载,成济兄弟不服罪,光着身子跑到屋顶,大骂司马昭,被军士从下乱箭射杀。", }, - characterTitle:{}, - characterFilter:{}, - dynamicTranslate:{}, - perfectPair:{ - jin_simayi:['jin_zhangchunhua','shibao','duyu'], - jin_simazhao:['jin_wangyuanji'], - jin_simashi:['jin_xiahouhui','jin_yanghuiyu'], - xuangongzhu:['duyu'], + characterTitle: {}, + characterFilter: {}, + dynamicTranslate: {}, + perfectPair: { + jin_simayi: ["jin_zhangchunhua", "shibao", "duyu"], + jin_simazhao: ["jin_wangyuanji"], + jin_simashi: ["jin_xiahouhui", "jin_yanghuiyu"], + xuangongzhu: ["duyu"], }, - characterReplace:{ - yanghu:['jin_yanghu','dc_yanghu','sp_yanghu'], - jiachong:['dc_jiachong','jin_jiachong','jiachong'], - yangyan:['yangyan','old_yangyan'], - yangzhi:['yangzhi','old_yangzhi'], - zhongyan:['zhongyan','clan_zhongyan'], + characterReplace: { + yanghu: ["jin_yanghu", "dc_yanghu", "sp_yanghu"], + jiachong: ["dc_jiachong", "jin_jiachong", "jiachong"], + yangyan: ["yangyan", "old_yangyan"], + yangzhi: ["yangzhi", "old_yangzhi"], + zhongyan: ["zhongyan", "clan_zhongyan"], }, - translate:{ - jin_zhangchunhua:'晋张春华', - jin_zhangchunhua_prefix:'晋', - huishi:'慧识', - huishi_info:'摸牌阶段,你可以放弃摸牌,改为观看牌堆顶的X张牌,获得其中的一半(向下取整),然后将其余牌置入牌堆底。(X为牌堆数量的个位数)', - qingleng:'清冷', - qingleng_info:'一名角色的回合结束时,若其体力值与手牌数之和不小于X,则你可将一张牌当无距离限制的冰属性【杀】对其使用(X为牌堆数量的个位数)。若这是你本局游戏内首次其发动过此技能,则你摸一张牌。', - xuanmu:'宣穆', - xuanmu2:'宣穆', - xuanmu_info:'锁定技,隐匿技。你于其他角色的回合登场时,防止你受到的伤害直到回合结束。', - jin_simayi:'晋司马懿', - jin_simayi_prefix:'晋', - zhanghuyuechen:'张虎乐綝', - xijue:'袭爵', - xijue_gain:'袭爵', - xijue_info:'锁定技,游戏开始时,你获得4枚“爵”。回合结束时,你获得X枚“爵”(X为你本回合内造成的伤害数)。你可弃置一枚“爵”并在合适的时机发动〖突袭〗和〖骁果〗。', - xijue_info_guozhan:'锁定技,当你首次明置此武将牌时,你获得4枚“爵”。回合结束时,你获得X枚“爵”(X为你本回合内造成的伤害数)。你可弃置一枚“爵”并在合适的时机发动〖突袭〗和〖骁果〗。', - xijue_tuxi:'突袭', - xijue_tuxi_info:'摸牌阶段摸牌时,你可以少摸任意张牌,然后获得等量的角色的各一张手牌。', - xijue_tuxi_info_guozhan:'摸牌阶段摸牌时,你可以少摸至多两张牌,然后获得等量的角色的各一张手牌。', - xijue_xiaoguo:'骁果', - xijue_xiaoguo_info:'其他角色的结束阶段开始时,你可以弃置一张手牌,令该角色选择一项:1.弃置一张装备牌,然后你摸一张牌;2.受到你对其造成的1点伤害。', - xijue_xiaoguo_info_guozhan:'其他角色的结束阶段开始时,你可以弃置一张基本牌,令该角色选择一项:1.弃置一张装备牌;2.受到你对其造成的1点伤害。', - gz_duyu:'杜预', - duyu:'晋杜预', - duyu_prefix:'晋', - sanchen:'三陈', - sanchen_info:'出牌阶段限一次。你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则其摸一张牌且〖三陈〗于此阶段内使用次数上限+1。', - sanchen_info_guozhan:'出牌阶段,你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则其摸一张牌且你获得技能〖破竹〗直到回合结束。否则你本阶段内不能再发动〖三陈〗。', - zhaotao:'诏讨', - zhaotao_info:'觉醒技,准备阶段,若你本局游戏内发动〖三陈〗的次数大于2,则你减1点体力上限并获得〖破竹〗。', - pozhu:'破竹', - pozhu_info:'出牌阶段,你可以将一张手牌当做【出其不意】使用。若你未因此牌造成过伤害,则你不能再发动〖破竹〗直到回合结束。', - pozhu_info_guozhan:'出牌阶段限一次,你可以将一张手牌当做【出其不意】使用。', - jin_wangyuanji:'晋王元姬', - jin_wangyuanji_prefix:'晋', - shiren:'识人', - shiren_info:'隐匿技。你于其他角色的回合内登场时,若其有手牌,则你可对其发动〖宴戏〗。', - yanxi:'宴戏', - yanxi2:'宴戏', - yanxi_info:'出牌阶段,你可选择一名有手牌的角色。你将该角色的一张随机手牌与牌堆顶的两张牌混合后展示,并选择其中一张。若你以此法选择的是该角色的手牌,则你获得这三张牌。否则你获得选择的牌。你通过〖宴戏〗得到的牌,不计入当前回合的手牌上限。', - yanxi_info_guozhan:'出牌阶段,你可选择一名有手牌的角色。你将该角色的一张随机手牌与牌堆中的两张随机牌混合后展示,并选择其中一张。若你以此法选择的是该角色的手牌,则你获得这三张牌。否则你获得选择的牌。你通过〖宴戏〗得到的牌,不计入当前回合的手牌上限。', - jin_simazhao:'晋司马昭', - jin_simazhao_prefix:'晋', - tuishi:'推弑', - tuishi_info:'隐匿技,你于其他角色A的回合内登场时,可于此回合结束时选择其攻击范围内的一名角色B。A选择一项:①对B使用一张【杀】。②你对A造成1点伤害。', - choufa:'筹伐', - choufa2:'筹伐', - choufa_info:'出牌阶段限一次,你可展示一名其他角色的一张手牌并记录其类型A。你令其原类型不为A的手牌的牌名均视为【杀】且均视为无属性,直到其回合结束。', - xinchoufa:'筹伐', - xinchoufa_info:'出牌阶段限一次,你可展示一名其他角色的一张手牌A。你令其所有类型与A不同的手牌的牌名均视为【杀】且均视为无属性,直到其回合结束。', - zhaoran:'昭然', - zhaoran2:'昭然', - zhaoran_info:'出牌阶段开始时,你可令你的手牌对其他角色可见直到出牌阶段结束。若如此做,当你于此阶段内失去一张手牌后,若你的手牌里没有与此牌花色相同的牌且你本回合内未因该花色的牌触发过此效果,则你选择一项:①摸一张牌。②弃置一名其他角色的一张牌。', - visible_zhaoran:'invisible', - chengwu:'成务', - chengwu_info:'主公技,锁定技,其他晋势力角色攻击范围内的角色视为在你的攻击范围内。', - jin_xiahouhui:'晋夏侯徽', - jin_xiahouhui_prefix:'晋', - baoqie:'宝箧', - baoqie_info:'隐匿技,锁定技。你登场后,从牌堆中获得一张不为赠物的宝物牌。若此牌在你的手牌区内为宝物牌,则你可以使用此牌。', - jyishi:'宜室', - jyishi_info:'每回合限一次,当有其他角色于其出牌阶段内因弃置而失去手牌后,你可令其获得这些牌中位于弃牌堆的一张,然后你获得其余位于弃牌堆的牌。', - shiduo:'识度', - shiduo_info:'出牌阶段限一次,你可以与一名其他角色拼点。若你赢,你获得其所有手牌。然后你交给其X张手牌(X为你手牌数的一半,向下取整)。', - jin_simashi:'晋司马师', - jin_simashi_prefix:'晋', - taoyin:'韬隐', - taoyin2:'韬隐', - taoyin_info:'隐匿技,当你登场后,若当前回合角色存在且不是你,则你可令该角色本回合的手牌上限-2。', - yimie:'夷灭', - yimie2:'夷灭', - yimie_info:'每回合限一次,当你对其他角色造成伤害时,若伤害值X小于Y,则你可失去1点体力,将伤害值改为Y。此伤害结算结束后,其回复(Y-X)点体力(Y为其体力值)。', - ruilve:'睿略', - ruilve2:'睿略', - ruilve_info:'主公技,其他晋势力角色的出牌阶段限一次,该角色可以将一张带有伤害标签的基本牌或锦囊牌交给你。', - tairan:'泰然', - tairan2:'泰然', - tairan_info:'锁定技,回合结束时,你将体力回复至体力上限,并将手牌摸至体力上限(称为“泰然”牌,且至多摸五张)。然后你的下一个出牌阶段开始时,你失去上一次以此法回复的体力值的体力,弃置所有“泰然”牌。', - gz_jin_simayi:'司马懿', - gz_jin_zhangchunhua:'张春华', - gz_jin_simazhao:'司马昭', - gz_jin_wangyuanji:'王元姬', - gz_jin_simashi:'司马师', - gz_jin_xiahouhui:'夏侯徽', - xinquanbian:'权变', - xinquanbian_info:'出牌阶段,每当你首次使用/打出一种花色的手牌时,你可以从牌堆顶的X张牌中获得一张与此牌花色不同的牌,并将其余牌以任意顺序置于牌堆顶。出牌阶段,你至多可使用X张非装备手牌。(X为你的体力上限)', - shibao:'石苞', - zhuosheng:'擢升', - zhuosheng_info:'出牌阶段,①你使用本轮内得到的基本牌时无次数和距离限制。②你使用本轮内获得的普通锦囊牌选择目标后,可令此牌的目标数+1或-1。③你使用本轮内得到的装备牌时可以摸一张牌(以此法得到的牌不能触发〖擢升〗)。', - zhuosheng_info_guozhan:'出牌阶段,①你使用本轮内得到的基本牌时无距离限制。②你使用本轮内获得的普通锦囊牌选择目标后,可令此牌的目标数+1或-1。③你使用本轮内得到的装备牌时可以摸一张牌(以此法得到的牌不能触发〖擢升〗)。', - jin_yanghuiyu:'晋羊徽瑜', - jin_yanghuiyu_prefix:'晋', - gz_jin_yanghuiyu:'羊徽瑜', - huirong:'慧容', - huirong_info:'隐匿技,锁定技。当你登场后,你令一名角色将手牌数摸至/弃至与体力值相同(至多摸至五张)。', - ciwei:'慈威', - ciwei_info:'一名角色于其回合内使用第二张牌时,若此牌为基本牌或普通锦囊牌,则你可以弃置一张牌,取消此牌的所有目标。', - caiyuan:'才媛', - caiyuan_info:'锁定技。回合结束时,若你于你的上一个回合结束后未扣减过体力,则你摸两张牌。', - simazhou:'司马伷', - caiwang:'才望', - caiwang_info:'当你使用或打出牌响应其他角色使用的牌,或其他角色使用或打出牌响应你使用的牌后,若这两张牌颜色相同,则你可以弃置对方的一张牌。', - naxiang:'纳降', - naxiang2:'纳降', - naxiang_info:'锁定技,当你受到其他角色造成的伤害后,或你对其他角色造成伤害后,你对其发动〖才望①〗时的“弃置”改为“获得”直到你的下回合开始。', - cheliji:'彻里吉', - chexuan:'车悬', - chexuan_info:'出牌阶段,若你的装备区里没有宝物牌,你可弃置一张黑色牌,选择一张【舆】置入你的装备区;当你失去装备区里的宝物牌后,你可进行判定,若结果为黑色,将一张随机的【舆】置入你的装备区。', - qiangshou:'羌首', - qiangshou_info:'锁定技,若你的装备区内有宝物牌,你与其他角色的距离-1。', - cheliji_sichengliangyu:'四乘粮舆', - cheliji_sichengliangyu_bg:'粮', - cheliji_sichengliangyu_info:'一名角色的回合结束时,若你的手牌数小于体力值,你可以摸两张牌,然后弃置此牌。', - cheliji_tiejixuanyu:'铁蒺玄舆', - cheliji_tiejixuanyu_bg:'蒺', - cheliji_tiejixuanyu_info:'其他角色的回合结束时,若其本回合未造成过伤害,你可以令其弃置两张牌,然后弃置此牌。', - cheliji_feilunzhanyu:'飞轮战舆', - cheliji_feilunzhanyu_bg:'轮', - cheliji_feilunzhanyu_info:'其他角色的回合结束时,若其本回合使用过非基本牌,你可以令其交给你一张牌,然后弃置此牌。', - weiguan:'卫瓘', - zhongyun:'忠允', - zhongyun2:'忠允', - zhongyun_info:'锁定技。每名角色的回合限一次,你受伤/回复体力后,若你的体力值与手牌数相等,你回复1点体力或对你攻击范围内的一名角色造成1点伤害;每名角色的回合限一次,你获得手牌或失去手牌后,若你的体力值与手牌数相等,你摸一张牌或弃置一名其他角色一张牌。', - shenpin:'神品', - shenpin_info:'当一名角色的判定牌生效前,你可以打出一张与判定牌颜色不同的牌代替之。', - zhongyan:'钟琰', - bolan:'博览', - bolan_info:'①出牌阶段开始时,你可从三个描述中带有“出牌阶段限一次”的技能中选择一个,令当前回合角色获得直至此阶段结束。②其他角色出牌阶段限一次,其可以失去1点体力,令你发动一次〖博览①〗。', - yifa:'仪法', - yifa2:'仪法', - yifa_info:'锁定技,其他角色使用【杀】或黑色普通锦囊牌指定你为目标后,其手牌上限-1直到其回合结束。', - ol_huaxin:'OL华歆', - ol_huaxin_prefix:'OL', - caozhao:'草诏', - caozhao_backup:'草诏', - caozhao_info:'出牌阶段限一次,你可展示一张手牌并声明一种未以此法声明过的基本牌或普通锦囊牌,令一名体力不大于你的其他角色选择一项:令此牌视为你声明的牌,或其失去1点体力。然后若此牌声明成功,然后你可将其交给一名其他角色。', - olxibing:'息兵', - olxibing_info:'当你受到其他角色造成的伤害后,你可弃置你或该角色两张牌,然后你们中手牌少的角色摸两张牌,以此法摸牌的角色不能使用牌指定你为目标直到回合结束。', - recaiwang:'才望', - recaiwang_info:'①当你使用或打出牌响应其他角色使用的牌,或其他角色使用或打出牌响应你使用的牌后,若这两张牌颜色相同,则你可以弃置对方的一张牌。②若你的手牌数为1,则你可以将该手牌当做【闪】使用或打出。③若你的装备区牌数为1,则你可以将该装备当做【无懈可击】使用或打出。④若你的判定区牌数为1,则你可以将该延时锦囊牌当做【杀】使用或打出。', - recaiwang_hand:'才望', - recaiwang_equip:'才望', - recaiwang_judge:'才望', - yangyan:'杨艳', - xuanbei:'选备', - xuanbei_info:'①游戏开始时,你从牌堆中获得两张具有应变标签的牌。②每回合限一次。当你使用的具有应变标签的牌结算结束后,你可将此牌对应的所有实体牌交给一名其他角色。', - xianwan:'娴婉', - xianwan_info:'①当你需要使用【闪】时,若你的武将牌未横置,则你可以横置武将牌并视为使用【闪】。②当你需要使用【杀】时,若你的武将牌横置,则你可以重置武将牌并视为使用【杀】。', - yangzhi:'杨芷', - wanyi:'婉嫕', - wanyi_info:'每回合每项限一次。出牌阶段,你可以将一张具有应变效果的牌当做【逐近弃远】/【出其不意】/【水淹七军】/【洞烛先机】使用。', - maihuo:'埋祸', - maihuo_info:'①当你成为其他角色使用【杀】的目标后,若此【杀】不为转化牌且有对应的实体牌且其武将牌上没有“祸”且你是此牌的唯一目标,则你可以令此牌对你无效,并将此【杀】置于其武将牌上,称为“祸”。②一名其他角色的出牌阶段开始时,若其武将牌上有“祸”,则其对你使用此“祸”(有距离限制且计入次数限制,若你不是此牌的合法目标,则改为将此“祸”置入弃牌堆)。③当你对有“祸”的其他角色造成伤害后,你移去其“祸”。', - xinchang:'辛敞', - canmou:'参谋', - canmou_info:'一名角色使用普通锦囊牌指定第一个目标时,若其手牌数为全场唯一最多,则你可以为此牌增加一个额外目标。', - congjian:'从鉴', - congjian_info:'一名其他角色成为普通锦囊牌的唯一目标时,若其体力值为全场唯一最多,则你也可以成为此牌的目标。此牌结算结束后,若你受到过渠道为此牌的伤害,则你摸两张牌。', - xuangongzhu:'宣公主', - gaoling:'高陵', - gaoling_info:'隐匿技。当你于回合外明置此武将牌时,你可以令一名角色回复1点体力。', - qimei:'齐眉', - qimei_info:'准备阶段,你可以选择一名其他角色。你获得如下效果直到下回合开始:①每回合限一次,当你或其获得牌/失去手牌后,若你与其手牌数相等,则另一名角色摸一张牌。②每回合限一次,当你或其的体力值变化后,若你与其体力值相等,则另一名角色摸一张牌。', - ybzhuiji:'追姬', - ybzhuiji_info:'出牌阶段开始时,你可选择一项:①摸两张牌,并于出牌阶段结束时失去1点体力;②回复1点体力,并于出牌阶段结束时弃置两张牌。', - jin_yanghu:'晋羊祜', - jin_yanghu_prefix:'晋', - huaiyuan:'怀远', - huaiyuanx:'绥', - huaiyuan_info:'①游戏开始时,你将你的手牌标记为“绥”。②当你失去一张“绥”后,你令一名角色执行一项:⒈其的手牌上限+1。⒉其的攻击范围+1。⒊其摸一张牌。③当你死亡时,你可令一名其他角色的手牌上限+X,且攻击范围+Y(X和Y为你自己被执行过〖怀远②〗的选项一和选项二的次数)。', - chongxin:'崇信', - chongxin_info:'出牌阶段限一次,你可重铸一张牌,且令一名有手牌的其他角色也重铸一张牌。', - dezhang:'德彰', - dezhang_info:'觉醒技。准备阶段,若你没有“绥”,则你减1点体力上限并获得〖卫戍〗。', - weishu:'卫戍', - weishu_info:'锁定技。①当你于摸牌阶段外不因〖卫戍①〗而摸牌后,你令一名角色摸一张牌。②当你于弃牌阶段外不因〖卫戍②〗而弃置牌后,你弃置一名其他角色的一张牌。', - jin_jiachong:'晋贾充', - jin_jiachong_prefix:'晋', - xiongshu:'凶竖', - xiongshu_info:'其他角色的出牌阶段开始时,你可弃置X张牌(X为你本轮内此前已发动过此技能的次数,为0则不弃)并展示其一张手牌,然后你预测“其本阶段内是否会使用与展示牌牌名相同的牌”。此阶段结束时,若你的预测正确,则你对其造成1点伤害;否则你获得展示牌。', - jianhui:'奸回', - jianhui_info:'锁定技。当你造成伤害后,若受伤角色为A,则你摸一张牌;当你受到伤害后,若伤害来源为A,则A弃置一张牌。(A为除本次伤害外最近一次对你造成过伤害的角色)', - xinxuanbei:'选备', - xinxuanbei_info:'出牌阶段限一次。你可选择一名其他角色区域内的一张牌。然后其对你使用对应实体牌为此牌的【杀】。然后若此【杀】,未对你造成过伤害,你摸一张牌;对你造成过伤害,你摸两张牌。', - xinwanyi:'婉嫕', - xinwanyi_info:'①当你使用【杀】或普通锦囊牌指定其他角色为唯一目标后,你可将其的一张牌置于你的武将牌上作为“嫕”。②你不能使用/打出/弃置与“嫕”花色相同的牌。③结束阶段或当你受到伤害后,你令一名角色获得你的一张“嫕”。', - jin_guohuai:'郭槐', - zhefu:'哲妇', - zhefu_info:'当你于回合外使用或打出牌后,你可令一名有手牌的其他角色选择一项:⒈弃置一张名称相同的牌。⒉受到你造成的1点伤害。', - yidu:'遗毒', - yidu_info:'当你使用的【杀】或伤害性锦囊牌结算结束后,你可以展示一名未受到过渠道为此牌伤害的目标角色的至多三张手牌。若这些牌颜色均相同,则你弃置这些牌。', - wangxiang:'王祥', - bingxin:'冰心', - bingxin_info:'每种牌名每回合限一次。当你需要使用基本牌时,若你的手牌数等于体力值且这些牌的颜色均相同,则你可以摸一张牌,视为使用一张基本牌。', - ol_lisu:'OL李肃', - ol_lisu_prefix:'OL', - qiaoyan:'巧言', - qiaoyan_info:'锁定技,当你于回合外受到其他角色造成的伤害时,若你:有“珠”,则你令伤害来源获得“珠”;没有“珠”,则你防止此伤害,然后摸一张牌,并将一张牌正面朝上置于武将牌上,称为“珠”。', - xianzhu:'献珠', - xianzhu_info:'锁定技,出牌阶段开始时,你令一名角色A获得“珠”。若A不为你自己,则你选择你攻击范围内的一名角色B,视为A对B使用一张【杀】。', - chengjichengcui:'成济成倅', - oltousui:'透髓', - oltousui_info:'你可以将任意张牌置于牌堆底,视为使用一张需使用等量张【闪】抵消的【杀】。', - olchuming:'畜鸣', - olchuming_info:'锁定技。当你对其他角色造成伤害时,或当你受到其他角色造成的伤害时,若此伤害的渠道不为牌或没有对应的实体牌,此伤害+1,否则其于本回合结束时将所有以此法造成伤害的牌当【借刀杀人】或【过河拆桥】对你使用。', + translate: { + jin_zhangchunhua: "晋张春华", + jin_zhangchunhua_prefix: "晋", + huishi: "慧识", + huishi_info: + "摸牌阶段,你可以放弃摸牌,改为观看牌堆顶的X张牌,获得其中的一半(向下取整),然后将其余牌置入牌堆底。(X为牌堆数量的个位数)", + qingleng: "清冷", + qingleng_info: + "一名角色的回合结束时,若其体力值与手牌数之和不小于X,则你可将一张牌当无距离限制的冰属性【杀】对其使用(X为牌堆数量的个位数)。若这是你本局游戏内首次对其发动此技能,则你摸一张牌。", + xuanmu: "宣穆", + xuanmu2: "宣穆", + xuanmu_info: "锁定技,隐匿技。你于其他角色的回合登场时,防止你受到的伤害直到回合结束。", + jin_simayi: "晋司马懿", + jin_simayi_prefix: "晋", + zhanghuyuechen: "张虎乐綝", + xijue: "袭爵", + xijue_gain: "袭爵", + xijue_info: + "锁定技,游戏开始时,你获得4枚“爵”。回合结束时,你获得X枚“爵”(X为你本回合内造成的伤害数)。你可弃置一枚“爵”并在合适的时机发动〖突袭〗和〖骁果〗。", + xijue_info_guozhan: + "锁定技,当你首次明置此武将牌时,你获得4枚“爵”。回合结束时,你获得X枚“爵”(X为你本回合内造成的伤害数)。你可弃置一枚“爵”并在合适的时机发动〖突袭〗和〖骁果〗。", + xijue_tuxi: "突袭", + xijue_tuxi_info: "摸牌阶段摸牌时,你可以少摸任意张牌,然后获得等量的角色的各一张手牌。", + xijue_tuxi_info_guozhan: "摸牌阶段摸牌时,你可以少摸至多两张牌,然后获得等量的角色的各一张手牌。", + xijue_xiaoguo: "骁果", + xijue_xiaoguo_info: + "其他角色的结束阶段开始时,你可以弃置一张手牌,令该角色选择一项:1.弃置一张装备牌,然后你摸一张牌;2.受到你对其造成的1点伤害。", + xijue_xiaoguo_info_guozhan: + "其他角色的结束阶段开始时,你可以弃置一张基本牌,令该角色选择一项:1.弃置一张装备牌;2.受到你对其造成的1点伤害。", + gz_duyu: "杜预", + duyu: "晋杜预", + duyu_prefix: "晋", + sanchen: "三陈", + sanchen_info: + "出牌阶段限一次。你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则其摸一张牌且〖三陈〗于此阶段内使用次数上限+1。", + sanchen_info_guozhan: + "出牌阶段,你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则其摸一张牌且你获得技能〖破竹〗直到回合结束。否则你本阶段内不能再发动〖三陈〗。", + zhaotao: "诏讨", + zhaotao_info: + "觉醒技,准备阶段,若你本局游戏内发动〖三陈〗的次数大于2,则你减1点体力上限并获得〖破竹〗。", + pozhu: "破竹", + pozhu_info: + "出牌阶段,你可以将一张手牌当做【出其不意】使用。若你未因此牌造成过伤害,则你不能再发动〖破竹〗直到回合结束。", + pozhu_info_guozhan: "出牌阶段限一次,你可以将一张手牌当做【出其不意】使用。", + jin_wangyuanji: "晋王元姬", + jin_wangyuanji_prefix: "晋", + shiren: "识人", + shiren_info: "隐匿技。你于其他角色的回合内登场时,若其有手牌,则你可对其发动〖宴戏〗。", + yanxi: "宴戏", + yanxi2: "宴戏", + yanxi_info: + "出牌阶段,你可选择一名有手牌的角色。你将该角色的一张随机手牌与牌堆顶的两张牌混合后展示,并选择其中一张。若你以此法选择的是该角色的手牌,则你获得这三张牌。否则你获得选择的牌。你通过〖宴戏〗得到的牌,不计入当前回合的手牌上限。", + yanxi_info_guozhan: + "出牌阶段,你可选择一名有手牌的角色。你将该角色的一张随机手牌与牌堆中的两张随机牌混合后展示,并选择其中一张。若你以此法选择的是该角色的手牌,则你获得这三张牌。否则你获得选择的牌。你通过〖宴戏〗得到的牌,不计入当前回合的手牌上限。", + jin_simazhao: "晋司马昭", + jin_simazhao_prefix: "晋", + tuishi: "推弑", + tuishi_info: + "隐匿技,你于其他角色A的回合内登场时,可于此回合结束时选择其攻击范围内的一名角色B。A选择一项:①对B使用一张【杀】。②你对A造成1点伤害。", + choufa: "筹伐", + choufa2: "筹伐", + choufa_info: + "出牌阶段限一次,你可展示一名其他角色的一张手牌并记录其类型A。你令其原类型不为A的手牌的牌名均视为【杀】且均视为无属性,直到其回合结束。", + xinchoufa: "筹伐", + xinchoufa_info: + "出牌阶段限一次,你可展示一名其他角色的一张手牌A。你令其所有类型与A不同的手牌的牌名均视为【杀】且均视为无属性,直到其回合结束。", + zhaoran: "昭然", + zhaoran2: "昭然", + zhaoran_info: + "出牌阶段开始时,你可令你的手牌对其他角色可见直到出牌阶段结束。若如此做,当你于此阶段内失去一张手牌后,若你的手牌里没有与此牌花色相同的牌且你本回合内未因该花色的牌触发过此效果,则你选择一项:①摸一张牌。②弃置一名其他角色的一张牌。", + visible_zhaoran: "invisible", + chengwu: "成务", + chengwu_info: "主公技,锁定技,其他晋势力角色攻击范围内的角色视为在你的攻击范围内。", + jin_xiahouhui: "晋夏侯徽", + jin_xiahouhui_prefix: "晋", + baoqie: "宝箧", + baoqie_info: + "隐匿技,锁定技。你登场后,从牌堆或弃牌堆中获得一张不为赠物的宝物牌。若此牌在你的手牌区内为宝物牌,则你可以使用此牌。", + jyishi: "宜室", + jyishi_info: + "每回合限一次,当有其他角色于其出牌阶段内因弃置而失去手牌后,你可令其获得这些牌中位于弃牌堆的一张,然后你获得其余位于弃牌堆的牌。", + shiduo: "识度", + shiduo_info: + "出牌阶段限一次,你可以与一名其他角色拼点。若你赢,你获得其所有手牌。然后你交给其X张手牌(X为你手牌数的一半,向下取整)。", + jin_simashi: "晋司马师", + jin_simashi_prefix: "晋", + taoyin: "韬隐", + taoyin2: "韬隐", + taoyin_info: "隐匿技,当你登场后,若当前回合角色存在且不是你,则你可令该角色本回合的手牌上限-2。", + yimie: "夷灭", + yimie2: "夷灭", + yimie_info: + "每回合限一次,当你对其他角色造成伤害时,若伤害值X小于Y,则你可失去1点体力,将伤害值改为Y。此伤害结算结束后,其回复(Y-X)点体力(Y为其体力值)。", + ruilve: "睿略", + ruilve2: "睿略", + ruilve_info: + "主公技,其他晋势力角色的出牌阶段限一次,该角色可以将一张带有伤害标签的基本牌或锦囊牌交给你。", + tairan: "泰然", + tairan2: "泰然", + tairan_info: + "锁定技,回合结束时,你将体力回复至体力上限,并将手牌摸至体力上限(称为“泰然”牌,且至多摸五张)。然后你的下一个出牌阶段开始时,你失去上一次以此法回复的体力值的体力,弃置所有“泰然”牌。", + gz_jin_simayi: "司马懿", + gz_jin_zhangchunhua: "张春华", + gz_jin_simazhao: "司马昭", + gz_jin_wangyuanji: "王元姬", + gz_jin_simashi: "司马师", + gz_jin_xiahouhui: "夏侯徽", + xinquanbian: "权变", + xinquanbian_info: + "出牌阶段,每当你首次使用/打出一种花色的手牌时,你可以从牌堆顶的X张牌中获得一张与此牌花色不同的牌,并将其余牌以任意顺序置于牌堆顶。出牌阶段,你至多可使用X张非装备手牌。(X为你的体力上限)", + shibao: "石苞", + zhuosheng: "擢升", + zhuosheng_info: + "出牌阶段,①你使用本轮内得到的基本牌时无次数和距离限制。②你使用本轮内获得的普通锦囊牌选择目标后,可令此牌的目标数+1或-1。③你使用本轮内得到的装备牌时可以摸一张牌(以此法得到的牌不能触发〖擢升〗)。", + zhuosheng_info_guozhan: + "出牌阶段,①你使用本轮内得到的基本牌时无距离限制。②你使用本轮内获得的普通锦囊牌选择目标后,可令此牌的目标数+1或-1。③你使用本轮内得到的装备牌时可以摸一张牌(以此法得到的牌不能触发〖擢升〗)。", + jin_yanghuiyu: "晋羊徽瑜", + jin_yanghuiyu_prefix: "晋", + gz_jin_yanghuiyu: "羊徽瑜", + huirong: "慧容", + huirong_info: + "隐匿技,锁定技。当你登场后,你令一名角色将手牌数摸至/弃至与体力值相同(至多摸至五张)。", + ciwei: "慈威", + ciwei_info: + "一名角色于其回合内使用第二张牌时,若此牌为基本牌或普通锦囊牌,则你可以弃置一张牌,取消此牌的所有目标。", + caiyuan: "才媛", + caiyuan_info: "锁定技。回合结束时,若你于你的上一个回合结束后未扣减过体力,则你摸两张牌。", + simazhou: "司马伷", + caiwang: "才望", + caiwang_info: + "当你使用或打出牌响应其他角色使用的牌,或其他角色使用或打出牌响应你使用的牌后,若这两张牌颜色相同,则你可以弃置对方的一张牌。", + naxiang: "纳降", + naxiang2: "纳降", + naxiang_info: + "锁定技,当你受到其他角色造成的伤害后,或你对其他角色造成伤害后,你对其发动〖才望①〗时的“弃置”改为“获得”直到你的下回合开始。", + cheliji: "彻里吉", + chexuan: "车悬", + chexuan_info: + "出牌阶段,若你的装备区里没有宝物牌,你可弃置一张黑色牌,选择一张【舆】置入你的装备区;当你失去装备区里的宝物牌后,你可进行判定,若结果为黑色,将一张随机的【舆】置入你的装备区。", + qiangshou: "羌首", + qiangshou_info: "锁定技,若你的装备区内有宝物牌,你与其他角色的距离-1。", + cheliji_sichengliangyu: "四乘粮舆", + cheliji_sichengliangyu_bg: "粮", + cheliji_sichengliangyu_info: + "一名角色的回合结束时,若你的手牌数小于体力值,你可以摸两张牌,然后弃置此牌。", + cheliji_tiejixuanyu: "铁蒺玄舆", + cheliji_tiejixuanyu_bg: "蒺", + cheliji_tiejixuanyu_info: + "其他角色的回合结束时,若其本回合未造成过伤害,你可以令其弃置两张牌,然后弃置此牌。", + cheliji_feilunzhanyu: "飞轮战舆", + cheliji_feilunzhanyu_bg: "轮", + cheliji_feilunzhanyu_info: + "其他角色的回合结束时,若其本回合使用过非基本牌,你可以令其交给你一张牌,然后弃置此牌。", + weiguan: "卫瓘", + zhongyun: "忠允", + zhongyun2: "忠允", + zhongyun_info: + "锁定技。每名角色的回合限一次,你受伤/回复体力后,若你的体力值与手牌数相等,你回复1点体力或对你攻击范围内的一名角色造成1点伤害;每名角色的回合限一次,你获得手牌或失去手牌后,若你的体力值与手牌数相等,你摸一张牌或弃置一名其他角色一张牌。", + shenpin: "神品", + shenpin_info: "当一名角色的判定牌生效前,你可以打出一张与判定牌颜色不同的牌代替之。", + zhongyan: "钟琰", + bolan: "博览", + bolan_info: + "①出牌阶段开始时,你可从三个描述中带有“出牌阶段限一次”的技能中选择一个,令当前回合角色获得直至此阶段结束。②其他角色出牌阶段限一次,其可以失去1点体力,令你发动一次〖博览①〗。", + yifa: "仪法", + yifa2: "仪法", + yifa_info: + "锁定技,其他角色使用【杀】或黑色普通锦囊牌指定你为目标后,其手牌上限-1直到其回合结束。", + ol_huaxin: "OL华歆", + ol_huaxin_prefix: "OL", + caozhao: "草诏", + caozhao_backup: "草诏", + caozhao_info: + "出牌阶段限一次,你可展示一张手牌并声明一种未以此法声明过的基本牌或普通锦囊牌,令一名体力不大于你的其他角色选择一项:令此牌视为你声明的牌,或其失去1点体力。然后若此牌声明成功,然后你可将其交给一名其他角色。", + olxibing: "息兵", + olxibing_info: + "当你受到其他角色造成的伤害后,你可弃置你或该角色两张牌,然后你们中手牌少的角色摸两张牌,以此法摸牌的角色不能使用牌指定你为目标直到回合结束。", + recaiwang: "才望", + recaiwang_info: + "①当你使用或打出牌响应其他角色使用的牌,或其他角色使用或打出牌响应你使用的牌后,若这两张牌颜色相同,则你可以弃置对方的一张牌。②若你的手牌数为1,则你可以将该手牌当做【闪】使用或打出。③若你的装备区牌数为1,则你可以将该装备当做【无懈可击】使用或打出。④若你的判定区牌数为1,则你可以将该延时锦囊牌当做【杀】使用或打出。", + recaiwang_hand: "才望", + recaiwang_equip: "才望", + recaiwang_judge: "才望", + yangyan: "杨艳", + xuanbei: "选备", + xuanbei_info: + "①游戏开始时,你从牌堆中获得两张具有应变标签的牌。②每回合限一次。当你使用的具有应变标签的牌结算结束后,你可将此牌对应的所有实体牌交给一名其他角色。", + xianwan: "娴婉", + xianwan_info: + "①当你需要使用【闪】时,若你的武将牌未横置,则你可以横置武将牌并视为使用【闪】。②当你需要使用【杀】时,若你的武将牌横置,则你可以重置武将牌并视为使用【杀】。", + yangzhi: "杨芷", + wanyi: "婉嫕", + wanyi_info: + "每回合每项限一次。出牌阶段,你可以将一张具有应变效果的牌当做【逐近弃远】/【出其不意】/【水淹七军】/【洞烛先机】使用。", + maihuo: "埋祸", + maihuo_info: + "①当你成为其他角色使用【杀】的目标后,若此【杀】不为转化牌且有对应的实体牌且其武将牌上没有“祸”且你是此牌的唯一目标,则你可以令此牌对你无效,并将此【杀】置于其武将牌上,称为“祸”。②一名其他角色的出牌阶段开始时,若其武将牌上有“祸”,则其对你使用此“祸”(有距离限制且计入次数限制,若你不是此牌的合法目标,则改为将此“祸”置入弃牌堆)。③当你对有“祸”的其他角色造成伤害后,你移去其“祸”。", + xinchang: "辛敞", + canmou: "参谋", + canmou_info: + "一名角色使用普通锦囊牌指定第一个目标时,若其手牌数为全场唯一最多,则你可以为此牌增加一个额外目标。", + congjian: "从鉴", + congjian_info: + "一名其他角色成为普通锦囊牌的唯一目标时,若其体力值为全场唯一最多,则你也可以成为此牌的目标。此牌结算结束后,若你受到过渠道为此牌的伤害,则你摸两张牌。", + xuangongzhu: "宣公主", + gaoling: "高陵", + gaoling_info: "隐匿技。当你于回合外明置此武将牌时,你可以令一名角色回复1点体力。", + qimei: "齐眉", + qimei_info: + "准备阶段,你可以选择一名其他角色。你获得如下效果直到下回合开始:①每回合限一次,当你或其获得牌/失去手牌后,若你与其手牌数相等,则另一名角色摸一张牌。②每回合限一次,当你或其的体力值变化后,若你与其体力值相等,则另一名角色摸一张牌。", + ybzhuiji: "追姬", + ybzhuiji_info: + "出牌阶段开始时,你可选择一项:①摸两张牌,并于出牌阶段结束时失去1点体力;②回复1点体力,并于出牌阶段结束时弃置两张牌。", + jin_yanghu: "晋羊祜", + jin_yanghu_prefix: "晋", + huaiyuan: "怀远", + huaiyuanx: "绥", + huaiyuan_info: + "①游戏开始时,你将你的手牌标记为“绥”。②当你失去一张“绥”后,你令一名角色执行一项:⒈其的手牌上限+1。⒉其的攻击范围+1。⒊其摸一张牌。③当你死亡时,你可令一名其他角色的手牌上限+X,且攻击范围+Y(X和Y为你自己被执行过〖怀远②〗的选项一和选项二的次数)。", + chongxin: "崇信", + chongxin_info: "出牌阶段限一次,你可重铸一张牌,且令一名有手牌的其他角色也重铸一张牌。", + dezhang: "德彰", + dezhang_info: "觉醒技。准备阶段,若你没有“绥”,则你减1点体力上限并获得〖卫戍〗。", + weishu: "卫戍", + weishu_info: + "锁定技。①当你于摸牌阶段外不因〖卫戍①〗而摸牌后,你令一名角色摸一张牌。②当你于弃牌阶段外不因〖卫戍②〗而弃置牌后,你弃置一名其他角色的一张牌。", + jin_jiachong: "晋贾充", + jin_jiachong_prefix: "晋", + xiongshu: "凶竖", + xiongshu_info: + "其他角色的出牌阶段开始时,你可弃置X张牌(X为你本轮内此前已发动过此技能的次数,为0则不弃)并展示其一张手牌,然后你预测“其本阶段内是否会使用与展示牌牌名相同的牌”。此阶段结束时,若你的预测正确,则你对其造成1点伤害;否则你获得展示牌。", + jianhui: "奸回", + jianhui_info: + "锁定技。当你造成伤害后,若受伤角色为A,则你摸一张牌;当你受到伤害后,若伤害来源为A,则A弃置一张牌。(A为除本次伤害外最近一次对你造成过伤害的角色)", + xinxuanbei: "选备", + xinxuanbei_info: + "出牌阶段限一次。你可选择一名其他角色区域内的一张牌。然后其对你使用对应实体牌为此牌的【杀】。然后若此【杀】,未对你造成过伤害,你摸一张牌;对你造成过伤害,你摸两张牌。", + xinwanyi: "婉嫕", + xinwanyi_info: + "①当你使用【杀】或普通锦囊牌指定其他角色为唯一目标后,你可将其的一张牌置于你的武将牌上作为“嫕”。②你不能使用/打出/弃置与“嫕”花色相同的牌。③结束阶段或当你受到伤害后,你令一名角色获得你的一张“嫕”。", + jin_guohuai: "郭槐", + zhefu: "哲妇", + zhefu_info: + "当你于回合外使用或打出牌后,你可令一名有手牌的其他角色选择一项:⒈弃置一张名称相同的牌。⒉受到你造成的1点伤害。", + yidu: "遗毒", + yidu_info: + "当你使用的【杀】或伤害性锦囊牌结算结束后,你可以展示一名未受到过渠道为此牌伤害的目标角色的至多三张手牌。若这些牌颜色均相同,则你弃置这些牌。", + wangxiang: "王祥", + bingxin: "冰心", + bingxin_info: + "每种牌名每回合限一次。当你需要使用基本牌时,若你的手牌数等于体力值且这些牌的颜色均相同,则你可以摸一张牌,视为使用一张基本牌。", + ol_lisu: "OL李肃", + ol_lisu_prefix: "OL", + qiaoyan: "巧言", + qiaoyan_info: + "锁定技,当你于回合外受到其他角色造成的伤害时,若你:有“珠”,则你令伤害来源获得“珠”;没有“珠”,则你防止此伤害,然后摸一张牌,并将一张牌正面朝上置于武将牌上,称为“珠”。", + xianzhu: "献珠", + xianzhu_info: + "锁定技,出牌阶段开始时,你令一名角色A获得“珠”。若A不为你自己,则你选择你攻击范围内的一名角色B,视为A对B使用一张【杀】。", + chengjichengcui: "成济成倅", + oltousui: "透髓", + oltousui_info: "你可以将任意张牌置于牌堆底,视为使用一张需使用等量张【闪】抵消的【杀】。", + olchuming: "畜鸣", + olchuming_info: + "锁定技。当你对其他角色造成伤害时,或当你受到其他角色造成的伤害时,若此伤害的渠道不为牌或没有对应的实体牌,此伤害+1,否则其于本回合结束时将所有以此法造成伤害的牌当【借刀杀人】或【过河拆桥】对你使用。", - yingbian_pack1:'文德武备·理', - yingbian_pack2:'文德武备·备', - yingbian_pack3:'文德武备·果', - yingbian_pack4:'文德武备·戒', - yingbian_pack5:'文德武备·约', + yingbian_pack1: "文德武备·理", + yingbian_pack2: "文德武备·备", + yingbian_pack3: "文德武备·果", + yingbian_pack4: "文德武备·戒", + yingbian_pack5: "文德武备·约", }, }; }); diff --git a/character/yxs.js b/character/yxs.js index 7af6f3ee5..5ea6c043b 100644 --- a/character/yxs.js +++ b/character/yxs.js @@ -1,3134 +1,3354 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../noname.js"; +game.import("character", function () { return { - name:'yxs', - character:{ - yxs_qinqiong:["male","wei",4,["yxs_fanji","yxs_menshen"],[]], - yxs_wuzetian:['female','wu',4,['nvquan','qiandu','yxsweiyi']], - yxs_caocao:['male','wei',4,['zhulu','xieling']], - yxs_mozi:['male','qun',3,['jieyong','feigong','jianai']], - yxs_bole:['male','wu',3,['bolehuiyan','xiangma']], - yxs_aijiyanhou:['female','qun',3,['seyou','sheshi']], - yxs_diaochan:['female','qun',3,['fengyi','wange']], - yxs_yangyuhuan:['female','wu',3,['fengyan','nichang']], - yxs_baosi:['female','wu',3,['jieyin','fenghuo']], - yxs_napolun:['male','wei',4,['tongling','fanpu']], - yxs_kaisa:['male','shu',4,['ducai']], - yxs_zhuyuanzhang:['male','wu',4,['qiangyun']], + name: "yxs", + character: { + yxs_qinqiong: ["male", "wei", 4, ["yxs_fanji", "yxs_menshen"], []], + yxs_wuzetian: ["female", "wu", 4, ["nvquan", "qiandu", "yxsweiyi"]], + yxs_caocao: ["male", "wei", 4, ["zhulu", "xieling"]], + yxs_mozi: ["male", "qun", 3, ["jieyong", "feigong", "jianai"]], + yxs_bole: ["male", "wu", 3, ["bolehuiyan", "xiangma"]], + yxs_aijiyanhou: ["female", "qun", 3, ["seyou", "sheshi"]], + yxs_diaochan: ["female", "qun", 3, ["fengyi", "wange"]], + yxs_yangyuhuan: ["female", "wu", 3, ["fengyan", "nichang"]], + yxs_baosi: ["female", "wu", 3, ["jieyin", "fenghuo"]], + yxs_napolun: ["male", "wei", 4, ["tongling", "fanpu"]], + yxs_kaisa: ["male", "shu", 4, ["ducai"]], + yxs_zhuyuanzhang: ["male", "wu", 4, ["qiangyun"]], // yxs_jinke:['male','qun',3,['cike','qiangxi']], - yxs_libai:['male','qun',3,['miaobi','zhexian']], - yxs_luban:['male','wu',3,['guifu','lshengong']], - yxs_lvzhi:['female','shu',4,['zhensha','xumou']], - yxs_goujian:['male','wu',3,['keji','tuqiang']], - yxs_lishimin:['male','qun',4,['kongju']], - yxs_huamulan:['female','shu',3,['xiaoji','yizhuang']], - yxs_luobinhan:['male','wu',4,['xiadao','sheshu','lguiyin']], - yxs_chengjisihan:['male','qun',4,['mashu','qianglue']], - yxs_mingchenghuanghou:['female','shu',3,['tiewan','chajue']], - yxs_wangzhaojun:['female','wei',3,['heqin','wluoyan']], - yxs_luocheng:['male','wu',4,['hanqiang','biaoqi']], - yxs_direnjie:['male','wei',3,['shentan','kanpo']], - yxs_sunwu:['male','wu',3,['bingsheng','taolue']], - yxs_chengyaojin:['male','shu',4,['sanbanfu']], - yxs_yujix:['female','shu',3,['ysheshen','changnian']], - yxs_xiangyu:['male','shu',4,['wushuang','ciqiu']], - yxs_yingzheng:['male','qun',4,['jianxiong','batu']], - yxs_yuefei:['male','qun',4,['longdan','wumu']], - yxs_fuermosi:['male','wei',3,['yanyi','jiean']], - yxs_guiguzi:['male','qun',3,['baihe','yinyang','xiushen']], - yxs_xiaoqiao:['female','wu',3,['chujia','zhijie']], - yxs_luzhishen:['male','wei',4,['yxsdili','kuangchan']], - yxs_zhaoyong:['male','shu',3,['zyhufu','hanbei']], - yxs_yangguang:['male','qun',3,['shiqin','yaoyi']], - yxs_tangbohu:['male','qun',3,['luobi','fengliu']], - yxs_zhangsanfeng:['male','wei',4,['zbudao','taiji']], - yxs_nandinggeer:['female','shu',3,['huli','xianqu','yixin']], - yxs_weizhongxian:['male','qun',3,['zhuxin','wlianhuan']], - yxs_meixi:['female','shu',3,['liebo','yaoji']], - yxs_lanlinwang:['male','shu',4,['guimian','lyuxue']], + yxs_libai: ["male", "qun", 3, ["miaobi", "zhexian"]], + yxs_luban: ["male", "wu", 3, ["guifu", "lshengong"]], + yxs_lvzhi: ["female", "shu", 4, ["zhensha", "xumou"]], + yxs_goujian: ["male", "wu", 3, ["keji", "tuqiang"]], + yxs_lishimin: ["male", "qun", 4, ["kongju"]], + yxs_huamulan: ["female", "shu", 3, ["xiaoji", "yizhuang"]], + yxs_luobinhan: ["male", "wu", 4, ["xiadao", "sheshu", "lguiyin"]], + yxs_chengjisihan: ["male", "qun", 4, ["mashu", "qianglue"]], + yxs_mingchenghuanghou: ["female", "shu", 3, ["tiewan", "chajue"]], + yxs_wangzhaojun: ["female", "wei", 3, ["heqin", "wluoyan"]], + yxs_luocheng: ["male", "wu", 4, ["hanqiang", "biaoqi"]], + yxs_direnjie: ["male", "wei", 3, ["shentan", "kanpo"]], + yxs_sunwu: ["male", "wu", 3, ["bingsheng", "taolue"]], + yxs_chengyaojin: ["male", "shu", 4, ["sanbanfu"]], + yxs_yujix: ["female", "shu", 3, ["ysheshen", "changnian"]], + yxs_xiangyu: ["male", "shu", 4, ["wushuang", "ciqiu"]], + yxs_yingzheng: ["male", "qun", 4, ["jianxiong", "batu"]], + yxs_yuefei: ["male", "qun", 4, ["longdan", "wumu"]], + yxs_fuermosi: ["male", "wei", 3, ["yanyi", "jiean"]], + yxs_guiguzi: ["male", "qun", 3, ["baihe", "yinyang", "xiushen"]], + yxs_xiaoqiao: ["female", "wu", 3, ["chujia", "zhijie"]], + yxs_luzhishen: ["male", "wei", 4, ["yxsdili", "kuangchan"]], + yxs_zhaoyong: ["male", "shu", 3, ["zyhufu", "hanbei"]], + yxs_yangguang: ["male", "qun", 3, ["shiqin", "yaoyi"]], + yxs_tangbohu: ["male", "qun", 3, ["luobi", "fengliu"]], + yxs_zhangsanfeng: ["male", "wei", 4, ["zbudao", "taiji"]], + yxs_nandinggeer: ["female", "shu", 3, ["huli", "xianqu", "yixin"]], + yxs_weizhongxian: ["male", "qun", 3, ["zhuxin", "wlianhuan"]], + yxs_meixi: ["female", "shu", 3, ["liebo", "yaoji"]], + yxs_lanlinwang: ["male", "shu", 4, ["guimian", "lyuxue"]], }, - characterIntro:{ - yxs_qinqiong:'秦琼(?—638年),字叔宝,齐州历城(今山东济南市)人,隋末唐初名将。初为隋将,先后在来护儿、张须陀、裴仁基帐下任职,因勇武过人而远近闻名。后随裴仁基投奔瓦岗军领袖李密,瓦岗败亡后转投王世充,因见王世充为人奸诈,与程咬金等人一起投奔李唐。投唐后随李世民南征北战,是一个能在万马军中取敌将首级的勇将,但也因此浑身是伤。唐统一后,秦琼久病缠身,于贞观十二年(638)病逝。生前官至左武卫大将军、翼国公,死后追赠为徐州都督、胡国公,谥曰“壮”。贞观十七年被列入凌烟阁二十四功臣。', - yxs_wuzetian:'中国历史上唯一一个正统的女皇帝,也是继位年龄最大的皇帝(67岁即位),又是寿命最长的皇帝之一(终年82岁)。唐高宗时为皇后(655—683)、唐中宗和唐睿宗时为皇太后(683—690),后自立为武周皇帝(690—705),改国号“唐”为“周”,定都洛阳,并号其为“神都”。史称“武周”或“南周”,705年退位。武则天也是一位女诗人和政治家。', - yxs_caocao:' 曹操(155年7月18日-220年3月15日),字孟德,一名吉利,小字阿瞒,汉族,沛国谯(今安徽省亳州市)人。曹操生于宦官之家,适逢乱世,但是胸怀大志,参与剿灭董卓战争,之后在官渡大败袁绍,占据北方,挟天子以令诸侯。最后兵败赤壁,与吴,蜀三分天下。', - yxs_mozi:' 宋国大夫,名翟,鲁人(今山东滕州人)。墨子是我国战国时期著名的思想家、教育家、科学家、军事家、社会活动家,墨家学派的创始人。墨子曾阻止鲁阳文君攻郑,说服公输般而止楚攻宋。楚惠王打算以书社封墨子,越王也打算以吴之地方五百里以封墨子,但墨子都没有接受。其创立墨家学说,并有《墨子》一书传世。', - yxs_bole:'伯乐,名孙阳,字子良,一作王良。春秋齐(今山东省威武)人。善于相马,为赵简子御。相传天上御者名伯乐,因其善相,遂号之,传至今。初,见老骥 拖车,喘息不定,伯乐哀之,马亦哀啼,方知乃良驹。后世长以伯乐比喻慧眼识人者。', - yxs_aijiyanhou:'埃及艳后即克丽奥佩托拉七世,是古埃及托勒密王朝的最后一任法老。她通过政治联姻为古埃及赢取了22年的和平。埃及艳后的一生富有戏剧性,特别是卷入罗马共和末期的政治漩涡,同恺撒、安东尼关系密切,并伴以种种传闻逸事,使她成为文学和艺术作品中的著名人物。', - yxs_diaochan:'中国古代四大美女之一,今山西忻州人,有野史说其姓霍,无名,又有一说称其任姓,小字红昌。貂蝉是东汉末年司徒王允的义女,国色天香,有倾国倾城之貌,相传貂婵在后花园拜月时,忽然轻风吹来,一块浮云将那皎洁的明月遮住。这时正好王允瞧见,便说我的女儿和月亮比美,月亮比不过,赶紧躲在云彩后面。此后,世人常用“闭月”来形容貂婵的美貌。', - yxs_yangyuhuan:'唐朝贵妃,名玉环,字太真,蒲州永乐人(今山西永济)。杨玉环自小习音律,善歌舞,姿色超群。27岁时,得唐玄宗宠幸,召入宫中,封为贵妃。杨贵妃天生丽质,回眸一笑百媚生,六宫粉黛无颜色,堪称大唐第一美女,此后千余年无出其右者。其与西施、昭君、貂蝉并称中国古代四大美女。', - yxs_baosi:'褒姒,周幽王姬宫涅的王后,褒姒原是一名弃婴,被一对做小买卖的夫妻收养,在褒国(今陕西省汉中西北)长大,公元前七七九年(周幽王三年),周幽王征伐有褒国,褒人献出美女褒姒乞降,幽王爱如掌上明珠,立为妃,宠冠周王宫,翌年,褒姒生子伯服(一作伯般),幽王对她更加宠爱,竟废去王后申氏和太子宜臼,册立褒姒为王后,立伯服为太子,周太史伯阳叹气道:“周王室已面临大祸,这是不可避免的了。”', - yxs_napolun:'法兰西第一共和国执政、法兰西第一帝国皇帝,出生在法国科西嘉岛,是一位卓越的军事天才。他多次击败保王党的反扑和反法同盟的入侵,捍卫了法国大革命的成果。他颁布的《民法典》更是成为了后世资本主义国家的立法蓝本。他执政期间多次对外扩张,形成了庞大的帝国体系,创造了一系列军事奇迹。', - kaisa:'凯撒是罗马共和国末期杰出的军事统帅、政治家。他公元前60年与庞培、克拉苏秘密结成前三巨头同盟,随后出任高卢总督,在大约8年的时间内征服了高卢全境(今法国一带),还袭击了日耳曼和不列颠。前49年,他率军占领罗马,打败庞培,集大权于一身,实行独裁统治并制定了《儒略历》。', - yxs_zhuyuanzhang:' 朱元璋,明王朝的开国皇帝。原名重八,后取名兴宗。汉族,濠州(今安徽凤阳县东)钟离太平乡人。朱元璋自幼贫寒,父母兄长均死于瘟疫,孤苦无依,入皇觉寺为小沙弥,入寺不到二个月,因荒年寺租难收,寺主封仓遣散众僧,只得离乡为游方僧,后参加了起义军,并改名“朱元璋”意为诛(朱)灭元朝的璋(璋,古代的一种玉器)。25岁时参加郭子兴领导的红巾军反抗蒙元暴政,在郭子兴手下,率兵出征,有攻必克;因此郭便把养女马氏嫁与了他。元至正二十八年(1368),在基本击破各路农民起义军和扫平元的残余势力后,于南京称帝,国号大明,年号洪武,建立了全国统一的封建政权。朱元璋统治时期被称为“洪武之治”。葬于明孝陵。', - yxs_jinke:'荆轲,喜好读书击剑,为人慷慨侠义。后游历到燕国,被称为“荆卿”(或荆叔),随之由燕国智勇深沉的“节侠”田光推荐给太子丹,拜为上卿。秦国灭赵后,兵锋直指燕国南界,太子丹震惧,与田光密谋,决定派荆轲入秦行刺秦王。荆轲献计太子丹,拟以秦国叛将樊于期之头及燕督亢(今河北涿县、易县、固安一带,是一块肥沃的土地)地图进献秦王,相机行刺。太子丹不忍杀樊于期,荆轲只好私见樊于期,告以实情,樊于期为成全荆轲而自刎。', - yxs_libai:'字太白,号青莲居士,又号“谪仙人”,祖籍陇西郡成纪县(今甘肃省平凉市静宁县南)。李白是唐朝著名的浪漫主义诗人,有“诗仙”之称。李白生平作诗无数,存世诗文达千余篇之多,《蜀道难》、《行路难》、《梦游天姥吟留别》、《将进酒》等诗篇脍炙人口,妇孺皆知,另有《李太白集》传世。', - yxs_luban:' 鲁班,姓公输,名般。战国时期鲁国公族之后,故又称公输子、班输等。出身于工匠世家,是我国古代最著名的发明家、建筑家。鲁班一生发明无数,而最具贡献意义的则要数木工使用的工具,诸如墨斗、锯、和鲁班尺等。为后世的建筑学提供了最基础的工具。除此之外,相传石磨、云梯等工具也是鲁班发明。', - yxs_lvzhi:' 吕雉,西汉开国皇帝高祖刘邦的原配夫人,中国历史上第一位掌权的女性统治者,是历史上有记载以来的第一位皇后、皇太后。于高祖刘邦死后掌握政权,实行高祖的“黄老政治”,百姓安乐民富国强,为“文景之治”奠定了坚实的基础。', - yxs_goujian:'勾践,又写作句践,在出土文物“越王勾践剑”里写为鸠浅,司马贞《史记索隐》引《纪年》作菼执。是中国春秋时代后期的越国君主。有关他的先世,有说“其先禹之苗裔”,亦有说“先世无所考”,也有说他是“祝融之后”并且是楚国的芈姓,众说纷纭。父亲则是越侯允常。', - yxs_lishimin:' 李世民,唐朝第二位皇帝。他的前半生是立下赫赫武功的军事家。平窦建德、王世充之后,始大量接触文学与书法,有《温泉铭》、《晋祠铭》等墨宝传世。后在玄武门之变杀死自己的兄弟李建成、李元吉两人,成为太子,唐高祖不久被迫让位。世民即位为帝后,积极听取群臣的意见、努力学习文治天下,成功转型为中国史上最出名的政治家与明君之一。唐太宗开创了历史上的“贞观之治”,经过主动消灭群雄割据势力,虚心纳谏、在国内厉行节约、使百姓休养生息,终于使得社会出现了国泰民安的局面。此举为后来的开元盛世奠定了重要的基础,将中国传统农业社会推向一个高峰。', - yxs_huamulan:' 花木兰是中国文学作品中的一位代父从军的巾帼英雄,其真实性不详。花木兰最早出现于南北朝一首叙事诗《木兰辞》中,该诗约作于北魏,最初录于南朝陈的《古今乐录》,僧人智匠在《古今乐录》称:“木兰不知名。”', - yxs_luobinhan:'罗宾汉是英国民间传说中的侠盗式的一个英雄人物,人称汉丁顿伯爵。他武艺出众、机智勇敢、聪明,仇视官吏和教士,是一位劫富济贫、行侠仗义的绿林英雄。传说他住在诺丁汉雪伍德森林。从14世纪中叶起,关于罗宾汉的民谣和传说就开始在民间流传。罗宾汉最突出的就是射箭术高超。现代射箭比赛里就有“罗宾汉”这一术语,指射中另一支已中靶心的箭。', - yxs_chengjisihan:'成吉思汗,名铁木真,孛儿只斤氏,奇渥温姓,乞颜(起延)部人。从小遭受结拜兄弟札木合迫害,形成刚毅坚韧的性格。1206年,被推举为蒙古帝国的大汗,统一蒙古各部,为之后的进攻中原提供了坚实的基础。', - yxs_mingchenghuanghou:'明成皇后,朝鲜近代史上的女政治家,本名闵兹映,通称闵妃,是朝鲜京畿道骊州郡人。她是朝鲜王朝高宗李熙的王妃,骊兴闵氏外戚集团的核心人物,19世纪末朝鲜的实际统治者。由于闵妃早期主张开放、后期力抗日本并身死殉难,故深受后世韩国人民的尊崇。 1897年,高宗李熙改国号称“大韩帝国”,追谥闵妃为“孝慈元圣正化合天明成皇后”,故现今韩国史学家多称她为“明成皇后”。', - yxs_wangzhaojun:'王昭君,名嫱,字昭君,晋朝时为避司马昭讳,又称“明妃”,汉元帝时期宫女,汉族,西汉南郡秭归(今湖北省兴山县)人。匈奴呼韩邪单于阏氏。 “昭君出塞”是汉匈交往上的大事,稳定了汉朝和匈奴的外交关系,《汉书.匈奴传》和《后汉书.南匈奴传》都记载了这件事。相传和亲途中,南飞的大雁听到昭君奏起悲壮的离别之曲,看到骑在马上的这位美丽女子,忘记摆动翅膀,跌落地下,因此得“落雁”之名。昭君出塞的故事也被后世传为佳话。', - yxs_luocheng:'《隋唐》说书和《说唐传》中的虚构人物,隋唐十八杰中列第七,十六杰列第八。在清初禇人获的讲史小说《隋唐演义》中,也虚构了罗成,是燕山罗艺的儿子,秦琼的表弟,精通枪法。', - yxs_direnjie:'唐武周时期杰出的著名政治家,时任豫州刺史、魏州刺史等要职,官至凤阁鸾台平章事、内史,卒后追封梁国公。狄仁杰生于贞观、卒于武周时期,经历了大唐鼎盛和动乱的年代。其一生秉承了以民为本、不畏权贵、为民请命的宗旨。狄仁杰通晓了吏治、兵刑等法律制度,在任大理丞任期内解决了诸多案件,被誉为“神探”。狄仁杰为官清廉,素有政绩,有辅国安邦之能,史称“唐室砥柱”。', - yxs_sunwu:'著名军事家,字长卿,中国春秋时期齐国乐安人。曾率领吴国军队大破数倍于己的楚国军队,占领了楚国都城郢城,几乎亡楚。其著有巨作《孙子兵法》十三篇,为后世兵法家所推崇,被誉为“兵学圣典”,置于《武经七书》之首,被译为英文、法文、德文、日文,成为国际间最著名的兵学典范之书。后人尊称其为孙子、孙武子、兵圣、百世兵家之师、东方兵学的鼻祖。', - yxs_chengyaojin:'程咬金,原名咬金,后更名知节,字义贞,中国济州东阿斑鸠店人(现山东省东平县斑鸠店)。“凌烟阁二十四功臣”之一,唐朝开国名将。隋朝末年,隋炀帝杨广统治残暴,骄奢荒淫,民不聊生,最终爆发了大规模的农民起义。程咬金先入瓦岗军,投王世充,后降唐,成为秦王李世民的骨干成员。据史书记载,程咬金“少骁勇,善用马槊。”而在以《说唐》为代表的系列话本及历史演义小说中,程咬金则使得一柄八卦宣花斧,以“三板斧”武艺著称,是一名性格直爽、粗中有细的福将。', - yxs_yujix:'虞姬,又称虞美人,西楚霸王项羽爱姬,相传为江苏沭阳县颜集乡人,一说苏州常熟人。公元前209年,项羽与叔父项梁起义反秦。项羽军中战将虞子期的妹妹虞姬,貌美好武,倾慕年轻勇猛的项羽,嫁其为妾,常伴左右随军出征,至终形影不离。 公元前202年,项羽在垓下之战中被刘邦、韩信、彭越三方大军合围困于垓下(今安徽灵璧县城南沱河北岸城后村),身陷十面埋伏,兵孤粮缺,夜闻四面楚歌,楚军士气尽失。项羽认为大势已去,帐中酌酒,对着虞姬唱起悲壮的“垓下歌”。虞姬拔剑起舞,含泪唱和:“汉兵已略地,四面楚歌声。大王义气尽,贱妾何聊生。”为免后顾之忧影响项羽突围,唱毕于其面前自刎。', - yxs_xiangyu:'项籍(前232—前202)字羽,通常被称作项羽,中国古代著名将领及政治人物,汉族,秦下相(今江苏省宿迁市宿城区)人。秦末时被楚怀王熊心封为鲁公,在前207年的决定性战役巨鹿之战中统率楚军大破秦军。秦亡后自封“西楚霸王”,统治黄河及长江下游的梁楚九郡。后在楚汉战争中为汉高祖刘邦所败,在乌江(今安徽和县)自刎而死。', - yxs_yingzheng:'秦始皇,赢姓,赵氏,名政,秦庄襄王之子。秦始皇22岁时,在雍城举行国君成人加冕仪式,开始“亲理朝政”。后除掉吕不韦,嫪毐等人,重用李斯,尉缭。自公元前230年至前221年,采取由近及远,集中力量,各个击破的策略,先后灭六国,完成统一中国的大业。同时建立起历史上第一个书同文,度同制,车同轨,行同伦的中央集权国家——秦朝。', - yxs_yuefei:' 岳飞(1103年-1142年),字鹏举,相州汤阴(今属河南)人。南宋军事家,中国历史上著名的抗金名将。绍兴十一年(1142)十二月二十九日,秦桧以“莫须有”的罪名将岳飞毒死于临安风波亭。1162年,宋孝宗时诏复官,谥武穆,宁宗时追封为鄂王,改谥忠武,有《岳武穆集》传世。', - yxs_fuermosi:'福尔摩斯,是一个虚构的侦探人物,是由19世纪末20世纪初的英国侦探小说家阿瑟?柯南·道尔所塑造的一个才华横溢的侦探形象。福尔摩斯不但头脑冷静、观察力敏锐、推理能力极强;而且,他的剑术、拳术和小提琴演奏水平也相当高超,已经成为侦探小说中的典型代表人物之一。', - yxs_guiguzi:'本名王诩,春秋时纵横家,卫国(今河南鹤壁一带)人。曾隐于清溪鬼谷,常入云梦采药修道,弟子无数。有张仪、苏秦、孙膑、庞涓四弟子。精于兵法、奇门遁甲、五行八卦之学。后人称之为王禅老祖。今传《鬼谷子》十四篇。', - yxs_xiaoqiao:'小乔,庐江皖县(今安徽潜山)人。 史书中称小桥,是中国汉末三国时期的女性, 乔公的次女,东吴名将周瑜的妻子。传说与其姐大乔均为绝世美女。合称“二乔”。', - yxs_luzhishen:'鲁智深,梁山泊第十三位好汉,十员步军头领第一名。鲁智深原名鲁达,绰号花和尚。是经略的提辖,因为见郑屠欺侮金翠莲父女,三拳打死了镇关西。被官府追捕,逃到五台山削发为僧,改名鲁智深。', - yxs_zhaoyong:'赵武灵王,战国中后期赵国君主,嬴姓,赵氏,名雍。赵武灵王在位时,推行的“胡服骑射”政策,赵国因而得以强盛,灭中山国,败林胡、楼烦二族,辟云中、雁门、代三郡,并修筑了“赵长城”。', - yxs_yangguang:'隋炀帝杨广,是隋朝第二代皇帝,华阴(今陕西华阴)人,生于隋京师长安。杨广在位期间修建大运河,营建东都迁都洛阳城,开创科举制度,亲征吐谷浑,三征高句丽。但因为杨广滥用民力,导致了隋朝的灭亡,618年在江都被部下缢杀。', - yxs_tangbohu:'唐伯虎,名寅,字伯虎,自号六如居士,明代诗人、画家,吴县(今江苏苏州)人。出身富商家庭,后家道衰落,因祝枝山之劝而潜心读书。公试时为状元,会试时候因科场舞弊案牵连而被斥为吏。后绝意仕途,以卖画为生。唐伯虎为人玩世不恭而又才气横溢,诗文擅名,与祝枝山、文征明、徐祯卿并称“江南四大才子”,画名更著,与沈周、文征明、仇英并称“吴门四家”。民间盛传其点秋香的故事。', - yxs_zhangsanfeng:'明朝最著名的武术家、道士。原名张通,字君宝,在武当山开山立派,成为武当派开山祖师。明英宗赐号“通微显化真人”;明宪宗特封号为“韬光尚志真仙”;明世宗赠封他为“清虚元妙真君”。传说其丰姿魁伟,大耳圆目,须髯如戟。无论寒暑,只一衲一蓑,一餐能食升斗,或数日一食,或数月不食,事能前知。其在武术上的造诣和超乎寻常的长寿都为后人称道。 曾传洪武年间,两度受朱元璋诏请入京,皆避而不见。其与明初巨贾沈万三亦有交际。其所创太极拳一直延续至今,成为后人养身妙术。', - yxs_nandinggeer:'出生于意大利,英国护士和统计学家。她谙熟数学,精通英、法、德、意四门语言,除古典文学外,还精于自然科学、历史和哲学,擅长音乐与绘画。在德国学习护理后,曾往伦敦的医院工作。南丁格尔于1854年和38位护士到克里米亚野战医院工作,成为该院的护士长,被称为“克里米亚的天使”又称“提灯女神”。1860年6月15日,南丁格尔在伦敦成立世界第一所护士学校。为了纪念她的成就,1912年,国际护士会倡仪各国医院和护士学校定每年5月12日南丁格尔诞辰日举行纪念活动,并将5月12日定为“国际护士节”,以缅怀和纪念这位伟大的女性。', - yxs_weizhongxian:'魏忠贤(1568年-1627年12月11日),字完吾,北直隶肃宁(今河北沧州肃宁县)人,汉族,原名李进忠。由才人王氏复姓,出任秉笔太监后,改名魏忠贤。明朝末期宦官。明熹宗时期,出任司礼秉笔太监,极受宠信,被称为“九千九百岁”,排除异己,专断国政,以致人们“只知有忠贤,而不知有皇上”。朱由检继位后,打击惩治阉党,治魏忠贤十大罪,命逮捕法办,自缢而亡,其余党亦被肃清。', - yxs_meixi:'妺喜,姓嬉(喜),生卒年不详,亦作妺嬉、末喜、末嬉,有施氏之女,夏朝最后一位君主夏桀的王后。根据先秦时代记述女子名时所用的全称和简称方式,妺喜应姓喜,即嬉(也作僖)。由于其名字的“妺”字与“妹妹”的“妹”字字形相似,且在《庄子》等作中也有以妺为妹的用法,因此常误作"妹喜"。', - yxs_lanlinwang:'高长恭(541年―573年),又名高孝瓘、高肃,祖籍渤海调蓨(今河北省景县),神武帝高欢之孙,文襄帝高澄第四子,生母不详,南北朝时期北齐宗室、将领,封爵兰陵郡王。高长恭貌柔心壮,音容兼美。为将躬勤细事,每得甘美,虽一瓜数果,必与将士分享。累次升任至并州刺史。突厥攻入晋阳,高长恭奋力将其击退。邙山之战,高长恭为中军,率领五百骑兵再入周军包围圈,直至金墉城下,因高长恭戴着头盔,城中的人不确定是敌军或是我军,直到高长恭把头盔脱下来城上的人才知道是高长恭,派弓箭手开始放箭保护他,之后高长恭成功替金墉解围,高长恭在此次战中威名大振,士兵们为此战而讴歌他,即后来知名的《兰陵王入阵曲》。', + characterIntro: { + yxs_qinqiong: + "秦琼(?—638年),字叔宝,齐州历城(今山东济南市)人,隋末唐初名将。初为隋将,先后在来护儿、张须陀、裴仁基帐下任职,因勇武过人而远近闻名。后随裴仁基投奔瓦岗军领袖李密,瓦岗败亡后转投王世充,因见王世充为人奸诈,与程咬金等人一起投奔李唐。投唐后随李世民南征北战,是一个能在万马军中取敌将首级的勇将,但也因此浑身是伤。唐统一后,秦琼久病缠身,于贞观十二年(638)病逝。生前官至左武卫大将军、翼国公,死后追赠为徐州都督、胡国公,谥曰“壮”。贞观十七年被列入凌烟阁二十四功臣。", + yxs_wuzetian: + "中国历史上唯一一个正统的女皇帝,也是继位年龄最大的皇帝(67岁即位),又是寿命最长的皇帝之一(终年82岁)。唐高宗时为皇后(655—683)、唐中宗和唐睿宗时为皇太后(683—690),后自立为武周皇帝(690—705),改国号“唐”为“周”,定都洛阳,并号其为“神都”。史称“武周”或“南周”,705年退位。武则天也是一位女诗人和政治家。", + yxs_caocao: + " 曹操(155年7月18日-220年3月15日),字孟德,一名吉利,小字阿瞒,汉族,沛国谯(今安徽省亳州市)人。曹操生于宦官之家,适逢乱世,但是胸怀大志,参与剿灭董卓战争,之后在官渡大败袁绍,占据北方,挟天子以令诸侯。最后兵败赤壁,与吴,蜀三分天下。", + yxs_mozi: + " 宋国大夫,名翟,鲁人(今山东滕州人)。墨子是我国战国时期著名的思想家、教育家、科学家、军事家、社会活动家,墨家学派的创始人。墨子曾阻止鲁阳文君攻郑,说服公输般而止楚攻宋。楚惠王打算以书社封墨子,越王也打算以吴之地方五百里以封墨子,但墨子都没有接受。其创立墨家学说,并有《墨子》一书传世。", + yxs_bole: + "伯乐,名孙阳,字子良,一作王良。春秋齐(今山东省威武)人。善于相马,为赵简子御。相传天上御者名伯乐,因其善相,遂号之,传至今。初,见老骥 拖车,喘息不定,伯乐哀之,马亦哀啼,方知乃良驹。后世长以伯乐比喻慧眼识人者。", + yxs_aijiyanhou: + "埃及艳后即克丽奥佩托拉七世,是古埃及托勒密王朝的最后一任法老。她通过政治联姻为古埃及赢取了22年的和平。埃及艳后的一生富有戏剧性,特别是卷入罗马共和末期的政治漩涡,同恺撒、安东尼关系密切,并伴以种种传闻逸事,使她成为文学和艺术作品中的著名人物。", + yxs_diaochan: + "中国古代四大美女之一,今山西忻州人,有野史说其姓霍,无名,又有一说称其任姓,小字红昌。貂蝉是东汉末年司徒王允的义女,国色天香,有倾国倾城之貌,相传貂婵在后花园拜月时,忽然轻风吹来,一块浮云将那皎洁的明月遮住。这时正好王允瞧见,便说我的女儿和月亮比美,月亮比不过,赶紧躲在云彩后面。此后,世人常用“闭月”来形容貂婵的美貌。", + yxs_yangyuhuan: + "唐朝贵妃,名玉环,字太真,蒲州永乐人(今山西永济)。杨玉环自小习音律,善歌舞,姿色超群。27岁时,得唐玄宗宠幸,召入宫中,封为贵妃。杨贵妃天生丽质,回眸一笑百媚生,六宫粉黛无颜色,堪称大唐第一美女,此后千余年无出其右者。其与西施、昭君、貂蝉并称中国古代四大美女。", + yxs_baosi: + "褒姒,周幽王姬宫涅的王后,褒姒原是一名弃婴,被一对做小买卖的夫妻收养,在褒国(今陕西省汉中西北)长大,公元前七七九年(周幽王三年),周幽王征伐有褒国,褒人献出美女褒姒乞降,幽王爱如掌上明珠,立为妃,宠冠周王宫,翌年,褒姒生子伯服(一作伯般),幽王对她更加宠爱,竟废去王后申氏和太子宜臼,册立褒姒为王后,立伯服为太子,周太史伯阳叹气道:“周王室已面临大祸,这是不可避免的了。”", + yxs_napolun: + "法兰西第一共和国执政、法兰西第一帝国皇帝,出生在法国科西嘉岛,是一位卓越的军事天才。他多次击败保王党的反扑和反法同盟的入侵,捍卫了法国大革命的成果。他颁布的《民法典》更是成为了后世资本主义国家的立法蓝本。他执政期间多次对外扩张,形成了庞大的帝国体系,创造了一系列军事奇迹。", + kaisa: "凯撒是罗马共和国末期杰出的军事统帅、政治家。他公元前60年与庞培、克拉苏秘密结成前三巨头同盟,随后出任高卢总督,在大约8年的时间内征服了高卢全境(今法国一带),还袭击了日耳曼和不列颠。前49年,他率军占领罗马,打败庞培,集大权于一身,实行独裁统治并制定了《儒略历》。", + yxs_zhuyuanzhang: + " 朱元璋,明王朝的开国皇帝。原名重八,后取名兴宗。汉族,濠州(今安徽凤阳县东)钟离太平乡人。朱元璋自幼贫寒,父母兄长均死于瘟疫,孤苦无依,入皇觉寺为小沙弥,入寺不到二个月,因荒年寺租难收,寺主封仓遣散众僧,只得离乡为游方僧,后参加了起义军,并改名“朱元璋”意为诛(朱)灭元朝的璋(璋,古代的一种玉器)。25岁时参加郭子兴领导的红巾军反抗蒙元暴政,在郭子兴手下,率兵出征,有攻必克;因此郭便把养女马氏嫁与了他。元至正二十八年(1368),在基本击破各路农民起义军和扫平元的残余势力后,于南京称帝,国号大明,年号洪武,建立了全国统一的封建政权。朱元璋统治时期被称为“洪武之治”。葬于明孝陵。", + yxs_jinke: + "荆轲,喜好读书击剑,为人慷慨侠义。后游历到燕国,被称为“荆卿”(或荆叔),随之由燕国智勇深沉的“节侠”田光推荐给太子丹,拜为上卿。秦国灭赵后,兵锋直指燕国南界,太子丹震惧,与田光密谋,决定派荆轲入秦行刺秦王。荆轲献计太子丹,拟以秦国叛将樊于期之头及燕督亢(今河北涿县、易县、固安一带,是一块肥沃的土地)地图进献秦王,相机行刺。太子丹不忍杀樊于期,荆轲只好私见樊于期,告以实情,樊于期为成全荆轲而自刎。", + yxs_libai: + "字太白,号青莲居士,又号“谪仙人”,祖籍陇西郡成纪县(今甘肃省平凉市静宁县南)。李白是唐朝著名的浪漫主义诗人,有“诗仙”之称。李白生平作诗无数,存世诗文达千余篇之多,《蜀道难》、《行路难》、《梦游天姥吟留别》、《将进酒》等诗篇脍炙人口,妇孺皆知,另有《李太白集》传世。", + yxs_luban: + " 鲁班,姓公输,名般。战国时期鲁国公族之后,故又称公输子、班输等。出身于工匠世家,是我国古代最著名的发明家、建筑家。鲁班一生发明无数,而最具贡献意义的则要数木工使用的工具,诸如墨斗、锯、和鲁班尺等。为后世的建筑学提供了最基础的工具。除此之外,相传石磨、云梯等工具也是鲁班发明。", + yxs_lvzhi: + " 吕雉,西汉开国皇帝高祖刘邦的原配夫人,中国历史上第一位掌权的女性统治者,是历史上有记载以来的第一位皇后、皇太后。于高祖刘邦死后掌握政权,实行高祖的“黄老政治”,百姓安乐民富国强,为“文景之治”奠定了坚实的基础。", + yxs_goujian: + "勾践,又写作句践,在出土文物“越王勾践剑”里写为鸠浅,司马贞《史记索隐》引《纪年》作菼执。是中国春秋时代后期的越国君主。有关他的先世,有说“其先禹之苗裔”,亦有说“先世无所考”,也有说他是“祝融之后”并且是楚国的芈姓,众说纷纭。父亲则是越侯允常。", + yxs_lishimin: + " 李世民,唐朝第二位皇帝。他的前半生是立下赫赫武功的军事家。平窦建德、王世充之后,始大量接触文学与书法,有《温泉铭》、《晋祠铭》等墨宝传世。后在玄武门之变杀死自己的兄弟李建成、李元吉两人,成为太子,唐高祖不久被迫让位。世民即位为帝后,积极听取群臣的意见、努力学习文治天下,成功转型为中国史上最出名的政治家与明君之一。唐太宗开创了历史上的“贞观之治”,经过主动消灭群雄割据势力,虚心纳谏、在国内厉行节约、使百姓休养生息,终于使得社会出现了国泰民安的局面。此举为后来的开元盛世奠定了重要的基础,将中国传统农业社会推向一个高峰。", + yxs_huamulan: + " 花木兰是中国文学作品中的一位代父从军的巾帼英雄,其真实性不详。花木兰最早出现于南北朝一首叙事诗《木兰辞》中,该诗约作于北魏,最初录于南朝陈的《古今乐录》,僧人智匠在《古今乐录》称:“木兰不知名。”", + yxs_luobinhan: + "罗宾汉是英国民间传说中的侠盗式的一个英雄人物,人称汉丁顿伯爵。他武艺出众、机智勇敢、聪明,仇视官吏和教士,是一位劫富济贫、行侠仗义的绿林英雄。传说他住在诺丁汉雪伍德森林。从14世纪中叶起,关于罗宾汉的民谣和传说就开始在民间流传。罗宾汉最突出的就是射箭术高超。现代射箭比赛里就有“罗宾汉”这一术语,指射中另一支已中靶心的箭。", + yxs_chengjisihan: + "成吉思汗,名铁木真,孛儿只斤氏,奇渥温姓,乞颜(起延)部人。从小遭受结拜兄弟札木合迫害,形成刚毅坚韧的性格。1206年,被推举为蒙古帝国的大汗,统一蒙古各部,为之后的进攻中原提供了坚实的基础。", + yxs_mingchenghuanghou: + "明成皇后,朝鲜近代史上的女政治家,本名闵兹映,通称闵妃,是朝鲜京畿道骊州郡人。她是朝鲜王朝高宗李熙的王妃,骊兴闵氏外戚集团的核心人物,19世纪末朝鲜的实际统治者。由于闵妃早期主张开放、后期力抗日本并身死殉难,故深受后世韩国人民的尊崇。 1897年,高宗李熙改国号称“大韩帝国”,追谥闵妃为“孝慈元圣正化合天明成皇后”,故现今韩国史学家多称她为“明成皇后”。", + yxs_wangzhaojun: + "王昭君,名嫱,字昭君,晋朝时为避司马昭讳,又称“明妃”,汉元帝时期宫女,汉族,西汉南郡秭归(今湖北省兴山县)人。匈奴呼韩邪单于阏氏。 “昭君出塞”是汉匈交往上的大事,稳定了汉朝和匈奴的外交关系,《汉书.匈奴传》和《后汉书.南匈奴传》都记载了这件事。相传和亲途中,南飞的大雁听到昭君奏起悲壮的离别之曲,看到骑在马上的这位美丽女子,忘记摆动翅膀,跌落地下,因此得“落雁”之名。昭君出塞的故事也被后世传为佳话。", + yxs_luocheng: + "《隋唐》说书和《说唐传》中的虚构人物,隋唐十八杰中列第七,十六杰列第八。在清初禇人获的讲史小说《隋唐演义》中,也虚构了罗成,是燕山罗艺的儿子,秦琼的表弟,精通枪法。", + yxs_direnjie: + "唐武周时期杰出的著名政治家,时任豫州刺史、魏州刺史等要职,官至凤阁鸾台平章事、内史,卒后追封梁国公。狄仁杰生于贞观、卒于武周时期,经历了大唐鼎盛和动乱的年代。其一生秉承了以民为本、不畏权贵、为民请命的宗旨。狄仁杰通晓了吏治、兵刑等法律制度,在任大理丞任期内解决了诸多案件,被誉为“神探”。狄仁杰为官清廉,素有政绩,有辅国安邦之能,史称“唐室砥柱”。", + yxs_sunwu: + "著名军事家,字长卿,中国春秋时期齐国乐安人。曾率领吴国军队大破数倍于己的楚国军队,占领了楚国都城郢城,几乎亡楚。其著有巨作《孙子兵法》十三篇,为后世兵法家所推崇,被誉为“兵学圣典”,置于《武经七书》之首,被译为英文、法文、德文、日文,成为国际间最著名的兵学典范之书。后人尊称其为孙子、孙武子、兵圣、百世兵家之师、东方兵学的鼻祖。", + yxs_chengyaojin: + "程咬金,原名咬金,后更名知节,字义贞,中国济州东阿斑鸠店人(现山东省东平县斑鸠店)。“凌烟阁二十四功臣”之一,唐朝开国名将。隋朝末年,隋炀帝杨广统治残暴,骄奢荒淫,民不聊生,最终爆发了大规模的农民起义。程咬金先入瓦岗军,投王世充,后降唐,成为秦王李世民的骨干成员。据史书记载,程咬金“少骁勇,善用马槊。”而在以《说唐》为代表的系列话本及历史演义小说中,程咬金则使得一柄八卦宣花斧,以“三板斧”武艺著称,是一名性格直爽、粗中有细的福将。", + yxs_yujix: + "虞姬,又称虞美人,西楚霸王项羽爱姬,相传为江苏沭阳县颜集乡人,一说苏州常熟人。公元前209年,项羽与叔父项梁起义反秦。项羽军中战将虞子期的妹妹虞姬,貌美好武,倾慕年轻勇猛的项羽,嫁其为妾,常伴左右随军出征,至终形影不离。 公元前202年,项羽在垓下之战中被刘邦、韩信、彭越三方大军合围困于垓下(今安徽灵璧县城南沱河北岸城后村),身陷十面埋伏,兵孤粮缺,夜闻四面楚歌,楚军士气尽失。项羽认为大势已去,帐中酌酒,对着虞姬唱起悲壮的“垓下歌”。虞姬拔剑起舞,含泪唱和:“汉兵已略地,四面楚歌声。大王义气尽,贱妾何聊生。”为免后顾之忧影响项羽突围,唱毕于其面前自刎。", + yxs_xiangyu: + "项籍(前232—前202)字羽,通常被称作项羽,中国古代著名将领及政治人物,汉族,秦下相(今江苏省宿迁市宿城区)人。秦末时被楚怀王熊心封为鲁公,在前207年的决定性战役巨鹿之战中统率楚军大破秦军。秦亡后自封“西楚霸王”,统治黄河及长江下游的梁楚九郡。后在楚汉战争中为汉高祖刘邦所败,在乌江(今安徽和县)自刎而死。", + yxs_yingzheng: + "秦始皇,赢姓,赵氏,名政,秦庄襄王之子。秦始皇22岁时,在雍城举行国君成人加冕仪式,开始“亲理朝政”。后除掉吕不韦,嫪毐等人,重用李斯,尉缭。自公元前230年至前221年,采取由近及远,集中力量,各个击破的策略,先后灭六国,完成统一中国的大业。同时建立起历史上第一个书同文,度同制,车同轨,行同伦的中央集权国家——秦朝。", + yxs_yuefei: + " 岳飞(1103年-1142年),字鹏举,相州汤阴(今属河南)人。南宋军事家,中国历史上著名的抗金名将。绍兴十一年(1142)十二月二十九日,秦桧以“莫须有”的罪名将岳飞毒死于临安风波亭。1162年,宋孝宗时诏复官,谥武穆,宁宗时追封为鄂王,改谥忠武,有《岳武穆集》传世。", + yxs_fuermosi: + "福尔摩斯,是一个虚构的侦探人物,是由19世纪末20世纪初的英国侦探小说家阿瑟?柯南·道尔所塑造的一个才华横溢的侦探形象。福尔摩斯不但头脑冷静、观察力敏锐、推理能力极强;而且,他的剑术、拳术和小提琴演奏水平也相当高超,已经成为侦探小说中的典型代表人物之一。", + yxs_guiguzi: + "本名王诩,春秋时纵横家,卫国(今河南鹤壁一带)人。曾隐于清溪鬼谷,常入云梦采药修道,弟子无数。有张仪、苏秦、孙膑、庞涓四弟子。精于兵法、奇门遁甲、五行八卦之学。后人称之为王禅老祖。今传《鬼谷子》十四篇。", + yxs_xiaoqiao: + "小乔,庐江皖县(今安徽潜山)人。 史书中称小桥,是中国汉末三国时期的女性, 乔公的次女,东吴名将周瑜的妻子。传说与其姐大乔均为绝世美女。合称“二乔”。", + yxs_luzhishen: + "鲁智深,梁山泊第十三位好汉,十员步军头领第一名。鲁智深原名鲁达,绰号花和尚。是经略的提辖,因为见郑屠欺侮金翠莲父女,三拳打死了镇关西。被官府追捕,逃到五台山削发为僧,改名鲁智深。", + yxs_zhaoyong: + "赵武灵王,战国中后期赵国君主,嬴姓,赵氏,名雍。赵武灵王在位时,推行的“胡服骑射”政策,赵国因而得以强盛,灭中山国,败林胡、楼烦二族,辟云中、雁门、代三郡,并修筑了“赵长城”。", + yxs_yangguang: + "隋炀帝杨广,是隋朝第二代皇帝,华阴(今陕西华阴)人,生于隋京师长安。杨广在位期间修建大运河,营建东都迁都洛阳城,开创科举制度,亲征吐谷浑,三征高句丽。但因为杨广滥用民力,导致了隋朝的灭亡,618年在江都被部下缢杀。", + yxs_tangbohu: + "唐伯虎,名寅,字伯虎,自号六如居士,明代诗人、画家,吴县(今江苏苏州)人。出身富商家庭,后家道衰落,因祝枝山之劝而潜心读书。公试时为状元,会试时候因科场舞弊案牵连而被斥为吏。后绝意仕途,以卖画为生。唐伯虎为人玩世不恭而又才气横溢,诗文擅名,与祝枝山、文征明、徐祯卿并称“江南四大才子”,画名更著,与沈周、文征明、仇英并称“吴门四家”。民间盛传其点秋香的故事。", + yxs_zhangsanfeng: + "明朝最著名的武术家、道士。原名张通,字君宝,在武当山开山立派,成为武当派开山祖师。明英宗赐号“通微显化真人”;明宪宗特封号为“韬光尚志真仙”;明世宗赠封他为“清虚元妙真君”。传说其丰姿魁伟,大耳圆目,须髯如戟。无论寒暑,只一衲一蓑,一餐能食升斗,或数日一食,或数月不食,事能前知。其在武术上的造诣和超乎寻常的长寿都为后人称道。 曾传洪武年间,两度受朱元璋诏请入京,皆避而不见。其与明初巨贾沈万三亦有交际。其所创太极拳一直延续至今,成为后人养身妙术。", + yxs_nandinggeer: + "出生于意大利,英国护士和统计学家。她谙熟数学,精通英、法、德、意四门语言,除古典文学外,还精于自然科学、历史和哲学,擅长音乐与绘画。在德国学习护理后,曾往伦敦的医院工作。南丁格尔于1854年和38位护士到克里米亚野战医院工作,成为该院的护士长,被称为“克里米亚的天使”又称“提灯女神”。1860年6月15日,南丁格尔在伦敦成立世界第一所护士学校。为了纪念她的成就,1912年,国际护士会倡仪各国医院和护士学校定每年5月12日南丁格尔诞辰日举行纪念活动,并将5月12日定为“国际护士节”,以缅怀和纪念这位伟大的女性。", + yxs_weizhongxian: + "魏忠贤(1568年-1627年12月11日),字完吾,北直隶肃宁(今河北沧州肃宁县)人,汉族,原名李进忠。由才人王氏复姓,出任秉笔太监后,改名魏忠贤。明朝末期宦官。明熹宗时期,出任司礼秉笔太监,极受宠信,被称为“九千九百岁”,排除异己,专断国政,以致人们“只知有忠贤,而不知有皇上”。朱由检继位后,打击惩治阉党,治魏忠贤十大罪,命逮捕法办,自缢而亡,其余党亦被肃清。", + yxs_meixi: + '妺喜,姓嬉(喜),生卒年不详,亦作妺嬉、末喜、末嬉,有施氏之女,夏朝最后一位君主夏桀的王后。根据先秦时代记述女子名时所用的全称和简称方式,妺喜应姓喜,即嬉(也作僖)。由于其名字的“妺”字与“妹妹”的“妹”字字形相似,且在《庄子》等作中也有以妺为妹的用法,因此常误作"妹喜"。', + yxs_lanlinwang: + "高长恭(541年―573年),又名高孝瓘、高肃,祖籍渤海调蓨(今河北省景县),神武帝高欢之孙,文襄帝高澄第四子,生母不详,南北朝时期北齐宗室、将领,封爵兰陵郡王。高长恭貌柔心壮,音容兼美。为将躬勤细事,每得甘美,虽一瓜数果,必与将士分享。累次升任至并州刺史。突厥攻入晋阳,高长恭奋力将其击退。邙山之战,高长恭为中军,率领五百骑兵再入周军包围圈,直至金墉城下,因高长恭戴着头盔,城中的人不确定是敌军或是我军,直到高长恭把头盔脱下来城上的人才知道是高长恭,派弓箭手开始放箭保护他,之后高长恭成功替金墉解围,高长恭在此次战中威名大振,士兵们为此战而讴歌他,即后来知名的《兰陵王入阵曲》。", }, - characterTitle:{ - yxs_qinqiong:"Sukincen", + characterTitle: { + yxs_qinqiong: "Sukincen", }, - skill:{ - yxs_fanji:{ - audio:2, - trigger:{ - player:"damageEnd", + 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&&(event.card.name=='sha'||event.card.name=='juedou'); + 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'; + 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", + 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'; + direct: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && get.color(event.card) == "red"; }, - content:function (){ - trigger.directHit=true; + content: function () { + trigger.directHit = true; }, }, - yxs_menshen3:{ - trigger:{ - player:['phaseBegin','dieBegin'], + yxs_menshen3: { + trigger: { + player: ["phaseBegin", "dieBegin"], }, - silent:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hasSkill('yxs_menshen2'); + silent: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.hasSkill("yxs_menshen2"); }); }, - content:function(){ - for(var i=0;i1; + 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{ + 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, + ai: { + expose: 0.5, }, }, - yxs_menshen2:{ - audio:2, - mark:'character', - intro:{ - content:'当你成为【杀】或【决斗】的目标后,改为$成为目标' + yxs_menshen2: { + audio: 2, + mark: "character", + intro: { + content: "当你成为【杀】或【决斗】的目标后,改为$成为目标", }, - nopop:true, - priority:15, - trigger:{ - target:["shaBegin","juedouBegin"], + nopop: true, + priority: 15, + trigger: { + target: ["shaBegin", "juedouBegin"], }, - forced:true, - popup:false, - filter:function(event,player){ + forced: true, + popup: false, + filter: function (event, player) { return player.isAlive(); }, - content:function (){ - var target=player.storage.yxs_menshen2; - trigger.player.line(target,'green'); + 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, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&_status.currentPhase==player; + guimian: { + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && _status.currentPhase == player; }, - content:function(){ + content: function () { player.getStat().card.sha--; - } + }, }, - lyuxue:{ - trigger:{source:'damageEnd'}, - forced:true, - logTarget:'player', - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - return event.player.isIn()&&!event.player.hasSkill('lyuxue2'); + lyuxue: { + trigger: { source: "damageEnd" }, + forced: true, + logTarget: "player", + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + return event.player.isIn() && !event.player.hasSkill("lyuxue2"); }, - content:function(){ - trigger.player.addSkill('lyuxue2'); + content: function () { + trigger.player.addSkill("lyuxue2"); }, - subSkill:{ - clear:{ - trigger:{player:['phaseBegin','dieBegin']}, - forced:true, - filter:function(event,player){ - var num=game.countPlayer(function(current){ - return current.hasSkill('lyuxue2'); + subSkill: { + clear: { + trigger: { player: ["phaseBegin", "dieBegin"] }, + forced: true, + filter: function (event, player) { + var num = game.countPlayer(function (current) { + return current.hasSkill("lyuxue2"); }); - if(!num) return false; - if(event.name=='die') return true; - return num>=Math.floor(game.countPlayer()/2); + if (!num) return false; + if (event.name == "die") return true; + return num >= Math.floor(game.countPlayer() / 2); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return current.hasSkill('lyuxue2'); + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return current.hasSkill("lyuxue2"); }); list.sortBySeat(); - event.list=list; - player.line(list,'green'); - 'step 1' - if(event.list.length){ - event.list.shift().removeSkill('lyuxue2'); + event.list = list; + player.line(list, "green"); + "step 1"; + if (event.list.length) { + event.list.shift().removeSkill("lyuxue2"); event.redo(); } - } - } + }, + }, }, - group:'lyuxue_clear', + group: "lyuxue_clear", }, - lyuxue2:{ - mark:true, - intro:{ - content:'已获得浴血标记' + lyuxue2: { + mark: true, + intro: { + content: "已获得浴血标记", }, - onremove:function(player){ + onremove: function (player) { player.loseHp(); - } + }, }, - yaoji:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source!=player&&!event.source.hasJudge('lebu'); + yaoji: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.source != player && + !event.source.hasJudge("lebu") + ); }, - check:function(event,player){ - return get.attitude(player,event.source)<=0; + check: function (event, player) { + return get.attitude(player, event.source) <= 0; }, - logTarget:'source', - content:function(){ - var card=game.createCard('lebu'); + logTarget: "source", + content: function () { + var card = game.createCard("lebu"); trigger.source.addJudge(card); trigger.source.$draw(card); game.delay(); }, - ai:{ - maixie_defend:true, - } - }, - liebo:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return Math.abs(target.countCards('h')-player.countCards('h'))<=1; + ai: { + maixie_defend: true, }, - content:function(){ + }, + liebo: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return Math.abs(target.countCards("h") - player.countCards("h")) <= 1; + }, + content: function () { player.swapHandcards(target); }, - ai:{ - order:function(){ - var player=_status.event.player; - if(player.hasCard(function(card){ - return get.value(card)>=8; - })){ + ai: { + order: function () { + var player = _status.event.player; + if ( + player.hasCard(function (card) { + return get.value(card) >= 8; + }) + ) { return 0; } - var nh=player.countCards('h'); - if(game.hasPlayer(function(current){ - return get.attitude(player,current)<=0&¤t.countCards('h')==nh+1; - })){ + var nh = player.countCards("h"); + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(player, current) <= 0 && current.countCards("h") == nh + 1 + ); + }) + ) { return 9; } return 1; }, - result:{ - player:function(player,target){ - var att=get.attitude(player,target); - if(att>0) return 0; - if(player.hasCard(function(card){ - return get.value(card)>=8; - })){ + result: { + player: function (player, target) { + var att = get.attitude(player, target); + if (att > 0) return 0; + if ( + player.hasCard(function (card) { + return get.value(card) >= 8; + }) + ) { return 0; } - var n1=target.countCards('h'),n2=player.countCards('h'); - var num=0; - if(n1-n2==1){ - num=1; + var n1 = target.countCards("h"), + n2 = player.countCards("h"); + var num = 0; + if (n1 - n2 == 1) { + num = 1; } - if(player.countCards('h','du')){ - if(n1==n2) num=0.5; - else num=0.1; + if (player.countCards("h", "du")) { + if (n1 == n2) num = 0.5; + else num = 0.1; } - if(att==0){ - num/=2; + if (att == 0) { + num /= 2; } return num; - } - } - } + }, + }, + }, }, - zhuxin:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h'); + zhuxin: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("h"); }, - filter:function(event,player){ - return player.countCards('h'); + filter: function (event, player) { + return player.countCards("h"); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ + "step 1"; + if (result.bool) { target.damage(); } }, - ai:{ - order:8, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); - } - } - } - }, - wlianhuan:{ - trigger:{source:'damageBegin'}, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.countCards('e'); + ai: { + order: 8, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); + }, + }, }, - direct:true, - content:function(){ - 'step 0' - var next=player.chooseToDiscard('e',get.prompt('wlianhuan',trigger.player),'弃置一张装备区内的牌使伤害+1'); - next.ai=function(card){ - if(get.attitude(player,trigger.player)<0){ - return 7-get.value(card); + }, + wlianhuan: { + trigger: { source: "damageBegin" }, + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.countCards("e"); + }, + direct: true, + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "e", + get.prompt("wlianhuan", trigger.player), + "弃置一张装备区内的牌使伤害+1" + ); + next.ai = function (card) { + if (get.attitude(player, trigger.player) < 0) { + return 7 - get.value(card); } return 0; - } - next.logSkill=['wlianhuan',trigger.player]; - 'step 1' - if(result.bool){ + }; + next.logSkill = ["wlianhuan", trigger.player]; + "step 1"; + if (result.bool) { trigger.num++; } - } + }, }, - huli:{ - enable:'phaseUse', - filterCard:{suit:'heart'}, - filterTarget:function(card,player,target){ - return get.distance(player,target)<=1&&lib.filter.cardEnabled({name:'tao'},target,target); + huli: { + enable: "phaseUse", + filterCard: { suit: "heart" }, + filterTarget: function (card, player, target) { + return ( + get.distance(player, target) <= 1 && + lib.filter.cardEnabled({ name: "tao" }, target, target) + ); }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - discard:false, - lose:false, - filter:function(event,player){ - if(player.countCards('h',{suit:'heart'})){ + discard: false, + lose: false, + filter: function (event, player) { + if (player.countCards("h", { suit: "heart" })) { return true; } return false; }, - prepare:'throw', - content:function(){ - player.useCard({name:'tao'},cards,targets[0]).animate=false; + prepare: "throw", + content: function () { + player.useCard({ name: "tao" }, cards, targets[0]).animate = false; }, - ai:{ - order:9.5, - result:{ - target:function(player,target){ - return get.recoverEffect(target,player,target); - } + ai: { + order: 9.5, + result: { + target: function (player, target) { + return get.recoverEffect(target, player, target); + }, }, - threaten:1.6 - } + threaten: 1.6, + }, }, - yixin:{ - skillAnimation:true, - unique:true, - mark:true, - init:function(player){ - player.storage.yixin=false; + yixin: { + skillAnimation: true, + unique: true, + mark: true, + init: function (player) { + player.storage.yixin = false; }, - enable:'phaseUse', - filter:function(event,player){ - return !player.storage.yixin&&player.countCards('he')>2; + enable: "phaseUse", + filter: function (event, player) { + return !player.storage.yixin && player.countCards("he") > 2; }, - intro:{ - content:'limited' + intro: { + content: "limited", }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return target.isDamaged(); }, - filterCard:true, - position:'he', - selectCard:2, - check:function(card){ - return 7-get.value(card); + filterCard: true, + position: "he", + selectCard: 2, + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - player.awakenSkill('yixin'); - player.storage.yixin=true; - var num=Math.min(4,target.maxHp-target.hp); + content: function () { + player.awakenSkill("yixin"); + player.storage.yixin = true; + var num = Math.min(4, target.maxHp - target.hp); target.recover(num); - if(num<4){ - target.draw(4-num); + if (num < 4) { + target.draw(4 - num); } }, - ai:{ - order:9.6, - result:{ - target:function(player,target){ - if(target.hp==1&&target.maxHp>=3){ - return get.recoverEffect(target,player,target); + ai: { + order: 9.6, + result: { + target: function (player, target) { + if (target.hp == 1 && target.maxHp >= 3) { + return get.recoverEffect(target, player, target); } return 0; - } - } - } - }, - xianqu:{ - mod:{ - targetEnabled:function(card){ - if(card.name=='sha'&&card.number<8) return false; - } + }, + }, }, }, - zbudao:{ - trigger:{player:'phaseDrawBegin'}, + xianqu: { + mod: { + targetEnabled: function (card) { + if (card.name == "sha" && card.number < 8) return false; + }, + }, + }, + zbudao: { + trigger: { player: "phaseDrawBegin" }, //check:function(event,player){ // if(player.hasFriend()) return true; // return false; //}, - content:function(){ + content: function () { trigger.num++; - player.addTempSkill('zbudao2','phaseDrawAfter'); + player.addTempSkill("zbudao2", "phaseDrawAfter"); }, - ai:{ - threaten:1.3 + ai: { + threaten: 1.3, }, }, - zbudao2:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - popup:false, - filter:function(event){ - return event.cards&&event.cards.length; + zbudao2: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + popup: false, + filter: function (event) { + return event.cards && event.cards.length; }, - content:function(){ - 'step 0' - event.cards=trigger.cards.slice(0); + content: function () { + "step 0"; + event.cards = trigger.cards.slice(0); player.chooseCardTarget({ - filterCard:function(card){ + filterCard: function (card) { return _status.event.getParent().cards.includes(card); }, - selectCard:1, - filterTarget:function(card,player,target){ - return player!=target; + selectCard: 1, + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - if(ui.selected.cards.length>0) return -1; - if(card.name=='du') return 20; - return (_status.event.player.countCards('h')-_status.event.player.hp); + ai1: function (card) { + if (ui.selected.cards.length > 0) return -1; + if (card.name == "du") return 20; + return _status.event.player.countCards("h") - _status.event.player.hp; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - return 1-att; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + return 1 - att; } - return att-4; + return att - 4; }, //forced:true, - prompt:'将得到的一张牌交给一名其他角色,或点取消' + prompt: "将得到的一张牌交给一名其他角色,或点取消", }); - "step 1" - if(result.bool){ - player.line(result.targets,'green'); - result.targets[0].gain(result.cards,player); - player.$give(result.cards.length,result.targets[0]); + "step 1"; + if (result.bool) { + player.line(result.targets, "green"); + result.targets[0].gain(result.cards, player); + player.$give(result.cards.length, result.targets[0]); game.delay(0.7); } - } - }, - taiji:{ - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - return event.card.name=='shan'&&player.hasSha(); - }, - direct:true, - content:function(){ - player.chooseToUse({name:'sha'},'太极:是否使用一张杀?').logSkill='taiji'; }, }, - fengliu:{ - trigger:{player:'phaseDrawBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.sex=='female'; + taiji: { + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + return event.card.name == "shan" && player.hasSha(); + }, + direct: true, + content: function () { + player.chooseToUse({ name: "sha" }, "太极:是否使用一张杀?").logSkill = "taiji"; + }, + }, + fengliu: { + trigger: { player: "phaseDrawBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.sex == "female"; }); }, - forced:true, - content:function(){ - var num=game.countPlayer(function(current){ - return current.sex=='female'; + forced: true, + content: function () { + var num = game.countPlayer(function (current) { + return current.sex == "female"; }); - if(num>2) num=2; - trigger.num+=num; + if (num > 2) num = 2; + trigger.num += num; }, - ai:{ - threaten:function(){ - var num=game.countPlayer(function(current){ - return current.sex=='female'; + ai: { + threaten: function () { + var num = game.countPlayer(function (current) { + return current.sex == "female"; }); - switch(num){ - case 0:return 1; - case 1:return 1.3; - default:return 2; + switch (num) { + case 0: + return 1; + case 1: + return 1.3; + default: + return 2; } - } + }, }, }, - luobi:{ - trigger:{player:'phaseEnd'}, - filter:function(event,player){ + luobi: { + trigger: { player: "phaseEnd" }, + filter: function (event, player) { return player.isDamaged(); }, - content:function(){ - "step 0" - player.draw(player.maxHp-player.hp); - "step 1" - event.cards=result; - "step 2" + content: function () { + "step 0"; + player.draw(player.maxHp - player.hp); + "step 1"; + event.cards = result; + "step 2"; player.chooseCardTarget({ - filterCard:function(card){ + filterCard: function (card) { return _status.event.getParent().cards.includes(card); }, - selectCard:[1,event.cards.length], - filterTarget:function(card,player,target){ - return player!=target; + selectCard: [1, event.cards.length], + filterTarget: function (card, player, target) { + return player != target; }, - ai1:function(card){ - if(ui.selected.cards.length>0) return -1; - if(card.name=='du') return 20; - return (_status.event.player.countCards('h')-_status.event.player.hp); + ai1: function (card) { + if (ui.selected.cards.length > 0) return -1; + if (card.name == "du") return 20; + return _status.event.player.countCards("h") - _status.event.player.hp; }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ - return 1-att; + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { + return 1 - att; } - return att-4; + return att - 4; }, - prompt:'请选择要送人的卡牌' + prompt: "请选择要送人的卡牌", }); - "step 3" - if(result.bool){ - player.line(result.targets,'green'); - result.targets[0].gain(result.cards,player); - player.$give(result.cards.length,result.targets[0]); - for(var i=0;i0){ - return game.hasPlayer(function(current){ - return current.group!='qun'&¤t!=player; + yaoyi: { + trigger: { player: "damageEnd" }, + direct: true, + filter: function (event, player) { + if (event.num > 0) { + return game.hasPlayer(function (current) { + return current.group != "qun" && current != player; }); } return false; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('yaoyi'),[1,2],function(card,player,target){ - return target.countCards('h')&&target.group!='qun'&&target!=player; - }).set('ai',function(target){ - return 0.5-get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - player.logSkill('yaoyi',result.targets); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("yaoyi"), [1, 2], function (card, player, target) { + return target.countCards("h") && target.group != "qun" && target != player; + }) + .set("ai", function (target) { + return 0.5 - get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + player.logSkill("yaoyi", result.targets); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets&&event.targets.length){ - event.target=event.targets.shift(); - event.target.chooseCard('交给'+get.translation(player)+'一张手牌',true).ai=function(card){ - return -get.value(card); - } - } - else{ + "step 2"; + if (event.targets && event.targets.length) { + event.target = event.targets.shift(); + event.target.chooseCard("交给" + get.translation(player) + "一张手牌", true).ai = + function (card) { + return -get.value(card); + }; + } else { event.finish(); } - 'step 3' - if(result.bool&&result.cards&&result.cards.length){ - event.target.$give(1,player); - player.gain(result.cards,event.target); + "step 3"; + if (result.bool && result.cards && result.cards.length) { + event.target.$give(1, player); + player.gain(result.cards, event.target); } event.goto(2); }, - ai:{ - maixie:true, - maixie_hp:true, - expose:0.2, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var players=game.filterPlayer(); - for(var i=0;i=4) return [1,get.tag(card,'damage')*2]; - if(target.hp==3) return [1,get.tag(card,'damage')*1.5]; - if(target.hp==2) return [1,get.tag(card,'damage')*0.5]; + ai: { + maixie: true, + maixie_hp: true, + expose: 0.2, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].group != "qun" && + get.attitude(player, players[i]) <= 0 && + players[i] != player + ) { + if (target.hp >= 4) return [1, get.tag(card, "damage") * 2]; + if (target.hp == 3) return [1, get.tag(card, "damage") * 1.5]; + if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } } } - } - } - } + }, + }, + }, }, - shiqin:{ - trigger:{global:'dying'}, - priority:9, - filter:function(event,player){ - return event.player!=player&&event.player.hp<=0&&event.player.group=='qun'; + shiqin: { + trigger: { global: "dying" }, + priority: 9, + filter: function (event, player) { + return event.player != player && event.player.hp <= 0 && event.player.group == "qun"; }, - check:function(event,player){ - return get.attitude(player,event.player)<0; + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - forced:true, - logTarget:'player', - content:function(){ - 'step 0' + forced: true, + logTarget: "player", + content: function () { + "step 0"; game.delayx(); trigger.player.die(); - 'step 1' - if(!trigger.player.isAlive()){ + "step 1"; + if (!trigger.player.isAlive()) { trigger.cancel(true); } - } + }, }, - zyhufu:{ - trigger:{player:'phaseDrawBegin'}, - filter:function(event,player){ + zyhufu: { + trigger: { player: "phaseDrawBegin" }, + filter: function (event, player) { return !player.getEquip(2); }, - forced:true, - content:function(){ + forced: true, + content: function () { trigger.num++; }, - ai:{ - threaten:1.3 + ai: { + threaten: 1.3, + }, + mod: { + maxHandcard: function (player, num) { + if (player.getEquip(2)) return num + 5; + }, }, - mod:{ - maxHandcard:function(player,num){ - if(player.getEquip(2)) return num+5; - } - } }, - hanbei:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - if(player.getEquip(3)||player.getEquip(4)) return true; + hanbei: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + if (player.getEquip(3) || player.getEquip(4)) return true; return false; }, - content:function(){ - trigger.directHit=true; - } + content: function () { + trigger.directHit = true; + }, }, - sheshu:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event,player){ - return event.target.hp>=3; + sheshu: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event, player) { + return event.target.hp >= 3; }, - content:function(){ - trigger.directHit=true; + content: function () { + trigger.directHit = true; }, - mod:{ - targetInRange:function(card){ - if(card.name=='sha') return true; + mod: { + targetInRange: function (card) { + if (card.name == "sha") return true; }, }, }, - lguiyin:{ - unique:true, - forceunique:true, - enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('tongyu_guiyin')&&!player.getStat('damage'); + lguiyin: { + unique: true, + forceunique: true, + enable: "phaseUse", + filter: function (event, player) { + return !player.hasSkill("tongyu_guiyin") && !player.getStat("damage"); }, - derivation:['lzhangyi','jimin','tongyu'], - content:function(){ + derivation: ["lzhangyi", "jimin", "tongyu"], + content: function () { player.draw(); - player.setAvatar('yxs_luobinhan','yxs_handingdun'); - player.removeSkill('lguiyin'); - player.removeSkill('sheshu'); - player.removeSkill('xiadao'); - player.addSkill('jimin'); - player.addSkill('lzhangyi'); - player.addSkill('tongyu'); - player.addTempSkill('tongyu_guiyin'); + player.setAvatar("yxs_luobinhan", "yxs_handingdun"); + player.removeSkill("lguiyin"); + player.removeSkill("sheshu"); + player.removeSkill("xiadao"); + player.addSkill("jimin"); + player.addSkill("lzhangyi"); + player.addSkill("tongyu"); + player.addTempSkill("tongyu_guiyin"); }, - ai:{ - order:function(){ - if(_status.event.player.hp==1) return 9; + ai: { + order: function () { + if (_status.event.player.hp == 1) return 9; return 0.5; }, - result:{ - player:function(player){ - if(player.hp0&&!player.hasSkill('tongyu_guiyin'); + tongyu: { + unique: true, + forceunique: true, + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("he") > 0 && !player.hasSkill("tongyu_guiyin"); }, - filterCard:true, - position:'he', - check:function(card){ - return 7-get.value(card); + filterCard: true, + position: "he", + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - player.setAvatar('yxs_luobinhan','yxs_luobinhan'); - player.addSkill('lguiyin'); - player.addSkill('sheshu'); - player.addSkill('xiadao'); - player.removeSkill('jimin'); - player.removeSkill('lzhangyi'); - player.removeSkill('tongyu'); - player.addTempSkill('tongyu_guiyin'); + content: function () { + player.setAvatar("yxs_luobinhan", "yxs_luobinhan"); + player.addSkill("lguiyin"); + player.addSkill("sheshu"); + player.addSkill("xiadao"); + player.removeSkill("jimin"); + player.removeSkill("lzhangyi"); + player.removeSkill("tongyu"); + player.addTempSkill("tongyu_guiyin"); }, - ai:{ - order:9, - result:{ - player:function(player){ - if(player.hasFriend()) return 1; + ai: { + order: 9, + result: { + player: function (player) { + if (player.hasFriend()) return 1; return 0; - } - } - } + }, + }, + }, }, - tongyu_guiyin:{}, - zhijie:{ - enable:'phaseUse', - usable:1, - viewAsFilter:function(player){ - return player.countCards('h',{suit:'heart'})>0; + tongyu_guiyin: {}, + zhijie: { + enable: "phaseUse", + usable: 1, + viewAsFilter: function (player) { + return player.countCards("h", { suit: "heart" }) > 0; + }, + viewAs: { name: "wuzhong" }, + filterCard: { suit: "heart" }, + check: function (card) { + return 8 - get.value(card); }, - viewAs:{name:'wuzhong'}, - filterCard:{suit:'heart'}, - check:function(card){ - return 8-get.value(card); - } }, - yxsdili:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ - return player.hp=player.maxHp-1) return [0,0]; - } - } - } - }, - kuangchan:{ - ai:{ - neg:true + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, + }, }, - init:function(player){ - if(player.isZhu){ + }, + kuangchan: { + ai: { + neg: true, + }, + init: function (player) { + if (player.isZhu) { player.maxHp--; player.update(); } - } + }, }, - chujia:{ - enable:'phaseUse', - filterCard:function(card){ - if(ui.selected.cards.length){ - return get.color(card)==get.color(ui.selected.cards[0]); + chujia: { + enable: "phaseUse", + filterCard: function (card) { + if (ui.selected.cards.length) { + return get.color(card) == get.color(ui.selected.cards[0]); } return true; }, - complexCard:true, - usable:1, - selectCard:2, - check:function(card){ - return 6-get.value(card); + complexCard: true, + usable: 1, + selectCard: 2, + check: function (card) { + return 6 - get.value(card); }, - filterTarget:function(card,player,target){ - return target.hptarget.hp){ - target.draw(target.maxHp-target.hp); + content: function () { + if (target.maxHp > target.hp) { + target.draw(target.maxHp - target.hp); } }, - ai:{ - order:2, - result:{ - target:function(player,target){ - var num=target.maxHp-target.hp; - if(num>2) return num; + ai: { + order: 2, + result: { + target: function (player, target) { + var num = target.maxHp - target.hp; + if (num > 2) return num; return 0; - } - } - } + }, + }, + }, }, - baihe:{ - enable:'phaseUse', - usable:1, - filterCard:true, - position:'he', - filterTarget:true, - content:function(){ - 'step 0' - if(target.isLinked()){ + baihe: { + enable: "phaseUse", + usable: 1, + filterCard: true, + position: "he", + filterTarget: true, + content: function () { + "step 0"; + if (target.isLinked()) { target.link(); - } - else{ + } else { target.link(); target.draw(); event.finish(); } - 'step 1' - if(target.countCards('h')){ - target.chooseToDiscard('h',true); + "step 1"; + if (target.countCards("h")) { + target.chooseToDiscard("h", true); } }, - check:function(card){ - return 8-get.value(card); + check: function (card) { + return 8 - get.value(card); }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(!player.hasSkill('xiushen')) return 0; - if(target.isLinked()) return 0; - if(game.hasPlayer(function(current){ - return current.isLinked(); - })){ + ai: { + order: 1, + result: { + player: function (player, target) { + if (!player.hasSkill("xiushen")) return 0; + if (target.isLinked()) return 0; + if ( + game.hasPlayer(function (current) { + return current.isLinked(); + }) + ) { return 0; } return 1; - } - } - } + }, + }, + }, }, - yinyang:{ - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:2, - filterTarget:true, - selectTarget:3, - content:function(){ + yinyang: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 2, + filterTarget: true, + selectTarget: 3, + content: function () { target.link(); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - ai:{ - order:2, - result:{ - target:function(player,target){ - if(target.isLinked()) return 1; + ai: { + order: 2, + result: { + target: function (player, target) { + if (target.isLinked()) return 1; return -1; - } - } - } + }, + }, + }, }, - xiushen:{ - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ + xiushen: { + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { return current.isLinked(); }); }, - content:function(){ + content: function () { player.draw(2); }, - ai:{ - threaten:1.6 - } - }, - jiean:{ - trigger:{source:'damageEnd'}, - frequent:true, - filter:function(event){ - if(event._notrigger.includes(event.player)) return false; - return event.player.isAlive()&&event.parent.name=='yanyi'&&event.player.hp0) return -1; - return (_status.event.player.countCards('h')-_status.event.player.hp); + ai1: function (card) { + if (ui.selected.cards.length > 0) return -1; + return _status.event.player.countCards("h") - _status.event.player.hp; }, - ai2:function(target){ - return get.attitude(_status.event.player,target)-4; + ai2: function (target) { + return get.attitude(_status.event.player, target) - 4; }, - prompt:'请选择要送人的卡牌' + prompt: "请选择要送人的卡牌", }); - "step 3" - if(result.bool){ - result.targets[0].gain(result.cards,player); - player.$give(result.cards.length,result.targets[0]); - for(var i=0;i0; }, - content:function(){ - "step 0" - player.chooseControl('heart2','diamond2','club2','spade2').ai=function(event){ - switch(Math.floor(Math.random()*5)){ - case 0:return 'heart2'; - case 1:case 4:return 'diamond2'; - case 2:return 'club2'; - case 3:return 'spade2'; + }, + yanyi: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "black" }, + position: "he", + filterTarget: function (card, player, target) { + return target != player && target.countCards("h") > 0; + }, + content: function () { + "step 0"; + player.chooseControl("heart2", "diamond2", "club2", "spade2").ai = function (event) { + switch (Math.floor(Math.random() * 5)) { + case 0: + return "heart2"; + case 1: + case 4: + return "diamond2"; + case 2: + return "club2"; + case 3: + return "spade2"; } }; - "step 1" - game.log(player,'选择了'+get.translation(result.control)); - event.choice=result.control.slice(0,result.control.length-1); + "step 1"; + game.log(player, "选择了" + get.translation(result.control)); + event.choice = result.control.slice(0, result.control.length - 1); target.popup(result.control); target.showHandcards(); - "step 2" - if(target.countCards('h',{suit:event.choice})){ + "step 2"; + if (target.countCards("h", { suit: event.choice })) { target.damage(); } }, - ai:{ - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); - } - } - } - }, - wumu:{ - mod:{ - targetInRange:function(card,player){ - if(card.name=='sha'&&get.color(card)=='black') return true; + ai: { + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); + }, }, - cardUsable:function(card){ - if(card.name=='sha'&&get.color(card)=='red') return Infinity; - } }, - trigger:{player:'useCard'}, - filter:function(event,player){ - return event.card.name=='sha'&&get.color(event.card)=='red'; + }, + wumu: { + mod: { + targetInRange: function (card, player) { + if (card.name == "sha" && get.color(card) == "black") return true; + }, + cardUsable: function (card) { + if (card.name == "sha" && get.color(card) == "red") return Infinity; + }, }, - forced:true, - content:function(){ - if(player.stat[player.stat.length-1].card.sha>0){ - player.stat[player.stat.length-1].card.sha--; + trigger: { player: "useCard" }, + filter: function (event, player) { + return event.card.name == "sha" && get.color(event.card) == "red"; + }, + forced: true, + content: function () { + if (player.stat[player.stat.length - 1].card.sha > 0) { + player.stat[player.stat.length - 1].card.sha--; } }, }, - ysheshen:{ - inherit:'yiji' + ysheshen: { + inherit: "yiji", }, - sanbanfu:{ - trigger:{player:'shaBegin'}, - filter:function(event,player){ - if(player.storage.sanbanfu||player.storage.sanbanfu2) return false; + sanbanfu: { + trigger: { player: "shaBegin" }, + filter: function (event, player) { + if (player.storage.sanbanfu || player.storage.sanbanfu2) return false; return !event.directHit; }, - check:function(event,player){ - if(get.attitude(player,event.target)>=0) return false; - if(event.target.hasSkillTag('freeShan',false,{ - player:player, - card:event.card - },true)) return false; - if(event.target.hasSkillTag('respondShan')&&event.target.countCards('h')>=3) return false; + check: function (event, player) { + if (get.attitude(player, event.target) >= 0) return false; + if ( + event.target.hasSkillTag( + "freeShan", + false, + { + player: player, + card: event.card, + }, + true + ) + ) + return false; + if (event.target.hasSkillTag("respondShan") && event.target.countCards("h") >= 3) + return false; return true; }, - logTarget:'target', - content:function(){ - "step 0" - var next=trigger.target.chooseToRespond({name:'shan'}); - next.autochoose=lib.filter.autoRespondShan; - next.ai=function(card){ + logTarget: "target", + content: function () { + "step 0"; + var next = trigger.target.chooseToRespond({ name: "shan" }); + next.autochoose = lib.filter.autoRespondShan; + next.ai = function (card) { return get.unuseful2(card); }; - player.storage.sanbanfu=false; - player.storage.sanbanfu2=false; - "step 1" - if(result.bool==false){ + player.storage.sanbanfu = false; + player.storage.sanbanfu2 = false; + "step 1"; + if (result.bool == false) { trigger.untrigger(); - trigger.directHit=true; - player.storage.sanbanfu2=true; - } - else{ - player.storage.sanbanfu=true; + trigger.directHit = true; + player.storage.sanbanfu2 = true; + } else { + player.storage.sanbanfu = true; } }, - group:['sanbanfu2','sanbanfu3'] + group: ["sanbanfu2", "sanbanfu3"], }, - sanbanfu2:{ - trigger:{player:'shaAfter'}, - silent:true, - content:function(){ - if(player.storage.sanbanfu) player.damage(trigger.target); + sanbanfu2: { + trigger: { player: "shaAfter" }, + silent: true, + content: function () { + if (player.storage.sanbanfu) player.damage(trigger.target); delete player.storage.sanbanfu; delete player.storage.sanbanfu2; - } - }, - sanbanfu3:{ - trigger:{source:'damageBegin'}, - silent:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.storage.sanbanfu2; }, - content:function(){ - trigger.num++; - } }, - bingsheng:{ - enable:'phaseUse', - usable:1, - filterCard:function(card){ - if(ui.selected.cards.length){ - return get.suit(card)!=get.suit(ui.selected.cards[0]); + sanbanfu3: { + trigger: { source: "damageBegin" }, + silent: true, + filter: function (event, player) { + return event.card && event.card.name == "sha" && player.storage.sanbanfu2; + }, + content: function () { + trigger.num++; + }, + }, + bingsheng: { + enable: "phaseUse", + usable: 1, + filterCard: function (card) { + if (ui.selected.cards.length) { + return get.suit(card) != get.suit(ui.selected.cards[0]); } return true; }, - complexCard:true, - selectCard:2, - check:function(card){ - return 8-get.value(card); + complexCard: true, + selectCard: 2, + check: function (card) { + return 8 - get.value(card); }, - filterTarget:function(card,player,target){ - if(target.hp==Infinity) return false; - if(target.hp>player.hp) return true; - if(target.hp player.hp) return true; + if (target.hp < player.hp && target.hp < target.maxHp) return true; return false; }, - content:function(){ - var num=target.hp-player.hp; - if(num>2){ - num=2; + content: function () { + var num = target.hp - player.hp; + if (num > 2) { + num = 2; } - if(num<-2){ - num=-2; + if (num < -2) { + num = -2; } - if(num>0){ + if (num > 0) { target.damage(num); - } - else if(num<0&&target.hptarget.maxHp){ - num=player.hp-target.maxHp; + if (player.hp > target.maxHp) { + num = player.hp - target.maxHp; + } else { + num = player.hp - target.hp; } - else{ - num=player.hp-target.hp; - } - if(target.hp==1&&num){ - return num+1; + if (target.hp == 1 && num) { + return num + 1; } return num; - } - } - } - }, - taolue:{ - mod:{ - maxHandcard:function(player,num){ - return num+1; - } + }, + }, }, }, - shentan:{ - enable:'phaseUse', - usable:1, - filterCard:true, - filterTarget:function(card,player,target){ - return target.countCards('h')>0&&get.distance(player,target)<=2; + taolue: { + mod: { + maxHandcard: function (player, num) { + return num + 1; + }, }, - check:function(card){ - return 7-get.value(card); + }, + shentan: { + enable: "phaseUse", + usable: 1, + filterCard: true, + filterTarget: function (card, player, target) { + return target.countCards("h") > 0 && get.distance(player, target) <= 2; }, - position:'he', - content:function(){ - "step 0" - var hs=target.getCards('h'); - if(hs.length){ - event.card=hs.randomGet(); - player.gain(event.card,target); - target.$giveAuto(event.card,player); - } - else{ + check: function (card) { + return 7 - get.value(card); + }, + position: "he", + content: function () { + "step 0"; + var hs = target.getCards("h"); + if (hs.length) { + event.card = hs.randomGet(); + player.gain(event.card, target); + target.$giveAuto(event.card, player); + } else { event.finish(); } - "step 1" - var source=target; - player.chooseTarget('选择一个目标送出'+get.translation(event.card),function(card,player,target){ - return target!=player; - }).ai=function(target){ - var att=get.attitude(player,target); - if(att>3&&player.countCards('h')>target.countCards('h')){ + "step 1"; + var source = target; + player.chooseTarget( + "选择一个目标送出" + get.translation(event.card), + function (card, player, target) { + return target != player; + } + ).ai = function (target) { + var att = get.attitude(player, target); + if (att > 3 && player.countCards("h") > target.countCards("h")) { return att; } return 0; - } - "step 2" - if(result.bool){ - result.targets[0].gain(card,player); - player.$give(1,result.targets[0]); - player.line(result.targets,'green'); + }; + "step 2"; + if (result.bool) { + result.targets[0].gain(card, player); + player.$give(1, result.targets[0]); + player.line(result.targets, "green"); game.delay(); } }, - ai:{ - order:9, - result:{ - target:-1, - player:function(player,target){ - if(get.attitude(player,target)>0){ + ai: { + order: 9, + result: { + target: -1, + player: function (player, target) { + if (get.attitude(player, target) > 0) { return 0; } return 1; - } + }, }, }, }, - hanqiang:{ - mod:{ - attackFrom:function(from,to,distance){ - if(!from.getEquip(1)) return distance-1 - } - } + hanqiang: { + mod: { + attackFrom: function (from, to, distance) { + if (!from.getEquip(1)) return distance - 1; + }, + }, }, - biaoqi:{ - trigger:{player:'shaBegin'}, - forced:true, - content:function(){ - var range=player.getAttackRange(); - if(range>trigger.target.hp){ - trigger.directHit=true; - } - else if(range trigger.target.hp) { + trigger.directHit = true; + } else if (range < trigger.target.hp) { player.draw(); } - } + }, }, - wluoyan:{ - trigger:{player:'damageBefore'}, - forced:true, - content:function(){ + wluoyan: { + trigger: { player: "damageBefore" }, + forced: true, + content: function () { trigger.cancel(); player.loseHp(); }, - ai:{ - noDirectDamage:true, - } + ai: { + noDirectDamage: true, + }, }, - heqin:{ - skillAnimation:true, - enable:'phaseUse', - filter:function(event,player){ + heqin: { + skillAnimation: true, + enable: "phaseUse", + filter: function (event, player) { return !player.storage.heqin; }, - filterTarget:function(card,player,target){ - return target.sex=='male'&&target!=player; + filterTarget: function (card, player, target) { + return target.sex == "male" && target != player; }, - content:function(){ - player.awakenSkill('heqin'); - player.addSkill('heqin2'); - target.addSkill('heqin2'); + content: function () { + player.awakenSkill("heqin"); + player.addSkill("heqin2"); + target.addSkill("heqin2"); - target.marks.heqin=target.markCharacter(player,{ - name:'和亲', - content:'摸牌阶段摸牌数+1' + target.marks.heqin = target.markCharacter(player, { + name: "和亲", + content: "摸牌阶段摸牌数+1", }); - game.addVideo('markCharacter',target,{ - name:'放权', - content:'摸牌阶段摸牌数+1', - id:'heqin', - target:player.dataset.position + game.addVideo("markCharacter", target, { + name: "放权", + content: "摸牌阶段摸牌数+1", + id: "heqin", + target: player.dataset.position, }); - player.storage.heqin=target; - target.storage.heqin=player; + player.storage.heqin = target; + target.storage.heqin = player; - player.marks.heqin=player.markCharacter(target,{ - name:'和亲', - content:'摸牌阶段摸牌数+1' + player.marks.heqin = player.markCharacter(target, { + name: "和亲", + content: "摸牌阶段摸牌数+1", }); - game.addVideo('markCharacter',player,{ - name:'放权', - content:'摸牌阶段摸牌数+1', - id:'heqin', - target:target.dataset.position + game.addVideo("markCharacter", player, { + name: "放权", + content: "摸牌阶段摸牌数+1", + id: "heqin", + target: target.dataset.position, }); }, - ai:{ - order:1, - result:{ - target:1 - } - } + ai: { + order: 1, + result: { + target: 1, + }, + }, }, - heqin2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ + heqin2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + content: function () { trigger.num++; }, - group:'heqin3' + group: "heqin3", }, - heqin3:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content:function(){ - player.removeSkill('heqin2'); - player.unmarkSkill('heqin'); - if(player.storage.heqin){ - player.storage.heqin.removeSkill('heqin2'); - player.storage.heqin.unmarkSkill('heqin'); + heqin3: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + content: function () { + player.removeSkill("heqin2"); + player.unmarkSkill("heqin"); + if (player.storage.heqin) { + player.storage.heqin.removeSkill("heqin2"); + player.storage.heqin.unmarkSkill("heqin"); } - } + }, }, - chajue:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return _status.currentPhase!=player; + chajue: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return _status.currentPhase != player; + }, + content: function () { + player.addTempSkill("chajue2", { player: "phaseBegin" }); }, - content:function(){ - player.addTempSkill('chajue2',{player:'phaseBegin'}); - } }, - chajue2:{ - trigger:{target:'useCardToBefore'}, - forced:true, - priority:15, - mark:true, - intro:{ - content:'杀或普通锦囊牌对你无效' + chajue2: { + trigger: { target: "useCardToBefore" }, + forced: true, + priority: 15, + mark: true, + intro: { + content: "杀或普通锦囊牌对你无效", }, - filter:function(event,player){ - return get.type(event.card)=='trick'||event.card.name=='sha'; + filter: function (event, player) { + return get.type(event.card) == "trick" || event.card.name == "sha"; }, - content:function(){ - game.log(player,'发动了察觉,',trigger.card,'对',trigger.target,'失效') + content: function () { + game.log(player, "发动了察觉,", trigger.card, "对", trigger.target, "失效"); trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='trick'||card.name=='sha') return 'zeroplayertarget'; - } - } - } - }, - tiewan:{ - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return get.type(event.card.viewAs||event.card.name)=='delay'&&event.player!=player; - }, - direct:true, - content:function(){ - 'step 0' - player.chooseCardTarget({ - prompt:get.prompt('tiewan'), - filterCard:{color:'red'}, - position:'he', - filterTarget:function(card,player,target){ - return player.canUse({name:'lebu'},target); + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "trick" || card.name == "sha") return "zeroplayertarget"; }, - ai1:function(card){ - return 7-get.value(card); - }, - ai2:function(target){ - return get.effect(target,{name:'lebu'},player,player); - } - }); - 'step 1' - if(result.bool){ - player.logSkill('tiewan'); - player.useCard({name:'lebu'},result.cards,result.targets); - } - }, - ai:{ - threaten:1.5 - } - }, - qianglue:{ - trigger:{player:'shaMiss'}, - priority:-1, - filter:function(event){ - return event.target.countCards('he')>0; - }, - check:function(event,player){ - return get.attitude(player,event.target)<0; - }, - content:function(){ - 'step 0' - player.judge(function(card){ - return get.color(card)=='black'?1:-1; - }); - 'step 1' - if(result.bool){ - player.gainPlayerCard('he',trigger.target); - } - } - }, - jimin:{ - enable:['chooseToRespond','chooseToUse'], - filterCard:true, - viewAs:{name:'shan'}, - viewAsFilter:function(player){ - if(!player.countCards('h')) return false; - if(player.countCards('e')) return false; - }, - prompt:'将一张手牌当闪使用或打出', - check:function(){return 1}, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('h')) return false; - if(player.countCards('e')) return false; }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0&&!target.countCards('e')) return 0.6 - } - } - } + }, }, - xiadao:{ - trigger:{source:'damageEnd'}, - direct:true, - filter:function(event,player){ - if(event._notrigger.includes(event.player)) return false; - if(event.player.isDead()) return false; - var nh=event.player.countCards('h'); - if(nh==0) return false; - var players=game.filterPlayer(); - for(var i=0;i 0; + }, + check: function (event, player) { + return get.attitude(player, event.target) < 0; + }, + content: function () { + "step 0"; + player.judge(function (card) { + return get.color(card) == "black" ? 1 : -1; + }); + "step 1"; + if (result.bool) { + player.gainPlayerCard("he", trigger.target); + } + }, + }, + jimin: { + enable: ["chooseToRespond", "chooseToUse"], + filterCard: true, + viewAs: { name: "shan" }, + viewAsFilter: function (player) { + if (!player.countCards("h")) return false; + if (player.countCards("e")) return false; + }, + prompt: "将一张手牌当闪使用或打出", + check: function () { + return 1; + }, + ai: { + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("h")) return false; + if (player.countCards("e")) return false; + }, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0 && !target.countCards("e")) + return 0.6; + }, + }, + }, + }, + xiadao: { + trigger: { source: "damageEnd" }, + direct: true, + filter: function (event, player) { + if (event._notrigger.includes(event.player)) return false; + if (event.player.isDead()) return false; + var nh = event.player.countCards("h"); + if (nh == 0) return false; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i] != player && + players[i] != event.player && + players[i].countCards("h") <= nh + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var nh=trigger.player.countCards('h'); - var att=get.attitude(player,trigger.player); - player.chooseTarget(get.prompt('xiadao'),function(card,player,target){ - return target!=player&&target!=trigger.player&&target.countCards('h')<=nh; - }).ai=function(target){ - if(att>0) return 0; - return get.attitude(player,target); - } - 'step 1' - if(result.bool){ - player.logSkill('xiadao'); - player.line2([trigger.player,result.targets[0]],'green'); - event.target=result.targets[0]; + content: function () { + "step 0"; + var nh = trigger.player.countCards("h"); + var att = get.attitude(player, trigger.player); + player.chooseTarget(get.prompt("xiadao"), function (card, player, target) { + return target != player && target != trigger.player && target.countCards("h") <= nh; + }).ai = function (target) { + if (att > 0) return 0; + return get.attitude(player, target); + }; + "step 1"; + if (result.bool) { + player.logSkill("xiadao"); + player.line2([trigger.player, result.targets[0]], "green"); + event.target = result.targets[0]; game.delay(); - } - else{ + } else { event.finish(); } - 'step 0' - if(event.target){ - var card=trigger.player.getCards('h').randomGet(); - event.target.gain(card,trigger.player); - trigger.player.$giveAuto(card,event.target); + "step 0"; + if (event.target) { + var card = trigger.player.getCards("h").randomGet(); + event.target.gain(card, trigger.player); + trigger.player.$giveAuto(card, event.target); } }, - ai:{ - expose:0.2, - threaten:1.4 - } + ai: { + expose: 0.2, + threaten: 1.4, + }, }, - lzhangyi:{ - trigger:{player:'discardAfter'}, - filter:function(event,player){ - for(var i=0;i2){ - du=0; + if (du == -1 && trigger.cards.length > 2) { + du = 0; } } - player.chooseTarget(get.prompt('lzhangyi'),function(card,player,target){ - return player!=target - }).set('du',du).ai=function(target){ - var att=get.attitude(_status.event.player,target); - return att*_status.event.du; + player + .chooseTarget(get.prompt("lzhangyi"), function (card, player, target) { + return player != target; + }) + .set("du", du).ai = function (target) { + var att = get.attitude(_status.event.player, target); + return att * _status.event.du; }; - "step 2" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('lzhangyi',target); - var cards=[]; - for(var i=0;i0) return 0; - return 7-get.value(card); + ai1: function (card) { + if ( + player.additionalSkills.yizhuang && + player.additionalSkills.yizhuang.length > 0 + ) + return 0; + return 7 - get.value(card); + }, + ai2: function (target) { + if (target.isMin()) return 0; + return 6 - target.maxHp; }, - ai2:function(target){ - if(target.isMin()) return 0; - return 6-target.maxHp; - } }); - } - else{ + } else { event.finish(); } - "step 1" - if(result.bool){ - player.unmark(player.storage.yizhuang+'_charactermark'); + "step 1"; + if (result.bool) { + player.unmark(player.storage.yizhuang + "_charactermark"); player.discard(result.cards); - player.logSkill('yizhuang',result.targets); - var name=result.targets[0].name; - if(name.indexOf('unknown')==0){ - name=result.targets[0].name2; + player.logSkill("yizhuang", result.targets); + var name = result.targets[0].name; + if (name.indexOf("unknown") == 0) { + name = result.targets[0].name2; } - var list=[]; - var skills=lib.character[name][3]; - for(var j=0;j0; + ai: { + threaten: 1.5, }, - content:function(){ - player.unmark(player.storage.yizhuang+'_charactermark'); - player.removeAdditionalSkill('yizhuang'); + }, + yizhuang2: { + trigger: { player: "damageAfter" }, + priority: -15, + forced: true, + filter: function (event, player) { + return player.additionalSkills.yizhuang && player.additionalSkills.yizhuang.length > 0; + }, + content: function () { + player.unmark(player.storage.yizhuang + "_charactermark"); + player.removeAdditionalSkill("yizhuang"); delete player.storage.yizhuang; player.checkMarks(); - } + }, }, - kongju:{ - mod:{ - maxHandcard:function(player,num){ - if(player.hp target.maxHp) { + if (card.name == "lebu") return false; } - else if(target.countCards('h')>target.maxHp){ - if(card.name=='lebu') return false; - } - } + }, }, }, - tuqiang:{ - trigger:{player:['respond','useCard']}, - filter:function(event,player){ - return event.card&&event.card.name=='shan'; + tuqiang: { + trigger: { player: ["respond", "useCard"] }, + filter: function (event, player) { + return event.card && event.card.name == "shan"; }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); }, - ai:{ - mingzhi:false, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'respondShan')){ + ai: { + mingzhi: false, + effect: { + target: function (card, player, target) { + if (get.tag(card, "respondShan")) { return 0.8; } - } + }, }, - } - }, - xumou:{ - inherit:'jushou' - }, - zhensha:{ - trigger:{global:'dying'}, - priority:9, - filter:function(event,player){ - return event.player.hp<=0&&(player.countCards('h','jiu')>0||player.countCards('h',{color:'black'})>=2)&&player!=event.player; }, - direct:true, - content:function(){ - 'step 0' - var goon=(get.attitude(player,trigger.player)<0); - var next=player.chooseToDiscard('鸠杀:是否弃置一张酒或两张黑色手牌令'+get.translation(trigger.player)+'立即死亡?'); - next.ai=function(card){ - if(ui.selected.cards.length){ - if(ui.selected.cards[0].name=='jiu') return 0; + }, + xumou: { + inherit: "jushou", + }, + zhensha: { + trigger: { global: "dying" }, + priority: 9, + filter: function (event, player) { + return ( + event.player.hp <= 0 && + (player.countCards("h", "jiu") > 0 || + player.countCards("h", { color: "black" }) >= 2) && + player != event.player + ); + }, + direct: true, + content: function () { + "step 0"; + var goon = get.attitude(player, trigger.player) < 0; + var next = player.chooseToDiscard( + "鸠杀:是否弃置一张酒或两张黑色手牌令" + + get.translation(trigger.player) + + "立即死亡?" + ); + next.ai = function (card) { + if (ui.selected.cards.length) { + if (ui.selected.cards[0].name == "jiu") return 0; } - if(goon){ - if(card.name=='jiu') return 2; + if (goon) { + if (card.name == "jiu") return 2; return 1; } return 0; }; - next.filterCard=function(card){ - if(ui.selected.cards.length){ - return get.color(card)=='black'; + next.filterCard = function (card) { + if (ui.selected.cards.length) { + return get.color(card) == "black"; } - return get.color(card)=='black'||card.name=='jiu'; + return get.color(card) == "black" || card.name == "jiu"; }; - next.complexCard=true, - next.logSkill=['zhensha',trigger.player]; - next.selectCard=function(){ - if(ui.selected.cards.length){ - if(get.color(ui.selected.cards[0])!='black') return [1,1]; + (next.complexCard = true), (next.logSkill = ["zhensha", trigger.player]); + next.selectCard = function () { + if (ui.selected.cards.length) { + if (get.color(ui.selected.cards[0]) != "black") return [1, 1]; } - return [1,2]; - } - 'step 1' - if(result.bool){ + return [1, 2]; + }; + "step 1"; + if (result.bool) { trigger.player.die(); - } - else{ + } else { event.finish(); } - 'step 2' - if(!trigger.player.isAlive()){ + "step 2"; + if (!trigger.player.isAlive()) { trigger.cancel(true); } }, - ai:{ - threaten:1.5 - } + ai: { + threaten: 1.5, + }, }, - ducai:{ - enable:'phaseUse', - usable:1, - unique:true, - forceunique:true, - check:function(card){ - if(_status.event.player.countCards('h')>=3){ - return 5-get.value(card); + ducai: { + enable: "phaseUse", + usable: 1, + unique: true, + forceunique: true, + check: function (card) { + if (_status.event.player.countCards("h") >= 3) { + return 5 - get.value(card); } return 0; }, - position:'he', - filterCard:true, - content:function(){ - player.storage.ducai2=cards[0]; - player.addTempSkill('ducai2',{player:'phaseBegin'}); + position: "he", + filterCard: true, + content: function () { + player.storage.ducai2 = cards[0]; + player.addTempSkill("ducai2", { player: "phaseBegin" }); }, - ai:{ - order:8, - result:{ - player:1 - } + ai: { + order: 8, + result: { + player: 1, + }, }, - global:'ducai3' + global: "ducai3", }, - ducai2:{ - mark:'card', - intro:{ - content:'card' - } - }, - ducai3:{ - mod:{ - cardEnabled:function(card,player){ - if(player.hasSkill('ducai2')) return; - var suit,players=game.filterPlayer(); - for(var i=0;i=3; + fanpu: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.storage.tongling >= 3; }, - filterTarget:function(card,player,target){ - return player.canUse('sha',target); + filterTarget: function (card, player, target) { + return player.canUse("sha", target); }, - selectTarget:[1,3], - multitarget:true, - multiline:true, - content:function(){ - player.storage.tongling-=3; - player.unmarkSkill('tongling'); - player.syncStorage('tongling'); - player.useCard({name:'sha'},targets,false); + selectTarget: [1, 3], + multitarget: true, + multiline: true, + content: function () { + player.storage.tongling -= 3; + player.unmarkSkill("tongling"); + player.syncStorage("tongling"); + player.useCard({ name: "sha" }, targets, false); + }, + ai: { + combo: "tongling", + order: 2, }, - ai:{ - combo:'tongling', - order:2 - } }, - fanpu_old:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.storage.tongling>=3; + fanpu_old: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.storage.tongling >= 3; }, - promptfunc:function(){ - return '令自己在本轮内不能成为出杀的目标(选择自己),或对攻击范围内的至多两名角色使用一张杀' + promptfunc: function () { + return "令自己在本轮内不能成为出杀的目标(选择自己),或对攻击范围内的至多两名角色使用一张杀"; }, - filterTarget:function(card,player,target){ - return player==target||get.distance(player,target,'attack')<=1; + filterTarget: function (card, player, target) { + return player == target || get.distance(player, target, "attack") <= 1; }, - content:function(){ - if(target==player){ - target.addTempSkill('fanpu_disable',{player:'phaseBegin'}); - } - else{ + content: function () { + if (target == player) { + target.addTempSkill("fanpu_disable", { player: "phaseBegin" }); + } else { target.damage(); } - player.storage.tongling-=3; - player.unmarkSkill('tongling'); - player.syncStorage('tongling'); + player.storage.tongling -= 3; + player.unmarkSkill("tongling"); + player.syncStorage("tongling"); }, - subSkill:{ - disable:{ - mark:true, - intro:{ - content:'不能成为杀的目标' + subSkill: { + disable: { + mark: true, + intro: { + content: "不能成为杀的目标", }, - mod:{ - targetEnabled:function(card,player,target,now){ - if(card.name=='sha') return false; - } - } - } + mod: { + targetEnabled: function (card, player, target, now) { + if (card.name == "sha") return false; + }, + }, + }, }, - ai:{ - combo:'tongling', - order:2, - result:{ - target:function(player,target){ - if(player==target){ - if(player.hp<=2&&!player.countCards('h','shan')){ + ai: { + combo: "tongling", + order: 2, + result: { + target: function (player, target) { + if (player == target) { + if (player.hp <= 2 && !player.countCards("h", "shan")) { return 2; } return 0; + } else { + return get.damageEffect(target, player, target); } - else{ - return get.damageEffect(target,player,target); - } - } - } - } - }, - fenghuo:{ - enable:'chooseToUse', - filter:function(event,player){ - return player.countCards('e')>0; + }, + }, }, - filterCard:true, - position:'e', - viewAs:{name:'nanman'}, - prompt:'将一张装备区内的牌当南蛮入侵使用', - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 11-get.equipValue(card); - } - if(player.countCards('h') 0; + }, + filterCard: true, + position: "e", + viewAs: { name: "nanman" }, + prompt: "将一张装备区内的牌当南蛮入侵使用", + check: function (card) { + var player = _status.currentPhase; + if (player.countCards("he", { subtype: get.subtype(card) }) > 1) { + return 11 - get.equipValue(card); + } + if (player.countCards("h") < player.hp) { + return 6 - get.value(card); + } + return 2 - get.equipValue(card); + }, + ai: { + order: 9, + threaten: 1.1, + }, + }, + nichang: { + trigger: { player: "phaseDrawBefore" }, + check: function (event, player) { + if (player.skipList.includes("phaseUse")) return true; + var suits = ["spade", "heart", "diamond", "club"]; + var cards = player.getCards("h"); + for (var i = 0; i < cards.length; i++) { suits.remove(get.suit(cards[i])); } - return suits.length>=2; + return suits.length >= 2; }, - content:function(){ + content: function () { trigger.cancel(); - player.addSkill('nichang2'); - } + player.addSkill("nichang2"); + }, }, - nichang2:{ - trigger:{player:'phaseEnd'}, - forced:true, - content:function(){ - "step 0" - if(player.countCards('h')){ + nichang2: { + trigger: { player: "phaseEnd" }, + forced: true, + content: function () { + "step 0"; + if (player.countCards("h")) { player.showHandcards(); } - player.removeSkill('nichang2'); - "step 1" - var suits=['spade','heart','diamond','club']; - var cards=player.getCards('h'); - for(var i=0;i1){ - if(game.phaseNumber 1) { + if (game.phaseNumber < game.players.length) return 0; + for (var i = 0; i < players.length; i++) { + if (players[i].ai.shown == 0) return 0; + if (players[i].sex == "unknown") return 0; } } - var effect=0; - for(var i=0;i=3){ + if (get.suit(card) == suit || i >= 3) { break; } } - event.cards=cards; - event.suit=suit; + event.cards = cards; + event.suit = suit; player.showCards(cards); - } - else{ + } else { event.finish(); } - "step 2" - if(event.cards&&event.cards.length){ - if(get.suit(event.cards[event.cards.length-1])==event.suit){ + "step 2"; + if (event.cards && event.cards.length) { + if (get.suit(event.cards[event.cards.length - 1]) == event.suit) { event.cards.pop().discard(); } - if(event.cards.length){ - player.gain(event.cards,'draw2'); + if (event.cards.length) { + player.gain(event.cards, "draw2"); } } }, - ai:{ - maixie:true, - maixie_hp:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - if(target.hp>=4) return [1,2]; - if(target.hp==3) return [1,1.5]; - if(target.hp==2) return [1,0.5]; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + if (target.hp >= 4) return [1, 2]; + if (target.hp == 3) return [1, 1.5]; + if (target.hp == 2) return [1, 0.5]; } - } - } - } - }, - bolehuiyan:{ - trigger:{global:'shaBegin'}, - direct:true, - priority:11, - filter:function(event,player){ - if(player.hasSkill('bolehuiyan4')) return false; - if(event.target.isUnderControl()) return false; - return event.player!=player&&event.target!=player&&event.target.countCards('h')>0; + }, + }, }, - group:['bolehuiyan2','bolehuiyan3'], - content:function(){ - "step 0" - if(event.isMine()){ - event.dialog=ui.create.dialog('慧眼:预言'+get.translation(trigger.player)+'对'+get.translation(trigger.target)+'的杀能否命中'); + }, + bolehuiyan: { + trigger: { global: "shaBegin" }, + direct: true, + priority: 11, + filter: function (event, player) { + if (player.hasSkill("bolehuiyan4")) return false; + if (event.target.isUnderControl()) return false; + return ( + event.player != player && event.target != player && event.target.countCards("h") > 0 + ); + }, + group: ["bolehuiyan2", "bolehuiyan3"], + content: function () { + "step 0"; + if (event.isMine()) { + event.dialog = ui.create.dialog( + "慧眼:预言" + + get.translation(trigger.player) + + "对" + + get.translation(trigger.target) + + "的杀能否命中" + ); } - player.chooseControl('能命中','不能命中','cancel').ai=function(event){ - if(trigger.player.hasSkill('wushuang')) return 0; - if(trigger.player.hasSkill('liegong')) return 0; - if(trigger.player.hasSkill('tieji')) return 0; - if(trigger.player.hasSkill('juji')) return 0; - if(trigger.player.hasSkill('retieji')) return 0; - if(trigger.player.hasSkill('roulin')&&trigger.target.sex=='female') return 0; - if(trigger.player.hasSkill('nvquan')&&trigger.target.sex=='male') return 0; - if(trigger.target.hasSkill('yijue2')) return 0; - if(trigger.target.hasSkill('shejie2')) return 0; - if(trigger.target.hasSkill('shanguang2')) return 0; + player.chooseControl("能命中", "不能命中", "cancel").ai = function (event) { + if (trigger.player.hasSkill("wushuang")) return 0; + if (trigger.player.hasSkill("liegong")) return 0; + if (trigger.player.hasSkill("tieji")) return 0; + if (trigger.player.hasSkill("juji")) return 0; + if (trigger.player.hasSkill("retieji")) return 0; + if (trigger.player.hasSkill("roulin") && trigger.target.sex == "female") return 0; + if (trigger.player.hasSkill("nvquan") && trigger.target.sex == "male") return 0; + if (trigger.target.hasSkill("yijue2")) return 0; + if (trigger.target.hasSkill("shejie2")) return 0; + if (trigger.target.hasSkill("shanguang2")) return 0; - var equip=trigger.target.getEquip(2); - if(equip&&(equip.name=='bagua'||equip.name=='rewrite_bagua')) return 1; - return trigger.target.countCards('h')<2?0:1; + var equip = trigger.target.getEquip(2); + if (equip && (equip.name == "bagua" || equip.name == "rewrite_bagua")) return 1; + return trigger.target.countCards("h") < 2 ? 0 : 1; }; - "step 1" - if(event.dialog){ + "step 1"; + if (event.dialog) { event.dialog.close(); } - if(result.control!='cancel'){ - player.addTempSkill('bolehuiyan4'); - player.logSkill(['bolehuiyan',result.control],trigger.target); - game.log(player,'预言'+result.control); - player.storage.bolehuiyan=result.control; + if (result.control != "cancel") { + player.addTempSkill("bolehuiyan4"); + player.logSkill(["bolehuiyan", result.control], trigger.target); + game.log(player, "预言" + result.control); + player.storage.bolehuiyan = result.control; game.delay(); } }, - ai:{ - threaten:1.3 - } - }, - bolehuiyan2:{ - trigger:{global:'shaEnd'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.bolehuiyan?true:false; + ai: { + threaten: 1.3, }, - content:function(){ - if(player.storage.bolehuiyan=='不能命中'){ - player.popup('预言成功'); + }, + bolehuiyan2: { + trigger: { global: "shaEnd" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.bolehuiyan ? true : false; + }, + content: function () { + if (player.storage.bolehuiyan == "不能命中") { + player.popup("预言成功"); player.draw(); - } - else{ - player.popup('预言失败'); - player.chooseToDiscard('预言失败,请弃置一张牌','he',true); + } else { + player.popup("预言失败"); + player.chooseToDiscard("预言失败,请弃置一张牌", "he", true); } delete player.storage.bolehuiyan; - } - }, - bolehuiyan3:{ - trigger:{global:'shaDamage'}, - forced:true, - popup:false, - filter:function(event,player){ - return player.storage.bolehuiyan?true:false; }, - content:function(){ - if(player.storage.bolehuiyan=='能命中'){ - player.popup('预言成功'); + }, + bolehuiyan3: { + trigger: { global: "shaDamage" }, + forced: true, + popup: false, + filter: function (event, player) { + return player.storage.bolehuiyan ? true : false; + }, + content: function () { + if (player.storage.bolehuiyan == "能命中") { + player.popup("预言成功"); player.draw(); - } - else{ - player.popup('预言失败'); - player.chooseToDiscard('预言失败,请弃置一张牌','he',true); + } else { + player.popup("预言失败"); + player.chooseToDiscard("预言失败,请弃置一张牌", "he", true); } delete player.storage.bolehuiyan; - } - }, - bolehuiyan4:{}, - oldbolehuiyan:{ - trigger:{global:'judgeBegin'}, - direct:true, - priority:11, - filter:function(event,player){ - return event.player!=player; }, - content:function(){ - "step 0" - if(event.isMine()){ - event.dialog=ui.create.dialog('慧眼:预言'+get.translation(trigger.player)+'的'+trigger.judgestr+'判定'); + }, + bolehuiyan4: {}, + oldbolehuiyan: { + trigger: { global: "judgeBegin" }, + direct: true, + priority: 11, + filter: function (event, player) { + return event.player != player; + }, + content: function () { + "step 0"; + if (event.isMine()) { + event.dialog = ui.create.dialog( + "慧眼:预言" + get.translation(trigger.player) + "的" + trigger.judgestr + "判定" + ); } - player.chooseControl('heart2','diamond2','club2','spade2','cancel').ai=function(event){ - switch(Math.floor(Math.random()*4)){ - case 0:return 'heart2'; - case 1:return 'diamond2'; - case 2:return 'club2'; - case 3:return 'spade2'; + player.chooseControl("heart2", "diamond2", "club2", "spade2", "cancel").ai = function ( + event + ) { + switch (Math.floor(Math.random() * 4)) { + case 0: + return "heart2"; + case 1: + return "diamond2"; + case 2: + return "club2"; + case 3: + return "spade2"; } }; - "step 1" - if(event.dialog){ + "step 1"; + if (event.dialog) { event.dialog.close(); } - if(result.control!='cancel'){ - game.log(player,'预言判定结果为'+get.translation(result.control)); - player.storage.bolehuiyan=result.control.slice(0,result.control.length-1); + if (result.control != "cancel") { + game.log(player, "预言判定结果为" + get.translation(result.control)); + player.storage.bolehuiyan = result.control.slice(0, result.control.length - 1); player.popup(result.control); game.delay(); } }, - group:'bolehuiyan2' + group: "bolehuiyan2", }, - oldbolehuiyan2:{ - trigger:{global:'judgeEnd'}, - forced:true, - popup:false, - content:function(){ - if(player.storage.bolehuiyan==trigger.result.suit){ - game.log(player,'预言成功'); - player.popup('洗具'); + oldbolehuiyan2: { + trigger: { global: "judgeEnd" }, + forced: true, + popup: false, + content: function () { + if (player.storage.bolehuiyan == trigger.result.suit) { + game.log(player, "预言成功"); + player.popup("洗具"); player.draw(2); - } - else if(get.color({suit:player.storage.bolehuiyan})==trigger.result.color){ - player.popup('洗具'); + } else if (get.color({ suit: player.storage.bolehuiyan }) == trigger.result.color) { + player.popup("洗具"); player.draw(); } delete player.storage.bolehuiyan; - } + }, }, - xiangma:{ - inherit:'yicong' + xiangma: { + inherit: "yicong", }, - yxsweiyi:{ - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return (event.source&&event.source.countCards('he')); + yxsweiyi: { + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return event.source && event.source.countCards("he"); }, - check:function(event,player){ - return get.attitude(player,event.source)<0; + check: function (event, player) { + return get.attitude(player, event.source) < 0; }, - content:function(){ - trigger.source.chooseToDiscard(2,'he',true); + content: function () { + trigger.source.chooseToDiscard(2, "he", true); }, - logTarget:'source', - ai:{ - maixie_defend:true, - expose:0.3, - result:{ - target:function(card,player,target){ - if(player.countCards('he')>1&&get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1]; - if(get.attitude(target,player)<0) return [1,0,0,-1.5]; + logTarget: "source", + ai: { + maixie_defend: true, + expose: 0.3, + result: { + target: function (card, player, target) { + if (player.countCards("he") > 1 && get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1]; + if (get.attitude(target, player) < 0) return [1, 0, 0, -1.5]; } - } - } - } + }, + }, + }, }, - qiandu:{ - enable:'phaseUse', - usable:1, - changeSeat:true, - filterTarget:function(card,player,target){ - return player!=target&&player.next!=target; + qiandu: { + enable: "phaseUse", + usable: 1, + changeSeat: true, + filterTarget: function (card, player, target) { + return player != target && player.next != target; }, - filterCard:{color:'black'}, - check:function(card){ - return 4-get.value(card); + filterCard: { color: "black" }, + check: function (card) { + return 4 - get.value(card); }, - content:function(){ - game.swapSeat(player,target); + content: function () { + game.swapSeat(player, target); }, - ai:{ - order:5, - result:{ - player:function(player,target){ - var att=get.attitude(player,target); - if(target==player.previous&&att>0) return att; - if(target==player.next&&att<0) return -att; - var att2=get.attitude(player,player.next); - if(target==player.next.next&&att<0&&att2<0) return -att-att2; + ai: { + order: 5, + result: { + player: function (player, target) { + var att = get.attitude(player, target); + if (target == player.previous && att > 0) return att; + if (target == player.next && att < 0) return -att; + var att2 = get.attitude(player, player.next); + if (target == player.next.next && att < 0 && att2 < 0) return -att - att2; return 0; - } - } - } - }, - nvquan:{ - locked:true, - group:['nvquan1','nvquan2','nvquan3'], - }, - nvquan1:{ - trigger:{player:'shaBegin'}, - forced:true, - filter:function(event){ - return event.target.sex=='male'; + }, + }, }, - priority:-1, - content:function(){ - if(typeof trigger.shanRequired=='number'){ + }, + nvquan: { + locked: true, + group: ["nvquan1", "nvquan2", "nvquan3"], + }, + nvquan1: { + trigger: { player: "shaBegin" }, + forced: true, + filter: function (event) { + return event.target.sex == "male"; + }, + priority: -1, + content: function () { + if (typeof trigger.shanRequired == "number") { trigger.shanRequired++; + } else { + trigger.shanRequired = 2; } - else{ - trigger.shanRequired=2; - } - } - }, - nvquan2:{ - trigger:{player:'juedou',target:'juedou'}, - forced:true, - filter:function(event,player){ - return event.turn!=player&&event.turn.sex=='male'; }, - priority:-1, - content:function(){ - "step 0" - var next=trigger.turn.chooseToRespond({name:'sha'},'请打出一张杀响应决斗'); - next.set('prompt2','(共需打出2张杀)'); - next.autochoose=lib.filter.autoRespondSha; - next.ai=function(card){ - if(get.attitude(trigger.turn,player)<0&&trigger.turn.countCards('h','sha')>1){ + }, + nvquan2: { + trigger: { player: "juedou", target: "juedou" }, + forced: true, + filter: function (event, player) { + return event.turn != player && event.turn.sex == "male"; + }, + priority: -1, + content: function () { + "step 0"; + var next = trigger.turn.chooseToRespond({ name: "sha" }, "请打出一张杀响应决斗"); + next.set("prompt2", "(共需打出2张杀)"); + next.autochoose = lib.filter.autoRespondSha; + next.ai = function (card) { + if ( + get.attitude(trigger.turn, player) < 0 && + trigger.turn.countCards("h", "sha") > 1 + ) { return get.unuseful2(card); } return -1; }; - "step 1" - if(result.bool==false){ - trigger.directHit=true; + "step 1"; + if (result.bool == false) { + trigger.directHit = true; } }, - ai:{ - result:{ - target:function(card,player,target){ - if(card.name=='juedou'&&target.countCards('h')>0) return [1,0,0,-1]; - } - } - } + ai: { + result: { + target: function (card, player, target) { + if (card.name == "juedou" && target.countCards("h") > 0) return [1, 0, 0, -1]; + }, + }, + }, }, - nvquan3:{ - mod:{ - targetEnabled:function(card,player,target){ - if(card.name=='juedou'&&player.sex=='male'){ + nvquan3: { + mod: { + targetEnabled: function (card, player, target) { + if (card.name == "juedou" && player.sex == "male") { return false; } - } - } - }, - feigong:{ - trigger:{global:'useCard'}, - priority:15, - filter:function(event,player){ - return event.card.name=='sha'&&event.player!=player&& - player.countCards('h','sha')>0&&event.targets.includes(player)==false; + }, }, - direct:true, - content:function(){ - "step 0" - var effect=0; - for(var i=0;i 0 && + event.targets.includes(player) == false + ); + }, + direct: true, + content: function () { + "step 0"; + var effect = 0; + for (var i = 0; i < trigger.targets.length; i++) { + effect += get.effect(trigger.targets[i], trigger.card, trigger.player, player); } - var str='弃置一张杀令'+get.translation(trigger.player); - if(trigger.targets&&trigger.targets.length){ - str+='对'+get.translation(trigger.targets); + var str = "弃置一张杀令" + get.translation(trigger.player); + if (trigger.targets && trigger.targets.length) { + str += "对" + get.translation(trigger.targets); } - str+='的'+get.translation(trigger.card)+'失效'; - var next=player.chooseToDiscard('h',{name:'sha'},get.prompt('feigong')); - next.prompt2=str; - next.ai=function(card){ - if(effect<0){ - return 9-get.value(card); + str += "的" + get.translation(trigger.card) + "失效"; + var next = player.chooseToDiscard("h", { name: "sha" }, get.prompt("feigong")); + next.prompt2 = str; + next.ai = function (card) { + if (effect < 0) { + return 9 - get.value(card); } return -1; - } - next.autodelay=true; - next.logSkill=['feigong',trigger.player]; - "step 1" - if(result.bool){ + }; + next.autodelay = true; + next.logSkill = ["feigong", trigger.player]; + "step 1"; + if (result.bool) { trigger.cancel(); } }, - ai:{ - threaten:1.2, - expose:0.2 - } + ai: { + threaten: 1.2, + expose: 0.2, + }, }, - feiming:{ - trigger:{player:'damageEnd'}, - check:function(event,player){ - return get.attitude(player,event.source)<=0; + feiming: { + trigger: { player: "damageEnd" }, + check: function (event, player) { + return get.attitude(player, event.source) <= 0; }, - filter:function(event,player){ - return event.source&&event.source!=player; + filter: function (event, player) { + return event.source && event.source != player; }, - content:function(){ - "step 0" - trigger.source.chooseCard('交出一张红桃牌或失去1点体力',function(card){ - return get.suit(card)=='heart'; - }).ai=function(card){ - return 6-get.value(card); + content: function () { + "step 0"; + trigger.source.chooseCard("交出一张红桃牌或失去1点体力", function (card) { + return get.suit(card) == "heart"; + }).ai = function (card) { + return 6 - get.value(card); }; - "step 1" - if(result.bool){ - player.gain(result.cards[0],trigger.source); - trigger.source.$give(1,player); - } - else{ + "step 1"; + if (result.bool) { + player.gain(result.cards[0], trigger.source); + trigger.source.$give(1, player); + } else { trigger.source.loseHp(); } }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return [1,0,0,-1]; - } - } - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) return [1, 0, 0, -1]; + }, + }, + }, }, - jianai:{ - trigger:{player:'recoverEnd'}, - check:function(event,player){ - if(event.parent.name=='taoyuan'&&event.parent.player==player){ + jianai: { + trigger: { player: "recoverEnd" }, + check: function (event, player) { + if (event.parent.name == "taoyuan" && event.parent.player == player) { return false; } - var num=0; - var eff,players=game.filterPlayer(); - for(var i=0;i2){ - eff+=0.5; + if (players[i].hp == 1 && players[i].maxHp > 2) { + eff += 0.5; } } - if(get.attitude(player,players[i])>0){ - num+=eff; - } - else if(get.attitude(player,players[i])<0){ - num-=eff; + if (get.attitude(player, players[i]) > 0) { + num += eff; + } else if (get.attitude(player, players[i]) < 0) { + num -= eff; } } - return num>0; + return num > 0; }, - content:function(){ - "step 0" - event.targets=game.filterPlayer(); + content: function () { + "step 0"; + event.targets = game.filterPlayer(); event.targets.remove(player); - "step 1" - if(event.targets.length){ + "step 1"; + if (event.targets.length) { event.targets.shift().recover(); event.redo(); } }, - ai:{ - expose:0.1 - } - }, - jieyong:{ - trigger:{player:'useCardAfter'}, - direct:true, - filter:function(event,player){ - if(event.cards.filterInD().length==0) return false; - if(player.hasSkill('jieyong2')) return false; - return player.countCards('he',{color:'black'})>0; + ai: { + expose: 0.1, }, - content:function(){ - "step 0" - var next=player.chooseToDiscard('he','是否弃置一张黑色牌并收回'+get.translation(trigger.cards.filterInD())+'?',{color:'black'}); - next.ai=function(card){ - return get.value(trigger.card)-get.value(card); - } - next.logSkill='jieyong'; - "step 1" - if(result.bool){ - player.gain(trigger.cards.filterInD(),'gain2','log'); - player.addTempSkill('jieyong2',['phaseAfter','phaseBegin']); - } - }, - ai:{ - threaten:1.3 - } }, - jieyong2:{ - filterCard:{suit:'heart'}, - popname:true, - }, - jieyong3:{ - trigger:{player:'useCardBefore'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.skill=='jieyong2'; + jieyong: { + trigger: { player: "useCardAfter" }, + direct: true, + filter: function (event, player) { + if (event.cards.filterInD().length == 0) return false; + if (player.hasSkill("jieyong2")) return false; + return player.countCards("he", { color: "black" }) > 0; }, - content:function(){ - player.popup(trigger.card.name); - player.getStat('skill').jieyong++; - } - }, - jieyong4:{}, - jieyong5:{}, - jieyong6:{}, - zhulu:{ - trigger:{global:'useCardAfter'}, - direct:true, - filter:function(event,player){ - return _status.currentPhase!=player&&event.player!=player&&get.type(event.card)=='trick'&& - event.cards.filterInD().length>0&&!player.hasSkill('zhulu2')&& - player.countCards('he',{suit:get.suit(event.card)})>0; - }, - content:function(){ - "step 0" - var val=get.value(trigger.card); - var suit=get.suit(trigger.card); - var next=player.chooseToDiscard('he','逐鹿:是否弃置一张'+get.translation(suit)+ - '牌并获得'+get.translation(trigger.cards.filterInD())+'?',{suit:suit}); - next.ai=function(card){ - return val-get.value(card); + content: function () { + "step 0"; + var next = player.chooseToDiscard( + "he", + "是否弃置一张黑色牌并收回" + get.translation(trigger.cards.filterInD()) + "?", + { color: "black" } + ); + next.ai = function (card) { + return get.value(trigger.card) - get.value(card); }; - next.logSkill='zhulu'; - "step 1" - if(result.bool){ - player.gain(trigger.cards.filterInD(),'log','gain2'); - player.addTempSkill('zhulu2'); + next.logSkill = "jieyong"; + "step 1"; + if (result.bool) { + player.gain(trigger.cards.filterInD(), "gain2", "log"); + player.addTempSkill("jieyong2", ["phaseAfter", "phaseBegin"]); } }, - ai:{ - threaten:1.2 - } + ai: { + threaten: 1.3, + }, }, - zhulu2:{}, - xieling:{ - enable:'phaseUse', - usable:1, - filterCard:true, - selectCard:2, - check:function(card){ - return 7-get.value(card); + jieyong2: { + filterCard: { suit: "heart" }, + popname: true, + }, + jieyong3: { + trigger: { player: "useCardBefore" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.skill == "jieyong2"; }, - multitarget:true, - targetprompt:['被移走','移动目标'], - filterTarget:function(card,player,target){ - if(ui.selected.targets.length){ - var from=ui.selected.targets[0]; - var judges=from.getCards('j'); - for(var i=0;i 0 && + !player.hasSkill("zhulu2") && + player.countCards("he", { suit: get.suit(event.card) }) > 0 + ); + }, + content: function () { + "step 0"; + var val = get.value(trigger.card); + var suit = get.suit(trigger.card); + var next = player.chooseToDiscard( + "he", + "逐鹿:是否弃置一张" + + get.translation(suit) + + "牌并获得" + + get.translation(trigger.cards.filterInD()) + + "?", + { suit: suit } + ); + next.ai = function (card) { + return val - get.value(card); + }; + next.logSkill = "zhulu"; + "step 1"; + if (result.bool) { + player.gain(trigger.cards.filterInD(), "log", "gain2"); + player.addTempSkill("zhulu2"); + } + }, + ai: { + threaten: 1.2, + }, + }, + zhulu2: {}, + xieling: { + enable: "phaseUse", + usable: 1, + filterCard: true, + selectCard: 2, + check: function (card) { + return 7 - get.value(card); + }, + multitarget: true, + targetprompt: ["被移走", "移动目标"], + filterTarget: function (card, player, target) { + if (ui.selected.targets.length) { + var from = ui.selected.targets[0]; + var judges = from.getCards("j"); + for (var i = 0; i < judges.length; i++) { + if (!target.hasJudge(judges[i].viewAs || judges[i].name)) return true; } - if(target.isMin()) return false; - if((from.getEquip(1)&&!target.getEquip(1))|| - (from.getEquip(2)&&!target.getEquip(2))|| - (from.getEquip(3)&&!target.getEquip(3))|| - (from.getEquip(4)&&!target.getEquip(4))|| - (from.getEquip(5)&&!target.getEquip(5))) return true; + if (target.isMin()) return false; + if ( + (from.getEquip(1) && !target.getEquip(1)) || + (from.getEquip(2) && !target.getEquip(2)) || + (from.getEquip(3) && !target.getEquip(3)) || + (from.getEquip(4) && !target.getEquip(4)) || + (from.getEquip(5) && !target.getEquip(5)) + ) + return true; return false; - } - else{ - return target.countCards('ej')>0; + } else { + return target.countCards("ej") > 0; } }, - selectTarget:2, - content:function(){ - "step 0" - if(targets.length==2){ - player.choosePlayerCard('ej',function(button){ - if(get.attitude(player,targets[0])>get.attitude(player,targets[1])){ - return get.position(button.link)=='j'?10:0; - } - else{ - if(get.position(button.link)=='j') return -10; - return get.equipValue(button.link); - } - },targets[0]); - } - else{ + selectTarget: 2, + content: function () { + "step 0"; + if (targets.length == 2) { + player.choosePlayerCard( + "ej", + function (button) { + if (get.attitude(player, targets[0]) > get.attitude(player, targets[1])) { + return get.position(button.link) == "j" ? 10 : 0; + } else { + if (get.position(button.link) == "j") return -10; + return get.equipValue(button.link); + } + }, + targets[0] + ); + } else { event.finish(); } - "step 1" - if(result.bool){ - if(get.position(result.buttons[0].link)=='e'){ + "step 1"; + if (result.bool) { + if (get.position(result.buttons[0].link) == "e") { event.targets[1].equip(result.buttons[0].link); - } - else if(result.buttons[0].link.viewAs){ - event.targets[1].addJudge({name:result.buttons[0].link.viewAs},[result.buttons[0].link]); - } - else{ + } else if (result.buttons[0].link.viewAs) { + event.targets[1].addJudge({ name: result.buttons[0].link.viewAs }, [ + result.buttons[0].link, + ]); + } else { event.targets[1].addJudge(result.buttons[0].link); } - event.targets[0].$give(result.buttons[0].link,event.targets[1]) + event.targets[0].$give(result.buttons[0].link, event.targets[1]); game.delay(); } }, - ai:{ - order:10, - result:{ - target:function(player,target){ - if(ui.selected.targets.length==0){ - if(target.countCards('j')&&get.attitude(player,target)>0) return 1; - if(get.attitude(player,target)<0){ - var players=game.filterPlayer(); - for(var i=0;i0){ - if((target.getEquip(1)&&!players[i].getEquip(1))|| - (target.getEquip(2)&&!players[i].getEquip(2))|| - (target.getEquip(3)&&!players[i].getEquip(3))|| - (target.getEquip(4)&&!players[i].getEquip(4))|| - (target.getEquip(5)&&!players[i].getEquip(5))) + ai: { + order: 10, + result: { + target: function (player, target) { + if (ui.selected.targets.length == 0) { + if (target.countCards("j") && get.attitude(player, target) > 0) return 1; + if (get.attitude(player, target) < 0) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(player, players[i]) > 0) { + if ( + (target.getEquip(1) && !players[i].getEquip(1)) || + (target.getEquip(2) && !players[i].getEquip(2)) || + (target.getEquip(3) && !players[i].getEquip(3)) || + (target.getEquip(4) && !players[i].getEquip(4)) || + (target.getEquip(5) && !players[i].getEquip(5)) + ) return -1; } } } return 0; - } - else{ - return get.attitude(player,ui.selected.targets[0])>0?-1:1; + } else { + return get.attitude(player, ui.selected.targets[0]) > 0 ? -1 : 1; } }, }, - expose:0.2, - threaten:1.5 - } + expose: 0.2, + threaten: 1.5, + }, }, - qiangyun:{ - trigger:{player:'loseEnd'}, - frequent:true, - filter:function(event,player){ - if(player.countCards('h')) return false; - for(var i=0;i0; + ai: { + threaten: 1.2, }, - content:function(){ - 'step 0' - player.discardPlayerCard(target,true); - 'step 1' - if(result.bool){ - var type=get.type(result.cards[0]); - if(type!='basic'&&type!='trick'){ - player.chooseToDiscard('he',true); + }, + miaobix: { + filterCard: true, + selectCard: 1, + popname: true, + }, + miaobi: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; + }, + content: function () { + "step 0"; + player.discardPlayerCard(target, true); + "step 1"; + if (result.bool) { + var type = get.type(result.cards[0]); + if (type != "basic" && type != "trick") { + player.chooseToDiscard("he", true); event.finish(); + } else { + event.card = result.cards[0]; } - else{ - event.card=result.cards[0]; - } - } - else{ + } else { event.finish(); } - 'step 2' - var card=event.card; - card={name:card.name,nature:card.nature,suit:card.suit,number:card.number}; - if(lib.filter.cardEnabled(card)){ - if(game.hasPlayer(function(current){ - return player.canUse(card,current); - })){ - lib.skill.miaobix.viewAs=card; - var next=player.chooseToUse(); - next.logSkill='miaobi'; - next.set('openskilldialog','妙笔:将一张手牌当'+get.translation(card)+'使用'); - next.set('norestore',true); - next.set('_backupevent','miaobix'); - next.set('custom',{ - add:{}, - replace:{window:function(){}} + "step 2"; + var card = event.card; + card = { name: card.name, nature: card.nature, suit: card.suit, number: card.number }; + if (lib.filter.cardEnabled(card)) { + if ( + game.hasPlayer(function (current) { + return player.canUse(card, current); + }) + ) { + lib.skill.miaobix.viewAs = card; + var next = player.chooseToUse(); + next.logSkill = "miaobi"; + next.set( + "openskilldialog", + "妙笔:将一张手牌当" + get.translation(card) + "使用" + ); + next.set("norestore", true); + next.set("_backupevent", "miaobix"); + next.set("custom", { + add: {}, + replace: { window: function () {} }, }); - next.backup('miaobix'); + next.backup("miaobix"); } } }, - ai:{ - order:9, - result:{ - target:-1 - } - } - }, - zhexian:{ - trigger:{player:'loseEnd'}, - usable:1, - filter:function(event,player){ - return _status.currentPhase!=player; + ai: { + order: 9, + result: { + target: -1, + }, }, - frequent:true, - content:function(){ + }, + zhexian: { + trigger: { player: "loseEnd" }, + usable: 1, + filter: function (event, player) { + return _status.currentPhase != player; + }, + frequent: true, + content: function () { player.draw(); - } - }, - guifu:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.countCards('e')>0; }, - content:function(){ - 'step 0' - player.discardPlayerCard(target,'e',true); - 'step 1' - game.asyncDraw([player,target]); - }, - ai:{ - order:8, - threaten:1.5, - result:{ - target:-1, - player:0.5 - } - } }, - lshengong:{ - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target.hasCard(function(card){ + guifu: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.countCards("e") > 0; + }, + content: function () { + "step 0"; + player.discardPlayerCard(target, "e", true); + "step 1"; + game.asyncDraw([player, target]); + }, + ai: { + order: 8, + threaten: 1.5, + result: { + target: -1, + player: 0.5, + }, + }, + }, + lshengong: { + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target.hasCard(function (card) { return !get.info(card).unique; - },'e'); + }, "e"); }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - filterCard:function(card){ - var info=lib.card[card.name]; - if(!info) return false; - return !info.image&&!info.fullimage; + filterCard: function (card) { + var info = lib.card[card.name]; + if (!info) return false; + return !info.image && !info.fullimage; }, - discard:false, - lose:false, - content:function(){ - 'step 0' - var next=player.choosePlayerCard(target,'e',true); - next.ai=get.buttonValue; - next.filterButton=function(button){ + discard: false, + lose: false, + content: function () { + "step 0"; + var next = player.choosePlayerCard(target, "e", true); + next.ai = get.buttonValue; + next.filterButton = function (button) { return !get.info(button.link).unique; - } - 'step 1' - if(result.links[0]){ - cards[0].init([result.links[0].suit,result.links[0].number,result.links[0].name,result.links[0].nature]); - event.card=cards[0]; - player.chooseTarget('选择一个角色装备'+get.translation(result.links),function(card,player,target){ - return !target.isMin(); - }).ai=function(target){ - if(!target.countCards('e',{subtype:get.subtype(event.card)})){ - return get.attitude(player,target); + }; + "step 1"; + if (result.links[0]) { + cards[0].init([ + result.links[0].suit, + result.links[0].number, + result.links[0].name, + result.links[0].nature, + ]); + event.card = cards[0]; + player.chooseTarget( + "选择一个角色装备" + get.translation(result.links), + function (card, player, target) { + return !target.isMin(); + } + ).ai = function (target) { + if (!target.countCards("e", { subtype: get.subtype(event.card) })) { + return get.attitude(player, target); } return 0; - } - } - else{ + }; + } else { event.finish(); } - 'step 2' - if(result.targets&&result.targets[0]&&event.card){ - player.$give(event.card,result.targets[0]); + "step 2"; + if (result.targets && result.targets[0] && event.card) { + player.$give(event.card, result.targets[0]); game.delay(); - event.toequip=result.targets[0]; - } - else{ + event.toequip = result.targets[0]; + } else { event.finish(); } - 'step 3' - if(event.toequip){ + "step 3"; + if (event.toequip) { event.toequip.equip(event.card); } }, - ai:{ - order:9, - threaten:1.5, - result:{ - player:function(player){ - if(player.countCards('e')<3) return 1; + ai: { + order: 9, + threaten: 1.5, + result: { + player: function (player) { + if (player.countCards("e") < 3) return 1; return 0; - } - } - } - } + }, + }, + }, + }, }, - translate:{ - yxs_guanyu:'关羽', - yxs_wuzetian:'武则天', - yxs_caocao:'曹操', - yxs_mozi:'墨子', - yxs_bole:'伯乐', - yxs_aijiyanhou:'埃及艳后', - yxs_diaochan:'貂蝉', - yxs_yangyuhuan:'杨玉环', - yxs_baosi:'褒姒', - yxs_napolun:'拿破仑', - yxs_kaisa:'凯撒', - yxs_zhuyuanzhang:'朱元璋', - yxs_jinke:'荆轲', - yxs_libai:'李白', - yxs_luban:'鲁班', - yxs_lvzhi:'吕雉', - yxs_goujian:'勾践', - yxs_lishimin:'李世民', - yxs_huamulan:'花木兰', - yxs_luobinhan:'罗宾汉', - yxs_chengjisihan:'成吉思汗', - yxs_mingchenghuanghou:'明成皇后', - yxs_wangzhaojun:'王昭君', - yxs_luocheng:'罗成', - yxs_direnjie:'狄仁杰', - yxs_sunwu:'孙武', - yxs_chengyaojin:'程咬金', - yxs_yujix:'虞姬', - yxs_xiangyu:'项羽', - yxs_yingzheng:'嬴政', - yxs_yuefei:'岳飞', - yxs_fuermosi:'福尔摩斯', - yxs_guiguzi:'鬼谷子', - yxs_xiaoqiao:'小乔', - yxs_luzhishen:'鲁智深', - yxs_handingdun:'汉丁顿伯爵', - yxs_zhaoyong:'赵雍', - yxs_yangguang:'杨广', - yxs_tangbohu:'唐伯虎', - yxs_zhangsanfeng:'张三丰', - yxs_nandinggeer:'南丁格尔', - yxs_weizhongxian:'魏忠贤', - yxs_lanlinwang:'兰陵王', - yxs_meixi:'妹喜', - yxs_qinqiong:"秦琼", + translate: { + yxs_guanyu: "关羽", + yxs_wuzetian: "武则天", + yxs_caocao: "曹操", + yxs_mozi: "墨子", + yxs_bole: "伯乐", + yxs_aijiyanhou: "埃及艳后", + yxs_diaochan: "貂蝉", + yxs_yangyuhuan: "杨玉环", + yxs_baosi: "褒姒", + yxs_napolun: "拿破仑", + yxs_kaisa: "凯撒", + yxs_zhuyuanzhang: "朱元璋", + yxs_jinke: "荆轲", + yxs_libai: "李白", + yxs_luban: "鲁班", + yxs_lvzhi: "吕雉", + yxs_goujian: "勾践", + yxs_lishimin: "李世民", + yxs_huamulan: "花木兰", + yxs_luobinhan: "罗宾汉", + yxs_chengjisihan: "成吉思汗", + yxs_mingchenghuanghou: "明成皇后", + yxs_wangzhaojun: "王昭君", + yxs_luocheng: "罗成", + yxs_direnjie: "狄仁杰", + yxs_sunwu: "孙武", + yxs_chengyaojin: "程咬金", + yxs_yujix: "虞姬", + yxs_xiangyu: "项羽", + yxs_yingzheng: "嬴政", + yxs_yuefei: "岳飞", + yxs_fuermosi: "福尔摩斯", + yxs_guiguzi: "鬼谷子", + yxs_xiaoqiao: "小乔", + yxs_luzhishen: "鲁智深", + yxs_handingdun: "汉丁顿伯爵", + yxs_zhaoyong: "赵雍", + yxs_yangguang: "杨广", + yxs_tangbohu: "唐伯虎", + yxs_zhangsanfeng: "张三丰", + yxs_nandinggeer: "南丁格尔", + yxs_weizhongxian: "魏忠贤", + yxs_lanlinwang: "兰陵王", + yxs_meixi: "妹喜", + yxs_qinqiong: "秦琼", - yxs_fanji:"反击", - yxs_fanji2:"反击", - yxs_fanji_info:"当你受到【杀】或【决斗】造成的伤害后,你可以对伤害来源使用一张【杀】。若此【杀】为红色,其不可闪避。", - yxs_menshen:"门神", - yxs_menshen2:"门神", - yxs_menshen3:"门神", - yxs_menshen_info:"回合结束阶段,你可选择一名其他角色,若如此做,直到你的下回合开始,所有角色对该角色使用的【杀】或【决斗】均视为对你使用。", - zhuxin:'诛心', - zhuxin_info:'出牌阶段限一次,你可以与一名其他角色拼点,若你赢,你对其造成1点伤害。', - wlianhuan:'连环', - wlianhuan_info:'你使用【杀】造成伤害时,可以弃置一张装备区内的牌并令伤害+1。', - liebo:'裂帛', - liebo_info:'出牌阶段限一次,你可以将你的手牌与一名其他角色交换(手牌数之差不能多于1)。', - yaoji:'妖姬', - yaoji_info:'每当你受到一次伤害,你可以将一张【乐不思蜀】置入伤害来源的判定区。', - guimian:'鬼面', - guimian_info:'锁定技,每当你在出牌阶段使用【杀】造成伤害,本阶段内出【杀】次数上限+1。', - lyuxue:'浴血', - lyuxue2:'浴血', - lyuxue_info:'锁定技,每当你造成一次伤害,若目标没有浴血标记,你令其获得一个浴血标记;当一名角色失去浴血标记时,其失去1点体力;准备阶段,若场上浴血标记的数量不少于存活角色数的一半(向下取整),你清空浴血标记;当你即将死亡时,你清空浴血标记。', - huli:'护理', - huli_info:'出牌阶段,你可以将一张红桃手牌当作【桃】对距离1以内的角色使用。', - yixin:'医心', - yixin_info:'限定技,你可以弃置两张牌,然后令一名已受伤角色回复X点体力并摸4-X张牌(X为该角色已损失的体力值且不超过4)。', - xianqu:'先驱', - xianqu_info:'锁定技,你不能成为点数小于8的杀的目标。', - zbudao:'布道', - zbudao_info:'摸牌阶段,你可以额外摸一张牌,然后将摸到的牌中的一张交给一名其他角色。', - taiji:'太极', - taiji_info:'每当你使用或打出一张【闪】,你可以使用一张【杀】。', - luobi:'落笔', - luobi_info:'结束阶段,可以摸数量等同于已损失体力值的牌,并以任意方式分配给任意角色。', - fengliu:'风流', - fengliu_info:'锁定技,摸牌阶段,你额外摸X张牌,X为存活女性角色数且不超过2。', - shiqin:'弑亲', - shiqin_info:'锁定技,其他群势力角色濒死时,你令其立即死亡。', - yjujian:'拒谏', - yjujian_info:'出牌阶段限一次,你可以交给一名其他角色一张牌,该角色的锦囊牌不能指定你为目标直到你的下一回合开始。', - yaoyi:'徭役', - yaoyi_info:'每当你受到一次伤害,你可以令至多2名非群势力角色交给你一张手牌。', - zyhufu:'胡服', - zyhufu_info:'锁定技,当你的装备区内没有防具牌时,你摸牌阶段额外摸一张牌;当你装备区内有防具牌时,你的手牌上限+5。', - hanbei:'捍北', - hanbei_info:'锁定技,你的装备区有马时,你的【杀】不可闪避。', - kuangchan:'狂禅', - kuangchan_info:'锁定技,你做主公时,不增加体力上限。', - yxsdili:'底力', + yxs_fanji: "反击", + yxs_fanji2: "反击", + yxs_fanji_info: + "当你受到【杀】或【决斗】造成的伤害后,你可以对伤害来源使用一张【杀】。若此【杀】为红色,其不可闪避。", + yxs_menshen: "门神", + yxs_menshen2: "门神", + yxs_menshen3: "门神", + yxs_menshen_info: + "回合结束阶段,你可选择一名其他角色,若如此做,直到你的下回合开始,所有角色对该角色使用的【杀】或【决斗】均视为对你使用。", + zhuxin: "诛心", + zhuxin_info: "出牌阶段限一次,你可以与一名其他角色拼点,若你赢,你对其造成1点伤害。", + wlianhuan: "连环", + wlianhuan_info: "你使用【杀】造成伤害时,可以弃置一张装备区内的牌并令伤害+1。", + liebo: "裂帛", + liebo_info: "出牌阶段限一次,你可以将你的手牌与一名其他角色交换(手牌数之差不能多于1)。", + yaoji: "妖姬", + yaoji_info: "每当你受到一次伤害,你可以将一张【乐不思蜀】置入伤害来源的判定区。", + guimian: "鬼面", + guimian_info: "锁定技,每当你在出牌阶段使用【杀】造成伤害,本阶段内出【杀】次数上限+1。", + lyuxue: "浴血", + lyuxue2: "浴血", + lyuxue_info: + "锁定技,每当你造成一次伤害,若目标没有浴血标记,你令其获得一个浴血标记;当一名角色失去浴血标记时,其失去1点体力;准备阶段,若场上浴血标记的数量不少于存活角色数的一半(向下取整),你清空浴血标记;当你即将死亡时,你清空浴血标记。", + huli: "护理", + huli_info: "出牌阶段,你可以将一张红桃手牌当作【桃】对距离1以内的角色使用。", + yixin: "医心", + yixin_info: + "限定技,你可以弃置两张牌,然后令一名已受伤角色回复X点体力并摸4-X张牌(X为该角色已损失的体力值且不超过4)。", + xianqu: "先驱", + xianqu_info: "锁定技,你不能成为点数小于8的杀的目标。", + zbudao: "布道", + zbudao_info: "摸牌阶段,你可以额外摸一张牌,然后将摸到的牌中的一张交给一名其他角色。", + taiji: "太极", + taiji_info: "每当你使用或打出一张【闪】,你可以使用一张【杀】。", + luobi: "落笔", + luobi_info: "结束阶段,可以摸数量等同于已损失体力值的牌,并以任意方式分配给任意角色。", + fengliu: "风流", + fengliu_info: "锁定技,摸牌阶段,你额外摸X张牌,X为存活女性角色数且不超过2。", + shiqin: "弑亲", + shiqin_info: "锁定技,其他群势力角色濒死时,你令其立即死亡。", + yjujian: "拒谏", + yjujian_info: + "出牌阶段限一次,你可以交给一名其他角色一张牌,该角色的锦囊牌不能指定你为目标直到你的下一回合开始。", + yaoyi: "徭役", + yaoyi_info: "每当你受到一次伤害,你可以令至多2名非群势力角色交给你一张手牌。", + zyhufu: "胡服", + zyhufu_info: + "锁定技,当你的装备区内没有防具牌时,你摸牌阶段额外摸一张牌;当你装备区内有防具牌时,你的手牌上限+5。", + hanbei: "捍北", + hanbei_info: "锁定技,你的装备区有马时,你的【杀】不可闪避。", + kuangchan: "狂禅", + kuangchan_info: "锁定技,你做主公时,不增加体力上限。", + yxsdili: "底力", // yxsdili_info:'锁定技,摸牌阶段,你额外摸X张牌,X为你已损失的体力值。', - yxsdili_info:'锁定技,摸牌阶段,你额外摸X张牌,X为你已损失的体力值的一半,向上取整且最多为2。', - chujia:'初嫁', - chujia_info:'出牌阶段限一次,你可以弃置两张相同颜色的手牌,指定任意一名角色摸X张牌。(X为该角色已损失的体力值)', - zhijie:'知节', - zhijie_info:'出牌阶段限一次,你的红桃手牌可以当做【无中生有】使用。', - baihe:'捭阖', - baihe_info:'出牌阶段限一次,你可以弃置一张牌,选择以下1项执行:(1)横置1名未横置角色,该角色摸一张牌;(2)重置一名已横置角色,该角色弃置一张手牌。', - yinyang:'阴阳', - yinyang_info:'出牌阶段限一次,你可以弃置两张手牌并选择3名角色,分别横置或重置这些角色。', - xiushen:'修身', + yxsdili_info: "锁定技,摸牌阶段,你额外摸X张牌,X为你已损失的体力值的一半,向上取整且最多为2。", + chujia: "初嫁", + chujia_info: + "出牌阶段限一次,你可以弃置两张相同颜色的手牌,指定任意一名角色摸X张牌。(X为该角色已损失的体力值)", + zhijie: "知节", + zhijie_info: "出牌阶段限一次,你的红桃手牌可以当做【无中生有】使用。", + baihe: "捭阖", + baihe_info: + "出牌阶段限一次,你可以弃置一张牌,选择以下1项执行:(1)横置1名未横置角色,该角色摸一张牌;(2)重置一名已横置角色,该角色弃置一张手牌。", + yinyang: "阴阳", + yinyang_info: "出牌阶段限一次,你可以弃置两张手牌并选择3名角色,分别横置或重置这些角色。", + xiushen: "修身", // xiushen_info:'锁定技,结束阶段,若场上有横置角色,你摸两张牌。', - xiushen_info:'锁定技,出牌阶段结束时,若场上有横置角色,你摸两张牌。', - yanyi:'演绎', - yanyi_info:'出牌阶段限一次,你可以弃置一张黑色牌,指定1名角色和1种花色,若被指定角色的手牌中含有此花色,则受到1点伤害。', - jiean:'结案', - jiean_info:'每当【演绎】造成伤害时,你可以摸X张牌,并以任意数量分配给任意角色(X为被【演绎】造成伤害角色的已损失体力值)。', - wumu:'武穆', - wumu_info:'锁定技,你的黑色【杀】无视距离,红色【杀】不计入回合内的出杀限制。', - ysheshen:'舍身', - ysheshen_info:'每当你受到1点伤害,可以观看牌堆顶的两张牌,并将其交给任意1~2名角色。', - sanbanfu:'三板斧', - sanbanfu_info:'当你对其他角色使用【杀】时,你可以使此【杀】有如下效果:若对方没有出【闪】,其受到2点伤害;若对方打出了一张【闪】,你与其各受到1点伤害;若对方打出了两张【闪】,你受到1点伤害。', - bingsheng:'兵圣', - bingsheng_info:'出牌阶段限一次,你可以弃置两张花色不同的手牌,指定一名其他角色使其体力值与你相同(体力最多变化2点)。', - taolue:'韬略', - taolue_info:'锁定技,你的手牌上限+1。', - shentan:'神探', - shentan_info:'出牌阶段限一次,你可以弃置一张牌,获得距离2以内的一名角色的手牌,并可以将其交给任意一名角色。', - hanqiang:'寒枪', - hanqiang_info:'锁定技,当你没装备武器时,攻击范围+1。', - biaoqi:'骠骑', - biaoqi_info:'锁定技,当你出【杀】指定目标后,若你的攻击范围大于目标体力值,则此【杀】不可闪避;若你的攻击范围小于目标体力值,你摸一张牌。', - wluoyan:'落雁', - wluoyan_info:'锁定技,你防止即将受到的伤害,改为失去1点体力。', - heqin:'和亲', - heqin2:'和亲', - heqin3:'和亲', - heqin_info:'限定技,你可以与场上一名男性角色形成【和亲】状态,你与该男性角色于摸牌阶段摸牌数+1。你或者男性角色阵亡时,【和亲】状态消失。', - chajue:'察觉', - chajue2:'察觉', - chajue_info:'锁定技,你的回合外,你每受到一次伤害,任何【杀】或普通锦囊牌均对你无效,直到你的回合开始。', - tiewan:'铁腕', - tiewan_info:'每当其他角色使用延时类锦囊牌时,你可以立即将一张红色牌当作【乐不思蜀】使用。', - qianglue:'强掠', - qianglue_info:'每当你的【杀】被闪避时,你可以进行一次判定,若结果为黑色,你可以获得对方的一张牌。', - xiadao:'侠盗', - xiadao_info:'每当你造成一次伤害,你可以令一名手牌数不少于受伤害角色的另一名角色获得其一张手牌。', - jimin:'机敏', - jimin_info:'当你的装备区内没有牌时,你可以将一张手牌当作【闪】使用或打出。', - sheshu:'射术', - sheshu_info:'锁定技,你的【杀】无视距离;体力值不小于3的角色不能闪避你的【杀】。', - tongyu:'统御', - tongyu_info:'出牌阶段,你可以弃置一张牌,并转变为罗宾汉(每回合只能转变一次)。', - lguiyin:'归隐', - lguiyin_info:'出牌阶段,若你本回合内未造成伤害,你可以摸一张牌,并转变为汉丁顿伯爵(每回合只能转变一次)。', - lzhangyi:'仗义', - lzhangyi_info:'你可以将你弃置的卡牌交给一名其他角色。', - yizhuang:'易装', - yizhuang2:'易装', - yizhuang_info:'准备阶段,你可以弃置一张牌并选择一名男性角色,获得其所有技能,直到你首次受到伤害。', - kongju:'控局', - kongju_info:'锁定技,你的手牌上限为你的体力上限;当你的手牌数小于体力上限时,你不能成为过河拆桥或顺手牵羊的目标;当你的手牌数大于体力上限时,你不能成为乐不思蜀的目标。', - tuqiang:'图强', - tuqiang_info:'每当你使用或打出一张【闪】,你可以摸一张牌。', - zhensha:'鸩杀', - zhensha_info:'当场上有角色进入濒死状态时,你可以弃置一张【酒】或两张黑色手牌,则该角色立即死亡。', - xumou:'蓄谋', - xumou_info:'结束阶段,你可以将武将牌翻面并摸三张牌。', - guifu:'鬼斧', - guifu_info:'出牌阶段限一次,你可以指定一名角色装备区内的一张牌,将其弃掉,自己和对方同时摸取一张牌。', - lshengong:'神工', - lshengong_info:'出牌阶段限一次,你可以选定场上任意一名角色的装备区的非特殊牌,出自己的一张手牌复制该装备,然后可以选择装备上自己或者别的角色的装备区。', - zhexian:'谪仙', - zhexian_info:'当你于一名其他角色的回合内首次失去牌时,你可以摸一张牌。', - miaobi:'妙笔', - miaobi_info:'出牌阶段限一次,你可以弃置一名其他角色的一张牌,若此牌是基本牌或普通锦囊,你可以将一张手牌当此牌使用;否则你须弃置一张牌。', - cike:'刺客', - cike_info:'你对别的角色出【杀】时可以选择做一次判定:若判定牌为红色花色,则此【杀】不可回避,直接命中;若判定牌为黑色花色,你可以选择弃掉对方一张牌。', - qiangyun:'强运', - qiangyun_info:'每当你失去最后一张手牌,可摸两张牌。', - ducai:'独裁', - ducai2:'独裁', - ducai3:'独裁', - ducai_info:'出牌阶段限一次,你可以弃置一张牌,则本轮内除你外的角色不能使用或打出与该手牌花色相同的手牌。', - tongling:'统领', - tongling_info:'锁定技,每当一名友方角色造成一次伤害,你获得1个统领标记(标记上限为3)。', - fanpu:'反扑', - fanpu_info:'出牌阶段限一次,你可以移去3枚统领标记并视为对攻击范围内的至多3名角色使用一张【杀】。', - fenghuo:'烽火', - fenghuo_info:'你可以将一张装备区内的牌当作【南蛮入侵】使用。', - yxsweiyi:'威仪', - yxsweiyi_info:'每当你受到一次伤害,可以令伤害来源弃置两张牌。', - xieling:'挟令', - xieling_info:'出牌阶段,弃掉两张手牌,将任意一名角色装备区或判定区的牌移动到另一名角色对应的区域。', - baye:'霸业', - baye_info:'出牌阶段,你可以将一张牌当做本回合内前一张使用的牌来使用。每回合限用一次。', - nvquan:'女权', - nvquan1:'女权', - nvquan2:'女权', - nvquan_info:'你对男性角色使用【杀】或【决斗】时,对方需连续打出两张【闪】或【杀】响应;你不能成为男性角色的决斗目标。', - qiandu:'迁都', - qiandu_info:'出牌阶段,你可以弃一张黑色手牌,和一名存活的玩家与其交换位置。每回合限一次。', - budao:'补刀', - budao_info:'你的回合外,你的攻击范围的一名角色受到【杀】的伤害时,你可以对其使用一张【杀】,只要你的【杀】对目标角色造成了伤害,你就可以继续对其使用【杀】。', - feigong:'非攻', - feigong_info:'其他角色使用【杀】时,若你不是【杀】的目标,可以弃置一张【杀】取消之。', - jianai:'兼爱', - jianai_info:'每当你回复1点体力,可以令所有其他角色回复1点体力。', - bolehuiyan:'慧眼', - bolehuiyan_info:'当一名有手牌的其他角色成为来源不为你的杀的目标时,你可以预言此杀能否命中,若预言正确,你摸一张牌,否则你须弃置一张牌。每回合限发动一次。', - xiangma:'相马', - xiangma_info:'锁定技,只要你的体力值大于2点,你的进攻距离+1;只要你的体力值为2点或更低,你的防御距离+1。', - seyou:'色诱', - seyou_info:'限定技,出牌阶段,你可以指定任意1名角色,其他所有男性角色需选择1项执行:(1)对你指定的角色出【杀】;(2)令你获得其一张牌。', - sheshi:'蛇噬', - sheshi_info:'每受到1次伤害,可以指定1种花色,依次展示牌堆顶的牌,直到出现指定花色的牌为止,你获得与指定花色不同花色的所有牌(最多展示四张牌)。', + xiushen_info: "锁定技,出牌阶段结束时,若场上有横置角色,你摸两张牌。", + yanyi: "演绎", + yanyi_info: + "出牌阶段限一次,你可以弃置一张黑色牌,指定1名角色和1种花色,若被指定角色的手牌中含有此花色,则受到1点伤害。", + jiean: "结案", + jiean_info: + "每当【演绎】造成伤害时,你可以摸X张牌,并以任意数量分配给任意角色(X为被【演绎】造成伤害角色的已损失体力值)。", + wumu: "武穆", + wumu_info: "锁定技,你的黑色【杀】无视距离,红色【杀】不计入回合内的出杀限制。", + ysheshen: "舍身", + ysheshen_info: "每当你受到1点伤害,可以观看牌堆顶的两张牌,并将其交给任意1~2名角色。", + sanbanfu: "三板斧", + sanbanfu_info: + "当你对其他角色使用【杀】时,你可以使此【杀】有如下效果:若对方没有出【闪】,其受到2点伤害;若对方打出了一张【闪】,你与其各受到1点伤害;若对方打出了两张【闪】,你受到1点伤害。", + bingsheng: "兵圣", + bingsheng_info: + "出牌阶段限一次,你可以弃置两张花色不同的手牌,指定一名其他角色使其体力值与你相同(体力最多变化2点)。", + taolue: "韬略", + taolue_info: "锁定技,你的手牌上限+1。", + shentan: "神探", + shentan_info: + "出牌阶段限一次,你可以弃置一张牌,获得距离2以内的一名角色的手牌,并可以将其交给任意一名角色。", + hanqiang: "寒枪", + hanqiang_info: "锁定技,当你没装备武器时,攻击范围+1。", + biaoqi: "骠骑", + biaoqi_info: + "锁定技,当你出【杀】指定目标后,若你的攻击范围大于目标体力值,则此【杀】不可闪避;若你的攻击范围小于目标体力值,你摸一张牌。", + wluoyan: "落雁", + wluoyan_info: "锁定技,你防止即将受到的伤害,改为失去1点体力。", + heqin: "和亲", + heqin2: "和亲", + heqin3: "和亲", + heqin_info: + "限定技,你可以与场上一名男性角色形成【和亲】状态,你与该男性角色于摸牌阶段摸牌数+1。你或者男性角色阵亡时,【和亲】状态消失。", + chajue: "察觉", + chajue2: "察觉", + chajue_info: + "锁定技,你的回合外,你每受到一次伤害,任何【杀】或普通锦囊牌均对你无效,直到你的回合开始。", + tiewan: "铁腕", + tiewan_info: "每当其他角色使用延时类锦囊牌时,你可以立即将一张红色牌当作【乐不思蜀】使用。", + qianglue: "强掠", + qianglue_info: + "每当你的【杀】被闪避时,你可以进行一次判定,若结果为黑色,你可以获得对方的一张牌。", + xiadao: "侠盗", + xiadao_info: "每当你造成一次伤害,你可以令一名手牌数不少于受伤害角色的另一名角色获得其一张手牌。", + jimin: "机敏", + jimin_info: "当你的装备区内没有牌时,你可以将一张手牌当作【闪】使用或打出。", + sheshu: "射术", + sheshu_info: "锁定技,你的【杀】无视距离;体力值不小于3的角色不能闪避你的【杀】。", + tongyu: "统御", + tongyu_info: "出牌阶段,你可以弃置一张牌,并转变为罗宾汉(每回合只能转变一次)。", + lguiyin: "归隐", + lguiyin_info: + "出牌阶段,若你本回合内未造成伤害,你可以摸一张牌,并转变为汉丁顿伯爵(每回合只能转变一次)。", + lzhangyi: "仗义", + lzhangyi_info: "你可以将你弃置的卡牌交给一名其他角色。", + yizhuang: "易装", + yizhuang2: "易装", + yizhuang_info: + "准备阶段,你可以弃置一张牌并选择一名男性角色,获得其所有技能,直到你首次受到伤害。", + kongju: "控局", + kongju_info: + "锁定技,你的手牌上限为你的体力上限;当你的手牌数小于体力上限时,你不能成为过河拆桥或顺手牵羊的目标;当你的手牌数大于体力上限时,你不能成为乐不思蜀的目标。", + tuqiang: "图强", + tuqiang_info: "每当你使用或打出一张【闪】,你可以摸一张牌。", + zhensha: "鸩杀", + zhensha_info: + "当场上有角色进入濒死状态时,你可以弃置一张【酒】或两张黑色手牌,则该角色立即死亡。", + xumou: "蓄谋", + xumou_info: "结束阶段,你可以将武将牌翻面并摸三张牌。", + guifu: "鬼斧", + guifu_info: + "出牌阶段限一次,你可以指定一名角色装备区内的一张牌,将其弃掉,自己和对方同时摸取一张牌。", + lshengong: "神工", + lshengong_info: + "出牌阶段限一次,你可以选定场上任意一名角色的装备区的非特殊牌,出自己的一张手牌复制该装备,然后可以选择装备上自己或者别的角色的装备区。", + zhexian: "谪仙", + zhexian_info: "当你于一名其他角色的回合内首次失去牌时,你可以摸一张牌。", + miaobi: "妙笔", + miaobi_info: + "出牌阶段限一次,你可以弃置一名其他角色的一张牌,若此牌是基本牌或普通锦囊,你可以将一张手牌当此牌使用;否则你须弃置一张牌。", + cike: "刺客", + cike_info: + "你对别的角色出【杀】时可以选择做一次判定:若判定牌为红色花色,则此【杀】不可回避,直接命中;若判定牌为黑色花色,你可以选择弃掉对方一张牌。", + qiangyun: "强运", + qiangyun_info: "每当你失去最后一张手牌,可摸两张牌。", + ducai: "独裁", + ducai2: "独裁", + ducai3: "独裁", + ducai_info: + "出牌阶段限一次,你可以弃置一张牌,则本轮内除你外的角色不能使用或打出与该手牌花色相同的手牌。", + tongling: "统领", + tongling_info: "锁定技,每当一名友方角色造成一次伤害,你获得1个统领标记(标记上限为3)。", + fanpu: "反扑", + fanpu_info: + "出牌阶段限一次,你可以移去3枚统领标记并视为对攻击范围内的至多3名角色使用一张【杀】。", + fenghuo: "烽火", + fenghuo_info: "你可以将一张装备区内的牌当作【南蛮入侵】使用。", + yxsweiyi: "威仪", + yxsweiyi_info: "每当你受到一次伤害,可以令伤害来源弃置两张牌。", + xieling: "挟令", + xieling_info: + "出牌阶段,弃掉两张手牌,将任意一名角色装备区或判定区的牌移动到另一名角色对应的区域。", + baye: "霸业", + baye_info: "出牌阶段,你可以将一张牌当做本回合内前一张使用的牌来使用。每回合限用一次。", + nvquan: "女权", + nvquan1: "女权", + nvquan2: "女权", + nvquan_info: + "你对男性角色使用【杀】或【决斗】时,对方需连续打出两张【闪】或【杀】响应;你不能成为男性角色的决斗目标。", + qiandu: "迁都", + qiandu_info: "出牌阶段,你可以弃一张黑色手牌,和一名存活的玩家与其交换位置。每回合限一次。", + budao: "补刀", + budao_info: + "你的回合外,你的攻击范围的一名角色受到【杀】的伤害时,你可以对其使用一张【杀】,只要你的【杀】对目标角色造成了伤害,你就可以继续对其使用【杀】。", + feigong: "非攻", + feigong_info: "其他角色使用【杀】时,若你不是【杀】的目标,可以弃置一张【杀】取消之。", + jianai: "兼爱", + jianai_info: "每当你回复1点体力,可以令所有其他角色回复1点体力。", + bolehuiyan: "慧眼", + bolehuiyan_info: + "当一名有手牌的其他角色成为来源不为你的杀的目标时,你可以预言此杀能否命中,若预言正确,你摸一张牌,否则你须弃置一张牌。每回合限发动一次。", + xiangma: "相马", + xiangma_info: + "锁定技,只要你的体力值大于2点,你的进攻距离+1;只要你的体力值为2点或更低,你的防御距离+1。", + seyou: "色诱", + seyou_info: + "限定技,出牌阶段,你可以指定任意1名角色,其他所有男性角色需选择1项执行:(1)对你指定的角色出【杀】;(2)令你获得其一张牌。", + sheshi: "蛇噬", + sheshi_info: + "每受到1次伤害,可以指定1种花色,依次展示牌堆顶的牌,直到出现指定花色的牌为止,你获得与指定花色不同花色的所有牌(最多展示四张牌)。", - fengyi:'凤仪', - fengyi_info:'出牌阶段,你可以弃一张手牌,指定任意目标摸两张牌。(每回合限用一次)', - wange:'婉歌', - wange_info:'摸牌时,你可以少摸一张牌,则结束阶段你可以抽取一名其他角色的手牌,至少1张,至多X张(X为你当前的掉血量)。', - nichang:'霓裳', - nichang2:'霓裳', - nichang_info:'摸牌时,你可以选择不摸牌,并在结束阶段展示手牌,每少一种花色摸一张牌。', - fengyan:'丰艳', - fengyan_info:'你可以获得其他男性角色的红色判定牌。', - zhulu:'逐鹿', - zhulu_info:'回合外,当有普通锦囊牌结算完毕后,你可以立即弃掉一张相同花色手牌或装备区的牌,获得这张锦囊牌。', - jieyong:'节用', - jieyong2:'节用', - jieyong_info:'你使用的卡牌结算完成后,你可以弃置一张黑色牌并重新获得之。(每回合限一次)', - shangtong:'尚同', - shangtong_info:'每当你令其他角色恢复1点血量或掉1点血量时,你可以摸一张牌(摸牌上限为4)。', - feiming:'非命', - feiming_info:'其他角色对你造成伤害时,你可以令该角色须选择1项执行:1,将1张红桃花色手牌交给你;2,失去1点血量。', - yxsrenwang:'人望', - yxsrenwang_info:'出牌阶段,你可以弃置两张牌并指定一名手牌数大于你的角色,你摸牌至与该角色手牌数相等,每阶段限一次。', - shiwei:'施威', - shiwei_info:'当其他角色失去最后一张手牌时,你可以将牌堆顶的一张牌背面朝上置于该角色面前,该角色回合,跳过出牌阶段并弃掉这张牌。', - yxswushuang:'无双', - yxswushuang_info:'出牌阶段,你使用【杀】时可同时打出两张【杀】,则该【杀】具有以下效果之一:1,伤害+1;2,额外指定两个目标。', - xiaoyong:'骁勇', - xiaoyong_info:'你可以将黑色手牌当作【杀】来使用。', - yxsqinzheng:'亲征', - yxsqinzheng_info:'出牌阶段,你对其他角色造成伤害时,可以令场上任意角色摸一张牌。', - juma:'拒马', - juma_info:'你与其他角色的距离始终视为1。', + fengyi: "凤仪", + fengyi_info: "出牌阶段,你可以弃一张手牌,指定任意目标摸两张牌。(每回合限用一次)", + wange: "婉歌", + wange_info: + "摸牌时,你可以少摸一张牌,则结束阶段你可以抽取一名其他角色的手牌,至少1张,至多X张(X为你当前的掉血量)。", + nichang: "霓裳", + nichang2: "霓裳", + nichang_info: "摸牌时,你可以选择不摸牌,并在结束阶段展示手牌,每少一种花色摸一张牌。", + fengyan: "丰艳", + fengyan_info: "你可以获得其他男性角色的红色判定牌。", + zhulu: "逐鹿", + zhulu_info: + "回合外,当有普通锦囊牌结算完毕后,你可以立即弃掉一张相同花色手牌或装备区的牌,获得这张锦囊牌。", + jieyong: "节用", + jieyong2: "节用", + jieyong_info: "你使用的卡牌结算完成后,你可以弃置一张黑色牌并重新获得之。(每回合限一次)", + shangtong: "尚同", + shangtong_info: "每当你令其他角色恢复1点血量或掉1点血量时,你可以摸一张牌(摸牌上限为4)。", + feiming: "非命", + feiming_info: + "其他角色对你造成伤害时,你可以令该角色须选择1项执行:1,将1张红桃花色手牌交给你;2,失去1点血量。", + yxsrenwang: "人望", + yxsrenwang_info: + "出牌阶段,你可以弃置两张牌并指定一名手牌数大于你的角色,你摸牌至与该角色手牌数相等,每阶段限一次。", + shiwei: "施威", + shiwei_info: + "当其他角色失去最后一张手牌时,你可以将牌堆顶的一张牌背面朝上置于该角色面前,该角色回合,跳过出牌阶段并弃掉这张牌。", + yxswushuang: "无双", + yxswushuang_info: + "出牌阶段,你使用【杀】时可同时打出两张【杀】,则该【杀】具有以下效果之一:1,伤害+1;2,额外指定两个目标。", + xiaoyong: "骁勇", + xiaoyong_info: "你可以将黑色手牌当作【杀】来使用。", + yxsqinzheng: "亲征", + yxsqinzheng_info: "出牌阶段,你对其他角色造成伤害时,可以令场上任意角色摸一张牌。", + juma: "拒马", + juma_info: "你与其他角色的距离始终视为1。", }, }; }); diff --git a/character/zhuogui.js b/character/zhuogui.js index e9f0cedc5..cd1efcf37 100644 --- a/character/zhuogui.js +++ b/character/zhuogui.js @@ -1,342 +1,343 @@ -import { game } from '../noname.js'; -game.import('character',function(lib,game,ui,get,ai,_status){ - return { - name:'zhuogui', - character:{ - nianshou:['male','shu',4,['nianrui','qixiang']], - mamian:['male','qun',4,['lianyu','guiji']], - niutou:['male','shu',4,['manjia','xiaoshou']], - baiwuchang:['male','qun',3,['qiangzheng','moukui']], - heiwuchang:['male','qun',3,['suoling','xixing']], - }, - skill:{ - qixiang:{ - group:['qixiang1','qixiang2'], - ai:{ - effect:{ - target:function(card,player,target,current){ - if(card.name=='lebu'&&card.name=='bingliang') return 0.8; - } - } - } - }, - qixiang1:{ - trigger:{player:'judge'}, - forced:true, - filter:function(event,player){ - if(event.card){ - if(event.card.viewAs){ - return event.card.viewAs=='lebu'; - } - else{ - return event.card.name=='lebu'; - } - } - }, - content:function(){ - player.addTempSkill('qixiang3','phaseJudgeAfter'); - } - }, - qixiang2:{ - trigger:{player:'judge'}, - forced:true, - filter:function(event,player){ - if(event.card){ - if(event.card.viewAs){ - return event.card.viewAs=='bingliang'; - } - else{ - return event.card.name=='bingliang'; - } - } - }, - content:function(){ - player.addTempSkill('qixiang4','phaseJudgeAfter'); - } - }, - qixiang3:{ - mod:{ - suit:function(card,suit){ - if(suit=='diamond') return 'heart'; - } - } - }, - qixiang4:{ - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'club'; - } - } - }, - nianrui:{ - trigger:{player:['phaseBegin','phaseEnd']}, - content:function(){ - "step 0" - player.judge(function(card){ - return get.color(card)=='red'?1:0; - }); - "step 1" - if(result.bool){ - player.draw(); - } - } - }, - lianyu:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'red'}, - check:function(card){return 6-get.value(card)}, - filterTarget:true, - selectTarget:-1, - line:'fire', - content:function(){ - target.damage('fire'); - }, - ai:{ - result:{ - player:function(card,player,target){ - var eff=0; - for(var i=0;iplayers[1].hp&&players[0]!=player; - }, - check:function(event,player){ - var players=game.players.slice(0); - players.sort(function(a,b){ - return b.hp-a.hp; - }); - return get.damageEffect(players[0],player,player,'fire')>0; - }, - prompt:function(){ - var players=game.players.slice(0); - players.sort(function(a,b){ - return b.hp-a.hp; - }); - return '枭首:是否对'+get.translation(players[0])+'造成1点火焰伤害?'; - }, - content:function(){ - var players=game.players.slice(0); - players.sort(function(a,b){ - return b.hp-a.hp; - }); - if(players[0].hp>players[1].hp&&players[0]!=player){ - players[0].damage('fire'); - player.line(players[0],'fire'); - } - }, - ai:{ - expose:0.2 - } - }, - guiji:{ - trigger:{player:'phaseJudgeBegin'}, - forced:true, - content:function(){ - player.discard(player.getCards('j').randomGet()); - }, - filter:function(event ,player){ - return player.countCards('j')>0; - }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='delay'&&target.countCards('j')==0) return 0.1; - } - } - } - }, - qiangzheng:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - forced:true, - filter:function(event,player){ - for(var i=0;i0; - }).ai=function(target){ - return -get.attitude(player,target); - }; - "step 1" - if(result.targets&&result.targets.length){ - player.logSkill('qiangzheng',result.targets); - player.gain(result.targets[0].getCards('h').randomGet(),result.targets[0]); - result.targets[0].$give(1,player); - game.delay(); - } - }, - ai:{ - threaten:1.7 - } - }, - suoling:{ - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ - if(player.isLinked()) return true; - for(var i=0;i players[1].hp && players[0] != player; + }, + check: function (event, player) { + var players = game.players.slice(0); + players.sort(function (a, b) { + return b.hp - a.hp; + }); + return get.damageEffect(players[0], player, player, "fire") > 0; + }, + prompt: function () { + var players = game.players.slice(0); + players.sort(function (a, b) { + return b.hp - a.hp; + }); + return "枭首:是否对" + get.translation(players[0]) + "造成1点火焰伤害?"; + }, + content: function () { + var players = game.players.slice(0); + players.sort(function (a, b) { + return b.hp - a.hp; + }); + if (players[0].hp > players[1].hp && players[0] != player) { + players[0].damage("fire"); + player.line(players[0], "fire"); + } + }, + ai: { + expose: 0.2, + }, + }, + guiji: { + trigger: { player: "phaseJudgeBegin" }, + forced: true, + content: function () { + player.discard(player.getCards("j").randomGet()); + }, + filter: function (event, player) { + return player.countCards("j") > 0; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "delay" && target.countCards("j") == 0) return 0.1; + }, + }, + }, + }, + qiangzheng: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + forced: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player && game.players[i].countCards("h")) return true; + } + return false; + }, + content: function () { + "step 0"; + player.chooseTarget("获得一名角色的一张手牌", true, function (card, player, target) { + return player != target && target.countCards("h") > 0; + }).ai = function (target) { + return -get.attitude(player, target); + }; + "step 1"; + if (result.targets && result.targets.length) { + player.logSkill("qiangzheng", result.targets); + player.gain(result.targets[0].getCards("h").randomGet(), result.targets[0]); + result.targets[0].$give(1, player); + game.delay(); + } + }, + ai: { + threaten: 1.7, + }, + }, + suoling: { + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { + if (player.isLinked()) return true; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player && !game.players[i].isLinked()) { + return true; + } + } + return false; + }, + content: function () { + "step 0"; + event.targets = game.players.slice(0); + event.targets.remove(player); + event.targets.sort(lib.sort.seat); + if (player.isLinked()) player.link(); + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + if (!target.isLinked()) { + target.link(); + } + event.redo(); + } + }, + }, + xixing: { + enable: "phaseUse", + usable: 1, + filterCard: function (card) { + var type = get.type(card); + for (var i = 0; i < ui.selected.cards.length; i++) { + if (get.type(ui.selected.cards[i]) == type) return false; + } + return true; + }, + complexCard: true, + selectCard: 3, + position: "he", + filterTarget: function (card, player, target) { + return player != target; + }, + check: function (card) { + if (_status.event.player.hp == _status.event.player.maxHp) { + return 5 - get.value(card); + } + return 10 - get.value(card); + }, + content: function () { + "step 0"; + target.damage(); + "step 1"; + player.recover(); + }, + ai: { + order: 9.5, + result: { + target: function (player, target) { + return get.damageEffect(target, player); + }, + }, + expose: 0.2, + }, + }, + }, + translate: { + nianshou: "年兽", + nianrui: "年瑞", + qixiang: "祺祥", + qixiang1: "祺祥", + qixiang2: "祺祥", + nianrui_info: "准备阶段和结束阶段,你可以进行一次判定,若结果为红色则摸一张牌。", + qixiang_info: "乐不思蜀判定时,你的方块判定牌视为红桃;兵粮寸断判定时,你的黑桃判定牌视为草花。", + + mamian: "马面", + lianyu: "炼狱", + lianyu_info: "出牌阶段限一次,你可以弃置一张红色手牌令场上所有角色受到1点火焰伤害。", + + niutou: "牛头", + manjia: "蛮甲", + manjia1: "蛮甲", + manjia2: "蛮甲", + manjia_info: "锁定技,若你的装备区内没有防具牌,则你视为装备了【藤甲】。", + xiaoshou: "枭首", + xiaoshou_info: "结束阶段,若场上体力值最多的角色只有一个,你可以对其造成1点火焰伤害。", + guiji: "诡计", + guiji_info: "锁定技,准备阶段结束时,若你的判定区内有牌,你随机弃置其中一张牌。", + + baiwuchang: "白无常", + qiangzheng: "强征", + qiangzheng_info: "锁定技,结束阶段,你获得一名其他角色的一张手牌。", + zuijiu: "醉酒", + zuijiu_info: "锁定技,你的黑杀造成的伤害+1,造成伤害后须弃置一张手牌。", + + heiwuchang: "黑无常", + suoling: "索令", + suoling_info: "锁定技,结束阶段,你解除横置状态,除你之外的所有角色进入横置状态。", + xixing: "吸星", + xixing_info: + "出牌阶段限一次,你可以弃置三张不同类别的牌,对一名其他角色造成1点伤害,然后回复1点体力。", + }, + }; +}); diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..127cec053 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,39 @@ +import js from "@eslint/js"; +import globals from "globals"; + +export default [ + js.configs.recommended, + { + rules: { + "no-console": 0, + "no-constant-condition": [ + "error", + { + checkLoops: false, + }, + ], + "no-irregular-whitespace": [ + "error", + { + skipStrings: true, + skipTemplates: true, + }, + ], + "no-redeclare": 0, + "no-undef": 0, + "no-unused-vars": 0, + "require-yield": 0, + }, + languageOptions: { + ecmaVersion: 13, + sourceType: "module", + globals: { + ...globals.browser, + ...globals.es2015, + ...globals.node, + ...globals.serviceworker, + ...globals.worker, + }, + }, + }, +]; diff --git a/extension/boss/extension.js b/extension/boss/extension.js index 6dad31016..ae63473b0 100644 --- a/extension/boss/extension.js +++ b/extension/boss/extension.js @@ -1,136 +1,161 @@ -'use strict'; -game.import('play',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../../noname.js"; +game.import("play", function () { return { - name:'boss', - init:function(){ - if(get.mode()=='tafang') return; - var storage=localStorage.getItem('boss_storage_playpackconfig'); - try{ - storage=JSON.parse(storage)||{}; + name: "boss", + init: function () { + if (get.mode() == "tafang") return; + var storage = localStorage.getItem("boss_storage_playpackconfig"); + try { + storage = JSON.parse(storage) || {}; + } catch (e) { + storage = {}; } - catch(e){ - storage={}; - } - if(get.mode()!='boss'){ - lib.characterPack.mode_extension_boss=storage.boss||{}; - for(var i in lib.characterPack.mode_extension_boss){ - lib.characterPack.mode_extension_boss[i][4].push('mode:boss'); - lib.character[i]=lib.characterPack.mode_extension_boss[i]; - if(typeof lib.character[i][2]!='number'&&(typeof lib.character[i][2]!='string'||lib.character[i][2].indexOf('/')==-1)){ - lib.character[i][2]=Infinity; + if (get.mode() != "boss") { + lib.characterPack.mode_extension_boss = storage.boss || {}; + for (var i in lib.characterPack.mode_extension_boss) { + lib.characterPack.mode_extension_boss[i][4].push( + "mode:boss" + ); + lib.character[i] = lib.characterPack.mode_extension_boss[i]; + if ( + typeof lib.character[i][2] != "number" && + (typeof lib.character[i][2] != "string" || + lib.character[i][2].indexOf("/") == -1) + ) { + lib.character[i][2] = Infinity; } - if(!lib.config.boss_enableai_playpackconfig){ + if (!lib.config.boss_enableai_playpackconfig) { lib.config.forbidai.push(i); } } } - var list2=storage.versus||{}; - if(get.mode()!='versus'||get.config('versus_mode')!='jiange'){ - lib.characterPack.mode_extension_jiange=list2; - for(var i in list2){ - lib.characterPack.mode_extension_jiange[i]=list2[i]; - lib.characterPack.mode_extension_jiange[i][4].push('mode:versus'); - lib.character[i]=list2[i]; - if(typeof lib.character[i][2]!='number'){ - lib.character[i][2]=Infinity; + var list2 = storage.versus || {}; + if ( + get.mode() != "versus" || + get.config("versus_mode") != "jiange" + ) { + lib.characterPack.mode_extension_jiange = list2; + for (var i in list2) { + lib.characterPack.mode_extension_jiange[i] = list2[i]; + lib.characterPack.mode_extension_jiange[i][4].push( + "mode:versus" + ); + lib.character[i] = list2[i]; + if (typeof lib.character[i][2] != "number") { + lib.character[i][2] = Infinity; } - if(!lib.config.boss_enableai_playpackconfig){ + if (!lib.config.boss_enableai_playpackconfig) { lib.config.forbidai.push(i); } } - lib.characterIntro.boss_liedixuande=lib.characterIntro.liubei; - lib.characterIntro.boss_gongshenyueying=lib.characterIntro.huangyueying; - lib.characterIntro.boss_tianhoukongming=lib.characterIntro.shen_zhugeliang; - lib.characterIntro.boss_yuhuoshiyuan=lib.characterIntro.pangtong; - lib.characterIntro.boss_qiaokuijunyi=lib.characterIntro.zhanghe; - lib.characterIntro.boss_jiarenzidan=lib.characterIntro.caozhen; - lib.characterIntro.boss_duanyuzhongda=lib.characterIntro.simayi; - lib.characterIntro.boss_juechenmiaocai=lib.characterIntro.xiahouyuan; - } - else if(_status.mode!='jiange'){ - for(var i in list2){ - lib.character[i]=list2[i]; - if(!lib.config.boss_enableai_playpackconfig){ + lib.characterIntro.boss_liedixuande = lib.characterIntro.liubei; + lib.characterIntro.boss_gongshenyueying = + lib.characterIntro.huangyueying; + lib.characterIntro.boss_tianhoukongming = + lib.characterIntro.shen_zhugeliang; + lib.characterIntro.boss_yuhuoshiyuan = + lib.characterIntro.pangtong; + lib.characterIntro.boss_qiaokuijunyi = + lib.characterIntro.zhanghe; + lib.characterIntro.boss_jiarenzidan = + lib.characterIntro.caozhen; + lib.characterIntro.boss_duanyuzhongda = + lib.characterIntro.simayi; + lib.characterIntro.boss_juechenmiaocai = + lib.characterIntro.xiahouyuan; + } else if (_status.mode != "jiange") { + for (var i in list2) { + lib.character[i] = list2[i]; + if (!lib.config.boss_enableai_playpackconfig) { lib.config.forbidai.push(i); } } } - var list=storage.translate||{}; - list.mode_extension_boss_character_config='挑战武将'; - list.mode_extension_jiange_character_config='剑阁武将'; + var list = storage.translate || {}; + list.mode_extension_boss_character_config = "挑战武将"; + list.mode_extension_jiange_character_config = "剑阁武将"; - for(var i in list){ - lib.translate[i]=lib.translate[i]||list[i]; + for (var i in list) { + lib.translate[i] = lib.translate[i] || list[i]; } }, - arenaReady:function(){ - if(get.mode()=='tafang') return; - var storage=localStorage.getItem('boss_storage_playpackconfig'); - try{ - storage=JSON.parse(storage)||{}; + arenaReady: function () { + if (get.mode() == "tafang") return; + var storage = localStorage.getItem("boss_storage_playpackconfig"); + try { + storage = JSON.parse(storage) || {}; + } catch (e) { + storage = {}; } - catch(e){ - storage={}; + if (!storage.translate) { + storage.translate = {}; } - if(!storage.translate){ - storage.translate={}; - } - var loadversus=function(){ - if(get.mode()!='versus'){ - game.loadModeAsync('versus',function(mode){ - for(var i in mode.translate){ - lib.translate[i]=lib.translate[i]||mode.translate[i]; - storage.translate[i]=mode.translate[i]; + var loadversus = function () { + if (get.mode() != "versus") { + game.loadModeAsync("versus", function (mode) { + for (var i in mode.translate) { + lib.translate[i] = + lib.translate[i] || mode.translate[i]; + storage.translate[i] = mode.translate[i]; } - for(var i in mode.skill){ - if(lib.skill[i]) console.log(i); - if(i!='versus_ladder'){ - lib.skill[i]=mode.skill[i]; + for (var i in mode.skill) { + if (lib.skill[i]) console.log(i); + if (i != "versus_ladder") { + lib.skill[i] = mode.skill[i]; } } - for(var ii in mode.skill){ - if(ii!='versus_ladder'){ + for (var ii in mode.skill) { + if (ii != "versus_ladder") { game.finishSkill(ii); } } - storage.versus={}; - for(var i in mode.jiangeboss){ - if(mode.jiangeboss[i][4].includes('bossallowed')){ - storage.versus[i]=mode.jiangeboss[i]; + storage.versus = {}; + for (var i in mode.jiangeboss) { + if (mode.jiangeboss[i][4].includes("bossallowed")) { + storage.versus[i] = mode.jiangeboss[i]; } } - localStorage.setItem('boss_storage_playpackconfig',JSON.stringify(storage)); + localStorage.setItem( + "boss_storage_playpackconfig", + JSON.stringify(storage) + ); }); - } - else{ - localStorage.setItem('boss_storage_playpackconfig',JSON.stringify(storage)); + } else { + localStorage.setItem( + "boss_storage_playpackconfig", + JSON.stringify(storage) + ); } }; - if(get.mode()!='boss'){ - game.loadModeAsync('boss',function(mode){ - for(var i in mode.translate){ - lib.translate[i]=lib.translate[i]||mode.translate[i]; - storage.translate[i]=mode.translate[i]; + if (get.mode() != "boss") { + game.loadModeAsync("boss", function (mode) { + for (var i in mode.translate) { + lib.translate[i] = + lib.translate[i] || mode.translate[i]; + storage.translate[i] = mode.translate[i]; } - for(var i in mode.skill){ - if(lib.skill[i]) console.log(i); - lib.skill[i]=mode.skill[i]; + for (var i in mode.skill) { + if (lib.skill[i]) console.log(i); + lib.skill[i] = mode.skill[i]; } - for(var ii in mode.skill){ - if(ii!='versus_ladder'){ + for (var ii in mode.skill) { + if (ii != "versus_ladder") { game.finishSkill(ii); } } - storage.boss={}; - for(var i in mode.characterPack.mode_boss){ - if(mode.characterPack.mode_boss[i][4].includes('bossallowed')){ - storage.boss[i]=mode.characterPack.mode_boss[i]; + storage.boss = {}; + for (var i in mode.characterPack.mode_boss) { + if ( + mode.characterPack.mode_boss[i][4].includes( + "bossallowed" + ) + ) { + storage.boss[i] = mode.characterPack.mode_boss[i]; } } loadversus(); }); - } - else{ + } else { loadversus(); } }, diff --git a/extension/cardpile/extension.js b/extension/cardpile/extension.js index 9590a4988..f8606250c 100644 --- a/extension/cardpile/extension.js +++ b/extension/cardpile/extension.js @@ -1,92 +1,102 @@ -'use strict'; -game.import('play',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../../noname.js"; +game.import("play", function () { return { - name:'cardpile', - arenaReady:function(){ - var data={ - total:160, - sha:{ - diamond:6, - club:14, - heart:3, - spade:7, + name: "cardpile", + arenaReady: function () { + var data = { + total: 160, + sha: { + diamond: 6, + club: 14, + heart: 3, + spade: 7, }, - huosha:{ - diamond:2, - heart:3 + huosha: { + diamond: 2, + heart: 3, }, - leisha:{ - spade:5, - club:4 + leisha: { + spade: 5, + club: 4, }, - shan:{ - heart:6, - diamond:18 + shan: { + heart: 6, + diamond: 18, }, - jiu:{ - diamond:1, - spade:2, - club:2 + jiu: { + diamond: 1, + spade: 2, + club: 2, }, - tao:{ - heart:9, - diamond:3, + tao: { + heart: 9, + diamond: 3, }, - wanjian:{ - heart:1, + wanjian: { + heart: 1, }, - nanman:{ - spade:2, - club:1, + nanman: { + spade: 2, + club: 1, }, - guohe:{ - spade:3, - club:2, - heart:1 + guohe: { + spade: 3, + club: 2, + heart: 1, }, - shunshou:{ - spade:3, - diamond:2 + shunshou: { + spade: 3, + diamond: 2, }, - wuxie:{ - heart:2, - diamond:1, - spade:2, - club:2 + wuxie: { + heart: 2, + diamond: 1, + spade: 2, + club: 2, }, - tiesuo:{ - spade:2, - club:4 + tiesuo: { + spade: 2, + club: 4, + }, + }; + var rand = function () { + return Math.ceil(Math.random() * 13); + }; + var getn = function (i, j) { + return Math.round( + data[i][j] * + parseFloat( + lib.config["cardpile_" + i + "_playpackconfig"] + ) + ); + }; + var num = 0; + for (var i in data) { + for (var j in data[i]) { + num += getn(i, j); } } - var rand=function(){ - return Math.ceil(Math.random()*13); - }; - var getn=function(i,j){ - return Math.round(data[i][j]*parseFloat(lib.config['cardpile_'+i+'_playpackconfig'])); - }; - var num=0; - for(var i in data){ - for(var j in data[i]){ - num+=getn(i,j); - } - } - var dn=num*(lib.card.list.length-data.total)/(data.total-num); - if(dn>1000) dn=1000; - if(dn>0){ - var p=0; - for(var i in data){ - for(var j in data[i]){ - var n=Math.round(dn*getn(i,j)/num); - while(n--){ - if(i=='huosha'){ - lib.card.list.push([j,rand(),'sha','fire']); - } - else if(i=='leisha'){ - lib.card.list.push([j,rand(),'sha','thunder']); - } - else{ - lib.card.list.push([j,rand(),i]); + var dn = + (num * (lib.card.list.length - data.total)) / + (data.total - num); + if (dn > 1000) dn = 1000; + if (dn > 0) { + var p = 0; + for (var i in data) { + for (var j in data[i]) { + var n = Math.round((dn * getn(i, j)) / num); + while (n--) { + if (i == "huosha") { + lib.card.list.push([j, rand(), "sha", "fire"]); + } else if (i == "leisha") { + lib.card.list.push([ + j, + rand(), + "sha", + "thunder", + ]); + } else { + lib.card.list.push([j, rand(), i]); } } } diff --git a/extension/coin/extension.js b/extension/coin/extension.js index e7d840d01..0e59440fe 100644 --- a/extension/coin/extension.js +++ b/extension/coin/extension.js @@ -1,180 +1,208 @@ -'use strict'; -game.import('play',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../../noname.js"; +game.import("play", function () { return { - name:'coin', - init:function(){ - if(lib.config.mode!='chess'||get.config('chess_mode')!='leader'){ - _status.coin=0; + name: "coin", + init: function () { + if ( + lib.config.mode != "chess" || + get.config("chess_mode") != "leader" + ) { + _status.coin = 0; } }, - arenaReady:function(){ - if(_status.video||_status.connectMode) return; - if(lib.config.mode!='chess'||get.config('chess_mode')!='leader'){ + arenaReady: function () { + if (_status.video || _status.connectMode) return; + if ( + lib.config.mode != "chess" || + get.config("chess_mode") != "leader" + ) { var str; - if(lib.config.coin_display_playpackconfig=='text'){ - str=''+lib.config.coin+'' + if (lib.config.coin_display_playpackconfig == "text") { + str = "" + lib.config.coin + ""; + } else { + str = + '' + + lib.config.coin + + ""; } - else{ - str=''+lib.config.coin+''; + if (lib.config.coin_canvas_playpackconfig) { + ui.window.classList.add("canvas_top"); } - if(lib.config.coin_canvas_playpackconfig){ - ui.window.classList.add('canvas_top'); - } - ui.coin=ui.create.system(str,null,true); - if(lib.config.snowFall){ - game.haveFun.list.snow.bought=true; - setTimeout(function(){ + ui.coin = ui.create.system(str, null, true); + if (lib.config.snowFall) { + game.haveFun.list.snow.bought = true; + setTimeout(function () { game.haveFun.snow(); - },500); + }, 500); } - lib.setPopped(ui.coin,function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.classList.add('coin_menu') - uiintro.add('商店'); - uiintro.listen(function(e){ - e.stopPropagation(); - }); - var clickBuy=function(){ - if(this.innerHTML=='停止'){ - game.haveFun[this.name+'Stop'](); - } - else if(this.innerHTML=='开始'){ - game.haveFun[this.name](); - } - else if(this.innerHTML.indexOf('金')!=-1){ - if(lib.config.coin>=this.content.cost){ - this.content.bought=true; - game.changeCoin(-this.content.cost); - game.haveFun[this.name](); - if(this.content.onbuy){ - this.content.onbuy.call(this); - } - } - else{ - return; - } - } - ui.click.window(); - }; - for(var i in game.haveFun.list){ - var item=game.haveFun.list[i]; - uiintro.add('
              '+item.name+'
              '); - var buy=uiintro.content.lastChild.lastChild.lastChild; - if(lib.config.coin本局获胜'); - var bet=uiintro.content.lastChild.lastChild.lastChild; - bet.listen(function(){ - if(_status.betWin) return; - _status.betWin=true; - game.changeCoin(-20); - this.innerHTML='已下注'; + lib.setPopped( + ui.coin, + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.classList.add("coin_menu"); + uiintro.add("商店"); + uiintro.listen(function (e) { + e.stopPropagation(); }); - if(_status.betWin){ - bet.innerHTML='已下注'; + var clickBuy = function () { + if (this.innerHTML == "停止") { + game.haveFun[this.name + "Stop"](); + } else if (this.innerHTML == "开始") { + game.haveFun[this.name](); + } else if (this.innerHTML.indexOf("金") != -1) { + if (lib.config.coin >= this.content.cost) { + this.content.bought = true; + game.changeCoin(-this.content.cost); + game.haveFun[this.name](); + if (this.content.onbuy) { + this.content.onbuy.call(this); + } + } else { + return; + } + } + ui.click.window(); + }; + for (var i in game.haveFun.list) { + var item = game.haveFun.list[i]; + uiintro.add( + '
              ' + + item.name + + '
              " + ); + var buy = + uiintro.content.lastChild.lastChild.lastChild; + if (lib.config.coin < item.cost && !item.bought) { + buy.classList.add("disabled"); + } + if (item.bought) { + if (item.running) { + buy.innerHTML = "停止"; + if (item.control) { + var node = item.control(); + if (node) { + buy.parentNode.appendChild( + node, + buy + ); + } + } + } else { + buy.innerHTML = "开始"; + } + } + buy.name = i; + buy.content = item; + buy.listen(clickBuy); } - } - else if(_status.betWin){ - uiintro.add('下注'); - uiintro.add('
              本局获胜
              '); - } - uiintro.classList.add('noleave'); + if (!game.phaseNumber && !game.online) { + uiintro.add("下注"); + uiintro.add( + '
              本局获胜
              ' + ); + var bet = + uiintro.content.lastChild.lastChild.lastChild; + bet.listen(function () { + if (_status.betWin) return; + _status.betWin = true; + game.changeCoin(-20); + this.innerHTML = "已下注"; + }); + if (_status.betWin) { + bet.innerHTML = "已下注"; + } + } else if (_status.betWin) { + uiintro.add("下注"); + uiintro.add( + '
              本局获胜
              ' + ); + } - return uiintro; - },220,400); + uiintro.classList.add("noleave"); + + return uiintro; + }, + 220, + 400 + ); } }, - game:{ - changeCoin:function(num){ - if(typeof num=='number'&&ui.coin){ - game.saveConfig('coin',lib.config.coin+num); + game: { + changeCoin: function (num) { + if (typeof num == "number" && ui.coin) { + game.saveConfig("coin", lib.config.coin + num); var str; - if(lib.config.coin_display_playpackconfig=='text'){ - str=''+lib.config.coin+'' + if (lib.config.coin_display_playpackconfig == "text") { + str = + "" + + lib.config.coin + + ""; + } else { + str = + '' + + lib.config.coin + + ""; } - else{ - str=''+lib.config.coin+''; - } - ui.coin.innerHTML=str; + ui.coin.innerHTML = str; } }, - haveFun:{ - list:{ - firework:{ - name:'烟花', - cost:50, + haveFun: { + list: { + firework: { + name: "烟花", + cost: 50, }, - snow:{ - name:'下雪', - cost:20, - size:'large', - control:function(){ - var size=ui.create.div('.menubutton'); - if(game.haveFun.list.snow.size=='small'){ - size.innerHTML='大雪'; - } - else{ - size.innerHTML='小雪'; + snow: { + name: "下雪", + cost: 20, + size: "large", + control: function () { + var size = ui.create.div(".menubutton"); + if (game.haveFun.list.snow.size == "small") { + size.innerHTML = "大雪"; + } else { + size.innerHTML = "小雪"; } size.listen(game.haveFun.snowSize); return size; - } + }, }, - star:{ - name:'星云', - cost:10 + star: { + name: "星云", + cost: 10, + }, + blink: { + name: "闪烁", + cost: 10, }, - blink:{ - name:'闪烁', - cost:10 - } }, - alwaysSnow:function(){ - game.saveConfig('snowFall',!lib.config.snowFall); + alwaysSnow: function () { + game.saveConfig("snowFall", !lib.config.snowFall); game.reload(); }, - blink:function(){ - if(game.haveFun.list.blink.running) return; - game.haveFun.list.blink.running=true; - if(game.haveFun.blinkLoop){ + blink: function () { + if (game.haveFun.list.blink.running) return; + game.haveFun.list.blink.running = true; + if (game.haveFun.blinkLoop) { game.haveFun.blinkLoop(); - } - else{ + } else { var canvas = document.createElement("canvas"); ui.window.appendChild(canvas); - canvas.classList.add('fun'); - canvas.style.zIndex=20; + canvas.classList.add("fun"); + canvas.style.zIndex = 20; var ctx = canvas.getContext("2d"); //Make the canvas occupy the full page - var W = ui.window.offsetWidth, H = ui.window.offsetHeight; + var W = ui.window.offsetWidth, + H = ui.window.offsetHeight; canvas.width = W; canvas.height = H; - lib.onresize.push(function(){ - var W = ui.window.offsetWidth, H = ui.window.offsetHeight; + lib.onresize.push(function () { + var W = ui.window.offsetWidth, + H = ui.window.offsetHeight; canvas.width = W; canvas.height = H; }); @@ -185,61 +213,56 @@ game.import('play',function(lib,game,ui,get,ai,_status){ //Lets create some particles now var particle_count = 25; - //finally some mouse tracking - ui.window.addEventListener('mousemove', function(e) - { + ui.window.addEventListener("mousemove", function (e) { //since the canvas = full page the position of the mouse //relative to the document will suffice - mouse.x = e.pageX/game.documentZoom; - mouse.y = e.pageY/game.documentZoom; + mouse.x = e.pageX / game.documentZoom; + mouse.y = e.pageY / game.documentZoom; }); - ui.window.addEventListener('touchmove',function(e){ - mouse.x = e.touches[0].clientX/game.documentZoom; - mouse.y = e.touches[0].clientY/game.documentZoom; + ui.window.addEventListener("touchmove", function (e) { + mouse.x = e.touches[0].clientX / game.documentZoom; + mouse.y = e.touches[0].clientY / game.documentZoom; }); - var particle=function() - { + var particle = function () { //speed, life, location, life, colors //speed.x range = -2.5 to 2.5 //speed.y range = -15 to -5 to make it move upwards //lets change the Y speed to make it look like a flame - this.speed = {x: -2.5+Math.random()*5, y: -5+Math.random()*10}; - this.speed.x/=4; - this.speed.y/=4; + this.speed = { + x: -2.5 + Math.random() * 5, + y: -5 + Math.random() * 10, + }; + this.speed.x /= 4; + this.speed.y /= 4; //location = mouse coordinates //Now the flame follows the mouse coordinates - if(mouse.x && mouse.y) - { - this.location = {x: mouse.x, y: mouse.y}; - } - else - { - this.location = {x: W/2, y: H/2}; + if (mouse.x && mouse.y) { + this.location = { x: mouse.x, y: mouse.y }; + } else { + this.location = { x: W / 2, y: H / 2 }; } //radius range = 10-30 - this.radius = 10+Math.random()*20; + this.radius = 10 + Math.random() * 20; //life range = 20-30 - this.radius/=4; - this.life = 20+Math.random()*10; - this.life*=4; + this.radius /= 4; + this.life = 20 + Math.random() * 10; + this.life *= 4; this.remaining_life = this.life; //colors - this.r = Math.round(Math.random()*255); - this.g = Math.round(Math.random()*255); - this.b = Math.round(Math.random()*255); - } - for(var i = 0; i < particle_count; i++) - { + this.r = Math.round(Math.random() * 255); + this.g = Math.round(Math.random() * 255); + this.b = Math.round(Math.random() * 255); + }; + for (var i = 0; i < particle_count; i++) { particles.push(new particle()); } - var draw=function() - { - if(!game.haveFun.list.blink.running){ - canvas.width=W; - canvas.height=H; + var draw = function () { + if (!game.haveFun.list.blink.running) { + canvas.width = W; + canvas.height = H; return; } ctx.clearRect(0, 0, W, H); @@ -250,52 +273,96 @@ game.import('play',function(lib,game,ui,get,ai,_status){ //previous frame ctx.globalCompositeOperation = "lighter"; - for(var i = 0; i < particles.length; i++) - { + for (var i = 0; i < particles.length; i++) { var p = particles[i]; ctx.beginPath(); //changing opacity according to the life. //opacity goes to 0 at the end of life of a particle - p.opacity = Math.round(p.remaining_life/p.life*100)/100 + p.opacity = + Math.round( + (p.remaining_life / p.life) * 100 + ) / 100; //a gradient instead of white fill - var gradient = ctx.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius); - gradient.addColorStop(0, "rgba("+p.r+", "+p.g+", "+p.b+", "+p.opacity+")"); - gradient.addColorStop(0.5, "rgba("+p.r+", "+p.g+", "+p.b+", "+p.opacity+")"); - gradient.addColorStop(1, "rgba("+p.r+", "+p.g+", "+p.b+", 0)"); + var gradient = ctx.createRadialGradient( + p.location.x, + p.location.y, + 0, + p.location.x, + p.location.y, + p.radius + ); + gradient.addColorStop( + 0, + "rgba(" + + p.r + + ", " + + p.g + + ", " + + p.b + + ", " + + p.opacity + + ")" + ); + gradient.addColorStop( + 0.5, + "rgba(" + + p.r + + ", " + + p.g + + ", " + + p.b + + ", " + + p.opacity + + ")" + ); + gradient.addColorStop( + 1, + "rgba(" + + p.r + + ", " + + p.g + + ", " + + p.b + + ", 0)" + ); ctx.fillStyle = gradient; - ctx.arc(p.location.x, p.location.y, p.radius, Math.PI*2, false); + ctx.arc( + p.location.x, + p.location.y, + p.radius, + Math.PI * 2, + false + ); ctx.fill(); //lets move the particles p.remaining_life--; - p.radius-=0.2; + p.radius -= 0.2; p.location.x += p.speed.x; p.location.y += p.speed.y; //regenerate particles - if(p.remaining_life < 0 || p.radius < 0) - { + if (p.remaining_life < 0 || p.radius < 0) { //a brand new particle replacing the dead one particles[i] = new particle(); } } requestAnimationFrame(draw); - } + }; draw(); - game.haveFun.blinkLoop=draw; - game.haveFun.blinkStop=function(){ - game.haveFun.list.blink.running=false; - } + game.haveFun.blinkLoop = draw; + game.haveFun.blinkStop = function () { + game.haveFun.list.blink.running = false; + }; } }, - star:function(){ - if(game.haveFun.list.star.running) return; - game.haveFun.list.star.running=true; - if(game.haveFun.starLoop){ + star: function () { + if (game.haveFun.list.star.running) return; + game.haveFun.list.star.running = true; + if (game.haveFun.starLoop) { game.haveFun.starLoop(); - } - else{ + } else { //****************************************************** // Yet Another Particle Engine var cos = Math.cos, @@ -306,11 +373,13 @@ game.import('play',function(lib,game,ui,get,ai,_status){ log = Math.log, random = Math.random, PI = Math.PI, - sqr = function(v){return v*v;}, + sqr = function (v) { + return v * v; + }, particles = [], drawScale = 1, emitters = [], - forces = [], + forces = [], collidedMass = 0, maxParticles = 100, emissionRate = 1, @@ -318,238 +387,285 @@ game.import('play',function(lib,game,ui,get,ai,_status){ //------------------------------------------------------- // Vectors, and not the kind you put stuff in - var Vector=function(x, y, z) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - } + var Vector = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + }; Vector.prototype = { - add : function(vector) { - this.x += vector.x; - this.y += vector.y; - this.z += vector.z; - return this; - }, - subtract : function(vector) { - this.x -= vector.x; - this.y -= vector.y; - this.z -= vector.z; - return this; - }, - multiply : function(another) { - this.x /= another.x; - this.y /= another.y; - this.z /= another.z; - return this; - }, - divide : function(another) { - this.x /= another.x; - this.y /= another.y; - this.z /= another.z; - return this; - }, - scale : function(factor) { - this.x *= factor; - this.y *= factor; - this.z *= factor; - return this; - }, - magnitude : function () { - return sqrt(sqr(this.x + this.y)); - }, - distance : function (another) { - return abs(sqrt(sqr(this.x - another.x) + sqr(this.y - another.y))); - }, - angle : function (angle, magnitude) { - if(angle && magnitude) - return Vector.fromAngle(angle, magnitude); - return atan2(this.y, this.x); - }, - clone : function() { - return new Vector(this.x, this.y, this.z); - }, - equals : function(another) { - return this.x === another.x&& - this.y === another.y&& - this.z === another.z; - }, - random : function(r) { - this.x += (random() * r * 2) - r; - this.y += (random() * r * 2) - r; - return this; - } + add: function (vector) { + this.x += vector.x; + this.y += vector.y; + this.z += vector.z; + return this; + }, + subtract: function (vector) { + this.x -= vector.x; + this.y -= vector.y; + this.z -= vector.z; + return this; + }, + multiply: function (another) { + this.x /= another.x; + this.y /= another.y; + this.z /= another.z; + return this; + }, + divide: function (another) { + this.x /= another.x; + this.y /= another.y; + this.z /= another.z; + return this; + }, + scale: function (factor) { + this.x *= factor; + this.y *= factor; + this.z *= factor; + return this; + }, + magnitude: function () { + return sqrt(sqr(this.x + this.y)); + }, + distance: function (another) { + return abs( + sqrt( + sqr(this.x - another.x) + + sqr(this.y - another.y) + ) + ); + }, + angle: function (angle, magnitude) { + if (angle && magnitude) + return Vector.fromAngle(angle, magnitude); + return atan2(this.y, this.x); + }, + clone: function () { + return new Vector(this.x, this.y, this.z); + }, + equals: function (another) { + return ( + this.x === another.x && + this.y === another.y && + this.z === another.z + ); + }, + random: function (r) { + this.x += random() * r * 2 - r; + this.y += random() * r * 2 - r; + return this; + }, }; Vector.fromAngle = function (angle, magnitude) { - return new Vector( - magnitude * cos(angle), - magnitude * sin(angle), - magnitude * sin(angle)); + return new Vector( + magnitude * cos(angle), + magnitude * sin(angle), + magnitude * sin(angle) + ); }; //****************************************************** // A thing with mass, position, and velocity - like your mom - var Particle=function(pt, vc, ac, mass) { - this.pos = pt || new Vector(0, 0); - this.vc = vc || new Vector(0, 0); - this.ac = ac || new Vector(0, 0); - this.mass = mass || 1; - this.alive = true; - } + var Particle = function (pt, vc, ac, mass) { + this.pos = pt || new Vector(0, 0); + this.vc = vc || new Vector(0, 0); + this.ac = ac || new Vector(0, 0); + this.mass = mass || 1; + this.alive = true; + }; Particle.prototype.move = function () { - this.vc.add(this.ac); - this.pos.add(this.vc); + this.vc.add(this.ac); + this.pos.add(this.vc); }; Particle.prototype.reactToForces = function (fields) { - var totalAccelerationX = 0; - var totalAccelerationY = 0; + var totalAccelerationX = 0; + var totalAccelerationY = 0; - for (var i = 0; i < fields.length; i++) { - var field = fields[i]; - var vectorX = field.pos.x - this.pos.x; - var vectorY = field.pos.y - this.pos.y; - var distance = this.pos.distance(field.pos); - if(distance < 1) field.grow(this); - if(distance < 100) this.doubleSize = true; - var force = G(this.forceBetween(field, distance)); - totalAccelerationX += vectorX * force; - totalAccelerationY += vectorY * force; - } - this.ac = new Vector(totalAccelerationX, totalAccelerationY); - - totalAccelerationX = 0; - totalAccelerationY = 0; - for (var i = 0; i < particles.length; i++) { - var field = particles[i]; - if(field === this || !field.alive) continue; - var vectorX = field.pos.x - this.pos.x; - var vectorY = field.pos.y - this.pos.y; - var distance = this.pos.distance(field.pos); - if(distance < 1) { - if(this.mass >= field.mass) { - var massRatio = this.mass / field.mass; - if(particles.length <= maxParticles && this.mass>40) { - this.alive = false; - this.nova = true; - collidedMass += this.mass; - } else this.grow(field); - } else this.alive = false; + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var vectorX = field.pos.x - this.pos.x; + var vectorY = field.pos.y - this.pos.y; + var distance = this.pos.distance(field.pos); + if (distance < 1) field.grow(this); + if (distance < 100) this.doubleSize = true; + var force = G( + this.forceBetween(field, distance) + ); + totalAccelerationX += vectorX * force; + totalAccelerationY += vectorY * force; } - if(this.alive) { - var force = G(this.forceBetween(field, distance)); - totalAccelerationX += vectorX * G(force); - totalAccelerationY += vectorY * G(force); + this.ac = new Vector( + totalAccelerationX, + totalAccelerationY + ); + + totalAccelerationX = 0; + totalAccelerationY = 0; + for (var i = 0; i < particles.length; i++) { + var field = particles[i]; + if (field === this || !field.alive) continue; + var vectorX = field.pos.x - this.pos.x; + var vectorY = field.pos.y - this.pos.y; + var distance = this.pos.distance(field.pos); + if (distance < 1) { + if (this.mass >= field.mass) { + var massRatio = this.mass / field.mass; + if ( + particles.length <= maxParticles && + this.mass > 40 + ) { + this.alive = false; + this.nova = true; + collidedMass += this.mass; + } else this.grow(field); + } else this.alive = false; + } + if (this.alive) { + var force = G( + this.forceBetween(field, distance) + ); + totalAccelerationX += vectorX * G(force); + totalAccelerationY += vectorY * G(force); + } } - } - var travelDist = this.pos.distance(this.lastPos ? this.lastPos : this.pos); - this.velocity = travelDist - (this.lastDistance ? this.lastDistance : travelDist); - this.lastDistance = travelDist; - this.lastPos = this.pos.clone(); + var travelDist = this.pos.distance( + this.lastPos ? this.lastPos : this.pos + ); + this.velocity = + travelDist - + (this.lastDistance + ? this.lastDistance + : travelDist); + this.lastDistance = travelDist; + this.lastPos = this.pos.clone(); - this.ac.add(new Vector(totalAccelerationX, totalAccelerationY)); - this.lastPos = this.pos.clone(); - // if(this.mass > 20) { - // var chance = 1 / (this.mass - 20); - // if(Math.random()>chance) { - // this.supernova = true; - // this.supernovaDur = 10; - // this.alive = false; - // if(particles.length <= maxParticles) collidedMass += this.mass; - // delete this.size; - // } - // } + this.ac.add( + new Vector( + totalAccelerationX, + totalAccelerationY + ) + ); + this.lastPos = this.pos.clone(); + // if(this.mass > 20) { + // var chance = 1 / (this.mass - 20); + // if(Math.random()>chance) { + // this.supernova = true; + // this.supernovaDur = 10; + // this.alive = false; + // if(particles.length <= maxParticles) collidedMass += this.mass; + // delete this.size; + // } + // } }; Particle.prototype.grow = function (another) { - this.mass += another.mass; - this.nova = true; - another.alive = false; - delete this.size; + this.mass += another.mass; + this.nova = true; + another.alive = false; + delete this.size; }; - Particle.prototype.breakApart = function(minMass, maxParts) { - if(!minMass) minMass = 1; - if(!maxParts) maxParts = 2; - var remainingMass = this.mass; - var num = 0; - while(remainingMass > 0) { - var np = new Particle(this.pos.clone().random(this.mass), new Vector(0,0)); - np.mass = 1 + Math.random() * (remainingMass - 1); - if(num>=maxParts-1) np.mass = remainingMass; - np.mass = np.mass < minMass ? minMass : np.mass; - remainingMass -= np.mass; - num++; - } - this.nova = true; - delete this.size; - this.alive = false; + Particle.prototype.breakApart = function ( + minMass, + maxParts + ) { + if (!minMass) minMass = 1; + if (!maxParts) maxParts = 2; + var remainingMass = this.mass; + var num = 0; + while (remainingMass > 0) { + var np = new Particle( + this.pos.clone().random(this.mass), + new Vector(0, 0) + ); + np.mass = + 1 + Math.random() * (remainingMass - 1); + if (num >= maxParts - 1) + np.mass = remainingMass; + np.mass = np.mass < minMass ? minMass : np.mass; + remainingMass -= np.mass; + num++; + } + this.nova = true; + delete this.size; + this.alive = false; }; - Particle.prototype.forceBetween = function(another, distance) { - var distance = distance? distance : this.pos.distance(another.pos); - return (this.mass * another.mass) / sqr(distance); + Particle.prototype.forceBetween = function ( + another, + distance + ) { + var distance = distance + ? distance + : this.pos.distance(another.pos); + return (this.mass * another.mass) / sqr(distance); }; //****************************************************** //This certainly doesn't *sub*mit to particles, that's for sure - var ParticleEmitter=function(pos, vc, ang) { - // to do config options for emitter - random, static, show emitter, emitter color, etc - this.pos = pos; - this.vc = vc; - this.ang = ang || 0.09; - this.color = "#999"; - } - ParticleEmitter.prototype.emit = function() { - var angle = this.vc.angle() + - this.ang - (Math.random() * this.ang * 2); - var magnitude = this.vc.magnitude(); - var position = this.pos.clone(); - position.add( + var ParticleEmitter = function (pos, vc, ang) { + // to do config options for emitter - random, static, show emitter, emitter color, etc + this.pos = pos; + this.vc = vc; + this.ang = ang || 0.09; + this.color = "#999"; + }; + ParticleEmitter.prototype.emit = function () { + var angle = + this.vc.angle() + + this.ang - + Math.random() * this.ang * 2; + var magnitude = this.vc.magnitude(); + var position = this.pos.clone(); + position.add( new Vector( - ~~((Math.random() * 100) - 50) * drawScale, - ~~((Math.random() * 100) - 50) * drawScale - )); - var velocity = Vector.fromAngle(angle, magnitude); - return new Particle(position,velocity); + ~~(Math.random() * 100 - 50) * drawScale, + ~~(Math.random() * 100 - 50) * drawScale + ) + ); + var velocity = Vector.fromAngle(angle, magnitude); + return new Particle(position, velocity); }; //****************************************************** // Use it, Luke // to do collapse functionality into particle - var Force=function(pos, m) { - this.pos = pos; - this.mass = m || 100; - } + var Force = function (pos, m) { + this.pos = pos; + this.mass = m || 100; + }; Force.prototype.grow = function (another) { - this.mass += another.mass; - this.burp = true; - another.alive = false; + this.mass += another.mass; + this.burp = true; + another.alive = false; }; - - - var G=function(data) { - return 0.00674 * data; - } + var G = function (data) { + return 0.00674 * data; + }; //****************************************************** - var canvas = document.createElement('canvas'); - canvas.classList.add('fun'); + var canvas = document.createElement("canvas"); + canvas.classList.add("fun"); ui.window.appendChild(canvas); - var ctx = canvas.getContext('2d'); + var ctx = canvas.getContext("2d"); canvas.width = ui.window.offsetWidth; canvas.height = ui.window.offsetHeight; var canvasWidth = canvas.width; var canvasHeight = canvas.height; - lib.onresize.push(function() { + lib.onresize.push(function () { canvas.width = ui.window.offsetWidth; canvas.height = ui.window.offsetHeight; canvasWidth = canvas.width; canvasHeight = canvas.height; }); - var renderToCanvas = function (width, height, renderFunction) { - var buffer = document.createElement('canvas'); + var renderToCanvas = function ( + width, + height, + renderFunction + ) { + var buffer = document.createElement("canvas"); buffer.width = width; buffer.height = height; - renderFunction(buffer.getContext('2d')); + renderFunction(buffer.getContext("2d")); return buffer; }; @@ -558,174 +674,183 @@ game.import('play',function(lib,game,ui,get,ai,_status){ drawScale = 1.3; minParticleSize = 2; emitters = [ - //br - new ParticleEmitter( - new Vector( - canvasWidth / 2 * drawScale + 400, - canvasHeight / 2 * drawScale - ), - Vector.fromAngle(2, 5), - 1 - ), - // // bl - // new ParticleEmitter( - // new Vector( - // canvasWidth / 2 * drawScale - 400, - // canvasHeight / 2 * drawScale + 400 - // ), - // Vector.fromAngle(1.5, 1), - // 1 - // ), + //br + new ParticleEmitter( + new Vector( + (canvasWidth / 2) * drawScale + 400, + (canvasHeight / 2) * drawScale + ), + Vector.fromAngle(2, 5), + 1 + ), + // // bl + // new ParticleEmitter( + // new Vector( + // canvasWidth / 2 * drawScale - 400, + // canvasHeight / 2 * drawScale + 400 + // ), + // Vector.fromAngle(1.5, 1), + // 1 + // ), // tl - new ParticleEmitter( - new Vector( - canvasWidth / 2 * drawScale - 400, - canvasHeight / 2 * drawScale - ), - Vector.fromAngle(5, 5), - 1 - ), - // // tr - // new ParticleEmitter( - // new Vector( - // canvasWidth / 2 * drawScale + 400, - // canvasHeight / 2 * drawScale - 400 - // ), - // Vector.fromAngle(4.5, 1), - // 1 - // ) + new ParticleEmitter( + new Vector( + (canvasWidth / 2) * drawScale - 400, + (canvasHeight / 2) * drawScale + ), + Vector.fromAngle(5, 5), + 1 + ), + // // tr + // new ParticleEmitter( + // new Vector( + // canvasWidth / 2 * drawScale + 400, + // canvasHeight / 2 * drawScale - 400 + // ), + // Vector.fromAngle(4.5, 1), + // 1 + // ) ]; - forces = [ - new Force( - new Vector((canvasWidth / 2 * drawScale) , - (canvasHeight / 2 * drawScale)), 1800) + forces = [ + new Force( + new Vector( + (canvasWidth / 2) * drawScale, + (canvasHeight / 2) * drawScale + ), + 1800 + ), ]; - var loop=function() { - if(!game.haveFun.list.star.running){ - canvas.width=ui.window.offsetWidth; - canvas.height=ui.window.offsetHeight; + var loop = function () { + if (!game.haveFun.list.star.running) { + canvas.width = ui.window.offsetWidth; + canvas.height = ui.window.offsetHeight; return; } clear(); update(); draw(); queue(); - } - game.haveFun.starLoop=loop; - game.haveFun.starStop=function(){ - game.haveFun.list.star.running=false; + }; + game.haveFun.starLoop = loop; + game.haveFun.starStop = function () { + game.haveFun.list.star.running = false; }; - - var clear=function() { - ctx.clearRect(0, 0, canvas.width, canvas.height); - } + var clear = function () { + ctx.clearRect(0, 0, canvas.width, canvas.height); + }; var ctr = 0; var c = [ - 'rgba(255,255,255,', - 'rgba(0,150,255,', - 'rgba(255,255,128,', - 'rgba(255,255,255,' + "rgba(255,255,255,", + "rgba(0,150,255,", + "rgba(255,255,128,", + "rgba(255,255,255,", ]; - var rndc=function() { - return c[~~(Math.random() * c.length-1)]; - } - var c2 = 'rgba(255,64,32,'; - var addNewParticles=function() { - var _emit = function() { - var ret = 0; - for (var i = 0; i < emitters.length; i++) { - for (var j = 0; j < emissionRate; j++) { - var p = emitters[i].emit(); - p.color = ( ctr % 10 === 0 )? - ( Math.random() * 5 <= 1 ? c2 : rndc() ) - : rndc(); - p.mass = ~~(Math.random() * 5); - particles.push(p); - ret += p.mass; - ctr++; - } + var rndc = function () { + return c[~~(Math.random() * c.length - 1)]; + }; + var c2 = "rgba(255,64,32,"; + var addNewParticles = function () { + var _emit = function () { + var ret = 0; + for (var i = 0; i < emitters.length; i++) { + for (var j = 0; j < emissionRate; j++) { + var p = emitters[i].emit(); + p.color = + ctr % 10 === 0 + ? Math.random() * 5 <= 1 + ? c2 + : rndc() + : rndc(); + p.mass = ~~(Math.random() * 5); + particles.push(p); + ret += p.mass; + ctr++; + } + } + return ret; + }; + if (collidedMass !== 0) { + while (collidedMass !== 0) { + collidedMass -= _emit(); + collidedMass = + collidedMass < 0 ? 0 : collidedMass; + } } - return ret; - }; - if(collidedMass !== 0) { - while(collidedMass !== 0) { - collidedMass -= _emit(); - collidedMass = collidedMass<0 ? 0 :collidedMass; - } - } - if (particles.length > maxParticles) - return; - _emit(); - } + if (particles.length > maxParticles) return; + _emit(); + }; var CLIPOFFSCREEN = 1, BUFFEROFFSCREEN = 2, LOOPSCREEN = 3; - var isPositionAliveAndAdjust=function(particle,check) { - return true; - // var pos = particle.pos; - // if(!check) check = BUFFEROFFSCREEN; - // if(check === CLIPOFFSCREEN) { - // return !(!particle.alive || - // pos.x < 0 || - // (pos.x / drawScale) > boundsX || - // pos.y < 0 || - // (pos.y / drawScale) > boundsY); - // } else if(check === BUFFEROFFSCREEN) { - // return !(!particle.alive || - // pos.x < -boundsX * drawScale || - // pos.x > 2 * boundsX * drawScale || - // pos.y < -boundsY * drawScale || - // pos.y > 2 * boundsY * drawScale); - // } else if(check === LOOPSCREEN) { - // if (pos.x < 0) pos.x = boundsX * drawScale; - // if ((pos.x / drawScale) > boundsX) pos.x = 0; - // if (pos.y < 0) pos.y = boundsY * drawScale; - // if ((pos.y / drawScale) > boundsY) pos.y = 0; - // return true; - // } - } + var isPositionAliveAndAdjust = function ( + particle, + check + ) { + return true; + // var pos = particle.pos; + // if(!check) check = BUFFEROFFSCREEN; + // if(check === CLIPOFFSCREEN) { + // return !(!particle.alive || + // pos.x < 0 || + // (pos.x / drawScale) > boundsX || + // pos.y < 0 || + // (pos.y / drawScale) > boundsY); + // } else if(check === BUFFEROFFSCREEN) { + // return !(!particle.alive || + // pos.x < -boundsX * drawScale || + // pos.x > 2 * boundsX * drawScale || + // pos.y < -boundsY * drawScale || + // pos.y > 2 * boundsY * drawScale); + // } else if(check === LOOPSCREEN) { + // if (pos.x < 0) pos.x = boundsX * drawScale; + // if ((pos.x / drawScale) > boundsX) pos.x = 0; + // if (pos.y < 0) pos.y = boundsY * drawScale; + // if ((pos.y / drawScale) > boundsY) pos.y = 0; + // return true; + // } + }; - var plotParticles=function(boundsX, boundsY) { - var currentParticles = []; - for (var i = 0; i < particles.length; i++) { - var particle = particles[i]; - particle.reactToForces(forces); - if(!isPositionAliveAndAdjust(particle)) - continue; - particle.move(); - currentParticles.push(particle); - } - } + var plotParticles = function (boundsX, boundsY) { + var currentParticles = []; + for (var i = 0; i < particles.length; i++) { + var particle = particles[i]; + particle.reactToForces(forces); + if (!isPositionAliveAndAdjust(particle)) + continue; + particle.move(); + currentParticles.push(particle); + } + }; var offscreenCache = {}; - var renderParticle=function(p) { + var renderParticle = function (p) { var position = p.pos; - if(!p.size) p.size = Math.floor(p.mass / 100); + if (!p.size) p.size = Math.floor(p.mass / 100); - - if(!p.opacity) p.opacity = 0.05; - if(p.velocity > 0) { - if(p.opacity<=0.18) - p.opacity += 0.04; + if (!p.opacity) p.opacity = 0.05; + if (p.velocity > 0) { + if (p.opacity <= 0.18) p.opacity += 0.04; } - if(p.opacity>0.08) - p.opacity -= 0.02; + if (p.opacity > 0.08) p.opacity -= 0.02; var actualSize = p.size / drawScale; - actualSize = actualSize < minParticleSize ? minParticleSize : actualSize; - if(p.mass>8) actualSize *= 2; - if(p.nova) { - actualSize *= 4; - p.nova = false; + actualSize = + actualSize < minParticleSize + ? minParticleSize + : actualSize; + if (p.mass > 8) actualSize *= 2; + if (p.nova) { + actualSize *= 4; + p.nova = false; } - if(p.doubleSize) { - p.doubleSize = false; - actualSize *= 2; + if (p.doubleSize) { + p.doubleSize = false; + actualSize *= 2; } // if(p.supernova) { // actualSize *= 6; @@ -734,124 +859,155 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // if(p.supernovaDur === 0) // p.supernova = false; // } - var cacheKey = actualSize + '_' + p.opacity + '_' + p.color; + var cacheKey = + actualSize + "_" + p.opacity + "_" + p.color; var cacheValue = offscreenCache[cacheKey]; - if(!cacheValue) { - cacheValue = renderToCanvas(actualSize * 32, actualSize * 32, function(ofsContext) { - var opacity = p.opacity; - var fills = [ - {size:actualSize/2, opacity:1}, - {size:actualSize, opacity:opacity}, - {size:actualSize * 2, opacity:opacity / 2}, - {size:actualSize * 4, opacity:opacity / 3}, - {size:actualSize * 8, opacity:opacity / 5}, - {size:actualSize * 16, opacity:opacity / 16} - ]; - ofsContext.beginPath(); - for(var f in fills) { - f = fills[f]; - ofsContext.fillStyle = p.color + f.opacity + ')'; - ofsContext.arc( - actualSize * 16, - actualSize * 16, - f.size , 0, Math.PI*2, true); - ofsContext.fill(); - } - ofsContext.closePath(); - }); - offscreenCache[cacheKey] = cacheValue; + if (!cacheValue) { + cacheValue = renderToCanvas( + actualSize * 32, + actualSize * 32, + function (ofsContext) { + var opacity = p.opacity; + var fills = [ + { + size: actualSize / 2, + opacity: 1, + }, + { + size: actualSize, + opacity: opacity, + }, + { + size: actualSize * 2, + opacity: opacity / 2, + }, + { + size: actualSize * 4, + opacity: opacity / 3, + }, + { + size: actualSize * 8, + opacity: opacity / 5, + }, + { + size: actualSize * 16, + opacity: opacity / 16, + }, + ]; + ofsContext.beginPath(); + for (var f in fills) { + f = fills[f]; + ofsContext.fillStyle = + p.color + f.opacity + ")"; + ofsContext.arc( + actualSize * 16, + actualSize * 16, + f.size, + 0, + Math.PI * 2, + true + ); + ofsContext.fill(); + } + ofsContext.closePath(); + } + ); + offscreenCache[cacheKey] = cacheValue; } - var posX = p.pos.x / drawScale; + var posX = p.pos.x / drawScale; var posY = p.pos.y / drawScale; ctx.drawImage(cacheValue, posX, posY); - } + }; var fills = [ - {size:15,opacity:1 }, - {size:25,opacity:0.3}, - {size:50,opacity:0.1} ]; + { size: 15, opacity: 1 }, + { size: 25, opacity: 0.3 }, + { size: 50, opacity: 0.1 }, + ]; - var renderScene=function(ofsContext) { - for (var i = 0; i < forces.length; i++) { - var p = forces[i]; - var position = p.pos; - var opacity = 1; + var renderScene = function (ofsContext) { + for (var i = 0; i < forces.length; i++) { + var p = forces[i]; + var position = p.pos; + var opacity = 1; - ofsContext.beginPath(); - for(var f in fills) { - f = fills[f]; - var o = p.burp === true ? 1 : f.opacity; - p.burp = false; - // ofsContext.fillStyle = 'rgba(255,255,255,' + o + ')'; - // ofsContext.arc(position.x / drawScale, - // position.y / drawScale, - // f.size / drawScale, 0, Math.PI*2, true); - // ofsContext.fill(); + ofsContext.beginPath(); + for (var f in fills) { + f = fills[f]; + var o = p.burp === true ? 1 : f.opacity; + p.burp = false; + // ofsContext.fillStyle = 'rgba(255,255,255,' + o + ')'; + // ofsContext.arc(position.x / drawScale, + // position.y / drawScale, + // f.size / drawScale, 0, Math.PI*2, true); + // ofsContext.fill(); + } + ofsContext.closePath(); } - ofsContext.closePath(); - } - for (var i = 0; i < particles.length; i++) { - var p = particles[i]; - renderParticle(p); - } - } + for (var i = 0; i < particles.length; i++) { + var p = particles[i]; + renderParticle(p); + } + }; - var draw=function() { - renderScene(ctx); - } + var draw = function () { + renderScene(ctx); + }; - var update=function() { - addNewParticles(); - plotParticles(canvas.width, canvas.height); - } + var update = function () { + addNewParticles(); + plotParticles(canvas.width, canvas.height); + }; - var queue=function() { - window.requestAnimationFrame(loop); - } + var queue = function () { + window.requestAnimationFrame(loop); + }; loop(); - } }, - snow:function(){ - game.haveFun.list.snow.running=true; - if(game.haveFun.snowStart){ + snow: function () { + game.haveFun.list.snow.running = true; + if (game.haveFun.snowStart) { game.haveFun.snowStart(); - } - else{ + } else { /* - * 自由下雪 snowFall - * author:xuanfeng - * time: 2014-01-11 - */ + * 自由下雪 snowFall + * author:xuanfeng + * time: 2014-01-11 + */ // 控制下雪 var canvas; - var snowFall=function(snow) { + var snowFall = function (snow) { // 可配置属性 snow = snow || {}; - this.maxFlake = snow.maxFlake || 200; //最多片数 - this.flakeSize = snow.flakeSize || 10; //雪花形状 - this.fallSpeed = snow.fallSpeed || 2; //坠落速度 - this.status = 0; //0-初始化、1-开始下雪、2-停止下雪、3-暂停下雪、4-继续下雪 - } + this.maxFlake = snow.maxFlake || 200; //最多片数 + this.flakeSize = snow.flakeSize || 10; //雪花形状 + this.fallSpeed = snow.fallSpeed || 2; //坠落速度 + this.status = 0; //0-初始化、1-开始下雪、2-停止下雪、3-暂停下雪、4-继续下雪 + }; // 兼容写法 - var requestAnimationFrame = window.requestAnimationFrame || - window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || - window.msRequestAnimationFrame || - window.oRequestAnimationFrame || - function(callback) { setTimeout(callback, 1000 / 60); }; - var cancelAnimationFrame = window.cancelAnimationFrame || - window.mozCancelAnimationFrame || - window.webkitCancelAnimationFrame || - window.msCancelAnimationFrame || - window.oCancelAnimationFrame; + var requestAnimationFrame = + window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame || + window.oRequestAnimationFrame || + function (callback) { + setTimeout(callback, 1000 / 60); + }; + var cancelAnimationFrame = + window.cancelAnimationFrame || + window.mozCancelAnimationFrame || + window.webkitCancelAnimationFrame || + window.msCancelAnimationFrame || + window.oCancelAnimationFrame; // 开始下雪 - snowFall.prototype.start = function(){ - if(this.status == 1 || this.status == 4){ + snowFall.prototype.start = function () { + if (this.status == 1 || this.status == 4) { // 已经在下雪则不作处理 return false; } @@ -862,12 +1018,16 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // 创建雪花形状 createFlakes.apply(this); // 画雪 - drawSnow.apply(this) - } + drawSnow.apply(this); + }; // 停止下雪 - snowFall.prototype.stop = function(){ - if(this.status == 2 || this.status == 0 || !this.canvas){ + snowFall.prototype.stop = function () { + if ( + this.status == 2 || + this.status == 0 || + !this.canvas + ) { return false; } // 停止动画循环 @@ -876,82 +1036,93 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // 删除画布 this.canvas.parentNode.removeChild(this.canvas); this.canvas = null; - } + }; // 暂停下雪 - snowFall.prototype.pause = function(){ - if(this.status == 3){ + snowFall.prototype.pause = function () { + if (this.status == 3) { return false; } this.status = 3; - cancelAnimationFrame(this.loop) + cancelAnimationFrame(this.loop); }; // 继续下雪 - snowFall.prototype.resume = function(){ - if(this.status == 3 && this.canvas){ + snowFall.prototype.resume = function () { + if (this.status == 3 && this.canvas) { this.status = 4; // 动画的计时控制 - var that=this; - this.loop = requestAnimationFrame(function() { - drawSnow.apply(that) + var that = this; + this.loop = requestAnimationFrame(function () { + drawSnow.apply(that); }); } }; // 创建画布 - var snowCanvas=function() { + var snowCanvas = function () { // 添加Dom结点 var snowcanvas = document.createElement("canvas"); - snowcanvas.classList.add('fun'); + snowcanvas.classList.add("fun"); snowcanvas.id = "snowfall"; ui.window.appendChild(snowcanvas); - canvas=snowcanvas; + canvas = snowcanvas; this.canvas = snowcanvas; this.ctx = snowcanvas.getContext("2d"); // 窗口大小改变的处理 - lib.onresize.push(function() { + lib.onresize.push(function () { snowcanvas.width = ui.window.offsetWidth; - snowcanvas.height = ui.window.offsetHeight + snowcanvas.height = ui.window.offsetHeight; }); snowcanvas.width = ui.window.offsetWidth; snowcanvas.height = ui.window.offsetHeight; - } + }; // 雪运动对象 - var flakeMove=function(canvasWidth, canvasHeight, flakeSize, fallSpeed) { - this.x = Math.floor(Math.random() * canvasWidth); //x坐标 - this.y = Math.floor(Math.random() * canvasHeight); //y坐标 - this.size = Math.random() * flakeSize + 2; //形状 - this.maxSize = flakeSize; //最大形状 - this.speed = Math.random() * 1 + fallSpeed; //坠落速度 - this.fallSpeed = fallSpeed; //坠落速度 - this.velY = this.speed; //Y方向速度 - this.velX = 0; //X方向速度 - this.stepSize = Math.random() / 30; //步长 - this.step = 0 //步数 - } + var flakeMove = function ( + canvasWidth, + canvasHeight, + flakeSize, + fallSpeed + ) { + this.x = Math.floor(Math.random() * canvasWidth); //x坐标 + this.y = Math.floor(Math.random() * canvasHeight); //y坐标 + this.size = Math.random() * flakeSize + 2; //形状 + this.maxSize = flakeSize; //最大形状 + this.speed = Math.random() * 1 + fallSpeed; //坠落速度 + this.fallSpeed = fallSpeed; //坠落速度 + this.velY = this.speed; //Y方向速度 + this.velX = 0; //X方向速度 + this.stepSize = Math.random() / 30; //步长 + this.step = 0; //步数 + }; - flakeMove.prototype.update = function() { + flakeMove.prototype.update = function () { var x = this.x, y = this.y; // 左右摆动(余弦) this.velX *= 0.98; if (this.velY <= this.speed) { - this.velY = this.speed + this.velY = this.speed; } - this.velX += Math.cos(this.step += 0.05) * this.stepSize; + this.velX += + Math.cos((this.step += 0.05)) * this.stepSize; this.y += this.velY; this.x += this.velX; // 飞出边界的处理 - if (this.x >= canvas.width || this.x <= 0 || this.y >= canvas.height || this.y <= 0) { - this.reset(canvas.width, canvas.height) + if ( + this.x >= canvas.width || + this.x <= 0 || + this.y >= canvas.height || + this.y <= 0 + ) { + this.reset(canvas.width, canvas.height); } }; // 飞出边界-放置最顶端继续坠落 - flakeMove.prototype.reset = function(width, height) { + flakeMove.prototype.reset = function (width, height) { this.x = Math.floor(Math.random() * width); this.y = 0; this.size = Math.random() * snow.flakeSize + 2; @@ -961,10 +1132,23 @@ game.import('play',function(lib,game,ui,get,ai,_status){ }; // 渲染雪花-随机形状 - flakeMove.prototype.render = function(ctx) { - var snowFlake = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.size); - snowFlake.addColorStop(0, "rgba(255, 255, 255, 0.9)"); - snowFlake.addColorStop(0.5, "rgba(255, 255, 255, 0.5)"); + flakeMove.prototype.render = function (ctx) { + var snowFlake = ctx.createRadialGradient( + this.x, + this.y, + 0, + this.x, + this.y, + this.size + ); + snowFlake.addColorStop( + 0, + "rgba(255, 255, 255, 0.9)" + ); + snowFlake.addColorStop( + 0.5, + "rgba(255, 255, 255, 0.5)" + ); snowFlake.addColorStop(1, "rgba(255, 255, 255, 0)"); ctx.save(); ctx.fillStyle = snowFlake; @@ -975,20 +1159,29 @@ game.import('play',function(lib,game,ui,get,ai,_status){ }; // 创建雪花-定义形状 - var createFlakes=function() { + var createFlakes = function () { var maxFlake = this.maxFlake, - flakes = this.flakes = [], + flakes = (this.flakes = []), canvas = this.canvas; for (var i = 0; i < 200; i++) { - flakes.push(new flakeMove(canvas.width, canvas.height, this.flakeSize, this.fallSpeed)) + flakes.push( + new flakeMove( + canvas.width, + canvas.height, + this.flakeSize, + this.fallSpeed + ) + ); } - } + }; // 画雪 - var drawSnow=function() { + var drawSnow = function () { var maxFlake = this.maxFlake, flakes = this.flakes; - var ctx = this.ctx, canvas = this.canvas, that = this; + var ctx = this.ctx, + canvas = this.canvas, + that = this; // 清空雪花 ctx.clearRect(0, 0, canvas.width, canvas.height); for (var e = 0; e < maxFlake; e++) { @@ -996,98 +1189,98 @@ game.import('play',function(lib,game,ui,get,ai,_status){ flakes[e].render(ctx); } // 一帧一帧的画 - this.loop = requestAnimationFrame(function() { + this.loop = requestAnimationFrame(function () { drawSnow.apply(that); }); - } + }; // 调用及控制方法 var snow = new snowFall(); - game.haveFun.snowStart=function(){ + game.haveFun.snowStart = function () { snow.start(); - } - game.haveFun.snowStop=function(){ - game.haveFun.list.snow.running=false; + }; + game.haveFun.snowStop = function () { + game.haveFun.list.snow.running = false; snow.stop(); - } - game.haveFun.snowSize=function(){ - if(game.haveFun.list.snow.size=='large'){ - game.haveFun.list.snow.size='small'; - snow.maxFlake=80; - snow.flakeSize=3; - snow.fallSpeed=1; - if(this&&this.innerHTML){ - this.innerHTML='大雪'; + }; + game.haveFun.snowSize = function () { + if (game.haveFun.list.snow.size == "large") { + game.haveFun.list.snow.size = "small"; + snow.maxFlake = 80; + snow.flakeSize = 3; + snow.fallSpeed = 1; + if (this && this.innerHTML) { + this.innerHTML = "大雪"; } - game.saveConfig('coinSnowSize',true); - } - else{ - game.haveFun.list.snow.size='large'; - snow.maxFlake=200; - snow.flakeSize=10; - snow.fallSpeed=2; - if(this&&this.innerHTML){ - this.innerHTML='小雪'; + game.saveConfig("coinSnowSize", true); + } else { + game.haveFun.list.snow.size = "large"; + snow.maxFlake = 200; + snow.flakeSize = 10; + snow.fallSpeed = 2; + if (this && this.innerHTML) { + this.innerHTML = "小雪"; } - game.saveConfig('coinSnowSize',false); + game.saveConfig("coinSnowSize", false); } - } - if(lib.config.coinSnowSize){ + }; + if (lib.config.coinSnowSize) { game.haveFun.snowSize(); } snow.start(); } }, - firework:function(){ - if(game.haveFun.list.firework.running) return; - game.haveFun.list.firework.running=true; - if(game.haveFun.fireworkLoop){ + firework: function () { + if (game.haveFun.list.firework.running) return; + game.haveFun.list.firework.running = true; + if (game.haveFun.fireworkLoop) { game.haveFun.fireworkLoop(); - } - else{ + } else { // when animating on canvas, it is best to use requestAnimationFrame instead of setTimeout or setInterval // not supported in all browsers though and sometimes needs a prefix, so we need a shim - var requestAnimFrame = ( function() { - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - function( callback ) { - window.setTimeout( callback, 1000 / 60 ); - }; + var requestAnimFrame = (function () { + return ( + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + function (callback) { + window.setTimeout(callback, 1000 / 60); + } + ); })(); // now we will setup our basic variables for the demo - var canvas = document.createElement( 'canvas' ), - ctx = canvas.getContext( '2d' ), - // full screen dimensions - cw = ui.window.offsetWidth, - ch = ui.window.offsetHeight, - // firework collection - fireworks = [], - // particle collection - particles = [], - // starting hue - hue = 120, - // when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks - limiterTotal = 5, - limiterTick = 0, - // this will time the auto launches of fireworks, one launch per 80 loop ticks - timerTotal = 80, - timerTick = 0, - mousedown = false, - // mouse x coordinate, - mx, - // mouse y coordinate - my; + var canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"), + // full screen dimensions + cw = ui.window.offsetWidth, + ch = ui.window.offsetHeight, + // firework collection + fireworks = [], + // particle collection + particles = [], + // starting hue + hue = 120, + // when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks + limiterTotal = 5, + limiterTick = 0, + // this will time the auto launches of fireworks, one launch per 80 loop ticks + timerTotal = 80, + timerTick = 0, + mousedown = false, + // mouse x coordinate, + mx, + // mouse y coordinate + my; // set canvas dimensions canvas.width = cw; canvas.height = ch; ui.window.appendChild(canvas); - canvas.classList.add('fun'); - lib.onresize.push(function(){ - cw=ui.window.offsetWidth; - ch=ui.window.offsetHeight; + canvas.classList.add("fun"); + lib.onresize.push(function () { + cw = ui.window.offsetWidth; + ch = ui.window.offsetHeight; canvas.width = cw; canvas.height = ch; }); @@ -1095,19 +1288,21 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // now we are going to setup our function placeholders for the entire demo // get a random number within a range - var random=function( min, max ) { - return Math.random() * ( max - min ) + min; - } + var random = function (min, max) { + return Math.random() * (max - min) + min; + }; // calculate the distance between two points - var calculateDistance=function( p1x, p1y, p2x, p2y ) { + var calculateDistance = function (p1x, p1y, p2x, p2y) { var xDistance = p1x - p2x, - yDistance = p1y - p2y; - return Math.sqrt( Math.pow( xDistance, 2 ) + Math.pow( yDistance, 2 ) ); - } + yDistance = p1y - p2y; + return Math.sqrt( + Math.pow(xDistance, 2) + Math.pow(yDistance, 2) + ); + }; // create firework - var Firework=function( sx, sy, tx, ty ) { + var Firework = function (sx, sy, tx, ty) { // actual coordinates this.x = sx; this.y = sy; @@ -1118,32 +1313,37 @@ game.import('play',function(lib,game,ui,get,ai,_status){ this.tx = tx; this.ty = ty; // distance from starting point to target - this.distanceToTarget = calculateDistance( sx, sy, tx, ty ); + this.distanceToTarget = calculateDistance( + sx, + sy, + tx, + ty + ); this.distanceTraveled = 0; // track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trails this.coordinates = []; this.coordinateCount = 3; // populate initial coordinate collection with the current coordinates - while( this.coordinateCount-- ) { - this.coordinates.push( [ this.x, this.y ] ); + while (this.coordinateCount--) { + this.coordinates.push([this.x, this.y]); } - this.angle = Math.atan2( ty - sy, tx - sx ); + this.angle = Math.atan2(ty - sy, tx - sx); this.speed = 2; this.acceleration = 1.05; - this.brightness = random( 50, 70 ); + this.brightness = random(50, 70); // circle target indicator radius this.targetRadius = 1; - } + }; // update firework - Firework.prototype.update = function( index ) { + Firework.prototype.update = function (index) { // remove last item in coordinates array this.coordinates.pop(); // add current coordinates to the start of the array - this.coordinates.unshift( [ this.x, this.y ] ); + this.coordinates.unshift([this.x, this.y]); // cycle the circle target indicator radius - if( this.targetRadius < 8 ) { + if (this.targetRadius < 8) { this.targetRadius += 0.3; } else { this.targetRadius = 1; @@ -1153,104 +1353,141 @@ game.import('play',function(lib,game,ui,get,ai,_status){ this.speed *= this.acceleration; // get the current velocities based on angle and speed - var vx = Math.cos( this.angle ) * this.speed, - vy = Math.sin( this.angle ) * this.speed; + var vx = Math.cos(this.angle) * this.speed, + vy = Math.sin(this.angle) * this.speed; // how far will the firework have traveled with velocities applied? - this.distanceTraveled = calculateDistance( this.sx, this.sy, this.x + vx, this.y + vy ); + this.distanceTraveled = calculateDistance( + this.sx, + this.sy, + this.x + vx, + this.y + vy + ); // if the distance traveled, including velocities, is greater than the initial distance to the target, then the target has been reached - if( this.distanceTraveled >= this.distanceToTarget ) { - createParticles( this.tx, this.ty ); + if ( + this.distanceTraveled >= this.distanceToTarget + ) { + createParticles(this.tx, this.ty); // remove the firework, use the index passed into the update function to determine which to remove - fireworks.splice( index, 1 ); + fireworks.splice(index, 1); } else { // target not reached, keep traveling this.x += vx; this.y += vy; } - } + }; // draw firework - Firework.prototype.draw = function() { + Firework.prototype.draw = function () { ctx.beginPath(); // move to the last tracked coordinate in the set, then draw a line to the current x and y - ctx.moveTo( this.coordinates[ this.coordinates.length - 1][ 0 ], this.coordinates[ this.coordinates.length - 1][ 1 ] ); - ctx.lineTo( this.x, this.y ); - ctx.strokeStyle = 'hsl(' + hue + ', 100%, ' + this.brightness + '%)'; + ctx.moveTo( + this.coordinates[ + this.coordinates.length - 1 + ][0], + this.coordinates[this.coordinates.length - 1][1] + ); + ctx.lineTo(this.x, this.y); + ctx.strokeStyle = + "hsl(" + + hue + + ", 100%, " + + this.brightness + + "%)"; ctx.stroke(); ctx.beginPath(); // draw the target for this firework with a pulsing circle - ctx.arc( this.tx, this.ty, this.targetRadius, 0, Math.PI * 2 ); + ctx.arc( + this.tx, + this.ty, + this.targetRadius, + 0, + Math.PI * 2 + ); ctx.stroke(); - } + }; // create particle - var Particle=function( x, y ) { + var Particle = function (x, y) { this.x = x; this.y = y; // track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails this.coordinates = []; this.coordinateCount = 5; - while( this.coordinateCount-- ) { - this.coordinates.push( [ this.x, this.y ] ); + while (this.coordinateCount--) { + this.coordinates.push([this.x, this.y]); } // set a random angle in all possible directions, in radians - this.angle = random( 0, Math.PI * 2 ); - this.speed = random( 1, 10 ); + this.angle = random(0, Math.PI * 2); + this.speed = random(1, 10); // friction will slow the particle down this.friction = 0.95; // gravity will be applied and pull the particle down this.gravity = 1; // set the hue to a random number +-20 of the overall hue variable - this.hue = random( hue - 20, hue + 20 ); - this.brightness = random( 50, 80 ); + this.hue = random(hue - 20, hue + 20); + this.brightness = random(50, 80); this.alpha = 1; // set how fast the particle fades out - this.decay = random( 0.015, 0.03 ); - } + this.decay = random(0.015, 0.03); + }; // update particle - Particle.prototype.update = function( index ) { + Particle.prototype.update = function (index) { // remove last item in coordinates array this.coordinates.pop(); // add current coordinates to the start of the array - this.coordinates.unshift( [ this.x, this.y ] ); + this.coordinates.unshift([this.x, this.y]); // slow down the particle this.speed *= this.friction; // apply velocity - this.x += Math.cos( this.angle ) * this.speed; - this.y += Math.sin( this.angle ) * this.speed + this.gravity; + this.x += Math.cos(this.angle) * this.speed; + this.y += + Math.sin(this.angle) * this.speed + + this.gravity; // fade out the particle this.alpha -= this.decay; // remove the particle once the alpha is low enough, based on the passed in index - if( this.alpha <= this.decay ) { - particles.splice( index, 1 ); + if (this.alpha <= this.decay) { + particles.splice(index, 1); } - } + }; // draw particle - Particle.prototype.draw = function() { - ctx. beginPath(); + Particle.prototype.draw = function () { + ctx.beginPath(); // move to the last tracked coordinates in the set, then draw a line to the current x and y - ctx.moveTo( this.coordinates[ this.coordinates.length - 1 ][ 0 ], this.coordinates[ this.coordinates.length - 1 ][ 1 ] ); - ctx.lineTo( this.x, this.y ); - ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')'; + ctx.moveTo( + this.coordinates[ + this.coordinates.length - 1 + ][0], + this.coordinates[this.coordinates.length - 1][1] + ); + ctx.lineTo(this.x, this.y); + ctx.strokeStyle = + "hsla(" + + this.hue + + ", 100%, " + + this.brightness + + "%, " + + this.alpha + + ")"; ctx.stroke(); - } + }; // create particle group/explosion - var createParticles=function( x, y ) { + var createParticles = function (x, y) { // increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though var particleCount = 30; - while( particleCount-- ) { - particles.push( new Particle( x, y ) ); + while (particleCount--) { + particles.push(new Particle(x, y)); } - } + }; // main demo loop - var loop=function() { + var loop = function () { // if(lib.config.coin_free_playpackconfig&&!_status.imchoosing){ // canvas.style.display='none'; // } @@ -1258,13 +1495,12 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // canvas.style.display=''; // } // this function will run endlessly with requestAnimationFrame - if(!game.haveFun.list.firework.running){ - canvas.width=cw; - canvas.height=ch; + if (!game.haveFun.list.firework.running) { + canvas.width = cw; + canvas.height = ch; return; - } - else{ - requestAnimFrame( loop ); + } else { + requestAnimFrame(loop); } // increase the hue to get different colored fireworks over time @@ -1273,33 +1509,40 @@ game.import('play',function(lib,game,ui,get,ai,_status){ // normally, clearRect() would be used to clear the canvas // we want to create a trailing effect though // setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely - ctx.globalCompositeOperation = 'destination-out'; + ctx.globalCompositeOperation = "destination-out"; // decrease the alpha property to create more prominent trails - ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; - ctx.fillRect( 0, 0, cw, ch ); + ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; + ctx.fillRect(0, 0, cw, ch); // change the composite operation back to our main mode // lighter creates bright highlight points as the fireworks and particles overlap each other - ctx.globalCompositeOperation = 'lighter'; + ctx.globalCompositeOperation = "lighter"; // loop over each firework, draw it, update it var i = fireworks.length; - while( i-- ) { - fireworks[ i ].draw(); - fireworks[ i ].update( i ); + while (i--) { + fireworks[i].draw(); + fireworks[i].update(i); } // loop over each particle, draw it, update it var i = particles.length; - while( i-- ) { - particles[ i ].draw(); - particles[ i ].update( i ); + while (i--) { + particles[i].draw(); + particles[i].update(i); } // launch fireworks automatically to random coordinates, when the mouse isn't down - if( timerTick >= timerTotal ) { - if( !mousedown ) { + if (timerTick >= timerTotal) { + if (!mousedown) { // start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of the top half of the screen - fireworks.push( new Firework( cw / 2, ch, random( 0, cw ), random( 0, ch / 2 ) ) ); + fireworks.push( + new Firework( + cw / 2, + ch, + random(0, cw), + random(0, ch / 2) + ) + ); timerTick = 0; } } else { @@ -1307,69 +1550,95 @@ game.import('play',function(lib,game,ui,get,ai,_status){ } // limit the rate at which fireworks get launched when mouse is down - if( limiterTick >= limiterTotal ) { - if( mousedown ) { + if (limiterTick >= limiterTotal) { + if (mousedown) { // start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target - fireworks.push( new Firework( cw / 2, ch, mx, my ) ); + fireworks.push( + new Firework(cw / 2, ch, mx, my) + ); limiterTick = 0; } } else { limiterTick++; } - } + }; - - if(lib.config.touchscreen){ - ui.window.addEventListener( 'touchmove', function( e ) { - mx = e.touches[0].clientX/game.documentZoom - canvas.offsetLeft; - my = e.touches[0].clientY/game.documentZoom - canvas.offsetTop; - }); - ui.window.addEventListener( 'touchstart', function( e ) { - mousedown = true; - }); - ui.window.addEventListener( 'touchend', function( e ) { - mousedown = false; - }); - } - else{ + if (lib.config.touchscreen) { + ui.window.addEventListener( + "touchmove", + function (e) { + mx = + e.touches[0].clientX / + game.documentZoom - + canvas.offsetLeft; + my = + e.touches[0].clientY / + game.documentZoom - + canvas.offsetTop; + } + ); + ui.window.addEventListener( + "touchstart", + function (e) { + mousedown = true; + } + ); + ui.window.addEventListener( + "touchend", + function (e) { + mousedown = false; + } + ); + } else { // mouse event bindings // update the mouse coordinates on mousemove - ui.window.addEventListener( 'mousemove', function( e ) { - mx = e.pageX/game.documentZoom - canvas.offsetLeft; - my = e.pageY/game.documentZoom - canvas.offsetTop; - }); + ui.window.addEventListener( + "mousemove", + function (e) { + mx = + e.pageX / game.documentZoom - + canvas.offsetLeft; + my = + e.pageY / game.documentZoom - + canvas.offsetTop; + } + ); // toggle mousedown state and prevent canvas from being selected - ui.window.addEventListener( 'mousedown', function( e ) { - e.preventDefault(); - mousedown = true; - }); + ui.window.addEventListener( + "mousedown", + function (e) { + e.preventDefault(); + mousedown = true; + } + ); - ui.window.addEventListener( 'mouseup', function( e ) { + ui.window.addEventListener("mouseup", function (e) { e.preventDefault(); mousedown = false; }); } // once the window loads, we are ready for some fireworks! - game.haveFun.fireworkLoop=loop; - game.haveFun.fireworkStop=function(){ - game.haveFun.list.firework.running=false; - }, - loop(); + game.haveFun.fireworkLoop = loop; + (game.haveFun.fireworkStop = function () { + game.haveFun.list.firework.running = false; + }), + loop(); } - } - } + }, + }, + }, + help: { + 富甲天下: + "
              • 每完成一次对局,可获得一定数量的金币" + + "
              • 战斗胜利可额外获得20金币,每杀死一个敌人可获得10金币(托管无效)" + + "
              • 使用的武将越强,获得的金币数越少" + + "
              • 执行以下操作时,将扣除金币:
                • 作弊:20金币
                • 换将卡:3金币
                • " + + "自由选将:10金币
                • 手气卡:3金币
                • 换人:10金币
                " + + "
              • 金币可用于购买烟花等游戏特效(点击右上角的金币按钮)" + + "
              • 修改金币:
                game.changCoin" + + "
              • 默认下雪:
                game.haveFun.alwaysSnow", }, - help:{ - '富甲天下':'
                • 每完成一次对局,可获得一定数量的金币'+ - '
                • 战斗胜利可额外获得20金币,每杀死一个敌人可获得10金币(托管无效)'+ - '
                • 使用的武将越强,获得的金币数越少'+ - '
                • 执行以下操作时,将扣除金币:
                  • 作弊:20金币
                  • 换将卡:3金币
                  • '+ - '自由选将:10金币
                  • 手气卡:3金币
                  • 换人:10金币
                  '+ - '
                • 金币可用于购买烟花等游戏特效(点击右上角的金币按钮)'+ - '
                • 修改金币:
                  game.changCoin'+ - '
                • 默认下雪:
                  game.haveFun.alwaysSnow' - } }; }); diff --git a/extension/wuxing/extension.js b/extension/wuxing/extension.js index f398a3685..b5a428f38 100644 --- a/extension/wuxing/extension.js +++ b/extension/wuxing/extension.js @@ -1,229 +1,376 @@ -'use strict'; -game.import('play',function(lib,game,ui,get,ai,_status){ +import { lib, game, ui, get, ai, _status } from "../../noname.js"; +game.import("play", function () { return { - name:'wuxing', - arenaReady:function(){ - if(_status.connectMode) return; - lib.card.list.splice(Math.floor(lib.card.list.length*Math.random()),0,['spade',5,'wuxingpan']); - if(!_status.video){ + name: "wuxing", + arenaReady: function () { + if (_status.connectMode) return; + lib.card.list.splice( + Math.floor(lib.card.list.length * Math.random()), + 0, + ["spade", 5, "wuxingpan"] + ); + if (!_status.video) { lib.video.push({ - type:'play', - name:'wuxing' + type: "play", + name: "wuxing", }); } }, - video:function(){ - for(var i in this.translate){ - lib.translate[i]=this.translate[i]; + video: function () { + for (var i in this.translate) { + lib.translate[i] = this.translate[i]; } - for(var i in this.card){ - lib.card[i]=this.card[i]; + for (var i in this.card) { + lib.card[i] = this.card[i]; } - for(var i in this.skill){ - lib.skill[i]=this.skill[i]; + for (var i in this.skill) { + lib.skill[i] = this.skill[i]; } }, - element:{ - player:{ - init:function(player){ - if(player.node.wuxing){ + element: { + player: { + init: function (player) { + if (player.node.wuxing) { player.node.wuxing.remove(); } - if(_status.video||_status.connectMode) return; - var node=ui.create.div('.wunature',player); - var list=['metal','wood','water','fire','soil']; - var nature=list.randomGet(); - player.wunature=nature; - node.dataset.nature=nature; - node.innerHTML=get.translation(nature); - player.node.wuxing=node; - } + if (_status.video || _status.connectMode) return; + var node = ui.create.div(".wunature", player); + var list = ["metal", "wood", "water", "fire", "soil"]; + var nature = list.randomGet(); + player.wunature = nature; + node.dataset.nature = nature; + node.innerHTML = get.translation(nature); + player.node.wuxing = node; + }, }, - card:{ - init:function(card){ - if(_status.video||_status.connectMode) return; - if(card.name=='wuxingpan') return; - if(card.wunature) return; - if(Math.random()>(parseFloat(lib.config.wuxing_num_playpackconfig)||0)) return; - var node=ui.create.div('.wunature',card); - var list=['metal','wood','water','fire','soil']; - var nature=list.randomGet(); - card.wunature=nature; - node.dataset.nature=nature; - node.innerHTML=get.translation(nature); - card.node.wuxing=node; - if(!card.suit||!card.number){ - card.node.wuxing.style.display='none'; + card: { + init: function (card) { + if (_status.video || _status.connectMode) return; + if (card.name == "wuxingpan") return; + if (card.wunature) return; + if ( + Math.random() > + (parseFloat(lib.config.wuxing_num_playpackconfig) || 0) + ) + return; + var node = ui.create.div(".wunature", card); + var list = ["metal", "wood", "water", "fire", "soil"]; + var nature = list.randomGet(); + card.wunature = nature; + node.dataset.nature = nature; + node.innerHTML = get.translation(nature); + card.node.wuxing = node; + if (!card.suit || !card.number) { + card.node.wuxing.style.display = "none"; } - } - } + }, + }, }, - skill:{ - _shengke:{ - trigger:{target:'useCardToBegin'}, - forced:true, - popup:false, - filter:function(event,player){ - if(_status.connectMode) return false; - return event.card.wunature&&player.wunature; + skill: { + _shengke: { + trigger: { target: "useCardToBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + if (_status.connectMode) return false; + return event.card.wunature && player.wunature; }, - content:function(){ - switch(trigger.card.wunature){ - case 'metal': - switch(player.wunature){ - case 'wood': - if(player.countCards('he')){ - game.log(player,'被'+get.translation(trigger.card.wunature)+'属性的卡牌克制'); - player.chooseToDiscard('你被金属性卡牌克制,需弃置一张牌',true,'he').ai=get.disvalue;player.popup('金克木')}return; - case 'water': - game.log(player,'得到'+get.translation(trigger.card.wunature)+'属性卡牌的加成'); - player.draw();player.popup('金生水'); - return; - } - return; - case 'wood': - switch(player.wunature){ - case 'soil': - if(player.countCards('he')){ - game.log(player,'被'+get.translation(trigger.card.wunature)+'属性的卡牌克制'); - player.chooseToDiscard('你被木属性卡牌克制,需弃置一张牌',true,'he').ai=get.disvalue;player.popup('木克土')}return; - case 'fire': - game.log(player,'得到'+get.translation(trigger.card.wunature)+'属性卡牌的加成'); - player.draw();player.popup('木生火'); - return; - } - return; - case 'water': - switch(player.wunature){ - case 'fire': - if(player.countCards('he')){ - game.log(player,'被'+get.translation(trigger.card.wunature)+'属性的卡牌克制'); - player.chooseToDiscard('你被水属性卡牌克制,需弃置一张牌',true,'he').ai=get.disvalue;player.popup('水克火')}return; - case 'wood': - game.log(player,'得到'+get.translation(trigger.card.wunature)+'属性卡牌的加成'); - player.draw();player.popup('水生木'); - return; - } - return; - case 'fire': - switch(player.wunature){ - case 'metal': - if(player.countCards('he')){ - game.log(player,'被'+get.translation(trigger.card.wunature)+'属性的卡牌克制'); - player.chooseToDiscard('你被火属性卡牌克制,需弃置一张牌',true,'he').ai=get.disvalue;player.popup('火克金')}return; - case 'soil': - game.log(player,'得到'+get.translation(trigger.card.wunature)+'属性卡牌的加成'); - player.draw();player.popup('火生土'); - return; - } - return; - case 'soil': - switch(player.wunature){ - case 'water': - if(player.countCards('he')){ - game.log(player,'被'+get.translation(trigger.card.wunature)+'属性的卡牌克制'); - player.chooseToDiscard('你被土属性卡牌克制,需弃置一张牌',true,'he').ai=get.disvalue;player.popup('土克水')}return; - case 'metal': - game.log(player,'得到'+get.translation(trigger.card.wunature)+'属性卡牌的加成'); - player.draw();player.popup('土生金'); - return; - } - return; - } - }, - ai:{ - effect:{ - target:function(card,player,target,current){ - switch(card.wunature){ - case 'metal': - switch(target.wunature){ - case 'wood':if(current!=0) return [1,-0.3];return; - case 'water':if(current!=0) return [1,0.3];return; - } - return; - case 'wood': - switch(target.wunature){ - case 'soil':if(current!=0) return [1,-0.3];return; - case 'fire':if(current!=0) return [1,0.3];return; - } - return; - case 'water': - switch(target.wunature){ - case 'fire':if(current!=0) return [1,-0.3];return; - case 'wood':if(current!=0) return [1,0.3];return; - } - return; - case 'fire': - switch(target.wunature){ - case 'metal':if(current!=0) return [1,-0.3];return; - case 'soil':if(current!=0) return [1,0.3];return; - } - return; - case 'soil': - switch(target.wunature){ - case 'water':if(current!=0) return [1,-0.3];return; - case 'metal':if(current!=0) return [1,0.3];return; - } - return; + content: function () { + switch (trigger.card.wunature) { + case "metal": + switch (player.wunature) { + case "wood": + if (player.countCards("he")) { + game.log( + player, + "被" + + get.translation( + trigger.card.wunature + ) + + "属性的卡牌克制" + ); + player.chooseToDiscard( + "你被金属性卡牌克制,需弃置一张牌", + true, + "he" + ).ai = get.disvalue; + player.popup("金克木"); + } + return; + case "water": + game.log( + player, + "得到" + + get.translation( + trigger.card.wunature + ) + + "属性卡牌的加成" + ); + player.draw(); + player.popup("金生水"); + return; } - } + return; + case "wood": + switch (player.wunature) { + case "soil": + if (player.countCards("he")) { + game.log( + player, + "被" + + get.translation( + trigger.card.wunature + ) + + "属性的卡牌克制" + ); + player.chooseToDiscard( + "你被木属性卡牌克制,需弃置一张牌", + true, + "he" + ).ai = get.disvalue; + player.popup("木克土"); + } + return; + case "fire": + game.log( + player, + "得到" + + get.translation( + trigger.card.wunature + ) + + "属性卡牌的加成" + ); + player.draw(); + player.popup("木生火"); + return; + } + return; + case "water": + switch (player.wunature) { + case "fire": + if (player.countCards("he")) { + game.log( + player, + "被" + + get.translation( + trigger.card.wunature + ) + + "属性的卡牌克制" + ); + player.chooseToDiscard( + "你被水属性卡牌克制,需弃置一张牌", + true, + "he" + ).ai = get.disvalue; + player.popup("水克火"); + } + return; + case "wood": + game.log( + player, + "得到" + + get.translation( + trigger.card.wunature + ) + + "属性卡牌的加成" + ); + player.draw(); + player.popup("水生木"); + return; + } + return; + case "fire": + switch (player.wunature) { + case "metal": + if (player.countCards("he")) { + game.log( + player, + "被" + + get.translation( + trigger.card.wunature + ) + + "属性的卡牌克制" + ); + player.chooseToDiscard( + "你被火属性卡牌克制,需弃置一张牌", + true, + "he" + ).ai = get.disvalue; + player.popup("火克金"); + } + return; + case "soil": + game.log( + player, + "得到" + + get.translation( + trigger.card.wunature + ) + + "属性卡牌的加成" + ); + player.draw(); + player.popup("火生土"); + return; + } + return; + case "soil": + switch (player.wunature) { + case "water": + if (player.countCards("he")) { + game.log( + player, + "被" + + get.translation( + trigger.card.wunature + ) + + "属性的卡牌克制" + ); + player.chooseToDiscard( + "你被土属性卡牌克制,需弃置一张牌", + true, + "he" + ).ai = get.disvalue; + player.popup("土克水"); + } + return; + case "metal": + game.log( + player, + "得到" + + get.translation( + trigger.card.wunature + ) + + "属性卡牌的加成" + ); + player.draw(); + player.popup("土生金"); + return; + } + return; } - } + }, + ai: { + effect: { + target: function (card, player, target, current) { + switch (card.wunature) { + case "metal": + switch (target.wunature) { + case "wood": + if (current != 0) return [1, -0.3]; + return; + case "water": + if (current != 0) return [1, 0.3]; + return; + } + return; + case "wood": + switch (target.wunature) { + case "soil": + if (current != 0) return [1, -0.3]; + return; + case "fire": + if (current != 0) return [1, 0.3]; + return; + } + return; + case "water": + switch (target.wunature) { + case "fire": + if (current != 0) return [1, -0.3]; + return; + case "wood": + if (current != 0) return [1, 0.3]; + return; + } + return; + case "fire": + switch (target.wunature) { + case "metal": + if (current != 0) return [1, -0.3]; + return; + case "soil": + if (current != 0) return [1, 0.3]; + return; + } + return; + case "soil": + switch (target.wunature) { + case "water": + if (current != 0) return [1, -0.3]; + return; + case "metal": + if (current != 0) return [1, 0.3]; + return; + } + return; + } + }, + }, + }, }, - wuxingpan_skill:{ - enable:'phaseUse', - usable:1, - filterCard:true, - lose:false, - prompt:'选择一张手牌永久改变其五行属性', - content:function(){ - "step 0" - player.chooseControl('metal','wood','water','fire','soil'); - "step 1" - var card=cards[0]; - if(!card.node.wuxing){ - card.node.wuxing=ui.create.div('.wunature',card); + wuxingpan_skill: { + enable: "phaseUse", + usable: 1, + filterCard: true, + lose: false, + prompt: "选择一张手牌永久改变其五行属性", + content: function () { + "step 0"; + player.chooseControl( + "metal", + "wood", + "water", + "fire", + "soil" + ); + ("step 1"); + var card = cards[0]; + if (!card.node.wuxing) { + card.node.wuxing = ui.create.div(".wunature", card); } - - card.wunature=result.control; - card.node.wuxing.dataset.nature=result.control; - card.node.wuxing.innerHTML=get.translation(result.control); - } - } + card.wunature = result.control; + card.node.wuxing.dataset.nature = result.control; + card.node.wuxing.innerHTML = get.translation( + result.control + ); + }, + }, }, - card:{ - wuxingpan:{ - type:'equip', - subtype:'equip5', - skills:['wuxingpan_skill'], - fullskin:true - } + card: { + wuxingpan: { + type: "equip", + subtype: "equip5", + skills: ["wuxingpan_skill"], + fullskin: true, + }, }, - translate:{ - metal:'金', - wood:'木', - water:'水', - soil:'土', - goldColor:'rgb(236,236,130)', - woodColor:'rgb(149,202,147)', - waterColor:'rgb(150,88,201)', - fireColor:'rgb(236,132,106)', - soilColor:'rgb(201,159,98)', - goldColor2:'rgba(236,236,57,0.3)', - woodColor2:'rgba(33,155,10,0.3)', - waterColor2:'rgba(29,156,255,0.3)', - fireColor2:'rgba(255,51,0,0.3)', - soilColor2:'rgba(163,98,0,0.3)', - wuxingpan:'五行盘', - wuxingpan_skill:'五行', - wuxingpan_skill_info:'出牌阶段限一次,你可以永久改变一张手牌的五行属性', - wuxingpan_info:'出牌阶段限一次,你可以永久改变一张手牌的五行属性', + translate: { + metal: "金", + wood: "木", + water: "水", + soil: "土", + goldColor: "rgb(236,236,130)", + woodColor: "rgb(149,202,147)", + waterColor: "rgb(150,88,201)", + fireColor: "rgb(236,132,106)", + soilColor: "rgb(201,159,98)", + goldColor2: "rgba(236,236,57,0.3)", + woodColor2: "rgba(33,155,10,0.3)", + waterColor2: "rgba(29,156,255,0.3)", + fireColor2: "rgba(255,51,0,0.3)", + soilColor2: "rgba(163,98,0,0.3)", + wuxingpan: "五行盘", + wuxingpan_skill: "五行", + wuxingpan_skill_info: + "出牌阶段限一次,你可以永久改变一张手牌的五行属性", + wuxingpan_info: "出牌阶段限一次,你可以永久改变一张手牌的五行属性", + }, + help: { + 五行生克: + "
                  • 每名角色在游戏开始时随机获得一个属性
                  • 牌堆中三分之一的牌会随机获得一个属性
                  • 当一名成为相克属性卡牌的目标时," + + "须弃置一张牌
                  • 当一名角色成为相生的卡牌的目标时,须摸一张牌" + + "
                  • 金克木,金生水;
                    木克土,木生火;
                    水克火,水生木;
                    火克金,火生土;
                    土克水,土生金", }, - help:{ - '五行生克':'
                    • 每名角色在游戏开始时随机获得一个属性
                    • 牌堆中三分之一的牌会随机获得一个属性
                    • 当一名成为相克属性卡牌的目标时,'+ - '须弃置一张牌
                    • 当一名角色成为相生的卡牌的目标时,须摸一张牌'+ - '
                    • 金克木,金生水;
                      木克土,木生火;
                      水克火,水生木;
                      火克金,火生土;
                      土克水,土生金' - } }; }); diff --git a/game/NoSleep.js b/game/NoSleep.js index eee50a69d..7195991a7 100644 --- a/game/NoSleep.js +++ b/game/NoSleep.js @@ -1,192 +1,192 @@ -/*! NoSleep.js v0.9.0 - git.io/vfn01 - Rich Tibbett - MIT license */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["NoSleep"] = factory(); - else - root["NoSleep"] = factory(); -})(typeof self !== 'undefined' ? self : this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var _require = __webpack_require__(1), - webm = _require.webm, - mp4 = _require.mp4; - -// Detect iOS browsers < version 10 - - -var oldIOS = typeof navigator !== 'undefined' && parseFloat(('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1]).replace('undefined', '3_2').replace('_', '.').replace('_', '')) < 10 && !window.MSStream; - -var NoSleep = function () { - function NoSleep() { - var _this = this; - - _classCallCheck(this, NoSleep); - - if (oldIOS) { - this.noSleepTimer = null; - } else { - // Set up no sleep video element - this.noSleepVideo = document.createElement('video'); - - this.noSleepVideo.setAttribute('muted', ''); - this.noSleepVideo.setAttribute('title', 'No Sleep'); - this.noSleepVideo.setAttribute('playsinline', ''); - - this._addSourceToVideo(this.noSleepVideo, 'webm', webm); - this._addSourceToVideo(this.noSleepVideo, 'mp4', mp4); - - this.noSleepVideo.addEventListener('loadedmetadata', function () { - if (_this.noSleepVideo.duration <= 1) { - // webm source - _this.noSleepVideo.setAttribute('loop', ''); - } else { - // mp4 source - _this.noSleepVideo.addEventListener('timeupdate', function () { - if (_this.noSleepVideo.currentTime > 0.5) { - _this.noSleepVideo.currentTime = Math.random(); - } - }); - } - }); - } - } - - _createClass(NoSleep, [{ - key: '_addSourceToVideo', - value: function _addSourceToVideo(element, type, dataURI) { - var source = document.createElement('source'); - source.src = dataURI; - source.type = 'video/' + type; - element.appendChild(source); - } - }, { - key: 'enable', - value: function enable() { - if (oldIOS) { - this.disable(); - console.warn('\n NoSleep enabled for older iOS devices. This can interrupt\n active or long-running network requests from completing successfully.\n See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n '); - this.noSleepTimer = window.setInterval(function () { - if (!document.hidden) { - window.location.href = window.location.href.split('#')[0]; - window.setTimeout(window.stop, 0); - } - }, 15000); - } else { - this.noSleepVideo.play(); - } - } - }, { - key: 'disable', - value: function disable() { - if (oldIOS) { - if (this.noSleepTimer) { - console.warn('\n NoSleep now disabled for older iOS devices.\n '); - window.clearInterval(this.noSleepTimer); - this.noSleepTimer = null; - } - } else { - this.noSleepVideo.pause(); - } - } - }]); - - return NoSleep; -}(); - -; - -module.exports = NoSleep; - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - webm: 'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA=', - mp4: 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA=' -}; - -/***/ }) -/******/ ]); -}); \ No newline at end of file +/*! NoSleep.js v0.9.0 - git.io/vfn01 - Rich Tibbett - MIT license */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["NoSleep"] = factory(); + else + root["NoSleep"] = factory(); +})(typeof self !== 'undefined' ? self : this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var _require = __webpack_require__(1), + webm = _require.webm, + mp4 = _require.mp4; + +// Detect iOS browsers < version 10 + + +var oldIOS = typeof navigator !== 'undefined' && parseFloat(('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1]).replace('undefined', '3_2').replace('_', '.').replace('_', '')) < 10 && !window.MSStream; + +var NoSleep = function () { + function NoSleep() { + var _this = this; + + _classCallCheck(this, NoSleep); + + if (oldIOS) { + this.noSleepTimer = null; + } else { + // Set up no sleep video element + this.noSleepVideo = document.createElement('video'); + + this.noSleepVideo.setAttribute('muted', ''); + this.noSleepVideo.setAttribute('title', 'No Sleep'); + this.noSleepVideo.setAttribute('playsinline', ''); + + this._addSourceToVideo(this.noSleepVideo, 'webm', webm); + this._addSourceToVideo(this.noSleepVideo, 'mp4', mp4); + + this.noSleepVideo.addEventListener('loadedmetadata', function () { + if (_this.noSleepVideo.duration <= 1) { + // webm source + _this.noSleepVideo.setAttribute('loop', ''); + } else { + // mp4 source + _this.noSleepVideo.addEventListener('timeupdate', function () { + if (_this.noSleepVideo.currentTime > 0.5) { + _this.noSleepVideo.currentTime = Math.random(); + } + }); + } + }); + } + } + + _createClass(NoSleep, [{ + key: '_addSourceToVideo', + value: function _addSourceToVideo(element, type, dataURI) { + var source = document.createElement('source'); + source.src = dataURI; + source.type = 'video/' + type; + element.appendChild(source); + } + }, { + key: 'enable', + value: function enable() { + if (oldIOS) { + this.disable(); + console.warn('\n NoSleep enabled for older iOS devices. This can interrupt\n active or long-running network requests from completing successfully.\n See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n '); + this.noSleepTimer = window.setInterval(function () { + if (!document.hidden) { + window.location.href = window.location.href.split('#')[0]; + window.setTimeout(window.stop, 0); + } + }, 15000); + } else { + this.noSleepVideo.play(); + } + } + }, { + key: 'disable', + value: function disable() { + if (oldIOS) { + if (this.noSleepTimer) { + console.warn('\n NoSleep now disabled for older iOS devices.\n '); + window.clearInterval(this.noSleepTimer); + this.noSleepTimer = null; + } + } else { + this.noSleepVideo.pause(); + } + } + }]); + + return NoSleep; +}(); + +; + +module.exports = NoSleep; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + webm: 'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA=', + mp4: 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA=' +}; + +/***/ }) +/******/ ]); +}); diff --git a/game/asset.js b/game/asset.js index 80a424b5c..d118d75a4 100644 --- a/game/asset.js +++ b/game/asset.js @@ -1,9610 +1,9756 @@ -window.noname_asset_list=[ - 'v1.10.10', - /*audio start*/ - 'audio/background/aozhan_chaoming.mp3', - 'audio/background/aozhan_online.mp3', - 'audio/background/aozhan_rewrite.mp3', - 'audio/background/music_danji.mp3', - 'audio/background/music_default.mp3', - 'audio/background/music_diaochan.mp3', - 'audio/background/music_jifeng.mp3', - 'audio/background/music_jilve.mp3', - 'audio/background/music_phliosophy.mp3', - 'audio/background/music_shezhan.mp3', - /*cardaudio start*/ - 'audio/card/default.mp3', - - 'audio/card/female/caomu.mp3', - 'audio/card/female/chiling.mp3', - 'audio/card/female/diaohulishan.mp3', - 'audio/card/female/fulei.mp3', - 'audio/card/female/huoshaolianying.mp3', - 'audio/card/female/jinchan.mp3', - 'audio/card/female/lianjunshengyan.mp3', - 'audio/card/female/lulitongxin.mp3', - 'audio/card/female/qijia.mp3', - 'audio/card/female/shengdong.mp3', - 'audio/card/female/shuiyanqijun.mp3', - 'audio/card/female/xietianzi.mp3', - 'audio/card/female/zengbin.mp3', - 'audio/card/female/chuqibuyi.mp3', - 'audio/card/female/dongzhuxianji.mp3', - 'audio/card/female/sha_ice.mp3', - 'audio/card/female/suijiyingbian.mp3', - 'audio/card/female/zhujinqiyuan.mp3', - 'audio/card/female/binglinchengxiax.mp3', - 'audio/card/female/chenghuodajie.mp3', - 'audio/card/female/dz_mantianguohai.mp3', - 'audio/card/female/guaguliaodu.mp3', - 'audio/card/female/gz_guguoanbang.mp3', - 'audio/card/female/gz_haolingtianxia.mp3', - 'audio/card/female/gz_kefuzhongyuan.mp3', - 'audio/card/female/gz_wenheluanwu.mp3', - 'audio/card/female/kaihua.mp3', - 'audio/card/female/qizhengxiangsheng.mp3', - 'audio/card/female/sha_stab.mp3', - 'audio/card/female/tiaojiyanmei.mp3', - 'audio/card/female/tuixinzhifu.mp3', - - 'audio/card/female/bagua.mp3', - 'audio/card/female/baiyin.mp3', - 'audio/card/female/chitu.mp3', - 'audio/card/female/cixiong.mp3', - 'audio/card/female/dawan.mp3', - 'audio/card/female/dilu.mp3', - 'audio/card/female/fangtian.mp3', - 'audio/card/female/guanshi.mp3', - 'audio/card/female/guding.mp3', - 'audio/card/female/hanbing.mp3', - 'audio/card/female/hualiu.mp3', - 'audio/card/female/jueying.mp3', - 'audio/card/female/muniu.mp3', - 'audio/card/female/qilin.mp3', - 'audio/card/female/qinggang.mp3', - 'audio/card/female/qinglong.mp3', - 'audio/card/female/renwang.mp3', - 'audio/card/female/sanjian.mp3', - 'audio/card/female/tengjia.mp3', - 'audio/card/female/wuliu.mp3', - 'audio/card/female/zhangba.mp3', - 'audio/card/female/zhuahuang.mp3', - 'audio/card/female/zhuge.mp3', - 'audio/card/female/zhuque.mp3', - 'audio/card/female/zixin.mp3', - - 'audio/card/female/bingliang.mp3', - 'audio/card/female/guohe.mp3', - 'audio/card/female/huogong.mp3', - 'audio/card/female/jiedao.mp3', - 'audio/card/female/jiu.mp3', - 'audio/card/female/juedou.mp3', - 'audio/card/female/lebu.mp3', - 'audio/card/female/nanman.mp3', - 'audio/card/female/sha.mp3', - 'audio/card/female/sha_fire.mp3', - 'audio/card/female/sha_thunder.mp3', - 'audio/card/female/shan.mp3', - 'audio/card/female/shandian.mp3', - 'audio/card/female/shunshou.mp3', - 'audio/card/female/taoyuan.mp3', - 'audio/card/female/tiesuo.mp3', - 'audio/card/female/wanjian.mp3', - 'audio/card/female/wugu.mp3', - 'audio/card/female/wuxie.mp3', - 'audio/card/female/wuzhong.mp3', - 'audio/card/female/yiyi.mp3', - 'audio/card/female/yuanjiao.mp3', - 'audio/card/female/zhibi.mp3', - - 'audio/card/male/caomu.mp3', - 'audio/card/male/chiling.mp3', - 'audio/card/male/diaohulishan.mp3', - 'audio/card/male/fulei.mp3', - 'audio/card/male/huoshaolianying.mp3', - 'audio/card/male/jinchan.mp3', - 'audio/card/male/lianjunshengyan.mp3', - 'audio/card/male/lulitongxin.mp3', - 'audio/card/male/qijia.mp3', - 'audio/card/male/shengdong.mp3', - 'audio/card/male/shuiyanqijun.mp3', - 'audio/card/male/xietianzi.mp3', - 'audio/card/male/zengbin.mp3', - 'audio/card/male/chuqibuyi.mp3', - 'audio/card/male/dongzhuxianji.mp3', - 'audio/card/male/sha_ice.mp3', - 'audio/card/male/suijiyingbian.mp3', - 'audio/card/male/zhujinqiyuan.mp3', - 'audio/card/male/binglinchengxiax.mp3', - 'audio/card/male/chenghuodajie.mp3', - 'audio/card/male/dz_mantianguohai.mp3', - 'audio/card/male/guaguliaodu.mp3', - 'audio/card/male/gz_guguoanbang.mp3', - 'audio/card/male/gz_haolingtianxia.mp3', - 'audio/card/male/gz_kefuzhongyuan.mp3', - 'audio/card/male/gz_wenheluanwu.mp3', - 'audio/card/male/kaihua.mp3', - 'audio/card/male/qizhengxiangsheng.mp3', - 'audio/card/male/sha_stab.mp3', - 'audio/card/male/tiaojiyanmei.mp3', - 'audio/card/male/tuixinzhifu.mp3', - - 'audio/card/male/bagua.mp3', - 'audio/card/male/baiyin.mp3', - 'audio/card/male/chitu.mp3', - 'audio/card/male/cixiong.mp3', - 'audio/card/male/dawan.mp3', - 'audio/card/male/dilu.mp3', - 'audio/card/male/fangtian.mp3', - 'audio/card/male/guanshi.mp3', - 'audio/card/male/guding.mp3', - 'audio/card/male/hanbing.mp3', - 'audio/card/male/hualiu.mp3', - 'audio/card/male/jueying.mp3', - 'audio/card/male/muniu.mp3', - 'audio/card/male/qilin.mp3', - 'audio/card/male/qinggang.mp3', - 'audio/card/male/qinglong.mp3', - 'audio/card/male/renwang.mp3', - 'audio/card/male/sanjian.mp3', - 'audio/card/male/tengjia.mp3', - 'audio/card/male/wuliu.mp3', - 'audio/card/male/zhangba.mp3', - 'audio/card/male/zhuahuang.mp3', - 'audio/card/male/zhuge.mp3', - 'audio/card/male/zhuque.mp3', - 'audio/card/male/zixin.mp3', - - 'audio/card/male/bingliang.mp3', - 'audio/card/male/guohe.mp3', - 'audio/card/male/huogong.mp3', - 'audio/card/male/jiedao.mp3', - 'audio/card/male/jiu.mp3', - 'audio/card/male/juedou.mp3', - 'audio/card/male/lebu.mp3', - 'audio/card/male/nanman.mp3', - 'audio/card/male/sha.mp3', - 'audio/card/male/sha_fire.mp3', - 'audio/card/male/sha_thunder.mp3', - 'audio/card/male/shan.mp3', - 'audio/card/male/shandian.mp3', - 'audio/card/male/shunshou.mp3', - 'audio/card/male/taoyuan.mp3', - 'audio/card/male/tiesuo.mp3', - 'audio/card/male/wanjian.mp3', - 'audio/card/male/wugu.mp3', - 'audio/card/male/wuxie.mp3', - 'audio/card/male/wuzhong.mp3', - 'audio/card/male/yiyi.mp3', - 'audio/card/male/yuanjiao.mp3', - 'audio/card/male/zhibi.mp3', - /*cardaudio end*/ - - /*dieaudio begin*/ - 'audio/die/ahuinan.mp3', - 'audio/die/bailingyun.mp3', - 'audio/die/baosanniang.mp3', - 'audio/die/beimihu.mp3', - 'audio/die/bianfuren.mp3', - 'audio/die/bianxi.mp3', - 'audio/die/boss_lvbu1.mp3', - 'audio/die/boss_lvbu2.mp3', - 'audio/die/boss_lvbu3.mp3', - 'audio/die/boss_wuguanwang.mp3', - 'audio/die/boss_zhaoyun.mp3', - 'audio/die/bulianshi.mp3', - 'audio/die/buzhi.mp3', - 'audio/die/caesar.mp3', - 'audio/die/caifuren.mp3', - 'audio/die/caimaozhangyun.mp3', - 'audio/die/caiwenji.mp3', - 'audio/die/caiyong.mp3', - 'audio/die/caizhaoji.mp3', - 'audio/die/caizhenji.mp3', - 'audio/die/caoang.mp3', - 'audio/die/caoanmin.mp3', - 'audio/die/caocao.mp3', - 'audio/die/caochong.mp3', - 'audio/die/caochun.mp3', - 'audio/die/caohong.mp3', - 'audio/die/caohua.mp3', - 'audio/die/caojie.mp3', - 'audio/die/caojinyu.mp3', - 'audio/die/caomao.mp3', - 'audio/die/caopi.mp3', - 'audio/die/caoren.mp3', - 'audio/die/caorui.mp3', - 'audio/die/caoshuang.mp3', - 'audio/die/caosong.mp3', - 'audio/die/caoxi.mp3', - 'audio/die/caoxian.mp3', - 'audio/die/caoxiancaohua.mp3', - 'audio/die/caoxing.mp3', - 'audio/die/caoxiu.mp3', - 'audio/die/caoyi.mp3', - 'audio/die/caoying.mp3', - 'audio/die/caoyu.mp3', - 'audio/die/caozhang.mp3', - 'audio/die/caozhen.mp3', - 'audio/die/caozhi.mp3', - 'audio/die/cenhun.mp3', - 'audio/die/cheliji.mp3', - 'audio/die/chendao.mp3', - 'audio/die/chendeng.mp3', - 'audio/die/chendong.mp3', - 'audio/die/chengbing.mp3', - 'audio/die/chengjichengcui.mp3', - 'audio/die/chengong.mp3', - 'audio/die/chengpu.mp3', - 'audio/die/chengui.mp3', - 'audio/die/chengyu.mp3', - 'audio/die/chenjiao.mp3', - 'audio/die/chenlin.mp3', - 'audio/die/chenqun.mp3', - 'audio/die/chenshi.mp3', - 'audio/die/chentai.mp3', - 'audio/die/chenwudongxi.mp3', - 'audio/die/chunyuqiong.mp3', - 'audio/die/clan_hanrong.mp3', - 'audio/die/clan_hanshao.mp3', - 'audio/die/clan_wanghun.mp3', - 'audio/die/clan_wangling.mp3', - 'audio/die/clan_wanglun.mp3', - 'audio/die/clan_wangyun.mp3', - 'audio/die/clan_wuban.mp3', - 'audio/die/clan_wukuang.mp3', - 'audio/die/clan_wuxian.mp3', - 'audio/die/clan_xuncai.mp3', - 'audio/die/clan_xuncan.mp3', - 'audio/die/clan_xunchen.mp3', - 'audio/die/clan_xunshu.mp3', - 'audio/die/clan_xunyou.mp3', - 'audio/die/clan_zhonghui.mp3', - 'audio/die/clan_zhongyan.mp3', - 'audio/die/clan_zhongyu.mp3', - 'audio/die/cuimao.mp3', - 'audio/die/cuiyan.mp3', - 'audio/die/daqiao.mp3', - 'audio/die/daxiaoqiao.mp3', - 'audio/die/db_wenyang.mp3', - 'audio/die/dc_bulianshi.mp3', - 'audio/die/dc_caiyang.mp3', - 'audio/die/dc_caoshuang.mp3', - 'audio/die/dc_caozhi.mp3', - 'audio/die/dc_chenqun.mp3', - 'audio/die/dc_dengzhi.mp3', - 'audio/die/dc_dongzhao.mp3', - 'audio/die/dc_duyu.mp3', - 'audio/die/dc_gaolan.mp3', - 'audio/die/dc_gongsunzan.mp3', - 'audio/die/dc_huangchengyan.mp3', - 'audio/die/dc_huanghao.mp3', - 'audio/die/dc_huangquan.mp3', - 'audio/die/dc_huangzu.mp3', - 'audio/die/dc_huban.mp3', - 'audio/die/dc_hujinding.mp3', - 'audio/die/dc_huojun.mp3', - 'audio/die/dc_jiachong.mp3', - 'audio/die/dc_jiben.mp3', - 'audio/die/dc_jiling.mp3', - 'audio/die/dc_liru.mp3', - 'audio/die/dc_liuba.mp3', - 'audio/die/dc_liuli.mp3', - 'audio/die/dc_liuye.mp3', - 'audio/die/dc_liuyu.mp3', - 'audio/die/dc_luotong.mp3', - 'audio/die/dc_lvkuanglvxiang.mp3', - 'audio/die/dc_mengda.mp3', - 'audio/die/dc_ruiji.mp3', - 'audio/die/dc_sb_lusu.mp3', - 'audio/die/dc_sb_simayi.mp3', - 'audio/die/dc_sb_simayi_shadow.mp3', - 'audio/die/dc_sb_zhouyu.mp3', - 'audio/die/dc_sp_jiaxu.mp3', - 'audio/die/dc_sunchen.mp3', - 'audio/die/dc_sunhanhua.mp3', - 'audio/die/dc_sunru.mp3', - 'audio/die/dc_sunziliufang.mp3', - 'audio/die/dc_tengfanglan.mp3', - 'audio/die/dc_wangchang.mp3', - 'audio/die/dc_wangjun.mp3', - 'audio/die/dc_wangyun.mp3', - 'audio/die/dc_wuban.mp3', - 'audio/die/dc_xujing.mp3', - 'audio/die/dc_xushu.mp3', - 'audio/die/dc_yangbiao.mp3', - 'audio/die/dc_yanghu.mp3', - 'audio/die/dc_yuejiu.mp3', - 'audio/die/dc_zhangmancheng.mp3', - 'audio/die/dc_zhaotongzhaoguang.mp3', - 'audio/die/dc_zhaoyǎn.mp3', - 'audio/die/dc_zhaoyun.mp3', - 'audio/die/dc_zhouxuān.mp3', - 'audio/die/dc_zhuling.mp3', - 'audio/die/dengai.mp3', - 'audio/die/dengshizai.mp3', - 'audio/die/dengzhi.mp3', - 'audio/die/dengzhong.mp3', - 'audio/die/dianwei.mp3', - 'audio/die/diaochan.mp3', - 'audio/die/dingfeng.mp3', - 'audio/die/dingshangwan.mp3', - 'audio/die/dingyuan.mp3', - 'audio/die/dongbai.mp3', - 'audio/die/dongcheng.mp3', - 'audio/die/dongguiren.mp3', - 'audio/die/dongtuna.mp3', - 'audio/die/dongwan.mp3', - 'audio/die/dongxie.mp3', - 'audio/die/dongyun.mp3', - 'audio/die/dongzhao.mp3', - 'audio/die/dongzhuo.mp3', - 'audio/die/duanjiong.mp3', - 'audio/die/duanqiaoxiao.mp3', - 'audio/die/duanwei.mp3', - 'audio/die/dufuren.mp3', - 'audio/die/duji.mp3', - 'audio/die/dukui.mp3', - 'audio/die/duosidawang.mp3', - 'audio/die/duxi.mp3', - 'audio/die/duyu.mp3', - 'audio/die/erqiao.mp3', - 'audio/die/erzhang.mp3', - 'audio/die/fanchou.mp3', - 'audio/die/fanjiangzhangda.mp3', - 'audio/die/fanyufeng.mp3', - 'audio/die/fazheng.mp3', - 'audio/die/feiyi.mp3', - 'audio/die/fengfang.mp3', - 'audio/die/fengfangnv.mp3', - 'audio/die/fengxi.mp3', - 'audio/die/fuhuanghou.mp3', - 'audio/die/furong.mp3', - 'audio/die/furongfuqian.mp3', - 'audio/die/fuwan.mp3', - 'audio/die/ganfuren.mp3', - 'audio/die/ganfurenmifuren.mp3', - 'audio/die/ganning.mp3', - 'audio/die/gaogan.mp3', - 'audio/die/gaolan.mp3', - 'audio/die/gaoshun.mp3', - 'audio/die/gaoxiang.mp3', - 'audio/die/gexuan.mp3', - 'audio/die/gongsundu.mp3', - 'audio/die/gongsunkang.mp3', - 'audio/die/gongsunyuan.mp3', - 'audio/die/gongsunzan.mp3', - 'audio/die/guanhai.mp3', - 'audio/die/guanlu.mp3', - 'audio/die/guanning.mp3', - 'audio/die/guānning.mp3', - 'audio/die/guanping.mp3', - 'audio/die/guanqiujian.mp3', - 'audio/die/guanxingzhangbao.mp3', - 'audio/die/guanyinping.mp3', - 'audio/die/guanyu.mp3', - 'audio/die/guanzhang.mp3', - 'audio/die/guohuai.mp3', - 'audio/die/guohuanghou.mp3', - 'audio/die/guojia.mp3', - 'audio/die/guosi.mp3', - 'audio/die/guotu.mp3', - 'audio/die/guotufengji.mp3', - 'audio/die/guozhao.mp3', - 'audio/die/guyong.mp3', - 'audio/die/guzhielai.mp3', - 'audio/die/gz_dc_yanghu.mp3', - 'audio/die/gz_dengzhi.mp3', - 'audio/die/gz_gongsunyuan.mp3', - 'audio/die/gz_huangzu.mp3', - 'audio/die/gz_jun_caocao.mp3', - 'audio/die/gz_jun_liubei.mp3', - 'audio/die/gz_jun_sunquan.mp3', - 'audio/die/gz_jun_zhangjiao.mp3', - 'audio/die/gz_liuba.mp3', - 'audio/die/gz_liuqi.mp3', - 'audio/die/gz_lukang.mp3', - 'audio/die/gz_luxun.mp3', - 'audio/die/gz_miheng.mp3', - 'audio/die/gz_panjun.mp3', - 'audio/die/gz_pengyang.mp3', - 'audio/die/gz_re_xushu.mp3', - 'audio/die/gz_shixie.mp3', - 'audio/die/gz_simazhao.mp3', - 'audio/die/gz_sunchen.mp3', - 'audio/die/gz_tangzi.mp3', - 'audio/die/gz_wenqin.mp3', - 'audio/die/gz_wujing.mp3', - 'audio/die/gz_xf_sufei.mp3', - 'audio/die/gz_xiahouba.mp3', - 'audio/die/gz_xuyou.mp3', - 'audio/die/gz_yanbaihu.mp3', - 'audio/die/gz_zhanglu.mp3', - 'audio/die/gz_zhonghui.mp3', - 'audio/die/gz_zhugeke.mp3', - 'audio/die/gz_zhuling.mp3', - 'audio/die/hanba.mp3', - 'audio/die/handang.mp3', - 'audio/die/hanfu.mp3', - 'audio/die/hanhaoshihuan.mp3', - 'audio/die/hanlong.mp3', - 'audio/die/hanmeng.mp3', - 'audio/die/hansui.mp3', - 'audio/die/haomeng.mp3', - 'audio/die/haopu.mp3', - 'audio/die/haozhao.mp3', - 'audio/die/hejin.mp3', - 'audio/die/heqi.mp3', - 'audio/die/hetaihou.mp3', - 'audio/die/heyan.mp3', - 'audio/die/huaman.mp3', - 'audio/die/huanfan.mp3', - 'audio/die/huangchengyan.mp3', - 'audio/die/huangfusong.mp3', - 'audio/die/huanggai.mp3', - 'audio/die/huanghao.mp3', - 'audio/die/huangquan.mp3', - 'audio/die/huangyueying.mp3', - 'audio/die/huangzhong.mp3', - 'audio/die/huangzu.mp3', - 'audio/die/huatuo.mp3', - 'audio/die/huaxin.mp3', - 'audio/die/huaxiong.mp3', - 'audio/die/hucheer.mp3', - 'audio/die/hujinding.mp3', - 'audio/die/huojun.mp3', - 'audio/die/huzhao.mp3', - 'audio/die/jiachong.mp3', - 'audio/die/jiakui.mp3', - 'audio/die/jiangboyue.mp3', - 'audio/die/jiangfei.mp3', - 'audio/die/jianggan.mp3', - 'audio/die/jiangqin.mp3', - 'audio/die/jiangwanfeiyi.mp3', - 'audio/die/jiangwei.mp3', - 'audio/die/jianyong.mp3', - 'audio/die/jiawenhe.mp3', - 'audio/die/jiaxu.mp3', - 'audio/die/jikang.mp3', - 'audio/die/jiling.mp3', - 'audio/die/jin_guohuai.mp3', - 'audio/die/jin_jiachong.mp3', - 'audio/die/jin_simashi.mp3', - 'audio/die/jin_simayi.mp3', - 'audio/die/jin_simazhao.mp3', - 'audio/die/jin_wangyuanji.mp3', - 'audio/die/jin_xiahouhui.mp3', - 'audio/die/jin_yanghu.mp3', - 'audio/die/jin_yanghuiyu.mp3', - 'audio/die/jin_zhangchunhua.mp3', - 'audio/die/jin_zhouchu.mp3', - 'audio/die/jinxuandi.mp3', - 'audio/die/jsp_caoren.mp3', - 'audio/die/jsp_guanyu.mp3', - 'audio/die/jsp_huangyueying.mp3', - 'audio/die/junk_guanyu.mp3', - 'audio/die/kanze.mp3', - 'audio/die/kebineng.mp3', - 'audio/die/key_abyusa.mp3', - 'audio/die/key_hinata.mp3', - 'audio/die/key_hisako.mp3', - 'audio/die/key_noda.mp3', - 'audio/die/key_saya.mp3', - 'audio/die/key_shiina.mp3', - 'audio/die/key_shiki.mp3', - 'audio/die/key_shiorimiyuki.mp3', - 'audio/die/key_yui.mp3', - 'audio/die/key_yuri.mp3', - 'audio/die/kongrong.mp3', - 'audio/die/kuailiangkuaiyue.mp3', - 'audio/die/kuaiqi.mp3', - 'audio/die/laimin.mp3', - 'audio/die/laiyinger.mp3', - 'audio/die/leibo.mp3', - 'audio/die/leitong.mp3', - 'audio/die/liangxing.mp3', - 'audio/die/liaohua.mp3', - 'audio/die/libai.mp3', - 'audio/die/licaiwei.mp3', - 'audio/die/lidian.mp3', - 'audio/die/lifeng.mp3', - 'audio/die/lijue.mp3', - 'audio/die/lingcao.mp3', - 'audio/die/lingju.mp3', - 'audio/die/lingtong.mp3', - 'audio/die/liqueguosi.mp3', - 'audio/die/liru.mp3', - 'audio/die/lisu.mp3', - 'audio/die/litong.mp3', - 'audio/die/liuba.mp3', - 'audio/die/liubei.mp3', - 'audio/die/liubian.mp3', - 'audio/die/liubiao.mp3', - 'audio/die/liuchen.mp3', - 'audio/die/liucheng.mp3', - 'audio/die/liuchongluojun.mp3', - 'audio/die/liufeng.mp3', - 'audio/die/liuhong.mp3', - 'audio/die/liuhui.mp3', - 'audio/die/liupi.mp3', - 'audio/die/liuqi.mp3', - 'audio/die/liushan.mp3', - 'audio/die/liuxie.mp3', - 'audio/die/liuyan.mp3', - 'audio/die/liuyao.mp3', - 'audio/die/liuye.mp3', - 'audio/die/liuyong.mp3', - 'audio/die/liuyu.mp3', - 'audio/die/liuzan.mp3', - 'audio/die/liuzhang.mp3', - 'audio/die/liwan.mp3', - 'audio/die/liyan.mp3', - 'audio/die/liyi.mp3', - 'audio/die/liyixiejing.mp3', - 'audio/die/longwang.mp3', - 'audio/die/luboyan.mp3', - 'audio/die/luji.mp3', - 'audio/die/lukai.mp3', - 'audio/die/lukang.mp3', - 'audio/die/luotong.mp3', - 'audio/die/luoxian.mp3', - 'audio/die/lushi.mp3', - 'audio/die/lusu.mp3', - 'audio/die/luxun.mp3', - 'audio/die/luyi.mp3', - 'audio/die/luyusheng.mp3', - 'audio/die/luzhi.mp3', - 'audio/die/lvboshe.mp3', - 'audio/die/lvbu.mp3', - 'audio/die/lvdai.mp3', - 'audio/die/lvfan.mp3', - 'audio/die/lvkai.mp3', - 'audio/die/lvkuanglvxiang.mp3', - 'audio/die/lvlingqi.mp3', - 'audio/die/lvmeng.mp3', - 'audio/die/lvqian.mp3', - 'audio/die/machao.mp3', - 'audio/die/macheng.mp3', - 'audio/die/madai.mp3', - 'audio/die/majun.mp3', - 'audio/die/maliang.mp3', - 'audio/die/malingli.mp3', - 'audio/die/mamidi.mp3', - 'audio/die/manchong.mp3', - 'audio/die/mangyachang.mp3', - 'audio/die/mateng.mp3', - 'audio/die/maxiumatie.mp3', - 'audio/die/mayuanyi.mp3', - 'audio/die/mayunlu.mp3', - 'audio/die/mazhong.mp3', - 'audio/die/mb_chengui.mp3', - 'audio/die/mb_huban.mp3', - 'audio/die/mb_xianglang.mp3', - 'audio/die/mengda.mp3', - 'audio/die/menghuo.mp3', - 'audio/die/mengjie.mp3', - 'audio/die/mengyou.mp3', - 'audio/die/mifangfushiren.mp3', - 'audio/die/mifuren.mp3', - 'audio/die/miheng.mp3', - 'audio/die/mizhu.mp3', - 'audio/die/mp_liuling.mp3', - 'audio/die/muludawang.mp3', - 'audio/die/mushun.mp3', - 'audio/die/nanhualaoxian.mp3', - 'audio/die/nashime.mp3', - 'audio/die/neo_xuchu.mp3', - 'audio/die/neo_zhouyu.mp3', - 'audio/die/new_caoren.mp3', - 'audio/die/nezha.mp3', - 'audio/die/niufu.mp3', - 'audio/die/niujin.mp3', - 'audio/die/ns_zanghong.mp3', - 'audio/die/ol_caiwenji.mp3', - 'audio/die/ol_chendeng.mp3', - 'audio/die/ol_dengai.mp3', - 'audio/die/ol_dengzhi.mp3', - 'audio/die/ol_dianwei.mp3', - 'audio/die/ol_dingshangwan.mp3', - 'audio/die/ol_dingyuan.mp3', - 'audio/die/ol_dongzhao.mp3', - 'audio/die/ol_dongzhuo.mp3', - 'audio/die/ol_feiyi.mp3', - 'audio/die/ol_furong.mp3', - 'audio/die/ol_huangzhong.mp3', - 'audio/die/ol_huaxin.mp3', - 'audio/die/ol_huban.mp3', - 'audio/die/ol_hujinding.mp3', - 'audio/die/ol_jiangwei.mp3', - 'audio/die/ol_lisu.mp3', - 'audio/die/ol_liuba.mp3', - 'audio/die/ol_liushan.mp3', - 'audio/die/ol_lusu.mp3', - 'audio/die/ol_masu.mp3', - 'audio/die/ol_mengda.mp3', - 'audio/die/ol_pangde.mp3', - 'audio/die/ol_pangtong.mp3', - 'audio/die/ol_puyuan.mp3', - 'audio/die/ol_qianzhao.mp3', - 'audio/die/ol_sb_guanyu.mp3', - 'audio/die/ol_sb_jiangwei.mp3', - 'audio/die/ol_sb_taishici.mp3', - 'audio/die/ol_sb_yuanshao.mp3', - 'audio/die/ol_sb_yuanshao_shadow.mp3', - 'audio/die/ol_sp_zhugeliang.mp3', - 'audio/die/ol_sunjian.mp3', - 'audio/die/ol_wangrong.mp3', - 'audio/die/ol_weiyan.mp3', - 'audio/die/ol_wenqin.mp3', - 'audio/die/ol_xiahouyuan.mp3', - 'audio/die/ol_xiaoqiao.mp3', - 'audio/die/ol_xuhuang.mp3', - 'audio/die/ol_xunyu.mp3', - 'audio/die/ol_yangyi.mp3', - 'audio/die/ol_yanwen.mp3', - 'audio/die/ol_yuanshao.mp3', - 'audio/die/ol_yujin.mp3', - 'audio/die/ol_zhangyì.mp3', - 'audio/die/ol_zhangzhang.mp3', - 'audio/die/ol_zhouqun.mp3', - 'audio/die/ol_zhujun.mp3', - 'audio/die/ol_zhuling.mp3', - 'audio/die/ol_zhurong.mp3', - 'audio/die/old_guanzhang.mp3', - 'audio/die/old_madai.mp3', - 'audio/die/old_quancong.mp3', - 'audio/die/old_wangyi.mp3', - 'audio/die/old_zhuhuan.mp3', - 'audio/die/panfeng.mp3', - 'audio/die/pangde.mp3', - 'audio/die/pangdegong.mp3', - 'audio/die/panghui.mp3', - 'audio/die/panglingming.mp3', - 'audio/die/pangshanmin.mp3', - 'audio/die/pangtong.mp3', - 'audio/die/panjun.mp3', - 'audio/die/panshu.mp3', - 'audio/die/panzhangmazhong.mp3', - 'audio/die/peixiu.mp3', - 'audio/die/peiyuanshao.mp3', - 'audio/die/puyuan.mp3', - 'audio/die/qianzhao.mp3', - 'audio/die/qiaogong.mp3', - 'audio/die/qiaorui.mp3', - 'audio/die/qiaozhou.mp3', - 'audio/die/qinghegongzhu.mp3', - 'audio/die/qinlang.mp3', - 'audio/die/qinmi.mp3', - 'audio/die/qinyilu.mp3', - 'audio/die/qiuliju.mp3', - 'audio/die/quancong.mp3', - 'audio/die/quanhuijie.mp3', - 'audio/die/quhuang.mp3', - 'audio/die/quyi.mp3', - 'audio/die/re_bulianshi.mp3', - 'audio/die/re_caifuren.mp3', - 'audio/die/re_caiwenji.mp3', - 'audio/die/re_caiyong.mp3', - 'audio/die/re_caocao.mp3', - 'audio/die/re_caochong.mp3', - 'audio/die/re_caopi.mp3', - 'audio/die/re_caoxiu.mp3', - 'audio/die/re_caozhang.mp3', - 'audio/die/re_caozhen.mp3', - 'audio/die/re_caozhi.mp3', - 'audio/die/re_chendeng.mp3', - 'audio/die/re_chengong.mp3', - 'audio/die/re_chengpu.mp3', - 'audio/die/re_chenqun.mp3', - 'audio/die/re_chunyuqiong.mp3', - 'audio/die/re_daqiao.mp3', - 'audio/die/re_dengai.mp3', - 'audio/die/re_dianwei.mp3', - 'audio/die/re_diaochan.mp3', - 'audio/die/re_dongbai.mp3', - 'audio/die/re_dongcheng.mp3', - 'audio/die/re_dongzhuo.mp3', - 'audio/die/re_duji.mp3', - 'audio/die/re_fazheng.mp3', - 'audio/die/re_fengfangnv.mp3', - 'audio/die/re_fuhuanghou.mp3', - 'audio/die/re_ganning.mp3', - 'audio/die/re_gaoshun.mp3', - 'audio/die/re_gongsunyuan.mp3', - 'audio/die/re_gongsunzan.mp3', - 'audio/die/re_guanping.mp3', - 'audio/die/re_guanyu.mp3', - 'audio/die/re_guanzhang.mp3', - 'audio/die/re_guohuai.mp3', - 'audio/die/re_guohuanghou.mp3', - 'audio/die/re_guojia.mp3', - 'audio/die/re_guotufengji.mp3', - 'audio/die/re_guyong.mp3', - 'audio/die/re_handang.mp3', - 'audio/die/re_hanhaoshihuan.mp3', - 'audio/die/re_huanggai.mp3', - 'audio/die/re_huangyueying.mp3', - 'audio/die/re_huangzhong.mp3', - 'audio/die/re_huatuo.mp3', - 'audio/die/re_huaxiong.mp3', - 'audio/die/re_hucheer.mp3', - 'audio/die/re_jiangwei.mp3', - 'audio/die/re_jianyong.mp3', - 'audio/die/re_jiaxu.mp3', - 'audio/die/re_jsp_huangyueying.mp3', - 'audio/die/re_jsp_pangtong.mp3', - 'audio/die/re_jushou.mp3', - 'audio/die/re_liaohua.mp3', - 'audio/die/re_lingtong.mp3', - 'audio/die/re_liru.mp3', - 'audio/die/re_liubei.mp3', - 'audio/die/re_liubiao.mp3', - 'audio/die/re_liuchen.mp3', - 'audio/die/re_liufeng.mp3', - 'audio/die/re_liushan.mp3', - 'audio/die/re_liuzan.mp3', - 'audio/die/re_lusu.mp3', - 'audio/die/re_luxun.mp3', - 'audio/die/re_lvbu.mp3', - 'audio/die/re_lvmeng.mp3', - 'audio/die/re_machao.mp3', - 'audio/die/re_madai.mp3', - 'audio/die/re_manchong.mp3', - 'audio/die/re_masu.mp3', - 'audio/die/re_mazhong.mp3', - 'audio/die/re_menghuo.mp3', - 'audio/die/re_miheng.mp3', - 'audio/die/re_nanhualaoxian.mp3', - 'audio/die/re_panfeng.mp3', - 'audio/die/re_pangde.mp3', - 'audio/die/re_pangdegong.mp3', - 'audio/die/re_pangtong.mp3', - 'audio/die/re_panshu.mp3', - 'audio/die/re_panzhangmazhong.mp3', - 'audio/die/re_quancong.mp3', - 'audio/die/re_simayi.mp3', - 'audio/die/re_sp_taishici.mp3', - 'audio/die/re_sp_zhugeliang.mp3', - 'audio/die/re_sunben.mp3', - 'audio/die/re_sunce.mp3', - 'audio/die/re_sundeng.mp3', - 'audio/die/re_sunjian.mp3', - 'audio/die/re_sunluban.mp3', - 'audio/die/re_sunquan.mp3', - 'audio/die/re_sunshangxiang.mp3', - 'audio/die/re_sunxiu.mp3', - 'audio/die/re_sunyi.mp3', - 'audio/die/re_taishici.mp3', - 'audio/die/re_taoqian.mp3', - 'audio/die/re_wangyi.mp3', - 'audio/die/re_weiyan.mp3', - 'audio/die/re_wenpin.mp3', - 'audio/die/re_wuguotai.mp3', - 'audio/die/re_wuyi.mp3', - 'audio/die/re_xiahoudun.mp3', - 'audio/die/re_xiahoushi.mp3', - 'audio/die/re_xiahouyuan.mp3', - 'audio/die/re_xiaoqiao.mp3', - 'audio/die/re_xuhuang.mp3', - 'audio/die/re_xunchen.mp3', - 'audio/die/re_xunyou.mp3', - 'audio/die/re_xunyu.mp3', - 'audio/die/re_xusheng.mp3', - 'audio/die/re_xushu.mp3', - 'audio/die/re_xuzhu.mp3', - 'audio/die/re_yanwen.mp3', - 'audio/die/re_yuanshu.mp3', - 'audio/die/re_yufan.mp3', - 'audio/die/re_yuji.mp3', - 'audio/die/re_zhangchunhua.mp3', - 'audio/die/re_zhangfei.mp3', - 'audio/die/re_zhanghe.mp3', - 'audio/die/re_zhangjiao.mp3', - 'audio/die/re_zhangliang.mp3', - 'audio/die/re_zhangliao.mp3', - 'audio/die/re_zhangsong.mp3', - 'audio/die/re_zhangyi.mp3', - 'audio/die/re_zhangzhang.mp3', - 'audio/die/re_zhaoyun.mp3', - 'audio/die/re_zhenji.mp3', - 'audio/die/re_zhonghui.mp3', - 'audio/die/re_zhongyao.mp3', - 'audio/die/re_zhoucang.mp3', - 'audio/die/re_zhouyu.mp3', - 'audio/die/re_zhugeliang.mp3', - 'audio/die/re_zhuhuan.mp3', - 'audio/die/re_zhuran.mp3', - 'audio/die/re_zhurong.mp3', - 'audio/die/re_zhuzhi.mp3', - 'audio/die/re_zoushi.mp3', - 'audio/die/re_zuoci.mp3', - 'audio/die/ruanhui.mp3', - 'audio/die/ruanji.mp3', - 'audio/die/ruanyu.mp3', - 'audio/die/ruiji.mp3', - 'audio/die/sb_caocao.mp3', - 'audio/die/sb_caopi.mp3', - 'audio/die/sb_caoren.mp3', - 'audio/die/sb_chengong.mp3', - 'audio/die/sb_daqiao.mp3', - 'audio/die/sb_diaochan.mp3', - 'audio/die/sb_fazheng.mp3', - 'audio/die/sb_ganning.mp3', - 'audio/die/sb_guanyu.mp3', - 'audio/die/sb_huanggai.mp3', - 'audio/die/sb_huangyueying.mp3', - 'audio/die/sb_huangzhong.mp3', - 'audio/die/sb_huaxiong.mp3', - 'audio/die/sb_jiangwei.mp3', - 'audio/die/sb_liubei.mp3', - 'audio/die/sb_liubiao.mp3', - 'audio/die/sb_lvmeng.mp3', - 'audio/die/sb_machao.mp3', - 'audio/die/sb_menghuo.mp3', - 'audio/die/sb_pangtong.mp3', - 'audio/die/sb_sp_zhugeliang.mp3', - 'audio/die/sb_sunce.mp3', - 'audio/die/sb_sunquan.mp3', - 'audio/die/sb_sunshangxiang.mp3', - 'audio/die/sb_xiahoushi.mp3', - 'audio/die/sb_xiaoqiao.mp3', - 'audio/die/sb_xuhuang.mp3', - 'audio/die/sb_xunyu.mp3', - 'audio/die/sb_yl_luzhi.mp3', - 'audio/die/sb_yuanshao.mp3', - 'audio/die/sb_yujin.mp3', - 'audio/die/sb_zhangfei.mp3', - 'audio/die/sb_zhanghe.mp3', - 'audio/die/sb_zhangjiao.mp3', - 'audio/die/sb_zhaoyun.mp3', - 'audio/die/sb_zhenji.mp3', - 'audio/die/sb_zhouyu.mp3', - 'audio/die/sb_zhugeliang.mp3', - 'audio/die/sb_zhurong.mp3', - 'audio/die/shamoke.mp3', - 'audio/die/shen_caocao.mp3', - 'audio/die/shen_caopi.mp3', - 'audio/die/shen_dengai.mp3', - 'audio/die/shen_dianwei.mp3', - 'audio/die/shen_diaochan.mp3', - 'audio/die/shen_ganning.mp3', - 'audio/die/shen_guanyu.mp3', - 'audio/die/shen_guojia.mp3', - 'audio/die/shen_huatuo.mp3', - 'audio/die/shen_jiangwei.mp3', - 'audio/die/shen_liubei.mp3', - 'audio/die/shen_lusu.mp3', - 'audio/die/shen_luxun.mp3', - 'audio/die/shen_lvbu.mp3', - 'audio/die/shen_lvbu1.mp3', - 'audio/die/shen_lvbu2.mp3', - 'audio/die/shen_lvmeng.mp3', - 'audio/die/shen_machao.mp3', - 'audio/die/shen_simayi.mp3', - 'audio/die/shen_sunce.mp3', - 'audio/die/shen_sunquan.mp3', - 'audio/die/shen_taishici.mp3', - 'audio/die/shen_xunyu.mp3', - 'audio/die/shen_xuzhu.mp3', - 'audio/die/shen_zhangfei.mp3', - 'audio/die/shen_zhangjiao.mp3', - 'audio/die/shen_zhangliao.mp3', - 'audio/die/shen_zhaoyun.mp3', - 'audio/die/shen_zhenji.mp3', - 'audio/die/shen_zhouyu.mp3', - 'audio/die/shen_zhugeliang.mp3', - 'audio/die/shenpei.mp3', - 'audio/die/shibao.mp3', - 'audio/die/shichangshi.mp3', - 'audio/die/shichangshiRest.mp3', - 'audio/die/shixie.mp3', - 'audio/die/shiyi.mp3', - 'audio/die/simafu.mp3', - 'audio/die/simahui.mp3', - 'audio/die/simalang.mp3', - 'audio/die/simashi.mp3', - 'audio/die/simayi.mp3', - 'audio/die/simazhao.mp3', - 'audio/die/simazhou.mp3', - 'audio/die/sp_bianfuren.mp3', - 'audio/die/sp_caiwenji.mp3', - 'audio/die/sp_caohong.mp3', - 'audio/die/sp_caoren.mp3', - 'audio/die/sp_caosong.mp3', - 'audio/die/sp_chendong.mp3', - 'audio/die/sp_chenzhen.mp3', - 'audio/die/sp_cuiyan.mp3', - 'audio/die/sp_dongzhuo.mp3', - 'audio/die/sp_duyu.mp3', - 'audio/die/sp_gaolan.mp3', - 'audio/die/sp_guanyu.mp3', - 'audio/die/sp_huaman.mp3', - 'audio/die/sp_huangfusong.mp3', - 'audio/die/sp_huaxin.mp3', - 'audio/die/sp_jianggan.mp3', - 'audio/die/sp_jiangqing.mp3', - 'audio/die/sp_jiangwan.mp3', - 'audio/die/sp_jiangwei.mp3', - 'audio/die/sp_jiaxu.mp3', - 'audio/die/sp_key_kanade.mp3', - 'audio/die/sp_kongrong.mp3', - 'audio/die/sp_lvfan.mp3', - 'audio/die/sp_machao.mp3', - 'audio/die/sp_maojie.mp3', - 'audio/die/sp_menghuo.mp3', - 'audio/die/sp_mifangfushiren.mp3', - 'audio/die/sp_mifuren.mp3', - 'audio/die/sp_ol_zhanghe.mp3', - 'audio/die/sp_pangde.mp3', - 'audio/die/sp_pangtong.mp3', - 'audio/die/sp_pengyang.mp3', - 'audio/die/sp_shenpei.mp3', - 'audio/die/sp_sufei.mp3', - 'audio/die/sp_sunshangxiang.mp3', - 'audio/die/sp_sunshao.mp3', - 'audio/die/sp_taishici.mp3', - 'audio/die/sp_wangcan.mp3', - 'audio/die/sp_wangshuang.mp3', - 'audio/die/sp_wenpin.mp3', - 'audio/die/sp_xiahoudun.mp3', - 'audio/die/sp_xinpi.mp3', - 'audio/die/sp_xujing.mp3', - 'audio/die/sp_xunchen.mp3', - 'audio/die/sp_xusheng.mp3', - 'audio/die/sp_xuyou.mp3', - 'audio/die/sp_yanghu.mp3', - 'audio/die/sp_yangwan.mp3', - 'audio/die/sp_yuji.mp3', - 'audio/die/sp_zhangchangpu.mp3', - 'audio/die/sp_zhanghe.mp3', - 'audio/die/sp_zhangliao.mp3', - 'audio/die/sp_zhangwen.mp3', - 'audio/die/sp_zhugeliang.mp3', - 'audio/die/sp_zhujun.mp3', - 'audio/die/sp_zongyu.mp3', - 'audio/die/st_xushu.mp3', - 'audio/die/st_yuanshu.mp3', - 'audio/die/star_caoren.mp3', - 'audio/die/star_dongzhuo.mp3', - 'audio/die/star_yuanshao.mp3', - 'audio/die/star_yuanshu.mp3', - 'audio/die/sufei.mp3', - 'audio/die/sunce.mp3', - 'audio/die/sundeng.mp3', - 'audio/die/sunhanhua.mp3', - 'audio/die/sunhao.mp3', - 'audio/die/sunhong.mp3', - 'audio/die/sunhuan.mp3', - 'audio/die/sunjian.mp3', - 'audio/die/sunlang.mp3', - 'audio/die/sunliang.mp3', - 'audio/die/sunlingluan.mp3', - 'audio/die/sunluban.mp3', - 'audio/die/sunluyu.mp3', - 'audio/die/sunqian.mp3', - 'audio/die/sunquan.mp3', - 'audio/die/sunru.mp3', - 'audio/die/sunshangxiang.mp3', - 'audio/die/sunshao.mp3', - 'audio/die/sunwukong.mp3', - 'audio/die/sunxiu.mp3', - 'audio/die/sunyi.mp3', - 'audio/die/sunyu.mp3', - 'audio/die/sunziliufang.mp3', - 'audio/die/tadun.mp3', - 'audio/die/taishici.mp3', - 'audio/die/tangji.mp3', - 'audio/die/tangzi.mp3', - 'audio/die/taoqian.mp3', - 'audio/die/taoshen.mp3', - 'audio/die/tengfanglan.mp3', - 'audio/die/tenggongzhu.mp3', - 'audio/die/tengyin.mp3', - 'audio/die/tianchou.mp3', - 'audio/die/tianfeng.mp3', - 'audio/die/tianshangyi.mp3', - 'audio/die/tianyu.mp3', - 'audio/die/tongyuan.mp3', - 'audio/die/tw_baoxin.mp3', - 'audio/die/tw_beimihu.mp3', - 'audio/die/tw_bingyuan.mp3', - 'audio/die/tw_caocao.mp3', - 'audio/die/tw_caozhao.mp3', - 'audio/die/tw_chenzhen.mp3', - 'audio/die/tw_dongzhao.mp3', - 'audio/die/tw_fengxí.mp3', - 'audio/die/tw_gexuan.mp3', - 'audio/die/tw_gongsunfan.mp3', - 'audio/die/tw_haomeng.mp3', - 'audio/die/tw_huchuquan.mp3', - 'audio/die/tw_huojun.mp3', - 'audio/die/tw_jiangji.mp3', - 'audio/die/tw_jiangwei.mp3', - 'audio/die/tw_jianshuo.mp3', - 'audio/die/tw_liubei.mp3', - 'audio/die/tw_liufuren.mp3', - 'audio/die/tw_liuhong.mp3', - 'audio/die/tw_liwei.mp3', - 'audio/die/tw_mateng.mp3', - 'audio/die/tw_niufudongxie.mp3', - 'audio/die/tw_puyangxing.mp3', - 'audio/die/tw_qiaorui.mp3', - 'audio/die/tw_shen_guanyu.mp3', - 'audio/die/tw_shen_lvmeng.mp3', - 'audio/die/tw_tianyu.mp3', - 'audio/die/tw_wangcan.mp3', - 'audio/die/tw_wangchang.mp3', - 'audio/die/tw_weixu.mp3', - 'audio/die/tw_xiahouen.mp3', - 'audio/die/tw_xiahoushang.mp3', - 'audio/die/tw_yangang.mp3', - 'audio/die/tw_yanxiang.mp3', - 'audio/die/tw_yufuluo.mp3', - 'audio/die/tw_yujin.mp3', - 'audio/die/tw_zhanghong.mp3', - 'audio/die/tw_zhangji.mp3', - 'audio/die/tw_zhangnan.mp3', - 'audio/die/tw_zhangning.mp3', - 'audio/die/tw_zhangzhao.mp3', - 'audio/die/vtb_xiaojiu.mp3', - 'audio/die/vtb_xiaole.mp3', - 'audio/die/vtb_xiaosha.mp3', - 'audio/die/vtb_xiaoshan.mp3', - 'audio/die/vtb_xiaotao.mp3', - 'audio/die/wangcan.mp3', - 'audio/die/wangfuzhaolei.mp3', - 'audio/die/wangguan.mp3', - 'audio/die/wangji.mp3', - 'audio/die/wangjun.mp3', - 'audio/die/wanglang.mp3', - 'audio/die/wanglie.mp3', - 'audio/die/wangling.mp3', - 'audio/die/wangping.mp3', - 'audio/die/wangrong.mp3', - 'audio/die/wangshuang.mp3', - 'audio/die/wangtao.mp3', - 'audio/die/wangwei.mp3', - 'audio/die/wangxiang.mp3', - 'audio/die/wangyan.mp3', - 'audio/die/wangyi.mp3', - 'audio/die/wangyuanji.mp3', - 'audio/die/wangyue.mp3', - 'audio/die/wangyun.mp3', - 'audio/die/wanniangongzhu.mp3', - 'audio/die/weiguan.mp3', - 'audio/die/weiwenzhugezhi.mp3', - 'audio/die/weiyan.mp3', - 'audio/die/weizi.mp3', - 'audio/die/wenpin.mp3', - 'audio/die/wenyang.mp3', - 'audio/die/wis_huaxiong.mp3', - 'audio/die/wis_jiangwan.mp3', - 'audio/die/wis_jiangwei.mp3', - 'audio/die/wis_shuijing.mp3', - 'audio/die/wis_sunce.mp3', - 'audio/die/wis_tianfeng.mp3', - 'audio/die/wis_xuyou.mp3', - 'audio/die/wis_zhangzhao.mp3', - 'audio/die/wolongfengchu.mp3', - 'audio/die/wu_luxun.mp3', - 'audio/die/wu_zhugeliang.mp3', - 'audio/die/wu_zhutiexiong.mp3', - 'audio/die/wuanguo.mp3', - 'audio/die/wuban.mp3', - 'audio/die/wufan.mp3', - 'audio/die/wuguotai.mp3', - 'audio/die/wujing.mp3', - 'audio/die/wulan.mp3', - 'audio/die/wutugu.mp3', - 'audio/die/wuxian.mp3', - 'audio/die/wuyan.mp3', - 'audio/die/wuyi.mp3', - 'audio/die/xf_yiji.mp3', - 'audio/die/xia_dianwei.mp3', - 'audio/die/xia_liubei.mp3', - 'audio/die/xia_liyàn.mp3', - 'audio/die/xia_lusu.mp3', - 'audio/die/xia_tongyuan.mp3', - 'audio/die/xia_wangyue.mp3', - 'audio/die/xia_xiahoudun.mp3', - 'audio/die/xia_xiahousone.mp3', - 'audio/die/xia_xiahouzie.mp3', - 'audio/die/xia_xushu.mp3', - 'audio/die/xia_zhangwei.mp3', - 'audio/die/xia_zhaoe.mp3', - 'audio/die/xiahouba.mp3', - 'audio/die/xiahoudun.mp3', - 'audio/die/xiahoujie.mp3', - 'audio/die/xiahoujuan.mp3', - 'audio/die/xiahoulingnv.mp3', - 'audio/die/xiahoumao.mp3', - 'audio/die/xiahoushi.mp3', - 'audio/die/xiahouxuan.mp3', - 'audio/die/xiahouyuan.mp3', - 'audio/die/xiangchong.mp3', - 'audio/die/xianglang.mp3', - 'audio/die/xiangrang.mp3', - 'audio/die/xiaoqiao.mp3', - 'audio/die/xiaoyuehankehan.mp3', - 'audio/die/xielingyu.mp3', - 'audio/die/xin_caifuren.mp3', - 'audio/die/xin_caoxiu.mp3', - 'audio/die/xin_caozhang.mp3', - 'audio/die/xin_caozhen.mp3', - 'audio/die/xin_chengpu.mp3', - 'audio/die/xin_fazheng.mp3', - 'audio/die/xin_fuhuanghou.mp3', - 'audio/die/xin_gaoshun.mp3', - 'audio/die/xin_gongsunzan.mp3', - 'audio/die/xin_guohuai.mp3', - 'audio/die/xin_guozhao.mp3', - 'audio/die/xin_guyong.mp3', - 'audio/die/xin_handang.mp3', - 'audio/die/xin_hansui.mp3', - 'audio/die/xin_jianyong.mp3', - 'audio/die/xin_jushou.mp3', - 'audio/die/xin_liaohua.mp3', - 'audio/die/xin_lingtong.mp3', - 'audio/die/xin_liubiao.mp3', - 'audio/die/xin_mamidi.mp3', - 'audio/die/xin_panzhangmazhong.mp3', - 'audio/die/xin_quancong.mp3', - 'audio/die/xin_sunluban.mp3', - 'audio/die/xin_sunxiu.mp3', - 'audio/die/xin_wuguotai.mp3', - 'audio/die/xin_wuyi.mp3', - 'audio/die/xin_xusheng.mp3', - 'audio/die/xin_xushu.mp3', - 'audio/die/xin_yuanshao.mp3', - 'audio/die/xin_yufan.mp3', - 'audio/die/xin_yuji.mp3', - 'audio/die/xin_zhangyi.mp3', - 'audio/die/xin_zhonghui.mp3', - 'audio/die/xin_zhuhuan.mp3', - 'audio/die/xin_zhuran.mp3', - 'audio/die/xin_zhuzhi.mp3', - 'audio/die/xinchang.mp3', - 'audio/die/xinfu_yuji.mp3', - 'audio/die/xingdaorong.mp3', - 'audio/die/xinpi.mp3', - 'audio/die/xinping.mp3', - 'audio/die/xinxianying.mp3', - 'audio/die/xinzhongyong.mp3', - 'audio/die/xizheng.mp3', - 'audio/die/xizhicai.mp3', - 'audio/die/xuangongzhu.mp3', - 'audio/die/xuelingyun.mp3', - 'audio/die/xuezong.mp3', - 'audio/die/xugong.mp3', - 'audio/die/xuhuang.mp3', - 'audio/die/xujing.mp3', - 'audio/die/xunchen.mp3', - 'audio/die/xunyou.mp3', - 'audio/die/xunyu.mp3', - 'audio/die/xurong.mp3', - 'audio/die/xushao.mp3', - 'audio/die/xusheng.mp3', - 'audio/die/xushi.mp3', - 'audio/die/xushu.mp3', - 'audio/die/xuyou.mp3', - 'audio/die/xuzhu.mp3', - 'audio/die/yanbaihu.mp3', - 'audio/die/yanfuren.mp3', - 'audio/die/yangbiao.mp3', - 'audio/die/yangfu.mp3', - 'audio/die/yanghong.mp3', - 'audio/die/yanghuiyu.mp3', - 'audio/die/yangwan.mp3', - 'audio/die/yangxiu.mp3', - 'audio/die/yangyan.mp3', - 'audio/die/yangyi.mp3', - 'audio/die/yangzhi.mp3', - 'audio/die/yanjun.mp3', - 'audio/die/yanpu.mp3', - 'audio/die/yanrou.mp3', - 'audio/die/yanwen.mp3', - 'audio/die/yanyan.mp3', - 'audio/die/yinfuren.mp3', - 'audio/die/yitianjian.mp3', - 'audio/die/yj_ganning.mp3', - 'audio/die/yj_huangzhong.mp3', - 'audio/die/yj_jushou.mp3', - 'audio/die/yj_qiaozhou.mp3', - 'audio/die/yj_sufei.mp3', - 'audio/die/yj_weiyan.mp3', - 'audio/die/yj_xuhuang.mp3', - 'audio/die/yj_zhanghe.mp3', - 'audio/die/yj_zhangliao.mp3', - 'audio/die/yj_zhoubuyi.mp3', - 'audio/die/yl_luzhi.mp3', - 'audio/die/yl_yuanshu.mp3', - 'audio/die/yuanhuan.mp3', - 'audio/die/yuanji.mp3', - 'audio/die/yuanshao.mp3', - 'audio/die/yuanshu.mp3', - 'audio/die/yuantanyuanshang.mp3', - 'audio/die/yuantanyuanxiyuanshang.mp3', - 'audio/die/yue_caiwenji.mp3', - 'audio/die/yue_daqiao.mp3', - 'audio/die/yue_xiaoqiao.mp3', - 'audio/die/yue_zhoufei.mp3', - 'audio/die/yuechen.mp3', - 'audio/die/yuejin.mp3', - 'audio/die/yuejiu.mp3', - 'audio/die/yufan.mp3', - 'audio/die/yuji.mp3', - 'audio/die/yujin.mp3', - 'audio/die/yujin_yujin.mp3', - 'audio/die/zangba.mp3', - 'audio/die/zerong.mp3', - 'audio/die/zhangbao.mp3', - 'audio/die/zhangchangpu.mp3', - 'audio/die/zhangchu.mp3', - 'audio/die/zhangchunhua.mp3', - 'audio/die/zhangfei.mp3', - 'audio/die/zhangfen.mp3', - 'audio/die/zhanggong.mp3', - 'audio/die/zhanggongqi.mp3', - 'audio/die/zhanghe.mp3', - 'audio/die/zhangheng.mp3', - 'audio/die/zhanghu.mp3', - 'audio/die/zhanghua.mp3', - 'audio/die/zhanghuyuechen.mp3', - 'audio/die/zhangji.mp3', - 'audio/die/zhangjiao.mp3', - 'audio/die/zhangjinyun.mp3', - 'audio/die/zhangjunyi.mp3', - 'audio/die/zhangkai.mp3', - 'audio/die/zhangliao.mp3', - 'audio/die/zhangling.mp3', - 'audio/die/zhanglu.mp3', - 'audio/die/zhangmancheng.mp3', - 'audio/die/zhangmiao.mp3', - 'audio/die/zhangning.mp3', - 'audio/die/zhangqiying.mp3', - 'audio/die/zhangrang.mp3', - 'audio/die/zhangren.mp3', - 'audio/die/zhangshiping.mp3', - 'audio/die/zhangsong.mp3', - 'audio/die/zhangwen.mp3', - 'audio/die/zhangxingcai.mp3', - 'audio/die/zhangxiu.mp3', - 'audio/die/zhangxuan.mp3', - 'audio/die/zhangxun.mp3', - 'audio/die/zhangyan.mp3', - 'audio/die/zhangyao.mp3', - 'audio/die/zhangyi.mp3', - 'audio/die/zhangyì.mp3', - 'audio/die/zhangzhang.mp3', - 'audio/die/zhangzhi.mp3', - 'audio/die/zhangzhongjing.mp3', - 'audio/die/zhaoang.mp3', - 'audio/die/zhaotongzhaoguang.mp3', - 'audio/die/zhaoxiang.mp3', - 'audio/die/zhaoyan.mp3', - 'audio/die/zhaoyǎn.mp3', - 'audio/die/zhaoyun.mp3', - 'audio/die/zhaozhi.mp3', - 'audio/die/zhaozhong.mp3', - 'audio/die/zhenghun.mp3', - 'audio/die/zhengxuan.mp3', - 'audio/die/zhenji.mp3', - 'audio/die/zhiling.mp3', - 'audio/die/zhonghui.mp3', - 'audio/die/zhongshiji.mp3', - 'audio/die/zhongyan.mp3', - 'audio/die/zhongyao.mp3', - 'audio/die/zhoubuyi.mp3', - 'audio/die/zhoucang.mp3', - 'audio/die/zhouchu.mp3', - 'audio/die/zhoufang.mp3', - 'audio/die/zhoufei.mp3', - 'audio/die/zhouqun.mp3', - 'audio/die/zhoushan.mp3', - 'audio/die/zhoutai.mp3', - 'audio/die/zhouyi.mp3', - 'audio/die/zhouyu.mp3', - 'audio/die/zhugedan.mp3', - 'audio/die/zhugeguo.mp3', - 'audio/die/zhugejin.mp3', - 'audio/die/zhugeke.mp3', - 'audio/die/zhugeliang.mp3', - 'audio/die/zhugemengxue.mp3', - 'audio/die/zhugeruoxue.mp3', - 'audio/die/zhugeshang.mp3', - 'audio/die/zhugezhan.mp3', - 'audio/die/zhuhuan.mp3', - 'audio/die/zhujianping.mp3', - 'audio/die/zhujun.mp3', - 'audio/die/zhuling.mp3', - 'audio/die/zhuran.mp3', - 'audio/die/zhurong.mp3', - 'audio/die/zhutiexiong.mp3', - 'audio/die/zhuzhi.mp3', - 'audio/die/zongyu.mp3', - 'audio/die/zoushi.mp3', - 'audio/die/zumao.mp3', - 'audio/die/zuoci.mp3', - 'audio/die/zuofen.mp3', - /*effect audio end*/ - - /*skill audio begin*/ - 'audio/skill/abyusa_dunying1.mp3', - 'audio/skill/abyusa_dunying2.mp3', - 'audio/skill/abyusa_jueqing1.mp3', - 'audio/skill/abyusa_jueqing2.mp3', - 'audio/skill/aichen1.mp3', - 'audio/skill/aichen2.mp3', - 'audio/skill/anguo1.mp3', - 'audio/skill/anguo2.mp3', - 'audio/skill/anjian1.mp3', - 'audio/skill/anjian2.mp3', - 'audio/skill/anxian1.mp3', - 'audio/skill/anxian2.mp3', - 'audio/skill/anxu1.mp3', - 'audio/skill/anxu2.mp3', - 'audio/skill/anyong1.mp3', - 'audio/skill/anyong2.mp3', - 'audio/skill/aocai_gz_zhugeke1.mp3', - 'audio/skill/aocai_gz_zhugeke2.mp3', - 'audio/skill/aocai1.mp3', - 'audio/skill/aocai2.mp3', - 'audio/skill/bagua_skill.mp3', - 'audio/skill/baijia_tw_beimihu1.mp3', - 'audio/skill/baijia_tw_beimihu2.mp3', - 'audio/skill/baijia1.mp3', - 'audio/skill/baijia2.mp3', - 'audio/skill/baiyi1.mp3', - 'audio/skill/baiyi2.mp3', - 'audio/skill/baiyin_skill.mp3', - 'audio/skill/baoling1.mp3', - 'audio/skill/baoling2.mp3', - 'audio/skill/baonu1.mp3', - 'audio/skill/baonu2.mp3', - 'audio/skill/baonue2_re_dongzhuo1.mp3', - 'audio/skill/baonue2_re_dongzhuo2.mp3', - 'audio/skill/baonue21.mp3', - 'audio/skill/baonue22.mp3', - 'audio/skill/baoqie1.mp3', - 'audio/skill/baoqie2.mp3', - 'audio/skill/baoshu1.mp3', - 'audio/skill/baoshu2.mp3', - 'audio/skill/bazhan1.mp3', - 'audio/skill/bazhan2.mp3', - 'audio/skill/bazhen_ol_pangtong1.mp3', - 'audio/skill/bazhen_ol_pangtong2.mp3', - 'audio/skill/bazhen_ol_sp_zhugeliang1.mp3', - 'audio/skill/bazhen_ol_sp_zhugeliang2.mp3', - 'audio/skill/bazhen_re_sp_zhugeliang1.mp3', - 'audio/skill/bazhen_re_sp_zhugeliang2.mp3', - 'audio/skill/bazhen1.mp3', - 'audio/skill/bazhen2.mp3', - 'audio/skill/beige_ol_caiwenji1.mp3', - 'audio/skill/beige_ol_caiwenji2.mp3', - 'audio/skill/beige_re_caiwenji1.mp3', - 'audio/skill/beige_re_caiwenji2.mp3', - 'audio/skill/beige1.mp3', - 'audio/skill/beige2.mp3', - 'audio/skill/beini1.mp3', - 'audio/skill/beini2.mp3', - 'audio/skill/beishui1.mp3', - 'audio/skill/beishui2.mp3', - 'audio/skill/beizhan1.mp3', - 'audio/skill/beizhan2.mp3', - 'audio/skill/beizhu1.mp3', - 'audio/skill/beizhu2.mp3', - 'audio/skill/beizhu3.mp3', - 'audio/skill/benghuai_ol_dongzhuo1.mp3', - 'audio/skill/benghuai_ol_dongzhuo2.mp3', - 'audio/skill/benghuai_re_dongzhuo1.mp3', - 'audio/skill/benghuai_re_dongzhuo2.mp3', - 'audio/skill/benghuai_zhugedan1.mp3', - 'audio/skill/benghuai_zhugedan2.mp3', - 'audio/skill/benghuai1.mp3', - 'audio/skill/benghuai2.mp3', - 'audio/skill/benxi1.mp3', - 'audio/skill/benxi2.mp3', - 'audio/skill/benyu1.mp3', - 'audio/skill/benyu2.mp3', - 'audio/skill/biaozhao1.mp3', - 'audio/skill/biaozhao2.mp3', - 'audio/skill/biejun1.mp3', - 'audio/skill/biejun2.mp3', - 'audio/skill/bifa1.mp3', - 'audio/skill/bifa2.mp3', - 'audio/skill/bihuo1.mp3', - 'audio/skill/bihuo2.mp3', - 'audio/skill/biluan1.mp3', - 'audio/skill/biluan2.mp3', - 'audio/skill/binghuo1.mp3', - 'audio/skill/binghuo2.mp3', - 'audio/skill/bingjie1.mp3', - 'audio/skill/bingjie2.mp3', - 'audio/skill/binglun1.mp3', - 'audio/skill/binglun2.mp3', - 'audio/skill/bingqing1.mp3', - 'audio/skill/bingqing2.mp3', - 'audio/skill/bingxin1.mp3', - 'audio/skill/bingxin2.mp3', - 'audio/skill/bingyi_xin_guyong1.mp3', - 'audio/skill/bingyi_xin_guyong2.mp3', - 'audio/skill/bingyi1.mp3', - 'audio/skill/bingyi2.mp3', - 'audio/skill/bingzheng1.mp3', - 'audio/skill/bingzheng2.mp3', - 'audio/skill/bixiong1.mp3', - 'audio/skill/bixiong2.mp3', - 'audio/skill/biyue1.mp3', - 'audio/skill/biyue2.mp3', - 'audio/skill/bizheng1.mp3', - 'audio/skill/bizheng2.mp3', - 'audio/skill/bizhuan1.mp3', - 'audio/skill/bizhuan2.mp3', - 'audio/skill/bmcanshi_tw_beimihu1.mp3', - 'audio/skill/bmcanshi_tw_beimihu2.mp3', - 'audio/skill/bmcanshi1.mp3', - 'audio/skill/bmcanshi2.mp3', - 'audio/skill/bolan1.mp3', - 'audio/skill/bolan2.mp3', - 'audio/skill/boming1.mp3', - 'audio/skill/boming2.mp3', - 'audio/skill/boss_baolin.mp3', - 'audio/skill/boss_baonu1.mp3', - 'audio/skill/boss_baonu2.mp3', - 'audio/skill/boss_biantianx1.mp3', - 'audio/skill/boss_biantianx2.mp3', - 'audio/skill/boss_bufo.mp3', - 'audio/skill/boss_chiying1.mp3', - 'audio/skill/boss_chiying2.mp3', - 'audio/skill/boss_chuanyun.mp3', - 'audio/skill/boss_dayuan.mp3', - 'audio/skill/boss_diting.mp3', - 'audio/skill/boss_fanshi.mp3', - 'audio/skill/boss_fengxing.mp3', - 'audio/skill/boss_gongshenjg1.mp3', - 'audio/skill/boss_gongshenjg2.mp3', - 'audio/skill/boss_guihan1.mp3', - 'audio/skill/boss_guihan2.mp3', - 'audio/skill/boss_honglian1.mp3', - 'audio/skill/boss_honglian2.mp3', - 'audio/skill/boss_hujia1.mp3', - 'audio/skill/boss_hujia2.mp3', - 'audio/skill/boss_huodi1.mp3', - 'audio/skill/boss_huodi2.mp3', - 'audio/skill/boss_jingmiao1.mp3', - 'audio/skill/boss_jingmiao2.mp3', - 'audio/skill/boss_jizhen1.mp3', - 'audio/skill/boss_jizhen2.mp3', - 'audio/skill/boss_jizhi1.mp3', - 'audio/skill/boss_jizhi2.mp3', - 'audio/skill/boss_jueji1.mp3', - 'audio/skill/boss_jueji2.mp3', - 'audio/skill/boss_leiji1.mp3', - 'audio/skill/boss_leiji2.mp3', - 'audio/skill/boss_leili1.mp3', - 'audio/skill/boss_leili2.mp3', - 'audio/skill/boss_lingfeng1.mp3', - 'audio/skill/boss_lingfeng2.mp3', - 'audio/skill/boss_qiangzheng1.mp3', - 'audio/skill/boss_qiangzheng2.mp3', - 'audio/skill/boss_qiwu.mp3', - 'audio/skill/boss_shengshou.mp3', - 'audio/skill/boss_shiyou.mp3', - 'audio/skill/boss_skonghun.mp3', - 'audio/skill/boss_tianyu.mp3', - 'audio/skill/boss_tianyujg.mp3', - 'audio/skill/boss_wanghun.mp3', - 'audio/skill/boss_wangshi.mp3', - 'audio/skill/boss_wuliang.mp3', - 'audio/skill/boss_wuxin1.mp3', - 'audio/skill/boss_wuxin2.mp3', - 'audio/skill/boss_xianyin1.mp3', - 'audio/skill/boss_xianyin2.mp3', - 'audio/skill/boss_xuanlei.mp3', - 'audio/skill/boss_yuhuojg.mp3', - 'audio/skill/boss_zhinang1.mp3', - 'audio/skill/boss_zhinang2.mp3', - 'audio/skill/botu1.mp3', - 'audio/skill/botu2.mp3', - 'audio/skill/boyan1.mp3', - 'audio/skill/boyan2.mp3', - 'audio/skill/buchen1.mp3', - 'audio/skill/buchen2.mp3', - 'audio/skill/buqi1.mp3', - 'audio/skill/buqi2.mp3', - 'audio/skill/buqu1.mp3', - 'audio/skill/buqu2.mp3', - 'audio/skill/bushi1.mp3', - 'audio/skill/bushi2.mp3', - 'audio/skill/busuan1.mp3', - 'audio/skill/busuan2.mp3', - 'audio/skill/buxu1.mp3', - 'audio/skill/buxu2.mp3', - 'audio/skill/buyi_re_wuguotai1.mp3', - 'audio/skill/buyi_re_wuguotai2.mp3', - 'audio/skill/buyi1.mp3', - 'audio/skill/buyi2.mp3', - 'audio/skill/caishi1.mp3', - 'audio/skill/caishi2.mp3', - 'audio/skill/caiwang1.mp3', - 'audio/skill/caiwang2.mp3', - 'audio/skill/caiyi1.mp3', - 'audio/skill/caiyi2.mp3', - 'audio/skill/caiyuan1.mp3', - 'audio/skill/caiyuan2.mp3', - 'audio/skill/caizhaoji_hujia.mp3', - 'audio/skill/cangchu1.mp3', - 'audio/skill/cangchu2.mp3', - 'audio/skill/cangji.mp3', - 'audio/skill/cangzhuo1.mp3', - 'audio/skill/cangzhuo2.mp3', - 'audio/skill/canmou1.mp3', - 'audio/skill/canmou2.mp3', - 'audio/skill/canshi1.mp3', - 'audio/skill/canshi2.mp3', - 'audio/skill/caozhao1.mp3', - 'audio/skill/caozhao2.mp3', - 'audio/skill/changbiao1.mp3', - 'audio/skill/changbiao2.mp3', - 'audio/skill/chanhui1.mp3', - 'audio/skill/chanhui2.mp3', - 'audio/skill/channi1.mp3', - 'audio/skill/channi2.mp3', - 'audio/skill/chanyuan1.mp3', - 'audio/skill/chanyuan2.mp3', - 'audio/skill/chaofeng1.mp3', - 'audio/skill/chaofeng2.mp3', - 'audio/skill/chenggong1.mp3', - 'audio/skill/chenggong2.mp3', - 'audio/skill/chengshang1.mp3', - 'audio/skill/chengshang2.mp3', - 'audio/skill/chengwu1.mp3', - 'audio/skill/chengwu2.mp3', - 'audio/skill/chengxiang1.mp3', - 'audio/skill/chengxiang2.mp3', - 'audio/skill/chengye1.mp3', - 'audio/skill/chengye2.mp3', - 'audio/skill/chengye3.mp3', - 'audio/skill/chengzhang1.mp3', - 'audio/skill/chengzhang2.mp3', - 'audio/skill/chengzhao1.mp3', - 'audio/skill/chengzhao2.mp3', - 'audio/skill/chenjian1.mp3', - 'audio/skill/chenjian2.mp3', - 'audio/skill/chenjie1.mp3', - 'audio/skill/chenjie2.mp3', - 'audio/skill/chenqing1.mp3', - 'audio/skill/chenqing2.mp3', - 'audio/skill/chexuan1.mp3', - 'audio/skill/chexuan2.mp3', - 'audio/skill/chijie.mp3', - 'audio/skill/chizhong1.mp3', - 'audio/skill/chizhong2.mp3', - 'audio/skill/chongxin1.mp3', - 'audio/skill/chongxin2.mp3', - 'audio/skill/chongxu1.mp3', - 'audio/skill/chongxu2.mp3', - 'audio/skill/chongzhen1.mp3', - 'audio/skill/chongzhen2.mp3', - 'audio/skill/chouce1.mp3', - 'audio/skill/chouce2.mp3', - 'audio/skill/choufa1.mp3', - 'audio/skill/choufa2.mp3', - 'audio/skill/chouhai1.mp3', - 'audio/skill/chouhai2.mp3', - 'audio/skill/choujue1.mp3', - 'audio/skill/choujue2.mp3', - 'audio/skill/chouliang.mp3', - 'audio/skill/choulve1.mp3', - 'audio/skill/choulve2.mp3', - 'audio/skill/choutao1.mp3', - 'audio/skill/choutao2.mp3', - 'audio/skill/chuaili1.mp3', - 'audio/skill/chuaili2.mp3', - 'audio/skill/chuanshu1.mp3', - 'audio/skill/chuanshu2.mp3', - 'audio/skill/chuanxin1.mp3', - 'audio/skill/chuanxin2.mp3', - 'audio/skill/chuanyun.mp3', - 'audio/skill/chuhai1.mp3', - 'audio/skill/chuhai2.mp3', - 'audio/skill/chuhai3.mp3', - 'audio/skill/chuiti1.mp3', - 'audio/skill/chuiti2.mp3', - 'audio/skill/chulao1.mp3', - 'audio/skill/chulao2.mp3', - 'audio/skill/chunlao_xin_chengpu1.mp3', - 'audio/skill/chunlao_xin_chengpu2.mp3', - 'audio/skill/chunlao1.mp3', - 'audio/skill/chunlao2.mp3', - 'audio/skill/chuyuan1.mp3', - 'audio/skill/chuyuan2.mp3', - 'audio/skill/cibei1.mp3', - 'audio/skill/cibei2.mp3', - 'audio/skill/cihuang1.mp3', - 'audio/skill/cihuang2.mp3', - 'audio/skill/ciwei1.mp3', - 'audio/skill/ciwei2.mp3', - 'audio/skill/cixiao1.mp3', - 'audio/skill/cixiao2.mp3', - 'audio/skill/cixiong_skill.mp3', - 'audio/skill/clanbaichu1.mp3', - 'audio/skill/clanbaichu2.mp3', - 'audio/skill/clanbalong1.mp3', - 'audio/skill/clanbalong2.mp3', - 'audio/skill/clanbaozu_clan_zhonghui1.mp3', - 'audio/skill/clanbaozu_clan_zhonghui2.mp3', - 'audio/skill/clanbaozu_clan_zhongyan1.mp3', - 'audio/skill/clanbaozu_clan_zhongyan2.mp3', - 'audio/skill/clanbaozu_clan_zhongyu1.mp3', - 'audio/skill/clanbaozu_clan_zhongyu2.mp3', - 'audio/skill/clanbeishi1.mp3', - 'audio/skill/clanbeishi2.mp3', - 'audio/skill/clanbolong1.mp3', - 'audio/skill/clanbolong2.mp3', - 'audio/skill/clanchenya1.mp3', - 'audio/skill/clanchenya2.mp3', - 'audio/skill/clandaojie_clan_xuncai1.mp3', - 'audio/skill/clandaojie_clan_xuncai2.mp3', - 'audio/skill/clandaojie_clan_xuncan1.mp3', - 'audio/skill/clandaojie_clan_xuncan2.mp3', - 'audio/skill/clandaojie_clan_xunchen1.mp3', - 'audio/skill/clandaojie_clan_xunchen2.mp3', - 'audio/skill/clandaojie_clan_xunshu1.mp3', - 'audio/skill/clandaojie_clan_xunshu2.mp3', - 'audio/skill/clandaojie_clan_xunyou1.mp3', - 'audio/skill/clandaojie_clan_xunyou2.mp3', - 'audio/skill/clandianzhan1.mp3', - 'audio/skill/clandianzhan2.mp3', - 'audio/skill/clanfangzhen1.mp3', - 'audio/skill/clanfangzhen2.mp3', - 'audio/skill/clanfenchai1.mp3', - 'audio/skill/clanfenchai2.mp3', - 'audio/skill/clanfuxun1.mp3', - 'audio/skill/clanfuxun2.mp3', - 'audio/skill/clanguangu1.mp3', - 'audio/skill/clanguangu2.mp3', - 'audio/skill/clanguixiang1.mp3', - 'audio/skill/clanguixiang2.mp3', - 'audio/skill/clanhuanghan1.mp3', - 'audio/skill/clanhuanghan2.mp3', - 'audio/skill/clanhuanjia1.mp3', - 'audio/skill/clanhuanjia2.mp3', - 'audio/skill/clanhuanyin1.mp3', - 'audio/skill/clanhuanyin2.mp3', - 'audio/skill/clanjianyuan1.mp3', - 'audio/skill/clanjianyuan2.mp3', - 'audio/skill/clanjiejian1.mp3', - 'audio/skill/clanjiejian2.mp3', - 'audio/skill/clanjiexuan1.mp3', - 'audio/skill/clanjiexuan2.mp3', - 'audio/skill/clanlianhe1.mp3', - 'audio/skill/clanlianhe2.mp3', - 'audio/skill/clanlianzhu1.mp3', - 'audio/skill/clanlianzhu2.mp3', - 'audio/skill/clanlieshi1.mp3', - 'audio/skill/clanlieshi2.mp3', - 'audio/skill/clanliuju1.mp3', - 'audio/skill/clanliuju2.mp3', - 'audio/skill/clanmingjie1.mp3', - 'audio/skill/clanmingjie2.mp3', - 'audio/skill/clanmuyin_clan_wuban1.mp3', - 'audio/skill/clanmuyin_clan_wuban2.mp3', - 'audio/skill/clanmuyin_clan_wukuang1.mp3', - 'audio/skill/clanmuyin_clan_wukuang2.mp3', - 'audio/skill/clanmuyin_clan_wuxian1.mp3', - 'audio/skill/clanmuyin_clan_wuxian2.mp3', - 'audio/skill/clanqiuxin1.mp3', - 'audio/skill/clanqiuxin2.mp3', - 'audio/skill/clansankuang1.mp3', - 'audio/skill/clansankuang2.mp3', - 'audio/skill/clanshangshen1.mp3', - 'audio/skill/clanshangshen2.mp3', - 'audio/skill/clanshenjun1.mp3', - 'audio/skill/clanshenjun2.mp3', - 'audio/skill/clanxiaoyong1.mp3', - 'audio/skill/clanxiaoyong2.mp3', - 'audio/skill/clanxieshu1.mp3', - 'audio/skill/clanxieshu2.mp3', - 'audio/skill/clanxumin_clan_hanrong1.mp3', - 'audio/skill/clanxumin_clan_hanrong2.mp3', - 'audio/skill/clanxumin_clan_hanshao1.mp3', - 'audio/skill/clanxumin_clan_hanshao2.mp3', - 'audio/skill/clanyirong1.mp3', - 'audio/skill/clanyirong2.mp3', - 'audio/skill/clanyunshen1.mp3', - 'audio/skill/clanyunshen2.mp3', - 'audio/skill/clanyuzhi1.mp3', - 'audio/skill/clanyuzhi2.mp3', - 'audio/skill/clanzhanding1.mp3', - 'audio/skill/clanzhanding2.mp3', - 'audio/skill/clanzhongliu_clan_wanghun1.mp3', - 'audio/skill/clanzhongliu_clan_wanghun2.mp3', - 'audio/skill/clanzhongliu_clan_wangling1.mp3', - 'audio/skill/clanzhongliu_clan_wangling2.mp3', - 'audio/skill/clanzhongliu_clan_wanglun1.mp3', - 'audio/skill/clanzhongliu_clan_wanglun2.mp3', - 'audio/skill/clanzhongliu_clan_wangyun1.mp3', - 'audio/skill/clanzhongliu_clan_wangyun2.mp3', - 'audio/skill/congjian1.mp3', - 'audio/skill/congjian2.mp3', - 'audio/skill/cslilu1.mp3', - 'audio/skill/cslilu2.mp3', - 'audio/skill/csyizheng1.mp3', - 'audio/skill/csyizheng2.mp3', - 'audio/skill/cuguo1.mp3', - 'audio/skill/cuguo2.mp3', - 'audio/skill/cuijian1.mp3', - 'audio/skill/cuijian2.mp3', - 'audio/skill/cuijin1.mp3', - 'audio/skill/cuijin2.mp3', - 'audio/skill/cuijue1.mp3', - 'audio/skill/cuijue2.mp3', - 'audio/skill/cunsi1.mp3', - 'audio/skill/cunsi2.mp3', - 'audio/skill/cuorui1.mp3', - 'audio/skill/cuorui2.mp3', - 'audio/skill/cxliushi1.mp3', - 'audio/skill/cxliushi2.mp3', - 'audio/skill/dahe.mp3', - 'audio/skill/daiyan1.mp3', - 'audio/skill/daiyan2.mp3', - 'audio/skill/daming1.mp3', - 'audio/skill/daming2.mp3', - 'audio/skill/dangmo1.mp3', - 'audio/skill/dangmo2.mp3', - 'audio/skill/dangxian_guansuo1.mp3', - 'audio/skill/dangxian_guansuo2.mp3', - 'audio/skill/dangxian_re_liaohua1.mp3', - 'audio/skill/dangxian_re_liaohua2.mp3', - 'audio/skill/dangxian_xin_liaohua1.mp3', - 'audio/skill/dangxian_xin_liaohua2.mp3', - 'audio/skill/dangxian1.mp3', - 'audio/skill/dangxian2.mp3', - 'audio/skill/dangzai1.mp3', - 'audio/skill/dangzai2.mp3', - 'audio/skill/danji1.mp3', - 'audio/skill/danji2.mp3', - 'audio/skill/danlao1.mp3', - 'audio/skill/danlao2.mp3', - 'audio/skill/danshou1.mp3', - 'audio/skill/danshou2.mp3', - 'audio/skill/danxin1.mp3', - 'audio/skill/danxin2.mp3', - 'audio/skill/daoji1.mp3', - 'audio/skill/daoji2.mp3', - 'audio/skill/daoshu1.mp3', - 'audio/skill/daoshu2.mp3', - 'audio/skill/dawu1.mp3', - 'audio/skill/dawu2.mp3', - 'audio/skill/dbchongjian1.mp3', - 'audio/skill/dbchongjian2.mp3', - 'audio/skill/dbchoujue1.mp3', - 'audio/skill/dbchoujue2.mp3', - 'audio/skill/dbquedi1.mp3', - 'audio/skill/dbquedi2.mp3', - 'audio/skill/dbzhuifeng1.mp3', - 'audio/skill/dbzhuifeng2.mp3', - 'audio/skill/dcaichen1.mp3', - 'audio/skill/dcaichen2.mp3', - 'audio/skill/dcaishou1.mp3', - 'audio/skill/dcaishou2.mp3', - 'audio/skill/dcanliao1.mp3', - 'audio/skill/dcanliao2.mp3', - 'audio/skill/dcanxu1.mp3', - 'audio/skill/dcanxu2.mp3', - 'audio/skill/dcanzhi1.mp3', - 'audio/skill/dcanzhi2.mp3', - 'audio/skill/dcbeifen1.mp3', - 'audio/skill/dcbeifen2.mp3', - 'audio/skill/dcbeini1.mp3', - 'audio/skill/dcbeini2.mp3', - 'audio/skill/dcbenshi1.mp3', - 'audio/skill/dcbenshi2.mp3', - 'audio/skill/dcbianzhuang1.mp3', - 'audio/skill/dcbianzhuang2.mp3', - 'audio/skill/dcbihuo1.mp3', - 'audio/skill/dcbihuo2.mp3', - 'audio/skill/dcbingji1.mp3', - 'audio/skill/dcbingji2.mp3', - 'audio/skill/dccaisi1.mp3', - 'audio/skill/dccaisi2.mp3', - 'audio/skill/dccaixia1.mp3', - 'audio/skill/dccaixia2.mp3', - 'audio/skill/dccaizhuang1.mp3', - 'audio/skill/dccaizhuang2.mp3', - 'audio/skill/dccansi1.mp3', - 'audio/skill/dccansi2.mp3', - 'audio/skill/dcchaixie1.mp3', - 'audio/skill/dcchaixie2.mp3', - 'audio/skill/dcchangqu1.mp3', - 'audio/skill/dcchangqu2.mp3', - 'audio/skill/dcchanjuan1.mp3', - 'audio/skill/dcchanjuan2.mp3', - 'audio/skill/dcchenyong1.mp3', - 'audio/skill/dcchenyong2.mp3', - 'audio/skill/dcchiying1.mp3', - 'audio/skill/dcchiying2.mp3', - 'audio/skill/dcchongwang1.mp3', - 'audio/skill/dcchongwang2.mp3', - 'audio/skill/dcchongxu1.mp3', - 'audio/skill/dcchongxu2.mp3', - 'audio/skill/dcchongyi1.mp3', - 'audio/skill/dcchongyi2.mp3', - 'audio/skill/dccibei1.mp3', - 'audio/skill/dccibei2.mp3', - 'audio/skill/dccongshi1.mp3', - 'audio/skill/dccongshi2.mp3', - 'audio/skill/dcctjiuxian1.mp3', - 'audio/skill/dcctjiuxian2.mp3', - 'audio/skill/dccuichuan1.mp3', - 'audio/skill/dccuichuan2.mp3', - 'audio/skill/dccuijin1.mp3', - 'audio/skill/dccuijin2.mp3', - 'audio/skill/dccuixin1.mp3', - 'audio/skill/dccuixin2.mp3', - 'audio/skill/dccunwei1.mp3', - 'audio/skill/dccunwei2.mp3', - 'audio/skill/dcdanyi1.mp3', - 'audio/skill/dcdanyi2.mp3', - 'audio/skill/dcdanying1.mp3', - 'audio/skill/dcdanying2.mp3', - 'audio/skill/dcdehua1.mp3', - 'audio/skill/dcdehua2.mp3', - 'audio/skill/dcdeshao1.mp3', - 'audio/skill/dcdeshao2.mp3', - 'audio/skill/dcdeshi1.mp3', - 'audio/skill/dcdeshi2.mp3', - 'audio/skill/dcdingji1.mp3', - 'audio/skill/dcdingji2.mp3', - 'audio/skill/dcditing1.mp3', - 'audio/skill/dcditing2.mp3', - 'audio/skill/dcdouzhen1.mp3', - 'audio/skill/dcdouzhen2.mp3', - 'audio/skill/dcdyqingshi1.mp3', - 'audio/skill/dcdyqingshi2.mp3', - 'audio/skill/dcenyu1.mp3', - 'audio/skill/dcenyu2.mp3', - 'audio/skill/dcfangdu1.mp3', - 'audio/skill/dcfangdu2.mp3', - 'audio/skill/dcfanshi1.mp3', - 'audio/skill/dcfanshi2.mp3', - 'audio/skill/dcfanyin1.mp3', - 'audio/skill/dcfanyin2.mp3', - 'audio/skill/dcfaqi1.mp3', - 'audio/skill/dcfaqi2.mp3', - 'audio/skill/dcfencheng1.mp3', - 'audio/skill/dcfencheng2.mp3', - 'audio/skill/dcfengyan1.mp3', - 'audio/skill/dcfengyan2.mp3', - 'audio/skill/dcfengying1.mp3', - 'audio/skill/dcfengying2.mp3', - 'audio/skill/dcfozong1.mp3', - 'audio/skill/dcfozong2.mp3', - 'audio/skill/dcfudao1.mp3', - 'audio/skill/dcfudao2.mp3', - 'audio/skill/dcfudou1.mp3', - 'audio/skill/dcfudou2.mp3', - 'audio/skill/dcfuli1.mp3', - 'audio/skill/dcfuli2.mp3', - 'audio/skill/dcfumou1.mp3', - 'audio/skill/dcfumou2.mp3', - 'audio/skill/dcfuning1.mp3', - 'audio/skill/dcfuning2.mp3', - 'audio/skill/dcfuxue1.mp3', - 'audio/skill/dcfuxue2.mp3', - 'audio/skill/dcgeyuan1.mp3', - 'audio/skill/dcgeyuan2.mp3', - 'audio/skill/dcgonghu1.mp3', - 'audio/skill/dcgonghu2.mp3', - 'audio/skill/dcguangshi1.mp3', - 'audio/skill/dcguangshi2.mp3', - 'audio/skill/dcgue1.mp3', - 'audio/skill/dcgue2.mp3', - 'audio/skill/dcgusuan1.mp3', - 'audio/skill/dcgusuan2.mp3', - 'audio/skill/dchanying1.mp3', - 'audio/skill/dchanying2.mp3', - 'audio/skill/dchaochong1.mp3', - 'audio/skill/dchaochong2.mp3', - 'audio/skill/dchuace1.mp3', - 'audio/skill/dchuace2.mp3', - 'audio/skill/dchuagui1.mp3', - 'audio/skill/dchuagui2.mp3', - 'audio/skill/dchuahuo1.mp3', - 'audio/skill/dchuahuo2.mp3', - 'audio/skill/dchuayi1.mp3', - 'audio/skill/dchuayi2.mp3', - 'audio/skill/dchuiling1.mp3', - 'audio/skill/dchuiling2.mp3', - 'audio/skill/dchuishu1.mp3', - 'audio/skill/dchuishu2.mp3', - 'audio/skill/dchuizhi1.mp3', - 'audio/skill/dchuizhi2.mp3', - 'audio/skill/dchumei1.mp3', - 'audio/skill/dchumei2.mp3', - 'audio/skill/dcjianguo1.mp3', - 'audio/skill/dcjianguo2.mp3', - 'audio/skill/dcjianji1.mp3', - 'audio/skill/dcjianji2.mp3', - 'audio/skill/dcjianying1.mp3', - 'audio/skill/dcjianying2.mp3', - 'audio/skill/dcjianzheng1.mp3', - 'audio/skill/dcjianzheng2.mp3', - 'audio/skill/dcjianzhuan1.mp3', - 'audio/skill/dcjianzhuan2.mp3', - 'audio/skill/dcjiaofeng1.mp3', - 'audio/skill/dcjiaofeng2.mp3', - 'audio/skill/dcjiaoxia1.mp3', - 'audio/skill/dcjiaoxia2.mp3', - 'audio/skill/dcjichun1.mp3', - 'audio/skill/dcjichun2.mp3', - 'audio/skill/dcjieling1.mp3', - 'audio/skill/dcjieling2.mp3', - 'audio/skill/dcjieshu1.mp3', - 'audio/skill/dcjieshu2.mp3', - 'audio/skill/dcjiexing1.mp3', - 'audio/skill/dcjiexing2.mp3', - 'audio/skill/dcjiezhen1.mp3', - 'audio/skill/dcjiezhen2.mp3', - 'audio/skill/dcjijiao1.mp3', - 'audio/skill/dcjijiao2.mp3', - 'audio/skill/dcjincui1.mp3', - 'audio/skill/dcjincui2.mp3', - 'audio/skill/dcjinggong1.mp3', - 'audio/skill/dcjinggong2.mp3', - 'audio/skill/dcjingzao1.mp3', - 'audio/skill/dcjingzao2.mp3', - 'audio/skill/dcjini1.mp3', - 'audio/skill/dcjini2.mp3', - 'audio/skill/dcjinjian1.mp3', - 'audio/skill/dcjinjian2.mp3', - 'audio/skill/dcjinjie1.mp3', - 'audio/skill/dcjinjie2.mp3', - 'audio/skill/dcjinjin1.mp3', - 'audio/skill/dcjinjin2.mp3', - 'audio/skill/dcjiudun1.mp3', - 'audio/skill/dcjiudun2.mp3', - 'audio/skill/dcjiushi1.mp3', - 'audio/skill/dcjiushi2.mp3', - 'audio/skill/dcjizhong1.mp3', - 'audio/skill/dcjizhong2.mp3', - 'audio/skill/dcjue1.mp3', - 'audio/skill/dcjue2.mp3', - 'audio/skill/dcjuejing1.mp3', - 'audio/skill/dcjuejing2.mp3', - 'audio/skill/dcjuying1.mp3', - 'audio/skill/dcjuying2.mp3', - 'audio/skill/dckaiji1.mp3', - 'audio/skill/dckaiji2.mp3', - 'audio/skill/dckanji1.mp3', - 'audio/skill/dckanji2.mp3', - 'audio/skill/dclbjiuxian1.mp3', - 'audio/skill/dclbjiuxian2.mp3', - 'audio/skill/dcliangxiu1.mp3', - 'audio/skill/dcliangxiu2.mp3', - 'audio/skill/dclianzhi1.mp3', - 'audio/skill/dclianzhi2.mp3', - 'audio/skill/dclibang1.mp3', - 'audio/skill/dclibang2.mp3', - 'audio/skill/dcliehou1.mp3', - 'audio/skill/dcliehou2.mp3', - 'audio/skill/dcligong1.mp3', - 'audio/skill/dcligong2.mp3', - 'audio/skill/dclingfang1.mp3', - 'audio/skill/dclingfang2.mp3', - 'audio/skill/dclinghui1.mp3', - 'audio/skill/dclinghui2.mp3', - 'audio/skill/dclingkong1.mp3', - 'audio/skill/dclingkong2.mp3', - 'audio/skill/dclingxi1.mp3', - 'audio/skill/dclingxi2.mp3', - 'audio/skill/dclingyin1.mp3', - 'audio/skill/dclingyin2.mp3', - 'audio/skill/dclingyue1.mp3', - 'audio/skill/dclingyue2.mp3', - 'audio/skill/dcliuzhuan1.mp3', - 'audio/skill/dcliuzhuan2.mp3', - 'audio/skill/dcliying1.mp3', - 'audio/skill/dcliying2.mp3', - 'audio/skill/dclonggong1.mp3', - 'audio/skill/dclonggong2.mp3', - 'audio/skill/dclonghun1.mp3', - 'audio/skill/dclonghun2.mp3', - 'audio/skill/dclongsong1.mp3', - 'audio/skill/dclongsong2.mp3', - 'audio/skill/dcluochong1.mp3', - 'audio/skill/dcluochong2.mp3', - 'audio/skill/dclvecheng1.mp3', - 'audio/skill/dclvecheng2.mp3', - 'audio/skill/dcmanzhi1.mp3', - 'audio/skill/dcmanzhi2.mp3', - 'audio/skill/dcmengjie1.mp3', - 'audio/skill/dcmengjie2.mp3', - 'audio/skill/dcmieji1.mp3', - 'audio/skill/dcmieji2.mp3', - 'audio/skill/dcmingfa1.mp3', - 'audio/skill/dcmingfa2.mp3', - 'audio/skill/dcminze1.mp3', - 'audio/skill/dcminze2.mp3', - 'audio/skill/dcmiyi1.mp3', - 'audio/skill/dcmiyi2.mp3', - 'audio/skill/dcmiyun1.mp3', - 'audio/skill/dcmiyun2.mp3', - 'audio/skill/dcmoyu1.mp3', - 'audio/skill/dcmoyu2.mp3', - 'audio/skill/dcneifa1.mp3', - 'audio/skill/dcneifa2.mp3', - 'audio/skill/dcniji1.mp3', - 'audio/skill/dcniji2.mp3', - 'audio/skill/dcnuanhui1.mp3', - 'audio/skill/dcnuanhui2.mp3', - 'audio/skill/dcnuchen1.mp3', - 'audio/skill/dcnuchen2.mp3', - 'audio/skill/dcnutao1.mp3', - 'audio/skill/dcnutao2.mp3', - 'audio/skill/dcnutao3.mp3', - 'audio/skill/dcnutao4.mp3', - 'audio/skill/dcpandi1.mp3', - 'audio/skill/dcpandi2.mp3', - 'audio/skill/dcpeiqi1.mp3', - 'audio/skill/dcpeiqi2.mp3', - 'audio/skill/dcpijing1.mp3', - 'audio/skill/dcpijing2.mp3', - 'audio/skill/dcpingxi1.mp3', - 'audio/skill/dcpingxi2.mp3', - 'audio/skill/dcpitian1.mp3', - 'audio/skill/dcpitian2.mp3', - 'audio/skill/dcporui1.mp3', - 'audio/skill/dcporui2.mp3', - 'audio/skill/dcposuo1.mp3', - 'audio/skill/dcposuo2.mp3', - 'audio/skill/dcpoyuan1.mp3', - 'audio/skill/dcpoyuan2.mp3', - 'audio/skill/dcqiangzhi1.mp3', - 'audio/skill/dcqiangzhi2.mp3', - 'audio/skill/dcqianzheng1.mp3', - 'audio/skill/dcqianzheng2.mp3', - 'audio/skill/dcqiaomeng1.mp3', - 'audio/skill/dcqiaomeng2.mp3', - 'audio/skill/dcqijing1.mp3', - 'audio/skill/dcqijing2.mp3', - 'audio/skill/dcqinghuang1.mp3', - 'audio/skill/dcqinghuang2.mp3', - 'audio/skill/dcqingren1.mp3', - 'audio/skill/dcqingren2.mp3', - 'audio/skill/dcqingshi1.mp3', - 'audio/skill/dcqingshi2.mp3', - 'audio/skill/dcqingyan1.mp3', - 'audio/skill/dcqingyan2.mp3', - 'audio/skill/dcqinqing1.mp3', - 'audio/skill/dcqinqing2.mp3', - 'audio/skill/dcqinshen1.mp3', - 'audio/skill/dcqinshen2.mp3', - 'audio/skill/dcqiongying1.mp3', - 'audio/skill/dcqiongying2.mp3', - 'audio/skill/dcqiqin_yue_daqiao1.mp3', - 'audio/skill/dcqiqin_yue_daqiao2.mp3', - 'audio/skill/dcqiqin1.mp3', - 'audio/skill/dcqiqin2.mp3', - 'audio/skill/dcquanjian1.mp3', - 'audio/skill/dcquanjian2.mp3', - 'audio/skill/dcquanshou1.mp3', - 'audio/skill/dcquanshou2.mp3', - 'audio/skill/dcrihui1.mp3', - 'audio/skill/dcrihui2.mp3', - 'audio/skill/dcruizhan1.mp3', - 'audio/skill/dcruizhan2.mp3', - 'audio/skill/dcruxian1.mp3', - 'audio/skill/dcruxian2.mp3', - 'audio/skill/dcruyi1.mp3', - 'audio/skill/dcruyi2.mp3', - 'audio/skill/dcsantou1.mp3', - 'audio/skill/dcsantou2.mp3', - 'audio/skill/dcsaowei1.mp3', - 'audio/skill/dcsaowei2.mp3', - 'audio/skill/dcsbmengmou1.mp3', - 'audio/skill/dcsbmengmou2.mp3', - 'audio/skill/dcsbmingshi1.mp3', - 'audio/skill/dcsbmingshi2.mp3', - 'audio/skill/dcsbpingliao_dc_sb_simayi_shadow1.mp3', - 'audio/skill/dcsbpingliao_dc_sb_simayi_shadow2.mp3', - 'audio/skill/dcsbpingliao1.mp3', - 'audio/skill/dcsbpingliao2.mp3', - 'audio/skill/dcsbquanmou_dc_sb_simayi_shadow1.mp3', - 'audio/skill/dcsbquanmou_dc_sb_simayi_shadow2.mp3', - 'audio/skill/dcsbquanmou1.mp3', - 'audio/skill/dcsbquanmou2.mp3', - 'audio/skill/dcsbronghuo1.mp3', - 'audio/skill/dcsbronghuo2.mp3', - 'audio/skill/dcsbyingmou1.mp3', - 'audio/skill/dcsbyingmou2.mp3', - 'audio/skill/dcshangyu1.mp3', - 'audio/skill/dcshangyu2.mp3', - 'audio/skill/dcshengdu1.mp3', - 'audio/skill/dcshengdu2.mp3', - 'audio/skill/dcshexue1.mp3', - 'audio/skill/dcshexue2.mp3', - 'audio/skill/dcshibei1.mp3', - 'audio/skill/dcshibei2.mp3', - 'audio/skill/dcshiji1.mp3', - 'audio/skill/dcshiji2.mp3', - 'audio/skill/dcshilie1.mp3', - 'audio/skill/dcshilie2.mp3', - 'audio/skill/dcshixian1.mp3', - 'audio/skill/dcshixian2.mp3', - 'audio/skill/dcshizhao1.mp3', - 'audio/skill/dcshizhao2.mp3', - 'audio/skill/dcshizong1.mp3', - 'audio/skill/dcshizong2.mp3', - 'audio/skill/dcshoutan1.mp3', - 'audio/skill/dcshoutan2.mp3', - 'audio/skill/dcshouze.mp3', - 'audio/skill/dcshuaijie1.mp3', - 'audio/skill/dcshuaijie2.mp3', - 'audio/skill/dcshuangjia1.mp3', - 'audio/skill/dcshuangjia2.mp3', - 'audio/skill/dcshuangren1.mp3', - 'audio/skill/dcshuangren2.mp3', - 'audio/skill/dcshuhe1.mp3', - 'audio/skill/dcshuhe2.mp3', - 'audio/skill/dcsigong1.mp3', - 'audio/skill/dcsigong2.mp3', - 'audio/skill/dcsilun1.mp3', - 'audio/skill/dcsilun2.mp3', - 'audio/skill/dcsilve1.mp3', - 'audio/skill/dcsilve2.mp3', - 'audio/skill/dcsitian1.mp3', - 'audio/skill/dcsitian2.mp3', - 'audio/skill/dcsuifu1.mp3', - 'audio/skill/dcsuifu2.mp3', - 'audio/skill/dcsushou1.mp3', - 'audio/skill/dcsushou2.mp3', - 'audio/skill/dctaji1.mp3', - 'audio/skill/dctaji2.mp3', - 'audio/skill/dctianji1.mp3', - 'audio/skill/dctianji2.mp3', - 'audio/skill/dctingxian1.mp3', - 'audio/skill/dctingxian2.mp3', - 'audio/skill/dctongguan1.mp3', - 'audio/skill/dctongguan2.mp3', - 'audio/skill/dctongliao1.mp3', - 'audio/skill/dctongliao2.mp3', - 'audio/skill/dctongliao3.mp3', - 'audio/skill/dctongye1.mp3', - 'audio/skill/dctongye2.mp3', - 'audio/skill/dctujue1.mp3', - 'audio/skill/dctujue2.mp3', - 'audio/skill/dctuoyu1.mp3', - 'audio/skill/dctuoyu2.mp3', - 'audio/skill/dcwanglu1.mp3', - 'audio/skill/dcwanglu2.mp3', - 'audio/skill/dcwangyuan1.mp3', - 'audio/skill/dcwangyuan2.mp3', - 'audio/skill/dcweidang1.mp3', - 'audio/skill/dcweidang2.mp3', - 'audio/skill/dcweiwan1.mp3', - 'audio/skill/dcweiwan2.mp3', - 'audio/skill/dcwencan1.mp3', - 'audio/skill/dcwencan2.mp3', - 'audio/skill/dcwudao1.mp3', - 'audio/skill/dcwudao2.mp3', - 'audio/skill/dcwudao3.mp3', - 'audio/skill/dcwujie1.mp3', - 'audio/skill/dcwujie2.mp3', - 'audio/skill/dcwumei1.mp3', - 'audio/skill/dcwumei2.mp3', - 'audio/skill/dcwuyuan1.mp3', - 'audio/skill/dcwuyuan2.mp3', - 'audio/skill/dcxiace1.mp3', - 'audio/skill/dcxiace2.mp3', - 'audio/skill/dcxialei1.mp3', - 'audio/skill/dcxialei2.mp3', - 'audio/skill/dcxiangmian1.mp3', - 'audio/skill/dcxiangmian2.mp3', - 'audio/skill/dcxiangshu1.mp3', - 'audio/skill/dcxiangshu2.mp3', - 'audio/skill/dcxianjin1.mp3', - 'audio/skill/dcxianjin2.mp3', - 'audio/skill/dcxianshu1.mp3', - 'audio/skill/dcxianshu2.mp3', - 'audio/skill/dcxianzhu1.mp3', - 'audio/skill/dcxianzhu2.mp3', - 'audio/skill/dcxiaojuan1.mp3', - 'audio/skill/dcxiaojuan2.mp3', - 'audio/skill/dcxiaoren1.mp3', - 'audio/skill/dcxiaoren2.mp3', - 'audio/skill/dcxiaoxi1.mp3', - 'audio/skill/dcxiaoxi2.mp3', - 'audio/skill/dcxiaoyin1.mp3', - 'audio/skill/dcxiaoyin2.mp3', - 'audio/skill/dcxieshou1.mp3', - 'audio/skill/dcxieshou2.mp3', - 'audio/skill/dcxinyou1.mp3', - 'audio/skill/dcxinyou2.mp3', - 'audio/skill/dcxiongmu1.mp3', - 'audio/skill/dcxiongmu2.mp3', - 'audio/skill/dcxiuwen1.mp3', - 'audio/skill/dcxiuwen2.mp3', - 'audio/skill/dcxuewei1.mp3', - 'audio/skill/dcxuewei2.mp3', - 'audio/skill/dcxunbie1.mp3', - 'audio/skill/dcxunbie2.mp3', - 'audio/skill/dcxunji1.mp3', - 'audio/skill/dcxunji2.mp3', - 'audio/skill/dcxunjie1.mp3', - 'audio/skill/dcxunjie2.mp3', - 'audio/skill/dcyaoyi1.mp3', - 'audio/skill/dcyaoyi2.mp3', - 'audio/skill/dcyicong1.mp3', - 'audio/skill/dcyicong2.mp3', - 'audio/skill/dcyijia1.mp3', - 'audio/skill/dcyijia2.mp3', - 'audio/skill/dcyingtu1.mp3', - 'audio/skill/dcyingtu2.mp3', - 'audio/skill/dcyingyu1.mp3', - 'audio/skill/dcyingyu2.mp3', - 'audio/skill/dcyinjun1.mp3', - 'audio/skill/dcyinjun2.mp3', - 'audio/skill/dcyinlu1.mp3', - 'audio/skill/dcyinlu2.mp3', - 'audio/skill/dcyinshi1.mp3', - 'audio/skill/dcyinshi2.mp3', - 'audio/skill/dcyishu1.mp3', - 'audio/skill/dcyishu2.mp3', - 'audio/skill/dcyiyong1.mp3', - 'audio/skill/dcyiyong2.mp3', - 'audio/skill/dcyongbi1.mp3', - 'audio/skill/dcyongbi2.mp3', - 'audio/skill/dcyouqi1.mp3', - 'audio/skill/dcyouqi2.mp3', - 'audio/skill/dcyouzhan1.mp3', - 'audio/skill/dcyouzhan2.mp3', - 'audio/skill/dcyuandi1.mp3', - 'audio/skill/dcyuandi2.mp3', - 'audio/skill/dcyuanmo1.mp3', - 'audio/skill/dcyuanmo2.mp3', - 'audio/skill/dcyuguan1.mp3', - 'audio/skill/dcyuguan2.mp3', - 'audio/skill/dcyuxin1.mp3', - 'audio/skill/dcyuxin2.mp3', - 'audio/skill/dczecai1.mp3', - 'audio/skill/dczecai2.mp3', - 'audio/skill/dczhangcai1.mp3', - 'audio/skill/dczhangcai2.mp3', - 'audio/skill/dczhanmeng1.mp3', - 'audio/skill/dczhanmeng2.mp3', - 'audio/skill/dczhanyi1.mp3', - 'audio/skill/dczhanyi2.mp3', - 'audio/skill/dczhaohan1.mp3', - 'audio/skill/dczhaohan2.mp3', - 'audio/skill/dczhaowen1.mp3', - 'audio/skill/dczhaowen2.mp3', - 'audio/skill/dczhengxu1.mp3', - 'audio/skill/dczhengxu2.mp3', - 'audio/skill/dczhenze1.mp3', - 'audio/skill/dczhenze2.mp3', - 'audio/skill/dczhifou1.mp3', - 'audio/skill/dczhifou2.mp3', - 'audio/skill/dczhizhe1.mp3', - 'audio/skill/dczhizhe2.mp3', - 'audio/skill/dczhongji1.mp3', - 'audio/skill/dczhongji2.mp3', - 'audio/skill/dczhongjie1.mp3', - 'audio/skill/dczhongjie2.mp3', - 'audio/skill/dczhouli2.mp3', - 'audio/skill/dczhubi1.mp3', - 'audio/skill/dczhubi2.mp3', - 'audio/skill/dczhuiyi1.mp3', - 'audio/skill/dczhuiyi2.mp3', - 'audio/skill/dczhuoli1.mp3', - 'audio/skill/dczigu1.mp3', - 'audio/skill/dczigu2.mp3', - 'audio/skill/dczimu1.mp3', - 'audio/skill/dczixi1.mp3', - 'audio/skill/dczixi2.mp3', - 'audio/skill/dczuojian1.mp3', - 'audio/skill/dczuojian2.mp3', - 'audio/skill/dczuowei1.mp3', - 'audio/skill/dczuowei2.mp3', - 'audio/skill/debao1.mp3', - 'audio/skill/debao2.mp3', - 'audio/skill/decadejingce1.mp3', - 'audio/skill/decadejingce2.mp3', - 'audio/skill/decadejinjiu1.mp3', - 'audio/skill/decadejinjiu2.mp3', - 'audio/skill/decadepojun1.mp3', - 'audio/skill/decadepojun2.mp3', - 'audio/skill/decadexianzhen1.mp3', - 'audio/skill/decadexianzhen2.mp3', - 'audio/skill/decadezhenjun1.mp3', - 'audio/skill/decadezhenjun2.mp3', - 'audio/skill/decadezishou1.mp3', - 'audio/skill/decadezishou2.mp3', - 'audio/skill/decadezongshi1.mp3', - 'audio/skill/decadezongshi2.mp3', - 'audio/skill/dengji1.mp3', - 'audio/skill/dengji2.mp3', - 'audio/skill/dengzhi.mp3', - 'audio/skill/dezhang1.mp3', - 'audio/skill/dezhang2.mp3', - 'audio/skill/diancai1.mp3', - 'audio/skill/diancai2.mp3', - 'audio/skill/diaodu1.mp3', - 'audio/skill/diaodu2.mp3', - 'audio/skill/diaoling1.mp3', - 'audio/skill/diaoling2.mp3', - 'audio/skill/diezhang1.mp3', - 'audio/skill/diezhang2.mp3', - 'audio/skill/difa1.mp3', - 'audio/skill/difa2.mp3', - 'audio/skill/dili_chigang1.mp3', - 'audio/skill/dili_chigang2.mp3', - 'audio/skill/dili_jiaohui1.mp3', - 'audio/skill/dili_jiaohui2.mp3', - 'audio/skill/dili_qionglan1.mp3', - 'audio/skill/dili_qionglan2.mp3', - 'audio/skill/dili_quandao1.mp3', - 'audio/skill/dili_quandao2.mp3', - 'audio/skill/dili_shengzhi1.mp3', - 'audio/skill/dili_shengzhi2.mp3', - 'audio/skill/dili_yuanlv1.mp3', - 'audio/skill/dili_yuanlv2.mp3', - 'audio/skill/dili1.mp3', - 'audio/skill/dili2.mp3', - 'audio/skill/dimeng1.mp3', - 'audio/skill/dimeng2.mp3', - 'audio/skill/dingfa1.mp3', - 'audio/skill/dingfa2.mp3', - 'audio/skill/dinghan1.mp3', - 'audio/skill/dinghan2.mp3', - 'audio/skill/dingpan1.mp3', - 'audio/skill/dingpan2.mp3', - 'audio/skill/dingpin1.mp3', - 'audio/skill/dingpin2.mp3', - 'audio/skill/dingzhou1.mp3', - 'audio/skill/dingzhou2.mp3', - 'audio/skill/disordersidi1.mp3', - 'audio/skill/disordersidi2.mp3', - 'audio/skill/donggui1.mp3', - 'audio/skill/donggui2.mp3', - 'audio/skill/drlt_congjian1.mp3', - 'audio/skill/drlt_congjian2.mp3', - 'audio/skill/drlt_duorui1.mp3', - 'audio/skill/drlt_duorui2.mp3', - 'audio/skill/drlt_hongju1.mp3', - 'audio/skill/drlt_hongju2.mp3', - 'audio/skill/drlt_huairou1.mp3', - 'audio/skill/drlt_huairou2.mp3', - 'audio/skill/drlt_jieying1.mp3', - 'audio/skill/drlt_jieying2.mp3', - 'audio/skill/drlt_jueyan1.mp3', - 'audio/skill/drlt_jueyan2.mp3', - 'audio/skill/drlt_poshi1.mp3', - 'audio/skill/drlt_poshi2.mp3', - 'audio/skill/drlt_poxi1.mp3', - 'audio/skill/drlt_poxi2.mp3', - 'audio/skill/drlt_qianjie1.mp3', - 'audio/skill/drlt_qianjie2.mp3', - 'audio/skill/drlt_qingce1.mp3', - 'audio/skill/drlt_qingce2.mp3', - 'audio/skill/drlt_wanglie1.mp3', - 'audio/skill/drlt_wanglie2.mp3', - 'audio/skill/drlt_weidi1.mp3', - 'audio/skill/drlt_weidi2.mp3', - 'audio/skill/drlt_xiongluan1.mp3', - 'audio/skill/drlt_xiongluan2.mp3', - 'audio/skill/drlt_yongsi1.mp3', - 'audio/skill/drlt_yongsi2.mp3', - 'audio/skill/drlt_zhenggu1.mp3', - 'audio/skill/drlt_zhenggu2.mp3', - 'audio/skill/drlt_zhenrong1.mp3', - 'audio/skill/drlt_zhenrong2.mp3', - 'audio/skill/drlt_zhiti1.mp3', - 'audio/skill/drlt_zhiti2.mp3', - 'audio/skill/duanbi1.mp3', - 'audio/skill/duanbi2.mp3', - 'audio/skill/duanbing_heqi1.mp3', - 'audio/skill/duanbing_heqi2.mp3', - 'audio/skill/duanbing1.mp3', - 'audio/skill/duanbing2.mp3', - 'audio/skill/duanchang_ol_caiwenji1.mp3', - 'audio/skill/duanchang_ol_caiwenji2.mp3', - 'audio/skill/duanchang_re_caiwenji1.mp3', - 'audio/skill/duanchang_re_caiwenji2.mp3', - 'audio/skill/duanchang1.mp3', - 'audio/skill/duanchang2.mp3', - 'audio/skill/duanliang1_re_xuhuang1.mp3', - 'audio/skill/duanliang1_re_xuhuang2.mp3', - 'audio/skill/duanliang11.mp3', - 'audio/skill/duanliang12.mp3', - 'audio/skill/duansuo1.mp3', - 'audio/skill/duansuo2.mp3', - 'audio/skill/duanwan1.mp3', - 'audio/skill/duanwan2.mp3', - 'audio/skill/duanxie1.mp3', - 'audio/skill/duanxie2.mp3', - 'audio/skill/dujin1.mp3', - 'audio/skill/dujin2.mp3', - 'audio/skill/duliang1.mp3', - 'audio/skill/duliang2.mp3', - 'audio/skill/dulie1.mp3', - 'audio/skill/dulie2.mp3', - 'audio/skill/dunshi1.mp3', - 'audio/skill/dunshi2.mp3', - 'audio/skill/dunxi1.mp3', - 'audio/skill/dunxi2.mp3', - 'audio/skill/duodao1.mp3', - 'audio/skill/duodao2.mp3', - 'audio/skill/duoduan1.mp3', - 'audio/skill/duoduan2.mp3', - 'audio/skill/duoji1.mp3', - 'audio/skill/duoji2.mp3', - 'audio/skill/duoshi1.mp3', - 'audio/skill/duoshi2.mp3', - 'audio/skill/dushi1.mp3', - 'audio/skill/dushi2.mp3', - 'audio/skill/duwang1.mp3', - 'audio/skill/duwang2.mp3', - 'audio/skill/duwu1.mp3', - 'audio/skill/duwu2.mp3', - 'audio/skill/dzgengzhan1.mp3', - 'audio/skill/dzgengzhan2.mp3', - 'audio/skill/dzkanpo1.mp3', - 'audio/skill/dzkanpo2.mp3', - 'audio/skill/ejian1.mp3', - 'audio/skill/ejian2.mp3', - 'audio/skill/enyuan1.mp3', - 'audio/skill/enyuan2.mp3', - 'audio/skill/equan1.mp3', - 'audio/skill/equan2.mp3', - 'audio/skill/faen1.mp3', - 'audio/skill/faen2.mp3', - 'audio/skill/fanghun1.mp3', - 'audio/skill/fanghun2.mp3', - 'audio/skill/fangquan1.mp3', - 'audio/skill/fangquan2.mp3', - 'audio/skill/fangtian_skill.mp3', - 'audio/skill/fangzhu1.mp3', - 'audio/skill/fangzhu2.mp3', - 'audio/skill/fanjian1.mp3', - 'audio/skill/fanjian2.mp3', - 'audio/skill/fankui1.mp3', - 'audio/skill/fankui2.mp3', - 'audio/skill/fanxiang1.mp3', - 'audio/skill/fanxiang2.mp3', - 'audio/skill/fencheng1.mp3', - 'audio/skill/fencheng2.mp3', - 'audio/skill/fengji1.mp3', - 'audio/skill/fengji2.mp3', - 'audio/skill/fengjie1.mp3', - 'audio/skill/fengjie2.mp3', - 'audio/skill/fengliang1.mp3', - 'audio/skill/fengliang2.mp3', - 'audio/skill/fenglve1.mp3', - 'audio/skill/fenglve2.mp3', - 'audio/skill/fengpo1.mp3', - 'audio/skill/fengpo2.mp3', - 'audio/skill/fengwu1.mp3', - 'audio/skill/fengwu2.mp3', - 'audio/skill/fengxiang1.mp3', - 'audio/skill/fengxiang2.mp3', - 'audio/skill/fengyang1.mp3', - 'audio/skill/fengyang2.mp3', - 'audio/skill/fengying1.mp3', - 'audio/skill/fengying2.mp3', - 'audio/skill/fenji1.mp3', - 'audio/skill/fenji2.mp3', - 'audio/skill/fenli_xin_zhuhuan1.mp3', - 'audio/skill/fenli_xin_zhuhuan2.mp3', - 'audio/skill/fenli1.mp3', - 'audio/skill/fenli2.mp3', - 'audio/skill/fenming1.mp3', - 'audio/skill/fenming2.mp3', - 'audio/skill/fenrui1.mp3', - 'audio/skill/fenrui2.mp3', - 'audio/skill/fensi1.mp3', - 'audio/skill/fensi2.mp3', - 'audio/skill/fentian1.mp3', - 'audio/skill/fentian2.mp3', - 'audio/skill/fenwei_heqi1.mp3', - 'audio/skill/fenwei_heqi2.mp3', - 'audio/skill/fenwei1.mp3', - 'audio/skill/fenwei2.mp3', - 'audio/skill/fenxin1.mp3', - 'audio/skill/fenxin2.mp3', - 'audio/skill/fenxun1.mp3', - 'audio/skill/fenxun2.mp3', - 'audio/skill/fenyin1.mp3', - 'audio/skill/fenyin2.mp3', - 'audio/skill/fenyong1.mp3', - 'audio/skill/fenyong2.mp3', - 'audio/skill/fenyue1.mp3', - 'audio/skill/fenyue2.mp3', - 'audio/skill/fubi1.mp3', - 'audio/skill/fubi2.mp3', - 'audio/skill/fuhan1.mp3', - 'audio/skill/fuhan2.mp3', - 'audio/skill/fuhun_re_guanzhang1.mp3', - 'audio/skill/fuhun_re_guanzhang2.mp3', - 'audio/skill/fuhun1.mp3', - 'audio/skill/fuhun2.mp3', - 'audio/skill/fuli1.mp3', - 'audio/skill/fuli2.mp3', - 'audio/skill/fulin1.mp3', - 'audio/skill/fulin2.mp3', - 'audio/skill/fuman1.mp3', - 'audio/skill/fuman2.mp3', - 'audio/skill/fumian1.mp3', - 'audio/skill/fumian2.mp3', - 'audio/skill/funan1.mp3', - 'audio/skill/funan2.mp3', - 'audio/skill/fuping1.mp3', - 'audio/skill/fuping2.mp3', - 'audio/skill/fuqi1.mp3', - 'audio/skill/fuqi2.mp3', - 'audio/skill/fuyuan1.mp3', - 'audio/skill/fuyuan2.mp3', - 'audio/skill/fuzhong1.mp3', - 'audio/skill/fuzhong2.mp3', - 'audio/skill/fuzhu1.mp3', - 'audio/skill/fuzhu2.mp3', - 'audio/skill/fyjianyu1.mp3', - 'audio/skill/fyjianyu2.mp3', - 'audio/skill/fz_liegong.mp3', - 'audio/skill/fz_new_longdan.mp3', - 'audio/skill/fz_new_paoxiao.mp3', - 'audio/skill/fz_new_tieji.mp3', - 'audio/skill/fz_wusheng.mp3', - 'audio/skill/fz_xinkuanggu.mp3', - 'audio/skill/ganglie1.mp3', - 'audio/skill/ganglie2.mp3', - 'audio/skill/gangzhi1.mp3', - 'audio/skill/gangzhi2.mp3', - 'audio/skill/ganlu1.mp3', - 'audio/skill/ganlu2.mp3', - 'audio/skill/gaoling1.mp3', - 'audio/skill/gaoling2.mp3', - 'audio/skill/gaoyuan1.mp3', - 'audio/skill/gaoyuan2.mp3', - 'audio/skill/gebo1.mp3', - 'audio/skill/gebo2.mp3', - 'audio/skill/gnjinfan1.mp3', - 'audio/skill/gnjinfan2.mp3', - 'audio/skill/gnsheque1.mp3', - 'audio/skill/gnsheque2.mp3', - 'audio/skill/gongao1.mp3', - 'audio/skill/gongao2.mp3', - 'audio/skill/gonghuan1.mp3', - 'audio/skill/gonghuan2.mp3', - 'audio/skill/gongji1.mp3', - 'audio/skill/gongji2.mp3', - 'audio/skill/gongjian1.mp3', - 'audio/skill/gongjian2.mp3', - 'audio/skill/gongsun1.mp3', - 'audio/skill/gongsun2.mp3', - 'audio/skill/gongxin_gexuan1.mp3', - 'audio/skill/gongxin_re_lvmeng1.mp3', - 'audio/skill/gongxin_re_lvmeng2.mp3', - 'audio/skill/gongxin1.mp3', - 'audio/skill/gongxin2.mp3', - 'audio/skill/gongxiu1.mp3', - 'audio/skill/gongxiu2.mp3', - 'audio/skill/guanshi_skill.mp3', - 'audio/skill/guanxing_gexuan1.mp3', - 'audio/skill/guanxing_jiangwei1.mp3', - 'audio/skill/guanxing_jiangwei2.mp3', - 'audio/skill/guanxing_ol_jiangwei1.mp3', - 'audio/skill/guanxing_ol_jiangwei2.mp3', - 'audio/skill/guanxing_re_jiangwei1.mp3', - 'audio/skill/guanxing_re_jiangwei2.mp3', - 'audio/skill/guanxing_re_zhugeliang1.mp3', - 'audio/skill/guanxing_re_zhugeliang2.mp3', - 'audio/skill/guanxing1.mp3', - 'audio/skill/guanxing2.mp3', - 'audio/skill/guanxu1.mp3', - 'audio/skill/guanxu2.mp3', - 'audio/skill/guanzong1.mp3', - 'audio/skill/guanzong2.mp3', - 'audio/skill/guding_skill.mp3', - 'audio/skill/guhuo_guess1.mp3', - 'audio/skill/guhuo_guess2.mp3', - 'audio/skill/guhuo1.mp3', - 'audio/skill/guhuo2.mp3', - 'audio/skill/guicai1.mp3', - 'audio/skill/guicai2.mp3', - 'audio/skill/guidao_sp_zhangjiao1.mp3', - 'audio/skill/guidao_sp_zhangjiao2.mp3', - 'audio/skill/guidao1.mp3', - 'audio/skill/guidao2.mp3', - 'audio/skill/guili1.mp3', - 'audio/skill/guili2.mp3', - 'audio/skill/guiming1.mp3', - 'audio/skill/guiming2.mp3', - 'audio/skill/guimou1.mp3', - 'audio/skill/guimou2.mp3', - 'audio/skill/guixin1.mp3', - 'audio/skill/guixin2.mp3', - 'audio/skill/guixiu1.mp3', - 'audio/skill/guixiu2.mp3', - 'audio/skill/guizao1.mp3', - 'audio/skill/guizao2.mp3', - 'audio/skill/guizhen1.mp3', - 'audio/skill/guizhen2.mp3', - 'audio/skill/guju_tw_beimihu1.mp3', - 'audio/skill/guju_tw_beimihu2.mp3', - 'audio/skill/guju1.mp3', - 'audio/skill/guju2.mp3', - 'audio/skill/guose1.mp3', - 'audio/skill/guose2.mp3', - 'audio/skill/guowu1.mp3', - 'audio/skill/guowu2.mp3', - 'audio/skill/gushe1.mp3', - 'audio/skill/gushe2.mp3', - 'audio/skill/guying1.mp3', - 'audio/skill/guying2.mp3', - 'audio/skill/guzheng_re_zhangzhang1.mp3', - 'audio/skill/guzheng_re_zhangzhang2.mp3', - 'audio/skill/guzheng1.mp3', - 'audio/skill/guzheng2.mp3', - 'audio/skill/gxlianhua1.mp3', - 'audio/skill/gxlianhua2.mp3', - 'audio/skill/gz_jun_liubei.mp3', - 'audio/skill/gz_jun_sunquan.mp3', - 'audio/skill/gzbaolie1.mp3', - 'audio/skill/gzbaolie2.mp3', - 'audio/skill/gzbiluan1.mp3', - 'audio/skill/gzbiluan2.mp3', - 'audio/skill/gzbuqu1.mp3', - 'audio/skill/gzbuqu2.mp3', - 'audio/skill/gzbushi1.mp3', - 'audio/skill/gzbushi2.mp3', - 'audio/skill/gzchenglve1.mp3', - 'audio/skill/gzchenglve2.mp3', - 'audio/skill/gzcongcha1.mp3', - 'audio/skill/gzcongcha2.mp3', - 'audio/skill/gzduannian1.mp3', - 'audio/skill/gzduannian2.mp3', - 'audio/skill/gzduwu1.mp3', - 'audio/skill/gzduwu2.mp3', - 'audio/skill/gzfangyuan1.mp3', - 'audio/skill/gzfangyuan2.mp3', - 'audio/skill/gzfankui1.mp3', - 'audio/skill/gzfankui2.mp3', - 'audio/skill/gzfudi1.mp3', - 'audio/skill/gzfudi2.mp3', - 'audio/skill/gzhuaiyi1.mp3', - 'audio/skill/gzhuaiyi2.mp3', - 'audio/skill/gzjiancai1.mp3', - 'audio/skill/gzjiancai2.mp3', - 'audio/skill/gzjianliang1.mp3', - 'audio/skill/gzjianliang2.mp3', - 'audio/skill/gzjieyue1.mp3', - 'audio/skill/gzjieyue2.mp3', - 'audio/skill/gzjili1.mp3', - 'audio/skill/gzjili2.mp3', - 'audio/skill/gzjinfa1.mp3', - 'audio/skill/gzjinfa2.mp3', - 'audio/skill/gzjixi.mp3', - 'audio/skill/gzjixi1.mp3', - 'audio/skill/gzjuejue1.mp3', - 'audio/skill/gzjuejue2.mp3', - 'audio/skill/gzkuangcai1.mp3', - 'audio/skill/gzkuangcai2.mp3', - 'audio/skill/gzlianpian1.mp3', - 'audio/skill/gzlianpian2.mp3', - 'audio/skill/gzlianyou1.mp3', - 'audio/skill/gzlianyou2.mp3', - 'audio/skill/gzlixia1.mp3', - 'audio/skill/gzlixia2.mp3', - 'audio/skill/gzmidao1.mp3', - 'audio/skill/gzmidao2.mp3', - 'audio/skill/gzpaiyi1.mp3', - 'audio/skill/gzpaiyi2.mp3', - 'audio/skill/gzquanji1.mp3', - 'audio/skill/gzquanji2.mp3', - 'audio/skill/gzshejian1.mp3', - 'audio/skill/gzshejian2.mp3', - 'audio/skill/gzshicai1.mp3', - 'audio/skill/gzshicai2.mp3', - 'audio/skill/gzshilu1.mp3', - 'audio/skill/gzshilu2.mp3', - 'audio/skill/gzsuzhi1.mp3', - 'audio/skill/gzsuzhi2.mp3', - 'audio/skill/gztunjiang1.mp3', - 'audio/skill/gztunjiang2.mp3', - 'audio/skill/gzweimeng1.mp3', - 'audio/skill/gzweimeng2.mp3', - 'audio/skill/gzwenji1.mp3', - 'audio/skill/gzwenji2.mp3', - 'audio/skill/gzxingzhao_xunxun1.mp3', - 'audio/skill/gzxingzhao_xunxun2.mp3', - 'audio/skill/gzxingzhao1.mp3', - 'audio/skill/gzxingzhao2.mp3', - 'audio/skill/gzxiongnve1.mp3', - 'audio/skill/gzxiongnve2.mp3', - 'audio/skill/gzxishe1.mp3', - 'audio/skill/gzxishe2.mp3', - 'audio/skill/gzyinghun_re_sunyi1.mp3', - 'audio/skill/gzyjili1.mp3', - 'audio/skill/gzyjili2.mp3', - 'audio/skill/gzzhaoxin1.mp3', - 'audio/skill/gzzhaoxin2.mp3', - 'audio/skill/gzzhidao1.mp3', - 'audio/skill/gzzhidao2.mp3', - 'audio/skill/gzzisui1.mp3', - 'audio/skill/gzzisui2.mp3', - 'audio/skill/gzzongyu1.mp3', - 'audio/skill/gzzongyu2.mp3', - 'audio/skill/hanbing_skill.mp3', - 'audio/skill/hannan1.mp3', - 'audio/skill/hannan2.mp3', - 'audio/skill/hanyong1.mp3', - 'audio/skill/hanyong2.mp3', - 'audio/skill/hanzhan1.mp3', - 'audio/skill/hanzhan2.mp3', - 'audio/skill/haoshi1.mp3', - 'audio/skill/haoshi2.mp3', - 'audio/skill/heji1.mp3', - 'audio/skill/heji2.mp3', - 'audio/skill/hengjiang1.mp3', - 'audio/skill/hengjiang2.mp3', - 'audio/skill/hengwu1.mp3', - 'audio/skill/hengwu2.mp3', - 'audio/skill/hengzheng1.mp3', - 'audio/skill/hengzheng2.mp3', - 'audio/skill/heqia1.mp3', - 'audio/skill/heqia2.mp3', - 'audio/skill/hezhong1.mp3', - 'audio/skill/hezhong2.mp3', - 'audio/skill/hfjieying1.mp3', - 'audio/skill/hfjieying2.mp3', - 'audio/skill/hinata_ehou1.mp3', - 'audio/skill/hinata_ehou2.mp3', - 'audio/skill/hinata_qiulve1.mp3', - 'audio/skill/hinata_qiulve2.mp3', - 'audio/skill/hisako_yinbao1.mp3', - 'audio/skill/hisako_yinbao2.mp3', - 'audio/skill/hmxili1.mp3', - 'audio/skill/hmxili2.mp3', - 'audio/skill/hongde1.mp3', - 'audio/skill/hongde2.mp3', - 'audio/skill/hongfa_hp.mp3', - 'audio/skill/hongfa1.mp3', - 'audio/skill/hongfa2.mp3', - 'audio/skill/hongyan.mp3', - 'audio/skill/hongyi1.mp3', - 'audio/skill/hongyi2.mp3', - 'audio/skill/hongyuan1.mp3', - 'audio/skill/hongyuan2.mp3', - 'audio/skill/houfeng1.mp3', - 'audio/skill/houfeng2.mp3', - 'audio/skill/houfeng3.mp3', - 'audio/skill/huaibi1.mp3', - 'audio/skill/huaibi2.mp3', - 'audio/skill/huaiyi1.mp3', - 'audio/skill/huaiyi2.mp3', - 'audio/skill/huaiyuan1.mp3', - 'audio/skill/huaiyuan2.mp3', - 'audio/skill/huamu1.mp3', - 'audio/skill/huamu2.mp3', - 'audio/skill/huamu3.mp3', - 'audio/skill/huamu4.mp3', - 'audio/skill/huamu5.mp3', - 'audio/skill/huamu6.mp3', - 'audio/skill/huangjintianbingfu1.mp3', - 'audio/skill/huangjintianbingfu2.mp3', - 'audio/skill/huangkong1.mp3', - 'audio/skill/huangkong2.mp3', - 'audio/skill/huangtian2_re_zhangjiao1.mp3', - 'audio/skill/huangtian2_re_zhangjiao2.mp3', - 'audio/skill/huangtian2_zhangjiao1.mp3', - 'audio/skill/huangtian2_zhangjiao2.mp3', - 'audio/skill/huangtian21.mp3', - 'audio/skill/huangtian22.mp3', - 'audio/skill/huanhua1.mp3', - 'audio/skill/huanhua2.mp3', - 'audio/skill/huanshi1.mp3', - 'audio/skill/huanshi2.mp3', - 'audio/skill/huantu1.mp3', - 'audio/skill/huantu2.mp3', - 'audio/skill/huaping.mp3', - 'audio/skill/huaping1.mp3', - 'audio/skill/huaping2.mp3', - 'audio/skill/huashen21.mp3', - 'audio/skill/huashen22.mp3', - 'audio/skill/huguan_wangyue1.mp3', - 'audio/skill/huguan_wangyue2.mp3', - 'audio/skill/huguan1.mp3', - 'audio/skill/huguan2.mp3', - 'audio/skill/huibian1.mp3', - 'audio/skill/huibian2.mp3', - 'audio/skill/huilei1.mp3', - 'audio/skill/huilei2.mp3', - 'audio/skill/huimin1.mp3', - 'audio/skill/huimin2.mp3', - 'audio/skill/huirong1.mp3', - 'audio/skill/huirong2.mp3', - 'audio/skill/huisheng_dc_huanghao1.mp3', - 'audio/skill/huisheng_dc_huanghao2.mp3', - 'audio/skill/huisheng1.mp3', - 'audio/skill/huisheng2.mp3', - 'audio/skill/huishi1.mp3', - 'audio/skill/huishi2.mp3', - 'audio/skill/huituo1.mp3', - 'audio/skill/huituo2.mp3', - 'audio/skill/hujia_re_caocao1.mp3', - 'audio/skill/hujia_re_caocao2.mp3', - 'audio/skill/hujia1.mp3', - 'audio/skill/hujia2.mp3', - 'audio/skill/hunzi1.mp3', - 'audio/skill/hunzi2.mp3', - 'audio/skill/huoji1.mp3', - 'audio/skill/huoji2.mp3', - 'audio/skill/huomo_huzhao1.mp3', - 'audio/skill/huomo_huzhao2.mp3', - 'audio/skill/huomo_re_zhongyao1.mp3', - 'audio/skill/huomo_re_zhongyao2.mp3', - 'audio/skill/huomo1.mp3', - 'audio/skill/huomo2.mp3', - 'audio/skill/huoshaowuchao.mp3', - 'audio/skill/huoshou1_re_menghuo1.mp3', - 'audio/skill/huoshou1_re_menghuo2.mp3', - 'audio/skill/huoshou11.mp3', - 'audio/skill/huoshou12.mp3', - 'audio/skill/huoshui1.mp3', - 'audio/skill/huoshui2.mp3', - 'audio/skill/huoxin1.mp3', - 'audio/skill/huoxin2.mp3', - 'audio/skill/huwei1.mp3', - 'audio/skill/huwei2.mp3', - 'audio/skill/huxiao1.mp3', - 'audio/skill/huxiao2.mp3', - 'audio/skill/huyuan1.mp3', - 'audio/skill/huyuan2.mp3', - 'audio/skill/hxrenshi1.mp3', - 'audio/skill/hxrenshi2.mp3', - 'audio/skill/jiahe_put1.mp3', - 'audio/skill/jiahe_put2.mp3', - 'audio/skill/jiahe1.mp3', - 'audio/skill/jiahe2.mp3', - 'audio/skill/jianan1.mp3', - 'audio/skill/jianan2.mp3', - 'audio/skill/jianchu_re_pangde1.mp3', - 'audio/skill/jianchu_re_pangde2.mp3', - 'audio/skill/jianchu1.mp3', - 'audio/skill/jianchu2.mp3', - 'audio/skill/jiang_re_sunben1.mp3', - 'audio/skill/jiang_re_sunben2.mp3', - 'audio/skill/jiang_re_sunce1.mp3', - 'audio/skill/jiang_re_sunce2.mp3', - 'audio/skill/jiang_sp_lvmeng1.mp3', - 'audio/skill/jiang_sp_lvmeng2.mp3', - 'audio/skill/jiang1.mp3', - 'audio/skill/jiang2.mp3', - 'audio/skill/jiangchi1.mp3', - 'audio/skill/jiangchi2.mp3', - 'audio/skill/jianglue1.mp3', - 'audio/skill/jianglue2.mp3', - 'audio/skill/jiangxi1.mp3', - 'audio/skill/jiangxi2.mp3', - 'audio/skill/jianhui1.mp3', - 'audio/skill/jianhui2.mp3', - 'audio/skill/jianliang1.mp3', - 'audio/skill/jianliang2.mp3', - 'audio/skill/jianshoudaiyuan.mp3', - 'audio/skill/jianshu1.mp3', - 'audio/skill/jianshu2.mp3', - 'audio/skill/jianxiong1.mp3', - 'audio/skill/jianxiong2.mp3', - 'audio/skill/jianyan1.mp3', - 'audio/skill/jianyan2.mp3', - 'audio/skill/jianying1.mp3', - 'audio/skill/jianying2.mp3', - 'audio/skill/jianzhan1.mp3', - 'audio/skill/jianzhan2.mp3', - 'audio/skill/jianzheng1.mp3', - 'audio/skill/jianzheng2.mp3', - 'audio/skill/jiaojin1.mp3', - 'audio/skill/jiaojin2.mp3', - 'audio/skill/jiaoxia1.mp3', - 'audio/skill/jiaoxia2.mp3', - 'audio/skill/jiaoying1.mp3', - 'audio/skill/jiaoying2.mp3', - 'audio/skill/jiaozhao1.mp3', - 'audio/skill/jiaozhao2.mp3', - 'audio/skill/jiaozi1.mp3', - 'audio/skill/jiaozi2.mp3', - 'audio/skill/jibing1.mp3', - 'audio/skill/jibing2.mp3', - 'audio/skill/jici1.mp3', - 'audio/skill/jici2.mp3', - 'audio/skill/jidian1.mp3', - 'audio/skill/jidian2.mp3', - 'audio/skill/jiebing1.mp3', - 'audio/skill/jiebing2.mp3', - 'audio/skill/jiefan_re_handang1.mp3', - 'audio/skill/jiefan_re_handang2.mp3', - 'audio/skill/jiefan1.mp3', - 'audio/skill/jiefan2.mp3', - 'audio/skill/jieliang1.mp3', - 'audio/skill/jieliang2.mp3', - 'audio/skill/jielie1.mp3', - 'audio/skill/jielie2.mp3', - 'audio/skill/jieming1.mp3', - 'audio/skill/jieming2.mp3', - 'audio/skill/jiewei1.mp3', - 'audio/skill/jiewei2.mp3', - 'audio/skill/jiexun1.mp3', - 'audio/skill/jiexun2.mp3', - 'audio/skill/jieyin1.mp3', - 'audio/skill/jieyin2.mp3', - 'audio/skill/jieyuan_less.mp3', - 'audio/skill/jieyuan_more.mp3', - 'audio/skill/jieyue_shan.mp3', - 'audio/skill/jieyue_wuxie.mp3', - 'audio/skill/jieyue1.mp3', - 'audio/skill/jieyue2.mp3', - 'audio/skill/jiezhong1.mp3', - 'audio/skill/jiezhong2.mp3', - 'audio/skill/jiezi1.mp3', - 'audio/skill/jiezi2.mp3', - 'audio/skill/jigong1.mp3', - 'audio/skill/jigong2.mp3', - 'audio/skill/jihun1.mp3', - 'audio/skill/jihun2.mp3', - 'audio/skill/jijiang1_liushan1.mp3', - 'audio/skill/jijiang1_liushan2.mp3', - 'audio/skill/jijiang1_ol_liushan1.mp3', - 'audio/skill/jijiang1_ol_liushan2.mp3', - 'audio/skill/jijiang1_re_liubei1.mp3', - 'audio/skill/jijiang1_re_liubei2.mp3', - 'audio/skill/jijiang1_re_liushan1.mp3', - 'audio/skill/jijiang1_re_liushan2.mp3', - 'audio/skill/jijiang11.mp3', - 'audio/skill/jijiang12.mp3', - 'audio/skill/jijiang2_liushan1.mp3', - 'audio/skill/jijiang2_liushan2.mp3', - 'audio/skill/jijiang21.mp3', - 'audio/skill/jijiang22.mp3', - 'audio/skill/jijing1.mp3', - 'audio/skill/jijing2.mp3', - 'audio/skill/jijiu_re_huatuo1.mp3', - 'audio/skill/jijiu_re_huatuo2.mp3', - 'audio/skill/jijiu1.mp3', - 'audio/skill/jijiu2.mp3', - 'audio/skill/jilei1.mp3', - 'audio/skill/jilei2.mp3', - 'audio/skill/jili1.mp3', - 'audio/skill/jili2.mp3', - 'audio/skill/jilue_fangzhu.mp3', - 'audio/skill/jilue_fangzhu1.mp3', - 'audio/skill/jilue_guicai.mp3', - 'audio/skill/jilue_guicai1.mp3', - 'audio/skill/jilue_jizhi.mp3', - 'audio/skill/jilue_jizhi1.mp3', - 'audio/skill/jilue_wansha.mp3', - 'audio/skill/jilue_zhiheng.mp3', - 'audio/skill/jilue_zhiheng1.mp3', - 'audio/skill/jimeng1.mp3', - 'audio/skill/jimeng2.mp3', - 'audio/skill/jingce1.mp3', - 'audio/skill/jingce2.mp3', - 'audio/skill/jinghe1.mp3', - 'audio/skill/jinghe2.mp3', - 'audio/skill/jinglan1.mp3', - 'audio/skill/jinglan2.mp3', - 'audio/skill/jinglve1.mp3', - 'audio/skill/jinglve2.mp3', - 'audio/skill/jingong1.mp3', - 'audio/skill/jingong2.mp3', - 'audio/skill/jingzhong1.mp3', - 'audio/skill/jingzhong2.mp3', - 'audio/skill/jinhui1.mp3', - 'audio/skill/jinhui2.mp3', - 'audio/skill/jinjian1.mp3', - 'audio/skill/jinjian2.mp3', - 'audio/skill/jinjiu1.mp3', - 'audio/skill/jinjiu2.mp3', - 'audio/skill/jinqu1.mp3', - 'audio/skill/jinqu2.mp3', - 'audio/skill/jintao1.mp3', - 'audio/skill/jintao2.mp3', - 'audio/skill/jinzhi1.mp3', - 'audio/skill/jinzhi2.mp3', - 'audio/skill/jiqiao1.mp3', - 'audio/skill/jiqiao2.mp3', - 'audio/skill/jishe1.mp3', - 'audio/skill/jishe2.mp3', - 'audio/skill/jishi1.mp3', - 'audio/skill/jishi2.mp3', - 'audio/skill/jisi1.mp3', - 'audio/skill/jisi2.mp3', - 'audio/skill/jiuchi_re_dongzhuo1.mp3', - 'audio/skill/jiuchi_re_dongzhuo2.mp3', - 'audio/skill/jiuchi1.mp3', - 'audio/skill/jiuchi2.mp3', - 'audio/skill/jiufa1.mp3', - 'audio/skill/jiufa2.mp3', - 'audio/skill/jiushi11.mp3', - 'audio/skill/jiushi12.mp3', - 'audio/skill/jiushi21.mp3', - 'audio/skill/jiushi22.mp3', - 'audio/skill/jiushi31.mp3', - 'audio/skill/jiushi32.mp3', - 'audio/skill/jiuwei.mp3', - 'audio/skill/jiuyuan1.mp3', - 'audio/skill/jiuyuan2.mp3', - 'audio/skill/jiwu1.mp3', - 'audio/skill/jiwu2.mp3', - 'audio/skill/jixi_gz_dengai1.mp3', - 'audio/skill/jixi_gz_dengai2.mp3', - 'audio/skill/jixi_ol_dengai1.mp3', - 'audio/skill/jixi_ol_dengai2.mp3', - 'audio/skill/jixi_re_dengai1.mp3', - 'audio/skill/jixi_re_dengai2.mp3', - 'audio/skill/jixi1.mp3', - 'audio/skill/jixi2.mp3', - 'audio/skill/jixian1.mp3', - 'audio/skill/jixian2.mp3', - 'audio/skill/jiyu1.mp3', - 'audio/skill/jiyu2.mp3', - 'audio/skill/jizhao1.mp3', - 'audio/skill/jizhao2.mp3', - 'audio/skill/jizhi_jianyong1.mp3', - 'audio/skill/jizhi_jianyong2.mp3', - 'audio/skill/jizhi1.mp3', - 'audio/skill/jizhi2.mp3', - 'audio/skill/jspdanqi1.mp3', - 'audio/skill/jspdanqi2.mp3', - 'audio/skill/juanjia1.mp3', - 'audio/skill/juanjia2.mp3', - 'audio/skill/jubao1.mp3', - 'audio/skill/jubao2.mp3', - 'audio/skill/juece_dc_liru1.mp3', - 'audio/skill/juece_dc_liru2.mp3', - 'audio/skill/juece1.mp3', - 'audio/skill/juece2.mp3', - 'audio/skill/juedi1.mp3', - 'audio/skill/juedi2.mp3', - 'audio/skill/juejing.mp3', - 'audio/skill/jueman1.mp3', - 'audio/skill/jueman2.mp3', - 'audio/skill/jueqing1.mp3', - 'audio/skill/jueqing2.mp3', - 'audio/skill/juesheng1.mp3', - 'audio/skill/juesheng2.mp3', - 'audio/skill/juesi1.mp3', - 'audio/skill/juesi2.mp3', - 'audio/skill/juetao1.mp3', - 'audio/skill/juetao2.mp3', - 'audio/skill/juexiang_he1.mp3', - 'audio/skill/juexiang_ji1.mp3', - 'audio/skill/juexiang_lie1.mp3', - 'audio/skill/juexiang_rou1.mp3', - 'audio/skill/juexiang1.mp3', - 'audio/skill/juexiang2.mp3', - 'audio/skill/jueyong1.mp3', - 'audio/skill/jueyong2.mp3', - 'audio/skill/juezhi1.mp3', - 'audio/skill/juezhi2.mp3', - 'audio/skill/jugu1.mp3', - 'audio/skill/jugu2.mp3', - 'audio/skill/juguan1.mp3', - 'audio/skill/juguan2.mp3', - 'audio/skill/jujian1.mp3', - 'audio/skill/jujian2.mp3', - 'audio/skill/junbing1.mp3', - 'audio/skill/junbing2.mp3', - 'audio/skill/junxing1.mp3', - 'audio/skill/junxing2.mp3', - 'audio/skill/jushou.mp3', - 'audio/skill/jushou1.mp3', - 'audio/skill/jushou2.mp3', - 'audio/skill/juxiang1_ol_zhurong1.mp3', - 'audio/skill/juxiang1_ol_zhurong2.mp3', - 'audio/skill/juxiang1_re_zhurong1.mp3', - 'audio/skill/juxiang1_re_zhurong2.mp3', - 'audio/skill/juxiang11.mp3', - 'audio/skill/juxiang12.mp3', - 'audio/skill/juyi1.mp3', - 'audio/skill/juyi2.mp3', - 'audio/skill/jyishi1.mp3', - 'audio/skill/jyishi2.mp3', - 'audio/skill/jyzongshi_re_jianyong1.mp3', - 'audio/skill/jyzongshi_re_jianyong2.mp3', - 'audio/skill/jyzongshi1.mp3', - 'audio/skill/jyzongshi2.mp3', - 'audio/skill/kaikang1.mp3', - 'audio/skill/kaikang2.mp3', - 'audio/skill/kanade_benzhan1.mp3', - 'audio/skill/kanade_benzhan2.mp3', - 'audio/skill/kanade_benzhan3.mp3', - 'audio/skill/kanade_mapo1.mp3', - 'audio/skill/kanade_mapo2.mp3', - 'audio/skill/kangge1.mp3', - 'audio/skill/kangge2.mp3', - 'audio/skill/kanpo1.mp3', - 'audio/skill/kanpo2.mp3', - 'audio/skill/keji_re_lvmeng1.mp3', - 'audio/skill/keji_re_lvmeng2.mp3', - 'audio/skill/keji1.mp3', - 'audio/skill/keji2.mp3', - 'audio/skill/keshou1.mp3', - 'audio/skill/keshou2.mp3', - 'audio/skill/kongcheng_re_zhugeliang1.mp3', - 'audio/skill/kongcheng_re_zhugeliang2.mp3', - 'audio/skill/kongcheng11.mp3', - 'audio/skill/kongcheng12.mp3', - 'audio/skill/kongsheng1.mp3', - 'audio/skill/kongsheng2.mp3', - 'audio/skill/koulve1.mp3', - 'audio/skill/koulve2.mp3', - 'audio/skill/kousheng1.mp3', - 'audio/skill/kousheng2.mp3', - 'audio/skill/kuangbi1.mp3', - 'audio/skill/kuangbi2.mp3', - 'audio/skill/kuangcai1.mp3', - 'audio/skill/kuangcai2.mp3', - 'audio/skill/kuangfeng1.mp3', - 'audio/skill/kuangfeng2.mp3', - 'audio/skill/kuangfu1.mp3', - 'audio/skill/kuangfu2.mp3', - 'audio/skill/kuanggu_ol_weiyan1.mp3', - 'audio/skill/kuanggu_ol_weiyan2.mp3', - 'audio/skill/kuanggu_re_weiyan1.mp3', - 'audio/skill/kuanggu_re_weiyan2.mp3', - 'audio/skill/kuanggu1.mp3', - 'audio/skill/kuanggu2.mp3', - 'audio/skill/kuanshi1.mp3', - 'audio/skill/kuanshi2.mp3', - 'audio/skill/kuiji1.mp3', - 'audio/skill/kuiji2.mp3', - 'audio/skill/kuimang1.mp3', - 'audio/skill/kuimang2.mp3', - 'audio/skill/kuiwei1.mp3', - 'audio/skill/kuiwei2.mp3', - 'audio/skill/kunfen1.mp3', - 'audio/skill/kunfen2.mp3', - 'audio/skill/kurou1.mp3', - 'audio/skill/kurou2.mp3', - 'audio/skill/kuwu.mp3', - 'audio/skill/laishou1.mp3', - 'audio/skill/laishou2.mp3', - 'audio/skill/laishou3.mp3', - 'audio/skill/langmie1.mp3', - 'audio/skill/langmie2.mp3', - 'audio/skill/lanjiang1.mp3', - 'audio/skill/lanjiang2.mp3', - 'audio/skill/leiji1.mp3', - 'audio/skill/leiji2.mp3', - 'audio/skill/liandui1.mp3', - 'audio/skill/liandui2.mp3', - 'audio/skill/liangcaokuifa.mp3', - 'audio/skill/liangfan1.mp3', - 'audio/skill/liangfan2.mp3', - 'audio/skill/liangjue1.mp3', - 'audio/skill/liangjue2.mp3', - 'audio/skill/liangjunxiangchi.mp3', - 'audio/skill/liangyin1.mp3', - 'audio/skill/liangyin2.mp3', - 'audio/skill/liangying1.mp3', - 'audio/skill/liangyuan1.mp3', - 'audio/skill/liangyuan2.mp3', - 'audio/skill/liangzhu1.mp3', - 'audio/skill/liangzhu2.mp3', - 'audio/skill/lianhuan1.mp3', - 'audio/skill/lianhuan2.mp3', - 'audio/skill/lianhuo1.mp3', - 'audio/skill/lianhuo2.mp3', - 'audio/skill/lianji.mp3', - 'audio/skill/lianpo.mp3', - 'audio/skill/lianpo1.mp3', - 'audio/skill/lianpo2.mp3', - 'audio/skill/lianying1.mp3', - 'audio/skill/lianying2.mp3', - 'audio/skill/lianzhou1.mp3', - 'audio/skill/lianzhou2.mp3', - 'audio/skill/lianzhu1.mp3', - 'audio/skill/lianzhu2.mp3', - 'audio/skill/lianzi1.mp3', - 'audio/skill/lianzi2.mp3', - 'audio/skill/liaoyi1.mp3', - 'audio/skill/liaoyi2.mp3', - 'audio/skill/liechi1.mp3', - 'audio/skill/liechi2.mp3', - 'audio/skill/liedan1.mp3', - 'audio/skill/liedan2.mp3', - 'audio/skill/liegong_ol_huangzhong1.mp3', - 'audio/skill/liegong_ol_huangzhong2.mp3', - 'audio/skill/liegong_re_huangzhong1.mp3', - 'audio/skill/liegong_re_huangzhong2.mp3', - 'audio/skill/liegong1.mp3', - 'audio/skill/liegong2.mp3', - 'audio/skill/liehou1.mp3', - 'audio/skill/liehou2.mp3', - 'audio/skill/liejie1.mp3', - 'audio/skill/liejie2.mp3', - 'audio/skill/lieren_ol_zhurong1.mp3', - 'audio/skill/lieren_ol_zhurong2.mp3', - 'audio/skill/lieren1.mp3', - 'audio/skill/lieren2.mp3', - 'audio/skill/liewei1.mp3', - 'audio/skill/liewei2.mp3', - 'audio/skill/lieyi1.mp3', - 'audio/skill/lieyi2.mp3', - 'audio/skill/liezhi1.mp3', - 'audio/skill/liezhi2.mp3', - 'audio/skill/lihun1.mp3', - 'audio/skill/lihun2.mp3', - 'audio/skill/lihuo_re_chengpu1.mp3', - 'audio/skill/lihuo_re_chengpu2.mp3', - 'audio/skill/lihuo1.mp3', - 'audio/skill/lihuo2.mp3', - 'audio/skill/liji1.mp3', - 'audio/skill/liji2.mp3', - 'audio/skill/lijian_re_diaochan1.mp3', - 'audio/skill/lijian_re_diaochan2.mp3', - 'audio/skill/lijian1.mp3', - 'audio/skill/lijian2.mp3', - 'audio/skill/lingbo1.mp3', - 'audio/skill/lingbo2.mp3', - 'audio/skill/lingce1.mp3', - 'audio/skill/lingce2.mp3', - 'audio/skill/linglong1.mp3', - 'audio/skill/linglong2.mp3', - 'audio/skill/lingren_jianxiong1.mp3', - 'audio/skill/lingren_xingshang1.mp3', - 'audio/skill/lirang1.mp3', - 'audio/skill/lirang2.mp3', - 'audio/skill/lisi1.mp3', - 'audio/skill/lisi2.mp3', - 'audio/skill/liubing1.mp3', - 'audio/skill/liubing2.mp3', - 'audio/skill/liuli_daxiaoqiao1.mp3', - 'audio/skill/liuli_daxiaoqiao2.mp3', - 'audio/skill/liuli_re_daqiao1.mp3', - 'audio/skill/liuli_re_daqiao2.mp3', - 'audio/skill/liuli1.mp3', - 'audio/skill/liuli2.mp3', - 'audio/skill/liunian1.mp3', - 'audio/skill/liunian2.mp3', - 'audio/skill/lixia1.mp3', - 'audio/skill/lixia2.mp3', - 'audio/skill/liyu1.mp3', - 'audio/skill/liyu2.mp3', - 'audio/skill/lizhan1.mp3', - 'audio/skill/lizhan2.mp3', - 'audio/skill/lkbushi1.mp3', - 'audio/skill/lkbushi2.mp3', - 'audio/skill/lkzhongzhuang1.mp3', - 'audio/skill/lkzhongzhuang2.mp3', - 'audio/skill/llqshenwei1.mp3', - 'audio/skill/llqshenwei2.mp3', - 'audio/skill/longdan_sha_re_zhaoyun1.mp3', - 'audio/skill/longdan_sha_re_zhaoyun2.mp3', - 'audio/skill/longdan_sha1.mp3', - 'audio/skill/longdan_sha2.mp3', - 'audio/skill/longdan_tongyuan.mp3', - 'audio/skill/longhun1.mp3', - 'audio/skill/longhun2.mp3', - 'audio/skill/longhun3.mp3', - 'audio/skill/longhun4.mp3', - 'audio/skill/longyin1.mp3', - 'audio/skill/longyin2.mp3', - 'audio/skill/longyuan1.mp3', - 'audio/skill/longyuan2.mp3', - 'audio/skill/lskuizhu1.mp3', - 'audio/skill/lskuizhu2.mp3', - 'audio/skill/lslixun1.mp3', - 'audio/skill/lslixun2.mp3', - 'audio/skill/luanchou1.mp3', - 'audio/skill/luanchou2.mp3', - 'audio/skill/luanfeng1.mp3', - 'audio/skill/luanfeng2.mp3', - 'audio/skill/luanji1.mp3', - 'audio/skill/luanji2.mp3', - 'audio/skill/luanqun1.mp3', - 'audio/skill/luanqun2.mp3', - 'audio/skill/luanwu_re_jiaxu1.mp3', - 'audio/skill/luanwu_re_jiaxu2.mp3', - 'audio/skill/luanwu1.mp3', - 'audio/skill/luanwu2.mp3', - 'audio/skill/luanzhan1.mp3', - 'audio/skill/luanzhan2.mp3', - 'audio/skill/lulve1.mp3', - 'audio/skill/lulve2.mp3', - 'audio/skill/luochong1.mp3', - 'audio/skill/luochong2.mp3', - 'audio/skill/luoshen1.mp3', - 'audio/skill/luoshen2.mp3', - 'audio/skill/luoyi1.mp3', - 'audio/skill/luoyi2.mp3', - 'audio/skill/luoying_discard1.mp3', - 'audio/skill/luoying_discard2.mp3', - 'audio/skill/luoying_judge1.mp3', - 'audio/skill/luoying_judge2.mp3', - 'audio/skill/luoying1.mp3', - 'audio/skill/luoying2.mp3', - 'audio/skill/lvli1.mp3', - 'audio/skill/lvli2.mp3', - 'audio/skill/lxzhuixi1.mp3', - 'audio/skill/lxzhuixi2.mp3', - 'audio/skill/maihuo1.mp3', - 'audio/skill/maihuo2.mp3', - 'audio/skill/manji1.mp3', - 'audio/skill/manji2.mp3', - 'audio/skill/manjuan.mp3', - 'audio/skill/mansi1.mp3', - 'audio/skill/mansi2.mp3', - 'audio/skill/manyi_mengyou1.mp3', - 'audio/skill/manyi_mengyou2.mp3', - 'audio/skill/manyi1.mp3', - 'audio/skill/manyi2.mp3', - 'audio/skill/mazui.mp3', - 'audio/skill/mbaosi1.mp3', - 'audio/skill/mbaosi2.mp3', - 'audio/skill/mbdaoshu1.mp3', - 'audio/skill/mbdaoshu2.mp3', - 'audio/skill/mbdaoshu3.mp3', - 'audio/skill/mbguli1.mp3', - 'audio/skill/mbguli2.mp3', - 'audio/skill/mbhuiyao1.mp3', - 'audio/skill/mbhuiyao2.mp3', - 'audio/skill/mbquesong1.mp3', - 'audio/skill/mbquesong2.mp3', - 'audio/skill/mbshihe1.mp3', - 'audio/skill/mbshihe2.mp3', - 'audio/skill/mbyilie1.mp3', - 'audio/skill/mbyilie2.mp3', - 'audio/skill/mbyilie3.mp3', - 'audio/skill/mbzhenfu1.mp3', - 'audio/skill/mbzhenfu2.mp3', - 'audio/skill/meibu1.mp3', - 'audio/skill/meibu2.mp3', - 'audio/skill/meihun1.mp3', - 'audio/skill/meihun2.mp3', - 'audio/skill/mengjin1.mp3', - 'audio/skill/mengjin2.mp3', - 'audio/skill/mengqing1.mp3', - 'audio/skill/mengqing2.mp3', - 'audio/skill/mffengshi_sp_mifangfushiren1.mp3', - 'audio/skill/mffengshi_sp_mifangfushiren2.mp3', - 'audio/skill/mffengshi1.mp3', - 'audio/skill/mffengshi2.mp3', - 'audio/skill/miaojian1.mp3', - 'audio/skill/miaojian2.mp3', - 'audio/skill/miaoxian1.mp3', - 'audio/skill/miaoxian2.mp3', - 'audio/skill/mibei1.mp3', - 'audio/skill/mibei2.mp3', - 'audio/skill/midao1.mp3', - 'audio/skill/midao2.mp3', - 'audio/skill/midu1.mp3', - 'audio/skill/midu2.mp3', - 'audio/skill/mieji1.mp3', - 'audio/skill/mieji2.mp3', - 'audio/skill/miji_re_wangyi1.mp3', - 'audio/skill/miji_re_wangyi2.mp3', - 'audio/skill/miji1.mp3', - 'audio/skill/miji2.mp3', - 'audio/skill/mingce1.mp3', - 'audio/skill/mingce2.mp3', - 'audio/skill/mingcha1.mp3', - 'audio/skill/mingcha2.mp3', - 'audio/skill/mingfa1.mp3', - 'audio/skill/mingfa2.mp3', - 'audio/skill/mingjian1.mp3', - 'audio/skill/mingjian2.mp3', - 'audio/skill/mingjie1.mp3', - 'audio/skill/mingluan1.mp3', - 'audio/skill/mingluan2.mp3', - 'audio/skill/mingshi1.mp3', - 'audio/skill/mingshi2.mp3', - 'audio/skill/mingzhe1.mp3', - 'audio/skill/mingzhe2.mp3', - 'audio/skill/minsi1.mp3', - 'audio/skill/minsi2.mp3', - 'audio/skill/mizhao1.mp3', - 'audio/skill/mizhao2.mp3', - 'audio/skill/mjchenshi1.mp3', - 'audio/skill/mjchenshi2.mp3', - 'audio/skill/mjdingyi1.mp3', - 'audio/skill/mjdingyi2.mp3', - 'audio/skill/mjmouzhi1.mp3', - 'audio/skill/mjmouzhi2.mp3', - 'audio/skill/mjweipo1.mp3', - 'audio/skill/mjweipo2.mp3', - 'audio/skill/mobiledanshou1.mp3', - 'audio/skill/mobiledanshou2.mp3', - 'audio/skill/mobilejingce1.mp3', - 'audio/skill/mobilejingce2.mp3', - 'audio/skill/mobilexingxue1.mp3', - 'audio/skill/mobilexingxue2.mp3', - 'audio/skill/mobileyanzhu1.mp3', - 'audio/skill/mobileyanzhu2.mp3', - 'audio/skill/mobilezhongyong1.mp3', - 'audio/skill/mobilezhongyong2.mp3', - 'audio/skill/monkey.mp3', - 'audio/skill/moucheng1.mp3', - 'audio/skill/moucheng2.mp3', - 'audio/skill/moucuan1.mp3', - 'audio/skill/moucuan2.mp3', - 'audio/skill/moukui1.mp3', - 'audio/skill/moukui2.mp3', - 'audio/skill/mouli1.mp3', - 'audio/skill/mouli2.mp3', - 'audio/skill/mouni1.mp3', - 'audio/skill/mouni2.mp3', - 'audio/skill/mouzhi1.mp3', - 'audio/skill/mouzhi2.mp3', - 'audio/skill/mouzhu1.mp3', - 'audio/skill/mouzhu2.mp3', - 'audio/skill/mozhi1.mp3', - 'audio/skill/mozhi2.mp3', - 'audio/skill/mpbishi1.mp3', - 'audio/skill/mpbishi2.mp3', - 'audio/skill/mpjiusong1.mp3', - 'audio/skill/mpjiusong2.mp3', - 'audio/skill/mpmaotao1.mp3', - 'audio/skill/mpmaotao2.mp3', - 'audio/skill/mubing1.mp3', - 'audio/skill/mubing2.mp3', - 'audio/skill/mumu1.mp3', - 'audio/skill/mumu2.mp3', - 'audio/skill/muzhen1.mp3', - 'audio/skill/muzhen2.mp3', - 'audio/skill/naman1.mp3', - 'audio/skill/naman2.mp3', - 'audio/skill/naxiang1.mp3', - 'audio/skill/naxiang2.mp3', - 'audio/skill/naxue1.mp3', - 'audio/skill/naxue2.mp3', - 'audio/skill/neifa1.mp3', - 'audio/skill/neifa2.mp3', - 'audio/skill/new_jiangchi1.mp3', - 'audio/skill/new_jiangchi2.mp3', - 'audio/skill/new_reqingnang1.mp3', - 'audio/skill/new_reqingnang2.mp3', - 'audio/skill/new_reyaowu_sb_huaxiong1.mp3', - 'audio/skill/new_reyaowu_sb_huaxiong2.mp3', - 'audio/skill/new_reyaowu1.mp3', - 'audio/skill/new_reyaowu2.mp3', - 'audio/skill/niepan_re_pangtong1.mp3', - 'audio/skill/niepan_re_pangtong2.mp3', - 'audio/skill/niepan1.mp3', - 'audio/skill/niepan2.mp3', - 'audio/skill/nifu1.mp3', - 'audio/skill/nifu2.mp3', - 'audio/skill/niluan1.mp3', - 'audio/skill/niluan2.mp3', - 'audio/skill/noda_fengcheng1.mp3', - 'audio/skill/noda_fengcheng2.mp3', - 'audio/skill/noda_xunxin1.mp3', - 'audio/skill/noda_xunxin2.mp3', - 'audio/skill/ns_nsshimeng1.mp3', - 'audio/skill/ns_nsshimeng2.mp3', - 'audio/skill/nzry_binglve1.mp3', - 'audio/skill/nzry_binglve2.mp3', - 'audio/skill/nzry_chenglve1.mp3', - 'audio/skill/nzry_chenglve2.mp3', - 'audio/skill/nzry_cuike1.mp3', - 'audio/skill/nzry_cuike2.mp3', - 'audio/skill/nzry_cunmu1.mp3', - 'audio/skill/nzry_cunmu2.mp3', - 'audio/skill/nzry_dinghuo1.mp3', - 'audio/skill/nzry_dinghuo2.mp3', - 'audio/skill/nzry_feijun1.mp3', - 'audio/skill/nzry_feijun2.mp3', - 'audio/skill/nzry_huaiju1.mp3', - 'audio/skill/nzry_huaiju2.mp3', - 'audio/skill/nzry_jianxiang1.mp3', - 'audio/skill/nzry_jianxiang2.mp3', - 'audio/skill/nzry_jieying1.mp3', - 'audio/skill/nzry_jieying2.mp3', - 'audio/skill/nzry_junlve1.mp3', - 'audio/skill/nzry_junlve2.mp3', - 'audio/skill/nzry_juzhan_11.mp3', - 'audio/skill/nzry_juzhan_12.mp3', - 'audio/skill/nzry_kuizhu1.mp3', - 'audio/skill/nzry_kuizhu2.mp3', - 'audio/skill/nzry_lijun11.mp3', - 'audio/skill/nzry_lijun12.mp3', - 'audio/skill/nzry_longnu1.mp3', - 'audio/skill/nzry_longnu2.mp3', - 'audio/skill/nzry_mingren_1_sb_yl_luzhi1.mp3', - 'audio/skill/nzry_mingren_1_sb_yl_luzhi2.mp3', - 'audio/skill/nzry_mingren_11.mp3', - 'audio/skill/nzry_mingren_12.mp3', - 'audio/skill/nzry_shenshi_11.mp3', - 'audio/skill/nzry_shenshi_12.mp3', - 'audio/skill/nzry_shicai_21.mp3', - 'audio/skill/nzry_shicai_22.mp3', - 'audio/skill/nzry_yili1.mp3', - 'audio/skill/nzry_yili2.mp3', - 'audio/skill/nzry_zhenglun1.mp3', - 'audio/skill/nzry_zhenglun2.mp3', - 'audio/skill/nzry_zhenliang_11.mp3', - 'audio/skill/nzry_zhenliang_12.mp3', - 'audio/skill/nzry_zhizheng1.mp3', - 'audio/skill/nzry_zhizheng2.mp3', - 'audio/skill/ocongjian_tongyuan.mp3', - 'audio/skill/ol_shenfen1.mp3', - 'audio/skill/ol_shenfen2.mp3', - 'audio/skill/ol_shichou1.mp3', - 'audio/skill/ol_shichou2.mp3', - 'audio/skill/ol_wuqian1.mp3', - 'audio/skill/ol_wuqian2.mp3', - 'audio/skill/olbaonue1.mp3', - 'audio/skill/olbaonue2.mp3', - 'audio/skill/olbeige1.mp3', - 'audio/skill/olbeige2.mp3', - 'audio/skill/olbihun1.mp3', - 'audio/skill/olbihun2.mp3', - 'audio/skill/olbixin1.mp3', - 'audio/skill/olbixin2.mp3', - 'audio/skill/olchanshuang1.mp3', - 'audio/skill/olchanshuang2.mp3', - 'audio/skill/olchenglie1.mp3', - 'audio/skill/olchenglie2.mp3', - 'audio/skill/olchenshuo1.mp3', - 'audio/skill/olchenshuo2.mp3', - 'audio/skill/olchongshen1.mp3', - 'audio/skill/olchongshen2.mp3', - 'audio/skill/olchuanwu1.mp3', - 'audio/skill/olchuanwu2.mp3', - 'audio/skill/olchuming1.mp3', - 'audio/skill/olchuming2.mp3', - 'audio/skill/olcuipo1.mp3', - 'audio/skill/olcuipo2.mp3', - 'audio/skill/old_fuhun1.mp3', - 'audio/skill/old_fuhun2.mp3', - 'audio/skill/old_guhuo1.mp3', - 'audio/skill/old_guhuo2.mp3', - 'audio/skill/oldaili1.mp3', - 'audio/skill/oldaili2.mp3', - 'audio/skill/oldianjun1.mp3', - 'audio/skill/oldianjun2.mp3', - 'audio/skill/oldimeng1.mp3', - 'audio/skill/oldimeng2.mp3', - 'audio/skill/oldingcuo1.mp3', - 'audio/skill/oldingcuo2.mp3', - 'audio/skill/oldmiji1.mp3', - 'audio/skill/oldmiji2.mp3', - 'audio/skill/oldongdao1.mp3', - 'audio/skill/oldongdao2.mp3', - 'audio/skill/oldqianxi1.mp3', - 'audio/skill/oldqianxi2.mp3', - 'audio/skill/olduanliang1.mp3', - 'audio/skill/olduanliang2.mp3', - 'audio/skill/oldzhenlie1.mp3', - 'audio/skill/oldzhenlie2.mp3', - 'audio/skill/olfangquan_shen_caopi1.mp3', - 'audio/skill/olfangquan_shen_caopi2.mp3', - 'audio/skill/olfangquan1.mp3', - 'audio/skill/olfangquan2.mp3', - 'audio/skill/olfeibai1.mp3', - 'audio/skill/olfeibai2.mp3', - 'audio/skill/olfengji1.mp3', - 'audio/skill/olfengji2.mp3', - 'audio/skill/olfengyan1.mp3', - 'audio/skill/olfengyan2.mp3', - 'audio/skill/olfengzi1.mp3', - 'audio/skill/olfengzi2.mp3', - 'audio/skill/olfudao1.mp3', - 'audio/skill/olfudao2.mp3', - 'audio/skill/olfushi1.mp3', - 'audio/skill/olfushi2.mp3', - 'audio/skill/olfusong1.mp3', - 'audio/skill/olfusong2.mp3', - 'audio/skill/olgangshu1.mp3', - 'audio/skill/olgangshu2.mp3', - 'audio/skill/olgongjie1.mp3', - 'audio/skill/olgongjie2.mp3', - 'audio/skill/olgoude1.mp3', - 'audio/skill/olgoude2.mp3', - 'audio/skill/olguangao1.mp3', - 'audio/skill/olguangao2.mp3', - 'audio/skill/olguzheng1.mp3', - 'audio/skill/olguzheng2.mp3', - 'audio/skill/olhaoshi1.mp3', - 'audio/skill/olhaoshi2.mp3', - 'audio/skill/olhongji1.mp3', - 'audio/skill/olhongji2.mp3', - 'audio/skill/olhuanfu1.mp3', - 'audio/skill/olhuanfu2.mp3', - 'audio/skill/olhuiqi1.mp3', - 'audio/skill/olhuiqi2.mp3', - 'audio/skill/olhuiyun1.mp3', - 'audio/skill/olhuiyun2.mp3', - 'audio/skill/olhunzi_re_sunyi1.mp3', - 'audio/skill/olhunzi_re_sunyi2.mp3', - 'audio/skill/olhunzi1.mp3', - 'audio/skill/olhunzi2.mp3', - 'audio/skill/oljianhe1.mp3', - 'audio/skill/oljianhe2.mp3', - 'audio/skill/oljianman1.mp3', - 'audio/skill/oljianman2.mp3', - 'audio/skill/oljianxuan1.mp3', - 'audio/skill/oljianxuan2.mp3', - 'audio/skill/oljieming1.mp3', - 'audio/skill/oljieming2.mp3', - 'audio/skill/oljiezi1.mp3', - 'audio/skill/oljiezi2.mp3', - 'audio/skill/oljiuchi1.mp3', - 'audio/skill/oljiuchi2.mp3', - 'audio/skill/oljizhan1.mp3', - 'audio/skill/oljizhan2.mp3', - 'audio/skill/oljuanxia1.mp3', - 'audio/skill/oljuanxia2.mp3', - 'audio/skill/olkangrui1.mp3', - 'audio/skill/olkangrui2.mp3', - 'audio/skill/olkenshang1.mp3', - 'audio/skill/olkenshang2.mp3', - 'audio/skill/olkuansai1.mp3', - 'audio/skill/olkuansai2.mp3', - 'audio/skill/ollangdao1.mp3', - 'audio/skill/ollangdao2.mp3', - 'audio/skill/olleijie1.mp3', - 'audio/skill/olleijie2.mp3', - 'audio/skill/olluanji_shen_caopi1.mp3', - 'audio/skill/olluanji_shen_caopi2.mp3', - 'audio/skill/olluanji1.mp3', - 'audio/skill/olluanji2.mp3', - 'audio/skill/olmiuyan1.mp3', - 'audio/skill/olmiuyan2.mp3', - 'audio/skill/olniepan1.mp3', - 'audio/skill/olniepan2.mp3', - 'audio/skill/olningwu1.mp3', - 'audio/skill/olningwu2.mp3', - 'audio/skill/olnishou1.mp3', - 'audio/skill/olnishou2.mp3', - 'audio/skill/olqiejian1.mp3', - 'audio/skill/olqiejian2.mp3', - 'audio/skill/olqingyi1.mp3', - 'audio/skill/olqingyi2.mp3', - 'audio/skill/olqingyuan1.mp3', - 'audio/skill/olqingyuan2.mp3', - 'audio/skill/olqisi1.mp3', - 'audio/skill/olqisi2.mp3', - 'audio/skill/olqushi1.mp3', - 'audio/skill/olqushi2.mp3', - 'audio/skill/olruoyu1.mp3', - 'audio/skill/olruoyu2.mp3', - 'audio/skill/olsaogu1.mp3', - 'audio/skill/olsaogu2.mp3', - 'audio/skill/olsbdouchan1.mp3', - 'audio/skill/olsbdouchan2.mp3', - 'audio/skill/olsbdulie1.mp3', - 'audio/skill/olsbdulie2.mp3', - 'audio/skill/olsbduoshou1.mp3', - 'audio/skill/olsbduoshou2.mp3', - 'audio/skill/olsbfumeng1.mp3', - 'audio/skill/olsbfumeng2.mp3', - 'audio/skill/olsbguidao1.mp3', - 'audio/skill/olsbguidao2.mp3', - 'audio/skill/olsbhetao_ol_sb_yuanshao_shadow1.mp3', - 'audio/skill/olsbhetao_ol_sb_yuanshao_shadow2.mp3', - 'audio/skill/olsbhetao_ol_sb_yuanshao_shadow3.mp3', - 'audio/skill/olsbhetao1.mp3', - 'audio/skill/olsbhetao2.mp3', - 'audio/skill/olsbhetao3.mp3', - 'audio/skill/olsbranji1.mp3', - 'audio/skill/olsbranji2.mp3', - 'audio/skill/olsbshenli_ol_sb_yuanshao_shadow1.mp3', - 'audio/skill/olsbshenli_ol_sb_yuanshao_shadow2.mp3', - 'audio/skill/olsbshenli_ol_sb_yuanshao_shadow3.mp3', - 'audio/skill/olsbshenli1.mp3', - 'audio/skill/olsbshenli2.mp3', - 'audio/skill/olsbshenli3.mp3', - 'audio/skill/olsbshishou_ol_sb_yuanshao_shadow1.mp3', - 'audio/skill/olsbshishou_ol_sb_yuanshao_shadow2.mp3', - 'audio/skill/olsbshishou_ol_sb_yuanshao_shadow3.mp3', - 'audio/skill/olsbshishou1.mp3', - 'audio/skill/olsbshishou2.mp3', - 'audio/skill/olsbshishou3.mp3', - 'audio/skill/olsbweilin1.mp3', - 'audio/skill/olsbweilin2.mp3', - 'audio/skill/olsbyufeng_ol_sb_yuanshao_shadow1.mp3', - 'audio/skill/olsbyufeng1.mp3', - 'audio/skill/olsbyufeng2.mp3', - 'audio/skill/olsbzhuri1.mp3', - 'audio/skill/olsbzhuri2.mp3', - 'audio/skill/olshandao1.mp3', - 'audio/skill/olshandao2.mp3', - 'audio/skill/olshengong1.mp3', - 'audio/skill/olshengong2.mp3', - 'audio/skill/olshilu1.mp3', - 'audio/skill/olshilu2.mp3', - 'audio/skill/olshuangxiong1.mp3', - 'audio/skill/olshuangxiong2.mp3', - 'audio/skill/olsuji1.mp3', - 'audio/skill/olsuji2.mp3', - 'audio/skill/olsujian1.mp3', - 'audio/skill/olsujian2.mp3', - 'audio/skill/oltianhou_club.mp3', - 'audio/skill/oltianhou_diamond.mp3', - 'audio/skill/oltianhou_heart.mp3', - 'audio/skill/oltianhou_spade.mp3', - 'audio/skill/oltianhou1.mp3', - 'audio/skill/oltianhou2.mp3', - 'audio/skill/oltongduo1.mp3', - 'audio/skill/oltongduo2.mp3', - 'audio/skill/oltousui1.mp3', - 'audio/skill/oltousui2.mp3', - 'audio/skill/oltuntian1.mp3', - 'audio/skill/oltuntian2.mp3', - 'audio/skill/olweifu1.mp3', - 'audio/skill/olweifu2.mp3', - 'audio/skill/olweijie1.mp3', - 'audio/skill/olweijie2.mp3', - 'audio/skill/olxianbi1.mp3', - 'audio/skill/olxianbi2.mp3', - 'audio/skill/olxiangxv1.mp3', - 'audio/skill/olxiangxv2.mp3', - 'audio/skill/olxiangzuo1.mp3', - 'audio/skill/olxiangzuo2.mp3', - 'audio/skill/olxianlve1.mp3', - 'audio/skill/olxianlve2.mp3', - 'audio/skill/olxiaosi1.mp3', - 'audio/skill/olxiaosi2.mp3', - 'audio/skill/olxibing1.mp3', - 'audio/skill/olxibing2.mp3', - 'audio/skill/olxieju1.mp3', - 'audio/skill/olxieju2.mp3', - 'audio/skill/olximo1.mp3', - 'audio/skill/olximo2.mp3', - 'audio/skill/olximo3.mp3', - 'audio/skill/olxinggu1.mp3', - 'audio/skill/olxinggu2.mp3', - 'audio/skill/olxiuhao1.mp3', - 'audio/skill/olxiuhao2.mp3', - 'audio/skill/olxueyi1.mp3', - 'audio/skill/olxueyi2.mp3', - 'audio/skill/olzaowang1.mp3', - 'audio/skill/olzaowang2.mp3', - 'audio/skill/olzaoxian1.mp3', - 'audio/skill/olzaoxian2.mp3', - 'audio/skill/olzenrun1.mp3', - 'audio/skill/olzenrun2.mp3', - 'audio/skill/olzeyue1.mp3', - 'audio/skill/olzeyue2.mp3', - 'audio/skill/olzhanjin1.mp3', - 'audio/skill/olzhanjin2.mp3', - 'audio/skill/olzhenying1.mp3', - 'audio/skill/olzhenying2.mp3', - 'audio/skill/olzhiba1.mp3', - 'audio/skill/olzhiba2.mp3', - 'audio/skill/olzhiji1.mp3', - 'audio/skill/olzhiji2.mp3', - 'audio/skill/olzhijian1.mp3', - 'audio/skill/olzhijian2.mp3', - 'audio/skill/olzhubi1.mp3', - 'audio/skill/olzhubi2.mp3', - 'audio/skill/olzhuyan1.mp3', - 'audio/skill/olzhuyan2.mp3', - 'audio/skill/paiyi_re_zhonghui1.mp3', - 'audio/skill/paiyi_re_zhonghui2.mp3', - 'audio/skill/paiyi1.mp3', - 'audio/skill/paiyi2.mp3', - 'audio/skill/paoxiao_guanzhang1.mp3', - 'audio/skill/paoxiao_guanzhang2.mp3', - 'audio/skill/paoxiao_re_guanzhang1.mp3', - 'audio/skill/paoxiao_re_guanzhang2.mp3', - 'audio/skill/paoxiao_re_zhangfei1.mp3', - 'audio/skill/paoxiao_re_zhangfei2.mp3', - 'audio/skill/paoxiao_xiahouba1.mp3', - 'audio/skill/paoxiao_xiahouba2.mp3', - 'audio/skill/paoxiao1.mp3', - 'audio/skill/paoxiao2.mp3', - 'audio/skill/pcaudio_fengchu_card.mp3', - 'audio/skill/pcaudio_shuijing_card.mp3', - 'audio/skill/pcaudio_wolong_card.mp3', - 'audio/skill/pcaudio_xuanjian_card.mp3', - 'audio/skill/pianchong1.mp3', - 'audio/skill/pianchong2.mp3', - 'audio/skill/pianyi1.mp3', - 'audio/skill/pianyi2.mp3', - 'audio/skill/piaoling1.mp3', - 'audio/skill/piaoling2.mp3', - 'audio/skill/piaoping1.mp3', - 'audio/skill/piaoping2.mp3', - 'audio/skill/pindi1.mp3', - 'audio/skill/pindi2.mp3', - 'audio/skill/pinghe1.mp3', - 'audio/skill/pinghe2.mp3', - 'audio/skill/pingjian1.mp3', - 'audio/skill/pingjian2.mp3', - 'audio/skill/pingkou1.mp3', - 'audio/skill/pingkou2.mp3', - 'audio/skill/pingxiang1.mp3', - 'audio/skill/pingxiang2.mp3', - 'audio/skill/pojun1.mp3', - 'audio/skill/pojun2.mp3', - 'audio/skill/polu1.mp3', - 'audio/skill/polu2.mp3', - 'audio/skill/poxiang1.mp3', - 'audio/skill/poxiang2.mp3', - 'audio/skill/pozhu1.mp3', - 'audio/skill/pozhu2.mp3', - 'audio/skill/pytianjiang1.mp3', - 'audio/skill/pytianjiang2.mp3', - 'audio/skill/pyzhuren1.mp3', - 'audio/skill/pyzhuren2.mp3', - 'audio/skill/qhzhangji1.mp3', - 'audio/skill/qhzhangji2.mp3', - 'audio/skill/qiangwu1.mp3', - 'audio/skill/qiangwu2.mp3', - 'audio/skill/qiangxi_boss_lvbu31.mp3', - 'audio/skill/qiangxi_boss_lvbu32.mp3', - 'audio/skill/qiangxi_ol_dianwei1.mp3', - 'audio/skill/qiangxi_ol_dianwei2.mp3', - 'audio/skill/qiangxi1.mp3', - 'audio/skill/qiangxi2.mp3', - 'audio/skill/qiangzhi_re_zhangsong1.mp3', - 'audio/skill/qiangzhi_re_zhangsong2.mp3', - 'audio/skill/qiangzhi1.mp3', - 'audio/skill/qiangzhi2.mp3', - 'audio/skill/qianhuan1.mp3', - 'audio/skill/qianhuan2.mp3', - 'audio/skill/qianlong1.mp3', - 'audio/skill/qianlong2.mp3', - 'audio/skill/qianmeng1.mp3', - 'audio/skill/qianmeng2.mp3', - 'audio/skill/qianxi1.mp3', - 'audio/skill/qianxi2.mp3', - 'audio/skill/qianxin1.mp3', - 'audio/skill/qianxin2.mp3', - 'audio/skill/qianxun1.mp3', - 'audio/skill/qianxun2.mp3', - 'audio/skill/qianya1.mp3', - 'audio/skill/qianya2.mp3', - 'audio/skill/qiaobian1.mp3', - 'audio/skill/qiaobian2.mp3', - 'audio/skill/qiaoli1.mp3', - 'audio/skill/qiaoli2.mp3', - 'audio/skill/qiaomeng1.mp3', - 'audio/skill/qiaomeng2.mp3', - 'audio/skill/qiaoshi1.mp3', - 'audio/skill/qiaoshi2.mp3', - 'audio/skill/qiaoshui1.mp3', - 'audio/skill/qiaoshui2.mp3', - 'audio/skill/qiaoyan1.mp3', - 'audio/skill/qiaoyan2.mp3', - 'audio/skill/qibaodao2.mp3', - 'audio/skill/qibie1.mp3', - 'audio/skill/qibie2.mp3', - 'audio/skill/qice_clan_xunyou1.mp3', - 'audio/skill/qice_clan_xunyou2.mp3', - 'audio/skill/qice1.mp3', - 'audio/skill/qice2.mp3', - 'audio/skill/qieting1.mp3', - 'audio/skill/qieting2.mp3', - 'audio/skill/qiexie1.mp3', - 'audio/skill/qiexie2.mp3', - 'audio/skill/qigong1.mp3', - 'audio/skill/qigong2.mp3', - 'audio/skill/qilin_skill.mp3', - 'audio/skill/qiluan21.mp3', - 'audio/skill/qiluan22.mp3', - 'audio/skill/qimei1.mp3', - 'audio/skill/qimei2.mp3', - 'audio/skill/qimou1.mp3', - 'audio/skill/qimou2.mp3', - 'audio/skill/qinbao1.mp3', - 'audio/skill/qinbao2.mp3', - 'audio/skill/qingbei1.mp3', - 'audio/skill/qingbei2.mp3', - 'audio/skill/qingcheng1.mp3', - 'audio/skill/qingcheng2.mp3', - 'audio/skill/qinggang_skill.mp3', - 'audio/skill/qingguo_sb_zhenji1.mp3', - 'audio/skill/qingguo_sb_zhenji2.mp3', - 'audio/skill/qingguo1.mp3', - 'audio/skill/qingguo2.mp3', - 'audio/skill/qingjian1.mp3', - 'audio/skill/qingjian2.mp3', - 'audio/skill/qingjiao1.mp3', - 'audio/skill/qingjiao2.mp3', - 'audio/skill/qingjue1.mp3', - 'audio/skill/qingjue2.mp3', - 'audio/skill/qingleng1.mp3', - 'audio/skill/qingleng2.mp3', - 'audio/skill/qingliang1.mp3', - 'audio/skill/qingliang2.mp3', - 'audio/skill/qinglong_skill.mp3', - 'audio/skill/qingman1.mp3', - 'audio/skill/qingman2.mp3', - 'audio/skill/qingnang1.mp3', - 'audio/skill/qingnang2.mp3', - 'audio/skill/qingtan1.mp3', - 'audio/skill/qingtan2.mp3', - 'audio/skill/qinguo_lose1.mp3', - 'audio/skill/qinguo_lose2.mp3', - 'audio/skill/qinguo_use1.mp3', - 'audio/skill/qinguo_use2.mp3', - 'audio/skill/qingxi1.mp3', - 'audio/skill/qingxi2.mp3', - 'audio/skill/qingxian1.mp3', - 'audio/skill/qingxian2.mp3', - 'audio/skill/qingyi1.mp3', - 'audio/skill/qingyi2.mp3', - 'audio/skill/qingyin1.mp3', - 'audio/skill/qingyin2.mp3', - 'audio/skill/qingyu1.mp3', - 'audio/skill/qingyu2.mp3', - 'audio/skill/qingyu3.mp3', - 'audio/skill/qingzhong1.mp3', - 'audio/skill/qingzhong2.mp3', - 'audio/skill/qinqing1.mp3', - 'audio/skill/qinqing2.mp3', - 'audio/skill/qinwang11.mp3', - 'audio/skill/qinwang12.mp3', - 'audio/skill/qinwang21.mp3', - 'audio/skill/qinwang22.mp3', - 'audio/skill/qinxue1.mp3', - 'audio/skill/qinxue2.mp3', - 'audio/skill/qinyin1.mp3', - 'audio/skill/qinyin2.mp3', - 'audio/skill/qinzheng1.mp3', - 'audio/skill/qinzheng2.mp3', - 'audio/skill/qiongshou1.mp3', - 'audio/skill/qiongshou2.mp3', - 'audio/skill/qirang1.mp3', - 'audio/skill/qirang2.mp3', - 'audio/skill/qiuan1.mp3', - 'audio/skill/qiuan2.mp3', - 'audio/skill/qiuyuan1.mp3', - 'audio/skill/qiuyuan2.mp3', - 'audio/skill/qiwu.mp3', - 'audio/skill/qixi_re_ganning1.mp3', - 'audio/skill/qixi_re_ganning2.mp3', - 'audio/skill/qixi_re_heqi1.mp3', - 'audio/skill/qixi_re_heqi2.mp3', - 'audio/skill/qixi1.mp3', - 'audio/skill/qixi2.mp3', - 'audio/skill/qixing1.mp3', - 'audio/skill/qixing2.mp3', - 'audio/skill/qizhi1.mp3', - 'audio/skill/qizhi2.mp3', - 'audio/skill/qljsuiren1.mp3', - 'audio/skill/qljsuiren2.mp3', - 'audio/skill/quanbian1.mp3', - 'audio/skill/quanbian2.mp3', - 'audio/skill/quanfeng1.mp3', - 'audio/skill/quanfeng2.mp3', - 'audio/skill/quanji1.mp3', - 'audio/skill/quanji2.mp3', - 'audio/skill/quanjin1.mp3', - 'audio/skill/quanjin2.mp3', - 'audio/skill/quanjiu1.mp3', - 'audio/skill/quanjiu2.mp3', - 'audio/skill/quhu_ol_xunyu1.mp3', - 'audio/skill/quhu_ol_xunyu2.mp3', - 'audio/skill/quhu_re_xunyu1.mp3', - 'audio/skill/quhu_re_xunyu2.mp3', - 'audio/skill/quhu1.mp3', - 'audio/skill/quhu2.mp3', - 'audio/skill/quji1.mp3', - 'audio/skill/quji2.mp3', - 'audio/skill/quxi1.mp3', - 'audio/skill/quxi2.mp3', - 'audio/skill/rangjie1.mp3', - 'audio/skill/rangjie2.mp3', - 'audio/skill/ranshang1.mp3', - 'audio/skill/ranshang2.mp3', - 'audio/skill/ranshang21.mp3', - 'audio/skill/ranshang22.mp3', - 'audio/skill/reandong1.mp3', - 'audio/skill/reandong2.mp3', - 'audio/skill/reanguo1.mp3', - 'audio/skill/reanguo2.mp3', - 'audio/skill/reanjian1.mp3', - 'audio/skill/reanjian2.mp3', - 'audio/skill/reanxu1.mp3', - 'audio/skill/reanxu2.mp3', - 'audio/skill/rebaobian1.mp3', - 'audio/skill/rebaobian2.mp3', - 'audio/skill/rebingyi1.mp3', - 'audio/skill/rebingyi2.mp3', - 'audio/skill/rebiyue1.mp3', - 'audio/skill/rebiyue2.mp3', - 'audio/skill/rebizhuan1.mp3', - 'audio/skill/rebizhuan2.mp3', - 'audio/skill/recangchu1.mp3', - 'audio/skill/recangchu2.mp3', - 'audio/skill/rechanhui1.mp3', - 'audio/skill/rechanhui2.mp3', - 'audio/skill/rechanyuan1.mp3', - 'audio/skill/rechanyuan2.mp3', - 'audio/skill/rechengxiang1.mp3', - 'audio/skill/rechengxiang2.mp3', - 'audio/skill/rechunlao1.mp3', - 'audio/skill/rechunlao2.mp3', - 'audio/skill/redanxin1.mp3', - 'audio/skill/redanxin2.mp3', - 'audio/skill/redaoji1.mp3', - 'audio/skill/redaoji2.mp3', - 'audio/skill/redingpin1.mp3', - 'audio/skill/redingpin2.mp3', - 'audio/skill/reduodao1.mp3', - 'audio/skill/reduodao2.mp3', - 'audio/skill/reenyuan1.mp3', - 'audio/skill/reenyuan2.mp3', - 'audio/skill/refaen_dc_chenqun1.mp3', - 'audio/skill/refaen_dc_chenqun2.mp3', - 'audio/skill/refaen1.mp3', - 'audio/skill/refaen2.mp3', - 'audio/skill/refangquan1.mp3', - 'audio/skill/refangquan2.mp3', - 'audio/skill/refangzhu1.mp3', - 'audio/skill/refangzhu2.mp3', - 'audio/skill/refanjian1.mp3', - 'audio/skill/refanjian2.mp3', - 'audio/skill/refankui1.mp3', - 'audio/skill/refankui2.mp3', - 'audio/skill/refenglve1.mp3', - 'audio/skill/refenglve2.mp3', - 'audio/skill/refenli1.mp3', - 'audio/skill/refenli2.mp3', - 'audio/skill/refenyin_wufan1.mp3', - 'audio/skill/refenyin_wufan2.mp3', - 'audio/skill/refenyin1.mp3', - 'audio/skill/refenyin2.mp3', - 'audio/skill/refuli1.mp3', - 'audio/skill/refuli2.mp3', - 'audio/skill/refuman1.mp3', - 'audio/skill/refuman2.mp3', - 'audio/skill/refuyuan1.mp3', - 'audio/skill/refuyuan2.mp3', - 'audio/skill/reganglie1.mp3', - 'audio/skill/reganglie2.mp3', - 'audio/skill/reganlu1.mp3', - 'audio/skill/reganlu2.mp3', - 'audio/skill/regongji1.mp3', - 'audio/skill/regongji2.mp3', - 'audio/skill/reguhuo1.mp3', - 'audio/skill/reguhuo2.mp3', - 'audio/skill/reguicai1.mp3', - 'audio/skill/reguicai2.mp3', - 'audio/skill/reguose1.mp3', - 'audio/skill/reguose2.mp3', - 'audio/skill/rehongyan1.mp3', - 'audio/skill/rehongyan2.mp3', - 'audio/skill/rehuaiyi1.mp3', - 'audio/skill/rehuaiyi2.mp3', - 'audio/skill/rehuashen1.mp3', - 'audio/skill/rehuashen2.mp3', - 'audio/skill/rehunzi1.mp3', - 'audio/skill/rehunzi2.mp3', - 'audio/skill/rehuoji_ol_pangtong1.mp3', - 'audio/skill/rehuoji_ol_pangtong2.mp3', - 'audio/skill/rehuoji_ol_sp_zhugeliang1.mp3', - 'audio/skill/rehuoji_ol_sp_zhugeliang2.mp3', - 'audio/skill/rehuoji1.mp3', - 'audio/skill/rehuoji2.mp3', - 'audio/skill/rehuoshui1.mp3', - 'audio/skill/rehuoshui2.mp3', - 'audio/skill/rejianchu1.mp3', - 'audio/skill/rejianchu2.mp3', - 'audio/skill/rejiangchi1.mp3', - 'audio/skill/rejiangchi2.mp3', - 'audio/skill/rejianxiong_shen_caopi1.mp3', - 'audio/skill/rejianxiong_shen_caopi2.mp3', - 'audio/skill/rejianxiong1.mp3', - 'audio/skill/rejianxiong2.mp3', - 'audio/skill/rejianyan1.mp3', - 'audio/skill/rejianyan2.mp3', - 'audio/skill/rejiaojin1.mp3', - 'audio/skill/rejiaojin2.mp3', - 'audio/skill/rejiaozhao1.mp3', - 'audio/skill/rejiaozhao2.mp3', - 'audio/skill/rejieming1.mp3', - 'audio/skill/rejieming2.mp3', - 'audio/skill/rejieyin1.mp3', - 'audio/skill/rejieyin2.mp3', - 'audio/skill/rejieyue1.mp3', - 'audio/skill/rejieyue2.mp3', - 'audio/skill/rejigong1.mp3', - 'audio/skill/rejigong2.mp3', - 'audio/skill/rejinjiu1.mp3', - 'audio/skill/rejinjiu2.mp3', - 'audio/skill/rejiqiao1.mp3', - 'audio/skill/rejiqiao2.mp3', - 'audio/skill/rejiushi1.mp3', - 'audio/skill/rejiushi2.mp3', - 'audio/skill/rejiuyuan1.mp3', - 'audio/skill/rejiuyuan2.mp3', - 'audio/skill/rejixu1.mp3', - 'audio/skill/rejixu2.mp3', - 'audio/skill/rejizhi_lukang1.mp3', - 'audio/skill/rejizhi_lukang2.mp3', - 'audio/skill/rejizhi1.mp3', - 'audio/skill/rejizhi2.mp3', - 'audio/skill/rejuece1.mp3', - 'audio/skill/rejuece2.mp3', - 'audio/skill/rejueqing1.mp3', - 'audio/skill/rejueqing2.mp3', - 'audio/skill/rejunxing1.mp3', - 'audio/skill/rejunxing2.mp3', - 'audio/skill/rekanpo_ol_pangtong1.mp3', - 'audio/skill/rekanpo_ol_pangtong2.mp3', - 'audio/skill/rekanpo_ol_sp_zhugeliang1.mp3', - 'audio/skill/rekanpo_ol_sp_zhugeliang2.mp3', - 'audio/skill/rekanpo1.mp3', - 'audio/skill/rekanpo2.mp3', - 'audio/skill/rekuangbi1.mp3', - 'audio/skill/rekuangbi2.mp3', - 'audio/skill/rekuangcai1.mp3', - 'audio/skill/rekuangcai2.mp3', - 'audio/skill/rekurou1.mp3', - 'audio/skill/rekurou2.mp3', - 'audio/skill/releiji1.mp3', - 'audio/skill/releiji2.mp3', - 'audio/skill/reliangying1.mp3', - 'audio/skill/reliangying2.mp3', - 'audio/skill/relianying1.mp3', - 'audio/skill/relianying2.mp3', - 'audio/skill/relieren1.mp3', - 'audio/skill/relieren2.mp3', - 'audio/skill/relihuo1.mp3', - 'audio/skill/relihuo2.mp3', - 'audio/skill/relinglong1.mp3', - 'audio/skill/relinglong2.mp3', - 'audio/skill/relonghun1.mp3', - 'audio/skill/relonghun2.mp3', - 'audio/skill/relongyin1.mp3', - 'audio/skill/relongyin2.mp3', - 'audio/skill/reluanji1.mp3', - 'audio/skill/reluanji2.mp3', - 'audio/skill/reluoshen1.mp3', - 'audio/skill/reluoshen2.mp3', - 'audio/skill/reluoyi1.mp3', - 'audio/skill/reluoyi2.mp3', - 'audio/skill/reluoying_dc_caozhi1.mp3', - 'audio/skill/reluoying_dc_caozhi2.mp3', - 'audio/skill/reluoying1.mp3', - 'audio/skill/reluoying2.mp3', - 'audio/skill/remieji1.mp3', - 'audio/skill/remieji2.mp3', - 'audio/skill/remingce1.mp3', - 'audio/skill/remingce2.mp3', - 'audio/skill/rende1.mp3', - 'audio/skill/rende2.mp3', - 'audio/skill/renjie.mp3', - 'audio/skill/renjie2.mp3', - 'audio/skill/renjie21.mp3', - 'audio/skill/renjie22.mp3', - 'audio/skill/renshe1.mp3', - 'audio/skill/renshe2.mp3', - 'audio/skill/renshi1.mp3', - 'audio/skill/renshi2.mp3', - 'audio/skill/renwang_skill.mp3', - 'audio/skill/renxin_re_caochong1.mp3', - 'audio/skill/renxin_re_caochong2.mp3', - 'audio/skill/renxin1.mp3', - 'audio/skill/renxin2.mp3', - 'audio/skill/renzheng1.mp3', - 'audio/skill/renzheng2.mp3', - 'audio/skill/repaoxiao1.mp3', - 'audio/skill/repaoxiao2.mp3', - 'audio/skill/repindi1.mp3', - 'audio/skill/repindi2.mp3', - 'audio/skill/repingkou1.mp3', - 'audio/skill/repingkou2.mp3', - 'audio/skill/repojun1.mp3', - 'audio/skill/repojun2.mp3', - 'audio/skill/repolu1.mp3', - 'audio/skill/reqiangxi1.mp3', - 'audio/skill/reqiangxi2.mp3', - 'audio/skill/reqianxi1.mp3', - 'audio/skill/reqianxi2.mp3', - 'audio/skill/reqianxun1.mp3', - 'audio/skill/reqianxun2.mp3', - 'audio/skill/reqiaobian1.mp3', - 'audio/skill/reqiaobian2.mp3', - 'audio/skill/reqiaoshi1.mp3', - 'audio/skill/reqiaoshi2.mp3', - 'audio/skill/reqiaoshui1.mp3', - 'audio/skill/reqiaoshui2.mp3', - 'audio/skill/reqice1.mp3', - 'audio/skill/reqice2.mp3', - 'audio/skill/reqieting1.mp3', - 'audio/skill/reqieting2.mp3', - 'audio/skill/reqimou1.mp3', - 'audio/skill/reqimou2.mp3', - 'audio/skill/reqingcheng1.mp3', - 'audio/skill/reqingcheng2.mp3', - 'audio/skill/reqingguo1.mp3', - 'audio/skill/reqingguo2.mp3', - 'audio/skill/reqingxi1.mp3', - 'audio/skill/reqingxi2.mp3', - 'audio/skill/reqinwang1.mp3', - 'audio/skill/reqinwang2.mp3', - 'audio/skill/reqiuyuan1.mp3', - 'audio/skill/reqiuyuan2.mp3', - 'audio/skill/requanji1.mp3', - 'audio/skill/requanji2.mp3', - 'audio/skill/rerende_gz_jun_liubei1.mp3', - 'audio/skill/rerende_gz_jun_liubei2.mp3', - 'audio/skill/rerende_shen_caopi1.mp3', - 'audio/skill/rerende_shen_caopi2.mp3', - 'audio/skill/rerende1.mp3', - 'audio/skill/rerende2.mp3', - 'audio/skill/resanyao1.mp3', - 'audio/skill/resanyao2.mp3', - 'audio/skill/reshangshi1.mp3', - 'audio/skill/reshangshi2.mp3', - 'audio/skill/reshejian1.mp3', - 'audio/skill/reshejian2.mp3', - 'audio/skill/reshenduan1.mp3', - 'audio/skill/reshenduan2.mp3', - 'audio/skill/reshenxing1.mp3', - 'audio/skill/reshenxing2.mp3', - 'audio/skill/reshishou1.mp3', - 'audio/skill/reshishou2.mp3', - 'audio/skill/residi1.mp3', - 'audio/skill/residi2.mp3', - 'audio/skill/retieji_boss_lvbu31.mp3', - 'audio/skill/retieji_boss_lvbu32.mp3', - 'audio/skill/retieji1.mp3', - 'audio/skill/retieji2.mp3', - 'audio/skill/retishen1.mp3', - 'audio/skill/retishen2.mp3', - 'audio/skill/retongbo1.mp3', - 'audio/skill/retongbo2.mp3', - 'audio/skill/retuntian1.mp3', - 'audio/skill/retuntian2.mp3', - 'audio/skill/retuxi1.mp3', - 'audio/skill/retuxi2.mp3', - 'audio/skill/rewangzu1.mp3', - 'audio/skill/rewangzu2.mp3', - 'audio/skill/reweimu1.mp3', - 'audio/skill/reweimu2.mp3', - 'audio/skill/rewurong1.mp3', - 'audio/skill/rewurong2.mp3', - 'audio/skill/rexiantu1.mp3', - 'audio/skill/rexiantu2.mp3', - 'audio/skill/rexianzhen1.mp3', - 'audio/skill/rexianzhen2.mp3', - 'audio/skill/rexianzhou1.mp3', - 'audio/skill/rexianzhou2.mp3', - 'audio/skill/rexingshang1.mp3', - 'audio/skill/rexingshang2.mp3', - 'audio/skill/rexingsheng1.mp3', - 'audio/skill/rexingsheng2.mp3', - 'audio/skill/rexingxue1.mp3', - 'audio/skill/rexingxue2.mp3', - 'audio/skill/rexinsheng1.mp3', - 'audio/skill/rexinsheng2.mp3', - 'audio/skill/rexuanhuo1.mp3', - 'audio/skill/rexuanhuo2.mp3', - 'audio/skill/reyajiao1.mp3', - 'audio/skill/reyajiao2.mp3', - 'audio/skill/reyanyu1.mp3', - 'audio/skill/reyanyu2.mp3', - 'audio/skill/reyanzhu1.mp3', - 'audio/skill/reyanzhu2.mp3', - 'audio/skill/reyicong_dc_gongsunzan.mp3', - 'audio/skill/reyicong_dc_gongsunzan1.mp3', - 'audio/skill/reyicong1.mp3', - 'audio/skill/reyicong2.mp3', - 'audio/skill/reyiji1.mp3', - 'audio/skill/reyiji2.mp3', - 'audio/skill/reyingshi1.mp3', - 'audio/skill/reyingshi2.mp3', - 'audio/skill/reyingshui1.mp3', - 'audio/skill/reyingshui2.mp3', - 'audio/skill/reyingzi_gexuan1.mp3', - 'audio/skill/reyingzi_heqi1.mp3', - 'audio/skill/reyingzi_heqi2.mp3', - 'audio/skill/reyingzi_re_heqi1.mp3', - 'audio/skill/reyingzi_re_heqi2.mp3', - 'audio/skill/reyingzi_re_sunben1.mp3', - 'audio/skill/reyingzi_re_sunben2.mp3', - 'audio/skill/reyingzi_re_sunce1.mp3', - 'audio/skill/reyingzi_re_sunce2.mp3', - 'audio/skill/reyingzi_re_sunyi1.mp3', - 'audio/skill/reyingzi_sunce1.mp3', - 'audio/skill/reyingzi_sunce2.mp3', - 'audio/skill/reyingzi1.mp3', - 'audio/skill/reyingzi2.mp3', - 'audio/skill/reyonglve1.mp3', - 'audio/skill/reyonglve2.mp3', - 'audio/skill/rezaiqi1.mp3', - 'audio/skill/rezaiqi2.mp3', - 'audio/skill/rezhanjue1.mp3', - 'audio/skill/rezhanjue2.mp3', - 'audio/skill/rezhiheng_shen_caopi1.mp3', - 'audio/skill/rezhiheng_shen_caopi2.mp3', - 'audio/skill/rezhiheng1.mp3', - 'audio/skill/rezhiheng2.mp3', - 'audio/skill/rezhijian1.mp3', - 'audio/skill/rezhijian2.mp3', - 'audio/skill/rezhiyu1.mp3', - 'audio/skill/rezhiyu2.mp3', - 'audio/skill/rezhongyong1.mp3', - 'audio/skill/rezhongyong2.mp3', - 'audio/skill/rezhuhai1.mp3', - 'audio/skill/rezhuhai2.mp3', - 'audio/skill/rezhuikong1.mp3', - 'audio/skill/rezhuikong2.mp3', - 'audio/skill/rezongshi1.mp3', - 'audio/skill/rezongshi2.mp3', - 'audio/skill/rezongxuan1.mp3', - 'audio/skill/rezongxuan2.mp3', - 'audio/skill/rongbei1.mp3', - 'audio/skill/rongbei2.mp3', - 'audio/skill/roulin_ol_dongzhuo1.mp3', - 'audio/skill/roulin_ol_dongzhuo2.mp3', - 'audio/skill/roulin_re_dongzhuo1.mp3', - 'audio/skill/roulin_re_dongzhuo2.mp3', - 'audio/skill/roulin1.mp3', - 'audio/skill/roulin2.mp3', - 'audio/skill/ruilve1.mp3', - 'audio/skill/ruilve2.mp3', - 'audio/skill/ruoyu_re_liushan1.mp3', - 'audio/skill/ruoyu_re_liushan2.mp3', - 'audio/skill/ruoyu1.mp3', - 'audio/skill/ruoyu2.mp3', - 'audio/skill/rw_bagua_skill.mp3', - 'audio/skill/rw_baiyin_skill.mp3', - 'audio/skill/rw_renwang_skill.mp3', - 'audio/skill/rw_tengjia1.mp3', - 'audio/skill/rw_tengjia2.mp3', - 'audio/skill/rw_zhuge_skill.mp3', - 'audio/skill/sanchen1.mp3', - 'audio/skill/sanchen2.mp3', - 'audio/skill/sangu1.mp3', - 'audio/skill/sangu2.mp3', - 'audio/skill/sanjian_skill.mp3', - 'audio/skill/sanku1.mp3', - 'audio/skill/sanku2.mp3', - 'audio/skill/sanshou1.mp3', - 'audio/skill/sanshou2.mp3', - 'audio/skill/sanyao1.mp3', - 'audio/skill/sanyao2.mp3', - 'audio/skill/saodi1.mp3', - 'audio/skill/saodi2.mp3', - 'audio/skill/saya_powei1.mp3', - 'audio/skill/saya_powei2.mp3', - 'audio/skill/saya_shouji1.mp3', - 'audio/skill/saya_shouji2.mp3', - 'audio/skill/sbaiyin.mp3', - 'audio/skill/sbaiyin1.mp3', - 'audio/skill/sbaiyin2.mp3', - 'audio/skill/sbanguo1.mp3', - 'audio/skill/sbanguo2.mp3', - 'audio/skill/sbanguo3.mp3', - 'audio/skill/sbbenxi1.mp3', - 'audio/skill/sbbenxi2.mp3', - 'audio/skill/sbbenxi3.mp3', - 'audio/skill/sbbiyue1.mp3', - 'audio/skill/sbbiyue2.mp3', - 'audio/skill/sbduanliang_false.mp3', - 'audio/skill/sbduanliang_true1.mp3', - 'audio/skill/sbduanliang_true2.mp3', - 'audio/skill/sbduanliang1.mp3', - 'audio/skill/sbdujiang1.mp3', - 'audio/skill/sbdujiang2.mp3', - 'audio/skill/sbduojing1.mp3', - 'audio/skill/sbduojing2.mp3', - 'audio/skill/sbenyuan1.mp3', - 'audio/skill/sbenyuan2.mp3', - 'audio/skill/sbfangzhu1.mp3', - 'audio/skill/sbfangzhu2.mp3', - 'audio/skill/sbfanjian1.mp3', - 'audio/skill/sbfanjian2.mp3', - 'audio/skill/sbfenwei1.mp3', - 'audio/skill/sbfenwei2.mp3', - 'audio/skill/sbguanxing1.mp3', - 'audio/skill/sbguanxing2.mp3', - 'audio/skill/sbguidao1.mp3', - 'audio/skill/sbguidao2.mp3', - 'audio/skill/sbguose1.mp3', - 'audio/skill/sbguose2.mp3', - 'audio/skill/sbhuangtian1.mp3', - 'audio/skill/sbhuangtian2.mp3', - 'audio/skill/sbhujia1.mp3', - 'audio/skill/sbhujia2.mp3', - 'audio/skill/sbhunzi1.mp3', - 'audio/skill/sbhunzi2.mp3', - 'audio/skill/sbhuoji1.mp3', - 'audio/skill/sbhuoji2.mp3', - 'audio/skill/sbhuoji3.mp3', - 'audio/skill/sbhuoshou1.mp3', - 'audio/skill/sbhuoshou2.mp3', - 'audio/skill/sbjiang1.mp3', - 'audio/skill/sbjiang2.mp3', - 'audio/skill/sbjianxiong1.mp3', - 'audio/skill/sbjianxiong2.mp3', - 'audio/skill/sbjieming1.mp3', - 'audio/skill/sbjieming2.mp3', - 'audio/skill/sbjiewei1.mp3', - 'audio/skill/sbjiewei2.mp3', - 'audio/skill/sbjieyin1.mp3', - 'audio/skill/sbjieyin2.mp3', - 'audio/skill/sbjieyue1.mp3', - 'audio/skill/sbjieyue2.mp3', - 'audio/skill/sbjieyue3.mp3', - 'audio/skill/sbjieyue4.mp3', - 'audio/skill/sbjijiang1.mp3', - 'audio/skill/sbjijiang2.mp3', - 'audio/skill/sbjiuyuan1.mp3', - 'audio/skill/sbjiuyuan2.mp3', - 'audio/skill/sbjizhi1.mp3', - 'audio/skill/sbjizhi2.mp3', - 'audio/skill/sbjizhu1.mp3', - 'audio/skill/sbjizhu2.mp3', - 'audio/skill/sbjizhu3.mp3', - 'audio/skill/sbjushou1.mp3', - 'audio/skill/sbjushou2.mp3', - 'audio/skill/sbjushou3.mp3', - 'audio/skill/sbjuxiang1.mp3', - 'audio/skill/sbjuxiang2.mp3', - 'audio/skill/sbkanpo1.mp3', - 'audio/skill/sbkanpo2.mp3', - 'audio/skill/sbkeji1.mp3', - 'audio/skill/sbkeji2.mp3', - 'audio/skill/sbkongcheng1.mp3', - 'audio/skill/sbkongcheng2.mp3', - 'audio/skill/sbkurou1.mp3', - 'audio/skill/sbkurou2.mp3', - 'audio/skill/sbleiji1.mp3', - 'audio/skill/sbleiji2.mp3', - 'audio/skill/sbliangzhu1.mp3', - 'audio/skill/sbliangzhu2.mp3', - 'audio/skill/sblianhuan1.mp3', - 'audio/skill/sblianhuan2.mp3', - 'audio/skill/sbliegong1.mp3', - 'audio/skill/sbliegong2.mp3', - 'audio/skill/sblieren1.mp3', - 'audio/skill/sblieren2.mp3', - 'audio/skill/sblijian1.mp3', - 'audio/skill/sblijian2.mp3', - 'audio/skill/sbliuli1.mp3', - 'audio/skill/sbliuli2.mp3', - 'audio/skill/sblongdan1.mp3', - 'audio/skill/sblongdan2.mp3', - 'audio/skill/sbluanji1.mp3', - 'audio/skill/sbluanji2.mp3', - 'audio/skill/sbluoshen1.mp3', - 'audio/skill/sbluoshen2.mp3', - 'audio/skill/sbmingce1.mp3', - 'audio/skill/sbmingce2.mp3', - 'audio/skill/sbniepan1.mp3', - 'audio/skill/sbniepan2.mp3', - 'audio/skill/sbpaoxiao1.mp3', - 'audio/skill/sbpaoxiao2.mp3', - 'audio/skill/sbqiaobian1.mp3', - 'audio/skill/sbqiaobian2.mp3', - 'audio/skill/sbqiaoshi1.mp3', - 'audio/skill/sbqiaoshi2.mp3', - 'audio/skill/sbqicai1.mp3', - 'audio/skill/sbqicai2.mp3', - 'audio/skill/sbqingzheng1.mp3', - 'audio/skill/sbqingzheng2.mp3', - 'audio/skill/sbqixi1.mp3', - 'audio/skill/sbqixi2.mp3', - 'audio/skill/sbquhu1.mp3', - 'audio/skill/sbquhu2.mp3', - 'audio/skill/sbrende1.mp3', - 'audio/skill/sbrende2.mp3', - 'audio/skill/sbrende3.mp3', - 'audio/skill/sbshipo1.mp3', - 'audio/skill/sbshipo2.mp3', - 'audio/skill/sbsongwei1.mp3', - 'audio/skill/sbsongwei2.mp3', - 'audio/skill/sbtianxiang1.mp3', - 'audio/skill/sbtianxiang2.mp3', - 'audio/skill/sbtiaoxin1.mp3', - 'audio/skill/sbtiaoxin2.mp3', - 'audio/skill/sbtieji_false.mp3', - 'audio/skill/sbtieji_true1.mp3', - 'audio/skill/sbtieji_true2.mp3', - 'audio/skill/sbtieji1.mp3', - 'audio/skill/sbtongye1.mp3', - 'audio/skill/sbtongye2.mp3', - 'audio/skill/sbwusheng1.mp3', - 'audio/skill/sbwusheng2.mp3', - 'audio/skill/sbwusheng3.mp3', - 'audio/skill/sbxiaoji1.mp3', - 'audio/skill/sbxiaoji2.mp3', - 'audio/skill/sbxiayuan1.mp3', - 'audio/skill/sbxiayuan2.mp3', - 'audio/skill/sbxieji1.mp3', - 'audio/skill/sbxieji2.mp3', - 'audio/skill/sbxieji3.mp3', - 'audio/skill/sbxingshang1.mp3', - 'audio/skill/sbxingshang2.mp3', - 'audio/skill/sbxuanhuo1.mp3', - 'audio/skill/sbxuanhuo2.mp3', - 'audio/skill/sbxueyi1.mp3', - 'audio/skill/sbxueyi2.mp3', - 'audio/skill/sbyangwei1.mp3', - 'audio/skill/sbyangwei2.mp3', - 'audio/skill/sbyanyu1.mp3', - 'audio/skill/sbyanyu2.mp3', - 'audio/skill/sbyaoming1.mp3', - 'audio/skill/sbyaoming2.mp3', - 'audio/skill/sbyijue1.mp3', - 'audio/skill/sbyijue2.mp3', - 'audio/skill/sbyingzi_sb_sunce1.mp3', - 'audio/skill/sbyingzi_sb_sunce2.mp3', - 'audio/skill/sbyingzi1.mp3', - 'audio/skill/sbyingzi2.mp3', - 'audio/skill/sbzaiqi1.mp3', - 'audio/skill/sbzaiqi2.mp3', - 'audio/skill/sbzhangwu1.mp3', - 'audio/skill/sbzhangwu2.mp3', - 'audio/skill/sbzhaxiang1.mp3', - 'audio/skill/sbzhaxiang2.mp3', - 'audio/skill/sbzhenliang1.mp3', - 'audio/skill/sbzhenliang2.mp3', - 'audio/skill/sbzhiba1.mp3', - 'audio/skill/sbzhiba2.mp3', - 'audio/skill/sbzhichi1.mp3', - 'audio/skill/sbzhichi2.mp3', - 'audio/skill/sbzhiheng1.mp3', - 'audio/skill/sbzhiheng2.mp3', - 'audio/skill/sbzhiji1.mp3', - 'audio/skill/sbzhiji2.mp3', - 'audio/skill/sbzishou1.mp3', - 'audio/skill/sbzishou2.mp3', - 'audio/skill/sbzongshi1.mp3', - 'audio/skill/sbzongshi2.mp3', - 'audio/skill/scfuhai1.mp3', - 'audio/skill/scfuhai2.mp3', - 'audio/skill/scs_bilan_enter.mp3', - 'audio/skill/scs_duangui_enter.mp3', - 'audio/skill/scs_gaowang_enter.mp3', - 'audio/skill/scs_guosheng_enter.mp3', - 'audio/skill/scs_hankui_enter.mp3', - 'audio/skill/scs_lisong_enter.mp3', - 'audio/skill/scs_sunzhang_enter.mp3', - 'audio/skill/scs_xiayun_enter.mp3', - 'audio/skill/scs_zhangrang_enter.mp3', - 'audio/skill/scs_zhaozhong_enter.mp3', - 'audio/skill/scsanruo1.mp3', - 'audio/skill/scschihe1.mp3', - 'audio/skill/scschiyan1.mp3', - 'audio/skill/scskuiji1.mp3', - 'audio/skill/scsniqu1.mp3', - 'audio/skill/scspicai1.mp3', - 'audio/skill/scstaoluan1.mp3', - 'audio/skill/scsxiaolu1.mp3', - 'audio/skill/scsyaozhuo1.mp3', - 'audio/skill/scszimou1.mp3', - 'audio/skill/sghuishi1.mp3', - 'audio/skill/sghuishi2.mp3', - 'audio/skill/sgrenwang1.mp3', - 'audio/skill/sgrenwang2.mp3', - 'audio/skill/shameng1.mp3', - 'audio/skill/shameng2.mp3', - 'audio/skill/shanduan1.mp3', - 'audio/skill/shanduan2.mp3', - 'audio/skill/shangshi1.mp3', - 'audio/skill/shangshi2.mp3', - 'audio/skill/shangshix1.mp3', - 'audio/skill/shangshix2.mp3', - 'audio/skill/shangyi1.mp3', - 'audio/skill/shangyi2.mp3', - 'audio/skill/shanjia1.mp3', - 'audio/skill/shanjia2.mp3', - 'audio/skill/shanli1.mp3', - 'audio/skill/shanli2.mp3', - 'audio/skill/shanshen1.mp3', - 'audio/skill/shanshen2.mp3', - 'audio/skill/shanxi1.mp3', - 'audio/skill/shanxi2.mp3', - 'audio/skill/shanxie1.mp3', - 'audio/skill/shanxie2.mp3', - 'audio/skill/shanzhuan1.mp3', - 'audio/skill/shanzhuan2.mp3', - 'audio/skill/shebian1.mp3', - 'audio/skill/shebian2.mp3', - 'audio/skill/shefu1.mp3', - 'audio/skill/shefu2.mp3', - 'audio/skill/shejian1.mp3', - 'audio/skill/shejian2.mp3', - 'audio/skill/shelie1.mp3', - 'audio/skill/shelie2.mp3', - 'audio/skill/shencai1.mp3', - 'audio/skill/shencai2.mp3', - 'audio/skill/shenduan1.mp3', - 'audio/skill/shenduan2.mp3', - 'audio/skill/shenfen1.mp3', - 'audio/skill/shenfen2.mp3', - 'audio/skill/shenfu1.mp3', - 'audio/skill/shenfu2.mp3', - 'audio/skill/shengxi_feiyi1.mp3', - 'audio/skill/shengxi_feiyi2.mp3', - 'audio/skill/shengxi1.mp3', - 'audio/skill/shengxi2.mp3', - 'audio/skill/shenji1.mp3', - 'audio/skill/shenji2.mp3', - 'audio/skill/shenju1.mp3', - 'audio/skill/shenju2.mp3', - 'audio/skill/shenpin1.mp3', - 'audio/skill/shenpin2.mp3', - 'audio/skill/shenqu1.mp3', - 'audio/skill/shenqu2.mp3', - 'audio/skill/shensu1_ol_xiahouyuan1.mp3', - 'audio/skill/shensu1_ol_xiahouyuan2.mp3', - 'audio/skill/shensu1_re_xiahouyuan1.mp3', - 'audio/skill/shensu1_re_xiahouyuan2.mp3', - 'audio/skill/shensu1_xiahouba1.mp3', - 'audio/skill/shensu1_xiahouba2.mp3', - 'audio/skill/shensu11.mp3', - 'audio/skill/shensu12.mp3', - 'audio/skill/shensu21.mp3', - 'audio/skill/shensu22.mp3', - 'audio/skill/shenwei1.mp3', - 'audio/skill/shenwei2.mp3', - 'audio/skill/shenxian1.mp3', - 'audio/skill/shenxian2.mp3', - 'audio/skill/shenxing1.mp3', - 'audio/skill/shenxing2.mp3', - 'audio/skill/shenzhi1.mp3', - 'audio/skill/shenzhi2.mp3', - 'audio/skill/shenzhu1.mp3', - 'audio/skill/shenzhu2.mp3', - 'audio/skill/sheyan1.mp3', - 'audio/skill/sheyan2.mp3', - 'audio/skill/sheyi1.mp3', - 'audio/skill/sheyi2.mp3', - 'audio/skill/shezang1.mp3', - 'audio/skill/shezang2.mp3', - 'audio/skill/shhlianhua1.mp3', - 'audio/skill/shhlianhua2.mp3', - 'audio/skill/shibei_xin_jushou1.mp3', - 'audio/skill/shibei_xin_jushou2.mp3', - 'audio/skill/shibei1.mp3', - 'audio/skill/shibei2.mp3', - 'audio/skill/shichou1.mp3', - 'audio/skill/shichou2.mp3', - 'audio/skill/shiduo1.mp3', - 'audio/skill/shiduo2.mp3', - 'audio/skill/shifei_re_guotufengji1.mp3', - 'audio/skill/shifei_re_guotufengji2.mp3', - 'audio/skill/shifei1.mp3', - 'audio/skill/shifei2.mp3', - 'audio/skill/shiina_feiyan1.mp3', - 'audio/skill/shiina_qingshen1.mp3', - 'audio/skill/shiina_retieji1.mp3', - 'audio/skill/shiki_omusubi1.mp3', - 'audio/skill/shiki_omusubi2.mp3', - 'audio/skill/shiming1.mp3', - 'audio/skill/shiming2.mp3', - 'audio/skill/shiorimiyuki_banyin1.mp3', - 'audio/skill/shiorimiyuki_banyin2.mp3', - 'audio/skill/shiorimiyuki_tingxian1.mp3', - 'audio/skill/shiorimiyuki_tingxian2.mp3', - 'audio/skill/shiren1.mp3', - 'audio/skill/shiren2.mp3', - 'audio/skill/shishengshibai.mp3', - 'audio/skill/shixin1.mp3', - 'audio/skill/shixin2.mp3', - 'audio/skill/shiyong1.mp3', - 'audio/skill/shiyong2.mp3', - 'audio/skill/shiyong3.mp3', - 'audio/skill/shiyuan1.mp3', - 'audio/skill/shiyuan2.mp3', - 'audio/skill/shizhan1.mp3', - 'audio/skill/shizhan2.mp3', - 'audio/skill/shoucheng1.mp3', - 'audio/skill/shoucheng2.mp3', - 'audio/skill/shoufa1.mp3', - 'audio/skill/shoufa2.mp3', - 'audio/skill/shouli1.mp3', - 'audio/skill/shouli2.mp3', - 'audio/skill/shoulijian.mp3', - 'audio/skill/shouxi1.mp3', - 'audio/skill/shouxi2.mp3', - 'audio/skill/shouye1.mp3', - 'audio/skill/shouye2.mp3', - 'audio/skill/shuaiyan1.mp3', - 'audio/skill/shuaiyan2.mp3', - 'audio/skill/shuangren1.mp3', - 'audio/skill/shuangren2.mp3', - 'audio/skill/shuangxiong_re_yanwen1.mp3', - 'audio/skill/shuangxiong_re_yanwen2.mp3', - 'audio/skill/shuangxiong1.mp3', - 'audio/skill/shuangxiong2.mp3', - 'audio/skill/shuchen1.mp3', - 'audio/skill/shuchen2.mp3', - 'audio/skill/shuimeng1.mp3', - 'audio/skill/shuimeng2.mp3', - 'audio/skill/shuishi1.mp3', - 'audio/skill/shuishi2.mp3', - 'audio/skill/shuliang1.mp3', - 'audio/skill/shuliang2.mp3', - 'audio/skill/shunshi1.mp3', - 'audio/skill/shunshi2.mp3', - 'audio/skill/shuojian1.mp3', - 'audio/skill/shuojian2.mp3', - 'audio/skill/shushen1.mp3', - 'audio/skill/shushen2.mp3', - 'audio/skill/sibian1.mp3', - 'audio/skill/sibian2.mp3', - 'audio/skill/sidi.mp3', - 'audio/skill/sidi1.mp3', - 'audio/skill/sidi2.mp3', - 'audio/skill/sijian1.mp3', - 'audio/skill/sijian2.mp3', - 'audio/skill/sijun1.mp3', - 'audio/skill/sijun2.mp3', - 'audio/skill/sishu1.mp3', - 'audio/skill/sishu2.mp3', - 'audio/skill/smyyingshi1.mp3', - 'audio/skill/smyyingshi2.mp3', - 'audio/skill/songci1.mp3', - 'audio/skill/songci2.mp3', - 'audio/skill/songshu1.mp3', - 'audio/skill/songshu2.mp3', - 'audio/skill/songwei_re_caopi1.mp3', - 'audio/skill/songwei_re_caopi2.mp3', - 'audio/skill/songwei2_re_caopi1.mp3', - 'audio/skill/songwei2_re_caopi2.mp3', - 'audio/skill/songwei21.mp3', - 'audio/skill/songwei22.mp3', - 'audio/skill/souying1.mp3', - 'audio/skill/souying2.mp3', - 'audio/skill/spchijie1.mp3', - 'audio/skill/spchijie2.mp3', - 'audio/skill/spcunsi1.mp3', - 'audio/skill/spcunsi2.mp3', - 'audio/skill/spdaizui1.mp3', - 'audio/skill/spdaizui2.mp3', - 'audio/skill/spdaming1.mp3', - 'audio/skill/spdaming2.mp3', - 'audio/skill/spdaming3.mp3', - 'audio/skill/spdaoshu1.mp3', - 'audio/skill/spdaoshu2.mp3', - 'audio/skill/spdaoshu3.mp3', - 'audio/skill/spdengli1.mp3', - 'audio/skill/spdengli2.mp3', - 'audio/skill/spdiancai1.mp3', - 'audio/skill/spdiancai2.mp3', - 'audio/skill/spdiaodu1.mp3', - 'audio/skill/spdiaodu2.mp3', - 'audio/skill/spdifei1.mp3', - 'audio/skill/spdifei2.mp3', - 'audio/skill/spell2131_1.mp3', - 'audio/skill/spell2131_2.mp3', - 'audio/skill/spfangzong1.mp3', - 'audio/skill/spfangzong2.mp3', - 'audio/skill/spfenming1.mp3', - 'audio/skill/spfenming2.mp3', - 'audio/skill/spguixiu1.mp3', - 'audio/skill/spguixiu2.mp3', - 'audio/skill/spjianyi1.mp3', - 'audio/skill/spjianyi2.mp3', - 'audio/skill/spjiedao1.mp3', - 'audio/skill/spjiedao2.mp3', - 'audio/skill/spjincui1.mp3', - 'audio/skill/spjincui2.mp3', - 'audio/skill/spjungong1.mp3', - 'audio/skill/spjungong2.mp3', - 'audio/skill/splirang1.mp3', - 'audio/skill/splirang2.mp3', - 'audio/skill/splveying1.mp3', - 'audio/skill/splveying2.mp3', - 'audio/skill/spmanwang1.mp3', - 'audio/skill/spmanwang2.mp3', - 'audio/skill/spmiewu1.mp3', - 'audio/skill/spmiewu2.mp3', - 'audio/skill/spmingshi1.mp3', - 'audio/skill/spmingshi2.mp3', - 'audio/skill/spmingxuan1.mp3', - 'audio/skill/spmingxuan2.mp3', - 'audio/skill/spolzhouxuan1.mp3', - 'audio/skill/spolzhouxuan2.mp3', - 'audio/skill/sppanqin1.mp3', - 'audio/skill/sppanqin2.mp3', - 'audio/skill/spqiai1.mp3', - 'audio/skill/spqiai2.mp3', - 'audio/skill/spqishe1.mp3', - 'audio/skill/spqishe2.mp3', - 'audio/skill/spsanchen1.mp3', - 'audio/skill/spsanchen2.mp3', - 'audio/skill/spshangyi1.mp3', - 'audio/skill/spshangyi2.mp3', - 'audio/skill/spshanxi1.mp3', - 'audio/skill/spshanxi2.mp3', - 'audio/skill/spshicai1.mp3', - 'audio/skill/spshicai2.mp3', - 'audio/skill/spshidi1.mp3', - 'audio/skill/spshidi2.mp3', - 'audio/skill/spshiji1.mp3', - 'audio/skill/spshiji2.mp3', - 'audio/skill/spsongshu1.mp3', - 'audio/skill/spsongshu2.mp3', - 'audio/skill/sptaoluan1.mp3', - 'audio/skill/sptaoluan2.mp3', - 'audio/skill/sptunjiang1.mp3', - 'audio/skill/sptunjiang2.mp3', - 'audio/skill/spwanwei1.mp3', - 'audio/skill/spwanwei2.mp3', - 'audio/skill/spweiwu1.mp3', - 'audio/skill/spweiwu2.mp3', - 'audio/skill/spwenji1.mp3', - 'audio/skill/spwenji2.mp3', - 'audio/skill/spwuku1.mp3', - 'audio/skill/spwuku2.mp3', - 'audio/skill/spxianchou1.mp3', - 'audio/skill/spxianchou2.mp3', - 'audio/skill/spxiangzhen1.mp3', - 'audio/skill/spxiangzhen2.mp3', - 'audio/skill/spxiaoni1.mp3', - 'audio/skill/spxiaoni2.mp3', - 'audio/skill/spxizhan1.mp3', - 'audio/skill/spxizhan2.mp3', - 'audio/skill/spxizhan3.mp3', - 'audio/skill/spxizhan4.mp3', - 'audio/skill/spyajun1.mp3', - 'audio/skill/spyajun2.mp3', - 'audio/skill/spyanji1.mp3', - 'audio/skill/spyanji2.mp3', - 'audio/skill/spyanji3.mp3', - 'audio/skill/spyanjiao1.mp3', - 'audio/skill/spyanjiao2.mp3', - 'audio/skill/spyilie1.mp3', - 'audio/skill/spyilie2.mp3', - 'audio/skill/spyingwu1.mp3', - 'audio/skill/spyingwu2.mp3', - 'audio/skill/spyinju1.mp3', - 'audio/skill/spyinju2.mp3', - 'audio/skill/spyishi1.mp3', - 'audio/skill/spyishi2.mp3', - 'audio/skill/spyuejian1.mp3', - 'audio/skill/spyuejian2.mp3', - 'audio/skill/spzhengjun1.mp3', - 'audio/skill/spzhengjun2.mp3', - 'audio/skill/spzhengjun3.mp3', - 'audio/skill/spzhenting1.mp3', - 'audio/skill/spzhenting2.mp3', - 'audio/skill/spzhenwei1.mp3', - 'audio/skill/spzhenwei2.mp3', - 'audio/skill/spzhuilie1.mp3', - 'audio/skill/spzhuilie2.mp3', - 'audio/skill/spzundi1.mp3', - 'audio/skill/spzundi2.mp3', - 'audio/skill/staraoshi1.mp3', - 'audio/skill/staraoshi2.mp3', - 'audio/skill/starcanxi1.mp3', - 'audio/skill/starcanxi2.mp3', - 'audio/skill/starhaoshou1.mp3', - 'audio/skill/starhaoshou2.mp3', - 'audio/skill/starjiaowang1.mp3', - 'audio/skill/starjiaowang2.mp3', - 'audio/skill/starlifeng1.mp3', - 'audio/skill/starlifeng2.mp3', - 'audio/skill/starpizhi1.mp3', - 'audio/skill/starpizhi2.mp3', - 'audio/skill/starsujun1.mp3', - 'audio/skill/starsujun2.mp3', - 'audio/skill/starweilin1.mp3', - 'audio/skill/starweilin2.mp3', - 'audio/skill/starxiaoyan1.mp3', - 'audio/skill/starxiaoyan2.mp3', - 'audio/skill/starzhangrong1.mp3', - 'audio/skill/starzhangrong2.mp3', - 'audio/skill/starzhonggu1.mp3', - 'audio/skill/starzhonggu2.mp3', - 'audio/skill/starzongshi1.mp3', - 'audio/skill/starzongshi2.mp3', - 'audio/skill/stianyi1.mp3', - 'audio/skill/stianyi2.mp3', - 'audio/skill/suishi1.mp3', - 'audio/skill/suishi2.mp3', - 'audio/skill/suizheng1.mp3', - 'audio/skill/suizheng2.mp3', - 'audio/skill/suoliang1.mp3', - 'audio/skill/suoliang2.mp3', - 'audio/skill/sushou1.mp3', - 'audio/skill/sushou2.mp3', - 'audio/skill/suzi1.mp3', - 'audio/skill/suzi2.mp3', - 'audio/skill/syjiqiao1.mp3', - 'audio/skill/syjiqiao2.mp3', - 'audio/skill/syxiongyi1.mp3', - 'audio/skill/syxiongyi2.mp3', - 'audio/skill/tairan1.mp3', - 'audio/skill/tairan2.mp3', - 'audio/skill/tamo1.mp3', - 'audio/skill/tamo2.mp3', - 'audio/skill/taoluan1.mp3', - 'audio/skill/taoluan2.mp3', - 'audio/skill/taomie1.mp3', - 'audio/skill/taomie2.mp3', - 'audio/skill/taomie3.mp3', - 'audio/skill/taoxi1.mp3', - 'audio/skill/taoxi2.mp3', - 'audio/skill/taoyin1.mp3', - 'audio/skill/taoyin2.mp3', - 'audio/skill/tashui1.mp3', - 'audio/skill/tashui2.mp3', - 'audio/skill/tengjia1.mp3', - 'audio/skill/tengjia2.mp3', - 'audio/skill/tianbian1.mp3', - 'audio/skill/tianbian2.mp3', - 'audio/skill/tiandao.mp3', - 'audio/skill/tiandu_re_guojia1.mp3', - 'audio/skill/tiandu_re_guojia2.mp3', - 'audio/skill/tiandu_xizhicai1.mp3', - 'audio/skill/tiandu_xizhicai2.mp3', - 'audio/skill/tiandu1.mp3', - 'audio/skill/tiandu2.mp3', - 'audio/skill/tianfu1.mp3', - 'audio/skill/tianfu2.mp3', - 'audio/skill/tianjie1.mp3', - 'audio/skill/tianjie2.mp3', - 'audio/skill/tianming1.mp3', - 'audio/skill/tianming2.mp3', - 'audio/skill/tianren1.mp3', - 'audio/skill/tianren2.mp3', - 'audio/skill/tianshu1.mp3', - 'audio/skill/tianshu2.mp3', - 'audio/skill/tiansuan1.mp3', - 'audio/skill/tiansuan2.mp3', - 'audio/skill/tianxiang_daxiaoqiao1.mp3', - 'audio/skill/tianxiang_daxiaoqiao2.mp3', - 'audio/skill/tianxiang_ol_xiaoqiao1.mp3', - 'audio/skill/tianxiang_ol_xiaoqiao2.mp3', - 'audio/skill/tianxiang_re_xiaoqiao1.mp3', - 'audio/skill/tianxiang_re_xiaoqiao2.mp3', - 'audio/skill/tianxiang1.mp3', - 'audio/skill/tianxiang2.mp3', - 'audio/skill/tianxing1.mp3', - 'audio/skill/tianxing2.mp3', - 'audio/skill/tianyi_re_taishici1.mp3', - 'audio/skill/tianyi_re_taishici2.mp3', - 'audio/skill/tianyi1.mp3', - 'audio/skill/tianyi2.mp3', - 'audio/skill/tianyin1.mp3', - 'audio/skill/tianyin2.mp3', - 'audio/skill/tianyun1.mp3', - 'audio/skill/tianyun2.mp3', - 'audio/skill/tianze1.mp3', - 'audio/skill/tianze2.mp3', - 'audio/skill/tianzuo1.mp3', - 'audio/skill/tianzuo2.mp3', - 'audio/skill/tiaoxin_gz_jiangwei1.mp3', - 'audio/skill/tiaoxin_gz_jiangwei2.mp3', - 'audio/skill/tiaoxin_ol_jiangwei1.mp3', - 'audio/skill/tiaoxin_ol_jiangwei2.mp3', - 'audio/skill/tiaoxin_re_jiangwei1.mp3', - 'audio/skill/tiaoxin_re_jiangwei2.mp3', - 'audio/skill/tiaoxin_sp_jiangwei1.mp3', - 'audio/skill/tiaoxin_sp_jiangwei2.mp3', - 'audio/skill/tiaoxin_xiahouba1.mp3', - 'audio/skill/tiaoxin_xiahouba2.mp3', - 'audio/skill/tiaoxin1.mp3', - 'audio/skill/tiaoxin2.mp3', - 'audio/skill/tieji1.mp3', - 'audio/skill/tieji2.mp3', - 'audio/skill/tiqi1.mp3', - 'audio/skill/tiqi2.mp3', - 'audio/skill/tongbo1.mp3', - 'audio/skill/tongbo2.mp3', - 'audio/skill/tongduo1.mp3', - 'audio/skill/tongduo2.mp3', - 'audio/skill/tongji1.mp3', - 'audio/skill/tongji2.mp3', - 'audio/skill/tongli1.mp3', - 'audio/skill/tongli2.mp3', - 'audio/skill/tongqu1.mp3', - 'audio/skill/tongqu2.mp3', - 'audio/skill/tongwei1.mp3', - 'audio/skill/tongwei2.mp3', - 'audio/skill/tongxie1.mp3', - 'audio/skill/tongxie2.mp3', - 'audio/skill/tongyuan1.mp3', - 'audio/skill/tongyuan2.mp3', - 'audio/skill/tspowei1.mp3', - 'audio/skill/tspowei2.mp3', - 'audio/skill/tspowei3.mp3', - 'audio/skill/tsumugi_mugyu1.mp3', - 'audio/skill/tsumugi_mugyu2.mp3', - 'audio/skill/tsumugi_mugyu3.mp3', - 'audio/skill/tsumugi_mugyu4.mp3', - 'audio/skill/tsumugi_mugyu5.mp3', - 'audio/skill/tuifeng1.mp3', - 'audio/skill/tuifeng2.mp3', - 'audio/skill/tuishi1.mp3', - 'audio/skill/tuishi2.mp3', - 'audio/skill/tuiyan1.mp3', - 'audio/skill/tuiyan2.mp3', - 'audio/skill/tunchu1.mp3', - 'audio/skill/tunchu2.mp3', - 'audio/skill/tuntian_gz_dengai1.mp3', - 'audio/skill/tuntian_gz_dengai2.mp3', - 'audio/skill/tuntian1.mp3', - 'audio/skill/tuntian2.mp3', - 'audio/skill/tuogu1.mp3', - 'audio/skill/tuogu2.mp3', - 'audio/skill/tuoxian.mp3', - 'audio/skill/tuoxian2.mp3', - 'audio/skill/tuxi1.mp3', - 'audio/skill/tuxi2.mp3', - 'audio/skill/tuxing1.mp3', - 'audio/skill/tuxing2.mp3', - 'audio/skill/twbingde1.mp3', - 'audio/skill/twbingde2.mp3', - 'audio/skill/twbudao1.mp3', - 'audio/skill/twbudao2.mp3', - 'audio/skill/twchaofeng1.mp3', - 'audio/skill/twchaofeng2.mp3', - 'audio/skill/twchayi1.mp3', - 'audio/skill/twchengxi1.mp3', - 'audio/skill/twchengxi2.mp3', - 'audio/skill/twchongqi1.mp3', - 'audio/skill/twchongqi2.mp3', - 'audio/skill/twchuanshu1.mp3', - 'audio/skill/twchuanshu2.mp3', - 'audio/skill/twchungang1.mp3', - 'audio/skill/twchungang2.mp3', - 'audio/skill/twdanfa1.mp3', - 'audio/skill/twdanfa2.mp3', - 'audio/skill/twdanlie1.mp3', - 'audio/skill/twdanlie2.mp3', - 'audio/skill/twdianyi1.mp3', - 'audio/skill/twdianyi2.mp3', - 'audio/skill/twdingzhen1.mp3', - 'audio/skill/twdingzhen2.mp3', - 'audio/skill/twduoren1.mp3', - 'audio/skill/twduoren2.mp3', - 'audio/skill/twfeifu1.mp3', - 'audio/skill/twfeifu2.mp3', - 'audio/skill/twfengji1.mp3', - 'audio/skill/twfengji2.mp3', - 'audio/skill/twfenwang1.mp3', - 'audio/skill/twfenwang2.mp3', - 'audio/skill/twfenwu1.mp3', - 'audio/skill/twfenwu2.mp3', - 'audio/skill/twfucuan1.mp3', - 'audio/skill/twfucuan2.mp3', - 'audio/skill/twfujian1.mp3', - 'audio/skill/twfujian2.mp3', - 'audio/skill/twfupan1.mp3', - 'audio/skill/twfupan2.mp3', - 'audio/skill/twfupan3.mp3', - 'audio/skill/twfuzuan1.mp3', - 'audio/skill/twfuzuan2.mp3', - 'audio/skill/twgezhi1.mp3', - 'audio/skill/twgezhi2.mp3', - 'audio/skill/twgongge1.mp3', - 'audio/skill/twgongge2.mp3', - 'audio/skill/twgongge3.mp3', - 'audio/skill/twhanyu1.mp3', - 'audio/skill/twhanyu2.mp3', - 'audio/skill/twhuiyuan1.mp3', - 'audio/skill/twhuiyuan2.mp3', - 'audio/skill/twhuzhong1.mp3', - 'audio/skill/twhuzhong2.mp3', - 'audio/skill/twjiange1.mp3', - 'audio/skill/twjiange2.mp3', - 'audio/skill/twjianming1.mp3', - 'audio/skill/twjianming2.mp3', - 'audio/skill/twjianwei1.mp3', - 'audio/skill/twjianwei2.mp3', - 'audio/skill/twjiaohua1.mp3', - 'audio/skill/twjiaohua2.mp3', - 'audio/skill/twjichou1.mp3', - 'audio/skill/twjichou2.mp3', - 'audio/skill/twjiekuang1.mp3', - 'audio/skill/twjiekuang2.mp3', - 'audio/skill/twjieyu1.mp3', - 'audio/skill/twjieyu2.mp3', - 'audio/skill/twjijiang1.mp3', - 'audio/skill/twjijiang2.mp3', - 'audio/skill/twjilun1.mp3', - 'audio/skill/twjilun2.mp3', - 'audio/skill/twjingce1.mp3', - 'audio/skill/twjingce2.mp3', - 'audio/skill/twjuchen1.mp3', - 'audio/skill/twjuchen2.mp3', - 'audio/skill/twjuezhu1.mp3', - 'audio/skill/twjuezhu2.mp3', - 'audio/skill/twjuntun1.mp3', - 'audio/skill/twjuntun2.mp3', - 'audio/skill/twkaiji1.mp3', - 'audio/skill/twkaiji2.mp3', - 'audio/skill/twkaizeng1.mp3', - 'audio/skill/twkaizeng2.mp3', - 'audio/skill/twkujian1.mp3', - 'audio/skill/twkujian2.mp3', - 'audio/skill/twkujian3.mp3', - 'audio/skill/twkunsi1.mp3', - 'audio/skill/twkunsi2.mp3', - 'audio/skill/twlanjiang.mp3', - 'audio/skill/twliexi1.mp3', - 'audio/skill/twliexi2.mp3', - 'audio/skill/twlijian1.mp3', - 'audio/skill/twlijian2.mp3', - 'audio/skill/twlingbao1.mp3', - 'audio/skill/twlingbao2.mp3', - 'audio/skill/twlingfa1.mp3', - 'audio/skill/twlingfa2.mp3', - 'audio/skill/twluanlve1.mp3', - 'audio/skill/twluanlve2.mp3', - 'audio/skill/twluannian1.mp3', - 'audio/skill/twluannian2.mp3', - 'audio/skill/twlvren1.mp3', - 'audio/skill/twlvren2.mp3', - 'audio/skill/twmiaolve1.mp3', - 'audio/skill/twmiaolve2.mp3', - 'audio/skill/twmutao1.mp3', - 'audio/skill/twmutao2.mp3', - 'audio/skill/twmuyue1.mp3', - 'audio/skill/twneirao1.mp3', - 'audio/skill/twneirao2.mp3', - 'audio/skill/twqingkou1.mp3', - 'audio/skill/twqingkou2.mp3', - 'audio/skill/twqingren1.mp3', - 'audio/skill/twqingren2.mp3', - 'audio/skill/twqingtao1.mp3', - 'audio/skill/twqingtao2.mp3', - 'audio/skill/twqiongji1.mp3', - 'audio/skill/twqiongji2.mp3', - 'audio/skill/twquanqian1.mp3', - 'audio/skill/twquanqian2.mp3', - 'audio/skill/twrenchou1.mp3', - 'audio/skill/twrenchou2.mp3', - 'audio/skill/twrouke1.mp3', - 'audio/skill/twrouke2.mp3', - 'audio/skill/twruilian1.mp3', - 'audio/skill/twruilian2.mp3', - 'audio/skill/twshanghe1.mp3', - 'audio/skill/twshanghe2.mp3', - 'audio/skill/twshenyi1.mp3', - 'audio/skill/twshenyi2.mp3', - 'audio/skill/twshepan1.mp3', - 'audio/skill/twshepan2.mp3', - 'audio/skill/twshexhong1.mp3', - 'audio/skill/twshexhong2.mp3', - 'audio/skill/twshezhong1.mp3', - 'audio/skill/twshezhong2.mp3', - 'audio/skill/twshigong1.mp3', - 'audio/skill/twshigong2.mp3', - 'audio/skill/twshoushou1.mp3', - 'audio/skill/twshoushou2.mp3', - 'audio/skill/twsidai1.mp3', - 'audio/skill/twsidai2.mp3', - 'audio/skill/twsidao1.mp3', - 'audio/skill/twsidao2.mp3', - 'audio/skill/twsuizheng1.mp3', - 'audio/skill/twsuizheng2.mp3', - 'audio/skill/twsuizheng3.mp3', - 'audio/skill/twtanfeng1.mp3', - 'audio/skill/twtanfeng2.mp3', - 'audio/skill/twtiaoxin1.mp3', - 'audio/skill/twtiaoxin2.mp3', - 'audio/skill/twtuidao1.mp3', - 'audio/skill/twtuidao2.mp3', - 'audio/skill/twwuhun1.mp3', - 'audio/skill/twwuhun2.mp3', - 'audio/skill/twxiafeng1.mp3', - 'audio/skill/twxiafeng2.mp3', - 'audio/skill/twxianfeng1.mp3', - 'audio/skill/twxianfeng2.mp3', - 'audio/skill/twxiawang1.mp3', - 'audio/skill/twxiawang2.mp3', - 'audio/skill/twxiawei1.mp3', - 'audio/skill/twxiawei2.mp3', - 'audio/skill/twxinghan1.mp3', - 'audio/skill/twxinghan2.mp3', - 'audio/skill/twxingzhui1.mp3', - 'audio/skill/twxingzhui2.mp3', - 'audio/skill/twxiongjun1.mp3', - 'audio/skill/twxiongjun2.mp3', - 'audio/skill/twxiongxi1.mp3', - 'audio/skill/twxiongxi2.mp3', - 'audio/skill/twxiongzheng1.mp3', - 'audio/skill/twxiongzheng2.mp3', - 'audio/skill/twxuechang1.mp3', - 'audio/skill/twxuechang2.mp3', - 'audio/skill/twyangming1.mp3', - 'audio/skill/twyangming2.mp3', - 'audio/skill/twyangshi1.mp3', - 'audio/skill/twyangshi2.mp3', - 'audio/skill/twyanshi1.mp3', - 'audio/skill/twyanshi2.mp3', - 'audio/skill/twyanshi3.mp3', - 'audio/skill/twyiju1.mp3', - 'audio/skill/twyiju2.mp3', - 'audio/skill/twyimou1.mp3', - 'audio/skill/twyimou2.mp3', - 'audio/skill/twyingji1.mp3', - 'audio/skill/twyingji2.mp3', - 'audio/skill/twyingjia1.mp3', - 'audio/skill/twyingjia2.mp3', - 'audio/skill/twyouye1.mp3', - 'audio/skill/twyouye2.mp3', - 'audio/skill/twyujue1.mp3', - 'audio/skill/twyujue2.mp3', - 'audio/skill/twyulong1.mp3', - 'audio/skill/twyulong2.mp3', - 'audio/skill/twzhangwu1.mp3', - 'audio/skill/twzhangwu2.mp3', - 'audio/skill/twzhengjian1.mp3', - 'audio/skill/twzhengjian2.mp3', - 'audio/skill/twzhenhu1.mp3', - 'audio/skill/twzhenhu2.mp3', - 'audio/skill/twzhenxi1.mp3', - 'audio/skill/twzhenxi2.mp3', - 'audio/skill/twzhian1.mp3', - 'audio/skill/twzhian2.mp3', - 'audio/skill/twzhiji1.mp3', - 'audio/skill/twzhiji2.mp3', - 'audio/skill/twzhiqu1.mp3', - 'audio/skill/twzhiqu2.mp3', - 'audio/skill/twzhongchi1.mp3', - 'audio/skill/twzhongchi2.mp3', - 'audio/skill/twzhuidu1.mp3', - 'audio/skill/twzhuidu2.mp3', - 'audio/skill/vtbguisha1.mp3', - 'audio/skill/vtbleyu1.mp3', - 'audio/skill/vtbmeiniang1.mp3', - 'audio/skill/vtbshanwu1.mp3', - 'audio/skill/vtbshuli1.mp3', - 'audio/skill/vtbtaoyan1.mp3', - 'audio/skill/vtbxianli1.mp3', - 'audio/skill/vtbyanli1.mp3', - 'audio/skill/vtbyaoli1.mp3', - 'audio/skill/vtbyuanli1.mp3', - 'audio/skill/waishi1.mp3', - 'audio/skill/waishi2.mp3', - 'audio/skill/wanggui1.mp3', - 'audio/skill/wanggui2.mp3', - 'audio/skill/wangjing1.mp3', - 'audio/skill/wangjing2.mp3', - 'audio/skill/wangong1.mp3', - 'audio/skill/wangong2.mp3', - 'audio/skill/wangxi1.mp3', - 'audio/skill/wangxi2.mp3', - 'audio/skill/wangzun1.mp3', - 'audio/skill/wangzun2.mp3', - 'audio/skill/wanlan1.mp3', - 'audio/skill/wanlan2.mp3', - 'audio/skill/wanrong1.mp3', - 'audio/skill/wanrong2.mp3', - 'audio/skill/wansha_boss_lvbu31.mp3', - 'audio/skill/wansha_boss_lvbu32.mp3', - 'audio/skill/wansha_re_jiaxu1.mp3', - 'audio/skill/wansha_re_jiaxu2.mp3', - 'audio/skill/wansha_shen_simayi1.mp3', - 'audio/skill/wansha_shen_simayi2.mp3', - 'audio/skill/wansha1.mp3', - 'audio/skill/wansha2.mp3', - 'audio/skill/wanwei1.mp3', - 'audio/skill/wanwei2.mp3', - 'audio/skill/wanyi1.mp3', - 'audio/skill/wanyi2.mp3', - 'audio/skill/weicheng1.mp3', - 'audio/skill/weicheng2.mp3', - 'audio/skill/weidi1.mp3', - 'audio/skill/weidi2.mp3', - 'audio/skill/weifeng1.mp3', - 'audio/skill/weifeng2.mp3', - 'audio/skill/weijing1.mp3', - 'audio/skill/weijing2.mp3', - 'audio/skill/weikui1.mp3', - 'audio/skill/weikui2.mp3', - 'audio/skill/weilie1.mp3', - 'audio/skill/weilie2.mp3', - 'audio/skill/weimeng1.mp3', - 'audio/skill/weimeng2.mp3', - 'audio/skill/weimu1.mp3', - 'audio/skill/weimu2.mp3', - 'audio/skill/weipo1.mp3', - 'audio/skill/weipo2.mp3', - 'audio/skill/weishu1.mp3', - 'audio/skill/weishu2.mp3', - 'audio/skill/weiyi1.mp3', - 'audio/skill/weiyi2.mp3', - 'audio/skill/weizhong1.mp3', - 'audio/skill/weizhong2.mp3', - 'audio/skill/wendao1.mp3', - 'audio/skill/wendao2.mp3', - 'audio/skill/wengua1.mp3', - 'audio/skill/wengua2.mp3', - 'audio/skill/wfyuyan1.mp3', - 'audio/skill/wfyuyan2.mp3', - 'audio/skill/wlcuorui1.mp3', - 'audio/skill/wlcuorui2.mp3', - 'audio/skill/wufei1.mp3', - 'audio/skill/wufei2.mp3', - 'audio/skill/wuhun21.mp3', - 'audio/skill/wuhun22.mp3', - 'audio/skill/wuji1.mp3', - 'audio/skill/wuji2.mp3', - 'audio/skill/wulie1.mp3', - 'audio/skill/wulie2.mp3', - 'audio/skill/wuling1.mp3', - 'audio/skill/wuling2.mp3', - 'audio/skill/wumou1.mp3', - 'audio/skill/wumou2.mp3', - 'audio/skill/wuniang1.mp3', - 'audio/skill/wuniang2.mp3', - 'audio/skill/wuqian1.mp3', - 'audio/skill/wuqian2.mp3', - 'audio/skill/wuqin1.mp3', - 'audio/skill/wuqin2.mp3', - 'audio/skill/wurong1.mp3', - 'audio/skill/wurong2.mp3', - 'audio/skill/wushen1.mp3', - 'audio/skill/wushen2.mp3', - 'audio/skill/wusheng_dc_jsp_guanyu1.mp3', - 'audio/skill/wusheng_dc_jsp_guanyu2.mp3', - 'audio/skill/wusheng_guansuo1.mp3', - 'audio/skill/wusheng_guansuo2.mp3', - 'audio/skill/wusheng_guanzhang1.mp3', - 'audio/skill/wusheng_guanzhang2.mp3', - 'audio/skill/wusheng_jsp_guanyu1.mp3', - 'audio/skill/wusheng_jsp_guanyu2.mp3', - 'audio/skill/wusheng_re_guanyu1.mp3', - 'audio/skill/wusheng_re_guanyu2.mp3', - 'audio/skill/wusheng_re_guanzhang1.mp3', - 'audio/skill/wusheng_re_guanzhang2.mp3', - 'audio/skill/wusheng1.mp3', - 'audio/skill/wusheng2.mp3', - 'audio/skill/wushuang_lvlingqi1.mp3', - 'audio/skill/wushuang_lvlingqi2.mp3', - 'audio/skill/wushuang_re_lvbu1.mp3', - 'audio/skill/wushuang_re_lvbu2.mp3', - 'audio/skill/wushuang_shen_lvbu1.mp3', - 'audio/skill/wushuang_shen_lvbu2.mp3', - 'audio/skill/wushuang_wechat_lvbu1.mp3', - 'audio/skill/wushuang_wechat_lvbu2.mp3', - 'audio/skill/wushuang1.mp3', - 'audio/skill/wushuang11.mp3', - 'audio/skill/wushuang12.mp3', - 'audio/skill/wushuang2.mp3', - 'audio/skill/wushuang21.mp3', - 'audio/skill/wushuang22.mp3', - 'audio/skill/wuxin1.mp3', - 'audio/skill/wuxin2.mp3', - 'audio/skill/wuyan1.mp3', - 'audio/skill/wuyan2.mp3', - 'audio/skill/wuyuan1.mp3', - 'audio/skill/wuyuan2.mp3', - 'audio/skill/wylianji1.mp3', - 'audio/skill/wylianji2.mp3', - 'audio/skill/xhzhiyan1.mp3', - 'audio/skill/xhzhiyan2.mp3', - 'audio/skill/xianfu1.mp3', - 'audio/skill/xianfu2.mp3', - 'audio/skill/xianfu3.mp3', - 'audio/skill/xianfu4.mp3', - 'audio/skill/xianfu5.mp3', - 'audio/skill/xianfu6.mp3', - 'audio/skill/xianghai1.mp3', - 'audio/skill/xianghai2.mp3', - 'audio/skill/xiangle_ol_liushan1.mp3', - 'audio/skill/xiangle_ol_liushan2.mp3', - 'audio/skill/xiangle_re_liushan1.mp3', - 'audio/skill/xiangle_re_liushan2.mp3', - 'audio/skill/xiangle1.mp3', - 'audio/skill/xiangle2.mp3', - 'audio/skill/xiangshu1.mp3', - 'audio/skill/xiangshu2.mp3', - 'audio/skill/xianjing1.mp3', - 'audio/skill/xianjing2.mp3', - 'audio/skill/xianshuai1.mp3', - 'audio/skill/xianshuai2.mp3', - 'audio/skill/xiansi_re_liufeng1.mp3', - 'audio/skill/xiansi_re_liufeng2.mp3', - 'audio/skill/xiansi1.mp3', - 'audio/skill/xiansi2.mp3', - 'audio/skill/xiansi21.mp3', - 'audio/skill/xiansi22.mp3', - 'audio/skill/xiantu1.mp3', - 'audio/skill/xiantu2.mp3', - 'audio/skill/xianwan1.mp3', - 'audio/skill/xianwan2.mp3', - 'audio/skill/xianwang1.mp3', - 'audio/skill/xianwang2.mp3', - 'audio/skill/xianwei1.mp3', - 'audio/skill/xianwei2.mp3', - 'audio/skill/xianzhen1.mp3', - 'audio/skill/xianzhen2.mp3', - 'audio/skill/xianzhou_xin_caifuren1.mp3', - 'audio/skill/xianzhou_xin_caifuren2.mp3', - 'audio/skill/xianzhou1.mp3', - 'audio/skill/xianzhou2.mp3', - 'audio/skill/xianzhu1.mp3', - 'audio/skill/xianzhu2.mp3', - 'audio/skill/xiaoguo1.mp3', - 'audio/skill/xiaoguo2.mp3', - 'audio/skill/xiaoji_re_sunshangxiang1.mp3', - 'audio/skill/xiaoji_re_sunshangxiang2.mp3', - 'audio/skill/xiaoji_sp_sunshangxiang1.mp3', - 'audio/skill/xiaoji_sp_sunshangxiang2.mp3', - 'audio/skill/xiaoji1.mp3', - 'audio/skill/xiaoji2.mp3', - 'audio/skill/xiaoni1.mp3', - 'audio/skill/xiaoni2.mp3', - 'audio/skill/xiaowu1.mp3', - 'audio/skill/xiaowu2.mp3', - 'audio/skill/xiaoxi_hansui1.mp3', - 'audio/skill/xiaoxi_hansui2.mp3', - 'audio/skill/xiaoxi_machao1.mp3', - 'audio/skill/xiaoxi_machao2.mp3', - 'audio/skill/xiaoxi_pangde1.mp3', - 'audio/skill/xiaoxi_pangde2.mp3', - 'audio/skill/xiashu1.mp3', - 'audio/skill/xiashu2.mp3', - 'audio/skill/xibing1.mp3', - 'audio/skill/xibing2.mp3', - 'audio/skill/xiechan1.mp3', - 'audio/skill/xiechan2.mp3', - 'audio/skill/xiecui1.mp3', - 'audio/skill/xiecui2.mp3', - 'audio/skill/xiemu1.mp3', - 'audio/skill/xiemu2.mp3', - 'audio/skill/xijue_tuxi1.mp3', - 'audio/skill/xijue_tuxi2.mp3', - 'audio/skill/xijue_xiaoguo1.mp3', - 'audio/skill/xijue_xiaoguo2.mp3', - 'audio/skill/xijue1.mp3', - 'audio/skill/xijue2.mp3', - 'audio/skill/xinanjian1.mp3', - 'audio/skill/xinanjian2.mp3', - 'audio/skill/xinbenxi1.mp3', - 'audio/skill/xinbenxi2.mp3', - 'audio/skill/xinbuyi1.mp3', - 'audio/skill/xinbuyi2.mp3', - 'audio/skill/xindanshou1.mp3', - 'audio/skill/xindanshou2.mp3', - 'audio/skill/xinduodao1.mp3', - 'audio/skill/xinduodao2.mp3', - 'audio/skill/xinenyuan1.mp3', - 'audio/skill/xinenyuan2.mp3', - 'audio/skill/xinfencheng_re_liru1.mp3', - 'audio/skill/xinfencheng_re_liru2.mp3', - 'audio/skill/xinfencheng1.mp3', - 'audio/skill/xinfencheng2.mp3', - 'audio/skill/xinfu_andong1.mp3', - 'audio/skill/xinfu_andong2.mp3', - 'audio/skill/xinfu_bijing1.mp3', - 'audio/skill/xinfu_bijing2.mp3', - 'audio/skill/xinfu_chenghao1.mp3', - 'audio/skill/xinfu_chenghao2.mp3', - 'audio/skill/xinfu_daigong1.mp3', - 'audio/skill/xinfu_daigong2.mp3', - 'audio/skill/xinfu_denglou1.mp3', - 'audio/skill/xinfu_denglou2.mp3', - 'audio/skill/xinfu_dianhu1.mp3', - 'audio/skill/xinfu_dianhu2.mp3', - 'audio/skill/xinfu_dianhua1.mp3', - 'audio/skill/xinfu_dianhua2.mp3', - 'audio/skill/xinfu_duanfa1.mp3', - 'audio/skill/xinfu_duanfa2.mp3', - 'audio/skill/xinfu_falu1.mp3', - 'audio/skill/xinfu_falu2.mp3', - 'audio/skill/xinfu_fangtong1.mp3', - 'audio/skill/xinfu_fangtong2.mp3', - 'audio/skill/xinfu_fuhai1.mp3', - 'audio/skill/xinfu_fuhai2.mp3', - 'audio/skill/xinfu_fujian1.mp3', - 'audio/skill/xinfu_fujian2.mp3', - 'audio/skill/xinfu_fuyin1.mp3', - 'audio/skill/xinfu_fuyin2.mp3', - 'audio/skill/xinfu_gongqing_gz_panjun1.mp3', - 'audio/skill/xinfu_gongqing_gz_panjun2.mp3', - 'audio/skill/xinfu_gongqing1.mp3', - 'audio/skill/xinfu_gongqing2.mp3', - 'audio/skill/xinfu_guanchao1.mp3', - 'audio/skill/xinfu_guanchao2.mp3', - 'audio/skill/xinfu_guanwei1.mp3', - 'audio/skill/xinfu_guanwei2.mp3', - 'audio/skill/xinfu_guhuo2.mp3', - 'audio/skill/xinfu_guolun1.mp3', - 'audio/skill/xinfu_guolun2.mp3', - 'audio/skill/xinfu_jianji1.mp3', - 'audio/skill/xinfu_jianji2.mp3', - 'audio/skill/xinfu_jianjie1.mp3', - 'audio/skill/xinfu_jianjie2.mp3', - 'audio/skill/xinfu_jianjie3.mp3', - 'audio/skill/xinfu_jijie1.mp3', - 'audio/skill/xinfu_jijie2.mp3', - 'audio/skill/xinfu_jijun1.mp3', - 'audio/skill/xinfu_jijun2.mp3', - 'audio/skill/xinfu_jingxie1.mp3', - 'audio/skill/xinfu_jingxie2.mp3', - 'audio/skill/xinfu_jixu1.mp3', - 'audio/skill/xinfu_jixu2.mp3', - 'audio/skill/xinfu_jiyuan1.mp3', - 'audio/skill/xinfu_jiyuan2.mp3', - 'audio/skill/xinfu_kannan1.mp3', - 'audio/skill/xinfu_kannan2.mp3', - 'audio/skill/xinfu_langxi1.mp3', - 'audio/skill/xinfu_langxi2.mp3', - 'audio/skill/xinfu_lianpian1.mp3', - 'audio/skill/xinfu_lianpian2.mp3', - 'audio/skill/xinfu_limu1.mp3', - 'audio/skill/xinfu_limu2.mp3', - 'audio/skill/xinfu_lingren1.mp3', - 'audio/skill/xinfu_lingren2.mp3', - 'audio/skill/xinfu_longyuan1.mp3', - 'audio/skill/xinfu_longyuan2.mp3', - 'audio/skill/xinfu_lveming1.mp3', - 'audio/skill/xinfu_lveming2.mp3', - 'audio/skill/xinfu_pingcai.mp3', - 'audio/skill/xinfu_qiai1.mp3', - 'audio/skill/xinfu_qiai2.mp3', - 'audio/skill/xinfu_qianchong1.mp3', - 'audio/skill/xinfu_qianchong2.mp3', - 'audio/skill/xinfu_qianchong3.mp3', - 'audio/skill/xinfu_qianxin1.mp3', - 'audio/skill/xinfu_qianxin2.mp3', - 'audio/skill/xinfu_qiaosi1.mp3', - 'audio/skill/xinfu_qiaosi2.mp3', - 'audio/skill/xinfu_sanwen1.mp3', - 'audio/skill/xinfu_sanwen2.mp3', - 'audio/skill/xinfu_shajue1.mp3', - 'audio/skill/xinfu_shajue2.mp3', - 'audio/skill/xinfu_shangjian1.mp3', - 'audio/skill/xinfu_shangjian2.mp3', - 'audio/skill/xinfu_sidao1.mp3', - 'audio/skill/xinfu_sidao2.mp3', - 'audio/skill/xinfu_songsang1.mp3', - 'audio/skill/xinfu_songsang2.mp3', - 'audio/skill/xinfu_tanbei1.mp3', - 'audio/skill/xinfu_tanbei2.mp3', - 'audio/skill/xinfu_tunan1.mp3', - 'audio/skill/xinfu_tunan2.mp3', - 'audio/skill/xinfu_tunjun1.mp3', - 'audio/skill/xinfu_tunjun2.mp3', - 'audio/skill/xinfu_tushe1.mp3', - 'audio/skill/xinfu_tushe2.mp3', - 'audio/skill/xinfu_weilu1.mp3', - 'audio/skill/xinfu_weilu2.mp3', - 'audio/skill/xinfu_wuniang1.mp3', - 'audio/skill/xinfu_wuniang2.mp3', - 'audio/skill/xinfu_xingluan1.mp3', - 'audio/skill/xinfu_xingluan2.mp3', - 'audio/skill/xinfu_xingzhao.mp3', - 'audio/skill/xinfu_xingzhao2.mp3', - 'audio/skill/xinfu_xionghuo1.mp3', - 'audio/skill/xinfu_xionghuo2.mp3', - 'audio/skill/xinfu_xunxian1.mp3', - 'audio/skill/xinfu_xunxian2.mp3', - 'audio/skill/xinfu_xushen1.mp3', - 'audio/skill/xinfu_xushen2.mp3', - 'audio/skill/xinfu_yingshi1.mp3', - 'audio/skill/xinfu_yingshi2.mp3', - 'audio/skill/xinfu_yinshi1.mp3', - 'audio/skill/xinfu_yinshi2.mp3', - 'audio/skill/xinfu_yisuan1.mp3', - 'audio/skill/xinfu_yisuan2.mp3', - 'audio/skill/xinfu_youdi1.mp3', - 'audio/skill/xinfu_youdi2.mp3', - 'audio/skill/xinfu_zengdao1.mp3', - 'audio/skill/xinfu_zengdao2.mp3', - 'audio/skill/xinfu_zhanji1.mp3', - 'audio/skill/xinfu_zhanji2.mp3', - 'audio/skill/xinfu_zhaoxin1.mp3', - 'audio/skill/xinfu_zhaoxin2.mp3', - 'audio/skill/xinfu_zhennan1.mp3', - 'audio/skill/xinfu_zhennan2.mp3', - 'audio/skill/xinfu_zhenxing1.mp3', - 'audio/skill/xinfu_zhenxing2.mp3', - 'audio/skill/xinfu_zhenyi1.mp3', - 'audio/skill/xinfu_zhenyi2.mp3', - 'audio/skill/xinfu_zuilun1.mp3', - 'audio/skill/xinfu_zuilun2.mp3', - 'audio/skill/xinfuli1.mp3', - 'audio/skill/xinfuli2.mp3', - 'audio/skill/xinganlu1.mp3', - 'audio/skill/xinganlu2.mp3', - 'audio/skill/xingbu1.mp3', - 'audio/skill/xingbu2.mp3', - 'audio/skill/xingchong1.mp3', - 'audio/skill/xingchong2.mp3', - 'audio/skill/xinghan1.mp3', - 'audio/skill/xinghan2.mp3', - 'audio/skill/xingongji1.mp3', - 'audio/skill/xingongji2.mp3', - 'audio/skill/xingqi1.mp3', - 'audio/skill/xingqi2.mp3', - 'audio/skill/xingshang1.mp3', - 'audio/skill/xingshang2.mp3', - 'audio/skill/xingshen1.mp3', - 'audio/skill/xingshen2.mp3', - 'audio/skill/xingshuai1.mp3', - 'audio/skill/xingshuai2.mp3', - 'audio/skill/xingtu1.mp3', - 'audio/skill/xingtu2.mp3', - 'audio/skill/xinguidao1.mp3', - 'audio/skill/xinguidao2.mp3', - 'audio/skill/xinguixiu1.mp3', - 'audio/skill/xinguixiu2.mp3', - 'audio/skill/xingwu1.mp3', - 'audio/skill/xingwu2.mp3', - 'audio/skill/xingxue1.mp3', - 'audio/skill/xingxue2.mp3', - 'audio/skill/xingzuo1.mp3', - 'audio/skill/xingzuo2.mp3', - 'audio/skill/xinhuangtian2_re_zhangjiao1.mp3', - 'audio/skill/xinhuangtian2_re_zhangjiao2.mp3', - 'audio/skill/xinjiangchi1.mp3', - 'audio/skill/xinjiangchi2.mp3', - 'audio/skill/xinjianying1.mp3', - 'audio/skill/xinjianying2.mp3', - 'audio/skill/xinjiaojin1.mp3', - 'audio/skill/xinjiaojin2.mp3', - 'audio/skill/xinjiefan1.mp3', - 'audio/skill/xinjiefan2.mp3', - 'audio/skill/xinjiewei1.mp3', - 'audio/skill/xinjiewei2.mp3', - 'audio/skill/xinjingce1.mp3', - 'audio/skill/xinjingce2.mp3', - 'audio/skill/xinjuece1.mp3', - 'audio/skill/xinjuece2.mp3', - 'audio/skill/xinjuejing1.mp3', - 'audio/skill/xinjuejing2.mp3', - 'audio/skill/xinjujian1.mp3', - 'audio/skill/xinjujian2.mp3', - 'audio/skill/xinjushou1.mp3', - 'audio/skill/xinjushou2.mp3', - 'audio/skill/xinjyzongshi1.mp3', - 'audio/skill/xinjyzongshi2.mp3', - 'audio/skill/xinkuangfu1.mp3', - 'audio/skill/xinkuangfu2.mp3', - 'audio/skill/xinleiji1.mp3', - 'audio/skill/xinleiji2.mp3', - 'audio/skill/xinlianhuan_ol_pangtong1.mp3', - 'audio/skill/xinlianhuan_ol_pangtong2.mp3', - 'audio/skill/xinlianhuan1.mp3', - 'audio/skill/xinlianhuan2.mp3', - 'audio/skill/xinmieji1.mp3', - 'audio/skill/xinmieji2.mp3', - 'audio/skill/xinniluan1.mp3', - 'audio/skill/xinniluan2.mp3', - 'audio/skill/xinpaiyi1.mp3', - 'audio/skill/xinpaiyi2.mp3', - 'audio/skill/xinpingkou1.mp3', - 'audio/skill/xinpingkou2.mp3', - 'audio/skill/xinpojun1.mp3', - 'audio/skill/xinpojun2.mp3', - 'audio/skill/xinqiaoshui1.mp3', - 'audio/skill/xinqiaoshui2.mp3', - 'audio/skill/xinqieting1.mp3', - 'audio/skill/xinqieting2.mp3', - 'audio/skill/xinqingxi1.mp3', - 'audio/skill/xinqingxi2.mp3', - 'audio/skill/xinqiuyuan1.mp3', - 'audio/skill/xinqiuyuan2.mp3', - 'audio/skill/xinquanji1.mp3', - 'audio/skill/xinquanji2.mp3', - 'audio/skill/xinrende1.mp3', - 'audio/skill/xinrende2.mp3', - 'audio/skill/xinsheng1.mp3', - 'audio/skill/xinsheng2.mp3', - 'audio/skill/xinshenxing1.mp3', - 'audio/skill/xinshenxing2.mp3', - 'audio/skill/xintan1.mp3', - 'audio/skill/xintan2.mp3', - 'audio/skill/xinwurong1.mp3', - 'audio/skill/xinwurong2.mp3', - 'audio/skill/xinwurong3.mp3', - 'audio/skill/xinwusheng1.mp3', - 'audio/skill/xinwusheng2.mp3', - 'audio/skill/xinwuyan1.mp3', - 'audio/skill/xinwuyan2.mp3', - 'audio/skill/xinxuanhuo1.mp3', - 'audio/skill/xinxuanhuo2.mp3', - 'audio/skill/xinyaoming1.mp3', - 'audio/skill/xinyaoming2.mp3', - 'audio/skill/xinzenhui1.mp3', - 'audio/skill/xinzenhui2.mp3', - 'audio/skill/xinzhan1.mp3', - 'audio/skill/xinzhan2.mp3', - 'audio/skill/xinzhenjun1.mp3', - 'audio/skill/xinzhenjun2.mp3', - 'audio/skill/xinzhiyan1.mp3', - 'audio/skill/xinzhiyan2.mp3', - 'audio/skill/xinzhuikong1.mp3', - 'audio/skill/xinzhuikong2.mp3', - 'audio/skill/xinzili1.mp3', - 'audio/skill/xinzili2.mp3', - 'audio/skill/xinzongxuan1.mp3', - 'audio/skill/xinzongxuan2.mp3', - 'audio/skill/xiongmang1.mp3', - 'audio/skill/xiongmang2.mp3', - 'audio/skill/xiongrao1.mp3', - 'audio/skill/xiongrao2.mp3', - 'audio/skill/xiongshu1.mp3', - 'audio/skill/xiongshu2.mp3', - 'audio/skill/xiongsuan1.mp3', - 'audio/skill/xiongsuan2.mp3', - 'audio/skill/xiongyi1.mp3', - 'audio/skill/xiongyi2.mp3', - 'audio/skill/xiongzhi1.mp3', - 'audio/skill/xiongzhi2.mp3', - 'audio/skill/xiuluo1.mp3', - 'audio/skill/xiuluo2.mp3', - 'audio/skill/xiusheng1.mp3', - 'audio/skill/xiusheng2.mp3', - 'audio/skill/xixiu1.mp3', - 'audio/skill/xixiu2.mp3', - 'audio/skill/xiyan1.mp3', - 'audio/skill/xiyan2.mp3', - 'audio/skill/xiying1.mp3', - 'audio/skill/xiying2.mp3', - 'audio/skill/xizhen1.mp3', - 'audio/skill/xizhen2.mp3', - 'audio/skill/xjshijian1.mp3', - 'audio/skill/xjshijian2.mp3', - 'audio/skill/xpchijie1.mp3', - 'audio/skill/xpchijie2.mp3', - 'audio/skill/xsqianxin1.mp3', - 'audio/skill/xsqianxin2.mp3', - 'audio/skill/xuanbei1.mp3', - 'audio/skill/xuanbei2.mp3', - 'audio/skill/xuancun1.mp3', - 'audio/skill/xuancun2.mp3', - 'audio/skill/xuanfeng_boss_lvbu31.mp3', - 'audio/skill/xuanfeng_boss_lvbu32.mp3', - 'audio/skill/xuanfeng_re_heqi1.mp3', - 'audio/skill/xuanfeng_re_heqi2.mp3', - 'audio/skill/xuanfeng_re_lingtong1.mp3', - 'audio/skill/xuanfeng_re_lingtong2.mp3', - 'audio/skill/xuanfeng_xin_lingtong1.mp3', - 'audio/skill/xuanfeng_xin_lingtong2.mp3', - 'audio/skill/xuanfeng1.mp3', - 'audio/skill/xuanfeng2.mp3', - 'audio/skill/xuanhuo1.mp3', - 'audio/skill/xuanhuo2.mp3', - 'audio/skill/xuanlve1.mp3', - 'audio/skill/xuanlve2.mp3', - 'audio/skill/xuanmu1.mp3', - 'audio/skill/xuanmu2.mp3', - 'audio/skill/xueji1.mp3', - 'audio/skill/xueji2.mp3', - 'audio/skill/xuelunyang.mp3', - 'audio/skill/xuewei1.mp3', - 'audio/skill/xuewei2.mp3', - 'audio/skill/xueyi1.mp3', - 'audio/skill/xueyi2.mp3', - 'audio/skill/xuezhao1.mp3', - 'audio/skill/xuezhao2.mp3', - 'audio/skill/xunde1.mp3', - 'audio/skill/xunde2.mp3', - 'audio/skill/xunli1.mp3', - 'audio/skill/xunli2.mp3', - 'audio/skill/xunshi1.mp3', - 'audio/skill/xunshi2.mp3', - 'audio/skill/xunxun1.mp3', - 'audio/skill/xunxun2.mp3', - 'audio/skill/xunyi1.mp3', - 'audio/skill/xunyi2.mp3', - 'audio/skill/xunzhi1.mp3', - 'audio/skill/xunzhi2.mp3', - 'audio/skill/xushen1.mp3', - 'audio/skill/xushen2.mp3', - 'audio/skill/xutuhuanjin.mp3', - 'audio/skill/xuxie1.mp3', - 'audio/skill/xuxie2.mp3', - 'audio/skill/xz_xunxun1.mp3', - 'audio/skill/xz_xunxun2.mp3', - 'audio/skill/yachai1.mp3', - 'audio/skill/yachai2.mp3', - 'audio/skill/yaner1.mp3', - 'audio/skill/yaner2.mp3', - 'audio/skill/yangjie1.mp3', - 'audio/skill/yangjie2.mp3', - 'audio/skill/yangkuang1.mp3', - 'audio/skill/yangkuang2.mp3', - 'audio/skill/yangzhong1.mp3', - 'audio/skill/yangzhong2.mp3', - 'audio/skill/yanhuo1.mp3', - 'audio/skill/yanhuo2.mp3', - 'audio/skill/yanjiao1.mp3', - 'audio/skill/yanjiao2.mp3', - 'audio/skill/yanru1.mp3', - 'audio/skill/yanru2.mp3', - 'audio/skill/yanxi1.mp3', - 'audio/skill/yanxi2.mp3', - 'audio/skill/yanxiao1.mp3', - 'audio/skill/yanxiao2.mp3', - 'audio/skill/yanyu1.mp3', - 'audio/skill/yanyu2.mp3', - 'audio/skill/yanzheng1.mp3', - 'audio/skill/yanzheng2.mp3', - 'audio/skill/yanzhu1.mp3', - 'audio/skill/yanzhu2.mp3', - 'audio/skill/yaoming1.mp3', - 'audio/skill/yaoming2.mp3', - 'audio/skill/yaopei1.mp3', - 'audio/skill/yaopei2.mp3', - 'audio/skill/yaowu1.mp3', - 'audio/skill/yaowu2.mp3', - 'audio/skill/yashi1.mp3', - 'audio/skill/yashi2.mp3', - 'audio/skill/yawang1.mp3', - 'audio/skill/yawang2.mp3', - 'audio/skill/ybzhuiji1.mp3', - 'audio/skill/ybzhuiji2.mp3', - 'audio/skill/yechou1.mp3', - 'audio/skill/yechou2.mp3', - 'audio/skill/yeyan1.mp3', - 'audio/skill/yeyan2.mp3', - 'audio/skill/yeyan3.mp3', - 'audio/skill/yicheng1.mp3', - 'audio/skill/yicheng2.mp3', - 'audio/skill/yichong1.mp3', - 'audio/skill/yichong2.mp3', - 'audio/skill/yicong1.mp3', - 'audio/skill/yicong2.mp3', - 'audio/skill/yidian1.mp3', - 'audio/skill/yidian2.mp3', - 'audio/skill/yidu1.mp3', - 'audio/skill/yidu2.mp3', - 'audio/skill/yifa1.mp3', - 'audio/skill/yifa2.mp3', - 'audio/skill/yigui1.mp3', - 'audio/skill/yigui2.mp3', - 'audio/skill/yiji1.mp3', - 'audio/skill/yiji2.mp3', - 'audio/skill/yijiao1.mp3', - 'audio/skill/yijiao2.mp3', - 'audio/skill/yijie1.mp3', - 'audio/skill/yijie2.mp3', - 'audio/skill/yijin1.mp3', - 'audio/skill/yijin2.mp3', - 'audio/skill/yijin3.mp3', - 'audio/skill/yijue1.mp3', - 'audio/skill/yijue2.mp3', - 'audio/skill/yilie1.mp3', - 'audio/skill/yilie2.mp3', - 'audio/skill/yimie1.mp3', - 'audio/skill/yimie2.mp3', - 'audio/skill/yinbing1.mp3', - 'audio/skill/yinbing2.mp3', - 'audio/skill/yingba1.mp3', - 'audio/skill/yingba2.mp3', - 'audio/skill/yingbin1.mp3', - 'audio/skill/yingbin2.mp3', - 'audio/skill/yingbing1.mp3', - 'audio/skill/yingbing2.mp3', - 'audio/skill/yingfeng1.mp3', - 'audio/skill/yingfeng2.mp3', - 'audio/skill/yinghun_ol_sunjian1.mp3', - 'audio/skill/yinghun_ol_sunjian2.mp3', - 'audio/skill/yinghun_re_sunben1.mp3', - 'audio/skill/yinghun_re_sunben2.mp3', - 'audio/skill/yinghun_re_sunce1.mp3', - 'audio/skill/yinghun_re_sunce2.mp3', - 'audio/skill/yinghun_re_sunjian1.mp3', - 'audio/skill/yinghun_re_sunjian2.mp3', - 'audio/skill/yinghun_sb_sunce1.mp3', - 'audio/skill/yinghun_sb_sunce2.mp3', - 'audio/skill/yinghun_sunce1.mp3', - 'audio/skill/yinghun_sunce2.mp3', - 'audio/skill/yinghun_sunjian1.mp3', - 'audio/skill/yinghun_sunjian2.mp3', - 'audio/skill/yinghun1.mp3', - 'audio/skill/yinghun2.mp3', - 'audio/skill/yingyang1.mp3', - 'audio/skill/yingyang2.mp3', - 'audio/skill/yingyuan1.mp3', - 'audio/skill/yingyuan2.mp3', - 'audio/skill/yingzi1.mp3', - 'audio/skill/yingzi2.mp3', - 'audio/skill/yinju1.mp3', - 'audio/skill/yinju2.mp3', - 'audio/skill/yinlang1.mp3', - 'audio/skill/yinlang2.mp3', - 'audio/skill/yinli1.mp3', - 'audio/skill/yinli2.mp3', - 'audio/skill/yinyi1.mp3', - 'audio/skill/yinyi2.mp3', - 'audio/skill/yirang_re_taoqian1.mp3', - 'audio/skill/yirang_re_taoqian2.mp3', - 'audio/skill/yirang1.mp3', - 'audio/skill/yirang2.mp3', - 'audio/skill/yise1.mp3', - 'audio/skill/yise2.mp3', - 'audio/skill/yishe1.mp3', - 'audio/skill/yishe2.mp3', - 'audio/skill/yitian.mp3', - 'audio/skill/yixiang_re_taoqian1.mp3', - 'audio/skill/yixiang_re_taoqian2.mp3', - 'audio/skill/yixiang1.mp3', - 'audio/skill/yixiang2.mp3', - 'audio/skill/yiyong1.mp3', - 'audio/skill/yiyong2.mp3', - 'audio/skill/yizan_respond_shan1.mp3', - 'audio/skill/yizan_respond_shan2.mp3', - 'audio/skill/yizhao1.mp3', - 'audio/skill/yizhao2.mp3', - 'audio/skill/yizheng1.mp3', - 'audio/skill/yizheng2.mp3', - 'audio/skill/yizhi1.mp3', - 'audio/skill/yizhi2.mp3', - 'audio/skill/yizhong1.mp3', - 'audio/skill/yizhong2.mp3', - 'audio/skill/yizhu1.mp3', - 'audio/skill/yizhu2.mp3', - 'audio/skill/yizu1.mp3', - 'audio/skill/yizu2.mp3', - 'audio/skill/yongdi_xinping1.mp3', - 'audio/skill/yongdi_xinping2.mp3', - 'audio/skill/yongdi1.mp3', - 'audio/skill/yongdi2.mp3', - 'audio/skill/yongjin_xin_lingtong1.mp3', - 'audio/skill/yongjin_xin_lingtong2.mp3', - 'audio/skill/yongjin1.mp3', - 'audio/skill/yongjin2.mp3', - 'audio/skill/yongjue1.mp3', - 'audio/skill/yongjue2.mp3', - 'audio/skill/yonglve1.mp3', - 'audio/skill/yonglve2.mp3', - 'audio/skill/yongsi1.mp3', - 'audio/skill/yongsi2.mp3', - 'audio/skill/youdi1.mp3', - 'audio/skill/youdi2.mp3', - 'audio/skill/youlong1.mp3', - 'audio/skill/youlong2.mp3', - 'audio/skill/youxu1.mp3', - 'audio/skill/youxu2.mp3', - 'audio/skill/youyan1.mp3', - 'audio/skill/youyan2.mp3', - 'audio/skill/youyi1.mp3', - 'audio/skill/youyi2.mp3', - 'audio/skill/yuanchou1.mp3', - 'audio/skill/yuanchou2.mp3', - 'audio/skill/yuanhu1.mp3', - 'audio/skill/yuanhu2.mp3', - 'audio/skill/yuanhu3.mp3', - 'audio/skill/yuanlve1.mp3', - 'audio/skill/yuanlve2.mp3', - 'audio/skill/yuanqing1.mp3', - 'audio/skill/yuanqing2.mp3', - 'audio/skill/yuanyu1.mp3', - 'audio/skill/yuanyu2.mp3', - 'audio/skill/yuanzi1.mp3', - 'audio/skill/yuanzi2.mp3', - 'audio/skill/yuce_re_manchong1.mp3', - 'audio/skill/yuce_re_manchong2.mp3', - 'audio/skill/yuce1.mp3', - 'audio/skill/yuce2.mp3', - 'audio/skill/yuehun1.mp3', - 'audio/skill/yuehun2.mp3', - 'audio/skill/yuejian1.mp3', - 'audio/skill/yuejian2.mp3', - 'audio/skill/yufeng1.mp3', - 'audio/skill/yufeng2.mp3', - 'audio/skill/yuheng1.mp3', - 'audio/skill/yuheng2.mp3', - 'audio/skill/yuhua1.mp3', - 'audio/skill/yuhua2.mp3', - 'audio/skill/yui_jiang1.mp3', - 'audio/skill/yui_jiang2.mp3', - 'audio/skill/yui_lieyin1.mp3', - 'audio/skill/yui_lieyin2.mp3', - 'audio/skill/yui_takaramono1.mp3', - 'audio/skill/yui_takaramono2.mp3', - 'audio/skill/yujue1.mp3', - 'audio/skill/yujue2.mp3', - 'audio/skill/yuqi1.mp3', - 'audio/skill/yuqi2.mp3', - 'audio/skill/yuri_wangxi1.mp3', - 'audio/skill/yuri_wangxi2.mp3', - 'audio/skill/yuri_xingdong_gain1.mp3', - 'audio/skill/yuri_xingdong_gain2.mp3', - 'audio/skill/yuri_xingdong1.mp3', - 'audio/skill/yuri_xingdong2.mp3', - 'audio/skill/yuri_xingdong3.mp3', - 'audio/skill/yusui1.mp3', - 'audio/skill/yusui2.mp3', - 'audio/skill/yuxiang.mp3', - 'audio/skill/yuxu1.mp3', - 'audio/skill/yuxu2.mp3', - 'audio/skill/yuyan1.mp3', - 'audio/skill/yuyan2.mp3', - 'audio/skill/yuyun1.mp3', - 'audio/skill/yuyun2.mp3', - 'audio/skill/yuzhang1.mp3', - 'audio/skill/yuzhang2.mp3', - 'audio/skill/zaiqi1.mp3', - 'audio/skill/zaiqi2.mp3', - 'audio/skill/zaoli1.mp3', - 'audio/skill/zaoli2.mp3', - 'audio/skill/zaoxian_re_dengai1.mp3', - 'audio/skill/zaoxian_re_dengai2.mp3', - 'audio/skill/zaoxian1.mp3', - 'audio/skill/zaoxian2.mp3', - 'audio/skill/zaoyun1.mp3', - 'audio/skill/zaoyun2.mp3', - 'audio/skill/zengou1.mp3', - 'audio/skill/zengou2.mp3', - 'audio/skill/zfengshi1.mp3', - 'audio/skill/zfengshi2.mp3', - 'audio/skill/zhafu1.mp3', - 'audio/skill/zhafu2.mp3', - 'audio/skill/zhangba_skill.mp3', - 'audio/skill/zhangming1.mp3', - 'audio/skill/zhangming2.mp3', - 'audio/skill/zhangu1.mp3', - 'audio/skill/zhangu2.mp3', - 'audio/skill/zhangwu1.mp3', - 'audio/skill/zhangwu2.mp3', - 'audio/skill/zhanjue1.mp3', - 'audio/skill/zhanjue2.mp3', - 'audio/skill/zhanshen1.mp3', - 'audio/skill/zhanshen2.mp3', - 'audio/skill/zhanwan1.mp3', - 'audio/skill/zhanwan2.mp3', - 'audio/skill/zhanyanliangzhuwenchou.mp3', - 'audio/skill/zhanyi1.mp3', - 'audio/skill/zhanyi2.mp3', - 'audio/skill/zhanyuan1.mp3', - 'audio/skill/zhanyuan2.mp3', - 'audio/skill/zhaofu1.mp3', - 'audio/skill/zhaofu2.mp3', - 'audio/skill/zhaohan1.mp3', - 'audio/skill/zhaohan2.mp3', - 'audio/skill/zhaohuo_re_taoqian1.mp3', - 'audio/skill/zhaohuo_re_taoqian2.mp3', - 'audio/skill/zhaohuo1.mp3', - 'audio/skill/zhaohuo2.mp3', - 'audio/skill/zhaolie1.mp3', - 'audio/skill/zhaolie2.mp3', - 'audio/skill/zhaoran1.mp3', - 'audio/skill/zhaoran2.mp3', - 'audio/skill/zhaosong1.mp3', - 'audio/skill/zhaosong2.mp3', - 'audio/skill/zhaotao1.mp3', - 'audio/skill/zhaotao2.mp3', - 'audio/skill/zhaxiang1.mp3', - 'audio/skill/zhaxiang2.mp3', - 'audio/skill/zhefu1.mp3', - 'audio/skill/zhefu2.mp3', - 'audio/skill/zhendu1.mp3', - 'audio/skill/zhendu2.mp3', - 'audio/skill/zhengbi1.mp3', - 'audio/skill/zhengbi2.mp3', - 'audio/skill/zhengding1.mp3', - 'audio/skill/zhengding2.mp3', - 'audio/skill/zhenge1.mp3', - 'audio/skill/zhenge2.mp3', - 'audio/skill/zhengjian1.mp3', - 'audio/skill/zhengjian2.mp3', - 'audio/skill/zhengjing_boom.mp3', - 'audio/skill/zhengjing_click.mp3', - 'audio/skill/zhengjing_finish.mp3', - 'audio/skill/zhengjing_guanju.mp3', - 'audio/skill/zhengjing1.mp3', - 'audio/skill/zhengjing2.mp3', - 'audio/skill/zhengnan1.mp3', - 'audio/skill/zhengnan2.mp3', - 'audio/skill/zhengqing1.mp3', - 'audio/skill/zhengqing2.mp3', - 'audio/skill/zhenlie_re_wangyi1.mp3', - 'audio/skill/zhenlie_re_wangyi2.mp3', - 'audio/skill/zhenlie1.mp3', - 'audio/skill/zhenlie2.mp3', - 'audio/skill/zhenshan1.mp3', - 'audio/skill/zhenshan2.mp3', - 'audio/skill/zhente1.mp3', - 'audio/skill/zhente2.mp3', - 'audio/skill/zhenwei_re_wenpin1.mp3', - 'audio/skill/zhenwei_re_wenpin2.mp3', - 'audio/skill/zhenwei1.mp3', - 'audio/skill/zhenwei2.mp3', - 'audio/skill/zhiba2_re_sunben1.mp3', - 'audio/skill/zhiba2_re_sunben2.mp3', - 'audio/skill/zhiba21.mp3', - 'audio/skill/zhiba22.mp3', - 'audio/skill/zhibian1.mp3', - 'audio/skill/zhibian2.mp3', - 'audio/skill/zhichi_re_chengong1.mp3', - 'audio/skill/zhichi_re_chengong2.mp3', - 'audio/skill/zhichi1.mp3', - 'audio/skill/zhichi2.mp3', - 'audio/skill/zhidao1.mp3', - 'audio/skill/zhidao2.mp3', - 'audio/skill/zhige1.mp3', - 'audio/skill/zhige2.mp3', - 'audio/skill/zhiheng_gz_jun_sunquan1.mp3', - 'audio/skill/zhiheng_gz_jun_sunquan2.mp3', - 'audio/skill/zhiheng1.mp3', - 'audio/skill/zhiheng2.mp3', - 'audio/skill/zhiji_re_jiangwei1.mp3', - 'audio/skill/zhiji_re_jiangwei2.mp3', - 'audio/skill/zhiji1.mp3', - 'audio/skill/zhiji2.mp3', - 'audio/skill/zhijian1.mp3', - 'audio/skill/zhijian2.mp3', - 'audio/skill/zhilve1.mp3', - 'audio/skill/zhilve2.mp3', - 'audio/skill/zhiman_guansuo1.mp3', - 'audio/skill/zhiman_guansuo2.mp3', - 'audio/skill/zhiman_re_masu1.mp3', - 'audio/skill/zhiman_re_masu2.mp3', - 'audio/skill/zhiman1.mp3', - 'audio/skill/zhiman2.mp3', - 'audio/skill/zhimeng1.mp3', - 'audio/skill/zhimeng2.mp3', - 'audio/skill/zhiming1.mp3', - 'audio/skill/zhiming2.mp3', - 'audio/skill/zhiren1.mp3', - 'audio/skill/zhiren2.mp3', - 'audio/skill/zhiri1.mp3', - 'audio/skill/zhiri2.mp3', - 'audio/skill/zhishi1.mp3', - 'audio/skill/zhishi2.mp3', - 'audio/skill/zhiwei1.mp3', - 'audio/skill/zhiwei2.mp3', - 'audio/skill/zhiyan_gexuan1.mp3', - 'audio/skill/zhiyan_re_yufan1.mp3', - 'audio/skill/zhiyan_re_yufan2.mp3', - 'audio/skill/zhiyan_xin_yufan1.mp3', - 'audio/skill/zhiyan_xin_yufan2.mp3', - 'audio/skill/zhiyan1.mp3', - 'audio/skill/zhiyan2.mp3', - 'audio/skill/zhiyi1.mp3', - 'audio/skill/zhiyi2.mp3', - 'audio/skill/zhiyu1.mp3', - 'audio/skill/zhiyu2.mp3', - 'audio/skill/zhongjian1.mp3', - 'audio/skill/zhongjian2.mp3', - 'audio/skill/zhongjie1.mp3', - 'audio/skill/zhongjie2.mp3', - 'audio/skill/zhongyi1.mp3', - 'audio/skill/zhongyi2.mp3', - 'audio/skill/zhongyong1.mp3', - 'audio/skill/zhongyong2.mp3', - 'audio/skill/zhongyun1.mp3', - 'audio/skill/zhongyun2.mp3', - 'audio/skill/zhongzuo1.mp3', - 'audio/skill/zhongzuo2.mp3', - 'audio/skill/zhoufu1.mp3', - 'audio/skill/zhoufu2.mp3', - 'audio/skill/zhoulin1.mp3', - 'audio/skill/zhoulin2.mp3', - 'audio/skill/zhouxian1.mp3', - 'audio/skill/zhouxian2.mp3', - 'audio/skill/zhouxuan1.mp3', - 'audio/skill/zhouxuan2.mp3', - 'audio/skill/zhuandui1.mp3', - 'audio/skill/zhuandui2.mp3', - 'audio/skill/zhuangdan1.mp3', - 'audio/skill/zhuangdan2.mp3', - 'audio/skill/zhuangpo1.mp3', - 'audio/skill/zhuangpo2.mp3', - 'audio/skill/zhuangrong1.mp3', - 'audio/skill/zhuangrong2.mp3', - 'audio/skill/zhuangshu1.mp3', - 'audio/skill/zhuangshu2.mp3', - 'audio/skill/zhuge_skill.mp3', - 'audio/skill/zhuhai_gz_re_xushu1.mp3', - 'audio/skill/zhuhai_gz_re_xushu2.mp3', - 'audio/skill/zhuhai1.mp3', - 'audio/skill/zhuhai2.mp3', - 'audio/skill/zhuide1.mp3', - 'audio/skill/zhuide2.mp3', - 'audio/skill/zhuihuan1.mp3', - 'audio/skill/zhuihuan2.mp3', - 'audio/skill/zhuikong1.mp3', - 'audio/skill/zhuikong2.mp3', - 'audio/skill/zhuitao1.mp3', - 'audio/skill/zhuitao2.mp3', - 'audio/skill/zhuiyi_re_bulianshi1.mp3', - 'audio/skill/zhuiyi_re_bulianshi2.mp3', - 'audio/skill/zhuiyi1.mp3', - 'audio/skill/zhuiyi2.mp3', - 'audio/skill/zhujian1.mp3', - 'audio/skill/zhujian2.mp3', - 'audio/skill/zhukou1.mp3', - 'audio/skill/zhukou2.mp3', - 'audio/skill/zhuning1.mp3', - 'audio/skill/zhuning2.mp3', - 'audio/skill/zhuosheng1.mp3', - 'audio/skill/zhuosheng2.mp3', - 'audio/skill/zhuque_skill.mp3', - 'audio/skill/zhushi1.mp3', - 'audio/skill/zhushi2.mp3', - 'audio/skill/zhuwei1.mp3', - 'audio/skill/zhuwei2.mp3', - 'audio/skill/zifu1.mp3', - 'audio/skill/zifu2.mp3', - 'audio/skill/zili_re_zhonghui1.mp3', - 'audio/skill/zili_re_zhonghui2.mp3', - 'audio/skill/zili1.mp3', - 'audio/skill/zili2.mp3', - 'audio/skill/ziliang1.mp3', - 'audio/skill/ziliang2.mp3', - 'audio/skill/ziqu1.mp3', - 'audio/skill/ziqu2.mp3', - 'audio/skill/zishou_re_liubiao1.mp3', - 'audio/skill/zishou_re_liubiao2.mp3', - 'audio/skill/zishou1.mp3', - 'audio/skill/zishou2.mp3', - 'audio/skill/zishu1.mp3', - 'audio/skill/zishu2.mp3', - 'audio/skill/ziyuan1.mp3', - 'audio/skill/ziyuan2.mp3', - 'audio/skill/zjjuxiang1.mp3', - 'audio/skill/zjjuxiang2.mp3', - 'audio/skill/zlhuji1.mp3', - 'audio/skill/zlhuji2.mp3', - 'audio/skill/zlshoufu1.mp3', - 'audio/skill/zlshoufu2.mp3', - 'audio/skill/zniaoxiang1.mp3', - 'audio/skill/zniaoxiang2.mp3', - 'audio/skill/zongfan1.mp3', - 'audio/skill/zongfan2.mp3', - 'audio/skill/zonghuo.mp3', - 'audio/skill/zongkui_tw_beimihu1.mp3', - 'audio/skill/zongkui_tw_beimihu2.mp3', - 'audio/skill/zongkui1.mp3', - 'audio/skill/zongkui2.mp3', - 'audio/skill/zongshi1.mp3', - 'audio/skill/zongshi2.mp3', - 'audio/skill/zongxuan1.mp3', - 'audio/skill/zongxuan2.mp3', - 'audio/skill/zongzuo1.mp3', - 'audio/skill/zongzuo2.mp3', - 'audio/skill/zuici1.mp3', - 'audio/skill/zuici2.mp3', - 'audio/skill/zuixiang.mp3', - 'audio/skill/zunwei1.mp3', - 'audio/skill/zunwei2.mp3', - 'audio/skill/zuoding_re_zhongyao1.mp3', - 'audio/skill/zuoding_re_zhongyao2.mp3', - 'audio/skill/zuoding1.mp3', - 'audio/skill/zuoding2.mp3', - 'audio/skill/zuoxing1.mp3', - 'audio/skill/zuoxing2.mp3', - 'audio/skill/zyqiao1.mp3', - 'audio/skill/zyqiao2.mp3', - /*skill audio end*/ - - /*voice begin*/ - 'audio/voice/male/0.mp3', - 'audio/voice/male/1.mp3', - 'audio/voice/male/2.mp3', - 'audio/voice/male/3.mp3', - 'audio/voice/male/4.mp3', - 'audio/voice/male/5.mp3', - 'audio/voice/male/6.mp3', - 'audio/voice/male/7.mp3', - 'audio/voice/male/8.mp3', - 'audio/voice/male/9.mp3', - 'audio/voice/male/10.mp3', - 'audio/voice/male/11.mp3', - 'audio/voice/male/12.mp3', - 'audio/voice/male/13.mp3', - 'audio/voice/male/14.mp3', - 'audio/voice/male/15.mp3', - 'audio/voice/male/16.mp3', - 'audio/voice/male/17.mp3', - 'audio/voice/male/18.mp3', - 'audio/voice/male/19.mp3', - 'audio/voice/male/20.mp3', - 'audio/voice/male/21.mp3', - 'audio/voice/male/22.mp3', - 'audio/voice/female/0.mp3', - 'audio/voice/female/1.mp3', - 'audio/voice/female/2.mp3', - 'audio/voice/female/3.mp3', - 'audio/voice/female/4.mp3', - 'audio/voice/female/5.mp3', - 'audio/voice/female/6.mp3', - 'audio/voice/female/7.mp3', - 'audio/voice/female/8.mp3', - 'audio/voice/female/9.mp3', - 'audio/voice/female/10.mp3', - 'audio/voice/female/11.mp3', - 'audio/voice/female/12.mp3', - 'audio/voice/female/13.mp3', - 'audio/voice/female/14.mp3', - 'audio/voice/female/15.mp3', - 'audio/voice/female/16.mp3', - 'audio/voice/female/17.mp3', - 'audio/voice/female/18.mp3', - 'audio/voice/female/19.mp3', - 'audio/voice/female/20.mp3', - 'audio/voice/female/21.mp3', - 'audio/voice/female/22.mp3', - /*voice end*/ - /*audio end*/ - - 'font/huangcao.woff2', - 'font/shousha.woff2', - 'font/xiaozhuan.woff2', - 'font/xingkai.woff2', - 'font/xinwei.woff2', - 'font/yuanli.woff2', - - /*background image begin*/ - 'image/background/beipan_bg.jpg', - 'image/background/heaven_bg.jpg', - 'image/background/huangtian_bg.jpg', - 'image/background/key_bg.jpg', - 'image/background/kyoani_bg.jpg', - 'image/background/lanting_bg.jpg', - 'image/background/lingju_bg.jpg', - 'image/background/noname_bg.jpg', - 'image/background/ol_bg.jpg', - 'image/background/oltianhou_club_bg.jpg', - 'image/background/oltianhou_diamond_bg.jpg', - 'image/background/oltianhou_heart_bg.jpg', - 'image/background/oltianhou_spade_bg.jpg', - 'image/background/planetarian_bg.jpg', - 'image/background/sanying_bg.jpg', - 'image/background/september_bg.jpg', - 'image/background/shengshi_bg.jpg', - 'image/background/taoyuan_bg.jpg', - 'image/background/wangshi_bg.jpg', - 'image/background/wuming_bg.jpg', - 'image/background/xiaowu_bg.jpg', - 'image/background/xinsha_bg.jpg', - 'image/background/xiongxin_bg.jpg', - 'image/background/yinxiang_bg.jpg', - 'image/background/zhanhuo_bg.jpg', - 'image/background/zhanyun_bg.jpg', - 'image/background/zhulin_bg.jpg', - /*background image end*/ - - /*card image begin*/ - 'image/card/bagua.png', - 'image/card/baihupifeng.png', - 'image/card/baishouzhihu.png', - 'image/card/baiyidujiang.png', - 'image/card/baiyin.png', - 'image/card/bingliang.png', - 'image/card/binglinchengxia.png', - 'image/card/binglinchengxiax.png', - 'image/card/bingpotong.png', - 'image/card/bintieshuangji.png', - 'image/card/cangchizhibi.png', - 'image/card/caochuan.png', - 'image/card/caochuanjiejian.png', - 'image/card/caomu.png', - 'image/card/caoyao.png', - 'image/card/cardtempname_bg.png', - 'image/card/changandajian_equip1.png', - 'image/card/charge.png', - 'image/card/cheliji_feilunzhanyu.png', - 'image/card/cheliji_sichengliangyu.png', - 'image/card/cheliji_tiejixuanyu.png', - 'image/card/chenghuodajie.png', - 'image/card/chenhuodajie.png', - 'image/card/chiling.png', - 'image/card/chilongya.png', - 'image/card/chitu.png', - 'image/card/chiyuxi.png', - 'image/card/chuansongmen.png', - 'image/card/chunbing.png', - 'image/card/chuqibuyi.png', - 'image/card/cisha.png', - 'image/card/cixiong.png', - 'image/card/cooperation_damage.png', - 'image/card/dagongche.png', - 'image/card/daihuofenglun.png', - 'image/card/dawan.png', - 'image/card/db_atk1.jpg', - 'image/card/db_atk1_出阵迎战.jpg', - 'image/card/db_atk1_反抗.jpg', - 'image/card/db_atk1_固守城池.jpg', - 'image/card/db_atk2.jpg', - 'image/card/db_atk2_拱卫中军.jpg', - 'image/card/db_atk2_归顺.jpg', - 'image/card/db_atk2_突出重围.jpg', - 'image/card/db_def1.jpg', - 'image/card/db_def1_围城断粮.jpg', - 'image/card/db_def1_镇压.jpg', - 'image/card/db_def1_直取敌营.jpg', - 'image/card/db_def2.jpg', - 'image/card/db_def2_安抚.jpg', - 'image/card/db_def2_擂鼓进军.jpg', - 'image/card/db_def2_扰阵疲敌.jpg', - 'image/card/diaobingqianjiang.png', - 'image/card/diaohulishan.png', - 'image/card/dilu.png', - 'image/card/dinglanyemingzhu.png', - 'image/card/dinvxuanshuang.png', - 'image/card/diqi.png', - 'image/card/donghuangzhong.png', - 'image/card/dongzhuxianji.png', - 'image/card/du.png', - 'image/card/duanjian.png', - 'image/card/dunpaigedang.png', - 'image/card/dz_mantianguohai.png', - 'image/card/expandedSlots.png', - 'image/card/fangtian.png', - 'image/card/feibiao.png', - 'image/card/feilongduofeng.png', - 'image/card/fengchu_card.png', - 'image/card/fengxueren.png', - 'image/card/fengyinzhidan.png', - 'image/card/fudichouxin.png', - 'image/card/fulei.png', - 'image/card/fuxiqin.png', - 'image/card/geanguanhuo.png', - 'image/card/gongshoujianbei.png', - 'image/card/gouhunluo.png', - 'image/card/group_jin.png', - 'image/card/group_key.png', - 'image/card/group_qun.png', - 'image/card/group_shen.png', - 'image/card/group_shu.png', - 'image/card/group_unknown.png', - 'image/card/group_wei.png', - 'image/card/group_western.png', - 'image/card/group_wu.png', - 'image/card/group_ye.png', - 'image/card/guaguliaodu.png', - 'image/card/guangshatianyi.png', - 'image/card/guanshi.png', - 'image/card/guding.png', - 'image/card/gudonggeng.png', - 'image/card/guilingzhitao.png', - 'image/card/guisheqi.png', - 'image/card/guiyanfadao.png', - 'image/card/guiyoujie.png', - 'image/card/guohe.png', - 'image/card/gw_aerdeyin.jpg', - 'image/card/gw_ansha.jpg', - 'image/card/gw_aozuzhilei.jpg', - 'image/card/gw_baishuang.jpg', - 'image/card/gw_baobaoshu.jpg', - 'image/card/gw_baoxueyaoshui.jpg', - 'image/card/gw_birinongwu.jpg', - 'image/card/gw_butianshu.jpg', - 'image/card/gw_chongci.jpg', - 'image/card/gw_ciguhanshuang.jpg', - 'image/card/gw_dieyi.png', - 'image/card/gw_dudayuanshuai1.jpg', - 'image/card/gw_dudayuanshuai2.jpg', - 'image/card/gw_fuyuan.jpg', - 'image/card/gw_ganhan.jpg', - 'image/card/gw_guaiwuchaoxue.jpg', - 'image/card/gw_huangjiashenpan.jpg', - 'image/card/gw_hudiewu.jpg', - 'image/card/gw_kunenfayin.jpg', - 'image/card/gw_lang.jpg', - 'image/card/gw_leizhoushu.jpg', - 'image/card/gw_niuquzhijing.jpg', - 'image/card/gw_nuhaifengbao.jpg', - 'image/card/gw_poxiao.jpg', - 'image/card/gw_qinpendayu.jpg', - 'image/card/gw_shanbengshu.jpg', - 'image/card/gw_shizizhaohuan.jpg', - 'image/card/gw_tongdi.jpg', - 'image/card/gw_tunshi.jpg', - 'image/card/gw_wenyi.jpg', - 'image/card/gw_wuyao.jpg', - 'image/card/gw_xianzumaijiu.jpg', - 'image/card/gw_xinsheng.jpg', - 'image/card/gw_yanziyaoshui.jpg', - 'image/card/gw_yigeniyin.jpg', - 'image/card/gw_youer.jpg', - 'image/card/gw_zhihuanjun.jpg', - 'image/card/gw_zhongmozhizhan.jpg', - 'image/card/gw_zhuoshao.jpg', - 'image/card/gw_zirankuizeng.jpg', - 'image/card/gw_zuihouyuanwang.jpg', - 'image/card/gw_zumoshoukao.jpg', - 'image/card/gx_chongyingshenfu.png', - 'image/card/gx_lingbaoxianhu.png', - 'image/card/gx_taijifuchen.png', - 'image/card/gz_guguoanbang.png', - 'image/card/gz_haolingtianxia.png', - 'image/card/gz_kefuzhongyuan.png', - 'image/card/gz_wenheluanwu.png', - 'image/card/hanbing.png', - 'image/card/handcard.png', - 'image/card/haotianta.png', - 'image/card/heiguangkai.png', - 'image/card/heilonglinpian.png', - 'image/card/hina_shenji.png', - 'image/card/hongshui.png', - 'image/card/hsbaowu_cangbaotu.jpg', - 'image/card/hsbaowu_huangjinyuanhou.jpg', - 'image/card/hsdusu_huangxuecao.jpg', - 'image/card/hsdusu_huoyanhua.jpg', - 'image/card/hsdusu_kuyecao.jpg', - 'image/card/hsdusu_shinancao.jpg', - 'image/card/hsdusu_xueji.jpg', - 'image/card/hsfashu_anyingjingxiang.jpg', - 'image/card/hsfashu_buwendingyibian.jpg', - 'image/card/hsjixie_zhadan.jpg', - 'image/card/hslingjian_jinjilengdong.jpg', - 'image/card/hslingjian_shengxiuhaojiao.jpg', - 'image/card/hslingjian_shijianhuisu.jpg', - 'image/card/hslingjian_xingtigaizao.jpg', - 'image/card/hslingjian_xuanfengzhiren.jpg', - 'image/card/hslingjian_yinmilichang.jpg', - 'image/card/hslingjian_zhongxinghujia.jpg', - 'image/card/hsmengjing_feicuiyoulong.jpg', - 'image/card/hsmengjing_huanxiaojiemei.jpg', - 'image/card/hsmengjing_mengjing.jpg', - 'image/card/hsmengjing_mengye.jpg', - 'image/card/hsmengjing_suxing.jpg', - 'image/card/hsqingyu_feibiao.jpg', - 'image/card/hsqingyu_hufu.jpg', - 'image/card/hsqingyu_shandian.jpg', - 'image/card/hsqingyu_zhanfang.jpg', - 'image/card/hsqingyu_zhao.jpg', - 'image/card/hsqizhou_feng.jpg', - 'image/card/hsqizhou_huo.jpg', - 'image/card/hsqizhou_shui.jpg', - 'image/card/hsqizhou_tu.jpg', - 'image/card/hsshenqi_kongbusangzhong.jpg', - 'image/card/hsshenqi_morijingxiang.jpg', - 'image/card/hsshenqi_nengliangzhiguang.jpg', - 'image/card/hstianqi_dalian.jpg', - 'image/card/hstianqi_nazigelin.jpg', - 'image/card/hstianqi_shali.jpg', - 'image/card/hstianqi_suolasi.jpg', - 'image/card/hsyaoshui.jpg', - 'image/card/hszuzhou_guhuo.jpg', - 'image/card/hszuzhou_nvwudeganguo.jpg', - 'image/card/hszuzhou_nvwudepingguo.jpg', - 'image/card/hszuzhou_nvwudexuetu.jpg', - 'image/card/hszuzhou_wushushike.jpg', - 'image/card/hualiu.png', - 'image/card/huanglinzhicong.png', - 'image/card/huanpodan.png', - 'image/card/hufu.png', - 'image/card/huimiezhichui.png', - 'image/card/huogong.png', - 'image/card/huoshan.png', - 'image/card/huoshaolianying.png', - 'image/card/huxinjing.png', - 'image/card/identity_commoner.jpg', - 'image/card/identity_enemy.jpg', - 'image/card/identity_fan.jpg', - 'image/card/identity_friend.jpg', - 'image/card/identity_nei.jpg', - 'image/card/identity_zhong.jpg', - 'image/card/identity_zhu.jpg', - 'image/card/jiedao.png', - 'image/card/jiejia.png', - 'image/card/jiguanfeng.png', - 'image/card/jiguanshu.png', - 'image/card/jiguantong.png', - 'image/card/jiguanyaoshu.png', - 'image/card/jiguanyuan.png', - 'image/card/jihuocard.png', - 'image/card/jinchan.png', - 'image/card/jingfanma.png', - 'image/card/jingleishan.png', - 'image/card/jinhe.png', - 'image/card/jinlianzhu.png', - 'image/card/jintuiziru.png', - 'image/card/jiu.png', - 'image/card/jiuwei.png', - 'image/card/jiwangkailai.png', - 'image/card/juedou.png', - 'image/card/jueying.png', - 'image/card/kaihua.png', - 'image/card/kamome_suitcase.png', - 'image/card/kano_paibingbuzhen.png', - 'image/card/kongdongyin.png', - 'image/card/kunlunjingc.png', - 'image/card/kuwu.png', - 'image/card/langeguaiyi.png', - 'image/card/lanyinjia.png', - 'image/card/lebu.png', - 'image/card/lianjunshengyan.png', - 'image/card/lianyaohu.png', - 'image/card/linghunzhihuo.png', - 'image/card/lingjiandai.png', - 'image/card/liufengsan.png', - 'image/card/liulongcanjia.png', - 'image/card/liutouge.png', - 'image/card/liuxiaxianniang.png', - 'image/card/liuxinghuoyu.png', - 'image/card/liyutang.png', - 'image/card/longxugou.png', - 'image/card/lukai_club.png', - 'image/card/lukai_diamond.png', - 'image/card/lukai_heart.png', - 'image/card/lukai_spade.png', - 'image/card/lulitongxin.png', - 'image/card/luojingxiashi.png', - 'image/card/luyugeng.png', - 'image/card/ly_piliche.png', - 'image/card/mapodoufu.png', - 'image/card/mianju.png', - 'image/card/mianlijinzhen.png', - 'image/card/miki_binoculars.png', - 'image/card/miki_hydrogladiator.png', - 'image/card/mingguangkai.png', - 'image/card/minguangkai.png', - 'image/card/mizhilianou.png', - 'image/card/molicha.png', - 'image/card/monkey.png', - 'image/card/mtg_bingheyaosai.jpg', - 'image/card/mtg_cangbaohaiwan.jpg', - 'image/card/mtg_duzhao.jpg', - 'image/card/mtg_feixu.jpg', - 'image/card/mtg_haidao.jpg', - 'image/card/mtg_lindixiliu.jpg', - 'image/card/mtg_linzhongjianta.jpg', - 'image/card/mtg_longlushanfeng.jpg', - 'image/card/mtg_shamolvzhou.jpg', - 'image/card/mtg_shuimomuxue.jpg', - 'image/card/mtg_yixialan.jpg', - 'image/card/mtg_youlin.jpg', - 'image/card/mujiaren.png', - 'image/card/muniu.png', - 'image/card/muniu_small.png', - 'image/card/mutoumianju.png', - 'image/card/nanman.png', - 'image/card/numa.png', - 'image/card/nvwashi.png', - 'image/card/nvzhuang.png', - 'image/card/pangufu.png', - 'image/card/pantao.png', - 'image/card/pss_paper.png', - 'image/card/pss_scissor.png', - 'image/card/pss_stone.png', - 'image/card/pyzhuren_club.png', - 'image/card/pyzhuren_diamond.png', - 'image/card/pyzhuren_heart.png', - 'image/card/pyzhuren_shandian.png', - 'image/card/pyzhuren_spade.png', - 'image/card/qiankunbiao.png', - 'image/card/qiankundai.png', - 'image/card/qiaosi_card1.png', - 'image/card/qiaosi_card2.png', - 'image/card/qiaosi_card3.png', - 'image/card/qiaosi_card4.png', - 'image/card/qiaosi_card5.png', - 'image/card/qiaosi_card6.png', - 'image/card/qibaodao.png', - 'image/card/qijia.png', - 'image/card/qilin.png', - 'image/card/qinggang.png', - 'image/card/qinglianxindeng.png', - 'image/card/qinglong.png', - 'image/card/qinglonglingzhu.png', - 'image/card/qinglongzhigui.png', - 'image/card/qingtuan.png', - 'image/card/qixingbaodao.png', - 'image/card/qizhengxiangsheng.png', - 'image/card/renwang.png', - 'image/card/rewrite_bagua.png', - 'image/card/rewrite_baiyin.png', - 'image/card/rewrite_lanyinjia.png', - 'image/card/rewrite_renwang.png', - 'image/card/rewrite_tengjia.png', - 'image/card/rewrite_zhuge.png', - 'image/card/ruyijingubang.png', - 'image/card/sadengjinhuan.png', - 'image/card/sanjian.png', - 'image/card/sanlve.png', - 'image/card/serafuku.png', - 'image/card/sex_double.png', - 'image/card/sex_female.png', - 'image/card/sex_male.png', - 'image/card/sex_male_castrated.png', - 'image/card/sex_none.png', - 'image/card/sex_unknown.png', - 'image/card/sha.png', - 'image/card/shan.png', - 'image/card/shandian.png', - 'image/card/shandianjian.png', - 'image/card/shatang.png', - 'image/card/shencaojie.png', - 'image/card/shenenshu.png', - 'image/card/shengdong.png', - 'image/card/shenhuofeiya.png', - 'image/card/shenmiguo.png', - 'image/card/shennongding.png', - 'image/card/shentoumianju.png', - 'image/card/shezhanqunru.png', - 'image/card/shield.png', - 'image/card/shihuawuqi.png', - 'image/card/shihuifen.png', - 'image/card/shijieshu.png', - 'image/card/shoulijian.png', - 'image/card/shuchui.png', - 'image/card/shuijing_card.png', - 'image/card/shuiyanqijun.png', - 'image/card/shuiyanqijunx.png', - 'image/card/shujinsan.png', - 'image/card/shunshou.png', - 'image/card/sifeizhenmian.png', - 'image/card/sizhaojian.png', - 'image/card/suijiyingbian.png', - 'image/card/suolianjia.png', - 'image/card/taigongyinfu.png', - 'image/card/taipingyaoshu.png', - 'image/card/tanhuadong.png', - 'image/card/tanshezhiren.png', - 'image/card/tao.png', - 'image/card/taoyuan.png', - 'image/card/tengjia.png', - 'image/card/tianjitu.png', - 'image/card/tianxianjiu.png', - 'image/card/tiaojiyanmei.png', - 'image/card/tiesuo.png', - 'image/card/tiesuo_mark.png', - 'image/card/tongque.png', - 'image/card/toulianghuanzhu.png', - 'image/card/toushiche.png', - 'image/card/tuhunsha.png', - 'image/card/tuixinzhifu.png', - 'image/card/tunliang.png', - 'image/card/tuteng1.jpg', - 'image/card/tuteng2.jpg', - 'image/card/tuteng3.jpg', - 'image/card/tuteng4.jpg', - 'image/card/tuteng5.jpg', - 'image/card/tuteng6.jpg', - 'image/card/tuteng7.jpg', - 'image/card/tuteng8.jpg', - 'image/card/wangmeizhike.png', - 'image/card/wanjian.png', - 'image/card/wenhuangsan.png', - 'image/card/wolong_card.png', - 'image/card/wufengjian.png', - 'image/card/wugu.png', - 'image/card/wuliu.png', - 'image/card/wutiesuolian.png', - 'image/card/wuxie.png', - 'image/card/wuxinghelingshan.png', - 'image/card/wuxingpan.png', - 'image/card/wuzhong.png', - 'image/card/wy_meirenji.png', - 'image/card/wy_xiaolicangdao.png', - 'image/card/xiajiao.png', - 'image/card/xianluhui.png', - 'image/card/xiaolicangdao.png', - 'image/card/xiayuncailing.png', - 'image/card/xietianzi.png', - 'image/card/xinge.png', - 'image/card/xingjiegoutong.png', - 'image/card/xingjunyan.png', - 'image/card/xionghuangjiu.png', - 'image/card/xixueguizhihuan.png', - 'image/card/xuanjian_card.png', - 'image/card/xuanwuzhihuang.png', - 'image/card/xuanyuanjian.png', - 'image/card/xuejibingbao.png', - 'image/card/xuelunyang.png', - 'image/card/xumou_jsrg.jpg', - 'image/card/yajiaoqiang.png', - 'image/card/yangpijuan.png', - 'image/card/yanjiadan_club.png', - 'image/card/yanjiadan_diamond.png', - 'image/card/yanjiadan_heart.png', - 'image/card/yanjiadan_spade.png', - 'image/card/yanxiao_card.jpg', - 'image/card/yexingyi.png', - 'image/card/yihuajiemu.png', - 'image/card/yinfengjia.png', - 'image/card/yinfengyi.png', - 'image/card/ying.png', - 'image/card/yinyueqiang.png', - 'image/card/yitianjian.png', - 'image/card/yiyi.png', - 'image/card/yonglv.png', - 'image/card/youdishenru.png', - 'image/card/yougeng.png', - 'image/card/yuanbaorou.png', - 'image/card/yuanjiao.png', - 'image/card/yuanjun.png', - 'image/card/yuansuhuimie.png', - 'image/card/yuchandui.png', - 'image/card/yuchangen.png', - 'image/card/yuchankan.png', - 'image/card/yuchankun.png', - 'image/card/yuchanli.png', - 'image/card/yuchanqian.png', - 'image/card/yuchanxun.png', - 'image/card/yuchanzhen.png', - 'image/card/yufulu.png', - 'image/card/yuheng.png', - 'image/card/yunvyuanshen.png', - 'image/card/yuruyi.png', - 'image/card/yuxi.png', - 'image/card/zengbin.png', - 'image/card/zhadan.png', - 'image/card/zhangba.png', - 'image/card/zhanxiang.png', - 'image/card/zhaogujing.png', - 'image/card/zhaomingdan.png', - 'image/card/zhaoshu.png', - 'image/card/zheji.png', - 'image/card/zhibi.png', - 'image/card/zhiliaobo.png', - 'image/card/zhiluxiaohu.png', - 'image/card/zhuahuang.png', - 'image/card/zhuangshu_basic.png', - 'image/card/zhuangshu_equip.png', - 'image/card/zhuangshu_trick.png', - 'image/card/zhufangshenshi.png', - 'image/card/zhuge.png', - 'image/card/zhujinqiyuan.png', - 'image/card/zhulu_card.png', - 'image/card/zhungangshuo.png', - 'image/card/zhuque.png', - 'image/card/zhuquezhizhang.png', - 'image/card/zixin.png', - 'image/card/ziyangdan.png', - 'image/card/zong.png', - /*card image end*/ - - /*character image begin*/ - 'image/character/ahuinan.jpg', - 'image/character/bailingyun.jpg', - 'image/character/baiwuchang.jpg', - 'image/character/baosanniang.jpg', - 'image/character/baoxin.jpg', - 'image/character/beimihu.jpg', - 'image/character/bianfuren.jpg', - 'image/character/bianxi.jpg', - 'image/character/boss_zhaoyun.jpg', - 'image/character/bulianshi.jpg', - 'image/character/buzhi.jpg', - 'image/character/caifuren.jpg', - 'image/character/caimaozhangyun.jpg', - 'image/character/caiwenji.jpg', - 'image/character/caiyang.jpg', - 'image/character/caiyong.jpg', - 'image/character/caizhenji.jpg', - 'image/character/caoang.jpg', - 'image/character/caoanmin.jpg', - 'image/character/caobuxing.jpg', - 'image/character/caocao.jpg', - 'image/character/caochong.jpg', - 'image/character/caochun.jpg', - 'image/character/caohong.jpg', - 'image/character/caohua.jpg', - 'image/character/caojie.jpg', - 'image/character/caojinyu.jpg', - 'image/character/caomao.jpg', - 'image/character/caopi.jpg', - 'image/character/caoren.jpg', - 'image/character/caorui.jpg', - 'image/character/caoshuang.jpg', - 'image/character/caosong.jpg', - 'image/character/caoxi.jpg', - 'image/character/caoxian.jpg', - 'image/character/caoxiancaohua.jpg', - 'image/character/caoxing.jpg', - 'image/character/caoxiu.jpg', - 'image/character/caoyi.jpg', - 'image/character/caoying.jpg', - 'image/character/caoyu.jpg', - 'image/character/caozhang.jpg', - 'image/character/caozhen.jpg', - 'image/character/caozhi.jpg', - 'image/character/cenhun.jpg', - 'image/character/cheliji.jpg', - 'image/character/chendao.jpg', - 'image/character/chendeng.jpg', - 'image/character/chendong.jpg', - 'image/character/chengbing.jpg', - 'image/character/chengjichengcui.jpg', - 'image/character/chengong.jpg', - 'image/character/chengpu.jpg', - 'image/character/chengui.jpg', - 'image/character/chengyu.jpg', - 'image/character/chenjiao.jpg', - 'image/character/chenlin.jpg', - 'image/character/chenqun.jpg', - 'image/character/chenshi.jpg', - 'image/character/chentai.jpg', - 'image/character/chunyuqiong.jpg', - 'image/character/clan_hanrong.jpg', - 'image/character/clan_hanshao.jpg', - 'image/character/clan_wanghun.jpg', - 'image/character/clan_wangling.jpg', - 'image/character/clan_wanglun.jpg', - 'image/character/clan_wangyun.jpg', - 'image/character/clan_wuban.jpg', - 'image/character/clan_wukuang.jpg', - 'image/character/clan_wuqiao.jpg', - 'image/character/clan_wuxian.jpg', - 'image/character/clan_xuncai.jpg', - 'image/character/clan_xuncan.jpg', - 'image/character/clan_xunchen.jpg', - 'image/character/clan_xunshu.jpg', - 'image/character/clan_xunyou.jpg', - 'image/character/clan_zhonghui.jpg', - 'image/character/clan_zhongyan.jpg', - 'image/character/clan_zhongyu.jpg', - 'image/character/cuimao.jpg', - 'image/character/cuiyan.jpg', - 'image/character/daqiao.jpg', - 'image/character/daxiaoqiao.jpg', - 'image/character/db_key_hina.jpg', - 'image/character/db_key_liyingxia.jpg', - 'image/character/db_wenyang.jpg', - 'image/character/dc_bulianshi.jpg', - 'image/character/dc_caiyang.jpg', - 'image/character/dc_caocao.jpg', - 'image/character/dc_caoshuang.jpg', - 'image/character/dc_caozhi.jpg', - 'image/character/dc_chenqun.jpg', - 'image/character/dc_daxiaoqiao.jpg', - 'image/character/dc_dongzhao.jpg', - 'image/character/dc_duyu.jpg', - 'image/character/dc_fuwan.jpg', - 'image/character/dc_ganfuren.jpg', - 'image/character/dc_gaolan.jpg', - 'image/character/dc_gongsunzan.jpg', - 'image/character/dc_guansuo.jpg', - 'image/character/dc_huangchengyan.jpg', - 'image/character/dc_huanghao.jpg', - 'image/character/dc_huangquan.jpg', - 'image/character/dc_huangzu.jpg', - 'image/character/dc_huban.jpg', - 'image/character/dc_hujinding.jpg', - 'image/character/dc_huojun.jpg', - 'image/character/dc_jiachong.jpg', - 'image/character/dc_jiben.jpg', - 'image/character/dc_jikang.jpg', - 'image/character/dc_jiling.jpg', - 'image/character/dc_jsp_guanyu.jpg', - 'image/character/dc_kongrong.jpg', - 'image/character/dc_liru.jpg', - 'image/character/dc_liuba.jpg', - 'image/character/dc_liubei.jpg', - 'image/character/dc_liuli.jpg', - 'image/character/dc_liuye.jpg', - 'image/character/dc_liuyu.jpg', - 'image/character/dc_luotong.jpg', - 'image/character/dc_lvkuanglvxiang.jpg', - 'image/character/dc_mengda.jpg', - 'image/character/dc_mifuren.jpg', - 'image/character/dc_ruiji.jpg', - 'image/character/dc_sb_lusu.jpg', - 'image/character/dc_sb_simayi.jpg', - 'image/character/dc_sb_simayi_shadow.jpg', - 'image/character/dc_sb_zhouyu.jpg', - 'image/character/dc_shixie.jpg', - 'image/character/dc_simashi.jpg', - 'image/character/dc_sp_jiaxu.jpg', - 'image/character/dc_sp_machao.jpg', - 'image/character/dc_sunce.jpg', - 'image/character/dc_sunchen.jpg', - 'image/character/dc_sunhanhua.jpg', - 'image/character/dc_sunquan.jpg', - 'image/character/dc_sunru.jpg', - 'image/character/dc_sunziliufang.jpg', - 'image/character/dc_tengfanglan.jpg', - 'image/character/dc_wangchang.jpg', - 'image/character/dc_wangjun.jpg', - 'image/character/dc_wangling.jpg', - 'image/character/dc_wangyun.jpg', - 'image/character/dc_wuban.jpg', - 'image/character/dc_xiahouba.jpg', - 'image/character/dc_xujing.jpg', - 'image/character/dc_xushu.jpg', - 'image/character/dc_yangbiao.jpg', - 'image/character/dc_yanghu.jpg', - 'image/character/dc_yuejiu.jpg', - 'image/character/dc_zhangmancheng.jpg', - 'image/character/dc_zhaotongzhaoguang.jpg', - 'image/character/dc_zhaoxiang.jpg', - 'image/character/dc_zhaoyǎn.jpg', - 'image/character/dc_zhaoyun.jpg', - 'image/character/dc_zhouxuān.jpg', - 'image/character/dc_zhuling.jpg', - 'image/character/ddd_baosanniang.jpg', - 'image/character/ddd_caomao.jpg', - 'image/character/ddd_caoshuang.jpg', - 'image/character/ddd_dingfeng.jpg', - 'image/character/ddd_guanning.jpg', - 'image/character/ddd_handang.jpg', - 'image/character/ddd_jianshuo.jpg', - 'image/character/ddd_kebineng.jpg', - 'image/character/ddd_liangxi.jpg', - 'image/character/ddd_lie.jpg', - 'image/character/ddd_liuba.jpg', - 'image/character/ddd_liuhong.jpg', - 'image/character/ddd_liuye.jpg', - 'image/character/ddd_sunliang.jpg', - 'image/character/ddd_wangkanglvkai.jpg', - 'image/character/ddd_wuzhi.jpg', - 'image/character/ddd_xiahouxuan.jpg', - 'image/character/ddd_xianglang.jpg', - 'image/character/ddd_xinxianying.jpg', - 'image/character/ddd_xuelingyun.jpg', - 'image/character/ddd_xujing.jpg', - 'image/character/ddd_yujin.jpg', - 'image/character/ddd_zhangkai.jpg', - 'image/character/ddd_zhaoang.jpg', - 'image/character/ddd_zhenji.jpg', - 'image/character/ddd_zhouchu.jpg', - 'image/character/default_silhouette_female.jpg', - 'image/character/default_silhouette_male.jpg', - 'image/character/dengai.jpg', - 'image/character/dengzhi.jpg', - 'image/character/dengzhong.jpg', - 'image/character/dianwei.jpg', - 'image/character/diaochan.jpg', - 'image/character/dingfeng.jpg', - 'image/character/dingshangwan.jpg', - 'image/character/dingyuan.jpg', - 'image/character/diy_caiwenji.jpg', - 'image/character/diy_feishi.jpg', - 'image/character/diy_hanlong.jpg', - 'image/character/diy_huangzhong.jpg', - 'image/character/diy_liufu.jpg', - 'image/character/diy_liuyan.jpg', - 'image/character/diy_liuzan.jpg', - 'image/character/diy_lukang.jpg', - 'image/character/diy_menghuo.jpg', - 'image/character/diy_tianyu.jpg', - 'image/character/diy_weiyan.jpg', - 'image/character/diy_wenyang.jpg', - 'image/character/diy_xizhenxihong.jpg', - 'image/character/diy_xuhuang.jpg', - 'image/character/diy_yangyi.jpg', - 'image/character/diy_yuji.jpg', - 'image/character/diy_zaozhirenjun.jpg', - 'image/character/diy_zhenji.jpg', - 'image/character/diy_zhouyu.jpg', - 'image/character/dongbai.jpg', - 'image/character/dongcheng.jpg', - 'image/character/dongguiren.jpg', - 'image/character/dongtuna.jpg', - 'image/character/dongwan.jpg', - 'image/character/dongxie.jpg', - 'image/character/dongyun.jpg', - 'image/character/dongzhao.jpg', - 'image/character/dongzhuo.jpg', - 'image/character/duanjiong.jpg', - 'image/character/duanqiaoxiao.jpg', - 'image/character/duanwei.jpg', - 'image/character/dufuren.jpg', - 'image/character/duji.jpg', - 'image/character/dukui.jpg', - 'image/character/duosidawang.jpg', - 'image/character/duxi.jpg', - 'image/character/duyu.jpg', - 'image/character/fanchou.jpg', - 'image/character/fanjiangzhangda.jpg', - 'image/character/fanyufeng.jpg', - 'image/character/fazheng.jpg', - 'image/character/feiyao.jpg', - 'image/character/feiyi.jpg', - 'image/character/fengfang.jpg', - 'image/character/fengfangnv.jpg', - 'image/character/fengxi.jpg', - 'image/character/fuhuanghou.jpg', - 'image/character/fuqian.jpg', - 'image/character/furong.jpg', - 'image/character/furongfuqian.jpg', - 'image/character/fuwan.jpg', - 'image/character/ganfuren.jpg', - 'image/character/ganfurenmifuren.jpg', - 'image/character/ganning.jpg', - 'image/character/gaogan.jpg', - 'image/character/gaolan.jpg', - 'image/character/gaoshun.jpg', - 'image/character/gaoxiang.jpg', - 'image/character/gexuan.jpg', - 'image/character/gjqt_aruan.jpg', - 'image/character/gjqt_bailitusu.jpg', - 'image/character/gjqt_beiluo.jpg', - 'image/character/gjqt_cenying.jpg', - 'image/character/gjqt_chuqi.jpg', - 'image/character/gjqt_fanglansheng.jpg', - 'image/character/gjqt_fengqingxue.jpg', - 'image/character/gjqt_hongyu.jpg', - 'image/character/gjqt_ouyangshaogong.jpg', - 'image/character/gjqt_wenrenyu.jpg', - 'image/character/gjqt_xiangling.jpg', - 'image/character/gjqt_xiayize.jpg', - 'image/character/gjqt_xieyi.jpg', - 'image/character/gjqt_xunfang.jpg', - 'image/character/gjqt_yanjiaxieyi.jpg', - 'image/character/gjqt_yinqianshang.jpg', - 'image/character/gjqt_yuewuyi.jpg', - 'image/character/gjqt_yunwuyue.jpg', - 'image/character/gongsundu.jpg', - 'image/character/gongsunkang.jpg', - 'image/character/gongsunyuan.jpg', - 'image/character/gongsunzan.jpg', - 'image/character/guanhai.jpg', - 'image/character/guanlu.jpg', - 'image/character/guanning.jpg', - 'image/character/guānning.jpg', - 'image/character/guanping.jpg', - 'image/character/guanqiujian.jpg', - 'image/character/guansuo.jpg', - 'image/character/guanxingzhangbao.jpg', - 'image/character/guanyinping.jpg', - 'image/character/guanyu.jpg', - 'image/character/guanzhang.jpg', - 'image/character/guohuai.jpg', - 'image/character/guohuanghou.jpg', - 'image/character/guojia.jpg', - 'image/character/guosi.jpg', - 'image/character/guotu.jpg', - 'image/character/guotufengji.jpg', - 'image/character/guozhao.jpg', - 'image/character/guyong.jpg', - 'image/character/gw_aigeleisi.jpg', - 'image/character/gw_aimin.jpg', - 'image/character/gw_airuiting.jpg', - 'image/character/gw_aisinie.jpg', - 'image/character/gw_aokeweisite.jpg', - 'image/character/gw_bierna.jpg', - 'image/character/gw_bulanwang.jpg', - 'image/character/gw_dagong.jpg', - 'image/character/gw_diandian.jpg', - 'image/character/gw_enxier.jpg', - 'image/character/gw_falanxisika.jpg', - 'image/character/gw_feilafanruide.jpg', - 'image/character/gw_fenghuang.jpg', - 'image/character/gw_fuertaisite.jpg', - 'image/character/gw_fulisi.jpg', - 'image/character/gw_gaier.jpg', - 'image/character/gw_haizhiyezhu.jpg', - 'image/character/gw_haluo.jpg', - 'image/character/gw_hanmuduoer.jpg', - 'image/character/gw_hengsaite.jpg', - 'image/character/gw_huoge.jpg', - 'image/character/gw_jieluote.jpg', - 'image/character/gw_kaerweite.jpg', - 'image/character/gw_kairuisi.jpg', - 'image/character/gw_kanbi.jpg', - 'image/character/gw_kaxier.jpg', - 'image/character/gw_kuite.jpg', - 'image/character/gw_laduoweide.jpg', - 'image/character/gw_lanbote.jpg', - 'image/character/gw_laomaotou.jpg', - 'image/character/gw_laomaotou2.jpg', - 'image/character/gw_linjing.jpg', - 'image/character/gw_luobo.jpg', - 'image/character/gw_luoqi.jpg', - 'image/character/gw_meizi.jpg', - 'image/character/gw_mieren.jpg', - 'image/character/gw_nitelila.jpg', - 'image/character/gw_nvyemo.jpg', - 'image/character/gw_oudimu.jpg', - 'image/character/gw_puxila.jpg', - 'image/character/gw_qigaiwang.jpg', - 'image/character/gw_sanhanya.jpg', - 'image/character/gw_saqiya.jpg', - 'image/character/gw_saqiya1.jpg', - 'image/character/gw_saqiya2.jpg', - 'image/character/gw_shanhu.jpg', - 'image/character/gw_shasixiwusi.jpg', - 'image/character/gw_telisi.jpg', - 'image/character/gw_xigedelifa.jpg', - 'image/character/gw_xili.jpg', - 'image/character/gw_yenaifa.jpg', - 'image/character/gw_yioufeisi.jpg', - 'image/character/gw_yioufeisisp.jpg', - 'image/character/gw_yisilinni.jpg', - 'image/character/gw_zhangyujushou.jpg', - 'image/character/gw_zhuoertan.jpg', - 'image/character/gz_caohong.jpg', - 'image/character/gz_caopi.jpg', - 'image/character/gz_chengong.jpg', - 'image/character/gz_dengai.jpg', - 'image/character/gz_dengzhi.jpg', - 'image/character/gz_dianwei.jpg', - 'image/character/gz_diaochan.jpg', - 'image/character/gz_dingfeng.jpg', - 'image/character/gz_fazheng.jpg', - 'image/character/gz_fengxi.jpg', - 'image/character/gz_ganfuren.jpg', - 'image/character/gz_gongsunyuan.jpg', - 'image/character/gz_guanyu.jpg', - 'image/character/gz_guohuai.jpg', - 'image/character/gz_guojia.jpg', - 'image/character/gz_hetaihou.jpg', - 'image/character/gz_huangyueying.jpg', - 'image/character/gz_huangzhong.jpg', - 'image/character/gz_huangzu.jpg', - 'image/character/gz_jiangwei.jpg', - 'image/character/gz_jiaxu.jpg', - 'image/character/gz_lingtong.jpg', - 'image/character/gz_liuba.jpg', - 'image/character/gz_liuqi.jpg', - 'image/character/gz_lukang.jpg', - 'image/character/gz_luxun.jpg', - 'image/character/gz_lvbu.jpg', - 'image/character/gz_lvlingqi.jpg', - 'image/character/gz_madai.jpg', - 'image/character/gz_masu.jpg', - 'image/character/gz_miheng.jpg', - 'image/character/gz_panfeng.jpg', - 'image/character/gz_panjun.jpg', - 'image/character/gz_pengyang.jpg', - 'image/character/gz_re_xushu.jpg', - 'image/character/gz_re_yuanshao.jpg', - 'image/character/gz_shamoke.jpg', - 'image/character/gz_shixie.jpg', - 'image/character/gz_simazhao.jpg', - 'image/character/gz_sp_zhugeliang.jpg', - 'image/character/gz_sunce.jpg', - 'image/character/gz_sunjian.jpg', - 'image/character/gz_sunshangxiang.jpg', - 'image/character/gz_tangzi.jpg', - 'image/character/gz_wangping.jpg', - 'image/character/gz_wenqin.jpg', - 'image/character/gz_wuguotai.jpg', - 'image/character/gz_wujing.jpg', - 'image/character/gz_xf_sufei.jpg', - 'image/character/gz_xiahouba.jpg', - 'image/character/gz_xiahouyuan.jpg', - 'image/character/gz_xiaoqiao.jpg', - 'image/character/gz_xunyou.jpg', - 'image/character/gz_xusheng.jpg', - 'image/character/gz_xuyou.jpg', - 'image/character/gz_yanbaihu.jpg', - 'image/character/gz_yangwan.jpg', - 'image/character/gz_yuanshu.jpg', - 'image/character/gz_yuejin.jpg', - 'image/character/gz_yuji.jpg', - 'image/character/gz_yujin.jpg', - 'image/character/gz_zhanglu.jpg', - 'image/character/gz_zhangxiu.jpg', - 'image/character/gz_zhenji.jpg', - 'image/character/gz_zhonghui.jpg', - 'image/character/gz_zhouyu.jpg', - 'image/character/gz_zhugeke.jpg', - 'image/character/gz_zhugeliang.jpg', - 'image/character/gz_zhuling.jpg', - 'image/character/gz_zuoci.jpg', - 'image/character/hanba.jpg', - 'image/character/handang.jpg', - 'image/character/hanfu.jpg', - 'image/character/hanhaoshihuan.jpg', - 'image/character/hanlong.jpg', - 'image/character/hanmeng.jpg', - 'image/character/hansui.jpg', - 'image/character/haomeng.jpg', - 'image/character/haopu.jpg', - 'image/character/haozhao.jpg', - 'image/character/heiwuchang.jpg', - 'image/character/hejin.jpg', - 'image/character/heqi.jpg', - 'image/character/hetaihou.jpg', - 'image/character/heyan.jpg', - 'image/character/hhzz_kanade.jpg', - 'image/character/hhzz_shiona.jpg', - 'image/character/hhzz_takaramono1.jpg', - 'image/character/hhzz_takaramono2.jpg', - 'image/character/hidden_image.jpg', - 'image/character/hs_aedwin.jpg', - 'image/character/hs_aerfusi.jpg', - 'image/character/hs_aiqinvyao.jpg', - 'image/character/hs_alakir.jpg', - 'image/character/hs_alextrasza.jpg', - 'image/character/hs_alleria.jpg', - 'image/character/hs_amala.jpg', - 'image/character/hs_anduin.jpg', - 'image/character/hs_anomalus.jpg', - 'image/character/hs_antonidas.jpg', - 'image/character/hs_ashamoer.jpg', - 'image/character/hs_aya.jpg', - 'image/character/hs_baiguyoulong.jpg', - 'image/character/hs_bannabusi.jpg', - 'image/character/hs_barnes.jpg', - 'image/character/hs_bchillmaw.jpg', - 'image/character/hs_bilanyoulong.jpg', - 'image/character/hs_bingshuangnvwang.jpg', - 'image/character/hs_blingtron.jpg', - 'image/character/hs_bolvar.jpg', - 'image/character/hs_brann.jpg', - 'image/character/hs_duyaxinshi.jpg', - 'image/character/hs_enzoth.jpg', - 'image/character/hs_fachaotuteng.jpg', - 'image/character/hs_fandral.jpg', - 'image/character/hs_fengjianhuanfengzhe.jpg', - 'image/character/hs_fenjie.jpg', - 'image/character/hs_finley.jpg', - 'image/character/hs_fuding.jpg', - 'image/character/hs_guldan.jpg', - 'image/character/hs_hajiasha.jpg', - 'image/character/hs_hallazeal.jpg', - 'image/character/hs_heifengqishi.jpg', - 'image/character/hs_hemite.jpg', - 'image/character/hs_hudunren.jpg', - 'image/character/hs_huolituteng.jpg', - 'image/character/hs_huzhixiannv.jpg', - 'image/character/hs_jaina.jpg', - 'image/character/hs_jgarrosh.jpg', - 'image/character/hs_jiawodun.jpg', - 'image/character/hs_jiaziruila.jpg', - 'image/character/hs_jinglinglong.jpg', - 'image/character/hs_kaituozhe.jpg', - 'image/character/hs_kalimosi.jpg', - 'image/character/hs_kazhakusi.jpg', - 'image/character/hs_kchromaggus.jpg', - 'image/character/hs_kcthun.jpg', - 'image/character/hs_khadgar.jpg', - 'image/character/hs_lafamu.jpg', - 'image/character/hs_laila.jpg', - 'image/character/hs_laxiao.jpg', - 'image/character/hs_lazi.jpg', - 'image/character/hs_liadrin.jpg', - 'image/character/hs_loatheb.jpg', - 'image/character/hs_lreno.jpg', - 'image/character/hs_lrexxar.jpg', - 'image/character/hs_lrhonin.jpg', - 'image/character/hs_magni.jpg', - 'image/character/hs_malfurion.jpg', - 'image/character/hs_malorne.jpg', - 'image/character/hs_malygos.jpg', - 'image/character/hs_manyututeng.jpg', - 'image/character/hs_medivh.jpg', - 'image/character/hs_mijiaojisi.jpg', - 'image/character/hs_mojinbaozi.jpg', - 'image/character/hs_morgl.jpg', - 'image/character/hs_nate.jpg', - 'image/character/hs_neptulon.jpg', - 'image/character/hs_nozdormu.jpg', - 'image/character/hs_nuogefu.jpg', - 'image/character/hs_pengpeng.jpg', - 'image/character/hs_pyros.jpg', - 'image/character/hs_pyros1.jpg', - 'image/character/hs_pyros2.jpg', - 'image/character/hs_ronghejuren.jpg', - 'image/character/hs_ruanniguai.jpg', - 'image/character/hs_sainaliusi.jpg', - 'image/character/hs_sapphiron.jpg', - 'image/character/hs_selajin.jpg', - 'image/character/hs_selajin2.jpg', - 'image/character/hs_shaku.jpg', - 'image/character/hs_shanlingjuren.jpg', - 'image/character/hs_shifazhe.jpg', - 'image/character/hs_shirencao.jpg', - 'image/character/hs_shizugui.jpg', - 'image/character/hs_shuiwenxuejia.jpg', - 'image/character/hs_siwangxianzhi.jpg', - 'image/character/hs_siwangzhiyi.jpg', - 'image/character/hs_sthrall.jpg', - 'image/character/hs_taisi.jpg', - 'image/character/hs_tanghangu.jpg', - 'image/character/hs_tgolem.jpg', - 'image/character/hs_totemic.jpg', - 'image/character/hs_trueheart.jpg', - 'image/character/hs_tuoqi.jpg', - 'image/character/hs_tyrande.jpg', - 'image/character/hs_waleera.jpg', - 'image/character/hs_walian.jpg', - 'image/character/hs_wolazi.jpg', - 'image/character/hs_wujiyuansu.jpg', - 'image/character/hs_wuther.jpg', - 'image/character/hs_wuyaowang.jpg', - 'image/character/hs_wvelen.jpg', - 'image/character/hs_xialikeer.jpg', - 'image/character/hs_xiangyaqishi.jpg', - 'image/character/hs_xsylvanas.jpg', - 'image/character/hs_xuanzhuanjijia.jpg', - 'image/character/hs_xuefashi.jpg', - 'image/character/hs_xukongzhiying.jpg', - 'image/character/hs_yangyanwageli.jpg', - 'image/character/hs_yashaji.jpg', - 'image/character/hs_yelinchulong.jpg', - 'image/character/hs_yelinlonghou.jpg', - 'image/character/hs_yelise.jpg', - 'image/character/hs_yinggencao.jpg', - 'image/character/hs_yngvar.jpg', - 'image/character/hs_yogg.jpg', - 'image/character/hs_ysera.jpg', - 'image/character/hs_yuhuozhe.jpg', - 'image/character/hs_zhanzhenggushu.jpg', - 'image/character/hs_zhihuanhua.jpg', - 'image/character/hs_zhishigushu.jpg', - 'image/character/hs_zhouzhuo.jpg', - 'image/character/huaman.jpg', - 'image/character/huanfan.jpg', - 'image/character/huangchengyan.jpg', - 'image/character/huangfusong.jpg', - 'image/character/huanggai.jpg', - 'image/character/huanghao.jpg', - 'image/character/huangjinleishi.jpg', - 'image/character/huangyueying.jpg', - 'image/character/huangzhong.jpg', - 'image/character/huangzu.jpg', - 'image/character/huatuo.jpg', - 'image/character/huaxin.jpg', - 'image/character/huaxiong.jpg', - 'image/character/huban.jpg', - 'image/character/hucheer.jpg', - 'image/character/hujinding.jpg', - 'image/character/huojun.jpg', - 'image/character/huzhao.jpg', - 'image/character/jiachong.jpg', - 'image/character/jiakui.jpg', - 'image/character/jiangfei.jpg', - 'image/character/jianggan.jpg', - 'image/character/jiangqing.jpg', - 'image/character/jiangwei.jpg', - 'image/character/jianyong.jpg', - 'image/character/jiaxu.jpg', - 'image/character/jikang.jpg', - 'image/character/jiling.jpg', - 'image/character/jin_guohuai.jpg', - 'image/character/jin_jiachong.jpg', - 'image/character/jin_simashi.jpg', - 'image/character/jin_simayi.jpg', - 'image/character/jin_simazhao.jpg', - 'image/character/jin_wangyuanji.jpg', - 'image/character/jin_xiahouhui.jpg', - 'image/character/jin_yanghu.jpg', - 'image/character/jin_yanghuiyu.jpg', - 'image/character/jin_zhangchunhua.jpg', - 'image/character/jin_zhouchu.jpg', - 'image/character/jsp_caoren.jpg', - 'image/character/jsp_guanyu.jpg', - 'image/character/jsp_huangyueying.jpg', - 'image/character/jsp_liubei.jpg', - 'image/character/jsp_zhaoyun.jpg', - 'image/character/jsrg_caocao.jpg', - 'image/character/jsrg_caofang.jpg', - 'image/character/jsrg_chendeng.jpg', - 'image/character/jsrg_chunyuqiong.jpg', - 'image/character/jsrg_dongbai.jpg', - 'image/character/jsrg_fanjiangzhangda.jpg', - 'image/character/jsrg_gaoxiang.jpg', - 'image/character/jsrg_guanyu.jpg', - 'image/character/jsrg_guojia.jpg', - 'image/character/jsrg_guoxun.jpg', - 'image/character/jsrg_guozhao.jpg', - 'image/character/jsrg_hansui.jpg', - 'image/character/jsrg_hejin.jpg', - 'image/character/jsrg_huangfusong.jpg', - 'image/character/jsrg_huangzhong.jpg', - 'image/character/jsrg_jiangwei.jpg', - 'image/character/jsrg_kongrong.jpg', - 'image/character/jsrg_liubei.jpg', - 'image/character/jsrg_liuhong.jpg', - 'image/character/jsrg_liuyan.jpg', - 'image/character/jsrg_liuyong.jpg', - 'image/character/jsrg_lougui.jpg', - 'image/character/jsrg_luxun.jpg', - 'image/character/jsrg_lvbu.jpg', - 'image/character/jsrg_machao.jpg', - 'image/character/jsrg_nanhualaoxian.jpg', - 'image/character/jsrg_pangtong.jpg', - 'image/character/jsrg_qiaoxuan.jpg', - 'image/character/jsrg_simayi.jpg', - 'image/character/jsrg_sunce.jpg', - 'image/character/jsrg_sunjian.jpg', - 'image/character/jsrg_sunjun.jpg', - 'image/character/jsrg_sunlubansunluyu.jpg', - 'image/character/jsrg_sunshangxiang.jpg', - 'image/character/jsrg_wangyun.jpg', - 'image/character/jsrg_weiwenzhugezhi.jpg', - 'image/character/jsrg_xiahouen.jpg', - 'image/character/jsrg_xiahourong.jpg', - 'image/character/jsrg_xugong.jpg', - 'image/character/jsrg_xushao.jpg', - 'image/character/jsrg_xuyou.jpg', - 'image/character/jsrg_yangbiao.jpg', - 'image/character/jsrg_zhangchu.jpg', - 'image/character/jsrg_zhangfei.jpg', - 'image/character/jsrg_zhanghe.jpg', - 'image/character/jsrg_zhangliao.jpg', - 'image/character/jsrg_zhangren.jpg', - 'image/character/jsrg_zhangxuan.jpg', - 'image/character/jsrg_zhaoyun.jpg', - 'image/character/jsrg_zhenji.jpg', - 'image/character/jsrg_zhugeliang.jpg', - 'image/character/jsrg_zhujun.jpg', - 'image/character/jsrg_zoushi.jpg', - 'image/character/jun_caocao.jpg', - 'image/character/jun_liubei.jpg', - 'image/character/jun_sunquan.jpg', - 'image/character/jun_zhangjiao.jpg', - 'image/character/junk_duanwei.jpg', - 'image/character/junk_guanyu.jpg', - 'image/character/junk_huangyueying.jpg', - 'image/character/junk_lidian.jpg', - 'image/character/junk_liubei.jpg', - 'image/character/junk_simayi.jpg', - 'image/character/junk_sunquan.jpg', - 'image/character/junk_xuyou.jpg', - 'image/character/junk_zhangjiao.jpg', - 'image/character/junk_zhangrang.jpg', - 'image/character/kaisa.jpg', - 'image/character/kanze.jpg', - 'image/character/kebineng.jpg', - 'image/character/key_abyusa.jpg', - 'image/character/key_akane.jpg', - 'image/character/key_akiko.jpg', - 'image/character/key_ao.jpg', - 'image/character/key_asara.jpg', - 'image/character/key_ayato.jpg', - 'image/character/key_chihaya.jpg', - 'image/character/key_doruji.jpg', - 'image/character/key_erika.jpg', - 'image/character/key_fuuko.jpg', - 'image/character/key_godan.jpg', - 'image/character/key_harukakanata.jpg', - 'image/character/key_haruko.jpg', - 'image/character/key_hina.jpg', - 'image/character/key_hinata.jpg', - 'image/character/key_hiroto.jpg', - 'image/character/key_hisako.jpg', - 'image/character/key_inari.jpg', - 'image/character/key_iriya.jpg', - 'image/character/key_iwasawa.jpg', - 'image/character/key_jojiro.jpg', - 'image/character/key_kagari.jpg', - 'image/character/key_kamome.jpg', - 'image/character/key_kano.jpg', - 'image/character/key_kaori.jpg', - 'image/character/key_kengo.jpg', - 'image/character/key_kiyu.jpg', - 'image/character/key_komari.jpg', - 'image/character/key_kotarou.jpg', - 'image/character/key_kotomi.jpg', - 'image/character/key_kotori.jpg', - 'image/character/key_kud.jpg', - 'image/character/key_kyoko.jpg', - 'image/character/key_kyou.jpg', - 'image/character/key_kyouko.jpg', - 'image/character/key_kyousuke.jpg', - 'image/character/key_lucia.jpg', - 'image/character/key_masato.jpg', - 'image/character/key_mia.jpg', - 'image/character/key_michiru.jpg', - 'image/character/key_midori.jpg', - 'image/character/key_miki.jpg', - 'image/character/key_minagi.jpg', - 'image/character/key_mio.jpg', - 'image/character/key_misa.jpg', - 'image/character/key_misuzu.jpg', - 'image/character/key_nagisa.jpg', - 'image/character/key_nao.jpg', - 'image/character/key_noda.jpg', - 'image/character/key_rei.jpg', - 'image/character/key_riki.jpg', - 'image/character/key_rin.jpg', - 'image/character/key_rumi.jpg', - 'image/character/key_ryoichi.jpg', - 'image/character/key_sakuya.jpg', - 'image/character/key_sasami.jpg', - 'image/character/key_satomi.jpg', - 'image/character/key_saya.jpg', - 'image/character/key_seira.jpg', - 'image/character/key_shiina.jpg', - 'image/character/key_shiki.jpg', - 'image/character/key_shiori.jpg', - 'image/character/key_shiorimiyuki.jpg', - 'image/character/key_shiroha.jpg', - 'image/character/key_shizuku.jpg', - 'image/character/key_shizuru.jpg', - 'image/character/key_sunohara.jpg', - 'image/character/key_tenzen.jpg', - 'image/character/key_tomoya.jpg', - 'image/character/key_tomoyo.jpg', - 'image/character/key_tsumugi.jpg', - 'image/character/key_umi.jpg', - 'image/character/key_ushio.jpg', - 'image/character/key_yoshino.jpg', - 'image/character/key_youta.jpg', - 'image/character/key_yui.jpg', - 'image/character/key_yuiko.jpg', - 'image/character/key_yukine.jpg', - 'image/character/key_yukito.jpg', - 'image/character/key_yuri.jpg', - 'image/character/key_yusa.jpg', - 'image/character/key_yuu.jpg', - 'image/character/key_yuuki.jpg', - 'image/character/key_yuzuru.jpg', - 'image/character/kongrong.jpg', - 'image/character/kuailiangkuaiyue.jpg', - 'image/character/kuaiqi.jpg', - 'image/character/laimin.jpg', - 'image/character/laiyinger.jpg', - 'image/character/le_shen_jiaxu.jpg', - 'image/character/leibo.jpg', - 'image/character/leitong.jpg', - 'image/character/liangxing.jpg', - 'image/character/liaohua.jpg', - 'image/character/libai.jpg', - 'image/character/licaiwei.jpg', - 'image/character/lifeng.jpg', - 'image/character/lijue.jpg', - 'image/character/lingcao.jpg', - 'image/character/lingju.jpg', - 'image/character/lingtong.jpg', - 'image/character/liqueguosi.jpg', - 'image/character/liru.jpg', - 'image/character/lisu.jpg', - 'image/character/litong.jpg', - 'image/character/liuba.jpg', - 'image/character/liubei.jpg', - 'image/character/liubian.jpg', - 'image/character/liubiao.jpg', - 'image/character/liuchen.jpg', - 'image/character/liucheng.jpg', - 'image/character/liuchongluojun.jpg', - 'image/character/liufeng.jpg', - 'image/character/liuhong.jpg', - 'image/character/liuhui.jpg', - 'image/character/liupan.jpg', - 'image/character/liupi.jpg', - 'image/character/liuqi.jpg', - 'image/character/liushan.jpg', - 'image/character/liuxie.jpg', - 'image/character/liuyan.jpg', - 'image/character/liuyao.jpg', - 'image/character/liuye.jpg', - 'image/character/liuyong.jpg', - 'image/character/liuyu.jpg', - 'image/character/liuzan.jpg', - 'image/character/liuzhang.jpg', - 'image/character/liwan.jpg', - 'image/character/liwei.jpg', - 'image/character/liyan.jpg', - 'image/character/liyi.jpg', - 'image/character/liyixiejing.jpg', - 'image/character/longwang.jpg', - 'image/character/longyufei.jpg', - 'image/character/luji.jpg', - 'image/character/lukai.jpg', - 'image/character/lukang.jpg', - 'image/character/luotong.jpg', - 'image/character/luoxian.jpg', - 'image/character/lushi.jpg', - 'image/character/luxun.jpg', - 'image/character/luyi.jpg', - 'image/character/luyusheng.jpg', - 'image/character/luzhi.jpg', - 'image/character/lvboshe.jpg', - 'image/character/lvbu.jpg', - 'image/character/lvdai.jpg', - 'image/character/lvfan.jpg', - 'image/character/lvkai.jpg', - 'image/character/lvkuanglvxiang.jpg', - 'image/character/lvlingqi.jpg', - 'image/character/lvmeng.jpg', - 'image/character/lvqian.jpg', - 'image/character/machao.jpg', - 'image/character/macheng.jpg', - 'image/character/madai.jpg', - 'image/character/majun.jpg', - 'image/character/maliang.jpg', - 'image/character/malingli.jpg', - 'image/character/mamian.jpg', - 'image/character/mamidi.jpg', - 'image/character/manchong.jpg', - 'image/character/mangyachang.jpg', - 'image/character/masu.jpg', - 'image/character/mateng.jpg', - 'image/character/maxiumatie.jpg', - 'image/character/mayuanyi.jpg', - 'image/character/mayunlu.jpg', - 'image/character/mazhong.jpg', - 'image/character/mb_chengui.jpg', - 'image/character/mb_huban.jpg', - 'image/character/mb_sunluyu.jpg', - 'image/character/mb_xianglang.jpg', - 'image/character/mengda.jpg', - 'image/character/menghuo.jpg', - 'image/character/mengjie.jpg', - 'image/character/mengyou.jpg', - 'image/character/mifangfushiren.jpg', - 'image/character/mifuren.jpg', - 'image/character/miheng.jpg', - 'image/character/mizhu.jpg', - 'image/character/mp_liuling.jpg', - 'image/character/mtg_ayeni.jpg', - 'image/character/mtg_jiding.jpg', - 'image/character/mtg_jiesi.jpg', - 'image/character/mtg_lilianna.jpg', - 'image/character/mtg_nisha.jpg', - 'image/character/mtg_qianzhuo.jpg', - 'image/character/muludawang.jpg', - 'image/character/mushun.jpg', - 'image/character/nanhualaoxian.jpg', - 'image/character/nashime.jpg', - 'image/character/new_caoren.jpg', - 'image/character/nezha.jpg', - 'image/character/nianshou.jpg', - 'image/character/niufu.jpg', - 'image/character/niujin.jpg', - 'image/character/niutou.jpg', - 'image/character/noname.jpg', - 'image/character/noname_machao.png', - 'image/character/noname_sunce.png', - 'image/character/ns_caimao.jpg', - 'image/character/ns_caoanmin.jpg', - 'image/character/ns_caocao.jpg', - 'image/character/ns_caocaosp.jpg', - 'image/character/ns_caoshuang.jpg', - 'image/character/ns_chendao.jpg', - 'image/character/ns_chengpu.jpg', - 'image/character/ns_chentai.jpg', - 'image/character/ns_duangui.jpg', - 'image/character/ns_duji.jpg', - 'image/character/ns_fanchou.jpg', - 'image/character/ns_guanlu.jpg', - 'image/character/ns_huamulan.jpg', - 'image/character/ns_huangchengyan.jpg', - 'image/character/ns_huangwudie.jpg', - 'image/character/ns_huangzu.jpg', - 'image/character/ns_jiaxu.jpg', - 'image/character/ns_jinke.jpg', - 'image/character/ns_lijue.jpg', - 'image/character/ns_limi.jpg', - 'image/character/ns_lisu.jpg', - 'image/character/ns_liuzhang.jpg', - 'image/character/ns_luyusheng.jpg', - 'image/character/ns_lvmeng.jpg', - 'image/character/ns_lvzhi.jpg', - 'image/character/ns_masu.jpg', - 'image/character/ns_mengyou.jpg', - 'image/character/ns_nanhua.jpg', - 'image/character/ns_nanhua_left.jpg', - 'image/character/ns_nanhua_right.jpg', - 'image/character/ns_ruanji.jpg', - 'image/character/ns_shenpei.jpg', - 'image/character/ns_simazhao.jpg', - 'image/character/ns_sunchensunjun.jpg', - 'image/character/ns_sundeng.jpg', - 'image/character/ns_sunjian.jpg', - 'image/character/ns_sunyi.jpg', - 'image/character/ns_wangyue.jpg', - 'image/character/ns_wangyun.jpg', - 'image/character/ns_wenchou.jpg', - 'image/character/ns_xinnanhua.jpg', - 'image/character/ns_xinxianying.jpg', - 'image/character/ns_yanghu.jpg', - 'image/character/ns_yangyi.jpg', - 'image/character/ns_yanliang.jpg', - 'image/character/ns_yuanxi.jpg', - 'image/character/ns_yuji.jpg', - 'image/character/ns_yujisp.jpg', - 'image/character/ns_zanghong.jpg', - 'image/character/ns_zhangbao.jpg', - 'image/character/ns_zhangji.jpg', - 'image/character/ns_zhangning.jpg', - 'image/character/ns_zhangwei.jpg', - 'image/character/ns_zhangxiu.jpg', - 'image/character/ns_zhonglimu.jpg', - 'image/character/ns_zhugeliang.jpg', - 'image/character/ns_zuoci.jpg', - 'image/character/ol_bianfuren.jpg', - 'image/character/ol_caiwenji.jpg', - 'image/character/ol_caozhang.jpg', - 'image/character/ol_chendeng.jpg', - 'image/character/ol_chengpu.jpg', - 'image/character/ol_dengai.jpg', - 'image/character/ol_dengzhi.jpg', - 'image/character/ol_dianwei.jpg', - 'image/character/ol_dingshangwan.jpg', - 'image/character/ol_dingyuan.jpg', - 'image/character/ol_dongzhao.jpg', - 'image/character/ol_dongzhuo.jpg', - 'image/character/ol_feiyi.jpg', - 'image/character/ol_furong.jpg', - 'image/character/ol_gaoshun.jpg', - 'image/character/ol_guohuai.jpg', - 'image/character/ol_huangzhong.jpg', - 'image/character/ol_huaxin.jpg', - 'image/character/ol_huaxiong.jpg', - 'image/character/ol_huban.jpg', - 'image/character/ol_hujinding.jpg', - 'image/character/ol_jiangwei.jpg', - 'image/character/ol_jianyong.jpg', - 'image/character/ol_lingtong.jpg', - 'image/character/ol_lisu.jpg', - 'image/character/ol_liuba.jpg', - 'image/character/ol_liushan.jpg', - 'image/character/ol_liuyu.jpg', - 'image/character/ol_liwan.jpg', - 'image/character/ol_lukai.jpg', - 'image/character/ol_lusu.jpg', - 'image/character/ol_luyusheng.jpg', - 'image/character/ol_maliang.jpg', - 'image/character/ol_mengda.jpg', - 'image/character/ol_pangde.jpg', - 'image/character/ol_pangtong.jpg', - 'image/character/ol_pengyang.jpg', - 'image/character/ol_puyuan.jpg', - 'image/character/ol_qianzhao.jpg', - 'image/character/ol_sb_guanyu.jpg', - 'image/character/ol_sb_jiangwei.jpg', - 'image/character/ol_sb_taishici.jpg', - 'image/character/ol_sb_yuanshao.jpg', - 'image/character/ol_sb_yuanshao_shadow.jpg', - 'image/character/ol_sp_zhugeliang.jpg', - 'image/character/ol_sunjian.jpg', - 'image/character/ol_wanglang.jpg', - 'image/character/ol_wangrong.jpg', - 'image/character/ol_weiyan.jpg', - 'image/character/ol_wenqin.jpg', - 'image/character/ol_xiahouyuan.jpg', - 'image/character/ol_xiaoqiao.jpg', - 'image/character/ol_xinxianying.jpg', - 'image/character/ol_xuhuang.jpg', - 'image/character/ol_xunyu.jpg', - 'image/character/ol_yangyi.jpg', - 'image/character/ol_yanwen.jpg', - 'image/character/ol_yuanshao.jpg', - 'image/character/ol_yuanshu.jpg', - 'image/character/ol_yufan.jpg', - 'image/character/ol_yujin.jpg', - 'image/character/ol_zhangchangpu.jpg', - 'image/character/ol_zhangliao.jpg', - 'image/character/ol_zhangrang.jpg', - 'image/character/ol_zhangyì.jpg', - 'image/character/ol_zhangzhang.jpg', - 'image/character/ol_zhouqun.jpg', - 'image/character/ol_zhujun.jpg', - 'image/character/ol_zhuling.jpg', - 'image/character/ol_zhurong.jpg', - 'image/character/old_bulianshi.jpg', - 'image/character/old_caocao.jpg', - 'image/character/old_caochong.jpg', - 'image/character/old_caochun.jpg', - 'image/character/old_caoren.jpg', - 'image/character/old_caorui.jpg', - 'image/character/old_caoxiu.jpg', - 'image/character/old_caozhen.jpg', - 'image/character/old_chendao.jpg', - 'image/character/old_chenqun.jpg', - 'image/character/old_dingfeng.jpg', - 'image/character/old_fuhuanghou.jpg', - 'image/character/old_gaoshun.jpg', - 'image/character/old_guanqiujian.jpg', - 'image/character/old_guanyinping.jpg', - 'image/character/old_guanyu.jpg', - 'image/character/old_guanzhang.jpg', - 'image/character/old_handang.jpg', - 'image/character/old_huangfusong.jpg', - 'image/character/old_huanghao.jpg', - 'image/character/old_huatuo.jpg', - 'image/character/old_huaxiong.jpg', - 'image/character/old_jiakui.jpg', - 'image/character/old_lingju.jpg', - 'image/character/old_lingtong.jpg', - 'image/character/old_liubiao.jpg', - 'image/character/old_liuzan.jpg', - 'image/character/old_liyan.jpg', - 'image/character/old_machao.jpg', - 'image/character/old_madai.jpg', - 'image/character/old_majun.jpg', - 'image/character/old_maliang.jpg', - 'image/character/old_quancong.jpg', - 'image/character/old_re_lidian.jpg', - 'image/character/old_shen_zhaoyun.jpg', - 'image/character/old_shixie.jpg', - 'image/character/old_wanglang.jpg', - 'image/character/old_wangyi.jpg', - 'image/character/old_wangyun.jpg', - 'image/character/old_xiaoqiao.jpg', - 'image/character/old_xusheng.jpg', - 'image/character/old_yangyan.jpg', - 'image/character/old_yangzhi.jpg', - 'image/character/old_yuanshu.jpg', - 'image/character/old_zhangfei.jpg', - 'image/character/old_zhangxingcai.jpg', - 'image/character/old_zhaoyun.jpg', - 'image/character/old_zhonghui.jpg', - 'image/character/old_zhoutai.jpg', - 'image/character/old_zhugezhan.jpg', - 'image/character/old_zhuhuan.jpg', - 'image/character/old_zhuran.jpg', - 'image/character/old_zhuzhi.jpg', - 'image/character/oldre_liubiao.jpg', - 'image/character/ow_ana.jpg', - 'image/character/ow_banzang.jpg', - 'image/character/ow_baolei.jpg', - 'image/character/ow_chanyata.jpg', - 'image/character/ow_dva.jpg', - 'image/character/ow_falaozhiying.jpg', - 'image/character/ow_heibaihe.jpg', - 'image/character/ow_heiying.jpg', - 'image/character/ow_kuangshu.jpg', - 'image/character/ow_laiyinhate.jpg', - 'image/character/ow_liekong.jpg', - 'image/character/ow_luba.jpg', - 'image/character/ow_luxiao.jpg', - 'image/character/ow_maikelei.jpg', - 'image/character/ow_mei.jpg', - 'image/character/ow_orisa.jpg', - 'image/character/ow_shibing.jpg', - 'image/character/ow_sishen.jpg', - 'image/character/ow_tianshi.jpg', - 'image/character/ow_tuobiang.jpg', - 'image/character/ow_wensidun.jpg', - 'image/character/ow_yuanshi.jpg', - 'image/character/ow_zhaliya.jpg', - 'image/character/ow_zhixuzhiguang.jpg', - 'image/character/pal_anu.jpg', - 'image/character/pal_changqing.jpg', - 'image/character/pal_hanlingsha.jpg', - 'image/character/pal_jiangcheng.jpg', - 'image/character/pal_jiangyunfan.jpg', - 'image/character/pal_jingtian.jpg', - 'image/character/pal_jushifang.jpg', - 'image/character/pal_leiyuange.jpg', - 'image/character/pal_linyueru.jpg', - 'image/character/pal_liumengli.jpg', - 'image/character/pal_lixiaoyao.jpg', - 'image/character/pal_longkui.jpg', - 'image/character/pal_longkuigui.jpg', - 'image/character/pal_longyou.jpg', - 'image/character/pal_luozhaoyan.jpg', - 'image/character/pal_mingxiu.jpg', - 'image/character/pal_muchanglan.jpg', - 'image/character/pal_murongziying.jpg', - 'image/character/pal_nangonghuang.jpg', - 'image/character/pal_shenqishuang.jpg', - 'image/character/pal_sumei.jpg', - 'image/character/pal_tangyurou.jpg', - 'image/character/pal_wangpengxu.jpg', - 'image/character/pal_wangxiaohu.jpg', - 'image/character/pal_wenhui.jpg', - 'image/character/pal_xia.jpg', - 'image/character/pal_xiahoujinxuan.jpg', - 'image/character/pal_xianqing.jpg', - 'image/character/pal_xiaoman.jpg', - 'image/character/pal_xingxuan.jpg', - 'image/character/pal_xuanxiao.jpg', - 'image/character/pal_xuejian.jpg', - 'image/character/pal_yuejinzhao.jpg', - 'image/character/pal_yueqi.jpg', - 'image/character/pal_yuntianhe.jpg', - 'image/character/pal_zhaoliner.jpg', - 'image/character/pal_zixuan.jpg', - 'image/character/panfeng.jpg', - 'image/character/pangde.jpg', - 'image/character/pangdegong.jpg', - 'image/character/panghui.jpg', - 'image/character/pangshanmin.jpg', - 'image/character/pangtong.jpg', - 'image/character/panjun.jpg', - 'image/character/panshu.jpg', - 'image/character/panzhangmazhong.jpg', - 'image/character/pe_mengda.jpg', - 'image/character/pe_sunchen.jpg', - 'image/character/pe_wangyun.jpg', - 'image/character/pe_wenqin.jpg', - 'image/character/pe_zhonghui.jpg', - 'image/character/peixiu.jpg', - 'image/character/peiyuanshao.jpg', - 'image/character/pengyang.jpg', - 'image/character/pk_sp_duyu.jpg', - 'image/character/prp_zhugeliang.jpg', - 'image/character/ps_caopi.jpg', - 'image/character/ps_caozhi.jpg', - 'image/character/ps_guanyu.jpg', - 'image/character/ps_jiaxu.jpg', - 'image/character/ps_jin_simayi.jpg', - 'image/character/ps_lvbu.jpg', - 'image/character/ps_machao.jpg', - 'image/character/ps_shen_machao.jpg', - 'image/character/ps_simayi.jpg', - 'image/character/ps_zhugeliang.jpg', - 'image/character/ps1059_guojia.jpg', - 'image/character/ps1062_zhouyu.jpg', - 'image/character/ps2063_zhaoyun.jpg', - 'image/character/ps2066_zhugeliang.jpg', - 'image/character/ps2067_zhaoyun.jpg', - 'image/character/ps2068_simayi.jpg', - 'image/character/ps2070_guojia.jpg', - 'image/character/ps2080_zhouyu.jpg', - 'image/character/pujing.jpg', - 'image/character/puyuan.jpg', - 'image/character/qianzhao.jpg', - 'image/character/qiaogong.jpg', - 'image/character/qiaorui.jpg', - 'image/character/qiaozhou.jpg', - 'image/character/qinghegongzhu.jpg', - 'image/character/qinlang.jpg', - 'image/character/qinmi.jpg', - 'image/character/qinyilu.jpg', - 'image/character/qiuliju.jpg', - 'image/character/quancong.jpg', - 'image/character/quanhuijie.jpg', - 'image/character/quhuang.jpg', - 'image/character/quyi.jpg', - 'image/character/re_baosanniang.jpg', - 'image/character/re_bulianshi.jpg', - 'image/character/re_caifuren.jpg', - 'image/character/re_caiwenji.jpg', - 'image/character/re_caiyong.jpg', - 'image/character/re_caocao.jpg', - 'image/character/re_caochong.jpg', - 'image/character/re_caopi.jpg', - 'image/character/re_caorui.jpg', - 'image/character/re_caoxiu.jpg', - 'image/character/re_caozhang.jpg', - 'image/character/re_caozhen.jpg', - 'image/character/re_caozhi.jpg', - 'image/character/re_chendeng.jpg', - 'image/character/re_chengong.jpg', - 'image/character/re_chengpu.jpg', - 'image/character/re_chenqun.jpg', - 'image/character/re_chunyuqiong.jpg', - 'image/character/re_daqiao.jpg', - 'image/character/re_dengai.jpg', - 'image/character/re_dengzhi.jpg', - 'image/character/re_dianwei.jpg', - 'image/character/re_diaochan.jpg', - 'image/character/re_dongbai.jpg', - 'image/character/re_dongcheng.jpg', - 'image/character/re_dongzhuo.jpg', - 'image/character/re_duji.jpg', - 'image/character/re_fazheng.jpg', - 'image/character/re_fengfangnv.jpg', - 'image/character/re_fuhuanghou.jpg', - 'image/character/re_ganning.jpg', - 'image/character/re_gaoshun.jpg', - 'image/character/re_gongsunyuan.jpg', - 'image/character/re_gongsunzan.jpg', - 'image/character/re_guanping.jpg', - 'image/character/re_guanqiujian.jpg', - 'image/character/re_guanyu.jpg', - 'image/character/re_guanzhang.jpg', - 'image/character/re_guohuai.jpg', - 'image/character/re_guohuanghou.jpg', - 'image/character/re_guojia.jpg', - 'image/character/re_guotufengji.jpg', - 'image/character/re_guyong.jpg', - 'image/character/re_handang.jpg', - 'image/character/re_hanhaoshihuan.jpg', - 'image/character/re_hansui.jpg', - 'image/character/re_hejin.jpg', - 'image/character/re_heqi.jpg', - 'image/character/re_huanggai.jpg', - 'image/character/re_huangyueying.jpg', - 'image/character/re_huangzhong.jpg', - 'image/character/re_huatuo.jpg', - 'image/character/re_huaxiong.jpg', - 'image/character/re_hucheer.jpg', - 'image/character/re_jiangwei.jpg', - 'image/character/re_jianyong.jpg', - 'image/character/re_jiaxu.jpg', - 'image/character/re_jikang.jpg', - 'image/character/re_jsp_huangyueying.jpg', - 'image/character/re_jsp_pangtong.jpg', - 'image/character/re_jushou.jpg', - 'image/character/re_kanze.jpg', - 'image/character/re_liaohua.jpg', - 'image/character/re_lidian.jpg', - 'image/character/re_lingtong.jpg', - 'image/character/re_liru.jpg', - 'image/character/re_liubei.jpg', - 'image/character/re_liubiao.jpg', - 'image/character/re_liuchen.jpg', - 'image/character/re_liufeng.jpg', - 'image/character/re_liushan.jpg', - 'image/character/re_liuzan.jpg', - 'image/character/re_lusu.jpg', - 'image/character/re_luxun.jpg', - 'image/character/re_lvbu.jpg', - 'image/character/re_lvmeng.jpg', - 'image/character/re_machao.jpg', - 'image/character/re_madai.jpg', - 'image/character/re_maliang.jpg', - 'image/character/re_manchong.jpg', - 'image/character/re_masu.jpg', - 'image/character/re_mazhong.jpg', - 'image/character/re_menghuo.jpg', - 'image/character/re_miheng.jpg', - 'image/character/re_nanhualaoxian.jpg', - 'image/character/re_niujin.jpg', - 'image/character/re_panfeng.jpg', - 'image/character/re_pangde.jpg', - 'image/character/re_pangdegong.jpg', - 'image/character/re_pangtong.jpg', - 'image/character/re_panshu.jpg', - 'image/character/re_panzhangmazhong.jpg', - 'image/character/re_quancong.jpg', - 'image/character/re_quyi.jpg', - 'image/character/re_simayi.jpg', - 'image/character/re_sp_taishici.jpg', - 'image/character/re_sp_zhugeliang.jpg', - 'image/character/re_sunben.jpg', - 'image/character/re_sunce.jpg', - 'image/character/re_sundeng.jpg', - 'image/character/re_sunjian.jpg', - 'image/character/re_sunluban.jpg', - 'image/character/re_sunluyu.jpg', - 'image/character/re_sunquan.jpg', - 'image/character/re_sunshangxiang.jpg', - 'image/character/re_sunxiu.jpg', - 'image/character/re_sunyi.jpg', - 'image/character/re_taishici.jpg', - 'image/character/re_taoqian.jpg', - 'image/character/re_wangyi.jpg', - 'image/character/re_wangyun.jpg', - 'image/character/re_weiwenzhugezhi.jpg', - 'image/character/re_weiyan.jpg', - 'image/character/re_wenpin.jpg', - 'image/character/re_wuguotai.jpg', - 'image/character/re_wuyi.jpg', - 'image/character/re_xiahoudun.jpg', - 'image/character/re_xiahoushi.jpg', - 'image/character/re_xiahouyuan.jpg', - 'image/character/re_xiaoqiao.jpg', - 'image/character/re_xinxianying.jpg', - 'image/character/re_xugong.jpg', - 'image/character/re_xuhuang.jpg', - 'image/character/re_xunchen.jpg', - 'image/character/re_xunyou.jpg', - 'image/character/re_xunyu.jpg', - 'image/character/re_xusheng.jpg', - 'image/character/re_xushu.jpg', - 'image/character/re_xuzhu.jpg', - 'image/character/re_yanwen.jpg', - 'image/character/re_yuanshao.jpg', - 'image/character/re_yuanshu.jpg', - 'image/character/re_yufan.jpg', - 'image/character/re_yuji.jpg', - 'image/character/re_yujin.jpg', - 'image/character/re_zhangbao.jpg', - 'image/character/re_zhangchunhua.jpg', - 'image/character/re_zhangfei.jpg', - 'image/character/re_zhanggong.jpg', - 'image/character/re_zhanghe.jpg', - 'image/character/re_zhangjiao.jpg', - 'image/character/re_zhangliang.jpg', - 'image/character/re_zhangliao.jpg', - 'image/character/re_zhangsong.jpg', - 'image/character/re_zhangyi.jpg', - 'image/character/re_zhangzhang.jpg', - 'image/character/re_zhaoyun.jpg', - 'image/character/re_zhenji.jpg', - 'image/character/re_zhonghui.jpg', - 'image/character/re_zhongyao.jpg', - 'image/character/re_zhoucang.jpg', - 'image/character/re_zhouyu.jpg', - 'image/character/re_zhugeliang.jpg', - 'image/character/re_zhuhuan.jpg', - 'image/character/re_zhuran.jpg', - 'image/character/re_zhurong.jpg', - 'image/character/re_zhuzhi.jpg', - 'image/character/re_zoushi.jpg', - 'image/character/re_zuoci.jpg', - 'image/character/ruanhui.jpg', - 'image/character/ruanji.jpg', - 'image/character/ruanyu.jpg', - 'image/character/ruiji.jpg', - 'image/character/sb_caocao.jpg', - 'image/character/sb_caopi.jpg', - 'image/character/sb_caoren.jpg', - 'image/character/sb_chengong.jpg', - 'image/character/sb_daqiao.jpg', - 'image/character/sb_diaochan.jpg', - 'image/character/sb_fazheng.jpg', - 'image/character/sb_ganning.jpg', - 'image/character/sb_guanyu.jpg', - 'image/character/sb_huanggai.jpg', - 'image/character/sb_huangyueying.jpg', - 'image/character/sb_huangzhong.jpg', - 'image/character/sb_huaxiong.jpg', - 'image/character/sb_jiangwei.jpg', - 'image/character/sb_liubei.jpg', - 'image/character/sb_liubiao.jpg', - 'image/character/sb_lvmeng.jpg', - 'image/character/sb_machao.jpg', - 'image/character/sb_menghuo.jpg', - 'image/character/sb_pangtong.jpg', - 'image/character/sb_sp_zhugeliang.jpg', - 'image/character/sb_sunce.jpg', - 'image/character/sb_sunquan.jpg', - 'image/character/sb_sunshangxiang.jpg', - 'image/character/sb_xiahoushi.jpg', - 'image/character/sb_xiaoqiao.jpg', - 'image/character/sb_xuhuang.jpg', - 'image/character/sb_yl_luzhi.jpg', - 'image/character/sb_yuanshao.jpg', - 'image/character/sb_yujin.jpg', - 'image/character/sb_zhangfei.jpg', - 'image/character/sb_zhanghe.jpg', - 'image/character/sb_zhangjiao.jpg', - 'image/character/sb_zhaoyun.jpg', - 'image/character/sb_zhenji.jpg', - 'image/character/sb_zhouyu.jpg', - 'image/character/sb_zhugeliang.jpg', - 'image/character/sb_zhurong.jpg', - 'image/character/scs_bilan.jpg', - 'image/character/scs_bilan_dead.jpg', - 'image/character/scs_duangui.jpg', - 'image/character/scs_duangui_dead.jpg', - 'image/character/scs_gaowang.jpg', - 'image/character/scs_gaowang_dead.jpg', - 'image/character/scs_guosheng.jpg', - 'image/character/scs_guosheng_dead.jpg', - 'image/character/scs_hankui.jpg', - 'image/character/scs_hankui_dead.jpg', - 'image/character/scs_lisong.jpg', - 'image/character/scs_lisong_dead.jpg', - 'image/character/scs_sunzhang.jpg', - 'image/character/scs_sunzhang_dead.jpg', - 'image/character/scs_xiayun.jpg', - 'image/character/scs_xiayun_dead.jpg', - 'image/character/scs_zhangrang.jpg', - 'image/character/scs_zhangrang_dead.jpg', - 'image/character/scs_zhaozhong.jpg', - 'image/character/scs_zhaozhong_dead.jpg', - 'image/character/shamoke.jpg', - 'image/character/shen_caocao.jpg', - 'image/character/shen_caopi.jpg', - 'image/character/shen_dengai.jpg', - 'image/character/shen_dianwei.jpg', - 'image/character/shen_diaochan.jpg', - 'image/character/shen_ganning.jpg', - 'image/character/shen_guanyu.jpg', - 'image/character/shen_guojia.jpg', - 'image/character/shen_huatuo.jpg', - 'image/character/shen_jiangwei.jpg', - 'image/character/shen_jiaxu.jpg', - 'image/character/shen_liubei.jpg', - 'image/character/shen_luxun.jpg', - 'image/character/shen_lvbu.jpg', - 'image/character/shen_lvmeng.jpg', - 'image/character/shen_machao.jpg', - 'image/character/shen_simayi.jpg', - 'image/character/shen_sunce.jpg', - 'image/character/shen_sunquan.jpg', - 'image/character/shen_taishici.jpg', - 'image/character/shen_xunyu.jpg', - 'image/character/shen_xuzhu.jpg', - 'image/character/shen_zhangfei.jpg', - 'image/character/shen_zhangjiao.jpg', - 'image/character/shen_zhangliao.jpg', - 'image/character/shen_zhaoyun.jpg', - 'image/character/shen_zhenji.jpg', - 'image/character/shen_zhouyu.jpg', - 'image/character/shen_zhugeliang.jpg', - 'image/character/shenpei.jpg', - 'image/character/shibao.jpg', - 'image/character/shibing1.jpg', - 'image/character/shibing2.jpg', - 'image/character/shichangshi.jpg', - 'image/character/shichangshi_dead.jpg', - 'image/character/shixie.jpg', - 'image/character/shiyi.jpg', - 'image/character/simafu.jpg', - 'image/character/simahui.jpg', - 'image/character/simalang.jpg', - 'image/character/simashi.jpg', - 'image/character/simayi.jpg', - 'image/character/simazhao.jpg', - 'image/character/simazhou.jpg', - 'image/character/sp_bianfuren.jpg', - 'image/character/sp_caiwenji.jpg', - 'image/character/sp_caoren.jpg', - 'image/character/sp_caosong.jpg', - 'image/character/sp_chendong.jpg', - 'image/character/sp_chenzhen.jpg', - 'image/character/sp_cuiyan.jpg', - 'image/character/sp_daqiao.jpg', - 'image/character/sp_diaochan.jpg', - 'image/character/sp_dongzhuo.jpg', - 'image/character/sp_duyu.jpg', - 'image/character/sp_fuhuanghou.jpg', - 'image/character/sp_fuwan.jpg', - 'image/character/sp_ganning.jpg', - 'image/character/sp_gaolan.jpg', - 'image/character/sp_gongsunzan.jpg', - 'image/character/sp_huaman.jpg', - 'image/character/sp_huangfusong.jpg', - 'image/character/sp_huaxin.jpg', - 'image/character/sp_jianggan.jpg', - 'image/character/sp_jiangqing.jpg', - 'image/character/sp_jiangwan.jpg', - 'image/character/sp_jiangwei.jpg', - 'image/character/sp_jiaxu.jpg', - 'image/character/sp_jiben.jpg', - 'image/character/sp_key_kanade.jpg', - 'image/character/sp_key_yuri.jpg', - 'image/character/sp_kongrong.jpg', - 'image/character/sp_liubei.jpg', - 'image/character/sp_liuqi.jpg', - 'image/character/sp_liuxie.jpg', - 'image/character/sp_lvfan.jpg', - 'image/character/sp_lvmeng.jpg', - 'image/character/sp_machao.jpg', - 'image/character/sp_maojie.jpg', - 'image/character/sp_menghuo.jpg', - 'image/character/sp_mifangfushiren.jpg', - 'image/character/sp_mifuren.jpg', - 'image/character/sp_mushun.jpg', - 'image/character/sp_ol_zhanghe.jpg', - 'image/character/sp_pangde.jpg', - 'image/character/sp_pangtong.jpg', - 'image/character/sp_pengyang.jpg', - 'image/character/sp_shenpei.jpg', - 'image/character/sp_simazhao.jpg', - 'image/character/sp_sufei.jpg', - 'image/character/sp_sunshangxiang.jpg', - 'image/character/sp_sunshao.jpg', - 'image/character/sp_taishici.jpg', - 'image/character/sp_wangcan.jpg', - 'image/character/sp_wangshuang.jpg', - 'image/character/sp_wangyuanji.jpg', - 'image/character/sp_xiahoudun.jpg', - 'image/character/sp_xiahoushi.jpg', - 'image/character/sp_xinpi.jpg', - 'image/character/sp_xinxianying.jpg', - 'image/character/sp_xujing.jpg', - 'image/character/sp_xunchen.jpg', - 'image/character/sp_xuyou.jpg', - 'image/character/sp_yanghu.jpg', - 'image/character/sp_yangwan.jpg', - 'image/character/sp_zhangchangpu.jpg', - 'image/character/sp_zhangfei.jpg', - 'image/character/sp_zhanghe.jpg', - 'image/character/sp_zhangjiao.jpg', - 'image/character/sp_zhangliao.jpg', - 'image/character/sp_zhangwen.jpg', - 'image/character/sp_zhaoyun.jpg', - 'image/character/sp_zhugeliang.jpg', - 'image/character/sp_zhujun.jpg', - 'image/character/sp_zongyu.jpg', - 'image/character/star_caoren.jpg', - 'image/character/star_dongzhuo.jpg', - 'image/character/star_yuanshao.jpg', - 'image/character/star_yuanshu.jpg', - 'image/character/star_zhangchunhua.jpg', - 'image/character/std_panfeng.jpg', - 'image/character/sunce.jpg', - 'image/character/sunchen.jpg', - 'image/character/sundeng.jpg', - 'image/character/sunhanhua.jpg', - 'image/character/sunhao.jpg', - 'image/character/sunhong.jpg', - 'image/character/sunhuan.jpg', - 'image/character/sunjian.jpg', - 'image/character/sunlang.jpg', - 'image/character/sunli.jpg', - 'image/character/sunliang.jpg', - 'image/character/sunlingluan.jpg', - 'image/character/sunluban.jpg', - 'image/character/sunluyu.jpg', - 'image/character/sunqian.jpg', - 'image/character/sunquan.jpg', - 'image/character/sunru.jpg', - 'image/character/sunshangxiang.jpg', - 'image/character/sunshao.jpg', - 'image/character/sunwukong.jpg', - 'image/character/sunxiu.jpg', - 'image/character/sunyang.jpg', - 'image/character/sunyi.jpg', - 'image/character/sunyu.jpg', - 'image/character/sunziliufang.jpg', - 'image/character/swd_anka.jpg', - 'image/character/swd_chenfu.jpg', - 'image/character/swd_chengyaojin.jpg', - 'image/character/swd_chenjingchou.jpg', - 'image/character/swd_cheyun.jpg', - 'image/character/swd_chunyuheng.jpg', - 'image/character/swd_duanmeng.jpg', - 'image/character/swd_duguningke.jpg', - 'image/character/swd_duopeng.jpg', - 'image/character/swd_fengtianling.jpg', - 'image/character/swd_fengyu.jpg', - 'image/character/swd_fu.jpg', - 'image/character/swd_fuyan.jpg', - 'image/character/swd_guyue.jpg', - 'image/character/swd_haidapang.jpg', - 'image/character/swd_hanlong.jpg', - 'image/character/swd_hanluo.jpg', - 'image/character/swd_hengai.jpg', - 'image/character/swd_huanglei.jpg', - 'image/character/swd_huanyuanzhi.jpg', - 'image/character/swd_huiyan.jpg', - 'image/character/swd_hupo.jpg', - 'image/character/swd_huyue.jpg', - 'image/character/swd_huzhongxian.jpg', - 'image/character/swd_jialanduo.jpg', - 'image/character/swd_jiangwu.jpg', - 'image/character/swd_jiangziya.jpg', - 'image/character/swd_jiliang.jpg', - 'image/character/swd_jipeng.jpg', - 'image/character/swd_jiting.jpg', - 'image/character/swd_jiuyou.jpg', - 'image/character/swd_kama.jpg', - 'image/character/swd_kangnalishi.jpg', - 'image/character/swd_kendi.jpg', - 'image/character/swd_lanmoshen.jpg', - 'image/character/swd_lanyin.jpg', - 'image/character/swd_lilian.jpg', - 'image/character/swd_linyue.jpg', - 'image/character/swd_luchengxuan.jpg', - 'image/character/swd_maixing.jpg', - 'image/character/swd_miles.jpg', - 'image/character/swd_moye.jpg', - 'image/character/swd_murongshi.jpg', - 'image/character/swd_muyue.jpg', - 'image/character/swd_muyun.jpg', - 'image/character/swd_nicole.jpg', - 'image/character/swd_qi.jpg', - 'image/character/swd_qiner.jpg', - 'image/character/swd_qinshubao.jpg', - 'image/character/swd_quxian.jpg', - 'image/character/swd_rongshuang.jpg', - 'image/character/swd_septem.jpg', - 'image/character/swd_shangzhang.jpg', - 'image/character/swd_shanxiaoxiao.jpg', - 'image/character/swd_shaowei.jpg', - 'image/character/swd_shuijing.jpg', - 'image/character/swd_shuwaner.jpg', - 'image/character/swd_sikongyu.jpg', - 'image/character/swd_situqiang.jpg', - 'image/character/swd_tuobayuer.jpg', - 'image/character/swd_tuwei.jpg', - 'image/character/swd_wangsiyue.jpg', - 'image/character/swd_weida.jpg', - 'image/character/swd_wushi.jpg', - 'image/character/swd_xiaohuanglong.jpg', - 'image/character/swd_xiarou.jpg', - 'image/character/swd_xiyan.jpg', - 'image/character/swd_xuanyuanjiantong.jpg', - 'image/character/swd_xuanyuanjianxian.jpg', - 'image/character/swd_yeyaxi.jpg', - 'image/character/swd_youzhao.jpg', - 'image/character/swd_yuchiyanhong.jpg', - 'image/character/swd_yuli.jpg', - 'image/character/swd_yunhu.jpg', - 'image/character/swd_yuwentuo.jpg', - 'image/character/swd_yuxiaoxue.jpg', - 'image/character/swd_zhanggao.jpg', - 'image/character/swd_zhaoyun.jpg', - 'image/character/swd_zhiyin.jpg', - 'image/character/swd_zhuoshanzhu.jpg', - 'image/character/swd_zidashu.jpg', - 'image/character/swd_ziqiao.jpg', - 'image/character/tadun.jpg', - 'image/character/taishici.jpg', - 'image/character/tangji.jpg', - 'image/character/tangzi.jpg', - 'image/character/taoqian.jpg', - 'image/character/taoshen.jpg', - 'image/character/tengfanglan.jpg', - 'image/character/tenggongzhu.jpg', - 'image/character/tengyin.jpg', - 'image/character/tianchou.jpg', - 'image/character/tianfeng.jpg', - 'image/character/tianshangyi.jpg', - 'image/character/tianyu.jpg', - 'image/character/tongyuan.jpg', - 'image/character/tw_baoxin.jpg', - 'image/character/tw_beimihu.jpg', - 'image/character/tw_bianfuren.jpg', - 'image/character/tw_bingyuan.jpg', - 'image/character/tw_caoang.jpg', - 'image/character/tw_caocao.jpg', - 'image/character/tw_caohong.jpg', - 'image/character/tw_caoxiu.jpg', - 'image/character/tw_caozhao.jpg', - 'image/character/tw_chendong.jpg', - 'image/character/tw_chengpu.jpg', - 'image/character/tw_chenzhen.jpg', - 'image/character/tw_daxiaoqiao.jpg', - 'image/character/tw_dengzhi.jpg', - 'image/character/tw_dingfeng.jpg', - 'image/character/tw_dongzhao.jpg', - 'image/character/tw_fanchou.jpg', - 'image/character/tw_feiyi.jpg', - 'image/character/tw_fengxí.jpg', - 'image/character/tw_furong.jpg', - 'image/character/tw_fuwan.jpg', - 'image/character/tw_gexuan.jpg', - 'image/character/tw_gongsunfan.jpg', - 'image/character/tw_guanqiujian.jpg', - 'image/character/tw_guohuai.jpg', - 'image/character/tw_guyong.jpg', - 'image/character/tw_handang.jpg', - 'image/character/tw_haomeng.jpg', - 'image/character/tw_hejin.jpg', - 'image/character/tw_hucheer.jpg', - 'image/character/tw_huchuquan.jpg', - 'image/character/tw_huojun.jpg', - 'image/character/tw_jiangji.jpg', - 'image/character/tw_jiangqing.jpg', - 'image/character/tw_jianshuo.jpg', - 'image/character/tw_jiling.jpg', - 'image/character/tw_liufuren.jpg', - 'image/character/tw_liuhong.jpg', - 'image/character/tw_liuzhang.jpg', - 'image/character/tw_liwei.jpg', - 'image/character/tw_madai.jpg', - 'image/character/tw_maliang.jpg', - 'image/character/tw_mateng.jpg', - 'image/character/tw_mayunlu.jpg', - 'image/character/tw_menghuo.jpg', - 'image/character/tw_niufudongxie.jpg', - 'image/character/tw_niujin.jpg', - 'image/character/tw_ol_sunjian.jpg', - 'image/character/tw_puyangxing.jpg', - 'image/character/tw_qiaogong.jpg', - 'image/character/tw_qiaorui.jpg', - 'image/character/tw_re_caohong.jpg', - 'image/character/tw_re_fazheng.jpg', - 'image/character/tw_shen_guanyu.jpg', - 'image/character/tw_shen_lvmeng.jpg', - 'image/character/tw_sunyi.jpg', - 'image/character/tw_tianyu.jpg', - 'image/character/tw_wangcan.jpg', - 'image/character/tw_wangchang.jpg', - 'image/character/tw_wangling.jpg', - 'image/character/tw_weixu.jpg', - 'image/character/tw_wujing.jpg', - 'image/character/tw_xiahouba.jpg', - 'image/character/tw_xiahouen.jpg', - 'image/character/tw_xiahoushang.jpg', - 'image/character/tw_xuezong.jpg', - 'image/character/tw_xujing.jpg', - 'image/character/tw_xunchen.jpg', - 'image/character/tw_yangang.jpg', - 'image/character/tw_yangyi.jpg', - 'image/character/tw_yanxiang.jpg', - 'image/character/tw_yl_luzhi.jpg', - 'image/character/tw_yufuluo.jpg', - 'image/character/tw_yujin.jpg', - 'image/character/tw_zangba.jpg', - 'image/character/tw_zhangfei.jpg', - 'image/character/tw_zhanghong.jpg', - 'image/character/tw_zhangji.jpg', - 'image/character/tw_zhangmancheng.jpg', - 'image/character/tw_zhangnan.jpg', - 'image/character/tw_zhangning.jpg', - 'image/character/tw_zhangzhao.jpg', - 'image/character/tw_zhaoxiang.jpg', - 'image/character/tw_zhouchu.jpg', - 'image/character/tw_zhugeguo.jpg', - 'image/character/tw_zongyu.jpg', - 'image/character/tw_zumao.jpg', - 'image/character/vtb_xiaojiu.jpg', - 'image/character/vtb_xiaole.jpg', - 'image/character/vtb_xiaosha.jpg', - 'image/character/vtb_xiaoshan.jpg', - 'image/character/vtb_xiaotao.jpg', - 'image/character/wangcan.jpg', - 'image/character/wangfuzhaolei.jpg', - 'image/character/wangguan.jpg', - 'image/character/wangji.jpg', - 'image/character/wangjun.jpg', - 'image/character/wanglang.jpg', - 'image/character/wanglie.jpg', - 'image/character/wangling.jpg', - 'image/character/wangping.jpg', - 'image/character/wangrong.jpg', - 'image/character/wangshuang.jpg', - 'image/character/wangtao.jpg', - 'image/character/wangwei.jpg', - 'image/character/wangxiang.jpg', - 'image/character/wangyan.jpg', - 'image/character/wangyi.jpg', - 'image/character/wangyuanji.jpg', - 'image/character/wangyue.jpg', - 'image/character/wangyun.jpg', - 'image/character/wanniangongzhu.jpg', - 'image/character/weiguan.jpg', - 'image/character/weiwenzhugezhi.jpg', - 'image/character/weiyan.jpg', - 'image/character/weizi.jpg', - 'image/character/wenpin.jpg', - 'image/character/wenqin.jpg', - 'image/character/wenyang.jpg', - 'image/character/wolongfengchu.jpg', - 'image/character/wu_luxun.jpg', - 'image/character/wu_zhugeliang.jpg', - 'image/character/wu_zhutiexiong.jpg', - 'image/character/wuanguo.jpg', - 'image/character/wuban.jpg', - 'image/character/wufan.jpg', - 'image/character/wuguotai.jpg', - 'image/character/wujing.jpg', - 'image/character/wulan.jpg', - 'image/character/wutugu.jpg', - 'image/character/wuxian.jpg', - 'image/character/wuyan.jpg', - 'image/character/wuyi.jpg', - 'image/character/xf_huangquan.jpg', - 'image/character/xf_sufei.jpg', - 'image/character/xf_tangzi.jpg', - 'image/character/xf_yiji.jpg', - 'image/character/xia_dianwei.jpg', - 'image/character/xia_liubei.jpg', - 'image/character/xia_liyàn.jpg', - 'image/character/xia_lusu.jpg', - 'image/character/xia_tongyuan.jpg', - 'image/character/xia_wangyue.jpg', - 'image/character/xia_xiahoudun.jpg', - 'image/character/xia_xiahousone.jpg', - 'image/character/xia_xiahouzie.jpg', - 'image/character/xia_xushu.jpg', - 'image/character/xia_zhangwei.jpg', - 'image/character/xia_zhaoe.jpg', - 'image/character/xiahouba.jpg', - 'image/character/xiahoudun.jpg', - 'image/character/xiahoujie.jpg', - 'image/character/xiahoulingnv.jpg', - 'image/character/xiahoumao.jpg', - 'image/character/xiahoushi.jpg', - 'image/character/xiahouxuan.jpg', - 'image/character/xiahouyuan.jpg', - 'image/character/xiangchong.jpg', - 'image/character/xianglang.jpg', - 'image/character/xiaoqiao.jpg', - 'image/character/xiaoyuehankehan.jpg', - 'image/character/xielingyu.jpg', - 'image/character/xin_baosanniang.jpg', - 'image/character/xin_caifuren.jpg', - 'image/character/xin_caoxiu.jpg', - 'image/character/xin_caozhang.jpg', - 'image/character/xin_caozhen.jpg', - 'image/character/xin_chengpu.jpg', - 'image/character/xin_fazheng.jpg', - 'image/character/xin_fuhuanghou.jpg', - 'image/character/xin_gaoshun.jpg', - 'image/character/xin_gongsunzan.jpg', - 'image/character/xin_guohuai.jpg', - 'image/character/xin_guozhao.jpg', - 'image/character/xin_guyong.jpg', - 'image/character/xin_handang.jpg', - 'image/character/xin_hansui.jpg', - 'image/character/xin_jianyong.jpg', - 'image/character/xin_jushou.jpg', - 'image/character/xin_liaohua.jpg', - 'image/character/xin_lingtong.jpg', - 'image/character/xin_liru.jpg', - 'image/character/xin_liubiao.jpg', - 'image/character/xin_mamidi.jpg', - 'image/character/xin_masu.jpg', - 'image/character/xin_panzhangmazhong.jpg', - 'image/character/xin_quancong.jpg', - 'image/character/xin_sunliang.jpg', - 'image/character/xin_sunluban.jpg', - 'image/character/xin_sunxiu.jpg', - 'image/character/xin_wuguotai.jpg', - 'image/character/xin_wuyi.jpg', - 'image/character/xin_xiahoudun.jpg', - 'image/character/xin_xusheng.jpg', - 'image/character/xin_xushu.jpg', - 'image/character/xin_yuanshao.jpg', - 'image/character/xin_yufan.jpg', - 'image/character/xin_yuji.jpg', - 'image/character/xin_yujin.jpg', - 'image/character/xin_zhangfei.jpg', - 'image/character/xin_zhangyi.jpg', - 'image/character/xin_zhonghui.jpg', - 'image/character/xin_zhoucang.jpg', - 'image/character/xin_zhoutai.jpg', - 'image/character/xin_zhuhuan.jpg', - 'image/character/xin_zhuran.jpg', - 'image/character/xin_zhuzhi.jpg', - 'image/character/xinchang.jpg', - 'image/character/xingdaorong.jpg', - 'image/character/xinpi.jpg', - 'image/character/xinping.jpg', - 'image/character/xinxianying.jpg', - 'image/character/xizheng.jpg', - 'image/character/xizhicai.jpg', - 'image/character/xuangongzhu.jpg', - 'image/character/xuelingyun.jpg', - 'image/character/xuezong.jpg', - 'image/character/xugong.jpg', - 'image/character/xuhuang.jpg', - 'image/character/xujing.jpg', - 'image/character/xunchen.jpg', - 'image/character/xunyou.jpg', - 'image/character/xunyu.jpg', - 'image/character/xurong.jpg', - 'image/character/xushao.jpg', - 'image/character/xusheng.jpg', - 'image/character/xushi.jpg', - 'image/character/xushu.jpg', - 'image/character/xuyou.jpg', - 'image/character/xuzhu.jpg', - 'image/character/yanbaihu.jpg', - 'image/character/yanfuren.jpg', - 'image/character/yangbiao.jpg', - 'image/character/yangfu.jpg', - 'image/character/yanghong.jpg', - 'image/character/yanghuiyu.jpg', - 'image/character/yangwan.jpg', - 'image/character/yangxiu.jpg', - 'image/character/yangyan.jpg', - 'image/character/yangyi.jpg', - 'image/character/yangzhi.jpg', - 'image/character/yanjun.jpg', - 'image/character/yanpu.jpg', - 'image/character/yanrou.jpg', - 'image/character/yanwen.jpg', - 'image/character/yanxiang.jpg', - 'image/character/yanyan.jpg', - 'image/character/yeshiwen.jpg', - 'image/character/yinfuren.jpg', - 'image/character/yj_caoang.jpg', - 'image/character/yj_caocao.jpg', - 'image/character/yj_caohong.jpg', - 'image/character/yj_dongzhuo.jpg', - 'image/character/yj_ganning.jpg', - 'image/character/yj_huangzhong.jpg', - 'image/character/yj_jiaxu.jpg', - 'image/character/yj_jushou.jpg', - 'image/character/yj_liru.jpg', - 'image/character/yj_qiaozhou.jpg', - 'image/character/yj_sufei.jpg', - 'image/character/yj_weiyan.jpg', - 'image/character/yj_xuhuang.jpg', - 'image/character/yj_xuyou.jpg', - 'image/character/yj_zhangfei.jpg', - 'image/character/yj_zhanghe.jpg', - 'image/character/yj_zhangliao.jpg', - 'image/character/yj_zhenji.jpg', - 'image/character/yj_zhoubuyi.jpg', - 'image/character/yl_luzhi.jpg', - 'image/character/yl_yuanshu.jpg', - 'image/character/yongjian_ganning.jpg', - 'image/character/yuanhuan.jpg', - 'image/character/yuanji.jpg', - 'image/character/yuanshu.jpg', - 'image/character/yuantanyuanshang.jpg', - 'image/character/yuantanyuanxiyuanshang.jpg', - 'image/character/yue_caiwenji.jpg', - 'image/character/yue_daqiao.jpg', - 'image/character/yue_xiaoqiao.jpg', - 'image/character/yue_zhoufei.jpg', - 'image/character/yuechen.jpg', - 'image/character/yuejin.jpg', - 'image/character/yuejiu.jpg', - 'image/character/yufan.jpg', - 'image/character/yuji.jpg', - 'image/character/yujin.jpg', - 'image/character/yujin_yujin.jpg', - 'image/character/yxs_aijiyanhou.jpg', - 'image/character/yxs_baosi.jpg', - 'image/character/yxs_bole.jpg', - 'image/character/yxs_caocao.jpg', - 'image/character/yxs_chengjisihan.jpg', - 'image/character/yxs_chengyaojin.jpg', - 'image/character/yxs_diaochan.jpg', - 'image/character/yxs_direnjie.jpg', - 'image/character/yxs_fuermosi.jpg', - 'image/character/yxs_goujian.jpg', - 'image/character/yxs_guiguzi.jpg', - 'image/character/yxs_handingdun.jpg', - 'image/character/yxs_huamulan.jpg', - 'image/character/yxs_jinke.jpg', - 'image/character/yxs_kaisa.jpg', - 'image/character/yxs_lanlinwang.jpg', - 'image/character/yxs_libai.jpg', - 'image/character/yxs_lishimin.jpg', - 'image/character/yxs_luban.jpg', - 'image/character/yxs_luobinhan.jpg', - 'image/character/yxs_luocheng.jpg', - 'image/character/yxs_luzhishen.jpg', - 'image/character/yxs_lvzhi.jpg', - 'image/character/yxs_meixi.jpg', - 'image/character/yxs_mingchenghuanghou.jpg', - 'image/character/yxs_mozi.jpg', - 'image/character/yxs_nandinggeer.jpg', - 'image/character/yxs_napolun.jpg', - 'image/character/yxs_qinqiong.jpg', - 'image/character/yxs_sunwu.jpg', - 'image/character/yxs_tangbohu.jpg', - 'image/character/yxs_wangzhaojun.jpg', - 'image/character/yxs_weizhongxian.jpg', - 'image/character/yxs_wuzetian.jpg', - 'image/character/yxs_xiangyu.jpg', - 'image/character/yxs_xiaoqiao.jpg', - 'image/character/yxs_yangguang.jpg', - 'image/character/yxs_yangyuhuan.jpg', - 'image/character/yxs_yingzheng.jpg', - 'image/character/yxs_yuefei.jpg', - 'image/character/yxs_yujix.jpg', - 'image/character/yxs_zhangsanfeng.jpg', - 'image/character/yxs_zhaoyong.jpg', - 'image/character/yxs_zhuyuanzhang.jpg', - 'image/character/zangba.jpg', - 'image/character/zerong.jpg', - 'image/character/zhangbao.jpg', - 'image/character/zhangchangpu.jpg', - 'image/character/zhangchu.jpg', - 'image/character/zhangchunhua.jpg', - 'image/character/zhangfei.jpg', - 'image/character/zhangfen.jpg', - 'image/character/zhanggong.jpg', - 'image/character/zhanghe.jpg', - 'image/character/zhangheng.jpg', - 'image/character/zhanghu.jpg', - 'image/character/zhanghua.jpg', - 'image/character/zhanghuyuechen.jpg', - 'image/character/zhangji.jpg', - 'image/character/zhangjiao.jpg', - 'image/character/zhangjinyun.jpg', - 'image/character/zhangkai.jpg', - 'image/character/zhangliang.jpg', - 'image/character/zhangliao.jpg', - 'image/character/zhangling.jpg', - 'image/character/zhanglu.jpg', - 'image/character/zhangmiao.jpg', - 'image/character/zhangning.jpg', - 'image/character/zhangqiying.jpg', - 'image/character/zhangrang.jpg', - 'image/character/zhangren.jpg', - 'image/character/zhangshiping.jpg', - 'image/character/zhangsong.jpg', - 'image/character/zhangwen.jpg', - 'image/character/zhangxingcai.jpg', - 'image/character/zhangxiu.jpg', - 'image/character/zhangxuan.jpg', - 'image/character/zhangxun.jpg', - 'image/character/zhangyan.jpg', - 'image/character/zhangyao.jpg', - 'image/character/zhangyi.jpg', - 'image/character/zhangyì.jpg', - 'image/character/zhangzhang.jpg', - 'image/character/zhangzhi.jpg', - 'image/character/zhangzhongjing.jpg', - 'image/character/zhaoang.jpg', - 'image/character/zhaotongzhaoguang.jpg', - 'image/character/zhaoxiang.jpg', - 'image/character/zhaoyan.jpg', - 'image/character/zhaoyǎn.jpg', - 'image/character/zhaoyun.jpg', - 'image/character/zhaozhi.jpg', - 'image/character/zhaozhong.jpg', - 'image/character/zhenghun.jpg', - 'image/character/zhengxuan.jpg', - 'image/character/zhenji.jpg', - 'image/character/zhonghui.jpg', - 'image/character/zhongyan.jpg', - 'image/character/zhongyao.jpg', - 'image/character/zhoubuyi.jpg', - 'image/character/zhoucang.jpg', - 'image/character/zhouchu.jpg', - 'image/character/zhoufang.jpg', - 'image/character/zhoufei.jpg', - 'image/character/zhouqun.jpg', - 'image/character/zhoushan.jpg', - 'image/character/zhoutai.jpg', - 'image/character/zhouyi.jpg', - 'image/character/zhouyu.jpg', - 'image/character/zhugedan.jpg', - 'image/character/zhugeguo.jpg', - 'image/character/zhugejin.jpg', - 'image/character/zhugeke.jpg', - 'image/character/zhugeliang.jpg', - 'image/character/zhugemengxue.jpg', - 'image/character/zhugeruoxue.jpg', - 'image/character/zhugeshang.jpg', - 'image/character/zhugezhan.jpg', - 'image/character/zhuhuan.jpg', - 'image/character/zhujianping.jpg', - 'image/character/zhujun.jpg', - 'image/character/zhuling.jpg', - 'image/character/zhuran.jpg', - 'image/character/zhurong.jpg', - 'image/character/zhutiexiong.jpg', - 'image/character/zhuzhi.jpg', - 'image/character/zongyu.jpg', - 'image/character/zoushi.jpg', - 'image/character/zumao.jpg', - 'image/character/zuoci.jpg', - 'image/character/zuofen.jpg', - /*character image end*/ - - 'image/emotion/shibing_emotion/1.gif', - 'image/emotion/shibing_emotion/2.gif', - 'image/emotion/shibing_emotion/3.gif', - 'image/emotion/shibing_emotion/4.gif', - 'image/emotion/shibing_emotion/5.gif', - 'image/emotion/shibing_emotion/6.gif', - 'image/emotion/shibing_emotion/7.gif', - 'image/emotion/shibing_emotion/8.gif', - 'image/emotion/shibing_emotion/9.gif', - 'image/emotion/shibing_emotion/10.gif', - 'image/emotion/shibing_emotion/11.gif', - 'image/emotion/shibing_emotion/12.gif', - 'image/emotion/shibing_emotion/13.gif', - 'image/emotion/shibing_emotion/14.gif', - 'image/emotion/shibing_emotion/15.gif', - 'image/emotion/guojia_emotion/1.gif', - 'image/emotion/guojia_emotion/2.gif', - 'image/emotion/guojia_emotion/3.gif', - 'image/emotion/guojia_emotion/4.gif', - 'image/emotion/guojia_emotion/5.gif', - 'image/emotion/guojia_emotion/6.gif', - 'image/emotion/guojia_emotion/7.gif', - 'image/emotion/guojia_emotion/8.gif', - 'image/emotion/guojia_emotion/9.gif', - 'image/emotion/guojia_emotion/10.gif', - 'image/emotion/guojia_emotion/11.gif', - 'image/emotion/guojia_emotion/12.gif', - 'image/emotion/guojia_emotion/13.gif', - 'image/emotion/guojia_emotion/14.gif', - 'image/emotion/guojia_emotion/15.gif', - 'image/emotion/guojia_emotion/16.gif', - 'image/emotion/guojia_emotion/17.gif', - 'image/emotion/guojia_emotion/18.gif', - 'image/emotion/guojia_emotion/19.gif', - 'image/emotion/guojia_emotion/20.gif', - 'image/emotion/zhenji_emotion/1.gif', - 'image/emotion/zhenji_emotion/2.gif', - 'image/emotion/zhenji_emotion/3.gif', - 'image/emotion/zhenji_emotion/4.gif', - 'image/emotion/zhenji_emotion/5.gif', - 'image/emotion/zhenji_emotion/6.gif', - 'image/emotion/zhenji_emotion/7.gif', - 'image/emotion/zhenji_emotion/8.gif', - 'image/emotion/zhenji_emotion/9.gif', - 'image/emotion/zhenji_emotion/10.gif', - 'image/emotion/zhenji_emotion/11.gif', - 'image/emotion/zhenji_emotion/12.gif', - 'image/emotion/zhenji_emotion/13.gif', - 'image/emotion/zhenji_emotion/14.gif', - 'image/emotion/zhenji_emotion/15.gif', - 'image/emotion/zhenji_emotion/16.gif', - 'image/emotion/zhenji_emotion/17.gif', - 'image/emotion/zhenji_emotion/18.gif', - 'image/emotion/zhenji_emotion/19.gif', - 'image/emotion/zhenji_emotion/20.gif', - 'image/emotion/xiaojiu_emotion/1.gif', - 'image/emotion/xiaojiu_emotion/2.gif', - 'image/emotion/xiaojiu_emotion/3.gif', - 'image/emotion/xiaojiu_emotion/4.gif', - 'image/emotion/xiaojiu_emotion/5.gif', - 'image/emotion/xiaojiu_emotion/6.gif', - 'image/emotion/xiaojiu_emotion/7.gif', - 'image/emotion/xiaojiu_emotion/8.gif', - 'image/emotion/xiaojiu_emotion/9.gif', - 'image/emotion/xiaojiu_emotion/10.gif', - 'image/emotion/xiaojiu_emotion/11.gif', - 'image/emotion/xiaojiu_emotion/12.gif', - 'image/emotion/xiaojiu_emotion/13.gif', - 'image/emotion/xiaojiu_emotion/14.gif', - 'image/emotion/xiaojiu_emotion/15.gif', - 'image/emotion/xiaojiu_emotion/16.gif', - 'image/emotion/xiaojiu_emotion/17.gif', - 'image/emotion/xiaojiu_emotion/18.gif', - 'image/emotion/xiaojiu_emotion/19.gif', - 'image/emotion/xiaojiu_emotion/20.gif', - 'image/emotion/xiaokuo_emotion/1.gif', - 'image/emotion/xiaokuo_emotion/2.gif', - 'image/emotion/xiaokuo_emotion/3.gif', - 'image/emotion/xiaokuo_emotion/4.gif', - 'image/emotion/xiaokuo_emotion/5.gif', - 'image/emotion/xiaokuo_emotion/6.gif', - 'image/emotion/xiaokuo_emotion/7.gif', - 'image/emotion/xiaokuo_emotion/8.gif', - 'image/emotion/xiaosha_emotion/1.gif', - 'image/emotion/xiaosha_emotion/2.gif', - 'image/emotion/xiaosha_emotion/3.gif', - 'image/emotion/xiaosha_emotion/4.gif', - 'image/emotion/xiaosha_emotion/5.gif', - 'image/emotion/xiaosha_emotion/6.gif', - 'image/emotion/xiaosha_emotion/7.gif', - 'image/emotion/xiaosha_emotion/8.gif', - 'image/emotion/xiaosha_emotion/9.gif', - 'image/emotion/xiaosha_emotion/10.gif', - 'image/emotion/xiaosha_emotion/11.gif', - 'image/emotion/xiaosha_emotion/12.gif', - 'image/emotion/xiaosha_emotion/13.gif', - 'image/emotion/xiaosha_emotion/14.gif', - 'image/emotion/xiaosha_emotion/15.gif', - 'image/emotion/xiaosha_emotion/16.gif', - 'image/emotion/xiaosha_emotion/17.gif', - 'image/emotion/xiaosha_emotion/18.gif', - 'image/emotion/xiaosha_emotion/19.gif', - 'image/emotion/xiaosha_emotion/20.gif', - 'image/emotion/xiaotao_emotion/1.gif', - 'image/emotion/xiaotao_emotion/2.gif', - 'image/emotion/xiaotao_emotion/3.gif', - 'image/emotion/xiaotao_emotion/4.gif', - 'image/emotion/xiaotao_emotion/5.gif', - 'image/emotion/xiaotao_emotion/6.gif', - 'image/emotion/xiaotao_emotion/7.gif', - 'image/emotion/xiaotao_emotion/8.gif', - 'image/emotion/xiaotao_emotion/9.gif', - 'image/emotion/xiaotao_emotion/10.gif', - 'image/emotion/xiaotao_emotion/11.gif', - 'image/emotion/xiaotao_emotion/12.gif', - 'image/emotion/xiaotao_emotion/13.gif', - 'image/emotion/xiaotao_emotion/14.gif', - 'image/emotion/xiaotao_emotion/15.gif', - 'image/emotion/xiaotao_emotion/16.gif', - 'image/emotion/xiaotao_emotion/17.gif', - 'image/emotion/xiaotao_emotion/18.gif', - 'image/emotion/xiaotao_emotion/19.gif', - 'image/emotion/xiaotao_emotion/20.gif', - 'image/emotion/xiaowu_emotion/1.gif', - 'image/emotion/xiaowu_emotion/2.gif', - 'image/emotion/xiaowu_emotion/3.gif', - 'image/emotion/xiaowu_emotion/4.gif', - 'image/emotion/xiaowu_emotion/5.gif', - 'image/emotion/xiaowu_emotion/6.gif', - 'image/emotion/xiaowu_emotion/7.gif', - 'image/emotion/xiaowu_emotion/8.gif', - 'image/emotion/xiaowu_emotion/9.gif', - 'image/emotion/xiaowu_emotion/10.gif', - 'image/emotion/xiaowu_emotion/11.gif', - 'image/emotion/xiaowu_emotion/12.gif', - 'image/emotion/xiaowu_emotion/13.gif', - 'image/emotion/xiaowu_emotion/14.gif', - 'image/emotion/throw_emotion/egg1.png', - 'image/emotion/throw_emotion/egg2.png', - 'image/emotion/throw_emotion/flower1.png', - 'image/emotion/throw_emotion/flower2.png', - 'image/emotion/throw_emotion/shoe1.png', - 'image/emotion/throw_emotion/shoe2.png', - 'image/emotion/throw_emotion/jiasuo1.png', - 'image/emotion/throw_emotion/jiasuo2.png', - 'image/emotion/throw_emotion/wine1.png', - 'image/emotion/throw_emotion/wine2.png', - 'image/emotion/throw_emotion/yuxisx1.png', - 'image/emotion/throw_emotion/yuxisx2.png', - - 'image/mode/boss/card/chixueqingfeng.png', - 'image/mode/boss/card/chiyanzhenhunqin.png', - 'image/mode/boss/card/guilongzhanyuedao.png', - 'image/mode/boss/card/guofengyupao.png', - 'image/mode/boss/card/honghuangzhili.png', - 'image/mode/boss/card/hongmianbaihuapao.png', - 'image/mode/boss/card/juechenjinge.png', - 'image/mode/boss/card/linglongshimandai.png', - 'image/mode/boss/card/qimenbagua.png', - 'image/mode/boss/card/sadouchengbing.png', - 'image/mode/boss/card/shufazijinguan.png', - 'image/mode/boss/card/wushuangfangtianji.png', - 'image/mode/boss/card/xiuluolianyuji.png', - 'image/mode/boss/card/xuwangzhimian.png', - 'image/mode/boss/card/yihuajiemu.png', - 'image/mode/boss/card/qicaishenlu.png', - 'image/mode/boss/card/longfenghemingjian.png', - 'image/mode/boss/card/boss_mengpohuihun.png', - 'image/mode/boss/card/gubuzifeng.png', - 'image/mode/boss/card/jinwuluorigong.png', - 'image/mode/boss/card/lingsheji.png', - 'image/mode/boss/card/shanrangzhaoshu.png', - 'image/mode/boss/card/xingtianpojunfu.png', - 'image/mode/boss/card/niaobaidaowenha.png', - - 'image/mode/boss/character/boss_baihu.jpg', - 'image/mode/boss/character/boss_baimangshilian.jpg', - 'image/mode/boss/character/boss_baiwuchang.jpg', - 'image/mode/boss/character/boss_bianchengwang.jpg', - 'image/mode/boss/character/boss_bifang.jpg', - 'image/mode/boss/character/boss_caiwenji.jpg', - 'image/mode/boss/character/boss_caocao.jpg', - 'image/mode/boss/character/boss_chi.jpg', - 'image/mode/boss/character/boss_chiyanshilian.jpg', - 'image/mode/boss/character/boss_chujiangwang.jpg', - 'image/mode/boss/character/boss_diaochan.jpg', - 'image/mode/boss/character/boss_dizangwang.jpg', - 'image/mode/boss/character/boss_dongzhuo.jpg', - 'image/mode/boss/character/boss_dushiwang.jpg', - 'image/mode/boss/character/boss_guojia.jpg', - 'image/mode/boss/character/boss_heiwuchang.jpg', - 'image/mode/boss/character/boss_huangyueying.jpg', - 'image/mode/boss/character/boss_huatuo.jpg', - 'image/mode/boss/character/boss_hundun.jpg', - 'image/mode/boss/character/boss_huoshenzhurong.jpg', - 'image/mode/boss/character/boss_jinshenrushou.jpg', - 'image/mode/boss/character/boss_liang.jpg', - 'image/mode/boss/character/boss_liubei.jpg', - 'image/mode/boss/character/boss_luocha.jpg', - 'image/mode/boss/character/boss_luxun.jpg', - 'image/mode/boss/character/boss_lvbu1.jpg', - 'image/mode/boss/character/boss_lvbu2.jpg', - 'image/mode/boss/character/boss_lvbu3.jpg', - 'image/mode/boss/character/boss_mamian.jpg', - 'image/mode/boss/character/boss_mengpo.jpg', - 'image/mode/boss/character/boss_mingxingzhu.jpg', - 'image/mode/boss/character/boss_mo.jpg', - 'image/mode/boss/character/boss_mushengoumang.jpg', - 'image/mode/boss/character/boss_nianshou.jpg', - 'image/mode/boss/character/boss_nianshou_baonu.jpg', - 'image/mode/boss/character/boss_nianshou_heti.jpg', - 'image/mode/boss/character/boss_nianshou_jingjue.jpg', - 'image/mode/boss/character/boss_nianshou_renxing.jpg', - 'image/mode/boss/character/boss_nianshou_ruizhi.jpg', - 'image/mode/boss/character/boss_niutou.jpg', - 'image/mode/boss/character/boss_pangtong.jpg', - 'image/mode/boss/character/boss_pingdengwang.jpg', - 'image/mode/boss/character/boss_qinglong.jpg', - 'image/mode/boss/character/boss_qingmushilian.jpg', - 'image/mode/boss/character/boss_qinguangwang.jpg', - 'image/mode/boss/character/boss_qiongqi.jpg', - 'image/mode/boss/character/boss_satan.jpg', - 'image/mode/boss/character/boss_shaohao.jpg', - 'image/mode/boss/character/boss_shuijing.jpg', - 'image/mode/boss/character/boss_shuishengonggong.jpg', - 'image/mode/boss/character/boss_shuishenxuanming.jpg', - 'image/mode/boss/character/boss_shujing.jpg', - 'image/mode/boss/character/boss_songdiwang.jpg', - 'image/mode/boss/character/boss_sunshangxiang.jpg', - 'image/mode/boss/character/boss_taihao.jpg', - 'image/mode/boss/character/boss_taishanwang.jpg', - 'image/mode/boss/character/boss_taotie.jpg', - 'image/mode/boss/character/boss_taowu.jpg', - 'image/mode/boss/character/boss_wang.jpg', - 'image/mode/boss/character/boss_wuguanwang.jpg', - 'image/mode/boss/character/boss_xiangliu.jpg', - 'image/mode/boss/character/boss_xuanlinshilian.jpg', - 'image/mode/boss/character/boss_xuanwu.jpg', - 'image/mode/boss/character/boss_yandi.jpg', - 'image/mode/boss/character/boss_yanling.jpg', - 'image/mode/boss/character/boss_yanluowang.jpg', - 'image/mode/boss/character/boss_yecha.jpg', - 'image/mode/boss/character/boss_yingzhao.jpg', - 'image/mode/boss/character/boss_yuji.jpg', - 'image/mode/boss/character/boss_zhangchunhua.jpg', - 'image/mode/boss/character/boss_zhangjiao.jpg', - 'image/mode/boss/character/boss_zhenji.jpg', - 'image/mode/boss/character/boss_zhouyu.jpg', - 'image/mode/boss/character/boss_zhuanlunwang.jpg', - 'image/mode/boss/character/boss_zhuanxu.jpg', - 'image/mode/boss/character/boss_zhugeliang.jpg', - 'image/mode/boss/character/boss_zhuoguiquxie.jpg', - 'image/mode/boss/character/boss_zhuque.jpg', - 'image/mode/boss/character/boss_zhuyan.jpg', - 'image/mode/boss/character/boss_zhuyin.jpg', - 'image/mode/boss/character/boss_zuoci.jpg', - - 'image/mode/chess/card/chess_chuzhang.png', - 'image/mode/chess/card/chess_shezhang.png', - 'image/mode/chess/character/chess_beimingjukun.jpg', - 'image/mode/chess/character/chess_caocao.jpg', - 'image/mode/chess/character/chess_diaochan.jpg', - 'image/mode/chess/character/chess_dongzhuo.jpg', - 'image/mode/chess/character/chess_huangzhong.jpg', - 'image/mode/chess/character/chess_huatuo.jpg', - 'image/mode/chess/character/chess_jinchidiao.jpg', - 'image/mode/chess/character/chess_sunshangxiang.jpg', - 'image/mode/chess/character/chess_taishici.jpg', - 'image/mode/chess/character/chess_wuzhaojinlong.jpg', - 'image/mode/chess/character/chess_xingtian.jpg', - 'image/mode/chess/character/chess_zhangliao.jpg', - 'image/mode/chess/character/leader_caocao.jpg', - 'image/mode/chess/character/leader_liubei.jpg', - 'image/mode/chess/character/leader_sunquan.jpg', - 'image/mode/chess/character/leader_yuri.jpg', - 'image/mode/chess/difficulty/leader_easy.jpg', - 'image/mode/chess/difficulty/leader_hard.jpg', - 'image/mode/chess/difficulty/leader_medium.jpg', - 'image/mode/stone/card/spell_ansezhadan.jpg', - 'image/mode/stone/card/spell_anyingkuangluan.jpg', - 'image/mode/stone/card/spell_anyinglieyan.jpg', - 'image/mode/stone/card/spell_anyingxingtai.jpg', - 'image/mode/stone/card/spell_anzhongpohuai.jpg', - 'image/mode/stone/card/spell_aoshufeidan.jpg', - 'image/mode/stone/card/spell_aoshuzhihui.jpg', - 'image/mode/stone/card/spell_baofengxue.jpg', - 'image/mode/stone/card/spell_beici.jpg', - 'image/mode/stone/card/spell_bianxingshu.jpg', - 'image/mode/stone/card/spell_bingdong.jpg', - 'image/mode/stone/card/spell_binghuan.jpg', - 'image/mode/stone/card/spell_canying.jpg', - 'image/mode/stone/card/spell_chazhuangshandian.jpg', - 'image/mode/stone/card/spell_chenmo.jpg', - 'image/mode/stone/card/spell_chirehuoba.jpg', - 'image/mode/stone/card/spell_chongfeng.jpg', - 'image/mode/stone/card/spell_cigu.jpg', - 'image/mode/stone/card/spell_cisha.jpg', - 'image/mode/stone/card/spell_conglinzhihun.jpg', - 'image/mode/stone/card/spell_daoshan.jpg', - 'image/mode/stone/card/spell_diyulieyan.jpg', - 'image/mode/stone/card/spell_dubiao.jpg', - 'image/mode/stone/card/spell_dunpaimengji.jpg', - 'image/mode/stone/card/spell_duochongsheji.jpg', - 'image/mode/stone/card/spell_emozhinu.jpg', - 'image/mode/stone/card/spell_emozhixin.jpg', - 'image/mode/stone/card/spell_enzeshu.jpg', - 'image/mode/stone/card/spell_fengnu.jpg', - 'image/mode/stone/card/spell_fengxian.jpg', - 'image/mode/stone/card/spell_fennu.jpg', - 'image/mode/stone/card/spell_fennuzhichui.jpg', - 'image/mode/stone/card/spell_fuchoudaji.jpg', - 'image/mode/stone/card/spell_fuchouzhinu.jpg', - 'image/mode/stone/card/spell_fugen.jpg', - 'image/mode/stone/card/spell_fushishu.jpg', - 'image/mode/stone/card/spell_guanmenfanggou.jpg', - 'image/mode/stone/card/spell_hanbingjian.jpg', - 'image/mode/stone/card/spell_hanbingpingzhang.jpg', - 'image/mode/stone/card/spell_heiandiyu.jpg', - 'image/mode/stone/card/spell_heianqiyue.jpg', - 'image/mode/stone/card/spell_hengsao.jpg', - 'image/mode/stone/card/spell_huoqiushu.jpg', - 'image/mode/stone/card/spell_huotigenxu.jpg', - 'image/mode/stone/card/spell_jianrenluanwu.jpg', - 'image/mode/stone/card/spell_jingshenkongzhi.jpg', - 'image/mode/stone/card/spell_jingxiang.jpg', - 'image/mode/stone/card/spell_jinyingduijue.jpg', - 'image/mode/stone/card/spell_jipao.jpg', - 'image/mode/stone/card/spell_juemingluandou.jpg', - 'image/mode/stone/card/spell_kongxinshu.jpg', - 'image/mode/stone/card/spell_kuaisusheji.jpg', - 'image/mode/stone/card/spell_kuaisuzhiliao.jpg', - 'image/mode/stone/card/spell_kuangbao.jpg', - 'image/mode/stone/card/spell_laojiuhuoba.jpg', - 'image/mode/stone/card/spell_lianhuanbaolie.jpg', - 'image/mode/stone/card/spell_lierenyinji.jpg', - 'image/mode/stone/card/spell_lieyanfengbao.jpg', - 'image/mode/stone/card/spell_liliangdaijia.jpg', - 'image/mode/stone/card/spell_liliangzhufu.jpg', - 'image/mode/stone/card/spell_linghunhongxi.jpg', - 'image/mode/stone/card/spell_maizang.jpg', - 'image/mode/stone/card/spell_mengun.jpg', - 'image/mode/stone/card/spell_modaoyou.jpg', - 'image/mode/stone/card/spell_morizaihuo.jpg', - 'image/mode/stone/card/spell_naluzhiguang.jpg', - 'image/mode/stone/card/spell_niuquxukong.jpg', - 'image/mode/stone/card/spell_nuhuozhongshao.jpg', - 'image/mode/stone/card/spell_nuxi.jpg', - 'image/mode/stone/card/spell_piaoqie.jpg', - 'image/mode/stone/card/spell_qiangfengsheji.jpg', - 'image/mode/stone/card/spell_rongyanbaolie.jpg', - 'image/mode/stone/card/spell_sanghunzhao.jpg', - 'image/mode/stone/card/spell_shalumingling.jpg', - 'image/mode/stone/card/spell_shandianfengbao.jpg', - 'image/mode/stone/card/spell_shengerpingdeng.jpg', - 'image/mode/stone/card/spell_shengguangzhadan.jpg', - 'image/mode/stone/card/spell_shengliaoshu.jpg', - 'image/mode/stone/card/spell_shenpan.jpg', - 'image/mode/stone/card/spell_shenshengfennu.jpg', - 'image/mode/stone/card/spell_shenshengxinxing.jpg', - 'image/mode/stone/card/spell_shihuawuqi.jpg', - 'image/mode/stone/card/spell_shixue.jpg', - 'image/mode/stone/card/spell_sijidaifa.jpg', - 'image/mode/stone/card/spell_siwangchanrao.jpg', - 'image/mode/stone/card/spell_tanxianmao.jpg', - 'image/mode/stone/card/spell_tianjiangzhuqun.jpg', - 'image/mode/stone/card/spell_wangzhezhufu.jpg', - 'image/mode/stone/card/spell_weijisifu.jpg', - 'image/mode/stone/card/spell_wuyashenxiang.jpg', - 'image/mode/stone/card/spell_xianzuzhaohuan.jpg', - 'image/mode/stone/card/spell_xianzuzhihun.jpg', - 'image/mode/stone/card/spell_xianzuzhiliao.jpg', - 'image/mode/stone/card/spell_xianzuzhishi.jpg', - 'image/mode/stone/card/spell_xiaoguibaopo.jpg', - 'image/mode/stone/card/spell_xiaoshi.jpg', - 'image/mode/stone/card/spell_xingchenzhuiluo.jpg', - 'image/mode/stone/card/spell_xinlinghanbao.jpg', - 'image/mode/stone/card/spell_xinlingshijie.jpg', - 'image/mode/stone/card/spell_xishengqiyue.jpg', - 'image/mode/stone/card/spell_xuanfengzhan.jpg', - 'image/mode/stone/card/spell_yanbaoshu.jpg', - 'image/mode/stone/card/spell_yanmie.jpg', - 'image/mode/stone/card/spell_yaoshu.jpg', - 'image/mode/stone/card/spell_yemanpaoxiao.jpg', - 'image/mode/stone/card/spell_yexingchengzhang.jpg', - 'image/mode/stone/card/spell_yexinglanghun.jpg', - 'image/mode/stone/card/spell_yingyongdaji.jpg', - 'image/mode/stone/card/spell_yongshizhufu.jpg', - 'image/mode/stone/card/spell_zhandounuhuo.jpg', - 'image/mode/stone/card/spell_zhansha.jpg', - 'image/mode/stone/card/spell_zhaohuanchongwu.jpg', - 'image/mode/stone/card/spell_zhengqianghaosheng.jpg', - 'image/mode/stone/card/spell_zhenyanshu.jpg', - 'image/mode/stone/card/spell_zhihuizhufu.jpg', - 'image/mode/stone/card/spell_zhiliaoshui.jpg', - 'image/mode/stone/card/spell_zhiliaozhichu.jpg', - 'image/mode/stone/card/spell_zhiliaozhihuan.jpg', - 'image/mode/stone/card/spell_zhongnian.jpg', - 'image/mode/stone/card/spell_zhuizongshu.jpg', - 'image/mode/stone/card/spell_zhumo.jpg', - 'image/mode/stone/card/spell_zidanshangtang.jpg', - 'image/mode/stone/card/spell_ziranzhili.jpg', - 'image/mode/stone/card/spell_ziyang.jpg', - 'image/mode/stone/card/spell_zuozhandongyuan.jpg', - 'image/mode/stone/card/spell_zuzhou.jpg', - 'image/mode/stone/career/druid.png', - 'image/mode/stone/career/hunter.png', - 'image/mode/stone/career/knight.png', - 'image/mode/stone/career/mage.png', - 'image/mode/stone/career/paladin.png', - 'image/mode/stone/career/priest.png', - 'image/mode/stone/career/rogue.png', - 'image/mode/stone/career/shaman.png', - 'image/mode/stone/career/warlock.png', - 'image/mode/stone/career/warrior.png', - 'image/mode/stone/character/stone_aidewen.jpg', - 'image/mode/stone/character/stone_aihaozhihun.jpg', - 'image/mode/stone/character/stone_alaikesita.jpg', - 'image/mode/stone/character/stone_andongni.jpg', - 'image/mode/stone/character/stone_anyingzisi.jpg', - 'image/mode/stone/character/stone_aolajier.jpg', - 'image/mode/stone/character/stone_aomishouwei.jpg', - 'image/mode/stone/character/stone_aoshushi.jpg', - 'image/mode/stone/character/stone_baohuzhishu.jpg', - 'image/mode/stone/character/stone_baoqishi.jpg', - 'image/mode/stone/character/stone_baoweizhe.jpg', - 'image/mode/stone/character/stone_beijunmushi.jpg', - 'image/mode/stone/character/stone_caoyuanshi.jpg', - 'image/mode/stone/character/stone_chidunshinv.jpg', - 'image/mode/stone/character/stone_chidunweishi.jpg', - 'image/mode/stone/character/stone_chilundashi.jpg', - 'image/mode/stone/character/stone_cike.jpg', - 'image/mode/stone/character/stone_conglinshouwei.jpg', - 'image/mode/stone/character/stone_conglinxiaoshou.jpg', - 'image/mode/stone/character/stone_damoshatuo.jpg', - 'image/mode/stone/character/stone_daomufeizei.jpg', - 'image/mode/stone/character/stone_dijieshicong.jpg', - 'image/mode/stone/character/stone_diyuhuo.jpg', - 'image/mode/stone/character/stone_diyuhuox.jpg', - 'image/mode/stone/character/stone_duyanhaidao.jpg', - 'image/mode/stone/character/stone_fachao.jpg', - 'image/mode/stone/character/stone_falifulong.jpg', - 'image/mode/stone/character/stone_famingjia.jpg', - 'image/mode/stone/character/stone_faqishi.jpg', - 'image/mode/stone/character/stone_fatiaozhuru.jpg', - 'image/mode/stone/character/stone_fennuxiaoji.jpg', - 'image/mode/stone/character/stone_fuding.jpg', - 'image/mode/stone/character/stone_fuhuokaijia.jpg', - 'image/mode/stone/character/stone_fukongmoyan.jpg', - 'image/mode/stone/character/stone_gangtiewushi.jpg', - 'image/mode/stone/character/stone_geluomashi.jpg', - 'image/mode/stone/character/stone_guangmingquan.jpg', - 'image/mode/stone/character/stone_guangyaozhizi.jpg', - 'image/mode/stone/character/stone_guanliyuan.jpg', - 'image/mode/stone/character/stone_guiqishi.jpg', - 'image/mode/stone/character/stone_haidao.jpg', - 'image/mode/stone/character/stone_haidaotoumu.jpg', - 'image/mode/stone/character/stone_hanguangzhizhe.jpg', - 'image/mode/stone/character/stone_heianjiaotu.jpg', - 'image/mode/stone/character/stone_heishitanfan.jpg', - 'image/mode/stone/character/stone_heitieairen.jpg', - 'image/mode/stone/character/stone_heiyaoyaoshou.jpg', - 'image/mode/stone/character/stone_honglongyongshi.jpg', - 'image/mode/stone/character/stone_huangjialeixiang.jpg', - 'image/mode/stone/character/stone_huangyeqishi.jpg', - 'image/mode/stone/character/stone_hudunren.jpg', - 'image/mode/stone/character/stone_huofu.jpg', - 'image/mode/stone/character/stone_huoli.jpg', - 'image/mode/stone/character/stone_huoqiangshou.jpg', - 'image/mode/stone/character/stone_huoshanxiemu.jpg', - 'image/mode/stone/character/stone_huoshe.jpg', - 'image/mode/stone/character/stone_huoyanweishi.jpg', - 'image/mode/stone/character/stone_huoyao.jpg', - 'image/mode/stone/character/stone_huoyuansu.jpg', - 'image/mode/stone/character/stone_jialakesi.jpg', - 'image/mode/stone/character/stone_jialakesix.jpg', - 'image/mode/stone/character/stone_jiangong.jpg', - 'image/mode/stone/character/stone_jiewangzhu.jpg', - 'image/mode/stone/character/stone_jingxiang.jpg', - 'image/mode/stone/character/stone_jingyingweishi.jpg', - 'image/mode/stone/character/stone_jujishou.jpg', - 'image/mode/stone/character/stone_junxuguan.jpg', - 'image/mode/stone/character/stone_juxingchanchu.jpg', - 'image/mode/stone/character/stone_kaodalalong.jpg', - 'image/mode/stone/character/stone_kelushi.jpg', - 'image/mode/stone/character/stone_kongjuzhanma.jpg', - 'image/mode/stone/character/stone_kuangyedoushi.jpg', - 'image/mode/stone/character/stone_kuangzhanshi.jpg', - 'image/mode/stone/character/stone_kutongsiseng.jpg', - 'image/mode/stone/character/stone_langren.jpg', - 'image/mode/stone/character/stone_lansaizhanshi.jpg', - 'image/mode/stone/character/stone_leiouke.jpg', - 'image/mode/stone/character/stone_liebao.jpg', - 'image/mode/stone/character/stone_liegou.jpg', - 'image/mode/stone/character/stone_liewangshouwei.jpg', - 'image/mode/stone/character/stone_lieyanxiaogui.jpg', - 'image/mode/stone/character/stone_lifaji.jpg', - 'image/mode/stone/character/stone_lindishuyao.jpg', - 'image/mode/stone/character/stone_linghunjisi.jpg', - 'image/mode/stone/character/stone_longmianjiaoguan.jpg', - 'image/mode/stone/character/stone_longwangpeiou.jpg', - 'image/mode/stone/character/stone_mafengzhuru.jpg', - 'image/mode/stone/character/stone_maligousi.jpg', - 'image/mode/stone/character/stone_meimo.jpg', - 'image/mode/stone/character/stone_mengmaren.jpg', - 'image/mode/stone/character/stone_mianyang.jpg', - 'image/mode/stone/character/stone_mingguangjisi.jpg', - 'image/mode/stone/character/stone_misha.jpg', - 'image/mode/stone/character/stone_morishouwei.jpg', - 'image/mode/stone/character/stone_muguangchulong.jpg', - 'image/mode/stone/character/stone_muyangren.jpg', - 'image/mode/stone/character/stone_nianqingjisi.jpg', - 'image/mode/stone/character/stone_nuoziduomu.jpg', - 'image/mode/stone/character/stone_peilianshi.jpg', - 'image/mode/stone/character/stone_qiezei.jpg', - 'image/mode/stone/character/stone_qingwa.jpg', - 'image/mode/stone/character/stone_renyaqishi.jpg', - 'image/mode/stone/character/stone_sainaliusi.jpg', - 'image/mode/stone/character/stone_senlinlang.jpg', - 'image/mode/stone/character/stone_shachuisaman.jpg', - 'image/mode/stone/character/stone_shalinxingzhe.jpg', - 'image/mode/stone/character/stone_shengdianzhishi.jpg', - 'image/mode/stone/character/stone_shengguanghuwei.jpg', - 'image/mode/stone/character/stone_shengjiachong.jpg', - 'image/mode/stone/character/stone_shenmiqishou.jpg', - 'image/mode/stone/character/stone_shenshengyongshi.jpg', - 'image/mode/stone/character/stone_shifazhe.jpg', - 'image/mode/stone/character/stone_shihualong.jpg', - 'image/mode/stone/character/stone_shishigui.jpg', - 'image/mode/stone/character/stone_shixiangweishi.jpg', - 'image/mode/stone/character/stone_shuiyuansu.jpg', - 'image/mode/stone/character/stone_shumiao.jpg', - 'image/mode/stone/character/stone_shuren.jpg', - 'image/mode/stone/character/stone_shurenx.jpg', - 'image/mode/stone/character/stone_shurenxx.jpg', - 'image/mode/stone/character/stone_siwangzhiyi.jpg', - 'image/mode/stone/character/stone_suoxiaojishi.jpg', - 'image/mode/stone/character/stone_tegong.jpg', - 'image/mode/stone/character/stone_tongkunvwang.jpg', - 'image/mode/stone/character/stone_tujiu.jpg', - 'image/mode/stone/character/stone_tuteng1.jpg', - 'image/mode/stone/character/stone_tuteng2.jpg', - 'image/mode/stone/character/stone_tuteng3.jpg', - 'image/mode/stone/character/stone_tuteng4.jpg', - 'image/mode/stone/character/stone_tutengshi.jpg', - 'image/mode/stone/character/stone_tutengyongshi.jpg', - 'image/mode/stone/character/stone_tuyuansu.jpg', - 'image/mode/stone/character/stone_wanshiyuansu.jpg', - 'image/mode/stone/character/stone_weilun.jpg', - 'image/mode/stone/character/stone_wujiyuansu.jpg', - 'image/mode/stone/character/stone_wushixuetu.jpg', - 'image/mode/stone/character/stone_wuyi.jpg', - 'image/mode/stone/character/stone_xiaogui.jpg', - 'image/mode/stone/character/stone_xiaoguishouling.jpg', - 'image/mode/stone/character/stone_xiaojingling.jpg', - 'image/mode/stone/character/stone_xinbing.jpg', - 'image/mode/stone/character/stone_xiushuihaidao.jpg', - 'image/mode/stone/character/stone_xuefanzhanshi.jpg', - 'image/mode/stone/character/stone_xuejuren.jpg', - 'image/mode/stone/character/stone_xukongkongmo.jpg', - 'image/mode/stone/character/stone_xukongxingzhe.jpg', - 'image/mode/stone/character/stone_xulingwushi.jpg', - 'image/mode/stone/character/stone_xunmashi.jpg', - 'image/mode/stone/character/stone_xunmenglong.jpg', - 'image/mode/stone/character/stone_xunshoushi.jpg', - 'image/mode/stone/character/stone_yanjingshe.jpg', - 'image/mode/stone/character/stone_yanshushi.jpg', - 'image/mode/stone/character/stone_yaosaishouwei.jpg', - 'image/mode/stone/character/stone_yingxiongzhihun.jpg', - 'image/mode/stone/character/stone_yisela.jpg', - 'image/mode/stone/character/stone_youlinglang.jpg', - 'image/mode/stone/character/stone_yuanguanying.jpg', - 'image/mode/stone/character/stone_yuanhou.jpg', - 'image/mode/stone/character/stone_yurenqishi.jpg', - 'image/mode/stone/character/stone_zhaohuanzhe.jpg', - 'image/mode/stone/character/stone_zhifuzhe.jpg', - 'image/mode/stone/character/stone_zhihuiguan.jpg', - 'image/mode/stone/character/stone_zhiyuzhe.jpg', - 'image/mode/stone/character/stone_zhongshi.jpg', - 'image/mode/stone/character/stone_zhucangzhe.jpg', - 'image/mode/stone/character/stone_zhujiashi.jpg', - 'image/mode/stone/character/stone_zhumo.jpg', - 'image/mode/stone/character/stone_zongxiong.jpg', - 'image/mode/stone/character/stone_zousishangfan.jpg', - 'image/mode/tafang/character/tafang_mech_dubiaoxianjing.jpg', - 'image/mode/tafang/character/tafang_mech_gongchengche.jpg', - 'image/mode/tafang/character/tafang_mech_guangmingquan.jpg', - 'image/mode/tafang/character/tafang_mech_jiguanren.jpg', - 'image/mode/tafang/character/tafang_mech_jiqishi.jpg', - 'image/mode/tafang/character/tafang_mech_mutong.jpg', - 'image/mode/tafang/character/tafang_mech_nengliangqiu.jpg', - 'image/mode/tafang/character/tafang_mech_shanggukanshou.jpg', - 'image/mode/tafang/character/tafang_mech_shenmidiaoxiang.jpg', - 'image/mode/tafang/character/tafang_mech_shenpanxianjing.jpg', - 'image/mode/tafang/character/tafang_mech_shiyuansu.jpg', - 'image/mode/tafang/character/tafang_mech_toushiche.jpg', - 'image/mode/tafang/character/tafang_mech_tutengzhen.jpg', - 'image/mode/tafang/character/tafang_mech_weixingxianjing.jpg', - 'image/mode/tafang/character/tafang_mech_wuyashenxiang.jpg', - 'image/mode/versus/character/boss_chiyuzhuque.jpg', - 'image/mode/versus/character/boss_duanyuzhongda.jpg', - 'image/mode/versus/character/boss_fudibian.jpg', - 'image/mode/versus/character/boss_gongshenyueying.jpg', - 'image/mode/versus/character/boss_jiarenzidan.jpg', - 'image/mode/versus/character/boss_jileibaihu.jpg', - 'image/mode/versus/character/boss_juechenmiaocai.jpg', - 'image/mode/versus/character/boss_liedixuande.jpg', - 'image/mode/versus/character/boss_lieshiyazi.jpg', - 'image/mode/versus/character/boss_lingjiaxuanwu.jpg', - 'image/mode/versus/character/boss_qiaokuijunyi.jpg', - 'image/mode/versus/character/boss_shihuosuanni.jpg', - 'image/mode/versus/character/boss_tianhoukongming.jpg', - 'image/mode/versus/character/boss_tuntianchiwen.jpg', - 'image/mode/versus/character/boss_yuhuoshiyuan.jpg', - 'image/mode/versus/character/boss_yunpingqinglong.jpg', - 'image/mode/versus/character/boss_baijiwenyuan.jpg', - 'image/mode/versus/character/boss_fuweizilong.jpg', - 'image/mode/versus/character/boss_kumuyuanrang.jpg', - 'image/mode/versus/character/boss_yihanyunchang.jpg', - 'image/mode/versus/character/liuqi.jpg', - 'image/mode/versus/character/tangzi.jpg', - - /*splash image begin*/ - 'image/splash/style1.jpg', - 'image/splash/style2.jpg', - 'image/splash/style1/boss.jpg', - 'image/splash/style1/brawl.jpg', - 'image/splash/style1/chess.jpg', - 'image/splash/style1/connect.jpg', - 'image/splash/style1/doudizhu.jpg', - 'image/splash/style1/guozhan.jpg', - 'image/splash/style1/identity.jpg', - 'image/splash/style1/single.jpg', - 'image/splash/style1/stone.jpg', - 'image/splash/style1/tafang.jpg', - 'image/splash/style1/versus.jpg', - 'image/splash/style2/boss.jpg', - 'image/splash/style2/brawl.jpg', - 'image/splash/style2/chess.jpg', - 'image/splash/style2/connect.jpg', - 'image/splash/style2/doudizhu.jpg', - 'image/splash/style2/guozhan.jpg', - 'image/splash/style2/identity.jpg', - 'image/splash/style2/single.jpg', - 'image/splash/style2/stone.jpg', - 'image/splash/style2/tafang.jpg', - 'image/splash/style2/versus.jpg', - /*splash image end*/ - - 'theme/music/grid.png', - 'theme/music/wood.png', - 'theme/music/wood3.png', - 'theme/simple/card.png', - 'theme/simple/card2.png', - 'theme/simple/grid.png', - 'theme/simple/unknown.png', - 'theme/simple/wood.png', - 'theme/simple/wood3.png', - 'theme/style/card/image/border_bronze.jpg', - 'theme/style/card/image/border_gold.jpg', - 'theme/style/card/image/border_map.jpg', - 'theme/style/card/image/border_silver.jpg', - 'theme/style/card/image/border_wood.jpg', - 'theme/style/card/image/new.png', - 'theme/style/card/image/ol.png', - 'theme/style/cardback/image/feicheng.png', - 'theme/style/cardback/image/feicheng2.png', - 'theme/style/cardback/image/liusha.png', - 'theme/style/cardback/image/liusha2.png', - 'theme/style/cardback/image/new.png', - 'theme/style/cardback/image/new2.png', - 'theme/style/cardback/image/official.png', - 'theme/style/cardback/image/official2.png', - 'theme/style/cardback/image/ol.png', - 'theme/style/cardback/image/ol2.png', - 'theme/style/hp/image/emotion1.png', - 'theme/style/hp/image/emotion2.png', - 'theme/style/hp/image/emotion3.png', - 'theme/style/hp/image/emotion4.png', - 'theme/style/hp/image/glass1.png', - 'theme/style/hp/image/glass2.png', - 'theme/style/hp/image/glass3.png', - 'theme/style/hp/image/glass4.png', - 'theme/style/hp/image/official1.png', - 'theme/style/hp/image/official2.png', - 'theme/style/hp/image/official3.png', - 'theme/style/hp/image/official4.png', - 'theme/style/hp/image/ol1.png', - 'theme/style/hp/image/ol2.png', - 'theme/style/hp/image/ol3.png', - 'theme/style/hp/image/ol4.png', - 'theme/style/hp/image/round1.png', - 'theme/style/hp/image/round2.png', - 'theme/style/hp/image/round3.png', - 'theme/style/hp/image/round4.png', - 'theme/style/player/bronze1.png', - 'theme/style/player/bronze2.png', - 'theme/style/player/bronze3.png', - 'theme/style/player/bronze_d1.png', - 'theme/style/player/bronze_d2.png', - 'theme/style/player/gold1.png', - 'theme/style/player/gold2.png', - 'theme/style/player/gold3.png', - 'theme/style/player/gold_d1.png', - 'theme/style/player/gold_d2.png', - 'theme/style/player/silver1.png', - 'theme/style/player/silver2.png', - 'theme/style/player/silver3.png', - 'theme/style/player/silver_d1.png', - 'theme/style/player/silver_d2.png', - 'theme/woodden/grid.png', - 'theme/woodden/wood.jpg', - 'theme/woodden/wood.png', - 'theme/woodden/wood2.jpg', - 'theme/woodden/wood2.png' -]; -window.noname_skin_list={}; \ No newline at end of file +window.noname_asset_list = [ + "v1.10.11", + /*audio start*/ + "audio/background/aozhan_chaoming.mp3", + "audio/background/aozhan_online.mp3", + "audio/background/aozhan_rewrite.mp3", + "audio/background/music_danji.mp3", + "audio/background/music_default.mp3", + "audio/background/music_diaochan.mp3", + "audio/background/music_jifeng.mp3", + "audio/background/music_jilve.mp3", + "audio/background/music_phliosophy.mp3", + "audio/background/music_shezhan.mp3", + /*cardaudio start*/ + "audio/card/default.mp3", + + "audio/card/female/caomu.mp3", + "audio/card/female/chiling.mp3", + "audio/card/female/diaohulishan.mp3", + "audio/card/female/fulei.mp3", + "audio/card/female/huoshaolianying.mp3", + "audio/card/female/jinchan.mp3", + "audio/card/female/lianjunshengyan.mp3", + "audio/card/female/lulitongxin.mp3", + "audio/card/female/qijia.mp3", + "audio/card/female/shengdong.mp3", + "audio/card/female/shuiyanqijun.mp3", + "audio/card/female/xietianzi.mp3", + "audio/card/female/zengbin.mp3", + "audio/card/female/chuqibuyi.mp3", + "audio/card/female/dongzhuxianji.mp3", + "audio/card/female/sha_ice.mp3", + "audio/card/female/suijiyingbian.mp3", + "audio/card/female/zhujinqiyuan.mp3", + "audio/card/female/binglinchengxiax.mp3", + "audio/card/female/chenghuodajie.mp3", + "audio/card/female/dz_mantianguohai.mp3", + "audio/card/female/guaguliaodu.mp3", + "audio/card/female/gz_guguoanbang.mp3", + "audio/card/female/gz_haolingtianxia.mp3", + "audio/card/female/gz_kefuzhongyuan.mp3", + "audio/card/female/gz_wenheluanwu.mp3", + "audio/card/female/kaihua.mp3", + "audio/card/female/qizhengxiangsheng.mp3", + "audio/card/female/sha_stab.mp3", + "audio/card/female/tiaojiyanmei.mp3", + "audio/card/female/tuixinzhifu.mp3", + + "audio/card/female/bagua.mp3", + "audio/card/female/baiyin.mp3", + "audio/card/female/chitu.mp3", + "audio/card/female/cixiong.mp3", + "audio/card/female/dawan.mp3", + "audio/card/female/dilu.mp3", + "audio/card/female/fangtian.mp3", + "audio/card/female/guanshi.mp3", + "audio/card/female/guding.mp3", + "audio/card/female/hanbing.mp3", + "audio/card/female/hualiu.mp3", + "audio/card/female/jueying.mp3", + "audio/card/female/muniu.mp3", + "audio/card/female/qilin.mp3", + "audio/card/female/qinggang.mp3", + "audio/card/female/qinglong.mp3", + "audio/card/female/renwang.mp3", + "audio/card/female/sanjian.mp3", + "audio/card/female/tengjia.mp3", + "audio/card/female/wuliu.mp3", + "audio/card/female/zhangba.mp3", + "audio/card/female/zhuahuang.mp3", + "audio/card/female/zhuge.mp3", + "audio/card/female/zhuque.mp3", + "audio/card/female/zixin.mp3", + + "audio/card/female/bingliang.mp3", + "audio/card/female/guohe.mp3", + "audio/card/female/huogong.mp3", + "audio/card/female/jiedao.mp3", + "audio/card/female/jiu.mp3", + "audio/card/female/juedou.mp3", + "audio/card/female/lebu.mp3", + "audio/card/female/nanman.mp3", + "audio/card/female/sha.mp3", + "audio/card/female/sha_fire.mp3", + "audio/card/female/sha_thunder.mp3", + "audio/card/female/shan.mp3", + "audio/card/female/shandian.mp3", + "audio/card/female/shunshou.mp3", + "audio/card/female/taoyuan.mp3", + "audio/card/female/tiesuo.mp3", + "audio/card/female/wanjian.mp3", + "audio/card/female/wugu.mp3", + "audio/card/female/wuxie.mp3", + "audio/card/female/wuzhong.mp3", + "audio/card/female/yiyi.mp3", + "audio/card/female/yuanjiao.mp3", + "audio/card/female/zhibi.mp3", + + "audio/card/female/fudichouxin.mp3", + "audio/card/female/toulianghuanzhu.mp3", + + "audio/card/male/caomu.mp3", + "audio/card/male/chiling.mp3", + "audio/card/male/diaohulishan.mp3", + "audio/card/male/fulei.mp3", + "audio/card/male/huoshaolianying.mp3", + "audio/card/male/jinchan.mp3", + "audio/card/male/lianjunshengyan.mp3", + "audio/card/male/lulitongxin.mp3", + "audio/card/male/qijia.mp3", + "audio/card/male/shengdong.mp3", + "audio/card/male/shuiyanqijun.mp3", + "audio/card/male/xietianzi.mp3", + "audio/card/male/zengbin.mp3", + "audio/card/male/chuqibuyi.mp3", + "audio/card/male/dongzhuxianji.mp3", + "audio/card/male/sha_ice.mp3", + "audio/card/male/suijiyingbian.mp3", + "audio/card/male/zhujinqiyuan.mp3", + "audio/card/male/binglinchengxiax.mp3", + "audio/card/male/chenghuodajie.mp3", + "audio/card/male/dz_mantianguohai.mp3", + "audio/card/male/guaguliaodu.mp3", + "audio/card/male/gz_guguoanbang.mp3", + "audio/card/male/gz_haolingtianxia.mp3", + "audio/card/male/gz_kefuzhongyuan.mp3", + "audio/card/male/gz_wenheluanwu.mp3", + "audio/card/male/kaihua.mp3", + "audio/card/male/qizhengxiangsheng.mp3", + "audio/card/male/sha_stab.mp3", + "audio/card/male/tiaojiyanmei.mp3", + "audio/card/male/tuixinzhifu.mp3", + + "audio/card/male/bagua.mp3", + "audio/card/male/baiyin.mp3", + "audio/card/male/chitu.mp3", + "audio/card/male/cixiong.mp3", + "audio/card/male/dawan.mp3", + "audio/card/male/dilu.mp3", + "audio/card/male/fangtian.mp3", + "audio/card/male/guanshi.mp3", + "audio/card/male/guding.mp3", + "audio/card/male/hanbing.mp3", + "audio/card/male/hualiu.mp3", + "audio/card/male/jueying.mp3", + "audio/card/male/muniu.mp3", + "audio/card/male/qilin.mp3", + "audio/card/male/qinggang.mp3", + "audio/card/male/qinglong.mp3", + "audio/card/male/renwang.mp3", + "audio/card/male/sanjian.mp3", + "audio/card/male/tengjia.mp3", + "audio/card/male/wuliu.mp3", + "audio/card/male/zhangba.mp3", + "audio/card/male/zhuahuang.mp3", + "audio/card/male/zhuge.mp3", + "audio/card/male/zhuque.mp3", + "audio/card/male/zixin.mp3", + + "audio/card/male/bingliang.mp3", + "audio/card/male/guohe.mp3", + "audio/card/male/huogong.mp3", + "audio/card/male/jiedao.mp3", + "audio/card/male/jiu.mp3", + "audio/card/male/juedou.mp3", + "audio/card/male/lebu.mp3", + "audio/card/male/nanman.mp3", + "audio/card/male/sha.mp3", + "audio/card/male/sha_fire.mp3", + "audio/card/male/sha_thunder.mp3", + "audio/card/male/shan.mp3", + "audio/card/male/shandian.mp3", + "audio/card/male/shunshou.mp3", + "audio/card/male/taoyuan.mp3", + "audio/card/male/tiesuo.mp3", + "audio/card/male/wanjian.mp3", + "audio/card/male/wugu.mp3", + "audio/card/male/wuxie.mp3", + "audio/card/male/wuzhong.mp3", + "audio/card/male/yiyi.mp3", + "audio/card/male/yuanjiao.mp3", + "audio/card/male/zhibi.mp3", + + "audio/card/female/fudichouxin.mp3", + "audio/card/female/toulianghuanzhu.mp3", + "audio/card/female/wangmeizhike.mp3", + /*cardaudio end*/ + + /*dieaudio begin*/ + "audio/die/ahuinan.mp3", + "audio/die/bailingyun.mp3", + "audio/die/baosanniang.mp3", + "audio/die/beimihu.mp3", + "audio/die/bianfuren.mp3", + "audio/die/bianxi.mp3", + "audio/die/boss_lvbu1.mp3", + "audio/die/boss_lvbu2.mp3", + "audio/die/boss_lvbu3.mp3", + "audio/die/boss_wuguanwang.mp3", + "audio/die/boss_zhaoyun.mp3", + "audio/die/bulianshi.mp3", + "audio/die/buzhi.mp3", + "audio/die/caesar.mp3", + "audio/die/caifuren.mp3", + "audio/die/caimaozhangyun.mp3", + "audio/die/caiwenji.mp3", + "audio/die/caiyong.mp3", + "audio/die/caizhaoji.mp3", + "audio/die/caizhenji.mp3", + "audio/die/caoang.mp3", + "audio/die/caoanmin.mp3", + "audio/die/caocao.mp3", + "audio/die/caochong.mp3", + "audio/die/caochun.mp3", + "audio/die/caofang.mp3", + "audio/die/caohong.mp3", + "audio/die/caohua.mp3", + "audio/die/caojie.mp3", + "audio/die/caojinyu.mp3", + "audio/die/caomao.mp3", + "audio/die/caopi.mp3", + "audio/die/caoren.mp3", + "audio/die/caorui.mp3", + "audio/die/caoshuang.mp3", + "audio/die/caosong.mp3", + "audio/die/caoxi.mp3", + "audio/die/caoxian.mp3", + "audio/die/caoxiancaohua.mp3", + "audio/die/caoxing.mp3", + "audio/die/caoxiu.mp3", + "audio/die/caoyi.mp3", + "audio/die/caoying.mp3", + "audio/die/caoyu.mp3", + "audio/die/caozhang.mp3", + "audio/die/caozhen.mp3", + "audio/die/caozhi.mp3", + "audio/die/cenhun.mp3", + "audio/die/cheliji.mp3", + "audio/die/chendao.mp3", + "audio/die/chendeng.mp3", + "audio/die/chendong.mp3", + "audio/die/chengbing.mp3", + "audio/die/chengji.mp3", + "audio/die/chengjichengcui.mp3", + "audio/die/chengong.mp3", + "audio/die/chengpu.mp3", + "audio/die/chengui.mp3", + "audio/die/chengyu.mp3", + "audio/die/chenjiao.mp3", + "audio/die/chenlin.mp3", + "audio/die/chenqun.mp3", + "audio/die/chenshi.mp3", + "audio/die/chentai.mp3", + "audio/die/chenwudongxi.mp3", + "audio/die/chunyuqiong.mp3", + "audio/die/clan_hanrong.mp3", + "audio/die/clan_hanshao.mp3", + "audio/die/clan_wanghun.mp3", + "audio/die/clan_wangling.mp3", + "audio/die/clan_wanglun.mp3", + "audio/die/clan_wangyun.mp3", + "audio/die/clan_wuban.mp3", + "audio/die/clan_wukuang.mp3", + "audio/die/clan_wuqiao.mp3", + "audio/die/clan_wuxian.mp3", + "audio/die/clan_xuncai.mp3", + "audio/die/clan_xuncan.mp3", + "audio/die/clan_xunchen.mp3", + "audio/die/clan_xunshu.mp3", + "audio/die/clan_xunyou.mp3", + "audio/die/clan_zhonghui.mp3", + "audio/die/clan_zhongyan.mp3", + "audio/die/clan_zhongyu.mp3", + "audio/die/cuimao.mp3", + "audio/die/cuiyan.mp3", + "audio/die/daqiao.mp3", + "audio/die/daxiaoqiao.mp3", + "audio/die/db_wenyang.mp3", + "audio/die/dc_bulianshi.mp3", + "audio/die/dc_caiyang.mp3", + "audio/die/dc_caoshuang.mp3", + "audio/die/dc_caozhi.mp3", + "audio/die/dc_chenqun.mp3", + "audio/die/dc_dengzhi.mp3", + "audio/die/dc_dongzhao.mp3", + "audio/die/dc_duyu.mp3", + "audio/die/dc_gaolan.mp3", + "audio/die/dc_gongsunzan.mp3", + "audio/die/dc_huangchengyan.mp3", + "audio/die/dc_huanghao.mp3", + "audio/die/dc_huangquan.mp3", + "audio/die/dc_huangzu.mp3", + "audio/die/dc_huban.mp3", + "audio/die/dc_hujinding.mp3", + "audio/die/dc_huojun.mp3", + "audio/die/dc_jiachong.mp3", + "audio/die/dc_jiangji.mp3", + "audio/die/dc_jiben.mp3", + "audio/die/dc_jiling.mp3", + "audio/die/dc_liru.mp3", + "audio/die/dc_liuba.mp3", + "audio/die/dc_liuli.mp3", + "audio/die/dc_liuye.mp3", + "audio/die/dc_liuyu.mp3", + "audio/die/dc_luotong.mp3", + "audio/die/dc_lvkuanglvxiang.mp3", + "audio/die/dc_mengda.mp3", + "audio/die/dc_ruiji.mp3", + "audio/die/dc_sb_lusu.mp3", + "audio/die/dc_sb_simayi.mp3", + "audio/die/dc_sb_simayi_shadow.mp3", + "audio/die/dc_sb_zhouyu.mp3", + "audio/die/dc_sp_jiaxu.mp3", + "audio/die/dc_sunchen.mp3", + "audio/die/dc_sunhanhua.mp3", + "audio/die/dc_sunru.mp3", + "audio/die/dc_sunziliufang.mp3", + "audio/die/dc_tengfanglan.mp3", + "audio/die/dc_wangchang.mp3", + "audio/die/dc_wangjun.mp3", + "audio/die/dc_wangyun.mp3", + "audio/die/dc_wuban.mp3", + "audio/die/dc_xujing.mp3", + "audio/die/dc_xushu.mp3", + "audio/die/dc_yangbiao.mp3", + "audio/die/dc_yanghu.mp3", + "audio/die/dc_yuejiu.mp3", + "audio/die/dc_zhangmancheng.mp3", + "audio/die/dc_zhaotongzhaoguang.mp3", + "audio/die/dc_zhaoyǎn.mp3", + "audio/die/dc_zhaoyun.mp3", + "audio/die/dc_zhouxuān.mp3", + "audio/die/dc_zhuling.mp3", + "audio/die/dengai.mp3", + "audio/die/dengshizai.mp3", + "audio/die/dengzhi.mp3", + "audio/die/dengzhong.mp3", + "audio/die/dianwei.mp3", + "audio/die/diaochan.mp3", + "audio/die/dingfeng.mp3", + "audio/die/dingshangwan.mp3", + "audio/die/dingyuan.mp3", + "audio/die/dongbai.mp3", + "audio/die/dongcheng.mp3", + "audio/die/dongguiren.mp3", + "audio/die/dongtuna.mp3", + "audio/die/dongwan.mp3", + "audio/die/dongxie.mp3", + "audio/die/dongyun.mp3", + "audio/die/dongzhao.mp3", + "audio/die/dongzhuo.mp3", + "audio/die/duanjiong.mp3", + "audio/die/duanqiaoxiao.mp3", + "audio/die/duanwei.mp3", + "audio/die/dufuren.mp3", + "audio/die/duji.mp3", + "audio/die/dukui.mp3", + "audio/die/duosidawang.mp3", + "audio/die/duxi.mp3", + "audio/die/duyu.mp3", + "audio/die/erqiao.mp3", + "audio/die/erzhang.mp3", + "audio/die/fanchou.mp3", + "audio/die/fanjiangzhangda.mp3", + "audio/die/fanyufeng.mp3", + "audio/die/fazheng.mp3", + "audio/die/feiyi.mp3", + "audio/die/fengfang.mp3", + "audio/die/fengfangnv.mp3", + "audio/die/fengxi.mp3", + "audio/die/fuhuanghou.mp3", + "audio/die/furong.mp3", + "audio/die/furongfuqian.mp3", + "audio/die/fuwan.mp3", + "audio/die/ganfuren.mp3", + "audio/die/ganfurenmifuren.mp3", + "audio/die/ganning.mp3", + "audio/die/gaogan.mp3", + "audio/die/gaolan.mp3", + "audio/die/gaoshun.mp3", + "audio/die/gaoxiang.mp3", + "audio/die/gexuan.mp3", + "audio/die/gongsundu.mp3", + "audio/die/gongsunkang.mp3", + "audio/die/gongsunxiu.mp3", + "audio/die/gongsunyuan.mp3", + "audio/die/gongsunzan.mp3", + "audio/die/guanhai.mp3", + "audio/die/guanlu.mp3", + "audio/die/guanning.mp3", + "audio/die/guānning.mp3", + "audio/die/guanping.mp3", + "audio/die/guanqiujian.mp3", + "audio/die/guanxingzhangbao.mp3", + "audio/die/guanyinping.mp3", + "audio/die/guanyu.mp3", + "audio/die/guanzhang.mp3", + "audio/die/guohuai.mp3", + "audio/die/guohuanghou.mp3", + "audio/die/guojia.mp3", + "audio/die/guosi.mp3", + "audio/die/guotu.mp3", + "audio/die/guotufengji.mp3", + "audio/die/guozhao.mp3", + "audio/die/guyong.mp3", + "audio/die/guzhielai.mp3", + "audio/die/gz_dc_yanghu.mp3", + "audio/die/gz_dengzhi.mp3", + "audio/die/gz_gongsunyuan.mp3", + "audio/die/gz_huangzu.mp3", + "audio/die/gz_jun_caocao.mp3", + "audio/die/gz_jun_liubei.mp3", + "audio/die/gz_jun_sunquan.mp3", + "audio/die/gz_jun_zhangjiao.mp3", + "audio/die/gz_liuba.mp3", + "audio/die/gz_liuqi.mp3", + "audio/die/gz_lukang.mp3", + "audio/die/gz_luxun.mp3", + "audio/die/gz_miheng.mp3", + "audio/die/gz_panjun.mp3", + "audio/die/gz_pengyang.mp3", + "audio/die/gz_re_xushu.mp3", + "audio/die/gz_shixie.mp3", + "audio/die/gz_simazhao.mp3", + "audio/die/gz_sunchen.mp3", + "audio/die/gz_tangzi.mp3", + "audio/die/gz_wenqin.mp3", + "audio/die/gz_wujing.mp3", + "audio/die/gz_xf_sufei.mp3", + "audio/die/gz_xiahouba.mp3", + "audio/die/gz_xuyou.mp3", + "audio/die/gz_yanbaihu.mp3", + "audio/die/gz_yuji.mp3", + "audio/die/gz_zhanglu.mp3", + "audio/die/gz_zhonghui.mp3", + "audio/die/gz_zhugeke.mp3", + "audio/die/gz_zhuling.mp3", + "audio/die/hanba.mp3", + "audio/die/handang.mp3", + "audio/die/hanfu.mp3", + "audio/die/hanhaoshihuan.mp3", + "audio/die/hanlong.mp3", + "audio/die/hanmeng.mp3", + "audio/die/hansui.mp3", + "audio/die/haomeng.mp3", + "audio/die/haopu.mp3", + "audio/die/haozhao.mp3", + "audio/die/hejin.mp3", + "audio/die/heqi.mp3", + "audio/die/hetaihou.mp3", + "audio/die/heyan.mp3", + "audio/die/huaman.mp3", + "audio/die/huanfan.mp3", + "audio/die/huangchengyan.mp3", + "audio/die/huangfusong.mp3", + "audio/die/huanggai.mp3", + "audio/die/huanghao.mp3", + "audio/die/huangquan.mp3", + "audio/die/huangyueying.mp3", + "audio/die/huangzhong.mp3", + "audio/die/huangzu.mp3", + "audio/die/huatuo.mp3", + "audio/die/huaxin.mp3", + "audio/die/huaxiong.mp3", + "audio/die/hucheer.mp3", + "audio/die/hujinding.mp3", + "audio/die/huojun.mp3", + "audio/die/huzhao.mp3", + "audio/die/jiachong.mp3", + "audio/die/jiakui.mp3", + "audio/die/jiangboyue.mp3", + "audio/die/jiangfei.mp3", + "audio/die/jianggan.mp3", + "audio/die/jiangqin.mp3", + "audio/die/jiangwanfeiyi.mp3", + "audio/die/jiangwei.mp3", + "audio/die/jianyong.mp3", + "audio/die/jiawenhe.mp3", + "audio/die/jiaxu.mp3", + "audio/die/jikang.mp3", + "audio/die/jiling.mp3", + "audio/die/jin_guohuai.mp3", + "audio/die/jin_jiachong.mp3", + "audio/die/jin_simashi.mp3", + "audio/die/jin_simayi.mp3", + "audio/die/jin_simazhao.mp3", + "audio/die/jin_wangyuanji.mp3", + "audio/die/jin_xiahouhui.mp3", + "audio/die/jin_yanghu.mp3", + "audio/die/jin_yanghuiyu.mp3", + "audio/die/jin_zhangchunhua.mp3", + "audio/die/jin_zhouchu.mp3", + "audio/die/jinxuandi.mp3", + "audio/die/jsp_caoren.mp3", + "audio/die/jsp_guanyu.mp3", + "audio/die/jsp_huangyueying.mp3", + "audio/die/junk_guanyu.mp3", + "audio/die/kanze.mp3", + "audio/die/kebineng.mp3", + "audio/die/key_abyusa.mp3", + "audio/die/key_hinata.mp3", + "audio/die/key_hisako.mp3", + "audio/die/key_noda.mp3", + "audio/die/key_saya.mp3", + "audio/die/key_shiina.mp3", + "audio/die/key_shiki.mp3", + "audio/die/key_shiorimiyuki.mp3", + "audio/die/key_yui.mp3", + "audio/die/key_yuri.mp3", + "audio/die/kongrong.mp3", + "audio/die/kuailiangkuaiyue.mp3", + "audio/die/kuaiqi.mp3", + "audio/die/laimin.mp3", + "audio/die/laiyinger.mp3", + "audio/die/leibo.mp3", + "audio/die/leitong.mp3", + "audio/die/liangxing.mp3", + "audio/die/liaohua.mp3", + "audio/die/libai.mp3", + "audio/die/licaiwei.mp3", + "audio/die/lidian.mp3", + "audio/die/lifeng.mp3", + "audio/die/lijue.mp3", + "audio/die/lingcao.mp3", + "audio/die/lingju.mp3", + "audio/die/lingtong.mp3", + "audio/die/liqueguosi.mp3", + "audio/die/liru.mp3", + "audio/die/lisu.mp3", + "audio/die/litong.mp3", + "audio/die/liuba.mp3", + "audio/die/liubei.mp3", + "audio/die/liubian.mp3", + "audio/die/liubiao.mp3", + "audio/die/liuchen.mp3", + "audio/die/liucheng.mp3", + "audio/die/liuchongluojun.mp3", + "audio/die/liufeng.mp3", + "audio/die/liuhong.mp3", + "audio/die/liuhui.mp3", + "audio/die/liupi.mp3", + "audio/die/liuqi.mp3", + "audio/die/liushan.mp3", + "audio/die/liuxie.mp3", + "audio/die/liuyan.mp3", + "audio/die/liuyao.mp3", + "audio/die/liuye.mp3", + "audio/die/liuyong.mp3", + "audio/die/liuyu.mp3", + "audio/die/liuzan.mp3", + "audio/die/liuzhang.mp3", + "audio/die/liwan.mp3", + "audio/die/liyan.mp3", + "audio/die/liyi.mp3", + "audio/die/liyixiejing.mp3", + "audio/die/lizhaojiaobo.mp3", + "audio/die/longwang.mp3", + "audio/die/luboyan.mp3", + "audio/die/luji.mp3", + "audio/die/lukai.mp3", + "audio/die/lukang.mp3", + "audio/die/luotong.mp3", + "audio/die/luoxian.mp3", + "audio/die/lushi.mp3", + "audio/die/lusu.mp3", + "audio/die/luxun.mp3", + "audio/die/luyi.mp3", + "audio/die/luyusheng.mp3", + "audio/die/luzhi.mp3", + "audio/die/lvboshe.mp3", + "audio/die/lvbu.mp3", + "audio/die/lvdai.mp3", + "audio/die/lvfan.mp3", + "audio/die/lvkai.mp3", + "audio/die/lvkuanglvxiang.mp3", + "audio/die/lvlingqi.mp3", + "audio/die/lvmeng.mp3", + "audio/die/lvqian.mp3", + "audio/die/machao.mp3", + "audio/die/macheng.mp3", + "audio/die/madai.mp3", + "audio/die/majun.mp3", + "audio/die/maliang.mp3", + "audio/die/malingli.mp3", + "audio/die/mamidi.mp3", + "audio/die/manchong.mp3", + "audio/die/mangyachang.mp3", + "audio/die/mateng.mp3", + "audio/die/maxiumatie.mp3", + "audio/die/mayuanyi.mp3", + "audio/die/mayunlu.mp3", + "audio/die/mazhong.mp3", + "audio/die/mb_caomao.mp3", + "audio/die/mb_chengui.mp3", + "audio/die/mb_huban.mp3", + "audio/die/mb_sp_guanqiujian.mp3", + "audio/die/mb_xianglang.mp3", + "audio/die/mengda.mp3", + "audio/die/menghuo.mp3", + "audio/die/mengjie.mp3", + "audio/die/mengyou.mp3", + "audio/die/mifangfushiren.mp3", + "audio/die/mifuren.mp3", + "audio/die/miheng.mp3", + "audio/die/mizhu.mp3", + "audio/die/mp_liuling.mp3", + "audio/die/muludawang.mp3", + "audio/die/mushun.mp3", + "audio/die/nanhualaoxian.mp3", + "audio/die/nashime.mp3", + "audio/die/neo_xuchu.mp3", + "audio/die/neo_zhouyu.mp3", + "audio/die/new_caoren.mp3", + "audio/die/nezha.mp3", + "audio/die/niufu.mp3", + "audio/die/niujin.mp3", + "audio/die/ns_zanghong.mp3", + "audio/die/ol_caiwenji.mp3", + "audio/die/ol_chendeng.mp3", + "audio/die/ol_dengai.mp3", + "audio/die/ol_dengzhi.mp3", + "audio/die/ol_dianwei.mp3", + "audio/die/ol_dingshangwan.mp3", + "audio/die/ol_dingyuan.mp3", + "audio/die/ol_dongzhao.mp3", + "audio/die/ol_dongzhuo.mp3", + "audio/die/ol_feiyi.mp3", + "audio/die/ol_furong.mp3", + "audio/die/ol_huangzhong.mp3", + "audio/die/ol_huaxin.mp3", + "audio/die/ol_huban.mp3", + "audio/die/ol_hujinding.mp3", + "audio/die/ol_jiangwei.mp3", + "audio/die/ol_lisu.mp3", + "audio/die/ol_liuba.mp3", + "audio/die/ol_liushan.mp3", + "audio/die/ol_lukai.mp3", + "audio/die/ol_lusu.mp3", + "audio/die/ol_masu.mp3", + "audio/die/ol_mengda.mp3", + "audio/die/ol_pangde.mp3", + "audio/die/ol_pangtong.mp3", + "audio/die/ol_puyuan.mp3", + "audio/die/ol_qianzhao.mp3", + "audio/die/ol_sb_guanyu.mp3", + "audio/die/ol_sb_jiangwei.mp3", + "audio/die/ol_sb_taishici.mp3", + "audio/die/ol_sb_yuanshao.mp3", + "audio/die/ol_sb_yuanshao_shadow.mp3", + "audio/die/ol_sp_zhugeliang.mp3", + "audio/die/ol_sunjian.mp3", + "audio/die/ol_wangrong.mp3", + "audio/die/ol_weiyan.mp3", + "audio/die/ol_wenqin.mp3", + "audio/die/ol_xiahouyuan.mp3", + "audio/die/ol_xiaoqiao.mp3", + "audio/die/ol_xuhuang.mp3", + "audio/die/ol_xunyu.mp3", + "audio/die/ol_yangyi.mp3", + "audio/die/ol_yanwen.mp3", + "audio/die/ol_yuanshao.mp3", + "audio/die/ol_yujin.mp3", + "audio/die/ol_zhangyì.mp3", + "audio/die/ol_zhangzhang.mp3", + "audio/die/ol_zhouqun.mp3", + "audio/die/ol_zhujun.mp3", + "audio/die/ol_zhuling.mp3", + "audio/die/ol_zhurong.mp3", + "audio/die/old_guanzhang.mp3", + "audio/die/old_madai.mp3", + "audio/die/old_quancong.mp3", + "audio/die/old_wangyi.mp3", + "audio/die/old_zhuhuan.mp3", + "audio/die/panfeng.mp3", + "audio/die/pangde.mp3", + "audio/die/pangdegong.mp3", + "audio/die/panghui.mp3", + "audio/die/panglingming.mp3", + "audio/die/pangshanmin.mp3", + "audio/die/pangtong.mp3", + "audio/die/panjun.mp3", + "audio/die/panshu.mp3", + "audio/die/panzhangmazhong.mp3", + "audio/die/peixiu.mp3", + "audio/die/peiyuanshao.mp3", + "audio/die/puyuan.mp3", + "audio/die/qianzhao.mp3", + "audio/die/qiaogong.mp3", + "audio/die/qiaorui.mp3", + "audio/die/qiaozhou.mp3", + "audio/die/qinghegongzhu.mp3", + "audio/die/qinlang.mp3", + "audio/die/qinmi.mp3", + "audio/die/qinyilu.mp3", + "audio/die/qiuliju.mp3", + "audio/die/quancong.mp3", + "audio/die/quanhuijie.mp3", + "audio/die/quhuang.mp3", + "audio/die/quyi.mp3", + "audio/die/re_bulianshi.mp3", + "audio/die/re_caifuren.mp3", + "audio/die/re_caiwenji.mp3", + "audio/die/re_caiyong.mp3", + "audio/die/re_caocao.mp3", + "audio/die/re_caochong.mp3", + "audio/die/re_caopi.mp3", + "audio/die/re_caoxiu.mp3", + "audio/die/re_caozhang.mp3", + "audio/die/re_caozhen.mp3", + "audio/die/re_caozhi.mp3", + "audio/die/re_chendeng.mp3", + "audio/die/re_chengong.mp3", + "audio/die/re_chengpu.mp3", + "audio/die/re_chenqun.mp3", + "audio/die/re_chunyuqiong.mp3", + "audio/die/re_daqiao.mp3", + "audio/die/re_dengai.mp3", + "audio/die/re_dianwei.mp3", + "audio/die/re_diaochan.mp3", + "audio/die/re_dongbai.mp3", + "audio/die/re_dongcheng.mp3", + "audio/die/re_dongzhuo.mp3", + "audio/die/re_duji.mp3", + "audio/die/re_fazheng.mp3", + "audio/die/re_fengfangnv.mp3", + "audio/die/re_fuhuanghou.mp3", + "audio/die/re_ganning.mp3", + "audio/die/re_gaoshun.mp3", + "audio/die/re_gongsunyuan.mp3", + "audio/die/re_gongsunzan.mp3", + "audio/die/re_guanping.mp3", + "audio/die/re_guanyu.mp3", + "audio/die/re_guanzhang.mp3", + "audio/die/re_guohuai.mp3", + "audio/die/re_guohuanghou.mp3", + "audio/die/re_guojia.mp3", + "audio/die/re_guotufengji.mp3", + "audio/die/re_guyong.mp3", + "audio/die/re_handang.mp3", + "audio/die/re_hanhaoshihuan.mp3", + "audio/die/re_huanggai.mp3", + "audio/die/re_huangyueying.mp3", + "audio/die/re_huangzhong.mp3", + "audio/die/re_huatuo.mp3", + "audio/die/re_huaxiong.mp3", + "audio/die/re_hucheer.mp3", + "audio/die/re_jiangwei.mp3", + "audio/die/re_jianyong.mp3", + "audio/die/re_jiaxu.mp3", + "audio/die/re_jsp_huangyueying.mp3", + "audio/die/re_jsp_pangtong.mp3", + "audio/die/re_jushou.mp3", + "audio/die/re_liaohua.mp3", + "audio/die/re_lingtong.mp3", + "audio/die/re_liru.mp3", + "audio/die/re_liubei.mp3", + "audio/die/re_liubiao.mp3", + "audio/die/re_liuchen.mp3", + "audio/die/re_liufeng.mp3", + "audio/die/re_liushan.mp3", + "audio/die/re_liuzan.mp3", + "audio/die/re_lusu.mp3", + "audio/die/re_luxun.mp3", + "audio/die/re_lvbu.mp3", + "audio/die/re_lvmeng.mp3", + "audio/die/re_machao.mp3", + "audio/die/re_madai.mp3", + "audio/die/re_manchong.mp3", + "audio/die/re_masu.mp3", + "audio/die/re_mazhong.mp3", + "audio/die/re_menghuo.mp3", + "audio/die/re_miheng.mp3", + "audio/die/re_nanhualaoxian.mp3", + "audio/die/re_panfeng.mp3", + "audio/die/re_pangde.mp3", + "audio/die/re_pangdegong.mp3", + "audio/die/re_pangtong.mp3", + "audio/die/re_panshu.mp3", + "audio/die/re_panzhangmazhong.mp3", + "audio/die/re_quancong.mp3", + "audio/die/re_simayi.mp3", + "audio/die/re_sp_taishici.mp3", + "audio/die/re_sp_zhugeliang.mp3", + "audio/die/re_sunben.mp3", + "audio/die/re_sunce.mp3", + "audio/die/re_sundeng.mp3", + "audio/die/re_sunjian.mp3", + "audio/die/re_sunluban.mp3", + "audio/die/re_sunquan.mp3", + "audio/die/re_sunshangxiang.mp3", + "audio/die/re_sunxiu.mp3", + "audio/die/re_sunyi.mp3", + "audio/die/re_taishici.mp3", + "audio/die/re_taoqian.mp3", + "audio/die/re_wangyi.mp3", + "audio/die/re_weiyan.mp3", + "audio/die/re_wenpin.mp3", + "audio/die/re_wuguotai.mp3", + "audio/die/re_wuyi.mp3", + "audio/die/re_xiahoudun.mp3", + "audio/die/re_xiahoushi.mp3", + "audio/die/re_xiahouyuan.mp3", + "audio/die/re_xiaoqiao.mp3", + "audio/die/re_xuhuang.mp3", + "audio/die/re_xunchen.mp3", + "audio/die/re_xunyou.mp3", + "audio/die/re_xunyu.mp3", + "audio/die/re_xusheng.mp3", + "audio/die/re_xushu.mp3", + "audio/die/re_xuzhu.mp3", + "audio/die/re_yanwen.mp3", + "audio/die/re_yuanshu.mp3", + "audio/die/re_yufan.mp3", + "audio/die/re_yuji.mp3", + "audio/die/re_zhangchunhua.mp3", + "audio/die/re_zhangfei.mp3", + "audio/die/re_zhanghe.mp3", + "audio/die/re_zhangjiao.mp3", + "audio/die/re_zhangliang.mp3", + "audio/die/re_zhangliao.mp3", + "audio/die/re_zhangsong.mp3", + "audio/die/re_zhangyi.mp3", + "audio/die/re_zhangzhang.mp3", + "audio/die/re_zhaoyun.mp3", + "audio/die/re_zhenji.mp3", + "audio/die/re_zhonghui.mp3", + "audio/die/re_zhongyao.mp3", + "audio/die/re_zhoucang.mp3", + "audio/die/re_zhouyu.mp3", + "audio/die/re_zhugeliang.mp3", + "audio/die/re_zhuhuan.mp3", + "audio/die/re_zhuran.mp3", + "audio/die/re_zhurong.mp3", + "audio/die/re_zhuzhi.mp3", + "audio/die/re_zoushi.mp3", + "audio/die/re_zuoci.mp3", + "audio/die/ruanhui.mp3", + "audio/die/ruanji.mp3", + "audio/die/ruanyu.mp3", + "audio/die/ruiji.mp3", + "audio/die/sb_caocao.mp3", + "audio/die/sb_caopi.mp3", + "audio/die/sb_caoren.mp3", + "audio/die/sb_chengong.mp3", + "audio/die/sb_daqiao.mp3", + "audio/die/sb_diaochan.mp3", + "audio/die/sb_fazheng.mp3", + "audio/die/sb_ganning.mp3", + "audio/die/sb_gaoshun.mp3", + "audio/die/sb_guanyu.mp3", + "audio/die/sb_huanggai.mp3", + "audio/die/sb_huangyueying.mp3", + "audio/die/sb_huangzhong.mp3", + "audio/die/sb_huaxiong.mp3", + "audio/die/sb_jiangwei.mp3", + "audio/die/sb_liubei.mp3", + "audio/die/sb_liubiao.mp3", + "audio/die/sb_lvmeng.mp3", + "audio/die/sb_machao.mp3", + "audio/die/sb_menghuo.mp3", + "audio/die/sb_pangtong.mp3", + "audio/die/sb_sp_zhugeliang.mp3", + "audio/die/sb_sunce.mp3", + "audio/die/sb_sunquan.mp3", + "audio/die/sb_sunshangxiang.mp3", + "audio/die/sb_xiahoudun.mp3", + "audio/die/sb_xiahoushi.mp3", + "audio/die/sb_xiaoqiao.mp3", + "audio/die/sb_xuhuang.mp3", + "audio/die/sb_xunyu.mp3", + "audio/die/sb_yl_luzhi.mp3", + "audio/die/sb_yuanshao.mp3", + "audio/die/sb_yujin.mp3", + "audio/die/sb_zhangfei.mp3", + "audio/die/sb_zhanghe.mp3", + "audio/die/sb_zhangjiao.mp3", + "audio/die/sb_zhaoyun.mp3", + "audio/die/sb_zhenji.mp3", + "audio/die/sb_zhouyu.mp3", + "audio/die/sb_zhugeliang.mp3", + "audio/die/sb_zhurong.mp3", + "audio/die/shamoke.mp3", + "audio/die/shen_caocao.mp3", + "audio/die/shen_caopi.mp3", + "audio/die/shen_dengai.mp3", + "audio/die/shen_dianwei.mp3", + "audio/die/shen_diaochan.mp3", + "audio/die/shen_ganning.mp3", + "audio/die/shen_guanyu.mp3", + "audio/die/shen_guojia.mp3", + "audio/die/shen_huatuo.mp3", + "audio/die/shen_jiangwei.mp3", + "audio/die/shen_liubei.mp3", + "audio/die/shen_lusu.mp3", + "audio/die/shen_luxun.mp3", + "audio/die/shen_lvbu.mp3", + "audio/die/shen_lvbu1.mp3", + "audio/die/shen_lvbu2.mp3", + "audio/die/shen_lvmeng.mp3", + "audio/die/shen_machao.mp3", + "audio/die/shen_simayi.mp3", + "audio/die/shen_sunce.mp3", + "audio/die/shen_sunquan.mp3", + "audio/die/shen_taishici.mp3", + "audio/die/shen_xunyu.mp3", + "audio/die/shen_xuzhu.mp3", + "audio/die/shen_zhangfei.mp3", + "audio/die/shen_zhangjiao.mp3", + "audio/die/shen_zhangliao.mp3", + "audio/die/shen_zhaoyun.mp3", + "audio/die/shen_zhenji.mp3", + "audio/die/shen_zhouyu.mp3", + "audio/die/shen_zhugeliang.mp3", + "audio/die/shenpei.mp3", + "audio/die/shibao.mp3", + "audio/die/shichangshi.mp3", + "audio/die/shichangshiRest.mp3", + "audio/die/shixie.mp3", + "audio/die/shiyi.mp3", + "audio/die/simafu.mp3", + "audio/die/simahui.mp3", + "audio/die/simalang.mp3", + "audio/die/simashi.mp3", + "audio/die/simayi.mp3", + "audio/die/simazhao.mp3", + "audio/die/simazhou.mp3", + "audio/die/sp_bianfuren.mp3", + "audio/die/sp_caiwenji.mp3", + "audio/die/sp_caohong.mp3", + "audio/die/sp_caoren.mp3", + "audio/die/sp_caosong.mp3", + "audio/die/sp_chendong.mp3", + "audio/die/sp_chenzhen.mp3", + "audio/die/sp_cuiyan.mp3", + "audio/die/sp_dongzhuo.mp3", + "audio/die/sp_duyu.mp3", + "audio/die/sp_gaolan.mp3", + "audio/die/sp_guanyu.mp3", + "audio/die/sp_huaman.mp3", + "audio/die/sp_huangfusong.mp3", + "audio/die/sp_huaxin.mp3", + "audio/die/sp_jianggan.mp3", + "audio/die/sp_jiangqing.mp3", + "audio/die/sp_jiangwan.mp3", + "audio/die/sp_jiangwei.mp3", + "audio/die/sp_jiaxu.mp3", + "audio/die/sp_key_kanade.mp3", + "audio/die/sp_kongrong.mp3", + "audio/die/sp_lvfan.mp3", + "audio/die/sp_machao.mp3", + "audio/die/sp_maojie.mp3", + "audio/die/sp_menghuo.mp3", + "audio/die/sp_mifangfushiren.mp3", + "audio/die/sp_mifuren.mp3", + "audio/die/sp_ol_zhanghe.mp3", + "audio/die/sp_pangde.mp3", + "audio/die/sp_pangtong.mp3", + "audio/die/sp_pengyang.mp3", + "audio/die/sp_shenpei.mp3", + "audio/die/sp_sufei.mp3", + "audio/die/sp_sunce.mp3", + "audio/die/sp_sunshangxiang.mp3", + "audio/die/sp_sunshao.mp3", + "audio/die/sp_taishici.mp3", + "audio/die/sp_wangcan.mp3", + "audio/die/sp_wangshuang.mp3", + "audio/die/sp_wenpin.mp3", + "audio/die/sp_xiahoudun.mp3", + "audio/die/sp_xinpi.mp3", + "audio/die/sp_xujing.mp3", + "audio/die/sp_xunchen.mp3", + "audio/die/sp_xusheng.mp3", + "audio/die/sp_xuyou.mp3", + "audio/die/sp_yanghu.mp3", + "audio/die/sp_yangwan.mp3", + "audio/die/sp_yuji.mp3", + "audio/die/sp_zhangchangpu.mp3", + "audio/die/sp_zhanghe.mp3", + "audio/die/sp_zhangliao.mp3", + "audio/die/sp_zhangwen.mp3", + "audio/die/sp_zhugeliang.mp3", + "audio/die/sp_zhujun.mp3", + "audio/die/sp_zongyu.mp3", + "audio/die/st_xushu.mp3", + "audio/die/st_yuanshu.mp3", + "audio/die/star_caoren.mp3", + "audio/die/star_dongzhuo.mp3", + "audio/die/star_yuanshao.mp3", + "audio/die/star_yuanshu.mp3", + "audio/die/sufei.mp3", + "audio/die/sunce.mp3", + "audio/die/sundeng.mp3", + "audio/die/sunhanhua.mp3", + "audio/die/sunhao.mp3", + "audio/die/sunhong.mp3", + "audio/die/sunhuan.mp3", + "audio/die/sunjian.mp3", + "audio/die/sunlang.mp3", + "audio/die/sunliang.mp3", + "audio/die/sunlingluan.mp3", + "audio/die/sunluban.mp3", + "audio/die/sunluyu.mp3", + "audio/die/sunqian.mp3", + "audio/die/sunquan.mp3", + "audio/die/sunru.mp3", + "audio/die/sunshangxiang.mp3", + "audio/die/sunshao.mp3", + "audio/die/sunwukong.mp3", + "audio/die/sunxiu.mp3", + "audio/die/sunyi.mp3", + "audio/die/sunyu.mp3", + "audio/die/sunziliufang.mp3", + "audio/die/tadun.mp3", + "audio/die/taishici.mp3", + "audio/die/tangji.mp3", + "audio/die/tangzi.mp3", + "audio/die/taoqian.mp3", + "audio/die/taoshen.mp3", + "audio/die/tengfanglan.mp3", + "audio/die/tenggongzhu.mp3", + "audio/die/tengyin.mp3", + "audio/die/tianchou.mp3", + "audio/die/tianfeng.mp3", + "audio/die/tianshangyi.mp3", + "audio/die/tianyu.mp3", + "audio/die/tongyuan.mp3", + "audio/die/tw_baoxin.mp3", + "audio/die/tw_beimihu.mp3", + "audio/die/tw_bingyuan.mp3", + "audio/die/tw_caocao.mp3", + "audio/die/tw_caozhao.mp3", + "audio/die/tw_chenzhen.mp3", + "audio/die/tw_dongzhao.mp3", + "audio/die/tw_fengxí.mp3", + "audio/die/tw_gexuan.mp3", + "audio/die/tw_gongsunfan.mp3", + "audio/die/tw_haomeng.mp3", + "audio/die/tw_huchuquan.mp3", + "audio/die/tw_huojun.mp3", + "audio/die/tw_jiangji.mp3", + "audio/die/tw_jiangwei.mp3", + "audio/die/tw_jianshuo.mp3", + "audio/die/tw_liubei.mp3", + "audio/die/tw_liufuren.mp3", + "audio/die/tw_liuhong.mp3", + "audio/die/tw_liwei.mp3", + "audio/die/tw_mateng.mp3", + "audio/die/tw_niufudongxie.mp3", + "audio/die/tw_puyangxing.mp3", + "audio/die/tw_qiaorui.mp3", + "audio/die/tw_shen_guanyu.mp3", + "audio/die/tw_shen_lvmeng.mp3", + "audio/die/tw_tianyu.mp3", + "audio/die/tw_wangcan.mp3", + "audio/die/tw_wangchang.mp3", + "audio/die/tw_weixu.mp3", + "audio/die/tw_wenchou.mp3", + "audio/die/tw_xiahouen.mp3", + "audio/die/tw_xiahoushang.mp3", + "audio/die/tw_yangang.mp3", + "audio/die/tw_yanliang.mp3", + "audio/die/tw_yanxiang.mp3", + "audio/die/tw_yuantan.mp3", + "audio/die/tw_yufuluo.mp3", + "audio/die/tw_yujin.mp3", + "audio/die/tw_zhanghong.mp3", + "audio/die/tw_zhangji.mp3", + "audio/die/tw_zhangnan.mp3", + "audio/die/tw_zhangning.mp3", + "audio/die/tw_zhangzhao.mp3", + "audio/die/vtb_xiaojiu.mp3", + "audio/die/vtb_xiaole.mp3", + "audio/die/vtb_xiaosha.mp3", + "audio/die/vtb_xiaoshan.mp3", + "audio/die/vtb_xiaotao.mp3", + "audio/die/wangcan.mp3", + "audio/die/wangfuzhaolei.mp3", + "audio/die/wangguan.mp3", + "audio/die/wangji.mp3", + "audio/die/wangjun.mp3", + "audio/die/wanglang.mp3", + "audio/die/wanglie.mp3", + "audio/die/wangling.mp3", + "audio/die/wangping.mp3", + "audio/die/wangrong.mp3", + "audio/die/wangshuang.mp3", + "audio/die/wangtao.mp3", + "audio/die/wangwei.mp3", + "audio/die/wangxiang.mp3", + "audio/die/wangyan.mp3", + "audio/die/wangyi.mp3", + "audio/die/wangyuanji.mp3", + "audio/die/wangyue.mp3", + "audio/die/wangyun.mp3", + "audio/die/wanniangongzhu.mp3", + "audio/die/weiguan.mp3", + "audio/die/weiwenzhugezhi.mp3", + "audio/die/weiyan.mp3", + "audio/die/weizi.mp3", + "audio/die/wenpin.mp3", + "audio/die/wenyang.mp3", + "audio/die/wis_huaxiong.mp3", + "audio/die/wis_jiangwan.mp3", + "audio/die/wis_jiangwei.mp3", + "audio/die/wis_shuijing.mp3", + "audio/die/wis_sunce.mp3", + "audio/die/wis_tianfeng.mp3", + "audio/die/wis_xuyou.mp3", + "audio/die/wis_zhangzhao.mp3", + "audio/die/wolongfengchu.mp3", + "audio/die/wu_luxun.mp3", + "audio/die/wu_zhugeliang.mp3", + "audio/die/wu_zhutiexiong.mp3", + "audio/die/wuanguo.mp3", + "audio/die/wuban.mp3", + "audio/die/wufan.mp3", + "audio/die/wuguotai.mp3", + "audio/die/wujing.mp3", + "audio/die/wulan.mp3", + "audio/die/wutugu.mp3", + "audio/die/wuxian.mp3", + "audio/die/wuyan.mp3", + "audio/die/wuyi.mp3", + "audio/die/xf_yiji.mp3", + "audio/die/xia_dianwei.mp3", + "audio/die/xia_guanyu.mp3", + "audio/die/xia_liubei.mp3", + "audio/die/xia_liyàn.mp3", + "audio/die/xia_lusu.mp3", + "audio/die/xia_shie.mp3", + "audio/die/xia_shitao.mp3", + "audio/die/xia_tongyuan.mp3", + "audio/die/xia_wangyue.mp3", + "audio/die/xia_xiahoudun.mp3", + "audio/die/xia_xiahousone.mp3", + "audio/die/xia_xiahouzie.mp3", + "audio/die/xia_xushu.mp3", + "audio/die/xia_yuzhenzi.mp3", + "audio/die/xia_zhangwei.mp3", + "audio/die/xia_zhaoe.mp3", + "audio/die/xiahouba.mp3", + "audio/die/xiahoudun.mp3", + "audio/die/xiahoujie.mp3", + "audio/die/xiahoujuan.mp3", + "audio/die/xiahoulingnv.mp3", + "audio/die/xiahoumao.mp3", + "audio/die/xiahoushi.mp3", + "audio/die/xiahouxuan.mp3", + "audio/die/xiahouyuan.mp3", + "audio/die/xiangchong.mp3", + "audio/die/xianglang.mp3", + "audio/die/xiangrang.mp3", + "audio/die/xiaoqiao.mp3", + "audio/die/xiaoyuehankehan.mp3", + "audio/die/xielingyu.mp3", + "audio/die/xin_caifuren.mp3", + "audio/die/xin_caoxiu.mp3", + "audio/die/xin_caozhang.mp3", + "audio/die/xin_caozhen.mp3", + "audio/die/xin_chengpu.mp3", + "audio/die/xin_fazheng.mp3", + "audio/die/xin_fuhuanghou.mp3", + "audio/die/xin_gaoshun.mp3", + "audio/die/xin_gongsunzan.mp3", + "audio/die/xin_guohuai.mp3", + "audio/die/xin_guozhao.mp3", + "audio/die/xin_guyong.mp3", + "audio/die/xin_handang.mp3", + "audio/die/xin_hansui.mp3", + "audio/die/xin_jianyong.mp3", + "audio/die/xin_jushou.mp3", + "audio/die/xin_liaohua.mp3", + "audio/die/xin_lingtong.mp3", + "audio/die/xin_liubiao.mp3", + "audio/die/xin_mamidi.mp3", + "audio/die/xin_panzhangmazhong.mp3", + "audio/die/xin_quancong.mp3", + "audio/die/xin_sunluban.mp3", + "audio/die/xin_sunxiu.mp3", + "audio/die/xin_wuguotai.mp3", + "audio/die/xin_wuyi.mp3", + "audio/die/xin_xusheng.mp3", + "audio/die/xin_xushu.mp3", + "audio/die/xin_yuanshao.mp3", + "audio/die/xin_yufan.mp3", + "audio/die/xin_yuji.mp3", + "audio/die/xin_zhangyi.mp3", + "audio/die/xin_zhonghui.mp3", + "audio/die/xin_zhuhuan.mp3", + "audio/die/xin_zhuran.mp3", + "audio/die/xin_zhuzhi.mp3", + "audio/die/xinchang.mp3", + "audio/die/xinfu_yuji.mp3", + "audio/die/xingdaorong.mp3", + "audio/die/xinpi.mp3", + "audio/die/xinping.mp3", + "audio/die/xinxianying.mp3", + "audio/die/xinzhongyong.mp3", + "audio/die/xizheng.mp3", + "audio/die/xizhicai.mp3", + "audio/die/xuangongzhu.mp3", + "audio/die/xuelingyun.mp3", + "audio/die/xuezong.mp3", + "audio/die/xugong.mp3", + "audio/die/xuhuang.mp3", + "audio/die/xujing.mp3", + "audio/die/xunchen.mp3", + "audio/die/xunyou.mp3", + "audio/die/xunyu.mp3", + "audio/die/xurong.mp3", + "audio/die/xushao.mp3", + "audio/die/xusheng.mp3", + "audio/die/xushi.mp3", + "audio/die/xushu.mp3", + "audio/die/xuyou.mp3", + "audio/die/xuzhu.mp3", + "audio/die/yanbaihu.mp3", + "audio/die/yanfuren.mp3", + "audio/die/yangbiao.mp3", + "audio/die/yangfeng.mp3", + "audio/die/yangfu.mp3", + "audio/die/yanghong.mp3", + "audio/die/yanghuiyu.mp3", + "audio/die/yangwan.mp3", + "audio/die/yangxiu.mp3", + "audio/die/yangyan.mp3", + "audio/die/yangyi.mp3", + "audio/die/yangzhi.mp3", + "audio/die/yanjun.mp3", + "audio/die/yanpu.mp3", + "audio/die/yanrou.mp3", + "audio/die/yanwen.mp3", + "audio/die/yanyan.mp3", + "audio/die/yinfuren.mp3", + "audio/die/yitianjian.mp3", + "audio/die/yj_ganning.mp3", + "audio/die/yj_huangzhong.mp3", + "audio/die/yj_jushou.mp3", + "audio/die/yj_qiaozhou.mp3", + "audio/die/yj_sufei.mp3", + "audio/die/yj_weiyan.mp3", + "audio/die/yj_xuhuang.mp3", + "audio/die/yj_zhanghe.mp3", + "audio/die/yj_zhangliao.mp3", + "audio/die/yj_zhoubuyi.mp3", + "audio/die/yl_luzhi.mp3", + "audio/die/yl_yuanshu.mp3", + "audio/die/yuanhuan.mp3", + "audio/die/yuanji.mp3", + "audio/die/yuanshao.mp3", + "audio/die/yuanshu.mp3", + "audio/die/yuantanyuanshang.mp3", + "audio/die/yuantanyuanxiyuanshang.mp3", + "audio/die/yue_caiwenji.mp3", + "audio/die/yue_daqiao.mp3", + "audio/die/yue_xiaoqiao.mp3", + "audio/die/yue_zhoufei.mp3", + "audio/die/yuechen.mp3", + "audio/die/yuejin.mp3", + "audio/die/yuejiu.mp3", + "audio/die/yufan.mp3", + "audio/die/yuji.mp3", + "audio/die/yujin.mp3", + "audio/die/yujin_yujin.mp3", + "audio/die/zangba.mp3", + "audio/die/zerong.mp3", + "audio/die/zhangbao.mp3", + "audio/die/zhangchangpu.mp3", + "audio/die/zhangchu.mp3", + "audio/die/zhangchunhua.mp3", + "audio/die/zhangfei.mp3", + "audio/die/zhangfen.mp3", + "audio/die/zhanggong.mp3", + "audio/die/zhanggongqi.mp3", + "audio/die/zhanghe.mp3", + "audio/die/zhangheng.mp3", + "audio/die/zhanghu.mp3", + "audio/die/zhanghua.mp3", + "audio/die/zhanghuyuechen.mp3", + "audio/die/zhangji.mp3", + "audio/die/zhangjiao.mp3", + "audio/die/zhangjinyun.mp3", + "audio/die/zhangjunyi.mp3", + "audio/die/zhangkai.mp3", + "audio/die/zhangliao.mp3", + "audio/die/zhangling.mp3", + "audio/die/zhanglu.mp3", + "audio/die/zhangmancheng.mp3", + "audio/die/zhangmiao.mp3", + "audio/die/zhangning.mp3", + "audio/die/zhangqiying.mp3", + "audio/die/zhangrang.mp3", + "audio/die/zhangren.mp3", + "audio/die/zhangshiping.mp3", + "audio/die/zhangsong.mp3", + "audio/die/zhangwen.mp3", + "audio/die/zhangxingcai.mp3", + "audio/die/zhangxiu.mp3", + "audio/die/zhangxuan.mp3", + "audio/die/zhangxun.mp3", + "audio/die/zhangyan.mp3", + "audio/die/zhangyao.mp3", + "audio/die/zhangyi.mp3", + "audio/die/zhangyì.mp3", + "audio/die/zhangzhang.mp3", + "audio/die/zhangzhi.mp3", + "audio/die/zhangzhongjing.mp3", + "audio/die/zhaoang.mp3", + "audio/die/zhaotongzhaoguang.mp3", + "audio/die/zhaoxiang.mp3", + "audio/die/zhaoyan.mp3", + "audio/die/zhaoyǎn.mp3", + "audio/die/zhaoyun.mp3", + "audio/die/zhaozhi.mp3", + "audio/die/zhaozhong.mp3", + "audio/die/zhenghun.mp3", + "audio/die/zhengxuan.mp3", + "audio/die/zhenji.mp3", + "audio/die/zhiling.mp3", + "audio/die/zhonghui.mp3", + "audio/die/zhongshiji.mp3", + "audio/die/zhongyan.mp3", + "audio/die/zhongyao.mp3", + "audio/die/zhoubuyi.mp3", + "audio/die/zhoucang.mp3", + "audio/die/zhouchu.mp3", + "audio/die/zhoufang.mp3", + "audio/die/zhoufei.mp3", + "audio/die/zhouqun.mp3", + "audio/die/zhoushan.mp3", + "audio/die/zhoutai.mp3", + "audio/die/zhouyi.mp3", + "audio/die/zhouyu.mp3", + "audio/die/zhugedan.mp3", + "audio/die/zhugeguo.mp3", + "audio/die/zhugejin.mp3", + "audio/die/zhugeke.mp3", + "audio/die/zhugeliang.mp3", + "audio/die/zhugemengxue.mp3", + "audio/die/zhugeruoxue.mp3", + "audio/die/zhugeshang.mp3", + "audio/die/zhugezhan.mp3", + "audio/die/zhuhuan.mp3", + "audio/die/zhujianping.mp3", + "audio/die/zhujun.mp3", + "audio/die/zhuling.mp3", + "audio/die/zhuran.mp3", + "audio/die/zhurong.mp3", + "audio/die/zhutiexiong.mp3", + "audio/die/zhuzhi.mp3", + "audio/die/zongyu.mp3", + "audio/die/zoushi.mp3", + "audio/die/zumao.mp3", + "audio/die/zuoci.mp3", + "audio/die/zuofen.mp3", + /*effect audio end*/ + + /*skill audio begin*/ + "audio/skill/abyusa_dunying1.mp3", + "audio/skill/abyusa_dunying2.mp3", + "audio/skill/abyusa_jueqing1.mp3", + "audio/skill/abyusa_jueqing2.mp3", + "audio/skill/aichen1.mp3", + "audio/skill/aichen2.mp3", + "audio/skill/anguo1.mp3", + "audio/skill/anguo2.mp3", + "audio/skill/anjian1.mp3", + "audio/skill/anjian2.mp3", + "audio/skill/anxian1.mp3", + "audio/skill/anxian2.mp3", + "audio/skill/anxu1.mp3", + "audio/skill/anxu2.mp3", + "audio/skill/anyong1.mp3", + "audio/skill/anyong2.mp3", + "audio/skill/aocai_gz_zhugeke1.mp3", + "audio/skill/aocai_gz_zhugeke2.mp3", + "audio/skill/aocai1.mp3", + "audio/skill/aocai2.mp3", + "audio/skill/bagua_skill.mp3", + "audio/skill/baijia_tw_beimihu1.mp3", + "audio/skill/baijia_tw_beimihu2.mp3", + "audio/skill/baijia1.mp3", + "audio/skill/baijia2.mp3", + "audio/skill/baiyi1.mp3", + "audio/skill/baiyi2.mp3", + "audio/skill/baiyin_skill.mp3", + "audio/skill/baoling1.mp3", + "audio/skill/baoling2.mp3", + "audio/skill/baonu1.mp3", + "audio/skill/baonu2.mp3", + "audio/skill/baonue2_re_dongzhuo1.mp3", + "audio/skill/baonue2_re_dongzhuo2.mp3", + "audio/skill/baonue21.mp3", + "audio/skill/baonue22.mp3", + "audio/skill/baoqie1.mp3", + "audio/skill/baoqie2.mp3", + "audio/skill/baoshu1.mp3", + "audio/skill/baoshu2.mp3", + "audio/skill/bazhan1.mp3", + "audio/skill/bazhan2.mp3", + "audio/skill/bazhen_ol_pangtong1.mp3", + "audio/skill/bazhen_ol_pangtong2.mp3", + "audio/skill/bazhen_ol_sp_zhugeliang1.mp3", + "audio/skill/bazhen_ol_sp_zhugeliang2.mp3", + "audio/skill/bazhen_re_sp_zhugeliang1.mp3", + "audio/skill/bazhen_re_sp_zhugeliang2.mp3", + "audio/skill/bazhen1.mp3", + "audio/skill/bazhen2.mp3", + "audio/skill/beige_ol_caiwenji1.mp3", + "audio/skill/beige_ol_caiwenji2.mp3", + "audio/skill/beige_re_caiwenji1.mp3", + "audio/skill/beige_re_caiwenji2.mp3", + "audio/skill/beige1.mp3", + "audio/skill/beige2.mp3", + "audio/skill/beini1.mp3", + "audio/skill/beini2.mp3", + "audio/skill/beishui1.mp3", + "audio/skill/beishui2.mp3", + "audio/skill/beizhan1.mp3", + "audio/skill/beizhan2.mp3", + "audio/skill/beizhu1.mp3", + "audio/skill/beizhu2.mp3", + "audio/skill/beizhu3.mp3", + "audio/skill/benghuai_ol_dongzhuo1.mp3", + "audio/skill/benghuai_ol_dongzhuo2.mp3", + "audio/skill/benghuai_re_dongzhuo1.mp3", + "audio/skill/benghuai_re_dongzhuo2.mp3", + "audio/skill/benghuai_zhugedan1.mp3", + "audio/skill/benghuai_zhugedan2.mp3", + "audio/skill/benghuai1.mp3", + "audio/skill/benghuai2.mp3", + "audio/skill/benxi1.mp3", + "audio/skill/benxi2.mp3", + "audio/skill/benyu1.mp3", + "audio/skill/benyu2.mp3", + "audio/skill/biaozhao1.mp3", + "audio/skill/biaozhao2.mp3", + "audio/skill/biejun1.mp3", + "audio/skill/biejun2.mp3", + "audio/skill/bifa1.mp3", + "audio/skill/bifa2.mp3", + "audio/skill/bihuo1.mp3", + "audio/skill/bihuo2.mp3", + "audio/skill/biluan1.mp3", + "audio/skill/biluan2.mp3", + "audio/skill/binghuo1.mp3", + "audio/skill/binghuo2.mp3", + "audio/skill/bingjie1.mp3", + "audio/skill/bingjie2.mp3", + "audio/skill/binglun1.mp3", + "audio/skill/binglun2.mp3", + "audio/skill/bingqing1.mp3", + "audio/skill/bingqing2.mp3", + "audio/skill/bingxin1.mp3", + "audio/skill/bingxin2.mp3", + "audio/skill/bingyi_xin_guyong1.mp3", + "audio/skill/bingyi_xin_guyong2.mp3", + "audio/skill/bingyi1.mp3", + "audio/skill/bingyi2.mp3", + "audio/skill/bingzheng1.mp3", + "audio/skill/bingzheng2.mp3", + "audio/skill/bixiong1.mp3", + "audio/skill/bixiong2.mp3", + "audio/skill/biyue1.mp3", + "audio/skill/biyue2.mp3", + "audio/skill/bizheng1.mp3", + "audio/skill/bizheng2.mp3", + "audio/skill/bizhuan1.mp3", + "audio/skill/bizhuan2.mp3", + "audio/skill/bmcanshi_tw_beimihu1.mp3", + "audio/skill/bmcanshi_tw_beimihu2.mp3", + "audio/skill/bmcanshi1.mp3", + "audio/skill/bmcanshi2.mp3", + "audio/skill/bolan1.mp3", + "audio/skill/bolan2.mp3", + "audio/skill/boming1.mp3", + "audio/skill/boming2.mp3", + "audio/skill/boss_baolin.mp3", + "audio/skill/boss_baonu1.mp3", + "audio/skill/boss_baonu2.mp3", + "audio/skill/boss_biantianx1.mp3", + "audio/skill/boss_biantianx2.mp3", + "audio/skill/boss_bufo.mp3", + "audio/skill/boss_chiying1.mp3", + "audio/skill/boss_chiying2.mp3", + "audio/skill/boss_chuanyun.mp3", + "audio/skill/boss_dayuan.mp3", + "audio/skill/boss_diting.mp3", + "audio/skill/boss_fanshi.mp3", + "audio/skill/boss_fengxing.mp3", + "audio/skill/boss_gongshenjg1.mp3", + "audio/skill/boss_gongshenjg2.mp3", + "audio/skill/boss_guihan1.mp3", + "audio/skill/boss_guihan2.mp3", + "audio/skill/boss_honglian1.mp3", + "audio/skill/boss_honglian2.mp3", + "audio/skill/boss_hujia1.mp3", + "audio/skill/boss_hujia2.mp3", + "audio/skill/boss_huodi1.mp3", + "audio/skill/boss_huodi2.mp3", + "audio/skill/boss_jingmiao1.mp3", + "audio/skill/boss_jingmiao2.mp3", + "audio/skill/boss_jizhen1.mp3", + "audio/skill/boss_jizhen2.mp3", + "audio/skill/boss_jizhi1.mp3", + "audio/skill/boss_jizhi2.mp3", + "audio/skill/boss_jueji1.mp3", + "audio/skill/boss_jueji2.mp3", + "audio/skill/boss_leiji1.mp3", + "audio/skill/boss_leiji2.mp3", + "audio/skill/boss_leili1.mp3", + "audio/skill/boss_leili2.mp3", + "audio/skill/boss_lingfeng1.mp3", + "audio/skill/boss_lingfeng2.mp3", + "audio/skill/boss_qiangzheng1.mp3", + "audio/skill/boss_qiangzheng2.mp3", + "audio/skill/boss_qiwu.mp3", + "audio/skill/boss_shengshou.mp3", + "audio/skill/boss_shiyou.mp3", + "audio/skill/boss_skonghun.mp3", + "audio/skill/boss_tianyu.mp3", + "audio/skill/boss_tianyujg.mp3", + "audio/skill/boss_wanghun.mp3", + "audio/skill/boss_wangshi.mp3", + "audio/skill/boss_wuliang.mp3", + "audio/skill/boss_wuxin1.mp3", + "audio/skill/boss_wuxin2.mp3", + "audio/skill/boss_xianyin1.mp3", + "audio/skill/boss_xianyin2.mp3", + "audio/skill/boss_xuanlei.mp3", + "audio/skill/boss_yuhuojg.mp3", + "audio/skill/boss_zhinang1.mp3", + "audio/skill/boss_zhinang2.mp3", + "audio/skill/botu1.mp3", + "audio/skill/botu2.mp3", + "audio/skill/boyan1.mp3", + "audio/skill/boyan2.mp3", + "audio/skill/buchen1.mp3", + "audio/skill/buchen2.mp3", + "audio/skill/buqi1.mp3", + "audio/skill/buqi2.mp3", + "audio/skill/buqu1.mp3", + "audio/skill/buqu2.mp3", + "audio/skill/bushi1.mp3", + "audio/skill/bushi2.mp3", + "audio/skill/busuan1.mp3", + "audio/skill/busuan2.mp3", + "audio/skill/buxu1.mp3", + "audio/skill/buxu2.mp3", + "audio/skill/buyi_re_wuguotai1.mp3", + "audio/skill/buyi_re_wuguotai2.mp3", + "audio/skill/buyi1.mp3", + "audio/skill/buyi2.mp3", + "audio/skill/caishi1.mp3", + "audio/skill/caishi2.mp3", + "audio/skill/caiwang1.mp3", + "audio/skill/caiwang2.mp3", + "audio/skill/caiyi1.mp3", + "audio/skill/caiyi2.mp3", + "audio/skill/caiyuan1.mp3", + "audio/skill/caiyuan2.mp3", + "audio/skill/caizhaoji_hujia.mp3", + "audio/skill/cangchu1.mp3", + "audio/skill/cangchu2.mp3", + "audio/skill/cangji.mp3", + "audio/skill/cangzhuo1.mp3", + "audio/skill/cangzhuo2.mp3", + "audio/skill/canmou1.mp3", + "audio/skill/canmou2.mp3", + "audio/skill/canshi1.mp3", + "audio/skill/canshi2.mp3", + "audio/skill/caozhao1.mp3", + "audio/skill/caozhao2.mp3", + "audio/skill/changbiao1.mp3", + "audio/skill/changbiao2.mp3", + "audio/skill/chanhui1.mp3", + "audio/skill/chanhui2.mp3", + "audio/skill/channi1.mp3", + "audio/skill/channi2.mp3", + "audio/skill/chanyuan1.mp3", + "audio/skill/chanyuan2.mp3", + "audio/skill/chaofeng1.mp3", + "audio/skill/chaofeng2.mp3", + "audio/skill/chenggong1.mp3", + "audio/skill/chenggong2.mp3", + "audio/skill/chengshang1.mp3", + "audio/skill/chengshang2.mp3", + "audio/skill/chengwu1.mp3", + "audio/skill/chengwu2.mp3", + "audio/skill/chengxiang1.mp3", + "audio/skill/chengxiang2.mp3", + "audio/skill/chengye1.mp3", + "audio/skill/chengye2.mp3", + "audio/skill/chengye3.mp3", + "audio/skill/chengzhang1.mp3", + "audio/skill/chengzhang2.mp3", + "audio/skill/chengzhao1.mp3", + "audio/skill/chengzhao2.mp3", + "audio/skill/chenjian1.mp3", + "audio/skill/chenjian2.mp3", + "audio/skill/chenjie1.mp3", + "audio/skill/chenjie2.mp3", + "audio/skill/chenqing1.mp3", + "audio/skill/chenqing2.mp3", + "audio/skill/chexuan1.mp3", + "audio/skill/chexuan2.mp3", + "audio/skill/chijie.mp3", + "audio/skill/chizhong1.mp3", + "audio/skill/chizhong2.mp3", + "audio/skill/chongxin1.mp3", + "audio/skill/chongxin2.mp3", + "audio/skill/chongxu1.mp3", + "audio/skill/chongxu2.mp3", + "audio/skill/chongzhen1.mp3", + "audio/skill/chongzhen2.mp3", + "audio/skill/chouce1.mp3", + "audio/skill/chouce2.mp3", + "audio/skill/choufa1.mp3", + "audio/skill/choufa2.mp3", + "audio/skill/chouhai1.mp3", + "audio/skill/chouhai2.mp3", + "audio/skill/choujue1.mp3", + "audio/skill/choujue2.mp3", + "audio/skill/chouliang.mp3", + "audio/skill/choulve1.mp3", + "audio/skill/choulve2.mp3", + "audio/skill/choutao1.mp3", + "audio/skill/choutao2.mp3", + "audio/skill/chuaili1.mp3", + "audio/skill/chuaili2.mp3", + "audio/skill/chuanshu1.mp3", + "audio/skill/chuanshu2.mp3", + "audio/skill/chuanxin1.mp3", + "audio/skill/chuanxin2.mp3", + "audio/skill/chuanyun.mp3", + "audio/skill/chuhai1.mp3", + "audio/skill/chuhai2.mp3", + "audio/skill/chuhai3.mp3", + "audio/skill/chuiti1.mp3", + "audio/skill/chuiti2.mp3", + "audio/skill/chulao1.mp3", + "audio/skill/chulao2.mp3", + "audio/skill/chunlao_xin_chengpu1.mp3", + "audio/skill/chunlao_xin_chengpu2.mp3", + "audio/skill/chunlao1.mp3", + "audio/skill/chunlao2.mp3", + "audio/skill/chuyuan1.mp3", + "audio/skill/chuyuan2.mp3", + "audio/skill/cibei1.mp3", + "audio/skill/cibei2.mp3", + "audio/skill/cihuang1.mp3", + "audio/skill/cihuang2.mp3", + "audio/skill/ciwei1.mp3", + "audio/skill/ciwei2.mp3", + "audio/skill/cixiao1.mp3", + "audio/skill/cixiao2.mp3", + "audio/skill/cixiong_skill.mp3", + "audio/skill/clanbaichu1.mp3", + "audio/skill/clanbaichu2.mp3", + "audio/skill/clanbalong1.mp3", + "audio/skill/clanbalong2.mp3", + "audio/skill/clanbaozu_clan_zhonghui1.mp3", + "audio/skill/clanbaozu_clan_zhonghui2.mp3", + "audio/skill/clanbaozu_clan_zhongyan1.mp3", + "audio/skill/clanbaozu_clan_zhongyan2.mp3", + "audio/skill/clanbaozu_clan_zhongyu1.mp3", + "audio/skill/clanbaozu_clan_zhongyu2.mp3", + "audio/skill/clanbeishi1.mp3", + "audio/skill/clanbeishi2.mp3", + "audio/skill/clanbolong1.mp3", + "audio/skill/clanbolong2.mp3", + "audio/skill/clanchenya1.mp3", + "audio/skill/clanchenya2.mp3", + "audio/skill/clandaojie_clan_xuncai1.mp3", + "audio/skill/clandaojie_clan_xuncai2.mp3", + "audio/skill/clandaojie_clan_xuncan1.mp3", + "audio/skill/clandaojie_clan_xuncan2.mp3", + "audio/skill/clandaojie_clan_xunchen1.mp3", + "audio/skill/clandaojie_clan_xunchen2.mp3", + "audio/skill/clandaojie_clan_xunshu1.mp3", + "audio/skill/clandaojie_clan_xunshu2.mp3", + "audio/skill/clandaojie_clan_xunyou1.mp3", + "audio/skill/clandaojie_clan_xunyou2.mp3", + "audio/skill/clandianzhan1.mp3", + "audio/skill/clandianzhan2.mp3", + "audio/skill/clanfangzhen1.mp3", + "audio/skill/clanfangzhen2.mp3", + "audio/skill/clanfenchai1.mp3", + "audio/skill/clanfenchai2.mp3", + "audio/skill/clanfuxun1.mp3", + "audio/skill/clanfuxun2.mp3", + "audio/skill/clanguangu1.mp3", + "audio/skill/clanguangu2.mp3", + "audio/skill/clanguixiang1.mp3", + "audio/skill/clanguixiang2.mp3", + "audio/skill/clanhuanghan1.mp3", + "audio/skill/clanhuanghan2.mp3", + "audio/skill/clanhuanjia1.mp3", + "audio/skill/clanhuanjia2.mp3", + "audio/skill/clanhuanyin1.mp3", + "audio/skill/clanhuanyin2.mp3", + "audio/skill/clanjianyuan1.mp3", + "audio/skill/clanjianyuan2.mp3", + "audio/skill/clanjiejian1.mp3", + "audio/skill/clanjiejian2.mp3", + "audio/skill/clanjiexuan1.mp3", + "audio/skill/clanjiexuan2.mp3", + "audio/skill/clanlianhe1.mp3", + "audio/skill/clanlianhe2.mp3", + "audio/skill/clanlianzhu1.mp3", + "audio/skill/clanlianzhu2.mp3", + "audio/skill/clanlieshi1.mp3", + "audio/skill/clanlieshi2.mp3", + "audio/skill/clanliuju1.mp3", + "audio/skill/clanliuju2.mp3", + "audio/skill/clanmingjie1.mp3", + "audio/skill/clanmingjie2.mp3", + "audio/skill/clanmuyin_clan_wuban1.mp3", + "audio/skill/clanmuyin_clan_wuban2.mp3", + "audio/skill/clanmuyin_clan_wukuang1.mp3", + "audio/skill/clanmuyin_clan_wukuang2.mp3", + "audio/skill/clanmuyin_clan_wuqiao1.mp3", + "audio/skill/clanmuyin_clan_wuqiao2.mp3", + "audio/skill/clanmuyin_clan_wuxian1.mp3", + "audio/skill/clanmuyin_clan_wuxian2.mp3", + "audio/skill/clanqiajue1.mp3", + "audio/skill/clanqiajue2.mp3", + "audio/skill/clanqiuxin1.mp3", + "audio/skill/clanqiuxin2.mp3", + "audio/skill/clansankuang1.mp3", + "audio/skill/clansankuang2.mp3", + "audio/skill/clanshangshen1.mp3", + "audio/skill/clanshangshen2.mp3", + "audio/skill/clanshenjun1.mp3", + "audio/skill/clanshenjun2.mp3", + "audio/skill/clanxiaoyong1.mp3", + "audio/skill/clanxiaoyong2.mp3", + "audio/skill/clanxieshu1.mp3", + "audio/skill/clanxieshu2.mp3", + "audio/skill/clanxumin_clan_hanrong1.mp3", + "audio/skill/clanxumin_clan_hanrong2.mp3", + "audio/skill/clanxumin_clan_hanshao1.mp3", + "audio/skill/clanxumin_clan_hanshao2.mp3", + "audio/skill/clanyirong1.mp3", + "audio/skill/clanyirong2.mp3", + "audio/skill/clanyunshen1.mp3", + "audio/skill/clanyunshen2.mp3", + "audio/skill/clanyuzhi1.mp3", + "audio/skill/clanyuzhi2.mp3", + "audio/skill/clanzhanding1.mp3", + "audio/skill/clanzhanding2.mp3", + "audio/skill/clanzhongliu_clan_wanghun1.mp3", + "audio/skill/clanzhongliu_clan_wanghun2.mp3", + "audio/skill/clanzhongliu_clan_wangling1.mp3", + "audio/skill/clanzhongliu_clan_wangling2.mp3", + "audio/skill/clanzhongliu_clan_wanglun1.mp3", + "audio/skill/clanzhongliu_clan_wanglun2.mp3", + "audio/skill/clanzhongliu_clan_wangyun1.mp3", + "audio/skill/clanzhongliu_clan_wangyun2.mp3", + "audio/skill/congjian1.mp3", + "audio/skill/congjian2.mp3", + "audio/skill/cslilu1.mp3", + "audio/skill/cslilu2.mp3", + "audio/skill/csyizheng1.mp3", + "audio/skill/csyizheng2.mp3", + "audio/skill/cuguo1.mp3", + "audio/skill/cuguo2.mp3", + "audio/skill/cuijian1.mp3", + "audio/skill/cuijian2.mp3", + "audio/skill/cuijin1.mp3", + "audio/skill/cuijin2.mp3", + "audio/skill/cuijue1.mp3", + "audio/skill/cuijue2.mp3", + "audio/skill/cunsi1.mp3", + "audio/skill/cunsi2.mp3", + "audio/skill/cuorui1.mp3", + "audio/skill/cuorui2.mp3", + "audio/skill/cxliushi1.mp3", + "audio/skill/cxliushi2.mp3", + "audio/skill/dahe.mp3", + "audio/skill/daiyan1.mp3", + "audio/skill/daiyan2.mp3", + "audio/skill/daming1.mp3", + "audio/skill/daming2.mp3", + "audio/skill/dangmo1.mp3", + "audio/skill/dangmo2.mp3", + "audio/skill/dangxian_guansuo1.mp3", + "audio/skill/dangxian_guansuo2.mp3", + "audio/skill/dangxian_re_liaohua1.mp3", + "audio/skill/dangxian_re_liaohua2.mp3", + "audio/skill/dangxian_xin_liaohua1.mp3", + "audio/skill/dangxian_xin_liaohua2.mp3", + "audio/skill/dangxian1.mp3", + "audio/skill/dangxian2.mp3", + "audio/skill/dangzai1.mp3", + "audio/skill/dangzai2.mp3", + "audio/skill/danji1.mp3", + "audio/skill/danji2.mp3", + "audio/skill/danlao1.mp3", + "audio/skill/danlao2.mp3", + "audio/skill/danshou1.mp3", + "audio/skill/danshou2.mp3", + "audio/skill/danxin1.mp3", + "audio/skill/danxin2.mp3", + "audio/skill/daoji1.mp3", + "audio/skill/daoji2.mp3", + "audio/skill/daoshu1.mp3", + "audio/skill/daoshu2.mp3", + "audio/skill/dawu1.mp3", + "audio/skill/dawu2.mp3", + "audio/skill/dbchongjian1.mp3", + "audio/skill/dbchongjian2.mp3", + "audio/skill/dbchoujue1.mp3", + "audio/skill/dbchoujue2.mp3", + "audio/skill/dbquedi1.mp3", + "audio/skill/dbquedi2.mp3", + "audio/skill/dbzhuifeng1.mp3", + "audio/skill/dbzhuifeng2.mp3", + "audio/skill/dcaichen1.mp3", + "audio/skill/dcaichen2.mp3", + "audio/skill/dcaishou1.mp3", + "audio/skill/dcaishou2.mp3", + "audio/skill/dcanliao1.mp3", + "audio/skill/dcanliao2.mp3", + "audio/skill/dcanxu1.mp3", + "audio/skill/dcanxu2.mp3", + "audio/skill/dcanzhi1.mp3", + "audio/skill/dcanzhi2.mp3", + "audio/skill/dcbeifen1.mp3", + "audio/skill/dcbeifen2.mp3", + "audio/skill/dcbeini1.mp3", + "audio/skill/dcbeini2.mp3", + "audio/skill/dcbenshi1.mp3", + "audio/skill/dcbenshi2.mp3", + "audio/skill/dcbianzhuang1.mp3", + "audio/skill/dcbianzhuang2.mp3", + "audio/skill/dcbihuo1.mp3", + "audio/skill/dcbihuo2.mp3", + "audio/skill/dcbingji1.mp3", + "audio/skill/dcbingji2.mp3", + "audio/skill/dccaisi1.mp3", + "audio/skill/dccaisi2.mp3", + "audio/skill/dccaixia1.mp3", + "audio/skill/dccaixia2.mp3", + "audio/skill/dccaizhuang1.mp3", + "audio/skill/dccaizhuang2.mp3", + "audio/skill/dccansi1.mp3", + "audio/skill/dccansi2.mp3", + "audio/skill/dcchaixie1.mp3", + "audio/skill/dcchaixie2.mp3", + "audio/skill/dcchangqu1.mp3", + "audio/skill/dcchangqu2.mp3", + "audio/skill/dcchanjuan1.mp3", + "audio/skill/dcchanjuan2.mp3", + "audio/skill/dcchenyong1.mp3", + "audio/skill/dcchenyong2.mp3", + "audio/skill/dcchiying1.mp3", + "audio/skill/dcchiying2.mp3", + "audio/skill/dcchongwang1.mp3", + "audio/skill/dcchongwang2.mp3", + "audio/skill/dcchongxu1.mp3", + "audio/skill/dcchongxu2.mp3", + "audio/skill/dcchongyi1.mp3", + "audio/skill/dcchongyi2.mp3", + "audio/skill/dccibei1.mp3", + "audio/skill/dccibei2.mp3", + "audio/skill/dccongshi1.mp3", + "audio/skill/dccongshi2.mp3", + "audio/skill/dcctjiuxian1.mp3", + "audio/skill/dcctjiuxian2.mp3", + "audio/skill/dccuichuan1.mp3", + "audio/skill/dccuichuan2.mp3", + "audio/skill/dccuijin1.mp3", + "audio/skill/dccuijin2.mp3", + "audio/skill/dccuixin1.mp3", + "audio/skill/dccuixin2.mp3", + "audio/skill/dccunwei1.mp3", + "audio/skill/dccunwei2.mp3", + "audio/skill/dcdanyi1.mp3", + "audio/skill/dcdanyi2.mp3", + "audio/skill/dcdanying1.mp3", + "audio/skill/dcdanying2.mp3", + "audio/skill/dcdehua1.mp3", + "audio/skill/dcdehua2.mp3", + "audio/skill/dcdeshao1.mp3", + "audio/skill/dcdeshao2.mp3", + "audio/skill/dcdeshi1.mp3", + "audio/skill/dcdeshi2.mp3", + "audio/skill/dcdingji1.mp3", + "audio/skill/dcdingji2.mp3", + "audio/skill/dcditing1.mp3", + "audio/skill/dcditing2.mp3", + "audio/skill/dcdouzhen1.mp3", + "audio/skill/dcdouzhen2.mp3", + "audio/skill/dcdyqingshi1.mp3", + "audio/skill/dcdyqingshi2.mp3", + "audio/skill/dcenyu1.mp3", + "audio/skill/dcenyu2.mp3", + "audio/skill/dcfangdu1.mp3", + "audio/skill/dcfangdu2.mp3", + "audio/skill/dcfanshi1.mp3", + "audio/skill/dcfanshi2.mp3", + "audio/skill/dcfanyin1.mp3", + "audio/skill/dcfanyin2.mp3", + "audio/skill/dcfaqi1.mp3", + "audio/skill/dcfaqi2.mp3", + "audio/skill/dcfencheng1.mp3", + "audio/skill/dcfencheng2.mp3", + "audio/skill/dcfengyan1.mp3", + "audio/skill/dcfengyan2.mp3", + "audio/skill/dcfengying1.mp3", + "audio/skill/dcfengying2.mp3", + "audio/skill/dcfozong1.mp3", + "audio/skill/dcfozong2.mp3", + "audio/skill/dcfudao1.mp3", + "audio/skill/dcfudao2.mp3", + "audio/skill/dcfudou1.mp3", + "audio/skill/dcfudou2.mp3", + "audio/skill/dcfuli1.mp3", + "audio/skill/dcfuli2.mp3", + "audio/skill/dcfumou1.mp3", + "audio/skill/dcfumou2.mp3", + "audio/skill/dcfuning1.mp3", + "audio/skill/dcfuning2.mp3", + "audio/skill/dcfuxue1.mp3", + "audio/skill/dcfuxue2.mp3", + "audio/skill/dcgangu1.mp3", + "audio/skill/dcgangu2.mp3", + "audio/skill/dcgeyuan1.mp3", + "audio/skill/dcgeyuan2.mp3", + "audio/skill/dcgonghu1.mp3", + "audio/skill/dcgonghu2.mp3", + "audio/skill/dcguangshi1.mp3", + "audio/skill/dcguangshi2.mp3", + "audio/skill/dcgue1.mp3", + "audio/skill/dcgue2.mp3", + "audio/skill/dcgusuan1.mp3", + "audio/skill/dcgusuan2.mp3", + "audio/skill/dchanying1.mp3", + "audio/skill/dchanying2.mp3", + "audio/skill/dchaochong1.mp3", + "audio/skill/dchaochong2.mp3", + "audio/skill/dchuace1.mp3", + "audio/skill/dchuace2.mp3", + "audio/skill/dchuagui1.mp3", + "audio/skill/dchuagui2.mp3", + "audio/skill/dchuahuo1.mp3", + "audio/skill/dchuahuo2.mp3", + "audio/skill/dchuayi1.mp3", + "audio/skill/dchuayi2.mp3", + "audio/skill/dchuiling1.mp3", + "audio/skill/dchuiling2.mp3", + "audio/skill/dchuishu1.mp3", + "audio/skill/dchuishu2.mp3", + "audio/skill/dchuizhi1.mp3", + "audio/skill/dchuizhi2.mp3", + "audio/skill/dchumei1.mp3", + "audio/skill/dchumei2.mp3", + "audio/skill/dcjianguo1.mp3", + "audio/skill/dcjianguo2.mp3", + "audio/skill/dcjianji1.mp3", + "audio/skill/dcjianji2.mp3", + "audio/skill/dcjianying1.mp3", + "audio/skill/dcjianying2.mp3", + "audio/skill/dcjianzheng1.mp3", + "audio/skill/dcjianzheng2.mp3", + "audio/skill/dcjianzhuan1.mp3", + "audio/skill/dcjianzhuan2.mp3", + "audio/skill/dcjiaofeng1.mp3", + "audio/skill/dcjiaofeng2.mp3", + "audio/skill/dcjiaoxia1.mp3", + "audio/skill/dcjiaoxia2.mp3", + "audio/skill/dcjichun1.mp3", + "audio/skill/dcjichun2.mp3", + "audio/skill/dcjieling1.mp3", + "audio/skill/dcjieling2.mp3", + "audio/skill/dcjieshu1.mp3", + "audio/skill/dcjieshu2.mp3", + "audio/skill/dcjiexing1.mp3", + "audio/skill/dcjiexing2.mp3", + "audio/skill/dcjiezhen1.mp3", + "audio/skill/dcjiezhen2.mp3", + "audio/skill/dcjijiao1.mp3", + "audio/skill/dcjijiao2.mp3", + "audio/skill/dcjincui1.mp3", + "audio/skill/dcjincui2.mp3", + "audio/skill/dcjinggong1.mp3", + "audio/skill/dcjinggong2.mp3", + "audio/skill/dcjingzao1.mp3", + "audio/skill/dcjingzao2.mp3", + "audio/skill/dcjini1.mp3", + "audio/skill/dcjini2.mp3", + "audio/skill/dcjinjian1.mp3", + "audio/skill/dcjinjian2.mp3", + "audio/skill/dcjinjie1.mp3", + "audio/skill/dcjinjie2.mp3", + "audio/skill/dcjinjin1.mp3", + "audio/skill/dcjinjin2.mp3", + "audio/skill/dcjiudun1.mp3", + "audio/skill/dcjiudun2.mp3", + "audio/skill/dcjiushi1.mp3", + "audio/skill/dcjiushi2.mp3", + "audio/skill/dcjizhong1.mp3", + "audio/skill/dcjizhong2.mp3", + "audio/skill/dcjue1.mp3", + "audio/skill/dcjue2.mp3", + "audio/skill/dcjuejing1.mp3", + "audio/skill/dcjuejing2.mp3", + "audio/skill/dcjujian1.mp3", + "audio/skill/dcjujian2.mp3", + "audio/skill/dcjuying1.mp3", + "audio/skill/dcjuying2.mp3", + "audio/skill/dckaiji1.mp3", + "audio/skill/dckaiji2.mp3", + "audio/skill/dckanji1.mp3", + "audio/skill/dckanji2.mp3", + "audio/skill/dckuizhen1.mp3", + "audio/skill/dckuizhen2.mp3", + "audio/skill/dclbjiuxian1.mp3", + "audio/skill/dclbjiuxian2.mp3", + "audio/skill/dcliangxiu1.mp3", + "audio/skill/dcliangxiu2.mp3", + "audio/skill/dclianzhi1.mp3", + "audio/skill/dclianzhi2.mp3", + "audio/skill/dclibang1.mp3", + "audio/skill/dclibang2.mp3", + "audio/skill/dcliehou1.mp3", + "audio/skill/dcliehou2.mp3", + "audio/skill/dcligong1.mp3", + "audio/skill/dcligong2.mp3", + "audio/skill/dclingfang1.mp3", + "audio/skill/dclingfang2.mp3", + "audio/skill/dclinghui1.mp3", + "audio/skill/dclinghui2.mp3", + "audio/skill/dclingkong1.mp3", + "audio/skill/dclingkong2.mp3", + "audio/skill/dclingxi1.mp3", + "audio/skill/dclingxi2.mp3", + "audio/skill/dclingyin1.mp3", + "audio/skill/dclingyin2.mp3", + "audio/skill/dclingyue1.mp3", + "audio/skill/dclingyue2.mp3", + "audio/skill/dcliuzhuan1.mp3", + "audio/skill/dcliuzhuan2.mp3", + "audio/skill/dcliying1.mp3", + "audio/skill/dcliying2.mp3", + "audio/skill/dclonggong1.mp3", + "audio/skill/dclonggong2.mp3", + "audio/skill/dclonghun1.mp3", + "audio/skill/dclonghun2.mp3", + "audio/skill/dclongsong1.mp3", + "audio/skill/dclongsong2.mp3", + "audio/skill/dcluochong1.mp3", + "audio/skill/dcluochong2.mp3", + "audio/skill/dclvecheng1.mp3", + "audio/skill/dclvecheng2.mp3", + "audio/skill/dcmanzhi1.mp3", + "audio/skill/dcmanzhi2.mp3", + "audio/skill/dcmengjie1.mp3", + "audio/skill/dcmengjie2.mp3", + "audio/skill/dcmieji1.mp3", + "audio/skill/dcmieji2.mp3", + "audio/skill/dcmingfa1.mp3", + "audio/skill/dcmingfa2.mp3", + "audio/skill/dcminze1.mp3", + "audio/skill/dcminze2.mp3", + "audio/skill/dcmiyi1.mp3", + "audio/skill/dcmiyi2.mp3", + "audio/skill/dcmiyun1.mp3", + "audio/skill/dcmiyun2.mp3", + "audio/skill/dcmoyu1.mp3", + "audio/skill/dcmoyu2.mp3", + "audio/skill/dcneifa1.mp3", + "audio/skill/dcneifa2.mp3", + "audio/skill/dcniji1.mp3", + "audio/skill/dcniji2.mp3", + "audio/skill/dcnuanhui1.mp3", + "audio/skill/dcnuanhui2.mp3", + "audio/skill/dcnuchen1.mp3", + "audio/skill/dcnuchen2.mp3", + "audio/skill/dcnutao1.mp3", + "audio/skill/dcnutao2.mp3", + "audio/skill/dcnutao3.mp3", + "audio/skill/dcnutao4.mp3", + "audio/skill/dcpandi1.mp3", + "audio/skill/dcpandi2.mp3", + "audio/skill/dcpeiqi1.mp3", + "audio/skill/dcpeiqi2.mp3", + "audio/skill/dcpijing1.mp3", + "audio/skill/dcpijing2.mp3", + "audio/skill/dcpingxi1.mp3", + "audio/skill/dcpingxi2.mp3", + "audio/skill/dcpitian1.mp3", + "audio/skill/dcpitian2.mp3", + "audio/skill/dcporui1.mp3", + "audio/skill/dcporui2.mp3", + "audio/skill/dcposuo1.mp3", + "audio/skill/dcposuo2.mp3", + "audio/skill/dcpoyuan1.mp3", + "audio/skill/dcpoyuan2.mp3", + "audio/skill/dcqiangzhi1.mp3", + "audio/skill/dcqiangzhi2.mp3", + "audio/skill/dcqianzheng1.mp3", + "audio/skill/dcqianzheng2.mp3", + "audio/skill/dcqiaomeng1.mp3", + "audio/skill/dcqiaomeng2.mp3", + "audio/skill/dcqijing1.mp3", + "audio/skill/dcqijing2.mp3", + "audio/skill/dcqinghuang1.mp3", + "audio/skill/dcqinghuang2.mp3", + "audio/skill/dcqingren1.mp3", + "audio/skill/dcqingren2.mp3", + "audio/skill/dcqingshi1.mp3", + "audio/skill/dcqingshi2.mp3", + "audio/skill/dcqingyan1.mp3", + "audio/skill/dcqingyan2.mp3", + "audio/skill/dcqinqing1.mp3", + "audio/skill/dcqinqing2.mp3", + "audio/skill/dcqinshen1.mp3", + "audio/skill/dcqinshen2.mp3", + "audio/skill/dcqiongying1.mp3", + "audio/skill/dcqiongying2.mp3", + "audio/skill/dcqiqin_yue_daqiao1.mp3", + "audio/skill/dcqiqin_yue_daqiao2.mp3", + "audio/skill/dcqiqin1.mp3", + "audio/skill/dcqiqin2.mp3", + "audio/skill/dcquanjian1.mp3", + "audio/skill/dcquanjian2.mp3", + "audio/skill/dcquanshou1.mp3", + "audio/skill/dcquanshou2.mp3", + "audio/skill/dcrihui1.mp3", + "audio/skill/dcrihui2.mp3", + "audio/skill/dcruizhan1.mp3", + "audio/skill/dcruizhan2.mp3", + "audio/skill/dcruxian1.mp3", + "audio/skill/dcruxian2.mp3", + "audio/skill/dcruyi1.mp3", + "audio/skill/dcruyi2.mp3", + "audio/skill/dcsantou1.mp3", + "audio/skill/dcsantou2.mp3", + "audio/skill/dcsaowei1.mp3", + "audio/skill/dcsaowei2.mp3", + "audio/skill/dcsbmengmou1.mp3", + "audio/skill/dcsbmengmou2.mp3", + "audio/skill/dcsbmingshi1.mp3", + "audio/skill/dcsbmingshi2.mp3", + "audio/skill/dcsbpingliao_dc_sb_simayi_shadow1.mp3", + "audio/skill/dcsbpingliao_dc_sb_simayi_shadow2.mp3", + "audio/skill/dcsbpingliao1.mp3", + "audio/skill/dcsbpingliao2.mp3", + "audio/skill/dcsbquanmou_dc_sb_simayi_shadow1.mp3", + "audio/skill/dcsbquanmou_dc_sb_simayi_shadow2.mp3", + "audio/skill/dcsbquanmou1.mp3", + "audio/skill/dcsbquanmou2.mp3", + "audio/skill/dcsbronghuo1.mp3", + "audio/skill/dcsbronghuo2.mp3", + "audio/skill/dcsbyingmou1.mp3", + "audio/skill/dcsbyingmou2.mp3", + "audio/skill/dcshangyu1.mp3", + "audio/skill/dcshangyu2.mp3", + "audio/skill/dcshengdu1.mp3", + "audio/skill/dcshengdu2.mp3", + "audio/skill/dcshexue1.mp3", + "audio/skill/dcshexue2.mp3", + "audio/skill/dcshibei1.mp3", + "audio/skill/dcshibei2.mp3", + "audio/skill/dcshiji1.mp3", + "audio/skill/dcshiji2.mp3", + "audio/skill/dcshiju1.mp3", + "audio/skill/dcshiju2.mp3", + "audio/skill/dcshilie1.mp3", + "audio/skill/dcshilie2.mp3", + "audio/skill/dcshixian1.mp3", + "audio/skill/dcshixian2.mp3", + "audio/skill/dcshizhao1.mp3", + "audio/skill/dcshizhao2.mp3", + "audio/skill/dcshizong1.mp3", + "audio/skill/dcshizong2.mp3", + "audio/skill/dcshoutan1.mp3", + "audio/skill/dcshoutan2.mp3", + "audio/skill/dcshouze.mp3", + "audio/skill/dcshuaijie1.mp3", + "audio/skill/dcshuaijie2.mp3", + "audio/skill/dcshuangjia1.mp3", + "audio/skill/dcshuangjia2.mp3", + "audio/skill/dcshuangren1.mp3", + "audio/skill/dcshuangren2.mp3", + "audio/skill/dcshuhe1.mp3", + "audio/skill/dcshuhe2.mp3", + "audio/skill/dcsigong1.mp3", + "audio/skill/dcsigong2.mp3", + "audio/skill/dcsilun1.mp3", + "audio/skill/dcsilun2.mp3", + "audio/skill/dcsilve1.mp3", + "audio/skill/dcsilve2.mp3", + "audio/skill/dcsitian1.mp3", + "audio/skill/dcsitian2.mp3", + "audio/skill/dcsuifu1.mp3", + "audio/skill/dcsuifu2.mp3", + "audio/skill/dcsushou1.mp3", + "audio/skill/dcsushou2.mp3", + "audio/skill/dctaji1.mp3", + "audio/skill/dctaji2.mp3", + "audio/skill/dctianji1.mp3", + "audio/skill/dctianji2.mp3", + "audio/skill/dctingxian1.mp3", + "audio/skill/dctingxian2.mp3", + "audio/skill/dctongguan1.mp3", + "audio/skill/dctongguan2.mp3", + "audio/skill/dctongliao1.mp3", + "audio/skill/dctongliao2.mp3", + "audio/skill/dctongliao3.mp3", + "audio/skill/dctongye1.mp3", + "audio/skill/dctongye2.mp3", + "audio/skill/dctujue1.mp3", + "audio/skill/dctujue2.mp3", + "audio/skill/dctuoyu1.mp3", + "audio/skill/dctuoyu2.mp3", + "audio/skill/dcwanglu1.mp3", + "audio/skill/dcwanglu2.mp3", + "audio/skill/dcwangyuan1.mp3", + "audio/skill/dcwangyuan2.mp3", + "audio/skill/dcweidang1.mp3", + "audio/skill/dcweidang2.mp3", + "audio/skill/dcweiwan1.mp3", + "audio/skill/dcweiwan2.mp3", + "audio/skill/dcwencan1.mp3", + "audio/skill/dcwencan2.mp3", + "audio/skill/dcwudao1.mp3", + "audio/skill/dcwudao2.mp3", + "audio/skill/dcwudao3.mp3", + "audio/skill/dcwujie1.mp3", + "audio/skill/dcwujie2.mp3", + "audio/skill/dcwumei1.mp3", + "audio/skill/dcwumei2.mp3", + "audio/skill/dcwuyuan1.mp3", + "audio/skill/dcwuyuan2.mp3", + "audio/skill/dcxiace1.mp3", + "audio/skill/dcxiace2.mp3", + "audio/skill/dcxialei1.mp3", + "audio/skill/dcxialei2.mp3", + "audio/skill/dcxiangmian1.mp3", + "audio/skill/dcxiangmian2.mp3", + "audio/skill/dcxiangshu1.mp3", + "audio/skill/dcxiangshu2.mp3", + "audio/skill/dcxianjin1.mp3", + "audio/skill/dcxianjin2.mp3", + "audio/skill/dcxianshu1.mp3", + "audio/skill/dcxianshu2.mp3", + "audio/skill/dcxianzhu1.mp3", + "audio/skill/dcxianzhu2.mp3", + "audio/skill/dcxiaojuan1.mp3", + "audio/skill/dcxiaojuan2.mp3", + "audio/skill/dcxiaoren1.mp3", + "audio/skill/dcxiaoren2.mp3", + "audio/skill/dcxiaoxi1.mp3", + "audio/skill/dcxiaoxi2.mp3", + "audio/skill/dcxiaoyin1.mp3", + "audio/skill/dcxiaoyin2.mp3", + "audio/skill/dcxieshou1.mp3", + "audio/skill/dcxieshou2.mp3", + "audio/skill/dcxinyou1.mp3", + "audio/skill/dcxinyou2.mp3", + "audio/skill/dcxiongmu1.mp3", + "audio/skill/dcxiongmu2.mp3", + "audio/skill/dcxiuwen1.mp3", + "audio/skill/dcxiuwen2.mp3", + "audio/skill/dcxuewei1.mp3", + "audio/skill/dcxuewei2.mp3", + "audio/skill/dcxunbie1.mp3", + "audio/skill/dcxunbie2.mp3", + "audio/skill/dcxunji1.mp3", + "audio/skill/dcxunji2.mp3", + "audio/skill/dcxunjie1.mp3", + "audio/skill/dcxunjie2.mp3", + "audio/skill/dcyaoyi1.mp3", + "audio/skill/dcyaoyi2.mp3", + "audio/skill/dcyicong1.mp3", + "audio/skill/dcyicong2.mp3", + "audio/skill/dcyijia1.mp3", + "audio/skill/dcyijia2.mp3", + "audio/skill/dcyingshi1.mp3", + "audio/skill/dcyingshi2.mp3", + "audio/skill/dcyingtu1.mp3", + "audio/skill/dcyingtu2.mp3", + "audio/skill/dcyingyu1.mp3", + "audio/skill/dcyingyu2.mp3", + "audio/skill/dcyinjun1.mp3", + "audio/skill/dcyinjun2.mp3", + "audio/skill/dcyinlu1.mp3", + "audio/skill/dcyinlu2.mp3", + "audio/skill/dcyinshi1.mp3", + "audio/skill/dcyinshi2.mp3", + "audio/skill/dcyishu1.mp3", + "audio/skill/dcyishu2.mp3", + "audio/skill/dcyiyong1.mp3", + "audio/skill/dcyiyong2.mp3", + "audio/skill/dcyongbi1.mp3", + "audio/skill/dcyongbi2.mp3", + "audio/skill/dcyouqi1.mp3", + "audio/skill/dcyouqi2.mp3", + "audio/skill/dcyouzhan1.mp3", + "audio/skill/dcyouzhan2.mp3", + "audio/skill/dcyuandi1.mp3", + "audio/skill/dcyuandi2.mp3", + "audio/skill/dcyuanmo1.mp3", + "audio/skill/dcyuanmo2.mp3", + "audio/skill/dcyuguan1.mp3", + "audio/skill/dcyuguan2.mp3", + "audio/skill/dcyuxin1.mp3", + "audio/skill/dcyuxin2.mp3", + "audio/skill/dczecai1.mp3", + "audio/skill/dczecai2.mp3", + "audio/skill/dczhangcai1.mp3", + "audio/skill/dczhangcai2.mp3", + "audio/skill/dczhanmeng1.mp3", + "audio/skill/dczhanmeng2.mp3", + "audio/skill/dczhanyi1.mp3", + "audio/skill/dczhanyi2.mp3", + "audio/skill/dczhaohan1.mp3", + "audio/skill/dczhaohan2.mp3", + "audio/skill/dczhaowen1.mp3", + "audio/skill/dczhaowen2.mp3", + "audio/skill/dczhengxu1.mp3", + "audio/skill/dczhengxu2.mp3", + "audio/skill/dczhenze1.mp3", + "audio/skill/dczhenze2.mp3", + "audio/skill/dczhifou1.mp3", + "audio/skill/dczhifou2.mp3", + "audio/skill/dczhimin1.mp3", + "audio/skill/dczhimin2.mp3", + "audio/skill/dczhizhe1.mp3", + "audio/skill/dczhizhe2.mp3", + "audio/skill/dczhongji1.mp3", + "audio/skill/dczhongji2.mp3", + "audio/skill/dczhongjie1.mp3", + "audio/skill/dczhongjie2.mp3", + "audio/skill/dczhouli2.mp3", + "audio/skill/dczhubi1.mp3", + "audio/skill/dczhubi2.mp3", + "audio/skill/dczhuiyi1.mp3", + "audio/skill/dczhuiyi2.mp3", + "audio/skill/dczhuoli1.mp3", + "audio/skill/dczigu1.mp3", + "audio/skill/dczigu2.mp3", + "audio/skill/dczimu1.mp3", + "audio/skill/dczixi1.mp3", + "audio/skill/dczixi2.mp3", + "audio/skill/dczuojian1.mp3", + "audio/skill/dczuojian2.mp3", + "audio/skill/dczuowei1.mp3", + "audio/skill/dczuowei2.mp3", + "audio/skill/debao1.mp3", + "audio/skill/debao2.mp3", + "audio/skill/decadejingce1.mp3", + "audio/skill/decadejingce2.mp3", + "audio/skill/decadejinjiu1.mp3", + "audio/skill/decadejinjiu2.mp3", + "audio/skill/decadepojun1.mp3", + "audio/skill/decadepojun2.mp3", + "audio/skill/decadexianzhen1.mp3", + "audio/skill/decadexianzhen2.mp3", + "audio/skill/decadezhenjun1.mp3", + "audio/skill/decadezhenjun2.mp3", + "audio/skill/decadezishou1.mp3", + "audio/skill/decadezishou2.mp3", + "audio/skill/decadezongshi1.mp3", + "audio/skill/decadezongshi2.mp3", + "audio/skill/dengji1.mp3", + "audio/skill/dengji2.mp3", + "audio/skill/dengzhi.mp3", + "audio/skill/dezhang1.mp3", + "audio/skill/dezhang2.mp3", + "audio/skill/diancai1.mp3", + "audio/skill/diancai2.mp3", + "audio/skill/diaodu1.mp3", + "audio/skill/diaodu2.mp3", + "audio/skill/diaoling1.mp3", + "audio/skill/diaoling2.mp3", + "audio/skill/diezhang1.mp3", + "audio/skill/diezhang2.mp3", + "audio/skill/difa1.mp3", + "audio/skill/difa2.mp3", + "audio/skill/dili_chigang1.mp3", + "audio/skill/dili_chigang2.mp3", + "audio/skill/dili_jiaohui1.mp3", + "audio/skill/dili_jiaohui2.mp3", + "audio/skill/dili_qionglan1.mp3", + "audio/skill/dili_qionglan2.mp3", + "audio/skill/dili_quandao1.mp3", + "audio/skill/dili_quandao2.mp3", + "audio/skill/dili_shengzhi1.mp3", + "audio/skill/dili_shengzhi2.mp3", + "audio/skill/dili_yuanlv1.mp3", + "audio/skill/dili_yuanlv2.mp3", + "audio/skill/dili1.mp3", + "audio/skill/dili2.mp3", + "audio/skill/dimeng1.mp3", + "audio/skill/dimeng2.mp3", + "audio/skill/dingfa1.mp3", + "audio/skill/dingfa2.mp3", + "audio/skill/dinghan1.mp3", + "audio/skill/dinghan2.mp3", + "audio/skill/dingpan1.mp3", + "audio/skill/dingpan2.mp3", + "audio/skill/dingpin1.mp3", + "audio/skill/dingpin2.mp3", + "audio/skill/dingzhou1.mp3", + "audio/skill/dingzhou2.mp3", + "audio/skill/disordersidi1.mp3", + "audio/skill/disordersidi2.mp3", + "audio/skill/donggui1.mp3", + "audio/skill/donggui2.mp3", + "audio/skill/drlt_congjian1.mp3", + "audio/skill/drlt_congjian2.mp3", + "audio/skill/drlt_duorui1.mp3", + "audio/skill/drlt_duorui2.mp3", + "audio/skill/drlt_hongju1.mp3", + "audio/skill/drlt_hongju2.mp3", + "audio/skill/drlt_huairou1.mp3", + "audio/skill/drlt_huairou2.mp3", + "audio/skill/drlt_jieying1.mp3", + "audio/skill/drlt_jieying2.mp3", + "audio/skill/drlt_jueyan1.mp3", + "audio/skill/drlt_jueyan2.mp3", + "audio/skill/drlt_poshi1.mp3", + "audio/skill/drlt_poshi2.mp3", + "audio/skill/drlt_poxi1.mp3", + "audio/skill/drlt_poxi2.mp3", + "audio/skill/drlt_qianjie1.mp3", + "audio/skill/drlt_qianjie2.mp3", + "audio/skill/drlt_qingce1.mp3", + "audio/skill/drlt_qingce2.mp3", + "audio/skill/drlt_wanglie1.mp3", + "audio/skill/drlt_wanglie2.mp3", + "audio/skill/drlt_weidi1.mp3", + "audio/skill/drlt_weidi2.mp3", + "audio/skill/drlt_xiongluan1.mp3", + "audio/skill/drlt_xiongluan2.mp3", + "audio/skill/drlt_yongsi1.mp3", + "audio/skill/drlt_yongsi2.mp3", + "audio/skill/drlt_zhenggu1.mp3", + "audio/skill/drlt_zhenggu2.mp3", + "audio/skill/drlt_zhenrong1.mp3", + "audio/skill/drlt_zhenrong2.mp3", + "audio/skill/drlt_zhiti1.mp3", + "audio/skill/drlt_zhiti2.mp3", + "audio/skill/duanbi1.mp3", + "audio/skill/duanbi2.mp3", + "audio/skill/duanbing_heqi1.mp3", + "audio/skill/duanbing_heqi2.mp3", + "audio/skill/duanbing1.mp3", + "audio/skill/duanbing2.mp3", + "audio/skill/duanchang_ol_caiwenji1.mp3", + "audio/skill/duanchang_ol_caiwenji2.mp3", + "audio/skill/duanchang_re_caiwenji1.mp3", + "audio/skill/duanchang_re_caiwenji2.mp3", + "audio/skill/duanchang1.mp3", + "audio/skill/duanchang2.mp3", + "audio/skill/duanliang1_re_xuhuang1.mp3", + "audio/skill/duanliang1_re_xuhuang2.mp3", + "audio/skill/duanliang11.mp3", + "audio/skill/duanliang12.mp3", + "audio/skill/duansuo1.mp3", + "audio/skill/duansuo2.mp3", + "audio/skill/duanwan1.mp3", + "audio/skill/duanwan2.mp3", + "audio/skill/duanxie1.mp3", + "audio/skill/duanxie2.mp3", + "audio/skill/dujin1.mp3", + "audio/skill/dujin2.mp3", + "audio/skill/duliang1.mp3", + "audio/skill/duliang2.mp3", + "audio/skill/dulie1.mp3", + "audio/skill/dulie2.mp3", + "audio/skill/dunshi1.mp3", + "audio/skill/dunshi2.mp3", + "audio/skill/dunxi1.mp3", + "audio/skill/dunxi2.mp3", + "audio/skill/duodao1.mp3", + "audio/skill/duodao2.mp3", + "audio/skill/duoduan1.mp3", + "audio/skill/duoduan2.mp3", + "audio/skill/duoji1.mp3", + "audio/skill/duoji2.mp3", + "audio/skill/duoshi1.mp3", + "audio/skill/duoshi2.mp3", + "audio/skill/dushi1.mp3", + "audio/skill/dushi2.mp3", + "audio/skill/duwang1.mp3", + "audio/skill/duwang2.mp3", + "audio/skill/duwu1.mp3", + "audio/skill/duwu2.mp3", + "audio/skill/dzgengzhan1.mp3", + "audio/skill/dzgengzhan2.mp3", + "audio/skill/dzkanpo1.mp3", + "audio/skill/dzkanpo2.mp3", + "audio/skill/ejian1.mp3", + "audio/skill/ejian2.mp3", + "audio/skill/enyuan1.mp3", + "audio/skill/enyuan2.mp3", + "audio/skill/equan1.mp3", + "audio/skill/equan2.mp3", + "audio/skill/faen1.mp3", + "audio/skill/faen2.mp3", + "audio/skill/fanghun1.mp3", + "audio/skill/fanghun2.mp3", + "audio/skill/fangquan1.mp3", + "audio/skill/fangquan2.mp3", + "audio/skill/fangtian_skill.mp3", + "audio/skill/fangzhu1.mp3", + "audio/skill/fangzhu2.mp3", + "audio/skill/fanjian1.mp3", + "audio/skill/fanjian2.mp3", + "audio/skill/fankui1.mp3", + "audio/skill/fankui2.mp3", + "audio/skill/fanxiang1.mp3", + "audio/skill/fanxiang2.mp3", + "audio/skill/fencheng1.mp3", + "audio/skill/fencheng2.mp3", + "audio/skill/fengji1.mp3", + "audio/skill/fengji2.mp3", + "audio/skill/fengjie1.mp3", + "audio/skill/fengjie2.mp3", + "audio/skill/fengliang1.mp3", + "audio/skill/fengliang2.mp3", + "audio/skill/fenglve1.mp3", + "audio/skill/fenglve2.mp3", + "audio/skill/fengpo1.mp3", + "audio/skill/fengpo2.mp3", + "audio/skill/fengwu1.mp3", + "audio/skill/fengwu2.mp3", + "audio/skill/fengxiang1.mp3", + "audio/skill/fengxiang2.mp3", + "audio/skill/fengyang1.mp3", + "audio/skill/fengyang2.mp3", + "audio/skill/fengying1.mp3", + "audio/skill/fengying2.mp3", + "audio/skill/fenji1.mp3", + "audio/skill/fenji2.mp3", + "audio/skill/fenli_xin_zhuhuan1.mp3", + "audio/skill/fenli_xin_zhuhuan2.mp3", + "audio/skill/fenli1.mp3", + "audio/skill/fenli2.mp3", + "audio/skill/fenming1.mp3", + "audio/skill/fenming2.mp3", + "audio/skill/fenrui1.mp3", + "audio/skill/fenrui2.mp3", + "audio/skill/fensi1.mp3", + "audio/skill/fensi2.mp3", + "audio/skill/fentian1.mp3", + "audio/skill/fentian2.mp3", + "audio/skill/fenwei_heqi1.mp3", + "audio/skill/fenwei_heqi2.mp3", + "audio/skill/fenwei1.mp3", + "audio/skill/fenwei2.mp3", + "audio/skill/fenxin1.mp3", + "audio/skill/fenxin2.mp3", + "audio/skill/fenxun1.mp3", + "audio/skill/fenxun2.mp3", + "audio/skill/fenyin1.mp3", + "audio/skill/fenyin2.mp3", + "audio/skill/fenyong1.mp3", + "audio/skill/fenyong2.mp3", + "audio/skill/fenyue1.mp3", + "audio/skill/fenyue2.mp3", + "audio/skill/fubi1.mp3", + "audio/skill/fubi2.mp3", + "audio/skill/fuhan1.mp3", + "audio/skill/fuhan2.mp3", + "audio/skill/fuhun_re_guanzhang1.mp3", + "audio/skill/fuhun_re_guanzhang2.mp3", + "audio/skill/fuhun1.mp3", + "audio/skill/fuhun2.mp3", + "audio/skill/fuli1.mp3", + "audio/skill/fuli2.mp3", + "audio/skill/fulin1.mp3", + "audio/skill/fulin2.mp3", + "audio/skill/fuman1.mp3", + "audio/skill/fuman2.mp3", + "audio/skill/fumian1.mp3", + "audio/skill/fumian2.mp3", + "audio/skill/funan1.mp3", + "audio/skill/funan2.mp3", + "audio/skill/fuping1.mp3", + "audio/skill/fuping2.mp3", + "audio/skill/fuqi1.mp3", + "audio/skill/fuqi2.mp3", + "audio/skill/fuyuan1.mp3", + "audio/skill/fuyuan2.mp3", + "audio/skill/fuzhong1.mp3", + "audio/skill/fuzhong2.mp3", + "audio/skill/fuzhu1.mp3", + "audio/skill/fuzhu2.mp3", + "audio/skill/fyjianyu1.mp3", + "audio/skill/fyjianyu2.mp3", + "audio/skill/fz_liegong.mp3", + "audio/skill/fz_new_longdan.mp3", + "audio/skill/fz_new_paoxiao.mp3", + "audio/skill/fz_new_tieji.mp3", + "audio/skill/fz_wusheng.mp3", + "audio/skill/fz_xinkuanggu.mp3", + "audio/skill/ganglie1.mp3", + "audio/skill/ganglie2.mp3", + "audio/skill/gangzhi1.mp3", + "audio/skill/gangzhi2.mp3", + "audio/skill/ganlu1.mp3", + "audio/skill/ganlu2.mp3", + "audio/skill/gaoling1.mp3", + "audio/skill/gaoling2.mp3", + "audio/skill/gaoyuan1.mp3", + "audio/skill/gaoyuan2.mp3", + "audio/skill/gebo1.mp3", + "audio/skill/gebo2.mp3", + "audio/skill/gnjinfan1.mp3", + "audio/skill/gnjinfan2.mp3", + "audio/skill/gnsheque1.mp3", + "audio/skill/gnsheque2.mp3", + "audio/skill/gongao1.mp3", + "audio/skill/gongao2.mp3", + "audio/skill/gonghuan1.mp3", + "audio/skill/gonghuan2.mp3", + "audio/skill/gongji1.mp3", + "audio/skill/gongji2.mp3", + "audio/skill/gongjian1.mp3", + "audio/skill/gongjian2.mp3", + "audio/skill/gongsun1.mp3", + "audio/skill/gongsun2.mp3", + "audio/skill/gongxin_gexuan1.mp3", + "audio/skill/gongxin_re_lvmeng1.mp3", + "audio/skill/gongxin_re_lvmeng2.mp3", + "audio/skill/gongxin1.mp3", + "audio/skill/gongxin2.mp3", + "audio/skill/gongxiu1.mp3", + "audio/skill/gongxiu2.mp3", + "audio/skill/guanshi_skill.mp3", + "audio/skill/guanxing_gexuan1.mp3", + "audio/skill/guanxing_jiangwei1.mp3", + "audio/skill/guanxing_jiangwei2.mp3", + "audio/skill/guanxing_ol_jiangwei1.mp3", + "audio/skill/guanxing_ol_jiangwei2.mp3", + "audio/skill/guanxing_re_jiangwei1.mp3", + "audio/skill/guanxing_re_jiangwei2.mp3", + "audio/skill/guanxing_re_zhugeliang1.mp3", + "audio/skill/guanxing_re_zhugeliang2.mp3", + "audio/skill/guanxing1.mp3", + "audio/skill/guanxing2.mp3", + "audio/skill/guanxu1.mp3", + "audio/skill/guanxu2.mp3", + "audio/skill/guanzong1.mp3", + "audio/skill/guanzong2.mp3", + "audio/skill/guding_skill.mp3", + "audio/skill/guhuo_guess1.mp3", + "audio/skill/guhuo_guess2.mp3", + "audio/skill/guhuo1.mp3", + "audio/skill/guhuo2.mp3", + "audio/skill/guicai1.mp3", + "audio/skill/guicai2.mp3", + "audio/skill/guidao_sp_zhangjiao1.mp3", + "audio/skill/guidao_sp_zhangjiao2.mp3", + "audio/skill/guidao1.mp3", + "audio/skill/guidao2.mp3", + "audio/skill/guili1.mp3", + "audio/skill/guili2.mp3", + "audio/skill/guiming1.mp3", + "audio/skill/guiming2.mp3", + "audio/skill/guimou1.mp3", + "audio/skill/guimou2.mp3", + "audio/skill/guixin1.mp3", + "audio/skill/guixin2.mp3", + "audio/skill/guixiu1.mp3", + "audio/skill/guixiu2.mp3", + "audio/skill/guizao1.mp3", + "audio/skill/guizao2.mp3", + "audio/skill/guizhen1.mp3", + "audio/skill/guizhen2.mp3", + "audio/skill/guju_tw_beimihu1.mp3", + "audio/skill/guju_tw_beimihu2.mp3", + "audio/skill/guju1.mp3", + "audio/skill/guju2.mp3", + "audio/skill/guose1.mp3", + "audio/skill/guose2.mp3", + "audio/skill/guowu1.mp3", + "audio/skill/guowu2.mp3", + "audio/skill/gushe1.mp3", + "audio/skill/gushe2.mp3", + "audio/skill/guying1.mp3", + "audio/skill/guying2.mp3", + "audio/skill/guzheng_re_zhangzhang1.mp3", + "audio/skill/guzheng_re_zhangzhang2.mp3", + "audio/skill/guzheng1.mp3", + "audio/skill/guzheng2.mp3", + "audio/skill/gxlianhua1.mp3", + "audio/skill/gxlianhua2.mp3", + "audio/skill/gz_jun_liubei.mp3", + "audio/skill/gz_jun_sunquan.mp3", + "audio/skill/gzbaolie1.mp3", + "audio/skill/gzbaolie2.mp3", + "audio/skill/gzbiluan1.mp3", + "audio/skill/gzbiluan2.mp3", + "audio/skill/gzbuqu1.mp3", + "audio/skill/gzbuqu2.mp3", + "audio/skill/gzbushi1.mp3", + "audio/skill/gzbushi2.mp3", + "audio/skill/gzchenglve1.mp3", + "audio/skill/gzchenglve2.mp3", + "audio/skill/gzcongcha1.mp3", + "audio/skill/gzcongcha2.mp3", + "audio/skill/gzduannian1.mp3", + "audio/skill/gzduannian2.mp3", + "audio/skill/gzduwu1.mp3", + "audio/skill/gzduwu2.mp3", + "audio/skill/gzfangyuan1.mp3", + "audio/skill/gzfangyuan2.mp3", + "audio/skill/gzfankui1.mp3", + "audio/skill/gzfankui2.mp3", + "audio/skill/gzfudi1.mp3", + "audio/skill/gzfudi2.mp3", + "audio/skill/gzhuaiyi1.mp3", + "audio/skill/gzhuaiyi2.mp3", + "audio/skill/gzjiancai1.mp3", + "audio/skill/gzjiancai2.mp3", + "audio/skill/gzjianliang1.mp3", + "audio/skill/gzjianliang2.mp3", + "audio/skill/gzjieyue1.mp3", + "audio/skill/gzjieyue2.mp3", + "audio/skill/gzjili1.mp3", + "audio/skill/gzjili2.mp3", + "audio/skill/gzjinfa1.mp3", + "audio/skill/gzjinfa2.mp3", + "audio/skill/gzjixi.mp3", + "audio/skill/gzjixi1.mp3", + "audio/skill/gzjuejue1.mp3", + "audio/skill/gzjuejue2.mp3", + "audio/skill/gzkuangcai1.mp3", + "audio/skill/gzkuangcai2.mp3", + "audio/skill/gzlianpian1.mp3", + "audio/skill/gzlianpian2.mp3", + "audio/skill/gzlianyou1.mp3", + "audio/skill/gzlianyou2.mp3", + "audio/skill/gzlixia1.mp3", + "audio/skill/gzlixia2.mp3", + "audio/skill/gzmidao1.mp3", + "audio/skill/gzmidao2.mp3", + "audio/skill/gzpaiyi1.mp3", + "audio/skill/gzpaiyi2.mp3", + "audio/skill/gzquanji1.mp3", + "audio/skill/gzquanji2.mp3", + "audio/skill/gzshejian1.mp3", + "audio/skill/gzshejian2.mp3", + "audio/skill/gzshicai1.mp3", + "audio/skill/gzshicai2.mp3", + "audio/skill/gzshilu1.mp3", + "audio/skill/gzshilu2.mp3", + "audio/skill/gzsuzhi1.mp3", + "audio/skill/gzsuzhi2.mp3", + "audio/skill/gztongduo1.mp3", + "audio/skill/gztongduo2.mp3", + "audio/skill/gztunjiang1.mp3", + "audio/skill/gztunjiang2.mp3", + "audio/skill/gzweimeng1.mp3", + "audio/skill/gzweimeng2.mp3", + "audio/skill/gzwenji1.mp3", + "audio/skill/gzwenji2.mp3", + "audio/skill/gzxingzhao_xunxun1.mp3", + "audio/skill/gzxingzhao_xunxun2.mp3", + "audio/skill/gzxingzhao1.mp3", + "audio/skill/gzxingzhao2.mp3", + "audio/skill/gzxiongnve1.mp3", + "audio/skill/gzxiongnve2.mp3", + "audio/skill/gzxishe1.mp3", + "audio/skill/gzxishe2.mp3", + "audio/skill/gzyinghun_re_sunyi1.mp3", + "audio/skill/gzyjili1.mp3", + "audio/skill/gzyjili2.mp3", + "audio/skill/gzzhaoxin1.mp3", + "audio/skill/gzzhaoxin2.mp3", + "audio/skill/gzzhidao1.mp3", + "audio/skill/gzzhidao2.mp3", + "audio/skill/gzzisui1.mp3", + "audio/skill/gzzisui2.mp3", + "audio/skill/gzzongyu1.mp3", + "audio/skill/gzzongyu2.mp3", + "audio/skill/hanbing_skill.mp3", + "audio/skill/hannan1.mp3", + "audio/skill/hannan2.mp3", + "audio/skill/hanyong1.mp3", + "audio/skill/hanyong2.mp3", + "audio/skill/hanzhan1.mp3", + "audio/skill/hanzhan2.mp3", + "audio/skill/haoshi1.mp3", + "audio/skill/haoshi2.mp3", + "audio/skill/heji1.mp3", + "audio/skill/heji2.mp3", + "audio/skill/hengjiang1.mp3", + "audio/skill/hengjiang2.mp3", + "audio/skill/hengwu1.mp3", + "audio/skill/hengwu2.mp3", + "audio/skill/hengzheng1.mp3", + "audio/skill/hengzheng2.mp3", + "audio/skill/heqia1.mp3", + "audio/skill/heqia2.mp3", + "audio/skill/hezhong1.mp3", + "audio/skill/hezhong2.mp3", + "audio/skill/hfjieying1.mp3", + "audio/skill/hfjieying2.mp3", + "audio/skill/hinata_ehou1.mp3", + "audio/skill/hinata_ehou2.mp3", + "audio/skill/hinata_qiulve1.mp3", + "audio/skill/hinata_qiulve2.mp3", + "audio/skill/hisako_yinbao1.mp3", + "audio/skill/hisako_yinbao2.mp3", + "audio/skill/hmxili1.mp3", + "audio/skill/hmxili2.mp3", + "audio/skill/hongde1.mp3", + "audio/skill/hongde2.mp3", + "audio/skill/hongfa_hp.mp3", + "audio/skill/hongfa1.mp3", + "audio/skill/hongfa2.mp3", + "audio/skill/hongyan.mp3", + "audio/skill/hongyi1.mp3", + "audio/skill/hongyi2.mp3", + "audio/skill/hongyuan1.mp3", + "audio/skill/hongyuan2.mp3", + "audio/skill/houfeng1.mp3", + "audio/skill/houfeng2.mp3", + "audio/skill/houfeng3.mp3", + "audio/skill/huaibi1.mp3", + "audio/skill/huaibi2.mp3", + "audio/skill/huaiyi1.mp3", + "audio/skill/huaiyi2.mp3", + "audio/skill/huaiyuan1.mp3", + "audio/skill/huaiyuan2.mp3", + "audio/skill/huamu1.mp3", + "audio/skill/huamu2.mp3", + "audio/skill/huamu3.mp3", + "audio/skill/huamu4.mp3", + "audio/skill/huamu5.mp3", + "audio/skill/huamu6.mp3", + "audio/skill/huangjintianbingfu1.mp3", + "audio/skill/huangjintianbingfu2.mp3", + "audio/skill/huangkong1.mp3", + "audio/skill/huangkong2.mp3", + "audio/skill/huangtian2_re_zhangjiao1.mp3", + "audio/skill/huangtian2_re_zhangjiao2.mp3", + "audio/skill/huangtian2_zhangjiao1.mp3", + "audio/skill/huangtian2_zhangjiao2.mp3", + "audio/skill/huangtian21.mp3", + "audio/skill/huangtian22.mp3", + "audio/skill/huanhua1.mp3", + "audio/skill/huanhua2.mp3", + "audio/skill/huanshi1.mp3", + "audio/skill/huanshi2.mp3", + "audio/skill/huantu1.mp3", + "audio/skill/huantu2.mp3", + "audio/skill/huaping.mp3", + "audio/skill/huaping1.mp3", + "audio/skill/huaping2.mp3", + "audio/skill/huashen21.mp3", + "audio/skill/huashen22.mp3", + "audio/skill/huguan_wangyue1.mp3", + "audio/skill/huguan_wangyue2.mp3", + "audio/skill/huguan1.mp3", + "audio/skill/huguan2.mp3", + "audio/skill/huibian1.mp3", + "audio/skill/huibian2.mp3", + "audio/skill/huilei1.mp3", + "audio/skill/huilei2.mp3", + "audio/skill/huimin1.mp3", + "audio/skill/huimin2.mp3", + "audio/skill/huirong1.mp3", + "audio/skill/huirong2.mp3", + "audio/skill/huisheng_dc_huanghao1.mp3", + "audio/skill/huisheng_dc_huanghao2.mp3", + "audio/skill/huisheng1.mp3", + "audio/skill/huisheng2.mp3", + "audio/skill/huishi1.mp3", + "audio/skill/huishi2.mp3", + "audio/skill/huituo1.mp3", + "audio/skill/huituo2.mp3", + "audio/skill/hujia_re_caocao1.mp3", + "audio/skill/hujia_re_caocao2.mp3", + "audio/skill/hujia1.mp3", + "audio/skill/hujia2.mp3", + "audio/skill/hunzi1.mp3", + "audio/skill/hunzi2.mp3", + "audio/skill/huoji1.mp3", + "audio/skill/huoji2.mp3", + "audio/skill/huomo_huzhao1.mp3", + "audio/skill/huomo_huzhao2.mp3", + "audio/skill/huomo_re_zhongyao1.mp3", + "audio/skill/huomo_re_zhongyao2.mp3", + "audio/skill/huomo1.mp3", + "audio/skill/huomo2.mp3", + "audio/skill/huoshaowuchao.mp3", + "audio/skill/huoshou1_re_menghuo1.mp3", + "audio/skill/huoshou1_re_menghuo2.mp3", + "audio/skill/huoshou11.mp3", + "audio/skill/huoshou12.mp3", + "audio/skill/huoshui1.mp3", + "audio/skill/huoshui2.mp3", + "audio/skill/huoxin1.mp3", + "audio/skill/huoxin2.mp3", + "audio/skill/huwei1.mp3", + "audio/skill/huwei2.mp3", + "audio/skill/huxiao1.mp3", + "audio/skill/huxiao2.mp3", + "audio/skill/huyuan1.mp3", + "audio/skill/huyuan2.mp3", + "audio/skill/hxrenshi1.mp3", + "audio/skill/hxrenshi2.mp3", + "audio/skill/jiahe_put1.mp3", + "audio/skill/jiahe_put2.mp3", + "audio/skill/jiahe1.mp3", + "audio/skill/jiahe2.mp3", + "audio/skill/jianan1.mp3", + "audio/skill/jianan2.mp3", + "audio/skill/jianchu_re_pangde1.mp3", + "audio/skill/jianchu_re_pangde2.mp3", + "audio/skill/jianchu1.mp3", + "audio/skill/jianchu2.mp3", + "audio/skill/jiang_re_sunben1.mp3", + "audio/skill/jiang_re_sunben2.mp3", + "audio/skill/jiang_re_sunce1.mp3", + "audio/skill/jiang_re_sunce2.mp3", + "audio/skill/jiang_sp_lvmeng1.mp3", + "audio/skill/jiang_sp_lvmeng2.mp3", + "audio/skill/jiang1.mp3", + "audio/skill/jiang2.mp3", + "audio/skill/jiangchi1.mp3", + "audio/skill/jiangchi2.mp3", + "audio/skill/jianglue1.mp3", + "audio/skill/jianglue2.mp3", + "audio/skill/jiangxi1.mp3", + "audio/skill/jiangxi2.mp3", + "audio/skill/jianhui1.mp3", + "audio/skill/jianhui2.mp3", + "audio/skill/jianliang1.mp3", + "audio/skill/jianliang2.mp3", + "audio/skill/jianshoudaiyuan.mp3", + "audio/skill/jianshu1.mp3", + "audio/skill/jianshu2.mp3", + "audio/skill/jianxiong1.mp3", + "audio/skill/jianxiong2.mp3", + "audio/skill/jianyan1.mp3", + "audio/skill/jianyan2.mp3", + "audio/skill/jianying1.mp3", + "audio/skill/jianying2.mp3", + "audio/skill/jianzhan1.mp3", + "audio/skill/jianzhan2.mp3", + "audio/skill/jianzheng1.mp3", + "audio/skill/jianzheng2.mp3", + "audio/skill/jiaojin1.mp3", + "audio/skill/jiaojin2.mp3", + "audio/skill/jiaoxia1.mp3", + "audio/skill/jiaoxia2.mp3", + "audio/skill/jiaoying1.mp3", + "audio/skill/jiaoying2.mp3", + "audio/skill/jiaozhao1.mp3", + "audio/skill/jiaozhao2.mp3", + "audio/skill/jiaozi1.mp3", + "audio/skill/jiaozi2.mp3", + "audio/skill/jibing1.mp3", + "audio/skill/jibing2.mp3", + "audio/skill/jici1.mp3", + "audio/skill/jici2.mp3", + "audio/skill/jidian1.mp3", + "audio/skill/jidian2.mp3", + "audio/skill/jiebing1.mp3", + "audio/skill/jiebing2.mp3", + "audio/skill/jiefan_re_handang1.mp3", + "audio/skill/jiefan_re_handang2.mp3", + "audio/skill/jiefan1.mp3", + "audio/skill/jiefan2.mp3", + "audio/skill/jieliang1.mp3", + "audio/skill/jieliang2.mp3", + "audio/skill/jielie1.mp3", + "audio/skill/jielie2.mp3", + "audio/skill/jieming1.mp3", + "audio/skill/jieming2.mp3", + "audio/skill/jiewei1.mp3", + "audio/skill/jiewei2.mp3", + "audio/skill/jiexun1.mp3", + "audio/skill/jiexun2.mp3", + "audio/skill/jieyin1.mp3", + "audio/skill/jieyin2.mp3", + "audio/skill/jieyuan_less.mp3", + "audio/skill/jieyuan_more.mp3", + "audio/skill/jieyue_shan.mp3", + "audio/skill/jieyue_wuxie.mp3", + "audio/skill/jieyue1.mp3", + "audio/skill/jieyue2.mp3", + "audio/skill/jiezhong1.mp3", + "audio/skill/jiezhong2.mp3", + "audio/skill/jiezi1.mp3", + "audio/skill/jiezi2.mp3", + "audio/skill/jigong1.mp3", + "audio/skill/jigong2.mp3", + "audio/skill/jihun1.mp3", + "audio/skill/jihun2.mp3", + "audio/skill/jijiang1_liushan1.mp3", + "audio/skill/jijiang1_liushan2.mp3", + "audio/skill/jijiang1_ol_liushan1.mp3", + "audio/skill/jijiang1_ol_liushan2.mp3", + "audio/skill/jijiang1_re_liubei1.mp3", + "audio/skill/jijiang1_re_liubei2.mp3", + "audio/skill/jijiang1_re_liushan1.mp3", + "audio/skill/jijiang1_re_liushan2.mp3", + "audio/skill/jijiang11.mp3", + "audio/skill/jijiang12.mp3", + "audio/skill/jijiang2_liushan1.mp3", + "audio/skill/jijiang2_liushan2.mp3", + "audio/skill/jijiang21.mp3", + "audio/skill/jijiang22.mp3", + "audio/skill/jijing1.mp3", + "audio/skill/jijing2.mp3", + "audio/skill/jijiu_re_huatuo1.mp3", + "audio/skill/jijiu_re_huatuo2.mp3", + "audio/skill/jijiu1.mp3", + "audio/skill/jijiu2.mp3", + "audio/skill/jilei1.mp3", + "audio/skill/jilei2.mp3", + "audio/skill/jili1.mp3", + "audio/skill/jili2.mp3", + "audio/skill/jilue_fangzhu.mp3", + "audio/skill/jilue_fangzhu1.mp3", + "audio/skill/jilue_guicai.mp3", + "audio/skill/jilue_guicai1.mp3", + "audio/skill/jilue_jizhi.mp3", + "audio/skill/jilue_jizhi1.mp3", + "audio/skill/jilue_wansha.mp3", + "audio/skill/jilue_zhiheng.mp3", + "audio/skill/jilue_zhiheng1.mp3", + "audio/skill/jimeng1.mp3", + "audio/skill/jimeng2.mp3", + "audio/skill/jingce1.mp3", + "audio/skill/jingce2.mp3", + "audio/skill/jinghe1.mp3", + "audio/skill/jinghe2.mp3", + "audio/skill/jinglan1.mp3", + "audio/skill/jinglan2.mp3", + "audio/skill/jinglve1.mp3", + "audio/skill/jinglve2.mp3", + "audio/skill/jingong1.mp3", + "audio/skill/jingong2.mp3", + "audio/skill/jingzhong1.mp3", + "audio/skill/jingzhong2.mp3", + "audio/skill/jinhui1.mp3", + "audio/skill/jinhui2.mp3", + "audio/skill/jinjian1.mp3", + "audio/skill/jinjian2.mp3", + "audio/skill/jinjiu1.mp3", + "audio/skill/jinjiu2.mp3", + "audio/skill/jinqu1.mp3", + "audio/skill/jinqu2.mp3", + "audio/skill/jintao1.mp3", + "audio/skill/jintao2.mp3", + "audio/skill/jinzhi1.mp3", + "audio/skill/jinzhi2.mp3", + "audio/skill/jiqiao1.mp3", + "audio/skill/jiqiao2.mp3", + "audio/skill/jishe1.mp3", + "audio/skill/jishe2.mp3", + "audio/skill/jishi1.mp3", + "audio/skill/jishi2.mp3", + "audio/skill/jisi1.mp3", + "audio/skill/jisi2.mp3", + "audio/skill/jiuchi_re_dongzhuo1.mp3", + "audio/skill/jiuchi_re_dongzhuo2.mp3", + "audio/skill/jiuchi1.mp3", + "audio/skill/jiuchi2.mp3", + "audio/skill/jiufa1.mp3", + "audio/skill/jiufa2.mp3", + "audio/skill/jiushi11.mp3", + "audio/skill/jiushi12.mp3", + "audio/skill/jiushi21.mp3", + "audio/skill/jiushi22.mp3", + "audio/skill/jiushi31.mp3", + "audio/skill/jiushi32.mp3", + "audio/skill/jiuwei.mp3", + "audio/skill/jiuyuan1.mp3", + "audio/skill/jiuyuan2.mp3", + "audio/skill/jiwu1.mp3", + "audio/skill/jiwu2.mp3", + "audio/skill/jixi_gz_dengai1.mp3", + "audio/skill/jixi_gz_dengai2.mp3", + "audio/skill/jixi_ol_dengai1.mp3", + "audio/skill/jixi_ol_dengai2.mp3", + "audio/skill/jixi_re_dengai1.mp3", + "audio/skill/jixi_re_dengai2.mp3", + "audio/skill/jixi1.mp3", + "audio/skill/jixi2.mp3", + "audio/skill/jixian1.mp3", + "audio/skill/jixian2.mp3", + "audio/skill/jiyu1.mp3", + "audio/skill/jiyu2.mp3", + "audio/skill/jizhao1.mp3", + "audio/skill/jizhao2.mp3", + "audio/skill/jizhi_jianyong1.mp3", + "audio/skill/jizhi_jianyong2.mp3", + "audio/skill/jizhi1.mp3", + "audio/skill/jizhi2.mp3", + "audio/skill/jspdanqi1.mp3", + "audio/skill/jspdanqi2.mp3", + "audio/skill/juanjia1.mp3", + "audio/skill/juanjia2.mp3", + "audio/skill/jubao1.mp3", + "audio/skill/jubao2.mp3", + "audio/skill/juece_dc_liru1.mp3", + "audio/skill/juece_dc_liru2.mp3", + "audio/skill/juece1.mp3", + "audio/skill/juece2.mp3", + "audio/skill/juedi1.mp3", + "audio/skill/juedi2.mp3", + "audio/skill/juejing.mp3", + "audio/skill/jueman1.mp3", + "audio/skill/jueman2.mp3", + "audio/skill/jueqing1.mp3", + "audio/skill/jueqing2.mp3", + "audio/skill/juesheng1.mp3", + "audio/skill/juesheng2.mp3", + "audio/skill/juesi1.mp3", + "audio/skill/juesi2.mp3", + "audio/skill/juetao1.mp3", + "audio/skill/juetao2.mp3", + "audio/skill/juexiang_he1.mp3", + "audio/skill/juexiang_ji1.mp3", + "audio/skill/juexiang_lie1.mp3", + "audio/skill/juexiang_rou1.mp3", + "audio/skill/juexiang1.mp3", + "audio/skill/juexiang2.mp3", + "audio/skill/jueyong1.mp3", + "audio/skill/jueyong2.mp3", + "audio/skill/juezhi1.mp3", + "audio/skill/juezhi2.mp3", + "audio/skill/jugu1.mp3", + "audio/skill/jugu2.mp3", + "audio/skill/juguan1.mp3", + "audio/skill/juguan2.mp3", + "audio/skill/jujian1.mp3", + "audio/skill/jujian2.mp3", + "audio/skill/junbing1.mp3", + "audio/skill/junbing2.mp3", + "audio/skill/junxing1.mp3", + "audio/skill/junxing2.mp3", + "audio/skill/jushou.mp3", + "audio/skill/jushou1.mp3", + "audio/skill/jushou2.mp3", + "audio/skill/juxiang1_ol_zhurong1.mp3", + "audio/skill/juxiang1_ol_zhurong2.mp3", + "audio/skill/juxiang1_re_zhurong1.mp3", + "audio/skill/juxiang1_re_zhurong2.mp3", + "audio/skill/juxiang11.mp3", + "audio/skill/juxiang12.mp3", + "audio/skill/juyi1.mp3", + "audio/skill/juyi2.mp3", + "audio/skill/jyishi1.mp3", + "audio/skill/jyishi2.mp3", + "audio/skill/jyzongshi_re_jianyong1.mp3", + "audio/skill/jyzongshi_re_jianyong2.mp3", + "audio/skill/jyzongshi1.mp3", + "audio/skill/jyzongshi2.mp3", + "audio/skill/kaikang1.mp3", + "audio/skill/kaikang2.mp3", + "audio/skill/kanade_benzhan1.mp3", + "audio/skill/kanade_benzhan2.mp3", + "audio/skill/kanade_benzhan3.mp3", + "audio/skill/kanade_mapo1.mp3", + "audio/skill/kanade_mapo2.mp3", + "audio/skill/kangge1.mp3", + "audio/skill/kangge2.mp3", + "audio/skill/kanpo1.mp3", + "audio/skill/kanpo2.mp3", + "audio/skill/keji_re_lvmeng1.mp3", + "audio/skill/keji_re_lvmeng2.mp3", + "audio/skill/keji1.mp3", + "audio/skill/keji2.mp3", + "audio/skill/keshou1.mp3", + "audio/skill/keshou2.mp3", + "audio/skill/kongcheng_re_zhugeliang1.mp3", + "audio/skill/kongcheng_re_zhugeliang2.mp3", + "audio/skill/kongcheng11.mp3", + "audio/skill/kongcheng12.mp3", + "audio/skill/kongsheng1.mp3", + "audio/skill/kongsheng2.mp3", + "audio/skill/koulve1.mp3", + "audio/skill/koulve2.mp3", + "audio/skill/kousheng1.mp3", + "audio/skill/kousheng2.mp3", + "audio/skill/kuangbi1.mp3", + "audio/skill/kuangbi2.mp3", + "audio/skill/kuangcai1.mp3", + "audio/skill/kuangcai2.mp3", + "audio/skill/kuangfeng1.mp3", + "audio/skill/kuangfeng2.mp3", + "audio/skill/kuangfu1.mp3", + "audio/skill/kuangfu2.mp3", + "audio/skill/kuanggu_ol_weiyan1.mp3", + "audio/skill/kuanggu_ol_weiyan2.mp3", + "audio/skill/kuanggu_re_weiyan1.mp3", + "audio/skill/kuanggu_re_weiyan2.mp3", + "audio/skill/kuanggu1.mp3", + "audio/skill/kuanggu2.mp3", + "audio/skill/kuanshi1.mp3", + "audio/skill/kuanshi2.mp3", + "audio/skill/kuiji1.mp3", + "audio/skill/kuiji2.mp3", + "audio/skill/kuimang1.mp3", + "audio/skill/kuimang2.mp3", + "audio/skill/kuiwei1.mp3", + "audio/skill/kuiwei2.mp3", + "audio/skill/kunfen1.mp3", + "audio/skill/kunfen2.mp3", + "audio/skill/kurou1.mp3", + "audio/skill/kurou2.mp3", + "audio/skill/kuwu.mp3", + "audio/skill/laishou1.mp3", + "audio/skill/laishou2.mp3", + "audio/skill/laishou3.mp3", + "audio/skill/langmie1.mp3", + "audio/skill/langmie2.mp3", + "audio/skill/lanjiang1.mp3", + "audio/skill/lanjiang2.mp3", + "audio/skill/leiji1.mp3", + "audio/skill/leiji2.mp3", + "audio/skill/liandui1.mp3", + "audio/skill/liandui2.mp3", + "audio/skill/liangcaokuifa.mp3", + "audio/skill/liangfan1.mp3", + "audio/skill/liangfan2.mp3", + "audio/skill/liangjue1.mp3", + "audio/skill/liangjue2.mp3", + "audio/skill/liangjunxiangchi.mp3", + "audio/skill/liangyin1.mp3", + "audio/skill/liangyin2.mp3", + "audio/skill/liangying1.mp3", + "audio/skill/liangyuan1.mp3", + "audio/skill/liangyuan2.mp3", + "audio/skill/liangzhu1.mp3", + "audio/skill/liangzhu2.mp3", + "audio/skill/lianhuan1.mp3", + "audio/skill/lianhuan2.mp3", + "audio/skill/lianhuo1.mp3", + "audio/skill/lianhuo2.mp3", + "audio/skill/lianji.mp3", + "audio/skill/lianpo.mp3", + "audio/skill/lianpo1.mp3", + "audio/skill/lianpo2.mp3", + "audio/skill/lianying1.mp3", + "audio/skill/lianying2.mp3", + "audio/skill/lianzhou1.mp3", + "audio/skill/lianzhou2.mp3", + "audio/skill/lianzhu1.mp3", + "audio/skill/lianzhu2.mp3", + "audio/skill/lianzi1.mp3", + "audio/skill/lianzi2.mp3", + "audio/skill/liaoyi1.mp3", + "audio/skill/liaoyi2.mp3", + "audio/skill/liechi1.mp3", + "audio/skill/liechi2.mp3", + "audio/skill/liedan1.mp3", + "audio/skill/liedan2.mp3", + "audio/skill/liegong_ol_huangzhong1.mp3", + "audio/skill/liegong_ol_huangzhong2.mp3", + "audio/skill/liegong_re_huangzhong1.mp3", + "audio/skill/liegong_re_huangzhong2.mp3", + "audio/skill/liegong1.mp3", + "audio/skill/liegong2.mp3", + "audio/skill/liehou1.mp3", + "audio/skill/liehou2.mp3", + "audio/skill/liejie1.mp3", + "audio/skill/liejie2.mp3", + "audio/skill/lieren_ol_zhurong1.mp3", + "audio/skill/lieren_ol_zhurong2.mp3", + "audio/skill/lieren1.mp3", + "audio/skill/lieren2.mp3", + "audio/skill/liewei1.mp3", + "audio/skill/liewei2.mp3", + "audio/skill/lieyi1.mp3", + "audio/skill/lieyi2.mp3", + "audio/skill/liezhi1.mp3", + "audio/skill/liezhi2.mp3", + "audio/skill/lihun1.mp3", + "audio/skill/lihun2.mp3", + "audio/skill/lihuo_re_chengpu1.mp3", + "audio/skill/lihuo_re_chengpu2.mp3", + "audio/skill/lihuo1.mp3", + "audio/skill/lihuo2.mp3", + "audio/skill/liji1.mp3", + "audio/skill/liji2.mp3", + "audio/skill/lijian_re_diaochan1.mp3", + "audio/skill/lijian_re_diaochan2.mp3", + "audio/skill/lijian1.mp3", + "audio/skill/lijian2.mp3", + "audio/skill/lingbo1.mp3", + "audio/skill/lingbo2.mp3", + "audio/skill/lingce1.mp3", + "audio/skill/lingce2.mp3", + "audio/skill/linglong1.mp3", + "audio/skill/linglong2.mp3", + "audio/skill/lingren_jianxiong1.mp3", + "audio/skill/lingren_xingshang1.mp3", + "audio/skill/lirang1.mp3", + "audio/skill/lirang2.mp3", + "audio/skill/lisi1.mp3", + "audio/skill/lisi2.mp3", + "audio/skill/liubing1.mp3", + "audio/skill/liubing2.mp3", + "audio/skill/liuli_daxiaoqiao1.mp3", + "audio/skill/liuli_daxiaoqiao2.mp3", + "audio/skill/liuli_re_daqiao1.mp3", + "audio/skill/liuli_re_daqiao2.mp3", + "audio/skill/liuli1.mp3", + "audio/skill/liuli2.mp3", + "audio/skill/liunian1.mp3", + "audio/skill/liunian2.mp3", + "audio/skill/lixia1.mp3", + "audio/skill/lixia2.mp3", + "audio/skill/liyu1.mp3", + "audio/skill/liyu2.mp3", + "audio/skill/lizhan1.mp3", + "audio/skill/lizhan2.mp3", + "audio/skill/lkbushi1.mp3", + "audio/skill/lkbushi2.mp3", + "audio/skill/lkzhongzhuang1.mp3", + "audio/skill/lkzhongzhuang2.mp3", + "audio/skill/llqshenwei1.mp3", + "audio/skill/llqshenwei2.mp3", + "audio/skill/longdan_sha_re_zhaoyun1.mp3", + "audio/skill/longdan_sha_re_zhaoyun2.mp3", + "audio/skill/longdan_sha1.mp3", + "audio/skill/longdan_sha2.mp3", + "audio/skill/longdan_tongyuan.mp3", + "audio/skill/longhun1.mp3", + "audio/skill/longhun2.mp3", + "audio/skill/longhun3.mp3", + "audio/skill/longhun4.mp3", + "audio/skill/longyin1.mp3", + "audio/skill/longyin2.mp3", + "audio/skill/longyuan1.mp3", + "audio/skill/longyuan2.mp3", + "audio/skill/lskuizhu1.mp3", + "audio/skill/lskuizhu2.mp3", + "audio/skill/lslixun1.mp3", + "audio/skill/lslixun2.mp3", + "audio/skill/luanchou1.mp3", + "audio/skill/luanchou2.mp3", + "audio/skill/luanfeng1.mp3", + "audio/skill/luanfeng2.mp3", + "audio/skill/luanji1.mp3", + "audio/skill/luanji2.mp3", + "audio/skill/luanqun1.mp3", + "audio/skill/luanqun2.mp3", + "audio/skill/luanwu_re_jiaxu1.mp3", + "audio/skill/luanwu_re_jiaxu2.mp3", + "audio/skill/luanwu1.mp3", + "audio/skill/luanwu2.mp3", + "audio/skill/luanzhan1.mp3", + "audio/skill/luanzhan2.mp3", + "audio/skill/lulve1.mp3", + "audio/skill/lulve2.mp3", + "audio/skill/luochong1.mp3", + "audio/skill/luochong2.mp3", + "audio/skill/luoshen1.mp3", + "audio/skill/luoshen2.mp3", + "audio/skill/luoyi1.mp3", + "audio/skill/luoyi2.mp3", + "audio/skill/luoying_discard1.mp3", + "audio/skill/luoying_discard2.mp3", + "audio/skill/luoying_judge1.mp3", + "audio/skill/luoying_judge2.mp3", + "audio/skill/luoying1.mp3", + "audio/skill/luoying2.mp3", + "audio/skill/lvli1.mp3", + "audio/skill/lvli2.mp3", + "audio/skill/lxzhuixi1.mp3", + "audio/skill/lxzhuixi2.mp3", + "audio/skill/maihuo1.mp3", + "audio/skill/maihuo2.mp3", + "audio/skill/manji1.mp3", + "audio/skill/manji2.mp3", + "audio/skill/manjuan.mp3", + "audio/skill/mansi1.mp3", + "audio/skill/mansi2.mp3", + "audio/skill/manyi_mengyou1.mp3", + "audio/skill/manyi_mengyou2.mp3", + "audio/skill/manyi1.mp3", + "audio/skill/manyi2.mp3", + "audio/skill/mazui.mp3", + "audio/skill/mbaosi1.mp3", + "audio/skill/mbaosi2.mp3", + "audio/skill/mbcuizhen1.mp3", + "audio/skill/mbcuizhen2.mp3", + "audio/skill/mbdaoshu1.mp3", + "audio/skill/mbdaoshu2.mp3", + "audio/skill/mbdaoshu3.mp3", + "audio/skill/mbguli1.mp3", + "audio/skill/mbguli2.mp3", + "audio/skill/mbhuiyao1.mp3", + "audio/skill/mbhuiyao2.mp3", + "audio/skill/mbjuejin1.mp3", + "audio/skill/mbjuejin2.mp3", + "audio/skill/mbkuangli1.mp3", + "audio/skill/mbkuangli2.mp3", + "audio/skill/mbkuili1.mp3", + "audio/skill/mbkuili2.mp3", + "audio/skill/mbqianlong1.mp3", + "audio/skill/mbqianlong2.mp3", + "audio/skill/mbqianlong3.mp3", + "audio/skill/mbqianlong4.mp3", + "audio/skill/mbqianlong5.mp3", + "audio/skill/mbqianlong6.mp3", + "audio/skill/mbquesong1.mp3", + "audio/skill/mbquesong2.mp3", + "audio/skill/mbshihe1.mp3", + "audio/skill/mbshihe2.mp3", + "audio/skill/mbshishou1.mp3", + "audio/skill/mbshishou2.mp3", + "audio/skill/mbweiming1.mp3", + "audio/skill/mbweiming2.mp3", + "audio/skill/mbweiming3.mp3", + "audio/skill/mbweitong1.mp3", + "audio/skill/mbxiongsi1.mp3", + "audio/skill/mbxiongsi2.mp3", + "audio/skill/mbxuetu_re_yangfeng1.mp3", + "audio/skill/mbxuetu_re_yangfeng2.mp3", + "audio/skill/mbxuetu1.mp3", + "audio/skill/mbxuetu2.mp3", + "audio/skill/mbyilie1.mp3", + "audio/skill/mbyilie2.mp3", + "audio/skill/mbyilie3.mp3", + "audio/skill/mbzhenfu1.mp3", + "audio/skill/mbzhenfu2.mp3", + "audio/skill/mbzuoyou1.mp3", + "audio/skill/mbzuoyou2.mp3", + "audio/skill/meibu1.mp3", + "audio/skill/meibu2.mp3", + "audio/skill/meihun1.mp3", + "audio/skill/meihun2.mp3", + "audio/skill/mengjin1.mp3", + "audio/skill/mengjin2.mp3", + "audio/skill/mengqing1.mp3", + "audio/skill/mengqing2.mp3", + "audio/skill/mffengshi_sp_mifangfushiren1.mp3", + "audio/skill/mffengshi_sp_mifangfushiren2.mp3", + "audio/skill/mffengshi1.mp3", + "audio/skill/mffengshi2.mp3", + "audio/skill/miaojian1.mp3", + "audio/skill/miaojian2.mp3", + "audio/skill/miaoxian1.mp3", + "audio/skill/miaoxian2.mp3", + "audio/skill/mibei1.mp3", + "audio/skill/mibei2.mp3", + "audio/skill/midao1.mp3", + "audio/skill/midao2.mp3", + "audio/skill/midu1.mp3", + "audio/skill/midu2.mp3", + "audio/skill/mieji1.mp3", + "audio/skill/mieji2.mp3", + "audio/skill/miji_re_wangyi1.mp3", + "audio/skill/miji_re_wangyi2.mp3", + "audio/skill/miji1.mp3", + "audio/skill/miji2.mp3", + "audio/skill/mingce1.mp3", + "audio/skill/mingce2.mp3", + "audio/skill/mingcha1.mp3", + "audio/skill/mingcha2.mp3", + "audio/skill/mingfa1.mp3", + "audio/skill/mingfa2.mp3", + "audio/skill/mingjian1.mp3", + "audio/skill/mingjian2.mp3", + "audio/skill/mingjie1.mp3", + "audio/skill/mingluan1.mp3", + "audio/skill/mingluan2.mp3", + "audio/skill/mingshi1.mp3", + "audio/skill/mingshi2.mp3", + "audio/skill/mingzhe1.mp3", + "audio/skill/mingzhe2.mp3", + "audio/skill/minsi1.mp3", + "audio/skill/minsi2.mp3", + "audio/skill/mizhao1.mp3", + "audio/skill/mizhao2.mp3", + "audio/skill/mjchenshi1.mp3", + "audio/skill/mjchenshi2.mp3", + "audio/skill/mjdingyi1.mp3", + "audio/skill/mjdingyi2.mp3", + "audio/skill/mjmouzhi1.mp3", + "audio/skill/mjmouzhi2.mp3", + "audio/skill/mjweipo1.mp3", + "audio/skill/mjweipo2.mp3", + "audio/skill/mobiledanshou1.mp3", + "audio/skill/mobiledanshou2.mp3", + "audio/skill/mobilejingce1.mp3", + "audio/skill/mobilejingce2.mp3", + "audio/skill/mobilexingxue1.mp3", + "audio/skill/mobilexingxue2.mp3", + "audio/skill/mobileyanzhu1.mp3", + "audio/skill/mobileyanzhu2.mp3", + "audio/skill/mobilezhongyong1.mp3", + "audio/skill/mobilezhongyong2.mp3", + "audio/skill/monkey.mp3", + "audio/skill/moucheng1.mp3", + "audio/skill/moucheng2.mp3", + "audio/skill/moucuan1.mp3", + "audio/skill/moucuan2.mp3", + "audio/skill/moukui1.mp3", + "audio/skill/moukui2.mp3", + "audio/skill/mouli1.mp3", + "audio/skill/mouli2.mp3", + "audio/skill/mouni1.mp3", + "audio/skill/mouni2.mp3", + "audio/skill/mouzhi1.mp3", + "audio/skill/mouzhi2.mp3", + "audio/skill/mouzhu1.mp3", + "audio/skill/mouzhu2.mp3", + "audio/skill/mozhi1.mp3", + "audio/skill/mozhi2.mp3", + "audio/skill/mpbishi1.mp3", + "audio/skill/mpbishi2.mp3", + "audio/skill/mpjiusong1.mp3", + "audio/skill/mpjiusong2.mp3", + "audio/skill/mpmaotao1.mp3", + "audio/skill/mpmaotao2.mp3", + "audio/skill/mubing1.mp3", + "audio/skill/mubing2.mp3", + "audio/skill/mumu1.mp3", + "audio/skill/mumu2.mp3", + "audio/skill/muzhen1.mp3", + "audio/skill/muzhen2.mp3", + "audio/skill/naman1.mp3", + "audio/skill/naman2.mp3", + "audio/skill/naxiang1.mp3", + "audio/skill/naxiang2.mp3", + "audio/skill/naxue1.mp3", + "audio/skill/naxue2.mp3", + "audio/skill/neifa1.mp3", + "audio/skill/neifa2.mp3", + "audio/skill/new_jiangchi1.mp3", + "audio/skill/new_jiangchi2.mp3", + "audio/skill/new_reqingnang1.mp3", + "audio/skill/new_reqingnang2.mp3", + "audio/skill/new_reyaowu_sb_huaxiong1.mp3", + "audio/skill/new_reyaowu_sb_huaxiong2.mp3", + "audio/skill/new_reyaowu1.mp3", + "audio/skill/new_reyaowu2.mp3", + "audio/skill/niepan_re_pangtong1.mp3", + "audio/skill/niepan_re_pangtong2.mp3", + "audio/skill/niepan1.mp3", + "audio/skill/niepan2.mp3", + "audio/skill/nifu1.mp3", + "audio/skill/nifu2.mp3", + "audio/skill/niluan1.mp3", + "audio/skill/niluan2.mp3", + "audio/skill/noda_fengcheng1.mp3", + "audio/skill/noda_fengcheng2.mp3", + "audio/skill/noda_xunxin1.mp3", + "audio/skill/noda_xunxin2.mp3", + "audio/skill/ns_nsshimeng1.mp3", + "audio/skill/ns_nsshimeng2.mp3", + "audio/skill/nzry_binglve1.mp3", + "audio/skill/nzry_binglve2.mp3", + "audio/skill/nzry_chenglve1.mp3", + "audio/skill/nzry_chenglve2.mp3", + "audio/skill/nzry_cuike1.mp3", + "audio/skill/nzry_cuike2.mp3", + "audio/skill/nzry_cunmu1.mp3", + "audio/skill/nzry_cunmu2.mp3", + "audio/skill/nzry_dinghuo1.mp3", + "audio/skill/nzry_dinghuo2.mp3", + "audio/skill/nzry_feijun1.mp3", + "audio/skill/nzry_feijun2.mp3", + "audio/skill/nzry_huaiju1.mp3", + "audio/skill/nzry_huaiju2.mp3", + "audio/skill/nzry_jianxiang1.mp3", + "audio/skill/nzry_jianxiang2.mp3", + "audio/skill/nzry_jieying1.mp3", + "audio/skill/nzry_jieying2.mp3", + "audio/skill/nzry_junlve1.mp3", + "audio/skill/nzry_junlve2.mp3", + "audio/skill/nzry_juzhan_11.mp3", + "audio/skill/nzry_juzhan_12.mp3", + "audio/skill/nzry_kuizhu1.mp3", + "audio/skill/nzry_kuizhu2.mp3", + "audio/skill/nzry_lijun11.mp3", + "audio/skill/nzry_lijun12.mp3", + "audio/skill/nzry_longnu1.mp3", + "audio/skill/nzry_longnu2.mp3", + "audio/skill/nzry_mingren_1_sb_yl_luzhi1.mp3", + "audio/skill/nzry_mingren_1_sb_yl_luzhi2.mp3", + "audio/skill/nzry_mingren_11.mp3", + "audio/skill/nzry_mingren_12.mp3", + "audio/skill/nzry_shenshi_11.mp3", + "audio/skill/nzry_shenshi_12.mp3", + "audio/skill/nzry_shicai_21.mp3", + "audio/skill/nzry_shicai_22.mp3", + "audio/skill/nzry_yili1.mp3", + "audio/skill/nzry_yili2.mp3", + "audio/skill/nzry_zhenglun1.mp3", + "audio/skill/nzry_zhenglun2.mp3", + "audio/skill/nzry_zhenliang_11.mp3", + "audio/skill/nzry_zhenliang_12.mp3", + "audio/skill/nzry_zhizheng1.mp3", + "audio/skill/nzry_zhizheng2.mp3", + "audio/skill/ocongjian_tongyuan.mp3", + "audio/skill/ol_shenfen1.mp3", + "audio/skill/ol_shenfen2.mp3", + "audio/skill/ol_shichou1.mp3", + "audio/skill/ol_shichou2.mp3", + "audio/skill/ol_wuqian1.mp3", + "audio/skill/ol_wuqian2.mp3", + "audio/skill/olbaonue1.mp3", + "audio/skill/olbaonue2.mp3", + "audio/skill/olbeige1.mp3", + "audio/skill/olbeige2.mp3", + "audio/skill/olbihun1.mp3", + "audio/skill/olbihun2.mp3", + "audio/skill/olbixin1.mp3", + "audio/skill/olbixin2.mp3", + "audio/skill/olchanshuang1.mp3", + "audio/skill/olchanshuang2.mp3", + "audio/skill/olchenglie1.mp3", + "audio/skill/olchenglie2.mp3", + "audio/skill/olchenshuo1.mp3", + "audio/skill/olchenshuo2.mp3", + "audio/skill/olchongshen1.mp3", + "audio/skill/olchongshen2.mp3", + "audio/skill/olchuanwu1.mp3", + "audio/skill/olchuanwu2.mp3", + "audio/skill/olchuming1.mp3", + "audio/skill/olchuming2.mp3", + "audio/skill/olcuipo1.mp3", + "audio/skill/olcuipo2.mp3", + "audio/skill/old_fuhun1.mp3", + "audio/skill/old_fuhun2.mp3", + "audio/skill/old_guhuo1.mp3", + "audio/skill/old_guhuo2.mp3", + "audio/skill/oldaili1.mp3", + "audio/skill/oldaili2.mp3", + "audio/skill/oldianjun1.mp3", + "audio/skill/oldianjun2.mp3", + "audio/skill/oldimeng1.mp3", + "audio/skill/oldimeng2.mp3", + "audio/skill/oldingcuo1.mp3", + "audio/skill/oldingcuo2.mp3", + "audio/skill/oldmiji1.mp3", + "audio/skill/oldmiji2.mp3", + "audio/skill/oldongdao1.mp3", + "audio/skill/oldongdao2.mp3", + "audio/skill/oldqianxi1.mp3", + "audio/skill/oldqianxi2.mp3", + "audio/skill/olduanliang1.mp3", + "audio/skill/olduanliang2.mp3", + "audio/skill/oldzhenlie1.mp3", + "audio/skill/oldzhenlie2.mp3", + "audio/skill/olfangquan_shen_caopi1.mp3", + "audio/skill/olfangquan_shen_caopi2.mp3", + "audio/skill/olfangquan1.mp3", + "audio/skill/olfangquan2.mp3", + "audio/skill/olfeibai1.mp3", + "audio/skill/olfeibai2.mp3", + "audio/skill/olfengji1.mp3", + "audio/skill/olfengji2.mp3", + "audio/skill/olfengyan1.mp3", + "audio/skill/olfengyan2.mp3", + "audio/skill/olfengzi1.mp3", + "audio/skill/olfengzi2.mp3", + "audio/skill/olfudao1.mp3", + "audio/skill/olfudao2.mp3", + "audio/skill/olfushi1.mp3", + "audio/skill/olfushi2.mp3", + "audio/skill/olfusong1.mp3", + "audio/skill/olfusong2.mp3", + "audio/skill/olgangshu1.mp3", + "audio/skill/olgangshu2.mp3", + "audio/skill/olgongjie1.mp3", + "audio/skill/olgongjie2.mp3", + "audio/skill/olgoude1.mp3", + "audio/skill/olgoude2.mp3", + "audio/skill/olguangao1.mp3", + "audio/skill/olguangao2.mp3", + "audio/skill/olguzheng1.mp3", + "audio/skill/olguzheng2.mp3", + "audio/skill/olhaoshi1.mp3", + "audio/skill/olhaoshi2.mp3", + "audio/skill/olhongji1.mp3", + "audio/skill/olhongji2.mp3", + "audio/skill/olhuanfu1.mp3", + "audio/skill/olhuanfu2.mp3", + "audio/skill/olhuiqi1.mp3", + "audio/skill/olhuiqi2.mp3", + "audio/skill/olhuiyun1.mp3", + "audio/skill/olhuiyun2.mp3", + "audio/skill/olhunzi_re_sunyi1.mp3", + "audio/skill/olhunzi_re_sunyi2.mp3", + "audio/skill/olhunzi1.mp3", + "audio/skill/olhunzi2.mp3", + "audio/skill/oljiane1.mp3", + "audio/skill/oljiane2.mp3", + "audio/skill/oljianhe1.mp3", + "audio/skill/oljianhe2.mp3", + "audio/skill/oljianman1.mp3", + "audio/skill/oljianman2.mp3", + "audio/skill/oljianxuan1.mp3", + "audio/skill/oljianxuan2.mp3", + "audio/skill/oljieming1.mp3", + "audio/skill/oljieming2.mp3", + "audio/skill/oljiezi1.mp3", + "audio/skill/oljiezi2.mp3", + "audio/skill/oljiuchi1.mp3", + "audio/skill/oljiuchi2.mp3", + "audio/skill/oljizhan1.mp3", + "audio/skill/oljizhan2.mp3", + "audio/skill/oljuanxia1.mp3", + "audio/skill/oljuanxia2.mp3", + "audio/skill/olkangrui1.mp3", + "audio/skill/olkangrui2.mp3", + "audio/skill/olkenshang1.mp3", + "audio/skill/olkenshang2.mp3", + "audio/skill/olkuansai1.mp3", + "audio/skill/olkuansai2.mp3", + "audio/skill/ollangdao1.mp3", + "audio/skill/ollangdao2.mp3", + "audio/skill/olleijie1.mp3", + "audio/skill/olleijie2.mp3", + "audio/skill/olliantao1.mp3", + "audio/skill/olliantao2.mp3", + "audio/skill/olluanji_shen_caopi1.mp3", + "audio/skill/olluanji_shen_caopi2.mp3", + "audio/skill/olluanji1.mp3", + "audio/skill/olluanji2.mp3", + "audio/skill/olmiuyan1.mp3", + "audio/skill/olmiuyan2.mp3", + "audio/skill/olniepan1.mp3", + "audio/skill/olniepan2.mp3", + "audio/skill/olningwu1.mp3", + "audio/skill/olningwu2.mp3", + "audio/skill/olnishou1.mp3", + "audio/skill/olnishou2.mp3", + "audio/skill/olqiejian1.mp3", + "audio/skill/olqiejian2.mp3", + "audio/skill/olqingyi1.mp3", + "audio/skill/olqingyi2.mp3", + "audio/skill/olqingyuan1.mp3", + "audio/skill/olqingyuan2.mp3", + "audio/skill/olqisi1.mp3", + "audio/skill/olqisi2.mp3", + "audio/skill/olqushi1.mp3", + "audio/skill/olqushi2.mp3", + "audio/skill/olruoyu1.mp3", + "audio/skill/olruoyu2.mp3", + "audio/skill/olsaogu1.mp3", + "audio/skill/olsaogu2.mp3", + "audio/skill/olsbdouchan1.mp3", + "audio/skill/olsbdouchan2.mp3", + "audio/skill/olsbdulie1.mp3", + "audio/skill/olsbdulie2.mp3", + "audio/skill/olsbduoshou1.mp3", + "audio/skill/olsbduoshou2.mp3", + "audio/skill/olsbfumeng1.mp3", + "audio/skill/olsbfumeng2.mp3", + "audio/skill/olsbguidao1.mp3", + "audio/skill/olsbguidao2.mp3", + "audio/skill/olsbhetao_ol_sb_yuanshao_shadow1.mp3", + "audio/skill/olsbhetao_ol_sb_yuanshao_shadow2.mp3", + "audio/skill/olsbhetao_ol_sb_yuanshao_shadow3.mp3", + "audio/skill/olsbhetao1.mp3", + "audio/skill/olsbhetao2.mp3", + "audio/skill/olsbhetao3.mp3", + "audio/skill/olsbranji1.mp3", + "audio/skill/olsbranji2.mp3", + "audio/skill/olsbshenli_ol_sb_yuanshao_shadow1.mp3", + "audio/skill/olsbshenli_ol_sb_yuanshao_shadow2.mp3", + "audio/skill/olsbshenli_ol_sb_yuanshao_shadow3.mp3", + "audio/skill/olsbshenli1.mp3", + "audio/skill/olsbshenli2.mp3", + "audio/skill/olsbshenli3.mp3", + "audio/skill/olsbshishou_ol_sb_yuanshao_shadow1.mp3", + "audio/skill/olsbshishou_ol_sb_yuanshao_shadow2.mp3", + "audio/skill/olsbshishou_ol_sb_yuanshao_shadow3.mp3", + "audio/skill/olsbshishou1.mp3", + "audio/skill/olsbshishou2.mp3", + "audio/skill/olsbshishou3.mp3", + "audio/skill/olsbweilin1.mp3", + "audio/skill/olsbweilin2.mp3", + "audio/skill/olsbyufeng_ol_sb_yuanshao_shadow1.mp3", + "audio/skill/olsbyufeng1.mp3", + "audio/skill/olsbyufeng2.mp3", + "audio/skill/olsbzhuri1.mp3", + "audio/skill/olsbzhuri2.mp3", + "audio/skill/olshandao1.mp3", + "audio/skill/olshandao2.mp3", + "audio/skill/olshengong1.mp3", + "audio/skill/olshengong2.mp3", + "audio/skill/olshilu1.mp3", + "audio/skill/olshilu2.mp3", + "audio/skill/olshuangxiong1.mp3", + "audio/skill/olshuangxiong2.mp3", + "audio/skill/olsuji1.mp3", + "audio/skill/olsuji2.mp3", + "audio/skill/olsujian1.mp3", + "audio/skill/olsujian2.mp3", + "audio/skill/oltianhou_club.mp3", + "audio/skill/oltianhou_diamond.mp3", + "audio/skill/oltianhou_heart.mp3", + "audio/skill/oltianhou_spade.mp3", + "audio/skill/oltianhou1.mp3", + "audio/skill/oltianhou2.mp3", + "audio/skill/oltongduo1.mp3", + "audio/skill/oltongduo2.mp3", + "audio/skill/oltousui1.mp3", + "audio/skill/oltousui2.mp3", + "audio/skill/oltuntian1.mp3", + "audio/skill/oltuntian2.mp3", + "audio/skill/olweifu1.mp3", + "audio/skill/olweifu2.mp3", + "audio/skill/olweijie1.mp3", + "audio/skill/olweijie2.mp3", + "audio/skill/olxianbi1.mp3", + "audio/skill/olxianbi2.mp3", + "audio/skill/olxiangxv1.mp3", + "audio/skill/olxiangxv2.mp3", + "audio/skill/olxiangzuo1.mp3", + "audio/skill/olxiangzuo2.mp3", + "audio/skill/olxianlve1.mp3", + "audio/skill/olxianlve2.mp3", + "audio/skill/olxiaosi1.mp3", + "audio/skill/olxiaosi2.mp3", + "audio/skill/olxibing1.mp3", + "audio/skill/olxibing2.mp3", + "audio/skill/olxieju1.mp3", + "audio/skill/olxieju2.mp3", + "audio/skill/olximo1.mp3", + "audio/skill/olximo2.mp3", + "audio/skill/olximo3.mp3", + "audio/skill/olxinggu1.mp3", + "audio/skill/olxinggu2.mp3", + "audio/skill/olxiuhao1.mp3", + "audio/skill/olxiuhao2.mp3", + "audio/skill/olxuanzhu1.mp3", + "audio/skill/olxuanzhu2.mp3", + "audio/skill/olxueyi1.mp3", + "audio/skill/olxueyi2.mp3", + "audio/skill/olzaowang1.mp3", + "audio/skill/olzaowang2.mp3", + "audio/skill/olzaoxian1.mp3", + "audio/skill/olzaoxian2.mp3", + "audio/skill/olzenrun1.mp3", + "audio/skill/olzenrun2.mp3", + "audio/skill/olzeyue1.mp3", + "audio/skill/olzeyue2.mp3", + "audio/skill/olzhanjin1.mp3", + "audio/skill/olzhanjin2.mp3", + "audio/skill/olzhenying1.mp3", + "audio/skill/olzhenying2.mp3", + "audio/skill/olzhiba1.mp3", + "audio/skill/olzhiba2.mp3", + "audio/skill/olzhiji1.mp3", + "audio/skill/olzhiji2.mp3", + "audio/skill/olzhijian1.mp3", + "audio/skill/olzhijian2.mp3", + "audio/skill/olzhubi1.mp3", + "audio/skill/olzhubi2.mp3", + "audio/skill/olzhuyan1.mp3", + "audio/skill/olzhuyan2.mp3", + "audio/skill/paiyi_re_zhonghui1.mp3", + "audio/skill/paiyi_re_zhonghui2.mp3", + "audio/skill/paiyi1.mp3", + "audio/skill/paiyi2.mp3", + "audio/skill/paoxiao_guanzhang1.mp3", + "audio/skill/paoxiao_guanzhang2.mp3", + "audio/skill/paoxiao_re_guanzhang1.mp3", + "audio/skill/paoxiao_re_guanzhang2.mp3", + "audio/skill/paoxiao_re_zhangfei1.mp3", + "audio/skill/paoxiao_re_zhangfei2.mp3", + "audio/skill/paoxiao_xiahouba1.mp3", + "audio/skill/paoxiao_xiahouba2.mp3", + "audio/skill/paoxiao1.mp3", + "audio/skill/paoxiao2.mp3", + "audio/skill/pcaudio_fengchu_card.mp3", + "audio/skill/pcaudio_shuijing_card.mp3", + "audio/skill/pcaudio_wolong_card.mp3", + "audio/skill/pcaudio_xuanjian_card.mp3", + "audio/skill/pianchong1.mp3", + "audio/skill/pianchong2.mp3", + "audio/skill/pianyi1.mp3", + "audio/skill/pianyi2.mp3", + "audio/skill/piaoling1.mp3", + "audio/skill/piaoling2.mp3", + "audio/skill/piaoping1.mp3", + "audio/skill/piaoping2.mp3", + "audio/skill/pindi1.mp3", + "audio/skill/pindi2.mp3", + "audio/skill/pinghe1.mp3", + "audio/skill/pinghe2.mp3", + "audio/skill/pingjian1.mp3", + "audio/skill/pingjian2.mp3", + "audio/skill/pingkou1.mp3", + "audio/skill/pingkou2.mp3", + "audio/skill/pingxiang1.mp3", + "audio/skill/pingxiang2.mp3", + "audio/skill/pojun1.mp3", + "audio/skill/pojun2.mp3", + "audio/skill/polu1.mp3", + "audio/skill/polu2.mp3", + "audio/skill/poxiang1.mp3", + "audio/skill/poxiang2.mp3", + "audio/skill/pozhu1.mp3", + "audio/skill/pozhu2.mp3", + "audio/skill/pytianjiang1.mp3", + "audio/skill/pytianjiang2.mp3", + "audio/skill/pyzhuren1.mp3", + "audio/skill/pyzhuren2.mp3", + "audio/skill/qhzhangji1.mp3", + "audio/skill/qhzhangji2.mp3", + "audio/skill/qiangwu1.mp3", + "audio/skill/qiangwu2.mp3", + "audio/skill/qiangxi_boss_lvbu31.mp3", + "audio/skill/qiangxi_boss_lvbu32.mp3", + "audio/skill/qiangxi_ol_dianwei1.mp3", + "audio/skill/qiangxi_ol_dianwei2.mp3", + "audio/skill/qiangxi1.mp3", + "audio/skill/qiangxi2.mp3", + "audio/skill/qiangzhi_re_zhangsong1.mp3", + "audio/skill/qiangzhi_re_zhangsong2.mp3", + "audio/skill/qiangzhi1.mp3", + "audio/skill/qiangzhi2.mp3", + "audio/skill/qianhuan1.mp3", + "audio/skill/qianhuan2.mp3", + "audio/skill/qianlong1.mp3", + "audio/skill/qianlong2.mp3", + "audio/skill/qianmeng1.mp3", + "audio/skill/qianmeng2.mp3", + "audio/skill/qianxi1.mp3", + "audio/skill/qianxi2.mp3", + "audio/skill/qianxin1.mp3", + "audio/skill/qianxin2.mp3", + "audio/skill/qianxun1.mp3", + "audio/skill/qianxun2.mp3", + "audio/skill/qianya1.mp3", + "audio/skill/qianya2.mp3", + "audio/skill/qiaobian1.mp3", + "audio/skill/qiaobian2.mp3", + "audio/skill/qiaoli1.mp3", + "audio/skill/qiaoli2.mp3", + "audio/skill/qiaomeng1.mp3", + "audio/skill/qiaomeng2.mp3", + "audio/skill/qiaoshi1.mp3", + "audio/skill/qiaoshi2.mp3", + "audio/skill/qiaoshui1.mp3", + "audio/skill/qiaoshui2.mp3", + "audio/skill/qiaoyan1.mp3", + "audio/skill/qiaoyan2.mp3", + "audio/skill/qibaodao2.mp3", + "audio/skill/qibie1.mp3", + "audio/skill/qibie2.mp3", + "audio/skill/qice_clan_xunyou1.mp3", + "audio/skill/qice_clan_xunyou2.mp3", + "audio/skill/qice1.mp3", + "audio/skill/qice2.mp3", + "audio/skill/qieting1.mp3", + "audio/skill/qieting2.mp3", + "audio/skill/qiexie1.mp3", + "audio/skill/qiexie2.mp3", + "audio/skill/qigong1.mp3", + "audio/skill/qigong2.mp3", + "audio/skill/qilin_skill.mp3", + "audio/skill/qiluan21.mp3", + "audio/skill/qiluan22.mp3", + "audio/skill/qimei1.mp3", + "audio/skill/qimei2.mp3", + "audio/skill/qimou1.mp3", + "audio/skill/qimou2.mp3", + "audio/skill/qinbao1.mp3", + "audio/skill/qinbao2.mp3", + "audio/skill/qingbei1.mp3", + "audio/skill/qingbei2.mp3", + "audio/skill/qingcheng1.mp3", + "audio/skill/qingcheng2.mp3", + "audio/skill/qinggang_skill.mp3", + "audio/skill/qingguo_sb_zhenji1.mp3", + "audio/skill/qingguo_sb_zhenji2.mp3", + "audio/skill/qingguo1.mp3", + "audio/skill/qingguo2.mp3", + "audio/skill/qingjian1.mp3", + "audio/skill/qingjian2.mp3", + "audio/skill/qingjiao1.mp3", + "audio/skill/qingjiao2.mp3", + "audio/skill/qingjue1.mp3", + "audio/skill/qingjue2.mp3", + "audio/skill/qingleng1.mp3", + "audio/skill/qingleng2.mp3", + "audio/skill/qingliang1.mp3", + "audio/skill/qingliang2.mp3", + "audio/skill/qinglong_skill.mp3", + "audio/skill/qingman1.mp3", + "audio/skill/qingman2.mp3", + "audio/skill/qingnang1.mp3", + "audio/skill/qingnang2.mp3", + "audio/skill/qingtan1.mp3", + "audio/skill/qingtan2.mp3", + "audio/skill/qinguo_lose1.mp3", + "audio/skill/qinguo_lose2.mp3", + "audio/skill/qinguo_use1.mp3", + "audio/skill/qinguo_use2.mp3", + "audio/skill/qingxi1.mp3", + "audio/skill/qingxi2.mp3", + "audio/skill/qingxian1.mp3", + "audio/skill/qingxian2.mp3", + "audio/skill/qingyi1.mp3", + "audio/skill/qingyi2.mp3", + "audio/skill/qingyin1.mp3", + "audio/skill/qingyin2.mp3", + "audio/skill/qingyu1.mp3", + "audio/skill/qingyu2.mp3", + "audio/skill/qingyu3.mp3", + "audio/skill/qingzhong1.mp3", + "audio/skill/qingzhong2.mp3", + "audio/skill/qinqing1.mp3", + "audio/skill/qinqing2.mp3", + "audio/skill/qinwang11.mp3", + "audio/skill/qinwang12.mp3", + "audio/skill/qinwang21.mp3", + "audio/skill/qinwang22.mp3", + "audio/skill/qinxue1.mp3", + "audio/skill/qinxue2.mp3", + "audio/skill/qinyin1.mp3", + "audio/skill/qinyin2.mp3", + "audio/skill/qinzheng1.mp3", + "audio/skill/qinzheng2.mp3", + "audio/skill/qiongshou1.mp3", + "audio/skill/qiongshou2.mp3", + "audio/skill/qirang1.mp3", + "audio/skill/qirang2.mp3", + "audio/skill/qiuan1.mp3", + "audio/skill/qiuan2.mp3", + "audio/skill/qiuyuan1.mp3", + "audio/skill/qiuyuan2.mp3", + "audio/skill/qiwu.mp3", + "audio/skill/qixi_re_ganning1.mp3", + "audio/skill/qixi_re_ganning2.mp3", + "audio/skill/qixi_re_heqi1.mp3", + "audio/skill/qixi_re_heqi2.mp3", + "audio/skill/qixi1.mp3", + "audio/skill/qixi2.mp3", + "audio/skill/qixing1.mp3", + "audio/skill/qixing2.mp3", + "audio/skill/qizhi1.mp3", + "audio/skill/qizhi2.mp3", + "audio/skill/qljsuiren1.mp3", + "audio/skill/qljsuiren2.mp3", + "audio/skill/quanbian1.mp3", + "audio/skill/quanbian2.mp3", + "audio/skill/quanfeng1.mp3", + "audio/skill/quanfeng2.mp3", + "audio/skill/quanji1.mp3", + "audio/skill/quanji2.mp3", + "audio/skill/quanjin1.mp3", + "audio/skill/quanjin2.mp3", + "audio/skill/quanjiu1.mp3", + "audio/skill/quanjiu2.mp3", + "audio/skill/quhu_ol_xunyu1.mp3", + "audio/skill/quhu_ol_xunyu2.mp3", + "audio/skill/quhu_re_xunyu1.mp3", + "audio/skill/quhu_re_xunyu2.mp3", + "audio/skill/quhu1.mp3", + "audio/skill/quhu2.mp3", + "audio/skill/quji1.mp3", + "audio/skill/quji2.mp3", + "audio/skill/quxi1.mp3", + "audio/skill/quxi2.mp3", + "audio/skill/rangjie1.mp3", + "audio/skill/rangjie2.mp3", + "audio/skill/ranshang1.mp3", + "audio/skill/ranshang2.mp3", + "audio/skill/ranshang21.mp3", + "audio/skill/ranshang22.mp3", + "audio/skill/reandong1.mp3", + "audio/skill/reandong2.mp3", + "audio/skill/reanguo1.mp3", + "audio/skill/reanguo2.mp3", + "audio/skill/reanjian1.mp3", + "audio/skill/reanjian2.mp3", + "audio/skill/reanxu1.mp3", + "audio/skill/reanxu2.mp3", + "audio/skill/rebaobian1.mp3", + "audio/skill/rebaobian2.mp3", + "audio/skill/rebingyi1.mp3", + "audio/skill/rebingyi2.mp3", + "audio/skill/rebiyue1.mp3", + "audio/skill/rebiyue2.mp3", + "audio/skill/rebizhuan1.mp3", + "audio/skill/rebizhuan2.mp3", + "audio/skill/recangchu1.mp3", + "audio/skill/recangchu2.mp3", + "audio/skill/rechanhui1.mp3", + "audio/skill/rechanhui2.mp3", + "audio/skill/rechanyuan1.mp3", + "audio/skill/rechanyuan2.mp3", + "audio/skill/rechengxiang1.mp3", + "audio/skill/rechengxiang2.mp3", + "audio/skill/rechunlao1.mp3", + "audio/skill/rechunlao2.mp3", + "audio/skill/redanxin1.mp3", + "audio/skill/redanxin2.mp3", + "audio/skill/redaoji1.mp3", + "audio/skill/redaoji2.mp3", + "audio/skill/redingpin1.mp3", + "audio/skill/redingpin2.mp3", + "audio/skill/reduodao1.mp3", + "audio/skill/reduodao2.mp3", + "audio/skill/reenyuan1.mp3", + "audio/skill/reenyuan2.mp3", + "audio/skill/refaen_dc_chenqun1.mp3", + "audio/skill/refaen_dc_chenqun2.mp3", + "audio/skill/refaen1.mp3", + "audio/skill/refaen2.mp3", + "audio/skill/refangquan1.mp3", + "audio/skill/refangquan2.mp3", + "audio/skill/refangzhu1.mp3", + "audio/skill/refangzhu2.mp3", + "audio/skill/refanjian1.mp3", + "audio/skill/refanjian2.mp3", + "audio/skill/refankui1.mp3", + "audio/skill/refankui2.mp3", + "audio/skill/refenglve1.mp3", + "audio/skill/refenglve2.mp3", + "audio/skill/refenli1.mp3", + "audio/skill/refenli2.mp3", + "audio/skill/refenyin_wufan1.mp3", + "audio/skill/refenyin_wufan2.mp3", + "audio/skill/refenyin1.mp3", + "audio/skill/refenyin2.mp3", + "audio/skill/refuli1.mp3", + "audio/skill/refuli2.mp3", + "audio/skill/refuman1.mp3", + "audio/skill/refuman2.mp3", + "audio/skill/refuyuan1.mp3", + "audio/skill/refuyuan2.mp3", + "audio/skill/reganglie1.mp3", + "audio/skill/reganglie2.mp3", + "audio/skill/reganlu1.mp3", + "audio/skill/reganlu2.mp3", + "audio/skill/regongji1.mp3", + "audio/skill/regongji2.mp3", + "audio/skill/reguhuo1.mp3", + "audio/skill/reguhuo2.mp3", + "audio/skill/reguicai1.mp3", + "audio/skill/reguicai2.mp3", + "audio/skill/reguose1.mp3", + "audio/skill/reguose2.mp3", + "audio/skill/rehongyan1.mp3", + "audio/skill/rehongyan2.mp3", + "audio/skill/rehuaiyi1.mp3", + "audio/skill/rehuaiyi2.mp3", + "audio/skill/rehuashen1.mp3", + "audio/skill/rehuashen2.mp3", + "audio/skill/rehunzi1.mp3", + "audio/skill/rehunzi2.mp3", + "audio/skill/rehuoji_ol_pangtong1.mp3", + "audio/skill/rehuoji_ol_pangtong2.mp3", + "audio/skill/rehuoji_ol_sp_zhugeliang1.mp3", + "audio/skill/rehuoji_ol_sp_zhugeliang2.mp3", + "audio/skill/rehuoji1.mp3", + "audio/skill/rehuoji2.mp3", + "audio/skill/rehuoshui1.mp3", + "audio/skill/rehuoshui2.mp3", + "audio/skill/rejianchu1.mp3", + "audio/skill/rejianchu2.mp3", + "audio/skill/rejiangchi1.mp3", + "audio/skill/rejiangchi2.mp3", + "audio/skill/rejianxiong_shen_caopi1.mp3", + "audio/skill/rejianxiong_shen_caopi2.mp3", + "audio/skill/rejianxiong1.mp3", + "audio/skill/rejianxiong2.mp3", + "audio/skill/rejianyan1.mp3", + "audio/skill/rejianyan2.mp3", + "audio/skill/rejiaojin1.mp3", + "audio/skill/rejiaojin2.mp3", + "audio/skill/rejiaozhao1.mp3", + "audio/skill/rejiaozhao2.mp3", + "audio/skill/rejieming1.mp3", + "audio/skill/rejieming2.mp3", + "audio/skill/rejieyin1.mp3", + "audio/skill/rejieyin2.mp3", + "audio/skill/rejieyue1.mp3", + "audio/skill/rejieyue2.mp3", + "audio/skill/rejigong1.mp3", + "audio/skill/rejigong2.mp3", + "audio/skill/rejinjiu1.mp3", + "audio/skill/rejinjiu2.mp3", + "audio/skill/rejiqiao1.mp3", + "audio/skill/rejiqiao2.mp3", + "audio/skill/rejiushi_mb_caomao1.mp3", + "audio/skill/rejiushi_mb_caomao2.mp3", + "audio/skill/rejiushi1.mp3", + "audio/skill/rejiushi2.mp3", + "audio/skill/rejiuyuan1.mp3", + "audio/skill/rejiuyuan2.mp3", + "audio/skill/rejixu1.mp3", + "audio/skill/rejixu2.mp3", + "audio/skill/rejizhi_lukang1.mp3", + "audio/skill/rejizhi_lukang2.mp3", + "audio/skill/rejizhi1.mp3", + "audio/skill/rejizhi2.mp3", + "audio/skill/rejuece1.mp3", + "audio/skill/rejuece2.mp3", + "audio/skill/rejueqing1.mp3", + "audio/skill/rejueqing2.mp3", + "audio/skill/rejunxing1.mp3", + "audio/skill/rejunxing2.mp3", + "audio/skill/rekanpo_ol_pangtong1.mp3", + "audio/skill/rekanpo_ol_pangtong2.mp3", + "audio/skill/rekanpo_ol_sp_zhugeliang1.mp3", + "audio/skill/rekanpo_ol_sp_zhugeliang2.mp3", + "audio/skill/rekanpo1.mp3", + "audio/skill/rekanpo2.mp3", + "audio/skill/rekuangbi1.mp3", + "audio/skill/rekuangbi2.mp3", + "audio/skill/rekuangcai1.mp3", + "audio/skill/rekuangcai2.mp3", + "audio/skill/rekurou1.mp3", + "audio/skill/rekurou2.mp3", + "audio/skill/releiji1.mp3", + "audio/skill/releiji2.mp3", + "audio/skill/reliangying1.mp3", + "audio/skill/reliangying2.mp3", + "audio/skill/relianying1.mp3", + "audio/skill/relianying2.mp3", + "audio/skill/relieren1.mp3", + "audio/skill/relieren2.mp3", + "audio/skill/relihuo1.mp3", + "audio/skill/relihuo2.mp3", + "audio/skill/relinglong1.mp3", + "audio/skill/relinglong2.mp3", + "audio/skill/relonghun1.mp3", + "audio/skill/relonghun2.mp3", + "audio/skill/relongyin1.mp3", + "audio/skill/relongyin2.mp3", + "audio/skill/reluanji1.mp3", + "audio/skill/reluanji2.mp3", + "audio/skill/reluoshen1.mp3", + "audio/skill/reluoshen2.mp3", + "audio/skill/reluoyi1.mp3", + "audio/skill/reluoyi2.mp3", + "audio/skill/reluoying_dc_caozhi1.mp3", + "audio/skill/reluoying_dc_caozhi2.mp3", + "audio/skill/reluoying1.mp3", + "audio/skill/reluoying2.mp3", + "audio/skill/remieji1.mp3", + "audio/skill/remieji2.mp3", + "audio/skill/remingce1.mp3", + "audio/skill/remingce2.mp3", + "audio/skill/rende1.mp3", + "audio/skill/rende2.mp3", + "audio/skill/renjie.mp3", + "audio/skill/renjie2.mp3", + "audio/skill/renjie21.mp3", + "audio/skill/renjie22.mp3", + "audio/skill/renshe1.mp3", + "audio/skill/renshe2.mp3", + "audio/skill/renshi1.mp3", + "audio/skill/renshi2.mp3", + "audio/skill/renwang_skill.mp3", + "audio/skill/renxin_re_caochong1.mp3", + "audio/skill/renxin_re_caochong2.mp3", + "audio/skill/renxin1.mp3", + "audio/skill/renxin2.mp3", + "audio/skill/renzheng1.mp3", + "audio/skill/renzheng2.mp3", + "audio/skill/repaoxiao1.mp3", + "audio/skill/repaoxiao2.mp3", + "audio/skill/repindi1.mp3", + "audio/skill/repindi2.mp3", + "audio/skill/repingkou1.mp3", + "audio/skill/repingkou2.mp3", + "audio/skill/repojun1.mp3", + "audio/skill/repojun2.mp3", + "audio/skill/repolu1.mp3", + "audio/skill/reqiangxi1.mp3", + "audio/skill/reqiangxi2.mp3", + "audio/skill/reqianxi1.mp3", + "audio/skill/reqianxi2.mp3", + "audio/skill/reqianxun1.mp3", + "audio/skill/reqianxun2.mp3", + "audio/skill/reqiaobian1.mp3", + "audio/skill/reqiaobian2.mp3", + "audio/skill/reqiaoshi1.mp3", + "audio/skill/reqiaoshi2.mp3", + "audio/skill/reqiaoshui1.mp3", + "audio/skill/reqiaoshui2.mp3", + "audio/skill/reqice1.mp3", + "audio/skill/reqice2.mp3", + "audio/skill/reqieting1.mp3", + "audio/skill/reqieting2.mp3", + "audio/skill/reqimou1.mp3", + "audio/skill/reqimou2.mp3", + "audio/skill/reqingcheng1.mp3", + "audio/skill/reqingcheng2.mp3", + "audio/skill/reqingguo1.mp3", + "audio/skill/reqingguo2.mp3", + "audio/skill/reqingxi1.mp3", + "audio/skill/reqingxi2.mp3", + "audio/skill/reqinwang1.mp3", + "audio/skill/reqinwang2.mp3", + "audio/skill/reqiuyuan1.mp3", + "audio/skill/reqiuyuan2.mp3", + "audio/skill/requanji1.mp3", + "audio/skill/requanji2.mp3", + "audio/skill/rerende_gz_jun_liubei1.mp3", + "audio/skill/rerende_gz_jun_liubei2.mp3", + "audio/skill/rerende_shen_caopi1.mp3", + "audio/skill/rerende_shen_caopi2.mp3", + "audio/skill/rerende1.mp3", + "audio/skill/rerende2.mp3", + "audio/skill/resanyao1.mp3", + "audio/skill/resanyao2.mp3", + "audio/skill/reshangshi1.mp3", + "audio/skill/reshangshi2.mp3", + "audio/skill/reshejian1.mp3", + "audio/skill/reshejian2.mp3", + "audio/skill/reshenduan1.mp3", + "audio/skill/reshenduan2.mp3", + "audio/skill/reshenxing1.mp3", + "audio/skill/reshenxing2.mp3", + "audio/skill/reshishou1.mp3", + "audio/skill/reshishou2.mp3", + "audio/skill/residi1.mp3", + "audio/skill/residi2.mp3", + "audio/skill/retieji_boss_lvbu31.mp3", + "audio/skill/retieji_boss_lvbu32.mp3", + "audio/skill/retieji1.mp3", + "audio/skill/retieji2.mp3", + "audio/skill/retishen1.mp3", + "audio/skill/retishen2.mp3", + "audio/skill/retongbo1.mp3", + "audio/skill/retongbo2.mp3", + "audio/skill/retuntian1.mp3", + "audio/skill/retuntian2.mp3", + "audio/skill/retuxi1.mp3", + "audio/skill/retuxi2.mp3", + "audio/skill/rewangzu1.mp3", + "audio/skill/rewangzu2.mp3", + "audio/skill/reweimu1.mp3", + "audio/skill/reweimu2.mp3", + "audio/skill/rewurong1.mp3", + "audio/skill/rewurong2.mp3", + "audio/skill/rexiantu1.mp3", + "audio/skill/rexiantu2.mp3", + "audio/skill/rexianzhen1.mp3", + "audio/skill/rexianzhen2.mp3", + "audio/skill/rexianzhou1.mp3", + "audio/skill/rexianzhou2.mp3", + "audio/skill/rexingshang1.mp3", + "audio/skill/rexingshang2.mp3", + "audio/skill/rexingsheng1.mp3", + "audio/skill/rexingsheng2.mp3", + "audio/skill/rexingxue1.mp3", + "audio/skill/rexingxue2.mp3", + "audio/skill/rexinsheng1.mp3", + "audio/skill/rexinsheng2.mp3", + "audio/skill/rexuanhuo1.mp3", + "audio/skill/rexuanhuo2.mp3", + "audio/skill/reyajiao1.mp3", + "audio/skill/reyajiao2.mp3", + "audio/skill/reyanyu1.mp3", + "audio/skill/reyanyu2.mp3", + "audio/skill/reyanzhu1.mp3", + "audio/skill/reyanzhu2.mp3", + "audio/skill/reyicong_dc_gongsunzan.mp3", + "audio/skill/reyicong_dc_gongsunzan1.mp3", + "audio/skill/reyicong1.mp3", + "audio/skill/reyicong2.mp3", + "audio/skill/reyiji1.mp3", + "audio/skill/reyiji2.mp3", + "audio/skill/reyingshi1.mp3", + "audio/skill/reyingshi2.mp3", + "audio/skill/reyingshui1.mp3", + "audio/skill/reyingshui2.mp3", + "audio/skill/reyingzi_gexuan1.mp3", + "audio/skill/reyingzi_heqi1.mp3", + "audio/skill/reyingzi_heqi2.mp3", + "audio/skill/reyingzi_re_heqi1.mp3", + "audio/skill/reyingzi_re_heqi2.mp3", + "audio/skill/reyingzi_re_sunben1.mp3", + "audio/skill/reyingzi_re_sunben2.mp3", + "audio/skill/reyingzi_re_sunce1.mp3", + "audio/skill/reyingzi_re_sunce2.mp3", + "audio/skill/reyingzi_re_sunyi1.mp3", + "audio/skill/reyingzi_sunce1.mp3", + "audio/skill/reyingzi_sunce2.mp3", + "audio/skill/reyingzi1.mp3", + "audio/skill/reyingzi2.mp3", + "audio/skill/reyonglve1.mp3", + "audio/skill/reyonglve2.mp3", + "audio/skill/rezaiqi1.mp3", + "audio/skill/rezaiqi2.mp3", + "audio/skill/rezhanjue1.mp3", + "audio/skill/rezhanjue2.mp3", + "audio/skill/rezhiheng_shen_caopi1.mp3", + "audio/skill/rezhiheng_shen_caopi2.mp3", + "audio/skill/rezhiheng1.mp3", + "audio/skill/rezhiheng2.mp3", + "audio/skill/rezhijian1.mp3", + "audio/skill/rezhijian2.mp3", + "audio/skill/rezhiyu1.mp3", + "audio/skill/rezhiyu2.mp3", + "audio/skill/rezhongyong1.mp3", + "audio/skill/rezhongyong2.mp3", + "audio/skill/rezhuhai1.mp3", + "audio/skill/rezhuhai2.mp3", + "audio/skill/rezhuikong1.mp3", + "audio/skill/rezhuikong2.mp3", + "audio/skill/rezongshi1.mp3", + "audio/skill/rezongshi2.mp3", + "audio/skill/rezongxuan1.mp3", + "audio/skill/rezongxuan2.mp3", + "audio/skill/rongbei1.mp3", + "audio/skill/rongbei2.mp3", + "audio/skill/roulin_ol_dongzhuo1.mp3", + "audio/skill/roulin_ol_dongzhuo2.mp3", + "audio/skill/roulin_re_dongzhuo1.mp3", + "audio/skill/roulin_re_dongzhuo2.mp3", + "audio/skill/roulin1.mp3", + "audio/skill/roulin2.mp3", + "audio/skill/ruilve1.mp3", + "audio/skill/ruilve2.mp3", + "audio/skill/ruoyu_re_liushan1.mp3", + "audio/skill/ruoyu_re_liushan2.mp3", + "audio/skill/ruoyu1.mp3", + "audio/skill/ruoyu2.mp3", + "audio/skill/rw_bagua_skill.mp3", + "audio/skill/rw_baiyin_skill.mp3", + "audio/skill/rw_renwang_skill.mp3", + "audio/skill/rw_tengjia1.mp3", + "audio/skill/rw_tengjia2.mp3", + "audio/skill/rw_zhuge_skill.mp3", + "audio/skill/sanchen1.mp3", + "audio/skill/sanchen2.mp3", + "audio/skill/sangu1.mp3", + "audio/skill/sangu2.mp3", + "audio/skill/sanjian_skill.mp3", + "audio/skill/sanku1.mp3", + "audio/skill/sanku2.mp3", + "audio/skill/sanshou1.mp3", + "audio/skill/sanshou2.mp3", + "audio/skill/sanyao1.mp3", + "audio/skill/sanyao2.mp3", + "audio/skill/saodi1.mp3", + "audio/skill/saodi2.mp3", + "audio/skill/saya_powei1.mp3", + "audio/skill/saya_powei2.mp3", + "audio/skill/saya_shouji1.mp3", + "audio/skill/saya_shouji2.mp3", + "audio/skill/sbaiyin.mp3", + "audio/skill/sbaiyin1.mp3", + "audio/skill/sbaiyin2.mp3", + "audio/skill/sbanguo1.mp3", + "audio/skill/sbanguo2.mp3", + "audio/skill/sbanguo3.mp3", + "audio/skill/sbbenxi1.mp3", + "audio/skill/sbbenxi2.mp3", + "audio/skill/sbbenxi3.mp3", + "audio/skill/sbbiyue1.mp3", + "audio/skill/sbbiyue2.mp3", + "audio/skill/sbduanliang_false.mp3", + "audio/skill/sbduanliang_true1.mp3", + "audio/skill/sbduanliang_true2.mp3", + "audio/skill/sbduanliang1.mp3", + "audio/skill/sbdujiang1.mp3", + "audio/skill/sbdujiang2.mp3", + "audio/skill/sbduojing1.mp3", + "audio/skill/sbduojing2.mp3", + "audio/skill/sbenyuan1.mp3", + "audio/skill/sbenyuan2.mp3", + "audio/skill/sbfangzhu_mb_caomao1.mp3", + "audio/skill/sbfangzhu_mb_caomao2.mp3", + "audio/skill/sbfangzhu1.mp3", + "audio/skill/sbfangzhu2.mp3", + "audio/skill/sbfanjian1.mp3", + "audio/skill/sbfanjian2.mp3", + "audio/skill/sbfenwei1.mp3", + "audio/skill/sbfenwei2.mp3", + "audio/skill/sbganglie1.mp3", + "audio/skill/sbganglie2.mp3", + "audio/skill/sbguanxing1.mp3", + "audio/skill/sbguanxing2.mp3", + "audio/skill/sbguidao1.mp3", + "audio/skill/sbguidao2.mp3", + "audio/skill/sbguose1.mp3", + "audio/skill/sbguose2.mp3", + "audio/skill/sbhuangtian1.mp3", + "audio/skill/sbhuangtian2.mp3", + "audio/skill/sbhujia1.mp3", + "audio/skill/sbhujia2.mp3", + "audio/skill/sbhunzi1.mp3", + "audio/skill/sbhunzi2.mp3", + "audio/skill/sbhuoji1.mp3", + "audio/skill/sbhuoji2.mp3", + "audio/skill/sbhuoji3.mp3", + "audio/skill/sbhuoshou1.mp3", + "audio/skill/sbhuoshou2.mp3", + "audio/skill/sbjiang1.mp3", + "audio/skill/sbjiang2.mp3", + "audio/skill/sbjianxiong1.mp3", + "audio/skill/sbjianxiong2.mp3", + "audio/skill/sbjieming1.mp3", + "audio/skill/sbjieming2.mp3", + "audio/skill/sbjiewei1.mp3", + "audio/skill/sbjiewei2.mp3", + "audio/skill/sbjieyin1.mp3", + "audio/skill/sbjieyin2.mp3", + "audio/skill/sbjieyue1.mp3", + "audio/skill/sbjieyue2.mp3", + "audio/skill/sbjieyue3.mp3", + "audio/skill/sbjieyue4.mp3", + "audio/skill/sbjijiang1.mp3", + "audio/skill/sbjijiang2.mp3", + "audio/skill/sbjinjiu1.mp3", + "audio/skill/sbjinjiu2.mp3", + "audio/skill/sbjiuyuan1.mp3", + "audio/skill/sbjiuyuan2.mp3", + "audio/skill/sbjizhi1.mp3", + "audio/skill/sbjizhi2.mp3", + "audio/skill/sbjizhu1.mp3", + "audio/skill/sbjizhu2.mp3", + "audio/skill/sbjizhu3.mp3", + "audio/skill/sbjushou1.mp3", + "audio/skill/sbjushou2.mp3", + "audio/skill/sbjushou3.mp3", + "audio/skill/sbjuxiang1.mp3", + "audio/skill/sbjuxiang2.mp3", + "audio/skill/sbkanpo1.mp3", + "audio/skill/sbkanpo2.mp3", + "audio/skill/sbkeji1.mp3", + "audio/skill/sbkeji2.mp3", + "audio/skill/sbkongcheng1.mp3", + "audio/skill/sbkongcheng2.mp3", + "audio/skill/sbkurou1.mp3", + "audio/skill/sbkurou2.mp3", + "audio/skill/sbleiji1.mp3", + "audio/skill/sbleiji2.mp3", + "audio/skill/sbliangzhu1.mp3", + "audio/skill/sbliangzhu2.mp3", + "audio/skill/sblianhuan1.mp3", + "audio/skill/sblianhuan2.mp3", + "audio/skill/sbliegong1.mp3", + "audio/skill/sbliegong2.mp3", + "audio/skill/sblieren1.mp3", + "audio/skill/sblieren2.mp3", + "audio/skill/sblijian1.mp3", + "audio/skill/sblijian2.mp3", + "audio/skill/sbliuli1.mp3", + "audio/skill/sbliuli2.mp3", + "audio/skill/sblongdan1.mp3", + "audio/skill/sblongdan2.mp3", + "audio/skill/sbluanji1.mp3", + "audio/skill/sbluanji2.mp3", + "audio/skill/sbluoshen1.mp3", + "audio/skill/sbluoshen2.mp3", + "audio/skill/sbmingce1.mp3", + "audio/skill/sbmingce2.mp3", + "audio/skill/sbniepan1.mp3", + "audio/skill/sbniepan2.mp3", + "audio/skill/sbpaoxiao1.mp3", + "audio/skill/sbpaoxiao2.mp3", + "audio/skill/sbqiaobian1.mp3", + "audio/skill/sbqiaobian2.mp3", + "audio/skill/sbqiaoshi1.mp3", + "audio/skill/sbqiaoshi2.mp3", + "audio/skill/sbqicai1.mp3", + "audio/skill/sbqicai2.mp3", + "audio/skill/sbqingjian1.mp3", + "audio/skill/sbqingjian2.mp3", + "audio/skill/sbqingzheng_mb_caomao1.mp3", + "audio/skill/sbqingzheng_mb_caomao2.mp3", + "audio/skill/sbqingzheng1.mp3", + "audio/skill/sbqingzheng2.mp3", + "audio/skill/sbqixi1.mp3", + "audio/skill/sbqixi2.mp3", + "audio/skill/sbquhu1.mp3", + "audio/skill/sbquhu2.mp3", + "audio/skill/sbrende1.mp3", + "audio/skill/sbrende2.mp3", + "audio/skill/sbrende3.mp3", + "audio/skill/sbshipo1.mp3", + "audio/skill/sbshipo2.mp3", + "audio/skill/sbsongwei1.mp3", + "audio/skill/sbsongwei2.mp3", + "audio/skill/sbtianxiang1.mp3", + "audio/skill/sbtianxiang2.mp3", + "audio/skill/sbtiaoxin1.mp3", + "audio/skill/sbtiaoxin2.mp3", + "audio/skill/sbtieji_false.mp3", + "audio/skill/sbtieji_true1.mp3", + "audio/skill/sbtieji_true2.mp3", + "audio/skill/sbtieji1.mp3", + "audio/skill/sbtongye1.mp3", + "audio/skill/sbtongye2.mp3", + "audio/skill/sbwusheng1.mp3", + "audio/skill/sbwusheng2.mp3", + "audio/skill/sbwusheng3.mp3", + "audio/skill/sbxianzhen1.mp3", + "audio/skill/sbxianzhen2.mp3", + "audio/skill/sbxiaoji1.mp3", + "audio/skill/sbxiaoji2.mp3", + "audio/skill/sbxiayuan1.mp3", + "audio/skill/sbxiayuan2.mp3", + "audio/skill/sbxieji1.mp3", + "audio/skill/sbxieji2.mp3", + "audio/skill/sbxieji3.mp3", + "audio/skill/sbxingshang1.mp3", + "audio/skill/sbxingshang2.mp3", + "audio/skill/sbxuanhuo1.mp3", + "audio/skill/sbxuanhuo2.mp3", + "audio/skill/sbxueyi1.mp3", + "audio/skill/sbxueyi2.mp3", + "audio/skill/sbyangwei1.mp3", + "audio/skill/sbyangwei2.mp3", + "audio/skill/sbyanyu1.mp3", + "audio/skill/sbyanyu2.mp3", + "audio/skill/sbyaoming1.mp3", + "audio/skill/sbyaoming2.mp3", + "audio/skill/sbyijue1.mp3", + "audio/skill/sbyijue2.mp3", + "audio/skill/sbyingzi_sb_sunce1.mp3", + "audio/skill/sbyingzi_sb_sunce2.mp3", + "audio/skill/sbyingzi1.mp3", + "audio/skill/sbyingzi2.mp3", + "audio/skill/sbzaiqi1.mp3", + "audio/skill/sbzaiqi2.mp3", + "audio/skill/sbzhangwu1.mp3", + "audio/skill/sbzhangwu2.mp3", + "audio/skill/sbzhaxiang1.mp3", + "audio/skill/sbzhaxiang2.mp3", + "audio/skill/sbzhenliang1.mp3", + "audio/skill/sbzhenliang2.mp3", + "audio/skill/sbzhiba1.mp3", + "audio/skill/sbzhiba2.mp3", + "audio/skill/sbzhichi1.mp3", + "audio/skill/sbzhichi2.mp3", + "audio/skill/sbzhiheng1.mp3", + "audio/skill/sbzhiheng2.mp3", + "audio/skill/sbzhiji1.mp3", + "audio/skill/sbzhiji2.mp3", + "audio/skill/sbzishou1.mp3", + "audio/skill/sbzishou2.mp3", + "audio/skill/sbzongshi1.mp3", + "audio/skill/sbzongshi2.mp3", + "audio/skill/scfuhai1.mp3", + "audio/skill/scfuhai2.mp3", + "audio/skill/scs_bilan_enter.mp3", + "audio/skill/scs_duangui_enter.mp3", + "audio/skill/scs_gaowang_enter.mp3", + "audio/skill/scs_guosheng_enter.mp3", + "audio/skill/scs_hankui_enter.mp3", + "audio/skill/scs_lisong_enter.mp3", + "audio/skill/scs_sunzhang_enter.mp3", + "audio/skill/scs_xiayun_enter.mp3", + "audio/skill/scs_zhangrang_enter.mp3", + "audio/skill/scs_zhaozhong_enter.mp3", + "audio/skill/scsanruo1.mp3", + "audio/skill/scschihe1.mp3", + "audio/skill/scschiyan1.mp3", + "audio/skill/scskuiji1.mp3", + "audio/skill/scsniqu1.mp3", + "audio/skill/scspicai1.mp3", + "audio/skill/scstaoluan1.mp3", + "audio/skill/scsxiaolu1.mp3", + "audio/skill/scsyaozhuo1.mp3", + "audio/skill/scszimou1.mp3", + "audio/skill/sghuishi1.mp3", + "audio/skill/sghuishi2.mp3", + "audio/skill/sgrenwang1.mp3", + "audio/skill/sgrenwang2.mp3", + "audio/skill/shameng1.mp3", + "audio/skill/shameng2.mp3", + "audio/skill/shanduan1.mp3", + "audio/skill/shanduan2.mp3", + "audio/skill/shangshi1.mp3", + "audio/skill/shangshi2.mp3", + "audio/skill/shangshix1.mp3", + "audio/skill/shangshix2.mp3", + "audio/skill/shangyi1.mp3", + "audio/skill/shangyi2.mp3", + "audio/skill/shanjia1.mp3", + "audio/skill/shanjia2.mp3", + "audio/skill/shanli1.mp3", + "audio/skill/shanli2.mp3", + "audio/skill/shanshen1.mp3", + "audio/skill/shanshen2.mp3", + "audio/skill/shanxi1.mp3", + "audio/skill/shanxi2.mp3", + "audio/skill/shanxie1.mp3", + "audio/skill/shanxie2.mp3", + "audio/skill/shanzhuan1.mp3", + "audio/skill/shanzhuan2.mp3", + "audio/skill/shebian1.mp3", + "audio/skill/shebian2.mp3", + "audio/skill/shefu1.mp3", + "audio/skill/shefu2.mp3", + "audio/skill/shejian1.mp3", + "audio/skill/shejian2.mp3", + "audio/skill/shelie1.mp3", + "audio/skill/shelie2.mp3", + "audio/skill/shencai1.mp3", + "audio/skill/shencai2.mp3", + "audio/skill/shenduan1.mp3", + "audio/skill/shenduan2.mp3", + "audio/skill/shenfen1.mp3", + "audio/skill/shenfen2.mp3", + "audio/skill/shenfu1.mp3", + "audio/skill/shenfu2.mp3", + "audio/skill/shengxi_feiyi1.mp3", + "audio/skill/shengxi_feiyi2.mp3", + "audio/skill/shengxi1.mp3", + "audio/skill/shengxi2.mp3", + "audio/skill/shenji1.mp3", + "audio/skill/shenji2.mp3", + "audio/skill/shenju1.mp3", + "audio/skill/shenju2.mp3", + "audio/skill/shenpin1.mp3", + "audio/skill/shenpin2.mp3", + "audio/skill/shenqu1.mp3", + "audio/skill/shenqu2.mp3", + "audio/skill/shensu1_ol_xiahouyuan1.mp3", + "audio/skill/shensu1_ol_xiahouyuan2.mp3", + "audio/skill/shensu1_re_xiahouyuan1.mp3", + "audio/skill/shensu1_re_xiahouyuan2.mp3", + "audio/skill/shensu1_xiahouba1.mp3", + "audio/skill/shensu1_xiahouba2.mp3", + "audio/skill/shensu11.mp3", + "audio/skill/shensu12.mp3", + "audio/skill/shensu21.mp3", + "audio/skill/shensu22.mp3", + "audio/skill/shenwei1.mp3", + "audio/skill/shenwei2.mp3", + "audio/skill/shenxian1.mp3", + "audio/skill/shenxian2.mp3", + "audio/skill/shenxing1.mp3", + "audio/skill/shenxing2.mp3", + "audio/skill/shenzhi1.mp3", + "audio/skill/shenzhi2.mp3", + "audio/skill/shenzhu1.mp3", + "audio/skill/shenzhu2.mp3", + "audio/skill/sheyan1.mp3", + "audio/skill/sheyan2.mp3", + "audio/skill/sheyi1.mp3", + "audio/skill/sheyi2.mp3", + "audio/skill/shezang1.mp3", + "audio/skill/shezang2.mp3", + "audio/skill/shhlianhua1.mp3", + "audio/skill/shhlianhua2.mp3", + "audio/skill/shibei_xin_jushou1.mp3", + "audio/skill/shibei_xin_jushou2.mp3", + "audio/skill/shibei1.mp3", + "audio/skill/shibei2.mp3", + "audio/skill/shichou1.mp3", + "audio/skill/shichou2.mp3", + "audio/skill/shiduo1.mp3", + "audio/skill/shiduo2.mp3", + "audio/skill/shifei_re_guotufengji1.mp3", + "audio/skill/shifei_re_guotufengji2.mp3", + "audio/skill/shifei1.mp3", + "audio/skill/shifei2.mp3", + "audio/skill/shiina_feiyan1.mp3", + "audio/skill/shiina_qingshen1.mp3", + "audio/skill/shiina_retieji1.mp3", + "audio/skill/shiki_omusubi1.mp3", + "audio/skill/shiki_omusubi2.mp3", + "audio/skill/shiming1.mp3", + "audio/skill/shiming2.mp3", + "audio/skill/shiorimiyuki_banyin1.mp3", + "audio/skill/shiorimiyuki_banyin2.mp3", + "audio/skill/shiorimiyuki_tingxian1.mp3", + "audio/skill/shiorimiyuki_tingxian2.mp3", + "audio/skill/shiren1.mp3", + "audio/skill/shiren2.mp3", + "audio/skill/shishengshibai.mp3", + "audio/skill/shixin1.mp3", + "audio/skill/shixin2.mp3", + "audio/skill/shiyong1.mp3", + "audio/skill/shiyong2.mp3", + "audio/skill/shiyong3.mp3", + "audio/skill/shiyuan1.mp3", + "audio/skill/shiyuan2.mp3", + "audio/skill/shizhan1.mp3", + "audio/skill/shizhan2.mp3", + "audio/skill/shoucheng1.mp3", + "audio/skill/shoucheng2.mp3", + "audio/skill/shoufa1.mp3", + "audio/skill/shoufa2.mp3", + "audio/skill/shouli1.mp3", + "audio/skill/shouli2.mp3", + "audio/skill/shoulijian.mp3", + "audio/skill/shouxi1.mp3", + "audio/skill/shouxi2.mp3", + "audio/skill/shouye1.mp3", + "audio/skill/shouye2.mp3", + "audio/skill/shuaiyan1.mp3", + "audio/skill/shuaiyan2.mp3", + "audio/skill/shuangren1.mp3", + "audio/skill/shuangren2.mp3", + "audio/skill/shuangxiong_re_yanwen1.mp3", + "audio/skill/shuangxiong_re_yanwen2.mp3", + "audio/skill/shuangxiong1.mp3", + "audio/skill/shuangxiong2.mp3", + "audio/skill/shuchen1.mp3", + "audio/skill/shuchen2.mp3", + "audio/skill/shuimeng1.mp3", + "audio/skill/shuimeng2.mp3", + "audio/skill/shuishi1.mp3", + "audio/skill/shuishi2.mp3", + "audio/skill/shuliang1.mp3", + "audio/skill/shuliang2.mp3", + "audio/skill/shunshi1.mp3", + "audio/skill/shunshi2.mp3", + "audio/skill/shuojian1.mp3", + "audio/skill/shuojian2.mp3", + "audio/skill/shushen1.mp3", + "audio/skill/shushen2.mp3", + "audio/skill/sibian1.mp3", + "audio/skill/sibian2.mp3", + "audio/skill/sidi.mp3", + "audio/skill/sidi1.mp3", + "audio/skill/sidi2.mp3", + "audio/skill/sijian1.mp3", + "audio/skill/sijian2.mp3", + "audio/skill/sijun1.mp3", + "audio/skill/sijun2.mp3", + "audio/skill/sishu1.mp3", + "audio/skill/sishu2.mp3", + "audio/skill/smyyingshi1.mp3", + "audio/skill/smyyingshi2.mp3", + "audio/skill/songci1.mp3", + "audio/skill/songci2.mp3", + "audio/skill/songshu1.mp3", + "audio/skill/songshu2.mp3", + "audio/skill/songwei_re_caopi1.mp3", + "audio/skill/songwei_re_caopi2.mp3", + "audio/skill/songwei2_re_caopi1.mp3", + "audio/skill/songwei2_re_caopi2.mp3", + "audio/skill/songwei21.mp3", + "audio/skill/songwei22.mp3", + "audio/skill/souying1.mp3", + "audio/skill/souying2.mp3", + "audio/skill/spchijie1.mp3", + "audio/skill/spchijie2.mp3", + "audio/skill/spcunsi1.mp3", + "audio/skill/spcunsi2.mp3", + "audio/skill/spdaizui1.mp3", + "audio/skill/spdaizui2.mp3", + "audio/skill/spdaming1.mp3", + "audio/skill/spdaming2.mp3", + "audio/skill/spdaming3.mp3", + "audio/skill/spdaoshu1.mp3", + "audio/skill/spdaoshu2.mp3", + "audio/skill/spdaoshu3.mp3", + "audio/skill/spdengli1.mp3", + "audio/skill/spdengli2.mp3", + "audio/skill/spdiancai1.mp3", + "audio/skill/spdiancai2.mp3", + "audio/skill/spdiaodu1.mp3", + "audio/skill/spdiaodu2.mp3", + "audio/skill/spdifei1.mp3", + "audio/skill/spdifei2.mp3", + "audio/skill/spell2131_1.mp3", + "audio/skill/spell2131_2.mp3", + "audio/skill/spfangzong1.mp3", + "audio/skill/spfangzong2.mp3", + "audio/skill/spfenming1.mp3", + "audio/skill/spfenming2.mp3", + "audio/skill/spguixiu1.mp3", + "audio/skill/spguixiu2.mp3", + "audio/skill/spjianyi1.mp3", + "audio/skill/spjianyi2.mp3", + "audio/skill/spjiedao1.mp3", + "audio/skill/spjiedao2.mp3", + "audio/skill/spjincui1.mp3", + "audio/skill/spjincui2.mp3", + "audio/skill/spjungong1.mp3", + "audio/skill/spjungong2.mp3", + "audio/skill/splirang1.mp3", + "audio/skill/splirang2.mp3", + "audio/skill/splveying1.mp3", + "audio/skill/splveying2.mp3", + "audio/skill/spmanwang1.mp3", + "audio/skill/spmanwang2.mp3", + "audio/skill/spmiewu1.mp3", + "audio/skill/spmiewu2.mp3", + "audio/skill/spmingshi1.mp3", + "audio/skill/spmingshi2.mp3", + "audio/skill/spmingxuan1.mp3", + "audio/skill/spmingxuan2.mp3", + "audio/skill/spolzhouxuan1.mp3", + "audio/skill/spolzhouxuan2.mp3", + "audio/skill/sppanqin1.mp3", + "audio/skill/sppanqin2.mp3", + "audio/skill/spqiai1.mp3", + "audio/skill/spqiai2.mp3", + "audio/skill/spqishe1.mp3", + "audio/skill/spqishe2.mp3", + "audio/skill/spsanchen1.mp3", + "audio/skill/spsanchen2.mp3", + "audio/skill/spshangyi1.mp3", + "audio/skill/spshangyi2.mp3", + "audio/skill/spshanxi1.mp3", + "audio/skill/spshanxi2.mp3", + "audio/skill/spshicai1.mp3", + "audio/skill/spshicai2.mp3", + "audio/skill/spshidi1.mp3", + "audio/skill/spshidi2.mp3", + "audio/skill/spshiji1.mp3", + "audio/skill/spshiji2.mp3", + "audio/skill/spsongshu1.mp3", + "audio/skill/spsongshu2.mp3", + "audio/skill/sptaoluan1.mp3", + "audio/skill/sptaoluan2.mp3", + "audio/skill/sptunjiang1.mp3", + "audio/skill/sptunjiang2.mp3", + "audio/skill/spwanwei1.mp3", + "audio/skill/spwanwei2.mp3", + "audio/skill/spweiwu1.mp3", + "audio/skill/spweiwu2.mp3", + "audio/skill/spwenji1.mp3", + "audio/skill/spwenji2.mp3", + "audio/skill/spwuku1.mp3", + "audio/skill/spwuku2.mp3", + "audio/skill/spxianchou1.mp3", + "audio/skill/spxianchou2.mp3", + "audio/skill/spxiangzhen1.mp3", + "audio/skill/spxiangzhen2.mp3", + "audio/skill/spxiaoni1.mp3", + "audio/skill/spxiaoni2.mp3", + "audio/skill/spxizhan1.mp3", + "audio/skill/spxizhan2.mp3", + "audio/skill/spxizhan3.mp3", + "audio/skill/spxizhan4.mp3", + "audio/skill/spyajun1.mp3", + "audio/skill/spyajun2.mp3", + "audio/skill/spyanji1.mp3", + "audio/skill/spyanji2.mp3", + "audio/skill/spyanji3.mp3", + "audio/skill/spyanjiao1.mp3", + "audio/skill/spyanjiao2.mp3", + "audio/skill/spyilie1.mp3", + "audio/skill/spyilie2.mp3", + "audio/skill/spyingwu1.mp3", + "audio/skill/spyingwu2.mp3", + "audio/skill/spyinju1.mp3", + "audio/skill/spyinju2.mp3", + "audio/skill/spyishi1.mp3", + "audio/skill/spyishi2.mp3", + "audio/skill/spyuejian1.mp3", + "audio/skill/spyuejian2.mp3", + "audio/skill/spzhengjun1.mp3", + "audio/skill/spzhengjun2.mp3", + "audio/skill/spzhengjun3.mp3", + "audio/skill/spzhenting1.mp3", + "audio/skill/spzhenting2.mp3", + "audio/skill/spzhenwei1.mp3", + "audio/skill/spzhenwei2.mp3", + "audio/skill/spzhuilie1.mp3", + "audio/skill/spzhuilie2.mp3", + "audio/skill/spzundi1.mp3", + "audio/skill/spzundi2.mp3", + "audio/skill/staraoshi1.mp3", + "audio/skill/staraoshi2.mp3", + "audio/skill/starcanxi1.mp3", + "audio/skill/starcanxi2.mp3", + "audio/skill/starhaoshou1.mp3", + "audio/skill/starhaoshou2.mp3", + "audio/skill/starjiaowang1.mp3", + "audio/skill/starjiaowang2.mp3", + "audio/skill/starlifeng1.mp3", + "audio/skill/starlifeng2.mp3", + "audio/skill/starpizhi1.mp3", + "audio/skill/starpizhi2.mp3", + "audio/skill/starsujun1.mp3", + "audio/skill/starsujun2.mp3", + "audio/skill/starweilin1.mp3", + "audio/skill/starweilin2.mp3", + "audio/skill/starxiaoyan1.mp3", + "audio/skill/starxiaoyan2.mp3", + "audio/skill/starzhangrong1.mp3", + "audio/skill/starzhangrong2.mp3", + "audio/skill/starzhonggu1.mp3", + "audio/skill/starzhonggu2.mp3", + "audio/skill/starzongshi1.mp3", + "audio/skill/starzongshi2.mp3", + "audio/skill/stianyi1.mp3", + "audio/skill/stianyi2.mp3", + "audio/skill/suishi1.mp3", + "audio/skill/suishi2.mp3", + "audio/skill/suizheng1.mp3", + "audio/skill/suizheng2.mp3", + "audio/skill/suoliang1.mp3", + "audio/skill/suoliang2.mp3", + "audio/skill/sushou1.mp3", + "audio/skill/sushou2.mp3", + "audio/skill/suzi1.mp3", + "audio/skill/suzi2.mp3", + "audio/skill/syjiqiao1.mp3", + "audio/skill/syjiqiao2.mp3", + "audio/skill/syxiongyi1.mp3", + "audio/skill/syxiongyi2.mp3", + "audio/skill/tairan1.mp3", + "audio/skill/tairan2.mp3", + "audio/skill/tamo1.mp3", + "audio/skill/tamo2.mp3", + "audio/skill/taoluan1.mp3", + "audio/skill/taoluan2.mp3", + "audio/skill/taomie1.mp3", + "audio/skill/taomie2.mp3", + "audio/skill/taomie3.mp3", + "audio/skill/taoxi1.mp3", + "audio/skill/taoxi2.mp3", + "audio/skill/taoyin1.mp3", + "audio/skill/taoyin2.mp3", + "audio/skill/tashui1.mp3", + "audio/skill/tashui2.mp3", + "audio/skill/tengjia1.mp3", + "audio/skill/tengjia2.mp3", + "audio/skill/tianbian1.mp3", + "audio/skill/tianbian2.mp3", + "audio/skill/tiandao.mp3", + "audio/skill/tiandu_re_guojia1.mp3", + "audio/skill/tiandu_re_guojia2.mp3", + "audio/skill/tiandu_xizhicai1.mp3", + "audio/skill/tiandu_xizhicai2.mp3", + "audio/skill/tiandu1.mp3", + "audio/skill/tiandu2.mp3", + "audio/skill/tianfu1.mp3", + "audio/skill/tianfu2.mp3", + "audio/skill/tianjie1.mp3", + "audio/skill/tianjie2.mp3", + "audio/skill/tianming1.mp3", + "audio/skill/tianming2.mp3", + "audio/skill/tianren1.mp3", + "audio/skill/tianren2.mp3", + "audio/skill/tianshu1.mp3", + "audio/skill/tianshu2.mp3", + "audio/skill/tiansuan1.mp3", + "audio/skill/tiansuan2.mp3", + "audio/skill/tianxiang_daxiaoqiao1.mp3", + "audio/skill/tianxiang_daxiaoqiao2.mp3", + "audio/skill/tianxiang_ol_xiaoqiao1.mp3", + "audio/skill/tianxiang_ol_xiaoqiao2.mp3", + "audio/skill/tianxiang_re_xiaoqiao1.mp3", + "audio/skill/tianxiang_re_xiaoqiao2.mp3", + "audio/skill/tianxiang1.mp3", + "audio/skill/tianxiang2.mp3", + "audio/skill/tianxing1.mp3", + "audio/skill/tianxing2.mp3", + "audio/skill/tianyi_re_taishici1.mp3", + "audio/skill/tianyi_re_taishici2.mp3", + "audio/skill/tianyi1.mp3", + "audio/skill/tianyi2.mp3", + "audio/skill/tianyin1.mp3", + "audio/skill/tianyin2.mp3", + "audio/skill/tianyun1.mp3", + "audio/skill/tianyun2.mp3", + "audio/skill/tianze1.mp3", + "audio/skill/tianze2.mp3", + "audio/skill/tianzuo1.mp3", + "audio/skill/tianzuo2.mp3", + "audio/skill/tiaoxin_gz_jiangwei1.mp3", + "audio/skill/tiaoxin_gz_jiangwei2.mp3", + "audio/skill/tiaoxin_ol_jiangwei1.mp3", + "audio/skill/tiaoxin_ol_jiangwei2.mp3", + "audio/skill/tiaoxin_re_jiangwei1.mp3", + "audio/skill/tiaoxin_re_jiangwei2.mp3", + "audio/skill/tiaoxin_sp_jiangwei1.mp3", + "audio/skill/tiaoxin_sp_jiangwei2.mp3", + "audio/skill/tiaoxin_xiahouba1.mp3", + "audio/skill/tiaoxin_xiahouba2.mp3", + "audio/skill/tiaoxin1.mp3", + "audio/skill/tiaoxin2.mp3", + "audio/skill/tieji1.mp3", + "audio/skill/tieji2.mp3", + "audio/skill/tiqi1.mp3", + "audio/skill/tiqi2.mp3", + "audio/skill/tongbo1.mp3", + "audio/skill/tongbo2.mp3", + "audio/skill/tongduo1.mp3", + "audio/skill/tongduo2.mp3", + "audio/skill/tongji1.mp3", + "audio/skill/tongji2.mp3", + "audio/skill/tongli1.mp3", + "audio/skill/tongli2.mp3", + "audio/skill/tongqu1.mp3", + "audio/skill/tongqu2.mp3", + "audio/skill/tongwei1.mp3", + "audio/skill/tongwei2.mp3", + "audio/skill/tongxie1.mp3", + "audio/skill/tongxie2.mp3", + "audio/skill/tongyuan1.mp3", + "audio/skill/tongyuan2.mp3", + "audio/skill/tspowei1.mp3", + "audio/skill/tspowei2.mp3", + "audio/skill/tspowei3.mp3", + "audio/skill/tsumugi_mugyu1.mp3", + "audio/skill/tsumugi_mugyu2.mp3", + "audio/skill/tsumugi_mugyu3.mp3", + "audio/skill/tsumugi_mugyu4.mp3", + "audio/skill/tsumugi_mugyu5.mp3", + "audio/skill/tuifeng1.mp3", + "audio/skill/tuifeng2.mp3", + "audio/skill/tuishi1.mp3", + "audio/skill/tuishi2.mp3", + "audio/skill/tuiyan1.mp3", + "audio/skill/tuiyan2.mp3", + "audio/skill/tunchu1.mp3", + "audio/skill/tunchu2.mp3", + "audio/skill/tuntian_gz_dengai1.mp3", + "audio/skill/tuntian_gz_dengai2.mp3", + "audio/skill/tuntian1.mp3", + "audio/skill/tuntian2.mp3", + "audio/skill/tuogu1.mp3", + "audio/skill/tuogu2.mp3", + "audio/skill/tuoxian.mp3", + "audio/skill/tuoxian2.mp3", + "audio/skill/tuxi1.mp3", + "audio/skill/tuxi2.mp3", + "audio/skill/tuxing1.mp3", + "audio/skill/tuxing2.mp3", + "audio/skill/twbaizu1.mp3", + "audio/skill/twbaizu2.mp3", + "audio/skill/twbingde1.mp3", + "audio/skill/twbingde2.mp3", + "audio/skill/twbudao1.mp3", + "audio/skill/twbudao2.mp3", + "audio/skill/twchaofeng1.mp3", + "audio/skill/twchaofeng2.mp3", + "audio/skill/twchayi1.mp3", + "audio/skill/twchengxi1.mp3", + "audio/skill/twchengxi2.mp3", + "audio/skill/twchongqi1.mp3", + "audio/skill/twchongqi2.mp3", + "audio/skill/twchuanshu1.mp3", + "audio/skill/twchuanshu2.mp3", + "audio/skill/twchue1.mp3", + "audio/skill/twchue2.mp3", + "audio/skill/twchungang1.mp3", + "audio/skill/twchungang2.mp3", + "audio/skill/twdanfa1.mp3", + "audio/skill/twdanfa2.mp3", + "audio/skill/twdanlie1.mp3", + "audio/skill/twdanlie2.mp3", + "audio/skill/twdengjian1.mp3", + "audio/skill/twdengjian2.mp3", + "audio/skill/twdianyi1.mp3", + "audio/skill/twdianyi2.mp3", + "audio/skill/twdingzhen1.mp3", + "audio/skill/twdingzhen2.mp3", + "audio/skill/twduoren1.mp3", + "audio/skill/twduoren2.mp3", + "audio/skill/twduwang1.mp3", + "audio/skill/twduwang2.mp3", + "audio/skill/twenchou1.mp3", + "audio/skill/twenchou2.mp3", + "audio/skill/twfeifu1.mp3", + "audio/skill/twfeifu2.mp3", + "audio/skill/twfengji1.mp3", + "audio/skill/twfengji2.mp3", + "audio/skill/twfenwang1.mp3", + "audio/skill/twfenwang2.mp3", + "audio/skill/twfenwu1.mp3", + "audio/skill/twfenwu2.mp3", + "audio/skill/twfucuan1.mp3", + "audio/skill/twfucuan2.mp3", + "audio/skill/twfujian1.mp3", + "audio/skill/twfujian2.mp3", + "audio/skill/twfupan1.mp3", + "audio/skill/twfupan2.mp3", + "audio/skill/twfupan3.mp3", + "audio/skill/twfuzuan1.mp3", + "audio/skill/twfuzuan2.mp3", + "audio/skill/twgezhi1.mp3", + "audio/skill/twgezhi2.mp3", + "audio/skill/twgongge1.mp3", + "audio/skill/twgongge2.mp3", + "audio/skill/twgongge3.mp3", + "audio/skill/twhanyu1.mp3", + "audio/skill/twhanyu2.mp3", + "audio/skill/twhuajing1.mp3", + "audio/skill/twhuajing2.mp3", + "audio/skill/twhuiyuan1.mp3", + "audio/skill/twhuiyuan2.mp3", + "audio/skill/twhuzhong1.mp3", + "audio/skill/twhuzhong2.mp3", + "audio/skill/twjiange1.mp3", + "audio/skill/twjiange2.mp3", + "audio/skill/twjianming1.mp3", + "audio/skill/twjianming2.mp3", + "audio/skill/twjianwei1.mp3", + "audio/skill/twjianwei2.mp3", + "audio/skill/twjiaohua1.mp3", + "audio/skill/twjiaohua2.mp3", + "audio/skill/twjichou1.mp3", + "audio/skill/twjichou2.mp3", + "audio/skill/twjiekuang1.mp3", + "audio/skill/twjiekuang2.mp3", + "audio/skill/twjieqiu1.mp3", + "audio/skill/twjieqiu2.mp3", + "audio/skill/twjieyu1.mp3", + "audio/skill/twjieyu2.mp3", + "audio/skill/twjijiang1.mp3", + "audio/skill/twjijiang2.mp3", + "audio/skill/twjilun1.mp3", + "audio/skill/twjilun2.mp3", + "audio/skill/twjingce1.mp3", + "audio/skill/twjingce2.mp3", + "audio/skill/twjuchen1.mp3", + "audio/skill/twjuchen2.mp3", + "audio/skill/twjuexing1.mp3", + "audio/skill/twjuexing2.mp3", + "audio/skill/twjuezhu1.mp3", + "audio/skill/twjuezhu2.mp3", + "audio/skill/twjuntun1.mp3", + "audio/skill/twjuntun2.mp3", + "audio/skill/twkaiji1.mp3", + "audio/skill/twkaiji2.mp3", + "audio/skill/twkaizeng1.mp3", + "audio/skill/twkaizeng2.mp3", + "audio/skill/twkujian1.mp3", + "audio/skill/twkujian2.mp3", + "audio/skill/twkujian3.mp3", + "audio/skill/twkunsi1.mp3", + "audio/skill/twkunsi2.mp3", + "audio/skill/twlanjiang.mp3", + "audio/skill/twliexi1.mp3", + "audio/skill/twliexi2.mp3", + "audio/skill/twlijian1.mp3", + "audio/skill/twlijian2.mp3", + "audio/skill/twlingbao1.mp3", + "audio/skill/twlingbao2.mp3", + "audio/skill/twlingfa1.mp3", + "audio/skill/twlingfa2.mp3", + "audio/skill/twluanlve1.mp3", + "audio/skill/twluanlve2.mp3", + "audio/skill/twluannian1.mp3", + "audio/skill/twluannian2.mp3", + "audio/skill/twlvren1.mp3", + "audio/skill/twlvren2.mp3", + "audio/skill/twmiaolve1.mp3", + "audio/skill/twmiaolve2.mp3", + "audio/skill/twmutao1.mp3", + "audio/skill/twmutao2.mp3", + "audio/skill/twmuyue1.mp3", + "audio/skill/twneirao1.mp3", + "audio/skill/twneirao2.mp3", + "audio/skill/twqiaosi1.mp3", + "audio/skill/twqiaosi2.mp3", + "audio/skill/twqingkou1.mp3", + "audio/skill/twqingkou2.mp3", + "audio/skill/twqingren1.mp3", + "audio/skill/twqingren2.mp3", + "audio/skill/twqingtao1.mp3", + "audio/skill/twqingtao2.mp3", + "audio/skill/twqiongji1.mp3", + "audio/skill/twqiongji2.mp3", + "audio/skill/twquanqian1.mp3", + "audio/skill/twquanqian2.mp3", + "audio/skill/twrenchou1.mp3", + "audio/skill/twrenchou2.mp3", + "audio/skill/twrouke1.mp3", + "audio/skill/twrouke2.mp3", + "audio/skill/twruilian1.mp3", + "audio/skill/twruilian2.mp3", + "audio/skill/twshanghe1.mp3", + "audio/skill/twshanghe2.mp3", + "audio/skill/twshenyi1.mp3", + "audio/skill/twshenyi2.mp3", + "audio/skill/twshepan1.mp3", + "audio/skill/twshepan2.mp3", + "audio/skill/twshexhong1.mp3", + "audio/skill/twshexhong2.mp3", + "audio/skill/twshezhong1.mp3", + "audio/skill/twshezhong2.mp3", + "audio/skill/twshigong1.mp3", + "audio/skill/twshigong2.mp3", + "audio/skill/twshoushou1.mp3", + "audio/skill/twshoushou2.mp3", + "audio/skill/twsidai1.mp3", + "audio/skill/twsidai2.mp3", + "audio/skill/twsidao1.mp3", + "audio/skill/twsidao2.mp3", + "audio/skill/twsuizheng1.mp3", + "audio/skill/twsuizheng2.mp3", + "audio/skill/twsuizheng3.mp3", + "audio/skill/twtanfeng1.mp3", + "audio/skill/twtanfeng2.mp3", + "audio/skill/twtianshou1.mp3", + "audio/skill/twtianshou2.mp3", + "audio/skill/twtiaoxin1.mp3", + "audio/skill/twtiaoxin2.mp3", + "audio/skill/twtuidao1.mp3", + "audio/skill/twtuidao2.mp3", + "audio/skill/twwuhun1.mp3", + "audio/skill/twwuhun2.mp3", + "audio/skill/twxiafeng1.mp3", + "audio/skill/twxiafeng2.mp3", + "audio/skill/twxianfeng1.mp3", + "audio/skill/twxianfeng2.mp3", + "audio/skill/twxiawang1.mp3", + "audio/skill/twxiawang2.mp3", + "audio/skill/twxiawei1.mp3", + "audio/skill/twxiawei2.mp3", + "audio/skill/twxiayong1.mp3", + "audio/skill/twxiayong1_tw_yanliang.mp3", + "audio/skill/twxiayong2.mp3", + "audio/skill/twxiayong2_tw_yanliang.mp3", + "audio/skill/twxinghan1.mp3", + "audio/skill/twxinghan2.mp3", + "audio/skill/twxingzhui1.mp3", + "audio/skill/twxingzhui2.mp3", + "audio/skill/twxinshou1.mp3", + "audio/skill/twxinshou2.mp3", + "audio/skill/twxiongjun1.mp3", + "audio/skill/twxiongjun2.mp3", + "audio/skill/twxiongxi1.mp3", + "audio/skill/twxiongxi2.mp3", + "audio/skill/twxiongzheng1.mp3", + "audio/skill/twxiongzheng2.mp3", + "audio/skill/twxuechang1.mp3", + "audio/skill/twxuechang2.mp3", + "audio/skill/twyangming1.mp3", + "audio/skill/twyangming2.mp3", + "audio/skill/twyangshi1.mp3", + "audio/skill/twyangshi2.mp3", + "audio/skill/twyanshi1.mp3", + "audio/skill/twyanshi2.mp3", + "audio/skill/twyanshi3.mp3", + "audio/skill/twyiju1.mp3", + "audio/skill/twyiju2.mp3", + "audio/skill/twyimou1.mp3", + "audio/skill/twyimou2.mp3", + "audio/skill/twyingji1.mp3", + "audio/skill/twyingji2.mp3", + "audio/skill/twyingjia1.mp3", + "audio/skill/twyingjia2.mp3", + "audio/skill/twylyanshi1.mp3", + "audio/skill/twylyanshi2.mp3", + "audio/skill/twyouye1.mp3", + "audio/skill/twyouye2.mp3", + "audio/skill/twyujue1.mp3", + "audio/skill/twyujue2.mp3", + "audio/skill/twyulong1.mp3", + "audio/skill/twyulong2.mp3", + "audio/skill/twzhangwu1.mp3", + "audio/skill/twzhangwu2.mp3", + "audio/skill/twzhengjian1.mp3", + "audio/skill/twzhengjian2.mp3", + "audio/skill/twzhenhu1.mp3", + "audio/skill/twzhenhu2.mp3", + "audio/skill/twzhenxi1.mp3", + "audio/skill/twzhenxi2.mp3", + "audio/skill/twzhian1.mp3", + "audio/skill/twzhian2.mp3", + "audio/skill/twzhiji1.mp3", + "audio/skill/twzhiji2.mp3", + "audio/skill/twzhiqu1.mp3", + "audio/skill/twzhiqu2.mp3", + "audio/skill/twzhongchi1.mp3", + "audio/skill/twzhongchi2.mp3", + "audio/skill/twzhongyi1.mp3", + "audio/skill/twzhongyi2.mp3", + "audio/skill/twzhuidu1.mp3", + "audio/skill/twzhuidu2.mp3", + "audio/skill/vtbguisha1.mp3", + "audio/skill/vtbleyu1.mp3", + "audio/skill/vtbmeiniang1.mp3", + "audio/skill/vtbshanwu1.mp3", + "audio/skill/vtbshuli1.mp3", + "audio/skill/vtbtaoyan1.mp3", + "audio/skill/vtbxianli1.mp3", + "audio/skill/vtbyanli1.mp3", + "audio/skill/vtbyaoli1.mp3", + "audio/skill/vtbyuanli1.mp3", + "audio/skill/waishi1.mp3", + "audio/skill/waishi2.mp3", + "audio/skill/wanggui1.mp3", + "audio/skill/wanggui2.mp3", + "audio/skill/wangjing1.mp3", + "audio/skill/wangjing2.mp3", + "audio/skill/wangong1.mp3", + "audio/skill/wangong2.mp3", + "audio/skill/wangxi1.mp3", + "audio/skill/wangxi2.mp3", + "audio/skill/wangzun1.mp3", + "audio/skill/wangzun2.mp3", + "audio/skill/wanlan1.mp3", + "audio/skill/wanlan2.mp3", + "audio/skill/wanrong1.mp3", + "audio/skill/wanrong2.mp3", + "audio/skill/wansha_boss_lvbu31.mp3", + "audio/skill/wansha_boss_lvbu32.mp3", + "audio/skill/wansha_re_jiaxu1.mp3", + "audio/skill/wansha_re_jiaxu2.mp3", + "audio/skill/wansha_shen_simayi1.mp3", + "audio/skill/wansha_shen_simayi2.mp3", + "audio/skill/wansha1.mp3", + "audio/skill/wansha2.mp3", + "audio/skill/wanwei1.mp3", + "audio/skill/wanwei2.mp3", + "audio/skill/wanyi1.mp3", + "audio/skill/wanyi2.mp3", + "audio/skill/weicheng1.mp3", + "audio/skill/weicheng2.mp3", + "audio/skill/weidi1.mp3", + "audio/skill/weidi2.mp3", + "audio/skill/weifeng1.mp3", + "audio/skill/weifeng2.mp3", + "audio/skill/weijing1.mp3", + "audio/skill/weijing2.mp3", + "audio/skill/weikui1.mp3", + "audio/skill/weikui2.mp3", + "audio/skill/weilie1.mp3", + "audio/skill/weilie2.mp3", + "audio/skill/weimeng1.mp3", + "audio/skill/weimeng2.mp3", + "audio/skill/weimu1.mp3", + "audio/skill/weimu2.mp3", + "audio/skill/weipo1.mp3", + "audio/skill/weipo2.mp3", + "audio/skill/weishu1.mp3", + "audio/skill/weishu2.mp3", + "audio/skill/weiyi1.mp3", + "audio/skill/weiyi2.mp3", + "audio/skill/weizhong1.mp3", + "audio/skill/weizhong2.mp3", + "audio/skill/wendao1.mp3", + "audio/skill/wendao2.mp3", + "audio/skill/wengua1.mp3", + "audio/skill/wengua2.mp3", + "audio/skill/wfyuyan1.mp3", + "audio/skill/wfyuyan2.mp3", + "audio/skill/wlcuorui1.mp3", + "audio/skill/wlcuorui2.mp3", + "audio/skill/wufei1.mp3", + "audio/skill/wufei2.mp3", + "audio/skill/wuhun21.mp3", + "audio/skill/wuhun22.mp3", + "audio/skill/wuji1.mp3", + "audio/skill/wuji2.mp3", + "audio/skill/wulie1.mp3", + "audio/skill/wulie2.mp3", + "audio/skill/wuling1.mp3", + "audio/skill/wuling2.mp3", + "audio/skill/wumou1.mp3", + "audio/skill/wumou2.mp3", + "audio/skill/wuniang1.mp3", + "audio/skill/wuniang2.mp3", + "audio/skill/wuqian1.mp3", + "audio/skill/wuqian2.mp3", + "audio/skill/wuqin1.mp3", + "audio/skill/wuqin2.mp3", + "audio/skill/wurong1.mp3", + "audio/skill/wurong2.mp3", + "audio/skill/wushen1.mp3", + "audio/skill/wushen2.mp3", + "audio/skill/wusheng_dc_jsp_guanyu1.mp3", + "audio/skill/wusheng_dc_jsp_guanyu2.mp3", + "audio/skill/wusheng_guansuo1.mp3", + "audio/skill/wusheng_guansuo2.mp3", + "audio/skill/wusheng_guanzhang1.mp3", + "audio/skill/wusheng_guanzhang2.mp3", + "audio/skill/wusheng_jsp_guanyu1.mp3", + "audio/skill/wusheng_jsp_guanyu2.mp3", + "audio/skill/wusheng_re_guanyu1.mp3", + "audio/skill/wusheng_re_guanyu2.mp3", + "audio/skill/wusheng_re_guanzhang1.mp3", + "audio/skill/wusheng_re_guanzhang2.mp3", + "audio/skill/wusheng1.mp3", + "audio/skill/wusheng2.mp3", + "audio/skill/wushuang_lvlingqi1.mp3", + "audio/skill/wushuang_lvlingqi2.mp3", + "audio/skill/wushuang_re_lvbu1.mp3", + "audio/skill/wushuang_re_lvbu2.mp3", + "audio/skill/wushuang_shen_lvbu1.mp3", + "audio/skill/wushuang_shen_lvbu2.mp3", + "audio/skill/wushuang_wechat_lvbu1.mp3", + "audio/skill/wushuang_wechat_lvbu2.mp3", + "audio/skill/wushuang1.mp3", + "audio/skill/wushuang11.mp3", + "audio/skill/wushuang12.mp3", + "audio/skill/wushuang2.mp3", + "audio/skill/wushuang21.mp3", + "audio/skill/wushuang22.mp3", + "audio/skill/wuxin1.mp3", + "audio/skill/wuxin2.mp3", + "audio/skill/wuyan1.mp3", + "audio/skill/wuyan2.mp3", + "audio/skill/wuyuan1.mp3", + "audio/skill/wuyuan2.mp3", + "audio/skill/wylianji1.mp3", + "audio/skill/wylianji2.mp3", + "audio/skill/xhzhiyan1.mp3", + "audio/skill/xhzhiyan2.mp3", + "audio/skill/xianfu1.mp3", + "audio/skill/xianfu2.mp3", + "audio/skill/xianfu3.mp3", + "audio/skill/xianfu4.mp3", + "audio/skill/xianfu5.mp3", + "audio/skill/xianfu6.mp3", + "audio/skill/xianghai1.mp3", + "audio/skill/xianghai2.mp3", + "audio/skill/xiangle_ol_liushan1.mp3", + "audio/skill/xiangle_ol_liushan2.mp3", + "audio/skill/xiangle_re_liushan1.mp3", + "audio/skill/xiangle_re_liushan2.mp3", + "audio/skill/xiangle1.mp3", + "audio/skill/xiangle2.mp3", + "audio/skill/xiangshu1.mp3", + "audio/skill/xiangshu2.mp3", + "audio/skill/xianjing1.mp3", + "audio/skill/xianjing2.mp3", + "audio/skill/xianshuai1.mp3", + "audio/skill/xianshuai2.mp3", + "audio/skill/xiansi_re_liufeng1.mp3", + "audio/skill/xiansi_re_liufeng2.mp3", + "audio/skill/xiansi1.mp3", + "audio/skill/xiansi2.mp3", + "audio/skill/xiansi21.mp3", + "audio/skill/xiansi22.mp3", + "audio/skill/xiantu1.mp3", + "audio/skill/xiantu2.mp3", + "audio/skill/xianwan1.mp3", + "audio/skill/xianwan2.mp3", + "audio/skill/xianwang1.mp3", + "audio/skill/xianwang2.mp3", + "audio/skill/xianwei1.mp3", + "audio/skill/xianwei2.mp3", + "audio/skill/xianzhen1.mp3", + "audio/skill/xianzhen2.mp3", + "audio/skill/xianzhou_xin_caifuren1.mp3", + "audio/skill/xianzhou_xin_caifuren2.mp3", + "audio/skill/xianzhou1.mp3", + "audio/skill/xianzhou2.mp3", + "audio/skill/xianzhu1.mp3", + "audio/skill/xianzhu2.mp3", + "audio/skill/xiaoguo1.mp3", + "audio/skill/xiaoguo2.mp3", + "audio/skill/xiaoji_re_sunshangxiang1.mp3", + "audio/skill/xiaoji_re_sunshangxiang2.mp3", + "audio/skill/xiaoji_sp_sunshangxiang1.mp3", + "audio/skill/xiaoji_sp_sunshangxiang2.mp3", + "audio/skill/xiaoji1.mp3", + "audio/skill/xiaoji2.mp3", + "audio/skill/xiaoni1.mp3", + "audio/skill/xiaoni2.mp3", + "audio/skill/xiaowu1.mp3", + "audio/skill/xiaowu2.mp3", + "audio/skill/xiaoxi_hansui1.mp3", + "audio/skill/xiaoxi_hansui2.mp3", + "audio/skill/xiaoxi_machao1.mp3", + "audio/skill/xiaoxi_machao2.mp3", + "audio/skill/xiaoxi_pangde1.mp3", + "audio/skill/xiaoxi_pangde2.mp3", + "audio/skill/xiashu1.mp3", + "audio/skill/xiashu2.mp3", + "audio/skill/xibing1.mp3", + "audio/skill/xibing2.mp3", + "audio/skill/xiechan1.mp3", + "audio/skill/xiechan2.mp3", + "audio/skill/xiecui1.mp3", + "audio/skill/xiecui2.mp3", + "audio/skill/xiemu1.mp3", + "audio/skill/xiemu2.mp3", + "audio/skill/xijue_tuxi1.mp3", + "audio/skill/xijue_tuxi2.mp3", + "audio/skill/xijue_xiaoguo1.mp3", + "audio/skill/xijue_xiaoguo2.mp3", + "audio/skill/xijue1.mp3", + "audio/skill/xijue2.mp3", + "audio/skill/xinanjian1.mp3", + "audio/skill/xinanjian2.mp3", + "audio/skill/xinbenxi1.mp3", + "audio/skill/xinbenxi2.mp3", + "audio/skill/xinbuyi1.mp3", + "audio/skill/xinbuyi2.mp3", + "audio/skill/xindanshou1.mp3", + "audio/skill/xindanshou2.mp3", + "audio/skill/xinduodao1.mp3", + "audio/skill/xinduodao2.mp3", + "audio/skill/xinenyuan1.mp3", + "audio/skill/xinenyuan2.mp3", + "audio/skill/xinfencheng_re_liru1.mp3", + "audio/skill/xinfencheng_re_liru2.mp3", + "audio/skill/xinfencheng1.mp3", + "audio/skill/xinfencheng2.mp3", + "audio/skill/xinfu_andong1.mp3", + "audio/skill/xinfu_andong2.mp3", + "audio/skill/xinfu_bijing1.mp3", + "audio/skill/xinfu_bijing2.mp3", + "audio/skill/xinfu_chenghao1.mp3", + "audio/skill/xinfu_chenghao2.mp3", + "audio/skill/xinfu_daigong1.mp3", + "audio/skill/xinfu_daigong2.mp3", + "audio/skill/xinfu_denglou1.mp3", + "audio/skill/xinfu_denglou2.mp3", + "audio/skill/xinfu_dianhu1.mp3", + "audio/skill/xinfu_dianhu2.mp3", + "audio/skill/xinfu_dianhua1.mp3", + "audio/skill/xinfu_dianhua2.mp3", + "audio/skill/xinfu_duanfa1.mp3", + "audio/skill/xinfu_duanfa2.mp3", + "audio/skill/xinfu_falu1.mp3", + "audio/skill/xinfu_falu2.mp3", + "audio/skill/xinfu_fangtong1.mp3", + "audio/skill/xinfu_fangtong2.mp3", + "audio/skill/xinfu_fuhai1.mp3", + "audio/skill/xinfu_fuhai2.mp3", + "audio/skill/xinfu_fujian1.mp3", + "audio/skill/xinfu_fujian2.mp3", + "audio/skill/xinfu_fuyin1.mp3", + "audio/skill/xinfu_fuyin2.mp3", + "audio/skill/xinfu_gongqing_gz_panjun1.mp3", + "audio/skill/xinfu_gongqing_gz_panjun2.mp3", + "audio/skill/xinfu_gongqing1.mp3", + "audio/skill/xinfu_gongqing2.mp3", + "audio/skill/xinfu_guanchao1.mp3", + "audio/skill/xinfu_guanchao2.mp3", + "audio/skill/xinfu_guanwei1.mp3", + "audio/skill/xinfu_guanwei2.mp3", + "audio/skill/xinfu_guhuo2.mp3", + "audio/skill/xinfu_guolun1.mp3", + "audio/skill/xinfu_guolun2.mp3", + "audio/skill/xinfu_jianji1.mp3", + "audio/skill/xinfu_jianji2.mp3", + "audio/skill/xinfu_jianjie1.mp3", + "audio/skill/xinfu_jianjie2.mp3", + "audio/skill/xinfu_jianjie3.mp3", + "audio/skill/xinfu_jijie1.mp3", + "audio/skill/xinfu_jijie2.mp3", + "audio/skill/xinfu_jijun1.mp3", + "audio/skill/xinfu_jijun2.mp3", + "audio/skill/xinfu_jingxie1.mp3", + "audio/skill/xinfu_jingxie2.mp3", + "audio/skill/xinfu_jixu1.mp3", + "audio/skill/xinfu_jixu2.mp3", + "audio/skill/xinfu_jiyuan1.mp3", + "audio/skill/xinfu_jiyuan2.mp3", + "audio/skill/xinfu_kannan1.mp3", + "audio/skill/xinfu_kannan2.mp3", + "audio/skill/xinfu_langxi1.mp3", + "audio/skill/xinfu_langxi2.mp3", + "audio/skill/xinfu_lianpian1.mp3", + "audio/skill/xinfu_lianpian2.mp3", + "audio/skill/xinfu_limu1.mp3", + "audio/skill/xinfu_limu2.mp3", + "audio/skill/xinfu_lingren1.mp3", + "audio/skill/xinfu_lingren2.mp3", + "audio/skill/xinfu_longyuan1.mp3", + "audio/skill/xinfu_longyuan2.mp3", + "audio/skill/xinfu_lveming1.mp3", + "audio/skill/xinfu_lveming2.mp3", + "audio/skill/xinfu_pingcai.mp3", + "audio/skill/xinfu_qiai1.mp3", + "audio/skill/xinfu_qiai2.mp3", + "audio/skill/xinfu_qianchong1.mp3", + "audio/skill/xinfu_qianchong2.mp3", + "audio/skill/xinfu_qianchong3.mp3", + "audio/skill/xinfu_qianxin1.mp3", + "audio/skill/xinfu_qianxin2.mp3", + "audio/skill/xinfu_qiaosi1.mp3", + "audio/skill/xinfu_qiaosi2.mp3", + "audio/skill/xinfu_sanwen1.mp3", + "audio/skill/xinfu_sanwen2.mp3", + "audio/skill/xinfu_shajue1.mp3", + "audio/skill/xinfu_shajue2.mp3", + "audio/skill/xinfu_shangjian1.mp3", + "audio/skill/xinfu_shangjian2.mp3", + "audio/skill/xinfu_sidao1.mp3", + "audio/skill/xinfu_sidao2.mp3", + "audio/skill/xinfu_songsang1.mp3", + "audio/skill/xinfu_songsang2.mp3", + "audio/skill/xinfu_tanbei1.mp3", + "audio/skill/xinfu_tanbei2.mp3", + "audio/skill/xinfu_tunan1.mp3", + "audio/skill/xinfu_tunan2.mp3", + "audio/skill/xinfu_tunjun1.mp3", + "audio/skill/xinfu_tunjun2.mp3", + "audio/skill/xinfu_tushe1.mp3", + "audio/skill/xinfu_tushe2.mp3", + "audio/skill/xinfu_weilu1.mp3", + "audio/skill/xinfu_weilu2.mp3", + "audio/skill/xinfu_wuniang1.mp3", + "audio/skill/xinfu_wuniang2.mp3", + "audio/skill/xinfu_xingluan1.mp3", + "audio/skill/xinfu_xingluan2.mp3", + "audio/skill/xinfu_xingzhao.mp3", + "audio/skill/xinfu_xingzhao2.mp3", + "audio/skill/xinfu_xionghuo1.mp3", + "audio/skill/xinfu_xionghuo2.mp3", + "audio/skill/xinfu_xunxian1.mp3", + "audio/skill/xinfu_xunxian2.mp3", + "audio/skill/xinfu_xushen1.mp3", + "audio/skill/xinfu_xushen2.mp3", + "audio/skill/xinfu_yingshi1.mp3", + "audio/skill/xinfu_yingshi2.mp3", + "audio/skill/xinfu_yinshi1.mp3", + "audio/skill/xinfu_yinshi2.mp3", + "audio/skill/xinfu_yisuan1.mp3", + "audio/skill/xinfu_yisuan2.mp3", + "audio/skill/xinfu_youdi1.mp3", + "audio/skill/xinfu_youdi2.mp3", + "audio/skill/xinfu_zengdao1.mp3", + "audio/skill/xinfu_zengdao2.mp3", + "audio/skill/xinfu_zhanji1.mp3", + "audio/skill/xinfu_zhanji2.mp3", + "audio/skill/xinfu_zhaoxin1.mp3", + "audio/skill/xinfu_zhaoxin2.mp3", + "audio/skill/xinfu_zhennan1.mp3", + "audio/skill/xinfu_zhennan2.mp3", + "audio/skill/xinfu_zhenxing1.mp3", + "audio/skill/xinfu_zhenxing2.mp3", + "audio/skill/xinfu_zhenyi1.mp3", + "audio/skill/xinfu_zhenyi2.mp3", + "audio/skill/xinfu_zuilun1.mp3", + "audio/skill/xinfu_zuilun2.mp3", + "audio/skill/xinfuli1.mp3", + "audio/skill/xinfuli2.mp3", + "audio/skill/xinganlu1.mp3", + "audio/skill/xinganlu2.mp3", + "audio/skill/xingbu1.mp3", + "audio/skill/xingbu2.mp3", + "audio/skill/xingchong1.mp3", + "audio/skill/xingchong2.mp3", + "audio/skill/xinghan1.mp3", + "audio/skill/xinghan2.mp3", + "audio/skill/xingongji1.mp3", + "audio/skill/xingongji2.mp3", + "audio/skill/xingqi1.mp3", + "audio/skill/xingqi2.mp3", + "audio/skill/xingshang1.mp3", + "audio/skill/xingshang2.mp3", + "audio/skill/xingshen1.mp3", + "audio/skill/xingshen2.mp3", + "audio/skill/xingshuai1.mp3", + "audio/skill/xingshuai2.mp3", + "audio/skill/xingtu1.mp3", + "audio/skill/xingtu2.mp3", + "audio/skill/xinguidao1.mp3", + "audio/skill/xinguidao2.mp3", + "audio/skill/xinguixiu1.mp3", + "audio/skill/xinguixiu2.mp3", + "audio/skill/xingwu1.mp3", + "audio/skill/xingwu2.mp3", + "audio/skill/xingxue1.mp3", + "audio/skill/xingxue2.mp3", + "audio/skill/xingzuo1.mp3", + "audio/skill/xingzuo2.mp3", + "audio/skill/xinhuangtian2_re_zhangjiao1.mp3", + "audio/skill/xinhuangtian2_re_zhangjiao2.mp3", + "audio/skill/xinjiangchi1.mp3", + "audio/skill/xinjiangchi2.mp3", + "audio/skill/xinjianying1.mp3", + "audio/skill/xinjianying2.mp3", + "audio/skill/xinjiaojin1.mp3", + "audio/skill/xinjiaojin2.mp3", + "audio/skill/xinjiefan1.mp3", + "audio/skill/xinjiefan2.mp3", + "audio/skill/xinjiewei1.mp3", + "audio/skill/xinjiewei2.mp3", + "audio/skill/xinjingce1.mp3", + "audio/skill/xinjingce2.mp3", + "audio/skill/xinjuece1.mp3", + "audio/skill/xinjuece2.mp3", + "audio/skill/xinjuejing1.mp3", + "audio/skill/xinjuejing2.mp3", + "audio/skill/xinjujian1.mp3", + "audio/skill/xinjujian2.mp3", + "audio/skill/xinjushou1.mp3", + "audio/skill/xinjushou2.mp3", + "audio/skill/xinjyzongshi1.mp3", + "audio/skill/xinjyzongshi2.mp3", + "audio/skill/xinkuangfu1.mp3", + "audio/skill/xinkuangfu2.mp3", + "audio/skill/xinleiji1.mp3", + "audio/skill/xinleiji2.mp3", + "audio/skill/xinlianhuan_ol_pangtong1.mp3", + "audio/skill/xinlianhuan_ol_pangtong2.mp3", + "audio/skill/xinlianhuan1.mp3", + "audio/skill/xinlianhuan2.mp3", + "audio/skill/xinmieji1.mp3", + "audio/skill/xinmieji2.mp3", + "audio/skill/xinniluan1.mp3", + "audio/skill/xinniluan2.mp3", + "audio/skill/xinpaiyi1.mp3", + "audio/skill/xinpaiyi2.mp3", + "audio/skill/xinpingkou1.mp3", + "audio/skill/xinpingkou2.mp3", + "audio/skill/xinpojun1.mp3", + "audio/skill/xinpojun2.mp3", + "audio/skill/xinqiaoshui1.mp3", + "audio/skill/xinqiaoshui2.mp3", + "audio/skill/xinqieting1.mp3", + "audio/skill/xinqieting2.mp3", + "audio/skill/xinqingxi1.mp3", + "audio/skill/xinqingxi2.mp3", + "audio/skill/xinqiuyuan1.mp3", + "audio/skill/xinqiuyuan2.mp3", + "audio/skill/xinquanji1.mp3", + "audio/skill/xinquanji2.mp3", + "audio/skill/xinrende1.mp3", + "audio/skill/xinrende2.mp3", + "audio/skill/xinsheng1.mp3", + "audio/skill/xinsheng2.mp3", + "audio/skill/xinshenxing1.mp3", + "audio/skill/xinshenxing2.mp3", + "audio/skill/xintan1.mp3", + "audio/skill/xintan2.mp3", + "audio/skill/xinwurong1.mp3", + "audio/skill/xinwurong2.mp3", + "audio/skill/xinwurong3.mp3", + "audio/skill/xinwusheng1.mp3", + "audio/skill/xinwusheng2.mp3", + "audio/skill/xinwuyan1.mp3", + "audio/skill/xinwuyan2.mp3", + "audio/skill/xinxuanhuo1.mp3", + "audio/skill/xinxuanhuo2.mp3", + "audio/skill/xinyaoming1.mp3", + "audio/skill/xinyaoming2.mp3", + "audio/skill/xinzenhui1.mp3", + "audio/skill/xinzenhui2.mp3", + "audio/skill/xinzhan1.mp3", + "audio/skill/xinzhan2.mp3", + "audio/skill/xinzhenjun1.mp3", + "audio/skill/xinzhenjun2.mp3", + "audio/skill/xinzhiyan1.mp3", + "audio/skill/xinzhiyan2.mp3", + "audio/skill/xinzhuikong1.mp3", + "audio/skill/xinzhuikong2.mp3", + "audio/skill/xinzili1.mp3", + "audio/skill/xinzili2.mp3", + "audio/skill/xinzongxuan1.mp3", + "audio/skill/xinzongxuan2.mp3", + "audio/skill/xiongmang1.mp3", + "audio/skill/xiongmang2.mp3", + "audio/skill/xiongrao1.mp3", + "audio/skill/xiongrao2.mp3", + "audio/skill/xiongshu1.mp3", + "audio/skill/xiongshu2.mp3", + "audio/skill/xiongsuan1.mp3", + "audio/skill/xiongsuan2.mp3", + "audio/skill/xiongyi1.mp3", + "audio/skill/xiongyi2.mp3", + "audio/skill/xiongzhi1.mp3", + "audio/skill/xiongzhi2.mp3", + "audio/skill/xiuluo1.mp3", + "audio/skill/xiuluo2.mp3", + "audio/skill/xiusheng1.mp3", + "audio/skill/xiusheng2.mp3", + "audio/skill/xixiu1.mp3", + "audio/skill/xixiu2.mp3", + "audio/skill/xiyan1.mp3", + "audio/skill/xiyan2.mp3", + "audio/skill/xiying1.mp3", + "audio/skill/xiying2.mp3", + "audio/skill/xizhen1.mp3", + "audio/skill/xizhen2.mp3", + "audio/skill/xjshijian1.mp3", + "audio/skill/xjshijian2.mp3", + "audio/skill/xpchijie1.mp3", + "audio/skill/xpchijie2.mp3", + "audio/skill/xsqianxin1.mp3", + "audio/skill/xsqianxin2.mp3", + "audio/skill/xuanbei1.mp3", + "audio/skill/xuanbei2.mp3", + "audio/skill/xuancun1.mp3", + "audio/skill/xuancun2.mp3", + "audio/skill/xuanfeng_boss_lvbu31.mp3", + "audio/skill/xuanfeng_boss_lvbu32.mp3", + "audio/skill/xuanfeng_re_heqi1.mp3", + "audio/skill/xuanfeng_re_heqi2.mp3", + "audio/skill/xuanfeng_re_lingtong1.mp3", + "audio/skill/xuanfeng_re_lingtong2.mp3", + "audio/skill/xuanfeng_xin_lingtong1.mp3", + "audio/skill/xuanfeng_xin_lingtong2.mp3", + "audio/skill/xuanfeng1.mp3", + "audio/skill/xuanfeng2.mp3", + "audio/skill/xuanhuo1.mp3", + "audio/skill/xuanhuo2.mp3", + "audio/skill/xuanlve1.mp3", + "audio/skill/xuanlve2.mp3", + "audio/skill/xuanmu1.mp3", + "audio/skill/xuanmu2.mp3", + "audio/skill/xueji1.mp3", + "audio/skill/xueji2.mp3", + "audio/skill/xuelunyang.mp3", + "audio/skill/xuewei1.mp3", + "audio/skill/xuewei2.mp3", + "audio/skill/xueyi1.mp3", + "audio/skill/xueyi2.mp3", + "audio/skill/xuezhao1.mp3", + "audio/skill/xuezhao2.mp3", + "audio/skill/xunde1.mp3", + "audio/skill/xunde2.mp3", + "audio/skill/xunli1.mp3", + "audio/skill/xunli2.mp3", + "audio/skill/xunshi1.mp3", + "audio/skill/xunshi2.mp3", + "audio/skill/xunxun1.mp3", + "audio/skill/xunxun2.mp3", + "audio/skill/xunyi1.mp3", + "audio/skill/xunyi2.mp3", + "audio/skill/xunzhi1.mp3", + "audio/skill/xunzhi2.mp3", + "audio/skill/xushen1.mp3", + "audio/skill/xushen2.mp3", + "audio/skill/xutuhuanjin.mp3", + "audio/skill/xuxie1.mp3", + "audio/skill/xuxie2.mp3", + "audio/skill/xz_xunxun1.mp3", + "audio/skill/xz_xunxun2.mp3", + "audio/skill/yachai1.mp3", + "audio/skill/yachai2.mp3", + "audio/skill/yaner1.mp3", + "audio/skill/yaner2.mp3", + "audio/skill/yangjie1.mp3", + "audio/skill/yangjie2.mp3", + "audio/skill/yangkuang1.mp3", + "audio/skill/yangkuang2.mp3", + "audio/skill/yangzhong1.mp3", + "audio/skill/yangzhong2.mp3", + "audio/skill/yanhuo1.mp3", + "audio/skill/yanhuo2.mp3", + "audio/skill/yanjiao1.mp3", + "audio/skill/yanjiao2.mp3", + "audio/skill/yanru1.mp3", + "audio/skill/yanru2.mp3", + "audio/skill/yanxi1.mp3", + "audio/skill/yanxi2.mp3", + "audio/skill/yanxiao1.mp3", + "audio/skill/yanxiao2.mp3", + "audio/skill/yanyu1.mp3", + "audio/skill/yanyu2.mp3", + "audio/skill/yanzheng1.mp3", + "audio/skill/yanzheng2.mp3", + "audio/skill/yanzhu1.mp3", + "audio/skill/yanzhu2.mp3", + "audio/skill/yaoming1.mp3", + "audio/skill/yaoming2.mp3", + "audio/skill/yaopei1.mp3", + "audio/skill/yaopei2.mp3", + "audio/skill/yaowu1.mp3", + "audio/skill/yaowu2.mp3", + "audio/skill/yashi1.mp3", + "audio/skill/yashi2.mp3", + "audio/skill/yawang1.mp3", + "audio/skill/yawang2.mp3", + "audio/skill/ybzhuiji1.mp3", + "audio/skill/ybzhuiji2.mp3", + "audio/skill/yechou1.mp3", + "audio/skill/yechou2.mp3", + "audio/skill/yeyan1.mp3", + "audio/skill/yeyan2.mp3", + "audio/skill/yeyan3.mp3", + "audio/skill/yicheng1.mp3", + "audio/skill/yicheng2.mp3", + "audio/skill/yichong1.mp3", + "audio/skill/yichong2.mp3", + "audio/skill/yicong1.mp3", + "audio/skill/yicong2.mp3", + "audio/skill/yidian1.mp3", + "audio/skill/yidian2.mp3", + "audio/skill/yidu1.mp3", + "audio/skill/yidu2.mp3", + "audio/skill/yifa1.mp3", + "audio/skill/yifa2.mp3", + "audio/skill/yigui1.mp3", + "audio/skill/yigui2.mp3", + "audio/skill/yiji1.mp3", + "audio/skill/yiji2.mp3", + "audio/skill/yijiao1.mp3", + "audio/skill/yijiao2.mp3", + "audio/skill/yijie1.mp3", + "audio/skill/yijie2.mp3", + "audio/skill/yijin1.mp3", + "audio/skill/yijin2.mp3", + "audio/skill/yijin3.mp3", + "audio/skill/yijue1.mp3", + "audio/skill/yijue2.mp3", + "audio/skill/yilie1.mp3", + "audio/skill/yilie2.mp3", + "audio/skill/yimie1.mp3", + "audio/skill/yimie2.mp3", + "audio/skill/yinbing1.mp3", + "audio/skill/yinbing2.mp3", + "audio/skill/yingba1.mp3", + "audio/skill/yingba2.mp3", + "audio/skill/yingbin1.mp3", + "audio/skill/yingbin2.mp3", + "audio/skill/yingbing1.mp3", + "audio/skill/yingbing2.mp3", + "audio/skill/yingfeng1.mp3", + "audio/skill/yingfeng2.mp3", + "audio/skill/yinghun_ol_sunjian1.mp3", + "audio/skill/yinghun_ol_sunjian2.mp3", + "audio/skill/yinghun_re_sunben1.mp3", + "audio/skill/yinghun_re_sunben2.mp3", + "audio/skill/yinghun_re_sunce1.mp3", + "audio/skill/yinghun_re_sunce2.mp3", + "audio/skill/yinghun_re_sunjian1.mp3", + "audio/skill/yinghun_re_sunjian2.mp3", + "audio/skill/yinghun_sb_sunce1.mp3", + "audio/skill/yinghun_sb_sunce2.mp3", + "audio/skill/yinghun_sunce1.mp3", + "audio/skill/yinghun_sunce2.mp3", + "audio/skill/yinghun_sunjian1.mp3", + "audio/skill/yinghun_sunjian2.mp3", + "audio/skill/yinghun1.mp3", + "audio/skill/yinghun2.mp3", + "audio/skill/yingyang1.mp3", + "audio/skill/yingyang2.mp3", + "audio/skill/yingyuan1.mp3", + "audio/skill/yingyuan2.mp3", + "audio/skill/yingzi1.mp3", + "audio/skill/yingzi2.mp3", + "audio/skill/yinju1.mp3", + "audio/skill/yinju2.mp3", + "audio/skill/yinlang1.mp3", + "audio/skill/yinlang2.mp3", + "audio/skill/yinli1.mp3", + "audio/skill/yinli2.mp3", + "audio/skill/yinyi1.mp3", + "audio/skill/yinyi2.mp3", + "audio/skill/yirang_re_taoqian1.mp3", + "audio/skill/yirang_re_taoqian2.mp3", + "audio/skill/yirang1.mp3", + "audio/skill/yirang2.mp3", + "audio/skill/yise1.mp3", + "audio/skill/yise2.mp3", + "audio/skill/yishe1.mp3", + "audio/skill/yishe2.mp3", + "audio/skill/yitian.mp3", + "audio/skill/yixiang_re_taoqian1.mp3", + "audio/skill/yixiang_re_taoqian2.mp3", + "audio/skill/yixiang1.mp3", + "audio/skill/yixiang2.mp3", + "audio/skill/yiyong1.mp3", + "audio/skill/yiyong2.mp3", + "audio/skill/yizan_respond_shan1.mp3", + "audio/skill/yizan_respond_shan2.mp3", + "audio/skill/yizhao1.mp3", + "audio/skill/yizhao2.mp3", + "audio/skill/yizheng1.mp3", + "audio/skill/yizheng2.mp3", + "audio/skill/yizhi1.mp3", + "audio/skill/yizhi2.mp3", + "audio/skill/yizhong1.mp3", + "audio/skill/yizhong2.mp3", + "audio/skill/yizhu1.mp3", + "audio/skill/yizhu2.mp3", + "audio/skill/yizu1.mp3", + "audio/skill/yizu2.mp3", + "audio/skill/yongdi_xinping1.mp3", + "audio/skill/yongdi_xinping2.mp3", + "audio/skill/yongdi1.mp3", + "audio/skill/yongdi2.mp3", + "audio/skill/yongjin_xin_lingtong1.mp3", + "audio/skill/yongjin_xin_lingtong2.mp3", + "audio/skill/yongjin1.mp3", + "audio/skill/yongjin2.mp3", + "audio/skill/yongjue1.mp3", + "audio/skill/yongjue2.mp3", + "audio/skill/yonglve1.mp3", + "audio/skill/yonglve2.mp3", + "audio/skill/yongsi1.mp3", + "audio/skill/yongsi2.mp3", + "audio/skill/youdi1.mp3", + "audio/skill/youdi2.mp3", + "audio/skill/youlong1.mp3", + "audio/skill/youlong2.mp3", + "audio/skill/youxu1.mp3", + "audio/skill/youxu2.mp3", + "audio/skill/youyan1.mp3", + "audio/skill/youyan2.mp3", + "audio/skill/youyi1.mp3", + "audio/skill/youyi2.mp3", + "audio/skill/yuanchou1.mp3", + "audio/skill/yuanchou2.mp3", + "audio/skill/yuanhu1.mp3", + "audio/skill/yuanhu2.mp3", + "audio/skill/yuanhu3.mp3", + "audio/skill/yuanlve1.mp3", + "audio/skill/yuanlve2.mp3", + "audio/skill/yuanqing1.mp3", + "audio/skill/yuanqing2.mp3", + "audio/skill/yuanyu1.mp3", + "audio/skill/yuanyu2.mp3", + "audio/skill/yuanzi1.mp3", + "audio/skill/yuanzi2.mp3", + "audio/skill/yuce_re_manchong1.mp3", + "audio/skill/yuce_re_manchong2.mp3", + "audio/skill/yuce1.mp3", + "audio/skill/yuce2.mp3", + "audio/skill/yuehun1.mp3", + "audio/skill/yuehun2.mp3", + "audio/skill/yuejian1.mp3", + "audio/skill/yuejian2.mp3", + "audio/skill/yufeng1.mp3", + "audio/skill/yufeng2.mp3", + "audio/skill/yuheng1.mp3", + "audio/skill/yuheng2.mp3", + "audio/skill/yuhua1.mp3", + "audio/skill/yuhua2.mp3", + "audio/skill/yui_jiang1.mp3", + "audio/skill/yui_jiang2.mp3", + "audio/skill/yui_lieyin1.mp3", + "audio/skill/yui_lieyin2.mp3", + "audio/skill/yui_takaramono1.mp3", + "audio/skill/yui_takaramono2.mp3", + "audio/skill/yujue1.mp3", + "audio/skill/yujue2.mp3", + "audio/skill/yuqi1.mp3", + "audio/skill/yuqi2.mp3", + "audio/skill/yuri_wangxi1.mp3", + "audio/skill/yuri_wangxi2.mp3", + "audio/skill/yuri_xingdong_gain1.mp3", + "audio/skill/yuri_xingdong_gain2.mp3", + "audio/skill/yuri_xingdong1.mp3", + "audio/skill/yuri_xingdong2.mp3", + "audio/skill/yuri_xingdong3.mp3", + "audio/skill/yusui1.mp3", + "audio/skill/yusui2.mp3", + "audio/skill/yuxiang.mp3", + "audio/skill/yuxu1.mp3", + "audio/skill/yuxu2.mp3", + "audio/skill/yuyan1.mp3", + "audio/skill/yuyan2.mp3", + "audio/skill/yuyun1.mp3", + "audio/skill/yuyun2.mp3", + "audio/skill/yuzhang1.mp3", + "audio/skill/yuzhang2.mp3", + "audio/skill/zaiqi1.mp3", + "audio/skill/zaiqi2.mp3", + "audio/skill/zaoli1.mp3", + "audio/skill/zaoli2.mp3", + "audio/skill/zaoxian_re_dengai1.mp3", + "audio/skill/zaoxian_re_dengai2.mp3", + "audio/skill/zaoxian1.mp3", + "audio/skill/zaoxian2.mp3", + "audio/skill/zaoyun1.mp3", + "audio/skill/zaoyun2.mp3", + "audio/skill/zengou1.mp3", + "audio/skill/zengou2.mp3", + "audio/skill/zfengshi1.mp3", + "audio/skill/zfengshi2.mp3", + "audio/skill/zhafu1.mp3", + "audio/skill/zhafu2.mp3", + "audio/skill/zhangba_skill.mp3", + "audio/skill/zhangming1.mp3", + "audio/skill/zhangming2.mp3", + "audio/skill/zhangu1.mp3", + "audio/skill/zhangu2.mp3", + "audio/skill/zhangwu1.mp3", + "audio/skill/zhangwu2.mp3", + "audio/skill/zhanjue1.mp3", + "audio/skill/zhanjue2.mp3", + "audio/skill/zhanshen1.mp3", + "audio/skill/zhanshen2.mp3", + "audio/skill/zhanwan1.mp3", + "audio/skill/zhanwan2.mp3", + "audio/skill/zhanyanliangzhuwenchou.mp3", + "audio/skill/zhanyi1.mp3", + "audio/skill/zhanyi2.mp3", + "audio/skill/zhanyuan1.mp3", + "audio/skill/zhanyuan2.mp3", + "audio/skill/zhaofu1.mp3", + "audio/skill/zhaofu2.mp3", + "audio/skill/zhaohan1.mp3", + "audio/skill/zhaohan2.mp3", + "audio/skill/zhaohuo_re_taoqian1.mp3", + "audio/skill/zhaohuo_re_taoqian2.mp3", + "audio/skill/zhaohuo1.mp3", + "audio/skill/zhaohuo2.mp3", + "audio/skill/zhaolie1.mp3", + "audio/skill/zhaolie2.mp3", + "audio/skill/zhaoran1.mp3", + "audio/skill/zhaoran2.mp3", + "audio/skill/zhaosong1.mp3", + "audio/skill/zhaosong2.mp3", + "audio/skill/zhaotao1.mp3", + "audio/skill/zhaotao2.mp3", + "audio/skill/zhaxiang1.mp3", + "audio/skill/zhaxiang2.mp3", + "audio/skill/zhefu1.mp3", + "audio/skill/zhefu2.mp3", + "audio/skill/zhendu1.mp3", + "audio/skill/zhendu2.mp3", + "audio/skill/zhengbi1.mp3", + "audio/skill/zhengbi2.mp3", + "audio/skill/zhengding1.mp3", + "audio/skill/zhengding2.mp3", + "audio/skill/zhenge1.mp3", + "audio/skill/zhenge2.mp3", + "audio/skill/zhengjian1.mp3", + "audio/skill/zhengjian2.mp3", + "audio/skill/zhengjing_boom.mp3", + "audio/skill/zhengjing_click.mp3", + "audio/skill/zhengjing_finish.mp3", + "audio/skill/zhengjing_guanju.mp3", + "audio/skill/zhengjing1.mp3", + "audio/skill/zhengjing2.mp3", + "audio/skill/zhengnan1.mp3", + "audio/skill/zhengnan2.mp3", + "audio/skill/zhengqing1.mp3", + "audio/skill/zhengqing2.mp3", + "audio/skill/zhenlie_re_wangyi1.mp3", + "audio/skill/zhenlie_re_wangyi2.mp3", + "audio/skill/zhenlie1.mp3", + "audio/skill/zhenlie2.mp3", + "audio/skill/zhenshan1.mp3", + "audio/skill/zhenshan2.mp3", + "audio/skill/zhente1.mp3", + "audio/skill/zhente2.mp3", + "audio/skill/zhenwei_re_wenpin1.mp3", + "audio/skill/zhenwei_re_wenpin2.mp3", + "audio/skill/zhenwei1.mp3", + "audio/skill/zhenwei2.mp3", + "audio/skill/zhiba2_re_sunben1.mp3", + "audio/skill/zhiba2_re_sunben2.mp3", + "audio/skill/zhiba21.mp3", + "audio/skill/zhiba22.mp3", + "audio/skill/zhibian1.mp3", + "audio/skill/zhibian2.mp3", + "audio/skill/zhichi_re_chengong1.mp3", + "audio/skill/zhichi_re_chengong2.mp3", + "audio/skill/zhichi1.mp3", + "audio/skill/zhichi2.mp3", + "audio/skill/zhidao1.mp3", + "audio/skill/zhidao2.mp3", + "audio/skill/zhige1.mp3", + "audio/skill/zhige2.mp3", + "audio/skill/zhiheng_gz_jun_sunquan1.mp3", + "audio/skill/zhiheng_gz_jun_sunquan2.mp3", + "audio/skill/zhiheng1.mp3", + "audio/skill/zhiheng2.mp3", + "audio/skill/zhiji_re_jiangwei1.mp3", + "audio/skill/zhiji_re_jiangwei2.mp3", + "audio/skill/zhiji1.mp3", + "audio/skill/zhiji2.mp3", + "audio/skill/zhijian1.mp3", + "audio/skill/zhijian2.mp3", + "audio/skill/zhilve1.mp3", + "audio/skill/zhilve2.mp3", + "audio/skill/zhiman_guansuo1.mp3", + "audio/skill/zhiman_guansuo2.mp3", + "audio/skill/zhiman_re_masu1.mp3", + "audio/skill/zhiman_re_masu2.mp3", + "audio/skill/zhiman1.mp3", + "audio/skill/zhiman2.mp3", + "audio/skill/zhimeng1.mp3", + "audio/skill/zhimeng2.mp3", + "audio/skill/zhiming1.mp3", + "audio/skill/zhiming2.mp3", + "audio/skill/zhiren1.mp3", + "audio/skill/zhiren2.mp3", + "audio/skill/zhiri1.mp3", + "audio/skill/zhiri2.mp3", + "audio/skill/zhishi1.mp3", + "audio/skill/zhishi2.mp3", + "audio/skill/zhiwei1.mp3", + "audio/skill/zhiwei2.mp3", + "audio/skill/zhiyan_gexuan1.mp3", + "audio/skill/zhiyan_re_yufan1.mp3", + "audio/skill/zhiyan_re_yufan2.mp3", + "audio/skill/zhiyan_xin_yufan1.mp3", + "audio/skill/zhiyan_xin_yufan2.mp3", + "audio/skill/zhiyan1.mp3", + "audio/skill/zhiyan2.mp3", + "audio/skill/zhiyi1.mp3", + "audio/skill/zhiyi2.mp3", + "audio/skill/zhiyu1.mp3", + "audio/skill/zhiyu2.mp3", + "audio/skill/zhongjian1.mp3", + "audio/skill/zhongjian2.mp3", + "audio/skill/zhongjie1.mp3", + "audio/skill/zhongjie2.mp3", + "audio/skill/zhongyi1.mp3", + "audio/skill/zhongyi2.mp3", + "audio/skill/zhongyong1.mp3", + "audio/skill/zhongyong2.mp3", + "audio/skill/zhongyun1.mp3", + "audio/skill/zhongyun2.mp3", + "audio/skill/zhongzuo1.mp3", + "audio/skill/zhongzuo2.mp3", + "audio/skill/zhoufu1.mp3", + "audio/skill/zhoufu2.mp3", + "audio/skill/zhoulin1.mp3", + "audio/skill/zhoulin2.mp3", + "audio/skill/zhouxian1.mp3", + "audio/skill/zhouxian2.mp3", + "audio/skill/zhouxuan1.mp3", + "audio/skill/zhouxuan2.mp3", + "audio/skill/zhuandui1.mp3", + "audio/skill/zhuandui2.mp3", + "audio/skill/zhuangdan1.mp3", + "audio/skill/zhuangdan2.mp3", + "audio/skill/zhuangpo1.mp3", + "audio/skill/zhuangpo2.mp3", + "audio/skill/zhuangrong1.mp3", + "audio/skill/zhuangrong2.mp3", + "audio/skill/zhuangshu1.mp3", + "audio/skill/zhuangshu2.mp3", + "audio/skill/zhuge_skill.mp3", + "audio/skill/zhuhai_gz_re_xushu1.mp3", + "audio/skill/zhuhai_gz_re_xushu2.mp3", + "audio/skill/zhuhai1.mp3", + "audio/skill/zhuhai2.mp3", + "audio/skill/zhuide1.mp3", + "audio/skill/zhuide2.mp3", + "audio/skill/zhuihuan1.mp3", + "audio/skill/zhuihuan2.mp3", + "audio/skill/zhuikong1.mp3", + "audio/skill/zhuikong2.mp3", + "audio/skill/zhuitao1.mp3", + "audio/skill/zhuitao2.mp3", + "audio/skill/zhuiyi_re_bulianshi1.mp3", + "audio/skill/zhuiyi_re_bulianshi2.mp3", + "audio/skill/zhuiyi1.mp3", + "audio/skill/zhuiyi2.mp3", + "audio/skill/zhujian1.mp3", + "audio/skill/zhujian2.mp3", + "audio/skill/zhukou1.mp3", + "audio/skill/zhukou2.mp3", + "audio/skill/zhuning1.mp3", + "audio/skill/zhuning2.mp3", + "audio/skill/zhuosheng1.mp3", + "audio/skill/zhuosheng2.mp3", + "audio/skill/zhuque_skill.mp3", + "audio/skill/zhushi1.mp3", + "audio/skill/zhushi2.mp3", + "audio/skill/zhuwei1.mp3", + "audio/skill/zhuwei2.mp3", + "audio/skill/zifu1.mp3", + "audio/skill/zifu2.mp3", + "audio/skill/zili_re_zhonghui1.mp3", + "audio/skill/zili_re_zhonghui2.mp3", + "audio/skill/zili1.mp3", + "audio/skill/zili2.mp3", + "audio/skill/ziliang1.mp3", + "audio/skill/ziliang2.mp3", + "audio/skill/ziqu1.mp3", + "audio/skill/ziqu2.mp3", + "audio/skill/zishou_re_liubiao1.mp3", + "audio/skill/zishou_re_liubiao2.mp3", + "audio/skill/zishou1.mp3", + "audio/skill/zishou2.mp3", + "audio/skill/zishu1.mp3", + "audio/skill/zishu2.mp3", + "audio/skill/ziyuan1.mp3", + "audio/skill/ziyuan2.mp3", + "audio/skill/zjjuxiang1.mp3", + "audio/skill/zjjuxiang2.mp3", + "audio/skill/zlhuji1.mp3", + "audio/skill/zlhuji2.mp3", + "audio/skill/zlshoufu1.mp3", + "audio/skill/zlshoufu2.mp3", + "audio/skill/zniaoxiang1.mp3", + "audio/skill/zniaoxiang2.mp3", + "audio/skill/zongfan1.mp3", + "audio/skill/zongfan2.mp3", + "audio/skill/zonghuo.mp3", + "audio/skill/zongkui_tw_beimihu1.mp3", + "audio/skill/zongkui_tw_beimihu2.mp3", + "audio/skill/zongkui1.mp3", + "audio/skill/zongkui2.mp3", + "audio/skill/zongshi1.mp3", + "audio/skill/zongshi2.mp3", + "audio/skill/zongxuan1.mp3", + "audio/skill/zongxuan2.mp3", + "audio/skill/zongzuo1.mp3", + "audio/skill/zongzuo2.mp3", + "audio/skill/zuici1.mp3", + "audio/skill/zuici2.mp3", + "audio/skill/zuixiang.mp3", + "audio/skill/zunwei1.mp3", + "audio/skill/zunwei2.mp3", + "audio/skill/zuoding_re_zhongyao1.mp3", + "audio/skill/zuoding_re_zhongyao2.mp3", + "audio/skill/zuoding1.mp3", + "audio/skill/zuoding2.mp3", + "audio/skill/zuoxing1.mp3", + "audio/skill/zuoxing2.mp3", + "audio/skill/zyqiao1.mp3", + "audio/skill/zyqiao2.mp3", + /*skill audio end*/ + + /*voice begin*/ + "audio/voice/male/0.mp3", + "audio/voice/male/1.mp3", + "audio/voice/male/2.mp3", + "audio/voice/male/3.mp3", + "audio/voice/male/4.mp3", + "audio/voice/male/5.mp3", + "audio/voice/male/6.mp3", + "audio/voice/male/7.mp3", + "audio/voice/male/8.mp3", + "audio/voice/male/9.mp3", + "audio/voice/male/10.mp3", + "audio/voice/male/11.mp3", + "audio/voice/male/12.mp3", + "audio/voice/male/13.mp3", + "audio/voice/male/14.mp3", + "audio/voice/male/15.mp3", + "audio/voice/male/16.mp3", + "audio/voice/male/17.mp3", + "audio/voice/male/18.mp3", + "audio/voice/male/19.mp3", + "audio/voice/male/20.mp3", + "audio/voice/male/21.mp3", + "audio/voice/male/22.mp3", + "audio/voice/female/0.mp3", + "audio/voice/female/1.mp3", + "audio/voice/female/2.mp3", + "audio/voice/female/3.mp3", + "audio/voice/female/4.mp3", + "audio/voice/female/5.mp3", + "audio/voice/female/6.mp3", + "audio/voice/female/7.mp3", + "audio/voice/female/8.mp3", + "audio/voice/female/9.mp3", + "audio/voice/female/10.mp3", + "audio/voice/female/11.mp3", + "audio/voice/female/12.mp3", + "audio/voice/female/13.mp3", + "audio/voice/female/14.mp3", + "audio/voice/female/15.mp3", + "audio/voice/female/16.mp3", + "audio/voice/female/17.mp3", + "audio/voice/female/18.mp3", + "audio/voice/female/19.mp3", + "audio/voice/female/20.mp3", + "audio/voice/female/21.mp3", + "audio/voice/female/22.mp3", + /*voice end*/ + /*audio end*/ + + "font/huangcao.woff2", + "font/shousha.woff2", + "font/xiaozhuan.woff2", + "font/xingkai.woff2", + "font/xinwei.woff2", + "font/yuanli.woff2", + + /*background image begin*/ + "image/background/beipan_bg.jpg", + "image/background/heaven_bg.jpg", + "image/background/huangtian_bg.jpg", + "image/background/key_bg.jpg", + "image/background/kyoani_bg.jpg", + "image/background/lanting_bg.jpg", + "image/background/lingju_bg.jpg", + "image/background/noname_bg.jpg", + "image/background/ol_bg.jpg", + "image/background/oltianhou_club_bg.jpg", + "image/background/oltianhou_diamond_bg.jpg", + "image/background/oltianhou_heart_bg.jpg", + "image/background/oltianhou_spade_bg.jpg", + "image/background/planetarian_bg.jpg", + "image/background/sanying_bg.jpg", + "image/background/september_bg.jpg", + "image/background/shengshi_bg.jpg", + "image/background/taoyuan_bg.jpg", + "image/background/wangshi_bg.jpg", + "image/background/wuming_bg.jpg", + "image/background/xiaowu_bg.jpg", + "image/background/xinsha_bg.jpg", + "image/background/xiongxin_bg.jpg", + "image/background/yinxiang_bg.jpg", + "image/background/zhanhuo_bg.jpg", + "image/background/zhanyun_bg.jpg", + "image/background/zhulin_bg.jpg", + /*background image end*/ + + /*card image begin*/ + "image/card/bagua.png", + "image/card/baihupifeng.png", + "image/card/baishouzhihu.png", + "image/card/baiyidujiang.png", + "image/card/baiyin.png", + "image/card/bingliang.png", + "image/card/binglinchengxia.png", + "image/card/binglinchengxiax.png", + "image/card/bingpotong.png", + "image/card/bintieshuangji.png", + "image/card/cangchizhibi.png", + "image/card/caochuan.png", + "image/card/caochuanjiejian.png", + "image/card/caomu.png", + "image/card/caoyao.png", + "image/card/cardtempname_bg.png", + "image/card/changandajian_equip1.png", + "image/card/charge.png", + "image/card/cheliji_feilunzhanyu.png", + "image/card/cheliji_sichengliangyu.png", + "image/card/cheliji_tiejixuanyu.png", + "image/card/chenghuodajie.png", + "image/card/chenhuodajie.png", + "image/card/chiling.png", + "image/card/chilongya.png", + "image/card/chitu.png", + "image/card/chiyuxi.png", + "image/card/chuansongmen.png", + "image/card/chunbing.png", + "image/card/chuqibuyi.png", + "image/card/cisha.png", + "image/card/cixiong.png", + "image/card/cooperation_damage.png", + "image/card/dagongche.png", + "image/card/daihuofenglun.png", + "image/card/dawan.png", + "image/card/db_atk1.jpg", + "image/card/db_atk1_出阵迎战.jpg", + "image/card/db_atk1_反抗.jpg", + "image/card/db_atk1_固守城池.jpg", + "image/card/db_atk2.jpg", + "image/card/db_atk2_拱卫中军.jpg", + "image/card/db_atk2_归顺.jpg", + "image/card/db_atk2_突出重围.jpg", + "image/card/db_def1.jpg", + "image/card/db_def1_围城断粮.jpg", + "image/card/db_def1_镇压.jpg", + "image/card/db_def1_直取敌营.jpg", + "image/card/db_def2.jpg", + "image/card/db_def2_安抚.jpg", + "image/card/db_def2_擂鼓进军.jpg", + "image/card/db_def2_扰阵疲敌.jpg", + "image/card/diaobingqianjiang.png", + "image/card/diaohulishan.png", + "image/card/dilu.png", + "image/card/dinglanyemingzhu.png", + "image/card/dinvxuanshuang.png", + "image/card/diqi.png", + "image/card/donghuangzhong.png", + "image/card/dongzhuxianji.png", + "image/card/du.png", + "image/card/duanjian.png", + "image/card/dunpaigedang.png", + "image/card/dz_mantianguohai.png", + "image/card/expandedSlots.png", + "image/card/fangtian.png", + "image/card/feibiao.png", + "image/card/feilongduofeng.png", + "image/card/fengchu_card.png", + "image/card/fengxueren.png", + "image/card/fengyinzhidan.png", + "image/card/fudichouxin.png", + "image/card/fulei.png", + "image/card/fuxiqin.png", + "image/card/geanguanhuo.png", + "image/card/gongshoujianbei.png", + "image/card/gouhunluo.png", + "image/card/group_jin.png", + "image/card/group_key.png", + "image/card/group_qun.png", + "image/card/group_shen.png", + "image/card/group_shu.png", + "image/card/group_unknown.png", + "image/card/group_wei.png", + "image/card/group_western.png", + "image/card/group_wu.png", + "image/card/group_ye.png", + "image/card/guaguliaodu.png", + "image/card/guangshatianyi.png", + "image/card/guanshi.png", + "image/card/guding.png", + "image/card/gudonggeng.png", + "image/card/guilingzhitao.png", + "image/card/guisheqi.png", + "image/card/guiyanfadao.png", + "image/card/guiyoujie.png", + "image/card/guohe.png", + "image/card/gw_aerdeyin.jpg", + "image/card/gw_ansha.jpg", + "image/card/gw_aozuzhilei.jpg", + "image/card/gw_baishuang.jpg", + "image/card/gw_baobaoshu.jpg", + "image/card/gw_baoxueyaoshui.jpg", + "image/card/gw_birinongwu.jpg", + "image/card/gw_butianshu.jpg", + "image/card/gw_chongci.jpg", + "image/card/gw_ciguhanshuang.jpg", + "image/card/gw_dieyi.png", + "image/card/gw_dudayuanshuai1.jpg", + "image/card/gw_dudayuanshuai2.jpg", + "image/card/gw_fuyuan.jpg", + "image/card/gw_ganhan.jpg", + "image/card/gw_guaiwuchaoxue.jpg", + "image/card/gw_huangjiashenpan.jpg", + "image/card/gw_hudiewu.jpg", + "image/card/gw_kunenfayin.jpg", + "image/card/gw_lang.jpg", + "image/card/gw_leizhoushu.jpg", + "image/card/gw_niuquzhijing.jpg", + "image/card/gw_nuhaifengbao.jpg", + "image/card/gw_poxiao.jpg", + "image/card/gw_qinpendayu.jpg", + "image/card/gw_shanbengshu.jpg", + "image/card/gw_shizizhaohuan.jpg", + "image/card/gw_tongdi.jpg", + "image/card/gw_tunshi.jpg", + "image/card/gw_wenyi.jpg", + "image/card/gw_wuyao.jpg", + "image/card/gw_xianzumaijiu.jpg", + "image/card/gw_xinsheng.jpg", + "image/card/gw_yanziyaoshui.jpg", + "image/card/gw_yigeniyin.jpg", + "image/card/gw_youer.jpg", + "image/card/gw_zhihuanjun.jpg", + "image/card/gw_zhongmozhizhan.jpg", + "image/card/gw_zhuoshao.jpg", + "image/card/gw_zirankuizeng.jpg", + "image/card/gw_zuihouyuanwang.jpg", + "image/card/gw_zumoshoukao.jpg", + "image/card/gx_chongyingshenfu.png", + "image/card/gx_lingbaoxianhu.png", + "image/card/gx_taijifuchen.png", + "image/card/gz_guguoanbang.png", + "image/card/gz_haolingtianxia.png", + "image/card/gz_kefuzhongyuan.png", + "image/card/gz_wenheluanwu.png", + "image/card/hanbing.png", + "image/card/handcard.png", + "image/card/haotianta.png", + "image/card/heiguangkai.png", + "image/card/heilonglinpian.png", + "image/card/hina_shenji.png", + "image/card/hongshui.png", + "image/card/hsbaowu_cangbaotu.jpg", + "image/card/hsbaowu_huangjinyuanhou.jpg", + "image/card/hsdusu_huangxuecao.jpg", + "image/card/hsdusu_huoyanhua.jpg", + "image/card/hsdusu_kuyecao.jpg", + "image/card/hsdusu_shinancao.jpg", + "image/card/hsdusu_xueji.jpg", + "image/card/hsfashu_anyingjingxiang.jpg", + "image/card/hsfashu_buwendingyibian.jpg", + "image/card/hsjixie_zhadan.jpg", + "image/card/hslingjian_jinjilengdong.jpg", + "image/card/hslingjian_shengxiuhaojiao.jpg", + "image/card/hslingjian_shijianhuisu.jpg", + "image/card/hslingjian_xingtigaizao.jpg", + "image/card/hslingjian_xuanfengzhiren.jpg", + "image/card/hslingjian_yinmilichang.jpg", + "image/card/hslingjian_zhongxinghujia.jpg", + "image/card/hsmengjing_feicuiyoulong.jpg", + "image/card/hsmengjing_huanxiaojiemei.jpg", + "image/card/hsmengjing_mengjing.jpg", + "image/card/hsmengjing_mengye.jpg", + "image/card/hsmengjing_suxing.jpg", + "image/card/hsqingyu_feibiao.jpg", + "image/card/hsqingyu_hufu.jpg", + "image/card/hsqingyu_shandian.jpg", + "image/card/hsqingyu_zhanfang.jpg", + "image/card/hsqingyu_zhao.jpg", + "image/card/hsqizhou_feng.jpg", + "image/card/hsqizhou_huo.jpg", + "image/card/hsqizhou_shui.jpg", + "image/card/hsqizhou_tu.jpg", + "image/card/hsshenqi_kongbusangzhong.jpg", + "image/card/hsshenqi_morijingxiang.jpg", + "image/card/hsshenqi_nengliangzhiguang.jpg", + "image/card/hstianqi_dalian.jpg", + "image/card/hstianqi_nazigelin.jpg", + "image/card/hstianqi_shali.jpg", + "image/card/hstianqi_suolasi.jpg", + "image/card/hsyaoshui.jpg", + "image/card/hszuzhou_guhuo.jpg", + "image/card/hszuzhou_nvwudeganguo.jpg", + "image/card/hszuzhou_nvwudepingguo.jpg", + "image/card/hszuzhou_nvwudexuetu.jpg", + "image/card/hszuzhou_wushushike.jpg", + "image/card/hualiu.png", + "image/card/huanglinzhicong.png", + "image/card/huanpodan.png", + "image/card/hufu.png", + "image/card/huimiezhichui.png", + "image/card/huogong.png", + "image/card/huoshan.png", + "image/card/huoshaolianying.png", + "image/card/huxinjing.png", + "image/card/identity_commoner.jpg", + "image/card/identity_enemy.jpg", + "image/card/identity_fan.jpg", + "image/card/identity_friend.jpg", + "image/card/identity_nei.jpg", + "image/card/identity_zhong.jpg", + "image/card/identity_zhu.jpg", + "image/card/jiedao.png", + "image/card/jiejia.png", + "image/card/jiguanfeng.png", + "image/card/jiguanshu.png", + "image/card/jiguantong.png", + "image/card/jiguanyaoshu.png", + "image/card/jiguanyuan.png", + "image/card/jihuocard.png", + "image/card/jinchan.png", + "image/card/jingfanma.png", + "image/card/jingleishan.png", + "image/card/jinhe.png", + "image/card/jinlianzhu.png", + "image/card/jintuiziru.png", + "image/card/jiu.png", + "image/card/jiuwei.png", + "image/card/jiwangkailai.png", + "image/card/juedou.png", + "image/card/jueying.png", + "image/card/kaihua.png", + "image/card/kamome_suitcase.png", + "image/card/kano_paibingbuzhen.png", + "image/card/kongdongyin.png", + "image/card/kunlunjingc.png", + "image/card/kuwu.png", + "image/card/langeguaiyi.png", + "image/card/lanyinjia.png", + "image/card/lebu.png", + "image/card/lianjunshengyan.png", + "image/card/lianyaohu.png", + "image/card/linghunzhihuo.png", + "image/card/lingjiandai.png", + "image/card/liufengsan.png", + "image/card/liulongcanjia.png", + "image/card/liutouge.png", + "image/card/liuxiaxianniang.png", + "image/card/liuxinghuoyu.png", + "image/card/liyutang.png", + "image/card/longxugou.png", + "image/card/lukai_club.png", + "image/card/lukai_diamond.png", + "image/card/lukai_heart.png", + "image/card/lukai_spade.png", + "image/card/lulitongxin.png", + "image/card/luojingxiashi.png", + "image/card/luyugeng.png", + "image/card/ly_piliche.png", + "image/card/mapodoufu.png", + "image/card/mianju.png", + "image/card/mianlijinzhen.png", + "image/card/miki_binoculars.png", + "image/card/miki_hydrogladiator.png", + "image/card/mingguangkai.png", + "image/card/minguangkai.png", + "image/card/mizhilianou.png", + "image/card/molicha.png", + "image/card/monkey.png", + "image/card/mtg_bingheyaosai.jpg", + "image/card/mtg_cangbaohaiwan.jpg", + "image/card/mtg_duzhao.jpg", + "image/card/mtg_feixu.jpg", + "image/card/mtg_haidao.jpg", + "image/card/mtg_lindixiliu.jpg", + "image/card/mtg_linzhongjianta.jpg", + "image/card/mtg_longlushanfeng.jpg", + "image/card/mtg_shamolvzhou.jpg", + "image/card/mtg_shuimomuxue.jpg", + "image/card/mtg_yixialan.jpg", + "image/card/mtg_youlin.jpg", + "image/card/mujiaren.png", + "image/card/muniu.png", + "image/card/muniu_small.png", + "image/card/mutoumianju.png", + "image/card/nanman.png", + "image/card/numa.png", + "image/card/nvwashi.png", + "image/card/nvzhuang.png", + "image/card/pangufu.png", + "image/card/pantao.png", + "image/card/pss_paper.png", + "image/card/pss_scissor.png", + "image/card/pss_stone.png", + "image/card/pyzhuren_club.png", + "image/card/pyzhuren_diamond.png", + "image/card/pyzhuren_heart.png", + "image/card/pyzhuren_shandian.png", + "image/card/pyzhuren_spade.png", + "image/card/qiankunbiao.png", + "image/card/qiankundai.png", + "image/card/qiaosi_card1.png", + "image/card/qiaosi_card2.png", + "image/card/qiaosi_card3.png", + "image/card/qiaosi_card4.png", + "image/card/qiaosi_card5.png", + "image/card/qiaosi_card6.png", + "image/card/qibaodao.png", + "image/card/qijia.png", + "image/card/qilin.png", + "image/card/qinggang.png", + "image/card/qinglianxindeng.png", + "image/card/qinglong.png", + "image/card/qinglonglingzhu.png", + "image/card/qinglongzhigui.png", + "image/card/qingtuan.png", + "image/card/qixingbaodao.png", + "image/card/qizhengxiangsheng.png", + "image/card/renwang.png", + "image/card/rewrite_bagua.png", + "image/card/rewrite_baiyin.png", + "image/card/rewrite_lanyinjia.png", + "image/card/rewrite_renwang.png", + "image/card/rewrite_tengjia.png", + "image/card/rewrite_zhuge.png", + "image/card/ruyijingubang.png", + "image/card/sadengjinhuan.png", + "image/card/sanjian.png", + "image/card/sanlve.png", + "image/card/serafuku.png", + "image/card/sex_double.png", + "image/card/sex_female.png", + "image/card/sex_male.png", + "image/card/sex_male_castrated.png", + "image/card/sex_none.png", + "image/card/sex_unknown.png", + "image/card/sha.png", + "image/card/shan.png", + "image/card/shandian.png", + "image/card/shandianjian.png", + "image/card/shatang.png", + "image/card/shencaojie.png", + "image/card/shenenshu.png", + "image/card/shengdong.png", + "image/card/shenhuofeiya.png", + "image/card/shenmiguo.png", + "image/card/shennongding.png", + "image/card/shentoumianju.png", + "image/card/shezhanqunru.png", + "image/card/shield.png", + "image/card/shihuawuqi.png", + "image/card/shihuifen.png", + "image/card/shijieshu.png", + "image/card/shoulijian.png", + "image/card/shuchui.png", + "image/card/shuijing_card.png", + "image/card/shuiyanqijun.png", + "image/card/shuiyanqijunx.png", + "image/card/shujinsan.png", + "image/card/shunshou.png", + "image/card/sifeizhenmian.png", + "image/card/sizhaojian.png", + "image/card/suijiyingbian.png", + "image/card/suolianjia.png", + "image/card/taigongyinfu.png", + "image/card/taipingyaoshu.png", + "image/card/tanhuadong.png", + "image/card/tanshezhiren.png", + "image/card/tao.png", + "image/card/taoyuan.png", + "image/card/tengjia.png", + "image/card/tianjitu.png", + "image/card/tianxianjiu.png", + "image/card/tiaojiyanmei.png", + "image/card/tiesuo.png", + "image/card/tiesuo_mark.png", + "image/card/tongque.png", + "image/card/toulianghuanzhu.png", + "image/card/toushiche.png", + "image/card/tuhunsha.png", + "image/card/tuixinzhifu.png", + "image/card/tunliang.png", + "image/card/tuteng1.jpg", + "image/card/tuteng2.jpg", + "image/card/tuteng3.jpg", + "image/card/tuteng4.jpg", + "image/card/tuteng5.jpg", + "image/card/tuteng6.jpg", + "image/card/tuteng7.jpg", + "image/card/tuteng8.jpg", + "image/card/wangmeizhike.png", + "image/card/wanjian.png", + "image/card/wenhuangsan.png", + "image/card/wolong_card.png", + "image/card/wufengjian.png", + "image/card/wugu.png", + "image/card/wuliu.png", + "image/card/wutiesuolian.png", + "image/card/wuxie.png", + "image/card/wuxinghelingshan.png", + "image/card/wuxingpan.png", + "image/card/wuzhong.png", + "image/card/wy_meirenji.png", + "image/card/wy_xiaolicangdao.png", + "image/card/xiajiao.png", + "image/card/xianluhui.png", + "image/card/xiaolicangdao.png", + "image/card/xiayuncailing.png", + "image/card/xietianzi.png", + "image/card/xinge.png", + "image/card/xingjiegoutong.png", + "image/card/xingjunyan.png", + "image/card/xionghuangjiu.png", + "image/card/xixueguizhihuan.png", + "image/card/xuanjian_card.png", + "image/card/xuanwuzhihuang.png", + "image/card/xuanyuanjian.png", + "image/card/xuejibingbao.png", + "image/card/xuelunyang.png", + "image/card/xumou_jsrg.jpg", + "image/card/yajiaoqiang.png", + "image/card/yangpijuan.png", + "image/card/yanjiadan_club.png", + "image/card/yanjiadan_diamond.png", + "image/card/yanjiadan_heart.png", + "image/card/yanjiadan_spade.png", + "image/card/yanxiao_card.jpg", + "image/card/yexingyi.png", + "image/card/yihuajiemu.png", + "image/card/yinfengjia.png", + "image/card/yinfengyi.png", + "image/card/ying.png", + "image/card/yinyueqiang.png", + "image/card/yitianjian.png", + "image/card/yiyi.png", + "image/card/yonglv.png", + "image/card/youdishenru.png", + "image/card/yougeng.png", + "image/card/yuanbaorou.png", + "image/card/yuanjiao.png", + "image/card/yuanjun.png", + "image/card/yuansuhuimie.png", + "image/card/yuchandui.png", + "image/card/yuchangen.png", + "image/card/yuchankan.png", + "image/card/yuchankun.png", + "image/card/yuchanli.png", + "image/card/yuchanqian.png", + "image/card/yuchanxun.png", + "image/card/yuchanzhen.png", + "image/card/yufulu.png", + "image/card/yuheng.png", + "image/card/yunvyuanshen.png", + "image/card/yuruyi.png", + "image/card/yuxi.png", + "image/card/zengbin.png", + "image/card/zhadan.png", + "image/card/zhangba.png", + "image/card/zhanxiang.png", + "image/card/zhaogujing.png", + "image/card/zhaomingdan.png", + "image/card/zhaoshu.png", + "image/card/zheji.png", + "image/card/zhibi.png", + "image/card/zhiliaobo.png", + "image/card/zhiluxiaohu.png", + "image/card/zhuahuang.png", + "image/card/zhuangshu_basic.png", + "image/card/zhuangshu_equip.png", + "image/card/zhuangshu_trick.png", + "image/card/zhufangshenshi.png", + "image/card/zhuge.png", + "image/card/zhujinqiyuan.png", + "image/card/zhulu_card.png", + "image/card/zhungangshuo.png", + "image/card/zhuque.png", + "image/card/zhuquezhizhang.png", + "image/card/zixin.png", + "image/card/ziyangdan.png", + "image/card/zong.png", + /*card image end*/ + + /*character image begin*/ + "image/character/ahuinan.jpg", + "image/character/bailingyun.jpg", + "image/character/baiwuchang.jpg", + "image/character/baosanniang.jpg", + "image/character/baoxin.jpg", + "image/character/beimihu.jpg", + "image/character/bianfuren.jpg", + "image/character/bianxi.jpg", + "image/character/boss_zhaoyun.jpg", + "image/character/bulianshi.jpg", + "image/character/buzhi.jpg", + "image/character/caifuren.jpg", + "image/character/caimaozhangyun.jpg", + "image/character/caiwenji.jpg", + "image/character/caiyang.jpg", + "image/character/caiyong.jpg", + "image/character/caizhenji.jpg", + "image/character/caoang.jpg", + "image/character/caoanmin.jpg", + "image/character/caobuxing.jpg", + "image/character/caocao.jpg", + "image/character/caochong.jpg", + "image/character/caochun.jpg", + "image/character/caofang.jpg", + "image/character/caohong.jpg", + "image/character/caohua.jpg", + "image/character/caojie.jpg", + "image/character/caojinyu.jpg", + "image/character/caomao.jpg", + "image/character/caopi.jpg", + "image/character/caoren.jpg", + "image/character/caorui.jpg", + "image/character/caoshuang.jpg", + "image/character/caosong.jpg", + "image/character/caoxi.jpg", + "image/character/caoxian.jpg", + "image/character/caoxiancaohua.jpg", + "image/character/caoxing.jpg", + "image/character/caoxiu.jpg", + "image/character/caoyi.jpg", + "image/character/caoying.jpg", + "image/character/caoyu.jpg", + "image/character/caozhang.jpg", + "image/character/caozhen.jpg", + "image/character/caozhi.jpg", + "image/character/cenhun.jpg", + "image/character/cheliji.jpg", + "image/character/chendao.jpg", + "image/character/chendeng.jpg", + "image/character/chendong.jpg", + "image/character/chengbing.jpg", + "image/character/chengjichengcui.jpg", + "image/character/chengong.jpg", + "image/character/chengpu.jpg", + "image/character/chengui.jpg", + "image/character/chengyu.jpg", + "image/character/chenjiao.jpg", + "image/character/chenlin.jpg", + "image/character/chenqun.jpg", + "image/character/chenshi.jpg", + "image/character/chentai.jpg", + "image/character/chunyuqiong.jpg", + "image/character/clan_hanrong.jpg", + "image/character/clan_hanshao.jpg", + "image/character/clan_wangguang.jpg", + "image/character/clan_wanghun.jpg", + "image/character/clan_wangling.jpg", + "image/character/clan_wanglun.jpg", + "image/character/clan_wangmingshan.jpg", + "image/character/clan_wangyun.jpg", + "image/character/clan_wuban.jpg", + "image/character/clan_wukuang.jpg", + "image/character/clan_wuqiao.jpg", + "image/character/clan_wuxian.jpg", + "image/character/clan_xuncai.jpg", + "image/character/clan_xuncan.jpg", + "image/character/clan_xunchen.jpg", + "image/character/clan_xunshu.jpg", + "image/character/clan_xunyou.jpg", + "image/character/clan_zhonghui.jpg", + "image/character/clan_zhongyan.jpg", + "image/character/clan_zhongyu.jpg", + "image/character/cuimao.jpg", + "image/character/cuiyan.jpg", + "image/character/daqiao.jpg", + "image/character/daxiaoqiao.jpg", + "image/character/db_key_hina.jpg", + "image/character/db_key_liyingxia.jpg", + "image/character/db_wenyang.jpg", + "image/character/dc_bulianshi.jpg", + "image/character/dc_caiyang.jpg", + "image/character/dc_caocao.jpg", + "image/character/dc_caoshuang.jpg", + "image/character/dc_caozhi.jpg", + "image/character/dc_chenqun.jpg", + "image/character/dc_daxiaoqiao.jpg", + "image/character/dc_dongzhao.jpg", + "image/character/dc_duyu.jpg", + "image/character/dc_fuwan.jpg", + "image/character/dc_ganfuren.jpg", + "image/character/dc_gaolan.jpg", + "image/character/dc_gongsunzan.jpg", + "image/character/dc_guansuo.jpg", + "image/character/dc_huangchengyan.jpg", + "image/character/dc_huanghao.jpg", + "image/character/dc_huangquan.jpg", + "image/character/dc_huangzu.jpg", + "image/character/dc_huban.jpg", + "image/character/dc_hujinding.jpg", + "image/character/dc_huojun.jpg", + "image/character/dc_jiachong.jpg", + "image/character/dc_jiangji.jpg", + "image/character/dc_jiben.jpg", + "image/character/dc_jikang.jpg", + "image/character/dc_jiling.jpg", + "image/character/dc_jsp_guanyu.jpg", + "image/character/dc_kongrong.jpg", + "image/character/dc_liru.jpg", + "image/character/dc_liuba.jpg", + "image/character/dc_liubei.jpg", + "image/character/dc_liuli.jpg", + "image/character/dc_liuye.jpg", + "image/character/dc_liuyu.jpg", + "image/character/dc_luotong.jpg", + "image/character/dc_lvkuanglvxiang.jpg", + "image/character/dc_mengda.jpg", + "image/character/dc_mifuren.jpg", + "image/character/dc_ruiji.jpg", + "image/character/dc_sb_lusu.jpg", + "image/character/dc_sb_simayi.jpg", + "image/character/dc_sb_simayi_shadow.jpg", + "image/character/dc_sb_zhouyu.jpg", + "image/character/dc_shixie.jpg", + "image/character/dc_simashi.jpg", + "image/character/dc_sp_jiaxu.jpg", + "image/character/dc_sp_machao.jpg", + "image/character/dc_sunce.jpg", + "image/character/dc_sunchen.jpg", + "image/character/dc_sunhanhua.jpg", + "image/character/dc_sunquan.jpg", + "image/character/dc_sunru.jpg", + "image/character/dc_sunziliufang.jpg", + "image/character/dc_tengfanglan.jpg", + "image/character/dc_wangchang.jpg", + "image/character/dc_wangjun.jpg", + "image/character/dc_wangling.jpg", + "image/character/dc_wangyun.jpg", + "image/character/dc_wuban.jpg", + "image/character/dc_xiahouba.jpg", + "image/character/dc_xujing.jpg", + "image/character/dc_xushu.jpg", + "image/character/dc_yangbiao.jpg", + "image/character/dc_yanghu.jpg", + "image/character/dc_yuejiu.jpg", + "image/character/dc_zhangmancheng.jpg", + "image/character/dc_zhaotongzhaoguang.jpg", + "image/character/dc_zhaoxiang.jpg", + "image/character/dc_zhaoyǎn.jpg", + "image/character/dc_zhaoyun.jpg", + "image/character/dc_zhouxuān.jpg", + "image/character/dc_zhuling.jpg", + "image/character/ddd_baosanniang.jpg", + "image/character/ddd_caomao.jpg", + "image/character/ddd_caoshuang.jpg", + "image/character/ddd_dingfeng.jpg", + "image/character/ddd_guanning.jpg", + "image/character/ddd_handang.jpg", + "image/character/ddd_jianshuo.jpg", + "image/character/ddd_kebineng.jpg", + "image/character/ddd_liangxi.jpg", + "image/character/ddd_lie.jpg", + "image/character/ddd_liuba.jpg", + "image/character/ddd_liuhong.jpg", + "image/character/ddd_liuye.jpg", + "image/character/ddd_sunliang.jpg", + "image/character/ddd_wangkanglvkai.jpg", + "image/character/ddd_wuzhi.jpg", + "image/character/ddd_xiahouxuan.jpg", + "image/character/ddd_xianglang.jpg", + "image/character/ddd_xinxianying.jpg", + "image/character/ddd_xuelingyun.jpg", + "image/character/ddd_xujing.jpg", + "image/character/ddd_yujin.jpg", + "image/character/ddd_zhangkai.jpg", + "image/character/ddd_zhaoang.jpg", + "image/character/ddd_zhenji.jpg", + "image/character/ddd_zhouchu.jpg", + "image/character/default_silhouette_double.jpg", + "image/character/default_silhouette_female.jpg", + "image/character/default_silhouette_male.jpg", + "image/character/dengai.jpg", + "image/character/dengzhi.jpg", + "image/character/dengzhong.jpg", + "image/character/dianwei.jpg", + "image/character/diaochan.jpg", + "image/character/dingfeng.jpg", + "image/character/dingshangwan.jpg", + "image/character/dingyuan.jpg", + "image/character/diy_caiwenji.jpg", + "image/character/diy_feishi.jpg", + "image/character/diy_hanlong.jpg", + "image/character/diy_huangzhong.jpg", + "image/character/diy_liufu.jpg", + "image/character/diy_liuyan.jpg", + "image/character/diy_liuzan.jpg", + "image/character/diy_lukang.jpg", + "image/character/diy_menghuo.jpg", + "image/character/diy_tianyu.jpg", + "image/character/diy_weiyan.jpg", + "image/character/diy_wenyang.jpg", + "image/character/diy_xizhenxihong.jpg", + "image/character/diy_xuhuang.jpg", + "image/character/diy_yangyi.jpg", + "image/character/diy_yuji.jpg", + "image/character/diy_zaozhirenjun.jpg", + "image/character/diy_zhenji.jpg", + "image/character/diy_zhouyu.jpg", + "image/character/dongbai.jpg", + "image/character/dongcheng.jpg", + "image/character/dongguiren.jpg", + "image/character/dongtuna.jpg", + "image/character/dongwan.jpg", + "image/character/dongxie.jpg", + "image/character/dongyun.jpg", + "image/character/dongzhao.jpg", + "image/character/dongzhuo.jpg", + "image/character/drag_caoren.jpg", + "image/character/drag_guanyu.jpg", + "image/character/drag_lvchang.jpg", + "image/character/duanjiong.jpg", + "image/character/duanqiaoxiao.jpg", + "image/character/duanwei.jpg", + "image/character/dufuren.jpg", + "image/character/duji.jpg", + "image/character/dukui.jpg", + "image/character/duosidawang.jpg", + "image/character/duxi.jpg", + "image/character/duyu.jpg", + "image/character/fanchou.jpg", + "image/character/fanjiangzhangda.jpg", + "image/character/fanyufeng.jpg", + "image/character/fazheng.jpg", + "image/character/feiyao.jpg", + "image/character/feiyi.jpg", + "image/character/fengfang.jpg", + "image/character/fengfangnv.jpg", + "image/character/fengxi.jpg", + "image/character/fuhuanghou.jpg", + "image/character/fuqian.jpg", + "image/character/furong.jpg", + "image/character/furongfuqian.jpg", + "image/character/fuwan.jpg", + "image/character/ganfuren.jpg", + "image/character/ganfurenmifuren.jpg", + "image/character/ganning.jpg", + "image/character/gaogan.jpg", + "image/character/gaolan.jpg", + "image/character/gaoshun.jpg", + "image/character/gaoxiang.jpg", + "image/character/gexuan.jpg", + "image/character/gjqt_aruan.jpg", + "image/character/gjqt_bailitusu.jpg", + "image/character/gjqt_beiluo.jpg", + "image/character/gjqt_cenying.jpg", + "image/character/gjqt_chuqi.jpg", + "image/character/gjqt_fanglansheng.jpg", + "image/character/gjqt_fengqingxue.jpg", + "image/character/gjqt_hongyu.jpg", + "image/character/gjqt_ouyangshaogong.jpg", + "image/character/gjqt_wenrenyu.jpg", + "image/character/gjqt_xiangling.jpg", + "image/character/gjqt_xiayize.jpg", + "image/character/gjqt_xieyi.jpg", + "image/character/gjqt_xunfang.jpg", + "image/character/gjqt_yanjiaxieyi.jpg", + "image/character/gjqt_yinqianshang.jpg", + "image/character/gjqt_yuewuyi.jpg", + "image/character/gjqt_yunwuyue.jpg", + "image/character/gongsundu.jpg", + "image/character/gongsunkang.jpg", + "image/character/gongsunxiu.jpg", + "image/character/gongsunyuan.jpg", + "image/character/gongsunzan.jpg", + "image/character/guanhai.jpg", + "image/character/guanlu.jpg", + "image/character/guanning.jpg", + "image/character/guānning.jpg", + "image/character/guanping.jpg", + "image/character/guanqiujian.jpg", + "image/character/guansuo.jpg", + "image/character/guanxingzhangbao.jpg", + "image/character/guanyinping.jpg", + "image/character/guanyu.jpg", + "image/character/guanzhang.jpg", + "image/character/guohuai.jpg", + "image/character/guohuanghou.jpg", + "image/character/guojia.jpg", + "image/character/guosi.jpg", + "image/character/guotu.jpg", + "image/character/guotufengji.jpg", + "image/character/guozhao.jpg", + "image/character/guyong.jpg", + "image/character/gw_aigeleisi.jpg", + "image/character/gw_aimin.jpg", + "image/character/gw_airuiting.jpg", + "image/character/gw_aisinie.jpg", + "image/character/gw_aokeweisite.jpg", + "image/character/gw_bierna.jpg", + "image/character/gw_bulanwang.jpg", + "image/character/gw_dagong.jpg", + "image/character/gw_diandian.jpg", + "image/character/gw_enxier.jpg", + "image/character/gw_falanxisika.jpg", + "image/character/gw_feilafanruide.jpg", + "image/character/gw_fenghuang.jpg", + "image/character/gw_fuertaisite.jpg", + "image/character/gw_fulisi.jpg", + "image/character/gw_gaier.jpg", + "image/character/gw_haizhiyezhu.jpg", + "image/character/gw_haluo.jpg", + "image/character/gw_hanmuduoer.jpg", + "image/character/gw_hengsaite.jpg", + "image/character/gw_huoge.jpg", + "image/character/gw_jieluote.jpg", + "image/character/gw_kaerweite.jpg", + "image/character/gw_kairuisi.jpg", + "image/character/gw_kanbi.jpg", + "image/character/gw_kaxier.jpg", + "image/character/gw_kuite.jpg", + "image/character/gw_laduoweide.jpg", + "image/character/gw_lanbote.jpg", + "image/character/gw_laomaotou.jpg", + "image/character/gw_laomaotou2.jpg", + "image/character/gw_linjing.jpg", + "image/character/gw_luobo.jpg", + "image/character/gw_luoqi.jpg", + "image/character/gw_meizi.jpg", + "image/character/gw_mieren.jpg", + "image/character/gw_nitelila.jpg", + "image/character/gw_nvyemo.jpg", + "image/character/gw_oudimu.jpg", + "image/character/gw_puxila.jpg", + "image/character/gw_qigaiwang.jpg", + "image/character/gw_sanhanya.jpg", + "image/character/gw_saqiya.jpg", + "image/character/gw_saqiya1.jpg", + "image/character/gw_saqiya2.jpg", + "image/character/gw_shanhu.jpg", + "image/character/gw_shasixiwusi.jpg", + "image/character/gw_telisi.jpg", + "image/character/gw_xigedelifa.jpg", + "image/character/gw_xili.jpg", + "image/character/gw_yenaifa.jpg", + "image/character/gw_yioufeisi.jpg", + "image/character/gw_yioufeisisp.jpg", + "image/character/gw_yisilinni.jpg", + "image/character/gw_zhangyujushou.jpg", + "image/character/gw_zhuoertan.jpg", + "image/character/gz_caohong.jpg", + "image/character/gz_caopi.jpg", + "image/character/gz_chengong.jpg", + "image/character/gz_dengai.jpg", + "image/character/gz_dengzhi.jpg", + "image/character/gz_dianwei.jpg", + "image/character/gz_diaochan.jpg", + "image/character/gz_dingfeng.jpg", + "image/character/gz_fazheng.jpg", + "image/character/gz_fengxi.jpg", + "image/character/gz_ganfuren.jpg", + "image/character/gz_gaoshun.jpg", + "image/character/gz_gongsunyuan.jpg", + "image/character/gz_guanyu.jpg", + "image/character/gz_guohuai.jpg", + "image/character/gz_guojia.jpg", + "image/character/gz_hetaihou.jpg", + "image/character/gz_huangyueying.jpg", + "image/character/gz_huangzhong.jpg", + "image/character/gz_huangzu.jpg", + "image/character/gz_jiangwei.jpg", + "image/character/gz_jiaxu.jpg", + "image/character/gz_lingtong.jpg", + "image/character/gz_liuba.jpg", + "image/character/gz_liuqi.jpg", + "image/character/gz_lukang.jpg", + "image/character/gz_luxun.jpg", + "image/character/gz_lvbu.jpg", + "image/character/gz_lvlingqi.jpg", + "image/character/gz_madai.jpg", + "image/character/gz_masu.jpg", + "image/character/gz_miheng.jpg", + "image/character/gz_panfeng.jpg", + "image/character/gz_panjun.jpg", + "image/character/gz_pengyang.jpg", + "image/character/gz_re_xushu.jpg", + "image/character/gz_re_yuanshao.jpg", + "image/character/gz_shamoke.jpg", + "image/character/gz_shixie.jpg", + "image/character/gz_simazhao.jpg", + "image/character/gz_sp_zhugeliang.jpg", + "image/character/gz_sunce.jpg", + "image/character/gz_sunjian.jpg", + "image/character/gz_sunshangxiang.jpg", + "image/character/gz_tangzi.jpg", + "image/character/gz_wangping.jpg", + "image/character/gz_wenqin.jpg", + "image/character/gz_wuguotai.jpg", + "image/character/gz_wujing.jpg", + "image/character/gz_xf_sufei.jpg", + "image/character/gz_xiahouba.jpg", + "image/character/gz_xiahouyuan.jpg", + "image/character/gz_xiaoqiao.jpg", + "image/character/gz_xunyou.jpg", + "image/character/gz_xusheng.jpg", + "image/character/gz_xuyou.jpg", + "image/character/gz_yanbaihu.jpg", + "image/character/gz_yangwan.jpg", + "image/character/gz_yuanshu.jpg", + "image/character/gz_yuejin.jpg", + "image/character/gz_yuji.jpg", + "image/character/gz_yujin.jpg", + "image/character/gz_zhanglu.jpg", + "image/character/gz_zhangxiu.jpg", + "image/character/gz_zhenji.jpg", + "image/character/gz_zhonghui.jpg", + "image/character/gz_zhouyu.jpg", + "image/character/gz_zhugeke.jpg", + "image/character/gz_zhugeliang.jpg", + "image/character/gz_zhuling.jpg", + "image/character/gz_zuoci.jpg", + "image/character/hanba.jpg", + "image/character/handang.jpg", + "image/character/hanfu.jpg", + "image/character/hanhaoshihuan.jpg", + "image/character/hanlong.jpg", + "image/character/hanmeng.jpg", + "image/character/hansui.jpg", + "image/character/haomeng.jpg", + "image/character/haopu.jpg", + "image/character/haozhao.jpg", + "image/character/heiwuchang.jpg", + "image/character/hejin.jpg", + "image/character/heqi.jpg", + "image/character/hetaihou.jpg", + "image/character/heyan.jpg", + "image/character/hhzz_kanade.jpg", + "image/character/hhzz_shiona.jpg", + "image/character/hhzz_takaramono1.jpg", + "image/character/hhzz_takaramono2.jpg", + "image/character/hidden_image.jpg", + "image/character/hs_aedwin.jpg", + "image/character/hs_aerfusi.jpg", + "image/character/hs_aiqinvyao.jpg", + "image/character/hs_alakir.jpg", + "image/character/hs_alextrasza.jpg", + "image/character/hs_alleria.jpg", + "image/character/hs_amala.jpg", + "image/character/hs_anduin.jpg", + "image/character/hs_anomalus.jpg", + "image/character/hs_antonidas.jpg", + "image/character/hs_ashamoer.jpg", + "image/character/hs_aya.jpg", + "image/character/hs_baiguyoulong.jpg", + "image/character/hs_bannabusi.jpg", + "image/character/hs_barnes.jpg", + "image/character/hs_bchillmaw.jpg", + "image/character/hs_bilanyoulong.jpg", + "image/character/hs_bingshuangnvwang.jpg", + "image/character/hs_blingtron.jpg", + "image/character/hs_bolvar.jpg", + "image/character/hs_brann.jpg", + "image/character/hs_duyaxinshi.jpg", + "image/character/hs_enzoth.jpg", + "image/character/hs_fachaotuteng.jpg", + "image/character/hs_fandral.jpg", + "image/character/hs_fengjianhuanfengzhe.jpg", + "image/character/hs_fenjie.jpg", + "image/character/hs_finley.jpg", + "image/character/hs_fuding.jpg", + "image/character/hs_guldan.jpg", + "image/character/hs_hajiasha.jpg", + "image/character/hs_hallazeal.jpg", + "image/character/hs_heifengqishi.jpg", + "image/character/hs_hemite.jpg", + "image/character/hs_hudunren.jpg", + "image/character/hs_huolituteng.jpg", + "image/character/hs_huzhixiannv.jpg", + "image/character/hs_jaina.jpg", + "image/character/hs_jgarrosh.jpg", + "image/character/hs_jiawodun.jpg", + "image/character/hs_jiaziruila.jpg", + "image/character/hs_jinglinglong.jpg", + "image/character/hs_kaituozhe.jpg", + "image/character/hs_kalimosi.jpg", + "image/character/hs_kazhakusi.jpg", + "image/character/hs_kchromaggus.jpg", + "image/character/hs_kcthun.jpg", + "image/character/hs_khadgar.jpg", + "image/character/hs_lafamu.jpg", + "image/character/hs_laila.jpg", + "image/character/hs_laxiao.jpg", + "image/character/hs_lazi.jpg", + "image/character/hs_liadrin.jpg", + "image/character/hs_loatheb.jpg", + "image/character/hs_lreno.jpg", + "image/character/hs_lrexxar.jpg", + "image/character/hs_lrhonin.jpg", + "image/character/hs_magni.jpg", + "image/character/hs_malfurion.jpg", + "image/character/hs_malorne.jpg", + "image/character/hs_malygos.jpg", + "image/character/hs_manyututeng.jpg", + "image/character/hs_medivh.jpg", + "image/character/hs_mijiaojisi.jpg", + "image/character/hs_mojinbaozi.jpg", + "image/character/hs_morgl.jpg", + "image/character/hs_nate.jpg", + "image/character/hs_neptulon.jpg", + "image/character/hs_nozdormu.jpg", + "image/character/hs_nuogefu.jpg", + "image/character/hs_pengpeng.jpg", + "image/character/hs_pyros.jpg", + "image/character/hs_pyros1.jpg", + "image/character/hs_pyros2.jpg", + "image/character/hs_ronghejuren.jpg", + "image/character/hs_ruanniguai.jpg", + "image/character/hs_sainaliusi.jpg", + "image/character/hs_sapphiron.jpg", + "image/character/hs_selajin.jpg", + "image/character/hs_selajin2.jpg", + "image/character/hs_shaku.jpg", + "image/character/hs_shanlingjuren.jpg", + "image/character/hs_shifazhe.jpg", + "image/character/hs_shirencao.jpg", + "image/character/hs_shizugui.jpg", + "image/character/hs_shuiwenxuejia.jpg", + "image/character/hs_siwangxianzhi.jpg", + "image/character/hs_siwangzhiyi.jpg", + "image/character/hs_sthrall.jpg", + "image/character/hs_taisi.jpg", + "image/character/hs_tanghangu.jpg", + "image/character/hs_tgolem.jpg", + "image/character/hs_totemic.jpg", + "image/character/hs_trueheart.jpg", + "image/character/hs_tuoqi.jpg", + "image/character/hs_tyrande.jpg", + "image/character/hs_waleera.jpg", + "image/character/hs_walian.jpg", + "image/character/hs_wolazi.jpg", + "image/character/hs_wujiyuansu.jpg", + "image/character/hs_wuther.jpg", + "image/character/hs_wuyaowang.jpg", + "image/character/hs_wvelen.jpg", + "image/character/hs_xialikeer.jpg", + "image/character/hs_xiangyaqishi.jpg", + "image/character/hs_xsylvanas.jpg", + "image/character/hs_xuanzhuanjijia.jpg", + "image/character/hs_xuefashi.jpg", + "image/character/hs_xukongzhiying.jpg", + "image/character/hs_yangyanwageli.jpg", + "image/character/hs_yashaji.jpg", + "image/character/hs_yelinchulong.jpg", + "image/character/hs_yelinlonghou.jpg", + "image/character/hs_yelise.jpg", + "image/character/hs_yinggencao.jpg", + "image/character/hs_yngvar.jpg", + "image/character/hs_yogg.jpg", + "image/character/hs_ysera.jpg", + "image/character/hs_yuhuozhe.jpg", + "image/character/hs_zhanzhenggushu.jpg", + "image/character/hs_zhihuanhua.jpg", + "image/character/hs_zhishigushu.jpg", + "image/character/hs_zhouzhuo.jpg", + "image/character/huaman.jpg", + "image/character/huanfan.jpg", + "image/character/huangchengyan.jpg", + "image/character/huangfusong.jpg", + "image/character/huanggai.jpg", + "image/character/huanghao.jpg", + "image/character/huangjinleishi.jpg", + "image/character/huangyueying.jpg", + "image/character/huangzhong.jpg", + "image/character/huangzu.jpg", + "image/character/huatuo.jpg", + "image/character/huaxin.jpg", + "image/character/huaxiong.jpg", + "image/character/huban.jpg", + "image/character/hucheer.jpg", + "image/character/hujinding.jpg", + "image/character/huojun.jpg", + "image/character/huzhao.jpg", + "image/character/jiachong.jpg", + "image/character/jiakui.jpg", + "image/character/jiangfei.jpg", + "image/character/jianggan.jpg", + "image/character/jiangqing.jpg", + "image/character/jiangwei.jpg", + "image/character/jianyong.jpg", + "image/character/jiaxu.jpg", + "image/character/jikang.jpg", + "image/character/jiling.jpg", + "image/character/jin_guohuai.jpg", + "image/character/jin_jiachong.jpg", + "image/character/jin_simashi.jpg", + "image/character/jin_simayi.jpg", + "image/character/jin_simazhao.jpg", + "image/character/jin_wangyuanji.jpg", + "image/character/jin_xiahouhui.jpg", + "image/character/jin_yanghu.jpg", + "image/character/jin_yanghuiyu.jpg", + "image/character/jin_zhangchunhua.jpg", + "image/character/jin_zhouchu.jpg", + "image/character/jsp_caoren.jpg", + "image/character/jsp_guanyu.jpg", + "image/character/jsp_huangyueying.jpg", + "image/character/jsp_liubei.jpg", + "image/character/jsp_zhaoyun.jpg", + "image/character/jsrg_caocao.jpg", + "image/character/jsrg_caofang.jpg", + "image/character/jsrg_chendeng.jpg", + "image/character/jsrg_chunyuqiong.jpg", + "image/character/jsrg_dongbai.jpg", + "image/character/jsrg_fanjiangzhangda.jpg", + "image/character/jsrg_gaoxiang.jpg", + "image/character/jsrg_guanyu.jpg", + "image/character/jsrg_guojia.jpg", + "image/character/jsrg_guoxun.jpg", + "image/character/jsrg_guozhao.jpg", + "image/character/jsrg_hansui.jpg", + "image/character/jsrg_hejin.jpg", + "image/character/jsrg_huangfusong.jpg", + "image/character/jsrg_huangzhong.jpg", + "image/character/jsrg_jiangwei.jpg", + "image/character/jsrg_kongrong.jpg", + "image/character/jsrg_liubei.jpg", + "image/character/jsrg_liuhong.jpg", + "image/character/jsrg_liuyan.jpg", + "image/character/jsrg_liuyong.jpg", + "image/character/jsrg_lougui.jpg", + "image/character/jsrg_luxun.jpg", + "image/character/jsrg_lvbu.jpg", + "image/character/jsrg_machao.jpg", + "image/character/jsrg_nanhualaoxian.jpg", + "image/character/jsrg_pangtong.jpg", + "image/character/jsrg_qiaoxuan.jpg", + "image/character/jsrg_simayi.jpg", + "image/character/jsrg_sunce.jpg", + "image/character/jsrg_sunjian.jpg", + "image/character/jsrg_sunjun.jpg", + "image/character/jsrg_sunlubansunluyu.jpg", + "image/character/jsrg_sunshangxiang.jpg", + "image/character/jsrg_wangyun.jpg", + "image/character/jsrg_weiwenzhugezhi.jpg", + "image/character/jsrg_xiahouen.jpg", + "image/character/jsrg_xiahourong.jpg", + "image/character/jsrg_xugong.jpg", + "image/character/jsrg_xushao.jpg", + "image/character/jsrg_xuyou.jpg", + "image/character/jsrg_yangbiao.jpg", + "image/character/jsrg_zhangchu.jpg", + "image/character/jsrg_zhangfei.jpg", + "image/character/jsrg_zhanghe.jpg", + "image/character/jsrg_zhangliao.jpg", + "image/character/jsrg_zhangren.jpg", + "image/character/jsrg_zhangxuan.jpg", + "image/character/jsrg_zhaoyun.jpg", + "image/character/jsrg_zhenji.jpg", + "image/character/jsrg_zhugeliang.jpg", + "image/character/jsrg_zhujun.jpg", + "image/character/jsrg_zoushi.jpg", + "image/character/jun_caocao.jpg", + "image/character/jun_liubei.jpg", + "image/character/jun_sunquan.jpg", + "image/character/jun_zhangjiao.jpg", + "image/character/junk_duanwei.jpg", + "image/character/junk_guanyu.jpg", + "image/character/junk_huangyueying.jpg", + "image/character/junk_lidian.jpg", + "image/character/junk_liubei.jpg", + "image/character/junk_simayi.jpg", + "image/character/junk_sunquan.jpg", + "image/character/junk_xuyou.jpg", + "image/character/junk_zhangjiao.jpg", + "image/character/junk_zhangrang.jpg", + "image/character/kaisa.jpg", + "image/character/kanze.jpg", + "image/character/kebineng.jpg", + "image/character/key_abyusa.jpg", + "image/character/key_akane.jpg", + "image/character/key_akiko.jpg", + "image/character/key_ao.jpg", + "image/character/key_asara.jpg", + "image/character/key_ayato.jpg", + "image/character/key_chihaya.jpg", + "image/character/key_doruji.jpg", + "image/character/key_erika.jpg", + "image/character/key_fuuko.jpg", + "image/character/key_godan.jpg", + "image/character/key_harukakanata.jpg", + "image/character/key_haruko.jpg", + "image/character/key_hina.jpg", + "image/character/key_hinata.jpg", + "image/character/key_hiroto.jpg", + "image/character/key_hisako.jpg", + "image/character/key_inari.jpg", + "image/character/key_iriya.jpg", + "image/character/key_iwasawa.jpg", + "image/character/key_jojiro.jpg", + "image/character/key_kagari.jpg", + "image/character/key_kamome.jpg", + "image/character/key_kano.jpg", + "image/character/key_kaori.jpg", + "image/character/key_kengo.jpg", + "image/character/key_kiyu.jpg", + "image/character/key_komari.jpg", + "image/character/key_kotarou.jpg", + "image/character/key_kotomi.jpg", + "image/character/key_kotori.jpg", + "image/character/key_kud.jpg", + "image/character/key_kyoko.jpg", + "image/character/key_kyou.jpg", + "image/character/key_kyouko.jpg", + "image/character/key_kyousuke.jpg", + "image/character/key_lucia.jpg", + "image/character/key_masato.jpg", + "image/character/key_mia.jpg", + "image/character/key_michiru.jpg", + "image/character/key_midori.jpg", + "image/character/key_miki.jpg", + "image/character/key_minagi.jpg", + "image/character/key_mio.jpg", + "image/character/key_misa.jpg", + "image/character/key_misuzu.jpg", + "image/character/key_nagisa.jpg", + "image/character/key_nao.jpg", + "image/character/key_noda.jpg", + "image/character/key_rei.jpg", + "image/character/key_riki.jpg", + "image/character/key_rin.jpg", + "image/character/key_rumi.jpg", + "image/character/key_ryoichi.jpg", + "image/character/key_sakuya.jpg", + "image/character/key_sasami.jpg", + "image/character/key_satomi.jpg", + "image/character/key_saya.jpg", + "image/character/key_seira.jpg", + "image/character/key_shiina.jpg", + "image/character/key_shiki.jpg", + "image/character/key_shiori.jpg", + "image/character/key_shiorimiyuki.jpg", + "image/character/key_shiroha.jpg", + "image/character/key_shizuku.jpg", + "image/character/key_shizuru.jpg", + "image/character/key_sunohara.jpg", + "image/character/key_tenzen.jpg", + "image/character/key_tomoya.jpg", + "image/character/key_tomoyo.jpg", + "image/character/key_tsumugi.jpg", + "image/character/key_umi.jpg", + "image/character/key_ushio.jpg", + "image/character/key_yoshino.jpg", + "image/character/key_youta.jpg", + "image/character/key_yui.jpg", + "image/character/key_yuiko.jpg", + "image/character/key_yukine.jpg", + "image/character/key_yukito.jpg", + "image/character/key_yuri.jpg", + "image/character/key_yusa.jpg", + "image/character/key_yuu.jpg", + "image/character/key_yuuki.jpg", + "image/character/key_yuzuru.jpg", + "image/character/kongrong.jpg", + "image/character/kuailiangkuaiyue.jpg", + "image/character/kuaiqi.jpg", + "image/character/laimin.jpg", + "image/character/laiyinger.jpg", + "image/character/le_shen_jiaxu.jpg", + "image/character/leibo.jpg", + "image/character/leitong.jpg", + "image/character/liangxing.jpg", + "image/character/liaohua.jpg", + "image/character/libai.jpg", + "image/character/licaiwei.jpg", + "image/character/lifeng.jpg", + "image/character/lijue.jpg", + "image/character/lingcao.jpg", + "image/character/lingju.jpg", + "image/character/lingtong.jpg", + "image/character/liqueguosi.jpg", + "image/character/liru.jpg", + "image/character/lisu.jpg", + "image/character/litong.jpg", + "image/character/liuba.jpg", + "image/character/liubei.jpg", + "image/character/liubian.jpg", + "image/character/liubiao.jpg", + "image/character/liuchen.jpg", + "image/character/liucheng.jpg", + "image/character/liuchongluojun.jpg", + "image/character/liufeng.jpg", + "image/character/liuhong.jpg", + "image/character/liuhui.jpg", + "image/character/liupan.jpg", + "image/character/liupi.jpg", + "image/character/liuqi.jpg", + "image/character/liushan.jpg", + "image/character/liuxie.jpg", + "image/character/liuyan.jpg", + "image/character/liuyao.jpg", + "image/character/liuye.jpg", + "image/character/liuyong.jpg", + "image/character/liuyu.jpg", + "image/character/liuzan.jpg", + "image/character/liuzhang.jpg", + "image/character/liwan.jpg", + "image/character/liwei.jpg", + "image/character/liyan.jpg", + "image/character/liyi.jpg", + "image/character/liyixiejing.jpg", + "image/character/longwang.jpg", + "image/character/longyufei.jpg", + "image/character/luji.jpg", + "image/character/lukai.jpg", + "image/character/lukang.jpg", + "image/character/luotong.jpg", + "image/character/luoxian.jpg", + "image/character/lushi.jpg", + "image/character/luxun.jpg", + "image/character/luyi.jpg", + "image/character/luyusheng.jpg", + "image/character/luzhi.jpg", + "image/character/lvboshe.jpg", + "image/character/lvbu.jpg", + "image/character/lvdai.jpg", + "image/character/lvfan.jpg", + "image/character/lvkai.jpg", + "image/character/lvkuanglvxiang.jpg", + "image/character/lvlingqi.jpg", + "image/character/lvmeng.jpg", + "image/character/lvqian.jpg", + "image/character/machao.jpg", + "image/character/macheng.jpg", + "image/character/madai.jpg", + "image/character/majun.jpg", + "image/character/maliang.jpg", + "image/character/malingli.jpg", + "image/character/mamian.jpg", + "image/character/mamidi.jpg", + "image/character/manchong.jpg", + "image/character/mangyachang.jpg", + "image/character/masu.jpg", + "image/character/mateng.jpg", + "image/character/maxiumatie.jpg", + "image/character/mayuanyi.jpg", + "image/character/mayunlu.jpg", + "image/character/mazhong.jpg", + "image/character/mb_chengui.jpg", + "image/character/mb_huban.jpg", + "image/character/mb_sunluyu.jpg", + "image/character/mb_xianglang.jpg", + "image/character/mengda.jpg", + "image/character/menghuo.jpg", + "image/character/mengjie.jpg", + "image/character/mengyou.jpg", + "image/character/mifangfushiren.jpg", + "image/character/mifuren.jpg", + "image/character/miheng.jpg", + "image/character/mizhu.jpg", + "image/character/mp_liuling.jpg", + "image/character/mtg_ayeni.jpg", + "image/character/mtg_jiding.jpg", + "image/character/mtg_jiesi.jpg", + "image/character/mtg_lilianna.jpg", + "image/character/mtg_nisha.jpg", + "image/character/mtg_qianzhuo.jpg", + "image/character/muludawang.jpg", + "image/character/mushun.jpg", + "image/character/nanhualaoxian.jpg", + "image/character/nashime.jpg", + "image/character/new_caoren.jpg", + "image/character/nezha.jpg", + "image/character/nianshou.jpg", + "image/character/niufu.jpg", + "image/character/niujin.jpg", + "image/character/niutou.jpg", + "image/character/noname.jpg", + "image/character/noname_machao.png", + "image/character/noname_sunce.png", + "image/character/ns_caimao.jpg", + "image/character/ns_caoanmin.jpg", + "image/character/ns_caocao.jpg", + "image/character/ns_caocaosp.jpg", + "image/character/ns_caoshuang.jpg", + "image/character/ns_chendao.jpg", + "image/character/ns_chengpu.jpg", + "image/character/ns_chentai.jpg", + "image/character/ns_duangui.jpg", + "image/character/ns_duji.jpg", + "image/character/ns_fanchou.jpg", + "image/character/ns_guanlu.jpg", + "image/character/ns_huamulan.jpg", + "image/character/ns_huangchengyan.jpg", + "image/character/ns_huangwudie.jpg", + "image/character/ns_huangzu.jpg", + "image/character/ns_jiaxu.jpg", + "image/character/ns_jinke.jpg", + "image/character/ns_lijue.jpg", + "image/character/ns_limi.jpg", + "image/character/ns_lisu.jpg", + "image/character/ns_liuzhang.jpg", + "image/character/ns_luyusheng.jpg", + "image/character/ns_lvmeng.jpg", + "image/character/ns_lvzhi.jpg", + "image/character/ns_masu.jpg", + "image/character/ns_mengyou.jpg", + "image/character/ns_nanhua.jpg", + "image/character/ns_nanhua_left.jpg", + "image/character/ns_nanhua_right.jpg", + "image/character/ns_ruanji.jpg", + "image/character/ns_shenpei.jpg", + "image/character/ns_simazhao.jpg", + "image/character/ns_sunchensunjun.jpg", + "image/character/ns_sundeng.jpg", + "image/character/ns_sunjian.jpg", + "image/character/ns_sunyi.jpg", + "image/character/ns_wangyue.jpg", + "image/character/ns_wangyun.jpg", + "image/character/ns_wenchou.jpg", + "image/character/ns_xinnanhua.jpg", + "image/character/ns_xinxianying.jpg", + "image/character/ns_yanghu.jpg", + "image/character/ns_yangyi.jpg", + "image/character/ns_yanliang.jpg", + "image/character/ns_yuanxi.jpg", + "image/character/ns_yuji.jpg", + "image/character/ns_yujisp.jpg", + "image/character/ns_zanghong.jpg", + "image/character/ns_zhangbao.jpg", + "image/character/ns_zhangji.jpg", + "image/character/ns_zhangning.jpg", + "image/character/ns_zhangwei.jpg", + "image/character/ns_zhangxiu.jpg", + "image/character/ns_zhonglimu.jpg", + "image/character/ns_zhugeliang.jpg", + "image/character/ns_zuoci.jpg", + "image/character/ol_bianfuren.jpg", + "image/character/ol_caiwenji.jpg", + "image/character/ol_caozhang.jpg", + "image/character/ol_chendeng.jpg", + "image/character/ol_chengpu.jpg", + "image/character/ol_dengai.jpg", + "image/character/ol_dengzhi.jpg", + "image/character/ol_dianwei.jpg", + "image/character/ol_dingshangwan.jpg", + "image/character/ol_dingyuan.jpg", + "image/character/ol_dongzhao.jpg", + "image/character/ol_dongzhuo.jpg", + "image/character/ol_feiyi.jpg", + "image/character/ol_furong.jpg", + "image/character/ol_gaoshun.jpg", + "image/character/ol_guohuai.jpg", + "image/character/ol_huangzhong.jpg", + "image/character/ol_huaxin.jpg", + "image/character/ol_huaxiong.jpg", + "image/character/ol_huban.jpg", + "image/character/ol_hujinding.jpg", + "image/character/ol_jiangwei.jpg", + "image/character/ol_jianyong.jpg", + "image/character/ol_lingtong.jpg", + "image/character/ol_lisu.jpg", + "image/character/ol_liuba.jpg", + "image/character/ol_liupi.jpg", + "image/character/ol_liushan.jpg", + "image/character/ol_liuyu.jpg", + "image/character/ol_liwan.jpg", + "image/character/ol_lukai.jpg", + "image/character/ol_lusu.jpg", + "image/character/ol_luyusheng.jpg", + "image/character/ol_maliang.jpg", + "image/character/ol_mengda.jpg", + "image/character/ol_pangde.jpg", + "image/character/ol_pangtong.jpg", + "image/character/ol_pengyang.jpg", + "image/character/ol_puyuan.jpg", + "image/character/ol_qianzhao.jpg", + "image/character/ol_sb_guanyu.jpg", + "image/character/ol_sb_jiangwei.jpg", + "image/character/ol_sb_taishici.jpg", + "image/character/ol_sb_yuanshao.jpg", + "image/character/ol_sb_yuanshao_shadow.jpg", + "image/character/ol_sp_zhugeliang.jpg", + "image/character/ol_sunjian.jpg", + "image/character/ol_wanglang.jpg", + "image/character/ol_wangrong.jpg", + "image/character/ol_wangyi.jpg", + "image/character/ol_weiyan.jpg", + "image/character/ol_wenqin.jpg", + "image/character/ol_xiahouyuan.jpg", + "image/character/ol_xiaoqiao.jpg", + "image/character/ol_xinxianying.jpg", + "image/character/ol_xuhuang.jpg", + "image/character/ol_xunyu.jpg", + "image/character/ol_yangyi.jpg", + "image/character/ol_yanwen.jpg", + "image/character/ol_yuanshao.jpg", + "image/character/ol_yuanshu.jpg", + "image/character/ol_yufan.jpg", + "image/character/ol_yujin.jpg", + "image/character/ol_zhangchangpu.jpg", + "image/character/ol_zhangliao.jpg", + "image/character/ol_zhangrang.jpg", + "image/character/ol_zhangyì.jpg", + "image/character/ol_zhangzhang.jpg", + "image/character/ol_zhouqun.jpg", + "image/character/ol_zhujun.jpg", + "image/character/ol_zhuling.jpg", + "image/character/ol_zhurong.jpg", + "image/character/old_bulianshi.jpg", + "image/character/old_caocao.jpg", + "image/character/old_caochong.jpg", + "image/character/old_caochun.jpg", + "image/character/old_caoren.jpg", + "image/character/old_caorui.jpg", + "image/character/old_caoxiu.jpg", + "image/character/old_caozhen.jpg", + "image/character/old_chendao.jpg", + "image/character/old_chenqun.jpg", + "image/character/old_dingfeng.jpg", + "image/character/old_fuhuanghou.jpg", + "image/character/old_gaoshun.jpg", + "image/character/old_guanqiujian.jpg", + "image/character/old_guanyinping.jpg", + "image/character/old_guanyu.jpg", + "image/character/old_guanzhang.jpg", + "image/character/old_handang.jpg", + "image/character/old_huangfusong.jpg", + "image/character/old_huanghao.jpg", + "image/character/old_huatuo.jpg", + "image/character/old_huaxiong.jpg", + "image/character/old_jiakui.jpg", + "image/character/old_lingju.jpg", + "image/character/old_lingtong.jpg", + "image/character/old_liubiao.jpg", + "image/character/old_liuzan.jpg", + "image/character/old_liyan.jpg", + "image/character/old_machao.jpg", + "image/character/old_madai.jpg", + "image/character/old_majun.jpg", + "image/character/old_maliang.jpg", + "image/character/old_quancong.jpg", + "image/character/old_re_lidian.jpg", + "image/character/old_shen_zhaoyun.jpg", + "image/character/old_shixie.jpg", + "image/character/old_wanglang.jpg", + "image/character/old_wangyi.jpg", + "image/character/old_wangyun.jpg", + "image/character/old_xiaoqiao.jpg", + "image/character/old_xusheng.jpg", + "image/character/old_yangyan.jpg", + "image/character/old_yangzhi.jpg", + "image/character/old_yuanshu.jpg", + "image/character/old_zhangfei.jpg", + "image/character/old_zhangxingcai.jpg", + "image/character/old_zhaoyun.jpg", + "image/character/old_zhonghui.jpg", + "image/character/old_zhoutai.jpg", + "image/character/old_zhugezhan.jpg", + "image/character/old_zhuhuan.jpg", + "image/character/old_zhuran.jpg", + "image/character/old_zhuzhi.jpg", + "image/character/oldre_liubiao.jpg", + "image/character/ow_ana.jpg", + "image/character/ow_banzang.jpg", + "image/character/ow_baolei.jpg", + "image/character/ow_chanyata.jpg", + "image/character/ow_dva.jpg", + "image/character/ow_falaozhiying.jpg", + "image/character/ow_heibaihe.jpg", + "image/character/ow_heiying.jpg", + "image/character/ow_kuangshu.jpg", + "image/character/ow_laiyinhate.jpg", + "image/character/ow_liekong.jpg", + "image/character/ow_luba.jpg", + "image/character/ow_luxiao.jpg", + "image/character/ow_maikelei.jpg", + "image/character/ow_mei.jpg", + "image/character/ow_orisa.jpg", + "image/character/ow_shibing.jpg", + "image/character/ow_sishen.jpg", + "image/character/ow_tianshi.jpg", + "image/character/ow_tuobiang.jpg", + "image/character/ow_wensidun.jpg", + "image/character/ow_yuanshi.jpg", + "image/character/ow_zhaliya.jpg", + "image/character/ow_zhixuzhiguang.jpg", + "image/character/pal_anu.jpg", + "image/character/pal_changqing.jpg", + "image/character/pal_hanlingsha.jpg", + "image/character/pal_jiangcheng.jpg", + "image/character/pal_jiangyunfan.jpg", + "image/character/pal_jingtian.jpg", + "image/character/pal_jushifang.jpg", + "image/character/pal_leiyuange.jpg", + "image/character/pal_linyueru.jpg", + "image/character/pal_liumengli.jpg", + "image/character/pal_lixiaoyao.jpg", + "image/character/pal_longkui.jpg", + "image/character/pal_longkuigui.jpg", + "image/character/pal_longyou.jpg", + "image/character/pal_luozhaoyan.jpg", + "image/character/pal_mingxiu.jpg", + "image/character/pal_muchanglan.jpg", + "image/character/pal_murongziying.jpg", + "image/character/pal_nangonghuang.jpg", + "image/character/pal_shenqishuang.jpg", + "image/character/pal_sumei.jpg", + "image/character/pal_tangyurou.jpg", + "image/character/pal_wangpengxu.jpg", + "image/character/pal_wangxiaohu.jpg", + "image/character/pal_wenhui.jpg", + "image/character/pal_xia.jpg", + "image/character/pal_xiahoujinxuan.jpg", + "image/character/pal_xianqing.jpg", + "image/character/pal_xiaoman.jpg", + "image/character/pal_xingxuan.jpg", + "image/character/pal_xuanxiao.jpg", + "image/character/pal_xuejian.jpg", + "image/character/pal_yuejinzhao.jpg", + "image/character/pal_yueqi.jpg", + "image/character/pal_yuntianhe.jpg", + "image/character/pal_zhaoliner.jpg", + "image/character/pal_zixuan.jpg", + "image/character/panfeng.jpg", + "image/character/pangde.jpg", + "image/character/pangdegong.jpg", + "image/character/panghui.jpg", + "image/character/pangshanmin.jpg", + "image/character/pangtong.jpg", + "image/character/panjun.jpg", + "image/character/panshu.jpg", + "image/character/panzhangmazhong.jpg", + "image/character/pe_mengda.jpg", + "image/character/pe_sunchen.jpg", + "image/character/pe_wangyun.jpg", + "image/character/pe_wenqin.jpg", + "image/character/pe_zhonghui.jpg", + "image/character/peixiu.jpg", + "image/character/peiyuanshao.jpg", + "image/character/pengyang.jpg", + "image/character/pk_sp_duyu.jpg", + "image/character/prp_zhugeliang.jpg", + "image/character/ps_caopi.jpg", + "image/character/ps_caozhi.jpg", + "image/character/ps_guanyu.jpg", + "image/character/ps_jiaxu.jpg", + "image/character/ps_jin_simayi.jpg", + "image/character/ps_lvbu.jpg", + "image/character/ps_machao.jpg", + "image/character/ps_shen_machao.jpg", + "image/character/ps_simayi.jpg", + "image/character/ps_zhugeliang.jpg", + "image/character/ps1059_guojia.jpg", + "image/character/ps1062_zhouyu.jpg", + "image/character/ps2063_zhaoyun.jpg", + "image/character/ps2066_zhugeliang.jpg", + "image/character/ps2067_zhaoyun.jpg", + "image/character/ps2068_simayi.jpg", + "image/character/ps2070_guojia.jpg", + "image/character/ps2080_zhouyu.jpg", + "image/character/pujing.jpg", + "image/character/puyuan.jpg", + "image/character/qianzhao.jpg", + "image/character/qiaogong.jpg", + "image/character/qiaorui.jpg", + "image/character/qiaozhou.jpg", + "image/character/qinghegongzhu.jpg", + "image/character/qinlang.jpg", + "image/character/qinmi.jpg", + "image/character/qinyilu.jpg", + "image/character/qiuliju.jpg", + "image/character/quancong.jpg", + "image/character/quanhuijie.jpg", + "image/character/quhuang.jpg", + "image/character/quyi.jpg", + "image/character/re_baosanniang.jpg", + "image/character/re_bulianshi.jpg", + "image/character/re_caifuren.jpg", + "image/character/re_caiwenji.jpg", + "image/character/re_caiyong.jpg", + "image/character/re_caocao.jpg", + "image/character/re_caochong.jpg", + "image/character/re_caopi.jpg", + "image/character/re_caorui.jpg", + "image/character/re_caoxiu.jpg", + "image/character/re_caozhang.jpg", + "image/character/re_caozhen.jpg", + "image/character/re_caozhi.jpg", + "image/character/re_chendeng.jpg", + "image/character/re_chengong.jpg", + "image/character/re_chengpu.jpg", + "image/character/re_chenqun.jpg", + "image/character/re_chunyuqiong.jpg", + "image/character/re_daqiao.jpg", + "image/character/re_dengai.jpg", + "image/character/re_dengzhi.jpg", + "image/character/re_dianwei.jpg", + "image/character/re_diaochan.jpg", + "image/character/re_dongbai.jpg", + "image/character/re_dongcheng.jpg", + "image/character/re_dongzhuo.jpg", + "image/character/re_duji.jpg", + "image/character/re_fazheng.jpg", + "image/character/re_fengfangnv.jpg", + "image/character/re_fuhuanghou.jpg", + "image/character/re_ganning.jpg", + "image/character/re_gaoshun.jpg", + "image/character/re_gongsunyuan.jpg", + "image/character/re_gongsunzan.jpg", + "image/character/re_guanping.jpg", + "image/character/re_guanqiujian.jpg", + "image/character/re_guanyu.jpg", + "image/character/re_guanzhang.jpg", + "image/character/re_guohuai.jpg", + "image/character/re_guohuanghou.jpg", + "image/character/re_guojia.jpg", + "image/character/re_guotufengji.jpg", + "image/character/re_guyong.jpg", + "image/character/re_handang.jpg", + "image/character/re_hanhaoshihuan.jpg", + "image/character/re_hansui.jpg", + "image/character/re_hejin.jpg", + "image/character/re_heqi.jpg", + "image/character/re_huanggai.jpg", + "image/character/re_huangyueying.jpg", + "image/character/re_huangzhong.jpg", + "image/character/re_huatuo.jpg", + "image/character/re_huaxiong.jpg", + "image/character/re_hucheer.jpg", + "image/character/re_jiangwei.jpg", + "image/character/re_jianyong.jpg", + "image/character/re_jiaxu.jpg", + "image/character/re_jikang.jpg", + "image/character/re_jsp_huangyueying.jpg", + "image/character/re_jsp_pangtong.jpg", + "image/character/re_jushou.jpg", + "image/character/re_kanze.jpg", + "image/character/re_liaohua.jpg", + "image/character/re_lidian.jpg", + "image/character/re_lingtong.jpg", + "image/character/re_liru.jpg", + "image/character/re_liubei.jpg", + "image/character/re_liubiao.jpg", + "image/character/re_liuchen.jpg", + "image/character/re_liufeng.jpg", + "image/character/re_liushan.jpg", + "image/character/re_liuzan.jpg", + "image/character/re_lusu.jpg", + "image/character/re_luxun.jpg", + "image/character/re_lvbu.jpg", + "image/character/re_lvmeng.jpg", + "image/character/re_machao.jpg", + "image/character/re_madai.jpg", + "image/character/re_maliang.jpg", + "image/character/re_manchong.jpg", + "image/character/re_masu.jpg", + "image/character/re_mazhong.jpg", + "image/character/re_menghuo.jpg", + "image/character/re_miheng.jpg", + "image/character/re_nanhualaoxian.jpg", + "image/character/re_niujin.jpg", + "image/character/re_panfeng.jpg", + "image/character/re_pangde.jpg", + "image/character/re_pangdegong.jpg", + "image/character/re_pangtong.jpg", + "image/character/re_panshu.jpg", + "image/character/re_panzhangmazhong.jpg", + "image/character/re_quancong.jpg", + "image/character/re_quyi.jpg", + "image/character/re_simayi.jpg", + "image/character/re_sp_taishici.jpg", + "image/character/re_sp_zhugeliang.jpg", + "image/character/re_sunben.jpg", + "image/character/re_sunce.jpg", + "image/character/re_sundeng.jpg", + "image/character/re_sunjian.jpg", + "image/character/re_sunluban.jpg", + "image/character/re_sunluyu.jpg", + "image/character/re_sunquan.jpg", + "image/character/re_sunshangxiang.jpg", + "image/character/re_sunxiu.jpg", + "image/character/re_sunyi.jpg", + "image/character/re_taishici.jpg", + "image/character/re_taoqian.jpg", + "image/character/re_wangyi.jpg", + "image/character/re_wangyun.jpg", + "image/character/re_weiwenzhugezhi.jpg", + "image/character/re_weiyan.jpg", + "image/character/re_wenpin.jpg", + "image/character/re_wuguotai.jpg", + "image/character/re_wuyi.jpg", + "image/character/re_xiahoudun.jpg", + "image/character/re_xiahoushi.jpg", + "image/character/re_xiahouyuan.jpg", + "image/character/re_xiaoqiao.jpg", + "image/character/re_xinxianying.jpg", + "image/character/re_xugong.jpg", + "image/character/re_xuhuang.jpg", + "image/character/re_xunchen.jpg", + "image/character/re_xunyou.jpg", + "image/character/re_xunyu.jpg", + "image/character/re_xusheng.jpg", + "image/character/re_xushu.jpg", + "image/character/re_xuzhu.jpg", + "image/character/re_yanwen.jpg", + "image/character/re_yuanshao.jpg", + "image/character/re_yuanshu.jpg", + "image/character/re_yufan.jpg", + "image/character/re_yuji.jpg", + "image/character/re_yujin.jpg", + "image/character/re_zhangbao.jpg", + "image/character/re_zhangchunhua.jpg", + "image/character/re_zhangfei.jpg", + "image/character/re_zhanggong.jpg", + "image/character/re_zhanghe.jpg", + "image/character/re_zhangjiao.jpg", + "image/character/re_zhangliang.jpg", + "image/character/re_zhangliao.jpg", + "image/character/re_zhangsong.jpg", + "image/character/re_zhangyi.jpg", + "image/character/re_zhangzhang.jpg", + "image/character/re_zhaoyun.jpg", + "image/character/re_zhenji.jpg", + "image/character/re_zhonghui.jpg", + "image/character/re_zhongyao.jpg", + "image/character/re_zhoucang.jpg", + "image/character/re_zhouyu.jpg", + "image/character/re_zhugeliang.jpg", + "image/character/re_zhuhuan.jpg", + "image/character/re_zhuran.jpg", + "image/character/re_zhurong.jpg", + "image/character/re_zhuzhi.jpg", + "image/character/re_zoushi.jpg", + "image/character/re_zuoci.jpg", + "image/character/ruanhui.jpg", + "image/character/ruanji.jpg", + "image/character/ruanyu.jpg", + "image/character/ruiji.jpg", + "image/character/sb_caocao.jpg", + "image/character/sb_caopi.jpg", + "image/character/sb_caoren.jpg", + "image/character/sb_chengong.jpg", + "image/character/sb_daqiao.jpg", + "image/character/sb_diaochan.jpg", + "image/character/sb_fazheng.jpg", + "image/character/sb_ganning.jpg", + "image/character/sb_guanyu.jpg", + "image/character/sb_huanggai.jpg", + "image/character/sb_huangyueying.jpg", + "image/character/sb_huangzhong.jpg", + "image/character/sb_huaxiong.jpg", + "image/character/sb_jiangwei.jpg", + "image/character/sb_liubei.jpg", + "image/character/sb_liubiao.jpg", + "image/character/sb_lvmeng.jpg", + "image/character/sb_machao.jpg", + "image/character/sb_menghuo.jpg", + "image/character/sb_pangtong.jpg", + "image/character/sb_sp_zhugeliang.jpg", + "image/character/sb_sunce.jpg", + "image/character/sb_sunquan.jpg", + "image/character/sb_sunshangxiang.jpg", + "image/character/sb_xiahoushi.jpg", + "image/character/sb_xiaoqiao.jpg", + "image/character/sb_xuhuang.jpg", + "image/character/sb_xunyu.jpg", + "image/character/sb_yl_luzhi.jpg", + "image/character/sb_yuanshao.jpg", + "image/character/sb_yujin.jpg", + "image/character/sb_zhangfei.jpg", + "image/character/sb_zhanghe.jpg", + "image/character/sb_zhangjiao.jpg", + "image/character/sb_zhaoyun.jpg", + "image/character/sb_zhenji.jpg", + "image/character/sb_zhouyu.jpg", + "image/character/sb_zhugeliang.jpg", + "image/character/sb_zhurong.jpg", + "image/character/scs_bilan.jpg", + "image/character/scs_bilan_dead.jpg", + "image/character/scs_duangui.jpg", + "image/character/scs_duangui_dead.jpg", + "image/character/scs_gaowang.jpg", + "image/character/scs_gaowang_dead.jpg", + "image/character/scs_guosheng.jpg", + "image/character/scs_guosheng_dead.jpg", + "image/character/scs_hankui.jpg", + "image/character/scs_hankui_dead.jpg", + "image/character/scs_lisong.jpg", + "image/character/scs_lisong_dead.jpg", + "image/character/scs_sunzhang.jpg", + "image/character/scs_sunzhang_dead.jpg", + "image/character/scs_xiayun.jpg", + "image/character/scs_xiayun_dead.jpg", + "image/character/scs_zhangrang.jpg", + "image/character/scs_zhangrang_dead.jpg", + "image/character/scs_zhaozhong.jpg", + "image/character/scs_zhaozhong_dead.jpg", + "image/character/shamoke.jpg", + "image/character/shen_caocao.jpg", + "image/character/shen_caopi.jpg", + "image/character/shen_dengai.jpg", + "image/character/shen_dianwei.jpg", + "image/character/shen_diaochan.jpg", + "image/character/shen_ganning.jpg", + "image/character/shen_guanyu.jpg", + "image/character/shen_guojia.jpg", + "image/character/shen_huatuo.jpg", + "image/character/shen_jiangwei.jpg", + "image/character/shen_jiaxu.jpg", + "image/character/shen_liubei.jpg", + "image/character/shen_lusu.jpg", + "image/character/shen_luxun.jpg", + "image/character/shen_lvbu.jpg", + "image/character/shen_lvmeng.jpg", + "image/character/shen_machao.jpg", + "image/character/shen_simayi.jpg", + "image/character/shen_sunce.jpg", + "image/character/shen_sunquan.jpg", + "image/character/shen_taishici.jpg", + "image/character/shen_xunyu.jpg", + "image/character/shen_xuzhu.jpg", + "image/character/shen_zhangfei.jpg", + "image/character/shen_zhangjiao.jpg", + "image/character/shen_zhangliao.jpg", + "image/character/shen_zhaoyun.jpg", + "image/character/shen_zhenji.jpg", + "image/character/shen_zhouyu.jpg", + "image/character/shen_zhugeliang.jpg", + "image/character/shenpei.jpg", + "image/character/shibao.jpg", + "image/character/shibing1.jpg", + "image/character/shibing2.jpg", + "image/character/shichangshi.jpg", + "image/character/shichangshi_dead.jpg", + "image/character/shixie.jpg", + "image/character/shiyi.jpg", + "image/character/simafu.jpg", + "image/character/simahui.jpg", + "image/character/simalang.jpg", + "image/character/simashi.jpg", + "image/character/simayi.jpg", + "image/character/simazhao.jpg", + "image/character/simazhou.jpg", + "image/character/sp_bianfuren.jpg", + "image/character/sp_caiwenji.jpg", + "image/character/sp_caoren.jpg", + "image/character/sp_caosong.jpg", + "image/character/sp_chendong.jpg", + "image/character/sp_chenzhen.jpg", + "image/character/sp_cuiyan.jpg", + "image/character/sp_daqiao.jpg", + "image/character/sp_diaochan.jpg", + "image/character/sp_dongzhuo.jpg", + "image/character/sp_duyu.jpg", + "image/character/sp_fuhuanghou.jpg", + "image/character/sp_fuwan.jpg", + "image/character/sp_ganning.jpg", + "image/character/sp_gaolan.jpg", + "image/character/sp_gongsunzan.jpg", + "image/character/sp_huaman.jpg", + "image/character/sp_huangfusong.jpg", + "image/character/sp_huaxin.jpg", + "image/character/sp_jianggan.jpg", + "image/character/sp_jiangqing.jpg", + "image/character/sp_jiangwan.jpg", + "image/character/sp_jiangwei.jpg", + "image/character/sp_jiaxu.jpg", + "image/character/sp_jiben.jpg", + "image/character/sp_key_kanade.jpg", + "image/character/sp_key_yuri.jpg", + "image/character/sp_kongrong.jpg", + "image/character/sp_liubei.jpg", + "image/character/sp_liuqi.jpg", + "image/character/sp_liuxie.jpg", + "image/character/sp_lvfan.jpg", + "image/character/sp_lvmeng.jpg", + "image/character/sp_machao.jpg", + "image/character/sp_maojie.jpg", + "image/character/sp_menghuo.jpg", + "image/character/sp_mifangfushiren.jpg", + "image/character/sp_mifuren.jpg", + "image/character/sp_mushun.jpg", + "image/character/sp_ol_zhanghe.jpg", + "image/character/sp_pangde.jpg", + "image/character/sp_pangtong.jpg", + "image/character/sp_pengyang.jpg", + "image/character/sp_shenpei.jpg", + "image/character/sp_simazhao.jpg", + "image/character/sp_sufei.jpg", + "image/character/sp_sunce.jpg", + "image/character/sp_sunshangxiang.jpg", + "image/character/sp_sunshao.jpg", + "image/character/sp_taishici.jpg", + "image/character/sp_wangcan.jpg", + "image/character/sp_wangshuang.jpg", + "image/character/sp_wangyuanji.jpg", + "image/character/sp_xiahoudun.jpg", + "image/character/sp_xiahoushi.jpg", + "image/character/sp_xinpi.jpg", + "image/character/sp_xinxianying.jpg", + "image/character/sp_xujing.jpg", + "image/character/sp_xunchen.jpg", + "image/character/sp_xuyou.jpg", + "image/character/sp_yanghu.jpg", + "image/character/sp_yangwan.jpg", + "image/character/sp_zhangchangpu.jpg", + "image/character/sp_zhangfei.jpg", + "image/character/sp_zhanghe.jpg", + "image/character/sp_zhangjiao.jpg", + "image/character/sp_zhangliao.jpg", + "image/character/sp_zhangwen.jpg", + "image/character/sp_zhaoyun.jpg", + "image/character/sp_zhugeliang.jpg", + "image/character/sp_zhujun.jpg", + "image/character/sp_zongyu.jpg", + "image/character/star_caoren.jpg", + "image/character/star_dongzhuo.jpg", + "image/character/star_yuanshao.jpg", + "image/character/star_yuanshu.jpg", + "image/character/star_zhangchunhua.jpg", + "image/character/std_panfeng.jpg", + "image/character/sunce.jpg", + "image/character/sunchen.jpg", + "image/character/sundeng.jpg", + "image/character/sunhanhua.jpg", + "image/character/sunhao.jpg", + "image/character/sunhong.jpg", + "image/character/sunhuan.jpg", + "image/character/sunjian.jpg", + "image/character/sunlang.jpg", + "image/character/sunli.jpg", + "image/character/sunliang.jpg", + "image/character/sunlingluan.jpg", + "image/character/sunluban.jpg", + "image/character/sunluyu.jpg", + "image/character/sunqian.jpg", + "image/character/sunquan.jpg", + "image/character/sunru.jpg", + "image/character/sunshangxiang.jpg", + "image/character/sunshao.jpg", + "image/character/sunwukong.jpg", + "image/character/sunxiu.jpg", + "image/character/sunyang.jpg", + "image/character/sunyi.jpg", + "image/character/sunyu.jpg", + "image/character/sunziliufang.jpg", + "image/character/swd_anka.jpg", + "image/character/swd_chenfu.jpg", + "image/character/swd_chengyaojin.jpg", + "image/character/swd_chenjingchou.jpg", + "image/character/swd_cheyun.jpg", + "image/character/swd_chunyuheng.jpg", + "image/character/swd_duanmeng.jpg", + "image/character/swd_duguningke.jpg", + "image/character/swd_duopeng.jpg", + "image/character/swd_fengtianling.jpg", + "image/character/swd_fengyu.jpg", + "image/character/swd_fu.jpg", + "image/character/swd_fuyan.jpg", + "image/character/swd_guyue.jpg", + "image/character/swd_haidapang.jpg", + "image/character/swd_hanlong.jpg", + "image/character/swd_hanluo.jpg", + "image/character/swd_hengai.jpg", + "image/character/swd_huanglei.jpg", + "image/character/swd_huanyuanzhi.jpg", + "image/character/swd_huiyan.jpg", + "image/character/swd_hupo.jpg", + "image/character/swd_huyue.jpg", + "image/character/swd_huzhongxian.jpg", + "image/character/swd_jialanduo.jpg", + "image/character/swd_jiangwu.jpg", + "image/character/swd_jiangziya.jpg", + "image/character/swd_jiliang.jpg", + "image/character/swd_jipeng.jpg", + "image/character/swd_jiting.jpg", + "image/character/swd_jiuyou.jpg", + "image/character/swd_kama.jpg", + "image/character/swd_kangnalishi.jpg", + "image/character/swd_kendi.jpg", + "image/character/swd_lanmoshen.jpg", + "image/character/swd_lanyin.jpg", + "image/character/swd_lilian.jpg", + "image/character/swd_linyue.jpg", + "image/character/swd_luchengxuan.jpg", + "image/character/swd_maixing.jpg", + "image/character/swd_miles.jpg", + "image/character/swd_moye.jpg", + "image/character/swd_murongshi.jpg", + "image/character/swd_muyue.jpg", + "image/character/swd_muyun.jpg", + "image/character/swd_nicole.jpg", + "image/character/swd_qi.jpg", + "image/character/swd_qiner.jpg", + "image/character/swd_qinshubao.jpg", + "image/character/swd_quxian.jpg", + "image/character/swd_rongshuang.jpg", + "image/character/swd_septem.jpg", + "image/character/swd_shangzhang.jpg", + "image/character/swd_shanxiaoxiao.jpg", + "image/character/swd_shaowei.jpg", + "image/character/swd_shuijing.jpg", + "image/character/swd_shuwaner.jpg", + "image/character/swd_sikongyu.jpg", + "image/character/swd_situqiang.jpg", + "image/character/swd_tuobayuer.jpg", + "image/character/swd_tuwei.jpg", + "image/character/swd_wangsiyue.jpg", + "image/character/swd_weida.jpg", + "image/character/swd_wushi.jpg", + "image/character/swd_xiaohuanglong.jpg", + "image/character/swd_xiarou.jpg", + "image/character/swd_xiyan.jpg", + "image/character/swd_xuanyuanjiantong.jpg", + "image/character/swd_xuanyuanjianxian.jpg", + "image/character/swd_yeyaxi.jpg", + "image/character/swd_youzhao.jpg", + "image/character/swd_yuchiyanhong.jpg", + "image/character/swd_yuli.jpg", + "image/character/swd_yunhu.jpg", + "image/character/swd_yuwentuo.jpg", + "image/character/swd_yuxiaoxue.jpg", + "image/character/swd_zhanggao.jpg", + "image/character/swd_zhaoyun.jpg", + "image/character/swd_zhiyin.jpg", + "image/character/swd_zhuoshanzhu.jpg", + "image/character/swd_zidashu.jpg", + "image/character/swd_ziqiao.jpg", + "image/character/tadun.jpg", + "image/character/taishici.jpg", + "image/character/tangji.jpg", + "image/character/tangzi.jpg", + "image/character/taoqian.jpg", + "image/character/taoshen.jpg", + "image/character/tengfanglan.jpg", + "image/character/tenggongzhu.jpg", + "image/character/tengyin.jpg", + "image/character/tianchou.jpg", + "image/character/tianfeng.jpg", + "image/character/tianshangyi.jpg", + "image/character/tianyu.jpg", + "image/character/tongyuan.jpg", + "image/character/tw_baoxin.jpg", + "image/character/tw_beimihu.jpg", + "image/character/tw_bianfuren.jpg", + "image/character/tw_bingyuan.jpg", + "image/character/tw_caoang.jpg", + "image/character/tw_caocao.jpg", + "image/character/tw_caohong.jpg", + "image/character/tw_caoxiu.jpg", + "image/character/tw_caozhao.jpg", + "image/character/tw_chendong.jpg", + "image/character/tw_chengpu.jpg", + "image/character/tw_chenzhen.jpg", + "image/character/tw_daxiaoqiao.jpg", + "image/character/tw_dengzhi.jpg", + "image/character/tw_dingfeng.jpg", + "image/character/tw_dongzhao.jpg", + "image/character/tw_fanchou.jpg", + "image/character/tw_feiyi.jpg", + "image/character/tw_fengxí.jpg", + "image/character/tw_furong.jpg", + "image/character/tw_fuwan.jpg", + "image/character/tw_gexuan.jpg", + "image/character/tw_gongsunfan.jpg", + "image/character/tw_guanqiujian.jpg", + "image/character/tw_guohuai.jpg", + "image/character/tw_guyong.jpg", + "image/character/tw_handang.jpg", + "image/character/tw_haomeng.jpg", + "image/character/tw_hejin.jpg", + "image/character/tw_hucheer.jpg", + "image/character/tw_huchuquan.jpg", + "image/character/tw_huojun.jpg", + "image/character/tw_jiangji.jpg", + "image/character/tw_jiangqing.jpg", + "image/character/tw_jianshuo.jpg", + "image/character/tw_jiling.jpg", + "image/character/tw_liufuren.jpg", + "image/character/tw_liuhong.jpg", + "image/character/tw_liuzhang.jpg", + "image/character/tw_liwei.jpg", + "image/character/tw_madai.jpg", + "image/character/tw_maliang.jpg", + "image/character/tw_mateng.jpg", + "image/character/tw_mayunlu.jpg", + "image/character/tw_menghuo.jpg", + "image/character/tw_niufudongxie.jpg", + "image/character/tw_niujin.jpg", + "image/character/tw_ol_sunjian.jpg", + "image/character/tw_puyangxing.jpg", + "image/character/tw_qiaogong.jpg", + "image/character/tw_qiaorui.jpg", + "image/character/tw_re_caohong.jpg", + "image/character/tw_re_fazheng.jpg", + "image/character/tw_shen_guanyu.jpg", + "image/character/tw_shen_lvmeng.jpg", + "image/character/tw_sunyi.jpg", + "image/character/tw_tianyu.jpg", + "image/character/tw_wangcan.jpg", + "image/character/tw_wangchang.jpg", + "image/character/tw_wangling.jpg", + "image/character/tw_weixu.jpg", + "image/character/tw_wenchou.jpg", + "image/character/tw_wujing.jpg", + "image/character/tw_xiahouba.jpg", + "image/character/tw_xiahouen.jpg", + "image/character/tw_xiahoushang.jpg", + "image/character/tw_xuezong.jpg", + "image/character/tw_xujing.jpg", + "image/character/tw_xunchen.jpg", + "image/character/tw_yangang.jpg", + "image/character/tw_yangyi.jpg", + "image/character/tw_yanliang.jpg", + "image/character/tw_yanxiang.jpg", + "image/character/tw_yl_luzhi.jpg", + "image/character/tw_yuantan.jpg", + "image/character/tw_yufuluo.jpg", + "image/character/tw_yujin.jpg", + "image/character/tw_zangba.jpg", + "image/character/tw_zhangfei.jpg", + "image/character/tw_zhanghong.jpg", + "image/character/tw_zhangji.jpg", + "image/character/tw_zhangmancheng.jpg", + "image/character/tw_zhangnan.jpg", + "image/character/tw_zhangning.jpg", + "image/character/tw_zhangzhao.jpg", + "image/character/tw_zhaoxiang.jpg", + "image/character/tw_zhouchu.jpg", + "image/character/tw_zhugeguo.jpg", + "image/character/tw_zongyu.jpg", + "image/character/tw_zumao.jpg", + "image/character/vtb_xiaojiu.jpg", + "image/character/vtb_xiaole.jpg", + "image/character/vtb_xiaosha.jpg", + "image/character/vtb_xiaoshan.jpg", + "image/character/vtb_xiaotao.jpg", + "image/character/wangcan.jpg", + "image/character/wangfuzhaolei.jpg", + "image/character/wangguan.jpg", + "image/character/wangji.jpg", + "image/character/wangjun.jpg", + "image/character/wanglang.jpg", + "image/character/wanglie.jpg", + "image/character/wangling.jpg", + "image/character/wangping.jpg", + "image/character/wangrong.jpg", + "image/character/wangshuang.jpg", + "image/character/wangtao.jpg", + "image/character/wangwei.jpg", + "image/character/wangxiang.jpg", + "image/character/wangyan.jpg", + "image/character/wangyi.jpg", + "image/character/wangyuanji.jpg", + "image/character/wangyue.jpg", + "image/character/wangyun.jpg", + "image/character/wanniangongzhu.jpg", + "image/character/weiguan.jpg", + "image/character/weiwenzhugezhi.jpg", + "image/character/weiyan.jpg", + "image/character/weizi.jpg", + "image/character/wenpin.jpg", + "image/character/wenqin.jpg", + "image/character/wenyang.jpg", + "image/character/wolongfengchu.jpg", + "image/character/wu_luxun.jpg", + "image/character/wu_zhugeliang.jpg", + "image/character/wu_zhutiexiong.jpg", + "image/character/wuanguo.jpg", + "image/character/wuban.jpg", + "image/character/wufan.jpg", + "image/character/wuguotai.jpg", + "image/character/wujing.jpg", + "image/character/wulan.jpg", + "image/character/wutugu.jpg", + "image/character/wuxian.jpg", + "image/character/wuyan.jpg", + "image/character/wuyi.jpg", + "image/character/xf_huangquan.jpg", + "image/character/xf_sufei.jpg", + "image/character/xf_tangzi.jpg", + "image/character/xf_yiji.jpg", + "image/character/xia_dianwei.jpg", + "image/character/xia_guanyu.jpg", + "image/character/xia_liubei.jpg", + "image/character/xia_liyàn.jpg", + "image/character/xia_lusu.jpg", + "image/character/xia_shie.jpg", + "image/character/xia_shitao.jpg", + "image/character/xia_tongyuan.jpg", + "image/character/xia_wangyue.jpg", + "image/character/xia_xiahoudun.jpg", + "image/character/xia_xiahousone.jpg", + "image/character/xia_xiahouzie.jpg", + "image/character/xia_xushu.jpg", + "image/character/xia_yuzhenzi.jpg", + "image/character/xia_zhangwei.jpg", + "image/character/xia_zhaoe.jpg", + "image/character/xiahouba.jpg", + "image/character/xiahoudun.jpg", + "image/character/xiahoujie.jpg", + "image/character/xiahoulingnv.jpg", + "image/character/xiahoumao.jpg", + "image/character/xiahoushi.jpg", + "image/character/xiahouxuan.jpg", + "image/character/xiahouyuan.jpg", + "image/character/xiangchong.jpg", + "image/character/xianglang.jpg", + "image/character/xiaoqiao.jpg", + "image/character/xiaoyuehankehan.jpg", + "image/character/xielingyu.jpg", + "image/character/xin_baosanniang.jpg", + "image/character/xin_caifuren.jpg", + "image/character/xin_caoxiu.jpg", + "image/character/xin_caozhang.jpg", + "image/character/xin_caozhen.jpg", + "image/character/xin_chengpu.jpg", + "image/character/xin_fazheng.jpg", + "image/character/xin_fuhuanghou.jpg", + "image/character/xin_gaoshun.jpg", + "image/character/xin_gongsunzan.jpg", + "image/character/xin_guohuai.jpg", + "image/character/xin_guozhao.jpg", + "image/character/xin_guyong.jpg", + "image/character/xin_handang.jpg", + "image/character/xin_hansui.jpg", + "image/character/xin_jianyong.jpg", + "image/character/xin_jushou.jpg", + "image/character/xin_liaohua.jpg", + "image/character/xin_lingtong.jpg", + "image/character/xin_liru.jpg", + "image/character/xin_liubiao.jpg", + "image/character/xin_mamidi.jpg", + "image/character/xin_masu.jpg", + "image/character/xin_panzhangmazhong.jpg", + "image/character/xin_quancong.jpg", + "image/character/xin_sunliang.jpg", + "image/character/xin_sunluban.jpg", + "image/character/xin_sunxiu.jpg", + "image/character/xin_wuguotai.jpg", + "image/character/xin_wuyi.jpg", + "image/character/xin_xiahoudun.jpg", + "image/character/xin_xusheng.jpg", + "image/character/xin_xushu.jpg", + "image/character/xin_yuanshao.jpg", + "image/character/xin_yufan.jpg", + "image/character/xin_yuji.jpg", + "image/character/xin_yujin.jpg", + "image/character/xin_zhangfei.jpg", + "image/character/xin_zhangyi.jpg", + "image/character/xin_zhonghui.jpg", + "image/character/xin_zhoucang.jpg", + "image/character/xin_zhoutai.jpg", + "image/character/xin_zhuhuan.jpg", + "image/character/xin_zhuran.jpg", + "image/character/xin_zhuzhi.jpg", + "image/character/xinchang.jpg", + "image/character/xingdaorong.jpg", + "image/character/xinpi.jpg", + "image/character/xinping.jpg", + "image/character/xinxianying.jpg", + "image/character/xizheng.jpg", + "image/character/xizhicai.jpg", + "image/character/xuangongzhu.jpg", + "image/character/xuelingyun.jpg", + "image/character/xuezong.jpg", + "image/character/xugong.jpg", + "image/character/xuhuang.jpg", + "image/character/xujing.jpg", + "image/character/xunchen.jpg", + "image/character/xunyou.jpg", + "image/character/xunyu.jpg", + "image/character/xurong.jpg", + "image/character/xushao.jpg", + "image/character/xusheng.jpg", + "image/character/xushi.jpg", + "image/character/xushu.jpg", + "image/character/xuyou.jpg", + "image/character/xuzhu.jpg", + "image/character/yanbaihu.jpg", + "image/character/yanfuren.jpg", + "image/character/yangbiao.jpg", + "image/character/yangfu.jpg", + "image/character/yanghong.jpg", + "image/character/yanghuiyu.jpg", + "image/character/yangwan.jpg", + "image/character/yangxiu.jpg", + "image/character/yangyan.jpg", + "image/character/yangyi.jpg", + "image/character/yangzhi.jpg", + "image/character/yanjun.jpg", + "image/character/yanpu.jpg", + "image/character/yanrou.jpg", + "image/character/yanwen.jpg", + "image/character/yanxiang.jpg", + "image/character/yanyan.jpg", + "image/character/yeshiwen.jpg", + "image/character/yinfuren.jpg", + "image/character/yj_caoang.jpg", + "image/character/yj_caocao.jpg", + "image/character/yj_caohong.jpg", + "image/character/yj_dongzhuo.jpg", + "image/character/yj_ganning.jpg", + "image/character/yj_huangzhong.jpg", + "image/character/yj_jiaxu.jpg", + "image/character/yj_jushou.jpg", + "image/character/yj_liru.jpg", + "image/character/yj_qiaozhou.jpg", + "image/character/yj_sufei.jpg", + "image/character/yj_weiyan.jpg", + "image/character/yj_xuhuang.jpg", + "image/character/yj_xuyou.jpg", + "image/character/yj_zhangfei.jpg", + "image/character/yj_zhanghe.jpg", + "image/character/yj_zhangliao.jpg", + "image/character/yj_zhenji.jpg", + "image/character/yj_zhoubuyi.jpg", + "image/character/yl_luzhi.jpg", + "image/character/yl_yuanshu.jpg", + "image/character/yongjian_ganning.jpg", + "image/character/yuanhuan.jpg", + "image/character/yuanji.jpg", + "image/character/yuanshu.jpg", + "image/character/yuantanyuanshang.jpg", + "image/character/yuantanyuanxiyuanshang.jpg", + "image/character/yue_caiwenji.jpg", + "image/character/yue_daqiao.jpg", + "image/character/yue_xiaoqiao.jpg", + "image/character/yue_zhoufei.jpg", + "image/character/yuechen.jpg", + "image/character/yuejin.jpg", + "image/character/yuejiu.jpg", + "image/character/yufan.jpg", + "image/character/yuji.jpg", + "image/character/yujin.jpg", + "image/character/yujin_yujin.jpg", + "image/character/yxs_aijiyanhou.jpg", + "image/character/yxs_baosi.jpg", + "image/character/yxs_bole.jpg", + "image/character/yxs_caocao.jpg", + "image/character/yxs_chengjisihan.jpg", + "image/character/yxs_chengyaojin.jpg", + "image/character/yxs_diaochan.jpg", + "image/character/yxs_direnjie.jpg", + "image/character/yxs_fuermosi.jpg", + "image/character/yxs_goujian.jpg", + "image/character/yxs_guiguzi.jpg", + "image/character/yxs_handingdun.jpg", + "image/character/yxs_huamulan.jpg", + "image/character/yxs_jinke.jpg", + "image/character/yxs_kaisa.jpg", + "image/character/yxs_lanlinwang.jpg", + "image/character/yxs_libai.jpg", + "image/character/yxs_lishimin.jpg", + "image/character/yxs_luban.jpg", + "image/character/yxs_luobinhan.jpg", + "image/character/yxs_luocheng.jpg", + "image/character/yxs_luzhishen.jpg", + "image/character/yxs_lvzhi.jpg", + "image/character/yxs_meixi.jpg", + "image/character/yxs_mingchenghuanghou.jpg", + "image/character/yxs_mozi.jpg", + "image/character/yxs_nandinggeer.jpg", + "image/character/yxs_napolun.jpg", + "image/character/yxs_qinqiong.jpg", + "image/character/yxs_sunwu.jpg", + "image/character/yxs_tangbohu.jpg", + "image/character/yxs_wangzhaojun.jpg", + "image/character/yxs_weizhongxian.jpg", + "image/character/yxs_wuzetian.jpg", + "image/character/yxs_xiangyu.jpg", + "image/character/yxs_xiaoqiao.jpg", + "image/character/yxs_yangguang.jpg", + "image/character/yxs_yangyuhuan.jpg", + "image/character/yxs_yingzheng.jpg", + "image/character/yxs_yuefei.jpg", + "image/character/yxs_yujix.jpg", + "image/character/yxs_zhangsanfeng.jpg", + "image/character/yxs_zhaoyong.jpg", + "image/character/yxs_zhuyuanzhang.jpg", + "image/character/zangba.jpg", + "image/character/zerong.jpg", + "image/character/zhangbao.jpg", + "image/character/zhangchangpu.jpg", + "image/character/zhangchu.jpg", + "image/character/zhangchunhua.jpg", + "image/character/zhangfei.jpg", + "image/character/zhangfen.jpg", + "image/character/zhanggong.jpg", + "image/character/zhanghe.jpg", + "image/character/zhangheng.jpg", + "image/character/zhanghu.jpg", + "image/character/zhanghua.jpg", + "image/character/zhanghuyuechen.jpg", + "image/character/zhangji.jpg", + "image/character/zhangjiao.jpg", + "image/character/zhangjinyun.jpg", + "image/character/zhangkai.jpg", + "image/character/zhangliang.jpg", + "image/character/zhangliao.jpg", + "image/character/zhangling.jpg", + "image/character/zhanglu.jpg", + "image/character/zhangmiao.jpg", + "image/character/zhangning.jpg", + "image/character/zhangqiying.jpg", + "image/character/zhangrang.jpg", + "image/character/zhangren.jpg", + "image/character/zhangshiping.jpg", + "image/character/zhangsong.jpg", + "image/character/zhangwen.jpg", + "image/character/zhangxingcai.jpg", + "image/character/zhangxiu.jpg", + "image/character/zhangxuan.jpg", + "image/character/zhangxun.jpg", + "image/character/zhangyan.jpg", + "image/character/zhangyao.jpg", + "image/character/zhangyi.jpg", + "image/character/zhangyì.jpg", + "image/character/zhangzhang.jpg", + "image/character/zhangzhi.jpg", + "image/character/zhangzhongjing.jpg", + "image/character/zhaoang.jpg", + "image/character/zhaotongzhaoguang.jpg", + "image/character/zhaoxiang.jpg", + "image/character/zhaoyan.jpg", + "image/character/zhaoyǎn.jpg", + "image/character/zhaoyun.jpg", + "image/character/zhaozhi.jpg", + "image/character/zhaozhong.jpg", + "image/character/zhenghun.jpg", + "image/character/zhengxuan.jpg", + "image/character/zhenji.jpg", + "image/character/zhonghui.jpg", + "image/character/zhongyan.jpg", + "image/character/zhongyao.jpg", + "image/character/zhoubuyi.jpg", + "image/character/zhoucang.jpg", + "image/character/zhouchu.jpg", + "image/character/zhoufang.jpg", + "image/character/zhoufei.jpg", + "image/character/zhouqun.jpg", + "image/character/zhoushan.jpg", + "image/character/zhoutai.jpg", + "image/character/zhouyi.jpg", + "image/character/zhouyu.jpg", + "image/character/zhugedan.jpg", + "image/character/zhugeguo.jpg", + "image/character/zhugejin.jpg", + "image/character/zhugeke.jpg", + "image/character/zhugeliang.jpg", + "image/character/zhugemengxue.jpg", + "image/character/zhugeruoxue.jpg", + "image/character/zhugeshang.jpg", + "image/character/zhugezhan.jpg", + "image/character/zhuhuan.jpg", + "image/character/zhujianping.jpg", + "image/character/zhujun.jpg", + "image/character/zhuling.jpg", + "image/character/zhuran.jpg", + "image/character/zhurong.jpg", + "image/character/zhutiexiong.jpg", + "image/character/zhuzhi.jpg", + "image/character/zongyu.jpg", + "image/character/zoushi.jpg", + "image/character/zumao.jpg", + "image/character/zuoci.jpg", + "image/character/zuofen.jpg", + /*character image end*/ + + "image/emotion/shibing_emotion/1.gif", + "image/emotion/shibing_emotion/2.gif", + "image/emotion/shibing_emotion/3.gif", + "image/emotion/shibing_emotion/4.gif", + "image/emotion/shibing_emotion/5.gif", + "image/emotion/shibing_emotion/6.gif", + "image/emotion/shibing_emotion/7.gif", + "image/emotion/shibing_emotion/8.gif", + "image/emotion/shibing_emotion/9.gif", + "image/emotion/shibing_emotion/10.gif", + "image/emotion/shibing_emotion/11.gif", + "image/emotion/shibing_emotion/12.gif", + "image/emotion/shibing_emotion/13.gif", + "image/emotion/shibing_emotion/14.gif", + "image/emotion/shibing_emotion/15.gif", + "image/emotion/guojia_emotion/1.gif", + "image/emotion/guojia_emotion/2.gif", + "image/emotion/guojia_emotion/3.gif", + "image/emotion/guojia_emotion/4.gif", + "image/emotion/guojia_emotion/5.gif", + "image/emotion/guojia_emotion/6.gif", + "image/emotion/guojia_emotion/7.gif", + "image/emotion/guojia_emotion/8.gif", + "image/emotion/guojia_emotion/9.gif", + "image/emotion/guojia_emotion/10.gif", + "image/emotion/guojia_emotion/11.gif", + "image/emotion/guojia_emotion/12.gif", + "image/emotion/guojia_emotion/13.gif", + "image/emotion/guojia_emotion/14.gif", + "image/emotion/guojia_emotion/15.gif", + "image/emotion/guojia_emotion/16.gif", + "image/emotion/guojia_emotion/17.gif", + "image/emotion/guojia_emotion/18.gif", + "image/emotion/guojia_emotion/19.gif", + "image/emotion/guojia_emotion/20.gif", + "image/emotion/zhenji_emotion/1.gif", + "image/emotion/zhenji_emotion/2.gif", + "image/emotion/zhenji_emotion/3.gif", + "image/emotion/zhenji_emotion/4.gif", + "image/emotion/zhenji_emotion/5.gif", + "image/emotion/zhenji_emotion/6.gif", + "image/emotion/zhenji_emotion/7.gif", + "image/emotion/zhenji_emotion/8.gif", + "image/emotion/zhenji_emotion/9.gif", + "image/emotion/zhenji_emotion/10.gif", + "image/emotion/zhenji_emotion/11.gif", + "image/emotion/zhenji_emotion/12.gif", + "image/emotion/zhenji_emotion/13.gif", + "image/emotion/zhenji_emotion/14.gif", + "image/emotion/zhenji_emotion/15.gif", + "image/emotion/zhenji_emotion/16.gif", + "image/emotion/zhenji_emotion/17.gif", + "image/emotion/zhenji_emotion/18.gif", + "image/emotion/zhenji_emotion/19.gif", + "image/emotion/zhenji_emotion/20.gif", + "image/emotion/xiaojiu_emotion/1.gif", + "image/emotion/xiaojiu_emotion/2.gif", + "image/emotion/xiaojiu_emotion/3.gif", + "image/emotion/xiaojiu_emotion/4.gif", + "image/emotion/xiaojiu_emotion/5.gif", + "image/emotion/xiaojiu_emotion/6.gif", + "image/emotion/xiaojiu_emotion/7.gif", + "image/emotion/xiaojiu_emotion/8.gif", + "image/emotion/xiaojiu_emotion/9.gif", + "image/emotion/xiaojiu_emotion/10.gif", + "image/emotion/xiaojiu_emotion/11.gif", + "image/emotion/xiaojiu_emotion/12.gif", + "image/emotion/xiaojiu_emotion/13.gif", + "image/emotion/xiaojiu_emotion/14.gif", + "image/emotion/xiaojiu_emotion/15.gif", + "image/emotion/xiaojiu_emotion/16.gif", + "image/emotion/xiaojiu_emotion/17.gif", + "image/emotion/xiaojiu_emotion/18.gif", + "image/emotion/xiaojiu_emotion/19.gif", + "image/emotion/xiaojiu_emotion/20.gif", + "image/emotion/xiaokuo_emotion/1.gif", + "image/emotion/xiaokuo_emotion/2.gif", + "image/emotion/xiaokuo_emotion/3.gif", + "image/emotion/xiaokuo_emotion/4.gif", + "image/emotion/xiaokuo_emotion/5.gif", + "image/emotion/xiaokuo_emotion/6.gif", + "image/emotion/xiaokuo_emotion/7.gif", + "image/emotion/xiaokuo_emotion/8.gif", + "image/emotion/xiaosha_emotion/1.gif", + "image/emotion/xiaosha_emotion/2.gif", + "image/emotion/xiaosha_emotion/3.gif", + "image/emotion/xiaosha_emotion/4.gif", + "image/emotion/xiaosha_emotion/5.gif", + "image/emotion/xiaosha_emotion/6.gif", + "image/emotion/xiaosha_emotion/7.gif", + "image/emotion/xiaosha_emotion/8.gif", + "image/emotion/xiaosha_emotion/9.gif", + "image/emotion/xiaosha_emotion/10.gif", + "image/emotion/xiaosha_emotion/11.gif", + "image/emotion/xiaosha_emotion/12.gif", + "image/emotion/xiaosha_emotion/13.gif", + "image/emotion/xiaosha_emotion/14.gif", + "image/emotion/xiaosha_emotion/15.gif", + "image/emotion/xiaosha_emotion/16.gif", + "image/emotion/xiaosha_emotion/17.gif", + "image/emotion/xiaosha_emotion/18.gif", + "image/emotion/xiaosha_emotion/19.gif", + "image/emotion/xiaosha_emotion/20.gif", + "image/emotion/xiaotao_emotion/1.gif", + "image/emotion/xiaotao_emotion/2.gif", + "image/emotion/xiaotao_emotion/3.gif", + "image/emotion/xiaotao_emotion/4.gif", + "image/emotion/xiaotao_emotion/5.gif", + "image/emotion/xiaotao_emotion/6.gif", + "image/emotion/xiaotao_emotion/7.gif", + "image/emotion/xiaotao_emotion/8.gif", + "image/emotion/xiaotao_emotion/9.gif", + "image/emotion/xiaotao_emotion/10.gif", + "image/emotion/xiaotao_emotion/11.gif", + "image/emotion/xiaotao_emotion/12.gif", + "image/emotion/xiaotao_emotion/13.gif", + "image/emotion/xiaotao_emotion/14.gif", + "image/emotion/xiaotao_emotion/15.gif", + "image/emotion/xiaotao_emotion/16.gif", + "image/emotion/xiaotao_emotion/17.gif", + "image/emotion/xiaotao_emotion/18.gif", + "image/emotion/xiaotao_emotion/19.gif", + "image/emotion/xiaotao_emotion/20.gif", + "image/emotion/xiaowu_emotion/1.gif", + "image/emotion/xiaowu_emotion/2.gif", + "image/emotion/xiaowu_emotion/3.gif", + "image/emotion/xiaowu_emotion/4.gif", + "image/emotion/xiaowu_emotion/5.gif", + "image/emotion/xiaowu_emotion/6.gif", + "image/emotion/xiaowu_emotion/7.gif", + "image/emotion/xiaowu_emotion/8.gif", + "image/emotion/xiaowu_emotion/9.gif", + "image/emotion/xiaowu_emotion/10.gif", + "image/emotion/xiaowu_emotion/11.gif", + "image/emotion/xiaowu_emotion/12.gif", + "image/emotion/xiaowu_emotion/13.gif", + "image/emotion/xiaowu_emotion/14.gif", + "image/emotion/throw_emotion/egg1.png", + "image/emotion/throw_emotion/egg2.png", + "image/emotion/throw_emotion/flower1.png", + "image/emotion/throw_emotion/flower2.png", + "image/emotion/throw_emotion/shoe1.png", + "image/emotion/throw_emotion/shoe2.png", + "image/emotion/throw_emotion/jiasuo1.png", + "image/emotion/throw_emotion/jiasuo2.png", + "image/emotion/throw_emotion/wine1.png", + "image/emotion/throw_emotion/wine2.png", + "image/emotion/throw_emotion/yuxisx1.png", + "image/emotion/throw_emotion/yuxisx2.png", + + "image/mode/boss/card/chixueqingfeng.png", + "image/mode/boss/card/chiyanzhenhunqin.png", + "image/mode/boss/card/guilongzhanyuedao.png", + "image/mode/boss/card/guofengyupao.png", + "image/mode/boss/card/honghuangzhili.png", + "image/mode/boss/card/hongmianbaihuapao.png", + "image/mode/boss/card/juechenjinge.png", + "image/mode/boss/card/linglongshimandai.png", + "image/mode/boss/card/qimenbagua.png", + "image/mode/boss/card/sadouchengbing.png", + "image/mode/boss/card/shufazijinguan.png", + "image/mode/boss/card/wushuangfangtianji.png", + "image/mode/boss/card/xiuluolianyuji.png", + "image/mode/boss/card/xuwangzhimian.png", + "image/mode/boss/card/yihuajiemu.png", + "image/mode/boss/card/qicaishenlu.png", + "image/mode/boss/card/longfenghemingjian.png", + "image/mode/boss/card/boss_mengpohuihun.png", + "image/mode/boss/card/gubuzifeng.png", + "image/mode/boss/card/jinwuluorigong.png", + "image/mode/boss/card/lingsheji.png", + "image/mode/boss/card/shanrangzhaoshu.png", + "image/mode/boss/card/xingtianpojunfu.png", + "image/mode/boss/card/niaobaidaowenha.png", + + "image/mode/boss/character/boss_baihu.jpg", + "image/mode/boss/character/boss_baimangshilian.jpg", + "image/mode/boss/character/boss_baiwuchang.jpg", + "image/mode/boss/character/boss_bianchengwang.jpg", + "image/mode/boss/character/boss_bifang.jpg", + "image/mode/boss/character/boss_caiwenji.jpg", + "image/mode/boss/character/boss_caocao.jpg", + "image/mode/boss/character/boss_chi.jpg", + "image/mode/boss/character/boss_chiyanshilian.jpg", + "image/mode/boss/character/boss_chujiangwang.jpg", + "image/mode/boss/character/boss_diaochan.jpg", + "image/mode/boss/character/boss_dizangwang.jpg", + "image/mode/boss/character/boss_dongzhuo.jpg", + "image/mode/boss/character/boss_dushiwang.jpg", + "image/mode/boss/character/boss_guojia.jpg", + "image/mode/boss/character/boss_heiwuchang.jpg", + "image/mode/boss/character/boss_huangyueying.jpg", + "image/mode/boss/character/boss_huatuo.jpg", + "image/mode/boss/character/boss_hundun.jpg", + "image/mode/boss/character/boss_huoshenzhurong.jpg", + "image/mode/boss/character/boss_jinshenrushou.jpg", + "image/mode/boss/character/boss_liang.jpg", + "image/mode/boss/character/boss_liubei.jpg", + "image/mode/boss/character/boss_luocha.jpg", + "image/mode/boss/character/boss_luxun.jpg", + "image/mode/boss/character/boss_lvbu1.jpg", + "image/mode/boss/character/boss_lvbu2.jpg", + "image/mode/boss/character/boss_lvbu3.jpg", + "image/mode/boss/character/boss_mamian.jpg", + "image/mode/boss/character/boss_mengpo.jpg", + "image/mode/boss/character/boss_mingxingzhu.jpg", + "image/mode/boss/character/boss_mo.jpg", + "image/mode/boss/character/boss_mushengoumang.jpg", + "image/mode/boss/character/boss_nianshou.jpg", + "image/mode/boss/character/boss_nianshou_baonu.jpg", + "image/mode/boss/character/boss_nianshou_heti.jpg", + "image/mode/boss/character/boss_nianshou_jingjue.jpg", + "image/mode/boss/character/boss_nianshou_renxing.jpg", + "image/mode/boss/character/boss_nianshou_ruizhi.jpg", + "image/mode/boss/character/boss_niutou.jpg", + "image/mode/boss/character/boss_pangtong.jpg", + "image/mode/boss/character/boss_pingdengwang.jpg", + "image/mode/boss/character/boss_qinglong.jpg", + "image/mode/boss/character/boss_qingmushilian.jpg", + "image/mode/boss/character/boss_qinguangwang.jpg", + "image/mode/boss/character/boss_qiongqi.jpg", + "image/mode/boss/character/boss_satan.jpg", + "image/mode/boss/character/boss_shaohao.jpg", + "image/mode/boss/character/boss_shuijing.jpg", + "image/mode/boss/character/boss_shuishengonggong.jpg", + "image/mode/boss/character/boss_shuishenxuanming.jpg", + "image/mode/boss/character/boss_shujing.jpg", + "image/mode/boss/character/boss_songdiwang.jpg", + "image/mode/boss/character/boss_sunshangxiang.jpg", + "image/mode/boss/character/boss_taihao.jpg", + "image/mode/boss/character/boss_taishanwang.jpg", + "image/mode/boss/character/boss_taotie.jpg", + "image/mode/boss/character/boss_taowu.jpg", + "image/mode/boss/character/boss_wang.jpg", + "image/mode/boss/character/boss_wuguanwang.jpg", + "image/mode/boss/character/boss_xiangliu.jpg", + "image/mode/boss/character/boss_xuanlinshilian.jpg", + "image/mode/boss/character/boss_xuanwu.jpg", + "image/mode/boss/character/boss_yandi.jpg", + "image/mode/boss/character/boss_yanling.jpg", + "image/mode/boss/character/boss_yanluowang.jpg", + "image/mode/boss/character/boss_yecha.jpg", + "image/mode/boss/character/boss_yingzhao.jpg", + "image/mode/boss/character/boss_yuji.jpg", + "image/mode/boss/character/boss_zhangchunhua.jpg", + "image/mode/boss/character/boss_zhangjiao.jpg", + "image/mode/boss/character/boss_zhenji.jpg", + "image/mode/boss/character/boss_zhouyu.jpg", + "image/mode/boss/character/boss_zhuanlunwang.jpg", + "image/mode/boss/character/boss_zhuanxu.jpg", + "image/mode/boss/character/boss_zhugeliang.jpg", + "image/mode/boss/character/boss_zhuoguiquxie.jpg", + "image/mode/boss/character/boss_zhuque.jpg", + "image/mode/boss/character/boss_zhuyan.jpg", + "image/mode/boss/character/boss_zhuyin.jpg", + "image/mode/boss/character/boss_zuoci.jpg", + + "image/mode/chess/card/chess_chuzhang.png", + "image/mode/chess/card/chess_shezhang.png", + "image/mode/chess/character/chess_beimingjukun.jpg", + "image/mode/chess/character/chess_caocao.jpg", + "image/mode/chess/character/chess_diaochan.jpg", + "image/mode/chess/character/chess_dongzhuo.jpg", + "image/mode/chess/character/chess_huangzhong.jpg", + "image/mode/chess/character/chess_huatuo.jpg", + "image/mode/chess/character/chess_jinchidiao.jpg", + "image/mode/chess/character/chess_sunshangxiang.jpg", + "image/mode/chess/character/chess_taishici.jpg", + "image/mode/chess/character/chess_wuzhaojinlong.jpg", + "image/mode/chess/character/chess_xingtian.jpg", + "image/mode/chess/character/chess_zhangliao.jpg", + "image/mode/chess/character/leader_caocao.jpg", + "image/mode/chess/character/leader_liubei.jpg", + "image/mode/chess/character/leader_sunquan.jpg", + "image/mode/chess/character/leader_yuri.jpg", + "image/mode/chess/difficulty/leader_easy.jpg", + "image/mode/chess/difficulty/leader_hard.jpg", + "image/mode/chess/difficulty/leader_medium.jpg", + "image/mode/stone/card/spell_ansezhadan.jpg", + "image/mode/stone/card/spell_anyingkuangluan.jpg", + "image/mode/stone/card/spell_anyinglieyan.jpg", + "image/mode/stone/card/spell_anyingxingtai.jpg", + "image/mode/stone/card/spell_anzhongpohuai.jpg", + "image/mode/stone/card/spell_aoshufeidan.jpg", + "image/mode/stone/card/spell_aoshuzhihui.jpg", + "image/mode/stone/card/spell_baofengxue.jpg", + "image/mode/stone/card/spell_beici.jpg", + "image/mode/stone/card/spell_bianxingshu.jpg", + "image/mode/stone/card/spell_bingdong.jpg", + "image/mode/stone/card/spell_binghuan.jpg", + "image/mode/stone/card/spell_canying.jpg", + "image/mode/stone/card/spell_chazhuangshandian.jpg", + "image/mode/stone/card/spell_chenmo.jpg", + "image/mode/stone/card/spell_chirehuoba.jpg", + "image/mode/stone/card/spell_chongfeng.jpg", + "image/mode/stone/card/spell_cigu.jpg", + "image/mode/stone/card/spell_cisha.jpg", + "image/mode/stone/card/spell_conglinzhihun.jpg", + "image/mode/stone/card/spell_daoshan.jpg", + "image/mode/stone/card/spell_diyulieyan.jpg", + "image/mode/stone/card/spell_dubiao.jpg", + "image/mode/stone/card/spell_dunpaimengji.jpg", + "image/mode/stone/card/spell_duochongsheji.jpg", + "image/mode/stone/card/spell_emozhinu.jpg", + "image/mode/stone/card/spell_emozhixin.jpg", + "image/mode/stone/card/spell_enzeshu.jpg", + "image/mode/stone/card/spell_fengnu.jpg", + "image/mode/stone/card/spell_fengxian.jpg", + "image/mode/stone/card/spell_fennu.jpg", + "image/mode/stone/card/spell_fennuzhichui.jpg", + "image/mode/stone/card/spell_fuchoudaji.jpg", + "image/mode/stone/card/spell_fuchouzhinu.jpg", + "image/mode/stone/card/spell_fugen.jpg", + "image/mode/stone/card/spell_fushishu.jpg", + "image/mode/stone/card/spell_guanmenfanggou.jpg", + "image/mode/stone/card/spell_hanbingjian.jpg", + "image/mode/stone/card/spell_hanbingpingzhang.jpg", + "image/mode/stone/card/spell_heiandiyu.jpg", + "image/mode/stone/card/spell_heianqiyue.jpg", + "image/mode/stone/card/spell_hengsao.jpg", + "image/mode/stone/card/spell_huoqiushu.jpg", + "image/mode/stone/card/spell_huotigenxu.jpg", + "image/mode/stone/card/spell_jianrenluanwu.jpg", + "image/mode/stone/card/spell_jingshenkongzhi.jpg", + "image/mode/stone/card/spell_jingxiang.jpg", + "image/mode/stone/card/spell_jinyingduijue.jpg", + "image/mode/stone/card/spell_jipao.jpg", + "image/mode/stone/card/spell_juemingluandou.jpg", + "image/mode/stone/card/spell_kongxinshu.jpg", + "image/mode/stone/card/spell_kuaisusheji.jpg", + "image/mode/stone/card/spell_kuaisuzhiliao.jpg", + "image/mode/stone/card/spell_kuangbao.jpg", + "image/mode/stone/card/spell_laojiuhuoba.jpg", + "image/mode/stone/card/spell_lianhuanbaolie.jpg", + "image/mode/stone/card/spell_lierenyinji.jpg", + "image/mode/stone/card/spell_lieyanfengbao.jpg", + "image/mode/stone/card/spell_liliangdaijia.jpg", + "image/mode/stone/card/spell_liliangzhufu.jpg", + "image/mode/stone/card/spell_linghunhongxi.jpg", + "image/mode/stone/card/spell_maizang.jpg", + "image/mode/stone/card/spell_mengun.jpg", + "image/mode/stone/card/spell_modaoyou.jpg", + "image/mode/stone/card/spell_morizaihuo.jpg", + "image/mode/stone/card/spell_naluzhiguang.jpg", + "image/mode/stone/card/spell_niuquxukong.jpg", + "image/mode/stone/card/spell_nuhuozhongshao.jpg", + "image/mode/stone/card/spell_nuxi.jpg", + "image/mode/stone/card/spell_piaoqie.jpg", + "image/mode/stone/card/spell_qiangfengsheji.jpg", + "image/mode/stone/card/spell_rongyanbaolie.jpg", + "image/mode/stone/card/spell_sanghunzhao.jpg", + "image/mode/stone/card/spell_shalumingling.jpg", + "image/mode/stone/card/spell_shandianfengbao.jpg", + "image/mode/stone/card/spell_shengerpingdeng.jpg", + "image/mode/stone/card/spell_shengguangzhadan.jpg", + "image/mode/stone/card/spell_shengliaoshu.jpg", + "image/mode/stone/card/spell_shenpan.jpg", + "image/mode/stone/card/spell_shenshengfennu.jpg", + "image/mode/stone/card/spell_shenshengxinxing.jpg", + "image/mode/stone/card/spell_shihuawuqi.jpg", + "image/mode/stone/card/spell_shixue.jpg", + "image/mode/stone/card/spell_sijidaifa.jpg", + "image/mode/stone/card/spell_siwangchanrao.jpg", + "image/mode/stone/card/spell_tanxianmao.jpg", + "image/mode/stone/card/spell_tianjiangzhuqun.jpg", + "image/mode/stone/card/spell_wangzhezhufu.jpg", + "image/mode/stone/card/spell_weijisifu.jpg", + "image/mode/stone/card/spell_wuyashenxiang.jpg", + "image/mode/stone/card/spell_xianzuzhaohuan.jpg", + "image/mode/stone/card/spell_xianzuzhihun.jpg", + "image/mode/stone/card/spell_xianzuzhiliao.jpg", + "image/mode/stone/card/spell_xianzuzhishi.jpg", + "image/mode/stone/card/spell_xiaoguibaopo.jpg", + "image/mode/stone/card/spell_xiaoshi.jpg", + "image/mode/stone/card/spell_xingchenzhuiluo.jpg", + "image/mode/stone/card/spell_xinlinghanbao.jpg", + "image/mode/stone/card/spell_xinlingshijie.jpg", + "image/mode/stone/card/spell_xishengqiyue.jpg", + "image/mode/stone/card/spell_xuanfengzhan.jpg", + "image/mode/stone/card/spell_yanbaoshu.jpg", + "image/mode/stone/card/spell_yanmie.jpg", + "image/mode/stone/card/spell_yaoshu.jpg", + "image/mode/stone/card/spell_yemanpaoxiao.jpg", + "image/mode/stone/card/spell_yexingchengzhang.jpg", + "image/mode/stone/card/spell_yexinglanghun.jpg", + "image/mode/stone/card/spell_yingyongdaji.jpg", + "image/mode/stone/card/spell_yongshizhufu.jpg", + "image/mode/stone/card/spell_zhandounuhuo.jpg", + "image/mode/stone/card/spell_zhansha.jpg", + "image/mode/stone/card/spell_zhaohuanchongwu.jpg", + "image/mode/stone/card/spell_zhengqianghaosheng.jpg", + "image/mode/stone/card/spell_zhenyanshu.jpg", + "image/mode/stone/card/spell_zhihuizhufu.jpg", + "image/mode/stone/card/spell_zhiliaoshui.jpg", + "image/mode/stone/card/spell_zhiliaozhichu.jpg", + "image/mode/stone/card/spell_zhiliaozhihuan.jpg", + "image/mode/stone/card/spell_zhongnian.jpg", + "image/mode/stone/card/spell_zhuizongshu.jpg", + "image/mode/stone/card/spell_zhumo.jpg", + "image/mode/stone/card/spell_zidanshangtang.jpg", + "image/mode/stone/card/spell_ziranzhili.jpg", + "image/mode/stone/card/spell_ziyang.jpg", + "image/mode/stone/card/spell_zuozhandongyuan.jpg", + "image/mode/stone/card/spell_zuzhou.jpg", + "image/mode/stone/career/druid.png", + "image/mode/stone/career/hunter.png", + "image/mode/stone/career/knight.png", + "image/mode/stone/career/mage.png", + "image/mode/stone/career/paladin.png", + "image/mode/stone/career/priest.png", + "image/mode/stone/career/rogue.png", + "image/mode/stone/career/shaman.png", + "image/mode/stone/career/warlock.png", + "image/mode/stone/career/warrior.png", + "image/mode/stone/character/stone_aidewen.jpg", + "image/mode/stone/character/stone_aihaozhihun.jpg", + "image/mode/stone/character/stone_alaikesita.jpg", + "image/mode/stone/character/stone_andongni.jpg", + "image/mode/stone/character/stone_anyingzisi.jpg", + "image/mode/stone/character/stone_aolajier.jpg", + "image/mode/stone/character/stone_aomishouwei.jpg", + "image/mode/stone/character/stone_aoshushi.jpg", + "image/mode/stone/character/stone_baohuzhishu.jpg", + "image/mode/stone/character/stone_baoqishi.jpg", + "image/mode/stone/character/stone_baoweizhe.jpg", + "image/mode/stone/character/stone_beijunmushi.jpg", + "image/mode/stone/character/stone_caoyuanshi.jpg", + "image/mode/stone/character/stone_chidunshinv.jpg", + "image/mode/stone/character/stone_chidunweishi.jpg", + "image/mode/stone/character/stone_chilundashi.jpg", + "image/mode/stone/character/stone_cike.jpg", + "image/mode/stone/character/stone_conglinshouwei.jpg", + "image/mode/stone/character/stone_conglinxiaoshou.jpg", + "image/mode/stone/character/stone_damoshatuo.jpg", + "image/mode/stone/character/stone_daomufeizei.jpg", + "image/mode/stone/character/stone_dijieshicong.jpg", + "image/mode/stone/character/stone_diyuhuo.jpg", + "image/mode/stone/character/stone_diyuhuox.jpg", + "image/mode/stone/character/stone_duyanhaidao.jpg", + "image/mode/stone/character/stone_fachao.jpg", + "image/mode/stone/character/stone_falifulong.jpg", + "image/mode/stone/character/stone_famingjia.jpg", + "image/mode/stone/character/stone_faqishi.jpg", + "image/mode/stone/character/stone_fatiaozhuru.jpg", + "image/mode/stone/character/stone_fennuxiaoji.jpg", + "image/mode/stone/character/stone_fuding.jpg", + "image/mode/stone/character/stone_fuhuokaijia.jpg", + "image/mode/stone/character/stone_fukongmoyan.jpg", + "image/mode/stone/character/stone_gangtiewushi.jpg", + "image/mode/stone/character/stone_geluomashi.jpg", + "image/mode/stone/character/stone_guangmingquan.jpg", + "image/mode/stone/character/stone_guangyaozhizi.jpg", + "image/mode/stone/character/stone_guanliyuan.jpg", + "image/mode/stone/character/stone_guiqishi.jpg", + "image/mode/stone/character/stone_haidao.jpg", + "image/mode/stone/character/stone_haidaotoumu.jpg", + "image/mode/stone/character/stone_hanguangzhizhe.jpg", + "image/mode/stone/character/stone_heianjiaotu.jpg", + "image/mode/stone/character/stone_heishitanfan.jpg", + "image/mode/stone/character/stone_heitieairen.jpg", + "image/mode/stone/character/stone_heiyaoyaoshou.jpg", + "image/mode/stone/character/stone_honglongyongshi.jpg", + "image/mode/stone/character/stone_huangjialeixiang.jpg", + "image/mode/stone/character/stone_huangyeqishi.jpg", + "image/mode/stone/character/stone_hudunren.jpg", + "image/mode/stone/character/stone_huofu.jpg", + "image/mode/stone/character/stone_huoli.jpg", + "image/mode/stone/character/stone_huoqiangshou.jpg", + "image/mode/stone/character/stone_huoshanxiemu.jpg", + "image/mode/stone/character/stone_huoshe.jpg", + "image/mode/stone/character/stone_huoyanweishi.jpg", + "image/mode/stone/character/stone_huoyao.jpg", + "image/mode/stone/character/stone_huoyuansu.jpg", + "image/mode/stone/character/stone_jialakesi.jpg", + "image/mode/stone/character/stone_jialakesix.jpg", + "image/mode/stone/character/stone_jiangong.jpg", + "image/mode/stone/character/stone_jiewangzhu.jpg", + "image/mode/stone/character/stone_jingxiang.jpg", + "image/mode/stone/character/stone_jingyingweishi.jpg", + "image/mode/stone/character/stone_jujishou.jpg", + "image/mode/stone/character/stone_junxuguan.jpg", + "image/mode/stone/character/stone_juxingchanchu.jpg", + "image/mode/stone/character/stone_kaodalalong.jpg", + "image/mode/stone/character/stone_kelushi.jpg", + "image/mode/stone/character/stone_kongjuzhanma.jpg", + "image/mode/stone/character/stone_kuangyedoushi.jpg", + "image/mode/stone/character/stone_kuangzhanshi.jpg", + "image/mode/stone/character/stone_kutongsiseng.jpg", + "image/mode/stone/character/stone_langren.jpg", + "image/mode/stone/character/stone_lansaizhanshi.jpg", + "image/mode/stone/character/stone_leiouke.jpg", + "image/mode/stone/character/stone_liebao.jpg", + "image/mode/stone/character/stone_liegou.jpg", + "image/mode/stone/character/stone_liewangshouwei.jpg", + "image/mode/stone/character/stone_lieyanxiaogui.jpg", + "image/mode/stone/character/stone_lifaji.jpg", + "image/mode/stone/character/stone_lindishuyao.jpg", + "image/mode/stone/character/stone_linghunjisi.jpg", + "image/mode/stone/character/stone_longmianjiaoguan.jpg", + "image/mode/stone/character/stone_longwangpeiou.jpg", + "image/mode/stone/character/stone_mafengzhuru.jpg", + "image/mode/stone/character/stone_maligousi.jpg", + "image/mode/stone/character/stone_meimo.jpg", + "image/mode/stone/character/stone_mengmaren.jpg", + "image/mode/stone/character/stone_mianyang.jpg", + "image/mode/stone/character/stone_mingguangjisi.jpg", + "image/mode/stone/character/stone_misha.jpg", + "image/mode/stone/character/stone_morishouwei.jpg", + "image/mode/stone/character/stone_muguangchulong.jpg", + "image/mode/stone/character/stone_muyangren.jpg", + "image/mode/stone/character/stone_nianqingjisi.jpg", + "image/mode/stone/character/stone_nuoziduomu.jpg", + "image/mode/stone/character/stone_peilianshi.jpg", + "image/mode/stone/character/stone_qiezei.jpg", + "image/mode/stone/character/stone_qingwa.jpg", + "image/mode/stone/character/stone_renyaqishi.jpg", + "image/mode/stone/character/stone_sainaliusi.jpg", + "image/mode/stone/character/stone_senlinlang.jpg", + "image/mode/stone/character/stone_shachuisaman.jpg", + "image/mode/stone/character/stone_shalinxingzhe.jpg", + "image/mode/stone/character/stone_shengdianzhishi.jpg", + "image/mode/stone/character/stone_shengguanghuwei.jpg", + "image/mode/stone/character/stone_shengjiachong.jpg", + "image/mode/stone/character/stone_shenmiqishou.jpg", + "image/mode/stone/character/stone_shenshengyongshi.jpg", + "image/mode/stone/character/stone_shifazhe.jpg", + "image/mode/stone/character/stone_shihualong.jpg", + "image/mode/stone/character/stone_shishigui.jpg", + "image/mode/stone/character/stone_shixiangweishi.jpg", + "image/mode/stone/character/stone_shuiyuansu.jpg", + "image/mode/stone/character/stone_shumiao.jpg", + "image/mode/stone/character/stone_shuren.jpg", + "image/mode/stone/character/stone_shurenx.jpg", + "image/mode/stone/character/stone_shurenxx.jpg", + "image/mode/stone/character/stone_siwangzhiyi.jpg", + "image/mode/stone/character/stone_suoxiaojishi.jpg", + "image/mode/stone/character/stone_tegong.jpg", + "image/mode/stone/character/stone_tongkunvwang.jpg", + "image/mode/stone/character/stone_tujiu.jpg", + "image/mode/stone/character/stone_tuteng1.jpg", + "image/mode/stone/character/stone_tuteng2.jpg", + "image/mode/stone/character/stone_tuteng3.jpg", + "image/mode/stone/character/stone_tuteng4.jpg", + "image/mode/stone/character/stone_tutengshi.jpg", + "image/mode/stone/character/stone_tutengyongshi.jpg", + "image/mode/stone/character/stone_tuyuansu.jpg", + "image/mode/stone/character/stone_wanshiyuansu.jpg", + "image/mode/stone/character/stone_weilun.jpg", + "image/mode/stone/character/stone_wujiyuansu.jpg", + "image/mode/stone/character/stone_wushixuetu.jpg", + "image/mode/stone/character/stone_wuyi.jpg", + "image/mode/stone/character/stone_xiaogui.jpg", + "image/mode/stone/character/stone_xiaoguishouling.jpg", + "image/mode/stone/character/stone_xiaojingling.jpg", + "image/mode/stone/character/stone_xinbing.jpg", + "image/mode/stone/character/stone_xiushuihaidao.jpg", + "image/mode/stone/character/stone_xuefanzhanshi.jpg", + "image/mode/stone/character/stone_xuejuren.jpg", + "image/mode/stone/character/stone_xukongkongmo.jpg", + "image/mode/stone/character/stone_xukongxingzhe.jpg", + "image/mode/stone/character/stone_xulingwushi.jpg", + "image/mode/stone/character/stone_xunmashi.jpg", + "image/mode/stone/character/stone_xunmenglong.jpg", + "image/mode/stone/character/stone_xunshoushi.jpg", + "image/mode/stone/character/stone_yanjingshe.jpg", + "image/mode/stone/character/stone_yanshushi.jpg", + "image/mode/stone/character/stone_yaosaishouwei.jpg", + "image/mode/stone/character/stone_yingxiongzhihun.jpg", + "image/mode/stone/character/stone_yisela.jpg", + "image/mode/stone/character/stone_youlinglang.jpg", + "image/mode/stone/character/stone_yuanguanying.jpg", + "image/mode/stone/character/stone_yuanhou.jpg", + "image/mode/stone/character/stone_yurenqishi.jpg", + "image/mode/stone/character/stone_zhaohuanzhe.jpg", + "image/mode/stone/character/stone_zhifuzhe.jpg", + "image/mode/stone/character/stone_zhihuiguan.jpg", + "image/mode/stone/character/stone_zhiyuzhe.jpg", + "image/mode/stone/character/stone_zhongshi.jpg", + "image/mode/stone/character/stone_zhucangzhe.jpg", + "image/mode/stone/character/stone_zhujiashi.jpg", + "image/mode/stone/character/stone_zhumo.jpg", + "image/mode/stone/character/stone_zongxiong.jpg", + "image/mode/stone/character/stone_zousishangfan.jpg", + "image/mode/tafang/character/tafang_mech_dubiaoxianjing.jpg", + "image/mode/tafang/character/tafang_mech_gongchengche.jpg", + "image/mode/tafang/character/tafang_mech_guangmingquan.jpg", + "image/mode/tafang/character/tafang_mech_jiguanren.jpg", + "image/mode/tafang/character/tafang_mech_jiqishi.jpg", + "image/mode/tafang/character/tafang_mech_mutong.jpg", + "image/mode/tafang/character/tafang_mech_nengliangqiu.jpg", + "image/mode/tafang/character/tafang_mech_shanggukanshou.jpg", + "image/mode/tafang/character/tafang_mech_shenmidiaoxiang.jpg", + "image/mode/tafang/character/tafang_mech_shenpanxianjing.jpg", + "image/mode/tafang/character/tafang_mech_shiyuansu.jpg", + "image/mode/tafang/character/tafang_mech_toushiche.jpg", + "image/mode/tafang/character/tafang_mech_tutengzhen.jpg", + "image/mode/tafang/character/tafang_mech_weixingxianjing.jpg", + "image/mode/tafang/character/tafang_mech_wuyashenxiang.jpg", + "image/mode/versus/character/boss_chiyuzhuque.jpg", + "image/mode/versus/character/boss_duanyuzhongda.jpg", + "image/mode/versus/character/boss_fudibian.jpg", + "image/mode/versus/character/boss_gongshenyueying.jpg", + "image/mode/versus/character/boss_jiarenzidan.jpg", + "image/mode/versus/character/boss_jileibaihu.jpg", + "image/mode/versus/character/boss_juechenmiaocai.jpg", + "image/mode/versus/character/boss_liedixuande.jpg", + "image/mode/versus/character/boss_lieshiyazi.jpg", + "image/mode/versus/character/boss_lingjiaxuanwu.jpg", + "image/mode/versus/character/boss_qiaokuijunyi.jpg", + "image/mode/versus/character/boss_shihuosuanni.jpg", + "image/mode/versus/character/boss_tianhoukongming.jpg", + "image/mode/versus/character/boss_tuntianchiwen.jpg", + "image/mode/versus/character/boss_yuhuoshiyuan.jpg", + "image/mode/versus/character/boss_yunpingqinglong.jpg", + "image/mode/versus/character/boss_baijiwenyuan.jpg", + "image/mode/versus/character/boss_fuweizilong.jpg", + "image/mode/versus/character/boss_kumuyuanrang.jpg", + "image/mode/versus/character/boss_yihanyunchang.jpg", + "image/mode/versus/character/liuqi.jpg", + "image/mode/versus/character/tangzi.jpg", + + /*splash image begin*/ + "image/splash/style1.jpg", + "image/splash/style2.jpg", + "image/splash/style1/boss.jpg", + "image/splash/style1/brawl.jpg", + "image/splash/style1/chess.jpg", + "image/splash/style1/connect.jpg", + "image/splash/style1/doudizhu.jpg", + "image/splash/style1/guozhan.jpg", + "image/splash/style1/identity.jpg", + "image/splash/style1/single.jpg", + "image/splash/style1/stone.jpg", + "image/splash/style1/tafang.jpg", + "image/splash/style1/versus.jpg", + "image/splash/style2/boss.jpg", + "image/splash/style2/brawl.jpg", + "image/splash/style2/chess.jpg", + "image/splash/style2/connect.jpg", + "image/splash/style2/doudizhu.jpg", + "image/splash/style2/guozhan.jpg", + "image/splash/style2/identity.jpg", + "image/splash/style2/single.jpg", + "image/splash/style2/stone.jpg", + "image/splash/style2/tafang.jpg", + "image/splash/style2/versus.jpg", + /*splash image end*/ + + "theme/music/grid.png", + "theme/music/wood.png", + "theme/music/wood3.png", + "theme/simple/card.png", + "theme/simple/card2.png", + "theme/simple/grid.png", + "theme/simple/unknown.png", + "theme/simple/wood.png", + "theme/simple/wood3.png", + "theme/style/card/image/border_bronze.jpg", + "theme/style/card/image/border_gold.jpg", + "theme/style/card/image/border_map.jpg", + "theme/style/card/image/border_silver.jpg", + "theme/style/card/image/border_wood.jpg", + "theme/style/card/image/new.png", + "theme/style/card/image/ol.png", + "theme/style/cardback/image/feicheng.png", + "theme/style/cardback/image/feicheng2.png", + "theme/style/cardback/image/liusha.png", + "theme/style/cardback/image/liusha2.png", + "theme/style/cardback/image/new.png", + "theme/style/cardback/image/new2.png", + "theme/style/cardback/image/official.png", + "theme/style/cardback/image/official2.png", + "theme/style/cardback/image/ol.png", + "theme/style/cardback/image/ol2.png", + "theme/style/hp/image/emotion1.png", + "theme/style/hp/image/emotion2.png", + "theme/style/hp/image/emotion3.png", + "theme/style/hp/image/emotion4.png", + "theme/style/hp/image/glass1.png", + "theme/style/hp/image/glass2.png", + "theme/style/hp/image/glass3.png", + "theme/style/hp/image/glass4.png", + "theme/style/hp/image/official1.png", + "theme/style/hp/image/official2.png", + "theme/style/hp/image/official3.png", + "theme/style/hp/image/official4.png", + "theme/style/hp/image/ol1.png", + "theme/style/hp/image/ol2.png", + "theme/style/hp/image/ol3.png", + "theme/style/hp/image/ol4.png", + "theme/style/hp/image/round1.png", + "theme/style/hp/image/round2.png", + "theme/style/hp/image/round3.png", + "theme/style/hp/image/round4.png", + "theme/style/player/bronze1.png", + "theme/style/player/bronze2.png", + "theme/style/player/bronze3.png", + "theme/style/player/bronze_d1.png", + "theme/style/player/bronze_d2.png", + "theme/style/player/gold1.png", + "theme/style/player/gold2.png", + "theme/style/player/gold3.png", + "theme/style/player/gold_d1.png", + "theme/style/player/gold_d2.png", + "theme/style/player/silver1.png", + "theme/style/player/silver2.png", + "theme/style/player/silver3.png", + "theme/style/player/silver_d1.png", + "theme/style/player/silver_d2.png", + "theme/woodden/grid.png", + "theme/woodden/wood.jpg", + "theme/woodden/wood.png", + "theme/woodden/wood2.jpg", + "theme/woodden/wood2.png", +]; +window.noname_skin_list = {}; diff --git a/game/canUse.ts b/game/canUse.ts index 4f3678080..13e08568d 100644 --- a/game/canUse.ts +++ b/game/canUse.ts @@ -1,4 +1,4 @@ // apk每次安装后第一次启动加载Service Worker会失败 // 所以每次导入这个ts判断是否会成功,失败的话重启一次 -export const text: string = 'ts文件导入成功'; \ No newline at end of file +export const text: string = "ts文件导入成功"; diff --git a/game/codemirror.js b/game/codemirror.js index c25437c24..82ac6d5c1 100644 --- a/game/codemirror.js +++ b/game/codemirror.js @@ -1,10458 +1,10458 @@ - -function getDocumentZoom() { - //一般body的缩放是xy同步的 - var transform = getComputedStyle(document.body).transform; - // @ts-ignore - if (transform == 'none') transform = 1; - // @ts-ignore - else transform = +transform.slice(7, -1).split(',')[0]; - return +transform; -} - -// BROWSER SNIFFING - -// Kludges for bugs and behavior differences that can't be feature -// detected are enabled based on userAgent etc sniffing. -var userAgent = navigator.userAgent; -var platform = navigator.platform; - -var gecko = /gecko\/\d/i.test(userAgent); -var ie_upto10 = /MSIE \d/.test(userAgent); -var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); -var ie = ie_upto10 || ie_11up; -// @ts-ignore -var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); -var webkit = /WebKit\//.test(userAgent); -var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); -var chrome = /Chrome\//.test(userAgent); -var presto = /Opera\//.test(userAgent); -var safari = /Apple Computer/.test(navigator.vendor); -var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); -var phantom = /PhantomJS/.test(userAgent); - -var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); -// This is woefully incomplete. Suggestions for alternative methods welcome. -var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); -var mac = ios || /Mac/.test(platform); -var chromeOS = /\bCrOS\b/.test(userAgent); -var windows = /win/i.test(platform); - -var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); -// @ts-ignore -if (presto_version) presto_version = Number(presto_version[1]); -// @ts-ignore -if (presto_version && presto_version >= 15) { presto = false; webkit = true; } -// Some browsers use the wrong event properties to signal cmd/ctrl on OS X -// @ts-ignore -var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); -var captureRightClick = gecko || (ie && ie_version >= 9); - -// Optimize some code when these features are not used. -var sawReadOnlySpans = false, sawCollapsedSpans = false; - -// EDITOR CONSTRUCTOR - -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . - -/** - * @type { typeof import('codemirror/index') } - */ -// @ts-ignore -var CodeMirror = (function () { - - // A CodeMirror instance represents an editor. This is the object - // that user code is usually dealing with. - - function CodeMirror(place, options) { - if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - - this.options = options = options ? copyObj(options) : {}; - // Determine effective options based on given values and defaults. - copyObj(defaults, options, false); - setGuttersForLineNumbers(options); - - var doc = options.value; - if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); - this.doc = doc; - - var input = new CodeMirror.inputStyles[options.inputStyle](this); - var display = this.display = new Display(place, doc, input); - display.wrapper.CodeMirror = this; - updateGutters(this); - themeChanged(this); - if (options.lineWrapping) - this.display.wrapper.className += " CodeMirror-wrap"; - if (options.autofocus && !mobile) display.input.focus(); - initScrollbars(this); - - this.state = { - keyMaps: [], // stores maps added by addKeyMap - overlays: [], // highlighting overlays, as added by addOverlay - modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info - overwrite: false, - delayingBlurEvent: false, - focused: false, - suppressEdits: false, // used to disable editing during key handlers when in readOnly mode - pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll - selectingText: false, - draggingText: false, - highlight: new Delayed(), // stores highlight worker timeout - keySeq: null, // Unfinished key sequence - specialChars: null - }; - - var cm = this; - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie && ie_version < 11) setTimeout(function () { cm.display.input.reset(true); }, 20); - - registerEventHandlers(this); - ensureGlobalHandlers(); - - startOperation(this); - this.curOp.forceUpdate = true; - attachDoc(this, doc); - - if ((options.autofocus && !mobile) || cm.hasFocus()) - setTimeout(bind(onFocus, this), 20); - else - onBlur(this); - - for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) - optionHandlers[opt](this, options[opt], Init); - maybeUpdateLineNumberWidth(this); - if (options.finishInit) options.finishInit(this); - for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); - endOperation(this); - // Suppress optimizelegibility in Webkit, since it breaks text - // measuring on line wrapping boundaries. - if (webkit && options.lineWrapping && - getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") - display.lineDiv.style.textRendering = "auto"; - } - - // DISPLAY CONSTRUCTOR - - // The display handles the DOM integration, both for input reading - // and content drawing. It holds references to DOM nodes and - // display-related state. - - function Display(place, doc, input) { - var d = this; - this.input = input; - - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - d.scrollbarFiller.setAttribute("cm-not-content", "true"); - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - d.gutterFiller.setAttribute("cm-not-content", "true"); - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = elt("div", null, "CodeMirror-code"); - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - d.cursorDiv = elt("div", null, "CodeMirror-cursors"); - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure"); - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none"); - // Moved around its parent to cover visible view. - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - d.sizerWidth = null; - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; - - if (place) { - if (place.appendChild) place.appendChild(d.wrapper); - else place(d.wrapper); - } - - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first; - d.reportedViewFrom = d.reportedViewTo = doc.first; - // Information about the rendered lines. - d.view = []; - d.renderedView = null; - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null; - // Empty space (in pixels) above the view - d.viewOffset = 0; - d.lastWrapHeight = d.lastWrapWidth = 0; - d.updateLineNumbers = null; - - d.nativeBarWidth = d.barHeight = d.barWidth = 0; - d.scrollbarsClipped = false; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false; - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - // True when shift is held down. - d.shift = false; - - // Used to track whether anything happened since the context menu - // was opened. - d.selForContextMenu = null; - - d.activeTouch = null; - - input.init(d); - } - - // STATE UPDATES - - // Used to get the editor into a consistent state again when options change. - - function loadMode(cm) { - cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); - resetModeState(cm); - } - - function resetModeState(cm) { - cm.doc.iter(function (line) { - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - }); - cm.doc.frontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) regChange(cm); - } - - function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - addClass(cm.display.wrapper, "CodeMirror-wrap"); - cm.display.sizer.style.minWidth = ""; - cm.display.sizerWidth = null; - } else { - rmClass(cm.display.wrapper, "CodeMirror-wrap"); - findMaxLine(cm); - } - estimateLineHeights(cm); - regChange(cm); - clearCaches(cm); - setTimeout(function () { updateScrollbars(cm); }, 100); - } - - // Returns a function that estimates the height of a line, to use as - // first approximation until the line becomes visible (and is thus - // properly measurable). - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function (line) { - if (lineIsHidden(cm.doc, line)) return 0; - - var widgetsHeight = 0; - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; - } - - if (wrapping) - return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; - else - return widgetsHeight + th; - }; - } - - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function (line) { - var estHeight = est(line); - if (estHeight != line.height) updateLineHeight(line, estHeight); - }); - } - - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - function guttersChanged(cm) { - updateGutters(cm); - regChange(cm); - setTimeout(function () { alignHorizontally(cm); }, 20); - } - - // Rebuild the gutter elements, ensure the margin to the left of the - // code matches their width. - function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters; - removeChildren(gutters); - for (var i = 0; i < specs.length; ++i) { - var gutterClass = specs[i]; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt; - gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = i ? "" : "none"; - updateGutterSpace(cm); - } - - function updateGutterSpace(cm) { - var width = cm.display.gutters.offsetWidth; - cm.display.sizer.style.marginLeft = width + "px"; - } - - // Compute the character length of a line, taking into account - // collapsed ranges (see markText) that might hide parts, and join - // other lines onto it. - function lineLength(line) { - if (line.height == 0) return 0; - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true); - cur = found.from.line; - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found = merged.find(0, true); - len -= cur.text.length - found.from.ch; - cur = found.to.line; - len += cur.text.length - found.to.ch; - } - return len; - } - - // Find the longest line in the document. - function findMaxLine(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(d.maxLine); - d.maxLineChanged = true; - doc.iter(function (line) { - var len = lineLength(line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } - - // Make sure the gutters options contains the element - // "CodeMirror-linenumbers" when the lineNumbers option is true. - function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers"); - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0); - options.gutters.splice(found, 1); - } - } - - // SCROLLBARS - - // Prepare DOM reads needed to update the scrollbars. Done in one - // shot to minimize update/measure roundtrips. - function measureForScrollbars(cm) { - var d = cm.display, gutterW = d.gutters.offsetWidth; - var docH = Math.round(cm.doc.height + paddingVert(cm.display)); - return { - clientHeight: d.scroller.clientHeight, - viewHeight: d.wrapper.clientHeight, - scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, - viewWidth: d.wrapper.clientWidth, - barLeft: cm.options.fixedGutter ? gutterW : 0, - docHeight: docH, - scrollHeight: docH + scrollGap(cm) + d.barHeight, - nativeBarWidth: d.nativeBarWidth, - gutterWidth: gutterW - }; - } - - function NativeScrollbars(place, scroll, cm) { - this.cm = cm; - var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); - var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); - place(vert); place(horiz); - - on(vert, "scroll", function () { - if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); - }); - on(horiz, "scroll", function () { - if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); - }); - - this.checkedZeroWidth = false; - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; - } - - NativeScrollbars.prototype = copyObj({ - update: function (measure) { - var needsH = measure.scrollWidth > measure.clientWidth + 1; - var needsV = measure.scrollHeight > measure.clientHeight + 1; - var sWidth = measure.nativeBarWidth; - - if (needsV) { - this.vert.style.display = "block"; - this.vert.style.bottom = needsH ? sWidth + "px" : "0"; - var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); - // A bug in IE8 can cause this value to be negative, so guard it. - this.vert.firstChild.style.height = - Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; - } else { - this.vert.style.display = ""; - this.vert.firstChild.style.height = "0"; - } - - if (needsH) { - this.horiz.style.display = "block"; - this.horiz.style.right = needsV ? sWidth + "px" : "0"; - this.horiz.style.left = measure.barLeft + "px"; - var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); - this.horiz.firstChild.style.width = - (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; - } else { - this.horiz.style.display = ""; - this.horiz.firstChild.style.width = "0"; - } - - if (!this.checkedZeroWidth && measure.clientHeight > 0) { - if (sWidth == 0) this.zeroWidthHack(); - this.checkedZeroWidth = true; - } - - return { right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0 }; - }, - setScrollLeft: function (pos) { - if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; - if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz); - }, - setScrollTop: function (pos) { - if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; - if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert); - }, - zeroWidthHack: function () { - var w = mac && !mac_geMountainLion ? "12px" : "18px"; - this.horiz.style.height = this.vert.style.width = w; - this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; - this.disableHoriz = new Delayed; - this.disableVert = new Delayed; - }, - enableZeroWidthBar: function (bar, delay) { - bar.style.pointerEvents = "auto"; - function maybeDisable() { - // To find out whether the scrollbar is still visible, we - // check whether the element under the pixel in the bottom - // left corner of the scrollbar box is the scrollbar box - // itself (when the bar is still visible) or its filler child - // (when the bar is hidden). If it is still visible, we keep - // it enabled, if it's hidden, we disable pointer events. - var box = bar.getBoundingClientRect(); - var elt = document.elementFromPoint(box.left + 1, box.bottom - 1); - if (elt != bar) bar.style.pointerEvents = "none"; - else delay.set(1000, maybeDisable); - } - delay.set(1000, maybeDisable); - }, - clear: function () { - var parent = this.horiz.parentNode; - parent.removeChild(this.horiz); - parent.removeChild(this.vert); - } - }, NativeScrollbars.prototype); - - function NullScrollbars() { } - - NullScrollbars.prototype = copyObj({ - update: function () { return { bottom: 0, right: 0 }; }, - setScrollLeft: function () { }, - setScrollTop: function () { }, - clear: function () { } - }, NullScrollbars.prototype); - - CodeMirror.scrollbarModel = { "native": NativeScrollbars, "null": NullScrollbars }; - - function initScrollbars(cm) { - if (cm.display.scrollbars) { - cm.display.scrollbars.clear(); - if (cm.display.scrollbars.addClass) - rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); - } - - cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function (node) { - cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); - // Prevent clicks in the scrollbars from killing focus - on(node, "mousedown", function () { - if (cm.state.focused) setTimeout(function () { cm.display.input.focus(); }, 0); - }); - node.setAttribute("cm-not-content", "true"); - }, function (pos, axis) { - if (axis == "horizontal") setScrollLeft(cm, pos); - else setScrollTop(cm, pos); - }, cm); - if (cm.display.scrollbars.addClass) - addClass(cm.display.wrapper, cm.display.scrollbars.addClass); - } - - function updateScrollbars(cm, measure) { - if (!measure) measure = measureForScrollbars(cm); - var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; - updateScrollbarsInner(cm, measure); - for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { - if (startWidth != cm.display.barWidth && cm.options.lineWrapping) - updateHeightsInViewport(cm); - updateScrollbarsInner(cm, measureForScrollbars(cm)); - startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; - } - } - - // Re-synchronize the fake scrollbars with the actual size of the - // content. - function updateScrollbarsInner(cm, measure) { - var d = cm.display; - var sizes = d.scrollbars.update(measure); - - d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; - d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; - d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" - - if (sizes.right && sizes.bottom) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = sizes.bottom + "px"; - d.scrollbarFiller.style.width = sizes.right + "px"; - } else d.scrollbarFiller.style.display = ""; - if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = sizes.bottom + "px"; - d.gutterFiller.style.width = measure.gutterWidth + "px"; - } else d.gutterFiller.style.display = ""; - } - - // Compute the lines that are visible in a given viewport (defaults - // the the current scroll position). viewport may contain top, - // height, and ensure (see op.scrollToPos) properties. - function visibleLines(display, doc, viewport) { - var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; - top = Math.floor(top - paddingTop(display)); - var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewport && viewport.ensure) { - var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; - if (ensureFrom < from) { - from = ensureFrom; - to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); - } else if (Math.min(ensureTo, doc.lastLine()) >= to) { - from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); - to = ensureTo; - } - } - return { from: from, to: Math.max(to, from + 1) }; - } - - // LINE NUMBERS - - // Re-align line numbers and gutter marks to compensate for - // horizontal scrolling. - function alignHorizontally(cm) { - var display = cm.display, view = display.view; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, left = comp + "px"; - for (var i = 0; i < view.length; i++) if (!view[i].hidden) { - if (cm.options.fixedGutter && view[i].gutter) - view[i].gutter.style.left = left; - var align = view[i].alignable; - if (align) for (var j = 0; j < align.length; j++) - align[j].style.left = left; - } - if (cm.options.fixedGutter) - display.gutters.style.left = (comp + gutterW) + "px"; - } - - // Used to ensure that the line number gutter is still the right - // size for the current document size. Returns true when an update - // is needed. - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) return false; - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - var documentZoom = getDocumentZoom(); - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = (Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1) /* / documentZoom */; - display.lineNumWidth = (display.lineNumInnerWidth + padding) /* / documentZoom */; - display.lineNumChars = (display.lineNumInnerWidth ? last.length : -1) /* / documentZoom */; - display.lineGutter.style.width = display.lineNumWidth + "px"; - updateGutterSpace(cm); - return true; - } - return false; - } - - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)); - } - - // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, - // but using getBoundingClientRect to get a sub-pixel-accurate - // result. - function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; - } - - // DISPLAY DRAWING - - function DisplayUpdate(cm, viewport, force) { - var display = cm.display; - - this.viewport = viewport; - // Store some values that we'll need later (but don't want to force a relayout for) - this.visible = visibleLines(display, cm.doc, viewport); - this.editorIsHidden = !display.wrapper.offsetWidth; - this.wrapperHeight = display.wrapper.clientHeight; - this.wrapperWidth = display.wrapper.clientWidth; - this.oldDisplayWidth = displayWidth(cm); - this.force = force; - this.dims = getDimensions(cm); - this.events = []; - } - - DisplayUpdate.prototype.signal = function (emitter, type) { - if (hasHandler(emitter, type)) - this.events.push(arguments); - }; - DisplayUpdate.prototype.finish = function () { - for (var i = 0; i < this.events.length; i++) - signal.apply(null, this.events[i]); - }; - - function maybeClipScrollbars(cm) { - var display = cm.display; - if (!display.scrollbarsClipped && display.scroller.offsetWidth) { - display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; - display.heightForcer.style.height = scrollGap(cm) + "px"; - display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; - display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; - display.scrollbarsClipped = true; - } - } - - // Does the actual updating of the line display. Bails out - // (returning false) when there is nothing to be done and forced is - // false. - function updateDisplayIfNeeded(cm, update) { - var display = cm.display, doc = cm.doc; - - if (update.editorIsHidden) { - resetView(cm); - return false; - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!update.force && - update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && - display.renderedView == display.view && countDirtyView(cm) == 0) - return false; - - if (maybeUpdateLineNumberWidth(cm)) { - resetView(cm); - update.dims = getDimensions(cm); - } - - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size; - var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, update.visible.to + cm.options.viewportMargin); - if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); - if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from); - to = visualLineEndNo(cm.doc, to); - } - - var different = from != display.viewFrom || to != display.viewTo || - display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; - adjustView(cm, from, to); - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px"; - - var toUpdate = countDirtyView(cm); - if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) - return false; - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var focused = activeElt(); - if (toUpdate > 4) display.lineDiv.style.display = "none"; - patchDisplay(cm, display.updateLineNumbers, update.dims); - if (toUpdate > 4) display.lineDiv.style.display = ""; - display.renderedView = display.view; - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); - - // Prevent selection and cursors from interfering with the scroll - // width and height. - removeChildren(display.cursorDiv); - removeChildren(display.selectionDiv); - display.gutters.style.height = display.sizer.style.minHeight = 0; - - if (different) { - display.lastWrapHeight = update.wrapperHeight; - display.lastWrapWidth = update.wrapperWidth; - startWorker(cm, 400); - } - - display.updateLineNumbers = null; - - return true; - } - - function postUpdateDisplay(cm, update) { - var viewport = update.viewport; - - for (var first = true; ; first = false) { - if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { - // Clip forced viewport to actual scrollable area. - if (viewport && viewport.top != null) - viewport = { top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top) }; - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - update.visible = visibleLines(cm.display, cm.doc, viewport); - if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) - break; - } - if (!updateDisplayIfNeeded(cm, update)) break; - updateHeightsInViewport(cm); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - } - - update.signal(cm, "update", cm); - if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { - update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); - cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; - } - } - - function updateDisplaySimple(cm, viewport) { - var update = new DisplayUpdate(cm, viewport); - if (updateDisplayIfNeeded(cm, update)) { - updateHeightsInViewport(cm); - postUpdateDisplay(cm, update); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - update.finish(); - } - } - - function setDocumentHeight(cm, measure) { - var documentZoom = getDocumentZoom(); - cm.display.sizer.style.minHeight = measure.docHeight / documentZoom + "px"; - cm.display.heightForcer.style.top = measure.docHeight / documentZoom + "px"; - cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) / documentZoom + "px"; - } - - // Read the actual heights of the rendered lines, and update their - // stored heights to match. - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], height; - if (cur.hidden) continue; - if (ie && ie_version < 8) { - var bot = cur.node.offsetTop + cur.node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = cur.node.getBoundingClientRect(); - height = box.bottom - box.top; - } - var diff = cur.line.height - height; - if (height < 2) height = textHeight(display); - if (diff > .001 || diff < -.001) { - updateLineHeight(cur.line, height); - updateWidgetHeight(cur.line); - if (cur.rest) for (var j = 0; j < cur.rest.length; j++) - updateWidgetHeight(cur.rest[j]); - } - } - } - - // Read and store the height of line widgets associated with the - // given line. - function updateWidgetHeight(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) - line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; - } - - // Do a bulk-read of the DOM positions and sizes needed to draw the - // view, so that we don't interleave reading and writing to the DOM. - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - var gutterLeft = d.gutters.clientLeft; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; - width[cm.options.gutters[i]] = n.clientWidth; - } - return { - fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth - }; - } - - // Sync the actual display DOM structure with display.view, removing - // nodes for lines that are no longer in view, and creating the ones - // that are not there yet, and updating the ones that are out of - // date. - function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers; - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) - node.style.display = "none"; - else - node.parentNode.removeChild(node); - return next; - } - - var view = display.view, lineN = display.viewFrom; - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (lineView.hidden) { - } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims); - container.insertBefore(node, cur); - } else { // Already drawn - while (cur != lineView.node) cur = rm(cur); - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber; - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; - updateLineForChanges(cm, lineView, lineN, dims); - } - if (updateNumber) { - removeChildren(lineView.lineNumber); - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); - } - cur = lineView.node.nextSibling; - } - lineN += lineView.size; - } - while (cur) cur = rm(cur); - } - - // When an aspect of a line changes, a string is added to - // lineView.changes. This updates the relevant part of the line's - // DOM structure. - function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j]; - if (type == "text") updateLineText(cm, lineView); - else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); - else if (type == "class") updateLineClasses(lineView); - else if (type == "widget") updateLineWidgets(cm, lineView, dims); - } - lineView.changes = null; - } - - // Lines with gutter elements, widgets or a background class need to - // be wrapped, and have the extra elements added to the wrapper div - function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative"); - if (lineView.text.parentNode) - lineView.text.parentNode.replaceChild(lineView.node, lineView.text); - lineView.node.appendChild(lineView.text); - if (ie && ie_version < 8) lineView.node.style.zIndex = 2; - } - return lineView.node; - } - - function updateLineBackground(lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; - if (cls) cls += " CodeMirror-linebackground"; - if (lineView.background) { - if (cls) lineView.background.className = cls; - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } - } else if (cls) { - var wrap = ensureLineWrapped(lineView); - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); - } - } - - // Wrapper around buildLineContent which will reuse the structure - // in display.externalMeasured when possible. - function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured; - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null; - lineView.measure = ext.measure; - return ext.built; - } - return buildLineContent(cm, lineView); - } - - // Redraw the line's text. Interacts with the background and text - // classes because the mode may output tokens that influence these - // classes. - function updateLineText(cm, lineView) { - var cls = lineView.text.className; - var built = getLineContent(cm, lineView); - if (lineView.text == lineView.node) lineView.node = built.pre; - lineView.text.parentNode.replaceChild(built.pre, lineView.text); - lineView.text = built.pre; - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass; - lineView.textClass = built.textClass; - updateLineClasses(lineView); - } else if (cls) { - lineView.text.className = cls; - } - } - - function updateLineClasses(lineView) { - updateLineBackground(lineView); - if (lineView.line.wrapClass) - ensureLineWrapped(lineView).className = lineView.line.wrapClass; - else if (lineView.node != lineView.text) - lineView.node.className = ""; - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; - lineView.text.className = textClass || ""; - } - - function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter); - lineView.gutter = null; - } - if (lineView.gutterBackground) { - lineView.node.removeChild(lineView.gutterBackground); - lineView.gutterBackground = null; - } - if (lineView.line.gutterClass) { - var wrap = ensureLineWrapped(lineView); - lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, - "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + - "px; width: " + dims.gutterTotalWidth + "px"); - wrap.insertBefore(lineView.gutterBackground, lineView.text); - } - var markers = lineView.line.gutterMarkers; - if (cm.options.lineNumbers || markers) { - var wrap = ensureLineWrapped(lineView); - var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + - (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"); - cm.display.input.setUneditable(gutterWrap); - wrap.insertBefore(gutterWrap, lineView.text); - if (lineView.line.gutterClass) - gutterWrap.className += " " + lineView.line.gutterClass; - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " - + cm.display.lineNumInnerWidth + "px")); - if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; - if (found) - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + - dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] / + "px")); - } - } - } - - function updateLineWidgets(cm, lineView, dims) { - if (lineView.alignable) lineView.alignable = null; - for (var node = lineView.node.firstChild, next; node; node = next) { - var next = node.nextSibling; - if (node.className == "CodeMirror-linewidget") - lineView.node.removeChild(node); - } - insertLineWidgets(cm, lineView, dims); - } - - // Build a line's DOM representation from scratch - function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView); - lineView.text = lineView.node = built.pre; - if (built.bgClass) lineView.bgClass = built.bgClass; - if (built.textClass) lineView.textClass = built.textClass; - - updateLineClasses(lineView); - updateLineGutter(cm, lineView, lineN, dims); - insertLineWidgets(cm, lineView, dims); - return lineView.node; - } - - // A lineView may contain multiple logical lines (when merged by - // collapsed spans). The widgets for all of them need to be drawn. - function insertLineWidgets(cm, lineView, dims) { - insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); - } - - function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { - if (!line.widgets) return; - var wrap = ensureLineWrapped(lineView); - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); - if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); - positionLineWidget(widget, node, lineView, dims); - cm.display.input.setUneditable(node); - if (allowAbove && widget.above) - wrap.insertBefore(node, lineView.gutter || lineView.text); - else - wrap.appendChild(node); - signalLater(widget, "redraw"); - } - } - - function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - (lineView.alignable || (lineView.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; - } - } - - // POSITION OBJECT - - // A Pos instance represents a position within the text. - var Pos = CodeMirror.Pos = function (line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - }; - - // Compare two positions, return 0 if they are the same, a negative - // number when a is less, and a positive number otherwise. - var cmp = CodeMirror.cmpPos = function (a, b) { return a.line - b.line || a.ch - b.ch; }; - - function copyPos(x) { return Pos(x.line, x.ch); } - function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } - function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } - - // INPUT HANDLING - - function ensureFocus(cm) { - if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } - } - - // This will be set to a {lineWise: bool, text: [string]} object, so - // that, when pasting, we know what kind of selections the copied - // text was made out of. - var lastCopied = null; - - function applyTextInput(cm, inserted, deleted, sel, origin) { - var doc = cm.doc; - cm.display.shift = false; - if (!sel) sel = doc.sel; - - var paste = cm.state.pasteIncoming || origin == "paste"; - var textLines = doc.splitLines(inserted), multiPaste = null - // When pasing N lines into N selections, insert one line per selection - if (paste && sel.ranges.length > 1) { - if (lastCopied && lastCopied.text.join("\n") == inserted) { - if (sel.ranges.length % lastCopied.text.length == 0) { - multiPaste = []; - for (var i = 0; i < lastCopied.text.length; i++) - multiPaste.push(doc.splitLines(lastCopied.text[i])); - } - } else if (textLines.length == sel.ranges.length) { - multiPaste = map(textLines, function (l) { return [l]; }); - } - } - - // Normal behavior is to insert the new text into every selection - for (var i = sel.ranges.length - 1; i >= 0; i--) { - var range = sel.ranges[i]; - var from = range.from(), to = range.to(); - if (range.empty()) { - if (deleted && deleted > 0) // Handle deletion - from = Pos(from.line, from.ch - deleted); - else if (cm.state.overwrite && !paste) // Handle overwrite - to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); - else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted) - from = to = Pos(from.line, 0) - } - var updateInput = cm.curOp.updateInput; - var changeEvent = { - from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, - origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input") - }; - makeChange(cm.doc, changeEvent); - signalLater(cm, "inputRead", cm, changeEvent); - } - if (inserted && !paste) - triggerElectric(cm, inserted); - - ensureCursorVisible(cm); - cm.curOp.updateInput = updateInput; - cm.curOp.typing = true; - cm.state.pasteIncoming = cm.state.cutIncoming = false; - } - - function handlePaste(e, cm) { - var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); - if (pasted) { - e.preventDefault(); - if (!cm.isReadOnly() && !cm.options.disableInput) - runInOp(cm, function () { applyTextInput(cm, pasted, 0, null, "paste"); }); - return true; - } - } - - function triggerElectric(cm, inserted) { - // When an 'electric' character is inserted, immediately trigger a reindent - if (!cm.options.electricChars || !cm.options.smartIndent) return; - var sel = cm.doc.sel; - - for (var i = sel.ranges.length - 1; i >= 0; i--) { - var range = sel.ranges[i]; - if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; - var mode = cm.getModeAt(range.head); - var indented = false; - if (mode.electricChars) { - for (var j = 0; j < mode.electricChars.length; j++) - if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indented = indentLine(cm, range.head.line, "smart"); - break; - } - } else if (mode.electricInput) { - if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) - indented = indentLine(cm, range.head.line, "smart"); - } - if (indented) signalLater(cm, "electricInput", cm, range.head.line); - } - } - - function copyableRanges(cm) { - var text = [], ranges = []; - for (var i = 0; i < cm.doc.sel.ranges.length; i++) { - var line = cm.doc.sel.ranges[i].head.line; - var lineRange = { anchor: Pos(line, 0), head: Pos(line + 1, 0) }; - ranges.push(lineRange); - text.push(cm.getRange(lineRange.anchor, lineRange.head)); - } - return { text: text, ranges: ranges }; - } - - function disableBrowserMagic(field) { - field.setAttribute("autocorrect", "off"); - field.setAttribute("autocapitalize", "off"); - field.setAttribute("spellcheck", "false"); - } - - // TEXTAREA INPUT STYLE - - function TextareaInput(cm) { - this.cm = cm; - // See input.poll and input.reset - this.prevInput = ""; - - // Flag that indicates whether we expect input to appear real soon - // now (after some event like 'keypress' or 'input') and are - // polling intensively. - this.pollingFast = false; - // Self-resetting timeout for the poller - this.polling = new Delayed(); - // Tracks when input.reset has punted to just putting a short - // string into the textarea instead of the full selection. - this.inaccurateSelection = false; - // Used to work around IE issue with selection being forgotten when focus moves away from textarea - this.hasSelection = false; - this.composing = null; - }; - - function hiddenTextarea() { - var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none"); - var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); - // The textarea is kept positioned near the cursor to prevent the - // fact that it'll be scrolled into view on input from scrolling - // our fake cursor out of view. On webkit, when wrap=off, paste is - // very slow. So make the area wide instead. - if (webkit) te.style.width = "1000px"; - else te.setAttribute("wrap", "off"); - // If border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) te.style.border = "1px solid black"; - disableBrowserMagic(te); - return div; - } - - TextareaInput.prototype = copyObj({ - init: function (display) { - var input = this, cm = this.cm; - - // Wraps and hides input textarea - var div = this.wrapper = hiddenTextarea(); - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var te = this.textarea = div.firstChild; - display.wrapper.insertBefore(div, display.wrapper.firstChild); - - // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) - if (ios) te.style.width = "0px"; - - on(te, "input", function () { - if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; - input.poll(); - }); - - on(te, "paste", function (e) { - if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return - - cm.state.pasteIncoming = true; - input.fastPoll(); - }); - - function prepareCopyCut(e) { - if (signalDOMEvent(cm, e)) return - if (cm.somethingSelected()) { - lastCopied = { lineWise: false, text: cm.getSelections() }; - if (input.inaccurateSelection) { - input.prevInput = ""; - input.inaccurateSelection = false; - te.value = lastCopied.text.join("\n"); - selectInput(te); - } - } else if (!cm.options.lineWiseCopyCut) { - return; - } else { - var ranges = copyableRanges(cm); - lastCopied = { lineWise: true, text: ranges.text }; - if (e.type == "cut") { - cm.setSelections(ranges.ranges, null, sel_dontScroll); - } else { - input.prevInput = ""; - te.value = ranges.text.join("\n"); - selectInput(te); - } - } - if (e.type == "cut") cm.state.cutIncoming = true; - } - on(te, "cut", prepareCopyCut); - on(te, "copy", prepareCopyCut); - - on(display.scroller, "paste", function (e) { - if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return; - cm.state.pasteIncoming = true; - input.focus(); - }); - - // Prevent normal selection in the editor (we handle our own) - on(display.lineSpace, "selectstart", function (e) { - if (!eventInWidget(display, e)) e_preventDefault(e); - }); - - on(te, "compositionstart", function () { - var start = cm.getCursor("from"); - if (input.composing) input.composing.range.clear() - input.composing = { - start: start, - range: cm.markText(start, cm.getCursor("to"), { className: "CodeMirror-composing" }) - }; - }); - on(te, "compositionend", function () { - if (input.composing) { - input.poll(); - input.composing.range.clear(); - input.composing = null; - } - }); - }, - - prepareSelection: function () { - // Redraw the selection and/or cursor - var cm = this.cm, display = cm.display, doc = cm.doc; - var result = prepareSelection(cm); - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); - var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); - result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)); - result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)); - } - - return result; - }, - - showSelection: function (drawn) { - var cm = this.cm, display = cm.display; - removeChildrenAndAdd(display.cursorDiv, drawn.cursors); - removeChildrenAndAdd(display.selectionDiv, drawn.selection); - if (drawn.teTop != null) { - this.wrapper.style.top = drawn.teTop + "px"; - this.wrapper.style.left = drawn.teLeft + "px"; - } - }, - - // Reset the input to correspond to the selection (or to be empty, - // when not typing and nothing is selected) - reset: function (typing) { - if (this.contextMenuPending) return; - var minimal, selected, cm = this.cm, doc = cm.doc; - if (cm.somethingSelected()) { - this.prevInput = ""; - var range = doc.sel.primary(); - minimal = hasCopyEvent && - (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); - var content = minimal ? "-" : selected || cm.getSelection(); - this.textarea.value = content; - if (cm.state.focused) selectInput(this.textarea); - if (ie && ie_version >= 9) this.hasSelection = content; - } else if (!typing) { - this.prevInput = this.textarea.value = ""; - if (ie && ie_version >= 9) this.hasSelection = null; - } - this.inaccurateSelection = minimal; - }, - - getField: function () { return this.textarea; }, - - supportsTouch: function () { return false; }, - - focus: function () { - if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { - try { this.textarea.focus(); } - catch (e) { } // IE8 will throw if the textarea is display: none or not in DOM - } - }, - - blur: function () { this.textarea.blur(); }, - - resetPosition: function () { - this.wrapper.style.top = this.wrapper.style.left = 0; - }, - - receivedFocus: function () { this.slowPoll(); }, - - // Poll for input changes, using the normal rate of polling. This - // runs as long as the editor is focused. - slowPoll: function () { - var input = this; - if (input.pollingFast) return; - input.polling.set(this.cm.options.pollInterval, function () { - input.poll(); - if (input.cm.state.focused) input.slowPoll(); - }); - }, - - // When an event has just come in that is likely to add or change - // something in the input textarea, we poll faster, to ensure that - // the change appears on the screen quickly. - fastPoll: function () { - var missed = false, input = this; - input.pollingFast = true; - function p() { - var changed = input.poll(); - if (!changed && !missed) { missed = true; input.polling.set(60, p); } - else { input.pollingFast = false; input.slowPoll(); } - } - input.polling.set(20, p); - }, - - // Read input from the textarea, and update the document to match. - // When something is selected, it is present in the textarea, and - // selected (unless it is huge, in which case a placeholder is - // used). When nothing is selected, the cursor sits after previously - // seen text (can be empty), which is stored in prevInput (we must - // not reset the textarea when typing, because that breaks IME). - poll: function () { - var cm = this.cm, input = this.textarea, prevInput = this.prevInput; - // Since this is called a *lot*, try to bail out as cheaply as - // possible when it is clear that nothing happened. hasSelection - // will be the case when there is a lot of text in the textarea, - // in which case reading its value would be expensive. - if (this.contextMenuPending || !cm.state.focused || - (hasSelection(input) && !prevInput && !this.composing) || - cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) - return false; - - var text = input.value; - // If nothing changed, bail. - if (text == prevInput && !cm.somethingSelected()) return false; - // Work around nonsensical selection resetting in IE9/10, and - // inexplicable appearance of private area unicode characters on - // some key combos in Mac (#2689). - if (ie && ie_version >= 9 && this.hasSelection === text || - mac && /[\uf700-\uf7ff]/.test(text)) { - cm.display.input.reset(); - return false; - } - - if (cm.doc.sel == cm.display.selForContextMenu) { - var first = text.charCodeAt(0); - if (first == 0x200b && !prevInput) prevInput = "\u200b"; - if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } - } - // Find the part of the input that is actually new - var same = 0, l = Math.min(prevInput.length, text.length); - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - - var self = this; - runInOp(cm, function () { - applyTextInput(cm, text.slice(same), prevInput.length - same, - null, self.composing ? "*compose" : null); - - // Don't leave long text in the textarea, since it makes further polling slow - if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; - else self.prevInput = text; - - if (self.composing) { - self.composing.range.clear(); - self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), - { className: "CodeMirror-composing" }); - } - }); - return true; - }, - - ensurePolled: function () { - if (this.pollingFast && this.poll()) this.pollingFast = false; - }, - - onKeyPress: function () { - if (ie && ie_version >= 9) this.hasSelection = null; - this.fastPoll(); - }, - - onContextMenu: function (e) { - var input = this, cm = input.cm, display = cm.display, te = input.textarea; - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; - if (!pos || presto) return; // Opera is difficult. - - // Reset the current text selection only if the click is done outside of the selection - // and 'resetSelectionOnContextMenu' option is true. - var reset = cm.options.resetSelectionOnContextMenu; - if (reset && cm.doc.sel.contains(pos) == -1) - operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); - - var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText; - input.wrapper.style.cssText = "position: absolute" - var wrapperBox = input.wrapper.getBoundingClientRect() - te.style.cssText = "position: absolute; width: 30px; height: 30px; top: " + (e.clientY - wrapperBox.top - 5) + - "px; left: " + (e.clientX - wrapperBox.left - 5) + "px; z-index: 1000; background: " + - (ie ? "rgba(255, 255, 255, .05)" : "transparent") + - "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; - if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) - display.input.focus(); - if (webkit) window.scrollTo(null, oldScrollY); - display.input.reset(); - // Adds "Select all" to context menu in FF - if (!cm.somethingSelected()) te.value = input.prevInput = " "; - input.contextMenuPending = true; - display.selForContextMenu = cm.doc.sel; - clearTimeout(display.detectingSelectAll); - - // Select-all will be greyed out if there's nothing to select, so - // this adds a zero-width space so that we can later check whether - // it got selected. - function prepareSelectAllHack() { - if (te.selectionStart != null) { - var selected = cm.somethingSelected(); - var extval = "\u200b" + (selected ? te.value : ""); - te.value = "\u21da"; // Used to catch context-menu undo - te.value = extval; - input.prevInput = selected ? "" : "\u200b"; - te.selectionStart = 1; te.selectionEnd = extval.length; - // Re-set this, in case some other handler touched the - // selection in the meantime. - display.selForContextMenu = cm.doc.sel; - } - } - function rehide() { - input.contextMenuPending = false; - input.wrapper.style.cssText = oldWrapperCSS - te.style.cssText = oldCSS; - if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); - - // Try to detect the user choosing select-all - if (te.selectionStart != null) { - if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); - var i = 0, poll = function () { - if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && - te.selectionEnd > 0 && input.prevInput == "\u200b") - operation(cm, commands.selectAll)(cm); - else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); - else display.input.reset(); - }; - display.detectingSelectAll = setTimeout(poll, 200); - } - } - - if (ie && ie_version >= 9) prepareSelectAllHack(); - if (captureRightClick) { - e_stop(e); - var mouseup = function () { - off(window, "mouseup", mouseup); - setTimeout(rehide, 20); - }; - on(window, "mouseup", mouseup); - } else { - setTimeout(rehide, 50); - } - }, - - readOnlyChanged: function (val) { - if (!val) this.reset(); - }, - - setUneditable: nothing, - - needsContentAttribute: false - }, TextareaInput.prototype); - - // CONTENTEDITABLE INPUT STYLE - - function ContentEditableInput(cm) { - this.cm = cm; - this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; - this.polling = new Delayed(); - this.gracePeriod = false; - } - - ContentEditableInput.prototype = copyObj({ - init: function (display) { - var input = this, cm = input.cm; - var div = input.div = display.lineDiv; - disableBrowserMagic(div); - - on(div, "paste", function (e) { - if (!signalDOMEvent(cm, e)) handlePaste(e, cm); - }) - - on(div, "compositionstart", function (e) { - var data = e.data; - input.composing = { sel: cm.doc.sel, data: data, startData: data }; - if (!data) return; - var prim = cm.doc.sel.primary(); - var line = cm.getLine(prim.head.line); - var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); - if (found > -1 && found <= prim.head.ch) - input.composing.sel = simpleSelection(Pos(prim.head.line, found), - Pos(prim.head.line, found + data.length)); - }); - on(div, "compositionupdate", function (e) { - input.composing.data = e.data; - }); - on(div, "compositionend", function (e) { - var ours = input.composing; - if (!ours) return; - if (e.data != ours.startData && !/\u200b/.test(e.data)) - ours.data = e.data; - // Need a small delay to prevent other code (input event, - // selection polling) from doing damage when fired right after - // compositionend. - setTimeout(function () { - if (!ours.handled) - input.applyComposition(ours); - if (input.composing == ours) - input.composing = null; - }, 50); - }); - - on(div, "touchstart", function () { - input.forceCompositionEnd(); - }); - - on(div, "input", function () { - if (input.composing) return; - if (cm.isReadOnly() || !input.pollContent()) - runInOp(input.cm, function () { regChange(cm); }); - }); - - function onCopyCut(e) { - if (signalDOMEvent(cm, e)) return - if (cm.somethingSelected()) { - lastCopied = { lineWise: false, text: cm.getSelections() }; - if (e.type == "cut") cm.replaceSelection("", null, "cut"); - } else if (!cm.options.lineWiseCopyCut) { - return; - } else { - var ranges = copyableRanges(cm); - lastCopied = { lineWise: true, text: ranges.text }; - if (e.type == "cut") { - cm.operation(function () { - cm.setSelections(ranges.ranges, 0, sel_dontScroll); - cm.replaceSelection("", null, "cut"); - }); - } - } - // iOS exposes the clipboard API, but seems to discard content inserted into it - if (e.clipboardData && !ios) { - e.preventDefault(); - e.clipboardData.clearData(); - e.clipboardData.setData("text/plain", lastCopied.text.join("\n")); - } else { - // Old-fashioned briefly-focus-a-textarea hack - var kludge = hiddenTextarea(), te = kludge.firstChild; - cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); - te.value = lastCopied.text.join("\n"); - var hadFocus = document.activeElement; - selectInput(te); - setTimeout(function () { - cm.display.lineSpace.removeChild(kludge); - hadFocus.focus(); - }, 50); - } - } - on(div, "copy", onCopyCut); - on(div, "cut", onCopyCut); - }, - - prepareSelection: function () { - var result = prepareSelection(this.cm, false); - result.focus = this.cm.state.focused; - return result; - }, - - showSelection: function (info, takeFocus) { - if (!info || !this.cm.display.view.length) return; - if (info.focus || takeFocus) this.showPrimarySelection(); - this.showMultipleSelections(info); - }, - - showPrimarySelection: function () { - var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); - var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); - var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); - if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && - cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && - cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) - return; - - var start = posToDOM(this.cm, prim.from()); - var end = posToDOM(this.cm, prim.to()); - if (!start && !end) return; - - var view = this.cm.display.view; - var old = sel.rangeCount && sel.getRangeAt(0); - if (!start) { - start = { node: view[0].measure.map[2], offset: 0 }; - } else if (!end) { // FIXME dangerously hacky - var measure = view[view.length - 1].measure; - var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; - end = { node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3] }; - } - - try { var rng = range(start.node, start.offset, end.offset, end.node); } - catch (e) { } // Our model of the DOM might be outdated, in which case the range we try to set can be impossible - if (rng) { - if (!gecko && this.cm.state.focused) { - sel.collapse(start.node, start.offset); - if (!rng.collapsed) sel.addRange(rng); - } else { - sel.removeAllRanges(); - sel.addRange(rng); - } - if (old && sel.anchorNode == null) sel.addRange(old); - else if (gecko) this.startGracePeriod(); - } - this.rememberSelection(); - }, - - startGracePeriod: function () { - var input = this; - clearTimeout(this.gracePeriod); - this.gracePeriod = setTimeout(function () { - input.gracePeriod = false; - if (input.selectionChanged()) - input.cm.operation(function () { input.cm.curOp.selectionChanged = true; }); - }, 20); - }, - - showMultipleSelections: function (info) { - removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); - removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); - }, - - rememberSelection: function () { - var sel = window.getSelection(); - this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; - this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; - }, - - selectionInEditor: function () { - var sel = window.getSelection(); - if (!sel.rangeCount) return false; - var node = sel.getRangeAt(0).commonAncestorContainer; - return contains(this.div, node); - }, - - focus: function () { - if (this.cm.options.readOnly != "nocursor") this.div.focus(); - }, - blur: function () { this.div.blur(); }, - getField: function () { return this.div; }, - - supportsTouch: function () { return true; }, - - receivedFocus: function () { - var input = this; - if (this.selectionInEditor()) - this.pollSelection(); - else - runInOp(this.cm, function () { input.cm.curOp.selectionChanged = true; }); - - function poll() { - if (input.cm.state.focused) { - input.pollSelection(); - input.polling.set(input.cm.options.pollInterval, poll); - } - } - this.polling.set(this.cm.options.pollInterval, poll); - }, - - selectionChanged: function () { - var sel = window.getSelection(); - return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || - sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; - }, - - pollSelection: function () { - if (!this.composing && !this.gracePeriod && this.selectionChanged()) { - var sel = window.getSelection(), cm = this.cm; - this.rememberSelection(); - var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); - var head = domToPos(cm, sel.focusNode, sel.focusOffset); - if (anchor && head) runInOp(cm, function () { - setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); - if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; - }); - } - }, - - pollContent: function () { - var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); - var from = sel.from(), to = sel.to(); - if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; - - var fromIndex; - if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { - var fromLine = lineNo(display.view[0].line); - var fromNode = display.view[0].node; - } else { - var fromLine = lineNo(display.view[fromIndex].line); - var fromNode = display.view[fromIndex - 1].node.nextSibling; - } - var toIndex = findViewIndex(cm, to.line); - if (toIndex == display.view.length - 1) { - var toLine = display.viewTo - 1; - var toNode = display.lineDiv.lastChild; - } else { - var toLine = lineNo(display.view[toIndex + 1].line) - 1; - var toNode = display.view[toIndex + 1].node.previousSibling; - } - - var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); - var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); - while (newText.length > 1 && oldText.length > 1) { - if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } - else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } - else break; - } - - var cutFront = 0, cutEnd = 0; - var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); - while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) - ++cutFront; - var newBot = lst(newText), oldBot = lst(oldText); - var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), - oldBot.length - (oldText.length == 1 ? cutFront : 0)); - while (cutEnd < maxCutEnd && - newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) - ++cutEnd; - - newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); - newText[0] = newText[0].slice(cutFront); - - var chFrom = Pos(fromLine, cutFront); - var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); - if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { - replaceRange(cm.doc, newText, chFrom, chTo, "+input"); - return true; - } - }, - - ensurePolled: function () { - this.forceCompositionEnd(); - }, - reset: function () { - this.forceCompositionEnd(); - }, - forceCompositionEnd: function () { - if (!this.composing || this.composing.handled) return; - this.applyComposition(this.composing); - this.composing.handled = true; - this.div.blur(); - this.div.focus(); - }, - applyComposition: function (composing) { - if (this.cm.isReadOnly()) - operation(this.cm, regChange)(this.cm) - else if (composing.data && composing.data != composing.startData) - operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); - }, - - setUneditable: function (node) { - node.contentEditable = "false" - }, - - onKeyPress: function (e) { - e.preventDefault(); - if (!this.cm.isReadOnly()) - operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); - }, - - readOnlyChanged: function (val) { - this.div.contentEditable = String(val != "nocursor") - }, - - onContextMenu: nothing, - resetPosition: nothing, - - needsContentAttribute: true - }, ContentEditableInput.prototype); - - function posToDOM(cm, pos) { - var view = findViewForLine(cm, pos.line); - if (!view || view.hidden) return null; - var line = getLine(cm.doc, pos.line); - var info = mapFromLineView(view, line, pos.line); - - var order = getOrder(line), side = "left"; - if (order) { - var partPos = getBidiPartAt(order, pos.ch); - side = partPos % 2 ? "right" : "left"; - } - var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); - result.offset = result.collapse == "right" ? result.end : result.start; - return result; - } - - function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } - - function domToPos(cm, node, offset) { - var lineNode; - if (node == cm.display.lineDiv) { - lineNode = cm.display.lineDiv.childNodes[offset]; - if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); - node = null; offset = 0; - } else { - for (lineNode = node; ; lineNode = lineNode.parentNode) { - if (!lineNode || lineNode == cm.display.lineDiv) return null; - if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; - } - } - for (var i = 0; i < cm.display.view.length; i++) { - var lineView = cm.display.view[i]; - if (lineView.node == lineNode) - return locateNodeInLineView(lineView, node, offset); - } - } - - function locateNodeInLineView(lineView, node, offset) { - var wrapper = lineView.text.firstChild, bad = false; - if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); - if (node == wrapper) { - bad = true; - node = wrapper.childNodes[offset]; - offset = 0; - if (!node) { - var line = lineView.rest ? lst(lineView.rest) : lineView.line; - return badPos(Pos(lineNo(line), line.text.length), bad); - } - } - - var textNode = node.nodeType == 3 ? node : null, topNode = node; - if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { - textNode = node.firstChild; - if (offset) offset = textNode.nodeValue.length; - } - while (topNode.parentNode != wrapper) topNode = topNode.parentNode; - var measure = lineView.measure, maps = measure.maps; - - function find(textNode, topNode, offset) { - for (var i = -1; i < (maps ? maps.length : 0); i++) { - var map = i < 0 ? measure.map : maps[i]; - for (var j = 0; j < map.length; j += 3) { - var curNode = map[j + 2]; - if (curNode == textNode || curNode == topNode) { - var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); - var ch = map[j] + offset; - if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; - return Pos(line, ch); - } - } - } - } - var found = find(textNode, topNode, offset); - if (found) return badPos(found, bad); - - // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems - for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { - found = find(after, after.firstChild, 0); - if (found) - return badPos(Pos(found.line, found.ch - dist), bad); - else - dist += after.textContent.length; - } - for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { - found = find(before, before.firstChild, -1); - if (found) - return badPos(Pos(found.line, found.ch + dist), bad); - else - dist += after.textContent.length; - } - } - - function domTextBetween(cm, from, to, fromLine, toLine) { - var text = "", closing = false, lineSep = cm.doc.lineSeparator(); - function recognizeMarker(id) { return function (marker) { return marker.id == id; }; } - function walk(node) { - if (node.nodeType == 1) { - var cmText = node.getAttribute("cm-text"); - if (cmText != null) { - if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); - text += cmText; - return; - } - var markerID = node.getAttribute("cm-marker"), range; - if (markerID) { - var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); - if (found.length && (range = found[0].find())) - text += getBetween(cm.doc, range.from, range.to).join(lineSep); - return; - } - if (node.getAttribute("contenteditable") == "false") return; - for (var i = 0; i < node.childNodes.length; i++) - walk(node.childNodes[i]); - if (/^(pre|div|p)$/i.test(node.nodeName)) - closing = true; - } else if (node.nodeType == 3) { - var val = node.nodeValue; - if (!val) return; - if (closing) { - text += lineSep; - closing = false; - } - text += val; - } - } - for (; ;) { - walk(from); - if (from == to) break; - from = from.nextSibling; - } - return text; - } - - CodeMirror.inputStyles = { "textarea": TextareaInput, "contenteditable": ContentEditableInput }; - - // SELECTION / CURSOR - - // Selection objects are immutable. A new one is created every time - // the selection changes. A selection is one or more non-overlapping - // (and non-touching) ranges, sorted, and an integer that indicates - // which one is the primary selection (the one that's scrolled into - // view, that getCursor returns, etc). - function Selection(ranges, primIndex) { - this.ranges = ranges; - this.primIndex = primIndex; - } - - Selection.prototype = { - primary: function () { return this.ranges[this.primIndex]; }, - equals: function (other) { - if (other == this) return true; - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; - for (var i = 0; i < this.ranges.length; i++) { - var here = this.ranges[i], there = other.ranges[i]; - if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; - } - return true; - }, - deepCopy: function () { - for (var out = [], i = 0; i < this.ranges.length; i++) - out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); - return new Selection(out, this.primIndex); - }, - somethingSelected: function () { - for (var i = 0; i < this.ranges.length; i++) - if (!this.ranges[i].empty()) return true; - return false; - }, - contains: function (pos, end) { - if (!end) end = pos; - for (var i = 0; i < this.ranges.length; i++) { - var range = this.ranges[i]; - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) - return i; - } - return -1; - } - }; - - function Range(anchor, head) { - this.anchor = anchor; this.head = head; - } - - Range.prototype = { - from: function () { return minPos(this.anchor, this.head); }, - to: function () { return maxPos(this.anchor, this.head); }, - empty: function () { - return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; - } - }; - - // Take an unsorted, potentially overlapping set of ranges, and - // build a selection out of it. 'Consumes' ranges array (modifying - // it). - function normalizeSelection(ranges, primIndex) { - var prim = ranges[primIndex]; - ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }); - primIndex = indexOf(ranges, prim); - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1]; - if (cmp(prev.to(), cur.from()) >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; - if (i <= primIndex) --primIndex; - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); - } - } - return new Selection(ranges, primIndex); - } - - function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0); - } - - // Most of the external API clips given positions to make sure they - // actually exist within the document. - function clipLine(doc, n) { return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1)); } - function clipPos(doc, pos) { - if (pos.line < doc.first) return Pos(doc.first, 0); - var last = doc.first + doc.size - 1; - if (pos.line > last) return Pos(last, getLine(doc, last).text.length); - return clipToLen(pos, getLine(doc, pos.line).text.length); - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) return Pos(pos.line, linelen); - else if (ch < 0) return Pos(pos.line, 0); - else return pos; - } - function isLine(doc, l) { return l >= doc.first && l < doc.first + doc.size; } - function clipPosArray(doc, array) { - for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); - return out; - } - - // SELECTION UPDATES - - // The 'scroll' parameter given to many of these indicated whether - // the new cursor position should be scrolled into view after - // modifying the selection. - - // If shift is held or the extend flag is set, extends a range to - // include a given position (and optionally a second position). - // Otherwise, simply returns the range between the given positions. - // Used for cursor motion and such. - function extendRange(doc, range, head, other) { - if (doc.cm && doc.cm.display.shift || doc.extend) { - var anchor = range.anchor; - if (other) { - var posBefore = cmp(head, anchor) < 0; - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head; - head = other; - } else if (posBefore != (cmp(head, other) < 0)) { - head = other; - } - } - return new Range(anchor, head); - } else { - return new Range(other || head, head); - } - } - - // Extend the primary selection range, discard the rest. - function extendSelection(doc, head, other, options) { - setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); - } - - // Extend all selections (pos is an array of selections with length - // equal the number of selections) - function extendSelections(doc, heads, options) { - for (var out = [], i = 0; i < doc.sel.ranges.length; i++) - out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); - var newSel = normalizeSelection(out, doc.sel.primIndex); - setSelection(doc, newSel, options); - } - - // Updates a single range in the selection. - function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0); - ranges[i] = range; - setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); - } - - // Reset the selection to a single range. - function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options); - } - - // Give beforeSelectionChange handlers a change to influence a - // selection update. - function filterSelectionChange(doc, sel, options) { - var obj = { - ranges: sel.ranges, - update: function (ranges) { - this.ranges = []; - for (var i = 0; i < ranges.length; i++) - this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)); - }, - origin: options && options.origin - }; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); - if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); - else return sel; - } - - function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done); - if (last && last.ranges) { - done[done.length - 1] = sel; - setSelectionNoUndo(doc, sel, options); - } else { - setSelection(doc, sel, options); - } - } - - // Set a new selection. - function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options); - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); - } - - function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) - sel = filterSelectionChange(doc, sel, options); - - var bias = options && options.bias || - (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); - - if (!(options && options.scroll === false) && doc.cm) - ensureCursorVisible(doc.cm); - } - - function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) return; - - doc.sel = sel; - - if (doc.cm) { - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; - signalCursorActivity(doc.cm); - } - signalLater(doc, "cursorActivity", doc); - } - - // Verify that the selection does not partially select any atomic - // marked ranges. - function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); - } - - // Return a selection that does not partially select any atomic - // ranges. - function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; - var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); - var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) out = sel.ranges.slice(0, i); - out[i] = new Range(newAnchor, newHead); - } - } - return out ? normalizeSelection(out, sel.primIndex) : sel; - } - - function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { - var line = getLine(doc, pos.line); - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) break; - else { --i; continue; } - } - } - if (!m.atomic) continue; - - if (oldPos) { - var near = m.find(dir < 0 ? 1 : -1), diff; - if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) - near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); - if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) - return skipAtomicInner(doc, near, pos, dir, mayClear); - } - - var far = m.find(dir < 0 ? -1 : 1); - if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) - far = movePos(doc, far, dir, far.line == pos.line ? line : null); - return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null; - } - } - return pos; - } - - // Ensure a given position is not inside an atomic range. - function skipAtomic(doc, pos, oldPos, bias, mayClear) { - var dir = bias || 1; - var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || - skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); - if (!found) { - doc.cantEdit = true; - return Pos(doc.first, 0); - } - return found; - } - - function movePos(doc, pos, dir, line) { - if (dir < 0 && pos.ch == 0) { - if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1)); - else return null; - } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { - if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0); - else return null; - } else { - return new Pos(pos.line, pos.ch + dir); - } - } - - // SELECTION DRAWING - - function updateSelection(cm) { - cm.display.input.showSelection(cm.display.input.prepareSelection()); - } - - function prepareSelection(cm, primary) { - var doc = cm.doc, result = {}; - var curFragment = result.cursors = document.createDocumentFragment(); - var selFragment = result.selection = document.createDocumentFragment(); - - for (var i = 0; i < doc.sel.ranges.length; i++) { - if (primary === false && i == doc.sel.primIndex) continue; - var range = doc.sel.ranges[i]; - if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue; - var collapsed = range.empty(); - if (collapsed || cm.options.showCursorWhenSelecting) - drawSelectionCursor(cm, range.head, curFragment); - if (!collapsed) - drawSelectionRange(cm, range, selFragment); - } - return result; - } - - // Draws a cursor for the given range - function drawSelectionCursor(cm, head, output) { - var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); - - var documentZoom = getDocumentZoom(); - - cursor.style.left = pos.left / documentZoom + "px"; - cursor.style.top = pos.top / documentZoom + "px"; - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight / documentZoom + "px"; - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); - otherCursor.style.display = ""; - otherCursor.style.left = pos.other.left / documentZoom + "px"; - otherCursor.style.top = pos.other.top / documentZoom + "px"; - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 / documentZoom + "px"; - } - } - - // Draws the given range as a highlighted selection - function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc; - var fragment = document.createDocumentFragment(); - var padding = paddingH(cm.display), leftSide = padding.left; - var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; - - function add(left, top, width, bottom) { - if (top < 0) top = 0; - top = Math.round(top); - bottom = Math.round(bottom); - - var documentZoom = getDocumentZoom(); - - fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left / documentZoom + - "px; top: " + top / documentZoom + "px; width: " + (width == null ? rightSide - left : width) / documentZoom + - "px; height: " + (bottom - top) / documentZoom + "px")); - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias); - } - - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right; - if (from == to) { - rightPos = leftPos; - left = right = leftPos.left; - } else { - rightPos = coords(to - 1, "right"); - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } - left = leftPos.left; - right = rightPos.right; - } - if (fromArg == null && from == 0) left = leftSide; - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom); - left = leftSide; - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); - } - if (toArg == null && to == lineLen) right = rightSide; - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos; - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos; - if (left < leftSide + 1) left = leftSide; - add(left, rightPos.top, right - left, rightPos.bottom); - }); - return { start: start, end: end }; - } - - var sFrom = range.from(), sTo = range.to(); - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch); - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); - var singleVLine = visualLine(fromLine) == visualLine(toLine); - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) - add(leftSide, leftEnd.bottom, null, rightStart.top); - } - - output.appendChild(fragment); - } - - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) return; - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursorDiv.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) - display.blinker = setInterval(function () { - display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - else if (cm.options.cursorBlinkRate < 0) - display.cursorDiv.style.visibility = "hidden"; - } - - // HIGHLIGHT WORKER - - function startWorker(cm, time) { - if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) - cm.state.highlight.set(time, bind(highlightWorker, cm)); - } - - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.frontier < doc.first) doc.frontier = doc.first; - if (doc.frontier >= cm.display.viewTo) return; - var end = +new Date + cm.options.workTime; - var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); - var changedLines = []; - - doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { - if (doc.frontier >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength; - var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true); - line.styles = highlighted.styles; - var oldCls = line.styleClasses, newCls = highlighted.classes; - if (newCls) line.styleClasses = newCls; - else if (oldCls) line.styleClasses = null; - var ischange = !oldStyles || oldStyles.length != line.styles.length || - oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); - for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; - if (ischange) changedLines.push(doc.frontier); - line.stateAfter = tooLong ? state : copyState(doc.mode, state); - } else { - if (line.text.length <= cm.options.maxHighlightLength) - processLine(cm, line.text, state); - line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; - } - ++doc.frontier; - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true; - } - }); - if (changedLines.length) runInOp(cm, function () { - for (var i = 0; i < changedLines.length; i++) - regLineChange(cm, changedLines[i], "text"); - }); - } - - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc; - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); - for (var search = n; search > lim; --search) { - if (search <= doc.first) return doc.first; - var line = getLine(doc, search - 1); - if (line.stateAfter && (!precise || search <= doc.frontier)) return search; - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline; - } - - function getStateBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) return true; - var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos - 1).stateAfter; - if (!state) state = startState(doc.mode); - else state = copyState(doc.mode, state); - doc.iter(pos, n, function (line) { - processLine(cm, line.text, state); - var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; - line.stateAfter = save ? copyState(doc.mode, state) : null; - ++pos; - }); - if (precise) doc.frontier = pos; - return state; - } - - // POSITION MEASUREMENT - - function paddingTop(display) { return display.lineSpace.offsetTop; } - function paddingVert(display) { return display.mover.offsetHeight - display.lineSpace.offsetHeight; } - function paddingH(display) { - if (display.cachedPaddingH) return display.cachedPaddingH; - var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; - var data = { left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight) }; - if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; - return data; - } - - function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } - function displayWidth(cm) { - return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; - } - function displayHeight(cm) { - return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; - } - - // Ensure the lineView.wrapping.heights array is populated. This is - // an array of bottom offsets for the lines that make up a drawn - // line. When lineWrapping is on, there might be more than one - // height. - function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping; - var curWidth = wrapping && displayWidth(cm); - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = []; - if (wrapping) { - lineView.measure.width = curWidth; - var rects = lineView.text.firstChild.getClientRects(); - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1]; - if (Math.abs(cur.bottom - next.bottom) > 2) - heights.push((cur.bottom + next.top) / 2 - rect.top); - } - } - heights.push(rect.bottom - rect.top); - } - } - - // Find a line map (mapping character offsets to text nodes) and a - // measurement cache for the given line number. (A line view might - // contain multiple lines when collapsed ranges are present.) - function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) - return { map: lineView.measure.map, cache: lineView.measure.cache }; - for (var i = 0; i < lineView.rest.length; i++) - if (lineView.rest[i] == line) - return { map: lineView.measure.maps[i], cache: lineView.measure.caches[i] }; - for (var i = 0; i < lineView.rest.length; i++) - if (lineNo(lineView.rest[i]) > lineN) - return { map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true }; - } - - // Render a line into the hidden node display.externalMeasured. Used - // when measurement is needed for a line that's not in the viewport. - function updateExternalMeasurement(cm, line) { - line = visualLine(line); - var lineN = lineNo(line); - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); - view.lineN = lineN; - var built = view.built = buildLineContent(cm, view); - view.text = built.pre; - removeChildrenAndAdd(cm.display.lineMeasure, built.pre); - return view; - } - - // Get a {top, bottom, left, right} box (in line-local coordinates) - // for a given character. - function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); - } - - // Find a line view that corresponds to the given line number. - function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) - return cm.display.view[findViewIndex(cm, lineN)]; - var ext = cm.display.externalMeasured; - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) - return ext; - } - - // Measurement can be split in two steps, the set-up work that - // applies to the whole line, and the measurement of the actual - // character. Functions like coordsChar, that need to do a lot of - // measurements in a row, can thus ensure that the set-up work is - // only done once. - function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line); - var view = findViewForLine(cm, lineN); - if (view && !view.text) { - view = null; - } else if (view && view.changes) { - updateLineForChanges(cm, view, lineN, getDimensions(cm)); - cm.curOp.forceUpdate = true; - } - if (!view) - view = updateExternalMeasurement(cm, line); - - var info = mapFromLineView(view, line, lineN); - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - }; - } - - // Given a prepared measurement object, measures the position of an - // actual character (or fetches it from the cache). - function measureCharPrepared(cm, prepared, ch, bias, varHeight) { - if (prepared.before) ch = -1; - var key = ch + (bias || ""), found; - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key]; - } else { - if (!prepared.rect) - prepared.rect = prepared.view.text.getBoundingClientRect(); - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect); - prepared.hasHeights = true; - } - found = measureCharInner(cm, prepared, ch, bias); - if (!found.bogus) prepared.cache[key] = found; - } - return { - left: found.left, right: found.right, - top: varHeight ? found.rtop : found.top, - bottom: varHeight ? found.rbottom : found.bottom - }; - } - - var nullRect = { left: 0, right: 0, top: 0, bottom: 0 }; - - function nodeAndOffsetInLineMap(map, ch, bias) { - var node, start, end, collapse; - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - var mStart = map[i], mEnd = map[i + 1]; - if (ch < mStart) { - start = 0; end = 1; - collapse = "left"; - } else if (ch < mEnd) { - start = ch - mStart; - end = start + 1; - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart; - start = end - 1; - if (ch >= mEnd) collapse = "right"; - } - if (start != null) { - node = map[i + 2]; - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) - collapse = bias; - if (bias == "left" && start == 0) - while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2]; - collapse = "left"; - } - if (bias == "right" && start == mEnd - mStart) - while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2]; - collapse = "right"; - } - break; - } - } - return { node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd }; - } - - function getUsefulRect(rects, bias) { - var rect = nullRect - if (bias == "left") for (var i = 0; i < rects.length; i++) { - if ((rect = rects[i]).left != rect.right) break - } else for (var i = rects.length - 1; i >= 0; i--) { - if ((rect = rects[i]).left != rect.right) break - } - return rect - } - - function measureCharInner(cm, prepared, ch, bias) { - var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); - var node = place.node, start = place.start, end = place.end, collapse = place.collapse; - - var rect; - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned - while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; - while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; - if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) - rect = node.parentNode.getBoundingClientRect(); - else - rect = getUsefulRect(range(node, start, end).getClientRects(), bias) - if (rect.left || rect.right || start == 0) break; - end = start; - start = start - 1; - collapse = "right"; - } - if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) collapse = bias = "right"; - var rects; - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = node.getBoundingClientRect(); - } - if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0]; - if (rSpan) - rect = { left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom }; - else - rect = nullRect; - } - - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; - var mid = (rtop + rbot) / 2; - var heights = prepared.view.measure.heights; - for (var i = 0; i < heights.length - 1; i++) - if (mid < heights[i]) break; - var top = i ? heights[i - 1] : 0, bot = heights[i]; - var result = { - left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot - }; - if (!rect.left && !rect.right) result.bogus = true; - if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } - - return result; - } - - // Work around problem with bounding client rects on ranges being - // returned incorrectly when zoomed on IE10 and below. - function maybeUpdateRectForZooming(measure, rect) { - if (!window.screen || screen.logicalXDPI == null || - screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) - return rect; - var scaleX = screen.logicalXDPI / screen.deviceXDPI; - var scaleY = screen.logicalYDPI / screen.deviceYDPI; - return { - left: rect.left * scaleX, right: rect.right * scaleX, - top: rect.top * scaleY, bottom: rect.bottom * scaleY - }; - } - - function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {}; - lineView.measure.heights = null; - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - lineView.measure.caches[i] = {}; - } - } - - function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null; - removeChildren(cm.display.lineMeasure); - for (var i = 0; i < cm.display.view.length; i++) - clearLineMeasurementCacheFor(cm.display.view[i]); - } - - function clearCaches(cm) { - clearLineMeasurementCache(cm); - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; - if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; - cm.display.lineNumChars = null; - } - - function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } - function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - - // Converts a {top, bottom, left, right} box from line-local - // coordinates into another coordinate system. Context may be one of - // "line", "div" (display.lineDiv), "local"/null (editor), "window", - // or "page". - function intoCoordSystem(cm, lineObj, rect, context) { - if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]); - rect.top += size; rect.bottom += size; - } - if (context == "line") return rect; - if (!context) context = "local"; - var yOff = heightAtLine(lineObj); - if (context == "local") yOff += paddingTop(cm.display); - else yOff -= cm.display.viewOffset; - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect(); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect; - } - - // Coverts a box from "div" coords to another coordinate system. - // Context may be "window", "page", "div", or "local"/null. - function fromCoordSystem(cm, coords, context) { - if (context == "div") return coords; - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect(); - left += localBox.left; - top += localBox.top; - } - - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); - return { left: left - lineSpaceBox.left, top: top - lineSpaceBox.top }; - } - - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) lineObj = getLine(cm.doc, pos.line); - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); - } - - // Returns a box for a given cursor position, which may have an - // 'other' property containing the position of the secondary cursor - // on a bidi boundary. - function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); - if (right) m.left = m.right; else m.right = m.left; - return intoCoordSystem(cm, lineObj, m, context); - } - function getBidi(ch, partPos) { - var part = order[partPos], right = part.level % 2; - if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { - part = order[--partPos]; - ch = bidiRight(part) - (part.level % 2 ? 0 : 1); - right = true; - } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { - part = order[++partPos]; - ch = bidiLeft(part) - part.level % 2; - right = false; - } - if (right && ch == part.to && ch > part.from) return get(ch - 1); - return get(ch, right); - } - var order = getOrder(lineObj), ch = pos.ch; - if (!order) return get(ch); - var partPos = getBidiPartAt(order, ch); - var val = getBidi(ch, partPos); - if (bidiOther != null) val.other = getBidi(ch, bidiOther); - return val; - } - - // Used to cheaply estimate the coordinates for a position. Used for - // intermediate scroll updates. - function estimateCoords(cm, pos) { - var left = 0, pos = clipPos(cm.doc, pos); - if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; - var lineObj = getLine(cm.doc, pos.line); - var top = heightAtLine(lineObj) + paddingTop(cm.display); - return { left: left, right: left, top: top, bottom: top + lineObj.height }; - } - - // Positions returned by coordsChar contain some extra information. - // xRel is the relative x position of the input coordinates compared - // to the found position (so xRel > 0 means the coordinates are to - // the right of the character position, for example). When outside - // is true, that means the coordinates lie outside the line's - // vertical range. - function PosWithInfo(line, ch, outside, xRel) { - var pos = Pos(line, ch); - pos.xRel = xRel; - if (outside) pos.outside = true; - return pos; - } - - // Compute the character position closest to the given coordinates. - // Input must be lineSpace-local ("div" coordinate system). - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) return PosWithInfo(doc.first, 0, true, -1); - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineN > last) - return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); - if (x < 0) x = 0; - - var lineObj = getLine(doc, lineN); - for (; ;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(0, true); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - lineN = lineNo(lineObj = mergedPos.to.line); - else - return found; - } - } - - function coordsCharInner(cm, lineObj, lineNo, x, y) { - var innerOff = y - heightAtLine(lineObj); - var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; - var preparedMeasure = prepareMeasureForLine(cm, lineObj); - - function getX(ch) { - var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); - wrongLine = true; - if (innerOff > sp.bottom) return sp.left - adjust; - else if (innerOff < sp.top) return sp.left + adjust; - else wrongLine = false; - return sp.left; - } - - var bidi = getOrder(lineObj), dist = lineObj.text.length; - var from = lineLeft(lineObj), to = lineRight(lineObj); - var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - - if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); - // Do a binary search between these bounds. - for (; ;) { - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { - var ch = x < fromX || x - fromX <= toX - x ? from : to; - var outside = ch == from ? fromOutside : toOutside - var xDiff = x - (ch == from ? fromX : toX); - // This is a kludge to handle the case where the coordinates - // are after a line-wrapped line. We should replace it with a - // more general handling of cursor positions around line - // breaks. (Issue #4078) - if (toOutside && !bidi && !/\s/.test(lineObj.text.charAt(ch)) && xDiff > 0 && - ch < lineObj.text.length && preparedMeasure.view.measure.heights.length > 1) { - var charSize = measureCharPrepared(cm, preparedMeasure, ch, "right"); - if (innerOff <= charSize.bottom && innerOff >= charSize.top && Math.abs(x - charSize.right) < xDiff) { - outside = false - ch++ - xDiff = x - charSize.right - } - } - while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; - var pos = PosWithInfo(lineNo, ch, outside, xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); - return pos; - } - var step = Math.ceil(dist / 2), middle = from + step; - if (bidi) { - middle = from; - for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); - } - var middleX = getX(middle); - if (middleX > x) { to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step; } - else { from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step; } - } - } - - var measureText; - // Compute the default text height. - function textHeight(display) { - if (display.cachedTextHeight != null) return display.cachedTextHeight; - if (measureText == null) { - measureText = elt("pre"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) display.cachedTextHeight = height; - removeChildren(display.measure); - return height || 1; - } - - // Compute the default character width. - function charWidth(display) { - if (display.cachedCharWidth != null) return display.cachedCharWidth; - var anchor = elt("span", "xxxxxxxxxx"); - var pre = elt("pre", [anchor]); - removeChildrenAndAdd(display.measure, pre); - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; - if (width > 2) display.cachedCharWidth = width; - return width || 10; - } - - // OPERATIONS - - // Operations are used to wrap a series of changes to the editor - // state in such a way that each change won't have to update the - // cursor and display (which would be awkward, slow, and - // error-prone). Instead, display updates are batched and then all - // combined and executed at once. - - var operationGroup = null; - - var nextOpId = 0; - // Start a new operation. - function startOperation(cm) { - cm.curOp = { - cm: cm, - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: null, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - focus: false, - id: ++nextOpId // Unique ID - }; - if (operationGroup) { - operationGroup.ops.push(cm.curOp); - } else { - cm.curOp.ownsGroup = operationGroup = { - ops: [cm.curOp], - delayedCallbacks: [] - }; - } - } - - function fireCallbacksForOps(group) { - // Calls delayed callbacks and cursorActivity handlers until no - // new ones appear - var callbacks = group.delayedCallbacks, i = 0; - do { - for (; i < callbacks.length; i++) - callbacks[i].call(null); - for (var j = 0; j < group.ops.length; j++) { - var op = group.ops[j]; - if (op.cursorActivityHandlers) - while (op.cursorActivityCalled < op.cursorActivityHandlers.length) - op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); - } - } while (i < callbacks.length); - } - - // Finish an operation, updating the display and signalling delayed events - function endOperation(cm) { - var op = cm.curOp, group = op.ownsGroup; - if (!group) return; - - try { fireCallbacksForOps(group); } - finally { - operationGroup = null; - for (var i = 0; i < group.ops.length; i++) - group.ops[i].cm.curOp = null; - endOperations(group); - } - } - - // The DOM updates done when an operation finishes are batched so - // that the minimum number of relayouts are required. - function endOperations(group) { - var ops = group.ops; - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_R1(ops[i]); - for (var i = 0; i < ops.length; i++) // Write DOM (maybe) - endOperation_W1(ops[i]); - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_R2(ops[i]); - for (var i = 0; i < ops.length; i++) // Write DOM (maybe) - endOperation_W2(ops[i]); - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_finish(ops[i]); - } - - function endOperation_R1(op) { - var cm = op.cm, display = cm.display; - maybeClipScrollbars(cm); - if (op.updateMaxLine) findMaxLine(cm); - - op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping; - op.update = op.mustUpdate && - new DisplayUpdate(cm, op.mustUpdate && { top: op.scrollTop, ensure: op.scrollToPos }, op.forceUpdate); - } - - function endOperation_W1(op) { - op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); - } - - function endOperation_R2(op) { - var cm = op.cm, display = cm.display; - if (op.updatedDisplay) updateHeightsInViewport(cm); - - op.barMeasure = measureForScrollbars(cm); - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - // updateDisplay_W2 will use these properties to do the actual resizing - if (display.maxLineChanged && !cm.options.lineWrapping) { - op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; - cm.display.sizerWidth = op.adjustWidthTo; - op.barMeasure.scrollWidth = - Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); - op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); - } - - if (op.updatedDisplay || op.selectionChanged) - op.preparedSelection = display.input.prepareSelection(op.focus); - } - - function endOperation_W2(op) { - var cm = op.cm; - - if (op.adjustWidthTo != null) { - cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; - if (op.maxScrollLeft < cm.doc.scrollLeft) - setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); - cm.display.maxLineChanged = false; - } - - var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()) - if (op.preparedSelection) - cm.display.input.showSelection(op.preparedSelection, takeFocus); - if (op.updatedDisplay || op.startHeight != cm.doc.height) - updateScrollbars(cm, op.barMeasure); - if (op.updatedDisplay) - setDocumentHeight(cm, op.barMeasure); - - if (op.selectionChanged) restartBlink(cm); - - if (cm.state.focused && op.updateInput) - cm.display.input.reset(op.typing); - if (takeFocus) ensureFocus(op.cm); - } - - function endOperation_finish(op) { - var cm = op.cm, display = cm.display, doc = cm.doc; - - if (op.updatedDisplay) postUpdateDisplay(cm, op.update); - - // Abort mouse wheel delta measurement, when scrolling explicitly - if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) - display.wheelStartX = display.wheelStartY = null; - - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { - doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); - display.scrollbars.setScrollTop(doc.scrollTop); - display.scroller.scrollTop = doc.scrollTop; - } - if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { - doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); - display.scrollbars.setScrollLeft(doc.scrollLeft); - display.scroller.scrollLeft = doc.scrollLeft; - alignHorizontally(cm); - } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), - clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); - if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); - } - - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) for (var i = 0; i < hidden.length; ++i) - if (!hidden[i].lines.length) signal(hidden[i], "hide"); - if (unhidden) for (var i = 0; i < unhidden.length; ++i) - if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - - if (display.wrapper.offsetHeight) - doc.scrollTop = cm.display.scroller.scrollTop; - - // Fire change events, and delayed event handlers - if (op.changeObjs) - signal(cm, "changes", cm, op.changeObjs); - if (op.update) - op.update.finish(); - } - - // Run the given function in an operation - function runInOp(cm, f) { - if (cm.curOp) return f(); - startOperation(cm); - try { return f(); } - finally { endOperation(cm); } - } - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm, f) { - return function () { - if (cm.curOp) return f.apply(cm, arguments); - startOperation(cm); - try { return f.apply(cm, arguments); } - finally { endOperation(cm); } - }; - } - // Used to add methods to editor and doc instances, wrapping them in - // operations. - function methodOp(f) { - return function () { - if (this.curOp) return f.apply(this, arguments); - startOperation(this); - try { return f.apply(this, arguments); } - finally { endOperation(this); } - }; - } - function docMethodOp(f) { - return function () { - var cm = this.cm; - if (!cm || cm.curOp) return f.apply(this, arguments); - startOperation(cm); - try { return f.apply(this, arguments); } - finally { endOperation(cm); } - }; - } - - // VIEW TRACKING - - // These objects are used to represent the visible (currently drawn) - // part of the document. A LineView may correspond to multiple - // logical lines, if those are connected by collapsed ranges. - function LineView(doc, line, lineN) { - // The starting line - this.line = line; - // Continuing lines, if any - this.rest = visualLineContinued(line); - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; - this.node = this.text = null; - this.hidden = lineIsHidden(doc, line); - } - - // Create a range of LineView objects for the given lines. - function buildViewArray(cm, from, to) { - var array = [], nextPos; - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); - nextPos = pos + view.size; - array.push(view); - } - return array; - } - - // Updates the display.view data structure for a given change to the - // document. From and to are in pre-change coordinates. Lendiff is - // the amount of lines added or subtracted by the change. This is - // used for changes that span multiple lines, or change the way - // lines are divided into visual lines. regLineChange (below) - // registers single-line changes. - function regChange(cm, from, to, lendiff) { - if (from == null) from = cm.doc.first; - if (to == null) to = cm.doc.first + cm.doc.size; - if (!lendiff) lendiff = 0; - - var display = cm.display; - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) - display.updateLineNumbers = from; - - cm.curOp.viewChanged = true; - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) - resetView(cm); - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm); - } else { - display.viewFrom += lendiff; - display.viewTo += lendiff; - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm); - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cut) { - display.view = display.view.slice(cut.index); - display.viewFrom = cut.lineN; - display.viewTo += lendiff; - } else { - resetView(cm); - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut = viewCuttingPoint(cm, from, from, -1); - if (cut) { - display.view = display.view.slice(0, cut.index); - display.viewTo = cut.lineN; - } else { - resetView(cm); - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1); - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)); - display.viewTo += lendiff; - } else { - resetView(cm); - } - } - - var ext = display.externalMeasured; - if (ext) { - if (to < ext.lineN) - ext.lineN += lendiff; - else if (from < ext.lineN + ext.size) - display.externalMeasured = null; - } - } - - // Register a change to a single line. Type must be one of "text", - // "gutter", "class", "widget" - function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true; - var display = cm.display, ext = cm.display.externalMeasured; - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) - display.externalMeasured = null; - - if (line < display.viewFrom || line >= display.viewTo) return; - var lineView = display.view[findViewIndex(cm, line)]; - if (lineView.node == null) return; - var arr = lineView.changes || (lineView.changes = []); - if (indexOf(arr, type) == -1) arr.push(type); - } - - // Clear the view. - function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first; - cm.display.view = []; - cm.display.viewOffset = 0; - } - - // Find the view element corresponding to a given line. Return null - // when the line isn't visible. - function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) return null; - n -= cm.display.viewFrom; - if (n < 0) return null; - var view = cm.display.view; - for (var i = 0; i < view.length; i++) { - n -= view[i].size; - if (n < 0) return i; - } - } - - function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view; - if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) - return { index: index, lineN: newN }; - for (var i = 0, n = cm.display.viewFrom; i < index; i++) - n += view[i].size; - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) return null; - diff = (n + view[index].size) - oldN; - index++; - } else { - diff = n - oldN; - } - oldN += diff; newN += diff; - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) return null; - newN += dir * view[index - (dir < 0 ? 1 : 0)].size; - index += dir; - } - return { index: index, lineN: newN }; - } - - // Force the view to cover a given range, adding empty view element - // or clipping off existing ones as needed. - function adjustView(cm, from, to) { - var display = cm.display, view = display.view; - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to); - display.viewFrom = from; - } else { - if (display.viewFrom > from) - display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); - else if (display.viewFrom < from) - display.view = display.view.slice(findViewIndex(cm, from)); - display.viewFrom = from; - if (display.viewTo < to) - display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); - else if (display.viewTo > to) - display.view = display.view.slice(0, findViewIndex(cm, to)); - } - display.viewTo = to; - } - - // Count the number of lines in the view whose DOM representation is - // out of date (or nonexistent). - function countDirtyView(cm) { - var view = cm.display.view, dirty = 0; - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; - } - return dirty; - } - - // EVENT HANDLERS - - // Attach the necessary event handlers when initializing the editor - function registerEventHandlers(cm) { - var d = cm.display; - on(d.scroller, "mousedown", operation(cm, onMouseDown)); - // Older IE's will not fire a second mousedown for a double click - if (ie && ie_version < 11) - on(d.scroller, "dblclick", operation(cm, function (e) { - if (signalDOMEvent(cm, e)) return; - var pos = posFromMouse(cm, e); - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; - e_preventDefault(e); - var word = cm.findWordAt(pos); - extendSelection(cm.doc, word.anchor, word.head); - })); - else - on(d.scroller, "dblclick", function (e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); - // Some browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for these browsers. - if (!captureRightClick) on(d.scroller, "contextmenu", function (e) { onContextMenu(cm, e); }); - - // Used to suppress mouse event handling when a touch happens - var touchFinished, prevTouch = { end: 0 }; - function finishTouch() { - if (d.activeTouch) { - touchFinished = setTimeout(function () { d.activeTouch = null; }, 1000); - prevTouch = d.activeTouch; - prevTouch.end = +new Date; - } - }; - function isMouseLikeTouchEvent(e) { - if (e.touches.length != 1) return false; - var touch = e.touches[0]; - return touch.radiusX <= 1 && touch.radiusY <= 1; - } - function farAway(touch, other) { - if (other.left == null) return true; - var dx = other.left - touch.left, dy = other.top - touch.top; - return dx * dx + dy * dy > 20 * 20; - } - on(d.scroller, "touchstart", function (e) { - if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { - clearTimeout(touchFinished); - var now = +new Date; - d.activeTouch = { - start: now, moved: false, - prev: now - prevTouch.end <= 300 ? prevTouch : null - }; - if (e.touches.length == 1) { - d.activeTouch.left = e.touches[0].pageX; - d.activeTouch.top = e.touches[0].pageY; - } - } - }); - on(d.scroller, "touchmove", function () { - if (d.activeTouch) d.activeTouch.moved = true; - }); - on(d.scroller, "touchend", function (e) { - var touch = d.activeTouch; - if (touch && !eventInWidget(d, e) && touch.left != null && - !touch.moved && new Date - touch.start < 300) { - var pos = cm.coordsChar(d.activeTouch, "page"), range; - if (!touch.prev || farAway(touch, touch.prev)) // Single tap - range = new Range(pos, pos); - else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap - range = cm.findWordAt(pos); - else // Triple tap - range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); - cm.setSelection(range.anchor, range.head); - cm.focus(); - e_preventDefault(e); - } - finishTouch(); - }); - on(d.scroller, "touchcancel", finishTouch); - - // Sync scrolling between fake scrollbars and real scrollable - // area, ensure viewport is updated when scrolling. - on(d.scroller, "scroll", function () { - if (d.scroller.clientHeight) { - setScrollTop(cm, d.scroller.scrollTop); - setScrollLeft(cm, d.scroller.scrollLeft, true); - signal(cm, "scroll", cm); - } - }); - - // Listen to wheel events in order to try and update the viewport on time. - on(d.scroller, "mousewheel", function (e) { onScrollWheel(cm, e); }); - on(d.scroller, "DOMMouseScroll", function (e) { onScrollWheel(cm, e); }); - - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function () { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - - d.dragFunctions = { - enter: function (e) { if (!signalDOMEvent(cm, e)) e_stop(e); }, - over: function (e) { if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); } }, - start: function (e) { onDragStart(cm, e); }, - drop: operation(cm, onDrop), - leave: function (e) { if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); } } - }; - - var inp = d.input.getField(); - on(inp, "keyup", function (e) { onKeyUp.call(cm, e); }); - on(inp, "keydown", operation(cm, onKeyDown)); - on(inp, "keypress", operation(cm, onKeyPress)); - on(inp, "focus", bind(onFocus, cm)); - on(inp, "blur", bind(onBlur, cm)); - } - - function dragDropChanged(cm, value, old) { - var wasOn = old && old != CodeMirror.Init; - if (!value != !wasOn) { - var funcs = cm.display.dragFunctions; - var toggle = value ? on : off; - toggle(cm.display.scroller, "dragstart", funcs.start); - toggle(cm.display.scroller, "dragenter", funcs.enter); - toggle(cm.display.scroller, "dragover", funcs.over); - toggle(cm.display.scroller, "dragleave", funcs.leave); - toggle(cm.display.scroller, "drop", funcs.drop); - } - } - - // Called when the window resizes - function onResize(cm) { - var d = cm.display; - if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) - return; - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - d.scrollbarsClipped = false; - cm.setSize(); - } - - // MOUSE EVENTS - - // Return true when the given mouse event happened in a widget - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || - (n.parentNode == display.sizer && n != display.mover)) - return true; - } - } - - // Given a mouse event, find the corresponding position. If liberal - // is false, it checks whether a gutter or scrollbar was clicked, - // and returns null if it was. forRect is used by rectangular - // selections, and tries to estimate a character position even for - // coordinates beyond the right of the text. - function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display; - if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; - - var x, y, space = display.lineSpace.getBoundingClientRect(); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top; } - catch (e) { return null; } - var coords = coordsChar(cm, x, y), line; - if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); - } - return coords; - } - - // A mouse down can be a single click, double click, triple click, - // start of selection drag, start of text drag, new cursor - // (ctrl-click), rectangle drag (alt-drag), or xwin - // middle-click-paste. Or it might be a click on something we should - // not interfere with, such as a scrollbar or widget. - function onMouseDown(e) { - var cm = this, display = cm.display; - if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return; - display.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false; - setTimeout(function () { display.scroller.draggable = true; }, 100); - } - return; - } - if (clickInGutter(cm, e)) return; - var start = posFromMouse(cm, e); - window.focus(); - - switch (e_button(e)) { - case 1: - // #3261: make sure, that we're not starting a second selection - if (cm.state.selectingText) - cm.state.selectingText(e); - else if (start) - leftButtonDown(cm, e, start); - else if (e_target(e) == display.scroller) - e_preventDefault(e); - break; - case 2: - if (webkit) cm.state.lastMiddleDown = +new Date; - if (start) extendSelection(cm.doc, start); - setTimeout(function () { display.input.focus(); }, 20); - e_preventDefault(e); - break; - case 3: - if (captureRightClick) onContextMenu(cm, e); - else delayBlurEvent(cm); - break; - } - } - - var lastClick, lastDoubleClick; - function leftButtonDown(cm, e, start) { - if (ie) setTimeout(bind(ensureFocus, cm), 0); - else cm.curOp.focus = activeElt(); - - var now = +new Date, type; - if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { - type = "triple"; - } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { - type = "double"; - lastDoubleClick = { time: now, pos: start }; - } else { - type = "single"; - lastClick = { time: now, pos: start }; - } - - var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; - if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && - type == "single" && (contained = sel.contains(start)) > -1 && - (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && - (cmp(contained.to(), start) > 0 || start.xRel < 0)) - leftButtonStartDrag(cm, e, start, modifier); - else - leftButtonSelect(cm, e, start, type, modifier); - } - - // Start a text drag. When it ends, see if any dragging actually - // happen, and treat as a click if it didn't. - function leftButtonStartDrag(cm, e, start, modifier) { - var display = cm.display, startTime = +new Date; - var dragEnd = operation(cm, function (e2) { - if (webkit) display.scroller.draggable = false; - cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(display.scroller, "drop", dragEnd); - if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { - e_preventDefault(e2); - if (!modifier && +new Date - 200 < startTime) - extendSelection(cm.doc, start); - // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) - if (webkit || ie && ie_version == 9) - setTimeout(function () { document.body.focus(); display.input.focus(); }, 20); - else - display.input.focus(); - } - }); - // Let the drag handler handle this. - if (webkit) display.scroller.draggable = true; - cm.state.draggingText = dragEnd; - dragEnd.copy = mac ? e.altKey : e.ctrlKey - // IE's approach to draggable - if (display.scroller.dragDrop) display.scroller.dragDrop(); - on(document, "mouseup", dragEnd); - on(display.scroller, "drop", dragEnd); - } - - // Normal selection, as opposed to text dragging. - function leftButtonSelect(cm, e, start, type, addNew) { - var display = cm.display, doc = cm.doc; - e_preventDefault(e); - - var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; - if (addNew && !e.shiftKey) { - ourIndex = doc.sel.contains(start); - if (ourIndex > -1) - ourRange = ranges[ourIndex]; - else - ourRange = new Range(start, start); - } else { - ourRange = doc.sel.primary(); - ourIndex = doc.sel.primIndex; - } - - if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) { - type = "rect"; - if (!addNew) ourRange = new Range(start, start); - start = posFromMouse(cm, e, true, true); - ourIndex = -1; - } else if (type == "double") { - var word = cm.findWordAt(start); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, word.anchor, word.head); - else - ourRange = word; - } else if (type == "triple") { - var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, line.anchor, line.head); - else - ourRange = line; - } else { - ourRange = extendRange(doc, ourRange, start); - } - - if (!addNew) { - ourIndex = 0; - setSelection(doc, new Selection([ourRange], 0), sel_mouse); - startSel = doc.sel; - } else if (ourIndex == -1) { - ourIndex = ranges.length; - setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), - { scroll: false, origin: "*mouse" }); - } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { - setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), - { scroll: false, origin: "*mouse" }); - startSel = doc.sel; - } else { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); - } - - var lastPos = start; - function extendTo(pos) { - if (cmp(lastPos, pos) == 0) return; - lastPos = pos; - - if (type == "rect") { - var ranges = [], tabSize = cm.options.tabSize; - var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); - var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); - var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); - for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); - line <= end; line++) { - var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); - if (left == right) - ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); - else if (text.length > leftPos) - ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); - } - if (!ranges.length) ranges.push(new Range(start, start)); - setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), - { origin: "*mouse", scroll: false }); - cm.scrollIntoView(pos); - } else { - var oldRange = ourRange; - var anchor = oldRange.anchor, head = pos; - if (type != "single") { - if (type == "double") - var range = cm.findWordAt(pos); - else - var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); - if (cmp(range.anchor, anchor) > 0) { - head = range.head; - anchor = minPos(oldRange.from(), range.anchor); - } else { - head = range.anchor; - anchor = maxPos(oldRange.to(), range.head); - } - } - var ranges = startSel.ranges.slice(0); - ranges[ourIndex] = new Range(clipPos(doc, anchor), head); - setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); - } - } - - var editorSize = display.wrapper.getBoundingClientRect(); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true, type == "rect"); - if (!cur) return; - if (cmp(cur, lastPos) != 0) { - cm.curOp.focus = activeElt(); - extendTo(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) - setTimeout(operation(cm, function () { if (counter == curCount) extend(e); }), 150); - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) setTimeout(operation(cm, function () { - if (counter != curCount) return; - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - - function done(e) { - cm.state.selectingText = false; - counter = Infinity; - e_preventDefault(e); - display.input.focus(); - off(document, "mousemove", move); - off(document, "mouseup", up); - doc.history.lastSelOrigin = null; - } - - var move = operation(cm, function (e) { - if (!e_button(e)) done(e); - else extend(e); - }); - var up = operation(cm, done); - cm.state.selectingText = up; - on(document, "mousemove", move); - on(document, "mouseup", up); - } - - // Determines whether an event happened in the gutter, and fires the - // handlers for the corresponding event. - function gutterEvent(cm, e, type, prevent) { - try { var mX = e.clientX, mY = e.clientY; } - catch (e) { return false; } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; - if (prevent) e_preventDefault(e); - - var display = cm.display; - var lineBox = display.lineDiv.getBoundingClientRect(); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.options.gutters[i]; - signal(cm, type, cm, line, gutter, e); - return e_defaultPrevented(e); - } - } - } - - function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true); - } - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - clearDragCursor(cm); - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) - return; - e_preventDefault(e); - if (ie) lastDrop = +new Date; - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || cm.isReadOnly()) return; - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var loadFile = function (file, i) { - if (cm.options.allowDropFileTypes && - indexOf(cm.options.allowDropFileTypes, file.type) == -1) - return; - - var reader = new FileReader; - reader.onload = operation(cm, function () { - var content = reader.result; - if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = ""; - text[i] = content; - if (++read == n) { - pos = clipPos(cm.doc, pos); - var change = { - from: pos, to: pos, - text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), - origin: "paste" - }; - makeChange(cm.doc, change); - setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); - } - }); - reader.readAsText(file); - }; - for (var i = 0; i < n; ++i) loadFile(files[i], i); - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(function () { cm.display.input.focus(); }, 20); - return; - } - try { - var text = e.dataTransfer.getData("Text"); - if (text) { - if (cm.state.draggingText && !cm.state.draggingText.copy) - var selected = cm.listSelections(); - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); - if (selected) for (var i = 0; i < selected.length; ++i) - replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); - cm.replaceSelection(text, "around", "paste"); - cm.display.input.focus(); - } - } - catch (e) { } - } - } - - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - - e.dataTransfer.setData("Text", cm.getSelection()); - e.dataTransfer.effectAllowed = "copyMove" - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (presto) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (presto) img.parentNode.removeChild(img); - } - } - - function onDragOver(cm, e) { - var pos = posFromMouse(cm, e); - if (!pos) return; - var frag = document.createDocumentFragment(); - drawSelectionCursor(cm, pos, frag); - if (!cm.display.dragCursor) { - cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); - cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); - } - removeChildrenAndAdd(cm.display.dragCursor, frag); - } - - function clearDragCursor(cm) { - if (cm.display.dragCursor) { - cm.display.lineSpace.removeChild(cm.display.dragCursor); - cm.display.dragCursor = null; - } - } - - // SCROLL EVENTS - - // Sync the scrollable area and scrollbars, ensure the viewport - // covers the visible area. - function setScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) return; - cm.doc.scrollTop = val; - if (!gecko) updateDisplaySimple(cm, { top: val }); - if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; - cm.display.scrollbars.setScrollTop(val); - if (gecko) updateDisplaySimple(cm); - startWorker(cm, 100); - } - // Sync scroller and scrollbar, ensure the gutter elements are - // aligned. - function setScrollLeft(cm, val, isScroller) { - if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; - cm.display.scrollbars.setScrollLeft(val); - } - - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) wheelPixelsPerUnit = -.53; - else if (gecko) wheelPixelsPerUnit = 15; - else if (chrome) wheelPixelsPerUnit = -.7; - else if (safari) wheelPixelsPerUnit = -1 / 3; - - var wheelEventDelta = function (e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; - else if (dy == null) dy = e.wheelDelta; - return { x: dx, y: dy }; - }; - CodeMirror.wheelEventPixels = function (e) { - var delta = wheelEventDelta(e); - delta.x *= wheelPixelsPerUnit; - delta.y *= wheelPixelsPerUnit; - return delta; - }; - - function onScrollWheel(cm, e) { - var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - var canScrollX = scroll.scrollWidth > scroll.clientWidth; - var canScrollY = scroll.scrollHeight > scroll.clientHeight; - if (!(dx && canScrollX || dy && canScrollY)) return; - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur; - break outer; - } - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy && canScrollY) - setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); - setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); - // Only prevent default scrolling if vertical scrolling is - // actually possible. Otherwise, it causes vertical scroll - // jitter on OSX trackpads when deltaX is small and deltaY - // is large (issue #3579) - if (!dy || (dy && canScrollY)) - e_preventDefault(e); - display.wheelStartX = null; // Abort measurement, if in progress - return; - } - - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) top = Math.max(0, top + pixels - 50); - else bot = Math.min(cm.doc.height, bot + pixels + 50); - updateDisplaySimple(cm, { top: top, bottom: bot }); - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function () { - if (display.wheelStartX == null) return; - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) return; - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } - - // KEY EVENTS - - // Run a handler that was bound to a key. - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) return false; - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - cm.display.input.ensurePolled(); - var prevShift = cm.display.shift, done = false; - try { - if (cm.isReadOnly()) cm.state.suppressEdits = true; - if (dropShift) cm.display.shift = false; - done = bound(cm) != Pass; - } finally { - cm.display.shift = prevShift; - cm.state.suppressEdits = false; - } - return done; - } - - function lookupKeyForEditor(cm, name, handle) { - for (var i = 0; i < cm.state.keyMaps.length; i++) { - var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); - if (result) return result; - } - return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) - || lookupKey(name, cm.options.keyMap, handle, cm); - } - - var stopSeq = new Delayed; - function dispatchKey(cm, name, e, handle) { - var seq = cm.state.keySeq; - if (seq) { - if (isModifierKey(name)) return "handled"; - stopSeq.set(50, function () { - if (cm.state.keySeq == seq) { - cm.state.keySeq = null; - cm.display.input.reset(); - } - }); - name = seq + " " + name; - } - var result = lookupKeyForEditor(cm, name, handle); - - if (result == "multi") - cm.state.keySeq = name; - if (result == "handled") - signalLater(cm, "keyHandled", cm, name, e); - - if (result == "handled" || result == "multi") { - e_preventDefault(e); - restartBlink(cm); - } - - if (seq && !result && /\'$/.test(name)) { - e_preventDefault(e); - return true; - } - return !!result; - } - - // Handle a key from the keydown event. - function handleKeyBinding(cm, e) { - var name = keyName(e, true); - if (!name) return false; - - if (e.shiftKey && !cm.state.keySeq) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) - || dispatchKey(cm, name, e, function (b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - return doHandleBinding(cm, b); - }); - } else { - return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }); - } - } - - // Handle a key from the keypress event - function handleCharBinding(cm, e, ch) { - return dispatchKey(cm, "'" + ch + "'", e, - function (b) { return doHandleBinding(cm, b, true); }); - } - - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - cm.curOp.focus = activeElt(); - if (signalDOMEvent(cm, e)) return; - // IE does strange things with escape. - if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; - var code = e.keyCode; - cm.display.shift = code == 16 || e.shiftKey; - var handled = handleKeyBinding(cm, e); - if (presto) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - cm.replaceSelection("", null, "cut"); - } - - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) - showCrossHair(cm); - } - - function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv; - addClass(lineDiv, "CodeMirror-crosshair"); - - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair"); - off(document, "keyup", up); - off(document, "mouseover", up); - } - } - on(document, "keyup", up); - on(document, "mouseover", up); - } - - function onKeyUp(e) { - if (e.keyCode == 16) this.doc.sel.shift = false; - signalDOMEvent(this, e); - } - - function onKeyPress(e) { - var cm = this; - if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; - var keyCode = e.keyCode, charCode = e.charCode; - if (presto && keyCode == lastStoppedKey) { lastStoppedKey = null; e_preventDefault(e); return; } - if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - if (handleCharBinding(cm, e, ch)) return; - cm.display.input.onKeyPress(e); - } - - // FOCUS/BLUR EVENTS - - function delayBlurEvent(cm) { - cm.state.delayingBlurEvent = true; - setTimeout(function () { - if (cm.state.delayingBlurEvent) { - cm.state.delayingBlurEvent = false; - onBlur(cm); - } - }, 100); - } - - function onFocus(cm) { - if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; - - if (cm.options.readOnly == "nocursor") return; - if (!cm.state.focused) { - signal(cm, "focus", cm); - cm.state.focused = true; - addClass(cm.display.wrapper, "CodeMirror-focused"); - // This test prevents this from firing when a context - // menu is closed (since the input reset would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { - cm.display.input.reset(); - if (webkit) setTimeout(function () { cm.display.input.reset(true); }, 20); // Issue #1730 - } - cm.display.input.receivedFocus(); - } - restartBlink(cm); - } - function onBlur(cm) { - if (cm.state.delayingBlurEvent) return; - - if (cm.state.focused) { - signal(cm, "blur", cm); - cm.state.focused = false; - rmClass(cm.display.wrapper, "CodeMirror-focused"); - } - clearInterval(cm.display.blinker); - setTimeout(function () { if (!cm.state.focused) cm.display.shift = false; }, 150); - } - - // CONTEXT MENU HANDLING - - // To make the context menu work, we need to briefly unhide the - // textarea (making it as unobtrusive as possible) to let the - // right-click take effect on it. - function onContextMenu(cm, e) { - if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; - if (signalDOMEvent(cm, e, "contextmenu")) return; - cm.display.input.onContextMenu(e); - } - - function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) return false; - return gutterEvent(cm, e, "gutterContextMenu", false); - } - - // UPDATING - - // Compute the position of the end of a change (its 'to' property - // refers to the pre-change end). - var changeEnd = CodeMirror.changeEnd = function (change) { - if (!change.text) return change.to; - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); - }; - - // Adjust a position to refer to the post-change position of the - // same text, or the end of the change if the change covers it. - function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) return pos; - if (cmp(pos, change.to) <= 0) return changeEnd(change); - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; - return Pos(line, ch); - } - - function computeSelAfterChange(doc, change) { - var out = []; - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))); - } - return normalizeSelection(out, doc.sel.primIndex); - } - - function offsetPos(pos, old, nw) { - if (pos.line == old.line) - return Pos(nw.line, pos.ch - old.ch + nw.ch); - else - return Pos(nw.line + (pos.line - old.line), pos.ch); - } - - // Used by replaceSelections to allow moving the selection to the - // start or around the replaced test. Hint may be "start" or "around". - function computeReplacedSel(doc, changes, hint) { - var out = []; - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - var from = offsetPos(change.from, oldPrev, newPrev); - var to = offsetPos(changeEnd(change), oldPrev, newPrev); - oldPrev = change.to; - newPrev = to; - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; - out[i] = new Range(inv ? to : from, inv ? from : to); - } else { - out[i] = new Range(from, from); - } - } - return new Selection(out, doc.sel.primIndex); - } - - // Allow "beforeChange" event handlers to influence a change - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function () { this.canceled = true; } - }; - if (update) obj.update = function (from, to, text, origin) { - if (from) this.from = clipPos(doc, from); - if (to) this.to = clipPos(doc, to); - if (text) this.text = text; - if (origin !== undefined) this.origin = origin; - }; - signal(doc, "beforeChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - - if (obj.canceled) return null; - return { from: obj.from, to: obj.to, text: obj.text, origin: obj.origin }; - } - - // Apply a change to a document, and add it to the document's - // history, and propagating it to all linked documents. - function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); - if (doc.cm.state.suppressEdits) return; - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) return; - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 0; --i) - makeChangeInner(doc, { from: split[i].from, to: split[i].to, text: i ? [""] : change.text }); - } else { - makeChangeInner(doc, change); - } - } - - function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; - var selAfter = computeSelAfterChange(doc, change); - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; - - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } - - // Revert a change stored in a document's history. - function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) return; - - var hist = doc.history, event, selAfter = doc.sel; - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; - - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - for (var i = 0; i < source.length; i++) { - event = source[i]; - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) - break; - } - if (i == source.length) return; - hist.lastOrigin = hist.lastSelOrigin = null; - - for (; ;) { - event = source.pop(); - if (event.ranges) { - pushSelectionToHistory(event, dest); - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, { clearRedo: false }); - return; - } - selAfter = event; - } - else break; - } - - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = []; - pushSelectionToHistory(selAfter, dest); - dest.push({ changes: antiChanges, generation: hist.generation }); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - for (var i = event.changes.length - 1; i >= 0; --i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - source.length = 0; - return; - } - - antiChanges.push(historyChangeFromChange(doc, change)); - - var after = i ? computeSelAfterChange(doc, change) : lst(source); - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - if (!i && doc.cm) doc.cm.scrollIntoView({ from: change.from, to: changeEnd(change) }); - var rebased = []; - - // Propagate to the linked documents - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - } - } - - // Sub-views need their line numbers shifted when text is added - // above or below them in the parent document. - function shiftDoc(doc, distance) { - if (distance == 0) return; - doc.first += distance; - doc.sel = new Selection(map(doc.sel.ranges, function (range) { - return new Range(Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch)); - }), doc.sel.primIndex); - if (doc.cm) { - regChange(doc.cm, doc.first, doc.first - distance, distance); - for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) - regLineChange(doc.cm, l, "gutter"); - } - } - - // More lower-level change function, handling only a single document - // (not linked ones). - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return; - } - if (change.from.line > doc.lastLine()) return; - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = { - from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin - }; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = { - from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin - }; - } - - change.removed = getBetween(doc, change.from, change.to); - - if (!selAfter) selAfter = computeSelAfterChange(doc, change); - if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); - else updateDoc(doc, change, spans); - setSelectionNoUndo(doc, selAfter, sel_dontScroll); - } - - // Handle the interaction of a change to a document with the editor - // that this document is part of. - function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function (line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true; - } - }); - } - - if (doc.sel.contains(change.from, change.to) > -1) - signalCursorActivity(cm); - - updateDoc(doc, change, spans, estimateHeight(cm)); - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function (line) { - var len = lineLength(line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) cm.curOp.updateMaxLine = true; - } - - // Adjust frontier, schedule worker - doc.frontier = Math.min(doc.frontier, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - if (change.full) - regChange(cm); - else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) - regLineChange(cm, from.line, "text"); - else - regChange(cm, from.line, to.line + 1, lendiff); - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - }; - if (changeHandler) signalLater(cm, "change", cm, obj); - if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); - } - cm.display.selForContextMenu = null; - } - - function replaceRange(doc, code, from, to, origin) { - if (!to) to = from; - if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } - if (typeof code == "string") code = doc.splitLines(code); - makeChange(doc, { from: from, to: to, text: code, origin: origin }); - } - - // SCROLLING THINGS INTO VIEW - - // If an editor sits on the top or bottom of the window, partially - // scrolled out of view, this ensures that the cursor is visible. - function maybeScrollWindow(cm, coords) { - if (signalDOMEvent(cm, "scrollCursorIntoView")) return; - - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; - if (coords.top + box.top < 0) doScroll = true; - else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + - (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + - (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + - coords.left + "px; width: 2px;"); - cm.display.lineSpace.appendChild(scrollNode); - scrollNode.scrollIntoView(doScroll); - cm.display.lineSpace.removeChild(scrollNode); - } - } - - // Scroll a given position into view (immediately), verifying that - // it actually became visible (as line heights are accurately - // measured, the position of something may 'drift' during drawing). - function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) margin = 0; - for (var limit = 0; limit < 5; limit++) { - var changed = false, coords = cursorCoords(cm, pos); - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); - var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), - Math.min(coords.top, endCoords.top) - margin, - Math.max(coords.left, endCoords.left), - Math.max(coords.bottom, endCoords.bottom) + margin); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - setScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; - } - if (!changed) break; - } - return coords; - } - - // Scroll a given set of coordinates into view (immediately). - function scrollIntoView(cm, x1, y1, x2, y2) { - var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); - if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); - if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); - } - - // Calculate a new scroll position needed to scroll the given - // rectangle into view. Returns an object with scrollTop and - // scrollLeft properties. When these are undefined, the - // vertical/horizontal position does not need to be adjusted. - function calculateScrollPos(cm, x1, y1, x2, y2) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (y1 < 0) y1 = 0; - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; - var screen = displayHeight(cm), result = {}; - if (y2 - y1 > screen) y2 = y1 + screen; - var docBottom = cm.doc.height + paddingVert(display); - var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; - if (y1 < screentop) { - result.scrollTop = atTop ? 0 : y1; - } else if (y2 > screentop + screen) { - var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); - if (newTop != screentop) result.scrollTop = newTop; - } - - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; - var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); - var tooWide = x2 - x1 > screenw; - if (tooWide) x2 = x1 + screenw; - if (x1 < 10) - result.scrollLeft = 0; - else if (x1 < screenleft) - result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); - else if (x2 > screenw + screenleft - 3) - result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; - return result; - } - - // Store a relative adjustment to the scroll position in the current - // operation (to be applied when the operation finishes). - function addToScrollPos(cm, left, top) { - if (left != null || top != null) resolveScrollToPos(cm); - if (left != null) - cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; - if (top != null) - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; - } - - // Make sure that at the end of the operation the current cursor is - // shown. - function ensureCursorVisible(cm) { - resolveScrollToPos(cm); - var cur = cm.getCursor(), from = cur, to = cur; - if (!cm.options.lineWrapping) { - from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; - to = Pos(cur.line, cur.ch + 1); - } - cm.curOp.scrollToPos = { from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true }; - } - - // When an operation has its scrollToPos property set, and another - // scroll action is applied before the end of the operation, this - // 'simulates' scrolling that position into view in a cheap way, so - // that the effect of intermediate scroll commands is not ignored. - function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos; - if (range) { - cm.curOp.scrollToPos = null; - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); - var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), - Math.min(from.top, to.top) - range.margin, - Math.max(from.right, to.right), - Math.max(from.bottom, to.bottom) + range.margin); - cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - } - - // API UTILITIES - - // Indent the given line. The how parameter can be "smart", - // "add"/null, "subtract", or "prev". When aggressive is false - // (typically set to true for forced single-line indents), empty - // lines are not indented, and places where the mode returns Pass - // are left alone. - function indentLine(cm, n, how, aggressive) { - var doc = cm.doc, state; - if (how == null) how = "add"; - if (how == "smart") { - // Fall back to "prev" when the mode doesn't have an indentation - // method. - if (!doc.mode.indent) how = "prev"; - else state = getStateBefore(cm, n); - } - - var tabSize = cm.options.tabSize; - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); - if (line.stateAfter) line.stateAfter = null; - var curSpaceString = line.text.match(/^\s*/)[0], indentation; - if (!aggressive && !/\S/.test(line.text)) { - indentation = 0; - how = "not"; - } else if (how == "smart") { - indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); - if (indentation == Pass || indentation > 150) { - if (!aggressive) return; - how = "prev"; - } - } - if (how == "prev") { - if (n > doc.first) indentation = countColumn(getLine(doc, n - 1).text, null, tabSize); - else indentation = 0; - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit; - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit; - } else if (typeof how == "number") { - indentation = curSpace + how; - } - indentation = Math.max(0, indentation); - - var indentString = "", pos = 0; - if (cm.options.indentWithTabs) - for (var i = Math.floor(indentation / tabSize); i; --i) { pos += tabSize; indentString += "\t"; } - if (pos < indentation) indentString += spaceStr(indentation - pos); - - if (indentString != curSpaceString) { - replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); - line.stateAfter = null; - return true; - } else { - // Ensure that, if the cursor was in the whitespace at the start - // of the line, it is moved to the end of that space. - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - if (range.head.line == n && range.head.ch < curSpaceString.length) { - var pos = Pos(n, curSpaceString.length); - replaceOneSelection(doc, i, new Range(pos, pos)); - break; - } - } - } - } - - // Utility for applying a change to a line by handle or number, - // returning the number and optionally registering the line as - // changed. - function changeLine(doc, handle, changeType, op) { - var no = handle, line = handle; - if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); - else no = lineNo(handle); - if (no == null) return null; - if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); - return line; - } - - // Helper for deleting text near the selection(s), used to implement - // backspace, delete, and similar functionality. - function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = []; - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]); - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop(); - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from; - break; - } - } - kill.push(toKill); - } - // Next, remove those actual ranges. - runInOp(cm, function () { - for (var i = kill.length - 1; i >= 0; i--) - replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); - ensureCursorVisible(cm); - }); - } - - // Used for horizontal relative motion. Dir is -1 or 1 (left or - // right), unit can be "char", "column" (like char, but doesn't - // cross line boundaries), "word" (across next word), or "group" (to - // the start of next group of word or non-word-non-whitespace - // chars). The visually param controls whether, in right-to-left - // text, direction 1 means to move towards the next index in the - // string, or towards the character to the right of the current - // position. The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosH(doc, pos, dir, unit, visually) { - var line = pos.line, ch = pos.ch, origDir = dir; - var lineObj = getLine(doc, line); - function findNextLine() { - var l = line + dir; - if (l < doc.first || l >= doc.first + doc.size) return false - line = l; - return lineObj = getLine(doc, l); - } - function moveOnce(boundToLine) { - var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); - if (next == null) { - if (!boundToLine && findNextLine()) { - if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); - else ch = dir < 0 ? lineObj.text.length : 0; - } else return false - } else ch = next; - return true; - } - - if (unit == "char") { - moveOnce() - } else if (unit == "column") { - moveOnce(true) - } else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group"; - var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); - for (var first = true; ; first = false) { - if (dir < 0 && !moveOnce(!first)) break; - var cur = lineObj.text.charAt(ch) || "\n"; - var type = isWordChar(cur, helper) ? "w" - : group && cur == "\n" ? "n" - : !group || /\s/.test(cur) ? null - : "p"; - if (group && !first && !type) type = "s"; - if (sawType && sawType != type) { - if (dir < 0) { dir = 1; moveOnce(); } - break; - } - - if (type) sawType = type; - if (dir > 0 && !moveOnce(!first)) break; - } - } - var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true); - if (!cmp(pos, result)) result.hitSide = true; - return result; - } - - // For relative vertical movement. Dir may be -1 or 1. Unit can be - // "page" or "line". The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y; - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); - y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3; - } - for (; ;) { - var target = coordsChar(cm, x, y); - if (!target.outside) break; - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } - y += dir * 5; - } - return target; - } - - // EDITOR METHODS - - // The publicly visible API. Note that methodOp(f) means - // 'wrap f in an operation, performed on its `this` parameter'. - - // This is not the complete set of editor methods. Most of the - // methods defined on the Doc type are also injected into - // CodeMirror.prototype, for backwards compatibility and - // convenience. - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function () { window.focus(); this.display.input.focus(); }, - - setOption: function (option, value) { - var options = this.options, old = options[option]; - if (options[option] == value && option != "mode") return; - options[option] = value; - if (optionHandlers.hasOwnProperty(option)) - operation(this, optionHandlers[option])(this, value, old); - }, - - getOption: function (option) { return this.options[option]; }, - getDoc: function () { return this.doc; }, - - addKeyMap: function (map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); - }, - removeKeyMap: function (map) { - var maps = this.state.keyMaps; - for (var i = 0; i < maps.length; ++i) - if (maps[i] == map || maps[i].name == map) { - maps.splice(i, 1); - return true; - } - }, - - addOverlay: methodOp(function (spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); - if (mode.startState) throw new Error("Overlays may not be stateful."); - this.state.overlays.push({ mode: mode, modeSpec: spec, opaque: options && options.opaque }); - this.state.modeGen++; - regChange(this); - }), - removeOverlay: methodOp(function (spec) { - var overlays = this.state.overlays; - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec; - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1); - this.state.modeGen++; - regChange(this); - return; - } - } - }), - - indentLine: methodOp(function (n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; - else dir = dir ? "add" : "subtract"; - } - if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); - }), - indentSelection: methodOp(function (how) { - var ranges = this.doc.sel.ranges, end = -1; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty()) { - var from = range.from(), to = range.to(); - var start = Math.max(end, from.line); - end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; - for (var j = start; j < end; ++j) - indentLine(this, j, how); - var newRanges = this.doc.sel.ranges; - if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) - replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); - } else if (range.head.line > end) { - indentLine(this, range.head.line, how, true); - end = range.head.line; - if (i == this.doc.sel.primIndex) ensureCursorVisible(this); - } - } - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function (pos, precise) { - return takeToken(this, pos, precise); - }, - - getLineTokens: function (line, precise) { - return takeToken(this, Pos(line), precise, true); - }, - - getTokenTypeAt: function (pos) { - pos = clipPos(this.doc, pos); - var styles = getLineStyles(this, getLine(this.doc, pos.line)); - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; - var type; - if (ch == 0) type = styles[2]; - else for (; ;) { - var mid = (before + after) >> 1; - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; - else if (styles[mid * 2 + 1] < ch) before = mid + 1; - else { type = styles[mid * 2 + 2]; break; } - } - var cut = type ? type.indexOf("cm-overlay ") : -1; - return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); - }, - - getModeAt: function (pos) { - var mode = this.doc.mode; - if (!mode.innerMode) return mode; - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; - }, - - getHelper: function (pos, type) { - return this.getHelpers(pos, type)[0]; - }, - - getHelpers: function (pos, type) { - var found = []; - if (!helpers.hasOwnProperty(type)) return found; - var help = helpers[type], mode = this.getModeAt(pos); - if (typeof mode[type] == "string") { - if (help[mode[type]]) found.push(help[mode[type]]); - } else if (mode[type]) { - for (var i = 0; i < mode[type].length; i++) { - var val = help[mode[type][i]]; - if (val) found.push(val); - } - } else if (mode.helperType && help[mode.helperType]) { - found.push(help[mode.helperType]); - } else if (help[mode.name]) { - found.push(help[mode.name]); - } - for (var i = 0; i < help._global.length; i++) { - var cur = help._global[i]; - if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) - found.push(cur.val); - } - return found; - }, - - getStateAfter: function (line, precise) { - var doc = this.doc; - line = clipLine(doc, line == null ? doc.first + doc.size - 1 : line); - return getStateBefore(this, line + 1, precise); - }, - - cursorCoords: function (start, mode) { - var pos, range = this.doc.sel.primary(); - if (start == null) pos = range.head; - else if (typeof start == "object") pos = clipPos(this.doc, start); - else pos = start ? range.from() : range.to(); - return cursorCoords(this, pos, mode || "page"); - }, - - charCoords: function (pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page"); - }, - - coordsChar: function (coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page"); - return coordsChar(this, coords.left, coords.top); - }, - - lineAtHeight: function (height, mode) { - height = fromCoordSystem(this, { top: height, left: 0 }, mode || "page").top; - return lineAtHeight(this.doc, height + this.display.viewOffset); - }, - heightAtLine: function (line, mode) { - var end = false, lineObj; - if (typeof line == "number") { - var last = this.doc.first + this.doc.size - 1; - if (line < this.doc.first) line = this.doc.first; - else if (line > last) { line = last; end = true; } - lineObj = getLine(this.doc, line); - } else { - lineObj = line; - } - return intoCoordSystem(this, lineObj, { top: 0, left: 0 }, mode || "page").top + - (end ? this.doc.height - heightAtLine(lineObj) : 0); - }, - - defaultTextHeight: function () { return textHeight(this.display); }, - defaultCharWidth: function () { return charWidth(this.display); }, - - setGutterMarker: methodOp(function (line, gutterID, value) { - return changeLine(this.doc, line, "gutter", function (line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) line.gutterMarkers = null; - return true; - }); - }), - - clearGutter: methodOp(function (gutterID) { - var cm = this, doc = cm.doc, i = doc.first; - doc.iter(function (line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - line.gutterMarkers[gutterID] = null; - regLineChange(cm, i, "gutter"); - if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; - } - ++i; - }); - }), - - lineInfo: function (line) { - if (typeof line == "number") { - if (!isLine(this.doc, line)) return null; - var n = line; - line = getLine(this.doc, line); - if (!line) return null; - } else { - var n = lineNo(line); - if (n == null) return null; - } - return { - line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets - }; - }, - - getViewport: function () { return { from: this.display.viewFrom, to: this.display.viewTo }; }, - - addWidget: function (pos, node, scroll, vert, horiz) { - var display = this.display; - pos = cursorCoords(this, clipPos(this.doc, pos)); - var top = pos.bottom, left = pos.left; - node.style.position = "absolute"; - node.setAttribute("cm-ignore-events", "true"); - this.display.input.setUneditable(node); - display.sizer.appendChild(node); - if (vert == "over") { - top = pos.top; - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - top = pos.top - node.offsetHeight; - else if (pos.bottom + node.offsetHeight <= vspace) - top = pos.bottom; - if (left + node.offsetWidth > hspace) - left = hspace - node.offsetWidth; - } - node.style.top = top + "px"; - node.style.left = node.style.right = ""; - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth; - node.style.right = "0px"; - } else { - if (horiz == "left") left = 0; - else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; - node.style.left = left + "px"; - } - if (scroll) - scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); - }, - - triggerOnKeyDown: methodOp(onKeyDown), - triggerOnKeyPress: methodOp(onKeyPress), - triggerOnKeyUp: onKeyUp, - - execCommand: function (cmd) { - if (commands.hasOwnProperty(cmd)) - return commands[cmd].call(null, this); - }, - - triggerElectric: methodOp(function (text) { triggerElectric(this, text); }), - - findPosH: function (from, amount, unit, visually) { - var dir = 1; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - cur = findPosH(this.doc, cur, dir, unit, visually); - if (cur.hitSide) break; - } - return cur; - }, - - moveH: methodOp(function (dir, unit) { - var cm = this; - cm.extendSelectionsBy(function (range) { - if (cm.display.shift || cm.doc.extend || range.empty()) - return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); - else - return dir < 0 ? range.from() : range.to(); - }, sel_move); - }), - - deleteH: methodOp(function (dir, unit) { - var sel = this.doc.sel, doc = this.doc; - if (sel.somethingSelected()) - doc.replaceSelection("", null, "+delete"); - else - deleteNearSelection(this, function (range) { - var other = findPosH(doc, range.head, dir, unit, false); - return dir < 0 ? { from: other, to: range.head } : { from: range.head, to: other }; - }); - }), - - findPosV: function (from, amount, unit, goalColumn) { - var dir = 1, x = goalColumn; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - var coords = cursorCoords(this, cur, "div"); - if (x == null) x = coords.left; - else coords.left = x; - cur = findPosV(this, coords, dir, unit); - if (cur.hitSide) break; - } - return cur; - }, - - moveV: methodOp(function (dir, unit) { - var cm = this, doc = this.doc, goals = []; - var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); - doc.extendSelectionsBy(function (range) { - if (collapse) - return dir < 0 ? range.from() : range.to(); - var headPos = cursorCoords(cm, range.head, "div"); - if (range.goalColumn != null) headPos.left = range.goalColumn; - goals.push(headPos.left); - var pos = findPosV(cm, headPos, dir, unit); - if (unit == "page" && range == doc.sel.primary()) - addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); - return pos; - }, sel_move); - if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) - doc.sel.ranges[i].goalColumn = goals[i]; - }), - - // Find the word at the given position (as returned by coordsChar). - findWordAt: function (pos) { - var doc = this.doc, line = getLine(doc, pos.line).text; - var start = pos.ch, end = pos.ch; - if (line) { - var helper = this.getHelper(pos, "wordChars"); - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar, helper) - ? function (ch) { return isWordChar(ch, helper); } - : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); } - : function (ch) { return !/\s/.test(ch) && !isWordChar(ch); }; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)); - }, - - toggleOverwrite: function (value) { - if (value != null && value == this.state.overwrite) return; - if (this.state.overwrite = !this.state.overwrite) - addClass(this.display.cursorDiv, "CodeMirror-overwrite"); - else - rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); - - signal(this, "overwriteToggle", this, this.state.overwrite); - }, - hasFocus: function () { return this.display.input.getField() == activeElt(); }, - isReadOnly: function () { return !!(this.options.readOnly || this.doc.cantEdit); }, - - scrollTo: methodOp(function (x, y) { - if (x != null || y != null) resolveScrollToPos(this); - if (x != null) this.curOp.scrollLeft = x; - if (y != null) this.curOp.scrollTop = y; - }), - getScrollInfo: function () { - var scroller = this.display.scroller; - return { - left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, - width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, - clientHeight: displayHeight(this), clientWidth: displayWidth(this) - }; - }, - - scrollIntoView: methodOp(function (range, margin) { - if (range == null) { - range = { from: this.doc.sel.primary().head, to: null }; - if (margin == null) margin = this.options.cursorScrollMargin; - } else if (typeof range == "number") { - range = { from: Pos(range, 0), to: null }; - } else if (range.from == null) { - range = { from: range, to: null }; - } - if (!range.to) range.to = range.from; - range.margin = margin || 0; - - if (range.from.line != null) { - resolveScrollToPos(this); - this.curOp.scrollToPos = range; - } else { - var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), - Math.min(range.from.top, range.to.top) - range.margin, - Math.max(range.from.right, range.to.right), - Math.max(range.from.bottom, range.to.bottom) + range.margin); - this.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - }), - - setSize: methodOp(function (width, height) { - var cm = this; - function interpret(val) { - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; - } - if (width != null) cm.display.wrapper.style.width = interpret(width); - if (height != null) cm.display.wrapper.style.height = interpret(height); - if (cm.options.lineWrapping) clearLineMeasurementCache(this); - var lineNo = cm.display.viewFrom; - cm.doc.iter(lineNo, cm.display.viewTo, function (line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) - if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } - ++lineNo; - }); - cm.curOp.forceUpdate = true; - signal(cm, "refresh", this); - }), - - operation: function (f) { return runInOp(this, f); }, - - refresh: methodOp(function () { - var oldHeight = this.display.cachedTextHeight; - regChange(this); - this.curOp.forceUpdate = true; - clearCaches(this); - this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); - updateGutterSpace(this); - if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) - estimateLineHeights(this); - signal(this, "refresh", this); - }), - - swapDoc: methodOp(function (doc) { - var old = this.doc; - old.cm = null; - attachDoc(this, doc); - clearCaches(this); - this.display.input.reset(); - this.scrollTo(doc.scrollLeft, doc.scrollTop); - this.curOp.forceScroll = true; - signalLater(this, "swapDoc", this, old); - return old; - }), - - getInputField: function () { return this.display.input.getField(); }, - getWrapperElement: function () { return this.display.wrapper; }, - getScrollerElement: function () { return this.display.scroller; }, - getGutterElement: function () { return this.display.gutters; } - }; - eventMixin(CodeMirror); - - // OPTION DEFAULTS - - // The default configuration options. - var defaults = CodeMirror.defaults = {}; - // Functions to run when options are changed. - var optionHandlers = CodeMirror.optionHandlers = {}; - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) optionHandlers[name] = - notOnInit ? function (cm, val, old) { if (old != Init) handle(cm, val, old); } : handle; - } - - // Passed to option handlers when there is no old value. - var Init = CodeMirror.Init = { toString: function () { return "CodeMirror.Init"; } }; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function (cm, val) { - cm.setValue(val); - }, true); - option("mode", null, function (cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function (cm) { - resetModeState(cm); - clearCaches(cm); - regChange(cm); - }, true); - option("lineSeparator", null, function (cm, val) { - cm.doc.lineSep = val; - if (!val) return; - var newBreaks = [], lineNo = cm.doc.first; - cm.doc.iter(function (line) { - for (var pos = 0; ;) { - var found = line.text.indexOf(val, pos); - if (found == -1) break; - pos = found + val.length; - newBreaks.push(Pos(lineNo, found)); - } - lineNo++; - }); - for (var i = newBreaks.length - 1; i >= 0; i--) - replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) - }); - option("specialChars", /[\u0000-\u001f\u007f\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) { - cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); - if (old != CodeMirror.Init) cm.refresh(); - }); - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { cm.refresh(); }, true); - option("electricChars", true); - option("inputStyle", mobile ? "contenteditable" : "textarea", function () { - throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME - }, true); - option("rtlMoveVisually", !windows); - option("wholeLineUpdateBefore", true); - - option("theme", "default", function (cm) { - themeChanged(cm); - guttersChanged(cm); - }, true); - option("keyMap", "default", function (cm, val, old) { - var next = getKeyMap(val); - var prev = old != CodeMirror.Init && getKeyMap(old); - if (prev && prev.detach) prev.detach(cm, next); - if (next.attach) next.attach(cm, prev || null); - }); - option("extraKeys", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function (cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("fixedGutter", true, function (cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, function (cm) { updateScrollbars(cm); }, true); - option("scrollbarStyle", "native", function (cm) { - initScrollbars(cm); - updateScrollbars(cm); - cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); - cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); - }, true); - option("lineNumbers", false, function (cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("firstLineNumber", 1, guttersChanged, true); - option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("resetSelectionOnContextMenu", true); - option("lineWiseCopyCut", true); - - option("readOnly", false, function (cm, val) { - if (val == "nocursor") { - onBlur(cm); - cm.display.input.blur(); - cm.display.disabled = true; - } else { - cm.display.disabled = false; - } - cm.display.input.readOnlyChanged(val) - }); - option("disableInput", false, function (cm, val) { if (!val) cm.display.input.reset(); }, true); - option("dragDrop", true, dragDropChanged); - option("allowDropFileTypes", null); - - option("cursorBlinkRate", 530); - option("cursorScrollMargin", 0); - option("cursorHeight", 1, updateSelection, true); - option("singleCursorHeightPerLine", true, updateSelection, true); - option("workTime", 100); - option("workDelay", 100); - option("flattenSpans", true, resetModeState, true); - option("addModeClass", false, resetModeState, true); - option("pollInterval", 100); - option("undoDepth", 200, function (cm, val) { cm.doc.history.undoDepth = val; }); - option("historyEventDelay", 1250); - option("viewportMargin", 10, function (cm) { cm.refresh(); }, true); - option("maxHighlightLength", 10000, resetModeState, true); - option("moveInputWithCursor", true, function (cm, val) { - if (!val) cm.display.input.resetPosition(); - }); - - option("tabindex", null, function (cm, val) { - cm.display.input.getField().tabIndex = val || ""; - }); - option("autofocus", null); - - // MODE DEFINITION AND QUERYING - - // Known modes, by name and by MIME - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; - - // Extra arguments are stored as the mode's dependencies, which is - // used by (legacy) mechanisms like loadmode.js to automatically - // load a mode. (Preferred mechanism is the require/define calls.) - CodeMirror.defineMode = function (name, mode) { - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; - if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); - modes[name] = mode; - }; - - CodeMirror.defineMIME = function (mime, spec) { - mimeModes[mime] = spec; - }; - - // Given a MIME type, a {name, ...options} config object, or a name - // string, return a mode config object. - CodeMirror.resolveMode = function (spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - if (typeof found == "string") found = { name: found }; - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return CodeMirror.resolveMode("application/xml"); - } - if (typeof spec == "string") return { name: spec }; - else return spec || { name: "null" }; - }; - - // Given a mode spec (anything that resolveMode accepts), find and - // initialize an actual mode object. - CodeMirror.getMode = function (options, spec) { - var spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return CodeMirror.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) modeObj.helperType = spec.helperType; - if (spec.modeProps) for (var prop in spec.modeProps) - modeObj[prop] = spec.modeProps[prop]; - - return modeObj; - }; - - // Minimal default mode. - CodeMirror.defineMode("null", function () { - return { token: function (stream) { stream.skipToEnd(); } }; - }); - CodeMirror.defineMIME("text/plain", "null"); - - // This can be used to attach properties to mode objects from - // outside the actual mode definition. - var modeExtensions = CodeMirror.modeExtensions = {}; - CodeMirror.extendMode = function (mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - }; - - // EXTENSIONS - - CodeMirror.defineExtension = function (name, func) { - CodeMirror.prototype[name] = func; - }; - CodeMirror.defineDocExtension = function (name, func) { - Doc.prototype[name] = func; - }; - CodeMirror.defineOption = option; - - var initHooks = []; - CodeMirror.defineInitHook = function (f) { initHooks.push(f); }; - - var helpers = CodeMirror.helpers = {}; - CodeMirror.registerHelper = function (type, name, value) { - if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = { _global: [] }; - helpers[type][name] = value; - }; - CodeMirror.registerGlobalHelper = function (type, name, predicate, value) { - CodeMirror.registerHelper(type, name, value); - helpers[type]._global.push({ pred: predicate, val: value }); - }; - - // MODE STATE HANDLING - - // Utility functions for working with state. Exported because nested - // modes need to do this for their inner modes. - - var copyState = CodeMirror.copyState = function (mode, state) { - if (state === true) return state; - if (mode.copyState) return mode.copyState(state); - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) val = val.concat([]); - nstate[n] = val; - } - return nstate; - }; - - var startState = CodeMirror.startState = function (mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; - }; - - // Given a mode and a state (for that mode), find the inner mode and - // state at the position that the state refers to. - CodeMirror.innerMode = function (mode, state) { - while (mode.innerMode) { - var info = mode.innerMode(state); - if (!info || info.mode == mode) break; - state = info.state; - mode = info.mode; - } - return info || { mode: mode, state: state }; - }; - - // STANDARD COMMANDS - - // Commands are parameter-less actions that can be performed on an - // editor, mostly used for keybindings. - var commands = CodeMirror.commands = { - selectAll: function (cm) { cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll); }, - singleSelection: function (cm) { - cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); - }, - killLine: function (cm) { - deleteNearSelection(cm, function (range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length; - if (range.head.ch == len && range.head.line < cm.lastLine()) - return { from: range.head, to: Pos(range.head.line + 1, 0) }; - else - return { from: range.head, to: Pos(range.head.line, len) }; - } else { - return { from: range.from(), to: range.to() }; - } - }); - }, - deleteLine: function (cm) { - deleteNearSelection(cm, function (range) { - return { - from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) - }; - }); - }, - delLineLeft: function (cm) { - deleteNearSelection(cm, function (range) { - return { from: Pos(range.from().line, 0), to: range.from() }; - }); - }, - delWrappedLineLeft: function (cm) { - deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - var leftPos = cm.coordsChar({ left: 0, top: top }, "div"); - return { from: leftPos, to: range.from() }; - }); - }, - delWrappedLineRight: function (cm) { - deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - var rightPos = cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div"); - return { from: range.from(), to: rightPos }; - }); - }, - undo: function (cm) { cm.undo(); }, - redo: function (cm) { cm.redo(); }, - undoSelection: function (cm) { cm.undoSelection(); }, - redoSelection: function (cm) { cm.redoSelection(); }, - goDocStart: function (cm) { cm.extendSelection(Pos(cm.firstLine(), 0)); }, - goDocEnd: function (cm) { cm.extendSelection(Pos(cm.lastLine())); }, - goLineStart: function (cm) { - cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, - { origin: "+move", bias: 1 }); - }, - goLineStartSmart: function (cm) { - cm.extendSelectionsBy(function (range) { - return lineStartSmart(cm, range.head); - }, { origin: "+move", bias: 1 }); - }, - goLineEnd: function (cm) { - cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, - { origin: "+move", bias: -1 }); - }, - goLineRight: function (cm) { - cm.extendSelectionsBy(function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div"); - }, sel_move); - }, - goLineLeft: function (cm) { - cm.extendSelectionsBy(function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({ left: 0, top: top }, "div"); - }, sel_move); - }, - goLineLeftSmart: function (cm) { - cm.extendSelectionsBy(function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - var pos = cm.coordsChar({ left: 0, top: top }, "div"); - if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); - return pos; - }, sel_move); - }, - goLineUp: function (cm) { cm.moveV(-1, "line"); }, - goLineDown: function (cm) { cm.moveV(1, "line"); }, - goPageUp: function (cm) { cm.moveV(-1, "page"); }, - goPageDown: function (cm) { cm.moveV(1, "page"); }, - goCharLeft: function (cm) { cm.moveH(-1, "char"); }, - goCharRight: function (cm) { cm.moveH(1, "char"); }, - goColumnLeft: function (cm) { cm.moveH(-1, "column"); }, - goColumnRight: function (cm) { cm.moveH(1, "column"); }, - goWordLeft: function (cm) { cm.moveH(-1, "word"); }, - goGroupRight: function (cm) { cm.moveH(1, "group"); }, - goGroupLeft: function (cm) { cm.moveH(-1, "group"); }, - goWordRight: function (cm) { cm.moveH(1, "word"); }, - delCharBefore: function (cm) { cm.deleteH(-1, "char"); }, - delCharAfter: function (cm) { cm.deleteH(1, "char"); }, - delWordBefore: function (cm) { cm.deleteH(-1, "word"); }, - delWordAfter: function (cm) { cm.deleteH(1, "word"); }, - delGroupBefore: function (cm) { cm.deleteH(-1, "group"); }, - delGroupAfter: function (cm) { cm.deleteH(1, "group"); }, - indentAuto: function (cm) { cm.indentSelection("smart"); }, - indentMore: function (cm) { cm.indentSelection("add"); }, - indentLess: function (cm) { cm.indentSelection("subtract"); }, - insertTab: function (cm) { cm.replaceSelection("\t"); }, - insertSoftTab: function (cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from(); - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); - spaces.push(spaceStr(tabSize - col % tabSize)); - } - cm.replaceSelections(spaces); - }, - defaultTab: function (cm) { - if (cm.somethingSelected()) cm.indentSelection("add"); - else cm.execCommand("insertTab"); - }, - transposeChars: function (cm) { - runInOp(cm, function () { - var ranges = cm.listSelections(), newSel = []; - for (var i = 0; i < ranges.length; i++) { - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; - if (line) { - if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); - if (cur.ch > 0) { - cur = new Pos(cur.line, cur.ch + 1); - cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), - Pos(cur.line, cur.ch - 2), cur, "+transpose"); - } else if (cur.line > cm.doc.first) { - var prev = getLine(cm.doc, cur.line - 1).text; - if (prev) - cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + - prev.charAt(prev.length - 1), - Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); - } - } - newSel.push(new Range(cur, cur)); - } - cm.setSelections(newSel); - }); - }, - newlineAndIndent: function (cm) { - runInOp(cm, function () { - var len = cm.listSelections().length; - for (var i = 0; i < len; i++) { - var range = cm.listSelections()[i]; - cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input"); - cm.indentLine(range.from().line + 1, null, true); - } - ensureCursorVisible(cm); - }); - }, - openLine: function (cm) { cm.replaceSelection("\n", "start") }, - toggleOverwrite: function (cm) { cm.toggleOverwrite(); } - }; - - - // STANDARD KEYMAPS - - var keyMap = CodeMirror.keyMap = {}; - - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" - }; - // Note that the save and find-related commands aren't defined by - // default. User code or addons can define them. Unknown commands - // are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" - }; - // Very basic readline/emacs-style bindings, which are standard on Mac. - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", - "Ctrl-O": "openLine" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - fallthrough: ["basic", "emacsy"] - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - - // KEYMAP DISPATCH - - function normalizeKeyName(name) { - var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; - var alt, ctrl, shift, cmd; - for (var i = 0; i < parts.length - 1; i++) { - var mod = parts[i]; - if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; - else if (/^a(lt)?$/i.test(mod)) alt = true; - else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; - else if (/^s(hift)$/i.test(mod)) shift = true; - else throw new Error("Unrecognized modifier name: " + mod); - } - if (alt) name = "Alt-" + name; - if (ctrl) name = "Ctrl-" + name; - if (cmd) name = "Cmd-" + name; - if (shift) name = "Shift-" + name; - return name; - } - - // This is a kludge to keep keymaps mostly working as raw objects - // (backwards compatibility) while at the same time support features - // like normalization and multi-stroke key bindings. It compiles a - // new normalized keymap, and then updates the old object to reflect - // this. - CodeMirror.normalizeKeyMap = function (keymap) { - var copy = {}; - for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { - var value = keymap[keyname]; - if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; - if (value == "...") { delete keymap[keyname]; continue; } - - var keys = map(keyname.split(" "), normalizeKeyName); - for (var i = 0; i < keys.length; i++) { - var val, name; - if (i == keys.length - 1) { - name = keys.join(" "); - val = value; - } else { - name = keys.slice(0, i + 1).join(" "); - val = "..."; - } - var prev = copy[name]; - if (!prev) copy[name] = val; - else if (prev != val) throw new Error("Inconsistent bindings for " + name); - } - delete keymap[keyname]; - } - for (var prop in copy) keymap[prop] = copy[prop]; - return keymap; - }; - - var lookupKey = CodeMirror.lookupKey = function (key, map, handle, context) { - map = getKeyMap(map); - var found = map.call ? map.call(key, context) : map[key]; - if (found === false) return "nothing"; - if (found === "...") return "multi"; - if (found != null && handle(found)) return "handled"; - - if (map.fallthrough) { - if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") - return lookupKey(key, map.fallthrough, handle, context); - for (var i = 0; i < map.fallthrough.length; i++) { - var result = lookupKey(key, map.fallthrough[i], handle, context); - if (result) return result; - } - } - }; - - // Modifier key presses don't count as 'real' key presses for the - // purpose of keymap fallthrough. - var isModifierKey = CodeMirror.isModifierKey = function (value) { - var name = typeof value == "string" ? value : keyNames[value.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; - }; - - // Look up the name of a key as indicated by an event object. - var keyName = CodeMirror.keyName = function (event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) return false; - var base = keyNames[event.keyCode], name = base; - if (name == null || event.altGraphKey) return false; - if (event.altKey && base != "Alt") name = "Alt-" + name; - if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; - if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; - if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; - return name; - }; - - function getKeyMap(val) { - return typeof val == "string" ? keyMap[val] : val; - } - - // FROMTEXTAREA - - CodeMirror.fromTextArea = function (textarea, options) { - options = options ? copyObj(options) : {}; - options.value = textarea.value; - if (!options.tabindex && textarea.tabIndex) - options.tabindex = textarea.tabIndex; - if (!options.placeholder && textarea.placeholder) - options.placeholder = textarea.placeholder; - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = activeElt(); - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body; - } - - function save() { textarea.value = cm.getValue(); } - if (textarea.form) { - on(textarea.form, "submit", save); - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form, realSubmit = form.submit; - try { - var wrappedSubmit = form.submit = function () { - save(); - form.submit = realSubmit; - form.submit(); - form.submit = wrappedSubmit; - }; - } catch (e) { } - } - } - - options.finishInit = function (cm) { - cm.save = save; - cm.getTextArea = function () { return textarea; }; - cm.toTextArea = function () { - cm.toTextArea = isNaN; // Prevent this from being ran twice - save(); - textarea.parentNode.removeChild(cm.getWrapperElement()); - textarea.style.display = ""; - if (textarea.form) { - off(textarea.form, "submit", save); - if (typeof textarea.form.submit == "function") - textarea.form.submit = realSubmit; - } - }; - }; - - textarea.style.display = "none"; - var cm = CodeMirror(function (node) { - textarea.parentNode.insertBefore(node, textarea.nextSibling); - }, options); - return cm; - }; - - // STRING STREAM - - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. - - var StringStream = CodeMirror.StringStream = function (string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - }; - - StringStream.prototype = { - eol: function () { return this.pos >= this.string.length; }, - sol: function () { return this.pos == this.lineStart; }, - peek: function () { return this.string.charAt(this.pos) || undefined; }, - next: function () { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function (match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) { ++this.pos; return ch; } - }, - eatWhile: function (match) { - var start = this.pos; - while (this.eat(match)) { } - return this.pos > start; - }, - eatSpace: function () { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function () { this.pos = this.string.length; }, - skipTo: function (ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) { this.pos = found; return true; } - }, - backUp: function (n) { this.pos -= n; }, - column: function () { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - indentation: function () { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - match: function (pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function () { return this.string.slice(this.start, this.pos); }, - hideFirstChars: function (n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } - }; - - // TEXTMARKERS - - // Created with markText and setBookmark methods. A TextMarker is a - // handle that can be used to clear or find a marked position in the - // document. Line objects hold arrays (markedSpans) containing - // {from, to, marker} object pointing to such marker objects, and - // indicating that such a marker is present on that line. Multiple - // lines may point to the same marker when it spans across lines. - // The spans will have null for their from/to properties when the - // marker continues beyond the start/end of the line. Markers have - // links back to the lines they currently touch. - - var nextMarkerId = 0; - - var TextMarker = CodeMirror.TextMarker = function (doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - this.id = ++nextMarkerId; - }; - eventMixin(TextMarker); - - // Clear the marker. - TextMarker.prototype.clear = function () { - if (this.explicitlyCleared) return; - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) startOperation(cm); - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) signalLater(this, "clear", found.from, found.to); - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); - else if (cm) { - if (span.to != null) max = lineNo(line); - if (span.from != null) min = lineNo(line); - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) - updateLineHeight(line, textHeight(cm.display)); - } - if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { - var visual = visualLine(this.lines[i]), len = lineLength(visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - - if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) reCheckSelection(cm.doc); - } - if (cm) signalLater(cm, "markerCleared", cm, this); - if (withOp) endOperation(cm); - if (this.parent) this.parent.clear(); - }; - - // Find the position of the marker in the document. Returns a {from, - // to} object by default. Side can be passed to get a specific side - // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the - // Pos objects returned contain a line object, rather than a line - // number (used to prevent looking up the same line twice). - TextMarker.prototype.find = function (side, lineObj) { - if (side == null && this.type == "bookmark") side = 1; - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from); - if (side == -1) return from; - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to); - if (side == 1) return to; - } - } - return from && { from: from, to: to }; - }; - - // Signals that the marker's widget changed, and surrounding layout - // should be recomputed. - TextMarker.prototype.changed = function () { - var pos = this.find(-1, true), widget = this, cm = this.doc.cm; - if (!pos || !cm) return; - runInOp(cm, function () { - var line = pos.line, lineN = lineNo(pos.line); - var view = findViewForLine(cm, lineN); - if (view) { - clearLineMeasurementCacheFor(view); - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; - } - cm.curOp.updateMaxLine = true; - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height; - widget.height = null; - var dHeight = widgetHeight(widget) - oldHeight; - if (dHeight) - updateLineHeight(line, line.height + dHeight); - } - }); - }; - - TextMarker.prototype.attachLine = function (line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); - } - this.lines.push(line); - }; - TextMarker.prototype.detachLine = function (line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - - // Collapsed markers have unique ids, in order to be able to order - // them, which is needed for uniquely determining an outer marker - // when they overlap (they may nest, but not partially overlap). - var nextMarkerId = 0; - - // Create a marker, wire it up to the right lines, and - function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) return markTextShared(doc, from, to, options, type); - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); - - var marker = new TextMarker(doc, type), diff = cmp(from, to); - if (options) copyObj(options, marker, false); - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) - return marker; - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true; - marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); - if (options.insertLeft) marker.widgetNode.insertLeft = true; - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) - throw new Error("Inserting collapsed marker partially overlapping an existing one"); - sawCollapsedSpans = true; - } - - if (marker.addToHistory) - addChangeToHistory(doc, { from: from, to: to, origin: "markText" }, doc.sel, NaN); - - var curLine = from.line, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function (line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) - updateMaxLine = true; - if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)); - ++curLine; - }); - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) doc.iter(from.line, to.line + 1, function (line) { - if (lineIsHidden(doc, line)) updateLineHeight(line, 0); - }); - - if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function () { marker.clear(); }); - - if (marker.readOnly) { - sawReadOnlySpans = true; - if (doc.history.done.length || doc.history.undone.length) - doc.clearHistory(); - } - if (marker.collapsed) { - marker.id = ++nextMarkerId; - marker.atomic = true; - } - if (cm) { - // Sync editor state - if (updateMaxLine) cm.curOp.updateMaxLine = true; - if (marker.collapsed) - regChange(cm, from.line, to.line + 1); - else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) - for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); - if (marker.atomic) reCheckSelection(cm.doc); - signalLater(cm, "markerAdded", cm, marker); - } - return marker; - } - - // SHARED TEXTMARKERS - - // A shared marker spans multiple linked documents. It is - // implemented as a meta-marker-object controlling multiple normal - // markers. - var SharedTextMarker = CodeMirror.SharedTextMarker = function (markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0; i < markers.length; ++i) - markers[i].parent = this; - }; - eventMixin(SharedTextMarker); - - SharedTextMarker.prototype.clear = function () { - if (this.explicitlyCleared) return; - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) - this.markers[i].clear(); - signalLater(this, "clear"); - }; - SharedTextMarker.prototype.find = function (side, lineObj) { - return this.primary.find(side, lineObj); - }; - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.widgetNode; - linkedDocs(doc, function (doc) { - if (widget) options.widgetNode = widget.cloneNode(true); - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) - if (doc.linked[i].isParent) return; - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary); - } - - function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), - function (m) { return m.parent; }); - } - - function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find(); - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); - marker.markers.push(subMark); - subMark.parent = marker; - } - } - } - - function detachSharedMarkers(markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], linked = [marker.primary.doc];; - linkedDocs(marker.primary.doc, function (d) { linked.push(d); }); - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j]; - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null; - marker.markers.splice(j--, 1); - } - } - } - } - - // TEXTMARKER SPANS - - function MarkedSpan(marker, from, to) { - this.marker = marker; - this.from = from; this.to = to; - } - - // Search an array of spans for a span matching the given marker. - function getMarkedSpanFor(spans, marker) { - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) return span; - } - } - // Remove a span from an array, returning undefined if no spans are - // left (we don't store arrays for lines without spans). - function removeMarkedSpan(spans, span) { - for (var r, i = 0; i < spans.length; ++i) - if (spans[i] != span) (r || (r = [])).push(spans[i]); - return r; - } - // Add a span to a line. - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } - - // Used for the algorithm that adjusts markers for a change in the - // document. These functions cut an array of spans at a given - // character position, returning an array of remaining chunks (or - // undefined if nothing remains). - function markedSpansBefore(old, startCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); - (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); - } - } - return nw; - } - function markedSpansAfter(old, endCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); - (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)); - } - } - return nw; - } - - // Given a change object, compute the new set of marker spans that - // cover the line in which the change took place. Removes spans - // entirely within the change, reconnects spans belonging to the - // same marker that appear on both sides of the change, and cuts off - // spans partially within the change. Returns an array of span - // arrays with one element for each line in (after) the change. - function stretchSpansOverChange(doc, change) { - if (change.full) return null; - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) return null; - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) span.to = startCh; - else if (sameLine) span.to = found.to == null ? null : found.to + offset; - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i = 0; i < last.length; ++i) { - var span = last[i]; - if (span.to != null) span.to += offset; - if (span.from == null) { - var found = getMarkedSpanFor(first, span.marker); - if (!found) { - span.from = offset; - if (sameLine) (first || (first = [])).push(span); - } - } else { - span.from += offset; - if (sameLine) (first || (first = [])).push(span); - } - } - } - // Make sure we didn't create any zero-length spans - if (first) first = clearEmptySpans(first); - if (last && last != first) last = clearEmptySpans(last); - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) - for (var i = 0; i < first.length; ++i) - if (first[i].to == null) - (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); - for (var i = 0; i < gap; ++i) - newMarkers.push(gapMarkers); - newMarkers.push(last); - } - return newMarkers; - } - - // Remove spans that are empty and don't have a clearWhenEmpty - // option of false. - function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) - spans.splice(i--, 1); - } - if (!spans.length) return null; - return spans; - } - - // Used for un/re-doing changes from the history. Combines the - // result of computing the existing spans with the set of spans that - // existed in the history (so that deleting around a span and then - // undoing brings back the span). - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) return stretched; - if (!stretched) return old; - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) - if (oldCur[k].marker == span.marker) continue spans; - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old; - } - - // Used to 'clip' out readOnly ranges when making a change. - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function (line) { - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - (markers || (markers = [])).push(mark); - } - }); - if (!markers) return null; - var parts = [{ from: from, to: to }]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) - newParts.push({ from: p.from, to: m.from }); - if (dto > 0 || !mk.inclusiveRight && !dto) - newParts.push({ from: m.to, to: p.to }); - parts.splice.apply(parts, newParts); - j += newParts.length - 1; - } - } - return parts; - } - - // Connect or disconnect spans from a line. - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.detachLine(line); - line.markedSpans = null; - } - function attachMarkedSpans(line, spans) { - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.attachLine(line); - line.markedSpans = spans; - } - - // Helpers used when computing which overlapping collapsed span - // counts as the larger one. - function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } - function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } - - // Returns a number indicating which of two overlapping collapsed - // spans is larger (and thus includes the other). Falls back to - // comparing ids when the spans cover exactly the same range. - function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length; - if (lenDiff != 0) return lenDiff; - var aPos = a.find(), bPos = b.find(); - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); - if (fromCmp) return -fromCmp; - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); - if (toCmp) return toCmp; - return b.id - a.id; - } - - // Find out whether a line ends or starts in a collapsed span. If - // so, return the marker for that span. - function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) - found = sp.marker; - } - return found; - } - function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } - function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } - - // Test whether there exists a collapsed span that partially - // overlaps (covers the start or end, but not both) of a new span. - // Such overlap is not allowed. - function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo); - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (!sp.marker.collapsed) continue; - var found = sp.marker.find(0); - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; - if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || - fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) - return true; - } - } - - // A visual line is a line as drawn on the screen. Folding, for - // example, can cause multiple logical lines to appear on the same - // visual line. This finds the start of the visual line that the - // given line is part of (usually that is the line itself). - function visualLine(line) { - var merged; - while (merged = collapsedSpanAtStart(line)) - line = merged.find(-1, true).line; - return line; - } - - // Returns an array of logical lines that continue the visual line - // started by the argument, or undefined if there are no such lines. - function visualLineContinued(line) { - var merged, lines; - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - (lines || (lines = [])).push(line); - } - return lines; - } - - // Get the line number of the start of the visual line that the - // given line number is part of. - function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line); - if (line == vis) return lineN; - return lineNo(vis); - } - // Get the line number of the start of the next visual line after - // the given line. - function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) return lineN; - var line = getLine(doc, lineN), merged; - if (!lineIsHidden(doc, line)) return lineN; - while (merged = collapsedSpanAtEnd(line)) - line = merged.find(1, true).line; - return lineNo(line) + 1; - } - - // Compute whether a line is hidden. Lines count as hidden when they - // are part of a visual line that starts with another line, or when - // they are entirely covered by collapsed, non-widget span. - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if (sp.from == null) return true; - if (sp.marker.widgetNode) continue; - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - return true; - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true); - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); - } - if (span.marker.inclusiveRight && span.to == line.text.length) - return true; - for (var sp, i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) return true; - } - } - - // LINE WIDGETS - - // Line widgets are block elements displayed above or below a line. - - var LineWidget = CodeMirror.LineWidget = function (doc, node, options) { - if (options) for (var opt in options) if (options.hasOwnProperty(opt)) - this[opt] = options[opt]; - this.doc = doc; - this.node = node; - }; - eventMixin(LineWidget); - - function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) - addToScrollPos(cm, null, diff); - } - - LineWidget.prototype.clear = function () { - var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); - if (no == null || !ws) return; - for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); - if (!ws.length) line.widgets = null; - var height = widgetHeight(this); - updateLineHeight(line, Math.max(0, line.height - height)); - if (cm) runInOp(cm, function () { - adjustScrollWhenAboveVisible(cm, line, -height); - regLineChange(cm, no, "widget"); - }); - }; - LineWidget.prototype.changed = function () { - var oldH = this.height, cm = this.doc.cm, line = this.line; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) return; - updateLineHeight(line, line.height + diff); - if (cm) runInOp(cm, function () { - cm.curOp.forceUpdate = true; - adjustScrollWhenAboveVisible(cm, line, diff); - }); - }; - - function widgetHeight(widget) { - if (widget.height != null) return widget.height; - var cm = widget.doc.cm; - if (!cm) return 0; - if (!contains(document.body, widget.node)) { - var parentStyle = "position: relative;"; - if (widget.coverGutter) - parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; - if (widget.noHScroll) - parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; - removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); - } - return widget.height = widget.node.parentNode.offsetHeight; - } - - function addLineWidget(doc, handle, node, options) { - var widget = new LineWidget(doc, node, options); - var cm = doc.cm; - if (cm && widget.noHScroll) cm.display.alignWidgets = true; - changeLine(doc, handle, "widget", function (line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) widgets.push(widget); - else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); - widget.line = line; - if (cm && !lineIsHidden(doc, line)) { - var aboveVisible = heightAtLine(line) < doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) addToScrollPos(cm, null, widget.height); - cm.curOp.forceUpdate = true; - } - return true; - }); - return widget; - } - - // LINE DATA STRUCTURE - - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = CodeMirror.Line = function (text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; - eventMixin(Line); - Line.prototype.lineNo = function () { return lineNo(this); }; - - // Change the content (text, markers) of a line. Automatically - // invalidates cached information and tries to re-estimate the - // line's height. - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - if (line.order != null) line.order = null; - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) updateLineHeight(line, estHeight); - } - - // Detach a line from the document tree and its markers. - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } - - function extractLineClasses(type, output) { - if (type) for (; ;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); - if (!lineClass) break; - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (output[prop] == null) - output[prop] = lineClass[2]; - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) - output[prop] += " " + lineClass[2]; - } - return type; - } - - function callBlankLine(mode, state) { - if (mode.blankLine) return mode.blankLine(state); - if (!mode.innerMode) return; - var inner = CodeMirror.innerMode(mode, state); - if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); - } - - function readToken(mode, stream, state, inner) { - for (var i = 0; i < 10; i++) { - if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; - var style = mode.token(stream, state); - if (stream.pos > stream.start) return style; - } - throw new Error("Mode " + mode.name + " failed to advance stream."); - } - - // Utility for getTokenAt and getLineTokens - function takeToken(cm, pos, precise, asArray) { - function getObj(copy) { - return { - start: stream.start, end: stream.pos, - string: stream.current(), - type: style || null, - state: copy ? copyState(doc.mode, state) : state - }; - } - - var doc = cm.doc, mode = doc.mode, style; - pos = clipPos(doc, pos); - var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); - var stream = new StringStream(line.text, cm.options.tabSize), tokens; - if (asArray) tokens = []; - while ((asArray || stream.pos < pos.ch) && !stream.eol()) { - stream.start = stream.pos; - style = readToken(mode, stream, state); - if (asArray) tokens.push(getObj(true)); - } - return asArray ? tokens : getObj(); - } - - // Run the given mode's parser over a line, calling f for each token. - function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize), style; - var inner = cm.options.addModeClass && [null]; - if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - if (forceToEnd) processLine(cm, text, state, stream.pos); - stream.pos = text.length; - style = null; - } else { - style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); - } - if (inner) { - var mName = inner[0].name; - if (mName) style = "m-" + (style ? mName + " " + style : mName); - } - if (!flattenSpans || curStyle != style) { - while (curStart < stream.start) { - curStart = Math.min(stream.start, curStart + 50000); - f(curStart, curStyle); - } - curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 characters - var pos = Math.min(stream.pos, curStart + 50000); - f(pos, curStyle); - curStart = pos; - } - } - - // Compute a style array (an array starting with a mode generation - // -- for invalidation -- followed by pairs of end positions and - // style strings), which is used to highlight the tokens on the - // line. - function highlightLine(cm, line, state, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {}; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, state, function (end, style) { - st.push(end, style); - }, lineClasses, forceToEnd); - - // Run overlays, adjust style array. - for (var o = 0; o < cm.state.overlays.length; ++o) { - var overlay = cm.state.overlays[o], i = 1, at = 0; - runMode(cm, line.text, overlay.mode, true, function (end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) - st.splice(i, 1, end, st[i + 1], i_end); - i += 2; - at = Math.min(end, i_end); - } - if (!style) return; - if (overlay.opaque) { - st.splice(start, i - start, end, "cm-overlay " + style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start + 1]; - st[start + 1] = (cur ? cur + " " : "") + "cm-overlay " + style; - } - } - }, lineClasses); - } - - return { styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null }; - } - - function getLineStyles(cm, line, updateFrontier) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var state = getStateBefore(cm, lineNo(line)); - var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); - line.stateAfter = state; - line.styles = result.styles; - if (result.classes) line.styleClasses = result.classes; - else if (line.styleClasses) line.styleClasses = null; - if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; - } - return line.styles; - } - - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. Used for lines that - // aren't currently visible. - function processLine(cm, text, state, startAt) { - var mode = cm.doc.mode; - var stream = new StringStream(text, cm.options.tabSize); - stream.start = stream.pos = startAt || 0; - if (text == "") callBlankLine(mode, state); - while (!stream.eol()) { - readToken(mode, stream, state); - stream.start = stream.pos; - } - } - - // Convert a style as returned by a mode (either null, or a string - // containing one or more styles) to a CSS style. This is cached, - // and also looks for line-wide styles. - var styleToClassCache = {}, styleToClassCacheWithMode = {}; - function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) return null; - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")); - } - - // Render the DOM representation of the text of a line. Also builds - // up a 'line map', which points at the DOM nodes that represent - // specific stretches of text, and is used by the measuring code. - // The returned object contains the DOM node, this map, and - // information about line-wide styles that were set by the mode. - function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); - var builder = { - pre: elt("pre", [content], "CodeMirror-line"), content: content, - col: 0, pos: 0, cm: cm, - trailingSpace: false, - splitSpaces: (ie || webkit) && cm.getOption("lineWrapping") - }; - lineView.measure = {}; - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order; - builder.pos = 0; - builder.addToken = buildToken; - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) - builder.addToken = buildTokenBadBidi(builder.addToken, order); - builder.map = []; - var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); - insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); - if (line.styleClasses) { - if (line.styleClasses.bgClass) - builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); - if (line.styleClasses.textClass) - builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); - } - - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) - builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); - - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map; - lineView.measure.cache = {}; - } else { - (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); - (lineView.measure.caches || (lineView.measure.caches = [])).push({}); - } - } - - // See issue #2901 - if (webkit) { - var last = builder.content.lastChild - if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) - builder.content.className = "cm-tab-wrap-hack"; - } - - signal(cm, "renderLine", cm, lineView.line, builder.pre); - if (builder.pre.className) - builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); - - return builder; - } - - function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + ch.charCodeAt(0).toString(16); - token.setAttribute("aria-label", token.title); - return token; - } - - // Build up the DOM representation for a single token, and add it to - // the line map. Takes care to render special characters separately. - function buildToken(builder, text, style, startStyle, endStyle, title, css) { - if (!text) return; - var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text - var special = builder.cm.state.specialChars, mustWrap = false; - if (!special.test(text)) { - builder.col += text.length; - var content = document.createTextNode(displayText); - builder.map.push(builder.pos, builder.pos + text.length, content); - if (ie && ie_version < 9) mustWrap = true; - builder.pos += text.length; - } else { - var content = document.createDocumentFragment(), pos = 0; - while (true) { - special.lastIndex = pos; - var m = special.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.map.push(builder.pos, builder.pos + skipped, txt); - builder.col += skipped; - builder.pos += skipped; - } - if (!m) break; - pos += skipped + 1; - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - txt.setAttribute("role", "presentation"); - txt.setAttribute("cm-text", "\t"); - builder.col += tabWidth; - } else if (m[0] == "\r" || m[0] == "\n") { - var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); - txt.setAttribute("cm-text", m[0]); - builder.col += 1; - } else { - var txt = builder.cm.options.specialCharPlaceholder(m[0]); - txt.setAttribute("cm-text", m[0]); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.col += 1; - } - builder.map.push(builder.pos, builder.pos + 1, txt); - builder.pos++; - } - } - builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 - if (style || startStyle || endStyle || mustWrap || css) { - var fullStyle = style || ""; - if (startStyle) fullStyle += startStyle; - if (endStyle) fullStyle += endStyle; - var token = elt("span", [content], fullStyle, css); - if (title) token.title = title; - return builder.content.appendChild(token); - } - builder.content.appendChild(content); - } - - function splitSpaces(text, trailingBefore) { - if (text.length > 1 && !/ /.test(text)) return text - var spaceBefore = trailingBefore, result = "" - for (var i = 0; i < text.length; i++) { - var ch = text.charAt(i) - if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) - ch = "\u00a0" - result += ch - spaceBefore = ch == " " - } - return result - } - - // Work around nonsense dimensions being reported for stretches of - // right-to-left text. - function buildTokenBadBidi(inner, order) { - return function (builder, text, style, startStyle, endStyle, title, css) { - style = style ? style + " cm-force-border" : "cm-force-border"; - var start = builder.pos, end = start + text.length; - for (; ;) { - // Find the part that overlaps with the start of this text - for (var i = 0; i < order.length; i++) { - var part = order[i]; - if (part.to > start && part.from <= start) break; - } - if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); - inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); - startStyle = null; - text = text.slice(part.to - start); - start = part.to; - } - }; - } - - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode; - if (widget) builder.map.push(builder.pos, builder.pos + size, widget); - if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { - if (!widget) - widget = builder.content.appendChild(document.createElement("span")); - widget.setAttribute("cm-marker", marker.id); - } - if (widget) { - builder.cm.display.input.setUneditable(widget); - builder.content.appendChild(widget); - } - builder.pos += size; - builder.trailingSpace = false - } - - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i = 1; i < styles.length; i += 2) - builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i + 1], builder.cm.options)); - return; - } - - var len = allText.length, pos = 0, i = 1, text = "", style, css; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; - for (; ;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = css = ""; - collapsed = null; nextChange = Infinity; - var foundBookmarks = [], endStyles - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { - foundBookmarks.push(m); - } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { - if (sp.to != null && sp.to != pos && nextChange > sp.to) { - nextChange = sp.to; - spanEndStyle = ""; - } - if (m.className) spanStyle += " " + m.className; - if (m.css) css = (css ? css + ";" : "") + m.css; - if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; - if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to) - if (m.title && !title) title = m.title; - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) - collapsed = sp; - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - } - if (endStyles) for (var j = 0; j < endStyles.length; j += 2) - if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j] - - if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j) - buildCollapsedSpan(builder, 0, foundBookmarks[j]); - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) return; - if (collapsed.to == pos) collapsed = false; - } - } - if (pos >= len) break; - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); - } - if (end >= upto) { text = text.slice(upto - pos); pos = upto; break; } - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder.cm.options); - } - } - } - - // DOCUMENT DATA STRUCTURE - - // By default, updates that start and end at the beginning of a line - // are treated specially, in order to make the association of line - // widgets and marker elements with the text behave more intuitive. - function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore); - } - - // Perform a change on the document data structure. - function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) { return markedSpans ? markedSpans[n] : null; } - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - function linesFor(start, end) { - for (var i = start, result = []; i < end; ++i) - result.push(new Line(text[i], spansFor(i), estimateHeight)); - return result; - } - - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // Adjust the line structure - if (change.full) { - doc.insert(0, linesFor(0, text.length)); - doc.remove(text.length, doc.size - text.length); - } else if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - var added = linesFor(0, text.length - 1); - update(lastLine, lastLine.text, lastSpans); - if (nlines) doc.remove(from.line, nlines); - if (added.length) doc.insert(from.line, added); - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - var added = linesFor(1, text.length - 1); - added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - var added = linesFor(1, text.length - 1); - if (nlines > 1) doc.remove(from.line + 1, nlines - 1); - doc.insert(from.line + 1, added); - } - - signalLater(doc, "change", doc, change); - } - - // The document is represented as a BTree consisting of leaves, with - // chunk of lines in them, and branches, with up to ten leaves or - // other branch nodes below them. The top node is always a branch - // node, and is the document object itself (meaning it has - // additional methods and properties). - // - // All nodes have parent links. The tree is used both to go from - // line numbers to line objects, and to go from objects to numbers. - // It also indexes by height, and is used to convert between height - // and line object, and to find the total height of the document. - // - // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - for (var i = 0, height = 0; i < lines.length; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } - - LeafChunk.prototype = { - chunkSize: function () { return this.lines.length; }, - // Remove the n lines at offset 'at'. - removeInner: function (at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, - // Helper used to collapse a small branch into a single leaf. - collapse: function (lines) { - lines.push.apply(lines, this.lines); - }, - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function (at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0; i < lines.length; ++i) lines[i].parent = this; - }, - // Used to iterate over a part of the tree. - iterN: function (at, n, op) { - for (var e = at + n; at < e; ++at) - if (op(this.lines[at])) return true; - } - }; - - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0; i < children.length; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } - - BranchChunk.prototype = { - chunkSize: function () { return this.size; }, - removeInner: function (at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) break; - at = 0; - } else at -= sz; - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, - collapse: function (lines) { - for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); - }, - insertInner: function (at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. - // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. - var remaining = child.lines.length % 25 + 25 - for (var pos = remaining; pos < child.lines.length;) { - var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)); - child.height -= leaf.height; - this.children.splice(++i, 0, leaf); - leaf.parent = this; - } - child.lines = child.lines.slice(0, remaining); - this.maybeSpill(); - } - break; - } - at -= sz; - } - }, - // When a node has grown, check whether it should be split. - maybeSpill: function () { - if (this.children.length <= 10) return; - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10); - me.parent.maybeSpill(); - }, - iterN: function (at, n, op) { - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) return true; - if ((n -= used) == 0) break; - at = 0; - } else at -= sz; - } - } - }; - - var nextDocId = 0; - var Doc = CodeMirror.Doc = function (text, mode, firstLine, lineSep) { - if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep); - if (firstLine == null) firstLine = 0; - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.cleanGeneration = 1; - this.frontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = simpleSelection(start); - this.history = new History(null); - this.id = ++nextDocId; - this.modeOption = mode; - this.lineSep = lineSep; - this.extend = false; - - if (typeof text == "string") text = this.splitLines(text); - updateDoc(this, { from: start, to: start, text: text }); - setSelection(this, simpleSelection(start), sel_dontScroll); - }; - - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function (from, to, op) { - if (op) this.iterN(from - this.first, to - from, op); - else this.iterN(this.first, this.first + this.size, from); - }, - - // Non-public interface for adding and removing lines. - insert: function (at, lines) { - var height = 0; - for (var i = 0; i < lines.length; ++i) height += lines[i].height; - this.insertInner(at - this.first, lines, height); - }, - remove: function (at, n) { this.removeInner(at - this.first, n); }, - - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. - - getValue: function (lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) return lines; - return lines.join(lineSep || this.lineSeparator()); - }, - setValue: docMethodOp(function (code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, { - from: top, to: Pos(last, getLine(this, last).text.length), - text: this.splitLines(code), origin: "setValue", full: true - }, true); - setSelection(this, simpleSelection(top)); - }), - replaceRange: function (code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function (from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) return lines; - return lines.join(lineSep || this.lineSeparator()); - }, - - getLine: function (line) { var l = this.getLineHandle(line); return l && l.text; }, - - getLineHandle: function (line) { if (isLine(this, line)) return getLine(this, line); }, - getLineNumber: function (line) { return lineNo(line); }, - - getLineHandleVisualStart: function (line) { - if (typeof line == "number") line = getLine(this, line); - return visualLine(line); - }, - - lineCount: function () { return this.size; }, - firstLine: function () { return this.first; }, - lastLine: function () { return this.first + this.size - 1; }, - - clipPos: function (pos) { return clipPos(this, pos); }, - - getCursor: function (start) { - var range = this.sel.primary(), pos; - if (start == null || start == "head") pos = range.head; - else if (start == "anchor") pos = range.anchor; - else if (start == "end" || start == "to" || start === false) pos = range.to(); - else pos = range.from(); - return pos; - }, - listSelections: function () { return this.sel.ranges; }, - somethingSelected: function () { return this.sel.somethingSelected(); }, - - setCursor: docMethodOp(function (line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); - }), - setSelection: docMethodOp(function (anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); - }), - extendSelection: docMethodOp(function (head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); - }), - extendSelections: docMethodOp(function (heads, options) { - extendSelections(this, clipPosArray(this, heads), options); - }), - extendSelectionsBy: docMethodOp(function (f, options) { - var heads = map(this.sel.ranges, f); - extendSelections(this, clipPosArray(this, heads), options); - }), - setSelections: docMethodOp(function (ranges, primary, options) { - if (!ranges.length) return; - for (var i = 0, out = []; i < ranges.length; i++) - out[i] = new Range(clipPos(this, ranges[i].anchor), - clipPos(this, ranges[i].head)); - if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); - setSelection(this, normalizeSelection(out, primary), options); - }), - addSelection: docMethodOp(function (anchor, head, options) { - var ranges = this.sel.ranges.slice(0); - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); - setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); - }), - - getSelection: function (lineSep) { - var ranges = this.sel.ranges, lines; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - lines = lines ? lines.concat(sel) : sel; - } - if (lineSep === false) return lines; - else return lines.join(lineSep || this.lineSeparator()); - }, - getSelections: function (lineSep) { - var parts = [], ranges = this.sel.ranges; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()); - parts[i] = sel; - } - return parts; - }, - replaceSelection: function (code, collapse, origin) { - var dup = []; - for (var i = 0; i < this.sel.ranges.length; i++) - dup[i] = code; - this.replaceSelections(dup, collapse, origin || "+input"); - }, - replaceSelections: docMethodOp(function (code, collapse, origin) { - var changes = [], sel = this.sel; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - changes[i] = { from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin }; - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); - for (var i = changes.length - 1; i >= 0; i--) - makeChange(this, changes[i]); - if (newSel) setSelectionReplaceHistory(this, newSel); - else if (this.cm) ensureCursorVisible(this.cm); - }), - undo: docMethodOp(function () { makeChangeFromHistory(this, "undo"); }), - redo: docMethodOp(function () { makeChangeFromHistory(this, "redo"); }), - undoSelection: docMethodOp(function () { makeChangeFromHistory(this, "undo", true); }), - redoSelection: docMethodOp(function () { makeChangeFromHistory(this, "redo", true); }), - - setExtending: function (val) { this.extend = val; }, - getExtending: function () { return this.extend; }, - - historySize: function () { - var hist = this.history, done = 0, undone = 0; - for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; - for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; - return { undo: done, redo: undone }; - }, - clearHistory: function () { this.history = new History(this.history.maxGeneration); }, - - markClean: function () { - this.cleanGeneration = this.changeGeneration(true); - }, - changeGeneration: function (forceSplit) { - if (forceSplit) - this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; - return this.history.generation; - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration); - }, - - getHistory: function () { - return { - done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone) - }; - }, - setHistory: function (histData) { - var hist = this.history = new History(this.history.maxGeneration); - hist.done = copyHistoryArray(histData.done.slice(0), null, true); - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); - }, - - addLineClass: docMethodOp(function (handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - if (!line[prop]) line[prop] = cls; - else if (classTest(cls).test(line[prop])) return false; - else line[prop] += " " + cls; - return true; - }); - }), - removeLineClass: docMethodOp(function (handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) return false; - else if (cls == null) line[prop] = null; - else { - var found = cur.match(classTest(cls)); - if (!found) return false; - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true; - }); - }), - - addLineWidget: docMethodOp(function (handle, node, options) { - return addLineWidget(this, handle, node, options); - }), - removeLineWidget: function (widget) { widget.clear(); }, - - markText: function (from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range"); - }, - setBookmark: function (pos, options) { - var realOpts = { - replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared, - handleMouseEvents: options && options.handleMouseEvents - }; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark"); - }, - findMarksAt: function (pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - markers.push(span.marker.parent || span.marker); - } - return markers; - }, - findMarks: function (from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to); - var found = [], lineNo = from.line; - this.iter(from.line, to.line + 1, function (line) { - var spans = line.markedSpans; - if (spans) for (var i = 0; i < spans.length; i++) { - var span = spans[i]; - if (!(span.to != null && lineNo == from.line && from.ch >= span.to || - span.from == null && lineNo != from.line || - span.from != null && lineNo == to.line && span.from >= to.ch) && - (!filter || filter(span.marker))) - found.push(span.marker.parent || span.marker); - } - ++lineNo; - }); - return found; - }, - getAllMarks: function () { - var markers = []; - this.iter(function (line) { - var sps = line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) - if (sps[i].from != null) markers.push(sps[i].marker); - }); - return markers; - }, - - posFromIndex: function (off) { - var ch, lineNo = this.first, sepSize = this.lineSeparator().length; - this.iter(function (line) { - var sz = line.text.length + sepSize; - if (sz > off) { ch = off; return true; } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)); - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) return 0; - var sepSize = this.lineSeparator().length; - this.iter(this.first, coords.line, function (line) { - index += line.text.length + sepSize; - }); - return index; - }, - - copy: function (copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), - this.modeOption, this.first, this.lineSep); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = this.sel; - doc.extend = false; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc; - }, - - linkedDoc: function (options) { - if (!options) options = {}; - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) from = options.from; - if (options.to != null && options.to < to) to = options.to; - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep); - if (options.sharedHist) copy.history = this.history; - (this.linked || (this.linked = [])).push({ doc: copy, sharedHist: options.sharedHist }); - copy.linked = [{ doc: this, isParent: true, sharedHist: options.sharedHist }]; - copySharedMarkers(copy, findSharedMarkers(this)); - return copy; - }, - unlinkDoc: function (other) { - if (other instanceof CodeMirror) other = other.doc; - if (this.linked) for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) continue; - this.linked.splice(i, 1); - other.unlinkDoc(this); - detachSharedMarkers(findSharedMarkers(this)); - break; - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function (doc) { splitIds.push(doc.id); }, true); - other.history = new History(null); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function (f) { linkedDocs(this, f); }, - - getMode: function () { return this.mode; }, - getEditor: function () { return this.cm; }, - - splitLines: function (str) { - if (this.lineSep) return str.split(this.lineSep); - return splitLinesAuto(str); - }, - lineSeparator: function () { return this.lineSep || "\n"; } - }); - - // Public alias. - Doc.prototype.eachLine = Doc.prototype.iter; - - // Set up methods on CodeMirror's prototype to redirect to the editor's document. - var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); - for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - CodeMirror.prototype[prop] = (function (method) { - return function () { return method.apply(this.doc, arguments); }; - })(Doc.prototype[prop]); - - eventMixin(Doc); - - // Call f for all linked documents. - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) continue; - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) continue; - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - propagate(doc, null, true); - } - - // Attach a document to an editor. - function attachDoc(cm, doc) { - if (doc.cm) throw new Error("This document is already in use."); - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - if (!cm.options.lineWrapping) findMaxLine(cm); - cm.options.mode = doc.modeOption; - regChange(cm); - } - - // LINE UTILITIES - - // Find the line object corresponding to the given line number. - function getLine(doc, n) { - n -= doc.first; - if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); - for (var chunk = doc; !chunk.lines;) { - for (var i = 0; ; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break; } - n -= sz; - } - } - return chunk.lines[n]; - } - - // Get the part of a document between two positions, as an array of - // strings. - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function (line) { - var text = line.text; - if (n == end.line) text = text.slice(0, end.ch); - if (n == start.line) text = text.slice(start.ch); - out.push(text); - ++n; - }); - return out; - } - // Get the lines between from and to, as array of strings. - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function (line) { out.push(line.text); }); - return out; - } - - // Update the height of a line, propagating the height change - // upwards to parent nodes. - function updateLineHeight(line, height) { - var diff = height - line.height; - if (diff) for (var n = line; n; n = n.parent) n.height += diff; - } - - // Given a line object, find its line number by walking up through - // its parent links. - function lineNo(line) { - if (line.parent == null) return null; - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0; ; ++i) { - if (chunk.children[i] == cur) break; - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first; - } - - // Find the line at the given vertical position, using the height - // information in the document tree. - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i = 0; i < chunk.children.length; ++i) { - var child = chunk.children[i], ch = child.height; - if (h < ch) { chunk = child; continue outer; } - h -= ch; - n += child.chunkSize(); - } - return n; - } while (!chunk.lines); - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) break; - h -= lh; - } - return n + i; - } - - - // Find the height above the given line. - function heightAtLine(lineObj) { - lineObj = visualLine(lineObj); - - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) break; - else h += line.height; - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i = 0; i < p.children.length; ++i) { - var cur = p.children[i]; - if (cur == chunk) break; - else h += cur.height; - } - } - return h; - } - - // Get the bidi ordering for the given line (and cache it). Returns - // false for lines that are fully left-to-right, and an array of - // BidiSpan objects otherwise. - function getOrder(line) { - var order = line.order; - if (order == null) order = line.order = bidiOrdering(line.text); - return order; - } - - // HISTORY - - function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = []; - this.undoDepth = Infinity; - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0; - this.lastOp = this.lastSelOp = null; - this.lastOrigin = this.lastSelOrigin = null; - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1; - } - - // Create a history change event from an updateDoc-style change - // object. - function historyChangeFromChange(doc, change) { - var histChange = { from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to) }; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function (doc) { attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true); - return histChange; - } - - // Pop all selection events off the end of a history array. Stop at - // a change event. - function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array); - if (last.ranges) array.pop(); - else break; - } - } - - // Find the top change event in the history. Pop off selection - // events that are in the way. - function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done); - return lst(hist.done); - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done); - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop(); - return lst(hist.done); - } - } - - // Register a change in the history. Merges changes that are within - // a single operation, ore are close together with an origin that - // allows merging (starting with "+") into a single event. - function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur; - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - var last = lst(cur.changes); - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done); - if (!before || !before.ranges) - pushSelectionToHistory(doc.sel, hist.done); - cur = { - changes: [historyChangeFromChange(doc, change)], - generation: hist.generation - }; - hist.done.push(cur); - while (hist.done.length > hist.undoDepth) { - hist.done.shift(); - if (!hist.done[0].ranges) hist.done.shift(); - } - } - hist.done.push(selAfter); - hist.generation = ++hist.maxGeneration; - hist.lastModTime = hist.lastSelTime = time; - hist.lastOp = hist.lastSelOp = opId; - hist.lastOrigin = hist.lastSelOrigin = change.origin; - - if (!last) signal(doc, "historyAdded"); - } - - function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0); - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); - } - - // Called whenever the selection changes, sets the new selection as - // the pending selection in the history, and pushes the old pending - // selection into the 'done' array when it was significantly - // different (in number of selected ranges, emptiness, or time). - function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin; - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastSelOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) - hist.done[hist.done.length - 1] = sel; - else - pushSelectionToHistory(sel, hist.done); - - hist.lastSelTime = +new Date; - hist.lastSelOrigin = origin; - hist.lastSelOp = opId; - if (options && options.clearRedo !== false) - clearSelectionEvents(hist.undone); - } - - function pushSelectionToHistory(sel, dest) { - var top = lst(dest); - if (!(top && top.ranges && top.equals(sel))) - dest.push(sel); - } - - // Used to store marked span information in the history. - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { - if (line.markedSpans) - (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; - ++n; - }); - } - - // When un/re-doing restores text containing marked spans, those - // that have been explicitly cleared should not be restored. - function removeClearedSpans(spans) { - if (!spans) return null; - for (var i = 0, out; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } - else if (out) out.push(spans[i]); - } - return !out ? spans : out.length ? out : null; - } - - // Retrieve and filter the old marked spans stored in a change event. - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) return null; - for (var i = 0, nw = []; i < change.text.length; ++i) - nw.push(removeClearedSpans(found[i])); - return nw; - } - - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup, instantiateSel) { - for (var i = 0, copy = []; i < events.length; ++i) { - var event = events[i]; - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); - continue; - } - var changes = event.changes, newChanges = []; - copy.push({ changes: newChanges }); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m; - newChanges.push({ from: change.from, to: change.to, text: change.text }); - if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - return copy; - } - - // Rebasing/resetting history to deal with externally-sourced changes - - function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } - - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); - } - continue; - } - for (var j = 0; j < sub.changes.length; ++j) { - var cur = sub.changes[j]; - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch); - cur.to = Pos(cur.to.line + diff, cur.to.ch); - } else if (from <= cur.to.line) { - ok = false; - break; - } - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - - // EVENT UTILITIES - - // Due to the fact that we still support jurassic IE versions, some - // compatibility wrappers are needed. - - var e_preventDefault = CodeMirror.e_preventDefault = function (e) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - }; - var e_stopPropagation = CodeMirror.e_stopPropagation = function (e) { - if (e.stopPropagation) e.stopPropagation(); - else e.cancelBubble = true; - }; - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; - } - var e_stop = CodeMirror.e_stop = function (e) { e_preventDefault(e); e_stopPropagation(e); }; - - function e_target(e) { return e.target || e.srcElement; } - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) b = 1; - else if (e.button & 2) b = 3; - else if (e.button & 4) b = 2; - } - if (mac && e.ctrlKey && b == 1) b = 3; - return b; - } - - // EVENT HANDLING - - // Lightweight event framework. on/off also work on DOM nodes, - // registering native DOM handlers. - - var on = CodeMirror.on = function (emitter, type, f) { - if (emitter.addEventListener) - emitter.addEventListener(type, f, false); - else if (emitter.attachEvent) - emitter.attachEvent("on" + type, f); - else { - var map = emitter._handlers || (emitter._handlers = {}); - var arr = map[type] || (map[type] = []); - arr.push(f); - } - }; - - var noHandlers = [] - function getHandlers(emitter, type, copy) { - var arr = emitter._handlers && emitter._handlers[type] - if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers - else return arr || noHandlers - } - - var off = CodeMirror.off = function (emitter, type, f) { - if (emitter.removeEventListener) - emitter.removeEventListener(type, f, false); - else if (emitter.detachEvent) - emitter.detachEvent("on" + type, f); - else { - var handlers = getHandlers(emitter, type, false) - for (var i = 0; i < handlers.length; ++i) - if (handlers[i] == f) { handlers.splice(i, 1); break; } - } - }; - - var signal = CodeMirror.signal = function (emitter, type /*, values...*/) { - var handlers = getHandlers(emitter, type, true) - if (!handlers.length) return; - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args); - }; - - var orphanDelayedCallbacks = null; - - // Often, we want to signal events at a point where we are in the - // middle of some work, but don't want the handler to start calling - // other methods on the editor, which might be in an inconsistent - // state or simply not expect any other events to happen. - // signalLater looks whether there are any handlers, and schedules - // them to be executed when the last operation ends, or, if no - // operation is active, when a timeout fires. - function signalLater(emitter, type /*, values...*/) { - var arr = getHandlers(emitter, type, false) - if (!arr.length) return; - var args = Array.prototype.slice.call(arguments, 2), list; - if (operationGroup) { - list = operationGroup.delayedCallbacks; - } else if (orphanDelayedCallbacks) { - list = orphanDelayedCallbacks; - } else { - list = orphanDelayedCallbacks = []; - setTimeout(fireOrphanDelayed, 0); - } - function bnd(f) { return function () { f.apply(null, args); }; }; - for (var i = 0; i < arr.length; ++i) - list.push(bnd(arr[i])); - } - - function fireOrphanDelayed() { - var delayed = orphanDelayedCallbacks; - orphanDelayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - // The DOM events that CodeMirror handles can be overridden by - // registering a (non-DOM) handler on the editor for the event name, - // and preventDefault-ing the event in that handler. - function signalDOMEvent(cm, e, override) { - if (typeof e == "string") - e = { type: e, preventDefault: function () { this.defaultPrevented = true; } }; - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore; - } - - function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity; - if (!arr) return; - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); - for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) - set.push(arr[i]); - } - - function hasHandler(emitter, type) { - return getHandlers(emitter, type).length > 0 - } - - // Add on and off methods to a constructor's prototype, to make - // registering events on such objects more convenient. - function eventMixin(ctor) { - ctor.prototype.on = function (type, f) { on(this, type, f); }; - ctor.prototype.off = function (type, f) { off(this, type, f); }; - } - - // MISC UTILITIES - - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerGap = 30; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = CodeMirror.Pass = { toString: function () { return "CodeMirror.Pass"; } }; - - // Reused option objects for setSelection & friends - var sel_dontScroll = { scroll: false }, sel_mouse = { origin: "*mouse" }, sel_move = { origin: "+move" }; - - function Delayed() { this.id = null; } - Delayed.prototype.set = function (ms, f) { - clearTimeout(this.id); - this.id = setTimeout(f, ms); - }; - - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - var countColumn = CodeMirror.countColumn = function (string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0; ;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) - return n + (end - i); - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } - }; - - // The inverse of countColumn -- find the offset that corresponds to - // a particular column. - var findColumn = CodeMirror.findColumn = function (string, goal, tabSize) { - for (var pos = 0, col = 0; ;) { - var nextTab = string.indexOf("\t", pos); - if (nextTab == -1) nextTab = string.length; - var skipped = nextTab - pos; - if (nextTab == string.length || col + skipped >= goal) - return pos + Math.min(skipped, goal - col); - col += nextTab - pos; - col += tabSize - (col % tabSize); - pos = nextTab + 1; - if (col >= goal) return pos; - } - } - - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) - spaceStrs.push(lst(spaceStrs) + " "); - return spaceStrs[n]; - } - - function lst(arr) { return arr[arr.length - 1]; } - - var selectInput = function (node) { node.select(); }; - if (ios) // Mobile Safari apparently has a bug where select() is broken. - selectInput = function (node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; - else if (ie) // Suppress mysterious IE10 errors - selectInput = function (node) { try { node.select(); } catch (_e) { } }; - - function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) - if (array[i] == elt) return i; - return -1; - } - function map(array, f) { - var out = []; - for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); - return out; - } - - function nothing() { } - - function createObj(base, props) { - var inst; - if (Object.create) { - inst = Object.create(base); - } else { - nothing.prototype = base; - inst = new nothing(); - } - if (props) copyObj(props, inst); - return inst; - }; - - function copyObj(obj, target, overwrite) { - if (!target) target = {}; - for (var prop in obj) - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - target[prop] = obj[prop]; - return target; - } - - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { return f.apply(null, args); }; - } - - var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - var isWordCharBasic = CodeMirror.isWordChar = function (ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); - }; - function isWordChar(ch, helper) { - if (!helper) return isWordCharBasic(ch); - if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; - return helper.test(ch); - } - - function isEmpty(obj) { - for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; - return true; - } - - // Extending unicode characters. A series of a non-extending char + - // any number of extending chars is treated as a single unit as far - // as editing and measuring is concerned. This is not fully correct, - // since some scripts/fonts/browsers also treat other configurations - // of code points as a group. - var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; - function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } - - // DOM UTILITIES - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - var range; - if (document.createRange) range = function (node, start, end, endNode) { - var r = document.createRange(); - r.setEnd(endNode || node, end); - r.setStart(node, start); - return r; - }; - else range = function (node, start, end) { - var r = document.body.createTextRange(); - try { r.moveToElementText(node.parentNode); } - catch (e) { return r; } - r.collapse(true); - r.moveEnd("character", end); - r.moveStart("character", start); - return r; - }; - - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - e.removeChild(e.firstChild); - return e; - } - - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e); - } - - var contains = CodeMirror.contains = function (parent, child) { - if (child.nodeType == 3) // Android browser always returns false when child is a textnode - child = child.parentNode; - if (parent.contains) - return parent.contains(child); - do { - if (child.nodeType == 11) child = child.host; - if (child == parent) return true; - } while (child = child.parentNode); - }; - - function activeElt() { - var activeElement = document.activeElement; - while (activeElement && activeElement.root && activeElement.root.activeElement) - activeElement = activeElement.root.activeElement; - return activeElement; - } - // Older versions of IE throws unspecified error when touching - // document.activeElement in some cases (during loading, in iframe) - if (ie && ie_version < 11) activeElt = function () { - try { return document.activeElement; } - catch (e) { return document.body; } - }; - - function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } - var rmClass = CodeMirror.rmClass = function (node, cls) { - var current = node.className; - var match = classTest(cls).exec(current); - if (match) { - var after = current.slice(match.index + match[0].length); - node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); - } - }; - var addClass = CodeMirror.addClass = function (node, cls) { - var current = node.className; - if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; - }; - function joinClasses(a, b) { - var as = a.split(" "); - for (var i = 0; i < as.length; i++) - if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; - return b; - } - - // WINDOW-WIDE EVENTS - - // These must be handled carefully, because naively registering a - // handler for each editor will cause the editors to never be - // garbage collected. - - function forEachCodeMirror(f) { - if (!document.body.getElementsByClassName) return; - var byClass = document.body.getElementsByClassName("CodeMirror"); - for (var i = 0; i < byClass.length; i++) { - var cm = byClass[i].CodeMirror; - if (cm) f(cm); - } - } - - var globalsRegistered = false; - function ensureGlobalHandlers() { - if (globalsRegistered) return; - registerGlobalHandlers(); - globalsRegistered = true; - } - function registerGlobalHandlers() { - // When the window resizes, we need to refresh active editors. - var resizeTimer; - on(window, "resize", function () { - if (resizeTimer == null) resizeTimer = setTimeout(function () { - resizeTimer = null; - forEachCodeMirror(onResize); - }, 100); - }); - // When the window loses focus, we want to show the editor as blurred - on(window, "blur", function () { - forEachCodeMirror(onBlur); - }); - } - - // FEATURE DETECTION - - // Detect drag-and-drop - var dragAndDrop = function () { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie && ie_version < 9) return false; - var div = elt('div'); - return "draggable" in div || "dragDrop" in div; - }(); - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) - zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); - } - var node = zwspSupported ? elt("span", "\u200b") : - elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - node.setAttribute("cm-text", ""); - return node; - } - - // Feature-detect IE's crummy client rect reporting for bidi text - var badBidiRects; - function hasBadBidiRects(measure) { - if (badBidiRects != null) return badBidiRects; - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); - var r0 = range(txt, 0, 1).getBoundingClientRect(); - var r1 = range(txt, 1, 2).getBoundingClientRect(); - removeChildren(measure); - if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) - return badBidiRects = (r1.right - r0.right < 3); - } - - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function (string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) nl = string.length; - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result; - } : function (string) { return string.split(/\r\n?|\n/); }; - - var hasSelection = window.getSelection ? function (te) { - try { return te.selectionStart != te.selectionEnd; } - catch (e) { return false; } - } : function (te) { - try { var range = te.ownerDocument.selection.createRange(); } - catch (e) { } - if (!range || range.parentElement() != te) return false; - return range.compareEndPoints("StartToEnd", range) != 0; - }; - - var hasCopyEvent = (function () { - var e = elt("div"); - if ("oncopy" in e) return true; - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == "function"; - })(); - - var badZoomedRects = null; - function hasBadZoomedRects(measure) { - if (badZoomedRects != null) return badZoomedRects; - var node = removeChildrenAndAdd(measure, elt("span", "x")); - var normal = node.getBoundingClientRect(); - var fromRange = range(node, 0, 1).getBoundingClientRect(); - return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; - } - - // KEY NAMES - - var keyNames = CodeMirror.keyNames = { - 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" - }; - (function () { - // Number keys - for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); - // Alphabetic keys - for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); - // Function keys - for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; - })(); - - // BIDI HELPERS - - function iterateBidiSections(order, from, to, f) { - if (!order) return f(from, to, "ltr"); - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); - found = true; - } - } - if (!found) f(from, to, "ltr"); - } - - function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } - function bidiRight(part) { return part.level % 2 ? part.from : part.to; } - - function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } - function lineRight(line) { - var order = getOrder(line); - if (!order) return line.text.length; - return bidiRight(lst(order)); - } - - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(line); - if (visual != line) lineN = lineNo(visual); - var order = getOrder(visual); - var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); - return Pos(lineN, ch); - } - function lineEnd(cm, lineN) { - var merged, line = getLine(cm.doc, lineN); - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - lineN = null; - } - var order = getOrder(line); - var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); - return Pos(lineN == null ? lineNo(line) : lineN, ch); - } - function lineStartSmart(cm, pos) { - var start = lineStart(cm, pos.line); - var line = getLine(cm.doc, start.line); - var order = getOrder(line); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)); - var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; - return Pos(start.line, inWS ? 0 : firstNonWS); - } - return start; - } - - function compareBidiLevel(order, a, b) { - var linedir = order[0].level; - if (a == linedir) return true; - if (b == linedir) return false; - return a < b; - } - var bidiOther; - function getBidiPartAt(order, pos) { - bidiOther = null; - for (var i = 0, found; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < pos && cur.to > pos) return i; - if ((cur.from == pos || cur.to == pos)) { - if (found == null) { - found = i; - } else if (compareBidiLevel(order, cur.level, order[found].level)) { - if (cur.from != cur.to) bidiOther = found; - return i; - } else { - if (cur.from != cur.to) bidiOther = i; - return found; - } - } - } - return found; - } - - function moveInLine(line, pos, dir, byUnit) { - if (!byUnit) return pos + dir; - do pos += dir; - while (pos > 0 && isExtendingChar(line.text.charAt(pos))); - return pos; - } - - // This is needed in order to move 'visually' through bi-directional - // text -- i.e., pressing left should make the cursor go left, even - // when in RTL text. The tricky part is the 'jumps', where RTL and - // LTR text touch each other. This often requires the cursor offset - // to move more than one unit, in order to visually move one unit. - function moveVisually(line, start, dir, byUnit) { - var bidi = getOrder(line); - if (!bidi) return moveLogically(line, start, dir, byUnit); - var pos = getBidiPartAt(bidi, start), part = bidi[pos]; - var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); - - for (; ;) { - if (target > part.from && target < part.to) return target; - if (target == part.from || target == part.to) { - if (getBidiPartAt(bidi, target) == pos) return target; - part = bidi[pos += dir]; - return (dir > 0) == part.level % 2 ? part.to : part.from; - } else { - part = bidi[pos += dir]; - if (!part) return null; - if ((dir > 0) == part.level % 2) - target = moveInLine(line, part.to, -1, byUnit); - else - target = moveInLine(line, part.from, 1, byUnit); - } - } - } - - function moveLogically(line, start, dir, byUnit) { - var target = start + dir; - if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; - return target < 0 || target > line.text.length ? null : target; - } - - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function () { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; - // Character types for codepoints 0x600 to 0x6ff - var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; - function charType(code) { - if (code <= 0xf7) return lowTypes.charAt(code); - else if (0x590 <= code && code <= 0x5f4) return "R"; - else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); - else if (0x6ee <= code && code <= 0x8ac) return "r"; - else if (0x2000 <= code && code <= 0x200b) return "w"; - else if (code == 0x200c) return "b"; - else return "L"; - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; - // Browsers seem to always treat the boundaries of block elements as being L. - var outerType = "L"; - - function BidiSpan(level, from, to) { - this.level = level; - this.from = from; this.to = to; - } - - return function (str) { - if (!bidiRE.test(str)) return false; - var len = str.length, types = []; - for (var i = 0, type; i < len; ++i) - types.push(type = charType(str.charCodeAt(i))); - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i = 0, prev = outerType; i < len; ++i) { - var type = types[i]; - if (type == "m") types[i] = prev; - else prev = type; - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (type == "1" && cur == "r") types[i] = "n"; - else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i = 1, prev = types[0]; i < len - 1; ++i) { - var type = types[i]; - if (type == "+" && prev == "1" && types[i + 1] == "1") types[i] = "1"; - else if (type == "," && prev == types[i + 1] && - (prev == "1" || prev == "n")) types[i] = prev; - prev = type; - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i = 0; i < len; ++i) { - var type = types[i]; - if (type == ",") types[i] = "N"; - else if (type == "%") { - for (var end = i + 1; end < len && types[end] == "%"; ++end) { } - var replace = (i && types[i - 1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (cur == "L" && type == "1") types[i] = "L"; - else if (isStrong.test(type)) cur = type; - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i = 0; i < len; ++i) { - if (isNeutral.test(types[i])) { - for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) { } - var before = (i ? types[i - 1] : outerType) == "L"; - var after = (end < len ? types[end] : outerType) == "L"; - var replace = before || after ? "L" : "R"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i = 0; i < len;) { - if (countsAsLeft.test(types[i])) { - var start = i; - for (++i; i < len && countsAsLeft.test(types[i]); ++i) { } - order.push(new BidiSpan(0, start, i)); - } else { - var pos = i, at = order.length; - for (++i; i < len && types[i] != "L"; ++i) { } - for (var j = pos; j < i;) { - if (countsAsNum.test(types[j])) { - if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); - var nstart = j; - for (++j; j < i && countsAsNum.test(types[j]); ++j) { } - order.splice(at, 0, new BidiSpan(2, nstart, j)); - pos = j; - } else ++j; - } - if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } - if (order[0].level == 2) - order.unshift(new BidiSpan(1, order[0].to, order[0].to)); - if (order[0].level != lst(order).level) - order.push(new BidiSpan(order[0].level, len, len)); - - return order; - }; - })(); - - // THE END - - CodeMirror.version = "5.17.0"; - - return CodeMirror; -})(); - -// @ts-ignore -window.CodeMirror = CodeMirror; - -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// TODO actually recognize syntax of TypeScript constructs - -(function () { - "use strict"; - - function expressionAllowed(stream, state, backUp) { - return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) || - (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) - } - - CodeMirror.defineMode("javascript", function (config, parserConfig) { - var indentUnit = config.indentUnit; - var statementIndent = parserConfig.statementIndent; - var jsonldMode = parserConfig.jsonld; - var jsonMode = parserConfig.json || jsonldMode; - var isTS = parserConfig.typescript; - var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; - - // Tokenizer - - var keywords = function () { - function kw(type) { return { type: type, style: "keyword" }; } - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = { type: "atom", style: "atom" }; - - var jsKeywords = { - "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, - "var": kw("var"), "const": kw("var"), "let": kw("var"), - "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, - "this": kw("this"), "class": kw("class"), "super": kw("atom"), - "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, - "await": C, "async": kw("async") - }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = { type: "variable", style: "variable-3" }; - var tsKeywords = { - // object-like things - "interface": kw("class"), - "implements": C, - "namespace": C, - "module": kw("module"), - "enum": kw("module"), - - // scope modifiers - "public": kw("modifier"), - "private": kw("modifier"), - "protected": kw("modifier"), - "abstract": kw("modifier"), - - // operators - "as": operator, - - // types - "string": type, "number": type, "boolean": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|~^]/; - var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; - - function readRegexp(stream) { - var escaped = false, next, inSet = false; - while ((next = stream.next()) != null) { - if (!escaped) { - if (next == "/" && !inSet) return; - if (next == "[") inSet = true; - else if (inSet && next == "]") inSet = false; - } - escaped = !escaped && next == "\\"; - } - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { - return ret("number", "number"); - } else if (ch == "." && stream.match("..")) { - return ret("spread", "meta"); - } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - return ret(ch); - } else if (ch == "=" && stream.eat(">")) { - return ret("=>", "operator"); - } else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/o/i)) { - stream.eatWhile(/[0-7]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/b/i)) { - stream.eatWhile(/[01]/i); - return ret("number", "number"); - } else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); - return ret("number", "number"); - } else if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } else if (expressionAllowed(stream, state, 1)) { - readRegexp(stream); - stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); - return ret("regexp", "string-2"); - } else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } - } else if (ch == "`") { - state.tokenize = tokenQuasi; - return tokenQuasi(stream, state); - } else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } else if (wordRE.test(ch)) { - stream.eatWhile(wordRE); - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; - return (known && state.lastType != ".") ? ret(known.type, known.style, word) : - ret("variable", "variable", word); - } - } - - function tokenString(quote) { - return function (stream, state) { - var escaped = false, next; - if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)) { - state.tokenize = tokenBase; - return ret("jsonld-keyword", "meta"); - } - while ((next = stream.next()) != null) { - if (next == quote && !escaped) break; - escaped = !escaped && next == "\\"; - } - if (!escaped) state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - function tokenQuasi(stream, state) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && next == "\\"; - } - return ret("quasi", "string-2", stream.current()); - } - - var brackets = "([{}])"; - // This is a crude lookahead trick to try and notice that we're - // parsing the argument patterns for a fat-arrow function before we - // actually hit the arrow token. It only works if the arrow is on - // the same line as the arguments and there's no strange noise - // (comments) in between. Fallback is to only notice when we hit the - // arrow, and not declare the arguments as locals for the arrow - // body. - function findFatArrow(stream, state) { - if (state.fatArrowAt) state.fatArrowAt = null; - var arrow = stream.string.indexOf("=>", stream.start); - if (arrow < 0) return; - - var depth = 0, sawSomething = false; - for (var pos = arrow - 1; pos >= 0; --pos) { - var ch = stream.string.charAt(pos); - var bracket = brackets.indexOf(ch); - if (bracket >= 0 && bracket < 3) { - if (!depth) { ++pos; break; } - if (--depth == 0) break; - } else if (bracket >= 3 && bracket < 6) { - ++depth; - } else if (wordRE.test(ch)) { - sawSomething = true; - } else if (/["'\/]/.test(ch)) { - return; - } else if (sawSomething && !depth) { - ++pos; - break; - } - } - if (sawSomething && !depth) state.fatArrowAt = pos; - } - - // Parser - - var atomicTypes = { "atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true }; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - for (var cx = state.context; cx; cx = cx.prev) { - for (var v = cx.vars; v; v = v.next) - if (v.name == varname) return true; - } - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while (true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while (cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = { state: null, column: null, marked: null, cc: null }; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } - var state = cx.state; - cx.marked = "def"; - if (state.context) { - if (inList(state.localVars)) return; - state.localVars = { name: varname, next: state.localVars }; - } else { - if (inList(state.globalVars)) return; - if (parserConfig.globalVars) - state.globalVars = { name: varname, next: state.globalVars }; - } - } - - // Combinators - - var defaultVars = { name: "this", next: { name: "arguments" } }; - function pushcontext() { - cx.state.context = { prev: cx.state.context, vars: cx.state.localVars }; - cx.state.localVars = defaultVars; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function () { - var state = cx.state, indent = state.indented; - if (state.lexical.type == "stat") indent = state.lexical.indented; - else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) - indent = outer.indented; - state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - function exp(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(exp); - }; - return exp; - } - - function statement(type, value) { - if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "if") { - if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) - cx.state.cc.pop()(); - return cont(pushlex("form"), expression, statement, poplex, maybeelse); - } - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); - if (type == "variable") return cont(pushlex("stat"), maybelabel); - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - if (type == "class") return cont(pushlex("form"), className, poplex); - if (type == "export") return cont(pushlex("stat"), afterExport, poplex); - if (type == "import") return cont(pushlex("stat"), afterImport, poplex); - if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) - if (type == "async") return cont(statement) - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - return expressionInner(type, false); - } - function expressionNoComma(type) { - return expressionInner(type, true); - } - function expressionInner(type, noComma) { - if (cx.state.fatArrowAt == cx.stream.start) { - var body = noComma ? arrowBodyNoComma : arrowBody; - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); - else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); - } - - var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; - if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); - if (type == "function") return cont(functiondef, maybeop); - if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression); - if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); - if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); - if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); - if (type == "{") return contCommasep(objprop, "}", null, maybeop); - if (type == "quasi") return pass(quasi, maybeop); - if (type == "new") return cont(maybeTarget(noComma)); - return cont(); - } - function maybeexpression(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expression); - } - function maybeexpressionNoComma(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expressionNoComma); - } - - function maybeoperatorComma(type, value) { - if (type == ",") return cont(expression); - return maybeoperatorNoComma(type, value, false); - } - function maybeoperatorNoComma(type, value, noComma) { - var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; - var expr = noComma == false ? expression : expressionNoComma; - if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); - if (type == "operator") { - if (/\+\+|--/.test(value)) return cont(me); - if (value == "?") return cont(expression, expect(":"), expr); - return cont(expr); - } - if (type == "quasi") { return pass(quasi, me); } - if (type == ";") return; - if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); - if (type == ".") return cont(property, me); - if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); - } - function quasi(type, value) { - if (type != "quasi") return pass(); - if (value.slice(value.length - 2) != "${") return cont(quasi); - return cont(expression, continueQuasi); - } - function continueQuasi(type) { - if (type == "}") { - cx.marked = "string-2"; - cx.state.tokenize = tokenQuasi; - return cont(quasi); - } - } - function arrowBody(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expression); - } - function arrowBodyNoComma(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expressionNoComma); - } - function maybeTarget(noComma) { - return function (type) { - if (type == ".") return cont(noComma ? targetNoComma : target); - else return pass(noComma ? expressionNoComma : expression); - }; - } - function target(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } - } - function targetNoComma(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperatorComma, expect(";"), poplex); - } - function property(type) { - if (type == "variable") { cx.marked = "property"; return cont(); } - } - function objprop(type, value) { - if (type == "async") return cont(objprop); - if (type == "variable" || cx.style == "keyword") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(getterSetter); - return cont(afterprop); - } else if (type == "number" || type == "string") { - cx.marked = jsonldMode ? "property" : (cx.style + " property"); - return cont(afterprop); - } else if (type == "jsonld-keyword") { - return cont(afterprop); - } else if (type == "modifier") { - return cont(objprop) - } else if (type == "[") { - return cont(expression, expect("]"), afterprop); - } else if (type == "spread") { - return cont(expression); - } - } - function getterSetter(type) { - if (type != "variable") return pass(afterprop); - cx.marked = "property"; - return cont(functiondef); - } - function afterprop(type) { - if (type == ":") return cont(expressionNoComma); - if (type == "(") return pass(functiondef); - } - function commasep(what, end) { - function proceed(type, value) { - if (type == ",") { - var lex = cx.state.lexical; - if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; - return cont(function (type, value) { - if (type == end || value == end) return pass() - return pass(what) - }, proceed); - } - if (type == end || value == end) return cont(); - return cont(expect(end)); - } - return function (type, value) { - if (type == end || value == end) return cont(); - return pass(what, proceed); - }; - } - function contCommasep(what, end, info) { - for (var i = 3; i < arguments.length; i++) - cx.cc.push(arguments[i]); - return cont(pushlex(end, info), commasep(what, end), poplex); - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function maybetype(type) { - if (isTS && type == ":") return cont(typeexpr); - } - function maybedefault(_, value) { - if (value == "=") return cont(expressionNoComma); - } - function typeexpr(type) { - if (type == "variable") { cx.marked = "variable-3"; return cont(afterType); } - } - function afterType(type, value) { - if (value == "<") return cont(commasep(typeexpr, ">"), afterType) - if (type == "[") return cont(expect("]"), afterType) - } - function vardef() { - return pass(pattern, maybetype, maybeAssign, vardefCont); - } - function pattern(type, value) { - if (type == "modifier") return cont(pattern) - if (type == "variable") { register(value); return cont(); } - if (type == "spread") return cont(pattern); - if (type == "[") return contCommasep(pattern, "]"); - if (type == "{") return contCommasep(proppattern, "}"); - } - function proppattern(type, value) { - if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { - register(value); - return cont(maybeAssign); - } - if (type == "variable") cx.marked = "property"; - if (type == "spread") return cont(pattern); - if (type == "}") return pass(); - return cont(expect(":"), pattern, maybeAssign); - } - function maybeAssign(_type, value) { - if (value == "=") return cont(expressionNoComma); - } - function vardefCont(type) { - if (type == ",") return cont(vardef); - } - function maybeelse(type, value) { - if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); - } - function forspec(type) { - if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); - } - function forspec1(type) { - if (type == "var") return cont(vardef, expect(";"), forspec2); - if (type == ";") return cont(forspec2); - if (type == "variable") return cont(formaybeinof); - return pass(expression, expect(";"), forspec2); - } - function formaybeinof(_type, value) { - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return cont(maybeoperatorComma, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return pass(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (value == "*") { cx.marked = "keyword"; return cont(functiondef); } - if (type == "variable") { register(value); return cont(functiondef); } - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); - } - function funarg(type) { - if (type == "spread") return cont(funarg); - return pass(pattern, maybetype, maybedefault); - } - function className(type, value) { - if (type == "variable") { register(value); return cont(classNameAfter); } - } - function classNameAfter(type, value) { - if (value == "extends") return cont(expression, classNameAfter); - if (type == "{") return cont(pushlex("}"), classBody, poplex); - } - function classBody(type, value) { - if (type == "variable" || cx.style == "keyword") { - if (value == "static") { - cx.marked = "keyword"; - return cont(classBody); - } - cx.marked = "property"; - if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); - return cont(functiondef, classBody); - } - if (value == "*") { - cx.marked = "keyword"; - return cont(classBody); - } - if (type == ";") return cont(classBody); - if (type == "}") return cont(); - } - function classGetterSetter(type) { - if (type != "variable") return pass(); - cx.marked = "property"; - return cont(); - } - function afterExport(_type, value) { - if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } - if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } - return pass(statement); - } - function afterImport(type) { - if (type == "string") return cont(); - return pass(importSpec, maybeFrom); - } - function importSpec(type, value) { - if (type == "{") return contCommasep(importSpec, "}"); - if (type == "variable") register(value); - if (value == "*") cx.marked = "keyword"; - return cont(maybeAs); - } - function maybeAs(_type, value) { - if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } - } - function maybeFrom(_type, value) { - if (value == "from") { cx.marked = "keyword"; return cont(expression); } - } - function arrayLiteral(type) { - if (type == "]") return cont(); - return pass(expressionNoComma, commasep(expressionNoComma, "]")); - } - - function isContinuedStatement(state, textAfter) { - return state.lastType == "operator" || state.lastType == "," || - isOperatorChar.test(textAfter.charAt(0)) || - /[,.]/.test(textAfter.charAt(0)); - } - - // Interface - - return { - startState: function (basecolumn) { - var state = { - tokenize: tokenBase, - lastType: "sof", - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: parserConfig.localVars, - context: parserConfig.localVars && { vars: parserConfig.localVars }, - indented: basecolumn || 0 - }; - if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") - state.globalVars = parserConfig.globalVars; - return state; - }, - - token: function (stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - findFatArrow(stream, state); - } - if (state.tokenize != tokenComment && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; - return parseJS(state, style, type, content, stream); - }, - - indent: function (state, textAfter) { - if (state.tokenize == tokenComment) return CodeMirror.Pass; - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; - // Kludge to prevent 'maybelse' from blocking lexical scope pops - if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { - var c = state.cc[i]; - if (c == poplex) lexical = lexical.prev; - else if (c != maybeelse) break; - } - if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; - if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") - lexical = lexical.prev; - var type = lexical.type, closing = firstChar == type; - - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "form") return lexical.indented + indentUnit; - else if (type == "stat") - return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); - else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, - blockCommentStart: jsonMode ? null : "/*", - blockCommentEnd: jsonMode ? null : "*/", - lineComment: jsonMode ? null : "//", - fold: "brace", - closeBrackets: "()[]{}''\"\"``", - - helperType: jsonMode ? "json" : "javascript", - jsonldMode: jsonldMode, - jsonMode: jsonMode, - - expressionAllowed: expressionAllowed, - skipExpression: function (state) { - var top = state.cc[state.cc.length - 1] - if (top == expression || top == expressionNoComma) state.cc.pop() - } - }; - }); - - CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); - - CodeMirror.defineMIME("text/javascript", "javascript"); - CodeMirror.defineMIME("text/ecmascript", "javascript"); - CodeMirror.defineMIME("application/javascript", "javascript"); - CodeMirror.defineMIME("application/x-javascript", "javascript"); - CodeMirror.defineMIME("application/ecmascript", "javascript"); - CodeMirror.defineMIME("application/json", { name: "javascript", json: true }); - CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true }); - CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true }); - CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); - CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); - -})(); - -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function () { - var defaults = { - pairs: "()[]{}''\"\"", - triples: "", - explode: "[]{}" - }; - - var Pos = CodeMirror.Pos; - - CodeMirror.defineOption("autoCloseBrackets", false, function (cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.removeKeyMap(keyMap); - cm.state.closeBrackets = null; - } - if (val) { - cm.state.closeBrackets = val; - cm.addKeyMap(keyMap); - } - }); - - function getOption(conf, name) { - if (name == "pairs" && typeof conf == "string") return conf; - if (typeof conf == "object" && conf[name] != null) return conf[name]; - return defaults[name]; - } - - var bind = defaults.pairs + "`"; - var keyMap = { Backspace: handleBackspace, Enter: handleEnter }; - for (var i = 0; i < bind.length; i++) - keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); - - function handler(ch) { - return function (cm) { return handleChar(cm, ch); }; - } - - function getConfig(cm) { - var deflt = cm.state.closeBrackets; - if (!deflt) return null; - var mode = cm.getModeAt(cm.getCursor()); - return mode.closeBrackets || deflt; - } - - function handleBackspace(cm) { - var conf = getConfig(cm); - if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; - - var pairs = getOption(conf, "pairs"); - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - for (var i = ranges.length - 1; i >= 0; i--) { - var cur = ranges[i].head; - cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); - } - } - - function handleEnter(cm) { - var conf = getConfig(cm); - var explode = conf && getOption(conf, "explode"); - if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; - - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - cm.operation(function () { - cm.replaceSelection("\n\n", null); - cm.execCommand("goCharLeft"); - ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var line = ranges[i].head.line; - cm.indentLine(line, null, true); - cm.indentLine(line + 1, null, true); - } - }); - } - - function contractSelection(sel) { - var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; - return { - anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), - head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1)) - }; - } - - function handleChar(cm, ch) { - var conf = getConfig(cm); - if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; - - var pairs = getOption(conf, "pairs"); - var pos = pairs.indexOf(ch); - if (pos == -1) return CodeMirror.Pass; - var triples = getOption(conf, "triples"); - - var identical = pairs.charAt(pos + 1) == ch; - var ranges = cm.listSelections(); - var opening = pos % 2 == 0; - - var type; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i], cur = range.head, curType; - var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); - if (opening && !range.empty()) { - curType = "surround"; - } else if ((identical || !opening) && next == ch) { - if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) - curType = "skipThree"; - else - curType = "skip"; - } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && - cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && - (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { - curType = "addFour"; - } else if (identical) { - if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; - else return CodeMirror.Pass; - } else if (opening && (cm.getLine(cur.line).length == cur.ch || - isClosingBracket(next, pairs) || - /\s/.test(next))) { - curType = "both"; - } else { - return CodeMirror.Pass; - } - if (!type) type = curType; - else if (type != curType) return CodeMirror.Pass; - } - - var left = pos % 2 ? pairs.charAt(pos - 1) : ch; - var right = pos % 2 ? ch : pairs.charAt(pos + 1); - cm.operation(function () { - if (type == "skip") { - cm.execCommand("goCharRight"); - } else if (type == "skipThree") { - for (var i = 0; i < 3; i++) - cm.execCommand("goCharRight"); - } else if (type == "surround") { - var sels = cm.getSelections(); - for (var i = 0; i < sels.length; i++) - sels[i] = left + sels[i] + right; - cm.replaceSelections(sels, "around"); - sels = cm.listSelections().slice(); - for (var i = 0; i < sels.length; i++) - sels[i] = contractSelection(sels[i]); - cm.setSelections(sels); - } else if (type == "both") { - cm.replaceSelection(left + right, null); - cm.triggerElectric(left + right); - cm.execCommand("goCharLeft"); - } else if (type == "addFour") { - cm.replaceSelection(left + left + left + left, "before"); - cm.execCommand("goCharRight"); - } - }); - } - - function isClosingBracket(ch, pairs) { - var pos = pairs.lastIndexOf(ch); - return pos > -1 && pos % 2 == 1; - } - - function charsAround(cm, pos) { - var str = cm.getRange(Pos(pos.line, pos.ch - 1), - Pos(pos.line, pos.ch + 1)); - return str.length == 2 ? str : null; - } - - // Project the token type that will exists after the given char is - // typed, and use it to determine whether it would cause the start - // of a string token. - function enteringString(cm, pos, ch) { - var line = cm.getLine(pos.line); - var token = cm.getTokenAt(pos); - if (/\bstring2?\b/.test(token.type)) return false; - var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); - stream.pos = stream.start = token.start; - for (; ;) { - var type1 = cm.getMode().token(stream, token.state); - if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); - stream.start = stream.pos; - } - } -})(); - -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: https://codemirror.net/LICENSE - -// declare global: DOMRect - -(function () { - "use strict"; - - var HINT_ELEMENT_CLASS = "CodeMirror-hint"; - var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; - - // This is the old interface, kept around for now to stay - // backwards-compatible. - CodeMirror.showHint = function (cm, getHints, options) { - if (!getHints) return cm.showHint(options); - if (options && options.async) getHints.async = true; - var newOpts = { hint: getHints }; - if (options) for (var prop in options) newOpts[prop] = options[prop]; - return cm.showHint(newOpts); - }; - - CodeMirror.defineExtension("showHint", function (options) { - options = parseOptions(this, this.getCursor("start"), options); - var selections = this.listSelections() - if (selections.length > 1) return; - // By default, don't allow completion when something is selected. - // A hint function can have a `supportsSelection` property to - // indicate that it can handle selections. - if (this.somethingSelected()) { - if (!options.hint.supportsSelection) return; - // Don't try with cross-line selections - for (var i = 0; i < selections.length; i++) - if (selections[i].head.line != selections[i].anchor.line) return; - } - - if (this.state.completionActive) this.state.completionActive.close(); - var completion = this.state.completionActive = new Completion(this, options); - if (!completion.options.hint) return; - - CodeMirror.signal(this, "startCompletion", this); - completion.update(true); - }); - - CodeMirror.defineExtension("closeHint", function () { - if (this.state.completionActive) this.state.completionActive.close() - }) - - function Completion(cm, options) { - this.cm = cm; - this.options = options; - this.widget = null; - this.debounce = 0; - this.tick = 0; - this.startPos = this.cm.getCursor("start"); - this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; - - if (this.options.updateOnCursorActivity) { - var self = this; - cm.on("cursorActivity", this.activityFunc = function () { self.cursorActivity(); }); - } - } - - var requestAnimationFrame = window.requestAnimationFrame || function (fn) { - return setTimeout(fn, 1000 / 60); - }; - var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; - - Completion.prototype = { - close: function () { - if (!this.active()) return; - this.cm.state.completionActive = null; - this.tick = null; - if (this.options.updateOnCursorActivity) { - this.cm.off("cursorActivity", this.activityFunc); - } - - if (this.widget && this.data) CodeMirror.signal(this.data, "close"); - if (this.widget) this.widget.close(); - CodeMirror.signal(this.cm, "endCompletion", this.cm); - }, - - active: function () { - return this.cm.state.completionActive == this; - }, - - pick: function (data, i) { - var completion = data.list[i], self = this; - this.cm.operation(function () { - if (completion.hint) - completion.hint(self.cm, data, completion); - else - self.cm.replaceRange(getText(completion), completion.from || data.from, - completion.to || data.to, "complete"); - CodeMirror.signal(data, "pick", completion); - self.cm.scrollIntoView(); - }); - if (this.options.closeOnPick) { - this.close(); - } - }, - - cursorActivity: function () { - if (this.debounce) { - cancelAnimationFrame(this.debounce); - this.debounce = 0; - } - - var identStart = this.startPos; - if (this.data) { - identStart = this.data.from; - } - - var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); - if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || - pos.ch < identStart.ch || this.cm.somethingSelected() || - (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { - this.close(); - } else { - var self = this; - this.debounce = requestAnimationFrame(function () { self.update(); }); - if (this.widget) this.widget.disable(); - } - }, - - update: function (first) { - if (this.tick == null) return - var self = this, myTick = ++this.tick - fetchHints(this.options.hint, this.cm, this.options, function (data) { - if (self.tick == myTick) self.finishUpdate(data, first) - }) - }, - - finishUpdate: function (data, first) { - if (this.data) CodeMirror.signal(this.data, "update"); - - var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); - if (this.widget) this.widget.close(); - - this.data = data; - - if (data && data.list.length) { - if (picked && data.list.length == 1) { - this.pick(data, 0); - } else { - this.widget = new Widget(this, data); - CodeMirror.signal(data, "shown"); - } - } - } - }; - - function parseOptions(cm, pos, options) { - var editor = cm.options.hintOptions; - var out = {}; - for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; - if (editor) for (var prop in editor) - if (editor[prop] !== undefined) out[prop] = editor[prop]; - if (options) for (var prop in options) - if (options[prop] !== undefined) out[prop] = options[prop]; - if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) - return out; - } - - function getText(completion) { - if (typeof completion == "string") return completion; - else return completion.text; - } - - function buildKeyMap(completion, handle) { - var baseMap = { - Up: function () { handle.moveFocus(-1); }, - Down: function () { handle.moveFocus(1); }, - PageUp: function () { handle.moveFocus(-handle.menuSize() + 1, true); }, - PageDown: function () { handle.moveFocus(handle.menuSize() - 1, true); }, - Home: function () { handle.setFocus(0); }, - End: function () { handle.setFocus(handle.length - 1); }, - Enter: handle.pick, - Tab: handle.pick, - Esc: handle.close - }; - - var mac = /Mac/.test(navigator.platform); - - if (mac) { - baseMap["Ctrl-P"] = function () { handle.moveFocus(-1); }; - baseMap["Ctrl-N"] = function () { handle.moveFocus(1); }; - } - - var custom = completion.options.customKeys; - var ourMap = custom ? {} : baseMap; - function addBinding(key, val) { - var bound; - if (typeof val != "string") - bound = function (cm) { return val(cm, handle); }; - // This mechanism is deprecated - else if (baseMap.hasOwnProperty(val)) - bound = baseMap[val]; - else - bound = val; - ourMap[key] = bound; - } - if (custom) - for (var key in custom) if (custom.hasOwnProperty(key)) - addBinding(key, custom[key]); - var extra = completion.options.extraKeys; - if (extra) - for (var key in extra) if (extra.hasOwnProperty(key)) - addBinding(key, extra[key]); - return ourMap; - } - - function getHintElement(hintsElement, el) { - while (el && el != hintsElement) { - if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; - el = el.parentNode; - } - } - - function Widget(completion, data) { - this.completion = completion; - this.data = data; - this.picked = false; - var widget = this, cm = completion.cm; - var ownerDocument = cm.getInputField().ownerDocument; - var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow; - var hints = this.hints = ownerDocument.createElement("ul"); - var theme = completion.cm.options.theme; - hints.className = "CodeMirror-hints " + theme; - this.selectedHint = data.selectedHint || 0; - - var completions = data.list; - for (var i = 0; i < completions.length; ++i) { - var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i]; - var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); - if (cur.className != null) className = cur.className + " " + className; - elt.className = className; - if (cur.render) cur.render(elt, data, cur); - else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur))); - elt.hintId = i; - CodeMirror.on(elt, "mouseover", function (e) { - widget.changeActive(this.hintId); - }); - CodeMirror.on(elt, "touchstart", function (e) { - widget.changeActive(this.hintId); - }); - CodeMirror.on(elt, "touchend", function (e) { - var cur = cm.getCursor(); - var self = this; - setTimeout(function () { - cm.focus(); - var cur2 = cm.getCursor(); - if (cur2.line == cur.line && cur2.ch == 0) { - var textLen = self.innerText.length; - cm.setCursor({ line: cur.line, ch: cur.ch + textLen }); - } - }, 10); - }); - } - - var container = completion.options.container || ownerDocument.body; - var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); - var left = pos.left, top = pos.bottom, below = true; - var offsetLeft = 0, offsetTop = 0; - if (container !== ownerDocument.body) { - // We offset the cursor position because left and top are relative to the offsetParent's top left corner. - var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1; - var offsetParent = isContainerPositioned ? container : container.offsetParent; - var offsetParentPosition = offsetParent.getBoundingClientRect(); - var bodyPosition = ownerDocument.body.getBoundingClientRect(); - offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft); - offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop); - } - var documentZoom = getDocumentZoom(); - hints.style.fontSize = 16 / documentZoom * 0.9 + "px"; - hints.style.left = (left - offsetLeft) / documentZoom + "px"; - hints.style.top = (top - offsetTop) / documentZoom + "px"; - - // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. - var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); - var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); - container.appendChild(hints); - - var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect(); - var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false; - - // Compute in the timeout to avoid reflow on init - var startScroll; - setTimeout(function () { startScroll = cm.getScrollInfo(); }); - - var overlapY = box.bottom - winH; - if (overlapY > 0) { - var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); - if (curTop - height > 0) { // Fits above cursor - hints.style.top = (top = pos.top - height - offsetTop) / documentZoom + "px"; - below = false; - } else if (height > winH) { - hints.style.height = (winH - 5) / documentZoom + "px"; - hints.style.top = (top = pos.bottom - box.top - offsetTop) / documentZoom + "px"; - var cursor = cm.getCursor(); - if (data.from.ch != cursor.ch) { - pos = cm.cursorCoords(cursor); - hints.style.left = (left = pos.left - offsetLeft) / documentZoom + "px"; - box = hints.getBoundingClientRect(); - } - } - } - var overlapX = box.right - winW; - if (overlapX > 0) { - if (box.right - box.left > winW) { - hints.style.width = (winW - 5) / documentZoom + "px"; - overlapX -= (box.right - box.left) - winW; - } - hints.style.left = (left = pos.left - overlapX - offsetLeft) / documentZoom + "px"; - } - if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling) - node.style.paddingRight = cm.display.nativeBarWidth / documentZoom + "px" - - cm.addKeyMap(this.keyMap = buildKeyMap(completion, { - moveFocus: function (n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, - setFocus: function (n) { widget.changeActive(n); }, - menuSize: function () { return widget.screenAmount(); }, - length: completions.length, - close: function () { completion.close(); }, - pick: function () { widget.pick(); }, - data: data - })); - - if (completion.options.closeOnUnfocus) { - var closingOnBlur; - cm.on("blur", this.onBlur = function () { closingOnBlur = setTimeout(function () { completion.close(); }, 100); }); - cm.on("focus", this.onFocus = function () { clearTimeout(closingOnBlur); }); - } - - cm.on("scroll", this.onScroll = function () { - // fix "startScroll == undfined" - if (!startScroll) return; - var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); - var newTop = top + startScroll.top - curScroll.top; - var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop); - if (!below) point += hints.offsetHeight; - if (point <= editor.top || point >= editor.bottom) return completion.close(); - hints.style.top = newTop / documentZoom + "px"; - hints.style.left = (left + startScroll.left - curScroll.left) / documentZoom + "px"; - }); - - CodeMirror.on(hints, "dblclick", function (e) { - var t = getHintElement(hints, e.target || e.srcElement); - if (t && t.hintId != null) { widget.changeActive(t.hintId); widget.pick(); } - }); - - CodeMirror.on(hints, "click", function (e) { - var t = getHintElement(hints, e.target || e.srcElement); - if (t && t.hintId != null) { - widget.changeActive(t.hintId); - if (completion.options.completeOnSingleClick) widget.pick(); - } - }); - - CodeMirror.on(hints, "mousedown", function () { - setTimeout(function () { cm.focus(); }, 20); - }); - - //滑动修复 - CodeMirror.on(hints, "touchmove", function (event) { - if (ios && this.scrollHeight <= this.offsetHeight + 5 && this.scrollWidth <= this.offsetWidth + 5) { - event.preventDefault(); - } - else { - event.stopPropagation(); - } - }); - hints.style.WebkitOverflowScrolling = 'touch'; - - // The first hint doesn't need to be scrolled to on init - var selectedHintRange = this.getSelectedHintRange(); - if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) { - this.scrollToActive(); - } - - CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]); - return true; - } - - Widget.prototype = { - close: function () { - if (this.completion.widget != this) return; - this.completion.widget = null; - this.hints.parentNode.removeChild(this.hints); - this.completion.cm.removeKeyMap(this.keyMap); - - var cm = this.completion.cm; - if (this.completion.options.closeOnUnfocus) { - cm.off("blur", this.onBlur); - cm.off("focus", this.onFocus); - } - cm.off("scroll", this.onScroll); - }, - - disable: function () { - this.completion.cm.removeKeyMap(this.keyMap); - var widget = this; - this.keyMap = { Enter: function () { widget.picked = true; } }; - this.completion.cm.addKeyMap(this.keyMap); - }, - - pick: function () { - this.completion.pick(this.data, this.selectedHint); - }, - - changeActive: function (i, avoidWrap) { - if (i >= this.data.list.length) - i = avoidWrap ? this.data.list.length - 1 : 0; - else if (i < 0) - i = avoidWrap ? 0 : this.data.list.length - 1; - if (this.selectedHint == i) return; - var node = this.hints.childNodes[this.selectedHint]; - if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); - node = this.hints.childNodes[this.selectedHint = i]; - node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; - this.scrollToActive() - CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); - }, - - scrollToActive: function () { - var selectedHintRange = this.getSelectedHintRange(); - var node1 = this.hints.childNodes[selectedHintRange.from]; - var node2 = this.hints.childNodes[selectedHintRange.to]; - var firstNode = this.hints.firstChild; - if (node1.offsetTop < this.hints.scrollTop) - this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop; - else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) - this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop; - }, - - screenAmount: function () { - return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; - }, - - getSelectedHintRange: function () { - var margin = this.completion.options.scrollMargin || 0; - return { - from: Math.max(0, this.selectedHint - margin), - to: Math.min(this.data.list.length - 1, this.selectedHint + margin), - }; - } - }; - - function applicableHelpers(cm, helpers) { - if (!cm.somethingSelected()) return helpers - var result = [] - for (var i = 0; i < helpers.length; i++) - if (helpers[i].supportsSelection) result.push(helpers[i]) - return result - } - - function fetchHints(hint, cm, options, callback) { - if (hint.async) { - hint(cm, callback, options) - } else { - var result = hint(cm, options) - if (result && result.then) result.then(callback) - else callback(result) - } - } - - function resolveAutoHints(cm, pos) { - var helpers = cm.getHelpers(pos, "hint"), words - if (helpers.length) { - var resolved = function (cm, callback, options) { - var app = applicableHelpers(cm, helpers); - function run(i) { - if (i == app.length) return callback(null) - fetchHints(app[i], cm, options, function (result) { - if (result && result.list.length > 0) callback(result) - else run(i + 1) - }) - } - run(0) - } - resolved.async = true - resolved.supportsSelection = true - return resolved - } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { - return function (cm) { return CodeMirror.hint.fromList(cm, { words: words }) } - } else if (CodeMirror.hint.anyword) { - return function (cm, options) { return CodeMirror.hint.anyword(cm, options) } - } else { - return function () { } - } - } - - CodeMirror.registerHelper("hint", "auto", { - resolve: resolveAutoHints - }); - - CodeMirror.registerHelper("hint", "fromList", function (cm, options) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur) - var term, from = CodeMirror.Pos(cur.line, token.start), to = cur - if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) { - term = token.string.substr(0, cur.ch - token.start) - } else { - term = "" - from = cur - } - var found = []; - for (var i = 0; i < options.words.length; i++) { - var word = options.words[i]; - if (word.slice(0, term.length) == term) - found.push(word); - } - - if (found.length) return { list: found, from: from, to: to }; - }); - - CodeMirror.commands.autocomplete = CodeMirror.showHint; - - var defaultOptions = { - hint: CodeMirror.hint.auto, - completeSingle: true, - alignWithWord: true, - closeCharacters: /[\s()\[\]{};:>,]/, - closeOnPick: true, - closeOnUnfocus: true, - updateOnCursorActivity: true, - completeOnSingleClick: true, - container: null, - customKeys: null, - extraKeys: null, - paddingForScrollbar: true, - moveOnOverlap: true, - }; - - CodeMirror.defineOption("hintOptions", null); -})(); - -export default CodeMirror; \ No newline at end of file + +function getDocumentZoom() { + //一般body的缩放是xy同步的 + var transform = getComputedStyle(document.body).transform; + // @ts-ignore + if (transform == 'none') transform = 1; + // @ts-ignore + else transform = +transform.slice(7, -1).split(',')[0]; + return +transform; +} + +// BROWSER SNIFFING + +// Kludges for bugs and behavior differences that can't be feature +// detected are enabled based on userAgent etc sniffing. +var userAgent = navigator.userAgent; +var platform = navigator.platform; + +var gecko = /gecko\/\d/i.test(userAgent); +var ie_upto10 = /MSIE \d/.test(userAgent); +var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); +var ie = ie_upto10 || ie_11up; +// @ts-ignore +var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); +var webkit = /WebKit\//.test(userAgent); +var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); +var chrome = /Chrome\//.test(userAgent); +var presto = /Opera\//.test(userAgent); +var safari = /Apple Computer/.test(navigator.vendor); +var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); +var phantom = /PhantomJS/.test(userAgent); + +var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); +// This is woefully incomplete. Suggestions for alternative methods welcome. +var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); +var mac = ios || /Mac/.test(platform); +var chromeOS = /\bCrOS\b/.test(userAgent); +var windows = /win/i.test(platform); + +var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); +// @ts-ignore +if (presto_version) presto_version = Number(presto_version[1]); +// @ts-ignore +if (presto_version && presto_version >= 15) { presto = false; webkit = true; } +// Some browsers use the wrong event properties to signal cmd/ctrl on OS X +// @ts-ignore +var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); +var captureRightClick = gecko || (ie && ie_version >= 9); + +// Optimize some code when these features are not used. +var sawReadOnlySpans = false, sawCollapsedSpans = false; + +// EDITOR CONSTRUCTOR + +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . + +/** + * @type { typeof import('codemirror/index') } + */ +// @ts-ignore +var CodeMirror = (function () { + + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. + + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); + + this.options = options = options ? copyObj(options) : {}; + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false); + setGuttersForLineNumbers(options); + + var doc = options.value; + if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); + this.doc = doc; + + var input = new CodeMirror.inputStyles[options.inputStyle](this); + var display = this.display = new Display(place, doc, input); + display.wrapper.CodeMirror = this; + updateGutters(this); + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + if (options.autofocus && !mobile) display.input.focus(); + initScrollbars(this); + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + selectingText: false, + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + }; + + var cm = this; + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) setTimeout(function () { cm.display.input.reset(true); }, 20); + + registerEventHandlers(this); + ensureGlobalHandlers(); + + startOperation(this); + this.curOp.forceUpdate = true; + attachDoc(this, doc); + + if ((options.autofocus && !mobile) || cm.hasFocus()) + setTimeout(bind(onFocus, this), 20); + else + onBlur(this); + + for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](this, options[opt], Init); + maybeUpdateLineNumberWidth(this); + if (options.finishInit) options.finishInit(this); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); + endOperation(this); + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + display.lineDiv.style.textRendering = "auto"; + } + + // DISPLAY CONSTRUCTOR + + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc, input) { + var d = this; + this.input = input; + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.scrollbarFiller.setAttribute("cm-not-content", "true"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + d.gutterFiller.setAttribute("cm-not-content", "true"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = elt("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + d.sizerWidth = null; + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; + + if (place) { + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + d.reportedViewFrom = d.reportedViewTo = doc.first; + // Information about the rendered lines. + d.view = []; + d.renderedView = null; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastWrapHeight = d.lastWrapWidth = 0; + d.updateLineNumbers = null; + + d.nativeBarWidth = d.barHeight = d.barWidth = 0; + d.scrollbarsClipped = false; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + // True when shift is held down. + d.shift = false; + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null; + + d.activeTouch = null; + + input.init(d); + } + + // STATE UPDATES + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } + + function resetModeState(cm) { + cm.doc.iter(function (line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap"); + cm.display.sizer.style.minWidth = ""; + cm.display.sizerWidth = null; + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap"); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function () { updateScrollbars(cm); }, 100); + } + + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function (line) { + if (lineIsHidden(cm.doc, line)) return 0; + + var widgetsHeight = 0; + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; + } + + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; + else + return widgetsHeight + th; + }; + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function (line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function () { alignHorizontally(cm); }, 20); + } + + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + updateGutterSpace(cm); + } + + function updateGutterSpace(cm) { + var width = cm.display.gutters.offsetWidth; + cm.display.sizer.style.marginLeft = width + "px"; + } + + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(0, true); + len -= cur.text.length - found.from.ch; + cur = found.to.line; + len += cur.text.length - found.to.ch; + } + return len; + } + + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function (line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(found, 1); + } + } + + // SCROLLBARS + + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth; + var docH = Math.round(cm.doc.height + paddingVert(cm.display)); + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + }; + } + + function NativeScrollbars(place, scroll, cm) { + this.cm = cm; + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + place(vert); place(horiz); + + on(vert, "scroll", function () { + if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); + }); + on(horiz, "scroll", function () { + if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); + }); + + this.checkedZeroWidth = false; + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; + } + + NativeScrollbars.prototype = copyObj({ + update: function (measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + var sWidth = measure.nativeBarWidth; + + if (needsV) { + this.vert.style.display = "block"; + this.vert.style.bottom = needsH ? sWidth + "px" : "0"; + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; + } else { + this.vert.style.display = ""; + this.vert.firstChild.style.height = "0"; + } + + if (needsH) { + this.horiz.style.display = "block"; + this.horiz.style.right = needsV ? sWidth + "px" : "0"; + this.horiz.style.left = measure.barLeft + "px"; + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); + this.horiz.firstChild.style.width = + (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; + } else { + this.horiz.style.display = ""; + this.horiz.firstChild.style.width = "0"; + } + + if (!this.checkedZeroWidth && measure.clientHeight > 0) { + if (sWidth == 0) this.zeroWidthHack(); + this.checkedZeroWidth = true; + } + + return { right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0 }; + }, + setScrollLeft: function (pos) { + if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; + if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz); + }, + setScrollTop: function (pos) { + if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; + if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert); + }, + zeroWidthHack: function () { + var w = mac && !mac_geMountainLion ? "12px" : "18px"; + this.horiz.style.height = this.vert.style.width = w; + this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; + this.disableHoriz = new Delayed; + this.disableVert = new Delayed; + }, + enableZeroWidthBar: function (bar, delay) { + bar.style.pointerEvents = "auto"; + function maybeDisable() { + // To find out whether the scrollbar is still visible, we + // check whether the element under the pixel in the bottom + // left corner of the scrollbar box is the scrollbar box + // itself (when the bar is still visible) or its filler child + // (when the bar is hidden). If it is still visible, we keep + // it enabled, if it's hidden, we disable pointer events. + var box = bar.getBoundingClientRect(); + var elt = document.elementFromPoint(box.left + 1, box.bottom - 1); + if (elt != bar) bar.style.pointerEvents = "none"; + else delay.set(1000, maybeDisable); + } + delay.set(1000, maybeDisable); + }, + clear: function () { + var parent = this.horiz.parentNode; + parent.removeChild(this.horiz); + parent.removeChild(this.vert); + } + }, NativeScrollbars.prototype); + + function NullScrollbars() { } + + NullScrollbars.prototype = copyObj({ + update: function () { return { bottom: 0, right: 0 }; }, + setScrollLeft: function () { }, + setScrollTop: function () { }, + clear: function () { } + }, NullScrollbars.prototype); + + CodeMirror.scrollbarModel = { "native": NativeScrollbars, "null": NullScrollbars }; + + function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear(); + if (cm.display.scrollbars.addClass) + rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function (node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function () { + if (cm.state.focused) setTimeout(function () { cm.display.input.focus(); }, 0); + }); + node.setAttribute("cm-not-content", "true"); + }, function (pos, axis) { + if (axis == "horizontal") setScrollLeft(cm, pos); + else setScrollTop(cm, pos); + }, cm); + if (cm.display.scrollbars.addClass) + addClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm); + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; + updateScrollbarsInner(cm, measure); + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + updateHeightsInViewport(cm); + updateScrollbarsInner(cm, measureForScrollbars(cm)); + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; + } + } + + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbarsInner(cm, measure) { + var d = cm.display; + var sizes = d.scrollbars.update(measure); + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; + d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = sizes.bottom + "px"; + d.scrollbarFiller.style.width = sizes.right + "px"; + } else d.scrollbarFiller.style.display = ""; + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = sizes.bottom + "px"; + d.gutterFiller.style.width = measure.gutterWidth + "px"; + } else d.gutterFiller.style.display = ""; + } + + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewport may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; + if (ensureFrom < from) { + from = ensureFrom; + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); + to = ensureTo; + } + } + return { from: from, to: Math.max(to, from + 1) }; + } + + // LINE NUMBERS + + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter && view[i].gutter) + view[i].gutter.style.left = left; + var align = view[i].alignable; + if (align) for (var j = 0; j < align.length; j++) + align[j].style.left = left; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } + + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + var documentZoom = getDocumentZoom(); + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = (Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1) /* / documentZoom */; + display.lineNumWidth = (display.lineNumInnerWidth + padding) /* / documentZoom */; + display.lineNumChars = (display.lineNumInnerWidth ? last.length : -1) /* / documentZoom */; + display.lineGutter.style.width = display.lineNumWidth + "px"; + updateGutterSpace(cm); + return true; + } + return false; + } + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } + + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; + } + + // DISPLAY DRAWING + + function DisplayUpdate(cm, viewport, force) { + var display = cm.display; + + this.viewport = viewport; + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport); + this.editorIsHidden = !display.wrapper.offsetWidth; + this.wrapperHeight = display.wrapper.clientHeight; + this.wrapperWidth = display.wrapper.clientWidth; + this.oldDisplayWidth = displayWidth(cm); + this.force = force; + this.dims = getDimensions(cm); + this.events = []; + } + + DisplayUpdate.prototype.signal = function (emitter, type) { + if (hasHandler(emitter, type)) + this.events.push(arguments); + }; + DisplayUpdate.prototype.finish = function () { + for (var i = 0; i < this.events.length; i++) + signal.apply(null, this.events[i]); + }; + + function maybeClipScrollbars(cm) { + var display = cm.display; + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; + display.heightForcer.style.height = scrollGap(cm) + "px"; + display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; + display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; + display.scrollbarsClipped = true; + } + } + + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc; + + if (update.editorIsHidden) { + resetView(cm); + return false; + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + return false; + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm); + update.dims = getDimensions(cm); + } + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, update.visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; + adjustView(cm, from, to); + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; + + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + return false; + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var focused = activeElt(); + if (toUpdate > 4) display.lineDiv.style.display = "none"; + patchDisplay(cm, display.updateLineNumbers, update.dims); + if (toUpdate > 4) display.lineDiv.style.display = ""; + display.renderedView = display.view; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + display.gutters.style.height = display.sizer.style.minHeight = 0; + + if (different) { + display.lastWrapHeight = update.wrapperHeight; + display.lastWrapWidth = update.wrapperWidth; + startWorker(cm, 400); + } + + display.updateLineNumbers = null; + + return true; + } + + function postUpdateDisplay(cm, update) { + var viewport = update.viewport; + + for (var first = true; ; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + viewport = { top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top) }; + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport); + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + break; + } + if (!updateDisplayIfNeeded(cm, update)) break; + updateHeightsInViewport(cm); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + } + + update.signal(cm, "update", cm); + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; + } + } + + function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport); + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm); + postUpdateDisplay(cm, update); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + update.finish(); + } + } + + function setDocumentHeight(cm, measure) { + var documentZoom = getDocumentZoom(); + cm.display.sizer.style.minHeight = measure.docHeight / documentZoom + "px"; + cm.display.heightForcer.style.top = measure.docHeight / documentZoom + "px"; + cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) / documentZoom + "px"; + } + + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height; + if (cur.hidden) continue; + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + } + var diff = cur.line.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) for (var j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]); + } + } + } + + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) + line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; + } + + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + var gutterLeft = d.gutters.clientLeft; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; + width[cm.options.gutters[i]] = n.clientWidth; + } + return { + fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth + }; + } + + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none"; + else + node.parentNode.removeChild(node); + return next; + } + + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur); + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; + updateLineForChanges(cm, lineView, lineN, dims); + } + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) cur = rm(cur); + } + + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") updateLineText(cm, lineView); + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); + else if (type == "class") updateLineClasses(lineView); + else if (type == "widget") updateLineWidgets(cm, lineView, dims); + } + lineView.changes = null; + } + + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text); + lineView.node.appendChild(lineView.text); + if (ie && ie_version < 8) lineView.node.style.zIndex = 2; + } + return lineView.node; + } + + function updateLineBackground(lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) cls += " CodeMirror-linebackground"; + if (lineView.background) { + if (cls) lineView.background.className = cls; + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + } + } + + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built; + } + return buildLineContent(cm, lineView); + } + + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) lineView.node = built.pre; + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(lineView); + } else if (cls) { + lineView.text.className = cls; + } + } + + function updateLineClasses(lineView) { + updateLineBackground(lineView); + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass; + else if (lineView.node != lineView.text) + lineView.node.className = ""; + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } + + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; + } + if (lineView.gutterBackground) { + lineView.node.removeChild(lineView.gutterBackground); + lineView.gutterBackground = null; + } + if (lineView.line.gutterClass) { + var wrap = ensureLineWrapped(lineView); + lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, + "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + + "px; width: " + dims.gutterTotalWidth + "px"); + wrap.insertBefore(lineView.gutterBackground, lineView.text); + } + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"); + cm.display.input.setUneditable(gutterWrap); + wrap.insertBefore(gutterWrap, lineView.text); + if (lineView.line.gutterClass) + gutterWrap.className += " " + lineView.line.gutterClass; + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + cm.display.lineNumInnerWidth + "px")); + if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] / + "px")); + } + } + } + + function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) lineView.alignable = null; + for (var node = lineView.node.firstChild, next; node; node = next) { + var next = node.nextSibling; + if (node.className == "CodeMirror-linewidget") + lineView.node.removeChild(node); + } + insertLineWidgets(cm, lineView, dims); + } + + // Build a line's DOM representation from scratch + function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView); + lineView.text = lineView.node = built.pre; + if (built.bgClass) lineView.bgClass = built.bgClass; + if (built.textClass) lineView.textClass = built.textClass; + + updateLineClasses(lineView); + updateLineGutter(cm, lineView, lineN, dims); + insertLineWidgets(cm, lineView, dims); + return lineView.node; + } + + // A lineView may contain multiple logical lines (when merged by + // collapsed spans). The widgets for all of them need to be drawn. + function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); + } + + function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) return; + var wrap = ensureLineWrapped(lineView); + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); + if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); + positionLineWidget(widget, node, lineView, dims); + cm.display.input.setUneditable(node); + if (allowAbove && widget.above) + wrap.insertBefore(node, lineView.gutter || lineView.text); + else + wrap.appendChild(node); + signalLater(widget, "redraw"); + } + } + + function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + (lineView.alignable || (lineView.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; + } + } + + // POSITION OBJECT + + // A Pos instance represents a position within the text. + var Pos = CodeMirror.Pos = function (line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + }; + + // Compare two positions, return 0 if they are the same, a negative + // number when a is less, and a positive number otherwise. + var cmp = CodeMirror.cmpPos = function (a, b) { return a.line - b.line || a.ch - b.ch; }; + + function copyPos(x) { return Pos(x.line, x.ch); } + function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } + function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } + + // INPUT HANDLING + + function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } + } + + // This will be set to a {lineWise: bool, text: [string]} object, so + // that, when pasting, we know what kind of selections the copied + // text was made out of. + var lastCopied = null; + + function applyTextInput(cm, inserted, deleted, sel, origin) { + var doc = cm.doc; + cm.display.shift = false; + if (!sel) sel = doc.sel; + + var paste = cm.state.pasteIncoming || origin == "paste"; + var textLines = doc.splitLines(inserted), multiPaste = null + // When pasing N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.text.join("\n") == inserted) { + if (sel.ranges.length % lastCopied.text.length == 0) { + multiPaste = []; + for (var i = 0; i < lastCopied.text.length; i++) + multiPaste.push(doc.splitLines(lastCopied.text[i])); + } + } else if (textLines.length == sel.ranges.length) { + multiPaste = map(textLines, function (l) { return [l]; }); + } + } + + // Normal behavior is to insert the new text into every selection + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + var from = range.from(), to = range.to(); + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + from = Pos(from.line, from.ch - deleted); + else if (cm.state.overwrite && !paste) // Handle overwrite + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); + else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted) + from = to = Pos(from.line, 0) + } + var updateInput = cm.curOp.updateInput; + var changeEvent = { + from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input") + }; + makeChange(cm.doc, changeEvent); + signalLater(cm, "inputRead", cm, changeEvent); + } + if (inserted && !paste) + triggerElectric(cm, inserted); + + ensureCursorVisible(cm); + cm.curOp.updateInput = updateInput; + cm.curOp.typing = true; + cm.state.pasteIncoming = cm.state.cutIncoming = false; + } + + function handlePaste(e, cm) { + var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); + if (pasted) { + e.preventDefault(); + if (!cm.isReadOnly() && !cm.options.disableInput) + runInOp(cm, function () { applyTextInput(cm, pasted, 0, null, "paste"); }); + return true; + } + } + + function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) return; + var sel = cm.doc.sel; + + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; + var mode = cm.getModeAt(range.head); + var indented = false; + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart"); + break; + } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + indented = indentLine(cm, range.head.line, "smart"); + } + if (indented) signalLater(cm, "electricInput", cm, range.head.line); + } + } + + function copyableRanges(cm) { + var text = [], ranges = []; + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line; + var lineRange = { anchor: Pos(line, 0), head: Pos(line + 1, 0) }; + ranges.push(lineRange); + text.push(cm.getRange(lineRange.anchor, lineRange.head)); + } + return { text: text, ranges: ranges }; + } + + function disableBrowserMagic(field) { + field.setAttribute("autocorrect", "off"); + field.setAttribute("autocapitalize", "off"); + field.setAttribute("spellcheck", "false"); + } + + // TEXTAREA INPUT STYLE + + function TextareaInput(cm) { + this.cm = cm; + // See input.poll and input.reset + this.prevInput = ""; + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false; + // Self-resetting timeout for the poller + this.polling = new Delayed(); + // Tracks when input.reset has punted to just putting a short + // string into the textarea instead of the full selection. + this.inaccurateSelection = false; + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false; + this.composing = null; + }; + + function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none"); + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) te.style.width = "1000px"; + else te.setAttribute("wrap", "off"); + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) te.style.border = "1px solid black"; + disableBrowserMagic(te); + return div; + } + + TextareaInput.prototype = copyObj({ + init: function (display) { + var input = this, cm = this.cm; + + // Wraps and hides input textarea + var div = this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var te = this.textarea = div.firstChild; + display.wrapper.insertBefore(div, display.wrapper.firstChild); + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) te.style.width = "0px"; + + on(te, "input", function () { + if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; + input.poll(); + }); + + on(te, "paste", function (e) { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return + + cm.state.pasteIncoming = true; + input.fastPoll(); + }); + + function prepareCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + lastCopied = { lineWise: false, text: cm.getSelections() }; + if (input.inaccurateSelection) { + input.prevInput = ""; + input.inaccurateSelection = false; + te.value = lastCopied.text.join("\n"); + selectInput(te); + } + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = { lineWise: true, text: ranges.text }; + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll); + } else { + input.prevInput = ""; + te.value = ranges.text.join("\n"); + selectInput(te); + } + } + if (e.type == "cut") cm.state.cutIncoming = true; + } + on(te, "cut", prepareCopyCut); + on(te, "copy", prepareCopyCut); + + on(display.scroller, "paste", function (e) { + if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return; + cm.state.pasteIncoming = true; + input.focus(); + }); + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function (e) { + if (!eventInWidget(display, e)) e_preventDefault(e); + }); + + on(te, "compositionstart", function () { + var start = cm.getCursor("from"); + if (input.composing) input.composing.range.clear() + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), { className: "CodeMirror-composing" }) + }; + }); + on(te, "compositionend", function () { + if (input.composing) { + input.poll(); + input.composing.range.clear(); + input.composing = null; + } + }); + }, + + prepareSelection: function () { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc; + var result = prepareSelection(cm); + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + } + + return result; + }, + + showSelection: function (drawn) { + var cm = this.cm, display = cm.display; + removeChildrenAndAdd(display.cursorDiv, drawn.cursors); + removeChildrenAndAdd(display.selectionDiv, drawn.selection); + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px"; + this.wrapper.style.left = drawn.teLeft + "px"; + } + }, + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + reset: function (typing) { + if (this.contextMenuPending) return; + var minimal, selected, cm = this.cm, doc = cm.doc; + if (cm.somethingSelected()) { + this.prevInput = ""; + var range = doc.sel.primary(); + minimal = hasCopyEvent && + (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + this.textarea.value = content; + if (cm.state.focused) selectInput(this.textarea); + if (ie && ie_version >= 9) this.hasSelection = content; + } else if (!typing) { + this.prevInput = this.textarea.value = ""; + if (ie && ie_version >= 9) this.hasSelection = null; + } + this.inaccurateSelection = minimal; + }, + + getField: function () { return this.textarea; }, + + supportsTouch: function () { return false; }, + + focus: function () { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus(); } + catch (e) { } // IE8 will throw if the textarea is display: none or not in DOM + } + }, + + blur: function () { this.textarea.blur(); }, + + resetPosition: function () { + this.wrapper.style.top = this.wrapper.style.left = 0; + }, + + receivedFocus: function () { this.slowPoll(); }, + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + slowPoll: function () { + var input = this; + if (input.pollingFast) return; + input.polling.set(this.cm.options.pollInterval, function () { + input.poll(); + if (input.cm.state.focused) input.slowPoll(); + }); + }, + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + fastPoll: function () { + var missed = false, input = this; + input.pollingFast = true; + function p() { + var changed = input.poll(); + if (!changed && !missed) { missed = true; input.polling.set(60, p); } + else { input.pollingFast = false; input.slowPoll(); } + } + input.polling.set(20, p); + }, + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + poll: function () { + var cm = this.cm, input = this.textarea, prevInput = this.prevInput; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput && !this.composing) || + cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) + return false; + + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false; + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset(); + return false; + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0); + if (first == 0x200b && !prevInput) prevInput = "\u200b"; + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; + + var self = this; + runInOp(cm, function () { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, self.composing ? "*compose" : null); + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; + else self.prevInput = text; + + if (self.composing) { + self.composing.range.clear(); + self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), + { className: "CodeMirror-composing" }); + } + }); + return true; + }, + + ensurePolled: function () { + if (this.pollingFast && this.poll()) this.pollingFast = false; + }, + + onKeyPress: function () { + if (ie && ie_version >= 9) this.hasSelection = null; + this.fastPoll(); + }, + + onContextMenu: function (e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea; + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) return; // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); + + var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText; + input.wrapper.style.cssText = "position: absolute" + var wrapperBox = input.wrapper.getBoundingClientRect() + te.style.cssText = "position: absolute; width: 30px; height: 30px; top: " + (e.clientY - wrapperBox.top - 5) + + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px; z-index: 1000; background: " + + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + + "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) + display.input.focus(); + if (webkit) window.scrollTo(null, oldScrollY); + display.input.reset(); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) te.value = input.prevInput = " "; + input.contextMenuPending = true; + display.selForContextMenu = cm.doc.sel; + clearTimeout(display.detectingSelectAll); + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected(); + var extval = "\u200b" + (selected ? te.value : ""); + te.value = "\u21da"; // Used to catch context-menu undo + te.value = extval; + input.prevInput = selected ? "" : "\u200b"; + te.selectionStart = 1; te.selectionEnd = extval.length; + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel; + } + } + function rehide() { + input.contextMenuPending = false; + input.wrapper.style.cssText = oldWrapperCSS + te.style.cssText = oldCSS; + if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); + var i = 0, poll = function () { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); + else display.input.reset(); + }; + display.detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && ie_version >= 9) prepareSelectAllHack(); + if (captureRightClick) { + e_stop(e); + var mouseup = function () { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + }, + + readOnlyChanged: function (val) { + if (!val) this.reset(); + }, + + setUneditable: nothing, + + needsContentAttribute: false + }, TextareaInput.prototype); + + // CONTENTEDITABLE INPUT STYLE + + function ContentEditableInput(cm) { + this.cm = cm; + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; + this.polling = new Delayed(); + this.gracePeriod = false; + } + + ContentEditableInput.prototype = copyObj({ + init: function (display) { + var input = this, cm = input.cm; + var div = input.div = display.lineDiv; + disableBrowserMagic(div); + + on(div, "paste", function (e) { + if (!signalDOMEvent(cm, e)) handlePaste(e, cm); + }) + + on(div, "compositionstart", function (e) { + var data = e.data; + input.composing = { sel: cm.doc.sel, data: data, startData: data }; + if (!data) return; + var prim = cm.doc.sel.primary(); + var line = cm.getLine(prim.head.line); + var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); + if (found > -1 && found <= prim.head.ch) + input.composing.sel = simpleSelection(Pos(prim.head.line, found), + Pos(prim.head.line, found + data.length)); + }); + on(div, "compositionupdate", function (e) { + input.composing.data = e.data; + }); + on(div, "compositionend", function (e) { + var ours = input.composing; + if (!ours) return; + if (e.data != ours.startData && !/\u200b/.test(e.data)) + ours.data = e.data; + // Need a small delay to prevent other code (input event, + // selection polling) from doing damage when fired right after + // compositionend. + setTimeout(function () { + if (!ours.handled) + input.applyComposition(ours); + if (input.composing == ours) + input.composing = null; + }, 50); + }); + + on(div, "touchstart", function () { + input.forceCompositionEnd(); + }); + + on(div, "input", function () { + if (input.composing) return; + if (cm.isReadOnly() || !input.pollContent()) + runInOp(input.cm, function () { regChange(cm); }); + }); + + function onCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + lastCopied = { lineWise: false, text: cm.getSelections() }; + if (e.type == "cut") cm.replaceSelection("", null, "cut"); + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = { lineWise: true, text: ranges.text }; + if (e.type == "cut") { + cm.operation(function () { + cm.setSelections(ranges.ranges, 0, sel_dontScroll); + cm.replaceSelection("", null, "cut"); + }); + } + } + // iOS exposes the clipboard API, but seems to discard content inserted into it + if (e.clipboardData && !ios) { + e.preventDefault(); + e.clipboardData.clearData(); + e.clipboardData.setData("text/plain", lastCopied.text.join("\n")); + } else { + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild; + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); + te.value = lastCopied.text.join("\n"); + var hadFocus = document.activeElement; + selectInput(te); + setTimeout(function () { + cm.display.lineSpace.removeChild(kludge); + hadFocus.focus(); + }, 50); + } + } + on(div, "copy", onCopyCut); + on(div, "cut", onCopyCut); + }, + + prepareSelection: function () { + var result = prepareSelection(this.cm, false); + result.focus = this.cm.state.focused; + return result; + }, + + showSelection: function (info, takeFocus) { + if (!info || !this.cm.display.view.length) return; + if (info.focus || takeFocus) this.showPrimarySelection(); + this.showMultipleSelections(info); + }, + + showPrimarySelection: function () { + var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); + var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); + var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && + cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) + return; + + var start = posToDOM(this.cm, prim.from()); + var end = posToDOM(this.cm, prim.to()); + if (!start && !end) return; + + var view = this.cm.display.view; + var old = sel.rangeCount && sel.getRangeAt(0); + if (!start) { + start = { node: view[0].measure.map[2], offset: 0 }; + } else if (!end) { // FIXME dangerously hacky + var measure = view[view.length - 1].measure; + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; + end = { node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3] }; + } + + try { var rng = range(start.node, start.offset, end.offset, end.node); } + catch (e) { } // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + if (!gecko && this.cm.state.focused) { + sel.collapse(start.node, start.offset); + if (!rng.collapsed) sel.addRange(rng); + } else { + sel.removeAllRanges(); + sel.addRange(rng); + } + if (old && sel.anchorNode == null) sel.addRange(old); + else if (gecko) this.startGracePeriod(); + } + this.rememberSelection(); + }, + + startGracePeriod: function () { + var input = this; + clearTimeout(this.gracePeriod); + this.gracePeriod = setTimeout(function () { + input.gracePeriod = false; + if (input.selectionChanged()) + input.cm.operation(function () { input.cm.curOp.selectionChanged = true; }); + }, 20); + }, + + showMultipleSelections: function (info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); + }, + + rememberSelection: function () { + var sel = window.getSelection(); + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; + }, + + selectionInEditor: function () { + var sel = window.getSelection(); + if (!sel.rangeCount) return false; + var node = sel.getRangeAt(0).commonAncestorContainer; + return contains(this.div, node); + }, + + focus: function () { + if (this.cm.options.readOnly != "nocursor") this.div.focus(); + }, + blur: function () { this.div.blur(); }, + getField: function () { return this.div; }, + + supportsTouch: function () { return true; }, + + receivedFocus: function () { + var input = this; + if (this.selectionInEditor()) + this.pollSelection(); + else + runInOp(this.cm, function () { input.cm.curOp.selectionChanged = true; }); + + function poll() { + if (input.cm.state.focused) { + input.pollSelection(); + input.polling.set(input.cm.options.pollInterval, poll); + } + } + this.polling.set(this.cm.options.pollInterval, poll); + }, + + selectionChanged: function () { + var sel = window.getSelection(); + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; + }, + + pollSelection: function () { + if (!this.composing && !this.gracePeriod && this.selectionChanged()) { + var sel = window.getSelection(), cm = this.cm; + this.rememberSelection(); + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var head = domToPos(cm, sel.focusNode, sel.focusOffset); + if (anchor && head) runInOp(cm, function () { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); + if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; + }); + } + }, + + pollContent: function () { + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); + var from = sel.from(), to = sel.to(); + if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; + + var fromIndex; + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + var fromLine = lineNo(display.view[0].line); + var fromNode = display.view[0].node; + } else { + var fromLine = lineNo(display.view[fromIndex].line); + var fromNode = display.view[fromIndex - 1].node.nextSibling; + } + var toIndex = findViewIndex(cm, to.line); + if (toIndex == display.view.length - 1) { + var toLine = display.viewTo - 1; + var toNode = display.lineDiv.lastChild; + } else { + var toLine = lineNo(display.view[toIndex + 1].line) - 1; + var toNode = display.view[toIndex + 1].node.previousSibling; + } + + var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } + else break; + } + + var cutFront = 0, cutEnd = 0; + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + ++cutFront; + var newBot = lst(newText), oldBot = lst(oldText); + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)); + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + ++cutEnd; + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); + newText[0] = newText[0].slice(cutFront); + + var chFrom = Pos(fromLine, cutFront); + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input"); + return true; + } + }, + + ensurePolled: function () { + this.forceCompositionEnd(); + }, + reset: function () { + this.forceCompositionEnd(); + }, + forceCompositionEnd: function () { + if (!this.composing || this.composing.handled) return; + this.applyComposition(this.composing); + this.composing.handled = true; + this.div.blur(); + this.div.focus(); + }, + applyComposition: function (composing) { + if (this.cm.isReadOnly()) + operation(this.cm, regChange)(this.cm) + else if (composing.data && composing.data != composing.startData) + operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); + }, + + setUneditable: function (node) { + node.contentEditable = "false" + }, + + onKeyPress: function (e) { + e.preventDefault(); + if (!this.cm.isReadOnly()) + operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); + }, + + readOnlyChanged: function (val) { + this.div.contentEditable = String(val != "nocursor") + }, + + onContextMenu: nothing, + resetPosition: nothing, + + needsContentAttribute: true + }, ContentEditableInput.prototype); + + function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line); + if (!view || view.hidden) return null; + var line = getLine(cm.doc, pos.line); + var info = mapFromLineView(view, line, pos.line); + + var order = getOrder(line), side = "left"; + if (order) { + var partPos = getBidiPartAt(order, pos.ch); + side = partPos % 2 ? "right" : "left"; + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); + result.offset = result.collapse == "right" ? result.end : result.start; + return result; + } + + function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } + + function domToPos(cm, node, offset) { + var lineNode; + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset]; + if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); + node = null; offset = 0; + } else { + for (lineNode = node; ; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) return null; + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i]; + if (lineView.node == lineNode) + return locateNodeInLineView(lineView, node, offset); + } + } + + function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false; + if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); + if (node == wrapper) { + bad = true; + node = wrapper.childNodes[offset]; + offset = 0; + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line; + return badPos(Pos(lineNo(line), line.text.length), bad); + } + } + + var textNode = node.nodeType == 3 ? node : null, topNode = node; + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild; + if (offset) offset = textNode.nodeValue.length; + } + while (topNode.parentNode != wrapper) topNode = topNode.parentNode; + var measure = lineView.measure, maps = measure.maps; + + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i]; + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2]; + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); + var ch = map[j] + offset; + if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; + return Pos(line, ch); + } + } + } + } + var found = find(textNode, topNode, offset); + if (found) return badPos(found, bad); + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0); + if (found) + return badPos(Pos(found.line, found.ch - dist), bad); + else + dist += after.textContent.length; + } + for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1); + if (found) + return badPos(Pos(found.line, found.ch + dist), bad); + else + dist += after.textContent.length; + } + } + + function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false, lineSep = cm.doc.lineSeparator(); + function recognizeMarker(id) { return function (marker) { return marker.id == id; }; } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text"); + if (cmText != null) { + if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); + text += cmText; + return; + } + var markerID = node.getAttribute("cm-marker"), range; + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); + if (found.length && (range = found[0].find())) + text += getBetween(cm.doc, range.from, range.to).join(lineSep); + return; + } + if (node.getAttribute("contenteditable") == "false") return; + for (var i = 0; i < node.childNodes.length; i++) + walk(node.childNodes[i]); + if (/^(pre|div|p)$/i.test(node.nodeName)) + closing = true; + } else if (node.nodeType == 3) { + var val = node.nodeValue; + if (!val) return; + if (closing) { + text += lineSep; + closing = false; + } + text += val; + } + } + for (; ;) { + walk(from); + if (from == to) break; + from = from.nextSibling; + } + return text; + } + + CodeMirror.inputStyles = { "textarea": TextareaInput, "contenteditable": ContentEditableInput }; + + // SELECTION / CURSOR + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + function Selection(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + } + + Selection.prototype = { + primary: function () { return this.ranges[this.primIndex]; }, + equals: function (other) { + if (other == this) return true; + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; + } + return true; + }, + deepCopy: function () { + for (var out = [], i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); + return new Selection(out, this.primIndex); + }, + somethingSelected: function () { + for (var i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true; + return false; + }, + contains: function (pos, end) { + if (!end) end = pos; + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i; + } + return -1; + } + }; + + function Range(anchor, head) { + this.anchor = anchor; this.head = head; + } + + Range.prototype = { + from: function () { return minPos(this.anchor, this.head); }, + to: function () { return maxPos(this.anchor, this.head); }, + empty: function () { + return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; + } + }; + + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex]; + ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) --primIndex; + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } + } + return new Selection(ranges, primIndex); + } + + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0); + } + + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) { return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1)); } + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) { return l >= doc.first && l < doc.first + doc.size; } + function clipPosArray(doc, array) { + for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); + return out; + } + + // SELECTION UPDATES + + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. + + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(doc, range, head, other) { + if (doc.cm && doc.cm.display.shift || doc.extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head); + } else { + return new Range(other || head, head); + } + } + + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options) { + setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); + } + + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + for (var out = [], i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); + var newSel = normalizeSelection(out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } + + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); + } + + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } + + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel, options) { + var obj = { + ranges: sel.ranges, + update: function (ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); + }, + origin: options && options.origin + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); + else return sel; + } + + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } + + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } + + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel, options); + + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm); + } + + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return; + + doc.sel = sel; + + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; + signalCursorActivity(doc.cm); + } + signalLater(doc, "cursorActivity", doc); + } + + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); + } + + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i); + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel; + } + + function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { + var line = getLine(doc, pos.line); + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else { --i; continue; } + } + } + if (!m.atomic) continue; + + if (oldPos) { + var near = m.find(dir < 0 ? 1 : -1), diff; + if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) + near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); + if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) + return skipAtomicInner(doc, near, pos, dir, mayClear); + } + + var far = m.find(dir < 0 ? -1 : 1); + if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) + far = movePos(doc, far, dir, far.line == pos.line ? line : null); + return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null; + } + } + return pos; + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, oldPos, bias, mayClear) { + var dir = bias || 1; + var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || + skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); + if (!found) { + doc.cantEdit = true; + return Pos(doc.first, 0); + } + return found; + } + + function movePos(doc, pos, dir, line) { + if (dir < 0 && pos.ch == 0) { + if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1)); + else return null; + } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { + if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0); + else return null; + } else { + return new Pos(pos.line, pos.ch + dir); + } + } + + // SELECTION DRAWING + + function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()); + } + + function prepareSelection(cm, primary) { + var doc = cm.doc, result = {}; + var curFragment = result.cursors = document.createDocumentFragment(); + var selFragment = result.selection = document.createDocumentFragment(); + + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (primary === false && i == doc.sel.primIndex) continue; + var range = doc.sel.ranges[i]; + if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue; + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + drawSelectionCursor(cm, range.head, curFragment); + if (!collapsed) + drawSelectionRange(cm, range, selFragment); + } + return result; + } + + // Draws a cursor for the given range + function drawSelectionCursor(cm, head, output) { + var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + + var documentZoom = getDocumentZoom(); + + cursor.style.left = pos.left / documentZoom + "px"; + cursor.style.top = pos.top / documentZoom + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight / documentZoom + "px"; + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left / documentZoom + "px"; + otherCursor.style.top = pos.other.top / documentZoom + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 / documentZoom + "px"; + } + } + + // Draws the given range as a highlighted selection + function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left; + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; + + function add(left, top, width, bottom) { + if (top < 0) top = 0; + top = Math.round(top); + bottom = Math.round(bottom); + + var documentZoom = getDocumentZoom(); + + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left / documentZoom + + "px; top: " + top / documentZoom + "px; width: " + (width == null ? rightSide - left : width) / documentZoom + + "px; height: " + (bottom - top) / documentZoom + "px")); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } + + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = leftSide; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = rightSide; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < leftSide + 1) left = leftSide; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return { start: start, end: end }; + } + + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top); + } + + output.appendChild(fragment); + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function () { + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + else if (cm.options.cursorBlinkRate < 0) + display.cursorDiv.style.visibility = "hidden"; + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.viewTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + var changedLines = []; + + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { + if (doc.frontier >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength; + var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true); + line.styles = highlighted.styles; + var oldCls = line.styleClasses, newCls = highlighted.classes; + if (newCls) line.styleClasses = newCls; + else if (oldCls) line.styleClasses = null; + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) changedLines.push(doc.frontier); + line.stateAfter = tooLong ? state : copyState(doc.mode, state); + } else { + if (line.text.length <= cm.options.maxHighlightLength) + processLine(cm, line.text, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + if (changedLines.length) runInOp(cm, function () { + for (var i = 0; i < changedLines.length; i++) + regLineChange(cm, changedLines[i], "text"); + }); + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } + + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos - 1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function (line) { + processLine(cm, line.text, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + if (precise) doc.frontier = pos; + return state; + } + + // POSITION MEASUREMENT + + function paddingTop(display) { return display.lineSpace.offsetTop; } + function paddingVert(display) { return display.mover.offsetHeight - display.lineSpace.offsetHeight; } + function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH; + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + var data = { left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight) }; + if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; + return data; + } + + function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } + function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; + } + function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; + } + + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && displayWidth(cm); + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top); + } + } + heights.push(rect.bottom - rect.top); + } + } + + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return { map: lineView.measure.map, cache: lineView.measure.cache }; + for (var i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return { map: lineView.measure.maps[i], cache: lineView.measure.caches[i] }; + for (var i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return { map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true }; + } + + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view; + } + + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); + } + + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)]; + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext; + } + + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) { + view = null; + } else if (view && view.changes) { + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + cm.curOp.forceUpdate = true; + } + if (!view) + view = updateExternalMeasurement(cm, line); + + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + }; + } + + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) ch = -1; + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect(); + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) prepared.cache[key] = found; + } + return { + left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom + }; + } + + var nullRect = { left: 0, right: 0, top: 0, bottom: 0 }; + + function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + var mStart = map[i], mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) collapse = "right"; + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias; + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } + break; + } + } + return { node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd }; + } + + function getUsefulRect(rects, bias) { + var rect = nullRect + if (bias == "left") for (var i = 0; i < rects.length; i++) { + if ((rect = rects[i]).left != rect.right) break + } else for (var i = rects.length - 1; i >= 0; i--) { + if ((rect = rects[i]).left != rect.right) break + } + return rect + } + + function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); + var node = place.node, start = place.start, end = place.end, collapse = place.collapse; + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) + rect = node.parentNode.getBoundingClientRect(); + else + rect = getUsefulRect(range(node, start, end).getClientRects(), bias) + if (rect.left || rect.right || start == 0) break; + end = start; + start = start - 1; + collapse = "right"; + } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right"; + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = node.getBoundingClientRect(); + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + rect = { left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom }; + else + rect = nullRect; + } + + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; + var mid = (rtop + rbot) / 2; + var heights = prepared.view.measure.heights; + for (var i = 0; i < heights.length - 1; i++) + if (mid < heights[i]) break; + var top = i ? heights[i - 1] : 0, bot = heights[i]; + var result = { + left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot + }; + if (!rect.left && !rect.right) result.bogus = true; + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } + + return result; + } + + // Work around problem with bounding client rects on ranges being + // returned incorrectly when zoomed on IE10 and below. + function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + return rect; + var scaleX = screen.logicalXDPI / screen.deviceXDPI; + var scaleY = screen.logicalYDPI / screen.deviceYDPI; + return { + left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY + }; + } + + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {}; + } + } + + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]); + } + + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } + + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } + + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"/null (editor), "window", + // or "page". + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } + + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"/null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return { left: left - lineSpaceBox.left, top: top - lineSpaceBox.top }; + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); + } + + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } + + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0, pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return { left: left, right: left, top: top, bottom: top + lineObj.height }; + } + + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, outside, xRel) { + var pos = Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } + + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; + + var lineObj = getLine(doc, lineN); + for (; ;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(0, true); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line); + else + return found; + } + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var preparedMeasure = prepareMeasureForLine(cm, lineObj); + + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } + + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; + + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (; ;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var outside = ch == from ? fromOutside : toOutside + var xDiff = x - (ch == from ? fromX : toX); + // This is a kludge to handle the case where the coordinates + // are after a line-wrapped line. We should replace it with a + // more general handling of cursor positions around line + // breaks. (Issue #4078) + if (toOutside && !bidi && !/\s/.test(lineObj.text.charAt(ch)) && xDiff > 0 && + ch < lineObj.text.length && preparedMeasure.view.measure.heights.length > 1) { + var charSize = measureCharPrepared(cm, preparedMeasure, ch, "right"); + if (innerOff <= charSize.bottom && innerOff >= charSize.top && Math.abs(x - charSize.right) < xDiff) { + outside = false + ch++ + xDiff = x - charSize.right + } + } + while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, outside, xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) { to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step; } + else { from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step; } + } + } + + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } + + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } + + // OPERATIONS + + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. + + var operationGroup = null; + + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + }; + if (operationGroup) { + operationGroup.ops.push(cm.curOp); + } else { + cm.curOp.ownsGroup = operationGroup = { + ops: [cm.curOp], + delayedCallbacks: [] + }; + } + } + + function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0; + do { + for (; i < callbacks.length; i++) + callbacks[i].call(null); + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j]; + if (op.cursorActivityHandlers) + while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); + } + } while (i < callbacks.length); + } + + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp, group = op.ownsGroup; + if (!group) return; + + try { fireCallbacksForOps(group); } + finally { + operationGroup = null; + for (var i = 0; i < group.ops.length; i++) + group.ops[i].cm.curOp = null; + endOperations(group); + } + } + + // The DOM updates done when an operation finishes are batched so + // that the minimum number of relayouts are required. + function endOperations(group) { + var ops = group.ops; + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R1(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W1(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R2(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W2(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_finish(ops[i]); + } + + function endOperation_R1(op) { + var cm = op.cm, display = cm.display; + maybeClipScrollbars(cm); + if (op.updateMaxLine) findMaxLine(cm); + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping; + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && { top: op.scrollTop, ensure: op.scrollToPos }, op.forceUpdate); + } + + function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); + } + + function endOperation_R2(op) { + var cm = op.cm, display = cm.display; + if (op.updatedDisplay) updateHeightsInViewport(cm); + + op.barMeasure = measureForScrollbars(cm); + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; + cm.display.sizerWidth = op.adjustWidthTo; + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); + } + + if (op.updatedDisplay || op.selectionChanged) + op.preparedSelection = display.input.prepareSelection(op.focus); + } + + function endOperation_W2(op) { + var cm = op.cm; + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; + if (op.maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); + cm.display.maxLineChanged = false; + } + + var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()) + if (op.preparedSelection) + cm.display.input.showSelection(op.preparedSelection, takeFocus); + if (op.updatedDisplay || op.startHeight != cm.doc.height) + updateScrollbars(cm, op.barMeasure); + if (op.updatedDisplay) + setDocumentHeight(cm, op.barMeasure); + + if (op.selectionChanged) restartBlink(cm); + + if (cm.state.focused && op.updateInput) + cm.display.input.reset(op.typing); + if (takeFocus) ensureFocus(op.cm); + } + + function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc; + + if (op.updatedDisplay) postUpdateDisplay(cm, op.update); + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + display.wheelStartX = display.wheelStartY = null; + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { + doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); + display.scrollbars.setScrollTop(doc.scrollTop); + display.scroller.scrollTop = doc.scrollTop; + } + if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { + doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); + display.scrollbars.setScrollLeft(doc.scrollLeft); + display.scroller.scrollLeft = doc.scrollLeft; + alignHorizontally(cm); + } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); + if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); + + if (display.wrapper.offsetHeight) + doc.scrollTop = cm.display.scroller.scrollTop; + + // Fire change events, and delayed event handlers + if (op.changeObjs) + signal(cm, "changes", cm, op.changeObjs); + if (op.update) + op.update.finish(); + } + + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) return f(); + startOperation(cm); + try { return f(); } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function () { + if (cm.curOp) return f.apply(cm, arguments); + startOperation(cm); + try { return f.apply(cm, arguments); } + finally { endOperation(cm); } + }; + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function () { + if (this.curOp) return f.apply(this, arguments); + startOperation(this); + try { return f.apply(this, arguments); } + finally { endOperation(this); } + }; + } + function docMethodOp(f) { + return function () { + var cm = this.cm; + if (!cm || cm.curOp) return f.apply(this, arguments); + startOperation(cm); + try { return f.apply(this, arguments); } + finally { endOperation(cm); } + }; + } + + // VIEW TRACKING + + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } + + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array; + } + + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + if (!lendiff) lendiff = 0; + + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from; + + cm.curOp.viewChanged = true; + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm); + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut = viewCuttingPoint(cm, from, from, -1); + if (cut) { + display.view = display.view.slice(0, cut.index); + display.viewTo = cut.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } + + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff; + else if (from < ext.lineN + ext.size) + display.externalMeasured = null; + } + } + + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null; + + if (line < display.viewFrom || line >= display.viewTo) return; + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) return; + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) arr.push(type); + } + + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } + + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null; + n -= cm.display.viewFrom; + if (n < 0) return null; + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) return i; + } + } + + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + return { index: index, lineN: newN }; + for (var i = 0, n = cm.display.viewFrom; i < index; i++) + n += view[i].size; + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null; + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null; + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return { index: index, lineN: newN }; + } + + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)); + display.viewFrom = from; + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)); + } + display.viewTo = to; + } + + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; + } + return dirty; + } + + // EVENT HANDLERS + + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + on(d.scroller, "dblclick", operation(cm, function (e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = cm.findWordAt(pos); + extendSelection(cm.doc, word.anchor, word.head); + })); + else + on(d.scroller, "dblclick", function (e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", function (e) { onContextMenu(cm, e); }); + + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = { end: 0 }; + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function () { d.activeTouch = null; }, 1000); + prevTouch = d.activeTouch; + prevTouch.end = +new Date; + } + }; + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) return false; + var touch = e.touches[0]; + return touch.radiusX <= 1 && touch.radiusY <= 1; + } + function farAway(touch, other) { + if (other.left == null) return true; + var dx = other.left - touch.left, dy = other.top - touch.top; + return dx * dx + dy * dy > 20 * 20; + } + on(d.scroller, "touchstart", function (e) { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { + clearTimeout(touchFinished); + var now = +new Date; + d.activeTouch = { + start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null + }; + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX; + d.activeTouch.top = e.touches[0].pageY; + } + } + }); + on(d.scroller, "touchmove", function () { + if (d.activeTouch) d.activeTouch.moved = true; + }); + on(d.scroller, "touchend", function (e) { + var touch = d.activeTouch; + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range; + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + range = new Range(pos, pos); + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + range = cm.findWordAt(pos); + else // Triple tap + range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); + cm.setSelection(range.anchor, range.head); + cm.focus(); + e_preventDefault(e); + } + finishTouch(); + }); + on(d.scroller, "touchcancel", finishTouch); + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function () { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function (e) { onScrollWheel(cm, e); }); + on(d.scroller, "DOMMouseScroll", function (e) { onScrollWheel(cm, e); }); + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function () { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + d.dragFunctions = { + enter: function (e) { if (!signalDOMEvent(cm, e)) e_stop(e); }, + over: function (e) { if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); } }, + start: function (e) { onDragStart(cm, e); }, + drop: operation(cm, onDrop), + leave: function (e) { if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); } } + }; + + var inp = d.input.getField(); + on(inp, "keyup", function (e) { onKeyUp.call(cm, e); }); + on(inp, "keydown", operation(cm, onKeyDown)); + on(inp, "keypress", operation(cm, onKeyPress)); + on(inp, "focus", bind(onFocus, cm)); + on(inp, "blur", bind(onBlur, cm)); + } + + function dragDropChanged(cm, value, old) { + var wasOn = old && old != CodeMirror.Init; + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions; + var toggle = value ? on : off; + toggle(cm.display.scroller, "dragstart", funcs.start); + toggle(cm.display.scroller, "dragenter", funcs.enter); + toggle(cm.display.scroller, "dragover", funcs.over); + toggle(cm.display.scroller, "dragleave", funcs.leave); + toggle(cm.display.scroller, "drop", funcs.drop); + } + } + + // Called when the window resizes + function onResize(cm) { + var d = cm.display; + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + return; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + d.scrollbarsClipped = false; + cm.setSize(); + } + + // MOUSE EVENTS + + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + return true; + } + } + + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; + + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e) { return null; } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); + } + return coords; + } + + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + var cm = this, display = cm.display; + if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return; + display.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function () { display.scroller.draggable = true; }, 100); + } + return; + } + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + window.focus(); + + switch (e_button(e)) { + case 1: + // #3261: make sure, that we're not starting a second selection + if (cm.state.selectingText) + cm.state.selectingText(e); + else if (start) + leftButtonDown(cm, e, start); + else if (e_target(e) == display.scroller) + e_preventDefault(e); + break; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(function () { display.input.focus(); }, 20); + e_preventDefault(e); + break; + case 3: + if (captureRightClick) onContextMenu(cm, e); + else delayBlurEvent(cm); + break; + } + } + + var lastClick, lastDoubleClick; + function leftButtonDown(cm, e, start) { + if (ie) setTimeout(bind(ensureFocus, cm), 0); + else cm.curOp.focus = activeElt(); + + var now = +new Date, type; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { + type = "triple"; + } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { + type = "double"; + lastDoubleClick = { time: now, pos: start }; + } else { + type = "single"; + lastClick = { time: now, pos: start }; + } + + var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; + if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && + type == "single" && (contained = sel.contains(start)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && + (cmp(contained.to(), start) > 0 || start.xRel < 0)) + leftButtonStartDrag(cm, e, start, modifier); + else + leftButtonSelect(cm, e, start, type, modifier); + } + + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, e, start, modifier) { + var display = cm.display, startTime = +new Date; + var dragEnd = operation(cm, function (e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + if (!modifier && +new Date - 200 < startTime) + extendSelection(cm.doc, start); + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + setTimeout(function () { document.body.focus(); display.input.focus(); }, 20); + else + display.input.focus(); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + dragEnd.copy = mac ? e.altKey : e.ctrlKey + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + } + + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, e, start, type, addNew) { + var display = cm.display, doc = cm.doc; + e_preventDefault(e); + + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; + if (addNew && !e.shiftKey) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + ourRange = ranges[ourIndex]; + else + ourRange = new Range(start, start); + } else { + ourRange = doc.sel.primary(); + ourIndex = doc.sel.primIndex; + } + + if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) { + type = "rect"; + if (!addNew) ourRange = new Range(start, start); + start = posFromMouse(cm, e, true, true); + ourIndex = -1; + } else if (type == "double") { + var word = cm.findWordAt(start); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, word.anchor, word.head); + else + ourRange = word; + } else if (type == "triple") { + var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, line.anchor, line.head); + else + ourRange = line; + } else { + ourRange = extendRange(doc, ourRange, start); + } + + if (!addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + startSel = doc.sel; + } else if (ourIndex == -1) { + ourIndex = ranges.length; + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + { scroll: false, origin: "*mouse" }); + } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), + { scroll: false, origin: "*mouse" }); + startSel = doc.sel; + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } + + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return; + lastPos = pos; + + if (type == "rect") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); + } + if (!ranges.length) ranges.push(new Range(start, start)); + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + { origin: "*mouse", scroll: false }); + cm.scrollIntoView(pos); + } else { + var oldRange = ourRange; + var anchor = oldRange.anchor, head = pos; + if (type != "single") { + if (type == "double") + var range = cm.findWordAt(pos); + else + var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + } + var ranges = startSel.ranges.slice(0); + ranges[ourIndex] = new Range(clipPos(doc, anchor), head); + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); + } + } + + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, type == "rect"); + if (!cur) return; + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt(); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function () { if (counter == curCount) extend(e); }), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function () { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } + + function done(e) { + cm.state.selectingText = false; + counter = Infinity; + e_preventDefault(e); + display.input.focus(); + off(document, "mousemove", move); + off(document, "mouseup", up); + doc.history.lastSelOrigin = null; + } + + var move = operation(cm, function (e) { + if (!e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + cm.state.selectingText = up; + on(document, "mousemove", move); + on(document, "mouseup", up); + } + + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent) { + try { var mX = e.clientX, mY = e.clientY; } + catch (e) { return false; } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; + if (prevent) e_preventDefault(e); + + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signal(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true); + } + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + clearDragCursor(cm); + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return; + e_preventDefault(e); + if (ie) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || cm.isReadOnly()) return; + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function (file, i) { + if (cm.options.allowDropFileTypes && + indexOf(cm.options.allowDropFileTypes, file.type) == -1) + return; + + var reader = new FileReader; + reader.onload = operation(cm, function () { + var content = reader.result; + if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = ""; + text[i] = content; + if (++read == n) { + pos = clipPos(cm.doc, pos); + var change = { + from: pos, to: pos, + text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), + origin: "paste" + }; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); + } + }); + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(function () { cm.display.input.focus(); }, 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + if (cm.state.draggingText && !cm.state.draggingText.copy) + var selected = cm.listSelections(); + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) for (var i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); + cm.replaceSelection(text, "around", "paste"); + cm.display.input.focus(); + } + } + catch (e) { } + } + } + + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; + + e.dataTransfer.setData("Text", cm.getSelection()); + e.dataTransfer.effectAllowed = "copyMove" + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) img.parentNode.removeChild(img); + } + } + + function onDragOver(cm, e) { + var pos = posFromMouse(cm, e); + if (!pos) return; + var frag = document.createDocumentFragment(); + drawSelectionCursor(cm, pos, frag); + if (!cm.display.dragCursor) { + cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); + cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); + } + removeChildrenAndAdd(cm.display.dragCursor, frag); + } + + function clearDragCursor(cm) { + if (cm.display.dragCursor) { + cm.display.lineSpace.removeChild(cm.display.dragCursor); + cm.display.dragCursor = null; + } + } + + // SCROLL EVENTS + + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplaySimple(cm, { top: val }); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + cm.display.scrollbars.setScrollTop(val); + if (gecko) updateDisplaySimple(cm); + startWorker(cm, 100); + } + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + cm.display.scrollbars.setScrollLeft(val); + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1 / 3; + + var wheelEventDelta = function (e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + return { x: dx, y: dy }; + }; + CodeMirror.wheelEventPixels = function (e) { + var delta = wheelEventDelta(e); + delta.x *= wheelPixelsPerUnit; + delta.y *= wheelPixelsPerUnit; + return delta; + }; + + function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + var canScrollX = scroll.scrollWidth > scroll.clientWidth; + var canScrollY = scroll.scrollHeight > scroll.clientHeight; + if (!(dx && canScrollX || dy && canScrollY)) return; + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer; + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy && canScrollY) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + // Only prevent default scrolling if vertical scrolling is + // actually possible. Otherwise, it causes vertical scroll + // jitter on OSX trackpads when deltaX is small and deltaY + // is large (issue #3579) + if (!dy || (dy && canScrollY)) + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplaySimple(cm, { top: top, bottom: bot }); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function () { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + // KEY EVENTS + + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled(); + var prevShift = cm.display.shift, done = false; + try { + if (cm.isReadOnly()) cm.state.suppressEdits = true; + if (dropShift) cm.display.shift = false; + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } + + function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); + if (result) return result; + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm); + } + + var stopSeq = new Delayed; + function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq; + if (seq) { + if (isModifierKey(name)) return "handled"; + stopSeq.set(50, function () { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null; + cm.display.input.reset(); + } + }); + name = seq + " " + name; + } + var result = lookupKeyForEditor(cm, name, handle); + + if (result == "multi") + cm.state.keySeq = name; + if (result == "handled") + signalLater(cm, "keyHandled", cm, name, e); + + if (result == "handled" || result == "multi") { + e_preventDefault(e); + restartBlink(cm); + } + + if (seq && !result && /\'$/.test(name)) { + e_preventDefault(e); + return true; + } + return !!result; + } + + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + var name = keyName(e, true); + if (!name) return false; + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) + || dispatchKey(cm, name, e, function (b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }); + } + } + + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, + function (b) { return doHandleBinding(cm, b, true); }); + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + cm.curOp.focus = activeElt(); + if (signalDOMEvent(cm, e)) return; + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut"); + } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + showCrossHair(cm); + } + + function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv; + addClass(lineDiv, "CodeMirror-crosshair"); + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair"); + off(document, "keyup", up); + off(document, "mouseover", up); + } + } + on(document, "keyup", up); + on(document, "mouseover", up); + } + + function onKeyUp(e) { + if (e.keyCode == 16) this.doc.sel.shift = false; + signalDOMEvent(this, e); + } + + function onKeyPress(e) { + var cm = this; + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) { lastStoppedKey = null; e_preventDefault(e); return; } + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (handleCharBinding(cm, e, ch)) return; + cm.display.input.onKeyPress(e); + } + + // FOCUS/BLUR EVENTS + + function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true; + setTimeout(function () { + if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false; + onBlur(cm); + } + }, 100); + } + + function onFocus(cm) { + if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; + + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + addClass(cm.display.wrapper, "CodeMirror-focused"); + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset(); + if (webkit) setTimeout(function () { cm.display.input.reset(true); }, 20); // Issue #1730 + } + cm.display.input.receivedFocus(); + } + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.delayingBlurEvent) return; + + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + rmClass(cm.display.wrapper, "CodeMirror-focused"); + } + clearInterval(cm.display.blinker); + setTimeout(function () { if (!cm.state.focused) cm.display.shift = false; }, 150); + } + + // CONTEXT MENU HANDLING + + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; + if (signalDOMEvent(cm, e, "contextmenu")) return; + cm.display.input.onContextMenu(e); + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false); + } + + // UPDATING + + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + var changeEnd = CodeMirror.changeEnd = function (change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; + + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos; + if (cmp(pos, change.to) <= 0) return changeEnd(change); + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; + return Pos(line, ch); + } + + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(out, doc.sel.primIndex); + } + + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch); + else + return Pos(nw.line + (pos.line - old.line), pos.ch); + } + + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex); + } + + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function () { this.canceled = true; } + }; + if (update) obj.update = function (from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); + + if (obj.canceled) return null; + return { from: obj.from, to: obj.to, text: obj.text, origin: obj.origin }; + } + + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, { from: split[i].from, to: split[i].to, text: i ? [""] : change.text }); + } else { + makeChangeInner(doc, change); + } + } + + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) return; + + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + for (var i = 0; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break; + } + if (i == source.length) return; + hist.lastOrigin = hist.lastSelOrigin = null; + + for (; ;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, { clearRedo: false }); + return; + } + selAfter = event; + } + else break; + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({ changes: antiChanges, generation: hist.generation }); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return; + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (!i && doc.cm) doc.cm.scrollIntoView({ from: change.from, to: changeEnd(change) }); + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + if (distance == 0) return; + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function (range) { + return new Range(Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch)); + }), doc.sel.primIndex); + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance); + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + regLineChange(doc.cm, l, "gutter"); + } + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = { + from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin + }; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = { + from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin + }; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); + else updateDoc(doc, change, spans); + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function (line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + signalCursorActivity(cm); + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function (line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (change.full) + regChange(cm); + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text"); + else + regChange(cm, from.line, to.line + 1, lendiff); + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }; + if (changeHandler) signalLater(cm, "change", cm, obj); + if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); + } + cm.display.selForContextMenu = null; + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = doc.splitLines(code); + makeChange(doc, { from: from, to: to, text: code, origin: origin }); + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, coords) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) return; + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + + (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + + (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + + coords.left + "px; width: 2px;"); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0; + for (var limit = 0; limit < 5; limit++) { + var changed = false, coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), + Math.min(coords.top, endCoords.top) - margin, + Math.max(coords.left, endCoords.left), + Math.max(coords.bottom, endCoords.bottom) + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) break; + } + return coords; + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = displayHeight(cm), result = {}; + if (y2 - y1 > screen) y2 = y1 + screen; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; + var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); + var tooWide = x2 - x1 > screenw; + if (tooWide) x2 = x1 + screenw; + if (x1 < 10) + result.scrollLeft = 0; + else if (x1 < screenleft) + result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); + else if (x2 > screenw + screenleft - 3) + result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; + return result; + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollPos(cm, left, top) { + if (left != null || top != null) resolveScrollToPos(cm); + if (left != null) + cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; + if (top != null) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(), from = cur, to = cur; + if (!cm.options.lineWrapping) { + from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; + to = Pos(cur.line, cur.ch + 1); + } + cm.curOp.scrollToPos = { from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true }; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), + Math.min(from.top, to.top) - range.margin, + Math.max(from.right, to.right), + Math.max(from.bottom, to.bottom) + range.margin); + cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + } + + // API UTILITIES + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) how = "add"; + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) how = "prev"; + else state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) line.stateAfter = null; + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass || indentation > 150) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n - 1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) { pos += tabSize; indentString += "\t"; } + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + return true; + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i, new Range(pos, pos)); + break; + } + } + } + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); + return line; + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break; + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function () { + for (var i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); + ensureCursorVisible(cm); + }); + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "char", "column" (like char, but doesn't + // cross line boundaries), "word" (across next word), or "group" (to + // the start of next group of word or non-word-non-whitespace + // chars). The visually param controls whether, in right-to-left + // text, direction 1 means to move towards the next index in the + // string, or towards the character to the right of the current + // position. The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return false + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return false + } else ch = next; + return true; + } + + if (unit == "char") { + moveOnce() + } else if (unit == "column") { + moveOnce(true) + } else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); + for (var first = true; ; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) type = "s"; + if (sawType && sawType != type) { + if (dir < 0) { dir = 1; moveOnce(); } + break; + } + + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true); + if (!cmp(pos, result)) result.hitSide = true; + return result; + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (; ;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + // EDITOR METHODS + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function () { window.focus(); this.display.input.focus(); }, + + setOption: function (option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function (option) { return this.options[option]; }, + getDoc: function () { return this.doc; }, + + addKeyMap: function (map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); + }, + removeKeyMap: function (map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: methodOp(function (spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({ mode: mode, modeSpec: spec, opaque: options && options.opaque }); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function (spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: methodOp(function (n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: methodOp(function (how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var from = range.from(), to = range.to(); + var start = Math.max(end, from.line); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + indentLine(this, j, how); + var newRanges = this.doc.sel.ranges; + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) ensureCursorVisible(this); + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function (pos, precise) { + return takeToken(this, pos, precise); + }, + + getLineTokens: function (line, precise) { + return takeToken(this, Pos(line), precise, true); + }, + + getTokenTypeAt: function (pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + var type; + if (ch == 0) type = styles[2]; + else for (; ;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else { type = styles[mid * 2 + 2]; break; } + } + var cut = type ? type.indexOf("cm-overlay ") : -1; + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); + }, + + getModeAt: function (pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function (pos, type) { + return this.getHelpers(pos, type)[0]; + }, + + getHelpers: function (pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) return found; + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]); + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) found.push(val); + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i = 0; i < help._global.length; i++) { + var cur = help._global[i]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val); + } + return found; + }, + + getStateAfter: function (line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1 : line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function (start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) pos = range.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? range.from() : range.to(); + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function (pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function (coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function (height, mode) { + height = fromCoordSystem(this, { top: height, left: 0 }, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function (line, mode) { + var end = false, lineObj; + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + lineObj = getLine(this.doc, line); + } else { + lineObj = line; + } + return intoCoordSystem(this, lineObj, { top: 0, left: 0 }, mode || "page").top + + (end ? this.doc.height - heightAtLine(lineObj) : 0); + }, + + defaultTextHeight: function () { return textHeight(this.display); }, + defaultCharWidth: function () { return charWidth(this.display); }, + + setGutterMarker: methodOp(function (line, gutterID, value) { + return changeLine(this.doc, line, "gutter", function (line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: methodOp(function (gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function (line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regLineChange(cm, i, "gutter"); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + lineInfo: function (line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return { + line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets + }; + }, + + getViewport: function () { return { from: this.display.viewFrom, to: this.display.viewTo }; }, + + addWidget: function (pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + node.setAttribute("cm-ignore-events", "true"); + this.display.input.setUneditable(node); + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + + execCommand: function (cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd].call(null, this); + }, + + triggerElectric: methodOp(function (text) { triggerElectric(this, text); }), + + findPosH: function (from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: methodOp(function (dir, unit) { + var cm = this; + cm.extendSelectionsBy(function (range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); + else + return dir < 0 ? range.from() : range.to(); + }, sel_move); + }), + + deleteH: methodOp(function (dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete"); + else + deleteNearSelection(this, function (range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? { from: other, to: range.head } : { from: range.head, to: other }; + }); + }), + + findPosV: function (from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: methodOp(function (dir, unit) { + var cm = this, doc = this.doc, goals = []; + var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function (range) { + if (collapse) + return dir < 0 ? range.from() : range.to(); + var headPos = cursorCoords(cm, range.head, "div"); + if (range.goalColumn != null) headPos.left = range.goalColumn; + goals.push(headPos.left); + var pos = findPosV(cm, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); + return pos; + }, sel_move); + if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i]; + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function (pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function (ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); } + : function (ch) { return !/\s/.test(ch) && !isWordChar(ch); }; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + }, + + toggleOverwrite: function (value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + addClass(this.display.cursorDiv, "CodeMirror-overwrite"); + else + rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function () { return this.display.input.getField() == activeElt(); }, + isReadOnly: function () { return !!(this.options.readOnly || this.doc.cantEdit); }, + + scrollTo: methodOp(function (x, y) { + if (x != null || y != null) resolveScrollToPos(this); + if (x != null) this.curOp.scrollLeft = x; + if (y != null) this.curOp.scrollTop = y; + }), + getScrollInfo: function () { + var scroller = this.display.scroller; + return { + left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this) + }; + }, + + scrollIntoView: methodOp(function (range, margin) { + if (range == null) { + range = { from: this.doc.sel.primary().head, to: null }; + if (margin == null) margin = this.options.cursorScrollMargin; + } else if (typeof range == "number") { + range = { from: Pos(range, 0), to: null }; + } else if (range.from == null) { + range = { from: range, to: null }; + } + if (!range.to) range.to = range.from; + range.margin = margin || 0; + + if (range.from.line != null) { + resolveScrollToPos(this); + this.curOp.scrollToPos = range; + } else { + var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), + Math.min(range.from.top, range.to.top) - range.margin, + Math.max(range.from.right, range.to.right), + Math.max(range.from.bottom, range.to.bottom) + range.margin); + this.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + }), + + setSize: methodOp(function (width, height) { + var cm = this; + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) cm.display.wrapper.style.width = interpret(width); + if (height != null) cm.display.wrapper.style.height = interpret(height); + if (cm.options.lineWrapping) clearLineMeasurementCache(this); + var lineNo = cm.display.viewFrom; + cm.doc.iter(lineNo, cm.display.viewTo, function (line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) + if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } + ++lineNo; + }); + cm.curOp.forceUpdate = true; + signal(cm, "refresh", this); + }), + + operation: function (f) { return runInOp(this, f); }, + + refresh: methodOp(function () { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + this.curOp.forceUpdate = true; + clearCaches(this); + this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); + updateGutterSpace(this); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function (doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + this.display.input.reset(); + this.scrollTo(doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; + signalLater(this, "swapDoc", this, old); + return old; + }), + + getInputField: function () { return this.display.input.getField(); }, + getWrapperElement: function () { return this.display.wrapper; }, + getScrollerElement: function () { return this.display.scroller; }, + getGutterElement: function () { return this.display.gutters; } + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + // Functions to run when options are changed. + var optionHandlers = CodeMirror.optionHandlers = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function (cm, val, old) { if (old != Init) handle(cm, val, old); } : handle; + } + + // Passed to option handlers when there is no old value. + var Init = CodeMirror.Init = { toString: function () { return "CodeMirror.Init"; } }; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function (cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function (cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function (cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("lineSeparator", null, function (cm, val) { + cm.doc.lineSep = val; + if (!val) return; + var newBreaks = [], lineNo = cm.doc.first; + cm.doc.iter(function (line) { + for (var pos = 0; ;) { + var found = line.text.indexOf(val, pos); + if (found == -1) break; + pos = found + val.length; + newBreaks.push(Pos(lineNo, found)); + } + lineNo++; + }); + for (var i = newBreaks.length - 1; i >= 0; i--) + replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) + }); + option("specialChars", /[\u0000-\u001f\u007f\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + if (old != CodeMirror.Init) cm.refresh(); + }); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { cm.refresh(); }, true); + option("electricChars", true); + option("inputStyle", mobile ? "contenteditable" : "textarea", function () { + throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME + }, true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function (cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", function (cm, val, old) { + var next = getKeyMap(val); + var prev = old != CodeMirror.Init && getKeyMap(old); + if (prev && prev.detach) prev.detach(cm, next); + if (next.attach) next.attach(cm, prev || null); + }); + option("extraKeys", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function (cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function (cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, function (cm) { updateScrollbars(cm); }, true); + option("scrollbarStyle", "native", function (cm) { + initScrollbars(cm); + updateScrollbars(cm); + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); + }, true); + option("lineNumbers", false, function (cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + option("lineWiseCopyCut", true); + + option("readOnly", false, function (cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + cm.display.disabled = true; + } else { + cm.display.disabled = false; + } + cm.display.input.readOnlyChanged(val) + }); + option("disableInput", false, function (cm, val) { if (!val) cm.display.input.reset(); }, true); + option("dragDrop", true, dragDropChanged); + option("allowDropFileTypes", null); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1, updateSelection, true); + option("singleCursorHeightPerLine", true, updateSelection, true); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function (cm, val) { cm.doc.history.undoDepth = val; }); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function (cm) { cm.refresh(); }, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function (cm, val) { + if (!val) cm.display.input.resetPosition(); + }); + + option("tabindex", null, function (cm, val) { + cm.display.input.getField().tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function (name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; + }; + + CodeMirror.defineMIME = function (mime, spec) { + mimeModes[mime] = spec; + }; + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + CodeMirror.resolveMode = function (spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") found = { name: found }; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return { name: spec }; + else return spec || { name: "null" }; + }; + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + CodeMirror.getMode = function (options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; + }; + + // Minimal default mode. + CodeMirror.defineMode("null", function () { + return { token: function (stream) { stream.skipToEnd(); } }; + }); + CodeMirror.defineMIME("text/plain", "null"); + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function (mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function (name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function (name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function (f) { initHooks.push(f); }; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function (type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = { _global: [] }; + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function (type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({ pred: predicate, val: value }); + }; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because nested + // modes need to do this for their inner modes. + + var copyState = CodeMirror.copyState = function (mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + }; + + var startState = CodeMirror.startState = function (mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + }; + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + CodeMirror.innerMode = function (mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || { mode: mode, state: state }; + }; + + // STANDARD COMMANDS + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = CodeMirror.commands = { + selectAll: function (cm) { cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll); }, + singleSelection: function (cm) { + cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); + }, + killLine: function (cm) { + deleteNearSelection(cm, function (range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + return { from: range.head, to: Pos(range.head.line + 1, 0) }; + else + return { from: range.head, to: Pos(range.head.line, len) }; + } else { + return { from: range.from(), to: range.to() }; + } + }); + }, + deleteLine: function (cm) { + deleteNearSelection(cm, function (range) { + return { + from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) + }; + }); + }, + delLineLeft: function (cm) { + deleteNearSelection(cm, function (range) { + return { from: Pos(range.from().line, 0), to: range.from() }; + }); + }, + delWrappedLineLeft: function (cm) { + deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + var leftPos = cm.coordsChar({ left: 0, top: top }, "div"); + return { from: leftPos, to: range.from() }; + }); + }, + delWrappedLineRight: function (cm) { + deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + var rightPos = cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div"); + return { from: range.from(), to: rightPos }; + }); + }, + undo: function (cm) { cm.undo(); }, + redo: function (cm) { cm.redo(); }, + undoSelection: function (cm) { cm.undoSelection(); }, + redoSelection: function (cm) { cm.redoSelection(); }, + goDocStart: function (cm) { cm.extendSelection(Pos(cm.firstLine(), 0)); }, + goDocEnd: function (cm) { cm.extendSelection(Pos(cm.lastLine())); }, + goLineStart: function (cm) { + cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, + { origin: "+move", bias: 1 }); + }, + goLineStartSmart: function (cm) { + cm.extendSelectionsBy(function (range) { + return lineStartSmart(cm, range.head); + }, { origin: "+move", bias: 1 }); + }, + goLineEnd: function (cm) { + cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, + { origin: "+move", bias: -1 }); + }, + goLineRight: function (cm) { + cm.extendSelectionsBy(function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div"); + }, sel_move); + }, + goLineLeft: function (cm) { + cm.extendSelectionsBy(function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({ left: 0, top: top }, "div"); + }, sel_move); + }, + goLineLeftSmart: function (cm) { + cm.extendSelectionsBy(function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + var pos = cm.coordsChar({ left: 0, top: top }, "div"); + if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); + return pos; + }, sel_move); + }, + goLineUp: function (cm) { cm.moveV(-1, "line"); }, + goLineDown: function (cm) { cm.moveV(1, "line"); }, + goPageUp: function (cm) { cm.moveV(-1, "page"); }, + goPageDown: function (cm) { cm.moveV(1, "page"); }, + goCharLeft: function (cm) { cm.moveH(-1, "char"); }, + goCharRight: function (cm) { cm.moveH(1, "char"); }, + goColumnLeft: function (cm) { cm.moveH(-1, "column"); }, + goColumnRight: function (cm) { cm.moveH(1, "column"); }, + goWordLeft: function (cm) { cm.moveH(-1, "word"); }, + goGroupRight: function (cm) { cm.moveH(1, "group"); }, + goGroupLeft: function (cm) { cm.moveH(-1, "group"); }, + goWordRight: function (cm) { cm.moveH(1, "word"); }, + delCharBefore: function (cm) { cm.deleteH(-1, "char"); }, + delCharAfter: function (cm) { cm.deleteH(1, "char"); }, + delWordBefore: function (cm) { cm.deleteH(-1, "word"); }, + delWordAfter: function (cm) { cm.deleteH(1, "word"); }, + delGroupBefore: function (cm) { cm.deleteH(-1, "group"); }, + delGroupAfter: function (cm) { cm.deleteH(1, "group"); }, + indentAuto: function (cm) { cm.indentSelection("smart"); }, + indentMore: function (cm) { cm.indentSelection("add"); }, + indentLess: function (cm) { cm.indentSelection("subtract"); }, + insertTab: function (cm) { cm.replaceSelection("\t"); }, + insertSoftTab: function (cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from(); + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); + spaces.push(spaceStr(tabSize - col % tabSize)); + } + cm.replaceSelections(spaces); + }, + defaultTab: function (cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.execCommand("insertTab"); + }, + transposeChars: function (cm) { + runInOp(cm, function () { + var ranges = cm.listSelections(), newSel = []; + for (var i = 0; i < ranges.length; i++) { + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (line) { + if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1); + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose"); + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text; + if (prev) + cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); + } + } + newSel.push(new Range(cur, cur)); + } + cm.setSelections(newSel); + }); + }, + newlineAndIndent: function (cm) { + runInOp(cm, function () { + var len = cm.listSelections().length; + for (var i = 0; i < len; i++) { + var range = cm.listSelections()[i]; + cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input"); + cm.indentLine(range.from().line + 1, null, true); + } + ensureCursorVisible(cm); + }); + }, + openLine: function (cm) { cm.replaceSelection("\n", "start") }, + toggleOverwrite: function (cm) { cm.toggleOverwrite(); } + }; + + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", + "Ctrl-O": "openLine" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; + var alt, ctrl, shift, cmd; + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; + else if (/^a(lt)?$/i.test(mod)) alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; + else if (/^s(hift)$/i.test(mod)) shift = true; + else throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) name = "Alt-" + name; + if (ctrl) name = "Ctrl-" + name; + if (cmd) name = "Cmd-" + name; + if (shift) name = "Shift-" + name; + return name; + } + + // This is a kludge to keep keymaps mostly working as raw objects + // (backwards compatibility) while at the same time support features + // like normalization and multi-stroke key bindings. It compiles a + // new normalized keymap, and then updates the old object to reflect + // this. + CodeMirror.normalizeKeyMap = function (keymap) { + var copy = {}; + for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname]; + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; + if (value == "...") { delete keymap[keyname]; continue; } + + var keys = map(keyname.split(" "), normalizeKeyName); + for (var i = 0; i < keys.length; i++) { + var val, name; + if (i == keys.length - 1) { + name = keys.join(" "); + val = value; + } else { + name = keys.slice(0, i + 1).join(" "); + val = "..."; + } + var prev = copy[name]; + if (!prev) copy[name] = val; + else if (prev != val) throw new Error("Inconsistent bindings for " + name); + } + delete keymap[keyname]; + } + for (var prop in copy) keymap[prop] = copy[prop]; + return keymap; + }; + + var lookupKey = CodeMirror.lookupKey = function (key, map, handle, context) { + map = getKeyMap(map); + var found = map.call ? map.call(key, context) : map[key]; + if (found === false) return "nothing"; + if (found === "...") return "multi"; + if (found != null && handle(found)) return "handled"; + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + return lookupKey(key, map.fallthrough, handle, context); + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context); + if (result) return result; + } + } + }; + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + var isModifierKey = CodeMirror.isModifierKey = function (value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + }; + + // Look up the name of a key as indicated by an event object. + var keyName = CodeMirror.keyName = function (event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false; + var base = keyNames[event.keyCode], name = base; + if (name == null || event.altGraphKey) return false; + if (event.altKey && base != "Alt") name = "Alt-" + name; + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; + if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; + return name; + }; + + function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val; + } + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function (textarea, options) { + options = options ? copyObj(options) : {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabIndex) + options.tabindex = textarea.tabIndex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() { textarea.value = cm.getValue(); } + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function () { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch (e) { } + } + } + + options.finishInit = function (cm) { + cm.save = save; + cm.getTextArea = function () { return textarea; }; + cm.toTextArea = function () { + cm.toTextArea = isNaN; // Prevent this from being ran twice + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + }; + + textarea.style.display = "none"; + var cm = CodeMirror(function (node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = CodeMirror.StringStream = function (string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function () { return this.pos >= this.string.length; }, + sol: function () { return this.pos == this.lineStart; }, + peek: function () { return this.string.charAt(this.pos) || undefined; }, + next: function () { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function (match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) { ++this.pos; return ch; } + }, + eatWhile: function (match) { + var start = this.pos; + while (this.eat(match)) { } + return this.pos > start; + }, + eatSpace: function () { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function () { this.pos = this.string.length; }, + skipTo: function (ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) { this.pos = found; return true; } + }, + backUp: function (n) { this.pos -= n; }, + column: function () { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function () { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function (pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function () { return this.string.slice(this.start, this.pos); }, + hideFirstChars: function (n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + var nextMarkerId = 0; + + var TextMarker = CodeMirror.TextMarker = function (doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + this.id = ++nextMarkerId; + }; + eventMixin(TextMarker); + + // Clear the marker. + TextMarker.prototype.clear = function () { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); + else if (cm) { + if (span.to != null) max = lineNo(line); + if (span.from != null) min = lineNo(line); + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(this.lines[i]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm.doc); + } + if (cm) signalLater(cm, "markerCleared", cm, this); + if (withOp) endOperation(cm); + if (this.parent) this.parent.clear(); + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function (side, lineObj) { + if (side == null && this.type == "bookmark") side = 1; + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) return from; + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) return to; + } + } + return from && { from: from, to: to }; + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function () { + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) return; + runInOp(cm, function () { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + updateLineHeight(line, line.height + dHeight); + } + }); + }; + + TextMarker.prototype.attachLine = function (line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function (line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type); + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) copyObj(options, marker, false); + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker; + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); + if (options.insertLeft) marker.widgetNode.insertLeft = true; + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one"); + sawCollapsedSpans = true; + } + + if (marker.addToHistory) + addChangeToHistory(doc, { from: from, to: to, origin: "markText" }, doc.sel, NaN); + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function (line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true; + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, function (line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function () { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.collapsed) + regChange(cm, from.line, to.line + 1); + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); + if (marker.atomic) reCheckSelection(cm.doc); + signalLater(cm, "markerAdded", cm, marker); + } + return marker; + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = CodeMirror.SharedTextMarker = function (markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0; i < markers.length; ++i) + markers[i].parent = this; + }; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function () { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function (side, lineObj) { + return this.primary.find(side, lineObj); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function (doc) { + if (widget) options.widgetNode = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), + function (m) { return m.parent; }); + } + + function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find(); + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); + marker.markers.push(subMark); + subMark.parent = marker; + } + } + } + + function detachSharedMarkers(markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], linked = [marker.primary.doc];; + linkedDocs(marker.primary.doc, function (d) { linked.push(d); }); + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j]; + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null; + marker.markers.splice(j--, 1); + } + } + } + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } + return nw; + } + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } + return nw; + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + if (change.full) return null; + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first); + if (last && last != first) last = clearEmptySpans(last); + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1); + } + if (!spans.length) return null; + return spans; + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function (line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{ from: from, to: to }]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({ from: p.from, to: m.from }); + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({ from: m.to, to: p.to }); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) return lenDiff; + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) return -fromCmp; + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) return toCmp; + return b.id - a.id; + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) continue; + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; + if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || + fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) + return true; + } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line; + return line; + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + (lines || (lines = [])).push(line); + } + return lines; + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) return lineN; + return lineNo(vis); + } + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN; + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) return lineN; + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line; + return lineNo(line) + 1; + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.widgetNode) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + // LINE WIDGETS + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = CodeMirror.LineWidget = function (doc, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.doc = doc; + this.node = node; + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollPos(cm, null, diff); + } + + LineWidget.prototype.clear = function () { + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) line.widgets = null; + var height = widgetHeight(this); + updateLineHeight(line, Math.max(0, line.height - height)); + if (cm) runInOp(cm, function () { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + }); + }; + LineWidget.prototype.changed = function () { + var oldH = this.height, cm = this.doc.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + updateLineHeight(line, line.height + diff); + if (cm) runInOp(cm, function () { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + }); + }; + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + var cm = widget.doc.cm; + if (!cm) return 0; + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;"; + if (widget.coverGutter) + parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; + if (widget.noHScroll) + parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); + } + return widget.height = widget.node.parentNode.offsetHeight; + } + + function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options); + var cm = doc.cm; + if (cm && widget.noHScroll) cm.display.alignWidgets = true; + changeLine(doc, handle, "widget", function (line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, null, widget.height); + cm.curOp.forceUpdate = true; + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function (text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + Line.prototype.lineNo = function () { return lineNo(this); }; + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + function extractLineClasses(type, output) { + if (type) for (; ;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) break; + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (output[prop] == null) + output[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + output[prop] += " " + lineClass[2]; + } + return type; + } + + function callBlankLine(mode, state) { + if (mode.blankLine) return mode.blankLine(state); + if (!mode.innerMode) return; + var inner = CodeMirror.innerMode(mode, state); + if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); + } + + function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; + var style = mode.token(stream, state); + if (stream.pos > stream.start) return style; + } + throw new Error("Mode " + mode.name + " failed to advance stream."); + } + + // Utility for getTokenAt and getLineTokens + function takeToken(cm, pos, precise, asArray) { + function getObj(copy) { + return { + start: stream.start, end: stream.pos, + string: stream.current(), + type: style || null, + state: copy ? copyState(doc.mode, state) : state + }; + } + + var doc = cm.doc, mode = doc.mode, style; + pos = clipPos(doc, pos); + var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); + var stream = new StringStream(line.text, cm.options.tabSize), tokens; + if (asArray) tokens = []; + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos; + style = readToken(mode, stream, state); + if (asArray) tokens.push(getObj(true)); + } + return asArray ? tokens : getObj(); + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + var inner = cm.options.addModeClass && [null]; + if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) processLine(cm, text, state, stream.pos); + stream.pos = text.length; + style = null; + } else { + style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); + } + if (inner) { + var mName = inner[0].name; + if (mName) style = "m-" + (style ? mName + " " + style : mName); + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 50000); + f(curStart, curStyle); + } + curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, state, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {}; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function (end, style) { + st.push(end, style); + }, lineClasses, forceToEnd); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function (end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i + 1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, "cm-overlay " + style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start + 1]; + st[start + 1] = (cur ? cur + " " : "") + "cm-overlay " + style; + } + } + }, lineClasses); + } + + return { styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null }; + } + + function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var state = getStateBefore(cm, lineNo(line)); + var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); + line.stateAfter = state; + line.styles = result.styles; + if (result.classes) line.styleClasses = result.classes; + else if (line.styleClasses) line.styleClasses = null; + if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; + } + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, state, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize); + stream.start = stream.pos = startAt || 0; + if (text == "") callBlankLine(mode, state); + while (!stream.eol()) { + readToken(mode, stream, state); + stream.start = stream.pos; + } + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) return null; + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")); + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = { + pre: elt("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + trailingSpace: false, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping") + }; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order; + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) + builder.addToken = buildTokenBadBidi(builder.addToken, order); + builder.map = []; + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); + if (line.styleClasses) { + if (line.styleClasses.bgClass) + builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); + if (line.styleClasses.textClass) + builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); + (lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + // See issue #2901 + if (webkit) { + var last = builder.content.lastChild + if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) + builder.content.className = "cm-tab-wrap-hack"; + } + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + if (builder.pre.className) + builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); + + return builder; + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + token.setAttribute("aria-label", token.title); + return token; + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) return; + var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text + var special = builder.cm.state.specialChars, mustWrap = false; + if (!special.test(text)) { + builder.col += text.length; + var content = document.createTextNode(displayText); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie && ie_version < 9) mustWrap = true; + builder.pos += text.length; + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + txt.setAttribute("role", "presentation"); + txt.setAttribute("cm-text", "\t"); + builder.col += tabWidth; + } else if (m[0] == "\r" || m[0] == "\n") { + var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); + txt.setAttribute("cm-text", m[0]); + builder.col += 1; + } else { + var txt = builder.cm.options.specialCharPlaceholder(m[0]); + txt.setAttribute("cm-text", m[0]); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt); + builder.pos++; + } + } + builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 + if (style || startStyle || endStyle || mustWrap || css) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle, css); + if (title) token.title = title; + return builder.content.appendChild(token); + } + builder.content.appendChild(content); + } + + function splitSpaces(text, trailingBefore) { + if (text.length > 1 && !/ /.test(text)) return text + var spaceBefore = trailingBefore, result = "" + for (var i = 0; i < text.length; i++) { + var ch = text.charAt(i) + if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) + ch = "\u00a0" + result += ch + spaceBefore = ch == " " + } + return result + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function (builder, text, style, startStyle, endStyle, title, css) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (; ;) { + // Find the part that overlaps with the start of this text + for (var i = 0; i < order.length; i++) { + var part = order[i]; + if (part.to > start && part.from <= start) break; + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) builder.map.push(builder.pos, builder.pos + size, widget); + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + widget = builder.content.appendChild(document.createElement("span")); + widget.setAttribute("cm-marker", marker.id); + } + if (widget) { + builder.cm.display.input.setUneditable(widget); + builder.content.appendChild(widget); + } + builder.pos += size; + builder.trailingSpace = false + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i += 2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i + 1], builder.cm.options)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (; ;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = [], endStyles + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m); + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to; + spanEndStyle = ""; + } + if (m.className) spanStyle += " " + m.className; + if (m.css) css = (css ? css + ";" : "") + m.css; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to) + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + } + if (endStyles) for (var j = 0; j < endStyles.length; j += 2) + if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j] + + if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return; + if (collapsed.to == pos) collapsed = false; + } + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); + } + if (end >= upto) { text = text.slice(upto - pos); pos = upto; break; } + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder.cm.options); + } + } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore); + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) { return markedSpans ? markedSpans[n] : null; } + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + function linesFor(start, end) { + for (var i = start, result = []; i < end; ++i) + result.push(new Line(text[i], spansFor(i), estimateHeight)); + return result; + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)); + doc.remove(text.length, doc.size - text.length); + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + var added = linesFor(1, text.length - 1); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + var added = linesFor(1, text.length - 1); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, height = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function () { return this.lines.length; }, + // Remove the n lines at offset 'at'. + removeInner: function (at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + // Helper used to collapse a small branch into a single leaf. + collapse: function (lines) { + lines.push.apply(lines, this.lines); + }, + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function (at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) lines[i].parent = this; + }, + // Used to iterate over a part of the tree. + iterN: function (at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function () { return this.size; }, + removeInner: function (at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function (lines) { + for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); + }, + insertInner: function (at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. + // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. + var remaining = child.lines.length % 25 + 25 + for (var pos = remaining; pos < child.lines.length;) { + var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)); + child.height -= leaf.height; + this.children.splice(++i, 0, leaf); + leaf.parent = this; + } + child.lines = child.lines.slice(0, remaining); + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + // When a node has grown, check whether it should be split. + maybeSpill: function () { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function (at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function (text, mode, firstLine, lineSep) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + this.lineSep = lineSep; + this.extend = false; + + if (typeof text == "string") text = this.splitLines(text); + updateDoc(this, { from: start, to: start, text: text }); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function (from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + // Non-public interface for adding and removing lines. + insert: function (at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function (at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function (lineSep) { + var lines = getLines(this, this.first, this.first + this.size); + if (lineSep === false) return lines; + return lines.join(lineSep || this.lineSeparator()); + }, + setValue: docMethodOp(function (code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, { + from: top, to: Pos(last, getLine(this, last).text.length), + text: this.splitLines(code), origin: "setValue", full: true + }, true); + setSelection(this, simpleSelection(top)); + }), + replaceRange: function (code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function (from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || this.lineSeparator()); + }, + + getLine: function (line) { var l = this.getLineHandle(line); return l && l.text; }, + + getLineHandle: function (line) { if (isLine(this, line)) return getLine(this, line); }, + getLineNumber: function (line) { return lineNo(line); }, + + getLineHandleVisualStart: function (line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(line); + }, + + lineCount: function () { return this.size; }, + firstLine: function () { return this.first; }, + lastLine: function () { return this.first + this.size - 1; }, + + clipPos: function (pos) { return clipPos(this, pos); }, + + getCursor: function (start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") pos = range.head; + else if (start == "anchor") pos = range.anchor; + else if (start == "end" || start == "to" || start === false) pos = range.to(); + else pos = range.from(); + return pos; + }, + listSelections: function () { return this.sel.ranges; }, + somethingSelected: function () { return this.sel.somethingSelected(); }, + + setCursor: docMethodOp(function (line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function (anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function (head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function (heads, options) { + extendSelections(this, clipPosArray(this, heads), options); + }), + extendSelectionsBy: docMethodOp(function (f, options) { + var heads = map(this.sel.ranges, f); + extendSelections(this, clipPosArray(this, heads), options); + }), + setSelections: docMethodOp(function (ranges, primary, options) { + if (!ranges.length) return; + for (var i = 0, out = []; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); + setSelection(this, normalizeSelection(out, primary), options); + }), + addSelection: docMethodOp(function (anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); + }), + + getSelection: function (lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) return lines; + else return lines.join(lineSep || this.lineSeparator()); + }, + getSelections: function (lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()); + parts[i] = sel; + } + return parts; + }, + replaceSelection: function (code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + dup[i] = code; + this.replaceSelections(dup, collapse, origin || "+input"); + }, + replaceSelections: docMethodOp(function (code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = { from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin }; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]); + if (newSel) setSelectionReplaceHistory(this, newSel); + else if (this.cm) ensureCursorVisible(this.cm); + }), + undo: docMethodOp(function () { makeChangeFromHistory(this, "undo"); }), + redo: docMethodOp(function () { makeChangeFromHistory(this, "redo"); }), + undoSelection: docMethodOp(function () { makeChangeFromHistory(this, "undo", true); }), + redoSelection: docMethodOp(function () { makeChangeFromHistory(this, "redo", true); }), + + setExtending: function (val) { this.extend = val; }, + getExtending: function () { return this.extend; }, + + historySize: function () { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; + for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; + return { undo: done, redo: undone }; + }, + clearHistory: function () { this.history = new History(this.history.maxGeneration); }, + + markClean: function () { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function (forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function () { + return { + done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone) + }; + }, + setHistory: function (histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + addLineClass: docMethodOp(function (handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (classTest(cls).test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + removeLineClass: docMethodOp(function (handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(classTest(cls)); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: docMethodOp(function (handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + removeLineWidget: function (widget) { widget.clear(); }, + + markText: function (from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range"); + }, + setBookmark: function (pos, options) { + var realOpts = { + replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents + }; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function (pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + findMarks: function (from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function (line) { + var spans = line.markedSpans; + if (spans) for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(span.to != null && lineNo == from.line && from.ch >= span.to || + span.from == null && lineNo != from.line || + span.from != null && lineNo == to.line && span.from >= to.ch) && + (!filter || filter(span.marker))) + found.push(span.marker.parent || span.marker); + } + ++lineNo; + }); + return found; + }, + getAllMarks: function () { + var markers = []; + this.iter(function (line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function (off) { + var ch, lineNo = this.first, sepSize = this.lineSeparator().length; + this.iter(function (line) { + var sz = line.text.length + sepSize; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + var sepSize = this.lineSeparator().length; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + sepSize; + }); + return index; + }, + + copy: function (copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), + this.modeOption, this.first, this.lineSep); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function (options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({ doc: copy, sharedHist: options.sharedHist }); + copy.linked = [{ doc: this, isParent: true, sharedHist: options.sharedHist }]; + copySharedMarkers(copy, findSharedMarkers(this)); + return copy; + }, + unlinkDoc: function (other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + detachSharedMarkers(findSharedMarkers(this)); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function (doc) { splitIds.push(doc.id); }, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function (f) { linkedDocs(this, f); }, + + getMode: function () { return this.mode; }, + getEditor: function () { return this.cm; }, + + splitLines: function (str) { + if (this.lineSep) return str.split(this.lineSep); + return splitLinesAuto(str); + }, + lineSeparator: function () { return this.lineSep || "\n"; } + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function (method) { + return function () { return method.apply(this.doc, arguments); }; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) findMaxLine(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); + for (var chunk = doc; !chunk.lines;) { + for (var i = 0; ; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function (line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to) { + var out = []; + doc.iter(from, to, function (line) { out.push(line.text); }); + return out; + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) for (var n = line; n; n = n.parent) n.height += diff; + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0; ; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0; i < chunk.children.length; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = this.lastSelOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = { from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to) }; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function (doc) { attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true); + return histChange; + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) array.pop(); + else break; + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done); + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done); + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done); + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, ore are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done); + cur = { + changes: [historyChangeFromChange(doc, change)], + generation: hist.generation + }; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) hist.done.shift(); + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = hist.lastSelOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) signal(doc, "historyAdded"); + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel; + else + pushSelectionToHistory(sel, hist.done); + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastSelOp = opId; + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone); + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel); + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue; + } + var changes = event.changes, newChanges = []; + copy.push({ changes: newChanges }); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({ from: change.from, to: change.to, text: change.text }); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue; + } + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT UTILITIES + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + var e_preventDefault = CodeMirror.e_preventDefault = function (e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + }; + var e_stopPropagation = CodeMirror.e_stopPropagation = function (e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + }; + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + var e_stop = CodeMirror.e_stop = function (e) { e_preventDefault(e); e_stopPropagation(e); }; + + function e_target(e) { return e.target || e.srcElement; } + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var on = CodeMirror.on = function (emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + }; + + var noHandlers = [] + function getHandlers(emitter, type, copy) { + var arr = emitter._handlers && emitter._handlers[type] + if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers + else return arr || noHandlers + } + + var off = CodeMirror.off = function (emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var handlers = getHandlers(emitter, type, false) + for (var i = 0; i < handlers.length; ++i) + if (handlers[i] == f) { handlers.splice(i, 1); break; } + } + }; + + var signal = CodeMirror.signal = function (emitter, type /*, values...*/) { + var handlers = getHandlers(emitter, type, true) + if (!handlers.length) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args); + }; + + var orphanDelayedCallbacks = null; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + function signalLater(emitter, type /*, values...*/) { + var arr = getHandlers(emitter, type, false) + if (!arr.length) return; + var args = Array.prototype.slice.call(arguments, 2), list; + if (operationGroup) { + list = operationGroup.delayedCallbacks; + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks; + } else { + list = orphanDelayedCallbacks = []; + setTimeout(fireOrphanDelayed, 0); + } + function bnd(f) { return function () { f.apply(null, args); }; }; + for (var i = 0; i < arr.length; ++i) + list.push(bnd(arr[i])); + } + + function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks; + orphanDelayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + e = { type: e, preventDefault: function () { this.defaultPrevented = true; } }; + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity; + if (!arr) return; + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); + for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) + set.push(arr[i]); + } + + function hasHandler(emitter, type) { + return getHandlers(emitter, type).length > 0 + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function (type, f) { on(this, type, f); }; + ctor.prototype.off = function (type, f) { off(this, type, f); }; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerGap = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = { toString: function () { return "CodeMirror.Pass"; } }; + + // Reused option objects for setSelection & friends + var sel_dontScroll = { scroll: false }, sel_mouse = { origin: "*mouse" }, sel_move = { origin: "+move" }; + + function Delayed() { this.id = null; } + Delayed.prototype.set = function (ms, f) { + clearTimeout(this.id); + this.id = setTimeout(f, ms); + }; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + var countColumn = CodeMirror.countColumn = function (string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0; ;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + }; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + var findColumn = CodeMirror.findColumn = function (string, goal, tabSize) { + for (var pos = 0, col = 0; ;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) nextTab = string.length; + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col); + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) return pos; + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length - 1]; } + + var selectInput = function (node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function (node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; + else if (ie) // Suppress mysterious IE10 errors + selectInput = function (node) { try { node.select(); } catch (_e) { } }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + if (array[i] == elt) return i; + return -1; + } + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); + return out; + } + + function nothing() { } + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) copyObj(props, inst); + return inst; + }; + + function copyObj(obj, target, overwrite) { + if (!target) target = {}; + for (var prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop]; + return target; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { return f.apply(null, args); }; + } + + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var isWordCharBasic = CodeMirror.isWordChar = function (ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + }; + function isWordChar(ch, helper) { + if (!helper) return isWordCharBasic(ch); + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; + return helper.test(ch); + } + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + var range; + if (document.createRange) range = function (node, start, end, endNode) { + var r = document.createRange(); + r.setEnd(endNode || node, end); + r.setStart(node, start); + return r; + }; + else range = function (node, start, end) { + var r = document.body.createTextRange(); + try { r.moveToElementText(node.parentNode); } + catch (e) { return r; } + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r; + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + var contains = CodeMirror.contains = function (parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + child = child.parentNode; + if (parent.contains) + return parent.contains(child); + do { + if (child.nodeType == 11) child = child.host; + if (child == parent) return true; + } while (child = child.parentNode); + }; + + function activeElt() { + var activeElement = document.activeElement; + while (activeElement && activeElement.root && activeElement.root.activeElement) + activeElement = activeElement.root.activeElement; + return activeElement; + } + // Older versions of IE throws unspecified error when touching + // document.activeElement in some cases (during loading, in iframe) + if (ie && ie_version < 11) activeElt = function () { + try { return document.activeElement; } + catch (e) { return document.body; } + }; + + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } + var rmClass = CodeMirror.rmClass = function (node, cls) { + var current = node.className; + var match = classTest(cls).exec(current); + if (match) { + var after = current.slice(match.index + match[0].length); + node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); + } + }; + var addClass = CodeMirror.addClass = function (node, cls) { + var current = node.className; + if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; + }; + function joinClasses(a, b) { + var as = a.split(" "); + for (var i = 0; i < as.length; i++) + if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; + return b; + } + + // WINDOW-WIDE EVENTS + + // These must be handled carefully, because naively registering a + // handler for each editor will cause the editors to never be + // garbage collected. + + function forEachCodeMirror(f) { + if (!document.body.getElementsByClassName) return; + var byClass = document.body.getElementsByClassName("CodeMirror"); + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror; + if (cm) f(cm); + } + } + + var globalsRegistered = false; + function ensureGlobalHandlers() { + if (globalsRegistered) return; + registerGlobalHandlers(); + globalsRegistered = true; + } + function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer; + on(window, "resize", function () { + if (resizeTimer == null) resizeTimer = setTimeout(function () { + resizeTimer = null; + forEachCodeMirror(onResize); + }, 100); + }); + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function () { + forEachCodeMirror(onBlur); + }); + } + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function () { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + node.setAttribute("cm-text", ""); + return node; + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects; + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + var r1 = range(txt, 1, 2).getBoundingClientRect(); + removeChildren(measure); + if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) + return badBidiRects = (r1.right - r0.right < 3); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function (string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function (string) { return string.split(/\r\n?|\n/); }; + + var hasSelection = window.getSelection ? function (te) { + try { return te.selectionStart != te.selectionEnd; } + catch (e) { return false; } + } : function (te) { + try { var range = te.ownerDocument.selection.createRange(); } + catch (e) { } + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function () { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function"; + })(); + + var badZoomedRects = null; + function hasBadZoomedRects(measure) { + if (badZoomedRects != null) return badZoomedRects; + var node = removeChildrenAndAdd(measure, elt("span", "x")); + var normal = node.getBoundingClientRect(); + var fromRange = range(node, 0, 1).getBoundingClientRect(); + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; + } + + // KEY NAMES + + var keyNames = CodeMirror.keyNames = { + 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" + }; + (function () { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line = getLine(cm.doc, lineN); + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + lineN = null; + } + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN == null ? lineNo(line) : lineN, ch); + } + function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line); + var line = getLine(cm.doc, start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; + return Pos(start.line, inWS ? 0 : firstNonWS); + } + return start; + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + bidiOther = null; + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) return i; + if ((cur.from == pos || cur.to == pos)) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + if (cur.from != cur.to) bidiOther = found; + return i; + } else { + if (cur.from != cur.to) bidiOther = i; + return found; + } + } + } + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar(line.text.charAt(pos))); + return pos; + } + + // This is needed in order to move 'visually' through bi-directional + // text -- i.e., pressing left should make the cursor go left, even + // when in RTL text. The tricky part is the 'jumps', where RTL and + // LTR text touch each other. This often requires the cursor offset + // to move more than one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (; ;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function () { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); + else if (0x6ee <= code && code <= 0x8ac) return "r"; + else if (0x2000 <= code && code <= 0x200b) return "w"; + else if (code == 0x200c) return "b"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function (str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i + 1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i + 1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) { } + var replace = (i && types[i - 1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) { } + var before = (i ? types[i - 1] : outerType) == "L"; + var after = (end < len ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) { } + order.push(new BidiSpan(0, start, i)); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) { } + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) { } + order.splice(at, 0, new BidiSpan(2, nstart, j)); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + if (order[0].level == 2) + order.unshift(new BidiSpan(1, order[0].to, order[0].to)); + if (order[0].level != lst(order).level) + order.push(new BidiSpan(order[0].level, len, len)); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "5.17.0"; + + return CodeMirror; +})(); + +// @ts-ignore +window.CodeMirror = CodeMirror; + +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// TODO actually recognize syntax of TypeScript constructs + +(function () { + "use strict"; + + function expressionAllowed(stream, state, backUp) { + return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) || + (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) + } + + CodeMirror.defineMode("javascript", function (config, parserConfig) { + var indentUnit = config.indentUnit; + var statementIndent = parserConfig.statementIndent; + var jsonldMode = parserConfig.jsonld; + var jsonMode = parserConfig.json || jsonldMode; + var isTS = parserConfig.typescript; + var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; + + // Tokenizer + + var keywords = function () { + function kw(type) { return { type: type, style: "keyword" }; } + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = { type: "atom", style: "atom" }; + + var jsKeywords = { + "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, + "var": kw("var"), "const": kw("var"), "let": kw("var"), + "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, + "this": kw("this"), "class": kw("class"), "super": kw("atom"), + "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, + "await": C, "async": kw("async") + }; + + // Extend the 'normal' keywords with the TypeScript language extensions + if (isTS) { + var type = { type: "variable", style: "variable-3" }; + var tsKeywords = { + // object-like things + "interface": kw("class"), + "implements": C, + "namespace": C, + "module": kw("module"), + "enum": kw("module"), + + // scope modifiers + "public": kw("modifier"), + "private": kw("modifier"), + "protected": kw("modifier"), + "abstract": kw("modifier"), + + // operators + "as": operator, + + // types + "string": type, "number": type, "boolean": type, "any": type + }; + + for (var attr in tsKeywords) { + jsKeywords[attr] = tsKeywords[attr]; + } + } + + return jsKeywords; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|~^]/; + var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; + + function readRegexp(stream) { + var escaped = false, next, inSet = false; + while ((next = stream.next()) != null) { + if (!escaped) { + if (next == "/" && !inSet) return; + if (next == "[") inSet = true; + else if (inSet && next == "]") inSet = false; + } + escaped = !escaped && next == "\\"; + } + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { + return ret("number", "number"); + } else if (ch == "." && stream.match("..")) { + return ret("spread", "meta"); + } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return ret(ch); + } else if (ch == "=" && stream.eat(">")) { + return ret("=>", "operator"); + } else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/o/i)) { + stream.eatWhile(/[0-7]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/b/i)) { + stream.eatWhile(/[01]/i); + return ret("number", "number"); + } else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } else if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } else if (expressionAllowed(stream, state, 1)) { + readRegexp(stream); + stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); + return ret("regexp", "string-2"); + } else { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } + } else if (ch == "`") { + state.tokenize = tokenQuasi; + return tokenQuasi(stream, state); + } else if (ch == "#") { + stream.skipToEnd(); + return ret("error", "error"); + } else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } else if (wordRE.test(ch)) { + stream.eatWhile(wordRE); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return (known && state.lastType != ".") ? ret(known.type, known.style, word) : + ret("variable", "variable", word); + } + } + + function tokenString(quote) { + return function (stream, state) { + var escaped = false, next; + if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)) { + state.tokenize = tokenBase; + return ret("jsonld-keyword", "meta"); + } + while ((next = stream.next()) != null) { + if (next == quote && !escaped) break; + escaped = !escaped && next == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("string", "string"); + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + function tokenQuasi(stream, state) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && next == "\\"; + } + return ret("quasi", "string-2", stream.current()); + } + + var brackets = "([{}])"; + // This is a crude lookahead trick to try and notice that we're + // parsing the argument patterns for a fat-arrow function before we + // actually hit the arrow token. It only works if the arrow is on + // the same line as the arguments and there's no strange noise + // (comments) in between. Fallback is to only notice when we hit the + // arrow, and not declare the arguments as locals for the arrow + // body. + function findFatArrow(stream, state) { + if (state.fatArrowAt) state.fatArrowAt = null; + var arrow = stream.string.indexOf("=>", stream.start); + if (arrow < 0) return; + + var depth = 0, sawSomething = false; + for (var pos = arrow - 1; pos >= 0; --pos) { + var ch = stream.string.charAt(pos); + var bracket = brackets.indexOf(ch); + if (bracket >= 0 && bracket < 3) { + if (!depth) { ++pos; break; } + if (--depth == 0) break; + } else if (bracket >= 3 && bracket < 6) { + ++depth; + } else if (wordRE.test(ch)) { + sawSomething = true; + } else if (/["'\/]/.test(ch)) { + return; + } else if (sawSomething && !depth) { + ++pos; + break; + } + } + if (sawSomething && !depth) state.fatArrowAt = pos; + } + + // Parser + + var atomicTypes = { "atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true }; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + for (var cx = state.context; cx; cx = cx.prev) { + for (var v = cx.vars; v; v = v.next) + if (v.name == varname) return true; + } + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while (true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while (cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + return style; + } + } + } + + // Combinator utils + + var cx = { state: null, column: null, marked: null, cc: null }; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + function inList(list) { + for (var v = list; v; v = v.next) + if (v.name == varname) return true; + return false; + } + var state = cx.state; + cx.marked = "def"; + if (state.context) { + if (inList(state.localVars)) return; + state.localVars = { name: varname, next: state.localVars }; + } else { + if (inList(state.globalVars)) return; + if (parserConfig.globalVars) + state.globalVars = { name: varname, next: state.globalVars }; + } + } + + // Combinators + + var defaultVars = { name: "this", next: { name: "arguments" } }; + function pushcontext() { + cx.state.context = { prev: cx.state.context, vars: cx.state.localVars }; + cx.state.localVars = defaultVars; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function () { + var state = cx.state, indent = state.indented; + if (state.lexical.type == "stat") indent = state.lexical.indented; + else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) + indent = outer.indented; + state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + function exp(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(exp); + }; + return exp; + } + + function statement(type, value) { + if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "if") { + if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) + cx.state.cc.pop()(); + return cont(pushlex("form"), expression, statement, poplex, maybeelse); + } + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + if (type == "class") return cont(pushlex("form"), className, poplex); + if (type == "export") return cont(pushlex("stat"), afterExport, poplex); + if (type == "import") return cont(pushlex("stat"), afterImport, poplex); + if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) + if (type == "async") return cont(statement) + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + return expressionInner(type, false); + } + function expressionNoComma(type) { + return expressionInner(type, true); + } + function expressionInner(type, noComma) { + if (cx.state.fatArrowAt == cx.stream.start) { + var body = noComma ? arrowBodyNoComma : arrowBody; + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); + else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); + } + + var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; + if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); + if (type == "function") return cont(functiondef, maybeop); + if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression); + if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); + if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); + if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); + if (type == "{") return contCommasep(objprop, "}", null, maybeop); + if (type == "quasi") return pass(quasi, maybeop); + if (type == "new") return cont(maybeTarget(noComma)); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + function maybeexpressionNoComma(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expressionNoComma); + } + + function maybeoperatorComma(type, value) { + if (type == ",") return cont(expression); + return maybeoperatorNoComma(type, value, false); + } + function maybeoperatorNoComma(type, value, noComma) { + var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; + var expr = noComma == false ? expression : expressionNoComma; + if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); + if (type == "operator") { + if (/\+\+|--/.test(value)) return cont(me); + if (value == "?") return cont(expression, expect(":"), expr); + return cont(expr); + } + if (type == "quasi") { return pass(quasi, me); } + if (type == ";") return; + if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); + if (type == ".") return cont(property, me); + if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); + } + function quasi(type, value) { + if (type != "quasi") return pass(); + if (value.slice(value.length - 2) != "${") return cont(quasi); + return cont(expression, continueQuasi); + } + function continueQuasi(type) { + if (type == "}") { + cx.marked = "string-2"; + cx.state.tokenize = tokenQuasi; + return cont(quasi); + } + } + function arrowBody(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expression); + } + function arrowBodyNoComma(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expressionNoComma); + } + function maybeTarget(noComma) { + return function (type) { + if (type == ".") return cont(noComma ? targetNoComma : target); + else return pass(noComma ? expressionNoComma : expression); + }; + } + function target(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } + } + function targetNoComma(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperatorComma, expect(";"), poplex); + } + function property(type) { + if (type == "variable") { cx.marked = "property"; return cont(); } + } + function objprop(type, value) { + if (type == "async") return cont(objprop); + if (type == "variable" || cx.style == "keyword") { + cx.marked = "property"; + if (value == "get" || value == "set") return cont(getterSetter); + return cont(afterprop); + } else if (type == "number" || type == "string") { + cx.marked = jsonldMode ? "property" : (cx.style + " property"); + return cont(afterprop); + } else if (type == "jsonld-keyword") { + return cont(afterprop); + } else if (type == "modifier") { + return cont(objprop) + } else if (type == "[") { + return cont(expression, expect("]"), afterprop); + } else if (type == "spread") { + return cont(expression); + } + } + function getterSetter(type) { + if (type != "variable") return pass(afterprop); + cx.marked = "property"; + return cont(functiondef); + } + function afterprop(type) { + if (type == ":") return cont(expressionNoComma); + if (type == "(") return pass(functiondef); + } + function commasep(what, end) { + function proceed(type, value) { + if (type == ",") { + var lex = cx.state.lexical; + if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; + return cont(function (type, value) { + if (type == end || value == end) return pass() + return pass(what) + }, proceed); + } + if (type == end || value == end) return cont(); + return cont(expect(end)); + } + return function (type, value) { + if (type == end || value == end) return cont(); + return pass(what, proceed); + }; + } + function contCommasep(what, end, info) { + for (var i = 3; i < arguments.length; i++) + cx.cc.push(arguments[i]); + return cont(pushlex(end, info), commasep(what, end), poplex); + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function maybetype(type) { + if (isTS && type == ":") return cont(typeexpr); + } + function maybedefault(_, value) { + if (value == "=") return cont(expressionNoComma); + } + function typeexpr(type) { + if (type == "variable") { cx.marked = "variable-3"; return cont(afterType); } + } + function afterType(type, value) { + if (value == "<") return cont(commasep(typeexpr, ">"), afterType) + if (type == "[") return cont(expect("]"), afterType) + } + function vardef() { + return pass(pattern, maybetype, maybeAssign, vardefCont); + } + function pattern(type, value) { + if (type == "modifier") return cont(pattern) + if (type == "variable") { register(value); return cont(); } + if (type == "spread") return cont(pattern); + if (type == "[") return contCommasep(pattern, "]"); + if (type == "{") return contCommasep(proppattern, "}"); + } + function proppattern(type, value) { + if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { + register(value); + return cont(maybeAssign); + } + if (type == "variable") cx.marked = "property"; + if (type == "spread") return cont(pattern); + if (type == "}") return pass(); + return cont(expect(":"), pattern, maybeAssign); + } + function maybeAssign(_type, value) { + if (value == "=") return cont(expressionNoComma); + } + function vardefCont(type) { + if (type == ",") return cont(vardef); + } + function maybeelse(type, value) { + if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); + } + function forspec(type) { + if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); + } + function forspec1(type) { + if (type == "var") return cont(vardef, expect(";"), forspec2); + if (type == ";") return cont(forspec2); + if (type == "variable") return cont(formaybeinof); + return pass(expression, expect(";"), forspec2); + } + function formaybeinof(_type, value) { + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return cont(maybeoperatorComma, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return pass(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (value == "*") { cx.marked = "keyword"; return cont(functiondef); } + if (type == "variable") { register(value); return cont(functiondef); } + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); + } + function funarg(type) { + if (type == "spread") return cont(funarg); + return pass(pattern, maybetype, maybedefault); + } + function className(type, value) { + if (type == "variable") { register(value); return cont(classNameAfter); } + } + function classNameAfter(type, value) { + if (value == "extends") return cont(expression, classNameAfter); + if (type == "{") return cont(pushlex("}"), classBody, poplex); + } + function classBody(type, value) { + if (type == "variable" || cx.style == "keyword") { + if (value == "static") { + cx.marked = "keyword"; + return cont(classBody); + } + cx.marked = "property"; + if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); + return cont(functiondef, classBody); + } + if (value == "*") { + cx.marked = "keyword"; + return cont(classBody); + } + if (type == ";") return cont(classBody); + if (type == "}") return cont(); + } + function classGetterSetter(type) { + if (type != "variable") return pass(); + cx.marked = "property"; + return cont(); + } + function afterExport(_type, value) { + if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } + if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } + return pass(statement); + } + function afterImport(type) { + if (type == "string") return cont(); + return pass(importSpec, maybeFrom); + } + function importSpec(type, value) { + if (type == "{") return contCommasep(importSpec, "}"); + if (type == "variable") register(value); + if (value == "*") cx.marked = "keyword"; + return cont(maybeAs); + } + function maybeAs(_type, value) { + if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } + } + function maybeFrom(_type, value) { + if (value == "from") { cx.marked = "keyword"; return cont(expression); } + } + function arrayLiteral(type) { + if (type == "]") return cont(); + return pass(expressionNoComma, commasep(expressionNoComma, "]")); + } + + function isContinuedStatement(state, textAfter) { + return state.lastType == "operator" || state.lastType == "," || + isOperatorChar.test(textAfter.charAt(0)) || + /[,.]/.test(textAfter.charAt(0)); + } + + // Interface + + return { + startState: function (basecolumn) { + var state = { + tokenize: tokenBase, + lastType: "sof", + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + context: parserConfig.localVars && { vars: parserConfig.localVars }, + indented: basecolumn || 0 + }; + if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") + state.globalVars = parserConfig.globalVars; + return state; + }, + + token: function (stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + findFatArrow(stream, state); + } + if (state.tokenize != tokenComment && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; + return parseJS(state, style, type, content, stream); + }, + + indent: function (state, textAfter) { + if (state.tokenize == tokenComment) return CodeMirror.Pass; + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; + // Kludge to prevent 'maybelse' from blocking lexical scope pops + if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { + var c = state.cc[i]; + if (c == poplex) lexical = lexical.prev; + else if (c != maybeelse) break; + } + if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; + if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") + lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "form") return lexical.indented + indentUnit; + else if (type == "stat") + return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); + else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, + blockCommentStart: jsonMode ? null : "/*", + blockCommentEnd: jsonMode ? null : "*/", + lineComment: jsonMode ? null : "//", + fold: "brace", + closeBrackets: "()[]{}''\"\"``", + + helperType: jsonMode ? "json" : "javascript", + jsonldMode: jsonldMode, + jsonMode: jsonMode, + + expressionAllowed: expressionAllowed, + skipExpression: function (state) { + var top = state.cc[state.cc.length - 1] + if (top == expression || top == expressionNoComma) state.cc.pop() + } + }; + }); + + CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); + + CodeMirror.defineMIME("text/javascript", "javascript"); + CodeMirror.defineMIME("text/ecmascript", "javascript"); + CodeMirror.defineMIME("application/javascript", "javascript"); + CodeMirror.defineMIME("application/x-javascript", "javascript"); + CodeMirror.defineMIME("application/ecmascript", "javascript"); + CodeMirror.defineMIME("application/json", { name: "javascript", json: true }); + CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true }); + CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true }); + CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); + CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); + +})(); + +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function () { + var defaults = { + pairs: "()[]{}''\"\"", + triples: "", + explode: "[]{}" + }; + + var Pos = CodeMirror.Pos; + + CodeMirror.defineOption("autoCloseBrackets", false, function (cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.removeKeyMap(keyMap); + cm.state.closeBrackets = null; + } + if (val) { + cm.state.closeBrackets = val; + cm.addKeyMap(keyMap); + } + }); + + function getOption(conf, name) { + if (name == "pairs" && typeof conf == "string") return conf; + if (typeof conf == "object" && conf[name] != null) return conf[name]; + return defaults[name]; + } + + var bind = defaults.pairs + "`"; + var keyMap = { Backspace: handleBackspace, Enter: handleEnter }; + for (var i = 0; i < bind.length; i++) + keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); + + function handler(ch) { + return function (cm) { return handleChar(cm, ch); }; + } + + function getConfig(cm) { + var deflt = cm.state.closeBrackets; + if (!deflt) return null; + var mode = cm.getModeAt(cm.getCursor()); + return mode.closeBrackets || deflt; + } + + function handleBackspace(cm) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); + } + } + + function handleEnter(cm) { + var conf = getConfig(cm); + var explode = conf && getOption(conf, "explode"); + if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function () { + cm.replaceSelection("\n\n", null); + cm.execCommand("goCharLeft"); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + } + + function contractSelection(sel) { + var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; + return { + anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), + head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1)) + }; + } + + function handleChar(cm, ch) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var pos = pairs.indexOf(ch); + if (pos == -1) return CodeMirror.Pass; + var triples = getOption(conf, "triples"); + + var identical = pairs.charAt(pos + 1) == ch; + var ranges = cm.listSelections(); + var opening = pos % 2 == 0; + + var type; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (opening && !range.empty()) { + curType = "surround"; + } else if ((identical || !opening) && next == ch) { + if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) + curType = "skipThree"; + else + curType = "skip"; + } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && + (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { + curType = "addFour"; + } else if (identical) { + if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; + else return CodeMirror.Pass; + } else if (opening && (cm.getLine(cur.line).length == cur.ch || + isClosingBracket(next, pairs) || + /\s/.test(next))) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + var left = pos % 2 ? pairs.charAt(pos - 1) : ch; + var right = pos % 2 ? ch : pairs.charAt(pos + 1); + cm.operation(function () { + if (type == "skip") { + cm.execCommand("goCharRight"); + } else if (type == "skipThree") { + for (var i = 0; i < 3; i++) + cm.execCommand("goCharRight"); + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + sels = cm.listSelections().slice(); + for (var i = 0; i < sels.length; i++) + sels[i] = contractSelection(sels[i]); + cm.setSelections(sels); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.triggerElectric(left + right); + cm.execCommand("goCharLeft"); + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + cm.execCommand("goCharRight"); + } + }); + } + + function isClosingBracket(ch, pairs) { + var pos = pairs.lastIndexOf(ch); + return pos > -1 && pos % 2 == 1; + } + + function charsAround(cm, pos) { + var str = cm.getRange(Pos(pos.line, pos.ch - 1), + Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + // Project the token type that will exists after the given char is + // typed, and use it to determine whether it would cause the start + // of a string token. + function enteringString(cm, pos, ch) { + var line = cm.getLine(pos.line); + var token = cm.getTokenAt(pos); + if (/\bstring2?\b/.test(token.type)) return false; + var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); + stream.pos = stream.start = token.start; + for (; ;) { + var type1 = cm.getMode().token(stream, token.state); + if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); + stream.start = stream.pos; + } + } +})(); + +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +// declare global: DOMRect + +(function () { + "use strict"; + + var HINT_ELEMENT_CLASS = "CodeMirror-hint"; + var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; + + // This is the old interface, kept around for now to stay + // backwards-compatible. + CodeMirror.showHint = function (cm, getHints, options) { + if (!getHints) return cm.showHint(options); + if (options && options.async) getHints.async = true; + var newOpts = { hint: getHints }; + if (options) for (var prop in options) newOpts[prop] = options[prop]; + return cm.showHint(newOpts); + }; + + CodeMirror.defineExtension("showHint", function (options) { + options = parseOptions(this, this.getCursor("start"), options); + var selections = this.listSelections() + if (selections.length > 1) return; + // By default, don't allow completion when something is selected. + // A hint function can have a `supportsSelection` property to + // indicate that it can handle selections. + if (this.somethingSelected()) { + if (!options.hint.supportsSelection) return; + // Don't try with cross-line selections + for (var i = 0; i < selections.length; i++) + if (selections[i].head.line != selections[i].anchor.line) return; + } + + if (this.state.completionActive) this.state.completionActive.close(); + var completion = this.state.completionActive = new Completion(this, options); + if (!completion.options.hint) return; + + CodeMirror.signal(this, "startCompletion", this); + completion.update(true); + }); + + CodeMirror.defineExtension("closeHint", function () { + if (this.state.completionActive) this.state.completionActive.close() + }) + + function Completion(cm, options) { + this.cm = cm; + this.options = options; + this.widget = null; + this.debounce = 0; + this.tick = 0; + this.startPos = this.cm.getCursor("start"); + this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; + + if (this.options.updateOnCursorActivity) { + var self = this; + cm.on("cursorActivity", this.activityFunc = function () { self.cursorActivity(); }); + } + } + + var requestAnimationFrame = window.requestAnimationFrame || function (fn) { + return setTimeout(fn, 1000 / 60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + + Completion.prototype = { + close: function () { + if (!this.active()) return; + this.cm.state.completionActive = null; + this.tick = null; + if (this.options.updateOnCursorActivity) { + this.cm.off("cursorActivity", this.activityFunc); + } + + if (this.widget && this.data) CodeMirror.signal(this.data, "close"); + if (this.widget) this.widget.close(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, + + active: function () { + return this.cm.state.completionActive == this; + }, + + pick: function (data, i) { + var completion = data.list[i], self = this; + this.cm.operation(function () { + if (completion.hint) + completion.hint(self.cm, data, completion); + else + self.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + CodeMirror.signal(data, "pick", completion); + self.cm.scrollIntoView(); + }); + if (this.options.closeOnPick) { + this.close(); + } + }, + + cursorActivity: function () { + if (this.debounce) { + cancelAnimationFrame(this.debounce); + this.debounce = 0; + } + + var identStart = this.startPos; + if (this.data) { + identStart = this.data.from; + } + + var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); + if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || + pos.ch < identStart.ch || this.cm.somethingSelected() || + (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { + this.close(); + } else { + var self = this; + this.debounce = requestAnimationFrame(function () { self.update(); }); + if (this.widget) this.widget.disable(); + } + }, + + update: function (first) { + if (this.tick == null) return + var self = this, myTick = ++this.tick + fetchHints(this.options.hint, this.cm, this.options, function (data) { + if (self.tick == myTick) self.finishUpdate(data, first) + }) + }, + + finishUpdate: function (data, first) { + if (this.data) CodeMirror.signal(this.data, "update"); + + var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); + if (this.widget) this.widget.close(); + + this.data = data; + + if (data && data.list.length) { + if (picked && data.list.length == 1) { + this.pick(data, 0); + } else { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + } + } + } + }; + + function parseOptions(cm, pos, options) { + var editor = cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) + return out; + } + + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } + + function buildKeyMap(completion, handle) { + var baseMap = { + Up: function () { handle.moveFocus(-1); }, + Down: function () { handle.moveFocus(1); }, + PageUp: function () { handle.moveFocus(-handle.menuSize() + 1, true); }, + PageDown: function () { handle.moveFocus(handle.menuSize() - 1, true); }, + Home: function () { handle.setFocus(0); }, + End: function () { handle.setFocus(handle.length - 1); }, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + + var mac = /Mac/.test(navigator.platform); + + if (mac) { + baseMap["Ctrl-P"] = function () { handle.moveFocus(-1); }; + baseMap["Ctrl-N"] = function () { handle.moveFocus(1); }; + } + + var custom = completion.options.customKeys; + var ourMap = custom ? {} : baseMap; + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function (cm) { return val(cm, handle); }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } + if (custom) + for (var key in custom) if (custom.hasOwnProperty(key)) + addBinding(key, custom[key]); + var extra = completion.options.extraKeys; + if (extra) + for (var key in extra) if (extra.hasOwnProperty(key)) + addBinding(key, extra[key]); + return ourMap; + } + + function getHintElement(hintsElement, el) { + while (el && el != hintsElement) { + if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; + el = el.parentNode; + } + } + + function Widget(completion, data) { + this.completion = completion; + this.data = data; + this.picked = false; + var widget = this, cm = completion.cm; + var ownerDocument = cm.getInputField().ownerDocument; + var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow; + var hints = this.hints = ownerDocument.createElement("ul"); + var theme = completion.cm.options.theme; + hints.className = "CodeMirror-hints " + theme; + this.selectedHint = data.selectedHint || 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i]; + var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + CodeMirror.on(elt, "mouseover", function (e) { + widget.changeActive(this.hintId); + }); + CodeMirror.on(elt, "touchstart", function (e) { + widget.changeActive(this.hintId); + }); + CodeMirror.on(elt, "touchend", function (e) { + var cur = cm.getCursor(); + var self = this; + setTimeout(function () { + cm.focus(); + var cur2 = cm.getCursor(); + if (cur2.line == cur.line && cur2.ch == 0) { + var textLen = self.innerText.length; + cm.setCursor({ line: cur.line, ch: cur.ch + textLen }); + } + }, 10); + }); + } + + var container = completion.options.container || ownerDocument.body; + var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + var offsetLeft = 0, offsetTop = 0; + if (container !== ownerDocument.body) { + // We offset the cursor position because left and top are relative to the offsetParent's top left corner. + var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1; + var offsetParent = isContainerPositioned ? container : container.offsetParent; + var offsetParentPosition = offsetParent.getBoundingClientRect(); + var bodyPosition = ownerDocument.body.getBoundingClientRect(); + offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft); + offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop); + } + var documentZoom = getDocumentZoom(); + hints.style.fontSize = 16 / documentZoom * 0.9 + "px"; + hints.style.left = (left - offsetLeft) / documentZoom + "px"; + hints.style.top = (top - offsetTop) / documentZoom + "px"; + + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. + var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); + var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); + container.appendChild(hints); + + var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect(); + var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false; + + // Compute in the timeout to avoid reflow on init + var startScroll; + setTimeout(function () { startScroll = cm.getScrollInfo(); }); + + var overlapY = box.bottom - winH; + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + hints.style.top = (top = pos.top - height - offsetTop) / documentZoom + "px"; + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) / documentZoom + "px"; + hints.style.top = (top = pos.bottom - box.top - offsetTop) / documentZoom + "px"; + var cursor = cm.getCursor(); + if (data.from.ch != cursor.ch) { + pos = cm.cursorCoords(cursor); + hints.style.left = (left = pos.left - offsetLeft) / documentZoom + "px"; + box = hints.getBoundingClientRect(); + } + } + } + var overlapX = box.right - winW; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) / documentZoom + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX - offsetLeft) / documentZoom + "px"; + } + if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling) + node.style.paddingRight = cm.display.nativeBarWidth / documentZoom + "px" + + cm.addKeyMap(this.keyMap = buildKeyMap(completion, { + moveFocus: function (n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, + setFocus: function (n) { widget.changeActive(n); }, + menuSize: function () { return widget.screenAmount(); }, + length: completions.length, + close: function () { completion.close(); }, + pick: function () { widget.pick(); }, + data: data + })); + + if (completion.options.closeOnUnfocus) { + var closingOnBlur; + cm.on("blur", this.onBlur = function () { closingOnBlur = setTimeout(function () { completion.close(); }, 100); }); + cm.on("focus", this.onFocus = function () { clearTimeout(closingOnBlur); }); + } + + cm.on("scroll", this.onScroll = function () { + // fix "startScroll == undfined" + if (!startScroll) return; + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop / documentZoom + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) / documentZoom + "px"; + }); + + CodeMirror.on(hints, "dblclick", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { widget.changeActive(t.hintId); widget.pick(); } + }); + + CodeMirror.on(hints, "click", function (e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + if (completion.options.completeOnSingleClick) widget.pick(); + } + }); + + CodeMirror.on(hints, "mousedown", function () { + setTimeout(function () { cm.focus(); }, 20); + }); + + //滑动修复 + CodeMirror.on(hints, "touchmove", function (event) { + if (ios && this.scrollHeight <= this.offsetHeight + 5 && this.scrollWidth <= this.offsetWidth + 5) { + event.preventDefault(); + } + else { + event.stopPropagation(); + } + }); + hints.style.WebkitOverflowScrolling = 'touch'; + + // The first hint doesn't need to be scrolled to on init + var selectedHintRange = this.getSelectedHintRange(); + if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) { + this.scrollToActive(); + } + + CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]); + return true; + } + + Widget.prototype = { + close: function () { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); + + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, + + disable: function () { + this.completion.cm.removeKeyMap(this.keyMap); + var widget = this; + this.keyMap = { Enter: function () { widget.picked = true; } }; + this.completion.cm.addKeyMap(this.keyMap); + }, + + pick: function () { + this.completion.pick(this.data, this.selectedHint); + }, + + changeActive: function (i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; + this.scrollToActive() + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, + + scrollToActive: function () { + var selectedHintRange = this.getSelectedHintRange(); + var node1 = this.hints.childNodes[selectedHintRange.from]; + var node2 = this.hints.childNodes[selectedHintRange.to]; + var firstNode = this.hints.firstChild; + if (node1.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop; + else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop; + }, + + screenAmount: function () { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + }, + + getSelectedHintRange: function () { + var margin = this.completion.options.scrollMargin || 0; + return { + from: Math.max(0, this.selectedHint - margin), + to: Math.min(this.data.list.length - 1, this.selectedHint + margin), + }; + } + }; + + function applicableHelpers(cm, helpers) { + if (!cm.somethingSelected()) return helpers + var result = [] + for (var i = 0; i < helpers.length; i++) + if (helpers[i].supportsSelection) result.push(helpers[i]) + return result + } + + function fetchHints(hint, cm, options, callback) { + if (hint.async) { + hint(cm, callback, options) + } else { + var result = hint(cm, options) + if (result && result.then) result.then(callback) + else callback(result) + } + } + + function resolveAutoHints(cm, pos) { + var helpers = cm.getHelpers(pos, "hint"), words + if (helpers.length) { + var resolved = function (cm, callback, options) { + var app = applicableHelpers(cm, helpers); + function run(i) { + if (i == app.length) return callback(null) + fetchHints(app[i], cm, options, function (result) { + if (result && result.list.length > 0) callback(result) + else run(i + 1) + }) + } + run(0) + } + resolved.async = true + resolved.supportsSelection = true + return resolved + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + return function (cm) { return CodeMirror.hint.fromList(cm, { words: words }) } + } else if (CodeMirror.hint.anyword) { + return function (cm, options) { return CodeMirror.hint.anyword(cm, options) } + } else { + return function () { } + } + } + + CodeMirror.registerHelper("hint", "auto", { + resolve: resolveAutoHints + }); + + CodeMirror.registerHelper("hint", "fromList", function (cm, options) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur) + var term, from = CodeMirror.Pos(cur.line, token.start), to = cur + if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) { + term = token.string.substr(0, cur.ch - token.start) + } else { + term = "" + from = cur + } + var found = []; + for (var i = 0; i < options.words.length; i++) { + var word = options.words[i]; + if (word.slice(0, term.length) == term) + found.push(word); + } + + if (found.length) return { list: found, from: from, to: to }; + }); + + CodeMirror.commands.autocomplete = CodeMirror.showHint; + + var defaultOptions = { + hint: CodeMirror.hint.auto, + completeSingle: true, + alignWithWord: true, + closeCharacters: /[\s()\[\]{};:>,]/, + closeOnPick: true, + closeOnUnfocus: true, + updateOnCursorActivity: true, + completeOnSingleClick: true, + container: null, + customKeys: null, + extraKeys: null, + paddingForScrollbar: true, + moveOnOverlap: true, + }; + + CodeMirror.defineOption("hintOptions", null); +})(); + +export default CodeMirror; diff --git a/game/config.js b/game/config.js index c343c0109..064b67daa 100644 --- a/game/config.js +++ b/game/config.js @@ -1,249 +1,410 @@ -window.config={ - extension_sources:{ - 'GitHub Proxy':'https://mirror.ghproxy.com/https://raw.githubusercontent.com/libccy/noname-extension/master/', - FastGit:'https://raw.fgit.cf/libccy/noname-extension/master/', - GitHub:'https://raw.githubusercontent.com/libccy/noname-extension/master/' +window.config = { + extension_sources: { + "GitHub Proxy": + "https://mirror.ghproxy.com/https://raw.githubusercontent.com/libccy/noname-extension/master/", + FastGit: "https://raw.fgit.cf/libccy/noname-extension/master/", + GitHub: "https://raw.githubusercontent.com/libccy/noname-extension/master/", }, - extension_source:'GitHub Proxy', - forbidai:['ns_liuzhang'], - forbidai_user:[], - forbidall:[], - forbidstone:['zhugedan','pal_xuanxiao','hs_malfurion','lusu','chenlin','hs_siwangzhiyi', - 'gjqt_bailitusu','yuanshao','swd_anka','swd_nicole','daqiao','re_daqiao','hs_xuanzhuanjijia', - 'zhuran','huatuo','swd_tuwei','hs_guldan','wangyi','caoang','swd_guyue','swd_rongshuang', - 'swd_jiangziya','guojia','re_guojia','shen_caocao','swd_qiner','caopi','hs_yngvar','guansuo', - 'gjqt_aruan','swd_hanluo','hs_anduin','swd_huanglei','yxs_yujix','yxs_luzhishen','swd_muyun','ow_tianshi', - 'pal_yuejinzhao','hs_antonidas','xushi','hs_lreno' + extension_source: "GitHub Proxy", + forbidai: ["ns_liuzhang"], + forbidai_user: [], + forbidall: [], + forbidstone: [ + "zhugedan", + "pal_xuanxiao", + "hs_malfurion", + "lusu", + "chenlin", + "hs_siwangzhiyi", + "gjqt_bailitusu", + "yuanshao", + "swd_anka", + "swd_nicole", + "daqiao", + "re_daqiao", + "hs_xuanzhuanjijia", + "zhuran", + "huatuo", + "swd_tuwei", + "hs_guldan", + "wangyi", + "caoang", + "swd_guyue", + "swd_rongshuang", + "swd_jiangziya", + "guojia", + "re_guojia", + "shen_caocao", + "swd_qiner", + "caopi", + "hs_yngvar", + "guansuo", + "gjqt_aruan", + "swd_hanluo", + "hs_anduin", + "swd_huanglei", + "yxs_yujix", + "yxs_luzhishen", + "swd_muyun", + "ow_tianshi", + "pal_yuejinzhao", + "hs_antonidas", + "xushi", + "hs_lreno", ], - forbidchess:['hetaihou','swd_kangnalishi'], - forbidboss:['caiwenji','gjqt_aruan','pal_xuanxiao','swd_hupo'], - forbiddouble:['zhugedan','swd_kangnalishi','dongzhuo','wutugu','hs_siwangzhiyi','hs_ronghejuren','hs_shanlingjuren'], - forbidthreecard:['qiankunbiao','shenhuofeiya','gw_ciguhanshuang','gw_birinongwu','gw_qinpendayu','gw_poxiao'], - zhinang_tricks:['guohe','wuxie','wuzhong','dongzhuxianji'], - connect_zhinang_tricks:['guohe','wuxie','wuzhong','dongzhuxianji'], - all:{ - sgscharacters:['standard','shenhua','xinghuoliaoyuan','refresh','yijiang','sp','sp2','xianding','huicui','extra','old','mobile','shiji','tw','yingbian','offline','jsrg','sb','clan','collab','onlyOL'], - sgscards:['standard','extra','sp','guozhan','zhulu','yingbian','yongjian'], - sgsmodes:['identity','guozhan','versus','doudizhu','single','brawl','connect'], - stockmode:['identity','guozhan','versus','boss','doudizhu','single','chess','stone','connect','brawl','tafang'], - stockextension:['boss','cardpile','coin','wuxing'], - layout:['default','newlayout'], - theme:['woodden','music','simple'], - card_font:['xiaozhuan','huangcao','caoshu','xingshu'], - double_hp:['hejiansan','pingjun','zuidazhi','zuixiaozhi','zonghe'], - image_background_filter:['default','blur','gray','sepia','invert','saturate','contrast','hue','brightness'], + forbidchess: ["hetaihou", "swd_kangnalishi"], + forbidboss: ["caiwenji", "gjqt_aruan", "pal_xuanxiao", "swd_hupo"], + forbiddouble: [ + "zhugedan", + "swd_kangnalishi", + "dongzhuo", + "wutugu", + "hs_siwangzhiyi", + "hs_ronghejuren", + "hs_shanlingjuren", + ], + forbidthreecard: [ + "qiankunbiao", + "shenhuofeiya", + "gw_ciguhanshuang", + "gw_birinongwu", + "gw_qinpendayu", + "gw_poxiao", + ], + zhinang_tricks: ["guohe", "wuxie", "wuzhong", "dongzhuxianji"], + connect_zhinang_tricks: ["guohe", "wuxie", "wuzhong", "dongzhuxianji"], + all: { + sgscharacters: [ + "standard", + "shenhua", + "xinghuoliaoyuan", + "refresh", + "yijiang", + "sp", + "sp2", + "xianding", + "huicui", + "extra", + "old", + "mobile", + "shiji", + "tw", + "yingbian", + "offline", + "jsrg", + "sb", + "clan", + "collab", + "onlyOL", + ], + sgscards: [ + "standard", + "extra", + "sp", + "guozhan", + "zhulu", + "yingbian", + "yongjian", + ], + sgsmodes: [ + "identity", + "guozhan", + "versus", + "doudizhu", + "single", + "brawl", + "connect", + ], + stockmode: [ + "identity", + "guozhan", + "versus", + "boss", + "doudizhu", + "single", + "chess", + "stone", + "connect", + "brawl", + "tafang", + ], + stockextension: ["boss", "cardpile", "coin", "wuxing"], + layout: ["default", "newlayout"], + theme: ["woodden", "music", "simple"], + card_font: ["xiaozhuan", "huangcao", "caoshu", "xingshu"], + double_hp: ["hejiansan", "pingjun", "zuidazhi", "zuixiaozhi", "zonghe"], + image_background_filter: [ + "default", + "blur", + "gray", + "sepia", + "invert", + "saturate", + "contrast", + "hue", + "brightness", + ], }, - game:'sgs', - duration:500, - hoveration:1000, - doubleclick_intro:true, - cheat:false, - volumn_background:8, - volumn_audio:8, + game: "sgs", + duration: 500, + hoveration: 1000, + doubleclick_intro: true, + cheat: false, + volumn_background: 8, + volumn_audio: 8, - connect_avatar:'caocao', - connect_nickname:'无名玩家', - config_menu:true, - auto_popped_config:true, - auto_popped_history:false, - auto_skill:true, - auto_confirm:true, - enable_drag:true, - enable_pressure:false, - pressure_taptic:true, - hover_handcard:true, - hover_all:true, - right_info:true, - longpress_info:true, - long_info:true, - background_music:'music_default', - background_audio:true, - background_speak:true, - glow_phase:'yellow', - die_move:'flip', + connect_avatar: "caocao", + connect_nickname: "无名玩家", + config_menu: true, + auto_popped_config: true, + auto_popped_history: false, + auto_skill: true, + auto_confirm: true, + enable_drag: true, + enable_pressure: false, + pressure_taptic: true, + hover_handcard: true, + hover_all: true, + right_info: true, + longpress_info: true, + long_info: true, + background_music: "music_default", + background_audio: true, + background_speak: true, + glow_phase: "yellow", + die_move: "flip", - skin:{}, - gameRecord:{}, - extensionInfo:{}, - autoskilllist:[], - hiddenModePack:[], - hiddenCharacterPack:[], - hiddenCardPack:[], - hiddenPlayPack:[], - hiddenBackgroundPack:[], - customBackgroundPack:[], - favouriteCharacter:[], - favouriteMode:[], - recentIP:[], - vintageSkills:[], - alteredSkills:[], - brokenFile:[], + skin: {}, + gameRecord: {}, + extensionInfo: {}, + autoskilllist: [], + hiddenModePack: [], + hiddenCharacterPack: [], + hiddenCardPack: [], + hiddenPlayPack: [], + hiddenBackgroundPack: [], + customBackgroundPack: [], + favouriteCharacter: [], + favouriteMode: [], + recentIP: [], + vintageSkills: [], + alteredSkills: [], + brokenFile: [], - theme:'woodden', - layout:'mobile', - card_style:'default', - cardback_style:'default', - hp_style:'default', + theme: "woodden", + layout: "mobile", + card_style: "default", + cardback_style: "default", + hp_style: "default", - image_character:'default', - image_background:'default', + image_character: "default", + image_background: "default", - asset_image:true, - asset_font:true, + asset_image: true, + asset_font: true, - card_font:'xiaozhuan', - show_statusbar_ios:'off', - show_statusbar_android:false, - show_name:true, - show_replay:false, - show_round_menu:true, - show_pause:true, - show_auto:true, - show_volumn:true, - show_cardpile:true, - only_fullskin:true, - show_connect:true, - show_wuxie:false, - show_wuxie_self:true, - show_stat:true, - show_playerids:true, - show_scrollbar:false, - mousewheel:true, - fold_card:true, - threed_card:false, - vertical_scroll:false, - handcard_scroll:0, - animation:true, - skill_animation_type:'default', - paused:false, - title:false, - button_press:true, - damage_shake:true, - log_highlight:true, - player_border:'normal', - radius_size:'default', + card_font: "xiaozhuan", + show_statusbar_ios: "off", + show_statusbar_android: false, + show_name: true, + show_replay: false, + show_round_menu: true, + show_pause: true, + show_auto: true, + show_volumn: true, + show_cardpile: true, + only_fullskin: true, + show_connect: true, + show_wuxie: false, + show_wuxie_self: true, + show_stat: true, + show_playerids: true, + show_scrollbar: false, + mousewheel: true, + fold_card: true, + threed_card: false, + vertical_scroll: false, + handcard_scroll: 0, + animation: true, + skill_animation_type: "default", + paused: false, + title: false, + button_press: true, + damage_shake: true, + log_highlight: true, + player_border: "normal", + radius_size: "default", - modeconfig:false, - gameconfig:false, - appearence:false, - video:'20', - coin:0, + modeconfig: false, + gameconfig: false, + appearence: false, + video: "20", + coin: 0, - intro:'i', - right_click:'pause', - sort:'type_sort', + intro: "i", + right_click: "pause", + sort: "type_sort", - cards:['standard','extra'], - characters:['standard','shenhua','sp','sp2','yijiang','refresh','xinghuoliaoyuan','mobile','extra','yingbian','sb','tw','offline','clan','collab','xianding','huicui','shiji','jsrg','onlyOL'], - connect_characters:['diy'], - connect_cards:['huanlekapai','guozhan','sp','zhulu','yingbian','yongjian'], - plays:[], - extensions:[], - banned:[], - bannedcards:[], - forbidlist:[], - bannedpile:{}, - customcardpile:{}, - addedpile:{}, + cards: ["standard", "extra"], + characters: [ + "standard", + "shenhua", + "sp", + "sp2", + "yijiang", + "refresh", + "xinghuoliaoyuan", + "mobile", + "extra", + "yingbian", + "sb", + "tw", + "offline", + "clan", + "collab", + "xianding", + "huicui", + "shiji", + "jsrg", + "onlyOL", + ], + connect_characters: ["diy"], + connect_cards: [ + "huanlekapai", + "guozhan", + "sp", + "zhulu", + "yingbian", + "yongjian", + ], + plays: [], + extensions: [], + banned: [], + bannedcards: [], + forbidlist: [], + bannedpile: {}, + customcardpile: {}, + addedpile: {}, - mode:'identity', - mode_config:{ - global:{ - player_number:8, - auto_identity:'off', - double_character:false, - save_progress:true, - free_choose:true, - swap:true, - change_identity:true, - battle_number:3, - double_hp:'pingjun', + mode: "identity", + mode_config: { + global: { + player_number: 8, + auto_identity: "off", + double_character: false, + save_progress: true, + free_choose: true, + swap: true, + change_identity: true, + battle_number: 3, + double_hp: "pingjun", }, - identity:{ - identity:[ - ['zhu','fan'], - ['zhu','nei','fan'], - ['zhu','zhong','nei','fan'], - ['zhu','zhong','nei','fan','fan'], - ['zhu','zhong','nei','fan','fan','fan'], - ['zhu','zhong','zhong','nei','fan','fan','fan'], - ['zhu','zhong','zhong','nei','fan','fan','fan','fan'], - ['zhu','zhong','zhong','zhong','nei','fan','fan','fan','fan'], - ['zhu','zhong','zhong','zhong','nei','nei','fan','fan','fan','fan'], + identity: { + identity: [ + ["zhu", "fan"], + ["zhu", "nei", "fan"], + ["zhu", "zhong", "nei", "fan"], + ["zhu", "zhong", "nei", "fan", "fan"], + ["zhu", "zhong", "nei", "fan", "fan", "fan"], + ["zhu", "zhong", "zhong", "nei", "fan", "fan", "fan"], + ["zhu", "zhong", "zhong", "nei", "fan", "fan", "fan", "fan"], + [ + "zhu", + "zhong", + "zhong", + "zhong", + "nei", + "fan", + "fan", + "fan", + "fan", + ], + [ + "zhu", + "zhong", + "zhong", + "zhong", + "nei", + "nei", + "fan", + "fan", + "fan", + "fan", + ], ], - choice:{ - zhu:3, - zhong:4, - nei:5, - fan:3, + choice: { + zhu: 3, + zhong: 4, + nei: 5, + fan: 3, }, - show_identity:true, - difficulty:'normal', - dierestart:true + show_identity: true, + difficulty: "normal", + dierestart: true, }, - guozhan:{ - difficulty:'normal', - initshow_draw:'mark', - dierestart:true + guozhan: { + difficulty: "normal", + initshow_draw: "mark", + dierestart: true, }, }, - current_mode:{}, - customforbid:[], - forbid:[ - ['huashen'], - ['rehuashen'], - ['xinmanjuan'], + current_mode: {}, + customforbid: [], + forbid: [ + ["huashen"], + ["rehuashen"], + ["xinmanjuan"], //['xinleiji','fuji'], - ['xinleiji','xinfu_jijun'], - ['reluanji','jueqing'], - ['lianying','rende'], - ['lianying','anxian'], - ['lianying','yinguo'], - ['lianying','qingjian'], - ['boss_juejing','rende'], - ['boss_juejing','anxian'], - ['boss_juejing','yinguo'], - ['boss_juejing','qingjian'], - ['shangshi','rende'], - ['shangshi','anxian'], - ['shangshi','yinguo'], - ['shangshi','qingjian'], - ['rende','relianying'], - ['anxian','relianying'], - ['yinguo','relianying'], - ['shenxing','relianying'], - ['qingjian','relianying'], - ['rende','yuling'], - ['anxian','yuling'], - ['yinguo','yuling'], - ['qingjian','yuling'], + ["xinleiji", "xinfu_jijun"], + ["reluanji", "jueqing"], + ["lianying", "rende"], + ["lianying", "anxian"], + ["lianying", "yinguo"], + ["lianying", "qingjian"], + ["boss_juejing", "rende"], + ["boss_juejing", "anxian"], + ["boss_juejing", "yinguo"], + ["boss_juejing", "qingjian"], + ["shangshi", "rende"], + ["shangshi", "anxian"], + ["shangshi", "yinguo"], + ["shangshi", "qingjian"], + ["rende", "relianying"], + ["anxian", "relianying"], + ["yinguo", "relianying"], + ["shenxing", "relianying"], + ["qingjian", "relianying"], + ["rende", "yuling"], + ["anxian", "yuling"], + ["yinguo", "yuling"], + ["qingjian", "yuling"], //['qingnang','yiji'], //['qingnang','reyiji'], //['qingjian','tuntian'], // ['yiji','tuntian'], // ['reyiji','tuntian'], - ['tuntian','guidao'], - ['tuntian','tiandao'], - ['tuntian','huanshi'], + ["tuntian", "guidao"], + ["tuntian", "tiandao"], + ["tuntian", "huanshi"], // ['tuntian','guicai'], // ['jiang','chongzhen'], // ['fenji','yuling'], - ['jiushi','guixin'], - ['xiuhua','qiaoxie'], - ['xiuhua','xuanfeng'], - ['xiuhua','duanxing'], - ['xiuhua','xiaoji'], - ['xiuhua','xiaoji'], + ["jiushi", "guixin"], + ["xiuhua", "qiaoxie"], + ["xiuhua", "xuanfeng"], + ["xiuhua", "duanxing"], + ["xiuhua", "xiaoji"], + ["xiuhua", "xiaoji"], // ['jiushi','jushou'], // ['jiushi','kuiwei'], - ['zishu','xinfu_songsang'], - ['zishu','shenxing'], - ['minishendao','luoshen'], - ['minishendao','reluoshen'], - ['akane_quanqing','lianying'], - ['akane_quanqing','relianying'], - ['akane_quanqing','shangshi'], - ['dcruyi','cxliushi'], - ] + ["zishu", "xinfu_songsang"], + ["zishu", "shenxing"], + ["minishendao", "luoshen"], + ["minishendao", "reluoshen"], + ["akane_quanqing", "lianying"], + ["akane_quanqing", "relianying"], + ["akane_quanqing", "shangshi"], + ["dcruyi", "cxliushi"], + ], }; diff --git a/game/directory.js b/game/directory.js index cdabbb940..bca4a4b84 100644 --- a/game/directory.js +++ b/game/directory.js @@ -1,176 +1,198 @@ -var fs=require('fs'); -var path=require('path'); -var exec = require('child_process').exec; -global.window=global; -require(__dirname+'/update.js'); -require(__dirname+'/asset.js'); - -var updates=window.noname_update; -var newversion=false; -var commit=false -if(process.argv[2]){ - if(/[0-9]/.test(process.argv[2][0])){ - newversion=true; - updates.update = updates.version; - updates.version = '1.9.' + process.argv[2]; - commit=updates.version; - } - else{ - commit=process.argv[2]; - } -} -var assetlist=''; -var skinlist='window.noname_skin_list={\n'; -var entrylist=[]; -var entrymap={}; -var get = function(dir,callback){ - fs.readdir(dir,function(err,list){ - var shift=function(){ - if(list.length){ - var filename=list.shift(); - var delay=false; - if(!/\.|~|_/.test(filename[0])){ - var url=dir+'/'+filename; - var stat=fs.statSync(url); - if(stat.isFile()){ - if(['.jpg','.png','.mp3','.ttf'].indexOf(path.extname(url))!=-1){ - var assetentry=path.relative(path.dirname(__dirname),url); - assetlist+=',\n\t\''+assetentry+'\''; - entrylist.push(assetentry); - } - } - else if(stat.isDirectory()){ - if(dir==path.dirname(__dirname)+'/image/skin'){ - fs.readdir(url,function(err,list){ - var num=0; - for(var i=0;i { - var updatelist='window.noname_update={\n\tversion:\''+updates.version+'\','; - updatelist+='\n\tupdate:\''+(updates.update||'')+'\','; - var apply=function(name,list){ - updatelist+='\n\t'+name+':[\n'; - for(var i=0;ib) return 1; - if (a { + var updatelist = + "window.noname_update={\n\tversion:'" + updates.version + "',"; + updatelist += "\n\tupdate:'" + (updates.update || "") + "',"; + var apply = function (name, list) { + updatelist += "\n\t" + name + ":[\n"; + for (var i = 0; i < list.length; i++) { + updatelist += "\t\t'" + list[i] + "'"; + if (i < list.length - 1) { + updatelist += ","; + } + updatelist += "\n"; + } + updatelist += "\t]"; + }; + if (updates.changeLog) { + apply("changeLog", updates.changeLog); + updatelist += ","; + } + if (updates.players) { + apply("players", updates.players); + updatelist += ","; + } + if (updates.cards) { + apply("cards", updates.cards); + updatelist += ","; + } + var changes = stdout.split("\n"); + for (var i = 0; i < changes.length; i++) { + var extname = path.extname(changes[i]); + if ( + !changes[i] || + (extname != ".js" && extname != ".css") || + changes[i] == "game/update.js" + ) { + changes.splice(i--, 1); + } + } + var files; + if (newversion) { + files = []; + } else { + files = updates.files || []; + } + for (var i = 0; i < changes.length; i++) { + if (files.indexOf(changes[i]) === -1) { + files.push(changes[i]); + } + } + files.sort(function (a, b) { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); + apply("files", files); + fs.writeFile( + "game/update.js", + updatelist + "\n};", + "utf-8", + function () { + console.log("updated update.js"); + if (commit && typeof commit === "string") { + exec("git add . && git commit -am " + commit); + console.log("committed " + commit); + } + } + ); + }); + }; + if (diff) { + var assetversion = + "window.noname_asset_list=[\n\t'" + updates.version + "'"; + fs.writeFile( + "game/asset.js", + assetversion + + assetlist + + "\n];\n" + + skinlist.slice(0, skinlist.length - 2) + + "\n};", + "utf-8", + function () { + console.log("udpated asset.js"); + next(); + } + ); + } else { + next(); + } +}); diff --git a/game/entry.js b/game/entry.js index 6678ac740..c4cae30cc 100644 --- a/game/entry.js +++ b/game/entry.js @@ -1,137 +1,171 @@ -import { game, get, lib, boot } from "../noname.js"; -import { canUseHttpProtocol, sendUpdate } from "../noname/init/index.js"; -import { userAgent } from "../noname/util/index.js"; - -const coreAndVersion = get.coreInfo(); -const core = coreAndVersion[0], version = coreAndVersion[1]; -//@todo: 77 -> 80 -if (core === 'chrome' && !isNaN(version) && version < 77) { - const tip = '检测到您的浏览器内核版本小于77,请及时升级浏览器或手机webview内核!'; - console.warn(tip); - game.print(tip); - const redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,将在未来的版本被废弃!\n目前使用的浏览器UA信息为:\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。`; - if (confirm(redirect_tip)) { - window.open('https://github.com/libccy/noname/releases/tag/chromium77-client'); - } -} - -boot().then(() => { - // 判断是否从file协议切换到http/s协议 - if (canUseHttpProtocol()) { - /* - 升级方法: - 1. 游戏启动后导出数据,然后以http/s协议重启 - 2. 以http/s协议导入数据 - 3. 保存http/s协议的状态,以后不再以file协议启动 - */ - // 导出数据到根目录的noname.config.txt - let data; - let export_data = function (data) { - game.promises.writeFile(lib.init.encode(JSON.stringify(data)), './', 'noname.config.txt') - .then(saveProtocol) - .catch(e => { - console.error('升级失败:', e); - }); - }; - // @ts-ignore - if (!lib.db) { - data = {}; - for (let i in localStorage) { - if (i.startsWith(lib.configprefix)) { - data[i] = localStorage[i]; - } - } - export_data(data); - } - else { - game.getDB('config', null, function (data1) { - game.getDB('data', null, function (data2) { - export_data({ - config: data1, - data: data2 - }); - }); - }); - } - // 保存协议的切换状态 - function saveProtocol() { - const url = sendUpdate(); - if (typeof url == 'string') { - if (typeof window.require == 'function' && typeof window.process == 'object') { - // @ts-ignore - const remote = require('@electron/remote'); - const thisWindow = remote.getCurrentWindow(); - thisWindow.loadURL(url); - } else { - location.href = url; - } - } - } - } else { - // 成功导入后删除noname.config.txt - let searchParams = new URLSearchParams(location.search); - for (let [key, value] of searchParams) { - if (key === 'sendUpdate' && value === 'true') { - game.promises.readFileAsText('noname.config.txt').then(data => { - return /** @type {Promise} */(new Promise(async (resolve, reject) => { - if (!data) return reject('!data'); - try { - data = JSON.parse(lib.init.decode(data)); - if (!data || typeof data != 'object') { - throw ('err'); - } - // @ts-ignore - if (lib.db && (!data.config || !data.data)) { - throw ('err'); - } - } - catch (e) { - console.log(e); - if (e == 'err') { - alert('导入文件格式不正确'); - reject('导入文件格式不正确'); - } else { - alert('导入失败: ' + e.message); - reject('导入失败: ' + e.message); - } - return; - } - alert('导入成功, 即将自动重启'); - // @ts-ignore - if (!lib.db) { - const noname_inited = localStorage.getItem('noname_inited'); - const onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - for (let i in data) { - localStorage.setItem(i, data[i]); - } - } - else { - for (let i in data.config) { - await game.putDB('config', i, data.config[i]); - lib.config[i] = data.config[i]; - } - for (let i in data.data) { - await game.putDB('data', i, data.data[i]); - } - } - lib.init.background(); - resolve(); - })); - }).then(() => { - return game.promises.removeFile('noname.config.txt'); - }).then(() => { - const url = new URL(location.href); - location.href = url.origin + url.pathname; - }); - } - } - } -}); - +import { game, get, lib, boot } from "../noname.js"; +import { canUseHttpProtocol, sendUpdate } from "../noname/init/index.js"; +import { userAgent } from "../noname/util/index.js"; + +const coreAndVersion = get.coreInfo(); +const core = coreAndVersion[0], + version = coreAndVersion[1]; +//@todo: 77 -> 80 +if (core === "chrome" && !isNaN(version) && version < 77) { + const tip = + "检测到您的浏览器内核版本小于77,请及时升级浏览器或手机webview内核!"; + console.warn(tip); + game.print(tip); + const redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,将在未来的版本被废弃!\n目前使用的浏览器UA信息为:\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。`; + if (confirm(redirect_tip)) { + window.open( + "https://github.com/libccy/noname/releases/tag/chromium77-client" + ); + } +} + +boot().then(() => { + // 判断是否从file协议切换到http/s协议 + if (canUseHttpProtocol()) { + /* + 升级方法: + 1. 游戏启动后导出数据,然后以http/s协议重启 + 2. 以http/s协议导入数据 + 3. 保存http/s协议的状态,以后不再以file协议启动 + */ + // 导出数据到根目录的noname.config.txt + let data; + let export_data = function (data) { + game.promises + .writeFile( + lib.init.encode(JSON.stringify(data)), + "./", + "noname.config.txt" + ) + .then(saveProtocol) + .catch((e) => { + console.error("升级失败:", e); + }); + }; + // @ts-ignore + if (!lib.db) { + data = {}; + for (let i in localStorage) { + if (i.startsWith(lib.configprefix)) { + data[i] = localStorage[i]; + } + } + export_data(data); + } else { + game.getDB("config", null, function (data1) { + game.getDB("data", null, function (data2) { + export_data({ + config: data1, + data: data2, + }); + }); + }); + } + // 保存协议的切换状态 + function saveProtocol() { + const url = sendUpdate(); + if (typeof url == "string") { + if ( + typeof window.require == "function" && + typeof window.process == "object" + ) { + // @ts-ignore + const remote = require("@electron/remote"); + const thisWindow = remote.getCurrentWindow(); + thisWindow.loadURL(url); + } else { + location.href = url; + } + } + } + } else { + // 成功导入后删除noname.config.txt + let searchParams = new URLSearchParams(location.search); + for (let [key, value] of searchParams) { + if (key === "sendUpdate" && value === "true") { + game.promises + .readFileAsText("noname.config.txt") + .then((data) => { + return /** @type {Promise} */ ( + new Promise(async (resolve, reject) => { + if (!data) return reject("!data"); + try { + data = JSON.parse(lib.init.decode(data)); + if (!data || typeof data != "object") { + throw "err"; + } + // @ts-ignore + if ( + lib.db && + (!data.config || !data.data) + ) { + throw "err"; + } + } catch (e) { + console.log(e); + if (e == "err") { + alert("导入文件格式不正确"); + reject("导入文件格式不正确"); + } else { + alert("导入失败: " + e.message); + reject("导入失败: " + e.message); + } + return; + } + alert("导入成功, 即将自动重启"); + // @ts-ignore + if (!lib.db) { + const noname_inited = + localStorage.getItem("noname_inited"); + const onlineKey = localStorage.getItem( + lib.configprefix + "key" + ); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem( + "noname_inited", + noname_inited + ); + } + if (onlineKey) { + localStorage.setItem( + lib.configprefix + "key", + onlineKey + ); + } + for (let i in data) { + localStorage.setItem(i, data[i]); + } + } else { + for (let i in data.config) { + await game.putDB( + "config", + i, + data.config[i] + ); + lib.config[i] = data.config[i]; + } + for (let i in data.data) { + await game.putDB( + "data", + i, + data.data[i] + ); + } + } + lib.init.background(); + resolve(); + }) + ); + }) + .then(() => { + return game.promises.removeFile("noname.config.txt"); + }) + .then(() => { + const url = new URL(location.href); + location.href = url.origin + url.pathname; + }); + } + } + } +}); diff --git a/game/game.js b/game/game.js index f071cb26e..b682ef2f2 100644 --- a/game/game.js +++ b/game/game.js @@ -1,232 +1,302 @@ -"use strict"; - -new Promise(resolve => { - // 客户端自带core.js的请注意跟进core.js版本 - if ('__core-js_shared__' in window) resolve(null); - else { - const nonameInitialized = localStorage.getItem('noname_inited'); - const assetURL = location.protocol.startsWith('http') || typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; - const coreJSBundle = document.createElement('script'); - coreJSBundle.onerror = coreJSBundle.onload = resolve; - coreJSBundle.src = `${assetURL}game/core-js-bundle.js`; - document.head.appendChild(coreJSBundle); - } -}).then(() => { - const nonameInitialized = localStorage.getItem('noname_inited'); - const assetURL = location.protocol.startsWith('http') || typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; - const userAgent = navigator.userAgent.toLowerCase(); - - const exit = () => { - const ios = userAgent.includes('iphone') || userAgent.includes('ipad') || userAgent.includes('macintosh'); - //electron - if (typeof window.process == 'object' && typeof window.require == 'function') { - const versions = window.process.versions; - // @ts-ignore - const electronVersion = parseFloat(versions.electron); - let remote; - if (electronVersion >= 14) { - // @ts-ignore - remote = require('@electron/remote'); - } else { - // @ts-ignore - remote = require('electron').remote; - } - const thisWindow = remote.getCurrentWindow(); - thisWindow.destroy(); - window.process.exit(); - } - //android-cordova环境 - //ios-cordova环境或ios浏览器环境 - //非ios的网页版 - else if (!ios) { - window.close(); - } - }; - - // 这个弹窗,在升级到http协议下的客户端不应该进行提示。 - if (!localStorage.getItem('gplv3_noname_alerted')) { - const nonameInitialized = localStorage.getItem('noname_inited'); - const callback = () => { - if (confirm('①无名杀是一款基于GPLv3协议的开源软件!\n你可以在遵守GPLv3协议的基础上任意使用,修改并转发《无名杀》,以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓️\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库!\n其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!')) { - // @ts-ignore - localStorage.setItem('gplv3_noname_alerted', true); - } - else { - exit(); - } - }; - if (location.protocol.startsWith('http')) { - if (!nonameInitialized || nonameInitialized.length == 0) { - callback(); - } else { - // @ts-ignore - localStorage.setItem('gplv3_noname_alerted', true); - } - } else callback(); - - } - window['b' + 'ann' + 'e' + 'dE' + 'x' + 'ten' + 's' + 'i' + 'o' + 'ns'] = ['\u4fa0\u4e49', '\u5168\u6559\u7a0b']; - - /** - * - * @returns {["firefox" | "chrome" | "safari" | "other", number, number, number]} - */ - function coreInfo() { - const regex = /(firefox|chrome|safari)\/(\d+(?:\.\d+)+)/ - let result - if (!(result = userAgent.match(regex))) return ["other", NaN, NaN, NaN] - if (result[1] != "safari") { - const [major, minor, patch] = result[2].split(".") - // @ts-ignore - return [result[1], parseInt(major), parseInt(minor), parseInt(patch)] - } - result = userAgent.match(/version\/(\d+(?:\.\d+)+).*safari/) - // @ts-ignore - const [major, minor, patch] = result[1].split(".") - return ["safari", parseInt(major), parseInt(minor), parseInt(patch)] - } - const [core, major, minor, patch] = coreInfo(); - const supportMap = { - "firefox": [60, 0, 0], - "chrome": [61, 0, 0], - "safari": [14, 5, 0] - } - const versions = [major, minor, patch] - // require是需求的版本号,current是浏览器环境本身的版本号 - const check = (require, current) => { - // 防止不存在的意外,提前截断当前版本号的长度 - if (current.length > require.length) current.length = require.length - - // 考虑到玄学的NaN情况,记录是否存在NaN - let flag = false - // 从主版本号遍历到修订版本号,只考虑当前版本号的长度 - for (let i = 0; i < current.length; ++i) { - // 当前环境版本号当前位若是NaN,则记录后直接到下一位 - if (isNaN(current[i])) { - flag = true - continue - } - // 如果此时flag为true且current[i]不为NaN,版本号则不合法,直接否 - if (flag) return false - // 上位版本号未达到要求,直接否决 - if (require[i] > current[i]) return false - // 上位版本号已超过要求,直接可行 - if (current[i] > require[i]) return true - } - return true - } - - if (core in supportMap && !check(supportMap[core], versions)) { - const tip = '检测到您的浏览器内核版本无法支持当前无名杀所需的功能,请立即升级浏览器或手机webview内核!'; - console.error(tip); - let redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n目前使用的浏览器UA信息为:\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。\n稍后您的无名杀将自动退出(可能的话)`; - if (core === 'safari') { - alert(`您使用的safari浏览器无法支持当前无名杀所需的功能,请至少升级至14.5.0!\n稍后您的无名杀将自动退出(可能的话)`); - } else { - if (confirm(redirect_tip)) { - window.open('https://github.com/libccy/noname/releases/tag/chromium77-client'); - } - } - exit(); - } - else { - // node环境下 - if (typeof window.require == 'function' && - typeof window.process == 'object' && - typeof window.__dirname == 'string') { - // 在http环境下修改__dirname和require的逻辑 - if (location.protocol.startsWith('http') && - window.__dirname.endsWith('electron.asar\\renderer')) { - const path = require('path'); - window.__dirname = path.join(path.resolve(), 'resources/app'); - const oldData = Object.entries(window.require); - // @ts-ignore - window.require = function (moduleId) { - try { - return module.require(moduleId); - } catch { - return module.require(path.join(window.__dirname, moduleId)); - } - }; - oldData.forEach(([key, value]) => { - window.require[key] = value; - }); - } - // 增加导入ts的逻辑 - window.require.extensions['.ts'] = function (module, filename) { - // @ts-ignore - const _compile = module._compile; - // @ts-ignore - module._compile = function (code, fileName) { - /** - * @type { import('typescript') } - */ - // @ts-ignore - const ts = require('./game/typescript.js'); - // 使用ts compiler对ts文件进行编译 - const result = ts.transpile(code, { - module: ts.ModuleKind.CommonJS, - //@todo: ES2019 -> ES2020 - target: ts.ScriptTarget.ES2019, - inlineSourceMap: true, - resolveJsonModule: true, - esModuleInterop: true, - }, fileName); - // 使用默认的js编译函数获取返回值 - return _compile.call(this, result, fileName); - } - // @ts-ignore - module._compile(require('fs').readFileSync(filename, 'utf8'), filename); - }; - } - // 使serviceWorker加载完成后,再加载entry.js - const loadEntryJs = () => { - const script = document.createElement('script') - script.type = "module"; - script.src = `${assetURL}game/entry.js`; - script.async = true; - script.onerror = event => { - console.error(event); - const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n请检查是否缺少游戏文件!隔版本更新请下载完整包而不是离线包!\n目前使用的浏览器UA信息为:\n${userAgent}\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》,请尝试更新手机的WebView内核,或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏,请改为运行文件夹内的“noname-server.exe”(或使用VSCode等工具启动Live Server),以动态服务器的方式启动《无名杀》!\n若您使用的是苹果端,请至少将Safari升级至14.5.0!`; - console.error(message); - alert(message); - exit(); - } - document.head.appendChild(script); - }; - - if (location.protocol.startsWith('http') && 'serviceWorker' in navigator) { - let scope = window.location.protocol + '//' + window.location.host + '/'; - navigator.serviceWorker.getRegistrations() - .then(async registrations => { - let findServiceWorker = registrations.find(registration => { - return registration && registration.active && registration.active.scriptURL == `${scope}service-worker.js`; - }); - try { - const registration_1 = await navigator.serviceWorker.register(`${scope}service-worker.js`, { - type: 'module', - updateViaCache: "all", - scope, - }); - // 初次加载worker,需要重新启动一次 - if (!findServiceWorker) location.reload(); - // 接收消息,暂时没用到 - navigator.serviceWorker.addEventListener('message', e => { - console.log(e); - }); - registration_1.update().catch(e => console.error('worker update失败', e)); - if (!sessionStorage.getItem('canUseTs')) { - await import('./canUse.ts').then(({ text }) => console.log(text)).catch(() => { - sessionStorage.setItem('canUseTs', '1'); - location.reload(); - }); - } - } catch (e_1) { - console.log('serviceWorker加载失败: ', e_1); - } - }).finally(loadEntryJs); - } else { - loadEntryJs(); - } - } -}); +"use strict"; + +new Promise((resolve) => { + // 客户端自带core.js的请注意跟进core.js版本 + if ("__core-js_shared__" in window) resolve(null); + else { + const nonameInitialized = localStorage.getItem("noname_inited"); + const assetURL = + location.protocol.startsWith("http") || + typeof nonameInitialized != "string" || + nonameInitialized == "nodejs" + ? "" + : nonameInitialized; + const coreJSBundle = document.createElement("script"); + coreJSBundle.onerror = coreJSBundle.onload = resolve; + coreJSBundle.src = `${assetURL}game/core-js-bundle.js`; + document.head.appendChild(coreJSBundle); + } +}).then(() => { + const nonameInitialized = localStorage.getItem("noname_inited"); + const assetURL = + location.protocol.startsWith("http") || + typeof nonameInitialized != "string" || + nonameInitialized == "nodejs" + ? "" + : nonameInitialized; + const userAgent = navigator.userAgent.toLowerCase(); + + const exit = () => { + const ios = + userAgent.includes("iphone") || + userAgent.includes("ipad") || + userAgent.includes("macintosh"); + //electron + if ( + typeof window.process == "object" && + typeof window.require == "function" + ) { + const versions = window.process.versions; + // @ts-ignore + const electronVersion = parseFloat(versions.electron); + let remote; + if (electronVersion >= 14) { + // @ts-ignore + remote = require("@electron/remote"); + } else { + // @ts-ignore + remote = require("electron").remote; + } + const thisWindow = remote.getCurrentWindow(); + thisWindow.destroy(); + window.process.exit(); + } + //android-cordova环境 + //ios-cordova环境或ios浏览器环境 + //非ios的网页版 + else if (!ios) { + window.close(); + } + }; + + // 这个弹窗,在升级到http协议下的客户端不应该进行提示。 + if (!localStorage.getItem("gplv3_noname_alerted")) { + const nonameInitialized = localStorage.getItem("noname_inited"); + const callback = () => { + if ( + confirm( + "①无名杀是一款基于GPLv3协议的开源软件!\n你可以在遵守GPLv3协议的基础上任意使用,修改并转发《无名杀》,以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓️\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库!\n其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!" + ) + ) { + // @ts-ignore + localStorage.setItem("gplv3_noname_alerted", true); + } else { + exit(); + } + }; + if (location.protocol.startsWith("http")) { + if (!nonameInitialized || nonameInitialized.length == 0) { + callback(); + } else { + // @ts-ignore + localStorage.setItem("gplv3_noname_alerted", true); + } + } else callback(); + } + window["b" + "ann" + "e" + "dE" + "x" + "ten" + "s" + "i" + "o" + "ns"] = [ + "\u4fa0\u4e49", + "\u5168\u6559\u7a0b", + "在线更新", //游戏内在线更新方式修改了,不再依赖于在线更新扩展了 + ]; + + /** + * + * @returns {["firefox" | "chrome" | "safari" | "other", number, number, number]} + */ + function coreInfo() { + const regex = /(firefox|chrome|safari)\/(\d+(?:\.\d+)+)/; + let result; + if (!(result = userAgent.match(regex))) return ["other", NaN, NaN, NaN]; + if (result[1] != "safari") { + const [major, minor, patch] = result[2].split("."); + // @ts-ignore + return [ + result[1], + parseInt(major), + parseInt(minor), + parseInt(patch), + ]; + } + result = userAgent.match(/version\/(\d+(?:\.\d+)+).*safari/); + // @ts-ignore + const [major, minor, patch] = result[1].split("."); + return ["safari", parseInt(major), parseInt(minor), parseInt(patch)]; + } + const [core, major, minor, patch] = coreInfo(); + const supportMap = { + firefox: [60, 0, 0], + chrome: [61, 0, 0], + safari: [14, 5, 0], + }; + const versions = [major, minor, patch]; + // require是需求的版本号,current是浏览器环境本身的版本号 + const check = (require, current) => { + // 防止不存在的意外,提前截断当前版本号的长度 + if (current.length > require.length) current.length = require.length; + + // 考虑到玄学的NaN情况,记录是否存在NaN + let flag = false; + // 从主版本号遍历到修订版本号,只考虑当前版本号的长度 + for (let i = 0; i < current.length; ++i) { + // 当前环境版本号当前位若是NaN,则记录后直接到下一位 + if (isNaN(current[i])) { + flag = true; + continue; + } + // 如果此时flag为true且current[i]不为NaN,版本号则不合法,直接否 + if (flag) return false; + // 上位版本号未达到要求,直接否决 + if (require[i] > current[i]) return false; + // 上位版本号已超过要求,直接可行 + if (current[i] > require[i]) return true; + } + return true; + }; + + if (core in supportMap && !check(supportMap[core], versions)) { + const tip = + "检测到您的浏览器内核版本无法支持当前无名杀所需的功能,请立即升级浏览器或手机webview内核!"; + console.error(tip); + let redirect_tip = `您使用的浏览器或无名杀客户端内核版本过低,已经无法正常运行无名杀!\n目前使用的浏览器UA信息为:\n${userAgent}\n点击“确认”以前往GitHub下载最新版无名杀客户端(可能需要科学上网)。\n稍后您的无名杀将自动退出(可能的话)`; + if (core === "safari") { + alert( + `您使用的safari浏览器无法支持当前无名杀所需的功能,请至少升级至14.5.0!\n稍后您的无名杀将自动退出(可能的话)` + ); + } else { + if (confirm(redirect_tip)) { + window.open( + "https://github.com/libccy/noname/releases/tag/chromium77-client" + ); + } + } + exit(); + } else { + // node环境下 + if ( + typeof window.require == "function" && + typeof window.process == "object" && + typeof window.__dirname == "string" + ) { + // 在http环境下修改__dirname和require的逻辑 + if ( + location.protocol.startsWith("http") && + window.__dirname.endsWith("electron.asar\\renderer") + ) { + const path = require("path"); + window.__dirname = path.join(path.resolve(), "resources/app"); + const oldData = Object.entries(window.require); + // @ts-ignore + window.require = function (moduleId) { + try { + return module.require(moduleId); + } catch { + return module.require( + path.join(window.__dirname, moduleId) + ); + } + }; + oldData.forEach(([key, value]) => { + window.require[key] = value; + }); + } + // 增加导入ts的逻辑 + window.require.extensions[".ts"] = function (module, filename) { + // @ts-ignore + const _compile = module._compile; + // @ts-ignore + module._compile = function (code, fileName) { + /** + * @type { import('typescript') } + */ + // @ts-ignore + const ts = require("./game/typescript.js"); + // 使用ts compiler对ts文件进行编译 + const result = ts.transpile( + code, + { + module: ts.ModuleKind.CommonJS, + //@todo: ES2019 -> ES2020 + target: ts.ScriptTarget.ES2019, + inlineSourceMap: true, + resolveJsonModule: true, + esModuleInterop: true, + }, + fileName + ); + // 使用默认的js编译函数获取返回值 + return _compile.call(this, result, fileName); + }; + // @ts-ignore + module._compile( + require("fs").readFileSync(filename, "utf8"), + filename + ); + }; + } + // 使serviceWorker加载完成后,再加载entry.js + const loadEntryJs = () => { + const script = document.createElement("script"); + script.type = "module"; + script.src = `${assetURL}game/entry.js`; + script.async = true; + script.onerror = (event) => { + console.error(event); + const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n请检查是否缺少游戏文件!隔版本更新请下载完整包而不是离线包!\n目前使用的浏览器UA信息为:\n${userAgent}\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》,请尝试更新手机的WebView内核,或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏,请改为运行文件夹内的“noname-server.exe”(或使用VSCode等工具启动Live Server),以动态服务器的方式启动《无名杀》!\n若您使用的是苹果端,请至少将Safari升级至14.5.0!`; + console.error(message); + alert(message); + exit(); + }; + document.head.appendChild(script); + }; + + if ( + location.protocol.startsWith("http") && + "serviceWorker" in navigator + ) { + let scope = + window.location.protocol + "//" + window.location.host + "/"; + navigator.serviceWorker + .getRegistrations() + .then(async (registrations) => { + let findServiceWorker = registrations.find( + (registration) => { + return ( + registration && + registration.active && + registration.active.scriptURL == + `${scope}service-worker.js` + ); + } + ); + try { + const registration_1 = + await navigator.serviceWorker.register( + `${scope}service-worker.js`, + { + type: "module", + updateViaCache: "all", + scope, + } + ); + // 初次加载worker,需要重新启动一次 + if (!findServiceWorker) location.reload(); + // 接收消息,暂时没用到 + navigator.serviceWorker.addEventListener( + "message", + (e) => { + console.log(e); + } + ); + registration_1 + .update() + .catch((e) => + console.error("worker update失败", e) + ); + if (!sessionStorage.getItem("canUseTs")) { + await import("./canUse.ts") + .then(({ text }) => console.log(text)) + .catch(() => { + sessionStorage.setItem("canUseTs", "1"); + location.reload(); + }); + } + } catch (e_1) { + console.log("serviceWorker加载失败: ", e_1); + } + }) + .finally(loadEntryJs); + } else { + loadEntryJs(); + } + } +}); diff --git a/game/http.js b/game/http.js index 95ed6fd41..b0bee2db9 100644 --- a/game/http.js +++ b/game/http.js @@ -1,87 +1,111 @@ -var http = require('http'); -var fs = require('fs'); -var server = new http.Server(); -server.listen(80); -server.on('request', function(request, response) { - var url = require('url').parse(request.url); - switch(url.pathname) { - case ''||'/' : - fs.readFile('./index.html', function(err, content){ - if(err) { - response.writeHead(404, { 'Content-Type':'text/plain; charset="UTF-8"' }); - response.write(err.message); - response.end(); - } else { - response.writeHead(200, { 'Content-Type' : 'text/html; charset=UTF-8' }); - response.write(content); - response.end(); - } - }); - break; - case '/test/delay': - var delay = parseInt(url.query) || 2000; - response.writeHead(200, {'Content-type':'text/plain; charset=UTF-8'}); - response.write('Sleeping for' + delay + ' milliseconds...'); - setTimeout(function(){ - response.write('done.'); - response.end(); - }, delay); - break; - case '/test/mirror': - response.writeHead(200, {'Content-type':'text/plain; charset=UTF-8'}); - response.write(request.mothod + ' ' + request.url + ' HTTP/' + request.httpVersion + '\r\n'); - for (var h in request.headers) { - response.write(h + ':' + request.headers[h] + '\r\n'); - } - response.write('\r\n'); - request.on('data', function(chunk) { response.write(chunk); }); - request.on('end', function(chunk){ response.end(); }); - break; - case '/json' : - response.writeHead(200, {'Content-type':'application/json; charset=UTF-8'}); - response.write(JSON.stringify({test:'success'})); - response.end(); - break; - default: - var filename = url.pathname.substring(1); - var type = getType(filename.substring(filename.lastIndexOf('.')+1)); - fs.readFile(filename, function(err, content){ - if(err) { - response.writeHead(404, { 'Content-Type':'text/plain; charset="UTF-8"' }); - response.write(err.message); - response.end(); - } else { - response.writeHead(200, { 'Content-Type' : type }); - response.write(content); - response.end(); - } - }); - break; - } - -}); -function getType(endTag){ - var type=null; - switch(endTag){ - case 'html' : - case 'htm' : - type = 'text/html; charset=UTF-8'; - break; - case 'js' : - type = 'application/javascript; charset="UTF-8"'; - break; - case 'css' : - type = 'text/css; charset="UTF-8"'; - break; - case 'txt' : - type = 'text/plain; charset="UTF-8"'; - break; - case 'manifest' : - type = 'text/cache-manifest; charset="UTF-8"'; - break; - default : - type = 'application/octet-stream'; - break; - } - return type; -} +var http = require("http"); +var fs = require("fs"); +var server = new http.Server(); +server.listen(80); +server.on("request", function (request, response) { + var url = require("url").parse(request.url); + switch (url.pathname) { + case "" || "/": + fs.readFile("./index.html", function (err, content) { + if (err) { + response.writeHead(404, { + "Content-Type": 'text/plain; charset="UTF-8"', + }); + response.write(err.message); + response.end(); + } else { + response.writeHead(200, { + "Content-Type": "text/html; charset=UTF-8", + }); + response.write(content); + response.end(); + } + }); + break; + case "/test/delay": + var delay = parseInt(url.query) || 2000; + response.writeHead(200, { + "Content-type": "text/plain; charset=UTF-8", + }); + response.write("Sleeping for" + delay + " milliseconds..."); + setTimeout(function () { + response.write("done."); + response.end(); + }, delay); + break; + case "/test/mirror": + response.writeHead(200, { + "Content-type": "text/plain; charset=UTF-8", + }); + response.write( + request.mothod + + " " + + request.url + + " HTTP/" + + request.httpVersion + + "\r\n" + ); + for (var h in request.headers) { + response.write(h + ":" + request.headers[h] + "\r\n"); + } + response.write("\r\n"); + request.on("data", function (chunk) { + response.write(chunk); + }); + request.on("end", function (chunk) { + response.end(); + }); + break; + case "/json": + response.writeHead(200, { + "Content-type": "application/json; charset=UTF-8", + }); + response.write(JSON.stringify({ test: "success" })); + response.end(); + break; + default: + var filename = url.pathname.substring(1); + var type = getType( + filename.substring(filename.lastIndexOf(".") + 1) + ); + fs.readFile(filename, function (err, content) { + if (err) { + response.writeHead(404, { + "Content-Type": 'text/plain; charset="UTF-8"', + }); + response.write(err.message); + response.end(); + } else { + response.writeHead(200, { "Content-Type": type }); + response.write(content); + response.end(); + } + }); + break; + } +}); +function getType(endTag) { + var type = null; + switch (endTag) { + case "html": + case "htm": + type = "text/html; charset=UTF-8"; + break; + case "js": + type = 'application/javascript; charset="UTF-8"'; + break; + case "css": + type = 'text/css; charset="UTF-8"'; + break; + case "txt": + type = 'text/plain; charset="UTF-8"'; + break; + case "manifest": + type = 'text/cache-manifest; charset="UTF-8"'; + break; + default: + type = "application/octet-stream"; + break; + } + return type; +} diff --git a/game/jszip.js b/game/jszip.js index 84a63d2e3..86efd905a 100644 --- a/game/jszip.js +++ b/game/jszip.js @@ -1,9720 +1,11690 @@ -// @ts-nocheck -/*! - -JSZip - A Javascript class for generating and reading zip files - - -(c) 2009-2014 Stuart Knightley -Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. - -JSZip uses the library pako released under the MIT license : -https://github.com/nodeca/pako/blob/master/LICENSE -*/ -/** - * @type { typeof import('@types/jszip') } - */ -(function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f() } else if (typeof define === "function" && define.amd) { define([], f) } else { var g; if (typeof window !== "undefined") { g = window } else if (typeof global !== "undefined") { g = global } else if (typeof self !== "undefined") { g = self } else { g = this } g.JSZip = f() } })(function () { - var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({ - 1: [function (require, module, exports) { - 'use strict'; - var DataReader = require('./dataReader'); - - function ArrayReader(data) { - if (data) { - this.data = data; - this.length = this.data.length; - this.index = 0; - this.zero = 0; - - for (var i = 0; i < this.data.length; i++) { - data[i] = data[i] & 0xFF; - } - } - } - ArrayReader.prototype = new DataReader(); - /** - * @see DataReader.byteAt - */ - ArrayReader.prototype.byteAt = function (i) { - return this.data[this.zero + i]; - }; - /** - * @see DataReader.lastIndexOfSignature - */ - ArrayReader.prototype.lastIndexOfSignature = function (sig) { - var sig0 = sig.charCodeAt(0), - sig1 = sig.charCodeAt(1), - sig2 = sig.charCodeAt(2), - sig3 = sig.charCodeAt(3); - for (var i = this.length - 4; i >= 0; --i) { - if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { - return i - this.zero; - } - } - - return -1; - }; - /** - * @see DataReader.readData - */ - ArrayReader.prototype.readData = function (size) { - this.checkOffset(size); - if (size === 0) { - return []; - } - var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); - this.index += size; - return result; - }; - module.exports = ArrayReader; - - }, { "./dataReader": 6 }], 2: [function (require, module, exports) { - 'use strict'; - // private property - var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - - // public method for encoding - exports.encode = function (input, utf8) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } - else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); - - } - - return output; - }; - - // public method for decoding - exports.decode = function (input, utf8) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = _keyStr.indexOf(input.charAt(i++)); - enc2 = _keyStr.indexOf(input.charAt(i++)); - enc3 = _keyStr.indexOf(input.charAt(i++)); - enc4 = _keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - - } - - return output; - - }; - - }, {}], 3: [function (require, module, exports) { - 'use strict'; - function CompressedObject() { - this.compressedSize = 0; - this.uncompressedSize = 0; - this.crc32 = 0; - this.compressionMethod = null; - this.compressedContent = null; - } - - CompressedObject.prototype = { - /** - * Return the decompressed content in an unspecified format. - * The format will depend on the decompressor. - * @return {Object} the decompressed content. - */ - getContent: function () { - return null; // see implementation - }, - /** - * Return the compressed content in an unspecified format. - * The format will depend on the compressed conten source. - * @return {Object} the compressed content. - */ - getCompressedContent: function () { - return null; // see implementation - } - }; - module.exports = CompressedObject; - - }, {}], 4: [function (require, module, exports) { - 'use strict'; - exports.STORE = { - magic: "\x00\x00", - compress: function (content, compressionOptions) { - return content; // no compression - }, - uncompress: function (content) { - return content; // no compression - }, - compressInputType: null, - uncompressInputType: null - }; - exports.DEFLATE = require('./flate'); - - }, { "./flate": 9 }], 5: [function (require, module, exports) { - 'use strict'; - - var utils = require('./utils'); - - var table = [ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D - ]; - - /** - * - * Javascript crc32 - * http://www.webtoolkit.info/ - * - */ - module.exports = function crc32(input, crc) { - if (typeof input === "undefined" || !input.length) { - return 0; - } - - var isArray = utils.getTypeOf(input) !== "string"; - - if (typeof (crc) == "undefined") { - crc = 0; - } - var x = 0; - var y = 0; - var b = 0; - - crc = crc ^ (-1); - for (var i = 0, iTop = input.length; i < iTop; i++) { - b = isArray ? input[i] : input.charCodeAt(i); - y = (crc ^ b) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); - }; - // vim: set shiftwidth=4 softtabstop=4: - - }, { "./utils": 22 }], 6: [function (require, module, exports) { - 'use strict'; - var utils = require('./utils'); - - function DataReader(data) { - this.data = null; // type : see implementation - this.length = 0; - this.index = 0; - this.zero = 0; - } - DataReader.prototype = { - /** - * Check that the offset will not go too far. - * @param {string} offset the additional offset to check. - * @throws {Error} an Error if the offset is out of bounds. - */ - checkOffset: function (offset) { - this.checkIndex(this.index + offset); - }, - /** - * Check that the specifed index will not be too far. - * @param {string} newIndex the index to check. - * @throws {Error} an Error if the index is out of bounds. - */ - checkIndex: function (newIndex) { - if (this.length < this.zero + newIndex || newIndex < 0) { - throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); - } - }, - /** - * Change the index. - * @param {number} newIndex The new index. - * @throws {Error} if the new index is out of the data. - */ - setIndex: function (newIndex) { - this.checkIndex(newIndex); - this.index = newIndex; - }, - /** - * Skip the next n bytes. - * @param {number} n the number of bytes to skip. - * @throws {Error} if the new index is out of the data. - */ - skip: function (n) { - this.setIndex(this.index + n); - }, - /** - * Get the byte at the specified index. - * @param {number} i the index to use. - * @return {number} a byte. - */ - byteAt: function (i) { - // see implementations - }, - /** - * Get the next number with a given byte size. - * @param {number} size the number of bytes to read. - * @return {number} the corresponding number. - */ - readInt: function (size) { - var result = 0, - i; - this.checkOffset(size); - for (i = this.index + size - 1; i >= this.index; i--) { - result = (result << 8) + this.byteAt(i); - } - this.index += size; - return result; - }, - /** - * Get the next string with a given byte size. - * @param {number} size the number of bytes to read. - * @return {string} the corresponding string. - */ - readString: function (size) { - return utils.transformTo("string", this.readData(size)); - }, - /** - * Get raw data without conversion, bytes. - * @param {number} size the number of bytes to read. - * @return {Object} the raw data, implementation specific. - */ - readData: function (size) { - // see implementations - }, - /** - * Find the last occurence of a zip signature (4 bytes). - * @param {string} sig the signature to find. - * @return {number} the index of the last occurence, -1 if not found. - */ - lastIndexOfSignature: function (sig) { - // see implementations - }, - /** - * Get the next date. - * @return {Date} the date. - */ - readDate: function () { - var dostime = this.readInt(4); - return new Date( - ((dostime >> 25) & 0x7f) + 1980, // year - ((dostime >> 21) & 0x0f) - 1, // month - (dostime >> 16) & 0x1f, // day - (dostime >> 11) & 0x1f, // hour - (dostime >> 5) & 0x3f, // minute - (dostime & 0x1f) << 1); // second - } - }; - module.exports = DataReader; - - }, { "./utils": 22 }], 7: [function (require, module, exports) { - 'use strict'; - exports.base64 = false; - exports.binary = false; - exports.dir = false; - exports.createFolders = false; - exports.date = null; - exports.compression = null; - exports.compressionOptions = null; - exports.comment = null; - exports.unixPermissions = null; - exports.dosPermissions = null; - - }, {}], 8: [function (require, module, exports) { - 'use strict'; - var utils = require('./utils'); - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.string2binary = function (str) { - return utils.string2binary(str); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.string2Uint8Array = function (str) { - return utils.transformTo("uint8array", str); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.uint8Array2String = function (array) { - return utils.transformTo("string", array); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.string2Blob = function (str) { - var buffer = utils.transformTo("arraybuffer", str); - return utils.arrayBuffer2Blob(buffer); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.arrayBuffer2Blob = function (buffer) { - return utils.arrayBuffer2Blob(buffer); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.transformTo = function (outputType, input) { - return utils.transformTo(outputType, input); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.getTypeOf = function (input) { - return utils.getTypeOf(input); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.checkSupport = function (type) { - return utils.checkSupport(type); - }; - - /** - * @deprecated - * This value will be removed in a future version without replacement. - */ - exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; - - /** - * @deprecated - * This value will be removed in a future version without replacement. - */ - exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; - - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.pretty = function (str) { - return utils.pretty(str); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.findCompression = function (compressionMethod) { - return utils.findCompression(compressionMethod); - }; - - /** - * @deprecated - * This function will be removed in a future version without replacement. - */ - exports.isRegExp = function (object) { - return utils.isRegExp(object); - }; - - - }, { "./utils": 22 }], 9: [function (require, module, exports) { - 'use strict'; - var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); - - var pako = require("pako"); - exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; - exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; - - exports.magic = "\x08\x00"; - exports.compress = function (input, compressionOptions) { - return pako.deflateRaw(input, { - level: compressionOptions.level || -1 // default compression - }); - }; - exports.uncompress = function (input) { - return pako.inflateRaw(input); - }; - - }, { "pako": 25 }], 10: [function (require, module, exports) { - 'use strict'; - - var base64 = require('./base64'); - - /** - Usage: - zip = new JSZip(); - zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); - zip.folder("images").file("smile.gif", base64Data, {base64: true}); - zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); - zip.remove("tempfile"); - - base64zip = zip.generate(); - - **/ - - /** - * Representation a of zip file in js - * @constructor - * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). - * @param {Object=} options the options for creating this objects (optional). - */ - function JSZip(data, options) { - // if this constructor is used without `new`, it adds `new` before itself: - if (!(this instanceof JSZip)) return new JSZip(data, options); - - // object containing the files : - // { - // "folder/" : {...}, - // "folder/data.txt" : {...} - // } - // NOTE: we use a null prototype because we do not - // want filenames like "toString" coming from a zip file - // to overwrite methods and attributes in a normal Object. - this.files = Object.create(null); - - this.comment = null; - - // Where we are in the hierarchy - this.root = ""; - if (data) { - this.load(data, options); - } - this.clone = function () { - var newObj = new JSZip(); - for (var i in this) { - if (typeof this[i] !== "function") { - newObj[i] = this[i]; - } - } - return newObj; - }; - } - JSZip.prototype = require('./object'); - JSZip.prototype.load = require('./load'); - JSZip.support = require('./support'); - JSZip.defaults = require('./defaults'); - - /** - * @deprecated - * This namespace will be removed in a future version without replacement. - */ - JSZip.utils = require('./deprecatedPublicUtils'); - - JSZip.base64 = { - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - encode: function (input) { - return base64.encode(input); - }, - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - decode: function (input) { - return base64.decode(input); - } - }; - JSZip.compressions = require('./compressions'); - module.exports = JSZip; - - }, { "./base64": 2, "./compressions": 4, "./defaults": 7, "./deprecatedPublicUtils": 8, "./load": 11, "./object": 14, "./support": 18 }], 11: [function (require, module, exports) { - 'use strict'; - var base64 = require('./base64'); - var utf8 = require('./utf8'); - var utils = require('./utils'); - var ZipEntries = require('./zipEntries'); - module.exports = function (data, options) { - var files, zipEntries, i, input; - options = utils.extend(options || {}, { - base64: false, - checkCRC32: false, - optimizedBinaryString: false, - createFolders: false, - decodeFileName: utf8.utf8decode - }); - if (options.base64) { - data = base64.decode(data); - } - - zipEntries = new ZipEntries(data, options); - files = zipEntries.files; - for (i = 0; i < files.length; i++) { - input = files[i]; - this.file(input.fileNameStr, input.decompressed, { - binary: true, - optimizedBinaryString: true, - date: input.date, - dir: input.dir, - comment: input.fileCommentStr.length ? input.fileCommentStr : null, - unixPermissions: input.unixPermissions, - dosPermissions: input.dosPermissions, - createFolders: options.createFolders - }); - } - if (zipEntries.zipComment.length) { - this.comment = zipEntries.zipComment; - } - - return this; - }; - - }, { "./base64": 2, "./utf8": 21, "./utils": 22, "./zipEntries": 23 }], 12: [function (require, module, exports) { - (function (Buffer) { - 'use strict'; - module.exports = function (data, encoding) { - return new Buffer(data, encoding); - }; - module.exports.test = function (b) { - return Buffer.isBuffer(b); - }; - - }).call(this, (typeof Buffer !== "undefined" ? Buffer : undefined)) - }, {}], 13: [function (require, module, exports) { - 'use strict'; - var Uint8ArrayReader = require('./uint8ArrayReader'); - - function NodeBufferReader(data) { - this.data = data; - this.length = this.data.length; - this.index = 0; - this.zero = 0; - } - NodeBufferReader.prototype = new Uint8ArrayReader(); - - /** - * @see DataReader.readData - */ - NodeBufferReader.prototype.readData = function (size) { - this.checkOffset(size); - var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); - this.index += size; - return result; - }; - module.exports = NodeBufferReader; - - }, { "./uint8ArrayReader": 19 }], 14: [function (require, module, exports) { - 'use strict'; - var support = require('./support'); - var utils = require('./utils'); - var crc32 = require('./crc32'); - var signature = require('./signature'); - var defaults = require('./defaults'); - var base64 = require('./base64'); - var compressions = require('./compressions'); - var CompressedObject = require('./compressedObject'); - var nodeBuffer = require('./nodeBuffer'); - var utf8 = require('./utf8'); - var StringWriter = require('./stringWriter'); - var Uint8ArrayWriter = require('./uint8ArrayWriter'); - - /** - * Returns the raw data of a ZipObject, decompress the content if necessary. - * @param {ZipObject} file the file to use. - * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. - */ - var getRawData = function (file) { - if (file._data instanceof CompressedObject) { - file._data = file._data.getContent(); - file.options.binary = true; - file.options.base64 = false; - - if (utils.getTypeOf(file._data) === "uint8array") { - var copy = file._data; - // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. - // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). - file._data = new Uint8Array(copy.length); - // with an empty Uint8Array, Opera fails with a "Offset larger than array size" - if (copy.length !== 0) { - file._data.set(copy, 0); - } - } - } - return file._data; - }; - - /** - * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. - * @param {ZipObject} file the file to use. - * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. - */ - var getBinaryData = function (file) { - var result = getRawData(file), - type = utils.getTypeOf(result); - if (type === "string") { - if (!file.options.binary) { - // unicode text ! - // unicode string => binary string is a painful process, check if we can avoid it. - if (support.nodebuffer) { - return nodeBuffer(result, "utf-8"); - } - } - return file.asBinary(); - } - return result; - }; - - /** - * Transform this._data into a string. - * @param {function} filter a function String -> String, applied if not null on the result. - * @return {String} the string representing this._data. - */ - var dataToString = function (asUTF8) { - var result = getRawData(this); - if (result === null || typeof result === "undefined") { - return ""; - } - // if the data is a base64 string, we decode it before checking the encoding ! - if (this.options.base64) { - result = base64.decode(result); - } - if (asUTF8 && this.options.binary) { - // JSZip.prototype.utf8decode supports arrays as input - // skip to array => string step, utf8decode will do it. - result = out.utf8decode(result); - } - else { - // no utf8 transformation, do the array => string step. - result = utils.transformTo("string", result); - } - - if (!asUTF8 && !this.options.binary) { - result = utils.transformTo("string", out.utf8encode(result)); - } - return result; - }; - /** - * A simple object representing a file in the zip file. - * @constructor - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data - * @param {Object} options the options of the file - */ - var ZipObject = function (name, data, options) { - this.name = name; - this.dir = options.dir; - this.date = options.date; - this.comment = options.comment; - this.unixPermissions = options.unixPermissions; - this.dosPermissions = options.dosPermissions; - - this._data = data; - this.options = options; - - /* - * This object contains initial values for dir and date. - * With them, we can check if the user changed the deprecated metadata in - * `ZipObject#options` or not. - */ - this._initialMetadata = { - dir: options.dir, - date: options.date - }; - }; - - ZipObject.prototype = { - /** - * Return the content as UTF8 string. - * @return {string} the UTF8 string. - */ - asText: function () { - return dataToString.call(this, true); - }, - /** - * Returns the binary content. - * @return {string} the content as binary. - */ - asBinary: function () { - return dataToString.call(this, false); - }, - /** - * Returns the content as a nodejs Buffer. - * @return {Buffer} the content as a Buffer. - */ - asNodeBuffer: function () { - var result = getBinaryData(this); - return utils.transformTo("nodebuffer", result); - }, - /** - * Returns the content as an Uint8Array. - * @return {Uint8Array} the content as an Uint8Array. - */ - asUint8Array: function () { - var result = getBinaryData(this); - return utils.transformTo("uint8array", result); - }, - /** - * Returns the content as an ArrayBuffer. - * @return {ArrayBuffer} the content as an ArrayBufer. - */ - asArrayBuffer: function () { - return this.asUint8Array().buffer; - } - }; - - /** - * Transform an integer into a string in hexadecimal. - * @private - * @param {number} dec the number to convert. - * @param {number} bytes the number of bytes to generate. - * @returns {string} the result. - */ - var decToHex = function (dec, bytes) { - var hex = "", - i; - for (i = 0; i < bytes; i++) { - hex += String.fromCharCode(dec & 0xff); - dec = dec >>> 8; - } - return hex; - }; - - /** - * Transforms the (incomplete) options from the user into the complete - * set of options to create a file. - * @private - * @param {Object} o the options from the user. - * @return {Object} the complete set of options. - */ - var prepareFileAttrs = function (o) { - o = o || {}; - if (o.base64 === true && (o.binary === null || o.binary === undefined)) { - o.binary = true; - } - o = utils.extend(o, defaults); - o.date = o.date || new Date(); - if (o.compression !== null) o.compression = o.compression.toUpperCase(); - - return o; - }; - - /** - * Add a file in the current folder. - * @private - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file - * @param {Object} o the options of the file - * @return {Object} the new file. - */ - var fileAdd = function (name, data, o) { - // be sure sub folders exist - var dataType = utils.getTypeOf(data), - parent; - - o = prepareFileAttrs(o); - - if (typeof o.unixPermissions === "string") { - o.unixPermissions = parseInt(o.unixPermissions, 8); - } - - // UNX_IFDIR 0040000 see zipinfo.c - if (o.unixPermissions && (o.unixPermissions & 0x4000)) { - o.dir = true; - } - // Bit 4 Directory - if (o.dosPermissions && (o.dosPermissions & 0x0010)) { - o.dir = true; - } - - if (o.dir) { - name = forceTrailingSlash(name); - } - - if (o.createFolders && (parent = parentFolder(name))) { - folderAdd.call(this, parent, true); - } - - if (o.dir || data === null || typeof data === "undefined") { - o.base64 = false; - o.binary = false; - data = null; - dataType = null; - } - else if (dataType === "string") { - if (o.binary && !o.base64) { - // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask - if (o.optimizedBinaryString !== true) { - // this is a string, not in a base64 format. - // Be sure that this is a correct "binary string" - data = utils.string2binary(data); - } - } - } - else { // arraybuffer, uint8array, ... - o.base64 = false; - o.binary = true; - - if (!dataType && !(data instanceof CompressedObject)) { - throw new Error("The data of '" + name + "' is in an unsupported format !"); - } - - // special case : it's way easier to work with Uint8Array than with ArrayBuffer - if (dataType === "arraybuffer") { - data = utils.transformTo("uint8array", data); - } - } - - var object = new ZipObject(name, data, o); - this.files[name] = object; - return object; - }; - - /** - * Find the parent folder of the path. - * @private - * @param {string} path the path to use - * @return {string} the parent folder, or "" - */ - var parentFolder = function (path) { - if (path.slice(-1) == '/') { - path = path.substring(0, path.length - 1); - } - var lastSlash = path.lastIndexOf('/'); - return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; - }; - - - /** - * Returns the path with a slash at the end. - * @private - * @param {String} path the path to check. - * @return {String} the path with a trailing slash. - */ - var forceTrailingSlash = function (path) { - // Check the name ends with a / - if (path.slice(-1) != "/") { - path += "/"; // IE doesn't like substr(-1) - } - return path; - }; - /** - * Add a (sub) folder in the current folder. - * @private - * @param {string} name the folder's name - * @param {boolean=} [createFolders] If true, automatically create sub - * folders. Defaults to false. - * @return {Object} the new folder. - */ - var folderAdd = function (name, createFolders) { - createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; - - name = forceTrailingSlash(name); - - // Does this folder already exist? - if (!this.files[name]) { - fileAdd.call(this, name, null, { - dir: true, - createFolders: createFolders - }); - } - return this.files[name]; - }; - - /** - * Generate a JSZip.CompressedObject for a given zipOject. - * @param {ZipObject} file the object to read. - * @param {JSZip.compression} compression the compression to use. - * @param {Object} compressionOptions the options to use when compressing. - * @return {JSZip.CompressedObject} the compressed result. - */ - var generateCompressedObjectFrom = function (file, compression, compressionOptions) { - var result = new CompressedObject(), - content; - - // the data has not been decompressed, we might reuse things ! - if (file._data instanceof CompressedObject) { - result.uncompressedSize = file._data.uncompressedSize; - result.crc32 = file._data.crc32; - - if (result.uncompressedSize === 0 || file.dir) { - compression = compressions['STORE']; - result.compressedContent = ""; - result.crc32 = 0; - } - else if (file._data.compressionMethod === compression.magic) { - result.compressedContent = file._data.getCompressedContent(); - } - else { - content = file._data.getContent(); - // need to decompress / recompress - result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); - } - } - else { - // have uncompressed data - content = getBinaryData(file); - if (!content || content.length === 0 || file.dir) { - compression = compressions['STORE']; - content = ""; - } - result.uncompressedSize = content.length; - result.crc32 = crc32(content); - result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); - } - - result.compressedSize = result.compressedContent.length; - result.compressionMethod = compression.magic; - - return result; - }; - - - - - /** - * Generate the UNIX part of the external file attributes. - * @param {Object} unixPermissions the unix permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : - * - * TTTTsstrwxrwxrwx0000000000ADVSHR - * ^^^^____________________________ file type, see zipinfo.c (UNX_*) - * ^^^_________________________ setuid, setgid, sticky - * ^^^^^^^^^________________ permissions - * ^^^^^^^^^^______ not used ? - * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only - */ - var generateUnixExternalFileAttr = function (unixPermissions, isDir) { - - var result = unixPermissions; - if (!unixPermissions) { - // I can't use octal values in strict mode, hence the hexa. - // 040775 => 0x41fd - // 0100664 => 0x81b4 - result = isDir ? 0x41fd : 0x81b4; - } - - return (result & 0xFFFF) << 16; - }; - - /** - * Generate the DOS part of the external file attributes. - * @param {Object} dosPermissions the dos permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * Bit 0 Read-Only - * Bit 1 Hidden - * Bit 2 System - * Bit 3 Volume Label - * Bit 4 Directory - * Bit 5 Archive - */ - var generateDosExternalFileAttr = function (dosPermissions, isDir) { - - // the dir flag is already set for compatibility - - return (dosPermissions || 0) & 0x3F; - }; - - /** - * Generate the various parts used in the construction of the final zip file. - * @param {string} name the file name. - * @param {ZipObject} file the file content. - * @param {JSZip.CompressedObject} compressedObject the compressed object. - * @param {number} offset the current offset from the start of the zip file. - * @param {String} platform let's pretend we are this platform (change platform dependents fields) - * @param {Function} encodeFileName the function to encode the file name / comment. - * @return {object} the zip parts. - */ - var generateZipParts = function (name, file, compressedObject, offset, platform, encodeFileName) { - var data = compressedObject.compressedContent, - useCustomEncoding = encodeFileName !== utf8.utf8encode, - encodedFileName = utils.transformTo("string", encodeFileName(file.name)), - utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), - comment = file.comment || "", - encodedComment = utils.transformTo("string", encodeFileName(comment)), - utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), - useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, - useUTF8ForComment = utfEncodedComment.length !== comment.length, - o = file.options, - dosTime, - dosDate, - extraFields = "", - unicodePathExtraField = "", - unicodeCommentExtraField = "", - dir, date; - - - // handle the deprecated options.dir - if (file._initialMetadata.dir !== file.dir) { - dir = file.dir; - } else { - dir = o.dir; - } - - // handle the deprecated options.date - if (file._initialMetadata.date !== file.date) { - date = file.date; - } else { - date = o.date; - } - - var extFileAttr = 0; - var versionMadeBy = 0; - if (dir) { - // dos or unix, we set the dos dir flag - extFileAttr |= 0x00010; - } - if (platform === "UNIX") { - versionMadeBy = 0x031E; // UNIX, version 3.0 - extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); - } else { // DOS or other, fallback to DOS - versionMadeBy = 0x0014; // DOS, version 2.0 - extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); - } - - // date - // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html - - dosTime = date.getHours(); - dosTime = dosTime << 6; - dosTime = dosTime | date.getMinutes(); - dosTime = dosTime << 5; - dosTime = dosTime | date.getSeconds() / 2; - - dosDate = date.getFullYear() - 1980; - dosDate = dosDate << 4; - dosDate = dosDate | (date.getMonth() + 1); - dosDate = dosDate << 5; - dosDate = dosDate | date.getDate(); - - if (useUTF8ForFileName) { - // set the unicode path extra field. unzip needs at least one extra - // field to correctly handle unicode path, so using the path is as good - // as any other information. This could improve the situation with - // other archive managers too. - // This field is usually used without the utf8 flag, with a non - // unicode path in the header (winrar, winzip). This helps (a bit) - // with the messy Windows' default compressed folders feature but - // breaks on p7zip which doesn't seek the unicode path extra field. - // So for now, UTF-8 everywhere ! - unicodePathExtraField = - // Version - decToHex(1, 1) + - // NameCRC32 - decToHex(crc32(encodedFileName), 4) + - // UnicodeName - utfEncodedFileName; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x70" + - // size - decToHex(unicodePathExtraField.length, 2) + - // content - unicodePathExtraField; - } - - if (useUTF8ForComment) { - - unicodeCommentExtraField = - // Version - decToHex(1, 1) + - // CommentCRC32 - decToHex(this.crc32(encodedComment), 4) + - // UnicodeName - utfEncodedComment; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x63" + - // size - decToHex(unicodeCommentExtraField.length, 2) + - // content - unicodeCommentExtraField; - } - - var header = ""; - - // version needed to extract - header += "\x0A\x00"; - // general purpose bit flag - // set bit 11 if utf8 - header += !useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; - // compression method - header += compressedObject.compressionMethod; - // last mod file time - header += decToHex(dosTime, 2); - // last mod file date - header += decToHex(dosDate, 2); - // crc-32 - header += decToHex(compressedObject.crc32, 4); - // compressed size - header += decToHex(compressedObject.compressedSize, 4); - // uncompressed size - header += decToHex(compressedObject.uncompressedSize, 4); - // file name length - header += decToHex(encodedFileName.length, 2); - // extra field length - header += decToHex(extraFields.length, 2); - - - var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields; - - var dirRecord = signature.CENTRAL_FILE_HEADER + - // version made by (00: DOS) - decToHex(versionMadeBy, 2) + - // file header (common to file and central directory) - header + - // file comment length - decToHex(encodedComment.length, 2) + - // disk number start - "\x00\x00" + - // internal file attributes TODO - "\x00\x00" + - // external file attributes - decToHex(extFileAttr, 4) + - // relative offset of local header - decToHex(offset, 4) + - // file name - encodedFileName + - // extra field - extraFields + - // file comment - encodedComment; - - return { - fileRecord: fileRecord, - dirRecord: dirRecord, - compressedObject: compressedObject - }; - }; - - - // return the actual prototype of JSZip - var out = { - /** - * Read an existing zip and merge the data in the current JSZip object. - * The implementation is in jszip-load.js, don't forget to include it. - * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load - * @param {Object} options Options for loading the stream. - * options.base64 : is the stream in base64 ? default : false - * @return {JSZip} the current JSZip object - */ - load: function (stream, options) { - throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); - }, - - /** - * Filter nested files/folders with the specified function. - * @param {Function} search the predicate to use : - * function (relativePath, file) {...} - * It takes 2 arguments : the relative path and the file. - * @return {Array} An array of matching elements. - */ - filter: function (search) { - var result = [], - filename, relativePath, file, fileClone; - for (filename in this.files) { - file = this.files[filename]; - // return a new object, don't let the user mess with our internal objects :) - fileClone = new ZipObject(file.name, file._data, utils.extend(file.options)); - relativePath = filename.slice(this.root.length, filename.length); - if (filename.slice(0, this.root.length) === this.root && // the file is in the current root - search(relativePath, fileClone)) { // and the file matches the function - result.push(fileClone); - } - } - return result; - }, - - /** - * Add a file to the zip file, or search a file. - * @param {string|RegExp} name The name of the file to add (if data is defined), - * the name of the file to find (if no data) or a regex to match files. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded - * @param {Object} o File options - * @return {JSZip|Object|Array} this JSZip object (when adding a file), - * a file (when searching by string) or an array of files (when searching by regex). - */ - file: function (name, data, o) { - if (arguments.length === 1) { - if (utils.isRegExp(name)) { - var regexp = name; - return this.filter(function (relativePath, file) { - return !file.dir && regexp.test(relativePath); - }); - } - else { // text - return this.filter(function (relativePath, file) { - return !file.dir && relativePath === name; - })[0] || null; - } - } - else { // more than one argument : we have data ! - name = this.root + name; - fileAdd.call(this, name, data, o); - } - return this; - }, - - /** - * Add a directory to the zip file, or search. - * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. - * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. - */ - folder: function (arg) { - if (!arg) { - return this; - } - - if (utils.isRegExp(arg)) { - return this.filter(function (relativePath, file) { - return file.dir && arg.test(relativePath); - }); - } - - // else, name is a new folder - var name = this.root + arg; - var newFolder = folderAdd.call(this, name); - - // Allow chaining by returning a new object with this folder as the root - var ret = this.clone(); - ret.root = newFolder.name; - return ret; - }, - - /** - * Delete a file, or a directory and all sub-files, from the zip - * @param {string} name the name of the file to delete - * @return {JSZip} this JSZip object - */ - remove: function (name) { - name = this.root + name; - var file = this.files[name]; - if (!file) { - // Look for any folders - if (name.slice(-1) != "/") { - name += "/"; - } - file = this.files[name]; - } - - if (file && !file.dir) { - // file - delete this.files[name]; - } else { - // maybe a folder, delete recursively - var kids = this.filter(function (relativePath, file) { - return file.name.slice(0, name.length) === name; - }); - for (var i = 0; i < kids.length; i++) { - delete this.files[kids[i].name]; - } - } - - return this; - }, - - /** - * Generate the complete zip file - * @param {Object} options the options to generate the zip file : - * - base64, (deprecated, use type instead) true to generate base64. - * - compression, "STORE" by default. - * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. - * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file - */ - generate: function (options) { - options = utils.extend(options || {}, { - base64: true, - compression: "STORE", - compressionOptions: null, - type: "base64", - platform: "DOS", - comment: null, - mimeType: 'application/zip', - encodeFileName: utf8.utf8encode - }); - - utils.checkSupport(options.type); - - // accept nodejs `process.platform` - if ( - options.platform === 'darwin' || - options.platform === 'freebsd' || - options.platform === 'linux' || - options.platform === 'sunos' - ) { - options.platform = "UNIX"; - } - if (options.platform === 'win32') { - options.platform = "DOS"; - } - - var zipData = [], - localDirLength = 0, - centralDirLength = 0, - writer, i, - encodedComment = utils.transformTo("string", options.encodeFileName(options.comment || this.comment || "")); - - // first, generate all the zip parts. - for (var name in this.files) { - var file = this.files[name]; - - var compressionName = file.options.compression || options.compression.toUpperCase(); - var compression = compressions[compressionName]; - if (!compression) { - throw new Error(compressionName + " is not a valid compression method !"); - } - var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; - - var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions); - - var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform, options.encodeFileName); - localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; - centralDirLength += zipPart.dirRecord.length; - zipData.push(zipPart); - } - - var dirEnd = ""; - - // end of central dir signature - dirEnd = signature.CENTRAL_DIRECTORY_END + - // number of this disk - "\x00\x00" + - // number of the disk with the start of the central directory - "\x00\x00" + - // total number of entries in the central directory on this disk - decToHex(zipData.length, 2) + - // total number of entries in the central directory - decToHex(zipData.length, 2) + - // size of the central directory 4 bytes - decToHex(centralDirLength, 4) + - // offset of start of central directory with respect to the starting disk number - decToHex(localDirLength, 4) + - // .ZIP file comment length - decToHex(encodedComment.length, 2) + - // .ZIP file comment - encodedComment; - - - // we have all the parts (and the total length) - // time to create a writer ! - var typeName = options.type.toLowerCase(); - if (typeName === "uint8array" || typeName === "arraybuffer" || typeName === "blob" || typeName === "nodebuffer") { - writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); - } else { - writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); - } - - for (i = 0; i < zipData.length; i++) { - writer.append(zipData[i].fileRecord); - writer.append(zipData[i].compressedObject.compressedContent); - } - for (i = 0; i < zipData.length; i++) { - writer.append(zipData[i].dirRecord); - } - - writer.append(dirEnd); - - var zip = writer.finalize(); - - - - switch (options.type.toLowerCase()) { - // case "zip is an Uint8Array" - case "uint8array": - case "arraybuffer": - case "nodebuffer": - return utils.transformTo(options.type.toLowerCase(), zip); - case "blob": - return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType); - // case "zip is a string" - case "base64": - return (options.base64) ? base64.encode(zip) : zip; - default: // case "string" : - return zip; - } - - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - crc32: function (input, crc) { - return crc32(input, crc); - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - utf8encode: function (string) { - return utils.transformTo("string", utf8.utf8encode(string)); - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - utf8decode: function (input) { - return utf8.utf8decode(input); - } - }; - module.exports = out; - - }, { "./base64": 2, "./compressedObject": 3, "./compressions": 4, "./crc32": 5, "./defaults": 7, "./nodeBuffer": 12, "./signature": 15, "./stringWriter": 17, "./support": 18, "./uint8ArrayWriter": 20, "./utf8": 21, "./utils": 22 }], 15: [function (require, module, exports) { - 'use strict'; - exports.LOCAL_FILE_HEADER = "PK\x03\x04"; - exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; - exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; - exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; - exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; - exports.DATA_DESCRIPTOR = "PK\x07\x08"; - - }, {}], 16: [function (require, module, exports) { - 'use strict'; - var DataReader = require('./dataReader'); - var utils = require('./utils'); - - function StringReader(data, optimizedBinaryString) { - this.data = data; - if (!optimizedBinaryString) { - this.data = utils.string2binary(this.data); - } - this.length = this.data.length; - this.index = 0; - this.zero = 0; - } - StringReader.prototype = new DataReader(); - /** - * @see DataReader.byteAt - */ - StringReader.prototype.byteAt = function (i) { - return this.data.charCodeAt(this.zero + i); - }; - /** - * @see DataReader.lastIndexOfSignature - */ - StringReader.prototype.lastIndexOfSignature = function (sig) { - return this.data.lastIndexOf(sig) - this.zero; - }; - /** - * @see DataReader.readData - */ - StringReader.prototype.readData = function (size) { - this.checkOffset(size); - // this will work because the constructor applied the "& 0xff" mask. - var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); - this.index += size; - return result; - }; - module.exports = StringReader; - - }, { "./dataReader": 6, "./utils": 22 }], 17: [function (require, module, exports) { - 'use strict'; - - var utils = require('./utils'); - - /** - * An object to write any content to a string. - * @constructor - */ - var StringWriter = function () { - this.data = []; - }; - StringWriter.prototype = { - /** - * Append any content to the current string. - * @param {Object} input the content to add. - */ - append: function (input) { - input = utils.transformTo("string", input); - this.data.push(input); - }, - /** - * Finalize the construction an return the result. - * @return {string} the generated string. - */ - finalize: function () { - return this.data.join(""); - } - }; - - module.exports = StringWriter; - - }, { "./utils": 22 }], 18: [function (require, module, exports) { - (function (Buffer) { - 'use strict'; - exports.base64 = true; - exports.array = true; - exports.string = true; - exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; - // contains true if JSZip can read/generate nodejs Buffer, false otherwise. - // Browserify will provide a Buffer implementation for browsers, which is - // an augmented Uint8Array (i.e., can be used as either Buffer or U8). - exports.nodebuffer = typeof Buffer !== "undefined"; - // contains true if JSZip can read/generate Uint8Array, false otherwise. - exports.uint8array = typeof Uint8Array !== "undefined"; - - if (typeof ArrayBuffer === "undefined") { - exports.blob = false; - } - else { - var buffer = new ArrayBuffer(0); - try { - exports.blob = new Blob([buffer], { - type: "application/zip" - }).size === 0; - } - catch (e) { - try { - var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; - var builder = new Builder(); - builder.append(buffer); - exports.blob = builder.getBlob('application/zip').size === 0; - } - catch (e) { - exports.blob = false; - } - } - } - - }).call(this, (typeof Buffer !== "undefined" ? Buffer : undefined)) - }, {}], 19: [function (require, module, exports) { - 'use strict'; - var ArrayReader = require('./arrayReader'); - - function Uint8ArrayReader(data) { - if (data) { - this.data = data; - this.length = this.data.length; - this.index = 0; - this.zero = 0; - } - } - Uint8ArrayReader.prototype = new ArrayReader(); - /** - * @see DataReader.readData - */ - Uint8ArrayReader.prototype.readData = function (size) { - this.checkOffset(size); - if (size === 0) { - // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. - return new Uint8Array(0); - } - var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size); - this.index += size; - return result; - }; - module.exports = Uint8ArrayReader; - - }, { "./arrayReader": 1 }], 20: [function (require, module, exports) { - 'use strict'; - - var utils = require('./utils'); - - /** - * An object to write any content to an Uint8Array. - * @constructor - * @param {number} length The length of the array. - */ - var Uint8ArrayWriter = function (length) { - this.data = new Uint8Array(length); - this.index = 0; - }; - Uint8ArrayWriter.prototype = { - /** - * Append any content to the current array. - * @param {Object} input the content to add. - */ - append: function (input) { - if (input.length !== 0) { - // with an empty Uint8Array, Opera fails with a "Offset larger than array size" - input = utils.transformTo("uint8array", input); - this.data.set(input, this.index); - this.index += input.length; - } - }, - /** - * Finalize the construction an return the result. - * @return {Uint8Array} the generated array. - */ - finalize: function () { - return this.data; - } - }; - - module.exports = Uint8ArrayWriter; - - }, { "./utils": 22 }], 21: [function (require, module, exports) { - 'use strict'; - - var utils = require('./utils'); - var support = require('./support'); - var nodeBuffer = require('./nodeBuffer'); - - /** - * The following functions come from pako, from pako/lib/utils/strings - * released under the MIT license, see pako https://github.com/nodeca/pako/ - */ - - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - var _utf8len = new Array(256); - for (var i = 0; i < 256; i++) { - _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); - } - _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start - - // convert string to array (typed, when possible) - var string2buf = function (str) { - var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - if (support.uint8array) { - buf = new Uint8Array(buf_len); - } else { - buf = new Array(buf_len); - } - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; - }; - - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - var utf8border = function (buf, max) { - var pos; - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Fuckup - very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means vuffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len[buf[pos]] > max) ? pos : max; - }; - - // convert array to string - var buf2string = function (buf) { - var str, i, out, c, c_len; - var len = buf.length; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - var utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - c_len = _utf8len[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - // shrinkBuf(utf16buf, out) - if (utf16buf.length !== out) { - if (utf16buf.subarray) { - utf16buf = utf16buf.subarray(0, out); - } else { - utf16buf.length = out; - } - } - - // return String.fromCharCode.apply(null, utf16buf); - return utils.applyFromCharCode(utf16buf); - }; - - - // That's all for the pako functions. - - - /** - * Transform a javascript string into an array (typed if possible) of bytes, - * UTF-8 encoded. - * @param {String} str the string to encode - * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. - */ - exports.utf8encode = function utf8encode(str) { - if (support.nodebuffer) { - return nodeBuffer(str, "utf-8"); - } - - return string2buf(str); - }; - - - /** - * Transform a bytes array (or a representation) representing an UTF-8 encoded - * string into a javascript string. - * @param {Array|Uint8Array|Buffer} buf the data de decode - * @return {String} the decoded string. - */ - exports.utf8decode = function utf8decode(buf) { - if (support.nodebuffer) { - return utils.transformTo("nodebuffer", buf).toString("utf-8"); - } - - buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); - - // return buf2string(buf); - // Chrome prefers to work with "small" chunks of data - // for the method buf2string. - // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. - var result = [], k = 0, len = buf.length, chunk = 65536; - while (k < len) { - var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); - if (support.uint8array) { - result.push(buf2string(buf.subarray(k, nextBoundary))); - } else { - result.push(buf2string(buf.slice(k, nextBoundary))); - } - k = nextBoundary; - } - return result.join(""); - - }; - // vim: set shiftwidth=4 softtabstop=4: - - }, { "./nodeBuffer": 12, "./support": 18, "./utils": 22 }], 22: [function (require, module, exports) { - 'use strict'; - var support = require('./support'); - var compressions = require('./compressions'); - var nodeBuffer = require('./nodeBuffer'); - /** - * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. - * @param {string} str the string to transform. - * @return {String} the binary string. - */ - exports.string2binary = function (str) { - var result = ""; - for (var i = 0; i < str.length; i++) { - result += String.fromCharCode(str.charCodeAt(i) & 0xff); - } - return result; - }; - exports.arrayBuffer2Blob = function (buffer, mimeType) { - exports.checkSupport("blob"); - mimeType = mimeType || 'application/zip'; - - try { - // Blob constructor - return new Blob([buffer], { - type: mimeType - }); - } - catch (e) { - - try { - // deprecated, browser only, old way - var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; - var builder = new Builder(); - builder.append(buffer); - return builder.getBlob(mimeType); - } - catch (e) { - - // well, fuck ?! - throw new Error("Bug : can't construct the Blob."); - } - } - - - }; - /** - * The identity function. - * @param {Object} input the input. - * @return {Object} the same input. - */ - function identity(input) { - return input; - } - - /** - * Fill in an array with a string. - * @param {String} str the string to use. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). - * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. - */ - function stringToArrayLike(str, array) { - for (var i = 0; i < str.length; ++i) { - array[i] = str.charCodeAt(i) & 0xFF; - } - return array; - } - - /** - * Transform an array-like object to a string. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. - * @return {String} the result. - */ - function arrayLikeToString(array) { - // Performances notes : - // -------------------- - // String.fromCharCode.apply(null, array) is the fastest, see - // see http://jsperf.com/converting-a-uint8array-to-a-string/2 - // but the stack is limited (and we can get huge arrays !). - // - // result += String.fromCharCode(array[i]); generate too many strings ! - // - // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 - var chunk = 65536; - var result = [], - len = array.length, - type = exports.getTypeOf(array), - k = 0, - canUseApply = true; - try { - switch (type) { - case "uint8array": - String.fromCharCode.apply(null, new Uint8Array(0)); - break; - case "nodebuffer": - String.fromCharCode.apply(null, nodeBuffer(0)); - break; - } - } catch (e) { - canUseApply = false; - } - - // no apply : slow and painful algorithm - // default browser on android 4.* - if (!canUseApply) { - var resultStr = ""; - for (var i = 0; i < array.length; i++) { - resultStr += String.fromCharCode(array[i]); - } - return resultStr; - } - while (k < len && chunk > 1) { - try { - if (type === "array" || type === "nodebuffer") { - result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); - } - else { - result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); - } - k += chunk; - } - catch (e) { - chunk = Math.floor(chunk / 2); - } - } - return result.join(""); - } - - exports.applyFromCharCode = arrayLikeToString; - - - /** - * Copy the data from an array-like to an other array-like. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. - * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. - */ - function arrayLikeToArrayLike(arrayFrom, arrayTo) { - for (var i = 0; i < arrayFrom.length; i++) { - arrayTo[i] = arrayFrom[i]; - } - return arrayTo; - } - - // a matrix containing functions to transform everything into everything. - var transform = {}; - - // string to ? - transform["string"] = { - "string": identity, - "array": function (input) { - return stringToArrayLike(input, new Array(input.length)); - }, - "arraybuffer": function (input) { - return transform["string"]["uint8array"](input).buffer; - }, - "uint8array": function (input) { - return stringToArrayLike(input, new Uint8Array(input.length)); - }, - "nodebuffer": function (input) { - return stringToArrayLike(input, nodeBuffer(input.length)); - } - }; - - // array to ? - transform["array"] = { - "string": arrayLikeToString, - "array": identity, - "arraybuffer": function (input) { - return (new Uint8Array(input)).buffer; - }, - "uint8array": function (input) { - return new Uint8Array(input); - }, - "nodebuffer": function (input) { - return nodeBuffer(input); - } - }; - - // arraybuffer to ? - transform["arraybuffer"] = { - "string": function (input) { - return arrayLikeToString(new Uint8Array(input)); - }, - "array": function (input) { - return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); - }, - "arraybuffer": identity, - "uint8array": function (input) { - return new Uint8Array(input); - }, - "nodebuffer": function (input) { - return nodeBuffer(new Uint8Array(input)); - } - }; - - // uint8array to ? - transform["uint8array"] = { - "string": arrayLikeToString, - "array": function (input) { - return arrayLikeToArrayLike(input, new Array(input.length)); - }, - "arraybuffer": function (input) { - return input.buffer; - }, - "uint8array": identity, - "nodebuffer": function (input) { - return nodeBuffer(input); - } - }; - - // nodebuffer to ? - transform["nodebuffer"] = { - "string": arrayLikeToString, - "array": function (input) { - return arrayLikeToArrayLike(input, new Array(input.length)); - }, - "arraybuffer": function (input) { - return transform["nodebuffer"]["uint8array"](input).buffer; - }, - "uint8array": function (input) { - return arrayLikeToArrayLike(input, new Uint8Array(input.length)); - }, - "nodebuffer": identity - }; - - /** - * Transform an input into any type. - * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. - * If no output type is specified, the unmodified input will be returned. - * @param {String} outputType the output type. - * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. - * @throws {Error} an Error if the browser doesn't support the requested output type. - */ - exports.transformTo = function (outputType, input) { - if (!input) { - // undefined, null, etc - // an empty string won't harm. - input = ""; - } - if (!outputType) { - return input; - } - exports.checkSupport(outputType); - var inputType = exports.getTypeOf(input); - var result = transform[inputType][outputType](input); - return result; - }; - - /** - * Return the type of the input. - * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. - * @param {Object} input the input to identify. - * @return {String} the (lowercase) type of the input. - */ - exports.getTypeOf = function (input) { - if (typeof input === "string") { - return "string"; - } - if (Object.prototype.toString.call(input) === "[object Array]") { - return "array"; - } - if (support.nodebuffer && nodeBuffer.test(input)) { - return "nodebuffer"; - } - if (support.uint8array && input instanceof Uint8Array) { - return "uint8array"; - } - if (support.arraybuffer && input instanceof ArrayBuffer) { - return "arraybuffer"; - } - }; - - /** - * Throw an exception if the type is not supported. - * @param {String} type the type to check. - * @throws {Error} an Error if the browser doesn't support the requested type. - */ - exports.checkSupport = function (type) { - var supported = support[type.toLowerCase()]; - if (!supported) { - throw new Error(type + " is not supported by this browser"); - } - }; - exports.MAX_VALUE_16BITS = 65535; - exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 - - /** - * Prettify a string read as binary. - * @param {string} str the string to prettify. - * @return {string} a pretty string. - */ - exports.pretty = function (str) { - var res = '', - code, i; - for (i = 0; i < (str || "").length; i++) { - code = str.charCodeAt(i); - res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); - } - return res; - }; - - /** - * Find a compression registered in JSZip. - * @param {string} compressionMethod the method magic to find. - * @return {Object|null} the JSZip compression object, null if none found. - */ - exports.findCompression = function (compressionMethod) { - for (var method in compressions) { - if (!compressions.hasOwnProperty(method)) { - continue; - } - if (compressions[method].magic === compressionMethod) { - return compressions[method]; - } - } - return null; - }; - /** - * Cross-window, cross-Node-context regular expression detection - * @param {Object} object Anything - * @return {Boolean} true if the object is a regular expression, - * false otherwise - */ - exports.isRegExp = function (object) { - return Object.prototype.toString.call(object) === "[object RegExp]"; - }; - - /** - * Merge the objects passed as parameters into a new one. - * @private - * @param {...Object} var_args All objects to merge. - * @return {Object} a new object with the data of the others. - */ - exports.extend = function () { - var result = {}, i, attr; - for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers - for (attr in arguments[i]) { - if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { - result[attr] = arguments[i][attr]; - } - } - } - return result; - }; - - - }, { "./compressions": 4, "./nodeBuffer": 12, "./support": 18 }], 23: [function (require, module, exports) { - 'use strict'; - var StringReader = require('./stringReader'); - var NodeBufferReader = require('./nodeBufferReader'); - var Uint8ArrayReader = require('./uint8ArrayReader'); - var ArrayReader = require('./arrayReader'); - var utils = require('./utils'); - var sig = require('./signature'); - var ZipEntry = require('./zipEntry'); - var support = require('./support'); - var jszipProto = require('./object'); - // class ZipEntries {{{ - /** - * All the entries in the zip file. - * @constructor - * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. - * @param {Object} loadOptions Options for loading the stream. - */ - function ZipEntries(data, loadOptions) { - this.files = []; - this.loadOptions = loadOptions; - if (data) { - this.load(data); - } - } - ZipEntries.prototype = { - /** - * Check that the reader is on the speficied signature. - * @param {string} expectedSignature the expected signature. - * @throws {Error} if it is an other signature. - */ - checkSignature: function (expectedSignature) { - var signature = this.reader.readString(4); - if (signature !== expectedSignature) { - throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); - } - }, - /** - * Check if the given signature is at the given index. - * @param {number} askedIndex the index to check. - * @param {string} expectedSignature the signature to expect. - * @return {boolean} true if the signature is here, false otherwise. - */ - isSignature: function (askedIndex, expectedSignature) { - var currentIndex = this.reader.index; - this.reader.setIndex(askedIndex); - var signature = this.reader.readString(4); - var result = signature === expectedSignature; - this.reader.setIndex(currentIndex); - return result; - }, - /** - * Read the end of the central directory. - */ - readBlockEndOfCentral: function () { - this.diskNumber = this.reader.readInt(2); - this.diskWithCentralDirStart = this.reader.readInt(2); - this.centralDirRecordsOnThisDisk = this.reader.readInt(2); - this.centralDirRecords = this.reader.readInt(2); - this.centralDirSize = this.reader.readInt(4); - this.centralDirOffset = this.reader.readInt(4); - - this.zipCommentLength = this.reader.readInt(2); - // warning : the encoding depends of the system locale - // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. - // On a windows machine, this field is encoded with the localized windows code page. - var zipComment = this.reader.readData(this.zipCommentLength); - var decodeParamType = support.uint8array ? "uint8array" : "array"; - // To get consistent behavior with the generation part, we will assume that - // this is utf8 encoded unless specified otherwise. - var decodeContent = utils.transformTo(decodeParamType, zipComment); - this.zipComment = this.loadOptions.decodeFileName(decodeContent); - }, - /** - * Read the end of the Zip 64 central directory. - * Not merged with the method readEndOfCentral : - * The end of central can coexist with its Zip64 brother, - * I don't want to read the wrong number of bytes ! - */ - readBlockZip64EndOfCentral: function () { - this.zip64EndOfCentralSize = this.reader.readInt(8); - this.versionMadeBy = this.reader.readString(2); - this.versionNeeded = this.reader.readInt(2); - this.diskNumber = this.reader.readInt(4); - this.diskWithCentralDirStart = this.reader.readInt(4); - this.centralDirRecordsOnThisDisk = this.reader.readInt(8); - this.centralDirRecords = this.reader.readInt(8); - this.centralDirSize = this.reader.readInt(8); - this.centralDirOffset = this.reader.readInt(8); - - this.zip64ExtensibleData = {}; - var extraDataSize = this.zip64EndOfCentralSize - 44, - index = 0, - extraFieldId, - extraFieldLength, - extraFieldValue; - while (index < extraDataSize) { - extraFieldId = this.reader.readInt(2); - extraFieldLength = this.reader.readInt(4); - extraFieldValue = this.reader.readString(extraFieldLength); - this.zip64ExtensibleData[extraFieldId] = { - id: extraFieldId, - length: extraFieldLength, - value: extraFieldValue - }; - } - }, - /** - * Read the end of the Zip 64 central directory locator. - */ - readBlockZip64EndOfCentralLocator: function () { - this.diskWithZip64CentralDirStart = this.reader.readInt(4); - this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); - this.disksCount = this.reader.readInt(4); - if (this.disksCount > 1) { - throw new Error("Multi-volumes zip are not supported"); - } - }, - /** - * Read the local files, based on the offset read in the central part. - */ - readLocalFiles: function () { - var i, file; - for (i = 0; i < this.files.length; i++) { - file = this.files[i]; - this.reader.setIndex(file.localHeaderOffset); - this.checkSignature(sig.LOCAL_FILE_HEADER); - file.readLocalPart(this.reader); - file.handleUTF8(); - file.processAttributes(); - } - }, - /** - * Read the central directory. - */ - readCentralDir: function () { - var file; - - this.reader.setIndex(this.centralDirOffset); - while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { - file = new ZipEntry({ - zip64: this.zip64 - }, this.loadOptions); - file.readCentralPart(this.reader); - this.files.push(file); - } - - if (this.centralDirRecords !== this.files.length) { - if (this.centralDirRecords !== 0 && this.files.length === 0) { - // We expected some records but couldn't find ANY. - // This is really suspicious, as if something went wrong. - throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); - } else { - // We found some records but not all. - // Something is wrong but we got something for the user: no error here. - // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); - } - } - }, - /** - * Read the end of central directory. - */ - readEndOfCentral: function () { - var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); - if (offset < 0) { - // Check if the content is a truncated zip or complete garbage. - // A "LOCAL_FILE_HEADER" is not required at the beginning (auto - // extractible zip for example) but it can give a good hint. - // If an ajax request was used without responseType, we will also - // get unreadable data. - var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); - - if (isGarbage) { - throw new Error("Can't find end of central directory : is this a zip file ? " + - "If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html"); - } else { - throw new Error("Corrupted zip : can't find end of central directory"); - } - } - this.reader.setIndex(offset); - var endOfCentralDirOffset = offset; - this.checkSignature(sig.CENTRAL_DIRECTORY_END); - this.readBlockEndOfCentral(); - - - /* extract from the zip spec : - 4) If one of the fields in the end of central directory - record is too small to hold required data, the field - should be set to -1 (0xFFFF or 0xFFFFFFFF) and the - ZIP64 format record should be created. - 5) The end of central directory record and the - Zip64 end of central directory locator record must - reside on the same disk when splitting or spanning - an archive. - */ - if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { - this.zip64 = true; - - /* - Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from - the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents - all numbers as 64-bit double precision IEEE 754 floating point numbers. - So, we have 53bits for integers and bitwise operations treat everything as 32bits. - see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators - and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 - */ - - // should look for a zip64 EOCD locator - offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); - if (offset < 0) { - throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); - } - this.reader.setIndex(offset); - this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); - this.readBlockZip64EndOfCentralLocator(); - - // now the zip64 EOCD record - if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) { - // console.warn("ZIP64 end of central directory not where expected."); - this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); - if (this.relativeOffsetEndOfZip64CentralDir < 0) { - throw new Error("Corrupted zip : can't find the ZIP64 end of central directory"); - } - } - this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); - this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); - this.readBlockZip64EndOfCentral(); - } - - var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize; - if (this.zip64) { - expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator - expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize; - } - - var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset; - - if (extraBytes > 0) { - // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); - if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) { - // The offsets seem wrong, but we have something at the specified offset. - // So… we keep it. - } else { - // the offset is wrong, update the "zero" of the reader - // this happens if data has been prepended (crx files for example) - this.reader.zero = extraBytes; - } - } else if (extraBytes < 0) { - throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes."); - } - }, - prepareReader: function (data) { - var type = utils.getTypeOf(data); - utils.checkSupport(type); - if (type === "string" && !support.uint8array) { - this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); - } - else if (type === "nodebuffer") { - this.reader = new NodeBufferReader(data); - } - else if (support.uint8array) { - this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); - } else if (support.array) { - this.reader = new ArrayReader(utils.transformTo("array", data)); - } else { - throw new Error("Unexpected error: unsupported type '" + type + "'"); - } - }, - /** - * Read a zip file and create ZipEntries. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. - */ - load: function (data) { - this.prepareReader(data); - this.readEndOfCentral(); - this.readCentralDir(); - this.readLocalFiles(); - } - }; - // }}} end of ZipEntries - module.exports = ZipEntries; - - }, { "./arrayReader": 1, "./nodeBufferReader": 13, "./object": 14, "./signature": 15, "./stringReader": 16, "./support": 18, "./uint8ArrayReader": 19, "./utils": 22, "./zipEntry": 24 }], 24: [function (require, module, exports) { - 'use strict'; - var StringReader = require('./stringReader'); - var utils = require('./utils'); - var CompressedObject = require('./compressedObject'); - var jszipProto = require('./object'); - var support = require('./support'); - - var MADE_BY_DOS = 0x00; - var MADE_BY_UNIX = 0x03; - - // class ZipEntry {{{ - /** - * An entry in the zip file. - * @constructor - * @param {Object} options Options of the current file. - * @param {Object} loadOptions Options for loading the stream. - */ - function ZipEntry(options, loadOptions) { - this.options = options; - this.loadOptions = loadOptions; - } - ZipEntry.prototype = { - /** - * say if the file is encrypted. - * @return {boolean} true if the file is encrypted, false otherwise. - */ - isEncrypted: function () { - // bit 1 is set - return (this.bitFlag & 0x0001) === 0x0001; - }, - /** - * say if the file has utf-8 filename/comment. - * @return {boolean} true if the filename/comment is in utf-8, false otherwise. - */ - useUTF8: function () { - // bit 11 is set - return (this.bitFlag & 0x0800) === 0x0800; - }, - /** - * Prepare the function used to generate the compressed content from this ZipFile. - * @param {DataReader} reader the reader to use. - * @param {number} from the offset from where we should read the data. - * @param {number} length the length of the data to read. - * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). - */ - prepareCompressedContent: function (reader, from, length) { - return function () { - var previousIndex = reader.index; - reader.setIndex(from); - var compressedFileData = reader.readData(length); - reader.setIndex(previousIndex); - - return compressedFileData; - }; - }, - /** - * Prepare the function used to generate the uncompressed content from this ZipFile. - * @param {DataReader} reader the reader to use. - * @param {number} from the offset from where we should read the data. - * @param {number} length the length of the data to read. - * @param {JSZip.compression} compression the compression used on this file. - * @param {number} uncompressedSize the uncompressed size to expect. - * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). - */ - prepareContent: function (reader, from, length, compression, uncompressedSize) { - return function () { - - var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); - var uncompressedFileData = compression.uncompress(compressedFileData); - - if (uncompressedFileData.length !== uncompressedSize) { - throw new Error("Bug : uncompressed data size mismatch"); - } - - return uncompressedFileData; - }; - }, - /** - * Read the local part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readLocalPart: function (reader) { - var compression, localExtraFieldsLength; - - // we already know everything from the central dir ! - // If the central dir data are false, we are doomed. - // On the bright side, the local part is scary : zip64, data descriptors, both, etc. - // The less data we get here, the more reliable this should be. - // Let's skip the whole header and dash to the data ! - reader.skip(22); - // in some zip created on windows, the filename stored in the central dir contains \ instead of /. - // Strangely, the filename here is OK. - // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes - // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... - // Search "unzip mismatching "local" filename continuing with "central" filename version" on - // the internet. - // - // I think I see the logic here : the central directory is used to display - // content and the local directory is used to extract the files. Mixing / and \ - // may be used to display \ to windows users and use / when extracting the files. - // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 - this.fileNameLength = reader.readInt(2); - localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir - this.fileName = reader.readData(this.fileNameLength); - reader.skip(localExtraFieldsLength); - - if (this.compressedSize == -1 || this.uncompressedSize == -1) { - throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); - } - - compression = utils.findCompression(this.compressionMethod); - if (compression === null) { // no compression found - throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); - } - this.decompressed = new CompressedObject(); - this.decompressed.compressedSize = this.compressedSize; - this.decompressed.uncompressedSize = this.uncompressedSize; - this.decompressed.crc32 = this.crc32; - this.decompressed.compressionMethod = this.compressionMethod; - this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); - this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); - - // we need to compute the crc32... - if (this.loadOptions.checkCRC32) { - this.decompressed = utils.transformTo("string", this.decompressed.getContent()); - if (jszipProto.crc32(this.decompressed) !== this.crc32) { - throw new Error("Corrupted zip : CRC32 mismatch"); - } - } - }, - - /** - * Read the central part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readCentralPart: function (reader) { - this.versionMadeBy = reader.readInt(2); - this.versionNeeded = reader.readInt(2); - this.bitFlag = reader.readInt(2); - this.compressionMethod = reader.readString(2); - this.date = reader.readDate(); - this.crc32 = reader.readInt(4); - this.compressedSize = reader.readInt(4); - this.uncompressedSize = reader.readInt(4); - this.fileNameLength = reader.readInt(2); - this.extraFieldsLength = reader.readInt(2); - this.fileCommentLength = reader.readInt(2); - this.diskNumberStart = reader.readInt(2); - this.internalFileAttributes = reader.readInt(2); - this.externalFileAttributes = reader.readInt(4); - this.localHeaderOffset = reader.readInt(4); - - if (this.isEncrypted()) { - throw new Error("Encrypted zip are not supported"); - } - - this.fileName = reader.readData(this.fileNameLength); - this.readExtraFields(reader); - this.parseZIP64ExtraField(reader); - this.fileComment = reader.readData(this.fileCommentLength); - }, - - /** - * Parse the external file attributes and get the unix/dos permissions. - */ - processAttributes: function () { - this.unixPermissions = null; - this.dosPermissions = null; - var madeBy = this.versionMadeBy >> 8; - - // Check if we have the DOS directory flag set. - // We look for it in the DOS and UNIX permissions - // but some unknown platform could set it as a compatibility flag. - this.dir = this.externalFileAttributes & 0x0010 ? true : false; - - if (madeBy === MADE_BY_DOS) { - // first 6 bits (0 to 5) - this.dosPermissions = this.externalFileAttributes & 0x3F; - } - - if (madeBy === MADE_BY_UNIX) { - this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; - // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); - } - - // fail safe : if the name ends with a / it probably means a folder - if (!this.dir && this.fileNameStr.slice(-1) === '/') { - this.dir = true; - } - }, - - /** - * Parse the ZIP64 extra field and merge the info in the current ZipEntry. - * @param {DataReader} reader the reader to use. - */ - parseZIP64ExtraField: function (reader) { - - if (!this.extraFields[0x0001]) { - return; - } - - // should be something, preparing the extra reader - var extraReader = new StringReader(this.extraFields[0x0001].value); - - // I really hope that these 64bits integer can fit in 32 bits integer, because js - // won't let us have more. - if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { - this.uncompressedSize = extraReader.readInt(8); - } - if (this.compressedSize === utils.MAX_VALUE_32BITS) { - this.compressedSize = extraReader.readInt(8); - } - if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { - this.localHeaderOffset = extraReader.readInt(8); - } - if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { - this.diskNumberStart = extraReader.readInt(4); - } - }, - /** - * Read the central part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readExtraFields: function (reader) { - var start = reader.index, - extraFieldId, - extraFieldLength, - extraFieldValue; - - this.extraFields = this.extraFields || {}; - - while (reader.index < start + this.extraFieldsLength) { - extraFieldId = reader.readInt(2); - extraFieldLength = reader.readInt(2); - extraFieldValue = reader.readString(extraFieldLength); - - this.extraFields[extraFieldId] = { - id: extraFieldId, - length: extraFieldLength, - value: extraFieldValue - }; - } - }, - /** - * Apply an UTF8 transformation if needed. - */ - handleUTF8: function () { - var decodeParamType = support.uint8array ? "uint8array" : "array"; - if (this.useUTF8()) { - this.fileNameStr = jszipProto.utf8decode(this.fileName); - this.fileCommentStr = jszipProto.utf8decode(this.fileComment); - } else { - var upath = this.findExtraFieldUnicodePath(); - if (upath !== null) { - this.fileNameStr = upath; - } else { - var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); - this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); - } - - var ucomment = this.findExtraFieldUnicodeComment(); - if (ucomment !== null) { - this.fileCommentStr = ucomment; - } else { - var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); - this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); - } - } - }, - - /** - * Find the unicode path declared in the extra field, if any. - * @return {String} the unicode path, null otherwise. - */ - findExtraFieldUnicodePath: function () { - var upathField = this.extraFields[0x7075]; - if (upathField) { - var extraReader = new StringReader(upathField.value); - - // wrong version - if (extraReader.readInt(1) !== 1) { - return null; - } - - // the crc of the filename changed, this field is out of date. - if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { - return null; - } - - return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); - } - return null; - }, - - /** - * Find the unicode comment declared in the extra field, if any. - * @return {String} the unicode comment, null otherwise. - */ - findExtraFieldUnicodeComment: function () { - var ucommentField = this.extraFields[0x6375]; - if (ucommentField) { - var extraReader = new StringReader(ucommentField.value); - - // wrong version - if (extraReader.readInt(1) !== 1) { - return null; - } - - // the crc of the comment changed, this field is out of date. - if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { - return null; - } - - return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); - } - return null; - } - }; - module.exports = ZipEntry; - - }, { "./compressedObject": 3, "./object": 14, "./stringReader": 16, "./support": 18, "./utils": 22 }], 25: [function (require, module, exports) { - // Top level file is just a mixin of submodules & constants - 'use strict'; - - var assign = require('./lib/utils/common').assign; - - var deflate = require('./lib/deflate'); - var inflate = require('./lib/inflate'); - var constants = require('./lib/zlib/constants'); - - var pako = {}; - - assign(pako, deflate, inflate, constants); - - module.exports = pako; - - }, { "./lib/deflate": 26, "./lib/inflate": 27, "./lib/utils/common": 28, "./lib/zlib/constants": 31 }], 26: [function (require, module, exports) { - 'use strict'; - - - var zlib_deflate = require('./zlib/deflate'); - var utils = require('./utils/common'); - var strings = require('./utils/strings'); - var msg = require('./zlib/messages'); - var ZStream = require('./zlib/zstream'); - - var toString = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - var Z_NO_FLUSH = 0; - var Z_FINISH = 4; - - var Z_OK = 0; - var Z_STREAM_END = 1; - var Z_SYNC_FLUSH = 2; - - var Z_DEFAULT_COMPRESSION = -1; - - var Z_DEFAULT_STRATEGY = 0; - - var Z_DEFLATED = 8; - - /* ===========================================================================*/ - - - /** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - - /* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - - /** - * Deflate.result -> Uint8Array|Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you - * push a chunk with explicit flush (call [[Deflate#push]] with - * `Z_SYNC_FLUSH` param). - **/ - - /** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - - /** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - - /** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `to` (String) - if equal to 'string', then result will be "binary string" - * (each char code [0..255]) - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * var deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ - function Deflate(options) { - if (!(this instanceof Deflate)) return new Deflate(options); - - this.options = utils.assign({ - level: Z_DEFAULT_COMPRESSION, - method: Z_DEFLATED, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY, - to: '' - }, options || {}); - - var opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new ZStream(); - this.strm.avail_out = 0; - - var status = zlib_deflate.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK) { - throw new Error(msg[status]); - } - - if (opt.header) { - zlib_deflate.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - var dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings.string2buf(opt.dictionary); - } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = zlib_deflate.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK) { - throw new Error(msg[status]); - } - - this._dict_set = true; - } - } - - /** - * Deflate#push(data[, mode]) -> Boolean - * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must have - * mode Z_FINISH (or `true`). That will flush internal pending buffers and call - * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you - * can use mode Z_SYNC_FLUSH, keeping the compression context. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * We strongly recommend to use `Uint8Array` on input for best speed (output - * array format is detected automatically). Also, don't skip last param and always - * use the same type in your code (boolean or number). That will improve JS speed. - * - * For regular `Array`-s make sure all elements are [0..255]. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Deflate.prototype.push = function (data, mode) { - var strm = this.strm; - var chunkSize = this.options.chunkSize; - var status, _mode; - - if (this.ended) { return false; } - - _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH); - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings.string2buf(data); - } else if (toString.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - do { - if (strm.avail_out === 0) { - strm.output = new utils.Buf8(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ - - if (status !== Z_STREAM_END && status !== Z_OK) { - this.onEnd(status); - this.ended = true; - return false; - } - if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) { - if (this.options.to === 'string') { - this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); - } else { - this.onData(utils.shrinkBuf(strm.output, strm.next_out)); - } - } - } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END); - - // Finalize on the last chunk. - if (_mode === Z_FINISH) { - status = zlib_deflate.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK; - } - - // callback interim results if Z_SYNC_FLUSH. - if (_mode === Z_SYNC_FLUSH) { - this.onEnd(Z_OK); - strm.avail_out = 0; - return true; - } - - return true; - }; - - - /** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array|Array|String): output data. Type of array depends - * on js engine support. When string output requested, each chunk - * will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Deflate.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) - * or if an error happened. By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Deflate.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = utils.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * deflate(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be "binary string" - * (each char code [0..255]) - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ - function deflate(input, options) { - var deflator = new Deflate(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || msg[deflator.err]; } - - return deflator.result; - } - - - /** - * deflateRaw(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function deflateRaw(input, options) { - options = options || {}; - options.raw = true; - return deflate(input, options); - } - - - /** - * gzip(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ - function gzip(input, options) { - options = options || {}; - options.gzip = true; - return deflate(input, options); - } - - - exports.Deflate = Deflate; - exports.deflate = deflate; - exports.deflateRaw = deflateRaw; - exports.gzip = gzip; - - }, { "./utils/common": 28, "./utils/strings": 29, "./zlib/deflate": 33, "./zlib/messages": 38, "./zlib/zstream": 40 }], 27: [function (require, module, exports) { - 'use strict'; - - - var zlib_inflate = require('./zlib/inflate'); - var utils = require('./utils/common'); - var strings = require('./utils/strings'); - var c = require('./zlib/constants'); - var msg = require('./zlib/messages'); - var ZStream = require('./zlib/zstream'); - var GZheader = require('./zlib/gzheader'); - - var toString = Object.prototype.toString; - - /** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - - /* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - - /** - * Inflate.result -> Uint8Array|Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you - * push a chunk with explicit flush (call [[Inflate#push]] with - * `Z_SYNC_FLUSH` param). - **/ - - /** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - - /** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - - /** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * var inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ - function Inflate(options) { - if (!(this instanceof Inflate)) return new Inflate(options); - - this.options = utils.assign({ - chunkSize: 16384, - windowBits: 0, - to: '' - }, options || {}); - - var opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new ZStream(); - this.strm.avail_out = 0; - - var status = zlib_inflate.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== c.Z_OK) { - throw new Error(msg[status]); - } - - this.header = new GZheader(); - - zlib_inflate.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings.string2buf(opt.dictionary); - } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== c.Z_OK) { - throw new Error(msg[status]); - } - } - } - } - - /** - * Inflate#push(data[, mode]) -> Boolean - * - data (Uint8Array|Array|ArrayBuffer|String): input data - * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. The last data block must have - * mode Z_FINISH (or `true`). That will flush internal pending buffers and call - * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you - * can use mode Z_SYNC_FLUSH, keeping the decompression context. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * We strongly recommend to use `Uint8Array` on input for best speed (output - * format is detected automatically). Also, don't skip last param and always - * use the same type in your code (boolean or number). That will improve JS speed. - * - * For regular `Array`-s make sure all elements are [0..255]. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Inflate.prototype.push = function (data, mode) { - var strm = this.strm; - var chunkSize = this.options.chunkSize; - var dictionary = this.options.dictionary; - var status, _mode; - var next_out_utf8, tail, utf8str; - - // Flag to properly process Z_BUF_ERROR on testing inflate call - // when we check that all output data was flushed. - var allowBufError = false; - - if (this.ended) { return false; } - _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH); - - // Convert data if needed - if (typeof data === 'string') { - // Only binary strings can be decompressed on practice - strm.input = strings.binstring2buf(data); - } else if (toString.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - do { - if (strm.avail_out === 0) { - strm.output = new utils.Buf8(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ - - if (status === c.Z_NEED_DICT && dictionary) { - status = zlib_inflate.inflateSetDictionary(this.strm, dictionary); - } - - if (status === c.Z_BUF_ERROR && allowBufError === true) { - status = c.Z_OK; - allowBufError = false; - } - - if (status !== c.Z_STREAM_END && status !== c.Z_OK) { - this.onEnd(status); - this.ended = true; - return false; - } - - if (strm.next_out) { - if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) { - - if (this.options.to === 'string') { - - next_out_utf8 = strings.utf8border(strm.output, strm.next_out); - - tail = strm.next_out - next_out_utf8; - utf8str = strings.buf2string(strm.output, next_out_utf8); - - // move tail - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } - - this.onData(utf8str); - - } else { - this.onData(utils.shrinkBuf(strm.output, strm.next_out)); - } - } - } - - // When no more input data, we should check that internal inflate buffers - // are flushed. The only way to do it when avail_out = 0 - run one more - // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR. - // Here we set flag to process this error properly. - // - // NOTE. Deflate does not return error in this case and does not needs such - // logic. - if (strm.avail_in === 0 && strm.avail_out === 0) { - allowBufError = true; - } - - } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END); - - if (status === c.Z_STREAM_END) { - _mode = c.Z_FINISH; - } - - // Finalize on the last chunk. - if (_mode === c.Z_FINISH) { - status = zlib_inflate.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === c.Z_OK; - } - - // callback interim results if Z_SYNC_FLUSH. - if (_mode === c.Z_SYNC_FLUSH) { - this.onEnd(c.Z_OK); - strm.avail_out = 0; - return true; - } - - return true; - }; - - - /** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|Array|String): output data. Type of array depends - * on js engine support. When string output requested, each chunk - * will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Inflate.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) - * or if an error happened. By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Inflate.prototype.onEnd = function (status) { - // On success - join - if (status === c.Z_OK) { - if (this.options.to === 'string') { - // Glue & convert here, until we teach pako to send - // utf8 aligned strings to onData - this.result = this.chunks.join(''); - } else { - this.result = utils.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * inflate(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) - * , output; - * - * try { - * output = pako.inflate(input); - * } catch (err) - * console.log(err); - * } - * ``` - **/ - function inflate(input, options) { - var inflator = new Inflate(options); - - inflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) { throw inflator.msg || msg[inflator.err]; } - - return inflator.result; - } - - - /** - * inflateRaw(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function inflateRaw(input, options) { - options = options || {}; - options.raw = true; - return inflate(input, options); - } - - - /** - * ungzip(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - - exports.Inflate = Inflate; - exports.inflate = inflate; - exports.inflateRaw = inflateRaw; - exports.ungzip = inflate; - - }, { "./utils/common": 28, "./utils/strings": 29, "./zlib/constants": 31, "./zlib/gzheader": 34, "./zlib/inflate": 36, "./zlib/messages": 38, "./zlib/zstream": 40 }], 28: [function (require, module, exports) { - 'use strict'; - - - var TYPED_OK = (typeof Uint8Array !== 'undefined') && - (typeof Uint16Array !== 'undefined') && - (typeof Int32Array !== 'undefined'); - - function _has(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); - } - - exports.assign = function (obj /*from1, from2, from3, ...*/) { - var sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - var source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (var p in source) { - if (_has(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; - }; - - - // reduce buffer size, avoiding mem copy - exports.shrinkBuf = function (buf, size) { - if (buf.length === size) { return buf; } - if (buf.subarray) { return buf.subarray(0, size); } - buf.length = size; - return buf; - }; - - - var fnTyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - if (src.subarray && dest.subarray) { - dest.set(src.subarray(src_offs, src_offs + len), dest_offs); - return; - } - // Fallback to ordinary array - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - var i, l, len, pos, chunk, result; - - // calculate data length - len = 0; - for (i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - result = new Uint8Array(len); - pos = 0; - for (i = 0, l = chunks.length; i < l; i++) { - chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; - } - }; - - var fnUntyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - return [].concat.apply([], chunks); - } - }; - - - // Enable/Disable typed arrays use, for testing - // - exports.setTyped = function (on) { - if (on) { - exports.Buf8 = Uint8Array; - exports.Buf16 = Uint16Array; - exports.Buf32 = Int32Array; - exports.assign(exports, fnTyped); - } else { - exports.Buf8 = Array; - exports.Buf16 = Array; - exports.Buf32 = Array; - exports.assign(exports, fnUntyped); - } - }; - - exports.setTyped(TYPED_OK); - - }, {}], 29: [function (require, module, exports) { - // String encode/decode helpers - 'use strict'; - - - var utils = require('./common'); - - - // Quick check if we can use fast array to bin string conversion - // - // - apply(Array) can fail on Android 2.2 - // - apply(Uint8Array) can fail on iOS 5.1 Safari - // - var STR_APPLY_OK = true; - var STR_APPLY_UIA_OK = true; - - try { String.fromCharCode.apply(null, [0]); } catch (__) { STR_APPLY_OK = false; } - try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; } - - - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - var _utf8len = new utils.Buf8(256); - for (var q = 0; q < 256; q++) { - _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); - } - _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start - - - // convert string to array (typed, when possible) - exports.string2buf = function (str) { - var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new utils.Buf8(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; - }; - - // Helper (used in 2 places) - function buf2binstring(buf, len) { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { - return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); - } - } - - var result = ''; - for (var i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; - } - - - // Convert byte array to binary string - exports.buf2binstring = function (buf) { - return buf2binstring(buf, buf.length); - }; - - - // Convert binary string (typed, when possible) - exports.binstring2buf = function (str) { - var buf = new utils.Buf8(str.length); - for (var i = 0, len = buf.length; i < len; i++) { - buf[i] = str.charCodeAt(i); - } - return buf; - }; - - - // convert array to string - exports.buf2string = function (buf, max) { - var i, out, c, c_len; - var len = max || buf.length; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - var utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - c_len = _utf8len[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring(utf16buf, out); - }; - - - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - exports.utf8border = function (buf, max) { - var pos; - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len[buf[pos]] > max) ? pos : max; - }; - - }, { "./common": 28 }], 30: [function (require, module, exports) { - 'use strict'; - - // Note: adler32 takes 12% for level 0 and 2% for level 6. - // It isn't worth it to make additional optimizations as in original. - // Small size is preferable. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function adler32(adler, buf, len, pos) { - var s1 = (adler & 0xffff) | 0, - s2 = ((adler >>> 16) & 0xffff) | 0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) | 0; - s2 = (s2 + s1) | 0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) | 0; - } - - - module.exports = adler32; - - }, {}], 31: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - module.exports = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - //Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type - }; - - }, {}], 32: [function (require, module, exports) { - 'use strict'; - - // Note: we can't get significant speed boost here. - // So write code to minimize size - no pregenerated tables - // and array tools dependencies. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // Use ordinary array, since untyped makes no boost here - function makeTable() { - var c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; - } - - // Create table on load. Just 255 signed longs. Not a problem. - var crcTable = makeTable(); - - - function crc32(crc, buf, len, pos) { - var t = crcTable, - end = pos + len; - - crc ^= -1; - - for (var i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; - } - - - module.exports = crc32; - - }, {}], 33: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var utils = require('../utils/common'); - var trees = require('./trees'); - var adler32 = require('./adler32'); - var crc32 = require('./crc32'); - var msg = require('./messages'); - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - - /* Allowed flush values; see deflate() and inflate() below for details */ - var Z_NO_FLUSH = 0; - var Z_PARTIAL_FLUSH = 1; - //var Z_SYNC_FLUSH = 2; - var Z_FULL_FLUSH = 3; - var Z_FINISH = 4; - var Z_BLOCK = 5; - //var Z_TREES = 6; - - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - var Z_OK = 0; - var Z_STREAM_END = 1; - //var Z_NEED_DICT = 2; - //var Z_ERRNO = -1; - var Z_STREAM_ERROR = -2; - var Z_DATA_ERROR = -3; - //var Z_MEM_ERROR = -4; - var Z_BUF_ERROR = -5; - //var Z_VERSION_ERROR = -6; - - - /* compression levels */ - //var Z_NO_COMPRESSION = 0; - //var Z_BEST_SPEED = 1; - //var Z_BEST_COMPRESSION = 9; - var Z_DEFAULT_COMPRESSION = -1; - - - var Z_FILTERED = 1; - var Z_HUFFMAN_ONLY = 2; - var Z_RLE = 3; - var Z_FIXED = 4; - var Z_DEFAULT_STRATEGY = 0; - - /* Possible values of the data_type field (though see inflate()) */ - //var Z_BINARY = 0; - //var Z_TEXT = 1; - //var Z_ASCII = 1; // = Z_TEXT - var Z_UNKNOWN = 2; - - - /* The deflate compression method */ - var Z_DEFLATED = 8; - - /*============================================================================*/ - - - var MAX_MEM_LEVEL = 9; - /* Maximum value for memLevel in deflateInit2 */ - var MAX_WBITS = 15; - /* 32K LZ77 window */ - var DEF_MEM_LEVEL = 8; - - - var LENGTH_CODES = 29; - /* number of length codes, not counting the special END_BLOCK code */ - var LITERALS = 256; - /* number of literal bytes 0..255 */ - var L_CODES = LITERALS + 1 + LENGTH_CODES; - /* number of Literal or Length codes, including the END_BLOCK code */ - var D_CODES = 30; - /* number of distance codes */ - var BL_CODES = 19; - /* number of codes used to transfer the bit lengths */ - var HEAP_SIZE = 2 * L_CODES + 1; - /* maximum heap size */ - var MAX_BITS = 15; - /* All codes must not exceed MAX_BITS bits */ - - var MIN_MATCH = 3; - var MAX_MATCH = 258; - var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - - var PRESET_DICT = 0x20; - - var INIT_STATE = 42; - var EXTRA_STATE = 69; - var NAME_STATE = 73; - var COMMENT_STATE = 91; - var HCRC_STATE = 103; - var BUSY_STATE = 113; - var FINISH_STATE = 666; - - var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ - var BS_BLOCK_DONE = 2; /* block flush performed */ - var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ - var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - - var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - - function err(strm, errorCode) { - strm.msg = msg[errorCode]; - return errorCode; - } - - function rank(f) { - return ((f) << 1) - ((f) > 4 ? 9 : 0); - } - - function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - - - /* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->output buffer and copying into it. - * (See also read_buf()). - */ - function flush_pending(strm) { - var s = strm.state; - - //_tr_flush_bits(s); - var len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } - } - - - function flush_block_only(s, last) { - trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); - } - - - function put_byte(s, b) { - s.pending_buf[s.pending++] = b; - } - - - /* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ - function putShortMSB(s, b) { - // put_byte(s, (Byte)(b >> 8)); - // put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; - } - - - /* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ - function read_buf(strm, buf, start, size) { - var len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - utils.arraySet(buf, strm.input, strm.next_in, len, start); - if (strm.state.wrap === 1) { - strm.adler = adler32(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; - } - - - /* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ - function longest_match(s, cur_match) { - var chain_length = s.max_chain_length; /* max hash chain length */ - var scan = s.strstart; /* current string */ - var match; /* matched string */ - var len; /* length of current match */ - var best_len = s.prev_length; /* best match length so far */ - var nice_match = s.nice_match; /* stop if match long enough */ - var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - var _win = s.window; // shortcut - - var wmask = s.w_mask; - var prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - var strend = s.strstart + MAX_MATCH; - var scan_end1 = _win[scan + best_len - 1]; - var scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; - } - - - /* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ - function fill_window(s) { - var _w_size = s.w_size; - var p, n, m, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - utils.arraySet(s.window, s.window, _w_size, _w_size, 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= _w_size ? m - _w_size : 0); - } while (--n); - - n = _w_size; - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= _w_size ? m - _w_size : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; - //#if MIN_MATCH != 3 - // Call update_hash() MIN_MATCH-3 more times - //#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - // if (s.high_water < s.window_size) { - // var curr = s.strstart + s.lookahead; - // var init = 0; - // - // if (s.high_water < curr) { - // /* Previous high water mark below current data -- zero WIN_INIT - // * bytes or up to end of window, whichever is less. - // */ - // init = s.window_size - curr; - // if (init > WIN_INIT) - // init = WIN_INIT; - // zmemzero(s->window + curr, (unsigned)init); - // s->high_water = curr + init; - // } - // else if (s->high_water < (ulg)curr + WIN_INIT) { - // /* High water mark at or above current data, but below current data - // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - // * to end of window, whichever is less. - // */ - // init = (ulg)curr + WIN_INIT - s->high_water; - // if (init > s->window_size - s->high_water) - // init = s->window_size - s->high_water; - // zmemzero(s->window + s->high_water, (unsigned)init); - // s->high_water += init; - // } - // } - // - // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - // "not enough room for search"); - } - - /* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ - function deflate_stored(s, flush) { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - var max_block_size = 0xffff; - - if (max_block_size > s.pending_buf_size - 5) { - max_block_size = s.pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (; ;) { - /* Fill the window as much as possible: */ - if (s.lookahead <= 1) { - - //Assert(s->strstart < s->w_size+MAX_DIST(s) || - // s->block_start >= (long)s->w_size, "slide too late"); - // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || - // s.block_start >= s.w_size)) { - // throw new Error("slide too late"); - // } - - fill_window(s); - if (s.lookahead === 0 && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - - if (s.lookahead === 0) { - break; - } - /* flush the current block */ - } - //Assert(s->block_start >= 0L, "block gone"); - // if (s.block_start < 0) throw new Error("block gone"); - - s.strstart += s.lookahead; - s.lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - var max_start = s.block_start + max_block_size; - - if (s.strstart === 0 || s.strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s.lookahead = s.strstart - max_start; - s.strstart = max_start; - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - - - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - - s.insert = 0; - - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - - if (s.strstart > s.block_start) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_NEED_MORE; - } - - /* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ - function deflate_fast(s, flush) { - var hash_head; /* head of the hash chain */ - var bflush; /* set if current block must be flushed */ - - for (; ;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; - - //#if MIN_MATCH != 3 - // Call UPDATE_HASH() MIN_MATCH-3 more times - //#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - } - - /* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ - function deflate_slow(s, flush) { - var hash_head; /* head of hash chain */ - var bflush; /* set if current block must be flushed */ - - var max_insert; - - /* Process the input block. */ - for (; ;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_BLOCK_DONE; - } - - - /* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ - function deflate_rle(s, flush) { - var bflush; /* set if current block must be flushed */ - var prev; /* byte at distance one to match */ - var scan, strend; /* scan goes up to strend for length of run */ - - var _win = s.window; - - for (; ;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - } - - /* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ - function deflate_huff(s, flush) { - var bflush; /* set if current block must be flushed */ - - for (; ;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - } - - /* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ - function Config(good_length, max_lazy, nice_length, max_chain, func) { - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; - } - - var configuration_table; - - configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ - - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ - ]; - - - /* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ - function lm_init(s) { - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; - } - - - function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); - this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); - this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new utils.Buf16(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.l_buf = 0; /* buffer index for literals or lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.last_lit = 0; /* running index in l_buf */ - - this.d_buf = 0; - /* Buffer index for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - } - - - function deflateResetKeep(strm) { - var s; - - if (!strm || !strm.state) { - return err(strm, Z_STREAM_ERROR); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; - - s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = (s.wrap ? INIT_STATE : BUSY_STATE); - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = Z_NO_FLUSH; - trees._tr_init(s); - return Z_OK; - } - - - function deflateReset(strm) { - var ret = deflateResetKeep(strm); - if (ret === Z_OK) { - lm_init(strm.state); - } - return ret; - } - - - function deflateSetHeader(strm, head) { - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } - strm.state.gzhead = head; - return Z_OK; - } - - - function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR; - } - var wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return err(strm, Z_STREAM_ERROR); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - var s = new DeflateState(); - - strm.state = s; - s.strm = strm; - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s.window = new utils.Buf8(s.w_size * 2); - s.head = new utils.Buf16(s.hash_size); - s.prev = new utils.Buf16(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - s.pending_buf_size = s.lit_bufsize * 4; - - //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - //s->pending_buf = (uchf *) overlay; - s.pending_buf = new utils.Buf8(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s.d_buf = 1 * s.lit_bufsize; - - //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - s.l_buf = (1 + 2) * s.lit_bufsize; - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset(strm); - } - - function deflateInit(strm, level) { - return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); - } - - - function deflate(strm, flush) { - var old_flush, s; - var beg, val; // for gzip header write only - - if (!strm || !strm.state || - flush > Z_BLOCK || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; - } - - s = strm.state; - - if (!strm.output || - (!strm.input && strm.avail_in !== 0) || - (s.status === FINISH_STATE && flush !== Z_FINISH)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); - } - - s.strm = strm; /* just in case */ - old_flush = s.last_flush; - s.last_flush = flush; - - /* Write the header */ - if (s.status === INIT_STATE) { - - if (s.wrap === 2) { // GZIP header - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; - } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; - } - } - else // DEFLATE header - { - var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; - var level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); - - s.status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - } - } - - //#ifdef GZIP - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - - while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - break; - } - } - put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); - s.gzindex++; - } - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (s.gzindex === s.gzhead.extra.length) { - s.gzindex = 0; - s.status = NAME_STATE; - } - } - else { - s.status = NAME_STATE; - } - } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; - - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (val === 0) { - s.gzindex = 0; - s.status = COMMENT_STATE; - } - } - else { - s.status = COMMENT_STATE; - } - } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; - - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (val === 0) { - s.status = HCRC_STATE; - } - } - else { - s.status = HCRC_STATE; - } - } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - } - if (s.pending + 2 <= s.pending_buf_size) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - } - } - else { - s.status = BUSY_STATE; - } - } - //#endif - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH) { - return err(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { - var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : - (s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush)); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; - } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - trees._tr_align(s); - } - else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - - trees._tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - //Assert(strm->avail_out > 0, "bug2"); - //if (strm.avail_out <= 0) { throw new Error("bug2");} - - if (flush !== Z_FINISH) { return Z_OK; } - if (s.wrap <= 0) { return Z_STREAM_END; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK : Z_STREAM_END; - } - - function deflateEnd(strm) { - var status; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR; - } - - status = strm.state.status; - if (status !== INIT_STATE && - status !== EXTRA_STATE && - status !== NAME_STATE && - status !== COMMENT_STATE && - status !== HCRC_STATE && - status !== BUSY_STATE && - status !== FINISH_STATE - ) { - return err(strm, Z_STREAM_ERROR); - } - - strm.state = null; - - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; - } - - - /* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ - function deflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; - - var s; - var str, n; - var wrap; - var avail; - var next; - var input; - var tmpDict; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR; - } - - s = strm.state; - wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - tmpDict = new utils.Buf8(s.w_size); - utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - avail = strm.avail_in; - next = strm.next_in; - input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - str = s.strstart; - n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK; - } - - - exports.deflateInit = deflateInit; - exports.deflateInit2 = deflateInit2; - exports.deflateReset = deflateReset; - exports.deflateResetKeep = deflateResetKeep; - exports.deflateSetHeader = deflateSetHeader; - exports.deflate = deflate; - exports.deflateEnd = deflateEnd; - exports.deflateSetDictionary = deflateSetDictionary; - exports.deflateInfo = 'pako deflate (from Nodeca project)'; - - /* Not implemented - exports.deflateBound = deflateBound; - exports.deflateCopy = deflateCopy; - exports.deflateParams = deflateParams; - exports.deflatePending = deflatePending; - exports.deflatePrime = deflatePrime; - exports.deflateTune = deflateTune; - */ - - }, { "../utils/common": 28, "./adler32": 30, "./crc32": 32, "./messages": 38, "./trees": 39 }], 34: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function GZheader() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; - } - - module.exports = GZheader; - - }, {}], 35: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // See state defs from inflate.js - var BAD = 30; /* got a data error -- remain here until reset */ - var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ - - /* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ - module.exports = function inflate_fast(strm, start) { - var state; - var _in; /* local strm.input */ - var last; /* have enough input while in < last */ - var _out; /* local strm.output */ - var beg; /* inflate()'s initial strm.output */ - var end; /* while out < end, enough space available */ - //#ifdef INFLATE_STRICT - var dmax; /* maximum distance from zlib header */ - //#endif - var wsize; /* window size or zero if not using window */ - var whave; /* valid bytes in the window */ - var wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - var s_window; /* allocated sliding window, if wsize != 0 */ - var hold; /* local strm.hold */ - var bits; /* local strm.bits */ - var lcode; /* local strm.lencode */ - var dcode; /* local strm.distcode */ - var lmask; /* mask for first level of length codes */ - var dmask; /* mask for first level of distance codes */ - var here; /* retrieved table entry */ - var op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - var len; /* match length, unused bytes */ - var dist; /* match distance */ - var from; /* where to copy match from */ - var from_source; - - - var input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - //#ifdef INFLATE_STRICT - dmax = state.dmax; - //#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (; ;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (; ;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); - //#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break top; - } - //#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break top; - } - - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // if (len <= op - whave) { - // do { - // output[_out++] = 0; - // } while (--len); - // continue top; - // } - // len -= op - whave; - // do { - // output[_out++] = 0; - // } while (--op > whave); - // if (op === 0) { - // from = _out - dist; - // do { - // output[_out++] = output[from++]; - // } while (--len); - // continue top; - // } - //#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; - }; - - }, {}], 36: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var utils = require('../utils/common'); - var adler32 = require('./adler32'); - var crc32 = require('./crc32'); - var inflate_fast = require('./inffast'); - var inflate_table = require('./inftrees'); - - var CODES = 0; - var LENS = 1; - var DISTS = 2; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - - /* Allowed flush values; see deflate() and inflate() below for details */ - //var Z_NO_FLUSH = 0; - //var Z_PARTIAL_FLUSH = 1; - //var Z_SYNC_FLUSH = 2; - //var Z_FULL_FLUSH = 3; - var Z_FINISH = 4; - var Z_BLOCK = 5; - var Z_TREES = 6; - - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - var Z_OK = 0; - var Z_STREAM_END = 1; - var Z_NEED_DICT = 2; - //var Z_ERRNO = -1; - var Z_STREAM_ERROR = -2; - var Z_DATA_ERROR = -3; - var Z_MEM_ERROR = -4; - var Z_BUF_ERROR = -5; - //var Z_VERSION_ERROR = -6; - - /* The deflate compression method */ - var Z_DEFLATED = 8; - - - /* STATES ====================================================================*/ - /* ===========================================================================*/ - - - var HEAD = 1; /* i: waiting for magic header */ - var FLAGS = 2; /* i: waiting for method and flags (gzip) */ - var TIME = 3; /* i: waiting for modification time (gzip) */ - var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ - var EXLEN = 5; /* i: waiting for extra length (gzip) */ - var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ - var NAME = 7; /* i: waiting for end of file name (gzip) */ - var COMMENT = 8; /* i: waiting for end of comment (gzip) */ - var HCRC = 9; /* i: waiting for header crc (gzip) */ - var DICTID = 10; /* i: waiting for dictionary check value */ - var DICT = 11; /* waiting for inflateSetDictionary() call */ - var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ - var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ - var STORED = 14; /* i: waiting for stored size (length and complement) */ - var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ - var COPY = 16; /* i/o: waiting for input or output to copy stored block */ - var TABLE = 17; /* i: waiting for dynamic block table lengths */ - var LENLENS = 18; /* i: waiting for code length code lengths */ - var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ - var LEN_ = 20; /* i: same as LEN below, but only first time in */ - var LEN = 21; /* i: waiting for length/lit/eob code */ - var LENEXT = 22; /* i: waiting for length extra bits */ - var DIST = 23; /* i: waiting for distance code */ - var DISTEXT = 24; /* i: waiting for distance extra bits */ - var MATCH = 25; /* o: waiting for output space to copy string */ - var LIT = 26; /* o: waiting for output space to write literal */ - var CHECK = 27; /* i: waiting for 32-bit check value */ - var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ - var DONE = 29; /* finished check, done -- remain here until reset */ - var BAD = 30; /* got a data error -- remain here until reset */ - var MEM = 31; /* got an inflate() memory error -- remain here until reset */ - var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ - - /* ===========================================================================*/ - - - - var ENOUGH_LENS = 852; - var ENOUGH_DISTS = 592; - //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - var MAX_WBITS = 15; - /* 32K LZ77 window */ - var DEF_WBITS = MAX_WBITS; - - - function zswap32(q) { - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); - } - - - function InflateState() { - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib) */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ - this.work = new utils.Buf16(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ - } - - function inflateResetKeep(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); - state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK; - } - - function inflateReset(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); - - } - - function inflateReset2(strm, windowBits) { - var wrap; - var state; - - /* get the state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); - } - - function inflateInit2(strm, windowBits) { - var ret; - var state; - - if (!strm) { return Z_STREAM_ERROR; } - //strm.msg = Z_NULL; /* in case we return an error */ - - state = new InflateState(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.window = null/*Z_NULL*/; - ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK) { - strm.state = null/*Z_NULL*/; - } - return ret; - } - - function inflateInit(strm) { - return inflateInit2(strm, DEF_WBITS); - } - - - /* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ - var virgin = true; - - var lenfix, distfix; // We have no pointers in JS, so keep tables separate - - function fixedtables(state) { - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - var sym; - - lenfix = new utils.Buf32(512); - distfix = new utils.Buf32(32); - - /* literal/length table */ - sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin = false; - } - - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; - } - - - /* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ - function updatewindow(strm, src, end, copy) { - var dist; - var state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new utils.Buf8(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - utils.arraySet(state.window, src, end - copy, dist, state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - utils.arraySet(state.window, src, end - copy, copy, 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; - } - - function inflate(strm, flush) { - var state; - var input, output; // input/output buffers - var next; /* next input INDEX */ - var put; /* next output INDEX */ - var have, left; /* available input and output */ - var hold; /* bit buffer */ - var bits; /* bits in bit buffer */ - var _in, _out; /* save starting available input and output */ - var copy; /* number of stored or match bytes to copy */ - var from; /* where to copy match bytes from */ - var from_source; - var here = 0; /* current decoding table entry */ - var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //var last; /* parent table entry */ - var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - var len; /* length to copy for repeats, bits to drop */ - var ret; /* return code */ - var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ - var opts; - - var n; // temporary var for NEED_BITS - - var order = /* permutation of code lengths */ - [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - - - if (!strm || !strm.state || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR; - } - - state = strm.state; - if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK; - - inf_leave: // goto emulation - for (; ;) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS; - break; - } - state.flags = 0; /* expect zlib header */ - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - else if (len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD; - break; - } - state.dmax = 1 << len; - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID : TYPE; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME; - /* falls through */ - case TIME: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if (state.flags & 0x0200) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS; - /* falls through */ - case OS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN; - /* falls through */ - case EXLEN: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA; - /* falls through */ - case EXTRA: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Array(state.head.extra_len); - } - utils.arraySet( - state.head.extra, - input, - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - copy, - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME; - /* falls through */ - case NAME: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT; - /* falls through */ - case COMMENT: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - /* falls through */ - case HCRC: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE; - break; - case DICTID: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT; - /* falls through */ - case DICT: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE; - /* falls through */ - case TYPE: - if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } - /* falls through */ - case TYPEDO: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_; /* decode codes */ - if (flush === Z_TREES) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case COPY_: - state.mode = COPY; - /* falls through */ - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - utils.arraySet(output, input, next, copy, put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE; - break; - case TABLE: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - //#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD; - break; - } - //#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS; - /* falls through */ - case LENLENS: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS; - /* falls through */ - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (; ;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case LEN_: - state.mode = LEN; - /* falls through */ - case LEN: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inflate_fast(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE) { - state.back = -1; - } - break; - } - state.back = 0; - for (; ;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - /* falls through */ - case LENEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST; - /* falls through */ - case DIST: - for (; ;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT; - /* falls through */ - case DISTEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } - //#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH; - /* falls through */ - case MATCH: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // Trace((stderr, "inflate.c too far\n")); - // copy -= state.whave; - // if (copy > state.length) { copy = state.length; } - // if (copy > left) { copy = left; } - // left -= copy; - // state.length -= copy; - // do { - // output[put++] = 0; - // } while (--copy); - // if (state.length === 0) { state.mode = LEN; } - // break; - //#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN; } - break; - case LIT: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if (_out) { - strm.adler = state.check = - /*UPDATE(state.check, put - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH; - /* falls through */ - case LENGTH: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE; - /* falls through */ - case DONE: - ret = Z_STREAM_END; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR; - break inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* falls through */ - default: - return Z_STREAM_ERROR; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && - (state.mode < CHECK || flush !== Z_FINISH))) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { - state.mode = MEM; - return Z_MEM_ERROR; - } - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if (state.wrap && _out) { - strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE ? 128 : 0) + - (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { - ret = Z_BUF_ERROR; - } - return ret; - } - - function inflateEnd(strm) { - - if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { - return Z_STREAM_ERROR; - } - - var state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK; - } - - function inflateGetHeader(strm, head) { - var state; - - /* check state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK; - } - - function inflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; - - var state; - var dictid; - var ret; - - /* check state */ - if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; - } - - exports.inflateReset = inflateReset; - exports.inflateReset2 = inflateReset2; - exports.inflateResetKeep = inflateResetKeep; - exports.inflateInit = inflateInit; - exports.inflateInit2 = inflateInit2; - exports.inflate = inflate; - exports.inflateEnd = inflateEnd; - exports.inflateGetHeader = inflateGetHeader; - exports.inflateSetDictionary = inflateSetDictionary; - exports.inflateInfo = 'pako inflate (from Nodeca project)'; - - /* Not implemented - exports.inflateCopy = inflateCopy; - exports.inflateGetDictionary = inflateGetDictionary; - exports.inflateMark = inflateMark; - exports.inflatePrime = inflatePrime; - exports.inflateSync = inflateSync; - exports.inflateSyncPoint = inflateSyncPoint; - exports.inflateUndermine = inflateUndermine; - */ - - }, { "../utils/common": 28, "./adler32": 30, "./crc32": 32, "./inffast": 35, "./inftrees": 37 }], 37: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var utils = require('../utils/common'); - - var MAXBITS = 15; - var ENOUGH_LENS = 852; - var ENOUGH_DISTS = 592; - //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - var CODES = 0; - var LENS = 1; - var DISTS = 2; - - var lbase = [ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ]; - - var lext = [ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 - ]; - - var dbase = [ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 - ]; - - var dext = [ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 - ]; - - module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) { - var bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - var len = 0; /* a code's length in bits */ - var sym = 0; /* index of code symbols */ - var min = 0, max = 0; /* minimum and maximum code lengths */ - var root = 0; /* number of index bits for root table */ - var curr = 0; /* number of index bits for current table */ - var drop = 0; /* code bits to drop for sub-table */ - var left = 0; /* number of prefix codes available */ - var used = 0; /* code entries in table used */ - var huff = 0; /* Huffman code */ - var incr; /* for incrementing code, index */ - var fill; /* index for replicating entries */ - var low; /* low bits for current root entry */ - var mask; /* mask for low root bits */ - var next; /* next available space in table */ - var base = null; /* base value table to use */ - var base_index = 0; - // var shoextra; /* extra bits table to use */ - var end; /* use base and extra for symbol > end */ - var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ - var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ - var extra = null; - var extra_index = 0; - - var here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES) { - base = extra = work; /* dummy value--not used */ - end = 19; - - } else if (type === LENS) { - base = lbase; - base_index -= 257; - extra = lext; - extra_index -= 257; - end = 256; - - } else { /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS && used > ENOUGH_LENS) || - (type === DISTS && used > ENOUGH_DISTS)) { - return 1; - } - - /* process all codes and make table entries */ - for (; ;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] < end) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] > end) { - here_op = extra[extra_index + work[sym]]; - here_val = base[base_index + work[sym]]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val | 0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS && used > ENOUGH_LENS) || - (type === DISTS && used > ENOUGH_DISTS)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) | 0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) | 0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; - }; - - }, { "../utils/common": 28 }], 38: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - module.exports = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ - }; - - }, {}], 39: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - /* eslint-disable space-unary-ops */ - - var utils = require('../utils/common'); - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - - //var Z_FILTERED = 1; - //var Z_HUFFMAN_ONLY = 2; - //var Z_RLE = 3; - var Z_FIXED = 4; - //var Z_DEFAULT_STRATEGY = 0; - - /* Possible values of the data_type field (though see inflate()) */ - var Z_BINARY = 0; - var Z_TEXT = 1; - //var Z_ASCII = 1; // = Z_TEXT - var Z_UNKNOWN = 2; - - /*============================================================================*/ - - - function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - - // From zutil.h - - var STORED_BLOCK = 0; - var STATIC_TREES = 1; - var DYN_TREES = 2; - /* The three kinds of block type */ - - var MIN_MATCH = 3; - var MAX_MATCH = 258; - /* The minimum and maximum match lengths */ - - // From deflate.h - /* =========================================================================== - * Internal compression state. - */ - - var LENGTH_CODES = 29; - /* number of length codes, not counting the special END_BLOCK code */ - - var LITERALS = 256; - /* number of literal bytes 0..255 */ - - var L_CODES = LITERALS + 1 + LENGTH_CODES; - /* number of Literal or Length codes, including the END_BLOCK code */ - - var D_CODES = 30; - /* number of distance codes */ - - var BL_CODES = 19; - /* number of codes used to transfer the bit lengths */ - - var HEAP_SIZE = 2 * L_CODES + 1; - /* maximum heap size */ - - var MAX_BITS = 15; - /* All codes must not exceed MAX_BITS bits */ - - var Buf_size = 16; - /* size of bit buffer in bi_buf */ - - - /* =========================================================================== - * Constants - */ - - var MAX_BL_BITS = 7; - /* Bit length codes must not exceed MAX_BL_BITS bits */ - - var END_BLOCK = 256; - /* end of block literal code */ - - var REP_3_6 = 16; - /* repeat previous bit length 3-6 times (2 bits of repeat count) */ - - var REPZ_3_10 = 17; - /* repeat a zero length 3-10 times (3 bits of repeat count) */ - - var REPZ_11_138 = 18; - /* repeat a zero length 11-138 times (7 bits of repeat count) */ - - /* eslint-disable comma-spacing,array-bracket-spacing */ - var extra_lbits = /* extra bits for each length code */ - [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]; - - var extra_dbits = /* extra bits for each distance code */ - [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]; - - var extra_blbits = /* extra bits for each bit length code */ - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]; - - var bl_order = - [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - /* eslint-enable comma-spacing,array-bracket-spacing */ - - /* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - - /* =========================================================================== - * Local data. These are initialized only once. - */ - - // We pre-fill arrays with 0 to avoid uninitialized gaps - - var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ - - // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 - var static_ltree = new Array((L_CODES + 2) * 2); - zero(static_ltree); - /* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - - var static_dtree = new Array(D_CODES * 2); - zero(static_dtree); - /* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - - var _dist_code = new Array(DIST_CODE_LEN); - zero(_dist_code); - /* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - - var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); - zero(_length_code); - /* length code for each normalized match length (0 == MIN_MATCH) */ - - var base_length = new Array(LENGTH_CODES); - zero(base_length); - /* First normalized length for each code (0 = MIN_MATCH) */ - - var base_dist = new Array(D_CODES); - zero(base_dist); - /* First normalized distance for each code (0 = distance of 1) */ - - - function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; - } - - - var static_l_desc; - var static_d_desc; - var static_bl_desc; - - - function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ - } - - - - function d_code(dist) { - return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; - } - - - /* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ - function put_short(s, w) { - // put_byte(s, (uch)((w) & 0xff)); - // put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; - } - - - /* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ - function send_bits(s, value, length) { - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } - } - - - function send_code(s, c, tree) { - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); - } - - - /* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ - function bi_reverse(code, len) { - var res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; - } - - - /* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ - function bi_flush(s) { - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } - } - - - /* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ - function gen_bitlen(s, desc) - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - { - var tree = desc.dyn_tree; - var max_code = desc.max_code; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var extra = desc.stat_desc.extra_bits; - var base = desc.stat_desc.extra_base; - var max_length = desc.stat_desc.max_length; - var h; /* heap index */ - var n, m; /* iterate over the tree elements */ - var bits; /* bit length */ - var xbits; /* extra bits */ - var f; /* frequency */ - var overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } - } - - - /* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ - function gen_codes(tree, max_code, bl_count) - // ct_data *tree; /* the tree to decorate */ - // int max_code; /* largest code with non zero frequency */ - // ushf *bl_count; /* number of codes at each bit length */ - { - var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */ - var code = 0; /* running code value */ - var bits; /* bit index */ - var n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits - 1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES - 1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree, L_CODES + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n * 2 + 1]/*.Len*/ = 5; - static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); - static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); - - //static_init_done = true; - } - - - /* =========================================================================== - * Initialize a new block. - */ - function init_block(s) { - var n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.last_lit = s.matches = 0; - } - - - /* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ - function bi_windup(s) { - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; - } - - /* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ - function copy_block(s, buf, len, header) - //DeflateState *s; - //charf *buf; /* the input data */ - //unsigned len; /* its length */ - //int header; /* true if block header must be written */ - { - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, len); - put_short(s, ~len); - } - // while (len--) { - // put_byte(s, *buf++); - // } - utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); - s.pending += len; - } - - /* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ - function smaller(tree, n, m, depth) { - var _n2 = n * 2; - var _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); - } - - /* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ - function pqdownheap(s, tree, k) - // deflate_state *s; - // ct_data *tree; /* the tree to restore */ - // int k; /* node to move down */ - { - var v = s.heap[k]; - var j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; - } - - - // inlined manually - // var SMALLEST = 1; - - /* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ - function compress_block(s, ltree, dtree) - // deflate_state *s; - // const ct_data *ltree; /* literal tree */ - // const ct_data *dtree; /* distance tree */ - { - var dist; /* distance of matched string */ - var lc; /* match length or unmatched char (if dist == 0) */ - var lx = 0; /* running index in l_buf */ - var code; /* the code to send */ - var extra; /* number of extra bits to send */ - - if (s.last_lit !== 0) { - do { - dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); - lc = s.pending_buf[s.l_buf + lx]; - lx++; - - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - // "pendingBuf overflow"); - - } while (lx < s.last_lit); - } - - send_code(s, END_BLOCK, ltree); - } - - - /* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ - function build_tree(s, desc) - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - { - var tree = desc.dyn_tree; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var elems = desc.stat_desc.elems; - var n, m; /* iterate over heap elements */ - var max_code = -1; /* largest code with non zero frequency */ - var node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); - } - - - /* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ - function scan_tree(s, tree, max_code) - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - { - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ - - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - } - - - /* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ - function send_tree(s, tree, max_code) - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - { - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ - - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - } - - - /* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ - function build_bl_tree(s) { - var max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; - } - - - /* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ - function send_all_trees(s, lcodes, dcodes, blcodes) - // deflate_state *s; - // int lcodes, dcodes, blcodes; /* number of codes for each tree */ - { - var rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); - } - - - /* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ - function detect_data_type(s) { - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - var black_mask = 0xf3ffc07f; - var n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>>= 1) { - if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } - } - - /* Check for textual ("white-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - for (n = 32; n < LITERALS; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; - } - - - var static_init_done = false; - - /* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ - function _tr_init(s) { - - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block(s); - } - - - /* =========================================================================== - * Send a stored block - */ - function _tr_stored_block(s, buf, stored_len, last) - //DeflateState *s; - //charf *buf; /* input block */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - { - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - copy_block(s, buf, stored_len, true); /* with header */ - } - - - /* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ - function _tr_align(s) { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); - bi_flush(s); - } - - - /* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ - function _tr_flush_block(s, buf, stored_len, last) - //DeflateState *s; - //charf *buf; /* input block, or NULL if too old */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - { - var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - var max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN) { - s.strm.data_type = detect_data_type(s); - } - - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->last_lit)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { - - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree, static_dtree); - - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); - } - - /* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ - function _tr_tally(s, dist, lc) - // deflate_state *s; - // unsigned dist; /* distance of matched string */ - // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - { - //var out_length, in_length, dcode; - - s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; - s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; - - s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; - s.last_lit++; - - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } - - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - - //#ifdef TRUNCATE_BLOCK - // /* Try to guess if it is profitable to stop the current block here */ - // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { - // /* Compute an upper bound for the compressed length */ - // out_length = s.last_lit*8; - // in_length = s.strstart - s.block_start; - // - // for (dcode = 0; dcode < D_CODES; dcode++) { - // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); - // } - // out_length >>>= 3; - // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - // // s->last_lit, in_length, out_length, - // // 100L - out_length*100L/in_length)); - // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { - // return true; - // } - // } - //#endif - - return (s.last_lit === s.lit_bufsize - 1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - } - - exports._tr_init = _tr_init; - exports._tr_stored_block = _tr_stored_block; - exports._tr_flush_block = _tr_flush_block; - exports._tr_tally = _tr_tally; - exports._tr_align = _tr_align; - - }, { "../utils/common": 28 }], 40: [function (require, module, exports) { - 'use strict'; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function ZStream() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; - } - - module.exports = ZStream; - - }, {}] - }, {}, [10])(10) -}); +// @ts-nocheck +/*! + +JSZip - A Javascript class for generating and reading zip files + + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +/** + * @type { typeof import('@types/jszip') } + */ +( + function (f) { + if (typeof exports === "object" && typeof module !== "undefined") { + module.exports = f(); + } else if (typeof define === "function" && define.amd) { + define([], f); + } else { + var g; + if (typeof window !== "undefined") { + g = window; + } else if (typeof global !== "undefined") { + g = global; + } else if (typeof self !== "undefined") { + g = self; + } else { + g = this; + } + g.JSZip = f(); + } + } +)(function () { + var define, module, exports; + return (function e(t, n, r) { + function s(o, u) { + if (!n[o]) { + if (!t[o]) { + var a = typeof require == "function" && require; + if (!u && a) return a(o, !0); + if (i) return i(o, !0); + var f = new Error("Cannot find module '" + o + "'"); + throw ((f.code = "MODULE_NOT_FOUND"), f); + } + var l = (n[o] = { exports: {} }); + t[o][0].call( + l.exports, + function (e) { + var n = t[o][1][e]; + return s(n ? n : e); + }, + l, + l.exports, + e, + t, + n, + r + ); + } + return n[o].exports; + } + var i = typeof require == "function" && require; + for (var o = 0; o < r.length; o++) s(r[o]); + return s; + })( + { + 1: [ + function (require, module, exports) { + "use strict"; + var DataReader = require("./dataReader"); + + function ArrayReader(data) { + if (data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + this.zero = 0; + + for (var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xff; + } + } + } + ArrayReader.prototype = new DataReader(); + /** + * @see DataReader.byteAt + */ + ArrayReader.prototype.byteAt = function (i) { + return this.data[this.zero + i]; + }; + /** + * @see DataReader.lastIndexOfSignature + */ + ArrayReader.prototype.lastIndexOfSignature = function ( + sig + ) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if ( + this.data[i] === sig0 && + this.data[i + 1] === sig1 && + this.data[i + 2] === sig2 && + this.data[i + 3] === sig3 + ) { + return i - this.zero; + } + } + + return -1; + }; + /** + * @see DataReader.readData + */ + ArrayReader.prototype.readData = function (size) { + this.checkOffset(size); + if (size === 0) { + return []; + } + var result = this.data.slice( + this.zero + this.index, + this.zero + this.index + size + ); + this.index += size; + return result; + }; + module.exports = ArrayReader; + }, + { "./dataReader": 6 }, + ], + 2: [ + function (require, module, exports) { + "use strict"; + // private property + var _keyStr = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + // public method for encoding + exports.encode = function (input, utf8) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = + output + + _keyStr.charAt(enc1) + + _keyStr.charAt(enc2) + + _keyStr.charAt(enc3) + + _keyStr.charAt(enc4); + } + + return output; + }; + + // public method for decoding + exports.decode = function (input, utf8) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + } + + return output; + }; + }, + {}, + ], + 3: [ + function (require, module, exports) { + "use strict"; + function CompressedObject() { + this.compressedSize = 0; + this.uncompressedSize = 0; + this.crc32 = 0; + this.compressionMethod = null; + this.compressedContent = null; + } + + CompressedObject.prototype = { + /** + * Return the decompressed content in an unspecified format. + * The format will depend on the decompressor. + * @return {Object} the decompressed content. + */ + getContent: function () { + return null; // see implementation + }, + /** + * Return the compressed content in an unspecified format. + * The format will depend on the compressed conten source. + * @return {Object} the compressed content. + */ + getCompressedContent: function () { + return null; // see implementation + }, + }; + module.exports = CompressedObject; + }, + {}, + ], + 4: [ + function (require, module, exports) { + "use strict"; + exports.STORE = { + magic: "\x00\x00", + compress: function (content, compressionOptions) { + return content; // no compression + }, + uncompress: function (content) { + return content; // no compression + }, + compressInputType: null, + uncompressInputType: null, + }; + exports.DEFLATE = require("./flate"); + }, + { "./flate": 9 }, + ], + 5: [ + function (require, module, exports) { + "use strict"; + + var utils = require("./utils"); + + var table = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + ]; + + /** + * + * Javascript crc32 + * http://www.webtoolkit.info/ + * + */ + module.exports = function crc32(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if (typeof crc == "undefined") { + crc = 0; + } + var x = 0; + var y = 0; + var b = 0; + + crc = crc ^ -1; + for (var i = 0, iTop = input.length; i < iTop; i++) { + b = isArray ? input[i] : input.charCodeAt(i); + y = (crc ^ b) & 0xff; + x = table[y]; + crc = (crc >>> 8) ^ x; + } + + return crc ^ -1; + }; + // vim: set shiftwidth=4 softtabstop=4: + }, + { "./utils": 22 }, + ], + 6: [ + function (require, module, exports) { + "use strict"; + var utils = require("./utils"); + + function DataReader(data) { + this.data = null; // type : see implementation + this.length = 0; + this.index = 0; + this.zero = 0; + } + DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function (offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specifed index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function (newIndex) { + if ( + this.length < this.zero + newIndex || + newIndex < 0 + ) { + throw new Error( + "End of data reached (data length = " + + this.length + + ", asked index = " + + newIndex + + "). Corrupted zip ?" + ); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function (newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function (n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function (i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function (size) { + var result = 0, + i; + this.checkOffset(size); + for ( + i = this.index + size - 1; + i >= this.index; + i-- + ) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function (size) { + return utils.transformTo( + "string", + this.readData(size) + ); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function (size) { + // see implementations + }, + /** + * Find the last occurence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurence, -1 if not found. + */ + lastIndexOfSignature: function (sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function () { + var dostime = this.readInt(4); + return new Date( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1 + ); // second + }, + }; + module.exports = DataReader; + }, + { "./utils": 22 }, + ], + 7: [ + function (require, module, exports) { + "use strict"; + exports.base64 = false; + exports.binary = false; + exports.dir = false; + exports.createFolders = false; + exports.date = null; + exports.compression = null; + exports.compressionOptions = null; + exports.comment = null; + exports.unixPermissions = null; + exports.dosPermissions = null; + }, + {}, + ], + 8: [ + function (require, module, exports) { + "use strict"; + var utils = require("./utils"); + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.string2binary = function (str) { + return utils.string2binary(str); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.string2Uint8Array = function (str) { + return utils.transformTo("uint8array", str); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.uint8Array2String = function (array) { + return utils.transformTo("string", array); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.string2Blob = function (str) { + var buffer = utils.transformTo("arraybuffer", str); + return utils.arrayBuffer2Blob(buffer); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.arrayBuffer2Blob = function (buffer) { + return utils.arrayBuffer2Blob(buffer); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.transformTo = function (outputType, input) { + return utils.transformTo(outputType, input); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.getTypeOf = function (input) { + return utils.getTypeOf(input); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.checkSupport = function (type) { + return utils.checkSupport(type); + }; + + /** + * @deprecated + * This value will be removed in a future version without replacement. + */ + exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; + + /** + * @deprecated + * This value will be removed in a future version without replacement. + */ + exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.pretty = function (str) { + return utils.pretty(str); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.findCompression = function (compressionMethod) { + return utils.findCompression(compressionMethod); + }; + + /** + * @deprecated + * This function will be removed in a future version without replacement. + */ + exports.isRegExp = function (object) { + return utils.isRegExp(object); + }; + }, + { "./utils": 22 }, + ], + 9: [ + function (require, module, exports) { + "use strict"; + var USE_TYPEDARRAY = + typeof Uint8Array !== "undefined" && + typeof Uint16Array !== "undefined" && + typeof Uint32Array !== "undefined"; + + var pako = require("pako"); + exports.uncompressInputType = USE_TYPEDARRAY + ? "uint8array" + : "array"; + exports.compressInputType = USE_TYPEDARRAY + ? "uint8array" + : "array"; + + exports.magic = "\x08\x00"; + exports.compress = function (input, compressionOptions) { + return pako.deflateRaw(input, { + level: compressionOptions.level || -1, // default compression + }); + }; + exports.uncompress = function (input) { + return pako.inflateRaw(input); + }; + }, + { pako: 25 }, + ], + 10: [ + function (require, module, exports) { + "use strict"; + + var base64 = require("./base64"); + + /** + Usage: + zip = new JSZip(); + zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); + zip.folder("images").file("smile.gif", base64Data, {base64: true}); + zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); + zip.remove("tempfile"); + + base64zip = zip.generate(); + + **/ + + /** + * Representation a of zip file in js + * @constructor + * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). + * @param {Object=} options the options for creating this objects (optional). + */ + function JSZip(data, options) { + // if this constructor is used without `new`, it adds `new` before itself: + if (!(this instanceof JSZip)) + return new JSZip(data, options); + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + // NOTE: we use a null prototype because we do not + // want filenames like "toString" coming from a zip file + // to overwrite methods and attributes in a normal Object. + this.files = Object.create(null); + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + if (data) { + this.load(data, options); + } + this.clone = function () { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; + } + JSZip.prototype = require("./object"); + JSZip.prototype.load = require("./load"); + JSZip.support = require("./support"); + JSZip.defaults = require("./defaults"); + + /** + * @deprecated + * This namespace will be removed in a future version without replacement. + */ + JSZip.utils = require("./deprecatedPublicUtils"); + + JSZip.base64 = { + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + encode: function (input) { + return base64.encode(input); + }, + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + decode: function (input) { + return base64.decode(input); + }, + }; + JSZip.compressions = require("./compressions"); + module.exports = JSZip; + }, + { + "./base64": 2, + "./compressions": 4, + "./defaults": 7, + "./deprecatedPublicUtils": 8, + "./load": 11, + "./object": 14, + "./support": 18, + }, + ], + 11: [ + function (require, module, exports) { + "use strict"; + var base64 = require("./base64"); + var utf8 = require("./utf8"); + var utils = require("./utils"); + var ZipEntries = require("./zipEntries"); + module.exports = function (data, options) { + var files, zipEntries, i, input; + options = utils.extend(options || {}, { + base64: false, + checkCRC32: false, + optimizedBinaryString: false, + createFolders: false, + decodeFileName: utf8.utf8decode, + }); + if (options.base64) { + data = base64.decode(data); + } + + zipEntries = new ZipEntries(data, options); + files = zipEntries.files; + for (i = 0; i < files.length; i++) { + input = files[i]; + this.file(input.fileNameStr, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment: input.fileCommentStr.length + ? input.fileCommentStr + : null, + unixPermissions: input.unixPermissions, + dosPermissions: input.dosPermissions, + createFolders: options.createFolders, + }); + } + if (zipEntries.zipComment.length) { + this.comment = zipEntries.zipComment; + } + + return this; + }; + }, + { + "./base64": 2, + "./utf8": 21, + "./utils": 22, + "./zipEntries": 23, + }, + ], + 12: [ + function (require, module, exports) { + (function (Buffer) { + "use strict"; + module.exports = function (data, encoding) { + return new Buffer(data, encoding); + }; + module.exports.test = function (b) { + return Buffer.isBuffer(b); + }; + }).call( + this, + typeof Buffer !== "undefined" ? Buffer : undefined + ); + }, + {}, + ], + 13: [ + function (require, module, exports) { + "use strict"; + var Uint8ArrayReader = require("./uint8ArrayReader"); + + function NodeBufferReader(data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + this.zero = 0; + } + NodeBufferReader.prototype = new Uint8ArrayReader(); + + /** + * @see DataReader.readData + */ + NodeBufferReader.prototype.readData = function (size) { + this.checkOffset(size); + var result = this.data.slice( + this.zero + this.index, + this.zero + this.index + size + ); + this.index += size; + return result; + }; + module.exports = NodeBufferReader; + }, + { "./uint8ArrayReader": 19 }, + ], + 14: [ + function (require, module, exports) { + "use strict"; + var support = require("./support"); + var utils = require("./utils"); + var crc32 = require("./crc32"); + var signature = require("./signature"); + var defaults = require("./defaults"); + var base64 = require("./base64"); + var compressions = require("./compressions"); + var CompressedObject = require("./compressedObject"); + var nodeBuffer = require("./nodeBuffer"); + var utf8 = require("./utf8"); + var StringWriter = require("./stringWriter"); + var Uint8ArrayWriter = require("./uint8ArrayWriter"); + + /** + * Returns the raw data of a ZipObject, decompress the content if necessary. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ + var getRawData = function (file) { + if (file._data instanceof CompressedObject) { + file._data = file._data.getContent(); + file.options.binary = true; + file.options.base64 = false; + + if (utils.getTypeOf(file._data) === "uint8array") { + var copy = file._data; + // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. + // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). + file._data = new Uint8Array(copy.length); + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + if (copy.length !== 0) { + file._data.set(copy, 0); + } + } + } + return file._data; + }; + + /** + * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ + var getBinaryData = function (file) { + var result = getRawData(file), + type = utils.getTypeOf(result); + if (type === "string") { + if (!file.options.binary) { + // unicode text ! + // unicode string => binary string is a painful process, check if we can avoid it. + if (support.nodebuffer) { + return nodeBuffer(result, "utf-8"); + } + } + return file.asBinary(); + } + return result; + }; + + /** + * Transform this._data into a string. + * @param {function} filter a function String -> String, applied if not null on the result. + * @return {String} the string representing this._data. + */ + var dataToString = function (asUTF8) { + var result = getRawData(this); + if (result === null || typeof result === "undefined") { + return ""; + } + // if the data is a base64 string, we decode it before checking the encoding ! + if (this.options.base64) { + result = base64.decode(result); + } + if (asUTF8 && this.options.binary) { + // JSZip.prototype.utf8decode supports arrays as input + // skip to array => string step, utf8decode will do it. + result = out.utf8decode(result); + } else { + // no utf8 transformation, do the array => string step. + result = utils.transformTo("string", result); + } + + if (!asUTF8 && !this.options.binary) { + result = utils.transformTo( + "string", + out.utf8encode(result) + ); + } + return result; + }; + /** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ + var ZipObject = function (name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this.options = options; + + /* + * This object contains initial values for dir and date. + * With them, we can check if the user changed the deprecated metadata in + * `ZipObject#options` or not. + */ + this._initialMetadata = { + dir: options.dir, + date: options.date, + }; + }; + + ZipObject.prototype = { + /** + * Return the content as UTF8 string. + * @return {string} the UTF8 string. + */ + asText: function () { + return dataToString.call(this, true); + }, + /** + * Returns the binary content. + * @return {string} the content as binary. + */ + asBinary: function () { + return dataToString.call(this, false); + }, + /** + * Returns the content as a nodejs Buffer. + * @return {Buffer} the content as a Buffer. + */ + asNodeBuffer: function () { + var result = getBinaryData(this); + return utils.transformTo("nodebuffer", result); + }, + /** + * Returns the content as an Uint8Array. + * @return {Uint8Array} the content as an Uint8Array. + */ + asUint8Array: function () { + var result = getBinaryData(this); + return utils.transformTo("uint8array", result); + }, + /** + * Returns the content as an ArrayBuffer. + * @return {ArrayBuffer} the content as an ArrayBufer. + */ + asArrayBuffer: function () { + return this.asUint8Array().buffer; + }, + }; + + /** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ + var decToHex = function (dec, bytes) { + var hex = "", + i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; + }; + + /** + * Transforms the (incomplete) options from the user into the complete + * set of options to create a file. + * @private + * @param {Object} o the options from the user. + * @return {Object} the complete set of options. + */ + var prepareFileAttrs = function (o) { + o = o || {}; + if ( + o.base64 === true && + (o.binary === null || o.binary === undefined) + ) { + o.binary = true; + } + o = utils.extend(o, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) + o.compression = o.compression.toUpperCase(); + + return o; + }; + + /** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} o the options of the file + * @return {Object} the new file. + */ + var fileAdd = function (name, data, o) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + o = prepareFileAttrs(o); + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && o.unixPermissions & 0x4000) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && o.dosPermissions & 0x0010) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + if ( + o.dir || + data === null || + typeof data === "undefined" + ) { + o.base64 = false; + o.binary = false; + data = null; + dataType = null; + } else if (dataType === "string") { + if (o.binary && !o.base64) { + // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask + if (o.optimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = utils.string2binary(data); + } + } + } else { + // arraybuffer, uint8array, ... + o.base64 = false; + o.binary = true; + + if ( + !dataType && + !(data instanceof CompressedObject) + ) { + throw new Error( + "The data of '" + + name + + "' is in an unsupported format !" + ); + } + + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = utils.transformTo("uint8array", data); + } + } + + var object = new ZipObject(name, data, o); + this.files[name] = object; + return object; + }; + + /** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ + var parentFolder = function (path) { + if (path.slice(-1) == "/") { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf("/"); + return lastSlash > 0 + ? path.substring(0, lastSlash) + : ""; + }; + + /** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ + var forceTrailingSlash = function (path) { + // Check the name ends with a / + if (path.slice(-1) != "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; + }; + /** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ + var folderAdd = function (name, createFolders) { + createFolders = + typeof createFolders !== "undefined" + ? createFolders + : false; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders, + }); + } + return this.files[name]; + }; + + /** + * Generate a JSZip.CompressedObject for a given zipOject. + * @param {ZipObject} file the object to read. + * @param {JSZip.compression} compression the compression to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return {JSZip.CompressedObject} the compressed result. + */ + var generateCompressedObjectFrom = function ( + file, + compression, + compressionOptions + ) { + var result = new CompressedObject(), + content; + + // the data has not been decompressed, we might reuse things ! + if (file._data instanceof CompressedObject) { + result.uncompressedSize = + file._data.uncompressedSize; + result.crc32 = file._data.crc32; + + if (result.uncompressedSize === 0 || file.dir) { + compression = compressions["STORE"]; + result.compressedContent = ""; + result.crc32 = 0; + } else if ( + file._data.compressionMethod === + compression.magic + ) { + result.compressedContent = + file._data.getCompressedContent(); + } else { + content = file._data.getContent(); + // need to decompress / recompress + result.compressedContent = compression.compress( + utils.transformTo( + compression.compressInputType, + content + ), + compressionOptions + ); + } + } else { + // have uncompressed data + content = getBinaryData(file); + if (!content || content.length === 0 || file.dir) { + compression = compressions["STORE"]; + content = ""; + } + result.uncompressedSize = content.length; + result.crc32 = crc32(content); + result.compressedContent = compression.compress( + utils.transformTo( + compression.compressInputType, + content + ), + compressionOptions + ); + } + + result.compressedSize = result.compressedContent.length; + result.compressionMethod = compression.magic; + + return result; + }; + + /** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ + var generateUnixExternalFileAttr = function ( + unixPermissions, + isDir + ) { + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + + return (result & 0xffff) << 16; + }; + + /** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ + var generateDosExternalFileAttr = function ( + dosPermissions, + isDir + ) { + // the dir flag is already set for compatibility + + return (dosPermissions || 0) & 0x3f; + }; + + /** + * Generate the various parts used in the construction of the final zip file. + * @param {string} name the file name. + * @param {ZipObject} file the file content. + * @param {JSZip.CompressedObject} compressedObject the compressed object. + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @param {Function} encodeFileName the function to encode the file name / comment. + * @return {object} the zip parts. + */ + var generateZipParts = function ( + name, + file, + compressedObject, + offset, + platform, + encodeFileName + ) { + var data = compressedObject.compressedContent, + useCustomEncoding = + encodeFileName !== utf8.utf8encode, + encodedFileName = utils.transformTo( + "string", + encodeFileName(file.name) + ), + utfEncodedFileName = utils.transformTo( + "string", + utf8.utf8encode(file.name) + ), + comment = file.comment || "", + encodedComment = utils.transformTo( + "string", + encodeFileName(comment) + ), + utfEncodedComment = utils.transformTo( + "string", + utf8.utf8encode(comment) + ), + useUTF8ForFileName = + utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = + utfEncodedComment.length !== comment.length, + o = file.options, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir, + date; + + // handle the deprecated options.dir + if (file._initialMetadata.dir !== file.dir) { + dir = file.dir; + } else { + dir = o.dir; + } + + // handle the deprecated options.date + if (file._initialMetadata.date !== file.date) { + date = file.date; + } else { + date = o.date; + } + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if (platform === "UNIX") { + versionMadeBy = 0x031e; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr( + file.unixPermissions, + dir + ); + } else { + // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr( + file.dosPermissions, + dir + ); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | (date.getSeconds() / 2); + + dosDate = date.getFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(encodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if (useUTF8ForComment) { + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(this.crc32(encodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + // set bit 11 if utf8 + header += + !useCustomEncoding && + (useUTF8ForFileName || useUTF8ForComment) + ? "\x00\x08" + : "\x00\x00"; + // compression method + header += compressedObject.compressionMethod; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(compressedObject.crc32, 4); + // compressed size + header += decToHex(compressedObject.compressedSize, 4); + // uncompressed size + header += decToHex( + compressedObject.uncompressedSize, + 4 + ); + // file name length + header += decToHex(encodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + var fileRecord = + signature.LOCAL_FILE_HEADER + + header + + encodedFileName + + extraFields; + + var dirRecord = + signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(encodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + encodedFileName + + // extra field + extraFields + + // file comment + encodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord, + compressedObject: compressedObject, + }; + }; + + // return the actual prototype of JSZip + var out = { + /** + * Read an existing zip and merge the data in the current JSZip object. + * The implementation is in jszip-load.js, don't forget to include it. + * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load + * @param {Object} options Options for loading the stream. + * options.base64 : is the stream in base64 ? default : false + * @return {JSZip} the current JSZip object + */ + load: function (stream, options) { + throw new Error( + "Load method is not defined. Is the file jszip-load.js included ?" + ); + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function (search) { + var result = [], + filename, + relativePath, + file, + fileClone; + for (filename in this.files) { + file = this.files[filename]; + // return a new object, don't let the user mess with our internal objects :) + fileClone = new ZipObject( + file.name, + file._data, + utils.extend(file.options) + ); + relativePath = filename.slice( + this.root.length, + filename.length + ); + if ( + filename.slice(0, this.root.length) === + this.root && // the file is in the current root + search(relativePath, fileClone) + ) { + // and the file matches the function + result.push(fileClone); + } + } + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function (name, data, o) { + if (arguments.length === 1) { + if (utils.isRegExp(name)) { + var regexp = name; + return this.filter(function ( + relativePath, + file + ) { + return ( + !file.dir && + regexp.test(relativePath) + ); + }); + } else { + // text + return ( + this.filter(function ( + relativePath, + file + ) { + return ( + !file.dir && + relativePath === name + ); + })[0] || null + ); + } + } else { + // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function (arg) { + if (!arg) { + return this; + } + + if (utils.isRegExp(arg)) { + return this.filter(function ( + relativePath, + file + ) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function (name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) != "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function ( + relativePath, + file + ) { + return ( + file.name.slice(0, name.length) === name + ); + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - base64, (deprecated, use type instead) true to generate base64. + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function (options) { + options = utils.extend(options || {}, { + base64: true, + compression: "STORE", + compressionOptions: null, + type: "base64", + platform: "DOS", + comment: null, + mimeType: "application/zip", + encodeFileName: utf8.utf8encode, + }); + + utils.checkSupport(options.type); + + // accept nodejs `process.platform` + if ( + options.platform === "darwin" || + options.platform === "freebsd" || + options.platform === "linux" || + options.platform === "sunos" + ) { + options.platform = "UNIX"; + } + if (options.platform === "win32") { + options.platform = "DOS"; + } + + var zipData = [], + localDirLength = 0, + centralDirLength = 0, + writer, + i, + encodedComment = utils.transformTo( + "string", + options.encodeFileName( + options.comment || this.comment || "" + ) + ); + + // first, generate all the zip parts. + for (var name in this.files) { + var file = this.files[name]; + + var compressionName = + file.options.compression || + options.compression.toUpperCase(); + var compression = compressions[compressionName]; + if (!compression) { + throw new Error( + compressionName + + " is not a valid compression method !" + ); + } + var compressionOptions = + file.options.compressionOptions || + options.compressionOptions || + {}; + + var compressedObject = + generateCompressedObjectFrom.call( + this, + file, + compression, + compressionOptions + ); + + var zipPart = generateZipParts.call( + this, + name, + file, + compressedObject, + localDirLength, + options.platform, + options.encodeFileName + ); + localDirLength += + zipPart.fileRecord.length + + compressedObject.compressedSize; + centralDirLength += zipPart.dirRecord.length; + zipData.push(zipPart); + } + + var dirEnd = ""; + + // end of central dir signature + dirEnd = + signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(zipData.length, 2) + + // total number of entries in the central directory + decToHex(zipData.length, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(encodedComment.length, 2) + + // .ZIP file comment + encodedComment; + + // we have all the parts (and the total length) + // time to create a writer ! + var typeName = options.type.toLowerCase(); + if ( + typeName === "uint8array" || + typeName === "arraybuffer" || + typeName === "blob" || + typeName === "nodebuffer" + ) { + writer = new Uint8ArrayWriter( + localDirLength + + centralDirLength + + dirEnd.length + ); + } else { + writer = new StringWriter( + localDirLength + + centralDirLength + + dirEnd.length + ); + } + + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].fileRecord); + writer.append( + zipData[i].compressedObject + .compressedContent + ); + } + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].dirRecord); + } + + writer.append(dirEnd); + + var zip = writer.finalize(); + + switch (options.type.toLowerCase()) { + // case "zip is an Uint8Array" + case "uint8array": + case "arraybuffer": + case "nodebuffer": + return utils.transformTo( + options.type.toLowerCase(), + zip + ); + case "blob": + return utils.arrayBuffer2Blob( + utils.transformTo("arraybuffer", zip), + options.mimeType + ); + // case "zip is a string" + case "base64": + return options.base64 + ? base64.encode(zip) + : zip; + default: // case "string" : + return zip; + } + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + crc32: function (input, crc) { + return crc32(input, crc); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8encode: function (string) { + return utils.transformTo( + "string", + utf8.utf8encode(string) + ); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8decode: function (input) { + return utf8.utf8decode(input); + }, + }; + module.exports = out; + }, + { + "./base64": 2, + "./compressedObject": 3, + "./compressions": 4, + "./crc32": 5, + "./defaults": 7, + "./nodeBuffer": 12, + "./signature": 15, + "./stringWriter": 17, + "./support": 18, + "./uint8ArrayWriter": 20, + "./utf8": 21, + "./utils": 22, + }, + ], + 15: [ + function (require, module, exports) { + "use strict"; + exports.LOCAL_FILE_HEADER = "PK\x03\x04"; + exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; + exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; + exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; + exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; + exports.DATA_DESCRIPTOR = "PK\x07\x08"; + }, + {}, + ], + 16: [ + function (require, module, exports) { + "use strict"; + var DataReader = require("./dataReader"); + var utils = require("./utils"); + + function StringReader(data, optimizedBinaryString) { + this.data = data; + if (!optimizedBinaryString) { + this.data = utils.string2binary(this.data); + } + this.length = this.data.length; + this.index = 0; + this.zero = 0; + } + StringReader.prototype = new DataReader(); + /** + * @see DataReader.byteAt + */ + StringReader.prototype.byteAt = function (i) { + return this.data.charCodeAt(this.zero + i); + }; + /** + * @see DataReader.lastIndexOfSignature + */ + StringReader.prototype.lastIndexOfSignature = function ( + sig + ) { + return this.data.lastIndexOf(sig) - this.zero; + }; + /** + * @see DataReader.readData + */ + StringReader.prototype.readData = function (size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice( + this.zero + this.index, + this.zero + this.index + size + ); + this.index += size; + return result; + }; + module.exports = StringReader; + }, + { "./dataReader": 6, "./utils": 22 }, + ], + 17: [ + function (require, module, exports) { + "use strict"; + + var utils = require("./utils"); + + /** + * An object to write any content to a string. + * @constructor + */ + var StringWriter = function () { + this.data = []; + }; + StringWriter.prototype = { + /** + * Append any content to the current string. + * @param {Object} input the content to add. + */ + append: function (input) { + input = utils.transformTo("string", input); + this.data.push(input); + }, + /** + * Finalize the construction an return the result. + * @return {string} the generated string. + */ + finalize: function () { + return this.data.join(""); + }, + }; + + module.exports = StringWriter; + }, + { "./utils": 22 }, + ], + 18: [ + function (require, module, exports) { + (function (Buffer) { + "use strict"; + exports.base64 = true; + exports.array = true; + exports.string = true; + exports.arraybuffer = + typeof ArrayBuffer !== "undefined" && + typeof Uint8Array !== "undefined"; + // contains true if JSZip can read/generate nodejs Buffer, false otherwise. + // Browserify will provide a Buffer implementation for browsers, which is + // an augmented Uint8Array (i.e., can be used as either Buffer or U8). + exports.nodebuffer = typeof Buffer !== "undefined"; + // contains true if JSZip can read/generate Uint8Array, false otherwise. + exports.uint8array = typeof Uint8Array !== "undefined"; + + if (typeof ArrayBuffer === "undefined") { + exports.blob = false; + } else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = + new Blob([buffer], { + type: "application/zip", + }).size === 0; + } catch (e) { + try { + var Builder = + window.BlobBuilder || + window.WebKitBlobBuilder || + window.MozBlobBuilder || + window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = + builder.getBlob("application/zip") + .size === 0; + } catch (e) { + exports.blob = false; + } + } + } + }).call( + this, + typeof Buffer !== "undefined" ? Buffer : undefined + ); + }, + {}, + ], + 19: [ + function (require, module, exports) { + "use strict"; + var ArrayReader = require("./arrayReader"); + + function Uint8ArrayReader(data) { + if (data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + this.zero = 0; + } + } + Uint8ArrayReader.prototype = new ArrayReader(); + /** + * @see DataReader.readData + */ + Uint8ArrayReader.prototype.readData = function (size) { + this.checkOffset(size); + if (size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray( + this.zero + this.index, + this.zero + this.index + size + ); + this.index += size; + return result; + }; + module.exports = Uint8ArrayReader; + }, + { "./arrayReader": 1 }, + ], + 20: [ + function (require, module, exports) { + "use strict"; + + var utils = require("./utils"); + + /** + * An object to write any content to an Uint8Array. + * @constructor + * @param {number} length The length of the array. + */ + var Uint8ArrayWriter = function (length) { + this.data = new Uint8Array(length); + this.index = 0; + }; + Uint8ArrayWriter.prototype = { + /** + * Append any content to the current array. + * @param {Object} input the content to add. + */ + append: function (input) { + if (input.length !== 0) { + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + input = utils.transformTo("uint8array", input); + this.data.set(input, this.index); + this.index += input.length; + } + }, + /** + * Finalize the construction an return the result. + * @return {Uint8Array} the generated array. + */ + finalize: function () { + return this.data; + }, + }; + + module.exports = Uint8ArrayWriter; + }, + { "./utils": 22 }, + ], + 21: [ + function (require, module, exports) { + "use strict"; + + var utils = require("./utils"); + var support = require("./support"); + var nodeBuffer = require("./nodeBuffer"); + + /** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + + // Table with utf8 lengths (calculated by first byte of sequence) + // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, + // because max possible codepoint is 0x10ffff + var _utf8len = new Array(256); + for (var i = 0; i < 256; i++) { + _utf8len[i] = + i >= 252 + ? 6 + : i >= 248 + ? 5 + : i >= 240 + ? 4 + : i >= 224 + ? 3 + : i >= 192 + ? 2 + : 1; + } + _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start + + // convert string to array (typed, when possible) + var string2buf = function (str) { + var buf, + c, + c2, + m_pos, + i, + str_len = str.length, + buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ( + (c & 0xfc00) === 0xd800 && + m_pos + 1 < str_len + ) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = + 0x10000 + + ((c - 0xd800) << 10) + + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += + c < 0x80 + ? 1 + : c < 0x800 + ? 2 + : c < 0x10000 + ? 3 + : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i = 0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ( + (c & 0xfc00) === 0xd800 && + m_pos + 1 < str_len + ) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = + 0x10000 + + ((c - 0xd800) << 10) + + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xc0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xe0 | (c >>> 12); + buf[i++] = 0x80 | ((c >>> 6) & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | ((c >>> 12) & 0x3f); + buf[i++] = 0x80 | ((c >>> 6) & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; + }; + + // Calculate max possible position in utf8 buffer, + // that will not break sequence. If that's not possible + // - (very small limits) return max size as is. + // + // buf[] - utf8 bytes array + // max - length limit (mandatory); + var utf8border = function (buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { + max = buf.length; + } + + // go back from last position, until start of sequence found + pos = max - 1; + while (pos >= 0 && (buf[pos] & 0xc0) === 0x80) { + pos--; + } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { + return max; + } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { + return max; + } + + return pos + _utf8len[buf[pos]] > max ? pos : max; + }; + + // convert array to string + var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len * 2); + + for (out = 0, i = 0; i < len; ) { + c = buf[i++]; + // quick process ascii + if (c < 0x80) { + utf16buf[out++] = c; + continue; + } + + c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { + utf16buf[out++] = 0xfffd; + i += c_len - 1; + continue; + } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { + utf16buf[out++] = 0xfffd; + continue; + } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if (utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); + }; + + // That's all for the pako functions. + + /** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ + exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodeBuffer(str, "utf-8"); + } + + return string2buf(str); + }; + + /** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ + exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils + .transformTo("nodebuffer", buf) + .toString("utf-8"); + } + + buf = utils.transformTo( + support.uint8array ? "uint8array" : "array", + buf + ); + + // return buf2string(buf); + // Chrome prefers to work with "small" chunks of data + // for the method buf2string. + // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. + var result = [], + k = 0, + len = buf.length, + chunk = 65536; + while (k < len) { + var nextBoundary = utf8border( + buf, + Math.min(k + chunk, len) + ); + if (support.uint8array) { + result.push( + buf2string(buf.subarray(k, nextBoundary)) + ); + } else { + result.push( + buf2string(buf.slice(k, nextBoundary)) + ); + } + k = nextBoundary; + } + return result.join(""); + }; + // vim: set shiftwidth=4 softtabstop=4: + }, + { "./nodeBuffer": 12, "./support": 18, "./utils": 22 }, + ], + 22: [ + function (require, module, exports) { + "use strict"; + var support = require("./support"); + var compressions = require("./compressions"); + var nodeBuffer = require("./nodeBuffer"); + /** + * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. + * @param {string} str the string to transform. + * @return {String} the binary string. + */ + exports.string2binary = function (str) { + var result = ""; + for (var i = 0; i < str.length; i++) { + result += String.fromCharCode( + str.charCodeAt(i) & 0xff + ); + } + return result; + }; + exports.arrayBuffer2Blob = function (buffer, mimeType) { + exports.checkSupport("blob"); + mimeType = mimeType || "application/zip"; + + try { + // Blob constructor + return new Blob([buffer], { + type: mimeType, + }); + } catch (e) { + try { + // deprecated, browser only, old way + var Builder = + window.BlobBuilder || + window.WebKitBlobBuilder || + window.MozBlobBuilder || + window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + return builder.getBlob(mimeType); + } catch (e) { + // well, fuck ?! + throw new Error( + "Bug : can't construct the Blob." + ); + } + } + }; + /** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ + function identity(input) { + return input; + } + + /** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ + function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xff; + } + return array; + } + + /** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ + function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + var chunk = 65536; + var result = [], + len = array.length, + type = exports.getTypeOf(array), + k = 0, + canUseApply = true; + try { + switch (type) { + case "uint8array": + String.fromCharCode.apply( + null, + new Uint8Array(0) + ); + break; + case "nodebuffer": + String.fromCharCode.apply( + null, + nodeBuffer(0) + ); + break; + } + } catch (e) { + canUseApply = false; + } + + // no apply : slow and painful algorithm + // default browser on android 4.* + if (!canUseApply) { + var resultStr = ""; + for (var i = 0; i < array.length; i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + } + while (k < len && chunk > 1) { + try { + if (type === "array" || type === "nodebuffer") { + result.push( + String.fromCharCode.apply( + null, + array.slice( + k, + Math.min(k + chunk, len) + ) + ) + ); + } else { + result.push( + String.fromCharCode.apply( + null, + array.subarray( + k, + Math.min(k + chunk, len) + ) + ) + ); + } + k += chunk; + } catch (e) { + chunk = Math.floor(chunk / 2); + } + } + return result.join(""); + } + + exports.applyFromCharCode = arrayLikeToString; + + /** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ + function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; + } + + // a matrix containing functions to transform everything into everything. + var transform = {}; + + // string to ? + transform["string"] = { + string: identity, + array: function (input) { + return stringToArrayLike( + input, + new Array(input.length) + ); + }, + arraybuffer: function (input) { + return transform["string"]["uint8array"](input) + .buffer; + }, + uint8array: function (input) { + return stringToArrayLike( + input, + new Uint8Array(input.length) + ); + }, + nodebuffer: function (input) { + return stringToArrayLike( + input, + nodeBuffer(input.length) + ); + }, + }; + + // array to ? + transform["array"] = { + string: arrayLikeToString, + array: identity, + arraybuffer: function (input) { + return new Uint8Array(input).buffer; + }, + uint8array: function (input) { + return new Uint8Array(input); + }, + nodebuffer: function (input) { + return nodeBuffer(input); + }, + }; + + // arraybuffer to ? + transform["arraybuffer"] = { + string: function (input) { + return arrayLikeToString(new Uint8Array(input)); + }, + array: function (input) { + return arrayLikeToArrayLike( + new Uint8Array(input), + new Array(input.byteLength) + ); + }, + arraybuffer: identity, + uint8array: function (input) { + return new Uint8Array(input); + }, + nodebuffer: function (input) { + return nodeBuffer(new Uint8Array(input)); + }, + }; + + // uint8array to ? + transform["uint8array"] = { + string: arrayLikeToString, + array: function (input) { + return arrayLikeToArrayLike( + input, + new Array(input.length) + ); + }, + arraybuffer: function (input) { + return input.buffer; + }, + uint8array: identity, + nodebuffer: function (input) { + return nodeBuffer(input); + }, + }; + + // nodebuffer to ? + transform["nodebuffer"] = { + string: arrayLikeToString, + array: function (input) { + return arrayLikeToArrayLike( + input, + new Array(input.length) + ); + }, + arraybuffer: function (input) { + return transform["nodebuffer"]["uint8array"](input) + .buffer; + }, + uint8array: function (input) { + return arrayLikeToArrayLike( + input, + new Uint8Array(input.length) + ); + }, + nodebuffer: identity, + }; + + /** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ + exports.transformTo = function (outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; + }; + + /** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ + exports.getTypeOf = function (input) { + if (typeof input === "string") { + return "string"; + } + if ( + Object.prototype.toString.call(input) === + "[object Array]" + ) { + return "array"; + } + if (support.nodebuffer && nodeBuffer.test(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if ( + support.arraybuffer && + input instanceof ArrayBuffer + ) { + return "arraybuffer"; + } + }; + + /** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ + exports.checkSupport = function (type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error( + type + " is not supported by this browser" + ); + } + }; + exports.MAX_VALUE_16BITS = 65535; + exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + + /** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ + exports.pretty = function (str) { + var res = "", + code, + i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += + "\\x" + + (code < 16 ? "0" : "") + + code.toString(16).toUpperCase(); + } + return res; + }; + + /** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ + exports.findCompression = function (compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if ( + compressions[method].magic === compressionMethod + ) { + return compressions[method]; + } + } + return null; + }; + /** + * Cross-window, cross-Node-context regular expression detection + * @param {Object} object Anything + * @return {Boolean} true if the object is a regular expression, + * false otherwise + */ + exports.isRegExp = function (object) { + return ( + Object.prototype.toString.call(object) === + "[object RegExp]" + ); + }; + + /** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ + exports.extend = function () { + var result = {}, + i, + attr; + for (i = 0; i < arguments.length; i++) { + // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if ( + arguments[i].hasOwnProperty(attr) && + typeof result[attr] === "undefined" + ) { + result[attr] = arguments[i][attr]; + } + } + } + return result; + }; + }, + { "./compressions": 4, "./nodeBuffer": 12, "./support": 18 }, + ], + 23: [ + function (require, module, exports) { + "use strict"; + var StringReader = require("./stringReader"); + var NodeBufferReader = require("./nodeBufferReader"); + var Uint8ArrayReader = require("./uint8ArrayReader"); + var ArrayReader = require("./arrayReader"); + var utils = require("./utils"); + var sig = require("./signature"); + var ZipEntry = require("./zipEntry"); + var support = require("./support"); + var jszipProto = require("./object"); + // class ZipEntries {{{ + /** + * All the entries in the zip file. + * @constructor + * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. + * @param {Object} loadOptions Options for loading the stream. + */ + function ZipEntries(data, loadOptions) { + this.files = []; + this.loadOptions = loadOptions; + if (data) { + this.load(data); + } + } + ZipEntries.prototype = { + /** + * Check that the reader is on the speficied signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function (expectedSignature) { + var signature = this.reader.readString(4); + if (signature !== expectedSignature) { + throw new Error( + "Corrupted zip or bug : unexpected signature " + + "(" + + utils.pretty(signature) + + ", expected " + + utils.pretty(expectedSignature) + + ")" + ); + } + }, + /** + * Check if the given signature is at the given index. + * @param {number} askedIndex the index to check. + * @param {string} expectedSignature the signature to expect. + * @return {boolean} true if the signature is here, false otherwise. + */ + isSignature: function (askedIndex, expectedSignature) { + var currentIndex = this.reader.index; + this.reader.setIndex(askedIndex); + var signature = this.reader.readString(4); + var result = signature === expectedSignature; + this.reader.setIndex(currentIndex); + return result; + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function () { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = + this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = + this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + var zipComment = this.reader.readData( + this.zipCommentLength + ); + var decodeParamType = support.uint8array + ? "uint8array" + : "array"; + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded unless specified otherwise. + var decodeContent = utils.transformTo( + decodeParamType, + zipComment + ); + this.zipComment = + this.loadOptions.decodeFileName(decodeContent); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function () { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.versionMadeBy = this.reader.readString(2); + this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = + this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = + this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = + this.reader.readString(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue, + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function () { + this.diskWithZip64CentralDirStart = + this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = + this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error( + "Multi-volumes zip are not supported" + ); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function () { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function () { + var file; + + this.reader.setIndex(this.centralDirOffset); + while ( + this.reader.readString(4) === + sig.CENTRAL_FILE_HEADER + ) { + file = new ZipEntry( + { + zip64: this.zip64, + }, + this.loadOptions + ); + file.readCentralPart(this.reader); + this.files.push(file); + } + + if (this.centralDirRecords !== this.files.length) { + if ( + this.centralDirRecords !== 0 && + this.files.length === 0 + ) { + // We expected some records but couldn't find ANY. + // This is really suspicious, as if something went wrong. + throw new Error( + "Corrupted zip or bug: expected " + + this.centralDirRecords + + " records in central dir, got " + + this.files.length + ); + } else { + // We found some records but not all. + // Something is wrong but we got something for the user: no error here. + // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); + } + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function () { + var offset = this.reader.lastIndexOfSignature( + sig.CENTRAL_DIRECTORY_END + ); + if (offset < 0) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = !this.isSignature( + 0, + sig.LOCAL_FILE_HEADER + ); + + if (isGarbage) { + throw new Error( + "Can't find end of central directory : is this a zip file ? " + + "If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html" + ); + } else { + throw new Error( + "Corrupted zip : can't find end of central directory" + ); + } + } + this.reader.setIndex(offset); + var endOfCentralDirOffset = offset; + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if ( + this.diskNumber === utils.MAX_VALUE_16BITS || + this.diskWithCentralDirStart === + utils.MAX_VALUE_16BITS || + this.centralDirRecordsOnThisDisk === + utils.MAX_VALUE_16BITS || + this.centralDirRecords === + utils.MAX_VALUE_16BITS || + this.centralDirSize === + utils.MAX_VALUE_32BITS || + this.centralDirOffset === utils.MAX_VALUE_32BITS + ) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature( + sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR + ); + if (offset < 0) { + throw new Error( + "Corrupted zip : can't find the ZIP64 end of central directory locator" + ); + } + this.reader.setIndex(offset); + this.checkSignature( + sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR + ); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + if ( + !this.isSignature( + this.relativeOffsetEndOfZip64CentralDir, + sig.ZIP64_CENTRAL_DIRECTORY_END + ) + ) { + // console.warn("ZIP64 end of central directory not where expected."); + this.relativeOffsetEndOfZip64CentralDir = + this.reader.lastIndexOfSignature( + sig.ZIP64_CENTRAL_DIRECTORY_END + ); + if ( + this + .relativeOffsetEndOfZip64CentralDir < + 0 + ) { + throw new Error( + "Corrupted zip : can't find the ZIP64 end of central directory" + ); + } + } + this.reader.setIndex( + this.relativeOffsetEndOfZip64CentralDir + ); + this.checkSignature( + sig.ZIP64_CENTRAL_DIRECTORY_END + ); + this.readBlockZip64EndOfCentral(); + } + + var expectedEndOfCentralDirOffset = + this.centralDirOffset + this.centralDirSize; + if (this.zip64) { + expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator + expectedEndOfCentralDirOffset += + 12 /* should not include the leading 12 bytes */ + + this.zip64EndOfCentralSize; + } + + var extraBytes = + endOfCentralDirOffset - + expectedEndOfCentralDirOffset; + + if (extraBytes > 0) { + // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); + if ( + this.isSignature( + endOfCentralDirOffset, + sig.CENTRAL_FILE_HEADER + ) + ) { + // The offsets seem wrong, but we have something at the specified offset. + // So… we keep it. + } else { + // the offset is wrong, update the "zero" of the reader + // this happens if data has been prepended (crx files for example) + this.reader.zero = extraBytes; + } + } else if (extraBytes < 0) { + throw new Error( + "Corrupted zip: missing " + + Math.abs(extraBytes) + + " bytes." + ); + } + }, + prepareReader: function (data) { + var type = utils.getTypeOf(data); + utils.checkSupport(type); + if (type === "string" && !support.uint8array) { + this.reader = new StringReader( + data, + this.loadOptions.optimizedBinaryString + ); + } else if (type === "nodebuffer") { + this.reader = new NodeBufferReader(data); + } else if (support.uint8array) { + this.reader = new Uint8ArrayReader( + utils.transformTo("uint8array", data) + ); + } else if (support.array) { + this.reader = new ArrayReader( + utils.transformTo("array", data) + ); + } else { + throw new Error( + "Unexpected error: unsupported type '" + + type + + "'" + ); + } + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function (data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + }, + }; + // }}} end of ZipEntries + module.exports = ZipEntries; + }, + { + "./arrayReader": 1, + "./nodeBufferReader": 13, + "./object": 14, + "./signature": 15, + "./stringReader": 16, + "./support": 18, + "./uint8ArrayReader": 19, + "./utils": 22, + "./zipEntry": 24, + }, + ], + 24: [ + function (require, module, exports) { + "use strict"; + var StringReader = require("./stringReader"); + var utils = require("./utils"); + var CompressedObject = require("./compressedObject"); + var jszipProto = require("./object"); + var support = require("./support"); + + var MADE_BY_DOS = 0x00; + var MADE_BY_UNIX = 0x03; + + // class ZipEntry {{{ + /** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ + function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; + } + ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function () { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function () { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Prepare the function used to generate the compressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). + */ + prepareCompressedContent: function ( + reader, + from, + length + ) { + return function () { + var previousIndex = reader.index; + reader.setIndex(from); + var compressedFileData = + reader.readData(length); + reader.setIndex(previousIndex); + + return compressedFileData; + }; + }, + /** + * Prepare the function used to generate the uncompressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @param {JSZip.compression} compression the compression used on this file. + * @param {number} uncompressedSize the uncompressed size to expect. + * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). + */ + prepareContent: function ( + reader, + from, + length, + compression, + uncompressedSize + ) { + return function () { + var compressedFileData = utils.transformTo( + compression.uncompressInputType, + this.getCompressedContent() + ); + var uncompressedFileData = + compression.uncompress(compressedFileData); + + if ( + uncompressedFileData.length !== + uncompressedSize + ) { + throw new Error( + "Bug : uncompressed data size mismatch" + ); + } + + return uncompressedFileData; + }; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function (reader) { + var compression, localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + this.fileName = reader.readData( + this.fileNameLength + ); + reader.skip(localExtraFieldsLength); + + if ( + this.compressedSize == -1 || + this.uncompressedSize == -1 + ) { + throw new Error( + "Bug or corrupted zip : didn't get enough informations from the central directory " + + "(compressedSize == -1 || uncompressedSize == -1)" + ); + } + + compression = utils.findCompression( + this.compressionMethod + ); + if (compression === null) { + // no compression found + throw new Error( + "Corrupted zip : compression " + + utils.pretty(this.compressionMethod) + + " unknown (inner file : " + + utils.transformTo( + "string", + this.fileName + ) + + ")" + ); + } + this.decompressed = new CompressedObject(); + this.decompressed.compressedSize = + this.compressedSize; + this.decompressed.uncompressedSize = + this.uncompressedSize; + this.decompressed.crc32 = this.crc32; + this.decompressed.compressionMethod = + this.compressionMethod; + this.decompressed.getCompressedContent = + this.prepareCompressedContent( + reader, + reader.index, + this.compressedSize, + compression + ); + this.decompressed.getContent = this.prepareContent( + reader, + reader.index, + this.compressedSize, + compression, + this.uncompressedSize + ); + + // we need to compute the crc32... + if (this.loadOptions.checkCRC32) { + this.decompressed = utils.transformTo( + "string", + this.decompressed.getContent() + ); + if ( + jszipProto.crc32(this.decompressed) !== + this.crc32 + ) { + throw new Error( + "Corrupted zip : CRC32 mismatch" + ); + } + } + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function (reader) { + this.versionMadeBy = reader.readInt(2); + this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + this.fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + if (this.isEncrypted()) { + throw new Error( + "Encrypted zip are not supported" + ); + } + + this.fileName = reader.readData( + this.fileNameLength + ); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readData( + this.fileCommentLength + ); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = + this.externalFileAttributes & 0x0010 + ? true + : false; + + if (madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = + this.externalFileAttributes & 0x3f; + } + + if (madeBy === MADE_BY_UNIX) { + this.unixPermissions = + (this.externalFileAttributes >> 16) & + 0xffff; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if ( + !this.dir && + this.fileNameStr.slice(-1) === "/" + ) { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function (reader) { + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = new StringReader( + this.extraFields[0x0001].value + ); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if ( + this.uncompressedSize === utils.MAX_VALUE_32BITS + ) { + this.uncompressedSize = extraReader.readInt(8); + } + if ( + this.compressedSize === utils.MAX_VALUE_32BITS + ) { + this.compressedSize = extraReader.readInt(8); + } + if ( + this.localHeaderOffset === + utils.MAX_VALUE_32BITS + ) { + this.localHeaderOffset = extraReader.readInt(8); + } + if ( + this.diskNumberStart === utils.MAX_VALUE_32BITS + ) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function (reader) { + var start = reader.index, + extraFieldId, + extraFieldLength, + extraFieldValue; + + this.extraFields = this.extraFields || {}; + + while ( + reader.index < + start + this.extraFieldsLength + ) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = + reader.readString(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue, + }; + } + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function () { + var decodeParamType = support.uint8array + ? "uint8array" + : "array"; + if (this.useUTF8()) { + this.fileNameStr = jszipProto.utf8decode( + this.fileName + ); + this.fileCommentStr = jszipProto.utf8decode( + this.fileComment + ); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileNameStr = upath; + } else { + var fileNameByteArray = utils.transformTo( + decodeParamType, + this.fileName + ); + this.fileNameStr = + this.loadOptions.decodeFileName( + fileNameByteArray + ); + } + + var ucomment = + this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileCommentStr = ucomment; + } else { + var commentByteArray = utils.transformTo( + decodeParamType, + this.fileComment + ); + this.fileCommentStr = + this.loadOptions.decodeFileName( + commentByteArray + ); + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function () { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = new StringReader( + upathField.value + ); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if ( + jszipProto.crc32(this.fileName) !== + extraReader.readInt(4) + ) { + return null; + } + + return jszipProto.utf8decode( + extraReader.readString( + upathField.length - 5 + ) + ); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function () { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = new StringReader( + ucommentField.value + ); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if ( + jszipProto.crc32(this.fileComment) !== + extraReader.readInt(4) + ) { + return null; + } + + return jszipProto.utf8decode( + extraReader.readString( + ucommentField.length - 5 + ) + ); + } + return null; + }, + }; + module.exports = ZipEntry; + }, + { + "./compressedObject": 3, + "./object": 14, + "./stringReader": 16, + "./support": 18, + "./utils": 22, + }, + ], + 25: [ + function (require, module, exports) { + // Top level file is just a mixin of submodules & constants + "use strict"; + + var assign = require("./lib/utils/common").assign; + + var deflate = require("./lib/deflate"); + var inflate = require("./lib/inflate"); + var constants = require("./lib/zlib/constants"); + + var pako = {}; + + assign(pako, deflate, inflate, constants); + + module.exports = pako; + }, + { + "./lib/deflate": 26, + "./lib/inflate": 27, + "./lib/utils/common": 28, + "./lib/zlib/constants": 31, + }, + ], + 26: [ + function (require, module, exports) { + "use strict"; + + var zlib_deflate = require("./zlib/deflate"); + var utils = require("./utils/common"); + var strings = require("./utils/strings"); + var msg = require("./zlib/messages"); + var ZStream = require("./zlib/zstream"); + + var toString = Object.prototype.toString; + + /* Public constants ==========================================================*/ + /* ===========================================================================*/ + + var Z_NO_FLUSH = 0; + var Z_FINISH = 4; + + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_SYNC_FLUSH = 2; + + var Z_DEFAULT_COMPRESSION = -1; + + var Z_DEFAULT_STRATEGY = 0; + + var Z_DEFLATED = 8; + + /* ===========================================================================*/ + + /** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + + /* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overridden. + **/ + + /** + * Deflate.result -> Uint8Array|Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Deflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + + /** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + + /** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + /** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ + function Deflate(options) { + if (!(this instanceof Deflate)) + return new Deflate(options); + + this.options = utils.assign( + { + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: "", + }, + options || {} + ); + + var opt = this.options; + + if (opt.raw && opt.windowBits > 0) { + opt.windowBits = -opt.windowBits; + } else if ( + opt.gzip && + opt.windowBits > 0 && + opt.windowBits < 16 + ) { + opt.windowBits += 16; + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ""; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new ZStream(); + this.strm.avail_out = 0; + + var status = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK) { + throw new Error(msg[status]); + } + + if (opt.header) { + zlib_deflate.deflateSetHeader( + this.strm, + opt.header + ); + } + + if (opt.dictionary) { + var dict; + // Convert data if needed + if (typeof opt.dictionary === "string") { + // If we need to compress text, change encoding to utf8. + dict = strings.string2buf(opt.dictionary); + } else if ( + toString.call(opt.dictionary) === + "[object ArrayBuffer]" + ) { + dict = new Uint8Array(opt.dictionary); + } else { + dict = opt.dictionary; + } + + status = zlib_deflate.deflateSetDictionary( + this.strm, + dict + ); + + if (status !== Z_OK) { + throw new Error(msg[status]); + } + + this._dict_set = true; + } + } + + /** + * Deflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be + * converted to utf8 byte sequence. + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the compression context. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * array format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ + Deflate.prototype.push = function (data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + + if (this.ended) { + return false; + } + + _mode = + mode === ~~mode + ? mode + : mode === true + ? Z_FINISH + : Z_NO_FLUSH; + + // Convert data if needed + if (typeof data === "string") { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else if ( + toString.call(data) === "[object ArrayBuffer]" + ) { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status = zlib_deflate.deflate( + strm, + _mode + ); /* no bad return value */ + + if (status !== Z_STREAM_END && status !== Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + if ( + strm.avail_out === 0 || + (strm.avail_in === 0 && + (_mode === Z_FINISH || + _mode === Z_SYNC_FLUSH)) + ) { + if (this.options.to === "string") { + this.onData( + strings.buf2binstring( + utils.shrinkBuf( + strm.output, + strm.next_out + ) + ) + ); + } else { + this.onData( + utils.shrinkBuf( + strm.output, + strm.next_out + ) + ); + } + } + } while ( + (strm.avail_in > 0 || strm.avail_out === 0) && + status !== Z_STREAM_END + ); + + // Finalize on the last chunk. + if (_mode === Z_FINISH) { + status = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK; + } + + // callback interim results if Z_SYNC_FLUSH. + if (_mode === Z_SYNC_FLUSH) { + this.onEnd(Z_OK); + strm.avail_out = 0; + return true; + } + + return true; + }; + + /** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): output data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ + Deflate.prototype.onData = function (chunk) { + this.chunks.push(chunk); + }; + + /** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ + Deflate.prototype.onEnd = function (status) { + // On success - join + if (status === Z_OK) { + if (this.options.to === "string") { + this.result = this.chunks.join(""); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; + }; + + /** + * deflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate algorithm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * - dictionary + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ + function deflate(input, options) { + var deflator = new Deflate(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { + throw deflator.msg || msg[deflator.err]; + } + + return deflator.result; + } + + /** + * deflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ + function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate(input, options); + } + + /** + * gzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ + function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate(input, options); + } + + exports.Deflate = Deflate; + exports.deflate = deflate; + exports.deflateRaw = deflateRaw; + exports.gzip = gzip; + }, + { + "./utils/common": 28, + "./utils/strings": 29, + "./zlib/deflate": 33, + "./zlib/messages": 38, + "./zlib/zstream": 40, + }, + ], + 27: [ + function (require, module, exports) { + "use strict"; + + var zlib_inflate = require("./zlib/inflate"); + var utils = require("./utils/common"); + var strings = require("./utils/strings"); + var c = require("./zlib/constants"); + var msg = require("./zlib/messages"); + var ZStream = require("./zlib/zstream"); + var GZheader = require("./zlib/gzheader"); + + var toString = Object.prototype.toString; + + /** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + + /* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overridden. + **/ + + /** + * Inflate.result -> Uint8Array|Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Inflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + + /** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + + /** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + /** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ + function Inflate(options) { + if (!(this instanceof Inflate)) + return new Inflate(options); + + this.options = utils.assign( + { + chunkSize: 16384, + windowBits: 0, + to: "", + }, + options || {} + ); + + var opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if ( + opt.raw && + opt.windowBits >= 0 && + opt.windowBits < 16 + ) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { + opt.windowBits = -15; + } + } + + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ( + opt.windowBits >= 0 && + opt.windowBits < 16 && + !(options && options.windowBits) + ) { + opt.windowBits += 32; + } + + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if (opt.windowBits > 15 && opt.windowBits < 48) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ""; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new ZStream(); + this.strm.avail_out = 0; + + var status = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); + + if (status !== c.Z_OK) { + throw new Error(msg[status]); + } + + this.header = new GZheader(); + + zlib_inflate.inflateGetHeader(this.strm, this.header); + + // Setup dictionary + if (opt.dictionary) { + // Convert data if needed + if (typeof opt.dictionary === "string") { + opt.dictionary = strings.string2buf( + opt.dictionary + ); + } else if ( + toString.call(opt.dictionary) === + "[object ArrayBuffer]" + ) { + opt.dictionary = new Uint8Array(opt.dictionary); + } + if (opt.raw) { + //In raw mode we need to set the dictionary early + status = zlib_inflate.inflateSetDictionary( + this.strm, + opt.dictionary + ); + if (status !== c.Z_OK) { + throw new Error(msg[status]); + } + } + } + } + + /** + * Inflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the decompression context. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ + Inflate.prototype.push = function (data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var dictionary = this.options.dictionary; + var status, _mode; + var next_out_utf8, tail, utf8str; + + // Flag to properly process Z_BUF_ERROR on testing inflate call + // when we check that all output data was flushed. + var allowBufError = false; + + if (this.ended) { + return false; + } + _mode = + mode === ~~mode + ? mode + : mode === true + ? c.Z_FINISH + : c.Z_NO_FLUSH; + + // Convert data if needed + if (typeof data === "string") { + // Only binary strings can be decompressed on practice + strm.input = strings.binstring2buf(data); + } else if ( + toString.call(data) === "[object ArrayBuffer]" + ) { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + status = zlib_inflate.inflate( + strm, + c.Z_NO_FLUSH + ); /* no bad return value */ + + if (status === c.Z_NEED_DICT && dictionary) { + status = zlib_inflate.inflateSetDictionary( + this.strm, + dictionary + ); + } + + if ( + status === c.Z_BUF_ERROR && + allowBufError === true + ) { + status = c.Z_OK; + allowBufError = false; + } + + if ( + status !== c.Z_STREAM_END && + status !== c.Z_OK + ) { + this.onEnd(status); + this.ended = true; + return false; + } + + if (strm.next_out) { + if ( + strm.avail_out === 0 || + status === c.Z_STREAM_END || + (strm.avail_in === 0 && + (_mode === c.Z_FINISH || + _mode === c.Z_SYNC_FLUSH)) + ) { + if (this.options.to === "string") { + next_out_utf8 = strings.utf8border( + strm.output, + strm.next_out + ); + + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string( + strm.output, + next_out_utf8 + ); + + // move tail + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { + utils.arraySet( + strm.output, + strm.output, + next_out_utf8, + tail, + 0 + ); + } + + this.onData(utf8str); + } else { + this.onData( + utils.shrinkBuf( + strm.output, + strm.next_out + ) + ); + } + } + } + + // When no more input data, we should check that internal inflate buffers + // are flushed. The only way to do it when avail_out = 0 - run one more + // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR. + // Here we set flag to process this error properly. + // + // NOTE. Deflate does not return error in this case and does not needs such + // logic. + if (strm.avail_in === 0 && strm.avail_out === 0) { + allowBufError = true; + } + } while ( + (strm.avail_in > 0 || strm.avail_out === 0) && + status !== c.Z_STREAM_END + ); + + if (status === c.Z_STREAM_END) { + _mode = c.Z_FINISH; + } + + // Finalize on the last chunk. + if (_mode === c.Z_FINISH) { + status = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === c.Z_OK; + } + + // callback interim results if Z_SYNC_FLUSH. + if (_mode === c.Z_SYNC_FLUSH) { + this.onEnd(c.Z_OK); + strm.avail_out = 0; + return true; + } + + return true; + }; + + /** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): output data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ + Inflate.prototype.onData = function (chunk) { + this.chunks.push(chunk); + }; + + /** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called either after you tell inflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ + Inflate.prototype.onEnd = function (status) { + // On success - join + if (status === c.Z_OK) { + if (this.options.to === "string") { + // Glue & convert here, until we teach pako to send + // utf8 aligned strings to onData + this.result = this.chunks.join(""); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; + }; + + /** + * inflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Decompress `data` with inflate/ungzip and `options`. Autodetect + * format via wrapper header by default. That's why we don't provide + * separate `ungzip` method. + * + * Supported options are: + * + * - windowBits + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) + * , output; + * + * try { + * output = pako.inflate(input); + * } catch (err) + * console.log(err); + * } + * ``` + **/ + function inflate(input, options) { + var inflator = new Inflate(options); + + inflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (inflator.err) { + throw inflator.msg || msg[inflator.err]; + } + + return inflator.result; + } + + /** + * inflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * The same as [[inflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ + function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate(input, options); + } + + /** + * ungzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Just shortcut to [[inflate]], because it autodetects format + * by header.content. Done for convenience. + **/ + + exports.Inflate = Inflate; + exports.inflate = inflate; + exports.inflateRaw = inflateRaw; + exports.ungzip = inflate; + }, + { + "./utils/common": 28, + "./utils/strings": 29, + "./zlib/constants": 31, + "./zlib/gzheader": 34, + "./zlib/inflate": 36, + "./zlib/messages": 38, + "./zlib/zstream": 40, + }, + ], + 28: [ + function (require, module, exports) { + "use strict"; + + var TYPED_OK = + typeof Uint8Array !== "undefined" && + typeof Uint16Array !== "undefined" && + typeof Int32Array !== "undefined"; + + function _has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + exports.assign = function ( + obj /*from1, from2, from3, ...*/ + ) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { + continue; + } + + if (typeof source !== "object") { + throw new TypeError( + source + "must be non-object" + ); + } + + for (var p in source) { + if (_has(source, p)) { + obj[p] = source[p]; + } + } + } + + return obj; + }; + + // reduce buffer size, avoiding mem copy + exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { + return buf; + } + if (buf.subarray) { + return buf.subarray(0, size); + } + buf.length = size; + return buf; + }; + + var fnTyped = { + arraySet: function ( + dest, + src, + src_offs, + len, + dest_offs + ) { + if (src.subarray && dest.subarray) { + dest.set( + src.subarray(src_offs, src_offs + len), + dest_offs + ); + return; + } + // Fallback to ordinary array + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; + }, + }; + + var fnUntyped = { + arraySet: function ( + dest, + src, + src_offs, + len, + dest_offs + ) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + return [].concat.apply([], chunks); + }, + }; + + // Enable/Disable typed arrays use, for testing + // + exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } + }; + + exports.setTyped(TYPED_OK); + }, + {}, + ], + 29: [ + function (require, module, exports) { + // String encode/decode helpers + "use strict"; + + var utils = require("./common"); + + // Quick check if we can use fast array to bin string conversion + // + // - apply(Array) can fail on Android 2.2 + // - apply(Uint8Array) can fail on iOS 5.1 Safari + // + var STR_APPLY_OK = true; + var STR_APPLY_UIA_OK = true; + + try { + String.fromCharCode.apply(null, [0]); + } catch (__) { + STR_APPLY_OK = false; + } + try { + String.fromCharCode.apply(null, new Uint8Array(1)); + } catch (__) { + STR_APPLY_UIA_OK = false; + } + + // Table with utf8 lengths (calculated by first byte of sequence) + // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, + // because max possible codepoint is 0x10ffff + var _utf8len = new utils.Buf8(256); + for (var q = 0; q < 256; q++) { + _utf8len[q] = + q >= 252 + ? 6 + : q >= 248 + ? 5 + : q >= 240 + ? 4 + : q >= 224 + ? 3 + : q >= 192 + ? 2 + : 1; + } + _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start + + // convert string to array (typed, when possible) + exports.string2buf = function (str) { + var buf, + c, + c2, + m_pos, + i, + str_len = str.length, + buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ( + (c & 0xfc00) === 0xd800 && + m_pos + 1 < str_len + ) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = + 0x10000 + + ((c - 0xd800) << 10) + + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += + c < 0x80 + ? 1 + : c < 0x800 + ? 2 + : c < 0x10000 + ? 3 + : 4; + } + + // allocate buffer + buf = new utils.Buf8(buf_len); + + // convert + for (i = 0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ( + (c & 0xfc00) === 0xd800 && + m_pos + 1 < str_len + ) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = + 0x10000 + + ((c - 0xd800) << 10) + + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xc0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xe0 | (c >>> 12); + buf[i++] = 0x80 | ((c >>> 6) & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | ((c >>> 12) & 0x3f); + buf[i++] = 0x80 | ((c >>> 6) & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; + }; + + // Helper (used in 2 places) + function buf2binstring(buf, len) { + // On Chrome, the arguments in a function call that are allowed is `65534`. + // If the length of the buffer is smaller than that, we can use this optimization, + // otherwise we will take a slower path. + if (len < 65534) { + if ( + (buf.subarray && STR_APPLY_UIA_OK) || + (!buf.subarray && STR_APPLY_OK) + ) { + return String.fromCharCode.apply( + null, + utils.shrinkBuf(buf, len) + ); + } + } + + var result = ""; + for (var i = 0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; + } + + // Convert byte array to binary string + exports.buf2binstring = function (buf) { + return buf2binstring(buf, buf.length); + }; + + // Convert binary string (typed, when possible) + exports.binstring2buf = function (str) { + var buf = new utils.Buf8(str.length); + for (var i = 0, len = buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; + }; + + // convert array to string + exports.buf2string = function (buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len * 2); + + for (out = 0, i = 0; i < len; ) { + c = buf[i++]; + // quick process ascii + if (c < 0x80) { + utf16buf[out++] = c; + continue; + } + + c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { + utf16buf[out++] = 0xfffd; + i += c_len - 1; + continue; + } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { + utf16buf[out++] = 0xfffd; + continue; + } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + return buf2binstring(utf16buf, out); + }; + + // Calculate max possible position in utf8 buffer, + // that will not break sequence. If that's not possible + // - (very small limits) return max size as is. + // + // buf[] - utf8 bytes array + // max - length limit (mandatory); + exports.utf8border = function (buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { + max = buf.length; + } + + // go back from last position, until start of sequence found + pos = max - 1; + while (pos >= 0 && (buf[pos] & 0xc0) === 0x80) { + pos--; + } + + // Very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { + return max; + } + + // If we came to start of buffer - that means buffer is too small, + // return max too. + if (pos === 0) { + return max; + } + + return pos + _utf8len[buf[pos]] > max ? pos : max; + }; + }, + { "./common": 28 }, + ], + 30: [ + function (require, module, exports) { + "use strict"; + + // Note: adler32 takes 12% for level 0 and 2% for level 6. + // It isn't worth it to make additional optimizations as in original. + // Small size is preferable. + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) | 0, + s2 = ((adler >>> 16) & 0xffff) | 0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) | 0; + s2 = (s2 + s1) | 0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return s1 | (s2 << 16) | 0; + } + + module.exports = adler32; + }, + {}, + ], + 31: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + module.exports = { + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8, + //Z_NULL: null // Use -1 or null inline, depending on var type + }; + }, + {}, + ], + 32: [ + function (require, module, exports) { + "use strict"; + + // Note: we can't get significant speed boost here. + // So write code to minimize size - no pregenerated tables + // and array tools dependencies. + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + // Use ordinary array, since untyped makes no boost here + function makeTable() { + var c, + table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; + } + table[n] = c; + } + + return table; + } + + // Create table on load. Just 255 signed longs. Not a problem. + var crcTable = makeTable(); + + function crc32(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; + + crc ^= -1; + + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xff]; + } + + return crc ^ -1; // >>> 0; + } + + module.exports = crc32; + }, + {}, + ], + 33: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + var utils = require("../utils/common"); + var trees = require("./trees"); + var adler32 = require("./adler32"); + var crc32 = require("./crc32"); + var msg = require("./messages"); + + /* Public constants ==========================================================*/ + /* ===========================================================================*/ + + /* Allowed flush values; see deflate() and inflate() below for details */ + var Z_NO_FLUSH = 0; + var Z_PARTIAL_FLUSH = 1; + //var Z_SYNC_FLUSH = 2; + var Z_FULL_FLUSH = 3; + var Z_FINISH = 4; + var Z_BLOCK = 5; + //var Z_TREES = 6; + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + var Z_OK = 0; + var Z_STREAM_END = 1; + //var Z_NEED_DICT = 2; + //var Z_ERRNO = -1; + var Z_STREAM_ERROR = -2; + var Z_DATA_ERROR = -3; + //var Z_MEM_ERROR = -4; + var Z_BUF_ERROR = -5; + //var Z_VERSION_ERROR = -6; + + /* compression levels */ + //var Z_NO_COMPRESSION = 0; + //var Z_BEST_SPEED = 1; + //var Z_BEST_COMPRESSION = 9; + var Z_DEFAULT_COMPRESSION = -1; + + var Z_FILTERED = 1; + var Z_HUFFMAN_ONLY = 2; + var Z_RLE = 3; + var Z_FIXED = 4; + var Z_DEFAULT_STRATEGY = 0; + + /* Possible values of the data_type field (though see inflate()) */ + //var Z_BINARY = 0; + //var Z_TEXT = 1; + //var Z_ASCII = 1; // = Z_TEXT + var Z_UNKNOWN = 2; + + /* The deflate compression method */ + var Z_DEFLATED = 8; + + /*============================================================================*/ + + var MAX_MEM_LEVEL = 9; + /* Maximum value for memLevel in deflateInit2 */ + var MAX_WBITS = 15; + /* 32K LZ77 window */ + var DEF_MEM_LEVEL = 8; + + var LENGTH_CODES = 29; + /* number of length codes, not counting the special END_BLOCK code */ + var LITERALS = 256; + /* number of literal bytes 0..255 */ + var L_CODES = LITERALS + 1 + LENGTH_CODES; + /* number of Literal or Length codes, including the END_BLOCK code */ + var D_CODES = 30; + /* number of distance codes */ + var BL_CODES = 19; + /* number of codes used to transfer the bit lengths */ + var HEAP_SIZE = 2 * L_CODES + 1; + /* maximum heap size */ + var MAX_BITS = 15; + /* All codes must not exceed MAX_BITS bits */ + + var MIN_MATCH = 3; + var MAX_MATCH = 258; + var MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1; + + var PRESET_DICT = 0x20; + + var INIT_STATE = 42; + var EXTRA_STATE = 69; + var NAME_STATE = 73; + var COMMENT_STATE = 91; + var HCRC_STATE = 103; + var BUSY_STATE = 113; + var FINISH_STATE = 666; + + var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ + var BS_BLOCK_DONE = 2; /* block flush performed */ + var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ + var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + + var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + + function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; + } + + function rank(f) { + return (f << 1) - (f > 4 ? 9 : 0); + } + + function zero(buf) { + var len = buf.length; + while (--len >= 0) { + buf[len] = 0; + } + } + + /* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ + function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { + return; + } + + utils.arraySet( + strm.output, + s.pending_buf, + s.pending_out, + len, + strm.next_out + ); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } + } + + function flush_block_only(s, last) { + trees._tr_flush_block( + s, + s.block_start >= 0 ? s.block_start : -1, + s.strstart - s.block_start, + last + ); + s.block_start = s.strstart; + flush_pending(s.strm); + } + + function put_byte(s, b) { + s.pending_buf[s.pending++] = b; + } + + /* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ + function putShortMSB(s, b) { + // put_byte(s, (Byte)(b >> 8)); + // put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; + } + + /* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ + function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { + len = size; + } + if (len === 0) { + return 0; + } + + strm.avail_in -= len; + + // zmemcpy(buf, strm->next_in, len); + utils.arraySet( + buf, + strm.input, + strm.next_in, + len, + start + ); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; + } + + /* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ + function longest_match(s, cur_match) { + var chain_length = + s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = + s.prev_length; /* best match length so far */ + var nice_match = + s.nice_match; /* stop if match long enough */ + var limit = + s.strstart > s.w_size - MIN_LOOKAHEAD + ? s.strstart - (s.w_size - MIN_LOOKAHEAD) + : 0; /*NIL*/ + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { + nice_match = s.lookahead; + } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if ( + _win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1] + ) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while ( + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && + scan < strend + ); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ( + (cur_match = prev[cur_match & wmask]) > limit && + --chain_length !== 0 + ); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; + } + + /* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ + function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if ( + s.strstart >= + _w_size + (_w_size - MIN_LOOKAHEAD) + ) { + utils.arraySet( + s.window, + s.window, + _w_size, + _w_size, + 0 + ); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = m >= _w_size ? m - _w_size : 0; + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = m >= _w_size ? m - _w_size : 0; + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf( + s.strm, + s.window, + s.strstart + s.lookahead, + more + ); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[str + 1]) & + s.hash_mask; + //#if MIN_MATCH != 3 + // Call update_hash() MIN_MATCH-3 more times + //#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[str + MIN_MATCH - 1]) & + s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while ( + s.lookahead < MIN_LOOKAHEAD && + s.strm.avail_in !== 0 + ); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + // if (s.high_water < s.window_size) { + // var curr = s.strstart + s.lookahead; + // var init = 0; + // + // if (s.high_water < curr) { + // /* Previous high water mark below current data -- zero WIN_INIT + // * bytes or up to end of window, whichever is less. + // */ + // init = s.window_size - curr; + // if (init > WIN_INIT) + // init = WIN_INIT; + // zmemzero(s->window + curr, (unsigned)init); + // s->high_water = curr + init; + // } + // else if (s->high_water < (ulg)curr + WIN_INIT) { + // /* High water mark at or above current data, but below current data + // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + // * to end of window, whichever is less. + // */ + // init = (ulg)curr + WIN_INIT - s->high_water; + // if (init > s->window_size - s->high_water) + // init = s->window_size - s->high_water; + // zmemzero(s->window + s->high_water, (unsigned)init); + // s->high_water += init; + // } + // } + // + // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + // "not enough room for search"); + } + + /* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ + function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); + // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || + // s.block_start >= s.w_size)) { + // throw new Error("slide too late"); + // } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); + // if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if ( + s.strstart - s.block_start >= + s.w_size - MIN_LOOKAHEAD + ) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; + } + + /* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ + function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if ( + s.lookahead < MIN_LOOKAHEAD && + flush === Z_NO_FLUSH + ) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0 /*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[s.strstart + MIN_MATCH - 1]) & + s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = + s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if ( + hash_head !== 0 /*NIL*/ && + s.strstart - hash_head <= + s.w_size - MIN_LOOKAHEAD + ) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally( + s, + s.strstart - s.match_start, + s.match_length - MIN_MATCH + ); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if ( + s.match_length <= + s.max_lazy_match /*max_insert_length*/ && + s.lookahead >= MIN_MATCH + ) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[ + s.strstart + MIN_MATCH - 1 + ]) & + s.hash_mask; + hash_head = s.prev[ + s.strstart & s.w_mask + ] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[s.strstart + 1]) & + s.hash_mask; + + //#if MIN_MATCH != 3 + // Call UPDATE_HASH() MIN_MATCH-3 more times + //#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally( + s, + 0, + s.window[s.strstart] + ); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = + s.strstart < MIN_MATCH - 1 + ? s.strstart + : MIN_MATCH - 1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; + } + + /* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ + function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if ( + s.lookahead < MIN_LOOKAHEAD && + flush === Z_NO_FLUSH + ) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0 /*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[s.strstart + MIN_MATCH - 1]) & + s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = + s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + + if ( + hash_head !== 0 /*NIL*/ && + s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= + s.w_size - MIN_LOOKAHEAD /*MAX_DIST(s)*/ + ) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if ( + s.match_length <= 5 && + (s.strategy === Z_FILTERED || + (s.match_length === MIN_MATCH && + s.strstart - s.match_start > + 4096) /*TOO_FAR*/) + ) { + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if ( + s.prev_length >= MIN_MATCH && + s.match_length <= s.prev_length + ) { + max_insert = + s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally( + s, + s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH + ); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[ + s.strstart + MIN_MATCH - 1 + ]) & + s.hash_mask; + hash_head = s.prev[ + s.strstart & s.w_mask + ] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally( + s, + 0, + s.window[s.strstart - 1] + ); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally( + s, + 0, + s.window[s.strstart - 1] + ); + + s.match_available = 0; + } + s.insert = + s.strstart < MIN_MATCH - 1 + ? s.strstart + : MIN_MATCH - 1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; + } + + /* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ + function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, + strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if ( + s.lookahead <= MAX_MATCH && + flush === Z_NO_FLUSH + ) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if ( + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] + ) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while ( + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + prev === _win[++scan] && + scan < strend + ); + s.match_length = + MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally( + s, + 1, + s.match_length - MIN_MATCH + ); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally( + s, + 0, + s.window[s.strstart] + ); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; + } + + /* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ + function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally( + s, + 0, + s.window[s.strstart] + ); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; + } + + /* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + function Config( + good_length, + max_lazy, + nice_length, + max_chain, + func + ) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; + } + + var configuration_table; + + configuration_table = [ + /* good lazy nice chain */ + new Config( + 0, + 0, + 0, + 0, + deflate_stored + ) /* 0 store only */, + new Config( + 4, + 4, + 8, + 4, + deflate_fast + ) /* 1 max speed, no lazy matches */, + new Config(4, 5, 16, 8, deflate_fast) /* 2 */, + new Config(4, 6, 32, 32, deflate_fast) /* 3 */, + + new Config( + 4, + 4, + 16, + 16, + deflate_slow + ) /* 4 lazy matches */, + new Config(8, 16, 32, 32, deflate_slow) /* 5 */, + new Config(8, 16, 128, 128, deflate_slow) /* 6 */, + new Config(8, 32, 128, 256, deflate_slow) /* 7 */, + new Config(32, 128, 258, 1024, deflate_slow) /* 8 */, + new Config( + 32, + 258, + 258, + 4096, + deflate_slow + ) /* 9 max compression */, + ]; + + /* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ + function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = + configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = + configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; + } + + function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = + null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = + -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); + this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS + 1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16( + 2 * L_CODES + 1 + ); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + } + + function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = s.wrap ? INIT_STATE : BUSY_STATE; + strm.adler = + s.wrap === 2 + ? 0 // crc32(0, Z_NULL, 0) + : 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; + } + + function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; + } + + function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + if (strm.state.wrap !== 2) { + return Z_STREAM_ERROR; + } + strm.state.gzhead = head; + return Z_OK; + } + + function deflateInit2( + strm, + level, + method, + windowBits, + memLevel, + strategy + ) { + if (!strm) { + // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { + /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + if ( + memLevel < 1 || + memLevel > MAX_MEM_LEVEL || + method !== Z_DEFLATED || + windowBits < 8 || + windowBits > 15 || + level < 0 || + level > 9 || + strategy < 0 || + strategy > Z_FIXED + ) { + return err(strm, Z_STREAM_ERROR); + } + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~( + (s.hash_bits + MIN_MATCH - 1) / + MIN_MATCH + ); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = + 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + + //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + //s->pending_buf = (uchf *) overlay; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) + //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s.d_buf = 1 * s.lit_bufsize; + + //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); + } + + function deflateInit(strm, level) { + return deflateInit2( + strm, + level, + Z_DEFLATED, + MAX_WBITS, + DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY + ); + } + + function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if ( + !strm || + !strm.state || + flush > Z_BLOCK || + flush < 0 + ) { + return strm + ? err(strm, Z_STREAM_ERROR) + : Z_STREAM_ERROR; + } + + s = strm.state; + + if ( + !strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH) + ) { + return err( + strm, + strm.avail_out === 0 + ? Z_BUF_ERROR + : Z_STREAM_ERROR + ); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + if (s.wrap === 2) { + // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { + // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte( + s, + s.level === 9 + ? 2 + : s.strategy >= Z_HUFFMAN_ONLY || + s.level < 2 + ? 4 + : 0 + ); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } else { + put_byte( + s, + (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte( + s, + s.level === 9 + ? 2 + : s.strategy >= Z_HUFFMAN_ONLY || + s.level < 2 + ? 4 + : 0 + ); + put_byte(s, s.gzhead.os & 0xff); + if ( + s.gzhead.extra && + s.gzhead.extra.length + ) { + put_byte( + s, + s.gzhead.extra.length & 0xff + ); + put_byte( + s, + (s.gzhead.extra.length >> 8) & 0xff + ); + } + if (s.gzhead.hcrc) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending, + 0 + ); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } // DEFLATE header + else { + var header = + (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if ( + s.strategy >= Z_HUFFMAN_ONLY || + s.level < 2 + ) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= level_flags << 6; + if (s.strstart !== 0) { + header |= PRESET_DICT; + } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + + //#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra /* != Z_NULL*/) { + beg = + s.pending; /* start of bytes to update crc */ + + while ( + s.gzindex < + (s.gzhead.extra.length & 0xffff) + ) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte( + s, + s.gzhead.extra[s.gzindex] & 0xff + ); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name /* != Z_NULL*/) { + beg = + s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = + s.gzhead.name.charCodeAt( + s.gzindex++ + ) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment /* != Z_NULL*/) { + beg = + s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = + s.gzhead.comment.charCodeAt( + s.gzindex++ + ) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32( + strm.adler, + s.pending_buf, + s.pending - beg, + beg + ); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } else { + s.status = BUSY_STATE; + } + } + //#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if ( + strm.avail_in === 0 && + rank(flush) <= rank(old_flush) && + flush !== Z_FINISH + ) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if ( + strm.avail_in !== 0 || + s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE) + ) { + var bstate = + s.strategy === Z_HUFFMAN_ONLY + ? deflate_huff(s, flush) + : s.strategy === Z_RLE + ? deflate_rle(s, flush) + : configuration_table[s.level].func( + s, + flush + ); + + if ( + bstate === BS_FINISH_STARTED || + bstate === BS_FINISH_DONE + ) { + s.status = FINISH_STATE; + } + if ( + bstate === BS_NEED_MORE || + bstate === BS_FINISH_STARTED + ) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } else if (flush !== Z_BLOCK) { + /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = + -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { + return Z_OK; + } + if (s.wrap <= 0) { + return Z_STREAM_END; + } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } else { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { + s.wrap = -s.wrap; + } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; + } + + function deflateEnd(strm) { + var status; + + if (!strm /*== Z_NULL*/ || !strm.state /*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if ( + status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE + ? err(strm, Z_DATA_ERROR) + : Z_OK; + } + + /* ========================================================================= + * Initializes the compression dictionary from the given byte + * sequence without producing any compressed output. + */ + function deflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var s; + var str, n; + var wrap; + var avail; + var next; + var input; + var tmpDict; + + if (!strm /*== Z_NULL*/ || !strm.state /*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + s = strm.state; + wrap = s.wrap; + + if ( + wrap === 2 || + (wrap === 1 && s.status !== INIT_STATE) || + s.lookahead + ) { + return Z_STREAM_ERROR; + } + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap === 1) { + /* adler32(strm->adler, dictionary, dictLength); */ + strm.adler = adler32( + strm.adler, + dictionary, + dictLength, + 0 + ); + } + + s.wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s.w_size) { + if (wrap === 0) { + /* already empty otherwise */ + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + /* use the tail */ + // dictionary = dictionary.slice(dictLength - s.w_size); + tmpDict = new utils.Buf8(s.w_size); + utils.arraySet( + tmpDict, + dictionary, + dictLength - s.w_size, + s.w_size, + 0 + ); + dictionary = tmpDict; + dictLength = s.w_size; + } + /* insert dictionary into window and hash */ + avail = strm.avail_in; + next = strm.next_in; + input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + str = s.strstart; + n = s.lookahead - (MIN_MATCH - 1); + do { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = + ((s.ins_h << s.hash_shift) ^ + s.window[str + MIN_MATCH - 1]) & + s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK; + } + + exports.deflateInit = deflateInit; + exports.deflateInit2 = deflateInit2; + exports.deflateReset = deflateReset; + exports.deflateResetKeep = deflateResetKeep; + exports.deflateSetHeader = deflateSetHeader; + exports.deflate = deflate; + exports.deflateEnd = deflateEnd; + exports.deflateSetDictionary = deflateSetDictionary; + exports.deflateInfo = "pako deflate (from Nodeca project)"; + + /* Not implemented + exports.deflateBound = deflateBound; + exports.deflateCopy = deflateCopy; + exports.deflateParams = deflateParams; + exports.deflatePending = deflatePending; + exports.deflatePrime = deflatePrime; + exports.deflateTune = deflateTune; + */ + }, + { + "../utils/common": 28, + "./adler32": 30, + "./crc32": 32, + "./messages": 38, + "./trees": 39, + }, + ], + 34: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + function GZheader() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications + + // + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes + // + + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ""; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ""; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; + } + + module.exports = GZheader; + }, + {}, + ], + 35: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + // See state defs from inflate.js + var BAD = 30; /* got a data error -- remain here until reset */ + var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + + /* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ + module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ + //#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ + //#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + var s_window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); + //#ifdef INFLATE_STRICT + dmax = state.dmax; + //#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: for (;;) { + // Goto emulation + op = here >>> 24 /*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff /*here.op*/; + if (op === 0) { + /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff /*here.val*/; + } else if (op & 16) { + /* length base */ + len = here & 0xffff /*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: for (;;) { + // goto emulation + op = here >>> 24 /*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff /*here.op*/; + + if (op & 16) { + /* distance base */ + dist = here & 0xffff /*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += + input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); + //#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = + "invalid distance too far back"; + state.mode = BAD; + break top; + } + //#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = + _out - + beg; /* max distance in output */ + if (dist > op) { + /* see if copy from window */ + op = + dist - + op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = + "invalid distance too far back"; + state.mode = BAD; + break top; + } + + // (!) This block is disabled in zlib defaults, + // don't enable it for binary compatibility + //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + // if (len <= op - whave) { + // do { + // output[_out++] = 0; + // } while (--len); + // continue top; + // } + // len -= op - whave; + // do { + // output[_out++] = 0; + // } while (--op > whave); + // if (op === 0) { + // from = _out - dist; + // do { + // output[_out++] = output[from++]; + // } while (--len); + // continue top; + // } + //#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { + /* very common case */ + from += wsize - op; + if (op < len) { + /* some from window */ + len -= op; + do { + output[_out++] = + s_window[ + from++ + ]; + } while (--op); + from = + _out - + dist; /* rest from output */ + from_source = output; + } + } else if (wnext < op) { + /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { + /* some from end of window */ + len -= op; + do { + output[_out++] = + s_window[ + from++ + ]; + } while (--op); + from = 0; + if (wnext < len) { + /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = + s_window[ + from++ + ]; + } while (--op); + from = + _out - + dist; /* rest from output */ + from_source = + output; + } + } + } else { + /* contiguous in window */ + from += wnext - op; + if (op < len) { + /* some from window */ + len -= op; + do { + output[_out++] = + s_window[ + from++ + ]; + } while (--op); + from = + _out - + dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = + from_source[from++]; + output[_out++] = + from_source[from++]; + output[_out++] = + from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = + from_source[from++]; + if (len > 1) { + output[_out++] = + from_source[from++]; + } + } + } else { + from = + _out - + dist; /* copy direct from output */ + do { + /* minimum length is three */ + output[_out++] = + output[from++]; + output[_out++] = + output[from++]; + output[_out++] = + output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = + output[from++]; + if (len > 1) { + output[_out++] = + output[from++]; + } + } + } + } else if ((op & 64) === 0) { + /* 2nd level distance code */ + here = + dcode[ + (here & + 0xffff) /*here.val*/ + + (hold & ((1 << op) - 1)) + ]; + continue dodist; + } else { + strm.msg = "invalid distance code"; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } else if ((op & 64) === 0) { + /* 2nd level length code */ + here = + lcode[ + (here & 0xffff) /*here.val*/ + + (hold & ((1 << op) - 1)) + ]; + continue dolen; + } else if (op & 32) { + /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } else { + strm.msg = "invalid literal/length code"; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = + _in < last ? 5 + (last - _in) : 5 - (_in - last); + strm.avail_out = + _out < end + ? 257 + (end - _out) + : 257 - (_out - end); + state.hold = hold; + state.bits = bits; + return; + }; + }, + {}, + ], + 36: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + var utils = require("../utils/common"); + var adler32 = require("./adler32"); + var crc32 = require("./crc32"); + var inflate_fast = require("./inffast"); + var inflate_table = require("./inftrees"); + + var CODES = 0; + var LENS = 1; + var DISTS = 2; + + /* Public constants ==========================================================*/ + /* ===========================================================================*/ + + /* Allowed flush values; see deflate() and inflate() below for details */ + //var Z_NO_FLUSH = 0; + //var Z_PARTIAL_FLUSH = 1; + //var Z_SYNC_FLUSH = 2; + //var Z_FULL_FLUSH = 3; + var Z_FINISH = 4; + var Z_BLOCK = 5; + var Z_TREES = 6; + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_NEED_DICT = 2; + //var Z_ERRNO = -1; + var Z_STREAM_ERROR = -2; + var Z_DATA_ERROR = -3; + var Z_MEM_ERROR = -4; + var Z_BUF_ERROR = -5; + //var Z_VERSION_ERROR = -6; + + /* The deflate compression method */ + var Z_DEFLATED = 8; + + /* STATES ====================================================================*/ + /* ===========================================================================*/ + + var HEAD = 1; /* i: waiting for magic header */ + var FLAGS = 2; /* i: waiting for method and flags (gzip) */ + var TIME = 3; /* i: waiting for modification time (gzip) */ + var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ + var EXLEN = 5; /* i: waiting for extra length (gzip) */ + var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ + var NAME = 7; /* i: waiting for end of file name (gzip) */ + var COMMENT = 8; /* i: waiting for end of comment (gzip) */ + var HCRC = 9; /* i: waiting for header crc (gzip) */ + var DICTID = 10; /* i: waiting for dictionary check value */ + var DICT = 11; /* waiting for inflateSetDictionary() call */ + var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ + var STORED = 14; /* i: waiting for stored size (length and complement) */ + var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ + var COPY = 16; /* i/o: waiting for input or output to copy stored block */ + var TABLE = 17; /* i: waiting for dynamic block table lengths */ + var LENLENS = 18; /* i: waiting for code length code lengths */ + var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ + var LEN_ = 20; /* i: same as LEN below, but only first time in */ + var LEN = 21; /* i: waiting for length/lit/eob code */ + var LENEXT = 22; /* i: waiting for length extra bits */ + var DIST = 23; /* i: waiting for distance code */ + var DISTEXT = 24; /* i: waiting for distance extra bits */ + var MATCH = 25; /* o: waiting for output space to copy string */ + var LIT = 26; /* o: waiting for output space to write literal */ + var CHECK = 27; /* i: waiting for 32-bit check value */ + var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ + var DONE = 29; /* finished check, done -- remain here until reset */ + var BAD = 30; /* got a data error -- remain here until reset */ + var MEM = 31; /* got an inflate() memory error -- remain here until reset */ + var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + + /* ===========================================================================*/ + + var ENOUGH_LENS = 852; + var ENOUGH_DISTS = 592; + //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + + var MAX_WBITS = 15; + /* 32K LZ77 window */ + var DEF_WBITS = MAX_WBITS; + + function zswap32(q) { + return ( + ((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24) + ); + } + + function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = + null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = + null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = + null; /* starting table for length/literal codes */ + this.distcode = + null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16( + 320 + ); /* temporary storage for code lengths */ + this.work = new utils.Buf16( + 288 + ); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = + null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = + null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ + } + + function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ""; /*Z_NULL*/ + if (state.wrap) { + /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null /*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32( + ENOUGH_LENS + ); + state.distcode = state.distdyn = new utils.Buf32( + ENOUGH_DISTS + ); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; + } + + function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + } + + function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if ( + state.window !== null && + state.wbits !== windowBits + ) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); + } + + function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { + return Z_STREAM_ERROR; + } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null /*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null /*Z_NULL*/; + } + return ret; + } + + function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); + } + + /* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ + var virgin = true; + + var lenfix, distfix; // We have no pointers in JS, so keep tables separate + + function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { + state.lens[sym++] = 8; + } + while (sym < 256) { + state.lens[sym++] = 9; + } + while (sym < 280) { + state.lens[sym++] = 7; + } + while (sym < 288) { + state.lens[sym++] = 8; + } + + inflate_table( + LENS, + state.lens, + 0, + 288, + lenfix, + 0, + state.work, + { bits: 9 } + ); + + /* distance table */ + sym = 0; + while (sym < 32) { + state.lens[sym++] = 5; + } + + inflate_table( + DISTS, + state.lens, + 0, + 32, + distfix, + 0, + state.work, + { bits: 5 } + ); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; + } + + /* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ + function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet( + state.window, + src, + end - state.wsize, + state.wsize, + 0 + ); + state.wnext = 0; + state.whave = state.wsize; + } else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet( + state.window, + src, + end - copy, + dist, + state.wnext + ); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet( + state.window, + src, + end - copy, + copy, + 0 + ); + state.wnext = copy; + state.whave = state.wsize; + } else { + state.wnext += dist; + if (state.wnext === state.wsize) { + state.wnext = 0; + } + if (state.whave < state.wsize) { + state.whave += dist; + } + } + } + return 0; + } + + function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, + _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8( + 4 + ); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = + /* permutation of code lengths */ + [ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, + 13, 2, 14, 1, 15, + ]; + + if ( + !strm || + !strm.state || + !strm.output || + (!strm.input && strm.avail_in !== 0) + ) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { + state.mode = TYPEDO; + } /* skip check */ + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + // goto emulation + inf_leave: for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.wrap & 2 && hold === 0x8b1f) { + /* gzip header */ + state.check = 0 /*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32( + state.check, + hbuf, + 2, + 0 + ); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if ( + !( + state.wrap & 1 + ) /* check if zlib header allowed */ || + (((hold & 0xff) /*BITS(8)*/ << 8) + + (hold >> 8)) % + 31 + ) { + strm.msg = "incorrect header check"; + state.mode = BAD; + break; + } + if ( + (hold & 0x0f) /*BITS(4)*/ !== + Z_DEFLATED + ) { + strm.msg = "unknown compression method"; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f) /*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } else if (len > state.wbits) { + strm.msg = "invalid window size"; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = + state.check = 1 /*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = "unknown compression method"; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = "unknown header flags set"; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = (hold >> 8) & 1; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32( + state.check, + hbuf, + 2, + 0 + ); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32( + state.check, + hbuf, + 4, + 0 + ); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = hold & 0xff; + state.head.os = hold >> 8; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32( + state.check, + hbuf, + 2, + 0 + ); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32( + state.check, + hbuf, + 2, + 0 + ); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } else if (state.head) { + state.head.extra = null /*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { + copy = have; + } + if (copy) { + if (state.head) { + len = + state.head.extra_len - + state.length; + if (!state.head.extra) { + // Use untyped array for more convenient processing later + state.head.extra = + new Array( + state.head.extra_len + ); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32( + state.check, + input, + copy, + next + ); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { + break inf_leave; + } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { + break inf_leave; + } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if ( + state.head && + len && + state.length < + 65536 /*state.head.name_max*/ + ) { + state.head.name += + String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32( + state.check, + input, + copy, + next + ); + } + have -= copy; + next += copy; + if (len) { + break inf_leave; + } + } else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { + break inf_leave; + } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if ( + state.head && + len && + state.length < + 65536 /*state.head.comm_max*/ + ) { + state.head.comment += + String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32( + state.check, + input, + copy, + next + ); + } + have -= copy; + next += copy; + if (len) { + break inf_leave; + } + } else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = "header crc mismatch"; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = + (state.flags >> 9) & 1; + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = + state.check = 1 /*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if ( + flush === Z_BLOCK || + flush === Z_TREES + ) { + break inf_leave; + } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = hold & 0x01 /*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch (hold & 0x03 /*BITS(2)*/) { + case 0 /* stored block */: + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1 /* fixed block */: + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = + LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2 /* dynamic block */: + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = "invalid block type"; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ( + (hold & 0xffff) !== + ((hold >>> 16) ^ 0xffff) + ) { + strm.msg = + "invalid stored block lengths"; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { + break inf_leave; + } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { + copy = have; + } + if (copy > left) { + copy = left; + } + if (copy === 0) { + break inf_leave; + } + //--- zmemcpy(put, next, copy); --- + utils.arraySet( + output, + input, + next, + copy, + put + ); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = + (hold & 0x1f) /*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f) /*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f) /*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + //#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = + "too many length or distance symbols"; + state.mode = BAD; + break; + } + //#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = + hold & 0x07; //BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inflate_table( + CODES, + state.lens, + 0, + 19, + state.lencode, + 0, + state.work, + opts + ); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = "invalid code lengths set"; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while ( + state.have < + state.nlen + state.ndist + ) { + for (;;) { + here = + state.lencode[ + hold & + ((1 << state.lenbits) - + 1) + ]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { + break; + } + //--- PULLBYTE() ---// + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += + input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = + "invalid bit length repeat"; + state.mode = BAD; + break; + } + len = + state.lens[state.have - 1]; + copy = 3 + (hold & 0x03); //BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += + input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07); //BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += + input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f); //BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if ( + state.have + copy > + state.nlen + state.ndist + ) { + strm.msg = + "invalid bit length repeat"; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { + break; + } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = + "invalid code -- missing end-of-block"; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inflate_table( + LENS, + state.lens, + 0, + state.nlen, + state.lencode, + 0, + state.work, + opts + ); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = + "invalid literal/lengths set"; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table( + DISTS, + state.lens, + state.nlen, + state.ndist, + state.distcode, + 0, + state.work, + opts + ); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = "invalid distances set"; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { + break inf_leave; + } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = + state.lencode[ + hold & + ((1 << state.lenbits) - 1) + ]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { + break; + } + //--- PULLBYTE() ---// + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = + state.lencode[ + last_val + + ((hold & + ((1 << + (last_bits + + last_op)) - + 1)) /*BITS(last.bits + last.op)*/ >> + last_bits) + ]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (last_bits + here_bits <= bits) { + break; + } + //--- PULLBYTE() ---// + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = + "invalid literal/length code"; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += + hold & + ((1 << state.extra) - + 1) /*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = + state.distcode[ + hold & + ((1 << state.distbits) - 1) + ]; /*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { + break; + } + //--- PULLBYTE() ---// + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = + state.distcode[ + last_val + + ((hold & + ((1 << + (last_bits + + last_op)) - + 1)) /*BITS(last.bits + last.op)*/ >> + last_bits) + ]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (last_bits + here_bits <= bits) { + break; + } + //--- PULLBYTE() ---// + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = "invalid distance code"; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = here_op & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += + hold & + ((1 << state.extra) - + 1) /*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = + "invalid distance too far back"; + state.mode = BAD; + break; + } + //#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { + break inf_leave; + } + copy = _out - left; + if (state.offset > copy) { + /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = + "invalid distance too far back"; + state.mode = BAD; + break; + } + // (!) This block is disabled in zlib defaults, + // don't enable it for binary compatibility + //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + // Trace((stderr, "inflate.c too far\n")); + // copy -= state.whave; + // if (copy > state.length) { copy = state.length; } + // if (copy > left) { copy = left; } + // left -= copy; + // state.length -= copy; + // do { + // output[put++] = 0; + // } while (--copy); + // if (state.length === 0) { state.mode = LEN; } + // break; + //#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } else { + from = state.wnext - copy; + } + if (copy > state.length) { + copy = state.length; + } + from_source = state.window; + } else { + /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { + copy = left; + } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { + state.mode = LEN; + } + break; + case LIT: + if (left === 0) { + break inf_leave; + } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + // Use '|' instead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + state.flags + ? crc32( + state.check, + output, + _out, + put - _out + ) + : adler32( + state.check, + output, + _out, + put - _out + ); + } + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ( + (state.flags + ? hold + : zswap32(hold)) !== state.check + ) { + strm.msg = "incorrect data check"; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ( + hold !== + (state.total & 0xffffffff) + ) { + strm.msg = "incorrect length check"; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if ( + state.wsize || + (_out !== strm.avail_out && + state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH)) + ) { + if ( + updatewindow( + strm, + strm.output, + strm.next_out, + _out - strm.avail_out + ) + ) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = + /*UPDATE(state.check, strm.next_out - _out, _out);*/ + state.flags + ? crc32( + state.check, + output, + _out, + strm.next_out - _out + ) + : adler32( + state.check, + output, + _out, + strm.next_out - _out + ); + } + strm.data_type = + state.bits + + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ + ? 256 + : 0); + if ( + ((_in === 0 && _out === 0) || flush === Z_FINISH) && + ret === Z_OK + ) { + ret = Z_BUF_ERROR; + } + return ret; + } + + function inflateEnd(strm) { + if ( + !strm || + !strm.state /*|| strm->zfree == (free_func)0*/ + ) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; + } + + function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + if ((state.wrap & 2) === 0) { + return Z_STREAM_ERROR; + } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; + } + + function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var state; + var dictid; + var ret; + + /* check state */ + if ( + !strm /* == Z_NULL */ || + !strm.state /* == Z_NULL */ + ) { + return Z_STREAM_ERROR; + } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow( + strm, + dictionary, + dictLength, + dictLength + ); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; + } + + exports.inflateReset = inflateReset; + exports.inflateReset2 = inflateReset2; + exports.inflateResetKeep = inflateResetKeep; + exports.inflateInit = inflateInit; + exports.inflateInit2 = inflateInit2; + exports.inflate = inflate; + exports.inflateEnd = inflateEnd; + exports.inflateGetHeader = inflateGetHeader; + exports.inflateSetDictionary = inflateSetDictionary; + exports.inflateInfo = "pako inflate (from Nodeca project)"; + + /* Not implemented + exports.inflateCopy = inflateCopy; + exports.inflateGetDictionary = inflateGetDictionary; + exports.inflateMark = inflateMark; + exports.inflatePrime = inflatePrime; + exports.inflateSync = inflateSync; + exports.inflateSyncPoint = inflateSyncPoint; + exports.inflateUndermine = inflateUndermine; + */ + }, + { + "../utils/common": 28, + "./adler32": 30, + "./crc32": 32, + "./inffast": 35, + "./inftrees": 37, + }, + ], + 37: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + var utils = require("../utils/common"); + + var MAXBITS = 15; + var ENOUGH_LENS = 852; + var ENOUGH_DISTS = 592; + //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + + var CODES = 0; + var LENS = 1; + var DISTS = 2; + + var lbase = [ + /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, + 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, + 83, 99, 115, 131, 163, 195, 227, 258, 0, 0, + ]; + + var lext = [ + /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, + 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, + 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78, + ]; + + var dbase = [ + /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, + 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, + 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, + 24577, 0, 0, + ]; + + var dext = [ + /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, + 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, + 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64, + ]; + + module.exports = function inflate_table( + type, + lens, + lens_index, + codes, + table, + table_index, + work, + opts + ) { + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, + max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; + // var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { + break; + } + } + if (root > max) { + root = max; + } + if (max === 0) { + /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { + break; + } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + } else { + /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ( + (type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS) + ) { + return 1; + } + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = + (here_bits << 24) | + (here_op << 16) | + here_val | + 0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { + break; + } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { + break; + } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ( + (type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS) + ) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = + (root << 24) | + (curr << 16) | + (next - table_index) | + 0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = + ((len - drop) << 24) | (64 << 16) | 0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; + }; + }, + { "../utils/common": 28 }, + ], + 38: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + module.exports = { + 2: "need dictionary" /* Z_NEED_DICT 2 */, + 1: "stream end" /* Z_STREAM_END 1 */, + 0: "" /* Z_OK 0 */, + "-1": "file error" /* Z_ERRNO (-1) */, + "-2": "stream error" /* Z_STREAM_ERROR (-2) */, + "-3": "data error" /* Z_DATA_ERROR (-3) */, + "-4": "insufficient memory" /* Z_MEM_ERROR (-4) */, + "-5": "buffer error" /* Z_BUF_ERROR (-5) */, + "-6": "incompatible version" /* Z_VERSION_ERROR (-6) */, + }; + }, + {}, + ], + 39: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + /* eslint-disable space-unary-ops */ + + var utils = require("../utils/common"); + + /* Public constants ==========================================================*/ + /* ===========================================================================*/ + + //var Z_FILTERED = 1; + //var Z_HUFFMAN_ONLY = 2; + //var Z_RLE = 3; + var Z_FIXED = 4; + //var Z_DEFAULT_STRATEGY = 0; + + /* Possible values of the data_type field (though see inflate()) */ + var Z_BINARY = 0; + var Z_TEXT = 1; + //var Z_ASCII = 1; // = Z_TEXT + var Z_UNKNOWN = 2; + + /*============================================================================*/ + + function zero(buf) { + var len = buf.length; + while (--len >= 0) { + buf[len] = 0; + } + } + + // From zutil.h + + var STORED_BLOCK = 0; + var STATIC_TREES = 1; + var DYN_TREES = 2; + /* The three kinds of block type */ + + var MIN_MATCH = 3; + var MAX_MATCH = 258; + /* The minimum and maximum match lengths */ + + // From deflate.h + /* =========================================================================== + * Internal compression state. + */ + + var LENGTH_CODES = 29; + /* number of length codes, not counting the special END_BLOCK code */ + + var LITERALS = 256; + /* number of literal bytes 0..255 */ + + var L_CODES = LITERALS + 1 + LENGTH_CODES; + /* number of Literal or Length codes, including the END_BLOCK code */ + + var D_CODES = 30; + /* number of distance codes */ + + var BL_CODES = 19; + /* number of codes used to transfer the bit lengths */ + + var HEAP_SIZE = 2 * L_CODES + 1; + /* maximum heap size */ + + var MAX_BITS = 15; + /* All codes must not exceed MAX_BITS bits */ + + var Buf_size = 16; + /* size of bit buffer in bi_buf */ + + /* =========================================================================== + * Constants + */ + + var MAX_BL_BITS = 7; + /* Bit length codes must not exceed MAX_BL_BITS bits */ + + var END_BLOCK = 256; + /* end of block literal code */ + + var REP_3_6 = 16; + /* repeat previous bit length 3-6 times (2 bits of repeat count) */ + + var REPZ_3_10 = 17; + /* repeat a zero length 3-10 times (3 bits of repeat count) */ + + var REPZ_11_138 = 18; + /* repeat a zero length 11-138 times (7 bits of repeat count) */ + + /* eslint-disable comma-spacing,array-bracket-spacing */ + var extra_lbits = + /* extra bits for each length code */ + [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, + 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, + ]; + + var extra_dbits = + /* extra bits for each distance code */ + [ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, + ]; + + var extra_blbits = + /* extra bits for each bit length code */ + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 3, 7, + ]; + + var bl_order = [ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, + 14, 1, 15, + ]; + /* eslint-enable comma-spacing,array-bracket-spacing */ + + /* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + + /* =========================================================================== + * Local data. These are initialized only once. + */ + + // We pre-fill arrays with 0 to avoid uninitialized gaps + + var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + + // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 + var static_ltree = new Array((L_CODES + 2) * 2); + zero(static_ltree); + /* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + + var static_dtree = new Array(D_CODES * 2); + zero(static_dtree); + /* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + + var _dist_code = new Array(DIST_CODE_LEN); + zero(_dist_code); + /* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + + var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); + zero(_length_code); + /* length code for each normalized match length (0 == MIN_MATCH) */ + + var base_length = new Array(LENGTH_CODES); + zero(base_length); + /* First normalized length for each code (0 = MIN_MATCH) */ + + var base_dist = new Array(D_CODES); + zero(base_dist); + /* First normalized distance for each code (0 = distance of 1) */ + + function StaticTreeDesc( + static_tree, + extra_bits, + extra_base, + elems, + max_length + ) { + this.static_tree = + static_tree; /* static tree or NULL */ + this.extra_bits = + extra_bits; /* extra bits for each code or NULL */ + this.extra_base = + extra_base; /* base index for extra_bits */ + this.elems = + elems; /* max number of elements in the tree */ + this.max_length = + max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; + } + + var static_l_desc; + var static_d_desc; + var static_bl_desc; + + function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = + stat_desc; /* the corresponding static tree */ + } + + function d_code(dist) { + return dist < 256 + ? _dist_code[dist] + : _dist_code[256 + (dist >>> 7)]; + } + + /* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ + function put_short(s, w) { + // put_byte(s, (uch)((w) & 0xff)); + // put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = w & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; + } + + /* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ + function send_bits(s, value, length) { + if (s.bi_valid > Buf_size - length) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } + } + + function send_code(s, c, tree) { + send_bits( + s, + tree[c * 2] /*.Code*/, + tree[c * 2 + 1] /*.Len*/ + ); + } + + /* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ + function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; + } + + /* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ + function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } + } + + /* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ + function gen_bitlen(s, desc) { + // deflate_state *s; + // tree_desc *desc; /* the tree descriptor */ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[ + s.heap[s.heap_max] * 2 + 1 + ] /*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = + tree[ + tree[n * 2 + 1] /*.Dad*/ * 2 + 1 + ] /*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n * 2 + 1] /*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { + continue; + } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2] /*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += + f * (stree[n * 2 + 1] /*.Len*/ + xbits); + } + } + if (overflow === 0) { + return; + } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { + bits--; + } + s.bl_count[ + bits + ]--; /* move one leaf down the tree */ + s.bl_count[ + bits + 1 + ] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { + continue; + } + if (tree[m * 2 + 1] /*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += + (bits - tree[m * 2 + 1]) /*.Len*/ * + tree[m * 2] /*.Freq*/; + tree[m * 2 + 1] /*.Len*/ = bits; + } + n--; + } + } + } + + /* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ + function gen_codes(tree, max_code, bl_count) { + // ct_data *tree; /* the tree to decorate */ + // int max_code; /* largest code with non zero frequency */ + // ushf *bl_count; /* number of codes at each bit length */ + var next_code = new Array( + MAX_BITS + 1 + ); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = + (code + bl_count[bits - 1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES - 1; code++) { + base_length[code] = length; + for (n = 0; n < 1 << extra_lbits[code]; n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < 1 << extra_dbits[code]; n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < 1 << (extra_dbits[code] - 7); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1] /*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1] /*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1] /*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1] /*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES + 1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n * 2 + 1] /*.Len*/ = 5; + static_dtree[n * 2] /*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc( + static_ltree, + extra_lbits, + LITERALS + 1, + L_CODES, + MAX_BITS + ); + static_d_desc = new StaticTreeDesc( + static_dtree, + extra_dbits, + 0, + D_CODES, + MAX_BITS + ); + static_bl_desc = new StaticTreeDesc( + new Array(0), + extra_blbits, + 0, + BL_CODES, + MAX_BL_BITS + ); + + //static_init_done = true; + } + + /* =========================================================================== + * Initialize a new block. + */ + function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { + s.dyn_ltree[n * 2] /*.Freq*/ = 0; + } + for (n = 0; n < D_CODES; n++) { + s.dyn_dtree[n * 2] /*.Freq*/ = 0; + } + for (n = 0; n < BL_CODES; n++) { + s.bl_tree[n * 2] /*.Freq*/ = 0; + } + + s.dyn_ltree[END_BLOCK * 2] /*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; + } + + /* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ + function bi_windup(s) { + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; + } + + /* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ + function copy_block(s, buf, len, header) { + //DeflateState *s; + //charf *buf; /* the input data */ + //unsigned len; /* its length */ + //int header; /* true if block header must be written */ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } + // while (len--) { + // put_byte(s, *buf++); + // } + utils.arraySet( + s.pending_buf, + s.window, + buf, + len, + s.pending + ); + s.pending += len; + } + + /* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ + function smaller(tree, n, m, depth) { + var _n2 = n * 2; + var _m2 = m * 2; + return ( + tree[_n2] /*.Freq*/ < tree[_m2] /*.Freq*/ || + (tree[_n2] /*.Freq*/ === tree[_m2] /*.Freq*/ && + depth[n] <= depth[m]) + ); + } + + /* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ + function pqdownheap(s, tree, k) { + // deflate_state *s; + // ct_data *tree; /* the tree to restore */ + // int k; /* node to move down */ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if ( + j < s.heap_len && + smaller(tree, s.heap[j + 1], s.heap[j], s.depth) + ) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { + break; + } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; + } + + // inlined manually + // var SMALLEST = 1; + + /* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ + function compress_block(s, ltree, dtree) { + // deflate_state *s; + // const ct_data *ltree; /* literal tree */ + // const ct_data *dtree; /* distance tree */ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = + (s.pending_buf[s.d_buf + lx * 2] << 8) | + s.pending_buf[s.d_buf + lx * 2 + 1]; + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code( + s, + lc, + ltree + ); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code( + s, + code + LITERALS + 1, + ltree + ); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits( + s, + lc, + extra + ); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code( + s, + code, + dtree + ); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits( + s, + dist, + extra + ); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); + } + + /* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ + function build_tree(s, desc) { + // deflate_state *s; + // tree_desc *desc; /* the tree descriptor */ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = + -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2] /*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + } else { + tree[n * 2 + 1] /*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = + max_code < 2 ? ++max_code : 0; + tree[node * 2] /*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node * 2 + 1] /*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s.heap_len >> 1 /*int /2*/; n >= 1; n--) { + pqdownheap(s, tree, n); + } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1 /*SMALLEST*/]; + s.heap[1 /*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1 /*SMALLEST*/); + /***/ + + m = + s + .heap[1 /*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = + n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2] /*.Freq*/ = + tree[n * 2] /*.Freq*/ + tree[m * 2] /*.Freq*/; + s.depth[node] = + (s.depth[n] >= s.depth[m] + ? s.depth[n] + : s.depth[m]) + 1; + tree[n * 2 + 1] /*.Dad*/ = tree[ + m * 2 + 1 + ] /*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1 /*SMALLEST*/] = node++; + pqdownheap(s, tree, 1 /*SMALLEST*/); + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1 /*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); + } + + /* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ + function scan_tree(s, tree, max_code) { + // deflate_state *s; + // ct_data *tree; /* the tree to be scanned */ + // int max_code; /* and its largest code of non zero frequency */ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = + tree[0 * 2 + 1]; /*.Len*/ /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[ + (max_code + 1) * 2 + 1 + ] /*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1] /*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + } else if (count < min_count) { + s.bl_tree[curlen * 2] /*.Freq*/ += count; + } else if (curlen !== 0) { + if (curlen !== prevlen) { + s.bl_tree[curlen * 2] /*.Freq*/++; + } + s.bl_tree[REP_3_6 * 2] /*.Freq*/++; + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2] /*.Freq*/++; + } else { + s.bl_tree[REPZ_11_138 * 2] /*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ + function send_tree(s, tree, max_code) { + // deflate_state *s; + // ct_data *tree; /* the tree to be scanned */ + // int max_code; /* and its largest code of non zero frequency */ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = + tree[0 * 2 + 1]; /*.Len*/ /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1] /*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + } else if (count < min_count) { + do { + send_code(s, curlen, s.bl_tree); + } while (--count !== 0); + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ + function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for ( + max_blindex = BL_CODES - 1; + max_blindex >= 3; + max_blindex-- + ) { + if ( + s.bl_tree[ + bl_order[max_blindex] * 2 + 1 + ] /*.Len*/ !== 0 + ) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; + } + + /* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ + function send_all_trees(s, lcodes, dcodes, blcodes) { + // deflate_state *s; + // int lcodes, dcodes, blcodes; /* number of codes for each tree */ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits( + s, + lcodes - 257, + 5 + ); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits( + s, + blcodes - 4, + 4 + ); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits( + s, + s.bl_tree[bl_order[rank] * 2 + 1] /*.Len*/, + 3 + ); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree( + s, + s.dyn_ltree, + lcodes - 1 + ); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree( + s, + s.dyn_dtree, + dcodes - 1 + ); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); + } + + /* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ + function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ( + black_mask & 1 && + s.dyn_ltree[n * 2] /*.Freq*/ !== 0 + ) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if ( + s.dyn_ltree[9 * 2] /*.Freq*/ !== 0 || + s.dyn_ltree[10 * 2] /*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2] /*.Freq*/ !== 0 + ) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2] /*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; + } + + var static_init_done = false; + + /* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ + function _tr_init(s) { + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); + } + + /* =========================================================================== + * Send a stored block + */ + function _tr_stored_block(s, buf, stored_len, last) { + //DeflateState *s; + //charf *buf; /* input block */ + //ulg stored_len; /* length of input block */ + //int last; /* one if this is the last block for a file */ + send_bits( + s, + (STORED_BLOCK << 1) + (last ? 1 : 0), + 3 + ); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ + } + + /* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ + function _tr_align(s) { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); + } + + /* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ + function _tr_flush_block(s, buf, stored_len, last) { + //DeflateState *s; + //charf *buf; /* input block, or NULL if too old */ + //ulg stored_len; /* length of input block */ + //int last; /* one if this is the last block for a file */ + var opt_lenb, + static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len + 3 + 7) >>> 3; + static_lenb = (s.static_len + 3 + 7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { + opt_lenb = static_lenb; + } + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = + stored_len + 5; /* force a stored block */ + } + + if (stored_len + 4 <= opt_lenb && buf !== -1) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + } else if ( + s.strategy === Z_FIXED || + static_lenb === opt_lenb + ) { + send_bits( + s, + (STATIC_TREES << 1) + (last ? 1 : 0), + 3 + ); + compress_block(s, static_ltree, static_dtree); + } else { + send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); + send_all_trees( + s, + s.l_desc.max_code + 1, + s.d_desc.max_code + 1, + max_blindex + 1 + ); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); + } + + /* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + function _tr_tally(s, dist, lc) { + // deflate_state *s; + // unsigned dist; /* distance of matched string */ + // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = + (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = + dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc * 2] /*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[ + (_length_code[lc] + LITERALS + 1) * 2 + ] /*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2] /*.Freq*/++; + } + + // (!) This block is disabled in zlib defaults, + // don't enable it for binary compatibility + + //#ifdef TRUNCATE_BLOCK + // /* Try to guess if it is profitable to stop the current block here */ + // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { + // /* Compute an upper bound for the compressed length */ + // out_length = s.last_lit*8; + // in_length = s.strstart - s.block_start; + // + // for (dcode = 0; dcode < D_CODES; dcode++) { + // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); + // } + // out_length >>>= 3; + // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + // // s->last_lit, in_length, out_length, + // // 100L - out_length*100L/in_length)); + // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { + // return true; + // } + // } + //#endif + + return s.last_lit === s.lit_bufsize - 1; + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + } + + exports._tr_init = _tr_init; + exports._tr_stored_block = _tr_stored_block; + exports._tr_flush_block = _tr_flush_block; + exports._tr_tally = _tr_tally; + exports._tr_align = _tr_align; + }, + { "../utils/common": 28 }, + ], + 40: [ + function (require, module, exports) { + "use strict"; + + // (C) 1995-2013 Jean-loup Gailly and Mark Adler + // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + + function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = "" /*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2 /*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; + } + + module.exports = ZStream; + }, + {}, + ], + }, + {}, + [10] + )(10); +}); diff --git a/game/keyWords.js b/game/keyWords.js index a1b8fe1c1..4b287bca7 100644 --- a/game/keyWords.js +++ b/game/keyWords.js @@ -1,3 +1,3 @@ window.bannedKeyWords=JSON.parse( decodeURIComponent( - atob("JTVCJTIyZ2hzJTIyJTJDJTIyJUU3JTlCJUI0JUU4JTgyJUEwJTIyJTJDJTIyJUU2JTgwJUE3JUU0JUJBJUE0JTIyJTJDJTIyJUU1JTgxJTlBJUU3JTg4JUIxJTIyJTJDJTIyaHR0cCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVBNSVCNiUyMiUyQyUyMiVFOSVBQSU5QSVFOSU4MCVCQyUyMiUyQyUyMiVFNSU5MyU4OCVFNSVCNyVCNCVFNyU4QiU5NyUyMiUyQyUyMiVFNyVCRSU4RSVFNyU5QyU4OSUyMiUyQyUyMiVFNyU5OSU4QyUyMiUyQyUyMiVFNSVCMSU4MSVFNyU5QyVCQyUyMiUyQyUyMiVFOCU4OSVCOSUyMiUyQyUyMiVFNSU4MiVCQiVFOSU4MCVCQyUyMiUyQyUyMiVFNiU5MyU4RCVFNCVCRCVBMCUyMiUyQyUyMiVFNSU4MSU5QSVFOSVCOCVBMSUyMiUyQyUyMiVFNSVBNSVCOCUyMiUyQyUyMiVFNSVBNyVBNiUyMiUyQyUyMiVFNSU4RCU4RSVFNCVCOCVCQSUyMiUyQyUyMiVFNSVCMSU4NCUyMiUyQyUyMiVFNyU4QiU5NyVFNSVBRCU5MCUyMiUyQyUyMiVFNSVCMSU4RSUyMiUyQyUyMiVFNSU5MCU4QyVFNiU4MCVBNyVFNiU4MSU4QiUyMiUyQyUyMiVFOCU4MiU5NiVFNiU4OCU5OCUyMiUyQyUyMiVFOSVCOCVBMSVFNSVCNyVCNCUyMiUyQyUyMiVFNyVCMiVCRSVFNiVCNiVCMiUyMiUyQyUyMiVFNyVCMiVBQSVFNiVCMCVCNCUyMiUyQyUyMiVFNiU4QyU4MiVFNiU5QyU4OCVFNCVCQSVBRSVFNCVCOCVBRCUyMiUyQyUyMiVFOCVCNCVCMSVFOSVBQSVBOCVFNSVBNCVCNCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVCMSU4MSUyMiUyQyUyMiVFNSU4MiVCQiUyMiUyQyUyMiVFNSVBNSVBNSVFNSU4OCVBOSVFNyVCQiU5OSUyMiUyQyUyMiVFNCVCOCU4MSVFNyU5QyU5RiUyMiUyQyUyMiVFOCU5QiU4NiUyMiUyQyUyMiVFOSVCQyVBMCVFOSVCQyVBMCUyMiUyQyUyMiVFOSVCQyVBMCVFNCVCQSVCQSUyMiUyQyUyMiVFNyVBNSU5RSVFNSU4RiU4QiUyMiUyQyUyMiUzQyUyRmElM0UlMjIlNUQ="))); \ No newline at end of file + atob("JTVCJTIyZ2hzJTIyJTJDJTIyJUU3JTlCJUI0JUU4JTgyJUEwJTIyJTJDJTIyJUU2JTgwJUE3JUU0JUJBJUE0JTIyJTJDJTIyJUU1JTgxJTlBJUU3JTg4JUIxJTIyJTJDJTIyaHR0cCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVBNSVCNiUyMiUyQyUyMiVFOSVBQSU5QSVFOSU4MCVCQyUyMiUyQyUyMiVFNSU5MyU4OCVFNSVCNyVCNCVFNyU4QiU5NyUyMiUyQyUyMiVFNyVCRSU4RSVFNyU5QyU4OSUyMiUyQyUyMiVFNyU5OSU4QyUyMiUyQyUyMiVFNSVCMSU4MSVFNyU5QyVCQyUyMiUyQyUyMiVFOCU4OSVCOSUyMiUyQyUyMiVFNSU4MiVCQiVFOSU4MCVCQyUyMiUyQyUyMiVFNiU5MyU4RCVFNCVCRCVBMCUyMiUyQyUyMiVFNSU4MSU5QSVFOSVCOCVBMSUyMiUyQyUyMiVFNSVBNSVCOCUyMiUyQyUyMiVFNSVBNyVBNiUyMiUyQyUyMiVFNSU4RCU4RSVFNCVCOCVCQSUyMiUyQyUyMiVFNSVCMSU4NCUyMiUyQyUyMiVFNyU4QiU5NyVFNSVBRCU5MCUyMiUyQyUyMiVFNSVCMSU4RSUyMiUyQyUyMiVFNSU5MCU4QyVFNiU4MCVBNyVFNiU4MSU4QiUyMiUyQyUyMiVFOCU4MiU5NiVFNiU4OCU5OCUyMiUyQyUyMiVFOSVCOCVBMSVFNSVCNyVCNCUyMiUyQyUyMiVFNyVCMiVCRSVFNiVCNiVCMiUyMiUyQyUyMiVFNyVCMiVBQSVFNiVCMCVCNCUyMiUyQyUyMiVFNiU4QyU4MiVFNiU5QyU4OCVFNCVCQSVBRSVFNCVCOCVBRCUyMiUyQyUyMiVFOCVCNCVCMSVFOSVBQSVBOCVFNSVBNCVCNCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVCMSU4MSUyMiUyQyUyMiVFNSU4MiVCQiUyMiUyQyUyMiVFNSVBNSVBNSVFNSU4OCVBOSVFNyVCQiU5OSUyMiUyQyUyMiVFNCVCOCU4MSVFNyU5QyU5RiUyMiUyQyUyMiVFOCU5QiU4NiUyMiUyQyUyMiVFOSVCQyVBMCVFOSVCQyVBMCUyMiUyQyUyMiVFOSVCQyVBMCVFNCVCQSVCQSUyMiUyQyUyMiVFNyVBNSU5RSVFNSU4RiU4QiUyMiUyQyUyMiUzQyUyRmElM0UlMjIlNUQ="))); diff --git a/game/package.js b/game/package.js index ff755200c..d59c37dac 100644 --- a/game/package.js +++ b/game/package.js @@ -1,144 +1,144 @@ -window.noname_package={ - character:{ - standard:'标准', - refresh:'界限突破', - shenhua:'神话再临', - yijiang:'一将成名', - sp:'璀璨星河', - onlyOL:'OL专属', - yingbian:'文德武备', - clan:'门阀士族', - xinghuoliaoyuan:'星火燎原', - huicui:'群英荟萃', - xianding:'限定专属', - sp2:'系列专属', - extra:'神将', - mobile:'移动版', - shiji:'始计篇', - sb:'谋攻篇', - tw:'外服武将', - collab:'联动卡', - offline:'线下武将', - jsrg:'江山如故', - old:'怀旧', - diy:'DIY', - ddd:'3D精选', - yxs:'英雄杀', - hearth:'炉石传说', - gwent:'昆特牌', - mtg:'万智牌', - ow:'守望先锋', - swd:'轩辕剑', - gujian:'古剑奇谭', - xianjian:'仙剑奇侠传', +window.noname_package = { + character: { + standard: "标准", + refresh: "界限突破", + shenhua: "神话再临", + yijiang: "一将成名", + sp: "璀璨星河", + onlyOL: "OL专属", + yingbian: "文德武备", + clan: "门阀士族", + xinghuoliaoyuan: "星火燎原", + huicui: "群英荟萃", + xianding: "限定专属", + sp2: "系列专属", + extra: "神将", + mobile: "移动版", + shiji: "始计篇", + sb: "谋攻篇", + tw: "外服武将", + collab: "联动卡", + offline: "线下武将", + jsrg: "江山如故", + old: "怀旧", + diy: "DIY", + ddd: "3D精选", + yxs: "英雄杀", + hearth: "炉石传说", + gwent: "昆特牌", + mtg: "万智牌", + ow: "守望先锋", + swd: "轩辕剑", + gujian: "古剑奇谭", + xianjian: "仙剑奇侠传", }, - card:{ - standard:'标准', - extra:'军争', - sp:'忠胆英杰', - guozhan:'国战', - zhulu:'逐鹿天下', - yingbian:'应变篇', - yongjian:'用间篇', - zhenfa:'阵法', - yunchou:'运筹帷幄', - swd:'轩辕剑', - gujian:'古剑奇谭', - hearth:'炉石传说', - gwent:'昆特牌', - mtg:'万智牌', - huanlekapai:'欢乐卡牌', + card: { + standard: "标准", + extra: "军争", + guozhan: "国战", + yingbian: "应变篇", + yongjian: "用间篇", + sp: "忠胆英杰", + zhulu: "逐鹿天下", + yunchou: "运筹帷幄", + zhenfa: "阵法", + swd: "轩辕剑", + gujian: "古剑奇谭", + hearth: "炉石传说", + gwent: "昆特牌", + mtg: "万智牌", + huanlekapai: "欢乐卡牌", }, - play:{ - boss:'诸神降临', - cardpile:'牌堆补充', - wuxing:'五行生克', - coin:'富甲天下', + play: { + boss: "诸神降临", + cardpile: "牌堆补充", + wuxing: "五行生克", + coin: "富甲天下", }, - mode:{ - identity:'身份', - guozhan:'国战', - versus:'对决', - connect:'联机', - boss:'挑战', - doudizhu:'斗地主', - single:'单挑', - chess:'战棋', - tafang:'塔防', - stone:'炉石', - brawl:'乱斗', + mode: { + identity: "身份", + guozhan: "国战", + versus: "对决", + connect: "联机", + boss: "挑战", + doudizhu: "斗地主", + single: "单挑", + chess: "战棋", + tafang: "塔防", + stone: "炉石", + brawl: "乱斗", }, - submode:{ - identity:{ - normal:'身份模式', - zhong:'忠胆英杰', - purple:'3v3v2', + submode: { + identity: { + normal: "身份模式", + zhong: "忠胆英杰", + purple: "3v3v2", }, - guozhan:{ - normal:'国战模式', - mingjiang:'明将国战' + guozhan: { + normal: "国战模式", + mingjiang: "明将国战", }, - versus:{ - four:'四人对抗', - three:'统率三军', - two:'欢乐成双', - jiange:'守卫剑阁', - siguo:'四国争霸', - standard:'自由对决' + versus: { + four: "四人对抗", + three: "统率三军", + two: "欢乐成双", + jiange: "守卫剑阁", + siguo: "四国争霸", + standard: "自由对决", }, - chess:{ - combat:'战棋模式', - three:'战棋统率', - leader:'战棋君主' + chess: { + combat: "战棋模式", + three: "战棋统率", + leader: "战棋君主", }, - single:{ - normal:'新1v1', + single: { + normal: "新1v1", }, }, - background:{ - ol_bg:'龙纹', - planetarian_bg:'星梦', - heaven_bg:'红烧', - kyoani_bg:'京都', - key_bg:'键社', - xiaowu_bg:'小无', - noname_bg:'璀璨', - wuming_bg:'无名', - zhulin_bg:'竹林', - shengshi_bg:'盛世', - taoyuan_bg:'桃园', - zhanhuo_bg:'战火', - huangtian_bg:'黄天', - september_bg:'九月', - yinxiang_bg:'印象', - zhanyun_bg:'战云', - beipan_bg:'背叛', - lanting_bg:'兰亭', - lingju_bg:'灵雎', - sanying_bg:'三英', - wangshi_bg:'往事', - xiongxin_bg:'雄心', - xinsha_bg:'新杀', + background: { + ol_bg: "龙纹", + planetarian_bg: "星梦", + heaven_bg: "红烧", + kyoani_bg: "京都", + key_bg: "键社", + xiaowu_bg: "小无", + noname_bg: "璀璨", + wuming_bg: "无名", + zhulin_bg: "竹林", + shengshi_bg: "盛世", + taoyuan_bg: "桃园", + zhanhuo_bg: "战火", + huangtian_bg: "黄天", + september_bg: "九月", + yinxiang_bg: "印象", + zhanyun_bg: "战云", + beipan_bg: "背叛", + lanting_bg: "兰亭", + lingju_bg: "灵雎", + sanying_bg: "三英", + wangshi_bg: "往事", + xiongxin_bg: "雄心", + xinsha_bg: "新杀", }, - music:{ - music_phliosophy:'Philosophy of ours', - music_diaochan:'貂蝉', - music_shezhan:'舌战群儒', - music_danji:'千里走单骑', - music_jifeng:'祭风', - music_jilve:'极略', + music: { + music_phliosophy: "Philosophy of ours", + music_diaochan: "貂蝉", + music_shezhan: "舌战群儒", + music_danji: "千里走单骑", + music_jifeng: "祭风", + music_jilve: "极略", }, - font:{ - xiaozhuan:'方正小篆体', - xinwei:'华文新魏_GBK', - huangcao:'方正黄草_GBK', - yuanli:'方正北魏楷书_GBK', - xingkai:'方正行楷_GBK', - shousha:'方正隶变_GBK', + font: { + xiaozhuan: "方正小篆体", + xinwei: "华文新魏_GBK", + huangcao: "方正黄草_GBK", + yuanli: "方正北魏楷书_GBK", + xingkai: "方正行楷_GBK", + shousha: "方正隶变_GBK", + }, + theme: { + woodden: "木纹", + music: "音乐", + simple: "简约", }, - theme:{ - woodden:'木纹', - music:'音乐', - simple:'简约' - } }; diff --git a/game/phantom.js b/game/phantom.js index 8d72bafdd..17e8a5cc5 100644 --- a/game/phantom.js +++ b/game/phantom.js @@ -1,29 +1,29 @@ -var fs = require('fs'); -var webpage = require('webpage') -var load = function(id){ - var page = webpage.create(); - page.settings.userAgent = 'NonameServer'; - page.open('file://'+fs.workingDirectory+'/index.html?server='+id, function(status) { - if(status !== 'success') { - console.log(fs.workingDirectory); - console.log('Unable to access network'); - } - setInterval(function(){ - if(page.evaluate(function(){ - if(!lib.node||!lib.node.clients||!lib.node.clients.length){ - return true; - } - else{ - return false; - } - })){ - page.close(); - load(id); - } - },600000); - }); -} - -load(1); -load(2); -load(3); +var fs = require('fs'); +var webpage = require('webpage') +var load = function(id){ + var page = webpage.create(); + page.settings.userAgent = 'NonameServer'; + page.open('file://'+fs.workingDirectory+'/index.html?server='+id, function(status) { + if(status !== 'success') { + console.log(fs.workingDirectory); + console.log('Unable to access network'); + } + setInterval(function(){ + if(page.evaluate(function(){ + if(!lib.node||!lib.node.clients||!lib.node.clients.length){ + return true; + } + else{ + return false; + } + })){ + page.close(); + load(id); + } + },600000); + }); +} + +load(1); +load(2); +load(3); diff --git a/game/pinyinjs.js b/game/pinyinjs.js index 20aa02846..9f338c748 100644 --- a/game/pinyinjs.js +++ b/game/pinyinjs.js @@ -41646,4 +41646,4 @@ var pinyin_dict_withtone = "yī,dīng zhēng,kǎo qiǎo yú,qī,shàng,xià,hǎn pinyinUtilx.dict = dict; window.pinyinUtilx = pinyinUtilx; -}); \ No newline at end of file +}); diff --git a/game/pressure.js b/game/pressure.js index 9e66e7e70..dbf205895 100644 --- a/game/pressure.js +++ b/game/pressure.js @@ -1,576 +1,576 @@ -// Pressure v2.1.1 | Created By Stuart Yamartino | MIT License | 2015 - 2017 -;(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define([], factory); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.Pressure = factory(); - } -}(this, function() { -'use strict'; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -//--------------------- Public API Section ---------------------// -// this is the Pressure Object, this is the only object that is accessible to the end user -// only the methods in this object can be called, making it the "public api" - -var Pressure = { - - // targets any device with Force or 3D Touch - set: function set(selector, closure, options) { - loopPressureElements(selector, closure, options); - }, - - - // set configuration options for global config - config: function config(options) { - Config.set(options); - }, - - - // the map method allows for interpolating a value from one range of values to another - // example from the Arduino documentation: https://www.arduino.cc/en/Reference/Map - map: function map(x, in_min, in_max, out_min, out_max) { - return _map.apply(null, arguments); - } -}; - -var Element = function () { - function Element(el, block, options) { - _classCallCheck(this, Element); - - this.routeEvents(el, block, options); - this.preventSelect(el, options); - } - - _createClass(Element, [{ - key: 'routeEvents', - value: function routeEvents(el, block, options) { - var type = Config.get('only', options); - // for devices that support pointer events - if (supportsPointer && (type === 'pointer' || type === null)) { - this.adapter = new AdapterPointer(el, block, options).bindEvents(); - } - // for devices that support 3D Touch - else if (supportsTouch && (type === 'touch' || type === null)) { - this.adapter = new Adapter3DTouch(el, block, options).bindEvents(); - } - // for devices that support Force Touch - else if (supportsMouse && (type === 'mouse' || type === null)) { - this.adapter = new AdapterForceTouch(el, block, options).bindEvents(); - } - // unsupported if it is requesting a type and your browser is of other type - else { - this.adapter = new Adapter(el, block).bindUnsupportedEvent(); - } - } - - // prevent the default action of text selection, "peak & pop", and force touch special feature - - }, { - key: 'preventSelect', - value: function preventSelect(el, options) { - if (Config.get('preventSelect', options)) { - el.style.webkitTouchCallout = "none"; - el.style.webkitUserSelect = "none"; - el.style.khtmlUserSelect = "none"; - el.style.MozUserSelect = "none"; - el.style.msUserSelect = "none"; - el.style.userSelect = "none"; - } - } - }]); - - return Element; -}(); - -/* -This is the base adapter from which all the other adapters extend. -*/ - -var Adapter = function () { - function Adapter(el, block, options) { - _classCallCheck(this, Adapter); - - this.el = el; - this.block = block; - this.options = options; - this.pressed = false; - this.deepPressed = false; - this.nativeSupport = false; - this.runningPolyfill = false; - this.runKey = Math.random(); - } - - _createClass(Adapter, [{ - key: 'setPressed', - value: function setPressed(boolean) { - this.pressed = boolean; - } - }, { - key: 'setDeepPressed', - value: function setDeepPressed(boolean) { - this.deepPressed = boolean; - } - }, { - key: 'isPressed', - value: function isPressed() { - return this.pressed; - } - }, { - key: 'isDeepPressed', - value: function isDeepPressed() { - return this.deepPressed; - } - }, { - key: 'add', - value: function add(event, set) { - this.el.addEventListener(event, set, false); - } - }, { - key: 'runClosure', - value: function runClosure(method) { - if (method in this.block) { - // call the closure method and apply nth arguments if they exist - this.block[method].apply(this.el, Array.prototype.slice.call(arguments, 1)); - } - } - }, { - key: 'fail', - value: function fail(event, runKey) { - if (Config.get('polyfill', this.options)) { - if (this.runKey === runKey) { - this.runPolyfill(event); - } - } else { - this.runClosure('unsupported', event); - } - } - }, { - key: 'bindUnsupportedEvent', - value: function bindUnsupportedEvent() { - var _this = this; - - this.add(supportsTouch ? 'touchstart' : 'mousedown', function (event) { - return _this.runClosure('unsupported', event); - }); - } - }, { - key: '_startPress', - value: function _startPress(event) { - if (this.isPressed() === false) { - this.runningPolyfill = false; - this.setPressed(true); - this.runClosure('start', event); - } - } - }, { - key: '_startDeepPress', - value: function _startDeepPress(event) { - if (this.isPressed() && this.isDeepPressed() === false) { - this.setDeepPressed(true); - this.runClosure('startDeepPress', event); - } - } - }, { - key: '_changePress', - value: function _changePress(force, event) { - this.nativeSupport = true; - this.runClosure('change', force, event); - } - }, { - key: '_endDeepPress', - value: function _endDeepPress() { - if (this.isPressed() && this.isDeepPressed()) { - this.setDeepPressed(false); - this.runClosure('endDeepPress'); - } - } - }, { - key: '_endPress', - value: function _endPress() { - if (this.runningPolyfill === false) { - if (this.isPressed()) { - this._endDeepPress(); - this.setPressed(false); - this.runClosure('end'); - } - this.runKey = Math.random(); - this.nativeSupport = false; - } else { - this.setPressed(false); - } - } - }, { - key: 'deepPress', - value: function deepPress(force, event) { - force >= 0.5 ? this._startDeepPress(event) : this._endDeepPress(); - } - }, { - key: 'runPolyfill', - value: function runPolyfill(event) { - this.increment = Config.get('polyfillSpeedUp', this.options) === 0 ? 1 : 10 / Config.get('polyfillSpeedUp', this.options); - this.decrement = Config.get('polyfillSpeedDown', this.options) === 0 ? 1 : 10 / Config.get('polyfillSpeedDown', this.options); - this.setPressed(true); - this.runClosure('start', event); - if (this.runningPolyfill === false) { - this.loopPolyfillForce(0, event); - } - } - }, { - key: 'loopPolyfillForce', - value: function loopPolyfillForce(force, event) { - if (this.nativeSupport === false) { - if (this.isPressed()) { - this.runningPolyfill = true; - force = force + this.increment > 1 ? 1 : force + this.increment; - this.runClosure('change', force, event); - this.deepPress(force, event); - setTimeout(this.loopPolyfillForce.bind(this, force, event), 10); - } else { - force = force - this.decrement < 0 ? 0 : force - this.decrement; - if (force < 0.5 && this.isDeepPressed()) { - this.setDeepPressed(false); - this.runClosure('endDeepPress'); - } - if (force === 0) { - this.runningPolyfill = false; - this.setPressed(true); - this._endPress(); - } else { - this.runClosure('change', force, event); - this.deepPress(force, event); - setTimeout(this.loopPolyfillForce.bind(this, force, event), 10); - } - } - } - } - }]); - - return Adapter; -}(); - -/* -This adapter is for Macs with Force Touch trackpads. -*/ - -var AdapterForceTouch = function (_Adapter) { - _inherits(AdapterForceTouch, _Adapter); - - function AdapterForceTouch(el, block, options) { - _classCallCheck(this, AdapterForceTouch); - - return _possibleConstructorReturn(this, (AdapterForceTouch.__proto__ || Object.getPrototypeOf(AdapterForceTouch)).call(this, el, block, options)); - } - - _createClass(AdapterForceTouch, [{ - key: 'bindEvents', - value: function bindEvents() { - this.add('webkitmouseforcewillbegin', this._startPress.bind(this)); - this.add('mousedown', this.support.bind(this)); - this.add('webkitmouseforcechanged', this.change.bind(this)); - this.add('webkitmouseforcedown', this._startDeepPress.bind(this)); - this.add('webkitmouseforceup', this._endDeepPress.bind(this)); - this.add('mouseleave', this._endPress.bind(this)); - this.add('mouseup', this._endPress.bind(this)); - } - }, { - key: 'support', - value: function support(event) { - if (this.isPressed() === false) { - this.fail(event, this.runKey); - } - } - }, { - key: 'change', - value: function change(event) { - if (this.isPressed() && event.webkitForce > 0) { - this._changePress(this.normalizeForce(event.webkitForce), event); - } - } - - // make the force the standard 0 to 1 scale and not the 1 to 3 scale - - }, { - key: 'normalizeForce', - value: function normalizeForce(force) { - return this.reachOne(_map(force, 1, 3, 0, 1)); - } - - // if the force value is above 0.995 set the force to 1 - - }, { - key: 'reachOne', - value: function reachOne(force) { - return force > 0.995 ? 1 : force; - } - }]); - - return AdapterForceTouch; -}(Adapter); - -/* -This adapter is more mobile devices that support 3D Touch. -*/ - -var Adapter3DTouch = function (_Adapter2) { - _inherits(Adapter3DTouch, _Adapter2); - - function Adapter3DTouch(el, block, options) { - _classCallCheck(this, Adapter3DTouch); - - return _possibleConstructorReturn(this, (Adapter3DTouch.__proto__ || Object.getPrototypeOf(Adapter3DTouch)).call(this, el, block, options)); - } - - _createClass(Adapter3DTouch, [{ - key: 'bindEvents', - value: function bindEvents() { - if (supportsTouchForceChange) { - this.add('touchforcechange', this.start.bind(this)); - this.add('touchstart', this.support.bind(this, 0)); - this.add('touchend', this._endPress.bind(this)); - } else { - this.add('touchstart', this.startLegacy.bind(this)); - this.add('touchend', this._endPress.bind(this)); - } - } - }, { - key: 'start', - value: function start(event) { - if (event.touches.length > 0) { - this._startPress(event); - this.touch = this.selectTouch(event); - if (this.touch) { - this._changePress(this.touch.force, event); - } - } - } - }, { - key: 'support', - value: function support(iter, event) { - var runKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.runKey; - - if (this.isPressed() === false) { - if (iter <= 6) { - iter++; - setTimeout(this.support.bind(this, iter, event, runKey), 10); - } else { - this.fail(event, runKey); - } - } - } - }, { - key: 'startLegacy', - value: function startLegacy(event) { - this.initialForce = event.touches[0].force; - this.supportLegacy(0, event, this.runKey, this.initialForce); - } - - // this checks up to 6 times on a touch to see if the touch can read a force value - // if the force value has changed it means the device supports pressure - // more info from this issue https://github.com/yamartino/pressure/issues/15 - - }, { - key: 'supportLegacy', - value: function supportLegacy(iter, event, runKey, force) { - if (force !== this.initialForce) { - this._startPress(event); - this.loopForce(event); - } else if (iter <= 6) { - iter++; - setTimeout(this.supportLegacy.bind(this, iter, event, runKey, force), 10); - } else { - this.fail(event, runKey); - } - } - }, { - key: 'loopForce', - value: function loopForce(event) { - if (this.isPressed()) { - this.touch = this.selectTouch(event); - setTimeout(this.loopForce.bind(this, event), 10); - this._changePress(this.touch.force, event); - } - } - - // link up the touch point to the correct element, this is to support multitouch - - }, { - key: 'selectTouch', - value: function selectTouch(event) { - if (event.touches.length === 1) { - return this.returnTouch(event.touches[0], event); - } else { - for (var i = 0; i < event.touches.length; i++) { - // if the target press is on this element - if (event.touches[i].target === this.el || this.el.contains(event.touches[i].target)) { - return this.returnTouch(event.touches[i], event); - } - } - } - } - - // return the touch and run a start or end for deep press - - }, { - key: 'returnTouch', - value: function returnTouch(touch, event) { - this.deepPress(touch.force, event); - return touch; - } - }]); - - return Adapter3DTouch; -}(Adapter); - -/* -This adapter is for devices that support pointer events. -*/ - -var AdapterPointer = function (_Adapter3) { - _inherits(AdapterPointer, _Adapter3); - - function AdapterPointer(el, block, options) { - _classCallCheck(this, AdapterPointer); - - return _possibleConstructorReturn(this, (AdapterPointer.__proto__ || Object.getPrototypeOf(AdapterPointer)).call(this, el, block, options)); - } - - _createClass(AdapterPointer, [{ - key: 'bindEvents', - value: function bindEvents() { - this.add('pointerdown', this.support.bind(this)); - this.add('pointermove', this.change.bind(this)); - this.add('pointerup', this._endPress.bind(this)); - this.add('pointerleave', this._endPress.bind(this)); - } - }, { - key: 'support', - value: function support(event) { - if (this.isPressed() === false) { - if (event.pressure === 0 || event.pressure === 0.5) { - this.fail(event, this.runKey); - } else { - this._startPress(event); - this._changePress(event.pressure, event); - } - } - } - }, { - key: 'change', - value: function change(event) { - if (this.isPressed() && event.pressure > 0 && event.pressure !== 0.5) { - this._changePress(event.pressure, event); - this.deepPress(event.pressure, event); - } - } - }]); - - return AdapterPointer; -}(Adapter); - -// This class holds the states of the the Pressure config - - -var Config = { - - // 'false' will make polyfill not run when pressure is not supported and the 'unsupported' method will be called - polyfill: true, - - // milliseconds it takes to go from 0 to 1 for the polyfill - polyfillSpeedUp: 1000, - - // milliseconds it takes to go from 1 to 0 for the polyfill - polyfillSpeedDown: 0, - - // 'true' prevents the selecting of text and images via css properties - preventSelect: true, - - // 'touch', 'mouse', or 'pointer' will make it run only on that type of device - only: null, - - // this will get the correct config / option settings for the current pressure check - get: function get(option, options) { - return options.hasOwnProperty(option) ? options[option] : this[option]; - }, - - - // this will set the global configs - set: function set(options) { - for (var k in options) { - if (options.hasOwnProperty(k) && this.hasOwnProperty(k) && k != 'get' && k != 'set') { - this[k] = options[k]; - } - } - } -}; - -//------------------- Helpers -------------------// - -// accepts jQuery object, node list, string selector, then called a setup for each element -var loopPressureElements = function loopPressureElements(selector, closure) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - // if a string is passed in as an element - if (typeof selector === 'string' || selector instanceof String) { - var elements = document.querySelectorAll(selector); - for (var i = 0; i < elements.length; i++) { - new Element(elements[i], closure, options); - } - // if a single element object is passed in - } else if (isElement(selector)) { - new Element(selector, closure, options); - // if a node list is passed in ex. jQuery $() object - } else { - for (var i = 0; i < selector.length; i++) { - new Element(selector[i], closure, options); - } - } -}; - -//Returns true if it is a DOM element -var isElement = function isElement(o) { - return (typeof HTMLElement === 'undefined' ? 'undefined' : _typeof(HTMLElement)) === "object" ? o instanceof HTMLElement : //DOM2 - o && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"; -}; - -// the map method allows for interpolating a value from one range of values to another -// example from the Arduino documentation: https://www.arduino.cc/en/Reference/Map -var _map = function _map(x, in_min, in_max, out_min, out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -}; - -var supportsMouse = false; -var supportsTouch = false; -var supportsPointer = false; -var supportsTouchForce = false; -var supportsTouchForceChange = false; - -if (typeof window !== 'undefined') { - // only attempt to assign these in a browser environment. - // on the server, this is a no-op, like the rest of the library - if (typeof Touch !== 'undefined') { - // In Android, new Touch requires arguments. - try { - if (Touch.prototype.hasOwnProperty('force') || 'force' in new Touch()) { - supportsTouchForce = true; - } - } catch (e) {} - } - supportsTouch = 'ontouchstart' in window.document && supportsTouchForce; - supportsMouse = 'onmousemove' in window.document && !supportsTouch; - supportsPointer = 'onpointermove' in window.document; - supportsTouchForceChange = 'ontouchforcechange' in window.document; -} -return Pressure; -})); +// Pressure v2.1.1 | Created By Stuart Yamartino | MIT License | 2015 - 2017 +;(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.Pressure = factory(); + } +}(this, function() { +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +//--------------------- Public API Section ---------------------// +// this is the Pressure Object, this is the only object that is accessible to the end user +// only the methods in this object can be called, making it the "public api" + +var Pressure = { + + // targets any device with Force or 3D Touch + set: function set(selector, closure, options) { + loopPressureElements(selector, closure, options); + }, + + + // set configuration options for global config + config: function config(options) { + Config.set(options); + }, + + + // the map method allows for interpolating a value from one range of values to another + // example from the Arduino documentation: https://www.arduino.cc/en/Reference/Map + map: function map(x, in_min, in_max, out_min, out_max) { + return _map.apply(null, arguments); + } +}; + +var Element = function () { + function Element(el, block, options) { + _classCallCheck(this, Element); + + this.routeEvents(el, block, options); + this.preventSelect(el, options); + } + + _createClass(Element, [{ + key: 'routeEvents', + value: function routeEvents(el, block, options) { + var type = Config.get('only', options); + // for devices that support pointer events + if (supportsPointer && (type === 'pointer' || type === null)) { + this.adapter = new AdapterPointer(el, block, options).bindEvents(); + } + // for devices that support 3D Touch + else if (supportsTouch && (type === 'touch' || type === null)) { + this.adapter = new Adapter3DTouch(el, block, options).bindEvents(); + } + // for devices that support Force Touch + else if (supportsMouse && (type === 'mouse' || type === null)) { + this.adapter = new AdapterForceTouch(el, block, options).bindEvents(); + } + // unsupported if it is requesting a type and your browser is of other type + else { + this.adapter = new Adapter(el, block).bindUnsupportedEvent(); + } + } + + // prevent the default action of text selection, "peak & pop", and force touch special feature + + }, { + key: 'preventSelect', + value: function preventSelect(el, options) { + if (Config.get('preventSelect', options)) { + el.style.webkitTouchCallout = "none"; + el.style.webkitUserSelect = "none"; + el.style.khtmlUserSelect = "none"; + el.style.MozUserSelect = "none"; + el.style.msUserSelect = "none"; + el.style.userSelect = "none"; + } + } + }]); + + return Element; +}(); + +/* +This is the base adapter from which all the other adapters extend. +*/ + +var Adapter = function () { + function Adapter(el, block, options) { + _classCallCheck(this, Adapter); + + this.el = el; + this.block = block; + this.options = options; + this.pressed = false; + this.deepPressed = false; + this.nativeSupport = false; + this.runningPolyfill = false; + this.runKey = Math.random(); + } + + _createClass(Adapter, [{ + key: 'setPressed', + value: function setPressed(boolean) { + this.pressed = boolean; + } + }, { + key: 'setDeepPressed', + value: function setDeepPressed(boolean) { + this.deepPressed = boolean; + } + }, { + key: 'isPressed', + value: function isPressed() { + return this.pressed; + } + }, { + key: 'isDeepPressed', + value: function isDeepPressed() { + return this.deepPressed; + } + }, { + key: 'add', + value: function add(event, set) { + this.el.addEventListener(event, set, false); + } + }, { + key: 'runClosure', + value: function runClosure(method) { + if (method in this.block) { + // call the closure method and apply nth arguments if they exist + this.block[method].apply(this.el, Array.prototype.slice.call(arguments, 1)); + } + } + }, { + key: 'fail', + value: function fail(event, runKey) { + if (Config.get('polyfill', this.options)) { + if (this.runKey === runKey) { + this.runPolyfill(event); + } + } else { + this.runClosure('unsupported', event); + } + } + }, { + key: 'bindUnsupportedEvent', + value: function bindUnsupportedEvent() { + var _this = this; + + this.add(supportsTouch ? 'touchstart' : 'mousedown', function (event) { + return _this.runClosure('unsupported', event); + }); + } + }, { + key: '_startPress', + value: function _startPress(event) { + if (this.isPressed() === false) { + this.runningPolyfill = false; + this.setPressed(true); + this.runClosure('start', event); + } + } + }, { + key: '_startDeepPress', + value: function _startDeepPress(event) { + if (this.isPressed() && this.isDeepPressed() === false) { + this.setDeepPressed(true); + this.runClosure('startDeepPress', event); + } + } + }, { + key: '_changePress', + value: function _changePress(force, event) { + this.nativeSupport = true; + this.runClosure('change', force, event); + } + }, { + key: '_endDeepPress', + value: function _endDeepPress() { + if (this.isPressed() && this.isDeepPressed()) { + this.setDeepPressed(false); + this.runClosure('endDeepPress'); + } + } + }, { + key: '_endPress', + value: function _endPress() { + if (this.runningPolyfill === false) { + if (this.isPressed()) { + this._endDeepPress(); + this.setPressed(false); + this.runClosure('end'); + } + this.runKey = Math.random(); + this.nativeSupport = false; + } else { + this.setPressed(false); + } + } + }, { + key: 'deepPress', + value: function deepPress(force, event) { + force >= 0.5 ? this._startDeepPress(event) : this._endDeepPress(); + } + }, { + key: 'runPolyfill', + value: function runPolyfill(event) { + this.increment = Config.get('polyfillSpeedUp', this.options) === 0 ? 1 : 10 / Config.get('polyfillSpeedUp', this.options); + this.decrement = Config.get('polyfillSpeedDown', this.options) === 0 ? 1 : 10 / Config.get('polyfillSpeedDown', this.options); + this.setPressed(true); + this.runClosure('start', event); + if (this.runningPolyfill === false) { + this.loopPolyfillForce(0, event); + } + } + }, { + key: 'loopPolyfillForce', + value: function loopPolyfillForce(force, event) { + if (this.nativeSupport === false) { + if (this.isPressed()) { + this.runningPolyfill = true; + force = force + this.increment > 1 ? 1 : force + this.increment; + this.runClosure('change', force, event); + this.deepPress(force, event); + setTimeout(this.loopPolyfillForce.bind(this, force, event), 10); + } else { + force = force - this.decrement < 0 ? 0 : force - this.decrement; + if (force < 0.5 && this.isDeepPressed()) { + this.setDeepPressed(false); + this.runClosure('endDeepPress'); + } + if (force === 0) { + this.runningPolyfill = false; + this.setPressed(true); + this._endPress(); + } else { + this.runClosure('change', force, event); + this.deepPress(force, event); + setTimeout(this.loopPolyfillForce.bind(this, force, event), 10); + } + } + } + } + }]); + + return Adapter; +}(); + +/* +This adapter is for Macs with Force Touch trackpads. +*/ + +var AdapterForceTouch = function (_Adapter) { + _inherits(AdapterForceTouch, _Adapter); + + function AdapterForceTouch(el, block, options) { + _classCallCheck(this, AdapterForceTouch); + + return _possibleConstructorReturn(this, (AdapterForceTouch.__proto__ || Object.getPrototypeOf(AdapterForceTouch)).call(this, el, block, options)); + } + + _createClass(AdapterForceTouch, [{ + key: 'bindEvents', + value: function bindEvents() { + this.add('webkitmouseforcewillbegin', this._startPress.bind(this)); + this.add('mousedown', this.support.bind(this)); + this.add('webkitmouseforcechanged', this.change.bind(this)); + this.add('webkitmouseforcedown', this._startDeepPress.bind(this)); + this.add('webkitmouseforceup', this._endDeepPress.bind(this)); + this.add('mouseleave', this._endPress.bind(this)); + this.add('mouseup', this._endPress.bind(this)); + } + }, { + key: 'support', + value: function support(event) { + if (this.isPressed() === false) { + this.fail(event, this.runKey); + } + } + }, { + key: 'change', + value: function change(event) { + if (this.isPressed() && event.webkitForce > 0) { + this._changePress(this.normalizeForce(event.webkitForce), event); + } + } + + // make the force the standard 0 to 1 scale and not the 1 to 3 scale + + }, { + key: 'normalizeForce', + value: function normalizeForce(force) { + return this.reachOne(_map(force, 1, 3, 0, 1)); + } + + // if the force value is above 0.995 set the force to 1 + + }, { + key: 'reachOne', + value: function reachOne(force) { + return force > 0.995 ? 1 : force; + } + }]); + + return AdapterForceTouch; +}(Adapter); + +/* +This adapter is more mobile devices that support 3D Touch. +*/ + +var Adapter3DTouch = function (_Adapter2) { + _inherits(Adapter3DTouch, _Adapter2); + + function Adapter3DTouch(el, block, options) { + _classCallCheck(this, Adapter3DTouch); + + return _possibleConstructorReturn(this, (Adapter3DTouch.__proto__ || Object.getPrototypeOf(Adapter3DTouch)).call(this, el, block, options)); + } + + _createClass(Adapter3DTouch, [{ + key: 'bindEvents', + value: function bindEvents() { + if (supportsTouchForceChange) { + this.add('touchforcechange', this.start.bind(this)); + this.add('touchstart', this.support.bind(this, 0)); + this.add('touchend', this._endPress.bind(this)); + } else { + this.add('touchstart', this.startLegacy.bind(this)); + this.add('touchend', this._endPress.bind(this)); + } + } + }, { + key: 'start', + value: function start(event) { + if (event.touches.length > 0) { + this._startPress(event); + this.touch = this.selectTouch(event); + if (this.touch) { + this._changePress(this.touch.force, event); + } + } + } + }, { + key: 'support', + value: function support(iter, event) { + var runKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.runKey; + + if (this.isPressed() === false) { + if (iter <= 6) { + iter++; + setTimeout(this.support.bind(this, iter, event, runKey), 10); + } else { + this.fail(event, runKey); + } + } + } + }, { + key: 'startLegacy', + value: function startLegacy(event) { + this.initialForce = event.touches[0].force; + this.supportLegacy(0, event, this.runKey, this.initialForce); + } + + // this checks up to 6 times on a touch to see if the touch can read a force value + // if the force value has changed it means the device supports pressure + // more info from this issue https://github.com/yamartino/pressure/issues/15 + + }, { + key: 'supportLegacy', + value: function supportLegacy(iter, event, runKey, force) { + if (force !== this.initialForce) { + this._startPress(event); + this.loopForce(event); + } else if (iter <= 6) { + iter++; + setTimeout(this.supportLegacy.bind(this, iter, event, runKey, force), 10); + } else { + this.fail(event, runKey); + } + } + }, { + key: 'loopForce', + value: function loopForce(event) { + if (this.isPressed()) { + this.touch = this.selectTouch(event); + setTimeout(this.loopForce.bind(this, event), 10); + this._changePress(this.touch.force, event); + } + } + + // link up the touch point to the correct element, this is to support multitouch + + }, { + key: 'selectTouch', + value: function selectTouch(event) { + if (event.touches.length === 1) { + return this.returnTouch(event.touches[0], event); + } else { + for (var i = 0; i < event.touches.length; i++) { + // if the target press is on this element + if (event.touches[i].target === this.el || this.el.contains(event.touches[i].target)) { + return this.returnTouch(event.touches[i], event); + } + } + } + } + + // return the touch and run a start or end for deep press + + }, { + key: 'returnTouch', + value: function returnTouch(touch, event) { + this.deepPress(touch.force, event); + return touch; + } + }]); + + return Adapter3DTouch; +}(Adapter); + +/* +This adapter is for devices that support pointer events. +*/ + +var AdapterPointer = function (_Adapter3) { + _inherits(AdapterPointer, _Adapter3); + + function AdapterPointer(el, block, options) { + _classCallCheck(this, AdapterPointer); + + return _possibleConstructorReturn(this, (AdapterPointer.__proto__ || Object.getPrototypeOf(AdapterPointer)).call(this, el, block, options)); + } + + _createClass(AdapterPointer, [{ + key: 'bindEvents', + value: function bindEvents() { + this.add('pointerdown', this.support.bind(this)); + this.add('pointermove', this.change.bind(this)); + this.add('pointerup', this._endPress.bind(this)); + this.add('pointerleave', this._endPress.bind(this)); + } + }, { + key: 'support', + value: function support(event) { + if (this.isPressed() === false) { + if (event.pressure === 0 || event.pressure === 0.5) { + this.fail(event, this.runKey); + } else { + this._startPress(event); + this._changePress(event.pressure, event); + } + } + } + }, { + key: 'change', + value: function change(event) { + if (this.isPressed() && event.pressure > 0 && event.pressure !== 0.5) { + this._changePress(event.pressure, event); + this.deepPress(event.pressure, event); + } + } + }]); + + return AdapterPointer; +}(Adapter); + +// This class holds the states of the the Pressure config + + +var Config = { + + // 'false' will make polyfill not run when pressure is not supported and the 'unsupported' method will be called + polyfill: true, + + // milliseconds it takes to go from 0 to 1 for the polyfill + polyfillSpeedUp: 1000, + + // milliseconds it takes to go from 1 to 0 for the polyfill + polyfillSpeedDown: 0, + + // 'true' prevents the selecting of text and images via css properties + preventSelect: true, + + // 'touch', 'mouse', or 'pointer' will make it run only on that type of device + only: null, + + // this will get the correct config / option settings for the current pressure check + get: function get(option, options) { + return options.hasOwnProperty(option) ? options[option] : this[option]; + }, + + + // this will set the global configs + set: function set(options) { + for (var k in options) { + if (options.hasOwnProperty(k) && this.hasOwnProperty(k) && k != 'get' && k != 'set') { + this[k] = options[k]; + } + } + } +}; + +//------------------- Helpers -------------------// + +// accepts jQuery object, node list, string selector, then called a setup for each element +var loopPressureElements = function loopPressureElements(selector, closure) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + // if a string is passed in as an element + if (typeof selector === 'string' || selector instanceof String) { + var elements = document.querySelectorAll(selector); + for (var i = 0; i < elements.length; i++) { + new Element(elements[i], closure, options); + } + // if a single element object is passed in + } else if (isElement(selector)) { + new Element(selector, closure, options); + // if a node list is passed in ex. jQuery $() object + } else { + for (var i = 0; i < selector.length; i++) { + new Element(selector[i], closure, options); + } + } +}; + +//Returns true if it is a DOM element +var isElement = function isElement(o) { + return (typeof HTMLElement === 'undefined' ? 'undefined' : _typeof(HTMLElement)) === "object" ? o instanceof HTMLElement : //DOM2 + o && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"; +}; + +// the map method allows for interpolating a value from one range of values to another +// example from the Arduino documentation: https://www.arduino.cc/en/Reference/Map +var _map = function _map(x, in_min, in_max, out_min, out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +}; + +var supportsMouse = false; +var supportsTouch = false; +var supportsPointer = false; +var supportsTouchForce = false; +var supportsTouchForceChange = false; + +if (typeof window !== 'undefined') { + // only attempt to assign these in a browser environment. + // on the server, this is a no-op, like the rest of the library + if (typeof Touch !== 'undefined') { + // In Android, new Touch requires arguments. + try { + if (Touch.prototype.hasOwnProperty('force') || 'force' in new Touch()) { + supportsTouchForce = true; + } + } catch (e) {} + } + supportsTouch = 'ontouchstart' in window.document && supportsTouchForce; + supportsMouse = 'onmousemove' in window.document && !supportsTouch; + supportsPointer = 'onpointermove' in window.document; + supportsTouchForceChange = 'ontouchforcechange' in window.document; +} +return Pressure; +})); diff --git a/game/server.js b/game/server.js index 0ddc4d1d6..49a0ad87f 100644 --- a/game/server.js +++ b/game/server.js @@ -1,386 +1,402 @@ -(function(){ - var WebSocketServer=require('ws').Server; - var wss=new WebSocketServer({port:8080}); - var bannedKeys=[]; - var bannedIps=[]; +(function () { + var WebSocketServer = require("ws").Server; + var wss = new WebSocketServer({ port: 8080 }); + var bannedKeys = []; + var bannedIps = []; - var rooms=[]; - var events=[]; - var clients={}; - var bannedKeyWords=[]; - var messages={ - create:function(key,nickname,avatar,config,mode){ - if(this.onlineKey!=key) return; - this.nickname=util.getNickname(nickname); - this.avatar=avatar; - var room={}; + var rooms = []; + var events = []; + var clients = {}; + var bannedKeyWords = []; + var messages = { + create: function (key, nickname, avatar, config, mode) { + if (this.onlineKey != key) return; + this.nickname = util.getNickname(nickname); + this.avatar = avatar; + var room = {}; rooms.push(room); - this.room=room; + this.room = room; delete this.status; - room.owner=this; - room.key=key; - this.sendl('createroom',key); + room.owner = this; + room.key = key; + this.sendl("createroom", key); }, - enter:function(key,nickname,avatar){ - this.nickname=util.getNickname(nickname); - this.avatar=avatar; - var room=false; - for(var i of rooms){ - if(i.key==key){ - room=i; + enter: function (key, nickname, avatar) { + this.nickname = util.getNickname(nickname); + this.avatar = avatar; + var room = false; + for (var i of rooms) { + if (i.key == key) { + room = i; break; } } - if(!room){ - this.sendl('enterroomfailed'); + if (!room) { + this.sendl("enterroomfailed"); return; } - this.room=room; + this.room = room; delete this.status; - if(room.owner){ - if(room.servermode&&!room.owner._onconfig&&config&&mode){ - room.owner.sendl('createroom',index,config,mode); - room.owner._onconfig=this; - room.owner.nickname=util.getNickname(nickname); - room.owner.avatar=avatar; - } - else if(!room.config||(room.config.gameStarted&&(!room.config.observe||!room.config.observeReady))){ - this.sendl('enterroomfailed'); - } - else{ - this.owner=room.owner; - this.owner.sendl('onconnection',this.wsid); + if (room.owner) { + if ( + room.servermode && + !room.owner._onconfig && + config && + mode + ) { + room.owner.sendl("createroom", index, config, mode); + room.owner._onconfig = this; + room.owner.nickname = util.getNickname(nickname); + room.owner.avatar = avatar; + } else if ( + !room.config || + (room.config.gameStarted && + (!room.config.observe || !room.config.observeReady)) + ) { + this.sendl("enterroomfailed"); + } else { + this.owner = room.owner; + this.owner.sendl("onconnection", this.wsid); } util.updaterooms(); } }, - changeAvatar:function(nickname,avatar){ - this.nickname=util.getNickname(nickname); - this.avatar=avatar; + changeAvatar: function (nickname, avatar) { + this.nickname = util.getNickname(nickname); + this.avatar = avatar; util.updateclients(); }, - server:function(cfg){ - if(cfg){ - this.servermode=true; - var room=rooms[cfg[0]]; - if(!room||room.owner){ - this.sendl('reloadroom',true); + server: function (cfg) { + if (cfg) { + this.servermode = true; + var room = rooms[cfg[0]]; + if (!room || room.owner) { + this.sendl("reloadroom", true); + } else { + room.owner = this; + this.room = room; + this.nickname = util.getNickname(cfg[1]); + this.avatar = cfg[2]; + this.sendl("createroom", cfg[0], {}, "auto"); } - else{ - room.owner=this; - this.room=room; - this.nickname=util.getNickname(cfg[1]); - this.avatar=cfg[2]; - this.sendl('createroom',cfg[0],{},'auto') - } - } - else{ - for(var i=0;i=20){ - this.sendl('eventsdenied','total'); - } - else if(cfg.utc<=time){ - this.sendl('eventsdenied','time'); - } - else if(util.isBanned(cfg.content)){ - this.sendl('eventsdenied','ban'); - } - else{ - cfg.nickname=util.getNickname(cfg.nickname); - cfg.avatar=cfg.nickname||'caocao'; - cfg.creator=id; - cfg.id=util.getid(); - cfg.members=[id]; + } else if ( + cfg.hasOwnProperty("utc") && + cfg.hasOwnProperty("day") && + cfg.hasOwnProperty("hour") && + cfg.hasOwnProperty("content") + ) { + if (events.length >= 20) { + this.sendl("eventsdenied", "total"); + } else if (cfg.utc <= time) { + this.sendl("eventsdenied", "time"); + } else if (util.isBanned(cfg.content)) { + this.sendl("eventsdenied", "ban"); + } else { + cfg.nickname = util.getNickname(cfg.nickname); + cfg.avatar = cfg.nickname || "caocao"; + cfg.creator = id; + cfg.id = util.getid(); + cfg.members = [id]; events.unshift(cfg); - changed=true; + changed = true; } } } - if(changed){ + if (changed) { util.updateevents(); } }, - config:function(config){ - var room=this.room; - if(room&&room.owner==this){ - if(room.servermode){ - room.servermode=false; - if(this._onconfig){ - if(clients[this._onconfig.wsid]){ - this._onconfig.owner=this; - this.sendl('onconnection',this._onconfig.wsid); + config: function (config) { + var room = this.room; + if (room && room.owner == this) { + if (room.servermode) { + room.servermode = false; + if (this._onconfig) { + if (clients[this._onconfig.wsid]) { + this._onconfig.owner = this; + this.sendl("onconnection", this._onconfig.wsid); } delete this._onconfig; } } - room.config=config; + room.config = config; } util.updaterooms(); }, - status:function(str){ - if(typeof str=='string'){ - this.status=str; - } - else{ + status: function (str) { + if (typeof str == "string") { + this.status = str; + } else { delete this.status; } util.updateclients(); }, - send:function(id,message){ - if(clients[id]&&clients[id].owner==this){ - try{ + send: function (id, message) { + if (clients[id] && clients[id].owner == this) { + try { clients[id].send(message); - } - catch(e){ + } catch (e) { clients[id].close(); } } }, - close:function(id){ - if(clients[id]&&clients[id].owner==this){ + close: function (id) { + if (clients[id] && clients[id].owner == this) { clients[id].close(); } }, }; - var util={ - getNickname:function(str){ - return typeof str=='string'?(str.slice(0,12)):'无名玩家'; + var util = { + getNickname: function (str) { + return typeof str == "string" ? str.slice(0, 12) : "无名玩家"; }, - isBanned:function(str){ - for(var i of bannedKeyWords){ - if(str.indexOf(i)!=-1) return true; + isBanned: function (str) { + for (var i of bannedKeyWords) { + if (str.indexOf(i) != -1) return true; } return false; }, - sendl:function(){ - var args=[]; - for(var i=0;i
                    • 选陆逊左慈张春华于吉蒋费孔融自动变孙笨', - lingsheji:'灵蛇髻', - lingsheji2:'灵蛇髻', - shanrangzhaoshu:'禅让诏书', - xingtianpojunfu:'刑天破军斧', - noda_axe:'刑天破军斧', - noda_axe2:'刑天破军斧', - jinwuluorigong:'金乌落日弓', - iwasawa_crowbow:'金乌落日弓', - lingsheji_info:'出牌阶段结束时,你可选择:1.摸一张牌。2.将一张武将牌置于武将牌上,并于回合结束后获得此牌。', - shanrangzhaoshu_info:'其他角色于回合外得到牌后,若是其本回合内第一次得到牌,则你可以选择一项:交给其一张牌,或令其交给你一张牌。', - xingtianpojunfu_info:'当你于出牌阶段内使用牌指定唯一目标后,你可弃置两张牌。若如此做,其本回合内不能使用或打出牌且其防具技能无效。', - jinwuluorigong_info:'当你于出牌阶段内一次性失去了两张以上的手牌后,你可以弃置一名其他角色等量的牌。', - TheDayIBecomeAGod:'神杀', - thedayibecomeagod:'传承', - thedayibecomeagod_info:'选择一名其他己方角色。若其势力非神,则改为神势力;若其势力为神,则将武将牌翻至正面,回复体力至体力上限,并将手牌摸至5。', - gubuzifeng:'故步自封', - gubuzifeng_disable:'故步自封', - gubuzifeng_info:'出牌阶段,对一名其他角色使用。其的一个随机技能失效直到其下个回合结束。', - goujiangdesidai:'篝酱的丝带', - goujiangdesidai_info:'锁定技,若你未拥有技能〖纵丝〗,则你视为拥有技能〖纵丝〗;若你拥有技能〖纵丝〗,则你将此技能改为「出牌阶段限两次」。', - goujiangdesidai_skill:'纵丝', - niaobaidaowenha:'鸟白岛文蛤', - niaobaidaowenha_skill:'鸟白岛文蛤', - niaobaidaowenha_info:'当你减少1点体力上限后,你可令一名其他角色增加1点体力上限并回复1点体力。', - niaobaidaowenha_skill_info:'当你减少1点体力上限后,你可令一名其他角色增加1点体力上限并回复1点体力。', - shenzhixiunvfu:'神之修女服', - shenzhixiunvfu_info:'没什么实际作用的衣服,仅仅是显得像个神而已。', + boss_newhuanren: "关卡说明", + boss_newhuanren_info: "", + boss_newhuanren_info_boss: + "第一关:挑战秦广王
                      第二关:挑战楚江王,宋帝王,五官王,阎罗王中的一个
                      第三关:挑战卞城王,泰山王,都市王,平等王中的一个
                      第四关:挑战转轮王
                      注:孟婆将在每局前三个阶段随机一个阶段登场
                      地藏王登场规则为,50回合内通过第三关,并且在前三关中成功击杀孟婆。
                    • 选陆逊左慈张春华于吉蒋费孔融自动变孙笨", + lingsheji: "灵蛇髻", + lingsheji2: "灵蛇髻", + shanrangzhaoshu: "禅让诏书", + xingtianpojunfu: "刑天破军斧", + noda_axe: "刑天破军斧", + noda_axe2: "刑天破军斧", + jinwuluorigong: "金乌落日弓", + iwasawa_crowbow: "金乌落日弓", + lingsheji_info: + "出牌阶段结束时,你可选择:1.摸一张牌。2.将一张武将牌置于武将牌上,并于回合结束后获得此牌。", + shanrangzhaoshu_info: + "其他角色于回合外得到牌后,若是其本回合内第一次得到牌,则你可以选择一项:交给其一张牌,或令其交给你一张牌。", + xingtianpojunfu_info: + "当你于出牌阶段内使用牌指定唯一目标后,你可弃置两张牌。若如此做,其本回合内不能使用或打出牌且其防具技能无效。", + jinwuluorigong_info: + "当你于出牌阶段内一次性失去了两张以上的手牌后,你可以弃置一名其他角色等量的牌。", + TheDayIBecomeAGod: "神杀", + thedayibecomeagod: "传承", + thedayibecomeagod_info: + "选择一名其他己方角色。若其势力非神,则改为神势力;若其势力为神,则将武将牌翻至正面,回复体力至体力上限,并将手牌摸至5。", + gubuzifeng: "故步自封", + gubuzifeng_disable: "故步自封", + gubuzifeng_info: "出牌阶段,对一名其他角色使用。其的一个随机技能失效直到其下个回合结束。", + goujiangdesidai: "篝酱的丝带", + goujiangdesidai_info: + "锁定技,若你未拥有技能〖纵丝〗,则你视为拥有技能〖纵丝〗;若你拥有技能〖纵丝〗,则你将此技能改为「出牌阶段限两次」。", + goujiangdesidai_skill: "纵丝", + niaobaidaowenha: "鸟白岛文蛤", + niaobaidaowenha_skill: "鸟白岛文蛤", + niaobaidaowenha_info: "当你减少1点体力上限后,你可令一名其他角色增加1点体力上限并回复1点体力。", + niaobaidaowenha_skill_info: + "当你减少1点体力上限后,你可令一名其他角色增加1点体力上限并回复1点体力。", + shenzhixiunvfu: "神之修女服", + shenzhixiunvfu_info: "没什么实际作用的衣服,仅仅是显得像个神而已。", - mode_boss_card_config:'挑战卡牌', - mode_boss_character_config:'挑战武将', + mode_boss_card_config: "挑战卡牌", + mode_boss_character_config: "挑战武将", + }, + get: { + rawAttitude: function (from, to) { + var num = to.identity == "zhong" ? 5 : 6; + return from.side === to.side ? num : -num; + }, }, - get:{ - rawAttitude:function(from,to){ - var num=(to.identity=='zhong')?5:6; - return (from.side===to.side?num:-num); - } - } }; }); diff --git a/mode/brawl.js b/mode/brawl.js index 949dd730a..1ddbb59d8 100644 --- a/mode/brawl.js +++ b/mode/brawl.js @@ -1,307 +1,307 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'brawl', - game:{ - syncMenu:true, + name: "brawl", + game: { + syncMenu: true, }, - start:function(){ + start: function () { ui.auto.hide(); - if(!lib.storage.scene){ - lib.storage.scene={}; + if (!lib.storage.scene) { + lib.storage.scene = {}; } - if(!lib.storage.stage){ - lib.storage.stage={}; + if (!lib.storage.stage) { + lib.storage.stage = {}; } - if(!_status.extensionmade){ - _status.extensionmade=[]; + if (!_status.extensionmade) { + _status.extensionmade = []; } - if(_status.extensionscene){ - game.save('scene',lib.storage.scene); + if (_status.extensionscene) { + game.save("scene", lib.storage.scene); } - if(_status.extensionstage){ - game.save('stage',lib.storage.stage); + if (_status.extensionstage) { + game.save("stage", lib.storage.stage); } - var dialog=ui.create.dialog('hidden'); - dialog.classList.add('fixed'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.classList.add('noupdate'); - dialog.classList.add('character'); - dialog.contentContainer.style.overflow='visible'; - dialog.style.overflow='hidden'; - dialog.content.style.height='100%'; - dialog.contentContainer.style.transition='all 0s'; - if(!lib.storage.directStage) dialog.open(); - var packnode=ui.create.div('.packnode',dialog); + var dialog = ui.create.dialog("hidden"); + dialog.classList.add("fixed"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.classList.add("noupdate"); + dialog.classList.add("character"); + dialog.contentContainer.style.overflow = "visible"; + dialog.style.overflow = "hidden"; + dialog.content.style.height = "100%"; + dialog.contentContainer.style.transition = "all 0s"; + if (!lib.storage.directStage) dialog.open(); + var packnode = ui.create.div(".packnode", dialog); lib.setScroll(packnode); - var clickCapt=function(){ - var active=this.parentNode.querySelector('.active'); - if(this.link=='stage'){ - if(get.is.empty(lib.storage.scene)){ - alert('请创建至少1个场景'); + var clickCapt = function () { + var active = this.parentNode.querySelector(".active"); + if (this.link == "stage") { + if (get.is.empty(lib.storage.scene)) { + alert("请创建至少1个场景"); return; } } - if(active){ - if(active==this) return; - for(var i=0;istage.level){ - stage.level=level.index+1; - game.save('stage',stagesave,'brawl'); + if (level.index + 1 > stage.level) { + stage.level = level.index + 1; + game.save("stage", stagesave, "brawl"); } - if(stage.mode!='sequal'){ - game.save('lastStage',level.index+1,'brawl'); + if (stage.mode != "sequal") { + game.save("lastStage", level.index + 1, "brawl"); } - } - else{ - ui.create.control('重新开始',function(){ - if(stage.mode=='sequal'&&bool&&level.index==stage.scenes.length-1){ - game.save('directStage',[stage.name,0],'brawl'); + } else { + ui.create.control("重新开始", function () { + if ( + stage.mode == "sequal" && + bool && + level.index == stage.scenes.length - 1 + ) { + game.save("directStage", [stage.name, 0], "brawl"); + } else { + game.save("directStage", [stage.name, level.index], "brawl"); } - else{ - game.save('directStage',[stage.name,level.index],'brawl'); - } - localStorage.setItem(lib.configprefix+'directstart',true); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); }); - if(stage.mode=='sequal'&&level.index==stage.scenes.length-1){ - stage.level=0; - game.save('stage',stagesave,'brawl'); + if (stage.mode == "sequal" && level.index == stage.scenes.length - 1) { + stage.level = 0; + game.save("stage", stagesave, "brawl"); } - if(stage.mode!='sequal'){ - game.save('lastStage',level.index,'brawl'); + if (stage.mode != "sequal") { + game.save("lastStage", level.index, "brawl"); } } delete _status.createControl; }); - var scene=stage.scenes[level.index]; - info={ - name:scene.name, - intro:scene.intro, + var scene = stage.scenes[level.index]; + info = { + name: scene.name, + intro: scene.intro, }; - for(var i in lib.brawl.scene.template){ - info[i]=get.copy(lib.brawl.scene.template[i]); + for (var i in lib.brawl.scene.template) { + info[i] = get.copy(lib.brawl.scene.template[i]); } - if(!scene.gameDraw){ - info.content.noGameDraw=true; + if (!scene.gameDraw) { + info.content.noGameDraw = true; } - info.content.scene=scene; - } - else{ + info.content.scene = scene; + } else { return; } + } else { + info = lib.brawl[active.link]; } - else{ - info=lib.brawl[active.link]; - } - lib.translate.restart='返回'; + lib.translate.restart = "返回"; dialog.delete(); - ui.brawlinfo=ui.create.system('乱斗',null,true); - lib.setPopped(ui.brawlinfo,function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add(info.name); - var intro; - if(Array.isArray(info.intro)){ - intro='
                        '; - for(var i=0;i'+intro+''); - var ul=uiintro.querySelector('ul'); - if(ul){ - ul.style.width='180px'; - } - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + uiintro.add('
                        ' + intro + "
                        "); + var ul = uiintro.querySelector("ul"); + if (ul) { + ul.style.width = "180px"; + } + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); ui.auto.show(); - _status.brawl=info.content; + _status.brawl = info.content; game.switchMode(info.mode); - if(info.init){ + if (info.init) { info.init(); } } }; - var start=ui.create.div('.menubutton.round.highlight','斗',dialog.content,clickStart); - start.style.position='absolute'; - start.style.left='auto'; - start.style.right='10px'; - start.style.top='auto'; - start.style.bottom='10px'; - start.style.width='80px'; - start.style.height='80px'; - start.style.lineHeight='80px'; - start.style.margin='0'; - start.style.padding='5px'; - start.style.fontSize='72px'; - start.style.zIndex=3; - start.style.transition='all 0s'; - game.addScene=function(name,clear){ - var scene=lib.storage.scene[name]; - var brawl={ - name:name, - intro:scene.intro, + var start = ui.create.div(".menubutton.round.highlight", "斗", dialog.content, clickStart); + start.style.position = "absolute"; + start.style.left = "auto"; + start.style.right = "10px"; + start.style.top = "auto"; + start.style.bottom = "10px"; + start.style.width = "80px"; + start.style.height = "80px"; + start.style.lineHeight = "80px"; + start.style.margin = "0"; + start.style.padding = "5px"; + start.style.fontSize = "72px"; + start.style.zIndex = 3; + start.style.transition = "all 0s"; + game.addScene = function (name, clear) { + var scene = lib.storage.scene[name]; + var brawl = { + name: name, + intro: scene.intro, }; - for(var i in lib.brawl.scene.template){ - brawl[i]=get.copy(lib.brawl.scene.template[i]); + for (var i in lib.brawl.scene.template) { + brawl[i] = get.copy(lib.brawl.scene.template[i]); } - if(!scene.gameDraw){ - brawl.content.noGameDraw=true; + if (!scene.gameDraw) { + brawl.content.noGameDraw = true; } - brawl.content.scene=scene; - lib.brawl['scene_'+name]=brawl; - var node=createNode('scene_'+name); - if(clear){ + brawl.content.scene = scene; + lib.brawl["scene_" + name] = brawl; + var node = createNode("scene_" + name); + if (clear) { game.addSceneClear(); clickCapt.call(node); - _status.sceneChanged=true; + _status.sceneChanged = true; } }; - game.addStage=function(name,clear){ - var stage=lib.storage.stage[name]; - var brawl={ - name:name, - intro:stage.intro, - content:{} + game.addStage = function (name, clear) { + var stage = lib.storage.stage[name]; + var brawl = { + name: name, + intro: stage.intro, + content: {}, }; - for(var i in lib.brawl.stage.template){ - brawl[i]=get.copy(lib.brawl.stage.template[i]); + for (var i in lib.brawl.stage.template) { + brawl[i] = get.copy(lib.brawl.stage.template[i]); } - brawl.content.stage=stage; - lib.brawl['stage_'+name]=brawl; - var node=createNode('stage_'+name); - if(clear){ + brawl.content.stage = stage; + lib.brawl["stage_" + name] = brawl; + var node = createNode("stage_" + name); + if (clear) { game.addStageClear(); clickCapt.call(node); } - } - game.removeScene=function(name){ + }; + game.removeScene = function (name) { delete lib.storage.scene[name]; - game.save('scene',lib.storage.scene); - _status.sceneChanged=true; - for(var i=0;i7){ - nodes[i].index=0; + if (nodes[i].index > 7) { + nodes[i].index = 0; } setPos(nodes[i]); } - },1000); + }, 1000); }, - init:function(){}, - content:{ - submode:'normal', - chooseCharacterBefore:function(){ - game.identityVideoName='幻化之战'; - var skills=[]; - var banned=[ - 'xinfu_guhuo','reguhuo','jixi','duanchang','huashen','xinsheng','rehuashen','rexinsheng', - 'jinqu','nzry_binglve','nzry_huaiju','nzry_yili','nzry_zhenglun','nzry_mingren','nzry_zhenliang','drlt_qingce', - 'new_wuhun','qixing','kuangfeng','dawu','baonu','wumou','ol_wuqian','ol_shenfen','renjie','jilue','nzry_junlve','nzry_dinghuo','drlt_duorui', - 'chuanxin','cunsi', - 'jueqing','huilei','paiyi','fuhun','zhuiyi','olddanshou','yanzhu','juexiang','jiexun','bizhuan','tongbo', - 'xinfu_zhanji','xinfu_jijun','xinfu_fangtong', - 'xinfu_qianchong','pdgyinshi','shuliang', - 'zongkui','guju','bmcanshi','dingpan','xinfu_lingren','new_luoyan','junwei','gxlianhua', - 'qizhou','fenyue','dianhu','linglong','fenxin','mouduan', - 'cuorui','xinmanjuan','xinfu_jianjie','jianjie_faq','new_meibu','xinfu_xingzhao','jici', - 'xianfu','fenyong','xuehen','yingbin','midao','yishe','yinbing','juedi', - 'bushi','xinfu_dianhua','xinfu_falu','xinfu_zhenyi','lskuizhu','pingjian','xjshijian','fentian','zhiri','xindan', - 'xinzhengnan','xinfu_xiaode', - 'komari_xueshang','qiaosi_map', - ]; - var characters=[]; - for(var name in lib.character){ - if(!lib.character[name]) continue; - if(lib.filter.characterDisabled(name)) continue; - if(name.indexOf('old_')==0) continue; - var skillsx=lib.character[name][3].slice(0); - lib.character[name][2]=4; - lib.character[name][3]=[]; - if(lib.character[name][4]) lib.character[name][4].remove('hiddenSkill'); - characters.push(name); - var list=skillsx.slice(0); - for(var j=0;j0; - }, - content:function(){ - target.removeSkillH(target.skillH.randomGet()); - var skills=lib.huanhuazhizhan.skills; - skills.randomSort(); - for(var i=0;i 0; + }, + content: function () { + target.removeSkillH(target.skillH.randomGet()); + var skills = lib.huanhuazhizhan.skills; + skills.randomSort(); + for (var i = 0; i < skills.length; i++) { + if (!target.skillH.includes(skills[i])) { + target.addSkillH(skills[i]); + break; + } } - } - }, - ai:{ - order:10, - result:{ - target:function(){ - return 0.5-Math.random(); + }, + ai: { + order: 10, + result: { + target: function () { + return 0.5 - Math.random(); + }, }, }, }, - }, - hhzz_fudichouxin:{ - enable:true, - cardimage:"fudichouxin", - type:'trick', - filterTarget:function(card,player,target){ - return target.skillH.length>0; - }, - content:function(){ - target.removeSkillH(target.skillH.randomGet()); - }, - ai:{ - order:10, - result:{target:-1}, - }, - }, - }, - character:{ - hhzz_shiona:['female','key',1,['hhzz_huilei']], - hhzz_kanade:['female','key',2,['hhzz_youlian']], - hhzz_takaramono1:['male','qun',5,['hhzz_jubao','hhzz_huizhen']], - hhzz_takaramono2:['male','qun',3,['hhzz_jubao','hhzz_zhencang']], - }, - skill:{ - _lingli_damage:{ - trigger:{source:'damage'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player==player._toKill; - }, - content:function(){ - game.log(player,'对击杀目标造成了伤害'); - player.changeLingli(trigger.num); - }, - }, - _lingli:{ - mark:true, - marktext:'灵', - popup:'聚灵', - intro:{ - name:'灵力', - content:'当前灵力点数:# / 5', - }, - trigger:{ - player:'phaseBeginStart', - }, - prompt:'是否消耗2点灵力获得一个技能?', - filter:function(event,player){ - return player.storage._lingli>1; - }, - check:function(event,player){ - return player.skillH.length<3; - }, - content:function(){ - 'step 0' - player.changeLingli(-2); - 'step 1' - event.skills=lib.huanhuazhizhan.skills; - var skills=event.skills; - skills.randomSort(); - var list=[]; - for(var i=0;i0) list.push('刷新'); - event.list=list; - var dialog=game.getSkillDialog(event.list,'选择获得一个技能'); - player.chooseControl(event.list).set('ai',function(){ - return 0; - }).dialog=dialog; - 'step 2' - if(result.control=='刷新'){ - player.changeLingli(-1); - event.goto(1); - return; - } - event.skill=result.control; - if(player.skillH.length==3){ - event.lose=true; - player.chooseControl(player.skillH).prompt='选择失去1个已有技能'; - } - 'step 3' - if(event.lose) player.removeSkillH(result.control); - player.addSkillH(event.skill); - }, - }, - _lingli_round:{ - trigger:{global:'roundStart'}, - forced:true, - popup:false, - filter:function(event,player){ - return _status._aozhan!=true&&game.roundNumber>1; - }, - content:function(){ - player.changeLingli(1); - }, - }, - _lingli_draw:{ - enable:'phaseUse', - filter:function(event,player){ - return player.storage._lingli>0; - }, - content:function(){ - player.changeLingli(-1); - player.draw(); - }, - delay:0, - ai:{ - order:10, - result:{ - player:function(player){ - return (player.storage._lingli-2*(3-player.skillH.length))>0?1:0; - }, + hhzz_fudichouxin: { + enable: true, + cardimage: "fudichouxin", + type: "trick", + filterTarget: function (card, player, target) { + return target.skillH.length > 0; + }, + content: function () { + target.removeSkillH(target.skillH.randomGet()); + }, + ai: { + order: 10, + result: { target: -1 }, }, }, }, - _lingli_save:{ - trigger:{target:'useCardToTargeted'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.name=='tao'&&player==event.player._toSave; - }, - content:function(){ - game.log(trigger.player,'帮助了保护目标'); - trigger.player.changeLingli(1); - }, + character: { + hhzz_shiona: ["female", "key", 1, ["hhzz_huilei"]], + hhzz_kanade: ["female", "key", 2, ["hhzz_youlian"]], + hhzz_takaramono1: ["male", "qun", 5, ["hhzz_jubao", "hhzz_huizhen"]], + hhzz_takaramono2: ["male", "qun", 3, ["hhzz_jubao", "hhzz_zhencang"]], }, - _hhzz_qiankunbagua:{ - trigger:{player:'phaseAfter'}, - forced:true, - forceDie:true, - popup:false, - filter:function(event,player){ - return _status._aozhan&&!player.getStat('damage')&&player.isAlive()||event._lastDead!=undefined; + skill: { + _lingli_damage: { + trigger: { source: "damage" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player._toKill; + }, + content: function () { + game.log(player, "对击杀目标造成了伤害"); + player.changeLingli(trigger.num); + }, }, - content:function(){ - 'step 0' - if(_status._aozhan&&!player.getStat('damage')){ - player.loseHp(); + _lingli: { + mark: true, + marktext: "灵", + popup: "聚灵", + intro: { + name: "灵力", + content: "当前灵力点数:# / 5", + }, + trigger: { + player: "phaseBeginStart", + }, + prompt: "是否消耗2点灵力获得一个技能?", + filter: function (event, player) { + return player.storage._lingli > 1; + }, + check: function (event, player) { + return player.skillH.length < 3; + }, + content: function () { + "step 0"; + player.changeLingli(-2); + "step 1"; + event.skills = lib.huanhuazhizhan.skills; + var skills = event.skills; + skills.randomSort(); + var list = []; + for (var i = 0; i < skills[i].length; i++) { + if (!player.skillH.includes(skills[i])) list.push(skills[i]); + if (list.length == 3) break; + } + if (!list.length) { + event.finish(); + return; + } + if (player.storage._lingli > 0) list.push("刷新"); + event.list = list; + var dialog = game.getSkillDialog(event.list, "选择获得一个技能"); + player.chooseControl(event.list).set("ai", function () { + return 0; + }).dialog = dialog; + "step 2"; + if (result.control == "刷新") { + player.changeLingli(-1); + event.goto(1); + return; + } + event.skill = result.control; + if (player.skillH.length == 3) { + event.lose = true; + player.chooseControl(player.skillH).prompt = + "选择失去1个已有技能"; + } + "step 3"; + if (event.lose) player.removeSkillH(result.control); + player.addSkillH(event.skill); + }, + }, + _lingli_round: { + trigger: { global: "roundStart" }, + forced: true, + popup: false, + filter: function (event, player) { + return _status._aozhan != true && game.roundNumber > 1; + }, + content: function () { player.changeLingli(1); - game.log(player,'本回合内未造成伤害,触发死战模式惩罚'); - } - if(trigger._lastDead==undefined) event.goto(2); - 'step 1' - var type=get.rand(1,8); - event.type=type; - trigger._lastDead.playerfocus(1200); - player.$fullscreenpop('乾坤八卦·'+['离','坎','乾','震','兑','艮','巽','坤'][type-1],get.groupnature(trigger._lastDead.group,'raw')); - game.delay(1.5); - 'step 2' - var type=event.type; - switch(type){ - case 1:{ - game.countPlayer(function(current){ - current.loseHp(); - }); - break; + }, + }, + _lingli_draw: { + enable: "phaseUse", + filter: function (event, player) { + return player.storage._lingli > 0; + }, + content: function () { + player.changeLingli(-1); + player.draw(); + }, + delay: 0, + ai: { + order: 10, + result: { + player: function (player) { + return player.storage._lingli - + 2 * (3 - player.skillH.length) > + 0 + ? 1 + : 0; + }, + }, + }, + }, + _lingli_save: { + trigger: { target: "useCardToTargeted" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card.name == "tao" && player == event.player._toSave; + }, + content: function () { + game.log(trigger.player, "帮助了保护目标"); + trigger.player.changeLingli(1); + }, + }, + _hhzz_qiankunbagua: { + trigger: { player: "phaseAfter" }, + forced: true, + forceDie: true, + popup: false, + filter: function (event, player) { + return ( + (_status._aozhan && + !player.getStat("damage") && + player.isAlive()) || + event._lastDead != undefined + ); + }, + content: function () { + "step 0"; + if (_status._aozhan && !player.getStat("damage")) { + player.loseHp(); + player.changeLingli(1); + game.log(player, "本回合内未造成伤害,触发死战模式惩罚"); } - case 2:{ - game.countPlayer(function(current){ - current.draw(2,'nodelay'); - }); - break; - } - case 3:{ - trigger._lastDead.revive(3); - trigger._lastDead.draw(3); - break; - } - case 4:{ - game.countPlayer(function(current){ - var he=current.getCards('he'); - if(he.length) current.discard(he.randomGet()).delay=false; - }); - break; - } - case 5:{ - game.countPlayer(function(current){ - current.changeLingli(1); - }); - break; - } - case 6:{ - var cards=[]; - game.countPlayer(function(current){ - var card=get.cardPile(function(card){ - return !cards.includes(card)&&get.type(card)=='equip'; + if (trigger._lastDead == undefined) event.goto(2); + "step 1"; + var type = get.rand(1, 8); + event.type = type; + trigger._lastDead.playerfocus(1200); + player.$fullscreenpop( + "乾坤八卦·" + + ["离", "坎", "乾", "震", "兑", "艮", "巽", "坤"][ + type - 1 + ], + get.groupnature(trigger._lastDead.group, "raw") + ); + game.delay(1.5); + "step 2"; + var type = event.type; + switch (type) { + case 1: { + game.countPlayer(function (current) { + current.loseHp(); }); - if(card){ - cards.push(card); - current.$gain(card,'gain2') - current.gain(card); - } - }); - break; - } - case 7:{ - game.countPlayer(function(current){ - if(current.skillH.length<3){ - var skills=lib.huanhuazhizhan.skills; - skills.randomSort(); - for(var i=0;i 0; + }, + content: function () { + var cards = player.getCards("he"); + cards.randomSort(); + cards = cards.slice(0, trigger.num); + trigger.source.gain("give", cards, player); + }, + ai: { + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) return [15, 0]; + }, + }, + }, }, }, - hhzz_noCard:{ - mod:{ - cardEnabled:function(){return false}, - cardSavable:function(){return false}, - cardRespondable:function(){return false}, - }, - }, - hhzz_huilei:{ - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - logTarget:'source', - filter:function(event,player){ - return event.source!=undefined; - }, - content:function(){ - var source=trigger.source; - var cards=source.getCards('he'); - if(cards.length) source.discard(cards); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return [-5,0]; - } - } - } - }, - hhzz_youlian:{ - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - logTarget:'source', - filter:function(event,player){ - return event.source!=undefined; - }, - content:function(){ - var source=trigger.source; - var cards=source.getCards('he'); - if(cards.length) source.discard(cards); - var skills=source.skillH; - if(skills.length) source.removeSkillH(skills.randomGet()); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return [-5,0]; - } - } - } - }, - hhzz_zhencang:{ - trigger:{player:'die'}, - forced:true, - filter:function(event,player){ - return event.source!=undefined; - }, - forceDie:true, - logTarget:'source', - content:function(){ - var source=trigger.source; - source.draw(); - if(source.skillH.length==3) source.removeSkillH(source.skillH.randomGet()); - var skills=lib.huanhuazhizhan.skills; - skills.randomSort(); - for(var i=0;i0; - }, - content:function(){ - var cards=player.getCards('he'); - cards.randomSort(); - cards=cards.slice(0,trigger.num); - trigger.source.gain('give',cards,player); - }, - ai:{ - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')) return [15,0]; - } - } - } + translate: { + _lingli: "聚灵", + _lingli_bg: "灵", + _lingli_draw: "聚灵", + hhzz_huilei: "挥泪", + hhzz_youlian: "犹怜", + hhzz_zhencang: "珍藏", + hhzz_huizhen: "汇珍", + hhzz_jubao: "聚宝", + hhzz_huilei_info: "锁定技,杀死你的角色弃置所有的牌。", + hhzz_youlian_info: "锁定技,杀死你的角色弃置所有牌并随机失去一个技能。", + hhzz_zhencang_info: + "锁定技,杀死你的角色摸一张牌并随机获得一个技能(已满则先随机移除一个)。", + hhzz_huizhen_info: + "锁定技,杀死你的角色摸三张牌并随机获得一个技能(已满则先随机移除一个)。", + hhzz_jubao_info: + "锁定技,当你受到伤害的点数确定时,伤害来源随机获得你区域内的X张牌(X为伤害点数)。", + hhzz_shiona: "汐奈", + hhzz_kanade: "立华奏", + hhzz_takaramono1: "坚实宝箱", + hhzz_takaramono2: "普通宝箱", + hhzz_toulianghuanzhu: "偷梁换柱", + hhzz_fudichouxin: "釜底抽薪", + hhzz_toulianghuanzhu_info: + "出牌阶段,对一名角色使用,随机更换其一个技能。可重铸。", + hhzz_fudichouxin_info: "出牌阶段,对一名角色使用,随机弃置其一个技能。", + nei: " ", + nei2: " ", + 刷新_info: "消耗1点灵力值,刷新上述技能。", }, }, - translate:{ - _lingli:'聚灵', - _lingli_bg:'灵', - _lingli_draw:'聚灵', - hhzz_huilei:'挥泪', - hhzz_youlian:'犹怜', - hhzz_zhencang:'珍藏', - hhzz_huizhen:'汇珍', - hhzz_jubao:'聚宝', - hhzz_huilei_info:'锁定技,杀死你的角色弃置所有的牌。', - hhzz_youlian_info:'锁定技,杀死你的角色弃置所有牌并随机失去一个技能。', - hhzz_zhencang_info:'锁定技,杀死你的角色摸一张牌并随机获得一个技能(已满则先随机移除一个)。', - hhzz_huizhen_info:'锁定技,杀死你的角色摸三张牌并随机获得一个技能(已满则先随机移除一个)。', - hhzz_jubao_info:'锁定技,当你受到伤害的点数确定时,伤害来源随机获得你区域内的X张牌(X为伤害点数)。', - hhzz_shiona:'汐奈', - hhzz_kanade:'立华奏', - hhzz_takaramono1:'坚实宝箱', - hhzz_takaramono2:'普通宝箱', - hhzz_toulianghuanzhu:'偷梁换柱', - hhzz_fudichouxin:'釜底抽薪', - hhzz_toulianghuanzhu_info:'出牌阶段,对一名角色使用,随机更换其一个技能。可重铸。', - hhzz_fudichouxin_info:'出牌阶段,对一名角色使用,随机弃置其一个技能。', - nei:' ', - nei2:' ', - 刷新_info:'消耗1点灵力值,刷新上述技能。', + get: { + rawAttitude: function (from, to) { + if (from == to || to == from._toSave) return 10; + if (to == from._toKill) return -30; + return -10; + }, }, - }, - get:{ - rawAttitude:function(from,to){ - if(from==to||to==from._toSave) return 10; - if(to==from._toKill) return -30; - return -10; + eltc: { + gameDraw: function () { + var end = player; + var numx; + var num = function (player) { + return player._hSeat > 5 ? 5 : 4; + }; + do { + if (typeof num == "function") { + numx = num(player); + } + if (player._hSeat > 6) player.changeLingli(1); + player.directgain(get.cards(numx)); + player = player.next; + } while (player != end); + }, + }, + eltp: { + addSkillH: function (skill) { + this.skillH.add(skill); + this.addSkillLog.apply(this, arguments); + }, + removeSkillH: function (skill) { + this.skillH.remove(skill); + game.log(this, "失去了技能", "#g【" + get.translation(skill) + "】"); + this.removeSkill(skill); + }, + dieAfter: function () { + var evt = _status.event.getParent("phase"); + if (evt) evt._lastDead = this; + if (game.playerx().length == 1) game.over(game.me.isAlive()); + }, + $dieAfter: function () {}, + hasUnknown: function () { + return false; + }, + isUnknown: function () { + return false; + }, + getEnemies: function () { + var list = game.playerx(); + list.remove(this); + return list; + }, + dieAfter2: function (source) { + if (source && this.name.indexOf("hhzz_") != 0) { + if (source._toKill == this) game.log(source, "击杀目标成功"); + source.draw(this == source._toKill ? 2 : 1); + source.changeLingli(this == source._toKill ? 3 : 2); + } + if (!_status._aozhan) { + var that = this; + game.countPlayer(function (current) { + if (current._toSave == that) { + game.log(current, "保护失败"); + var cards = current.getCards("he"); + if (cards.length) current.discard(cards.randomGets(4)); + } + }); + } + }, + logAi: function () {}, + changeLingli: function (num) { + if (typeof num != "number") num = 1; + if (typeof this.storage._lingli != "number") this.storage._lingli = 0; + if (num > 0) { + num = Math.min(num, 5 - this.storage._lingli); + if (num < 1) return; + game.log(this, "获得了", "#y" + get.cnNumber(num) + "点", "灵力"); + } else { + if (-num > this.storage._lingli) num = -this.storage._lingli; + if (num == 0) return; + game.log(this, "失去了", "#y" + get.cnNumber(-num) + "点", "灵力"); + } + this.storage._lingli += num; + this.markSkill("_lingli"); + }, + }, + game: { + playerx: function () { + return game.filterPlayer(function (current) { + if (current.name.indexOf("hhzz_") == 0) return; + return true; + }); + }, + randomMission: function () { + if (_status._aozhan) return; + if (!ui.huanhuazhizhan) { + ui.huanhuazhizhan = ui.create.div(".touchinfo.left", ui.window); + if (ui.time3) ui.time3.style.display = "none"; + } + var players = game.playerx(); + for (var i = 0; i < players.length; i++) { + var player = players[i]; + var list = players.slice(0).randomSort(); + list.remove(player); + player._toKill = list[0]; + player._toSave = list[1]; + } + ui.huanhuazhizhan.innerHTML = + "击杀" + + get.translation(game.me._toKill) + + ",保护" + + get.translation(game.me._toSave); + }, + getSkillDialog: function (skills, prompt) { + var dialog = ui.create.dialog("hidden", "forcebutton"); + if (prompt) dialog.addText(prompt); + for (var i = 0; i < skills.length; i++) { + dialog.add( + '" + ); + } + dialog.addText("
                        "); + return dialog; + }, + chooseCharacter: function () { + var next = game.createEvent("chooseCharacter"); + next.showConfig = true; + next.setContent(function () { + "step 0"; + game.zhu = game.players.randomGet(); + var i = 1; + var current = game.zhu; + while (true) { + current.skillH = []; + current._hSeat = i; + current.identity = "nei"; + current.setNickname(get.cnNumber(i, true) + "号位"); + for (var ii in lib.huanhuazhizhan.eltp) + current[ii] = lib.huanhuazhizhan.eltp[ii]; + current = current.next; + i++; + if (current == game.zhu) break; + } + ui.arena.classList.add("choose-character"); + game.me.chooseButton( + [ + "请选择角色形象", + [_status.characterlist.randomRemove(5), "character"], + ], + true + ).onfree = true; + "step 1"; + game.me.init(result.links[0]); + var list = ["xiandeng", "shulv", "xisheng"]; + game.me.chooseControl(list).dialog = game.getSkillDialog( + list, + "选择要获得的初始技能" + ); + "step 2"; + var list = [ + "_lingli", + "_lingli_round", + "_lingli_draw", + "_lingli_save", + "_hhzz_qiankunbagua", + "_lingli_damage", + ]; + for (var i = 0; i < list.length; i++) { + game.addGlobalSkill(list[i]); + } + game.me.addSkillH(result.control); + game.countPlayer(function (current) { + if (!current.name) { + current.init(_status.characterlist.randomRemove(1)[0]); + current.addSkillH( + ["xiandeng", "shulv", "xisheng"].randomGet() + ); + } + current.storage._lingli = 0; + current.markSkill("_lingli"); + }); + game.showIdentity(true); + "step 3"; + game.randomMission(); + var list = [ + game.createCard("hhzz_fudichouxin"), + game.createCard("hhzz_toulianghuanzhu"), + game.createCard("hhzz_toulianghuanzhu"), + game.createCard("hhzz_toulianghuanzhu"), + ]; + for (var i = 0; i < list.length; i++) { + ui.cardPile.insertBefore( + list[i], + ui.cardPile.childNodes[ + get.rand(ui.cardPile.childElementCount) + ] + ); + } + game.updateRoundNumber(); + "step 4"; + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + _status.videoInited = true; + game.addVideo("arrangeLib", null, { + skill: { + _lingli_damage: {}, + _lingli: { + mark: true, + marktext: "灵", + popup: "聚灵", + intro: { + name: "灵力", + content: "当前灵力点数:# / 5", + }, + }, + _lingli_round: {}, + _lingli_draw: {}, + _lingli_save: {}, + hhzz_noCard: {}, + hhzz_huilei: { + skillAnimation: true, + }, + hhzz_youlian: { + skillAnimation: true, + }, + hhzz_zhencang: {}, + hhzz_huizhen: {}, + hhzz_jubao: {}, + }, + card: { + hhzz_toulianghuanzhu: { + cardimage: "toulianghuanzhu", + }, + hhzz_fudichouxin: { + cardimage: "fudichouxin", + }, + }, + character: { + hhzz_shiona: ["female", "key", 1, ["hhzz_huilei"]], + hhzz_kanade: ["female", "key", 2, ["hhzz_youlian"]], + hhzz_takaramono1: [ + "male", + "qun", + 5, + ["hhzz_jubao", "hhzz_huizhen"], + ], + hhzz_takaramono2: [ + "male", + "qun", + 3, + ["hhzz_jubao", "hhzz_zhencang"], + ], + }, + translate: { + _lingli: "聚灵", + _lingli_bg: "灵", + _lingli_draw: "聚灵", + hhzz_huilei: "挥泪", + hhzz_youlian: "犹怜", + hhzz_zhencang: "珍藏", + hhzz_huizhen: "汇珍", + hhzz_jubao: "聚宝", + hhzz_huilei_info: "锁定技,杀死你的角色弃置所有的牌。", + hhzz_youlian_info: + "锁定技,杀死你的角色弃置所有牌并随机失去一个技能。", + hhzz_zhencang_info: + "锁定技,杀死你的角色摸一张牌并随机获得一个技能(已满则先随机移除一个)。", + hhzz_huizhen_info: + "锁定技,杀死你的角色摸三张牌并随机获得一个技能(已满则先随机移除一个)。", + hhzz_jubao_info: + "锁定技,当你受到伤害的点数确定时,伤害来源随机获得你区域内的X张牌(X为伤害点数)。", + nei: " ", + nei2: " ", + hhzz_shiona: "汐奈", + hhzz_kanade: "立华奏", + hhzz_takaramono1: "坚实宝箱", + hhzz_takaramono2: "普通宝箱", + hhzz_toulianghuanzhu: "偷梁换柱", + hhzz_fudichouxin: "釜底抽薪", + hhzz_toulianghuanzhu_info: + "出牌阶段,对一名角色使用,随机更换其一个技能。可重铸。", + hhzz_fudichouxin_info: + "出牌阶段,对一名角色使用,随机弃置其一个技能。", + }, + }); + }); + }, + }, + }; + var func = function (pack) { + for (var i in pack.pack) { + for (var j in pack.pack[i]) lib[i][j] = pack.pack[i][j]; } - }, - eltc:{ - gameDraw:function(){ - var end=player; - var numx; - var num=function(player){ - return player._hSeat>5?5:4; - }; - do{ - if(typeof num=='function'){ - numx=num(player); - } - if(player._hSeat>6) player.changeLingli(1); - player.directgain(get.cards(numx)); - player=player.next; - } - while(player!=end); - }, - }, - eltp:{ - addSkillH:function(skill){ - this.skillH.add(skill); - this.addSkillLog.apply(this,arguments); - }, - removeSkillH:function(skill){ - this.skillH.remove(skill); - game.log(this,'失去了技能','#g【'+get.translation(skill)+'】'); - this.removeSkill(skill); - }, - dieAfter:function(){ - var evt=_status.event.getParent('phase'); - if(evt) evt._lastDead=this; - if(game.playerx().length==1) game.over(game.me.isAlive()); - }, - $dieAfter:function(){}, - hasUnknown:function(){return false}, - isUnknown:function(){return false}, - getEnemies:function(){ - var list=game.playerx(); - list.remove(this); - return list; - }, - dieAfter2:function(source){ - if(source&&this.name.indexOf('hhzz_')!=0){ - if(source._toKill==this) game.log(source,'击杀目标成功'); - source.draw(this==source._toKill?2:1); - source.changeLingli(this==source._toKill?3:2); - } - if(!_status._aozhan){ - var that=this; - game.countPlayer(function(current){ - if(current._toSave==that){ - game.log(current,'保护失败'); - var cards=current.getCards('he'); - if(cards.length) current.discard(cards.randomGets(4)); - } - }); - } - }, - logAi:function(){}, - changeLingli:function(num){ - if(typeof num!='number') num=1; - if(typeof this.storage._lingli!='number') this.storage._lingli=0; - if(num>0){ - num=Math.min(num,5-this.storage._lingli); - if(num<1) return; - game.log(this,'获得了','#y'+get.cnNumber(num)+'点','灵力'); - } - else{ - if(-num>this.storage._lingli) num=-this.storage._lingli; - if(num==0) return; - game.log(this,'失去了','#y'+get.cnNumber(-num)+'点','灵力'); - } - this.storage._lingli+=num; - this.markSkill('_lingli'); - }, - }, - game:{ - playerx:function(){ - return game.filterPlayer(function(current){ - if(current.name.indexOf('hhzz_')==0) return; - return true; - }); - }, - randomMission:function(){ - if(_status._aozhan) return; - if(!ui.huanhuazhizhan){ - ui.huanhuazhizhan=ui.create.div('.touchinfo.left',ui.window); - if(ui.time3) ui.time3.style.display='none'; - } - var players=game.playerx(); - for(var i=0;i
                        【'+get.translation(skills[i])+'】
                        '+lib.translate[skills[i]+'_info']+'
                        '); - } - dialog.addText('
                        '); - return dialog; - }, - chooseCharacter:function(){ - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - 'step 0' - game.zhu=game.players.randomGet(); - var i=1; - var current=game.zhu; - while(true){ - current.skillH=[]; - current._hSeat=i; - current.identity='nei'; - current.setNickname(get.cnNumber(i,true)+'号位'); - for(var ii in lib.huanhuazhizhan.eltp) current[ii]=lib.huanhuazhizhan.eltp[ii]; - current=current.next; - i++; - if(current==game.zhu) break; - } - ui.arena.classList.add('choose-character'); - game.me.chooseButton(['请选择角色形象',[_status.characterlist.randomRemove(5),'character']],true).onfree=true; - 'step 1' - game.me.init(result.links[0]); - var list=['xiandeng','shulv','xisheng']; - game.me.chooseControl(list).dialog=game.getSkillDialog(list,'选择要获得的初始技能'); - 'step 2' - var list=['_lingli','_lingli_round','_lingli_draw','_lingli_save','_hhzz_qiankunbagua','_lingli_damage']; - for(var i=0;i7){ - setTimeout(function(){ - while(node.nodes.length>5){ + card.style.opacity = 1; + card.style.transform = "scale(1) rotate(" + rand3 + "deg)"; + if (node.nodes.length > 7) { + setTimeout(function () { + while (node.nodes.length > 5) { node.nodes.shift().delete(); } - },500); + }, 500); } }; - if(init){ - node.nodes=[]; - for(var i=0;i<5;i++){ + if (init) { + node.nodes = []; + for (var i = 0; i < 5; i++) { func(); } } - node.showcaseinterval=setInterval(func,1000); + node.showcaseinterval = setInterval(func, 1000); }, - content:{ - cardPile:function(list){ - game.identityVideoName='毒战三国杀'; - lib.config.bannedcards.remove('du'); - if(game.bannedcards) game.bannedcards.remove('du'); - var num=Math.ceil(list.length/10); - while(num--){ - list.push([['heart','diamond','club','spade'].randomGet(),Math.ceil(Math.random()*13),'du']); + content: { + cardPile: function (list) { + game.identityVideoName = "毒战三国杀"; + lib.config.bannedcards.remove("du"); + if (game.bannedcards) game.bannedcards.remove("du"); + var num = Math.ceil(list.length / 10); + while (num--) { + list.push([ + ["heart", "diamond", "club", "spade"].randomGet(), + Math.ceil(Math.random() * 13), + "du", + ]); } return list; - } + }, }, }, - daozhiyueying:{ - name:'导师月英', - mode:'identity', - intro:'牌堆中所有普通锦囊牌数量翻倍;移除拥有集智技能的角色', - showcase:function(init){ - var node=this; - var player1,player2; - if(init){ - player1=ui.create.player(null,true).init('huangyueying'); - player2=ui.create.player(null,true); - if(lib.character.jsp_huangyueying){ - player2.init('jsp_huangyueying'); + daozhiyueying: { + name: "导师月英", + mode: "identity", + intro: "牌堆中所有普通锦囊牌数量翻倍;移除拥有集智技能的角色", + showcase: function (init) { + var node = this; + var player1, player2; + if (init) { + player1 = ui.create.player(null, true).init("huangyueying"); + player2 = ui.create.player(null, true); + if (lib.character.jsp_huangyueying) { + player2.init("jsp_huangyueying"); + } else if (lib.character.re_huangyueying) { + player2.init("re_huangyueying"); + } else { + player2.init("huangyueying"); } - else if(lib.character.re_huangyueying){ - player2.init('re_huangyueying'); - } - else{ - player2.init('huangyueying'); - } - player1.style.left='20px'; - player1.style.top='20px'; - player1.style.transform='scale(0.9)'; - player1.node.count.innerHTML='2'; - player1.node.count.dataset.condition='mid'; - player2.style.left='auto'; - player2.style.right='20px'; - player2.style.top='20px'; - player2.style.transform='scale(0.9)'; - player2.node.count.innerHTML='2'; - player2.node.count.dataset.condition='mid'; + player1.style.left = "20px"; + player1.style.top = "20px"; + player1.style.transform = "scale(0.9)"; + player1.node.count.innerHTML = "2"; + player1.node.count.dataset.condition = "mid"; + player2.style.left = "auto"; + player2.style.right = "20px"; + player2.style.top = "20px"; + player2.style.transform = "scale(0.9)"; + player2.node.count.innerHTML = "2"; + player2.node.count.dataset.condition = "mid"; this.appendChild(player1); this.appendChild(player2); - this.player1=player1; - this.player2=player2; - } - else{ - player1=this.player1; - player2=this.player2; + this.player1 = player1; + this.player2 = player2; + } else { + player1 = this.player1; + player2 = this.player2; } - var createCard=function(wuxie){ + var createCard = function (wuxie) { var card; - if(wuxie){ - card=game.createCard('wuxie','noclick'); - card.style.transform='scale(0.9)'; + if (wuxie) { + card = game.createCard("wuxie", "noclick"); + card.style.transform = "scale(0.9)"; + } else { + card = ui.create.card(null, "noclick", true); } - else{ - card=ui.create.card(null,'noclick',true); - } - card.style.opacity=0; - card.style.position='absolute'; - card.style.zIndex=2; - card.style.margin=0; + card.style.opacity = 0; + card.style.position = "absolute"; + card.style.zIndex = 2; + card.style.margin = 0; return card; - } + }; - var func=function(){ - game.linexy([ - player1.getLeft()+player1.offsetWidth/2, - player1.getTop()+player1.offsetHeight/2, - player2.getLeft()+player2.offsetWidth/2, - player2.getTop()+player2.offsetHeight/2, - ],node); - var card=createCard(true); - card.style.left='43px'; - card.style.top='58px'; + var func = function () { + game.linexy( + [ + player1.getLeft() + player1.offsetWidth / 2, + player1.getTop() + player1.offsetHeight / 2, + player2.getLeft() + player2.offsetWidth / 2, + player2.getTop() + player2.offsetHeight / 2, + ], + node + ); + var card = createCard(true); + card.style.left = "43px"; + card.style.top = "58px"; node.appendChild(card); ui.refresh(card); - card.style.opacity=1; - card.style.transform='scale(0.9) translate(137px,152px)'; - setTimeout(function(){ + card.style.opacity = 1; + card.style.transform = "scale(0.9) translate(137px,152px)"; + setTimeout(function () { card.delete(); - },1000); - player1.node.count.innerHTML='1'; + }, 1000); + player1.node.count.innerHTML = "1"; - setTimeout(function(){ - if(!node.showcaseinterval) return; - player1.node.count.innerHTML='2'; - var card=createCard(); - card.style.left='43px'; - card.style.top='58px'; - card.style.transform='scale(0.9) translate(137px,152px)'; + setTimeout(function () { + if (!node.showcaseinterval) return; + player1.node.count.innerHTML = "2"; + var card = createCard(); + card.style.left = "43px"; + card.style.top = "58px"; + card.style.transform = "scale(0.9) translate(137px,152px)"; node.appendChild(card); ui.refresh(card); - card.style.opacity=1; - card.style.transform='scale(0.9)'; - setTimeout(function(){ + card.style.opacity = 1; + card.style.transform = "scale(0.9)"; + setTimeout(function () { card.delete(); - },1000); - },300); + }, 1000); + }, 300); - setTimeout(function(){ - if(!node.showcaseinterval) return; - player2.node.count.innerHTML='1'; - game.linexy([ - player2.getLeft()+player2.offsetWidth/2, - player2.getTop()+player2.offsetHeight/2, - player1.getLeft()+player1.offsetWidth/2, - player1.getTop()+player1.offsetHeight/2, - ],node); - var card=createCard(true); - card.style.left='auto'; - card.style.right='43px'; - card.style.top='58px'; + setTimeout(function () { + if (!node.showcaseinterval) return; + player2.node.count.innerHTML = "1"; + game.linexy( + [ + player2.getLeft() + player2.offsetWidth / 2, + player2.getTop() + player2.offsetHeight / 2, + player1.getLeft() + player1.offsetWidth / 2, + player1.getTop() + player1.offsetHeight / 2, + ], + node + ); + var card = createCard(true); + card.style.left = "auto"; + card.style.right = "43px"; + card.style.top = "58px"; node.appendChild(card); ui.refresh(card); - card.style.opacity=1; - card.style.transform='scale(0.9) translate(-137px,152px)'; - setTimeout(function(){ + card.style.opacity = 1; + card.style.transform = "scale(0.9) translate(-137px,152px)"; + setTimeout(function () { card.delete(); - },700); + }, 700); - setTimeout(function(){ - if(!node.showcaseinterval) return; - player2.node.count.innerHTML='2'; - var card=createCard(); - card.style.left='auto'; - card.style.right='43px'; - card.style.top='58px'; - card.style.transform='scale(0.9) translate(-137px,152px)'; + setTimeout(function () { + if (!node.showcaseinterval) return; + player2.node.count.innerHTML = "2"; + var card = createCard(); + card.style.left = "auto"; + card.style.right = "43px"; + card.style.top = "58px"; + card.style.transform = "scale(0.9) translate(-137px,152px)"; node.appendChild(card); ui.refresh(card); - card.style.opacity=1; - card.style.transform='scale(0.9)'; - setTimeout(function(){ + card.style.opacity = 1; + card.style.transform = "scale(0.9)"; + setTimeout(function () { card.delete(); - },700); - },300); - },1000); + }, 700); + }, 300); + }, 1000); }; - node.showcaseinterval=setInterval(func,2200); + node.showcaseinterval = setInterval(func, 2200); func(); }, - init:function(){ - for(var i in lib.character){ - var skills=lib.character[i][3] - if(skills.includes('jizhi')||skills.includes('rejizhi')||skills.includes('lingzhou')||skills.includes('sbaiyin')){ + init: function () { + for (var i in lib.character) { + var skills = lib.character[i][3]; + if ( + skills.includes("jizhi") || + skills.includes("rejizhi") || + skills.includes("lingzhou") || + skills.includes("sbaiyin") + ) { delete lib.character[i]; } } }, - content:{ - cardPile:function(list){ - game.identityVideoName='导师月英'; - var list2=[]; - for(var i=0;i=5){ - num=0; + if (num >= 5) { + num = 0; } - },700); + }, 700); }, - init:function(){ - game.identityVideoName='唯我独尊'; - lib.skill.weiwoduzun={ - mark:true, - intro:{ - content:'杀造成的伤害+1' + init: function () { + game.identityVideoName = "唯我独尊"; + lib.skill.weiwoduzun = { + mark: true, + intro: { + content: "杀造成的伤害+1", }, - group:['weiwoduzun_damage','weiwoduzun_lose'], - subSkill:{ - damage:{ - trigger:{source:'damageBegin'}, - forced:true, - filter:function(event){ - return event.card&&event.card.name=='sha'&&event.notLink(); + group: ["weiwoduzun_damage", "weiwoduzun_lose"], + subSkill: { + damage: { + trigger: { source: "damageBegin" }, + forced: true, + filter: function (event) { + return event.card && event.card.name == "sha" && event.notLink(); }, - content:function(){ + content: function () { trigger.num++; - } - }, - lose:{ - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event){ - return event.source&&event.source.isAlive(); }, - content:function(){ - player.removeSkill('weiwoduzun'); - trigger.source.addSkill('weiwoduzun'); - } - } - } + }, + lose: { + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event) { + return event.source && event.source.isAlive(); + }, + content: function () { + player.removeSkill("weiwoduzun"); + trigger.source.addSkill("weiwoduzun"); + }, + }, + }, }; - lib.translate.weiwoduzun='战神'; - lib.translate.weiwoduzun_bg='尊'; + lib.translate.weiwoduzun = "战神"; + lib.translate.weiwoduzun_bg = "尊"; }, - content:{ - cardPile:function(list){ - var num=0; - for(var i=0;i4){ - setTimeout(function(){ - while(node.nodes.length>3){ + card.style.transform = "scale(0.9) rotate(" + rand3 + "deg)"; + card.style.opacity = 1; + if (node.nodes.length > 4) { + setTimeout(function () { + while (node.nodes.length > 3) { node.nodes.shift().delete(); } - },500); + }, 500); } }; - node.list=[]; - if(init){ - node.nodes=[]; - for(var i=0;i<3;i++){ + node.list = []; + if (init) { + node.nodes = []; + for (var i = 0; i < 3; i++) { func(); } } - node.showcaseinterval=setInterval(func,1000); + node.showcaseinterval = setInterval(func, 1000); }, - init:function(){ - var map={}; - var map3=[]; - var list1=['司','夏','诸','皇']; - var list2=['马','侯','葛','甫']; - for(var i in lib.character){ - if(lib.filter.characterDisabled(i)) continue; - if(lib.character[i][1]=='key') continue; - var surname=get.rawName2(i); - for(var j=0;j7){ - nodes[i].index=0; + if (nodes[i].index > 7) { + nodes[i].index = 0; } setPos(nodes[i]); } - },1000); + }, 1000); }, - content:{ - gameStart:function(){ - game.identityVideoName='同将模式'; - var target=(_status.mode=='zhong')?game.zhong:game.zhu; - if(get.config('double_character')){ - target.init(game.me.name1,game.me.name2); - } - else{ + content: { + gameStart: function () { + game.identityVideoName = "同将模式"; + var target = _status.mode == "zhong" ? game.zhong : game.zhu; + if (get.config("double_character")) { + target.init(game.me.name1, game.me.name2); + } else { target.init(game.me.name1); } target.hp++; target.maxHp++; target.update(); - if(get.config('choose_group')){ - var list=lib.group.slice(0); - list.remove('shen'); - game.players.forEach(i=>{ - if(i.group=='shen'&&i!=game.me){ - var group=list.randomGet(); - i.group=group; - i.node.name.dataset.nature=get.groupnature(group); + if (get.config("choose_group")) { + var list = lib.group.slice(0); + list.remove("shen"); + game.players.forEach((i) => { + if (i.group == "shen" && i != game.me) { + var group = list.randomGet(); + i.group = group; + i.node.name.dataset.nature = get.groupnature(group); i.update(); } }); } }, - chooseCharacterAi:function(player,list,list2,back){ - if(player==game.zhu){ + chooseCharacterAi: function (player, list, list2, back) { + if (player == game.zhu) { return; - } - else{ - if(get.config('double_character')){ - player.init(game.me.name1,game.me.name2); - } - else{ + } else { + if (get.config("double_character")) { + player.init(game.me.name1, game.me.name2); + } else { player.init(game.me.name1); } } }, - chooseCharacter:function(list,list2,num){ - if(game.me!=game.zhu){ - return list.slice(0,list2); - } - else{ - if(_status.event.zhongmode){ - return list.slice(0,6); - } - else{ - return list.concat(list2.slice(0,num)); + chooseCharacter: function (list, list2, num) { + if (game.me != game.zhu) { + return list.slice(0, list2); + } else { + if (_status.event.zhongmode) { + return list.slice(0, 6); + } else { + return list.concat(list2.slice(0, num)); } } }, - chooseCharacterBefore:function(){ - if(_status.mode=='purple') _status.mode='normal'; + chooseCharacterBefore: function () { + if (_status.mode == "purple") _status.mode = "normal"; }, - } + }, }, - jiazuzhizheng:{ - name:'家族之争', - mode:'versus', - submode:'2v2', - intro:'势力相同的武将组合一队,获得专属势力技能', - showcase:function(init){ - var node=this; - var getList=function(){ - var list=[ - ['liubei','guanyu','zhangfei'], - ['caocao','guojia','xunyu'], - ['sunquan','zhangzhang','zhouyu'], - ['re_yuanshao','guotufengji','yj_jushou'], - ['jin_simayi','jin_simazhao','jin_wangyuanji'], + jiazuzhizheng: { + name: "家族之争", + mode: "versus", + submode: "2v2", + intro: "势力相同的武将组合一队,获得专属势力技能", + showcase: function (init) { + var node = this; + var getList = function () { + var list = [ + ["liubei", "guanyu", "zhangfei"], + ["caocao", "guojia", "xunyu"], + ["sunquan", "zhangzhang", "zhouyu"], + ["re_yuanshao", "guotufengji", "yj_jushou"], + ["jin_simayi", "jin_simazhao", "jin_wangyuanji"], ]; - if(_status.keyVerified) list.push(['key_yuri','key_yuzuru','sp_key_kanade']) + if (_status.keyVerified) list.push(["key_yuri", "key_yuzuru", "sp_key_kanade"]); list.randomSort(); - var list2=[]; - for(var i=0;i4){ - setTimeout(function(){ - while(node.nodes.length>3){ + card.style.transform = "scale(0.9) rotate(" + rand3 + "deg)"; + card.style.opacity = 1; + if (node.nodes.length > 4) { + setTimeout(function () { + while (node.nodes.length > 3) { node.nodes.shift().delete(); } - },500); + }, 500); } }; - node.list=[]; - if(init){ - node.nodes=[]; - for(var i=0;i<3;i++){ + node.list = []; + if (init) { + node.nodes = []; + for (var i = 0; i < 3; i++) { func(); } } - node.showcaseinterval=setInterval(func,1000); + node.showcaseinterval = setInterval(func, 1000); }, - init:function(){}, - content:{ - submode:'two', - chooseCharacterFixed:true, - chooseCharacterBefore:function(){ - _status.noReplaceCharacter=true; - game.versusVideoName='家族之争'; - var map={ - wei:[], - shu:[], - wu:[], - qun:[], - jin:[], - key:[], + init: function () {}, + content: { + submode: "two", + chooseCharacterFixed: true, + chooseCharacterBefore: function () { + _status.noReplaceCharacter = true; + game.versusVideoName = "家族之争"; + var map = { + wei: [], + shu: [], + wu: [], + qun: [], + jin: [], + key: [], }; - var map3=[]; - var banned=['zuoci','re_zuoci','tw_xiahouba']; - for(var i in lib.character){ - if(lib.filter.characterDisabled2(i)||lib.filter.characterDisabled(i)||banned.includes(i)) continue; - var group=lib.character[i][1]; - if(group&&map[group]) map[group].push(i); + var map3 = []; + var banned = ["zuoci", "re_zuoci", "tw_xiahouba"]; + for (var i in lib.character) { + if ( + lib.filter.characterDisabled2(i) || + lib.filter.characterDisabled(i) || + banned.includes(i) + ) + continue; + var group = lib.character[i][1]; + if (group && map[group]) map[group].push(i); } - for(var i in map){ - if(map[i].length<8||(i=='key'&&!_status.keyVerified)){ + for (var i in map) { + if (map[i].length < 8 || (i == "key" && !_status.keyVerified)) { delete map[i]; - } - else{ + } else { map3.push(i); } } - _status.brawl.map=map; - _status.brawl.map3=map3; - var skill={ - _jiazu_wei:{ - trigger:{player:'phaseBegin'}, - direct:true, - popup:'魏业', - prompt2:'回合开始时,你可以弃置一张牌并指定一名敌方角色,该角色须弃置一张牌,否则你摸一张牌。', - filter:function(event,player){ - return player.group=='wei'&&player.countCards('he')>0; + _status.brawl.map = map; + _status.brawl.map3 = map3; + var skill = { + _jiazu_wei: { + trigger: { player: "phaseBegin" }, + direct: true, + popup: "魏业", + prompt2: + "回合开始时,你可以弃置一张牌并指定一名敌方角色,该角色须弃置一张牌,否则你摸一张牌。", + filter: function (event, player) { + return player.group == "wei" && player.countCards("he") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseCardTarget({ - prompt:get.prompt2(event.name), - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ - return player.side!=target.side; + prompt: get.prompt2(event.name), + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { + return player.side != target.side; }, - position:'he', - ai1:function(card){ - return 6-get.value(card); + position: "he", + ai1: function (card) { + return 6 - get.value(card); }, - ai2:function(target){ - return 1/(1+target.countCards('he')); + ai2: function (target) { + return 1 / (1 + target.countCards("he")); }, }); - 'step 1' - if(result.bool){ - player.logSkill(event.name,result.targets); + "step 1"; + if (result.bool) { + player.logSkill(event.name, result.targets); player.discard(result.cards); - result.targets[0].chooseToDiscard('弃置一张牌,或令'+get.translation(player)+'摸一张牌','he').ai=lib.skill.zhiheng.check; - } - else event.finish(); - 'step 2' - if(!result.bool) player.draw(); + result.targets[0].chooseToDiscard( + "弃置一张牌,或令" + get.translation(player) + "摸一张牌", + "he" + ).ai = lib.skill.zhiheng.check; + } else event.finish(); + "step 2"; + if (!result.bool) player.draw(); }, }, - _jiazu_shu:{ - popup:'蜀义', - prompt2:'你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。', - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha'&&player.group=='shu') return num+1; + _jiazu_shu: { + popup: "蜀义", + prompt2: + "你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。", + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha" && player.group == "shu") return num + 1; }, }, - trigger:{player:'phaseUseEnd'}, - forced:true, - filter:function(event,player){ - return player.group=='shu'&&player.getHistory('useCard',function(evt){ - return evt.card&&evt.card.name=='sha'&&evt.getParent('phaseUse')==event; - }).length>1; + trigger: { player: "phaseUseEnd" }, + forced: true, + filter: function (event, player) { + return ( + player.group == "shu" && + player.getHistory("useCard", function (evt) { + return ( + evt.card && + evt.card.name == "sha" && + evt.getParent("phaseUse") == event + ); + }).length > 1 + ); }, - content:function(){player.draw()}, - }, - _jiazu_wu:{ - trigger:{player:'phaseEnd'}, - forced:true, - popup:'吴耀', - prompt2:'回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。', - filter:function(event,player){ - return player.group=='wu'&&player.countCards('h')!=player.hp; - }, - content:function(){player.draw()}, - }, - _jiazu_qun:{ - popup:'群心', - prompt2:'锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1', - trigger:{player:'phaseDiscardBegin'}, - forced:true, - filter:function(event,player){ - return player.group=='qun'&&(player.isDamaged()||player.countCards('h')-player.hp>1); - }, - content:function(){ - var num=0; - if(player.isDamaged()) num++; - if(player.countCards('h')-player.hp>1) num++; - player.addMark('qunxin_temp',num,false); - player.addTempSkill('qunxin_temp','phaseDiscardEnd'); - }, - }, - _jiazu_jin:{ - trigger:{player:'phaseDrawEnd'}, - popup:'晋势', - prompt2:'摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。', - filter:function(event,player){ - var hs=player.getCards('h'); - return player.group=='jin'&&hs.length>0&&player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=event) return false; - for(var i of evt.cards){ - if(hs.includes(i)) return true; - } - return false; - }).length>0; - }, - check:function(event,player){ - var hs=player.getCards('h'),cards=[],suits=[]; - player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=event) return false; - for(var i of evt.cards){ - if(hs.includes(i)){ - cards.add(i); - suits.add(get.suit(i,player)); - } - } - }); - return cards.length==suits.length; - }, - content:function(){ - var hs=player.getCards('h'),cards=[],suits=[]; - player.getHistory('gain',function(evt){ - if(evt.getParent().name!='draw'||evt.getParent('phaseDraw')!=trigger) return false; - for(var i of evt.cards){ - if(hs.includes(i)){ - cards.add(i); - suits.add(get.suit(i,player)); - } - } - }); - player.showCards(cards,get.translation(player)+'发动了【晋势】'); - if(cards.length==suits.length) player.draw(); - }, - }, - _jiazu_key:{ - enable:'phaseUse', - usable:1, - popup:'键魂', - filter:function(event,player){ - return player.group=='key'; - }, - prompt2:'出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。', - content:function(){ - "step 0" + content: function () { player.draw(); - "step 1" + }, + }, + _jiazu_wu: { + trigger: { player: "phaseEnd" }, + forced: true, + popup: "吴耀", + prompt2: "回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。", + filter: function (event, player) { + return player.group == "wu" && player.countCards("h") != player.hp; + }, + content: function () { + player.draw(); + }, + }, + _jiazu_qun: { + popup: "群心", + prompt2: + "锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1", + trigger: { player: "phaseDiscardBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.group == "qun" && + (player.isDamaged() || player.countCards("h") - player.hp > 1) + ); + }, + content: function () { + var num = 0; + if (player.isDamaged()) num++; + if (player.countCards("h") - player.hp > 1) num++; + player.addMark("qunxin_temp", num, false); + player.addTempSkill("qunxin_temp", "phaseDiscardEnd"); + }, + }, + _jiazu_jin: { + trigger: { player: "phaseDrawEnd" }, + popup: "晋势", + prompt2: + "摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。", + filter: function (event, player) { + var hs = player.getCards("h"); + return ( + player.group == "jin" && + hs.length > 0 && + player.getHistory("gain", function (evt) { + if ( + evt.getParent().name != "draw" || + evt.getParent("phaseDraw") != event + ) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) return true; + } + return false; + }).length > 0 + ); + }, + check: function (event, player) { + var hs = player.getCards("h"), + cards = [], + suits = []; + player.getHistory("gain", function (evt) { + if ( + evt.getParent().name != "draw" || + evt.getParent("phaseDraw") != event + ) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) { + cards.add(i); + suits.add(get.suit(i, player)); + } + } + }); + return cards.length == suits.length; + }, + content: function () { + var hs = player.getCards("h"), + cards = [], + suits = []; + player.getHistory("gain", function (evt) { + if ( + evt.getParent().name != "draw" || + evt.getParent("phaseDraw") != trigger + ) + return false; + for (var i of evt.cards) { + if (hs.includes(i)) { + cards.add(i); + suits.add(get.suit(i, player)); + } + } + }); + player.showCards(cards, get.translation(player) + "发动了【晋势】"); + if (cards.length == suits.length) player.draw(); + }, + }, + _jiazu_key: { + enable: "phaseUse", + usable: 1, + popup: "键魂", + filter: function (event, player) { + return player.group == "key"; + }, + prompt2: + "出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。", + content: function () { + "step 0"; + player.draw(); + "step 1"; player.changeHujia(1); - "step 2" - var evt=event.getParent('phase'); - if(evt&&evt.after){ - var next=player.loseHp(); + "step 2"; + var evt = event.getParent("phase"); + if (evt && evt.after) { + var next = player.loseHp(); event.next.remove(next); evt.after.push(next); } }, - ai:{ - order:10, - result:{ - player:function(player){ - return player.hp-1; + ai: { + order: 10, + result: { + player: function (player) { + return player.hp - 1; }, }, }, }, - qunxin_temp:{ - noGlobal:true, - onremove:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('qunxin_temp'); + qunxin_temp: { + noGlobal: true, + onremove: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("qunxin_temp"); }, }, }, - _jiazu_awaken_wei:{ - popup:'许昌', - intro:{ - content:'锁定技,当你受到伤害后,你摸一张牌。', + _jiazu_awaken_wei: { + popup: "许昌", + intro: { + content: "锁定技,当你受到伤害后,你摸一张牌。", }, - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player._jiazuAwaken&&player.group=='wei'; + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return player._jiazuAwaken && player.group == "wei"; + }, + content: function () { + player.draw(); }, - content:function(){player.draw()}, }, - _jiazu_awaken_shu:{ - popup:'成都', - intro:{ - content:'锁定技,当你使用【杀】造成伤害后,你摸一张牌。', + _jiazu_awaken_shu: { + popup: "成都", + intro: { + content: "锁定技,当你使用【杀】造成伤害后,你摸一张牌。", }, - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player._jiazuAwaken&&player.group=='shu'&&event.card&&event.card.name=='sha'; + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + player._jiazuAwaken && + player.group == "shu" && + event.card && + event.card.name == "sha" + ); + }, + content: function () { + player.draw(); }, - content:function(){player.draw()}, }, - _jiazu_awaken_wu:{ - popup:'武昌', - intro:{ - content:'锁定技,当你使用装备牌时,你摸一张牌。', + _jiazu_awaken_wu: { + popup: "武昌", + intro: { + content: "锁定技,当你使用装备牌时,你摸一张牌。", }, - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return player._jiazuAwaken&&player.group=='wu'&&get.type(event.card)=='equip'; + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return ( + player._jiazuAwaken && + player.group == "wu" && + get.type(event.card) == "equip" + ); + }, + content: function () { + player.draw(); }, - content:function(){player.draw()}, }, - _jiazu_awaken_qun:{ - popup:'邺城', - intro:{ - content:'锁定技,当你使用锦囊牌指定其他角色为目标后,你摸一张牌。', + _jiazu_awaken_qun: { + popup: "邺城", + intro: { + content: "锁定技,当你使用锦囊牌指定其他角色为目标后,你摸一张牌。", }, - trigger:{player:'useCardToPlayered'}, - forced:true, - filter:function(event,player){ - if(!player._jiazuAwaken||player.group!='qun'||!event.isFirstTarget||get.type(event.card,'trick')!='trick') return false; - for(var i=0;i2) return false; + trigger: { player: ["loseHpEnd", "recoverEnd"] }, + forced: true, + filter: function (event, player) { + return player._jiazuAwaken && player.group == "key"; + }, + content: function () { + player.draw(); + }, + }, + _jiazu_awaken_jin: { + popup: "洛阳", + intro: { + content: "锁定技,结束阶段,若你手牌中的花色数小于3,则你摸一张牌。", + }, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + if (!player._jiazuAwaken || player.group != "jin") return false; + var hs = player.getCards("h"), + suits = []; + if (hs.length < 3) return true; + for (var i of hs) { + suits.add(get.suit(i, player)); + if (suits.length > 2) return false; } return true; }, - content:function(){ + content: function () { player.draw(); }, }, - _jiazu_awaken:{ - trigger:{global:'die'}, - forced:true, - filter:function(event,player){ - return !player._jiazuAwaken&&event.player.side==player.side; + _jiazu_awaken: { + trigger: { global: "die" }, + forced: true, + filter: function (event, player) { + return !player._jiazuAwaken && event.player.side == player.side; }, - content:function(){ - player._jiazuAwaken=true; - var name='_jiazu_awaken_'+player.group; - if(lib.skill[name]) player.markSkill(name); + content: function () { + player._jiazuAwaken = true; + var name = "_jiazu_awaken_" + player.group; + if (lib.skill[name]) player.markSkill(name); }, }, }; - var translate={}; - for(var i in skill){ - lib.skill[i]=skill[i]; - if(skill[i].popup){ - lib.translate[i]=skill[i].popup; - translate[i]=skill[i].popup; + var translate = {}; + for (var i in skill) { + lib.skill[i] = skill[i]; + if (skill[i].popup) { + lib.translate[i] = skill[i].popup; + translate[i] = skill[i].popup; } - if(skill[i].prompt2){ - lib.translate[i+'_info']=skill[i].prompt2; - translate[i+'_info']=skill[i].prompt2; + if (skill[i].prompt2) { + lib.translate[i + "_info"] = skill[i].prompt2; + translate[i + "_info"] = skill[i].prompt2; } - if(!skill[i].noGlobal) game.addGlobalSkill(i); + if (!skill[i].noGlobal) game.addGlobalSkill(i); } - game.addVideo('arrangeLib',null,{ - skill:{ - _jiazu_wei:{ - popup:'魏业', - prompt2:'回合开始时,你可以弃置一张牌并指定一名敌方角色,该角色须弃置一张牌,否则你摸一张牌。', - }, - _jiazu_shu:{ - popup:'蜀义', - prompt2:'你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。', - }, - _jiazu_wu:{ - popup:'吴耀', - prompt2:'回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。', - }, - _jiazu_qun:{ - popup:'群心', - prompt2:'锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1', - }, - _jiazu_jin:{ - popup:'晋势', - prompt2:'摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。', + game.addVideo("arrangeLib", null, { + skill: { + _jiazu_wei: { + popup: "魏业", + prompt2: + "回合开始时,你可以弃置一张牌并指定一名敌方角色,该角色须弃置一张牌,否则你摸一张牌。", }, - _jiazu_key:{ - popup:'键魂', - prompt2:'出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。', - }, - _jiazu_awaken_wei:{ - popup:'许昌', - intro:{ - content:'锁定技,当你受到伤害后,你摸一张牌。', + _jiazu_shu: { + popup: "蜀义", + prompt2: + "你使用【杀】上限+1;出牌阶段结束时,若你于此阶段使用【杀】次数不少于2,摸一张牌。", }, - }, - _jiazu_awaken_shu:{ - popup:'成都', - intro:{ - content:'锁定技,当你使用【杀】造成伤害后,你摸一张牌。', + _jiazu_wu: { + popup: "吴耀", + prompt2: "回合结束时,若你的手牌数不等于你的体力值,则你摸一张牌。", }, - }, - _jiazu_awaken_wu:{ - popup:'武昌', - intro:{ - content:'锁定技,当你使用装备牌时,你摸一张牌。', + _jiazu_qun: { + popup: "群心", + prompt2: + "锁定技,弃牌阶段开始时,若你的手牌数比体力值多2或更多,你本回合手牌上限+1;若你已损失体力值大于1,你手牌上限+1", }, - }, - _jiazu_awaken_qun:{ - popup:'邺城', - intro:{ - content:'锁定技,当你使用锦囊牌指定其他角色为目标后,你摸一张牌。', + _jiazu_jin: { + popup: "晋势", + prompt2: + "摸牌阶段结束时,你可以展示你于此阶段内因摸牌而得到的牌。若这些牌的花色均不同,则你摸一张牌。", }, - }, - _jiazu_awaken_jin:{ - popup:'洛阳', - intro:{ - content:'锁定技,结束阶段,若你手牌中的花色数小于3,则你摸一张牌。', + _jiazu_key: { + popup: "键魂", + prompt2: + "出牌阶段限一次,你可以摸一张牌并获得1点护甲。若如此做,你于当前回合结束时失去1点体力。", + }, + _jiazu_awaken_wei: { + popup: "许昌", + intro: { + content: "锁定技,当你受到伤害后,你摸一张牌。", }, }, - _jiazu_awaken_key:{ - popup:'光坂', - intro:{ - content:'锁定技,当你回复/失去体力后,你摸一张牌。', + _jiazu_awaken_shu: { + popup: "成都", + intro: { + content: "锁定技,当你使用【杀】造成伤害后,你摸一张牌。", + }, }, + _jiazu_awaken_wu: { + popup: "武昌", + intro: { + content: "锁定技,当你使用装备牌时,你摸一张牌。", + }, + }, + _jiazu_awaken_qun: { + popup: "邺城", + intro: { + content: "锁定技,当你使用锦囊牌指定其他角色为目标后,你摸一张牌。", + }, + }, + _jiazu_awaken_jin: { + popup: "洛阳", + intro: { + content: "锁定技,结束阶段,若你手牌中的花色数小于3,则你摸一张牌。", + }, + }, + _jiazu_awaken_key: { + popup: "光坂", + intro: { + content: "锁定技,当你回复/失去体力后,你摸一张牌。", + }, + }, + _jiazu_awaken: {}, }, - _jiazu_awaken:{}, - }, - translate:translate, + translate: translate, }); }, - chooseCharacter:function(list,player){ - if(player.side==game.me.side){ - if(_status.brawl.mylist){ - return _status.brawl.mylist.randomGets(player==game.me?5:3); + chooseCharacter: function (list, player) { + if (player.side == game.me.side) { + if (_status.brawl.mylist) { + return _status.brawl.mylist.randomGets(player == game.me ? 5 : 3); + } + } else { + if (_status.brawl.enemylist) { + return _status.brawl.enemylist.randomGets(player == game.me ? 5 : 3); } } - else{ - if(_status.brawl.enemylist){ - return _status.brawl.enemylist.randomGets(player==game.me?5:3); - } + var surname = _status.brawl.map3.randomRemove(); + var list = _status.brawl.map[surname]; + if (player == game.me) { + _status.brawl.mylist = list; + } else { + _status.brawl.enemylist = list; } - var surname=_status.brawl.map3.randomRemove(); - var list=_status.brawl.map[surname]; - if(player==game.me){ - _status.brawl.mylist=list; - } - else{ - _status.brawl.enemylist=list; - } - return list.randomRemove(player==game.me?5:3); - } - } + return list.randomRemove(player == game.me ? 5 : 3); + }, + }, }, - baiyidujiang:{ - name:'白衣渡江', - mode:'versus', - submode:'2v2', - showcase:function(init){ - var node=this; - var player1,player2; - if(init){ - player1=ui.create.player(null,true); - player1.classList.add('fullskin'); + baiyidujiang: { + name: "白衣渡江", + mode: "versus", + submode: "2v2", + showcase: function (init) { + var node = this; + var player1, player2; + if (init) { + player1 = ui.create.player(null, true); + player1.classList.add("fullskin"); player1.node.avatar.show(); - player1.node.avatar.setBackground('lvmeng','character'); - player2=ui.create.player(null,true) - player2.classList.add('fullskin'); + player1.node.avatar.setBackground("lvmeng", "character"); + player2 = ui.create.player(null, true); + player2.classList.add("fullskin"); player2.node.avatar.show(); - player2.node.avatar.setBackground('guanyu','character'); + player2.node.avatar.setBackground("guanyu", "character"); player1.node.marks.remove(); player1.node.hp.remove(); player2.node.marks.remove(); player2.node.hp.remove(); - player1.style.left='20px'; - player1.style.top='20px'; - player1.style.transform='scale(0.9)'; + player1.style.left = "20px"; + player1.style.top = "20px"; + player1.style.transform = "scale(0.9)"; player1.node.count.remove(); - player2.style.left='auto'; - player2.style.right='20px'; - player2.style.top='20px'; - player2.style.transform='scale(0.9)'; + player2.style.left = "auto"; + player2.style.right = "20px"; + player2.style.top = "20px"; + player2.style.transform = "scale(0.9)"; player2.node.count.remove(); this.appendChild(player1); this.appendChild(player2); - this.player1=player1; - this.player2=player2; + this.player1 = player1; + this.player2 = player2; + } else { + player1 = this.player1; + player2 = this.player2; } - else{ - player1=this.player1; - player2=this.player2; - } - var func=function(){ - setTimeout(function(){ + var func = function () { + setTimeout(function () { player1.smoothAvatar(); player2.smoothAvatar(); - player1.node.avatar.setBackground('re_lvmeng','character'); - player2.node.avatar.setBackground('re_guanyu','character'); - },1500); - setTimeout(function(){ + player1.node.avatar.setBackground("re_lvmeng", "character"); + player2.node.avatar.setBackground("re_guanyu", "character"); + }, 1500); + setTimeout(function () { player1.smoothAvatar(); player2.smoothAvatar(); - player1.node.avatar.setBackground('sp_lvmeng','character'); - player2.node.avatar.setBackground('jsp_guanyu','character'); - },3000); - setTimeout(function(){ + player1.node.avatar.setBackground("sp_lvmeng", "character"); + player2.node.avatar.setBackground("jsp_guanyu", "character"); + }, 3000); + setTimeout(function () { player1.smoothAvatar(); player2.smoothAvatar(); - player1.node.avatar.setBackground('shen_lvmeng','character'); - player2.node.avatar.setBackground('shen_guanyu','character'); - },4500); - setTimeout(function(){ + player1.node.avatar.setBackground("shen_lvmeng", "character"); + player2.node.avatar.setBackground("shen_guanyu", "character"); + }, 4500); + setTimeout(function () { player1.smoothAvatar(); player2.smoothAvatar(); - player1.node.avatar.setBackground('lvmeng','character'); - player2.node.avatar.setBackground('guanyu','character'); - },6000); + player1.node.avatar.setBackground("lvmeng", "character"); + player2.node.avatar.setBackground("guanyu", "character"); + }, 6000); }; - node.showcaseinterval=setInterval(func,6000); + node.showcaseinterval = setInterval(func, 6000); func(); }, - intro:[ - '玩家在选将时可从8张武将牌里选择两张武将牌,一张面向大家可见(加入游戏),另一张是隐藏面孔(暗置)', - '选择的两张武将牌需满足以下至少两个条件:1.性别相同;2.体力上限相同;3.技能数量相同', - '每名玩家在其回合开始或回合结束时,可以选择将自己的武将牌弃置,然后使用暗置的武将牌进行剩余的游戏' + intro: [ + "玩家在选将时可从8张武将牌里选择两张武将牌,一张面向大家可见(加入游戏),另一张是隐藏面孔(暗置)", + "选择的两张武将牌需满足以下至少两个条件:1.性别相同;2.体力上限相同;3.技能数量相同", + "每名玩家在其回合开始或回合结束时,可以选择将自己的武将牌弃置,然后使用暗置的武将牌进行剩余的游戏", ], - content:{ - submode:'two', - chooseCharacterBefore:function(){ - game.versusVideoName='白衣渡江'; - lib.skill._changeCharacter={ - trigger:{player:['phaseBefore','phaseAfter']}, - forced:true, - silent:true, - popup:false, - filter:function(event,player){ - return player._backupCharacter!=undefined; + content: { + submode: "two", + chooseCharacterBefore: function () { + game.versusVideoName = "白衣渡江"; + (lib.skill._changeCharacter = { + trigger: { player: ["phaseBefore", "phaseAfter"] }, + forced: true, + silent: true, + popup: false, + filter: function (event, player) { + return player._backupCharacter != undefined; }, - content:function(){ - "step 0" - player.chooseControl('确定','取消').set('dialog',['是否替换自己的武将牌?',[[player._backupCharacter],'character']]).set('ai',function(){ - return Math.random()<0.15?'确定':'取消'; - }); - "step 1" - if(result.control=='确定'){ - game.log(player,'将',player.name,'替换为了',player._backupCharacter); - player.reinit(player.name,player._backupCharacter); - player.changeGroup(lib.character[player._backupCharacter][1],false); + content: function () { + "step 0"; + player + .chooseControl("确定", "取消") + .set("dialog", [ + "是否替换自己的武将牌?", + [[player._backupCharacter], "character"], + ]) + .set("ai", function () { + return Math.random() < 0.15 ? "确定" : "取消"; + }); + "step 1"; + if (result.control == "确定") { + game.log(player, "将", player.name, "替换为了", player._backupCharacter); + player.reinit(player.name, player._backupCharacter); + player.changeGroup(lib.character[player._backupCharacter][1], false); delete player._backupCharacter; } }, - }, - game.addGlobalSkill('_changeCharacter'); - game.chooseCharacterTwo=function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - 'step 0' - ui.arena.classList.add('choose-character'); - for(var i in lib.skill){ - if(lib.skill[i].changeSeat){ - lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; + }), + game.addGlobalSkill("_changeCharacter"); + game.chooseCharacterTwo = function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); + for (var i in lib.skill) { + if (lib.skill[i].changeSeat) { + lib.skill[i] = {}; + if (lib.translate[i + "_info"]) { + lib.translate[i + "_info"] = "此模式下不可用"; } } } - var bool=Math.random()<0.5; - var bool2=Math.random()<0.5; - var ref=game.players[0]; + var bool = Math.random() < 0.5; + var bool2 = Math.random() < 0.5; + var ref = game.players[0]; - ref.side=bool; - ref.next.side=bool2; - ref.next.next.side=!bool; - ref.previous.side=!bool2; + ref.side = bool; + ref.next.side = bool2; + ref.next.next.side = !bool; + ref.previous.side = !bool2; - var firstChoose=game.players.randomGet(); - if(firstChoose.next.side==firstChoose.side){ - firstChoose=firstChoose.next; + var firstChoose = game.players.randomGet(); + if (firstChoose.next.side == firstChoose.side) { + firstChoose = firstChoose.next; } - _status.firstAct=firstChoose; - for(var i=0;i<4;i++){ - firstChoose.node.name.innerHTML=get.verticalStr(get.cnNumber(i+1,true)+'号位'); - firstChoose=firstChoose.next; + _status.firstAct = firstChoose; + for (var i = 0; i < 4; i++) { + firstChoose.node.name.innerHTML = get.verticalStr( + get.cnNumber(i + 1, true) + "号位" + ); + firstChoose = firstChoose.next; } - for(var i=0;i1; + var choose = []; + _status.characterlist = list; + event.filterChoice = function (name1, name2) { + var info1 = lib.character[name1]; + var info2 = lib.character[name2]; + if (!info1 || !info2) return; + var num = 0; + if (info1[0] == info2[0]) num++; + if (get.infoMaxHp(info1[2]) == get.infoMaxHp(info2[2])) num++; + if (info1[3].length == info2[3].length) num++; + return num > 1; }; - var list2=list.randomGets(8); - var next=game.me.chooseButton(2,true,['请选择您的武将牌',[list2,'character']]); - next.set('onfree',true); - next.set('filterButton',function(button){ - if(!ui.selected.buttons.length){ - for(var i=0;i1){ - game.fellow.node.marks.lastChild.remove(); - } - for(var i in game.fellow.tempSkills){ - game.fellow.removeSkill(i); - } - var skills=game.fellow.getSkills(); - for(var i=0;i 1) { + game.fellow.node.marks.lastChild.remove(); + } + for (var i in game.fellow.tempSkills) { + game.fellow.removeSkill(i); + } + var skills = game.fellow.getSkills(); + for (var i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]].temp) { + game.fellow.removeSkill(skills[i]); + } + } + var cards = game.fellow.getCards("hej"); + while (cards.length) { + ui.discardPile.appendChild(cards.shift()); } } - var cards=game.fellow.getCards('hej'); - while(cards.length){ - ui.discardPile.appendChild(cards.shift()); + "step 1"; + if (game.fellow) { + game.dead.remove(game.fellow); + game.fellow.remove(); + game.fan.dataset.position = 1; + ui.arena.setNumber(2); + game.zhu.next = game.fan; + game.fan.next = game.zhu; + game.zhu.nextSeat = game.fan; + game.fan.nextSeat = game.zhu; } - } - 'step 1' - if(game.fellow){ - game.dead.remove(game.fellow); - game.fellow.remove(); - game.fan.dataset.position=1; - ui.arena.setNumber(2); - game.zhu.next=game.fan; - game.fan.next=game.zhu; - game.zhu.nextSeat=game.fan; - game.fan.nextSeat=game.zhu; - } - if(_status.qianlidanji.completeNumber!=5){ - var list=_status.qianlidanji.completeReward.randomGets(3); - var list2=[]; - for(var i=0;i= 6) { + list.push("我不想再打了,直接在这里结束吧!"); + list2.push(function () { + game.over(true); + }); + } + event.list = list2; + game.zhu + .chooseControl() + .set("choiceList", list) + .set( + "prompt", + "请选择一项奖励(当前已通过" + + _status.qianlidanji.completeNumber + + "关)" + ); } - if(_status.qianlidanji.completeNumber>=6){ - list.push('我不想再打了,直接在这里结束吧!'); - list2.push(function(){ + "step 2"; + if (_status.qianlidanji.completeNumber != 5) { + if (result.index == 3) { game.over(true); - }); + return; + } + event.reward = event.list[result.index]; } - event.list=list2; - game.zhu.chooseControl().set('choiceList',list).set('prompt','请选择一项奖励(当前已通过'+_status.qianlidanji.completeNumber+'关)'); - } - 'step 2' - if(_status.qianlidanji.completeNumber!=5){ - if(result.index==3){ - game.over(true); - return; + _status.characterlist.removeArray(_status.qianlidanji.used); + if (_status.qianlidanji.completeNumber == 5) + event._result = { links: ["caiyang"] }; + else + game.zhu.chooseButton( + [ + "选择下一关出战的对手", + [_status.characterlist.randomGets(3), "character"], + ], + true + ); + "step 3"; + _status.event.getParent("phaseLoop").player = game.zhu; + var source = game.fan; + var name = result.links[0]; + source.revive(null, false); + _status.characterlist.remove(name); + _status.qianlidanji.used.push(name); + source.uninit(); + source.init(name); + game.addVideo("reinit", source, [name]); + source.lose(source.getCards("hej"))._triggered = null; + var gain = 4; + var add = 0; + switch (_status.qianlidanji.completeNumber) { + case 5: + break; + case 1: + gain = 5; + break; + case 2: + gain = 5; + add = 1; + break; + case 3: + gain = 6; + add = 1; + break; + default: + gain = 6; + add = 2; + break; } - event.reward=event.list[result.index]; - } - _status.characterlist.removeArray(_status.qianlidanji.used); - if(_status.qianlidanji.completeNumber==5) event._result={links:['caiyang']}; - else game.zhu.chooseButton(['选择下一关出战的对手',[_status.characterlist.randomGets(3),'character']],true); - 'step 3' - _status.event.getParent('phaseLoop').player=game.zhu; - var source=game.fan; - var name=result.links[0]; - source.revive(null,false); - _status.characterlist.remove(name); - _status.qianlidanji.used.push(name); - source.uninit(); - source.init(name); - game.addVideo('reinit',source,[name]); - source.lose(source.getCards('hej'))._triggered=null; - var gain=4; - var add=0; - switch(_status.qianlidanji.completeNumber){ - case 5:break; - case 1:gain=5;break; - case 2:gain=5;add=1;break; - case 3:gain=6;add=1;break; - default:gain=6;add=2;break; - } - source.hp+=add; - source.maxHp+=add; - source.update(); - source.gain(get.cards(gain))._triggered=null; - game.triggerEnter(source); - if(event.reward) event.reward(); - 'step 4' - var cards=Array.from(ui.ordering.childNodes); - while(cards.length){ - cards.shift().discard(); - } - var evt=_status.event.getParent('phase'); - if(evt){ - game.resetSkills(); - _status.event=evt; - _status.event.finish(); - _status.event.untrigger(true); - } - }, - }; - _status.qianlidanji.player_number=get.config('player_number'); - game.saveConfig('player_number','2','identity'); + source.hp += add; + source.maxHp += add; + source.update(); + source.gain(get.cards(gain))._triggered = null; + game.triggerEnter(source); + if (event.reward) event.reward(); + "step 4"; + var cards = Array.from(ui.ordering.childNodes); + while (cards.length) { + cards.shift().discard(); + } + var evt = _status.event.getParent("phase"); + if (evt) { + game.resetSkills(); + _status.event = evt; + _status.event.finish(); + _status.event.untrigger(true); + } + }, + }; + _status.qianlidanji.player_number = get.config("player_number"); + game.saveConfig("player_number", "2", "identity"); }, - content:{ - submode:'normal', - chooseCharacterBefore:function(){ - game.identityVideoName='千里单骑'; - game.saveConfig('player_number',_status.qianlidanji.player_number,'identity'); - game.chooseCharacter=function(){ - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - "step 0" - ui.arena.classList.add('choose-character'); - game.me.identity='zhu'; - game.zhu=game.me; - game.fan=game.me.next; - game.fan.identity='fan'; + content: { + submode: "normal", + chooseCharacterBefore: function () { + game.identityVideoName = "千里单骑"; + game.saveConfig("player_number", _status.qianlidanji.player_number, "identity"); + game.chooseCharacter = function () { + var next = game.createEvent("chooseCharacter"); + next.showConfig = true; + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); + game.me.identity = "zhu"; + game.zhu = game.me; + game.fan = game.me.next; + game.fan.identity = "fan"; game.zhu.setIdentity(); - game.zhu.identityShown=true; - game.zhu.node.identity.classList.remove('guessing'); + game.zhu.identityShown = true; + game.zhu.node.identity.classList.remove("guessing"); game.fan.setIdentity(); - game.fan.identityShown=true; - game.fan.node.identity.classList.remove('guessing'); + game.fan.identityShown = true; + game.fan.node.identity.classList.remove("guessing"); - event.list=[]; - for(var i in lib.character){ - if(lib.filter.characterDisabled(i)) continue; + event.list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled(i)) continue; event.list.push(i); } event.list.randomSort(); - _status.characterlist=event.list.slice(0); - var list=event.list.slice(0,5); + _status.characterlist = event.list.slice(0); + var list = event.list.slice(0, 5); delete event.swapnochoose; var dialog; - if(event.swapnodialog){ - dialog=ui.dialog; - event.swapnodialog(dialog,list); + if (event.swapnodialog) { + dialog = ui.dialog; + event.swapnodialog(dialog, list); delete event.swapnodialog; + } else { + var str = "选择角色"; + dialog = ui.create.dialog(str, "hidden", [list, "character"]); } - else{ - var str='选择角色'; - dialog=ui.create.dialog(str,'hidden',[list,'character']); - } - dialog.setCaption('选择角色'); - game.me.chooseButton(dialog,true).set('onfree',true); + dialog.setCaption("选择角色"); + game.me.chooseButton(dialog, true).set("onfree", true); - ui.create.cheat=function(){ - _status.createControl=ui.cheat2; - ui.cheat=ui.create.control('更换',function(){ - if(ui.cheat2&&ui.cheat2.dialog==_status.event.dialog){ + ui.create.cheat = function () { + _status.createControl = ui.cheat2; + ui.cheat = ui.create.control("更换", function () { + if (ui.cheat2 && ui.cheat2.dialog == _status.event.dialog) { return; } - if(game.changeCoin){ + if (game.changeCoin) { game.changeCoin(-3); } event.list.randomSort(); - list=event.list.slice(0,5); + list = event.list.slice(0, 5); - var buttons=ui.create.div('.buttons'); - var node=_status.event.dialog.buttons[0].parentNode; - _status.event.dialog.buttons=ui.create.buttons(list,'character',buttons); - _status.event.dialog.content.insertBefore(buttons,node); - buttons.addTempClass('start'); + var buttons = ui.create.div(".buttons"); + var node = _status.event.dialog.buttons[0].parentNode; + _status.event.dialog.buttons = ui.create.buttons( + list, + "character", + buttons + ); + _status.event.dialog.content.insertBefore(buttons, node); + buttons.addTempClass("start"); node.remove(); game.uncheck(); game.check(); }); delete _status.createControl; }; - if(lib.onfree){ - lib.onfree.push(function(){ - event.dialogxx=ui.create.characterDialog('heightset'); - if(ui.cheat2){ - ui.cheat2.addTempClass('controlpressdownx',500); - ui.cheat2.classList.remove('disabled'); + if (lib.onfree) { + lib.onfree.push(function () { + event.dialogxx = ui.create.characterDialog("heightset"); + if (ui.cheat2) { + ui.cheat2.addTempClass("controlpressdownx", 500); + ui.cheat2.classList.remove("disabled"); } }); - } - else{ - event.dialogxx=ui.create.characterDialog('heightset'); + } else { + event.dialogxx = ui.create.characterDialog("heightset"); } - ui.create.cheat2=function(){ - ui.cheat2=ui.create.control('自由选将',function(){ - if(this.dialog==_status.event.dialog){ - if(game.changeCoin){ + ui.create.cheat2 = function () { + ui.cheat2 = ui.create.control("自由选将", function () { + if (this.dialog == _status.event.dialog) { + if (game.changeCoin) { game.changeCoin(50); } this.dialog.close(); - _status.event.dialog=this.backup; + _status.event.dialog = this.backup; this.backup.open(); delete this.backup; game.uncheck(); game.check(); - if(ui.cheat){ - ui.cheat.addTempClass('controlpressdownx',500); - ui.cheat.classList.remove('disabled'); + if (ui.cheat) { + ui.cheat.addTempClass("controlpressdownx", 500); + ui.cheat.classList.remove("disabled"); } - } - else{ - if(game.changeCoin){ + } else { + if (game.changeCoin) { game.changeCoin(-10); } - this.backup=_status.event.dialog; + this.backup = _status.event.dialog; _status.event.dialog.close(); - _status.event.dialog=_status.event.parent.dialogxx; - this.dialog=_status.event.dialog; + _status.event.dialog = _status.event.parent.dialogxx; + this.dialog = _status.event.dialog; this.dialog.open(); game.uncheck(); game.check(); - if(ui.cheat){ - ui.cheat.classList.add('disabled'); + if (ui.cheat) { + ui.cheat.classList.add("disabled"); } } }); - if(lib.onfree){ - ui.cheat2.classList.add('disabled'); + if (lib.onfree) { + ui.cheat2.classList.add("disabled"); } + }; + if (!_status.brawl || !_status.brawl.chooseCharacterFixed) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); } - if(!_status.brawl||!_status.brawl.chooseCharacterFixed){ - if(!ui.cheat&&get.config('change_choice')) - ui.create.cheat(); - if(!ui.cheat2&&get.config('free_choose')) - ui.create.cheat2(); - } - "step 1" - if(ui.cheat){ + "step 1"; + if (ui.cheat) { ui.cheat.close(); delete ui.cheat; } - if(ui.cheat2){ + if (ui.cheat2) { ui.cheat2.close(); delete ui.cheat2; } @@ -3031,1611 +3469,1962 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ game.zhu.init(result.buttons[0].link); _status.characterlist.remove(result.buttons[0].link); _status.qianlidanji.used.add(result.buttons[0].link); - game.zhu.chooseControl('地狱','困难','普通','简单','无双').set('prompt','请选择游戏难度'); - "step 2" - var hp=Math.floor(result.index/2); - event.draw=Math.floor((result.index+1)/2); - if(hp){ - game.zhu.hp+=hp; - game.zhu.maxHp+=hp; + game.zhu + .chooseControl("地狱", "困难", "普通", "简单", "无双") + .set("prompt", "请选择游戏难度"); + "step 2"; + var hp = Math.floor(result.index / 2); + event.draw = Math.floor((result.index + 1) / 2); + if (hp) { + game.zhu.hp += hp; + game.zhu.maxHp += hp; game.zhu.update(); } - game.zhu.chooseButton(['请选择对手的登场武将',[_status.characterlist.randomGets(3),'character']],true); - "step 3" + game.zhu.chooseButton( + [ + "请选择对手的登场武将", + [_status.characterlist.randomGets(3), "character"], + ], + true + ); + "step 3"; game.fan.init(result.links[0]); _status.characterlist.remove(result.links[0]); _status.qianlidanji.used.add(result.links[0]); - if(event.draw){ + if (event.draw) { game.zhu.directgain(get.cards(event.draw)); } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); - var pack={ - character:{ - pujing:['male','qun',1,[],[]], - huban:['male','qun',2,[],[]], - caiyang:['male','qun',1,['zhuixi'],[]], + var pack = { + character: { + pujing: ["male", "qun", 1, [], []], + huban: ["male", "qun", 2, [], []], + caiyang: ["male", "qun", 1, ["zhuixi"], []], }, - translate:{ - pujing:'普净', - huban:'胡班', + translate: { + pujing: "普净", + huban: "胡班", }, - skill:{ - qianlidanji_phase:{ - trigger:{global:'phaseBefore'}, - forced:true, - silent:true, - firstDo:true, - content:function(){ - player.removeSkill('qianlidanji_phase'); + skill: { + qianlidanji_phase: { + trigger: { global: "phaseBefore" }, + forced: true, + silent: true, + firstDo: true, + content: function () { + player.removeSkill("qianlidanji_phase"); player.insertPhase(); }, }, }, }; - for(var i in pack){ - for(var j in pack[i]){ - lib[i][j]=pack[i][j]; + for (var i in pack) { + for (var j in pack[i]) { + lib[i][j] = pack[i][j]; } } delete pack.skill; - game.addVideo('arrangeLib',null,pack); - game.addOverDialog=function(dialog){ - dialog.addText('共计通过'+_status.qianlidanji.completeNumber+'关'); - }; - lib.element.player.dieAfter=function(){ - if(this==game.fellow) return; - _status.characterlist.removeArray(_status.qianlidanji.used); - if(game.zhu==this||!_status.characterlist.length){ - var bool=false; - if(_status.qianlidanji.completeNumber>5) bool=true; - game.over(bool); - } - else{ - var next=game.createEvent('qianlidanji_replace',false); - next.setContent(_status.qianlidanji.replace_character); - } - }; - lib.element.player.dieAfter2=function(){ - _status.characterlist.removeArray(_status.qianlidanji.used); - }; - game.zhu.dieAfter=lib.element.player.dieAfter; - game.fan.dieAfter=lib.element.player.dieAfter; - game.zhu.dieAfter2=lib.element.player.dieAfter2; - game.fan.dieAfter2=lib.element.player.dieAfter2; + game.addVideo("arrangeLib", null, pack); + game.addOverDialog = function (dialog) { + dialog.addText("共计通过" + _status.qianlidanji.completeNumber + "关"); + }; + lib.element.player.dieAfter = function () { + if (this == game.fellow) return; + _status.characterlist.removeArray(_status.qianlidanji.used); + if (game.zhu == this || !_status.characterlist.length) { + var bool = false; + if (_status.qianlidanji.completeNumber > 5) bool = true; + game.over(bool); + } else { + var next = game.createEvent("qianlidanji_replace", false); + next.setContent(_status.qianlidanji.replace_character); + } + }; + lib.element.player.dieAfter2 = function () { + _status.characterlist.removeArray(_status.qianlidanji.used); + }; + game.zhu.dieAfter = lib.element.player.dieAfter; + game.fan.dieAfter = lib.element.player.dieAfter; + game.zhu.dieAfter2 = lib.element.player.dieAfter2; + game.fan.dieAfter2 = lib.element.player.dieAfter2; }); }; - } - } + }, + }, }, - liangjunduilei:{ - name:'两军对垒', - mode:'versus', - submode:'2v2', - showcase:function(init){ - var node=this; - var player1,player2; - var list=[ - ['re_sp_zhugeliang','yujin_yujin','re_zhangliao','re_lusu'], - ['re_huangzhong','re_xiahouyuan','zhanghe','xin_fazheng'], - ['re_caocao','xin_yuanshao','guotufengji','re_guojia'], - ['chunyuqiong','sp_xuyou','re_xuhuang','gaolan'], - ['re_sp_zhugeliang','re_zhangzhang','guyong','re_lusu'], - ['yj_jushou','re_caocao','jsp_guanyu','re_yanwen'], - ['re_lingtong','re_lidian','re_zhangliao','re_ganning'], - ['re_guanyu','caoren','re_lvmeng','guanping'], + liangjunduilei: { + name: "两军对垒", + mode: "versus", + submode: "2v2", + showcase: function (init) { + var node = this; + var player1, player2; + var list = [ + ["re_sp_zhugeliang", "yujin_yujin", "re_zhangliao", "re_lusu"], + ["re_huangzhong", "re_xiahouyuan", "zhanghe", "xin_fazheng"], + ["re_caocao", "xin_yuanshao", "guotufengji", "re_guojia"], + ["chunyuqiong", "sp_xuyou", "re_xuhuang", "gaolan"], + ["re_sp_zhugeliang", "re_zhangzhang", "guyong", "re_lusu"], + ["yj_jushou", "re_caocao", "jsp_guanyu", "re_yanwen"], + ["re_lingtong", "re_lidian", "re_zhangliao", "re_ganning"], + ["re_guanyu", "caoren", "re_lvmeng", "guanping"], ].randomGet(); - if(_status.keyVerified){ - list=[ - ['caozhen','key_hisako','key_iwasawa','sp_key_kanade'], - ].randomGet(); + if (_status.keyVerified) { + list = [["caozhen", "key_hisako", "key_iwasawa", "sp_key_kanade"]].randomGet(); } - if(init){ - player1=ui.create.player(null,true); - player2=ui.create.player(null,true); + if (init) { + player1 = ui.create.player(null, true); + player2 = ui.create.player(null, true); player1.node.marks.remove(); player1.node.hp.remove(); player2.node.marks.remove(); player2.node.hp.remove(); - player1.style.left='20px'; - player1.style.top='20px'; - player1.style.transform='scale(0.9)'; + player1.style.left = "20px"; + player1.style.top = "20px"; + player1.style.transform = "scale(0.9)"; player1.node.count.remove(); - player2.style.left='auto'; - player2.style.right='20px'; - player2.style.top='20px'; - player2.style.transform='scale(0.9)'; + player2.style.left = "auto"; + player2.style.right = "20px"; + player2.style.top = "20px"; + player2.style.transform = "scale(0.9)"; player2.node.count.remove(); this.appendChild(player1); this.appendChild(player2); - this.player1=player1; - this.player2=player2; + this.player1 = player1; + this.player2 = player2; + } else { + player1 = this.player1; + player2 = this.player2; } - else{ - player1=this.player1; - player2=this.player2; - } - var player3,player4; - if(init){ - player3=ui.create.player(null,true); - player4=ui.create.player(null,true); + var player3, player4; + if (init) { + player3 = ui.create.player(null, true); + player4 = ui.create.player(null, true); player3.node.marks.remove(); player3.node.hp.remove(); player4.node.marks.remove(); player4.node.hp.remove(); - player3.style.left='60px'; - player3.style.top='120px'; - player3.style.transform='scale(0.9)'; + player3.style.left = "60px"; + player3.style.top = "120px"; + player3.style.transform = "scale(0.9)"; player3.node.count.remove(); - player4.style.left='auto'; - player4.style.right='60px'; - player4.style.top='120px'; - player4.style.transform='scale(0.9)'; + player4.style.left = "auto"; + player4.style.right = "60px"; + player4.style.top = "120px"; + player4.style.transform = "scale(0.9)"; player4.node.count.remove(); this.appendChild(player3); this.appendChild(player4); - this.player3=player3; - this.player4=player4; - } - else{ - player3=this.player3; - player4=this.player4; + this.player3 = player3; + this.player4 = player4; + } else { + player3 = this.player3; + player4 = this.player4; } player1.init(list[0]); player2.init(list[1]); player3.init(list[3]); player4.init(list[2]); }, - intro:['双方使用特定的武将,搭配特定的技能,还原特定的经典场景'], - content:{ - submode:'two', - chooseCharacterBefore:function(){ - var list=[ + intro: ["双方使用特定的武将,搭配特定的技能,还原特定的经典场景"], + content: { + submode: "two", + chooseCharacterBefore: function () { + var list = [ { - name:'草船借箭', - place:[true,false,false,true], - character:['re_sp_zhugeliang','yujin_yujin','re_zhangliao','re_lusu'], - lib:{ - character:{ - re_sp_zhugeliang:['male','shu',3,['tiaoxin','bazhen','feiying'],[]], - yujin_yujin:['male','wei',4,['jiangchi','danshou'],[]], - re_zhangliao:['male','wei',4,['benxi','tuifeng','qingxi'],[]], - re_lusu:['male','wu',3,['kaikang','shenxian'],[]], + name: "草船借箭", + place: [true, false, false, true], + character: ["re_sp_zhugeliang", "yujin_yujin", "re_zhangliao", "re_lusu"], + lib: { + character: { + re_sp_zhugeliang: [ + "male", + "shu", + 3, + ["tiaoxin", "bazhen", "feiying"], + [], + ], + yujin_yujin: ["male", "wei", 4, ["jiangchi", "danshou"], []], + re_zhangliao: ["male", "wei", 4, ["benxi", "tuifeng", "qingxi"], []], + re_lusu: ["male", "wu", 3, ["kaikang", "shenxian"], []], }, - translate:{ - re_sp_zhugeliang:'诸葛卧龙', - yujin_yujin:'于文则', - re_zhangliao:'张文远', - re_lusu:'鲁子敬', + translate: { + re_sp_zhugeliang: "诸葛卧龙", + yujin_yujin: "于文则", + re_zhangliao: "张文远", + re_lusu: "鲁子敬", }, }, }, { - name:'定军山之战', - place:[true,false,false,true], - character:['re_huangzhong','re_xiahouyuan','zhanghe','xin_fazheng'], - lib:{ - character:{ - re_huangzhong:['male','shu',4,['yingjian','weikui','gzyinghun'],[]], - re_xiahouyuan:['male','wei',4,['benxi','yaowu','dujin','juesi'],[]], - zhanghe:['male','wei',4,['kaikang','xingshang','zhiheng'],[]], - xin_fazheng:['male','shu',4,['xinfu_zhanji','nzry_chenglve','yiji'],[]], + name: "定军山之战", + place: [true, false, false, true], + character: ["re_huangzhong", "re_xiahouyuan", "zhanghe", "xin_fazheng"], + lib: { + character: { + re_huangzhong: [ + "male", + "shu", + 4, + ["yingjian", "weikui", "gzyinghun"], + [], + ], + re_xiahouyuan: [ + "male", + "wei", + 4, + ["benxi", "yaowu", "dujin", "juesi"], + [], + ], + zhanghe: ["male", "wei", 4, ["kaikang", "xingshang", "zhiheng"], []], + xin_fazheng: [ + "male", + "shu", + 4, + ["xinfu_zhanji", "nzry_chenglve", "yiji"], + [], + ], }, - translate:{ - re_huangzhong:'定军黄忠', - re_xiahouyuan:'定军妙才', - zhanghe:'定军张郃', - xin_fazheng:'定军法正', + translate: { + re_huangzhong: "定军黄忠", + re_xiahouyuan: "定军妙才", + zhanghe: "定军张郃", + xin_fazheng: "定军法正", }, }, }, { - name:'官渡追击战', - place:[false,true,true,false], - character:['re_caocao','xin_yuanshao','guotufengji','re_guojia'], - lib:{ - character:{ - re_caocao:['male','wei',4,['fankui','zhuiji','duanbing'],[]], - xin_yuanshao:['male','qun','3/6',['reluanji','kuanggu','benghuai','weizhong'],[]], - guotufengji:['male','qun',2,['sijian','jigong','shifei','jianying'],[]], - re_guojia:['male','wei',3,['yiji','sanyao','gongxin'],[]], + name: "官渡追击战", + place: [false, true, true, false], + character: ["re_caocao", "xin_yuanshao", "guotufengji", "re_guojia"], + lib: { + character: { + re_caocao: ["male", "wei", 4, ["fankui", "zhuiji", "duanbing"], []], + xin_yuanshao: [ + "male", + "qun", + "3/6", + ["reluanji", "kuanggu", "benghuai", "weizhong"], + [], + ], + guotufengji: [ + "male", + "qun", + 2, + ["sijian", "jigong", "shifei", "jianying"], + [], + ], + re_guojia: ["male", "wei", 3, ["yiji", "sanyao", "gongxin"], []], }, - translate:{ - re_caocao:'官渡曹操', - xin_yuanshao:'官渡袁绍', - guotufengji:'袁军智囊', - re_guojia:'官渡郭嘉', + translate: { + re_caocao: "官渡曹操", + xin_yuanshao: "官渡袁绍", + guotufengji: "袁军智囊", + re_guojia: "官渡郭嘉", }, }, }, { - name:'奇袭乌巢', - place:[true,false,false,true], - character:['chunyuqiong','sp_xuyou','re_xuhuang','gaolan'], - lib:{ - character:{ - chunyuqiong:['male','qun',8,['ranshang','duliang','jiuchi'],[]], - sp_xuyou:['male','qun',3,['qice','lianying','nzry_jianxiang'],[]], - re_xuhuang:['male','wei',4,['shenduan','xiaoguo','nzry_juzhan'],[]], - gaolan:['male','qun',4,['yuanhu','shensu','benyu','suishi'],[]], + name: "奇袭乌巢", + place: [true, false, false, true], + character: ["chunyuqiong", "sp_xuyou", "re_xuhuang", "gaolan"], + lib: { + character: { + chunyuqiong: [ + "male", + "qun", + 8, + ["ranshang", "duliang", "jiuchi"], + [], + ], + sp_xuyou: [ + "male", + "qun", + 3, + ["qice", "lianying", "nzry_jianxiang"], + [], + ], + re_xuhuang: [ + "male", + "wei", + 4, + ["shenduan", "xiaoguo", "nzry_juzhan"], + [], + ], + gaolan: [ + "male", + "qun", + 4, + ["yuanhu", "shensu", "benyu", "suishi"], + [], + ], }, - translate:{ - chunyuqiong:'乌巢淳于琼', - sp_xuyou:'乌巢许攸', - re_xuhuang:'乌巢徐晃', - gaolan:'乌巢高览', + translate: { + chunyuqiong: "乌巢淳于琼", + sp_xuyou: "乌巢许攸", + re_xuhuang: "乌巢徐晃", + gaolan: "乌巢高览", }, }, }, { - name:'舌战群儒', - place:[false,true,false,true], - character:['re_zhangzhang','re_sp_zhugeliang','guyong','re_lusu'], - lib:{ - character:{ - re_sp_zhugeliang:['male','shu',3,['tianbian','jyzongshi','xinfu_guolun'],[]], - re_zhangzhang:['male','wu',3,['zhuandui','tiaoxin','guzheng'],[]], - guyong:['male','wu',3,['qiaoshui','qicai','bingyi'],[]], - re_lusu:['male','wu',3,['qingzhongx','shuimeng'],[]], + name: "舌战群儒", + place: [false, true, false, true], + character: ["re_zhangzhang", "re_sp_zhugeliang", "guyong", "re_lusu"], + lib: { + character: { + re_sp_zhugeliang: [ + "male", + "shu", + 3, + ["tianbian", "jyzongshi", "xinfu_guolun"], + [], + ], + re_zhangzhang: [ + "male", + "wu", + 3, + ["zhuandui", "tiaoxin", "guzheng"], + [], + ], + guyong: ["male", "wu", 3, ["qiaoshui", "qicai", "bingyi"], []], + re_lusu: ["male", "wu", 3, ["qingzhongx", "shuimeng"], []], }, - translate:{ - re_sp_zhugeliang:'诸葛卧龙', - re_zhangzhang:'张子布', - guyong:'顾元叹', - re_lusu:'鲁子敬', + translate: { + re_sp_zhugeliang: "诸葛卧龙", + re_zhangzhang: "张子布", + guyong: "顾元叹", + re_lusu: "鲁子敬", }, }, }, { - name:'武圣战双雄', - place:[true,false,false,true], - character:['yj_jushou','re_caocao','jsp_guanyu','re_yanwen'], - lib:{ - character:{ - yj_jushou:['male','qun',3,['mingce','jianyan','shibei'],[]], - re_caocao:['male','wei',4,['miji','beige','feiying'],[]], - jsp_guanyu:['male','wei',4,['nuzhan','jianchu','new_rewusheng'],[]], - re_yanwen:['male','qun',4,['shuangxiong','zhanyi','zhichi'],[]], + name: "武圣战双雄", + place: [true, false, false, true], + character: ["yj_jushou", "re_caocao", "jsp_guanyu", "re_yanwen"], + lib: { + character: { + yj_jushou: ["male", "qun", 3, ["mingce", "jianyan", "shibei"], []], + re_caocao: ["male", "wei", 4, ["miji", "beige", "feiying"], []], + jsp_guanyu: [ + "male", + "wei", + 4, + ["nuzhan", "jianchu", "new_rewusheng"], + [], + ], + re_yanwen: [ + "male", + "qun", + 4, + ["shuangxiong", "zhanyi", "zhichi"], + [], + ], }, - translate:{ - yj_jushou:'白马沮授', - re_caocao:'白马曹操', - jsp_guanyu:'武圣关羽', - re_yanwen:'颜文双雄', + translate: { + yj_jushou: "白马沮授", + re_caocao: "白马曹操", + jsp_guanyu: "武圣关羽", + re_yanwen: "颜文双雄", }, }, }, { - name:'合肥之战', - place:[true,false,false,true], - character:['re_lingtong','re_lidian','re_zhangliao','re_ganning'], - lib:{ - character:{ - re_lingtong:['male','wu',4,['xuanfeng','zishou','tiaoxin'],[]], - re_lidian:['male','wei',3,['weijing','wangxi','zhuandui'],[]], - re_zhangliao:['male','wei',3,['retuxi','mashu','reyingzi','xinpojun'],[]], - re_ganning:['male','wu',5,['lizhan','jiang','zhenwei'],[]], + name: "合肥之战", + place: [true, false, false, true], + character: ["re_lingtong", "re_lidian", "re_zhangliao", "re_ganning"], + lib: { + character: { + re_lingtong: ["male", "wu", 4, ["xuanfeng", "zishou", "tiaoxin"], []], + re_lidian: ["male", "wei", 3, ["weijing", "wangxi", "zhuandui"], []], + re_zhangliao: [ + "male", + "wei", + 3, + ["retuxi", "mashu", "reyingzi", "xinpojun"], + [], + ], + re_ganning: ["male", "wu", 5, ["lizhan", "jiang", "zhenwei"], []], }, - translate:{ - re_lingtong:'合肥凌统', - re_lidian:'合肥李典', - re_zhangliao:'合肥张辽', - re_ganning:'合肥甘宁', + translate: { + re_lingtong: "合肥凌统", + re_lidian: "合肥李典", + re_zhangliao: "合肥张辽", + re_ganning: "合肥甘宁", }, }, }, { - name:'荆州之战', - place:[true,false,false,true], - character:['re_guanyu','caoren','re_lvmeng','guanping'], - lib:{ - character:{ - re_guanyu:['male','shu',5,['wusheng','zishou','zhongyong'],[]], - caoren:['male','wei',1,['xinjiewei','qiuyuan','gzbuqu','xinjushou'],[]], - re_lvmeng:['male','wu',4,['gongxin','duodao','dujin','huituo'],[]], - guanping:['male','shu',5,['longyin','suishi'],[]], + name: "荆州之战", + place: [true, false, false, true], + character: ["re_guanyu", "caoren", "re_lvmeng", "guanping"], + lib: { + character: { + re_guanyu: ["male", "shu", 5, ["wusheng", "zishou", "zhongyong"], []], + caoren: [ + "male", + "wei", + 1, + ["xinjiewei", "qiuyuan", "gzbuqu", "xinjushou"], + [], + ], + re_lvmeng: [ + "male", + "wu", + 4, + ["gongxin", "duodao", "dujin", "huituo"], + [], + ], + guanping: ["male", "shu", 5, ["longyin", "suishi"], []], }, - translate:{ - re_guanyu:'荆州关羽', - caoren:'樊城曹仁', - re_lvmeng:'江东吕蒙', - guanping:'荆州关平', + translate: { + re_guanyu: "荆州关羽", + caoren: "樊城曹仁", + re_lvmeng: "江东吕蒙", + guanping: "荆州关平", }, }, }, { - name:'雒城之战', - place:[true,false,false,true], - character:['liubei','re_wuyi','zhangren','pangtong'], - lib:{ - character:{ - liubei:['male','shu',4,['rezhijian','jijiu','reyingzi'],[]], - re_wuyi:['male','qun',4,['weijing','rerende'],[]], - zhangren:['male','qun',4,['shefu','gnsheque'],[]], - pangtong:['male','shu',3,['dujin'],[]], + name: "雒城之战", + place: [true, false, false, true], + character: ["liubei", "re_wuyi", "zhangren", "pangtong"], + lib: { + character: { + liubei: ["male", "shu", 4, ["rezhijian", "jijiu", "reyingzi"], []], + re_wuyi: ["male", "qun", 4, ["weijing", "rerende"], []], + zhangren: ["male", "qun", 4, ["shefu", "gnsheque"], []], + pangtong: ["male", "shu", 3, ["dujin"], []], }, - translate:{ - liubei:'雒城刘备', - re_wuyi:'雒城吴懿', - zhangren:'雒城张任', - pangtong:'雒城庞统', - rezhijian:'厚恩', - zhijian:'厚恩', - jijiu:'驰援', - reyingzi:'征令', - rerende:'遣军', + translate: { + liubei: "雒城刘备", + re_wuyi: "雒城吴懿", + zhangren: "雒城张任", + pangtong: "雒城庞统", + rezhijian: "厚恩", + zhijian: "厚恩", + jijiu: "驰援", + reyingzi: "征令", + rerende: "遣军", }, }, }, ]; - if(_status.keyVerified) list=[ + if (_status.keyVerified) + list = [ { - name:'My Song', - place:[false,true,true,false], - character:['caozhen','key_hisako','key_iwasawa','sp_key_kanade'], - lib:{ - character:{ - caozhen:['male','wei',4,['xinsidi','tuxi']], - key_hisako:['female','key','2/3',['hisako_yinbao','shenzhi','shiorimiyuki_banyin','hisako_zhuanyun'],[]], - key_iwasawa:['female','key','-999/3',['iwasawa_yinhang','iwasawa_mysong','hisako_zhuanyun']], - sp_key_kanade:['female','key',3,['xinwuyan','xinbenxi']], - }, - translate:{ - caozhen:'突袭教师', - key_hisako:'绝望恶魔', - key_iwasawa:'引吭孤鸦', - sp_key_kanade:'学生会长', + name: "My Song", + place: [false, true, true, false], + character: ["caozhen", "key_hisako", "key_iwasawa", "sp_key_kanade"], + lib: { + character: { + caozhen: ["male", "wei", 4, ["xinsidi", "tuxi"]], + key_hisako: [ + "female", + "key", + "2/3", + [ + "hisako_yinbao", + "shenzhi", + "shiorimiyuki_banyin", + "hisako_zhuanyun", + ], + [], + ], + key_iwasawa: [ + "female", + "key", + "-999/3", + ["iwasawa_yinhang", "iwasawa_mysong", "hisako_zhuanyun"], + ], + sp_key_kanade: ["female", "key", 3, ["xinwuyan", "xinbenxi"]], + }, + translate: { + caozhen: "突袭教师", + key_hisako: "绝望恶魔", + key_iwasawa: "引吭孤鸦", + sp_key_kanade: "学生会长", + }, }, }, - }, - { - name:'Day Game', - place:[false,true,true,false], - character:['key_yuzuru','sp_key_kanade','key_ayato','key_hinata'], - lib:{ - character:{ - key_yuzuru:['male','key',4,['hinata_qiulve','kurou']], - sp_key_kanade:['female','key',3,['hinata_qiulve','benxi'],[]], - key_ayato:['male','key',3,['hinata_qiulve','retieji']], - key_hinata:['female','key',4,['hinata_qiulve','hinata_ehou']], - }, - translate:{ - key_yuzuru:'新秀球王', - sp_key_kanade:'学生会长', - key_ayato:'副会长', - key_hinata:'球队领袖', + { + name: "Day Game", + place: [false, true, true, false], + character: ["key_yuzuru", "sp_key_kanade", "key_ayato", "key_hinata"], + lib: { + character: { + key_yuzuru: ["male", "key", 4, ["hinata_qiulve", "kurou"]], + sp_key_kanade: [ + "female", + "key", + 3, + ["hinata_qiulve", "benxi"], + [], + ], + key_ayato: ["male", "key", 3, ["hinata_qiulve", "retieji"]], + key_hinata: [ + "female", + "key", + 4, + ["hinata_qiulve", "hinata_ehou"], + ], + }, + translate: { + key_yuzuru: "新秀球王", + sp_key_kanade: "学生会长", + key_ayato: "副会长", + key_hinata: "球队领袖", + }, }, }, - }, - ] - game.liangjunduilei=list; - game.chooseCharacterTwo=function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - 'step 0' - for(var i in lib.skill){ - if(lib.skill[i].audio&&!lib.skill[i].equipSkill) lib.skill[i].audio=false; - if(lib.skill[i].changeSeat){ - lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; + ]; + game.liangjunduilei = list; + game.chooseCharacterTwo = function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + for (var i in lib.skill) { + if (lib.skill[i].audio && !lib.skill[i].equipSkill) + lib.skill[i].audio = false; + if (lib.skill[i].changeSeat) { + lib.skill[i] = {}; + if (lib.translate[i + "_info"]) { + lib.translate[i + "_info"] = "此模式下不可用"; } } } - ui.arena.classList.add('choose-character'); - var list=game.liangjunduilei; - var id=lib.status.videoId++; - var choiceList=ui.create.dialog('请选择要游玩的剧情','forcebutton'); - choiceList.videoId=id; - choiceList.add([list.map((item,i)=>{ - return [i,``]; - }),'textbutton']) - game.me.chooseButton(true).set('dialog',id).set('onfree',true); - 'step 1' - var pack=game.liangjunduilei[result.links[0]]; - game.versusVideoName=pack.name; - if(get.is.phoneLayout()){ - ui.duileiInfo=ui.create.div('.touchinfo.left',ui.window); + ui.arena.classList.add("choose-character"); + var list = game.liangjunduilei; + var id = lib.status.videoId++; + var choiceList = ui.create.dialog("请选择要游玩的剧情", "forcebutton"); + choiceList.videoId = id; + choiceList.add([ + list.map((item, i) => { + return [ + i, + ``, + ]; + }), + "textbutton", + ]); + game.me.chooseButton(true).set("dialog", id).set("onfree", true); + "step 1"; + var pack = game.liangjunduilei[result.links[0]]; + game.versusVideoName = pack.name; + if (get.is.phoneLayout()) { + ui.duileiInfo = ui.create.div(".touchinfo.left", ui.window); + } else { + ui.duileiInfo = ui.create.div(ui.gameinfo); } - else{ - ui.duileiInfo=ui.create.div(ui.gameinfo); - } - ui.duileiInfo.innerHTML='当前剧情:'+pack.name; - for(var i in pack.lib){ - for(var j in pack.lib[i]){ - lib[i][j]=pack.lib[i][j]; + ui.duileiInfo.innerHTML = "当前剧情:" + pack.name; + for (var i in pack.lib) { + for (var j in pack.lib[i]) { + lib[i][j] = pack.lib[i][j]; } } - var player=game.players.randomGet(); - _status.firstAct=player; - for(var i=0;i<4;i++){ + var player = game.players.randomGet(); + _status.firstAct = player; + for (var i = 0; i < 4; i++) { player.init(pack.character[i]); - player.side=pack.place[i]; - player=player.next; + player.side = pack.place[i]; + player = player.next; } - for(var i=0;i=0;i--){ + for (var i = scene.cardPileTop.length - 1; i >= 0; i--) { list.unshift(parseInfo(scene.cardPileTop[i])); } - for(var i=0;igame.players[i].maxHp){ - game.players[i].hp=game.players[i].maxHp; + var info = game.players[i].brawlinfo; + if (info.maxHp) { + game.players[i].maxHp = info.maxHp; + if (game.players[i].hp > game.players[i].maxHp) { + game.players[i].hp = game.players[i].maxHp; } } - if(info.hp){ - game.players[i].hp=info.hp; - if(game.players[i].hp>game.players[i].maxHp){ - game.players[i].maxHp=game.players[i].hp; + if (info.hp) { + game.players[i].hp = info.hp; + if (game.players[i].hp > game.players[i].maxHp) { + game.players[i].maxHp = game.players[i].hp; } } game.players[i].update(); } - var scene=_status.brawl.scene; - var over=function(str){ - switch(str){ - case 'win':game.over(true);break; - case 'lose':game.over(false);break; - case 'tie':game.over('平局');break; + var scene = _status.brawl.scene; + var over = function (str) { + switch (str) { + case "win": + game.over(true); + break; + case "lose": + game.over(false); + break; + case "tie": + game.over("平局"); + break; } - } - if(scene.turns){ - var turns=scene.turns[0]; - lib.onphase.push(function(){ + }; + if (scene.turns) { + var turns = scene.turns[0]; + lib.onphase.push(function () { turns--; - if(turns<0){ + if (turns < 0) { over(scene.turns[1]); } }); } - if(scene.washes){ - var washes=scene.washes[0]; - lib.onwash.push(function(){ + if (scene.washes) { + var washes = scene.washes[0]; + lib.onwash.push(function () { washes--; - if(washes<=0){ + if (washes <= 0) { over(scene.washes[1]); } }); } }, - chooseCharacterBefore:function(){ - var scene=_status.brawl.scene; - var playercontrol=[]; - var maxpos=0; - for(var i=0;ibb?1:-1; + if (aa != bb) { + return aa > bb ? 1 : -1; } - return a>b?1:-1; + return a > b ? 1 : -1; }); - list.unshift(['random','自选主将']); - var name1=ui.create.selectlist(list,list[0],line2); - name1.style.marginLeft='3px'; - name1.style.marginRight='3px'; - name1.style.maxWidth='80px'; - list[0][1]='自选副将'; - list.unshift(['none','无副将']); - var name2=ui.create.selectlist(list,list[0],line2); - name2.style.marginLeft='3px'; - name2.style.marginRight='3px'; - name2.style.maxWidth='80px'; + list.unshift(["random", "自选主将"]); + var name1 = ui.create.selectlist(list, list[0], line2); + name1.style.marginLeft = "3px"; + name1.style.marginRight = "3px"; + name1.style.maxWidth = "80px"; + list[0][1] = "自选副将"; + list.unshift(["none", "无副将"]); + var name2 = ui.create.selectlist(list, list[0], line2); + name2.style.marginLeft = "3px"; + name2.style.marginRight = "3px"; + name2.style.maxWidth = "80px"; - var capt9=ui.create.div(style2,'','编辑牌堆',this); - capt9.style.display='none'; + var capt9 = ui.create.div(style2, "", "编辑牌堆", this); + capt9.style.display = "none"; - var capt2=ui.create.div(style2,'','添加卡牌',this); - var line3=ui.create.div(style2,this); - line3.style.display='none'; - capt1.style.display='none'; - capt2.style.display='none'; + var capt2 = ui.create.div(style2, "", "添加卡牌", this); + var line3 = ui.create.div(style2, this); + line3.style.display = "none"; + capt1.style.display = "none"; + capt2.style.display = "none"; - var line5=ui.create.div(style2,this); - line5.style.display='none'; - var pileaddlist=[]; - for(var i=0;i替换牌堆'); - line11.style.display='none'; - var replacepile=ui.create.node('input',line11); - replacepile.type='checkbox'; + var line11 = ui.create.div(style2, this, "", "替换牌堆"); + line11.style.display = "none"; + var replacepile = ui.create.node("input", line11); + replacepile.type = "checkbox"; - ui.create.node('span',line11,'开局摸牌',{marginLeft:'10px'}); - var gameDraw=ui.create.node('input',line11); - gameDraw.type='checkbox'; - gameDraw.checked=true; + ui.create.node("span", line11, "开局摸牌", { marginLeft: "10px" }); + var gameDraw = ui.create.node("input", line11); + gameDraw.type = "checkbox"; + gameDraw.checked = true; - var capt_t=ui.create.div(style2,'','牌堆顶',this); - var line6_t=ui.create.div(style2,this); - var capt_b=ui.create.div(style2,'','牌堆底',this); - var line6_b=ui.create.div(style2,this); - var capt_d=ui.create.div(style2,'','弃牌堆',this); - var line6_d=ui.create.div(style2,this); - line6_d.style.marginBottom='10px'; - capt_t.style.display='none'; - capt_b.style.display='none'; - capt_d.style.display='none'; + var capt_t = ui.create.div(style2, "", "牌堆顶", this); + var line6_t = ui.create.div(style2, this); + var capt_b = ui.create.div(style2, "", "牌堆底", this); + var line6_b = ui.create.div(style2, this); + var capt_d = ui.create.div(style2, "", "弃牌堆", this); + var line6_d = ui.create.div(style2, this); + line6_d.style.marginBottom = "10px"; + capt_t.style.display = "none"; + capt_b.style.display = "none"; + capt_d.style.display = "none"; - var line4=ui.create.div(style2,this); - line4.style.display='none'; - line4.style.marginTop='20px'; - var resetCharacter=function(){ + var line4 = ui.create.div(style2, this); + line4.style.display = "none"; + line4.style.marginTop = "20px"; + var resetCharacter = function () { // line1.style.display='block'; - editPile.disabled=false; + editPile.disabled = false; // editCode.disabled=false; - saveButton.disabled=false; + saveButton.disabled = false; // exportButton.disabled=false; - line7.style.display='block'; - line2.style.display='none'; - line2_t.style.display='none'; - line3.style.display='none'; - line4.style.display='none'; - line5.style.display='none'; - line6_h.style.display='none'; - line6_e.style.display='none'; - line6_j.style.display='none'; - capt1.style.display='none'; - capt2.style.display='none'; - capt_h.style.display='none'; - capt_e.style.display='none'; - capt_j.style.display='none'; + line7.style.display = "block"; + line2.style.display = "none"; + line2_t.style.display = "none"; + line3.style.display = "none"; + line4.style.display = "none"; + line5.style.display = "none"; + line6_h.style.display = "none"; + line6_e.style.display = "none"; + line6_j.style.display = "none"; + capt1.style.display = "none"; + capt2.style.display = "none"; + capt_h.style.display = "none"; + capt_e.style.display = "none"; + capt_j.style.display = "none"; - name1.value='random'; - name2.value='none'; - identity.value='fan'; - position.value='0'; - hp.value=''; - maxHp.value=''; - line6_h.innerHTML=''; - line6_e.innerHTML=''; - line6_j.innerHTML=''; - cardpileaddname.value='random'; - cardpileaddsuit.value='random'; - cardpileaddnumber.value='random'; - linked.checked=false; - turnedover.checked=false; - playercontrol.checked=false; + name1.value = "random"; + name2.value = "none"; + identity.value = "fan"; + position.value = "0"; + hp.value = ""; + maxHp.value = ""; + line6_h.innerHTML = ""; + line6_e.innerHTML = ""; + line6_j.innerHTML = ""; + cardpileaddname.value = "random"; + cardpileaddsuit.value = "random"; + cardpileaddnumber.value = "random"; + linked.checked = false; + turnedover.checked = false; + playercontrol.checked = false; }; - var createCharacter=function(info){ - var player=ui.create.player(null,true); - player._customintro=function(uiintro){ - if(info.handcards.length){ - uiintro.addText('手牌',true); - var hs=ui.create.div('.buttons'); - for(var i=0;i stage.level) { + node.classList.add("unselectable"); } } - else if(stage.mode=='normal'){ - if(i>stage.level){ - node.classList.add('unselectable'); - } - } - if(lib.storage.lastStage==i&&!node.classList.contains('unselectable')){ - node.classList.add('active'); - noactive=false; - } - else if(lib.storage.lastStage==undefined&&noactive&&!node.classList.contains('unselectable')){ - node.classList.add('active'); - noactive=false; + if (lib.storage.lastStage == i && !node.classList.contains("unselectable")) { + node.classList.add("active"); + noactive = false; + } else if ( + lib.storage.lastStage == undefined && + noactive && + !node.classList.contains("unselectable") + ) { + node.classList.add("active"); + noactive = false; } } } }, }, - showcase:function(init){ - if(_status.sceneChanged){ - init=true; - this.innerHTML=''; + showcase: function (init) { + if (_status.sceneChanged) { + init = true; + this.innerHTML = ""; delete _status.sceneChanged; } - if(init){ - this.style.transition='all 0s'; - this.style.height=(this.offsetHeight-10)+'px'; + if (init) { + this.style.transition = "all 0s"; + this.style.height = this.offsetHeight - 10 + "px"; // this.style.overflow='scroll'; // lib.setScroll(this); - var style2={position:'relative',display:'block',left:0,top:0,marginBottom:'6px',padding:0,width:'100%'}; - var style3={marginLeft:'4px',marginRight:'4px',position:'relative'} + var style2 = { + position: "relative", + display: "block", + left: 0, + top: 0, + marginBottom: "6px", + padding: 0, + width: "100%", + }; + var style3 = { marginLeft: "4px", marginRight: "4px", position: "relative" }; - var scenename=ui.create.node('input',ui.create.div(style2,'','关卡名称:',this),{width:'120px'}); - scenename.type='text'; - scenename.style.marginTop='20px'; - var sceneintro=ui.create.node('input',ui.create.div(style2,'','关卡描述:',this),{width:'120px'}); - sceneintro.type='text'; - sceneintro.style.marginBottom='10px'; + var scenename = ui.create.node( + "input", + ui.create.div(style2, "", "关卡名称:", this), + { width: "120px" } + ); + scenename.type = "text"; + scenename.style.marginTop = "20px"; + var sceneintro = ui.create.node( + "input", + ui.create.div(style2, "", "关卡描述:", this), + { width: "120px" } + ); + sceneintro.type = "text"; + sceneintro.style.marginBottom = "10px"; - var line1=ui.create.div(style2,this); - var line2=ui.create.div(style2,this); - line1.style.marginBottom='10px'; - line2.style.lineHeight='50px'; - line2.style.overflow='scroll'; + var line1 = ui.create.div(style2, this); + var line2 = ui.create.div(style2, this); + line1.style.marginBottom = "10px"; + line2.style.lineHeight = "50px"; + line2.style.overflow = "scroll"; lib.setScroll(line2); - var container=this.parentNode.parentNode; - setTimeout(function(){ - var rect1=container.getBoundingClientRect(); - var rect2=line2.getBoundingClientRect(); - line2.style.height=(rect1.height-(rect2.top-rect1.top))+'px'; - },1000); - var scenes=[]; - for(var i in lib.storage.scene){ - scenes.push([i,i]); + var container = this.parentNode.parentNode; + setTimeout(function () { + var rect1 = container.getBoundingClientRect(); + var rect2 = line2.getBoundingClientRect(); + line2.style.height = rect1.height - (rect2.top - rect1.top) + "px"; + }, 1000); + var scenes = []; + for (var i in lib.storage.scene) { + scenes.push([i, i]); } - if(!scenes.length){ - alert('请创建至少1个场景'); + if (!scenes.length) { + alert("请创建至少1个场景"); return; } - var scenelist=ui.create.selectlist(scenes,null,line1); - var e1=function(){ - if(this.nextSibling){ - this.parentNode.insertBefore(this,this.nextSibling.nextSibling); + var scenelist = ui.create.selectlist(scenes, null, line1); + var e1 = function () { + if (this.nextSibling) { + this.parentNode.insertBefore(this, this.nextSibling.nextSibling); } - } - var e2=function(){ - var that=this; - this.movetimeout=setTimeout(function(){ + }; + var e2 = function () { + var that = this; + this.movetimeout = setTimeout(function () { e1.call(that); - },500); - } - var e3=function(){ + }, 500); + }; + var e3 = function () { clearTimeout(this.movetimeout); delete this.movetimeout; - } - var e4=function(value){ - var node=ui.create.div('.menubutton.large',value,line2,style3,function(){ - if(confirm('是否移除'+this.innerHTML+'?')){ + }; + var e4 = function (value) { + var node = ui.create.div(".menubutton.large", value, line2, style3, function () { + if (confirm("是否移除" + this.innerHTML + "?")) { this.remove(); } }); - if(lib.config.touchscreen){ - node.ontouchstart=e2; - node.ontouchend=e3; - node.ontouchmove=e3; + if (lib.config.touchscreen) { + node.ontouchstart = e2; + node.ontouchend = e3; + node.ontouchmove = e3; + } else { + node.oncontextmenu = e1; + node.onmousedown = e2; + node.onmouseup = e3; + node.onmouseleave = e3; } - else{ - node.oncontextmenu=e1; - node.onmousedown=e2; - node.onmouseup=e3; - node.onmouseleave=e3; - } - } - var addButton=ui.create.node('button','添加场景',line1,function(){ - e4(scenelist.value); - },{marginLeft:'6px',marginRight:'12px'}); - var sceneconfig=ui.create.selectlist([ - ['normal','默认模式'], - ['sequal','连续闯关'], - ['free','自由选关'] - ],null,line1); - var saveButton=ui.create.node('button','保存关卡',line1,function(){ - if(!scenename.value){ - alert('请填写关卡名称'); - return; - } - if(line2.childElementCount<2){ - alert('请添加至少2个场景'); - return; - } - var stage={ - name:scenename.value, - intro:sceneintro.value, - scenes:[], - mode:sceneconfig.value, - level:0 - }; - for(var i=0;i0){ - var ng=Math.floor(gridnum*nco); - for(var i=0;i 0) { + var ng = Math.floor(gridnum * nco); + for (var i = 0; i < ng; i++) { + var cg = grids.randomRemove(); + game.addObstacle(cg.toString(), false); event.obs.push(cg.toString()); } } } - _status.enemyCount=_status.enemylist.length; - _status.friendCount=_status.mylist.length; - while(_status.mylist.length){ - friend=ui.create.player().addTempClass('start'); + _status.enemyCount = _status.enemylist.length; + _status.friendCount = _status.mylist.length; + while (_status.mylist.length) { + friend = ui.create.player().addTempClass("start"); friend.getId(); - if(!event.friendZhu){ - event.friendZhu=friend; - } - else if(!event.friendViceZhu){ - event.friendViceZhu=friend; + if (!event.friendZhu) { + event.friendZhu = friend; + } else if (!event.friendViceZhu) { + event.friendViceZhu = friend; } friend.init(_status.mylist.shift()); - friend.side=side; - friend.setIdentity('friend'); - friend.identity='friend'; - friend.node.identity.dataset.color=get.translation(side+'Color'); + friend.side = side; + friend.setIdentity("friend"); + friend.identity = "friend"; + friend.node.identity.dataset.color = get.translation(side + "Color"); game.players.push(friend); ui.chess.appendChild(friend); - if(event.video){ - ui.placeChess(friend,mylistmap.shift()); - } - else{ - ui.placeChess(friend,grids.randomRemove()); - if(_status.enterArena&&game.data.arena.acted.includes(friend.name)){ + if (event.video) { + ui.placeChess(friend, mylistmap.shift()); + } else { + ui.placeChess(friend, grids.randomRemove()); + if (_status.enterArena && game.data.arena.acted.includes(friend.name)) { friend.hp--; friend.update(); } - if(_status.enterArena){ - friend.addSkill('arenaAdd'); + if (_status.enterArena) { + friend.addSkill("arenaAdd"); } } - lib.posmap[friend.dataset.position]=friend; + lib.posmap[friend.dataset.position] = friend; } - while(_status.enemylist.length){ - enemy=ui.create.player().addTempClass('start'); + while (_status.enemylist.length) { + enemy = ui.create.player().addTempClass("start"); enemy.getId(); enemy.init(_status.enemylist.shift()); - enemy.side=!side; - enemy.setIdentity('enemy'); - enemy.identity='enemy'; - enemy.node.identity.dataset.color=get.translation(!side+'Color'); + enemy.side = !side; + enemy.setIdentity("enemy"); + enemy.identity = "enemy"; + enemy.node.identity.dataset.color = get.translation(!side + "Color"); game.players.push(enemy); ui.chess.appendChild(enemy); - if(event.video){ - ui.placeChess(enemy,enemylistmap.shift()); + if (event.video) { + ui.placeChess(enemy, enemylistmap.shift()); + } else { + ui.placeChess(enemy, grids.randomRemove()); } - else{ - ui.placeChess(enemy,grids.randomRemove()); - } - lib.posmap[enemy.dataset.position]=enemy; + lib.posmap[enemy.dataset.position] = enemy; } - if(lib.config.show_handcardbutton){ - lib.setPopped(ui.create.system('手牌',null,true),function(){ - var uiintro=ui.create.dialog('hidden'); - var added=false; - for(var i=0;i_status.enemyDied){ + } else if (_status.friendDied > _status.enemyDied) { game.forceOver(false); - } - else{ + } else { game.forceOver(); } }); - ui.finishGame.classList.add('finish_game'); - ui.finishGame.parentNode.insertBefore(finishGameBr,ui.finishGame); + ui.finishGame.classList.add("finish_game"); + ui.finishGame.parentNode.insertBefore(finishGameBr, ui.finishGame); } ui.create.me(); ui.create.fakeme(); - if(!event.video&&((_status.mode=='combat'&&get.config('zhu')&&!_status.vsboss&&game.players.length>2)||_status.mode=='three')){ - game.friendZhu=event.friendZhu; + if ( + !event.video && + ((_status.mode == "combat" && + get.config("zhu") && + !_status.vsboss && + game.players.length > 2) || + _status.mode == "three") + ) { + game.friendZhu = event.friendZhu; game.friendZhu.hp++; game.friendZhu.maxHp++; game.friendZhu.update(); - game.friendZhu.node.identity.firstChild.innerHTML='将'; + game.friendZhu.node.identity.firstChild.innerHTML = "将"; - for(var i=0;i=ui.chesswidth){ - x=ui.chesswidth-1; + moveTo: function (x, y) { + game.addVideo("moveTo", this, [x, y]); + if (x >= ui.chesswidth) { + x = ui.chesswidth - 1; } - if(y>=ui.chessheight){ - y=ui.chessheight-1; + if (y >= ui.chessheight) { + y = ui.chessheight - 1; } - var pos=y*ui.chesswidth+x; - if(!lib.posmap[pos]){ + var pos = y * ui.chesswidth + x; + if (!lib.posmap[pos]) { delete lib.posmap[this.dataset.position]; // this.changeSeat(pos,false); - ui.placeChess(this,pos); - lib.posmap[pos]=this; + ui.placeChess(this, pos); + lib.posmap[pos] = this; this.chessFocus(); } - if(get.mode()=='tafang'&&!_status.video){ - if(_status.tafangend.includes(this.dataset.position)){ - if(_status.enemies.includes(this)){ + if (get.mode() == "tafang" && !_status.video) { + if (_status.tafangend.includes(this.dataset.position)) { + if (_status.enemies.includes(this)) { game.over(false); - } - else{ + } else { this.delete(); delete lib.posmap[this]; game.players.remove(this); _status.friends.remove(this); - this.classList.add('dead'); - if(_status.roundStart==this){ - _status.roundStart=player.next||player.getNext()||game.players[0]; + this.classList.add("dead"); + if (_status.roundStart == this) { + _status.roundStart = player.next || player.getNext() || game.players[0]; } - if(this==game.me){ - if(ui.confirm){ + if (this == game.me) { + if (ui.confirm) { ui.confirm.close(); } - if(_status.friends.length==0){ + if (_status.friends.length == 0) { ui.fakeme.hide(); this.node.handcards1.delete(); this.node.handcards2.delete(); - game.me=ui.create.player(); - game.me.side=false; - game.addVideo('removeTafangPlayer'); - } - else{ + game.me = ui.create.player(); + game.me.side = false; + game.addVideo("removeTafangPlayer"); + } else { game.modeSwapPlayer(_status.friends[0]); } } - for(var i=0;i0&&this.movable(1,0)) return true; - if(dy<0&&this.movable(0,-1)) return true; - if(dy>0&&this.movable(0,1)) return true; + canMoveTowards: function (target) { + var fxy = this.getXY(); + var txy = target.getXY(); + var dx = txy[0] - fxy[0]; + var dy = txy[1] - fxy[1]; + if (dx < 0 && this.movable(-1, 0)) return true; + if (dx > 0 && this.movable(1, 0)) return true; + if (dy < 0 && this.movable(0, -1)) return true; + if (dy > 0 && this.movable(0, 1)) return true; return false; }, - moveTowards:function(target,forbid){ - var fxy=this.getXY(); + moveTowards: function (target, forbid) { + var fxy = this.getXY(); var txy; - if(Array.isArray(target)){ - txy=target; + if (Array.isArray(target)) { + txy = target; + } else if (typeof target == "string") { + var pos = parseInt(target); + txy = [pos % ui.chesswidth, Math.floor(pos / ui.chesswidth)]; + } else { + txy = target.getXY(); } - else if(typeof target=='string'){ - var pos=parseInt(target); - txy=[pos%ui.chesswidth,Math.floor(pos/ui.chesswidth)]; - } - else{ - txy=target.getXY(); - } - var dx=txy[0]-fxy[0]; - var dy=txy[1]-fxy[1]; - forbid=forbid||[]; - if(Math.abs(dx)>Math.abs(dy)){ - if(dx<0){ - if(!forbid.includes('moveLeft')&&this.movable(-1,0)){ + var dx = txy[0] - fxy[0]; + var dy = txy[1] - fxy[1]; + forbid = forbid || []; + if (Math.abs(dx) > Math.abs(dy)) { + if (dx < 0) { + if (!forbid.includes("moveLeft") && this.movable(-1, 0)) { this.moveLeft(); - return 'moveLeft'; + return "moveLeft"; } - } - else if(dx>0){ - if(!forbid.includes('moveRight')&&this.movable(1,0)){ + } else if (dx > 0) { + if (!forbid.includes("moveRight") && this.movable(1, 0)) { this.moveRight(); - return 'moveRight'; + return "moveRight"; } } - if(dy<0){ - if(!forbid.includes('moveUp')&&this.movable(0,-1)){ + if (dy < 0) { + if (!forbid.includes("moveUp") && this.movable(0, -1)) { this.moveUp(); - return 'moveUp'; + return "moveUp"; } - } - else if(dy>0){ - if(!forbid.includes('moveDown')&&this.movable(0,1)){ + } else if (dy > 0) { + if (!forbid.includes("moveDown") && this.movable(0, 1)) { this.moveDown(); - return 'moveDown'; + return "moveDown"; } } - } - else{ - if(dy<0){ - if(!forbid.includes('moveUp')&&this.movable(0,-1)){ + } else { + if (dy < 0) { + if (!forbid.includes("moveUp") && this.movable(0, -1)) { this.moveUp(); - return 'moveUp'; + return "moveUp"; } - } - else if(dy>0){ - if(!forbid.includes('moveDown')&&this.movable(0,1)){ + } else if (dy > 0) { + if (!forbid.includes("moveDown") && this.movable(0, 1)) { this.moveDown(); - return 'moveDown'; + return "moveDown"; } } - if(dx<0){ - if(!forbid.includes('moveLeft')&&this.movable(-1,0)){ + if (dx < 0) { + if (!forbid.includes("moveLeft") && this.movable(-1, 0)) { this.moveLeft(); - return 'moveLeft'; + return "moveLeft"; } - } - else if(dx>0){ - if(!forbid.includes('moveRight')&&this.movable(1,0)){ + } else if (dx > 0) { + if (!forbid.includes("moveRight") && this.movable(1, 0)) { this.moveRight(); - return 'moveRight'; + return "moveRight"; } } } return false; }, - chessFocus:function(){ - game.addVideo('chessFocus',this); - if(ui.chess._chessdrag) return; - if(_status.chessscrolling) return; - var player=this; - var dx=0,dy=0; + chessFocus: function () { + game.addVideo("chessFocus", this); + if (ui.chess._chessdrag) return; + if (_status.chessscrolling) return; + var player = this; + var dx = 0, + dy = 0; - if(player.getLeft()-ui.chessContainer.chessLeft<14){ - dx=player.getLeft()-ui.chessContainer.chessLeft-14; + if (player.getLeft() - ui.chessContainer.chessLeft < 14) { + dx = player.getLeft() - ui.chessContainer.chessLeft - 14; + } else if ( + player.getLeft() - ui.chessContainer.chessLeft > + ui.chessContainer.offsetWidth - 134 + ) { + dx = + player.getLeft() - + ui.chessContainer.chessLeft - + ui.chessContainer.offsetWidth + + 134; } - else if(player.getLeft()-ui.chessContainer.chessLeft>ui.chessContainer.offsetWidth-134){ - dx=player.getLeft()-ui.chessContainer.chessLeft-ui.chessContainer.offsetWidth+134; - } - if(player.getTop()-ui.chessContainer.chessTop<14){ - dy=player.getTop()-ui.chessContainer.chessTop-14; - } - else if(player.getTop()+ui.chess.offsetTop-ui.chessContainer.chessTop>ui.chessContainer.offsetHeight-134){ - dy=player.getTop()+ui.chess.offsetTop-ui.chessContainer.chessTop-ui.chessContainer.offsetHeight+134; + if (player.getTop() - ui.chessContainer.chessTop < 14) { + dy = player.getTop() - ui.chessContainer.chessTop - 14; + } else if ( + player.getTop() + ui.chess.offsetTop - ui.chessContainer.chessTop > + ui.chessContainer.offsetHeight - 134 + ) { + dy = + player.getTop() + + ui.chess.offsetTop - + ui.chessContainer.chessTop - + ui.chessContainer.offsetHeight + + 134; } // if(_status.currentChessFocus){ // cancelAnimationFrame(_status.currentChessFocus); // } - var count=lib.config.low_performance?6:12; - var ddx=Math.floor(dx/count); - var ddy=Math.floor(dy/count); - if(dx||dy){ - ui.chessContainer.move(dx,dy,true); + var count = lib.config.low_performance ? 6 : 12; + var ddx = Math.floor(dx / count); + var ddy = Math.floor(dy / count); + if (dx || dy) { + ui.chessContainer.move(dx, dy, true); // var chessFocus=function(){ // if(count--){ // ui.chessContainer.chessLeft+=ddx; @@ -714,733 +752,746 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ // _status.currentChessFocus=requestAnimationFrame(chessFocus); } }, - getXY:function(){ - var pos=parseInt(this.dataset.position); - var x=pos%ui.chesswidth; - var y=Math.floor(pos/ui.chesswidth); - return [x,y]; + getXY: function () { + var pos = parseInt(this.dataset.position); + var x = pos % ui.chesswidth; + var y = Math.floor(pos / ui.chesswidth); + return [x, y]; }, - getDataPos:function(x,y){ - var xy=this.getXY(); - if(typeof x!='number') x=0; - if(typeof y!='number') y=0; - x+=xy[0]; - y+=xy[1]; - return x+y*ui.chesswidth; + getDataPos: function (x, y) { + var xy = this.getXY(); + if (typeof x != "number") x = 0; + if (typeof y != "number") y = 0; + x += xy[0]; + y += xy[1]; + return x + y * ui.chesswidth; }, - getNeighbour:function(x,y){ - var xy=this.getXY(); - if(xy[0]+x<0) return null; - if(xy[1]+y<0) return null; - if(xy[0]+x>=ui.chesswidth) return null; - if(xy[1]+y>=ui.chessheight) return null; - return lib.posmap[this.getDataPos(x,y)]||null; + getNeighbour: function (x, y) { + var xy = this.getXY(); + if (xy[0] + x < 0) return null; + if (xy[1] + y < 0) return null; + if (xy[0] + x >= ui.chesswidth) return null; + if (xy[1] + y >= ui.chessheight) return null; + return lib.posmap[this.getDataPos(x, y)] || null; }, - getNeighbours:function(){ - var players=[]; - for(var i=0;i=ui.chesswidth) return false; - if(xy[1]+y>=ui.chessheight) return false; - return !this.getNeighbour(x,y); + movable: function (x, y) { + var xy = this.getXY(); + if (xy[0] + x < 0) return false; + if (xy[1] + y < 0) return false; + if (xy[0] + x >= ui.chesswidth) return false; + if (xy[1] + y >= ui.chessheight) return false; + return !this.getNeighbour(x, y); }, - moveRight:function(){ - if(this.movable(1,0)){ - this.move(1,0); + moveRight: function () { + if (this.movable(1, 0)) { + this.move(1, 0); return true; } return false; }, - moveLeft:function(){ - if(this.movable(-1,0)){ - this.move(-1,0); + moveLeft: function () { + if (this.movable(-1, 0)) { + this.move(-1, 0); return true; } return false; }, - moveUp:function(){ - if(this.movable(0,-1)){ - this.move(0,-1); + moveUp: function () { + if (this.movable(0, -1)) { + this.move(0, -1); return true; } return false; }, - moveDown:function(){ - if(this.movable(0,1)){ - this.move(0,1); + moveDown: function () { + if (this.movable(0, 1)) { + this.move(0, 1); return true; } return false; }, - dieAfter2:function(){ - var player=this; + dieAfter2: function () { + var player = this; delete lib.posmap[player.dataset.position]; - setTimeout(function(){ + setTimeout(function () { player.delete(); - },500); - for(var i=0;i1){ - if(cards){ - that.$gain(cards,null,false) - } - else{ - that.$gain(num-1,null,false) + }, 500); + var that = this; + if (num && num > 1) { + if (cards) { + that.$gain(cards, null, false); + } else { + that.$gain(num - 1, null, false); } } }, - $throw:function(card,time,init){ - if(init!==false){ - if(get.itemtype(card)!='cards'){ - if(get.itemtype(card)=='card'){ - card=[card]; - } - else{ + $throw: function (card, time, init) { + if (init !== false) { + if (get.itemtype(card) != "cards") { + if (get.itemtype(card) == "card") { + card = [card]; + } else { return; } } - game.addVideo('throw',this,[get.cardsInfo(card),time]); + game.addVideo("throw", this, [get.cardsInfo(card), time]); } this.chessFocus(); - if(get.itemtype(card)=='cards'){ - for(var i=0;i=0){ - for(var i=0;i= 0) { + for (var i = 0; i < card; i++) { + from.$givemod("", player); } - } - else{ + } else { var node; - if(get.itemtype(card)=='card'){ - node=card.copy('card','thrown',false); - } - else{ - node=ui.create.div('.card.thrown'); + if (get.itemtype(card) == "card") { + node = card.copy("card", "thrown", false); + } else { + node = ui.create.div(".card.thrown"); } - node.dataset.position=this.dataset.position; - node.fixed=true; + node.dataset.position = this.dataset.position; + node.fixed = true; node.hide(); this.parentNode.appendChild(node); ui.refresh(node); node.show(); - this.$randomMove(node,130,0); + this.$randomMove(node, 130, 0); - setTimeout(function(){ - lib.element.card.moveTo.call(node,player); - setTimeout(function(){ + setTimeout(function () { + lib.element.card.moveTo.call(node, player); + setTimeout(function () { node.delete(); - },200); + }, 200); // node.removeAttribute('style'); // node.dataset.position=player.dataset.position; // node.delete(); - },700); + }, 700); } }, - $throwxy:function(card,left,top,transform){ - var node=card.copy('thrown','thrownhighlight'); - var rect=this.getBoundingClientRect(); - node.style.left=(rect.left+8)+'px'; - node.style.top=(rect.top+8)+'px'; + $throwxy: function (card, left, top, transform) { + var node = card.copy("thrown", "thrownhighlight"); + var rect = this.getBoundingClientRect(); + node.style.left = rect.left + 8 + "px"; + node.style.top = rect.top + 8 + "px"; node.hide(); - node.style.transitionProperty='left,top,opacity'; - if(transform){ - node.style.transform='rotate('+(Math.random()*16-8)+'deg)'; + node.style.transitionProperty = "left,top,opacity"; + if (transform) { + node.style.transform = "rotate(" + (Math.random() * 16 - 8) + "deg)"; } ui.arena.appendChild(node); ui.refresh(node); node.show(); - node.style.left=left; - node.style.top=top; + node.style.left = left; + node.style.top = top; return node; }, - $phaseJudge:function(card){ - game.addVideo('phaseJudge',this,get.cardInfo(card)); - var clone=card.copy('thrown',this.parentNode).addTempClass('judgestart'); - var player=this; - clone.style.opacity=0.6; - clone.style.left=(Math.random()*100-50+ui.chessContainer.chessLeft+ui.chessContainer.offsetWidth/2-52)+'px'; - clone.style.top=(Math.random()*80-40+ui.chessContainer.chessTop+ui.chessContainer.offsetHeight/2-52-ui.chessContainer.offsetTop)+'px'; + $phaseJudge: function (card) { + game.addVideo("phaseJudge", this, get.cardInfo(card)); + var clone = card.copy("thrown", this.parentNode).addTempClass("judgestart"); + var player = this; + clone.style.opacity = 0.6; + clone.style.left = + Math.random() * 100 - + 50 + + ui.chessContainer.chessLeft + + ui.chessContainer.offsetWidth / 2 - + 52 + + "px"; + clone.style.top = + Math.random() * 80 - + 40 + + ui.chessContainer.chessTop + + ui.chessContainer.offsetHeight / 2 - + 52 - + ui.chessContainer.offsetTop + + "px"; game.delay(); - game.linexy([ - clone.offsetLeft+clone.offsetWidth/2, - clone.offsetTop+clone.offsetHeight/2, - player.getLeft()+player.offsetWidth/2, - player.getTop()+player.offsetHeight/2 - ],{opacity:0.5,dashed:true},true); + game.linexy( + [ + clone.offsetLeft + clone.offsetWidth / 2, + clone.offsetTop + clone.offsetHeight / 2, + player.getLeft() + player.offsetWidth / 2, + player.getTop() + player.offsetHeight / 2, + ], + { opacity: 0.5, dashed: true }, + true + ); }, - $randomMove:function(node,length,rand){ - if(!this.node.chessthrown){ - this.node.chessthrown=[]; + $randomMove: function (node, length, rand) { + if (!this.node.chessthrown) { + this.node.chessthrown = []; } - var thrown=this.node.chessthrown; - for(var i=0;i= ui.chessContainer.offsetHeight) { + amin = 0; + amax = 90; + } else { + amin = -90; + amax = 90; } - else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ - amin=0; - amax=90; + } else if (rect.left + rect.width + 80 >= ui.chessContainer.offsetWidth) { + if (rect.top <= 80) { + amin = 180; + amax = 270; + } else if (rect.top + rect.height + 80 >= ui.chessContainer.offsetHeight) { + amin = 90; + amax = 180; + } else { + amin = 90; + amax = 270; } - else{ - amin=-90; - amax=90; - } - } - else if(rect.left+rect.width+80>=ui.chessContainer.offsetWidth){ - if(rect.top<=80){ - amin=180; - amax=270; - } - else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ - amin=90; - amax=180; - } - else{ - amin=90; - amax=270; - } - } - else if(rect.top<=80){ - amin=180; - amax=360; - } - else if(rect.top+rect.height+80>=ui.chessContainer.offsetHeight){ - amin=0; - amax=180; - } - else{ - var dx=ui.chessContainer.offsetWidth/2-(rect.left+rect.width/2); - var dy=-ui.chessContainer.offsetHeight/2+(rect.top+rect.height/2); - var ang=Math.abs(Math.atan(dy/dx))*180/Math.PI; - if(dx<0){ - if(dy>0){ - ang=180-ang; - } - else{ - ang+=180; + } else if (rect.top <= 80) { + amin = 180; + amax = 360; + } else if (rect.top + rect.height + 80 >= ui.chessContainer.offsetHeight) { + amin = 0; + amax = 180; + } else { + var dx = ui.chessContainer.offsetWidth / 2 - (rect.left + rect.width / 2); + var dy = -ui.chessContainer.offsetHeight / 2 + (rect.top + rect.height / 2); + var ang = (Math.abs(Math.atan(dy / dx)) * 180) / Math.PI; + if (dx < 0) { + if (dy > 0) { + ang = 180 - ang; + } else { + ang += 180; } + } else if (dy < 0) { + ang = 360 - ang; } - else if(dy<0){ - ang=360-ang; - } - amin=ang-180; - amax=ang+180; + amin = ang - 180; + amax = ang + 180; } - var da=(amax-amin)/(thrown.length*2); - if(da>30&&thrown.length>1){ - amin+=(da-30)*thrown.length; - da=30; + var da = (amax - amin) / (thrown.length * 2); + if (da > 30 && thrown.length > 1) { + amin += (da - 30) * thrown.length; + da = 30; } - for(var i=0;i.player'+pos+ // '{left:'+(14+i*148)+'px;top:'+(14+j*148)+'px}',0); - ui.chesssheet.sheet.insertRule('#arena.chess #chess>.card'+pos+ - '{left:'+(22+i*148)+'px;top:'+(22+j*148)+'px}',0); - ui.chesssheet.sheet.insertRule('#arena.chess #chess>.popup'+pos+ - '{left:'+(19+i*148)+'px;top:'+(142+j*148)+'px}',0); + ui.chesssheet.sheet.insertRule( + "#arena.chess #chess>.card" + + pos + + "{left:" + + (22 + i * 148) + + "px;top:" + + (22 + j * 148) + + "px}", + 0 + ); + ui.chesssheet.sheet.insertRule( + "#arena.chess #chess>.popup" + + pos + + "{left:" + + (19 + i * 148) + + "px;top:" + + (142 + j * 148) + + "px}", + 0 + ); } } }, - getVideoName:function(){ - var str='战棋'+get.translation(_status.mode)+' - '+_status.friendCount+'v'+_status.enemyCount; - var name=[get.translation(game.me.name),str]; + getVideoName: function () { + var str = + "战棋" + + get.translation(_status.mode) + + " - " + + _status.friendCount + + "v" + + _status.enemyCount; + var name = [get.translation(game.me.name), str]; return name; }, - addChessPlayer:function(name,enemy,num,pos){ - if(typeof num!='number'){ - num=4; + addChessPlayer: function (name, enemy, num, pos) { + if (typeof num != "number") { + num = 4; } - var player=ui.create.player(); + var player = ui.create.player(); player.getId(); - if(enemy=='treasure'){ - player.addTempClass('judgestart'); - player.side=null; - player.identity='neutral'; + if (enemy == "treasure") { + player.addTempClass("judgestart"); + player.side = null; + player.identity = "neutral"; player.setIdentity(); - player.node.identity.dataset.color='zhong'; - player.classList.add('treasure'); - player.node.hp.classList.add('treasure'); - player.life=6+Math.floor(Math.random()*6); + player.node.identity.dataset.color = "zhong"; + player.classList.add("treasure"); + player.node.hp.classList.add("treasure"); + player.life = 6 + Math.floor(Math.random() * 6); game.treasures.add(player); - } - else{ - player.addTempClass('start'); - if(enemy){ - if(get.mode()=='tafang'){ - player.side=true; + } else { + player.addTempClass("start"); + if (enemy) { + if (get.mode() == "tafang") { + player.side = true; + } else { + player.side = !game.me.side; } - else{ - player.side=!game.me.side; + player.setIdentity("enemy"); + player.identity = "enemy"; + } else { + if (get.mode() == "tafang") { + player.side = false; + } else { + player.side = game.me.side; } - player.setIdentity('enemy'); - player.identity='enemy'; + player.setIdentity("friend"); + player.identity = "friend"; } - else{ - if(get.mode()=='tafang'){ - player.side=false; - } - else{ - player.side=game.me.side; - } - player.setIdentity('friend'); - player.identity='friend'; - } - player.node.identity.dataset.color=get.translation(player.side+'Color'); + player.node.identity.dataset.color = get.translation(player.side + "Color"); game.players.push(player); // if(lib.config.animation){ // setTimeout(function(){ @@ -1564,38 +1638,36 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ // } } ui.chess.appendChild(player); - if(_status.video||(pos&&!lib.posmap[pos])){ - ui.placeChess(player,pos); - } - else{ - var grids=[]; - var gridnum=ui.chessheight*ui.chesswidth; - for(var i=0;i=ui.chesswidth){ - x=ui.chesswidth-1; + if (typeof x == "string") { + pos = x; + } else { + if (x >= ui.chesswidth) { + x = ui.chesswidth - 1; } - if(y>=ui.chessheight){ - y=ui.chessheight-1; + if (y >= ui.chessheight) { + y = ui.chessheight - 1; } - pos=y*ui.chesswidth+x; + pos = y * ui.chesswidth + x; } - if(!lib.posmap[pos]){ - var grid=ui.create.div('.player.minskin.obstacle',ui.chess).addTempClass('start'); - ui.placeChess(grid,pos); + if (!lib.posmap[pos]) { + var grid = ui.create.div(".player.minskin.obstacle", ui.chess).addTempClass("start"); + ui.placeChess(grid, pos); grid.listen(ui.click.obstacle); - lib.posmap[pos]=grid; + lib.posmap[pos] = grid; game.obstacles.push(grid); return grid; } return null; }, - addTempObstacle:function(x,y,num){ - var node=game.addObstacle(x,y); - if(node){ - game.colorObstacle(node,'blue'); - node.tempObstacle=num; + addTempObstacle: function (x, y, num) { + var node = game.addObstacle(x, y); + if (node) { + game.colorObstacle(node, "blue"); + node.tempObstacle = num; } }, - removeObstacle:function(pos){ - if(get.is.div(pos)){ - pos=pos.dataset.position; + removeObstacle: function (pos) { + if (get.is.div(pos)) { + pos = pos.dataset.position; } - var node=lib.posmap[pos]; - if(node&&game.obstacles.includes(node)){ - game.addVideo('removeObstacle',null,pos); + var node = lib.posmap[pos]; + if (node && game.obstacles.includes(node)) { + game.addVideo("removeObstacle", null, pos); game.obstacles.remove(node); delete lib.posmap[pos]; node.delete(); } }, - moveObstacle:function(pos,x,y){ - if(get.is.div(pos)){ - pos=pos.dataset.position; + moveObstacle: function (pos, x, y) { + if (get.is.div(pos)) { + pos = pos.dataset.position; } - var node=lib.posmap[pos]; - if(node&&game.obstacles.includes(node)){ - pos=parseInt(pos); - var x2=pos%ui.chesswidth+x; - var y2=Math.floor(pos/ui.chesswidth)+y; - if(x2>=ui.chesswidth){ - x2=ui.chesswidth-1; + var node = lib.posmap[pos]; + if (node && game.obstacles.includes(node)) { + pos = parseInt(pos); + var x2 = (pos % ui.chesswidth) + x; + var y2 = Math.floor(pos / ui.chesswidth) + y; + if (x2 >= ui.chesswidth) { + x2 = ui.chesswidth - 1; } - if(y2>=ui.chessheight){ - y2=ui.chessheight-1; + if (y2 >= ui.chessheight) { + y2 = ui.chessheight - 1; } - if(x2<0){ - x2=0; + if (x2 < 0) { + x2 = 0; } - if(y2<0){ - y2=0; + if (y2 < 0) { + y2 = 0; } - var pos2=y2*ui.chesswidth+x2; - if(!lib.posmap[pos2]){ - game.addVideo('moveObstacle',null,[pos,x,y]); - ui.placeChess(node,pos2); + var pos2 = y2 * ui.chesswidth + x2; + if (!lib.posmap[pos2]) { + game.addVideo("moveObstacle", null, [pos, x, y]); + ui.placeChess(node, pos2); delete lib.posmap[pos]; - lib.posmap[pos2]=node; + lib.posmap[pos2] = node; return true; } } return false; }, - colorObstacle:function(pos,color){ - if(get.is.div(pos)){ - pos=pos.dataset.position; + colorObstacle: function (pos, color) { + if (get.is.div(pos)) { + pos = pos.dataset.position; } - var node=lib.posmap[pos]; - if(node&&game.obstacles.includes(node)){ - game.addVideo('colorObstacle',null,[pos,color]); - node.dataset.obscolor=color; + var node = lib.posmap[pos]; + if (node && game.obstacles.includes(node)) { + game.addVideo("colorObstacle", null, [pos, color]); + node.dataset.obscolor = color; } }, - addOverDialog:function(dialog,result){ - if(ui.finishGame){ + addOverDialog: function (dialog, result) { + if (ui.finishGame) { ui.finishGame.remove(); } - dialog.classList.add('center'); - if(_status.mode!='leader') return; - if(result=='战斗胜利'){ - _status.victory=true; - if(!_status.enterArena){ - var div=ui.create.div(); - div.innerHTML='获得'+game.reward+'金'; + dialog.classList.add("center"); + if (_status.mode != "leader") return; + if (result == "战斗胜利") { + _status.victory = true; + if (!_status.enterArena) { + var div = ui.create.div(); + div.innerHTML = "获得" + game.reward + "金"; dialog.add(div); - if(_status.challenge&&_status.challengeMoney<=game.data.dust){ - var div2=ui.create.div(); - div2.style.display='block'; - div2.innerHTML='招降所需招募令:'+_status.challengeMoney+'/'+game.data.dust; + if (_status.challenge && _status.challengeMoney <= game.data.dust) { + var div2 = ui.create.div(); + div2.style.display = "block"; + div2.innerHTML = + "招降所需招募令:" + _status.challengeMoney + "/" + game.data.dust; dialog.add(div2); } game.changeMoney(game.reward); game.saveData(); } - } - else if(_status.zhaoxiang){ - var div=ui.create.div(); - div.innerHTML='招降'+get.translation(_status.zhaoxiang)+'成功'; + } else if (_status.zhaoxiang) { + var div = ui.create.div(); + div.innerHTML = "招降" + get.translation(_status.zhaoxiang) + "成功"; dialog.add(div); } }, - controlOver:function(){ - if(_status.mode=='three'){ - ui.create.control('再战',function(){ - game.saveConfig('continue_name_chess',{ - friend:_status.friendBackup, - enemy:_status.enemyBackup, - color:_status.color + controlOver: function () { + if (_status.mode == "three") { + ui.create.control("再战", function () { + game.saveConfig("continue_name_chess", { + friend: _status.friendBackup, + enemy: _status.enemyBackup, + color: _status.color, }); - game.saveConfig('mode',lib.config.mode); - localStorage.setItem(lib.configprefix+'directstart',true); + game.saveConfig("mode", lib.config.mode); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); }); } - ui.create.control('返回',game.reload); - if(_status.mode!='leader') return; - if(_status.enterArena){ - game.data.arena.acted.length=0; - if(_status.victory){ + ui.create.control("返回", game.reload); + if (_status.mode != "leader") return; + if (_status.enterArena) { + game.data.arena.acted.length = 0; + if (_status.victory) { game.data.arena.win++; - for(var i=0;i=money){ - ui.create.control('招降'+get.translation(_status.challenge),function(){ + if (_status.challenge && !_status.zhaoxiang && _status.victory) { + var money = _status.challengeMoney; + if (game.data.dust >= money) { + ui.create.control("招降" + get.translation(_status.challenge), function () { game.data.character.add(_status.challenge); - game.data.challenge=game.getLeaderList(); + game.data.challenge = game.getLeaderList(); game.changeDust(-money); game.reload(); }); @@ -1781,402 +1851,425 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } } }, - phaseLoopThree:function(player){ - var next=game.createEvent('phaseLoop'); - next.player=player; - next.swap=function(player){ - if(player.side==game.me.side){ + phaseLoopThree: function (player) { + var next = game.createEvent("phaseLoop"); + next.player = player; + (next.swap = function (player) { + if (player.side == game.me.side) { return game.enemyZhu; - } - else{ + } else { return game.me; } - }, - next.setContent(function(){ - 'step 0' - player.classList.add('acted'); - player.phase(); - 'step 1' - if(player!=game.friendZhu&&player!=game.enemyZhu){ - for(var i=0;inum1){ - if(next.side==game.me.side){ - next=game.me; + var num2 = game.players.length - num1; + if (num2 > num1) { + if (next.side == game.me.side) { + next = game.me; } var str; - if(num2-num1>1){ - str='选择至多'+get.cnNumber(num2-num1)+'个已方角色各摸一张牌' + if (num2 - num1 > 1) { + str = "选择至多" + get.cnNumber(num2 - num1) + "个已方角色各摸一张牌"; + } else { + str = "选择一个已方角色摸一张牌"; } - else{ - str='选择一个已方角色摸一张牌' - } - var nevt=player.chooseTarget(str,function(card,player,target){ - return target.side==player.side; - },[1,num2-num1]); - nevt.ai=function(target){ - return Math.max(1,10-target.countCards('h')); + var nevt = player.chooseTarget( + str, + function (card, player, target) { + return target.side == player.side; + }, + [1, num2 - num1] + ); + nevt.ai = function (target) { + return Math.max(1, 10 - target.countCards("h")); }; - nevt.includeOut=true; - nevt.chessForceAll=true; - } - else{ + nevt.includeOut = true; + nevt.chessForceAll = true; + } else { game.delay(); event.goto(2); } - } - else{ + } else { event.goto(2); } - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { game.asyncDraw(result.targets); } - "step 2" - if(player.side==game.me.side){ - player=game.me; + "step 2"; + if (player.side == game.me.side) { + player = game.me; } - if(player.isDead()){ - for(var i=0;i1){ - var nevt=player.chooseTarget('选择下一个行动的角色',function(card,player,target){ - return target.side==player.side&&!target.classList.contains('acted'); - },true); - nevt.chessForceAll=true; - nevt.includeOut=true; - nevt.ai=function(target){ - var nj=target.countCards('j'); - if(nj){ + if (players.length > 1) { + var nevt = player.chooseTarget( + "选择下一个行动的角色", + function (card, player, target) { + return target.side == player.side && !target.classList.contains("acted"); + }, + true + ); + nevt.chessForceAll = true; + nevt.includeOut = true; + nevt.ai = function (target) { + var nj = target.countCards("j"); + if (nj) { return -nj; } - return Math.max(0,10-target.hp); - } - } - else if(players.length){ - event.decided=players[0]; - } - else{ - event.player=game.findPlayer(function(current){ - return current.side!=player.side; + return Math.max(0, 10 - target.hp); + }; + } else if (players.length) { + event.decided = players[0]; + } else { + event.player = game.findPlayer(function (current) { + return current.side != player.side; }); event.goto(0); } - "step 3" - if(event.decided){ + "step 3"; + if (event.decided) { event.decided.phase(); - event.justacted=event.decided; + event.justacted = event.decided; delete event.decided; - } - else{ - var current=result.targets[0]; + } else { + var current = result.targets[0]; current.phase(); - event.justacted=current; + event.justacted = current; } - "step 4" - event.justacted.classList.add('acted'); + "step 4"; + event.justacted.classList.add("acted"); event.goto(0); - for(var i=0;i'+game.data.money+'金币'); - uiintro.addText('通过战斗或竞技场可获得金币。花费100金币可招募3名随机武将;花费150金币可参加一次竞技场'); - uiintro.add(''+game.data.dust+'招募令'); - uiintro.addText('通过遣返武将或竞技场可获得招募令。挑战武将成功后可通过招募令招募该武将,普通/稀有/史诗/传说武将分别花费40/100/400/1600招募令'); + ui.money = ui.create.div(ui.window); + lib.setIntro(ui.money, function (uiintro) { + uiintro.add('' + game.data.money + "金币"); + uiintro.addText( + "通过战斗或竞技场可获得金币。花费100金币可招募3名随机武将;花费150金币可参加一次竞技场" + ); + uiintro.add('' + game.data.dust + "招募令"); + uiintro.addText( + "通过遣返武将或竞技场可获得招募令。挑战武将成功后可通过招募令招募该武将,普通/稀有/史诗/传说武将分别花费40/100/400/1600招募令" + ); }); - ui.money.innerHTML=''+game.data.dust+''+ - ''+game.data.money+''; - ui.money.style.top='auto'; - ui.money.style.left='auto'; - ui.money.style.right='20px'; - ui.money.style.bottom='15px'; - ui.money.childNodes[0].style.color='rgb(111, 198, 255)'; - ui.money.childNodes[1].style.fontFamily='huangcao'; - ui.money.childNodes[1].style.marginRight='10px'; - ui.money.childNodes[2].style.color='#FFE600'; - ui.money.childNodes[3].style.fontFamily='huangcao'; - ui.money.style.letterSpacing='4px'; - if(get.config('chess_leader_allcharacter')){ - for(var i in lib.rank){ - if(Array.isArray(lib.rank[i])){ - for(var j=0;j" + + game.data.dust + + "" + + "" + + game.data.money + + ""; + ui.money.style.top = "auto"; + ui.money.style.left = "auto"; + ui.money.style.right = "20px"; + ui.money.style.bottom = "15px"; + ui.money.childNodes[0].style.color = "rgb(111, 198, 255)"; + ui.money.childNodes[1].style.fontFamily = "huangcao"; + ui.money.childNodes[1].style.marginRight = "10px"; + ui.money.childNodes[2].style.color = "#FFE600"; + ui.money.childNodes[3].style.fontFamily = "huangcao"; + ui.money.style.letterSpacing = "4px"; + if (get.config("chess_leader_allcharacter")) { + for (var i in lib.rank) { + if (Array.isArray(lib.rank[i])) { + for (var j = 0; j < lib.rank[i].length; j++) { + if (!lib.character[lib.rank[i][j]]) { + lib.rank[i].splice(j--, 1); } } } } - for(var i in lib.rank.rarity){ - if(Array.isArray(lib.rank.rarity[i])){ - for(var j=0;jb?1:-1; - } - return aa>bb?1:-1; }); - if(game.data.character.length==0||!game.data.challenge){ - game.data.character=lib.rank.rarity.common.randomGets(3); - game.data.challenge=game.getLeaderList(); + game.data.character.sort(function (a, b) { + var del = groupSort(a) - groupSort(b); + if (del != 0) return del; + var aa = a, + bb = b; + if (a.indexOf("_") != -1) { + a = a.slice(a.indexOf("_") + 1); + } + if (b.indexOf("_") != -1) { + b = b.slice(b.indexOf("_") + 1); + } + if (a != b) { + return a > b ? 1 : -1; + } + return aa > bb ? 1 : -1; + }); + if (game.data.character.length == 0 || !game.data.challenge) { + game.data.character = lib.rank.rarity.common.randomGets(3); + game.data.challenge = game.getLeaderList(); game.saveData(); } - var fixButton=function(button){ - var rarity=game.getRarity(button.link); - if(rarity!='common'){ - var intro=button.node.intro; - intro.classList.add('showintro'); - intro.style.fontFamily='yuanli'; - intro.style.fontSize='20px'; - intro.style.top='82px'; - intro.style.left='2px'; - switch(rarity){ - case 'rare':intro.dataset.nature='thunderm';break; - case 'epic':intro.dataset.nature='metalm';break; - case 'legend':intro.dataset.nature='orangem';break; + var fixButton = function (button) { + var rarity = game.getRarity(button.link); + if (rarity != "common") { + var intro = button.node.intro; + intro.classList.add("showintro"); + intro.style.fontFamily = "yuanli"; + intro.style.fontSize = "20px"; + intro.style.top = "82px"; + intro.style.left = "2px"; + switch (rarity) { + case "rare": + intro.dataset.nature = "thunderm"; + break; + case "epic": + intro.dataset.nature = "metalm"; + break; + case "legend": + intro.dataset.nature = "orangem"; + break; } - intro.innerHTML=get.translation(rarity); + intro.innerHTML = get.translation(rarity); } - } - game.leaderLord=['leader_caocao','leader_liubei','leader_sunquan','leader_yuri']; - var dialog1=ui.create.dialog('选择君主','hidden'); - event.dialog1=dialog1; - dialog1.classList.add('fullheight'); - dialog1.classList.add('halfleft'); - dialog1.classList.add('fixed'); - dialog1.classList.add('pointerbutton'); - dialog1.add([game.leaderLord,'character']); + }; + game.leaderLord = ["leader_caocao", "leader_liubei", "leader_sunquan", "leader_yuri"]; + var dialog1 = ui.create.dialog("选择君主", "hidden"); + event.dialog1 = dialog1; + dialog1.classList.add("fullheight"); + dialog1.classList.add("halfleft"); + dialog1.classList.add("fixed"); + dialog1.classList.add("pointerbutton"); + dialog1.add([game.leaderLord, "character"]); var i; - for(i=0;ib?1:-1; + namecapt.sort(function (a, b) { + return a > b ? 1 : -1; }); - captnode.innerHTML=''; - for(i=0;i3&&selected.character.length){ - event.removeCharacter.addTempClass('controlpressdownx',500); - event.removeCharacter.classList.remove('disabled'); + if (game.data.character.length > 3 && selected.character.length) { + event.removeCharacter.addTempClass("controlpressdownx", 500); + event.removeCharacter.classList.remove("disabled"); } - if(game.data.money<150&&!game.data._arena){ - event.enterArena.classList.add('disabled'); + if (game.data.money < 150 && !game.data._arena) { + event.enterArena.classList.add("disabled"); + } else { + event.enterArena.addTempClass("controlpressdownx", 500); + event.enterArena.classList.remove("disabled"); } - else{ - event.enterArena.addTempClass('controlpressdownx',500); - event.enterArena.classList.remove('disabled'); - } - if(game.data.money<100){ - event.addCharacter.classList.add('disabled'); - } - else{ - event.addCharacter.addTempClass('controlpressdownx',500); - event.addCharacter.classList.remove('disabled'); + if (game.data.money < 100) { + event.addCharacter.classList.add("disabled"); + } else { + event.addCharacter.addTempClass("controlpressdownx", 500); + event.addCharacter.classList.remove("disabled"); } initcapt(); - },200); - },200); - },500); + }, 200); + }, 200); + }, 500); }; - event.addCharacter=ui.create.control('招募','nozoom',zhaomu2); - if(game.data.money<150&&!game.data._arena){ - event.enterArena.classList.add('disabled'); + event.addCharacter = ui.create.control("招募", "nozoom", zhaomu2); + if (game.data.money < 150 && !game.data._arena) { + event.enterArena.classList.add("disabled"); } - if(game.data.money<100){ - event.addCharacter.classList.add('disabled'); + if (game.data.money < 100) { + event.addCharacter.classList.add("disabled"); } - var qianfan=function(){ - if(_status.kaibao) return; - if(game.data.character.length<=3) return; - if(!selected.character.length) return; + var qianfan = function () { + if (_status.kaibao) return; + if (game.data.character.length <= 3) return; + if (!selected.character.length) return; // _status.chessclicked=true; // _status.qianfan=true; // event.enterArena.style.opacity=0.5; // event.addCharacter.style.opacity=0.5; // event.fight.style.opacity=0.5; - var current=selected.character.slice(0); + var current = selected.character.slice(0); clearSelected(); - var maxq=game.data.character.length-3; - if(current.length<=maxq){ - for(var i=0;i=100){ - event.addCharacter.addTempClass('controlpressdownx',500); - event.addCharacter.classList.remove('disabled'); + if (game.data.money >= 100) { + event.addCharacter.addTempClass("controlpressdownx", 500); + event.addCharacter.classList.remove("disabled"); } - if(game.data.money>=150){ - event.enterArena.addTempClass('controlpressdownx',500); - event.enterArena.classList.remove('disabled'); + if (game.data.money >= 150) { + event.enterArena.addTempClass("controlpressdownx", 500); + event.enterArena.classList.remove("disabled"); } node.delete(); dialog1.buttons.remove(node); @@ -2726,291 +2862,398 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ initcapt(); } }; - event.removeCharacter=ui.create.control('遣返','nozoom',qianfan); - event.removeCharacter.classList.add('disabled'); - event.fight=ui.create.control('开始战斗','nozoom',function(){ - if(_status.kaibao||_status.qianfan) return; - if(selected.challenge.length){ - var cname=selected.challenge[0].link; - var rarity=game.getRarity(cname); - switch(rarity){ - case 'common':rarity=40;break; - case 'rare':rarity=100;break; - case 'epic':rarity=400;break; - case 'legend':rarity=1600;break; + event.removeCharacter = ui.create.control("遣返", "nozoom", qianfan); + event.removeCharacter.classList.add("disabled"); + event.fight = ui.create.control("开始战斗", "nozoom", function () { + if (_status.kaibao || _status.qianfan) return; + if (selected.challenge.length) { + var cname = selected.challenge[0].link; + var rarity = game.getRarity(cname); + switch (rarity) { + case "common": + rarity = 40; + break; + case "rare": + rarity = 100; + break; + case "epic": + rarity = 400; + break; + case "legend": + rarity = 1600; + break; } - if(!confirm('即将挑战'+get.translation(cname)+',战斗胜利后可消耗'+rarity+'招募令招募该武将,无论是否招募,挑战列表将被刷新。是否继续?')){ + if ( + !confirm( + "即将挑战" + + get.translation(cname) + + ",战斗胜利后可消耗" + + rarity + + "招募令招募该武将,无论是否招募,挑战列表将被刷新。是否继续?" + ) + ) { return; } } - _status.enemylist=[]; - _status.mylist=[]; - if(selected.lord.length){ + _status.enemylist = []; + _status.mylist = []; + if (selected.lord.length) { _status.mylist.push(selected.lord[0].link); - _status.lord=selected.lord[0].link; + _status.lord = selected.lord[0].link; } - if(selected.character.length){ - for(var i=0;i0){ - switch(difficulty){ - case 'leader_easy':reward+=10*numdel;break; - case 'leader_medium':reward+=20*numdel;break; - case 'leader_hard':reward+=40*numdel;break; + if (numdel > 0) { + switch (difficulty) { + case "leader_easy": + reward += 10 * numdel; + break; + case "leader_medium": + reward += 20 * numdel; + break; + case "leader_hard": + reward += 40 * numdel; + break; } } - var punish=0; - for(var i=0;i<_status.mylist.length;i++){ - switch(get.rank(_status.mylist[i])){ - case 's':punish+=25;break; - case 'ap':punish+=20;break; - case 'a':punish+=16;break; - case 'am':punish+=12;break; - case 'bp':punish+=9;break; - case 'b':punish+=7;break; - case 'bm':punish+=5;break; - case 'c':punish+=3;break; - case 'd':punish+=2;break; + var punish = 0; + for (var i = 0; i < _status.mylist.length; i++) { + switch (get.rank(_status.mylist[i])) { + case "s": + punish += 25; + break; + case "ap": + punish += 20; + break; + case "a": + punish += 16; + break; + case "am": + punish += 12; + break; + case "bp": + punish += 9; + break; + case "b": + punish += 7; + break; + case "bm": + punish += 5; + break; + case "c": + punish += 3; + break; + case "d": + punish += 2; + break; } } - if(numdel<0){ - switch(difficulty){ - case 'leader_easy':punish-=5*numdel;break; - case 'leader_medium':punish-=10*numdel;break; - case 'leader_hard':punish-=20*numdel;break; + if (numdel < 0) { + switch (difficulty) { + case "leader_easy": + punish -= 5 * numdel; + break; + case "leader_medium": + punish -= 10 * numdel; + break; + case "leader_hard": + punish -= 20 * numdel; + break; } } - game.reward=Math.max(3*_status.enemylist.length,reward-punish); - if(!_status.lord){ - switch(difficulty){ - case 'leader_easy':game.reward+=10;break; - case 'leader_medium':game.reward+=20;break; - case 'leader_hard':game.reward+=40;break; + game.reward = Math.max(3 * _status.enemylist.length, reward - punish); + if (!_status.lord) { + switch (difficulty) { + case "leader_easy": + game.reward += 10; + break; + case "leader_medium": + game.reward += 20; + break; + case "leader_hard": + game.reward += 40; + break; } } game.resume(); }); - event.custom.replace.button=function(button){ - if(_status.kaibao) return; - if(button.classList.contains('unselectable')&& - !button.classList.contains('selected')) return; - _status.chessclicked=true; - button.classList.toggle('selected'); - if(button.classList.contains('selected')){ + event.custom.replace.button = function (button) { + if (_status.kaibao) return; + if ( + button.classList.contains("unselectable") && + !button.classList.contains("selected") + ) + return; + _status.chessclicked = true; + button.classList.toggle("selected"); + if (button.classList.contains("selected")) { selected[button.area].add(button); - } - else{ + } else { selected[button.area].remove(button); } - switch(button.area){ - case 'lord':{ - for(var i=0;i5)|| - (_status.qianfan&&selected.character.length>=maxq)){ - dialog1.buttons[i].classList.add('unselectable'); - } - else{ - dialog1.buttons[i].classList.remove('unselectable'); + case "character": { + for (var i = 0; i < dialog1.buttons.length; i++) { + if (dialog1.buttons[i].area == "character") { + var maxq = game.data.character.length - 3; + if ( + (!_status.qianfan && selected.character.length > 5) || + (_status.qianfan && selected.character.length >= maxq) + ) { + dialog1.buttons[i].classList.add("unselectable"); + } else { + dialog1.buttons[i].classList.remove("unselectable"); } } } break; } - case 'difficulty':case 'number':{ - for(var i=0;i3){ - event.removeCharacter.addTempClass('controlpressdownx',500); - event.removeCharacter.classList.remove('disabled'); - } - else{ - event.removeCharacter.classList.add('disabled'); + if (selected.character.length && game.data.character.length > 3) { + event.removeCharacter.addTempClass("controlpressdownx", 500); + event.removeCharacter.classList.remove("disabled"); + } else { + event.removeCharacter.classList.add("disabled"); } }; - event.custom.add.window=function(){ - if(!_status.kaibao){ - var glows=document.querySelectorAll('.button.glow2'); - for(var i=0;i=100){ - event.addCharacter.addTempClass('controlpressdownx',500); - event.addCharacter.classList.remove('disabled'); + if (_status.qianfan) { + _status.qianfan = false; + event.removeCharacter.replace("遣返", qianfan); + if (game.data.money >= 100) { + event.addCharacter.addTempClass("controlpressdownx", 500); + event.addCharacter.classList.remove("disabled"); + } else { + event.addCharacter.classList.add("disabled"); } - else{ - event.addCharacter.classList.add('disabled'); + if (game.data.money >= 150 || game.data._arena) { + event.enterArena.addTempClass("controlpressdownx", 500); + event.enterArena.classList.remove("disabled"); + } else { + event.enterArena.classList.add("disabled"); } - if(game.data.money>=150||game.data._arena){ - event.enterArena.addTempClass('controlpressdownx',500); - event.enterArena.classList.remove('disabled'); - } - else{ - event.enterArena.classList.add('disabled'); - } - event.fight.style.opacity=1; + event.fight.style.opacity = 1; } clearSelected(); }; lib.init.onfree(); game.pause(); - 'step 2' - if(!game.data.arena){ + "step 2"; + if (!game.data.arena) { event.dialog1.close(); event.dialog2.close(); event.fight.close(); @@ -3018,501 +3261,565 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ event.addCharacter.close(); event.removeCharacter.close(); } - ui.arena.classList.add('leaderhide'); + ui.arena.classList.add("leaderhide"); ui.money.hide(); game.delay(); - 'step 3' - ui.arena.classList.remove('leaderhide'); - if(!_status.enterArena){ + "step 3"; + ui.arena.classList.remove("leaderhide"); + if (!_status.enterArena) { ui.wuxie.show(); ui.auto.show(); - ui.control.style.top=''; - if(!get.is.safari()){ - ui.control.style.transition=''; - ui.control.style.display='none'; + ui.control.style.top = ""; + if (!get.is.safari()) { + ui.control.style.transition = ""; + ui.control.style.display = "none"; } event.finish(); - } - else{ - game.minskin=false; - event.arenanodes=[]; - event.arenachoice=[]; - event.arenachoicenodes=[]; - event.arrangeNodes=function(){ - var num=event.arenachoicenodes.length; - var width=num*75+(num-1)*8; - for(var i=0;i=3){ - for(var i=0;i= 3) { + for (var i = 0; i < event.arenachoicenodes.length; i++) { + if (!event.arenachoicenodes[i].classList.contains("dead")) { + event.arenachoicenodes[i].classList.add("unselectable"); } } - } - else{ - for(var i=0;i胜'; - victory.style.top='auto'; - victory.style.left='auto'; - victory.style.right='20px'; - victory.style.bottom='15px'; - victory.style.fontSize='30px' - victory.style.fontFamily='huangcao'; - victory.firstChild.style.marginRight='5px'; + var victory = ui.create.div().hide(); + victory.innerHTML = "" + game.data.arena.win + "胜"; + victory.style.top = "auto"; + victory.style.left = "auto"; + victory.style.right = "20px"; + victory.style.bottom = "15px"; + victory.style.fontSize = "30px"; + victory.style.fontFamily = "huangcao"; + victory.firstChild.style.marginRight = "5px"; ui.window.appendChild(victory); ui.refresh(victory); victory.show(); - event.checkPrize=function(){ + event.checkPrize = function () { // event.kaibao=true; - event.prize=[]; - event.turnCard2=function(){ - if(this.turned) return; - _status.chessclicked=true; - this.turned=true; - var node=this; - setTimeout(function(){ - node.turned2=true; - },1000); - if(node.name=='chess_coin'||node.name=='chess_dust'){ - node.style.transition='all 0s'; - node.style.transform='none'; - node.style.overflow='visible'; - node.style.background='none'; - node.style.boxShadow='none'; - var div=ui.create.div(node); - div.style.transition='all 0s'; - if(node.name=='chess_coin'){ - div.innerHTML=''+node.num+''; - div.firstChild.style.color='rgb(255, 230, 0)'; + event.prize = []; + event.turnCard2 = function () { + if (this.turned) return; + _status.chessclicked = true; + this.turned = true; + var node = this; + setTimeout(function () { + node.turned2 = true; + }, 1000); + if (node.name == "chess_coin" || node.name == "chess_dust") { + node.style.transition = "all 0s"; + node.style.transform = "none"; + node.style.overflow = "visible"; + node.style.background = "none"; + node.style.boxShadow = "none"; + var div = ui.create.div(node); + div.style.transition = "all 0s"; + if (node.name == "chess_coin") { + div.innerHTML = "" + node.num + ""; + div.firstChild.style.color = "rgb(255, 230, 0)"; node.$coin(); - } - else{ - div.innerHTML=''+node.num+''; - div.firstChild.style.color='rgb(111, 198, 255)'; - div.firstChild.style.marginRight='3px'; + } else { + div.innerHTML = "" + node.num + ""; + div.firstChild.style.color = "rgb(111, 198, 255)"; + div.firstChild.style.marginRight = "3px"; node.$dust(); } - div.style.fontFamily='huangcao'; - div.style.fontSize='50px'; - div.style.top='40px'; - div.style.letterSpacing='8px'; - div.style.whiteSpace='nowrap'; + div.style.fontFamily = "huangcao"; + div.style.fontSize = "50px"; + div.style.top = "40px"; + div.style.letterSpacing = "8px"; + div.style.whiteSpace = "nowrap"; // div.dataset.nature='metal'; return; } - node.style.transition='all ease-in 0.3s'; - node.style.transform='perspective(1200px) rotateY(270deg) translateX(150px)'; - var onEnd=function(){ + node.style.transition = "all ease-in 0.3s"; + node.style.transform = "perspective(1200px) rotateY(270deg) translateX(150px)"; + var onEnd = function () { node.init(node.name); - node.node.avatar.style.display=''; - if(node.rarity){ - node.node.intro.innerHTML=get.translation(node.rarity); - node.node.intro.classList.add('showintro'); + node.node.avatar.style.display = ""; + if (node.rarity) { + node.node.intro.innerHTML = get.translation(node.rarity); + node.node.intro.classList.add("showintro"); } - node.classList.add('playerflip'); - node.style.transform='none'; - node.style.transition=''; - if(lib.config.animation&&!lib.config.low_performance){ - setTimeout(function(){ - switch(game.getRarity(node.name)){ - case 'rare':node.$rare();break; - case 'epic':node.$epic();break; - case 'legend':node.$legend();break; + node.classList.add("playerflip"); + node.style.transform = "none"; + node.style.transition = ""; + if (lib.config.animation && !lib.config.low_performance) { + setTimeout(function () { + switch (game.getRarity(node.name)) { + case "rare": + node.$rare(); + break; + case "epic": + node.$epic(); + break; + case "legend": + node.$legend(); + break; } - },150); + }, 150); } }; node.listenTransition(onEnd); }; - setTimeout(function(){ + setTimeout(function () { nodes[0].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[1].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[2].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[3].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[4].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[5].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[6].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[7].delete(); - },400+Math.random()*300); - setTimeout(function(){ + }, 400 + Math.random() * 300); + setTimeout(function () { nodes[8].delete(); - },400+Math.random()*300); - setTimeout(function(){ - var prize=new Array(6); - var map=[1,2,3,4,5]; - var ccount=3; - var win=game.data.arena.win; + }, 400 + Math.random() * 300); + setTimeout(function () { + var prize = new Array(6); + var map = [1, 2, 3, 4, 5]; + var ccount = 3; + var win = game.data.arena.win; var prizeValue; - switch(win){ - case 0:prizeValue=100;break; - case 1:prizeValue=120;break; - case 2:prizeValue=150;break; - case 3:prizeValue=190;break; - case 4:prizeValue=240;break; - case 5:prizeValue=300;break; - case 6:prizeValue=370;break; - case 7:prizeValue=450;break; - case 8:prizeValue=540;break; - case 9:prizeValue=640;break; - case 10:prizeValue=750;break; - case 11:prizeValue=870;break; - case 12:prizeValue=1000;break; + switch (win) { + case 0: + prizeValue = 100; + break; + case 1: + prizeValue = 120; + break; + case 2: + prizeValue = 150; + break; + case 3: + prizeValue = 190; + break; + case 4: + prizeValue = 240; + break; + case 5: + prizeValue = 300; + break; + case 6: + prizeValue = 370; + break; + case 7: + prizeValue = 450; + break; + case 8: + prizeValue = 540; + break; + case 9: + prizeValue = 640; + break; + case 10: + prizeValue = 750; + break; + case 11: + prizeValue = 870; + break; + case 12: + prizeValue = 1000; + break; } - if(Math.random()<0.4){ - if(win>=3&&Math.random()<0.5){ - ccount=4; - prizeValue-=33; - } - else{ - ccount=2; - prizeValue+=33; + if (Math.random() < 0.4) { + if (win >= 3 && Math.random() < 0.5) { + ccount = 4; + prizeValue -= 33; + } else { + ccount = 2; + prizeValue += 33; } } - prizeValue-=100; - while(ccount--){ - prize[map.randomRemove()]=game.getLeaderCharacter(); + prizeValue -= 100; + while (ccount--) { + prize[map.randomRemove()] = game.getLeaderCharacter(); } - if(map.length){ - prizeValue/=map.length; + if (map.length) { + prizeValue /= map.length; } - while(map.length){ - var val=Math.round((Math.random()*0.4+0.8)*prizeValue); - if(Math.random()<0.7){ - prize[map.shift()]=['chess_coin',Math.max(Math.ceil(Math.random()*5),val)]; - } - else{ - val=Math.round(val/3); - prize[map.shift()]=['chess_dust',Math.max(Math.ceil(Math.random()*3),val)]; + while (map.length) { + var val = Math.round((Math.random() * 0.4 + 0.8) * prizeValue); + if (Math.random() < 0.7) { + prize[map.shift()] = [ + "chess_coin", + Math.max(Math.ceil(Math.random() * 5), val), + ]; + } else { + val = Math.round(val / 3); + prize[map.shift()] = [ + "chess_dust", + Math.max(Math.ceil(Math.random() * 3), val), + ]; } } - for(var i=1;i=4&&!bosses.childNodes[i].classList.contains('glow')){ - bosses.childNodes[i].classList.add('forbidden'); - } - else{ - bosses.childNodes[i].classList.remove('forbidden'); + for (var i = 0; i < bosses.childElementCount; i++) { + if (num >= 4 && !bosses.childNodes[i].classList.contains("glow")) { + bosses.childNodes[i].classList.add("forbidden"); + } else { + bosses.childNodes[i].classList.remove("forbidden"); } } - if(num){ - if(!event.asboss){ - event.asboss=ui.create.control('应战',function(){ - _status.boss=true; + if (num) { + if (!event.asboss) { + event.asboss = ui.create.control("应战", function () { + _status.boss = true; ui.click.ok(); }); } - } - else{ - if(event.asboss){ + } else { + if (event.asboss) { event.asboss.close(); delete event.asboss; } @@ -3718,193 +4019,246 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ addToButton(); }; - var clickedJiange=false; - var clickJiange=function(){ - clickedJiange=true; - if(this.classList.contains('glow2')){ - this.classList.remove('glow2'); - } - else{ - this.classList.add('glow2'); + var clickedJiange = false; + var clickJiange = function () { + clickedJiange = true; + if (this.classList.contains("glow2")) { + this.classList.remove("glow2"); + } else { + this.classList.add("glow2"); } addToButton(); }; - for(var i=0;inum){ - for(var i=num;i num) { + for (var i = num; i < dialog.buttons.length; i++) { dialog.buttons[i].remove(); } dialog.buttons.splice(num); - } - else if(dialog.buttons.length2) return false; - var xy1=event.source.getXY(); - var xy2=player.getXY(); - var dx=xy2[0]-xy1[0]; - var dy=xy2[1]-xy1[1]; + _attackmove: { + trigger: { player: "damage" }, + silent: true, + priority: 50, + filter: function (event, player) { + if (!event.source) return false; + if (get.distance(event.source, player, "pure") > 2) return false; + var xy1 = event.source.getXY(); + var xy2 = player.getXY(); + var dx = xy2[0] - xy1[0]; + var dy = xy2[1] - xy1[1]; // if(dx*dy!=0) return false; - if(dx==0&&Math.abs(dy)==2){ - dy/=2; + if (dx == 0 && Math.abs(dy) == 2) { + dy /= 2; } - if(dy==0&&Math.abs(dx)==2){ - dx/=2; + if (dy == 0 && Math.abs(dx) == 2) { + dx /= 2; } - return player.movable(dx,dy); + return player.movable(dx, dy); }, - content:function(){ - var xy1=trigger.source.getXY(); - var xy2=player.getXY(); - var dx=xy2[0]-xy1[0]; - var dy=xy2[1]-xy1[1]; - if(dx==0&&Math.abs(dy)==2){ - dy/=2; + content: function () { + var xy1 = trigger.source.getXY(); + var xy2 = player.getXY(); + var dx = xy2[0] - xy1[0]; + var dy = xy2[1] - xy1[1]; + if (dx == 0 && Math.abs(dy) == 2) { + dy /= 2; } - if(dy==0&&Math.abs(dx)==2){ - dx/=2; + if (dy == 0 && Math.abs(dx) == 2) { + dx /= 2; } - if(player.movable(dx,dy)){ - player.move(dx,dy); + if (player.movable(dx, dy)) { + player.move(dx, dy); } - } + }, }, - dubiaoxianjing:{ - global:'dubiaoxianjing2' + dubiaoxianjing: { + global: "dubiaoxianjing2", }, - dubiaoxianjing2:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - if(player.hp<=1) return false; - for(var i=0;i1) return false; - for(var i=0;i 1) return false; + for (var i = 0; i < game.treasures.length; i++) { + if (game.treasures[i].name == "treasure_wuyashenxiang") { + return get.chessDistance(game.treasures[i], player) <= 3; } } return false; }, - content:function(){ - 'step 0' - var source=null; - for(var i=0;inh) return false; + shenpanxianjing2: { + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + var nh = player.countCards("h"); + if (!nh) return false; + for (var i = 0; i < game.treasures.length; i++) { + if (game.treasures[i].name == "treasure_shenpanxianjing") { + for (var j = 0; j < game.players.length; j++) { + if (game.players[j].countCards("h") > nh) return false; } return true; } } return false; }, - content:function(){ - 'step 0' - var source=null; - for(var i=0;i3; + shenmidiaoxiang2: { + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + for (var i = 0; i < game.treasures.length; i++) { + if (game.treasures[i].name == "treasure_shenmidiaoxiang") { + return ( + player.canMoveTowards(game.treasures[i]) && + get.chessDistance(game.treasures[i], player) > 3 + ); } } return false; }, - content:function(){ - 'step 0' - var source=null; - for(var i=0;igame.data.arena.dead.length; }, - direct:true, - delay:0, - preservecancel:true, - content:function(){ - "step 0" - var list=game.data.arena.arenachoice.slice(0); - for(var i=0;i game.data.arena.dead.length + ); + }, + direct: true, + delay: 0, + preservecancel: true, + content: function () { + "step 0"; + var list = game.data.arena.arenachoice.slice(0); + for (var i = 0; i < game.data.arena.dead.length; i++) { list.remove(game.data.arena.dead[i]); } - event.dialog=ui.create.dialog('选择一个出场武将',[list,'character']); + event.dialog = ui.create.dialog("选择一个出场武将", [list, "character"]); game.pause(); - _status.imchoosing=true; - event.custom.replace.button=function(button){ - event.choice=button.link; + _status.imchoosing = true; + event.custom.replace.button = function (button) { + event.choice = button.link; game.resume(); + }; + event.custom.replace.confirm = game.resume; + event.switchToAuto = game.resume; + "step 1"; + if (ui.confirm) { + ui.confirm.classList.add("removing"); } - event.custom.replace.confirm=game.resume; - event.switchToAuto=game.resume; - "step 1" - if(ui.confirm){ - ui.confirm.classList.add('removing'); - } - _status.imchoosing=false; + _status.imchoosing = false; event.dialog.close(); - if(event.choice){ - var name=event.choice; + if (event.choice) { + var name = event.choice; game.addChessPlayer(name); game.data.arena.dead.push(name); game.saveData(); - if(!_status.arenaAdd){ - _status.arenaAdd=[]; + if (!_status.arenaAdd) { + _status.arenaAdd = []; } _status.arenaAdd.push(name); game.delay(); - } - else{ - player.getStat('skill').arenaAdd--; + } else { + player.getStat("skill").arenaAdd--; } }, }, - leader_zhaoxiang:{ - unique:true, - enable:'phaseUse', - usable:1, - promptfunc:function(event,player){ - var targets=[]; - var skill=lib.skill.leader_zhaoxiang; - for(var i=0;i

                        ' - for(var i=0;i'+ - (skill.chance(targets[i],player)*100).toFixed(2)+'%
                        '; + var str = lib.translate.leader_zhaoxiang_info; + if (targets.length) { + str = + '

                        ⚑ ' + + game.data.dust + + '

                        '; + for (var i = 0; i < targets.length; i++) { + str += + '' + + get.translation(targets[i]) + + ':' + + (skill.chance(targets[i], player) * 100).toFixed(2) + + "%
                        "; } - str+='

                        ' + str += "

                        "; } return str; }, - chance:function(target,player){ + chance: function (target, player) { var chance; - var renyi=player.hasSkill('leader_renyi'); - switch(target.hp){ - case 1:chance=0.7;break; - case 2:chance=0.4;break; - default:chance=0.2;break; + var renyi = player.hasSkill("leader_renyi"); + switch (target.hp) { + case 1: + chance = 0.7; + break; + case 2: + chance = 0.4; + break; + default: + chance = 0.2; + break; } - switch(target.countCards('he')){ - case 0:break; - case 1:chance/=1.2;break; - case 2:chance/=1.4;break; - case 3:chance/=1.7;break; - default:chance/=2;break; + switch (target.countCards("he")) { + case 0: + break; + case 1: + chance /= 1.2; + break; + case 2: + chance /= 1.4; + break; + case 3: + chance /= 1.7; + break; + default: + chance /= 2; + break; } - switch(game.getRarity(target.name)){ - case 'common':{ - if(renyi) chance*=2; + switch (game.getRarity(target.name)) { + case "common": { + if (renyi) chance *= 2; break; } - case 'rare':{ - chance/=2; - if(renyi) chance*=2; + case "rare": { + chance /= 2; + if (renyi) chance *= 2; break; } - case 'epic':{ - chance/=5; - if(renyi) chance*=1.5; + case "epic": { + chance /= 5; + if (renyi) chance *= 1.5; break; } - case 'legend':{ - chance/=15; - if(renyi) chance*=1.2; + case "legend": { + chance /= 15; + if (renyi) chance *= 1.2; break; } } - return Math.min(1,chance); + return Math.min(1, chance); }, - filter:function(){ - return game.data.dust>=10; + filter: function () { + return game.data.dust >= 10; }, - filterTarget:function(card,player,target){ - return game.isChessNeighbour(player,target)&&!game.data.character.includes(target.name); + filterTarget: function (card, player, target) { + return ( + game.isChessNeighbour(player, target) && !game.data.character.includes(target.name) + ); }, - content:function(){ - var chance=lib.skill.leader_zhaoxiang.chance(target,player); + content: function () { + var chance = lib.skill.leader_zhaoxiang.chance(target, player); game.changeDust(-10); - if(Math.random()0; }, - content:function(){ - switch(_status.difficulty){ - case 'leader_easy':game.reward+=2*trigger.num;break; - case 'leader_medium':game.reward+=4*trigger.num;break; - case 'leader_hard':game.reward+=6*trigger.num;break; + }, + leader_xiaoxiong: { + unique: true, + forced: true, + trigger: { source: "damageSource" }, + filter: function (event, player) { + return event.num > 0; + }, + content: function () { + switch (_status.difficulty) { + case "leader_easy": + game.reward += 2 * trigger.num; + break; + case "leader_medium": + game.reward += 4 * trigger.num; + break; + case "leader_hard": + game.reward += 6 * trigger.num; + break; } - } - }, - leader_renyi:{ - unique:true, - }, - leader_mouduan:{ - unique:true, - global:'leader_mouduan2' - }, - leader_mouduan2:{ - mod:{ - chessMove:function(player,current){ - if(player.side&&player.name!=_status.lord) return current+1; - } - } - }, - leader_zhenlve:{ - trigger:{global:'useCard1'}, - unique:true, - charlotte:true, - firstDo:true, - forced:true, - popup:false, - filter:function(event,player){ - return get.type(event.card)=='trick'&&event.player.isFriendOf(player); - }, - content:function(){ - trigger.nowuxie=true; }, }, - tongshuai:{ - unique:true, - forbid:['guozhan'], - init:function(player){ - player.storage.tongshuai={ - list:[], - owned:{}, - player:player, - get:function(num){ - if(typeof num!='number') num=1; - var player=this.player; - while(num--){ - var name=player.storage.tongshuai.unowned.shift(); - if(!name) return; - var skills=lib.character[name][3].slice(0); - for(var i=0;i
                        【'+get.translation(skill)+ - '】
                        '+lib.translate[skill+'_info']+'
                        '); + var skill = player.additionalSkills.tongshuai[0]; + if (skill) { + dialog.add( + '
                        【' + + get.translation(skill) + + "】
                        " + + lib.translate[skill + "_info"] + + "
                        " + ); } - } + }, }, // mark:true }, - tongshuai1:{ - trigger:{global:'gameStart'}, - forced:true, - popup:false, - priority:10, - content:function(){ - for(var i=0;i1){ + if (player.storage.tongshuai.unowned.length > 1) { player.storage.tongshuai.get(2); - } - else if(player.storage.tongshuai.unowned.length==1){ + } else if (player.storage.tongshuai.unowned.length == 1) { player.storage.tongshuai.get(); + } else { + player.removeSkill("tongshuai"); } - else{ - player.removeSkill('tongshuai'); - } - } + }, }, - tongshuai2:{ - audio:2, - trigger:{player:['phaseBegin','phaseEnd'],global:'gameStart'}, - filter:function(event,player,name){ - if(!player.hasSkill('tongshuai')) return false; - if(name=='phaseBegin'&&game.phaseNumber==1) return false; + tongshuai2: { + audio: 2, + trigger: { player: ["phaseBegin", "phaseEnd"], global: "gameStart" }, + filter: function (event, player, name) { + if (!player.hasSkill("tongshuai")) return false; + if (name == "phaseBegin" && game.phaseNumber == 1) return false; return true; }, - priority:-9, - forced:true, - popup:false, - content:function(){ - var slist=player.storage.tongshuai.owned; - var list=[]; - for(var i in slist){ + priority: -9, + forced: true, + popup: false, + content: function () { + var slist = player.storage.tongshuai.owned; + var list = []; + for (var i in slist) { list.push(i); } - if(event.isMine()){ - event.dialog=ui.create.dialog('选择获得一项技能',[list,'character']); - if(trigger.name=='game'){ - event.control=ui.create.control(); + if (event.isMine()) { + event.dialog = ui.create.dialog("选择获得一项技能", [list, "character"]); + if (trigger.name == "game") { + event.control = ui.create.control(); + } else { + event.control = ui.create.control(["cancel"]); } - else{ - event.control=ui.create.control(['cancel']); - } - event.clickControl=function(link){ - if(link!='cancel'){ - var currentname=event.dialog.querySelector('.selected.button').link; - var mark=player.marks.tongshuai; - if(!mark){ - player.markSkill('tongshuai'); - mark=player.marks.tongshuai; - if(mark.firstChild){ + event.clickControl = function (link) { + if (link != "cancel") { + var currentname = event.dialog.querySelector(".selected.button").link; + var mark = player.marks.tongshuai; + if (!mark) { + player.markSkill("tongshuai"); + mark = player.marks.tongshuai; + if (mark.firstChild) { mark.firstChild.remove(); } } - mark.setBackground(currentname,'character'); + mark.setBackground(currentname, "character"); - player.addAdditionalSkill('tongshuai',link); - game.addVideo('chess_tongshuai_skill',player,[currentname,link]); - player.logSkill('tongshuai2'); - game.log(player,'获得技能','【'+get.translation(link)+'】'); + player.addAdditionalSkill("tongshuai", link); + game.addVideo("chess_tongshuai_skill", player, [currentname, link]); + player.logSkill("tongshuai2"); + game.log(player, "获得技能", "【" + get.translation(link) + "】"); player.popup(link); - for(var i=0;i0; }, - content:function(){ - player.storage.tongshuai.get(); - } }, - cangming:{ - enable:'phaseUse', - usable:1, - unique:true, - filter:function(event,player){ - if(player.isTurnedOver()) return false; - var suits=[]; - var hs=player.getCards('h'); - for(var i=0;i 0 + ); + }, + content: function () { + player.storage.tongshuai.get(); + }, + }, + cangming: { + enable: "phaseUse", + usable: 1, + unique: true, + filter: function (event, player) { + if (player.isTurnedOver()) return false; + var suits = []; + var hs = player.getCards("h"); + for (var i = 0; i < hs.length; i++) { suits.add(get.suit(hs[i])); - if(suits.length>=4) return true; + if (suits.length >= 4) return true; } return false; }, - filterCard:function(card){ - var suit=get.suit(card); - for(var i=0;i1) break; + if (num > 1) break; } } - if(num<=1) return; - if(_status.currentPhase==player&&player.countCards('h')=6){ - if(typeof card=='string') return; - if(card.name=='wuzhong') return; - if(card.name=='shunshou') return; - if(card.name=='yuanjiao') return; - if(card.name=='yiyi') return; - if(!player.hasSkill('cangming2')) return 'zeroplayertarget'; + if (num <= 1) return; + if ( + _status.currentPhase == player && + player.countCards("h") < player.hp && + player.hp >= 6 + ) { + if (typeof card == "string") return; + if (card.name == "wuzhong") return; + if (card.name == "shunshou") return; + if (card.name == "yuanjiao") return; + if (card.name == "yiyi") return; + if (!player.hasSkill("cangming2")) return "zeroplayertarget"; } - } + }, }, - result:{ - target:function(player){ - var num=0; - for(var i=0;i1) break; + if (num > 1) break; } } - if(num<=1) return 0; + if (num <= 1) return 0; return -10; - } - } + }, + }, }, }, - cangming2:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - popup:false, - content:function(){ - for(var i=0;i0; + filter: function (event, player) { + if (event.targets.length != 1 || event.card.name != "sha") return false; + return lib.skill.guanchuan.getTargets(player, event.targets[0]).length > 0; }, - check:function(event,player){ - var targets=lib.skill.guanchuan.getTargets(player,event.targets[0]); - var eff=0; - for(var i=0;i0; + return eff > 0; }, - content:function(){ - var targets=lib.skill.guanchuan.getTargets(player,trigger.targets[0]); - for(var i=0;i1&&lib.filter.filterCard({name:'sha'},player); + player.logSkill("guanchuan", targets); }, - filterCard:{name:'sha'}, - selectCard:2, - check:function(card){ - var num=0; - var player=_status.event.player; - for(var i=0;i0){ + }, + sanjiansheji: { + enable: "phaseUse", + filter: function (event, player) { + return ( + player.countCards("h", "sha") > 1 && lib.filter.filterCard({ name: "sha" }, player) + ); + }, + filterCard: { name: "sha" }, + selectCard: 2, + check: function (card) { + var num = 0; + var player = _status.event.player; + for (var i = 0; i < game.players.length; i++) { + if ( + lib.filter.targetEnabled({ name: "sha" }, player, game.players[i]) && + get.effect(game.players[i], { name: "sha" }, player) > 0 + ) { num++; - if(num>1) return 8-get.value(card); + if (num > 1) return 8 - get.value(card); } } return 0; }, - selectTarget:[1,Infinity], - discard:false, - prepare:'throw', - filterTarget:function(card,player,target){ - return lib.filter.targetEnabled({name:'sha'},player,target)&& - get.distance(player,target,'pure')<=5; + selectTarget: [1, Infinity], + discard: false, + prepare: "throw", + filterTarget: function (card, player, target) { + return ( + lib.filter.targetEnabled({ name: "sha" }, player, target) && + get.distance(player, target, "pure") <= 5 + ); }, - content:function(){ + content: function () { targets.sort(lib.sort.seat); - player.useCard({name:'sha'},cards,targets,'luanjian').animate=false; + player.useCard({ name: "sha" }, cards, targets, "luanjian").animate = false; }, - multitarget:true, - ai:{ - order:function(){ - return get.order({name:'sha'})+0.1; + multitarget: true, + ai: { + order: function () { + return get.order({ name: "sha" }) + 0.1; }, - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,target); - } + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, }, - effect:{ - player:function(card,player){ - if(_status.currentPhase!=player) return; - if(card.name=='sha'&&player.countCards('h','sha')<2&&player.countCards('h')<=player.hp){ - var num=0; - var player=_status.event.player; - for(var i=0;i1) return 'zeroplayertarget'; + if (num > 1) return "zeroplayertarget"; } } } - } + }, }, - } - }, - zhiming:{ - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return get.distance(event.player,player,'attack')>1&&event.card&&event.card.name=='sha'; }, - forced:true, - content:function(){ + }, + zhiming: { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + get.distance(event.player, player, "attack") > 1 && + event.card && + event.card.name == "sha" + ); + }, + forced: true, + content: function () { trigger.num++; - } + }, }, - lianshe:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha'){ - return num+player.getHistory('useCard',function(evt){ - return evt.card.name!='sha'; - }).length; + lianshe: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") { + return ( + num + + player.getHistory("useCard", function (evt) { + return evt.card.name != "sha"; + }).length + ); } }, }, - trigger:{player:'useCard'}, - frequent:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; - })[0]==event; + trigger: { player: "useCard" }, + frequent: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; + })[0] == event + ); }, - content:function(){ + content: function () { player.draw(); }, - ai:{ - threaten:1.5, - } - }, - pianyi:{ - direct:true, - filter:function(event,player){ - return !player.getStat('damage'); + ai: { + threaten: 1.5, }, - content:function(){ - "step 0" - player.chooseToMoveChess(2,get.prompt('pianyi')); - "step 1" - if(result.bool){ - player.logSkill('pianyi'); + }, + pianyi: { + direct: true, + filter: function (event, player) { + return !player.getStat("damage"); + }, + content: function () { + "step 0"; + player.chooseToMoveChess(2, get.prompt("pianyi")); + "step 1"; + if (result.bool) { + player.logSkill("pianyi"); } - } - }, - lingdong:{ - trigger:{player:'phaseJieshuBegin'}, - direct:true, - filter:function(event,player){ - return player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; - }).length>0; }, - content:function(){ - "step 0" - player.chooseToMoveChess(player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; - }).length,get.prompt('lingdong')); - "step 1" - if(result.bool){ - player.logSkill('lingdong'); + }, + lingdong: { + trigger: { player: "phaseJieshuBegin" }, + direct: true, + filter: function (event, player) { + return ( + player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; + }).length > 0 + ); + }, + content: function () { + "step 0"; + player.chooseToMoveChess( + player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; + }).length, + get.prompt("lingdong") + ); + "step 1"; + if (result.bool) { + player.logSkill("lingdong"); } - } - }, - _noactpunish:{ - trigger:{player:'useCard'}, - filter:function(event,player){ - return _status.currentPhase==player&&event.targets&&(event.targets.length>1||event.targets[0]!=player); }, - forced:true, - popup:false, - content:function(){ - player.addTempSkill('noactpunish'); - } }, - noactpunish:{}, - _chess_chuzhang:{ - enable:'phaseUse', - usable:1, - direct:true, - delay:false, - preservecancel:true, - filter:function(event,player){ - var num=0; - var xy=player.getXY(); + _noactpunish: { + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + _status.currentPhase == player && + event.targets && + (event.targets.length > 1 || event.targets[0] != player) + ); + }, + forced: true, + popup: false, + content: function () { + player.addTempSkill("noactpunish"); + }, + }, + noactpunish: {}, + _chess_chuzhang: { + enable: "phaseUse", + usable: 1, + direct: true, + delay: false, + preservecancel: true, + filter: function (event, player) { + var num = 0; + var xy = player.getXY(); var neighbour; - neighbour=player.getNeighbour(-1,0); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(-1, 0); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { + num++; + } else if (xy[0] == 0) { num++; } - else if(xy[0]==0){ + neighbour = player.getNeighbour(1, 0); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { + num++; + } else if (xy[0] + 1 >= ui.chesswidth) { num++; } - neighbour=player.getNeighbour(1,0); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(0, -1); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { + num++; + } else if (xy[1] == 0) { num++; } - else if(xy[0]+1>=ui.chesswidth){ + neighbour = player.getNeighbour(0, 1); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { + num++; + } else if (xy[1] + 1 >= ui.chessheight) { num++; } - neighbour=player.getNeighbour(0,-1); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ - num++; - } - else if(xy[1]==0){ - num++; - } - neighbour=player.getNeighbour(0,1); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ - num++; - } - else if(xy[1]+1>=ui.chessheight){ - num++; - } - return num>=3; + return num >= 3; }, - content:function(){ - 'step 0' - event.obstacles=[]; - event.movemap={}; + content: function () { + "step 0"; + event.obstacles = []; + event.movemap = {}; var neighbour; - neighbour=player.getNeighbour(-1,0); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(-1, 0); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { event.obstacles.push(neighbour); - if(player.movable(-2,0)){ - event.movemap['[-1,0]']=neighbour; + if (player.movable(-2, 0)) { + event.movemap["[-1,0]"] = neighbour; } } - neighbour=player.getNeighbour(1,0); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(1, 0); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { event.obstacles.push(neighbour); - if(player.movable(2,0)){ - event.movemap['[1,0]']=neighbour; + if (player.movable(2, 0)) { + event.movemap["[1,0]"] = neighbour; } } - neighbour=player.getNeighbour(0,-1); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(0, -1); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { event.obstacles.push(neighbour); - if(player.movable(0,-2)){ - event.movemap['[0,-1]']=neighbour; + if (player.movable(0, -2)) { + event.movemap["[0,-1]"] = neighbour; } } - neighbour=player.getNeighbour(0,1); - if(neighbour&&typeof neighbour.tempObstacle!='number'&&game.obstacles.includes(neighbour)){ + neighbour = player.getNeighbour(0, 1); + if ( + neighbour && + typeof neighbour.tempObstacle != "number" && + game.obstacles.includes(neighbour) + ) { event.obstacles.push(neighbour); - if(player.movable(0,2)){ - event.movemap['[0,1]']=neighbour; + if (player.movable(0, 2)) { + event.movemap["[0,1]"] = neighbour; } } - if(!event.obstacles.length){ + if (!event.obstacles.length) { event.finish(); return; - } - else if(event.obstacles.length==1){ - event.obstacle=event.obstacles[0]; - } - else if(event.isMine()){ - for(var i=0;i'+lib.translate._chess_chuzhang_info+''); - event.custom.replace.confirm=function(){ + _status.imchoosing = true; + event.dialog = ui.create.dialog("移动一个与你相邻的路障"); + event.dialog.add( + '
                        ' + lib.translate._chess_chuzhang_info + "
                        " + ); + event.custom.replace.confirm = function () { player.getStat().skill._chess_chuzhang--; - event.cancelled=true; + event.cancelled = true; game.resume(); }; } - 'step 1' - if(ui.confirm){ - ui.confirm.classList.add('removing'); + "step 1"; + if (ui.confirm) { + ui.confirm.classList.add("removing"); } - _status.imchoosing=false; - if(!event.cancelled){ - if(!event.obstacle){ - event.obstacle=event.obstacles.randomGet(); + _status.imchoosing = false; + if (!event.cancelled) { + if (!event.obstacle) { + event.obstacle = event.obstacles.randomGet(); } - var moved=false; - for(var i in event.movemap){ - if(event.movemap[i]==event.obstacle){ - var xy=JSON.parse(i); - if(game.moveObstacle(event.obstacle,xy[0],xy[1])){ - moved=true; + var moved = false; + for (var i in event.movemap) { + if (event.movemap[i] == event.obstacle) { + var xy = JSON.parse(i); + if (game.moveObstacle(event.obstacle, xy[0], xy[1])) { + moved = true; break; } } } - if(!moved){ + if (!moved) { game.removeObstacle(event.obstacle); } - player.popup('除障'); + player.popup("除障"); game.delay(); } - for(var i=0;i0; + var move = 2; + move = game.checkMod(player, move, "chessMove", player); + return move > 0; }, - content:function(){ - "step 0" - var move=2; - move=game.checkMod(player,move,'chessMove',player); - player.chooseToMoveChess(move).phasing=true; - "step 1" - if(ui.confirm){ - ui.confirm.classList.add('removing'); + content: function () { + "step 0"; + var move = 2; + move = game.checkMod(player, move, "chessMove", player); + player.chooseToMoveChess(move).phasing = true; + "step 1"; + if (ui.confirm) { + ui.confirm.classList.add("removing"); } - if(!result.bool){ - var skill=player.getStat().skill; + if (!result.bool) { + var skill = player.getStat().skill; skill._chessmove--; - if(typeof skill._chessmovetried=='number'){ + if (typeof skill._chessmovetried == "number") { skill._chessmovetried++; - } - else{ - skill._chessmovetried=1; + } else { + skill._chessmovetried = 1; } } }, - ai:{ - order:5, - result:{ - playerx:function(player){ - if(get.mode()=='tafang'&&_status.enemies.includes(player)){ + ai: { + order: 5, + result: { + playerx: function (player) { + if (get.mode() == "tafang" && _status.enemies.includes(player)) { return 1; } - var nh=player.countCards('h'); - if(!player.countCards('h','sha')&& - !player.countCards('h','shunshou')&& - !player.countCards('h','bingliang')){ - if(nh<=Math.min(3,player.hp)) return Math.random()-0.3; - else if(nh<=Math.min(2,player.hp)) return Math.random()-0.4; - return Math.random()-0.5; + var nh = player.countCards("h"); + if ( + !player.countCards("h", "sha") && + !player.countCards("h", "shunshou") && + !player.countCards("h", "bingliang") + ) { + if (nh <= Math.min(3, player.hp)) return Math.random() - 0.3; + else if (nh <= Math.min(2, player.hp)) return Math.random() - 0.4; + return Math.random() - 0.5; } var neighbour; - neighbour=player.getNeighbour(0,1); - if(neighbour&&game.players.includes(neighbour)&&neighbour.side!=player.side){ - if(get.distance(player,neighbour,'attack')<1) return 1; + neighbour = player.getNeighbour(0, 1); + if ( + neighbour && + game.players.includes(neighbour) && + neighbour.side != player.side + ) { + if (get.distance(player, neighbour, "attack") < 1) return 1; return 0; } - neighbour=player.getNeighbour(0,-1); - if(neighbour&&game.players.includes(neighbour)&&neighbour.side!=player.side){ - if(get.distance(player,neighbour,'attack')<1) return 1; + neighbour = player.getNeighbour(0, -1); + if ( + neighbour && + game.players.includes(neighbour) && + neighbour.side != player.side + ) { + if (get.distance(player, neighbour, "attack") < 1) return 1; return 0; } - neighbour=player.getNeighbour(1,0); - if(neighbour&&game.players.includes(neighbour)&&neighbour.side!=player.side){ - if(get.distance(player,neighbour,'attack')<1) return 1; + neighbour = player.getNeighbour(1, 0); + if ( + neighbour && + game.players.includes(neighbour) && + neighbour.side != player.side + ) { + if (get.distance(player, neighbour, "attack") < 1) return 1; return 0; } - neighbour=player.getNeighbour(-1,0); - if(neighbour&&game.players.includes(neighbour)&&neighbour.side!=player.side){ - if(get.distance(player,neighbour,'attack')<1) return 1; + neighbour = player.getNeighbour(-1, 0); + if ( + neighbour && + game.players.includes(neighbour) && + neighbour.side != player.side + ) { + if (get.distance(player, neighbour, "attack") < 1) return 1; return 0; } return 1; }, - player:function(player){ - if(player.getStat().skill._chessmovetried>=10){ + player: function (player) { + if (player.getStat().skill._chessmovetried >= 10) { return 0; } - var x=lib.skill._chessmove.ai.result.playerx(player); - if(player.isMad()) return -x; + var x = lib.skill._chessmove.ai.result.playerx(player); + if (player.isMad()) return -x; return x; - } - } - } + }, + }, + }, }, - _chesscenter:{ - trigger:{player:['phaseBegin','useCardBegin','useSkillBegin','respondBegin','damageBegin','loseHpBegin'], - target:'useCardToBegin'}, - forced:true, - priority:100, - popup:false, - content:function(){ + _chesscenter: { + trigger: { + player: [ + "phaseBegin", + "useCardBegin", + "useSkillBegin", + "respondBegin", + "damageBegin", + "loseHpBegin", + ], + target: "useCardToBegin", + }, + forced: true, + priority: 100, + popup: false, + content: function () { player.chessFocus(); }, }, - boss_bfengxing:{ - mod:{ - chessMove:function(player,current){ - return current+2; + boss_bfengxing: { + mod: { + chessMove: function (player, current) { + return current + 2; }, - attackFrom:function(from,to,current){ - return current-2; + attackFrom: function (from, to, current) { + return current - 2; }, }, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event){ + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event) { return !event.numFixed; }, - content:function(){ - trigger.num+=2; - } + content: function () { + trigger.num += 2; + }, }, - boss_chiyu:{ - enable:'phaseUse', - usable:1, - filterCard:{color:'red'}, - nodelay:true, - check:function(card){return 8-get.value(card);}, - filterTarget:function(card,player,target){ - return get.distance(player,target)<=5&&player!=target; + boss_chiyu: { + enable: "phaseUse", + usable: 1, + filterCard: { color: "red" }, + nodelay: true, + check: function (card) { + return 8 - get.value(card); }, - filter:function(event,player){ - return player.countCards('h',{color:'red'})>0; + filterTarget: function (card, player, target) { + return get.distance(player, target) <= 5 && player != target; }, - selectTarget:-1, - content:function(){ - target.damage('fire'); + filter: function (event, player) { + return player.countCards("h", { color: "red" }) > 0; }, - line:'fire', - ai:{ - order:1, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'fire'); - } - } - } - }, - boss_tenglong:{ - enable:'phaseUse', - usable:1, - position:'he', - filterCard:{type:'equip'}, - init:function(player){ - for(var i=1;i<6;i++){ - player.$disableEquip('equip'+i); - } + selectTarget: -1, + content: function () { + target.damage("fire"); }, - check:function(card){ - var player=_status.currentPhase; - if(player.countCards('he',{subtype:get.subtype(card)})>1){ - return 12-get.equipValue(card); - } - return 8-get.equipValue(card); - }, - filter:function(event,player){ - return player.countCards('he',{type:'equip'}); - }, - filterTarget:function(card,player,target){ - return player!=target&&get.distance(player,target)<=2; - }, - content:function(){ - target.damage(3,'fire'); - }, - ai:{ - order:9, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'fire'); - } - } - } - }, - boss_wuying:{ - mod:{ - globalTo:function(from,to,distance){ - return distance+2; + line: "fire", + ai: { + order: 1, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "fire"); + }, }, - chessMove:function(player,current){ - return current-1; - } - } + }, }, - boss_wushang:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - for(var i=0;i 1) { + return 12 - get.equipValue(card); + } + return 8 - get.equipValue(card); + }, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }); + }, + filterTarget: function (card, player, target) { + return player != target && get.distance(player, target) <= 2; + }, + content: function () { + target.damage(3, "fire"); + }, + ai: { + order: 9, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "fire"); + }, + }, + }, + }, + boss_wuying: { + mod: { + globalTo: function (from, to, distance) { + return distance + 2; + }, + chessMove: function (player, current) { + return current - 1; + }, + }, + }, + boss_wushang: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if ( + game.players[i] != player && + game.players[i].countCards("h") && + get.distance(player, game.players[i]) <= 5 + ) { return true; } } return false; }, - content:function(){ - "step 0" - var players=[]; - for(var i=0;i=ui.chessheight-1) return false; + }, + translate: { + zhu_config: "启用主将", + main_zhu_config: "启用副将", + noreplace_end_config: "无替补时结束", + reward_config: "杀敌摸牌", + punish_config: "杀死队友", + seat_order_config: "行动顺序", + battle_number_config: "对战人数", + replace_number_config: "替补人数", + first_less_config: "先手少摸牌", + single_control_config: "单人控制", + additional_player_config: "无尽模式", + choice_number_config: "无尽模式候选", + + friend: "友", + enemy: "敌", + neutral: "中", + trueColor: "zhu", + falseColor: "wei", + _chessmove: "移动", + leader: "君主", + combat: "对阵", + chessscroll_speed_config: "边缘滚动速度", + chess_character_config: "战棋武将", + only_chess_character_config: "只用战棋武将", + chess_ordered_config: "指定行动顺序", + chess_mode_config: "游戏模式", + chess_leader_save_config: "选择历程", + chess_leader_clear_config: "清除进度", + save1: "一", + save2: "二", + save3: "三", + save4: "四", + save5: "五", + + leader_2: " ", + leader_2_bg: "二", + leader_3: " ", + leader_3_bg: "三", + leader_5: " ", + leader_5_bg: "五", + leader_8: " ", + leader_8_bg: "八", + + leader_easy: " ", + leader_easy_bg: "简单", + leader_medium: " ", + leader_medium_bg: "普通", + leader_hard: " ", + leader_hard_bg: "困难", + + chess_caocao: "曹操", + chess_xunyu: "荀彧", + chess_simayi: "司马懿", + chess_xiahoudun: "夏侯惇", + chess_dianwei: "典韦", + chess_xuzhu: "许褚", + chess_zhangliao: "张辽", + chess_jiaxu: "贾诩", + + chess_liubei: "刘备", + chess_guanyu: "关羽", + chess_zhangfei: "张飞", + chess_zhaoyun: "赵云", + chess_machao: "马超", + chess_huangzhong: "黄忠", + chess_maliang: "马良", + chess_zhugeliang: "诸葛亮", + + chess_sunquan: "孙权", + chess_zhouyu: "周瑜", + chess_lvmeng: "吕蒙", + chess_huanggai: "黄盖", + chess_lusu: "鲁肃", + chess_luxun: "陆逊", + chess_ganning: "甘宁", + chess_taishici: "太史慈", + + chess_lvbu: "吕布", + chess_sunshangxiang: "孙尚香", + chess_diaochan: "貂蝉", + chess_huatuo: "华佗", + chess_zhangjiao: "张辽", + chess_menghuo: "孟获", + + chess_dongzhuo: "董卓", + chess_xingtian: "刑天", + chess_jinchidiao: "金翅雕", + chess_beimingjukun: "北溟巨鲲", + chess_wuzhaojinlong: "五爪金龙", + + treasure_dubiaoxianjing: "毒镖陷阱", + treasure_jiqishi: "集气石", + treasure_shenmidiaoxiang: "神秘雕像", + treasure_shenpanxianjing: "审判之刃", + treasure_shiyuansu: "石元素", + treasure_wuyashenxiang: "乌鸦神像", + + dubiaoxianjing: "飞刃", + dubiaoxianjing_info: "距离两格体力值大于1的角色在回合结束后受到1点伤害,然后摸两张牌。", + jiqishi: "集气", + jiqishi_info: "距离两格以内的已受伤角色在回合结束后回复1点体力,然后弃置两张牌。", + shenmidiaoxiang: "秘咒", + shenmidiaoxiang_info: "距离三格以外的所有角色在回合结束后强制向此处移动一格。", + shenpanxianjing: "审判", + shenpanxianjing_info: + "在任意一名角色回合结束后,若没有其他角色手牌数比其多,随机弃置其一张手牌。", + shiyuansu: "护体", + shiyuansu_info: "任意一名角色一次性受到不少于2点伤害后,使其获得1点护甲。", + wuyashenxiang: "厄音", + wuyashenxiang_info: + "距离3格以内的角色在其回合结束后,若体力值不大于1,令其回复1点体力,然后将牌堆中的一张延时锦囊牌置于其判定区。", + + leader_caocao: "曹操", + leader_liubei: "刘备", + leader_sunquan: "孙权", + leader_yuri: "由理", + leader_xiaoxiong: "枭雄", + leader_xiaoxiong_info: "当你造成伤害后,获胜后会得到一定数量的额外金币奖励。", + leader_renyi: "仁义", + leader_renyi_info: "你招降敌将的成功率大幅增加。", + leader_mouduan: "谋断", + leader_mouduan_info: "其他友方角色回合内的行动范围+1。", + leader_zhenlve: "缜略", + leader_zhenlve_info: "友方角色使用的普通锦囊牌不可被【无懈可击】响应。", + + tongshuai: "统率", + tongshuai_info: "准备阶段和结束阶段,你可以选择一名未上场的已方武将的一个技能作为你的技能。", + leader_zhaoxiang: "招降", + leader_zhaoxiang_info: + "出牌阶段限一次,你可以尝试对相邻敌方武将进行招降,若成功,你获得该武将并立即结束本局游戏,若失败,你受到1点伤害。每发动一次消耗10招募令。", + + common: "普通", + rare: "精品", + epic: "史诗", + legend: "传说", + + chess_shezhang: "设置路障", + chess_shezhang_info: "选择一名角色,在其四周设置临时路障,持续X回合(X为存活角色数)。", + chess_chuzhang: "清除路障", + chess_chuzhang_info: "将与你相邻的路障向后推移一格,每影响一个路障你摸一张牌。", + + _chess_chuzhang: "除障", + _chess_chuzhang_info: + "出牌阶段限一次,若你周围四格至少有三个为障碍或在边缘外,你可以选择将其中一个障碍向后推移一格(若无法推移则改为清除之)。", + + arenaAdd: "援军", + arenaAdd_info: + "出牌阶段限一次,你可以令一名未出场的已方角色加入战场。战斗结束后,该角色无论是否存活均不能再次出场。", + + pianyi: "翩仪", + pianyi_info: "结束阶段,若你于本回合内未造成过伤害,你获得一次移动机会。", + lingdong: "灵动", + lingdong_info: "结束阶段,你可以移动至多X格(X为你本回合内使用【杀】的次数)。", + lianshe: "箭舞", + lianshe_info: + "当你于一回合内首次使用【杀】时,你可以摸一张牌;你的回合内,当你使用一张不为【杀】的牌时,你令本回合内使用【杀】的次数上限+1。", + zhiming: "穿杨", + zhiming_info: "锁定技,当你使用【杀】造成伤害时,若你不在目标角色的攻击范围内,此伤害+1。", + sanjiansheji: "散箭", + sanjiansheji_info: + "你可以将两张【杀】当做【杀】使用,你以此法使用的【杀】可以指定距离5格内的角色为目标。", + guanchuan: "强弩", + guanchuan_info: "当你使用【杀】指定唯一目标后,你可令攻击射线内的其他角色也成为此【杀】的目标。", + + boss_stoneqiangzheng: "强征", + boss_stoneqiangzheng_info: "锁定技,结束阶段,你获得所有其他角色的各一张手牌。", + boss_stonebaolin: "暴凌", + boss_moyan: "魔焰", + boss_moyan_info: "锁定技,结束阶段,你对场上所有角色造成1点火焰伤害。", + + cangming: "颠动沧溟", + cangming_info: + "出牌阶段限一次,你可弃置四张花色不同的手牌并将武将牌翻至背面,然后令所有其他角色进入混乱状态直到你的下一回合开始。", + boss_bfengxing: "风行", + boss_bfengxing_info: "锁定技,摸牌阶段,你多摸两张牌;你的攻击范围+2;你回合内的移动距离+2。", + boss_chiyu: "炽羽", + boss_chiyu_info: + "出牌阶段限一次,你可以弃置一张红色牌,对距离5以内的所有其他角色各造成1点火焰伤害。", + boss_tenglong: "腾龙八齐", + boss_tenglong_info: + "锁定技,你废除你的装备区;出牌阶段限一次,你可以弃置一张装备牌并对一名距离你2以内的其他角色造成3点火焰伤害。", + boss_wushang: "神天并地", + boss_wushang_info: "锁定技,准备阶段,距离你5以内的所有其他角色需交给你一张手牌。", + boss_wuying: "无影", + boss_wuying_info: "锁定技,你回合内的移动距离-1;其他角色至你的距离+2。", + + chess_default: "常规", + chess_boss: "魔王", + chess_leader: "君主", + + mode_chess_character_config: "战棋模式", + mode_chess_card_config: "战棋模式", + }, + ui: { + placeChess: function (player, pos) { + player.dataset.position = pos; + pos = parseInt(pos); + var j = Math.floor(pos / ui.chesswidth); + var i = pos - j * ui.chesswidth; + var dx = i * 148; + var dy = j * 148; + player._chesstransform = [dx, dy]; + player.style.transform = "translate(" + dx + "px," + dy + "px)"; + }, + create: { + playergrid: function (player, x, y) { + var pos = player.getDataPos(x, y); + if (get.mode() == "tafang") { + if (pos < ui.chesswidth) return false; + if (pos / ui.chesswidth >= ui.chessheight - 1) return false; } - var node=ui.create.div('.player.minskin.playergrid',player.parentNode); - node.link=player; - ui.placeChess(node,pos); + var node = ui.create.div(".player.minskin.playergrid", player.parentNode); + node.link = player; + ui.placeChess(node, pos); return node; }, - fakeme:function(){ - if(ui.fakeme){ + fakeme: function () { + if (ui.fakeme) { ui.fakeme.delete(); } - ui.fakeme=ui.create.div('.fakeme.avatar',ui.me); - ui.fakeme.style.backgroundImage=game.me.node.avatar.style.backgroundImage; - } + ui.fakeme = ui.create.div(".fakeme.avatar", ui.me); + ui.fakeme.style.backgroundImage = game.me.node.avatar.style.backgroundImage; + }, }, - click:{ - moveContainer:function(x,y,scroll){ - if(scroll){ + click: { + moveContainer: function (x, y, scroll) { + if (scroll) { clearTimeout(ui.chessContainer._scrolling); - ui.chessContainer._scrolling=true; - ui.chess.style.transition='transform 0.5s'; + ui.chessContainer._scrolling = true; + ui.chess.style.transition = "transform 0.5s"; ui.refresh(ui.chess); - } - else if(ui.chessContainer._scrolling){ + } else if (ui.chessContainer._scrolling) { return; } - if(typeof x==='number') ui.chessContainer.chessLeft+=x; - if(typeof y==='number') ui.chessContainer.chessTop+=y; - var xmin=0; - if(lib.config.show_history=='left'){ - xmin=-50; + if (typeof x === "number") ui.chessContainer.chessLeft += x; + if (typeof y === "number") ui.chessContainer.chessTop += y; + var xmin = 0; + if (lib.config.show_history == "left") { + xmin = -50; } - if(ui.chessContainer.chessLeftxmax) ui.chessContainer.chessLeft=xmax; - if(ui.chessContainer.chessTop>ymax) ui.chessContainer.chessTop=ymax; - ui.chess.style.transform='translate('+(-ui.chessContainer.chessLeft)+'px,'+(-ui.chessContainer.chessTop)+'px)'; - if(scroll){ - var ending=ui.chess.listenTransition(function(){ - if(ui.chess._ending==ending){ + if (ui.chessContainer.chessLeft < xmin) ui.chessContainer.chessLeft = xmin; + if (ui.chessContainer.chessTop < 0) ui.chessContainer.chessTop = 0; + var xmax = ui.chessContainer.xmax; + var ymax = ui.chessContainer.ymax; + if (ui.chessContainer.chessLeft > xmax) ui.chessContainer.chessLeft = xmax; + if (ui.chessContainer.chessTop > ymax) ui.chessContainer.chessTop = ymax; + ui.chess.style.transform = + "translate(" + + -ui.chessContainer.chessLeft + + "px," + + -ui.chessContainer.chessTop + + "px)"; + if (scroll) { + var ending = ui.chess.listenTransition(function () { + if (ui.chess._ending == ending) { clearTimeout(ui.chessContainer._scrolling); delete ui.chess._ending; - ui.chess._scrolling=setTimeout(function(){ - ui.chessContainer._scrolling=null; - ui.chess.style.transition=''; - },500); + ui.chess._scrolling = setTimeout(function () { + ui.chessContainer._scrolling = null; + ui.chess.style.transition = ""; + }, 500); } }); - ui.chess._ending=ending; + ui.chess._ending = ending; } }, - chessInfo:function(e){ - if(this.link.isAlive()){ + chessInfo: function (e) { + if (this.link.isAlive()) { this.link.chessFocus(); - if(this.link.classList.contains('selectable')|| - this.link.classList.contains('selected')){ - ui.click.target.call(this.link,e); - ui.click.window.call(ui.window,e); + if ( + this.link.classList.contains("selectable") || + this.link.classList.contains("selected") + ) { + ui.click.target.call(this.link, e); + ui.click.window.call(ui.window, e); } e.stopPropagation(); } }, - playergrid:function(){ - if(!_status.paused) return; - var pos=parseInt(this.dataset.position); - this.link.moveTo(pos%ui.chesswidth,Math.floor(pos/ui.chesswidth)); - if(ui.movegrids){ - while(ui.movegrids.length){ + playergrid: function () { + if (!_status.paused) return; + var pos = parseInt(this.dataset.position); + this.link.moveTo(pos % ui.chesswidth, Math.floor(pos / ui.chesswidth)); + if (ui.movegrids) { + while (ui.movegrids.length) { ui.movegrids.shift().delete(); } } - _status.event.result={ - bool:true, - move:this.link.dataset.position + _status.event.result = { + bool: true, + move: this.link.dataset.position, }; game.resume(); }, - obstacle:function(){ - if(_status.event.chooseObstacle&&_status.paused&& - _status.event.obstacles&&_status.event.obstacles.includes(this)){ - _status.event.obstacle=this; + obstacle: function () { + if ( + _status.event.chooseObstacle && + _status.paused && + _status.event.obstacles && + _status.event.obstacles.includes(this) + ) { + _status.event.obstacle = this; game.resume(); } - } - } - }, - get:{ - chessDistance:function(from,to){ - var fxy=from.getXY(); - var txy=to.getXY(); - return Math.abs(fxy[0]-txy[0])+Math.abs(fxy[1]-txy[1]); + }, }, - rawAttitude:function(from,to){ - return (from.side===to.side?6:-6); - } }, - card:{ - chess_shezhang:{ - type:'basic', - fullskin:true, - modeimage:'chess', - enable:true, - filterTarget:function(card,player,target){ - if(target.movable(-1,0)) return true; - if(target.movable(1,0)) return true; - if(target.movable(0,-1)) return true; - if(target.movable(0,1)) return true; + get: { + chessDistance: function (from, to) { + var fxy = from.getXY(); + var txy = to.getXY(); + return Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); + }, + rawAttitude: function (from, to) { + return from.side === to.side ? 6 : -6; + }, + }, + card: { + chess_shezhang: { + type: "basic", + fullskin: true, + modeimage: "chess", + enable: true, + filterTarget: function (card, player, target) { + if (target.movable(-1, 0)) return true; + if (target.movable(1, 0)) return true; + if (target.movable(0, -1)) return true; + if (target.movable(0, 1)) return true; return false; }, - content:function(){ - var xy=target.getXY(); - var x=xy[0]; - var y=xy[1]; - if(target.movable(-1,0)){ - game.addTempObstacle(x-1,y,game.countPlayer()); + content: function () { + var xy = target.getXY(); + var x = xy[0]; + var y = xy[1]; + if (target.movable(-1, 0)) { + game.addTempObstacle(x - 1, y, game.countPlayer()); } - if(target.movable(1,0)){ - game.addTempObstacle(x+1,y,game.countPlayer()); + if (target.movable(1, 0)) { + game.addTempObstacle(x + 1, y, game.countPlayer()); } - if(target.movable(0,1)){ - game.addTempObstacle(x,y+1,game.countPlayer()); + if (target.movable(0, 1)) { + game.addTempObstacle(x, y + 1, game.countPlayer()); } - if(target.movable(0,-1)){ - game.addTempObstacle(x,y-1,game.countPlayer()); + if (target.movable(0, -1)) { + game.addTempObstacle(x, y - 1, game.countPlayer()); } }, - content_old:function(){ - 'step 0' - var pos=parseInt(player.dataset.position); - var poses=[]; - if(player.movable(-1,0)){ - poses.push(pos-1); + content_old: function () { + "step 0"; + var pos = parseInt(player.dataset.position); + var poses = []; + if (player.movable(-1, 0)) { + poses.push(pos - 1); } - if(player.movable(1,0)){ - poses.push(pos+1); + if (player.movable(1, 0)) { + poses.push(pos + 1); } - if(player.movable(0,-1)){ - poses.push(pos-ui.chesswidth); + if (player.movable(0, -1)) { + poses.push(pos - ui.chesswidth); } - if(player.movable(0,1)){ - poses.push(pos+ui.chesswidth); + if (player.movable(0, 1)) { + poses.push(pos + ui.chesswidth); } - event.poses=poses; - if(poses.length==1){ - event.obstacle=poses[0]; - event.grids=[]; - } - else if(event.isMine()){ - event.grids=player.createRangeShadow(1,function(){ - event.obstacle=this.dataset.position; + event.poses = poses; + if (poses.length == 1) { + event.obstacle = poses[0]; + event.grids = []; + } else if (event.isMine()) { + event.grids = player.createRangeShadow(1, function () { + event.obstacle = this.dataset.position; game.resume(); - }) + }); game.pause(); - _status.imchoosing=true; - for(var i=0;i对阵模式
                        • n人对战n人的模式,由单人控制,开始游戏后随机分配位置与出牌顺序
                        • '+ - '每人在出牌阶段有一次移动的机会,可移动的最大距离为2
                        • '+ - '任何卡牌或技能无法指定位置相隔8个格以上的角色为目标
                        • '+ - '杀死对方阵营的角色可摸一张牌,杀死本方阵营无惩罚
                        • '+ - '若开启主将,双方各选择一名角色成为主将。主将体力上限加一,主将死亡后,若有副将,副将代替之成为主将,否则游戏结束
                        • '+ - '开启无尽模式后,任何一方有角色死亡都将选择一名新角色重新加入战场,直到点击左上角的结束游戏按钮手动结束游戏。结束游戏时,杀敌更多的一方获胜
                        • '+ - '行动顺序为指定时,双方无论存活角色角色多少都将轮流进行行动。在一方所有角色行动完毕进行下一轮行动时,若其人数比另一方少,另一方可指定至多X名角色名摸一张牌,X为人数之差
                        • '+ - '开启战场机关后,每个回合结束时有一定机率出现一个机关,该机关不参与战斗,并有一个影响周围或全体角色的效果。机关在出现后的5~10个回合内消失
                        • '+ - '开启击退效果后,当一名角色对距离两格以内的目标造成伤害后,受伤害角色将沿反方向移动一格
                        • '+ - '战场上可设置出现随机路障,角色无法移动到路障处。当一名角色的周围四格有至少三格为路障或在战场外时,其可以在回合内清除一个相邻路障
                        '+ - '
                        君主模式
                        • 收集武将进行战斗,根据战斗难度及我方出场武将的强度,战斗胜利后将获得数量不等的金钱。没有君主出场时,获得的金钱较多
                        • '+ - '金钱可以用来招募随机武将,招到已有武将,或遣返不需要的武将时可得到招募令
                        • '+ - '战斗中有君主出场时可招降敌将,成功率取决于敌将的稀有度、剩余体力值以及手牌数。成功后战斗立即结束且没有金钱奖励。每发动一次招降,无论成功还是失败,都会扣除10招募令
                        • '+ - '挑战武将会与该武将以及与其强度相近的武将进行战斗,敌方人数与我方出场人数相同,但不少于3。胜利后可通过招募令招募该武将,普通/稀有/史诗/传说武将分别需要40/100/400/1600招募令
                        • '+ - '竞技场:
                          随机选择9名武将,每次派出1~3名武将参战。战斗中阵亡的武将不能再次上场。

                          战斗后武将进入疲劳状态,若立即再次出场则初始体力值-1。

                          战斗中本方武将行动时可召唤后援,令一名未出场的已方武将加入战斗。后援武将在战斗结束后无论存活与否均不能再次出场

                          当取得12场胜利或所有武将全部阵亡后结束,并根据胜场数获得随机奖励
                        • '+ - '修改金钱:
                          game.changeMoney
                          修改招募令:
                          game.changeDust
                        ' + rank: {}, + posmap: {}, + help: { + 战棋模式: + '
                        对阵模式
                        • n人对战n人的模式,由单人控制,开始游戏后随机分配位置与出牌顺序
                        • ' + + "每人在出牌阶段有一次移动的机会,可移动的最大距离为2
                        • " + + "任何卡牌或技能无法指定位置相隔8个格以上的角色为目标
                        • " + + "杀死对方阵营的角色可摸一张牌,杀死本方阵营无惩罚
                        • " + + "若开启主将,双方各选择一名角色成为主将。主将体力上限加一,主将死亡后,若有副将,副将代替之成为主将,否则游戏结束
                        • " + + "开启无尽模式后,任何一方有角色死亡都将选择一名新角色重新加入战场,直到点击左上角的结束游戏按钮手动结束游戏。结束游戏时,杀敌更多的一方获胜
                        • " + + "行动顺序为指定时,双方无论存活角色角色多少都将轮流进行行动。在一方所有角色行动完毕进行下一轮行动时,若其人数比另一方少,另一方可指定至多X名角色名摸一张牌,X为人数之差
                        • " + + "开启战场机关后,每个回合结束时有一定机率出现一个机关,该机关不参与战斗,并有一个影响周围或全体角色的效果。机关在出现后的5~10个回合内消失
                        • " + + "开启击退效果后,当一名角色对距离两格以内的目标造成伤害后,受伤害角色将沿反方向移动一格
                        • " + + "战场上可设置出现随机路障,角色无法移动到路障处。当一名角色的周围四格有至少三格为路障或在战场外时,其可以在回合内清除一个相邻路障
                        " + + '
                        君主模式
                        • 收集武将进行战斗,根据战斗难度及我方出场武将的强度,战斗胜利后将获得数量不等的金钱。没有君主出场时,获得的金钱较多
                        • ' + + "金钱可以用来招募随机武将,招到已有武将,或遣返不需要的武将时可得到招募令
                        • " + + "战斗中有君主出场时可招降敌将,成功率取决于敌将的稀有度、剩余体力值以及手牌数。成功后战斗立即结束且没有金钱奖励。每发动一次招降,无论成功还是失败,都会扣除10招募令
                        • " + + "挑战武将会与该武将以及与其强度相近的武将进行战斗,敌方人数与我方出场人数相同,但不少于3。胜利后可通过招募令招募该武将,普通/稀有/史诗/传说武将分别需要40/100/400/1600招募令
                        • " + + "竞技场:
                          随机选择9名武将,每次派出1~3名武将参战。战斗中阵亡的武将不能再次上场。

                          战斗后武将进入疲劳状态,若立即再次出场则初始体力值-1。

                          战斗中本方武将行动时可召唤后援,令一名未出场的已方武将加入战斗。后援武将在战斗结束后无论存活与否均不能再次出场

                          当取得12场胜利或所有武将全部阵亡后结束,并根据胜场数获得随机奖励
                        • " + + "修改金钱:
                          game.changeMoney
                          修改招募令:
                          game.changeDust
                        ", }, }; }); diff --git a/mode/connect.js b/mode/connect.js index 6772b11dc..8977d7b24 100644 --- a/mode/connect.js +++ b/mode/connect.js @@ -1,182 +1,208 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ - return { - name:'connect', - start:function(){ - var directstartmode=lib.config.directstartmode; - ui.create.menu(true); - event.textnode=ui.create.div('','输入联机地址'); - var createNode=function(){ - if(event.created) return; - if(directstartmode&&lib.node){ - ui.exitroom=ui.create.system('退出房间',function(){ - game.saveConfig('directstartmode'); - game.reload(); - },true); - game.switchMode(directstartmode); - return; - } - if(lib.node&&window.require){ - ui.startServer=ui.create.system('启动服务器',function(e){ - ui.click.shortcut(false); - e.stopPropagation(); - ui.click.connectMenu(); - },true); - } - - event.created=true; - var node=ui.create.div('.shadowed'); - node.style.width='400px'; - node.style.height='30px'; - node.style.lineHeight='30px'; - node.style.fontFamily='xinwei'; - node.style.fontSize='30px'; - node.style.padding='10px'; - node.style.left='calc(50% - 210px)'; - node.style.top='calc(50% - 20px)'; - node.style.whiteSpace='nowrap'; - node.textContent=lib.config.last_ip||lib.hallURL; - node.contentEditable=true; - node.style.webkitUserSelect='text'; - node.style.textAlign='center'; - node.style.overflow='hidden'; - - var connect=function(e){ - event.textnode.textContent='正在连接...'; - clearTimeout(event.timeout); - if(e) e.preventDefault(); - game.saveConfig('last_ip',node.textContent); - game.connect(node.textContent,function(success){ - if(success){ - var info=lib.config.reconnect_info; - if(info&&info[0]==_status.ip){ - game.onlineID=info[1]; - if(typeof (game.roomId=info[2])=='string') game.roomIdServer=true; - } - return; - } - if(event.textnode){ - alert('连接失败'); - event.textnode.textContent='输入联机地址'; - } - }); - }; - node.addEventListener('keydown',function(e){ - if(e.keyCode==13){ - connect(e); - } - }); - ui.window.appendChild(node); - ui.ipnode=node; - - var text=event.textnode; - text.style.width='400px'; - text.style.height='30px'; - text.style.lineHeight='30px'; - text.style.fontFamily='xinwei'; - text.style.fontSize='30px'; - text.style.padding='10px'; - text.style.left='calc(50% - 200px)'; - text.style.top='calc(50% - 80px)'; - text.style.textAlign='center'; - ui.window.appendChild(text); - ui.iptext=text; - - var button=ui.create.div('.menubutton.highlight.large.pointerdiv','连接',connect); - button.style.width='70px'; - button.style.left='calc(50% - 35px)'; - button.style.top='calc(50% + 60px)'; - ui.window.appendChild(button); - ui.ipbutton=button; - - ui.hall_button=ui.create.system('联机大厅',function(){ - node.textContent=get.config('hall_ip')||lib.hallURL; - connect(); - },true); - if(!get.config('hall_button')){ - ui.hall_button.style.display='none'; - } - ui.recentIP=ui.create.system('最近连接',null,true); - var clickLink=function(){ - node.textContent=this.textContent; - connect(); - }; - lib.setPopped(ui.recentIP,function(){ - if(!lib.config.recentIP.length) return; - var uiintro=ui.create.dialog('hidden'); - uiintro.listen(function(e){ - e.stopPropagation(); - }); - var list=ui.create.div('.caption'); - for(var i=0;i清除'); - clear.style.paddingTop=0; - clear.style.paddingBottom='3px'; - clear.listen(function(){ - lib.config.recentIP.length=0; - game.saveConfig('recentIP',[]); - uiintro.delete(); - }); - return uiintro; - },220); - if (get.config('read_clipboard','connect')){ - var ced=false; - var read=text=>{ - try{ - var text2=text.split('\n')[2]; - var ip=text2.slice(5); - if(ip.length>0&&text2.startsWith("联机地址:")&&(ced||confirm('是否根据剪贴板的邀请链接以进入联机地址和房间?'))){ - node.innerHTML=ip; - event.textnode.innerHTML='正在连接...'; - clearTimeout(event.timeout); - game.saveConfig('last_ip',node.innerHTML); - game.connect(node.innerHTML,function(success){ - if(!success&&event.textnode){ - alert('邀请链接解析失败'); - event.textnode.innerHTML='输入联机地址'; - } - if (success) _status.read_clipboard_text=text; - }); - } - }catch(e){console.log(e);} - } - window.focus(); - if (navigator.clipboard&&lib.node){ - navigator.clipboard.readText().then(read).catch(_=>{}); - }else{ - var input=ui.create.node('textarea',ui.window,{opacity:'0'}); - input.select(); - var result=document.execCommand('paste'); - input.blur(); - ui.window.removeChild(input); - if(result||input.value.length>0) read(input.value); - else if(confirm('是否输入邀请链接以进入联机地址和房间?')){ - ced=true; - var text=prompt('请输入邀请链接'); - if(typeof text=='string'&&text.length>0) read(text); - } - } - } - lib.init.onfree(); - } - if(window.isNonameServer){ - game.connect(window.isNonameServerIp||'localhost'); - } - else{ - createNode(); - } - if(!game.onlineKey){ - game.onlineKey=localStorage.getItem(lib.configprefix+'key'); - if(!game.onlineKey){ - game.onlineKey=get.id(); - localStorage.setItem(lib.configprefix+'key',game.onlineKey); - } - } - _status.connectDenied=createNode; - setTimeout(lib.init.onfree,1000); - } - }; -}); +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { + return { + name: "connect", + start: function () { + var directstartmode = lib.config.directstartmode; + ui.create.menu(true); + event.textnode = ui.create.div("", "输入联机地址"); + var createNode = function () { + if (event.created) return; + if (directstartmode && lib.node) { + ui.exitroom = ui.create.system( + "退出房间", + function () { + game.saveConfig("directstartmode"); + game.reload(); + }, + true + ); + game.switchMode(directstartmode); + return; + } + if (lib.node && window.require) { + ui.startServer = ui.create.system( + "启动服务器", + function (e) { + ui.click.shortcut(false); + e.stopPropagation(); + ui.click.connectMenu(); + }, + true + ); + } + + event.created = true; + var node = ui.create.div(".shadowed"); + node.style.width = "400px"; + node.style.height = "30px"; + node.style.lineHeight = "30px"; + node.style.fontFamily = "xinwei"; + node.style.fontSize = "30px"; + node.style.padding = "10px"; + node.style.left = "calc(50% - 210px)"; + node.style.top = "calc(50% - 20px)"; + node.style.whiteSpace = "nowrap"; + node.textContent = lib.config.last_ip || lib.hallURL; + node.contentEditable = true; + node.style.webkitUserSelect = "text"; + node.style.textAlign = "center"; + node.style.overflow = "hidden"; + + var connect = function (e) { + event.textnode.textContent = "正在连接..."; + clearTimeout(event.timeout); + if (e) e.preventDefault(); + game.saveConfig("last_ip", node.textContent); + game.connect(node.textContent, function (success) { + if (success) { + var info = lib.config.reconnect_info; + if (info && info[0] == _status.ip) { + game.onlineID = info[1]; + if (typeof (game.roomId = info[2]) == "string") game.roomIdServer = true; + } + return; + } + if (event.textnode) { + alert("连接失败"); + event.textnode.textContent = "输入联机地址"; + } + }); + }; + node.addEventListener("keydown", function (e) { + if (e.keyCode == 13) { + connect(e); + } + }); + ui.window.appendChild(node); + ui.ipnode = node; + + var text = event.textnode; + text.style.width = "400px"; + text.style.height = "30px"; + text.style.lineHeight = "30px"; + text.style.fontFamily = "xinwei"; + text.style.fontSize = "30px"; + text.style.padding = "10px"; + text.style.left = "calc(50% - 200px)"; + text.style.top = "calc(50% - 80px)"; + text.style.textAlign = "center"; + ui.window.appendChild(text); + ui.iptext = text; + + var button = ui.create.div(".menubutton.highlight.large.pointerdiv", "连接", connect); + button.style.width = "70px"; + button.style.left = "calc(50% - 35px)"; + button.style.top = "calc(50% + 60px)"; + ui.window.appendChild(button); + ui.ipbutton = button; + + ui.hall_button = ui.create.system( + "联机大厅", + function () { + node.textContent = get.config("hall_ip") || lib.hallURL; + connect(); + }, + true + ); + if (!get.config("hall_button")) { + ui.hall_button.style.display = "none"; + } + ui.recentIP = ui.create.system("最近连接", null, true); + var clickLink = function () { + node.textContent = this.textContent; + connect(); + }; + lib.setPopped( + ui.recentIP, + function () { + if (!lib.config.recentIP.length) return; + var uiintro = ui.create.dialog("hidden"); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + var list = ui.create.div(".caption"); + for (var i = 0; i < lib.config.recentIP.length; i++) { + ui.create.div(".text.textlink", list, clickLink).textContent = get.trimip( + lib.config.recentIP[i] + ); + } + uiintro.add(list); + var clear = uiintro.add('
                        清除
                        '); + clear.style.paddingTop = 0; + clear.style.paddingBottom = "3px"; + clear.listen(function () { + lib.config.recentIP.length = 0; + game.saveConfig("recentIP", []); + uiintro.delete(); + }); + return uiintro; + }, + 220 + ); + if (get.config("read_clipboard", "connect")) { + var ced = false; + var read = (text) => { + try { + var text2 = text.split("\n")[2]; + var ip = text2.slice(5); + if ( + ip.length > 0 && + text2.startsWith("联机地址:") && + (ced || confirm("是否根据剪贴板的邀请链接以进入联机地址和房间?")) + ) { + node.innerHTML = ip; + event.textnode.innerHTML = "正在连接..."; + clearTimeout(event.timeout); + game.saveConfig("last_ip", node.innerHTML); + game.connect(node.innerHTML, function (success) { + if (!success && event.textnode) { + alert("邀请链接解析失败"); + event.textnode.innerHTML = "输入联机地址"; + } + if (success) _status.read_clipboard_text = text; + }); + } + } catch (e) { + console.log(e); + } + }; + window.focus(); + if (navigator.clipboard && lib.node) { + navigator.clipboard + .readText() + .then(read) + .catch((_) => {}); + } else { + var input = ui.create.node("textarea", ui.window, { opacity: "0" }); + input.select(); + var result = document.execCommand("paste"); + input.blur(); + ui.window.removeChild(input); + if (result || input.value.length > 0) read(input.value); + else if (confirm("是否输入邀请链接以进入联机地址和房间?")) { + ced = true; + var text = prompt("请输入邀请链接"); + if (typeof text == "string" && text.length > 0) read(text); + } + } + } + lib.init.onfree(); + }; + if (window.isNonameServer) { + game.connect(window.isNonameServerIp || "localhost"); + } else { + createNode(); + } + if (!game.onlineKey) { + game.onlineKey = localStorage.getItem(lib.configprefix + "key"); + if (!game.onlineKey) { + game.onlineKey = get.id(); + localStorage.setItem(lib.configprefix + "key", game.onlineKey); + } + } + _status.connectDenied = createNode; + setTimeout(lib.init.onfree, 1000); + }, + }; +}); diff --git a/mode/doudizhu.js b/mode/doudizhu.js index c96b92544..9acb775e0 100644 --- a/mode/doudizhu.js +++ b/mode/doudizhu.js @@ -1,3191 +1,3797 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'doudizhu', - start:function(){ - "step 0" - var playback=localStorage.getItem(lib.configprefix+'playback'); - if(playback){ + name: "doudizhu", + start: function () { + "step 0"; + var playback = localStorage.getItem(lib.configprefix + "playback"); + if (playback) { ui.create.me(); - ui.arena.style.display='none'; - ui.system.style.display='none'; - _status.playback=playback; - localStorage.removeItem(lib.configprefix+'playback'); - var store=lib.db.transaction(['video'],'readwrite').objectStore('video'); - store.get(parseInt(playback)).onsuccess=function(e){ - if(e.target.result){ + ui.arena.style.display = "none"; + ui.system.style.display = "none"; + _status.playback = playback; + localStorage.removeItem(lib.configprefix + "playback"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + store.get(parseInt(playback)).onsuccess = function (e) { + if (e.target.result) { game.playVideoContent(e.target.result.video); - } - else{ - alert('播放失败:找不到录像'); + } else { + alert("播放失败:找不到录像"); game.reload(); } - } + }; event.finish(); - } - else if(!_status.connectMode){ + } else if (!_status.connectMode) { game.prepareArena(3); } - "step 1" - event.replacePile=function(){ - var map={ - shuiyanqijunx:'shuiyanqijuny', - bingliang:'binglinchengxia', - fangtian:'toushiche', - wutiesuolian:'toushiche', + "step 1"; + event.replacePile = function () { + var map = { + shuiyanqijunx: "shuiyanqijuny", + bingliang: "binglinchengxia", + fangtian: "toushiche", + wutiesuolian: "toushiche", }; - for(var i=0;i3) num++; - if(lib.character[player.name2]&&get.infoHp(lib.character[player.name2][2])>3) num++; + var next = game.gameDraw(game.zhu || _status.firstAct || game.me); + if (_status.mode == "online") { + game.zhu.$equip(game.createCard("diqi", "club", 13)); + next.num = function (player) { + var num = 4; + if (player == game.zhu) { + if (lib.character[player.name1] && get.infoHp(lib.character[player.name1][2]) > 3) + num++; + if (lib.character[player.name2] && get.infoHp(lib.character[player.name2][2]) > 3) + num++; } return num; }; - } - else if(_status.mode=='binglin'){ - next.num=function(player){ - return (player==game.zhu?5:4); + } else if (_status.mode == "binglin") { + next.num = function (player) { + return player == game.zhu ? 5 : 4; }; } - if(_status.mode!='online'&&_status.connectMode&&lib.configOL.change_card) game.replaceHandcards(game.players.slice(0)); - game.phaseLoop(game.zhu||_status.firstAct||game.me); + if (_status.mode != "online" && _status.connectMode && lib.configOL.change_card) + game.replaceHandcards(game.players.slice(0)); + game.phaseLoop(game.zhu || _status.firstAct || game.me); game.zhu.showGiveup(); }, - game:{ - canReplaceViewpoint:()=>true, - recommendDizhu:[ - 're_guojia','re_huanggai','re_lvbu','re_guanyu','re_sunquan','re_xusheng','re_wuyi','re_sunben', - 'xuyou','zhangchunhua','caochong','zhangsong','zhongyao','wangyi', - 'caochun','maliang','sp_diaochan','quyi','sp_zhaoyun','shamoke', - 'lijue','liuzan','wenyang','shen_lvmeng','shen_ganning', - 'jiakui','wangyuanji','lingcao','miheng', - 'sp_key_yuri','key_hinata','key_rin','key_kyousuke', - 'ns_chendao','jiakui','haozhao', + game: { + canReplaceViewpoint: () => true, + recommendDizhu: [ + "re_guojia", + "re_huanggai", + "re_lvbu", + "re_guanyu", + "re_sunquan", + "re_xusheng", + "re_wuyi", + "re_sunben", + "xuyou", + "zhangchunhua", + "caochong", + "zhangsong", + "zhongyao", + "wangyi", + "caochun", + "maliang", + "sp_diaochan", + "quyi", + "sp_zhaoyun", + "shamoke", + "lijue", + "liuzan", + "wenyang", + "shen_lvmeng", + "shen_ganning", + "jiakui", + "wangyuanji", + "lingcao", + "miheng", + "sp_key_yuri", + "key_hinata", + "key_rin", + "key_kyousuke", + "ns_chendao", + "jiakui", + "haozhao", ], - addRecord:function(bool){ - if(typeof bool=='boolean'){ - var data=lib.config.gameRecord.doudizhu.data; - var identity=game.me.identity; - if(!data[identity]){ - data[identity]=[0,0]; + addRecord: function (bool) { + if (typeof bool == "boolean") { + var data = lib.config.gameRecord.doudizhu.data; + var identity = game.me.identity; + if (!data[identity]) { + data[identity] = [0, 0]; } - if(bool){ + if (bool) { data[identity][0]++; - } - else{ + } else { data[identity][1]++; } - var list=['zhu','fan']; - var str=''; - for(var i=0;i'; + var list = ["zhu", "fan"]; + var str = ""; + for (var i = 0; i < list.length; i++) { + if (data[list[i]]) { + str += + lib.translate[list[i] + "2"] + + ":" + + data[list[i]][0] + + "胜" + + " " + + data[list[i]][1] + + "负
                        "; } } - lib.config.gameRecord.doudizhu.str=str; - game.saveConfig('gameRecord',lib.config.gameRecord); + lib.config.gameRecord.doudizhu.str = str; + game.saveConfig("gameRecord", lib.config.gameRecord); } }, - getState:function(){ - var state={}; - for(var i in lib.playerOL){ - var player=lib.playerOL[i]; - state[i]={identity:player.identity}; + getState: function () { + var state = {}; + for (var i in lib.playerOL) { + var player = lib.playerOL[i]; + state[i] = { identity: player.identity }; } return state; }, - updateState:function(state){ - for(var i in state){ - var player=lib.playerOL[i]; - if(player){ - player.identity=state[i].identity; + updateState: function (state) { + for (var i in state) { + var player = lib.playerOL[i]; + if (player) { + player.identity = state[i].identity; } } }, - updateRoundNumber:function(){ - if(_status.mode=='online'){ - game.broadcastAll(function(num1,num2,top,bonusNum){ - if(ui.cardPileNumber){ - var str=num1+'轮 公共牌堆: '+num2; - if(game.me&&game.me.storage.doudizhu_cardPile&&game.me.storage.doudizhu_cardPile.length) str+=(' 个人牌堆: '+game.me.storage.doudizhu_cardPile.length); - if(bonusNum) str+=('
                        本场叫价: '+bonusNum*100); - ui.cardPileNumber.innerHTML=str; - } - _status.pileTop=top; - },game.roundNumber,ui.cardPile.childNodes.length,ui.cardPile.firstChild,game.bonusNum); + updateRoundNumber: function () { + if (_status.mode == "online") { + game.broadcastAll( + function (num1, num2, top, bonusNum) { + if (ui.cardPileNumber) { + var str = num1 + "轮 公共牌堆: " + num2; + if ( + game.me && + game.me.storage.doudizhu_cardPile && + game.me.storage.doudizhu_cardPile.length + ) + str += " 个人牌堆: " + game.me.storage.doudizhu_cardPile.length; + if (bonusNum) str += "
                        本场叫价: " + bonusNum * 100; + ui.cardPileNumber.innerHTML = str; + } + _status.pileTop = top; + }, + game.roundNumber, + ui.cardPile.childNodes.length, + ui.cardPile.firstChild, + game.bonusNum + ); return; } - game.broadcastAll(function(num1,num2,top){ - if(ui.cardPileNumber) ui.cardPileNumber.innerHTML=num1+'轮 剩余牌: '+num2; - _status.pileTop=top; - },game.roundNumber,ui.cardPile.childNodes.length,ui.cardPile.firstChild); + game.broadcastAll( + function (num1, num2, top) { + if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = num1 + "轮 剩余牌: " + num2; + _status.pileTop = top; + }, + game.roundNumber, + ui.cardPile.childNodes.length, + ui.cardPile.firstChild + ); }, - getRoomInfo:function(uiintro){ - uiintro.add('
                        双将模式:'+(lib.configOL.double_character?'开启':'关闭')); + getRoomInfo: function (uiintro) { + uiintro.add( + '
                        双将模式:' + (lib.configOL.double_character ? "开启" : "关闭") + ); // uiintro.add('
                        屏蔽弱将:'+(lib.configOL.ban_weak?'开启':'关闭')); // var last=uiintro.add('
                        屏蔽强将:'+(lib.configOL.ban_strong?'开启':'关闭')); - if(lib.configOL.banned.length){ - uiintro.add('
                        禁用武将:'+get.translation(lib.configOL.banned)); + if (lib.configOL.banned.length) { + uiintro.add('
                        禁用武将:' + get.translation(lib.configOL.banned)); } - if(lib.configOL.bannedcards.length){ - uiintro.add('
                        禁用卡牌:'+get.translation(lib.configOL.bannedcards)); + if (lib.configOL.bannedcards.length) { + uiintro.add( + '
                        禁用卡牌:' + get.translation(lib.configOL.bannedcards) + ); } - uiintro.style.paddingBottom='8px'; + uiintro.style.paddingBottom = "8px"; }, - getVideoName:function(){ - var str=get.translation(game.me.name); - if(game.me.name2){ - str+='/'+get.translation(game.me.name2); + getVideoName: function () { + var str = get.translation(game.me.name); + if (game.me.name2) { + str += "/" + get.translation(game.me.name2); } var namex; - switch(_status.mode){ - case 'normal':namex='休闲斗地主';break; - case 'kaihei':namex='开黑斗地主';break; - case 'huanle':namex='欢乐斗地主';break; - case 'binglin':namex='兵临城下';break; - case 'online':namex='智斗三国';break; + switch (_status.mode) { + case "normal": + namex = "休闲斗地主"; + break; + case "kaihei": + namex = "开黑斗地主"; + break; + case "huanle": + namex = "欢乐斗地主"; + break; + case "binglin": + namex = "兵临城下"; + break; + case "online": + namex = "智斗三国"; + break; } - var name=[ - str, - namex+' - '+lib.translate[game.me.identity+'2'] - ]; + var name = [str, namex + " - " + lib.translate[game.me.identity + "2"]]; return name; }, - showIdentity:function(me){ - for(var i=0;i1) return; - if(me==game.zhu){ + checkResult: function () { + var me = game.me._trueMe || game.me; + if (game.zhu.isAlive()) { + if ( + _status.mode != "online" && + (_status.mode != "binglin" || game.roundNumber < 3) && + game.players.length > 1 + ) + return; + if (me == game.zhu) { game.over(true); - } - else{ + } else { game.over(false); } - } - else { - if(me==game.zhu){ + } else { + if (me == game.zhu) { game.over(false); - } - else{ + } else { game.over(true); } } }, - checkOnlineResult:function(player){ - if(game.zhu.isAlive()){ - return player.identity=='zhu'; - } - else return player.identity=='fan'; + checkOnlineResult: function (player) { + if (game.zhu.isAlive()) { + return player.identity == "zhu"; + } else return player.identity == "fan"; }, - chooseCharacterZhidou:function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - "step 0" - game.no_continue_game=true; + chooseCharacterZhidou: function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + game.no_continue_game = true; lib.init.onfree(); - "step 1" - ui.arena.classList.add('choose-character'); + "step 1"; + ui.arena.classList.add("choose-character"); var i; - var groups=[]; - event.list=[]; - event.map={}; - var chara=(get.config('character_online')||lib.characterOnline); - for(i in chara){ - var list=chara[i]; - for(var j=0;j=3){ + if (list.length >= 3) { groups.push(i); event.list.addArray(list); } } event.list.randomSort(); - _status.characterlist=event.list.slice(0); - event.controls=['不叫地主','一倍','两倍','三倍']; - for(var player of game.players){ - var id=player.playerid; - player._group=groups.randomRemove(1)[0]; - event.map[id]=chara[player._group].randomGets(4); - player.storage.doudizhu_cardPile=get.cards(20).sort(function(a,b){ - if(a.name!=b.name) return lib.sort.card(a.name,b.name); - else if(a.suit!=b.suit) return lib.suit.indexOf(a)-lib.suit.indexOf(b); - else return a.number-b.number; + _status.characterlist = event.list.slice(0); + event.controls = ["不叫地主", "一倍", "两倍", "三倍"]; + for (var player of game.players) { + var id = player.playerid; + player._group = groups.randomRemove(1)[0]; + event.map[id] = chara[player._group].randomGets(4); + player.storage.doudizhu_cardPile = get.cards(20).sort(function (a, b) { + if (a.name != b.name) return lib.sort.card(a.name, b.name); + else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); + else return a.number - b.number; }); } - event.dialog=ui.create.dialog('你的选将框与底牌',[event.map[game.me.playerid],'character'],game.me.storage.doudizhu_cardPile); - event.start=game.players.randomGet(); - event.current=event.start; + event.dialog = ui.create.dialog( + "你的选将框与底牌", + [event.map[game.me.playerid], "character"], + game.me.storage.doudizhu_cardPile + ); + event.start = game.players.randomGet(); + event.current = event.start; game.delay(7); - "step 2" - event.current.classList.add('glow_phase'); - if(event.current==game.me) event.dialog.content.firstChild.innerHTML='是否叫地主?'; - else{ - event.dialog.content.firstChild.innerHTML='请等待其他玩家叫地主'; + "step 2"; + event.current.classList.add("glow_phase"); + if (event.current == game.me) event.dialog.content.firstChild.innerHTML = "是否叫地主?"; + else { + event.dialog.content.firstChild.innerHTML = "请等待其他玩家叫地主"; game.delay(2); } - event.current.chooseControl(event.controls).set('ai',function(){ + event.current.chooseControl(event.controls).set("ai", function () { return _status.event.getParent().controls.randomGet(); }); - "step 3" - event.current.classList.remove('glow_phase'); - event.current._control=result.control; + "step 3"; + event.current.classList.remove("glow_phase"); + event.current._control = result.control; event.current.chat(result.control); - if(result.control=='三倍'){ - game.bonusNum=3; - game.zhu=event.current; + if (result.control == "三倍") { + game.bonusNum = 3; + game.zhu = event.current; return; + } else if (result.control != "不叫地主") { + event.controls.splice(1, event.controls.indexOf(result.control)); + event.tempDizhu = event.current; + if (result.control == "二倍") game.bonusNum = 2; } - else if(result.control!='不叫地主'){ - event.controls.splice(1,event.controls.indexOf(result.control)); - event.tempDizhu=event.current; - if(result.control=='二倍') game.bonusNum=2; - } - event.current=event.current.next; - if(event.current==event.start&&(event.start==event.tempDizhu||event.start._control=='不叫地主')){ - game.zhu=event.tempDizhu||event.start.previous; - } - else if(event.current==event.start.next&&event.current._control){ - game.zhu=event.tempDizhu; - } - else event.goto(2); - if(event.current==event.start.previous&&!event.tempDizhu) event.controls.remove('不叫地主'); - "step 4" + event.current = event.current.next; + if ( + event.current == event.start && + (event.start == event.tempDizhu || event.start._control == "不叫地主") + ) { + game.zhu = event.tempDizhu || event.start.previous; + } else if (event.current == event.start.next && event.current._control) { + game.zhu = event.tempDizhu; + } else event.goto(2); + if (event.current == event.start.previous && !event.tempDizhu) + event.controls.remove("不叫地主"); + "step 4"; game.updateRoundNumber(); - for(var player of game.players){ - player.identity=player==game.zhu?'zhu':'fan'; + for (var player of game.players) { + player.identity = player == game.zhu ? "zhu" : "fan"; player.showIdentity(); } - event.dialog.content.firstChild.innerHTML='请选择'+get.cnNumber(game.me==game.zhu?2:1)+'张武将牌'; - game.me.chooseButton(event.dialog,true,game.me==game.zhu?2:1).set('filterButton',function(button){ - return typeof button.link=='string'; - }); - "step 5" - game.me.init(result.links[0],result.links[1]); - for(var player of game.players){ - if(player!=game.me){ - if(player==game.zhu){ - var list=event.map[player.playerid].randomGets(2); - player.init(list[0],list[1]); - } - else player.init(event.map[player.playerid].randomGet()); + event.dialog.content.firstChild.innerHTML = + "请选择" + get.cnNumber(game.me == game.zhu ? 2 : 1) + "张武将牌"; + game.me + .chooseButton(event.dialog, true, game.me == game.zhu ? 2 : 1) + .set("filterButton", function (button) { + return typeof button.link == "string"; + }); + "step 5"; + game.me.init(result.links[0], result.links[1]); + for (var player of game.players) { + if (player != game.me) { + if (player == game.zhu) { + var list = event.map[player.playerid].randomGets(2); + player.init(list[0], list[1]); + } else player.init(event.map[player.playerid].randomGet()); } - player.markSkill('doudizhu_cardPile'); + player.markSkill("doudizhu_cardPile"); } - game.zhu.hp=4; - game.zhu.maxHp=4; + game.zhu.hp = 4; + game.zhu.maxHp = 4; game.zhu.update(); - for(var i=0;i队友的选将框
                        '); - list.push([event.map[friend.playerid],'character']); + list.push([event.map[friend.playerid], "character"]); } - game.me.chooseButton(list,true).set('list',event.map[game.me.playerid]).set('filterButton',function(button){ - return _status.event.list.includes(button.link); - }); - "step 6" + game.me + .chooseButton(list, true) + .set("list", event.map[game.me.playerid]) + .set("filterButton", function (button) { + return _status.event.list.includes(button.link); + }); + "step 6"; game.me.init(result.links[0]); - for(var player of game.players){ - if(player!=game.me) player.init(event.map[player.playerid].randomGet()); - if(player==game.zhu){ + for (var player of game.players) { + if (player != game.me) player.init(event.map[player.playerid].randomGet()); + if (player == game.zhu) { player.addSkill(game.zhuSkill); - } - else player.addSkill('binglin_neihong'); + } else player.addSkill("binglin_neihong"); } - if(!game.zhu.isInitFilter('noZhuHp')){ + if (!game.zhu.isInitFilter("noZhuHp")) { game.zhu.maxHp++; game.zhu.hp++; game.zhu.update(); } - for(var i=0;i0.5?'不叫':'叫地主'; + "step 1"; + event.current.chooseControl(event.controls).set("ai", function () { + return Math.random() > 0.5 ? "不叫" : "叫地主"; }); - if(event.current==game.me){ - event.dialog.content.childNodes[0].innerHTML='是否抢地主?'; + if (event.current == game.me) { + event.dialog.content.childNodes[0].innerHTML = "是否抢地主?"; } - "step 2" + "step 2"; event.current.chat(result.control); - if(result.control=='叫地主'||event.current==event.start.next){ - game.zhu=result.control=='叫地主'?event.current:event.current.next; - for(var player of game.players){ - player.identity=player==game.zhu?'zhu':'fan'; + if (result.control == "叫地主" || event.current == event.start.next) { + game.zhu = result.control == "叫地主" ? event.current : event.current.next; + for (var player of game.players) { + player.identity = player == game.zhu ? "zhu" : "fan"; player.showIdentity(); } event.dialog.close(); event.map[game.zhu.playerid].addArray(event.list.randomRemove(3)); - } - else{ - event.current=event.current.next; + } else { + event.current = event.current.next; event.goto(1); game.delay(1.5); } - "step 3" - game.me.chooseButton(['请选择你的武将',[event.map[game.me.playerid],'character']],true); - "step 4" + "step 3"; + game.me.chooseButton( + ["请选择你的武将", [event.map[game.me.playerid], "character"]], + true + ); + "step 4"; game.me.init(result.links[0]); - for(var player of game.players){ - if(player!=game.me) player.init(event.map[player.playerid].randomGet()); + for (var player of game.players) { + if (player != game.me) player.init(event.map[player.playerid].randomGet()); } - if(!game.zhu.isInitFilter('noZhuHp')){ + if (!game.zhu.isInitFilter("noZhuHp")) { game.zhu.maxHp++; game.zhu.hp++; game.zhu.update(); } - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(game.zhu.name){ - if(link!='random'){ - _status.event.parent.fixedseat=get.distance(game.me,game.zhu,'absolute'); + td.innerHTML = "" + get.translation(listi[i] + "2") + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (game.zhu.name) { + if (link != "random") { + _status.event.parent.fixedseat = get.distance( + game.me, + game.zhu, + "absolute" + ); } game.zhu.uninit(); delete game.zhu.isZhu; delete game.zhu.identityShown; } - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - current=seats.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + current = seats.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - if(link=='random'){ - link=['zhu','fan'].randomGet(); - for(var i=0;i0.5?'不叫':'叫地主'; + _status.characterlist = event.list.slice(0); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (map, id) { + ui.create.dialog("你的选将框", [map[game.me.playerid], "character"]).videoId = id; + }, + event.map, + event.videoId + ); + event.start = game.players.randomGet(); + event.current = event.start; + if (event.current != game.me || !event.current.isOnline()) game.delay(3); + "step 1"; + event.current.chooseControl(event.controls).set("ai", function () { + return Math.random() > 0.5 ? "不叫" : "叫地主"; }); - "step 2" + "step 2"; event.current.chat(result.control); - if(result.control=='叫地主'||event.current==event.start.next){ - game.zhu=result.control=='叫地主'?event.current:event.current.next; - for(var player of game.players){ - player.identity=player==game.zhu?'zhu':'fan'; + if (result.control == "叫地主" || event.current == event.start.next) { + game.zhu = result.control == "叫地主" ? event.current : event.current.next; + for (var player of game.players) { + player.identity = player == game.zhu ? "zhu" : "fan"; player.showIdentity(); - player.identityShown=true; + player.identityShown = true; } - game.broadcastAll('closeDialog',event.videoId) + game.broadcastAll("closeDialog", event.videoId); event.map[game.zhu.playerid].addArray(event.list.randomRemove(3)); - } - else{ - event.current=event.current.next; + } else { + event.current = event.current.next; event.goto(1); } - "step 3" - var list=[]; - var str='选择角色'; - for(var i=0;i队友的选将框
                        '); - dialog.push([event.map[friend.playerid],'character']); + dialog.push([event.map[friend.playerid], "character"]); } - list.push([game.players[i],dialog,true,function(){return Math.random()},function(button){ - return _status.event.player._characterChoice.includes(button.link); - }]); + list.push([ + game.players[i], + dialog, + true, + function () { + return Math.random(); + }, + function (button) { + return _status.event.player._characterChoice.includes(button.link); + }, + ]); } - game.me.chooseButtonOL(list,function(player,result){ - if(game.online||player==game.me) player.init(result.links[0]); + game.me.chooseButtonOL(list, function (player, result) { + if (game.online || player == game.me) player.init(result.links[0]); }); - "step 4" - for(var i in lib.playerOL){ - if(!result[i]||result[i]=='ai'||!result[i].links||!result[i].links.length){ - result[i]=event.map[i].randomGet(); + "step 4"; + for (var i in lib.playerOL) { + if (!result[i] || result[i] == "ai" || !result[i].links || !result[i].links.length) { + result[i] = event.map[i].randomGet(); + } else { + result[i] = result[i].links[0]; } - else{ - result[i]=result[i].links[0]; - } - if(!lib.playerOL[i].name){ + if (!lib.playerOL[i].name) { lib.playerOL[i].init(result[i]); } } - if(!game.zhu.isInitFilter('noZhuHp')){ + if (!game.zhu.isInitFilter("noZhuHp")) { game.zhu.maxHp++; game.zhu.hp++; game.zhu.update(); } - game.broadcast(function(result,zhu){ - for(var i in result){ - if(!lib.playerOL[i].name){ - lib.playerOL[i].init(result[i]); + game.broadcast( + function (result, zhu) { + for (var i in result) { + if (!lib.playerOL[i].name) { + lib.playerOL[i].init(result[i]); + } + } + game.zhu = zhu; + if (!game.zhu.isInitFilter("noZhuHp")) { + game.zhu.maxHp++; + game.zhu.hp++; + game.zhu.update(); } - } - game.zhu=zhu; - if(!game.zhu.isInitFilter('noZhuHp')){ - game.zhu.maxHp++; - game.zhu.hp++; - game.zhu.update(); - } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); - },result,game.zhu); - for(var player of game.players){ - if(player==game.zhu){ + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + }, + result, + game.zhu + ); + for (var player of game.players) { + if (player == game.zhu) { player.addSkill(game.zhuSkill); - } - else player.addSkill(['binglin_shaxue','binglin_neihong']); + } else player.addSkill(["binglin_shaxue", "binglin_neihong"]); } - for(var i=0;i=3){ + if (list.length >= 3) { groups.push(i); event.list.addArray(list); } } event.list.randomSort(); - _status.characterlist=event.list.slice(0); - event.controls=['不叫地主','一倍','两倍','三倍']; - for(var player of game.players){ - var id=player.playerid; - player._group=groups.randomRemove(1)[0]; - event.map[id]=chara[player._group].randomGets(3); - player.storage.doudizhu_cardPile=get.cards(20).sort(function(a,b){ - if(a.name!=b.name) return lib.sort.card(a.name,b.name); - else if(a.suit!=b.suit) return lib.suit.indexOf(a)-lib.suit.indexOf(b); - else return a.number-b.number; + _status.characterlist = event.list.slice(0); + event.controls = ["不叫地主", "一倍", "两倍", "三倍"]; + for (var player of game.players) { + var id = player.playerid; + player._group = groups.randomRemove(1)[0]; + event.map[id] = chara[player._group].randomGets(3); + player.storage.doudizhu_cardPile = get.cards(20).sort(function (a, b) { + if (a.name != b.name) return lib.sort.card(a.name, b.name); + else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); + else return a.number - b.number; }); - player.markSkill('doudizhu_cardPile'); + player.markSkill("doudizhu_cardPile"); } - event.start=game.players.randomGet(); - event.current=event.start; + event.start = game.players.randomGet(); + event.current = event.start; - event.videoId=lib.status.videoId++; - game.broadcastAll(function(map,id){ - ui.create.dialog('你的选将框和底牌',[map[game.me.playerid],'character'],game.me.storage.doudizhu_cardPile).videoId=id; - },event.map,event.videoId); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (map, id) { + ui.create.dialog( + "你的选将框和底牌", + [map[game.me.playerid], "character"], + game.me.storage.doudizhu_cardPile + ).videoId = id; + }, + event.map, + event.videoId + ); game.delay(4); - "step 1" - game.broadcastAll(function(id,current){ - var dialog=get.idDialog(id); - if(dialog){ - if(game.me==current) dialog.content.firstChild.innerHTML='是否叫地主?'; - else dialog.content.firstChild.innerHTML='请等待其他玩家叫地主'; - } - },event.videoId,event.current); - if(event.current!=game.me&&!event.current.isOnline()) game.delay(2); - event.current.chooseControl(event.controls).set('ai',function(){ + "step 1"; + game.broadcastAll( + function (id, current) { + var dialog = get.idDialog(id); + if (dialog) { + if (game.me == current) dialog.content.firstChild.innerHTML = "是否叫地主?"; + else dialog.content.firstChild.innerHTML = "请等待其他玩家叫地主"; + } + }, + event.videoId, + event.current + ); + if (event.current != game.me && !event.current.isOnline()) game.delay(2); + event.current.chooseControl(event.controls).set("ai", function () { return _status.event.getParent().controls.randomGet(); }); - "step 2" - event.current._control=result.control; + "step 2"; + event.current._control = result.control; event.current.chat(result.control); - if(result.control=='三倍'){ - game.bonusNum=3; - game.zhu=event.current; + if (result.control == "三倍") { + game.bonusNum = 3; + game.zhu = event.current; return; + } else if (result.control != "不叫地主") { + event.controls.splice(1, event.controls.indexOf(result.control)); + event.tempDizhu = event.current; + if (result.control == "二倍") game.bonusNum = 2; } - else if(result.control!='不叫地主'){ - event.controls.splice(1,event.controls.indexOf(result.control)); - event.tempDizhu=event.current; - if(result.control=='二倍') game.bonusNum=2; - } - event.current=event.current.next; - if(event.current==event.start&&(event.start==event.tempDizhu||event.start._control=='不叫地主')){ - game.zhu=event.tempDizhu||event.start.previous; - } - else if(event.current==event.start.next&&event.current._control){ - game.zhu=event.tempDizhu; - } - else event.goto(1); - if(event.current==event.start.previous&&!event.tempDizhu) event.controls.remove('不叫地主'); - "step 3" - for(var player of game.players){ - player.identity=player==game.zhu?'zhu':'fan'; + event.current = event.current.next; + if ( + event.current == event.start && + (event.start == event.tempDizhu || event.start._control == "不叫地主") + ) { + game.zhu = event.tempDizhu || event.start.previous; + } else if (event.current == event.start.next && event.current._control) { + game.zhu = event.tempDizhu; + } else event.goto(1); + if (event.current == event.start.previous && !event.tempDizhu) + event.controls.remove("不叫地主"); + "step 3"; + for (var player of game.players) { + player.identity = player == game.zhu ? "zhu" : "fan"; player.showIdentity(); - player.identityShown=true; + player.identityShown = true; } - game.broadcastAll('closeDialog',event.videoId); - var list=[]; - for(var i=0;i5){ - num=5; + var num, + num2 = 0; + num = Math.floor(event.list.length / game.players.length); + num2 = event.list.length - num * game.players.length; + if (num > 5) { + num = 5; } - if(num2>2){ - num2=2; + if (num2 > 2) { + num2 = 2; } - for(var i=0;i14; + skill: { + binglin_bingjin: { + trigger: { player: "phaseEnd" }, + forced: true, + ruleSkill: true, + filter: function (event, player) { + return _status.mode == "binglin" && game.roundNumber > 14; }, - content:function(){ + content: function () { player.loseHp(); }, }, - zhuSkill_xiangyang:{ - trigger:{player:'phaseEnd'}, - charlotte:true, - direct:true, - content:function(){ - 'step 0' - player.chooseControl('摸牌阶段','出牌阶段','cancel2').set('prompt','襄阳:是否执行一个额外的阶段?'); - 'step 1' - if(result.control!='cancel2'){ + zhuSkill_xiangyang: { + trigger: { player: "phaseEnd" }, + charlotte: true, + direct: true, + content: function () { + "step 0"; + player + .chooseControl("摸牌阶段", "出牌阶段", "cancel2") + .set("prompt", "襄阳:是否执行一个额外的阶段?"); + "step 1"; + if (result.control != "cancel2") { player.logSkill(event.name); - var next=player[result.index?'phaseUse':'phaseDraw'](); + var next = player[result.index ? "phaseUse" : "phaseDraw"](); event.next.remove(next); trigger.next.push(next); } }, }, - zhuSkill_jiangling:{ - trigger:{player:'phaseUseBegin'}, - direct:true, - charlotte:true, - content:function(){ - 'step 0' - player.chooseControl('加目标','多刀','取消').set('prompt',get.prompt2('zhuSkill_jiangling')).set('ai',()=>(3-game.countPlayer())); - 'step 1' - if(result.index<2){ - player.logSkill('zhuSkill_jiangling'); - player.addTempSkill('zhuSkill_jiangling'+result.index,'phaseUseAfter'); - game.log(player,'选择了','#y'+result.control,'的效果'); + zhuSkill_jiangling: { + trigger: { player: "phaseUseBegin" }, + direct: true, + charlotte: true, + content: function () { + "step 0"; + player + .chooseControl("加目标", "多刀", "取消") + .set("prompt", get.prompt2("zhuSkill_jiangling")) + .set("ai", () => 3 - game.countPlayer()); + "step 1"; + if (result.index < 2) { + player.logSkill("zhuSkill_jiangling"); + player.addTempSkill("zhuSkill_jiangling" + result.index, "phaseUseAfter"); + game.log(player, "选择了", "#y" + result.control, "的效果"); } }, }, - zhuSkill_jiangling0:{ - trigger:{player:'useCard2'}, - direct:true, - charlotte:true, - filter:function(event,player){ - if(event.card.name!='sha'&&get.type(event.card)!='trick') return false; - if(!event.targets||event.targets.length!=1) return false; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + zhuSkill_jiangling0: { + trigger: { player: "useCard2" }, + direct: true, + charlotte: true, + filter: function (event, player) { + if (event.card.name != "sha" && get.type(event.card) != "trick") return false; + if (!event.targets || event.targets.length != 1) return false; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加一个目标' - player.chooseTarget(get.prompt('zhuSkill_jiangling'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return false; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加一个目标"; + player + .chooseTarget(get.prompt("zhuSkill_jiangling"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return false; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('zhuSkill_jiangling',event.targets); - if(trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets); - else{ + "step 2"; + if (event.targets) { + player.logSkill("zhuSkill_jiangling", event.targets); + if (trigger.targets.includes(event.targets[0])) + trigger.targets.removeArray(event.targets); + else { //trigger.directHit.addArray(event.targets); trigger.targets.addArray(event.targets); } } }, }, - zhuSkill_jiangling1:{ - charlotte:true, - mod:{ - cardUsable:function(card,player){ - if(card.name=='sha'||get.type(card)=='trick') return Infinity; + zhuSkill_jiangling1: { + charlotte: true, + mod: { + cardUsable: function (card, player) { + if (card.name == "sha" || get.type(card) == "trick") return Infinity; }, }, }, - zhuSkill_fancheng:{ - enable:'phaseUse', - limited:true, - charlotte:true, - skillAnimation:true, - animationColor:'gray', - content:function(){ - 'step 0' - player.awakenSkill('zhuSkill_fancheng'); - player.chooseControl('杀','其他').set('prompt','选择要强化的伤害').set('ai',()=>get.rand(0,1)); - 'step 1' - player.addSkill('zhuSkill_fancheng'+result.index); - game.log(player,'本局游戏内',result.index?'#g杀以外':'#y杀','的伤害+1'); + zhuSkill_fancheng: { + enable: "phaseUse", + limited: true, + charlotte: true, + skillAnimation: true, + animationColor: "gray", + content: function () { + "step 0"; + player.awakenSkill("zhuSkill_fancheng"); + player + .chooseControl("杀", "其他") + .set("prompt", "选择要强化的伤害") + .set("ai", () => get.rand(0, 1)); + "step 1"; + player.addSkill("zhuSkill_fancheng" + result.index); + game.log(player, "本局游戏内", result.index ? "#g杀以外" : "#y杀", "的伤害+1"); }, - ai:{ - order:100, - result:{player:100}, + ai: { + order: 100, + result: { player: 100 }, }, }, - zhuSkill_fancheng0:{ - trigger:{source:'damageBegin2'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player!=player&&event.card&&event.card.name=='sha'&&event.getParent().name=='sha'; + zhuSkill_fancheng0: { + trigger: { source: "damageBegin2" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.player != player && + event.card && + event.card.name == "sha" && + event.getParent().name == "sha" + ); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.num++; }, - mark:true, - marktext:'殺', - intro:{content:'因执行【杀】的效果对其他角色造成的伤害+1'}, + mark: true, + marktext: "殺", + intro: { content: "因执行【杀】的效果对其他角色造成的伤害+1" }, }, - zhuSkill_fancheng1:{ - trigger:{source:'damageBegin2'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player!=player&&(!event.card||event.card.name!='sha'); + zhuSkill_fancheng1: { + trigger: { source: "damageBegin2" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return event.player != player && (!event.card || event.card.name != "sha"); }, - logTarget:'player', - content:function(){ + logTarget: "player", + content: function () { trigger.num++; }, - mark:true, - marktext:'谋', - intro:{content:'不因【杀】对其他角色造成的伤害+1'}, + mark: true, + marktext: "谋", + intro: { content: "不因【杀】对其他角色造成的伤害+1" }, }, - binglin_shaxue:{ - init:function(player,skill){ - player.addMark(skill,3,false); + binglin_shaxue: { + init: function (player, skill) { + player.addMark(skill, 3, false); }, - trigger:{player:'damageBegin3'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.source&&player!=event.source&&player.identity==event.source.identity&&player.countMark('binglin_shaxue')>0; + trigger: { player: "damageBegin3" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.source && + player != event.source && + player.identity == event.source.identity && + player.countMark("binglin_shaxue") > 0 + ); }, - content:function(){ + content: function () { trigger.cancel(); - player.removeMark('binglin_shaxue',1,false); - trigger.source.removeMark('binglin_shaxue',1,false); + player.removeMark("binglin_shaxue", 1, false); + trigger.source.removeMark("binglin_shaxue", 1, false); }, - intro:{content:'剩余次数:#'}, - ai:{ - viewHandcard:true, - skillTagFilter:function(player,tag,arg){ - return player!=arg&&arg.hasSkill('binglin_shaxue'); + intro: { content: "剩余次数:#" }, + ai: { + viewHandcard: true, + skillTagFilter: function (player, tag, arg) { + return player != arg && arg.hasSkill("binglin_shaxue"); }, }, }, - binglin_neihong:{charlotte:true}, - toushiche_skill:{ - trigger:{player:'phaseJieshuBegin'}, - forced:true, - equipSkill:true, - filter:function(event,player){ - return lib.skill.toushiche_skill.logTarget(null,player).length>0; + binglin_neihong: { charlotte: true }, + toushiche_skill: { + trigger: { player: "phaseJieshuBegin" }, + forced: true, + equipSkill: true, + filter: function (event, player) { + return lib.skill.toushiche_skill.logTarget(null, player).length > 0; }, - logTarget:function(event,player){ - var hs=player.countCards('h'); - return game.filterPlayer(function(current){ - return current!=player&¤t.countCards('h')>hs; + logTarget: function (event, player) { + var hs = player.countCards("h"); + return game.filterPlayer(function (current) { + return current != player && current.countCards("h") > hs; }); }, - content:function(){ - 'step 0' - event.targets=lib.skill.toushiche_skill.logTarget(null,player).sortBySeat(); - 'step 1' - var target=targets.shift(); - if(target.countCards('h')>0) target.chooseToDiscard('h',true); - if(targets.length) event.redo(); + content: function () { + "step 0"; + event.targets = lib.skill.toushiche_skill.logTarget(null, player).sortBySeat(); + "step 1"; + var target = targets.shift(); + if (target.countCards("h") > 0) target.chooseToDiscard("h", true); + if (targets.length) event.redo(); }, }, - online_gongshoujintui:{ - enable:'chooseToUse', - filter:function(event,player){ - var cards=player.getCards('hs'); - for(var i of cards){ - var name=get.name(i,player); - if(name=='gongshoujianbei'){ - if(event.filterCard({ - name:'wanjian', - isCard:true, - cards:[i], - },player,event)||event.filterCard({ - name:'taoyuan', - isCard:true, - cards:[i], - },player,event)) return true; + online_gongshoujintui: { + enable: "chooseToUse", + filter: function (event, player) { + var cards = player.getCards("hs"); + for (var i of cards) { + var name = get.name(i, player); + if (name == "gongshoujianbei") { + if ( + event.filterCard( + { + name: "wanjian", + isCard: true, + cards: [i], + }, + player, + event + ) || + event.filterCard( + { + name: "taoyuan", + isCard: true, + cards: [i], + }, + player, + event + ) + ) + return true; } - if(name=='jintuiziru'){ - if(event.filterCard({ - name:'nanman', - isCard:true, - cards:[i], - },player,event)||event.filterCard({ - name:'wugu', - isCard:true, - cards:[i], - },player,event)) return true; + if (name == "jintuiziru") { + if ( + event.filterCard( + { + name: "nanman", + isCard: true, + cards: [i], + }, + player, + event + ) || + event.filterCard( + { + name: "wugu", + isCard: true, + cards: [i], + }, + player, + event + ) + ) + return true; } } return false; }, - chooseButton:{ - dialog:function(event,player){ - var list=[]; - if(player.countCards('hs','gongshoujianbei')){ - list.push(['锦囊','','wanjian']); - list.push(['锦囊','','taoyuan']); + chooseButton: { + dialog: function (event, player) { + var list = []; + if (player.countCards("hs", "gongshoujianbei")) { + list.push(["锦囊", "", "wanjian"]); + list.push(["锦囊", "", "taoyuan"]); } - if(player.countCards('hs','jintuiziru')){ - list.push(['锦囊','','nanman']); - list.push(['锦囊','','wugu']); + if (player.countCards("hs", "jintuiziru")) { + list.push(["锦囊", "", "nanman"]); + list.push(["锦囊", "", "wugu"]); } - return ui.create.dialog('攻守兼备/进退自如',[list,'vcard'],'hidden'); + return ui.create.dialog("攻守兼备/进退自如", [list, "vcard"], "hidden"); }, - filter:function(button,player){ - var name=button.link[2]; - var rawname=((name=='wanjian'||name=='taoyuan')?'gongshoujianbei':'jintuiziru'); - var cards=player.getCards('hs'); - var evt=_status.event.getParent(); - for(var i of cards){ - if(get.name(i,player)==rawname&&evt.filterCard({ - name:name, - isCard:true, - cards:[i], - },player,evt)) return true; + filter: function (button, player) { + var name = button.link[2]; + var rawname = + name == "wanjian" || name == "taoyuan" ? "gongshoujianbei" : "jintuiziru"; + var cards = player.getCards("hs"); + var evt = _status.event.getParent(); + for (var i of cards) { + if ( + get.name(i, player) == rawname && + evt.filterCard( + { + name: name, + isCard: true, + cards: [i], + }, + player, + evt + ) + ) + return true; } return false; }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2],isCard:true}); + check: function (button) { + return _status.event.player.getUseValue({ name: button.link[2], isCard: true }); }, - backup:function(links){ - var name=links[0][2]; - var rawname=((name=='wanjian'||name=='taoyuan')?'gongshoujianbei':'jintuiziru'); + backup: function (links) { + var name = links[0][2]; + var rawname = + name == "wanjian" || name == "taoyuan" ? "gongshoujianbei" : "jintuiziru"; return { - popname:true, - viewAs:{name:name,isCard:true}, - filterCard:{name:rawname}, - ai1:()=>1, - } + popname: true, + viewAs: { name: name, isCard: true }, + filterCard: { name: rawname }, + ai1: () => 1, + }; + }, + prompt: function (links) { + var name = links[0][2]; + var rawname = + name == "wanjian" || name == "taoyuan" ? "gongshoujianbei" : "jintuiziru"; + return "将一张" + get.translation(rawname) + "当做" + get.translation(name) + "使用"; }, - prompt:function(links){ - var name=links[0][2]; - var rawname=((name=='wanjian'||name=='taoyuan')?'gongshoujianbei':'jintuiziru'); - return '将一张'+get.translation(rawname)+'当做'+get.translation(name)+'使用'; - } }, - ai:{ - order:10, - result:{ - player:1, + ai: { + order: 10, + result: { + player: 1, }, }, }, - doudizhu_cardPile:{ - intro:{ - content:'cardCount', + doudizhu_cardPile: { + intro: { + content: "cardCount", }, }, - kaihei:{ - enable:'phaseUse', - filter:function(event,player){ - return player==game.zhu&&game.hasPlayer(function(current){ - return lib.skill.kaihei.filterTarget(null,player,current); - }); + kaihei: { + enable: "phaseUse", + filter: function (event, player) { + return ( + player == game.zhu && + game.hasPlayer(function (current) { + return lib.skill.kaihei.filterTarget(null, player, current); + }) + ); }, - filterTarget:function(card,player,target){ - return player!=target&&!target.storage.kaihei&&target.countGainableCards(player,'he')>0; + filterTarget: function (card, player, target) { + return ( + player != target && + !target.storage.kaihei && + target.countGainableCards(player, "he") > 0 + ); }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,[1,2],'he',true); - target.storage.kaihei=true; - 'step 1' - if(!result.bool||!result.cards.length){ - event.finish();return; + content: function () { + "step 0"; + player.gainPlayerCard(target, [1, 2], "he", true); + target.storage.kaihei = true; + "step 1"; + if (!result.bool || !result.cards.length) { + event.finish(); + return; } - var num=result.cards.length; - var hs=player.getCards('he'); - if(hs.length){ - if(hs.length<=num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,num,'选择交给'+get.translation(target)+get.cnNumber(num)+'张牌'); - } - else event.finish(); - 'step 2' - if(result.bool&&result.cards&&result.cards.length) player.give(result.cards,target); + var num = result.cards.length; + var hs = player.getCards("he"); + if (hs.length) { + if (hs.length <= num) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "he", + true, + num, + "选择交给" + get.translation(target) + get.cnNumber(num) + "张牌" + ); + } else event.finish(); + "step 2"; + if (result.bool && result.cards && result.cards.length) player.give(result.cards, target); }, - ai:{ - viewHandcard:true, - skillTagFilter:function(player,tag,target){ - if(player==target||player.identity!='fan'||target.identity!='fan') return false; + ai: { + viewHandcard: true, + skillTagFilter: function (player, tag, target) { + if (player == target || player.identity != "fan" || target.identity != "fan") + return false; }, }, }, - feiyang:{ - trigger:{player:'phaseJudgeBegin'}, - charlotte:true, - direct:true, - filter:function(event,player){ - return _status.mode!='online'&&_status.mode!='binglin'&&player==game.zhu&&player.countCards('j')&&player.countCards('h')>1; + feiyang: { + trigger: { player: "phaseJudgeBegin" }, + charlotte: true, + direct: true, + filter: function (event, player) { + return ( + _status.mode != "online" && + _status.mode != "binglin" && + player == game.zhu && + player.countCards("j") && + player.countCards("h") > 1 + ); }, - content:function(){ - "step 0" - player.chooseToDiscard('h',2,get.prompt('feiyang'),'弃置两张手牌,然后弃置判定区里的一张牌').set('logSkill','feiyang').set('ai',function(card){ - if(_status.event.goon) return 6-get.value(card); - return 0; - }).set('goon',(()=>{ - if(player.hasSkillTag('rejudge')&&player.countCards('j')<2) return false; - return player.hasCard(function(card){ - if(get.tag(card,'damage')&&get.damageEffect(player,player,_status.event.player,get.natureList(card))>=0) return false; - return get.effect(player,{ - name:card.viewAs||card.name, - cards:[card], - },player,player)<0; - },'j'); - })()); - "step 1" - if(result.bool){ - player.discardPlayerCard(player,'j',true); + content: function () { + "step 0"; + player + .chooseToDiscard( + "h", + 2, + get.prompt("feiyang"), + "弃置两张手牌,然后弃置判定区里的一张牌" + ) + .set("logSkill", "feiyang") + .set("ai", function (card) { + if (_status.event.goon) return 6 - get.value(card); + return 0; + }) + .set( + "goon", + (() => { + if (player.hasSkillTag("rejudge") && player.countCards("j") < 2) return false; + return player.hasCard(function (card) { + if ( + get.tag(card, "damage") && + get.damageEffect( + player, + player, + _status.event.player, + get.natureList(card) + ) >= 0 + ) + return false; + return ( + get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ) < 0 + ); + }, "j"); + })() + ); + "step 1"; + if (result.bool) { + player.discardPlayerCard(player, "j", true); } }, }, - bahu:{ - trigger:{player:'phaseZhunbeiBegin'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return _status.mode!='online'&&_status.mode!='binglin'&&player==game.zhu; + bahu: { + trigger: { player: "phaseZhunbeiBegin" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return _status.mode != "online" && _status.mode != "binglin" && player == game.zhu; }, - content:function(){ + content: function () { player.draw(); }, - mod:{ - cardUsable:function(card,player,num){ - if(_status.mode!='online'&&_status.mode!='binglin'&&player==game.zhu&&card.name=='sha') return num+1; + mod: { + cardUsable: function (card, player, num) { + if ( + _status.mode != "online" && + _status.mode != "binglin" && + player == game.zhu && + card.name == "sha" + ) + return num + 1; }, }, }, - diqi_skill:{ - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - var card=player.getEquip('diqi'); - return get.itemtype(card)=='card'&&lib.filter.cardDiscardable(card,player,'diqi_skill'); + diqi_skill: { + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + var card = player.getEquip("diqi"); + return ( + get.itemtype(card) == "card" && lib.filter.cardDiscardable(card, player, "diqi_skill") + ); }, - check:function(event,player){ - return event.num>=Math.min(player.hp,2); + check: function (event, player) { + return event.num >= Math.min(player.hp, 2); }, - prompt2:function(event,player){ - return '弃置'+get.translation(player.getEquip('diqi'))+'并防止即将受到的'+get.cnNumber(event.num)+'点伤害'; + prompt2: function (event, player) { + return ( + "弃置" + + get.translation(player.getEquip("diqi")) + + "并防止即将受到的" + + get.cnNumber(event.num) + + "点伤害" + ); }, - content:function(){ - player.discard(player.getEquip('diqi')); + content: function () { + player.discard(player.getEquip("diqi")); trigger.cancel(); }, - ai:{ - filterDamage:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.player){ - if(arg.player.hasSkillTag('jueqing',false,player)) return false; + ai: { + filterDamage: true, + skillTagFilter: function (player, tag, arg) { + if (arg && arg.player) { + if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, - online_aozhan:{ - trigger:{player:'phaseBefore'}, - forced:true, - popup:false, - firstDo:true, - filter:function(event,player){ - return !_status._aozhan&&game.roundNumber>10; + online_aozhan: { + trigger: { player: "phaseBefore" }, + forced: true, + popup: false, + firstDo: true, + filter: function (event, player) { + return !_status._aozhan && game.roundNumber > 10; }, - content:function(){ - var color=get.groupnature(player.group,"raw"); - if(player.isUnseen()) color='fire'; - player.$fullscreenpop('鏖战模式',color); - game.broadcastAll(function(){ - _status._aozhan=true; - ui.aozhan=ui.create.div('.touchinfo.left',ui.window); - ui.aozhan.innerHTML='鏖战模式'; - if(ui.time3) ui.time3.style.display='none'; - ui.aozhanInfo=ui.create.system('鏖战模式',null,true); - lib.setPopped(ui.aozhanInfo,function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add('鏖战模式'); - var list=[ - '从第11轮开始,游戏将进入〔鏖战模式〕。', - '在鏖战模式下,任何角色均不是非转化的【桃】的合法目标。【桃】可以被当做【杀】或【闪】使用或打出。', - ]; - var intro='
                          '; - for(var i=0;i'+intro+'
                        '); - var ul=uiintro.querySelector('ul'); - if(ul){ - ul.style.width='180px'; - } - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + content: function () { + var color = get.groupnature(player.group, "raw"); + if (player.isUnseen()) color = "fire"; + player.$fullscreenpop("鏖战模式", color); + game.broadcastAll(function () { + _status._aozhan = true; + ui.aozhan = ui.create.div(".touchinfo.left", ui.window); + ui.aozhan.innerHTML = "鏖战模式"; + if (ui.time3) ui.time3.style.display = "none"; + ui.aozhanInfo = ui.create.system("鏖战模式", null, true); + lib.setPopped( + ui.aozhanInfo, + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.add("鏖战模式"); + var list = [ + "从第11轮开始,游戏将进入〔鏖战模式〕。", + "在鏖战模式下,任何角色均不是非转化的【桃】的合法目标。【桃】可以被当做【杀】或【闪】使用或打出。", + ]; + var intro = '
                          '; + for (var i = 0; i < list.length; i++) { + intro += "
                        • " + list[i]; + } + intro += "
                        "; + uiintro.add('
                        ' + intro + "
                        "); + var ul = uiintro.querySelector("ul"); + if (ul) { + ul.style.width = "180px"; + } + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); game.playBackgroundMusic(); }); - game.removeGlobalSkill('online_aozhan'); - game.countPlayer(function(current){current.addSkill('aozhan')}); + game.removeGlobalSkill("online_aozhan"); + game.countPlayer(function (current) { + current.addSkill("aozhan"); + }); }, }, - online_juzhong:{ - trigger:{global:'useCard'}, - direct:true, - ruleSkill:true, - filter:function(event,player){ - return _status.mode=='online'&&!event.all_excluded&&event.player.isFriendOf(player)&&event.player!=player&&lib.skill.online_juzhong.infos[event.card.name]&&player.hasCard(function(card){ - if(_status.connectMode) return true; - return get.name(card,player)==event.card.name; - },'h'); + online_juzhong: { + trigger: { global: "useCard" }, + direct: true, + ruleSkill: true, + filter: function (event, player) { + return ( + _status.mode == "online" && + !event.all_excluded && + event.player.isFriendOf(player) && + event.player != player && + lib.skill.online_juzhong.infos[event.card.name] && + player.hasCard(function (card) { + if (_status.connectMode) return true; + return get.name(card, player) == event.card.name; + }, "h") + ); }, - content:function(){ - 'step 0' - player.chooseToDiscard('是否响应【聚众】?',get.translation(trigger.player)+'使用了'+get.translation(trigger.card)+'。你可弃置一张名称相同的牌,令'+lib.skill.online_juzhong.infos[trigger.card.name][0],function(card,player){ - return get.name(card,player)==_status.event.getTrigger().card.name; - }).set('ai',lib.skill.online_juzhong.infos[trigger.card.name][2]).logSkill=['_juzhong',trigger.player]; - 'step 1' - if(result.bool){ + content: function () { + "step 0"; + player + .chooseToDiscard( + "是否响应【聚众】?", + get.translation(trigger.player) + + "使用了" + + get.translation(trigger.card) + + "。你可弃置一张名称相同的牌,令" + + lib.skill.online_juzhong.infos[trigger.card.name][0], + function (card, player) { + return get.name(card, player) == _status.event.getTrigger().card.name; + } + ) + .set("ai", lib.skill.online_juzhong.infos[trigger.card.name][2]).logSkill = [ + "_juzhong", + trigger.player, + ]; + "step 1"; + if (result.bool) { lib.skill.online_juzhong.infos[trigger.card.name][1](); - if(!event.goon) event.finish(); - } - else event.finish(); - 'step 2' - trigger.player.chooseTarget('你可选择一名角色,弃置其的一张牌',function(card,player,target){ - return target.countDiscardableCards(player,'he')>0; - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - trigger.player.line(target,'green'); - trigger.player.discardPlayerCard(target,true,'he'); + if (!event.goon) event.finish(); + } else event.finish(); + "step 2"; + trigger.player + .chooseTarget("你可选择一名角色,弃置其的一张牌", function (card, player, target) { + return target.countDiscardableCards(player, "he") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + trigger.player.line(target, "green"); + trigger.player.discardPlayerCard(target, true, "he"); } }, - infos:{ - sha:['此【杀】的伤害值基数+1。',function(){ - var evt=_status.event._trigger; - if(!evt.baseDamage) evt.baseDamage=1; - evt.baseDamage++; - },function(card){ - var evt=_status.event.getTrigger(); - if(!evt.targets.length) return 0; - if(evt.targets[0].hasShan()||evt.targets[0].hasSkillTag('filterDamage',null,{ - player:evt.targets[0], - card:evt.card, - })) return 0; - return 1; - }], - shan:['其可弃置一名角色的一张牌。',function(){ - _status.event.goon=true; - },function(card){ - if(game.zhu.countCards('he',function(card){ - return get.value(card,game.zhu)>=6; - })) return 7-get.value(card); - if(game.zhu.countCards('he',function(card){ - return get.value(card,game.zhu)>0 - })) return 5-get.value(card); - return 0; - }], - tao:['其摸两张牌。',function(){ - _status.event._trigger.player.draw(2); - },function(card){ - return 6-get.value(card); - }], - jiu:['其本回合的伤害值或回复值+1。',function(){ - var player=_status.event._trigger.player; - player.addTempSkill('juzhong_jiu'); - player.addMark('juzhong_jiu',1,false); - },function(card){ - return 6-get.value(card); - }], + infos: { + sha: [ + "此【杀】的伤害值基数+1。", + function () { + var evt = _status.event._trigger; + if (!evt.baseDamage) evt.baseDamage = 1; + evt.baseDamage++; + }, + function (card) { + var evt = _status.event.getTrigger(); + if (!evt.targets.length) return 0; + if ( + evt.targets[0].hasShan() || + evt.targets[0].hasSkillTag("filterDamage", null, { + player: evt.targets[0], + card: evt.card, + }) + ) + return 0; + return 1; + }, + ], + shan: [ + "其可弃置一名角色的一张牌。", + function () { + _status.event.goon = true; + }, + function (card) { + if ( + game.zhu.countCards("he", function (card) { + return get.value(card, game.zhu) >= 6; + }) + ) + return 7 - get.value(card); + if ( + game.zhu.countCards("he", function (card) { + return get.value(card, game.zhu) > 0; + }) + ) + return 5 - get.value(card); + return 0; + }, + ], + tao: [ + "其摸两张牌。", + function () { + _status.event._trigger.player.draw(2); + }, + function (card) { + return 6 - get.value(card); + }, + ], + jiu: [ + "其本回合的伤害值或回复值+1。", + function () { + var player = _status.event._trigger.player; + player.addTempSkill("juzhong_jiu"); + player.addMark("juzhong_jiu", 1, false); + }, + function (card) { + return 6 - get.value(card); + }, + ], }, - ai:{ - viewHandcard:true, - skillTagFilter:function(player,tag,target){ - if(_status.mode!='online'||player==target||player.identity!=target.identity) return false; + ai: { + viewHandcard: true, + skillTagFilter: function (player, tag, target) { + if ( + _status.mode != "online" || + player == target || + player.identity != target.identity + ) + return false; }, }, }, - juzhong_jiu:{ - trigger:{ - player:'recoverBegin', - source:'damageBegin1', + juzhong_jiu: { + trigger: { + player: "recoverBegin", + source: "damageBegin1", }, - forced:true, - popup:false, - content:function(){ - trigger.num+=player.countMark('juzhong_jiu'); + forced: true, + popup: false, + content: function () { + trigger.num += player.countMark("juzhong_jiu"); }, - onremove:true, - intro:{content:'本回合的伤害值和回复值+#'}, + onremove: true, + intro: { content: "本回合的伤害值和回复值+#" }, }, - online_zhadan_button:{ - trigger:{ - global:'gameDrawAfter', - player:['gainEnd','loseEnd'], + online_zhadan_button: { + trigger: { + global: "gameDrawAfter", + player: ["gainEnd", "loseEnd"], }, - firstDo:true, - forced:true, - charlotte:true, - popup:false, - silent:true, - filter:function(event,player){ - if(_status.mode!='online'||(player!=game.me&&!player.isOnline())) return; - if(event.name!='lose') return !player.hasZhadan&&player.countCards('hs','zhadan')>0; - return player.hasZhadan&&!player.countCards('hs','zhadan'); + firstDo: true, + forced: true, + charlotte: true, + popup: false, + silent: true, + filter: function (event, player) { + if (_status.mode != "online" || (player != game.me && !player.isOnline())) return; + if (event.name != "lose") + return !player.hasZhadan && player.countCards("hs", "zhadan") > 0; + return player.hasZhadan && !player.countCards("hs", "zhadan"); }, - content:function(){ - if(!player.hasZhadan){ - player.hasZhadan=true; - if(player==game.me) lib.skill.online_zhadan_button.initZhadan(); - else player.send(function(){lib.skill.online_zhadan_button.initZhadan()}); - } - else{ + content: function () { + if (!player.hasZhadan) { + player.hasZhadan = true; + if (player == game.me) lib.skill.online_zhadan_button.initZhadan(); + else + player.send(function () { + lib.skill.online_zhadan_button.initZhadan(); + }); + } else { delete player.hasZhadan; - if(player==game.me) lib.skill.online_zhadan_button.removeZhadan(); - else player.send(function(){lib.skill.online_zhadan_button.removeZhadan()}); + if (player == game.me) lib.skill.online_zhadan_button.removeZhadan(); + else + player.send(function () { + lib.skill.online_zhadan_button.removeZhadan(); + }); } }, - initZhadan:function(){ - ui.zhadan_button=ui.create.control('激活炸弹','stayleft',function(){ - if(this.classList.contains('hidden')) return; - this.classList.toggle('glow'); - if(this.classList.contains('glow')&&_status.event.type=='zhadan'&& - _status.event.isMine()&&ui.confirm&&_status.imchoosing){ + initZhadan: function () { + ui.zhadan_button = ui.create.control("激活炸弹", "stayleft", function () { + if (this.classList.contains("hidden")) return; + this.classList.toggle("glow"); + if ( + this.classList.contains("glow") && + _status.event.type == "zhadan" && + _status.event.isMine() && + ui.confirm && + _status.imchoosing + ) { ui.click.cancel(ui.confirm.lastChild); } }); }, - removeZhadan:function(){ - if(ui.zhadan_button){ + removeZhadan: function () { + if (ui.zhadan_button) { ui.zhadan_button.remove(); delete ui.zhadan_button; } }, }, - online_zhadan:{ - trigger:{player:'useCard'}, - priority:5, - popup:false, - forced:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.hasCard(function(card){ - if(get.name(card)!='zhadan') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - },'hs'); + online_zhadan: { + trigger: { player: "useCard" }, + priority: 5, + popup: false, + forced: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.hasCard(function (card) { + if (get.name(card) != "zhadan") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }, "hs"); }); }, - forceLoad:true, - content:function(){ - 'step 0' - event.source=trigger.player; - event.card=trigger.card; - event.targets=trigger.targets; - event._global_waiting=true; - event.filterCard=function(card,player){ - if(get.name(card)!='zhadan'||get.itemtype(card)!='card') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); + forceLoad: true, + content: function () { + "step 0"; + event.source = trigger.player; + event.card = trigger.card; + event.targets = trigger.targets; + event._global_waiting = true; + event.filterCard = function (card, player) { + if (get.name(card) != "zhadan" || get.itemtype(card) != "card") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); }; - event.send=function(player,card,source,targets,id,id2,skillState){ - if(skillState){ + event.send = function (player, card, source, targets, id, id2, skillState) { + if (skillState) { player.applySkills(skillState); } - if(player==game.me&&ui.zhadan_button&&!ui.zhadan_button.classList.contains('glow')){ - _status.event._result={bool:false}; - if(game.online){ - _status.event._resultid=id; + if ( + player == game.me && + ui.zhadan_button && + !ui.zhadan_button.classList.contains("glow") + ) { + _status.event._result = { bool: false }; + if (game.online) { + _status.event._resultid = id; game.resume(); } return; } - var str=get.translation(source); - if(targets&&targets.length){ - str+='对'+get.translation(targets); + var str = get.translation(source); + if (targets && targets.length) { + str += "对" + get.translation(targets); } - str+='使用了'; - str+=get.translation(card); - str+=',是否对其使用【炸弹】?'; + str += "使用了"; + str += get.translation(card); + str += ",是否对其使用【炸弹】?"; - var next=player.chooseToUse({ - filterCard:function(card,player){ - if(get.name(card)!='zhadan'||get.itemtype(card)!='card') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); + var next = player.chooseToUse({ + filterCard: function (card, player) { + if (get.name(card) != "zhadan" || get.itemtype(card) != "card") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); }, - prompt:str, - _global_waiting:true, - ai1:function(card){ - var evt=_status.event.getParent('_zhadan')._trigger,player=_status.event.player; - if(!evt) return 0; - if(get.attitude(player,evt.player)>0) return 0; - var eff=0; - if(!targets.length) return Math.random()-0.5; - for(var i of targets) eff-=get.effect(i,evt.card,evt.player,player); - return eff-8; + prompt: str, + _global_waiting: true, + ai1: function (card) { + var evt = _status.event.getParent("_zhadan")._trigger, + player = _status.event.player; + if (!evt) return 0; + if (get.attitude(player, evt.player) > 0) return 0; + var eff = 0; + if (!targets.length) return Math.random() - 0.5; + for (var i of targets) eff -= get.effect(i, evt.card, evt.player, player); + return eff - 8; }, - source:source, - source2:targets, - id:id, - id2:id2, - type:'zhadan', + source: source, + source2: targets, + id: id, + id2: id2, + type: "zhadan", }); - next.set('respondTo',[source,card]); + next.set("respondTo", [source, card]); - if(game.online){ - _status.event._resultid=id; + if (game.online) { + _status.event._resultid = id; game.resume(); - } - else{ - next.nouse=true; + } else { + next.nouse = true; } }; - 'step 1' - var list=game.filterPlayer(function(current){ - return current.hasCard(function(card){ - if(get.name(card)!='zhadan') return false; - return lib.filter.cardEnabled(card,player,'forceEnable'); - },'hs'); + "step 1"; + var list = game.filterPlayer(function (current) { + return current.hasCard(function (card) { + if (get.name(card) != "zhadan") return false; + return lib.filter.cardEnabled(card, player, "forceEnable"); + }, "hs"); }); - event.list=list; - event.id=get.id(); - list.sort(function(a,b){ - return get.distance(event.source,a,'absolute')-get.distance(event.source,b,'absolute'); + event.list = list; + event.id = get.id(); + list.sort(function (a, b) { + return ( + get.distance(event.source, a, "absolute") - + get.distance(event.source, b, "absolute") + ); }); - 'step 2' - if(event.list.length==0){ + "step 2"; + if (event.list.length == 0) { event.finish(); - } - else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)){ + } else if ( + _status.connectMode && + (event.list[0].isOnline() || event.list[0] == game.me) + ) { event.goto(4); + } else { + event.current = event.list.shift(); + event.send( + event.current, + event.card, + event.source, + event.targets, + event.id, + trigger.parent.id + ); } - else{ - event.current=event.list.shift(); - event.send(event.current,event.card,event.source,event.targets,event.id,trigger.parent.id); - } - 'step 3' - if(result.bool){ - event.zhadanresult=event.current; - event.zhadanresult2=result; - if(event.current!=game.me&&!event.current.isOnline()) game.delayx(); + "step 3"; + if (result.bool) { + event.zhadanresult = event.current; + event.zhadanresult2 = result; + if (event.current != game.me && !event.current.isOnline()) game.delayx(); event.goto(8); - } - else{ + } else { event.goto(2); } - 'step 4' - var id=event.id; - var sendback=function(result,player){ - if(result&&result.id==id&&!event.zhadanresult&&result.bool){ - event.zhadanresult=player; - event.zhadanresult2=result; - game.broadcast('cancel',id); - if(_status.event.id==id&&_status.event.name=='chooseToUse'&&_status.paused){ - return (function(){ - event.resultOL=_status.event.resultOL; + "step 4"; + var id = event.id; + var sendback = function (result, player) { + if (result && result.id == id && !event.zhadanresult && result.bool) { + event.zhadanresult = player; + event.zhadanresult2 = result; + game.broadcast("cancel", id); + if ( + _status.event.id == id && + _status.event.name == "chooseToUse" && + _status.paused + ) { + return function () { + event.resultOL = _status.event.resultOL; ui.click.cancel(); - if(ui.confirm) ui.confirm.close(); - }); + if (ui.confirm) ui.confirm.close(); + }; } - } - else{ - if(_status.event.id==id&&_status.event.name=='chooseToUse'&&_status.paused){ - return (function(){ - event.resultOL=_status.event.resultOL; - }); + } else { + if ( + _status.event.id == id && + _status.event.name == "chooseToUse" && + _status.paused + ) { + return function () { + event.resultOL = _status.event.resultOL; + }; } } }; - var withme=false; - var withol=false; - var list=event.list; - for(var i=0;inum1) num1=num; - if(num num1) num1 = num; + if (num < num2) num2 = num; }); - var num=target.countCards('h'),choices=[]; - event.addIndex=0; - if(num num2) { + choices.push("令" + str + "将手牌弃置至" + get.cnNumber(num2) + "张"); + event.num2 = num2; } - else event.addIndex++; - if(num>num2){ - choices.push('令'+str+'将手牌弃置至'+get.cnNumber(num2)+'张'); - event.num2=num2; - } - if(!choices.length) event.finish(); - else if(choices.length==1) event._result={index:0}; - else player.chooseControl().set('choiceList',choices).set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0?0:1; - }); - 'step 1' - if(result.index+event.addIndex==0){ - target.drawTo(event.num1); - } - else target.chooseToDiscard(true,'h',target.countCards('h')-event.num2); - }, - ai:{ - order:6, - value:4, - useful:2, - tag:{ - draw:1, - loseCard:1, - }, - result:{ - target:function(player,target,card,isLink){ - var num1=0,num2=Infinity,str=get.translation(target); - game.countPlayer(function(current){ - var num=current.countCards('h',function(cardx){ - if(ui.selected.cards.includes(cardx)) return false; - if(card.cards&&card.cards.includes(cardx)) return false; - return true; - }); - if(num>num1) num1=num; - if(num 0 ? 0 : 1; }); - var num=target.countCards('h',function(cardx){ - if(ui.selected.cards.includes(cardx)) return false; - if(card.cards&&card.cards.includes(cardx)) return false; + "step 1"; + if (result.index + event.addIndex == 0) { + target.drawTo(event.num1); + } else target.chooseToDiscard(true, "h", target.countCards("h") - event.num2); + }, + ai: { + order: 6, + value: 4, + useful: 2, + tag: { + draw: 1, + loseCard: 1, + }, + result: { + target: function (player, target, card, isLink) { + var num1 = 0, + num2 = Infinity, + str = get.translation(target); + game.countPlayer(function (current) { + var num = current.countCards("h", function (cardx) { + if (ui.selected.cards.includes(cardx)) return false; + if (card.cards && card.cards.includes(cardx)) return false; + return true; + }); + if (num > num1) num1 = num; + if (num < num2) num2 = num; + }); + var num = target.countCards("h", function (cardx) { + if (ui.selected.cards.includes(cardx)) return false; + if (card.cards && card.cards.includes(cardx)) return false; return true; }); - if(num1>num){ - if(get.attitude(player,target)>0) return (num1-num)/1.2; + if (num1 > num) { + if (get.attitude(player, target) > 0) return (num1 - num) / 1.2; } - if(num20) return (num2-num)/1.2; + if (num2 < num) { + if (get.attitude(player, target) > 0) return (num2 - num) / 1.2; } return 0; - } - } - } - }, - shuiyanqijuny:{ - fullskin:true, - cardimage:'shuiyanqijunx', - enable:true, - filterTarget:true, - type:'trick', - selectTarget:[1,2], - targetprompt:['受伤弃牌','受伤摸牌'], - contentBefore:function(){ - var evt=event.getParent(),target=evt.stocktargets[0]; - evt.shuiyanqijun_target=target; - }, - content:function(){ - target.damage('thunder'); - if(target!=event.getParent().shuiyanqijun_target) target.draw(); - else target.chooseToDiscard('he',true); - }, - ai:{ - order:6, - value:4, - useful:2, - tag:{ - damage:1, - thunderDamage:1, - natureDamage:1, - loseCard:1, - }, - result:{ - target:function(player,target){ - if(!ui.selected.targets.length) return -1.5; - return -0.5 - } - } - } - }, - luojingxiashi:{ - fullskin:true, - enable:true, - type:'trick', - selectTarget:-1, - filterTarget:function(card,player,target){ - return target!=player&&target.isDamaged(); - }, - content:function(){ - target.damage(); - }, - ai:{ - order:3, - value:4, - useful:2, - tag:{ - loseCard:1, - }, - result:{ - target:-1.5, - } - } - }, - binglinchengxia:{ - fullskin:true, - type:'delay', - filterTarget:function(card,player,target){ - return (lib.filter.judge(card,player,target)&&player!=target); - }, - judge:function(card){ - if(get.suit(card)=='diamond') return 0; - return -3; - }, - effect:function(){ - 'step 0' - if(result.bool==false){ - if(!player.countCards('e',function(card){ - return lib.filter.cardDiscardable(card,player,'shuiyanqijuny'); - })){ - player.damage('nosource'); - event.finish(); - return; - } - else player.chooseControl('discard_card','take_damage',function(event,player){ - if(get.damageEffect(player,event.player,player)>=0){ - return 'take_damage'; - } - if(player.hp>=3&&player.countCards('e')>=2){ - return 'take_damage'; - } - return 'discard_card'; - }); - } - else event.finish(); - 'step 1' - if(result.control=='discard_card'){ - player.discard(player.getCards('e',function(card){ - return lib.filter.cardDiscardable(card,player,'shuiyanqijuny'); - })); - } - else player.damage('nosource'); - }, - ai:{ - order:1, - value:3, - useful:2, - tag:{ - damage:1, - loseCard:1, - }, - result:{ - target:function(player,target,card,isLink){ - var es=target.getCards('e'); - if(!es.length) return -1.5; - var val=0; - for(var i of es) val+=get.value(i,target); - return -Math.min(1.5,val/5); - } - } - } - }, - toushiche:{ - fullskin:true, - type:'equip', - subtype:'equip1', - distance:{attackFrom:-3}, - ai:{ - basic:{ - equipValue:2.5 - } - }, - skills:['toushiche_skill'] - }, - gongshoujianbei:{ - fullskin:true, - type:'trick', - }, - jintuiziru:{ - fullskin:true, - type:'trick', - }, - diqi:{ - fullskin:true, - type:"equip", - subtype:"equip2", - skills:['diqi_skill'], - destroy:'diqi_skill', - ai:{ - basic:{ - equipValue:6 - }, - }, - }, - zhadan:{ - audio:true, - fullskin:true, - type:'trick', - ai:{ - basic:{ - useful:[6,4], - value:[6,4], - }, - result:{player:1}, - }, - notarget:true, - content:function(){ - var evt=event.getParent(2)._trigger; - evt.targets.length=0; - evt.all_excluded=true; - game.log(evt.card,'的效果被炸弹抵消了'); - }, - }, - jiwangkailai:{ - audio:true, - fullskin:true, - type:'trick', - enable:function(card,player){ - var hs=player.getCards('h',function(cardx){ - return cardx!=card&&(!card.cards||!card.cards.includes(cardx)); - }); - if(!hs.length) return false; - var use=true,discard=true; - for(var i of hs){ - if(use&&!game.checkMod(i,player,'unchanged','cardEnabled2',player)) use=false; - if(discard&&!lib.filter.cardDiscardable(i,player,'jiwangkailai')) discard=false; - if(!use&&!discard) return false; - } - return true; - }, - selectTarget:-1, - toself:true, - filterTarget:function(card,player,target){ - return target==player; - }, - modTarget:true, - content:function(){ - 'step 0' - var hs=player.getCards('h'); - if(hs.length){ - var use=true,discard=true; - for(var i of hs){ - if(use&&!game.checkMod(i,player,'unchanged','cardEnabled2',player)) use=false; - if(discard&&!lib.filter.cardDiscardable(i,player,'jiwangkailai')) discard=false; - if(!use&&!discard) break; - } - if(use&&discard) player.chooseControl().set('prompt','继往开来:请选择一项').set('choiceList',[ - '弃置所有手牌,然后摸等量的牌', - '将所有手牌当做一张普通锦囊牌使用', - ]).set('ai',function(){ - if(_status.event.player.countCards('h')>2) return 0; - return 1; - }); - else if(use) event._result={index:1}; - else if(discard) event._result={index:0}; - else event.finish(); - } - else event.finish(); - 'step 1' - var cards=player.getCards('h'); - if(result.index==0){ - player.discard(cards); - player.draw(cards.length); - event.finish(); - } - else{ - var list=[]; - for(var i of lib.inpile){ - if(i!='jiwangkailai'&&get.type(i)=='trick'&&lib.filter.filterCard({name:i,cards:cards},player)) list.push(['锦囊','',i]); - } - if(list.length){ - player.chooseButton(['继往开来:选择要使用的牌',[list,'vcard']],true).set('ai',function(button){ - var player=_status.event.player; - return player.getUseValue({name:button.link[2],cards:player.getCards('h')}); - }); - } - else event.finish(); - } - 'step 2' - if(result.bool) player.chooseUseTarget({name:result.links[0][2]},player.getCards('h'),true); - }, - ai:{ - basic:{ - order:0.5, - useful:3, - value:5 - }, - result:{ - target:function(player,target){ - if(target.needsToDiscard(1)||!target.countCards('h',function(card){ - return get.value(card,player)>=5.5; - })) return 1; - return 0; }, }, - tag:{ - draw:2 + }, + }, + luojingxiashi: { + fullskin: true, + enable: true, + type: "trick", + selectTarget: -1, + filterTarget: function (card, player, target) { + return target != player && target.isDamaged(); + }, + content: function () { + target.damage(); + }, + ai: { + order: 3, + value: 4, + useful: 2, + tag: { + loseCard: 1, + }, + result: { + target: -1.5, + }, + }, + }, + binglinchengxia: { + fullskin: true, + type: "delay", + filterTarget: function (card, player, target) { + return lib.filter.judge(card, player, target) && player != target; + }, + judge: function (card) { + if (get.suit(card) == "diamond") return 0; + return -3; + }, + effect: function () { + "step 0"; + if (result.bool == false) { + if ( + !player.countCards("e", function (card) { + return lib.filter.cardDiscardable(card, player, "shuiyanqijuny"); + }) + ) { + player.damage("nosource"); + event.finish(); + return; + } else + player.chooseControl("discard_card", "take_damage", function (event, player) { + if (get.damageEffect(player, event.player, player) >= 0) { + return "take_damage"; + } + if (player.hp >= 3 && player.countCards("e") >= 2) { + return "take_damage"; + } + return "discard_card"; + }); + } else event.finish(); + "step 1"; + if (result.control == "discard_card") { + player.discard( + player.getCards("e", function (card) { + return lib.filter.cardDiscardable(card, player, "shuiyanqijuny"); + }) + ); + } else player.damage("nosource"); + }, + ai: { + order: 1, + value: 3, + useful: 2, + tag: { + damage: 1, + loseCard: 1, + }, + result: { + target: function (player, target, card, isLink) { + var es = target.getCards("e"); + if (!es.length) return -1.5; + var val = 0; + for (var i of es) val += get.value(i, target); + return -Math.min(1.5, val / 5); + }, + }, + }, + }, + toushiche: { + fullskin: true, + type: "equip", + subtype: "equip1", + distance: { attackFrom: -3 }, + ai: { + basic: { + equipValue: 2.5, + }, + }, + skills: ["toushiche_skill"], + }, + gongshoujianbei: { + fullskin: true, + type: "trick", + }, + jintuiziru: { + fullskin: true, + type: "trick", + }, + diqi: { + fullskin: true, + type: "equip", + subtype: "equip2", + skills: ["diqi_skill"], + destroy: "diqi_skill", + ai: { + basic: { + equipValue: 6, + }, + }, + }, + zhadan: { + audio: true, + fullskin: true, + type: "trick", + ai: { + basic: { + useful: [6, 4], + value: [6, 4], + }, + result: { player: 1 }, + }, + notarget: true, + content: function () { + var evt = event.getParent(2)._trigger; + evt.targets.length = 0; + evt.all_excluded = true; + game.log(evt.card, "的效果被炸弹抵消了"); + }, + }, + jiwangkailai: { + audio: true, + fullskin: true, + type: "trick", + enable: function (card, player) { + var hs = player.getCards("h", function (cardx) { + return cardx != card && (!card.cards || !card.cards.includes(cardx)); + }); + if (!hs.length) return false; + var use = true, + discard = true; + for (var i of hs) { + if (use && !game.checkMod(i, player, "unchanged", "cardEnabled2", player)) + use = false; + if (discard && !lib.filter.cardDiscardable(i, player, "jiwangkailai")) + discard = false; + if (!use && !discard) return false; } - } + return true; + }, + selectTarget: -1, + toself: true, + filterTarget: function (card, player, target) { + return target == player; + }, + modTarget: true, + content: function () { + "step 0"; + var hs = player.getCards("h"); + if (hs.length) { + var use = true, + discard = true; + for (var i of hs) { + if (use && !game.checkMod(i, player, "unchanged", "cardEnabled2", player)) + use = false; + if (discard && !lib.filter.cardDiscardable(i, player, "jiwangkailai")) + discard = false; + if (!use && !discard) break; + } + if (use && discard) + player + .chooseControl() + .set("prompt", "继往开来:请选择一项") + .set("choiceList", [ + "弃置所有手牌,然后摸等量的牌", + "将所有手牌当做一张普通锦囊牌使用", + ]) + .set("ai", function () { + if (_status.event.player.countCards("h") > 2) return 0; + return 1; + }); + else if (use) event._result = { index: 1 }; + else if (discard) event._result = { index: 0 }; + else event.finish(); + } else event.finish(); + "step 1"; + var cards = player.getCards("h"); + if (result.index == 0) { + player.discard(cards); + player.draw(cards.length); + event.finish(); + } else { + var list = []; + for (var i of lib.inpile) { + if ( + i != "jiwangkailai" && + get.type(i) == "trick" && + lib.filter.filterCard({ name: i, cards: cards }, player) + ) + list.push(["锦囊", "", i]); + } + if (list.length) { + player + .chooseButton(["继往开来:选择要使用的牌", [list, "vcard"]], true) + .set("ai", function (button) { + var player = _status.event.player; + return player.getUseValue({ + name: button.link[2], + cards: player.getCards("h"), + }); + }); + } else event.finish(); + } + "step 2"; + if (result.bool) + player.chooseUseTarget({ name: result.links[0][2] }, player.getCards("h"), true); + }, + ai: { + basic: { + order: 0.5, + useful: 3, + value: 5, + }, + result: { + target: function (player, target) { + if ( + target.needsToDiscard(1) || + !target.countCards("h", function (card) { + return get.value(card, player) >= 5.5; + }) + ) + return 1; + return 0; + }, + }, + tag: { + draw: 2, + }, + }, }, }, - characterOnline:{ - wei:[ - 're_caocao','re_guojia','re_simayi','re_xiahoudun','xuzhu','re_zhangliao','re_zhenji','ol_xiahouyuan','dianwei','re_xunyu','zhanghe', - 'yujin_yujin','re_caozhang','wangyi','guohuai','hanhaoshihuan','chenqun','re_caoxiu','guohuanghou','sunziliufang','xunyou','xinxianying', - 'sp_caiwenji','caoang','caochun','caohong','sp_caoren','chenlin','sp_jiaxu','litong','sp_pangde','simalang','wanglang', - 'kuailiangkuaiyue','wangji','sp_simazhao','sp_wangyuanji','yuejin','zangba','xinpi','liuye','simashi','zhuling','duji','caoanmin', + characterOnline: { + wei: [ + "re_caocao", + "re_guojia", + "re_simayi", + "re_xiahoudun", + "xuzhu", + "re_zhangliao", + "re_zhenji", + "ol_xiahouyuan", + "dianwei", + "re_xunyu", + "zhanghe", + "yujin_yujin", + "re_caozhang", + "wangyi", + "guohuai", + "hanhaoshihuan", + "chenqun", + "re_caoxiu", + "guohuanghou", + "sunziliufang", + "xunyou", + "xinxianying", + "sp_caiwenji", + "caoang", + "caochun", + "caohong", + "sp_caoren", + "chenlin", + "sp_jiaxu", + "litong", + "sp_pangde", + "simalang", + "wanglang", + "kuailiangkuaiyue", + "wangji", + "sp_simazhao", + "sp_wangyuanji", + "yuejin", + "zangba", + "xinpi", + "liuye", + "simashi", + "zhuling", + "duji", + "caoanmin", ], - shu:[ - 're_guanyu','re_huangyueying','re_liubei','re_machao','re_zhangfei','zhaoyun','re_huangzhong','re_weiyan','re_pangtong','ol_sp_zhugeliang', - 're_menghuo','re_zhurong','re_fazheng','re_masu','guanxingzhangbao','xin_liaohua','old_madai','re_jianyong','wuyi','zhangsong','zhoucang', - 'liuchen','xiahoushi','re_zhangyi','liyan','guanyinping','guansuo','mayunlu','mazhong','mizhu','sunqian','xiahouba','zhangxingcai', - 'wangping','yanyan','chendao','ganfuren','re_maliang','dengzhi','lifeng','zhangyì', + shu: [ + "re_guanyu", + "re_huangyueying", + "re_liubei", + "re_machao", + "re_zhangfei", + "zhaoyun", + "re_huangzhong", + "re_weiyan", + "re_pangtong", + "ol_sp_zhugeliang", + "re_menghuo", + "re_zhurong", + "re_fazheng", + "re_masu", + "guanxingzhangbao", + "xin_liaohua", + "old_madai", + "re_jianyong", + "wuyi", + "zhangsong", + "zhoucang", + "liuchen", + "xiahoushi", + "re_zhangyi", + "liyan", + "guanyinping", + "guansuo", + "mayunlu", + "mazhong", + "mizhu", + "sunqian", + "xiahouba", + "zhangxingcai", + "wangping", + "yanyan", + "chendao", + "ganfuren", + "re_maliang", + "dengzhi", + "lifeng", + "zhangyì", ], - wu:[ - 're_ganning','re_huanggai','re_sunquan','re_sunshangxiang','re_zhouyu','old_zhoutai','re_xiaoqiao','re_taishici','sunjian','re_zhangzhang', - 're_lingtong','re_wuguotai','xin_xusheng','re_bulianshi','re_chengpu','handang','xin_panzhangmazhong','xin_zhuran','guyong','zhuhuan','cenhun','sundeng','xuezong', - 'daxiaoqiao','heqi','kanze','sunhao','re_sunluyu','sunshao','zhugejin','zumao','dingfeng','sunliang','zhoufei', - 'weiwenzhugezhi','xf_sufei','xugong','lingcao','sunru','lvdai','panjun','yanjun','zhoufang', + wu: [ + "re_ganning", + "re_huanggai", + "re_sunquan", + "re_sunshangxiang", + "re_zhouyu", + "old_zhoutai", + "re_xiaoqiao", + "re_taishici", + "sunjian", + "re_zhangzhang", + "re_lingtong", + "re_wuguotai", + "xin_xusheng", + "re_bulianshi", + "re_chengpu", + "handang", + "xin_panzhangmazhong", + "xin_zhuran", + "guyong", + "zhuhuan", + "cenhun", + "sundeng", + "xuezong", + "daxiaoqiao", + "heqi", + "kanze", + "sunhao", + "re_sunluyu", + "sunshao", + "zhugejin", + "zumao", + "dingfeng", + "sunliang", + "zhoufei", + "weiwenzhugezhi", + "xf_sufei", + "xugong", + "lingcao", + "sunru", + "lvdai", + "panjun", + "yanjun", + "zhoufang", ], - qun:[ - 're_diaochan','re_gongsunzan','re_huatuo','re_huaxiong','re_lvbu','ol_pangde','re_yanwen','jiaxu','gaoshun','xin_liubiao','chengong', - 're_gongsunyuan','guotufengji','dongbai','fuwan','liuxie','sp_machao','tadun','yanbaihu','yuanshu','zhangbao','yl_luzhi','huangfusong','sp_ganning','huangjinleishi', - 're_panfeng','guosi','sp_liuqi','mangyachang','gaolan','lvkuanglvxiang','xunchen','sp_zhanghe','re_hansui','re_hejin','zhujun','ol_dingyuan','hanfu','wangrong', - 'dongcheng','gongsunkang','hucheer','sp_sufei','yj_xuhuang','yj_zhanghe','yj_zhangliao','liuyao','wangcan','sp_taishici','caimao','jiling', + qun: [ + "re_diaochan", + "re_gongsunzan", + "re_huatuo", + "re_huaxiong", + "re_lvbu", + "ol_pangde", + "re_yanwen", + "jiaxu", + "gaoshun", + "xin_liubiao", + "chengong", + "re_gongsunyuan", + "guotufengji", + "dongbai", + "fuwan", + "liuxie", + "sp_machao", + "tadun", + "yanbaihu", + "yuanshu", + "zhangbao", + "yl_luzhi", + "huangfusong", + "sp_ganning", + "huangjinleishi", + "re_panfeng", + "guosi", + "sp_liuqi", + "mangyachang", + "gaolan", + "lvkuanglvxiang", + "xunchen", + "sp_zhanghe", + "re_hansui", + "re_hejin", + "zhujun", + "ol_dingyuan", + "hanfu", + "wangrong", + "dongcheng", + "gongsunkang", + "hucheer", + "sp_sufei", + "yj_xuhuang", + "yj_zhanghe", + "yj_zhangliao", + "liuyao", + "wangcan", + "sp_taishici", + "caimao", + "jiling", ], - key:[ - 'sp_key_yuri','key_akane','key_akiko','key_ao','key_harukakanata','key_haruko','key_hinata','key_kengo','key_komari','key_kotori','key_kyoko','key_nagisa','key_noda','key_rei','key_rin','key_rumi','key_ryoichi','key_sasami','key_shiorimiyuki','key_shiroha','key_shizuku','key_tomoya','key_tsumugi','key_umi','key_yoshino','key_youta','key_yukine','key_nao','key_misuzu', + key: [ + "sp_key_yuri", + "key_akane", + "key_akiko", + "key_ao", + "key_harukakanata", + "key_haruko", + "key_hinata", + "key_kengo", + "key_komari", + "key_kotori", + "key_kyoko", + "key_nagisa", + "key_noda", + "key_rei", + "key_rin", + "key_rumi", + "key_ryoichi", + "key_sasami", + "key_shiorimiyuki", + "key_shiroha", + "key_shizuku", + "key_tomoya", + "key_tsumugi", + "key_umi", + "key_yoshino", + "key_youta", + "key_yukine", + "key_nao", + "key_misuzu", ], }, - online_cardPile:[ - ['spade',1,'guding'], - ['spade',1,'zhadan'], - ['spade',2,'tengjia'], - ['spade',2,'cixiong'], - ['spade',3,'jiu'], - ['spade',3,'guohe'], - ['spade',4,'sha','thunder'], - ['spade',4,'guohe'], - ['spade',5,'sha','thunder'], - ['spade',5,'qinglong'], - ['spade',6,'sha','thunder'], - ['spade',6,'jiwangkailai'], - ['spade',7,'sha','thunder'], - ['spade',7,'jintuiziru'], - ['spade',8,'sha','thunder'], - ['spade',8,'sha'], - ['spade',9,'jiu'], - ['spade',9,'sha'], - ['spade',10,'gongshoujianbei'], - ['spade',10,'sha'], - ['spade',11,'tiesuo'], - ['spade',11,'shunshou'], - ['spade',12,'tiesuo'], - ['spade',12,'zhangba'], - ['spade',13,'wuxie'], - ['spade',13,'dawanma'], + online_cardPile: [ + ["spade", 1, "guding"], + ["spade", 1, "zhadan"], + ["spade", 2, "tengjia"], + ["spade", 2, "cixiong"], + ["spade", 3, "jiu"], + ["spade", 3, "guohe"], + ["spade", 4, "sha", "thunder"], + ["spade", 4, "guohe"], + ["spade", 5, "sha", "thunder"], + ["spade", 5, "qinglong"], + ["spade", 6, "sha", "thunder"], + ["spade", 6, "jiwangkailai"], + ["spade", 7, "sha", "thunder"], + ["spade", 7, "jintuiziru"], + ["spade", 8, "sha", "thunder"], + ["spade", 8, "sha"], + ["spade", 9, "jiu"], + ["spade", 9, "sha"], + ["spade", 10, "gongshoujianbei"], + ["spade", 10, "sha"], + ["spade", 11, "tiesuo"], + ["spade", 11, "shunshou"], + ["spade", 12, "tiesuo"], + ["spade", 12, "zhangba"], + ["spade", 13, "wuxie"], + ["spade", 13, "dawanma"], - ['club',1,'baiyin'], - ['club',1,'zhuge'], - ['club',2,'tengjia'], - ['club',2,'bagua'], - ['club',3,'jiu'], - ['club',3,'sha'], - ['club',4,'jintuiziru'], - ['club',4,'sha'], - ['club',5,'sha','thunder'], - ['club',5,'dilu'], - ['club',6,'sha','thunder'], - ['club',6,'sha'], - ['club',7,'sha','thunder'], - ['club',7,'sha'], - ['club',8,'sha','thunder'], - ['club',8,'sha'], - ['club',9,'jiu'], - ['club',9,'sha'], - ['club',10,'tiesuo'], - ['club',10,'sha'], - ['club',11,'tiesuo'], - ['club',11,'sha'], - ['club',12,'tiesuo'], - ['club',12,'wuxie'], - ['club',13,'tiesuo'], - ['club',13,'jiedao'], - ['club',13,'wuxie'], + ["club", 1, "baiyin"], + ["club", 1, "zhuge"], + ["club", 2, "tengjia"], + ["club", 2, "bagua"], + ["club", 3, "jiu"], + ["club", 3, "sha"], + ["club", 4, "jintuiziru"], + ["club", 4, "sha"], + ["club", 5, "sha", "thunder"], + ["club", 5, "dilu"], + ["club", 6, "sha", "thunder"], + ["club", 6, "sha"], + ["club", 7, "sha", "thunder"], + ["club", 7, "sha"], + ["club", 8, "sha", "thunder"], + ["club", 8, "sha"], + ["club", 9, "jiu"], + ["club", 9, "sha"], + ["club", 10, "tiesuo"], + ["club", 10, "sha"], + ["club", 11, "tiesuo"], + ["club", 11, "sha"], + ["club", 12, "tiesuo"], + ["club", 12, "wuxie"], + ["club", 13, "tiesuo"], + ["club", 13, "jiedao"], + ["club", 13, "wuxie"], - ['heart',1,'wuxie'], - ['heart',1,'gongshoujianbei'], - ['heart',1,'zhadan'], - ['heart',2,'huogong'], - ['heart',2,'shan'], - ['heart',3,'huogong'], - ['heart',3,'wuzhong'], - ['heart',4,'sha','fire'], - ['heart',4,'tao'], - ['heart',5,'tao'], - ['heart',5,'chitu'], - ['heart',6,'tao'], - ['heart',6,'jiwangkailai'], - ['heart',7,'sha','fire'], - ['heart',7,'tao'], - ['heart',8,'shan'], - ['heart',8,'wuzhong'], - ['heart',9,'shan'], - ['heart',9,'tao'], - ['heart',10,'sha','fire'], - ['heart',10,'sha'], - ['heart',11,'shan'], - ['heart',11,'wuzhong'], - ['heart',12,'shan'], - ['heart',12,'guohe'], - ['heart',13,'wuxie'], - ['heart',13,'zhuahuang'], + ["heart", 1, "wuxie"], + ["heart", 1, "gongshoujianbei"], + ["heart", 1, "zhadan"], + ["heart", 2, "huogong"], + ["heart", 2, "shan"], + ["heart", 3, "huogong"], + ["heart", 3, "wuzhong"], + ["heart", 4, "sha", "fire"], + ["heart", 4, "tao"], + ["heart", 5, "tao"], + ["heart", 5, "chitu"], + ["heart", 6, "tao"], + ["heart", 6, "jiwangkailai"], + ["heart", 7, "sha", "fire"], + ["heart", 7, "tao"], + ["heart", 8, "shan"], + ["heart", 8, "wuzhong"], + ["heart", 9, "shan"], + ["heart", 9, "tao"], + ["heart", 10, "sha", "fire"], + ["heart", 10, "sha"], + ["heart", 11, "shan"], + ["heart", 11, "wuzhong"], + ["heart", 12, "shan"], + ["heart", 12, "guohe"], + ["heart", 13, "wuxie"], + ["heart", 13, "zhuahuang"], - ['diamond',1,'zhuque'], - ['diamond',1,'juedou'], - ['diamond',2,'tao'], - ['diamond',2,'shan'], - ['diamond',3,'tao'], - ['diamond',3,'shan'], - ['diamond',4,'sha','fire'], - ['diamond',4,'shunshou'], - ['diamond',5,'sha','fire'], - ['diamond',5,'guanshi'], - ['diamond',6,'shan'], - ['diamond',6,'sha'], - ['diamond',7,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'shan'], - ['diamond',8,'shan'], - ['diamond',9,'jiu'], - ['diamond',9,'shan'], - ['diamond',10,'shan'], - ['diamond',10,'sha'], - ['diamond',11,'shan'], - ['diamond',11,'shan'], - ['diamond',12,'huogong'], - ['diamond',12,'tao'], - ['diamond',13,'xiliu'], - ['diamond',13,'sha'], - ['diamond',13,'wuxie'] + ["diamond", 1, "zhuque"], + ["diamond", 1, "juedou"], + ["diamond", 2, "tao"], + ["diamond", 2, "shan"], + ["diamond", 3, "tao"], + ["diamond", 3, "shan"], + ["diamond", 4, "sha", "fire"], + ["diamond", 4, "shunshou"], + ["diamond", 5, "sha", "fire"], + ["diamond", 5, "guanshi"], + ["diamond", 6, "shan"], + ["diamond", 6, "sha"], + ["diamond", 7, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "jiu"], + ["diamond", 9, "shan"], + ["diamond", 10, "shan"], + ["diamond", 10, "sha"], + ["diamond", 11, "shan"], + ["diamond", 11, "shan"], + ["diamond", 12, "huogong"], + ["diamond", 12, "tao"], + ["diamond", 13, "xiliu"], + ["diamond", 13, "sha"], + ["diamond", 13, "wuxie"], ], - help:{ - '斗地主':'
                        游戏规则
                        • 游戏人数
                          游戏人数为3人(地主x1 + 农民x2)。
                        • 胜利条件
                          农民:地主死亡。
                          地主:所有农民死亡且自己存活。'+ - '
                        • 死亡奖惩
                          当有农民死亡时,若另一名农民存活,则其可以选择摸两张牌或回复1点体力。
                        • 地主专属技能
                          地主可以使用专属技能〖飞扬〗和〖跋扈〗。
                          〖飞扬〗判定阶段开始时,若你的判定区有牌,则你可以弃置两张手牌,然后弃置你判定区的一张牌。每回合限一次。
                          〖跋扈〗锁定技,准备阶段开始时,你摸一张牌。出牌阶段,你可以多使用一张【杀】。
                        ', - } + help: { + 斗地主: + '
                        游戏规则
                        • 游戏人数
                          游戏人数为3人(地主x1 + 农民x2)。
                        • 胜利条件
                          农民:地主死亡。
                          地主:所有农民死亡且自己存活。' + + "
                        • 死亡奖惩
                          当有农民死亡时,若另一名农民存活,则其可以选择摸两张牌或回复1点体力。
                        • 地主专属技能
                          地主可以使用专属技能〖飞扬〗和〖跋扈〗。
                          〖飞扬〗判定阶段开始时,若你的判定区有牌,则你可以弃置两张手牌,然后弃置你判定区的一张牌。每回合限一次。
                          〖跋扈〗锁定技,准备阶段开始时,你摸一张牌。出牌阶段,你可以多使用一张【杀】。
                        ", + }, }; }); diff --git a/mode/guozhan.js b/mode/guozhan.js index 7fa010ee5..b979e592c 100644 --- a/mode/guozhan.js +++ b/mode/guozhan.js @@ -1,1555 +1,2247 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'guozhan', - startBefore:function(){ - var playback=localStorage.getItem(lib.configprefix+'playback'); - for(var i in lib.characterPack.mode_guozhan){ - if(!get.config('onlyguozhan')&&!playback){ - if(lib.character[i.slice(3)]) continue; + name: "guozhan", + startBefore: function () { + var playback = localStorage.getItem(lib.configprefix + "playback"); + for (var i in lib.characterPack.mode_guozhan) { + if (!get.config("onlyguozhan") && !playback) { + if (lib.character[i.slice(3)]) continue; } - lib.character[i]=lib.characterPack.mode_guozhan[i]; - if(!lib.character[i][4]){ - lib.character[i][4]=[]; + lib.character[i] = lib.characterPack.mode_guozhan[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; } - if(!lib.translate[i]){ - lib.translate[i]=lib.translate[i.slice(3)]; + if (!lib.translate[i]) { + lib.translate[i] = lib.translate[i.slice(3)]; } } - for(var i in lib.character){ - if(lib.character[i][1]=='shen'){ - if(lib.character[i][4]){ - var group=lib.character[i][4].find(group=>lib.group.includes(group)||group=='key'||group.startsWith('gzgroup:')); - if(group){ - if(group.startsWith('gzgroup:')) lib.character[i][1]=group.slice(8); - else lib.character[i][1]=group; - } - else lib.character[i][1]='qun'; - } - else lib.character[i][1]='qun'; + for (var i in lib.character) { + if (lib.character[i][1] == "shen") { + if (lib.character[i][4]) { + var group = lib.character[i][4].find( + (group) => + lib.group.includes(group) || group == "key" || group.startsWith("gzgroup:") + ); + if (group) { + if (group.startsWith("gzgroup:")) lib.character[i][1] = group.slice(8); + else lib.character[i][1] = group; + } else lib.character[i][1] = "qun"; + } else lib.character[i][1] = "qun"; } } }, - onreinit:function(){ - var pack=lib.characterPack.mode_guozhan; - for(var i in pack){ - lib.character[i]=pack[i]; - if(!lib.character[i][4]){ - lib.character[i][4]=[]; + onreinit: function () { + var pack = lib.characterPack.mode_guozhan; + for (var i in pack) { + lib.character[i] = pack[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; } - if(!lib.translate[i]){ - lib.translate[i]=lib.translate[i.slice(3)]; + if (!lib.translate[i]) { + lib.translate[i] = lib.translate[i.slice(3)]; } } - for(var i in lib.character){ - if(lib.character[i][1]=='shen'){ - if(lib.character[i][4]){ - var group=lib.character[i][4].find(group=>lib.group.includes(group)||group=='key'||group.startsWith('gzgroup:')); - if(group){ - if(group.startsWith('gzgroup:')) lib.character[i][1]=group.slice(8); - else lib.character[i][1]=group; - } - else lib.character[i][1]='qun'; - } - else lib.character[i][1]='qun'; + for (var i in lib.character) { + if (lib.character[i][1] == "shen") { + if (lib.character[i][4]) { + var group = lib.character[i][4].find( + (group) => + lib.group.includes(group) || group == "key" || group.startsWith("gzgroup:") + ); + if (group) { + if (group.startsWith("gzgroup:")) lib.character[i][1] = group.slice(8); + else lib.character[i][1] = group; + } else lib.character[i][1] = "qun"; + } else lib.character[i][1] = "qun"; } } }, - start:function(){ - "step 0" - var playback=localStorage.getItem(lib.configprefix+'playback'); - if(playback){ + start: function () { + "step 0"; + var playback = localStorage.getItem(lib.configprefix + "playback"); + if (playback) { ui.create.me(); - ui.arena.style.display='none'; - ui.system.style.display='none'; - _status.playback=playback; - localStorage.removeItem(lib.configprefix+'playback'); - var store=lib.db.transaction(['video'],'readwrite').objectStore('video'); - store.get(parseInt(playback)).onsuccess=function(e){ - if(e.target.result){ + ui.arena.style.display = "none"; + ui.system.style.display = "none"; + _status.playback = playback; + localStorage.removeItem(lib.configprefix + "playback"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + store.get(parseInt(playback)).onsuccess = function (e) { + if (e.target.result) { game.playVideoContent(e.target.result.video); - } - else{ - alert('播放失败:找不到录像'); + } else { + alert("播放失败:找不到录像"); game.reload(); } - } + }; event.finish(); - } - else if(_status.connectMode){ + } else if (_status.connectMode) { game.waitForPlayer(); - } - else{ - _status.mode=get.config('guozhan_mode'); - if(!['normal','yingbian','old','free'].includes(_status.mode)) _status.mode='normal'; + } else { + _status.mode = get.config("guozhan_mode"); + if (!["normal", "yingbian", "old", "free"].includes(_status.mode)) _status.mode = "normal"; //决定牌堆 - switch(_status.mode){ - case 'old':lib.card.list=lib.guozhanPile_old.slice(0);break; - case 'yingbian': - lib.card.list=lib.guozhanPile_yingbian.slice(0); + switch (_status.mode) { + case "old": + lib.card.list = lib.guozhanPile_old.slice(0); + break; + case "yingbian": + lib.card.list = lib.guozhanPile_yingbian.slice(0); delete lib.translate.shuiyanqijunx_info_guozhan; - const pack=lib.yingbian_guozhan; - for(const i in pack){ - if(!pack[i][4]) pack[i][4]=[]; - lib.character[i]=pack[i]; - lib.characterPack.mode_guozhan[i]=pack[i]; - if(!lib.translate[i]) lib.translate[i]=lib.translate[i.slice(3)]; + const pack = lib.yingbian_guozhan; + for (const i in pack) { + if (!pack[i][4]) pack[i][4] = []; + lib.character[i] = pack[i]; + lib.characterPack.mode_guozhan[i] = pack[i]; + if (!lib.translate[i]) lib.translate[i] = lib.translate[i.slice(3)]; } break; - case 'normal':lib.card.list=lib.guozhanPile.slice(0);break; + case "normal": + lib.card.list = lib.guozhanPile.slice(0); + break; } - if(_status.mode!='free') game.fixedPile=true; - else{ + if (_status.mode != "free") game.fixedPile = true; + else { delete lib.translate.shuiyanqijunx_info_guozhan; } game.prepareArena(); // game.delay(); game.showChangeLog(); } - if(!_status.connectMode){ - _status.mode=get.config('guozhan_mode'); - if(_status.brawl&&_status.brawl.submode){ - _status.mode=_status.brawl.submode; + if (!_status.connectMode) { + _status.mode = get.config("guozhan_mode"); + if (_status.brawl && _status.brawl.submode) { + _status.mode = _status.brawl.submode; } - if(get.config('separatism')) _status.separatism=true; + if (get.config("separatism")) _status.separatism = true; } - "step 1" - if(_status.connectMode){ - _status.mode=lib.configOL.guozhan_mode; - if(!['normal','yingbian','old'].includes(_status.mode)) _status.mode='normal'; - if(lib.configOL.separatism) _status.separatism=true; + "step 1"; + if (_status.connectMode) { + _status.mode = lib.configOL.guozhan_mode; + if (!["normal", "yingbian", "old"].includes(_status.mode)) _status.mode = "normal"; + if (lib.configOL.separatism) _status.separatism = true; //决定牌堆 - switch(_status.mode){ - case 'old':lib.card.list=lib.guozhanPile_old.slice(0);break; - case 'yingbian': - lib.card.list=lib.guozhanPile_yingbian.slice(0); + switch (_status.mode) { + case "old": + lib.card.list = lib.guozhanPile_old.slice(0); + break; + case "yingbian": + lib.card.list = lib.guozhanPile_yingbian.slice(0); delete lib.translate.shuiyanqijunx_info_guozhan; break; - default:lib.card.list=lib.guozhanPile.slice(0);break; + default: + lib.card.list = lib.guozhanPile.slice(0); + break; } - game.fixedPile=true; - game.broadcastAll((mode,separatism)=>{ - _status.mode=mode; - if(separatism) _status.separatism=true; - var pack=lib.characterPack.mode_guozhan; - if(mode=='yingbian'){ - delete lib.translate.shuiyanqijunx_info_guozhan; - const pack2=lib.yingbian_guozhan; - for(const i in pack2){ - if(!pack2[i][4]) pack2[i][4]=[]; - pack[i]=pack2[i]; - } - } - for(var i=0;ilib.group.includes(group)||group=='key'||group.startsWith('gzgroup:')); - if(group){ - if(group.startsWith('gzgroup:')) lib.character[i][1]=group.slice(8); - else lib.character[i][1]=group; - } - else lib.character[i][1]='qun'; + game.fixedPile = true; + game.broadcastAll( + (mode, separatism) => { + _status.mode = mode; + if (separatism) _status.separatism = true; + var pack = lib.characterPack.mode_guozhan; + if (mode == "yingbian") { + delete lib.translate.shuiyanqijunx_info_guozhan; + const pack2 = lib.yingbian_guozhan; + for (const i in pack2) { + if (!pack2[i][4]) pack2[i][4] = []; + pack[i] = pack2[i]; } - else lib.character[i][1]='qun'; } - } - //lib.characterReplace={}; - },_status.mode,_status.separatism); + for (var i = 0; i < game.players.length; i++) { + game.players[i].node.name.hide(); + game.players[i].node.name2.hide(); + } + for (var i in pack) { + lib.character[i] = pack[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; + } + if (!lib.translate[i]) { + lib.translate[i] = lib.translate[i.slice(3)]; + } + } + for (var i in lib.character) { + if (lib.character[i][1] == "shen") { + if (lib.character[i][4]) { + var group = lib.character[i][4].find( + (group) => + lib.group.includes(group) || + group == "key" || + group.startsWith("gzgroup:") + ); + if (group) { + if (group.startsWith("gzgroup:")) + lib.character[i][1] = group.slice(8); + else lib.character[i][1] = group; + } else lib.character[i][1] = "qun"; + } else lib.character[i][1] = "qun"; + } + } + //lib.characterReplace={}; + }, + _status.mode, + _status.separatism + ); game.randomMapOL(); - } - else{ + } else { //lib.characterReplace={}; - for(var i=0;i{ - if(_status.connectMode) return true; - return get.type(card)=='basic'&&lib.filter.cardDiscardable(card,player); - }); + fakexiaoguo: { + audio: "xiaoguo", + trigger: { global: "phaseZhunbeiBegin" }, + filter(event, player) { + return ( + event.player != player && + player.countCards("h", (card) => { + if (_status.connectMode) return true; + return get.type(card) == "basic" && lib.filter.cardDiscardable(card, player); + }) + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseToDiscard(get.prompt2('fakexiaoguo',trigger.player),(card,player)=>{ - return get.type(card)=='basic'; - },[1,Infinity]).set('complexSelect',true).set('ai',card=>{ - const player=get.event('player'),target=get.event().getTrigger().player; - const effect=get.damageEffect(target,player,player); - const cards=target.getCards('e',card=>get.attitude(player,target)*get.value(card,target)<0); - if(effect<=0&&!cards.length) return 0; - if(ui.selected.cards.length>cards.length-(effect<=0?1:0)) return 0; - return 1/(get.value(card)||0.5); - }).set('logSkill',['fakexiaoguo',trigger.player]).setHiddenSkill('fakexiaoguo').forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseToDiscard( + get.prompt2("fakexiaoguo", trigger.player), + (card, player) => { + return get.type(card) == "basic"; + }, + [1, Infinity] + ) + .set("complexSelect", true) + .set("ai", (card) => { + const player = get.event("player"), + target = get.event().getTrigger().player; + const effect = get.damageEffect(target, player, player); + const cards = target.getCards( + "e", + (card) => get.attitude(player, target) * get.value(card, target) < 0 + ); + if (effect <= 0 && !cards.length) return 0; + if (ui.selected.cards.length > cards.length - (effect <= 0 ? 1 : 0)) return 0; + return 1 / (get.value(card) || 0.5); + }) + .set("logSkill", ["fakexiaoguo", trigger.player]) + .setHiddenSkill("fakexiaoguo") + .forResult(); }, - popup:false, - preHidden:true, - async content(event,trigger,player){ - const num=trigger.player.countCards('e'),num2=event.cards.length; - await player.discardPlayerCard(trigger.player,'e',num2,true); - if(num2>num) await trigger.player.damage(); + popup: false, + preHidden: true, + async content(event, trigger, player) { + const num = trigger.player.countCards("e"), + num2 = event.cards.length; + await player.discardPlayerCard(trigger.player, "e", num2, true); + if (num2 > num) await trigger.player.damage(); }, }, - fakeduanbing:{ - audio:'duanbing', - inherit:'reduanbing', - preHidden:['fakeduanbing_sha'], - group:['fakeduanbing_sha'], - get content(){ - let content=get.info('reduanbing').content; - content=content.toString().replaceAll('reduanbing','fakeduanbing'); - content=new Function('return '+content)(); + fakeduanbing: { + audio: "duanbing", + inherit: "reduanbing", + preHidden: ["fakeduanbing_sha"], + group: ["fakeduanbing_sha"], + get content() { + let content = get.info("reduanbing").content; + content = content.toString().replaceAll("reduanbing", "fakeduanbing"); + content = new Function("return " + content)(); delete this.content; - this.content=content; + this.content = content; return content; }, - subSkill:{ - sha:{ - audio:'duanbing', - trigger:{player:'useCardToPlayered'}, - filter(event,player){ - return event.card.name=='sha'&&!event.getParent().directHit.includes(event.target)&&event.targets.length==1; + subSkill: { + sha: { + audio: "duanbing", + trigger: { player: "useCardToPlayered" }, + filter(event, player) { + return ( + event.card.name == "sha" && + !event.getParent().directHit.includes(event.target) && + event.targets.length == 1 + ); }, - forced:true, - logTarget:'target', - content(){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number') map[id].shanRequired++; - else map[id].shanRequired=2; + forced: true, + logTarget: "target", + content() { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") map[id].shanRequired++; + else map[id].shanRequired = 2; }, - ai:{ - directHit_ai:true, - skillTagFilter(player,tag,arg){ - if(!arg||!arg.card||!arg.target||arg.card.name!='sha'||arg.target.countCards('h','shan')>1||get.distance(player,arg.target)>1) return false; + ai: { + directHit_ai: true, + skillTagFilter(player, tag, arg) { + if ( + !arg || + !arg.card || + !arg.target || + arg.card.name != "sha" || + arg.target.countCards("h", "shan") > 1 || + get.distance(player, arg.target) > 1 + ) + return false; }, }, }, }, }, - fakeduoshi:{ - audio:'duoshi', - global:'fakeduoshi_global', - subSkill:{ - global:{ - audio:'duoshi', - forceaudio:true, - enable:'chooseToUse', - filter(event,player){ - const info=get.info('fakeduoshi').subSkill.global; - return game.hasPlayer(target=>{ - return info.filterTarget(null,player,target); - })&&player.countCards('hs',card=>{ - return info.filterCard(card,player); - }); + fakeduoshi: { + audio: "duoshi", + global: "fakeduoshi_global", + subSkill: { + global: { + audio: "duoshi", + forceaudio: true, + enable: "chooseToUse", + filter(event, player) { + const info = get.info("fakeduoshi").subSkill.global; + return ( + game.hasPlayer((target) => { + return info.filterTarget(null, player, target); + }) && + player.countCards("hs", (card) => { + return info.filterCard(card, player); + }) + ); }, - filterTarget(card,player,target){ - return target.hasSkill('fakeduoshi')&&!target.isTempBanned('fakeduoshi')&&target.isFriendOf(player); + filterTarget(card, player, target) { + return ( + target.hasSkill("fakeduoshi") && + !target.isTempBanned("fakeduoshi") && + target.isFriendOf(player) + ); }, - filterCard(card,player){ - if(!game.checkMod(card,player,'unchanged','cardEnabled2',player)) return false; - return get.color(card)=='red'&&player.hasUseTarget(get.autoViewAs({name:'yiyi'},[card])); + filterCard(card, player) { + if (!game.checkMod(card, player, "unchanged", "cardEnabled2", player)) + return false; + return ( + get.color(card) == "red" && + player.hasUseTarget(get.autoViewAs({ name: "yiyi" }, [card])) + ); }, - discard:false, - lose:false, - delay:false, - line:false, - prompt:'选择一张红色手牌当作【以逸待劳】使用,并选择一名拥有【度势】的角色', - async content(event,trigger,player){ - const target=event.target; - target.tempBanSkill('fakeduoshi','roundStart',false); - let {result}=await player.chooseUseTarget(true,{name:'yiyi'},event.cards); - if(result.bool&&result.targets.length&&target.isNotMajor()){ - const num=result.targets.length,str='将'+get.cnNumber(num)+'张手牌当作不可被响应的【火烧连营】使用?'; - const {result:{bool,targets}}=await player.chooseTarget('是否令一名友方角色'+str,(card,player,target)=>{ - return target.isFriendOf(player)&&target.countCards('h',card=>{ - if(!target.hasUseTarget(get.autoViewAs({name:'huoshaolianying'},[card]))) return false; - return target!=player||game.checkMod(card,player,'unchanged','cardEnabled2',player); - })>=get.event('num'); - }).set('num',num).set('ai',target=>{ - return target.getUseValue(new lib.element.VCard({name:'huoshaolianying'})); - }); - if(bool){ - player.line(targets[0]); - game.broadcastAll(num=>{ - lib.skill.fakeduoshi_backup.selectCard=num; - lib.skill.fakeduoshi.subSkill.backup.selectCard=num; - },num); - await targets[0].chooseToUse() - .set('openskilldialog','度势:是否'+str) - .set('norestore',true) - .set('_backupevent','fakeduoshi_backup') - .set('custom',{ - add:{}, - replace:{window:function(){}} + discard: false, + lose: false, + delay: false, + line: false, + prompt: "选择一张红色手牌当作【以逸待劳】使用,并选择一名拥有【度势】的角色", + async content(event, trigger, player) { + const target = event.target; + target.tempBanSkill("fakeduoshi", "roundStart", false); + let { result } = await player.chooseUseTarget( + true, + { name: "yiyi" }, + event.cards + ); + if (result.bool && result.targets.length && target.isNotMajor()) { + const num = result.targets.length, + str = + "将" + get.cnNumber(num) + "张手牌当作不可被响应的【火烧连营】使用?"; + const { + result: { bool, targets }, + } = await player + .chooseTarget("是否令一名友方角色" + str, (card, player, target) => { + return ( + target.isFriendOf(player) && + target.countCards("h", (card) => { + if ( + !target.hasUseTarget( + get.autoViewAs({ name: "huoshaolianying" }, [card]) + ) + ) + return false; + return ( + target != player || + game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ) + ); + }) >= get.event("num") + ); }) - .set('addCount',false) - .set('oncard',()=>_status.event.directHit.addArray(game.players)) - .backup('fakeduoshi_backup'); + .set("num", num) + .set("ai", (target) => { + return target.getUseValue( + new lib.element.VCard({ name: "huoshaolianying" }) + ); + }); + if (bool) { + player.line(targets[0]); + game.broadcastAll((num) => { + lib.skill.fakeduoshi_backup.selectCard = num; + lib.skill.fakeduoshi.subSkill.backup.selectCard = num; + }, num); + await targets[0] + .chooseToUse() + .set("openskilldialog", "度势:是否" + str) + .set("norestore", true) + .set("_backupevent", "fakeduoshi_backup") + .set("custom", { + add: {}, + replace: { window: function () {} }, + }) + .set("addCount", false) + .set("oncard", () => _status.event.directHit.addArray(game.players)) + .backup("fakeduoshi_backup"); } } }, - ai:{ - order(item,player){ - const card=new lib.element.VCard({name:'huoshaolianying'}); - return get.order(card,player)+0.1; + ai: { + order(item, player) { + const card = new lib.element.VCard({ name: "huoshaolianying" }); + return get.order(card, player) + 0.1; }, - result:{target:1}, + result: { target: 1 }, }, }, - backup:{ - filterCard:true, - position:'hs', - check(card){ - return 7-get.value(card); + backup: { + filterCard: true, + position: "hs", + check(card) { + return 7 - get.value(card); }, - log:false, - viewAs:{name:'huoshaolianying'}, - precontent(){ + log: false, + viewAs: { name: "huoshaolianying" }, + precontent() { delete event.result.skill; }, }, }, }, - fakehanzhan:{ - audio:'hanzhan', - trigger:{ - player:['chooseToCompareAfter','compareMultipleAfter'], - target:['chooseToCompareAfter','compareMultipleAfter'], + fakehanzhan: { + audio: "hanzhan", + trigger: { + player: ["chooseToCompareAfter", "compareMultipleAfter"], + target: ["chooseToCompareAfter", "compareMultipleAfter"], }, - filter(event,player){ - if(event.preserve) return false; - const list=[event.player,event.target]; - const targets=list.slice().filter(i=>(event.num1-event.num2)*get.sgn(0.5-list.indexOf(i))<=0); - return targets.some(i=>i.countGainableCards(list[1-list.indexOf(i)],'e')); + filter(event, player) { + if (event.preserve) return false; + const list = [event.player, event.target]; + const targets = list + .slice() + .filter((i) => (event.num1 - event.num2) * get.sgn(0.5 - list.indexOf(i)) <= 0); + return targets.some((i) => i.countGainableCards(list[1 - list.indexOf(i)], "e")); }, - async cost(event,trigger,player){ - let users=[]; - const list=[event.player,event.target]; - let targets=list.slice().filter(i=>(event.num1-event.num2)*get.sgn(0.5-list.indexOf(i))<=0); - targets=targets.filter(i=>i.countGainableCards(list[1-list.indexOf(i)],'e')).sortBySeat(player); - for(const i of targets){ - const aim=list[1-list.indexOf(i)]; - const {result:{bool}}=await i.chooseBool(get.prompt('fakehanzhan'),'获得'+get.translation(aim)+'装备区的一张牌').set('choice',target.hasCard(card=>{ - return get.value(card,aim)*get.attitude(i,aim)<0; - },'e')); - if(bool) users.push(i); + async cost(event, trigger, player) { + let users = []; + const list = [event.player, event.target]; + let targets = list + .slice() + .filter((i) => (event.num1 - event.num2) * get.sgn(0.5 - list.indexOf(i)) <= 0); + targets = targets + .filter((i) => i.countGainableCards(list[1 - list.indexOf(i)], "e")) + .sortBySeat(player); + for (const i of targets) { + const aim = list[1 - list.indexOf(i)]; + const { + result: { bool }, + } = await i + .chooseBool( + get.prompt("fakehanzhan"), + "获得" + get.translation(aim) + "装备区的一张牌" + ) + .set( + "choice", + target.hasCard((card) => { + return get.value(card, aim) * get.attitude(i, aim) < 0; + }, "e") + ); + if (bool) users.push(i); } - event.result={bool:Boolean(users.length),targets:users}; + event.result = { bool: Boolean(users.length), targets: users }; }, - async content(event,trigger,player){ - const list=[trigger.player,trigger.target]; - let targets=list.slice().filter(i=>(trigger.num1-trigger.num2)*get.sgn(0.5-list.indexOf(i))<=0); - targets=targets.filter(i=>i.countGainableCards(list[1-list.indexOf(i)],'e')&&event.targets.includes(i)).sortBySeat(player); - for(const i of targets){ - const aim=list[1-list.indexOf(i)]; - await i.gainPlayerCard(aim,'e',true); + async content(event, trigger, player) { + const list = [trigger.player, trigger.target]; + let targets = list + .slice() + .filter((i) => (trigger.num1 - trigger.num2) * get.sgn(0.5 - list.indexOf(i)) <= 0); + targets = targets + .filter( + (i) => + i.countGainableCards(list[1 - list.indexOf(i)], "e") && + event.targets.includes(i) + ) + .sortBySeat(player); + for (const i of targets) { + const aim = list[1 - list.indexOf(i)]; + await i.gainPlayerCard(aim, "e", true); } }, }, - fakeshuangxiong:{ - audio:'shuangxiong', - subfrequent:['tiandu'], - group:['fakeshuangxiong_effect','fakeshuangxiong_tiandu'], - subSkill:{ - effect:{ - audio:'shuangxiong1', - inherit:'shuangxiong1', - content(){ - player.judge().set('callback',get.info('fakeshuangxiong').subSkill.effect.callback); + fakeshuangxiong: { + audio: "shuangxiong", + subfrequent: ["tiandu"], + group: ["fakeshuangxiong_effect", "fakeshuangxiong_tiandu"], + subSkill: { + effect: { + audio: "shuangxiong1", + inherit: "shuangxiong1", + content() { + player + .judge() + .set("callback", get.info("fakeshuangxiong").subSkill.effect.callback); trigger.changeToZero(); }, - callback(){ - player.addTempSkill('shuangxiong2'); - player.markAuto('shuangxiong2',[event.judgeResult.color]); + callback() { + player.addTempSkill("shuangxiong2"); + player.markAuto("shuangxiong2", [event.judgeResult.color]); }, }, - tiandu:{ - audio:'shuangxiong', - inherit:'tiandu', - filter(event,player){ - return _status.currentPhase==player&&get.info('tiandu').filter(event,player); + tiandu: { + audio: "shuangxiong", + inherit: "tiandu", + filter(event, player) { + return _status.currentPhase == player && get.info("tiandu").filter(event, player); }, }, }, }, - fakeyicheng:{ - audio:'yicheng', - inherit:'yicheng', - async content(event,trigger,player){ - const target=trigger.target; + fakeyicheng: { + audio: "yicheng", + inherit: "yicheng", + async content(event, trigger, player) { + const target = trigger.target; await target.draw(); - await target.chooseToUse(function(card){ - if(get.type(card)!='equip') return false; - return lib.filter.cardEnabled(card,_status.event.player,_status.event); - },'疑城:是否使用装备牌?'); - if(!target.storage.fakeyicheng){ - target.when({global:'phaseEnd'}).then(()=>{ - player.chooseToDiscard('he',player.countMark('fakeyicheng'),true); + await target.chooseToUse(function (card) { + if (get.type(card) != "equip") return false; + return lib.filter.cardEnabled(card, _status.event.player, _status.event); + }, "疑城:是否使用装备牌?"); + if (!target.storage.fakeyicheng) { + target.when({ global: "phaseEnd" }).then(() => { + player.chooseToDiscard("he", player.countMark("fakeyicheng"), true); delete player.storage.fakeyicheng; }); } - target.addMark('fakeyicheng',1,false); + target.addMark("fakeyicheng", 1, false); }, }, - fakefenming:{ - audio:'fenming', - enable:'phaseUse', - filter(event,player){ + fakefenming: { + audio: "fenming", + enable: "phaseUse", + filter(event, player) { return player.isLinked(); }, - filterTarget(card,player,target){ + filterTarget(card, player, target) { return target.isLinked(); }, - selectTarget:-1, - usable:1, - multiline:true, - multitarget:true, - async content(event,trigger,player){ - for(const target of event.targets){ - if(player==target) await player.chooseToDiscard(true,'he'); - else await player.discardPlayerCard(true,'he',target); + selectTarget: -1, + usable: 1, + multiline: true, + multitarget: true, + async content(event, trigger, player) { + for (const target of event.targets) { + if (player == target) await player.chooseToDiscard(true, "he"); + else await player.discardPlayerCard(true, "he", target); } }, - ai:{ - order(item,player){ - return get.order({name:'sha'},player)+0.1; + ai: { + order(item, player) { + return get.order({ name: "sha" }, player) + 0.1; }, - result:{ - target(player,target){ - return get.sgn(get.attitude(player,target))*get.effect(target,{name:'guohe_copy2'},player,player); + result: { + target(player, target) { + return ( + get.sgn(get.attitude(player, target)) * + get.effect(target, { name: "guohe_copy2" }, player, player) + ); }, }, }, }, - fakebaoling:{ - audio:'baoling', - inherit:'baoling', - init(player){ - player.checkMainSkill('fakebaoling'); + fakebaoling: { + audio: "baoling", + inherit: "baoling", + init(player) { + player.checkMainSkill("fakebaoling"); }, - content(){ - 'step 0' + content() { + "step 0"; player.removeCharacter(1); - 'step 1' + "step 1"; player.gainMaxHp(3); player.recover(3); - 'step 2' - player.addSkills('fakebenghuai'); + "step 2"; + player.addSkills("fakebenghuai"); }, - derivation:'fakebenghuai', + derivation: "fakebenghuai", }, - fakebenghuai:{ - audio:'benghuai', - inherit:'benghuai', - async content(event,trigger,player){ - const {result:{control}}=await player.chooseControl('体力','上限','背水!').set('prompt','崩坏:请选择一项').set('choiceList',[ - '失去1点体力','减1点体力上限','背水!依次执行前两项,然后执行一个额外的摸牌阶段', - ]).set('ai',()=>{ - const player=get.event('player'); - if(player.maxHp>1&&(player.getHp()==2||!player.countCards('h'))) return '背水!'; - return player.isDamaged()?'上限':'体力'; - }); + fakebenghuai: { + audio: "benghuai", + inherit: "benghuai", + async content(event, trigger, player) { + const { + result: { control }, + } = await player + .chooseControl("体力", "上限", "背水!") + .set("prompt", "崩坏:请选择一项") + .set("choiceList", [ + "失去1点体力", + "减1点体力上限", + "背水!依次执行前两项,然后执行一个额外的摸牌阶段", + ]) + .set("ai", () => { + const player = get.event("player"); + if (player.maxHp > 1 && (player.getHp() == 2 || !player.countCards("h"))) + return "背水!"; + return player.isDamaged() ? "上限" : "体力"; + }); player.popup(control); - game.log(player,'选择了','#g'+control); - if(control!='上限') await player.loseHp(); - if(control!='体力') await player.loseMaxHp(); - if(control=='背水!'){ - const next=player.phaseDraw(); + game.log(player, "选择了", "#g" + control); + if (control != "上限") await player.loseHp(); + if (control != "体力") await player.loseMaxHp(); + if (control == "背水!") { + const next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); } }, }, - fakediaodu:{ - audio:'diaodu', - inherit:'xindiaodu', - group:'fakediaodu_use', - get content(){ - let content=get.info('xindiaodu').content; - content=content.toString().replaceAll('xindiaodu','fakediaodu'); - content=new Function('return '+content)(); + fakediaodu: { + audio: "diaodu", + inherit: "xindiaodu", + group: "fakediaodu_use", + get content() { + let content = get.info("xindiaodu").content; + content = content.toString().replaceAll("xindiaodu", "fakediaodu"); + content = new Function("return " + content)(); delete this.content; - this.content=content; + this.content = content; return content; }, - subSkill:{ - use:{ - trigger:{global:'useCard'}, - filter(event,player){ - if(!lib.skill.xindiaodu.isFriendOf(player,event.player)||!(event.targets||[]).includes(player)) return false; - return (player==event.player||player.hasSkill('fakediaodu'))&&!event.player.getStorage('fakediaodu_temp').includes(get.type2(event.card)); + subSkill: { + use: { + trigger: { global: "useCard" }, + filter(event, player) { + if ( + !lib.skill.xindiaodu.isFriendOf(player, event.player) || + !(event.targets || []).includes(player) + ) + return false; + return ( + (player == event.player || player.hasSkill("fakediaodu")) && + !event.player.getStorage("fakediaodu_temp").includes(get.type2(event.card)) + ); }, - direct:true, - async content(event,trigger,player){ - const target=trigger.target,next=await target.chooseBool(get.prompt('fakediaodu'),'摸一张牌?'); - if(player.hasSkill('fakediaodu')) next.set('frequentSkill','fakediaodu'); - if(player==trigger.player) next.setHiddenSkill('fakediaodu'); - const {result:{bool}}=next; - if(bool){ - player.logSkill('fakediaodu',target); - target.draw('nodelay'); - target.addTempSkill('fakediaodu_temp'); - target.markAuto('fakediaodu_temp',[get.type2(trigger.card)]); + direct: true, + async content(event, trigger, player) { + const target = trigger.target, + next = await target.chooseBool(get.prompt("fakediaodu"), "摸一张牌?"); + if (player.hasSkill("fakediaodu")) next.set("frequentSkill", "fakediaodu"); + if (player == trigger.player) next.setHiddenSkill("fakediaodu"); + const { + result: { bool }, + } = next; + if (bool) { + player.logSkill("fakediaodu", target); + target.draw("nodelay"); + target.addTempSkill("fakediaodu_temp"); + target.markAuto("fakediaodu_temp", [get.type2(trigger.card)]); } }, }, - temp:{ - charlotte:true, - onremove:true, + temp: { + charlotte: true, + onremove: true, }, }, }, - fakeyigui:{ - audio:'yigui', - hiddenCard(player,name){ - if(['shan','wuxie'].includes(name)||!['basic','trick'].includes(get.type(name))) return false; - return lib.inpile.includes(name)&&player.getStorage('fakeyigui').length&&!player.getStorage('fakeyigui2').includes(get.type2(name)); + fakeyigui: { + audio: "yigui", + hiddenCard(player, name) { + if (["shan", "wuxie"].includes(name) || !["basic", "trick"].includes(get.type(name))) + return false; + return ( + lib.inpile.includes(name) && + player.getStorage("fakeyigui").length && + !player.getStorage("fakeyigui2").includes(get.type2(name)) + ); }, - enable:'chooseToUse', - filter(event,player){ - if(event.type=='wuxie'||event.type=='respondShan') return false; - const storage=player.getStorage('fakeyigui'),storage2=player.getStorage('fakeyigui2'); - if(!storage.length||storage2.length>1) return false; - if(event.type=='dying'){ - if(storage2.includes('basic')) return false; - if(!event.filterCard({name:'tao'},player,event)&&!event.filterCard({name:'jiu'},player,event)) return false; - const target=event.dying; - return target.identity=='unknown'||target.identity=='ye'||storage.some(i=>{ - var group=get.character(i,1); - if(group=='ye'||target.identity==group) return true; - var double=get.is.double(i,true); - if(double&&double.includes(target.identity)) return true; - }); + enable: "chooseToUse", + filter(event, player) { + if (event.type == "wuxie" || event.type == "respondShan") return false; + const storage = player.getStorage("fakeyigui"), + storage2 = player.getStorage("fakeyigui2"); + if (!storage.length || storage2.length > 1) return false; + if (event.type == "dying") { + if (storage2.includes("basic")) return false; + if ( + !event.filterCard({ name: "tao" }, player, event) && + !event.filterCard({ name: "jiu" }, player, event) + ) + return false; + const target = event.dying; + return ( + target.identity == "unknown" || + target.identity == "ye" || + storage.some((i) => { + var group = get.character(i, 1); + if (group == "ye" || target.identity == group) return true; + var double = get.is.double(i, true); + if (double && double.includes(target.identity)) return true; + }) + ); } - return get.inpileVCardList(info=>{ - const name=info[2]; - if(storage2.includes(get.type(name))) return false; - return get.type(name)=='basic'||get.type(name)=='trick'; - }).some(cardx=>{ - const card={name:cardx[2],nature:cardx[3]},info=get.info(card); - return storage.some(character=>{ - if(!lib.filter.filterCard(card,player,event)) return false; - if(event.filterCard&&!event.filterCard(card,player,event)) return false; - const group=get.character(character,1),double=get.is.double(character,true); - if(info.changeTarget){ - const list=game.filterPlayer(current=>player.canUse(card,current)); - for(let i=0;i { + const name = info[2]; + if (storage2.includes(get.type(name))) return false; + return get.type(name) == "basic" || get.type(name) == "trick"; + }) + .some((cardx) => { + const card = { name: cardx[2], nature: cardx[3] }, + info = get.info(card); + return storage.some((character) => { + if (!lib.filter.filterCard(card, player, event)) return false; + if (event.filterCard && !event.filterCard(card, player, event)) return false; + const group = get.character(character, 1), + double = get.is.double(character, true); + if (info.changeTarget) { + const list = game.filterPlayer((current) => player.canUse(card, current)); + for (let i = 0; i < list.length; i++) { + let giveup = false, + targets = [list[i]]; + info.changeTarget(player, targets); + for (let j = 0; j < targets.length; j++) { + if ( + group != "ye" && + targets[j].identity != "unknown" && + targets[j].identity != "ye" && + targets[j].identity != group && + (!double || !double.includes(targets[j].identity)) + ) { + giveup = true; + break; + } } + if (giveup) continue; + if (!giveup) return true; } - if(giveup) continue; - if(!giveup) return true; + return false; } - return false; - } - return game.hasPlayer(current=>{ - return event.filterTarget(card,player,current)&&(group=='ye'||current.identity=='unknown'||current.identity=='ye'||current.identity==group||(double&&double.includes(current.identity))); + return game.hasPlayer((current) => { + return ( + event.filterTarget(card, player, current) && + (group == "ye" || + current.identity == "unknown" || + current.identity == "ye" || + current.identity == group || + (double && double.includes(current.identity))) + ); + }); }); }); - }); }, - chooseButton:{ - select:2, - dialog(event,player){ - var dialog=ui.create.dialog('役鬼','hidden'); - dialog.add([player.getStorage('fakeyigui'),'character']); - const list=get.inpileVCardList(info=>{ - const name=info[2]; - if(player.getStorage('fakeyigui2').includes(get.type(name))) return false; - return get.type(name)=='basic'||get.type(name)=='trick'; + chooseButton: { + select: 2, + dialog(event, player) { + var dialog = ui.create.dialog("役鬼", "hidden"); + dialog.add([player.getStorage("fakeyigui"), "character"]); + const list = get.inpileVCardList((info) => { + const name = info[2]; + if (player.getStorage("fakeyigui2").includes(get.type(name))) return false; + return get.type(name) == "basic" || get.type(name) == "trick"; }); - dialog.add([list,'vcard']); + dialog.add([list, "vcard"]); return dialog; }, - filter(button,player){ - var evt=_status.event.getParent('chooseToUse'); - if(!ui.selected.buttons.length){ - if(typeof button.link!='string') return false; - if(evt.type=='dying'){ - if(evt.dying.identity=='unknown'||evt.dying.identity=='ye') return true; - var double=get.is.double(button.link,true); - return evt.dying.identity==lib.character[button.link][1]||lib.character[button.link][1]=='ye'||(double&&double.includes(evt.dying.identity)); + filter(button, player) { + var evt = _status.event.getParent("chooseToUse"); + if (!ui.selected.buttons.length) { + if (typeof button.link != "string") return false; + if (evt.type == "dying") { + if (evt.dying.identity == "unknown" || evt.dying.identity == "ye") + return true; + var double = get.is.double(button.link, true); + return ( + evt.dying.identity == lib.character[button.link][1] || + lib.character[button.link][1] == "ye" || + (double && double.includes(evt.dying.identity)) + ); } return true; - } - else{ - if(typeof ui.selected.buttons[0].link!='string') return false; - if(typeof button.link!='object') return false; - var name=button.link[2]; - if(player.getStorage('fakeyigui2').includes(get.type(name))) return false; - var card={name:name}; - if(button.link[3]) card.nature=button.link[3]; - var info=get.info(card); - var group=lib.character[ui.selected.buttons[0].link][1]; - var double=get.is.double(ui.selected.buttons[0].link,true); - if(evt.type=='dying') return evt.filterCard(card,player,evt); - if(!lib.filter.filterCard(card,player,evt)) return false; - else if(evt.filterCard&&!evt.filterCard(card,player,evt)) return false; - if(info.changeTarget){ - var list=game.filterPlayer(function(current){ - return player.canUse(card,current); + } else { + if (typeof ui.selected.buttons[0].link != "string") return false; + if (typeof button.link != "object") return false; + var name = button.link[2]; + if (player.getStorage("fakeyigui2").includes(get.type(name))) return false; + var card = { name: name }; + if (button.link[3]) card.nature = button.link[3]; + var info = get.info(card); + var group = lib.character[ui.selected.buttons[0].link][1]; + var double = get.is.double(ui.selected.buttons[0].link, true); + if (evt.type == "dying") return evt.filterCard(card, player, evt); + if (!lib.filter.filterCard(card, player, evt)) return false; + else if (evt.filterCard && !evt.filterCard(card, player, evt)) return false; + if (info.changeTarget) { + var list = game.filterPlayer(function (current) { + return player.canUse(card, current); }); - for(var i=0;i1) return (1.7+Math.random())*Math.max(num,1); + if (num <= 0) return 0; + if (list.length > 1) return (1.7 + Math.random()) * Math.max(num, 1); } } - return 1+Math.random(); + return 1 + Math.random(); }, - backup(links,player){ - var name=links[1][2],nature=links[1][3]||null; - var character=links[0],group=lib.character[character][1]; - var next={ - character:character, - group:group, - filterCard:()=>false, - selectCard:-1, - popname:true, - audio:'yigui', - viewAs:{ - name:name, - nature:nature, - isCard:true, + backup(links, player) { + var name = links[1][2], + nature = links[1][3] || null; + var character = links[0], + group = lib.character[character][1]; + var next = { + character: character, + group: group, + filterCard: () => false, + selectCard: -1, + popname: true, + audio: "yigui", + viewAs: { + name: name, + nature: nature, + isCard: true, }, - filterTarget(card,player,target){ - var xx=lib.skill.fakeyigui_backup; - var evt=_status.event; - var group=xx.group; - var double=get.is.double(xx.character,true); - var info=get.info(card); - if((!(info.singleCard&&ui.selected.targets.length))&&group!='ye'&&target.identity!='unknown'&&target.identity!='ye'&&target.identity!=group&&(!double||!double.includes(target.identity))) return false; - if(info.changeTarget){ - var targets=[target]; - info.changeTarget(player,targets); - for(var i=0;idelete player.storage.fakeyigui2); + game.log(player, "移除了", "#g“魂”", "#y" + get.translation(character)); + if (!player.storage.fakeyigui2) { + player + .when({ global: "phaseBefore" }) + .then(() => delete player.storage.fakeyigui2); } - player.markAuto('fakeyigui2',[get.type(result.card.name)]); + player.markAuto("fakeyigui2", [get.type(result.card.name)]); }, }; return next; }, - prompt(links,player){ - var name=links[1][2],character=links[0],nature=links[1][3]; - return '移除「'+get.translation(character)+'」并视为使用'+(get.translation(nature)||'')+get.translation(name); + prompt(links, player) { + var name = links[1][2], + character = links[0], + nature = links[1][3]; + return ( + "移除「" + + get.translation(character) + + "」并视为使用" + + (get.translation(nature) || "") + + get.translation(name) + ); }, }, - ai:{ - order:()=>1+10*Math.random(), - result:{player:1}, + ai: { + order: () => 1 + 10 * Math.random(), + result: { player: 1 }, }, - group:'fakeyigui_init', - marktext:'魂', - intro:{ - onunmark(storage){ + group: "fakeyigui_init", + marktext: "魂", + intro: { + onunmark(storage) { _status.characterlist.addArray(storage); - storage=[]; + storage = []; }, - mark(dialog,storage,player){ - if(storage&&storage.length){ - if(player.isUnderControl(true)) dialog.addSmall([storage,'character']); - else return '共有'+get.cnNumber(storage.length)+'张“魂”'; - } - else return '没有“魂”'; + mark(dialog, storage, player) { + if (storage && storage.length) { + if (player.isUnderControl(true)) dialog.addSmall([storage, "character"]); + else return "共有" + get.cnNumber(storage.length) + "张“魂”"; + } else return "没有“魂”"; }, - content(storage){ - return '共有'+get.cnNumber(storage.length)+'张“魂”'; + content(storage) { + return "共有" + get.cnNumber(storage.length) + "张“魂”"; }, }, - gainHun(player,num){ - const list=_status.characterlist.randomGets(num); - if(list.length){ + gainHun(player, num) { + const list = _status.characterlist.randomGets(num); + if (list.length) { _status.characterlist.removeArray(list); - player.markAuto('fakeyigui',list); - get.info('rehuashen').drawCharacter(player,list); - game.log(player,'获得了'+get.cnNumber(list.length)+'张','#g“魂”'); + player.markAuto("fakeyigui", list); + get.info("rehuashen").drawCharacter(player, list); + game.log(player, "获得了" + get.cnNumber(list.length) + "张", "#g“魂”"); } }, - subSkill:{ - backup:{}, - init:{ - audio:'fakeyigui', - trigger:{player:'showCharacterAfter'}, - filter(event,player){ - if(!event.toShow.some(i=>get.character(i,3).includes('fakeyigui'))) return false; - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakeyigui')); - },event).indexOf(event)==0; + subSkill: { + backup: {}, + init: { + audio: "fakeyigui", + trigger: { player: "showCharacterAfter" }, + filter(event, player) { + if (!event.toShow.some((i) => get.character(i, 3).includes("fakeyigui"))) + return false; + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => + get.character(i, 3).includes("fakeyigui") + ) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - forced:true, - locked:false, - content(){ - get.info('fakeyigui').gainHun(player,2); + forced: true, + locked: false, + content() { + get.info("fakeyigui").gainHun(player, 2); }, }, }, }, - fakejihun:{ - audio:'jihun', - inherit:'jihun', - content(){ - get.info('fakeyigui').gainHun(player,1); + fakejihun: { + audio: "jihun", + inherit: "jihun", + content() { + get.info("fakeyigui").gainHun(player, 1); }, - ai:{combo:'fakeyigui'}, - group:'fakejihun_zhiheng', - subSkill:{ - zhiheng:{ - audio:'jihun', - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ - return player.getStorage('fakeyigui').length; + ai: { combo: "fakeyigui" }, + group: "fakejihun_zhiheng", + subSkill: { + zhiheng: { + audio: "jihun", + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { + return player.getStorage("fakeyigui").length; }, - async cost(event,trigger,player){ - const {result:{bool,links}}=await player.chooseButton([ - get.prompt('fakejihun'),'
                        弃置至多两张“魂”,然后获得等量的“魂”
                        ', - [player.getStorage('fakeyigui'),'character'], - ],[1,2]).set('ai',button=>{ - const getNum=(character)=>{ - return game.countPlayer(target=>{ - const group=get.character(character,1); - if(group=='ye'||target.identity==group) return true; - const double=get.is.double(character,true); - if(double&&double.includes(target.identity)) return true; - })+1; - }; - return game.countPlayer()-getNum(button.link); - }); - event.result={bool:bool,cost_data:links}; + async cost(event, trigger, player) { + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + get.prompt("fakejihun"), + '
                        弃置至多两张“魂”,然后获得等量的“魂”
                        ', + [player.getStorage("fakeyigui"), "character"], + ], + [1, 2] + ) + .set("ai", (button) => { + const getNum = (character) => { + return ( + game.countPlayer((target) => { + const group = get.character(character, 1); + if (group == "ye" || target.identity == group) return true; + const double = get.is.double(character, true); + if (double && double.includes(target.identity)) return true; + }) + 1 + ); + }; + return game.countPlayer() - getNum(button.link); + }); + event.result = { bool: bool, cost_data: links }; }, - async content(event,trigger,player){ - player.unmarkAuto('fakeyigui',event.cost_data); + async content(event, trigger, player) { + player.unmarkAuto("fakeyigui", event.cost_data); _status.characterlist.addArray(event.cost_data); - game.log(player,'移除了'+get.cnNumber(event.cost_data.length)+'张','#g“魂”'); - get.info('fakeyigui').gainHun(player,event.cost_data.length); + game.log( + player, + "移除了" + get.cnNumber(event.cost_data.length) + "张", + "#g“魂”" + ); + get.info("fakeyigui").gainHun(player, event.cost_data.length); }, }, }, }, - fakejueyan:{ - mainSkill:true, - init(player){ - if(player.checkMainSkill('fakejueyan')) player.removeMaxHp(); + fakejueyan: { + mainSkill: true, + init(player) { + if (player.checkMainSkill("fakejueyan")) player.removeMaxHp(); }, - audio:'drlt_jueyan', - derivation:'fakejizhi', - trigger:{player:'phaseZhunbeiBegin'}, - async cost(event,trigger,player){ - const {result:{control}}=await player.chooseControl('判定区','装备区','手牌区','cancel2') - .set('prompt','###'+get.prompt('fakejueyan')+'###
                        于本回合结束阶段弃置一个区域的所有牌,然后…
                        ') - .set('choiceList',[ - '判定区:跳过判定阶段,获得〖集智〗直到回合结束', - '装备区:摸三张牌,本回合手牌上限+3', - '手牌区:本回合使用【杀】的额定次数+3', - ]).set('ai',()=>{ - const player=get.event('player'); - if(player.countCards('j',{type:'delay'})) return '判定区'; - if(player.countCards('h')<3) return '装备区'; - if(player.countCards('hs',card=>{ - return get.name(card)=='sha'&&player.hasUseTarget(card); - })>player.getCardUsable('sha')) return '手牌区'; - return '判定区'; - }); - event.result={bool:(control!='cancel2'),cost_data:control}; - }, - async content(event,trigger,player){ - const position={'判定区':'j','装备区':'e','手牌区':'h'}[event.cost_data]; - switch(position){ - case 'j': - player.skip('phaseJudge'); - player.addTempSkills('fakejizhi'); - break; - case 'e': - await player.draw(3); - player.addTempSkill('drlt_jueyan3'); - break; - case 'h': - player.addTempSkill('drlt_jueyan1'); - break; - } - player.when('phaseJieshuBegin').then(()=>{ - if(player.countCards(pos)) player.discard(player.getCards(pos)); - }).vars({pos:position}); - }, - }, - fakejizhi:{ - audio:'rejizhi', - audioname:['lukang'], - inherit:'jizhi', - }, - fakequanji:{ - audio:'gzquanji', - inherit:'gzquanji', - filter(event,player,name){ - return !player.hasHistory('useSkill',evt=>{ - return evt.skill=='fakequanji'&&evt.event.triggername==name; - }); - }, - content(){ - 'step 0' - const num=Math.max(1,Math.min(player.maxHp,player.getExpansions('fakequanji').length)); - event.num=num; - player.draw(num); - 'step 1' - var hs=player.getCards('he'); - if(hs.length>0){ - if(hs.length<=event.num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择'+get.cnNumber(event.num)+'张牌作为“权”',event.num); - } - else event.finish(); - 'step 2' - if(result.bool){ - var cs=result.cards; - player.addToExpansion(cs,player,'give').gaintag.add('fakequanji'); - } - }, - mod:{ - maxHandcard(player,num){ - return num+player.getExpansions('fakequanji').length; - }, - }, - }, - fakepaiyi:{ - audio:'gzpaiyi', - enable:'phaseUse', - filterTarget:true, - usable:1, - async content(event,trigger,player){ - const target=event.target; - const {result:{junling,targets}}=await player.chooseJunlingFor(target); - if(junling){ - const str=get.translation(player),num=get.cnNumber(player.getExpansions('fakequanji').length); - const {result:{index}}=await target.chooseJunlingControl(player,junling,targets).set('prompt','排异').set('choiceList',[ - '执行此军令,然后'+str+'摸'+num+'张牌并将一张“权”置入弃牌堆', - '不执行此军令,然后'+str+'可以对至多'+num+'名与你势力相同的角色各造成1点伤害并移去等量的“权”', - ]).set('ai',()=>{ - const all=player.getExpansions('fakequanji').length; - const effect=get.junlingEffect(player,junling,target,targets,target); - const eff1=(effect-get.effect(player,{name:'draw'},player,target)*all); - const eff2=((source,player,num)=>{ - let targets=game.filterPlayer(current=>{ - return current.isFriendOf(player)&&get.damageEffect(current,source,source)>0&&get.damageEffect(current,source,player)<0; - }).sort((a,b)=>{ - return (get.damageEffect(b,source,source)>0-get.damageEffect(b,source,player))-(get.damageEffect(a,source,source)>0-get.damageEffect(a,source,player)); - }).slice(0,num); - return targets.reduce((sum,target)=>{ - return sum+(get.damageEffect(target,source,source)-get.damageEffect(target,source,player))/2; - },0); - })(player,target,all); - return Math.max(0,get.sgn(eff1-eff2)); + audio: "drlt_jueyan", + derivation: "fakejizhi", + trigger: { player: "phaseZhunbeiBegin" }, + async cost(event, trigger, player) { + const { + result: { control }, + } = await player + .chooseControl("判定区", "装备区", "手牌区", "cancel2") + .set( + "prompt", + "###" + + get.prompt("fakejueyan") + + '###
                        于本回合结束阶段弃置一个区域的所有牌,然后…
                        ' + ) + .set("choiceList", [ + "判定区:跳过判定阶段,获得〖集智〗直到回合结束", + "装备区:摸三张牌,本回合手牌上限+3", + "手牌区:本回合使用【杀】的额定次数+3", + ]) + .set("ai", () => { + const player = get.event("player"); + if (player.countCards("j", { type: "delay" })) return "判定区"; + if (player.countCards("h") < 3) return "装备区"; + if ( + player.countCards("hs", (card) => { + return get.name(card) == "sha" && player.hasUseTarget(card); + }) > player.getCardUsable("sha") + ) + return "手牌区"; + return "判定区"; }); - const cards=player.getExpansions('fakequanji'); - if(index==0){ - await target.carryOutJunling(player,junling,targets); - if(cards.length){ - await player.draw(cards.length); - const {result:{bool,links}}=await player.chooseButton(['排异:请移去一张“权”',cards],true); - if(bool) await player.loseToDiscardpile(links); - } - } - else if(cards.length){ - const {result}=await player.chooseTarget('排异:是否对至多'+get.cnNumber(cards.length)+'名与'+get.translation(target)+'势力相同的角色各造成1点伤害并移去等量的“权”?',(card,player,target)=>{ - return target.isFriendOf(get.event('target')); - },[1,cards.length]).set('target',target).set('ai',target=>{ - return get.damageEffect(target,get.event('player'),get.event('player')); + event.result = { bool: control != "cancel2", cost_data: control }; + }, + async content(event, trigger, player) { + const position = { 判定区: "j", 装备区: "e", 手牌区: "h" }[event.cost_data]; + switch (position) { + case "j": + player.skip("phaseJudge"); + player.addTempSkills("fakejizhi"); + break; + case "e": + await player.draw(3); + player.addTempSkill("drlt_jueyan3"); + break; + case "h": + player.addTempSkill("drlt_jueyan1"); + break; + } + player + .when("phaseJieshuBegin") + .then(() => { + if (player.countCards(pos)) player.discard(player.getCards(pos)); + }) + .vars({ pos: position }); + }, + }, + fakejizhi: { + audio: "rejizhi", + audioname: ["lukang"], + inherit: "jizhi", + }, + fakequanji: { + audio: "gzquanji", + inherit: "gzquanji", + filter(event, player, name) { + return !player.hasHistory("useSkill", (evt) => { + return evt.skill == "fakequanji" && evt.event.triggername == name; + }); + }, + content() { + "step 0"; + const num = Math.max( + 1, + Math.min(player.maxHp, player.getExpansions("fakequanji").length) + ); + event.num = num; + player.draw(num); + "step 1"; + var hs = player.getCards("he"); + if (hs.length > 0) { + if (hs.length <= event.num) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "he", + true, + "选择" + get.cnNumber(event.num) + "张牌作为“权”", + event.num + ); + } else event.finish(); + "step 2"; + if (result.bool) { + var cs = result.cards; + player.addToExpansion(cs, player, "give").gaintag.add("fakequanji"); + } + }, + mod: { + maxHandcard(player, num) { + return num + player.getExpansions("fakequanji").length; + }, + }, + }, + fakepaiyi: { + audio: "gzpaiyi", + enable: "phaseUse", + filterTarget: true, + usable: 1, + async content(event, trigger, player) { + const target = event.target; + const { + result: { junling, targets }, + } = await player.chooseJunlingFor(target); + if (junling) { + const str = get.translation(player), + num = get.cnNumber(player.getExpansions("fakequanji").length); + const { + result: { index }, + } = await target + .chooseJunlingControl(player, junling, targets) + .set("prompt", "排异") + .set("choiceList", [ + "执行此军令,然后" + str + "摸" + num + "张牌并将一张“权”置入弃牌堆", + "不执行此军令,然后" + + str + + "可以对至多" + + num + + "名与你势力相同的角色各造成1点伤害并移去等量的“权”", + ]) + .set("ai", () => { + const all = player.getExpansions("fakequanji").length; + const effect = get.junlingEffect(player, junling, target, targets, target); + const eff1 = + effect - get.effect(player, { name: "draw" }, player, target) * all; + const eff2 = ((source, player, num) => { + let targets = game + .filterPlayer((current) => { + return ( + current.isFriendOf(player) && + get.damageEffect(current, source, source) > 0 && + get.damageEffect(current, source, player) < 0 + ); + }) + .sort((a, b) => { + return ( + (get.damageEffect(b, source, source) > + 0 - get.damageEffect(b, source, player)) - + (get.damageEffect(a, source, source) > + 0 - get.damageEffect(a, source, player)) + ); + }) + .slice(0, num); + return targets.reduce((sum, target) => { + return ( + sum + + (get.damageEffect(target, source, source) - + get.damageEffect(target, source, player)) / + 2 + ); + }, 0); + })(player, target, all); + return Math.max(0, get.sgn(eff1 - eff2)); }); - if(result.bool){ - const targetx=result.targets.sortBySeat(); + const cards = player.getExpansions("fakequanji"); + if (index == 0) { + await target.carryOutJunling(player, junling, targets); + if (cards.length) { + await player.draw(cards.length); + const { + result: { bool, links }, + } = await player.chooseButton(["排异:请移去一张“权”", cards], true); + if (bool) await player.loseToDiscardpile(links); + } + } else if (cards.length) { + const { result } = await player + .chooseTarget( + "排异:是否对至多" + + get.cnNumber(cards.length) + + "名与" + + get.translation(target) + + "势力相同的角色各造成1点伤害并移去等量的“权”?", + (card, player, target) => { + return target.isFriendOf(get.event("target")); + }, + [1, cards.length] + ) + .set("target", target) + .set("ai", (target) => { + return get.damageEffect(target, get.event("player"), get.event("player")); + }); + if (result.bool) { + const targetx = result.targets.sortBySeat(); player.line(targetx); - for(const i of targetx) await i.damage(); - const {result:{bool,links}}=await player.chooseButton(['排异:请移去'+get.cnNumber(targetx.length)+'张“权”',cards],targetx.length,true); - if(bool) await player.loseToDiscardpile(links); + for (const i of targetx) await i.damage(); + const { + result: { bool, links }, + } = await player.chooseButton( + ["排异:请移去" + get.cnNumber(targetx.length) + "张“权”", cards], + targetx.length, + true + ); + if (bool) await player.loseToDiscardpile(links); } } } }, - ai:{ - order:1, - result:{ - target(player,target){ - return -game.countPlayer(current=>{ - return current==target||current.isFriendOf(target); + ai: { + order: 1, + result: { + target(player, target) { + return -game.countPlayer((current) => { + return current == target || current.isFriendOf(target); }); }, }, }, }, - fakeshilu:{ - audio:'gzshilu', - trigger:{player:['phaseZhunbeiBegin','phaseUseEnd']}, - filter(event,player){ - if(event.name=='phaseZhunbei') return player.getStorage('fakeshilu').length; - if(!player.hasViceCharacter()) return false; - const skills=get.character(player.name2,3).filter(i=>!get.is.locked(i,player)); - return !player.hasHistory('useSkill',evt=>evt.event.getParent('phaseUse')==event&&skills.includes(evt.sourceSkill||evt.skill)); + fakeshilu: { + audio: "gzshilu", + trigger: { player: ["phaseZhunbeiBegin", "phaseUseEnd"] }, + filter(event, player) { + if (event.name == "phaseZhunbei") return player.getStorage("fakeshilu").length; + if (!player.hasViceCharacter()) return false; + const skills = get.character(player.name2, 3).filter((i) => !get.is.locked(i, player)); + return !player.hasHistory( + "useSkill", + (evt) => + evt.event.getParent("phaseUse") == event && + skills.includes(evt.sourceSkill || evt.skill) + ); }, - forced:true, - async content(event,trigger,player){ - if(trigger.name=='phaseZhunbei'){ - const num=player.getStorage('fakeshilu').length; - await player.chooseToDiscard(num,'h',true); + forced: true, + async content(event, trigger, player) { + if (trigger.name == "phaseZhunbei") { + const num = player.getStorage("fakeshilu").length; + await player.chooseToDiscard(num, "h", true); await player.draw(num); - } - else{ - await player.changeVice().setContent(get.info('fakeshilu').changeVice); + } else { + await player.changeVice().setContent(get.info("fakeshilu").changeVice); } }, - getGroups(player){ - return player.getStorage('fakeshilu').map(i=>{ - const double=get.is.double(i,true); - return double?double:[get.character(i,1)]; - }).reduce((all,groups)=>{ - all.addArray(groups); - return all; - },[]); + getGroups(player) { + return player + .getStorage("fakeshilu") + .map((i) => { + const double = get.is.double(i, true); + return double ? double : [get.character(i, 1)]; + }) + .reduce((all, groups) => { + all.addArray(groups); + return all; + }, []); }, - changeVice(){ - 'step 0' + changeVice() { + "step 0"; player.showCharacter(2); - if(!event.num) event.num=3; - var group=player.identity; - if(!lib.group.includes(group)) group=lib.character[player.name1][1]; + if (!event.num) event.num = 3; + var group = player.identity; + if (!lib.group.includes(group)) group = lib.character[player.name1][1]; _status.characterlist.randomSort(); - event.tochange=[]; - for(var i=0;i<_status.characterlist.length;i++){ - if(_status.characterlist[i].indexOf('gz_jun_')==0) continue; - var goon=false,group2=lib.character[_status.characterlist[i]][1]; - if(group=='ye'){ - if(group2!='ye') goon=true; - } - else{ - if(group==group2) goon=true; - else{ - var double=get.is.double(_status.characterlist[i],true); - if(double&&double.includes(group)) goon=true; + event.tochange = []; + for (var i = 0; i < _status.characterlist.length; i++) { + if (_status.characterlist[i].indexOf("gz_jun_") == 0) continue; + var goon = false, + group2 = lib.character[_status.characterlist[i]][1]; + if (group == "ye") { + if (group2 != "ye") goon = true; + } else { + if (group == group2) goon = true; + else { + var double = get.is.double(_status.characterlist[i], true); + if (double && double.includes(group)) goon = true; } } - if(goon){ + if (goon) { event.tochange.push(_status.characterlist[i]); } } - event.tochange=event.tochange.filter(character=>{ - const groups=get.info('fakeshilu').getGroups(player); - const doublex=get.is.double(character,true); - const group=(doublex?doublex:[get.character(character,1)]); - return !group.some(j=>groups.includes(j)); - }).randomGets(event.num); - if(!event.tochange.length) event.finish(); - else{ - if(event.tochange.length==1) event._result={ - bool:true, - links:event.tochange, - } - else player.chooseButton(true,['请选择要变更的武将牌,并将原副将武将牌置于武将牌上',[event.tochange,'character']]).ai=function(button){ - return get.guozhanRank(button.link); - }; + event.tochange = event.tochange + .filter((character) => { + const groups = get.info("fakeshilu").getGroups(player); + const doublex = get.is.double(character, true); + const group = doublex ? doublex : [get.character(character, 1)]; + return !group.some((j) => groups.includes(j)); + }) + .randomGets(event.num); + if (!event.tochange.length) event.finish(); + else { + if (event.tochange.length == 1) + event._result = { + bool: true, + links: event.tochange, + }; + else + player.chooseButton(true, [ + "请选择要变更的武将牌,并将原副将武将牌置于武将牌上", + [event.tochange, "character"], + ]).ai = function (button) { + return get.guozhanRank(button.link); + }; } - 'step 1' - var name=result.links[0]; + "step 1"; + var name = result.links[0]; _status.characterlist.remove(name); - if(player.hasViceCharacter()) event.change=true; - event.toRemove=player.name2; - event.toChange=name; - if(event.change) event.trigger('removeCharacterBefore'); - if(event.hidden){ - if(!player.isUnseen(1)) player.hideCharacter(1); + if (player.hasViceCharacter()) event.change = true; + event.toRemove = player.name2; + event.toChange = name; + if (event.change) event.trigger("removeCharacterBefore"); + if (event.hidden) { + if (!player.isUnseen(1)) player.hideCharacter(1); } - 'step 2' - var name=event.toChange; - if(event.hidden) game.log(player,'替换了副将','#g'+get.translation(player.name2)); - else game.log(player,'将副将从','#g'+get.translation(player.name2),'变更为','#g'+get.translation(name)); - player.viceChanged=true; - player.reinitCharacter(player.name2,name,false); - 'step 3' - if(event.change&&event.toRemove){ - const list=[event.toRemove]; - player.markAuto('fakeshilu',list); - game.log(player,'将','#g'+get.translation(list),'置于武将牌上作为','#y“戮”'); - game.broadcastAll((player,list)=>{ - var cards=[]; - for(var i=0;i { + var cards = []; + for (var i = 0; i < list.length; i++) { + var cardname = "huashen_card_" + list[i]; + lib.card[cardname] = { + fullimage: true, + image: "character:" + list[i], + }; + lib.translate[cardname] = get.rawName2(list[i]); + cards.push(game.createCard(cardname, "", "")); } - lib.translate[cardname]=get.rawName2(list[i]); - cards.push(game.createCard(cardname,'','')); - } - player.$draw(cards,'nobroadcast'); - },player,list); + player.$draw(cards, "nobroadcast"); + }, + player, + list + ); } }, - marktext:'戮', - intro:{ - content:'character', - onunmark(storage,player){ - if(storage&&storage.length){ - _status.characterlist.addArray(storage) - storage=[]; + marktext: "戮", + intro: { + content: "character", + onunmark(storage, player) { + if (storage && storage.length) { + _status.characterlist.addArray(storage); + storage = []; } }, - mark(dialog,storage,player){ - if(storage&&storage.length) dialog.addSmall([storage,'character']); - else return '没有“戮”'; + mark(dialog, storage, player) { + if (storage && storage.length) dialog.addSmall([storage, "character"]); + else return "没有“戮”"; }, }, }, - fakexiongnve:{ - audio:'gzxiongnve', - trigger:{ - source:'damageBegin1', - player:['damageBegin3','damageBegin4'], + fakexiongnve: { + audio: "gzxiongnve", + trigger: { + source: "damageBegin1", + player: ["damageBegin3", "damageBegin4"], }, - filter(event,player,name){ - if(!event.source) return false; - const num=parseInt(name.slice('damageBegin'.length)); - const groups=get.info('fakeshilu').getGroups(player); - const goon=(event.card&&event.card.name=='sha'); - if(num!=4) return goon&&[event.player,event.source].some(target=>groups.includes(target.identity)); - return !goon&&groups.includes(event.source.identity); + filter(event, player, name) { + if (!event.source) return false; + const num = parseInt(name.slice("damageBegin".length)); + const groups = get.info("fakeshilu").getGroups(player); + const goon = event.card && event.card.name == "sha"; + if (num != 4) + return ( + goon && + [event.player, event.source].some((target) => groups.includes(target.identity)) + ); + return !goon && groups.includes(event.source.identity); }, - forced:true, - logTarget(event,player){ - return event.source==player?event.player:event.source; + forced: true, + logTarget(event, player) { + return event.source == player ? event.player : event.source; }, - async content(event,trigger,player){ - trigger[parseInt(name.slice('damageBegin'.length))==4?'decrease':'increase']('num'); + async content(event, trigger, player) { + trigger[parseInt(name.slice("damageBegin".length)) == 4 ? "decrease" : "increase"]("num"); }, - ai:{ - combo:'fakeshilu', - effect:{ - target(card,player,target){ - if(card&&card.name=='sha') return; - if(player.hasSkillTag('jueqing',false,target)) return; - const groups=get.info('fakeshilu').getGroups(target); - if(groups.includes(player.identity)){ - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + combo: "fakeshilu", + effect: { + target(card, player, target) { + if (card && card.name == "sha") return; + if (player.hasSkillTag("jueqing", false, target)) return; + const groups = get.info("fakeshilu").getGroups(target); + if (groups.includes(player.identity)) { + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } } @@ -1557,1105 +2249,1615 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, }, - fakehuaiyi:{ - audio:'gzhuaiyi', - enable:'phaseUse', - filter(event,player){ - if(!game.hasPlayer(target=>target.isMajor())) return false; - return player.hasViceCharacter()||['h','e','j'].some(pos=>player.getCards(pos).every(card=>lib.filter.cardDiscardable(card,player))); + fakehuaiyi: { + audio: "gzhuaiyi", + enable: "phaseUse", + filter(event, player) { + if (!game.hasPlayer((target) => target.isMajor())) return false; + return ( + player.hasViceCharacter() || + ["h", "e", "j"].some((pos) => + player.getCards(pos).every((card) => lib.filter.cardDiscardable(card, player)) + ) + ); }, - usable:1, - chooseButton:{ - dialog(){ - return ui.create.dialog('###怀异###'+get.translation('fakehuaiyi_info')); + usable: 1, + chooseButton: { + dialog() { + return ui.create.dialog("###怀异###" + get.translation("fakehuaiyi_info")); }, - chooseControl(event,player){ - let list=[],map={'h':'手牌区','e':'装备区','j':'判定区'}; - list.addArray(['h','e','j'].filter(pos=>{ - return player.getCards(pos).every(card=>lib.filter.cardDiscardable(card,player)); - }).map(i=>map[i])); - if(player.hasViceCharacter()) list.push('移除副将'); - list.push('cancel2'); + chooseControl(event, player) { + let list = [], + map = { h: "手牌区", e: "装备区", j: "判定区" }; + list.addArray( + ["h", "e", "j"] + .filter((pos) => { + return player + .getCards(pos) + .every((card) => lib.filter.cardDiscardable(card, player)); + }) + .map((i) => map[i]) + ); + if (player.hasViceCharacter()) list.push("移除副将"); + list.push("cancel2"); return list; }, - check(){ - const player=get.event('player'); - if(player.getCards('j').every(card=>lib.filter.cardDiscardable(card,player))) return '判定区'; - if(player.hasViceCharacter()&&get.guozhanRank(player.name2,player)<=3) return '移除副将'; - if(player.getCards('e').every(card=>lib.filter.cardDiscardable(card,player))&&player.getCards('e')<=1) return '装备区'; - if(player.getCards('h').every(card=>lib.filter.cardDiscardable(card,player))&&player.getCards('h')<=1) return '手牌区'; - return 'cancel2'; + check() { + const player = get.event("player"); + if (player.getCards("j").every((card) => lib.filter.cardDiscardable(card, player))) + return "判定区"; + if (player.hasViceCharacter() && get.guozhanRank(player.name2, player) <= 3) + return "移除副将"; + if ( + player.getCards("e").every((card) => lib.filter.cardDiscardable(card, player)) && + player.getCards("e") <= 1 + ) + return "装备区"; + if ( + player.getCards("h").every((card) => lib.filter.cardDiscardable(card, player)) && + player.getCards("h") <= 1 + ) + return "手牌区"; + return "cancel2"; }, - backup(result,player){ + backup(result, player) { return { - audio:'gzhuaiyi', - filterCard:()=>false, - selectCard:-1, - info:result.control, - async content(event,trigger,player){ - const control=get.info('fakehuaiyi_backup').info; - if(info=='移除副将'){ + audio: "gzhuaiyi", + filterCard: () => false, + selectCard: -1, + info: result.control, + async content(event, trigger, player) { + const control = get.info("fakehuaiyi_backup").info; + if (info == "移除副将") { await player.removeCharacter(1); - } - else{ - const map={'手牌区':'h','装备区':'e','判定区':'j'}; + } else { + const map = { 手牌区: "h", 装备区: "e", 判定区: "j" }; await player.discard(player.getCards(map[control])); } - let num={}; - const targetx=game.filterPlayer(target=>target.isMajor()); - for(const target of targetx){ - if(typeof num[target.identity]!='number') num[target.identity]=0; + let num = {}; + const targetx = game.filterPlayer((target) => target.isMajor()); + for (const target of targetx) { + if (typeof num[target.identity] != "number") num[target.identity] = 0; } - let groups=Object.keys(num); - const competition=groups.length>1; - for(const target of targetx){ - if(target==player) continue; - const {result:{bool,cards}}=await target.chooseToGive(player,'he',true,[1,Infinity],'怀异:交给'+get.translation(player)+'至少一张牌').set('ai',card=>{ - const player=get.event('player'),targets=get.event('targetx'); - if(!get.event('competition')||!game.hasPlayer(target=>{ - return target.isFriendOf(player)&&target.hasViceCharacter()&&get.guozhanRank(target.name2,target)>4; - })) return -get.value(card); - if(ui.selected.cards.length>=get.rand(2,3)) return 0; - return 7.5-get.value(card); - }).set('targets',targetx).set('num',num).set('prompt2',competition?'交牌最少的势力的一名角色的副将会被移除':'').set('complexCard',true).set('competition',competition); - if(bool){ - num[target.identity]+=cards.length; + let groups = Object.keys(num); + const competition = groups.length > 1; + for (const target of targetx) { + if (target == player) continue; + const { + result: { bool, cards }, + } = await target + .chooseToGive( + player, + "he", + true, + [1, Infinity], + "怀异:交给" + get.translation(player) + "至少一张牌" + ) + .set("ai", (card) => { + const player = get.event("player"), + targets = get.event("targetx"); + if ( + !get.event("competition") || + !game.hasPlayer((target) => { + return ( + target.isFriendOf(player) && + target.hasViceCharacter() && + get.guozhanRank(target.name2, target) > 4 + ); + }) + ) + return -get.value(card); + if (ui.selected.cards.length >= get.rand(2, 3)) return 0; + return 7.5 - get.value(card); + }) + .set("targets", targetx) + .set("num", num) + .set( + "prompt2", + competition ? "交牌最少的势力的一名角色的副将会被移除" : "" + ) + .set("complexCard", true) + .set("competition", competition); + if (bool) { + num[target.identity] += cards.length; } } - groups.sort((a,b)=>num[a]-num[b]); - const group=groups[0]; - if(num[group]target.identity==group)); - if(targetx.some(target=>target.identity==group&&target.hasViceCharacter())){ - const {result:{bool,targets}}=await player.chooseTarget('怀异:移除'+get.translation(group)+'势力的其中一名角色的副将',(card,player,target)=>{ - return target.identity==get.event('group')&&target.hasViceCharacter(); - },true).set('group',group).set('ai',target=>-get.guozhanRank(target.name2,target)); - if(bool){ - const target=targets[0]; + groups.sort((a, b) => num[a] - num[b]); + const group = groups[0]; + if (num[group] < num[groups[groups.length - 1]]) { + player.line(targetx.filter((target) => target.identity == group)); + if ( + targetx.some( + (target) => target.identity == group && target.hasViceCharacter() + ) + ) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "怀异:移除" + + get.translation(group) + + "势力的其中一名角色的副将", + (card, player, target) => { + return ( + target.identity == get.event("group") && + target.hasViceCharacter() + ); + }, + true + ) + .set("group", group) + .set("ai", (target) => -get.guozhanRank(target.name2, target)); + if (bool) { + const target = targets[0]; player.line(target); - game.log(player,'选择了',target); + game.log(player, "选择了", target); await target.removeCharacter(1); } } } }, - ai:{result:{player:1}}, - } + ai: { result: { player: 1 } }, + }; }, }, - ai:{ - order:10, - result:{ - player(player,target){ - if(!game.hasPlayer(i=>i.isMajor()&&get.attitude(player,i)<0)) return 0; - if(player.getCards('j').every(card=>lib.filter.cardDiscardable(card,player))) return 1; - if(player.hasViceCharacter()&&get.guozhanRank(player.name2,player)<=3) return 1; - if(player.getCards('e').every(card=>lib.filter.cardDiscardable(card,player))&&player.getCards('e')<=1) return 1; - if(player.getCards('h').every(card=>lib.filter.cardDiscardable(card,player))&&player.getCards('h')<=1) return 1; + ai: { + order: 10, + result: { + player(player, target) { + if (!game.hasPlayer((i) => i.isMajor() && get.attitude(player, i) < 0)) return 0; + if ( + player.getCards("j").every((card) => lib.filter.cardDiscardable(card, player)) + ) + return 1; + if (player.hasViceCharacter() && get.guozhanRank(player.name2, player) <= 3) + return 1; + if ( + player + .getCards("e") + .every((card) => lib.filter.cardDiscardable(card, player)) && + player.getCards("e") <= 1 + ) + return 1; + if ( + player + .getCards("h") + .every((card) => lib.filter.cardDiscardable(card, player)) && + player.getCards("h") <= 1 + ) + return 1; return 0; }, }, }, - subSkill:{backup:{}}, + subSkill: { backup: {} }, }, - fakezisui:{ - audio:'gzzisui', - trigger:{global:'removeCharacterEnd'}, - filter(event,player){ - return event.getParent().player==player; + fakezisui: { + audio: "gzzisui", + trigger: { global: "removeCharacterEnd" }, + filter(event, player) { + return event.getParent().player == player; }, - forced:true, - content(){ - const list=[trigger.toRemove]; - player.markAuto('fakezisui',list); - game.log(player,'将','#g'+get.translation(list),'置于武将牌上作为','#y“异”'); - game.broadcastAll((player,list)=>{ - var cards=[]; - for(var i=0;i { + var cards = []; + for (var i = 0; i < list.length; i++) { + var cardname = "huashen_card_" + list[i]; + lib.card[cardname] = { + fullimage: true, + image: "character:" + list[i], + }; + lib.translate[cardname] = get.rawName2(list[i]); + cards.push(game.createCard(cardname, "", "")); } - lib.translate[cardname]=get.rawName2(list[i]); - cards.push(game.createCard(cardname,'','')); - } - player.$draw(cards,'nobroadcast'); - },player,list); - }, - marktext:'异', - intro:{ - content:'character', - onunmark(storage,player){ - if(storage&&storage.length){ - _status.characterlist.addArray(storage) - storage=[]; - } - }, - mark(dialog,storage,player){ - if(storage&&storage.length) dialog.addSmall([storage,'character']); - else return '没有“异”'; - }, - }, - group:'fakezisui_effect', - subSkill:{ - effect:{ - audio:'gzzisui', - trigger:{player:['phaseDrawBegin2','phaseJieshuBegin']}, - filter(event,player){ - const num=player.getStorage('fakezisui').length; - if(!num) return false; - if(event.name=='phaseDraw') return !event.numFixed; - return num>player.maxHp; + player.$draw(cards, "nobroadcast"); }, - forced:true, - content(){ - const num=player.getStorage('fakezisui').length; - if(trigger.name=='phaseDraw') trigger.num+=num; + player, + list + ); + }, + marktext: "异", + intro: { + content: "character", + onunmark(storage, player) { + if (storage && storage.length) { + _status.characterlist.addArray(storage); + storage = []; + } + }, + mark(dialog, storage, player) { + if (storage && storage.length) dialog.addSmall([storage, "character"]); + else return "没有“异”"; + }, + }, + group: "fakezisui_effect", + subSkill: { + effect: { + audio: "gzzisui", + trigger: { player: ["phaseDrawBegin2", "phaseJieshuBegin"] }, + filter(event, player) { + const num = player.getStorage("fakezisui").length; + if (!num) return false; + if (event.name == "phaseDraw") return !event.numFixed; + return num > player.maxHp; + }, + forced: true, + content() { + const num = player.getStorage("fakezisui").length; + if (trigger.name == "phaseDraw") trigger.num += num; else player.die(); }, }, }, }, - fakejujian:{ - audio:'gzjujian', - init(player){ - if(player.checkViceSkill('fakejujian')&&!player.viceChanged) player.removeMaxHp(); + fakejujian: { + audio: "gzjujian", + init(player) { + if (player.checkViceSkill("fakejujian") && !player.viceChanged) player.removeMaxHp(); }, - viceSkill:true, - filter(event,player){ - return player.countCards('he',card=>{ - return _status.connectMode||(get.type(card)!='basic'&&lib.filter.cardDiscardable(card,player)); + viceSkill: true, + filter(event, player) { + return player.countCards("he", (card) => { + return ( + _status.connectMode || + (get.type(card) != "basic" && lib.filter.cardDiscardable(card, player)) + ); }); }, - async cost(event,trigger,player){ - event.result=await player.chooseCardTarget({ - prompt:get.prompt2('fakejujian'), - filterTarget(card,player,target){ + async cost(event, trigger, player) { + event.result = await player.chooseCardTarget({ + prompt: get.prompt2("fakejujian"), + filterTarget(card, player, target) { return target.isFriendOf(player); }, - filterCard(card,player){ - return get.type(card)!='basic'&&lib.filter.cardDiscardable(card,player); + filterCard(card, player) { + return get.type(card) != "basic" && lib.filter.cardDiscardable(card, player); }, - position:'he', - ai1(card){ - return 7.5-get.value(card); + position: "he", + ai1(card) { + return 7.5 - get.value(card); }, - ai2(target){ - const player=get.event('player'); - return Math.max(get.effect(target,{name:'wuzhong'},player,player),get.recoverEffect(target,player,player)); + ai2(target) { + const player = get.event("player"); + return Math.max( + get.effect(target, { name: "wuzhong" }, player, player), + get.recoverEffect(target, player, player) + ); }, }); }, - async content(event,trigger,player){ + async content(event, trigger, player) { await player.discard(event.cards); - const target=event.targets[0]; - await target.chooseDrawRecover(2,'举荐:摸两张牌或回复1点体力',true); + const target = event.targets[0]; + await target.chooseDrawRecover(2, "举荐:摸两张牌或回复1点体力", true); await target.mayChangeVice(); }, }, - fakexibing:{ - audio:'xibing', - inherit:'xibing', - content(){ - 'step 0' - var num=trigger.player.hp-trigger.player.countCards('h'); - if(num>0) trigger.player.draw(num); - 'step 1' - trigger.player.addTempSkill('xibing2'); - player._xibing=true; - if(get.mode()!='guozhan'||player.isUnseen(2)||trigger.player.isUnseen(2)) event.finish(); - 'step 2' - var target=trigger.player; - var players1=[player.name1,player.name2]; - var players2=[target.name1,target.name2]; - player.chooseButton(2,[ - '是否暗置自己和'+get.translation(target)+'的各一张武将牌?', - '
                        你的武将牌
                        ', - [players1,'character'], - '
                        '+get.translation(target)+'的武将牌
                        ', - [players2,'character'], - ]).set('players',players1).set('complexSelect',true).set('filterButton',function(button){ - return !get.is.jun(button.link)&&(ui.selected.buttons.length==0)==(_status.event.players.includes(button.link)); - }); - 'step 3' - if(result.bool){ - var target=trigger.player; - player.hideCharacter(player.name1==result.links[0]?0:1); - target.hideCharacter(target.name1==result.links[1]?0:1); - player.addTempSkill('xibing3'); - target.addTempSkill('xibing3'); + fakexibing: { + audio: "xibing", + inherit: "xibing", + content() { + "step 0"; + var num = trigger.player.hp - trigger.player.countCards("h"); + if (num > 0) trigger.player.draw(num); + "step 1"; + trigger.player.addTempSkill("xibing2"); + player._xibing = true; + if (get.mode() != "guozhan" || player.isUnseen(2) || trigger.player.isUnseen(2)) + event.finish(); + "step 2"; + var target = trigger.player; + var players1 = [player.name1, player.name2]; + var players2 = [target.name1, target.name2]; + player + .chooseButton(2, [ + "是否暗置自己和" + get.translation(target) + "的各一张武将牌?", + '
                        你的武将牌
                        ', + [players1, "character"], + '
                        ' + get.translation(target) + "的武将牌
                        ", + [players2, "character"], + ]) + .set("players", players1) + .set("complexSelect", true) + .set("filterButton", function (button) { + return ( + !get.is.jun(button.link) && + (ui.selected.buttons.length == 0) == + _status.event.players.includes(button.link) + ); + }); + "step 3"; + if (result.bool) { + var target = trigger.player; + player.hideCharacter(player.name1 == result.links[0] ? 0 : 1); + target.hideCharacter(target.name1 == result.links[1] ? 0 : 1); + player.addTempSkill("xibing3"); + target.addTempSkill("xibing3"); } }, }, - fakechengshang:{ - audio:'chengshang', - trigger:{player:'useCardAfter'}, - filter(event,player){ - if(!lib.suit.includes(get.suit(event.card,false))||typeof get.number(event.card)!='number') return false; - if(player.getHistory('sourceDamage',evt=>{ - return evt.card==event.card; - }).length) return false; - const phsu=event.getParent('phaseUse'); - if(!phsu||phsu.player!=player) return false; - return event.targets.some(i=>i.isEnemyOf(player)); + fakechengshang: { + audio: "chengshang", + trigger: { player: "useCardAfter" }, + filter(event, player) { + if ( + !lib.suit.includes(get.suit(event.card, false)) || + typeof get.number(event.card) != "number" + ) + return false; + if ( + player.getHistory("sourceDamage", (evt) => { + return evt.card == event.card; + }).length + ) + return false; + const phsu = event.getParent("phaseUse"); + if (!phsu || phsu.player != player) return false; + return event.targets.some((i) => i.isEnemyOf(player)); }, - usable:1, - preHidden:true, - async content(event,trigger,player){ + usable: 1, + preHidden: true, + async content(event, trigger, player) { await player.draw(); - player.tempBanSkill('fakechengshang','phaseUseAfter',false); - player.addTempSkill('fakechengshang_effect'); - player.markAuto('fakechengshang_effect',[[get.suit(trigger.card),get.number(trigger.card),trigger.card.name]]); + player.tempBanSkill("fakechengshang", "phaseUseAfter", false); + player.addTempSkill("fakechengshang_effect"); + player.markAuto("fakechengshang_effect", [ + [get.suit(trigger.card), get.number(trigger.card), trigger.card.name], + ]); }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - hiddenCard(player,name){ - const type=get.type(name); - if(type!='basic'&&type!='trick') return false; - const storage=player.getStorage('fakechengshang_effect'); - return lib.card.list.some(list=>{ - return name==list[2]&&storage.some(card=>{ - return card[0]==list[0]&&card[1]==list[1]&&card[2]!=list[2]; - }); + subSkill: { + effect: { + charlotte: true, + onremove: true, + hiddenCard(player, name) { + const type = get.type(name); + if (type != "basic" && type != "trick") return false; + const storage = player.getStorage("fakechengshang_effect"); + return lib.card.list.some((list) => { + return ( + name == list[2] && + storage.some((card) => { + return card[0] == list[0] && card[1] == list[1] && card[2] != list[2]; + }) + ); }); }, - audio:'chengshang', - enable:'phaseUse', - chooseButton:{ - dialog(event,player){ - const storage=player.getStorage('fakechengshang_effect'); - const list=lib.card.list.filter(list=>{ - const type=get.type(card[2]); - if(type!='basic'&&type!='trick') return false; - return storage.some(card=>card[0]==list[0]&&card[1]==list[1]&&card[2]!=list[2]); - }).map(card=>[get.translation(type),'',card[2],card[3]]); - return ui.create.dialog('承赏',[list,'vcard']); + audio: "chengshang", + enable: "phaseUse", + chooseButton: { + dialog(event, player) { + const storage = player.getStorage("fakechengshang_effect"); + const list = lib.card.list + .filter((list) => { + const type = get.type(card[2]); + if (type != "basic" && type != "trick") return false; + return storage.some( + (card) => + card[0] == list[0] && card[1] == list[1] && card[2] != list[2] + ); + }) + .map((card) => [get.translation(type), "", card[2], card[3]]); + return ui.create.dialog("承赏", [list, "vcard"]); }, - filter(button,player){ - return get.event().getParent().filterCard({name:button.link[2],nature:button.link[3]},player,event); + filter(button, player) { + return get + .event() + .getParent() + .filterCard( + { name: button.link[2], nature: button.link[3] }, + player, + event + ); }, - check(button){ - const player=get.event('player'); - const card={name:button.link[2],nature:button.link[3]}; - if(player.countCards('hes',cardx=>cardx.name==card.name)) return 0; + check(button) { + const player = get.event("player"); + const card = { name: button.link[2], nature: button.link[3] }; + if (player.countCards("hes", (cardx) => cardx.name == card.name)) return 0; return player.getUseValue(card); }, - backup(links,player){ + backup(links, player) { return { - audio:'chengshang', - filterCard:true, - position:'hs', - popname:true, - precontent(){ - player.logSkill('fakechengshang_effect'); + audio: "chengshang", + filterCard: true, + position: "hs", + popname: true, + precontent() { + player.logSkill("fakechengshang_effect"); delete event.result.skill; - const cardx=event.result.card; - const removes=player.getStorage('fakechengshang_effect').filter(card=>{ - return lib.card.list.some(list=>{ - return cardx.name==list[2]&&card[0]==list[0]&&card[1]==list[1]&&card[2]!=list[2]; + const cardx = event.result.card; + const removes = player + .getStorage("fakechengshang_effect") + .filter((card) => { + return lib.card.list.some((list) => { + return ( + cardx.name == list[2] && + card[0] == list[0] && + card[1] == list[1] && + card[2] != list[2] + ); + }); }); - }); - player.unmarkAuto('fakechengshang_effect',removes); + player.unmarkAuto("fakechengshang_effect", removes); }, - viewAs:{ - name:links[0][2], - nature:links[0][3], + viewAs: { + name: links[0][2], + nature: links[0][3], }, - } + }; }, - prompt(links,player){ - return '将一张手牌当作'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt(links, player) { + return ( + "将一张手牌当作" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, }, }, }, - fakezhente:{ - audio:'zhente', - inherit:'zhente', - filter(event,player){ - var color=get.color(event.card),type=get.type(event.card); - if(player==event.player||event.player.isDead()||color=='none') return false; - return type=='trick'||(type=='basic'&&color=='black'); + fakezhente: { + audio: "zhente", + inherit: "zhente", + filter(event, player) { + var color = get.color(event.card), + type = get.type(event.card); + if (player == event.player || event.player.isDead() || color == "none") return false; + return type == "trick" || (type == "basic" && color == "black"); }, }, - fakezhiwei:{ - audio:'zhiwei', - inherit:'zhiwei', - content(){ - 'step 0' - player.chooseTarget('请选择【至微】的目标',true,lib.filter.notMe).set('ai',target=>{ - var att=get.attitude(_status.event.player,target); - if(att>0) return 1+att; - return Math.random(); - }).set('prompt2',lib.translate.fakezhiwei_info); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('fakezhiwei',target); - player.storage.fakezhiwei_effect=target; - player.addSkill('fakezhiwei_effect'); + fakezhiwei: { + audio: "zhiwei", + inherit: "zhiwei", + content() { + "step 0"; + player + .chooseTarget("请选择【至微】的目标", true, lib.filter.notMe) + .set("ai", (target) => { + var att = get.attitude(_status.event.player, target); + if (att > 0) return 1 + att; + return Math.random(); + }) + .set("prompt2", lib.translate.fakezhiwei_info); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("fakezhiwei", target); + player.storage.fakezhiwei_effect = target; + player.addSkill("fakezhiwei_effect"); } }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - audio:'zhiwei', - trigger:{player:'hideCharacterBefore'}, - filter(event,player){ - return get.character(event.toHide,3).includes('fakezhiwei'); + subSkill: { + effect: { + charlotte: true, + onremove: true, + audio: "zhiwei", + trigger: { player: "hideCharacterBefore" }, + filter(event, player) { + return get.character(event.toHide, 3).includes("fakezhiwei"); }, - forced:true, - content(){ + forced: true, + content() { trigger.cancel(); }, - mark:'character', - intro:{content:'已选择$'}, - group:['fakezhiwei_draw','fakezhiwei_discard','fakezhiwei_gain','fakezhiwei_clear'], + mark: "character", + intro: { content: "已选择$" }, + group: [ + "fakezhiwei_draw", + "fakezhiwei_discard", + "fakezhiwei_gain", + "fakezhiwei_clear", + ], }, - draw:{ - audio:'zhiwei', - trigger:{global:'damageSource'}, - forced:true, - filter(event,player){ - return event.source==player.storage.fakezhiwei_effect; + draw: { + audio: "zhiwei", + trigger: { global: "damageSource" }, + forced: true, + filter(event, player) { + return event.source == player.storage.fakezhiwei_effect; }, - logTarget:'source', - content(){ + logTarget: "source", + content() { player.draw(); }, }, - discard:{ - audio:'zhiwei', - trigger:{global:'damageEnd'}, - forced:true, - filter(event,player){ - return event.player==player.storage.fakezhiwei_effect&&player.hasCard(card=>{ - return _status.connectMode||lib.filter.cardDiscardable(card,player); - },'h'); + discard: { + audio: "zhiwei", + trigger: { global: "damageEnd" }, + forced: true, + filter(event, player) { + return ( + event.player == player.storage.fakezhiwei_effect && + player.hasCard((card) => { + return _status.connectMode || lib.filter.cardDiscardable(card, player); + }, "h") + ); }, - logTarget:'player', - content(){ - player.chooseToDiscard('h',true); + logTarget: "player", + content() { + player.chooseToDiscard("h", true); }, }, - gain:{ - audio:'zhiwei', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + gain: { + audio: "zhiwei", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - forced:true, - filter(event,player){ - if(event.type!='discard'||event.getlx===false||event.getParent('phaseDiscard').player!=player||!player.storage.fakezhiwei_effect||!player.storage.fakezhiwei_effect.isIn()) return false; - var evt=event.getl(player); - return evt&&evt.cards2.filterInD('d').length>0; + forced: true, + filter(event, player) { + if ( + event.type != "discard" || + event.getlx === false || + event.getParent("phaseDiscard").player != player || + !player.storage.fakezhiwei_effect || + !player.storage.fakezhiwei_effect.isIn() + ) + return false; + var evt = event.getl(player); + return evt && evt.cards2.filterInD("d").length > 0; }, - logTarget(event,player){ + logTarget(event, player) { return player.storage.fakezhiwei_effect; }, - content(){ - if(trigger.delay===false) game.delay(); - player.storage.fakezhiwei_effect.gain(trigger.getl(player).cards2.filterInD('d'),'gain2'); + content() { + if (trigger.delay === false) game.delay(); + player.storage.fakezhiwei_effect.gain( + trigger.getl(player).cards2.filterInD("d"), + "gain2" + ); }, }, - clear:{ - audio:'zhiwei', - trigger:{ - global:'die', - player:['hideCharacterEnd','removeCharacterEnd'], + clear: { + audio: "zhiwei", + trigger: { + global: "die", + player: ["hideCharacterEnd", "removeCharacterEnd"], }, - forced:true, - filter(event,player){ - if(event.name=='die') return event.player==player.storage.fakezhiwei_effect; - if(event.name=='removeCharacter') return get.character(event.toRemove,3).includes('fakezhiwei'); - return get.character(event.toHide,3).includes('fakezhiwei'); + forced: true, + filter(event, player) { + if (event.name == "die") return event.player == player.storage.fakezhiwei_effect; + if (event.name == "removeCharacter") + return get.character(event.toRemove, 3).includes("fakezhiwei"); + return get.character(event.toHide, 3).includes("fakezhiwei"); }, - content(){ - 'step 0' - player.removeSkill('fakezhiwei_effect'); - if(trigger.name!='die') event.finish(); - 'step 1' - if(get.character(player.name1,3).includes('fakezhiwei')) player.hideCharacter(0); - if(get.character(player.name2,3).includes('fakezhiwei')) player.hideCharacter(1); + content() { + "step 0"; + player.removeSkill("fakezhiwei_effect"); + if (trigger.name != "die") event.finish(); + "step 1"; + if (get.character(player.name1, 3).includes("fakezhiwei")) + player.hideCharacter(0); + if (get.character(player.name2, 3).includes("fakezhiwei")) + player.hideCharacter(1); }, }, }, }, - fakekuangcai:{ - inherit:'gzrekuangcai', - content(){ - const goon=Boolean(player.getHistory('useCard').length); - get.info('rekuangcai').change(player,goon?-1:1); - player.when({global:'phaseAfter'}).then(()=>{ - get.info('rekuangcai').change(player,goon?1:-1); - }).vars({goon:goon}); + fakekuangcai: { + inherit: "gzrekuangcai", + content() { + const goon = Boolean(player.getHistory("useCard").length); + get.info("rekuangcai").change(player, goon ? -1 : 1); + player + .when({ global: "phaseAfter" }) + .then(() => { + get.info("rekuangcai").change(player, goon ? 1 : -1); + }) + .vars({ goon: goon }); }, }, - faketunchu:{ - audio:'tunchu', - trigger:{player:'phaseDrawBegin2'}, - filter(event,player){ + faketunchu: { + audio: "tunchu", + trigger: { player: "phaseDrawBegin2" }, + filter(event, player) { return !event.numFixed; }, - check(event,player){ - return player.countCards('h')<=2; + check(event, player) { + return player.countCards("h") <= 2; }, - locked:false, - preHidden:true, - content(){ - trigger.num+=2; - player.when(['phaseDrawEnd','phaseDrawSkipped','phaseDrawCancelled']) - .filter(evt=>evt==trigger) - .then(()=>{ - var nh=player.countCards('h'); - if(nh){ - player.chooseCard('h',[1,Math.min(nh,2)],'将至多两张手牌置于你的武将牌上',true).set('ai',card=>{ - return 7.5-get.value(card); - }); - } - else{ - player.addTempSkill('faketunchu_effect'); - event.finish(); - } - }) - .then(()=>{ - if(result.bool) player.addToExpansion(result.cards,player,'giveAuto').gaintag.add('faketunchu'); - }) - .then(()=>{ - player.addTempSkill('faketunchu_effect'); - }); + locked: false, + preHidden: true, + content() { + trigger.num += 2; + player + .when(["phaseDrawEnd", "phaseDrawSkipped", "phaseDrawCancelled"]) + .filter((evt) => evt == trigger) + .then(() => { + var nh = player.countCards("h"); + if (nh) { + player + .chooseCard( + "h", + [1, Math.min(nh, 2)], + "将至多两张手牌置于你的武将牌上", + true + ) + .set("ai", (card) => { + return 7.5 - get.value(card); + }); + } else { + player.addTempSkill("faketunchu_effect"); + event.finish(); + } + }) + .then(() => { + if (result.bool) + player + .addToExpansion(result.cards, player, "giveAuto") + .gaintag.add("faketunchu"); + }) + .then(() => { + player.addTempSkill("faketunchu_effect"); + }); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - marktext:'粮', - onremove(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "粮", + onremove(player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - subSkill:{ - effect:{ - charlotte:true, - mod:{ - cardEnabled(card,player){ - if(card.name=='sha') return false; + subSkill: { + effect: { + charlotte: true, + mod: { + cardEnabled(card, player) { + if (card.name == "sha") return false; }, }, - mark:true, - intro:{content:'本回合不能使用【杀】'}, + mark: true, + intro: { content: "本回合不能使用【杀】" }, }, }, }, - fakeshuliang:{ - audio:'shuliang', - trigger:{global:'phaseJieshuBegin'}, - filter(event,player){ - const num=player.getExpansions('faketunchu').length; - if(!num||!event.player.isFriendOf(player)) return false; - return event.player.isIn()&&get.distance(player,event.player)<=num; + fakeshuliang: { + audio: "shuliang", + trigger: { global: "phaseJieshuBegin" }, + filter(event, player) { + const num = player.getExpansions("faketunchu").length; + if (!num || !event.player.isFriendOf(player)) return false; + return event.player.isIn() && get.distance(player, event.player) <= num; }, - async cost(event,trigger,player){ - const {result:{bool,links}}=await player.chooseButton([get.prompt2('fakeshuliang',trigger.player),player.getExpansions('faketunchu')]).set('ai',button=>{ - if(get.attitude(get.event('player'),get.event().getTrigger().player)<=0) return 0; - return 1+Math.random(); - }).set('hiddenSkill','fakeshuliang'); - event.result={bool:bool,cost_data:links}; + async cost(event, trigger, player) { + const { + result: { bool, links }, + } = await player + .chooseButton([ + get.prompt2("fakeshuliang", trigger.player), + player.getExpansions("faketunchu"), + ]) + .set("ai", (button) => { + if (get.attitude(get.event("player"), get.event().getTrigger().player) <= 0) + return 0; + return 1 + Math.random(); + }) + .set("hiddenSkill", "fakeshuliang"); + event.result = { bool: bool, cost_data: links }; }, - preHidden:true, - logTarget:'player', - content(){ + preHidden: true, + logTarget: "player", + content() { player.loseToDiscardpile(event.cost_data); trigger.player.draw(2); }, - ai:{combo:'faketunchu'}, + ai: { combo: "faketunchu" }, }, - fakedujin:{ - audio:'dujin', - inherit:'dujin', - filter(event,player){ - return player.countCards('e')&&!event.numFixed; + fakedujin: { + audio: "dujin", + inherit: "dujin", + filter(event, player) { + return player.countCards("e") && !event.numFixed; }, - content(){ - trigger.num+=Math.ceil(player.countCards('e')/2); + content() { + trigger.num += Math.ceil(player.countCards("e") / 2); }, - group:'fakedujin_first', - subSkill:{ - first:{ - audio:'dujin', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - if(game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakedujin')); - },event).indexOf(event)!=0) return false; - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player.isFriendOf(player); - })[0].player==player; + group: "fakedujin_first", + subSkill: { + first: { + audio: "dujin", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + if ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => + get.character(i, 3).includes("fakedujin") + ) + ); + }, + event + ) + .indexOf(event) != 0 + ) + return false; + return ( + game.getAllGlobalHistory("everything", (evt) => { + return evt.name == "showCharacter" && evt.player.isFriendOf(player); + })[0].player == player + ); }, - forced:true, - locked:false, - content(){ - player.addMark('xianqu_mark',1); + forced: true, + locked: false, + content() { + player.addMark("xianqu_mark", 1); }, }, }, }, - fakezhufu:{ - audio:'spwuku', - enable:'phaseUse', - filter(event,player){ - return player.hasCard(card=>{ - return get.info('fakezhufu').filterCard(card,player); - },'he'); + fakezhufu: { + audio: "spwuku", + enable: "phaseUse", + filter(event, player) { + return player.hasCard((card) => { + return get.info("fakezhufu").filterCard(card, player); + }, "he"); }, - filterCard(card,player){ - if(!lib.suit.includes(get.suit(card))) return false; - return lib.filter.cardDiscardable(card,player)&&!player.getStorage('fakezhufu_effect').includes(get.suit(card)); + filterCard(card, player) { + if (!lib.suit.includes(get.suit(card))) return false; + return ( + lib.filter.cardDiscardable(card, player) && + !player.getStorage("fakezhufu_effect").includes(get.suit(card)) + ); }, - position:'he', - check(card){ - const player=get.event('player'); - let cards=player.getCards('hs',card=>player.hasValueTarget(card,true,true)); - let discards=player.getCards('he',card=>get.info('fakezhufu').filterCard(card,player)); - for(let i=1;iget.suit(card)==get.suit(discards[i]))) discards.splice(i--,1); + position: "he", + check(card) { + const player = get.event("player"); + let cards = player.getCards("hs", (card) => player.hasValueTarget(card, true, true)); + let discards = player.getCards("he", (card) => + get.info("fakezhufu").filterCard(card, player) + ); + for (let i = 1; i < discards.length; i++) { + if (discards.slice(0, i).some((card) => get.suit(card) == get.suit(discards[i]))) + discards.splice(i--, 1); } cards.removeArray(discards); - if(!cards.length||!discards.length) return 0; - cards.sort((a,b)=>{ - return (player.getUseValue(b,true,true)>0?get.order(b):0)-(player.getUseValue(a,true,true)>0?get.order(a):0); + if (!cards.length || !discards.length) return 0; + cards.sort((a, b) => { + return ( + (player.getUseValue(b, true, true) > 0 ? get.order(b) : 0) - + (player.getUseValue(a, true, true) > 0 ? get.order(a) : 0) + ); }); - const cardx=cards[0]; - if(get.order(cardx,player)>0&&discards.includes(card)){ - if((get.suit(card)=='heart'&&get.type(cardx)!='equip'&&(function(card,player){ - const num=get.info('fakezhufu').getMaxUseTarget(card,player); - return num!=-1&&game.countPlayer(target=>player.canUse(card,target,true,true)&&get.effect(target,card,player,player)>0)>num; - }(cardx,player))&&game.hasPlayer(target=>{ - return target.isFriendOf(player)&&target.hasCard(cardy=>{ - return lib.filter.cardDiscardable(cardy,target)&&get.type2(cardy)==get.type2(cardx); - },'h'); - }))||(get.suit(card)=='diamond'&&get.type(cardx)!='equip'&&!game.hasPlayer(target=>{ - return target.countCards('h')>player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0); - }))||(get.suit(card)=='spade'&&player.getHp()==1)||(get.suit(card)=='club'&&get.tag(cardx,'damage')&&player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0)==0)) return 1/(getvalue(card)||0.5); + const cardx = cards[0]; + if (get.order(cardx, player) > 0 && discards.includes(card)) { + if ( + (get.suit(card) == "heart" && + get.type(cardx) != "equip" && + (function (card, player) { + const num = get.info("fakezhufu").getMaxUseTarget(card, player); + return ( + num != -1 && + game.countPlayer( + (target) => + player.canUse(card, target, true, true) && + get.effect(target, card, player, player) > 0 + ) > num + ); + })(cardx, player) && + game.hasPlayer((target) => { + return ( + target.isFriendOf(player) && + target.hasCard((cardy) => { + return ( + lib.filter.cardDiscardable(cardy, target) && + get.type2(cardy) == get.type2(cardx) + ); + }, "h") + ); + })) || + (get.suit(card) == "diamond" && + get.type(cardx) != "equip" && + !game.hasPlayer((target) => { + return ( + target.countCards("h") > + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) + ); + })) || + (get.suit(card) == "spade" && player.getHp() == 1) || + (get.suit(card) == "club" && + get.tag(cardx, "damage") && + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) == + 0) + ) + return 1 / (getvalue(card) || 0.5); } return 0; }, - async content(event,trigger,player){ - const suit=get.suit(event.cards[0],player); - player.addTempSkill('fakezhufu_effect','phaseUseAfter'); - player.markAuto('fakezhufu_effect',[[suit,false]]); + async content(event, trigger, player) { + const suit = get.suit(event.cards[0], player); + player.addTempSkill("fakezhufu_effect", "phaseUseAfter"); + player.markAuto("fakezhufu_effect", [[suit, false]]); }, - ai:{ - order(item,player){ - let cards=player.getCards('hs',card=>player.hasValueTarget(card,true,true)); - let discards=player.getCards('he',card=>get.info('fakezhufu').filterCard(card,player)); - for(let i=1;iget.suit(card)==get.suit(discards[i]))) discards.splice(i--,1); + ai: { + order(item, player) { + let cards = player.getCards("hs", (card) => player.hasValueTarget(card, true, true)); + let discards = player.getCards("he", (card) => + get.info("fakezhufu").filterCard(card, player) + ); + for (let i = 1; i < discards.length; i++) { + if (discards.slice(0, i).some((card) => get.suit(card) == get.suit(discards[i]))) + discards.splice(i--, 1); } cards.removeArray(discards); - if(!cards.length||!discards.length) return 0; - cards.sort((a,b)=>{ - return (player.getUseValue(b,true,true)>0?get.order(b):0)-(player.getUseValue(a,true,true)>0?get.order(a):0); + if (!cards.length || !discards.length) return 0; + cards.sort((a, b) => { + return ( + (player.getUseValue(b, true, true) > 0 ? get.order(b) : 0) - + (player.getUseValue(a, true, true) > 0 ? get.order(a) : 0) + ); }); - const cardx=cards[0]; - return (get.order(cardx,player)>0&&((discards.some(card=>{ - return get.suit(card)=='heart'; - })&&get.type(cardx)!='equip'&&(function(card,player){ - const num=get.info('fakezhufu').getMaxUseTarget(card,player); - return num!=-1&&game.countPlayer(target=>player.canUse(card,target,true,true)&&get.effect(target,card,player,player)>0)>num; - }(cardx,player))&&game.hasPlayer(target=>{ - return target.isFriendOf(player)&&target.hasCard(cardy=>{ - return lib.filter.cardDiscardable(cardy,target)&&get.type2(cardy)==get.type2(cardx); - },'h'); - }))||(get.type(cardx)!='equip'&&discards.some(card=>{ - return get.suit(card)=='diamond'&&!game.hasPlayer(target=>{ - return target.countCards('h')>player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0); - }); - }))||(discards.some(card=>{ - return get.suit(card)=='spade'; - })&&player.getHp()==1)||(get.tag(cardx,'damage')&&discards.some(card=>{ - return get.suit(card)=='club'&&player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0)==0; - }))))?(get.order(cardx,player)+0.00001):0; + const cardx = cards[0]; + return get.order(cardx, player) > 0 && + ((discards.some((card) => { + return get.suit(card) == "heart"; + }) && + get.type(cardx) != "equip" && + (function (card, player) { + const num = get.info("fakezhufu").getMaxUseTarget(card, player); + return ( + num != -1 && + game.countPlayer( + (target) => + player.canUse(card, target, true, true) && + get.effect(target, card, player, player) > 0 + ) > num + ); + })(cardx, player) && + game.hasPlayer((target) => { + return ( + target.isFriendOf(player) && + target.hasCard((cardy) => { + return ( + lib.filter.cardDiscardable(cardy, target) && + get.type2(cardy) == get.type2(cardx) + ); + }, "h") + ); + })) || + (get.type(cardx) != "equip" && + discards.some((card) => { + return ( + get.suit(card) == "diamond" && + !game.hasPlayer((target) => { + return ( + target.countCards("h") > + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) + ); + }) + ); + })) || + (discards.some((card) => { + return get.suit(card) == "spade"; + }) && + player.getHp() == 1) || + (get.tag(cardx, "damage") && + discards.some((card) => { + return ( + get.suit(card) == "club" && + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) == + 0 + ); + }))) + ? get.order(cardx, player) + 0.00001 + : 0; }, - result:{ - player(player,target){ - let cards=player.getCards('hs',card=>player.hasValueTarget(card,true,true)); - let discards=player.getCards('he',card=>get.info('fakezhufu').filterCard(card,player)); - discards=discards.sort((a,b)=>get.value(a)-get.value(b)); - for(let i=1;iget.suit(card)==get.suit(discards[i]))) discards.splice(i--,1); + result: { + player(player, target) { + let cards = player.getCards("hs", (card) => + player.hasValueTarget(card, true, true) + ); + let discards = player.getCards("he", (card) => + get.info("fakezhufu").filterCard(card, player) + ); + discards = discards.sort((a, b) => get.value(a) - get.value(b)); + for (let i = 1; i < discards.length; i++) { + if ( + discards + .slice(0, i) + .some((card) => get.suit(card) == get.suit(discards[i])) + ) + discards.splice(i--, 1); } cards.removeArray(discards); - if(!cards.length||!discards.length) return 0; - if((discards.some(card=>{ - return get.suit(card)=='heart'; - })&&cards.some(card=>{ - return get.type(card)!='equip'&&(function(card,player){ - const num=get.info('fakezhufu').getMaxUseTarget(card,player); - return num!=-1&&game.countPlayer(target=>player.canUse(card,target,true,true)&&get.effect(target,card,player,player)>0)>num; - }(card,player))&&game.hasPlayer(target=>{ - return target.isFriendOf(player)&&target.hasCard(cardx=>{ - return lib.filter.cardDiscardable(cardx,target)&&get.type2(cardx)==get.type2(card); - },'h'); - }); - }))||discards.some(card=>{ - return get.suit(card)=='diamond'&&cards.some(cardx=>{ - return get.type(cardx)!='equip'&&!game.hasPlayer(target=>{ - return target.countCards('h')>player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0); - }); - }); - })||(discards.some(card=>{ - return get.suit(card)=='spade'; - })&&player.getHp()==1)||discards.some(card=>{ - return get.suit(card)=='club'&&cards.some(cardx=>{ - return get.tag(cardx,'damage')&&player.countCards('h')-(get.position(card)=='h'?1:0)-(get.position(cardx)=='h'?1:0)==0; - }); - })) return 1; + if (!cards.length || !discards.length) return 0; + if ( + (discards.some((card) => { + return get.suit(card) == "heart"; + }) && + cards.some((card) => { + return ( + get.type(card) != "equip" && + (function (card, player) { + const num = get + .info("fakezhufu") + .getMaxUseTarget(card, player); + return ( + num != -1 && + game.countPlayer( + (target) => + player.canUse(card, target, true, true) && + get.effect(target, card, player, player) > 0 + ) > num + ); + })(card, player) && + game.hasPlayer((target) => { + return ( + target.isFriendOf(player) && + target.hasCard((cardx) => { + return ( + lib.filter.cardDiscardable(cardx, target) && + get.type2(cardx) == get.type2(card) + ); + }, "h") + ); + }) + ); + })) || + discards.some((card) => { + return ( + get.suit(card) == "diamond" && + cards.some((cardx) => { + return ( + get.type(cardx) != "equip" && + !game.hasPlayer((target) => { + return ( + target.countCards("h") > + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) + ); + }) + ); + }) + ); + }) || + (discards.some((card) => { + return get.suit(card) == "spade"; + }) && + player.getHp() == 1) || + discards.some((card) => { + return ( + get.suit(card) == "club" && + cards.some((cardx) => { + return ( + get.tag(cardx, "damage") && + player.countCards("h") - + (get.position(card) == "h" ? 1 : 0) - + (get.position(cardx) == "h" ? 1 : 0) == + 0 + ); + }) + ); + }) + ) + return 1; return 0; }, }, }, - subSkill:{ - effect:{ - charlotte:true, - onremove:true, - intro:{ - content(storage){ - const suitStorage=storage.slice().sort((a,b)=>lib.suit.indexOf(a[0])-lib.suit.indexOf(b[0])); - const suits=suitStorage.reduce((str,list)=>str+get.translation(list[0]),''); - const usedSuits=suitStorage.filter(list=>list[1]).reduce((str,list)=>str+get.translation(list[0]),''); - let str=''; - str+='
                      • 已弃置过的花色:'; - str+=suits; - if(usedSuits.length){ - str+='
                      • 已触发过的花色:'; - str+=usedSuits; + subSkill: { + effect: { + charlotte: true, + onremove: true, + intro: { + content(storage) { + const suitStorage = storage + .slice() + .sort((a, b) => lib.suit.indexOf(a[0]) - lib.suit.indexOf(b[0])); + const suits = suitStorage.reduce( + (str, list) => str + get.translation(list[0]), + "" + ); + const usedSuits = suitStorage + .filter((list) => list[1]) + .reduce((str, list) => str + get.translation(list[0]), ""); + let str = ""; + str += "
                      • 已弃置过的花色:"; + str += suits; + if (usedSuits.length) { + str += "
                      • 已触发过的花色:"; + str += usedSuits; } return str; }, }, - audio:'spwuku', - trigger:{player:'yingbian'}, - filter(event,player){ - return player.getStorage('fakezhufu_effect').some(list=>!list[1]); + audio: "spwuku", + trigger: { player: "yingbian" }, + filter(event, player) { + return player.getStorage("fakezhufu_effect").some((list) => !list[1]); }, - forced:true, - firstDo:true, - async content(event,trigger,player){ - const list=player.getStorage('fakezhufu_effect').filter(i=>!i[1]); - const forced=(function(trigger,player){ - if(trigger.forceYingbian||player.hasSkillTag('forceYingbian')) return true; - const list=(trigger.temporaryYingbian||[]); - return list.includes('force')||get.cardtag(trigger.card,'yingbian_force'); - }(trigger,player)); - if(forced){ - player.popup('yingbian_force_tag',lib.yingbian.condition.color.get('force')); - game.log(player,'触发了','#g【注傅】','为',trigger.card,'添加的应变条件'); + forced: true, + firstDo: true, + async content(event, trigger, player) { + const list = player.getStorage("fakezhufu_effect").filter((i) => !i[1]); + const forced = (function (trigger, player) { + if (trigger.forceYingbian || player.hasSkillTag("forceYingbian")) return true; + const list = trigger.temporaryYingbian || []; + return list.includes("force") || get.cardtag(trigger.card, "yingbian_force"); + })(trigger, player); + if (forced) { + player.popup("yingbian_force_tag", lib.yingbian.condition.color.get("force")); + game.log( + player, + "触发了", + "#g【注傅】", + "为", + trigger.card, + "添加的应变条件" + ); } - const hasYingBian=(trigger.temporaryYingbian||[]),map=get.info('fakezhufu').YingBianMap; - for(const j of list){ - player.storage.fakezhufu_effect[player.getStorage('fakezhufu_effect').indexOf(j)][1]=true; - const tag=map[j[0]][0],eff=map[j[0]][1]; - if(get.cardtag(trigger.card,`yingbian_${tag}`)) continue; - if(j[0]=='heart'){ - if(!forced&&!hasYingBian.includes('add')){ - const {result}=await lib.yingbian.condition.complex.get('zhuzhan')(trigger); - if(result.bool){ - game.log(player,'触发了','#g【注傅】','为',trigger.card,'添加的应变条件(','#g'+get.translation(j[0]),')'); - trigger.yingbian_addTarget=true; - player.addTempSkill('yingbian_changeTarget'); + const hasYingBian = trigger.temporaryYingbian || [], + map = get.info("fakezhufu").YingBianMap; + for (const j of list) { + player.storage.fakezhufu_effect[ + player.getStorage("fakezhufu_effect").indexOf(j) + ][1] = true; + const tag = map[j[0]][0], + eff = map[j[0]][1]; + if (get.cardtag(trigger.card, `yingbian_${tag}`)) continue; + if (j[0] == "heart") { + if (!forced && !hasYingBian.includes("add")) { + const { result } = await lib.yingbian.condition.complex.get( + "zhuzhan" + )(trigger); + if (result.bool) { + game.log( + player, + "触发了", + "#g【注傅】", + "为", + trigger.card, + "添加的应变条件(", + "#g" + get.translation(j[0]), + ")" + ); + trigger.yingbian_addTarget = true; + player.addTempSkill("yingbian_changeTarget"); } - } - else{ - if(!forced){ - game.log(player,'触发了','#g【注傅】','为',trigger.card,'添加的应变条件(','#g'+get.translation(j[0]),')'); + } else { + if (!forced) { + game.log( + player, + "触发了", + "#g【注傅】", + "为", + trigger.card, + "添加的应变条件(", + "#g" + get.translation(j[0]), + ")" + ); } - trigger.yingbian_addTarget=true; - player.addTempSkill('yingbian_changeTarget'); + trigger.yingbian_addTarget = true; + player.addTempSkill("yingbian_changeTarget"); } - } - else{ - const goon=(hasYingBian.includes(eff)||lib.yingbian.condition.simple.get(tag)(trigger)); - if(!forced&&goon){ - player.popup('yingbian_force_tag',lib.yingbian.condition.color.get(eff)); - game.log(player,'触发了','#g【注傅】','为',trigger.card,'添加的应变条件(','#g'+get.translation(j[0]),')'); + } else { + const goon = + hasYingBian.includes(eff) || + lib.yingbian.condition.simple.get(tag)(trigger); + if (!forced && goon) { + player.popup( + "yingbian_force_tag", + lib.yingbian.condition.color.get(eff) + ); + game.log( + player, + "触发了", + "#g【注傅】", + "为", + trigger.card, + "添加的应变条件(", + "#g" + get.translation(j[0]), + ")" + ); } - if(forced||goon) await game.yingbianEffect(trigger,lib.yingbian.effect.get(eff)); + if (forced || goon) + await game.yingbianEffect(trigger, lib.yingbian.effect.get(eff)); } } }, }, }, - YingBianMap:{ - 'heart':['zhuzhan','add'], - 'diamond':['fujia','hit'], - 'spade':['canqu','draw'], - 'club':['kongchao','damage'], + YingBianMap: { + heart: ["zhuzhan", "add"], + diamond: ["fujia", "hit"], + spade: ["canqu", "draw"], + club: ["kongchao", "damage"], }, - getMaxUseTarget(card,player){ + getMaxUseTarget(card, player) { let range; - const select=get.copy(get.info(card).selectTarget); - if(select==undefined) range=[1,1]; - else if(typeof select=='number') range=[select,select]; - else if(get.itemtype(select)=='select') range=select; - else if(typeof select=='function') range=select(card,player); - game.checkMod(card,player,range,'selectTarget',player); + const select = get.copy(get.info(card).selectTarget); + if (select == undefined) range = [1, 1]; + else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); return range; }, }, - fakeguishu:{ - inherit:'hmkguishu', - usable:1, + fakeguishu: { + inherit: "hmkguishu", + usable: 1, }, - fakeyuanyu:{ - inherit:'hmkyuanyu', - filter(event,player){ - if(event.num<=0||!event.source) return false; + fakeyuanyu: { + inherit: "hmkyuanyu", + filter(event, player) { + if (event.num <= 0 || !event.source) return false; return !event.source.inRange(player); }, - content(){ + content() { trigger.num--; }, - ai:{ - effect:{ - target(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(player.inRange(target)) return; - const num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; - return 'zeroplayertarget'; + ai: { + effect: { + target(card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (player.inRange(target)) return; + const num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; + return "zeroplayertarget"; } }, }, }, }, - fakemibei:{ - audio:'mibei', - trigger:{player:'phaseZhunbeiBegin'}, - filter(event,player){ + fakemibei: { + audio: "mibei", + trigger: { player: "phaseZhunbeiBegin" }, + filter(event, player) { return !player.isMaxHandcard(); }, - async cost(event,trigger,player){ - const filterTarget=(card,player,target)=>{ - return target!=player&&target.isMaxHandcard(); - },targetx=game.filterPlayer(current=>filterTarget(null,player,current)); - if(targetx.length==1) event.result={bool:true,targets:targetx}; - else event.result=await player.chooseTarget(filterTarget,true) - .set('prompt2',lib.translate.fakemibei_info) - .set('prompt','请选择【秘备】的目标').set('ai',target=>{ - const player=get.event('player'); - return get.attitude(player,target); - }).forResult(); - }, - preHidden:true, - async content(event,trigger,player){ - const target=event.targets[0]; - const {result:{junling,targets}}=await target.chooseJunlingFor(player); - const {result:{index}}=await player.chooseJunlingControl(target,junling,targets).set('prompt','秘备:是否执行军令?'); - if(index==0) await player.carryOutJunling(target,junling,targets); - }, - group:'fakemibei_junling', - subSkill:{ - junling:{ - audio:'mibei', - trigger:{player:['carryOutJunlingEnd','chooseJunlingControlEnd']}, - filter(event,player){ - if(event.name=='carryOutJunling'){ - return event.source.countCards('h')>player.countCards('h'); - } - return event.result.index==1&&player.countCards('h'); + async cost(event, trigger, player) { + const filterTarget = (card, player, target) => { + return target != player && target.isMaxHandcard(); }, - forced:true, - locked:false, - async content(event,trigger,player){ - if(trigger.name=='carryOutJunling'){ - const num=Math.min(5,trigger.source.countCards('h')-player.countCards('h')); - await player.draw(num); + targetx = game.filterPlayer((current) => filterTarget(null, player, current)); + if (targetx.length == 1) event.result = { bool: true, targets: targetx }; + else + event.result = await player + .chooseTarget(filterTarget, true) + .set("prompt2", lib.translate.fakemibei_info) + .set("prompt", "请选择【秘备】的目标") + .set("ai", (target) => { + const player = get.event("player"); + return get.attitude(player, target); + }) + .forResult(); + }, + preHidden: true, + async content(event, trigger, player) { + const target = event.targets[0]; + const { + result: { junling, targets }, + } = await target.chooseJunlingFor(player); + const { + result: { index }, + } = await player + .chooseJunlingControl(target, junling, targets) + .set("prompt", "秘备:是否执行军令?"); + if (index == 0) await player.carryOutJunling(target, junling, targets); + }, + group: "fakemibei_junling", + subSkill: { + junling: { + audio: "mibei", + trigger: { player: ["carryOutJunlingEnd", "chooseJunlingControlEnd"] }, + filter(event, player) { + if (event.name == "carryOutJunling") { + return event.source.countCards("h") > player.countCards("h"); } - else{ - const {result:{bool,cards}}=await player.chooseCard('秘备:展示一至三张手牌,本回合你可以将其中一张牌当作另一张基本牌或普通锦囊牌使用一次',[1,3],true).set('ai',card=>{ - const player=get.event('player'),goon=_status.currentPhase==player; - if(goon) return player.getUseValue(card)/get.value(card); - return get.value(card); - }); - if(bool){ - await player.showCards(cards,get.translation(player)+'发动了【秘备】'); - player.addGaintag(cards,'fakemibei_effect'); - player.addTempSkill('fakemibei_effect'); + return event.result.index == 1 && player.countCards("h"); + }, + forced: true, + locked: false, + async content(event, trigger, player) { + if (trigger.name == "carryOutJunling") { + const num = Math.min( + 5, + trigger.source.countCards("h") - player.countCards("h") + ); + await player.draw(num); + } else { + const { + result: { bool, cards }, + } = await player + .chooseCard( + "秘备:展示一至三张手牌,本回合你可以将其中一张牌当作另一张基本牌或普通锦囊牌使用一次", + [1, 3], + true + ) + .set("ai", (card) => { + const player = get.event("player"), + goon = _status.currentPhase == player; + if (goon) return player.getUseValue(card) / get.value(card); + return get.value(card); + }); + if (bool) { + await player.showCards(cards, get.translation(player) + "发动了【秘备】"); + player.addGaintag(cards, "fakemibei_effect"); + player.addTempSkill("fakemibei_effect"); } } }, }, - effect:{ - charlotte:true, - onremove(player){ - player.removeGaintag('fakemibei_effect'); + effect: { + charlotte: true, + onremove(player) { + player.removeGaintag("fakemibei_effect"); }, - hiddenCard(player,name){ - const cards=player.getCards('h',card=>card.hasGaintag('fakemibei_effect')); - if(cards.length<2) return false; - const type=get.type(name); - if(type!='basic'&&type!='trick') return false; - return cards.slice().map(i=>i.name).includes(name); + hiddenCard(player, name) { + const cards = player.getCards("h", (card) => card.hasGaintag("fakemibei_effect")); + if (cards.length < 2) return false; + const type = get.type(name); + if (type != "basic" && type != "trick") return false; + return cards + .slice() + .map((i) => i.name) + .includes(name); }, - audio:'mibei', - enable:'phaseUse', - chooseButton:{ - dialog(event,player){ - const list=player.getCards('h',card=>{ - const type=get.type(card); - if(type!='basic'&&type!='trick') return false; - return card.hasGaintag('fakemibei_effect'); - }).sort((a,b)=>{ - return lib.inpile.indexOf(a.name)+get.natureList(a,false).reduce((sum,nature)=>{ - return sum+lib.inpile_nature.indexOf(nature); - },0)-lib.inpile.indexOf(b.name)-get.natureList(b,false).reduce((sum,nature)=>{ - return sum+lib.inpile_nature.indexOf(nature); - },0); - }).slice().map(card=>[get.translation(get.type(card)),'',card.name,card.nature]); - return ui.create.dialog('秘备',[list,'vcard']); + audio: "mibei", + enable: "phaseUse", + chooseButton: { + dialog(event, player) { + const list = player + .getCards("h", (card) => { + const type = get.type(card); + if (type != "basic" && type != "trick") return false; + return card.hasGaintag("fakemibei_effect"); + }) + .sort((a, b) => { + return ( + lib.inpile.indexOf(a.name) + + get.natureList(a, false).reduce((sum, nature) => { + return sum + lib.inpile_nature.indexOf(nature); + }, 0) - + lib.inpile.indexOf(b.name) - + get.natureList(b, false).reduce((sum, nature) => { + return sum + lib.inpile_nature.indexOf(nature); + }, 0) + ); + }) + .slice() + .map((card) => [ + get.translation(get.type(card)), + "", + card.name, + card.nature, + ]); + return ui.create.dialog("秘备", [list, "vcard"]); }, - filter(button,player){ - const event=get.event().getParent(); - return event.filterCard({name:button.link[2],nature:button.link[3]},player,event); + filter(button, player) { + const event = get.event().getParent(); + return event.filterCard( + { name: button.link[2], nature: button.link[3] }, + player, + event + ); }, - check(button){ - const player=get.event('player'); - const card={name:button.link[2],nature:button.link[3]}; - if(player.countCards('hes',cardx=>cardx.name==card.name)) return 0; + check(button) { + const player = get.event("player"); + const card = { name: button.link[2], nature: button.link[3] }; + if (player.countCards("hes", (cardx) => cardx.name == card.name)) return 0; return player.getUseValue(card); }, - backup(links,player){ + backup(links, player) { return { - audio:'chengshang', - filterCard(card,player){ - const cardx=get.info('fakemibei_effect_backup').viewAs; - if(cardx.name==card.name&&cardx.nature==card.nature) return false; - return card.hasGaintag('fakemibei_effect'); + audio: "chengshang", + filterCard(card, player) { + const cardx = get.info("fakemibei_effect_backup").viewAs; + if (cardx.name == card.name && cardx.nature == card.nature) + return false; + return card.hasGaintag("fakemibei_effect"); }, - position:'h', - popname:true, - precontent(){ - player.logSkill('fakemibei_effect'); + position: "h", + popname: true, + precontent() { + player.logSkill("fakemibei_effect"); delete event.result.skill; - player.tempBanSkill('fakemibei_effect',null,false); + player.tempBanSkill("fakemibei_effect", null, false); }, - viewAs:{ - name:links[0][2], - nature:links[0][3], + viewAs: { + name: links[0][2], + nature: links[0][3], }, - } + }; }, - prompt(links,player){ - return '将一张“秘备”牌当作'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用'; + prompt(links, player) { + return ( + "将一张“秘备”牌当作" + + (get.translation(links[0][3]) || "") + + get.translation(links[0][2]) + + "使用" + ); }, }, }, }, }, - fakeqizhi:{ - audio:'qizhi', - inherit:'qizhi', - trigger:{player:'useCard1'}, - filter(event,player){ - if(!event.targets||!event.targets.length) return false; - if(_status.currentPhase!=player) return false; - if(get.type(event.card)=='equip') return false; - return game.hasPlayer(target=>!event.targets.includes(target)&&target.countCards('he')>0); + fakeqizhi: { + audio: "qizhi", + inherit: "qizhi", + trigger: { player: "useCard1" }, + filter(event, player) { + if (!event.targets || !event.targets.length) return false; + if (_status.currentPhase != player) return false; + if (get.type(event.card) == "equip") return false; + return game.hasPlayer( + (target) => !event.targets.includes(target) && target.countCards("he") > 0 + ); }, - direct:false, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt2('fakeqizhi'),(card,player,target)=>{ - return !get.event().getTrigger().targets.includes(target)&&target.countCards('he')>0; - }).set('ai',target=>{ - const player=get.event('player'); - if(target==player) return 2; - if(get.attitude(player,target)<=0) return 1; - return 0.5; - }).forResult(); + direct: false, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt2("fakeqizhi"), (card, player, target) => { + return ( + !get.event().getTrigger().targets.includes(target) && + target.countCards("he") > 0 + ); + }) + .set("ai", (target) => { + const player = get.event("player"); + if (target == player) return 2; + if (get.attitude(player, target) <= 0) return 1; + return 0.5; + }) + .forResult(); }, - async content(event,trigger,player){ - const target=event.targets[0]; - const {result:{bool,cards}}=await player.discardPlayerCard(target,'he',true); - if(bool){ + async content(event, trigger, player) { + const target = event.targets[0]; + const { + result: { bool, cards }, + } = await player.discardPlayerCard(target, "he", true); + if (bool) { await target.draw(); - if(cards.some(i=>get.suit(i,target)==get.suit(trigger.card))){ - trigger.forceYingbian=true; + if (cards.some((i) => get.suit(i, target) == get.suit(trigger.card))) { + trigger.forceYingbian = true; } } }, }, - fakejinqu:{ - audio:'jinqu', - trigger:{player:'phaseJieshuBegin'}, - check(event,player){ - return player.getHistory('useSkill',evt=>{ - return evt.skill=='fakeqizhi'; - }).length>=player.countCards('h'); + fakejinqu: { + audio: "jinqu", + trigger: { player: "phaseJieshuBegin" }, + check(event, player) { + return ( + player.getHistory("useSkill", (evt) => { + return evt.skill == "fakeqizhi"; + }).length >= player.countCards("h") + ); }, - prompt2(event,player){ - const num=player.getHistory('useSkill',evt=>evt.skill=='fakeqizhi').length; - return '摸两张牌,然后将手牌弃置至'+get.cnNumber(num)+'张'; + prompt2(event, player) { + const num = player.getHistory("useSkill", (evt) => evt.skill == "fakeqizhi").length; + return "摸两张牌,然后将手牌弃置至" + get.cnNumber(num) + "张"; }, - content(){ - 'step 0' + content() { + "step 0"; player.draw(2); - 'step 1' - var dh=player.countCards('h')-player.getHistory('useSkill',evt=>{ - return evt.skill=='fakeqizhi'; - }).length; - if(dh>0) player.chooseToDiscard(dh,true); + "step 1"; + var dh = + player.countCards("h") - + player.getHistory("useSkill", (evt) => { + return evt.skill == "fakeqizhi"; + }).length; + if (dh > 0) player.chooseToDiscard(dh, true); }, - ai:{combo:'fakeqizhi'}, + ai: { combo: "fakeqizhi" }, }, - fakejuzhan:{ - zhuanhuanji:true, - locked:false, - marktext:'☯', - intro:{ - content(storage){ - if(storage) return '当你使用【杀】指定目标后,你可以获得其X张牌,然后若你的武将牌均明置,则其可以暗置此武将牌,且你本回合不能明置此武将牌(X为你已损失的体力值且至少为1)'; - return '当你成为【杀】的目标后,你可以与其各摸X张牌,然后其武将牌均明置,则你可以暗置其一张武将牌,且其本回合不能明置此武将牌(X为其已损失的体力值且至少为1)'; + fakejuzhan: { + zhuanhuanji: true, + locked: false, + marktext: "☯", + intro: { + content(storage) { + if (storage) + return "当你使用【杀】指定目标后,你可以获得其X张牌,然后若你的武将牌均明置,则其可以暗置此武将牌,且你本回合不能明置此武将牌(X为你已损失的体力值且至少为1)"; + return "当你成为【杀】的目标后,你可以与其各摸X张牌,然后其武将牌均明置,则你可以暗置其一张武将牌,且其本回合不能明置此武将牌(X为其已损失的体力值且至少为1)"; }, }, - audio:'nzry_juzhan_1', - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + audio: "nzry_juzhan_1", + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter(event,player){ - if(event.card.name!='sha') return false; - const storage=player.storage.fakejuzhan; - if((event.player==player)!=Boolean(storage)) return false; - if(storage&&!event.target.countCards('he')) return false; + filter(event, player) { + if (event.card.name != "sha") return false; + const storage = player.storage.fakejuzhan; + if ((event.player == player) != Boolean(storage)) return false; + if (storage && !event.target.countCards("he")) return false; return true; }, - logTarget(event,player){ - const storage=player.storage.fakejuzhan; - return event[Boolean(storage)?'target':'player']; + logTarget(event, player) { + const storage = player.storage.fakejuzhan; + return event[Boolean(storage) ? "target" : "player"]; }, - async content(event,trigger,player){ - const storage=player.storage.fakejuzhan; - player.changeZhuanhuanji('fakejuzhan'); - const target=trigger[Boolean(storage)?'target':'player']; - const num=Math.max(target.getDamagedHp(),1); - if(!storage){ - await player.draw(num,'nodelay'); + async content(event, trigger, player) { + const storage = player.storage.fakejuzhan; + player.changeZhuanhuanji("fakejuzhan"); + const target = trigger[Boolean(storage) ? "target" : "player"]; + const num = Math.max(target.getDamagedHp(), 1); + if (!storage) { + await player.draw(num, "nodelay"); await target.draw(num); - if(!target.isUnseen(2)){ - const {result:{bool,links}}=await player.chooseButton([ - '拒战:是否暗置'+get.translation(target)+'的一张武将牌?', - '
                        '+get.translation(target)+'的武将牌
                        ', - [[target.name1,target.name2],'character'], - ]).set('filterButton',button=>!get.is.jun(button.link)); - if(bool){ - await target.hideCharacter(target.name1==links[0]?0:1); - target.addTempSkill('donggui2'); + if (!target.isUnseen(2)) { + const { + result: { bool, links }, + } = await player + .chooseButton([ + "拒战:是否暗置" + get.translation(target) + "的一张武将牌?", + '
                        ' + get.translation(target) + "的武将牌
                        ", + [[target.name1, target.name2], "character"], + ]) + .set("filterButton", (button) => !get.is.jun(button.link)); + if (bool) { + await target.hideCharacter(target.name1 == links[0] ? 0 : 1); + target.addTempSkill("donggui2"); } } - } - else{ - await player.gainPlayerCard(target,num,'he',true); - const names=[player.name1,player.name2].filter(i=>{ - return get.character(i,3).includes('fakejuzhan'); + } else { + await player.gainPlayerCard(target, num, "he", true); + const names = [player.name1, player.name2].filter((i) => { + return get.character(i, 3).includes("fakejuzhan"); }); - if(!player.isUnseen(2)&&names.length){ - const {result:{bool,links}}=await target.chooseBool('拒战:是否暗置'+get.translation(player)+'的'+(names.includes(player.name1)?'主将':'')+(names.length>1?'和':'')+(names.includes(player.name2)?'副将':'')+'?'); - if(bool){ - if(names.includes(player.name1)) await player.hideCharacter(0); - if(names.includes(player.name2)) await player.hideCharacter(1); - player.addTempSkill('donggui2'); + if (!player.isUnseen(2) && names.length) { + const { + result: { bool, links }, + } = await target.chooseBool( + "拒战:是否暗置" + + get.translation(player) + + "的" + + (names.includes(player.name1) ? "主将" : "") + + (names.length > 1 ? "和" : "") + + (names.includes(player.name2) ? "副将" : "") + + "?" + ); + if (bool) { + if (names.includes(player.name1)) await player.hideCharacter(0); + if (names.includes(player.name2)) await player.hideCharacter(1); + player.addTempSkill("donggui2"); } } } }, - group:'fakejuzhan_mark', - subSkill:{ - mark:{ - charlotte:true, - trigger:{player:['hideCharacterEnd','showCharacterEnd']}, - filter(event,player){ - return get.character(event[event.name=='hideCharacter'?'toHide':'toShow'],3).includes('fakejuzhan'); + group: "fakejuzhan_mark", + subSkill: { + mark: { + charlotte: true, + trigger: { player: ["hideCharacterEnd", "showCharacterEnd"] }, + filter(event, player) { + return get + .character(event[event.name == "hideCharacter" ? "toHide" : "toShow"], 3) + .includes("fakejuzhan"); }, - forced:true, - popup:false, - firstDo:true, - content(){ - player[(trigger.name=='hideCharacter'?'un':'')+'markSkill']('fakejuzhan'); + forced: true, + popup: false, + firstDo: true, + content() { + player[(trigger.name == "hideCharacter" ? "un" : "") + "markSkill"]("fakejuzhan"); }, }, }, }, - fakedanshou:{ - audio:'mobiledanshou', - trigger:{global:'phaseZhunbeiBegin'}, - filter(event,player){ - return ['h','e','j'].some(pos=>player.getCards(pos).every(card=>lib.filter.cardDiscardable(card,player))); + fakedanshou: { + audio: "mobiledanshou", + trigger: { global: "phaseZhunbeiBegin" }, + filter(event, player) { + return ["h", "e", "j"].some((pos) => + player.getCards(pos).every((card) => lib.filter.cardDiscardable(card, player)) + ); }, - async cost(event,trigger,player){ - let list=[],map={'h':'手牌区','e':'装备区','j':'判定区'}; - list.addArray(['h','e','j'].filter(pos=>{ - return player.getCards(pos).every(card=>lib.filter.cardDiscardable(card,player)); - }).map(i=>map[i])); - list.push('cancel2'); - const {result:{control}}=await player.chooseControl(list).set('prompt',get.prompt2('fakedanshou',trigger.player)).set('ai',()=>{ - const player=get.event().player,controls=get.event().controls.slice(); - if(controls.includes('判定区')) return '判定区'; - if(controls.includes('装备区')&&player.countCards('e')<3) return '装备区'; - if(controls.includes('手牌区')&&player.countCards('e')<5) return '手牌区'; - return 'cancel2'; - }); - event.result={bool:(control!='cancel2'),cost_data:control}; + async cost(event, trigger, player) { + let list = [], + map = { h: "手牌区", e: "装备区", j: "判定区" }; + list.addArray( + ["h", "e", "j"] + .filter((pos) => { + return player + .getCards(pos) + .every((card) => lib.filter.cardDiscardable(card, player)); + }) + .map((i) => map[i]) + ); + list.push("cancel2"); + const { + result: { control }, + } = await player + .chooseControl(list) + .set("prompt", get.prompt2("fakedanshou", trigger.player)) + .set("ai", () => { + const player = get.event().player, + controls = get.event().controls.slice(); + if (controls.includes("判定区")) return "判定区"; + if (controls.includes("装备区") && player.countCards("e") < 3) return "装备区"; + if (controls.includes("手牌区") && player.countCards("e") < 5) return "手牌区"; + return "cancel2"; + }); + event.result = { bool: control != "cancel2", cost_data: control }; }, - round:1, - logTarget:'player', - async content(event,trigger,player){ + round: 1, + logTarget: "player", + async content(event, trigger, player) { player.popup(event.cost_data); - await player.discard(player.getCards({'手牌区':'h','装备区':'e','判定区':'j'}[event.cost_data])); - player.addTempSkill('fakedanshou_effect'); - player.addMark('fakedanshou_effect',1,false); + await player.discard( + player.getCards({ 手牌区: "h", 装备区: "e", 判定区: "j" }[event.cost_data]) + ); + player.addTempSkill("fakedanshou_effect"); + player.addMark("fakedanshou_effect", 1, false); }, - subSkill:{ - effect:{ - charlotte:true, - onremove(player){ + subSkill: { + effect: { + charlotte: true, + onremove(player) { delete player.storage.fakedanshou_effect; delete player._fakedanshou_effect; }, - audio:'mobiledanshou', - trigger:{global:['phaseJudgeBegin','phaseDrawBegin','phaseUseBegin','phaseDiscardBegin']}, - async cost(event,trigger,player){ - const {result:{control}}=await player.chooseControl('摸牌','增加摸牌数').set('prompt','胆守:请选择一项').set('ai',()=>{ - const player=get.event().player,trigger=get.event().getTrigger(); - if(trigger.name=='phaseJudge') return '增加摸牌数'; - if(trigger.name=='phaseDiscard') return '摸牌'; - if(trigger.name=='phaseDraw'){ - if(get.damageEffect(trigger.player,player,player)>0){ - player._fakedanshou_effect=true; - return '增加摸牌数'; - } - } - return player._fakedanshou_effect?'增加摸牌数':'摸牌'; - }); - event.result={bool:true,cost_data:control}; + audio: "mobiledanshou", + trigger: { + global: [ + "phaseJudgeBegin", + "phaseDrawBegin", + "phaseUseBegin", + "phaseDiscardBegin", + ], }, - logTarget:'player', - async content(event,trigger,player){ - if(event.cost_data=='增加摸牌数'){ - player.addMark('fakedanshou_effect',1,false); - } - else{ - const num=player.countMark('fakedanshou_effect'); + async cost(event, trigger, player) { + const { + result: { control }, + } = await player + .chooseControl("摸牌", "增加摸牌数") + .set("prompt", "胆守:请选择一项") + .set("ai", () => { + const player = get.event().player, + trigger = get.event().getTrigger(); + if (trigger.name == "phaseJudge") return "增加摸牌数"; + if (trigger.name == "phaseDiscard") return "摸牌"; + if (trigger.name == "phaseDraw") { + if (get.damageEffect(trigger.player, player, player) > 0) { + player._fakedanshou_effect = true; + return "增加摸牌数"; + } + } + return player._fakedanshou_effect ? "增加摸牌数" : "摸牌"; + }); + event.result = { bool: true, cost_data: control }; + }, + logTarget: "player", + async content(event, trigger, player) { + if (event.cost_data == "增加摸牌数") { + player.addMark("fakedanshou_effect", 1, false); + } else { + const num = player.countMark("fakedanshou_effect"); await player.draw(num); - if(num>=4){ - const {result:{bool}}=await player.chooseBool('胆守:是否对'+get.translation(trigger.player)+'造成1点伤害?').set('choice',get.damageEffect(trigger.player,player,player)>0); - if(bool){ + if (num >= 4) { + const { + result: { bool }, + } = await player + .chooseBool( + "胆守:是否对" + get.translation(trigger.player) + "造成1点伤害?" + ) + .set("choice", get.damageEffect(trigger.player, player, player) > 0); + if (bool) { player.line(trigger.player); await trigger.player.damage(); } @@ -2665,872 +3867,1252 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, }, - fakexunxi:{ - trigger:{global:'showCharacterEnd'}, - filter(event,player){ - const card=new lib.element.VCard({name:'sha'}); - return event.player!=player&&event.player!=_status.currentPhase&&player.canUse(card,event.player,false); + fakexunxi: { + trigger: { global: "showCharacterEnd" }, + filter(event, player) { + const card = new lib.element.VCard({ name: "sha" }); + return ( + event.player != player && + event.player != _status.currentPhase && + player.canUse(card, event.player, false) + ); }, - check(event,player){ - const card=new lib.element.VCard({name:'sha'}); - return get.effect(event.player,card,player,player)>0; + check(event, player) { + const card = new lib.element.VCard({ name: "sha" }); + return get.effect(event.player, card, player, player) > 0; }, - logTarget:'player', - async content(event,trigger,player){ - const card=new lib.element.VCard({name:'sha'}); - await player.useCard(card,trigger.player,false); + logTarget: "player", + async content(event, trigger, player) { + const card = new lib.element.VCard({ name: "sha" }); + await player.useCard(card, trigger.player, false); }, }, - fakehuanjia:{ - trigger:{ - player:'useCardToPlayered', - target:'useCardToTargeted', + fakehuanjia: { + trigger: { + player: "useCardToPlayered", + target: "useCardToTargeted", }, - filter(event,player){ - if(event.card.name!='sha') return false; - if(event.target==player){ - if(player.getStorage('fakehuanjia_used').includes(2)) return false; + filter(event, player) { + if (event.card.name != "sha") return false; + if (event.target == player) { + if (player.getStorage("fakehuanjia_used").includes(2)) return false; return event.player.getEquips(2).length; } - if(event.targets.length!=1) return false; - if(player.getStorage('fakehuanjia_used').includes(1)) return false; + if (event.targets.length != 1) return false; + if (player.getStorage("fakehuanjia_used").includes(1)) return false; return event.target.getEquips(1).length; }, - logTarget(event,player){ - return event.target==player?event.player:event.target; + logTarget(event, player) { + return event.target == player ? event.player : event.target; }, - forced:true, - async content(event,trigger,player){ - player.addTempSkill('fakehuanjia_used'); - if(trigger.target==player){ - player.markAuto('fakehuanjia_used',[2]); - if(!player.getEquips(2).length&&player.hasEmptySlot(2)){ - player.addSkill('fakehuanjia_equip2'); - player.markAuto('fakehuanjia_equip2',[trigger.player]); - player.when({global:'phaseAfter',player:['equipEnd','disableEquipEnd','die']}) - .filter((evt,player)=>{ - if(evt.name=='phase'||evt.name=='die') return true; - if(evt.name=='discardEquip') return !player.hasEmptySlot(2); - return get.type(evt.card)=='equip2'; - }) - .then(()=>player.removeSkill('fakehuanjia_equip2')); - const cards=trigger.player.getEquips(2); - if(cards.length){ - const skills=cards.reduce((list,card)=>{ - if(get.info(card)&&get.info(card).skills) list.addArray(get.info(card).skills); + forced: true, + async content(event, trigger, player) { + player.addTempSkill("fakehuanjia_used"); + if (trigger.target == player) { + player.markAuto("fakehuanjia_used", [2]); + if (!player.getEquips(2).length && player.hasEmptySlot(2)) { + player.addSkill("fakehuanjia_equip2"); + player.markAuto("fakehuanjia_equip2", [trigger.player]); + player + .when({ + global: "phaseAfter", + player: ["equipEnd", "disableEquipEnd", "die"], + }) + .filter((evt, player) => { + if (evt.name == "phase" || evt.name == "die") return true; + if (evt.name == "discardEquip") return !player.hasEmptySlot(2); + return get.type(evt.card) == "equip2"; + }) + .then(() => player.removeSkill("fakehuanjia_equip2")); + const cards = trigger.player.getEquips(2); + if (cards.length) { + const skills = cards.reduce((list, card) => { + if (get.info(card) && get.info(card).skills) + list.addArray(get.info(card).skills); return list; - },[]); - if(skills.length) player.addAdditionalSkill('fakehuanjia_equip2',skills); + }, []); + if (skills.length) player.addAdditionalSkill("fakehuanjia_equip2", skills); } } - } - else{ - player.markAuto('fakehuanjia_used',[1]); - if(!player.getEquips(1).length&&player.hasEmptySlot(1)){ - player.addSkill('fakehuanjia_equip1'); - player.markAuto('fakehuanjia_equip1',[trigger.target]); - player.when({global:'phaseAfter',player:['equipEnd','disableEquipEnd','die']}) - .filter((evt,player)=>{ - if(evt.name=='phase'||evt.name=='die') return true; - if(evt.name=='discardEquip') return !player.hasEmptySlot(1); - return get.type(evt.card)=='equip1'; - }) - .then(()=>player.removeSkill('fakehuanjia_equip1')); - const cards=trigger.target.getEquips(1); - if(cards.length){ - const skills=cards.reduce((list,card)=>{ - if(get.info(card)&&get.info(card).skills) list.addArray(get.info(card).skills); + } else { + player.markAuto("fakehuanjia_used", [1]); + if (!player.getEquips(1).length && player.hasEmptySlot(1)) { + player.addSkill("fakehuanjia_equip1"); + player.markAuto("fakehuanjia_equip1", [trigger.target]); + player + .when({ + global: "phaseAfter", + player: ["equipEnd", "disableEquipEnd", "die"], + }) + .filter((evt, player) => { + if (evt.name == "phase" || evt.name == "die") return true; + if (evt.name == "discardEquip") return !player.hasEmptySlot(1); + return get.type(evt.card) == "equip1"; + }) + .then(() => player.removeSkill("fakehuanjia_equip1")); + const cards = trigger.target.getEquips(1); + if (cards.length) { + const skills = cards.reduce((list, card) => { + if (get.info(card) && get.info(card).skills) + list.addArray(get.info(card).skills); return list; - },[]); - if(skills.length) player.addAdditionalSkill('fakehuanjia_equip1',skills); + }, []); + if (skills.length) player.addAdditionalSkill("fakehuanjia_equip1", skills); } } } }, - subSkill:{ - used:{ - charlotte:true, - onremove:true, + subSkill: { + used: { + charlotte: true, + onremove: true, }, - equip1:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'攻', - mod:{ - attackRange(player,num){ - const targets=player.getStorage('fakehuanjia_equip1').filter(i=>i.isIn()); - return num+targets.reduce((sum,target)=>{ - return sum+target.getEquipRange(); - },0); + equip1: { + charlotte: true, + onremove: true, + mark: true, + marktext: "攻", + mod: { + attackRange(player, num) { + const targets = player + .getStorage("fakehuanjia_equip1") + .filter((i) => i.isIn()); + return ( + num + + targets.reduce((sum, target) => { + return sum + target.getEquipRange(); + }, 0) + ); }, }, - intro:{content:'视为装备$的武器'}, - trigger:{global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter','die']}, - filter(event,player){ - return game.hasPlayer(target=>{ - if(!player.getStorage('fakehuanjia_equip1').includes(target)) return false; - if(event.name=='die'&&event.player==target) return true; - if(event.name=='equip'&&event.player==target) return get.subtype(event.card)=='equip1'; - if(event.getl){ - const evt=event.getl(target); - return evt&&evt.player==target&&evt.es&&evt.es.some(i=>get.subtype(i)=='equip1'); + intro: { content: "视为装备$的武器" }, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + "die", + ], + }, + filter(event, player) { + return game.hasPlayer((target) => { + if (!player.getStorage("fakehuanjia_equip1").includes(target)) return false; + if (event.name == "die" && event.player == target) return true; + if (event.name == "equip" && event.player == target) + return get.subtype(event.card) == "equip1"; + if (event.getl) { + const evt = event.getl(target); + return ( + evt && + evt.player == target && + evt.es && + evt.es.some((i) => get.subtype(i) == "equip1") + ); } return false; }); }, - forced:true, - popup:false, - content(){ - const targets=player.getStorage('fakehuanjia_equip1').filter(i=>i.isIn()); - const skills=targets.reduce((list,target)=>{ - const cards=target.getEquips(1); - if(cards.length){ - const skills=cards.reduce((listx,card)=>{ - if(get.info(card)&&get.info(card).skills) listx.addArray(get.info(card).skills); + forced: true, + popup: false, + content() { + const targets = player.getStorage("fakehuanjia_equip1").filter((i) => i.isIn()); + const skills = targets.reduce((list, target) => { + const cards = target.getEquips(1); + if (cards.length) { + const skills = cards.reduce((listx, card) => { + if (get.info(card) && get.info(card).skills) + listx.addArray(get.info(card).skills); return listx; - },[]); - if(skills.length) list.addArray(skills); + }, []); + if (skills.length) list.addArray(skills); } return list; - },[]); - player.addAdditionalSkill('fakehuanjia_equip1',skills); + }, []); + player.addAdditionalSkill("fakehuanjia_equip1", skills); }, }, - equip2:{ - charlotte:true, - onremove:true, - mark:true, - marktext:'防', - intro:{content:'视为装备$的防具'}, - trigger:{global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter','die']}, - filter(event,player){ - return game.hasPlayer(target=>{ - if(!player.getStorage('fakehuanjia_equip2').includes(target)) return false; - if(event.name=='die'&&event.player==target) return true; - if(event.name=='equip'&&event.player==target) return get.subtype(event.card)=='equip2'; - if(event.getl){ - const evt=event.getl(target); - return evt&&evt.player==target&&evt.es&&evt.es.some(i=>get.subtype(i)=='equip2'); + equip2: { + charlotte: true, + onremove: true, + mark: true, + marktext: "防", + intro: { content: "视为装备$的防具" }, + trigger: { + global: [ + "loseAfter", + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + "die", + ], + }, + filter(event, player) { + return game.hasPlayer((target) => { + if (!player.getStorage("fakehuanjia_equip2").includes(target)) return false; + if (event.name == "die" && event.player == target) return true; + if (event.name == "equip" && event.player == target) + return get.subtype(event.card) == "equip2"; + if (event.getl) { + const evt = event.getl(target); + return ( + evt && + evt.player == target && + evt.es && + evt.es.some((i) => get.subtype(i) == "equip2") + ); } return false; }); }, - forced:true, - popup:false, - content(){ - const targets=player.getStorage('fakehuanjia_equip2').filter(i=>i.isIn()); - const skills=targets.reduce((list,target)=>{ - const cards=target.getEquips(2); - if(cards.length){ - const skills=cards.reduce((listx,card)=>{ - if(get.info(card)&&get.info(card).skills) listx.addArray(get.info(card).skills); + forced: true, + popup: false, + content() { + const targets = player.getStorage("fakehuanjia_equip2").filter((i) => i.isIn()); + const skills = targets.reduce((list, target) => { + const cards = target.getEquips(2); + if (cards.length) { + const skills = cards.reduce((listx, card) => { + if (get.info(card) && get.info(card).skills) + listx.addArray(get.info(card).skills); return listx; - },[]); - if(skills.length) list.addArray(skills); + }, []); + if (skills.length) list.addArray(skills); } return list; - },[]); - player.addAdditionalSkill('fakehuanjia_equip2',skills); + }, []); + player.addAdditionalSkill("fakehuanjia_equip2", skills); }, }, }, }, - fakexiongshu:{ - audio:'xiongshu', - trigger:{global:'useCardToPlayered'}, - filter(event,player){ - if(!event.isFirstTarget) return false; - if(event.player==player&&game.countPlayer()<2) return false; - if(event.player!=player&&!player.countDiscardableCards(player,'he')) return false; - return event.card.name=='sha'||(get.type(event.card)=='trick'&&get.tag(event.card,'damage')); + fakexiongshu: { + audio: "xiongshu", + trigger: { global: "useCardToPlayered" }, + filter(event, player) { + if (!event.isFirstTarget) return false; + if (event.player == player && game.countPlayer() < 2) return false; + if (event.player != player && !player.countDiscardableCards(player, "he")) return false; + return ( + event.card.name == "sha" || + (get.type(event.card) == "trick" && get.tag(event.card, "damage")) + ); }, - check(event,player){ - if(event.player==player){ - if(event.targets.some(i=>i.hasSkill('gzduanchang'))) return true; - return !event.targets.some(i=>i.getHp()==1&&!i.hasSkill('gzbuqu')&&i.isEnemyOf(player)); + check(event, player) { + if (event.player == player) { + if (event.targets.some((i) => i.hasSkill("gzduanchang"))) return true; + return !event.targets.some( + (i) => i.getHp() == 1 && !i.hasSkill("gzbuqu") && i.isEnemyOf(player) + ); } - if(event.targets.some(i=>i.hasSkill('gzduanchang'))) return false; - return event.targets.some(i=>i.getHp()==1&&!i.hasSkill('gzbuqu')&&i.isEnemyOf(player)); + if (event.targets.some((i) => i.hasSkill("gzduanchang"))) return false; + return event.targets.some( + (i) => i.getHp() == 1 && !i.hasSkill("gzbuqu") && i.isEnemyOf(player) + ); }, - usable:1, - async content(event,trigger,player){ - if(trigger.player==player){ + usable: 1, + async content(event, trigger, player) { + if (trigger.player == player) { await player.draw(); - const {result:{bool,targets}}=await player.chooseTarget('令一名其他角色成为'+get.translation(trigger.card)+'的伤害来源',true,lib.filter.notMe).set('ai',target=>{ - const player=get.event('player'),targets=get.event().getTrigger().targets; - const goon=(player.hasSkill('fakejianhui')&&targets.some(i=>i!=target&&i.isFriendOf(target))); - return targets.reduce((sum,i)=>sum+get.damageEffect(i,target,player),0)*(goon?3:1); - }); - if(bool){ - const target=targets[0]; + const { + result: { bool, targets }, + } = await player + .chooseTarget( + "令一名其他角色成为" + get.translation(trigger.card) + "的伤害来源", + true, + lib.filter.notMe + ) + .set("ai", (target) => { + const player = get.event("player"), + targets = get.event().getTrigger().targets; + const goon = + player.hasSkill("fakejianhui") && + targets.some((i) => i != target && i.isFriendOf(target)); + return ( + targets.reduce((sum, i) => sum + get.damageEffect(i, target, player), 0) * + (goon ? 3 : 1) + ); + }); + if (bool) { + const target = targets[0]; player.line(target); - game.log(target,'成为了',trigger.card,'的伤害来源'); - trigger.getParent().customArgs.default.customSource=target; + game.log(target, "成为了", trigger.card, "的伤害来源"); + trigger.getParent().customArgs.default.customSource = target; } - } - else{ - await player.chooseToDiscard('he',true); - game.log(player,'成为了',trigger.card,'的伤害来源'); - trigger.getParent().customArgs.default.customSource=player; + } else { + await player.chooseToDiscard("he", true); + game.log(player, "成为了", trigger.card, "的伤害来源"); + trigger.getParent().customArgs.default.customSource = player; } }, }, - fakejianhui:{ - audio:'jianhui', - trigger:{global:'damageSource'}, - filter(event,player){ - if(!event.source||!event.player||!event.source.isIn()||!event.player.isIn()||event.source==event.player) return false; - return event.source.isFriendOf(event.player)&&[event.source,event.player].some(target=>target.countCards('he')); + fakejianhui: { + audio: "jianhui", + trigger: { global: "damageSource" }, + filter(event, player) { + if ( + !event.source || + !event.player || + !event.source.isIn() || + !event.player.isIn() || + event.source == event.player + ) + return false; + return ( + event.source.isFriendOf(event.player) && + [event.source, event.player].some((target) => target.countCards("he")) + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt2('fakejianhui'),(card,player,target)=>{ - const trigger=get.event().getTrigger(); - if(!(trigger.source==target||trigger.player==target)) return false; - if(!ui.selected.targets.length) return true; - return target.countCards('he'); - },2).set('targetprompt',['摸牌','拆牌']).set('ai',target=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - const source=trigger.source,playerx=trigger.player; - const min=-Math.min(get.effect(source,{name:'draw'},player,player),get.effect(playerx,{name:'draw'},player,player)); - const max=Math.max(get.effect(source,{name:'guohe_copy'},player,player),get.effect(playerx,{name:'guohe_copy'},player,player)); - if(min>max) return 0; - if(!ui.selected.targets.length) return -1/Math.min(get.effect(target,{name:'draw'},player,player),-0.001); - return get.effect(target,{name:'guohe_copy'},player,player); - }).set('complexSelect',true).set('complexTarget',true).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt2("fakejianhui"), + (card, player, target) => { + const trigger = get.event().getTrigger(); + if (!(trigger.source == target || trigger.player == target)) return false; + if (!ui.selected.targets.length) return true; + return target.countCards("he"); + }, + 2 + ) + .set("targetprompt", ["摸牌", "拆牌"]) + .set("ai", (target) => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + const source = trigger.source, + playerx = trigger.player; + const min = -Math.min( + get.effect(source, { name: "draw" }, player, player), + get.effect(playerx, { name: "draw" }, player, player) + ); + const max = Math.max( + get.effect(source, { name: "guohe_copy" }, player, player), + get.effect(playerx, { name: "guohe_copy" }, player, player) + ); + if (min > max) return 0; + if (!ui.selected.targets.length) + return ( + -1 / + Math.min(get.effect(target, { name: "draw" }, player, player), -0.001) + ); + return get.effect(target, { name: "guohe_copy" }, player, player); + }) + .set("complexSelect", true) + .set("complexTarget", true) + .forResult(); }, - popup:false, - async content(event,trigger,player){ - player.logSkill('fakejianhui',event.targets,false); + popup: false, + async content(event, trigger, player) { + player.logSkill("fakejianhui", event.targets, false); player.line2(event.targets); await event.targets[0].draw(); - await player.discardPlayerCard(event.targets[1],'he',true); + await player.discardPlayerCard(event.targets[1], "he", true); }, }, - fakechongxin:{ - audio:'chongxin', - enable:'phaseUse', - filter(event,player){ - const card=new lib.element.VCard({name:'yiyi'}); - return lib.filter.targetEnabled2(card,player,player)&&game.hasPlayer(target=>{ - return lib.filter.targetEnabled2(card,player,target)&&target.isEnemyOf(player); - }); + fakechongxin: { + audio: "chongxin", + enable: "phaseUse", + filter(event, player) { + const card = new lib.element.VCard({ name: "yiyi" }); + return ( + lib.filter.targetEnabled2(card, player, player) && + game.hasPlayer((target) => { + return ( + lib.filter.targetEnabled2(card, player, target) && target.isEnemyOf(player) + ); + }) + ); }, - filterTarget(cardx,player,target){ - const card=new lib.element.VCard({name:'yiyi'}); - return lib.filter.targetEnabled2(card,player,target)&&target.isEnemyOf(player); + filterTarget(cardx, player, target) { + const card = new lib.element.VCard({ name: "yiyi" }); + return lib.filter.targetEnabled2(card, player, target) && target.isEnemyOf(player); }, - usable:1, - async content(event,trigger,player){ - const card=new lib.element.VCard({name:'yiyi'}); - await player.useCard(card,[player].concat(event.targets),false); + usable: 1, + async content(event, trigger, player) { + const card = new lib.element.VCard({ name: "yiyi" }); + await player.useCard(card, [player].concat(event.targets), false); }, - ai:{ - order(item,player){ - return get.order({name:'yiyi'},player)+0.1; + ai: { + order(item, player) { + return get.order({ name: "yiyi" }, player) + 0.1; }, - result:{ - target(player,target){ - const card=new lib.element.VCard({name:'yiyi'}); - const num=get.sgn(get.attitude(player,target)); - return num*(get.effect(player,card,player,player)-get.effect(target,card,player,player)); + result: { + target(player, target) { + const card = new lib.element.VCard({ name: "yiyi" }); + const num = get.sgn(get.attitude(player, target)); + return ( + num * + (get.effect(player, card, player, player) - + get.effect(target, card, player, player)) + ); }, }, }, }, - fakeweirong:{ - zhuanhuanji:true, - locked:false, - marktext:'☯', - intro:{ - content(storage){ - if(storage) return '出牌阶段,你可以摸X张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)'; - return '出牌阶段,你可以弃置X张牌,然后当你于本轮不因此法得到牌后,你摸一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)'; + fakeweirong: { + zhuanhuanji: true, + locked: false, + marktext: "☯", + intro: { + content(storage) { + if (storage) + return "出牌阶段,你可以摸X张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)"; + return "出牌阶段,你可以弃置X张牌,然后当你于本轮不因此法得到牌后,你摸一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)"; }, }, - audio:'weishu', - enable:'phaseUse', - filter(event,player){ - if(!get.info('fakeweirong').getNum(player)) return false; - const storage=player.storage.fakeweirong; - return storage||player.countCards('he',card=>lib.filter.cardDiscardable)>=get.info('fakeweirong').getNum(player); + audio: "weishu", + enable: "phaseUse", + filter(event, player) { + if (!get.info("fakeweirong").getNum(player)) return false; + const storage = player.storage.fakeweirong; + return ( + storage || + player.countCards("he", (card) => lib.filter.cardDiscardable) >= + get.info("fakeweirong").getNum(player) + ); }, - filterCard(card,player){ - return !Boolean(player.storage.fakeweirong)&&lib.filter.cardDiscardable(card,player); + filterCard(card, player) { + return !Boolean(player.storage.fakeweirong) && lib.filter.cardDiscardable(card, player); }, - selectCard(){ - const player=get.event('player'); - return player.storage.fakeweirong?-1:get.info('fakeweirong').getNum(player); + selectCard() { + const player = get.event("player"); + return player.storage.fakeweirong ? -1 : get.info("fakeweirong").getNum(player); }, - check(card){ - return 7.5-get.value(card); + check(card) { + return 7.5 - get.value(card); }, - prompt(){ - const player=get.event('player'); - const num=get.info('fakeweirong').getNum(player); - if(player.storage.fakeweirong) return '摸'+get.cnNumber(num)+'张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌'; - return '弃置'+get.cnNumber(num)+'张牌,然后当你于本轮不因此法得到牌后,你摸一张牌'; + prompt() { + const player = get.event("player"); + const num = get.info("fakeweirong").getNum(player); + if (player.storage.fakeweirong) + return ( + "摸" + get.cnNumber(num) + "张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌" + ); + return "弃置" + get.cnNumber(num) + "张牌,然后当你于本轮不因此法得到牌后,你摸一张牌"; }, - round:1, - async content(event,trigger,player){ - const storage=player.storage.fakeweirong; - player.changeZhuanhuanji('fakeweirong'); - if(storage) await player.draw(get.info('fakeweirong').getNum(player)); - player.addTempSkill('fakeweirong_'+(storage?'lose':'gain'),'roundStart'); + round: 1, + async content(event, trigger, player) { + const storage = player.storage.fakeweirong; + player.changeZhuanhuanji("fakeweirong"); + if (storage) await player.draw(get.info("fakeweirong").getNum(player)); + player.addTempSkill("fakeweirong_" + (storage ? "lose" : "gain"), "roundStart"); }, - ai:{ - order(item,player){ - const storage=player.storage.fakeweirong; - return storage?0.01:9; + ai: { + order(item, player) { + const storage = player.storage.fakeweirong; + return storage ? 0.01 : 9; }, - result:{player:1}, + result: { player: 1 }, }, - group:'fakeweirong_mark', - subSkill:{ - mark:{ - charlotte:true, - trigger:{player:['hideCharacterEnd','showCharacterEnd']}, - filter(event,player){ - return get.character(event[event.name=='hideCharacter'?'toHide':'toShow'],3).includes('fakeweirong'); + group: "fakeweirong_mark", + subSkill: { + mark: { + charlotte: true, + trigger: { player: ["hideCharacterEnd", "showCharacterEnd"] }, + filter(event, player) { + return get + .character(event[event.name == "hideCharacter" ? "toHide" : "toShow"], 3) + .includes("fakeweirong"); }, - forced:true, - popup:false, - firstDo:true, - content(){ - player[(trigger.name=='hideCharacter'?'un':'')+'markSkill']('fakeweirong'); + forced: true, + popup: false, + firstDo: true, + content() { + player[(trigger.name == "hideCharacter" ? "un" : "") + "markSkill"]( + "fakeweirong" + ); }, }, - gain:{ - charlotte:true, - mark:true, - marktext:'↑', - intro:{content:'不因此法得到牌后,你摸一张牌'}, - audio:'weishu', - trigger:{player:'gainAfter',global:'loseAsyncAfter'}, - filter(event,player){ - if(!event.getg||!event.getg(player).length) return false; - return event.getParent(2).name!='fakeweirong_gain'; + gain: { + charlotte: true, + mark: true, + marktext: "↑", + intro: { content: "不因此法得到牌后,你摸一张牌" }, + audio: "weishu", + trigger: { player: "gainAfter", global: "loseAsyncAfter" }, + filter(event, player) { + if (!event.getg || !event.getg(player).length) return false; + return event.getParent(2).name != "fakeweirong_gain"; }, - forced:true, - content(){ + forced: true, + content() { player.draw(); }, }, - lose:{ - charlotte:true, - mark:true, - marktext:'↓', - intro:{content:'不因此法失去牌后,你弃置一张牌'}, - audio:'weishu', - trigger:{player:'loseAfter',global:'loseAsyncAfter'}, - filter(event,player){ - if(!player.countCards('he')) return false; - const evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - return event.getParent(3).name!='fakeweirong_lose'; + lose: { + charlotte: true, + mark: true, + marktext: "↓", + intro: { content: "不因此法失去牌后,你弃置一张牌" }, + audio: "weishu", + trigger: { player: "loseAfter", global: "loseAsyncAfter" }, + filter(event, player) { + if (!player.countCards("he")) return false; + const evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + return event.getParent(3).name != "fakeweirong_lose"; }, - forced:true, - content(){ - player.chooseToDiscard('he',true); + forced: true, + content() { + player.chooseToDiscard("he", true); }, }, }, - getNum(player){ - let num=0,count=false; - const history=player.actionHistory; - for(let i=history.length-1;i>=0;i--){ - if(history[i].isRound){ - if(!count){ - count=true; + getNum(player) { + let num = 0, + count = false; + const history = player.actionHistory; + for (let i = history.length - 1; i >= 0; i--) { + if (history[i].isRound) { + if (!count) { + count = true; continue; - } - else break; + } else break; } - if(!count) continue; - const allHistory=history[i].gain.filter(evt=>{ - return evt.getParent(2).name=='fakeweirong'||evt.getParent(2).name=='fakeweirong_gain'; - }).slice().concat(history[i].lose.filter(evt=>{ - return evt.getParent(2).skill=='fakeweirong'||evt.getParent(3).name=='fakeweirong_lose'; - })); - for(const evt of allHistory) num+=evt.cards.length; + if (!count) continue; + const allHistory = history[i].gain + .filter((evt) => { + return ( + evt.getParent(2).name == "fakeweirong" || + evt.getParent(2).name == "fakeweirong_gain" + ); + }) + .slice() + .concat( + history[i].lose.filter((evt) => { + return ( + evt.getParent(2).skill == "fakeweirong" || + evt.getParent(3).name == "fakeweirong_lose" + ); + }) + ); + for (const evt of allHistory) num += evt.cards.length; } - return Math.max(1,Math.min(player.maxHp,num)); + return Math.max(1, Math.min(player.maxHp, num)); }, }, - fakequanbian:{ - audio:'quanbian', - trigger:{player:['useCard','respond']}, - filter(event,player){ - if(!Array.from(ui.cardPile.childNodes).length) return false; - return player.countCards('h')&&_status.currentPhase==player; + fakequanbian: { + audio: "quanbian", + trigger: { player: ["useCard", "respond"] }, + filter(event, player) { + if (!Array.from(ui.cardPile.childNodes).length) return false; + return player.countCards("h") && _status.currentPhase == player; }, - async cost(event,trigger,player){ - const cards=Array.from(ui.cardPile.childNodes); - const {result:{bool,moved}}=await player.chooseToMove(get.prompt2('fakequanbian')) - .set('list',[ - ['牌堆顶',cards.slice(0,Math.min(player.maxHp,cards.length)),'fakequanbian_tag'], - ['手牌',player.getCards('h')], - ]).set('filterOk',moved=>moved[1].filter(i=>!get.owner(i)).length==1) - .set('filterMove',(from,to)=>typeof to!='number').set('processAI',list=>{ - const player=get.event('player'),goon=player.hasSkill('fakezhouting'); - let cards1=list[0][1].slice(),cards2=list[1][1].slice(); - let card1=cards1.slice().sort((a,b)=>get[goon?'useful':'value'](goon?a:b)-get[goon?'useful':'value'](goon?b:a))[0]; - let card2=cards2.slice().sort((a,b)=>get[goon?'useful':'value'](goon?b:a)-get[goon?'useful':'value'](goon?a:b))[0]; - if(get[goon?'useful':'value'](card1)*(goon?-1:1)get.owner(i))[0], - moved[1].filter(i=>!get.owner(i))[0], + async cost(event, trigger, player) { + const cards = Array.from(ui.cardPile.childNodes); + const { + result: { bool, moved }, + } = await player + .chooseToMove(get.prompt2("fakequanbian")) + .set("list", [ + [ + "牌堆顶", + cards.slice(0, Math.min(player.maxHp, cards.length)), + "fakequanbian_tag", + ], + ["手牌", player.getCards("h")], + ]) + .set("filterOk", (moved) => moved[1].filter((i) => !get.owner(i)).length == 1) + .set("filterMove", (from, to) => typeof to != "number") + .set("processAI", (list) => { + const player = get.event("player"), + goon = player.hasSkill("fakezhouting"); + let cards1 = list[0][1].slice(), + cards2 = list[1][1].slice(); + let card1 = cards1 + .slice() + .sort( + (a, b) => + get[goon ? "useful" : "value"](goon ? a : b) - + get[goon ? "useful" : "value"](goon ? b : a) + )[0]; + let card2 = cards2 + .slice() + .sort( + (a, b) => + get[goon ? "useful" : "value"](goon ? b : a) - + get[goon ? "useful" : "value"](goon ? a : b) + )[0]; + if ( + get[goon ? "useful" : "value"](card1) * (goon ? -1 : 1) < + get[goon ? "useful" : "value"](card2) * (goon ? -1 : 1) + ) { + cards1.remove(card1); + cards2.remove(card2); + return [cards1.concat(card2), cards2.concat(card1)]; + } + }); + if (bool) { + event.result = { + bool: true, + cost_data: [ + moved[0].filter((i) => get.owner(i))[0], + moved[1].filter((i) => !get.owner(i))[0], ], }; - } - else event.result={bool:false}; + } else event.result = { bool: false }; }, - async content(event,trigger,player){ - await player.lose(event.cost_data[0],ui.cardPile).set('insert_index',()=>{ - return ui.cardPile.childNodes[Array.from(ui.cardPile.childNodes).indexOf(get.event('card2'))]; - }).set('card2',event.cost_data[1]); - await player.gain(event.cost_data[1],'gain2'); + async content(event, trigger, player) { + await player + .lose(event.cost_data[0], ui.cardPile) + .set("insert_index", () => { + return ui.cardPile.childNodes[ + Array.from(ui.cardPile.childNodes).indexOf(get.event("card2")) + ]; + }) + .set("card2", event.cost_data[1]); + await player.gain(event.cost_data[1], "gain2"); }, }, - fakezhouting:{ - unique:true, - limited:true, - audio:'xiongzhi', - enable:'phaseUse', - skillAnimation:true, - animationColor:'thunder', - async content(event,trigger,player){ - player.awakenSkill('fakezhouting'); - let gains=[]; - const cards=Array.from(ui.cardPile.childNodes).slice(0,Math.min(player.maxHp,Array.from(ui.cardPile.childNodes).length)); + fakezhouting: { + unique: true, + limited: true, + audio: "xiongzhi", + enable: "phaseUse", + skillAnimation: true, + animationColor: "thunder", + async content(event, trigger, player) { + player.awakenSkill("fakezhouting"); + let gains = []; + const cards = Array.from(ui.cardPile.childNodes).slice( + 0, + Math.min(player.maxHp, Array.from(ui.cardPile.childNodes).length) + ); await game.cardsGotoOrdering(cards); - for(const card of cards){ - if(player.hasUseTarget(card,false,false)){ - await player.chooseUseTarget(card,true,false,'nodistance'); - } - else gains.push(card); + for (const card of cards) { + if (player.hasUseTarget(card, false, false)) { + await player.chooseUseTarget(card, true, false, "nodistance"); + } else gains.push(card); } - if(gains.length) await player.gain(gains,'gain2'); - if(game.getGlobalHistory('everything',evt=>{ - return evt.name=='die'&&evt.getParent(6).name=='fakezhouting'&&evt.getParent(6).player==player; - }).length) player.restoreSkill('fakezhouting'); + if (gains.length) await player.gain(gains, "gain2"); + if ( + game.getGlobalHistory("everything", (evt) => { + return ( + evt.name == "die" && + evt.getParent(6).name == "fakezhouting" && + evt.getParent(6).player == player + ); + }).length + ) + player.restoreSkill("fakezhouting"); }, - ai:{ - order:1, - result:{ - player(player){ - return player.hasUnknown()?0:1; + ai: { + order: 1, + result: { + player(player) { + return player.hasUnknown() ? 0 : 1; }, }, }, }, - fakexuanbei:{ - audio:'xuanbei', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakexuanbei')); - },event).indexOf(event)==0; + fakexuanbei: { + audio: "xuanbei", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakexuanbei")) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - forced:true, - locked:false, - async content(event,trigger,player){ + forced: true, + locked: false, + async content(event, trigger, player) { await player.draw(2); - player.addTempSkill('fakexuanbei_effect'); + player.addTempSkill("fakexuanbei_effect"); }, - group:['fakexuanbei_change','fakexuanbei_give'], - subSkill:{ - effect:{ - charlotte:true, - mark:true, - intro:{content:'使用应变牌时直接获得强化'}, + group: ["fakexuanbei_change", "fakexuanbei_give"], + subSkill: { + effect: { + charlotte: true, + mark: true, + intro: { content: "使用应变牌时直接获得强化" }, }, - give:{ - audio:'xuanbei', - trigger:{player:'useCardAfter'}, - filter(event,player){ - return (event.card.yingbian||get.is.yingbian(event.card))&&event.cards.filterInD().length; + give: { + audio: "xuanbei", + trigger: { player: "useCardAfter" }, + filter(event, player) { + return ( + (event.card.yingbian || get.is.yingbian(event.card)) && + event.cards.filterInD().length + ); }, - usable:1, - async cost(event,trigger,player){ - const cards=trigger.cards.filterInD(); - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('fakexuanbei'),'令一名其他角色获得'+get.translation(event.cards),lib.filter.notMe).set('ai',target=>{ - const att=get.attitude(get.event('player'),target); - if(att<0) return 0; - if(target.hasJudge('lebu')) att/=2; - if(target.hasSkillTag('nogain')) att/=10; - return att/(1+get.distance(player,target,'absolute')); - }); - event.result={bool:bool,targets:targets,cards:cards}; + usable: 1, + async cost(event, trigger, player) { + const cards = trigger.cards.filterInD(); + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("fakexuanbei"), + "令一名其他角色获得" + get.translation(event.cards), + lib.filter.notMe + ) + .set("ai", (target) => { + const att = get.attitude(get.event("player"), target); + if (att < 0) return 0; + if (target.hasJudge("lebu")) att /= 2; + if (target.hasSkillTag("nogain")) att /= 10; + return att / (1 + get.distance(player, target, "absolute")); + }); + event.result = { bool: bool, targets: targets, cards: cards }; }, - async content(event,trigger,player){ - await event.targets[0].gain(event.cards,'gain2').set('giver',player); + async content(event, trigger, player) { + await event.targets[0].gain(event.cards, "gain2").set("giver", player); }, }, - change:{ - audio:'xuanbei', - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - async cost(event,trigger,player){ - const {result:{bool,targets}}=await player.chooseTarget(get.prompt('fakexuanbei'),'令一名其他角色变更副将',lib.filter.notMe).set('ai',target=>{ - const player=get.event('player'); - const rank=get.guozhanRank(target.name2,target)<=3; - const att=get.attitude(player,target); - if(att>0) return (4-rank)*att; - return -(rank-6)*att; - }).set('forceDie',true); - event.result={bool:bool,targets:targets}; + change: { + audio: "xuanbei", + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + async cost(event, trigger, player) { + const { + result: { bool, targets }, + } = await player + .chooseTarget( + get.prompt("fakexuanbei"), + "令一名其他角色变更副将", + lib.filter.notMe + ) + .set("ai", (target) => { + const player = get.event("player"); + const rank = get.guozhanRank(target.name2, target) <= 3; + const att = get.attitude(player, target); + if (att > 0) return (4 - rank) * att; + return -(rank - 6) * att; + }) + .set("forceDie", true); + event.result = { bool: bool, targets: targets }; }, - async content(event,trigger,player){ + async content(event, trigger, player) { await event.targets[0].changeVice(); }, }, }, }, - fakeqingleng:{ - audio:'qingleng', - trigger:{global:'phaseEnd'}, - filter(event,player){ - var target=event.player; - return target!=player&&target.isIn()&&!target.isUnseen(2)&&player.countCards('he')&&player.canUse({name:'sha',nature:'ice'},target,false); + fakeqingleng: { + audio: "qingleng", + trigger: { global: "phaseEnd" }, + filter(event, player) { + var target = event.player; + return ( + target != player && + target.isIn() && + !target.isUnseen(2) && + player.countCards("he") && + player.canUse({ name: "sha", nature: "ice" }, target, false) + ); }, - direct:true, - preHidden:true, - async content(event,trigger,player){ - const target=trigger.player; - const {result:{bool}}=await player.chooseToUse() - .set('openskilldialog',get.prompt2('fakeqingleng',target)) - .set('norestore',true).set('_backupevent','fakeqingleng_backup') - .set('custom',{ - add:{}, - replace:{window:function(){}} - }).set('targetRequired',true).set('complexSelect',true) - .set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',target).set('addCount',false).set('hiddenSkill','fakeqingleng') - .backup('fakeqingleng_backup').set('logSkill',['fakeqingleng',target]); - if(bool&&!player.getHistory('sourceDamage',evt=>{ - return evt.getParent(4)==event; - }).length){ - const {result:{bool,links}}=await player.chooseButton([ - '清冷:暗置'+get.translation(target)+'的一张武将牌', - '
                        '+get.translation(target)+'的武将牌
                        ', - [[target.name1,target.name2],'character'], - ],true).set('filterButton',button=>!get.is.jun(button.link)); - if(bool){ + direct: true, + preHidden: true, + async content(event, trigger, player) { + const target = trigger.player; + const { + result: { bool }, + } = await player + .chooseToUse() + .set("openskilldialog", get.prompt2("fakeqingleng", target)) + .set("norestore", true) + .set("_backupevent", "fakeqingleng_backup") + .set("custom", { + add: {}, + replace: { window: function () {} }, + }) + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", target) + .set("addCount", false) + .set("hiddenSkill", "fakeqingleng") + .backup("fakeqingleng_backup") + .set("logSkill", ["fakeqingleng", target]); + if ( + bool && + !player.getHistory("sourceDamage", (evt) => { + return evt.getParent(4) == event; + }).length + ) { + const { + result: { bool, links }, + } = await player + .chooseButton( + [ + "清冷:暗置" + get.translation(target) + "的一张武将牌", + '
                        ' + get.translation(target) + "的武将牌
                        ", + [[target.name1, target.name2], "character"], + ], + true + ) + .set("filterButton", (button) => !get.is.jun(button.link)); + if (bool) { player.line(target); - player.addSkill('fakeqingleng_effect'); - if(player.getStorage('fakeqingleng_effect').some(list=>list[0]==target)){ - player.storage.fakeqingleng_effect.indexOf(player.getStorage('fakeqingleng_effect').find(list=>list[0]==target))[1].addArray(links); - } - else player.markAuto('fakeqingleng_effect',[[target,links[0]]]); - target.when(['phaseBegin','die']) - .vars({target:player}).then(()=>{ - const removes=target.getStorage('fakeqingleng_effect').filter(list=>list[0]==player); - target.unmarkAuto('fakeqingleng_effect',removes); - if(!target.getStorage('fakeqingleng_effect').length){ - target.removeSkill('fakeqingleng_effect'); - } - }); - await target.hideCharacter(target.name1==links[0]?0:1); + player.addSkill("fakeqingleng_effect"); + if (player.getStorage("fakeqingleng_effect").some((list) => list[0] == target)) { + player.storage.fakeqingleng_effect + .indexOf( + player + .getStorage("fakeqingleng_effect") + .find((list) => list[0] == target) + )[1] + .addArray(links); + } else player.markAuto("fakeqingleng_effect", [[target, links[0]]]); + target + .when(["phaseBegin", "die"]) + .vars({ target: player }) + .then(() => { + const removes = target + .getStorage("fakeqingleng_effect") + .filter((list) => list[0] == player); + target.unmarkAuto("fakeqingleng_effect", removes); + if (!target.getStorage("fakeqingleng_effect").length) { + target.removeSkill("fakeqingleng_effect"); + } + }); + await target.hideCharacter(target.name1 == links[0] ? 0 : 1); } } }, - subSkill:{ - backup:{ - filterCard:true, - check(card){ - return 7.5-get.value(card); + subSkill: { + backup: { + filterCard: true, + check(card) { + return 7.5 - get.value(card); }, - position:'he', - popname:true, - viewAs:{name:'sha',nature:'ice'}, - precontent(){ + position: "he", + popname: true, + viewAs: { name: "sha", nature: "ice" }, + precontent() { delete event.result.skill; }, }, - effect:{ - charlotte:true, - onremove:true, - intro:{ - content(storage){ - return '•'+storage.map(list=>{ - return get.translation(list[0])+'明置'+get.translation(list[1])+'后,对其造成1点伤害'; - }).join('
                        •'); + effect: { + charlotte: true, + onremove: true, + intro: { + content(storage) { + return ( + "•" + + storage + .map((list) => { + return ( + get.translation(list[0]) + + "明置" + + get.translation(list[1]) + + "后,对其造成1点伤害" + ); + }) + .join("
                        •") + ); }, }, - audio:'qingleng', - trigger:{global:'showCharacterEnd'}, - filter(event,player){ - const list=player.getStorage('fakeqingleng_effect').find(list=>list[0]==event.player); - return list&&list[1].includes(event.toShow); + audio: "qingleng", + trigger: { global: "showCharacterEnd" }, + filter(event, player) { + const list = player + .getStorage("fakeqingleng_effect") + .find((list) => list[0] == event.player); + return list && list[1].includes(event.toShow); }, - forced:true, - logTarget:'player', - content(){ + forced: true, + logTarget: "player", + content() { trigger.player.damage(); }, }, }, }, - fakexijue:{ - audio:'xijue', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakexijue')); - },event).indexOf(event)==0; + fakexijue: { + audio: "xijue", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakexijue")) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - forced:true, - popup:false, - preHidden:['xijue_tuxi','fakexijue_xiaoguo'], - content(){ - player.addMark('xijue',2); + forced: true, + popup: false, + preHidden: ["xijue_tuxi", "fakexijue_xiaoguo"], + content() { + player.addMark("xijue", 2); }, - derivation:['xijue_tuxi','fakexijue_xiaoguo'], - group:['fakexijue_effect','xijue_tuxi','fakexijue_xiaoguo'], - subSkill:{ - effect:{ - audio:'xijue', - trigger:{player:['phaseDrawBegin2','phaseEnd']}, - filter(event,player){ - if(event.name=='phaseDraw') return !event.numFixed; - return player.getHistory('sourceDamage').length; + derivation: ["xijue_tuxi", "fakexijue_xiaoguo"], + group: ["fakexijue_effect", "xijue_tuxi", "fakexijue_xiaoguo"], + subSkill: { + effect: { + audio: "xijue", + trigger: { player: ["phaseDrawBegin2", "phaseEnd"] }, + filter(event, player) { + if (event.name == "phaseDraw") return !event.numFixed; + return player.getHistory("sourceDamage").length; }, - forced:true, - popup:false, - content(){ - if(trigger.name=='phaseDraw') trigger.num=Math.min(player.countMark('xijue'),player.maxHp); - else player.addMark('xijue',1); + forced: true, + popup: false, + content() { + if (trigger.name == "phaseDraw") + trigger.num = Math.min(player.countMark("xijue"), player.maxHp); + else player.addMark("xijue", 1); }, }, - xiaoguo:{ - audio:'xijue_xiaoguo', - trigger:{global:'phaseZhunbeiBegin'}, - filter(event,player){ - if(!player.hasMark('xijue')) return false; - return event.player!=player&&player.countCards('h',card=>{ - if(_status.connectMode) return true; - return get.type(card)=='basic'&&lib.filter.cardDiscardable(card,player); - }); + xiaoguo: { + audio: "xijue_xiaoguo", + trigger: { global: "phaseZhunbeiBegin" }, + filter(event, player) { + if (!player.hasMark("xijue")) return false; + return ( + event.player != player && + player.countCards("h", (card) => { + if (_status.connectMode) return true; + return ( + get.type(card) == "basic" && lib.filter.cardDiscardable(card, player) + ); + }) + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseToDiscard(get.prompt2('fakexijue_xiaoguo',trigger.player),(card,player)=>{ - return get.type(card)=='basic'; - },[1,Math.min(player.countMark('xijue'),player.maxHp)]).set('complexSelect',true).set('ai',card=>{ - const player=get.event('player'),target=get.event().getTrigger().player; - const effect=get.damageEffect(target,player,player); - const cards=target.getCards('e',card=>get.attitude(player,target)*get.value(card,target)<0); - if(effect<=0&&!cards.length) return 0; - if(ui.selected.cards.length>cards.length-(effect<=0?1:0)) return 0; - return 1/(get.value(card)||0.5); - }).set('logSkill',['fakexijue_xiaoguo',trigger.player]).setHiddenSkill('fakexijue_xiaoguo').forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseToDiscard( + get.prompt2("fakexijue_xiaoguo", trigger.player), + (card, player) => { + return get.type(card) == "basic"; + }, + [1, Math.min(player.countMark("xijue"), player.maxHp)] + ) + .set("complexSelect", true) + .set("ai", (card) => { + const player = get.event("player"), + target = get.event().getTrigger().player; + const effect = get.damageEffect(target, player, player); + const cards = target.getCards( + "e", + (card) => get.attitude(player, target) * get.value(card, target) < 0 + ); + if (effect <= 0 && !cards.length) return 0; + if (ui.selected.cards.length > cards.length - (effect <= 0 ? 1 : 0)) + return 0; + return 1 / (get.value(card) || 0.5); + }) + .set("logSkill", ["fakexijue_xiaoguo", trigger.player]) + .setHiddenSkill("fakexijue_xiaoguo") + .forResult(); }, - preHidden:true, - popup:false, - async content(event,trigger,player){ - const num=trigger.player.countCards('e'),num2=event.cards.length; - await player.discardPlayerCard(trigger.player,'e',num2,true); - if(num2>num) await trigger.player.damage(); - player.removeMark('xijue',1); + preHidden: true, + popup: false, + async content(event, trigger, player) { + const num = trigger.player.countCards("e"), + num2 = event.cards.length; + await player.discardPlayerCard(trigger.player, "e", num2, true); + if (num2 > num) await trigger.player.damage(); + player.removeMark("xijue", 1); }, }, }, }, - fakeqimei:{ - audio:'qimei', - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - preHidden:true, - content(){ - 'step 0' - player.chooseTarget(get.prompt('fakeqimei'),'选择一名其他角色并获得“齐眉”效果',lib.filter.notMe).set('ai',target=>{ - var player=_status.event.player; - return get.attitude(player,target)/(Math.abs(player.countCards('h')+2-target.countCards('h'))+1) - }).setHiddenSkill('fakeqimei'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('fakeqimei',target); - player.addTempSkill('fakeqimei_draw'); - player.storage.fakeqimei_draw=target; + fakeqimei: { + audio: "qimei", + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + preHidden: true, + content() { + "step 0"; + player + .chooseTarget( + get.prompt("fakeqimei"), + "选择一名其他角色并获得“齐眉”效果", + lib.filter.notMe + ) + .set("ai", (target) => { + var player = _status.event.player; + return ( + get.attitude(player, target) / + (Math.abs(player.countCards("h") + 2 - target.countCards("h")) + 1) + ); + }) + .setHiddenSkill("fakeqimei"); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("fakeqimei", target); + player.addTempSkill("fakeqimei_draw"); + player.storage.fakeqimei_draw = target; game.delayx(); } }, - subSkill:{ - draw:{ - audio:'qimei', - charlotte:true, - forced:true, - popup:false, - trigger:{global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','loseAfter','addToExpansionAfter']}, - filter(event,player){ - var target=player.storage.fakeqimei_draw; - if(!target||!target.isIn()) return false; - if(player.countCards('h')!=target.countCards('h')) return false; - var hasChange=function(event,player){ - var gain=0,lose=0; - if(event.getg) gain=event.getg(player).length; - if(event.getl) lose=event.getl(player).hs.length; - return gain!=lose; - }; - return (hasChange(event,player)&&target.isDamaged())||(hasChange(event,target)&&player.isDamaged()); + subSkill: { + draw: { + audio: "qimei", + charlotte: true, + forced: true, + popup: false, + trigger: { + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "loseAfter", + "addToExpansionAfter", + ], }, - content(){ - 'step 0' - if(trigger.delay===false) game.delayx(); - 'step 1' - var target=player.storage.fakeqimei_draw; - player.logSkill('fakeqimei_draw',target); - var drawer=[]; - var hasChange=function(event,player){ - var gain=0,lose=0; - if(event.getg) gain=event.getg(player).length; - if(event.getl) lose=event.getl(player).hs.length; - return gain!=lose; + filter(event, player) { + var target = player.storage.fakeqimei_draw; + if (!target || !target.isIn()) return false; + if (player.countCards("h") != target.countCards("h")) return false; + var hasChange = function (event, player) { + var gain = 0, + lose = 0; + if (event.getg) gain = event.getg(player).length; + if (event.getl) lose = event.getl(player).hs.length; + return gain != lose; }; - if(hasChange(trigger,player)) drawer.push(target); - if(hasChange(trigger,target)) drawer.push(player); - for(const i of drawer){ - if(i.isDamaged()) i.recover(); + return ( + (hasChange(event, player) && target.isDamaged()) || + (hasChange(event, target) && player.isDamaged()) + ); + }, + content() { + "step 0"; + if (trigger.delay === false) game.delayx(); + "step 1"; + var target = player.storage.fakeqimei_draw; + player.logSkill("fakeqimei_draw", target); + var drawer = []; + var hasChange = function (event, player) { + var gain = 0, + lose = 0; + if (event.getg) gain = event.getg(player).length; + if (event.getl) lose = event.getl(player).hs.length; + return gain != lose; + }; + if (hasChange(trigger, player)) drawer.push(target); + if (hasChange(trigger, target)) drawer.push(player); + for (const i of drawer) { + if (i.isDamaged()) i.recover(); } }, - group:'fakeqimei_hp', - onremove:true, - mark:true, - intro:{content:'已和$组成齐眉组合'}, + group: "fakeqimei_hp", + onremove: true, + mark: true, + intro: { content: "已和$组成齐眉组合" }, }, - hp:{ - audio:'qimei', - trigger:{global:'changeHp'}, - charlotte:true, - forced:true, - logTarget(event,player){ + hp: { + audio: "qimei", + trigger: { global: "changeHp" }, + charlotte: true, + forced: true, + logTarget(event, player) { return player.storage.fakeqimei_draw; }, - filter(event,player){ - var target=player.storage.fakeqimei_draw; - if(!target||!target.isIn()) return false; - if(player!=event.player&&target!=event.player) return false; - return player.hp==target.hp; + filter(event, player) { + var target = player.storage.fakeqimei_draw; + if (!target || !target.isIn()) return false; + if (player != event.player && target != event.player) return false; + return player.hp == target.hp; }, - content(){ + content() { game.delayx(); - (player==trigger.player?player.storage.fakeqimei_draw:player).draw(); + (player == trigger.player ? player.storage.fakeqimei_draw : player).draw(); }, }, }, }, - fakebaoqie:{ - audio:'baoqie', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - if(!game.hasPlayer(target=>{ - return target.getGainableCards(player,'e').some(card=>get.subtype(card)=='equip5'); - })) return false; - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakebaoqie')); - },event).indexOf(event)==0; + fakebaoqie: { + audio: "baoqie", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + if ( + !game.hasPlayer((target) => { + return target + .getGainableCards(player, "e") + .some((card) => get.subtype(card) == "equip5"); + }) + ) + return false; + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakebaoqie")) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt('fakebaoqie'),'获得一名角色的宝物牌,然后你可以使用此牌',(card,player,target)=>{ - return target.getGainableCards(player,'e').some(card=>get.subtype(card)=='equip5'); - }).set('ai',target=>{ - const player=get.event('player'); - return -get.sgn(get.attitude(player,target))*target.getGainableCards(player,'e').filter(card=>{ - return get.subtype(card)=='equip5'; - }).reduce((sum,card)=>sum+get.value(card,target),0); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("fakebaoqie"), + "获得一名角色装备区里所有的宝物牌,然后你可以使用其中的一张牌", + (card, player, target) => { + return target + .getGainableCards(player, "e") + .some((card) => get.subtype(card) == "equip5"); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return ( + -get.sgn(get.attitude(player, target)) * + target + .getGainableCards(player, "e") + .filter((card) => { + return get.subtype(card) == "equip5"; + }) + .reduce((sum, card) => sum + get.value(card, target), 0) + ); + }) + .forResult(); }, - async content(event,trigger,player){ - const target=event.targets[0]; - let cards=target.getGainableCards(player,'e').filter(card=>get.subtype(card)=='equip5'); - await player.gain(cards,target,'giveAuto'); - cards=cards.filter(i=>get.owner(i)==player&&get.position(i)=='h'&&player.hasUseTarget(i)); - if(cards.length){ - const {result:{bool,links}}=await player.chooseButton(['宝箧:是否使用其中一张宝物牌?',cards]).set('ai',button=>{ - return get.equipValue(button.link,get.event('player')); - }); - if(bool) await player.chooseUseTarget(links[0],true); + async content(event, trigger, player) { + const target = event.targets[0]; + let cards = target + .getGainableCards(player, "e") + .filter((card) => get.subtype(card) == "equip5"); + await player.gain(cards, target, "giveAuto"); + cards = cards.filter( + (i) => get.owner(i) == player && get.position(i) == "h" && player.hasUseTarget(i) + ); + if (cards.length) { + const { + result: { bool, links }, + } = await player + .chooseButton(["宝箧:是否使用其中的一张宝物牌?", cards]) + .set("ai", (button) => { + return get.equipValue(button.link, get.event("player")); + }); + if (bool) await player.chooseUseTarget(links[0], true); } }, - ai:{mingzhi_no:true}, - group:'fakebaoqie_damage', - subSkill:{ - damage:{ - audio:'baoqie', - trigger:{player:'damageBegin4'}, - filter(event,player){ - if(!player.getStockSkills(true,true,true).includes('fakebaoqie')) return false; - return !game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakebaoqie')); + ai: { mingzhi_no: true }, + group: "fakebaoqie_damage", + subSkill: { + damage: { + audio: "baoqie", + trigger: { player: "damageBegin4" }, + filter(event, player) { + if (!player.getStockSkills(true, true, true).includes("fakebaoqie")) return false; + return !game.getAllGlobalHistory("everything", (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakebaoqie")) + ); }).length; }, - check(event,player){ - return !event.source||get.damageEffect(player,event.source,player)<0; + check(event, player) { + return !event.source || get.damageEffect(player, event.source, player) < 0; }, - prompt:'宝箧:是否明置此武将牌并防止此伤害?', - content(){ + prompt: "宝箧:是否明置此武将牌并防止此伤害?", + content() { trigger.cancel(); }, }, }, }, - fakeciwei:{ - audio:'ciwei', - trigger:{global:'useCard'}, - filter(event,player){ - if(event.all_excluded||event.player==player||!player.countCards('he')) return false; - return event.player.getHistory('useCard').indexOf(event)%2==1; + fakeciwei: { + audio: "ciwei", + trigger: { global: "useCard" }, + filter(event, player) { + if (event.all_excluded || event.player == player || !player.countCards("he")) + return false; + return event.player.getHistory("useCard").indexOf(event) % 2 == 1; }, - async cost(event,trigger,player){ - let str='弃置一张牌,取消'+get.translation(trigger.card)+'的所有目标'; - if(get.type(trigger.card)=='equip') str+=',然后你获得此牌且你可以使用之'; - event.result=await player.chooseToDiscard(get.prompt('fakeciwei',trigger.player),str,'he').set('ai',card=>{ - return (_status.event.goon/1.4)-get.value(card); - }).set('goon',function(){ - if(!trigger.targets.length) return -get.attitude(player,trigger.player); - var num=0; - for(var i of trigger.targets){ - num-=get.effect(i,trigger.card,trigger.player,player); - } - return num; - }()).setHiddenSkill('fakeciwei').set('logSkill',['fakeciwei',trigger.player]).forResult(); + async cost(event, trigger, player) { + let str = "弃置一张牌,取消" + get.translation(trigger.card) + "的所有目标"; + if (get.type(trigger.card) == "equip") str += ",然后你获得此牌且你可以使用之"; + event.result = await player + .chooseToDiscard(get.prompt("fakeciwei", trigger.player), str, "he") + .set("ai", (card) => { + return _status.event.goon / 1.4 - get.value(card); + }) + .set( + "goon", + (function () { + if (!trigger.targets.length) return -get.attitude(player, trigger.player); + var num = 0; + for (var i of trigger.targets) { + num -= get.effect(i, trigger.card, trigger.player, player); + } + return num; + })() + ) + .setHiddenSkill("fakeciwei") + .set("logSkill", ["fakeciwei", trigger.player]) + .forResult(); }, - preHidden:true, - popup:false, - async content(event,trigger,player){ - trigger.targets.length=0; - trigger.all_excluded=true; - if(get.type(trigger.card)=='equip'&&!get.owner(trigger.card)){ - await player.gain(trigger.card,'gain2'); - if(get.owner(trigger.card)==player&&player.hasUseTarget(trigger.card)){ + preHidden: true, + popup: false, + async content(event, trigger, player) { + trigger.targets.length = 0; + trigger.all_excluded = true; + if (get.type(trigger.card) == "equip" && !get.owner(trigger.card)) { + await player.gain(trigger.card, "gain2"); + if (get.owner(trigger.card) == player && player.hasUseTarget(trigger.card)) { await player.chooseUseTarget(trigger.card); } } }, - global:'fakeciwei_ai', - subSkill:{ - ai:{ - mod:{ - aiOrder(player,card,num){ - if(!player.getHistory('useCard').length%2||!game.hasPlayer(current=>{ - return current!=player&&(get.realAttitude||get.attitude)(current,player)<0&¤t.hasSkill('fakeciwei')&¤t.countCards('he')>0; - })) return; - if(!player._fakeciwei_temp){ - player._fakeciwei_temp=true; - num/=Math.max(1,player.getUseValue(card)); + global: "fakeciwei_ai", + subSkill: { + ai: { + mod: { + aiOrder(player, card, num) { + if ( + !player.getHistory("useCard").length % 2 || + !game.hasPlayer((current) => { + return ( + current != player && + (get.realAttitude || get.attitude)(current, player) < 0 && + current.hasSkill("fakeciwei") && + current.countCards("he") > 0 + ); + }) + ) + return; + if (!player._fakeciwei_temp) { + player._fakeciwei_temp = true; + num /= Math.max(1, player.getUseValue(card)); } delete player._fakeciwei_temp; return num; @@ -3539,2790 +5121,3631 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, }, - fakehuirong:{ - audio:'huirong', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - if(!game.hasPlayer(target=>{ - return target.countCards('h')!=target.getHp(); - })) return false; - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakehuirong')); - },event).indexOf(event)==0; + fakehuirong: { + audio: "huirong", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + if ( + !game.hasPlayer((target) => { + return target.countCards("h") != target.getHp(); + }) + ) + return false; + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakehuirong")) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt('fakehuirong'),'令一名角色将手牌数摸至/弃置至与其体力值相同',(card,player,target)=>{ - return target.countCards('h')!=target.getHp(); - }).set('ai',target=>{ - const att=get.attitude(get.event('player'),target); - const num=target.countCards('h'); - if(num>target.hp) return -att*(num-target.getHp()); - return att*Math.max(0,target.getHp()-target.countCards('h')); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("fakehuirong"), + "令一名角色将手牌数摸至/弃置至与其体力值相同", + (card, player, target) => { + return target.countCards("h") != target.getHp(); + } + ) + .set("ai", (target) => { + const att = get.attitude(get.event("player"), target); + const num = target.countCards("h"); + if (num > target.hp) return -att * (num - target.getHp()); + return att * Math.max(0, target.getHp() - target.countCards("h")); + }) + .forResult(); }, - preHidden:true, - content(){ - const target=event.targets[0]; - if(target.countCards('h'){ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakehuirong')); + ai: { mingzhi_no: true }, + group: "fakehuirong_damage", + subSkill: { + damage: { + audio: "huirong", + trigger: { player: "damageBegin4" }, + filter(event, player) { + if (!player.getStockSkills(true, true, true).includes("fakehuirong")) + return false; + return !game.getAllGlobalHistory("everything", (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakehuirong")) + ); }).length; }, - check(event,player){ - return !event.source||get.damageEffect(player,event.source,player)<0; + check(event, player) { + return !event.source || get.damageEffect(player, event.source, player) < 0; }, - prompt:'慧容:是否明置此武将牌并防止此伤害?', - content(){ + prompt: "慧容:是否明置此武将牌并防止此伤害?", + content() { trigger.cancel(); }, }, }, }, - fakeyanxi:{ - audio:'yanxi', - enable:'phaseUse', - filter(event,player){ - return game.hasPlayer(target=>{ - return get.info('fakeyanxi').filterTarget(null,player,target); + fakeyanxi: { + audio: "yanxi", + enable: "phaseUse", + filter(event, player) { + return game.hasPlayer((target) => { + return get.info("fakeyanxi").filterTarget(null, player, target); }); }, - filterTarget(card,player,target){ - return target!=player&&target.countCards('h'); + filterTarget(card, player, target) { + return target != player && target.countCards("h"); }, - usable:1, - async content(event,trigger,player){ - const target=event.target,str=get.translation(target); - const {result:{bool,links}}=await player.choosePlayerCard(target,'宴戏:展示'+str+'的一张手牌','h',true); - if(bool){ - let cards=get.cards(2),gains=[]; + usable: 1, + async content(event, trigger, player) { + const target = event.target, + str = get.translation(target); + const { + result: { bool, links }, + } = await player.choosePlayerCard(target, "宴戏:展示" + str + "的一张手牌", "h", true); + if (bool) { + let cards = get.cards(2), + gains = []; await game.cardsGotoOrdering(cards); - cards=links.slice().concat(cards); - await player.showCards(cards,get.translation(player)+'发动了【宴戏】'); - for(const card of cards){ + cards = links.slice().concat(cards); + await player.showCards(cards, get.translation(player) + "发动了【宴戏】"); + for (const card of cards) { gains.unshift(get.color(card)); gains.add(get.type2(card)); } - gains=gains.unique().map(i=>i=='none'?'none2':i); - const {result:{control}}=await player.chooseControl(gains).set('cards',cards).set('ai',()=>{ - const player=get.event('player'),cards=get.event('cards'),getNum=function(cards,control,player){ - cards=cards.filter(i=>get.type2(i)==control||get.color(i)==control); - return cards.reduce((sum,card)=>sum+get.value(card,player),0); - }; - let controls=get.event('controls').slice().map(i=>i=='none2'?'none':i); - controls.sort((a,b)=>getNum(cards,b,player)-getNum(cards,a,player)); - return controls[0]=='none'?'none2':controls[0]; - }).set('dialog',['获得其中一种颜色或类别的所有牌,然后'+str+'获得剩余牌','hidden',cards]); - if(control){ - const choice=(control=='none2'?'none':control); - gains=cards.filter(i=>get.type2(i)==choice||get.color(i)==choice); - const num=gains.length; + gains = gains.unique().map((i) => (i == "none" ? "none2" : i)); + const { + result: { control }, + } = await player + .chooseControl(gains) + .set("cards", cards) + .set("ai", () => { + const player = get.event("player"), + cards = get.event("cards"), + getNum = function (cards, control, player) { + cards = cards.filter( + (i) => get.type2(i) == control || get.color(i) == control + ); + return cards.reduce((sum, card) => sum + get.value(card, player), 0); + }; + let controls = get + .event("controls") + .slice() + .map((i) => (i == "none2" ? "none" : i)); + controls.sort((a, b) => getNum(cards, b, player) - getNum(cards, a, player)); + return controls[0] == "none" ? "none2" : controls[0]; + }) + .set("dialog", [ + "获得其中一种颜色或类别的所有牌,然后" + str + "获得剩余牌", + "hidden", + cards, + ]); + if (control) { + const choice = control == "none2" ? "none" : control; + gains = cards.filter((i) => get.type2(i) == choice || get.color(i) == choice); + const num = gains.length; cards.removeArray(gains); - if(gains.includes(links[0])){ + if (gains.includes(links[0])) { gains.removeArray(links); - await player.gain(links,target,'give','bySelf'); + await player.gain(links, target, "give", "bySelf"); } - if(gains.length) await player.gain(gains,'gain2'); - player.addTempSkill('fakeyanxi_maxHand'); - player.addMark('fakeyanxi_maxHand',num,false); - cards=cards.filter(i=>!links.includes(i)); - if(cards.length) await target.gain(cards,'gain2'); + if (gains.length) await player.gain(gains, "gain2"); + player.addTempSkill("fakeyanxi_maxHand"); + player.addMark("fakeyanxi_maxHand", num, false); + cards = cards.filter((i) => !links.includes(i)); + if (cards.length) await target.gain(cards, "gain2"); } } }, - ai:{ - order:9, - result:{ - target(player,target){ - return [-1,1,2][get.sgn(get.attitude(player,target))+1]/target.countCards('h'); + ai: { + order: 9, + result: { + target(player, target) { + return ( + [-1, 1, 2][get.sgn(get.attitude(player, target)) + 1] / target.countCards("h") + ); }, }, }, - subSkill:{ - maxHand:{ - charlotte:true, - onremove:true, - intro:{content:'手牌上限+#'}, - mod:{ - maxHandcard(player,num){ - return num+player.countMark('fakeyanxi_maxHand'); + subSkill: { + maxHand: { + charlotte: true, + onremove: true, + intro: { content: "手牌上限+#" }, + mod: { + maxHandcard(player, num) { + return num + player.countMark("fakeyanxi_maxHand"); }, }, }, }, }, - fakeshiren:{ - audio:'shiren', - trigger:{player:'showCharacterEnd'}, - filter(event,player){ - if(!game.hasPlayer(target=>{ - return get.info('fakeyanxi').filterTarget(null,player,target); - })) return false; - return game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakeshiren')); - },event).indexOf(event)==0; + fakeshiren: { + audio: "shiren", + trigger: { player: "showCharacterEnd" }, + filter(event, player) { + if ( + !game.hasPlayer((target) => { + return get.info("fakeyanxi").filterTarget(null, player, target); + }) + ) + return false; + return ( + game + .getAllGlobalHistory( + "everything", + (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakeshiren")) + ); + }, + event + ) + .indexOf(event) == 0 + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt('fakeshiren'),'发动一次【宴戏】',(card,player,target)=>{ - return get.info('fakeyanxi').filterTarget(null,player,target); - }).set('ai',target=>{ - const player=get.event('player'); - return -get.sgn(get.attitude(player,target))*get.info('fakeyanxi').ai.result.target(player,target); - }).forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("fakeshiren"), + "发动一次【宴戏】", + (card, player, target) => { + return get.info("fakeyanxi").filterTarget(null, player, target); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return ( + -get.sgn(get.attitude(player, target)) * + get.info("fakeyanxi").ai.result.target(player, target) + ); + }) + .forResult(); }, - async content(event,trigger,player){ - const target=event.targets[0]; - player.useResult({skill:'fakeyanxi',target:target,targets:[target]},event); + async content(event, trigger, player) { + const target = event.targets[0]; + player.useResult({ skill: "fakeyanxi", target: target, targets: [target] }, event); }, - ai:{mingzhi_no:true}, - group:'fakeshiren_damage', - subSkill:{ - damage:{ - audio:'shiren', - trigger:{player:'damageBegin4'}, - filter(event,player){ - if(!player.getStockSkills(true,true,true).includes('fakeshiren')) return false; - return !game.getAllGlobalHistory('everything',evt=>{ - return evt.name=='showCharacter'&&evt.player==player&&evt.toShow.some(i=>get.character(i,3).includes('fakeshiren')); + ai: { mingzhi_no: true }, + group: "fakeshiren_damage", + subSkill: { + damage: { + audio: "shiren", + trigger: { player: "damageBegin4" }, + filter(event, player) { + if (!player.getStockSkills(true, true, true).includes("fakeshiren")) return false; + return !game.getAllGlobalHistory("everything", (evt) => { + return ( + evt.name == "showCharacter" && + evt.player == player && + evt.toShow.some((i) => get.character(i, 3).includes("fakeshiren")) + ); }).length; }, - check(event,player){ - return !event.source||get.damageEffect(player,event.source,player)<0; + check(event, player) { + return !event.source || get.damageEffect(player, event.source, player) < 0; }, - prompt:'识人:是否明置此武将牌并防止此伤害?', - content(){ + prompt: "识人:是否明置此武将牌并防止此伤害?", + content() { trigger.cancel(); }, }, }, }, - fakecanmou:{ - audio:'canmou', - trigger:{global:'useCardToPlayer'}, - filter(event,player){ - if(!event.player.isMaxHandcard(true)||!event.isFirstTarget||get.type(event.card)!='trick') return false; - if(event.targets.length>1&&!player.getStorage('fakecanmou_used').includes('-')) return true; - return get.info('fakecanmou').filter_add(event,player); + fakecanmou: { + audio: "canmou", + trigger: { global: "useCardToPlayer" }, + filter(event, player) { + if ( + !event.player.isMaxHandcard(true) || + !event.isFirstTarget || + get.type(event.card) != "trick" + ) + return false; + if (event.targets.length > 1 && !player.getStorage("fakecanmou_used").includes("-")) + return true; + return get.info("fakecanmou").filter_add(event, player); }, - filter_add(event,player){ - const info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget&&!player.getStorage('fakecanmou_used').includes('+')){ - if(game.hasPlayer(current=>{ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,event.player,current); - })) return true; + filter_add(event, player) { + const info = get.info(event.card); + if (info.allowMultiple == false) return false; + if ( + event.targets && + !info.multitarget && + !player.getStorage("fakecanmou_used").includes("+") + ) { + if ( + game.hasPlayer((current) => { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, event.player, current) + ); + }) + ) + return true; } return false; }, - async cost(event,trigger,player){ - let str='',goon=get.info('fakecanmou').filter_add(trigger,player),bool=(trigger.targets.length>1&&!player.getStorage('fakecanmou_used').includes('-')); - if(goon) str+='增加'; - if(goon&&bool) str='或'; - if(bool) str+='减少'; - event.result=await player.chooseTarget(get.prompt('fakecanmou'),(card,player,target)=>{ - const trigger=get.event().getTrigger(); - if(trigger.targets.length>1&&!player.getStorage('fakecanmou_used').includes('-')&&trigger.targets.includes(target)) return true; - return !player.getStorage('fakecanmou_used').includes('+')&&!trigger.targets.includes(target)&&lib.filter.targetEnabled2(trigger.card,trigger.player,target); - }).set('prompt2','为'+get.translation(trigger.card)+str+'一个目标').set('ai',target=>{ - const player=get.event('player'),trigger=get.event().getTrigger(); - return get.effect(target,trigger.card,trigger.player,player)*(trigger.targets.includes(target)?-1:1); - }).setHiddenSkill('fakecanmou').forResult(); + async cost(event, trigger, player) { + let str = "", + goon = get.info("fakecanmou").filter_add(trigger, player), + bool = + trigger.targets.length > 1 && !player.getStorage("fakecanmou_used").includes("-"); + if (goon) str += "增加"; + if (goon && bool) str = "或"; + if (bool) str += "减少"; + event.result = await player + .chooseTarget(get.prompt("fakecanmou"), (card, player, target) => { + const trigger = get.event().getTrigger(); + if ( + trigger.targets.length > 1 && + !player.getStorage("fakecanmou_used").includes("-") && + trigger.targets.includes(target) + ) + return true; + return ( + !player.getStorage("fakecanmou_used").includes("+") && + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(trigger.card, trigger.player, target) + ); + }) + .set("prompt2", "为" + get.translation(trigger.card) + str + "一个目标") + .set("ai", (target) => { + const player = get.event("player"), + trigger = get.event().getTrigger(); + return ( + get.effect(target, trigger.card, trigger.player, player) * + (trigger.targets.includes(target) ? -1 : 1) + ); + }) + .setHiddenSkill("fakecanmou") + .forResult(); }, - preHidden:true, - async content(event,trigger,player){ - const target=event.targets[0],goon=trigger.targets.includes(target); - player.addTempSkill('fakecanmou_used'); - player.markAuto('fakecanmou_used',[goon?'-':'+']); - if(goon){ + preHidden: true, + async content(event, trigger, player) { + const target = event.targets[0], + goon = trigger.targets.includes(target); + player.addTempSkill("fakecanmou_used"); + player.markAuto("fakecanmou_used", [goon ? "-" : "+"]); + if (goon) { trigger.targets.remove(target); - game.log(target,'被',player,'移除了目标'); - } - else{ + game.log(target, "被", player, "移除了目标"); + } else { trigger.targets.add(target); - game.log(target,'成为了',trigger.card,'移除了目标'); + game.log(target, "成为了", trigger.card, "移除了目标"); } }, - subSkill:{used:{charlotte:true,onremove:true}}, + subSkill: { used: { charlotte: true, onremove: true } }, }, - fakezhuosheng:{ - hiddenCard(player,name){ - return player.countCards('hs')>1&&get.type(name)=='basic'&&lib.inpile.includes(name)&&!player.getStorage('fakezhuosheng_count').includes(name); + fakezhuosheng: { + hiddenCard(player, name) { + return ( + player.countCards("hs") > 1 && + get.type(name) == "basic" && + lib.inpile.includes(name) && + !player.getStorage("fakezhuosheng_count").includes(name) + ); }, - audio:'zhuosheng', - enable:'chooseToUse', - filter(event,player){ - if(event.type=='wuxie') return false; - if(player.countCards('hs')<2) return false; - return get.inpileVCardList(info=>{ - const name=info[2]; - return !player.getStorage('fakezhuosheng_count').includes(name)&&get.type(name)=='basic'; - }).some(card=>event.filterCard({name:card[2],nature:card[3]},player,event)); + audio: "zhuosheng", + enable: "chooseToUse", + filter(event, player) { + if (event.type == "wuxie") return false; + if (player.countCards("hs") < 2) return false; + return get + .inpileVCardList((info) => { + const name = info[2]; + return ( + !player.getStorage("fakezhuosheng_count").includes(name) && + get.type(name) == "basic" + ); + }) + .some((card) => event.filterCard({ name: card[2], nature: card[3] }, player, event)); }, - chooseButton:{ - dialog(event,player){ - var list=get.inpileVCardList(info=>{ - const name=info[2]; - return !player.getStorage('fakezhuosheng_count').includes(name)&&get.type(name)=='basic'; - }).filter(card=>event.filterCard({name:card[2],nature:card[3]},player,event)); - return ui.create.dialog('擢升',[list,'vcard'],'hidden'); + chooseButton: { + dialog(event, player) { + var list = get + .inpileVCardList((info) => { + const name = info[2]; + return ( + !player.getStorage("fakezhuosheng_count").includes(name) && + get.type(name) == "basic" + ); + }) + .filter((card) => + event.filterCard({ name: card[2], nature: card[3] }, player, event) + ); + return ui.create.dialog("擢升", [list, "vcard"], "hidden"); }, - check(button){ - var player=_status.event.player; - var evt=_status.event.getParent(); - var name=button.link[2],card={name:name,nature:button.link[3]}; - if(name=='shan') return 2; - if(evt.type=='dying'){ - if(get.attitude(player,evt.dying)<2) return 0; - if(name=='jiu') return 2.1; + check(button) { + var player = _status.event.player; + var evt = _status.event.getParent(); + var name = button.link[2], + card = { name: name, nature: button.link[3] }; + if (name == "shan") return 2; + if (evt.type == "dying") { + if (get.attitude(player, evt.dying) < 2) return 0; + if (name == "jiu") return 2.1; return 1.9; } - if(evt.type=='phase'){ - if(button.link[2]=='jiu'){ - if(player.getUseValue({name:'jiu'})<=0) return 0; - var cards=player.getCards('hs',cardx=>get.value(cardx)<8); - cards.sort((a,b)=>get.value(a)-get.value(b)); - if(cards.some(cardx=>get.name(cardx)=='sha'&&!cards.slice(0,2).includes(cardx))) return player.getUseValue({name:'jiu'}); + if (evt.type == "phase") { + if (button.link[2] == "jiu") { + if (player.getUseValue({ name: "jiu" }) <= 0) return 0; + var cards = player.getCards("hs", (cardx) => get.value(cardx) < 8); + cards.sort((a, b) => get.value(a) - get.value(b)); + if ( + cards.some( + (cardx) => + get.name(cardx) == "sha" && !cards.slice(0, 2).includes(cardx) + ) + ) + return player.getUseValue({ name: "jiu" }); return 0; } - return player.getUseValue(card)/4; + return player.getUseValue(card) / 4; } return 1; }, - backup(links,player){ + backup(links, player) { return { - audio:'zhuosheng', - filterCard:true, - selectCard:[2,Infinity], - position:'hs', - complexCard:true, - check(card){ - if(ui.selected.cards.length>=2) return 0; - return 8-get.value(card); + audio: "zhuosheng", + filterCard: true, + selectCard: [2, Infinity], + position: "hs", + complexCard: true, + check(card) { + if (ui.selected.cards.length >= 2) return 0; + return 8 - get.value(card); }, - popname:true, - viewAs:{ - name:links[0][2], - nature:links[0][3], + popname: true, + viewAs: { + name: links[0][2], + nature: links[0][3], }, - precontent(){ - var name=event.result.card.name; - player.addTempSkill('fakezhuosheng_count'); - player.markAuto('fakezhuosheng_count',[name]); - player.when('yingbian') - .filter(evt=>evt.skill=='fakezhuosheng_backup') - .then(()=>{ - if(trigger.cards&&trigger.cards.length){ - let cards=trigger.cards.slice(); - cards=cards.filter(i=>get.is.yingbian(i)); - if(cards.length){ - if(!Array.isArray(trigger.temporaryYingbian)) trigger.temporaryYingbian=[]; - trigger.temporaryYingbian.add('force'); - trigger.temporaryYingbian.addArray(Array.from(lib.yingbian.effect.keys()).filter(value=>{ - return cards.some(card=>get.cardtag(card,`yingbian_${value}`)); - })); + precontent() { + var name = event.result.card.name; + player.addTempSkill("fakezhuosheng_count"); + player.markAuto("fakezhuosheng_count", [name]); + player + .when("yingbian") + .filter((evt) => evt.skill == "fakezhuosheng_backup") + .then(() => { + if (trigger.cards && trigger.cards.length) { + let cards = trigger.cards.slice(); + cards = cards.filter((i) => get.is.yingbian(i)); + if (cards.length) { + if (!Array.isArray(trigger.temporaryYingbian)) + trigger.temporaryYingbian = []; + trigger.temporaryYingbian.add("force"); + trigger.temporaryYingbian.addArray( + Array.from(lib.yingbian.effect.keys()).filter((value) => { + return cards.some((card) => + get.cardtag(card, `yingbian_${value}`) + ); + }) + ); + } } - } - }); + }); }, - } + }; }, - prompt(links,player){ - var name=links[0][2]; - var nature=links[0][3]; - return '将至少两张手牌当作'+(get.translation(nature)||'')+get.translation(name)+'使用'; + prompt(links, player) { + var name = links[0][2]; + var nature = links[0][3]; + return ( + "将至少两张手牌当作" + + (get.translation(nature) || "") + + get.translation(name) + + "使用" + ); }, }, - ai:{ - order(item,player){ - if(player&&_status.event.type=='phase'){ - var add=false,max=0; - var names=lib.inpile.filter(name=>get.type(name)=='basic'&&!player.getStorage('fakezhuosheng_count').includes(name)); - if(names.includes('sha')) add=true; - names=names.map(namex=>{return {name:namex}}); - if(add) lib.inpile_nature.forEach(nature=>names.push({name:'sha',nature:nature})); - names.forEach(card=>{ - if(player.getUseValue(card)>0){ - var temp=get.order(card); - if(card.name=='jiu'){ - var cards=player.getCards('hs',cardx=>get.value(cardx)<8); - cards.sort((a,b)=>get.value(a)-get.value(b)); - if(!cards.some(cardx=>get.name(cardx)=='sha'&&!cards.slice(0,2).includes(cardx))) temp=0; + ai: { + order(item, player) { + if (player && _status.event.type == "phase") { + var add = false, + max = 0; + var names = lib.inpile.filter( + (name) => + get.type(name) == "basic" && + !player.getStorage("fakezhuosheng_count").includes(name) + ); + if (names.includes("sha")) add = true; + names = names.map((namex) => { + return { name: namex }; + }); + if (add) + lib.inpile_nature.forEach((nature) => + names.push({ name: "sha", nature: nature }) + ); + names.forEach((card) => { + if (player.getUseValue(card) > 0) { + var temp = get.order(card); + if (card.name == "jiu") { + var cards = player.getCards("hs", (cardx) => get.value(cardx) < 8); + cards.sort((a, b) => get.value(a) - get.value(b)); + if ( + !cards.some( + (cardx) => + get.name(cardx) == "sha" && + !cards.slice(0, 2).includes(cardx) + ) + ) + temp = 0; } - if(temp>max) max=temp; + if (temp > max) max = temp; } }); - if(max>0) max-=0.001; + if (max > 0) max -= 0.001; return max; } return 0.5; }, - respondShan:true, - respondSha:true, - fireAttack:true, - skillTagFilter(player,tag,arg){ - if(arg=='respond') return false; - const name=(tag=='respondShan'?'shan':'sha'); - return get.info('fakezhuosheng').hiddenCard(player,name); + respondShan: true, + respondSha: true, + fireAttack: true, + skillTagFilter(player, tag, arg) { + if (arg == "respond") return false; + const name = tag == "respondShan" ? "shan" : "sha"; + return get.info("fakezhuosheng").hiddenCard(player, name); }, - result:{ - player(player){ - if(_status.event.dying) return get.attitude(player,_status.event.dying); + result: { + player(player) { + if (_status.event.dying) return get.attitude(player, _status.event.dying); return 1; }, }, }, - subSkill:{ - count:{charlotte:true,onremove:true}, - backup:{}, + subSkill: { + count: { charlotte: true, onremove: true }, + backup: {}, }, }, - fakejuhou:{ - zhenfa:'inline', - trigger:{global:'useCardToTargeted'}, - filter(event,player){ - return (event.card.name=='sha'||get.type(event.card)=='trick')&&event.target.inline(player); + fakejuhou: { + zhenfa: "inline", + trigger: { global: "useCardToTargeted" }, + filter(event, player) { + return ( + (event.card.name == "sha" || get.type(event.card) == "trick") && + event.target.inline(player) + ); }, - logTarget:'target', - async content(event,trigger,player){ - const target=trigger.target; - const {result:{bool,cards}}=await target.chooseCard('he',[1,Infinity],'是否将任意张牌置于武将牌上?').set('ai',card=>{ - const trigger=get.event().getTrigger(),player=trigger.target; - if(card.name=='baiyin'&&get.position(card)=='e'&&player.isDamaged()&&get.recoverEffect(player,player,player)>0) return 1; - if(['guohe','shunshou','zhujinqiyuan','chuqibuyi','huogong'].includes(trigger.card.name)&&get.effect(player,trigger.card,trigger.player,player)<0) return 1; - return 0; - }); - if(bool){ - target.addToExpansion(cards,'giveAuto',target).gaintag.add('fakejuhou'); - target.addSkill('fakejuhou'); - target.when({global:'useCardAfter'}) - .filter(evt=>evt==trigger.getParent()) - .then(()=>{ - const cards=player.getExpansions('fakejuhou'); - if(cards.length) player.gain(cards,'gain2'); + logTarget: "target", + async content(event, trigger, player) { + const target = trigger.target; + const { + result: { bool, cards }, + } = await target + .chooseCard("he", [1, Infinity], "是否将任意张牌置于武将牌上?") + .set("ai", (card) => { + const trigger = get.event().getTrigger(), + player = trigger.target; + if ( + card.name == "baiyin" && + get.position(card) == "e" && + player.isDamaged() && + get.recoverEffect(player, player, player) > 0 + ) + return 1; + if ( + ["guohe", "shunshou", "zhujinqiyuan", "chuqibuyi", "huogong"].includes( + trigger.card.name + ) && + get.effect(player, trigger.card, trigger.player, player) < 0 + ) + return 1; + return 0; }); + if (bool) { + target.addToExpansion(cards, "giveAuto", target).gaintag.add("fakejuhou"); + target.addSkill("fakejuhou"); + target + .when({ global: "useCardAfter" }) + .filter((evt) => evt == trigger.getParent()) + .then(() => { + const cards = player.getExpansions("fakejuhou"); + if (cards.length) player.gain(cards, "gain2"); + }); } }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, }, - gznaxiang:{ - audio:'naxiang', - inherit:'naxiang', + gznaxiang: { + audio: "naxiang", + inherit: "naxiang", }, - fakecaiwang:{ - audio:'caiwang', - trigger:{player:'loseAfter'}, - filter(event,player){ - const evt=event.getParent(2); - if(evt.name!='yingbianZhuzhan') return false; - const color=(get.color(evt.card)==get.color(event.cards[0])).toString(); - if(color=='true'&&!game.hasPlayer(target=>{ - return target!=player&&target.countCards('he'); - })) return false; - return !player.getStorage('fakecaiwang_used').includes(color); + fakecaiwang: { + audio: "caiwang", + trigger: { player: "loseAfter" }, + filter(event, player) { + const evt = event.getParent(2); + if (evt.name != "yingbianZhuzhan") return false; + const color = (get.color(evt.card) == get.color(event.cards[0])).toString(); + if ( + color == "true" && + !game.hasPlayer((target) => { + return target != player && target.countCards("he"); + }) + ) + return false; + return !player.getStorage("fakecaiwang_used").includes(color); }, - async cost(event,trigger,player){ - const color=(get.color(trigger.getParent(2).card)==get.color(trigger.cards[0])).toString(); - if(color=='false'){ + async cost(event, trigger, player) { + const color = ( + get.color(trigger.getParent(2).card) == get.color(trigger.cards[0]) + ).toString(); + if (color == "false") { //event.result=await player.chooseBool(get.prompt('fakecaiwang'),'摸一张牌').forResult(); - event.result={bool:true}; - } - else{ - event.result=await player.chooseTarget(get.prompt('fakecaiwang'),'弃置一名其他角色的一张牌',(card,player,target)=>{ - return target!=player&&target.countCards('he'); - }).set('ai',target=>{ - const player=get.event('player'); - return get.effect(target,{name:'guohe_copy2'},player,player); - }).forResult(); + event.result = { bool: true }; + } else { + event.result = await player + .chooseTarget( + get.prompt("fakecaiwang"), + "弃置一名其他角色的一张牌", + (card, player, target) => { + return target != player && target.countCards("he"); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return get.effect(target, { name: "guohe_copy2" }, player, player); + }) + .forResult(); } }, - async content(event,trigger,player){ - const color=(get.color(trigger.getParent(2).card)==get.color(trigger.cards[0])).toString(); - player.addTempSkill('fakecaiwang_used'); - player.markAuto('fakecaiwang_used',[color]); - if(color=='false') await player.draw(); - else await player.discardPlayerCard(event.targets[0],'he',true); + async content(event, trigger, player) { + const color = ( + get.color(trigger.getParent(2).card) == get.color(trigger.cards[0]) + ).toString(); + player.addTempSkill("fakecaiwang_used"); + player.markAuto("fakecaiwang_used", [color]); + if (color == "false") await player.draw(); + else await player.discardPlayerCard(event.targets[0], "he", true); }, - group:'fakecaiwang_zhuzhan', - subSkill:{ - used:{ - charlotte:true, - onremove:true, + group: "fakecaiwang_zhuzhan", + subSkill: { + used: { + charlotte: true, + onremove: true, }, - zhuzhan:{ - trigger:{player:'yingbianZhuzhanBegin'}, - forced:true, - locked:false, - popup:false, - firstDo:true, - content(){ - trigger.setContent(get.info('fakecaiwang').yingbian); + zhuzhan: { + trigger: { player: "yingbianZhuzhanBegin" }, + forced: true, + locked: false, + popup: false, + firstDo: true, + content() { + trigger.setContent(get.info("fakecaiwang").yingbian); }, }, }, - yingbian(){ - 'step 0'; + yingbian() { + "step 0"; event._global_waiting = true; event.send = (player, card, source, targets, id, id2, yingbianZhuzhanAI, skillState) => { if (skillState) player.applySkills(skillState); - var type = get.type2(card), str = get.translation(source); + var type = get.type2(card), + str = get.translation(source); if (targets && targets.length) str += `对${get.translation(targets)}`; - str += `使用了${get.translation(card)},是否弃置一张${get.translation(type)}为其助战?`; + str += `使用了${get.translation(card)},是否弃置一张${get.translation( + type + )}为其助战?`; player.chooseCard({ - filterCard: (card, player) => get.type2(card) == type && lib.filter.cardDiscardable(card, player), + filterCard: (card, player) => + get.type2(card) == type && lib.filter.cardDiscardable(card, player), prompt: str, - position: 'h', + position: "h", _global_waiting: true, id: id, id2: id2, - ai: typeof yingbianZhuzhanAI == 'function' ? yingbianZhuzhanAI(player, card, source, targets) : cardx => { - var info = get.info(card); - if (info && info.ai && info.ai.yingbian) { - var ai = info.ai.yingbian(card, source, targets, player); - if (!ai) return 0; - return ai - get.value(cardx); - } - else if (get.attitude(player, source) <= 0) return 0; - return 5 - get.value(cardx); - } + ai: + typeof yingbianZhuzhanAI == "function" + ? yingbianZhuzhanAI(player, card, source, targets) + : (cardx) => { + var info = get.info(card); + if (info && info.ai && info.ai.yingbian) { + var ai = info.ai.yingbian(card, source, targets, player); + if (!ai) return 0; + return ai - get.value(cardx); + } else if (get.attitude(player, source) <= 0) return 0; + return 5 - get.value(cardx); + }, }); if (!game.online) return; _status.event._resultid = id; game.resume(); }; - 'step 1'; + "step 1"; var type = get.type2(card); - event.list = game.filterPlayer(current => current.countCards('h') && (_status.connectMode || current.hasCard(cardx => get.type2(cardx) == type, 'h'))).sortBySeat(_status.currentPhase || player); + event.list = game + .filterPlayer( + (current) => + current.countCards("h") && + (_status.connectMode || + current.hasCard((cardx) => get.type2(cardx) == type, "h")) + ) + .sortBySeat(_status.currentPhase || player); event.id = get.id(); - 'step 2'; + "step 2"; if (!event.list.length) event.finish(); - else if (_status.connectMode && (event.list[0].isOnline() || event.list[0] == game.me)) event.goto(4); - else event.send(event.current = event.list.shift(), event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI); - 'step 3'; + else if (_status.connectMode && (event.list[0].isOnline() || event.list[0] == game.me)) + event.goto(4); + else + event.send( + (event.current = event.list.shift()), + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI + ); + "step 3"; if (result.bool) { event.zhuzhanresult = event.current; event.zhuzhanresult2 = result; if (event.current != game.me) game.delayx(); event.goto(8); - } - else event.goto(2); - 'step 4'; - var id = event.id, sendback = (result, player) => { - if (result && result.id == id && !event.zhuzhanresult && result.bool) { - event.zhuzhanresult = player; - event.zhuzhanresult2 = result; - game.broadcast('cancel', id); - if (_status.event.id == id && _status.event.name == 'chooseCard' && _status.paused) return () => { - event.resultOL = _status.event.resultOL; - ui.click.cancel(); - if (ui.confirm) ui.confirm.close(); - }; - } - else if (_status.event.id == id && _status.event.name == 'chooseCard' && _status.paused) return () => event.resultOL = _status.event.resultOL; - }, withme = false, withol = false, list = event.list; + } else event.goto(2); + "step 4"; + var id = event.id, + sendback = (result, player) => { + if (result && result.id == id && !event.zhuzhanresult && result.bool) { + event.zhuzhanresult = player; + event.zhuzhanresult2 = result; + game.broadcast("cancel", id); + if ( + _status.event.id == id && + _status.event.name == "chooseCard" && + _status.paused + ) + return () => { + event.resultOL = _status.event.resultOL; + ui.click.cancel(); + if (ui.confirm) ui.confirm.close(); + }; + } else if ( + _status.event.id == id && + _status.event.name == "chooseCard" && + _status.paused + ) + return () => (event.resultOL = _status.event.resultOL); + }, + withme = false, + withol = false, + list = event.list; for (var i = 0; i < list.length; i++) { var current = list[i]; if (current.isOnline()) { withol = true; current.wait(sendback); - current.send(event.send, current, event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI, get.skillState(current)); + current.send( + event.send, + current, + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI, + get.skillState(current) + ); list.splice(i--, 1); - } - else if (current == game.me) { + } else if (current == game.me) { withme = true; - event.send(current, event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI); + event.send( + current, + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI + ); list.splice(i--, 1); } } if (!withme) event.goto(6); - if (_status.connectMode && (withme || withol)) game.players.forEach(value => { - if (value != player) value.showTimer(); - }); + if (_status.connectMode && (withme || withol)) + game.players.forEach((value) => { + if (value != player) value.showTimer(); + }); event.withol = withol; - 'step 5'; + "step 5"; if (!result || !result.bool || event.zhuzhanresult) return; - game.broadcast('cancel', event.id); + game.broadcast("cancel", event.id); event.zhuzhanresult = game.me; event.zhuzhanresult2 = result; - 'step 6'; + "step 6"; if (event.withol && !event.resultOL) game.pause(); - 'step 7'; - game.players.forEach(value => value.hideTimer()); - 'step 8'; + "step 7"; + game.players.forEach((value) => value.hideTimer()); + "step 8"; if (event.zhuzhanresult) { var target = event.zhuzhanresult; - if(target==player&&player.hasSkill('fakecaiwang')) player.logSkill('fakecaiwang'); - target.line(player, 'green'); + if (target == player && player.hasSkill("fakecaiwang")) + player.logSkill("fakecaiwang"); + target.line(player, "green"); target.discard(event.zhuzhanresult2.cards).discarder = target; - if (typeof event.afterYingbianZhuzhan == 'function') event.afterYingbianZhuzhan(event, trigger); - var yingbianCondition = event.name.slice(8).toLowerCase(), yingbianConditionTag = `yingbian_${yingbianCondition}_tag`; - target.popup(yingbianConditionTag, lib.yingbian.condition.color.get(yingbianCondition)); - game.log(target, '响应了', '' + (target==player?'自己':get.translation(player)) + '', '发起的', yingbianConditionTag); + if (typeof event.afterYingbianZhuzhan == "function") + event.afterYingbianZhuzhan(event, trigger); + var yingbianCondition = event.name.slice(8).toLowerCase(), + yingbianConditionTag = `yingbian_${yingbianCondition}_tag`; + target.popup( + yingbianConditionTag, + lib.yingbian.condition.color.get(yingbianCondition) + ); + game.log( + target, + "响应了", + '' + + (target == player ? "自己" : get.translation(player)) + + "", + "发起的", + yingbianConditionTag + ); target.addExpose(0.2); event.result = { - bool: true + bool: true, + }; + } else + event.result = { + bool: false, }; - } - else event.result = { - bool: false - }; }, }, - fakenaxiang:{ - audio:'naxiang', - trigger:{ - source:'damageSource', - player:'damageEnd', + fakenaxiang: { + audio: "naxiang", + trigger: { + source: "damageSource", + player: "damageEnd", }, - filter(event,player){ - if(!event.source||!event.player||!event.source.isIn()||!event.player.isIn()||!event.source.isEnemyOf(event.player)) return false; - return !player.getStorage('fakenaxiang').includes(get.info('fakenaxiang').logTarget(event,player)); + filter(event, player) { + if ( + !event.source || + !event.player || + !event.source.isIn() || + !event.player.isIn() || + !event.source.isEnemyOf(event.player) + ) + return false; + return !player + .getStorage("fakenaxiang") + .includes(get.info("fakenaxiang").logTarget(event, player)); }, - logTarget(event,player){ - return event.source==player?event.player:event.source; + logTarget(event, player) { + return event.source == player ? event.player : event.source; }, - forced:true, - async content(event,trigger,player){ - const target=get.info('fakenaxiang').logTarget(trigger,player); - const {result:{junling,targets}}=await player.chooseJunlingFor(target); - const {result:{index}}=await target.chooseJunlingControl(player,junling,targets).set('prompt','纳降:是否执行军令?'); - if(index==0) await target.carryOutJunling(player,junling,targets); - else{ - if(!player.storage.fakenaxiang){ - player.when(['phaseBegin','die']).then(()=>{ - player.unmarkSkill('fakenaxiang'); + forced: true, + async content(event, trigger, player) { + const target = get.info("fakenaxiang").logTarget(trigger, player); + const { + result: { junling, targets }, + } = await player.chooseJunlingFor(target); + const { + result: { index }, + } = await target + .chooseJunlingControl(player, junling, targets) + .set("prompt", "纳降:是否执行军令?"); + if (index == 0) await target.carryOutJunling(player, junling, targets); + else { + if (!player.storage.fakenaxiang) { + player.when(["phaseBegin", "die"]).then(() => { + player.unmarkSkill("fakenaxiang"); delete player.storage.fakenaxiang; }); } - player.markAuto('fakenaxiang',[target]); + player.markAuto("fakenaxiang", [target]); } }, - onremove:true, - marktext:'', - intro:{content:'无法对$发动【纳降】'}, - group:['fakenaxiang_discard','fakenaxiang_yingbian'], - subSkill:{ - discard:{ - trigger:{player:'chooseCardBegin'}, - filter(event,player){ - return event.getParent().name=='yingbianZhuzhan'; + onremove: true, + marktext: '', + intro: { content: "无法对$发动【纳降】" }, + group: ["fakenaxiang_discard", "fakenaxiang_yingbian"], + subSkill: { + discard: { + trigger: { player: "chooseCardBegin" }, + filter(event, player) { + return event.getParent().name == "yingbianZhuzhan"; }, - forced:true, - popup:false, - firstDo:true, - content(){ - trigger.filterCard=lib.filter.cardDiscardable; + forced: true, + popup: false, + firstDo: true, + content() { + trigger.filterCard = lib.filter.cardDiscardable; }, }, - yingbian:{ - trigger:{player:'yingbian'}, - filter(event,player){ - if(event.card.yingbian) return false; - const temporaryYingbian=event.temporaryYingbian||[],card=event.card; - if(temporaryYingbian.includes('force')||get.cardtag(card,'yingbian_force')) return true; + yingbian: { + trigger: { player: "yingbian" }, + filter(event, player) { + if (event.card.yingbian) return false; + const temporaryYingbian = event.temporaryYingbian || [], + card = event.card; + if (temporaryYingbian.includes("force") || get.cardtag(card, "yingbian_force")) + return true; return get.yingbianConditions(event.card).length; }, - forced:true, - popup:false, - firstDo:true, - content(){ - 'step 0' - trigger.card.yingbian=true; - event.card=trigger.card; - event.temporaryYingbian=(trigger.temporaryYingbian||[]); - if(event.temporaryYingbian.includes('force')||get.cardtag(event.card,'yingbian_force')||trigger.forceYingbian||player.hasSkillTag('forceYingbian')){ - player.popup('yingbian_force_tag',lib.yingbian.condition.color.get('force')); - game.log(player,'触发了',event.card,'的应变条件'); - event._result={bool:true}; - } - else{ - trigger.yingbianZhuzhanAI=(player,card,source,targets)=>cardx=>{ - if(get.attitude(player,source)<=0) return 0; - var info=get.info(card),num=0; - if(info&&info.ai&&info.ai.yingbian){ - var ai=info.ai.yingbian(card,source,targets,player); - if(ai) num=ai; + forced: true, + popup: false, + firstDo: true, + content() { + "step 0"; + trigger.card.yingbian = true; + event.card = trigger.card; + event.temporaryYingbian = trigger.temporaryYingbian || []; + if ( + event.temporaryYingbian.includes("force") || + get.cardtag(event.card, "yingbian_force") || + trigger.forceYingbian || + player.hasSkillTag("forceYingbian") + ) { + player.popup("yingbian_force_tag", lib.yingbian.condition.color.get("force")); + game.log(player, "触发了", event.card, "的应变条件"); + event._result = { bool: true }; + } else { + trigger.yingbianZhuzhanAI = (player, card, source, targets) => (cardx) => { + if (get.attitude(player, source) <= 0) return 0; + var info = get.info(card), + num = 0; + if (info && info.ai && info.ai.yingbian) { + var ai = info.ai.yingbian(card, source, targets, player); + if (ai) num = ai; } - return Math.max(num,6)-get.value(cardx); + return Math.max(num, 6) - get.value(cardx); }; - lib.yingbian.condition.complex.get('zhuzhan')(trigger); + lib.yingbian.condition.complex.get("zhuzhan")(trigger); } - 'step 1' - if(!result.bool) return; - var yingbianEffectExecuted=false; - lib.yingbian.effect.forEach((value,key)=>{ - if(!event.temporaryYingbian.includes(key)&&!get.cardtag(card,`yingbian_${key}`)) return; - game.yingbianEffect(trigger,value); - if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + "step 1"; + if (!result.bool) return; + var yingbianEffectExecuted = false; + lib.yingbian.effect.forEach((value, key) => { + if ( + !event.temporaryYingbian.includes(key) && + !get.cardtag(card, `yingbian_${key}`) + ) + return; + game.yingbianEffect(trigger, value); + if (!yingbianEffectExecuted) yingbianEffectExecuted = true; }); - if(!yingbianEffectExecuted){ - var defaultYingbianEffect=get.defaultYingbianEffect(card); - if(lib.yingbian.effect.has(defaultYingbianEffect)){ - game.yingbianEffect(trigger,lib.yingbian.effect.get(defaultYingbianEffect)); - if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + if (!yingbianEffectExecuted) { + var defaultYingbianEffect = get.defaultYingbianEffect(card); + if (lib.yingbian.effect.has(defaultYingbianEffect)) { + game.yingbianEffect( + trigger, + lib.yingbian.effect.get(defaultYingbianEffect) + ); + if (!yingbianEffectExecuted) yingbianEffectExecuted = true; } } - if(yingbianEffectExecuted) player.addTempSkill('yingbian_changeTarget'); + if (yingbianEffectExecuted) player.addTempSkill("yingbian_changeTarget"); }, }, }, }, - fakehuyuan:{ - audio:'yuanhu', - trigger:{player:'phaseJieshuBegin'}, - filter(event,player){ - return player.countCards('he',card=>{ - if(get.position(card)=='h'&&_status.connectMode) return true; - return get.type(card)=='equip'; - })>0; + fakehuyuan: { + audio: "yuanhu", + trigger: { player: "phaseJieshuBegin" }, + filter(event, player) { + return ( + player.countCards("he", (card) => { + if (get.position(card) == "h" && _status.connectMode) return true; + return get.type(card) == "equip"; + }) > 0 + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseCardTarget({ - prompt:get.prompt2('yuanhu'), - filterCard(card){ - return get.type(card)=='equip'; - }, - position:'he', - filterTarget(card,player,target){ - return target.canEquip(card); - }, - ai1(card){ - return 6-get.value(card); - }, - ai2(target){ - return get.attitude(_status.event.player,target)-3; - }, - }).set('hiddenSkill','fakehuyuan').forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseCardTarget({ + prompt: get.prompt2("yuanhu"), + filterCard(card) { + return get.type(card) == "equip"; + }, + position: "he", + filterTarget(card, player, target) { + return target.canEquip(card); + }, + ai1(card) { + return 6 - get.value(card); + }, + ai2(target) { + return get.attitude(_status.event.player, target) - 3; + }, + }) + .set("hiddenSkill", "fakehuyuan") + .forResult(); }, - preHidden:true, - async content(event,trigger,player){ - const card=event.cards[0],target=event.targets[0]; - if(target!=player) player.$give(card,target,false); - await target.equip(thisCard); + preHidden: true, + async content(event, trigger, player) { + const card = event.cards[0], + target = event.targets[0]; + if (target != player) player.$give(card, target, false); + await target.equip(card); }, - group:'fakehuyuan_discard', - subSkill:{ - discard:{ - trigger:{global:'equipEnd'}, - filter(event,player){ - return _status.currentPhase==player&&game.hasPlayer(target=>{ - return get.distance(event.player,target)<=1&&target!=event.player&&target.countCards('hej'); - }); + group: "fakehuyuan_discard", + subSkill: { + discard: { + trigger: { global: "equipEnd" }, + filter(event, player) { + return ( + _status.currentPhase == player && + game.hasPlayer((target) => { + return ( + get.distance(event.player, target) <= 1 && + target != event.player && + target.countCards("hej") + ); + }) + ); }, - async cost(event,trigger,player){ - event.result=await player.chooseTarget(get.prompt('fakehuyuan'),'弃置一名与'+get.translation(trigger.player)+'距离为1以内的另一名角色区域里的一张牌',(card,player,target)=>{ - const trigger=get.event().getTrigger(); - return get.distance(trigger.player,target)<=1&&target!=trigger.player&&target.countCards('hej'); - }).set('ai',target=>{ - const player=get.event('player'); - return get.effect(target,{name:'guohe'},player,player); - }).set('hiddenSkill','fakehuyuan').forResult(); + async cost(event, trigger, player) { + event.result = await player + .chooseTarget( + get.prompt("fakehuyuan"), + "弃置一名与" + + get.translation(trigger.player) + + "距离为1以内的另一名角色区域里的一张牌", + (card, player, target) => { + const trigger = get.event().getTrigger(); + return ( + get.distance(trigger.player, target) <= 1 && + target != trigger.player && + target.countCards("hej") + ); + } + ) + .set("ai", (target) => { + const player = get.event("player"); + return get.effect(target, { name: "guohe" }, player, player); + }) + .set("hiddenSkill", "fakehuyuan") + .forResult(); }, - popup:false, - async content(event,trigger,player){ - const target=event.targets[0]; - player.logSkill('fakehuyuan',target); - await player.discardPlayerCard(target,'hej',true); + popup: false, + async content(event, trigger, player) { + const target = event.targets[0]; + player.logSkill("fakehuyuan", target); + await player.discardPlayerCard(target, "hej", true); }, }, }, }, - fakekeshou:{ - audio:'keshou', - trigger:{player:'damageBegin3'}, - filter(event,player){ - return event.num>0; + fakekeshou: { + audio: "keshou", + trigger: { player: "damageBegin3" }, + filter(event, player) { + return event.num > 0; }, - preHidden:true, - async cost(event,trigger,player){ - event.result=await player.chooseToDiscard(get.prompt('fakekeshou'),'弃置两张颜色相同的牌,令即将受到的伤害-1','he',2,card=>{ - return !ui.selected.cards.length||get.color(card)==get.color(ui.selected.cards[0]); - }).set('logSkill','fakekeshou').set('complexCard',true).setHiddenSkill('fakekeshou').set('ai',card=>{ - if(!_status.event.check) return 0; - var player=_status.event.player; - if(player.hp==1){ - if(!player.countCards('h',function(card){return get.tag(card,'save')})&&!player.hasSkillTag('save',true)) return 10-get.value(card); - return 7-get.value(card); - } - return 6-get.value(card); - }).set('check',(player.countCards('h',{color:'red'})>1||player.countCards('h',{color:'black'})>1)).forResult(); + preHidden: true, + async cost(event, trigger, player) { + event.result = await player + .chooseToDiscard( + get.prompt("fakekeshou"), + "弃置两张颜色相同的牌,令即将受到的伤害-1", + "he", + 2, + (card) => { + return ( + !ui.selected.cards.length || + get.color(card) == get.color(ui.selected.cards[0]) + ); + } + ) + .set("logSkill", "fakekeshou") + .set("complexCard", true) + .setHiddenSkill("fakekeshou") + .set("ai", (card) => { + if (!_status.event.check) return 0; + var player = _status.event.player; + if (player.hp == 1) { + if ( + !player.countCards("h", function (card) { + return get.tag(card, "save"); + }) && + !player.hasSkillTag("save", true) + ) + return 10 - get.value(card); + return 7 - get.value(card); + } + return 6 - get.value(card); + }) + .set( + "check", + player.countCards("h", { color: "red" }) > 1 || + player.countCards("h", { color: "black" }) > 1 + ) + .forResult(); }, - popup:false, - async content(event,trigger,player){ + popup: false, + async content(event, trigger, player) { trigger.num--; }, - group:'fakekeshou_draw', - subSkill:{ - draw:{ - audio:'keshou', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + group: "fakekeshou_draw", + subSkill: { + draw: { + audio: "keshou", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter(event,player){ - if(event.type!='discard'||event.getlx===false) return false; - if(!(!player.isUnseen()&&!game.hasPlayer(current=>{ - return current!=player&¤t.isFriendOf(player); - }))) return false; - const evt=event.getl(player); - return evt&&evt.cards2&&evt.cards2.length>1; + filter(event, player) { + if (event.type != "discard" || event.getlx === false) return false; + if ( + !( + !player.isUnseen() && + !game.hasPlayer((current) => { + return current != player && current.isFriendOf(player); + }) + ) + ) + return false; + const evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length > 1; }, - prompt2:'进行一次判定,若为红色,则你摸一张牌', - async content(event,trigger,player){ - const result=await player.judge(card=>{ - return get.color(card)=='red'?1:0; - }).forResult(); - if(result.judge>0) await player.draw(); + prompt2: "进行一次判定,若为红色,则你摸一张牌", + async content(event, trigger, player) { + const result = await player + .judge((card) => { + return get.color(card) == "red" ? 1 : 0; + }) + .forResult(); + if (result.judge > 0) await player.draw(); }, }, }, }, //国战典藏2023补充 //吕范 - gzdiaodu:{ - audio:'diaodu', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.isFriendOf(player)&¤t.countGainableCards(player,'e')>0; + gzdiaodu: { + audio: "diaodu", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.isFriendOf(player) && current.countGainableCards(player, "e") > 0; }); }, - direct:true, - frequent:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('gzdiaodu'),function(card,player,current){ - return current.isFriendOf(player)&¤t.countGainableCards(player,'e')>0; - }).set('ai',function(target){ - var num=0; - if(target.hasSkill('gzxiaoji')) num+=2.5; - if(target.isDamaged()&&target.getEquip('baiyin')) num+=2.5; - if(target.hasSkill('xuanlve')) num+=2; - return num; - }).setHiddenSkill('gzdiaodu'); - 'step 1' - if(result.bool){ - var target=result.targets[0] - event.target=target; - player.logSkill('gzdiaodu',target); - player.gainPlayerCard(target,'e',true); - } - else event.finish(); - 'step 2' - if(result.bool&&player.getCards('h').includes(result.cards[0])){ - event.card=result.cards[0]; - player.chooseTarget('将'+get.translation(event.card)+'交给另一名角色',function(card,player,current){ - return current!=player&¤t!=_status.event.target; - },true).set('target',target); - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - player.give(card,target); + direct: true, + frequent: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gzdiaodu"), function (card, player, current) { + return current.isFriendOf(player) && current.countGainableCards(player, "e") > 0; + }) + .set("ai", function (target) { + var num = 0; + if (target.hasSkill("gzxiaoji")) num += 2.5; + if (target.isDamaged() && target.getEquip("baiyin")) num += 2.5; + if (target.hasSkill("xuanlve")) num += 2; + return num; + }) + .setHiddenSkill("gzdiaodu"); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gzdiaodu", target); + player.gainPlayerCard(target, "e", true); + } else event.finish(); + "step 2"; + if (result.bool && player.getCards("h").includes(result.cards[0])) { + event.card = result.cards[0]; + player + .chooseTarget( + "将" + get.translation(event.card) + "交给另一名角色", + function (card, player, current) { + return current != player && current != _status.event.target; + }, + true + ) + .set("target", target); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + player.give(card, target); } }, - group:'gzdiaodu_use', - subSkill:{ - use:{ - trigger:{global:'useCard'}, - filter:function(event,player){ - return get.type(event.card)=='equip'&&event.player.isIn()&&event.player.isFriendOf(player)&&(player==event.player||player.hasSkill('gzdiaodu')); + group: "gzdiaodu_use", + subSkill: { + use: { + trigger: { global: "useCard" }, + filter: function (event, player) { + return ( + get.type(event.card) == "equip" && + event.player.isIn() && + event.player.isFriendOf(player) && + (player == event.player || player.hasSkill("gzdiaodu")) + ); }, - direct:true, - content:function(){ - 'step 0' - var next=trigger.player.chooseBool(get.prompt('gzdiaodu'),'摸一张牌'); - if(player.hasSkill('gzdiaodu')) next.set('frequentSkill','gzdiaodu'); - if(player==trigger.player) next.setHiddenSkill('gzdiaodu'); - 'step 1' - if(result.bool){ - player.logSkill('gzdiaodu',trigger.player); - trigger.player.draw('nodelay'); + direct: true, + content: function () { + "step 0"; + var next = trigger.player.chooseBool(get.prompt("gzdiaodu"), "摸一张牌"); + if (player.hasSkill("gzdiaodu")) next.set("frequentSkill", "gzdiaodu"); + if (player == trigger.player) next.setHiddenSkill("gzdiaodu"); + "step 1"; + if (result.bool) { + player.logSkill("gzdiaodu", trigger.player); + trigger.player.draw("nodelay"); } }, }, }, }, //徐庶 - gzqiance:{ - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget||get.type/*2*/(event.card)!='trick') return false;//延时锦囊不能响应有个锤用 - return event.player.isFriendOf(player)&&event.targets.some(target=>target.isMajor()); + gzqiance: { + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget || get.type(/*2*/ event.card) != "trick") return false; //延时锦囊不能响应有个锤用 + return ( + event.player.isFriendOf(player) && event.targets.some((target) => target.isMajor()) + ); }, - check:function(event,player){ - var num=0,targets=event.targets.filter(target=>target.isMajor()); - for(var target of targets) num+=get.sgn(get.attitude(player,target)*get.effect(target,event.card,event.player,player)); - return num>=0; + check: function (event, player) { + var num = 0, + targets = event.targets.filter((target) => target.isMajor()); + for (var target of targets) + num += get.sgn( + get.attitude(player, target) * + get.effect(target, event.card, event.player, player) + ); + return num >= 0; }, - logTarget:'player', - content:function(){ - trigger.getParent().directHit.addArray(trigger.targets.filter(target=>target.isMajor())); + logTarget: "player", + content: function () { + trigger + .getParent() + .directHit.addArray(trigger.targets.filter((target) => target.isMajor())); }, }, - gzjujian:{ - init:function(player){ - if(player.checkViceSkill('gzjujian')&&!player.viceChanged) player.removeMaxHp(); + gzjujian: { + init: function (player) { + if (player.checkViceSkill("gzjujian") && !player.viceChanged) player.removeMaxHp(); }, - viceSkill:true, - audio:'gzjiancai', - trigger:{global:'dying'}, - filter:function(event,player){ + viceSkill: true, + audio: "gzjiancai", + trigger: { global: "dying" }, + filter: function (event, player) { return event.player.isFriendOf(player); }, - forced:true, - logTarget:'player', - content:function(){ - trigger.player.recover(1-trigger.player.hp); + forced: true, + logTarget: "player", + content: function () { + trigger.player.recover(1 - trigger.player.hp); player.changeVice(); }, }, //彭羕 - gztongling:{ - audio:'daming', - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(event.player.isFriendOf(player)) return false; - return player.isPhaseUsing()&&event.player.isIn()&&!player.hasSkill('gztongling_used'); + gztongling: { + audio: "daming", + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (event.player.isFriendOf(player)) return false; + return ( + player.isPhaseUsing() && event.player.isIn() && !player.hasSkill("gztongling_used") + ); }, - direct:true, - content:function(){ - 'step 0' - var str=''; - if(get.itemtype(trigger.cards)=='cards'&&trigger.cards.filterInD().length) str+=';未造成伤害,其获得'+get.translation(trigger.cards.filterInD()); - player.chooseTarget(get.prompt('gztongling'),'令一名势力与你相同的角色选择是否对其使用一张牌。若使用且此牌:造成伤害,你与其各摸两张牌'+str,function(card,player,target){ - return target.isFriendOf(player); - }).set('ai',function(target){ - var aim=_status.event.aim; - var cards=target.getCards('hs',function(card){ - return target.canUse(card,aim,false)&&get.effect(aim,card,target,player)>0&&get.effect(aim,card,target,target)>0; - }) - if(cards.length) return cards.some(card=>get.tag(card,'damage'))?2:1; - return 0; - }).set('aim',trigger.player); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('gztongling',target); - player.addTempSkill('gztongling_used','phaseUseAfter'); - player.line2([target,trigger.player]); - target.chooseToUse(function(card,player,event){ - return lib.filter.filterCard.apply(this,arguments); - },'通令:是否对'+get.translation(trigger.player)+'使用一张牌?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.player).set('addCount',false); - } - else event.finish(); - 'step 2' - if(result.bool){ - if(target.hasHistory('sourceDamage',evt=>evt.getParent(4).name=='gztongling')){ - player.draw(2,'nodelay'); - target.draw(2); - } - else{ - if(get.itemtype(trigger.cards)=='cards'&&trigger.cards.filterInD().length&&trigger.player.isIn()) trigger.player.gain(trigger.cards.filterInD(),'gain2'); - } - } - }, - subSkill:{used:{charlotte:true}}, - }, - gzjinyu:{ - audio:'xiaoni', - trigger:{player:'showCharacterAfter'}, - filter:function(event,player){ - if(!game.hasPlayer(function(current){ - return get.distance(player,current)<=1; - })) return false; - return event.toShow.some(name=>lib.character[name][3].includes('gzjinyu')); - }, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return get.distance(player,current)<=1; - }).sortBySeat(player); - }, - forced:true, - locked:false, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return get.distance(player,current)<=1; - }).sortBySeat(player); - 'step 1' - var target=event.targets.shift(); - event.target=target; - if(!target.isUnseen(2)){ - if(get.is.jun(target)) event._result={control:'副将'}; - else{ - target.chooseControl('主将','副将').set('prompt','近谀:请暗置一张武将牌').set('ai',function(){ - var target=_status.event.player; - if(target.name=='gz_pengyang') return '主将'; - if(target.name2=='gz_pengyang') return '副将'; - if(lib.character[target.name][3].some(skill=>{ - var info=get.info(skill); - return info&&info.ai&&info.ai.maixie; - })) return '主将'; - if(target.name=='gz_zhoutai') return '副将'; - if(target.name2=='gz_zhoutai') return '主将'; - return '副将'; + direct: true, + content: function () { + "step 0"; + var str = ""; + if (get.itemtype(trigger.cards) == "cards" && trigger.cards.filterInD().length) + str += ";未造成伤害,其获得" + get.translation(trigger.cards.filterInD()); + player + .chooseTarget( + get.prompt("gztongling"), + "令一名势力与你相同的角色选择是否对其使用一张牌。若使用且此牌:造成伤害,你与其各摸两张牌" + + str, + function (card, player, target) { + return target.isFriendOf(player); + } + ) + .set("ai", function (target) { + var aim = _status.event.aim; + var cards = target.getCards("hs", function (card) { + return ( + target.canUse(card, aim, false) && + get.effect(aim, card, target, player) > 0 && + get.effect(aim, card, target, target) > 0 + ); }); + if (cards.length) return cards.some((card) => get.tag(card, "damage")) ? 2 : 1; + return 0; + }) + .set("aim", trigger.player); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gztongling", target); + player.addTempSkill("gztongling_used", "phaseUseAfter"); + player.line2([target, trigger.player]); + target + .chooseToUse(function (card, player, event) { + return lib.filter.filterCard.apply(this, arguments); + }, "通令:是否对" + get.translation(trigger.player) + "使用一张牌?") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.player) + .set("addCount", false); + } else event.finish(); + "step 2"; + if (result.bool) { + if ( + target.hasHistory("sourceDamage", (evt) => evt.getParent(4).name == "gztongling") + ) { + player.draw(2, "nodelay"); + target.draw(2); + } else { + if ( + get.itemtype(trigger.cards) == "cards" && + trigger.cards.filterInD().length && + trigger.player.isIn() + ) + trigger.player.gain(trigger.cards.filterInD(), "gain2"); } } - else{ - target.chooseToDiscard(2,'he',true); + }, + subSkill: { used: { charlotte: true } }, + }, + gzjinyu: { + audio: "xiaoni", + trigger: { player: "showCharacterAfter" }, + filter: function (event, player) { + if ( + !game.hasPlayer(function (current) { + return get.distance(player, current) <= 1; + }) + ) + return false; + return event.toShow.some((name) => lib.character[name][3].includes("gzjinyu")); + }, + logTarget: function (event, player) { + return game + .filterPlayer(function (current) { + return get.distance(player, current) <= 1; + }) + .sortBySeat(player); + }, + forced: true, + locked: false, + content: function () { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return get.distance(player, current) <= 1; + }) + .sortBySeat(player); + "step 1"; + var target = event.targets.shift(); + event.target = target; + if (!target.isUnseen(2)) { + if (get.is.jun(target)) event._result = { control: "副将" }; + else { + target + .chooseControl("主将", "副将") + .set("prompt", "近谀:请暗置一张武将牌") + .set("ai", function () { + var target = _status.event.player; + if (target.name == "gz_pengyang") return "主将"; + if (target.name2 == "gz_pengyang") return "副将"; + if ( + lib.character[target.name][3].some((skill) => { + var info = get.info(skill); + return info && info.ai && info.ai.maixie; + }) + ) + return "主将"; + if (target.name == "gz_zhoutai") return "副将"; + if (target.name2 == "gz_zhoutai") return "主将"; + return "副将"; + }); + } + } else { + target.chooseToDiscard(2, "he", true); event.goto(3); } - 'step 2' - if(result.control) target.hideCharacter(result.control=='主将'?0:1); - 'step 3' - if(event.targets.length) event.goto(1); + "step 2"; + if (result.control) target.hideCharacter(result.control == "主将" ? 0 : 1); + "step 3"; + if (event.targets.length) event.goto(1); }, }, //公孙渊 - gzrehuaiyi:{ - audio:'gzhuaiyi', - enable:'phaseUse', - filter:function(event,player){ - return player.countCards('h')>0; + gzrehuaiyi: { + audio: "gzhuaiyi", + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("h") > 0; }, - usable:1, - delay:false, - content:function(){ - 'step 0' - var map={} + usable: 1, + delay: false, + content: function () { + "step 0"; + var map = {}; player.showHandcards(); - for(var i of ['red','black','none']){ - if(player.countCards('h',{color:i})) map[i]=true; + for (var i of ["red", "black", "none"]) { + if (player.countCards("h", { color: i })) map[i] = true; } - if(Object.keys(map).length<2) event.finish(); - else event.map=map; - 'step 1' - var mapx={'red':'红色','black':'黑色','none':'无色'}; - player.chooseControl(Object.keys(event.map).map(color=>mapx[color])).set('ai',function(){ - var list=_status.event.controls; - var map={'红色':'red','黑色':'black','无色':'none'}; - return list.sort((a,b)=>player.countCards('h',{color:map[a]})-player.countCards('h',{color:map[b]}))[0]; - }).set('prompt','怀异:弃置一种颜色的所有牌'); - 'step 2' - var map={'红色':'red','黑色':'black','无色':'none'}; - var cards=player.getCards('h',{color:map[result.control]}); + if (Object.keys(map).length < 2) event.finish(); + else event.map = map; + "step 1"; + var mapx = { red: "红色", black: "黑色", none: "无色" }; + player + .chooseControl(Object.keys(event.map).map((color) => mapx[color])) + .set("ai", function () { + var list = _status.event.controls; + var map = { 红色: "red", 黑色: "black", 无色: "none" }; + return list.sort( + (a, b) => + player.countCards("h", { color: map[a] }) - + player.countCards("h", { color: map[b] }) + )[0]; + }) + .set("prompt", "怀异:弃置一种颜色的所有牌"); + "step 2"; + var map = { 红色: "red", 黑色: "black", 无色: "none" }; + var cards = player.getCards("h", { color: map[result.control] }); player.discard(cards); - event.num=cards.length; - 'step 3' - player.chooseTarget('请选择至多'+get.cnNumber(event.num)+'名有牌的其他角色,获得这些角色的各一张牌。',[1,event.num],function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)+0.5; - }); - 'step 4' - if(result.bool&&result.targets){ - player.line(result.targets,'green'); - event.targets=result.targets; + event.num = cards.length; + "step 3"; + player + .chooseTarget( + "请选择至多" + + get.cnNumber(event.num) + + "名有牌的其他角色,获得这些角色的各一张牌。", + [1, event.num], + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) + 0.5; + }); + "step 4"; + if (result.bool && result.targets) { + player.line(result.targets, "green"); + event.targets = result.targets; event.targets.sort(lib.sort.seat); - event.cards=[]; - } - else event.finish(); - 'step 5' - if(player.isIn()&&event.targets.length){ - player.gainPlayerCard(event.targets.shift(),'he',true); - } - else event.finish(); - 'step 6' - if(result.bool&&result.cards&&result.cards.length) event.cards.addArray(result.cards); - if(event.targets.length) event.goto(5); - 'step 7' - var hs=player.getCards('h'); - cards=cards.filter(function(card){ - return get.type(card)=='equip'&&hs.includes(card); + event.cards = []; + } else event.finish(); + "step 5"; + if (player.isIn() && event.targets.length) { + player.gainPlayerCard(event.targets.shift(), "he", true); + } else event.finish(); + "step 6"; + if (result.bool && result.cards && result.cards.length) + event.cards.addArray(result.cards); + if (event.targets.length) event.goto(5); + "step 7"; + var hs = player.getCards("h"); + cards = cards.filter(function (card) { + return get.type(card) == "equip" && hs.includes(card); }); - if(cards.length){ - player.$give(cards,player,false); - game.log(player,'将',cards,'置于了武将牌上'); - player.loseToSpecial(cards,'gzrehuaiyi').visible=true; - } - else event.finish(); - 'step 8' - player.addSkill('gzrehuaiyi_unmark'); - player.markSkill('gzrehuaiyi'); + if (cards.length) { + player.$give(cards, player, false); + game.log(player, "将", cards, "置于了武将牌上"); + player.loseToSpecial(cards, "gzrehuaiyi").visible = true; + } else event.finish(); + "step 8"; + player.addSkill("gzrehuaiyi_unmark"); + player.markSkill("gzrehuaiyi"); game.delayx(); }, - ai:{ - order:10, - result:{ - player:function(player,target){ - var map={}; - for(var i of ['red','black','none']){ - if(player.countCards('h',{color:i})) map[i]=true; + ai: { + order: 10, + result: { + player: function (player, target) { + var map = {}; + for (var i of ["red", "black", "none"]) { + if (player.countCards("h", { color: i })) map[i] = true; } - if(Object.keys(map).length<2) return 0; - var num=player.maxHp-player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); - }); - if(player.countCards('h',{color:'red'})<=num) return 1; - if(player.countCards('h',{color:'black'})<=num) return 1; + if (Object.keys(map).length < 2) return 0; + var num = + player.maxHp - + player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); + }); + if (player.countCards("h", { color: "red" }) <= num) return 1; + if (player.countCards("h", { color: "black" }) <= num) return 1; return 0; }, - } + }, }, - marktext:'异', - intro:{ - mark:function(dialog,storage,player){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); + marktext: "异", + intro: { + mark: function (dialog, storage, player) { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); }); - if(!cards||!cards.length) return; + if (!cards || !cards.length) return; dialog.addAuto(cards); }, - markcount:function(storage,player){ - return player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); + markcount: function (storage, player) { + return player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); }); }, - onunmark:function(storage,player){ - var cards=player.getCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); + onunmark: function (storage, player) { + var cards = player.getCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); }); - if(cards.length){ + if (cards.length) { player.loseToDiscardpile(cards); } }, }, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('gzrehuaiyi')) return num+(player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); - })>player.maxHp?0.5:-0.5); + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("gzrehuaiyi")) + return ( + num + + (player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); + }) > player.maxHp + ? 0.5 + : -0.5) + ); }, }, - subSkill:{ - unmark:{ - trigger:{player:'loseAfter'}, - filter:function(event,player){ - if(!event.ss||!event.ss.length) return false; - return !player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); + subSkill: { + unmark: { + trigger: { player: "loseAfter" }, + filter: function (event, player) { + if (!event.ss || !event.ss.length) return false; + return !player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); }); }, - charlotte:true, - forced:true, - silent:true, - content:function(){ - player.unmarkSkill('gzrehuaiyi'); - player.removeSkill('gzrehuaiyi_unmark'); + charlotte: true, + forced: true, + silent: true, + content: function () { + player.unmarkSkill("gzrehuaiyi"); + player.removeSkill("gzrehuaiyi_unmark"); }, }, }, }, - gzrezisui:{ - audio:'gzzisui', - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ - return !event.numFixed&&player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); - })>0; + gzrezisui: { + audio: "gzzisui", + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { + return ( + !event.numFixed && + player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); + }) > 0 + ); }, - forced:true, - content:function(){ - trigger.num+=player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); + forced: true, + content: function () { + trigger.num += player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); }); }, - group:'gzrezisui_die', - subSkill:{ - die:{ - audio:'gzzisui', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return player.countCards('s',function(card){ - return card.hasGaintag('gzrehuaiyi'); - })>player.maxHp; + group: "gzrezisui_die", + subSkill: { + die: { + audio: "gzzisui", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return ( + player.countCards("s", function (card) { + return card.hasGaintag("gzrehuaiyi"); + }) > player.maxHp + ); }, - forced:true, - content:function(){ + forced: true, + content: function () { player.die(); }, }, }, }, //南华老仙 - gztaidan:{ - derivation:'taipingyaoshu', - audio:'tianshu', - locked:true, - group:'gztaidan_taipingyaoshu', + gztaidan: { + derivation: "taipingyaoshu", + audio: "tianshu", + locked: true, + group: "gztaidan_taipingyaoshu", }, - gztaidan_taipingyaoshu:{ - equipSkill:true, - mod:{ - maxHandcard:function(player,num){ - if(!player.hasEmptySlot(2)) return; - if(player.hasSkill('huangjintianbingfu')){ - num+=player.getExpansions('huangjintianbingfu').length; + gztaidan_taipingyaoshu: { + equipSkill: true, + mod: { + maxHandcard: function (player, num) { + if (!player.hasEmptySlot(2)) return; + if (player.hasSkill("huangjintianbingfu")) { + num += player.getExpansions("huangjintianbingfu").length; } - return num+game.countPlayer(function(current){ - return current.isFriendOf(player); - }); - } + return ( + num + + game.countPlayer(function (current) { + return current.isFriendOf(player); + }) + ); + }, }, - audio:'tianshu', - inherit:'taipingyaoshu', - filter:function(event,player){ - if(!player.hasEmptySlot(2)) return false; - return lib.skill.taipingyaoshu.filter(event,player); + audio: "tianshu", + inherit: "taipingyaoshu", + filter: function (event, player) { + if (!player.hasEmptySlot(2)) return false; + return lib.skill.taipingyaoshu.filter(event, player); }, - noHidden:true, - ai:{ - effect:{ - target:function(card,player,target){ - if(!target.hasEmptySlot(2)) return; - if(player==target&&get.subtype(card)=='equip2'){ - if(get.equipValue(card)<=7.5) return 0; + noHidden: true, + ai: { + effect: { + target: function (card, player, target) { + if (!target.hasEmptySlot(2)) return; + if (player == target && get.subtype(card) == "equip2") { + if (get.equipValue(card) <= 7.5) return 0; } - return lib.skill.taipingyaoshu.ai.effect.target.apply(this,arguments); + return lib.skill.taipingyaoshu.ai.effect.target.apply(this, arguments); }, }, }, }, - gzrejinghe:{ - audio:'jinghe', - enable:'phaseUse', - usable:1, + gzrejinghe: { + audio: "jinghe", + enable: "phaseUse", + usable: 1, //delay:0, - content:function(){ - 'step 0' - if(!player.storage.gzrejinghe_tianshu){ - var list=lib.skill.gzrejinghe.derivation.slice(0); - list.remove('gzrejinghe_faq'); - var list2=list.slice(0,get.rand(0,list.length)); + content: function () { + "step 0"; + if (!player.storage.gzrejinghe_tianshu) { + var list = lib.skill.gzrejinghe.derivation.slice(0); + list.remove("gzrejinghe_faq"); + var list2 = list.slice(0, get.rand(0, list.length)); list.removeArray(list2); list.addArray(list2); - player.storage.gzrejinghe_tianshu=list; - } - else{ - var first=player.storage.gzrejinghe_tianshu[0]; + player.storage.gzrejinghe_tianshu = list; + } else { + var first = player.storage.gzrejinghe_tianshu[0]; player.storage.gzrejinghe_tianshu.remove(first); player.storage.gzrejinghe_tianshu.push(first); } - game.log(player,'转动了','#g“天书”'); - player.markSkill('gzrejinghe'); - var skill=player.storage.gzrejinghe_tianshu[0]; - event.skill=skill; - var cardname='gzrejinghe_'+skill; - lib.card[cardname]={ - fullimage:true, - image:'character:re_nanhualaoxian' + game.log(player, "转动了", "#g“天书”"); + player.markSkill("gzrejinghe"); + var skill = player.storage.gzrejinghe_tianshu[0]; + event.skill = skill; + var cardname = "gzrejinghe_" + skill; + lib.card[cardname] = { + fullimage: true, + image: "character:re_nanhualaoxian", }; - lib.translate[cardname]=get.translation(skill); - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,card){ - ui.create.dialog(get.translation(player)+'转动了“天书”',[[card],'card']).videoId=id; - },player,event.videoId,game.createCard(cardname,' ',' ')); + lib.translate[cardname] = get.translation(skill); + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, card) { + ui.create.dialog(get.translation(player) + "转动了“天书”", [ + [card], + "card", + ]).videoId = id; + }, + player, + event.videoId, + game.createCard(cardname, " ", " ") + ); game.delay(3); - 'step 1' - game.broadcastAll('closeDialog',event.videoId); - var targets=game.filterPlayer(current=>!current.hasSkill(event.skill)); - if(!targets.length){event.finish();return;} - player.chooseTarget('经合:令一名角色获得技能【'+get.translation(event.skill)+'】',function(card,player,target){ - return _status.event.targets.includes(target); - },true).set('ai',function(target){ - var player=_status.event.player; - return get.attitude(player,target); - }).set('targets',targets); - 'step 2' - if(result.bool){ - var target=result.targets[0],skill=event.skill; + "step 1"; + game.broadcastAll("closeDialog", event.videoId); + var targets = game.filterPlayer((current) => !current.hasSkill(event.skill)); + if (!targets.length) { + event.finish(); + return; + } + player + .chooseTarget( + "经合:令一名角色获得技能【" + get.translation(event.skill) + "】", + function (card, player, target) { + return _status.event.targets.includes(target); + }, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.attitude(player, target); + }) + .set("targets", targets); + "step 2"; + if (result.bool) { + var target = result.targets[0], + skill = event.skill; player.line(target); - player.addTempSkill('gzrejinghe_clear',{player:'phaseBegin'}); - target.addAdditionalSkills('gzrejinghe_'+player.playerid,skill); + player.addTempSkill("gzrejinghe_clear", { player: "phaseBegin" }); + target.addAdditionalSkills("gzrejinghe_" + player.playerid, skill); target.popup(skill); } }, - intro:{ - name:'写满技能的天书', - markcount:()=>8, - mark:function(dialog,storage,player){ - dialog.content.style['overflow-x']='visible'; - var list=player.storage.gzrejinghe_tianshu; - var core=document.createElement('div'); - var centerX=-10,centerY=80,radius=80; - var radian=Math.PI*2/list.length; - for(var i=0;i 8, + mark: function (dialog, storage, player) { + dialog.content.style["overflow-x"] = "visible"; + var list = player.storage.gzrejinghe_tianshu; + var core = document.createElement("div"); + var centerX = -10, + centerY = 80, + radius = 80; + var radian = (Math.PI * 2) / list.length; + for (var i = 0; i < list.length; i++) { + var td = document.createElement("div"); + td.innerHTML = get.translation(list[i]).slice(0, 1); + td.style.position = "absolute"; core.appendChild(td); - td.style.left=(centerX+radius*Math.sin(radian*i))+'px'; - td.style.top=(centerY-radius*Math.cos(radian*i))+'px'; + td.style.left = centerX + radius * Math.sin(radian * i) + "px"; + td.style.top = centerY - radius * Math.cos(radian * i) + "px"; } dialog.content.appendChild(core); }, }, - ai:{ - order:10, - result:{target:1}, + ai: { + order: 10, + result: { target: 1 }, }, - derivation:['gzrejinghe_faq','leiji','nhyinbing','nhhuoqi','nhguizhu','nhxianshou','nhlundao','nhguanyue','nhyanzheng'], - subSkill:{ - clear:{ - onremove:function(player){ - game.countPlayer(function(current){ - current.removeAdditionalSkills('gzrejinghe_'+player.playerid); + derivation: [ + "gzrejinghe_faq", + "leiji", + "nhyinbing", + "nhhuoqi", + "nhguizhu", + "nhxianshou", + "nhlundao", + "nhguanyue", + "nhyanzheng", + ], + subSkill: { + clear: { + onremove: function (player) { + game.countPlayer(function (current) { + current.removeAdditionalSkills("gzrejinghe_" + player.playerid); }); }, }, }, }, //张鲁·新 - gzrebushi:{ - onremove:true, - onunmark:true, - intro:{content:'mark'}, - group:'gzrebushi_give', - audio:'gzbushi', - trigger:{player:['phaseZhunbeiBegin','phaseAfter']}, - check:function(event,player){ - return event.name=='phase'; + gzrebushi: { + onremove: true, + onunmark: true, + intro: { content: "mark" }, + group: "gzrebushi_give", + audio: "gzbushi", + trigger: { player: ["phaseZhunbeiBegin", "phaseAfter"] }, + check: function (event, player) { + return event.name == "phase"; }, - forced:true, - locked:false, - content:function(){ - 'step 0' - if(trigger.name=='phaseZhunbei'){ - var num=game.countPlayer()-player.hp-2; - if(num>0) player.chooseToDiscard(num,'he',true); - } - else{ - player.addMark('gzrebushi',player.hp); + forced: true, + locked: false, + content: function () { + "step 0"; + if (trigger.name == "phaseZhunbei") { + var num = game.countPlayer() - player.hp - 2; + if (num > 0) player.chooseToDiscard(num, "he", true); + } else { + player.addMark("gzrebushi", player.hp); event.finish(); } - 'step 1' - player.removeMark('gzrebushi',player.countMark('gzrebushi')); - if(!player.hasMark('gzrebushi')) player.unmarkSkill('gzrebushi'); + "step 1"; + player.removeMark("gzrebushi", player.countMark("gzrebushi")); + if (!player.hasMark("gzrebushi")) player.unmarkSkill("gzrebushi"); }, - ai:{mingzhi_no:true}, - subSkill:{ - give:{ - trigger:{global:'phaseZhunbeiBegin'}, - filter:function(event,player){ - if(event.player==player) return false; - return player.hasMark('gzrebushi')&&player.countCards('he'); + ai: { mingzhi_no: true }, + subSkill: { + give: { + trigger: { global: "phaseZhunbeiBegin" }, + filter: function (event, player) { + if (event.player == player) return false; + return player.hasMark("gzrebushi") && player.countCards("he"); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCard(get.prompt('gzrebushi'),'he','失去1个“义舍”标记,将一张牌交给'+get.translation(trigger.player)+'并摸两张牌').set('ai',function(card){ - var player=_status.event.player; - var trigger=_status.event.getTrigger(); - var target=trigger.player; - var num=0,current=target; - while(current!=player){ - if(current.isFriendOf(player)&&!current.isTurnedOver()) num++; - current=current.next; - } - if(num>=player.countMark('gzrebushi')&&!target.isFriendOf(player)) return -1; - return 6-get.value(card); - }); - 'step 1' - if(result.bool){ - player.logSkill('gzrebushi',trigger.player); - player.removeMark('gzrebushi',1); - if(!player.hasMark('gzrebushi')) player.unmarkSkill('gzrebushi'); - trigger.player.gain(result.cards,player,'giveAuto'); + direct: true, + content: function () { + "step 0"; + player + .chooseCard( + get.prompt("gzrebushi"), + "he", + "失去1个“义舍”标记,将一张牌交给" + + get.translation(trigger.player) + + "并摸两张牌" + ) + .set("ai", function (card) { + var player = _status.event.player; + var trigger = _status.event.getTrigger(); + var target = trigger.player; + var num = 0, + current = target; + while (current != player) { + if (current.isFriendOf(player) && !current.isTurnedOver()) num++; + current = current.next; + } + if (num >= player.countMark("gzrebushi") && !target.isFriendOf(player)) + return -1; + return 6 - get.value(card); + }); + "step 1"; + if (result.bool) { + player.logSkill("gzrebushi", trigger.player); + player.removeMark("gzrebushi", 1); + if (!player.hasMark("gzrebushi")) player.unmarkSkill("gzrebushi"); + trigger.player.gain(result.cards, player, "giveAuto"); player.draw(2); } }, }, }, }, - gzremidao:{ - group:'gzremidao_change', - audio:'gzmidao', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - return !player.getExpansions('gzremidao').length; + gzremidao: { + group: "gzremidao_change", + audio: "gzmidao", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + return !player.getExpansions("gzremidao").length; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.draw(2); - 'step 1' - var cards=player.getCards('he'); - if(!cards.length) event.finish(); - else if(cards.length<=2) event._result={bool:true,cards:cards}; - else player.chooseCard(2,'he',true,'选择两张牌作为“米”'); - 'step 2' - if(result.bool) player.addToExpansion(result.cards,player,'give').gaintag.add('gzremidao'); + "step 1"; + var cards = player.getCards("he"); + if (!cards.length) event.finish(); + else if (cards.length <= 2) event._result = { bool: true, cards: cards }; + else player.chooseCard(2, "he", true, "选择两张牌作为“米”"); + "step 2"; + if (result.bool) + player.addToExpansion(result.cards, player, "give").gaintag.add("gzremidao"); }, - marktext:'米', - intro:{ - content:'expansion', - markcount:'expansion', + marktext: "米", + intro: { + content: "expansion", + markcount: "expansion", }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, - subSkill:{ - change:{ - trigger:{global:'judge'}, - filter:function(event,player){ - return player.getExpansions('gzremidao').length&&event.player.isAlive(); + subSkill: { + change: { + trigger: { global: "judge" }, + filter: function (event, player) { + return player.getExpansions("gzremidao").length && event.player.isAlive(); }, - direct:true, - content:function(){ - 'step 0' - var list=player.getExpansions('gzremidao'); - player.chooseButton([get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+get.translation(trigger.player.judging[0])+ - ','+get.prompt('gzremidao'),list,'hidden'],function(button){ - var card=button.link; - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(result==0) return 0.5; - return result*attitude; - }).set('judging',trigger.player.judging[0]).set('filterButton',function(button){ - var player=_status.event.player; - var card=button.link; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }); - 'step 1' - if(result.bool){ - event.forceDie=true; - player.respond(result.links,'gzremidao','highlight','noOrdering'); - result.cards=result.links; - var card=result.cards[0]; - event.card=card; - } - else event.finish(); - 'step 2' - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone) card.clone.classList.remove('thrownhighlight'); - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + direct: true, + content: function () { + "step 0"; + var list = player.getExpansions("gzremidao"); + player + .chooseButton( + [ + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("gzremidao"), + list, + "hidden", + ], + function (button) { + var card = button.link; + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (result == 0) return 0.5; + return result * attitude; + } + ) + .set("judging", trigger.player.judging[0]) + .set("filterButton", function (button) { + var player = _status.event.player; + var card = button.link; + var mod2 = game.checkMod( + card, + player, + "unchanged", + "cardEnabled2", + player + ); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + "unchanged", + "cardRespondable", + player + ); + if (mod != "unchanged") return mod; + return true; + }); + "step 1"; + if (result.bool) { + event.forceDie = true; + player.respond(result.links, "gzremidao", "highlight", "noOrdering"); + result.cards = result.links; + var card = result.cards[0]; + event.card = card; + } else event.finish(); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) card.clone.classList.remove("thrownhighlight"); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } player.$gain2(trigger.player.judging[0]); player.gain(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',card); + game.log(trigger.player, "的判定牌改为", card); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{rejudge:0.6}, + ai: { + rejudge: true, + tag: { rejudge: 0.6 }, }, }, }, }, //许贡 - gzbiaozhao:{ - audio:'biaozhao', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var players=game.filterPlayer(current=>current!=player); - if(players.length<2) return false; - for(var i=0;i current != player); + if (players.length < 2) return false; + for (var i = 0; i < players.length - 1; i++) { + for (var j = i + 1; j < players.length; j++) { + if (players[i].isEnemyOf(players[j])) return true; } } return false; }, - multitarget:true, - complexTarget:true, - complexSelect:true, - selectTarget:2, - filterTarget:function(card,player,target){ - if(target==player) return false; - var targets=ui.selected.targets; - if(targets.length==0) return player.canUse('zhibi',target); + multitarget: true, + complexTarget: true, + complexSelect: true, + selectTarget: 2, + filterTarget: function (card, player, target) { + if (target == player) return false; + var targets = ui.selected.targets; + if (targets.length == 0) return player.canUse("zhibi", target); return target.isEnemyOf(targets[0]); }, - targetprompt:['被知己知彼','获得牌'], - content:function(){ - 'step 0' - player.useCard({name:'zhibi',isCard:true},targets[0]); - 'step 1' - if(player.countCards('he')>0&&targets[1].isAlive()){ - player.chooseCard('he',true,'交给'+get.translation(targets[1])+'一张牌'); - } - else event.finish(); - 'step 2' - player.give(result.cards,targets[1]); + targetprompt: ["被知己知彼", "获得牌"], + content: function () { + "step 0"; + player.useCard({ name: "zhibi", isCard: true }, targets[0]); + "step 1"; + if (player.countCards("he") > 0 && targets[1].isAlive()) { + player.chooseCard("he", true, "交给" + get.translation(targets[1]) + "一张牌"); + } else event.finish(); + "step 2"; + player.give(result.cards, targets[1]); player.draw(); }, - ai:{ - order:6, - result:{ - player:function(player,target){ - if(ui.selected.targets.length) return 0.1; - return get.effect(target,{name:'zhibi'},player,player)+0.1; + ai: { + order: 6, + result: { + player: function (player, target) { + if (ui.selected.targets.length) return 0.1; + return get.effect(target, { name: "zhibi" }, player, player) + 0.1; }, - target:function(player,target){ - if(ui.selected.targets.length) return 2; + target: function (player, target) { + if (ui.selected.targets.length) return 2; return 0; }, }, }, }, - gzyechou:{ - audio:'yechou', - trigger:{player:'die'}, - forced:true, - forceDie:true, - skillAnimation:true, - animationColor:'gray', - logTarget:'source', - filter:function(event,player){ - return event.source&&event.source.isIn()&&player.canUse('sha',event.source,false); + gzyechou: { + audio: "yechou", + trigger: { player: "die" }, + forced: true, + forceDie: true, + skillAnimation: true, + animationColor: "gray", + logTarget: "source", + filter: function (event, player) { + return event.source && event.source.isIn() && player.canUse("sha", event.source, false); }, - content:function(){ - 'step 0' - var target=trigger.source; - event.target=target; - target.addTempSkill('gzyechou_unsavable'); - player.useCard({name:'sha',isCard:true},target).set('forceDie',true).set('oncard',function(){ - _status.event.directHit.addArray(game.filterPlayer()); - }); - 'step 1' - player.addTempSkill('gzyechou_unequip'); - if(!target.isIn()||!player.canUse('sha',target,false)){ - player.removeSkill('gzyechou_unequip'); + content: function () { + "step 0"; + var target = trigger.source; + event.target = target; + target.addTempSkill("gzyechou_unsavable"); + player + .useCard({ name: "sha", isCard: true }, target) + .set("forceDie", true) + .set("oncard", function () { + _status.event.directHit.addArray(game.filterPlayer()); + }); + "step 1"; + player.addTempSkill("gzyechou_unequip"); + if (!target.isIn() || !player.canUse("sha", target, false)) { + player.removeSkill("gzyechou_unequip"); event.goto(3); + } else { + player + .useCard( + { + name: "sha", + isCard: true, + storage: { gzyechou: true }, + }, + target + ) + .set("forceDie", true); } - else{ - player.useCard({ - name:'sha', - isCard:true, - storage:{gzyechou:true} - },target).set('forceDie',true); - } - 'step 2' - player.removeSkill('gzyechou_unequip'); - if(!target.isIn()||!player.canUse('sha',target,false)){ + "step 2"; + player.removeSkill("gzyechou_unequip"); + if (!target.isIn() || !player.canUse("sha", target, false)) { event.goto(3); - } - else player.useCard({name:'sha',isCard:true},target).set('forceDie',true).set('oncard',function(){ - _status.event.baseDamage++; - }); - 'step 3' - target.removeSkill('gzyechou_unsavable'); + } else + player + .useCard({ name: "sha", isCard: true }, target) + .set("forceDie", true) + .set("oncard", function () { + _status.event.baseDamage++; + }); + "step 3"; + target.removeSkill("gzyechou_unsavable"); }, - ai:{ - threaten:0.001, + ai: { + threaten: 0.001, }, - subSkill:{ - unsavable:{ - charlotte:true, - mod:{ - targetEnabled:function(card,player,target){ - if(card.name=='tao'&&target.isDying()&&player.isFriendOf(target)&&target!=player) return false; + subSkill: { + unsavable: { + charlotte: true, + mod: { + targetEnabled: function (card, player, target) { + if ( + card.name == "tao" && + target.isDying() && + player.isFriendOf(target) && + target != player + ) + return false; }, }, }, - unequip:{ - charlotte:true, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.card.storage||!arg.card.storage.gzyechou) return false; + unequip: { + charlotte: true, + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.card || !arg.card.storage || !arg.card.storage.gzyechou) + return false; }, }, }, }, }, //陈宫 - gzyinpan:{ - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current!=target&¤t.isEnemyOf(target) - }).sortBySeat(); - 'step 1' - if(!event.target.isIn()){ + gzyinpan: { + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return current != target && current.isEnemyOf(target); + }) + .sortBySeat(); + "step 1"; + if (!event.target.isIn()) { event.finish(); return; } - var target=targets.shift(); - if(target.isIn()&&(_status.connectMode||!lib.config.skip_shan||target.hasSha())){ - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'是否对'+get.translation(event.target)+'使用一张【杀】?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',event.target); + var target = targets.shift(); + if (target.isIn() && (_status.connectMode || !lib.config.skip_shan || target.hasSha())) { + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "是否对" + get.translation(event.target) + "使用一张【杀】?") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", event.target); } - if(targets.length>0) event.redo(); - 'step 2' - if(target.isIn()){ - var dying=false; - var num=target.getHistory('damage',function(evt){ - if(evt.card&&evt.card.name=='sha'){ - var evtx=evt.getParent('useCard'); - if(evt.card==evtx.card&&evtx.getParent(2)==event){ - if(evt._dyinged) dying=true; + if (targets.length > 0) event.redo(); + "step 2"; + if (target.isIn()) { + var dying = false; + var num = target.getHistory("damage", function (evt) { + if (evt.card && evt.card.name == "sha") { + var evtx = evt.getParent("useCard"); + if (evt.card == evtx.card && evtx.getParent(2) == event) { + if (evt._dyinged) dying = true; return true; } } }).length; - if(num>0){ - target.addTempSkill('gzyinpan_effect',{player:'phaseAfter'}); - target.addMark('gzyinpan_effect',num,false); - if(dying) target.recover(); + if (num > 0) { + target.addTempSkill("gzyinpan_effect", { player: "phaseAfter" }); + target.addMark("gzyinpan_effect", num, false); + if (dying) target.recover(); } } }, - ai:{ - order:1, - result:{target:-1}, + ai: { + order: 1, + result: { target: -1 }, }, - subSkill:{ - effect:{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.countMark('gzyinpan_effect'); + subSkill: { + effect: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.countMark("gzyinpan_effect"); }, }, - onremove:true, - charlotte:true, - intro:{content:'使用【杀】的次数上限+#'} + onremove: true, + charlotte: true, + intro: { content: "使用【杀】的次数上限+#" }, }, }, }, - gzxingmou:{ - trigger:{global:'gainAfter'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return event.getParent().name=='draw'&&event.getParent(2).name=='die'; + gzxingmou: { + trigger: { global: "gainAfter" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return event.getParent().name == "draw" && event.getParent(2).name == "die"; }, - content:function(){ + content: function () { player.draw(); }, - ai:{ - noDieAfter:true, - noDieAfter2:true, + ai: { + noDieAfter: true, + noDieAfter2: true, }, }, //朱儁 - gzgongjian:{ - audio:'gongjian', - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(!event.isFirstTarget||event.card.name!='sha') return false; - var history=game.getAllGlobalHistory('useCard',function(evt){ - return evt.card.name=='sha'; + gzgongjian: { + audio: "gongjian", + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (!event.isFirstTarget || event.card.name != "sha") return false; + var history = game.getAllGlobalHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - var evt=event.getParent(),index=history.indexOf(evt); - if(index<1) return false; - var evt0=history[index-1]; - for(var i of evt.targets){ - if(evt0.targets.includes(i)&&i.countCards('he')>0) return true; + var evt = event.getParent(), + index = history.indexOf(evt); + if (index < 1) return false; + var evt0 = history[index - 1]; + for (var i of evt.targets) { + if (evt0.targets.includes(i) && i.countCards("he") > 0) return true; } return false; }, - prompt2:'弃置这些角色的各两张牌', - preHidden:['gzgongjian_gain'], - subfrequent:['gain'], - logTarget:function(event,player){ - var history=game.getAllGlobalHistory('useCard',function(evt){ - return evt.card.name=='sha'; + prompt2: "弃置这些角色的各两张牌", + preHidden: ["gzgongjian_gain"], + subfrequent: ["gain"], + logTarget: function (event, player) { + var history = game.getAllGlobalHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - var evt=event.getParent(),index=history.indexOf(evt); - var evt0=history[index-1]; - return evt.targets.filter(function(target){ - return (evt0.targets.includes(target)&&target.countCards('he')>0); + var evt = event.getParent(), + index = history.indexOf(evt); + var evt0 = history[index - 1]; + return evt.targets.filter(function (target) { + return evt0.targets.includes(target) && target.countCards("he") > 0; }); }, - check:function(event,player){ - var targets=lib.skill.gzgongjian.logTarget(event,player),att=0; - for(var i of targets){ - att+=get.attitude(player,i); + check: function (event, player) { + var targets = lib.skill.gzgongjian.logTarget(event, player), + att = 0; + for (var i of targets) { + att += get.attitude(player, i); } - return att<0; + return att < 0; }, - content:function(){ - var history=game.getAllGlobalHistory('useCard',function(evt){ - return evt.card.name=='sha'; + content: function () { + var history = game.getAllGlobalHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - var evt=trigger.getParent(),index=history.indexOf(evt); - var evt0=history[index-1]; - var targets=evt.targets.filter(function(target){ - return evt0.targets.includes(target); - }).sortBySeat(); - for(var i of targets) i.chooseToDiscard(true,'he',2); + var evt = trigger.getParent(), + index = history.indexOf(evt); + var evt0 = history[index - 1]; + var targets = evt.targets + .filter(function (target) { + return evt0.targets.includes(target); + }) + .sortBySeat(); + for (var i of targets) i.chooseToDiscard(true, "he", 2); }, - group:'gzgongjian_gain', - subSkill:{ - gain:{ - audio:'gongjian', - trigger:{ - global:['loseAfter','loseAsyncAfter'], + group: "gzgongjian_gain", + subSkill: { + gain: { + audio: "gongjian", + trigger: { + global: ["loseAfter", "loseAsyncAfter"], }, - filter:function(event,player){ - if(event.name=='lose'){ - if(event.type!='discard'||event.player==player) return false; - if((event.discarder||event.getParent(event.getParent(2).name=='chooseToDiscard'?3:2).player)!=player) return false; - for(var i of event.cards2){ - if(i.name=='sha') return true; + filter: function (event, player) { + if (event.name == "lose") { + if (event.type != "discard" || event.player == player) return false; + if ( + (event.discarder || + event.getParent(event.getParent(2).name == "chooseToDiscard" ? 3 : 2) + .player) != player + ) + return false; + for (var i of event.cards2) { + if (i.name == "sha") return true; } - } - else if(event.type=='discard'){ - if(!event.discarder||event.discarder!=player) return false; - var cards=event.getd(null,'cards2'); - cards.removeArray(event.getd(player,'cards2')); - for(var i of cards){ - if(i.name=='sha') return true; + } else if (event.type == "discard") { + if (!event.discarder || event.discarder != player) return false; + var cards = event.getd(null, "cards2"); + cards.removeArray(event.getd(player, "cards2")); + for (var i of cards) { + if (i.name == "sha") return true; } } return false; }, - frequent:true, - prompt2:function(event,player){ - var cards=event.getd(null,'cards2'); - cards.removeArray(event.getd(player,'cards2')); - cards=cards.filter(card=>card.name=='sha'); - return '获得'+get.translation(cards); + frequent: true, + prompt2: function (event, player) { + var cards = event.getd(null, "cards2"); + cards.removeArray(event.getd(player, "cards2")); + cards = cards.filter((card) => card.name == "sha"); + return "获得" + get.translation(cards); }, - content:function(){ - var cards=trigger.getd(null,'cards2'); - cards.removeArray(trigger.getd(player,'cards2')); - cards=cards.filter(card=>card.name=='sha'); - if(cards.length) player.gain(cards,'gain2'); + content: function () { + var cards = trigger.getd(null, "cards2"); + cards.removeArray(trigger.getd(player, "cards2")); + cards = cards.filter((card) => card.name == "sha"); + if (cards.length) player.gain(cards, "gain2"); }, }, }, }, - gzkuimang:{ - audio:'kuimang', - trigger:{source:'die'}, - forced:true, - preHidden:true, - filter:function(event,player){ - var target=event.player; - if(target.isFriendOf(player)) return false; - var prev=target.getPrevious(),next=target.getNext(); - return (prev&&prev.isFriendOf(target))||(next&&next.isFriendOf(target)); + gzkuimang: { + audio: "kuimang", + trigger: { source: "die" }, + forced: true, + preHidden: true, + filter: function (event, player) { + var target = event.player; + if (target.isFriendOf(player)) return false; + var prev = target.getPrevious(), + next = target.getNext(); + return (prev && prev.isFriendOf(target)) || (next && next.isFriendOf(target)); }, - content:function(){ + content: function () { player.draw(2); }, }, //毌丘俭 - gzzhengrong:{ - audio:'drlt_zhenrong', - trigger:{ - source:'damageBegin3', - player:['damageBegin1','chooseJunlingForBegin'], + gzzhengrong: { + audio: "drlt_zhenrong", + trigger: { + source: "damageBegin3", + player: ["damageBegin1", "chooseJunlingForBegin"], }, - forced:true, - preHidden:true, - filter:function(event,player){ - if(event.name!='damage') return true; - if(player.identity!='unknown') return !game.hasPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); - }); - return !player.wontYe('wei')||!game.hasPlayer(current=>current.identity=='wei') + forced: true, + preHidden: true, + filter: function (event, player) { + if (event.name != "damage") return true; + if (player.identity != "unknown") + return !game.hasPlayer(function (current) { + return current != player && current.isFriendOf(player); + }); + return !player.wontYe("wei") || !game.hasPlayer((current) => current.identity == "wei"); }, - check:function(event,player){ - return !event.player.hasSkillTag('filterDamage',null,{ - player:event.source, - card:event.card, - })&&get.damageEffect(event.player,event.source,player,_status.event.player)>0; + check: function (event, player) { + return ( + !event.player.hasSkillTag("filterDamage", null, { + player: event.source, + card: event.card, + }) && get.damageEffect(event.player, event.source, player, _status.event.player) > 0 + ); }, - content:function(){ + content: function () { trigger.num++; }, - mod:{ - globalFrom:function(player,target,num){ - if(target.isMajor()) return num-1; + mod: { + globalFrom: function (player, target, num) { + if (target.isMajor()) return num - 1; }, }, - ai:{halfneg:true}, + ai: { halfneg: true }, }, - gzhongju:{ - audio:'drlt_hongju', - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - filterTarget:lib.filter.notMe, - content:function(){ - 'step 0' - player.awakenSkill('gzhongju'); - event.players=game.filterPlayer(function(current){ - return current!=player&¤t!=target; - }).sortBySeat(); + gzhongju: { + audio: "drlt_hongju", + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + filterTarget: lib.filter.notMe, + content: function () { + "step 0"; + player.awakenSkill("gzhongju"); + event.players = game + .filterPlayer(function (current) { + return current != player && current != target; + }) + .sortBySeat(); game.delayx(); - player.chooseJunlingFor(event.players[0]).set('prompt','请选择一项“军令”'); - 'step 1' - event.junling=result.junling; - event.targets=result.targets; - event.num=0; - player.carryOutJunling(player,event.junling,event.targets); - 'step 2' - if(num0?0:1; - }); + event.current + .chooseJunlingControl(player, event.junling, targets) + .set("prompt", "鸿举") + .set("choiceList", ["执行该军令", "不执行该军令,且被“调虎离山”化"]) + .set("ai", function () { + var evt = _status.event.getParent(2); + return get.junlingEffect( + evt.player, + evt.junling, + evt.current, + evt.targets, + evt.current + ) > 0 + ? 0 + : 1; + }); + } else event.goto(4); + "step 3"; + if (result.index == 0) { + event.current.carryOutJunling(player, event.junling, event.targets); + } else { + event.current.addTempSkill("diaohulishan"); } - else event.goto(4); - 'step 3' - if(result.index==0){ - event.current.carryOutJunling(player,event.junling,event.targets); - } - else{ - event.current.addTempSkill('diaohulishan'); - } - 'step 4' + "step 4"; game.delayx(); event.num++; - if(event.num=player.hp) return true; - return lib.skill.gzjingce.getDiscardNum()>=player.hp; + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + if (player.getHistory("useCard").length >= player.hp) return true; + return lib.skill.gzjingce.getDiscardNum() >= player.hp; }, - prompt2:function(event,player){ - var num1=player.getHistory('useCard').length,num2=lib.skill.gzjingce.getDiscardNum(); - if(num1>=player.hp&&num2>=player.hp) return '执行一套额外的摸牌阶段和出牌阶段'; - return '执行一个额外的'+(num1>num2?'出牌阶段':'摸牌阶段'); + prompt2: function (event, player) { + var num1 = player.getHistory("useCard").length, + num2 = lib.skill.gzjingce.getDiscardNum(); + if (num1 >= player.hp && num2 >= player.hp) return "执行一套额外的摸牌阶段和出牌阶段"; + return "执行一个额外的" + (num1 > num2 ? "出牌阶段" : "摸牌阶段"); }, - preHidden:true, - frequent:true, - content:function(){ - var num1=player.getHistory('useCard').length,num2=lib.skill.gzjingce.getDiscardNum(); - var num3=player.hp; - if(num2>=num3){ - var next=player.phaseDraw(); + preHidden: true, + frequent: true, + content: function () { + var num1 = player.getHistory("useCard").length, + num2 = lib.skill.gzjingce.getDiscardNum(); + var num3 = player.hp; + if (num2 >= num3) { + var next = player.phaseDraw(); event.next.remove(next); trigger.after.push(next); } - if(num1>=num3){ - var next=player.phaseUse(); + if (num1 >= num3) { + var next = player.phaseUse(); event.next.remove(next); trigger.after.push(next); } }, - ai:{threaten:2.6}, + ai: { threaten: 2.6 }, }, //黄权 - gzdianhu:{ - audio:'xinfu_dianhu', - trigger:{player:'showCharacterAfter'}, - forced:true, - filter:function(event,player){ - return event.toShow.includes('gz_xf_huangquan')&&!player.storage.gzdianhu_effect; + gzdianhu: { + audio: "xinfu_dianhu", + trigger: { player: "showCharacterAfter" }, + forced: true, + filter: function (event, player) { + return event.toShow.includes("gz_xf_huangquan") && !player.storage.gzdianhu_effect; }, - content:function(){ - 'step 0' - player.chooseTarget('请选择【点虎】的目标',true,'给一名角色标上“虎”标记。当你或你的队友对该角色造成伤害后摸一张牌。',lib.filter.notMe).set('ai',function(target){ - var player=_status.event.player; - var distance=game.countPlayer(function(current){ - if(current.isFriendOf(player)) return Math.pow(get.distance(current,target),1.2); + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【点虎】的目标", + true, + "给一名角色标上“虎”标记。当你或你的队友对该角色造成伤害后摸一张牌。", + lib.filter.notMe + ) + .set("ai", function (target) { + var player = _status.event.player; + var distance = game.countPlayer(function (current) { + if (current.isFriendOf(player)) + return Math.pow(get.distance(current, target), 1.2); + }); + return 10 / distance; }); - return 10/distance; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzdianhu',target); - target.markSkill('gzdianhu_mark'); - player.addSkill('gzdianhu_effect'); - player.markAuto('gzdianhu_effect',[target]); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzdianhu", target); + target.markSkill("gzdianhu_mark"); + player.addSkill("gzdianhu_effect"); + player.markAuto("gzdianhu_effect", [target]); } }, - subSkill:{ - mark:{ - mark:true, - marktext:'虎', - intro:{content:'已成为“点虎”目标'}, + subSkill: { + mark: { + mark: true, + marktext: "虎", + intro: { content: "已成为“点虎”目标" }, }, - effect:{ - trigger:{global:'damageEnd'}, - forced:true, - charlotte:true, - filter:function(event,player){ - if(!player.getStorage('gzdianhu_effect').includes(event.player)) return false; - var source=event.source; - return source&&source.isAlive()&&source.isFriendOf(player); + effect: { + trigger: { global: "damageEnd" }, + forced: true, + charlotte: true, + filter: function (event, player) { + if (!player.getStorage("gzdianhu_effect").includes(event.player)) return false; + var source = event.source; + return source && source.isAlive() && source.isFriendOf(player); }, - logTarget:'source', - content:function(){ + logTarget: "source", + content: function () { trigger.source.draw(); }, }, }, }, - gzjianji:{ - audio:'xinfu_jianji', - inherit:'xinfu_jianji', - filterTarget:true, - content:function(){ - 'step 0' - target.draw('visible'); - 'step 1' - var card=result[0]; - if(card&&game.hasPlayer(function(current){ - return target.canUse(card,current); - })&&get.owner(card)==target){ + gzjianji: { + audio: "xinfu_jianji", + inherit: "xinfu_jianji", + filterTarget: true, + content: function () { + "step 0"; + target.draw("visible"); + "step 1"; + var card = result[0]; + if ( + card && + game.hasPlayer(function (current) { + return target.canUse(card, current); + }) && + get.owner(card) == target + ) { target.chooseToUse({ - prompt:'是否使用'+get.translation(card)+'?', - filterCard:function(cardx,player,target){ - return cardx==_status.event.cardx; + prompt: "是否使用" + get.translation(card) + "?", + filterCard: function (cardx, player, target) { + return cardx == _status.event.cardx; }, - cardx:card, + cardx: card, }); } }, - ai:{ - order:10, - result:{target:1}, + ai: { + order: 10, + result: { target: 1 }, }, }, //杨婉 - gzyouyan:{ - audio:'youyan', - trigger:{ - player:'loseAfter', - global:'loseAsyncAfter', + gzyouyan: { + audio: "youyan", + trigger: { + player: "loseAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - if(event.type!='discard'||event.getlx===false||player!=_status.currentPhase) return false; - var evt=event.getl(player); - if(!evt||!evt.cards2||!evt.cards2.length) return false; - var list=[]; - for(var i of evt.cards2){ - list.add(get.suit(i,player)); - if(list.length>=lib.suit.length) return false; + filter: function (event, player) { + if (event.type != "discard" || event.getlx === false || player != _status.currentPhase) + return false; + var evt = event.getl(player); + if (!evt || !evt.cards2 || !evt.cards2.length) return false; + var list = []; + for (var i of evt.cards2) { + list.add(get.suit(i, player)); + if (list.length >= lib.suit.length) return false; } return true; }, - usable:1, - preHidden:true, - content:function(){ - var cards=get.cards(4); + usable: 1, + preHidden: true, + content: function () { + var cards = get.cards(4); game.cardsGotoOrdering(cards); - player.showCards(cards,get.translation(player)+'发动了【诱言】'); - var evt=trigger.getl(player); - var list=[]; - for(var i of evt.cards2){ - list.add(get.suit(i,player)); + player.showCards(cards, get.translation(player) + "发动了【诱言】"); + var evt = trigger.getl(player); + var list = []; + for (var i of evt.cards2) { + list.add(get.suit(i, player)); } - cards=cards.filter(card=>!list.includes(get.suit(card,false))); - if(cards.length) player.gain(cards,'gain2'); + cards = cards.filter((card) => !list.includes(get.suit(card, false))); + if (cards.length) player.gain(cards, "gain2"); }, - ai:{ - effect:{ - player_use:function(card,player,target){ - if(typeof card=='object'&&player==_status.currentPhase&& - (!player.storage.counttrigger||!player.storage.counttrigger.gzyouyan)&& - player.needsToDiscard()==1&&card.cards&&card.cards.filter(function(i){ - return get.position(i)=='h'; - }).length>0&&!get.tag(card,'draw')&&!get.tag(card,'gain')&&!get.tag(card,'discard')) return 'zeroplayertarget'; + ai: { + effect: { + player_use: function (card, player, target) { + if ( + typeof card == "object" && + player == _status.currentPhase && + (!player.storage.counttrigger || !player.storage.counttrigger.gzyouyan) && + player.needsToDiscard() == 1 && + card.cards && + card.cards.filter(function (i) { + return get.position(i) == "h"; + }).length > 0 && + !get.tag(card, "draw") && + !get.tag(card, "gain") && + !get.tag(card, "discard") + ) + return "zeroplayertarget"; }, }, }, }, - gzzhuihuan:{ - audio:'zhuihuan', - trigger:{player:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget([1,2],'选择至多两名角色获得“追还”效果').setHiddenSkill('gzzhuihuan').set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - 'step 1' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.logSkill('gzzhuihuan',targets); - event.targets=targets; - } - else event.finish(); - 'step 2' - var next=player.chooseTarget('选择一名角色获得反伤效果','被选择的目标角色下次受到伤害后,其对伤害来源造成1点伤害;未被选择的目标角色下次受到伤害后,伤害来源弃置两张牌。',function(card,player,target){ - return _status.event.getParent().targets.includes(target); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }); - if(targets.length>1) next.set('forced',true); - 'step 3' - for(var target of targets){ - player.addTempSkill('gzzhuihuan_timeout',{player:'phaseZhunbeiBegin'}); - var id='gzzhuihuan_'+player.playerid; - if(result.targets.includes(target)){ - player.line(target,'fire'); - target.addAdditionalSkill(id,'gzzhuihuan_damage'); - } - else{ - player.line(target,'thunder'); - target.addAdditionalSkill(id,'gzzhuihuan_discard'); + gzzhuihuan: { + audio: "zhuihuan", + trigger: { player: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget([1, 2], "选择至多两名角色获得“追还”效果") + .setHiddenSkill("gzzhuihuan") + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + "step 1"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.logSkill("gzzhuihuan", targets); + event.targets = targets; + } else event.finish(); + "step 2"; + var next = player + .chooseTarget( + "选择一名角色获得反伤效果", + "被选择的目标角色下次受到伤害后,其对伤害来源造成1点伤害;未被选择的目标角色下次受到伤害后,伤害来源弃置两张牌。", + function (card, player, target) { + return _status.event.getParent().targets.includes(target); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }); + if (targets.length > 1) next.set("forced", true); + "step 3"; + for (var target of targets) { + player.addTempSkill("gzzhuihuan_timeout", { player: "phaseZhunbeiBegin" }); + var id = "gzzhuihuan_" + player.playerid; + if (result.targets.includes(target)) { + player.line(target, "fire"); + target.addAdditionalSkill(id, "gzzhuihuan_damage"); + } else { + player.line(target, "thunder"); + target.addAdditionalSkill(id, "gzzhuihuan_discard"); } } }, - subSkill:{ - timeout:{ - charlotte:true, - onremove:function(player){ - var id='gzzhuihuan_'+player.playerid; - game.countPlayer((current)=>current.removeAdditionalSkill(id)); + subSkill: { + timeout: { + charlotte: true, + onremove: function (player) { + var id = "gzzhuihuan_" + player.playerid; + game.countPlayer((current) => current.removeAdditionalSkill(id)); }, }, - damage:{ - charlotte:true, - trigger:{player:'damageEnd'}, - forced:true, - forceDie:true, - filter:function(event,player){ - return event.source&&event.source.isAlive(); + damage: { + charlotte: true, + trigger: { player: "damageEnd" }, + forced: true, + forceDie: true, + filter: function (event, player) { + return event.source && event.source.isAlive(); }, - logTarget:'source', - content:function(){ - player.removeSkill('gzzhuihuan_damage'); + logTarget: "source", + content: function () { + player.removeSkill("gzzhuihuan_damage"); trigger.source.damage(); }, - mark:true, - marktext:'追', - intro:{ - content:'当你下次受到伤害后,你对伤害来源造成1点伤害。', + mark: true, + marktext: "追", + intro: { + content: "当你下次受到伤害后,你对伤害来源造成1点伤害。", }, - ai:{ - threaten:0.5, + ai: { + threaten: 0.5, }, }, - discard:{ - charlotte:true, - trigger:{player:'damageEnd'}, - forced:true, - forceDie:true, - filter:function(event,player){ - return event.source&&event.source.isAlive(); + discard: { + charlotte: true, + trigger: { player: "damageEnd" }, + forced: true, + forceDie: true, + filter: function (event, player) { + return event.source && event.source.isAlive(); }, - logTarget:'source', - content:function(){ - player.removeSkill('gzzhuihuan_discard'); - trigger.source.chooseToDiscard(2,'he',true); + logTarget: "source", + content: function () { + player.removeSkill("gzzhuihuan_discard"); + trigger.source.chooseToDiscard(2, "he", true); }, - mark:true, - marktext:'还', - intro:{ - content:'当你下次受到伤害后,你令伤害来源弃置两张牌。', + mark: true, + marktext: "还", + intro: { + content: "当你下次受到伤害后,你令伤害来源弃置两张牌。", }, - ai:{ - threaten:0.8, + ai: { + threaten: 0.8, }, }, }, }, //海外田豫 - gzzhenxi:{ - audio:'twzhenxi', - trigger:{player:'useCardToPlayered'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.target.countCards('he')||player.hasCard(function(card){ - return get.suit(card)=='diamond'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'lebu'},[card]),event.target); - },'he')||player.hasCard(function(card){ - return get.suit(card)=='club'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'bingliang'},[card]),event.target,false); - },'he')) return true; + gzzhenxi: { + audio: "twzhenxi", + trigger: { player: "useCardToPlayered" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if ( + event.target.countCards("he") || + player.hasCard(function (card) { + return ( + get.suit(card) == "diamond" && + get.type2(card) != "trick" && + player.canUse(get.autoViewAs({ name: "lebu" }, [card]), event.target) + ); + }, "he") || + player.hasCard(function (card) { + return ( + get.suit(card) == "club" && + get.type2(card) != "trick" && + player.canUse( + get.autoViewAs({ name: "bingliang" }, [card]), + event.target, + false + ) + ); + }, "he") + ) + return true; return false; }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - direct:true, - content:function(){ - 'step 0' - var target=trigger.target; - event.target=target; - var list=[],choiceList=[ - '弃置'+get.translation(target)+'一张牌', - '将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对'+get.translation(target)+'使用', - '背水!若其有暗置的武将牌且你的武将牌均明置,你依次执行上述两项' - ]; - if(target.countDiscardableCards(player,'he')) list.push('选项一'); - else choiceList[0]=''+choiceList[0]+''; - if(player.countCards('he',function(card){ - return get.suit(card)=='diamond'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'lebu'},[card]),target); - })||player.countCards('he',function(card){ - return get.suit(card)=='club'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'bingliang'},[card]),target); - })) list.push('选项二'); - else choiceList[1]=''+choiceList[1]+''; - if(target.isUnseen(2)&&!player.isUnseen(2)) list.push('背水!'); - else choiceList[2]=''+choiceList[2]+''; - player.chooseControl(list,'cancel2').set('prompt',get.prompt('gzzhenxi',target)).set('choiceList',choiceList).set('ai',function(){ - var player=_status.event.player,trigger=_status.event.getTrigger(),list=_status.event.list; - if(get.attitude(player,trigger.target)>0) return 'cancel2'; - if(list.includes('背水!')) return '背水!'; - if(list.includes('选项二')) return '选项二'; - return '选项一'; - }).set('list',list).set('hiddenSkill','gzzhenxi'); - 'step 1' - if(result.control=='cancel2'){ + direct: true, + content: function () { + "step 0"; + var target = trigger.target; + event.target = target; + var list = [], + choiceList = [ + "弃置" + get.translation(target) + "一张牌", + "将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对" + + get.translation(target) + + "使用", + "背水!若其有暗置的武将牌且你的武将牌均明置,你依次执行上述两项", + ]; + if (target.countDiscardableCards(player, "he")) list.push("选项一"); + else choiceList[0] = '' + choiceList[0] + ""; + if ( + player.countCards("he", function (card) { + return ( + get.suit(card) == "diamond" && + get.type2(card) != "trick" && + player.canUse(get.autoViewAs({ name: "lebu" }, [card]), target) + ); + }) || + player.countCards("he", function (card) { + return ( + get.suit(card) == "club" && + get.type2(card) != "trick" && + player.canUse(get.autoViewAs({ name: "bingliang" }, [card]), target) + ); + }) + ) + list.push("选项二"); + else choiceList[1] = '' + choiceList[1] + ""; + if (target.isUnseen(2) && !player.isUnseen(2)) list.push("背水!"); + else choiceList[2] = '' + choiceList[2] + ""; + player + .chooseControl(list, "cancel2") + .set("prompt", get.prompt("gzzhenxi", target)) + .set("choiceList", choiceList) + .set("ai", function () { + var player = _status.event.player, + trigger = _status.event.getTrigger(), + list = _status.event.list; + if (get.attitude(player, trigger.target) > 0) return "cancel2"; + if (list.includes("背水!")) return "背水!"; + if (list.includes("选项二")) return "选项二"; + return "选项一"; + }) + .set("list", list) + .set("hiddenSkill", "gzzhenxi"); + "step 1"; + if (result.control == "cancel2") { event.finish(); return; } - player.logSkill('gzzhenxi',target); - event.choice=result.control; - if(event.choice!='选项二'&&target.countDiscardableCards(player,'he')) player.discardPlayerCard(target,'he',true); - 'step 2' - if(event.choice!='选项一'&&(player.hasCard(function(card){ - return get.suit(card)=='diamond'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'lebu'},[card]),target); - },'he')||player.hasCard(function(card){ - return get.suit(card)=='club'&&get.type2(card)!='trick'&&player.canUse(get.autoViewAs({name:'bingliang'},[card]),target,false); - },'he'))){ - var next=game.createEvent('gzzhenxi_use'); - next.player=player; - next.target=target; + player.logSkill("gzzhenxi", target); + event.choice = result.control; + if (event.choice != "选项二" && target.countDiscardableCards(player, "he")) + player.discardPlayerCard(target, "he", true); + "step 2"; + if ( + event.choice != "选项一" && + (player.hasCard(function (card) { + return ( + get.suit(card) == "diamond" && + get.type2(card) != "trick" && + player.canUse(get.autoViewAs({ name: "lebu" }, [card]), target) + ); + }, "he") || + player.hasCard(function (card) { + return ( + get.suit(card) == "club" && + get.type2(card) != "trick" && + player.canUse( + get.autoViewAs({ name: "bingliang" }, [card]), + target, + false + ) + ); + }, "he")) + ) { + var next = game.createEvent("gzzhenxi_use"); + next.player = player; + next.target = target; next.setContent(lib.skill.gzzhenxi.contentx); } }, - ai:{unequip_ai:true}, - contentx:function(){ - 'step 0' + ai: { unequip_ai: true }, + contentx: function () { + "step 0"; player.chooseCard({ - position:'hes', - forced:true, - prompt:'震袭', - prompt2:'将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对'+get.translation(target)+'使用', - filterCard:function(card,player){ - if(get.itemtype(card)!='card'||get.type2(card)=='trick'||!['diamond','club'].includes(get.suit(card))) return false; - var cardx={name:get.suit(card)=='diamond'?'lebu':'bingliang'}; - return player.canUse(get.autoViewAs(cardx,[card]),_status.event.getParent().target,false); + position: "hes", + forced: true, + prompt: "震袭", + prompt2: + "将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对" + + get.translation(target) + + "使用", + filterCard: function (card, player) { + if ( + get.itemtype(card) != "card" || + get.type2(card) == "trick" || + !["diamond", "club"].includes(get.suit(card)) + ) + return false; + var cardx = { name: get.suit(card) == "diamond" ? "lebu" : "bingliang" }; + return player.canUse( + get.autoViewAs(cardx, [card]), + _status.event.getParent().target, + false + ); }, }); - 'step 1' - if(result.bool) player.useCard({name:get.suit(result.cards[0],player)=='diamond'?'lebu':'bingliang'},target,result.cards); + "step 1"; + if (result.bool) + player.useCard( + { name: get.suit(result.cards[0], player) == "diamond" ? "lebu" : "bingliang" }, + target, + result.cards + ); }, }, - gzjiansu:{ - init:function(player){ - if(player.checkViceSkill('gzjiansu')&&!player.viceChanged) player.removeMaxHp(); + gzjiansu: { + init: function (player) { + if (player.checkViceSkill("gzjiansu") && !player.viceChanged) player.removeMaxHp(); }, - viceSkill:true, - audio:2, - trigger:{ - player:'gainAfter', - global:'loseAsyncAfter', + viceSkill: true, + audio: 2, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", }, - filter:function(event,player){ - if(player==_status.currentPhase) return false; + filter: function (event, player) { + if (player == _status.currentPhase) return false; return event.getg(player).length; }, - frequent:true, - group:'gzjiansu_use', - preHidden:['gzjiansu_use'], - content:function(){ - player.showCards(trigger.getg(player),get.translation(player)+'发动了【俭素】'); - player.addGaintag(trigger.getg(player),'gzjiansu_tag'); - player.markSkill('gzjiansu'); + frequent: true, + group: "gzjiansu_use", + preHidden: ["gzjiansu_use"], + content: function () { + player.showCards(trigger.getg(player), get.translation(player) + "发动了【俭素】"); + player.addGaintag(trigger.getg(player), "gzjiansu_tag"); + player.markSkill("gzjiansu"); }, - intro:{ - mark:function(dialog,content,player){ - var hs=player.getCards('h',function(card){ - return card.hasGaintag('gzjiansu_tag'); + intro: { + mark: function (dialog, content, player) { + var hs = player.getCards("h", function (card) { + return card.hasGaintag("gzjiansu_tag"); }); - if(hs.length) dialog.addSmall(hs); - else dialog.addText('无已展示手牌'); + if (hs.length) dialog.addSmall(hs); + else dialog.addText("无已展示手牌"); }, - content:function(content,player){ - var hs=player.getCards('h',function(card){ - return card.hasGaintag('gzjiansu_tag'); + content: function (content, player) { + var hs = player.getCards("h", function (card) { + return card.hasGaintag("gzjiansu_tag"); }); - if(hs.length) return get.translation(hs); - else return '无已展示手牌'; + if (hs.length) return get.translation(hs); + else return "无已展示手牌"; }, }, - subSkill:{ - use:{ - audio:'gzjiansu', - trigger:{player:'phaseUseBegin'}, - filter:function(event,player){ - var num=player.countCards('h',function(card){ - return card.hasGaintag('gzjiansu_tag'); - }); - return num>0&&game.hasPlayer(function(current){ - return current.isDamaged()&¤t.getDamagedHp()<=num; + subSkill: { + use: { + audio: "gzjiansu", + trigger: { player: "phaseUseBegin" }, + filter: function (event, player) { + var num = player.countCards("h", function (card) { + return card.hasGaintag("gzjiansu_tag"); }); + return ( + num > 0 && + game.hasPlayer(function (current) { + return current.isDamaged() && current.getDamagedHp() <= num; + }) + ); }, - direct:true, - content:function(){ - 'step 0' - player.chooseCardTarget({ - prompt:get.prompt('gzjiansu'), - prompt2:'弃置任意张“俭”,令一名体力值不大于你以此法弃置的牌数的角色回复1点体力', - filterCard:function(card){ - return get.itemtype(card)=='card'&&card.hasGaintag('gzjiansu_tag'); - }, - selectCard:[1,Infinity], - filterTarget:function(card,player,target){ - return target.isDamaged(); - }, - filterOk:function(){ - return ui.selected.targets.length&&ui.selected.targets[0].hp<=ui.selected.cards.length; - }, - ai1:function(card){ - if(ui.selected.targets.length&&ui.selected.targets[0].hp<=ui.selected.cards.length) return 0; - return 6-get.value(card); - }, - ai2:function(target){ - var player=_status.event.player; - return get.recoverEffect(target,player,player); - }, - }).setHiddenSkill('gzjiansu_use'); - 'step 1' - if(result.bool){ - var target=result.targets[0],cards=result.cards; - player.logSkill('gzjiansu_use',target); + direct: true, + content: function () { + "step 0"; + player + .chooseCardTarget({ + prompt: get.prompt("gzjiansu"), + prompt2: + "弃置任意张“俭”,令一名体力值不大于你以此法弃置的牌数的角色回复1点体力", + filterCard: function (card) { + return ( + get.itemtype(card) == "card" && card.hasGaintag("gzjiansu_tag") + ); + }, + selectCard: [1, Infinity], + filterTarget: function (card, player, target) { + return target.isDamaged(); + }, + filterOk: function () { + return ( + ui.selected.targets.length && + ui.selected.targets[0].hp <= ui.selected.cards.length + ); + }, + ai1: function (card) { + if ( + ui.selected.targets.length && + ui.selected.targets[0].hp <= ui.selected.cards.length + ) + return 0; + return 6 - get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + return get.recoverEffect(target, player, player); + }, + }) + .setHiddenSkill("gzjiansu_use"); + "step 1"; + if (result.bool) { + var target = result.targets[0], + cards = result.cards; + player.logSkill("gzjiansu_use", target); player.discard(cards); target.recover(); } }, - } + }, }, }, //海外刘夫人 - gzzhuidu:{ - audio:'twzhuidu', - trigger:{source:'damageBegin3'}, - filter:function(event,player){ + gzzhuidu: { + audio: "twzhuidu", + trigger: { source: "damageBegin3" }, + filter: function (event, player) { return player.isPhaseUsing(); }, - check:function(event,player){ - return get.attitude(player,event.player)<0; + check: function (event, player) { + return get.attitude(player, event.player) < 0; }, - usable:1, - logTarget:'player', - content:function(){ - 'step 0' - var target=trigger.player; - event.target=target; - if(target.hasSex('female')&&target.countCards('e')>0) player.chooseToDiscard('he','追妒:是否弃置一张牌并令其执行两项?').set('ai',function(card){ - return 8-get.value(card); - }); + usable: 1, + logTarget: "player", + content: function () { + "step 0"; + var target = trigger.player; + event.target = target; + if (target.hasSex("female") && target.countCards("e") > 0) + player + .chooseToDiscard("he", "追妒:是否弃置一张牌并令其执行两项?") + .set("ai", function (card) { + return 8 - get.value(card); + }); else event.goto(2); - 'step 1' - if(result.bool){ - event._result={control:'我全都要!'}; + "step 1"; + if (result.bool) { + event._result = { control: "我全都要!" }; event.goto(3); } - 'step 2' - if(target.countCards('e')>0){ - target.chooseControl().set('prompt','追妒:请选择一项').set('choiceList',[ - '令'+get.translation(player)+'此次对你造成的伤害+1', - '弃置装备区里的所有牌', - ]).set('ai',function(){ - var player=_status.event.player,cards=player.getCards('e'); - if(player.hp<=2) return 1; - if(get.value(cards)<=7) return 1; - return 0; - }); - } - else event._result={control:'选项一'}; - 'step 3' + "step 2"; + if (target.countCards("e") > 0) { + target + .chooseControl() + .set("prompt", "追妒:请选择一项") + .set("choiceList", [ + "令" + get.translation(player) + "此次对你造成的伤害+1", + "弃置装备区里的所有牌", + ]) + .set("ai", function () { + var player = _status.event.player, + cards = player.getCards("e"); + if (player.hp <= 2) return 1; + if (get.value(cards) <= 7) return 1; + return 0; + }); + } else event._result = { control: "选项一" }; + "step 3"; player.line(target); - if(result.control!='选项二') trigger.num++; - if(result.control!='选项一') target.chooseToDiscard(target.countCards('e'),true,'e'); + if (result.control != "选项二") trigger.num++; + if (result.control != "选项一") target.chooseToDiscard(target.countCards("e"), true, "e"); }, }, - gzshigong:{ - audio:'twshigong', - trigger:{player:'dying'}, - filter:function(event,player){ - return _status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.isIn()&&player.hasViceCharacter()&&player.hp<=0; + gzshigong: { + audio: "twshigong", + trigger: { player: "dying" }, + filter: function (event, player) { + return ( + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.isIn() && + player.hasViceCharacter() && + player.hp <= 0 + ); }, - skillAnimation:true, - animationColor:'gray', - limited:true, - logTarget:()=>_status.currentPhase, - check:function(event,player){ - if(player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,event.player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,event.player); - return savable; - })>=1-event.player.hp) return false; + skillAnimation: true, + animationColor: "gray", + limited: true, + logTarget: () => _status.currentPhase, + check: function (event, player) { + if ( + player.countCards("h", function (card) { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + event.player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") savable = savable(card, player, event.player); + return savable; + }) >= + 1 - event.player.hp + ) + return false; return true; }, - content:function(){ - 'step 0' - var target=_status.currentPhase; - event.target=target; - player.awakenSkill('gzshigong'); - var list=lib.character[player.name2][3].filter(function(skill){ - return get.skillCategoriesOf(skill).length==0; + content: function () { + "step 0"; + var target = _status.currentPhase; + event.target = target; + player.awakenSkill("gzshigong"); + var list = lib.character[player.name2][3].filter(function (skill) { + return get.skillCategoriesOf(skill).length == 0; }); - if(!list.length){ - event._result={control:'cancel2'}; + if (!list.length) { + event._result = { control: "cancel2" }; event.goto(2); - } - else event.list=list; + } else event.list = list; player.removeCharacter(1); - 'step 1' - target.chooseControl(event.list,'cancel2').set('choiceList',event.list.map(i=>{ - return '
                        【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
                        '+get.skillInfoTranslation(i,_status.currentPhase)+'
                        '; - })).set('displayIndex',false).set('ai',function(){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0) return 0; - return [0,1].randomGet(); - }).set('prompt',get.translation(player)+'对你发动了【示恭】').set('prompt2','获得一个技能并令其将体力回复至体力上限;或点击“取消”,令其将体力值回复至1点。'); - 'step 2' - if(result.control=='cancel2'){ - player.recover(1-player.hp); + "step 1"; + target + .chooseControl(event.list, "cancel2") + .set( + "choiceList", + event.list.map((i) => { + return ( + '
                        【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
                        " + + get.skillInfoTranslation(i, _status.currentPhase) + + "
                        " + ); + }) + ) + .set("displayIndex", false) + .set("ai", function () { + if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) + return 0; + return [0, 1].randomGet(); + }) + .set("prompt", get.translation(player) + "对你发动了【示恭】") + .set( + "prompt2", + "获得一个技能并令其将体力回复至体力上限;或点击“取消”,令其将体力值回复至1点。" + ); + "step 2"; + if (result.control == "cancel2") { + player.recover(1 - player.hp); event.finish(); - } - else{ + } else { target.addSkills(result.control); target.line(player); - player.recover(player.maxHp-player.hp); + player.recover(player.maxHp - player.hp); } }, }, //海外服华雄 - gzyaowu:{ - audio:'new_reyaowu', - limited:true, - trigger:{source:'damageSource'}, - filter:function(event,player){ - if(player.isUnseen(0)&&lib.character[player.name1][3].includes('gzyaowu')) return true; - if(player.isUnseen(1)&&lib.character[player.name2][3].includes('gzyaowu')) return true; + gzyaowu: { + audio: "new_reyaowu", + limited: true, + trigger: { source: "damageSource" }, + filter: function (event, player) { + if (player.isUnseen(0) && lib.character[player.name1][3].includes("gzyaowu")) return true; + if (player.isUnseen(1) && lib.character[player.name2][3].includes("gzyaowu")) return true; return false; }, - skillAnimation:true, - animationColor:'fire', - check:function(event,player){ - return player.isDamaged()||player.hp<=2; + skillAnimation: true, + animationColor: "fire", + check: function (event, player) { + return player.isDamaged() || player.hp <= 2; }, - content:function(){ - player.awakenSkill('gzyaowu'); + content: function () { + player.awakenSkill("gzyaowu"); player.gainMaxHp(2); player.recover(2); - player.addSkill('gzyaowu_die'); + player.addSkill("gzyaowu_die"); }, - ai:{mingzhi_no:true}, - subSkill:{ - die:{ - audio:'new_reyaowu', - trigger:{player:'dieAfter'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); + ai: { mingzhi_no: true }, + subSkill: { + die: { + audio: "new_reyaowu", + trigger: { player: "dieAfter" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isFriendOf(player); }); }, - forced:true, - forceDie:true, - charlotte:true, - skillAnimation:true, - animationColor:'fire', - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); + forced: true, + forceDie: true, + charlotte: true, + skillAnimation: true, + animationColor: "fire", + logTarget: function (event, player) { + return game.filterPlayer(function (current) { + return current != player && current.isFriendOf(player); }); }, - content:function(){ - for(var target of lib.skill.gzyaowu_die.logTarget(trigger,player)) target.loseHp(); + content: function () { + for (var target of lib.skill.gzyaowu_die.logTarget(trigger, player)) + target.loseHp(); }, }, }, }, - gzshiyong:{ - audio:'shiyong', - derivation:'gzshiyongx', - trigger:{player:'damageEnd'}, - filter:function(event,player){ - if(!event.card) return false; - if(player.awakenedSkills.includes('gzyaowu')) return event.source&&event.source.isIn()&&get.color(event.card)!='black'; - return get.color(event.card)!='red'; + gzshiyong: { + audio: "shiyong", + derivation: "gzshiyongx", + trigger: { player: "damageEnd" }, + filter: function (event, player) { + if (!event.card) return false; + if (player.awakenedSkills.includes("gzyaowu")) + return event.source && event.source.isIn() && get.color(event.card) != "black"; + return get.color(event.card) != "red"; }, - forced:true, - logTarget:function(event,player){ - if(player.awakenedSkills.includes('gzyaowu')) return event.source; + forced: true, + logTarget: function (event, player) { + if (player.awakenedSkills.includes("gzyaowu")) return event.source; return; }, - content:function(){ - (lib.skill.gzshiyong.logTarget(trigger,player)||player).draw(); + content: function () { + (lib.skill.gzshiyong.logTarget(trigger, player) || player).draw(); }, }, //海外服夏侯尚 - gztanfeng:{ - audio:'twtanfeng', - trigger:{player:'phaseZhunbeiBegin'}, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return !current.isFriendOf(player)&¤t.countDiscardableCards('hej',player)>0; + gztanfeng: { + audio: "twtanfeng", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return ( + !current.isFriendOf(player) && current.countDiscardableCards("hej", player) > 0 + ); }); }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('gztanfeng'),function(card,player,target){ - return !target.isFriendOf(player)&&target.countDiscardableCards(player,'hej')>0; - }).set('ai',function(target){ - var player=_status.event.player; - if(target.hp+target.countCards('hs',{name:['tao','jiu']})<=2) return 3*get.effect(target,{name:'guohe'},player,player); - return get.effect(target,{name:'guohe'},player,player); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('gztanfeng',target); - player.discardPlayerCard(target,'hej',true); - } - else event.finish(); - 'step 2' - target.chooseBool('是否受到'+get.translation(player)+'造成的1点火焰伤害,令其跳过一个阶段?').set('ai',()=>_status.event.choice).set('choice',get.damageEffect(target,player,target)>=-5); - 'step 3' - if(result.bool){ + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gztanfeng"), function (card, player, target) { + return ( + !target.isFriendOf(player) && target.countDiscardableCards(player, "hej") > 0 + ); + }) + .set("ai", function (target) { + var player = _status.event.player; + if (target.hp + target.countCards("hs", { name: ["tao", "jiu"] }) <= 2) + return 3 * get.effect(target, { name: "guohe" }, player, player); + return get.effect(target, { name: "guohe" }, player, player); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gztanfeng", target); + player.discardPlayerCard(target, "hej", true); + } else event.finish(); + "step 2"; + target + .chooseBool( + "是否受到" + get.translation(player) + "造成的1点火焰伤害,令其跳过一个阶段?" + ) + .set("ai", () => _status.event.choice) + .set("choice", get.damageEffect(target, player, target) >= -5); + "step 3"; + if (result.bool) { player.line(target); - target.damage(1,'fire'); - } - else event.finish(); - 'step 4' - var list=[]; - var list2=[]; - event.map={phaseJudge:'判定阶段',phaseDraw:'摸牌阶段',phaseUse:'出牌阶段',phaseDiscard:'弃牌阶段'}; - for(var i of ['phaseJudge','phaseDraw','phaseUse','phaseDiscard']){ - if(!player.skipList.includes(i)){ - i=event.map[i]; + target.damage(1, "fire"); + } else event.finish(); + "step 4"; + var list = []; + var list2 = []; + event.map = { + phaseJudge: "判定阶段", + phaseDraw: "摸牌阶段", + phaseUse: "出牌阶段", + phaseDiscard: "弃牌阶段", + }; + for (var i of ["phaseJudge", "phaseDraw", "phaseUse", "phaseDiscard"]) { + if (!player.skipList.includes(i)) { + i = event.map[i]; list.push(i); - if(i!='判定阶段'&&i!='弃牌阶段') list2.push(i); + if (i != "判定阶段" && i != "弃牌阶段") list2.push(i); } } - target.chooseControl(list).set('prompt','探锋:令'+get.translation(player)+'跳过一个阶段').set('ai',function(){ - return _status.event.choice; - }).set('choice',function(){ - var att=get.attitude(target,player); - var num=player.countCards('j'); - if(att>0){ - if(list.includes('判定阶段')&&num>0) return '判定阶段'; - return '弃牌阶段'; - } - if(list.includes('摸牌阶段')&&player.hasJudge('lebu')) return '摸牌阶段'; - if(list.includes('出牌阶段')&&player.hasJudge('bingliang')||player.needsToDiscard()>0) return '出牌阶段'; - return list2.randomGet(); - }()); - 'step 5' - for(var i in event.map){ - if(event.map[i]==result.control) player.skip(i); + target + .chooseControl(list) + .set("prompt", "探锋:令" + get.translation(player) + "跳过一个阶段") + .set("ai", function () { + return _status.event.choice; + }) + .set( + "choice", + (function () { + var att = get.attitude(target, player); + var num = player.countCards("j"); + if (att > 0) { + if (list.includes("判定阶段") && num > 0) return "判定阶段"; + return "弃牌阶段"; + } + if (list.includes("摸牌阶段") && player.hasJudge("lebu")) return "摸牌阶段"; + if ( + (list.includes("出牌阶段") && player.hasJudge("bingliang")) || + player.needsToDiscard() > 0 + ) + return "出牌阶段"; + return list2.randomGet(); + })() + ); + "step 5"; + for (var i in event.map) { + if (event.map[i] == result.control) player.skip(i); } target.popup(result.control); target.line(player); - game.log(player,'跳过了','#y'+result.control); + game.log(player, "跳过了", "#y" + result.control); }, }, //杨芷 - gzwanyi:{ - audio:'wanyi', - enable:'phaseUse', - filter:function(event,player){ - if(player.getStorage('gzwanyi2').length>=4) return false; - if(_status.mode=='yingbian') return player.hasCard(function(i){ - return get.is.yingbian(i); - },'hs'); - return player.hasCard(function(card){ - return card.hasTag('lianheng'); - },'hs'); + gzwanyi: { + audio: "wanyi", + enable: "phaseUse", + filter: function (event, player) { + if (player.getStorage("gzwanyi2").length >= 4) return false; + if (_status.mode == "yingbian") + return player.hasCard(function (i) { + return get.is.yingbian(i); + }, "hs"); + return player.hasCard(function (card) { + return card.hasTag("lianheng"); + }, "hs"); }, - chooseButton:{ - dialog:function(event,player){ - var list=['lianjunshengyan','huoshaolianying','xietianzi','lulitongxin']; - if(_status.mode=='yingbian') list=['zhujinqiyuan','chuqibuyi','shuiyanqijunx','dongzhuxianji']; - list.removeArray(player.getStorage('gzwanyi2')); - return ui.create.dialog('婉嫕',[list,'vcard'],'hidden'); + chooseButton: { + dialog: function (event, player) { + var list = ["lianjunshengyan", "huoshaolianying", "xietianzi", "lulitongxin"]; + if (_status.mode == "yingbian") + list = ["zhujinqiyuan", "chuqibuyi", "shuiyanqijunx", "dongzhuxianji"]; + list.removeArray(player.getStorage("gzwanyi2")); + return ui.create.dialog("婉嫕", [list, "vcard"], "hidden"); }, - filter:function(button,player){ - return lib.filter.filterCard({name:button.link[2]},player,_status.event.getParent()); + filter: function (button, player) { + return lib.filter.filterCard( + { name: button.link[2] }, + player, + _status.event.getParent() + ); }, - check:function(button){ - return _status.event.player.getUseValue({name:button.link[2]}); + check: function (button) { + return _status.event.player.getUseValue({ name: button.link[2] }); }, - backup:function(links){ + backup: function (links) { return { - audio:'wanyi', - popname:true, - viewAs:{ - name:links[0][2], + audio: "wanyi", + popname: true, + viewAs: { + name: links[0][2], }, - filterCard:function(card){ - if(_status.mode=='yingbian') return get.is.yingbian(card); - return card.hasTag('lianheng'); + filterCard: function (card) { + if (_status.mode == "yingbian") return get.is.yingbian(card); + return card.hasTag("lianheng"); }, - check:function(card){ - return 1/Math.max(1,get.value(card)); + check: function (card) { + return 1 / Math.max(1, get.value(card)); }, - position:'hs', - onuse:function(links,player){ - if(!player.storage.gzwanyi2) player.storage.gzwanyi2=[]; + position: "hs", + onuse: function (links, player) { + if (!player.storage.gzwanyi2) player.storage.gzwanyi2 = []; player.storage.gzwanyi2.add(links.card.name); - player.addTempSkill('gzwanyi2'); + player.addTempSkill("gzwanyi2"); }, - } + }; }, - prompt:function(links){ - if(_status.mode=='yingbian') return '将一张应变牌当做'+get.translation(links[0][2])+'使用'; - return '将一张合纵牌当做'+get.translation(links[0][2])+'使用'; + prompt: function (links) { + if (_status.mode == "yingbian") + return "将一张应变牌当做" + get.translation(links[0][2]) + "使用"; + return "将一张合纵牌当做" + get.translation(links[0][2]) + "使用"; }, }, - subSkill:{backup:{}}, - ai:{order:8,result:{player:1}}, + subSkill: { backup: {} }, + ai: { order: 8, result: { player: 1 } }, }, - gzwanyi2:{onremove:true}, - gzmaihuo:{ - audio:'maihuo', - limited:true, - trigger:{global:'useCardToTarget'}, - logTarget:'player', - filter:function(event,player){ - return event.card.name=='sha'&&event.target.isIn()&&event.target.isFriendOf(player); + gzwanyi2: { onremove: true }, + gzmaihuo: { + audio: "maihuo", + limited: true, + trigger: { global: "useCardToTarget" }, + logTarget: "player", + filter: function (event, player) { + return event.card.name == "sha" && event.target.isIn() && event.target.isFriendOf(player); }, - preHidden:true, - skillAnimation:true, - animationColor:'thunder', - check:function(event,player){ - var source=event.player,targets=event.targets,card=event.card; - for(var target of targets){ - if(target.hasShan()||get.effect(target,card,source,player)>=0) continue; - if(player.hp<=1||target.hp<=(event.getParent().baseDamage||1)) return true; + preHidden: true, + skillAnimation: true, + animationColor: "thunder", + check: function (event, player) { + var source = event.player, + targets = event.targets, + card = event.card; + for (var target of targets) { + if (target.hasShan() || get.effect(target, card, source, player) >= 0) continue; + if (player.hp <= 1 || target.hp <= (event.getParent().baseDamage || 1)) return true; } return false; }, - content:function(){ - player.awakenSkill('gzmaihuo'); - trigger.targets.length=0; - trigger.getParent().triggeredTargets2.length=0; - player.addSkill('gzmaihuo_effect'); - player.markAuto('gzmaihuo_effect',[trigger.player]); - trigger.player.addMark('gzmaihuo_mark',1,false); + content: function () { + player.awakenSkill("gzmaihuo"); + trigger.targets.length = 0; + trigger.getParent().triggeredTargets2.length = 0; + player.addSkill("gzmaihuo_effect"); + player.markAuto("gzmaihuo_effect", [trigger.player]); + trigger.player.addMark("gzmaihuo_mark", 1, false); }, - subSkill:{ - effect:{ - audio:'maihuo', - trigger:{global:'phaseBegin'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return player.getStorage('gzmaihuo_effect').includes(event.player)&&event.player.canUse('sha',player,false); + subSkill: { + effect: { + audio: "maihuo", + trigger: { global: "phaseBegin" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return ( + player.getStorage("gzmaihuo_effect").includes(event.player) && + event.player.canUse("sha", player, false) + ); }, - content:function(){ - 'step 0' - var target=trigger.player; - player.unmarkAuto('gzmaihuo_effect',[target]); - target.removeMark('gzmaihuo_mark',1,false); - target.useCard({name:'sha',isCard:true},player,'gzmaihuo_effect',false); - 'step 1' - if(!player.getStorage('gzmaihuo_effect').length) player.removeSkill('gzmaihuo_effect'); + content: function () { + "step 0"; + var target = trigger.player; + player.unmarkAuto("gzmaihuo_effect", [target]); + target.removeMark("gzmaihuo_mark", 1, false); + target.useCard({ name: "sha", isCard: true }, player, "gzmaihuo_effect", false); + "step 1"; + if (!player.getStorage("gzmaihuo_effect").length) + player.removeSkill("gzmaihuo_effect"); }, - group:'gzmaihuo_remove', + group: "gzmaihuo_remove", }, - remove:{ - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - return event.card&&event.card.name=='sha'&&event.getParent().skill=='gzmaihuo_effect'; + remove: { + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + event.card.name == "sha" && + event.getParent().skill == "gzmaihuo_effect" + ); }, - content:function(){ + content: function () { trigger.cancel(); player.draw(2); - if(player.checkMainSkill('gzmaihuo',false)){ + if (player.checkMainSkill("gzmaihuo", false)) { player.removeCharacter(0); - } - else if(player.checkViceSkill('gzmaihuo',false)){ + } else if (player.checkViceSkill("gzmaihuo", false)) { player.changeVice(); } }, }, - mark:{ - marktext:'祸', - intro:{ - content:'mark', - onunmark:true, + mark: { + marktext: "祸", + intro: { + content: "mark", + onunmark: true, }, }, }, }, //羊徽瑜 - gzcaiyuan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - preHidden:true, - filter:function(event,player){ - var num1=player.countCards('h'),num2=num1; - player.getHistory('gain',function(evt){ - num2-=evt.cards.length; + gzcaiyuan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + forced: true, + preHidden: true, + filter: function (event, player) { + var num1 = player.countCards("h"), + num2 = num1; + player.getHistory("gain", function (evt) { + num2 -= evt.cards.length; }); - player.getHistory('lose',function(evt){ - if(evt.hs) num2+=evt.hs.length; + player.getHistory("lose", function (evt) { + if (evt.hs) num2 += evt.hs.length; }); - return num1>=num2; + return num1 >= num2; }, - content:function(){ - player.chooseDrawRecover(2,true); + content: function () { + player.chooseDrawRecover(2, true); }, }, //左棻 - gzzhaosong:{ - audio:'zhaosong', - enable:'phaseUse', - preHidden:['gzzhaosong_dying','gzzhaosong_sha'], - filter:function(event,player){ - return !player.getStorage('gzzhaosong').includes('效果②')&&game.hasPlayer((current)=>lib.skill.gzzhaosong.filterTarget(null,player,current)); + gzzhaosong: { + audio: "zhaosong", + enable: "phaseUse", + preHidden: ["gzzhaosong_dying", "gzzhaosong_sha"], + filter: function (event, player) { + return ( + !player.getStorage("gzzhaosong").includes("效果②") && + game.hasPlayer((current) => lib.skill.gzzhaosong.filterTarget(null, player, current)) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&(target.isUnseen(2)||target.countCards('h')>0); + filterTarget: function (card, player, target) { + return target != player && (target.isUnseen(2) || target.countCards("h") > 0); }, - promptfunc:()=>'出牌阶段,你可观看一名其他角色的所有暗置武将牌和手牌,然后可以获得其区域内的一张牌。', - content:function(){ - player.markAuto('gzzhaosong',['效果②']); - if(target.isUnseen(2)) player.viewCharacter(target,2); - if(target.countCards('hej')>0) player.gainPlayerCard(target,'hej','visible'); + promptfunc: () => + "出牌阶段,你可观看一名其他角色的所有暗置武将牌和手牌,然后可以获得其区域内的一张牌。", + content: function () { + player.markAuto("gzzhaosong", ["效果②"]); + if (target.isUnseen(2)) player.viewCharacter(target, 2); + if (target.countCards("hej") > 0) player.gainPlayerCard(target, "hej", "visible"); }, - ai:{ - order:11, - result:{ - player:function(player,target){ - return get.effect(target,{name:'zhibi'},player,player)+get.effect(target,{name:'shunshou_copy'},player,player); + ai: { + order: 11, + result: { + player: function (player, target) { + return ( + get.effect(target, { name: "zhibi" }, player, player) + + get.effect(target, { name: "shunshou_copy" }, player, player) + ); }, }, }, - group:['gzzhaosong_dying','gzzhaosong_sha'], - subSkill:{ - dying:{ - audio:'zhaosong', - trigger:{global:'dying'}, - logTarget:'player', - filter:function(event,player){ - return !player.getStorage('gzzhaosong').includes('效果①')&&event.player.isDying()&&event.player.hp<=0; + group: ["gzzhaosong_dying", "gzzhaosong_sha"], + subSkill: { + dying: { + audio: "zhaosong", + trigger: { global: "dying" }, + logTarget: "player", + filter: function (event, player) { + return ( + !player.getStorage("gzzhaosong").includes("效果①") && + event.player.isDying() && + event.player.hp <= 0 + ); }, - prompt2:'令该角色回复至2点体力并摸一张牌', - check:function(event,player){ - return event.player.isFriendOf(player)&&get.attitude(player,event.player)>0; + prompt2: "令该角色回复至2点体力并摸一张牌", + check: function (event, player) { + return event.player.isFriendOf(player) && get.attitude(player, event.player) > 0; }, - content:function(){ - player.markAuto('gzzhaosong',['效果①']); - var target=trigger.player,num=2-target.hp; - if(num>0) target.recover(num); + content: function () { + player.markAuto("gzzhaosong", ["效果①"]); + var target = trigger.player, + num = 2 - target.hp; + if (num > 0) target.recover(num); target.draw(); }, }, - sha:{ - audio:'zhaosong', - trigger:{global:'useCard2'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='sha'||player.getStorage('gzzhaosong').includes('效果③')) return false; - return game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.filterTarget(event.card,event.player,current); + sha: { + audio: "zhaosong", + trigger: { global: "useCard2" }, + direct: true, + filter: function (event, player) { + if (event.card.name != "sha" || player.getStorage("gzzhaosong").includes("效果③")) + return false; + return game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.filterTarget(event.card, event.player, current) + ); }); }, - content:function(){ - 'step 0' - player.chooseTarget([1,2],get.prompt('gzzhaosong'),'为'+get.translation(trigger.card)+'增加至多两个目标',function(card,player,target){ - var event=_status.event.getTrigger(); - return !event.targets.includes(target)&&lib.filter.filterTarget(event.card,event.player,target); - }).set('ai',function(target){ - var event=_status.event.getTrigger(); - return get.effect(target,event.card,event.player,_status.event.player); - }).set('goon',game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.filterTarget(trigger.card,trigger.player,current)&&get.effect(current,trigger.card,trigger.player,player)>0; - })>=Math.min(2,game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.filterTarget(trigger.card,trigger.player,current); - }))).setHiddenSkill('gzzhaosong_sha'); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - var targets=result.targets; - player.markAuto('gzzhaosong',['效果③']); - player.logSkill('gzzhaosong_sha',targets); + content: function () { + "step 0"; + player + .chooseTarget( + [1, 2], + get.prompt("gzzhaosong"), + "为" + get.translation(trigger.card) + "增加至多两个目标", + function (card, player, target) { + var event = _status.event.getTrigger(); + return ( + !event.targets.includes(target) && + lib.filter.filterTarget(event.card, event.player, target) + ); + } + ) + .set("ai", function (target) { + var event = _status.event.getTrigger(); + return get.effect(target, event.card, event.player, _status.event.player); + }) + .set( + "goon", + game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.filterTarget(trigger.card, trigger.player, current) && + get.effect(current, trigger.card, trigger.player, player) > 0 + ); + }) >= + Math.min( + 2, + game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.filterTarget( + trigger.card, + trigger.player, + current + ) + ); + }) + ) + ) + .setHiddenSkill("gzzhaosong_sha"); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + var targets = result.targets; + player.markAuto("gzzhaosong", ["效果③"]); + player.logSkill("gzzhaosong_sha", targets); trigger.targets.addArray(targets); }, }, }, }, - gzlisi:{ - audio:'lisi', - trigger:{global:'dieAfter'}, - filter:function(event,player){ - return event.player.isFriendOf(player)&&player.getStorage('gzzhaosong').length>0; + gzlisi: { + audio: "lisi", + trigger: { global: "dieAfter" }, + filter: function (event, player) { + return event.player.isFriendOf(player) && player.getStorage("gzzhaosong").length > 0; }, - direct:true, - content:function(){ - 'step 0' - var list=player.getStorage('gzzhaosong').slice(0); - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.prompt('gzlisi')).set('prompt2','恢复〖诏颂〗的一个已发动的选项'); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('gzlisi'); - player.unmarkAuto('gzzhaosong',[result.control]) + direct: true, + content: function () { + "step 0"; + var list = player.getStorage("gzzhaosong").slice(0); + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.prompt("gzlisi")) + .set("prompt2", "恢复〖诏颂〗的一个已发动的选项"); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("gzlisi"); + player.unmarkAuto("gzzhaosong", [result.control]); } }, }, //杨艳 - gzxuanbei:{ - audio:'xuanbei', - trigger:{player:'showCharacterAfter'}, - filter:function(event,player){ - return !player.storage.gzxuanbei&&event.toShow.includes('gz_yangyan'); + gzxuanbei: { + audio: "xuanbei", + trigger: { player: "showCharacterAfter" }, + filter: function (event, player) { + return !player.storage.gzxuanbei && event.toShow.includes("gz_yangyan"); }, - forced:true, - locked:false, - content:function(){ - 'step 0' - player.storage.gzxuanbei=true; - var cards=[]; - while(cards.length<2){ - var card=get.cardPile2(function(card){ - if(cards.includes(card)) return false; - return card.hasTag('lianheng')||get.is.yingbian(card); + forced: true, + locked: false, + content: function () { + "step 0"; + player.storage.gzxuanbei = true; + var cards = []; + while (cards.length < 2) { + var card = get.cardPile2(function (card) { + if (cards.includes(card)) return false; + return card.hasTag("lianheng") || get.is.yingbian(card); }); - if(!card) break; + if (!card) break; else cards.push(card); } - if(cards.length) player.gain(cards,'gain2'); - if(cards.length<2) player.draw(2-cards.length); - 'step 1' - player.addTempSkill('gzxuanbei_effect'); + if (cards.length) player.gain(cards, "gain2"); + if (cards.length < 2) player.draw(2 - cards.length); + "step 1"; + player.addTempSkill("gzxuanbei_effect"); }, - group:'gzxuanbei_change', - subSkill:{ - effect:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - charlotte:true, - filter:function(event,player){ - return get.cardtag(event.card,'lianheng'); + group: "gzxuanbei_change", + subSkill: { + effect: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + charlotte: true, + filter: function (event, player) { + return get.cardtag(event.card, "lianheng"); }, - content:function(){ + content: function () { player.draw(); }, - ai:{forceYingbian:true}, - mark:true, - intro:{content:'使用应变牌时直接获得强化,使用合纵牌时摸一张牌。'}, + ai: { forceYingbian: true }, + mark: true, + intro: { content: "使用应变牌时直接获得强化,使用合纵牌时摸一张牌。" }, }, - change:{ - audio:'xuanbei', - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('gzxuanbei'),'令一名其他角色变更副将',lib.filter.notMe).set('forceDie',true).set('ai',function(target){ - var player=_status.event.player; - var rank=get.guozhanRank(target.name2,target)<=3; - var att=get.attitude(player,target); - if(att>0){ - return (4-rank)*att; - } - return -(rank-6)*att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzxuanbei_change',target); + change: { + audio: "xuanbei", + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("gzxuanbei"), + "令一名其他角色变更副将", + lib.filter.notMe + ) + .set("forceDie", true) + .set("ai", function (target) { + var player = _status.event.player; + var rank = get.guozhanRank(target.name2, target) <= 3; + var att = get.attitude(player, target); + if (att > 0) { + return (4 - rank) * att; + } + return -(rank - 6) * att; + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzxuanbei_change", target); game.delayx(); target.changeVice(); } @@ -6331,228 +8754,264 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, //司马师 - gzyimie:{ - audio:'yimie', - inherit:'yimie', - init:function(player){ - if(player.checkMainSkill('gzyimie')){ + gzyimie: { + audio: "yimie", + inherit: "yimie", + init: function (player) { + if (player.checkMainSkill("gzyimie")) { player.removeMaxHp(2); } }, }, - gztairan:{ - audio:'tairan', - trigger:{player:'phaseUseBegin'}, - check:function(event,player){ - return player.isDamaged()&&player.hasCard(function(card){ - return 5.5-get.value(card); - },'he'); + gztairan: { + audio: "tairan", + trigger: { player: "phaseUseBegin" }, + check: function (event, player) { + return ( + player.isDamaged() && + player.hasCard(function (card) { + return 5.5 - get.value(card); + }, "he") + ); }, - content:function(){ - 'step 0' - var list=[],num=0; - if(player.isHealthy()||!player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'gztairan'); - },'he')) num=1; - event.num=num; - for(var i=num;i<=player.hp;i++){ - list.push(i+'点'); + content: function () { + "step 0"; + var list = [], + num = 0; + if ( + player.isHealthy() || + !player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "gztairan"); + }, "he") + ) + num = 1; + event.num = num; + for (var i = num; i <= player.hp; i++) { + list.push(i + "点"); } - player.chooseControl(list).set('prompt','###请先失去任意点体力###此回合结束时,你将恢复等量的体力'); - 'step 1' - var num1=result.index+num; - event.num1=num1; - if(num1>0) player.loseHp(num1); - 'step 2' - if(player.isDamaged()&&player.hasCard(function(card){ - return lib.filter.cardDiscardable(card,player,'gztairan') - },'he')){ - var next=player.chooseToDiscard('he',[1,player.getDamagedHp()],'然后请弃置任意张牌','此回合结束时,你将摸等量的牌。').set('ai',function(card){ - return 5.5-get.value(card); - }); - if(event.num1==0) next.set('forced',true); + player + .chooseControl(list) + .set("prompt", "###请先失去任意点体力###此回合结束时,你将恢复等量的体力"); + "step 1"; + var num1 = result.index + num; + event.num1 = num1; + if (num1 > 0) player.loseHp(num1); + "step 2"; + if ( + player.isDamaged() && + player.hasCard(function (card) { + return lib.filter.cardDiscardable(card, player, "gztairan"); + }, "he") + ) { + var next = player + .chooseToDiscard( + "he", + [1, player.getDamagedHp()], + "然后请弃置任意张牌", + "此回合结束时,你将摸等量的牌。" + ) + .set("ai", function (card) { + return 5.5 - get.value(card); + }); + if (event.num1 == 0) next.set("forced", true); } - 'step 3' - var num2=0; - if(result.bool) num2=result.cards.length; - var storage=[event.num1,num2]; - player.addTempSkill('gztairan_effect'); - player.storage.gztairan_effect=storage; + "step 3"; + var num2 = 0; + if (result.bool) num2 = result.cards.length; + var storage = [event.num1, num2]; + player.addTempSkill("gztairan_effect"); + player.storage.gztairan_effect = storage; }, - subSkill:{ - effect:{ - audio:'tairan', - trigger:{player:'phaseEnd'}, - filter:function(event,player){ - var storage=player.storage.gztairan_effect; - return storage&&storage.length==2&&(storage[1]>0||player.isDamaged()); + subSkill: { + effect: { + audio: "tairan", + trigger: { player: "phaseEnd" }, + filter: function (event, player) { + var storage = player.storage.gztairan_effect; + return storage && storage.length == 2 && (storage[1] > 0 || player.isDamaged()); }, - forced:true, - charlotte:true, - onremove:true, - content:function(){ - var storage=player.storage.gztairan_effect; - if(storage[0]>0) player.recover(storage[0]); - if(storage[1]>0) player.draw(storage[1]); + forced: true, + charlotte: true, + onremove: true, + content: function () { + var storage = player.storage.gztairan_effect; + if (storage[0] > 0) player.recover(storage[0]); + if (storage[1] > 0) player.draw(storage[1]); }, }, }, }, //杜预 - gzsanchen:{ - audio:'sanchen', - enable:'phaseUse', - filter(event,player){ - var stat=player.getStat('sanchen'); - return game.hasPlayer(function(current){ - return (!stat||!stat.includes(current)); + gzsanchen: { + audio: "sanchen", + enable: "phaseUse", + filter(event, player) { + var stat = player.getStat("sanchen"); + return game.hasPlayer(function (current) { + return !stat || !stat.includes(current); }); }, - filterTarget(card,player,target){ - var stat=player.getStat('sanchen'); - return (!stat||!stat.includes(target)); + filterTarget(card, player, target) { + var stat = player.getStat("sanchen"); + return !stat || !stat.includes(target); }, - usable:1, - content(){ - 'step 0' - if(!player._fakesanchen){ - player._fakesanchen=true; - player.when({global:'phaseAfter'}) - .then(()=>{ + usable: 1, + content() { + "step 0"; + if (!player._fakesanchen) { + player._fakesanchen = true; + player.when({ global: "phaseAfter" }).then(() => { delete player._fakesanchen; - if(player.hasMark('gzsanchen')){ - player.removeMark('gzsanchen',player.countMark('gzsanchen'),false); + if (player.hasMark("gzsanchen")) { + player.removeMark("gzsanchen", player.countMark("gzsanchen"), false); } }); } - var stat=player.getStat(); - if(!stat.sanchen) stat.sanchen=[]; + var stat = player.getStat(); + if (!stat.sanchen) stat.sanchen = []; stat.sanchen.push(target); target.draw(3); - 'step 1' - if(!target.countCards('he')) event.finish(); - else target.chooseToDiscard('he',true,3).set('ai',function(card){ - var list=ui.selected.cards.map(function(i){ - return get.type2(i); + "step 1"; + if (!target.countCards("he")) event.finish(); + else + target.chooseToDiscard("he", true, 3).set("ai", function (card) { + var list = ui.selected.cards.map(function (i) { + return get.type2(i); + }); + if (!list.includes(get.type2(card))) return 7 - get.value(card); + return -get.value(card); }); - if(!list.includes(get.type2(card))) return 7-get.value(card); - return -get.value(card); - }); - 'step 2' - if(result.bool&&result.cards&&result.cards.length){ - var list=[]; - for(var i of result.cards) list.add(get.type2(i)); - if(list.length==result.cards.length){ + "step 2"; + if (result.bool && result.cards && result.cards.length) { + var list = []; + for (var i of result.cards) list.add(get.type2(i)); + if (list.length == result.cards.length) { target.draw(); - player.getStat('skill').gzsanchen--; - player.addMark('gzsanchen',1,false); + player.getStat("skill").gzsanchen--; + player.addMark("gzsanchen", 1, false); } - } - else{ + } else { target.draw(); - player.getStat('skill').gzsanchen--; - player.addMark('gzsanchen',1,false); + player.getStat("skill").gzsanchen--; + player.addMark("gzsanchen", 1, false); } }, - ai:{ - order:9, - threaten:1.7, - result:{ - target(player,target){ - if(target.hasSkillTag('nogain')) return 0.1; - return Math.sqrt(target.countCards('he')); + ai: { + order: 9, + threaten: 1.7, + result: { + target(player, target) { + if (target.hasSkillTag("nogain")) return 0.1; + return Math.sqrt(target.countCards("he")); }, }, }, - marktext:'陈', - intro:{ - name2:'陈', - content:'mark', + marktext: "陈", + intro: { + name2: "陈", + content: "mark", }, }, - gzpozhu:{ - audio:'pozhu', - enable:'phaseUse', - mainSkill:true, - init(player){ - if(player.checkMainSkill('gzpozhu')) player.removeMaxHp(); + gzpozhu: { + audio: "pozhu", + enable: "phaseUse", + mainSkill: true, + init(player) { + if (player.checkMainSkill("gzpozhu")) player.removeMaxHp(); }, - viewAsFilter(player){ - return !player.hasSkill('pozhu3',null,null,false)&&player.countMark('gzsanchen')>0&&player.countCards('hs')>0; + viewAsFilter(player) { + return ( + !player.hasSkill("pozhu3", null, null, false) && + player.countMark("gzsanchen") > 0 && + player.countCards("hs") > 0 + ); }, - viewAs:{name:'chuqibuyi'}, - filterCard:true, - position:'hs', - check(card){ - return 7-get.value(card); + viewAs: { name: "chuqibuyi" }, + filterCard: true, + position: "hs", + check(card) { + return 7 - get.value(card); }, - onuse(result,player){ - player.removeMark('gzsanchen',1,false); + onuse(result, player) { + player.removeMark("gzsanchen", 1, false); }, }, //钟琰 - gzbolan:{ - audio:'bolan', - global:'gzbolan_global', - enable:'phaseUse', - usable:1, - content:function(){ - 'step 0' - if((event.num&&event.num>0)||!_status.characterlist.length){ + gzbolan: { + audio: "bolan", + global: "gzbolan_global", + enable: "phaseUse", + usable: 1, + content: function () { + "step 0"; + if ((event.num && event.num > 0) || !_status.characterlist.length) { event.finish(); return; } - var character=_status.characterlist.randomGet(); - var groups,double=get.is.double(character,true); - if(double) groups=double.slice(0); - else groups=[lib.character[character][1]]; - event.groups=groups; - event.videoId=lib.status.videoId++; - game.broadcastAll(function(player,id,character){ - ui.create.dialog(get.translation(player)+'发动了【博览】',[[character],'character']).videoId=id; - },player,event.videoId,character); + var character = _status.characterlist.randomGet(); + var groups, + double = get.is.double(character, true); + if (double) groups = double.slice(0); + else groups = [lib.character[character][1]]; + event.groups = groups; + event.videoId = lib.status.videoId++; + game.broadcastAll( + function (player, id, character) { + ui.create.dialog(get.translation(player) + "发动了【博览】", [ + [character], + "character", + ]).videoId = id; + }, + player, + event.videoId, + character + ); game.delay(3); - 'step 1' - game.broadcastAll('closeDialog',event.videoId); - var list1=['wei','shu','wu','qun','jin'],list2=['gzqice','tiaoxin','gzzhiheng','new_chuli','gzsanchen']; - var skills=[]; - for(var i=0;i0) return 3; - if(player.isHealthy()) return 1; + ai: { + order: 10, + result: { + player: function (player, target) { + if (get.effect(player, { name: "losehp" }, player, player) > 0) return 3; + if (player.isHealthy()) return 1; return -1; }, }, @@ -6561,191 +9020,250 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, //司马昭 - gzchoufa:{ - audio:'choufa', - inherit:'choufa', - content:function(){ - 'step 0' - player.choosePlayerCard(target,'h',true); - 'step 1' - player.showCards(result.cards,get.translation(player)+'对'+get.translation(target)+'发动了【筹伐】'); - var type=get.type2(result.cards[0],target),hs=target.getCards('h',function(card){ - return card!=result.cards[0]&&get.type2(card,target)!=type; - }); - if(hs.length){ - target.addGaintag(hs,'xinchoufa'); - target.addTempSkill('xinchoufa2'); + gzchoufa: { + audio: "choufa", + inherit: "choufa", + content: function () { + "step 0"; + player.choosePlayerCard(target, "h", true); + "step 1"; + player.showCards( + result.cards, + get.translation(player) + "对" + get.translation(target) + "发动了【筹伐】" + ); + var type = get.type2(result.cards[0], target), + hs = target.getCards("h", function (card) { + return card != result.cards[0] && get.type2(card, target) != type; + }); + if (hs.length) { + target.addGaintag(hs, "xinchoufa"); + target.addTempSkill("xinchoufa2"); } }, }, //张春华 - gzhuishi:{ - audio:2, - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ - return ui.discardPile.childNodes.length>0; + gzhuishi: { + audio: 2, + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { + return ui.discardPile.childNodes.length > 0; }, - preHidden:true, - prompt:function(){ - return get.prompt('huishi')+'(可观看牌数:'+lib.skill.gzhuishi.getNum()+')'; + preHidden: true, + prompt: function () { + return get.prompt("huishi") + "(可观看牌数:" + lib.skill.gzhuishi.getNum() + ")"; }, - check:function(event,player){ - return lib.skill.gzhuishi.getNum()>3; + check: function (event, player) { + return lib.skill.gzhuishi.getNum() > 3; }, - getNum:function(){ - var list=[]; + getNum: function () { + var list = []; list.push(ui.discardPile.lastChild); - if(list[0].previousSibling) list.push(list[0].previousSibling); - var num=0; - for(var i of list){ - var name=get.translation(i.name); - if(name=='挟令') name='挟天子以令诸侯'; - num+=name.length; + if (list[0].previousSibling) list.push(list[0].previousSibling); + var num = 0; + for (var i of list) { + var name = get.translation(i.name); + if (name == "挟令") name = "挟天子以令诸侯"; + num += name.length; } return num; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; trigger.changeToZero(); - var cards=game.cardsGotoOrdering(get.cards(lib.skill.gzhuishi.getNum())).cards; - var num=Math.ceil(cards.length/2); - var next=player.chooseToMove('慧识:将'+get.cnNumber(num)+'张牌置于牌堆底并获得其余的牌',true); - next.set('list',[ - ['牌堆顶的展示牌',cards], - ['牌堆底'], - ]); - next.set('filterMove',function(from,to,moved){ - if(moved[0].includes(from)&&to==1) return moved[1].length<_status.event.num; + var cards = game.cardsGotoOrdering(get.cards(lib.skill.gzhuishi.getNum())).cards; + var num = Math.ceil(cards.length / 2); + var next = player.chooseToMove( + "慧识:将" + get.cnNumber(num) + "张牌置于牌堆底并获得其余的牌", + true + ); + next.set("list", [["牌堆顶的展示牌", cards], ["牌堆底"]]); + next.set("filterMove", function (from, to, moved) { + if (moved[0].includes(from) && to == 1) return moved[1].length < _status.event.num; return true; }); - next.set('filterOk',function(moved){ - return moved[1].length==_status.event.num; + next.set("filterOk", function (moved) { + return moved[1].length == _status.event.num; }); - next.set('num',num); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.useful(a); + next.set("num", num); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.useful(a); }); - return [cards,cards.splice(cards.length-_status.event.num)]; + return [cards, cards.splice(cards.length - _status.event.num)]; }); - 'step 1' - if(result.bool){ - var list=result.moved; - if(list[0].length) player.gain(list[0],'gain2'); - while(list[1].length) ui.cardPile.appendChild(list[1].shift().fix()); + "step 1"; + if (result.bool) { + var list = result.moved; + if (list[0].length) player.gain(list[0], "gain2"); + while (list[1].length) ui.cardPile.appendChild(list[1].shift().fix()); } }, }, - gzqingleng:{ - audio:2, - trigger:{global:'phaseEnd'}, - direct:true, - preHidden:true, - filter:function(event,player){ - var target=event.player; - return target!=player&&target.isIn()&&target.isUnseen(2)&&player.countCards('he')>0&&player.canUse({name:'sha',nature:'ice'},target,false); + gzqingleng: { + audio: 2, + trigger: { global: "phaseEnd" }, + direct: true, + preHidden: true, + filter: function (event, player) { + var target = event.player; + return ( + target != player && + target.isIn() && + target.isUnseen(2) && + player.countCards("he") > 0 && + player.canUse({ name: "sha", nature: "ice" }, target, false) + ); }, - content:function(){ - 'step 0' - player.chooseCard('he',get.prompt('gzqingleng',trigger.player),'将一张牌当做冰【杀】对其使用',function(card,player){ - return player.canUse(get.autoViewAs({name:'sha',nature:'ice'},[card]),_status.event.target,false); - }).set('target',trigger.player).set('ai',function(card){ - if(get.effect(_status.event.target,get.autoViewAs({name:'sha',nature:'ice'},[card]),player)<=0) return false; - return 6-get.value(card); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.useCard(get.autoViewAs({name:'sha',nature:'ice'},result.cards),result.cards,false,trigger.player,'gzqingleng'); - if(trigger.player.isUnseen()){ + content: function () { + "step 0"; + player + .chooseCard( + "he", + get.prompt("gzqingleng", trigger.player), + "将一张牌当做冰【杀】对其使用", + function (card, player) { + return player.canUse( + get.autoViewAs({ name: "sha", nature: "ice" }, [card]), + _status.event.target, + false + ); + } + ) + .set("target", trigger.player) + .set("ai", function (card) { + if ( + get.effect( + _status.event.target, + get.autoViewAs({ name: "sha", nature: "ice" }, [card]), + player + ) <= 0 + ) + return false; + return 6 - get.value(card); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.useCard( + get.autoViewAs({ name: "sha", nature: "ice" }, result.cards), + result.cards, + false, + trigger.player, + "gzqingleng" + ); + if (trigger.player.isUnseen()) { player.draw(); } } }, }, //司马懿 - gzquanbian:{ - audio:'quanbian', - preHidden:true, - trigger:{player:['useCard','respond']}, - filter:function(event,player){ - if(player.hasSkill('gzquanbian_blocker')) return false; - var phase=event.getParent('phaseUse'); - if(!phase||phase.player!=player) return false; - var suit=get.suit(event.card); - if(!lib.suit.includes(suit)||!lib.skill.quanbian.hasHand(event)) return false; - return player.getHistory('useCard',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length+player.getHistory('respond',function(evt){ - return evt!=event&&get.suit(evt.card)==suit&&lib.skill.quanbian.hasHand(evt)&&evt.getParent('phaseUse')==phase; - }).length==0; + gzquanbian: { + audio: "quanbian", + preHidden: true, + trigger: { player: ["useCard", "respond"] }, + filter: function (event, player) { + if (player.hasSkill("gzquanbian_blocker")) return false; + var phase = event.getParent("phaseUse"); + if (!phase || phase.player != player) return false; + var suit = get.suit(event.card); + if (!lib.suit.includes(suit) || !lib.skill.quanbian.hasHand(event)) return false; + return ( + player.getHistory("useCard", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length + + player.getHistory("respond", function (evt) { + return ( + evt != event && + get.suit(evt.card) == suit && + lib.skill.quanbian.hasHand(evt) && + evt.getParent("phaseUse") == phase + ); + }).length == + 0 + ); }, - content:function(){ - 'step 0' - var cards=get.cards(player.maxHp); - for(var i=cards.length-1;i>=0;i--){ - ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); + content: function () { + "step 0"; + var cards = get.cards(player.maxHp); + for (var i = cards.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild); } game.updateRoundNumber(); - player.chooseButton(['权变:选择获得一张牌',cards],true).set('ai',function(button){ - var player=_status.event.player,card=button.link; - var suit=get.suit(card,false),val=get.value(card); - if(player.hasHistory('useCard',function(evt){ - return get.suit(evt.card,false)==suit; - })||player.hasHistory('respond',function(evt){ - return get.suit(evt.card,false)==suit; - })) return val; - return val+8; + player.chooseButton(["权变:选择获得一张牌", cards], true).set("ai", function (button) { + var player = _status.event.player, + card = button.link; + var suit = get.suit(card, false), + val = get.value(card); + if ( + player.hasHistory("useCard", function (evt) { + return get.suit(evt.card, false) == suit; + }) || + player.hasHistory("respond", function (evt) { + return get.suit(evt.card, false) == suit; + }) + ) + return val; + return val + 8; }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - player.gain(card,'gain2'); - var suit=get.suit(card,false); - if(player.hasHistory('useCard',function(evt){ - return get.suit(evt.card,false)==suit; - })||player.hasHistory('respond',function(evt){ - return get.suit(evt.card,false)==suit; - })) player.addTempSkill('gzquanbian_blocker'); + "step 1"; + if (result.bool) { + var card = result.links[0]; + player.gain(card, "gain2"); + var suit = get.suit(card, false); + if ( + player.hasHistory("useCard", function (evt) { + return get.suit(evt.card, false) == suit; + }) || + player.hasHistory("respond", function (evt) { + return get.suit(evt.card, false) == suit; + }) + ) + player.addTempSkill("gzquanbian_blocker"); } }, - subSkill:{blocker:{charlotte:true}}, + subSkill: { blocker: { charlotte: true } }, }, - gzxiongzhi:{ - audio:'xiongzhi', - enable:'phaseUse', - limited:true, - skillAnimation:true, - animationColor:'thunder', - content:function(){ - 'step 0' - player.awakenSkill('gzxiongzhi'); - event.cards=game.cardsGotoOrdering(get.cards(player.maxHp)).cards.slice(0); - 'step 1' - var card=cards.shift(); - event.card=card; + gzxiongzhi: { + audio: "xiongzhi", + enable: "phaseUse", + limited: true, + skillAnimation: true, + animationColor: "thunder", + content: function () { + "step 0"; + player.awakenSkill("gzxiongzhi"); + event.cards = game.cardsGotoOrdering(get.cards(player.maxHp)).cards.slice(0); + "step 1"; + var card = cards.shift(); + event.card = card; player.showCards(card); - if(!player.hasUseTarget(card)){ - if(cards.length>0) event.redo(); + if (!player.hasUseTarget(card)) { + if (cards.length > 0) event.redo(); else event.finish(); } - 'step 2' - var next=player.chooseUseTarget(card,true); - if(get.info(card).updateUsable=='phaseUse') next.addCount=false; - 'step 3' - if(result.bool&&cards.length>0) event.goto(1); + "step 2"; + var next = player.chooseUseTarget(card, true); + if (get.info(card).updateUsable == "phaseUse") next.addCount = false; + "step 3"; + if (result.bool && cards.length > 0) event.goto(1); }, - ai:{ - order:1, - result:{ - player:function(player){ - if(!player.hasSkill('smyyingshi')) return 1; - var cards=[]; - for(var i=0;i0; + check: function (event, player) { + return get.effect(event.player, { name: "guohe_copy2" }, player, player) > 0; }, - logTarget:'player', - content:function(){ - player.discardPlayerCard(trigger.player,true,'he'); + logTarget: "player", + content: function () { + player.discardPlayerCard(trigger.player, true, "he"); }, }, - gzmingfa:{ - audio:'dcmingfa', - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return player!=target&&target.isEnemyOf(player); + gzmingfa: { + audio: "dcmingfa", + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return player != target && target.isEnemyOf(player); }, - content:function(){ - player.markAuto('gzmingfa',targets); + content: function () { + player.markAuto("gzmingfa", targets); game.delayx(); }, - onremove:true, - ai:{ - order:1, - result:{target:-1}, + onremove: true, + ai: { + order: 1, + result: { target: -1 }, }, - group:'gzmingfa_effect', - subSkill:{ - effect:{ - audio:'dcmingfa', - trigger:{global:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return player.getStorage('gzmingfa').includes(event.player); + group: "gzmingfa_effect", + subSkill: { + effect: { + audio: "dcmingfa", + trigger: { global: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return player.getStorage("gzmingfa").includes(event.player); }, - logTarget:'player', - content:function(){ - var target=trigger.player; - player.unmarkAuto('gzmingfa',[target]); - if(target.isIn()){ - var num=player.countCards('h')-target.countCards('h'); - if(num>0){ + logTarget: "player", + content: function () { + var target = trigger.player; + player.unmarkAuto("gzmingfa", [target]); + if (target.isIn()) { + var num = player.countCards("h") - target.countCards("h"); + if (num > 0) { target.damage(); - player.gainPlayerCard(target,true,'h'); - } - else if(num<0){ - player.draw(Math.min(5,-num)); + player.gainPlayerCard(target, true, "h"); + } else if (num < 0) { + player.draw(Math.min(5, -num)); } } }, @@ -6823,158 +9352,191 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, //海外服国战 //杨修 - gzdanlao:{ - audio:'danlao', - inherit:'danlao', - preHidden:true, - filter:function(event,player){ - return get.type(event.card)=='trick'&&event.targets&&event.targets.length>1; + gzdanlao: { + audio: "danlao", + inherit: "danlao", + preHidden: true, + filter: function (event, player) { + return get.type(event.card) == "trick" && event.targets && event.targets.length > 1; }, }, - gzjilei:{ - inherit:'jilei', - preHidden:true, - content:function(){ - 'step 0' - player.chooseControl('basic','trick','equip','cancel2',function(){ - var source=_status.event.source; - if(get.attitude(_status.event.player,source)>0) return 'cancel2'; - var list=['basic','trick','equip'].filter(function(name){ - return (!source.storage.jilei2||!source.storage.jilei2.includes(name)); - }); - if(!list.length) return 'cancel2'; - if(list.includes('trick')&&source.countCards('h',function(card){ - return get.type(card,source)=='trick'&&source.hasValueTarget(card); - })>1) return 'trick'; - return list[0]; - }).set('prompt',get.prompt2('jilei',trigger.source)).set('source',trigger.source).setHiddenSkill('gzjilei'); - 'step 1' - if(result.control!='cancel2'){ - player.logSkill('gzjilei',trigger.source); - player.chat(get.translation(result.control)+'牌'); - game.log(player,'声明了','#y'+get.translation(result.control)+'牌'); - trigger.source.addTempSkill('jilei2'); + gzjilei: { + inherit: "jilei", + preHidden: true, + content: function () { + "step 0"; + player + .chooseControl("basic", "trick", "equip", "cancel2", function () { + var source = _status.event.source; + if (get.attitude(_status.event.player, source) > 0) return "cancel2"; + var list = ["basic", "trick", "equip"].filter(function (name) { + return !source.storage.jilei2 || !source.storage.jilei2.includes(name); + }); + if (!list.length) return "cancel2"; + if ( + list.includes("trick") && + source.countCards("h", function (card) { + return get.type(card, source) == "trick" && source.hasValueTarget(card); + }) > 1 + ) + return "trick"; + return list[0]; + }) + .set("prompt", get.prompt2("jilei", trigger.source)) + .set("source", trigger.source) + .setHiddenSkill("gzjilei"); + "step 1"; + if (result.control != "cancel2") { + player.logSkill("gzjilei", trigger.source); + player.chat(get.translation(result.control) + "牌"); + game.log(player, "声明了", "#y" + get.translation(result.control) + "牌"); + trigger.source.addTempSkill("jilei2"); trigger.source.storage.jilei2.add(result.control); - trigger.source.updateMarks('jilei2'); + trigger.source.updateMarks("jilei2"); game.delayx(); } }, }, //诸葛瑾 - gzhuanshi:{ - audio:'huanshi', - trigger:{global:'judge'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('hes')>0&&event.player.isFriendOf(player); + gzhuanshi: { + audio: "huanshi", + trigger: { global: "judge" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return player.countCards("hes") > 0 && event.player.isFriendOf(player); }, - content:function(){ - "step 0" - player.chooseCard(get.translation(trigger.player)+'的'+(trigger.judgestr||'')+'判定为'+ - get.translation(trigger.player.judging[0])+','+get.prompt('gzhuanshi'),'hes',function(card){ - var player=_status.event.player; - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,'unchanged','cardRespondable',player); - if(mod!='unchanged') return mod; - return true; - }).set('ai',function(card){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - var judging=_status.event.judging; - var result=trigger.judge(card)-trigger.judge(judging); - var attitude=get.attitude(player,trigger.player); - if(attitude==0||result==0) return 0; - if(attitude>0){ - return result-get.value(card)/2; - } - else{ - return -result-get.value(card)/2; - } - }).set('judging',trigger.player.judging[0]).setHiddenSkill('gzhuanshi'); - "step 1" - if(result.bool){ - player.respond(result.cards,'gzhuanshi','highlight','noOrdering'); - } - else{ + content: function () { + "step 0"; + player + .chooseCard( + get.translation(trigger.player) + + "的" + + (trigger.judgestr || "") + + "判定为" + + get.translation(trigger.player.judging[0]) + + "," + + get.prompt("gzhuanshi"), + "hes", + function (card) { + var player = _status.event.player; + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; + return true; + } + ) + .set("ai", function (card) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + var judging = _status.event.judging; + var result = trigger.judge(card) - trigger.judge(judging); + var attitude = get.attitude(player, trigger.player); + if (attitude == 0 || result == 0) return 0; + if (attitude > 0) { + return result - get.value(card) / 2; + } else { + return -result - get.value(card) / 2; + } + }) + .set("judging", trigger.player.judging[0]) + .setHiddenSkill("gzhuanshi"); + "step 1"; + if (result.bool) { + player.respond(result.cards, "gzhuanshi", "highlight", "noOrdering"); + } else { event.finish(); } - "step 2" - if(result.bool){ - if(trigger.player.judging[0].clone){ - trigger.player.judging[0].clone.classList.remove('thrownhighlight'); - game.broadcast(function(card){ - if(card.clone){ - card.clone.classList.remove('thrownhighlight'); + "step 2"; + if (result.bool) { + if (trigger.player.judging[0].clone) { + trigger.player.judging[0].clone.classList.remove("thrownhighlight"); + game.broadcast(function (card) { + if (card.clone) { + card.clone.classList.remove("thrownhighlight"); } - },trigger.player.judging[0]); - game.addVideo('deletenode',player,get.cardsInfo([trigger.player.judging[0].clone])); + }, trigger.player.judging[0]); + game.addVideo( + "deletenode", + player, + get.cardsInfo([trigger.player.judging[0].clone]) + ); } game.cardsDiscard(trigger.player.judging[0]); - trigger.player.judging[0]=result.cards[0]; + trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); - game.log(trigger.player,'的判定牌改为',result.cards[0]); + game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, - ai:{ - rejudge:true, - tag:{ - rejudge:1, - } - } + ai: { + rejudge: true, + tag: { + rejudge: 1, + }, + }, }, - gzhongyuan:{ - audio:'hongyuan', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.hasCard(function(card){ + gzhongyuan: { + audio: "hongyuan", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.hasCard(function (card) { return lib.skill.gzhongyuan.filterCard(card); - },'h'); + }, "h"); }, - filterCard:function(card){ - return !card.hasTag('lianheng')&&!card.hasGaintag('_lianheng'); + filterCard: function (card) { + return !card.hasTag("lianheng") && !card.hasGaintag("_lianheng"); }, - position:'h', - discard:false, - lose:false, - content:function(){ - cards[0].addGaintag('_lianheng'); - player.addTempSkill('gzhongyuan_clear') + position: "h", + discard: false, + lose: false, + content: function () { + cards[0].addGaintag("_lianheng"); + player.addTempSkill("gzhongyuan_clear"); }, - check:function(card){ - return 4.5-get.value(card); + check: function (card) { + return 4.5 - get.value(card); }, - group:'gzhongyuan_draw', - preHidden:true, - ai:{order:2,result:{player:1}}, - subSkill:{ - clear:{ - charlotte:true, - onremove:function(player){ - player.removeGaintag('_lianheng'); + group: "gzhongyuan_draw", + preHidden: true, + ai: { order: 2, result: { player: 1 } }, + subSkill: { + clear: { + charlotte: true, + onremove: function (player) { + player.removeGaintag("_lianheng"); }, }, - draw:{ - audio:'hongyuan', - trigger:{player:'drawBefore'}, - direct:true, - filter:function(event,player){ - return event.getParent().name=='_lianheng'&&game.hasPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); - }); + draw: { + audio: "hongyuan", + trigger: { player: "drawBefore" }, + direct: true, + filter: function (event, player) { + return ( + event.getParent().name == "_lianheng" && + game.hasPlayer(function (current) { + return current != player && current.isFriendOf(player); + }) + ); }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('gzhongyuan'),'将摸牌('+get.cnNumber(trigger.num)+'张)转移给一名同势力角色',function(card,player,target){ - return target!=player&&target.isFriendOf(player); - }).setHiddenSkill('gzhongyuan').set('ai',()=>-1); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzhongyuan',target); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("gzhongyuan"), + "将摸牌(" + get.cnNumber(trigger.num) + "张)转移给一名同势力角色", + function (card, player, target) { + return target != player && target.isFriendOf(player); + } + ) + .setHiddenSkill("gzhongyuan") + .set("ai", () => -1); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzhongyuan", target); trigger.cancel(); target.draw(trigger.num); } @@ -6982,1021 +9544,1267 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, }, - gzmingzhe:{ - audio:'mingzhe', - trigger:{ - player:['loseAfter','useCard','respond'], - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + gzmingzhe: { + audio: "mingzhe", + trigger: { + player: ["loseAfter", "useCard", "respond"], + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - if(player==_status.currentPhase) return false; - if(event.name=='useCard'||event.name=='respond'){ - return get.color(event.card,false)=='red'&&player.hasHistory('lose',function(evt){ - return evt.getParent()==event&&evt.hs&&evt.hs.length>0; - }); + filter: function (event, player) { + if (player == _status.currentPhase) return false; + if (event.name == "useCard" || event.name == "respond") { + return ( + get.color(event.card, false) == "red" && + player.hasHistory("lose", function (evt) { + return evt.getParent() == event && evt.hs && evt.hs.length > 0; + }) + ); } - var evt=event.getl(player); - if(!evt||!evt.es||!evt.es.length) return false; - for(var i of evt.es){ - if(get.color(i,player)=='red') return true; + var evt = event.getl(player); + if (!evt || !evt.es || !evt.es.length) return false; + for (var i of evt.es) { + if (get.color(i, player) == "red") return true; } return false; }, - frequent:true, - preHidden:true, - content:function(){ + frequent: true, + preHidden: true, + content: function () { player.draw(); }, }, //廖化 - gzdangxian:{ - trigger:{player:'phaseBegin'}, - forced:true, - preHidden:true, - audio:'dangxian', - audioname:['guansuo'], - content:function(){ - var next=player.phaseUse(); + gzdangxian: { + trigger: { player: "phaseBegin" }, + forced: true, + preHidden: true, + audio: "dangxian", + audioname: ["guansuo"], + content: function () { + var next = player.phaseUse(); event.next.remove(next); trigger.next.push(next); }, - group:'gzdangxian_show', - subSkill:{ - show:{ - audio:'dangxian', - trigger:{player:'showCharacterAfter'}, - forced:true, - filter:function(event,player){ - return event.toShow.includes('gz_liaohua')&&!player.storage.gzdangxian_draw; + group: "gzdangxian_show", + subSkill: { + show: { + audio: "dangxian", + trigger: { player: "showCharacterAfter" }, + forced: true, + filter: function (event, player) { + return event.toShow.includes("gz_liaohua") && !player.storage.gzdangxian_draw; }, - content:function(){ - player.storage.gzdangxian_draw=true; - player.addMark('xianqu_mark',1) + content: function () { + player.storage.gzdangxian_draw = true; + player.addMark("xianqu_mark", 1); }, }, }, }, //新国标2022 //许褚 - gzluoyi:{ - audio:'luoyi', - trigger:{player:'phaseDrawEnd'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('he')>0; + gzluoyi: { + audio: "luoyi", + trigger: { player: "phaseDrawEnd" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return player.countCards("he") > 0; }, - content:function(){ - 'step 0' - player.chooseToDiscard('he',get.prompt2('gzluoyi')).setHiddenSkill('gzluoyi').set('ai',function(card){ - var player=_status.event.player; - if(player.hasCard(function(cardx){ - if(cardx==card) return false; - return (cardx.name=='sha'||cardx.name=='juedou')&&player.hasValueTarget(cardx,null,true); - },'hs')) return 5-get.value(card); - return -get.value(card); - }).logSkill='gzluoyi'; - 'step 1' - if(result.bool) player.addTempSkill('gzluoyi_buff') + content: function () { + "step 0"; + player + .chooseToDiscard("he", get.prompt2("gzluoyi")) + .setHiddenSkill("gzluoyi") + .set("ai", function (card) { + var player = _status.event.player; + if ( + player.hasCard(function (cardx) { + if (cardx == card) return false; + return ( + (cardx.name == "sha" || cardx.name == "juedou") && + player.hasValueTarget(cardx, null, true) + ); + }, "hs") + ) + return 5 - get.value(card); + return -get.value(card); + }).logSkill = "gzluoyi"; + "step 1"; + if (result.bool) player.addTempSkill("gzluoyi_buff"); }, - subSkill:{ - buff:{ - audio:'luoyi', - charlotte:true, - forced:true, - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return event.card&&(event.card.name=='sha'||event.card.name=='juedou')&&event.getParent().type=='card'; + subSkill: { + buff: { + audio: "luoyi", + charlotte: true, + forced: true, + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return ( + event.card && + (event.card.name == "sha" || event.card.name == "juedou") && + event.getParent().type == "card" + ); }, - content:function(){ + content: function () { trigger.num++; }, }, }, }, //典韦 - gzqiangxi:{ - audio:'qiangxi', - inherit:'qiangxi', - filterTarget:function(card,player,target){ - return target!=player; + gzqiangxi: { + audio: "qiangxi", + inherit: "qiangxi", + filterTarget: function (card, player, target) { + return target != player; }, }, //小乔 - gztianxiang:{ - audio:'tianxiang', - audioname:['daxiaoqiao','re_xiaoqiao','ol_xiaoqiao'], - trigger:{player:'damageBegin4'}, - direct:true, - preHidden:true, - usable:1, - filter:function(event,player){ - return player.countCards('h',function(card){ - return _status.connectMode||get.suit(card,player)=='heart'; - })>0&&event.num>0; + gztianxiang: { + audio: "tianxiang", + audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"], + trigger: { player: "damageBegin4" }, + direct: true, + preHidden: true, + usable: 1, + filter: function (event, player) { + return ( + player.countCards("h", function (card) { + return _status.connectMode || get.suit(card, player) == "heart"; + }) > 0 && event.num > 0 + ); }, - content:function(){ - "step 0" - player.chooseCardTarget({ - filterCard:function(card,player){ - return get.suit(card)=='heart'&&lib.filter.cardDiscardable(card,player); - }, - filterTarget:function(card,player,target){ - return player!=target; - }, - ai1:function(card){ - return 10-get.value(card); - }, - ai2:function(target){ - var att=get.attitude(_status.event.player,target); - var trigger=_status.event.getTrigger(); - var da=0; - if(_status.event.player.hp==1){ - da=10; - } - var eff=get.damageEffect(target,trigger.source,target); - if(att==0) return 0.1+da; - if(eff>=0&&att>0){ - return att+da; - } - if(att>0&&target.hp>1){ - if(target.maxHp-target.hp>=3) return att*1.1+da; - if(target.maxHp-target.hp>=2) return att*0.9+da; - } - return -att+da; - }, - prompt:get.prompt('gztianxiang'), - prompt2:lib.translate.gztianxiang_info - }).setHiddenSkill(event.name); - "step 1" - if(result.bool){ + content: function () { + "step 0"; + player + .chooseCardTarget({ + filterCard: function (card, player) { + return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player); + }, + filterTarget: function (card, player, target) { + return player != target; + }, + ai1: function (card) { + return 10 - get.value(card); + }, + ai2: function (target) { + var att = get.attitude(_status.event.player, target); + var trigger = _status.event.getTrigger(); + var da = 0; + if (_status.event.player.hp == 1) { + da = 10; + } + var eff = get.damageEffect(target, trigger.source, target); + if (att == 0) return 0.1 + da; + if (eff >= 0 && att > 0) { + return att + da; + } + if (att > 0 && target.hp > 1) { + if (target.maxHp - target.hp >= 3) return att * 1.1 + da; + if (target.maxHp - target.hp >= 2) return att * 0.9 + da; + } + return -att + da; + }, + prompt: get.prompt("gztianxiang"), + prompt2: lib.translate.gztianxiang_info, + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { player.discard(result.cards); - var target=result.targets[0]; - player.chooseControlList(true,function(event,player){ - var target=_status.event.target; - var att=get.attitude(player,target); - if(target.hasSkillTag('maihp')) att=-att; - if(att>0){ - return 0; - } - else{ - return 1; - } - }, - ['令'+get.translation(target)+'受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)', - '令'+get.translation(target)+'失去1点体力,然后获得'+get.translation(result.cards)]).set('target',target); - player.logSkill(event.name,target); + var target = result.targets[0]; + player + .chooseControlList( + true, + function (event, player) { + var target = _status.event.target; + var att = get.attitude(player, target); + if (target.hasSkillTag("maihp")) att = -att; + if (att > 0) { + return 0; + } else { + return 1; + } + }, + [ + "令" + + get.translation(target) + + "受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)", + "令" + + get.translation(target) + + "失去1点体力,然后获得" + + get.translation(result.cards), + ] + ) + .set("target", target); + player.logSkill(event.name, target); trigger.cancel(); - event.target=target; - event.card=result.cards[0]; - } - else{ + event.target = target; + event.card = result.cards[0]; + } else { player.storage.counttrigger.gztianxiang--; event.finish(); } - "step 2" - if(typeof result.index=='number'){ - event.index=result.index; - if(result.index){ - event.related=event.target.loseHp(); + "step 2"; + if (typeof result.index == "number") { + event.index = result.index; + if (result.index) { + event.related = event.target.loseHp(); + } else { + event.related = event.target.damage(trigger.source || "nosource", "nocard"); } - else{ - event.related=event.target.damage(trigger.source||'nosource','nocard'); - } - } - else event.finish(); - "step 3" + } else event.finish(); + "step 3"; //if(event.related.cancelled||target.isDead()) return; - if(event.index&&card.isInPile()) target.gain(card,'gain2'); - else if(target.getDamagedHp()) target.draw(Math.min(5,target.getDamagedHp())); + if (event.index && card.isInPile()) target.gain(card, "gain2"); + else if (target.getDamagedHp()) target.draw(Math.min(5, target.getDamagedHp())); }, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(get.tag(card,'damage')&&target.countCards('he')>1) return 0.7; - } + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (get.tag(card, "damage") && target.countCards("he") > 1) return 0.7; + }, }, - } + }, }, - gzhongyan:{ - mod:{ - suit:function(card,suit){ - if(suit=='spade') return 'heart'; + gzhongyan: { + mod: { + suit: function (card, suit) { + if (suit == "spade") return "heart"; }, - maxHandcard:function(player,num){ - if(player.hasCard(function(card){ - return get.suit(card,player)=='heart'; - },'e')) return num+1; + maxHandcard: function (player, num) { + if ( + player.hasCard(function (card) { + return get.suit(card, player) == "heart"; + }, "e") + ) + return num + 1; }, - } + }, }, //黄忠 - gzliegong:{ - audio:'liegong', - locked:false, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&target.countCards('h')0) return 2; - return target.mayHaveShan(player,'use',target.getCards('h',i=>{ - return i.hasGaintag('sha_notshan'); - }))?1:0; - }); - 'step 1' - if(result.control!='cancel2'){ - var target=trigger.target; - player.logSkill('gzliegong',target); - if(result.index==1){ - game.log(trigger.card,'不可被',target,'响应'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + var str = get.translation(trigger.target), + card = get.translation(trigger.card); + player + .chooseControl("cancel2") + .set("choiceList", [ + "令" + card + "对" + str + "的伤害+1", + "令" + str + "不能响应" + card, + ]) + .set("prompt", get.prompt("gzliegong", trigger.target)) + .setHiddenSkill("gzliegong") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getTrigger().target; + if (get.attitude(player, target) > 0) return 2; + return target.mayHaveShan( + player, + "use", + target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ? 1 + : 0; + }); + "step 1"; + if (result.control != "cancel2") { + var target = trigger.target; + player.logSkill("gzliegong", target); + if (result.index == 1) { + game.log(trigger.card, "不可被", target, "响应"); trigger.directHit.add(target); - } - else { - game.log(trigger.card,'对',target,'的伤害+1'); - var map=trigger.getParent().customArgs,id=target.playerid; - if(!map[id]) map[id]={}; - if(!map[id].extraDamage) map[id].extraDamage=0; + } else { + game.log(trigger.card, "对", target, "的伤害+1"); + var map = trigger.getParent().customArgs, + id = target.playerid; + if (!map[id]) map[id] = {}; + if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; } } }, }, //潘凤 - gzkuangfu:{ - audio:'kuangfu', - trigger:{player:'useCardToPlayered'}, - shaRelated:true, - preHidden:true, - logTarget:'target', - filter:function(event,player){ - return event.card.name=='sha'&&player.isPhaseUsing()&&!player.hasSkill('gzkuangfu_extra')&&event.target.countGainableCards(player,'e')>0; + gzkuangfu: { + audio: "kuangfu", + trigger: { player: "useCardToPlayered" }, + shaRelated: true, + preHidden: true, + logTarget: "target", + filter: function (event, player) { + return ( + event.card.name == "sha" && + player.isPhaseUsing() && + !player.hasSkill("gzkuangfu_extra") && + event.target.countGainableCards(player, "e") > 0 + ); }, - check:function(event,player){ - if(get.attitude(player,event.target)>0||!event.target.hasCard(function(card){ - return lib.filter.canBeGained(card,player,event.target)&&get.value(card,event.target)>0; - },'e')) return false; + check: function (event, player) { + if ( + get.attitude(player, event.target) > 0 || + !event.target.hasCard(function (card) { + return ( + lib.filter.canBeGained(card, player, event.target) && + get.value(card, event.target) > 0 + ); + }, "e") + ) + return false; return true; }, - content:function(){ - trigger.getParent()._gzkuangfued=true; - player.gainPlayerCard(trigger.target,'e',true); - player.addTempSkill('gzkuangfu_extra','phaseUseAfter'); + content: function () { + trigger.getParent()._gzkuangfued = true; + player.gainPlayerCard(trigger.target, "e", true); + player.addTempSkill("gzkuangfu_extra", "phaseUseAfter"); }, - subSkill:{ - extra:{ - trigger:{player:'useCardAfter'}, - charlotte:true, - forced:true, - filter:function(event,player){ - return event._gzkuangfued&&!player.hasHistory('sourceDamage',function(evt){ - return evt.card&&event.card; - })&&player.countCards('h')>0; + subSkill: { + extra: { + trigger: { player: "useCardAfter" }, + charlotte: true, + forced: true, + filter: function (event, player) { + return ( + event._gzkuangfued && + !player.hasHistory("sourceDamage", function (evt) { + return evt.card && event.card; + }) && + player.countCards("h") > 0 + ); }, - content:function(){ - player.chooseToDiscard('h',2,true); + content: function () { + player.chooseToDiscard("h", 2, true); }, }, }, }, //吕布 - gzwushuang:{ - shaRelated:true, - audio:'wushuang', - audioname:['re_lvbu','shen_lvbu','lvlingqi'], - forced:true, - locked:true, - group:['wushuang1','wushuang2'], - preHidden:['wushuang1','wushuang2','gzwushuang'], - trigger:{player:'useCard1'}, - direct:true, - filter:function(event,player){ - if(event.card.name!='juedou'||!event.card.isCard) return false; - if(event.targets){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current); - })){ + gzwushuang: { + shaRelated: true, + audio: "wushuang", + audioname: ["re_lvbu", "shen_lvbu", "lvlingqi"], + forced: true, + locked: true, + group: ["wushuang1", "wushuang2"], + preHidden: ["wushuang1", "wushuang2", "gzwushuang"], + trigger: { player: "useCard1" }, + direct: true, + filter: function (event, player) { + if (event.card.name != "juedou" || !event.card.isCard) return false; + if (event.targets) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var num=game.countPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(trigger.card,player,current); + content: function () { + "step 0"; + var num = game.countPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(trigger.card, player, current) + ); }); - player.chooseTarget('无双:是否为'+get.translation(trigger.card)+'增加'+(num>1?'至多两个':'一个')+'目标?',[1,Math.min(2,num)],function(card,player,target){ - var trigger=_status.event.getTrigger(); - var card=trigger.card; - return !trigger.targets.includes(target)&&lib.filter.targetEnabled2(card,player,target); - }).set('ai',function(target){ - var player=_status.event.player; - var card=_status.event.getTrigger().card; - return get.effect(target,card,player,player); - }).setHiddenSkill('gzwushuang'); - 'step 1' - if(result.bool){ - if(player!=game.me&&!player.isOnline()) game.delayx(); - } - else event.finish(); - 'step 2' - var targets=result.targets.sortBySeat(); - player.logSkill('gzwushuang',targets); + player + .chooseTarget( + "无双:是否为" + + get.translation(trigger.card) + + "增加" + + (num > 1 ? "至多两个" : "一个") + + "目标?", + [1, Math.min(2, num)], + function (card, player, target) { + var trigger = _status.event.getTrigger(); + var card = trigger.card; + return ( + !trigger.targets.includes(target) && + lib.filter.targetEnabled2(card, player, target) + ); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + var card = _status.event.getTrigger().card; + return get.effect(target, card, player, player); + }) + .setHiddenSkill("gzwushuang"); + "step 1"; + if (result.bool) { + if (player != game.me && !player.isOnline()) game.delayx(); + } else event.finish(); + "step 2"; + var targets = result.targets.sortBySeat(); + player.logSkill("gzwushuang", targets); trigger.targets.addArray(targets); }, }, //夏侯渊 - gzshensu:{ - audio:'shensu1', - audioname:['xiahouba','re_xiahouyuan','ol_xiahouyuan'], - group:['shensu1','shensu2'], - preHidden:['shensu1','shensu2','gzshensu'], - trigger:{player:'phaseDiscardBegin'}, - direct:true, - filter:function(event,player){ - return player.hp>0; + gzshensu: { + audio: "shensu1", + audioname: ["xiahouba", "re_xiahouyuan", "ol_xiahouyuan"], + group: ["shensu1", "shensu2"], + preHidden: ["shensu1", "shensu2", "gzshensu"], + trigger: { player: "phaseDiscardBegin" }, + direct: true, + filter: function (event, player) { + return player.hp > 0; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('gzshensu'),'失去1点体力并跳过弃牌阶段,视为对一名其他角色使用使用一张无距离限制的【杀】',function(card,player,target){ - return player.canUse('sha',target,false); - }).setHiddenSkill('gzshensu').set('goon',player.needsToDiscard()).set('ai',function(target){ - var player=_status.event.player; - if(!_status.event.goon||player.hp<=target.hp) return false; - return get.effect(target,{name:'sha',isCard:true},player,player); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzshensu',target); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("gzshensu"), + "失去1点体力并跳过弃牌阶段,视为对一名其他角色使用使用一张无距离限制的【杀】", + function (card, player, target) { + return player.canUse("sha", target, false); + } + ) + .setHiddenSkill("gzshensu") + .set("goon", player.needsToDiscard()) + .set("ai", function (target) { + var player = _status.event.player; + if (!_status.event.goon || player.hp <= target.hp) return false; + return get.effect(target, { name: "sha", isCard: true }, player, player); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzshensu", target); player.loseHp(); trigger.cancel(); - player.useCard({name:'sha',isCard:true},target,false); + player.useCard({ name: "sha", isCard: true }, target, false); } }, }, //吕玲绮 - gzshenwei:{ - audio:'llqshenwei', - mainSkill:true, - init:function(player){ - if(player.checkMainSkill('gzshenwei')){ + gzshenwei: { + audio: "llqshenwei", + mainSkill: true, + init: function (player) { + if (player.checkMainSkill("gzshenwei")) { player.removeMaxHp(); } }, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:(event,player)=>!event.numFixed&&player.isMaxHandcard(), - preHidden:true, - content:function(){ - trigger.num+=2; + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: (event, player) => !event.numFixed && player.isMaxHandcard(), + preHidden: true, + content: function () { + trigger.num += 2; }, - mod:{ - maxHandcard:(player,num)=>num+2, + mod: { + maxHandcard: (player, num) => num + 2, }, }, - gzzhuangrong:{ - audio:'zhuangrong', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return !player.hasSkill('gzwushuang')&&player.hasCard(function(card){ - return get.type2(card,player)=='trick'; - },'h'); + gzzhuangrong: { + audio: "zhuangrong", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + !player.hasSkill("gzwushuang") && + player.hasCard(function (card) { + return get.type2(card, player) == "trick"; + }, "h") + ); }, - filterCard:function(card,player){ - return get.type2(card,player)=='trick'; + filterCard: function (card, player) { + return get.type2(card, player) == "trick"; }, - content:function(){ - player.addTempSkill('gzwushuang','phaseUseEnd'); + content: function () { + player.addTempSkill("gzwushuang", "phaseUseEnd"); }, - derivation:'gzwushuang', + derivation: "gzwushuang", }, //荀谌 - gzfenglve:{ - audio:'refenglve', - derivation:'gzfenglve_zongheng', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasSkillTag('noCompareSource')&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')>0&&!current.hasSkillTag('noCompareTarget'); - }); + gzfenglve: { + audio: "refenglve", + derivation: "gzfenglve_zongheng", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.hasSkillTag("noCompareSource") && + game.hasPlayer(function (current) { + return ( + current != player && + current.countCards("h") > 0 && + !current.hasSkillTag("noCompareTarget") + ); + }) + ); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')>0&&!target.hasSkillTag('noCompareTarget'); + filterTarget: function (card, player, target) { + return ( + target != player && + target.countCards("h") > 0 && + !target.hasSkillTag("noCompareTarget") + ); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - if(!target.countCards('hej')) event.goto(3); - else{ - event.giver=target; - event.gainner=player; - target.choosePlayerCard(target,true,'hej',2,'交给'+get.translation(player)+'两张牌'); + "step 1"; + if (result.bool) { + if (!target.countCards("hej")) event.goto(3); + else { + event.giver = target; + event.gainner = player; + target.choosePlayerCard( + target, + true, + "hej", + 2, + "交给" + get.translation(player) + "两张牌" + ); } - } - else if(result.tie){ + } else if (result.tie) { event.goto(3); - } - else{ - if(!player.countCards('he')) event.goto(3); - else{ - event.giver=player; - event.gainner=target; - player.chooseCard(true,'he','交给'+get.translation(target)+'一张牌'); + } else { + if (!player.countCards("he")) event.goto(3); + else { + event.giver = player; + event.gainner = target; + player.chooseCard(true, "he", "交给" + get.translation(target) + "一张牌"); } } - 'step 2' - if(result.bool) event.giver.give(result.cards,event.gainner,'giveAuto'); - 'step 3' - if(target.isIn()) player.chooseBool('纵横:是否令'+get.translation(target)+'获得【锋略】?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0; - }); + "step 2"; + if (result.bool) event.giver.give(result.cards, event.gainner, "giveAuto"); + "step 3"; + if (target.isIn()) + player + .chooseBool("纵横:是否令" + get.translation(target) + "获得【锋略】?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 0; + }); else event.finish(); - 'step 4' - if(result.bool){ - target.addTempSkill('gzfenglve_zongheng',{player:'phaseEnd'}); - game.log(player,'发起了','#y纵横',',令',target,'获得了技能','#g【锋略】'); + "step 4"; + if (result.bool) { + target.addTempSkill("gzfenglve_zongheng", { player: "phaseEnd" }); + game.log(player, "发起了", "#y纵横", ",令", target, "获得了技能", "#g【锋略】"); } }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(!player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=10; - } - if(val<=6){ - return card.number>=13; - } - return false; - })) return 0; - return -Math.sqrt(1+target.countCards('he'))/(1+target.countCards('j')); + ai: { + order: 8, + result: { + target: function (player, target) { + if ( + !player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 10; + } + if (val <= 6) { + return card.number >= 13; + } + return false; + }) + ) + return 0; + return -Math.sqrt(1 + target.countCards("he")) / (1 + target.countCards("j")); }, }, }, }, - gzfenglve_zongheng:{ - inherit:'gzfenglve', - content:function(){ - 'step 0' + gzfenglve_zongheng: { + inherit: "gzfenglve", + content: function () { + "step 0"; player.chooseToCompare(target); - 'step 1' - if(result.bool){ - if(!target.countCards('hej')) event.finish(); - else{ - event.giver=target; - event.gainner=player; - target.choosePlayerCard(target,true,'hej','交给'+get.translation(player)+'一张牌'); + "step 1"; + if (result.bool) { + if (!target.countCards("hej")) event.finish(); + else { + event.giver = target; + event.gainner = player; + target.choosePlayerCard( + target, + true, + "hej", + "交给" + get.translation(player) + "一张牌" + ); } - } - else if(result.tie){ + } else if (result.tie) { event.finish(); - } - else{ - if(!player.countCards('he')) event.finish(); - else{ - event.giver=player; - event.gainner=target; - player.chooseCard(true,'he',2,'交给'+get.translation(target)+'两张牌'); + } else { + if (!player.countCards("he")) event.finish(); + else { + event.giver = player; + event.gainner = target; + player.chooseCard(true, "he", 2, "交给" + get.translation(target) + "两张牌"); } } - 'step 2' - if(result.bool) event.giver.give(result.cards,event.gainner,'giveAuto'); + "step 2"; + if (result.bool) event.giver.give(result.cards, event.gainner, "giveAuto"); }, - ai:{ - order:8, - result:{ - target:function(player,target){ - if(!player.hasCard(function(card){ - if(get.position(card)!="h") return false; - var val=get.value(card); - if(val<0) return true; - if(val<=5){ - return card.number>=12; - } - if(val<=6){ - return card.number>=13; - } - return false; - })) return 0; - return -Math.sqrt(1+target.countCards('he'))/(1+target.countCards('j')); + ai: { + order: 8, + result: { + target: function (player, target) { + if ( + !player.hasCard(function (card) { + if (get.position(card) != "h") return false; + var val = get.value(card); + if (val < 0) return true; + if (val <= 5) { + return card.number >= 12; + } + if (val <= 6) { + return card.number >= 13; + } + return false; + }) + ) + return 0; + return -Math.sqrt(1 + target.countCards("he")) / (1 + target.countCards("j")); }, }, }, }, - gzanyong:{ - audio:'anyong', - trigger:{global:'damageBegin1'}, - usable:1, - filter:function(event,player){ - return event.source&&event.player!=event.source&& - event.source.isFriendOf(player)&&event.player.isIn(); + gzanyong: { + audio: "anyong", + trigger: { global: "damageBegin1" }, + usable: 1, + filter: function (event, player) { + return ( + event.source && + event.player != event.source && + event.source.isFriendOf(player) && + event.player.isIn() + ); }, - check:function(event,player){ - if(get.attitude(player,event.player)>0) return false; - if(event.player.hasSkillTag('filterDamage',null,{ - player:event.source, - card:event.card, - })) return false; - if(event.player.isUnseen()) return true; - if(event.player.hp>event.num&&event.player.hp<=event.num*2) return player.hp>1||event.player.isUnseen(2); + check: function (event, player) { + if (get.attitude(player, event.player) > 0) return false; + if ( + event.player.hasSkillTag("filterDamage", null, { + player: event.source, + card: event.card, + }) + ) + return false; + if (event.player.isUnseen()) return true; + if (event.player.hp > event.num && event.player.hp <= event.num * 2) + return player.hp > 1 || event.player.isUnseen(2); return false; }, - logTarget:'player', - preHidden:true, - content:function(){ - trigger.num*=2; - if(!trigger.player.isUnseen(2)){ + logTarget: "player", + preHidden: true, + content: function () { + trigger.num *= 2; + if (!trigger.player.isUnseen(2)) { player.loseHp(); - player.removeSkill('gzanyong'); - } - else if(!trigger.player.isUnseen()){ - player.chooseToDiscard('h',2,true); + player.removeSkill("gzanyong"); + } else if (!trigger.player.isUnseen()) { + player.chooseToDiscard("h", 2, true); } }, }, //周夷 - gzzhukou:{ - audio:'zhukou', - trigger:{source:'damageSource'}, - preHidden:true, - filter:function(event,player){ - if(!player.getHistory('useCard').length) return false; - var evt=event.getParent('phaseUse'); - if(!evt||!evt.player) return false; - return player.getHistory('sourceDamage',function(evtx){ - return evtx.getParent('phaseUse')==evt; - }).indexOf(event)==0; + gzzhukou: { + audio: "zhukou", + trigger: { source: "damageSource" }, + preHidden: true, + filter: function (event, player) { + if (!player.getHistory("useCard").length) return false; + var evt = event.getParent("phaseUse"); + if (!evt || !evt.player) return false; + return ( + player + .getHistory("sourceDamage", function (evtx) { + return evtx.getParent("phaseUse") == evt; + }) + .indexOf(event) == 0 + ); }, - frequent:true, - content:function(){ - player.draw(Math.min(player.getHistory('useCard').length,5)); + frequent: true, + content: function () { + player.draw(Math.min(player.getHistory("useCard").length, 5)); }, }, - gzduannian:{ - audio:2, - trigger:{player:'phaseUseEnd'}, - preHidden:true, - filter:function(event,player){ - return player.countCards('h')>0&&!player.hasCard(function(card){ - return !lib.filter.cardDiscardable(card,player,'gzduannian'); - },'h'); + gzduannian: { + audio: 2, + trigger: { player: "phaseUseEnd" }, + preHidden: true, + filter: function (event, player) { + return ( + player.countCards("h") > 0 && + !player.hasCard(function (card) { + return !lib.filter.cardDiscardable(card, player, "gzduannian"); + }, "h") + ); }, - check:function(event,player){ - return player.countCards('h',function(card){ - return get.value(card)>=6; - })<=Math.max(1,player.countCards('h')/2); + check: function (event, player) { + return ( + player.countCards("h", function (card) { + return get.value(card) >= 6; + }) <= Math.max(1, player.countCards("h") / 2) + ); }, - content:function(){ - 'step 0' - var cards=player.getCards('h',function(card){ - return lib.filter.cardDiscardable(card,player,'gzduannian'); + content: function () { + "step 0"; + var cards = player.getCards("h", function (card) { + return lib.filter.cardDiscardable(card, player, "gzduannian"); }); - if(cards.length){ + if (cards.length) { player.discard(cards); - } - else event.finish(); - 'step 1' - player.drawTo(Math.min(5,player.maxHp)); + } else event.finish(); + "step 1"; + player.drawTo(Math.min(5, player.maxHp)); }, }, - gzlianyou:{ - trigger:{player:'die'}, - direct:true, - forceDie:true, - skillAnimation:true, - animationColor:'fire', - content:function(){ - 'step 0' - player.chooseTarget(lib.filter.notMe,get.prompt('gzlianyou'),'令一名其他角色获得〖兴火〗').set('forceDie',true).set('ai',function(target){ - return 10+(get.attitude(_status.event.player,target)*(target.hasSkillTag('fireAttack',null,null,true)?2:1)); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzlianyou',target); - target.addSkills('gzxinghuo'); + gzlianyou: { + trigger: { player: "die" }, + direct: true, + forceDie: true, + skillAnimation: true, + animationColor: "fire", + content: function () { + "step 0"; + player + .chooseTarget(lib.filter.notMe, get.prompt("gzlianyou"), "令一名其他角色获得〖兴火〗") + .set("forceDie", true) + .set("ai", function (target) { + return ( + 10 + + get.attitude(_status.event.player, target) * + (target.hasSkillTag("fireAttack", null, null, true) ? 2 : 1) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzlianyou", target); + target.addSkills("gzxinghuo"); game.delayx(); } }, - derivation:'gzxinghuo', + derivation: "gzxinghuo", }, - gzxinghuo:{ - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event){ - return event.hasNature('fire'); + gzxinghuo: { + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event) { + return event.hasNature("fire"); }, - content:function(){ + content: function () { trigger.num++; }, }, //南华老仙 - gzgongxiu:{ - audio:'gongxiu', - trigger:{player:'phaseDrawBegin2'}, - preHidden:true, - filter:function(event,player){ - return !event.numFixed&&event.num>0&&player.maxHp>0; + gzgongxiu: { + audio: "gongxiu", + trigger: { player: "phaseDrawBegin2" }, + preHidden: true, + filter: function (event, player) { + return !event.numFixed && event.num > 0 && player.maxHp > 0; }, - content:function(){ + content: function () { trigger.num--; - player.addTempSkill('gzgongxiu2','phaseDrawAfter'); + player.addTempSkill("gzgongxiu2", "phaseDrawAfter"); }, }, - gzgongxiu2:{ - trigger:{player:'phaseDrawEnd'}, - forced:true, - charlotte:true, - popup:false, - content:function(){ - 'step 0' - var str='令至多'+get.cnNumber(player.maxHp)+'名角色'; - if(typeof player.storage.gzgongxiu!='number'){ - player.chooseControl().set('choiceList',[ - str+'各摸一张牌', - str+'各弃置一张牌', - ]); - } - else event._result={index:1-player.storage.gzgongxiu}; - 'step 1' - var num=result.index; - event.index=num; - player.storage.gzgongxiu=num; - player.chooseTarget(true,[1,player.maxHp],'选择至多'+get.cnNumber(player.maxHp)+'名角色各'+(num?'弃置':'摸')+'一张牌').set('goon',event.index?-1:1).set('ai',function(target){ - var evt=_status.event; - return evt.goon*get.attitude(evt.player,target); - }); - 'step 2' - if(result.bool){ - var targets=result.targets.sortBySeat(); - player.line(targets,'green'); - if(event.index==0) game.asyncDraw(targets); - else{ - for(var i of targets) i.chooseToDiscard('he',true); + gzgongxiu2: { + trigger: { player: "phaseDrawEnd" }, + forced: true, + charlotte: true, + popup: false, + content: function () { + "step 0"; + var str = "令至多" + get.cnNumber(player.maxHp) + "名角色"; + if (typeof player.storage.gzgongxiu != "number") { + player.chooseControl().set("choiceList", [str + "各摸一张牌", str + "各弃置一张牌"]); + } else event._result = { index: 1 - player.storage.gzgongxiu }; + "step 1"; + var num = result.index; + event.index = num; + player.storage.gzgongxiu = num; + player + .chooseTarget( + true, + [1, player.maxHp], + "选择至多" + + get.cnNumber(player.maxHp) + + "名角色各" + + (num ? "弃置" : "摸") + + "一张牌" + ) + .set("goon", event.index ? -1 : 1) + .set("ai", function (target) { + var evt = _status.event; + return evt.goon * get.attitude(evt.player, target); + }); + "step 2"; + if (result.bool) { + var targets = result.targets.sortBySeat(); + player.line(targets, "green"); + if (event.index == 0) game.asyncDraw(targets); + else { + for (var i of targets) i.chooseToDiscard("he", true); event.finish(); } } - 'step 3' + "step 3"; game.delayx(); }, }, - gzjinghe:{ - audio:'jinghe', - enable:'phaseUse', - filter:function(event,player){ - return player.maxHp>0&&player.countCards('h')>0&&!player.hasSkill('gzjinghe_clear'); + gzjinghe: { + audio: "jinghe", + enable: "phaseUse", + filter: function (event, player) { + return ( + player.maxHp > 0 && player.countCards("h") > 0 && !player.hasSkill("gzjinghe_clear") + ); }, - selectCard:function(){ - var max=_status.event.player.maxHp; - if(ui.selected.targets.length) return [ui.selected.targets.length,max]; - return [1,max]; + selectCard: function () { + var max = _status.event.player.maxHp; + if (ui.selected.targets.length) return [ui.selected.targets.length, max]; + return [1, max]; }, - selectTarget:function(){ + selectTarget: function () { return ui.selected.cards.length; }, - filterTarget:function(card,player,target){ + filterTarget: function (card, player, target) { return !target.isUnseen(); }, - filterCard:function(card){ - if(ui.selected.cards.length){ - var name=get.name(card); - for(var i of ui.selected.cards){ - if(get.name(i)==name) return false; + filterCard: function (card) { + if (ui.selected.cards.length) { + var name = get.name(card); + for (var i of ui.selected.cards) { + if (get.name(i) == name) return false; } } return true; }, - position:'h', - check:function(card){ - var player=_status.event.player; - if(game.countPlayer(function(current){ - return get.attitude(player,current)>0&&!current.isUnseen(); - })>ui.selected.cards.length) return get.position(card)=='e'?2:1; + position: "h", + check: function (card) { + var player = _status.event.player; + if ( + game.countPlayer(function (current) { + return get.attitude(player, current) > 0 && !current.isUnseen(); + }) > ui.selected.cards.length + ) + return get.position(card) == "e" ? 2 : 1; return 0; }, - complexCard:true, - discard:false, - lose:false, - delay:false, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - player.showCards(cards,get.translation(player)+'发动了【经合】'); - event.skills=lib.skill.gzjinghe.derivation.randomGets(targets.length); - player.addTempSkill('gzjinghe_clear',{player:'phaseBegin'}); + complexCard: true, + discard: false, + lose: false, + delay: false, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + player.showCards(cards, get.translation(player) + "发动了【经合】"); + event.skills = lib.skill.gzjinghe.derivation.randomGets(targets.length); + player.addTempSkill("gzjinghe_clear", { player: "phaseBegin" }); event.targets.sortBySeat(); - event.num=0; - 'step 1' - event.target=targets[num]; + event.num = 0; + "step 1"; + event.target = targets[num]; event.num++; - event.target.chooseControl(event.skills,'cancel2').set('choiceList',event.skills.map(function(i){ - return '
                        【'+get.translation(lib.translate[i+'_ab']||get.translation(i).slice(0,2))+'】
                        '+get.skillInfoTranslation(i,player)+'
                        '; - })).set('displayIndex',false).set('prompt','选择获得一个技能'); - 'step 2' - var skill=result.control; - if(skill!='cancel2'){ + event.target + .chooseControl(event.skills, "cancel2") + .set( + "choiceList", + event.skills.map(function (i) { + return ( + '
                        【' + + get.translation( + lib.translate[i + "_ab"] || get.translation(i).slice(0, 2) + ) + + "】
                        " + + get.skillInfoTranslation(i, player) + + "
                        " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "选择获得一个技能"); + "step 2"; + var skill = result.control; + if (skill != "cancel2") { event.skills.remove(skill); - target.addAdditionalSkills('gzjinghe_'+player.playerid,skill); + target.addAdditionalSkills("gzjinghe_" + player.playerid, skill); target.popup(skill); } - if(event.num0&&player.countCards('he')>0; + group: "gzshilu_zhiheng", + subSkill: { + zhiheng: { + audio: "gzshilu", + trigger: { player: "phaseZhunbeiBegin" }, + filter: function (event, player) { + return player.getStorage("gzshilu").length > 0 && player.countCards("he") > 0; }, - direct:true, - content:function(){ - 'step 0' - var num=Math.min(player.getStorage('gzshilu').length,player.countCards('he')); - player.chooseToDiscard('he',get.prompt('gzshilu'),'弃置至多'+get.cnNumber(num)+'张牌并摸等量的牌',[1,num]).logSkill='gzshilu'; - 'step 1' - if(result.bool&&result.cards&&result.cards.length) player.draw(result.cards.length); + direct: true, + content: function () { + "step 0"; + var num = Math.min(player.getStorage("gzshilu").length, player.countCards("he")); + player.chooseToDiscard( + "he", + get.prompt("gzshilu"), + "弃置至多" + get.cnNumber(num) + "张牌并摸等量的牌", + [1, num] + ).logSkill = "gzshilu"; + "step 1"; + if (result.bool && result.cards && result.cards.length) + player.draw(result.cards.length); }, }, }, }, - gzxiongnve:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return player.getStorage('gzshilu').length>0; + gzxiongnve: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return player.getStorage("gzshilu").length > 0; }, - content:function(){ - 'step 0' - player.chooseButton([get.prompt('gzxiongnve'),[player.storage.gzshilu,'character']]).set('ai',function(button){ - if(!_status.event.goon) return 0; - var name=button.link,group=get.is.double(name,true); - if(!group) group=[lib.character[name][1]]; - for(var i of group){ - if(game.hasPlayer(function(current){ - return player.inRange(current)&¤t.identity==i; - })) return 1+Math.random(); - } - return 0; - }).set('goon',player.countCards('hs',function(card){ - return get.tag(card,'damage')&&player.hasValueTarget(card); - })>1); - 'step 1' - if(result.bool){ - player.logSkill('gzxiongnve'); - lib.skill.gzxiongnve.throwCharacter(player,result.links); - game.delayx(); - var group=get.is.double(result.links[0],true); - if(!group) group=[lib.character[result.links[0]][1]]; - event.group=group; - var str=get.translation(group); - player.chooseControl().set('prompt','选择获得一项效果').set('choiceList',[ - '本回合对'+str+'势力的角色造成的伤害+1', - '本回合对'+str+'势力的角色造成伤害后,获得对方的一张牌', - '本回合对'+str+'势力的角色使用牌没有次数限制', - ]).set('ai',function(){ - var player=_status.event.player; - if(player.countCards('hs',function(card){ - return get.name(card)=='sha'&&player.hasValueTarget(card); - })>player.getCardUsable('sha')) return 0; - return get.rand(1,2); - }); - } - else event.finish(); - 'step 2' - var skill='gzxiongnve_effect'+result.index; - player.markAuto(skill,event.group); - player.addTempSkill(skill); - game.log(player,'本回合对'+get.translation(event.group)+'势力的角色','#g'+lib.skill[skill].promptx) - }, - group:'gzxiongnve_end', - throwCharacter:function(player,list){ - player.unmarkAuto('gzshilu',list); - _status.characterlist.addArray(list); - game.log(player,'从','#y“戮”','中移去了','#g'+get.translation(list)); - game.broadcastAll(function(player,list){ - var cards=[]; - for(var i=0;i 1 + ); + "step 1"; + if (result.bool) { + player.logSkill("gzxiongnve"); + lib.skill.gzxiongnve.throwCharacter(player, result.links); + game.delayx(); + var group = get.is.double(result.links[0], true); + if (!group) group = [lib.character[result.links[0]][1]]; + event.group = group; + var str = get.translation(group); + player + .chooseControl() + .set("prompt", "选择获得一项效果") + .set("choiceList", [ + "本回合对" + str + "势力的角色造成的伤害+1", + "本回合对" + str + "势力的角色造成伤害后,获得对方的一张牌", + "本回合对" + str + "势力的角色使用牌没有次数限制", + ]) + .set("ai", function () { + var player = _status.event.player; + if ( + player.countCards("hs", function (card) { + return get.name(card) == "sha" && player.hasValueTarget(card); + }) > player.getCardUsable("sha") + ) + return 0; + return get.rand(1, 2); + }); + } else event.finish(); + "step 2"; + var skill = "gzxiongnve_effect" + result.index; + player.markAuto(skill, event.group); + player.addTempSkill(skill); + game.log( + player, + "本回合对" + get.translation(event.group) + "势力的角色", + "#g" + lib.skill[skill].promptx + ); }, - subSkill:{ - effect0:{ - promptx:'造成的伤害+1', - charlotte:true, - onremove:true, - audio:'gzxiongnve', - intro:{ - content:'对$势力的角色造成的伤害+1', + group: "gzxiongnve_end", + throwCharacter: function (player, list) { + player.unmarkAuto("gzshilu", list); + _status.characterlist.addArray(list); + game.log(player, "从", "#y“戮”", "中移去了", "#g" + get.translation(list)); + game.broadcastAll( + function (player, list) { + var cards = []; + for (var i = 0; i < list.length; i++) { + var cardname = "huashen_card_" + list[i]; + lib.card[cardname] = { + fullimage: true, + image: "character:" + list[i], + }; + lib.translate[cardname] = get.rawName2(list[i]); + cards.push(game.createCard(cardname, "", "")); + } + player.$throw(cards, 1000, "nobroadcast"); }, - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event,player){ - return player.getStorage('gzxiongnve_effect0').includes(event.player.identity); + player, + list + ); + }, + subSkill: { + effect0: { + promptx: "造成的伤害+1", + charlotte: true, + onremove: true, + audio: "gzxiongnve", + intro: { + content: "对$势力的角色造成的伤害+1", }, - logTarget:'player', - content:function(){ + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event, player) { + return player.getStorage("gzxiongnve_effect0").includes(event.player.identity); + }, + logTarget: "player", + content: function () { trigger.num++; }, }, - effect1:{ - promptx:'造成伤害后,获得对方的一张牌', - charlotte:true, - onremove:true, - audio:'gzxiongnve', - intro:{ - content:'对$势力的角色造成伤害后,获得对方的一张牌', + effect1: { + promptx: "造成伤害后,获得对方的一张牌", + charlotte: true, + onremove: true, + audio: "gzxiongnve", + intro: { + content: "对$势力的角色造成伤害后,获得对方的一张牌", }, - trigger:{source:'damageEnd'}, - forced:true, - filter:function(event,player){ - return player.getStorage('gzxiongnve_effect1').includes(event.player.identity)&&event.player.countGainableCards(player,'he')>0; + trigger: { source: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + player.getStorage("gzxiongnve_effect1").includes(event.player.identity) && + event.player.countGainableCards(player, "he") > 0 + ); + }, + logTarget: "player", + content: function () { + player.gainPlayerCard(trigger.player, true, "he"); }, - logTarget:'player', - content:function(){ - player.gainPlayerCard(trigger.player,true,'he'); - } }, - effect2:{ - promptx:'使用牌没有次数限制', - charlotte:true, - onremove:true, - intro:{ - content:'对$势力的角色使用牌没有次数限制', + effect2: { + promptx: "使用牌没有次数限制", + charlotte: true, + onremove: true, + intro: { + content: "对$势力的角色使用牌没有次数限制", }, - mod:{ - cardUsableTarget:function(card,player,target){ - if(player.getStorage('gzxiongnve_effect2').includes(target.identity)) return true; + mod: { + cardUsableTarget: function (card, player, target) { + if (player.getStorage("gzxiongnve_effect2").includes(target.identity)) + return true; }, }, }, - effect3:{ - charlotte:true, - audio:'gzxiongnve', - mark:true, - intro:{ - content:'其他角色对你造成伤害时,此伤害-1', + effect3: { + charlotte: true, + audio: "gzxiongnve", + mark: true, + intro: { + content: "其他角色对你造成伤害时,此伤害-1", }, - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - return event.source&&event.source!=player; + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + return event.source && event.source != player; }, - forced:true, - logTarget:'source', - content:function(){ + forced: true, + logTarget: "source", + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(target==player) return; - if(player.hasSkillTag('jueqing',false,target)) return; - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + effect: { + target: function (card, player, target) { + if (target == player) return; + if (player.hasSkillTag("jueqing", false, target)) return; + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } }, }, }, }, - end:{ - trigger:{player:'phaseUseEnd'}, - direct:true, - filter:function(event,player){ - return player.getStorage('gzshilu').length>1; + end: { + trigger: { player: "phaseUseEnd" }, + direct: true, + filter: function (event, player) { + return player.getStorage("gzshilu").length > 1; }, - content:function(){ - 'step 0' - player.chooseButton(['是否移去两张“戮”获得减伤?',[player.storage.gzshilu,'character']],2).set('ai',function(button){ - var name=button.link,group=get.is.double(name,true); - if(!group) group=[lib.character[name][1]]; - for(var i of group){ - if(game.hasPlayer(function(current){ - return current.identity==i; - })) return 0; - } - return 1; - }); - 'step 1' - if(result.bool){ - player.logSkill('gzxiongnve'); - lib.skill.gzxiongnve.throwCharacter(player,result.links); - player.addTempSkill('gzxiongnve_effect3',{player:'phaseBegin'}); + content: function () { + "step 0"; + player + .chooseButton( + ["是否移去两张“戮”获得减伤?", [player.storage.gzshilu, "character"]], + 2 + ) + .set("ai", function (button) { + var name = button.link, + group = get.is.double(name, true); + if (!group) group = [lib.character[name][1]]; + for (var i of group) { + if ( + game.hasPlayer(function (current) { + return current.identity == i; + }) + ) + return 0; + } + return 1; + }); + "step 1"; + if (result.bool) { + player.logSkill("gzxiongnve"); + lib.skill.gzxiongnve.throwCharacter(player, result.links); + player.addTempSkill("gzxiongnve_effect3", { player: "phaseBegin" }); game.delayx(); } }, @@ -8004,295 +10812,355 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, //邓芝 - gzjianliang:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - preHidden:true, - filter:function(event,player){ + gzjianliang: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + preHidden: true, + filter: function (event, player) { return player.isMinHandcard(); }, - logTarget:function(event,player){ + logTarget: function (event, player) { var isFriend; - if(player.identity=='unknown'){ - var group='shu'; - if(!player.wontYe('shu')) group=null; - isFriend=function(current){ - return current==player||current.identity==group; - } - } - else isFriend=function(target){ - return target.isFriendOf(player); - }; + if (player.identity == "unknown") { + var group = "shu"; + if (!player.wontYe("shu")) group = null; + isFriend = function (current) { + return current == player || current.identity == group; + }; + } else + isFriend = function (target) { + return target.isFriendOf(player); + }; return game.filterPlayer(isFriend); }, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { return current.isFriendOf(player); }); - if(list.length==1){ + if (list.length == 1) { list[0].draw(); event.finish(); - } - else game.asyncDraw(list); - 'step 1' + } else game.asyncDraw(list); + "step 1"; game.delayx(); }, }, - gzweimeng:{ - audio:2, - enable:'phaseUse', - usable:1, - filterTarget:function(card,player,target){ - return target!=player&&target.countGainableCards(player,'h')>0; + gzweimeng: { + audio: 2, + enable: "phaseUse", + usable: 1, + filterTarget: function (card, player, target) { + return target != player && target.countGainableCards(player, "h") > 0; }, - content:function(){ - 'step 0' - player.gainPlayerCard(target,'h',true,event.name=='gzweimeng'?[1,player.hp]:1); - 'step 1' - if(result.bool&&target.isIn()){ - var num=result.cards.length,hs=player.getCards('he'); - if(!hs.length) event.goto(3); - else if(hs.length<=num) event._result={bool:true,cards:hs}; - else player.chooseCard('he',true,'选择交给'+get.translation(target)+get.cnNumber(num)+'张牌',num); - } - else event.goto(3); - 'step 2' - player.give(result.cards,target); - 'step 3' - if(target.isIn()&&event.name=='gzweimeng') player.chooseBool('纵横:是否令'+get.translation(target)+'获得【危盟】?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0; - }); + content: function () { + "step 0"; + player.gainPlayerCard(target, "h", true, event.name == "gzweimeng" ? [1, player.hp] : 1); + "step 1"; + if (result.bool && target.isIn()) { + var num = result.cards.length, + hs = player.getCards("he"); + if (!hs.length) event.goto(3); + else if (hs.length <= num) event._result = { bool: true, cards: hs }; + else + player.chooseCard( + "he", + true, + "选择交给" + get.translation(target) + get.cnNumber(num) + "张牌", + num + ); + } else event.goto(3); + "step 2"; + player.give(result.cards, target); + "step 3"; + if (target.isIn() && event.name == "gzweimeng") + player + .chooseBool("纵横:是否令" + get.translation(target) + "获得【危盟】?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 0; + }); else event.finish(); - 'step 4' - if(result.bool){ - target.addTempSkill('gzweimeng_zongheng',{player:'phaseEnd'}); - game.log(player,'发起了','#y纵横',',令',target,'获得了技能','#g【危盟】'); + "step 4"; + if (result.bool) { + target.addTempSkill("gzweimeng_zongheng", { player: "phaseEnd" }); + game.log(player, "发起了", "#y纵横", ",令", target, "获得了技能", "#g【危盟】"); } }, - derivation:'gzweimeng_zongheng', - subSkill:{ - zongheng:{ - inherit:'gzweimeng', - ai:{ - order:6, - tag:{ - lose:1, - loseCard:1, - gain:1, + derivation: "gzweimeng_zongheng", + subSkill: { + zongheng: { + inherit: "gzweimeng", + ai: { + order: 6, + tag: { + lose: 1, + loseCard: 1, + gain: 1, }, - result:{ - target:-1, + result: { + target: -1, }, }, }, }, - ai:{ - order:6, - tag:{ - lose:1, - loseCard:1, - gain:1, + ai: { + order: 6, + tag: { + lose: 1, + loseCard: 1, + gain: 1, }, - result:{ - target:function(player,target){ - return -Math.pow(Math.min(player.hp,target.countCards('h')),2)/4; + result: { + target: function (player, target) { + return -Math.pow(Math.min(player.hp, target.countCards("h")), 2) / 4; }, }, }, }, //邹氏 - huoshui:{ - audio:2, - forced:true, - global:'huoshui_mingzhi', - trigger:{player:'useCardToTargeted'}, - preHidden:true, - filter:function(event,player){ - return (event.card.name=='sha'||event.card.name=='wanjian')&&event.target.isUnseen(2)&&event.target.isEnemyOf(player); + huoshui: { + audio: 2, + forced: true, + global: "huoshui_mingzhi", + trigger: { player: "useCardToTargeted" }, + preHidden: true, + filter: function (event, player) { + return ( + (event.card.name == "sha" || event.card.name == "wanjian") && + event.target.isUnseen(2) && + event.target.isEnemyOf(player) + ); }, - logTarget:'target', - content:function(){ - var target=trigger.target; - target.addTempSkill('huoshui_norespond'); - target.markAuto('huoshui_norespond',[trigger.card]); + logTarget: "target", + content: function () { + var target = trigger.target; + target.addTempSkill("huoshui_norespond"); + target.markAuto("huoshui_norespond", [trigger.card]); }, }, - huoshui_norespond:{ - charlotte:true, - trigger:{global:'useCardEnd'}, - onremove:true, - forced:true, - popup:false, - silent:true, - firstDo:true, - filter:function(event,player){ - return player.getStorage('huoshui_norespond').includes(event.card); + huoshui_norespond: { + charlotte: true, + trigger: { global: "useCardEnd" }, + onremove: true, + forced: true, + popup: false, + silent: true, + firstDo: true, + filter: function (event, player) { + return player.getStorage("huoshui_norespond").includes(event.card); }, - content:function(){ - player.unmarkAuto('huoshui_norespond',[trigger.card]); - if(!player.storage.huoshui_norespond.length) player.removeSkill('huoshui_norespond'); + content: function () { + player.unmarkAuto("huoshui_norespond", [trigger.card]); + if (!player.storage.huoshui_norespond.length) player.removeSkill("huoshui_norespond"); }, - mod:{ - cardEnabled:function(card){ - if(card.name=='shan') return false; + mod: { + cardEnabled: function (card) { + if (card.name == "shan") return false; }, - cardRespondable:function(card){ - if(card.name=='shan') return false; + cardRespondable: function (card) { + if (card.name == "shan") return false; }, }, }, - huoshui_mingzhi:{ - ai:{ - nomingzhi:true, - skillTagFilter:function(player){ - if(_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.hasSkill('huoshui')){ + huoshui_mingzhi: { + ai: { + nomingzhi: true, + skillTagFilter: function (player) { + if ( + _status.currentPhase && + _status.currentPhase != player && + _status.currentPhase.hasSkill("huoshui") + ) { return true; } return false; - } - } - }, - qingcheng:{ - audio:2, - }, - qingcheng_ai:{ - ai:{ - effect:{ - target:function(card){ - if(get.tag(card,'damage')) return 2; - } - } - } - }, - //朱灵 - gzjuejue:{ - audio:2, - trigger:{player:'phaseDiscardBegin'}, - check:function(event,player){ - return player.hp>2&&player.needsToDiscard()>0&&game.countPlayer(function(current){ - return get.attitude(current,player)<=0; - })>game.countPlayer()/2; + }, }, - preHidden:true, - content:function(){ - player.addTempSkill('gzjuejue_effect'); - player.loseHp(); - }, - subSkill:{ - effect:{ - trigger:{player:'phaseDiscardAfter'}, - forced:true, - charlotte:true, - popup:false, - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - return evt.type=='discard'&&evt.cards2&&evt.cards2.length>0&&evt.getParent('phaseDiscard')==event; - }).length>0; - }, - content:function(){ - 'step 0' - var num=0; - player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) num+=evt.cards2.length; - }); - event.num=num; - event.targets=game.filterPlayer(function(current){ - return current!=player; - }).sortBySeat(); - player.line(event.targets,'green'); - 'step 1' - var target=targets.shift(); - event.target=target; - if(target.isIn()){ - target.addTempClass('target'); - target.chooseCard('h',num,'将'+get.cnNumber(num)+'张牌置入弃牌堆,或受到1点伤害').set('ai',function(card){ - var evt=_status.event.getParent(); - if(get.damageEffect(evt.target,evt.player,evt.target)>=0) return 0; - return (8/Math.sqrt(evt.num)+evt.target.getDamagedHp())-get.value(card); - }); - } - else if(targets.length) event.redo(); - else event.finish(); - 'step 2' - if(result.bool){ - target.lose(result.cards,ui.discardPile,'visible'); - target.$throw(result.cards,1000); - game.log(target,'将',result.cards,'置入了弃牌堆'); - } - else target.damage(); - 'step 3' - game.delayx(); - if(targets.length) event.goto(1); + }, + qingcheng: { + audio: 2, + }, + qingcheng_ai: { + ai: { + effect: { + target: function (card) { + if (get.tag(card, "damage")) return 2; }, }, }, - ai:{ - noDieAfter2:true, - skillTagFilter:function(player,tag,target){ + }, + //朱灵 + gzjuejue: { + audio: 2, + trigger: { player: "phaseDiscardBegin" }, + check: function (event, player) { + return ( + player.hp > 2 && + player.needsToDiscard() > 0 && + game.countPlayer(function (current) { + return get.attitude(current, player) <= 0; + }) > + game.countPlayer() / 2 + ); + }, + preHidden: true, + content: function () { + player.addTempSkill("gzjuejue_effect"); + player.loseHp(); + }, + subSkill: { + effect: { + trigger: { player: "phaseDiscardAfter" }, + forced: true, + charlotte: true, + popup: false, + filter: function (event, player) { + return ( + player.getHistory("lose", function (evt) { + return ( + evt.type == "discard" && + evt.cards2 && + evt.cards2.length > 0 && + evt.getParent("phaseDiscard") == event + ); + }).length > 0 + ); + }, + content: function () { + "step 0"; + var num = 0; + player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) + num += evt.cards2.length; + }); + event.num = num; + event.targets = game + .filterPlayer(function (current) { + return current != player; + }) + .sortBySeat(); + player.line(event.targets, "green"); + "step 1"; + var target = targets.shift(); + event.target = target; + if (target.isIn()) { + target.addTempClass("target"); + target + .chooseCard( + "h", + num, + "将" + get.cnNumber(num) + "张牌置入弃牌堆,或受到1点伤害" + ) + .set("ai", function (card) { + var evt = _status.event.getParent(); + if (get.damageEffect(evt.target, evt.player, evt.target) >= 0) + return 0; + return ( + 8 / Math.sqrt(evt.num) + + evt.target.getDamagedHp() - + get.value(card) + ); + }); + } else if (targets.length) event.redo(); + else event.finish(); + "step 2"; + if (result.bool) { + target.lose(result.cards, ui.discardPile, "visible"); + target.$throw(result.cards, 1000); + game.log(target, "将", result.cards, "置入了弃牌堆"); + } else target.damage(); + "step 3"; + game.delayx(); + if (targets.length) event.goto(1); + }, + }, + }, + ai: { + noDieAfter2: true, + skillTagFilter: function (player, tag, target) { return target.isFriendOf(player); }, }, }, - gzfangyuan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - zhenfa:'siege', - direct:true, - locked:true, - filter:function(event,player){ - return game.countPlayer()>4&&game.hasPlayer(function(current){ - return player.sieged(current)&&player.canUse('sha',current,false); - }); + gzfangyuan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + zhenfa: "siege", + direct: true, + locked: true, + filter: function (event, player) { + return ( + game.countPlayer() > 4 && + game.hasPlayer(function (current) { + return player.sieged(current) && player.canUse("sha", current, false); + }) + ); }, - preHidden:true, - content:function(){ - 'step 0' - var list=game.filterPlayer(function(current){ - return player.sieged(current)&&player.canUse('sha',current,false); + preHidden: true, + content: function () { + "step 0"; + var list = game.filterPlayer(function (current) { + return player.sieged(current) && player.canUse("sha", current, false); }); - if(player.hasSkill('gzfangyuan')){ - if(list.length==1) event._result={bool:true,targets:list}; - else player.chooseTarget('方圆:视为对一名围攻你的角色使用【杀】',function(card,player,target){ - return _status.event.list.includes(target); - },true).set('list',list).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha',isCard:true},player,player); - }).setHiddenSkill('gzfangyuan'); + if (player.hasSkill("gzfangyuan")) { + if (list.length == 1) event._result = { bool: true, targets: list }; + else + player + .chooseTarget( + "方圆:视为对一名围攻你的角色使用【杀】", + function (card, player, target) { + return _status.event.list.includes(target); + }, + true + ) + .set("list", list) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha", isCard: true }, player, player); + }) + .setHiddenSkill("gzfangyuan"); + } else { + player + .chooseTarget( + get.prompt("gzfangyuan"), + "视为对一名围攻你的角色使用【杀】", + function (card, player, target) { + return _status.event.list.includes(target); + } + ) + .set("list", list) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "sha", isCard: true }, player, player); + }); } - else{ - player.chooseTarget(get.prompt('gzfangyuan'),'视为对一名围攻你的角色使用【杀】',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',list).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha',isCard:true},player,player); - }); - } - 'step 1' - if(result.bool){ - player.useCard({name:'sha',isCard:true},result.targets[0],'gzfangyuan',false); + "step 1"; + if (result.bool) { + player.useCard({ name: "sha", isCard: true }, result.targets[0], "gzfangyuan", false); } }, - global:'gzfangyuan_siege', - subSkill:{ - siege:{ - mod:{ - maxHandcard:function(player,num){ - if(game.countPlayer()<4) return; - var next=player.getNext(),prev=player.getPrevious(),siege=[]; - if(player.siege(next)) siege.push(next.getNext()); - if(player.siege(prev)) siege.push(prev.getPrevious()); - if(siege.length){ + global: "gzfangyuan_siege", + subSkill: { + siege: { + mod: { + maxHandcard: function (player, num) { + if (game.countPlayer() < 4) return; + var next = player.getNext(), + prev = player.getPrevious(), + siege = []; + if (player.siege(next)) siege.push(next.getNext()); + if (player.siege(prev)) siege.push(prev.getPrevious()); + if (siege.length) { siege.push(player); - num+=siege.filter(function(source){ - return source.hasSkill('gzfangyuan'); + num += siege.filter(function (source) { + return source.hasSkill("gzfangyuan"); }).length; } - if(player.sieged()){ - if(next.hasSkill('gzfangyuan')) num--; - if(prev.hasSkill('gzfangyuan')) num--; + if (player.sieged()) { + if (next.hasSkill("gzfangyuan")) num--; + if (prev.hasSkill("gzfangyuan")) num--; } return num; }, @@ -8301,199 +11169,251 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, //彭羕 - daming:{ - audio:2, - trigger:{global:'phaseUseBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - if(!player.isFriendOf(event.player)||!game.hasPlayer(function(current){ - return !current.isLinked(); - })) return false; - if(_status.connectMode&&player.hasSkill('daming')) return player.countCards('h')>0; - return player.countCards('h',function(card){ - return get.type2(card,player)=='trick'; + daming: { + audio: 2, + trigger: { global: "phaseUseBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + if ( + !player.isFriendOf(event.player) || + !game.hasPlayer(function (current) { + return !current.isLinked(); + }) + ) + return false; + if (_status.connectMode && player.hasSkill("daming")) return player.countCards("h") > 0; + return player.countCards("h", function (card) { + return get.type2(card, player) == "trick"; }); }, - content:function(){ - 'step 0' - player.chooseCardTarget({ - prompt:get.prompt('daming'), - prompt2:'弃置一张锦囊牌并选择要横置的角色', - filterCard:function(card,player){ - return get.type2(card,player)=='trick'&&lib.filter.cardDiscardable(card,player,'daming'); - }, - filterTarget:function(card,player,target){ - return !target.isLinked(); - }, - goon:function(){ - var target=trigger.player; - if(get.recoverEffect(target,player,player)>0) return true; - var card={name:'sha',nature:'thunder',isCard:true}; - if(game.hasPlayer(function(current){ - return current!=player&¤t!=target&&target.canUse(card,current,false)&&get.effect(current,card,target,player)>0; - })) return true; - return false; - }(), - ai1:function(card){ - if(_status.event.goon) return 7-get.value(card); - return 0; - }, - ai2:function(target){ - var player=_status.event.player; - return ((target.identity!='unknown'&&!game.hasPlayer(function(current){ - return current!=target&¤t.isFriendOf(target)&¤t.isLinked(); - }))?3:1)*(-get.attitude(target,player,player)+1); - }, - }).setHiddenSkill('daming'); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('daming',target); + content: function () { + "step 0"; + player + .chooseCardTarget({ + prompt: get.prompt("daming"), + prompt2: "弃置一张锦囊牌并选择要横置的角色", + filterCard: function (card, player) { + return ( + get.type2(card, player) == "trick" && + lib.filter.cardDiscardable(card, player, "daming") + ); + }, + filterTarget: function (card, player, target) { + return !target.isLinked(); + }, + goon: (function () { + var target = trigger.player; + if (get.recoverEffect(target, player, player) > 0) return true; + var card = { name: "sha", nature: "thunder", isCard: true }; + if ( + game.hasPlayer(function (current) { + return ( + current != player && + current != target && + target.canUse(card, current, false) && + get.effect(current, card, target, player) > 0 + ); + }) + ) + return true; + return false; + })(), + ai1: function (card) { + if (_status.event.goon) return 7 - get.value(card); + return 0; + }, + ai2: function (target) { + var player = _status.event.player; + return ( + (target.identity != "unknown" && + !game.hasPlayer(function (current) { + return ( + current != target && + current.isFriendOf(target) && + current.isLinked() + ); + }) + ? 3 + : 1) * + (-get.attitude(target, player, player) + 1) + ); + }, + }) + .setHiddenSkill("daming"); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("daming", target); player.discard(result.cards); - } - else event.finish(); - 'step 2' - if(!target.isLinked()) target.link(); - 'step 3' - var map={},sides=[],pmap=_status.connectMode?lib.playerOL:game.playerMap,player; - for(var i of game.players){ - if(i.identity=='unknown') continue; - var added=false; - for(var j of sides){ - if(i.isFriendOf(pmap[j])){ - added=true; + } else event.finish(); + "step 2"; + if (!target.isLinked()) target.link(); + "step 3"; + var map = {}, + sides = [], + pmap = _status.connectMode ? lib.playerOL : game.playerMap, + player; + for (var i of game.players) { + if (i.identity == "unknown") continue; + var added = false; + for (var j of sides) { + if (i.isFriendOf(pmap[j])) { + added = true; map[j].push(i); - if(i==this) player=j; + if (i == this) player = j; break; } } - if(!added){ - map[i.playerid]=[i]; + if (!added) { + map[i.playerid] = [i]; sides.push(i.playerid); - if(i==this) player=i.playerid; + if (i == this) player = i.playerid; } } - var num=0; - for(var i in map){ - if(map[i].filter(function(i){ - return i.isLinked(); - }).length) num++; + var num = 0; + for (var i in map) { + if ( + map[i].filter(function (i) { + return i.isLinked(); + }).length + ) + num++; } - if(num>0) player.draw(num); - 'step 4' - if(trigger.player.isIn()){ - var target=trigger.player,sha=game.filterPlayer(function(current){ - return current!=target&¤t!=player&&target.canUse({name:'sha',nature:'thunder',isCard:true},current,false); - }); - if(sha.length){ - var next=player.chooseTarget('请选择'+get.translation(target)+'使用雷【杀】的目标',function(card,player,target){ - return _status.event.list.includes(target); + if (num > 0) player.draw(num); + "step 4"; + if (trigger.player.isIn()) { + var target = trigger.player, + sha = game.filterPlayer(function (current) { + return ( + current != target && + current != player && + target.canUse( + { name: "sha", nature: "thunder", isCard: true }, + current, + false + ) + ); }); - next.set('prompt2','或点「取消」令其回复1点体力'); - next.set('goon',get.recoverEffect(target,player,player)); - next.set('list',sha); - next.set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'sha',nature:'thunder',isCard:true},_status.event.getTrigger().player,player)-_status.event.goon; + if (sha.length) { + var next = player.chooseTarget( + "请选择" + get.translation(target) + "使用雷【杀】的目标", + function (card, player, target) { + return _status.event.list.includes(target); + } + ); + next.set("prompt2", "或点「取消」令其回复1点体力"); + next.set("goon", get.recoverEffect(target, player, player)); + next.set("list", sha); + next.set("ai", function (target) { + var player = _status.event.player; + return ( + get.effect( + target, + { name: "sha", nature: "thunder", isCard: true }, + _status.event.getTrigger().player, + player + ) - _status.event.goon + ); }); - } - else if(target.isDamaged()) event._result={bool:false}; + } else if (target.isDamaged()) event._result = { bool: false }; else event.finish(); - } - else event.finish(); - 'step 5' - if(result.bool){ - var target=result.targets[0]; - if(player==trigger.player) player.line(target); - else{ - player.line2([trigger.player,target]); + } else event.finish(); + "step 5"; + if (result.bool) { + var target = result.targets[0]; + if (player == trigger.player) player.line(target); + else { + player.line2([trigger.player, target]); game.delay(0.5); } - trigger.player.useCard({name:'sha',nature:'thunder',isCard:true},target,false).animate=false; - } - else{ + trigger.player.useCard( + { name: "sha", nature: "thunder", isCard: true }, + target, + false + ).animate = false; + } else { player.line(trigger.player); trigger.player.recover(); } }, }, - xiaoni:{ - audio:2, - trigger:{ - player:'useCard', - target:'useCardToTargeted', + xiaoni: { + audio: 2, + trigger: { + player: "useCard", + target: "useCardToTargeted", }, - forced:true, - filter:function(event,player){ - var type=get.type2(event.card); - if(type!='basic'&&type!='trick') return false; - var list=game.filterPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); + forced: true, + filter: function (event, player) { + var type = get.type2(event.card); + if (type != "basic" && type != "trick") return false; + var list = game.filterPlayer(function (current) { + return current != player && current.isFriendOf(player); }); - if(!list.length) return false; - var hs=player.countCards('h'); - for(var i of list){ - if(i.countCards('h')>hs) return false; + if (!list.length) return false; + var hs = player.countCards("h"); + for (var i of list) { + if (i.countCards("h") > hs) return false; } return true; }, - check:()=>false, - preHidden:true, - content:function(){ - if(trigger.name=='useCard') trigger.directHit.addArray(game.players); + check: () => false, + preHidden: true, + content: function () { + if (trigger.name == "useCard") trigger.directHit.addArray(game.players); else trigger.directHit.add(player); }, - global:'xiaoni_ai', - ai:{ - halfneg:true, - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(!arg.card) return false; - var type=get.type2(arg.card); - if(type!='basic'&&type!='trick') return false; - var list=game.filterPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); + global: "xiaoni_ai", + ai: { + halfneg: true, + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if (!arg.card) return false; + var type = get.type2(arg.card); + if (type != "basic" && type != "trick") return false; + var list = game.filterPlayer(function (current) { + return current != player && current.isFriendOf(player); }); - if(!list.length) return false; - var cards=[arg.card]; - if(arg.card.cards) cards.addArray(arg.card.cards); + if (!list.length) return false; + var cards = [arg.card]; + if (arg.card.cards) cards.addArray(arg.card.cards); cards.addArray(ui.selected.cards); - var hhs=function(card){ + var hhs = function (card) { return !cards.includes(card); }; - var hs=player.countCards('h',hhs); - for(var i of list){ - if(i.countCards('h',hhs)>hs) return false; + var hs = player.countCards("h", hhs); + for (var i of list) { + if (i.countCards("h", hhs) > hs) return false; } return true; }, }, - subSkill:{ - ai:{ - ai:{ - directHit_ai:true, - skillTagFilter:function(playerx,tag,arg){ - if(!arg.card) return false; - var type=get.type2(arg.card); - if(type!='basic'&&type!='trick') return false; + subSkill: { + ai: { + ai: { + directHit_ai: true, + skillTagFilter: function (playerx, tag, arg) { + if (!arg.card) return false; + var type = get.type2(arg.card); + if (type != "basic" && type != "trick") return false; var player; - if(arg.target&&arg.target.hasSkill('xiaoni')) player=arg.target; + if (arg.target && arg.target.hasSkill("xiaoni")) player = arg.target; else return false; - var list=game.filterPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); + var list = game.filterPlayer(function (current) { + return current != player && current.isFriendOf(player); }); - if(!list.length) return false; - var cards=[arg.card]; - if(arg.card.cards) cards.addArray(arg.card.cards); + if (!list.length) return false; + var cards = [arg.card]; + if (arg.card.cards) cards.addArray(arg.card.cards); cards.addArray(ui.selected.cards); - var hhs=function(card){ + var hhs = function (card) { return !cards.includes(card); }; - var hs=player.countCards('h',hhs); - for(var i of list){ - if(i.countCards('h',hhs)>hs) return false; + var hs = player.countCards("h", hhs); + for (var i of list) { + if (i.countCards("h", hhs) > hs) return false; } return true; }, @@ -8502,2431 +11422,3008 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, //刘巴 - gztongduo:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - if(player!=event.player&&!player.hasSkill('gztongduo')||!event.player.isFriendOf(player)) return false; - return event.player.getHistory('lose',function(evt){ - return evt.type=='discard'&&evt.cards2.length>0&&evt.getParent('phaseDiscard').player==event.player; - }).length>0; + gztongduo: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + if ( + (player != event.player && !player.hasSkill("gztongduo")) || + !event.player.isFriendOf(player) + ) + return false; + return ( + event.player.getHistory("lose", function (evt) { + return ( + evt.type == "discard" && + evt.cards2.length > 0 && + evt.getParent("phaseDiscard").player == event.player + ); + }).length > 0 + ); }, - content:function(){ - 'step 0' - var num=0; - trigger.player.getHistory('lose',function(evt){ - if(evt.type=='discard'&&evt.getParent('phaseDiscard').player==trigger.player) num+=evt.cards2.length; + content: function () { + "step 0"; + var num = 0; + trigger.player.getHistory("lose", function (evt) { + if (evt.type == "discard" && evt.getParent("phaseDiscard").player == trigger.player) + num += evt.cards2.length; }); - num=Math.min(3,num); - event.num=num; - var next=trigger.player.chooseBool('是否发动【统度】摸'+get.cnNumber(num)+'张牌?'); - if(player==trigger.player) next.setHiddenSkill('gztongduo'); - 'step 1' - if(result.bool){ - player.logSkill('gztongduo',trigger.player); + num = Math.min(3, num); + event.num = num; + var next = trigger.player.chooseBool("是否发动【统度】摸" + get.cnNumber(num) + "张牌?"); + if (player == trigger.player) next.setHiddenSkill("gztongduo"); + "step 1"; + if (result.bool) { + player.logSkill("gztongduo", trigger.player); trigger.player.draw(num); } }, }, - qingyin:{ - audio:2, - enable:'phaseUse', - limited:true, - delay:false, - filter:function(event,player){ + qingyin: { + audio: 2, + enable: "phaseUse", + limited: true, + delay: false, + filter: function (event, player) { var isFriend; - if(player.identity=='unknown'){ - var group='shu'; - if(!player.wontYe('shu')) group=null; - isFriend=function(current){ - return current==player||current.identity==group; - } - } - else isFriend=function(target){ - return target.isFriendOf(player); - }; - return game.hasPlayer(function(current){ - return isFriend(current)&¤t.isDamaged(); + if (player.identity == "unknown") { + var group = "shu"; + if (!player.wontYe("shu")) group = null; + isFriend = function (current) { + return current == player || current.identity == group; + }; + } else + isFriend = function (target) { + return target.isFriendOf(player); + }; + return game.hasPlayer(function (current) { + return isFriend(current) && current.isDamaged(); }); }, - selectTarget:-1, - filterTarget:function(card,player,target){ - if(player==target) return true; - if(player.identity=='unknown'){ - var group='shu'; - if(!player.wontYe('shu')) return false; - return target.identity==group; + selectTarget: -1, + filterTarget: function (card, player, target) { + if (player == target) return true; + if (player.identity == "unknown") { + var group = "shu"; + if (!player.wontYe("shu")) return false; + return target.identity == group; } return target.isFriendOf(player); }, - selectCard:[0,1], - filterCard:()=>false, - multitarget:true, - multiline:true, - skillAnimation:true, - animationColor:'orange', - content:function(){ - 'step 0' - player.awakenSkill('qingyin'); - event.num=0; - 'step 1' - if(targets[num].isDamaged()){ - targets[num].recover(targets[num].maxHp-targets[num].hp); + selectCard: [0, 1], + filterCard: () => false, + multitarget: true, + multiline: true, + skillAnimation: true, + animationColor: "orange", + content: function () { + "step 0"; + player.awakenSkill("qingyin"); + event.num = 0; + "step 1"; + if (targets[num].isDamaged()) { + targets[num].recover(targets[num].maxHp - targets[num].hp); } event.num++; - if(event.num=(1/Math.max(1.6,game.roundNumber))?1:-1; + return num / max >= 1 / Math.max(1.6, game.roundNumber) ? 1 : -1; }, - result:{ - player:1, + result: { + player: 1, }, }, }, //苏飞 - gzlianpian:{ - audio:2, - trigger:{global:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - if(player!=event.player&&!player.hasSkill('gzlianpian')) return false; - var num=0; - game.getGlobalHistory('cardMove',function(evt){ - if(evt.name=='lose'&&evt.type=='discard'&&evt.getParent(2).player==event.player) num+=evt.cards2.length; + gzlianpian: { + audio: 2, + trigger: { global: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + if (player != event.player && !player.hasSkill("gzlianpian")) return false; + var num = 0; + game.getGlobalHistory("cardMove", function (evt) { + if ( + evt.name == "lose" && + evt.type == "discard" && + evt.getParent(2).player == event.player + ) + num += evt.cards2.length; }); - if(num<=player.hp) return false; - if(player==event.player) return game.hasPlayer(function(current){ - return current.isFriendOf(player)&¤t.countCards('h')0||player.isDamaged(); + if (num <= player.hp) return false; + if (player == event.player) + return game.hasPlayer(function (current) { + return current.isFriendOf(player) && current.countCards("h") < current.maxHp; + }); + return player.countDiscardableCards(event.player, "he") > 0 || player.isDamaged(); }, - content:function(){ - 'step 0' - if(player==trigger.player){ - player.chooseTarget(get.prompt('gzlianpian'),'令一名己方角色将手牌摸至手牌上限',function(card,player,target){ - return target.isFriendOf(player)&&target.maxHp>target.countCards('h'); - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.hasSkillTag('nogain')) att/=6; - if(att>2){ - return Math.min(5,target.maxHp)-target.countCards('h'); - } - return att/3; - }).setHiddenSkill(event.name); - } - else{ + content: function () { + "step 0"; + if (player == trigger.player) { + player + .chooseTarget( + get.prompt("gzlianpian"), + "令一名己方角色将手牌摸至手牌上限", + function (card, player, target) { + return target.isFriendOf(player) && target.maxHp > target.countCards("h"); + } + ) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.hasSkillTag("nogain")) att /= 6; + if (att > 2) { + return Math.min(5, target.maxHp) - target.countCards("h"); + } + return att / 3; + }) + .setHiddenSkill(event.name); + } else { event.goto(2); - event.addIndex=0; - var list=[],target=trigger.player,str=get.translation(player); - event.target=target; - if(player.countDiscardableCards(target,'he')>0) list.push('弃置'+str+'的一张牌'); + event.addIndex = 0; + var list = [], + target = trigger.player, + str = get.translation(player); + event.target = target; + if (player.countDiscardableCards(target, "he") > 0) + list.push("弃置" + str + "的一张牌"); else event.addIndex++; - if(player.isDamaged()) list.push('令'+str+'回复1点体力'); - target.chooseControl('cancel2').set('choiceList',list).set('ai',function(){ - var evt=_status.event.getParent(); - if(get.attitude(evt.target,evt.player)>0) return 1-evt.addIndex; - return evt.addIndex; - }).set('prompt','是否对'+str+'发动【连翩】?'); + if (player.isDamaged()) list.push("令" + str + "回复1点体力"); + target + .chooseControl("cancel2") + .set("choiceList", list) + .set("ai", function () { + var evt = _status.event.getParent(); + if (get.attitude(evt.target, evt.player) > 0) return 1 - evt.addIndex; + return evt.addIndex; + }) + .set("prompt", "是否对" + str + "发动【连翩】?"); } - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzlianpian',target); - target.draw(Math.min(5,target.maxHp-target.countCards('h'))); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzlianpian", target); + target.draw(Math.min(5, target.maxHp - target.countCards("h"))); } event.finish(); - 'step 2' - if(result.control=='cancel2'){ + "step 2"; + if (result.control == "cancel2") { event.finish(); return; } - player.logSkill('gzlianpian',target,false); - target.line(player,'green'); - if(result.index+event.addIndex==0){ - target.discardPlayerCard('he',player,true); + player.logSkill("gzlianpian", target, false); + target.line(player, "green"); + if (result.index + event.addIndex == 0) { + target.discardPlayerCard("he", player, true); event.finish(); - } - else player.recover(); - 'step 3' + } else player.recover(); + "step 3"; game.delayx(); }, }, //冯熙 - gzyusui:{ - audio:'yusui', - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - return event.player!=player&&event.player.isIn()&&event.player.isEnemyOf(player)&&get.color(event.card)=='black'; + gzyusui: { + audio: "yusui", + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + return ( + event.player != player && + event.player.isIn() && + event.player.isEnemyOf(player) && + get.color(event.card) == "black" + ); }, - logTarget:'player', - check:function(event,player){ - var target=event.player; - if(player.hp<3||get.attitude(player,target)>-3) return false; - if(player.hp3) return true; + logTarget: "player", + check: function (event, player) { + var target = event.player; + if (player.hp < 3 || get.attitude(player, target) > -3) return false; + if (player.hp < target.hp) return true; + if (Math.min(target.maxHp, target.countCards("h")) > 3) return true; return false; }, - preHidden:true, - content:function(){ - 'step 0' + preHidden: true, + content: function () { + "step 0"; player.loseHp(); - event.target=trigger.player; - 'step 1' - event.addIndex=0; - var list=[]; - if(target.maxHp>0&&target.countCards('h')>0) list.push('令其弃置'+get.cnNumber(target.maxHp)+'张手牌'); + event.target = trigger.player; + "step 1"; + event.addIndex = 0; + var list = []; + if (target.maxHp > 0 && target.countCards("h") > 0) + list.push("令其弃置" + get.cnNumber(target.maxHp) + "张手牌"); else event.addIndex++; - if(target.hp>player.hp) list.push('令其失去'+get.cnNumber(target.hp-player.hp)+'点体力'); - if(!list.length) event.finish(); - else if(list.length==1) event._result={index:0}; - else player.chooseControl().set('choiceList',list).set('prompt','令'+get.translation(target)+'执行一项').set('ai',function(){ - var player=_status.event.player,target=_status.event.getParent().target; - return (target.hp-player.hp)>(Math.min(target.maxHp,target.countCards('h'))/2)?1:0; - }); - 'step 2' - if(result.index+event.addIndex==0) target.chooseToDiscard(target.maxHp,true,'h'); - else target.loseHp(target.hp-player.hp); + if (target.hp > player.hp) + list.push("令其失去" + get.cnNumber(target.hp - player.hp) + "点体力"); + if (!list.length) event.finish(); + else if (list.length == 1) event._result = { index: 0 }; + else + player + .chooseControl() + .set("choiceList", list) + .set("prompt", "令" + get.translation(target) + "执行一项") + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().target; + return target.hp - player.hp > + Math.min(target.maxHp, target.countCards("h")) / 2 + ? 1 + : 0; + }); + "step 2"; + if (result.index + event.addIndex == 0) target.chooseToDiscard(target.maxHp, true, "h"); + else target.loseHp(target.hp - player.hp); }, }, - gzboyan:{ - audio:'boyan', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer((target)=>lib.skill.gzboyan.filterTarget(null,player,target)); + gzboyan: { + audio: "boyan", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer((target) => lib.skill.gzboyan.filterTarget(null, player, target)); }, - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('h')0; - }); + content: function () { + "step 0"; + target.draw(Math.min(5, target.maxHp - target.countCards("h"))); + "step 1"; + target.addTempSkill("gzboyan_block"); + "step 2"; + if (target.isIn()) + player + .chooseBool("纵横:是否令" + get.translation(target) + "获得【驳言】?") + .set("ai", function () { + var evt = _status.event.getParent(); + return get.attitude(evt.player, evt.target) > 0; + }); else event.finish(); - 'step 3' - if(result.bool){ - target.addTempSkill('gzboyan_zongheng',{player:'phaseEnd'}); - game.log(player,'发起了','#y纵横',',令',target,'获得了技能','#g【驳言】'); + "step 3"; + if (result.bool) { + target.addTempSkill("gzboyan_zongheng", { player: "phaseEnd" }); + game.log(player, "发起了", "#y纵横", ",令", target, "获得了技能", "#g【驳言】"); } }, - derivation:'gzboyan_zongheng', - subSkill:{ - zongheng:{ - enable:'phaseUse', - usable:1, - filterTarget:lib.filter.notMe, - content:function(){ - target.addTempSkill('gzboyan_block'); + derivation: "gzboyan_zongheng", + subSkill: { + zongheng: { + enable: "phaseUse", + usable: 1, + filterTarget: lib.filter.notMe, + content: function () { + target.addTempSkill("gzboyan_block"); }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(target.countCards('h','shan')&&!target.hasSkillTag('respondShan',true,null,true)&&player.countCards('h',function(card){ - return get.tag(card,'respondShan')&&get.effect(target,card,player,player)>0&&player.getUseValue(card)>0; - })) return -target.countCards('h'); + ai: { + order: 4, + result: { + target: function (player, target) { + if ( + target.countCards("h", "shan") && + !target.hasSkillTag("respondShan", true, null, true) && + player.countCards("h", function (card) { + return ( + get.tag(card, "respondShan") && + get.effect(target, card, player, player) > 0 && + player.getUseValue(card) > 0 + ); + }) + ) + return -target.countCards("h"); return -0.5; }, }, }, }, - block:{ - mark:true, - intro:{content:'不能使用或打出手牌'}, - charlotte:true, - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + block: { + mark: true, + intro: { content: "不能使用或打出手牌" }, + charlotte: true, + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, }, }, }, - ai:{ - order:4, - result:{ - target:function(player,target){ - if(get.attitude(player,target)>0) return Math.min(5,target.maxHp-target.countCards('h')); - if(target.maxHp-target.countCards('h')==1&&target.countCards('h','shan')&&!target.hasSkillTag('respondShan',true,null,true)&&player.countCards('h',function(card){ - return get.tag(card,'respondShan')&&get.effect(target,card,player,player)>0&&player.getUseValue(card,null,true)>0; - })) return -2; + ai: { + order: 4, + result: { + target: function (player, target) { + if (get.attitude(player, target) > 0) + return Math.min(5, target.maxHp - target.countCards("h")); + if ( + target.maxHp - target.countCards("h") == 1 && + target.countCards("h", "shan") && + !target.hasSkillTag("respondShan", true, null, true) && + player.countCards("h", function (card) { + return ( + get.tag(card, "respondShan") && + get.effect(target, card, player, player) > 0 && + player.getUseValue(card, null, true) > 0 + ); + }) + ) + return -2; }, }, }, }, //文钦 - gzjinfa:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('he')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he')>0; - }) + gzjinfa: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + player.countCards("he") > 0 && + game.hasPlayer(function (current) { + return current != player && current.countCards("he") > 0; + }) + ); }, - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ - return target!=player&&target.countCards('he')>0; + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { + return target != player && target.countCards("he") > 0; }, - check:function(card){ - return 6-get.value(card); + check: function (card) { + return 6 - get.value(card); }, - content:function(){ - 'step 0' - target.chooseCard('he','交给'+get.translation(player)+'一张装备牌,或令其获得你的一张牌',{type:'equip'}).set('ai',function(card){ - if(_status.event.goon&&get.suit(card)=='spade') return 8-get.value(card); - return 5-get.value(card); - }).set('goon',target.canUse('sha',player,false)&&get.effect(player,{name:'sha'},target,target)>0); - 'step 1' - if(!result.bool){ - player.gainPlayerCard(target,'he',true); + content: function () { + "step 0"; + target + .chooseCard( + "he", + "交给" + get.translation(player) + "一张装备牌,或令其获得你的一张牌", + { type: "equip" } + ) + .set("ai", function (card) { + if (_status.event.goon && get.suit(card) == "spade") return 8 - get.value(card); + return 5 - get.value(card); + }) + .set( + "goon", + target.canUse("sha", player, false) && + get.effect(player, { name: "sha" }, target, target) > 0 + ); + "step 1"; + if (!result.bool) { + player.gainPlayerCard(target, "he", true); event.finish(); - } - else target.give(result.cards,player); - 'step 2' - if(result.bool&&result.cards&&result.cards.length&& - target.isIn()&&player.isIn()&&get.suit(result.cards[0],target)=='spade'&&target.canUse('sha',player,false)) target.useCard({name:'sha',isCard:true},false,player); + } else target.give(result.cards, player); + "step 2"; + if ( + result.bool && + result.cards && + result.cards.length && + target.isIn() && + player.isIn() && + get.suit(result.cards[0], target) == "spade" && + target.canUse("sha", player, false) + ) + target.useCard({ name: "sha", isCard: true }, false, player); }, - ai:{ - order:6, - result:{ - player:function(player,target){ - if(target.countCards('e',function(card){ - return get.suit(card)=='spade'&&get.value(card)<8; - })&&target.canUse('sha',player,false)) return get.effect(player,{name:'sha'},target,player); + ai: { + order: 6, + result: { + player: function (player, target) { + if ( + target.countCards("e", function (card) { + return get.suit(card) == "spade" && get.value(card) < 8; + }) && + target.canUse("sha", player, false) + ) + return get.effect(player, { name: "sha" }, target, player); return 0; }, - target:function(player,target){ - var es=target.getCards('e').sort(function(a,b){ - return get.value(b,target)-get.value(a,target); + target: function (player, target) { + var es = target.getCards("e").sort(function (a, b) { + return get.value(b, target) - get.value(a, target); }); - if(es.length) return -Math.min(2,get.value(es[0])) + if (es.length) return -Math.min(2, get.value(es[0])); return -2; }, }, }, }, //诸葛恪 - gzduwu:{ - limited:true, - audio:2, - enable:'phaseUse', - delay:false, - filter:function(event,player){ + gzduwu: { + limited: true, + audio: 2, + enable: "phaseUse", + delay: false, + filter: function (event, player) { var isEnemy; - if(player.identity=='unknown'){ - if(!player.wontYe('wu')) isEnemy=function(current){ - return current!=player; + if (player.identity == "unknown") { + if (!player.wontYe("wu")) + isEnemy = function (current) { + return current != player; + }; + else + isEnemy = function (current) { + return current != player && current.identity != "wu"; + }; + } else + isEnemy = function (target) { + return target.isEnemyOf(player); }; - else isEnemy=function(current){ - return current!=player&¤t.identity!='wu'; - } - } - else isEnemy=function(target){ - return target.isEnemyOf(player); - }; - return game.hasPlayer(function(current){ - return isEnemy(current)&&player.inRange(current); + return game.hasPlayer(function (current) { + return isEnemy(current) && player.inRange(current); }); }, - filterTarget:function(card,player,target){ - if(player==target||!player.inRange(target)) return false; - if(player.identity=='unknown'){ - if(!player.wontYe('wu')) return true; - return target.identity!='wu'; + filterTarget: function (card, player, target) { + if (player == target || !player.inRange(target)) return false; + if (player.identity == "unknown") { + if (!player.wontYe("wu")) return true; + return target.identity != "wu"; } return target.isEnemyOf(player); }, - selectTarget:-1, - filterCard:()=>false, - selectCard:[0,1], - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - player.awakenSkill('gzduwu'); - player.addSkill('gzduwu_count'); + selectTarget: -1, + filterCard: () => false, + selectCard: [0, 1], + multitarget: true, + multiline: true, + content: function () { + "step 0"; + player.awakenSkill("gzduwu"); + player.addSkill("gzduwu_count"); targets.sortBySeat(); - event.players=targets.slice(0); + event.players = targets.slice(0); game.delayx(); - player.chooseJunlingFor(event.players[0]).set('prompt','为所有目标角色选择军令牌'); - 'step 1' - event.junling=result.junling; - event.targets=result.targets; - event.num=0; - 'step 2' - if(num(get.damageEffect(evt.current,evt.player,evt.current)/get.attitude(evt.current,evt.current))?0:1; - }); - } - else event.goto(4); - 'step 3' - if(result.index==0){ - event.current.carryOutJunling(player,event.junling,targets); - } - else{ + player.chooseJunlingFor(event.players[0]).set("prompt", "为所有目标角色选择军令牌"); + "step 1"; + event.junling = result.junling; + event.targets = result.targets; + event.num = 0; + "step 2"; + if (num < event.players.length) event.current = event.players[num]; + if (event.current && event.current.isAlive()) { + event.current + .chooseJunlingControl(player, event.junling, targets) + .set("prompt", "黩武") + .set("choiceList", ["执行该军令", "不执行该军令并受到1点伤害"]) + .set("ai", function () { + var evt = _status.event.getParent(2); + return get.junlingEffect( + evt.player, + evt.junling, + evt.current, + evt.targets, + evt.current + ) > + get.damageEffect(evt.current, evt.player, evt.current) / + get.attitude(evt.current, evt.current) + ? 0 + : 1; + }); + } else event.goto(4); + "step 3"; + if (result.index == 0) { + event.current.carryOutJunling(player, event.junling, targets); + } else { player.draw(); event.current.damage(); } - 'step 4' + "step 4"; game.delayx(); event.num++; - if(event.num0&&player.canUse('sha',event.player,false); + gzxishe: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + event.player != player && + event.player.isIn() && + player.countCards("e") > 0 && + player.canUse("sha", event.player, false) + ); }, - content:function(){ - 'step 0' - player.chooseCard('e',get.prompt('gzxishe',trigger.player),'将装备区内的一张牌当做'+(player.hp>trigger.player.hp?'不可响应的':'')+'【杀】对其使用',function(card,player){ - return player.canUse({ - name:'sha', - cards:[card], - },_status.event.target,false); - }).set('target',trigger.player).set('ai',function(card){ - var evt=_status.event,eff=get.effect(evt.target,{ - name:'sha', - cards:[card], - },evt.player,evt.player); - if(eff<=0) return 0; - var val=get.value(card); - if(get.attitude(evt.player,evt.target)<-2&&evt.target.hp<=Math.min(2,evt.player.countCards('e'),evt.player.hp-1)) return 2/Math.max(1,val); - return eff-val; - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - var next=player.useCard({name:'sha'},result.cards,'gzxishe',trigger.player,false); - if(player.hp>trigger.player.hp) next.oncard=function(){ - _status.event.directHit.add(trigger.player); - } - } - else event.finish(); - 'step 2' - if(trigger.player.isDead()){ - player.mayChangeVice(null,'hidden'); - } - else if(lib.skill.gzxishe.filter(trigger,player)) event.goto(0); + content: function () { + "step 0"; + player + .chooseCard( + "e", + get.prompt("gzxishe", trigger.player), + "将装备区内的一张牌当做" + + (player.hp > trigger.player.hp ? "不可响应的" : "") + + "【杀】对其使用", + function (card, player) { + return player.canUse( + { + name: "sha", + cards: [card], + }, + _status.event.target, + false + ); + } + ) + .set("target", trigger.player) + .set("ai", function (card) { + var evt = _status.event, + eff = get.effect( + evt.target, + { + name: "sha", + cards: [card], + }, + evt.player, + evt.player + ); + if (eff <= 0) return 0; + var val = get.value(card); + if ( + get.attitude(evt.player, evt.target) < -2 && + evt.target.hp <= Math.min(2, evt.player.countCards("e"), evt.player.hp - 1) + ) + return 2 / Math.max(1, val); + return eff - val; + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + var next = player.useCard( + { name: "sha" }, + result.cards, + "gzxishe", + trigger.player, + false + ); + if (player.hp > trigger.player.hp) + next.oncard = function () { + _status.event.directHit.add(trigger.player); + }; + } else event.finish(); + "step 2"; + if (trigger.player.isDead()) { + player.mayChangeVice(null, "hidden"); + } else if (lib.skill.gzxishe.filter(trigger, player)) event.goto(0); }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - if(_status.event.getParent().name=='gzxishe'&&arg.card&&arg.card.name=='sha'&& - arg.target&&arg.target==_status.event.target&&player.hp>arg.target.hp) return true; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + if ( + _status.event.getParent().name == "gzxishe" && + arg.card && + arg.card.name == "sha" && + arg.target && + arg.target == _status.event.target && + player.hp > arg.target.hp + ) + return true; return false; }, }, }, //公孙渊 - gzhuaiyi:{ - audio:2, - enable:'phaseUse', - usable:1, - delay:false, - filter:function(event,player){ - return player.countCards('h')>0; + gzhuaiyi: { + audio: 2, + enable: "phaseUse", + usable: 1, + delay: false, + filter: function (event, player) { + return player.countCards("h") > 0; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - if(!player.countCards('h',{color:'red'})) event._result={control:'黑色'}; - else if(!player.countCards('h',{color:'black'})) event._result={control:'红色'}; - else player.chooseControl('红色','黑色').set('ai',function(){ - var player=_status.event.player,num=player.maxHp-player.getExpansions('gzhuaiyi').length; - if(player.countCards('h',{color:'red'})<=num&& - player.countCards('h',{color:'black'})>num) return '红色'; - return '黑色'; - }); - 'step 2' - event.control=result.control; + "step 1"; + if (!player.countCards("h", { color: "red" })) event._result = { control: "黑色" }; + else if (!player.countCards("h", { color: "black" })) event._result = { control: "红色" }; + else + player.chooseControl("红色", "黑色").set("ai", function () { + var player = _status.event.player, + num = player.maxHp - player.getExpansions("gzhuaiyi").length; + if ( + player.countCards("h", { color: "red" }) <= num && + player.countCards("h", { color: "black" }) > num + ) + return "红色"; + return "黑色"; + }); + "step 2"; + event.control = result.control; var cards; - if(event.control=='红色'){ - cards=player.getCards('h',{color:'red'}); - } - else{ - cards=player.getCards('h',{color:'black'}); + if (event.control == "红色") { + cards = player.getCards("h", { color: "red" }); + } else { + cards = player.getCards("h", { color: "black" }); } player.discard(cards); - event.num=cards.length; - 'step 3' - player.chooseTarget('请选择至多'+get.cnNumber(event.num)+'名有牌的其他角色,获得这些角色的各一张牌。',[1,event.num],function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target)+0.5; - }); - 'step 4' - if(result.bool&&result.targets){ - player.line(result.targets,'green'); - event.targets=result.targets; + event.num = cards.length; + "step 3"; + player + .chooseTarget( + "请选择至多" + + get.cnNumber(event.num) + + "名有牌的其他角色,获得这些角色的各一张牌。", + [1, event.num], + function (card, player, target) { + return target != player && target.countCards("he") > 0; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target) + 0.5; + }); + "step 4"; + if (result.bool && result.targets) { + player.line(result.targets, "green"); + event.targets = result.targets; event.targets.sort(lib.sort.seat); - event.cards=[]; - } - else{ + event.cards = []; + } else { event.finish(); } - 'step 5' - if(player.isAlive()&&event.targets.length){ - player.gainPlayerCard(event.targets.shift(),'he',true); - } - else event.finish(); - 'step 6' - if(result.bool&&result.cards&&result.cards.length) event.cards.addArray(result.cards); - if(event.targets.length) event.goto(5); - 'step 7' - var hs=player.getCards('h'); - cards=cards.filter(function(card){ - return get.type(card)=='equip'&&hs.includes(card); + "step 5"; + if (player.isAlive() && event.targets.length) { + player.gainPlayerCard(event.targets.shift(), "he", true); + } else event.finish(); + "step 6"; + if (result.bool && result.cards && result.cards.length) + event.cards.addArray(result.cards); + if (event.targets.length) event.goto(5); + "step 7"; + var hs = player.getCards("h"); + cards = cards.filter(function (card) { + return get.type(card) == "equip" && hs.includes(card); }); - if(cards.length){ - player.addToExpansion(cards,player,'give').gaintag.add('gzhuaiyi'); + if (cards.length) { + player.addToExpansion(cards, player, "give").gaintag.add("gzhuaiyi"); } }, - ai:{ - order:10, - result:{ - player:function(player,target){ - var num=player.maxHp-player.getExpansions('gzhuaiyi').length; - if(player.countCards('h',{color:'red'})<=num) return 1; - if(player.countCards('h',{color:'black'})<=num) return 1; + ai: { + order: 10, + result: { + player: function (player, target) { + var num = player.maxHp - player.getExpansions("gzhuaiyi").length; + if (player.countCards("h", { color: "red" }) <= num) return 1; + if (player.countCards("h", { color: "black" }) <= num) return 1; return 0; }, - } + }, }, - marktext:'异', - intro:{content:'expansion',markcount:'expansion'}, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + marktext: "异", + intro: { content: "expansion", markcount: "expansion" }, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, }, - gzzisui:{ - audio:2, - trigger:{player:'phaseDrawBegin2'}, - forced:true, - filter:function(event,player){ - return !event.numFixed&&player.getExpansions('gzhuaiyi').length>0; + gzzisui: { + audio: 2, + trigger: { player: "phaseDrawBegin2" }, + forced: true, + filter: function (event, player) { + return !event.numFixed && player.getExpansions("gzhuaiyi").length > 0; }, - content:function(){ - trigger.num+=player.getExpansions('gzhuaiyi').length; + content: function () { + trigger.num += player.getExpansions("gzhuaiyi").length; }, - group:'gzzisui_die', - subSkill:{ - die:{ - audio:'gzzisui', - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('gzhuaiyi').length>player.maxHp; + group: "gzzisui_die", + subSkill: { + die: { + audio: "gzzisui", + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("gzhuaiyi").length > player.maxHp; }, - content:function(){ + content: function () { player.die(); }, }, }, }, //潘濬 - gzcongcha:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.isUnseen(); - }) - }, - preHidden:'gzcongcha_draw', - prompt2:'选择一名武将牌均暗置的其他角色', - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('gzcongcha'),function(card,player,target){ - return target!=player&&target.isUnseen(); - }).set('ai',function(target){ - if(get.attitude(_status.event.player,target)>0) return Math.random()+Math.sqrt(target.hp); - return Math.random()+Math.sqrt(Math.max(1,4-target.hp)); + gzcongcha: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.isUnseen(); }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.logSkill('gzcongcha',target); - player.storage.gzcongcha2=target; - player.addTempSkill('gzcongcha2',{player:'phaseBegin'}); - target.addSkill('gzcongcha_ai'); + }, + preHidden: "gzcongcha_draw", + prompt2: "选择一名武将牌均暗置的其他角色", + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gzcongcha"), function (card, player, target) { + return target != player && target.isUnseen(); + }) + .set("ai", function (target) { + if (get.attitude(_status.event.player, target) > 0) + return Math.random() + Math.sqrt(target.hp); + return Math.random() + Math.sqrt(Math.max(1, 4 - target.hp)); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("gzcongcha", target); + player.storage.gzcongcha2 = target; + player.addTempSkill("gzcongcha2", { player: "phaseBegin" }); + target.addSkill("gzcongcha_ai"); game.delayx(); } }, - subfrequent:['draw'], - group:'gzcongcha_draw', - subSkill:{ - draw:{ - audio:'gzcongcha', - trigger:{player:'phaseDrawBegin2'}, - frequent:true, - filter:function(event,player){ - return !event.numFixed&&!game.hasPlayer(function(current){ - return current.isUnseen(); - }); + subfrequent: ["draw"], + group: "gzcongcha_draw", + subSkill: { + draw: { + audio: "gzcongcha", + trigger: { player: "phaseDrawBegin2" }, + frequent: true, + filter: function (event, player) { + return ( + !event.numFixed && + !game.hasPlayer(function (current) { + return current.isUnseen(); + }) + ); }, - prompt:'是否发动【聪察】多摸两张牌?', - content:function(){ - trigger.num+=2; + prompt: "是否发动【聪察】多摸两张牌?", + content: function () { + trigger.num += 2; }, }, }, }, - gzcongcha_ai:{ - charlotte:true, - ai:{ - mingzhi_yes:true, - mingzhi_no:true, - skillTagFilter:function(player,tag){ - if(_status.brawl) return false; - var group=lib.character[player.name1][1]; - if(tag=='mingzhi_yes'){ - if(group!='ye'&&player.wontYe(group)&&game.hasPlayer(function(current){ - return current.storage.gzcongcha2==player&¤t.identity==group; - })) return true; + gzcongcha_ai: { + charlotte: true, + ai: { + mingzhi_yes: true, + mingzhi_no: true, + skillTagFilter: function (player, tag) { + if (_status.brawl) return false; + var group = lib.character[player.name1][1]; + if (tag == "mingzhi_yes") { + if ( + group != "ye" && + player.wontYe(group) && + game.hasPlayer(function (current) { + return current.storage.gzcongcha2 == player && current.identity == group; + }) + ) + return true; return false; } - if(group=='ye'&&!player.wontYe(group)) return true; - return game.hasPlayer(function(current){ - return current.storage.gzcongcha2==player&¤t.identity!=group; - }) + if (group == "ye" && !player.wontYe(group)) return true; + return game.hasPlayer(function (current) { + return current.storage.gzcongcha2 == player && current.identity != group; + }); }, }, }, - gzcongcha2:{ - trigger:{global:'showCharacterAfter'}, - forced:true, - charlotte:true, - onremove:true, - filter:function(event,player){ - return event.player==player.storage.gzcongcha2; + gzcongcha2: { + trigger: { global: "showCharacterAfter" }, + forced: true, + charlotte: true, + onremove: true, + filter: function (event, player) { + return event.player == player.storage.gzcongcha2; }, - logTarget:'player', - content:function(){ - 'step 0' - player.removeSkill('gzcongcha2'); - trigger.player.removeSkill('gzcongcha_ai'); - if(player.isFriendOf(trigger.player)) game.asyncDraw([player,trigger.player].sortBySeat(_status.currentPhase),2); + logTarget: "player", + content: function () { + "step 0"; + player.removeSkill("gzcongcha2"); + trigger.player.removeSkill("gzcongcha_ai"); + if (player.isFriendOf(trigger.player)) + game.asyncDraw([player, trigger.player].sortBySeat(_status.currentPhase), 2); else trigger.player.loseHp(); - 'step 1' + "step 1"; game.delayx(); }, - mark:'character', - intro:{content:'已指定$为目标'}, + mark: "character", + intro: { content: "已指定$为目标" }, }, //司马昭 - gzzhaoxin:{ - audio:2, - trigger:{player:'damageEnd'}, - filter:function(event,player){ - return player.countCards('h')>0; + gzzhaoxin: { + audio: 2, + trigger: { player: "damageEnd" }, + filter: function (event, player) { + return player.countCards("h") > 0; }, - check:()=>false, - preHidden:true, - content:function(){ - 'step 0' + check: () => false, + preHidden: true, + content: function () { + "step 0"; player.showHandcards(); - 'step 1' - var hs=player.countCards('h'); - if(game.hasPlayer(function(current){ - return current!=player&¤t.countCards('h')<=hs; - })){ - player.chooseTarget(true,'请选择要交换手牌的目标角色',function(card,player,target){ - return target!=player&&target.countCards('h')<=player.countCards('h'); + "step 1"; + var hs = player.countCards("h"); + if ( + game.hasPlayer(function (current) { + return current != player && current.countCards("h") <= hs; }) - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + ) { + player.chooseTarget( + true, + "请选择要交换手牌的目标角色", + function (card, player, target) { + return target != player && target.countCards("h") <= player.countCards("h"); + } + ); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); player.swapHandcards(target); } }, }, - gzsuzhi:{ - audio:2, - derivation:'gzfankui', - mod:{ - targetInRange:function(card,player,target){ - if(player==_status.currentPhase&&player.countMark('gzsuzhi_count')<3&&get.type2(card)=='trick') return true; + gzsuzhi: { + audio: 2, + derivation: "gzfankui", + mod: { + targetInRange: function (card, player, target) { + if ( + player == _status.currentPhase && + player.countMark("gzsuzhi_count") < 3 && + get.type2(card) == "trick" + ) + return true; }, }, - trigger:{player:'phaseJieshuBegin'}, - forced:true, - filter:function(event,player){ - return player.countMark('gzsuzhi_count')<3; + trigger: { player: "phaseJieshuBegin" }, + forced: true, + filter: function (event, player) { + return player.countMark("gzsuzhi_count") < 3; }, - content:function(){ - player.addTempSkills('gzfankui',{player:'phaseBegin'}); + content: function () { + player.addTempSkills("gzfankui", { player: "phaseBegin" }); }, - group:['gzsuzhi_damage','gzsuzhi_draw','gzsuzhi_gain'], - preHidden:['gzsuzhi_damage','gzsuzhi_draw','gzsuzhi_gain'], - subSkill:{ - damage:{ - audio:'gzsuzhi', - trigger:{source:'damageBegin1'}, - forced:true, - filter:function(event,player){ - return player==_status.currentPhase&&player.countMark('gzsuzhi_count')<3&&event.card&& - (event.card.name=='sha'||event.card.name=='juedou')&&event.getParent().type=='card'; + group: ["gzsuzhi_damage", "gzsuzhi_draw", "gzsuzhi_gain"], + preHidden: ["gzsuzhi_damage", "gzsuzhi_draw", "gzsuzhi_gain"], + subSkill: { + damage: { + audio: "gzsuzhi", + trigger: { source: "damageBegin1" }, + forced: true, + filter: function (event, player) { + return ( + player == _status.currentPhase && + player.countMark("gzsuzhi_count") < 3 && + event.card && + (event.card.name == "sha" || event.card.name == "juedou") && + event.getParent().type == "card" + ); }, - content:function(){ + content: function () { trigger.num++; - player.addTempSkill('gzsuzhi_count'); - player.addMark('gzsuzhi_count',1,false); + player.addTempSkill("gzsuzhi_count"); + player.addMark("gzsuzhi_count", 1, false); }, }, - draw:{ - audio:'gzsuzhi', - trigger:{player:'useCard'}, - forced:true, - filter:function(event,player){ - return player==_status.currentPhase&&player.countMark('gzsuzhi_count')<3&&event.card.isCard&&get.type2(event.card)=='trick'; + draw: { + audio: "gzsuzhi", + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return ( + player == _status.currentPhase && + player.countMark("gzsuzhi_count") < 3 && + event.card.isCard && + get.type2(event.card) == "trick" + ); }, - content:function(){ + content: function () { player.draw(); - player.addTempSkill('gzsuzhi_count'); - player.addMark('gzsuzhi_count',1,false); + player.addTempSkill("gzsuzhi_count"); + player.addMark("gzsuzhi_count", 1, false); }, }, - gain:{ - audio:'gzsuzhi', - trigger:{global:'loseAfter'}, - forced:true, - filter:function(event,player){ - if(player!=_status.currentPhase||event.type!='discard'||player==event.player||player.countMark('gzsuzhi_count')>=3) return false; - return event.player.countGainableCards(player,'he')>0; + gain: { + audio: "gzsuzhi", + trigger: { global: "loseAfter" }, + forced: true, + filter: function (event, player) { + if ( + player != _status.currentPhase || + event.type != "discard" || + player == event.player || + player.countMark("gzsuzhi_count") >= 3 + ) + return false; + return event.player.countGainableCards(player, "he") > 0; }, - logTarget:'player', - content:function(){ - 'step 0' - player.addTempSkill('gzsuzhi_count'); - player.addMark('gzsuzhi_count',1,false); - if(trigger.delay==false) game.delay(); - 'step 1' - player.gainPlayerCard(trigger.player,'he',true); + logTarget: "player", + content: function () { + "step 0"; + player.addTempSkill("gzsuzhi_count"); + player.addMark("gzsuzhi_count", 1, false); + if (trigger.delay == false) game.delay(); + "step 1"; + player.gainPlayerCard(trigger.player, "he", true); }, }, - count:{ - onremove:true, + count: { + onremove: true, }, }, }, - gzfankui:{ - audio:2, - inherit:'fankui', + gzfankui: { + audio: 2, + inherit: "fankui", }, //夏侯霸 - gzbaolie:{ - audio:2, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='sha'&&target.hp>=player.hp) return true; + gzbaolie: { + audio: 2, + mod: { + targetInRange: function (card, player, target) { + if (card.name == "sha" && target.hp >= player.hp) return true; }, - cardUsableTarget:function(card,player,target){ - if(card.name=='sha'&&target.hp>=player.hp) return true; + cardUsableTarget: function (card, player, target) { + if (card.name == "sha" && target.hp >= player.hp) return true; }, }, - trigger:{player:'phaseUseBegin'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.isEnemyOf(player)&&player.inRangeOf(current); + trigger: { player: "phaseUseBegin" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.isEnemyOf(player) && player.inRangeOf(current); }); }, - logTarget:function(event,player){ - return game.filterPlayer(function(current){ - return current.isEnemyOf(player)&&player.inRangeOf(current); + logTarget: function (event, player) { + return game.filterPlayer(function (current) { + return current.isEnemyOf(player) && player.inRangeOf(current); }); }, - check:()=>false, - content:function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return current.isEnemyOf(player)&&player.inRangeOf(current); - }).sortBySeat(); - 'step 1' - var target=event.targets.shift(); - if(target.isIn()){ - event.target=target; - target.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'豹烈:对'+get.translation(player)+'使用一张杀,或令其弃置你的一张牌').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); - }).set('sourcex',player); - } - else if(targets.length) event.redo(); + check: () => false, + content: function () { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return current.isEnemyOf(player) && player.inRangeOf(current); + }) + .sortBySeat(); + "step 1"; + var target = event.targets.shift(); + if (target.isIn()) { + event.target = target; + target + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "豹烈:对" + get.translation(player) + "使用一张杀,或令其弃置你的一张牌") + .set("targetRequired", true) + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.filterTarget.apply(this, arguments); + }) + .set("sourcex", player); + } else if (targets.length) event.redo(); else event.finish(); - 'step 2' - if(result.bool==false&&target.countCards('he')>0){ - player.discardPlayerCard(target,'he',true); + "step 2"; + if (result.bool == false && target.countCards("he") > 0) { + player.discardPlayerCard(target, "he", true); } - if(targets.length) event.goto(1); + if (targets.length) event.goto(1); }, }, //许攸 - gzchenglve:{ - audio:2, - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - return event.targets.length>1&&event.player.isIn()&&event.player.isFriendOf(player); + gzchenglve: { + audio: 2, + trigger: { global: "useCardAfter" }, + filter: function (event, player) { + return event.targets.length > 1 && event.player.isIn() && event.player.isFriendOf(player); }, - logTarget:'player', - check:function(event,player){ - return get.attitude(player,event.player)>0; + logTarget: "player", + check: function (event, player) { + return get.attitude(player, event.player) > 0; }, - preHidden:true, - content:function(){ - 'step 0' + preHidden: true, + content: function () { + "step 0"; trigger.player.draw(); - if(player.hasHistory('damage',function(evt){ - return evt.card==trigger.card; - })&&game.hasPlayer(function(current){ - return current.isFriendOf(player)&&(!current.hasMark('yexinjia_mark')&&!current.hasMark('xianqu_mark')&&!current.hasMark('yinyang_mark')&&!current.hasMark('zhulianbihe_mark')) - })){ - player.chooseTarget('是否令一名己方角色获得“阴阳鱼”标记?',function(card,player,current){ - return current.isFriendOf(player)&&(!current.hasMark('yexinjia_mark')&&!current.hasMark('xianqu_mark')&&!current.hasMark('yinyang_mark')&&!current.hasMark('zhulianbihe_mark')); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target)*Math.sqrt(1+target.needsToDiscard()); - }); - } - else event.finish(); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - target.addMark('yinyang_mark',1,false); + if ( + player.hasHistory("damage", function (evt) { + return evt.card == trigger.card; + }) && + game.hasPlayer(function (current) { + return ( + current.isFriendOf(player) && + !current.hasMark("yexinjia_mark") && + !current.hasMark("xianqu_mark") && + !current.hasMark("yinyang_mark") && + !current.hasMark("zhulianbihe_mark") + ); + }) + ) { + player + .chooseTarget( + "是否令一名己方角色获得“阴阳鱼”标记?", + function (card, player, current) { + return ( + current.isFriendOf(player) && + !current.hasMark("yexinjia_mark") && + !current.hasMark("xianqu_mark") && + !current.hasMark("yinyang_mark") && + !current.hasMark("zhulianbihe_mark") + ); + } + ) + .set("ai", function (target) { + return ( + get.attitude(_status.event.player, target) * + Math.sqrt(1 + target.needsToDiscard()) + ); + }); + } else event.finish(); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + target.addMark("yinyang_mark", 1, false); game.delayx(); } }, }, - gzshicai:{ - audio:2, - trigger:{player:'damageEnd'}, - forced:true, - preHidden:true, - filter:function(event,player){ - return event.num==1||player.countCards('he')>0; + gzshicai: { + audio: 2, + trigger: { player: "damageEnd" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return event.num == 1 || player.countCards("he") > 0; }, - check:function(event,player){ - return event.num==1; + check: function (event, player) { + return event.num == 1; }, - content:function(){ - if(trigger.num==1) player.draw(); - else player.chooseToDiscard(true,'he',2); + content: function () { + if (trigger.num == 1) player.draw(); + else player.chooseToDiscard(true, "he", 2); }, }, - gzzhuosheng:{ - audio:'zhuosheng', - trigger:{global:'damageEnd'}, - logTarget:'player', - filter:function(event,player){ + gzzhuosheng: { + audio: "zhuosheng", + trigger: { global: "damageEnd" }, + logTarget: "player", + filter: function (event, player) { return event.player.isFriendOf(player); }, - preHidden:true, - content:function(){ - var target=trigger.player; - target.addTempSkill('gzzhuosheng2',{player:'phaseJieshuBegin'}); - target.draw().gaintag=['gzzhuosheng2']; + preHidden: true, + content: function () { + var target = trigger.player; + target.addTempSkill("gzzhuosheng2", { player: "phaseJieshuBegin" }); + target.draw().gaintag = ["gzzhuosheng2"]; }, }, - gzzhuosheng2:{ - onremove:function(player,skill){ + gzzhuosheng2: { + onremove: function (player, skill) { player.removeGaintag(skill); }, - mod:{ - targetInRange:function(card,player,target){ - if(!card.cards||get.type(card)!='basic') return; - for(var i of card.cards){ - if(i.hasGaintag('gzzhuosheng2')) return (game.online?player==_status.currentPhase:player.isPhaseUsing()); + mod: { + targetInRange: function (card, player, target) { + if (!card.cards || get.type(card) != "basic") return; + for (var i of card.cards) { + if (i.hasGaintag("gzzhuosheng2")) + return game.online ? player == _status.currentPhase : player.isPhaseUsing(); } }, - cardUsable:function(card,player,target){ - if(!card.cards||get.type(card)!='basic'||!(game.online?player==_status.currentPhase:player.isPhaseUsing())) return; - for(var i of card.cards){ - if(i.hasGaintag('gzzhuosheng2')) return Infinity; + cardUsable: function (card, player, target) { + if ( + !card.cards || + get.type(card) != "basic" || + !(game.online ? player == _status.currentPhase : player.isPhaseUsing()) + ) + return; + for (var i of card.cards) { + if (i.hasGaintag("gzzhuosheng2")) return Infinity; } }, - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('gzzhuosheng2')&&get.type(card)=='basic') return num-0.1; + aiOrder: function (player, card, num) { + if ( + get.itemtype(card) == "card" && + card.hasGaintag("gzzhuosheng2") && + get.type(card) == "basic" + ) + return num - 0.1; }, }, - audio:'zhuosheng', - trigger:{player:'useCard2'}, - direct:true, - filterx:function(event,player){ - if(!player.isPhaseUsing()) return false; - return player.getHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('gzzhuosheng2')) return true; - } - return false; - }).length>0; + audio: "zhuosheng", + trigger: { player: "useCard2" }, + direct: true, + filterx: function (event, player) { + if (!player.isPhaseUsing()) return false; + return ( + player.getHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("gzzhuosheng2")) return true; + } + return false; + }).length > 0 + ); }, - filter:function(event,player){ - if(!lib.skill.gzzhuosheng2.filterx(event,player)) return false; - if(get.type(event.card)!='trick') return false; - if(event.targets&&event.targets.length>0) return true; - var info=get.info(event.card); - if(info.allowMultiple==false) return false; - if(event.targets&&!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(event.card,player,current)&&lib.filter.targetInRange(event.card,player,current); - })){ + filter: function (event, player) { + if (!lib.skill.gzzhuosheng2.filterx(event, player)) return false; + if (get.type(event.card) != "trick") return false; + if (event.targets && event.targets.length > 0) return true; + var info = get.info(event.card); + if (info.allowMultiple == false) return false; + if (event.targets && !info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(event.card, player, current) && + lib.filter.targetInRange(event.card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var prompt2='为'+get.translation(trigger.card)+'增加或减少一个目标' - player.chooseTarget(get.prompt('gzzhuosheng2'),function(card,player,target){ - var player=_status.event.player; - if(_status.event.targets.includes(target)) return true; - return lib.filter.targetEnabled2(_status.event.card,player,target)&&lib.filter.targetInRange(_status.event.card,player,target); - }).set('prompt2',prompt2).set('ai',function(target){ - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player)*(_status.event.targets.includes(target)?-1:1); - }).set('targets',trigger.targets).set('card',trigger.card); - 'step 1' - if(result.bool){ - if(!event.isMine()&&!event.isOnline()) game.delayx(); - event.targets=result.targets; - } - else{ + content: function () { + "step 0"; + var prompt2 = "为" + get.translation(trigger.card) + "增加或减少一个目标"; + player + .chooseTarget(get.prompt("gzzhuosheng2"), function (card, player, target) { + var player = _status.event.player; + if (_status.event.targets.includes(target)) return true; + return ( + lib.filter.targetEnabled2(_status.event.card, player, target) && + lib.filter.targetInRange(_status.event.card, player, target) + ); + }) + .set("prompt2", prompt2) + .set("ai", function (target) { + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return ( + get.effect(target, trigger.card, player, player) * + (_status.event.targets.includes(target) ? -1 : 1) + ); + }) + .set("targets", trigger.targets) + .set("card", trigger.card); + "step 1"; + if (result.bool) { + if (!event.isMine() && !event.isOnline()) game.delayx(); + event.targets = result.targets; + } else { event.finish(); } - 'step 2' - if(event.targets){ - player.logSkill('gzzhuosheng2',event.targets); - if(trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets); + "step 2"; + if (event.targets) { + player.logSkill("gzzhuosheng2", event.targets); + if (trigger.targets.includes(event.targets[0])) + trigger.targets.removeArray(event.targets); else trigger.targets.addArray(event.targets); } }, - group:['gzzhuosheng2_equip','gzzhuosheng2_silent'], - subSkill:{ - equip:{ - audio:'zhuosheng', - trigger:{player:'useCard'}, - filter:function(event,player){ - return get.type(event.card)=='equip'&&lib.skill.gzzhuosheng2.filterx(event,player); + group: ["gzzhuosheng2_equip", "gzzhuosheng2_silent"], + subSkill: { + equip: { + audio: "zhuosheng", + trigger: { player: "useCard" }, + filter: function (event, player) { + return ( + get.type(event.card) == "equip" && + lib.skill.gzzhuosheng2.filterx(event, player) + ); }, - prompt:'是否发动【擢升】摸一张牌?', - content:function(){ + prompt: "是否发动【擢升】摸一张牌?", + content: function () { player.draw(); }, }, - silent:{ - trigger:{ - player:'useCard1', + silent: { + trigger: { + player: "useCard1", }, - silent:true, - firstDo:true, - filter:function(event,player){ - return get.type(event.card)=='basic'&&lib.skill.gzzhuosheng2.filterx(event,player)&&event.addCount!==false; + silent: true, + firstDo: true, + filter: function (event, player) { + return ( + get.type(event.card) == "basic" && + lib.skill.gzzhuosheng2.filterx(event, player) && + event.addCount !== false + ); }, - content:function(){ - trigger.addCount=false; - var stat=player.getStat(); - if(stat&&stat.card&&stat.card[trigger.card.name]) stat.card[trigger.card.name]--; + content: function () { + trigger.addCount = false; + var stat = player.getStat(); + if (stat && stat.card && stat.card[trigger.card.name]) + stat.card[trigger.card.name]--; }, }, }, }, - gzzhuhai:{ - audio:'zhuhai', - audioname:['gz_re_xushu'], - trigger:{global:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return event.player.isAlive()&&event.player.getStat('damage')&& - lib.filter.targetEnabled({name:'sha'},player,event.player)&&(player.hasSha()||_status.connectMode&&player.countCards('h')>0); + gzzhuhai: { + audio: "zhuhai", + audioname: ["gz_re_xushu"], + trigger: { global: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return ( + event.player.isAlive() && + event.player.getStat("damage") && + lib.filter.targetEnabled({ name: "sha" }, player, event.player) && + (player.hasSha() || (_status.connectMode && player.countCards("h") > 0)) + ); }, - content:function(){ - var next=player.chooseToUse(function(card,player,event){ - if(get.name(card)!='sha') return false; - return lib.filter.filterCard.apply(this,arguments); - },'诛害:是否对'+get.translation(trigger.player)+'使用一张杀?').set('logSkill','gzzhuhai').set('complexSelect',true).set('filterTarget',function(card,player,target){ - if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false; - return lib.filter.targetEnabled.apply(this,arguments); - }).set('sourcex',trigger.player).setHiddenSkill(event.name); - player.addTempSkill('gzzhuhai2'); - next.oncard=function(card,player){ - try{ - if(trigger.player.getHistory('sourceDamage',function(evt){ - return evt.player.isFriendOf(player); - }).length){ - player.addTempSkill('gzzhuhai2'); - card.gzzhuhai_tag=true; + content: function () { + var next = player + .chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") return false; + return lib.filter.filterCard.apply(this, arguments); + }, "诛害:是否对" + get.translation(trigger.player) + "使用一张杀?") + .set("logSkill", "gzzhuhai") + .set("complexSelect", true) + .set("filterTarget", function (card, player, target) { + if ( + target != _status.event.sourcex && + !ui.selected.targets.includes(_status.event.sourcex) + ) + return false; + return lib.filter.targetEnabled.apply(this, arguments); + }) + .set("sourcex", trigger.player) + .setHiddenSkill(event.name); + player.addTempSkill("gzzhuhai2"); + next.oncard = function (card, player) { + try { + if ( + trigger.player.getHistory("sourceDamage", function (evt) { + return evt.player.isFriendOf(player); + }).length + ) { + player.addTempSkill("gzzhuhai2"); + card.gzzhuhai_tag = true; } - }catch(e){ - alert('发生了一个导致【诛害】无法正常触发无视防具效果的错误。请关闭十周年UI/手杀UI等扩展以解决'); + } catch (e) { + alert( + "发生了一个导致【诛害】无法正常触发无视防具效果的错误。请关闭十周年UI/手杀UI等扩展以解决" + ); } - } + }; }, - ai:{ - unequip_ai:true, - skillTagFilter:function(player,tag,arg){ - var evt=_status.event.getParent(); - if(evt.name!='gzzhuhai'||!arg||!arg.target) return false; - if(!arg.target.getHistory('sourceDamage',function(evt){ - return evt.player.isFriendOf(player); - }).length) return false; + ai: { + unequip_ai: true, + skillTagFilter: function (player, tag, arg) { + var evt = _status.event.getParent(); + if (evt.name != "gzzhuhai" || !arg || !arg.target) return false; + if ( + !arg.target.getHistory("sourceDamage", function (evt) { + return evt.player.isFriendOf(player); + }).length + ) + return false; return true; }, }, }, - gzzhuhai2:{ - trigger:{player:'shaMiss'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.card.gzzhuhai_tag==true&&event.target.countCards('he')>0; + gzzhuhai2: { + trigger: { player: "shaMiss" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.card.gzzhuhai_tag == true && event.target.countCards("he") > 0; }, - content:function(){ + content: function () { player.line(trigger.target); - trigger.target.chooseToDiscard('he',true); + trigger.target.chooseToDiscard("he", true); }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!arg||!arg.card||!arg.card.gzzhuhai_tag) return false; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!arg || !arg.card || !arg.card.gzzhuhai_tag) return false; }, }, }, - quanjin:{ - audio:2, - enable:'phaseUse', - usable:1, - onChooseToUse:function(event){ - if(!game.online){ - event.set('quanjin_list',game.filterPlayer((i)=>(i!=event.player&&i.getHistory('damage').length))); + quanjin: { + audio: 2, + enable: "phaseUse", + usable: 1, + onChooseToUse: function (event) { + if (!game.online) { + event.set( + "quanjin_list", + game.filterPlayer((i) => i != event.player && i.getHistory("damage").length) + ); } }, - filter:function(event,player){ - return event.quanjin_list&&event.quanjin_list.length>0&&player.countCards('h')>0; + filter: function (event, player) { + return event.quanjin_list && event.quanjin_list.length > 0 && player.countCards("h") > 0; }, - filterCard:true, - filterTarget:function(card,player,target){ + filterCard: true, + filterTarget: function (card, player, target) { return _status.event.quanjin_list.includes(target); }, - discard:false, - lose:false, - delay:false, - check:function(card){ - var evt=_status.event; - if(evt.quanjin_list.filter(function(target){ - return get.attitude(evt.player,target)>0; - }).length) return 8-get.value(card); - return 6.5-get.value(card); + discard: false, + lose: false, + delay: false, + check: function (card) { + var evt = _status.event; + if ( + evt.quanjin_list.filter(function (target) { + return get.attitude(evt.player, target) > 0; + }).length + ) + return 8 - get.value(card); + return 6.5 - get.value(card); }, - content:function(){ - 'step 0' - player.give(cards,target); - 'step 1' + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; player.chooseJunlingFor(target); - 'step 2' - event.junling=result.junling; - event.targets=result.targets; - var str=get.translation(player); - target.chooseJunlingControl(player,result.junling,result.targets).set('prompt','劝进').set('choiceList',[ - '执行该军令,然后'+str+'摸一张牌', - '不执行该军令,然后其将手牌摸至与全场最多相同', - ]).set('ai',function(){ - var evt=_status.event.getParent(2),player=evt.target,source=evt.player,junling=evt.junling,targets=evt.targets; - var num=0; - game.countPlayer(function(current){ - var num2=current.countCards('h'); - if(num2>num) num=num2; + "step 2"; + event.junling = result.junling; + event.targets = result.targets; + var str = get.translation(player); + target + .chooseJunlingControl(player, result.junling, result.targets) + .set("prompt", "劝进") + .set("choiceList", [ + "执行该军令,然后" + str + "摸一张牌", + "不执行该军令,然后其将手牌摸至与全场最多相同", + ]) + .set("ai", function () { + var evt = _status.event.getParent(2), + player = evt.target, + source = evt.player, + junling = evt.junling, + targets = evt.targets; + var num = 0; + game.countPlayer(function (current) { + var num2 = current.countCards("h"); + if (num2 > num) num = num2; + }); + num = Math.max(0, num - source.countCards("h")); + if (num > 1) { + if (get.attitude(player, target) > 0) + return get.junlingEffect(source, junling, player, targets, player) > num; + return get.junlingEffect(source, junling, player, targets, player) > -num; + } + if (get.attitude(player, target) > 0) + return get.junlingEffect(source, junling, player, targets, player) > 0; + return get.junlingEffect(source, junling, player, targets, player) > 1; }); - num=Math.max(0,num-source.countCards('h')); - if(num>1){ - if(get.attitude(player,target)>0) return get.junlingEffect(source,junling,player,targets,player)>num; - return get.junlingEffect(source,junling,player,targets,player)>-num; - } - if(get.attitude(player,target)>0) return get.junlingEffect(source,junling,player,targets,player)>0; - return get.junlingEffect(source,junling,player,targets,player)>1; - }); - 'step 3' - if(result.index==0){ - target.carryOutJunling(player,event.junling,targets); + "step 3"; + if (result.index == 0) { + target.carryOutJunling(player, event.junling, targets); player.draw(); - } - else{ - var num=0; - game.countPlayer(function(current){ - var num2=current.countCards('h'); - if(num2>num) num=num2; + } else { + var num = 0; + game.countPlayer(function (current) { + var num2 = current.countCards("h"); + if (num2 > num) num = num2; }); - num-=player.countCards('h'); - if(num>0) player.draw(Math.min(num,5)); + num -= player.countCards("h"); + if (num > 0) player.draw(Math.min(num, 5)); } }, - ai:{ - order:1, - result:{ - player:function(player,target){ - if(get.attitude(player,target)>0) return 3.3; - var num=0; - game.countPlayer(function(current){ - var num2=current.countCards('h'); - if(player==current) num2--; - if(target==current) num2++; - if(num2>num) num=num2; + ai: { + order: 1, + result: { + player: function (player, target) { + if (get.attitude(player, target) > 0) return 3.3; + var num = 0; + game.countPlayer(function (current) { + var num2 = current.countCards("h"); + if (player == current) num2--; + if (target == current) num2++; + if (num2 > num) num = num2; }); - num=Math.max(0,num-player.countCards('h')); - if(!num) return 0; - if(num>1) return 2; - if(ui.selected.cards.length&&get.value(ui.selected.cards[0])>5) return 0; + num = Math.max(0, num - player.countCards("h")); + if (!num) return 0; + if (num > 1) return 2; + if (ui.selected.cards.length && get.value(ui.selected.cards[0]) > 5) return 0; return 1; }, }, }, }, - zaoyun:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - var num=player.countCards('h'); - return game.hasPlayer(function(current){ - if(current.isEnemyOf(player)){ - var dist=get.distance(player,current); - return dist>1&&dist<=num; + zaoyun: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + var num = player.countCards("h"); + return game.hasPlayer(function (current) { + if (current.isEnemyOf(player)) { + var dist = get.distance(player, current); + return dist > 1 && dist <= num; } }); }, - selectCard:function(){ - var list=[],player=_status.event.player; - if(ui.selected.targets.length) return get.distance(player,ui.selected.targets[0])-1; - game.countPlayer(function(current){ - if(current.isEnemyOf(player)){ - var dist=get.distance(player,current); - if(dist>1) list.push(dist-1); + selectCard: function () { + var list = [], + player = _status.event.player; + if (ui.selected.targets.length) return get.distance(player, ui.selected.targets[0]) - 1; + game.countPlayer(function (current) { + if (current.isEnemyOf(player)) { + var dist = get.distance(player, current); + if (dist > 1) list.push(dist - 1); } }); list.sort(); - return [list[0],list[list.length-1]]; + return [list[0], list[list.length - 1]]; }, - filterCard:true, - filterTarget:function(card,player,target){ - return target.isEnemyOf(player)&&get.distance(player,target)==ui.selected.cards.length+1; + filterCard: true, + filterTarget: function (card, player, target) { + return ( + target.isEnemyOf(player) && + get.distance(player, target) == ui.selected.cards.length + 1 + ); }, - check:function(card){ - var player=_status.event.player; - if(ui.selected.cards.length&&game.hasPlayer(function(current){ - return current.isEnemyOf(player)&&get.distance(player,current)==(ui.selected.cards.length+1)&&get.damageEffect(current,player,player)>0; - })) return 0; - return (7-ui.selected.cards.length*2)-get.value(card); + check: function (card) { + var player = _status.event.player; + if ( + ui.selected.cards.length && + game.hasPlayer(function (current) { + return ( + current.isEnemyOf(player) && + get.distance(player, current) == ui.selected.cards.length + 1 && + get.damageEffect(current, player, player) > 0 + ); + }) + ) + return 0; + return 7 - ui.selected.cards.length * 2 - get.value(card); }, - content:function(){ - target.damage('nocard'); - if(!player.storage.zaoyun2) player.storage.zaoyun2=[]; + content: function () { + target.damage("nocard"); + if (!player.storage.zaoyun2) player.storage.zaoyun2 = []; player.storage.zaoyun2.push(target); - player.addTempSkill('zaoyun2'); + player.addTempSkill("zaoyun2"); }, - ai:{ - order:5, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); + ai: { + order: 5, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); }, }, }, }, - zaoyun2:{ - onremove:true, - charlotte:true, - mod:{ - globalFrom:function(player,target){ - if(player.getStorage('zaoyun2').includes((target))) return -Infinity; + zaoyun2: { + onremove: true, + charlotte: true, + mod: { + globalFrom: function (player, target) { + if (player.getStorage("zaoyun2").includes(target)) return -Infinity; }, }, }, - gzzhidao:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - forced:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget('请选择【雉盗】的目标','本回合内只能对自己和该角色使用牌,且第一次对其造成伤害时摸一张牌',lib.filter.notMe,true).set('ai',function(target){ - var player=_status.event.player; - return (1-get.sgn(get.attitude(player,target)))*Math.max(1,get.distance(player,target)); - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); - game.log(player,'选择了',target); - player.storage.gzzhidao2=target; - player.addTempSkill('gzzhidao2'); + gzzhidao: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + forced: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget( + "请选择【雉盗】的目标", + "本回合内只能对自己和该角色使用牌,且第一次对其造成伤害时摸一张牌", + lib.filter.notMe, + true + ) + .set("ai", function (target) { + var player = _status.event.player; + return ( + (1 - get.sgn(get.attitude(player, target))) * + Math.max(1, get.distance(player, target)) + ); + }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); + game.log(player, "选择了", target); + player.storage.gzzhidao2 = target; + player.addTempSkill("gzzhidao2"); } }, }, - gzzhidao2:{ - mod:{ - playerEnabled:function(card,player,target){ - if(target!=player&&target!=player.storage.gzzhidao2) return false; + gzzhidao2: { + mod: { + playerEnabled: function (card, player, target) { + if (target != player && target != player.storage.gzzhidao2) return false; }, - globalFrom:function(from,to){ - if(to==from.storage.gzzhidao2) return -Infinity; + globalFrom: function (from, to) { + if (to == from.storage.gzzhidao2) return -Infinity; }, }, - audio:'gzzhidao', - trigger:{source:'damageSource'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player==player.storage.gzzhidao2&&player.getHistory('sourceDamage',function(evt){ - return evt.player==event.player; - }).indexOf(event)==0&&event.player.countGainableCards(player,'hej')>0; + audio: "gzzhidao", + trigger: { source: "damageSource" }, + forced: true, + charlotte: true, + filter: function (event, player) { + return ( + event.player == player.storage.gzzhidao2 && + player + .getHistory("sourceDamage", function (evt) { + return evt.player == event.player; + }) + .indexOf(event) == 0 && + event.player.countGainableCards(player, "hej") > 0 + ); }, - logTarget:'player', - content:function(){ - player.gainPlayerCard(trigger.player,'hej',true); + logTarget: "player", + content: function () { + player.gainPlayerCard(trigger.player, "hej", true); }, }, - gzyjili:{ - audio:2, - forced:true, - preHidden:['gzyjili_remove'], - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - if(get.color(event.card)!='red'||event.targets.length!=1) return false; - var type=get.type(event.card); - return type=='basic'||type=='trick'; + gzyjili: { + audio: 2, + forced: true, + preHidden: ["gzyjili_remove"], + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + if (get.color(event.card) != "red" || event.targets.length != 1) return false; + var type = get.type(event.card); + return type == "basic" || type == "trick"; }, - check:function(){ + check: function () { return false; }, - content:function(){ - player.addTempSkill('gzyjili2'); - var evt=trigger.getParent(); - if(!evt.gzyjili) evt.gzyjili=[]; + content: function () { + player.addTempSkill("gzyjili2"); + var evt = trigger.getParent(); + if (!evt.gzyjili) evt.gzyjili = []; evt.gzyjili.add(player); }, - group:'gzyjili_remove', - subSkill:{ - remove:{ - audio:'gzyjili', - trigger:{player:'damageBegin2'}, - forced:true, - filter:function(event,player){ - var evt=false; - for(var i of lib.phaseName){ - evt=event.getParent(i); - if(evt&&evt.player) break; + group: "gzyjili_remove", + subSkill: { + remove: { + audio: "gzyjili", + trigger: { player: "damageBegin2" }, + forced: true, + filter: function (event, player) { + var evt = false; + for (var i of lib.phaseName) { + evt = event.getParent(i); + if (evt && evt.player) break; } - return evt&&evt.player&&player.getHistory('damage',function(evtx){ - return evtx.getParent(evt.name)==evt; - }).length==1; + return ( + evt && + evt.player && + player.getHistory("damage", function (evtx) { + return evtx.getParent(evt.name) == evt; + }).length == 1 + ); }, - content:function(){ + content: function () { trigger.cancel(); - player.removeCharacter(player.name1=='gz_yanbaihu'?0:1); + player.removeCharacter(player.name1 == "gz_yanbaihu" ? 0 : 1); }, }, }, }, - gzyjili2:{ - trigger:{global:'useCardAfter'}, - charlotte:true, - popup:false, - forced:true, - filter:function(event,player){ - return event.gzyjili&&event.gzyjili.includes(player)&&!event.addedTarget&&event.player - &&event.player.isAlive()&&event.player.canUse({ - name:event.card.name, - nature:event.card.nature, - isCard:true, - },player); + gzyjili2: { + trigger: { global: "useCardAfter" }, + charlotte: true, + popup: false, + forced: true, + filter: function (event, player) { + return ( + event.gzyjili && + event.gzyjili.includes(player) && + !event.addedTarget && + event.player && + event.player.isAlive() && + event.player.canUse( + { + name: event.card.name, + nature: event.card.nature, + isCard: true, + }, + player + ) + ); }, - content:function(){ - trigger.player.useCard({ - name:trigger.card.name, - nature:trigger.card.nature, - isCard:true, - },player,false); - }, - }, - donggui:{ - audio:2, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.donggui.filterTarget(null,player,current); - }); - }, - filterTarget:function(card,player,target){ - return target!=player&&!target.isUnseen(2)&&player.canUse('diaohulishan',target); - }, - content:function(){ - 'step 0' - player.chooseButton(['暗置'+get.translation(target)+'的一张武将牌',[[target.name1,target.name2],'character']],true).set('filterButton',function(button){ - return !get.is.jun(button.link); - }); - 'step 1' - var target1=target.getNext(); - var target2=target.getPrevious(); - if(target1==target2||target.inline(target1)||target.inline(target2)||target1.inline(target2)) event.finish(); - else{ - event.target1=target1; - event.target2=target2; - } - target.hideCharacter(result.links[0]==target.name1?0:1); - target.addTempSkill('donggui2'); - player.useCard({name:'diaohulishan',isCard:true},target); - 'step 2' - if(event.target1.inline(event.target2)){ - player.draw(game.countPlayer(function(current){ - return current.inline(event.target1); - })); - } - }, - ai:{ - order:2, - result:{ - player:function(player,target){ - var target1=target.getNext(); - var target2=target.getPrevious(); - if(target1==target2||target.inline(target1)||target.inline(target2)||target1.inline(target2)||!target1.isFriendOf(target2)) return 0; - var num=game.countPlayer(function(current){ - return current!=target1&¤t!=target2&&(current.inline(target1)||current.inline(target2)); - }); - return 2+num; + content: function () { + trigger.player.useCard( + { + name: trigger.card.name, + nature: trigger.card.nature, + isCard: true, }, - }, + player, + false + ); }, }, - donggui2:{ai:{nomingzhi:true}}, - fengyang:{ - audio:2, - zhenfa:'inline', - trigger:{player:'phaseJieshuBegin'}, - filter:function(event,player){ - var bool=player.hasSkill('fengyang'); - return game.hasPlayer(function(current){ - return current!=player&¤t.inline(player); - })&&game.hasPlayer(function(current){ - return (current==player||bool)&¤t.inline(player)&¤t.countCards('e')>0; + donggui: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return lib.skill.donggui.filterTarget(null, player, current); }); }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - event.list=game.filterPlayer(function(current){ - return current.inline(player); - }).sortBySeat(); - 'step 1' - var target=event.list.shift(); - if((target==player||player.hasSkill('fengyang'))&&target.countCards('e')){ - event.target=target; - var next=target.chooseToDiscard('e',get.prompt('fengyang'),'弃置装备区内的一张牌并摸两张牌').set('ai',function(card){ - return 5.5-get.value(card); + filterTarget: function (card, player, target) { + return target != player && !target.isUnseen(2) && player.canUse("diaohulishan", target); + }, + content: function () { + "step 0"; + player + .chooseButton( + [ + "暗置" + get.translation(target) + "的一张武将牌", + [[target.name1, target.name2], "character"], + ], + true + ) + .set("filterButton", function (button) { + return !get.is.jun(button.link); }); - next.logSkill='fengyang'; - if(player==target) next.setHiddenSkill('fengyang'); + "step 1"; + var target1 = target.getNext(); + var target2 = target.getPrevious(); + if ( + target1 == target2 || + target.inline(target1) || + target.inline(target2) || + target1.inline(target2) + ) + event.finish(); + else { + event.target1 = target1; + event.target2 = target2; } - else event.goto(3); - 'step 2' - if(result.bool){ + target.hideCharacter(result.links[0] == target.name1 ? 0 : 1); + target.addTempSkill("donggui2"); + player.useCard({ name: "diaohulishan", isCard: true }, target); + "step 2"; + if (event.target1.inline(event.target2)) { + player.draw( + game.countPlayer(function (current) { + return current.inline(event.target1); + }) + ); + } + }, + ai: { + order: 2, + result: { + player: function (player, target) { + var target1 = target.getNext(); + var target2 = target.getPrevious(); + if ( + target1 == target2 || + target.inline(target1) || + target.inline(target2) || + target1.inline(target2) || + !target1.isFriendOf(target2) + ) + return 0; + var num = game.countPlayer(function (current) { + return ( + current != target1 && + current != target2 && + (current.inline(target1) || current.inline(target2)) + ); + }); + return 2 + num; + }, + }, + }, + }, + donggui2: { ai: { nomingzhi: true } }, + fengyang: { + audio: 2, + zhenfa: "inline", + trigger: { player: "phaseJieshuBegin" }, + filter: function (event, player) { + var bool = player.hasSkill("fengyang"); + return ( + game.hasPlayer(function (current) { + return current != player && current.inline(player); + }) && + game.hasPlayer(function (current) { + return ( + (current == player || bool) && + current.inline(player) && + current.countCards("e") > 0 + ); + }) + ); + }, + direct: true, + preHidden: true, + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + return current.inline(player); + }) + .sortBySeat(); + "step 1"; + var target = event.list.shift(); + if ((target == player || player.hasSkill("fengyang")) && target.countCards("e")) { + event.target = target; + var next = target + .chooseToDiscard("e", get.prompt("fengyang"), "弃置装备区内的一张牌并摸两张牌") + .set("ai", function (card) { + return 5.5 - get.value(card); + }); + next.logSkill = "fengyang"; + if (player == target) next.setHiddenSkill("fengyang"); + } else event.goto(3); + "step 2"; + if (result.bool) { target.draw(2); } - 'step 3' - if(event.list.length) event.goto(1); + "step 3"; + if (event.list.length) event.goto(1); }, }, - fengyang_old:{ - audio:'fengyang', - zhenfa:'inline', - global:'fengyang_old_nogain', - subSkill:{ - nogain:{ - mod:{ - canBeDiscarded:function(card,player,target){ - if(get.position(card)=='e'&&player.identity!=target.identity&&game.hasPlayer(function(current){ - return current.hasSkill('fengyang_old')&&(current==target||target.inline(current)); - })) return false; + fengyang_old: { + audio: "fengyang", + zhenfa: "inline", + global: "fengyang_old_nogain", + subSkill: { + nogain: { + mod: { + canBeDiscarded: function (card, player, target) { + if ( + get.position(card) == "e" && + player.identity != target.identity && + game.hasPlayer(function (current) { + return ( + current.hasSkill("fengyang_old") && + (current == target || target.inline(current)) + ); + }) + ) + return false; }, - canBeGained:function(card,player,target){ - if(get.position(card)=='e'&&player.identity!=target.identity&&game.hasPlayer(function(current){ - return current.hasSkill('fengyang_old')&&(current==target||target.inline(current)); - })) return false; + canBeGained: function (card, player, target) { + if ( + get.position(card) == "e" && + player.identity != target.identity && + game.hasPlayer(function (current) { + return ( + current.hasSkill("fengyang_old") && + (current == target || target.inline(current)) + ); + }) + ) + return false; }, }, }, }, }, - gzrekuangcai:{ - audio:'gzkuangcai', - forced:true, - preHidden:true, - trigger:{player:'phaseDiscardBegin'}, - filter:function(event,player){ - return !player.getHistory('useCard').length||!player.getHistory('sourceDamage').length; + gzrekuangcai: { + audio: "gzkuangcai", + forced: true, + preHidden: true, + trigger: { player: "phaseDiscardBegin" }, + filter: function (event, player) { + return !player.getHistory("useCard").length || !player.getHistory("sourceDamage").length; }, - check:function(event,player){ - return !player.getHistory('useCard').length; + check: function (event, player) { + return !player.getHistory("useCard").length; }, - content:function(){ - lib.skill.rekuangcai.change(player,player.getHistory('useCard').length?-1:1); + content: function () { + lib.skill.rekuangcai.change(player, player.getHistory("useCard").length ? -1 : 1); }, - mod:{ - targetInRange:function(card,player){ - if(player==_status.currentPhase) return true; + mod: { + targetInRange: function (card, player) { + if (player == _status.currentPhase) return true; }, - cardUsable:function(card,player){ - if(player==_status.currentPhase) return Infinity; + cardUsable: function (card, player) { + if (player == _status.currentPhase) return Infinity; }, }, }, - gzkuangcai:{ - audio:2, - trigger:{player:'useCard1'}, - forced:true, - firstDo:true, - noHidden:true, - preHidden:['gzkuangcai_discard'], - filter:function(event,player){ - return player==_status.currentPhase&&get.type(event.card)=='trick'; + gzkuangcai: { + audio: 2, + trigger: { player: "useCard1" }, + forced: true, + firstDo: true, + noHidden: true, + preHidden: ["gzkuangcai_discard"], + filter: function (event, player) { + return player == _status.currentPhase && get.type(event.card) == "trick"; }, - content:function(){ - trigger.nowuxie=true; + content: function () { + trigger.nowuxie = true; }, - mod:{ - targetInRange:function(card,player){ - if(player==_status.currentPhase) return true; + mod: { + targetInRange: function (card, player) { + if (player == _status.currentPhase) return true; }, - cardUsable:function(card,player){ - if(player==_status.currentPhase) return Infinity; + cardUsable: function (card, player) { + if (player == _status.currentPhase) return Infinity; }, }, - ai:{ - unequip:true, - skillTagFilter:function(player){ - return player==_status.currentPhase; + ai: { + unequip: true, + skillTagFilter: function (player) { + return player == _status.currentPhase; }, }, - group:'gzkuangcai_discard', - subSkill:{ - discard:{ - audio:'gzkuangcai', - trigger:{player:'phaseDiscardBegin'}, - forced:true, - filter:function(event,player){ - var use=player.getHistory('useCard').length; - var damage=(player.getStat('damage')||0); - if(use&&!damage) return true; - if(damage>=use) return true; + group: "gzkuangcai_discard", + subSkill: { + discard: { + audio: "gzkuangcai", + trigger: { player: "phaseDiscardBegin" }, + forced: true, + filter: function (event, player) { + var use = player.getHistory("useCard").length; + var damage = player.getStat("damage") || 0; + if (use && !damage) return true; + if (damage >= use) return true; return false; }, - check:function(event,player){ - var use=player.getHistory('useCard').length; - var damage=(player.getStat('damage')||0); - if(use&&!damage) return false; + check: function (event, player) { + var use = player.getHistory("useCard").length; + var damage = player.getStat("damage") || 0; + if (use && !damage) return false; return true; }, - content:function(){ - var use=player.getHistory('useCard').length; - var damage=(player.getStat('damage')||0); - if(use&&!damage) player.addTempSkill('gzkuangcai_less') - else{ + content: function () { + var use = player.getHistory("useCard").length; + var damage = player.getStat("damage") || 0; + if (use && !damage) player.addTempSkill("gzkuangcai_less"); + else { player.drawTo(player.maxHp); - player.addTempSkill('gzkuangcai_more'); + player.addTempSkill("gzkuangcai_more"); } }, }, - more:{ - mod:{ - maxHandcard:function(player,num){ - return num+2; + more: { + mod: { + maxHandcard: function (player, num) { + return num + 2; }, }, - charlotte:true, + charlotte: true, }, - less:{ - mod:{ - maxHandcard:function(player,num){ - return num-2; + less: { + mod: { + maxHandcard: function (player, num) { + return num - 2; }, }, - charlotte:true, + charlotte: true, }, }, }, - gzshejian:{ - audio:2, - preHidden:true, - trigger:{target:'useCardToTargeted'}, - filter:function(event,player){ - if(player==event.player||event.targets.length!=1) return false; - var hs=player.getCards('h'); - if(hs.length==0) return false; - for(var i of hs){ - if(!lib.filter.cardDiscardable(i,player,'gzshejian')) return false; + gzshejian: { + audio: 2, + preHidden: true, + trigger: { target: "useCardToTargeted" }, + filter: function (event, player) { + if (player == event.player || event.targets.length != 1) return false; + var hs = player.getCards("h"); + if (hs.length == 0) return false; + for (var i of hs) { + if (!lib.filter.cardDiscardable(i, player, "gzshejian")) return false; } return true; }, - check:function(event,player){ - var target=event.player; - if(get.damageEffect(target,player,player)<=0) return false; - if(target.hp<=(player.hasSkill('gzcongjian')?2:1)&&!target.getEquip('huxinjing')&&!game.hasPlayer(function(current){ - return current!=target&&!current.isFriendOf(player); - })) return true; - if(player.hasSkill('lirang')&&player.hasFriend()) return true; - if((event.card.name=='guohe'||event.card.name=='shunshou'||event.card.name=='zhujinqiyuan')&&player.countCards('h')==1) return true; - if(player.countCards('h')<3&&!player.countCards('h',function(card){ - return get.value(card,player)>5; - })) return true; - if(player.hp<=event.getParent().baseDamage){ - if(get.tag(event.card,'respondSha')){ - if(player.countCards('h',{name:'sha'})==0){ + check: function (event, player) { + var target = event.player; + if (get.damageEffect(target, player, player) <= 0) return false; + if ( + target.hp <= (player.hasSkill("gzcongjian") ? 2 : 1) && + !target.getEquip("huxinjing") && + !game.hasPlayer(function (current) { + return current != target && !current.isFriendOf(player); + }) + ) + return true; + if (player.hasSkill("lirang") && player.hasFriend()) return true; + if ( + (event.card.name == "guohe" || + event.card.name == "shunshou" || + event.card.name == "zhujinqiyuan") && + player.countCards("h") == 1 + ) + return true; + if ( + player.countCards("h") < 3 && + !player.countCards("h", function (card) { + return get.value(card, player) > 5; + }) + ) + return true; + if (player.hp <= event.getParent().baseDamage) { + if (get.tag(event.card, "respondSha")) { + if (player.countCards("h", { name: "sha" }) == 0) { return true; } - } - else if(get.tag(event.card,'respondShan')){ - if(player.countCards('h',{name:'shan'})==0){ + } else if (get.tag(event.card, "respondShan")) { + if (player.countCards("h", { name: "shan" }) == 0) { return true; } - } - else if(get.tag(event.card,'damage')){ - if(event.card.name=='shuiyanqijunx') return player.countCards('e')==0; + } else if (get.tag(event.card, "damage")) { + if (event.card.name == "shuiyanqijunx") return player.countCards("e") == 0; return true; } } return false; }, - logTarget:'player', - content:function(){ - 'step 0' - var cards=player.getCards('h'); - event.num=cards.length; + logTarget: "player", + content: function () { + "step 0"; + var cards = player.getCards("h"); + event.num = cards.length; player.discard(cards); - 'step 1' - var target=trigger.player,str=get.translation(target); - event.target=target; - if(!target.isIn()) event.finish(); - else if(!target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'he')) event._result={index:1}; - else player.chooseControl().set('choiceList',[ - '弃置'+str+'的'+get.cnNumber(num)+'张牌', - '对'+str+'造成1点伤害', - ]).set('ai',()=>1); - 'step 2' - if(result.index==0) player.discardPlayerCard(target,num,true,'he'); + "step 1"; + var target = trigger.player, + str = get.translation(target); + event.target = target; + if (!target.isIn()) event.finish(); + else if ( + !target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "he") + ) + event._result = { index: 1 }; + else + player + .chooseControl() + .set("choiceList", [ + "弃置" + str + "的" + get.cnNumber(num) + "张牌", + "对" + str + "造成1点伤害", + ]) + .set("ai", () => 1); + "step 2"; + if (result.index == 0) player.discardPlayerCard(target, num, true, "he"); else target.damage(); }, }, - gzpozhen:{ - audio:2, - trigger:{global:'phaseBegin'}, - limited:true, - preHidden:true, - filter:function(event,player){ - return player!=event.player; + gzpozhen: { + audio: 2, + trigger: { global: "phaseBegin" }, + limited: true, + preHidden: true, + filter: function (event, player) { + return player != event.player; }, - logTarget:'player', - skillAnimation:true, - animationColor:'orange', - check:function(event,player){ - var target=event.player; - if(get.attitude(player,target)>=-3) return false; - if(event.player.hasJudge('lebu')&&!game.hasPlayer(function(current){ - return get.attitude(current,target)>0&¤t.hasWuxie(); - })) return false; - var num=Math.min(target.getCardUsable('sha'),target.countCards('h',function(card){ - return get.name(card,target)=='sha'&&target.hasValueTarget(card); - }))+target.countCards('h',function(card){ - return get.name(card,target)!='sha'&&target.hasValueTarget(card); - }); - return num>=Math.max(2,target.hp); + logTarget: "player", + skillAnimation: true, + animationColor: "orange", + check: function (event, player) { + var target = event.player; + if (get.attitude(player, target) >= -3) return false; + if ( + event.player.hasJudge("lebu") && + !game.hasPlayer(function (current) { + return get.attitude(current, target) > 0 && current.hasWuxie(); + }) + ) + return false; + var num = + Math.min( + target.getCardUsable("sha"), + target.countCards("h", function (card) { + return get.name(card, target) == "sha" && target.hasValueTarget(card); + }) + ) + + target.countCards("h", function (card) { + return get.name(card, target) != "sha" && target.hasValueTarget(card); + }); + return num >= Math.max(2, target.hp); }, - content:function(){ - 'step 0' - player.awakenSkill('gzpozhen'); - var target=trigger.player; - target.addTempSkill('gzpozhen2'); - var list=game.filterPlayer(function(current){ - return current!=target&&(current.inline(target)|| - (current==target.getNext().getNext()&¤t.siege(target.getNext())||current==target.getPrevious().getPrevious()&¤t.siege(target.getPrevious()))); + content: function () { + "step 0"; + player.awakenSkill("gzpozhen"); + var target = trigger.player; + target.addTempSkill("gzpozhen2"); + var list = game.filterPlayer(function (current) { + return ( + current != target && + (current.inline(target) || + (current == target.getNext().getNext() && current.siege(target.getNext())) || + (current == target.getPrevious().getPrevious() && + current.siege(target.getPrevious()))) + ); }); - if(list.length){ + if (list.length) { list.add(target); list.sortBySeat(target); - event.targets=list; - } - else event.finish(); - 'step 1' - var target=targets.shift(); - if(target.countDiscardableCards(player,'he')>0) player.discardPlayerCard(target,'he',true).boolline=true; - if(targets.length) event.redo(); + event.targets = list; + } else event.finish(); + "step 1"; + var target = targets.shift(); + if (target.countDiscardableCards(player, "he") > 0) + player.discardPlayerCard(target, "he", true).boolline = true; + if (targets.length) event.redo(); }, }, - gzpozhen2:{ - mod:{ - cardEnabled2:function(card){ - if(get.position(card)=='h') return false; + gzpozhen2: { + mod: { + cardEnabled2: function (card) { + if (get.position(card) == "h") return false; }, - cardRecastable:function(card){ - if(get.position(card)=='h') return false; + cardRecastable: function (card) { + if (get.position(card) == "h") return false; }, }, }, - gzjiancai:{ - audio:2, - viceSkill:true, - trigger:{global:'damageBegin4'}, - preHidden:true, - init:function(player,skill){ - if(player.checkViceSkill(skill)&&!player.viceChanged) player.removeMaxHp(); + gzjiancai: { + audio: 2, + viceSkill: true, + trigger: { global: "damageBegin4" }, + preHidden: true, + init: function (player, skill) { + if (player.checkViceSkill(skill) && !player.viceChanged) player.removeMaxHp(); }, - filter:function(event,player){ - return event.player.isFriendOf(player)&&event.num>=event.player.hp; + filter: function (event, player) { + return event.player.isFriendOf(player) && event.num >= event.player.hp; }, - check:function(event,player){ - if(get.attitude(player,event.player)<3) return false; - if(event.num>=1||player.storage.gzpozhen) return true; - if(player.countCards('h',function(card){ - var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); - if(mod2!='unchanged') return mod2; - var mod=game.checkMod(card,player,event.player,'unchanged','cardSavable',player); - if(mod!='unchanged') return mod; - var savable=get.info(card).savable; - if(typeof savable=='function') savable=savable(card,player,event.player); - return savable; - })>=1+event.num-event.player.hp) return false; + check: function (event, player) { + if (get.attitude(player, event.player) < 3) return false; + if (event.num >= 1 || player.storage.gzpozhen) return true; + if ( + player.countCards("h", function (card) { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; + var mod = game.checkMod( + card, + player, + event.player, + "unchanged", + "cardSavable", + player + ); + if (mod != "unchanged") return mod; + var savable = get.info(card).savable; + if (typeof savable == "function") savable = savable(card, player, event.player); + return savable; + }) >= + 1 + event.num - event.player.hp + ) + return false; return true; }, - logTarget:'player', - skillAnimation:true, - animationColor:'orange', - content:function(){ + logTarget: "player", + skillAnimation: true, + animationColor: "orange", + content: function () { trigger.cancel(); player.changeVice(); }, - group:'gzjiancai_add', - subSkill:{ - add:{ - trigger:{global:'changeViceBegin'}, - logTarget:'player', - forced:true, - locked:false, - prompt:function(event,player){ - return get.translation(event.player)+'即将变更副将,是否发动【荐才】,令其此次变更副将时增加两张可选武将牌?'; + group: "gzjiancai_add", + subSkill: { + add: { + trigger: { global: "changeViceBegin" }, + logTarget: "player", + forced: true, + locked: false, + prompt: function (event, player) { + return ( + get.translation(event.player) + + "即将变更副将,是否发动【荐才】,令其此次变更副将时增加两张可选武将牌?" + ); }, - filter:function(event,player){ + filter: function (event, player) { return event.player.isFriendOf(player); }, - content:function(){ - trigger.num+=2; + content: function () { + trigger.num += 2; }, }, }, }, - gzxingzhao:{ - audio:2, - getNum:function(){ - var list=[],players=game.filterPlayer(); - for(var target of players){ - if(target.isUnseen()||target.isHealthy()) continue; - var add=true; - for(var i of list){ - if(i.isFriendOf(target)){ - add=false; + gzxingzhao: { + audio: 2, + getNum: function () { + var list = [], + players = game.filterPlayer(); + for (var target of players) { + if (target.isUnseen() || target.isHealthy()) continue; + var add = true; + for (var i of list) { + if (i.isFriendOf(target)) { + add = false; break; } } - if(add) list.add(target); + if (add) list.add(target); } return list.length; }, - mod:{ - maxHandcard:function(player,num){ - return num+(lib.skill.gzxingzhao.getNum()>2?4:0); + mod: { + maxHandcard: function (player, num) { + return num + (lib.skill.gzxingzhao.getNum() > 2 ? 4 : 0); }, }, - group:['gzxingzhao_xunxun','gzxingzhao_use','gzxingzhao_lose'], - preHidden:['gzxingzhao_xunxun','gzxingzhao_use','gzxingzhao_lose'], - subfrequent:['use'], - subSkill:{ - xunxun:{ - audio:2, - name:'恂恂', - description:'摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。', - trigger:{player:'phaseDrawBegin1'}, - filter:function(event,player){ - return lib.skill.gzxingzhao.getNum()>0; + group: ["gzxingzhao_xunxun", "gzxingzhao_use", "gzxingzhao_lose"], + preHidden: ["gzxingzhao_xunxun", "gzxingzhao_use", "gzxingzhao_lose"], + subfrequent: ["use"], + subSkill: { + xunxun: { + audio: 2, + name: "恂恂", + description: + "摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。", + trigger: { player: "phaseDrawBegin1" }, + filter: function (event, player) { + return lib.skill.gzxingzhao.getNum() > 0; }, - content:function(){ - 'step 0' - var cards=get.cards(4); + content: function () { + "step 0"; + var cards = get.cards(4); game.cardsGotoOrdering(cards); - var next=player.chooseToMove('恂恂:将两张牌置于牌堆顶',true); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('filterMove',function(from,to,moved){ - if(to==1&&moved[1].length>=2) return false; + var next = player.chooseToMove("恂恂:将两张牌置于牌堆顶", true); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("filterMove", function (from, to, moved) { + if (to == 1 && moved[1].length >= 2) return false; return true; }); - next.set('filterOk',function(moved){ - return moved[1].length==2; + next.set("filterOk", function (moved) { + return moved[1].length == 2; }); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0).sort(function(a,b){ - return get.value(b)-get.value(a); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0).sort(function (a, b) { + return get.value(b) - get.value(a); }); - return [cards,cards.splice(2)]; - }) - 'step 1' - var top=result.moved[0]; - var bottom=result.moved[1]; + return [cards, cards.splice(2)]; + }); + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; top.reverse(); - for(var i=0;i1&&!player.isMaxHandcard(); + forced: true, + filter: function (event, player) { + return ( + (event.name == "damage" || get.type(event.card) == "equip") && + lib.skill.gzxingzhao.getNum() > 1 && + !player.isMaxHandcard() + ); }, - frequent:true, - content:function(){ + frequent: true, + content: function () { player.draw(); }, }, - draw:{ - audio:'gzxingzhao', - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return lib.skill.gzxingzhao.getNum()>1&&event.source - &&event.source.isAlive()&&event.source.countCards('h')!=player.countCards('h'); + draw: { + audio: "gzxingzhao", + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + lib.skill.gzxingzhao.getNum() > 1 && + event.source && + event.source.isAlive() && + event.source.countCards("h") != player.countCards("h") + ); }, - logTarget:function(event,player){ - var target=event.source; - return target.countCards('h')>player.countCards('h')?player:target; + logTarget: function (event, player) { + var target = event.source; + return target.countCards("h") > player.countCards("h") ? player : target; }, - check:function(event,player){ - return get.attitude(player,lib.skill.gzxingzhao_draw.logTarget(event,player))>0; + check: function (event, player) { + return ( + get.attitude(player, lib.skill.gzxingzhao_draw.logTarget(event, player)) > 0 + ); }, - content:function(){ - lib.skill.gzxingzhao_draw.logTarget(trigger,player).draw(); + content: function () { + lib.skill.gzxingzhao_draw.logTarget(trigger, player).draw(); }, }, - skip:{ - audio:'gzxingzhao', - trigger:{player:'phaseDiscardBefore'}, - forced:true, - filter:function(){ - return lib.skill.gzxingzhao.getNum()>2; + skip: { + audio: "gzxingzhao", + trigger: { player: "phaseDiscardBefore" }, + forced: true, + filter: function () { + return lib.skill.gzxingzhao.getNum() > 2; }, - content:function(){ + content: function () { trigger.cancel(); - game.log(player,'跳过了','#y弃牌阶段'); + game.log(player, "跳过了", "#y弃牌阶段"); }, }, - lose:{ - audio:'gzxingzhao', - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + lose: { + audio: "gzxingzhao", + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&evt.player==player&&evt.es&&evt.es.length>0&&lib.skill.gzxingzhao.getNum()>3; + filter: function (event, player) { + var evt = event.getl(player); + return ( + evt && + evt.player == player && + evt.es && + evt.es.length > 0 && + lib.skill.gzxingzhao.getNum() > 3 + ); + }, + forced: true, + content: function () { + player.draw(); }, - forced:true, - content:function(){player.draw()}, }, }, - ai:{ - threaten:3, - effect:{ - target:function(card,player,target,current){ - if(lib.skill.gzxingzhao.getNum()>3&&get.type(card)=='equip'&&!get.cardtag(card,'gifts')) return [1,3]; - } + ai: { + threaten: 3, + effect: { + target: function (card, player, target, current) { + if ( + lib.skill.gzxingzhao.getNum() > 3 && + get.type(card) == "equip" && + !get.cardtag(card, "gifts") + ) + return [1, 3]; + }, }, - reverseEquip:true, - skillTagFilter:function(){ - return lib.skill.gzxingzhao.getNum()>3; + reverseEquip: true, + skillTagFilter: function () { + return lib.skill.gzxingzhao.getNum() > 3; }, }, }, - qiuan:{ - audio:2, - trigger:{player:'damageBegin2'}, - filter:function(event,player){ - return event.cards&&event.cards.filterInD().length>0&&!player.getExpansions('qiuan').length; + qiuan: { + audio: 2, + trigger: { player: "damageBegin2" }, + filter: function (event, player) { + return ( + event.cards && + event.cards.filterInD().length > 0 && + !player.getExpansions("qiuan").length + ); }, - check:function(event,player){ - if(get.damageEffect(player,event.source||player,player,event.nature)>=0) return false; + check: function (event, player) { + if (get.damageEffect(player, event.source || player, player, event.nature) >= 0) + return false; return true; }, - preHidden:true, - content:function(){ - var cards=trigger.cards.filterInD(); - player.addToExpansion('gain2',cards).gaintag.add('qiuan'); + preHidden: true, + content: function () { + var cards = trigger.cards.filterInD(); + player.addToExpansion("gain2", cards).gaintag.add("qiuan"); trigger.cancel(); }, - intro:{ - content:'expansion', - markcount:'expansion', + intro: { + content: "expansion", + markcount: "expansion", }, - marktext:'函', + marktext: "函", }, - liangfan:{ - audio:2, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('qiuan').length>0; + liangfan: { + audio: 2, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return player.getExpansions("qiuan").length > 0; }, - content:function(){ - 'step 0' - var cards=player.getExpansions('qiuan'); - player.gain(cards,'gain2').gaintag.add('liangfan'); - player.addTempSkill('liangfan2'); - 'step 1' + content: function () { + "step 0"; + var cards = player.getExpansions("qiuan"); + player.gain(cards, "gain2").gaintag.add("liangfan"); + player.addTempSkill("liangfan2"); + "step 1"; player.loseHp(); }, }, - liangfan2:{ - audio:'liangfan', - mark:true, - mod:{ - aiOrder:function(player,card,num){ - if(get.itemtype(card)=='card'&&card.hasGaintag('liangfan')) return num+0.1; + liangfan2: { + audio: "liangfan", + mark: true, + mod: { + aiOrder: function (player, card, num) { + if (get.itemtype(card) == "card" && card.hasGaintag("liangfan")) return num + 0.1; }, }, - intro:{content:'使用“量反”牌造成伤害后,可获得目标角色的一张牌'}, - trigger:{source:'damageEnd'}, - logTarget:'player', - charlotte:true, - onremove:function(player){ - player.removeGaintag('liangfan'); + intro: { content: "使用“量反”牌造成伤害后,可获得目标角色的一张牌" }, + trigger: { source: "damageEnd" }, + logTarget: "player", + charlotte: true, + onremove: function (player) { + player.removeGaintag("liangfan"); }, - prompt:(event)=>('量反:是否获得'+get.translation(event.player)+'的一张牌?'), - filter:function(event,player){ - var evt=event.getParent(2); - if(evt.name!='useCard'||evt.card!=event.card) return false; - if(!event.player.countGainableCards(player,'he')) return false; - return player.getHistory('lose',function(evt2){ - if(evt2.getParent()!=evt) return false; - for(var i in evt2.gaintag_map){ - if(evt2.gaintag_map[i].includes('liangfan')) return true; - } - return false; - }).length>0; + prompt: (event) => "量反:是否获得" + get.translation(event.player) + "的一张牌?", + filter: function (event, player) { + var evt = event.getParent(2); + if (evt.name != "useCard" || evt.card != event.card) return false; + if (!event.player.countGainableCards(player, "he")) return false; + return ( + player.getHistory("lose", function (evt2) { + if (evt2.getParent() != evt) return false; + for (var i in evt2.gaintag_map) { + if (evt2.gaintag_map[i].includes("liangfan")) return true; + } + return false; + }).length > 0 + ); }, - marktext:'反', - content:function(){ - player.gainPlayerCard(trigger.player,true,'he'); + marktext: "反", + content: function () { + player.gainPlayerCard(trigger.player, true, "he"); }, }, - gzwenji:{ - audio:2, - trigger:{player:'phaseUseBegin'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current!=player&¤t.countCards('he'); + gzwenji: { + audio: 2, + trigger: { player: "phaseUseBegin" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current != player && current.countCards("he"); }); }, - preHidden:true, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt2('gzwenji'),function(card,player,target){ - return target!=player&&target.countCards('he')>0; - }).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(target.identity=='unknown'&&att<=0) return 20; - if(att>0) return Math.sqrt(att)/10; - return 5-att; - }); - 'step 1' - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('gzwenji',target); - target.chooseCard('he',true,'问计:将一张牌交给'+get.translation(player)); - } - else{ - event.finish(); - } - 'step 2' - if(result.bool){ - event.card=result.cards[0]; - target.give(result.cards,player).gaintag.add('gzwenji'); - } - 'step 3' - if(target.identity=='unknown'||target.isFriendOf(player)){ - player.addTempSkill('gzwenji_respond'); - event.finish(); - } - else if(target.isIn()&&player.countCards('he',function(card){ - return !card.hasGaintag('gzwenji'); - })){ - player.chooseCard('he','交给'+get.translation(target)+'一张其他牌,或令其摸一张牌',function(card){ - return !card.hasGaintag('gzwenji'); - }).set('ai',function(card){ - return 5-get.value(card); + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gzwenji"), function (card, player, target) { + return target != player && target.countCards("he") > 0; + }) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (target.identity == "unknown" && att <= 0) return 20; + if (att > 0) return Math.sqrt(att) / 10; + return 5 - att; }); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gzwenji", target); + target.chooseCard("he", true, "问计:将一张牌交给" + get.translation(player)); + } else { + event.finish(); } - else event.finish(); - 'step 4' - if(result.bool){ - player.give(result.cards,target); - player.removeGaintag('gzwenji'); + "step 2"; + if (result.bool) { + event.card = result.cards[0]; + target.give(result.cards, player).gaintag.add("gzwenji"); } - else{ + "step 3"; + if (target.identity == "unknown" || target.isFriendOf(player)) { + player.addTempSkill("gzwenji_respond"); + event.finish(); + } else if ( + target.isIn() && + player.countCards("he", function (card) { + return !card.hasGaintag("gzwenji"); + }) + ) { + player + .chooseCard( + "he", + "交给" + get.translation(target) + "一张其他牌,或令其摸一张牌", + function (card) { + return !card.hasGaintag("gzwenji"); + } + ) + .set("ai", function (card) { + return 5 - get.value(card); + }); + } else event.finish(); + "step 4"; + if (result.bool) { + player.give(result.cards, target); + player.removeGaintag("gzwenji"); + } else { target.draw(); } }, - subSkill:{ - respond:{ - onremove:function(player){ - player.removeGaintag('gzwenji'); + subSkill: { + respond: { + onremove: function (player) { + player.removeGaintag("gzwenji"); }, - mod:{ - targetInRange:function(card,player,target){ - if(!card.cards) return; - for(var i of card.cards){ - if(i.hasGaintag('gzwenji')) return true; + mod: { + targetInRange: function (card, player, target) { + if (!card.cards) return; + for (var i of card.cards) { + if (i.hasGaintag("gzwenji")) return true; } }, - cardUsable:function(card,player,target){ - if(!card.cards) return; - for(var i of card.cards){ - if(i.hasGaintag('gzwenji')) return Infinity; + cardUsable: function (card, player, target) { + if (!card.cards) return; + for (var i of card.cards) { + if (i.hasGaintag("gzwenji")) return Infinity; } }, }, - trigger:{player:'useCard'}, - forced:true, - charlotte:true, - audio:'gzwenji', - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].includes('gzwenji')) return true; - } - return false; - }).length>0; + trigger: { player: "useCard" }, + forced: true, + charlotte: true, + audio: "gzwenji", + filter: function (event, player) { + return ( + player.getHistory("lose", function (evt) { + if (evt.getParent() != event) return false; + for (var i in evt.gaintag_map) { + if (evt.gaintag_map[i].includes("gzwenji")) return true; + } + return false; + }).length > 0 + ); }, - content:function(){ - trigger.directHit.addArray(game.filterPlayer(function(current){ - return current!=player; - })); - if(trigger.addCount!==false){ - trigger.addCount=false; - var stat=player.getStat(); - if(stat&&stat.card&&stat.card[trigger.card.name]) stat.card[trigger.card.name]--; + content: function () { + trigger.directHit.addArray( + game.filterPlayer(function (current) { + return current != player; + }) + ); + if (trigger.addCount !== false) { + trigger.addCount = false; + var stat = player.getStat(); + if (stat && stat.card && stat.card[trigger.card.name]) + stat.card[trigger.card.name]--; } }, - ai:{ - directHit_ai:true, - skillTagFilter:function(player,tag,arg){ - return arg.card&&arg.card.cards&&arg.card.cards.filter((card)=>card.hasGaintag('gzwenji')).length>0; + ai: { + directHit_ai: true, + skillTagFilter: function (player, tag, arg) { + return ( + arg.card && + arg.card.cards && + arg.card.cards.filter((card) => card.hasGaintag("gzwenji")).length > 0 + ); }, }, - } - } - }, - gztunjiang:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - frequent:true, - preHidden:true, - filter:function(event,player){ - if(!player.getHistory('useCard',function(evt){ - return evt.isPhaseUsing(); - }).length) return false; - return player.getHistory('useCard',function(evt){ - if(evt.targets&&evt.targets.length&&evt.isPhaseUsing()){ - var targets=evt.targets.slice(0); - while(targets.includes(player)) targets.remove(player); - return targets.length>0; - } - return false; - }).length==0; + }, }, - content:function(){ + }, + gztunjiang: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + frequent: true, + preHidden: true, + filter: function (event, player) { + if ( + !player.getHistory("useCard", function (evt) { + return evt.isPhaseUsing(); + }).length + ) + return false; + return ( + player.getHistory("useCard", function (evt) { + if (evt.targets && evt.targets.length && evt.isPhaseUsing()) { + var targets = evt.targets.slice(0); + while (targets.includes(player)) targets.remove(player); + return targets.length > 0; + } + return false; + }).length == 0 + ); + }, + content: function () { player.draw(game.countGroup()); }, }, - gzbushi:{ - audio:2, - trigger:{player:'damageEnd'}, - frequent:true, - preHidden:true, - content:function(){ - 'step 0' - event.count=trigger.num; - 'step 1' + gzbushi: { + audio: 2, + trigger: { player: "damageEnd" }, + frequent: true, + preHidden: true, + content: function () { + "step 0"; + event.count = trigger.num; + "step 1"; event.count--; player.draw(); - 'step 2' - if(event.count>0){ - player.chooseBool(get.prompt2('gzbushi')).set('frequentSkill','gzbushi'); - } - else event.finish(); - 'step 3' - if(result.bool) event.goto(1); + "step 2"; + if (event.count > 0) { + player.chooseBool(get.prompt2("gzbushi")).set("frequentSkill", "gzbushi"); + } else event.finish(); + "step 3"; + if (result.bool) event.goto(1); }, - group:'gzbushi_draw', - subSkill:{ - draw:{ - trigger:{source:'damageSource'}, - direct:true, - noHidden:true, - filter:function(event,player){ - return event.player.isEnemyOf(player)&&event.player.isIn(); + group: "gzbushi_draw", + subSkill: { + draw: { + trigger: { source: "damageSource" }, + direct: true, + noHidden: true, + filter: function (event, player) { + return event.player.isEnemyOf(player) && event.player.isIn(); }, - content:function(){ - 'step 0' - trigger.player.chooseBool('是否对'+get.translation(player)+'发动【布施】?','你摸一张牌,然后其摸一张牌'); - 'step 1' - if(result.bool){ - player.logSkill('gzbushi',trigger.player); - game.asyncDraw([trigger.player,player]); - } - else event.finish(); - 'step 2' + content: function () { + "step 0"; + trigger.player.chooseBool( + "是否对" + get.translation(player) + "发动【布施】?", + "你摸一张牌,然后其摸一张牌" + ); + "step 1"; + if (result.bool) { + player.logSkill("gzbushi", trigger.player); + game.asyncDraw([trigger.player, player]); + } else event.finish(); + "step 2"; game.delayx(); }, }, }, }, - gzbushi_old:{ - audio:2, - trigger:{ - player:'damageEnd', - source:'damageSource', + gzbushi_old: { + audio: 2, + trigger: { + player: "damageEnd", + source: "damageSource", }, - forced:true, - filter:function(event,player,name){ - if(name=='damageSource'&&player==event.player) return false; - return game.hasPlayer(function(current){ + forced: true, + filter: function (event, player, name) { + if (name == "damageSource" && player == event.player) return false; + return game.hasPlayer(function (current) { return current.isFriendOf(event.player); }); }, - check:function(event,player){ + check: function (event, player) { return player.isFriendOf(event.player); }, - content:function(){ - 'step 0' - event.count=trigger.num; - if(event.triggername=='damageSource') event.count=1; - 'step 1' + content: function () { + "step 0"; + event.count = trigger.num; + if (event.triggername == "damageSource") event.count = 1; + "step 1"; event.count--; - var target=trigger.player; - var list=game.filterPlayer(function(current){ + var target = trigger.player; + var list = game.filterPlayer(function (current) { return current.isFriendOf(target); }); - if(list.length){ - if(list.length==1) event._result={bool:true,targets:list}; - else player.chooseTarget('布施:令一名与'+(player==target?'你':get.translation(target))+'势力相同的角色摸一张牌',true,function(card,player,target){ - return target.isFriendOf(_status.event.target) - }).set('target',target); - } - else event.finish(); - 'step 2' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'green'); + if (list.length) { + if (list.length == 1) event._result = { bool: true, targets: list }; + else + player + .chooseTarget( + "布施:令一名与" + + (player == target ? "你" : get.translation(target)) + + "势力相同的角色摸一张牌", + true, + function (card, player, target) { + return target.isFriendOf(_status.event.target); + } + ) + .set("target", target); + } else event.finish(); + "step 2"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "green"); target.draw(); - if(event.count) event.goto(1); + if (event.count) event.goto(1); } }, }, - gzmidao:{ - audio:2, - trigger:{global:'useCardToPlayered'}, - direct:true, + gzmidao: { + audio: 2, + trigger: { global: "useCardToPlayered" }, + direct: true, //noHidden:true, - filter:function(event,player){ - var target=event.player; - return event.isFirstTarget&&target.isFriendOf(player)&& - target.isPhaseUsing()&&(target==player||player.hasSkill('gzmidao'))&& - (['basic','trick'].includes(get.type(event.card))&&get.tag(event.card,'damage')>0)&& - event.cards&&event.cards.length&&!target.hasSkill('gzmidao2'); + filter: function (event, player) { + var target = event.player; + return ( + event.isFirstTarget && + target.isFriendOf(player) && + target.isPhaseUsing() && + (target == player || player.hasSkill("gzmidao")) && + ["basic", "trick"].includes(get.type(event.card)) && + get.tag(event.card, "damage") > 0 && + event.cards && + event.cards.length && + !target.hasSkill("gzmidao2") + ); }, - preHidden:true, - content:function(){ - 'step 0' - var next=trigger.player.chooseBool('是否对'+get.translation(player)+'发动【米道】?','令该角色修改'+get.translation(trigger.card)+'的花色和伤害属性'); - next.set('ai',()=>false); - if(player==next.player) next.setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.logSkill('gzmidao'); - trigger.player.addTempSkill('gzmidao2'); - if(player!=trigger.player){ - trigger.player.line(player,'green'); + preHidden: true, + content: function () { + "step 0"; + var next = trigger.player.chooseBool( + "是否对" + get.translation(player) + "发动【米道】?", + "令该角色修改" + get.translation(trigger.card) + "的花色和伤害属性" + ); + next.set("ai", () => false); + if (player == next.player) next.setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("gzmidao"); + trigger.player.addTempSkill("gzmidao2"); + if (player != trigger.player) { + trigger.player.line(player, "green"); //player.gain(result.cards,trigger.player,'giveAuto'); } - } - else event.finish(); - 'step 2' - if(player.isUnderControl()){ + } else event.finish(); + "step 2"; + if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto=function(){ - _status.imchoosing=false; - var listn=['普通'].concat(lib.inpile_nature); - event._result={ - bool:true, - suit:lib.suit.randomGet(), - nature:listn.randomGet(), + var switchToAuto = function () { + _status.imchoosing = false; + var listn = ["普通"].concat(lib.inpile_nature); + event._result = { + bool: true, + suit: lib.suit.randomGet(), + nature: listn.randomGet(), }; - if(event.dialog) event.dialog.close(); - if(event.control) event.control.close(); + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); }; - var chooseButton=function(player,card){ - var event=_status.event; - player=player||event.player; - if(!event._result) event._result={}; - var dialog=ui.create.dialog('米道:请修改'+card+'的花色和属性','forcebutton','hidden'); - event.dialog=dialog; - dialog.addText('花色'); - var table=document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin='0'; - table.style.width='100%'; - table.style.position='relative'; - var listi=['spade','heart','club','diamond']; - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + td.innerHTML = "" + get.translation(listi[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.suit=link; + this.classList.add("bluebg"); + event._result.suit = link; }); } dialog.content.appendChild(table); - dialog.addText('属性'); - var table2=document.createElement('div'); - table2.classList.add('add-setting'); - table2.style.margin='0'; - table2.style.width='100%'; - table2.style.position='relative'; - var listn=['普通'].concat(lib.inpile_nature); - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + td.innerHTML = "" + get.translation(nature) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - this.classList.add('bluebg'); - event._result.nature=link; + this.classList.add("bluebg"); + event._result.nature = link; }); } dialog.content.appendChild(table2); - dialog.add('  '); + dialog.add("  "); event.dialog.open(); - event.switchToAuto=function(){ - event._result={ - bool:true, - nature:listn.randomGet(), - suit:listi.randomGet(), + event.switchToAuto = function () { + event._result = { + bool: true, + nature: listn.randomGet(), + suit: listi.randomGet(), }; event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }; - event.control=ui.create.control('ok','cancel2',function(link){ - var result=event._result; - if(link=='cancel2') result.bool=false; - else{ - if(!result.nature||!result.suit) return; - result.bool=true; + event.control = ui.create.control("ok", "cancel2", function (link) { + var result = event._result; + if (link == "cancel2") result.bool = false; + else { + if (!result.nature || !result.suit) return; + result.bool = true; } event.dialog.close(); event.control.close(); game.resume(); - _status.imchoosing=false; + _status.imchoosing = false; }); - for(var i=0;i=0) return 0; - if(target.countCards('e',function(card){ - return get.value(card,target)>=7-player.hp; - })>0) return 1; - var dist=get.distance(player,target,'attack'); - if(dist>1&&dist-target.countCards('e')<=1) return true; - return 0; - }); - 'step 1' - if(result.index==0) player.draw(); - else{ - target.discardPlayerCard(player,'e',true); + var str = get.translation(player); + target + .chooseControl() + .set("prompt", str + "发动了【礼下】,请选择一项") + .set("choiceList", [ + "令" + str + "摸一张牌", + "弃置" + str + "装备区内的一张牌并失去1点体力", + ]) + .set("ai", function () { + var player = _status.event.player, + target = _status.event.getParent().player; + if (player.hp <= 1 || get.attitude(player, target) >= 0) return 0; + if ( + target.countCards("e", function (card) { + return get.value(card, target) >= 7 - player.hp; + }) > 0 + ) + return 1; + var dist = get.distance(player, target, "attack"); + if (dist > 1 && dist - target.countCards("e") <= 1) return true; + return 0; + }); + "step 1"; + if (result.index == 0) player.draw(); + else { + target.discardPlayerCard(player, "e", true); target.loseHp(); } }, }, - gzlixia:{ - audio:2, - trigger:{global:'phaseZhunbeiBegin'}, - noHidden:true, - direct:true, - filter:function(event,player){ - return player!=event.player&&!event.player.isFriendOf(player)&&player.countDiscardableCards(event.player,'e')>0; + gzlixia: { + audio: 2, + trigger: { global: "phaseZhunbeiBegin" }, + noHidden: true, + direct: true, + filter: function (event, player) { + return ( + player != event.player && + !event.player.isFriendOf(player) && + player.countDiscardableCards(event.player, "e") > 0 + ); }, - content:function(){ - 'step 0' - trigger.player.chooseBool('是否对'+get.translation(player)+'发动【礼下】?','弃置其装备区内的一张牌,然后选择一项:①弃置两张牌。②失去1点体力。③令其摸两张牌。').set('ai',function(){ - var player=_status.event.player; - var target=_status.event.getParent().player; - if(get.attitude(player,target)>0) return target.countCards('e',function(card){ - return get.value(card,target)<3; - })>0; - if(target.countCards('e',function(card){ - return get.value(card,target)>=7; - })) return true; - var dist=get.distance(player,target,'attack'); - if(dist>1&&dist-target.countCards('e')<=1) return true; - return false; - }); - 'step 1' - if(result.bool){ - var target=trigger.player; - event.target=target; - player.logSkill('gzlixia'); - target.line(player,'green'); - target.discardPlayerCard(player,'e',true); - } - else event.finish(); - 'step 2' - var list=['失去1点体力','令'+get.translation(player)+'摸两张牌']; - event.addIndex=0; - if(target.countCards('h',function(card){ - return lib.filter.cardDiscardable(card,target,'gzlixia'); - })>1) list.unshift('弃置两张牌'); + content: function () { + "step 0"; + trigger.player + .chooseBool( + "是否对" + get.translation(player) + "发动【礼下】?", + "弃置其装备区内的一张牌,然后选择一项:①弃置两张牌。②失去1点体力。③令其摸两张牌。" + ) + .set("ai", function () { + var player = _status.event.player; + var target = _status.event.getParent().player; + if (get.attitude(player, target) > 0) + return ( + target.countCards("e", function (card) { + return get.value(card, target) < 3; + }) > 0 + ); + if ( + target.countCards("e", function (card) { + return get.value(card, target) >= 7; + }) + ) + return true; + var dist = get.distance(player, target, "attack"); + if (dist > 1 && dist - target.countCards("e") <= 1) return true; + return false; + }); + "step 1"; + if (result.bool) { + var target = trigger.player; + event.target = target; + player.logSkill("gzlixia"); + target.line(player, "green"); + target.discardPlayerCard(player, "e", true); + } else event.finish(); + "step 2"; + var list = ["失去1点体力", "令" + get.translation(player) + "摸两张牌"]; + event.addIndex = 0; + if ( + target.countCards("h", function (card) { + return lib.filter.cardDiscardable(card, target, "gzlixia"); + }) > 1 + ) + list.unshift("弃置两张牌"); else event.addIndex++; - target.chooseControl().set('choiceList',list).set('ai',function(){ - var num=2; - var player=_status.event.player; - var target=_status.event.getParent().player; - if(get.attitude(player,target)>=0) num=2; - else if(player.countCards('he',function(card){ - return lib.filter.cardDiscardable(card,player,'gzlixia')&&get.value(card,player)<5; - })>1) num=0; - else if(player.hp+player.countCards('h','tao')>3&&!player.hasJudge('lebu')) num=1; - return num-_status.event.getParent().addIndex; - }); - 'step 3' - switch(result.index+event.addIndex){ + target + .chooseControl() + .set("choiceList", list) + .set("ai", function () { + var num = 2; + var player = _status.event.player; + var target = _status.event.getParent().player; + if (get.attitude(player, target) >= 0) num = 2; + else if ( + player.countCards("he", function (card) { + return ( + lib.filter.cardDiscardable(card, player, "gzlixia") && + get.value(card, player) < 5 + ); + }) > 1 + ) + num = 0; + else if ( + player.hp + player.countCards("h", "tao") > 3 && + !player.hasJudge("lebu") + ) + num = 1; + return num - _status.event.getParent().addIndex; + }); + "step 3"; + switch (result.index + event.addIndex) { case 0: - target.chooseToDiscard(2,'h',true); + target.chooseToDiscard(2, "h", true); break; case 1: target.loseHp(); @@ -10938,2092 +14435,2664 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }, }, - yigui:{ - audio:2, - hiddenCard:function(player,name){ - var storage=player.storage.yigui; - if(name=='shan'||name=='wuxie'||!storage||!storage.character.length||storage.used.includes(name)||!lib.inpile.includes(name)) return false; + yigui: { + audio: 2, + hiddenCard: function (player, name) { + var storage = player.storage.yigui; + if ( + name == "shan" || + name == "wuxie" || + !storage || + !storage.character.length || + storage.used.includes(name) || + !lib.inpile.includes(name) + ) + return false; return true; }, - init:function(player,skill){ - if(!player.storage.skill) player.storage[skill]={ - character:[], - used:[], - } + init: function (player, skill) { + if (!player.storage.skill) + player.storage[skill] = { + character: [], + used: [], + }; }, - enable:"chooseToUse", - filter:function(event,player){ - if(event.type=='wuxie'||event.type=='respondShan') return false; - var storage=player.storage.yigui; - if(!storage||!storage.character.length) return false; - if(event.type=='dying'){ - if((!event.filterCard({name:'tao'},player,event)||storage.used.includes('tao'))&& - (!event.filterCard({name:'jiu'},player,event)||storage.used.includes('jiu'))) return false; - var target=event.dying; - if(target.identity=='unknown'||target.identity=='ye') return true; - for(var i=0;i1) return (1.7+Math.random())*Math.max(num,1); + if (num <= 0) return 0; + if (list.length > 1) return (1.7 + Math.random()) * Math.max(num, 1); } } - return 1+Math.random(); + return 1 + Math.random(); }, - filter:function(button,player){ - var evt=_status.event.getParent('chooseToUse'); - if(!ui.selected.buttons.length){ - if(typeof button.link!='string') return false; - if(evt.type=='dying'){ - if(evt.dying.identity=='unknown'||evt.dying.identity=='ye') return true; - var double=get.is.double(button.link,true); - return evt.dying.identity==lib.character[button.link][1]||lib.character[button.link][1]=='ye'||(double&&double.includes(evt.dying.identity)); + filter: function (button, player) { + var evt = _status.event.getParent("chooseToUse"); + if (!ui.selected.buttons.length) { + if (typeof button.link != "string") return false; + if (evt.type == "dying") { + if (evt.dying.identity == "unknown" || evt.dying.identity == "ye") + return true; + var double = get.is.double(button.link, true); + return ( + evt.dying.identity == lib.character[button.link][1] || + lib.character[button.link][1] == "ye" || + (double && double.includes(evt.dying.identity)) + ); } return true; - } - else{ - if(typeof ui.selected.buttons[0].link!='string') return false; - if(typeof button.link!='object') return false; - var name=button.link[2]; - if(player.storage.yigui.used.includes(name)) return false; - var card={name:name}; - if(button.link[3]) card.nature=button.link[3]; - var info=get.info(card); - var group=lib.character[ui.selected.buttons[0].link][1]; - var double=get.is.double(ui.selected.buttons[0].link,true); - if(evt.type=='dying'){ - return evt.filterCard(card,player,evt); + } else { + if (typeof ui.selected.buttons[0].link != "string") return false; + if (typeof button.link != "object") return false; + var name = button.link[2]; + if (player.storage.yigui.used.includes(name)) return false; + var card = { name: name }; + if (button.link[3]) card.nature = button.link[3]; + var info = get.info(card); + var group = lib.character[ui.selected.buttons[0].link][1]; + var double = get.is.double(ui.selected.buttons[0].link, true); + if (evt.type == "dying") { + return evt.filterCard(card, player, evt); } - if(!lib.filter.filterCard(card,player,evt)) return false; - else if(evt.filterCard&&!evt.filterCard(card,player,evt)) return false; - if(info.changeTarget){ - var list=game.filterPlayer(function(current){ - return player.canUse(card,current); + if (!lib.filter.filterCard(card, player, evt)) return false; + else if (evt.filterCard && !evt.filterCard(card, player, evt)) return false; + if (info.changeTarget) { + var list = game.filterPlayer(function (current) { + return player.canUse(card, current); }); - for(var i=0;ifalse, - selectCard:-1, - complexCard:true, - check:()=>1, - popname:true, - audio:'yigui', - viewAs:{name:'shan',isCard:true}, - onuse:function(result,player){ - player.logSkill('yigui'); - var character=lib.skill.yigui_gzshan_backup.character; - player.flashAvatar('yigui',character); + backup: function (links, player) { + var character = links[0]; + var next = { + character: character, + filterCard: () => false, + selectCard: -1, + complexCard: true, + check: () => 1, + popname: true, + audio: "yigui", + viewAs: { name: "shan", isCard: true }, + onuse: function (result, player) { + player.logSkill("yigui"); + var character = lib.skill.yigui_gzshan_backup.character; + player.flashAvatar("yigui", character); player.storage.yigui.character.remove(character); _status.characterlist.add(character); - game.log(player,'从「魂」中移除了','#g'+get.translation(character)); - player.syncStorage('yigui'); - player.updateMarks('yigui'); + game.log(player, "从「魂」中移除了", "#g" + get.translation(character)); + player.syncStorage("yigui"); + player.updateMarks("yigui"); player.storage.yigui.used.add(result.card.name); }, }; return next; }, }, - ai:{ - respondShan:true, - skillTagFilter:function(player,tag,arg){ - if(arg=='respond'||!lib.inpile.includes('shan')) return false; - var storage=player.storage.yigui; - if(!storage||!storage.character.length||storage.used.includes('shan')) return false; + ai: { + respondShan: true, + skillTagFilter: function (player, tag, arg) { + if (arg == "respond" || !lib.inpile.includes("shan")) return false; + var storage = player.storage.yigui; + if (!storage || !storage.character.length || storage.used.includes("shan")) + return false; }, - order:0.1, - result:{player:1}, + order: 0.1, + result: { player: 1 }, }, }, - yigui_gzwuxie:{ - hiddenWuxie(player,info){ - if(!lib.inpile.includes('wuxie')) return false; - const storage=player.storage.yigui; - if(!storage||!storage.character||!storage.character.length||(storage.used&&storage.used.includes('wuxie'))) return false; - if(_status.connectMode) return true; - const target=info.target; - if(!target) return false; - const identity=target.identity; - return ['unknown','ye'].includes(identity)||storage.character.some(function(i){ - if(lib.character[i][1]=='ye') return true; - const double=get.is.double(i,true); - return (double?double:[lib.character[i][1]]).includes(identity); - }); + yigui_gzwuxie: { + hiddenWuxie(player, info) { + if (!lib.inpile.includes("wuxie")) return false; + const storage = player.storage.yigui; + if ( + !storage || + !storage.character || + !storage.character.length || + (storage.used && storage.used.includes("wuxie")) + ) + return false; + if (_status.connectMode) return true; + const target = info.target; + if (!target) return false; + const identity = target.identity; + return ( + ["unknown", "ye"].includes(identity) || + storage.character.some(function (i) { + if (lib.character[i][1] == "ye") return true; + const double = get.is.double(i, true); + return (double ? double : [lib.character[i][1]]).includes(identity); + }) + ); }, - enable:'chooseToUse', - filter(event,player){ - if(event.type!='wuxie'||!lib.inpile.includes('wuxie')) return false; - const storage=player.storage.yigui; - if(!storage||!storage.character||!storage.character.length||(storage.used&&storage.used.includes('wuxie'))) return false; - const info=event.info_map,target=info.target,identity=target.identity; - return ['unknown','ye'].includes(identity)||storage.character.some(function(i){ - if(lib.character[i][1]=='ye') return true; - const double=get.is.double(i,true); - return (double?double:[lib.character[i][1]]).includes(identity); - }); + enable: "chooseToUse", + filter(event, player) { + if (event.type != "wuxie" || !lib.inpile.includes("wuxie")) return false; + const storage = player.storage.yigui; + if ( + !storage || + !storage.character || + !storage.character.length || + (storage.used && storage.used.includes("wuxie")) + ) + return false; + const info = event.info_map, + target = info.target, + identity = target.identity; + return ( + ["unknown", "ye"].includes(identity) || + storage.character.some(function (i) { + if (lib.character[i][1] == "ye") return true; + const double = get.is.double(i, true); + return (double ? double : [lib.character[i][1]]).includes(identity); + }) + ); }, - chooseButton:{ - dialog(event,player){ - let dialog=ui.create.dialog('役鬼','hidden'); - dialog.add([player.storage.yigui.character,'character']); + chooseButton: { + dialog(event, player) { + let dialog = ui.create.dialog("役鬼", "hidden"); + dialog.add([player.storage.yigui.character, "character"]); return dialog; }, - filter(button,player){ - const evt=get.event().getParent('chooseToUse'); - const info=evt.info_map,target=info.target,identity=target.identity; - if(['unknown','ye'].includes(identity)) return true; - if(lib.character[button.link][1]=='ye') return true; - const double=get.is.double(button.link,true); - return (double?double:[lib.character[button.link][1]]).includes(identity); + filter(button, player) { + const evt = get.event().getParent("chooseToUse"); + const info = evt.info_map, + target = info.target, + identity = target.identity; + if (["unknown", "ye"].includes(identity)) return true; + if (lib.character[button.link][1] == "ye") return true; + const double = get.is.double(button.link, true); + return (double ? double : [lib.character[button.link][1]]).includes(identity); }, - check(button){ - return 1+Math.random(); + check(button) { + return 1 + Math.random(); }, - backup(links,player){ + backup(links, player) { return { - character:links[0], - filterCard:()=>false, - selectCard:-1, - complexCard:true, - check:()=>1, - popname:true, - audio:'yigui', - viewAs:{name:'wuxie',isCard:true}, - onuse(result,player){ - player.logSkill('yigui'); - const character=lib.skill.yigui_gzwuxie_backup.character; - player.flashAvatar('yigui',character); + character: links[0], + filterCard: () => false, + selectCard: -1, + complexCard: true, + check: () => 1, + popname: true, + audio: "yigui", + viewAs: { name: "wuxie", isCard: true }, + onuse(result, player) { + player.logSkill("yigui"); + const character = lib.skill.yigui_gzwuxie_backup.character; + player.flashAvatar("yigui", character); player.storage.yigui.character.remove(character); _status.characterlist.add(character); - game.log(player,'从「魂」中移除了','#g'+get.translation(character)); - player.syncStorage('yigui'); - player.updateMarks('yigui'); + game.log(player, "从「魂」中移除了", "#g" + get.translation(character)); + player.syncStorage("yigui"); + player.updateMarks("yigui"); player.storage.yigui.used.add(result.card.name); }, }; }, }, - ai:{ - order:0.1, - result:{player:1}, + ai: { + order: 0.1, + result: { player: 1 }, }, }, - jihun:{ - trigger:{ - player:'damageEnd', - global:'dyingAfter', + jihun: { + trigger: { + player: "damageEnd", + global: "dyingAfter", }, - audio:2, - frequent:true, - preHidden:true, - filter:function(event,player){ - return event.name=='damage'||(event.player.isAlive()&&!event.player.isFriendOf(player)) + audio: 2, + frequent: true, + preHidden: true, + filter: function (event, player) { + return ( + event.name == "damage" || (event.player.isAlive() && !event.player.isFriendOf(player)) + ); }, - content:function(){ - var list=_status.characterlist.randomGets(1); - if(list.length){ + content: function () { + var list = _status.characterlist.randomGets(1); + if (list.length) { _status.characterlist.removeArray(list); player.storage.yigui.character.addArray(list); - lib.skill.gzhuashen.drawCharacter(player,list); - player.syncStorage('yigui'); - player.updateMarks('yigui'); - game.log(player,'获得了'+get.cnNumber(list.length)+'张「魂」'); + lib.skill.gzhuashen.drawCharacter(player, list); + player.syncStorage("yigui"); + player.updateMarks("yigui"); + game.log(player, "获得了" + get.cnNumber(list.length) + "张「魂」"); } }, }, - gzbuyi:{ - trigger:{global:'dyingAfter'}, - usable:1, - filter:function(event,player){ - if(!(event.player&&event.player.isAlive()&&event.source&&event.source.isAlive())) return false; - return event.player.isFriendOf(player)&&event.reason&&event.reason.name=='damage'; + gzbuyi: { + trigger: { global: "dyingAfter" }, + usable: 1, + filter: function (event, player) { + if (!(event.player && event.player.isAlive() && event.source && event.source.isAlive())) + return false; + return event.player.isFriendOf(player) && event.reason && event.reason.name == "damage"; }, - check:function(event,player){return get.attitude(player,event.player)>0}, - logTarget:'source', - preHidden:true, - content:function(){ - 'step 0' + check: function (event, player) { + return get.attitude(player, event.player) > 0; + }, + logTarget: "source", + preHidden: true, + content: function () { + "step 0"; player.chooseJunlingFor(trigger.source); - 'step 1' - event.junling=result.junling; - event.targets=result.targets; - var choiceList=[]; - choiceList.push('执行该军令'); - choiceList.push('令'+get.translation(trigger.player)+(trigger.player==trigger.source?'(你)':'')+'回复1点体力'); - trigger.source.chooseJunlingControl(player,result.junling,result.targets).set('prompt','补益').set('choiceList',choiceList).set('ai',function(){ - if(get.recoverEffect(trigger.player,player,_status.event.player)>0) return 1; - return (get.attitude(trigger.source,trigger.player)<0&&get.junlingEffect(player,result.junling,trigger.source,result.targets,trigger.source)>=-2)?1:0; - }); - 'step 2' - if(result.index==0) trigger.source.carryOutJunling(player,event.junling,targets); + "step 1"; + event.junling = result.junling; + event.targets = result.targets; + var choiceList = []; + choiceList.push("执行该军令"); + choiceList.push( + "令" + + get.translation(trigger.player) + + (trigger.player == trigger.source ? "(你)" : "") + + "回复1点体力" + ); + trigger.source + .chooseJunlingControl(player, result.junling, result.targets) + .set("prompt", "补益") + .set("choiceList", choiceList) + .set("ai", function () { + if (get.recoverEffect(trigger.player, player, _status.event.player) > 0) return 1; + return get.attitude(trigger.source, trigger.player) < 0 && + get.junlingEffect( + player, + result.junling, + trigger.source, + result.targets, + trigger.source + ) >= -2 + ? 1 + : 0; + }); + "step 2"; + if (result.index == 0) trigger.source.carryOutJunling(player, event.junling, targets); else trigger.player.recover(player); }, - audio:['buyi',2], + audio: ["buyi", 2], }, - keshou:{ - audio:2, - trigger:{player:'damageBegin3'}, - filter:function(event,player){ - return event.num>0; + keshou: { + audio: 2, + trigger: { player: "damageBegin3" }, + filter: function (event, player) { + return event.num > 0; }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - var check=(player.countCards('h',{color:'red'})>1||player.countCards('h',{color:'black'})>1); - player.chooseCard(get.prompt('keshou'),'弃置两张颜色相同的牌,令即将受到的伤害-1','he',2,function(card){ - if(ui.selected.cards.length) return get.color(card)==get.color(ui.selected.cards[0]); - return true; - }).set('complexCard',true).set('ai',function(card){ - if(!_status.event.check) return 0; - var player=_status.event.player; - if(player.hp==1){ - if(!player.countCards('h',function(card){return get.tag(card,'save')})&&!player.hasSkillTag('save',true)) return 10-get.value(card); - return 7-get.value(card); - } - return 6-get.value(card); - }).set('check',check).setHiddenSkill(event.name); - 'step 1' - var logged=false; - if(result.cards){ - logged=true; - player.logSkill('keshou'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + var check = + player.countCards("h", { color: "red" }) > 1 || + player.countCards("h", { color: "black" }) > 1; + player + .chooseCard( + get.prompt("keshou"), + "弃置两张颜色相同的牌,令即将受到的伤害-1", + "he", + 2, + function (card) { + if (ui.selected.cards.length) + return get.color(card) == get.color(ui.selected.cards[0]); + return true; + } + ) + .set("complexCard", true) + .set("ai", function (card) { + if (!_status.event.check) return 0; + var player = _status.event.player; + if (player.hp == 1) { + if ( + !player.countCards("h", function (card) { + return get.tag(card, "save"); + }) && + !player.hasSkillTag("save", true) + ) + return 10 - get.value(card); + return 7 - get.value(card); + } + return 6 - get.value(card); + }) + .set("check", check) + .setHiddenSkill(event.name); + "step 1"; + var logged = false; + if (result.cards) { + logged = true; + player.logSkill("keshou"); player.discard(result.cards); trigger.num--; } - if(!player.isUnseen()&&!game.hasPlayer(function(current){ - return current!=player&¤t.isFriendOf(player); - })){ - if(!logged) player.logSkill('keshou'); - player.judge(function(card){ - if(get.color(card)=='red') return 1; + if ( + !player.isUnseen() && + !game.hasPlayer(function (current) { + return current != player && current.isFriendOf(player); + }) + ) { + if (!logged) player.logSkill("keshou"); + player.judge(function (card) { + if (get.color(card) == "red") return 1; return 0; }); - } - else event.finish(); - 'step 2' - if(result.judge>0) player.draw(); - } + } else event.finish(); + "step 2"; + if (result.judge > 0) player.draw(); + }, }, - zhuwei:{ - audio:2, - trigger:{player:'judgeEnd'}, - filter:function(event){ - if(get.owner(event.result.card)) return false; - if(event.nogain&&event.nogain(event.result.card)) return false; + zhuwei: { + audio: 2, + trigger: { player: "judgeEnd" }, + filter: function (event) { + if (get.owner(event.result.card)) return false; + if (event.nogain && event.nogain(event.result.card)) return false; return true; //return event.result.card.name=='sha'||event.result.card.name=='juedou'; }, - frequent:true, - preHidden:true, - content:function(){ - 'step 0' - player.gain(trigger.result.card,'gain2'); - player.chooseBool('是否令'+get.translation(_status.currentPhase)+'本回合的手牌上限和使用【杀】的次数上限+1?').ai=function(){ - return get.attitude(player,_status.currentPhase)>0; + frequent: true, + preHidden: true, + content: function () { + "step 0"; + player.gain(trigger.result.card, "gain2"); + player.chooseBool( + "是否令" + + get.translation(_status.currentPhase) + + "本回合的手牌上限和使用【杀】的次数上限+1?" + ).ai = function () { + return get.attitude(player, _status.currentPhase) > 0; }; - 'step 1' - if(result.bool){ - var target=_status.currentPhase; - if(!target.hasSkill('zhuwei_eff')){ - target.addTempSkill('zhuwei_eff'); - target.storage.zhuwei_eff=1; - } - else target.storage.zhuwei_eff++; + "step 1"; + if (result.bool) { + var target = _status.currentPhase; + if (!target.hasSkill("zhuwei_eff")) { + target.addTempSkill("zhuwei_eff"); + target.storage.zhuwei_eff = 1; + } else target.storage.zhuwei_eff++; target.updateMarks(); } }, - subSkill:{ - eff:{ - sub:true, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+player.storage.zhuwei_eff; + subSkill: { + eff: { + sub: true, + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + player.storage.zhuwei_eff; + }, + maxHandcard: function (player, num) { + return num + player.storage.zhuwei_eff; }, - maxHandcard:function(player,num){return num+player.storage.zhuwei_eff} }, - mark:true, - charlotte:true, - intro:{ - content:function(storage){if(storage) return '使用【杀】的次数上限+'+storage+',手牌上限+'+storage} - } - } - } + mark: true, + charlotte: true, + intro: { + content: function (storage) { + if (storage) + return "使用【杀】的次数上限+" + storage + ",手牌上限+" + storage; + }, + }, + }, + }, }, - gzweidi:{ - init:function(player){player.storage.gzweidi=[]}, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.storage.gzweidi.length>0 + gzweidi: { + init: function (player) { + player.storage.gzweidi = []; }, - filterTarget:function(card,player,target){return target!=player&&player.storage.gzweidi.includes(target)}, - content:function(){ - 'step 0' + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.storage.gzweidi.length > 0; + }, + filterTarget: function (card, player, target) { + return target != player && player.storage.gzweidi.includes(target); + }, + content: function () { + "step 0"; player.chooseJunlingFor(target); - 'step 1' - event.junling=result.junling; - event.targets=result.targets; - var choiceList=['执行该军令']; - if(target!=player) choiceList.push('令'+get.translation(player)+'获得你所有手牌,然后交给你等量的牌'); - else choiceList.push('不执行该军令'); - target.chooseJunlingControl(player,result.junling,result.targets).set('prompt','伪帝').set('choiceList',choiceList).set('ai',function(){ - if(get.attitude(target,player)>=0) return get.junlingEffect(player,result.junling,target,result.targets,target)>=0?0:1; - return get.junlingEffect(player,result.junling,target,result.targets,target)>=-1?0:1; - }); - 'step 2' - if(result.index==0) target.carryOutJunling(player,event.junling,targets); - else if(target!=player&&target.countCards('h')) { - event.num=target.countCards('h'); - player.gain(target.getCards('h'),target,'giveAuto'); - player.chooseCard('交给'+get.translation(target)+get.cnNumber(event.num)+'张牌','he',event.num,true).set('ai',function(card){ - return -get.value(card); + "step 1"; + event.junling = result.junling; + event.targets = result.targets; + var choiceList = ["执行该军令"]; + if (target != player) + choiceList.push( + "令" + get.translation(player) + "获得你所有手牌,然后交给你等量的牌" + ); + else choiceList.push("不执行该军令"); + target + .chooseJunlingControl(player, result.junling, result.targets) + .set("prompt", "伪帝") + .set("choiceList", choiceList) + .set("ai", function () { + if (get.attitude(target, player) >= 0) + return get.junlingEffect( + player, + result.junling, + target, + result.targets, + target + ) >= 0 + ? 0 + : 1; + return get.junlingEffect( + player, + result.junling, + target, + result.targets, + target + ) >= -1 + ? 0 + : 1; }); - } - else event.finish(); - 'step 3' - if(result.cards){ - player.give(result.cards,target); + "step 2"; + if (result.index == 0) target.carryOutJunling(player, event.junling, targets); + else if (target != player && target.countCards("h")) { + event.num = target.countCards("h"); + player.gain(target.getCards("h"), target, "giveAuto"); + player + .chooseCard( + "交给" + get.translation(target) + get.cnNumber(event.num) + "张牌", + "he", + event.num, + true + ) + .set("ai", function (card) { + return -get.value(card); + }); + } else event.finish(); + "step 3"; + if (result.cards) { + player.give(result.cards, target); } }, - group:['gzweidi_ft','gzweidi_ftc'], - ai:{ - order:3, - result:{ - player:1, - } + group: ["gzweidi_ft", "gzweidi_ftc"], + ai: { + order: 3, + result: { + player: 1, + }, }, - subSkill:{ - ft:{ - sub:true, - trigger:{global:'gainBefore'}, - silent:true, - filter:function(event,player){ - if(player==event.player||player.storage.gzweidi.includes(event.player)||_status.currentPhase!=player) return false; - if(event.cards.length){ - if(event.getParent().name=='draw') return true; - for(var i=0;i0; - }) - }, - content:function(){trigger.num++}, - audio:['yongsi1',2], - }, - eff2:{ - sub:true, - trigger:{player:'phaseUseBegin'}, - //priority:8, - forced:true, - noHidden:true, - equipSkill:true, - filter:function(event,player){ - if(player.isDisabled(5)) return false; - return game.hasPlayer(function(current){ - return player.canUse('zhibi',current); - })&&!game.hasPlayer(function(current){ - return current.getEquips('yuxi').length>0; + forced: true, + filter: function (event, player) { + if (event.numFixed || player.isDisabled(5)) return false; + return !game.hasPlayer(function (current) { + return current.getEquips("yuxi").length > 0; }); }, - content:function(){ - player.chooseUseTarget('玉玺(庸肆):选择知己知彼的目标',{name:'zhibi'}); + content: function () { + trigger.num++; }, - audio:['yongsi1',2], + audio: ["yongsi1", 2], }, - eff3:{ - sub:true, - trigger:{global:'useCardToTargeted'}, - //priority:16, - forced:true, - filter:function(event,player){ - return event.target&&event.target==player&&event.card&&event.card.name=='zhibi' + eff2: { + sub: true, + trigger: { player: "phaseUseBegin" }, + //priority:8, + forced: true, + noHidden: true, + equipSkill: true, + filter: function (event, player) { + if (player.isDisabled(5)) return false; + return ( + game.hasPlayer(function (current) { + return player.canUse("zhibi", current); + }) && + !game.hasPlayer(function (current) { + return current.getEquips("yuxi").length > 0; + }) + ); }, - check:function(){return false}, - content:function(){ + content: function () { + player.chooseUseTarget("玉玺(庸肆):选择知己知彼的目标", { name: "zhibi" }); + }, + audio: ["yongsi1", 2], + }, + eff3: { + sub: true, + trigger: { global: "useCardToTargeted" }, + //priority:16, + forced: true, + filter: function (event, player) { + return ( + event.target && + event.target == player && + event.card && + event.card.name == "zhibi" + ); + }, + check: function () { + return false; + }, + content: function () { player.showHandcards(); - } - } - } + }, + }, + }, }, - gzfudi:{ - trigger:{global:'damageEnd'}, - direct:true, - preHidden:true, - audio:2, - filter:function(event,player){return event.source&&event.source.isAlive()&&event.source!=player&&event.player==player&&player.countCards('h')&&event.num>0}, - content:function(){ - 'step 0' - var players=game.filterPlayer(function(current){ - return current.isFriendOf(trigger.source)&¤t.hp>=player.hp&&!game.hasPlayer(function(current2){ - return current2.hp>current.hp&¤t2.isFriendOf(trigger.source); + gzfudi: { + trigger: { global: "damageEnd" }, + direct: true, + preHidden: true, + audio: 2, + filter: function (event, player) { + return ( + event.source && + event.source.isAlive() && + event.source != player && + event.player == player && + player.countCards("h") && + event.num > 0 + ); + }, + content: function () { + "step 0"; + var players = game.filterPlayer(function (current) { + return ( + current.isFriendOf(trigger.source) && + current.hp >= player.hp && + !game.hasPlayer(function (current2) { + return current2.hp > current.hp && current2.isFriendOf(trigger.source); + }) + ); + }); + var check = true; + if (!players.length) check = false; + else { + if (get.attitude(player, trigger.source) >= 0) check = false; + } + player + .chooseCard( + get.prompt("gzfudi", trigger.source), + "交给其一张手牌,然后对其势力中体力值最大且不小于你的一名角色造成1点伤害" + ) + .set("aicheck", check) + .set("ai", function (card) { + if (!_status.event.aicheck) return 0; + return 9 - get.value(card); }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("gzfudi", trigger.source); + player.give(result.cards, trigger.source); + } else event.finish(); + "step 2"; + var list = game.filterPlayer(function (current) { + return ( + current.hp >= player.hp && + current.isFriendOf(trigger.source) && + !game.hasPlayer(function (current2) { + return current2.hp > current.hp && current2.isFriendOf(trigger.source); + }) + ); }); - var check=true; - if(!players.length) check=false; - else{ - if(get.attitude(player,trigger.source)>=0) check=false; - } - player.chooseCard(get.prompt('gzfudi',trigger.source),'交给其一张手牌,然后对其势力中体力值最大且不小于你的一名角色造成1点伤害').set('aicheck',check).set('ai',function(card){ - if(!_status.event.aicheck) return 0; - return 9-get.value(card); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.logSkill('gzfudi',trigger.source); - player.give(result.cards,trigger.source); - } - else event.finish(); - 'step 2' - var list=game.filterPlayer(function(current){ - return current.hp>=player.hp&¤t.isFriendOf(trigger.source)&&!game.hasPlayer(function(current2){ - return current2.hp>current.hp&¤t2.isFriendOf(trigger.source); - }); - }); - if(list.length){ - if(list.length==1) event._result={bool:true,targets:list}; - else player.chooseTarget(true,'对'+get.translation(trigger.source)+'势力中体力值最大的一名角色造成1点伤害',function(card,player,target){ - return _status.event.list.includes(target); - }).set('list',list).set('ai',function(target){return get.damageEffect(target,player,player)}); - } - else event.finish(); - 'step 3' - if(result.bool&&result.targets.length){ + if (list.length) { + if (list.length == 1) event._result = { bool: true, targets: list }; + else + player + .chooseTarget( + true, + "对" + + get.translation(trigger.source) + + "势力中体力值最大的一名角色造成1点伤害", + function (card, player, target) { + return _status.event.list.includes(target); + } + ) + .set("list", list) + .set("ai", function (target) { + return get.damageEffect(target, player, player); + }); + } else event.finish(); + "step 3"; + if (result.bool && result.targets.length) { player.line(result.targets[0]); result.targets[0].damage(); } }, - ai:{ - maixie:true, - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.countCards('h')) return [1,-1]; - if(game.countPlayer(function(current){return current.isFriendOf(player)&¤t.hp>=target.hp-1})) return [1,0,0,-2]; + ai: { + maixie: true, + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.countCards("h")) return [1, -1]; + if ( + game.countPlayer(function (current) { + return current.isFriendOf(player) && current.hp >= target.hp - 1; + }) + ) + return [1, 0, 0, -2]; } - } - } - } - }, - gzcongjian:{ - trigger:{ - player:'damageBegin3', - source:'damageBegin1', + }, + }, }, - forced:true, - preHidden:true, - audio:'drlt_congjian', - filter:function(event,player,name){ - if(event.num<=0) return false; - if(name=='damageBegin1'&&_status.currentPhase!=player) return true; - if(name=='damageBegin3'&&_status.currentPhase==player) return true; + }, + gzcongjian: { + trigger: { + player: "damageBegin3", + source: "damageBegin1", + }, + forced: true, + preHidden: true, + audio: "drlt_congjian", + filter: function (event, player, name) { + if (event.num <= 0) return false; + if (name == "damageBegin1" && _status.currentPhase != player) return true; + if (name == "damageBegin3" && _status.currentPhase == player) return true; return false; }, - check:function(event,player){ - return _status.currentPhase!=player; + check: function (event, player) { + return _status.currentPhase != player; + }, + content: function () { + trigger.num++; }, - content:function(){trigger.num++}, }, - jianan:{ - audio:2, - unique:true, - forceunique:true, - group:'wuziliangjiangdao', - derivation:'wuziliangjiangdao', - lordSkill:true, - global:'g_jianan', + jianan: { + audio: 2, + unique: true, + forceunique: true, + group: "wuziliangjiangdao", + derivation: "wuziliangjiangdao", + lordSkill: true, + global: "g_jianan", }, - g_jianan:{ - trigger:{ - player:['phaseZhunbeiBegin','phaseBefore','dieBegin'], + g_jianan: { + trigger: { + player: ["phaseZhunbeiBegin", "phaseBefore", "dieBegin"], }, - audio:'jianan', - forceaudio:true, - filter:function(event,player,name){ - if(name!='phaseZhunbeiBegin') return get.is.jun(player)&&player.identity=='wei'; - return this.filter2.apply(this,arguments); + audio: "jianan", + forceaudio: true, + filter: function (event, player, name) { + if (name != "phaseZhunbeiBegin") return get.is.jun(player) && player.identity == "wei"; + return this.filter2.apply(this, arguments); }, - filter2:function(event,player){ - if(!get.zhu(player,'jianan')) return false; - if(!player.countCards('he')) return false; + filter2: function (event, player) { + if (!get.zhu(player, "jianan")) return false; + if (!player.countCards("he")) return false; return !player.isUnseen(); }, - direct:true, - content:function(){ - 'step 0' - if(event.triggername!='phaseZhunbeiBegin'){ - event.trigger('jiananUpdate'); + direct: true, + content: function () { + "step 0"; + if (event.triggername != "phaseZhunbeiBegin") { + event.trigger("jiananUpdate"); event.finish(); return; } - var skills=['new_retuxi','qiaobian','fakexiaoguo','gzjieyue','new_duanliang']; - game.countPlayer(function(current){ - if(current==player) return; - if(current.hasSkill('new_retuxi')) skills.remove('new_retuxi'); - if(current.hasSkill('qiaobian')) skills.remove('qiaobian'); - if(current.hasSkill('fakexiaoguo')) skills.remove('fakexiaoguo'); - if(current.hasSkill('gzjieyue')) skills.remove('gzjieyue'); - if(current.hasSkill('new_duanliang')) skills.remove('new_duanliang'); + var skills = ["new_retuxi", "qiaobian", "fakexiaoguo", "gzjieyue", "new_duanliang"]; + game.countPlayer(function (current) { + if (current == player) return; + if (current.hasSkill("new_retuxi")) skills.remove("new_retuxi"); + if (current.hasSkill("qiaobian")) skills.remove("qiaobian"); + if (current.hasSkill("fakexiaoguo")) skills.remove("fakexiaoguo"); + if (current.hasSkill("gzjieyue")) skills.remove("gzjieyue"); + if (current.hasSkill("new_duanliang")) skills.remove("new_duanliang"); }); - if(!skills.length) event.finish(); - else{ - event.skills=skills; - var next=player.chooseToDiscard('he'); - var str=''; - for(var i=0;i1) rank=4; - if(skills.includes('gzjieyue')&&player.countCards('h',function(card){ - return get.value(card)<7; - })>1) rank=5; - if(skills.includes('qiaobian')&&player.countCards('h')>4) rank=6; - if((get.guozhanRank(player.name1,player) 1 + ) + rank = 4; + if ( + skills.includes("gzjieyue") && + player.countCards("h", function (card) { + return get.value(card) < 7; + }) > 1 + ) + rank = 5; + if (skills.includes("qiaobian") && player.countCards("h") > 4) rank = 6; + if ( + (get.guozhanRank(player.name1, player) < rank && !player.isUnseen(0)) || + (get.guozhanRank(player.name2, player) < rank && !player.isUnseen(1)) + ) + return rank + 1 - get.value(card); return -1; }; } - 'step 1' - if(!result.bool) event.finish(); - else{ - var list=["主将","副将"]; - if(player.isUnseen(0)||get.is.jun(player)) list.remove("主将"); - if(player.isUnseen(1)) list.remove("副将"); - if(!list.length) event.goto(3); - else if(list.length<2) event._result={control:list[0]}; - else{ - player.chooseControl(list).set('ai',function(){ - return get.guozhanRank(player.name1,player)3) return 'qiaobian'; - if(skills.includes('gzjieyue')&&player.countCards('h',function(card){ - return get.value(card)<7; - })) return 'gzjieyue'; - if(skills.includes('new_retuxi')) return 'new_retuxi'; - return skills.randomGet(); - }).set("prompt","选择获得其中的一个技能直到君主的回合开始"); - 'step 4' - var link=result.control; - player.addTempSkill(link,"jiananUpdate"); - player.addTempSkill("jianan_eff","jiananUpdate"); - game.log(player,"获得了技能","#g【"+get.translation(result.control)+"】"); + "step 3"; + player + .chooseControl(event.skills) + .set("ai", function () { + var skills = event.skills; + if (skills.includes("qiaobian") && player.countCards("h") > 3) return "qiaobian"; + if ( + skills.includes("gzjieyue") && + player.countCards("h", function (card) { + return get.value(card) < 7; + }) + ) + return "gzjieyue"; + if (skills.includes("new_retuxi")) return "new_retuxi"; + return skills.randomGet(); + }) + .set("prompt", "选择获得其中的一个技能直到君主的回合开始"); + "step 4"; + var link = result.control; + player.addTempSkill(link, "jiananUpdate"); + player.addTempSkill("jianan_eff", "jiananUpdate"); + game.log(player, "获得了技能", "#g【" + get.translation(result.control) + "】"); }, }, - jianan_eff:{ - ai:{nomingzhi:true} + jianan_eff: { + ai: { nomingzhi: true }, }, - huibian:{ - enable:'phaseUse', - audio:2, - usable:1, - filter:function(event,player){ - return game.countPlayer(function(current){ - return current.identity=='wei'; - })>1&&game.hasPlayer(function(current){ - return current.isDamaged()&¤t.identity=='wei'; - }); + huibian: { + enable: "phaseUse", + audio: 2, + usable: 1, + filter: function (event, player) { + return ( + game.countPlayer(function (current) { + return current.identity == "wei"; + }) > 1 && + game.hasPlayer(function (current) { + return current.isDamaged() && current.identity == "wei"; + }) + ); }, - filterTarget:function(card,player,target){ - if(ui.selected.targets.length) return target.isDamaged()&&target.identity=='wei'; - return target.identity=='wei'; + filterTarget: function (card, player, target) { + if (ui.selected.targets.length) return target.isDamaged() && target.identity == "wei"; + return target.identity == "wei"; }, - selectTarget:2, - multitarget:true, - targetprompt:['受到伤害
                        然后摸牌','回复体力'], - content:function(){ - 'step 0' + selectTarget: 2, + multitarget: true, + targetprompt: ["受到伤害
                        然后摸牌", "回复体力"], + content: function () { + "step 0"; targets[0].damage(player); - 'step 1' - if(targets[0].isAlive()) targets[0].draw(2); + "step 1"; + if (targets[0].isAlive()) targets[0].draw(2); targets[1].recover(); }, - ai:{ - threaten:1.2, - order:9, - result:{ - target:function(player,target){ - if(ui.selected.targets.length) return 1; - if(get.damageEffect(target,player,player)>0) return 2; - if(target.hp>2) return 1; - if(target.hp==1) return -1; + ai: { + threaten: 1.2, + order: 9, + result: { + target: function (player, target) { + if (ui.selected.targets.length) return 1; + if (get.damageEffect(target, player, player) > 0) return 2; + if (target.hp > 2) return 1; + if (target.hp == 1) return -1; return 0.1; - } - }, - } - }, - gzzongyu:{ - audio:2, - unique:true, - forceunique:true, - group:['gzzongyu_others','gzzongyu_player'], - ai:{ - threaten:1.2, - }, - subSkill:{ - others:{ - trigger:{global:'equipAfter'}, - direct:true, - filter:function(event,player){ - if(event.player==player||!player.countCards('e',{subtype:['equip3','equip4']})) return false; - return event.card.name=='liulongcanjia'; }, - check:function(event,player){ - if(get.attitude(player,target)<=0) return player.countCards('e',{subtype:['equip4','equip4']})<2; + }, + }, + }, + gzzongyu: { + audio: 2, + unique: true, + forceunique: true, + group: ["gzzongyu_others", "gzzongyu_player"], + ai: { + threaten: 1.2, + }, + subSkill: { + others: { + trigger: { global: "equipAfter" }, + direct: true, + filter: function (event, player) { + if ( + event.player == player || + !player.countCards("e", { subtype: ["equip3", "equip4"] }) + ) + return false; + return event.card.name == "liulongcanjia"; + }, + check: function (event, player) { + if (get.attitude(player, target) <= 0) + return player.countCards("e", { subtype: ["equip4", "equip4"] }) < 2; return true; }, - content:function(){ - 'step 0' - player.chooseBool('是否发动【总御】,与'+get.translation(trigger.player)+'交换装备区内坐骑牌?'); - 'step 1' - if(result.bool){ - player.logSkill('gzzongyu',trigger.player); - event.cards=[player.getCards('e',{subtype:['equip3','equip4']}),trigger.player.getCards('e',{name:'liulongcanjia'})]; - player.lose(event.cards[0],ui.special); - trigger.player.lose(event.cards[1],ui.special); - if(event.cards[0].length) player.$give(event.cards[0],trigger.player); - if(event.cards[1].length) trigger.player.$give(event.cards[1],player); - } - else event.finish(); - 'step 2' - for(var i=0;i0.7; + check: function (event, player) { + if ( + player.countCards("h", function (card) { + return get.value(card) < 7; + }) + ) { + if (player.isUnseen()) return Math.random() > 0.7; return true; } }, - preHidden:true, - content:function(){ - 'step 0' - var choices=[]; - if(game.hasPlayer(function(current){return current.isUnseen()})) choices.push('选择一名未确定势力的角色'); - if(game.hasPlayer(function(current){return current!=player&&!current.isUnseen()})&&player.countCards('h',{type:'basic'})) choices.push('将一张基本牌交给一名已确定势力的角色'); - if(choices.length==1){ - event._result={index:choices[0]=='选择一名未确定势力的角色'?0:1}; - } - else player.chooseControl().set('ai',function(){ - if(choices.length>1){ - var player=_status.event.player; - if(!game.hasPlayer(function(current){ - return !current.isUnseen()&¤t.getEquip('yuxi')||current.hasSkill('gzyongsi')&&!game.hasPlayer(function(current){ - return current.getEquips('yuxi').length>0; - }); - })&&game.hasPlayer(function(current){return current!=player&¤t.isUnseen()})){ - var identity; - for(var i=0;i 1) { + var player = _status.event.player; + if ( + !game.hasPlayer(function (current) { + return ( + (!current.isUnseen() && current.getEquip("yuxi")) || + (current.hasSkill("gzyongsi") && + !game.hasPlayer(function (current) { + return current.getEquips("yuxi").length > 0; + })) + ); + }) && + game.hasPlayer(function (current) { + return current != player && current.isUnseen(); + }) + ) { + var identity; + for (var i = 0; i < game.players; i++) { + if (game.players[i].isMajor()) { + identity = game.players[i].identity; + break; + } + } + } + if ( + !player.isUnseen() && + player.identity != identity && + get.population(player.identity) + 1 >= get.population(identity) + ) + return 0; + return 1; } - } - if(!player.isUnseen()&&player.identity!=identity&&get.population(player.identity)+1>=get.population(identity)) return 0; - return 1; - } - return 0; - }).set('prompt','征辟:请选择一项').set('choiceList',choices); - 'step 1' - if(result.index==0) player.chooseTarget('请选择一名未确定势力的角色',function(card,player,target){ - return target!=player&&target.identity=='unknown' - },true); - else player.chooseCardTarget({ - prompt:'请将一张基本牌交给一名已确定势力的其他角色', - position:'h', - filterCard:function(card){return get.type(card)=='basic'}, - filterTarget:function(card,player,target){ - return target!=player&&target.identity!='unknown'; - }, - ai1:function(card){return 5-get.value(card)}, - ai2:function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); - if(att>0) return 0; - return -(att-1)/target.countCards('h'); - } - }).set('forced',true); - 'step 2' - event.target=result.targets[0]; - player.line(result.targets,'green'); - if(result.cards.length){ - event.cards=result.cards; - player.give(result.cards,result.targets[0]); - } - else{ - player.storage.gzzhengbi_eff1=result.targets[0]; - player.addTempSkill('gzzhengbi_eff1','phaseUseAfter'); + return 0; + }) + .set("prompt", "征辟:请选择一项") + .set("choiceList", choices); + "step 1"; + if (result.index == 0) + player.chooseTarget( + "请选择一名未确定势力的角色", + function (card, player, target) { + return target != player && target.identity == "unknown"; + }, + true + ); + else + player + .chooseCardTarget({ + prompt: "请将一张基本牌交给一名已确定势力的其他角色", + position: "h", + filterCard: function (card) { + return get.type(card) == "basic"; + }, + filterTarget: function (card, player, target) { + return target != player && target.identity != "unknown"; + }, + ai1: function (card) { + return 5 - get.value(card); + }, + ai2: function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + if (att > 0) return 0; + return -(att - 1) / target.countCards("h"); + }, + }) + .set("forced", true); + "step 2"; + event.target = result.targets[0]; + player.line(result.targets, "green"); + if (result.cards.length) { + event.cards = result.cards; + player.give(result.cards, result.targets[0]); + } else { + player.storage.gzzhengbi_eff1 = result.targets[0]; + player.addTempSkill("gzzhengbi_eff1", "phaseUseAfter"); event.finish(); } - 'step 3' - var choices=[]; - if(target.countCards('he',{type:['trick','delay','equip']})) choices.push('一张非基本牌'); - if(target.countCards('h',{type:'basic'})>1) choices.push('两张基本牌'); - if(choices.length) target.chooseControl(choices).set('ai',function(event,player){ - if(choices.length>1){ - if(player.countCards('he',{type:['trick','delay','equip']},function(card){return get.value(card)<7})) return 0; - return 1; - } - return 0; - }).set('prompt','征辟:交给'+get.translation(player)+'…
                      • '); - else{ - if(target.countCards('h')){ - var cards=target.getCards('h'); - target.give(cards,player); + "step 3"; + var choices = []; + if (target.countCards("he", { type: ["trick", "delay", "equip"] })) + choices.push("一张非基本牌"); + if (target.countCards("h", { type: "basic" }) > 1) choices.push("两张基本牌"); + if (choices.length) + target + .chooseControl(choices) + .set("ai", function (event, player) { + if (choices.length > 1) { + if ( + player.countCards( + "he", + { type: ["trick", "delay", "equip"] }, + function (card) { + return get.value(card) < 7; + } + ) + ) + return 0; + return 1; + } + return 0; + }) + .set("prompt", "征辟:交给" + get.translation(player) + "…
                        "); + else { + if (target.countCards("h")) { + var cards = target.getCards("h"); + target.give(cards, player); event.finish(); - } - else event.finish(); + } else event.finish(); } - 'step 4' - var check=(result.control=='一张非基本牌'); - target.chooseCard('he',(check?1:2),{type:(check?['trick','delay','equip']:'basic')},true); - 'step 5' - if(result.cards){ - target.give(result.cards,player); + "step 4"; + var check = result.control == "一张非基本牌"; + target.chooseCard( + "he", + check ? 1 : 2, + { type: check ? ["trick", "delay", "equip"] : "basic" }, + true + ); + "step 5"; + if (result.cards) { + target.give(result.cards, player); } }, - subSkill:{ - eff1:{ - audio:'zhengbi', - sub:true, - onremove:true, - trigger:{player:'phaseUseEnd'}, - forced:true, - charlotte:true, - filter:function(event,player){ - var target=player.storage.gzzhengbi_eff1; - return target&&!target.isUnseen()&&target.countGainableCards(player,'he')>0; + subSkill: { + eff1: { + audio: "zhengbi", + sub: true, + onremove: true, + trigger: { player: "phaseUseEnd" }, + forced: true, + charlotte: true, + filter: function (event, player) { + var target = player.storage.gzzhengbi_eff1; + return ( + target && !target.isUnseen() && target.countGainableCards(player, "he") > 0 + ); }, - logTarget:function(event,player){ + logTarget: function (event, player) { return player.storage.gzzhengbi_eff1; }, - content:function(){ - var num=0; - var target=player.storage.gzzhengbi_eff1; - if(target.countGainableCards(player,'h')) num++; - if(target.countGainableCards(player,'e')) num++; - if(num){ - player.gainPlayerCard(target,num,'he',true).set('filterButton',function(button){ - for(var i=0;i0; + gzfengying: { + audio: "fengying", + limited: true, + enable: "phaseUse", + position: "h", + filterCard: true, + selectCard: -1, + filter: function (event, player) { + return !player.storage.gzfengying && player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return target==player; + filterTarget: function (card, player, target) { + return target == player; }, - selectTarget:-1, - discard:false, - lose:false, - content:function(){ - 'step 0' - player.awakenSkill('gzfengying'); - player.storage.gzfengying=true; - player.useCard({name:'xietianzi'},cards,target); - 'step 1' - var list=game.filterPlayer(function(current){ - return current.isFriendOf(player)&¤t.countCards('h')=4) return 0; - for(var i=0;i= 4) return 0; + for (var i = 0; i < cards.length; i++) { + value += Math.max(0, get.value(cards[i], player, "raw")); } - var targets=game.filterPlayer(function(current){return current.isFriendOf(player)&¤t!=player}); - var eff=0; - for(var i=0;i0) return 11-get.value(card); - return 7-get.value(card); - }, - ai2:function(card,player,target){ - var att=get.attitude(player,target); - if(att<0) return -att; - return 1; - } - }).setHiddenSkill('gzjieyue'); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; - player.logSkill('gzjieyue',result.targets); - player.give(result.cards[0],result.targets[0]); + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseCardTarget({ + prompt: get.prompt2("gzjieyue"), + position: "h", + filterCard: true, + filterTarget: function (card, player, target) { + return target.identity != "wei" && target != player; + }, + ai1: function (card, player, target) { + if (get.attitude(player, target) > 0) return 11 - get.value(card); + return 7 - get.value(card); + }, + ai2: function (card, player, target) { + var att = get.attitude(player, target); + if (att < 0) return -att; + return 1; + }, + }) + .setHiddenSkill("gzjieyue"); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + player.logSkill("gzjieyue", result.targets); + player.give(result.cards[0], result.targets[0]); player.chooseJunlingFor(result.targets[0]); - } - else event.finish(); - 'step 2' - event.junling=result.junling; - event.targets=result.targets; - var choiceList=[]; - choiceList.push('执行该军令,然后'+get.translation(player)+'摸一张牌'); - choiceList.push('令'+get.translation(player)+'摸牌阶段额外摸三张牌'); - target.chooseJunlingControl(player,result.junling,result.targets).set('prompt','节钺').set('choiceList',choiceList).set('ai',function(){ - if(get.attitude(target,player)>0) return get.junlingEffect(player,result.junling,target,result.targets,target)>1?0:1; - return get.junlingEffect(player,result.junling,target,result.targets,target)>=-1?0:1; - }); - 'step 3' - if(result.index==0){ - target.carryOutJunling(player,event.junling,targets); + } else event.finish(); + "step 2"; + event.junling = result.junling; + event.targets = result.targets; + var choiceList = []; + choiceList.push("执行该军令,然后" + get.translation(player) + "摸一张牌"); + choiceList.push("令" + get.translation(player) + "摸牌阶段额外摸三张牌"); + target + .chooseJunlingControl(player, result.junling, result.targets) + .set("prompt", "节钺") + .set("choiceList", choiceList) + .set("ai", function () { + if (get.attitude(target, player) > 0) + return get.junlingEffect( + player, + result.junling, + target, + result.targets, + target + ) > 1 + ? 0 + : 1; + return get.junlingEffect( + player, + result.junling, + target, + result.targets, + target + ) >= -1 + ? 0 + : 1; + }); + "step 3"; + if (result.index == 0) { + target.carryOutJunling(player, event.junling, targets); player.draw(); - } - else player.addTempSkill('gzjieyue_eff'); + } else player.addTempSkill("gzjieyue_eff"); }, - ai:{threaten:2}, - subSkill:{ - eff:{ - sub:true, - trigger:{player:'phaseDrawBegin2'}, - filter:function(event,player){ + ai: { threaten: 2 }, + subSkill: { + eff: { + sub: true, + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { return !event.numFixed; }, - forced:true, - popup:false, - content:function(){ - trigger.num+=3; - } - } + forced: true, + popup: false, + content: function () { + trigger.num += 3; + }, + }, }, - audio:['jieyue',2], + audio: ["jieyue", 2], }, - jianglue:{ - limited:true, - audio:2, - enable:'phaseUse', - prepare:function(cards,player){ - var targets=game.filterPlayer(function(current){ - return current.isFriendOf(player)||current.isUnseen(); + jianglue: { + limited: true, + audio: 2, + enable: "phaseUse", + prepare: function (cards, player) { + var targets = game.filterPlayer(function (current) { + return current.isFriendOf(player) || current.isUnseen(); }); - player.line(targets,'fire'); + player.line(targets, "fire"); }, - content:function(){ - 'step 0' - player.awakenSkill('jianglue'); - player.addTempSkill('jianglue_count'); - player.chooseJunlingFor(player).set('prompt','选择一张军令牌,令与你势力相同的其他角色选择是否执行'); - 'step 1' - event.junling=result.junling; - event.targets=result.targets; - event.players=game.filterPlayer(function(current){ - if(current==player) return false; - return current.isFriendOf(player)||(player.identity!='ye'&¤t.isUnseen()); - }).sort(lib.sort.seat); - event.num=0; - event.filterName=function(name){ - return lib.character[name][1]==player.identity&&!get.is.double(name); - } - 'step 2' - if(num3||event.current.countCards('e')>2)) return 1; -return event.junling=='junling5'?1:0;}); - else if((event.filterName(event.current.name1)||event.filterName(event.current.name2))&&event.current.wontYe(player.identity)){ - event.showCharacter=true; - choiceList[0]='明置一张武将牌以'+choiceList[0]; - choiceList[1]='不明置武将牌且'+choiceList[1]; - event.current.chooseJunlingControl(player,event.junling,targets).set('prompt','将略').set('choiceList',choiceList).set('ai',function(){if(event.junling=='junling6'&&(event.current.countCards('h')>3||event.current.countCards('e')>2)) return 1; -return event.junling=='junling5'?1:0;}); - } - else event.current.chooseJunlingControl(player,event.junling,targets).set('prompt','将略').set('controls',['ok']); - } - else event.goto(4); - 'step 3' - event.carry=false; - if(result.index==0&&result.control!='ok'){ - event.carry=true; - if(event.showCharacter){ - var list=[]; - if(event.filterName(event.current.name1)) list.push('主将'); - if(event.filterName(event.current.name2)) list.push('副将'); - if(list.length>1) event.current.chooseControl(['主将','副将']).set('ai',function(){ - if(player.name1=='gz_fazheng') return 0; - if(player.name2=='gz_fazheng') return 1; - return Math.random()>0.5?0:1; - }).prompt='选择并展示一张武将牌,然后执行军令'; - else event._result={index:list[0]=='主将'?0:1}; + content: function () { + "step 0"; + player.awakenSkill("jianglue"); + player.addTempSkill("jianglue_count"); + player + .chooseJunlingFor(player) + .set("prompt", "选择一张军令牌,令与你势力相同的其他角色选择是否执行"); + "step 1"; + event.junling = result.junling; + event.targets = result.targets; + event.players = game + .filterPlayer(function (current) { + if (current == player) return false; + return ( + current.isFriendOf(player) || (player.identity != "ye" && current.isUnseen()) + ); + }) + .sort(lib.sort.seat); + event.num = 0; + event.filterName = function (name) { + return lib.character[name][1] == player.identity && !get.is.double(name); + }; + "step 2"; + if (num < event.players.length) event.current = event.players[num]; + if (event.current && event.current.isAlive()) { + event.showCharacter = false; + var choiceList = ["执行该军令,增加1点体力上限,然后回复1点体力", "不执行该军令"]; + if (event.current.isFriendOf(player)) + event.current + .chooseJunlingControl(player, event.junling, targets) + .set("prompt", "将略") + .set("choiceList", choiceList) + .set("ai", function () { + if ( + event.junling == "junling6" && + (event.current.countCards("h") > 3 || + event.current.countCards("e") > 2) + ) + return 1; + return event.junling == "junling5" ? 1 : 0; + }); + else if ( + (event.filterName(event.current.name1) || + event.filterName(event.current.name2)) && + event.current.wontYe(player.identity) + ) { + event.showCharacter = true; + choiceList[0] = "明置一张武将牌以" + choiceList[0]; + choiceList[1] = "不明置武将牌且" + choiceList[1]; + event.current + .chooseJunlingControl(player, event.junling, targets) + .set("prompt", "将略") + .set("choiceList", choiceList) + .set("ai", function () { + if ( + event.junling == "junling6" && + (event.current.countCards("h") > 3 || + event.current.countCards("e") > 2) + ) + return 1; + return event.junling == "junling5" ? 1 : 0; + }); + } else + event.current + .chooseJunlingControl(player, event.junling, targets) + .set("prompt", "将略") + .set("controls", ["ok"]); + } else event.goto(4); + "step 3"; + event.carry = false; + if (result.index == 0 && result.control != "ok") { + event.carry = true; + if (event.showCharacter) { + var list = []; + if (event.filterName(event.current.name1)) list.push("主将"); + if (event.filterName(event.current.name2)) list.push("副将"); + if (list.length > 1) + event.current.chooseControl(["主将", "副将"]).set("ai", function () { + if (player.name1 == "gz_fazheng") return 0; + if (player.name2 == "gz_fazheng") return 1; + return Math.random() > 0.5 ? 0 : 1; + }).prompt = "选择并展示一张武将牌,然后执行军令"; + else event._result = { index: list[0] == "主将" ? 0 : 1 }; } } - 'step 4' - if(!event.list) event.list=[player]; - if(event.carry){ - if(event.showCharacter) event.current.showCharacter(result.index); - event.current.carryOutJunling(player,event.junling,targets); + "step 4"; + if (!event.list) event.list = [player]; + if (event.carry) { + if (event.showCharacter) event.current.showCharacter(result.index); + event.current.carryOutJunling(player, event.junling, targets); event.list.push(event.current); } event.num++; - if(event.num0) player.draw(player.storage.jianglue_count); + "step 7"; + if (event.num < event.list.length) event.goto(6); + else if (player.storage.jianglue_count > 0) player.draw(player.storage.jianglue_count); }, - marktext:'略', - skillAnimation:'epic', - animationColor:'soil', - ai:{ - order:10, - result:{ - player:function(player){ - if(player.isUnseen()&&player.wontYe()){ - if(get.population(player.group)>=game.players.length/4) return 1; - return Math.random()>0.7?1:0; - } - else return 1; - } - } + marktext: "略", + skillAnimation: "epic", + animationColor: "soil", + ai: { + order: 10, + result: { + player: function (player) { + if (player.isUnseen() && player.wontYe()) { + if (get.population(player.group) >= game.players.length / 4) return 1; + return Math.random() > 0.7 ? 1 : 0; + } else return 1; + }, + }, + }, + subSkill: { + count: { + sub: true, + trigger: { global: "recoverAfter" }, + silent: true, + filter: function (event) { + return event.getParent("jianglue"); + }, + content: function () { + player.storage.jianglue_count++; + }, + }, }, - subSkill:{ - count:{ - sub:true, - trigger:{global:'recoverAfter'}, - silent:true, - filter:function(event){return event.getParent('jianglue')}, - content:function(){player.storage.jianglue_count++} - } - } }, - gzxuanhuo:{ - audio:'rexuanhuo', - global:'gzxuanhuo_others', - derivation:['fz_new_rewusheng','fz_gzpaoxiao','fz_new_longdan','fz_new_tieji','fz_liegong','fz_xinkuanggu'], - ai:{ - threaten:function(player,target){ - if(game.hasPlayer(function(current){ - return current!=target&¤t.isFriendOf(target); - })) return 1.5; + gzxuanhuo: { + audio: "rexuanhuo", + global: "gzxuanhuo_others", + derivation: [ + "fz_new_rewusheng", + "fz_gzpaoxiao", + "fz_new_longdan", + "fz_new_tieji", + "fz_liegong", + "fz_xinkuanggu", + ], + ai: { + threaten: function (player, target) { + if ( + game.hasPlayer(function (current) { + return current != target && current.isFriendOf(target); + }) + ) + return 1.5; return 0.5; }, }, - subSkill:{ - others:{ - audio:'rexuanhuo', - forceaudio:true, - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return (!player.isUnseen())&&player.countCards('h')>0&&game.hasPlayer(function(current){ - return current!=player&¤t.hasSkill('gzxuanhuo')&&player.isFriendOf(current); - }); + subSkill: { + others: { + audio: "rexuanhuo", + forceaudio: true, + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return ( + !player.isUnseen() && + player.countCards("h") > 0 && + game.hasPlayer(function (current) { + return ( + current != player && + current.hasSkill("gzxuanhuo") && + player.isFriendOf(current) + ); + }) + ); }, - prompt:'弃置一张手牌,然后获得以下技能中的一个:〖武圣〗〖咆哮〗〖龙胆〗〖铁骑〗〖烈弓〗〖狂骨〗', - position:'h', - filterCard:true, - check:function(card){ - var player=_status.event.player; - if(player.hasSkill('gzpaoxiao',true)||player.getEquip('zhuge')) return 0; - if(player.countCards('h',function(cardx){ - return cardx!=card&&cardx.name=='sha'&&player.hasUseTarget(cardx); - })<(player.getCardUsable('sha')+1)) return 0; - return 7-get.value(card); + prompt: "弃置一张手牌,然后获得以下技能中的一个:〖武圣〗〖咆哮〗〖龙胆〗〖铁骑〗〖烈弓〗〖狂骨〗", + position: "h", + filterCard: true, + check: function (card) { + var player = _status.event.player; + if (player.hasSkill("gzpaoxiao", true) || player.getEquip("zhuge")) return 0; + if ( + player.countCards("h", function (cardx) { + return cardx != card && cardx.name == "sha" && player.hasUseTarget(cardx); + }) < + player.getCardUsable("sha") + 1 + ) + return 0; + return 7 - get.value(card); }, - content:function(){ - 'step 0' - var list=['new_rewusheng','gzpaoxiao','new_longdan','new_tieji','liegong','xinkuanggu']; - player.chooseControl(list).set('ai',function(){ - if(list.includes('gzpaoxiao')) return 'gzpaoxiao'; - return list.randomGet(); - }).set('prompt','选择并获得一项技能直到回合结束'); - 'step 1' + content: function () { + "step 0"; + var list = [ + "new_rewusheng", + "gzpaoxiao", + "new_longdan", + "new_tieji", + "liegong", + "xinkuanggu", + ]; + player + .chooseControl(list) + .set("ai", function () { + if (list.includes("gzpaoxiao")) return "gzpaoxiao"; + return list.randomGet(); + }) + .set("prompt", "选择并获得一项技能直到回合结束"); + "step 1"; player.popup(result.control); - player.addTempSkill('fz_'+result.control); - game.log(player,'获得了技能','#g【'+get.translation(result.control)+'】'); + player.addTempSkill("fz_" + result.control); + game.log(player, "获得了技能", "#g【" + get.translation(result.control) + "】"); game.delay(); }, // forceaudio:true, // audio:['xuanhuo',2], - ai:{ - order:8, - result:{player:1}, + ai: { + order: 8, + result: { player: 1 }, }, }, //used:{}, }, // audio:['xuanhuo',2], }, - fz_gzpaoxiao:{ - audio:true, - inherit:'gzpaoxiao', + fz_gzpaoxiao: { + audio: true, + inherit: "gzpaoxiao", }, - fz_new_tieji:{ - audio:true, - inherit:'new_tieji', + fz_new_tieji: { + audio: true, + inherit: "new_tieji", }, - fz_new_rewusheng:{ - audio:true, - inherit:'new_rewusheng', + fz_new_rewusheng: { + audio: true, + inherit: "new_rewusheng", }, - fz_liegong:{ - audio:true, - inherit:'liegong', + fz_liegong: { + audio: true, + inherit: "liegong", }, - fz_xinkuanggu:{ - audio:true, - inherit:'xinkuanggu', + fz_xinkuanggu: { + audio: true, + inherit: "xinkuanggu", }, - fz_new_longdan:{ - audio:true, - group:["fz_new_longdan_sha","fz_new_longdan_shan","fz_new_longdan_draw","fz_new_longdan_shamiss","fz_new_longdan_shanafter"], - subSkill:{ - shanafter:{ - sub:true, - audio:"fz_new_longdan", - trigger:{ - player:"useCard", + fz_new_longdan: { + audio: true, + group: [ + "fz_new_longdan_sha", + "fz_new_longdan_shan", + "fz_new_longdan_draw", + "fz_new_longdan_shamiss", + "fz_new_longdan_shanafter", + ], + subSkill: { + shanafter: { + sub: true, + audio: "fz_new_longdan", + trigger: { + player: "useCard", }, //priority:1, - filter:function(event,player){ - return event.skill=='fz_new_longdan_shan'&&event.getParent(2).name=='sha'; + filter: function (event, player) { + return event.skill == "fz_new_longdan_shan" && event.getParent(2).name == "sha"; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget("是否发动【龙胆】令一名其他角色回复1点体力?",function(card,player,target){ - return target!=_status.event.source&&target!=player&&target.isDamaged(); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('source',trigger.getParent(2).player); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('fz_new_longdan',result.targets[0]); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + "是否发动【龙胆】令一名其他角色回复1点体力?", + function (card, player, target) { + return ( + target != _status.event.source && + target != player && + target.isDamaged() + ); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("source", trigger.getParent(2).player); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("fz_new_longdan", result.targets[0]); result.targets[0].recover(); } }, }, - shamiss:{ - sub:true, - audio:"fz_new_longdan", - trigger:{ - player:"shaMiss", + shamiss: { + sub: true, + audio: "fz_new_longdan", + trigger: { + player: "shaMiss", }, - direct:true, - filter:function(event,player){ - return event.skill=='fz_new_longdan_sha'; + direct: true, + filter: function (event, player) { + return event.skill == "fz_new_longdan_sha"; }, - content:function(){ - "step 0" - player.chooseTarget("是否发动【龙胆】对一名其他角色造成1点伤害?",function(card,player,target){ - return target!=_status.event.target&&target!=player; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }).set('target',trigger.target); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('fz_new_longdan',result.targets[0]); + content: function () { + "step 0"; + player + .chooseTarget( + "是否发动【龙胆】对一名其他角色造成1点伤害?", + function (card, player, target) { + return target != _status.event.target && target != player; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }) + .set("target", trigger.target); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("fz_new_longdan", result.targets[0]); result.targets[0].damage(); } }, }, - draw:{ - trigger:{ - player:["useCard","respond"], + draw: { + trigger: { + player: ["useCard", "respond"], }, - audio:"fz_new_longdan", - forced:true, - locked:false, - filter:function(event,player){ - if(!get.zhu(player,'shouyue')) return false; - return event.skill=='fz_new_longdan_sha'||event.skill=='fz_new_longdan_shan'; + audio: "fz_new_longdan", + forced: true, + locked: false, + filter: function (event, player) { + if (!get.zhu(player, "shouyue")) return false; + return ( + event.skill == "fz_new_longdan_sha" || event.skill == "fz_new_longdan_shan" + ); }, - content:function(){ + content: function () { player.draw(); //player.storage.fanghun2++; }, - sub:true, + sub: true, }, - sha:{ - audio:"fz_new_longdan", - enable:["chooseToUse","chooseToRespond"], - filterCard:{ - name:"shan", + sha: { + audio: "fz_new_longdan", + enable: ["chooseToUse", "chooseToRespond"], + filterCard: { + name: "shan", }, - viewAs:{ - name:"sha", + viewAs: { + name: "sha", }, - viewAsFilter:function(player){ - if(!player.countCards('hs','shan')) return false; + viewAsFilter: function (player) { + if (!player.countCards("hs", "shan")) return false; }, - prompt:"将一张闪当杀使用或打出", - position:'hs', - check:function(){return 1}, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.6 + prompt: "将一张闪当杀使用或打出", + position: "hs", + check: function () { + return 1; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.6; }, }, - respondSha:true, - skillTagFilter:function(player){ - if(!player.countCards('hs','shan')) return false; + respondSha: true, + skillTagFilter: function (player) { + if (!player.countCards("hs", "shan")) return false; }, - order:function(){ - return get.order({name:'sha'})+0.1; + order: function () { + return get.order({ name: "sha" }) + 0.1; }, }, - sub:true, + sub: true, }, - shan:{ - audio:"fz_new_longdan", - enable:['chooseToRespond','chooseToUse'], - filterCard:{ - name:"sha", + shan: { + audio: "fz_new_longdan", + enable: ["chooseToRespond", "chooseToUse"], + filterCard: { + name: "sha", }, - viewAs:{ - name:"shan", + viewAs: { + name: "shan", }, - position:'hs', - prompt:"将一张杀当闪使用或打出", - check:function(){return 1}, - viewAsFilter:function(player){ - if(!player.countCards('hs','sha')) return false; + position: "hs", + prompt: "将一张杀当闪使用或打出", + check: function () { + return 1; }, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hs','sha')) return false; + viewAsFilter: function (player) { + if (!player.countCards("hs", "sha")) return false; + }, + ai: { + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hs", "sha")) return false; }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.6 + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.6; }, }, }, - sub:true, + sub: true, }, }, }, - gzenyuan:{ - locked:true, - audio:'reenyuan', - group:['gzenyuan_gain','gzenyuan_damage'], - preHidden:true, - ai:{ - maixie_defend:true, - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-1.5]; - if(!target.hasFriend()) return; - if(get.tag(card,'damage')) return [1,0,0,-0.7]; - } - } + gzenyuan: { + locked: true, + audio: "reenyuan", + group: ["gzenyuan_gain", "gzenyuan_damage"], + preHidden: true, + ai: { + maixie_defend: true, + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -1.5]; + if (!target.hasFriend()) return; + if (get.tag(card, "damage")) return [1, 0, 0, -0.7]; + }, + }, }, - subSkill:{ - gain:{ - audio:'reenyuan', - trigger:{target:'useCardToTargeted'}, - forced:true, - filter:function(event,player){ - return event.card.name=='tao'&&event.player!=player; + subSkill: { + gain: { + audio: "reenyuan", + trigger: { target: "useCardToTargeted" }, + forced: true, + filter: function (event, player) { + return event.card.name == "tao" && event.player != player; }, - logTarget:'player', - content:function(){trigger.player.draw()}, - }, - damage:{ - audio:'reenyuan', - trigger:{player:'damageEnd'}, - forced:true, - filter:function(event,player){ - return event.source&&event.source!=player&&event.num>0; - }, - content:function(){ - 'step 0' - player.logSkill('enyuan_damage',trigger.source); - trigger.source.chooseCard('交给'+get.translation(player)+'一张手牌,或失去1点体力','h').set('ai',function(card){ - if(get.attitude(_status.event.player,_status.event.getParent().player)>0) return 11-get.value(card); - return 7-get.value(card); - }); - 'step 1' - if(result.bool){ - trigger.source.give(result.cards[0],player,'giveAuto'); - } - else trigger.source.loseHp(); + logTarget: "player", + content: function () { + trigger.player.draw(); }, }, - } + damage: { + audio: "reenyuan", + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return event.source && event.source != player && event.num > 0; + }, + content: function () { + "step 0"; + player.logSkill("enyuan_damage", trigger.source); + trigger.source + .chooseCard("交给" + get.translation(player) + "一张手牌,或失去1点体力", "h") + .set("ai", function (card) { + if ( + get.attitude(_status.event.player, _status.event.getParent().player) > + 0 + ) + return 11 - get.value(card); + return 7 - get.value(card); + }); + "step 1"; + if (result.bool) { + trigger.source.give(result.cards[0], player, "giveAuto"); + } else trigger.source.loseHp(); + }, + }, + }, }, - gzjushou:{ - audio:"xinjushou", - trigger:{ - player:"phaseJieshuBegin", + gzjushou: { + audio: "xinjushou", + trigger: { + player: "phaseJieshuBegin", }, - preHidden:true, - content:function(){ - 'step 0' - var list=[],players=game.filterPlayer(); - for(var target of players){ - if(target.isUnseen()) continue; - var add=true; - for(var i of list){ - if(i.isFriendOf(target)){ - add=false; + preHidden: true, + content: function () { + "step 0"; + var list = [], + players = game.filterPlayer(); + for (var target of players) { + if (target.isUnseen()) continue; + var add = true; + for (var i of list) { + if (i.isFriendOf(target)) { + add = false; break; } } - if(add) list.add(target); + if (add) list.add(target); } - event.num=list.length; + event.num = list.length; player.draw(event.num); - if(event.num>2) player.turnOver(); - 'step 1' - player.chooseCard('h',true,'弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之').set('ai',function(card){ - if(get.type(card)=='equip'){ - return 5-get.value(card); - } - return -get.value(card); - }).set('filterCard',lib.filter.cardDiscardable); - 'step 2' - if(result.bool&&result.cards.length){ - if(get.type(result.cards[0])=='equip'&&player.hasUseTarget(result.cards[0])){ - player.chooseUseTarget(result.cards[0],true,'nopopup'); - } - else{ + if (event.num > 2) player.turnOver(); + "step 1"; + player + .chooseCard("h", true, "弃置一张手牌,若以此法弃置的是装备牌,则你改为使用之") + .set("ai", function (card) { + if (get.type(card) == "equip") { + return 5 - get.value(card); + } + return -get.value(card); + }) + .set("filterCard", lib.filter.cardDiscardable); + "step 2"; + if (result.bool && result.cards.length) { + if (get.type(result.cards[0]) == "equip" && player.hasUseTarget(result.cards[0])) { + player.chooseUseTarget(result.cards[0], true, "nopopup"); + } else { player.discard(result.cards[0]); } } }, - ai:{ - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,1]; + ai: { + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 1]; }, }, }, }, - "new_duanliang":{ - subSkill:{ - off:{ - sub:true, + new_duanliang: { + subSkill: { + off: { + sub: true, }, }, - mod:{ - targetInRange:function(card,player,target){ - if(card.name=='bingliang'){ + mod: { + targetInRange: function (card, player, target) { + if (card.name == "bingliang") { return true; } }, }, - locked:false, - audio:"duanliang1", - enable:"chooseToUse", - filterCard:function(card){ - if(get.type(card)!='basic'&&get.type(card)!='equip') return false; - return get.color(card)=='black'; + locked: false, + audio: "duanliang1", + enable: "chooseToUse", + filterCard: function (card) { + if (get.type(card) != "basic" && get.type(card) != "equip") return false; + return get.color(card) == "black"; }, - filter:function(event,player){ - if(player.hasSkill('new_duanliang_off')) return false; - return player.countCards('hes',{type:['basic','equip'],color:'black'}) + filter: function (event, player) { + if (player.hasSkill("new_duanliang_off")) return false; + return player.countCards("hes", { type: ["basic", "equip"], color: "black" }); }, - position:"hes", - viewAs:{ - name:"bingliang", + position: "hes", + viewAs: { + name: "bingliang", }, - onuse:function(result,player){ - if(get.distance(player,result.targets[0])>2) player.addTempSkill('new_duanliang_off'); + onuse: function (result, player) { + if (get.distance(player, result.targets[0]) > 2) player.addTempSkill("new_duanliang_off"); }, - prompt:"将一黑色的基本牌或装备牌当兵粮寸断使用", - check:function(card){return 6-get.value(card)}, - ai:{ - order:9, - basic:{ - order:1, - useful:1, - value:4, + prompt: "将一黑色的基本牌或装备牌当兵粮寸断使用", + check: function (card) { + return 6 - get.value(card); + }, + ai: { + order: 9, + basic: { + order: 1, + useful: 1, + value: 4, }, - result:{ - target:function(player,target){ - if(target.hasJudge('caomu')) return 0; - return -1.5/Math.sqrt(target.countCards('h')+1); + result: { + target: function (player, target) { + if (target.hasJudge("caomu")) return 0; + return -1.5 / Math.sqrt(target.countCards("h") + 1); }, }, - tag:{ - skip:"phaseDraw", + tag: { + skip: "phaseDraw", }, }, }, - new_shushen:{ - audio:"shushen", - trigger:{ - player:"recoverAfter", + new_shushen: { + audio: "shushen", + trigger: { + player: "recoverAfter", }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - event.num=trigger.num||1; - "step 1" - player.chooseTarget(get.prompt2('new_shushen'),function(card,player,target){ - return target!=player; - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).setHiddenSkill('new_shushen'); - "step 2" - if(result.bool){ - player.logSkill('new_shushen',result.targets); + direct: true, + preHidden: true, + content: function () { + "step 0"; + event.num = trigger.num || 1; + "step 1"; + player + .chooseTarget(get.prompt2("new_shushen"), function (card, player, target) { + return target != player; + }) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .setHiddenSkill("new_shushen"); + "step 2"; + if (result.bool) { + player.logSkill("new_shushen", result.targets); result.targets[0].draw(); - if(event.num>1){ + if (event.num > 1) { event.num--; event.goto(1); } } }, - ai:{ - threaten:0.8, - expose:0.1, + ai: { + threaten: 0.8, + expose: 0.1, }, }, - "new_luanji":{ - audio:"luanji", - enable:"phaseUse", - viewAs:{ - name:"wanjian", + new_luanji: { + audio: "luanji", + enable: "phaseUse", + viewAs: { + name: "wanjian", }, - filterCard:function(card,player){ - if(!player.storage.new_luanji) return true; + filterCard: function (card, player) { + if (!player.storage.new_luanji) return true; return !player.storage.new_luanji.includes(get.suit(card)); }, - selectCard:2, - position:'hs', - filter:function(event,player){ - return player.countCards('hs',function(card){ - return !player.storage.new_luanji||!player.storage.new_luanji.includes(get.suit(card)); - })>1; + selectCard: 2, + position: "hs", + filter: function (event, player) { + return ( + player.countCards("hs", function (card) { + return ( + !player.storage.new_luanji || + !player.storage.new_luanji.includes(get.suit(card)) + ); + }) > 1 + ); }, - check:function(card){ - var player=_status.event.player; - var targets=game.filterPlayer(function(current){ - return player.canUse('wanjian',current); + check: function (card) { + var player = _status.event.player; + var targets = game.filterPlayer(function (current) { + return player.canUse("wanjian", current); }); - var num=0; - for(var i=0;i=7){ - if(num<2) return 0; - } - else if(targets.length>=5){ - if(num<1.5) return 0; + if (!player.needsToDiscard(-1)) { + if (targets.length >= 7) { + if (num < 2) return 0; + } else if (targets.length >= 5) { + if (num < 1.5) return 0; } } - return 6-get.value(card); + return 6 - get.value(card); }, - group:["new_luanji_count","new_luanji_reset","new_luanji_respond"], - subSkill:{ - reset:{ - trigger:{ - player:"phaseAfter", + group: ["new_luanji_count", "new_luanji_reset", "new_luanji_respond"], + subSkill: { + reset: { + trigger: { + player: "phaseAfter", }, - silent:true, - filter:function(event,player){ - return player.storage.new_luanji?true:false; + silent: true, + filter: function (event, player) { + return player.storage.new_luanji ? true : false; }, - content:function(){ + content: function () { delete player.storage.new_luanji; }, - sub:true, - forced:true, - popup:false, + sub: true, + forced: true, + popup: false, }, - count:{ - trigger:{ - player:"useCard", + count: { + trigger: { + player: "useCard", }, - silent:true, - filter:function(event){ - return event.skill=='new_luanji'; + silent: true, + filter: function (event) { + return event.skill == "new_luanji"; }, - content:function(){ - if(!player.storage.new_luanji){ - player.storage.new_luanji=[]; + content: function () { + if (!player.storage.new_luanji) { + player.storage.new_luanji = []; } - for(var i=0;i=0) return 0; - if(player.hasCard(function(card){ - return get.tag(card,'damage')&&player.canUse(card,target,true,true); - })){ - if(target.maxHp>3) return -0.5; + ai: { + order: 8, + result: { + target: function (player, target) { + if (target.hp <= 0) return -5; + if (player.getStat().skill.new_qingcheng) return 0; + if (!target.hasSkillTag("maixie")) return 0; + if (get.attitude(player, target) >= 0) return 0; + if ( + player.hasCard(function (card) { + return get.tag(card, "damage") && player.canUse(card, target, true, true); + }) + ) { + if (target.maxHp > 3) return -0.5; return -1; } return 0; @@ -13031,4061 +17100,4724 @@ return event.junling=='junling5'?1:0;}); }, }, }, - new_kongcheng:{ - group:["new_kongcheng_gain","new_kongcheng_got"], - subSkill:{ - gain:{ - audio:"kongcheng", - trigger:{ - player:"gainBefore", + new_kongcheng: { + group: ["new_kongcheng_gain", "new_kongcheng_got"], + subSkill: { + gain: { + audio: "kongcheng", + trigger: { + player: "gainBefore", }, - filter:function(event,player){ - return event.source&&event.source!=player&&player!=_status.currentPhase&&!event.bySelf&&player.countCards('h')==0; + filter: function (event, player) { + return ( + event.source && + event.source != player && + player != _status.currentPhase && + !event.bySelf && + player.countCards("h") == 0 + ); }, - content:function(){ - trigger.name='addToExpansion'; - trigger.setContent('addToExpansion'); - trigger.gaintag=['new_kongcheng']; + content: function () { + trigger.name = "addToExpansion"; + trigger.setContent("addToExpansion"); + trigger.gaintag = ["new_kongcheng"]; trigger.untrigger(); - trigger.trigger('addToExpansionBefore'); + trigger.trigger("addToExpansionBefore"); }, - sub:true, - forced:true, + sub: true, + forced: true, }, - got:{ - trigger:{ - player:"phaseDrawBegin1", + got: { + trigger: { + player: "phaseDrawBegin1", }, - filter:function(event,player){ - return player.getExpansions('new_kongcheng').length>0; + filter: function (event, player) { + return player.getExpansions("new_kongcheng").length > 0; }, - content:function(){ - player.gain(player.getExpansions('new_kongcheng'),'draw'); + content: function () { + player.gain(player.getExpansions("new_kongcheng"), "draw"); }, - sub:true, - forced:true, + sub: true, + forced: true, }, }, - audio:"kongcheng", - trigger:{ - target:"useCardToTarget", + audio: "kongcheng", + trigger: { + target: "useCardToTarget", }, - forced:true, - check:function(event,player){ - return get.effect(event.target,event.card,event.player,player)<0; + forced: true, + check: function (event, player) { + return get.effect(event.target, event.card, event.player, player) < 0; }, - filter:function(event,player){ - return player.countCards('h')==0&&(event.card.name=='sha'||event.card.name=='juedou'); + filter: function (event, player) { + return ( + player.countCards("h") == 0 && + (event.card.name == "sha" || event.card.name == "juedou") + ); }, - content:function(){ + content: function () { trigger.getParent().targets.remove(player); }, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(target.countCards('h')==0&&(card.name=='sha'||card.name=='juedou')) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target, current) { + if (target.countCards("h") == 0 && (card.name == "sha" || card.name == "juedou")) + return "zeroplayertarget"; }, }, }, - intro:{ - markcount:'expansion', - mark:function(dialog,content,player){ - var content=player.getExpansions('new_kongcheng'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + intro: { + markcount: "expansion", + mark: function (dialog, content, player) { + var content = player.getExpansions("new_kongcheng"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { dialog.addAuto(content); - } - else{ - return '共有'+get.cnNumber(content.length)+'张牌'; + } else { + return "共有" + get.cnNumber(content.length) + "张牌"; } } }, - content:function(content,player){ - var content=player.getExpansions('new_kongcheng'); - if(content&&content.length){ - if(player==game.me||player.isUnderControl()){ + content: function (content, player) { + var content = player.getExpansions("new_kongcheng"); + if (content && content.length) { + if (player == game.me || player.isUnderControl()) { return get.translation(content); } - return '共有'+get.cnNumber(content.length)+'张牌'; + return "共有" + get.cnNumber(content.length) + "张牌"; } }, }, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); }, }, - "new_keji":{ - audio:"keji", - forced:true, - trigger:{ - player:"phaseDiscardBegin", + new_keji: { + audio: "keji", + forced: true, + trigger: { + player: "phaseDiscardBegin", }, - filter:function(event,player){ - var list=[]; - player.getHistory('useCard',function(evt){ - if(evt.isPhaseUsing(player)){ - var color=get.color(evt.card); - if(color!='nocolor') list.add(color); + filter: function (event, player) { + var list = []; + player.getHistory("useCard", function (evt) { + if (evt.isPhaseUsing(player)) { + var color = get.color(evt.card); + if (color != "nocolor") list.add(color); } }); - return list.length<=1; + return list.length <= 1; }, - check:function(event,player){ + check: function (event, player) { return player.needsToDiscard(); }, - content:function(){ - player.addTempSkill('keji_add','phaseAfter'); + content: function () { + player.addTempSkill("keji_add", "phaseAfter"); }, }, - "keji_add":{ - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+4; + keji_add: { + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + 4; }, }, }, - "new_mouduan":{ - trigger:{ - player:"phaseJieshuBegin", + new_mouduan: { + trigger: { + player: "phaseJieshuBegin", }, //priority:2, - audio:"botu", - filter:function(event,player){ - var history=player.getHistory('useCard'); - var suits=[]; - var types=[]; - for(var i=0;i=4||types.length>=3; + return suits.length >= 4 || types.length >= 3; }, - check:function(event,player){ + check: function (event, player) { return player.canMoveCard(true); }, - content:function(){ + content: function () { player.moveCard(); }, }, - "new_longdan":{ - group:["new_longdan_sha","new_longdan_shan","new_longdan_draw","new_longdan_shamiss","new_longdan_shanafter"], - subSkill:{ - shanafter:{ - sub:true, - audio:"longdan_sha", - trigger:{ - player:"useCard", + new_longdan: { + group: [ + "new_longdan_sha", + "new_longdan_shan", + "new_longdan_draw", + "new_longdan_shamiss", + "new_longdan_shanafter", + ], + subSkill: { + shanafter: { + sub: true, + audio: "longdan_sha", + trigger: { + player: "useCard", }, //priority:1, - filter:function(event,player){ - return event.skill=='new_longdan_shan'&&event.getParent(2).name=='sha'; + filter: function (event, player) { + return event.skill == "new_longdan_shan" && event.getParent(2).name == "sha"; }, - direct:true, - content:function(){ - "step 0" - player.chooseTarget("是否发动【龙胆】令一名其他角色回复1点体力?",function(card,player,target){ - return target!=_status.event.source&&target!=player&&target.isDamaged(); - }).set('ai',function(target){ - return get.attitude(_status.event.player,target); - }).set('source',trigger.getParent(2).player); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('new_longdan',result.targets[0]); + direct: true, + content: function () { + "step 0"; + player + .chooseTarget( + "是否发动【龙胆】令一名其他角色回复1点体力?", + function (card, player, target) { + return ( + target != _status.event.source && + target != player && + target.isDamaged() + ); + } + ) + .set("ai", function (target) { + return get.attitude(_status.event.player, target); + }) + .set("source", trigger.getParent(2).player); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("new_longdan", result.targets[0]); result.targets[0].recover(); } }, }, - shamiss:{ - sub:true, - audio:"longdan_sha", - trigger:{ - player:"shaMiss", + shamiss: { + sub: true, + audio: "longdan_sha", + trigger: { + player: "shaMiss", }, - direct:true, - filter:function(event,player){ - return event.skill=='new_longdan_sha'; + direct: true, + filter: function (event, player) { + return event.skill == "new_longdan_sha"; }, - content:function(){ - "step 0" - player.chooseTarget("是否发动【龙胆】对一名其他角色造成1点伤害?",function(card,player,target){ - return target!=_status.event.target&&target!=player; - }).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }).set('target',trigger.target); - "step 1" - if(result.bool&&result.targets&&result.targets.length){ - player.logSkill('new_longdan',result.targets[0]); + content: function () { + "step 0"; + player + .chooseTarget( + "是否发动【龙胆】对一名其他角色造成1点伤害?", + function (card, player, target) { + return target != _status.event.target && target != player; + } + ) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }) + .set("target", trigger.target); + "step 1"; + if (result.bool && result.targets && result.targets.length) { + player.logSkill("new_longdan", result.targets[0]); result.targets[0].damage(); } }, }, - draw:{ - trigger:{ - player:["useCard","respond"], + draw: { + trigger: { + player: ["useCard", "respond"], }, - audio:"longdan_sha", - forced:true, - locked:false, - filter:function(event,player){ - if(!get.zhu(player,'shouyue')) return false; - return event.skill=='new_longdan_sha'||event.skill=='new_longdan_shan'; + audio: "longdan_sha", + forced: true, + locked: false, + filter: function (event, player) { + if (!get.zhu(player, "shouyue")) return false; + return event.skill == "new_longdan_sha" || event.skill == "new_longdan_shan"; }, - content:function(){ + content: function () { player.draw(); //player.storage.fanghun2++; }, - sub:true, + sub: true, }, - sha:{ - audio:"longdan_sha", - enable:["chooseToUse","chooseToRespond"], - filterCard:{ - name:"shan", + sha: { + audio: "longdan_sha", + enable: ["chooseToUse", "chooseToRespond"], + filterCard: { + name: "shan", }, - viewAs:{ - name:"sha", + viewAs: { + name: "sha", }, - position:'hs', - viewAsFilter:function(player){ - if(!player.countCards('hs','shan')) return false; + position: "hs", + viewAsFilter: function (player) { + if (!player.countCards("hs", "shan")) return false; }, - prompt:"将一张闪当杀使用或打出", - check:function(){return 1}, - ai:{ - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondSha')&¤t<0) return 0.6 + prompt: "将一张闪当杀使用或打出", + check: function () { + return 1; + }, + ai: { + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondSha") && current < 0) return 0.6; }, }, - respondSha:true, - skillTagFilter:function(player){ - if(!player.countCards('hs','shan')) return false; + respondSha: true, + skillTagFilter: function (player) { + if (!player.countCards("hs", "shan")) return false; }, - order:function(){ - return get.order({name:'sha'})+0.1; + order: function () { + return get.order({ name: "sha" }) + 0.1; }, }, - sub:true, + sub: true, }, - shan:{ - audio:"longdan_sha", - enable:['chooseToRespond','chooseToUse'], - filterCard:{ - name:"sha", + shan: { + audio: "longdan_sha", + enable: ["chooseToRespond", "chooseToUse"], + filterCard: { + name: "sha", }, - viewAs:{ - name:"shan", + viewAs: { + name: "shan", }, - position:'hs', - prompt:"将一张杀当闪使用或打出", - check:function(){return 1}, - viewAsFilter:function(player){ - if(!player.countCards('hs','sha')) return false; + position: "hs", + prompt: "将一张杀当闪使用或打出", + check: function () { + return 1; }, - ai:{ - respondShan:true, - skillTagFilter:function(player){ - if(!player.countCards('hs','sha')) return false; + viewAsFilter: function (player) { + if (!player.countCards("hs", "sha")) return false; + }, + ai: { + respondShan: true, + skillTagFilter: function (player) { + if (!player.countCards("hs", "sha")) return false; }, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'respondShan')&¤t<0) return 0.6 + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "respondShan") && current < 0) return 0.6; }, }, }, - sub:true, + sub: true, }, }, }, - gzpaoxiao:{ - audio:"paoxiao", - trigger:{ - player:"useCard", + gzpaoxiao: { + audio: "paoxiao", + trigger: { + player: "useCard", }, - filter:function(event,player){ - if(_status.currentPhase!=player) return false; - if(event.card.name!='sha') return false; - var history=player.getHistory('useCard',function(evt){ - return evt.card.name=='sha'; + filter: function (event, player) { + if (_status.currentPhase != player) return false; + if (event.card.name != "sha") return false; + var history = player.getHistory("useCard", function (evt) { + return evt.card.name == "sha"; }); - return history&&history.indexOf(event)==1; + return history && history.indexOf(event) == 1; }, - forced:true, - preHidden:true, - content:function(){ + forced: true, + preHidden: true, + content: function () { player.draw(); }, - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return Infinity; + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return Infinity; }, }, - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(!get.zhu(player,'shouyue')) return false; - if(arg&&arg.name=='sha') return true; + ai: { + unequip: true, + skillTagFilter: function (player, tag, arg) { + if (!get.zhu(player, "shouyue")) return false; + if (arg && arg.name == "sha") return true; return false; }, }, }, - "new_kurou":{ - audio:"rekurou", - enable:"phaseUse", - usable:1, - filterCard:true, - check:function(card){ - return 8-get.value(card); + new_kurou: { + audio: "rekurou", + enable: "phaseUse", + usable: 1, + filterCard: true, + check: function (card) { + return 8 - get.value(card); }, - position:"he", - content:function(){ + position: "he", + content: function () { player.loseHp(); player.draw(3); - player.addTempSkill('kurou_effect','phaseAfter'); + player.addTempSkill("kurou_effect", "phaseAfter"); }, - ai:{ - order:8, - result:{ - player:function(player){ - if(player.hp<=2) return player.countCards('h')==0?1:0; - if(player.countCards('h',{name:'sha',color:'red'})) return 1; - return player.countCards('h')<=player.hp?1:0; + ai: { + order: 8, + result: { + player: function (player) { + if (player.hp <= 2) return player.countCards("h") == 0 ? 1 : 0; + if (player.countCards("h", { name: "sha", color: "red" })) return 1; + return player.countCards("h") <= player.hp ? 1 : 0; }, }, }, }, - "kurou_effect":{ - mod:{ - cardUsable:function(card,player,num){ - if(card.name=='sha') return num+1; + kurou_effect: { + mod: { + cardUsable: function (card, player, num) { + if (card.name == "sha") return num + 1; }, }, }, - "new_chuli":{ - audio:"chulao", - enable:"phaseUse", - usable:1, - filterTarget:function(card,player,target){ - if(player==target) return false; - for(var i=0;i0; + return target.countCards("he") > 0; }, - filter:function(event,player){ - return player.countCards('he')>0; + filter: function (event, player) { + return player.countCards("he") > 0; }, - filterCard:true, - position:"he", - selectTarget:[1,3], - check:function(card){ - if(get.suit(card)=='spade') return 8-get.value(card); - return 5-get.value(card); + filterCard: true, + position: "he", + selectTarget: [1, 3], + check: function (card) { + if (get.suit(card) == "spade") return 8 - get.value(card); + return 5 - get.value(card); }, - contentBefore:function(){ - var evt=event.getParent(); - evt.draw=[]; - if(get.suit(cards[0])=='spade') evt.draw.push(player); + contentBefore: function () { + var evt = event.getParent(); + evt.draw = []; + if (get.suit(cards[0]) == "spade") evt.draw.push(player); }, - content:function(){ - "step 0" - player.discardPlayerCard(target,'he',true); - "step 1" - if(result.bool){ - if(get.suit(result.cards[0])=='spade') event.getParent().draw.push(target); + content: function () { + "step 0"; + player.discardPlayerCard(target, "he", true); + "step 1"; + if (result.bool) { + if (get.suit(result.cards[0]) == "spade") event.getParent().draw.push(target); } }, - contentAfter:function(){ - 'step 0' - var list=event.getParent().draw; - if(!list.length) event.finish(); + contentAfter: function () { + "step 0"; + var list = event.getParent().draw; + if (!list.length) event.finish(); else game.asyncDraw(list); - 'step 1' + "step 1"; game.delay(); }, - ai:{ - result:{ - target:-1, + ai: { + result: { + target: -1, }, - tag:{ - discard:1, - lose:1, - loseCard:1, + tag: { + discard: 1, + lose: 1, + loseCard: 1, }, - threaten:1.2, - order:3, + threaten: 1.2, + order: 3, }, }, - "baka_hunshang":{ - skillAnimation:true, - animationColor:'wood', - audio:"hunzi", - preHidden:true, - derivation:["baka_yingzi","baka_yinghun"], - viceSkill:true, - init:function(player){ - if(player.checkViceSkill('baka_hunshang')&&!player.viceChanged){ + baka_hunshang: { + skillAnimation: true, + animationColor: "wood", + audio: "hunzi", + preHidden: true, + derivation: ["baka_yingzi", "baka_yinghun"], + viceSkill: true, + init: function (player) { + if (player.checkViceSkill("baka_hunshang") && !player.viceChanged) { player.removeMaxHp(); } }, - trigger:{ - player:"phaseZhunbeiBegin", + trigger: { + player: "phaseZhunbeiBegin", }, - filter:function(event,player){ - return player.hp<=1; + filter: function (event, player) { + return player.hp <= 1; }, - forced:true, - locked:false, + forced: true, + locked: false, //priority:3, - content:function(){ - player.addTempSkills(['baka_yingzi','baka_yinghun']); + content: function () { + player.addTempSkills(["baka_yingzi", "baka_yinghun"]); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 2; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 2; return 0.5; }, - maixie:true, - effect:{ - target:function(card,player,target){ - if(!target.hasFriend()) return; - if(get.tag(card,'damage')==1&&target.hp==2&&!target.isTurnedOver()&& - _status.currentPhase!=target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; + maixie: true, + effect: { + target: function (card, player, target) { + if (!target.hasFriend()) return; + if ( + get.tag(card, "damage") == 1 && + target.hp == 2 && + !target.isTurnedOver() && + _status.currentPhase != target && + get.distance(_status.currentPhase, target, "absolute") <= 3 + ) + return [0.5, 1]; }, }, }, }, - baka_yinghun:{ - inherit:"yinghun", - audio:'yinghun_sunce', + baka_yinghun: { + inherit: "yinghun", + audio: "yinghun_sunce", }, - baka_yingzi:{ - mod:{ - maxHandcardBase:function(player,num){ + baka_yingzi: { + mod: { + maxHandcardBase: function (player, num) { return player.maxHp; }, }, - audio:'reyingzi_sunce', - trigger:{ - player:"phaseDrawBegin2", + audio: "reyingzi_sunce", + trigger: { + player: "phaseDrawBegin2", }, - frequent:true, - filter:function(event){return !event.numFixed}, - content:function(){ + frequent: true, + filter: function (event) { + return !event.numFixed; + }, + content: function () { trigger.num++; }, - ai:{ - threaten:1.3, + ai: { + threaten: 1.3, }, }, - gzyiji:{ - audio:"yiji", - trigger:{ - player:"damageEnd", + gzyiji: { + audio: "yiji", + trigger: { + player: "damageEnd", }, - frequent:true, - preHidden:true, - content:function(){ - 'step 0' - event.cards=game.cardsGotoOrdering(get.cards(2)).cards; - 'step 1' - if(_status.connectMode) game.broadcastAll(function(){_status.noclearcountdown=true}); - event.given_map={}; - 'step 2' - if(event.cards.length>1){ - player.chooseCardButton('遗计:请选择要分配的牌',true,event.cards,[1,event.cards.length]).set('ai',function(button){ - if(ui.selected.buttons.length==0) return 1; - return 0; + frequent: true, + preHidden: true, + content: function () { + "step 0"; + event.cards = game.cardsGotoOrdering(get.cards(2)).cards; + "step 1"; + if (_status.connectMode) + game.broadcastAll(function () { + _status.noclearcountdown = true; }); - } - else if(event.cards.length==1){ - event._result={links:event.cards.slice(0),bool:true}; - } - else{ + event.given_map = {}; + "step 2"; + if (event.cards.length > 1) { + player + .chooseCardButton("遗计:请选择要分配的牌", true, event.cards, [ + 1, + event.cards.length, + ]) + .set("ai", function (button) { + if (ui.selected.buttons.length == 0) return 1; + return 0; + }); + } else if (event.cards.length == 1) { + event._result = { links: event.cards.slice(0), bool: true }; + } else { event.finish(); } - 'step 3' - if(result.bool){ + "step 3"; + if (result.bool) { event.cards.removeArray(result.links); - event.togive=result.links.slice(0); - player.chooseTarget('选择一名角色获得'+get.translation(result.links),true).set('ai',function(target){ - var att=get.attitude(_status.event.player,target); - if(_status.event.enemy){ - return -att; - } - else if(att>0){ - return att/(1+target.countCards('h')); - } - else{ - return att/100; - } - }).set('enemy',get.value(event.togive[0],player,'raw')<0); + event.togive = result.links.slice(0); + player + .chooseTarget("选择一名角色获得" + get.translation(result.links), true) + .set("ai", function (target) { + var att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("enemy", get.value(event.togive[0], player, "raw") < 0); } - 'step 4' - if(result.targets.length){ - var id=result.targets[0].playerid,map=event.given_map; - if(!map[id]) map[id]=[]; + "step 4"; + if (result.targets.length) { + var id = result.targets[0].playerid, + map = event.given_map; + if (!map[id]) map[id] = []; map[id].addArray(event.togive); } - if(cards.length>0) event.goto(2); - 'step 5' - if(_status.connectMode){ - game.broadcastAll(function(){delete _status.noclearcountdown;game.stopCountChoose()}); + if (cards.length > 0) event.goto(2); + "step 5"; + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); } - var list=[]; - for(var i in event.given_map){ - var source=(_status.connectMode?lib.playerOL:game.playerMap)[i]; - player.line(source,'green'); - list.push([source,event.given_map[i]]); + var list = []; + for (var i in event.given_map) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + player.line(source, "green"); + list.push([source, event.given_map[i]]); } game.loseAsync({ - gain_list:list, - giver:player, - animate:'draw', - }).setContent('gaincardMultiple'); + gain_list: list, + giver: player, + animate: "draw", + }).setContent("gaincardMultiple"); }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(!target.hasFriend()) return; - var num=1; - if(get.attitude(player,target)>0){ - if(player.needsToDiscard()){ - num=0.7; - } - else{ - num=0.5; + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target) { + if (get.tag(card, "damage")) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + if (!target.hasFriend()) return; + var num = 1; + if (get.attitude(player, target) > 0) { + if (player.needsToDiscard()) { + num = 0.7; + } else { + num = 0.5; } } - if(target.hp>=4) return [1,num*2]; - if(target.hp==3) return [1,num*1.5]; - if(target.hp==2) return [1,num*0.5]; + if (target.hp >= 4) return [1, num * 2]; + if (target.hp == 3) return [1, num * 1.5]; + if (target.hp == 2) return [1, num * 0.5]; } }, }, }, }, - gzjieming:{ - audio:"jieming", - trigger:{ - player:"damageEnd", + gzjieming: { + audio: "jieming", + trigger: { + player: "damageEnd", }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('gzjieming'),'令一名角色将手牌补至X张(X为其体力上限且至多为5)',function(card,player,target){ - return true;//target.countCards('h')2){ - return Math.max(0,Math.min(5,target.maxHp)-target.countCards('h')); - } - return att/3; - }).setHiddenSkill('gzjieming'); - "step 1" - if(result.bool){ - player.logSkill('gzjieming',result.targets); - for(var i=0;i0) result.targets[i].draw(num); + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("gzjieming"), + "令一名角色将手牌补至X张(X为其体力上限且至多为5)", + function (card, player, target) { + return true; //target.countCards('h') 2) { + return Math.max(0, Math.min(5, target.maxHp) - target.countCards("h")); + } + return att / 3; + }) + .setHiddenSkill("gzjieming"); + "step 1"; + if (result.bool) { + player.logSkill("gzjieming", result.targets); + for (var i = 0; i < result.targets.length; i++) { + var num = + Math.min(5, result.targets[i].maxHp) - result.targets[i].countCards("h"); + if (num > 0) result.targets[i].draw(num); } } }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function(card,player,target,current){ - if(get.tag(card,'damage')&&target.hp>1){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - var max=0; - var players=game.filterPlayer(); - for(var i=0;i0){ - max=Math.max(Math.min(5,players[i].hp)-players[i].countCards('h'),max); + ai: { + maixie: true, + maixie_hp: true, + effect: { + target: function (card, player, target, current) { + if (get.tag(card, "damage") && target.hp > 1) { + if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; + var max = 0; + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (get.attitude(target, players[i]) > 0) { + max = Math.max( + Math.min(5, players[i].hp) - players[i].countCards("h"), + max + ); } } - switch(max){ - case 0:return 2; - case 1:return 1.5; - case 2:return [1,2]; - default:return [0,max]; + switch (max) { + case 0: + return 2; + case 1: + return 1.5; + case 2: + return [1, 2]; + default: + return [0, max]; } } - if((card.name=='tao'||card.name=='caoyao')&& - target.hp>1&&target.countCards('h')<=target.hp) return [0,0]; + if ( + (card.name == "tao" || card.name == "caoyao") && + target.hp > 1 && + target.countCards("h") <= target.hp + ) + return [0, 0]; }, }, }, }, - gzfangzhu:{ - audio:"fangzhu", - trigger:{ - player:"damageEnd", + gzfangzhu: { + audio: "fangzhu", + trigger: { + player: "damageEnd", }, - direct:true, - preHidden:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt2('gzfangzhu'),function(card,player,target){ - return player!=target; - }).setHiddenSkill('gzfangzhu').ai=function(target){ - if(target.hasSkillTag('noturn')) return 0; - var player=_status.event.player,att=get.attitude(player,target); - if(att==0) return 0; - if(att>0){ - if(target.isTurnedOver()) return 1000-target.countCards('h'); + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt2("gzfangzhu"), function (card, player, target) { + return player != target; + }) + .setHiddenSkill("gzfangzhu").ai = function (target) { + if (target.hasSkillTag("noturn")) return 0; + var player = _status.event.player, + att = get.attitude(player, target); + if (att == 0) return 0; + if (att > 0) { + if (target.isTurnedOver()) return 1000 - target.countCards("h"); return -1; + } else { + if (target.isTurnedOver()) return -1; + if (player.getDamagedHp() >= 3) return -1; + return target.countCards("h") + 1; } - else{ - if(target.isTurnedOver()) return -1; - if(player.getDamagedHp()>=3) return -1; - return target.countCards('h')+1; - } - } - "step 1" - if(result.bool){ - var target=result.targets[0]; - event.target=target; - player.logSkill('gzfangzhu',target); - var num=player.getDamagedHp(); - if(num>0) target.chooseToDiscard('he',num,'放逐:弃置'+get.cnNumber(num)+'张牌并失去1点体力','或者点击“取消”不弃牌,改为摸'+get.cnNumber(num)+'张牌并叠置').set('ai',function(card){ - var player=_status.event.player; - if(player.isTurnedOver()) return -1; - return (player.hp*player.hp)-Math.max(1,get.value(card)); - }); - else{ + }; + "step 1"; + if (result.bool) { + var target = result.targets[0]; + event.target = target; + player.logSkill("gzfangzhu", target); + var num = player.getDamagedHp(); + if (num > 0) + target + .chooseToDiscard( + "he", + num, + "放逐:弃置" + get.cnNumber(num) + "张牌并失去1点体力", + "或者点击“取消”不弃牌,改为摸" + get.cnNumber(num) + "张牌并叠置" + ) + .set("ai", function (card) { + var player = _status.event.player; + if (player.isTurnedOver()) return -1; + return player.hp * player.hp - Math.max(1, get.value(card)); + }); + else { target.turnOver(); event.finish(); } - } - else event.finish(); - "step 2" - if(result.bool){ + } else event.finish(); + "step 2"; + if (result.bool) { target.loseHp(); - } - else{ + } else { target.draw(player.getDamagedHp()); target.turnOver(); } }, - ai:{ - maixie:true, - "maixie_hp":true, - effect:{ - target:function(card,player,target){ - if(get.tag(card,'damage')){ - if(player.hasSkillTag('jueqing',false,target)) return [1,-2]; - if(target.hp<=1) return; - if(!target.hasFriend()) return; - var hastarget=false; - var turnfriend=false; - var players=game.filterPlayer(); - for(var i=0;i0&&players[i].isTurnedOver()){ - hastarget=true; - turnfriend=true; + if (get.attitude(target, players[i]) > 0 && players[i].isTurnedOver()) { + hastarget = true; + turnfriend = true; } } - if(get.attitude(player,target)>0&&!hastarget) return; - if(turnfriend||target.hp==target.maxHp) return [0.5,1]; - if(target.hp>1) return [1,0.5]; + if (get.attitude(player, target) > 0 && !hastarget) return; + if (turnfriend || target.hp == target.maxHp) return [0.5, 1]; + if (target.hp > 1) return [1, 0.5]; } }, }, }, }, - fengyin_main:{ - init:function(player,skill){ + fengyin_main: { + init: function (player, skill) { player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); }, - charlotte:true, - skillBlocker:function(skill,player){ - return lib.character[player.name1][3].includes(skill)&&!lib.skill[skill].charlotte&&!get.is.locked(skill,player); + charlotte: true, + skillBlocker: function (skill, player) { + return ( + lib.character[player.name1][3].includes(skill) && + !lib.skill[skill].charlotte && + !get.is.locked(skill, player) + ); }, - mark:true, - marktext:'主', - intro:{ - content:function(storage,player,skill){ - var list=player.getSkills(null,null,false).filter(function(i){ - return lib.skill.fengyin_main.skillBlocker(i,player); + mark: true, + marktext: "主", + intro: { + content: function (storage, player, skill) { + var list = player.getSkills(null, null, false).filter(function (i) { + return lib.skill.fengyin_main.skillBlocker(i, player); }); - if(list.length) return '失效技能:'+get.translation(list); - return '无失效技能'; - } - } + if (list.length) return "失效技能:" + get.translation(list); + return "无失效技能"; + }, + }, }, - fengyin_vice:{ - init:function(player,skill){ + fengyin_vice: { + init: function (player, skill) { player.addSkillBlocker(skill); }, - onremove:function(player,skill){ + onremove: function (player, skill) { player.removeSkillBlocker(skill); }, - charlotte:true, - skillBlocker:function(skill,player){ - return lib.character[player.name2][3].includes(skill)&&!lib.skill[skill].charlotte&&!get.is.locked(skill,player); + charlotte: true, + skillBlocker: function (skill, player) { + return ( + lib.character[player.name2][3].includes(skill) && + !lib.skill[skill].charlotte && + !get.is.locked(skill, player) + ); }, - mark:true, - marktext:'副', - intro:{ - content:function(storage,player,skill){ - var list=player.getSkills(null,null,false).filter(function(i){ - return lib.skill.fengyin_vice.skillBlocker(i,player); + mark: true, + marktext: "副", + intro: { + content: function (storage, player, skill) { + var list = player.getSkills(null, null, false).filter(function (i) { + return lib.skill.fengyin_vice.skillBlocker(i, player); }); - if(list.length) return '失效技能:'+get.translation(list); - return '无失效技能'; - } - } + if (list.length) return "失效技能:" + get.translation(list); + return "无失效技能"; + }, + }, }, - "new_tieji":{ - audio:"retieji", - trigger:{ - player:"useCardToPlayered", + new_tieji: { + audio: "retieji", + trigger: { + player: "useCardToPlayered", }, - check:function(event,player){ - return get.attitude(player,event.target)<0; + check: function (event, player) { + return get.attitude(player, event.target) < 0; }, - filter:function(event){ - return event.card.name=='sha'; + filter: function (event) { + return event.card.name == "sha"; }, - logTarget:"target", - content:function(){ - "step 0" - var target=trigger.target; - var controls=[]; - if(get.zhu(player,'shouyue')){ - if(!target.isUnseen(0)) target.addTempSkill('fengyin_main'); - if(!target.isUnseen(1)) target.addTempSkill('fengyin_vice'); + logTarget: "target", + content: function () { + "step 0"; + var target = trigger.target; + var controls = []; + if (get.zhu(player, "shouyue")) { + if (!target.isUnseen(0)) target.addTempSkill("fengyin_main"); + if (!target.isUnseen(1)) target.addTempSkill("fengyin_vice"); event.goto(2); } - if(!target.isUnseen(0)&&!target.hasSkill('fengyin_main')) controls.push("主将"); - if(!target.isUnseen(1)&&!target.hasSkill('fengyin_vice')) controls.push("副将"); - if(controls.length>0){ - if(controls.length==1) event._result={control:controls[0]}; - else{ - player.chooseControl(controls).set('ai',function(){ - var choice='主将'; - var skills=lib.character[target.name2][3]; - for(var i=0;i 0) { + if (controls.length == 1) event._result = { control: controls[0] }; + else { + player + .chooseControl(controls) + .set("ai", function () { + var choice = "主将"; + var skills = lib.character[target.name2][3]; + for (var i = 0; i < skills.length; i++) { + var info = get.info(skills[i]); + if (info && info.ai && info.ai.maixie) { + choice = "副将"; + break; + } + } + return choice; + }) + .set( + "prompt", + "请选择一个武将牌,令" + + get.translation(target) + + "该武将牌上的非锁定技全部失效。" + ); + } + } else event.goto(2); + "step 1"; + if (result.control) { + player.popup(result.control, "fire"); + var target = trigger.target; + if (result.control == "主将") target.addTempSkill("fengyin_main"); else target.addTempSkill("fengyin_vice"); } - "step 2" - player.judge(function(){return 0}); - "step 3" - var suit=get.suit(result.card); - var target=trigger.target; - var num=target.countCards('h','shan'); - target.chooseToDiscard('请弃置一张'+get.translation(suit)+'牌,否则不能使用闪抵消此杀','he',function(card){ - return get.suit(card)==_status.event.suit; - }).set('ai',function(card){ - var num=_status.event.num; - if(num==0) return 0; - if(card.name=='shan') return num>1?2:0; - return 8-get.value(card); - }).set('num',num).set('suit',suit); - "step 4" - if(!result.bool){ + "step 2"; + player.judge(function () { + return 0; + }); + "step 3"; + var suit = get.suit(result.card); + var target = trigger.target; + var num = target.countCards("h", "shan"); + target + .chooseToDiscard( + "请弃置一张" + get.translation(suit) + "牌,否则不能使用闪抵消此杀", + "he", + function (card) { + return get.suit(card) == _status.event.suit; + } + ) + .set("ai", function (card) { + var num = _status.event.num; + if (num == 0) return 0; + if (card.name == "shan") return num > 1 ? 2 : 0; + return 8 - get.value(card); + }) + .set("num", num) + .set("suit", suit); + "step 4"; + if (!result.bool) { trigger.getParent().directHit.add(trigger.target); } }, }, - hmkyuanyu:{ - audio:'zongkui', - trigger:{ - player:"damageBegin4", + hmkyuanyu: { + audio: "zongkui", + trigger: { + player: "damageBegin4", }, - forced:true, - preHidden:true, - filter:function(event,player){ - if(event.num<=0||!event.source) return false; - var n1=player.getNext(); - var p1=player.getPrevious(); - if(event.source!=n1&&event.source!=p1) return true; + forced: true, + preHidden: true, + filter: function (event, player) { + if (event.num <= 0 || !event.source) return false; + var n1 = player.getNext(); + var p1 = player.getPrevious(); + if (event.source != n1 && event.source != p1) return true; }, - content:function(){ + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(player==target.getNext()||player==target.getPrevious()) return; - if(get.tag(card,'damage')) return 'zeroplayertarget'; + ai: { + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (player == target.getNext() || player == target.getPrevious()) return; + if (get.tag(card, "damage")) return "zeroplayertarget"; }, }, }, }, - hmkguishu:{ - audio:'bmcanshi', - enable:"phaseUse", - filter:function(event,player){ - return player.countCards('hs',{suit:'spade'})>0; + hmkguishu: { + audio: "bmcanshi", + enable: "phaseUse", + filter: function (event, player) { + return player.countCards("hs", { suit: "spade" }) > 0; }, - init:function(player){ - if(!player.storage.hmkguishu) player.storage.hmkguishu=0; + init: function (player) { + if (!player.storage.hmkguishu) player.storage.hmkguishu = 0; }, - chooseButton:{ - dialog:function(event,player){ - var list=['yuanjiao','zhibi']; - for(var i=0;i2) return 1; + if (button.link == "zhibi") { + if (player.countCards("hs", { suit: "spade" }) > 2) return 1; return 0; } }, - backup:function(links,player){ + backup: function (links, player) { return { - audio:'bmcanshi', - filterCard:function(card,player){ - return get.suit(card)=='spade'; + audio: "bmcanshi", + filterCard: function (card, player) { + return get.suit(card) == "spade"; }, - position:"hs", - selectCard:1, - popname:true, - ai:function(card){ - return 6-ai.get.value(card); + position: "hs", + selectCard: 1, + popname: true, + ai: function (card) { + return 6 - ai.get.value(card); }, - viewAs:{name:links[0][2]}, - onuse:function(result,player){ - player.logSkill('hmkguishu'); - if(result.card.name=='yuanjiao') player.storage.hmkguishu=1; - else player.storage.hmkguishu=2; + viewAs: { name: links[0][2] }, + onuse: function (result, player) { + player.logSkill("hmkguishu"); + if (result.card.name == "yuanjiao") player.storage.hmkguishu = 1; + else player.storage.hmkguishu = 2; }, - } + }; }, - prompt:function(links,player){ - return '将一张手牌当作'+get.translation(links[0][2])+'使用'; + prompt: function (links, player) { + return "将一张手牌当作" + get.translation(links[0][2]) + "使用"; }, }, - ai:{ - order:4, - result:{ - player:function(player){ + ai: { + order: 4, + result: { + player: function (player) { return 2; }, }, - threaten:1.6, + threaten: 1.6, }, }, - "_mingzhisuodingji":{ - mode:["guozhan"], - enable:"phaseUse", - filter:function(event,player){ - if(player.hasSkillTag('nomingzhi',false,null,true)) return false; - var bool=false; - var skillm=lib.character[player.name1][3]; - var skillv=lib.character[player.name2][3]; - if(player.isUnseen(0)){ - for(var i=0;i1; + silent: true, + popup: false, + forced: true, + filter: function () { + if (_status.connectMode && !lib.configOL.viewnext) return false; + else if (!_status.connectMode && !get.config("viewnext")) return false; + return game.players.length > 1; }, - content:function(){ - var target=player.getNext(); - player.viewCharacter(target,1); + content: function () { + var target = player.getNext(); + player.viewCharacter(target, 1); }, }, - _aozhan_judge:{ - trigger:{ - player:"phaseBefore", + _aozhan_judge: { + trigger: { + player: "phaseBefore", }, - forced:true, - priority:22, - filter:function(event,player){ - if(get.mode()!='guozhan') return false; - if(_status.connectMode&&!lib.configOL.aozhan) return false; - else if(!_status.connectMode&&!get.config('aozhan')) return false; - if(_status._aozhan) return false; - if(game.players.length>4) return false; - if(game.players.length>3&&game.players.length+game.dead.length<=7) return false; - for(var i=0;i 4) return false; + if (game.players.length > 3 && game.players.length + game.dead.length <= 7) return false; + for (var i = 0; i < game.players.length; i++) { + for (var j = i + 1; j < game.players.length; j++) { + if (game.players[i].isFriendOf(game.players[j])) return false; } } return true; }, - content:function(){ - var color=get.groupnature(player.group,"raw"); - if(player.isUnseen()) color='fire'; - player.$fullscreenpop('鏖战模式',color); - game.broadcastAll(function(){ - _status._aozhan=true; - ui.aozhan=ui.create.div('.touchinfo.left',ui.window); - ui.aozhan.innerHTML='鏖战模式'; - if(ui.time3) ui.time3.style.display='none'; - ui.aozhanInfo=ui.create.system('鏖战模式',null,true); - lib.setPopped(ui.aozhanInfo,function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add('鏖战模式'); - var list=[ - '当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。', - '在鏖战模式下,任何角色均不是非转化的【桃】的合法目标。【桃】可以被当做【杀】或【闪】使用或打出。', - '进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。' - ]; - var intro='
                          '; - for(var i=0;i'+intro+'
                        '); - var ul=uiintro.querySelector('ul'); - if(ul){ - ul.style.width='180px'; - } - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); - game.playBackgroundMusic(); + content: function () { + var color = get.groupnature(player.group, "raw"); + if (player.isUnseen()) color = "fire"; + player.$fullscreenpop("鏖战模式", color); + game.broadcastAll(function () { + _status._aozhan = true; + ui.aozhan = ui.create.div(".touchinfo.left", ui.window); + ui.aozhan.innerHTML = "鏖战模式"; + if (ui.time3) ui.time3.style.display = "none"; + ui.aozhanInfo = ui.create.system("鏖战模式", null, true); + lib.setPopped( + ui.aozhanInfo, + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.add("鏖战模式"); + var list = [ + "当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。", + "在鏖战模式下,任何角色均不是非转化的【桃】的合法目标。【桃】可以被当做【杀】或【闪】使用或打出。", + "进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。", + ]; + var intro = '
                          '; + for (var i = 0; i < list.length; i++) { + intro += "
                        • " + list[i]; + } + intro += "
                        "; + uiintro.add('
                        ' + intro + "
                        "); + var ul = uiintro.querySelector("ul"); + if (ul) { + ul.style.width = "180px"; + } + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); + game.playBackgroundMusic(); + }); + game.countPlayer(function (current) { + current.addSkill("aozhan"); }); - game.countPlayer(function(current){current.addSkill('aozhan')}); }, }, - _guozhan_marks:{ - ruleSkill:true, - enable:'phaseUse', - filter:function(event,player){ - return player.hasMark('yexinjia_mark')||player.hasMark('xianqu_mark')||player.hasMark('yinyang_mark')||player.hasMark('zhulianbihe_mark'); + _guozhan_marks: { + ruleSkill: true, + enable: "phaseUse", + filter: function (event, player) { + return ( + player.hasMark("yexinjia_mark") || + player.hasMark("xianqu_mark") || + player.hasMark("yinyang_mark") || + player.hasMark("zhulianbihe_mark") + ); }, - chooseButton:{ - dialog:function(event,player){ - return ui.create.dialog('###国战标记###弃置一枚对应的标记,发动其对应的效果'); + chooseButton: { + dialog: function (event, player) { + return ui.create.dialog("###国战标记###弃置一枚对应的标记,发动其对应的效果"); }, - chooseControl:function(event,player){ - var list=[],bool=player.hasMark('yexinjia_mark'); - if(bool||player.hasMark('xianqu_mark')) list.push('先驱'); - if(bool||player.hasMark('zhulianbihe_mark')){ - list.push('珠联(摸牌)'); - if(event.filterCard({name:'tao',isCard:true},player,event)) list.push('珠联(桃)'); + chooseControl: function (event, player) { + var list = [], + bool = player.hasMark("yexinjia_mark"); + if (bool || player.hasMark("xianqu_mark")) list.push("先驱"); + if (bool || player.hasMark("zhulianbihe_mark")) { + list.push("珠联(摸牌)"); + if (event.filterCard({ name: "tao", isCard: true }, player, event)) + list.push("珠联(桃)"); } - if(bool||player.hasMark('yinyang_mark')) list.push('阴阳鱼'); - list.push('cancel2'); + if (bool || player.hasMark("yinyang_mark")) list.push("阴阳鱼"); + list.push("cancel2"); return list; }, - check:function(){ - var player=_status.event.player,bool=player.hasMark('yexinjia_mark'); - if((bool||player.hasMark('xianqu_mark'))&&(4-player.countCards('h'))>1) return '先驱'; - if(bool||player.hasMark('zhulianbihe_mark')){ - if(_status.event.getParent().filterCard({name:'tao',isCard:true},player,event)&&get.effect_use(player,{name:'tao'},player)>0) return '珠联(桃)'; - if(player.getHandcardLimit()-player.countCards('h')>1&&!game.hasPlayer(function(current){ - return current!=player&¤t.isFriendOf(player)&¤t.hp+current.countCards('h','shan')<=2; - })) return '珠联(摸牌)'; + check: function () { + var player = _status.event.player, + bool = player.hasMark("yexinjia_mark"); + if ((bool || player.hasMark("xianqu_mark")) && 4 - player.countCards("h") > 1) + return "先驱"; + if (bool || player.hasMark("zhulianbihe_mark")) { + if ( + _status.event + .getParent() + .filterCard({ name: "tao", isCard: true }, player, event) && + get.effect_use(player, { name: "tao" }, player) > 0 + ) + return "珠联(桃)"; + if ( + player.getHandcardLimit() - player.countCards("h") > 1 && + !game.hasPlayer(function (current) { + return ( + current != player && + current.isFriendOf(player) && + current.hp + current.countCards("h", "shan") <= 2 + ); + }) + ) + return "珠联(摸牌)"; } - if(player.hasMark('yinyang_mark')&&player.getHandcardLimit()-player.countCards('h')>0) return '阴阳鱼'; - return 'cancel2'; + if ( + player.hasMark("yinyang_mark") && + player.getHandcardLimit() - player.countCards("h") > 0 + ) + return "阴阳鱼"; + return "cancel2"; }, - backup:function(result,player){ - switch(result.control){ - case '珠联(桃)': return get.copy(lib.skill._zhulianbihe_mark_tao); - case '珠联(摸牌)': return { - content:function(){ - player.draw(2); - player.removeMark(player.hasMark('zhulianbihe_mark')?'zhulianbihe_mark':'yexinjia_mark',1); - }, - }; - case '阴阳鱼': return { - content:function(){ - player.draw(); - player.removeMark(player.hasMark('yinyang_mark')?'yinyang_mark':'yexinjia_mark',1); - } - }; - case '先驱': return {content:lib.skill.xianqu_mark.content}; + backup: function (result, player) { + switch (result.control) { + case "珠联(桃)": + return get.copy(lib.skill._zhulianbihe_mark_tao); + case "珠联(摸牌)": + return { + content: function () { + player.draw(2); + player.removeMark( + player.hasMark("zhulianbihe_mark") + ? "zhulianbihe_mark" + : "yexinjia_mark", + 1 + ); + }, + }; + case "阴阳鱼": + return { + content: function () { + player.draw(); + player.removeMark( + player.hasMark("yinyang_mark") ? "yinyang_mark" : "yexinjia_mark", + 1 + ); + }, + }; + case "先驱": + return { content: lib.skill.xianqu_mark.content }; } }, }, - ai:{ - order:1, - result:{ - player:1, + ai: { + order: 1, + result: { + player: 1, }, }, }, - xianqu_mark:{ - intro:{ - content:"◇出牌阶段,你可以弃置此标记,然后将手牌摸至四张并观看一名其他角色的一张武将牌。", + xianqu_mark: { + intro: { + content: + "◇出牌阶段,你可以弃置此标记,然后将手牌摸至四张并观看一名其他角色的一张武将牌。", }, - content:function(){ - "step 0" - player.removeMark(player.hasMark('xianqu_mark')?'xianqu_mark':'yexinjia_mark',1); - var num=4-player.countCards('h'); - if(num) player.draw(num); - "step 1" - if(game.hasPlayer(function(current){ - return current!=player&¤t.isUnseen(2); - })) player.chooseTarget('是否观看一名其他角色的一张暗置武将牌?',function(card,player,target){ - return target!=player&&target.isUnseen(2); - }).set('ai',function(target){ - if(target.isUnseen()){ - var next=_status.event.player.getNext(); - if (target!=next) return 10; - return 9; - } - return -get.attitude(_status.event.player,target); - }); + content: function () { + "step 0"; + player.removeMark(player.hasMark("xianqu_mark") ? "xianqu_mark" : "yexinjia_mark", 1); + var num = 4 - player.countCards("h"); + if (num) player.draw(num); + "step 1"; + if ( + game.hasPlayer(function (current) { + return current != player && current.isUnseen(2); + }) + ) + player + .chooseTarget( + "是否观看一名其他角色的一张暗置武将牌?", + function (card, player, target) { + return target != player && target.isUnseen(2); + } + ) + .set("ai", function (target) { + if (target.isUnseen()) { + var next = _status.event.player.getNext(); + if (target != next) return 10; + return 9; + } + return -get.attitude(_status.event.player, target); + }); else event.finish(); - "step 2" - if(result.bool){ - event.target=result.targets[0]; - player.line(event.target,'green'); - var controls=[]; - if(event.target.isUnseen(0)) controls.push('主将'); - if(event.target.isUnseen(1)) controls.push('副将'); - if(controls.length>1){ + "step 2"; + if (result.bool) { + event.target = result.targets[0]; + player.line(event.target, "green"); + var controls = []; + if (event.target.isUnseen(0)) controls.push("主将"); + if (event.target.isUnseen(1)) controls.push("副将"); + if (controls.length > 1) { player.chooseControl(controls); } - if(controls.length==0) event.finish(); - } - else{ - player.removeSkill('xianqu_mark'); + if (controls.length == 0) event.finish(); + } else { + player.removeSkill("xianqu_mark"); event.finish(); } - "step 3" - if(result.control){ - if(result.control=='主将'){ - player.viewCharacter(event.target,0); + "step 3"; + if (result.control) { + if (result.control == "主将") { + player.viewCharacter(event.target, 0); + } else { + player.viewCharacter(event.target, 1); } - else{ - player.viewCharacter(event.target,1); - } - } - else if(target.isUnseen(0)){ - player.viewCharacter(event.target,0); - } - else{ - player.viewCharacter(event.target,1); + } else if (target.isUnseen(0)) { + player.viewCharacter(event.target, 0); + } else { + player.viewCharacter(event.target, 1); } }, }, - zhulianbihe_mark:{ - intro:{ - content:"◇出牌阶段,你可以弃置此标记 然后摸两张牌。
                        ◇你可以将此标记当做【桃】使用。", + zhulianbihe_mark: { + intro: { + content: "◇出牌阶段,你可以弃置此标记 然后摸两张牌。
                        ◇你可以将此标记当做【桃】使用。", }, }, - yinyang_mark:{ - intro:{ - content:"◇出牌阶段,你可以弃置此标记,然后摸一张牌。
                        ◇弃牌阶段,你可以弃置此标记,然后本回合手牌上限+2。", + yinyang_mark: { + intro: { + content: + "◇出牌阶段,你可以弃置此标记,然后摸一张牌。
                        ◇弃牌阶段,你可以弃置此标记,然后本回合手牌上限+2。", }, }, - _zhulianbihe_mark_tao:{ - ruleSkill:true, - enable:"chooseToUse", - filter:function(event,player){ - return event.type!='phase'&&(player.hasMark('zhulianbihe_mark')||player.hasMark('yexinjia_mark')); + _zhulianbihe_mark_tao: { + ruleSkill: true, + enable: "chooseToUse", + filter: function (event, player) { + return ( + event.type != "phase" && + (player.hasMark("zhulianbihe_mark") || player.hasMark("yexinjia_mark")) + ); }, - viewAsFilter:function(player){ - return player.hasMark('zhulianbihe_mark')||player.hasMark('yexinjia_mark'); + viewAsFilter: function (player) { + return player.hasMark("zhulianbihe_mark") || player.hasMark("yexinjia_mark"); }, - viewAs:{ - name:"tao", - isCard:true, + viewAs: { + name: "tao", + isCard: true, }, - filterCard:function(){return false}, - selectCard:-1, - precontent:function(){ - player.removeMark(player.hasMark('zhulianbihe_mark')?'zhulianbihe_mark':'yexinjia_mark',1); + filterCard: function () { + return false; + }, + selectCard: -1, + precontent: function () { + player.removeMark( + player.hasMark("zhulianbihe_mark") ? "zhulianbihe_mark" : "yexinjia_mark", + 1 + ); }, }, - _yinyang_mark_add:{ - ruleSkill:true, - trigger:{ - player:"phaseDiscardBegin", + _yinyang_mark_add: { + ruleSkill: true, + trigger: { + player: "phaseDiscardBegin", }, - filter:function(event,player){ - return (player.hasMark('yinyang_mark')||player.hasMark('yexinjia_mark'))&&player.needsToDiscard(); + filter: function (event, player) { + return ( + (player.hasMark("yinyang_mark") || player.hasMark("yexinjia_mark")) && + player.needsToDiscard() + ); }, - prompt:function(event,player){ - return '是否弃置一枚【'+(player.hasMark('yinyang_mark')?'阴阳鱼':'野心家')+'】标记,使本回合的手牌上限+2?'; + prompt: function (event, player) { + return ( + "是否弃置一枚【" + + (player.hasMark("yinyang_mark") ? "阴阳鱼" : "野心家") + + "】标记,使本回合的手牌上限+2?" + ); }, - content:function(){ - player.addTempSkill('yinyang_add','phaseAfter'); - player.removeMark(player.hasMark('yinyang_mark')?'yinyang_mark':'yexinjia_mark',1); + content: function () { + player.addTempSkill("yinyang_add", "phaseAfter"); + player.removeMark(player.hasMark("yinyang_mark") ? "yinyang_mark" : "yexinjia_mark", 1); }, }, - yinyang_add:{ - mod:{ - maxHandcard:function(player,num){ - return num+2; + yinyang_add: { + mod: { + maxHandcard: function (player, num) { + return num + 2; }, }, }, - yexinjia_mark:{ - intro:{ - content:'◇你可以弃置此标记,并发动【先驱】标记或【珠联璧合】标记或【阴阳鱼】标记的效果。', + yexinjia_mark: { + intro: { + content: + "◇你可以弃置此标记,并发动【先驱】标记或【珠联璧合】标记或【阴阳鱼】标记的效果。", }, }, - yexinjia_friend:{ - marktext:'盟', - intro:{ - name:'结盟', - content:'已经与$结成联盟', + yexinjia_friend: { + marktext: "盟", + intro: { + name: "结盟", + content: "已经与$结成联盟", }, }, /*----分界线----*/ - _lianheng:{ - mode:['guozhan'], - enable:'phaseUse', - usable:1, - prompt:'将至多三张可合纵的牌交给一名与你势力不同的角色,或未确定势力的角色,若你交给与你势力不同的角色,则你摸等量的牌', - filter:function(event,player){ - return player.hasCard(function(card){ - return card.hasTag('lianheng')||card.hasGaintag('_lianheng'); - },'h'); + _lianheng: { + mode: ["guozhan"], + enable: "phaseUse", + usable: 1, + prompt: "将至多三张可合纵的牌交给一名与你势力不同的角色,或未确定势力的角色,若你交给与你势力不同的角色,则你摸等量的牌", + filter: function (event, player) { + return player.hasCard(function (card) { + return card.hasTag("lianheng") || card.hasGaintag("_lianheng"); + }, "h"); }, - filterCard:function(card){ - return card.hasTag('lianheng')||card.hasGaintag('_lianheng'); + filterCard: function (card) { + return card.hasTag("lianheng") || card.hasGaintag("_lianheng"); }, - filterTarget:function(card,player,target){ - if(target==player) return false; - if(player.isUnseen()) return target.isUnseen(); + filterTarget: function (card, player, target) { + if (target == player) return false; + if (player.isUnseen()) return target.isUnseen(); return !target.isFriendOf(player); }, - check:function(card){ - if(card.name=='tao') return 0; - return 7-get.value(card); + check: function (card) { + if (card.name == "tao") return 0; + return 7 - get.value(card); }, - selectCard:[1,3], - discard:false, - lose:false, - delay:false, - content:function(){ - "step 0" - player.give(cards,target); - "step 1" - if(!target.isUnseen()){ + selectCard: [1, 3], + discard: false, + lose: false, + delay: false, + content: function () { + "step 0"; + player.give(cards, target); + "step 1"; + if (!target.isUnseen()) { player.draw(cards.length); } }, - ai:{ - basic:{ - order:8 + ai: { + basic: { + order: 8, }, - result:{ - player:function(player,target){ - var huoshao=false; - for(var i=0;i=lib.suit.length) return false; - return player.isFriendOf(event.player)&&player.hasCard(function(card){ - if(_status.connectMode&&get.position(card)=='h') return true; - return !suits.includes(get.suit(card)); - },'he'); + if (suits.length >= lib.suit.length) return false; + return ( + player.isFriendOf(event.player) && + player.hasCard(function (card) { + if (_status.connectMode && get.position(card) == "h") return true; + return !suits.includes(get.suit(card)); + }, "he") + ); }, - direct:true, - content:function(){ - 'step 0' - var suits=[],cards=player.getExpansions('qianhuan'); - for(var i=0;i{ - return i.hasGaintag('sha_notshan'); - }))||trigger.target.hp>=3){ - goon=false; + direct: true, + content: function () { + "step 0"; + var goon = get.effect(trigger.target, trigger.card, trigger.player, player) < 0; + if (goon) { + if ( + [ + "tiesuo", + "diaohulishan", + "lianjunshengyan", + "zhibi", + "chiling", + "lulitongxin", + ].includes(trigger.card.name) + ) { + goon = false; + } else if (trigger.card.name == "sha") { + if ( + trigger.target.mayHaveShan( + player, + "use", + trigger.target.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) || + trigger.target.hp >= 3 + ) { + goon = false; } - } - else if(trigger.card.name=='guohe'){ - if(trigger.target.countCards('he')>=3||!trigger.target.countCards('h')){ - goon=false; + } else if (trigger.card.name == "guohe") { + if ( + trigger.target.countCards("he") >= 3 || + !trigger.target.countCards("h") + ) { + goon = false; } - } - else if(trigger.card.name=='shuiyanqijunx'){ - if(trigger.target.countCards('e')<=1||trigger.target.hp>=3){ - goon=false; + } else if (trigger.card.name == "shuiyanqijunx") { + if (trigger.target.countCards("e") <= 1 || trigger.target.hp >= 3) { + goon = false; } - } - else if(get.tag(trigger.card,'damage')&&trigger.target.hp>=3){ - goon=false; + } else if (get.tag(trigger.card, "damage") && trigger.target.hp >= 3) { + goon = false; } } - player.chooseButton().set('goon',goon).set('ai',function(button){ - if(_status.event.goon) return 1; - return 0; - }).set('createDialog',[get.prompt('qianhuan'),'
                        移去一张“千幻”牌令'+ - get.translation(trigger.player)+'对'+get.translation(trigger.target)+'的'+get.translation(trigger.card)+'失效
                        ',player.getExpansions('qianhuan')]); - 'step 1' - if(result.bool){ - player.logSkill('qianhuan',trigger.player); + player + .chooseButton() + .set("goon", goon) + .set("ai", function (button) { + if (_status.event.goon) return 1; + return 0; + }) + .set("createDialog", [ + get.prompt("qianhuan"), + '
                        移去一张“千幻”牌令' + + get.translation(trigger.player) + + "对" + + get.translation(trigger.target) + + "的" + + get.translation(trigger.card) + + "失效
                        ", + player.getExpansions("qianhuan"), + ]); + "step 1"; + if (result.bool) { + player.logSkill("qianhuan", trigger.player); trigger.getParent().targets.remove(trigger.target); - var card=result.links[0]; + var card = result.links[0]; player.loseToDiscardpile(card); } - } - } - } - }, - gzsanyao:{ - audio:'sanyao', - inherit:'sanyao', - filterTarget:function(card,player,target){ - return target.hp>player.hp||target.countCards('h')>player.countCards('h'); + }, + }, }, }, - gzzhiman:{ - audio:'zhiman', - inherit:'zhiman', - preHidden:true, - content:function(){ - 'step 0' - if(trigger.player.countGainableCards(player,'ej')){ - player.gainPlayerCard(trigger.player,'ej',true); + gzsanyao: { + audio: "sanyao", + inherit: "sanyao", + filterTarget: function (card, player, target) { + return target.hp > player.hp || target.countCards("h") > player.countCards("h"); + }, + }, + gzzhiman: { + audio: "zhiman", + inherit: "zhiman", + preHidden: true, + content: function () { + "step 0"; + if (trigger.player.countGainableCards(player, "ej")) { + player.gainPlayerCard(trigger.player, "ej", true); } trigger.cancel(); - 'step 1' - if(player.isFriendOf(trigger.player)){ + "step 1"; + if (player.isFriendOf(trigger.player)) { trigger.player.mayChangeVice(); } - } - }, - gzdiancai:{ - audio:'diancai', - trigger:{global:'phaseUseEnd'}, - filter:function(event,player){ - if(_status.currentPhase==player) return false; - var num=0; - player.getHistory('lose',function(evt){ - if(evt.cards2&&evt.getParent('phaseUse')==event) num+=evt.cards2.length; - }); - return num>=player.hp; }, - preHidden:true, - content:function(){ - 'step 0' - var num=player.maxHp-player.countCards('h'); - if(num>0){ + }, + gzdiancai: { + audio: "diancai", + trigger: { global: "phaseUseEnd" }, + filter: function (event, player) { + if (_status.currentPhase == player) return false; + var num = 0; + player.getHistory("lose", function (evt) { + if (evt.cards2 && evt.getParent("phaseUse") == event) num += evt.cards2.length; + }); + return num >= player.hp; + }, + preHidden: true, + content: function () { + "step 0"; + var num = player.maxHp - player.countCards("h"); + if (num > 0) { player.draw(num); } - 'step 1' + "step 1"; player.mayChangeVice(); }, }, - xuanlve:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], + xuanlve: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], }, - direct:true, - preHidden:true, - filter:function(event,player){ - var evt=event.getl(player); - return evt&&evt.es&&evt.es.length>0; + direct: true, + preHidden: true, + filter: function (event, player) { + var evt = event.getl(player); + return evt && evt.es && evt.es.length > 0; }, - content:function(){ - 'step 0' - player.chooseTarget(get.prompt('xuanlve'),'弃置一名其他角色的一张牌',function(card,player,target){ - return target!=player&&target.countDiscardableCards(player,'he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }).setHiddenSkill(event.name); - 'step 1' - if(result.bool){ - player.logSkill('xuanlve',result.targets); - player.discardPlayerCard(result.targets[0],'he',true); + content: function () { + "step 0"; + player + .chooseTarget( + get.prompt("xuanlve"), + "弃置一名其他角色的一张牌", + function (card, player, target) { + return target != player && target.countDiscardableCards(player, "he"); + } + ) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }) + .setHiddenSkill(event.name); + "step 1"; + if (result.bool) { + player.logSkill("xuanlve", result.targets); + player.discardPlayerCard(result.targets[0], "he", true); } }, - ai:{ - noe:true, - reverseEquip:true, - effect:{ - target:function(card,player,target,current){ - if(get.type(card)=='equip') return [1,1]; - } - } - } + ai: { + noe: true, + reverseEquip: true, + effect: { + target: function (card, player, target, current) { + if (get.type(card) == "equip") return [1, 1]; + }, + }, + }, }, - lianzi:{ - enable:'phaseUse', - usable:1, - audio:2, - filterCard:true, - check:function(card){ - if(get.type(card)=='equip') return 0; - var player=_status.event.player; - var num=game.countPlayer(function(current){ - if(current.identity=='wu'){ - return current.countCards('e'); - } - })+player.getExpansions('yuanjiangfenghuotu').length; - if(num>=5){ - return 8-get.value(card); + lianzi: { + enable: "phaseUse", + usable: 1, + audio: 2, + filterCard: true, + check: function (card) { + if (get.type(card) == "equip") return 0; + var player = _status.event.player; + var num = + game.countPlayer(function (current) { + if (current.identity == "wu") { + return current.countCards("e"); + } + }) + player.getExpansions("yuanjiangfenghuotu").length; + if (num >= 5) { + return 8 - get.value(card); } - if(num>=3){ - return 7-get.value(card); + if (num >= 3) { + return 7 - get.value(card); } - if(num>=2){ - return 3-get.value(card); + if (num >= 2) { + return 3 - get.value(card); } return 0; }, - content:function(){ - 'step 0' - var num=game.countPlayer(function(current){ - if(current.identity=='wu'){ - return current.countCards('e'); - } - })+player.getExpansions('yuanjiangfenghuotu').length; - if(num){ - event.shown=get.cards(num); - player.showCards(event.shown,get.translation('lianzi')); - } - else{ + content: function () { + "step 0"; + var num = + game.countPlayer(function (current) { + if (current.identity == "wu") { + return current.countCards("e"); + } + }) + player.getExpansions("yuanjiangfenghuotu").length; + if (num) { + event.shown = get.cards(num); + player.showCards(event.shown, get.translation("lianzi")); + } else { event.finish(); return; } - 'step 1' - var list=[]; - var discards=[]; - var type=get.type(cards[0],'trick'); - for(var i=0;i=3&&player.hasStockSkill('lianzi')){ - player.changeSkills(['gzzhiheng'],['lianzi']); + if (list.length) { + player.gain(list, "gain2"); + if (list.length >= 3 && player.hasStockSkill("lianzi")) { + player.changeSkills(["gzzhiheng"], ["lianzi"]); } } }, - ai:{ - order:7, - result:{ - player:1 - } - } - }, - jubao:{ - mod:{ - canBeGained:function(card,source,player){ - if(source!=player&&get.position(card)=='e'&&get.subtype(card)=='equip5') return false; - } + ai: { + order: 7, + result: { + player: 1, + }, }, - trigger:{player:'phaseJieshuBegin'}, - audio:2, - forced:true, - unique:true, - filter:function(event,player){ - if(game.hasPlayer(function(current){ - return current.countCards('ej',function(card){ - return card.name=='dinglanyemingzhu'; - }); - })){ + }, + jubao: { + mod: { + canBeGained: function (card, source, player) { + if (source != player && get.position(card) == "e" && get.subtype(card) == "equip5") + return false; + }, + }, + trigger: { player: "phaseJieshuBegin" }, + audio: 2, + forced: true, + unique: true, + filter: function (event, player) { + if ( + game.hasPlayer(function (current) { + return current.countCards("ej", function (card) { + return card.name == "dinglanyemingzhu"; + }); + }) + ) { return true; } - for(var i=0;i0; + trigger: { player: "damageEnd" }, + forced: true, + filter: function (event, player) { + return ( + event.card && + (event.card.name == "sha" || get.type(event.card, "trick") == "trick") && + player.getExpansions("yuanjiangfenghuotu").length > 0 + ); }, - content:function(){ - 'step 0' - player.chooseCardButton('将一张“烽火”置入弃牌堆',player.getExpansions('yuanjiangfenghuotu'),true); - 'step 1' - if(result.bool){ - var card=result.links[0]; + content: function () { + "step 0"; + player.chooseCardButton( + "将一张“烽火”置入弃牌堆", + player.getExpansions("yuanjiangfenghuotu"), + true + ); + "step 1"; + if (result.bool) { + var card = result.links[0]; player.loseToDiscardpile(card); } - } + }, }, - jiahe_put:{ - enable:'phaseUse', - audio:2, - forceaudio:true, - filter:function(event,player){ - var zhu=get.zhu(player,'jiahe'); - if(zhu){ - return player.countCards('he',{type:'equip'})>0; + jiahe_put: { + enable: "phaseUse", + audio: 2, + forceaudio: true, + filter: function (event, player) { + var zhu = get.zhu(player, "jiahe"); + if (zhu) { + return player.countCards("he", { type: "equip" }) > 0; } return false; }, - filterCard:{type:'equip'}, - position:'he', - usable:1, - check:function(card){ - var zhu=get.zhu(_status.event.player,'jiahe'); - if(!zhu) return 0; - var num=7-get.value(card); - if(get.position(card)=='h'){ - if(zhu.getExpansions('huangjintianbingfu').length>=5){ - return num-3; + filterCard: { type: "equip" }, + position: "he", + usable: 1, + check: function (card) { + var zhu = get.zhu(_status.event.player, "jiahe"); + if (!zhu) return 0; + var num = 7 - get.value(card); + if (get.position(card) == "h") { + if (zhu.getExpansions("huangjintianbingfu").length >= 5) { + return num - 3; } - return num+3; - } - else{ - var player=_status.event.player; - var zhu=get.zhu(player,'jiahe'); - var sub=get.subtype(card) - if(player.countCards('h',function(card){ - return get.type(card)=='equip'&&get.subtype(card)=='sub'&&player.hasValueTarget(card); - })) return num+4; - if(zhu.getExpansions('yuanjiangfenghuotu').length>=5&&!player.hasSkillTag('noe')){ - return num-5; + return num + 3; + } else { + var player = _status.event.player; + var zhu = get.zhu(player, "jiahe"); + var sub = get.subtype(card); + if ( + player.countCards("h", function (card) { + return ( + get.type(card) == "equip" && + get.subtype(card) == "sub" && + player.hasValueTarget(card) + ); + }) + ) + return num + 4; + if ( + zhu.getExpansions("yuanjiangfenghuotu").length >= 5 && + !player.hasSkillTag("noe") + ) { + return num - 5; } } return num; }, - discard:false, - lose:false, - delay:false, - prepare:function(cards,player){ - var zhu=get.zhu(player,'jiahe'); + discard: false, + lose: false, + delay: false, + prepare: function (cards, player) { + var zhu = get.zhu(player, "jiahe"); player.line(zhu); }, - content:function(){ - var zhu=get.zhu(player,'jiahe'); - zhu.addToExpansion(cards,player,'give').gaintag.add('yuanjiangfenghuotu'); + content: function () { + var zhu = get.zhu(player, "jiahe"); + zhu.addToExpansion(cards, player, "give").gaintag.add("yuanjiangfenghuotu"); }, - ai:{ - order:function(item,player){ - if(player.hasSkillTag('noe')||!player.countCards('h',function(card){ - return get.type(card)=='equip'&&!player.canEquip(card)&&player.hasValueTarget(card); - })) return 1; + ai: { + order: function (item, player) { + if ( + player.hasSkillTag("noe") || + !player.countCards("h", function (card) { + return ( + get.type(card) == "equip" && + !player.canEquip(card) && + player.hasValueTarget(card) + ); + }) + ) + return 1; return 10; }, - result:{ - player:1 - } - } + result: { + player: 1, + }, + }, }, - jiahe_skill:{ - trigger:{player:'phaseZhunbeiBegin'}, - direct:true, - audio:"jiahe_put", - forceaudio:true, - filter:function(event,player){ - var zhu=get.zhu(player,'jiahe'); - if(zhu&&zhu.getExpansions('yuanjiangfenghuotu').length){ + jiahe_skill: { + trigger: { player: "phaseZhunbeiBegin" }, + direct: true, + audio: "jiahe_put", + forceaudio: true, + filter: function (event, player) { + var zhu = get.zhu(player, "jiahe"); + if (zhu && zhu.getExpansions("yuanjiangfenghuotu").length) { return true; } return false; }, - content:function(){ - 'step 0' - var zhu=get.zhu(player,'jiahe'); - event.num=zhu.getExpansions('yuanjiangfenghuotu').length; - 'step 1' - var list=[]; - if(event.num>=1&&!player.hasSkill('jiahe_reyingzi')) list.push('reyingzi'); - if(event.num>=2&&!player.hasSkill('jiahe_haoshi')) list.push('haoshi'); - if(event.num>=3&&!player.hasSkill('jiahe_shelie')) list.push('shelie'); - if(event.num>=4&&!player.hasSkill('jiahe_duoshi')) list.push('fakeduoshi'); - if(!list.length){ + content: function () { + "step 0"; + var zhu = get.zhu(player, "jiahe"); + event.num = zhu.getExpansions("yuanjiangfenghuotu").length; + "step 1"; + var list = []; + if (event.num >= 1 && !player.hasSkill("jiahe_reyingzi")) list.push("reyingzi"); + if (event.num >= 2 && !player.hasSkill("jiahe_haoshi")) list.push("haoshi"); + if (event.num >= 3 && !player.hasSkill("jiahe_shelie")) list.push("shelie"); + if (event.num >= 4 && !player.hasSkill("jiahe_duoshi")) list.push("fakeduoshi"); + if (!list.length) { event.finish(); return; } - var prompt2='你可以获得下列一项技能直到回合结束'; - if(list.length>=5){ - if(event.done){ - prompt2+=' (2/2)'; - } - else{ - prompt2+=' (1/2)'; + var prompt2 = "你可以获得下列一项技能直到回合结束"; + if (list.length >= 5) { + if (event.done) { + prompt2 += " (2/2)"; + } else { + prompt2 += " (1/2)"; } } - list.push('cancel2'); - player.chooseControl(list).set('prompt',get.translation('yuanjiangfenghuotu')). - set('prompt2',prompt2).set('centerprompt2',true).set('ai',function(evt,player){ - var controls=_status.event.controls; - if(controls.includes('haoshi')){ - var nh=player.countCards('h'); - if(player.hasSkill('reyingzi')){ - if(nh==0) return 'haoshi'; + list.push("cancel2"); + player + .chooseControl(list) + .set("prompt", get.translation("yuanjiangfenghuotu")) + .set("prompt2", prompt2) + .set("centerprompt2", true) + .set("ai", function (evt, player) { + var controls = _status.event.controls; + if (controls.includes("haoshi")) { + var nh = player.countCards("h"); + if (player.hasSkill("reyingzi")) { + if (nh == 0) return "haoshi"; + } else { + if (nh <= 1) return "haoshi"; + } } - else{ - if(nh<=1) return 'haoshi'; + if (controls.includes("shelie")) { + return "shelie"; } - } - if(controls.includes('shelie')){ - return 'shelie'; - } - if(controls.includes('reyingzi')){ - return 'reyingzi'; - } - if(controls.includes('fakeduoshi')){ - return 'fakeduoshi'; - } - return controls.randomGet(); - }); - 'step 2' - if(result.control!='cancel2'){ - var skill=(result.control!='fakeduoshi'?'jiahe_':'')+result.control; + if (controls.includes("reyingzi")) { + return "reyingzi"; + } + if (controls.includes("fakeduoshi")) { + return "fakeduoshi"; + } + return controls.randomGet(); + }); + "step 2"; + if (result.control != "cancel2") { + var skill = (result.control != "fakeduoshi" ? "jiahe_" : "") + result.control; player.addTempSkills(skill); - if(!event.done) player.logSkill('jiahe_put'); + if (!event.done) player.logSkill("jiahe_put"); // game.log(player,'获得了技能','【'+get.translation(skill)+'】'); - if(event.num>=5&&!event.done){ - event.done=true; + if (event.num >= 5 && !event.done) { + event.done = true; event.goto(1); } } - } - }, - jiahe_reyingzi:{ - inherit:'reyingzi', - }, - jiahe_haoshi:{ - inherit:'haoshi', - }, - jiahe_shelie:{ - inherit:'shelie', - }, - jiahe_duoshi:{ - inherit:'duoshi', - }, - yuanjiangfenghuotu:{ - unique:true, - forceunique:true, - nopop:true, - mark:true, - onremove:function(player,skill){ - var cards=player.getExpansions(skill); - if(cards.length) player.loseToDiscardpile(cards); }, - intro:{ - content:'expansion', - markcount:'expansion', - mark:function(dialog,content,player){ - var content=player.getExpansions('yuanjiangfenghuotu'); - if(content&&content.length){ + }, + jiahe_reyingzi: { + inherit: "reyingzi", + }, + jiahe_haoshi: { + inherit: "haoshi", + }, + jiahe_shelie: { + inherit: "shelie", + }, + jiahe_duoshi: { + inherit: "duoshi", + }, + yuanjiangfenghuotu: { + unique: true, + forceunique: true, + nopop: true, + mark: true, + onremove: function (player, skill) { + var cards = player.getExpansions(skill); + if (cards.length) player.loseToDiscardpile(cards); + }, + intro: { + content: "expansion", + markcount: "expansion", + mark: function (dialog, content, player) { + var content = player.getExpansions("yuanjiangfenghuotu"); + if (content && content.length) { dialog.addSmall(content); } - dialog.addText('
                        • 每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
                        • 根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上~英姿;两张以上~好施;三张以上~涉猎;四张以上~度势;五张以上~可额外选择一项。
                        • 锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。',false) - } - } + dialog.addText( + '
                          • 每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
                          • 根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上~英姿;两张以上~好施;三张以上~涉猎;四张以上~度势;五张以上~可额外选择一项。
                          • 锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。', + false + ); + }, + }, }, - gzqice:{ - enable:'phaseUse', - usable:1, - audio:"qice_backup", - filter:function(event,player){ - var hs=player.getCards('h'); - if(!hs.length) return false; - for(var i=0;inum){ + if (get.select(info.selectTarget)[1] == -1) { + if ( + game.countPlayer(function (current) { + return player.canUse(card, current); + }) > num + ) { return false; } - } - else if(info.changeTarget){ - var giveup=true; - var list=game.filterPlayer(function(current){ - return player.canUse(card,current); + } else if (info.changeTarget) { + var giveup = true; + var list = game.filterPlayer(function (current) { + return player.canUse(card, current); }); - for(var i=0;inh){ - select[1]=nh; + filterCard: true, + audio: "qice_backup", + selectCard: -1, + position: "h", + selectTarget: function () { + var select = get.select(get.info(get.card()).selectTarget); + var nh = _status.event.player.countCards("h"); + if (select[1] > nh) { + select[1] = nh; } return select; }, - filterTarget:function(card,player,target){ - var info=get.info(card); - if(info.changeTarget){ - var targets=[target]; - info.changeTarget(player,targets); - if(targets.length>player.countCards('h')){ + filterTarget: function (card, player, target) { + var info = get.info(card); + if (info.changeTarget) { + var targets = [target]; + info.changeTarget(player, targets); + if (targets.length > player.countCards("h")) { return false; } } - return lib.filter.filterTarget(card,player,target); + return lib.filter.filterTarget(card, player, target); }, - popname:true, - viewAs:{name:links[0][2]}, - ai1:function(){ + popname: true, + viewAs: { name: links[0][2] }, + ai1: function () { return 1; - } - } + }, + }; + }, + prompt: function (links, player) { + return "将全部手牌当作" + get.translation(links[0][2]) + "使用"; }, - prompt:function(links,player){ - return '将全部手牌当作'+get.translation(links[0][2])+'使用'; - } }, - ai:{ - order:1, - result:{ - player:function(player){ - var num=0; - var cards=player.getCards('h'); - if(cards.length>=3&&player.hp>=3) return 0; - for(var i=0;i= 3 && player.hp >= 3) return 0; + for (var i = 0; i < cards.length; i++) { + num += Math.max(0, get.value(cards[i], player, "raw")); } - return 16-num; - } + return 16 - num; + }, }, - threaten:1.6, - } + threaten: 1.6, + }, }, - gzyuejian:{ - trigger:{global:'phaseDiscardBegin'}, - audio:'yuejian', - preHidden:true, - filter:function(event,player){ - if(player.isFriendOf(event.player)){ - return event.player.getHistory('useCard',function(evt){ - if(evt.targets){ - var targets=evt.targets.slice(0); - while(targets.includes(event.player)) targets.remove(event.player); - return targets.length!=0; - } - return false; - })==0; + gzyuejian: { + trigger: { global: "phaseDiscardBegin" }, + audio: "yuejian", + preHidden: true, + filter: function (event, player) { + if (player.isFriendOf(event.player)) { + return ( + event.player.getHistory("useCard", function (evt) { + if (evt.targets) { + var targets = evt.targets.slice(0); + while (targets.includes(event.player)) targets.remove(event.player); + return targets.length != 0; + } + return false; + }) == 0 + ); } return false; }, - content:function(){ - trigger.player.addTempSkill('gzyuejian_num'); + content: function () { + trigger.player.addTempSkill("gzyuejian_num"); }, - logTarget:'player', - forced:true, - subSkill:{ - num:{ - mod:{ - maxHandcardBase:function(player,num){ + logTarget: "player", + forced: true, + subSkill: { + num: { + mod: { + maxHandcardBase: function (player, num) { return player.maxHp; - } - } + }, + }, }, - } - }, - gzxinsheng:{ - trigger:{player:'damageEnd'}, - // frequent:true, - content:function(){ - game.log(player,'获得了一张','#g化身'); - lib.skill.gzhuashen.addCharacter(player,_status.characterlist.randomGet(),true); - game.delayx(); - } - }, - gzhuashen:{ - unique:true, - group:['gzhuashen_add','gzhuashen_swap','gzhuashen_remove','gzhuashen_disallow','gzhuashen_flash'], - init:function(player){ - player.storage.gzhuashen=[]; - player.storage.gzhuashen_removing=[]; - player.storage.gzhuashen_trigger=[]; - player.storage.gzhuashen_map={}; }, - onremove:function(player){ + }, + gzxinsheng: { + trigger: { player: "damageEnd" }, + // frequent:true, + content: function () { + game.log(player, "获得了一张", "#g化身"); + lib.skill.gzhuashen.addCharacter(player, _status.characterlist.randomGet(), true); + game.delayx(); + }, + }, + gzhuashen: { + unique: true, + group: [ + "gzhuashen_add", + "gzhuashen_swap", + "gzhuashen_remove", + "gzhuashen_disallow", + "gzhuashen_flash", + ], + init: function (player) { + player.storage.gzhuashen = []; + player.storage.gzhuashen_removing = []; + player.storage.gzhuashen_trigger = []; + player.storage.gzhuashen_map = {}; + }, + onremove: function (player) { delete player.storage.gzhuashen; delete player.storage.gzhuashen_removing; delete player.storage.gzhuashen_trigger; delete player.storage.gzhuashen_map; }, - ondisable:true, - mark:true, - intro:{ - mark:function(dialog,storage,player){ - if(storage&&storage.length){ - if(player.isUnderControl(true)){ - dialog.addSmall([storage,'character']); - var skills=[]; - for(var i in player.storage.gzhuashen_map){ + ondisable: true, + mark: true, + intro: { + mark: function (dialog, storage, player) { + if (storage && storage.length) { + if (player.isUnderControl(true)) { + dialog.addSmall([storage, "character"]); + var skills = []; + for (var i in player.storage.gzhuashen_map) { skills.addArray(player.storage.gzhuashen_map[i]); } - dialog.addText('可用技能:'+(skills.length?get.translation(skills):'无')); + dialog.addText( + "可用技能:" + (skills.length ? get.translation(skills) : "无") + ); + } else { + return "共有" + get.cnNumber(storage.length) + "张“化身”"; } - else{ - return '共有'+get.cnNumber(storage.length)+'张“化身”' - } - } - else{ - return '没有化身'; + } else { + return "没有化身"; } }, - content:function(storage,player){ - if(player.isUnderControl(true)){ - var skills=[]; - for(var i in player.storage.gzhuashen_map){ + content: function (storage, player) { + if (player.isUnderControl(true)) { + var skills = []; + for (var i in player.storage.gzhuashen_map) { skills.addArray(player.storage.gzhuashen_map[i]); } - return get.translation(storage)+';可用技能:'+(skills.length?get.translation(skills):'无'); + return ( + get.translation(storage) + + ";可用技能:" + + (skills.length ? get.translation(skills) : "无") + ); + } else { + return "共有" + get.cnNumber(storage.length) + "张“化身”"; } - else{ - return '共有'+get.cnNumber(storage.length)+'张“化身”' - } - } + }, }, - filterSkill:function(name){ - var skills=lib.character[name][3].slice(0); - for(var i=0;i=2; }, - content:function(){ - 'step 0' - var list=player.storage.gzhuashen.slice(0); - if(!list.length){ + }, + swap: { + trigger: { player: "phaseBeginStart" }, + direct: true, + filter: function (event, player) { + if (player.hasSkill("gzhuashen_triggered")) return false; + return player.storage.gzhuashen.length >= 2; + }, + content: function () { + "step 0"; + var list = player.storage.gzhuashen.slice(0); + if (!list.length) { event.finish(); return; } - player.chooseButton().set('ai',function(){ - return Math.random()-0.3; - }).set('createDialog',['是否替换一张“化身”?',[list,'character']]); - 'step 1' - if(result.bool){ - player.logSkill('gzhuashen'); - game.log(player,'替换了一张','#g化身'); - lib.skill.gzhuashen.addCharacter(player,_status.characterlist.randomGet(),true); - lib.skill.gzhuashen.removeCharacter(player,result.links[0]); + player + .chooseButton() + .set("ai", function () { + return Math.random() - 0.3; + }) + .set("createDialog", ["是否替换一张“化身”?", [list, "character"]]); + "step 1"; + if (result.bool) { + player.logSkill("gzhuashen"); + game.log(player, "替换了一张", "#g化身"); + lib.skill.gzhuashen.addCharacter( + player, + _status.characterlist.randomGet(), + true + ); + lib.skill.gzhuashen.removeCharacter(player, result.links[0]); game.delayx(); } - } + }, }, - triggered:{}, - flash:{ - hookTrigger:{ - log:function(player,skill){ - var sources=lib.skill.gzhuashen.getSkillSources(player,skill); - if(sources.length){ - player.flashAvatar('gzhuashen',sources.randomGet()); + triggered: {}, + flash: { + hookTrigger: { + log: function (player, skill) { + var sources = lib.skill.gzhuashen.getSkillSources(player, skill); + if (sources.length) { + player.flashAvatar("gzhuashen", sources.randomGet()); player.storage.gzhuashen_removing.add(skill); } - } + }, }, - trigger:{player:['useSkillBegin','useCard','respond']}, - silent:true, - filter:function(event,player){ - return event.skill&&lib.skill.gzhuashen.getSkillSources(player,event.skill).length>0; + trigger: { player: ["useSkillBegin", "useCard", "respond"] }, + silent: true, + filter: function (event, player) { + return ( + event.skill && + lib.skill.gzhuashen.getSkillSources(player, event.skill).length > 0 + ); + }, + content: function () { + lib.skill.gzhuashen_flash.hookTrigger.log(player, trigger.skill); }, - content:function(){ - lib.skill.gzhuashen_flash.hookTrigger.log(player,trigger.skill); - } }, - clear:{ - trigger:{player:'phaseAfter'}, - silent:true, - content:function(){ - player.storage.gzhuashen_trigger.length=0; - } + clear: { + trigger: { player: "phaseAfter" }, + silent: true, + content: function () { + player.storage.gzhuashen_trigger.length = 0; + }, }, - disallow:{ - hookTrigger:{ - block:function(event,player,name,skill){ - for(var i=0;i0){ + disallow: { + hookTrigger: { + block: function (event, player, name, skill) { + for (var i = 0; i < player.storage.gzhuashen_trigger.length; i++) { + var info = player.storage.gzhuashen_trigger[i]; + if ( + info[0] == event && + info[1] == name && + lib.skill.gzhuashen.getSkillSources(player, skill).length > 0 + ) { return true; } } return false; - } - } + }, + }, }, - remove:{ - trigger:{player:['useSkillAfter','useCardAfter','respondAfter','triggerAfter','skillAfter']}, - hookTrigger:{ - after:function(event,player){ - if(event._direct&&!player.storage.gzhuashen_removing.includes(event.skill)) return false; - if(lib.skill[event.skill].silent) return false; - return lib.skill.gzhuashen.getSkillSources(player,event.skill).length>0; - } + remove: { + trigger: { + player: [ + "useSkillAfter", + "useCardAfter", + "respondAfter", + "triggerAfter", + "skillAfter", + ], }, - silent:true, - filter:function(event,player){ - return event.skill&&lib.skill.gzhuashen.getSkillSources(player,event.skill).length>0; + hookTrigger: { + after: function (event, player) { + if (event._direct && !player.storage.gzhuashen_removing.includes(event.skill)) + return false; + if (lib.skill[event.skill].silent) return false; + return lib.skill.gzhuashen.getSkillSources(player, event.skill).length > 0; + }, }, - content:function(){ - 'step 0' - if(trigger.name=='trigger'){ - player.storage.gzhuashen_trigger.push([trigger._trigger,trigger.triggername]); + silent: true, + filter: function (event, player) { + return ( + event.skill && + lib.skill.gzhuashen.getSkillSources(player, event.skill).length > 0 + ); + }, + content: function () { + "step 0"; + if (trigger.name == "trigger") { + player.storage.gzhuashen_trigger.push([ + trigger._trigger, + trigger.triggername, + ]); } - var sources=lib.skill.gzhuashen.getSkillSources(player,trigger.skill); - if(sources.length==1){ - event.directresult=sources[0]; + var sources = lib.skill.gzhuashen.getSkillSources(player, trigger.skill); + if (sources.length == 1) { + event.directresult = sources[0]; + } else { + player + .chooseButton(true) + .set("createDialog", ["移除一张“化身”牌", [sources, "character"]]); } - else{ - player.chooseButton(true).set('createDialog',['移除一张“化身”牌',[sources,'character']]); + "step 1"; + if (!event.directresult && result && result.links[0]) { + event.directresult = result.links[0]; } - 'step 1' - if(!event.directresult&&result&&result.links[0]){ - event.directresult=result.links[0]; - } - var name=event.directresult; - lib.skill.gzhuashen.removeCharacter(player,name); - game.log(player,'移除了化身牌','#g'+get.translation(name)); - } - } + var name = event.directresult; + lib.skill.gzhuashen.removeCharacter(player, name); + game.log(player, "移除了化身牌", "#g" + get.translation(name)); + }, + }, }, - ai:{ - nofrequent:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&player.storage.gzhuashen){ - if(lib.skill.gzhuashen.getSkillSources(player,arg).length>0){ + ai: { + nofrequent: true, + skillTagFilter: function (player, tag, arg) { + if (arg && player.storage.gzhuashen) { + if (lib.skill.gzhuashen.getSkillSources(player, arg).length > 0) { return true; } } return false; - } - } - }, - gzxiongsuan:{ - limited:true, - audio:'xiongsuan', - enable:'phaseUse', - filterCard:true, - filter:function(event,player){ - return player.countCards('h'); + }, }, - filterTarget:function(card,player,target){ + }, + gzxiongsuan: { + limited: true, + audio: "xiongsuan", + enable: "phaseUse", + filterCard: true, + filter: function (event, player) { + return player.countCards("h"); + }, + filterTarget: function (card, player, target) { return target.isFriendOf(player); }, - check:function(card){ - return 7-get.value(card); + check: function (card) { + return 7 - get.value(card); }, - content:function(){ - 'step 0' - player.awakenSkill('gzxiongsuan'); - target.damage('nocard'); - 'step 1' + content: function () { + "step 0"; + player.awakenSkill("gzxiongsuan"); + target.damage("nocard"); + "step 1"; player.draw(3); - var list=[]; - var skills=target.getOriginalSkills(); - for(var i=0;i 1) { + player.chooseControl(list).set("prompt", "选择一个限定技在回合结束后重置之"); + } else { event.finish(); } - else if(list.length>1){ - player.chooseControl(list).set('prompt','选择一个限定技在回合结束后重置之'); - } - else{ - event.finish(); - } - 'step 2' - target.storage.gzxiongsuan_restore=result.control; - target.addTempSkill('gzxiongsuan_restore'); + "step 2"; + target.storage.gzxiongsuan_restore = result.control; + target.addTempSkill("gzxiongsuan_restore"); }, - subSkill:{ - restore:{ - trigger:{global:'phaseEnd'}, - forced:true, - popup:false, - charlotte:true, - onremove:true, - content:function(){ + subSkill: { + restore: { + trigger: { global: "phaseEnd" }, + forced: true, + popup: false, + charlotte: true, + onremove: true, + content: function () { player.restoreSkill(player.storage.gzxiongsuan_restore); - } - } + }, + }, }, - ai:{ - order:4, - damage:true, - result:{ - target:function(player,target){ - if(target.hp>1){ - var skills=target.getOriginalSkills(); - for(var i=0;i 1) { + var skills = target.getOriginalSkills(); + for (var i = 0; i < skills.length; i++) { + if ( + lib.skill[skills[i]].limited && + target.awakenedSkills.includes(skills[i]) + ) { return 8; } } } - if(target!=player) return 0; - if(get.damageEffect(target,player,player)>=0) return 10; - if(target.hp>=4) return 5; - if(target.hp==3){ - if(player.countCards('h')<=2&&game.hasPlayer(function(current){ - return current.hp<=1&&get.attitude(player,current)<0; - })){ + if (target != player) return 0; + if (get.damageEffect(target, player, player) >= 0) return 10; + if (target.hp >= 4) return 5; + if (target.hp == 3) { + if ( + player.countCards("h") <= 2 && + game.hasPlayer(function (current) { + return current.hp <= 1 && get.attitude(player, current) < 0; + }) + ) { return 3; } } return 0; - } - } - } + }, + }, + }, }, - gzsuishi:{ - audio:'suishi', - preHidden:['gzsuishi2'], - trigger:{global:'dying'}, - forced:true, + gzsuishi: { + audio: "suishi", + preHidden: ["gzsuishi2"], + trigger: { global: "dying" }, + forced: true, //priority:6.5, - check:function(){ + check: function () { return false; }, - filter:function(event,player){ - return event.player!=player&&event.parent.name=='damage'&&event.parent.source&&event.parent.source.isFriendOf(player); + filter: function (event, player) { + return ( + event.player != player && + event.parent.name == "damage" && + event.parent.source && + event.parent.source.isFriendOf(player) + ); }, - content:function(){ + content: function () { player.draw(); }, - group:'gzsuishi2' + group: "gzsuishi2", }, - gzsuishi2:{ - audio:'suishi', - trigger:{global:'dieAfter'}, - forced:true, - check:function(){return false}, - filter:function(event,player){ + gzsuishi2: { + audio: "suishi", + trigger: { global: "dieAfter" }, + forced: true, + check: function () { + return false; + }, + filter: function (event, player) { return event.player.isFriendOf(player); }, - content:function(){ + content: function () { player.loseHp(); - } + }, }, - hongfa_respond:{ - audio:'huangjintianbingfu', - forceaudio:true, - trigger:{player:'chooseToRespondBegin'}, - direct:true, - filter:function(event,player){ - if(event.responded) return false; - if(!event.filterCard({name:'sha'})) return false; - var zhu=get.zhu(player,'hongfa'); - if(zhu&&zhu.getExpansions('huangjintianbingfu').length>0){ + hongfa_respond: { + audio: "huangjintianbingfu", + forceaudio: true, + trigger: { player: "chooseToRespondBegin" }, + direct: true, + filter: function (event, player) { + if (event.responded) return false; + if (!event.filterCard({ name: "sha" })) return false; + var zhu = get.zhu(player, "hongfa"); + if (zhu && zhu.getExpansions("huangjintianbingfu").length > 0) { return true; } return false; }, - content:function(){ - "step 0" - var zhu=get.zhu(player,'hongfa'); - player.chooseCardButton(get.prompt('huangjintianbingfu'),zhu.getExpansions('huangjintianbingfu')).set('ai',function(){ - if(_status.event.goon) return 1; - return 0; - }).set('goon',player.countCards('h','sha')==0); - "step 1" - if(result.bool){ - var card=result.links[0]; + content: function () { + "step 0"; + var zhu = get.zhu(player, "hongfa"); + player + .chooseCardButton( + get.prompt("huangjintianbingfu"), + zhu.getExpansions("huangjintianbingfu") + ) + .set("ai", function () { + if (_status.event.goon) return 1; + return 0; + }) + .set("goon", player.countCards("h", "sha") == 0); + "step 1"; + if (result.bool) { + var card = result.links[0]; trigger.untrigger(); - trigger.responded=true; - trigger.result={bool:true,card:{name:'sha'},cards:[card]}; - var zhu=get.zhu(player,'hongfa'); - player.logSkill('hongfa_respond',zhu); + trigger.responded = true; + trigger.result = { bool: true, card: { name: "sha" }, cards: [card] }; + var zhu = get.zhu(player, "hongfa"); + player.logSkill("hongfa_respond", zhu); } - } + }, }, - hongfa_use:{ - audio:'huangjintianbingfu', - forceaudio:true, - enable:'chooseToUse', - filter:function(event,player){ - if(!event.filterCard({name:'sha'},player)) return false; - var zhu=get.zhu(player,'hongfa'); - if(zhu&&zhu.getExpansions('huangjintianbingfu').length>0){ + hongfa_use: { + audio: "huangjintianbingfu", + forceaudio: true, + enable: "chooseToUse", + filter: function (event, player) { + if (!event.filterCard({ name: "sha" }, player)) return false; + var zhu = get.zhu(player, "hongfa"); + if (zhu && zhu.getExpansions("huangjintianbingfu").length > 0) { return true; } return false; }, - chooseButton:{ - dialog:function(event,player){ - var zhu=get.zhu(player,'hongfa'); - return ui.create.dialog('黄巾天兵符',zhu.getExpansions('huangjintianbingfu'),'hidden'); + chooseButton: { + dialog: function (event, player) { + var zhu = get.zhu(player, "hongfa"); + return ui.create.dialog( + "黄巾天兵符", + zhu.getExpansions("huangjintianbingfu"), + "hidden" + ); }, - backup:function(links,player){ + backup: function (links, player) { return { - filterCard:function(){return false}, - selectCard:-1, - viewAs:{name:'sha',cards:links}, - cards:links, - precontent:function(){ - var cards=lib.skill.hongfa_use_backup.cards; - event.result.cards=cards; - player.logSkill('hongfa_use',result.targets); - } - } + filterCard: function () { + return false; + }, + selectCard: -1, + viewAs: { name: "sha", cards: links }, + cards: links, + precontent: function () { + var cards = lib.skill.hongfa_use_backup.cards; + event.result.cards = cards; + player.logSkill("hongfa_use", result.targets); + }, + }; + }, + prompt: function (links, player) { + return "选择杀的目标"; }, - prompt:function(links,player){ - return '选择杀的目标'; - } }, - ai:{ - respondSha:true, - skillTagFilter:function(player){ - var zhu=get.zhu(player,'hongfa'); - if(zhu&&zhu.getExpansions('huangjintianbingfu').length>0){ + ai: { + respondSha: true, + skillTagFilter: function (player) { + var zhu = get.zhu(player, "hongfa"); + if (zhu && zhu.getExpansions("huangjintianbingfu").length > 0) { return true; } return false; }, - order:function(){ - return get.order({name:'sha'})-0.1; + order: function () { + return get.order({ name: "sha" }) - 0.1; }, - result:{ - player:function(player){ - if(player.countCards('h','sha')) return 0; + result: { + player: function (player) { + if (player.countCards("h", "sha")) return 0; return 1; - } - } - } - }, - hongfa:{ - audio:2, - derivation:'huangjintianbingfu', - unique:true, - forceunique:true, - lordSkill:true, - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - filter:function(event,player){ - return player.getExpansions('huangjintianbingfu').length==0&&get.population('qun')>0; - }, - content:function(){ - var cards=get.cards(get.population('qun')); - player.addToExpansion(cards,'gain2').gaintag.add('huangjintianbingfu'); - }, - ai:{ - threaten:2, - }, - group:'hongfa_hp', - global:['hongfa_use','hongfa_respond'], - subSkill:{ - hp:{ - audio:true, - trigger:{player:'loseHpBefore'}, - filter:function(event,player){ - return player.getExpansions('huangjintianbingfu').length>0; }, - direct:true, - content:function(){ - 'step 0' - player.chooseCardButton(get.prompt('hongfa'),player.getExpansions('huangjintianbingfu')).set('ai',function(){ - return 1; - }); - 'step 1' - if(result.bool){ - player.logSkill('huangjintianbingfu'); + }, + }, + }, + hongfa: { + audio: 2, + derivation: "huangjintianbingfu", + unique: true, + forceunique: true, + lordSkill: true, + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + filter: function (event, player) { + return ( + player.getExpansions("huangjintianbingfu").length == 0 && get.population("qun") > 0 + ); + }, + content: function () { + var cards = get.cards(get.population("qun")); + player.addToExpansion(cards, "gain2").gaintag.add("huangjintianbingfu"); + }, + ai: { + threaten: 2, + }, + group: "hongfa_hp", + global: ["hongfa_use", "hongfa_respond"], + subSkill: { + hp: { + audio: true, + trigger: { player: "loseHpBefore" }, + filter: function (event, player) { + return player.getExpansions("huangjintianbingfu").length > 0; + }, + direct: true, + content: function () { + "step 0"; + player + .chooseCardButton( + get.prompt("hongfa"), + player.getExpansions("huangjintianbingfu") + ) + .set("ai", function () { + return 1; + }); + "step 1"; + if (result.bool) { + player.logSkill("huangjintianbingfu"); player.loseToDiscardpile(result.links); trigger.cancel(); } - } - } - } + }, + }, + }, }, - wendao:{ - audio:2, - unique:true, - forceunique:true, - enable:'phaseUse', - usable:1, - filterCard:function(card){ - return get.name(card)!='taipingyaoshu'&&get.color(card)=='red'; + wendao: { + audio: 2, + unique: true, + forceunique: true, + enable: "phaseUse", + usable: 1, + filterCard: function (card) { + return get.name(card) != "taipingyaoshu" && get.color(card) == "red"; }, - position:'he', - check:function(card){ - return 6-get.value(card); + position: "he", + check: function (card) { + return 6 - get.value(card); }, - onChooseToUse:function(event){ - if(game.online) return; - event.set('wendao',function(){ - for(var i=0;i
                          • 当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
                          • 每当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
                          • 与你势力相同的角色可将一张“天兵”当【杀】使用或打出。',false) - } - } - }, - wuxin:{ - trigger:{player:'phaseDrawBegin1'}, - audio:2, - filter:function(event,player){ - return get.population('qun')>0; + dialog.addText( + '
                            • 当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
                            • 每当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
                            • 与你势力相同的角色可将一张“天兵”当【杀】使用或打出。', + false + ); + }, }, - content:function(){ - 'step 0' - var num=get.population('qun'); - if(player.hasSkill('huangjintianbingfu')){ - num+=player.getExpansions('huangjintianbingfu').length; + }, + wuxin: { + trigger: { player: "phaseDrawBegin1" }, + audio: 2, + filter: function (event, player) { + return get.population("qun") > 0; + }, + content: function () { + "step 0"; + var num = get.population("qun"); + if (player.hasSkill("huangjintianbingfu")) { + num += player.getExpansions("huangjintianbingfu").length; } - var cards=get.cards(num); + var cards = get.cards(num); game.cardsGotoOrdering(cards); - var next=player.chooseToMove('悟心:将卡牌以任意顺序置于牌堆顶'); - next.set('list',[['牌堆顶',cards]]); - next.set('processAI',function(list){ - var cards=list[0][1].slice(0); - cards.sort(function(a,b){ - return get.value(b)-get.value(a); + var next = player.chooseToMove("悟心:将卡牌以任意顺序置于牌堆顶"); + next.set("list", [["牌堆顶", cards]]); + next.set("processAI", function (list) { + var cards = list[0][1].slice(0); + cards.sort(function (a, b) { + return get.value(b) - get.value(a); }); return [cards]; - }) - 'step 1' - if(result.bool){ - var list=result.moved[0].slice(0); - while(list.length){ - ui.cardPile.insertBefore(list.pop(),ui.cardPile.firstChild); + }); + "step 1"; + if (result.bool) { + var list = result.moved[0].slice(0); + while (list.length) { + ui.cardPile.insertBefore(list.pop(), ui.cardPile.firstChild); } game.updateRoundNumber(); } - } + }, }, - zhangwu:{ - audio:2, - unique:true, - forceunique:true, - ai:{ - threaten:2, + zhangwu: { + audio: 2, + unique: true, + forceunique: true, + ai: { + threaten: 2, }, - trigger:{ - global:['loseAfter','cardsDiscardAfter','equipAfter'], + trigger: { + global: ["loseAfter", "cardsDiscardAfter", "equipAfter"], }, - forced:true, - filter:function(event,player){ - if(event.name=='equip'){ - if(player==event.player) return false; - if(event.card.name=='feilongduofeng'&&event.player.getCards('e').includes(event.card)) return true; - return event.player.hasHistory('lose',function(evt){ - if(evt.position!=ui.discardPile||evt.getParent().name!='equip') return false; - for(var i of evt.cards){ - if(i.name=='feilongduofeng'&&get.position(i,true)=='d') return true; + forced: true, + filter: function (event, player) { + if (event.name == "equip") { + if (player == event.player) return false; + if ( + event.card.name == "feilongduofeng" && + event.player.getCards("e").includes(event.card) + ) + return true; + return event.player.hasHistory("lose", function (evt) { + if (evt.position != ui.discardPile || evt.getParent().name != "equip") + return false; + for (var i of evt.cards) { + if (i.name == "feilongduofeng" && get.position(i, true) == "d") return true; } return false; - }) + }); } - if(event.name=='lose'&&(event.position!=ui.discardPile||event.getParent().name=='equip')) return false; - for(var i of event.cards){ - if(i.name=='feilongduofeng'&&get.position(i,true)=='d') return true; + if ( + event.name == "lose" && + (event.position != ui.discardPile || event.getParent().name == "equip") + ) + return false; + for (var i of event.cards) { + if (i.name == "feilongduofeng" && get.position(i, true) == "d") return true; } return false; }, - logTarget:function(event,player){ - if(event.name=='equip'&&event.card.name=='feilongduofeng'&&event.player.getCards('e').includes(event.card)) return event.player; + logTarget: function (event, player) { + if ( + event.name == "equip" && + event.card.name == "feilongduofeng" && + event.player.getCards("e").includes(event.card) + ) + return event.player; return []; }, - content:function(){ + content: function () { game.delayx(); - var cards=[]; - if(trigger.name=='equip'){ - if(trigger.card.name=='feilongduofeng'&&trigger.player.getCards('e').includes(trigger.card)) cards.push(trigger.card); - trigger.player.getHistory('lose',function(evt){ - if(evt.position!=ui.discardPile||evt.getParent()!=trigger) return false; - for(var i of evt.cards){ - if(i.name=='feilongduofeng'&&get.position(i,true)=='d') cards.push(i); + var cards = []; + if (trigger.name == "equip") { + if ( + trigger.card.name == "feilongduofeng" && + trigger.player.getCards("e").includes(trigger.card) + ) + cards.push(trigger.card); + trigger.player.getHistory("lose", function (evt) { + if (evt.position != ui.discardPile || evt.getParent() != trigger) return false; + for (var i of evt.cards) { + if (i.name == "feilongduofeng" && get.position(i, true) == "d") cards.push(i); } return false; - }) + }); } - if(trigger.name=='lose'){ - for(var i of trigger.cards){ - if(i.name=='feilongduofeng'&&get.position(i,true)=='d') cards.push(i); + if (trigger.name == "lose") { + for (var i of trigger.cards) { + if (i.name == "feilongduofeng" && get.position(i, true) == "d") cards.push(i); } } - var owner=get.owner(cards[0]); - if(owner) player.gain(cards,'give',owner,'bySelf'); - else player.gain(cards,'gain2'); + var owner = get.owner(cards[0]); + if (owner) player.gain(cards, "give", owner, "bySelf"); + else player.gain(cards, "gain2"); }, - group:'zhangwu_draw', - subSkill:{ - draw:{ - audio:'zhangwu', - trigger:{ - player:'loseEnd', - global:['equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], + group: "zhangwu_draw", + subSkill: { + draw: { + audio: "zhangwu", + trigger: { + player: "loseEnd", + global: [ + "equipEnd", + "addJudgeEnd", + "gainEnd", + "loseAsyncEnd", + "addToExpansionEnd", + ], }, - filter:function(event,player){ - if(event.name=='lose'&&event.getParent().name=='useCard') return false; - var evt=event.getl(player); - return evt&&evt.player==player&&evt.cards2.filter(function(i){ - return i.name=='feilongduofeng'&&get.owner(i)!=player; - }).length>0; + filter: function (event, player) { + if (event.name == "lose" && event.getParent().name == "useCard") return false; + var evt = event.getl(player); + return ( + evt && + evt.player == player && + evt.cards2.filter(function (i) { + return i.name == "feilongduofeng" && get.owner(i) != player; + }).length > 0 + ); }, - forced:true, - content:function(){ - 'step 0' - var cards=[],evt=trigger.getl(player); - cards.addArray(evt.cards2.filter(function(i){ - return i.name=='feilongduofeng'&&get.owner(i)!=player; - })); - player.showCards(cards,get.translation(player)+'发动了【章武】'); - for(var i of cards){ - var owner=get.owner(i); - if(owner) owner.lose(i,ui.cardPile)._triggered=null; - else{ + forced: true, + content: function () { + "step 0"; + var cards = [], + evt = trigger.getl(player); + cards.addArray( + evt.cards2.filter(function (i) { + return i.name == "feilongduofeng" && get.owner(i) != player; + }) + ); + player.showCards(cards, get.translation(player) + "发动了【章武】"); + for (var i of cards) { + var owner = get.owner(i); + if (owner) owner.lose(i, ui.cardPile)._triggered = null; + else { i.fix(); ui.cardPile.appendChild(i); } } - 'step 1' + "step 1"; player.draw(2); }, }, }, }, - shouyue:{ - unique:true, - forceunique:true, - group:'wuhujiangdaqi', - derivation:'wuhujiangdaqi', - mark:true, - lordSkill:true, + shouyue: { + unique: true, + forceunique: true, + group: "wuhujiangdaqi", + derivation: "wuhujiangdaqi", + mark: true, + lordSkill: true, }, - wuhujiangdaqi:{ - unique:true, - forceunique:true, - nopop:true, - mark:true, - intro:{ - content:"@
                              【武圣】
                              将“红色牌”改为“任意牌”
                              【咆哮】
                              增加描述“你使用的【杀】无视其他角色的防具”
                              【龙胆】
                              增加描述“你每发动一次‘龙胆’便摸一张牌”
                              【烈弓】
                              增加描述“你的攻击范围+1”
                              【铁骑】
                              将“一张明置的武将牌”改为“所有明置的武将牌”
                              ", - } - }, - jizhao:{ - derivation:'rerende', - unique:true, - audio:2, - enable:'chooseToUse', - mark:true, - skillAnimation:true, - animationColor:'fire', - init:function(player){ - player.storage.jizhao=false; + wuhujiangdaqi: { + unique: true, + forceunique: true, + nopop: true, + mark: true, + intro: { + content: + '@
                              【武圣】
                              将“红色牌”改为“任意牌”
                              【咆哮】
                              增加描述“你使用的【杀】无视其他角色的防具”
                              【龙胆】
                              增加描述“你每发动一次‘龙胆’便摸一张牌”
                              【烈弓】
                              增加描述“你的攻击范围+1”
                              【铁骑】
                              将“一张明置的武将牌”改为“所有明置的武将牌”
                              ', }, - filter:function(event,player){ - if(player.storage.jizhao) return false; - if(event.type=='dying'){ - if(player!=event.dying) return false; + }, + jizhao: { + derivation: "rerende", + unique: true, + audio: 2, + enable: "chooseToUse", + mark: true, + skillAnimation: true, + animationColor: "fire", + init: function (player) { + player.storage.jizhao = false; + }, + filter: function (event, player) { + if (player.storage.jizhao) return false; + if (event.type == "dying") { + if (player != event.dying) return false; return true; } return false; }, - content:function(){ - 'step 0' - player.awakenSkill('jizhao'); - player.storage.jizhao=true; - var num=player.maxHp-player.countCards('h'); - if(num>0){ + content: function () { + "step 0"; + player.awakenSkill("jizhao"); + player.storage.jizhao = true; + var num = player.maxHp - player.countCards("h"); + if (num > 0) { player.draw(num); } - 'step 1' - if(player.hp<2){ - player.recover(2-player.hp); + "step 1"; + if (player.hp < 2) { + player.recover(2 - player.hp); } - 'step 2' - player.removeSkill('wuhujiangdaqi'); - player.changeSkills(['rerende'],['shouyue']); + "step 2"; + player.removeSkill("wuhujiangdaqi"); + player.changeSkills(["rerende"], ["shouyue"]); }, - ai:{ - order:1, - skillTagFilter:function(player,arg,target){ - if(player!=target||player.storage.jizhao) return false; + ai: { + order: 1, + skillTagFilter: function (player, arg, target) { + if (player != target || player.storage.jizhao) return false; }, - save:true, - result:{ - player:10 + save: true, + result: { + player: 10, }, }, - intro:{ - content:'limited' - } + intro: { + content: "limited", + }, }, - gzshoucheng:{ - inherit:'shoucheng', - audio:'shoucheng', - preHidden:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - if(current==_status.currentPhase||!current.isFriendOf(player)) return false; - var evt=event.getl(current); - return evt&&evt.hs&&evt.hs.length&¤t.countCards('h')==0; + gzshoucheng: { + inherit: "shoucheng", + audio: "shoucheng", + preHidden: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + if (current == _status.currentPhase || !current.isFriendOf(player)) return false; + var evt = event.getl(current); + return evt && evt.hs && evt.hs.length && current.countCards("h") == 0; }); }, - content:function(){ - "step 0" - event.list=game.filterPlayer(function(current){ - if(current==_status.currentPhase||!current.isFriendOf(player)) return false; - var evt=trigger.getl(current); - return evt&&evt.hs&&evt.hs.length; - }).sortBySeat(_status.currentPhase); - "step 1" - var target=event.list.shift(); - event.target=target; - if(target.isAlive()&&target.countCards('h')==0){ - player.chooseBool(get.prompt2('gzshoucheng',target)).set('ai',function(){ - return get.attitude(_status.event.player,_status.event.getParent().target)>0; - }).setHiddenSkill(event.name); - } - else event.goto(3); - "step 2" - if(result.bool){ - player.logSkill(event.name,target); + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + if (current == _status.currentPhase || !current.isFriendOf(player)) return false; + var evt = trigger.getl(current); + return evt && evt.hs && evt.hs.length; + }) + .sortBySeat(_status.currentPhase); + "step 1"; + var target = event.list.shift(); + event.target = target; + if (target.isAlive() && target.countCards("h") == 0) { + player + .chooseBool(get.prompt2("gzshoucheng", target)) + .set("ai", function () { + return ( + get.attitude(_status.event.player, _status.event.getParent().target) > 0 + ); + }) + .setHiddenSkill(event.name); + } else event.goto(3); + "step 2"; + if (result.bool) { + player.logSkill(event.name, target); target.draw(); } - "step 3" - if(event.list.length) event.goto(1); + "step 3"; + if (event.list.length) event.goto(1); }, }, - gzyicheng:{ - audio:'yicheng', - trigger:{ - global:['useCardToPlayered','useCardToTargeted'], + gzyicheng: { + audio: "yicheng", + trigger: { + global: ["useCardToPlayered", "useCardToTargeted"], }, - preHidden:true, + preHidden: true, //frequent:true, - direct:true, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(event.name=='useCardToPlayered'&&!event.isFirstTarget) return false; - var target=lib.skill.gzyicheng.logTarget(event,player); - if(target==player) return true; - return target.inline(player)&&target.isAlive()&&player.hasSkill('gzyicheng'); + direct: true, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (event.name == "useCardToPlayered" && !event.isFirstTarget) return false; + var target = lib.skill.gzyicheng.logTarget(event, player); + if (target == player) return true; + return target.inline(player) && target.isAlive() && player.hasSkill("gzyicheng"); }, - logTarget:function(event,player){ - return event.name=='useCardToPlayered'?event.player:event.target; + logTarget: function (event, player) { + return event.name == "useCardToPlayered" ? event.player : event.target; }, - content:function(){ - 'step 0' - var target=lib.skill.gzyicheng.logTarget(trigger,player); - event.target=target; - target.chooseBool(get.prompt('gzyicheng'),'摸一张牌,然后弃置一张牌').set('frequentSkill','gzyicheng'); - 'step 1' - if(result.bool){ - player.logSkill('gzyicheng',target); + content: function () { + "step 0"; + var target = lib.skill.gzyicheng.logTarget(trigger, player); + event.target = target; + target + .chooseBool(get.prompt("gzyicheng"), "摸一张牌,然后弃置一张牌") + .set("frequentSkill", "gzyicheng"); + "step 1"; + if (result.bool) { + player.logSkill("gzyicheng", target); target.draw(); - target.chooseToDiscard('he',true); + target.chooseToDiscard("he", true); } }, }, - yicheng:{ - audio:2, - trigger:{global:'useCardToTargeted'}, - filter:function(event,player){ - return event.card.name=='sha'&&event.target.isFriendOf(player); + yicheng: { + audio: 2, + trigger: { global: "useCardToTargeted" }, + filter: function (event, player) { + return event.card.name == "sha" && event.target.isFriendOf(player); }, - preHidden:true, - logTarget:'target', - content:function(){ - 'step 0' + preHidden: true, + logTarget: "target", + content: function () { + "step 0"; trigger.target.draw(); - 'step 1' - trigger.target.chooseToDiscard('he',true); - } + "step 1"; + trigger.target.chooseToDiscard("he", true); + }, }, - gzjixi:{ - inherit:'jixi', - audio:'jixi', - mainSkill:true, - init:function(player){ - if(player.checkMainSkill('gzjixi')){ + gzjixi: { + inherit: "jixi", + audio: "jixi", + mainSkill: true, + init: function (player) { + if (player.checkMainSkill("gzjixi")) { player.removeMaxHp(); } - } + }, }, - ziliang:{ - audio:2, - trigger:{global:'damageEnd'}, - filter:function(event,player){ - return event.player.isIn()&&event.player.isFriendOf(player)&&player.getExpansions('tuntian').length; + ziliang: { + audio: 2, + trigger: { global: "damageEnd" }, + filter: function (event, player) { + return ( + event.player.isIn() && + event.player.isFriendOf(player) && + player.getExpansions("tuntian").length + ); }, - init:function(player){ - player.checkViceSkill('ziliang'); + init: function (player) { + player.checkViceSkill("ziliang"); }, - viceSkill:true, - direct:true, - content:function(){ - 'step 0' - player.chooseCardButton(get.prompt('ziliang',trigger.player),player.getExpansions('tuntian')).set('ai',function(button){ - return get.value(button.link); - }); - 'step 1' - if(result.bool){ - var card=result.links[0]; - player.logSkill('ziliang',trigger.player); - player.give(card,trigger.player); + viceSkill: true, + direct: true, + content: function () { + "step 0"; + player + .chooseCardButton( + get.prompt("ziliang", trigger.player), + player.getExpansions("tuntian") + ) + .set("ai", function (button) { + return get.value(button.link); + }); + "step 1"; + if (result.bool) { + var card = result.links[0]; + player.logSkill("ziliang", trigger.player); + player.give(card, trigger.player); } - } - }, - gzhuyuan:{ - audio:'huyuan', - trigger:{player:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('he')>0; }, - content:function(){ - 'step 0' - player.chooseCardTarget({ - filterCard:true, - position:'he', - filterTarget:function(card,player,target){ - if(player==target) return false; - var card=ui.selected.cards[0]; - if(get.type(card)!='equip') return true; - return target.canEquip(card); - }, - prompt:get.prompt2('gzhuyuan'), - complexSelect:true, - ai1:function(card){ - if(!_status.event.goon) return false; - var player=_status.event.player; - if(get.type(card)!='equip') return 0; - return 7.5-get.value(card); - }, - ai2:function(target){ - if(!_status.event.goon) return false; - var player=_status.event.player,card=ui.selected.cards[0]; - return get.effect(target,card,player,player); - }, - goon:game.hasPlayer(function(current){ - return get.effect(current,{name:'guohe_copy',position:'ej'},player,player)>0; + }, + gzhuyuan: { + audio: "huyuan", + trigger: { player: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return player.countCards("he") > 0; + }, + content: function () { + "step 0"; + player + .chooseCardTarget({ + filterCard: true, + position: "he", + filterTarget: function (card, player, target) { + if (player == target) return false; + var card = ui.selected.cards[0]; + if (get.type(card) != "equip") return true; + return target.canEquip(card); + }, + prompt: get.prompt2("gzhuyuan"), + complexSelect: true, + ai1: function (card) { + if (!_status.event.goon) return false; + var player = _status.event.player; + if (get.type(card) != "equip") return 0; + return 7.5 - get.value(card); + }, + ai2: function (target) { + if (!_status.event.goon) return false; + var player = _status.event.player, + card = ui.selected.cards[0]; + return get.effect(target, card, player, player); + }, + goon: game.hasPlayer(function (current) { + return ( + get.effect( + current, + { name: "guohe_copy", position: "ej" }, + player, + player + ) > 0 + ); + }), }) - }).setHiddenSkill('gzhuyuan'); - 'step 1' - if(result.bool){ - var target=result.targets[0],card=result.cards[0]; - player.logSkill('gzhuyuan',target); - if(get.type(card)=='equip'){ - player.$give(card,target,false); + .setHiddenSkill("gzhuyuan"); + "step 1"; + if (result.bool) { + var target = result.targets[0], + card = result.cards[0]; + player.logSkill("gzhuyuan", target); + if (get.type(card) == "equip") { + player.$give(card, target, false); game.delayx(); target.equip(card); - } - else{ - player.give(card,target); + } else { + player.give(card, target); event.finish(); } - } - else event.finish(); - 'step 2' - if(game.hasPlayer(function(current){ - return current.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,current); - },'ej'); - })){ - player.chooseTarget('是否弃置场上的一张牌?',function(card,player,target){ - return target.hasCard(function(card){ - return lib.filter.canBeDiscarded(card,player,target); - },'ej'); - }).set('ai',function(target){ - const player=_status.event.player; - return get.effect(target,{name:'guohe_copy',position:'ej'},player,player); + } else event.finish(); + "step 2"; + if ( + game.hasPlayer(function (current) { + return current.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, current); + }, "ej"); }) - } - else event.finish(); - 'step 3' - if(result.bool){ - var target=result.targets[0]; - player.line(target,'thunder'); - player.discardPlayerCard(target,true,'ej'); + ) { + player + .chooseTarget("是否弃置场上的一张牌?", function (card, player, target) { + return target.hasCard(function (card) { + return lib.filter.canBeDiscarded(card, player, target); + }, "ej"); + }) + .set("ai", function (target) { + const player = _status.event.player; + return get.effect( + target, + { name: "guohe_copy", position: "ej" }, + player, + player + ); + }); + } else event.finish(); + "step 3"; + if (result.bool) { + var target = result.targets[0]; + player.line(target, "thunder"); + player.discardPlayerCard(target, true, "ej"); } }, }, - huyuan:{ - audio:2, - trigger:{player:'phaseJieshuBegin'}, - direct:true, - preHidden:true, - filter:function(event,player){ - return player.countCards('he',{type:'equip'})>0; + huyuan: { + audio: 2, + trigger: { player: "phaseJieshuBegin" }, + direct: true, + preHidden: true, + filter: function (event, player) { + return player.countCards("he", { type: "equip" }) > 0; }, - content:function(){ - "step 0" - player.chooseCardTarget({ - filterCard:function(card){ - return get.type(card)=='equip'; - }, - position:'he', - filterTarget:function(card,player,target){ - return target.canEquip(card); - }, - ai1:function(card){ - return 6-get.value(card); - }, - ai2:function(target){ - return get.attitude(_status.event.player,target)-3; - }, - prompt:get.prompt2('huyuan') - }).setHiddenSkill('huyuan'); - "step 1" - if(result.bool){ - var target=result.targets[0]; - player.logSkill('huyuan',target); - event.current=target; + content: function () { + "step 0"; + player + .chooseCardTarget({ + filterCard: function (card) { + return get.type(card) == "equip"; + }, + position: "he", + filterTarget: function (card, player, target) { + return target.canEquip(card); + }, + ai1: function (card) { + return 6 - get.value(card); + }, + ai2: function (target) { + return get.attitude(_status.event.player, target) - 3; + }, + prompt: get.prompt2("huyuan"), + }) + .setHiddenSkill("huyuan"); + "step 1"; + if (result.bool) { + var target = result.targets[0]; + player.logSkill("huyuan", target); + event.current = target; target.equip(result.cards[0]); - if(target!=player){ - player.$give(result.cards,target,false); + if (target != player) { + player.$give(result.cards, target, false); game.delay(2); } - player.chooseTarget('弃置一名角色的一张牌',function(card,player,target){ - var source=_status.event.source; - return get.distance(source,target)<=1&&source!=target&&target.countCards('he'); - }).set('ai',function(target){ - var player=_status.event.player; - return get.effect(target,{name:'guohe_copy2'},player,player); - }).set('source',target); - } - else{ + player + .chooseTarget("弃置一名角色的一张牌", function (card, player, target) { + var source = _status.event.source; + return ( + get.distance(source, target) <= 1 && + source != target && + target.countCards("he") + ); + }) + .set("ai", function (target) { + var player = _status.event.player; + return get.effect(target, { name: "guohe_copy2" }, player, player); + }) + .set("source", target); + } else { event.finish(); } - "step 2" - if(result.bool&&result.targets.length){ - event.current.line(result.targets,'green'); - player.discardPlayerCard(true,result.targets[0],'he'); + "step 2"; + if (result.bool && result.targets.length) { + event.current.line(result.targets, "green"); + player.discardPlayerCard(true, result.targets[0], "he"); } }, }, - heyi:{ - zhenfa:'inline', - global:'heyi_distance' + heyi: { + zhenfa: "inline", + global: "heyi_distance", }, - heyi_distance:{ - mod:{ - globalTo:function(from,to,distance){ - if(game.hasPlayer(function(current){ - return current.hasSkill('heyi')&¤t.inline(to); - })){ - return distance+1; + heyi_distance: { + mod: { + globalTo: function (from, to, distance) { + if ( + game.hasPlayer(function (current) { + return current.hasSkill("heyi") && current.inline(to); + }) + ) { + return distance + 1; } - } - } - }, - tianfu:{ - init:function(player){ - player.checkMainSkill('tianfu'); - }, - mainSkill:true, - inherit:'kanpo', - zhenfa:'inline', - viewAsFilter:function(player){ - return _status.currentPhase&&_status.currentPhase.inline(player)&&!player.hasSkill('kanpo')&&player.countCards('h',{color:'black'})>0; + }, }, }, - yizhi:{ - init:function(player){ - if(player.checkViceSkill('yizhi')&&!player.viceChanged){ + tianfu: { + init: function (player) { + player.checkMainSkill("tianfu"); + }, + mainSkill: true, + inherit: "kanpo", + zhenfa: "inline", + viewAsFilter: function (player) { + return ( + _status.currentPhase && + _status.currentPhase.inline(player) && + !player.hasSkill("kanpo") && + player.countCards("h", { color: "black" }) > 0 + ); + }, + }, + yizhi: { + init: function (player) { + if (player.checkViceSkill("yizhi") && !player.viceChanged) { player.removeMaxHp(); } }, - viceSkill:true, - inherit:'guanxing', - filter:function(event,player){ - return !player.hasSkill('guanxing'); - } + viceSkill: true, + inherit: "guanxing", + filter: function (event, player) { + return !player.hasSkill("guanxing"); + }, }, - gzshangyi:{ - audio:'shangyi', - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return player.countCards('h')>0; + gzshangyi: { + audio: "shangyi", + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return player.countCards("h") > 0; }, - filterTarget:function(card,player,target){ - return player!=target&&(target.countCards('h')||target.isUnseen(2)); + filterTarget: function (card, player, target) { + return player != target && (target.countCards("h") || target.isUnseen(2)); }, - content:function(){ - "step 0" + content: function () { + "step 0"; target.viewHandcards(player); - "step 1" - if(!target.countCards('h')){ - event._result={index:1}; + "step 1"; + if (!target.countCards("h")) { + event._result = { index: 1 }; + } else if (!target.isUnseen(2)) { + event._result = { index: 0 }; + } else { + player + .chooseControl() + .set("choiceList", [ + "观看" + get.translation(target) + "的手牌并可以弃置其中的一张黑色牌", + "观看" + get.translation(target) + "的所有暗置的武将牌", + ]); } - else if(!target.isUnseen(2)){ - event._result={index:0}; - } - else{ - player.chooseControl().set('choiceList',[ - '观看'+get.translation(target)+'的手牌并可以弃置其中的一张黑色牌', - '观看'+get.translation(target)+'的所有暗置的武将牌', - ]); - } - "step 2" - if(result.index==0){ - player.discardPlayerCard(target,'h').set('filterButton',function(button){ - return get.color(button.link)=='black'; - }).set('visible',true); - } - else{ - player.viewCharacter(target,2); + "step 2"; + if (result.index == 0) { + player + .discardPlayerCard(target, "h") + .set("filterButton", function (button) { + return get.color(button.link) == "black"; + }) + .set("visible", true); + } else { + player.viewCharacter(target, 2); } }, - ai:{ - order:11, - result:{ - target:function(player,target){ - return -target.countCards('h'); - } + ai: { + order: 11, + result: { + target: function (player, target) { + return -target.countCards("h"); + }, }, - threaten:1.1 + threaten: 1.1, }, }, - niaoxiang:{ - zhenfa:'siege', - audio:'zniaoxiang', - global:'niaoxiang_sha', - preHidden:true, - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(event.card.name!='sha') return false; - if(game.countPlayer()<4) return false; - return player.siege(event.target)&&event.player.siege(event.target); + niaoxiang: { + zhenfa: "siege", + audio: "zniaoxiang", + global: "niaoxiang_sha", + preHidden: true, + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (event.card.name != "sha") return false; + if (game.countPlayer() < 4) return false; + return player.siege(event.target) && event.player.siege(event.target); }, - forced:true, - forceaudio:true, - logTarget:'target', - content:function(){ - var id=trigger.target.playerid; - var map=trigger.getParent().customArgs; - if(!map[id]) map[id]={}; - if(typeof map[id].shanRequired=='number'){ + forced: true, + forceaudio: true, + logTarget: "target", + content: function () { + var id = trigger.target.playerid; + var map = trigger.getParent().customArgs; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") { map[id].shanRequired++; + } else { + map[id].shanRequired = 2; } - else{ - map[id].shanRequired=2; - } - } - }, - fengshi:{ - audio:'zfengshi', - zhenfa:'siege', - trigger:{global:'useCardToPlayered'}, - filter:function(event,player){ - if(event.card.name!='sha'||game.countPlayer()<4) return false; - return player.siege(event.target)&&event.player.siege(event.target)&&event.target.countCards('e'); }, - logTarget:'target', - content:function(){ - trigger.target.chooseToDiscard('e',true); - } }, - gzguixiu:{ - audio:'guixiu', - trigger:{player:['showCharacterAfter','removeCharacterBefore']}, - filter:function(event,player){ - if(event.name=='removeCharacter'||event.name=='changeVice') return event.toRemove=='gz_mifuren'&&player.isDamaged(); - return event.toShow.includes('gz_mifuren'); + fengshi: { + audio: "zfengshi", + zhenfa: "siege", + trigger: { global: "useCardToPlayered" }, + filter: function (event, player) { + if (event.card.name != "sha" || game.countPlayer() < 4) return false; + return ( + player.siege(event.target) && + event.player.siege(event.target) && + event.target.countCards("e") + ); }, - content:function(){ - if(trigger.name=='showCharacter'){ + logTarget: "target", + content: function () { + trigger.target.chooseToDiscard("e", true); + }, + }, + gzguixiu: { + audio: "guixiu", + trigger: { player: ["showCharacterAfter", "removeCharacterBefore"] }, + filter: function (event, player) { + if (event.name == "removeCharacter" || event.name == "changeVice") + return event.toRemove == "gz_mifuren" && player.isDamaged(); + return event.toShow.includes("gz_mifuren"); + }, + content: function () { + if (trigger.name == "showCharacter") { player.draw(2); - } - else{ + } else { player.recover(); } }, }, - gzcunsi:{ - derivation:'gzyongjue', - enable:'phaseUse', - audio:'cunsi', - filter:function(event,player){ - return player.checkMainSkill('gzcunsi',false)||player.checkViceSkill('gzcunsi',false); + gzcunsi: { + derivation: "gzyongjue", + enable: "phaseUse", + audio: "cunsi", + filter: function (event, player) { + return player.checkMainSkill("gzcunsi", false) || player.checkViceSkill("gzcunsi", false); }, - unique:true, - forceunique:true, - filterTarget:true, - skillAnimation:true, - animationColor:'orange', - content:function(){ - 'step 0' - if(player.checkMainSkill('gzcunsi',false)){ + unique: true, + forceunique: true, + filterTarget: true, + skillAnimation: true, + animationColor: "orange", + content: function () { + "step 0"; + if (player.checkMainSkill("gzcunsi", false)) { player.removeCharacter(0); - } - else{ + } else { player.removeCharacter(1); } - 'step 1' - target.addSkills('gzyongjue'); - if(target!=player){ + "step 1"; + target.addSkills("gzyongjue"); + if (target != player) { target.draw(2); } }, - ai:{ - order:9, - result:{ - player:function(player,target){ - var num=0; - if(player.isDamaged()&&target.isFriendOf(player)){ + ai: { + order: 9, + result: { + player: function (player, target) { + var num = 0; + if (player.isDamaged() && target.isFriendOf(player)) { num++; - if(target.hasSkill('kanpo')) num+=0.5; - if(target.hasSkill('liegong')) num+=0.5; - if(target.hasSkill('tieji')) num+=0.5; - if(target.hasSkill('gzrende')) num+=1.2; - if(target.hasSkill('longdan')) num+=1.2; - if(target.hasSkill('paoxiao')) num+=1.2; - if(target.hasSkill('zhangwu')) num+=1.5; - if(target!=player) num+=0.5; + if (target.hasSkill("kanpo")) num += 0.5; + if (target.hasSkill("liegong")) num += 0.5; + if (target.hasSkill("tieji")) num += 0.5; + if (target.hasSkill("gzrende")) num += 1.2; + if (target.hasSkill("longdan")) num += 1.2; + if (target.hasSkill("paoxiao")) num += 1.2; + if (target.hasSkill("zhangwu")) num += 1.5; + if (target != player) num += 0.5; } return num; - } - } - } + }, + }, + }, }, - gzyongjue:{ - audio:'yongjue', - trigger:{global:'useCardAfter'}, - filter:function(event,player){ - if(event==event.player.getHistory('useCard')[0]&&event.card.name=='sha'&&_status.currentPhase==event.player&&event.player.isFriendOf(player)){ - for(var i=0;i0&&event.source&&event.source.isUnseen(2); + gzmingshi: { + audio: "mingshi", + trigger: { player: "damageBegin3" }, + forced: true, + preHidden: true, + filter: function (event, player) { + return event.num > 0 && event.source && event.source.isUnseen(2); }, - content:function(){ + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card,player,target){ - if(player.hasSkillTag('jueqing',false,target)) return; - if(!player.isUnseen(2)) return; - var num=get.tag(card,'damage'); - if(num){ - if(num>1) return 0.5; + ai: { + effect: { + target: function (card, player, target) { + if (player.hasSkillTag("jueqing", false, target)) return; + if (!player.isUnseen(2)) return; + var num = get.tag(card, "damage"); + if (num) { + if (num > 1) return 0.5; return 0; } - } - } + }, + }, }, }, - hunshang:{ - init:function(player){ - if(player.checkViceSkill('hunshang')&&!player.viceChanged){ + hunshang: { + init: function (player) { + if (player.checkViceSkill("hunshang") && !player.viceChanged) { player.removeMaxHp(); } }, - group:['hunshang_yingzi','hunshang_yinghun'], + group: ["hunshang_yingzi", "hunshang_yinghun"], }, - reyingzi_sunce:{audio:2}, - yinghun_sunce:{audio:2}, - hunshang_yingzi:{ - inherit:'yingzi', - audio:'reyingzi_sunce', - filter:function(event,player){ - return player.hp<=1&&!player.hasSkill('yingzi'); - } + reyingzi_sunce: { audio: 2 }, + yinghun_sunce: { audio: 2 }, + hunshang_yingzi: { + inherit: "yingzi", + audio: "reyingzi_sunce", + filter: function (event, player) { + return player.hp <= 1 && !player.hasSkill("yingzi"); + }, }, - hunshang_yinghun:{ - inherit:'yinghun', - audio:'yinghun_sunce', - filter:function(event,player){ - return player.hp<=1&&player.isDamaged()&&!player.hasSkill('yinghun'); - } + hunshang_yinghun: { + inherit: "yinghun", + audio: "yinghun_sunce", + filter: function (event, player) { + return player.hp <= 1 && player.isDamaged() && !player.hasSkill("yinghun"); + }, }, - yingyang:{ - audio:2, - trigger:{player:'compare',target:'compare'}, - filter:function(event){ + yingyang: { + audio: 2, + trigger: { player: "compare", target: "compare" }, + filter: function (event) { return !event.iwhile; }, - direct:true, - preHidden:true, - content:function(){ - 'step 0' - player.chooseControl('点数+3','点数-3','cancel2').set('prompt',get.prompt2('yingyang')).set('ai',function(){ - if(_status.event.small) return 1; - else return 0; - }).set('small',trigger.small); - 'step 1' - if(result.index!=2){ - player.logSkill('yingyang'); - if(result.index==0){ - game.log(player,'拼点牌点数+3'); - if(player==trigger.player){ - trigger.num1+=3; - if(trigger.num1>13) trigger.num1=13; + direct: true, + preHidden: true, + content: function () { + "step 0"; + player + .chooseControl("点数+3", "点数-3", "cancel2") + .set("prompt", get.prompt2("yingyang")) + .set("ai", function () { + if (_status.event.small) return 1; + else return 0; + }) + .set("small", trigger.small); + "step 1"; + if (result.index != 2) { + player.logSkill("yingyang"); + if (result.index == 0) { + game.log(player, "拼点牌点数+3"); + if (player == trigger.player) { + trigger.num1 += 3; + if (trigger.num1 > 13) trigger.num1 = 13; + } else { + trigger.num2 += 3; + if (trigger.num2 > 13) trigger.num2 = 13; } - else{ - trigger.num2+=3; - if(trigger.num2>13) trigger.num2=13; - } - } - else{ - game.log(player,'拼点牌点数-3'); - if(player==trigger.player){ - trigger.num1-=3; - if(trigger.num1<1) trigger.num1=1; - } - else{ - trigger.num2-=3; - if(trigger.num2<1) trigger.num2=1; + } else { + game.log(player, "拼点牌点数-3"); + if (player == trigger.player) { + trigger.num1 -= 3; + if (trigger.num1 < 1) trigger.num1 = 1; + } else { + trigger.num2 -= 3; + if (trigger.num2 < 1) trigger.num2 = 1; } } } - } + }, }, - gzqianxi:{ - audio:'qianxi', - trigger:{player:'phaseZhunbeiBegin'}, - content:function(){ - "step 0" + gzqianxi: { + audio: "qianxi", + trigger: { player: "phaseZhunbeiBegin" }, + content: function () { + "step 0"; player.judge(); - "step 1" - event.color=result.color; - player.chooseTarget(function(card,player,target){ - return player!=target&&get.distance(player,target)<=1; - },true).set('ai',function(target){ - return -get.attitude(_status.event.player,target); - }); - "step 2" - if(result.bool&&result.targets.length){ - result.targets[0].storage.qianxi2=event.color; - result.targets[0].addSkill('qianxi2'); - player.line(result.targets,'green'); - game.addVideo('storage',result.targets[0],['qianxi2',event.color]); + "step 1"; + event.color = result.color; + player + .chooseTarget(function (card, player, target) { + return player != target && get.distance(player, target) <= 1; + }, true) + .set("ai", function (target) { + return -get.attitude(_status.event.player, target); + }); + "step 2"; + if (result.bool && result.targets.length) { + result.targets[0].storage.qianxi2 = event.color; + result.targets[0].addSkill("qianxi2"); + player.line(result.targets, "green"); + game.addVideo("storage", result.targets[0], ["qianxi2", event.color]); } }, }, - gzduanchang:{ - audio:'duanchang', - trigger:{player:'die'}, - forced:true, - forceDie:true, - filter:function(event,player){ - return event.source&&event.source.isIn()&&event.source!=player&& - (event.source.hasMainCharacter()||event.source.hasViceCharacter()); + gzduanchang: { + audio: "duanchang", + trigger: { player: "die" }, + forced: true, + forceDie: true, + filter: function (event, player) { + return ( + event.source && + event.source.isIn() && + event.source != player && + (event.source.hasMainCharacter() || event.source.hasViceCharacter()) + ); }, - content:function(){ - 'step 0' - if(!trigger.source.hasViceCharacter()){ - event._result={control:'主将'} + content: function () { + "step 0"; + if (!trigger.source.hasViceCharacter()) { + event._result = { control: "主将" }; + } else if (!trigger.source.hasMainCharacter()) { + event._result = { control: "副将" }; + } else { + player + .chooseControl("主将", "副将", function () { + return _status.event.choice; + }) + .set( + "prompt", + "令" + get.translation(trigger.source) + "失去一张武将牌的所有技能" + ) + .set("forceDie", true) + .set( + "choice", + (function () { + var rank = + get.guozhanRank(trigger.source.name1, trigger.source) - + get.guozhanRank(trigger.source.name2, trigger.source); + if (rank == 0) rank = Math.random() > 0.5 ? 1 : -1; + return rank * get.attitude(player, trigger.source) > 0 ? "副将" : "主将"; + })() + ); } - else if(!trigger.source.hasMainCharacter()){ - event._result={control:'副将'} - } - else{ - player.chooseControl('主将','副将',function(){ - return _status.event.choice; - }).set('prompt','令'+get.translation(trigger.source)+'失去一张武将牌的所有技能').set('forceDie',true).set('choice',function(){ - var rank=get.guozhanRank(trigger.source.name1,trigger.source)-get.guozhanRank(trigger.source.name2,trigger.source); - if(rank==0) rank=Math.random()>0.5?1:-1; - return (rank*get.attitude(player,trigger.source))>0?'副将':'主将'; - }()); - } - 'step 1' + "step 1"; var skills; - if(result.control=='主将'){ + if (result.control == "主将") { trigger.source.showCharacter(0); - game.broadcastAll(function(player){ - player.node.avatar.classList.add('disabled'); - },trigger.source); - skills=lib.character[trigger.source.name][3]; - game.log(trigger.source,'失去了主将技能'); - } - else{ + game.broadcastAll(function (player) { + player.node.avatar.classList.add("disabled"); + }, trigger.source); + skills = lib.character[trigger.source.name][3]; + game.log(trigger.source, "失去了主将技能"); + } else { trigger.source.showCharacter(1); - game.broadcastAll(function(player){ - player.node.avatar2.classList.add('disabled'); - },trigger.source); - skills=lib.character[trigger.source.name2][3]; - game.log(trigger.source,'失去了副将技能'); + game.broadcastAll(function (player) { + player.node.avatar2.classList.add("disabled"); + }, trigger.source); + skills = lib.character[trigger.source.name2][3]; + game.log(trigger.source, "失去了副将技能"); } - var list=[]; - for(var i=0;i2) return 0; - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du') return 0; - if(!ui.selected.cards.length&&card.name=='du') return 20; - var player=get.owner(card); - if(player.hp==player.maxHp||player.storage.gzrende<0||player.countCards('h')+player.storage.gzrende<=2){ - if(ui.selected.cards.length){ + }, + gzrende: { + audio: "rende", + group: ["gzrende1"], + enable: "phaseUse", + filterCard: true, + selectCard: [1, Infinity], + discard: false, + prepare: "give", + filterTarget: function (card, player, target) { + return player != target; + }, + check: function (card) { + if (ui.selected.cards.length > 2) return 0; + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; + if (!ui.selected.cards.length && card.name == "du") return 20; + var player = get.owner(card); + if ( + player.hp == player.maxHp || + player.storage.gzrende < 0 || + player.countCards("h") + player.storage.gzrende <= 2 + ) { + if (ui.selected.cards.length) { return -1; } - var players=game.filterPlayer(); - for(var i=0;i=3&& - get.attitude(players[i],player)>=3){ - return 11-get.value(card); + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hasSkill("haoshi") && + !players[i].isTurnedOver() && + !players[i].hasJudge("lebu") && + get.attitude(player, players[i]) >= 3 && + get.attitude(players[i], player) >= 3 + ) { + return 11 - get.value(card); } } - if(player.countCards('h')>player.hp) return 10-get.value(card); - if(player.countCards('h')>2) return 6-get.value(card); + if (player.countCards("h") > player.hp) return 10 - get.value(card); + if (player.countCards("h") > 2) return 6 - get.value(card); return -1; } - return 10-get.value(card); + return 10 - get.value(card); }, - content:function(){ - target.gain(cards,player); - if(typeof player.storage.gzrende!='number'){ - player.storage.gzrende=0; + content: function () { + target.gain(cards, player); + if (typeof player.storage.gzrende != "number") { + player.storage.gzrende = 0; } - if(player.storage.gzrende>=0){ - player.storage.gzrende+=cards.length; - if(player.storage.gzrende>=3){ + if (player.storage.gzrende >= 0) { + player.storage.gzrende += cards.length; + if (player.storage.gzrende >= 3) { player.recover(); - player.storage.gzrende=-1; + player.storage.gzrende = -1; } } }, - ai:{ - order:function(skill,player){ - if(player.hp==player.maxHp||player.storage.gzrende<0||player.countCards('h')+player.storage.gzrende<=2){ + ai: { + order: function (skill, player) { + if ( + player.hp == player.maxHp || + player.storage.gzrende < 0 || + player.countCards("h") + player.storage.gzrende <= 2 + ) { return 1; } return 10; }, - result:{ - target:function(player,target){ - if(ui.selected.cards.length&&ui.selected.cards[0].name=='du'){ + result: { + target: function (player, target) { + if (ui.selected.cards.length && ui.selected.cards[0].name == "du") { return -10; } - if(target.hasJudge('lebu')) return 0; - var nh=target.countCards('h'); - var np=player.countCards('h'); - if(player.hp==player.maxHp||player.storage.gzrende<0||player.countCards('h')+player.storage.gzrende<=2){ - if(nh>=np-1&&np<=player.hp&&!target.hasSkill('haoshi')) return 0; + if (target.hasJudge("lebu")) return 0; + var nh = target.countCards("h"); + var np = player.countCards("h"); + if ( + player.hp == player.maxHp || + player.storage.gzrende < 0 || + player.countCards("h") + player.storage.gzrende <= 2 + ) { + if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0; } - return Math.max(1,5-nh); - } + return Math.max(1, 5 - nh); + }, }, - effect:{ - target:function(card,player,target){ - if(player==target&&get.type(card)=='equip'){ - if(player.countCards('e',{subtype:get.subtype(card)})){ - var players=game.filterPlayer(); - for(var i=0;i0){ + effect: { + target: function (card, player, target) { + if (player == target && get.type(card) == "equip") { + if (player.countCards("e", { subtype: get.subtype(card) })) { + var players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if (players[i] != player && get.attitude(player, players[i]) > 0) { return 0; } } } } - } + }, }, - threaten:0.8 - } + threaten: 0.8, + }, }, - gzrende1:{ - trigger:{player:'phaseUseBegin'}, - silent:true, - content:function(){ - player.storage.gzrende=0; - } + gzrende1: { + trigger: { player: "phaseUseBegin" }, + silent: true, + content: function () { + player.storage.gzrende = 0; + }, }, - gzzhiheng:{ - inherit:'zhiheng', - audio:'zhiheng', - selectCard:function(){ - var player=_status.event.player; - var range1=[1,player.maxHp]; - if(player.hasSkill('dinglanyemingzhu_skill')){ - for(var i=0;i0; + complexCard: true, + complexSelect: true, + prompt: function () { + var player = _status.event.player; + if (player.hasSkill("dinglanyemingzhu_skill")) + return "出牌阶段限一次,你可以弃置任意张牌,然后摸等量的牌"; + return "出牌阶段限一次,你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌"; }, - check:function(card){ - return 5-get.value(card); - } }, - gzxiaoguo:{ - inherit:'xiaoguo', - audio:'xiaoguo', - preHidden:true, - content:function(){ - "step 0" - var nono=(Math.abs(get.attitude(player,trigger.player))<3); - if(get.damageEffect(trigger.player,player,player)<=0){ - nono=true; + duoshi: { + enable: "chooseToUse", + viewAs: { name: "yiyi" }, + usable: 4, + filterCard: { color: "red" }, + position: "hs", + viewAsFilter: function (player) { + return player.countCards("hs", { color: "red" }) > 0; + }, + check: function (card) { + return 5 - get.value(card); + }, + }, + gzxiaoguo: { + inherit: "xiaoguo", + audio: "xiaoguo", + preHidden: true, + content: function () { + "step 0"; + var nono = Math.abs(get.attitude(player, trigger.player)) < 3; + if (get.damageEffect(trigger.player, player, player) <= 0) { + nono = true; } - var next=player.chooseToDiscard(get.prompt2('gzxiaoguo',trigger.player),{type:'basic'}); - next.set('ai',function(card){ - if(_status.event.nono) return 0; - return 8-get.useful(card); + var next = player.chooseToDiscard(get.prompt2("gzxiaoguo", trigger.player), { + type: "basic", }); - next.set('logSkill',['gzxiaoguo',trigger.player]); - next.set('nono',nono); - next.setHiddenSkill('gzxiaoguo'); - "step 1" - if(result.bool){ - var nono=(get.damageEffect(trigger.player,player,trigger.player)>=0); - trigger.player.chooseToDiscard('弃置一张装备牌,或受到1点伤害','he',{type:'equip'}).set('ai',function(card){ - if(_status.event.nono){ - return 0; - } - if(_status.event.player.hp==1) return 10-get.value(card); - return 9-get.value(card); - }).set('nono',nono); - } - else{ + next.set("ai", function (card) { + if (_status.event.nono) return 0; + return 8 - get.useful(card); + }); + next.set("logSkill", ["gzxiaoguo", trigger.player]); + next.set("nono", nono); + next.setHiddenSkill("gzxiaoguo"); + "step 1"; + if (result.bool) { + var nono = get.damageEffect(trigger.player, player, trigger.player) >= 0; + trigger.player + .chooseToDiscard("弃置一张装备牌,或受到1点伤害", "he", { type: "equip" }) + .set("ai", function (card) { + if (_status.event.nono) { + return 0; + } + if (_status.event.player.hp == 1) return 10 - get.value(card); + return 9 - get.value(card); + }) + .set("nono", nono); + } else { event.finish(); } - "step 2" - if(!result.bool){ + "step 2"; + if (!result.bool) { trigger.player.damage(); } }, }, - _mingzhi1:{ - trigger:{player:'phaseBeginStart'}, + _mingzhi1: { + trigger: { player: "phaseBeginStart" }, //priority:19, - ruleSkill:true, - forced:true, - popup:false, - filter:function(event,player){ - return player.isUnseen(2)&&!player.hasSkillTag('nomingzhi',false,null,true); + ruleSkill: true, + forced: true, + popup: false, + filter: function (event, player) { + return player.isUnseen(2) && !player.hasSkillTag("nomingzhi", false, null, true); }, - content:function(){ - 'step 0' - if(player.phaseNumber==1&&player.isUnseen(0)&&(_status.connectMode?lib.configOL.junzhu:get.config('junzhu'))){ - var name=player.name1; - if(name.indexOf('gz_')!=0||!lib.junList.includes(name.slice(3))){ + content: function () { + "step 0"; + if ( + player.phaseNumber == 1 && + player.isUnseen(0) && + (_status.connectMode ? lib.configOL.junzhu : get.config("junzhu")) + ) { + var name = player.name1; + if (name.indexOf("gz_") != 0 || !lib.junList.includes(name.slice(3))) { event.goto(3); + } else { + event.junzhu_name = "gz_jun_" + name.slice(3); + player.chooseBool( + "是否将主武将牌替换为“" + get.translation(event.junzhu_name) + "”?" + ); } - else{ - event.junzhu_name='gz_jun_'+name.slice(3); - player.chooseBool('是否将主武将牌替换为“'+get.translation(event.junzhu_name)+'”?'); - } - } - else event.goto(3); - 'step 1' - if(result.bool){ - var to=event.junzhu_name; - event.maxHp=player.maxHp; - player.reinit(player.name1,to,4); - if(lib.skill[to]) game.trySkillAudio(to,player); + } else event.goto(3); + "step 1"; + if (result.bool) { + var to = event.junzhu_name; + event.maxHp = player.maxHp; + player.reinit(player.name1, to, 4); + if (lib.skill[to]) game.trySkillAudio(to, player); player.showCharacter(0); - var group=lib.character[to][1]; - var yelist=game.filterPlayer(function(current){ - if(current.identity!='ye') return false; - if(current==player) return true; - return current.group==group; + var group = lib.character[to][1]; + var yelist = game.filterPlayer(function (current) { + if (current.identity != "ye") return false; + if (current == player) return true; + return current.group == group; }); - if(yelist.length>0){ - player.line(yelist,'green'); - game.log(yelist,'失去了野心家身份'); - game.broadcastAll(function(list,group){ - for(var i=0;i 0) { + player.line(yelist, "green"); + game.log(yelist, "失去了野心家身份"); + game.broadcastAll( + function (list, group) { + for (var i = 0; i < list.length; i++) { + list[i].identity = group; + list[i].group = group; + list[i].setIdentity(); + } + }, + yelist, + player.group + ); } game.tryResult(); - } - else event.goto(3); - 'step 2' - if(player.maxHp>event.maxHp) player.recover(player.maxHp-event.maxHp); - 'step 3' - var choice=1; - for(var i=0;i event.maxHp) player.recover(player.maxHp - event.maxHp); + "step 3"; + var choice = 1; + for (var i = 0; i < player.hiddenSkills.length; i++) { + if (lib.skill[player.hiddenSkills[i]].ai) { + var mingzhi = lib.skill[player.hiddenSkills[i]].ai.mingzhi; + if (mingzhi == false) { + choice = 0; + break; } - if(typeof mingzhi=='function'&&mingzhi(trigger,player)==false){ - choice=0;break; + if (typeof mingzhi == "function" && mingzhi(trigger, player) == false) { + choice = 0; + break; } } } - if(player.isUnseen()){ - var group=lib.character[player.name1][1]; - player.chooseControl('bumingzhi','明置'+get.translation(player.name1), - '明置'+get.translation(player.name2),'tongshimingzhi',true).ai=function(event,player){ - if(player.hasSkillTag('mingzhi_yes')) return get.rand(1,2); - if(player.hasSkillTag('mingzhi_no')) return 0; - var popu=get.population(lib.character[player.name1][1]) - if(popu>=2||(popu==1&&game.players.length<=4)){ - return Math.random()<0.5?3:(Math.random()<0.5?2:1); + if (player.isUnseen()) { + var group = lib.character[player.name1][1]; + player.chooseControl( + "bumingzhi", + "明置" + get.translation(player.name1), + "明置" + get.translation(player.name2), + "tongshimingzhi", + true + ).ai = function (event, player) { + if (player.hasSkillTag("mingzhi_yes")) return get.rand(1, 2); + if (player.hasSkillTag("mingzhi_no")) return 0; + var popu = get.population(lib.character[player.name1][1]); + if (popu >= 2 || (popu == 1 && game.players.length <= 4)) { + return Math.random() < 0.5 ? 3 : Math.random() < 0.5 ? 2 : 1; } - if(choice==0) return 0; - if(get.population(group)>0&&player.wontYe()){ - return Math.random()<0.2?(Math.random()<0.5?3:(Math.random()<0.5?2:1)):0; + if (choice == 0) return 0; + if (get.population(group) > 0 && player.wontYe()) { + return Math.random() < 0.2 + ? Math.random() < 0.5 + ? 3 + : Math.random() < 0.5 + ? 2 + : 1 + : 0; } - var nming=0; - for(var i=0;i=2||(popu==1&&game.players.length<=4)){ + } else { + event.skillHidden = true; + var bool1 = game.expandSkills(lib.character[player.name1][3]).includes(trigger.skill); + var bool2 = game.expandSkills(lib.character[player.name2][3]).includes(trigger.skill); + var nai = function () { + var player = _status.event.player; + if (!_status.event.yes) return false; + if (player.hasSkillTag("mingzhi_no")) return false; + if (player.hasSkillTag("mingzhi_yes")) return true; + if (player.identity != "unknown") return true; + if (Math.random() < 0.5) return true; + var info = get.info(_status.event.hsskill); + if (info && info.ai && info.ai.mingzhi == true) return true; + if (info && info.ai && info.ai.maixie) return true; + var group = lib.character[player.name1][1]; + var popu = get.population(lib.character[player.name1][1]); + if (popu >= 2 || (popu == 1 && game.players.length <= 4)) { return true; } - if(get.population(group)>0&&player.wontYe()){ - return Math.random()<0.2?true:false; + if (get.population(group) > 0 && player.wontYe()) { + return Math.random() < 0.2 ? true : false; } - var nming=0; - for(var i=0;i0){ - target.chooseControl(list,'cancel2').set('prompt','是否响应'+get.translation(player)+'发起的阵法召唤?').set('ai',function(){ - return Math.random()<0.5?0:1; - }); - } - else event.goto(3); - } - else event.goto(3); - 'step 2' - if(result.control!='cancel2'){ - if(result.control=='明置'+get.translation(target.name1)){ + content: function () { + "step 0"; + event.list = game + .filterPlayer(function (current) { + return current.isUnseen(); + }) + .sortBySeat(); + "step 1"; + var target = event.list.shift(); + event.target = target; + if ( + target.wontYe(player.identity) && + lib.skill._zhenfazhaohuan.getConfig(player, target) + ) { + player.line(target, "green"); + var list = []; + if (target.getGuozhanGroup(0) == player.identity) + list.push("明置" + get.translation(target.name1)); + if (target.getGuozhanGroup(1) == player.identity) + list.push("明置" + get.translation(target.name2)); + if (list.length > 0) { + target + .chooseControl(list, "cancel2") + .set("prompt", "是否响应" + get.translation(player) + "发起的阵法召唤?") + .set("ai", function () { + return Math.random() < 0.5 ? 0 : 1; + }); + } else event.goto(3); + } else event.goto(3); + "step 2"; + if (result.control != "cancel2") { + if (result.control == "明置" + get.translation(target.name1)) { target.showCharacter(0); - } - else{ + } else { target.showCharacter(1); } } - 'step 3' - if(event.list.length) event.goto(1); - 'step 4' + "step 3"; + if (event.list.length) event.goto(1); + "step 4"; game.delay(); }, - ai:{ - order:5, - result:{ - player:1 - } - } + ai: { + order: 5, + result: { + player: 1, + }, + }, }, - ushio_huanxin:{ - trigger:{ - player:['damageEnd','useCardAfter'], - source:'damageSource', + ushio_huanxin: { + trigger: { + player: ["damageEnd", "useCardAfter"], + source: "damageSource", }, - frequent:true, - preHidden:true, - filter:function(event,player,name){ - if(name=='useCardAfter') return get.type(event.card)=='equip'; - if(name=='damageEnd') return true; - return event.getParent().name=='sha'; + frequent: true, + preHidden: true, + filter: function (event, player, name) { + if (name == "useCardAfter") return get.type(event.card) == "equip"; + if (name == "damageEnd") return true; + return event.getParent().name == "sha"; }, - content:function(){ - player.judge().set('callback',function(){ - var card=event.judgeResult.card; - if(card&&get.position(card,true)=='o'){ - player.gain(card,'gain2'); - player.chooseToDiscard(true,'he'); + content: function () { + player.judge().set("callback", function () { + var card = event.judgeResult.card; + if (card && get.position(card, true) == "o") { + player.gain(card, "gain2"); + player.chooseToDiscard(true, "he"); } }); }, }, - ushio_xilv:{ - trigger:{player:'judgeEnd'}, - forced:true, - preHidden:true, - content:function(){ - player.addTempSkill('ushio_xilv2',{player:'phaseJieshu'}); - player.addMark('ushio_xilv2',1,false); + ushio_xilv: { + trigger: { player: "judgeEnd" }, + forced: true, + preHidden: true, + content: function () { + player.addTempSkill("ushio_xilv2", { player: "phaseJieshu" }); + player.addMark("ushio_xilv2", 1, false); }, }, - ushio_xilv2:{ - onremove:true, - charlotte:true, - mod:{ - maxHandcard:function(player,num){ - return num+player.countMark('ushio_xilv2'); - } + ushio_xilv2: { + onremove: true, + charlotte: true, + mod: { + maxHandcard: function (player, num) { + return num + player.countMark("ushio_xilv2"); + }, }, - intro:{ - content:'手牌上限+#', + intro: { + content: "手牌上限+#", }, }, }, - game:{ - canReplaceViewpoint:()=>true, - showYexings:function(){ - if(_status.showYexings) return; - _status.showYexings=true; - var next=game.createEvent('showYexings',false); - next.setContent(function(){ - 'step 0' - event.targets=game.filterPlayer(function(current){ - return lib.character[current.name1][1]=='ye'; - }).sortBySeat(_status.currentPhase); - event.targets2=[]; - 'step 1' - var target=targets.shift(); - event.target=target; - target.chooseBool('是否【暴露野心】,展示主将并继续战斗?','若选择“否”,则视为本局游戏失败'); - 'step 2' - if(result.bool){ + game: { + canReplaceViewpoint: () => true, + showYexings: function () { + if (_status.showYexings) return; + _status.showYexings = true; + var next = game.createEvent("showYexings", false); + next.setContent(function () { + "step 0"; + event.targets = game + .filterPlayer(function (current) { + return lib.character[current.name1][1] == "ye"; + }) + .sortBySeat(_status.currentPhase); + event.targets2 = []; + "step 1"; + var target = targets.shift(); + event.target = target; + target.chooseBool( + "是否【暴露野心】,展示主将并继续战斗?", + "若选择“否”,则视为本局游戏失败" + ); + "step 2"; + if (result.bool) { event.targets2.push(target); - target.$fullscreenpop('暴露野心','thunder'); - game.log(target,'暴露了野心'); + target.$fullscreenpop("暴露野心", "thunder"); + game.log(target, "暴露了野心"); target.showCharacter(0); game.delay(2); - if(targets.length) event.goto(1); - } - else{ - if(targets.length) event.goto(1); - else{ - var winner=game.findPlayer(function(current){ - return lib.character[current.name1][1]!='ye'; + if (targets.length) event.goto(1); + } else { + if (targets.length) event.goto(1); + else { + var winner = game.findPlayer(function (current) { + return lib.character[current.name1][1] != "ye"; }); - if(winner){ - game.broadcastAll(function(id){ - game.winner_id=id; - },winner.playerid); + if (winner) { + game.broadcastAll(function (id) { + game.winner_id = id; + }, winner.playerid); game.checkResult(); } delete _status.showYexings; event.finish(); } } - 'step 3' - var source=event.targets2.shift(); - event.source=source; - event.targets3=[]; + "step 3"; + var source = event.targets2.shift(); + event.source = source; + event.targets3 = []; //event.targets4=[source]; - if(!_status.yexinjia_list) _status.yexinjia_list=['夏','商','周','秦','汉','隋','唐','宋','辽','金','元','明']; - source.chooseControl(_status.yexinjia_list).set('prompt','请选择自己所属的野心家势力的标识').set('ai',()=>(_status.yexinjia_list?_status.yexinjia_list.randomGet():0)); - 'step 4' - var text,source=event.source; - if(result.control){ - text=result.control; + if (!_status.yexinjia_list) + _status.yexinjia_list = [ + "夏", + "商", + "周", + "秦", + "汉", + "隋", + "唐", + "宋", + "辽", + "金", + "元", + "明", + ]; + source + .chooseControl(_status.yexinjia_list) + .set("prompt", "请选择自己所属的野心家势力的标识") + .set("ai", () => (_status.yexinjia_list ? _status.yexinjia_list.randomGet() : 0)); + "step 4"; + var text, + source = event.source; + if (result.control) { + text = result.control; _status.yexinjia_list.remove(result.control); - } - else text=_status.yexinjia_list.randomRemove(); + } else text = _status.yexinjia_list.randomRemove(); lib.group.push(text); - lib.translate[text+'2']=text; - lib.groupnature[text]='kami'; - event.text=text; - game.broadcastAll(function(player,text){ - player.identity=text; - player.setIdentity(text,'kami'); - },source,text); + lib.translate[text + "2"] = text; + lib.groupnature[text] = "kami"; + event.text = text; + game.broadcastAll( + function (player, text) { + player.identity = text; + player.setIdentity(text, "kami"); + }, + source, + text + ); source.changeGroup(text); - source.removeMark('yexinjia_mark',1); - var targets=game.filterPlayer(function(current){ - return current.identity!='ye'&¤t!=source&&!get.is.jun(current)&&!event.targets2.includes(current)&&!current.getStorage('yexinjia_friend').length; + source.removeMark("yexinjia_mark", 1); + var targets = game.filterPlayer(function (current) { + return ( + current.identity != "ye" && + current != source && + !get.is.jun(current) && + !event.targets2.includes(current) && + !current.getStorage("yexinjia_friend").length + ); }); - if(!targets.length) event.goto(8); - else event.targets=targets; - 'step 5' - var source=event.source; - var target=targets.shift(); - event.target=target; - source.line(target,'green'); - target.chooseBool('是否响应'+get.translation(source)+'发起的【拉拢人心】?','将势力改为'+event.text).set('ai',_status.event.choice).set('choice',function(){ - let fs=target.getFriends(true).length; - if(game.players.length<=2*fs) return false; - if(source.getFriends(true).length+fs>game.players.length/2) return true; - if(target.isDamaged()||target.countCards('h')<4) return false; - return true; - }()); - 'step 6' - if(result.bool){ - target.chat('加入'); + if (!targets.length) event.goto(8); + else event.targets = targets; + "step 5"; + var source = event.source; + var target = targets.shift(); + event.target = target; + source.line(target, "green"); + target + .chooseBool( + "是否响应" + get.translation(source) + "发起的【拉拢人心】?", + "将势力改为" + event.text + ) + .set("ai", _status.event.choice) + .set( + "choice", + (function () { + let fs = target.getFriends(true).length; + if (game.players.length <= 2 * fs) return false; + if (source.getFriends(true).length + fs > game.players.length / 2) + return true; + if (target.isDamaged() || target.countCards("h") < 4) return false; + return true; + })() + ); + "step 6"; + if (result.bool) { + target.chat("加入"); //event.targets4.push(target); - game.broadcastAll(function(player,text){ - player.identity=text; - player.setIdentity(text,'kami'); - },target,event.text); + game.broadcastAll( + function (player, text) { + player.identity = text; + player.setIdentity(text, "kami"); + }, + target, + event.text + ); target.changeGroup(event.text); - } - else{ - target.chat('拒绝'); + } else { + target.chat("拒绝"); event.targets3.push(target); } game.delay(1.5); - if(targets.length) event.goto(5); + if (targets.length) event.goto(5); /* else if(event.targets4.length){ for(var i of event.targets4){ @@ -17093,106 +21825,105 @@ return event.junling=='junling5'?1:0;}); } } */ - 'step 7' - if(event.targets3.length){ - for(var i of event.targets3){ + "step 7"; + if (event.targets3.length) { + for (var i of event.targets3) { i.drawTo(4); i.recover(); } } - 'step 8' - if(event.targets2.length) event.goto(3); - else{ + "step 8"; + if (event.targets2.length) event.goto(3); + else { delete _status.showYexings; - if(!game.hasPlayer(current=>{ - return game.hasPlayer(target=>{ - return !target.isFriendOf(current); - }); - })){ - game.broadcastAll(function(id){ - game.winner_id=id; - },event.source.playerid); + if ( + !game.hasPlayer((current) => { + return game.hasPlayer((target) => { + return !target.isFriendOf(current); + }); + }) + ) { + game.broadcastAll(function (id) { + game.winner_id = id; + }, event.source.playerid); game.checkResult(); } } }); }, - getCharacterChoice:function(list,num){ - var choice=list.splice(0,num).sort(function(a,b){ - return (get.is.double(a)?1:-1)-(get.is.double(b)?1:-1); + getCharacterChoice: function (list, num) { + var choice = list.splice(0, num).sort(function (a, b) { + return (get.is.double(a) ? 1 : -1) - (get.is.double(b) ? 1 : -1); }); - var map={wei:[],shu:[],wu:[],qun:[],key:[],jin:[],ye:[]}; - for(var i=0;i=num){ + list.splice(i--, 1); + if (choice.length >= num) { break; } } - } - else{ - if(!map[lib.character[list[i]][1]]&&!get.is.double(list[i])){ - group=lib.character[list[i]][1]; - if(group=='ye') group=null; + } else { + if (!map[lib.character[list[i]][1]] && !get.is.double(list[i])) { + group = lib.character[list[i]][1]; + if (group == "ye") group = null; choice.push(list[i]); - list.splice(i--,1); - if(choice.length>=num){ + list.splice(i--, 1); + if (choice.length >= num) { break; } } @@ -17201,262 +21932,316 @@ return event.junling=='junling5'?1:0;}); } return choice.randomSort(); }, - getState:function(){ - var state={}; - for(var i in lib.playerOL){ - var player=lib.playerOL[i]; - state[i]={ - identity:player.identity, + getState: function () { + var state = {}; + for (var i in lib.playerOL) { + var player = lib.playerOL[i]; + state[i] = { + identity: player.identity, //group:player.group, - shown:player.ai.shown, + shown: player.ai.shown, }; } return state; }, - updateState:function(state){ - for(var i in state){ - var player=lib.playerOL[i]; - if(player){ - player.identity=state[i].identity; + updateState: function (state) { + for (var i in state) { + var player = lib.playerOL[i]; + if (player) { + player.identity = state[i].identity; //player.group=state[i].group; - player.ai.shown=state[i].shown; + player.ai.shown = state[i].shown; } } }, - getRoomInfo:function(uiintro){ - var num,last; - if(lib.configOL.initshow_draw=='off'){ - num='关闭' + getRoomInfo: function (uiintro) { + var num, last; + if (lib.configOL.initshow_draw == "off") { + num = "关闭"; + } else { + num = { mark: "标记", draw: "摸牌" }[lib.configOL.initshow_draw]; } - else{ - num={mark:'标记',draw:'摸牌'}[lib.configOL.initshow_draw]; - } - uiintro.add('
                              群雄割据:'+(lib.configOL.separatism?'开启':'关闭')); - uiintro.add('
                              首亮奖励:'+num); - uiintro.add('
                              珠联璧合:'+(lib.configOL.zhulian?'开启':'关闭')); - uiintro.add('
                              出牌时限:'+lib.configOL.choose_timeout+'秒'); - uiintro.add('
                              国战牌堆:'+(lib.configOL.guozhanpile?'开启':'关闭')); - uiintro.add('
                              鏖战模式:'+(lib.configOL.aozhan?'开启':'关闭')); - last=uiintro.add('
                              观看下家副将:'+(lib.configOL.viewnext?'开启':'关闭')); - last.style.paddingBottom='8px'; + uiintro.add( + '
                              群雄割据:' + (lib.configOL.separatism ? "开启" : "关闭") + ); + uiintro.add('
                              首亮奖励:' + num); + uiintro.add('
                              珠联璧合:' + (lib.configOL.zhulian ? "开启" : "关闭")); + uiintro.add('
                              出牌时限:' + lib.configOL.choose_timeout + "秒"); + uiintro.add( + '
                              国战牌堆:' + (lib.configOL.guozhanpile ? "开启" : "关闭") + ); + uiintro.add('
                              鏖战模式:' + (lib.configOL.aozhan ? "开启" : "关闭")); + last = uiintro.add( + '
                              观看下家副将:' + (lib.configOL.viewnext ? "开启" : "关闭") + ); + last.style.paddingBottom = "8px"; }, - addRecord:function(bool){ - if(typeof bool=='boolean'){ - var data=lib.config.gameRecord.guozhan.data; - var identity=game.me.identity; - if(!data[identity]){ - data[identity]=[0,0]; + addRecord: function (bool) { + if (typeof bool == "boolean") { + var data = lib.config.gameRecord.guozhan.data; + var identity = game.me.identity; + if (!data[identity]) { + data[identity] = [0, 0]; } - if(bool){ + if (bool) { data[identity][0]++; - } - else{ + } else { data[identity][1]++; } - var list=lib.group.slice(0); - list.add('ye'); - var str=''; - for(var i=0;i'; + var list = lib.group.slice(0); + list.add("ye"); + var str = ""; + for (var i = 0; i < list.length; i++) { + if (list[i] != "shen" && data[list[i]]) { + str += + lib.translate[list[i] + "2"] + + ":" + + data[list[i]][0] + + "胜" + + " " + + data[list[i]][1] + + "负
                              "; } } - lib.config.gameRecord.guozhan.str=str; - game.saveConfig('gameRecord',lib.config.gameRecord); + lib.config.gameRecord.guozhan.str = str; + game.saveConfig("gameRecord", lib.config.gameRecord); } }, - getIdentityList:function(player){ - if(!player.isUnseen()) return; - if(player==game.me) return; - var list={ - wei:'魏', - shu:'蜀', - wu:'吴', - qun:'群', - ye:'野', - unknown:'猜' - } - var num=Math.floor((game.players.length+game.dead.length)/2); - var noye=true; - if(get.population('wei')>=num){ + getIdentityList: function (player) { + if (!player.isUnseen()) return; + if (player == game.me) return; + var list = { + wei: "魏", + shu: "蜀", + wu: "吴", + qun: "群", + ye: "野", + unknown: "猜", + }; + var num = Math.floor((game.players.length + game.dead.length) / 2); + var noye = true; + if (get.population("wei") >= num) { delete list.wei; - noye=false; + noye = false; } - if(get.population('shu')>=num){ + if (get.population("shu") >= num) { delete list.shu; - noye=false; + noye = false; } - if(get.population('wu')>=num){ + if (get.population("wu") >= num) { delete list.wu; - noye=false; + noye = false; } - if(get.population('qun')>=num){ + if (get.population("qun") >= num) { delete list.qun; - noye=false; + noye = false; } - if(noye){ + if (noye) { delete list.ye; } return list; }, - getIdentityList2:function(list){ - for(var i in list){ - switch(i){ - case 'unknown':list[i]='未知';break; - case 'ye':list[i]='野心家';break; - case 'qun':list[i]+='雄';break; - case 'key':list[i]='Key';break; - case 'jin':list[i]+='朝';break; - default:list[i]+='国'; + getIdentityList2: function (list) { + for (var i in list) { + switch (i) { + case "unknown": + list[i] = "未知"; + break; + case "ye": + list[i] = "野心家"; + break; + case "qun": + list[i] += "雄"; + break; + case "key": + list[i] = "Key"; + break; + case "jin": + list[i] += "朝"; + break; + default: + list[i] += "国"; } } }, - getVideoName:function(){ - var str=get.translation(game.me.name1)+'/'+get.translation(game.me.name2); - var str2=_status.separatism?get.modetrans({ - mode:lib.config.mode, - separatism:true - }):get.cnNumber(parseInt(get.config('player_number')))+'人'+ - get.translation(lib.config.mode); - if(game.me.identity=='ye'){ - str2+=' - 野心家'; + getVideoName: function () { + var str = get.translation(game.me.name1) + "/" + get.translation(game.me.name2); + var str2 = _status.separatism + ? get.modetrans({ + mode: lib.config.mode, + separatism: true, + }) + : get.cnNumber(parseInt(get.config("player_number"))) + + "人" + + get.translation(lib.config.mode); + if (game.me.identity == "ye") { + str2 += " - 野心家"; } - var name=[str,str2]; + var name = [str, str2]; return name; }, - showIdentity:function(started){ - if(game.phaseNumber==0&&!started) return; - for(var i=0;i1){ - if(!hiddens.length&&sides.length==2){ - if(map[sides[0]].length==1&&!map[sides[1]].filter(function(i){ - return i.identity!='ye'&&i.isUnseen(0); - }).length) map[sides[0]][0].showGiveup(); - if(map[sides[1]].length==1&&!map[sides[0]].filter(function(i){ - return i.identity!='ye'&&i.isUnseen(0); - }).length) map[sides[1]][0].showGiveup(); + if (!sides.length) return; + else if (sides.length > 1) { + if (!hiddens.length && sides.length == 2) { + if ( + map[sides[0]].length == 1 && + !map[sides[1]].filter(function (i) { + return i.identity != "ye" && i.isUnseen(0); + }).length + ) + map[sides[0]][0].showGiveup(); + if ( + map[sides[1]].length == 1 && + !map[sides[0]].filter(function (i) { + return i.identity != "ye" && i.isUnseen(0); + }).length + ) + map[sides[1]][0].showGiveup(); } - } - else{ - var isYe=function(player){ - return player.identity!='ye'&&lib.character[player.name1][1]=='ye'; - } - if(!hiddens.length){ - if(map[sides[0]].length>1){ - for(var i of map[sides[0]]){ - if(isYe(i)){ + } else { + var isYe = function (player) { + return player.identity != "ye" && lib.character[player.name1][1] == "ye"; + }; + if (!hiddens.length) { + if (map[sides[0]].length > 1) { + for (var i of map[sides[0]]) { + if (isYe(i)) { game.showYexings(); return; } } } - game.broadcastAll(function(id){ - game.winner_id=id; - },sides[0]); + game.broadcastAll(function (id) { + game.winner_id = id; + }, sides[0]); game.checkResult(); - } - else{ - var identity=map[sides[0]][0].identity; - if(identity=='ye') return; - for(var i of map[sides[0]]){ - if(isYe(i)) return; + } else { + var identity = map[sides[0]][0].identity; + if (identity == "ye") return; + for (var i of map[sides[0]]) { + if (isYe(i)) return; } - for(var ind=0;inddouble.includes(group)); + var filterChoice = function (name1, name2) { + if (_status.separatism) return true; + var group1 = lib.character[name1][1]; + var group2 = lib.character[name2][1]; + var doublex = get.is.double(name1, true); + if (doublex) { + var double = get.is.double(name2, true); + if (double) return doublex.some((group) => double.includes(group)); return doublex.includes(group2); - } - else{ - if(group1=='ye') return group2!='ye'; - var double=get.is.double(name2,true); - if(double) return double.includes(group1); - return group1==group2; + } else { + if (group1 == "ye") return group2 != "ye"; + var double = get.is.double(name2, true); + if (double) return double.includes(group1); + return group1 == group2; } }; - for(var i=0;iget.is.double(mainx,true).includes(group)).randomGet(); - else player.trueIdentity=get.is.double(mainx,true).find(group=>get.is.double(vicex,true).includes(group)); - } - else if(lib.character[mainx][1]=='ye'&&get.is.double(vicex,true)) player.trueIdentity=get.is.double(vicex,true).randomGet(); - if(back){ + player.init(mainx, vicex, false); + if (get.is.double(mainx, true)) { + if (!get.is.double(vicex, true)) + player.trueIdentity = lib.character[vicex][1]; + else if ( + get.is.double(mainx, true).removeArray(get.is.double(vicex, true)) + .length == 0 || + get.is.double(vicex, true).removeArray(get.is.double(mainx, true)) + .length == 0 + ) + player.trueIdentity = get.is + .double(vicex, true) + .filter((group) => get.is.double(mainx, true).includes(group)) + .randomGet(); + else + player.trueIdentity = get.is + .double(mainx, true) + .find((group) => get.is.double(vicex, true).includes(group)); + } else if (lib.character[mainx][1] == "ye" && get.is.double(vicex, true)) + player.trueIdentity = get.is.double(vicex, true).randomGet(); + if (back) { list.remove(player.name1); list.remove(player.name2); - for(var i=0;i'; - td.link=i-1; + }; + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); + var addSetting = function (dialog) { + dialog.add("选择座位").classList.add("add-setting"); + var seats = document.createElement("table"); + seats.classList.add("add-setting"); + seats.style.margin = "0"; + seats.style.width = "100%"; + seats.style.position = "relative"; + for (var i = 1; i <= game.players.length; i++) { + var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); + td.innerHTML = "" + get.cnNumber(i, true) + ""; + td.link = i - 1; seats.appendChild(td); - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - if(_status.cheat_seat){ - _status.cheat_seat.classList.remove('bluebg'); - if(_status.cheat_seat==this){ + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + if (_status.cheat_seat) { + _status.cheat_seat.classList.remove("bluebg"); + if (_status.cheat_seat == this) { delete _status.cheat_seat; return; } } - this.classList.add('bluebg'); - _status.cheat_seat=this; + this.classList.add("bluebg"); + _status.cheat_seat = this; }); } dialog.content.appendChild(seats); - if(game.me==game.zhu){ - seats.previousSibling.style.display='none'; - seats.style.display='none'; + if (game.me == game.zhu) { + seats.previousSibling.style.display = "none"; + seats.style.display = "none"; } - dialog.add(ui.create.div('.placeholder.add-setting')); - dialog.add(ui.create.div('.placeholder.add-setting')); - if(get.is.phoneLayout()) dialog.add(ui.create.div('.placeholder.add-setting')); + dialog.add(ui.create.div(".placeholder.add-setting")); + dialog.add(ui.create.div(".placeholder.add-setting")); + if (get.is.phoneLayout()) dialog.add(ui.create.div(".placeholder.add-setting")); }; - var removeSetting=function(){ - var dialog=_status.event.dialog; - if(dialog){ - dialog.style.height=''; + var removeSetting = function () { + var dialog = _status.event.dialog; + if (dialog) { + dialog.style.height = ""; delete dialog._scrollset; - var list=Array.from(dialog.querySelectorAll('.add-setting')); - while(list.length){ + var list = Array.from(dialog.querySelectorAll(".add-setting")); + while (list.length) { list.shift().remove(); } ui.update(); } }; - event.addSetting=addSetting; - event.removeSetting=removeSetting; + event.addSetting = addSetting; + event.removeSetting = removeSetting; - var chosen=lib.config.continue_name||[]; - game.saveConfig('continue_name'); - event.chosen=chosen; + var chosen = lib.config.continue_name || []; + game.saveConfig("continue_name"); + event.chosen = chosen; var i; - event.list=[]; - for(i in lib.character){ - if(i.indexOf('gz_shibing')==0) continue; - if(chosen.includes(i)) continue; - if(lib.filter.characterDisabled(i)) continue; - if(get.config('onlyguozhan')){ - if(!lib.characterGuozhanFilter.some(pack=>lib.characterPack[pack][i])) continue; - if(get.is.jun(i)) continue; + event.list = []; + for (i in lib.character) { + if (i.indexOf("gz_shibing") == 0) continue; + if (chosen.includes(i)) continue; + if (lib.filter.characterDisabled(i)) continue; + if (get.config("onlyguozhan")) { + if (!lib.characterGuozhanFilter.some((pack) => lib.characterPack[pack][i])) + continue; + if (get.is.jun(i)) continue; } - if(lib.character[i][4].includes('hiddenSkill')) continue; - if(lib.character[i][2]==3||lib.character[i][2]==4||lib.character[i][2]==5) - event.list.push(i); + if (lib.character[i][4].includes("hiddenSkill")) continue; + if (lib.character[i][2] == 3 || lib.character[i][2] == 4 || lib.character[i][2] == 5) + event.list.push(i); } - _status.characterlist=event.list.slice(0); - _status.yeidentity=[]; - if(_status.brawl&&_status.brawl.chooseCharacterFilter){ - event.list=_status.brawl.chooseCharacterFilter(event.list); + _status.characterlist = event.list.slice(0); + _status.yeidentity = []; + if (_status.brawl && _status.brawl.chooseCharacterFilter) { + event.list = _status.brawl.chooseCharacterFilter(event.list); } event.list.randomSort(); // var list=event.list.splice(0,parseInt(get.config('choice_num'))); var list; - if(_status.brawl&&_status.brawl.chooseCharacter){ - list=_status.brawl.chooseCharacter(event.list,game.me); + if (_status.brawl && _status.brawl.chooseCharacter) { + list = _status.brawl.chooseCharacter(event.list, game.me); + } else { + list = game.getCharacterChoice(event.list, parseInt(get.config("choice_num"))); } - else{ - list=game.getCharacterChoice(event.list,parseInt(get.config('choice_num'))); - } - if(_status.auto){ - event.ai(game.me,list); + if (_status.auto) { + event.ai(game.me, list); lib.init.onfree(); - } - else if(chosen.length){ - game.me.init(chosen[0],chosen[1],false); + } else if (chosen.length) { + game.me.init(chosen[0], chosen[1], false); lib.init.onfree(); - } - else{ - var dialog=ui.create.dialog('选择角色','hidden',[list,'character']); - if(!_status.brawl||!_status.brawl.noAddSetting){ - if(get.config('change_identity')){ + } else { + var dialog = ui.create.dialog("选择角色", "hidden", [list, "character"]); + if (!_status.brawl || !_status.brawl.noAddSetting) { + if (get.config("change_identity")) { addSetting(dialog); } } - var next=game.me.chooseButton(dialog,true,2).set('onfree',true); - next.filterButton=function(button){ - if(ui.dialog.buttons.length<=10){ - for(var i=0;idouble.includes(group)); + if (lib.character[button.link][4].includes("hiddenSkill")) return false; + var filterChoice = function (name1, name2) { + if (_status.separatism) return true; + var group1 = lib.character[name1][1]; + var group2 = lib.character[name2][1]; + var doublex = get.is.double(name1, true); + if (doublex) { + var double = get.is.double(name2, true); + if (double) return doublex.some((group) => double.includes(group)); return doublex.includes(group2); - } - else{ - if(group1=='ye') return group2!='ye'; - var double=get.is.double(name2,true); - if(double) return double.includes(group1); - return group1==group2; + } else { + if (group1 == "ye") return group2 != "ye"; + var double = get.is.double(name2, true); + if (double) return double.includes(group1); + return group1 == group2; } }; - if(!ui.selected.buttons.length){ - return ui.dialog.buttons.some(but=>{ - if(but==button) return false; - return filterChoice(button.link,but.link); + if (!ui.selected.buttons.length) { + return ui.dialog.buttons.some((but) => { + if (but == button) return false; + return filterChoice(button.link, but.link); }); } - return filterChoice(ui.selected.buttons[0].link,button.link); + return filterChoice(ui.selected.buttons[0].link, button.link); }; - next.switchToAuto=function(){ - event.ai(game.me,list); - ui.arena.classList.remove('selecting'); + next.switchToAuto = function () { + event.ai(game.me, list); + ui.arena.classList.remove("selecting"); }; - var createCharacterDialog=function(){ - event.dialogxx=ui.create.characterDialog('heightset',function(i){ - if(i.indexOf('gz_shibing')==0) return true; - if(get.config('onlyguozhan')){ - if(!lib.characterGuozhanFilter.some(pack=>lib.characterPack[pack][i])) return true; - if(get.is.jun(i)) return true; - } - },get.config('onlyguozhanexpand')?'expandall':undefined,get.config('onlyguozhan')?'onlypack:mode_guozhan':undefined); - if(ui.cheat2){ - ui.cheat2.addTempClass('controlpressdownx',500); - ui.cheat2.classList.remove('disabled'); + var createCharacterDialog = function () { + event.dialogxx = ui.create.characterDialog( + "heightset", + function (i) { + if (i.indexOf("gz_shibing") == 0) return true; + if (get.config("onlyguozhan")) { + if ( + !lib.characterGuozhanFilter.some( + (pack) => lib.characterPack[pack][i] + ) + ) + return true; + if (get.is.jun(i)) return true; + } + }, + get.config("onlyguozhanexpand") ? "expandall" : undefined, + get.config("onlyguozhan") ? "onlypack:mode_guozhan" : undefined + ); + if (ui.cheat2) { + ui.cheat2.addTempClass("controlpressdownx", 500); + ui.cheat2.classList.remove("disabled"); } }; - if(lib.onfree){ + if (lib.onfree) { lib.onfree.push(createCharacterDialog); - } - else{ + } else { createCharacterDialog(); } - ui.create.cheat2=function(){ - ui.cheat2=ui.create.control('自由选将',function(){ - if(this.dialog==_status.event.dialog){ - if(game.changeCoin){ + ui.create.cheat2 = function () { + ui.cheat2 = ui.create.control("自由选将", function () { + if (this.dialog == _status.event.dialog) { + if (game.changeCoin) { game.changeCoin(50); } this.dialog.close(); - _status.event.dialog=this.backup; + _status.event.dialog = this.backup; this.backup.open(); delete this.backup; game.uncheck(); game.check(); - if(ui.cheat){ - ui.cheat.addTempClass('controlpressdownx',500); - ui.cheat.classList.remove('disabled'); + if (ui.cheat) { + ui.cheat.addTempClass("controlpressdownx", 500); + ui.cheat.classList.remove("disabled"); } - } - else{ - if(game.changeCoin){ + } else { + if (game.changeCoin) { game.changeCoin(-10); } - this.backup=_status.event.dialog; + this.backup = _status.event.dialog; _status.event.dialog.close(); - _status.event.dialog=_status.event.parent.dialogxx; - this.dialog=_status.event.dialog; + _status.event.dialog = _status.event.parent.dialogxx; + this.dialog = _status.event.dialog; this.dialog.open(); game.uncheck(); game.check(); - if(ui.cheat){ - ui.cheat.classList.add('disabled'); + if (ui.cheat) { + ui.cheat.classList.add("disabled"); } } }); - if(lib.onfree){ - ui.cheat2.classList.add('disabled'); + if (lib.onfree) { + ui.cheat2.classList.add("disabled"); } - } - ui.create.cheat=function(){ - _status.createControl=ui.cheat2; - ui.cheat=ui.create.control('更换',function(){ - if(ui.cheat2&&ui.cheat2.dialog==_status.event.dialog){ + }; + ui.create.cheat = function () { + _status.createControl = ui.cheat2; + ui.cheat = ui.create.control("更换", function () { + if (ui.cheat2 && ui.cheat2.dialog == _status.event.dialog) { return; } - if(game.changeCoin){ + if (game.changeCoin) { game.changeCoin(-3); } - event.list=event.list.concat(list); + event.list = event.list.concat(list); event.list.randomSort(); // list=event.list.splice(0,parseInt(get.config('choice_num'))); - list=game.getCharacterChoice(event.list,parseInt(get.config('choice_num'))); - var buttons=ui.create.div('.buttons'); - var node=_status.event.dialog.buttons[0].parentNode; - _status.event.dialog.buttons=ui.create.buttons(list,'character',buttons); - _status.event.dialog.content.insertBefore(buttons,node); - buttons.addTempClass('start'); + list = game.getCharacterChoice( + event.list, + parseInt(get.config("choice_num")) + ); + var buttons = ui.create.div(".buttons"); + var node = _status.event.dialog.buttons[0].parentNode; + _status.event.dialog.buttons = ui.create.buttons(list, "character", buttons); + _status.event.dialog.content.insertBefore(buttons, node); + buttons.addTempClass("start"); node.remove(); game.uncheck(); game.check(); }); delete _status.createControl; - } - if(!_status.brawl||!_status.brawl.chooseCharacterFixed){ - if(!ui.cheat&&get.config('change_choice')) - ui.create.cheat(); - if(!ui.cheat2&&get.config('free_choose')) - ui.create.cheat2(); + }; + if (!_status.brawl || !_status.brawl.chooseCharacterFixed) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); } } - "step 1" - if(ui.cheat){ + "step 1"; + if (ui.cheat) { ui.cheat.close(); delete ui.cheat; } - if(ui.cheat2){ + if (ui.cheat2) { ui.cheat2.close(); delete ui.cheat2; } - if(result.buttons){ - var name1=result.buttons[0].link,name2=result.buttons[1].link; - event.choosen=[name1,name2]; - if(get.is.double(name1,true)){ - if(!get.is.double(name2,true)) event._result={control:lib.character[name2][1]}; - else if(get.is.double(name1,true).removeArray(get.is.double(name2,true)).length==0||get.is.double(name2,true).removeArray(get.is.double(name1,true)).length==0) game.me.chooseControl(get.is.double(name2,true).filter(group=>get.is.double(name1,true).includes(group))).set('prompt','请选择你代表的势力').set('ai',()=>_status.event.controls.randomGet()); - else event._result={control:get.is.double(name1,true).find(group=>get.is.double(name2,true).includes(group))}; - } - else if(lib.character[name1][1]=='ye'&&get.is.double(name2,true)) game.me.chooseControl(get.is.double(name2,true)).set('prompt','请选择副将代表的势力').set('ai',()=>_status.event.controls.randomGet()); + if (result.buttons) { + var name1 = result.buttons[0].link, + name2 = result.buttons[1].link; + event.choosen = [name1, name2]; + if (get.is.double(name1, true)) { + if (!get.is.double(name2, true)) + event._result = { control: lib.character[name2][1] }; + else if ( + get.is.double(name1, true).removeArray(get.is.double(name2, true)).length == + 0 || + get.is.double(name2, true).removeArray(get.is.double(name1, true)).length == 0 + ) + game.me + .chooseControl( + get.is + .double(name2, true) + .filter((group) => get.is.double(name1, true).includes(group)) + ) + .set("prompt", "请选择你代表的势力") + .set("ai", () => _status.event.controls.randomGet()); + else + event._result = { + control: get.is + .double(name1, true) + .find((group) => get.is.double(name2, true).includes(group)), + }; + } else if (lib.character[name1][1] == "ye" && get.is.double(name2, true)) + game.me + .chooseControl(get.is.double(name2, true)) + .set("prompt", "请选择副将代表的势力") + .set("ai", () => _status.event.controls.randomGet()); } - 'step 2' - if(result&&result.control) game.me.trueIdentity=result.control; - if(event.choosen){ - game.me.init(event.choosen[0],event.choosen[1],false); - game.addRecentCharacter(event.choosen[0],event.choosen[1]); + "step 2"; + if (result && result.control) game.me.trueIdentity = result.control; + if (event.choosen) { + game.me.init(event.choosen[0], event.choosen[1], false); + game.addRecentCharacter(event.choosen[0], event.choosen[1]); } event.list.remove(game.me.name1); event.list.remove(game.me.name2); - for(var i=0;ilist.length){ - num=5; + if (lib.configOL.number * 6 > list.length) { + num = 5; + } else if (lib.configOL.number * 7 > list.length) { + num = 6; + } else { + num = 7; } - else if(lib.configOL.number*7>list.length){ - num=6; - } - else{ - num=7; - } - var filterButton=function(button){ - if(ui.dialog){ - if(ui.dialog.buttons.length<=10){ - for(var i=0;idouble.includes(group)); + var filterChoice = function (name1, name2) { + if (_status.separatism) return true; + var group1 = lib.character[name1][1]; + var group2 = lib.character[name2][1]; + var doublex = get.is.double(name1, true); + if (doublex) { + var double = get.is.double(name2, true); + if (double) return doublex.some((group) => double.includes(group)); return doublex.includes(group2); - } - else{ - if(group1=='ye') return group2!='ye'; - var double=get.is.double(name2,true); - if(double) return double.includes(group1); - return group1==group2; + } else { + if (group1 == "ye") return group2 != "ye"; + var double = get.is.double(name2, true); + if (double) return double.includes(group1); + return group1 == group2; } }; - if(!ui.selected.buttons.length){ - return ui.dialog.buttons.some(but=>{ - if(but==button) return false; - return filterChoice(button.link,but.link); + if (!ui.selected.buttons.length) { + return ui.dialog.buttons.some((but) => { + if (but == button) return false; + return filterChoice(button.link, but.link); }); } - return filterChoice(ui.selected.buttons[0].link,button.link); + return filterChoice(ui.selected.buttons[0].link, button.link); }; list.randomSort(); - for(var i=0;idouble.includes(group)); - return doublex.includes(group2); - } - else{ - if(group1=='ye') return group2!='ye'; - var double=get.is.double(name2,true); - if(double) return double.includes(group1); - return group1==group2; - } - }; - for(var i=0;i double.includes(group)); + return doublex.includes(group2); + } else { + if (group1 == "ye") return group2 != "ye"; + var double = get.is.double(name2, true); + if (double) return double.includes(group1); + return group1 == group2; + } + }; + for (var i = 0; i < buttons.length - 1; i++) { + for (var j = i + 1; j < buttons.length; j++) { + if ( + filterChoice(buttons[i].link, buttons[j].link) || + filterChoice(buttons[j].link, buttons[i].link) + ) { + var mainx = buttons[i].link; + var vicex = buttons[j].link; + if ( + !filterChoice(mainx, vicex) || + (filterChoice(vicex, mainx) && get.guozhanReverse(mainx, vicex)) + ) { + mainx = buttons[j].link; + vicex = buttons[i].link; + } + var list = [mainx, vicex]; + return { + bool: true, + links: list, + }; } } } - } - }); - 'step 1' - var sort=true,chosen=[],chosenCharacter=[]; - for(var i in result){ - if(result[i]&&result[i].links){ - for(var j=0;jget.is.double(name2,true).includes(group)); - } - else if(lib.character[name1][1]=='ye'&&get.is.double(name2,true)){ + chosenCharacter.push([name1, name2]); + } else + lib.playerOL[i].trueIdentity = get.is + .double(name1, true) + .find((group) => get.is.double(name2, true).includes(group)); + } else if (lib.character[name1][1] == "ye" && get.is.double(name2, true)) { chosen.push(lib.playerOL[i]); - chosenCharacter.push([name1,name2]); + chosenCharacter.push([name1, name2]); } } - event.result2=result; - if(chosen.length){ - for(var i=0;iget.is.double(name1,true).includes(group)); + event.result2 = result; + if (chosen.length) { + for (var i = 0; i < chosen.length; i++) { + var name1 = chosenCharacter[i][0], + name2 = chosenCharacter[i][1], + str, + choice; + if (get.is.double(name1, true)) { + str = "请选择你代表的势力"; + choice = get.is + .double(name2, true) + .filter((group) => get.is.double(name1, true).includes(group)); } - if(lib.character[name1][1]=='ye'){ - str='请选择你的副将代表的势力'; - choice=get.is.double(name2,true); + if (lib.character[name1][1] == "ye") { + str = "请选择你的副将代表的势力"; + choice = get.is.double(name2, true); } - chosen[i]=[chosen[i],[str,[choice.map(function(i){ - return ['','','group_'+i]; - }),'vcard']],1,true]; + chosen[i] = [ + chosen[i], + [ + str, + [ + choice.map(function (i) { + return ["", "", "group_" + i]; + }), + "vcard", + ], + ], + 1, + true, + ]; } - game.me.chooseButtonOL(chosen,function(player,result){ - if(player==game.me) player.trueIdentity=result.links[0][2].slice(6); - }).set('switchToAuto',function(){ - _status.event.result='ai'; - }).set('processAI',function(){ - return { - bool:true, - links:[_status.event.dialog.buttons.randomGet().link], - } - }); - } - else event._result={}; - 'step 2' - if(!result) result={}; - var result2=event.result2; - game.broadcastAll(function(result,result2){ - for(var i=0;i根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上:〖英姿〗;两张以上:〖好施〗;三张以上:〖涉猎〗;四张以上:〖度势〗;五张以上:可额外选择一项。
                              锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。', - yuanjiangfenghuotu_ab:'江图', - yuanjiangfenghuotu_bg:'图', - wuxin:'悟心', - wuxin_info:'摸牌阶段开始时,你可以观看牌堆顶的X张牌(X为群势力角色的数量),然后将这些牌以任意顺序置于牌堆顶。', - hongfa:'弘法', - hongfa_use:'天兵', - hongfa_respond:'天兵', - hongfa_info:'君主技,锁定技,此武将牌明置时,你获得“黄巾天兵符”;准备阶段,若没有“天兵”,你将牌堆顶的X张牌置于“黄巾天兵符”上,称为“天兵”(X为群势力角色的数量)。', - wendao:'问道', - wendao_info:'出牌阶段限一次,你可以弃置一张不为【太平要术】的红色牌,然后获得弃牌堆或场上的一张【太平要术】。', - huangjintianbingfu:'黄巾天兵符', - huangjintianbingfu_ab:'兵符', - huangjintianbingfu_bg:'符', - huangjintianbingfu_info:'锁定技,当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
                              当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
                              与你势力相同的角色可将一张“天兵”当作【杀】使用或打出。', - wuhujiangdaqi:'五虎将大旗', - wuhujiangdaqi_ab:'将旗', - wuhujiangdaqi_bg:'旗', - wuhujiangdaqi_info:'存活的蜀势力角色的技能按以下规则改动:
                              武圣:将“红色牌”改为“任意牌”
                              咆哮:增加描述“你使用的【杀】无视其他角色的防具”
                              龙胆:增加描述“你发动〖龙胆〗使用或打出牌时摸一张牌”
                              烈弓:增加描述“你的攻击范围+1”
                              铁骑:将“一张明置的武将牌”改为“所有明置的武将牌”', - zhangwu:'章武', - zhangwu_info:'锁定技。当【飞龙夺凤】进入弃牌堆或其他角色的装备区后,你获得之。当你不因使用而失去【飞龙夺风】时,你展示此牌,将此牌置于牌堆底并摸两张牌。', - shouyue:'授钺', - shouyue_info:'君主技。只要此武将牌处于明置状态,你便拥有“五虎将大旗”。', - jizhao:'激诏', - jizhao_bg:'诏', - jizhao_info:'限定技。当你处于濒死状态时,你可以将手牌补至体力上限,体力回复至2点,失去技能〖授钺〗并获得技能〖仁德〗。', - gzshoucheng:'守成', - gzshoucheng_info:'当与你势力相同的一名角色于其回合外失去手牌时,若其没有手牌,则你可以令其摸一张牌。', - gzmingshi:'名士', - gzmingshi_info:'锁定技,当你受到伤害时,若伤害来源有暗置的武将牌,此伤害-1。', - fengshi:'锋矢', - fengshi_sha:'锋矢', - fengshi_info:'阵法技,在一个围攻关系中,若你是围攻角色,则你或另一名围攻角色使用【杀】指定被围攻角色为目标后,可令该角色弃置装备区内的一张牌。', - gzsuishi:'随势', - gzsuishi2:'随势', - gzsuishi_info:'锁定技,其他角色进入濒死状态时,若伤害来源与你势力相同,你摸一张牌;其他角色死亡时,若其与你势力相同,你失去1点体力。', - baoling:'暴凌', - baoling_info:'主将技,锁定技,出牌阶段结束时,若你有副将,则你移除副将,然后加3点体力上限,回复3点体力,失去技能〖暴凌〗并获得〖崩坏〗。', - yingyang:'鹰扬', - yingyang_info:'当你的拼点牌亮出后,你可以令此牌的点数+3或-3(至多为K,至少为1)。', - hunshang:'魂殇', - hunshang_info:'副将技,此武将牌减少半个阴阳鱼;准备阶段,若你的体力值不大于1,则你本回合获得“英姿”和“英魂”。', - gzguixiu:'闺秀', - gzguixiu_info:'当你明置此武将牌时,你可以摸两张牌;当你移除此武将牌时,你可以回复1点体力。', - gzcunsi:'存嗣', - gzcunsi_info:'出牌阶段,你可以移除此武将牌并选择一名角色,然后其获得技能〖勇决〗,若你选择的目标角色不是自己,则其摸两张牌。', - gzyongjue:'勇决', - gzyongjue_info:'与你势力相同的一名角色于其回合内使用【杀】结算完成后,若此牌是其本回合内使用的第一张牌,则其可以获得此牌对应的所有实体牌。', - gzqianxi:'潜袭', - gzqianxi_info:'准备阶段,你可以进行判定,然后你选择距离为1的一名角色,直到回合结束,该角色不能使用或打出与结果颜色相同的手牌。', - gzshangyi:'尚义', - gzshangyi_info:'出牌阶段限一次,你可以令一名其他角色观看你的手牌。若如此做,你选择一项:1.观看其手牌并可以弃置其中的一张黑色牌;2.观看其所有暗置的武将牌。', - niaoxiang:'鸟翔', - niaoxiang_sha:'鸟翔', - niaoxiang_info:'阵法技,在同一个围攻关系中,若你是围攻角色,则你或另一名围攻角色使用【杀】指定被围攻角色为目标后,该角色需依次使用两张【闪】才能抵消。', - yicheng:'疑城', - yicheng_info:'当与你势力相同的一名角色成为【杀】的目标后,你可以令该角色摸一张牌,然后弃置一张牌。', - gzyicheng:'疑城', - gzyicheng_info:'阵法技。当你和你队列中的角色使用【杀】指定第一个目标后,或成为【杀】的目标后,其可以摸一张牌,然后弃置一张牌。', - yizhi:'遗志', - yizhi_info:'副将技,此武将牌减少半个阴阳鱼。若你的主将拥有技能〖观星〗,则将其描述中的X改为5;若你的主将没有技能〖观星〗,则你视为拥有技能〖观星〗。', - tianfu:'天覆', - tianfu_info:'主将技,阵法技,若当前回合角色与你处于同一队列,则你视为拥有技能〖看破〗。', - ziliang:'资粮', - ziliang_info:'副将技,当与你势力相同的一名角色受到伤害后,你可以将一张“田”交给该角色。', - gzjixi:'急袭', - gzjixi_info:'主将技,此武将牌减少半个阴阳鱼。你可以将一张“田”当作【顺手牵羊】使用。', - huyuan:'护援', - huyuan_info:'结束阶段,你可以将一张装备牌置入一名角色的装备区,然后你可以弃置该角色距离为1的一名角色的一张牌。', - heyi:'鹤翼', - heyi_info:'阵法技。与你处于同一队列的角色视为拥有技能〖飞影〗。', - gzhuyuan:'护援', - gzhuyuan_info:'结束阶段,你可以选择一项:⒈将一张非装备牌交给一名其他角色。⒉将一张装备牌置入其他角色的装备区内,然后你可以弃置场上的一张牌。', - gz_shibing1wei:'魏兵', - gz_shibing2wei:'魏兵', - gz_shibing1shu:'蜀兵', - gz_shibing2shu:'蜀兵', - gz_shibing1wu:'吴兵', - gz_shibing2wu:'吴兵', - gz_shibing1qun:'群兵', - gz_shibing2qun:'群兵', - gz_shibing1jin:'晋兵', - gz_shibing2jin:'晋兵', - gz_shibing1ye:'士兵', - gz_shibing2ye:'士兵', - gz_shibing1key:'键兵', - gz_shibing2key:'键兵', - gzduanchang:'断肠', - gzduanchang_info:'锁定技,当你死亡时,你令杀死你的角色失去一张武将牌上的所有技能。', - gzweimu:'帷幕', - gzweimu_info:'锁定技,当你成为黑色普通锦囊牌的目标时,或有黑色延时锦囊牌进入你的判定区时,取消之。', - gzqianxun:'谦逊', - gzqianxun_info:'锁定技,当你成为【顺手牵羊】的目标时,或有【乐不思蜀】进入你的判定区时,取消之。', - gzkongcheng:'空城', - gzkongcheng_info:'锁定技,当你成为【杀】或【决斗】的目标时,若你没有手牌,则取消之。', - gzxiaoji:'枭姬', - gzxiaoji_info:'当你失去装备区里的牌后,你可以摸一张牌。若你不是当前回合角色,则你改为摸三张牌。', - gzrende:'仁德', - gzrende_info:'出牌阶段,你可以将任意张手牌交给其他角色,然后若你于此阶段内给出第三张“仁德”牌时,你回复1点体力。', - gzzhiheng:'制衡', - gzzhiheng_info:'出牌阶段限一次,你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌。', - duoshi:'度势', - duoshi_info:'出牌阶段限四次,你可以将一张红色手牌当做【以逸待劳】使用。', - gzxiaoguo:'骁果', - gzxiaoguo_info:'其他角色的结束阶段,你可以弃置一张基本牌,令该角色选择一项:1.弃置一张装备牌;2.受到你对其造成的1点伤害。', + jubao: "聚宝", + jubao_info: + "锁定技,你装备区里的宝物牌不能被其他角色获得。结束阶段,若场上或弃牌堆有【定澜夜明珠】,则你摸一张牌,然后获得装备区里有【定澜夜明珠】角色的一张牌。", + jiahe: "嘉禾", + jiahe_info: "君主技,只要此武将牌处于明置状态,你便拥有“缘江烽火图”。", + jiahe_put: "烽火", + jiahe_put_info: "出牌阶段限一次,你可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。", + jiahe_skill: "缘江烽火图", + yuanjiangfenghuotu: "缘江烽火图", + yuanjiangfenghuotu_info: + "每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
                              根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上:〖英姿〗;两张以上:〖好施〗;三张以上:〖涉猎〗;四张以上:〖度势〗;五张以上:可额外选择一项。
                              锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。", + yuanjiangfenghuotu_ab: "江图", + yuanjiangfenghuotu_bg: "图", + wuxin: "悟心", + wuxin_info: + "摸牌阶段开始时,你可以观看牌堆顶的X张牌(X为群势力角色的数量),然后将这些牌以任意顺序置于牌堆顶。", + hongfa: "弘法", + hongfa_use: "天兵", + hongfa_respond: "天兵", + hongfa_info: + "君主技,锁定技,此武将牌明置时,你获得“黄巾天兵符”;准备阶段,若没有“天兵”,你将牌堆顶的X张牌置于“黄巾天兵符”上,称为“天兵”(X为群势力角色的数量)。", + wendao: "问道", + wendao_info: + "出牌阶段限一次,你可以弃置一张不为【太平要术】的红色牌,然后获得弃牌堆或场上的一张【太平要术】。", + huangjintianbingfu: "黄巾天兵符", + huangjintianbingfu_ab: "兵符", + huangjintianbingfu_bg: "符", + huangjintianbingfu_info: + "锁定技,当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
                              当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
                              与你势力相同的角色可将一张“天兵”当作【杀】使用或打出。", + wuhujiangdaqi: "五虎将大旗", + wuhujiangdaqi_ab: "将旗", + wuhujiangdaqi_bg: "旗", + wuhujiangdaqi_info: + "存活的蜀势力角色的技能按以下规则改动:
                              武圣:将“红色牌”改为“任意牌”
                              咆哮:增加描述“你使用的【杀】无视其他角色的防具”
                              龙胆:增加描述“你发动〖龙胆〗使用或打出牌时摸一张牌”
                              烈弓:增加描述“你的攻击范围+1”
                              铁骑:将“一张明置的武将牌”改为“所有明置的武将牌”", + zhangwu: "章武", + zhangwu_info: + "锁定技。当【飞龙夺凤】进入弃牌堆或其他角色的装备区后,你获得之。当你不因使用而失去【飞龙夺风】时,你展示此牌,将此牌置于牌堆底并摸两张牌。", + shouyue: "授钺", + shouyue_info: "君主技。只要此武将牌处于明置状态,你便拥有“五虎将大旗”。", + jizhao: "激诏", + jizhao_bg: "诏", + jizhao_info: + "限定技。当你处于濒死状态时,你可以将手牌补至体力上限,体力回复至2点,失去技能〖授钺〗并获得技能〖仁德〗。", + gzshoucheng: "守成", + gzshoucheng_info: + "当与你势力相同的一名角色于其回合外失去手牌时,若其没有手牌,则你可以令其摸一张牌。", + gzmingshi: "名士", + gzmingshi_info: "锁定技,当你受到伤害时,若伤害来源有暗置的武将牌,此伤害-1。", + fengshi: "锋矢", + fengshi_sha: "锋矢", + fengshi_info: + "阵法技,在一个围攻关系中,若你是围攻角色,则你或另一名围攻角色使用【杀】指定被围攻角色为目标后,可令该角色弃置装备区内的一张牌。", + gzsuishi: "随势", + gzsuishi2: "随势", + gzsuishi_info: + "锁定技,其他角色进入濒死状态时,若伤害来源与你势力相同,你摸一张牌;其他角色死亡时,若其与你势力相同,你失去1点体力。", + baoling: "暴凌", + baoling_info: + "主将技,锁定技,出牌阶段结束时,若你有副将,则你移除副将,然后加3点体力上限,回复3点体力,失去技能〖暴凌〗并获得〖崩坏〗。", + yingyang: "鹰扬", + yingyang_info: "当你的拼点牌亮出后,你可以令此牌的点数+3或-3(至多为K,至少为1)。", + hunshang: "魂殇", + hunshang_info: + "副将技,此武将牌减少半个阴阳鱼;准备阶段,若你的体力值不大于1,则你本回合获得“英姿”和“英魂”。", + gzguixiu: "闺秀", + gzguixiu_info: "当你明置此武将牌时,你可以摸两张牌;当你移除此武将牌时,你可以回复1点体力。", + gzcunsi: "存嗣", + gzcunsi_info: + "出牌阶段,你可以移除此武将牌并选择一名角色,然后其获得技能〖勇决〗,若你选择的目标角色不是自己,则其摸两张牌。", + gzyongjue: "勇决", + gzyongjue_info: + "与你势力相同的一名角色于其回合内使用【杀】结算完成后,若此牌是其本回合内使用的第一张牌,则其可以获得此牌对应的所有实体牌。", + gzqianxi: "潜袭", + gzqianxi_info: + "准备阶段,你可以进行判定,然后你选择距离为1的一名角色,直到回合结束,该角色不能使用或打出与结果颜色相同的手牌。", + gzshangyi: "尚义", + gzshangyi_info: + "出牌阶段限一次,你可以令一名其他角色观看你的手牌。若如此做,你选择一项:1.观看其手牌并可以弃置其中的一张黑色牌;2.观看其所有暗置的武将牌。", + niaoxiang: "鸟翔", + niaoxiang_sha: "鸟翔", + niaoxiang_info: + "阵法技,在同一个围攻关系中,若你是围攻角色,则你或另一名围攻角色使用【杀】指定被围攻角色为目标后,该角色需依次使用两张【闪】才能抵消。", + yicheng: "疑城", + yicheng_info: + "当与你势力相同的一名角色成为【杀】的目标后,你可以令该角色摸一张牌,然后弃置一张牌。", + gzyicheng: "疑城", + gzyicheng_info: + "阵法技。当你和你队列中的角色使用【杀】指定第一个目标后,或成为【杀】的目标后,其可以摸一张牌,然后弃置一张牌。", + yizhi: "遗志", + yizhi_info: + "副将技,此武将牌减少半个阴阳鱼。若你的主将拥有技能〖观星〗,则将其描述中的X改为5;若你的主将没有技能〖观星〗,则你视为拥有技能〖观星〗。", + tianfu: "天覆", + tianfu_info: "主将技,阵法技,若当前回合角色与你处于同一队列,则你视为拥有技能〖看破〗。", + ziliang: "资粮", + ziliang_info: "副将技,当与你势力相同的一名角色受到伤害后,你可以将一张“田”交给该角色。", + gzjixi: "急袭", + gzjixi_info: "主将技,此武将牌减少半个阴阳鱼。你可以将一张“田”当作【顺手牵羊】使用。", + huyuan: "护援", + huyuan_info: + "结束阶段,你可以将一张装备牌置入一名角色的装备区,然后你可以弃置该角色距离为1的一名角色的一张牌。", + heyi: "鹤翼", + heyi_info: "阵法技。与你处于同一队列的角色视为拥有技能〖飞影〗。", + gzhuyuan: "护援", + gzhuyuan_info: + "结束阶段,你可以选择一项:⒈将一张非装备牌交给一名其他角色。⒉将一张装备牌置入其他角色的装备区内,然后你可以弃置场上的一张牌。", + gz_shibing1wei: "魏兵", + gz_shibing2wei: "魏兵", + gz_shibing1shu: "蜀兵", + gz_shibing2shu: "蜀兵", + gz_shibing1wu: "吴兵", + gz_shibing2wu: "吴兵", + gz_shibing1qun: "群兵", + gz_shibing2qun: "群兵", + gz_shibing1jin: "晋兵", + gz_shibing2jin: "晋兵", + gz_shibing1ye: "士兵", + gz_shibing2ye: "士兵", + gz_shibing1key: "键兵", + gz_shibing2key: "键兵", + gzduanchang: "断肠", + gzduanchang_info: "锁定技,当你死亡时,你令杀死你的角色失去一张武将牌上的所有技能。", + gzweimu: "帷幕", + gzweimu_info: + "锁定技,当你成为黑色普通锦囊牌的目标时,或有黑色延时锦囊牌进入你的判定区时,取消之。", + gzqianxun: "谦逊", + gzqianxun_info: + "锁定技,当你成为【顺手牵羊】的目标时,或有【乐不思蜀】进入你的判定区时,取消之。", + gzkongcheng: "空城", + gzkongcheng_info: "锁定技,当你成为【杀】或【决斗】的目标时,若你没有手牌,则取消之。", + gzxiaoji: "枭姬", + gzxiaoji_info: "当你失去装备区里的牌后,你可以摸一张牌。若你不是当前回合角色,则你改为摸三张牌。", + gzrende: "仁德", + gzrende_info: + "出牌阶段,你可以将任意张手牌交给其他角色,然后若你于此阶段内给出第三张“仁德”牌时,你回复1点体力。", + gzzhiheng: "制衡", + gzzhiheng_info: "出牌阶段限一次,你可以弃置至多X张牌(X为你的体力上限),然后摸等量的牌。", + duoshi: "度势", + duoshi_info: "出牌阶段限四次,你可以将一张红色手牌当做【以逸待劳】使用。", + gzxiaoguo: "骁果", + gzxiaoguo_info: + "其他角色的结束阶段,你可以弃置一张基本牌,令该角色选择一项:1.弃置一张装备牌;2.受到你对其造成的1点伤害。", - gzdangxian:'当先', - gzdangxian_info:'锁定技。当你首次明置此武将牌时,你获得一枚“先驱”标记。回合开始时,你获得一个额外的出牌阶段。', - gzhuanshi:'缓释', - gzhuanshi_info:'一名己方角色的判定牌生效前,你可打出一张牌代替之。', - gzhongyuan:'弘援', - gzhongyuan_info:'①出牌阶段限一次。你可以令一张没有「合纵」标签的卡牌视为拥有「合纵」标签直到本回合结束。②当你即将因合纵效果摸牌时,你可放弃摸牌,并令一名己方角色摸等量的牌。', - gzmingzhe:'明哲', - gzmingzhe_info:'你的回合外,当你使用或打出红色手牌,或失去装备区内的红色装备牌时,你可摸一张牌。', - gzxiongzhi:'雄志', - gzxiongzhi_info:'限定技。出牌阶段,你可依次展示牌堆顶的X张牌并使用之(X为你的体力上限)。', - gzquanbian:'权变', - gzquanbian_info:'当你于出牌阶段内使用/打出手牌时,若此牌有花色且你本回合内未使用/打出过该花色的其他手牌,则你可以观看牌堆顶X张牌,选择获得其中的一张并展示之。若你本回合使用过与得到的牌花色相同的牌,则你本回合内不能再发动〖权变〗。', - gzhuishi:'慧识', - gzhuishi_info:'摸牌阶段,你可以放弃摸牌,改为观看牌堆顶的X张牌,获得其中的一半(向下取整),然后将其余牌置入牌堆底。(X为弃牌堆顶的两张牌的名称字数之和)', - gzqingleng:'清冷', - gzqingleng_info:'一名角色的回合结束时,若其有未明置的武将牌,则你可将一张牌当无距离限制的冰属性【杀】对其使用;若其所有武将牌均未明置,则你摸一张牌。', - gzchoufa:'筹伐', - gzchoufa_info:'出牌阶段限一次,你可展示一名其他角色的一张手牌A。你令其所有类型与A不同的手牌的牌名均视为【杀】且均视为无属性直到本回合结束。', - gzbolan:'博览', - gzbolan_info:'每名角色的出牌阶段限一次。其可以随机展示武将牌堆顶的一张武将牌,然后根据此武将牌包含的势力选择获得一个技能直到回合结束:魏:〖奇策〗;蜀:〖挑衅〗;吴:〖制衡〗;群:〖除疠〗;晋:〖三陈〗。若该角色不为你,则其失去1点体力。', - gzsanchen:'三陈', - gzsanchen_info:'出牌阶段,你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则你于本回合获得一枚“陈”且其摸一张牌;否则你本阶段内不能再发动〖三陈〗。', - gzpozhu:'破竹', - gzpozhu_info:'主将技。此武将牌减少半个阴阳鱼。出牌阶段,你可以移去一枚“陈”并将一张手牌当做【出其不意】使用。', - gzyimie:'夷灭', - gzyimie_info:'主将技,此武将牌减少一整个阴阳鱼。每回合限一次,当你对其他角色造成伤害时,若伤害值X小于Y,则你可失去1点体力,将伤害值改为Y。此伤害结算结束后,其回复(Y-X)点体力。(Y为其体力值)', - gztairan:'泰然', - gztairan_info:'出牌阶段开始时,你可以失去任意点体力并弃置任意张牌(弃牌数不能大于你已损失的体力值)。若如此做,本回合结束时,你回复等量的体力并摸等量的牌。', - gzxuanbei:'选备', - gzxuanbei_info:'①当你首次明置此武将牌时,你获得两张拥有“应变”或“合纵”标签的牌(不足则摸牌),且你本回合内使用带有“应变”标签的牌时直接强化,使用带有“合纵”标签的牌时摸一张牌。②当你死亡时,你可以令一名其他角色变更副将。', - gzzhaosong:'诏颂', - gzzhaosong_info:'每局游戏每项限一次。①一名角色进入濒死状态时,你可以令其回复至2点体力并摸一张牌。②出牌阶段,你可观看一名其他角色的所有暗置武将牌和手牌,然后可以获得其区域内的一张牌。③一名角色使用【杀】选择唯一目标后,你可以为此【杀】增加两个目标。', - gzlisi:'离思', - gzlisi_info:'一名己方角色死亡后,你可以选择〖诏颂〗中的一个已发动过的选项,令其视为未发动过。', - gzcaiyuan:'才媛', - gzcaiyuan_info:'锁定技。结束阶段,若你的手牌数大于本回合开始时的手牌数,则你摸两张牌或回复1点体力。', - gzwanyi:'婉嫕', - gzwanyi_info:'出牌阶段每项各限一次。你可以将一张带有“合纵”标签的牌当做【联军盛宴】/【火烧连营】/【挟天子以令诸侯】/【戮力同心】使用。', - gzwanyi_info_guozhan_yingbian:'出牌阶段每项各限一次。你可以将一张带有“应变”标签的牌当做【逐近弃远】/【洞烛先机】/【水淹七军】/【出其不意】使用。', - gzmaihuo:'埋祸', - gzmaihuo_info:'限定技。当有己方角色成为【杀】的目标时,你可以取消此【杀】的所有目标。然后此【杀】的使用者下回合开始时,其视为对你使用一张【杀】。若此【杀】对你造成伤害,则你防止此伤害,摸两张牌并移除此武将牌(若此武将牌为副将则改为变更副将)。', - gzzhenxi:'震袭', - gzzhenxi_info:'当你使用【杀】指定目标后,你可以选择一项:1.弃置目标角色一张牌;2.将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对目标角色使用;3.背水:若其有暗置的武将牌且你的武将牌均明置,则你可以依次执行这两项。', - gzjiansu:'俭素', - gzjiansu_tag:'俭', - gzjiansu_info:'副将技。此武将牌减少半个阴阳鱼。①当你于回合外得到牌后,你可以展示这些牌,称为“俭”。②出牌阶段开始时,你可以弃置任意张“俭”,令一名体力值不大于X的角色回复1点体力(X为你以此法弃置的牌数)。', - gzzhuidu:'追妒', - gzzhuidu_info:'出牌阶段限一次。当你造成伤害时,你可以令受伤角色选择一项:1.此伤害+1;2.弃置装备区里的所有牌。若该角色为女性,则你可以弃置一张牌,改为令其选择两项。', - gzshigong:'示恭', - gzshigong_info:'限定技。当你于回合外进入濒死状态时,你可以移除副将,然后令当前回合角色选择一项:1.获得你以此法移除的副将武将牌上的一个没有技能标签的技能,然后令你将体力值回复至体力上限;2.令你将体力值回复至1点。', - gz_old_huaxiong:'华雄', - gzyaowu:'耀武', - gzyaowu_info:'限定技。当你造成伤害后,你可以明置此武将牌,然后你加2点体力上限并回复2点体力,修改〖恃勇〗,且当你死亡后,所有与你势力相同的角色失去1点体力。', - gzshiyong:'恃勇', - gzshiyong_info:'锁定技。当你受到牌造成的伤害后,若此牌不为红色,你摸一张牌。', - gzshiyongx:'恃勇·改', - gzshiyongx_info:'锁定技。当你受到牌造成的伤害后,若此牌不为黑色,伤害来源摸一张牌。', - gztanfeng:'探锋', - gztanfeng_info:'准备阶段,你可以弃置与你势力不同的一名角色区域内的一张牌,然后其可以令你对其造成1点火焰伤害,并令你跳过本回合的一个阶段(准备阶段和结束阶段除外)。', + gzdangxian: "当先", + gzdangxian_info: + "锁定技。当你首次明置此武将牌时,你获得一枚“先驱”标记。回合开始时,你获得一个额外的出牌阶段。", + gzhuanshi: "缓释", + gzhuanshi_info: "一名己方角色的判定牌生效前,你可打出一张牌代替之。", + gzhongyuan: "弘援", + gzhongyuan_info: + "①出牌阶段限一次。你可以令一张没有「合纵」标签的卡牌视为拥有「合纵」标签直到本回合结束。②当你即将因合纵效果摸牌时,你可放弃摸牌,并令一名己方角色摸等量的牌。", + gzmingzhe: "明哲", + gzmingzhe_info: + "你的回合外,当你使用或打出红色手牌,或失去装备区内的红色装备牌时,你可摸一张牌。", + gzxiongzhi: "雄志", + gzxiongzhi_info: "限定技。出牌阶段,你可依次展示牌堆顶的X张牌并使用之(X为你的体力上限)。", + gzquanbian: "权变", + gzquanbian_info: + "当你于出牌阶段内使用/打出手牌时,若此牌有花色且你本回合内未使用/打出过该花色的其他手牌,则你可以观看牌堆顶X张牌,选择获得其中的一张并展示之。若你本回合使用过与得到的牌花色相同的牌,则你本回合内不能再发动〖权变〗。", + gzhuishi: "慧识", + gzhuishi_info: + "摸牌阶段,你可以放弃摸牌,改为观看牌堆顶的X张牌,获得其中的一半(向下取整),然后将其余牌置入牌堆底。(X为弃牌堆顶的两张牌的名称字数之和)", + gzqingleng: "清冷", + gzqingleng_info: + "一名角色的回合结束时,若其有未明置的武将牌,则你可将一张牌当无距离限制的冰属性【杀】对其使用;若其所有武将牌均未明置,则你摸一张牌。", + gzchoufa: "筹伐", + gzchoufa_info: + "出牌阶段限一次,你可展示一名其他角色的一张手牌A。你令其所有类型与A不同的手牌的牌名均视为【杀】且均视为无属性直到本回合结束。", + gzbolan: "博览", + gzbolan_info: + "每名角色的出牌阶段限一次。其可以随机展示武将牌堆顶的一张武将牌,然后根据此武将牌包含的势力选择获得一个技能直到回合结束:魏:〖奇策〗;蜀:〖挑衅〗;吴:〖制衡〗;群:〖除疠〗;晋:〖三陈〗。若该角色不为你,则其失去1点体力。", + gzsanchen: "三陈", + gzsanchen_info: + "出牌阶段,你可选择一名本回合内未选择过的角色。其摸三张牌,然后弃置三张牌。若其未以此法弃置牌或以此法弃置的牌的类别均不相同,则你于本回合获得一枚“陈”且其摸一张牌;否则你本阶段内不能再发动〖三陈〗。", + gzpozhu: "破竹", + gzpozhu_info: + "主将技。此武将牌减少半个阴阳鱼。出牌阶段,你可以移去一枚“陈”并将一张手牌当做【出其不意】使用。", + gzyimie: "夷灭", + gzyimie_info: + "主将技,此武将牌减少一整个阴阳鱼。每回合限一次,当你对其他角色造成伤害时,若伤害值X小于Y,则你可失去1点体力,将伤害值改为Y。此伤害结算结束后,其回复(Y-X)点体力。(Y为其体力值)", + gztairan: "泰然", + gztairan_info: + "出牌阶段开始时,你可以失去任意点体力并弃置任意张牌(弃牌数不能大于你已损失的体力值)。若如此做,本回合结束时,你回复等量的体力并摸等量的牌。", + gzxuanbei: "选备", + gzxuanbei_info: + "①当你首次明置此武将牌时,你获得两张拥有“应变”或“合纵”标签的牌(不足则摸牌),且你本回合内使用带有“应变”标签的牌时直接强化,使用带有“合纵”标签的牌时摸一张牌。②当你死亡时,你可以令一名其他角色变更副将。", + gzzhaosong: "诏颂", + gzzhaosong_info: + "每局游戏每项限一次。①一名角色进入濒死状态时,你可以令其回复至2点体力并摸一张牌。②出牌阶段,你可观看一名其他角色的所有暗置武将牌和手牌,然后可以获得其区域内的一张牌。③一名角色使用【杀】选择唯一目标后,你可以为此【杀】增加两个目标。", + gzlisi: "离思", + gzlisi_info: "一名己方角色死亡后,你可以选择〖诏颂〗中的一个已发动过的选项,令其视为未发动过。", + gzcaiyuan: "才媛", + gzcaiyuan_info: + "锁定技。结束阶段,若你的手牌数大于本回合开始时的手牌数,则你摸两张牌或回复1点体力。", + gzwanyi: "婉嫕", + gzwanyi_info: + "出牌阶段每项各限一次。你可以将一张带有“合纵”标签的牌当做【联军盛宴】/【火烧连营】/【挟天子以令诸侯】/【戮力同心】使用。", + gzwanyi_info_guozhan_yingbian: + "出牌阶段每项各限一次。你可以将一张带有“应变”标签的牌当做【逐近弃远】/【洞烛先机】/【水淹七军】/【出其不意】使用。", + gzmaihuo: "埋祸", + gzmaihuo_info: + "限定技。当有己方角色成为【杀】的目标时,你可以取消此【杀】的所有目标。然后此【杀】的使用者下回合开始时,其视为对你使用一张【杀】。若此【杀】对你造成伤害,则你防止此伤害,摸两张牌并移除此武将牌(若此武将牌为副将则改为变更副将)。", + gzzhenxi: "震袭", + gzzhenxi_info: + "当你使用【杀】指定目标后,你可以选择一项:1.弃置目标角色一张牌;2.将一张♦非锦囊牌当做【乐不思蜀】或♣非锦囊牌当做【兵粮寸断】对目标角色使用;3.背水:若其有暗置的武将牌且你的武将牌均明置,则你可以依次执行这两项。", + gzjiansu: "俭素", + gzjiansu_tag: "俭", + gzjiansu_info: + "副将技。此武将牌减少半个阴阳鱼。①当你于回合外得到牌后,你可以展示这些牌,称为“俭”。②出牌阶段开始时,你可以弃置任意张“俭”,令一名体力值不大于X的角色回复1点体力(X为你以此法弃置的牌数)。", + gzzhuidu: "追妒", + gzzhuidu_info: + "出牌阶段限一次。当你造成伤害时,你可以令受伤角色选择一项:1.此伤害+1;2.弃置装备区里的所有牌。若该角色为女性,则你可以弃置一张牌,改为令其选择两项。", + gzshigong: "示恭", + gzshigong_info: + "限定技。当你于回合外进入濒死状态时,你可以移除副将,然后令当前回合角色选择一项:1.获得你以此法移除的副将武将牌上的一个没有技能标签的技能,然后令你将体力值回复至体力上限;2.令你将体力值回复至1点。", + gz_old_huaxiong: "华雄", + gzyaowu: "耀武", + gzyaowu_info: + "限定技。当你造成伤害后,你可以明置此武将牌,然后你加2点体力上限并回复2点体力,修改〖恃勇〗,且当你死亡后,所有与你势力相同的角色失去1点体力。", + gzshiyong: "恃勇", + gzshiyong_info: "锁定技。当你受到牌造成的伤害后,若此牌不为红色,你摸一张牌。", + gzshiyongx: "恃勇·改", + gzshiyongx_info: "锁定技。当你受到牌造成的伤害后,若此牌不为黑色,伤害来源摸一张牌。", + gztanfeng: "探锋", + gztanfeng_info: + "准备阶段,你可以弃置与你势力不同的一名角色区域内的一张牌,然后其可以令你对其造成1点火焰伤害,并令你跳过本回合的一个阶段(准备阶段和结束阶段除外)。", //官盗「群雄割据」 - gzduanshi:'断势', - gzduanshi_info:'主将技,锁定技。此武将牌减少半个阴阳鱼。当一名角色因杀死与你势力相同的角色而摸牌时,其少摸一张牌。然后你摸一张牌。', - gzjingce:'精策', - gzjingce_info:'回合结束时,若于本回合内进入弃牌堆的牌数不小于X,你可以执行一个额外的摸牌阶段;若你本回合使用过的牌数不小于X,你可以执行一个额外的出牌阶段(X为你的体力值)。', - gzzhengrong:'征荣', - gzzhengrong_info:'锁定技。①你至大势力角色的距离-1。②当你选择“军令”时,你令可选军令数量+1。③当你造成或受到伤害时,若你没有存活的队友,则此伤害+1。', - gzhongju:'鸿举', - gzhongju_info:'限定技。出牌阶段,你可以选择一名其他角色A并选择一个“军令”。你执行该军令,然后令除A以外的所有其他角色依次选择一项:⒈执行该军令。⒉于本回合视为移出游戏。', - gzbiaozhao:'表召', - gzbiaozhao_info:'出牌阶段限一次。你可以选择两名势力不同的其他角色A和B。你视为对A使用一张【知己知彼】,然后将一张牌交给B并摸一张牌。', - gzyechou:'业仇', - gzyechou_info:'锁定技。当你死亡时,你视为对杀死你的角色依次使用三张【杀】,其中第一张不可被响应,第二张无视防具,第三张对其造成的伤害+1。若其以此法进入濒死状态,则于本次濒死结算中除其外与其势力相同的角色不能对其使用【桃】。', + gzduanshi: "断势", + gzduanshi_info: + "主将技,锁定技。此武将牌减少半个阴阳鱼。当一名角色因杀死与你势力相同的角色而摸牌时,其少摸一张牌。然后你摸一张牌。", + gzjingce: "精策", + gzjingce_info: + "回合结束时,若于本回合内进入弃牌堆的牌数不小于X,你可以执行一个额外的摸牌阶段;若你本回合使用过的牌数不小于X,你可以执行一个额外的出牌阶段(X为你的体力值)。", + gzzhengrong: "征荣", + gzzhengrong_info: + "锁定技。①你至大势力角色的距离-1。②当你选择“军令”时,你令可选军令数量+1。③当你造成或受到伤害时,若你没有存活的队友,则此伤害+1。", + gzhongju: "鸿举", + gzhongju_info: + "限定技。出牌阶段,你可以选择一名其他角色A并选择一个“军令”。你执行该军令,然后令除A以外的所有其他角色依次选择一项:⒈执行该军令。⒉于本回合视为移出游戏。", + gzbiaozhao: "表召", + gzbiaozhao_info: + "出牌阶段限一次。你可以选择两名势力不同的其他角色A和B。你视为对A使用一张【知己知彼】,然后将一张牌交给B并摸一张牌。", + gzyechou: "业仇", + gzyechou_info: + "锁定技。当你死亡时,你视为对杀死你的角色依次使用三张【杀】,其中第一张不可被响应,第二张无视防具,第三张对其造成的伤害+1。若其以此法进入濒死状态,则于本次濒死结算中除其外与其势力相同的角色不能对其使用【桃】。", //官盗「十年经典」 - gzdianhu:'点虎', - gzdianhu_info:'锁定技。当你首次明置此武将牌时,你选择一名其他角色。与你势力相同的角色对其造成伤害后,伤害来源摸一张牌。', - gzjianji:'谏计', - gzjianji_info:'出牌阶段限一次。你可以令一名角色摸一张牌并展示之,然后其可以使用此牌。', - gzgongjian:'攻坚', - gzgongjian_info:'①当其他角色的牌因弃置而进入弃牌堆后,若令其弃置这些牌的角色为你,你获得其中所有的【杀】。②每回合限一次,当一名角色使用【杀】指定目标后,若有目标与本局游戏上一张被使用的【杀】相同,你可以令这些目标弃置两张牌。', - gzkuimang:'溃蟒', - gzkuimang_info:'锁定技。当你杀死与你势力不同且处于队列的角色时,你摸两张牌。', - gzyinpan:'引叛', - gzyinpan_info:'出牌阶段限一次。你可以选择一名其他角色,令所有与其势力不同的角色依次选择是否对其使用一张【杀】。然后其下回合使用【杀】的次数上限+X(X为其以此法受到的伤害次数),若其以此法进入过濒死状态,其回复1点体力。', - gzxingmou:'兴谋', - gzxingmou_info:'锁定技。①你杀死其他角色或其他角色杀死你均不执行奖惩。②其他角色因执行奖惩而摸牌时,你摸一张牌。', + gzdianhu: "点虎", + gzdianhu_info: + "锁定技。当你首次明置此武将牌时,你选择一名其他角色。与你势力相同的角色对其造成伤害后,伤害来源摸一张牌。", + gzjianji: "谏计", + gzjianji_info: "出牌阶段限一次。你可以令一名角色摸一张牌并展示之,然后其可以使用此牌。", + gzgongjian: "攻坚", + gzgongjian_info: + "①当其他角色的牌因弃置而进入弃牌堆后,若令其弃置这些牌的角色为你,你获得其中所有的【杀】。②每回合限一次,当一名角色使用【杀】指定目标后,若有目标与本局游戏上一张被使用的【杀】相同,你可以令这些目标弃置两张牌。", + gzkuimang: "溃蟒", + gzkuimang_info: "锁定技。当你杀死与你势力不同且处于队列的角色时,你摸两张牌。", + gzyinpan: "引叛", + gzyinpan_info: + "出牌阶段限一次。你可以选择一名其他角色,令所有与其势力不同的角色依次选择是否对其使用一张【杀】。然后其下回合使用【杀】的次数上限+X(X为其以此法受到的伤害次数),若其以此法进入过濒死状态,其回复1点体力。", + gzxingmou: "兴谋", + gzxingmou_info: + "锁定技。①你杀死其他角色或其他角色杀死你均不执行奖惩。②其他角色因执行奖惩而摸牌时,你摸一张牌。", //官正「十年踪迹十年心」 - gzyouyan:'诱言', - gzyouyan_info:'回合内限一次。当你的牌因弃置而进入弃牌堆后,你可以展示牌堆顶的四张牌,然后获得其中与你此次弃置的牌花色均不同的牌。', - gzzhuihuan:'追还', - gzzhuihuan_info:'结束阶段,你可以选择至多两名角色,然后依次为被选择的角色标记A或B(字母不能重复标记)。直到你的下回合开始,当A第一次受到伤害后,其对来源造成1点伤害;当B第一次受到伤害后,来源弃置两张手牌。', + gzyouyan: "诱言", + gzyouyan_info: + "回合内限一次。当你的牌因弃置而进入弃牌堆后,你可以展示牌堆顶的四张牌,然后获得其中与你此次弃置的牌花色均不同的牌。", + gzzhuihuan: "追还", + gzzhuihuan_info: + "结束阶段,你可以选择至多两名角色,然后依次为被选择的角色标记A或B(字母不能重复标记)。直到你的下回合开始,当A第一次受到伤害后,其对来源造成1点伤害;当B第一次受到伤害后,来源弃置两张手牌。", //插个眼,手杀国战新张鲁 - gzrebushi:'布施', - gzrebushi_info:'①回合结束后,你获得X个“义舍”标记(X为你的体力值)。②其他角色的准备阶段,你可以失去1个“义舍”标记,交给其一张牌并摸两张牌。③准备阶段,你须弃置Y张牌,然后失去所有“义舍”标记(Y为场上存活人数-你的体力值-2)。', - gzremidao:'米道', - gzremidao_info:'①结束阶段,若你的武将牌上没有“米”,则你可以摸两张牌。若如此做,你将两张牌置于武将牌上,称为“米”。②一名角色的判定牌生效前,你可以打出一张“米”作为新的判定牌,然后你获得原判定牌。', - jiahe_reyingzi:'英姿', - jiahe_haoshi:'好施', - jiahe_shelie:'涉猎', - jiahe_duoshi:'度势', + gzrebushi: "布施", + gzrebushi_info: + "①回合结束后,你获得X个“义舍”标记(X为你的体力值)。②其他角色的准备阶段,你可以失去1个“义舍”标记,交给其一张牌并摸两张牌。③准备阶段,你须弃置Y张牌,然后失去所有“义舍”标记(Y为场上存活人数-你的体力值-2)。", + gzremidao: "米道", + gzremidao_info: + "①结束阶段,若你的武将牌上没有“米”,则你可以摸两张牌。若如此做,你将两张牌置于武将牌上,称为“米”。②一名角色的判定牌生效前,你可以打出一张“米”作为新的判定牌,然后你获得原判定牌。", + jiahe_reyingzi: "英姿", + jiahe_haoshi: "好施", + jiahe_shelie: "涉猎", + jiahe_duoshi: "度势", //国战典藏2023 - gzdiaodu:'调度', - gzdiaodu_info:'①与你势力相同的角色使用装备牌时,其可以摸一张牌。②出牌阶段开始时,你可以获得一名与你势力相同的角色的装备区里的一张牌,然后你将此牌交给另一名角色。', - gzqiance:'谦策', - gzqiance_info:'与你势力相同的角色使用锦囊牌指定第一个目标后,你可以令其中的所有大势力角色无法响应此牌。', - gzjujian:'举荐', - gzjujian_info:'副将技,锁定技。①此武将牌计算体力上限时减少半个阴阳鱼。②与你势力相同的角色进入濒死状态时,你可以令其将体力值回复至1点,然后你变更副将。', - gztongling:'通令', - gztongling_info:'出牌阶段限一次,当你对一名与你势力不同的角色A造成伤害后,你可以选择一名与你势力相同的角色B,令B选择是否对A使用一张牌。若B选择使用,则此牌结算后,若此牌造成过伤害,你和B各摸两张牌,否则A获得你对其造成伤害的牌。', - gzjinyu:'近谀', - gzjinyu_info:'当你明置此武将牌后,你令所有与你距离为1以内的角色依次执行以下效果:若其武将牌均明置,则其选择一张武将牌暗置,否则其弃置两张牌。', - gzrehuaiyi:'怀异', - gzrehuaiyi_info:'出牌阶段限一次,你可以展示所有手牌。若其中至少包含两种颜色,则你可以弃置其中一种颜色的所有牌,然后获得至多等量名角色的各一张牌。然后你将以此法得到的装备牌置于武将牌上,称为“异”。你可以将“异”如手牌般使用或打出。', - gzrezisui:'恣睢', - gzrezisui_info:'锁定技。①摸牌阶段,你多摸X张牌。②结束阶段,若X大于你的体力上限,你死亡(X为你武将牌上的“异”数)。', - gztaidan:'太丹', - gztaidan_taipingyaoshu:'太丹', - gztaidan_info:'锁定技,若你的防具栏为空且你的防具栏未被废除,你视为装备【太平要术】。', - gzrejinghe:'经合', - gzrejinghe_info:'出牌阶段限一次,你可以转动“天书”,然后令一名角色获得“天书”向上一面的技能直到你的下个回合开始。', - gzrejinghe_faq:'转动“天书”', - gzrejinghe_faq_info:'
                            • 若游戏未拥有“天书”,系统将[雷击,阴兵,活气,鬼助,仙授,论道,观月,言政]以顺时针方向组成圆环作为“天书”,并转动圆环将随机一个技能至于最上面。
                            • 若游戏已拥有“天书”,则以逆时针方向转动转动“天书”至下个技能于最上面。', + gzdiaodu: "调度", + gzdiaodu_info: + "①与你势力相同的角色使用装备牌时,其可以摸一张牌。②出牌阶段开始时,你可以获得一名与你势力相同的角色的装备区里的一张牌,然后你将此牌交给另一名角色。", + gzqiance: "谦策", + gzqiance_info: + "与你势力相同的角色使用锦囊牌指定第一个目标后,你可以令其中的所有大势力角色无法响应此牌。", + gzjujian: "举荐", + gzjujian_info: + "副将技,锁定技。①此武将牌计算体力上限时减少半个阴阳鱼。②与你势力相同的角色进入濒死状态时,你可以令其将体力值回复至1点,然后你变更副将。", + gztongling: "通令", + gztongling_info: + "出牌阶段限一次,当你对一名与你势力不同的角色A造成伤害后,你可以选择一名与你势力相同的角色B,令B选择是否对A使用一张牌。若B选择使用,则此牌结算后,若此牌造成过伤害,你和B各摸两张牌,否则A获得你对其造成伤害的牌。", + gzjinyu: "近谀", + gzjinyu_info: + "当你明置此武将牌后,你令所有与你距离为1以内的角色依次执行以下效果:若其武将牌均明置,则其选择一张武将牌暗置,否则其弃置两张牌。", + gzrehuaiyi: "怀异", + gzrehuaiyi_info: + "出牌阶段限一次,你可以展示所有手牌。若其中至少包含两种颜色,则你可以弃置其中一种颜色的所有牌,然后获得至多等量名角色的各一张牌。然后你将以此法得到的装备牌置于武将牌上,称为“异”。你可以将“异”如手牌般使用或打出。", + gzrezisui: "恣睢", + gzrezisui_info: + "锁定技。①摸牌阶段,你多摸X张牌。②结束阶段,若X大于你的体力上限,你死亡(X为你武将牌上的“异”数)。", + gztaidan: "太丹", + gztaidan_taipingyaoshu: "太丹", + gztaidan_info: "锁定技,若你的防具栏为空且你的防具栏未被废除,你视为装备【太平要术】。", + gzrejinghe: "经合", + gzrejinghe_info: + "出牌阶段限一次,你可以转动“天书”,然后令一名角色获得“天书”向上一面的技能直到你的下个回合开始。", + gzrejinghe_faq: "转动“天书”", + gzrejinghe_faq_info: + "
                            • 若游戏未拥有“天书”,系统将[雷击,阴兵,活气,鬼助,仙授,论道,观月,言政]以顺时针方向组成圆环作为“天书”,并转动圆环将随机一个技能至于最上面。
                            • 若游戏已拥有“天书”,则以逆时针方向转动转动“天书”至下个技能于最上面。", - gz_key_ushio:'冈崎汐', - ushio_huanxin:'幻心', - ushio_huanxin_info:'当你受到伤害后/使用【杀】造成伤害后/使用装备牌后,你可进行判定。然后你获得判定牌并弃置一张牌。', - ushio_xilv:'汐旅', - ushio_xilv2:'汐旅', - ushio_xilv_info:'锁定技,此武将牌可作为任意单势力武将牌的副将。当你进行判定后,你令你的手牌上限+1直至你的下个结束阶段。', + gz_key_ushio: "冈崎汐", + ushio_huanxin: "幻心", + ushio_huanxin_info: + "当你受到伤害后/使用【杀】造成伤害后/使用装备牌后,你可进行判定。然后你获得判定牌并弃置一张牌。", + ushio_xilv: "汐旅", + ushio_xilv2: "汐旅", + ushio_xilv_info: + "锁定技,此武将牌可作为任意单势力武将牌的副将。当你进行判定后,你令你的手牌上限+1直至你的下个结束阶段。", //官盗2023 - fakexiaoguo:'骁果', - fakexiaoguo_info:'一名其他角色的准备阶段,你可以弃置任意张基本牌,然后弃置其装备区等量的牌,若其装备区的牌数小于你弃置的牌数,则你对其造成1点伤害。', - fakeduanbing:'短兵', - fakeduanbing_info:'①你使用【杀】可以额外指定一名距离为1或以内的目标。②当你使用【杀】指定唯一目标后,你令目标角色需要额外使用一张【闪】响应此【杀】。', - fakeduoshi:'度势', - fakeduoshi_info:'每轮限一次,友方角色可以将一张红色手牌当作【以逸待劳】使用,然后若你为小势力角色,你可以令一名友方角色将X张手牌当作不可被响应的【火烧连营】使用(X为此【以逸待劳】指定的目标数)。', - fakehanzhan:'酣战', - fakehanzhan_info:'有你参与的拼点事件结束后,没赢的角色可以获得对方装备区的一张牌。', - fakeshuangxiong:'双雄', - fakeshuangxiong_info:'①摸牌阶段,你可以放弃摸牌并进行判定,本回合你可以将一张与此牌颜色不同的手牌当作【决斗】使用。②当你的判定牌于回合内生效后,你获得此牌。', - fakeyicheng:'疑城', - fakeyicheng_info:'与你势力相同的角色成为【杀】的目标后,你可以令其摸一张牌,然后其可以使用一张装备牌,其于此回合结束时弃置X张牌(X为你本回合对其发动此技能的次数)。', - fakefenming:'奋命', - fakefenming_info:'出牌阶段限一次,若你处于横置状态,你可以弃置所有处于横置状态的角色的各一张牌。', - fakebaoling:'暴凌', - fakebaoling_info:'主将技,锁定技,出牌阶段结束时,若你有副将,则你移除副将,加3点体力上限并回复3点体力,然后获得〖崩坏〗。', - fakebenghuai:'崩坏', - fakebenghuai_info:'结束阶段,若你的体力值不为全场最低,则你选择一项:①失去1点体力;②减1点体力上限;③背水:执行一个额外的摸牌阶段。', - fakediaodu:'调度', - fakediaodu_info:'①每回合每种牌的类别限一次,与你势力相同的角色使用牌时,若此牌有目标且包含其,则其可以摸一张牌。②出牌阶段开始时,你可以获得与你势力相同的一名角色装备区内的一张牌,然后你可以将此牌交给另一名与你势力相同的其他角色。', - fakeyigui:'役鬼', - fakeyigui_info:'①当你首次明置此武将牌时,你将剩余武将牌堆的两张牌称为“魂”置于武将牌上。②你可以展示一张武将牌上的“魂”并将其置入剩余武将牌堆,视为使用一张本回合内未以此法使用过的类别的基本牌或普通锦囊牌(此牌须指定目标,且目标须为未确定势力的角色或野心家或与此“魂”势力相同的角色)。', - fakejihun:'汲魂', - fakejihun_info:'①当你受到伤害后,或与你势力不同的角色脱离濒死状态后,你可以将剩余武将牌堆的一张牌称为“魂”置于武将牌上。②准备阶段,你可以将至多两张“魂”置入剩余武将牌堆,然后将剩余武将牌堆的等量张牌称为“魂”置于武将牌上。', - fakejueyan:'决堰', - fakejizhi:'集智', - fakejueyan_info:'主将技。①此武将牌计算体力上限时减少半个阴阳鱼。②准备阶段,你可以选择一个区域并于本回合的结束阶段弃置此区域的所有牌,然后你于本回合获得以下对应效果:⒈判定区:跳过判定阶段,获得〖集智〗直到回合结束;⒉装备区:摸三张牌,本回合手牌上限+3;⒊本回合使用【杀】的额定次数+3。', - fakequanji:'权计', - fakequanji_info:'①每回合每项各限一次,当你造成或受到伤害后,你可以摸X张牌,然后将等量的牌称为“权”置于武将牌上。②你的手牌上限+X(X为你武将牌上的“权”数)。', - fakepaiyi:'排异', - fakepaiyi_info:'出牌阶段限一次,你可以选择一名角色,然后选择一个军令令其选择是否执行。若其执行,则你摸X张牌,然后将一张“权”置入弃牌堆;若其不执行,则你可以对至多X名与其势力相同的角色各造成1点伤害,然后将等量的“权”置入弃牌堆。(X为你武将牌上的“权”数)', - fakeshilu:'嗜戮', - fakeshilu_info:'①出牌阶段结束时,若你有副将且本阶段未发动过副将武将牌上的非锁定技,则你更换副将至你武将牌上的“戮”未包含的势力并将原副将称为“戮”置于武将牌上。②准备阶段,你弃置X张手牌,然后摸X张牌(X为你武将牌上的“戮”数,少牌全弃,无牌不弃)。', - fakexiongnve:'凶虐', - fakexiongnve_info:'①当你使用【杀】造成伤害时或受到【杀】造成的伤害时,若你武将牌上的“戮”包含伤害来源的势力,则你令此伤害+1。②当你受到不为【杀】造成的伤害时,若你武将牌上的“戮”包含伤害来源的势力,则此伤害-1。', - fakehuaiyi:'怀异', - fakehuaiyi_info:'出牌阶段限一次,你可以移除副将或弃置一个区域的所有牌,然后令所有大势力角色依次交给你至少一张牌,然后若存在多个大势力,则你移除一个此次交给你牌总数唯一最少的势力的其中一名角色的副将。', - fakezisui:'恣睢', - fakezisui_info:'锁定技。①一名角色被你移除副将后,你将被移除的武将牌称为“异”置于武将牌上。②摸牌阶段,你多摸X张牌。③结束阶段,若X大于你的体力上限,你死亡。(X为你武将牌上的“异”数)', - fakejujian:'举荐', - fakejujian_info:'副将技。①此武将牌计算体力上限时减少半个阴阳鱼。②结束阶段,你可以弃置一张非基本牌并选择一名友方角色,令其选择摸两张牌或回复1点体力,然后其可以变更副将。', - fakexibing:'息兵', - fakexibing_info:'当一名其他角色在其出牌阶段内使用第一张黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至体力值且本回合不能再使用手牌。若你与其均明置了所有武将牌,则你可以暗置你与其各一张武将牌且本回合不能再明置此武将牌。', - fakechengshang:'承赏', - fakechengshang_info:'出牌阶段限一次,当你使用存在花色和点数且指定了其他势力角色为目标的牌结算完毕后,若你未因此牌造成过伤害,则你可以摸一张牌,然后本阶段你可以将一张手牌当作初始游戏牌堆中与此牌花色和点数相同的另一张基本牌或普通锦囊牌使用一次。', - fakezhente:'贞特', - fakezhente_info:'每回合限一次,当你成为其他角色使用普通锦囊牌或黑色基本牌的目标后,你可令使用者选择一项:1.本回合不能再使用与此牌颜色相同的牌;2.令此牌对你无效。', - fakezhiwei:'至微', - fakezhiwei_info:'你明置此武将牌时,选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。该角色死亡时,若你的两个武将牌均明置,你暗置此武将牌。若该角色未死亡,则此武将牌被暗置前,取消之。', - fakekuangcai:'狂才', - fakekuangcai_info:'锁定技,你于回合内使用牌无距离和次数限制;弃牌阶段开始时,若你本回合内:未使用过牌,则你本回合手牌上限+1;使用过牌但未造成过伤害,则你本回合手牌上限-1。', - faketunchu:'屯储', - faketunchu_info:'摸牌阶段,你可以额外摸两张牌,然后你将一至两张牌称为“粮”置于武将牌上。若如此做,你本回合不能使用【杀】。', - fakeshuliang:'输粮', - fakeshuliang_info:'友方角色的结束阶段,若你与其的距离不大于你武将牌上的“粮”数,则你可以移去一张“粮”,然后令其摸两张牌。', - fakedujin:'独进', - fakedujin_info:'①摸牌阶段,你可以额外摸X张牌(X为你装备区的牌数的一半,向上取整)。②当你首次明置此武将牌时,若你为你们势力第一个明置武将牌的角色,则你获得1个“先驱”标记。', - fakezhufu:'注傅', - fakezhufu_info:'出牌阶段,你可以弃置一张本阶段未以此法弃置过的花色的牌,然后根据此牌的花色为你使用的下一张牌添加对应的应变效果:红桃,助战、目标+1;方片,富甲、不可被响应;黑桃,残躯、摸一张牌;草花,空巢、伤害+1。', - fakeguishu:'鬼术', - fakeguishu_info:'出牌阶段限一次,你可以将一张黑桃手牌当作【知己知彼】或【远交近攻】使用。若你本局游戏内已经发动过了〖鬼术〗,则你必须选择与上次不同的选项。', - fakeyuanyu:'远域', - fakeyuanyu_info:'锁定技,当你受到伤害时,若你不在伤害来源的攻击范围内,则防止此伤害。', - fakemibei:'秘备', - fakemibei_info:'①准备阶段,若你的手牌数不为全场最多,则你须选择一名手牌数为全场最多的角色,令其对你发起军令。②当你执行军令后,你将手牌数摸至与发起者相同(至多摸五张)。③当你拒绝执行军令后,你展示一至三张牌,然后你本回合可以将其中一张牌当作另一张基本牌或非延时锦囊牌使用一次。', - fakeqizhi:'奇制', - fakeqizhi_info:'当你于回合内声明使用非装备牌A时,你可以弃置不是此牌目标的一名角色的一张牌B,然后其摸一张牌。若A具有应变效果,且A和B的花色相同,则你无视条件触发A的应变效果。', - fakejinqu:'进趋', - fakejinqu_info:'结束阶段,你可以摸两张牌,然后你将手牌弃置至X张(X为你本回合发动过〖奇制〗的次数)。', - fakejuzhan:'拒战', - fakejuzhan_info:'转换技。阴:当你成为【杀】的目标后,你可以与使用者各摸X张牌,然后若使用者的武将牌均明置,则你可以暗置其一张武将牌,且其本回合不能明置此武将牌。阳,当你使用【杀】指定目标后,你可以获得目标角色的X张牌,然后若你的武将牌均明置,则其可以暗置此武将牌,且你本回合不能明置此武将牌。(X为使用者已损失的体力值且X至少为1)', - fakedanshou:'胆守', - fakedanshou_info:'每轮限一次,一名角色的准备阶段,你可以弃置一个区域的所有牌。若如此做,本回合其每个阶段开始时(准备阶段和结束阶段除外),你摸一张牌或令本回合以此法摸牌数+1,然后若你选择了摸牌且你本次至少摸了四张牌,则你可以对其造成1点伤害。', - fakexunxi:'迅析', - fakexunxi_info:'其他角色于回合外明置武将牌时,你可以视为对其使用一张【杀】(无距离限制)。', - fakehuanjia:'擐甲', - fakehuanjia_info:'锁定技,每回合每项各限一次。①当你成为【杀】的目标后,本回合你视为装备此牌使用者的防具,直到你的装备区中有防具。②当你使用【杀】指定唯一目标后,本回合你视为装备目标角色的武器,直到你的装备区中有武器。', - fakexiongshu:'凶竖', - fakexiongshu_info:'每回合限一次,一名角色使用【杀】或伤害类锦囊牌指定第一个目标后,若你为/不为此牌使用者,则你可以摸一张牌并令一名其他角色成为此牌的伤害来源/弃置一张牌并成为此牌的伤害来源。', - fakejianhui:'奸回', - fakejianhui_info:'当一名角色受到其势力相同的另一名角色造成的伤害后,你可以令其中一名角色摸一张牌,然后弃置其中另一名角色的一张牌。', - fakechongxin:'崇信', - fakechongxin_info:'出牌阶段限一次,你可以选择一名与你势力不同的角色,视为你使用一张指定你与其为目标的【以逸待劳】。', - fakeweirong:'卫戎', - fakeweirong_info:'转换技,每轮限一次,出牌阶段。阴:你可以弃置X张牌,然后当你于本轮不因此法得到牌后,你摸一张牌。阳:你可以摸X张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)', - gz_re_taishici:'太史慈', - gz_xin_zhuran:'朱然', - gz_jin_jiachong:'贾充', - gz_jin_yanghu:'羊祜', - gz_wangling:'王淩', - fakequanbian:'权变', - fakequanbian_tag:'牌堆顶', - fakequanbian_info:'当你于回合内使用或打出牌时,你可以将一张手牌与牌堆顶X张牌的其中一张进行交换(X为你的体力上限)。', - fakezhouting:'骤霆', - fakezhouting_info:'限定技,出牌阶段,你可以依次使用牌堆顶X张牌中所有可以使用的牌,然后获得其中不能使用的牌,然后若有角色因此死亡,则你重置〖骤霆〗(X为你的体力上限)。', - fakexuanbei:'选备', - fakexuanbei_info:'①当你首次明置此武将牌时,你摸两张牌,且你本回合内使用带有“应变”标签的牌时直接强化。②每回合限一次,当你使用带有“应变”标签的牌结算完毕后,你可以令一名其他角色获得此牌对应的所有实体牌。③当你死亡时,你可以令一名其他角色变更副将。', - fakeqingleng:'清冷', - fakeqingleng_info:'其他角色的结束阶段,若其武将牌均明置,则你可以将一张牌当作冰【杀】对其使用(无距离限制)。然后若此牌未对其造成伤害,则你暗置其一张武将牌,且直到其下个回合开始,其明置此武将牌时,你对其造成1点伤害。', - fakexijue:'袭爵', - fakexijue_info:'①当你首次明置此武将牌时,你获得2枚“爵”标记。②回合结束时,若你本回合造成过伤害,则你获得1枚“爵”标记。③你可以于合适的时机发动〖突袭〗或〖骁果〗(至多弃置X张基本牌),然后移去1枚“爵”标记。④摸牌阶段,你改为摸X张牌。(X为你的“爵”标记数,且X至多为你的体力上限)', - fakexijue_xiaoguo:'骁果', - fakexijue_xiaoguo_info:'一名其他角色的准备阶段,你可以弃置至多X张基本牌(X为你的“爵”标记数,且X至多为你的体力上限),然后弃置其装备区等量的牌,若其装备区的牌数小于你弃置的牌数,则你对其造成1点伤害。', - fakeqimei:'齐眉', - fakeqimei_info:'准备阶段,你可以选择一名其他角色。若如此做,直到回合结束:当你或其获得牌/失去手牌后,若你与其手牌数相等,则另一名角色回复1点体力;当你或其的体力值变化后,若你与其体力值相等,则另一名角色摸一张牌。', - fakebaoqie:'宝箧', - fakebaoqie_info:'①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以获得一名角色的宝物牌,然后你可以使用其中的一张牌。', - fakeciwei:'慈威', - fakeciwei_info:'其他角色于一回合内使用第偶数张牌时,你可以弃置一张牌并取消此牌的所有目标,然后若此牌为装备牌,你可以获得之且你可以使用之。', - fakehuirong:'慧容', - fakehuirong_info:'①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以令一名角色将手牌数调整至其体力值。', - fakeyanxi:'宴戏', - fakeyanxi_info:'出牌阶段限一次,你可以展示一名其他角色的一张手牌和牌堆顶的两张牌,然后你获得其中一种颜色或类别的所有牌且本回合手牌上限+X(X为你获得的牌数),然后其获得剩余的牌。', - fakeshiren:'识人', - fakeshiren_info:'①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以发动一次〖宴戏〗。', - fakecanmou:'参谋', - fakecanmou_info:'每回合每项限一次,一名角色使用普通锦囊牌指定第一个目标时,若其手牌数为全场唯一最多,则你可以为此牌增加或减少一个目标(目标数至少为1)。', - fakezhuosheng:'擢升', - fakezhuosheng_info:'每回合每种牌名限一次,你可以将至少两张手牌当作任意基本牌使用,若你以此法使用的牌中包含具有应变效果的牌,则你令此牌无视条件获得对应的应变效果。', - fakejuhou:'拒后', - fakejuhou_info:'阵法技,与你处于同一队列的角色成为【杀】或普通锦囊牌的目标后,你可以令其将任意张牌置于其武将牌上,然后其于此牌结算完毕后获得这些牌。', - gznaxiang:'纳降', - gznaxiang_info:'锁定技,当你受到其他角色造成的伤害后,或你对其他角色造成伤害后,你对其发动〖才望〗时的“弃置”改为“获得”直到你的下回合开始。', - fakecaiwang:'才望', - fakecaiwang_info:'①你可以助战自己。②每回合每项各限一次,当你响应助战后,若你弃置的牌和被强化的牌:颜色相同,你可以弃置一名其他角色的一张牌;颜色不同,你摸一张牌。', - fakenaxiang:'纳降', - fakenaxiang_info:'锁定技。①当你对与你势力不同的角色造成伤害后,或受到与你势力不同的角色对你造成的伤害后。你对其发起军令,若其不执行,则你不能对其发动〖纳降①〗直到你的下个回合开始。②你响应助战弃牌无类别限制,且你触发具有应变的卡牌的条件均视为助战。', - fakehuyuan:'护援', - fakehuyuan_info:'①你的回合内,当一张装备牌进入一名角色的装备区后,你可以弃置与其距离为1以内的另一名角色区域里的一张牌。②结束阶段,你可以将一张装备牌置入一名角色的装备区。', - fakekeshou:'恪守', - fakekeshou_info:'①当你受到伤害时,你可以弃置两张颜色相同的牌并令此伤害-1。②当你因弃置而一次性失去至少两张牌后,若你的势力已确定且场上没有与你势力相同的其他角色,则你可以进行判定,若结果判定为红色,你摸一张牌。', + fakexiaoguo: "骁果", + fakexiaoguo_info: + "一名其他角色的准备阶段,你可以弃置任意张基本牌,然后弃置其装备区等量的牌,若其装备区的牌数小于你弃置的牌数,则你对其造成1点伤害。", + fakeduanbing: "短兵", + fakeduanbing_info: + "①你使用【杀】可以额外指定一名距离为1或以内的目标。②当你使用【杀】指定唯一目标后,你令目标角色需要额外使用一张【闪】响应此【杀】。", + fakeduoshi: "度势", + fakeduoshi_info: + "每轮限一次,友方角色可以将一张红色手牌当作【以逸待劳】使用,然后若你为小势力角色,你可以令一名友方角色将X张手牌当作不可被响应的【火烧连营】使用(X为此【以逸待劳】指定的目标数)。", + fakehanzhan: "酣战", + fakehanzhan_info: "有你参与的拼点事件结束后,没赢的角色可以获得对方装备区的一张牌。", + fakeshuangxiong: "双雄", + fakeshuangxiong_info: + "①摸牌阶段,你可以放弃摸牌并进行判定,本回合你可以将一张与此牌颜色不同的手牌当作【决斗】使用。②当你的判定牌于回合内生效后,你获得此牌。", + fakeyicheng: "疑城", + fakeyicheng_info: + "与你势力相同的角色成为【杀】的目标后,你可以令其摸一张牌,然后其可以使用一张装备牌,其于此回合结束时弃置X张牌(X为你本回合对其发动此技能的次数)。", + fakefenming: "奋命", + fakefenming_info: + "出牌阶段限一次,若你处于横置状态,你可以弃置所有处于横置状态的角色的各一张牌。", + fakebaoling: "暴凌", + fakebaoling_info: + "主将技,锁定技,出牌阶段结束时,若你有副将,则你移除副将,加3点体力上限并回复3点体力,然后获得〖崩坏〗。", + fakebenghuai: "崩坏", + fakebenghuai_info: + "结束阶段,若你的体力值不为全场最低,则你选择一项:①失去1点体力;②减1点体力上限;③背水:执行一个额外的摸牌阶段。", + fakediaodu: "调度", + fakediaodu_info: + "①每回合每种牌的类别限一次,与你势力相同的角色使用牌时,若此牌有目标且包含其,则其可以摸一张牌。②出牌阶段开始时,你可以获得与你势力相同的一名角色装备区内的一张牌,然后你可以将此牌交给另一名与你势力相同的其他角色。", + fakeyigui: "役鬼", + fakeyigui_info: + "①当你首次明置此武将牌时,你将剩余武将牌堆的两张牌称为“魂”置于武将牌上。②你可以展示一张武将牌上的“魂”并将其置入剩余武将牌堆,视为使用一张本回合内未以此法使用过的类别的基本牌或普通锦囊牌(此牌须指定目标,且目标须为未确定势力的角色或野心家或与此“魂”势力相同的角色)。", + fakejihun: "汲魂", + fakejihun_info: + "①当你受到伤害后,或与你势力不同的角色脱离濒死状态后,你可以将剩余武将牌堆的一张牌称为“魂”置于武将牌上。②准备阶段,你可以将至多两张“魂”置入剩余武将牌堆,然后将剩余武将牌堆的等量张牌称为“魂”置于武将牌上。", + fakejueyan: "决堰", + fakejizhi: "集智", + fakejueyan_info: + "主将技。①此武将牌计算体力上限时减少半个阴阳鱼。②准备阶段,你可以选择一个区域并于本回合的结束阶段弃置此区域的所有牌,然后你于本回合获得以下对应效果:⒈判定区:跳过判定阶段,获得〖集智〗直到回合结束;⒉装备区:摸三张牌,本回合手牌上限+3;⒊本回合使用【杀】的额定次数+3。", + fakequanji: "权计", + fakequanji_info: + "①每回合每项各限一次,当你造成或受到伤害后,你可以摸X张牌,然后将等量的牌称为“权”置于武将牌上。②你的手牌上限+X(X为你武将牌上的“权”数)。", + fakepaiyi: "排异", + fakepaiyi_info: + "出牌阶段限一次,你可以选择一名角色,然后选择一个军令令其选择是否执行。若其执行,则你摸X张牌,然后将一张“权”置入弃牌堆;若其不执行,则你可以对至多X名与其势力相同的角色各造成1点伤害,然后将等量的“权”置入弃牌堆。(X为你武将牌上的“权”数)", + fakeshilu: "嗜戮", + fakeshilu_info: + "①出牌阶段结束时,若你有副将且本阶段未发动过副将武将牌上的非锁定技,则你更换副将至你武将牌上的“戮”未包含的势力并将原副将称为“戮”置于武将牌上。②准备阶段,你弃置X张手牌,然后摸X张牌(X为你武将牌上的“戮”数,少牌全弃,无牌不弃)。", + fakexiongnve: "凶虐", + fakexiongnve_info: + "①当你使用【杀】造成伤害时或受到【杀】造成的伤害时,若你武将牌上的“戮”包含伤害来源的势力,则你令此伤害+1。②当你受到不为【杀】造成的伤害时,若你武将牌上的“戮”包含伤害来源的势力,则此伤害-1。", + fakehuaiyi: "怀异", + fakehuaiyi_info: + "出牌阶段限一次,你可以移除副将或弃置一个区域的所有牌,然后令所有大势力角色依次交给你至少一张牌,然后若存在多个大势力,则你移除一个此次交给你牌总数唯一最少的势力的其中一名角色的副将。", + fakezisui: "恣睢", + fakezisui_info: + "锁定技。①一名角色被你移除副将后,你将被移除的武将牌称为“异”置于武将牌上。②摸牌阶段,你多摸X张牌。③结束阶段,若X大于你的体力上限,你死亡。(X为你武将牌上的“异”数)", + fakejujian: "举荐", + fakejujian_info: + "副将技。①此武将牌计算体力上限时减少半个阴阳鱼。②结束阶段,你可以弃置一张非基本牌并选择一名友方角色,令其选择摸两张牌或回复1点体力,然后其可以变更副将。", + fakexibing: "息兵", + fakexibing_info: + "当一名其他角色在其出牌阶段内使用第一张黑色【杀】或黑色普通锦囊牌指定唯一角色为目标后,你可令该角色将手牌摸至体力值且本回合不能再使用手牌。若你与其均明置了所有武将牌,则你可以暗置你与其各一张武将牌且本回合不能再明置此武将牌。", + fakechengshang: "承赏", + fakechengshang_info: + "出牌阶段限一次,当你使用存在花色和点数且指定了其他势力角色为目标的牌结算完毕后,若你未因此牌造成过伤害,则你可以摸一张牌,然后本阶段你可以将一张手牌当作初始游戏牌堆中与此牌花色和点数相同的另一张基本牌或普通锦囊牌使用一次。", + fakezhente: "贞特", + fakezhente_info: + "每回合限一次,当你成为其他角色使用普通锦囊牌或黑色基本牌的目标后,你可令使用者选择一项:1.本回合不能再使用与此牌颜色相同的牌;2.令此牌对你无效。", + fakezhiwei: "至微", + fakezhiwei_info: + "你明置此武将牌时,选择一名其他角色。该角色造成伤害后,你摸一张牌,该角色受到伤害后,你随机弃置一张手牌。你弃牌阶段弃置的牌均被该角色获得。该角色死亡时,若你的两个武将牌均明置,你暗置此武将牌。若该角色未死亡,则此武将牌被暗置前,取消之。", + fakekuangcai: "狂才", + fakekuangcai_info: + "锁定技,你于回合内使用牌无距离和次数限制;弃牌阶段开始时,若你本回合内:未使用过牌,则你本回合手牌上限+1;使用过牌但未造成过伤害,则你本回合手牌上限-1。", + faketunchu: "屯储", + faketunchu_info: + "摸牌阶段,你可以额外摸两张牌,然后你将一至两张牌称为“粮”置于武将牌上。若如此做,你本回合不能使用【杀】。", + fakeshuliang: "输粮", + fakeshuliang_info: + "友方角色的结束阶段,若你与其的距离不大于你武将牌上的“粮”数,则你可以移去一张“粮”,然后令其摸两张牌。", + fakedujin: "独进", + fakedujin_info: + "①摸牌阶段,你可以额外摸X张牌(X为你装备区的牌数的一半,向上取整)。②当你首次明置此武将牌时,若你为你们势力第一个明置武将牌的角色,则你获得1个“先驱”标记。", + fakezhufu: "注傅", + fakezhufu_info: + "出牌阶段,你可以弃置一张本阶段未以此法弃置过的花色的牌,然后根据此牌的花色为你使用的下一张牌添加对应的应变效果:红桃,助战、目标+1;方片,富甲、不可被响应;黑桃,残躯、摸一张牌;草花,空巢、伤害+1。", + fakeguishu: "鬼术", + fakeguishu_info: + "出牌阶段限一次,你可以将一张黑桃手牌当作【知己知彼】或【远交近攻】使用。若你本局游戏内已经发动过了〖鬼术〗,则你必须选择与上次不同的选项。", + fakeyuanyu: "远域", + fakeyuanyu_info: "锁定技,当你受到伤害时,若你不在伤害来源的攻击范围内,则防止此伤害。", + fakemibei: "秘备", + fakemibei_info: + "①准备阶段,若你的手牌数不为全场最多,则你须选择一名手牌数为全场最多的角色,令其对你发起军令。②当你执行军令后,你将手牌数摸至与发起者相同(至多摸五张)。③当你拒绝执行军令后,你展示一至三张牌,然后你本回合可以将其中一张牌当作另一张基本牌或非延时锦囊牌使用一次。", + fakeqizhi: "奇制", + fakeqizhi_info: + "当你于回合内声明使用非装备牌A时,你可以弃置不是此牌目标的一名角色的一张牌B,然后其摸一张牌。若A具有应变效果,且A和B的花色相同,则你无视条件触发A的应变效果。", + fakejinqu: "进趋", + fakejinqu_info: + "结束阶段,你可以摸两张牌,然后你将手牌弃置至X张(X为你本回合发动过〖奇制〗的次数)。", + fakejuzhan: "拒战", + fakejuzhan_info: + "转换技。阴:当你成为【杀】的目标后,你可以与使用者各摸X张牌,然后若使用者的武将牌均明置,则你可以暗置其一张武将牌,且其本回合不能明置此武将牌。阳,当你使用【杀】指定目标后,你可以获得目标角色的X张牌,然后若你的武将牌均明置,则其可以暗置此武将牌,且你本回合不能明置此武将牌。(X为使用者已损失的体力值且X至少为1)", + fakedanshou: "胆守", + fakedanshou_info: + "每轮限一次,一名角色的准备阶段,你可以弃置一个区域的所有牌。若如此做,本回合其每个阶段开始时(准备阶段和结束阶段除外),你摸一张牌或令本回合以此法摸牌数+1,然后若你选择了摸牌且你本次至少摸了四张牌,则你可以对其造成1点伤害。", + fakexunxi: "迅析", + fakexunxi_info: "其他角色于回合外明置武将牌时,你可以视为对其使用一张【杀】(无距离限制)。", + fakehuanjia: "擐甲", + fakehuanjia_info: + "锁定技,每回合每项各限一次。①当你成为【杀】的目标后,本回合你视为装备此牌使用者的防具,直到你的装备区中有防具。②当你使用【杀】指定唯一目标后,本回合你视为装备目标角色的武器,直到你的装备区中有武器。", + fakexiongshu: "凶竖", + fakexiongshu_info: + "每回合限一次,一名角色使用【杀】或伤害类锦囊牌指定第一个目标后,若你为/不为此牌使用者,则你可以摸一张牌并令一名其他角色成为此牌的伤害来源/弃置一张牌并成为此牌的伤害来源。", + fakejianhui: "奸回", + fakejianhui_info: + "当一名角色受到其势力相同的另一名角色造成的伤害后,你可以令其中一名角色摸一张牌,然后弃置其中另一名角色的一张牌。", + fakechongxin: "崇信", + fakechongxin_info: + "出牌阶段限一次,你可以选择一名与你势力不同的角色,视为你使用一张指定你与其为目标的【以逸待劳】。", + fakeweirong: "卫戎", + fakeweirong_info: + "转换技,每轮限一次,出牌阶段。阴:你可以弃置X张牌,然后当你于本轮不因此法得到牌后,你摸一张牌。阳:你可以摸X张牌,然后当你于本轮不因此法失去牌后,你弃置一张牌。(X为你上一轮以此法摸和弃置的牌数之和,且X至少为1,至多为你的体力上限)", + gz_re_taishici: "太史慈", + gz_xin_zhuran: "朱然", + gz_jin_jiachong: "贾充", + gz_jin_yanghu: "羊祜", + gz_wangling: "王淩", + fakequanbian: "权变", + fakequanbian_tag: "牌堆顶", + fakequanbian_info: + "当你于回合内使用或打出牌时,你可以将一张手牌与牌堆顶X张牌的其中一张进行交换(X为你的体力上限)。", + fakezhouting: "骤霆", + fakezhouting_info: + "限定技,出牌阶段,你可以依次使用牌堆顶X张牌中所有可以使用的牌,然后获得其中不能使用的牌,然后若有角色因此死亡,则你重置〖骤霆〗(X为你的体力上限)。", + fakexuanbei: "选备", + fakexuanbei_info: + "①当你首次明置此武将牌时,你摸两张牌,且你本回合内使用带有“应变”标签的牌时直接强化。②每回合限一次,当你使用带有“应变”标签的牌结算完毕后,你可以令一名其他角色获得此牌对应的所有实体牌。③当你死亡时,你可以令一名其他角色变更副将。", + fakeqingleng: "清冷", + fakeqingleng_info: + "其他角色的结束阶段,若其武将牌均明置,则你可以将一张牌当作冰【杀】对其使用(无距离限制)。然后若此牌未对其造成伤害,则你暗置其一张武将牌,且直到其下个回合开始,其明置此武将牌时,你对其造成1点伤害。", + fakexijue: "袭爵", + fakexijue_info: + "①当你首次明置此武将牌时,你获得2枚“爵”标记。②回合结束时,若你本回合造成过伤害,则你获得1枚“爵”标记。③你可以于合适的时机发动〖突袭〗或〖骁果〗(至多弃置X张基本牌),然后移去1枚“爵”标记。④摸牌阶段,你改为摸X张牌。(X为你的“爵”标记数,且X至多为你的体力上限)", + fakexijue_xiaoguo: "骁果", + fakexijue_xiaoguo_info: + "一名其他角色的准备阶段,你可以弃置至多X张基本牌(X为你的“爵”标记数,且X至多为你的体力上限),然后弃置其装备区等量的牌,若其装备区的牌数小于你弃置的牌数,则你对其造成1点伤害。", + fakeqimei: "齐眉", + fakeqimei_info: + "准备阶段,你可以选择一名其他角色。若如此做,直到回合结束:当你或其获得牌/失去手牌后,若你与其手牌数相等,则另一名角色回复1点体力;当你或其的体力值变化后,若你与其体力值相等,则另一名角色摸一张牌。", + fakebaoqie: "宝箧", + fakebaoqie_info: + "①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以获得一名角色装备区里所有的宝物牌,然后你可以使用其中的一张牌。", + fakeciwei: "慈威", + fakeciwei_info: + "其他角色于一回合内使用第偶数张牌时,你可以弃置一张牌并取消此牌的所有目标,然后若此牌为装备牌,你可以获得之且你可以使用之。", + fakehuirong: "慧容", + fakehuirong_info: + "①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以令一名角色将手牌数调整至其体力值。", + fakeyanxi: "宴戏", + fakeyanxi_info: + "出牌阶段限一次,你可以展示一名其他角色的一张手牌和牌堆顶的两张牌,然后你获得其中一种颜色或类别的所有牌且本回合手牌上限+X(X为你获得的牌数),然后其获得剩余的牌。", + fakeshiren: "识人", + fakeshiren_info: + "①当你受到伤害时,若此武将牌未明置过,则你可以明置此武将牌并防止此伤害。②当你首次明置此武将牌时,你可以发动一次〖宴戏〗。", + fakecanmou: "参谋", + fakecanmou_info: + "每回合每项限一次,一名角色使用普通锦囊牌指定第一个目标时,若其手牌数为全场唯一最多,则你可以为此牌增加或减少一个目标(目标数至少为1)。", + fakezhuosheng: "擢升", + fakezhuosheng_info: + "每回合每种牌名限一次,你可以将至少两张手牌当作任意基本牌使用,若你以此法使用的牌中包含具有应变效果的牌,则你令此牌无视条件获得对应的应变效果。", + fakejuhou: "拒后", + fakejuhou_info: + "阵法技,与你处于同一队列的角色成为【杀】或普通锦囊牌的目标后,你可以令其将任意张牌置于其武将牌上,然后其于此牌结算完毕后获得这些牌。", + gznaxiang: "纳降", + gznaxiang_info: + "锁定技,当你受到其他角色造成的伤害后,或你对其他角色造成伤害后,你对其发动〖才望〗时的“弃置”改为“获得”直到你的下回合开始。", + fakecaiwang: "才望", + fakecaiwang_info: + "①你可以助战自己。②每回合每项各限一次,当你响应助战后,若你弃置的牌和被强化的牌:颜色相同,你可以弃置一名其他角色的一张牌;颜色不同,你摸一张牌。", + fakenaxiang: "纳降", + fakenaxiang_info: + "锁定技。①当你对与你势力不同的角色造成伤害后,或受到与你势力不同的角色对你造成的伤害后。你对其发起军令,若其不执行,则你不能对其发动〖纳降①〗直到你的下个回合开始。②你响应助战弃牌无类别限制,且你触发具有应变的卡牌的条件均视为助战。", + fakehuyuan: "护援", + fakehuyuan_info: + "①你的回合内,当一张装备牌进入一名角色的装备区后,你可以弃置与其距离为1以内的另一名角色区域里的一张牌。②结束阶段,你可以将一张装备牌置入一名角色的装备区。", + fakekeshou: "恪守", + fakekeshou_info: + "①当你受到伤害时,你可以弃置两张颜色相同的牌并令此伤害-1。②当你因弃置而一次性失去至少两张牌后,若你的势力已确定且场上没有与你势力相同的其他角色,则你可以进行判定,若结果判定为红色,你摸一张牌。", - guozhan_default:"国战标准", - guozhan_zhen:"君临天下·阵", - guozhan_shi:"君临天下·势", - guozhan_bian:"君临天下·变", - guozhan_quan:"君临天下·权", - guozhan_jun:"君主武将", - guozhan_jin:'文德武备', - guozhan_single:'君临天下EX', - guozhan_double:'双势力武将', - guozhan_yexinjia:'野心家武将', - guozhan_zongheng:'纵横捭阖', - guozhan_tw:'海外服专属', - guozhan_mobile:'移动版', - guozhan_qunxiong:'群雄割据', - guozhan_decade:'十年踪迹十年心', - guozhan_others:"其他", + guozhan_default: "国战标准", + guozhan_zhen: "君临天下·阵", + guozhan_shi: "君临天下·势", + guozhan_bian: "君临天下·变", + guozhan_quan: "君临天下·权", + guozhan_jun: "君主武将", + guozhan_jin: "文德武备", + guozhan_single: "君临天下EX", + guozhan_double: "双势力武将", + guozhan_yexinjia: "野心家武将", + guozhan_zongheng: "纵横捭阖", + guozhan_tw: "海外服专属", + guozhan_mobile: "移动版", + guozhan_qunxiong: "群雄割据", + guozhan_decade: "十年踪迹十年心", + guozhan_others: "其他", }, - junList:['liubei','zhangjiao','sunquan','caocao'], - guozhanPile_yingbian:[ + junList: ["liubei", "zhangjiao", "sunquan", "caocao"], + guozhanPile_yingbian: [ //黑桃普通 - ['spade',1,'shandian'], - ['spade',1,'xietianzi'], - ['spade',1,'juedou'], - ['spade',2,'bagua'], - ['spade',2,'heiguangkai'], - ['spade',2,'cixiong'], - ['spade',2,'taigongyinfu'], - ['spade',3,'zhujinqiyuan',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',3,'huoshaolianying'], - ['spade',3,'shuiyanqijunx',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',4,'guohe'], - ['spade',4,'sha'], - ['spade',4,'shuiyanqijunx',null,['yingbian_zhuzhan','yingbian_add']], - ['spade',5,'jueying'], - ['spade',5,'qinglong'], - ['spade',5,'sha'], - ['spade',6,'qinggang'], - ['spade',6,'jiu'], - ['spade',6,'sha','ice'], - ['spade',7,'sha'], - ['spade',7,'sha'], - ['spade',7,'sha','ice'], - ['spade',8,'sha','ice'], - ['spade',8,'sha','ice'], - ['spade',8,'sha'], - ['spade',9,'jiu'], - ['spade',9,'sha','thunder'], - ['spade',9,'sha'], - ['spade',10,'bingliang'], - ['spade',10,'sha','thunder'], - ['spade',10,'sha',null,['yingbian_canqu','yingbian_add']], - ['spade',11,'wuxie',null,['yingbian_kongchao','yingbian_draw']], - ['spade',11,'sha',null,['yingbian_canqu','yingbian_add']], - ['spade',11,'sha','thunder'], - ['spade',12,'zhangba'], - ['spade',12,'lulitongxin'], - ['spade',12,'tiesuo'], - ['spade',13,'wutiesuolian'], - ['spade',13,'wuxie'], - ['spade',13,'nanman',null,['yingbian_fujia','yingbian_remove']], + ["spade", 1, "shandian"], + ["spade", 1, "xietianzi"], + ["spade", 1, "juedou"], + ["spade", 2, "bagua"], + ["spade", 2, "heiguangkai"], + ["spade", 2, "cixiong"], + ["spade", 2, "taigongyinfu"], + ["spade", 3, "zhujinqiyuan", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 3, "huoshaolianying"], + ["spade", 3, "shuiyanqijunx", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 4, "guohe"], + ["spade", 4, "sha"], + ["spade", 4, "shuiyanqijunx", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["spade", 5, "jueying"], + ["spade", 5, "qinglong"], + ["spade", 5, "sha"], + ["spade", 6, "qinggang"], + ["spade", 6, "jiu"], + ["spade", 6, "sha", "ice"], + ["spade", 7, "sha"], + ["spade", 7, "sha"], + ["spade", 7, "sha", "ice"], + ["spade", 8, "sha", "ice"], + ["spade", 8, "sha", "ice"], + ["spade", 8, "sha"], + ["spade", 9, "jiu"], + ["spade", 9, "sha", "thunder"], + ["spade", 9, "sha"], + ["spade", 10, "bingliang"], + ["spade", 10, "sha", "thunder"], + ["spade", 10, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["spade", 11, "wuxie", null, ["yingbian_kongchao", "yingbian_draw"]], + ["spade", 11, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["spade", 11, "sha", "thunder"], + ["spade", 12, "zhangba"], + ["spade", 12, "lulitongxin"], + ["spade", 12, "tiesuo"], + ["spade", 13, "wutiesuolian"], + ["spade", 13, "wuxie"], + ["spade", 13, "nanman", null, ["yingbian_fujia", "yingbian_remove"]], //草花普通 - ['club',1,'juedou'], - ['club',1,'yuxi'], - ['club',1,'huxinjing'], - ['club',2,'sha'], - ['club',2,'tianjitu'], - ['club',2,'renwang'], - ['club',2,'tengjia'], - ['club',3,'sha'], - ['club',3,'chiling'], - ['club',3,'zhibi'], - ['club',4,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',4,'sha','thunder'], - ['club',4,'zhibi'], - ['club',5,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',5,'sha','thunder'], - ['club',5,'tongque'], - ['club',6,'sha','thunder'], - ['club',6,'sha',null,['yingbian_kongchao','yingbian_add']], - ['club',6,'lebu'], - ['club',7,'sha','thunder'], - ['club',7,'sha'], - ['club',7,'nanman',null,['yingbian_fujia','yingbian_remove']], - ['club',8,'sha','thunder'], - ['club',8,'sha',null,['yingbian_canqu','yingbian_add']], - ['club',8,'sha'], - ['club',9,'sha'], - ['club',9,'jiu'], - ['club',9,'jiu'], - ['club',10,'bingliang'], - ['club',10,'lulitongxin'], - ['club',10,'sha'], - ['club',11,'sha'], - ['club',11,'huoshaolianying'], - ['club',11,'sha'], - ['club',12,'zhujinqiyuan',null,['yingbian_zhuzhan','yingbian_add']], - ['club',12,'jiedao',null,['yingbian_fujia','yingbian_hit']], - ['club',12,'tiesuo'], - ['club',13,'tiesuo'], - ['club',13,'wuxie',null,['guo']], - ['club',13,'wuxie',null,['guo']], + ["club", 1, "juedou"], + ["club", 1, "yuxi"], + ["club", 1, "huxinjing"], + ["club", 2, "sha"], + ["club", 2, "tianjitu"], + ["club", 2, "renwang"], + ["club", 2, "tengjia"], + ["club", 3, "sha"], + ["club", 3, "chiling"], + ["club", 3, "zhibi"], + ["club", 4, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 4, "sha", "thunder"], + ["club", 4, "zhibi"], + ["club", 5, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 5, "sha", "thunder"], + ["club", 5, "tongque"], + ["club", 6, "sha", "thunder"], + ["club", 6, "sha", null, ["yingbian_kongchao", "yingbian_add"]], + ["club", 6, "lebu"], + ["club", 7, "sha", "thunder"], + ["club", 7, "sha"], + ["club", 7, "nanman", null, ["yingbian_fujia", "yingbian_remove"]], + ["club", 8, "sha", "thunder"], + ["club", 8, "sha", null, ["yingbian_canqu", "yingbian_add"]], + ["club", 8, "sha"], + ["club", 9, "sha"], + ["club", 9, "jiu"], + ["club", 9, "jiu"], + ["club", 10, "bingliang"], + ["club", 10, "lulitongxin"], + ["club", 10, "sha"], + ["club", 11, "sha"], + ["club", 11, "huoshaolianying"], + ["club", 11, "sha"], + ["club", 12, "zhujinqiyuan", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["club", 12, "jiedao", null, ["yingbian_fujia", "yingbian_hit"]], + ["club", 12, "tiesuo"], + ["club", 13, "tiesuo"], + ["club", 13, "wuxie", null, ["guo"]], + ["club", 13, "wuxie", null, ["guo"]], //红桃普通 - ['heart',1,'wanjian'], - ['heart',1,'taoyuan'], - ['heart',1,'lianjunshengyan'], - ['heart',2,'shan'], - ['heart',2,'chuqibuyi',null,['yingbian_zhuzhan','yingbian_add']], - ['heart',2,'diaohulishan'], - ['heart',3,'chuqibuyi',null,['yingbian_zhuzhan','yingbian_add']], - ['heart',3,'wugu'], - ['heart',3,'jingfanma'], - ['heart',4,'tao'], - ['heart',4,'sha','fire',['yingbian_canqu','yingbian_damage']], - ['heart',4,'shan'], - ['heart',5,'qilin'], - ['heart',5,'chitu'], - ['heart',5,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['heart',6,'lebu'], - ['heart',6,'tao'], - ['heart',6,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['heart',7,'tao'], - ['heart',7,'dongzhuxianji'], - ['heart',7,'shan'], - ['heart',8,'tao'], - ['heart',8,'dongzhuxianji'], - ['heart',8,'tao'], - ['heart',9,'tao'], - ['heart',9,'yuanjiao'], - ['heart',9,'tao'], - ['heart',10,'sha'], - ['heart',10,'shan'], - ['heart',10,'sha'], - ['heart',11,'yiyi'], - ['heart',11,'tao'], - ['heart',11,'sha',null,['yingbian_zhuzhan','yingbian_add']], - ['heart',12,'tao'], - ['heart',12,'sha'], - ['heart',12,'huoshaolianying'], - ['heart',13,'zhuahuang'], - ['heart',13,'shan'], - ['heart',13,'huogong',null,['yingbian_zhuzhan','yingbian_add']], + ["heart", 1, "wanjian"], + ["heart", 1, "taoyuan"], + ["heart", 1, "lianjunshengyan"], + ["heart", 2, "shan"], + ["heart", 2, "chuqibuyi", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["heart", 2, "diaohulishan"], + ["heart", 3, "chuqibuyi", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["heart", 3, "wugu"], + ["heart", 3, "jingfanma"], + ["heart", 4, "tao"], + ["heart", 4, "sha", "fire", ["yingbian_canqu", "yingbian_damage"]], + ["heart", 4, "shan"], + ["heart", 5, "qilin"], + ["heart", 5, "chitu"], + ["heart", 5, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["heart", 6, "lebu"], + ["heart", 6, "tao"], + ["heart", 6, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["heart", 7, "tao"], + ["heart", 7, "dongzhuxianji"], + ["heart", 7, "shan"], + ["heart", 8, "tao"], + ["heart", 8, "dongzhuxianji"], + ["heart", 8, "tao"], + ["heart", 9, "tao"], + ["heart", 9, "yuanjiao"], + ["heart", 9, "tao"], + ["heart", 10, "sha"], + ["heart", 10, "shan"], + ["heart", 10, "sha"], + ["heart", 11, "yiyi"], + ["heart", 11, "tao"], + ["heart", 11, "sha", null, ["yingbian_zhuzhan", "yingbian_add"]], + ["heart", 12, "tao"], + ["heart", 12, "sha"], + ["heart", 12, "huoshaolianying"], + ["heart", 13, "zhuahuang"], + ["heart", 13, "shan"], + ["heart", 13, "huogong", null, ["yingbian_zhuzhan", "yingbian_add"]], //方片普通 - ['diamond',1,'wuxinghelingshan'], - ['diamond',1,'zhuge'], - ['diamond',1,'xietianzi'], - ['diamond',2,'shan'], - ['diamond',2,'tao'], - ['diamond',2,'tao'], - ['diamond',3,'shunshou'], - ['diamond',3,'shan'], - ['diamond',3,'tao'], - ['diamond',4,'yiyi'], - ['diamond',4,'sha','fire',['yingbian_canqu','yingbian_damage']], - ['diamond',4,'sha','fire',['yingbian_zhuzhan','yingbian_add']], - ['diamond',5,'guanshi'], - ['diamond',5,'sha','fire'], - ['diamond',5,'muniu'], - ['diamond',6,'wuliu'], - ['diamond',6,'shan'], - ['diamond',6,'shan'], - ['diamond',7,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',7,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',7,'shan'], - ['diamond',8,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',8,'shan',null,['yingbian_kongchao','yingbian_draw']], - ['diamond',8,'sha','fire'], - ['diamond',9,'jiu'], - ['diamond',9,'shan'], - ['diamond',9,'sha','fire'], - ['diamond',10,'shan'], - ['diamond',10,'sha'], - ['diamond',10,'diaohulishan'], - ['diamond',11,'sha'], - ['diamond',11,'shan'], - ['diamond',11,'wuxie',null,['guo']], - ['diamond',12,'sha'], - ['diamond',12,'sanjian'], - ['diamond',12,'wuxie',null,['guo']], - ['diamond',12,'fangtian'], - ['diamond',13,'zixin'], - ['diamond',13,'shan'], - ['diamond',13,'shan'], + ["diamond", 1, "wuxinghelingshan"], + ["diamond", 1, "zhuge"], + ["diamond", 1, "xietianzi"], + ["diamond", 2, "shan"], + ["diamond", 2, "tao"], + ["diamond", 2, "tao"], + ["diamond", 3, "shunshou"], + ["diamond", 3, "shan"], + ["diamond", 3, "tao"], + ["diamond", 4, "yiyi"], + ["diamond", 4, "sha", "fire", ["yingbian_canqu", "yingbian_damage"]], + ["diamond", 4, "sha", "fire", ["yingbian_zhuzhan", "yingbian_add"]], + ["diamond", 5, "guanshi"], + ["diamond", 5, "sha", "fire"], + ["diamond", 5, "muniu"], + ["diamond", 6, "wuliu"], + ["diamond", 6, "shan"], + ["diamond", 6, "shan"], + ["diamond", 7, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 7, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 7, "shan"], + ["diamond", 8, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 8, "shan", null, ["yingbian_kongchao", "yingbian_draw"]], + ["diamond", 8, "sha", "fire"], + ["diamond", 9, "jiu"], + ["diamond", 9, "shan"], + ["diamond", 9, "sha", "fire"], + ["diamond", 10, "shan"], + ["diamond", 10, "sha"], + ["diamond", 10, "diaohulishan"], + ["diamond", 11, "sha"], + ["diamond", 11, "shan"], + ["diamond", 11, "wuxie", null, ["guo"]], + ["diamond", 12, "sha"], + ["diamond", 12, "sanjian"], + ["diamond", 12, "wuxie", null, ["guo"]], + ["diamond", 12, "fangtian"], + ["diamond", 13, "zixin"], + ["diamond", 13, "shan"], + ["diamond", 13, "shan"], //特殊 - ['heart',3,'taipingyaoshu'], - ['diamond',4,'dinglanyemingzhu'], - ['heart',5,'liulongcanjia'], - ['spade',6,'feilongduofeng'], - ['club',12,'gz_wenheluanwu'], - ['heart',1,'gz_guguoanbang'], - ['spade',12,'gz_haolingtianxia'], - ['diamond',1,'gz_kefuzhongyuan'], + ["heart", 3, "taipingyaoshu"], + ["diamond", 4, "dinglanyemingzhu"], + ["heart", 5, "liulongcanjia"], + ["spade", 6, "feilongduofeng"], + ["club", 12, "gz_wenheluanwu"], + ["heart", 1, "gz_guguoanbang"], + ["spade", 12, "gz_haolingtianxia"], + ["diamond", 1, "gz_kefuzhongyuan"], ], - guozhanPile_old:[ - ['spade',1,'juedou'], - ['spade',1,'shandian'], - ['spade',2,'cixiong'], - ['spade',2,'bagua'], - ['spade',2,'hanbing'], - ['spade',3,'guohe'], - ['spade',3,'shunshou'], - ['spade',4,'guohe'], - ['spade',4,'shunshou'], - ['spade',5,'sha'], - ['spade',5,'jueying'], - ['spade',6,'qinggang'], - ['spade',6,'sha','thunder'], - ['spade',7,'sha'], - ['spade',7,'sha','thunder'], - ['spade',8,'sha'], - ['spade',8,'sha'], - ['spade',9,'sha'], - ['spade',9,'jiu'], - ['spade',10,'sha'], - ['spade',10,'bingliang'], - ['spade',11,'sha'], - ['spade',11,'wuxie'], - ['spade',12,'zhangba'], - ['spade',12,'tiesuo'], - ['spade',13,'nanman'], - ['spade',13,'dawan'], + guozhanPile_old: [ + ["spade", 1, "juedou"], + ["spade", 1, "shandian"], + ["spade", 2, "cixiong"], + ["spade", 2, "bagua"], + ["spade", 2, "hanbing"], + ["spade", 3, "guohe"], + ["spade", 3, "shunshou"], + ["spade", 4, "guohe"], + ["spade", 4, "shunshou"], + ["spade", 5, "sha"], + ["spade", 5, "jueying"], + ["spade", 6, "qinggang"], + ["spade", 6, "sha", "thunder"], + ["spade", 7, "sha"], + ["spade", 7, "sha", "thunder"], + ["spade", 8, "sha"], + ["spade", 8, "sha"], + ["spade", 9, "sha"], + ["spade", 9, "jiu"], + ["spade", 10, "sha"], + ["spade", 10, "bingliang"], + ["spade", 11, "sha"], + ["spade", 11, "wuxie"], + ["spade", 12, "zhangba"], + ["spade", 12, "tiesuo"], + ["spade", 13, "nanman"], + ["spade", 13, "dawan"], - ['club',1,'juedou'], - ['club',1,'baiyin'], - ['club',2,'sha'], - ['club',2,'tengjia'], - ['club',2,'renwang'], - ['club',3,'sha'], - ['club',3,'zhibi'], - ['club',4,'sha'], - ['club',4,'zhibi'], - ['club',5,'sha'], - ['club',5,'dilu'], - ['club',6,'lebu'], - ['club',6,'sha','thunder'], - ['club',7,'nanman'], - ['club',7,'sha','thunder'], - ['club',8,'sha'], - ['club',8,'sha','thunder'], - ['club',9,'sha'], - ['club',9,'jiu'], - ['club',10,'sha'], - ['club',10,'bingliang'], - ['club',11,'sha'], - ['club',11,'sha'], - ['club',12,'jiedao'], - ['club',12,'tiesuo'], - ['club',13,'wuxie',null,['guo']], - ['club',13,'tiesuo'], + ["club", 1, "juedou"], + ["club", 1, "baiyin"], + ["club", 2, "sha"], + ["club", 2, "tengjia"], + ["club", 2, "renwang"], + ["club", 3, "sha"], + ["club", 3, "zhibi"], + ["club", 4, "sha"], + ["club", 4, "zhibi"], + ["club", 5, "sha"], + ["club", 5, "dilu"], + ["club", 6, "lebu"], + ["club", 6, "sha", "thunder"], + ["club", 7, "nanman"], + ["club", 7, "sha", "thunder"], + ["club", 8, "sha"], + ["club", 8, "sha", "thunder"], + ["club", 9, "sha"], + ["club", 9, "jiu"], + ["club", 10, "sha"], + ["club", 10, "bingliang"], + ["club", 11, "sha"], + ["club", 11, "sha"], + ["club", 12, "jiedao"], + ["club", 12, "tiesuo"], + ["club", 13, "wuxie", null, ["guo"]], + ["club", 13, "tiesuo"], - ['diamond',1,'zhuge'], - ['diamond',1,'zhuque'], - ['diamond',2,'shan'], - ['diamond',2,'tao'], - ['diamond',3,'shan'], - ['diamond',3,'shunshou'], - ['diamond',4,'yiyi'], - ['diamond',4,'sha','fire'], - ['diamond',5,'guanshi'], - ['diamond',5,'sha','fire'], - ['diamond',6,'shan'], - ['diamond',6,'wuliu'], - ['diamond',7,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'shan'], - ['diamond',8,'shan'], - ['diamond',9,'shan'], - ['diamond',9,'jiu'], - ['diamond',10,'shan'], - ['diamond',10,'sha'], - ['diamond',11,'shan'], - ['diamond',11,'sha'], - ['diamond',12,'sha'], - ['diamond',12,'sanjian'], - ['diamond',12,'wuxie',null,['guo']], - ['diamond',13,'shan'], - ['diamond',13,'zixin'], + ["diamond", 1, "zhuge"], + ["diamond", 1, "zhuque"], + ["diamond", 2, "shan"], + ["diamond", 2, "tao"], + ["diamond", 3, "shan"], + ["diamond", 3, "shunshou"], + ["diamond", 4, "yiyi"], + ["diamond", 4, "sha", "fire"], + ["diamond", 5, "guanshi"], + ["diamond", 5, "sha", "fire"], + ["diamond", 6, "shan"], + ["diamond", 6, "wuliu"], + ["diamond", 7, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "shan"], + ["diamond", 9, "jiu"], + ["diamond", 10, "shan"], + ["diamond", 10, "sha"], + ["diamond", 11, "shan"], + ["diamond", 11, "sha"], + ["diamond", 12, "sha"], + ["diamond", 12, "sanjian"], + ["diamond", 12, "wuxie", null, ["guo"]], + ["diamond", 13, "shan"], + ["diamond", 13, "zixin"], - ['heart',1,'taoyuan'], - ['heart',1,'wanjian'], - ['heart',2,'shan'], - ['heart',2,'huogong'], - ['heart',3,'wugu'], - ['heart',3,'huogong'], - ['heart',4,'tao'], - ['heart',4,'sha','fire'], - ['heart',5,'qilin'], - ['heart',5,'chitu'], - ['heart',6,'tao'], - ['heart',6,'lebu'], - ['heart',7,'tao'], - ['heart',7,'wuzhong'], - ['heart',8,'tao'], - ['heart',8,'wuzhong'], - ['heart',9,'tao'], - ['heart',9,'yuanjiao'], - ['heart',10,'tao'], - ['heart',10,'sha'], - ['heart',11,'shan'], - ['heart',11,'yiyi'], - ['heart',12,'tao'], - ['heart',12,'sha'], - ['heart',12,'guohe'], - ['heart',13,'shan'], - ['heart',13,'zhuahuang'], + ["heart", 1, "taoyuan"], + ["heart", 1, "wanjian"], + ["heart", 2, "shan"], + ["heart", 2, "huogong"], + ["heart", 3, "wugu"], + ["heart", 3, "huogong"], + ["heart", 4, "tao"], + ["heart", 4, "sha", "fire"], + ["heart", 5, "qilin"], + ["heart", 5, "chitu"], + ["heart", 6, "tao"], + ["heart", 6, "lebu"], + ["heart", 7, "tao"], + ["heart", 7, "wuzhong"], + ["heart", 8, "tao"], + ["heart", 8, "wuzhong"], + ["heart", 9, "tao"], + ["heart", 9, "yuanjiao"], + ["heart", 10, "tao"], + ["heart", 10, "sha"], + ["heart", 11, "shan"], + ["heart", 11, "yiyi"], + ["heart", 12, "tao"], + ["heart", 12, "sha"], + ["heart", 12, "guohe"], + ["heart", 13, "shan"], + ["heart", 13, "zhuahuang"], ], - guozhanPile:[ - ['spade',1,'juedou'], - ['spade',1,'shandian'], - ['spade',2,'feilongduofeng'], - ['spade',2,'bagua'], - ['spade',2,'hanbing'], - ['spade',3,'guohe'], - ['spade',3,'shunshou'], - ['spade',4,'guohe'], - ['spade',4,'shunshou'], - ['spade',5,'sha'], - ['spade',5,'jueying'], - ['spade',6,'qinggang'], - ['spade',6,'sha','thunder'], - ['spade',7,'sha'], - ['spade',7,'sha','thunder'], - ['spade',8,'sha'], - ['spade',8,'sha'], - ['spade',9,'sha'], - ['spade',9,'jiu'], - ['spade',10,'sha'], - ['spade',10,'bingliang'], - ['spade',11,'sha'], - ['spade',11,'wuxie'], - ['spade',12,'zhangba'], - ['spade',12,'tiesuo'], - ['spade',13,'nanman'], - ['spade',13,'dawan'], + guozhanPile: [ + ["spade", 1, "juedou"], + ["spade", 1, "shandian"], + ["spade", 2, "feilongduofeng"], + ["spade", 2, "bagua"], + ["spade", 2, "hanbing"], + ["spade", 3, "guohe"], + ["spade", 3, "shunshou"], + ["spade", 4, "guohe"], + ["spade", 4, "shunshou"], + ["spade", 5, "sha"], + ["spade", 5, "jueying"], + ["spade", 6, "qinggang"], + ["spade", 6, "sha", "thunder"], + ["spade", 7, "sha"], + ["spade", 7, "sha", "thunder"], + ["spade", 8, "sha"], + ["spade", 8, "sha"], + ["spade", 9, "sha"], + ["spade", 9, "jiu"], + ["spade", 10, "sha"], + ["spade", 10, "bingliang"], + ["spade", 11, "sha"], + ["spade", 11, "wuxie"], + ["spade", 12, "zhangba"], + ["spade", 12, "tiesuo"], + ["spade", 13, "nanman"], + ["spade", 13, "dawan"], - ['club',1,'juedou'], - ['club',1,'baiyin'], - ['club',2,'sha'], - ['club',2,'tengjia'], - ['club',2,'renwang'], - ['club',3,'sha'], - ['club',3,'zhibi'], - ['club',4,'sha'], - ['club',4,'zhibi'], - ['club',5,'sha'], - ['club',5,'dilu'], - ['club',6,'lebu'], - ['club',6,'sha','thunder'], - ['club',7,'nanman'], - ['club',7,'sha','thunder'], - ['club',8,'sha'], - ['club',8,'sha','thunder'], - ['club',9,'sha'], - ['club',9,'jiu'], - ['club',10,'sha'], - ['club',10,'bingliang'], - ['club',11,'sha'], - ['club',11,'sha'], - ['club',12,'jiedao'], - ['club',12,'tiesuo'], - ['club',13,'wuxie',null,['guo']], - ['club',13,'tiesuo'], + ["club", 1, "juedou"], + ["club", 1, "baiyin"], + ["club", 2, "sha"], + ["club", 2, "tengjia"], + ["club", 2, "renwang"], + ["club", 3, "sha"], + ["club", 3, "zhibi"], + ["club", 4, "sha"], + ["club", 4, "zhibi"], + ["club", 5, "sha"], + ["club", 5, "dilu"], + ["club", 6, "lebu"], + ["club", 6, "sha", "thunder"], + ["club", 7, "nanman"], + ["club", 7, "sha", "thunder"], + ["club", 8, "sha"], + ["club", 8, "sha", "thunder"], + ["club", 9, "sha"], + ["club", 9, "jiu"], + ["club", 10, "sha"], + ["club", 10, "bingliang"], + ["club", 11, "sha"], + ["club", 11, "sha"], + ["club", 12, "jiedao"], + ["club", 12, "tiesuo"], + ["club", 13, "wuxie", null, ["guo"]], + ["club", 13, "tiesuo"], - ['diamond',1,'zhuge'], - ['diamond',1,'zhuque'], - ['diamond',2,'shan'], - ['diamond',2,'tao'], - ['diamond',3,'shan'], - ['diamond',3,'shunshou'], - ['diamond',4,'yiyi'], - ['diamond',4,'sha','fire'], - ['diamond',5,'guanshi'], - ['diamond',5,'sha','fire'], - ['diamond',6,'shan'], - ['diamond',6,'wuliu'], - ['diamond',7,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'shan'], - ['diamond',8,'shan'], - ['diamond',9,'shan'], - ['diamond',9,'jiu'], - ['diamond',10,'shan'], - ['diamond',10,'sha'], - ['diamond',11,'shan'], - ['diamond',11,'sha'], - ['diamond',12,'sha'], - ['diamond',12,'sanjian'], - ['diamond',12,'wuxie',null,['guo']], - ['diamond',13,'shan'], - ['diamond',13,'zixin'], + ["diamond", 1, "zhuge"], + ["diamond", 1, "zhuque"], + ["diamond", 2, "shan"], + ["diamond", 2, "tao"], + ["diamond", 3, "shan"], + ["diamond", 3, "shunshou"], + ["diamond", 4, "yiyi"], + ["diamond", 4, "sha", "fire"], + ["diamond", 5, "guanshi"], + ["diamond", 5, "sha", "fire"], + ["diamond", 6, "shan"], + ["diamond", 6, "wuliu"], + ["diamond", 7, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 8, "shan"], + ["diamond", 9, "shan"], + ["diamond", 9, "jiu"], + ["diamond", 10, "shan"], + ["diamond", 10, "sha"], + ["diamond", 11, "shan"], + ["diamond", 11, "sha"], + ["diamond", 12, "sha"], + ["diamond", 12, "sanjian"], + ["diamond", 12, "wuxie", null, ["guo"]], + ["diamond", 13, "shan"], + ["diamond", 13, "zixin"], - ['heart',1,'taoyuan'], - ['heart',1,'wanjian'], - ['heart',2,'shan'], - ['heart',2,'huogong'], - ['heart',3,'wugu'], - ['heart',3,'taipingyaoshu'], - ['heart',3,'huogong'], - ['heart',4,'tao'], - ['heart',4,'sha','fire'], - ['heart',5,'qilin'], - ['heart',5,'chitu'], - ['heart',6,'tao'], - ['heart',6,'lebu'], - ['heart',7,'tao'], - ['heart',7,'wuzhong'], - ['heart',8,'tao'], - ['heart',8,'wuzhong'], - ['heart',9,'tao'], - ['heart',9,'yuanjiao'], - ['heart',10,'tao'], - ['heart',10,'sha'], - ['heart',11,'shan'], - ['heart',11,'yiyi'], - ['heart',12,'tao'], - ['heart',12,'sha'], - ['heart',12,'guohe'], - ['heart',13,'shan'], - ['heart',13,'zhuahuang'], + ["heart", 1, "taoyuan"], + ["heart", 1, "wanjian"], + ["heart", 2, "shan"], + ["heart", 2, "huogong"], + ["heart", 3, "wugu"], + ["heart", 3, "taipingyaoshu"], + ["heart", 3, "huogong"], + ["heart", 4, "tao"], + ["heart", 4, "sha", "fire"], + ["heart", 5, "qilin"], + ["heart", 5, "chitu"], + ["heart", 6, "tao"], + ["heart", 6, "lebu"], + ["heart", 7, "tao"], + ["heart", 7, "wuzhong"], + ["heart", 8, "tao"], + ["heart", 8, "wuzhong"], + ["heart", 9, "tao"], + ["heart", 9, "yuanjiao"], + ["heart", 10, "tao"], + ["heart", 10, "sha"], + ["heart", 11, "shan"], + ["heart", 11, "yiyi"], + ["heart", 12, "tao"], + ["heart", 12, "sha"], + ["heart", 12, "guohe"], + ["heart", 13, "shan"], + ["heart", 13, "zhuahuang"], - ['spade',1,'xietianzi',null,['lianheng']], - ['spade',2,'minguangkai'], - ['spade',3,'huoshaolianying',null,['lianheng']], - ['spade',4,'sha'], - ['spade',5,'qinglong'], - ['spade',6,'jiu',null,['lianheng']], - ['spade',7,'sha'], - ['spade',8,'sha'], - ['spade',9,'sha','thunder'], - ['spade',10,'sha','thunder'], - ['spade',11,'sha','thunder',['lianheng']], - ['spade',12,'lulitongxin'], - ['spade',13,'wuxie'], + ["spade", 1, "xietianzi", null, ["lianheng"]], + ["spade", 2, "minguangkai"], + ["spade", 3, "huoshaolianying", null, ["lianheng"]], + ["spade", 4, "sha"], + ["spade", 5, "qinglong"], + ["spade", 6, "jiu", null, ["lianheng"]], + ["spade", 7, "sha"], + ["spade", 8, "sha"], + ["spade", 9, "sha", "thunder"], + ["spade", 10, "sha", "thunder"], + ["spade", 11, "sha", "thunder", ["lianheng"]], + ["spade", 12, "lulitongxin"], + ["spade", 13, "wuxie"], - ['heart',1,'lianjunshengyan'], - ['heart',2,'diaohulishan'], - ['heart',3,'jingfanma',null,['lianheng']], - ['heart',4,'shan'], - ['heart',5,'shan'], - ['heart',6,'shan'], - ['heart',7,'shan'], - ['heart',8,'tao'], - ['heart',9,'tao'], - ['heart',10,'sha'], - ['heart',11,'sha'], - ['heart',12,'huoshaolianying',null,['lianheng']], - ['heart',13,'shuiyanqijunx'], + ["heart", 1, "lianjunshengyan"], + ["heart", 2, "diaohulishan"], + ["heart", 3, "jingfanma", null, ["lianheng"]], + ["heart", 4, "shan"], + ["heart", 5, "shan"], + ["heart", 6, "shan"], + ["heart", 7, "shan"], + ["heart", 8, "tao"], + ["heart", 9, "tao"], + ["heart", 10, "sha"], + ["heart", 11, "sha"], + ["heart", 12, "huoshaolianying", null, ["lianheng"]], + ["heart", 13, "shuiyanqijunx"], - ['club',1,'yuxi'], - ['club',2,'huxinjing',null,['lianheng']], - ['club',3,'chiling'], - ['club',4,'sha'], - ['club',5,'sha','thunder',['lianheng']], - ['club',6,'sha'], - ['club',7,'sha'], - ['club',8,'sha'], - ['club',9,'jiu'], - ['club',10,'lulitongxin'], - ['club',11,'huoshaolianying',null,['lianheng']], - ['club',12,'shuiyanqijunx'], - ['club',13,'wuxie',null,['guo']], + ["club", 1, "yuxi"], + ["club", 2, "huxinjing", null, ["lianheng"]], + ["club", 3, "chiling"], + ["club", 4, "sha"], + ["club", 5, "sha", "thunder", ["lianheng"]], + ["club", 6, "sha"], + ["club", 7, "sha"], + ["club", 8, "sha"], + ["club", 9, "jiu"], + ["club", 10, "lulitongxin"], + ["club", 11, "huoshaolianying", null, ["lianheng"]], + ["club", 12, "shuiyanqijunx"], + ["club", 13, "wuxie", null, ["guo"]], - ['diamond',1,'xietianzi',null,['lianheng']], - ['diamond',2,'tao'], - ['diamond',3,'tao',null,['lianheng']], - ['diamond',4,'xietianzi',null,['lianheng']], - ['diamond',5,'muniu'], - ['diamond',6,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'sha','fire'], - ['diamond',9,'sha','fire'], - ['diamond',10,'diaohulishan',null,['lianheng']], - ['diamond',11,'wuxie',null,['guo']], - ['diamond',12,'fangtian'], - ['diamond',13,'shan'], + ["diamond", 1, "xietianzi", null, ["lianheng"]], + ["diamond", 2, "tao"], + ["diamond", 3, "tao", null, ["lianheng"]], + ["diamond", 4, "xietianzi", null, ["lianheng"]], + ["diamond", 5, "muniu"], + ["diamond", 6, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "sha", "fire"], + ["diamond", 9, "sha", "fire"], + ["diamond", 10, "diaohulishan", null, ["lianheng"]], + ["diamond", 11, "wuxie", null, ["guo"]], + ["diamond", 12, "fangtian"], + ["diamond", 13, "shan"], - ['diamond',6,'dinglanyemingzhu'], - ['heart',13,'liulongcanjia'], + ["diamond", 6, "dinglanyemingzhu"], + ["heart", 13, "liulongcanjia"], //['spade',12,'gz_haolingtianxia'], //['diamond',1,'gz_kefuzhongyuan'], //['heart',1,'gz_guguoanbang'], //['club',12,'gz_wenheluanwu'], ], - element:{ - content:{ - hideCharacter:function(){ - game.addVideo('hideCharacter',player,num); - var skills,log=event.log; - switch(num){ + element: { + content: { + hideCharacter: function () { + game.addVideo("hideCharacter", player, num); + var skills, + log = event.log; + switch (num) { case 0: - if(log!==false) game.log(player,'暗置了主将'+get.translation(player.name1)); - skills=lib.character[player.name1][3]; - player.name=player.name2; - player.sex=lib.character[player.name2][0]; - player.classList.add('unseen'); - break; + if (log !== false) game.log(player, "暗置了主将" + get.translation(player.name1)); + skills = lib.character[player.name1][3]; + player.name = player.name2; + player.sex = lib.character[player.name2][0]; + player.classList.add("unseen"); + break; case 1: - if(log!==false) game.log(player,'暗置了副将'+get.translation(player.name2)); - skills=lib.character[player.name2][3]; - player.classList.add('unseen2'); - break; + if (log !== false) game.log(player, "暗置了副将" + get.translation(player.name2)); + skills = lib.character[player.name2][3]; + player.classList.add("unseen2"); + break; } - game.broadcast(function(player,name,sex,num,skills){ - player.name=name; - player.sex=sex; - switch(num){ - case 0:player.classList.add('unseen');break; - case 1:player.classList.add('unseen2');break; - } - for(var i=0;i选项'+get.cnNumber(i+1,true)+':'+event.choiceList[i]+'
                        '); - controls.push('选项'+get.cnNumber(i+1,true)); + dialog.add([[event.junling], "vcard"]); + var controls = []; + if (event.choiceList) { + for (var i = 0; i < event.choiceList.length; i++) { + dialog.add( + '" + ); + controls.push("选项" + get.cnNumber(i + 1, true)); } - } - else if(event.controls) controls=event.controls; - else controls=['执行该军令','不执行该军令']; - if(!event.ai) event.ai=function(){return Math.floor(controls.length*Math.random())}; - player.chooseControl(controls).set('dialog',dialog).set('ai',event.ai); - 'step 1' - event.result={ - index:result.index, - control:result.control, + } else if (event.controls) controls = event.controls; + else controls = ["执行该军令", "不执行该军令"]; + if (!event.ai) + event.ai = function () { + return Math.floor(controls.length * Math.random()); + }; + player.chooseControl(controls).set("dialog", dialog).set("ai", event.ai); + "step 1"; + event.result = { + index: result.index, + control: result.control, }; }, - carryOutJunling:function(){ - 'step 0' - switch(event.junling){ - case 'junling1':{ - if(targets[0].isAlive()){ - player.line(targets,'green'); + carryOutJunling: function () { + "step 0"; + switch (event.junling) { + case "junling1": { + if (targets[0].isAlive()) { + player.line(targets, "green"); targets[0].damage(player); } break; } - case 'junling2':player.draw();event.num=1;break; - case 'junling3':player.loseHp();break; - case 'junling4':player.addTempSkill('junling4_eff');player.addTempSkill('fengyin_vice');player.addTempSkill('fengyin_main');break; - case 'junling5':player.turnOver();player.addTempSkill('junling5_eff');break; + case "junling2": + player.draw(); + event.num = 1; + break; + case "junling3": + player.loseHp(); + break; + case "junling4": + player.addTempSkill("junling4_eff"); + player.addTempSkill("fengyin_vice"); + player.addTempSkill("fengyin_main"); + break; + case "junling5": + player.turnOver(); + player.addTempSkill("junling5_eff"); + break; } - 'step 1' - if(event.junling=='junling2'&&source!=player&&player.countCards('he')>0){ - player.chooseCard('交给'+get.translation(source)+'第'+get.cnNumber(event.num)+'张牌(共两张)','he',true); - event.ing=true; + "step 1"; + if (event.junling == "junling2" && source != player && player.countCards("he") > 0) { + player.chooseCard( + "交给" + + get.translation(source) + + "第" + + get.cnNumber(event.num) + + "张牌(共两张)", + "he", + true + ); + event.ing = true; } - if(event.junling=='junling6'){ - var position='',num0=0; - if(player.countCards('h')){position+='h';num0++;} - if(player.countCards('e')){position+='e';num0++;} - player.chooseCard('选择一张手牌和一张装备区内牌(若有),然后弃置其余的牌',position,num0,function(card){ - if(ui.selected.cards.length) return get.position(card)!=get.position(ui.selected.cards[0]); - return true; - },true).set('complexCard',true).set('ai',function(card){return get.value(card)}); + if (event.junling == "junling6") { + var position = "", + num0 = 0; + if (player.countCards("h")) { + position += "h"; + num0++; + } + if (player.countCards("e")) { + position += "e"; + num0++; + } + player + .chooseCard( + "选择一张手牌和一张装备区内牌(若有),然后弃置其余的牌", + position, + num0, + function (card) { + if (ui.selected.cards.length) + return get.position(card) != get.position(ui.selected.cards[0]); + return true; + }, + true + ) + .set("complexCard", true) + .set("ai", function (card) { + return get.value(card); + }); } - 'step 2' - if(event.junling=='junling2'&&source!=player){ - if(result.cards.length&&event.ing){ - player.give(result.cards,source); + "step 2"; + if (event.junling == "junling2" && source != player) { + if (result.cards.length && event.ing) { + player.give(result.cards, source); } event.num++; - if(event.num<3){ - event.ing=false; + if (event.num < 3) { + event.ing = false; event.goto(1); } } - if(event.junling=='junling6'){ - var cards=player.getCards('he'); - for(var i=0;i0){ + removeMaxHp: function (num) { + if (game.online) return; + if (!num) num = 1; + while (num > 0) { num--; - if(typeof this.singleHp=='boolean'){ - if(this.singleHp){ - this.singleHp=false; - } - else{ - this.singleHp=true; + if (typeof this.singleHp == "boolean") { + if (this.singleHp) { + this.singleHp = false; + } else { + this.singleHp = true; this.maxHp--; } - } - else{ + } else { this.maxHp--; } } this.update(); }, - hideCharacter:function(num,log){ - if(this.isUnseen(2)) return; - var name=this['name'+(num+1)]; - var next=game.createEvent('hideCharacter'); - next.player=this; - next.toHide=name; - next.num=num; - next.log=log; - next.setContent('hideCharacter'); + hideCharacter: function (num, log) { + if (this.isUnseen(2)) return; + var name = this["name" + (num + 1)]; + var next = game.createEvent("hideCharacter"); + next.player = this; + next.toHide = name; + next.num = num; + next.log = log; + next.setContent("hideCharacter"); return next; }, - removeCharacter:function(num){ - var name=this['name'+(num+1)]; - var next=game.createEvent('removeCharacter'); - next.player=this; - next.toRemove=name; - next.num=num; - next.setContent('removeCharacter'); + removeCharacter: function (num) { + var name = this["name" + (num + 1)]; + var next = game.createEvent("removeCharacter"); + next.player = this; + next.toRemove = name; + next.num = num; + next.setContent("removeCharacter"); return next; }, - $removeCharacter:function(num){ - var name=this['name'+(num+1)]; - var info=lib.character[name]; - if(!info) return; - var to='gz_shibing'+(info[0]=='male'?1:2)+info[1]; - game.log(this,'移除了'+(num?'副将':'主将'),'#b'+name); - this.reinit(name,to,false); - this.showCharacter(num,false); + $removeCharacter: function (num) { + var name = this["name" + (num + 1)]; + var info = lib.character[name]; + if (!info) return; + var to = "gz_shibing" + (info[0] == "male" ? 1 : 2) + info[1]; + game.log(this, "移除了" + (num ? "副将" : "主将"), "#b" + name); + this.reinit(name, to, false); + this.showCharacter(num, false); _status.characterlist.add(name); }, - changeVice:function(hidden){ - var next=game.createEvent('changeVice'); - next.player=this; - next.setContent('changeVice'); - next.num=(!_status.connectMode&&get.config('changeViceType')=='online')?1:3; - if(hidden) next.hidden=true; + changeVice: function (hidden) { + var next = game.createEvent("changeVice"); + next.player = this; + next.setContent("changeVice"); + next.num = !_status.connectMode && get.config("changeViceType") == "online" ? 1 : 3; + if (hidden) next.hidden = true; return next; }, - hasMainCharacter:function(){ - return this.name1.indexOf('gz_shibing')!=0; + hasMainCharacter: function () { + return this.name1.indexOf("gz_shibing") != 0; }, - hasViceCharacter:function(){ - return this.name2.indexOf('gz_shibing')!=0; + hasViceCharacter: function () { + return this.name2.indexOf("gz_shibing") != 0; }, - $showCharacter:function(num,log){ - var showYe=false; - if(num==0&&!this.isUnseen(0)){ + $showCharacter: function (num, log) { + var showYe = false; + if (num == 0 && !this.isUnseen(0)) { return; } - if(num==1&&!this.isUnseen(1)){ + if (num == 1 && !this.isUnseen(1)) { return; } - if(!this.isUnseen(2)){ + if (!this.isUnseen(2)) { return; } - game.addVideo('showCharacter',this,num); - if(this.identity=='unknown'||((num==0||num==2)&&lib.character[this.name1][1]=='ye')){ - this.group=this.getGuozhanGroup(num); - if((num==0||num==2)&&lib.character[this.name1][1]=='ye'){ - this.identity='ye'; - if(!this._ye){ - this._ye=true; - showYe=true; + game.addVideo("showCharacter", this, num); + if ( + this.identity == "unknown" || + ((num == 0 || num == 2) && lib.character[this.name1][1] == "ye") + ) { + this.group = this.getGuozhanGroup(num); + if ((num == 0 || num == 2) && lib.character[this.name1][1] == "ye") { + this.identity = "ye"; + if (!this._ye) { + this._ye = true; + showYe = true; } - } - else if(get.is.jun(this.name1)&&this.isAlive()){ - this.identity=this.group; - } - else if(this.wontYe(this.group)){ - this.identity=this.group; - } - else{ - this.identity='ye'; + } else if (get.is.jun(this.name1) && this.isAlive()) { + this.identity = this.group; + } else if (this.wontYe(this.group)) { + this.identity = this.group; + } else { + this.identity = "ye"; } this.setIdentity(this.identity); - this.ai.shown=1; - this.node.identity.classList.remove('guessing'); + this.ai.shown = 1; + this.node.identity.classList.remove("guessing"); - if(_status.clickingidentity&&_status.clickingidentity[0]==this){ - for(var i=0;i<_status.clickingidentity[1].length;i++){ + if (_status.clickingidentity && _status.clickingidentity[0] == this) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform=''; + _status.clickingidentity[1][i].style.transform = ""; } delete _status.clickingidentity; } - game.addVideo('setIdentity',this,this.identity); + game.addVideo("setIdentity", this, this.identity); } var skills; - switch(num){ + switch (num) { case 0: - if(log!==false) game.log(this,'展示了主将','#b'+this.name1); - this.name=this.name1; - skills=lib.character[this.name][3]; - this.sex=lib.character[this.name][0]; - this.classList.remove('unseen'); - break; + if (log !== false) game.log(this, "展示了主将", "#b" + this.name1); + this.name = this.name1; + skills = lib.character[this.name][3]; + this.sex = lib.character[this.name][0]; + this.classList.remove("unseen"); + break; case 1: - if(log!==false) game.log(this,'展示了副将','#b'+this.name2); - skills=lib.character[this.name2][3]; - if(this.sex=='unknown') this.sex=lib.character[this.name2][0]; - if(this.name.indexOf('unknown')==0) this.name=this.name2; - this.classList.remove('unseen2'); - break; + if (log !== false) game.log(this, "展示了副将", "#b" + this.name2); + skills = lib.character[this.name2][3]; + if (this.sex == "unknown") this.sex = lib.character[this.name2][0]; + if (this.name.indexOf("unknown") == 0) this.name = this.name2; + this.classList.remove("unseen2"); + break; case 2: - if(log!==false) game.log(this,'展示了主将','#b'+this.name1,'、副将','#b'+this.name2); - this.name=this.name1; - skills=lib.character[this.name][3].concat(lib.character[this.name2][3]); - this.sex=lib.character[this.name][0]; - this.classList.remove('unseen'); - this.classList.remove('unseen2'); - break; + if (log !== false) + game.log(this, "展示了主将", "#b" + this.name1, "、副将", "#b" + this.name2); + this.name = this.name1; + skills = lib.character[this.name][3].concat(lib.character[this.name2][3]); + this.sex = lib.character[this.name][0]; + this.classList.remove("unseen"); + this.classList.remove("unseen2"); + break; } - game.broadcast(function(player,name,sex,num,identity,group){ - player.identityShown=true; - player.group=group; - player.name=name; - player.sex=sex; - player.node.identity.classList.remove('guessing'); - switch(num){ - case 0:player.classList.remove('unseen');break; - case 1:player.classList.remove('unseen2');break; - case 2:player.classList.remove('unseen');player.classList.remove('unseen2');break; - } - player.ai.shown=1; - player.identity=identity; - player.setIdentity(identity); - if(_status.clickingidentity&&_status.clickingidentity[0]==player){ - for(var i=0;i<_status.clickingidentity[1].length;i++){ - _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform=''; + game.broadcast( + function (player, name, sex, num, identity, group) { + player.identityShown = true; + player.group = group; + player.name = name; + player.sex = sex; + player.node.identity.classList.remove("guessing"); + switch (num) { + case 0: + player.classList.remove("unseen"); + break; + case 1: + player.classList.remove("unseen2"); + break; + case 2: + player.classList.remove("unseen"); + player.classList.remove("unseen2"); + break; } - delete _status.clickingidentity; - } - },this,this.name,this.sex,num,this.identity,this.group); - this.identityShown=true; - for(var i=0;imap[player].length) return false; + if (!player || map[player].length < 2) return false; + for (var i in map) { + if (map[i].length > map[player].length) return false; } return true; }, - isNotMajor:function(){ - for(var i=0;i0){ - for(var i=0;i 0) { + for (var i = 0; i < targets.length; i++) { + shown = Math.abs(targets[i].ai.shown); + if (shown < 0.2 || targets[i].identity == "nei") c = 0; + else if (shown < 0.4) c = 0.5; + else if (shown < 0.6) c = 0.8; + else c = 1; + effect += get.effect(targets[i], card, this) * c; } } - if(effect>0){ - if(effect<1) c=0.5; - else c=1; - if(targets.length==1&&targets[0]==this); - else if(targets.length==1) this.ai.shown+=0.2*c; - else this.ai.shown+=0.1*c; + if (effect > 0) { + if (effect < 1) c = 0.5; + else c = 1; + if (targets.length == 1 && targets[0] == this); + else if (targets.length == 1) this.ai.shown += 0.2 * c; + else this.ai.shown += 0.1 * c; } } - if(this.ai.shown>0.95) this.ai.shown=0.95; - if(this.ai.shown<-0.5) this.ai.shown=-0.5; + if (this.ai.shown > 0.95) this.ai.shown = 0.95; + if (this.ai.shown < -0.5) this.ai.shown = -0.5; }, - } + }, }, - get:{ - guozhanReverse:function(name1,name2){ - if(get.is.double(name2)) return false; - if(['gz_xunyou','gz_lvfan','gz_liubei'].includes(name2)) return true; - if(name1=='gz_re_xushu') return true; - if(name2=='gz_dengai') return lib.character[name1][2]%2==1; - if(['gz_sunce','gz_jiangwei'].includes(name1)) return name2=='gz_zhoutai'||lib.character[name2][2]%2==1; + get: { + guozhanReverse: function (name1, name2) { + if (get.is.double(name2)) return false; + if (["gz_xunyou", "gz_lvfan", "gz_liubei"].includes(name2)) return true; + if (name1 == "gz_re_xushu") return true; + if (name2 == "gz_dengai") return lib.character[name1][2] % 2 == 1; + if (["gz_sunce", "gz_jiangwei"].includes(name1)) + return name2 == "gz_zhoutai" || lib.character[name2][2] % 2 == 1; return false; }, - guozhanRank:function(name,player){ - if(name.indexOf('gz_shibing')==0) return -1; - if(name.indexOf('gz_jun_')==0) return 7; - if(player){ - var skills=lib.character[name][3].slice(0); - for(var i=0;i0})) eff1=2; - else{ - if(get.damageEffect(targets[0],performer,source)>=0) eff1=2; - else eff1=-2; - if(get.damageEffect(targets[0],source,performer)>=0) eff2=2; - else eff2=-2; - } - break; - case 'junling2': - if(performer.countCards('he')){eff1=1;eff2=0;} - else{eff1=2;eff2=-1;} - break; - case 'junling3': - if(performer.hp==1&&!performer.hasSkillTag('save',true)) eff2=-5; - else{ - if(performer==viewer){ - if(performer.hasSkillTag('maihp',true)) eff2=3; - else eff2=-2; + junlingEffect: function (source, junling, performer, targets, viewer) { + var att1 = get.attitude(viewer, source), + att2 = get.attitude(viewer, performer); + var eff1 = 0, + eff2 = 0; + switch (junling) { + case "junling1": + if ( + !targets.length && + game.countPlayer(function (current) { + return get.damageEffect(viewer, current, viewer) > 0; + }) + ) + eff1 = 2; + else { + if (get.damageEffect(targets[0], performer, source) >= 0) eff1 = 2; + else eff1 = -2; + if (get.damageEffect(targets[0], source, performer) >= 0) eff2 = 2; + else eff2 = -2; } - else{ - if(performer.hasSkillTag('maihp',false)) eff2=3; - else eff2=-2; + break; + case "junling2": + if (performer.countCards("he")) { + eff1 = 1; + eff2 = 0; + } else { + eff1 = 2; + eff2 = -1; } - } - break; - case 'junling4':eff1=0;eff2=-2;break; - case 'junling5': - var td=performer.isTurnedOver(); - if(td){ - if(performer==viewer){ - if(_status.currentPhase==performer&&performer.hasSkill('jushou')) eff2=-3; - else eff2=3; + break; + case "junling3": + if (performer.hp == 1 && !performer.hasSkillTag("save", true)) eff2 = -5; + else { + if (performer == viewer) { + if (performer.hasSkillTag("maihp", true)) eff2 = 3; + else eff2 = -2; + } else { + if (performer.hasSkillTag("maihp", false)) eff2 = 3; + else eff2 = -2; + } } - else eff2=3; - } - else{ - if(performer==viewer){ - if(performer.hasSkillTag('noturn',true)) eff2=0; - else eff2=-3; + break; + case "junling4": + eff1 = 0; + eff2 = -2; + break; + case "junling5": + var td = performer.isTurnedOver(); + if (td) { + if (performer == viewer) { + if (_status.currentPhase == performer && performer.hasSkill("jushou")) + eff2 = -3; + else eff2 = 3; + } else eff2 = 3; + } else { + if (performer == viewer) { + if (performer.hasSkillTag("noturn", true)) eff2 = 0; + else eff2 = -3; + } else { + if (performer.hasSkillTag("noturn", false)) eff2 = 0; + else eff2 = -3; + } } - else{ - if(performer.hasSkillTag('noturn',false)) eff2=0; - else eff2=-3; - } - } - break; - case 'junling6': - if(performer.countCards('h')>1) eff2+=1-performer.countCards('h'); - if(performer.countCards('e')>1) eff2+=1-performer.countCards('e'); - break; + break; + case "junling6": + if (performer.countCards("h") > 1) eff2 += 1 - performer.countCards("h"); + if (performer.countCards("e") > 1) eff2 += 1 - performer.countCards("e"); + break; } - return Math.sign(att1)*eff1+Math.sign(att2)*eff2; + return Math.sign(att1) * eff1 + Math.sign(att2) * eff2; }, - realAttitude:function(from,to,difficulty,toidentity){ - var getIdentity=function(player){ - if(player.isUnseen()){ - if(!player.wontYe()) return 'ye'; + realAttitude: function (from, to, difficulty, toidentity) { + var getIdentity = function (player) { + if (player.isUnseen()) { + if (!player.wontYe()) return "ye"; return player.getGuozhanGroup(0); } return player.identity; }; - var fid=getIdentity(from); - if(fid==toidentity&&toidentity!='ye'){ - return 4+difficulty; + var fid = getIdentity(from); + if (fid == toidentity && toidentity != "ye") { + return 4 + difficulty; } - if(from.identity=='unknown'&&fid==toidentity){ - if(from.wontYe()) return 4+difficulty; + if (from.identity == "unknown" && fid == toidentity) { + if (from.wontYe()) return 4 + difficulty; } - var groups=[]; - var map={},sides=[],pmap=_status.connectMode?lib.playerOL:game.playerMap,player; - for(var i of game.players){ - if(i.identity=='unknown') continue; - var added=false; - for(var j of sides){ - if(i.isFriendOf(pmap[j])){ - added=true; + var groups = []; + var map = {}, + sides = [], + pmap = _status.connectMode ? lib.playerOL : game.playerMap, + player; + for (var i of game.players) { + if (i.identity == "unknown") continue; + var added = false; + for (var j of sides) { + if (i.isFriendOf(pmap[j])) { + added = true; map[j].push(i); - if(i==this) player=j; + if (i == this) player = j; break; } } - if(!added){ - map[i.playerid]=[i]; + if (!added) { + map[i.playerid] = [i]; sides.push(i.playerid); - if(i==this) player=i.playerid; + if (i == this) player = i.playerid; } } - for(var i in map){ - var num=map[i].length; + for (var i in map) { + var num = map[i].length; groups.push(num); } - var max=Math.max.apply(this,groups); - if(max<=1) return -3; + var max = Math.max.apply(this, groups); + if (max <= 1) return -3; var from_p; - if(from.identity=='unknown'&&from.wontYe()) from_p=get.population(fid); - else from_p=game.countPlayer(function(current){ - return current.isFriendOf(from); - }); - var to_p=game.countPlayer(function(current){ + if (from.identity == "unknown" && from.wontYe()) from_p = get.population(fid); + else + from_p = game.countPlayer(function (current) { + return current.isFriendOf(from); + }); + var to_p = game.countPlayer(function (current) { return current.isFriendOf(to); }); - if(to.identity=='ye') to_p+=1.5; + if (to.identity == "ye") to_p += 1.5; - if(to_p>=max) return -5; - if(from_p>=max) return -2-to_p; - if(max>=game.players.length/2){ - if(to_p<=from_p){ + if (to_p >= max) return -5; + if (from_p >= max) return -2 - to_p; + if (max >= game.players.length / 2) { + if (to_p <= from_p) { return 0.5; } return 0; } - if(to_p=0.5) return att*to.ai.shown; + if (to.ai.shown >= 0.5) return att * to.ai.shown; - var nshown=0; - for(var i=0;i=game.players.length/2&&att>=0){ + if (to.ai.shown == 0) { + if (nshown >= game.players.length / 2 && att >= 0) { return 0; } - return Math.min(0,Math.random()-0.5)+difficulty; + return Math.min(0, Math.random() - 0.5) + difficulty; } - if(to.ai.shown>=0.2){ - if(att>2){ - return Math.max(0,Math.random()-0.5)+difficulty; + if (to.ai.shown >= 0.2) { + if (att > 2) { + return Math.max(0, Math.random() - 0.5) + difficulty; } - if(att>=0){ + if (att >= 0) { return 0; } - return Math.min(0,Math.random()-0.7)+difficulty; + return Math.min(0, Math.random() - 0.7) + difficulty; } - if(att>2){ - return Math.max(0,Math.random()-0.7)+difficulty; + if (att > 2) { + return Math.max(0, Math.random() - 0.7) + difficulty; } - if(att>=0){ - return Math.min(0,Math.random()-0.3)+difficulty; + if (att >= 0) { + return Math.min(0, Math.random() - 0.3) + difficulty; } - return Math.min(0,Math.random()-0.5)+difficulty; + return Math.min(0, Math.random() - 0.5) + difficulty; }, }, - help:{ - '国战模式': - '
                        声明
                        • 以下所有规则均为根据公开爆料整理,经村规改动后制定的临时规则。不代表任何官方意见。请以后续发布的官方规则作为标准。
                        ' - +'
                        双势力武将
                        • 双势力武将牌可以和野心家武将牌/包含势力单武将牌/含有重叠势力的其他双势力武将牌组合,若你的主将为双势力武将,则:若你的副将为单势力武将牌,你的势力视为此势力;若你的副将为双势力武将,你的势力视为两张武将牌上的重叠势力(若重叠势力不止一个则需在游戏开始时选择一个作为自己的势力);野心家武将牌为主将,双势力武将牌为副将时,游戏开始时需选择一个副将所含势力作为副将的势力。
                        • 变更副将时,可以选择包含原势力的双势力武将牌。左慈发动〖役鬼〗时,可以使用双势力武将牌同时指定两个不同势力的角色为目标。
                        • 特殊地,“冈崎汐”作为多势力武将牌,结算流程和规则与其他双势力武将相同。
                        ' - +'
                        野心家武将
                        • 野心家武将只能放在主将位置。副将可以为任意非野心家武将牌。
                        • 选择了野心家武将牌的角色(以下简称“野心家角色”)仅明置副将时,若副将为单势力武将牌,则势力暂时视为与该武将牌相同。若副将为双势力武将牌,则势力视为游戏开始时选择的副将代表的势力。
                        • 野心家角色明置主将时,其势力改为野心家。若其是首次明置该武将牌,则其获得一个“野心家”标记。
                        • “野心家”标记可以当做“先驱”标记,“阴阳鱼”标记或是“珠联璧合”标记使用。当同时拥有两种标记时,优先弃置原装标记,下次发动时才弃置“野心家”标记。
                        • 野心家角色变更副将时,若其主将未明置过,则按照副将的势力进行变更。若主将已经明置过,则可以选择所有的非野心家武将牌。左慈发动〖役鬼〗时,可以使用野心家武将牌同时指定所有势力的角色为目标。' - +'
                        • 当场上触发了胜利条件时,若这些角色中存在未明置过主将的野心家角色,则这些野心家角色选择是否“暴露野心”。若无人选择“是”且场上存在非野心家角色存活,则所有非野心家角色胜利,野心家角色失败。若有人选择“是”,则这些角色明置主将,然后选择是否发起“拉拢人心”。
                        • 选择发起“拉拢人心”的野心家角色选择一个新的势力作为自己的势力,弃置“野心家”标记,令所有其他非野心家角色且非君主且非已“结盟”角色依次选择是否和该野心家角色“结盟”。选择“是”的角色将势力改为和该野心家势力相同。此次“拉拢人心”对所有其他角色询问结束后,所有选择“否”的角色将手牌摸至四张并回复1点体力。
                        ' - +'
                        纵横捭阖
                        • 当一名角色对目标角色发动具有拥有“纵横”衍生技的技能时,其可以令对方获得“纵横”衍生技直到其下回合结束。
                        ', + help: { + 国战模式: + '
                        声明
                        • 以下所有规则均为根据公开爆料整理,经村规改动后制定的临时规则。不代表任何官方意见。请以后续发布的官方规则作为标准。
                        ' + + '
                        双势力武将
                        • 双势力武将牌可以和野心家武将牌/包含势力单武将牌/含有重叠势力的其他双势力武将牌组合,若你的主将为双势力武将,则:若你的副将为单势力武将牌,你的势力视为此势力;若你的副将为双势力武将,你的势力视为两张武将牌上的重叠势力(若重叠势力不止一个则需在游戏开始时选择一个作为自己的势力);野心家武将牌为主将,双势力武将牌为副将时,游戏开始时需选择一个副将所含势力作为副将的势力。
                        • 变更副将时,可以选择包含原势力的双势力武将牌。左慈发动〖役鬼〗时,可以使用双势力武将牌同时指定两个不同势力的角色为目标。
                        • 特殊地,“冈崎汐”作为多势力武将牌,结算流程和规则与其他双势力武将相同。
                        ' + + '
                        野心家武将
                        • 野心家武将只能放在主将位置。副将可以为任意非野心家武将牌。
                        • 选择了野心家武将牌的角色(以下简称“野心家角色”)仅明置副将时,若副将为单势力武将牌,则势力暂时视为与该武将牌相同。若副将为双势力武将牌,则势力视为游戏开始时选择的副将代表的势力。
                        • 野心家角色明置主将时,其势力改为野心家。若其是首次明置该武将牌,则其获得一个“野心家”标记。
                        • “野心家”标记可以当做“先驱”标记,“阴阳鱼”标记或是“珠联璧合”标记使用。当同时拥有两种标记时,优先弃置原装标记,下次发动时才弃置“野心家”标记。
                        • 野心家角色变更副将时,若其主将未明置过,则按照副将的势力进行变更。若主将已经明置过,则可以选择所有的非野心家武将牌。左慈发动〖役鬼〗时,可以使用野心家武将牌同时指定所有势力的角色为目标。' + + "
                        • 当场上触发了胜利条件时,若这些角色中存在未明置过主将的野心家角色,则这些野心家角色选择是否“暴露野心”。若无人选择“是”且场上存在非野心家角色存活,则所有非野心家角色胜利,野心家角色失败。若有人选择“是”,则这些角色明置主将,然后选择是否发起“拉拢人心”。
                        • 选择发起“拉拢人心”的野心家角色选择一个新的势力作为自己的势力,弃置“野心家”标记,令所有其他非野心家角色且非君主且非已“结盟”角色依次选择是否和该野心家角色“结盟”。选择“是”的角色将势力改为和该野心家势力相同。此次“拉拢人心”对所有其他角色询问结束后,所有选择“否”的角色将手牌摸至四张并回复1点体力。
                        " + + '
                        纵横捭阖
                        • 当一名角色对目标角色发动具有拥有“纵横”衍生技的技能时,其可以令对方获得“纵横”衍生技直到其下回合结束。
                        ', }, }; }); diff --git a/mode/identity.js b/mode/identity.js index 9e1e30cc2..15c00e139 100644 --- a/mode/identity.js +++ b/mode/identity.js @@ -1,1620 +1,1908 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'identity', - start:function(){ - "step 0" - if(!lib.config.new_tutorial){ - ui.arena.classList.add('only_dialog'); + name: "identity", + start: function () { + "step 0"; + if (!lib.config.new_tutorial) { + ui.arena.classList.add("only_dialog"); } - _status.mode=get.config('identity_mode'); - if(_status.brawl&&_status.brawl.submode){ - _status.mode=_status.brawl.submode; + _status.mode = get.config("identity_mode"); + if (_status.brawl && _status.brawl.submode) { + _status.mode = _status.brawl.submode; } - event.replacePile=function(){ - var list=['shengdong','qijia','caomu','jinchan','zengbin','fulei','qibaodao','zhungangshuo','lanyinjia']; - var map={ - shunshou:'shengdong', - jiedao:'qijia', - bingliang:'caomu', - wuxie:'jinchan', - wuzhong:'zengbin', - wugu:'zengbin', - shandian:'fulei', - qinggang:'qibaodao', - qinglong:'zhungangshuo', - bagua:'lanyinjia' + event.replacePile = function () { + var list = [ + "shengdong", + "qijia", + "caomu", + "jinchan", + "zengbin", + "fulei", + "qibaodao", + "zhungangshuo", + "lanyinjia", + ]; + var map = { + shunshou: "shengdong", + jiedao: "qijia", + bingliang: "caomu", + wuxie: "jinchan", + wuzhong: "zengbin", + wugu: "zengbin", + shandian: "fulei", + qinggang: "qibaodao", + qinglong: "zhungangshuo", + bagua: "lanyinjia", }; - for(var i=0;i跳过后,你可以在选项-其它中重置新手向导'); ui.auto.hide(); - ui.create.control('跳过向导',function(){ + ui.create.control("跳过向导", function () { clear(); clear2(); game.resume(); // lib.cheat.cfg(); // owidgets }); - ui.create.control('继续',step2); - } - var step2=function(){ - if(!lib.config.phonelayout){ + ui.create.control("继续", step2); + }; + var step2 = function () { + if (!lib.config.phonelayout) { clear(); - ui.create.dialog('如果你在使用手机,可能会觉得按钮有点小'+ - ',将布局改成移动可以使按钮变大'); + ui.create.dialog( + "如果你在使用手机,可能会觉得按钮有点小" + ",将布局改成移动可以使按钮变大" + ); ui.dialog.add('
                        你可以在选项-外观-布局中更改此设置'); - var lcontrol=ui.create.control('使用移动布局',function(){ - if(lib.config.phonelayout){ - ui.control.firstChild.firstChild.innerHTML='使用移动布局'; - game.saveConfig('phonelayout',false); - lib.init.layout('mobile'); - } - else{ - ui.control.firstChild.firstChild.innerHTML='使用默认布局'; - game.saveConfig('phonelayout',true); - lib.init.layout('mobile'); + var lcontrol = ui.create.control("使用移动布局", function () { + if (lib.config.phonelayout) { + ui.control.firstChild.firstChild.innerHTML = "使用移动布局"; + game.saveConfig("phonelayout", false); + lib.init.layout("mobile"); + } else { + ui.control.firstChild.firstChild.innerHTML = "使用默认布局"; + game.saveConfig("phonelayout", true); + lib.init.layout("mobile"); } }); - ui.create.control('继续',step3); - } - else{ + ui.create.control("继续", step3); + } else { step3(); } }; - var step3=function(){ - if(lib.config.touchscreen){ + var step3 = function () { + if (lib.config.touchscreen) { clear(); - ui.create.dialog('触屏模式中,下划可以显示菜单,上划可以切换托管,双指单击可以暂停'); + ui.create.dialog("触屏模式中,下划可以显示菜单,上划可以切换托管,双指单击可以暂停"); ui.dialog.add('
                        你可以在选项-通用-中更改手势设置'); - ui.create.control('继续',step4); - } - else{ + ui.create.control("继续", step4); + } else { step4(); } }; - var step4=lib.genAsync(function*(){ + var step4 = lib.genAsync(function* () { clear(); - ui.window.classList.add('noclick_important'); + ui.window.classList.add("noclick_important"); ui.click.configMenu(); - ui.control.classList.add('noclick_click_important'); - ui.control.style.top='calc(100% - 105px)'; - yield new Promise(resolve => ui.create.control('在菜单中,可以进行各项设置',resolve)); - ui.click.menuTab('选项'); - yield new Promise(resolve => ui.controls[0].replace('如果你感到游戏较卡,可以开启流畅模式',resolve)); - yield new Promise(resolve => ui.controls[0].replace('在技能一栏中,可以设置自动发动或双将禁配的技能',resolve)); - ui.click.menuTab('武将'); - yield new Promise(resolve => ui.controls[0].replace('在武将或卡牌一栏中,单击武将/卡牌可以将其禁用',resolve)); - ui.click.menuTab('战局'); - yield new Promise(resolve => ui.controls[0].replace('在战局中可以输入游戏命令,或者管理录像',resolve)); - ui.click.menuTab('帮助'); - yield new Promise(resolve => ui.controls[0].replace('在帮助中,可以检查更新和下载素材',resolve)); + ui.control.classList.add("noclick_click_important"); + ui.control.style.top = "calc(100% - 105px)"; + yield new Promise((resolve) => ui.create.control("在菜单中,可以进行各项设置", resolve)); + ui.click.menuTab("选项"); + yield new Promise((resolve) => + ui.controls[0].replace("如果你感到游戏较卡,可以开启流畅模式", resolve) + ); + yield new Promise((resolve) => + ui.controls[0].replace("在技能一栏中,可以设置自动发动或双将禁配的技能", resolve) + ); + ui.click.menuTab("武将"); + yield new Promise((resolve) => + ui.controls[0].replace("在武将或卡牌一栏中,单击武将/卡牌可以将其禁用", resolve) + ); + ui.click.menuTab("战局"); + yield new Promise((resolve) => + ui.controls[0].replace("在战局中可以输入游戏命令,或者管理录像", resolve) + ); + ui.click.menuTab("帮助"); + yield new Promise((resolve) => + ui.controls[0].replace("在帮助中,可以检查更新和下载素材", resolve) + ); ui.click.configMenu(); - ui.window.classList.remove('noclick_important'); - ui.control.classList.remove('noclick_click_important'); - ui.control.style.top=''; + ui.window.classList.remove("noclick_important"); + ui.control.classList.remove("noclick_click_important"); + ui.control.style.top = ""; step5(); }); - var step5=function(){ + var step5 = function () { clear(); - ui.create.dialog('如果还有其它问题,欢迎来到百度无名杀吧进行交流'); - ui.create.control('完成',function(){ + ui.create.dialog("如果还有其它问题,欢迎来到百度无名杀吧进行交流"); + ui.create.control("完成", function () { clear(); clear2(); game.resume(); - }) + }); }; game.pause(); step1(); - } - else{ - if(!_status.connectMode){ + } else { + if (!_status.connectMode) { game.showChangeLog(); } } - "step 3" - if(typeof _status.new_tutorial=='function'){ + "step 3"; + if (typeof _status.new_tutorial == "function") { _status.new_tutorial(); } delete _status.new_tutorial; - if(_status.connectMode){ - game.waitForPlayer(function(){ - if(lib.configOL.identity_mode=='zhong'||lib.configOL.identity_mode=='purple'){ - lib.configOL.number=8; + if (_status.connectMode) { + game.waitForPlayer(function () { + if (lib.configOL.identity_mode == "zhong" || lib.configOL.identity_mode == "purple") { + lib.configOL.number = 8; } }); } - "step 4" - var yearLimitCheck=()=>{ - var next=game.createEvent('year_limit_pop',false); - next.setContent(function(){ - 'step 0' - var str=get.cnNumber(game.shuffleNumber+1,true); - game.me.$fullscreenpop(`第${str}年`,'thunder'); - game.log('游戏进入了',`#y第${str}年`); - if(game.shuffleNumber+1 { + var next = game.createEvent("year_limit_pop", false); + next.setContent(function () { + "step 0"; + var str = get.cnNumber(game.shuffleNumber + 1, true); + game.me.$fullscreenpop(`第${str}年`, "thunder"); + game.log("游戏进入了", `#y第${str}年`); + if (game.shuffleNumber + 1 < game.countPlayer2()) event.finish(); else game.delay(2); - 'step 1' - game.me.$fullscreenpop('年份已到','metal'); - game.log('年份已到,主忠方判定为胜利'); + "step 1"; + game.me.$fullscreenpop("年份已到", "metal"); + game.log("年份已到,主忠方判定为胜利"); game.delay(2); - 'step 2' - game.over(game.me.identity=='zhu'||game.me.identity=='zhong'||game.me.identity=='mingzhong'||(game.me.identity=='commoner'&&game.me.isIn())); + "step 2"; + game.over( + game.me.identity == "zhu" || + game.me.identity == "zhong" || + game.me.identity == "mingzhong" || + (game.me.identity == "commoner" && game.me.isIn()) + ); }); }; - if(_status.connectMode){ - _status.mode=lib.configOL.identity_mode; - if(_status.mode=='zhong'){ - lib.configOL.number=8; - if(lib.configOL.zhong_card){ + if (_status.connectMode) { + _status.mode = lib.configOL.identity_mode; + if (_status.mode == "zhong") { + lib.configOL.number = 8; + if (lib.configOL.zhong_card) { event.replacePile(); } - } - else if(_status.mode=='purple'){ - lib.configOL.number=8; - } - else if(_status.mode=='normal'){ - if(lib.configOL.enable_commoner||lib.configOL.double_nei){ - var identity=lib.configOL.enable_commoner?'commoner':'nei'; - for(var i=1;ii=='nei').length>=2) toReplace='nei'; - else if(list.filter(i=>i=='zhong').length>list.filter(i=>i=='fan').length/2) toReplace='zhong'; - else toReplace='fan'; + if (list.filter((i) => i == "nei").length >= 2) toReplace = "nei"; + else if ( + list.filter((i) => i == "zhong").length > + list.filter((i) => i == "fan").length / 2 + ) + toReplace = "zhong"; + else toReplace = "fan"; list.remove(toReplace); list.push(identity); } - game.broadcast(identityList=>lib.config.mode_config.identity.identity=identityList,lib.config.mode_config.identity.identity); + game.broadcast( + (identityList) => (lib.config.mode_config.identity.identity = identityList), + lib.config.mode_config.identity.identity + ); } } - if(lib.configOL.number<2){ - lib.configOL.number=2; + if (lib.configOL.number < 2) { + lib.configOL.number = 2; } - if(_status.mode!='purple'&&lib.configOL.enable_year_limit){ + if (_status.mode != "purple" && lib.configOL.enable_year_limit) { lib.onwash.push(yearLimitCheck); } game.randomMapOL(); - } - else{ - if(_status.mode=='normal'&&(get.config('enable_commoner')||get.config('double_nei'))){ - var identity=get.config('enable_commoner')?'commoner':'nei'; - for(var i=1;ii=='nei').length>=2) toReplace='nei'; - else if(list.filter(i=>i=='zhong').length>list.filter(i=>i=='fan').length/2) toReplace='zhong'; - else toReplace='fan'; + if (list.filter((i) => i == "nei").length >= 2) toReplace = "nei"; + else if ( + list.filter((i) => i == "zhong").length > + list.filter((i) => i == "fan").length / 2 + ) + toReplace = "zhong"; + else toReplace = "fan"; list.remove(toReplace); list.push(identity); } } - if(_status.mode!='purple'&&get.config('enable_year_limit')){ + if (_status.mode != "purple" && get.config("enable_year_limit")) { lib.onwash.push(yearLimitCheck); } - for(var i=0;i{ - _status.stratagemFuryMax=3; - ui.css.stratagemCardStyle=lib.init.sheet([ - '.card.stratagem-fury-glow:before{', - 'opacity:0.2;', - 'box-shadow:rgba(0,0,0,0.2) 0 0 0 1px,rgb(255,109,12) 0 0 5px,rgb(255,0,0) 0 0 10px;', - 'background-color:yellow;', - '-webkit-filter:blur(5px);', - 'filter:blur(5px);', - '}' - ].join('')); + var stratagemBroadcast = () => { + _status.stratagemFuryMax = 3; + ui.css.stratagemCardStyle = lib.init.sheet( + [ + ".card.stratagem-fury-glow:before{", + "opacity:0.2;", + "box-shadow:rgba(0,0,0,0.2) 0 0 0 1px,rgb(255,109,12) 0 0 5px,rgb(255,0,0) 0 0 10px;", + "background-color:yellow;", + "-webkit-filter:blur(5px);", + "filter:blur(5px);", + "}", + ].join("") + ); }; game.broadcastAll(stratagemBroadcast); - if(_status.connectMode&&!_status.postReconnect.stratagemReinit) _status.postReconnect.stratagemReinit=[stratagemBroadcast,{}]; - for(var current of game.players){ - if(current.identity=='zhu') current.addSkill('stratagem_monarchy'); - if(current.identity=='fan') current.addSkill('stratagem_revitalization'); + if (_status.connectMode && !_status.postReconnect.stratagemReinit) + _status.postReconnect.stratagemReinit = [stratagemBroadcast, {}]; + for (var current of game.players) { + if (current.identity == "zhu") current.addSkill("stratagem_monarchy"); + if (current.identity == "fan") current.addSkill("stratagem_revitalization"); } } - if(game.zhu==game.me&&game.zhu.identity!='zhu'&&_status.brawl&&_status.brawl.identityShown){ + if ( + game.zhu == game.me && + game.zhu.identity != "zhu" && + _status.brawl && + _status.brawl.identityShown + ) { delete game.zhu; - } - else{ - if(!stratagemMode) game.zhu.ai.shown=1; - if(game.zhu2){ - game.zhong=game.zhu; - game.zhu=game.zhu2; + } else { + if (!stratagemMode) game.zhu.ai.shown = 1; + if (game.zhu2) { + game.zhong = game.zhu; + game.zhu = game.zhu2; delete game.zhu2; - if(game.zhong.sex=='male'&&game.zhong.maxHp<=4){ - game.zhong.addSkill('dongcha'); - } - else{ - game.zhong.addSkill('sheshen'); + if (game.zhong.sex == "male" && game.zhong.maxHp <= 4) { + game.zhong.addSkill("dongcha"); + } else { + game.zhong.addSkill("sheshen"); } } - var enhance_zhu=false; - if(_status.connectMode){ - enhance_zhu=(!['zhong','stratagem','purple'].includes(_status.mode)&&lib.configOL.enhance_zhu&&get.population('fan')>=3); + var enhance_zhu = false; + if (_status.connectMode) { + enhance_zhu = + !["zhong", "stratagem", "purple"].includes(_status.mode) && + lib.configOL.enhance_zhu && + get.population("fan") >= 3; + } else { + enhance_zhu = + !["zhong", "stratagem", "purple"].includes(_status.mode) && + get.config("enhance_zhu") && + get.population("fan") >= 3; } - else{ - enhance_zhu=(!['zhong','stratagem','purple'].includes(_status.mode)&&get.config('enhance_zhu')&&get.population('fan')>=3); - } - if(enhance_zhu){ + if (enhance_zhu) { var skill; - switch(game.zhu.name){ - case 'key_yuri':skill='buqu';break; - case 'liubei':skill='jizhen';break; - case 'dongzhuo':skill='hengzheng';break; - case 'sunquan':skill='batu';break; - case 'sp_zhangjiao':skill='tiangong';break; - case 'liushan':skill='shengxi';break; - case 'sunce':skill='ciqiu';break; - case 're_sunben':skill='ciqiu';break; - case 'yuanshao':skill='geju';break; - case 're_caocao':skill='dangping';break; - case 'caopi':skill='junxing';break; - case 'liuxie':skill='moukui';break; - default:skill='tianming';break; + switch (game.zhu.name) { + case "key_yuri": + skill = "buqu"; + break; + case "liubei": + skill = "jizhen"; + break; + case "dongzhuo": + skill = "hengzheng"; + break; + case "sunquan": + skill = "batu"; + break; + case "sp_zhangjiao": + skill = "tiangong"; + break; + case "liushan": + skill = "shengxi"; + break; + case "sunce": + skill = "ciqiu"; + break; + case "re_sunben": + skill = "ciqiu"; + break; + case "yuanshao": + skill = "geju"; + break; + case "re_caocao": + skill = "dangping"; + break; + case "caopi": + skill = "junxing"; + break; + case "liuxie": + skill = "moukui"; + break; + default: + skill = "tianming"; + break; } - game.broadcastAll(function(player,skill){ - player.addSkill(skill); - player.storage.enhance_zhu=skill; - },game.zhu,skill); + game.broadcastAll( + function (player, skill) { + player.addSkill(skill); + player.storage.enhance_zhu = skill; + }, + game.zhu, + skill + ); } } game.syncState(); - event.trigger('gameStart'); + event.trigger("gameStart"); - var players=get.players(lib.sort.position); - var info=[]; - for(var i=0;i5) return 5; + "step 6"; + if (_status.mode != "stratagem") + event.beginner = _status.firstAct2 || game.zhong || game.zhu || _status.firstAct || game.me; + game.gameDraw(event.beginner, function (player) { + if (_status.mode == "purple" && player.seatNum > 5) return 5; return 4; }); - if(_status.connectMode&&lib.configOL.change_card) game.replaceHandcards(game.players.slice(0)); - "step 7" + if (_status.connectMode && lib.configOL.change_card) game.replaceHandcards(game.players.slice(0)); + "step 7"; game.phaseLoop(event.beginner); }, - game:{ - canReplaceViewpoint:()=>true, - getState:function(){ - var state={}; - for(var i in lib.playerOL){ - var player=lib.playerOL[i]; - state[i]={identity:player.identity}; - if(player==game.zhu){ - state[i].zhu=true; + game: { + canReplaceViewpoint: () => true, + getState: function () { + var state = {}; + for (var i in lib.playerOL) { + var player = lib.playerOL[i]; + state[i] = { identity: player.identity }; + if (player == game.zhu) { + state[i].zhu = true; } - if(player==game.zhong){ - state[i].zhong=true; + if (player == game.zhong) { + state[i].zhong = true; } - if(player.isZhu){ - state[i].isZhu=true; + if (player.isZhu) { + state[i].isZhu = true; } - if(player.special_identity){ - state[i].special_identity=player.special_identity; + if (player.special_identity) { + state[i].special_identity = player.special_identity; } - state[i].shown=player.ai.shown; + state[i].shown = player.ai.shown; //state[i].group=player.group; } return state; }, - updateState:function(state){ - for(var i in state){ - var player=lib.playerOL[i]; - if(player){ - player.identity=state[i].identity; - if(state[i].identity=='rZhu'||state[i].identity=='bZhu') game[state[i].identity]=player; - if(state[i].special_identity){ - player.special_identity=state[i].special_identity; - if(player.node.dieidentity){ - player.node.dieidentity.innerHTML=get.translation(state[i].special_identity); - player.node.identity.firstChild.innerHTML=get.translation(state[i].special_identity+'_bg'); + updateState: function (state) { + for (var i in state) { + var player = lib.playerOL[i]; + if (player) { + player.identity = state[i].identity; + if (state[i].identity == "rZhu" || state[i].identity == "bZhu") + game[state[i].identity] = player; + if (state[i].special_identity) { + player.special_identity = state[i].special_identity; + if (player.node.dieidentity) { + player.node.dieidentity.innerHTML = get.translation( + state[i].special_identity + ); + player.node.identity.firstChild.innerHTML = get.translation( + state[i].special_identity + "_bg" + ); } } - if(state[i].zhu){ - game.zhu=player; + if (state[i].zhu) { + game.zhu = player; } - if(state[i].isZhu){ - player.isZhu=true; + if (state[i].isZhu) { + player.isZhu = true; } - if(state[i].zhong){ - game.zhong=player; + if (state[i].zhong) { + game.zhong = player; } - player.ai.shown=state[i].shown; + player.ai.shown = state[i].shown; //player.group=state[i].group; //player.node.name.dataset.nature=get.groupnature(player.group); } } }, - getRoomInfo:function(uiintro){ - uiintro.add('
                        游戏模式:'+(lib.configOL.identity_mode=='zhong'?'明忠':'标准')); - uiintro.add('
                        双将模式:'+(lib.configOL.double_character?'开启':'关闭')); - if(lib.configOL.identity_mode!='zhong'){ - if(lib.configOL.identity_mode=='stratagem'){ - uiintro.add('
                        首轮强化:'+(lib.configOL.round_one_use_fury?'开启':'关闭')); - } - else if(lib.configOL.identity_mode!='purple'){ - uiintro.add('
                        双内奸:'+(lib.configOL.double_nei?'开启':'关闭')); - if(lib.configOL.identity_mode!='stratagem'){ - uiintro.add('
                        加强主公:'+(lib.configOL.enhance_zhu?'开启':'关闭')); - uiintro.add('
                        平民身份:'+(lib.configOL.enable_commoner?'开启':'关闭')); + getRoomInfo: function (uiintro) { + uiintro.add( + '
                        游戏模式:' + + (lib.configOL.identity_mode == "zhong" ? "明忠" : "标准") + ); + uiintro.add( + '
                        双将模式:' + (lib.configOL.double_character ? "开启" : "关闭") + ); + if (lib.configOL.identity_mode != "zhong") { + if (lib.configOL.identity_mode == "stratagem") { + uiintro.add( + '
                        首轮强化:' + + (lib.configOL.round_one_use_fury ? "开启" : "关闭") + ); + } else if (lib.configOL.identity_mode != "purple") { + uiintro.add( + '
                        双内奸:' + (lib.configOL.double_nei ? "开启" : "关闭") + ); + if (lib.configOL.identity_mode != "stratagem") { + uiintro.add( + '
                        加强主公:' + + (lib.configOL.enhance_zhu ? "开启" : "关闭") + ); + uiintro.add( + '
                        平民身份:' + + (lib.configOL.enable_commoner ? "开启" : "关闭") + ); } - uiintro.add('
                        年机制:'+(lib.configOL.enable_year_limit?'开启':'关闭')); + uiintro.add( + '
                        年机制:' + + (lib.configOL.enable_year_limit ? "开启" : "关闭") + ); } + } else { + uiintro.add( + '
                        卡牌替换:' + (lib.configOL.zhong_card ? "开启" : "关闭") + ); } - else{ - uiintro.add('
                        卡牌替换:'+(lib.configOL.zhong_card?'开启':'关闭')); - } - var last=uiintro.add('
                        出牌时限:'+lib.configOL.choose_timeout+'秒'); + var last = uiintro.add( + '
                        出牌时限:' + lib.configOL.choose_timeout + "秒" + ); // uiintro.add('
                        屏蔽弱将:'+(lib.configOL.ban_weak?'开启':'关闭')); // var last=uiintro.add('
                        屏蔽强将:'+(lib.configOL.ban_strong?'开启':'关闭')); - if(lib.configOL.banned.length){ - last=uiintro.add('
                        禁用武将:'+get.translation(lib.configOL.banned)); + if (lib.configOL.banned.length) { + last = uiintro.add( + '
                        禁用武将:' + get.translation(lib.configOL.banned) + ); } - if(lib.configOL.bannedcards.length){ - last=uiintro.add('
                        禁用卡牌:'+get.translation(lib.configOL.bannedcards)); + if (lib.configOL.bannedcards.length) { + last = uiintro.add( + '
                        禁用卡牌:' + get.translation(lib.configOL.bannedcards) + ); } - last.style.paddingBottom='8px'; + last.style.paddingBottom = "8px"; }, - getIdentityList:function(player){ - if(player.identityShown) return; - if(player==game.me) return; - if(_status.mode=='purple'){ - if(_status.yeconfirm&&['rNei','bNei'].includes(game.me.identity)&&['rNei','bNei'].includes(player.identity)) return; - if(player.identity.slice(0,1)=='r') return { - cai2:'猜', - rZhong:'忠', - rNei:'内', - rYe:'野', - } + getIdentityList: function (player) { + if (player.identityShown) return; + if (player == game.me) return; + if (_status.mode == "purple") { + if ( + _status.yeconfirm && + ["rNei", "bNei"].includes(game.me.identity) && + ["rNei", "bNei"].includes(player.identity) + ) + return; + if (player.identity.slice(0, 1) == "r") + return { + cai2: "猜", + rZhong: "忠", + rNei: "内", + rYe: "野", + }; return { - cai:'猜', - bZhong:'忠', - bNei:'内', - bYe:'野', - } - } - else if(_status.mode=='zhong'){ - if(player.fanfixed) return; - if(game.zhu&&game.zhu.isZhu){ + cai: "猜", + bZhong: "忠", + bNei: "内", + bYe: "野", + }; + } else if (_status.mode == "zhong") { + if (player.fanfixed) return; + if (game.zhu && game.zhu.isZhu) { return { - fan:'反', - zhong:'忠', - nei:'内', - cai:'猜', - } - } - else{ + fan: "反", + zhong: "忠", + nei: "内", + cai: "猜", + }; + } else { return { - fan:'反', - zhong:'忠', - nei:'内', - zhu:'主', - cai:'猜', - } + fan: "反", + zhong: "忠", + nei: "内", + zhu: "主", + cai: "猜", + }; } - } - else if(_status.mode=='stratagem'){ - if(game.zhu&&game.zhu.isZhu&&game.zhu.identityShown||game.me.identity=='zhu'){ + } else if (_status.mode == "stratagem") { + if ((game.zhu && game.zhu.isZhu && game.zhu.identityShown) || game.me.identity == "zhu") { return { - fan:'反', - zhong:'忠', - nei:'内', - enemy:'敌', - friend:'友', - cai:'猜', - } + fan: "反", + zhong: "忠", + nei: "内", + enemy: "敌", + friend: "友", + cai: "猜", + }; + } else { + return { + fan: "反", + zhong: "忠", + nei: "内", + zhu: "主", + enemy: "敌", + friend: "友", + cai: "猜", + }; } - else{ + } else { + if (get.config("enable_commoner")) { return { - fan:'反', - zhong:'忠', - nei:'内', - zhu:'主', - enemy:'敌', - friend:'友', - cai:'猜', - } - } - } - else{ - if(get.config('enable_commoner')){ + fan: "反", + zhong: "忠", + nei: "内", + commoner: "民", + cai: "猜", + }; + } else { return { - fan:'反', - zhong:'忠', - nei:'内', - commoner:'民', - cai:'猜', - } - } - else{ - return { - fan:'反', - zhong:'忠', - nei:'内', - cai:'猜', - } + fan: "反", + zhong: "忠", + nei: "内", + cai: "猜", + }; } } }, - getIdentityList2:function(list){ - for(var i in list){ - switch(i){ - case 'fan':list[i]='反贼';break; - case 'zhong':list[i]='忠臣';break; - case 'nei':list[i]='内奸';break; - case 'commoner':list[i]='平民'; break; - case 'zhu':list[i]='主公';break; - case 'enemy':list[i]='敌方';break; - case 'friend':list[i]='友方';break; - case 'cai':case 'cai2':list[i]='未知';break; - case 'rZhong':case 'bZhong':list[i]='前锋';break; - case 'rNei':case 'bNei':list[i]='细作';break; - case 'rYe':case 'bYe':list[i]='野心家';break; + getIdentityList2: function (list) { + for (var i in list) { + switch (i) { + case "fan": + list[i] = "反贼"; + break; + case "zhong": + list[i] = "忠臣"; + break; + case "nei": + list[i] = "内奸"; + break; + case "commoner": + list[i] = "平民"; + break; + case "zhu": + list[i] = "主公"; + break; + case "enemy": + list[i] = "敌方"; + break; + case "friend": + list[i] = "友方"; + break; + case "cai": + case "cai2": + list[i] = "未知"; + break; + case "rZhong": + case "bZhong": + list[i] = "前锋"; + break; + case "rNei": + case "bNei": + list[i] = "细作"; + break; + case "rYe": + case "bYe": + list[i] = "野心家"; + break; } } }, - getVideoName:function(){ - var str=get.translation(game.me.name); - if(game.me.name2){ - str+='/'+get.translation(game.me.name2); + getVideoName: function () { + var str = get.translation(game.me.name); + if (game.me.name2) { + str += "/" + get.translation(game.me.name2); } var str2; - if(game.identityVideoName) str2=game.identityVideoName; - else{ - switch(_status.mode){ - case 'purple':str2='3v3v2 - '+(game.me.identity.indexOf('r')==0?'暖色':'冷色')+lib.translate[game.me.identity+'2'];break; - case 'zhong':str2='忠胆英杰 - '+lib.translate[game.me.identity+'2'];break; - case 'stratagem':str2=get.cnNumber(get.playerNumber())+'人谋攻'+'-'+lib.translate[game.me.identity+'2'];break; - default:str2=get.cnNumber(get.playerNumber())+'人'+get.translation(lib.config.mode)+' - '+lib.translate[game.me.identity+'2'] + if (game.identityVideoName) str2 = game.identityVideoName; + else { + switch (_status.mode) { + case "purple": + str2 = + "3v3v2 - " + + (game.me.identity.indexOf("r") == 0 ? "暖色" : "冷色") + + lib.translate[game.me.identity + "2"]; + break; + case "zhong": + str2 = "忠胆英杰 - " + lib.translate[game.me.identity + "2"]; + break; + case "stratagem": + str2 = + get.cnNumber(get.playerNumber()) + + "人谋攻" + + "-" + + lib.translate[game.me.identity + "2"]; + break; + default: + str2 = + get.cnNumber(get.playerNumber()) + + "人" + + get.translation(lib.config.mode) + + " - " + + lib.translate[game.me.identity + "2"]; } } - var name=[ - str, - str2, - ]; + var name = [str, str2]; return name; }, - addRecord:function(bool){ - if(typeof bool=='boolean'){ - var data=lib.config.gameRecord.identity.data; - var identity=game.me.identity; - if(identity=='mingzhong'){ - identity='zhong'; + addRecord: function (bool) { + if (typeof bool == "boolean") { + var data = lib.config.gameRecord.identity.data; + var identity = game.me.identity; + if (identity == "mingzhong") { + identity = "zhong"; } - if(!data[identity]){ - data[identity]=[0,0]; + if (!data[identity]) { + data[identity] = [0, 0]; } - if(bool){ + if (bool) { data[identity][0]++; - } - else{ + } else { data[identity][1]++; } - var list=['zhu','zhong','nei','fan','commoner']; - var str=''; - for(var i=0;i'; + var list = ["zhu", "zhong", "nei", "fan", "commoner"]; + var str = ""; + for (var i = 0; i < list.length; i++) { + if (data[list[i]]) { + str += + lib.translate[list[i] + "2"] + + ":" + + data[list[i]][0] + + "胜" + + " " + + data[list[i]][1] + + "负
                        "; } } - lib.config.gameRecord.identity.str=str; - game.saveConfig('gameRecord',lib.config.gameRecord); + lib.config.gameRecord.identity.str = str; + game.saveConfig("gameRecord", lib.config.gameRecord); } }, - showIdentity:function(me){ - for(var i=0;i0||loser.length==game.players.length){ - game.broadcastAll(function(winner,loser){ - _status.winner=winner; - _status.loser=loser; - },winner,loser); - if(loser.length==game.players.length){ + if (winner.length > 0 || loser.length == game.players.length) { + game.broadcastAll( + function (winner, loser) { + _status.winner = winner; + _status.loser = loser; + }, + winner, + loser + ); + if (loser.length == game.players.length) { game.showIdentity(); - game.over('游戏平局'); - } - else if(winner2.includes(me)){ + game.over("游戏平局"); + } else if (winner2.includes(me)) { game.showIdentity(); - if(loser2.includes(me)) game.over(false); + if (loser2.includes(me)) game.over(false); else game.over(true); - } - else{ + } else { game.showIdentity(); game.over(false); } } return; } - if(!game.zhu){ - if(get.population('fan')==0){ - switch(me.identity){ - case 'fan':game.over(false);break; - case 'zhong':game.over(true);break; - case 'commoner':game.over(true); break; - default:game.over();break; + if (!game.zhu) { + if (get.population("fan") == 0) { + switch (me.identity) { + case "fan": + game.over(false); + break; + case "zhong": + game.over(true); + break; + case "commoner": + game.over(true); + break; + default: + game.over(); + break; } - } - else if(get.population('zhong')==0){ - switch(me.identity){ - case 'fan':game.over(true);break; - case 'zhong':game.over(false);break; - case 'commoner':game.over(true); break; - default:game.over();break; + } else if (get.population("zhong") == 0) { + switch (me.identity) { + case "fan": + game.over(true); + break; + case "zhong": + game.over(false); + break; + case "commoner": + game.over(true); + break; + default: + game.over(); + break; } } return; } - if(game.zhu.isAlive()&&get.population('fan')+get.population('nei')>0) return; - if(game.zhong){ - game.zhong.identity='zhong'; + if (game.zhu.isAlive() && get.population("fan") + get.population("nei") > 0) return; + if (game.zhong) { + game.zhong.identity = "zhong"; } game.showIdentity(); - if(me.identity=='zhu'||me.identity=='zhong'||me.identity=='mingzhong'){ - if(game.zhu.classList.contains('dead')){ + if (me.identity == "zhu" || me.identity == "zhong" || me.identity == "mingzhong") { + if (game.zhu.classList.contains("dead")) { game.over(false); - } - else{ + } else { game.over(true); } - } - else if(me.identity=='nei'){ - if(game.players.length==(1+game.players.filter(i=>i.identity=='commoner').length)&&me.isAlive()){ + } else if (me.identity == "nei") { + if ( + game.players.length == + 1 + game.players.filter((i) => i.identity == "commoner").length && + me.isAlive() + ) { game.over(true); - } - else{ + } else { game.over(false); } - } - else if(me.identity=='fan'){ - if((get.population('fan')+get.population('zhong')>0||get.population('nei')>1)&& - game.zhu.classList.contains('dead')){ + } else if (me.identity == "fan") { + if ( + (get.population("fan") + get.population("zhong") > 0 || get.population("nei") > 1) && + game.zhu.classList.contains("dead") + ) { game.over(true); - } - else{ + } else { game.over(false); } - } - else if(me.identity=='commoner'){ + } else if (me.identity == "commoner") { game.over(true); } }, - checkOnlineResult:function(player){ - if(_status.winner&&_status.loser){ - if(_status.loser.length==game.players.length) return null; - if(_status.loser.includes(player)) return false; - if(_status.winner.includes(player)) return true; + checkOnlineResult: function (player) { + if (_status.winner && _status.loser) { + if (_status.loser.length == game.players.length) return null; + if (_status.loser.includes(player)) return false; + if (_status.winner.includes(player)) return true; } - if(game.zhu.isAlive()){ - return (player.identity=='zhu'||player.identity=='zhong'||player.identity=='mingzhong'||player.identity=='commoner'&&player.isAlive()); - } - else if(game.players.length==(1+game.players.filter(i=>i.identity=='commoner').length)&&game.players[0].identity=='nei'||game.players[0].identity=='commoner'){ + if (game.zhu.isAlive()) { + return ( + player.identity == "zhu" || + player.identity == "zhong" || + player.identity == "mingzhong" || + (player.identity == "commoner" && player.isAlive()) + ); + } else if ( + (game.players.length == 1 + game.players.filter((i) => i.identity == "commoner").length && + game.players[0].identity == "nei") || + game.players[0].identity == "commoner" + ) { return player.isAlive(); - } - else{ - return player.identity=='fan'||player.identity=='commoner'&&player.isAlive(); + } else { + return player.identity == "fan" || (player.identity == "commoner" && player.isAlive()); } }, - chooseCharacterPurpleOL:function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - "step 0" - ui.arena.classList.add('choose-character'); - "step 1" - var list=['rZhu','rZhong','rNei','rYe']; - var list2=['bZhu','bZhong','bNei','bYe']; + chooseCharacterPurpleOL: function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); + "step 1"; + var list = ["rZhu", "rZhong", "rNei", "rYe"]; + var list2 = ["bZhu", "bZhong", "bNei", "bYe"]; list.randomSort(); list2.randomSort(); - var identityList=list.concat(list2); - var num=get.rand(0,7); - var players=game.players.slice(0); - for(var i=0;i15?5:3; + } else event.mapNum[i] = map[i].length > 15 ? 5 : 3; } - list.sort(function(a,b){ - return lib.group.indexOf(a)-lib.group.indexOf(b); + list.sort(function (a, b) { + return lib.group.indexOf(a) - lib.group.indexOf(b); }); - event.list=list; - event.map=map; - event.map_zhu=map_zhu; - game.bZhu.chooseControl(list).set('prompt','请选择冷方武将势力').set('ai',function(){ - return _status.event.choice; - }).set('choice',event.list.randomGet()); - "step 3" - event.bZhu=result.control; + event.list = list; + event.map = map; + event.map_zhu = map_zhu; + game.bZhu + .chooseControl(list) + .set("prompt", "请选择冷方武将势力") + .set("ai", function () { + return _status.event.choice; + }) + .set("choice", event.list.randomGet()); + "step 3"; + event.bZhu = result.control; event.list.remove(event.bZhu); - game.rZhu.chooseControl(event.list).set('prompt','请选择暖方武将的势力').set('ai',function(){ - return _status.event.choice; - }).set('choice',event.list.randomGet()); - "step 4" - event.rZhu=result.control; - var players=[game.rZhu,game.bZhu]; - var list=[]; - for(var i=0;i5){ - num=5; + var num, + num2 = 0; + num = Math.floor(event.list.length / (game.players.length - 1)); + if (num > 5) { + num = 5; } - num2=event.list.length-num*(game.players.length-1); - if(lib.configOL.double_nei){ - num2=Math.floor(num2/2); + num2 = event.list.length - num * (game.players.length - 1); + if (lib.configOL.double_nei) { + num2 = Math.floor(num2 / 2); } - if(num2>2){ - num2=2; + if (num2 > 2) { + num2 = 2; } - for(var i=0;igame.addGlobalSkill(globalSkill)); - game.players.forEach(current=>{ - current.storage.zhibi=[]; - current.storage.stratagem_expose=[]; - current.markSkill('stratagem_fury'); + ["stratagem_gain", "stratagem_insight", "stratagem_expose"].forEach((globalSkill) => + game.addGlobalSkill(globalSkill) + ); + game.players.forEach((current) => { + current.storage.zhibi = []; + current.storage.stratagem_expose = []; + current.markSkill("stratagem_fury"); }); - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); }); }, - chooseCharacter:function(){ - if(_status.mode=='purple'){ + chooseCharacter: function () { + if (_status.mode == "purple") { game.chooseCharacterPurple(); return; } - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.addPlayer=function(player){ - var list=get.identityList(game.players.length-1); - var list2=get.identityList(game.players.length); - for(var i=0;i4){ - if(!player.isInitFilter('noZhuHp')){ + if (game.players.length > 4) { + if (!player.isInitFilter("noZhuHp")) { player.hp++; player.maxHp++; player.update(); } } - } - else if(player.identity=='zhong'&&(Math.random()<0.5||['sunliang','key_akane'].includes(game.zhu.name))&&!stratagemMode){ - var listc=list.slice(0); - for(var i=0;i'; - td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ - if(_status.dragged) return; - if(_status.justdragged) return; - _status.tempNoButton=true; - setTimeout(function(){ - _status.tempNoButton=false; - },500); - var link=this.link; - if(game.zhu){ - if(link!='random'){ - _status.event.parent.fixedseat=get.distance(game.me,game.zhu,'absolute'); + td.innerHTML = "" + get.translation(listi[i] + "2") + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + if (_status.dragged) return; + if (_status.justdragged) return; + _status.tempNoButton = true; + setTimeout(function () { + _status.tempNoButton = false; + }, 500); + var link = this.link; + if (game.zhu) { + if (link != "random") { + _status.event.parent.fixedseat = get.distance( + game.me, + game.zhu, + "absolute" + ); } - if(game.zhu.name) game.zhu.uninit(); + if (game.zhu.name) game.zhu.uninit(); delete game.zhu.isZhu; delete game.zhu.identityShown; } - var current=this.parentNode.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + var current = this.parentNode.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - current=_status.cheat_seat||seats.querySelector('.bluebg'); - if(current){ - current.classList.remove('bluebg'); + current = _status.cheat_seat || seats.querySelector(".bluebg"); + if (current) { + current.classList.remove("bluebg"); } - if(link=='random'){ - if(event.zhongmode){ - link=['zhu','zhong','nei','fan','mingzhong'].randomGet(); + if (link == "random") { + if (event.zhongmode) { + link = ["zhu", "zhong", "nei", "fan", "mingzhong"].randomGet(); + } else { + var listi = ["zhu", "zhong", "nei", "fan"]; + if (get.config("enable_commoner") && !event.stratagemMode) + listi.push("commoner"); + link = listi.randomGet(); } - else{ - var listi=['zhu','zhong','nei','fan']; - if(get.config('enable_commoner')&&!event.stratagemMode) listi.push('commoner'); - link=listi.randomGet(); - } - for(var i=0;i=1){ - fans.randomRemove().special_identity='identity_zeishou'; - event.special_identity.push('identity_zeishou'); + if (fans.length >= 1) { + fans.randomRemove().special_identity = "identity_zeishou"; + event.special_identity.push("identity_zeishou"); } - if(zhongs.length>1){ - zhongs.randomRemove().special_identity='identity_dajiang'; - zhongs.randomRemove().special_identity='identity_junshi'; - event.special_identity.push('identity_dajiang'); - event.special_identity.push('identity_junshi'); - } - else if(zhongs.length==1){ - if(Math.random()<0.5){ - zhongs.randomRemove().special_identity='identity_dajiang'; - event.special_identity.push('identity_dajiang'); - } - else{ - zhongs.randomRemove().special_identity='identity_junshi'; - event.special_identity.push('identity_junshi'); + if (zhongs.length > 1) { + zhongs.randomRemove().special_identity = "identity_dajiang"; + zhongs.randomRemove().special_identity = "identity_junshi"; + event.special_identity.push("identity_dajiang"); + event.special_identity.push("identity_junshi"); + } else if (zhongs.length == 1) { + if (Math.random() < 0.5) { + zhongs.randomRemove().special_identity = "identity_dajiang"; + event.special_identity.push("identity_dajiang"); + } else { + zhongs.randomRemove().special_identity = "identity_junshi"; + event.special_identity.push("identity_junshi"); } } } - if(!game.zhu) game.zhu=game.me; - else{ - if(!stratagemMode){ + if (!game.zhu) game.zhu = game.me; + else { + if (!stratagemMode) { game.zhu.setIdentity(); - game.zhu.identityShown=true; - game.zhu.node.identity.classList.remove('guessing'); + game.zhu.identityShown = true; + game.zhu.node.identity.classList.remove("guessing"); } - game.zhu.isZhu=(game.zhu.identity=='zhu'); + game.zhu.isZhu = game.zhu.identity == "zhu"; game.me.setIdentity(); - game.me.node.identity.classList.remove('guessing'); + game.me.node.identity.classList.remove("guessing"); } //选将框分配 - for(i in lib.characterReplace){ - var ix=lib.characterReplace[i]; - for(var j=0;j4){ - if(!game.me.isInitFilter('noZhuHp')){ + if (!event.stratagemMode && game.me == game.zhu && game.players.length > 4) { + if (!game.me.isInitFilter("noZhuHp")) { game.me.hp++; game.me.maxHp++; game.me.update(); } } - for(var i=0;igame.addGlobalSkill(globalSkill)); - game.players.forEach(i=>{ - i.storage.zhibi=[]; - i.storage.stratagem_expose=[]; - i.markSkill('stratagem_fury'); + "step 4"; + if (event.stratagemMode) { + ["stratagem_gain", "stratagem_insight", "stratagem_expose"].forEach((globalSkill) => + game.addGlobalSkill(globalSkill) + ); + game.players.forEach((i) => { + i.storage.zhibi = []; + i.storage.stratagem_expose = []; + i.markSkill("stratagem_fury"); }); } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); - if(event.special_identity){ - for(var i=0;i=1){ - map.identity_zeishou=fans.randomRemove(); + if (fans.length >= 1) { + map.identity_zeishou = fans.randomRemove(); } - if(zhongs.length>1){ - map.identity_dajiang=zhongs.randomRemove(); - map.identity_junshi=zhongs.randomRemove(); - } - else if(zhongs.length==1){ - if(Math.random()<0.5){ - map.identity_dajiang=zhongs.randomRemove(); - } - else{ - map.identity_junshi=zhongs.randomRemove(); + if (zhongs.length > 1) { + map.identity_dajiang = zhongs.randomRemove(); + map.identity_junshi = zhongs.randomRemove(); + } else if (zhongs.length == 1) { + if (Math.random() < 0.5) { + map.identity_dajiang = zhongs.randomRemove(); + } else { + map.identity_junshi = zhongs.randomRemove(); } } - game.broadcastAll(function(zhu,map){ - for(var i in map){ - map[i].special_identity=i; - } - },game.zhu,map); - event.special_identity=map; + game.broadcastAll( + function (zhu, map) { + for (var i in map) { + map[i].special_identity = i; + } + }, + game.zhu, + map + ); + event.special_identity = map; } game.zhu.setIdentity(); - game.zhu.identityShown=true; - game.zhu.isZhu=(game.zhu.identity=='zhu'); - game.zhu.node.identity.classList.remove('guessing'); + game.zhu.identityShown = true; + game.zhu.isZhu = game.zhu.identity == "zhu"; + game.zhu.node.identity.classList.remove("guessing"); game.me.setIdentity(); - game.me.node.identity.classList.remove('guessing'); - if(game.me.special_identity){ - game.me.node.identity.firstChild.innerHTML=get.translation(game.me.special_identity+'_bg'); + game.me.node.identity.classList.remove("guessing"); + if (game.me.special_identity) { + game.me.node.identity.firstChild.innerHTML = get.translation( + game.me.special_identity + "_bg" + ); } - for(var i=0;i4){ - if(!game.zhu.isInitFilter('noZhuHp')){ + if (game.players.length > 4) { + if (!game.zhu.isInitFilter("noZhuHp")) { game.zhu.maxHp++; game.zhu.hp++; game.zhu.update(); } } - game.broadcast(function(zhu,name,name2,addMaxHp){ - if(!zhu.name){ - zhu.init(name,name2); - } - if(addMaxHp){ - if(!zhu.isInitFilter('noZhuHp')){ - zhu.maxHp++; - zhu.hp++; - zhu.update(); + game.broadcast( + function (zhu, name, name2, addMaxHp) { + if (!zhu.name) { + zhu.init(name, name2); } - } - },game.zhu,result.links[0],result.links[1],game.players.length>4); + if (addMaxHp) { + if (!zhu.isInitFilter("noZhuHp")) { + zhu.maxHp++; + zhu.hp++; + zhu.update(); + } + } + }, + game.zhu, + result.links[0], + result.links[1], + game.players.length > 4 + ); - if(game.zhu.group=='shen'&&!game.zhu.isUnseen(0)){ - var list=['wei','shu','wu','qun','jin','key']; - for(var i=0;i5){ - num=5; + var num, + num2 = 0; + if (event.zhongmode) { + num = 6; + } else { + num = Math.floor(event.list.length / (game.players.length - 1)); + if (num > 5) { + num = 5; } - num2=event.list.length-num*(game.players.length-1); - if(lib.configOL.double_nei){ - num2=Math.floor(num2/2); + num2 = event.list.length - num * (game.players.length - 1); + if (lib.configOL.double_nei) { + num2 = Math.floor(num2 / 2); } - if(num2>2){ - num2=2; + if (num2 > 2) { + num2 = 2; } } - for(var i=0;i0.95){ - this.ai.shown=0.95; + addExpose: function (num) { + if (!game.zhu || !game.zhu.isZhu || !game.zhu.identityShown) return; + if (typeof this.ai.shown == "number" && !this.identityShown && this.ai.shown < 1) { + this.ai.shown += num; + if (this.ai.shown > 0.95) { + this.ai.shown = 0.95; } } return this; }, - yexinbilu:function(){ - game.broadcastAll(function(player){ + yexinbilu: function () { + game.broadcastAll(function (player) { player.showIdentity(); - },this); + }, this); this.gainMaxHp(); this.recover(); }, - $dieAfter:function(){ - if(_status.video) return; - if(!this.node.dieidentity){ + $dieAfter: function () { + if (_status.video) return; + if (!this.node.dieidentity) { var str; - if(this.special_identity){ - str=get.translation(this.special_identity); + if (this.special_identity) { + str = get.translation(this.special_identity); + } else { + str = get.translation(this.identity + "2"); } - else{ - str=get.translation(this.identity+'2'); - } - var node=ui.create.div('.damage.dieidentity',str,this); - if(str=='野心家'){ - node.style.fontSize='40px'; + var node = ui.create.div(".damage.dieidentity", str, this); + if (str == "野心家") { + node.style.fontSize = "40px"; } ui.refresh(node); - node.style.opacity=1; - this.node.dieidentity=node; + node.style.opacity = 1; + this.node.dieidentity = node; } - var trans=this.style.transform; - if(trans){ - if(trans.indexOf('rotateY')!=-1){ - this.node.dieidentity.style.transform='rotateY(180deg)'; + var trans = this.style.transform; + if (trans) { + if (trans.indexOf("rotateY") != -1) { + this.node.dieidentity.style.transform = "rotateY(180deg)"; + } else if (trans.indexOf("rotateX") != -1) { + this.node.dieidentity.style.transform = "rotateX(180deg)"; + } else { + this.node.dieidentity.style.transform = ""; } - else if(trans.indexOf('rotateX')!=-1){ - this.node.dieidentity.style.transform='rotateX(180deg)'; - } - else{ - this.node.dieidentity.style.transform=''; - } - } - else{ - this.node.dieidentity.style.transform=''; + } else { + this.node.dieidentity.style.transform = ""; } }, - dieAfter2:function(source){ - if(_status.mode=='stratagem') return; - if(_status.mode=='purple'){ - if(source){ - if(this.identity=='rZhu'||this.identity=='bZhu'){ - if(this.identity.slice(0,1)!=source.identity.slice(0,1)) source.recover(); - } - else if(this.identity=='rZhong'||this.identity=='bZhong'){ - if(this.identity.slice(0,1)!=source.identity.slice(0,1)) source.draw(2); - else if(source.identity.indexOf('Zhu')==1) source.discard(source.getCards('h')); - } - else if(this.identity=='rNei'||this.identity=='bNei'){ - if(this.identity.slice(0,1)==source.identity.slice(0,1)) source.draw(3); + dieAfter2: function (source) { + if (_status.mode == "stratagem") return; + if (_status.mode == "purple") { + if (source) { + if (this.identity == "rZhu" || this.identity == "bZhu") { + if (this.identity.slice(0, 1) != source.identity.slice(0, 1)) + source.recover(); + } else if (this.identity == "rZhong" || this.identity == "bZhong") { + if (this.identity.slice(0, 1) != source.identity.slice(0, 1)) source.draw(2); + else if (source.identity.indexOf("Zhu") == 1) + source.discard(source.getCards("h")); + } else if (this.identity == "rNei" || this.identity == "bNei") { + if (this.identity.slice(0, 1) == source.identity.slice(0, 1)) source.draw(3); } } - if(!_status.yeconfirm){ - _status.yeconfirm=true; - game.addGlobalSkill('yexinbilu'); - game.broadcastAll(function(){ - if(game.me.identity=='rYe'||game.me.identity=='bYe'){ - var player=game.findPlayer(function(current){ - return current!=game.me&&(current.identity=='bYe'||current.identity=='rYe'); + if (!_status.yeconfirm) { + _status.yeconfirm = true; + game.addGlobalSkill("yexinbilu"); + game.broadcastAll(function () { + if (game.me.identity == "rYe" || game.me.identity == "bYe") { + var player = game.findPlayer(function (current) { + return ( + current != game.me && + (current.identity == "bYe" || current.identity == "rYe") + ); }); - if(player){ + if (player) { player.showIdentity(); } } }); } } - if(this.identity=='fan'&&source) source.draw(3); - else if(this.identity=='commoner'&&source) source.draw(2); - else if(this.identity=='mingzhong'&&source){ - if(source.identity=='zhu'){ - source.discard(source.getCards('he')); - } - else{ + if (this.identity == "fan" && source) source.draw(3); + else if (this.identity == "commoner" && source) source.draw(2); + else if (this.identity == "mingzhong" && source) { + if (source.identity == "zhu") { + source.discard(source.getCards("he")); + } else { source.draw(3); } - } - else if(this.identity=='zhong'&&source&&source.identity=='zhu'&&source.isZhu){ - source.discard(source.getCards('he')); + } else if ( + this.identity == "zhong" && + source && + source.identity == "zhu" && + source.isZhu + ) { + source.discard(source.getCards("he")); } }, - dieAfter:function(source){ - if(!this.identityShown){ - game.broadcastAll(function(player,identity,identity2){ - player.setIdentity(player.identity); - player.identityShown=true; - player.node.identity.classList.remove('guessing'); - if(identity){ - player.node.identity.firstChild.innerHTML=get.translation(identity+'_bg'); - game.log(player,'的身份是','#g'+get.translation(identity)); - } - else{ - game.log(player,'的身份是','#g'+get.translation(identity2+'2')); - } - },this,this.special_identity,this.identity); + dieAfter: function (source) { + if (!this.identityShown) { + game.broadcastAll( + function (player, identity, identity2) { + player.setIdentity(player.identity); + player.identityShown = true; + player.node.identity.classList.remove("guessing"); + if (identity) { + player.node.identity.firstChild.innerHTML = get.translation( + identity + "_bg" + ); + game.log(player, "的身份是", "#g" + get.translation(identity)); + } else { + game.log(player, "的身份是", "#g" + get.translation(identity2 + "2")); + } + }, + this, + this.special_identity, + this.identity + ); } - if(this.special_identity){ - game.broadcastAll(function(zhu,identity){ - zhu.removeSkill(identity); - },game.zhu,this.special_identity); + if (this.special_identity) { + game.broadcastAll( + function (zhu, identity) { + zhu.removeSkill(identity); + }, + game.zhu, + this.special_identity + ); } game.checkResult(); - if(_status.mode=='purple'){ - var red=[]; - var blue=[]; - game.countPlayer(function(current){ - var identity=current.identity.slice(1); - if(identity!='Zhu'){ - if(current.identity.indexOf('r')==0) red.push(current); + if (_status.mode == "purple") { + var red = []; + var blue = []; + game.countPlayer(function (current) { + var identity = current.identity.slice(1); + if (identity != "Zhu") { + if (current.identity.indexOf("r") == 0) red.push(current); else blue.push(current); } }); - if(red.length<=1&&blue.length<=1) game.broadcastAll(game.showIdentity); + if (red.length <= 1 && blue.length <= 1) game.broadcastAll(game.showIdentity); return; } - if(game.zhu&&game.zhu.isZhu){ - if((get.population('zhong')+get.population('nei')==0|| - get.population('zhong')+get.population('fan')==0)&&get.population('commoner')==0){ - game.broadcastAll(function(){ - if(game.showIdentity) game.showIdentity(); - if(game.zhu&&game.zhu.isAlive()&&get.population('nei')==1&&get.config('nei_fullscreenpop')) game.me.$fullscreenpop('主公 vs 内奸',null,null,false); + if (game.zhu && game.zhu.isZhu) { + if ( + (get.population("zhong") + get.population("nei") == 0 || + get.population("zhong") + get.population("fan") == 0) && + get.population("commoner") == 0 + ) { + game.broadcastAll(function () { + if (game.showIdentity) game.showIdentity(); + if ( + game.zhu && + game.zhu.isAlive() && + get.population("nei") == 1 && + get.config("nei_fullscreenpop") + ) + game.me.$fullscreenpop( + '主公 vs 内奸', + null, + null, + false + ); }); } } - if(game.zhu&&game.zhu.storage.enhance_zhu&&get.population('fan')<3){ + if (game.zhu && game.zhu.storage.enhance_zhu && get.population("fan") < 3) { game.zhu.removeSkill(game.zhu.storage.enhance_zhu); delete game.zhu.storage.enhance_zhu; } - if(this==game.zhong){ - game.broadcastAll(function(player){ - game.zhu=player; - game.zhu.identityShown=true; - game.zhu.ai.shown=1; + if (this == game.zhong) { + game.broadcastAll(function (player) { + game.zhu = player; + game.zhu.identityShown = true; + game.zhu.ai.shown = 1; game.zhu.setIdentity(); - game.zhu.isZhu=true; - var skills=player.getStockSkills(true,true).filter(skill=>{ - if(player.hasSkill(skill)) return false; - var info=get.info(skill); - return info&&info.zhuSkill; + game.zhu.isZhu = true; + var skills = player.getStockSkills(true, true).filter((skill) => { + if (player.hasSkill(skill)) return false; + var info = get.info(skill); + return info && info.zhuSkill; }); - if(skills.length){ + if (skills.length) { player.addSkills(skills); } - game.zhu.node.identity.classList.remove('guessing'); - if(lib.config.animation&&!lib.config.low_performance) game.zhu.$legend(); + game.zhu.node.identity.classList.remove("guessing"); + if (lib.config.animation && !lib.config.low_performance) game.zhu.$legend(); delete game.zhong; - if(_status.clickingidentity&&_status.clickingidentity[0]==game.zhu){ - for(var i=0;i<_status.clickingidentity[1].length;i++){ + if (_status.clickingidentity && _status.clickingidentity[0] == game.zhu) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform=''; + _status.clickingidentity[1][i].style.transform = ""; } delete _status.clickingidentity; } - },game.zhu); + }, game.zhu); game.delay(2); game.zhu.playerfocus(1000); } - if(!_status.over){ + if (!_status.over) { var giveup; - if(get.population('fan')+get.population('nei')==1){ - for(var i=0;i0){ - for(var i=0;i 0) { + for (var i = 0; i < targets.length; i++) { + shown = Math.abs(targets[i].ai.shown); + if (shown < 0.2 || targets[i].identity == "nei") c = 0; + else if (shown < 0.4) c = 0.5; + else if (shown < 0.6) c = 0.8; + else c = 1; + var eff = get.effect(targets[i], card, this); + effect += eff * c; + if ( + eff == 0 && + shown == 0 && + ["zhong", "rZhong", "bZhong"].includes(this.identity) && + targets[i] != this + ) { + effect += 0.1; } } } - if(effect>0){ - if(effect<1) c=0.5; - else c=1; - if(targets.length==1&&targets[0]==this); - else if(targets.length==1) this.ai.shown+=0.2*c; - else this.ai.shown+=0.1*c; - } - else if(effect<0&&this==game.me&&['nei','commoner','rYe','bYe'].includes(game.me.identity)){ - if(targets.length==1&&targets[0]==this); - else if(targets.length==1) this.ai.shown-=0.2; - else this.ai.shown-=0.1; + if (effect > 0) { + if (effect < 1) c = 0.5; + else c = 1; + if (targets.length == 1 && targets[0] == this); + else if (targets.length == 1) this.ai.shown += 0.2 * c; + else this.ai.shown += 0.1 * c; + } else if ( + effect < 0 && + this == game.me && + ["nei", "commoner", "rYe", "bYe"].includes(game.me.identity) + ) { + if (targets.length == 1 && targets[0] == this); + else if (targets.length == 1) this.ai.shown -= 0.2; + else this.ai.shown -= 0.1; } } - if(!stratagemMode&&this!=game.me) this.ai.shown*=2; - if(this.ai.shown>0.95) this.ai.shown=0.95; - if(this.ai.shown<-0.5) this.ai.shown=-0.5; - if(_status.mode=='purple') return; - if(stratagemMode) return; + if (!stratagemMode && this != game.me) this.ai.shown *= 2; + if (this.ai.shown > 0.95) this.ai.shown = 0.95; + if (this.ai.shown < -0.5) this.ai.shown = -0.5; + if (_status.mode == "purple") return; + if (stratagemMode) return; - var marknow=(!_status.connectMode&&this!=game.me&&get.config('auto_mark_identity')&&this.ai.identity_mark!='finished'); + var marknow = + !_status.connectMode && + this != game.me && + get.config("auto_mark_identity") && + this.ai.identity_mark != "finished"; // if(true){ - if(marknow&&_status.clickingidentity&&_status.clickingidentity[0]==this){ - for(var i=0;i<_status.clickingidentity[1].length;i++){ - _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform=''; - } - delete _status.clickingidentity; - } - if(!Array.isArray(targets)){ - targets=[]; - } - var effect=0,c,shown; - var zhu=game.zhu; - if(_status.mode=='zhong'&&!game.zhu.isZhu){ - zhu=game.zhong; - } - if(targets.length==1&&targets[0]==this){ - effect=0; - } - else if(this.identity!='nei'&&this.identity!='commoner'){ - if(this.ai.shown>0){ - if(this.identity=='fan'){ - effect=-1; - } - else{ - effect=1; - } - } - } - else if(targets.length>0){ - for(var i=0;i0){ - if(this.ai.identity_mark=='fan'){ - if(marknow) this.setIdentity(); - this.ai.identity_mark='finished'; - } - else{ - if(marknow) this.setIdentity('zhong'); - this.ai.identity_mark='zhong'; - } - } - else if(effect<0&&get.population('fan')>0){ - if(this.ai.identity_mark=='zhong'){ - if(marknow) this.setIdentity(); - this.ai.identity_mark='finished'; - } - else{ - if(marknow) this.setIdentity('fan'); - this.ai.identity_mark='fan'; - } - } - } - else if(marknow){ - if(effect>0&&this.identity!='fan'){ - this.setIdentity('zhong'); - this.ai.identity_mark='finished'; - } - else if(effect<0&&this.identity=='fan'){ - this.setIdentity('fan'); - this.ai.identity_mark='finished'; - } - } - // } - }, - showIdentity:function(){ - this.node.identity.classList.remove('guessing'); - this.identityShown=true; - this.ai.shown=1; - this.setIdentity(); - if(this.special_identity){ - this.node.identity.firstChild.innerHTML=get.translation(this.special_identity+'_bg'); - } - if(this.identity=='zhu'){ - this.isZhu=true; - } - else{ - delete this.isZhu; - } - if(_status.clickingidentity){ - for(var i=0;i<_status.clickingidentity[1].length;i++){ + if (marknow && _status.clickingidentity && _status.clickingidentity[0] == this) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform=''; + _status.clickingidentity[1][i].style.transform = ""; } delete _status.clickingidentity; } - } + if (!Array.isArray(targets)) { + targets = []; + } + var effect = 0, + c, + shown; + var zhu = game.zhu; + if (_status.mode == "zhong" && !game.zhu.isZhu) { + zhu = game.zhong; + } + if (targets.length == 1 && targets[0] == this) { + effect = 0; + } else if (this.identity != "nei" && this.identity != "commoner") { + if (this.ai.shown > 0) { + if (this.identity == "fan") { + effect = -1; + } else { + effect = 1; + } + } + } else if (targets.length > 0) { + for (var i = 0; i < targets.length; i++) { + shown = Math.abs(targets[i].ai.shown); + if (shown < 0.2 || targets[i].identity == "nei") c = 0; + else if (shown < 0.4) c = 0.5; + else if (shown < 0.6) c = 0.8; + else c = 1; + effect += get.effect(targets[i], card, this, zhu) * c; + } + } + if (this.identity == "nei" || this.identity == "commoner") { + if (effect > 0) { + if (this.ai.identity_mark == "fan") { + if (marknow) this.setIdentity(); + this.ai.identity_mark = "finished"; + } else { + if (marknow) this.setIdentity("zhong"); + this.ai.identity_mark = "zhong"; + } + } else if (effect < 0 && get.population("fan") > 0) { + if (this.ai.identity_mark == "zhong") { + if (marknow) this.setIdentity(); + this.ai.identity_mark = "finished"; + } else { + if (marknow) this.setIdentity("fan"); + this.ai.identity_mark = "fan"; + } + } + } else if (marknow) { + if (effect > 0 && this.identity != "fan") { + this.setIdentity("zhong"); + this.ai.identity_mark = "finished"; + } else if (effect < 0 && this.identity == "fan") { + this.setIdentity("fan"); + this.ai.identity_mark = "finished"; + } + } + // } + }, + showIdentity: function () { + this.node.identity.classList.remove("guessing"); + this.identityShown = true; + this.ai.shown = 1; + this.setIdentity(); + if (this.special_identity) { + this.node.identity.firstChild.innerHTML = get.translation( + this.special_identity + "_bg" + ); + } + if (this.identity == "zhu") { + this.isZhu = true; + } else { + delete this.isZhu; + } + if (_status.clickingidentity) { + for (var i = 0; i < _status.clickingidentity[1].length; i++) { + _status.clickingidentity[1][i].delete(); + _status.clickingidentity[1][i].style.transform = ""; + } + delete _status.clickingidentity; + } + }, }, - content:{ - stratagemInsight:event=>{ - 'step 0' - game.log(player,'洞察了',target,'与其的阵营关系'); - 'step 1' - var storage=player.storage; - if(!storage.zhibi) storage.zhibi=[]; - var zhibi=storage.zhibi; - if(!zhibi.includes(target)) zhibi.push(target); - var insightResult=event.insightResult=get.insightResult(player,target); - event.videoId=lib.status.videoId++; - var send=(clientTarget,clientInsightResult,id)=>{ - var classList=clientTarget.classList,nonStratagemInsightFlashing=classList.contains('flash-animation-iteration-count-infinite'); - if(nonStratagemInsightFlashing) clientTarget.nonStratagemInsightFlashing=true; - else classList.add('flash-animation-iteration-count-infinite'); - var identity=get.translation(`${clientInsightResult}2`); - clientTarget.prompt(identity,clientInsightResult); - var dialog=ui.create.dialog(`${get.translation(clientTarget)}是${identity}
                        `,'forcebutton'); - ui.create.spinningIdentityCard(clientInsightResult,dialog); - var control=ui.create.control('ok',()=>{ + content: { + stratagemInsight: (event) => { + "step 0"; + game.log(player, "洞察了", target, "与其的阵营关系"); + "step 1"; + var storage = player.storage; + if (!storage.zhibi) storage.zhibi = []; + var zhibi = storage.zhibi; + if (!zhibi.includes(target)) zhibi.push(target); + var insightResult = (event.insightResult = get.insightResult(player, target)); + event.videoId = lib.status.videoId++; + var send = (clientTarget, clientInsightResult, id) => { + var classList = clientTarget.classList, + nonStratagemInsightFlashing = classList.contains( + "flash-animation-iteration-count-infinite" + ); + if (nonStratagemInsightFlashing) clientTarget.nonStratagemInsightFlashing = true; + else classList.add("flash-animation-iteration-count-infinite"); + var identity = get.translation(`${clientInsightResult}2`); + clientTarget.prompt(identity, clientInsightResult); + var dialog = ui.create.dialog( + `${get.translation(clientTarget)}是${identity}
                        `, + "forcebutton" + ); + ui.create.spinningIdentityCard(clientInsightResult, dialog); + var control = ui.create.control("ok", () => { dialog.close(); control.close(); - _status.imchoosing=false; - _status.event._result={ - bool:true + _status.imchoosing = false; + _status.event._result = { + bool: true, }; game.resume(); }); - dialog.videoId=id; + dialog.videoId = id; game.pause(); game.countChoose(); }; - game.broadcastAll((clientPlayer,clientTarget,id)=>{ - if(clientPlayer!=game.me) ui.create.dialog(`${get.translation(clientPlayer)}正在洞察${get.translation(clientTarget)}的阵营...
                        `).videoId=id; - },player,target,event.videoId); - if(event.isMine()) send(target,insightResult,event.videoId); - else if(event.isOnline()){ - player.send(send,target,insightResult,event.videoId); + game.broadcastAll( + (clientPlayer, clientTarget, id) => { + if (clientPlayer != game.me) + ui.create.dialog( + `${get.translation(clientPlayer)}正在洞察${get.translation( + clientTarget + )}的阵营...
                        ` + ).videoId = id; + }, + player, + target, + event.videoId + ); + if (event.isMine()) send(target, insightResult, event.videoId); + else if (event.isOnline()) { + player.send(send, target, insightResult, event.videoId); player.wait(); game.pause(); } - 'step 2' - game.broadcastAll('closeDialog',event.videoId); - if(!_status.connectMode&&get.config('auto_mark_identity')&&!target.node.identity.firstChild.innerHTML.length) game.broadcastAll((clientPlayer,clientTarget,insightResult)=>{ - if(clientPlayer.isUnderControl(true)) clientTarget.setIdentity(insightResult); - },player,target,event.insightResult); - var afterInsight=clientTarget=>{ + "step 2"; + game.broadcastAll("closeDialog", event.videoId); + if ( + !_status.connectMode && + get.config("auto_mark_identity") && + !target.node.identity.firstChild.innerHTML.length + ) + game.broadcastAll( + (clientPlayer, clientTarget, insightResult) => { + if (clientPlayer.isUnderControl(true)) + clientTarget.setIdentity(insightResult); + }, + player, + target, + event.insightResult + ); + var afterInsight = (clientTarget) => { clientTarget.unprompt(); - if(clientTarget.nonStratagemInsightFlashing){ + if (clientTarget.nonStratagemInsightFlashing) { delete clientTarget.nonStratagemInsightFlashing; return; } - var classList=clientTarget.classList; - if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite'); + var classList = clientTarget.classList; + if (classList.contains("flash-animation-iteration-count-infinite")) + classList.remove("flash-animation-iteration-count-infinite"); }; - if(event.isMine()) afterInsight(target); - else if(event.isOnline()) player.send(afterInsight,target); + if (event.isMine()) afterInsight(target); + else if (event.isOnline()) player.send(afterInsight, target); }, - stratagemCamouflage:()=>{ - 'step 0' - var camouflaged=event.targets=game.players.filter(current=>current.identity=='fan'&&!current.ai.stratagemCamouflage).randomGets(Math.max(Math.round(get.population()/6),1)); - camouflaged.forEach(current=>current.ai.stratagemCamouflage=true); - var me=game.me; - if(event.players.includes(me)&&me.identity=='nei'){ - event.videoId=lib.status.videoId++; - var rebel=get.translation('fan2'),dialog=ui.create.dialog(`${get.translation(camouflaged)}是${rebel}
                        `,'forcebutton'); - ui.create.spinningIdentityCard('fan',dialog); - dialog.videoId=event.videoId; - camouflaged.forEach(victim=>{ - var classList=victim.classList,nonCamouflageFlashing=classList.contains('flash-animation-iteration-count-infinite'); - if(nonCamouflageFlashing) victim.nonCamouflageFlashing=true; - else classList.add('flash-animation-iteration-count-infinite'); - victim.prompt(rebel,'fan'); + stratagemCamouflage: () => { + "step 0"; + var camouflaged = (event.targets = game.players + .filter((current) => current.identity == "fan" && !current.ai.stratagemCamouflage) + .randomGets(Math.max(Math.round(get.population() / 6), 1))); + camouflaged.forEach((current) => (current.ai.stratagemCamouflage = true)); + var me = game.me; + if (event.players.includes(me) && me.identity == "nei") { + event.videoId = lib.status.videoId++; + var rebel = get.translation("fan2"), + dialog = ui.create.dialog( + `${get.translation(camouflaged)}是${rebel}
                        `, + "forcebutton" + ); + ui.create.spinningIdentityCard("fan", dialog); + dialog.videoId = event.videoId; + camouflaged.forEach((victim) => { + var classList = victim.classList, + nonCamouflageFlashing = classList.contains( + "flash-animation-iteration-count-infinite" + ); + if (nonCamouflageFlashing) victim.nonCamouflageFlashing = true; + else classList.add("flash-animation-iteration-count-infinite"); + victim.prompt(rebel, "fan"); }); - me.chooseControl('ok').set('dialog',dialog); + me.chooseControl("ok").set("dialog", dialog); } - game.filterPlayer(current=>{ - if(current.identity!='nei') return; - var storage=current.storage; - if(!storage.zhibi) storage.zhibi=[]; + game.filterPlayer((current) => { + if (current.identity != "nei") return; + var storage = current.storage; + if (!storage.zhibi) storage.zhibi = []; storage.zhibi.addArray(camouflaged); }); - 'step 1' - targets.forEach(current=>{ - if(game.me.identity=='nei'&&get.config('nei_auto_mark_camouflage')) current.setIdentity(); + "step 1"; + targets.forEach((current) => { + if (game.me.identity == "nei" && get.config("nei_auto_mark_camouflage")) + current.setIdentity(); current.unprompt(); - if(current.nonCamouflageFlashing){ + if (current.nonCamouflageFlashing) { delete current.nonCamouflageFlashing; return; } - var classList=current.classList; - if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite'); + var classList = current.classList; + if (classList.contains("flash-animation-iteration-count-infinite")) + classList.remove("flash-animation-iteration-count-infinite"); }); }, - stratagemCamouflageOL:()=>{ - 'step 0' - var send=(clientCamouflaged,id,online)=>{ - var me=game.me; - if(me.identity=='nei'){ - var storage=me.storage; - if(!storage.zhibi) storage.zhibi=[]; + stratagemCamouflageOL: () => { + "step 0"; + var send = (clientCamouflaged, id, online) => { + var me = game.me; + if (me.identity == "nei") { + var storage = me.storage; + if (!storage.zhibi) storage.zhibi = []; storage.zhibi.addArray(clientCamouflaged); - var rebel=get.translation('fan2'),dialog=ui.create.dialog(`${get.translation(clientCamouflaged)}是${rebel}
                        `,'forcebutton'); - ui.create.spinningIdentityCard('fan',dialog); - dialog.videoId=id; - clientCamouflaged.forEach(victim=>{ - var classList=victim.classList,nonCamouflageFlashing=classList.contains('flash-animation-iteration-count-infinite'); - if(nonCamouflageFlashing) victim.nonCamouflageFlashing=true; - else classList.add('flash-animation-iteration-count-infinite'); - victim.prompt(rebel,'fan'); + var rebel = get.translation("fan2"), + dialog = ui.create.dialog( + `${get.translation(clientCamouflaged)}是${rebel}
                        `, + "forcebutton" + ); + ui.create.spinningIdentityCard("fan", dialog); + dialog.videoId = id; + clientCamouflaged.forEach((victim) => { + var classList = victim.classList, + nonCamouflageFlashing = classList.contains( + "flash-animation-iteration-count-infinite" + ); + if (nonCamouflageFlashing) victim.nonCamouflageFlashing = true; + else classList.add("flash-animation-iteration-count-infinite"); + victim.prompt(rebel, "fan"); }); - me.chooseControl('ok').set('dialog',dialog); - } - else ui.create.dialog('请等待内奸身份确认...').videoId=id; - if(online) game.resume(); + me.chooseControl("ok").set("dialog", dialog); + } else ui.create.dialog("请等待内奸身份确认...").videoId = id; + if (online) game.resume(); }; - var camouflaged=event.targets=game.players.filter(current=>current.identity=='fan'&&!current.ai.stratagemCamouflage).randomGets(Math.max(Math.round(get.population()/6),1)); - camouflaged.forEach(current=>current.ai.stratagemCamouflage=true); - event.videoId=lib.status.videoId++; - var time=10000; - if(lib.configOL&&lib.configOL.choose_timeout) time=parseInt(lib.configOL.choose_timeout)*1000; - var aiTargets=event.aiTargets=[]; - event.players.forEach(current=>{ + var camouflaged = (event.targets = game.players + .filter((current) => current.identity == "fan" && !current.ai.stratagemCamouflage) + .randomGets(Math.max(Math.round(get.population() / 6), 1))); + camouflaged.forEach((current) => (current.ai.stratagemCamouflage = true)); + event.videoId = lib.status.videoId++; + var time = 10000; + if (lib.configOL && lib.configOL.choose_timeout) + time = parseInt(lib.configOL.choose_timeout) * 1000; + var aiTargets = (event.aiTargets = []); + event.players.forEach((current) => { current.showTimer(time); - if(current.isOnline()){ - current.send(send,camouflaged,event.videoId,true); + if (current.isOnline()) { + current.send(send, camouflaged, event.videoId, true); current.wait(); - if(current.identity=='nei') event.withOL=true; + if (current.identity == "nei") event.withOL = true; return; } - var me=game.me; - if(current==me){ - event.withMe=true; - send(camouflaged,event.videoId); - if(me.identity=='nei') me.wait(); - else event._result={ - bool:true - }; + var me = game.me; + if (current == me) { + event.withMe = true; + send(camouflaged, event.videoId); + if (me.identity == "nei") me.wait(); + else + event._result = { + bool: true, + }; return; } - if(current.identity=='nei') aiTargets.push(current); + if (current.identity == "nei") aiTargets.push(current); }); - if(!aiTargets.length) return; + if (!aiTargets.length) return; aiTargets.randomSort(); - new Promise(resolve=>setTimeout(resolve,Math.ceil(5000+5000*Math.random()))).then(()=>{ - var interval=setInterval(()=>{ + new Promise((resolve) => + setTimeout(resolve, Math.ceil(5000 + 5000 * Math.random())) + ).then(() => { + var interval = setInterval(() => { aiTargets.shift(); - if(aiTargets.length) return; + if (aiTargets.length) return; clearInterval(interval); - if(event.withAI) game.resume(); - },Math.ceil(500+500*Math.random())) + if (event.withAI) game.resume(); + }, Math.ceil(500 + 500 * Math.random())); }); - 'step 1' - if(event.withMe) game.me.unwait(result); - 'step 2' - if(event.withOL&&!event.resultOL) game.pause(); - 'step 3' - if(!event.aiTargets.length) return; - event.withAI=true; + "step 1"; + if (event.withMe) game.me.unwait(result); + "step 2"; + if (event.withOL && !event.resultOL) game.pause(); + "step 3"; + if (!event.aiTargets.length) return; + event.withAI = true; game.pause(); - 'step 4' - game.broadcastAll('closeDialog',event.videoId); - event.players.forEach(current=>current.hideTimer()); - var afterCamouflage=clientCamouflaged=>clientCamouflaged.forEach(victim=>{ - victim.unprompt(); - if(victim.nonCamouflageFlashing){ - delete victim.nonCamouflageFlashing; + "step 4"; + game.broadcastAll("closeDialog", event.videoId); + event.players.forEach((current) => current.hideTimer()); + var afterCamouflage = (clientCamouflaged) => + clientCamouflaged.forEach((victim) => { + victim.unprompt(); + if (victim.nonCamouflageFlashing) { + delete victim.nonCamouflageFlashing; + return; + } + var classList = victim.classList; + if (classList.contains("flash-animation-iteration-count-infinite")) + classList.remove("flash-animation-iteration-count-infinite"); + }); + event.players.forEach((current) => { + if (current.isOnline()) { + current.send(afterCamouflage, targets); return; } - var classList=victim.classList; - if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite'); + var me = game.me; + if (current == me && me.identity == "nei") afterCamouflage(targets); }); - event.players.forEach(current=>{ - if(current.isOnline()){ - current.send(afterCamouflage,targets); - return; - } - var me=game.me; - if(current==me&&me.identity=='nei') afterCamouflage(targets); - }); - } - } + }, + }, }, - get:{ - rawAttitude:function(from,to){ - var x=0,num=0,temp,i; - if(_status.ai.customAttitude){ - for(i=0;i<_status.ai.customAttitude.length;i++){ - temp=_status.ai.customAttitude[i](from,to); - if(temp!=undefined){ - x+=temp; + get: { + rawAttitude: function (from, to) { + var x = 0, + num = 0, + temp, + i; + if (_status.ai.customAttitude) { + for (i = 0; i < _status.ai.customAttitude.length; i++) { + temp = _status.ai.customAttitude[i](from, to); + if (temp != undefined) { + x += temp; num++; } } } - if(num){ - return x/num; + if (num) { + return x / num; } - if(_status.mode=='purple'){ - var real=get.realAttitude(from,to); - if(from==to||to.identityShown||from.storage.zhibi&&from.storage.zhibi.includes(to)||(_status.yeconfirm&&['rYe','bYe'].includes(to.identity)&&['rYe','bYe'].includes(to.identity))) return real*1.1; - return ((to.ai.shown+0.1)*real+(from.identity.slice(0,1)==to.identity.slice(0,1)?3:-3)*(1-to.ai.shown)) - } - else if(_status.mode=='stratagem'){ - var x=0,num=0,temp,i; - if(_status.ai.customAttitude){ - for(i=0;i<_status.ai.customAttitude.length;i++){ - temp=_status.ai.customAttitude[i](from,to); - if(temp!=undefined){ - x+=temp; + if (_status.mode == "purple") { + var real = get.realAttitude(from, to); + if ( + from == to || + to.identityShown || + (from.storage.zhibi && from.storage.zhibi.includes(to)) || + (_status.yeconfirm && + ["rYe", "bYe"].includes(to.identity) && + ["rYe", "bYe"].includes(to.identity)) + ) + return real * 1.1; + return ( + (to.ai.shown + 0.1) * real + + (from.identity.slice(0, 1) == to.identity.slice(0, 1) ? 3 : -3) * (1 - to.ai.shown) + ); + } else if (_status.mode == "stratagem") { + var x = 0, + num = 0, + temp, + i; + if (_status.ai.customAttitude) { + for (i = 0; i < _status.ai.customAttitude.length; i++) { + temp = _status.ai.customAttitude[i](from, to); + if (temp != undefined) { + x += temp; num++; } } } - if(num){ - return x/num; + if (num) { + return x / num; } - var real=get.realAttitude(from,to),zhibi=from.storage.zhibi,stratagem_expose=from.storage.stratagem_expose,followCamouflage=true; - if(to.ai.shown) return to.ai.shown*(real+(from.identity==to.identity||from.identity=='zhu'&&to.identity=='zhong'||from.identity=='zhong'&&to.identity=='zhu'||from.identity=='nei'&&to.identity=='zhu'&&get.situation()<=1||(to.identity=='nei'&&get.situation()<=0&&['zhu','zhong'].includes(from.identity)||get.situation()>=3&&from.identity=='fan')?2.9:-2.9)) - if(from==to||to.identityShown||((stratagem_expose&&stratagem_expose.includes(to))||(zhibi&&zhibi.includes(to)))&&!to.ai.stratagemCamouflage) return real*1.1; - if(from.identity=='nei'&&to.ai.stratagemCamouflage) return real*1.1; - if(to.identity=='nei'){ - if(from.identity=='fan'){ - if(get.population('zhong')==0){ - if(zhibi){ - var dead=game.dead.slice(); - for(var current of dead){ - if(from.storage.zhibi.includes(current)&¤t.ai.stratagemCamouflage){ - if(from.storage.stratagem_expose&&from.storage.stratagem_expose.includes(to)) return -7; + var real = get.realAttitude(from, to), + zhibi = from.storage.zhibi, + stratagem_expose = from.storage.stratagem_expose, + followCamouflage = true; + if (to.ai.shown) + return ( + to.ai.shown * + (real + + (from.identity == to.identity || + (from.identity == "zhu" && to.identity == "zhong") || + (from.identity == "zhong" && to.identity == "zhu") || + (from.identity == "nei" && to.identity == "zhu" && get.situation() <= 1) || + (to.identity == "nei" && + get.situation() <= 0 && + ["zhu", "zhong"].includes(from.identity)) || + (get.situation() >= 3 && from.identity == "fan") + ? 2.9 + : -2.9)) + ); + if ( + from == to || + to.identityShown || + (((stratagem_expose && stratagem_expose.includes(to)) || + (zhibi && zhibi.includes(to))) && + !to.ai.stratagemCamouflage) + ) + return real * 1.1; + if (from.identity == "nei" && to.ai.stratagemCamouflage) return real * 1.1; + if (to.identity == "nei") { + if (from.identity == "fan") { + if (get.population("zhong") == 0) { + if (zhibi) { + var dead = game.dead.slice(); + for (var current of dead) { + if ( + from.storage.zhibi.includes(current) && + current.ai.stratagemCamouflage + ) { + if ( + from.storage.stratagem_expose && + from.storage.stratagem_expose.includes(to) + ) + return -7; } } - if(zhibi.includes(to)) return 3; + if (zhibi.includes(to)) return 3; } } } } - if(to.identity=='fan'&&from.identity=='nei'&&zhibi.includes(game.zhu)&&game.players.filter(i=>i!=from&&!zhibi.includes(i)).map(i=>i.identity).reduce((p,c)=>(!p.includes(c)?(p.push(c)&&p):p),[]).length==1) return real; - for(var fan of game.dead){ - if(fan.identity!='fan'||!fan.storage.stratagem_revitalization) continue; - for(var current of fan.storage.stratagem_expose){ - if(to==current){ + if ( + to.identity == "fan" && + from.identity == "nei" && + zhibi.includes(game.zhu) && + game.players + .filter((i) => i != from && !zhibi.includes(i)) + .map((i) => i.identity) + .reduce((p, c) => (!p.includes(c) ? p.push(c) && p : p), []).length == 1 + ) + return real; + for (var fan of game.dead) { + if (fan.identity != "fan" || !fan.storage.stratagem_revitalization) continue; + for (var current of fan.storage.stratagem_expose) { + if (to == current) { return real; } } } - if(from.identity=='fan'&&to.identity=='fan'){ - if(from.ai.stratagemCamouflage){ - var zhu=game.zhu&&game.zhu.isZhu&&game.zhu.identityShown?game.zhu:undefined; - if(zhu){ - if(zhu.storage.stratagem_expose&&zhu.storage.stratagem_expose.includes(to)) return 0; + if (from.identity == "fan" && to.identity == "fan") { + if (from.ai.stratagemCamouflage) { + var zhu = + game.zhu && game.zhu.isZhu && game.zhu.identityShown ? game.zhu : undefined; + if (zhu) { + if (zhu.storage.stratagem_expose && zhu.storage.stratagem_expose.includes(to)) + return 0; } - if(zhibi&&zhibi.includes(to)) return -7; + if (zhibi && zhibi.includes(to)) return -7; } - if(to.ai.stratagemCamouflage){ - var zhu=game.zhu&&game.zhu.isZhu&&game.zhu.identityShown?game.zhu:undefined; - if(zhu){ - if(zhu.storage.stratagem_expose&&zhu.storage.stratagem_expose.includes(to)) return 0; + if (to.ai.stratagemCamouflage) { + var zhu = + game.zhu && game.zhu.isZhu && game.zhu.identityShown ? game.zhu : undefined; + if (zhu) { + if (zhu.storage.stratagem_expose && zhu.storage.stratagem_expose.includes(to)) + return 0; } - if(zhibi&&zhibi.includes(to)) return -7; + if (zhibi && zhibi.includes(to)) return -7; } } - if(from.identity!='nei'&&zhibi&&zhibi.includes(to)&&!to.identityShown&&(followCamouflage&&to.ai.stratagemCamouflage)) return -5; - if(from.identity!='nei'&&stratagem_expose&&stratagem_expose.includes(to)&&!to.identityShown) return -5; - if(zhibi){ - for(var to2 of zhibi){ - if(to2.storage.stratagem_expose){ - if(to2.ai.stratagemCamouflage){ - for(var to3 of to2.storage.stratagem_expose){ - if(zhibi.slice().addArray(stratagem_expose).includes(to3)){ - if(to==to2){ + if ( + from.identity != "nei" && + zhibi && + zhibi.includes(to) && + !to.identityShown && + followCamouflage && + to.ai.stratagemCamouflage + ) + return -5; + if ( + from.identity != "nei" && + stratagem_expose && + stratagem_expose.includes(to) && + !to.identityShown + ) + return -5; + if (zhibi) { + for (var to2 of zhibi) { + if (to2.storage.stratagem_expose) { + if (to2.ai.stratagemCamouflage) { + for (var to3 of to2.storage.stratagem_expose) { + if (zhibi.slice().addArray(stratagem_expose).includes(to3)) { + if (to == to2) { return real; } - } else if(to==to3){ - return Math.abs(real+10)/10; + } else if (to == to3) { + return Math.abs(real + 10) / 10; } } - }else{ - for(var to3 of to2.storage.stratagem_expose){ - if(!zhibi.slice().addArray(stratagem_expose).includes(to3)&&to==to3){ - return get.rawAttitude(to3,to)*Math.sign(real); + } else { + for (var to3 of to2.storage.stratagem_expose) { + if ( + !zhibi.slice().addArray(stratagem_expose).includes(to3) && + to == to3 + ) { + return get.rawAttitude(to3, to) * Math.sign(real); } } } } } } - return Math.max(-1,Math.min(-0.1,(-Math.min(5,to.countCards('hes')/2+1)/5-Math.max(0,5-to.hp)/4)/2)); + return Math.max( + -1, + Math.min( + -0.1, + (-Math.min(5, to.countCards("hes") / 2 + 1) / 5 - Math.max(0, 5 - to.hp) / 4) / 2 + ) + ); } //正常身份模式态度 - var difficulty=0; - if(to==game.me) difficulty=2-get.difficulty(); - if(from==to||to.identityShown||(from.storage.dongcha==to)||to.identityShown||from.storage.zhibi&&from.storage.zhibi.includes(to)){ - return get.realAttitude(from,to)+difficulty*1.5; - } - else{ - if(from.identity=='zhong'&&to.ai.shown==0&&from.ai.tempIgnore&& - !from.ai.tempIgnore.includes(to)){ - for(var i=0;i1&&to.hp>fan.hp&&to.countCards('he')>fan.countCards('he')){ + if (fan) { + if ( + to.hp > 1 && + to.hp > fan.hp && + to.countCards("he") > fan.countCards("he") + ) { return -3; } } return 0; } - if(situation>1) return Math.max((situation-8)/3,-2); - return Math.min(3,get.population('fan')); - case 'fan': - if(get.population('fan')==1&&get.population('nei')==1&&game.players.length==3){ + if (situation > 1) return Math.max((situation - 8) / 3, -2); + return Math.min(3, get.population("fan")); + case "fan": + if ( + get.population("fan") == 1 && + get.population("nei") == 1 && + game.players.length == 3 + ) { var nei; - for(var i=0;i1&&nei.hp>to.hp&&nei.countCards('he')>to.countCards('he')){ + if (nei) { + if ( + nei.hp > 1 && + nei.hp > to.hp && + nei.countCards("he") > to.countCards("he") + ) { return 0; } } @@ -3382,831 +3976,967 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ return -4; } break; - case 'zhong': - switch (identity2){ - case 'zhu':return 10; - case 'zhong': - if(from==to) return 5; - if(get.population('zhong')>1) return 3; + case "zhong": + switch (identity2) { + case "zhu": + return 10; + case "zhong": + if (from == to) return 5; + if (get.population("zhong") > 1) return 3; return 4; - case 'nei': - if(get.population('fan')==0&&get.population('zhong')==1) return -2; - if(get.population('zhong')>=1) return Math.min(3,-situation); + case "nei": + if (get.population("fan") == 0 && get.population("zhong") == 1) return -2; + if (get.population("zhong") >= 1) return Math.min(3, -situation); return 3; - case 'fan':return -8; + case "fan": + return -8; } break; - case 'nei': - if(identity2=='zhu'&&game.players.length==2) return -10; - if(from!=to&&identity2!='zhu'&&game.players.length==3) return -8; - var strategy=get.aiStrategy(); - if(strategy==4){ - if(from==to) return 10; + case "nei": + if (identity2 == "zhu" && game.players.length == 2) return -10; + if (from != to && identity2 != "zhu" && game.players.length == 3) return -8; + var strategy = get.aiStrategy(); + if (strategy == 4) { + if (from == to) return 10; return 0; } var num; - switch (identity2){ - case 'zhu': - if(strategy==6) return -1; - if(strategy==5) return 10; - if(to.hp<=0) return 10; - if(get.population('fan')==1){ + switch (identity2) { + case "zhu": + if (strategy == 6) return -1; + if (strategy == 5) return 10; + if (to.hp <= 0) return 10; + if (get.population("fan") == 1) { var fan; - for(var i=0;i1&&to.hp>fan.hp&&to.countCards('he')>fan.countCards('he')){ + if (fan) { + if ( + to.hp > 1 && + to.hp > fan.hp && + to.countCards("he") > fan.countCards("he") + ) { return -3; } } return 0; + } else { + if (situation > 1 || get.population("fan") == 0) num = 0; + else num = get.population("fan") + Math.max(0, 3 - game.zhu.hp); } - else{ - if(situation>1||get.population('fan')==0) num=0; - else num=get.population('fan')+Math.max(0,3-game.zhu.hp); - } - if(strategy==2) num--; - if(strategy==3) num++; + if (strategy == 2) num--; + if (strategy == 3) num++; return num; - case 'zhong': - if(strategy==5) return Math.min(0,-situation); - if(strategy==6) return Math.max(-1,-situation); - if(get.population('fan')==0) num=-5; - else if(situation<=0) num=0; - else if(game.zhu&&game.zhu.hp<2) num=0; - else if(game.zhu&&game.zhu.hp==2) num=-1; - else if(game.zhu&&game.zhu.hp<=2&&situation>1) num=-1; - else num=-2; - if(strategy==2) num--; - if(strategy==3) num++; + case "zhong": + if (strategy == 5) return Math.min(0, -situation); + if (strategy == 6) return Math.max(-1, -situation); + if (get.population("fan") == 0) num = -5; + else if (situation <= 0) num = 0; + else if (game.zhu && game.zhu.hp < 2) num = 0; + else if (game.zhu && game.zhu.hp == 2) num = -1; + else if (game.zhu && game.zhu.hp <= 2 && situation > 1) num = -1; + else num = -2; + if (strategy == 2) num--; + if (strategy == 3) num++; return num; - case 'nei': - if(from==to) return 10; - if(from.ai.friend.includes(to)) return 5; - if(get.population('fan')+get.population('zhong')>0) return 0; + case "nei": + if (from == to) return 10; + if (from.ai.friend.includes(to)) return 5; + if (get.population("fan") + get.population("zhong") > 0) return 0; return -5; - case 'fan': - if(strategy==5) return Math.max(-1,situation); - if(strategy==6) return Math.min(0,situation); - if((game.zhu&&game.zhu.hp<=2&&situation<0)||situation<-1) num=-3; - else if(situation<0||get.population('zhong')==0) num=-2; - else if((game.zhu&&game.zhu.hp>=4&&situation>0)||situation>1) num=1; - else num=0; - if(strategy==2) num++; - if(strategy==3) num--; + case "fan": + if (strategy == 5) return Math.max(-1, situation); + if (strategy == 6) return Math.min(0, situation); + if ((game.zhu && game.zhu.hp <= 2 && situation < 0) || situation < -1) + num = -3; + else if (situation < 0 || get.population("zhong") == 0) num = -2; + else if ((game.zhu && game.zhu.hp >= 4 && situation > 0) || situation > 1) + num = 1; + else num = 0; + if (strategy == 2) num++; + if (strategy == 3) num--; return num; } break; - case 'fan': - switch (identity2){ - case 'zhu': - if(get.population('nei')>0){ - if(situation==1) return -6; - if(situation>1) return -5; + case "fan": + switch (identity2) { + case "zhu": + if (get.population("nei") > 0) { + if (situation == 1) return -6; + if (situation > 1) return -5; } return -8; - case 'zhong': - if(game.zhu.hp>=3&&to.hp==1){ + case "zhong": + if (game.zhu.hp >= 3 && to.hp == 1) { return -10; } return -7; - case 'nei': - if(get.population('fan')==1) return 0; - if(get.population('zhong')==0) return -2; - if(game.zhu&&game.zhu.hp<=2&&game.zhu.identityShown) return -1; + case "nei": + if (get.population("fan") == 1) return 0; + if (get.population("zhong") == 0) return -2; + if (game.zhu && game.zhu.hp <= 2 && game.zhu.identityShown) return -1; return 3; - case 'fan': + case "fan": return 5; } } } //正常身份模式态度 - if(!game.zhu){ - if(from.identity=='nei'||to.identity=='nei'||from.identity=='commoner'||to.identity=='commoner') return -1; - if(from.identity==to.identity) return 6; + if (!game.zhu) { + if ( + from.identity == "nei" || + to.identity == "nei" || + from.identity == "commoner" || + to.identity == "commoner" + ) + return -1; + if (from.identity == to.identity) return 6; return -6; } - var situation=get.situation(); - var identity=from.identity; - var identity2=to.identity; - if(identity2=='zhu'&&!to.isZhu){ - identity2='zhong'; - if(from==to) return 10; + var situation = get.situation(); + var identity = from.identity; + var identity2 = to.identity; + if (identity2 == "zhu" && !to.isZhu) { + identity2 = "zhong"; + if (from == to) return 10; } - if(from!=to&&to.identity=='nei'&&to.ai.shown<1&&(to.ai.identity_mark=='fan'||to.ai.identity_mark=='zhong')){ - identity2=to.ai.identity_mark; + if ( + from != to && + to.identity == "nei" && + to.ai.shown < 1 && + (to.ai.identity_mark == "fan" || to.ai.identity_mark == "zhong") + ) { + identity2 = to.ai.identity_mark; } - if(from.identity!='nei'&&from.identity!='commoner'&&from!=to&&get.population('fan')==0&&identity2=='zhong'){ - for(var i=0;i1&&to.hp>fan.hp&&to.countCards('he')>fan.countCards('he')){ + if (fan) { + if ( + to.hp > 1 && + to.hp > fan.hp && + to.countCards("he") > fan.countCards("he") + ) { return -3; } } return 0; } - if(situation>1) return 0; - return Math.min(3,get.population('fan')); - case 'fan': - if(get.population('fan')==1&&get.population('nei')==1&&game.players.length==3){ + if (situation > 1) return 0; + return Math.min(3, get.population("fan")); + case "fan": + if ( + get.population("fan") == 1 && + get.population("nei") == 1 && + game.players.length == 3 + ) { var nei; - for(var i=0;i1&&nei.hp>to.hp&&nei.countCards('he')>to.countCards('he')){ + if (nei) { + if ( + nei.hp > 1 && + nei.hp > to.hp && + nei.countCards("he") > to.countCards("he") + ) { return 0; } } return -3; } return -4; - case 'commoner': - if(to.identity=='zhong') return 0; - if(get.population('fan')==0){ - if(to.ai.identity_mark=='zhong'&&to.ai.shown<1) return 0; + case "commoner": + if (to.identity == "zhong") return 0; + if (get.population("fan") == 0) { + if (to.ai.identity_mark == "zhong" && to.ai.shown < 1) return 0; return -0.5; } - if(zhongmode&&to.ai.sizhong&&to.ai.shown<1) return 6; - if(game.players.length==3){ + if (zhongmode && to.ai.sizhong && to.ai.shown < 1) return 6; + if (game.players.length == 3) { var fan; - for(var i=0; i1&&to.hp>fan.hp&&to.countCards('he')>fan.countCards('he')){ + if (fan) { + if ( + to.hp > 1 && + to.hp > fan.hp && + to.countCards("he") > fan.countCards("he") + ) { return -3; } } return 3; } - if(situation<0&&game.zhu&&game.zhu.hp<=2) return -3.8; - return Math.max(-4,2-get.population('fan')); + if (situation < 0 && game.zhu && game.zhu.hp <= 2) return -3.8; + return Math.max(-4, 2 - get.population("fan")); } break; - case 'zhong':case 'mingzhong': - switch(identity2){ - case 'zhu': return 10; - case 'zhong':case 'mingzhong': return 4; - case 'nei': - if(get.population('fan')==0) return -2; - if(zhongmode&&to.ai.sizhong&&to.ai.shown<1) return 6; - return Math.min(3,-situation); - case 'fan': return -8; - case 'commoner': - return Math.min(3,Math.max(-3,situation-0.2)); + case "zhong": + case "mingzhong": + switch (identity2) { + case "zhu": + return 10; + case "zhong": + case "mingzhong": + return 4; + case "nei": + if (get.population("fan") == 0) return -2; + if (zhongmode && to.ai.sizhong && to.ai.shown < 1) return 6; + return Math.min(3, -situation); + case "fan": + return -8; + case "commoner": + return Math.min(3, Math.max(-3, situation - 0.2)); } break; - case 'nei': - if(identity2=='zhu'&&game.players.length==2) return -10; - if(from!=to&&identity2!='zhu'&&identity2!='commoner'&&game.players.length==3) return -8; - var strategy=get.aiStrategy(); - if(strategy==4){ - if(from==to) return 10; + case "nei": + if (identity2 == "zhu" && game.players.length == 2) return -10; + if ( + from != to && + identity2 != "zhu" && + identity2 != "commoner" && + game.players.length == 3 + ) + return -8; + var strategy = get.aiStrategy(); + if (strategy == 4) { + if (from == to) return 10; return 0; } var num; - switch(identity2){ - case 'zhu': - if(strategy==6) return -1; - if(strategy==5) return 10; - if(to.hp<=0) return 10; - if(get.population('fan')==1){ + switch (identity2) { + case "zhu": + if (strategy == 6) return -1; + if (strategy == 5) return 10; + if (to.hp <= 0) return 10; + if (get.population("fan") == 1) { var fan; - for(var i=0;i1&&to.hp>fan.hp&&to.countCards('he')>fan.countCards('he')){ + if (fan) { + if ( + to.hp > 1 && + to.hp > fan.hp && + to.countCards("he") > fan.countCards("he") + ) { return -1.7; } } return 0; + } else { + if (situation > 1 || get.population("fan") == 0) num = 0; + else num = get.population("fan") + Math.max(0, 3 - game.zhu.hp); } - else{ - if(situation>1||get.population('fan')==0) num=0; - else num=get.population('fan')+Math.max(0,3-game.zhu.hp); - } - if(strategy==2) num--; - if(strategy==3) num++; + if (strategy == 2) num--; + if (strategy == 3) num++; return num; - case 'zhong': - if(strategy==5) return Math.min(0,-situation); - if(strategy==6) return Math.max(-1,-situation); - if(get.population('fan')==0) num=-5; - else if(situation<=0) num=0; - else if(game.zhu&&game.zhu.hp<2) num=0; - else if(game.zhu&&game.zhu.hp==2) num=-1; - else if(game.zhu&&game.zhu.hp<=2&&situation>1) num=-1; - else num=-2; - if(zhongmode&&situation<2){ - num=4; + case "zhong": + if (strategy == 5) return Math.min(0, -situation); + if (strategy == 6) return Math.max(-1, -situation); + if (get.population("fan") == 0) num = -5; + else if (situation <= 0) num = 0; + else if (game.zhu && game.zhu.hp < 2) num = 0; + else if (game.zhu && game.zhu.hp == 2) num = -1; + else if (game.zhu && game.zhu.hp <= 2 && situation > 1) num = -1; + else num = -2; + if (zhongmode && situation < 2) { + num = 4; } - if(strategy==2) num--; - if(strategy==3) num++; + if (strategy == 2) num--; + if (strategy == 3) num++; return num; - case 'mingzhong': - if(zhongmode){ - if(from.ai.sizhong==undefined){ - from.ai.sizhong=(Math.random()<0.5); + case "mingzhong": + if (zhongmode) { + if (from.ai.sizhong == undefined) { + from.ai.sizhong = Math.random() < 0.5; } - if(from.ai.sizhong) return 6; + if (from.ai.sizhong) return 6; } - if(strategy==5) return Math.min(0,-situation); - if(strategy==6) return Math.max(-1,-situation); - if(get.population('fan')==0) num=-5; - else if(situation<=0) num=0; - else num=-3; - if(strategy==2) num--; - if(strategy==3) num++; + if (strategy == 5) return Math.min(0, -situation); + if (strategy == 6) return Math.max(-1, -situation); + if (get.population("fan") == 0) num = -5; + else if (situation <= 0) num = 0; + else num = -3; + if (strategy == 2) num--; + if (strategy == 3) num++; return num; - case 'nei': - if(from==to) return 10; - if(from.ai.friend.includes(to)) return 5; - if(get.population('fan')+get.population('zhong')>0) return 0; + case "nei": + if (from == to) return 10; + if (from.ai.friend.includes(to)) return 5; + if (get.population("fan") + get.population("zhong") > 0) return 0; return -5; - case 'fan': - if(strategy==5) return Math.max(-1,situation); - if(strategy==6) return Math.min(0,situation); - if((game.zhu&&game.zhu.hp<=2&&situation<0)||situation<-1) num=-3; - else if(situation<0||get.population('zhong')+get.population('mingzhong')==0) num=-2; - else if((game.zhu&&game.zhu.hp>=4&&situation>0)||situation>1) num=1; - else num=0; - if(strategy==2) num++; - if(strategy==3) num--; + case "fan": + if (strategy == 5) return Math.max(-1, situation); + if (strategy == 6) return Math.min(0, situation); + if ((game.zhu && game.zhu.hp <= 2 && situation < 0) || situation < -1) + num = -3; + else if ( + situation < 0 || + get.population("zhong") + get.population("mingzhong") == 0 + ) + num = -2; + else if ((game.zhu && game.zhu.hp >= 4 && situation > 0) || situation > 1) + num = 1; + else num = 0; + if (strategy == 2) num++; + if (strategy == 3) num--; return num; - case 'commoner': - if(game.players.length<=4) return 5; - return Math.min(Math.max(-situation,-2),2); + case "commoner": + if (game.players.length <= 4) return 5; + return Math.min(Math.max(-situation, -2), 2); } break; - case 'fan': - switch(identity2){ - case 'zhu': - if(get.population('nei')>0){ - if(situation==1) return -6; - if(situation>1) return -5; + case "fan": + switch (identity2) { + case "zhu": + if (get.population("nei") > 0) { + if (situation == 1) return -6; + if (situation > 1) return -5; } return -8; - case 'zhong': - if(!zhongmode&&game.zhu.hp>=3&&to.hp==1){ + case "zhong": + if (!zhongmode && game.zhu.hp >= 3 && to.hp == 1) { return -10; } return -7; - case 'mingzhong':return -5; - case 'nei': - if(zhongmode&&to.ai.sizhong) return -7; - if(get.population('fan')==1) return 0; - if(get.population('zhong')+get.population('mingzhong')==0) return -7; - if(game.zhu&&game.zhu.hp<=2) return -1; - return Math.min(3,situation); - case 'fan': return 5; - case 'commoner': - return 2*get.population('fan')-3; + case "mingzhong": + return -5; + case "nei": + if (zhongmode && to.ai.sizhong) return -7; + if (get.population("fan") == 1) return 0; + if (get.population("zhong") + get.population("mingzhong") == 0) return -7; + if (game.zhu && game.zhu.hp <= 2) return -1; + return Math.min(3, situation); + case "fan": + return 5; + case "commoner": + return 2 * get.population("fan") - 3; } break; - case 'commoner': - switch(identity2){ - case 'zhu': - if(situation>0) return 2*Math.min(4,(to.hp+to.countCards('h')/4-2)); - if(situation>=-3&&game.zhu) return (to.hp-2)+to.countCards('h')/4; //return Math.min(-0.1,5-game.zhu.hp); - return to.hp+to.countCards('h')/3-4; - case 'zhong': - if(situation>0){ - if(to.hp>=2) return Math.min(3,Math.max(1,to.hp+to.countCards('h')/4-4)); + case "commoner": + switch (identity2) { + case "zhu": + if (situation > 0) return 2 * Math.min(4, to.hp + to.countCards("h") / 4 - 2); + if (situation >= -3 && game.zhu) return to.hp - 2 + to.countCards("h") / 4; //return Math.min(-0.1,5-game.zhu.hp); + return to.hp + to.countCards("h") / 3 - 4; + case "zhong": + if (situation > 0) { + if (to.hp >= 2) + return Math.min(3, Math.max(1, to.hp + to.countCards("h") / 4 - 4)); else return 0; } return -2; - case 'nei': - if(game.players.length==3&&get.population('nei')==1) return Math.min(3.5,(to.hp-1.5)+to.countCards('h')/3)-(to.hp<(game.zhu?game.zhu.hp:0)?4:0); - if(game.players.length<=4&&get.population('nei')==1) return Math.min(5,(to.hp-1.5)+to.countCards('h')/3); - if(situation>0) return -3; + case "nei": + if (game.players.length == 3 && get.population("nei") == 1) + return ( + Math.min(3.5, to.hp - 1.5 + to.countCards("h") / 3) - + (to.hp < (game.zhu ? game.zhu.hp : 0) ? 4 : 0) + ); + if (game.players.length <= 4 && get.population("nei") == 1) + return Math.min(5, to.hp - 1.5 + to.countCards("h") / 3); + if (situation > 0) return -3; return 0; - case 'fan': - if(situation<0) return to.hp+to.countCards('h')/4-1.7*get.population('fan')+2; - else if(situation==0) return 0; - return 0.55*get.population('fan')-2.1; - case 'commoner': - return from==to?10:(to.hp<=2?-2:0); + case "fan": + if (situation < 0) + return to.hp + to.countCards("h") / 4 - 1.7 * get.population("fan") + 2; + else if (situation == 0) return 0; + return 0.55 * get.population("fan") - 2.1; + case "commoner": + return from == to ? 10 : to.hp <= 2 ? -2 : 0; } break; } }, - situation:function(absolute){ - var i,j,player; - var zhuzhong=0,total=0,zhu,fan=0; - for(i=0;i4){ - php=4; + situation: function (absolute) { + var i, j, player; + var zhuzhong = 0, + total = 0, + zhu, + fan = 0; + for (i = 0; i < game.players.length; i++) { + player = game.players[i]; + var php = player.hp; + if (player.hasSkill("benghuai") && php > 4) { + php = 4; + } else if (php > 6) { + php = 6; } - else if(php>6){ - php=6; - } - j=player.countCards('h')+player.countCards('e')*1.5+php*2; - if(player.identity=='zhu'){ - zhuzhong+=j*1.2+5; - total+=j*1.2+5; - zhu=j; - } - else if(player.identity=='zhong'||player.identity=='mingzhong'){ - zhuzhong+=j*0.8+3; - total+=j*0.8+3; - } - else if(player.identity=='fan'){ - zhuzhong-=j+4; - total+=j+4; - fan+=j+4; + j = player.countCards("h") + player.countCards("e") * 1.5 + php * 2; + if (player.identity == "zhu") { + zhuzhong += j * 1.2 + 5; + total += j * 1.2 + 5; + zhu = j; + } else if (player.identity == "zhong" || player.identity == "mingzhong") { + zhuzhong += j * 0.8 + 3; + total += j * 0.8 + 3; + } else if (player.identity == "fan") { + zhuzhong -= j + 4; + total += j + 4; + fan += j + 4; } } - if(absolute) return zhuzhong; - var result=parseInt(10*Math.abs(zhuzhong/total)); - if(zhuzhong<0) result=-result; - if(!game.zhong){ - if(zhu<12&&fan>30) result--; - if(zhu<6&&fan>15) result--; - if(zhu<4) result--; + if (absolute) return zhuzhong; + var result = parseInt(10 * Math.abs(zhuzhong / total)); + if (zhuzhong < 0) result = -result; + if (!game.zhong) { + if (zhu < 12 && fan > 30) result--; + if (zhu < 6 && fan > 15) result--; + if (zhu < 4) result--; } return result; }, - insightResult:function(from,to){ - var friend='friend',enemy='enemy'; - if(from.identity=='nei') return to.identity; - if(to.identity=='nei') return friend; - if(from.ai.stratagemCamouflage||to.ai.stratagemCamouflage) return enemy; - if(from.identity==to.identity||from.identity=='zhu'&&to.identity=='zhong'||from.identity=='zhong'&&to.identity=='zhu') return friend; + insightResult: function (from, to) { + var friend = "friend", + enemy = "enemy"; + if (from.identity == "nei") return to.identity; + if (to.identity == "nei") return friend; + if (from.ai.stratagemCamouflage || to.ai.stratagemCamouflage) return enemy; + if ( + from.identity == to.identity || + (from.identity == "zhu" && to.identity == "zhong") || + (from.identity == "zhong" && to.identity == "zhu") + ) + return friend; return enemy; - } + }, }, - skill:{ - stratagem_gain:{ - silent:true, - charlotte:true, - ruleSkill:true, - trigger:{ - player:['phaseBegin','damageEnd'] + skill: { + stratagem_gain: { + silent: true, + charlotte: true, + ruleSkill: true, + trigger: { + player: ["phaseBegin", "damageEnd"], + }, + content: () => { + player.changeFury(trigger.name == "damage" ? trigger.num : 1, true); }, - content:()=>{ - player.changeFury(trigger.name=='damage'?trigger.num:1,true); - } }, - stratagem_insight:{ - trigger:{ - source:'damageSource', - global:'loseHpEnd' + stratagem_insight: { + trigger: { + source: "damageSource", + global: "loseHpEnd", }, - filter:(event,player)=>{ - if(!player.storage.stratagem_fury) return false; - const target=event.player; - if(target==player||!target.isIn()||target.identityShown) return false; - let source=event.source; - if(event.name=='loseHp'){ - const trigger=event.getParent()._trigger; - if(trigger) source=trigger.source; + filter: (event, player) => { + if (!player.storage.stratagem_fury) return false; + const target = event.player; + if (target == player || !target.isIn() || target.identityShown) return false; + let source = event.source; + if (event.name == "loseHp") { + const trigger = event.getParent()._trigger; + if (trigger) source = trigger.source; } - return player==source; + return player == source; }, - logTarget:'player', - prompt2:event=>`消耗1点怒气,洞察${get.translation(event.player)}的身份`, - check:(event,player)=>{ - const storage=player.storage,zhibi=storage.zhibi; - if(zhibi&&zhibi.includes(event.player)) return false; - const stratagemExpose=storage.stratagem_expose; - if(stratagemExpose&&stratagemExpose.includes(event.player)) return false; - if(get.population('zhong')==0&&player.identity=='fan') return false; - return Math.abs(get.attitude(player,event.player))<=1; + logTarget: "player", + prompt2: (event) => `消耗1点怒气,洞察${get.translation(event.player)}的身份`, + check: (event, player) => { + const storage = player.storage, + zhibi = storage.zhibi; + if (zhibi && zhibi.includes(event.player)) return false; + const stratagemExpose = storage.stratagem_expose; + if (stratagemExpose && stratagemExpose.includes(event.player)) return false; + if (get.population("zhong") == 0 && player.identity == "fan") return false; + return Math.abs(get.attitude(player, event.player)) <= 1; }, - content:()=>{ - player.changeFury(-1,true); + content: () => { + player.changeFury(-1, true); player.insightInto(trigger.player); - } + }, }, - stratagem_monarchy:{ - trigger:{ - player:['dying','phaseZhunbeiBegin'], - global:'dieAfter', + stratagem_monarchy: { + trigger: { + player: ["dying", "phaseZhunbeiBegin"], + global: "dieAfter", }, - forced:true, - priority:100, - popup:false, - unique:true, - firstDo:true, - silent:true, - charlotte:true, - ruleSkill:true, - filter:(event,player,name)=>{ - if(player.storage.stratagem_monarchy||player.identity!='zhu') return false; - if(name=='dieAfter') return game.dead.length>=Math.max(Math.round(get.population()/3),2); - return name=='dying'||game.roundNumber>=Math.max(Math.round(get.population()/2),3); + forced: true, + priority: 100, + popup: false, + unique: true, + firstDo: true, + silent: true, + charlotte: true, + ruleSkill: true, + filter: (event, player, name) => { + if (player.storage.stratagem_monarchy || player.identity != "zhu") return false; + if (name == "dieAfter") + return game.dead.length >= Math.max(Math.round(get.population() / 3), 2); + return ( + name == "dying" || game.roundNumber >= Math.max(Math.round(get.population() / 2), 3) + ); }, - content:()=>{ - 'step 0' - if(event.triggername=='dying') game.delayx(); - 'step 1' - player.storage.stratagem_monarchy=true; - game.broadcastAll(clientPlayer=>{ - if(!game.zhu) game.zhu=clientPlayer; - clientPlayer.identityShown=true; - clientPlayer.ai.shown=1; + content: () => { + "step 0"; + if (event.triggername == "dying") game.delayx(); + "step 1"; + player.storage.stratagem_monarchy = true; + game.broadcastAll((clientPlayer) => { + if (!game.zhu) game.zhu = clientPlayer; + clientPlayer.identityShown = true; + clientPlayer.ai.shown = 1; clientPlayer.setIdentity(); - clientPlayer.isZhu=true; - clientPlayer.node.identity.classList.remove('guessing'); - var config=lib.config; - if(config.animation&&!config.low_performance) clientPlayer.$legend(); - var clickingIdentity=_status.clickingidentity; - if(!clickingIdentity||clickingIdentity[0]!=clientPlayer) return; - clickingIdentity[1].forEach(element=>{ + clientPlayer.isZhu = true; + clientPlayer.node.identity.classList.remove("guessing"); + var config = lib.config; + if (config.animation && !config.low_performance) clientPlayer.$legend(); + var clickingIdentity = _status.clickingidentity; + if (!clickingIdentity || clickingIdentity[0] != clientPlayer) return; + clickingIdentity[1].forEach((element) => { element.delete(); - element.style.transform=''; + element.style.transform = ""; }); delete _status.clickingidentity; - },player); - game.addVideo('showIdentity',player,'zhu'); + }, player); + game.addVideo("showIdentity", player, "zhu"); game.delay(2); player.playerfocus(1000); - event.trigger('zhuUpdate'); - 'step 2' + event.trigger("zhuUpdate"); + "step 2"; player.recover(); player.draw(); - 'step 3' - const skills = player.getStockSkills(true,true).filter(stockSkill=>{ - if(player.hasSkill(stockSkill)) return; - var info=get.info(stockSkill); - if(!info||!info.zhuSkill) return; + "step 3"; + const skills = player.getStockSkills(true, true).filter((stockSkill) => { + if (player.hasSkill(stockSkill)) return; + var info = get.info(stockSkill); + if (!info || !info.zhuSkill) return; return true; }); - if(skills.length) player.addSkills(skills) - } + if (skills.length) player.addSkills(skills); + }, }, - stratagem_revitalization:{ - trigger:{ - player:'dying', + stratagem_revitalization: { + trigger: { + player: "dying", }, - forced:true, - unique:true, - silent:true, - charlotte:true, - ruleSkill:true, - filter:(event,player)=>{ - const storage=player.storage; - return !storage.stratagem_revitalization&&player.ai.stratagemCamouflage&&game.dead.length=2; + forced: true, + unique: true, + silent: true, + charlotte: true, + ruleSkill: true, + filter: (event, player) => { + const storage = player.storage; + return ( + !storage.stratagem_revitalization && + player.ai.stratagemCamouflage && + game.dead.length < Math.max(Math.round(get.population() / 6), 1) && + storage.stratagem_fury >= 2 + ); }, - content:()=>{ - 'step 0' + content: () => { + "step 0"; game.delayx(); - 'step 1' - player.storage.stratagem_revitalization=true; - game.broadcastAll(clientPlayer=>{ - clientPlayer.identityShown=true; - clientPlayer.ai.shown=1; + "step 1"; + player.storage.stratagem_revitalization = true; + game.broadcastAll((clientPlayer) => { + clientPlayer.identityShown = true; + clientPlayer.ai.shown = 1; clientPlayer.setIdentity(); - clientPlayer.node.identity.classList.remove('guessing'); - if(lib.config.animation&&!lib.config.low_performance) clientPlayer.$thunder(); - },player); - game.addVideo('showIdentity',player,'fan'); + clientPlayer.node.identity.classList.remove("guessing"); + if (lib.config.animation && !lib.config.low_performance) clientPlayer.$thunder(); + }, player); + game.addVideo("showIdentity", player, "fan"); game.delay(2); player.playerfocus(800); - 'step 2' - player.changeFury(-player.storage.stratagem_fury,true); - player.discard(player.getCards('hej')); + "step 2"; + player.changeFury(-player.storage.stratagem_fury, true); + player.discard(player.getCards("hej")); player.link(false); player.turnOver(false); - player.recover(2-player.hp); + player.recover(2 - player.hp); player.draw(3); - } - }, - stratagem_expose:{ - trigger:{player:'useCard'}, - forced:true, - silent:true, - popup:false, - filter:(event,player)=>{ - const targets=event.targets; - if(targets.length!=1) return false; - const target=targets[0]; - return target==player&&(target.identityShown||player.storage.zhibi.includes(target)||game.hasPlayer2(current=>{ - if(!current.identityShown) return false; - const storage=current.storage; - return (storage.stratagem_revitalization||storage.stratagem_monarchy)&&storage.stratagem_expose.includes(target); - })); }, - content:()=>{ - var storage=trigger.targets[0].storage; - if(!storage.stratagem_expose) storage.stratagem_expose=[]; + }, + stratagem_expose: { + trigger: { player: "useCard" }, + forced: true, + silent: true, + popup: false, + filter: (event, player) => { + const targets = event.targets; + if (targets.length != 1) return false; + const target = targets[0]; + return ( + target == player && + (target.identityShown || + player.storage.zhibi.includes(target) || + game.hasPlayer2((current) => { + if (!current.identityShown) return false; + const storage = current.storage; + return ( + (storage.stratagem_revitalization || storage.stratagem_monarchy) && + storage.stratagem_expose.includes(target) + ); + })) + ); + }, + content: () => { + var storage = trigger.targets[0].storage; + if (!storage.stratagem_expose) storage.stratagem_expose = []; storage.stratagem_expose.add(player); - } - }, - yexinbilu:{ - enable:'phaseUse', - filter:function(event,player){ - return player.identity=='rYe'||player.identity=='bYe'; }, - skillAnimation:'legend', - animationColor:'thunder', - content:function(){ - game.removeGlobalSkill('yexinbilu'); + }, + yexinbilu: { + enable: "phaseUse", + filter: function (event, player) { + return player.identity == "rYe" || player.identity == "bYe"; + }, + skillAnimation: "legend", + animationColor: "thunder", + content: function () { + game.removeGlobalSkill("yexinbilu"); player.yexinbilu(); }, - ai:{ - order:10, - result:{ - player:function(player){ - return 1-game.countPlayer(function(current){ - return current!=player&&(current.identity=='rYe'||current.identity=='bYe')&&(current==game.me||current.isOnline()); - }) + ai: { + order: 10, + result: { + player: function (player) { + return ( + 1 - + game.countPlayer(function (current) { + return ( + current != player && + (current.identity == "rYe" || current.identity == "bYe") && + (current == game.me || current.isOnline()) + ); + }) + ); }, }, }, }, - identity_junshi:{ - name:'军师', - mark:true, - intro:{ - content:'准备阶段开始时,可以观看牌堆顶的三张牌,然后将这些牌以任意顺序置于牌堆顶或牌堆底' + identity_junshi: { + name: "军师", + mark: true, + intro: { + content: + "准备阶段开始时,可以观看牌堆顶的三张牌,然后将这些牌以任意顺序置于牌堆顶或牌堆底", }, - trigger:{player:'phaseZhunbeiBegin'}, - silent:true, - content:function(){ - "step 0" - var cards=get.cards(3); + trigger: { player: "phaseZhunbeiBegin" }, + silent: true, + content: function () { + "step 0"; + var cards = get.cards(3); game.cardsGotoOrdering(cards); - var next=player.chooseToMove(); - next.set('list',[ - ['牌堆顶',cards], - ['牌堆底'], - ]); - next.set('prompt','观星:点击将牌移动到牌堆顶或牌堆底'); - next.processAI=function(list){ - var cards=list[0][1],player=_status.event.player; - var top=[]; - var judges=player.getCards('j'); - var stopped=false; - if(!player.hasWuxie()){ - for(var i=0;i0; - }).set('ai',function(target){ - var player=_status.event.player; - var att=get.attitude(player,target); + forceunique: true, + content: function () { + "step 0"; + player + .chooseTarget(get.prompt("dongcha"), function (card, player, target) { + return target.countCards("ej") > 0; + }) + .set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); - if(att>0){ - var js=target.getCards('j'); - if(js.length){ - var jj=js[0].viewAs?{name:js[0].viewAs}:js[0]; - if(jj.name=='guohe'||js.length>1||get.effect(target,jj,target,player)<0){ - return 2*att; + if (att > 0) { + var js = target.getCards("j"); + if (js.length) { + var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0]; + if ( + jj.name == "guohe" || + js.length > 1 || + get.effect(target, jj, target, player) < 0 + ) { + return 2 * att; + } + } + if ( + target.getEquip("baiyin") && + target.isDamaged() && + get.recoverEffect(target, player, player) > 0 + ) { + if (target.hp == 1 && !target.hujia) return 1.6 * att; + if (target.hp == 2) return 0.01 * att; + return 0; } } - if(target.getEquip('baiyin')&&target.isDamaged()&& - get.recoverEffect(target,player,player)>0){ - if(target.hp==1&&!target.hujia) return 1.6*att; - if(target.hp==2) return 0.01*att; - return 0; - } - } - var es=target.getCards('e'); - var noe=target.hasSkillTag('noe'); - var noe2=(es.length==1&&es[0].name=='baiyin'&&target.isDamaged()); - if(noe||noe2) return 0; - if(att<=0&&!es.length) return 1.5*att; - return -1.5*att; - }); - 'step 1' - if(result.bool){ - event.target=result.targets[0]; + var es = target.getCards("e"); + var noe = target.hasSkillTag("noe"); + var noe2 = es.length == 1 && es[0].name == "baiyin" && target.isDamaged(); + if (noe || noe2) return 0; + if (att <= 0 && !es.length) return 1.5 * att; + return -1.5 * att; + }); + "step 1"; + if (result.bool) { + event.target = result.targets[0]; event.target.addExpose(0.1); - player.logSkill('dongcha',event.target); + player.logSkill("dongcha", event.target); game.delayx(); - } - else{ + } else { event.finish(); } - 'step 2' - if(event.target){ - player.discardPlayerCard('ej',true,event.target); + "step 2"; + if (event.target) { + player.discardPlayerCard("ej", true, event.target); } }, - group:['dongcha_begin','dongcha_log'], - subSkill:{ - begin:{ - trigger:{global:'gameStart'}, - forced:true, - popup:false, - content:function(){ - var list=[]; - for(var i=0;i0; + }, + }, }, - logTarget:'player', - content:function(){ - 'step 0' + }, + sheshen: { + trigger: { global: "dieBefore" }, + forced: true, + unique: true, + forceunique: true, + filter: function (event, player) { + return event.player == game.zhu && player.hp > 0; + }, + logTarget: "player", + content: function () { + "step 0"; trigger.player.gainMaxHp(); - 'step 1' - var dh=player.hp-trigger.player.hp; - if(dh>0){ + "step 1"; + var dh = player.hp - trigger.player.hp; + if (dh > 0) { trigger.player.recover(dh); } - 'step 2' - var cards=player.getCards('he'); - if(cards.length){ - trigger.player.gain(cards,player); - player.$giveAuto(cards,trigger.player); + "step 2"; + var cards = player.getCards("he"); + if (cards.length) { + trigger.player.gain(cards, player); + player.$giveAuto(cards, trigger.player); } - 'step 3' + "step 3"; trigger.cancel(); player.die(); - } - } + }, + }, + }, + help: { + 身份模式: + '
                        选项
                        • 加强主公
                          反贼人数多于2时主公会额外增加一个技能(每个主公的额外技能固定,非常备主公增加天命)' + + '
                        • 特殊身份
                          • 军师:忠臣身份。只要军师存活,主公在准备阶段开始时,可以观看牌堆顶的三张牌,然后将这些牌以任意顺序置于牌堆顶或牌堆底
                          • 大将:忠臣身份。只要大将存活,主公手牌上限+1
                          • 贼首:反贼身份,只要贼首存活,主公手牌上限-1
                        ' + + "
                      • 平民身份
                        英盗版三国杀于2017标准版中提出的新概念。平民的获胜条件为:当其他身份的角色达成了其获胜条件,且你存活,你也获胜;同时内奸的获胜条件改为:主公死亡时,场上所有忠臣和反贼均已死亡。即内奸可以和与平民共同胜利。杀死平民的角色的奖惩为:摸两张牌。" + + "
                      • 年机制
                        英盗版三国杀于2019标准版中提出的新概念。“年”是一个全局概念,游戏开始时为第一年,当牌堆洗牌时,年数+1。一局游戏的限定年数为本局游戏开始时玩家总数。当年数增加后,若当前年数已超过限定年数,则主忠方直接获胜,若平民存活则平民也获胜。", + 明忠模式: + '
                        明忠模式(忠胆英杰)
                        • 本模式需要8名玩家进行游戏,使用的身份牌为:1主公、2忠臣、4反贼和1内奸。游戏开始时,每名玩家随机获得一个身份,由系统随机选择一名忠臣身份的玩家亮出身份(将忠臣牌正面朝上放在面前),其他身份(包括主公)的玩家不亮出身份。
                        • ' + + "首先由亮出身份的忠臣玩家随机获得六张武将牌,挑选一名角色,并将选好的武将牌展示给其他玩家。之后其余每名玩家随机获得三张武将牌,各自从其中挑选一张同时亮出
                        • " + + "亮出身份牌的忠臣增加1点体力上限。角色濒死和死亡的结算及胜利条件与普通身份局相同。", + 谋攻模式: + '
                          模式命名由来
                          • 《谋攻篇》一词出自《孙子兵法·谋攻篇》,是春秋时期兵法家孙武创作的一篇散文。《谋攻篇》故知胜有五:知可以战与不可以战者胜,识众寡之用者胜,上下同欲者胜,以虞待不虞者胜,将能而君不御者胜。
                          ' + + '
                          游戏规则
                          • 谋攻篇模式为六名玩家参与的全暗身份模式,引入新机制“怒气”,玩家可以消耗怒气探查其他角色的身份是敌人或者队友,或使用怒气强化手牌,以达到识别出队友并击杀敌人的目标。' + + "
                          • 各身份玩家的胜利条件与身份局中对应身份的胜利条件一致,且该模式下没有奖惩。" + + "
                          • 当主公进入濒死、场上有两名角色阵亡、第三轮的主公准备阶段,主公将会翻开身份牌,回复1点体力并摸一张牌,并获得武将牌上的主公技。" + + "
                          • 内奸在游戏开始时将会得知一名反贼的身份,并令该反贼被“伪装”。本局游戏内,被“伪装”的反贼在被任何人探查身份时,结果都提示为“敌人”。作为补偿,其第一次进入濒死时,若场上没有角色死亡且其怒气值不小于2,其弃置区域内所有牌,重置武将牌,将体力回复至2点并摸三张牌。" + + "
                          • 特殊地,内奸在被所有角色探查时,都提示为“队友”;内奸在进行探查时,直接得知目标的身份。
                          " + + '
                          新机制“怒气”
                          • 一名角色在回合开始时或受到1点伤害后,将获得1点怒气;怒气上限为3。
                          • 一名角色令其他角色扣减体力后,该角色可以消耗1点怒气,查探扣减体力的角色是敌或友。
                          ' + + '
                          强化卡牌规则
                          • 在第二轮游戏开始后,当你需要使用一张“强化表”内的牌时,你可以通过消耗怒气将此牌强化。' + + '
                          • 可强化卡牌
                              ' + + "
                            • 【杀】:消耗1点怒气进行强化,你令响应此杀所需使用的【闪】数+1" + + "
                            • 【闪】:消耗1点怒气进行强化,使用时视为两张【闪】的效果" + + "
                            • 【决斗】:消耗2点怒气进行强化,对此牌的目标造成伤害时,伤害+1" + + "
                            • 【火攻】:消耗2点怒气进行强化,造成的伤害+1" + + "
                            • 【桃】:消耗3点怒气进行强化,回复的体力+1
                          ", + "3v3v2": + '
                          3v3v2模式
                          • 游戏准备
                            本模式需要8名玩家进行游戏。游戏开始前,所有玩家随机分成两组,每组四人,分别称为「冷色阵营」和「暖色阵营」,然后分发身份牌,抽取到「主帅」身份的玩家亮出身份牌。' + + "
                          • 身份牌
                            每组的身份分为四种。
                            主帅(主)和前锋(忠):联合对方阵营的细作,击杀己方细作,对方阵营的主帅和前锋以及所有的野心家。
                            细作(内):帮助对方阵营的主帅和前锋,击杀对方细作,己方阵营的主帅和前锋以及所有的野心家。
                            野心家(野):联合对方阵营中的野心家,击杀所有其他角色,成为最后的生还者。
                            " + + "
                          • 胜负判定
                            冷色主帅,先锋和暖色细作在所有野心家和对方主帅全部阵亡后视为胜利,在冷色主帅阵亡后视为游戏失败。
                            暖色主帅,先锋和冷色细作在所有野心家和对方主帅阵亡后视为胜利,在暖色主帅阵亡后视为失败。
                            野心家在所有不为野心家的角色阵亡后视为胜利,在双方主帅全部阵亡而有非野心家角色存活时失败。
                            当有角色阵亡后,若有角色满足胜利条件,游戏结束。若所有角色均满足失败条件,则游戏平局。若一名角色满足失败条件,即使其满足胜利条件,也视为游戏失败。
                            " + + "
                          • 游戏流程
                            在「游戏准备」中的工作完成后,冷色主帅选择一个势力,然后暖色主帅选择一个其他势力,作为双方各自的势力将池。
                            双方主帅从各自的势力将池中获得两张常备主公武将牌和四张非常备主公武将牌,然后选择一张作为武将牌,将其他的武将牌放回势力将池并洗混。然后双方的其他玩家从各自的势力将池中随机获得五张武将牌,选择一张作为自己的武将牌。
                            暖色主帅成为游戏的一号位,双方主帅各加1点体力和体力上限。七号位和八号位的起始手牌+1。
                            当场上第一次有玩家死亡时,野心家确认彼此的身份牌,然后获得技能〖野心毕露〗:出牌阶段,你可以明置身份牌,加1点体力上限和体力值。若如此做,所有的野心家失去技能〖野心毕露〗
                            " + + "
                          • 击杀奖惩
                            杀死颜色不同的主帅的角色回复1点体力,杀死颜色不同的先锋的角色摸两张牌,杀死颜色相同的细作的角色摸三张牌,杀死颜色相同的先锋的主帅弃置所有手牌。
                            " + + "
                          • 制作团队
                            游戏出品:紫星居
                            游戏设计:食茸貳拾肆
                            游戏开发:食茸貳拾肆、紫髯的小乔、聆星Mine、空城琴音依旧弥漫、丽景原同志、雪之彩翼、拉普拉斯、明月照沟渠
                            程序化:无名杀
                            鸣谢:荆哲、魔风、萨巴鲁酱、这就是秋夜
                        ", }, - help:{ - '身份模式':'
                        选项
                        • 加强主公
                          反贼人数多于2时主公会额外增加一个技能(每个主公的额外技能固定,非常备主公增加天命)'+ - '
                        • 特殊身份
                          • 军师:忠臣身份。只要军师存活,主公在准备阶段开始时,可以观看牌堆顶的三张牌,然后将这些牌以任意顺序置于牌堆顶或牌堆底
                          • 大将:忠臣身份。只要大将存活,主公手牌上限+1
                          • 贼首:反贼身份,只要贼首存活,主公手牌上限-1
                        '+ - '
                      • 平民身份
                        英盗版三国杀于2017标准版中提出的新概念。平民的获胜条件为:当其他身份的角色达成了其获胜条件,且你存活,你也获胜;同时内奸的获胜条件改为:主公死亡时,场上所有忠臣和反贼均已死亡。即内奸可以和与平民共同胜利。杀死平民的角色的奖惩为:摸两张牌。'+ - '
                      • 年机制
                        英盗版三国杀于2019标准版中提出的新概念。“年”是一个全局概念,游戏开始时为第一年,当牌堆洗牌时,年数+1。一局游戏的限定年数为本局游戏开始时玩家总数。当年数增加后,若当前年数已超过限定年数,则主忠方直接获胜,若平民存活则平民也获胜。', - '明忠模式':'
                        明忠模式(忠胆英杰)
                        • 本模式需要8名玩家进行游戏,使用的身份牌为:1主公、2忠臣、4反贼和1内奸。游戏开始时,每名玩家随机获得一个身份,由系统随机选择一名忠臣身份的玩家亮出身份(将忠臣牌正面朝上放在面前),其他身份(包括主公)的玩家不亮出身份。
                        • '+ - '首先由亮出身份的忠臣玩家随机获得六张武将牌,挑选一名角色,并将选好的武将牌展示给其他玩家。之后其余每名玩家随机获得三张武将牌,各自从其中挑选一张同时亮出
                        • '+ - '亮出身份牌的忠臣增加1点体力上限。角色濒死和死亡的结算及胜利条件与普通身份局相同。', - '谋攻模式':'
                          模式命名由来
                          • 《谋攻篇》一词出自《孙子兵法·谋攻篇》,是春秋时期兵法家孙武创作的一篇散文。《谋攻篇》故知胜有五:知可以战与不可以战者胜,识众寡之用者胜,上下同欲者胜,以虞待不虞者胜,将能而君不御者胜。
                          '+ - '
                          游戏规则
                          • 谋攻篇模式为六名玩家参与的全暗身份模式,引入新机制“怒气”,玩家可以消耗怒气探查其他角色的身份是敌人或者队友,或使用怒气强化手牌,以达到识别出队友并击杀敌人的目标。'+ - '
                          • 各身份玩家的胜利条件与身份局中对应身份的胜利条件一致,且该模式下没有奖惩。'+ - '
                          • 当主公进入濒死、场上有两名角色阵亡、第三轮的主公准备阶段,主公将会翻开身份牌,回复1点体力并摸一张牌,并获得武将牌上的主公技。'+ - '
                          • 内奸在游戏开始时将会得知一名反贼的身份,并令该反贼被“伪装”。本局游戏内,被“伪装”的反贼在被任何人探查身份时,结果都提示为“敌人”。作为补偿,其第一次进入濒死时,若场上没有角色死亡且其怒气值不小于2,其弃置区域内所有牌,重置武将牌,将体力回复至2点并摸三张牌。'+ - '
                          • 特殊地,内奸在被所有角色探查时,都提示为“队友”;内奸在进行探查时,直接得知目标的身份。
                          '+ - '
                          新机制“怒气”
                          • 一名角色在回合开始时或受到1点伤害后,将获得1点怒气;怒气上限为3。
                          • 一名角色令其他角色扣减体力后,该角色可以消耗1点怒气,查探扣减体力的角色是敌或友。
                          '+ - '
                          强化卡牌规则
                          • 在第二轮游戏开始后,当你需要使用一张“强化表”内的牌时,你可以通过消耗怒气将此牌强化。'+ - '
                          • 可强化卡牌
                              '+ - '
                            • 【杀】:消耗1点怒气进行强化,你令响应此杀所需使用的【闪】数+1'+ - '
                            • 【闪】:消耗1点怒气进行强化,使用时视为两张【闪】的效果'+ - '
                            • 【决斗】:消耗2点怒气进行强化,对此牌的目标造成伤害时,伤害+1'+ - '
                            • 【火攻】:消耗2点怒气进行强化,造成的伤害+1'+ - '
                            • 【桃】:消耗3点怒气进行强化,回复的体力+1
                          ', - '3v3v2':'
                          3v3v2模式
                          • 游戏准备
                            本模式需要8名玩家进行游戏。游戏开始前,所有玩家随机分成两组,每组四人,分别称为「冷色阵营」和「暖色阵营」,然后分发身份牌,抽取到「主帅」身份的玩家亮出身份牌。'+ - '
                          • 身份牌
                            每组的身份分为四种。
                            主帅(主)和前锋(忠):联合对方阵营的细作,击杀己方细作,对方阵营的主帅和前锋以及所有的野心家。
                            细作(内):帮助对方阵营的主帅和前锋,击杀对方细作,己方阵营的主帅和前锋以及所有的野心家。
                            野心家(野):联合对方阵营中的野心家,击杀所有其他角色,成为最后的生还者。
                            '+ - '
                          • 胜负判定
                            冷色主帅,先锋和暖色细作在所有野心家和对方主帅全部阵亡后视为胜利,在冷色主帅阵亡后视为游戏失败。
                            暖色主帅,先锋和冷色细作在所有野心家和对方主帅阵亡后视为胜利,在暖色主帅阵亡后视为失败。
                            野心家在所有不为野心家的角色阵亡后视为胜利,在双方主帅全部阵亡而有非野心家角色存活时失败。
                            当有角色阵亡后,若有角色满足胜利条件,游戏结束。若所有角色均满足失败条件,则游戏平局。若一名角色满足失败条件,即使其满足胜利条件,也视为游戏失败。
                            '+ - '
                          • 游戏流程
                            在「游戏准备」中的工作完成后,冷色主帅选择一个势力,然后暖色主帅选择一个其他势力,作为双方各自的势力将池。
                            双方主帅从各自的势力将池中获得两张常备主公武将牌和四张非常备主公武将牌,然后选择一张作为武将牌,将其他的武将牌放回势力将池并洗混。然后双方的其他玩家从各自的势力将池中随机获得五张武将牌,选择一张作为自己的武将牌。
                            暖色主帅成为游戏的一号位,双方主帅各加1点体力和体力上限。七号位和八号位的起始手牌+1。
                            当场上第一次有玩家死亡时,野心家确认彼此的身份牌,然后获得技能〖野心毕露〗:出牌阶段,你可以明置身份牌,加1点体力上限和体力值。若如此做,所有的野心家失去技能〖野心毕露〗
                            '+'
                          • 击杀奖惩
                            杀死颜色不同的主帅的角色回复1点体力,杀死颜色不同的先锋的角色摸两张牌,杀死颜色相同的细作的角色摸三张牌,杀死颜色相同的先锋的主帅弃置所有手牌。
                            '+ - '
                          • 制作团队
                            游戏出品:紫星居
                            游戏设计:食茸貳拾肆
                            游戏开发:食茸貳拾肆、紫髯的小乔、聆星Mine、空城琴音依旧弥漫、丽景原同志、雪之彩翼、拉普拉斯、明月照沟渠
                            程序化:无名杀
                            鸣谢:荆哲、魔风、萨巴鲁酱、这就是秋夜
                        ', - } }; }); diff --git a/mode/realtime.js b/mode/realtime.js index fb2f2ab9d..d8d9c1642 100644 --- a/mode/realtime.js +++ b/mode/realtime.js @@ -1,10 +1,8 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ - return { - name:'realtime', - start:function(){ - }, - game:{ - } - }; -}); +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { + return { + name: "realtime", + start: function () {}, + game: {}, + }; +}); diff --git a/mode/single.js b/mode/single.js index 9ee0a27fa..94e4ba69f 100644 --- a/mode/single.js +++ b/mode/single.js @@ -1,1884 +1,2284 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'single', - changbanCharacter:[ - "key_rei","key_yoshino","key_noda","key_nagisa", - "re_caocao","re_caozhang","re_diaochan","re_ganning","re_gongsunzan","re_guojia","re_huangyueying","re_lidian","re_lvbu", - "re_simayi","sunquan","re_xiahoudun","re_xushu","yuanshu","xf_yiji","re_zhangfei","re_zhangliao","re_xuzhu", - "re_zhaoyun","re_zhouyu","re_zhugeliang","ol_xiahouyuan","re_huangzhong","re_weiyan","dianwei","te_yanwen","re_pangde", - "re_zhurong","re_sunjian","jiaxu","dengai","re_jiangwei","re_sunben","wangji","wangping","guanqiujian","chendao","ol_yujin", - "re_caozhi","xin_masu","re_lingtong","xusheng","re_gaoshun","xunyou","guanzhang","madai","handang","caochong", - "re_guohuai","guanping","liufeng","re_zhuran","xin_liru","hanhaoshihuan","guyong","zhuhuan","caoxiu","liuchen","re_zhangyi", - "re_quancong","sunxiu","sundeng","guohuanghou","re_jikang","xuezong","qinmi","lvdai","re_zhangliang","lingcao", - "sunru","zhuling","sp_caoren","fanchou","fuwan","sp_ganning","guanyinping","guosi","heqi","sp_jiangwei","litong", - "re_panfeng","sp_pangde","xf_sufei","xf_tangzi","xiahouba","xujing","yuejin","sp_zhangfei","zhangji","zhangyì","dongcheng", + name: "single", + changbanCharacter: [ + "key_rei", + "key_yoshino", + "key_noda", + "key_nagisa", + "re_caocao", + "re_caozhang", + "re_diaochan", + "re_ganning", + "re_gongsunzan", + "re_guojia", + "re_huangyueying", + "re_lidian", + "re_lvbu", + "re_simayi", + "sunquan", + "re_xiahoudun", + "re_xushu", + "yuanshu", + "xf_yiji", + "re_zhangfei", + "re_zhangliao", + "re_xuzhu", + "re_zhaoyun", + "re_zhouyu", + "re_zhugeliang", + "ol_xiahouyuan", + "re_huangzhong", + "re_weiyan", + "dianwei", + "te_yanwen", + "re_pangde", + "re_zhurong", + "re_sunjian", + "jiaxu", + "dengai", + "re_jiangwei", + "re_sunben", + "wangji", + "wangping", + "guanqiujian", + "chendao", + "ol_yujin", + "re_caozhi", + "xin_masu", + "re_lingtong", + "xusheng", + "re_gaoshun", + "xunyou", + "guanzhang", + "madai", + "handang", + "caochong", + "re_guohuai", + "guanping", + "liufeng", + "re_zhuran", + "xin_liru", + "hanhaoshihuan", + "guyong", + "zhuhuan", + "caoxiu", + "liuchen", + "re_zhangyi", + "re_quancong", + "sunxiu", + "sundeng", + "guohuanghou", + "re_jikang", + "xuezong", + "qinmi", + "lvdai", + "re_zhangliang", + "lingcao", + "sunru", + "zhuling", + "sp_caoren", + "fanchou", + "fuwan", + "sp_ganning", + "guanyinping", + "guosi", + "heqi", + "sp_jiangwei", + "litong", + "re_panfeng", + "sp_pangde", + "xf_sufei", + "xf_tangzi", + "xiahouba", + "xujing", + "yuejin", + "sp_zhangfei", + "zhangji", + "zhangyì", + "dongcheng", ], - singlePile:[ - ['spade',5,'sha'], - ['spade',7,'sha'], - ['spade',8,'sha'], - ['spade',10,'sha'], - ['heart',10,'sha'], - ['heart',11,'sha'], - ['club',4,'sha'], - ['club',5,'sha'], - ['club',6,'sha'], - ['club',8,'sha'], - ['club',9,'sha'], - ['club',10,'sha'], - ['club',11,'sha'], - ['diamond',6,'sha'], - ['diamond',9,'sha'], - ['diamond',11,'sha'], - ['heart',2,'shan'], - ['heart',5,'shan'], - ['diamond',2,'shan'], - ['diamond',3,'shan'], - ['diamond',7,'shan'], - ['diamond',8,'shan'], - ['diamond',10,'shan'], - ['diamond',11,'shan'], - ['heart',3,'tao'], - ['heart',4,'tao'], - ['heart',9,'tao'], - ['diamond',12,'tao'], - ['club',12,'bingliang'], - ['spade',3,'guohe'], - ['diamond',12,'guohe'], - ['club',3,'guohe'], - ['club',1,'juedou'], - ['spade',1,'juedou'], - ['heart',6,'lebu'], - ['spade',1,'nanman'], - ['club',7,'shuiyanqijunx'], - ['spade',4,'shunshou'], - ['spade',11,'shunshou'], - ['diamond',4,'shunshou'], - ['heart',1,'wanjian'], - ['heart',5,'wuxie'], - ['club',5,'wuxie'], - ['heart',7,'wuzhong'], - ['heart',8,'wuzhong'], - ['diamond',5,'guanshi'], - ['spade',9,'hanbing'], - ['spade',6,'qinggang'], - ['spade',12,'zhangba'], - ['diamond',1,'zhuge'], - ['spade',2,'bagua'], - ['club',2,'renwang'], + singlePile: [ + ["spade", 5, "sha"], + ["spade", 7, "sha"], + ["spade", 8, "sha"], + ["spade", 10, "sha"], + ["heart", 10, "sha"], + ["heart", 11, "sha"], + ["club", 4, "sha"], + ["club", 5, "sha"], + ["club", 6, "sha"], + ["club", 8, "sha"], + ["club", 9, "sha"], + ["club", 10, "sha"], + ["club", 11, "sha"], + ["diamond", 6, "sha"], + ["diamond", 9, "sha"], + ["diamond", 11, "sha"], + ["heart", 2, "shan"], + ["heart", 5, "shan"], + ["diamond", 2, "shan"], + ["diamond", 3, "shan"], + ["diamond", 7, "shan"], + ["diamond", 8, "shan"], + ["diamond", 10, "shan"], + ["diamond", 11, "shan"], + ["heart", 3, "tao"], + ["heart", 4, "tao"], + ["heart", 9, "tao"], + ["diamond", 12, "tao"], + ["club", 12, "bingliang"], + ["spade", 3, "guohe"], + ["diamond", 12, "guohe"], + ["club", 3, "guohe"], + ["club", 1, "juedou"], + ["spade", 1, "juedou"], + ["heart", 6, "lebu"], + ["spade", 1, "nanman"], + ["club", 7, "shuiyanqijunx"], + ["spade", 4, "shunshou"], + ["spade", 11, "shunshou"], + ["diamond", 4, "shunshou"], + ["heart", 1, "wanjian"], + ["heart", 5, "wuxie"], + ["club", 5, "wuxie"], + ["heart", 7, "wuzhong"], + ["heart", 8, "wuzhong"], + ["diamond", 5, "guanshi"], + ["spade", 9, "hanbing"], + ["spade", 6, "qinggang"], + ["spade", 12, "zhangba"], + ["diamond", 1, "zhuge"], + ["spade", 2, "bagua"], + ["club", 2, "renwang"], ], - singlePile_wuxianhuoli:[ - ['heart',1,'wanjian'], - ['heart',2,'shan'], - ['heart',2,'huogong'], - ['heart',3,'tao'], - ['heart',3,'huogong'], - ['heart',4,'tao'], - ['heart',4,'sha','fire'], - ['heart',6,'tao'], - ['heart',7,'sha','fire'], - ['heart',7,'wuzhong'], - ['heart',8,'wuzhong'], - ['heart',9,'wuzhong'], - ['heart',10,'sha'], - ['heart',10,'sha'], - ['heart',10,'sha','fire'], - ['heart',12,'guohe'], - ['heart',12,'shandian'], - ['heart',13,'shan'], + singlePile_wuxianhuoli: [ + ["heart", 1, "wanjian"], + ["heart", 2, "shan"], + ["heart", 2, "huogong"], + ["heart", 3, "tao"], + ["heart", 3, "huogong"], + ["heart", 4, "tao"], + ["heart", 4, "sha", "fire"], + ["heart", 6, "tao"], + ["heart", 7, "sha", "fire"], + ["heart", 7, "wuzhong"], + ["heart", 8, "wuzhong"], + ["heart", 9, "wuzhong"], + ["heart", 10, "sha"], + ["heart", 10, "sha"], + ["heart", 10, "sha", "fire"], + ["heart", 12, "guohe"], + ["heart", 12, "shandian"], + ["heart", 13, "shan"], - ['diamond',1,'juedou'], - ['diamond',1,'zhuge'], - ['diamond',1,'zhuque'], - ['diamond',3,'shunshou'], - ['diamond',4,'shunshou'], - ['diamond',5,'guanshi'], - ['diamond',6,'sha'], - ['diamond',6,'shan'], - ['diamond',7,'sha'], - ['diamond',7,'shan'], - ['diamond',8,'sha'], - ['diamond',8,'shan'], - ['diamond',9,'sha'], - ['diamond',9,'shan'], - ['diamond',9,'jiu'], - ['diamond',10,'shan'], - ['diamond',11,'shan'], - ['diamond',12,'tao'], - ['diamond',12,'wuxie'], - ['diamond',12,'huogong'], + ["diamond", 1, "juedou"], + ["diamond", 1, "zhuge"], + ["diamond", 1, "zhuque"], + ["diamond", 3, "shunshou"], + ["diamond", 4, "shunshou"], + ["diamond", 5, "guanshi"], + ["diamond", 6, "sha"], + ["diamond", 6, "shan"], + ["diamond", 7, "sha"], + ["diamond", 7, "shan"], + ["diamond", 8, "sha"], + ["diamond", 8, "shan"], + ["diamond", 9, "sha"], + ["diamond", 9, "shan"], + ["diamond", 9, "jiu"], + ["diamond", 10, "shan"], + ["diamond", 11, "shan"], + ["diamond", 12, "tao"], + ["diamond", 12, "wuxie"], + ["diamond", 12, "huogong"], - ['club',1,'juedou'], - ['club',1,'baiyin'], - ['club',2,'sha'], - ['club',2,'bagua'], - ['club',2,'renwang'], - ['club',3,'sha'], - ['club',3,'guohe'], - ['club',4,'sha'], - ['club',5,'sha'], - ['club',5,'sha','thunder'], - ['club',6,'sha'], - ['club',6,'sha','thunder'], - ['club',7,'sha'], - ['club',7,'sha','thunder'], - ['club',7,'nanman'], - ['club',8,'sha'], - ['club',9,'sha'], - ['club',9,'jiu'], - ['club',12,'wuxie'], - ['club',13,'wuxie'], + ["club", 1, "juedou"], + ["club", 1, "baiyin"], + ["club", 2, "sha"], + ["club", 2, "bagua"], + ["club", 2, "renwang"], + ["club", 3, "sha"], + ["club", 3, "guohe"], + ["club", 4, "sha"], + ["club", 5, "sha"], + ["club", 5, "sha", "thunder"], + ["club", 6, "sha"], + ["club", 6, "sha", "thunder"], + ["club", 7, "sha"], + ["club", 7, "sha", "thunder"], + ["club", 7, "nanman"], + ["club", 8, "sha"], + ["club", 9, "sha"], + ["club", 9, "jiu"], + ["club", 12, "wuxie"], + ["club", 13, "wuxie"], - ['spade',1,'juedou'], - ['spade',1,'guding'], - ['spade',2,'cixiong'], - ['spade',2,'hanbing'], - ['spade',2,'tengjia'], - ['spade',3,'shunshou'], - ['spade',4,'sha','thunder'], - ['spade',4,'guohe'], - ['spade',4,'shunshou'], - ['spade',5,'sha','thunder'], - ['spade',5,'qinglong'], - ['spade',6,'sha','thunder'], - ['spade',6,'qinggang'], - ['spade',7,'sha'], - ['spade',7,'sha','thunder'], - ['spade',8,'sha'], - ['spade',8,'sha'], - ['spade',8,'sha','thunder'], - ['spade',9,'sha'], - ['spade',9,'jiu'], - ['spade',10,'sha'], - ['spade',10,'bingliang'], - ['spade',11,'wuxie'], - ['spade',12,'guohe'], - ['spade',12,'zhangba'], - ['spade',13,'nanman'], + ["spade", 1, "juedou"], + ["spade", 1, "guding"], + ["spade", 2, "cixiong"], + ["spade", 2, "hanbing"], + ["spade", 2, "tengjia"], + ["spade", 3, "shunshou"], + ["spade", 4, "sha", "thunder"], + ["spade", 4, "guohe"], + ["spade", 4, "shunshou"], + ["spade", 5, "sha", "thunder"], + ["spade", 5, "qinglong"], + ["spade", 6, "sha", "thunder"], + ["spade", 6, "qinggang"], + ["spade", 7, "sha"], + ["spade", 7, "sha", "thunder"], + ["spade", 8, "sha"], + ["spade", 8, "sha"], + ["spade", 8, "sha", "thunder"], + ["spade", 9, "sha"], + ["spade", 9, "jiu"], + ["spade", 10, "sha"], + ["spade", 10, "bingliang"], + ["spade", 11, "wuxie"], + ["spade", 12, "guohe"], + ["spade", 12, "zhangba"], + ["spade", 13, "nanman"], ], - characterSingle:{ - caocao:['male','wei',4,['jianxiong'],['zhu']], - simayi:['male','wei',3,['fankui','guicai']], - xiahoudun:['male','wei',4,['ganglie']], - zhangliao:['male','wei',4,['retuxi']], - xuzhu:['male','wei',4,['luoyi','xiechan']], - guojia:['male','wei',3,['tiandu','yiji']], - zhenji:['female','wei',3,['luoshen','sgqingguo']], - liubei:['male','shu',4,['sgrenwang'],['zhu']], - guanyu:['male','shu',4,['wusheng','huwei']], - zhangfei:['male','shu',4,['paoxiao']], - zhugeliang:['male','shu',3,['guanxing','kongcheng']], - zhaoyun:['male','shu',4,['longdan']], - machao:['male','shu',4,['xiaoxi','tieji']], - huangyueying:['female','shu',3,['jizhi','cangji']], - sunquan:['male','wu',4,['sgzhiheng'],['zhu']], - ganning:['male','wu',4,['qixi']], - lvmeng:['male','wu',4,['shenju','botu']], - huanggai:['male','wu',4,['kurou']], - zhouyu:['male','wu',3,['yingzi','fanjian']], - daqiao:['female','wu',3,['guose','wanrong']], - luxun:['male','wu',3,['qianxun','lianying']], - sunshangxiang:['female','wu',3,['xiaoji','yinli']], + characterSingle: { + caocao: ["male", "wei", 4, ["jianxiong"], ["zhu"]], + simayi: ["male", "wei", 3, ["fankui", "guicai"]], + xiahoudun: ["male", "wei", 4, ["ganglie"]], + zhangliao: ["male", "wei", 4, ["retuxi"]], + xuzhu: ["male", "wei", 4, ["luoyi", "xiechan"]], + guojia: ["male", "wei", 3, ["tiandu", "yiji"]], + zhenji: ["female", "wei", 3, ["luoshen", "sgqingguo"]], + liubei: ["male", "shu", 4, ["sgrenwang"], ["zhu"]], + guanyu: ["male", "shu", 4, ["wusheng", "huwei"]], + zhangfei: ["male", "shu", 4, ["paoxiao"]], + zhugeliang: ["male", "shu", 3, ["guanxing", "kongcheng"]], + zhaoyun: ["male", "shu", 4, ["longdan"]], + machao: ["male", "shu", 4, ["xiaoxi", "tieji"]], + huangyueying: ["female", "shu", 3, ["jizhi", "cangji"]], + sunquan: ["male", "wu", 4, ["sgzhiheng"], ["zhu"]], + ganning: ["male", "wu", 4, ["qixi"]], + lvmeng: ["male", "wu", 4, ["shenju", "botu"]], + huanggai: ["male", "wu", 4, ["kurou"]], + zhouyu: ["male", "wu", 3, ["yingzi", "fanjian"]], + daqiao: ["female", "wu", 3, ["guose", "wanrong"]], + luxun: ["male", "wu", 3, ["qianxun", "lianying"]], + sunshangxiang: ["female", "wu", 3, ["xiaoji", "yinli"]], //huatuo:['male','qun',3,['qingnang','jijiu']], - lvbu:['male','qun',4,['wushuang']], - diaochan:['female','qun',3,['pianyi','biyue']], + lvbu: ["male", "qun", 4, ["wushuang"]], + diaochan: ["female", "qun", 3, ["pianyi", "biyue"]], - xiahouyuan:['male','wei',4,['shensu','suzi']], - old_caoren:['male','wei',4,['jushou']], - huangzhong:['male','shu',4,['liegong']], - weiyan:['male','shu',4,['sgkuanggu']], - xiaoqiao:['female','wu',3,['tianxiang','hongyan']], - old_zhoutai:['male','wu',4,['gzbuqu']], - zhangjiao:['male','qun',3,['leiji','guidao'],['zhu']], + xiahouyuan: ["male", "wei", 4, ["shensu", "suzi"]], + old_caoren: ["male", "wei", 4, ["jushou"]], + huangzhong: ["male", "shu", 4, ["liegong"]], + weiyan: ["male", "shu", 4, ["sgkuanggu"]], + xiaoqiao: ["female", "wu", 3, ["tianxiang", "hongyan"]], + old_zhoutai: ["male", "wu", 4, ["gzbuqu"]], + zhangjiao: ["male", "qun", 3, ["leiji", "guidao"], ["zhu"]], - dianwei:['male','wei',4,['qiangxi']], - yanwen:['male','qun',4,['shuangxiong']], - pangde:['male','qun',4,['xiaoxi','mengjin']], + dianwei: ["male", "wei", 4, ["qiangxi"]], + yanwen: ["male", "qun", 4, ["shuangxiong"]], + pangde: ["male", "qun", 4, ["xiaoxi", "mengjin"]], - menghuo:['male','shu',4,['manyi','zaiqi']], - zhurong:['female','shu',4,['manyi','lieren']], - xuhuang:['male','wei',4,['sgduanliang']], - sunjian:['male','wu',4,['gzyinghun']], + menghuo: ["male", "shu", 4, ["manyi", "zaiqi"]], + zhurong: ["female", "shu", 4, ["manyi", "lieren"]], + xuhuang: ["male", "wei", 4, ["sgduanliang"]], + sunjian: ["male", "wu", 4, ["gzyinghun"]], - jiangwei:['male','shu',4,['tiaoxin']], + jiangwei: ["male", "shu", 4, ["tiaoxin"]], - hejin:['male','qun',4,['mouzhu','yanhuo']], - hansui:['male','qun',4,['xiaoxi','niluan']], - niujin:['male','wei',4,['cuorui','liewei']], + hejin: ["male", "qun", 4, ["mouzhu", "yanhuo"]], + hansui: ["male", "qun", 4, ["xiaoxi", "niluan"]], + niujin: ["male", "wei", 4, ["cuorui", "liewei"]], - jin_zhangchunhua:['female','jin',3,['huishi','qingleng']], - jin_simayi:['male','jin',3,['smyyingshi','xiongzhi','quanbian']], - jin_wangyuanji:['female','jin',3,['yanxi']], - jin_simazhao:['male','jin',3,['choufa','zhaoran']], - jin_xiahouhui:['female','jin',3,['jyishi','shiduo']], - jin_simashi:['male','jin','3/4',['yimie','tairan']], - zhanghuyuechen:['male','jin',4,['xijue']], - duyu:['male','jin',4,['sanchen','zhaotao']], + jin_zhangchunhua: ["female", "jin", 3, ["huishi", "qingleng"]], + jin_simayi: ["male", "jin", 3, ["smyyingshi", "xiongzhi", "quanbian"]], + jin_wangyuanji: ["female", "jin", 3, ["yanxi"]], + jin_simazhao: ["male", "jin", 3, ["choufa", "zhaoran"]], + jin_xiahouhui: ["female", "jin", 3, ["jyishi", "shiduo"]], + jin_simashi: ["male", "jin", "3/4", ["yimie", "tairan"]], + zhanghuyuechen: ["male", "jin", 4, ["xijue"]], + duyu: ["male", "jin", 4, ["sanchen", "zhaotao"]], }, - startBefore:function(){ - - }, - onreinit:function(){ - _status.mode=_status.connectMode?lib.configOL.single_mode:get.config('single_mode'); - if(_status.mode!='normal') return; - for(var i in lib.characterSingle){ - lib.character[i]=lib.characterSingle[i]; - if(!lib.character[i][4]){ - lib.character[i][4]=[]; + startBefore: function () {}, + onreinit: function () { + _status.mode = _status.connectMode ? lib.configOL.single_mode : get.config("single_mode"); + if (_status.mode != "normal") return; + for (var i in lib.characterSingle) { + lib.character[i] = lib.characterSingle[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; } } - for(var j in lib.singleTranslate) lib.translate[j]=lib.singleTranslate[j]; + for (var j in lib.singleTranslate) lib.translate[j] = lib.singleTranslate[j]; }, - start:function(){ - "step 0" - _status.mode=_status.connectMode?lib.configOL.single_mode:get.config('single_mode'); - var playback=localStorage.getItem(lib.configprefix+'playback'); - if(playback){ + start: function () { + "step 0"; + _status.mode = _status.connectMode ? lib.configOL.single_mode : get.config("single_mode"); + var playback = localStorage.getItem(lib.configprefix + "playback"); + if (playback) { ui.create.me(); - ui.arena.style.display='none'; - ui.system.style.display='none'; - _status.playback=playback; - localStorage.removeItem(lib.configprefix+'playback'); - var store=lib.db.transaction(['video'],'readwrite').objectStore('video'); - store.get(parseInt(playback)).onsuccess=function(e){ - if(e.target.result){ + ui.arena.style.display = "none"; + ui.system.style.display = "none"; + _status.playback = playback; + localStorage.removeItem(lib.configprefix + "playback"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + store.get(parseInt(playback)).onsuccess = function (e) { + if (e.target.result) { game.playVideoContent(e.target.result.video); - } - else{ - alert('播放失败:找不到录像'); + } else { + alert("播放失败:找不到录像"); game.reload(); } - } + }; event.finish(); - } - else if(!_status.connectMode){ + } else if (!_status.connectMode) { game.prepareArena(2); } - "step 1" - if(_status.connectMode){ - game.waitForPlayer(function(){ - lib.configOL.number=2; + "step 1"; + if (_status.connectMode) { + game.waitForPlayer(function () { + lib.configOL.number = 2; }); } - "step 2" - if(_status.mode=='normal'){ - lib.card.list=lib.singlePile.slice(0); - game.fixedPile=true; - game.broadcastAll(function(singleTranslate,characterSingle,jin){ - _status.mode='normal'; - for(var j in singleTranslate) lib.translate[j]=singleTranslate[j]; - _status.characterlist=[]; - for(var i in characterSingle){ - if(!jin&&characterSingle[i][1]=='jin') continue; - lib.character[i]=characterSingle[i]; - if(!lib.character[i][4]){ - lib.character[i][4]=[]; + "step 2"; + if (_status.mode == "normal") { + lib.card.list = lib.singlePile.slice(0); + game.fixedPile = true; + game.broadcastAll( + function (singleTranslate, characterSingle, jin) { + _status.mode = "normal"; + for (var j in singleTranslate) lib.translate[j] = singleTranslate[j]; + _status.characterlist = []; + for (var i in characterSingle) { + if (!jin && characterSingle[i][1] == "jin") continue; + lib.character[i] = characterSingle[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; + } + _status.characterlist.push(i); } - _status.characterlist.push(i); - } - },lib.singleTranslate,lib.characterSingle,_status.connectMode?lib.configOL.enable_jin:get.config('enable_jin')); - } - else if(_status.mode=='changban'){ - _status.characterlist=[]; - for(var i=0;i_status.characterlist=list,list); + _status.characterlist = list; + game.broadcast((list) => (_status.characterlist = list), list); } - if(_status.connectMode){ - lib.configOL.number=2; + if (_status.connectMode) { + lib.configOL.number = 2; game.randomMapOL(); - } - else{ - for(var i=0;icurrent.showGiveup(),true); + game.countPlayer((current) => current.showGiveup(), true); }, - game:{ - canReplaceViewpoint:()=>true, - addRecord:function(bool){ - if(typeof bool=='boolean'){ - var mode=_status.mode; - var data=lib.config.gameRecord.single.data; - if(!get.is.object(data[mode])) data[mode]={}; - var data2=data[mode] - var identity=game.me.identity; - if(!data2[identity]){ - data2[identity]=[0,0]; + game: { + canReplaceViewpoint: () => true, + addRecord: function (bool) { + if (typeof bool == "boolean") { + var mode = _status.mode; + var data = lib.config.gameRecord.single.data; + if (!get.is.object(data[mode])) data[mode] = {}; + var data2 = data[mode]; + var identity = game.me.identity; + if (!data2[identity]) { + data2[identity] = [0, 0]; } - if(bool){ + if (bool) { data2[identity][0]++; - } - else{ + } else { data2[identity][1]++; } - var list=['zhu','fan']; - var str=''; - for(var j in data){ - str+=get.translation(j+2)+':
                        '; - for(var i=0;i'; + var list = ["zhu", "fan"]; + var str = ""; + for (var j in data) { + str += get.translation(j + 2) + ":
                        "; + for (var i = 0; i < list.length; i++) { + if (data[j][list[i]]) { + str += + lib.translate[list[i] + "2"] + + ":" + + data[j][list[i]][0] + + "胜" + + " " + + data[j][list[i]][1] + + "负
                        "; } } } - lib.config.gameRecord.single.str=str; - game.saveConfig('gameRecord',lib.config.gameRecord); + lib.config.gameRecord.single.str = str; + game.saveConfig("gameRecord", lib.config.gameRecord); } }, - getState:function(){ - var state={}; - for(var i in lib.playerOL){ - var player=lib.playerOL[i]; - state[i]={identity:player.identity}; + getState: function () { + var state = {}; + for (var i in lib.playerOL) { + var player = lib.playerOL[i]; + state[i] = { identity: player.identity }; } return state; }, - updateState:function(state){ - for(var i in state){ - var player=lib.playerOL[i]; - if(player){ - player.identity=state[i].identity; + updateState: function (state) { + for (var i in state) { + var player = lib.playerOL[i]; + if (player) { + player.identity = state[i].identity; } } }, - getRoomInfo:function(uiintro){ - if(lib.configOL.single_mode=='normal') uiintro.add('
                        晋势力武将:'+(lib.configOL.enable_jin?'开启':'关闭')); - if(lib.configOL.bannedcards.length){ - uiintro.add('
                        禁用卡牌:'+get.translation(lib.configOL.bannedcards)); + getRoomInfo: function (uiintro) { + if (lib.configOL.single_mode == "normal") + uiintro.add( + '
                        晋势力武将:' + (lib.configOL.enable_jin ? "开启" : "关闭") + ); + if (lib.configOL.bannedcards.length) { + uiintro.add( + '
                        禁用卡牌:' + get.translation(lib.configOL.bannedcards) + ); } - uiintro.style.paddingBottom='8px'; + uiintro.style.paddingBottom = "8px"; }, - getVideoName:function(){ - var str=get.translation(game.me.name); - if(game.me.name2){ - str+='/'+get.translation(game.me.name2); + getVideoName: function () { + var str = get.translation(game.me.name); + if (game.me.name2) { + str += "/" + get.translation(game.me.name2); } - var name=[ + var name = [ str, - get.translation(_status.mode+2)+' - '+lib.translate[game.me.identity+'2'] + get.translation(_status.mode + 2) + " - " + lib.translate[game.me.identity + "2"], ]; return name; }, - showIdentity:function(){}, - checkResult:function(){ - game.over((game.me._trueMe||game.me).isAlive()); + showIdentity: function () {}, + checkResult: function () { + game.over((game.me._trueMe || game.me).isAlive()); }, - checkOnlineResult:function(player){ + checkOnlineResult: function (player) { return player.isAlive(); }, - chooseCharacterDianjiang:function(){ - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - "step 0" - ui.arena.classList.add('choose-character'); + chooseCharacterDianjiang: function () { + var next = game.createEvent("chooseCharacter"); + next.showConfig = true; + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); lib.init.onfree(); - "step 1" - game.me.chooseControl('先手','后手').prompt='请选择自己的行动顺序'; - "step 2" - var map=result.control=='先手'?['zhu','fan']:['fan','zhu']; - game.me.identity=map[0]; - game.me.next.identity=map[1]; + "step 1"; + game.me.chooseControl("先手", "后手").prompt = "请选择自己的行动顺序"; + "step 2"; + var map = result.control == "先手" ? ["zhu", "fan"] : ["fan", "zhu"]; + game.me.identity = map[0]; + game.me.next.identity = map[1]; game.me.showIdentity(); game.me.next.showIdentity(); - "step 3" - event.flipassign=true; - event.videoId=lib.status.videoId++; - var list=[]; - for(var i in lib.character){ - if(lib.filter.characterDisabled(i)) continue; + "step 3"; + event.flipassign = true; + event.videoId = lib.status.videoId++; + var list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled(i)) continue; list.push(i); } - _status.characterlist=list; - var filter=function(name){ + _status.characterlist = list; + var filter = function (name) { return !_status.characterlist.includes(name); }; - var dialog=ui.create.characterDialog('heightset',filter).open(); - dialog.videoId=event.videoId; + var dialog = ui.create.characterDialog("heightset", filter).open(); + dialog.videoId = event.videoId; - game.me.chooseButton(true).set('ai',function(button){ - return Math.random(); - }).set('dialog',event.videoId); - "step 4" + game.me + .chooseButton(true) + .set("ai", function (button) { + return Math.random(); + }) + .set("dialog", event.videoId); + "step 4"; game.me.init(result.links[0]); _status.characterlist.remove(result.links[0]); game.addRecentCharacter(result.links[0]); - game.me.chooseButton(true).set('ai',function(button){ - return Math.random(); - }).set('dialog',event.videoId); - "step 5" - game.broadcastAll('closeDialog',event.videoId); + game.me + .chooseButton(true) + .set("ai", function (button) { + return Math.random(); + }) + .set("dialog", event.videoId); + "step 5"; + game.broadcastAll("closeDialog", event.videoId); game.me.next.init(result.links[0]); _status.characterlist.remove(result.links[0]); game.addRecentCharacter(result.links[0]); - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); }); }, - chooseCharacterWuxianhuoli(){ - const next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - 'step 0' - ui.arena.classList.add('choose-character'); + chooseCharacterWuxianhuoli() { + const next = game.createEvent("chooseCharacter"); + next.showConfig = true; + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); lib.init.onfree(); - var num=[0,1].randomGet(); - game.players[num].identity='zhu'; - game.players[1-num].identity='fan'; - game.broadcastAll(function(p,t){ - p.enemy=t;t.enemy=p; - },game.players[0],game.players[1]); - for(var i=0;i本局游戏Buff
                        ', - ]; - game.globalBuff.forEach((buff,ind)=>{ - dialog.add(`
                        「${ind===0?'固定':'随机'}」 ${get.translation(buff)}:${get.skillInfoTranslation(buff)}
                        `); + const dialog = ["请选择出场武将", '
                        本局游戏Buff
                        ']; + game.globalBuff.forEach((buff, ind) => { + dialog.add( + `
                        「${ind === 0 ? "固定" : "随机"}」 ${get.translation( + buff + )}:${get.skillInfoTranslation(buff)}
                        ` + ); }); - dialog.add([_status.characterChoice[game.me.identity],'character']); - game.me.chooseButton(true,dialog); - 'step 2' + dialog.add([_status.characterChoice[game.me.identity], "character"]); + game.me.chooseButton(true, dialog); + "step 2"; game.me.init(result.links[0]); _status.characterChoice[game.me.identity].removeArray(result.links); - var list=_status.characterChoice[game.me.enemy.identity].randomRemove(1); + var list = _status.characterChoice[game.me.enemy.identity].randomRemove(1); game.me.enemy.init(list[0]); - [game.me,game.me.enemy].forEach(current=>{ - if(current.storage.nohp||lib.character[current.name1][4].includes('hiddenSkill')&&!current.noclick){ - current.storage.rawHp=1; - current.storage.rawMaxHp=1; + [game.me, game.me.enemy].forEach((current) => { + if ( + current.storage.nohp || + (lib.character[current.name1][4].includes("hiddenSkill") && !current.noclick) + ) { + current.storage.rawHp = 1; + current.storage.rawMaxHp = 1; } - current.hp=10; - current.maxHp=10; - current.hujia=0; + current.hp = 10; + current.maxHp = 10; + current.hujia = 0; current.update(); }); - game.globalBuff.forEach(buff=>{ + game.globalBuff.forEach((buff) => { game.addGlobalSkill(buff); }); - game.addGlobalSkill('wuxianhuoli_task'); - _status.wuxianhuoliProgress=0; - _status.wuxianhuoliLevel=0; - const func=()=>{ - ui.wuxianhuoliProgress=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - ui.wuxianhuoliProgress.innerHTML='任务进度(0/3)'; - const showTasks=()=>{ - if(ui.wuxianhuoliInfo) return; - ui.wuxianhuoliInfo=ui.create.system('无限火力',null,true); - ui.wuxianhuoliInfo.currentProgress=0; - ui.wuxianhuoliInfo.currentLevel=0; - lib.setPopped(ui.wuxianhuoliInfo,()=>{ - var uiintro=ui.create.dialog('hidden'); - uiintro.add(`
                        任务列表
                        `); - if(typeof _status.wuxianhuoliLevel!=='number'){ - uiintro.add(`
                        未获取当前进度,请于一名角色受伤后再查看
                        `); - } - else if(_status.wuxianhuoliLevel<2){ - uiintro.add(`
                        全场角色造成${_status.wuxianhuoliLevel===0?3:5}点伤害(当前${_status.wuxianhuoliProgress}点)
                        \ + game.addGlobalSkill("wuxianhuoli_task"); + _status.wuxianhuoliProgress = 0; + _status.wuxianhuoliLevel = 0; + const func = () => { + ui.wuxianhuoliProgress = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + ui.wuxianhuoliProgress.innerHTML = "任务进度(0/3)"; + const showTasks = () => { + if (ui.wuxianhuoliInfo) return; + ui.wuxianhuoliInfo = ui.create.system("无限火力", null, true); + ui.wuxianhuoliInfo.currentProgress = 0; + ui.wuxianhuoliInfo.currentLevel = 0; + lib.setPopped( + ui.wuxianhuoliInfo, + () => { + var uiintro = ui.create.dialog("hidden"); + uiintro.add( + `
                        任务列表
                        ` + ); + if (typeof _status.wuxianhuoliLevel !== "number") { + uiintro.add( + `
                        未获取当前进度,请于一名角色受伤后再查看
                        ` + ); + } else if (_status.wuxianhuoliLevel < 2) { + uiintro.add(`
                        全场角色造成${ + _status.wuxianhuoliLevel === 0 ? 3 : 5 + }点伤害(当前${_status.wuxianhuoliProgress}点)
                        \
                        奖励:获得一个技能,摸两张牌
                        `); - } - else{ - uiintro.add(`
                        所有任务已完成,无后续任务
                        `); - } - uiintro.add(`
                        全局Buff
                        `); - uiintro.add(`
                        ${game.globalBuff.map((buff,ind)=>{ - return get.translation(buff)+':'+get.skillInfoTranslation(buff); - }).join('
                        ')}
                        `); - var ul=uiintro.querySelector('ul'); - if(ul) ul.style.width='180px'; - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + } else { + uiintro.add( + `
                        所有任务已完成,无后续任务
                        ` + ); + } + uiintro.add( + `
                        全局Buff
                        ` + ); + uiintro.add( + `
                        ${game.globalBuff + .map((buff, ind) => { + return ( + get.translation(buff) + + ":" + + get.skillInfoTranslation(buff) + ); + }) + .join("
                        ")}
                        ` + ); + var ul = uiintro.querySelector("ul"); + if (ul) ul.style.width = "180px"; + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); }; showTasks(); - var dialog=ui.create.dialog('hidden','forcebutton'); + var dialog = ui.create.dialog("hidden", "forcebutton"); dialog.add(`任务一`); dialog.addText(`任务:全场角色共计造成3点伤害
                        奖励:获得一个技能,摸两张牌`); dialog.add(`任务二
                        (完成任务一后解锁)
                        \
                        任务:全场角色共计造成5点伤害
                        奖励:获得一个技能,摸两张牌
                        `); dialog.open(); - setTimeout(()=>{ + setTimeout(() => { dialog.close(); - },3000); + }, 3000); }; game.broadcastAll(func); - game.delay(0,3000); - 'step 3' + game.delay(0, 3000); + "step 3"; _status.characterlist.addArray(Object.values(_status.characterChoice).flat()); - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); }); }, - chooseCharacter:function(){ - if(_status.mode=='dianjiang'){ + chooseCharacter: function () { + if (_status.mode == "dianjiang") { game.chooseCharacterDianjiang(); return; } - if(_status.mode=='wuxianhuoli'){ + if (_status.mode == "wuxianhuoli") { game.chooseCharacterWuxianhuoli(); return; } - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - "step 0" - ui.arena.classList.add('choose-character'); - var num=[0,1].randomGet(); - game.players[num].identity='zhu'; - game.players[1-num].identity='fan'; - game.broadcastAll(function(p,t){ - p.enemy=t;t.enemy=p; - },game.players[0],game.players[1]); - for(var i=0;i{game.globalBuff=buff}; - game.broadcast(setBuff,game.globalBuff); - if(!_status.postReconnect.wuxianhuoliBuff) _status.postReconnect.wuxianhuoliBuff=[setBuff,[]]; - _status.postReconnect.wuxianhuoliBuff[1].addArray(game.globalBuff); - 'step 1' - _status.characterChoice={ - zhu:_status.characterlist.randomRemove(6), - fan:_status.characterlist.randomRemove(6), + const setBuff = (buff) => { + game.globalBuff = buff; }; - const list=['zhu','fan'].map(identity=>{ - const dialog=[ - '请选择出场武将', - '
                        本局游戏Buff
                        ', - ]; - game.globalBuff.forEach((buff,ind)=>{ - dialog.add(`
                        「${ind===0?'固定':'随机'}」 ${get.translation(buff)}:${get.skillInfoTranslation(buff)}
                        `); + game.broadcast(setBuff, game.globalBuff); + if (!_status.postReconnect.wuxianhuoliBuff) + _status.postReconnect.wuxianhuoliBuff = [setBuff, []]; + _status.postReconnect.wuxianhuoliBuff[1].addArray(game.globalBuff); + "step 1"; + _status.characterChoice = { + zhu: _status.characterlist.randomRemove(6), + fan: _status.characterlist.randomRemove(6), + }; + const list = ["zhu", "fan"].map((identity) => { + const dialog = ["请选择出场武将", '
                        本局游戏Buff
                        ']; + game.globalBuff.forEach((buff, ind) => { + dialog.add( + `
                        「${ind === 0 ? "固定" : "随机"}」 ${get.translation( + buff + )}:${get.skillInfoTranslation(buff)}
                        ` + ); }); - dialog.add([_status.characterChoice[identity],'character']); - return [game[identity],true,dialog]; + dialog.add([_status.characterChoice[identity], "character"]); + return [game[identity], true, dialog]; }); - game.me.chooseButtonOL(list,function(player,result){ - if(game.online||player==game.me){ + game.me.chooseButtonOL(list, function (player, result) { + if (game.online || player == game.me) { player.init(result.links[0]); - player.hp=10; - player.maxHp=10; - player.hujia=0; + player.hp = 10; + player.maxHp = 10; + player.hujia = 0; player.update(); } }); - 'step 2' - for(var i in result){ - var current=lib.playerOL[i]; - if(result[i]=='ai'){ - result[i]=_status.characterChoice[current.identity].randomGets(1); - } - else{ - result[i]=result[i].links; + "step 2"; + for (var i in result) { + var current = lib.playerOL[i]; + if (result[i] == "ai") { + result[i] = _status.characterChoice[current.identity].randomGets(1); + } else { + result[i] = result[i].links; } _status.characterChoice[current.identity].removeArray(result[i]); - if(!current.name){ + if (!current.name) { current.init(result[i][0]); - if(current.storage.nohp||lib.character[current.name1][4].includes('hiddenSkill')&&!current.noclick){ - current.storage.rawHp=1; - current.storage.rawMaxHp=1; + if ( + current.storage.nohp || + (lib.character[current.name1][4].includes("hiddenSkill") && !current.noclick) + ) { + current.storage.rawHp = 1; + current.storage.rawMaxHp = 1; } - current.hp=10; - current.maxHp=10; - current.hujia=0; + current.hp = 10; + current.maxHp = 10; + current.hujia = 0; current.update(); } } - game.broadcast(function(result){ - for(var i in result){ - const current=lib.playerOL[i]; - if(!current.name){ + game.broadcast(function (result) { + for (var i in result) { + const current = lib.playerOL[i]; + if (!current.name) { current.init(result[i][0]); - if(current.storage.nohp||lib.character[current.name1][4].includes('hiddenSkill')&&!current.noclick){ - current.storage.rawHp=1; - current.storage.rawMaxHp=1; + if ( + current.storage.nohp || + (lib.character[current.name1][4].includes("hiddenSkill") && + !current.noclick) + ) { + current.storage.rawHp = 1; + current.storage.rawMaxHp = 1; } - current.hp=10; - current.maxHp=10; - current.hujia=0; + current.hp = 10; + current.maxHp = 10; + current.hujia = 0; current.update(); } } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); - },result); - game.globalBuff.forEach(buff=>{ + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + }, result); + game.globalBuff.forEach((buff) => { game.addGlobalSkill(buff); }); - game.addGlobalSkill('wuxianhuoli_task'); - game.broadcastAll(()=>{ - _status.wuxianhuoliProgress=0; - _status.wuxianhuoliLevel=0; + game.addGlobalSkill("wuxianhuoli_task"); + game.broadcastAll(() => { + _status.wuxianhuoliProgress = 0; + _status.wuxianhuoliLevel = 0; }); - const func=()=>{ - ui.wuxianhuoliProgress=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - ui.wuxianhuoliProgress.innerHTML='任务进度(0/3)'; - const showTasks=()=>{ - if(ui.wuxianhuoliInfo) return; - ui.wuxianhuoliInfo=ui.create.system('无限火力',null,true); - ui.wuxianhuoliInfo.currentProgress=0; - ui.wuxianhuoliInfo.currentLevel=0; - lib.setPopped(ui.wuxianhuoliInfo,()=>{ - var uiintro=ui.create.dialog('hidden'); - uiintro.add(`
                        任务列表
                        `); - if(typeof _status.wuxianhuoliLevel!=='number'){ - uiintro.add(`
                        未获取当前进度,请于一名角色受伤后再查看
                        `); - } - else if(_status.wuxianhuoliLevel<2){ - uiintro.add(`
                        全场角色造成${_status.wuxianhuoliLevel===0?3:5}点伤害(当前${_status.wuxianhuoliProgress}点)
                        \ + const func = () => { + ui.wuxianhuoliProgress = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + ui.wuxianhuoliProgress.innerHTML = "任务进度(0/3)"; + const showTasks = () => { + if (ui.wuxianhuoliInfo) return; + ui.wuxianhuoliInfo = ui.create.system("无限火力", null, true); + ui.wuxianhuoliInfo.currentProgress = 0; + ui.wuxianhuoliInfo.currentLevel = 0; + lib.setPopped( + ui.wuxianhuoliInfo, + () => { + var uiintro = ui.create.dialog("hidden"); + uiintro.add( + `
                        任务列表
                        ` + ); + if (typeof _status.wuxianhuoliLevel !== "number") { + uiintro.add( + `
                        未获取当前进度,请于一名角色受伤后再查看
                        ` + ); + } else if (_status.wuxianhuoliLevel < 2) { + uiintro.add(`
                        全场角色造成${ + _status.wuxianhuoliLevel === 0 ? 3 : 5 + }点伤害(当前${_status.wuxianhuoliProgress}点)
                        \
                        奖励:获得一个技能,摸两张牌
                        `); - } - else{ - uiintro.add(`
                        所有任务已完成,无后续任务
                        `); - } - uiintro.add(`
                        全局Buff
                        `); - uiintro.add(`
                        ${game.globalBuff.map((buff,ind)=>{ - return get.translation(buff)+':'+get.skillInfoTranslation(buff); - }).join('
                        ')}
                        `); - var ul=uiintro.querySelector('ul'); - if(ul) ul.style.width='180px'; - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + } else { + uiintro.add( + `
                        所有任务已完成,无后续任务
                        ` + ); + } + uiintro.add( + `
                        全局Buff
                        ` + ); + uiintro.add( + `
                        ${game.globalBuff + .map((buff, ind) => { + return ( + get.translation(buff) + + ":" + + get.skillInfoTranslation(buff) + ); + }) + .join("
                        ")}
                        ` + ); + var ul = uiintro.querySelector("ul"); + if (ul) ul.style.width = "180px"; + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); }; showTasks(); - if(!_status.postReconnect.wuxianhuoliShowTasks) _status.postReconnect.wuxianhuoliShowTasks=[showTasks,[]]; - const dialog=ui.create.dialog('hidden','forcebutton'); + if (!_status.postReconnect.wuxianhuoliShowTasks) + _status.postReconnect.wuxianhuoliShowTasks = [showTasks, []]; + const dialog = ui.create.dialog("hidden", "forcebutton"); dialog.add(`任务一`); dialog.addText(`任务:全场角色共计造成3点伤害
                        奖励:获得一个技能,摸两张牌`); dialog.add(`任务二
                        (完成任务一后解锁)
                        \
                        任务:全场角色共计造成5点伤害
                        奖励:获得一个技能,摸两张牌
                        `); dialog.open(); - setTimeout(()=>{ + setTimeout(() => { dialog.close(); - },3000); + }, 3000); }; game.broadcastAll(func); - game.delay(0,3000); - 'step 3' + game.delay(0, 3000); + "step 3"; _status.characterlist.addArray(Object.values(_status.characterChoice).flat()); - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); }); }, - chooseCharacterOL:function(){ - if(_status.mode=='dianjiang'){ + chooseCharacterOL: function () { + if (_status.mode == "dianjiang") { game.chooseCharacterDianjiangOL(); return; } - if(_status.mode=='wuxianhuoli'){ + if (_status.mode == "wuxianhuoli") { game.chooseCharacterWuxianhuoliOL(); return; } - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - "step 0" - ui.arena.classList.add('choose-character'); - var num=[0,1].randomGet(); - game.players[num].identity='zhu'; - game.players[1-num].identity='fan'; - game.broadcastAll(function(p,t){ - p.enemy=t;t.enemy=p; - },game.players[0],game.players[1]); - for(var i=0;i=12; - })&&get.effect(target,{name:'juedou'},player,player)>0) return -1; + ai: { + order: 1, + result: { + target: function (player, target) { + if ( + player.countCards("h", function (card) { + return get.value(card) <= 5 && get.number(card) >= 12; + }) && + get.effect(target, { name: "juedou" }, player, player) > 0 + ) + return -1; return 0; }, }, }, }, - huwei:{ - audio:2, - trigger:{ - player:'enterGame', - global:'gameDrawAfter', + huwei: { + audio: 2, + trigger: { + player: "enterGame", + global: "gameDrawAfter", }, - direct:true, - content:function(){ - player.chooseUseTarget('shuiyanqijunx',get.prompt('huwei'),'视为使用一张【水淹七军】').logSkill='huwei'; + direct: true, + content: function () { + player.chooseUseTarget( + "shuiyanqijunx", + get.prompt("huwei"), + "视为使用一张【水淹七军】" + ).logSkill = "huwei"; }, }, - sgkuanggu:{ - audio:'kuanggu', - trigger:{source:'damageSource'}, - frequent:true, - filter:function(event,player){ + sgkuanggu: { + audio: "kuanggu", + trigger: { source: "damageSource" }, + frequent: true, + filter: function (event, player) { return player.isDamaged(); }, - content:function(){ - 'step 0' - player.judge(function(result){ - return get.color(result)=='black'?2:-2; + content: function () { + "step 0"; + player.judge(function (result) { + return get.color(result) == "black" ? 2 : -2; }); - 'step 1' - if(result.bool==true) player.recover(); + "step 1"; + if (result.bool == true) player.recover(); }, }, - suzi:{ - inherit:'xingshang', + suzi: { + inherit: "xingshang", }, - cangji:{ - trigger:{player:'die'}, - filter:function(event,player){ - return player.countCards('e')>0; + cangji: { + trigger: { player: "die" }, + filter: function (event, player) { + return player.countCards("e") > 0; }, - forceDie:true, - skillAnimation:true, - animationColor:'orange', - content:function(){ - var cards=player.getCards('e'); - player.cangji_yozuru=cards; - player.lose(cards,ui.special); - player.addSkill('cangji_yozuru'); + forceDie: true, + skillAnimation: true, + animationColor: "orange", + content: function () { + var cards = player.getCards("e"); + player.cangji_yozuru = cards; + player.lose(cards, ui.special); + player.addSkill("cangji_yozuru"); }, - subSkill:{ - yozuru:{ - sub:true, - charlotte:true, - superCharlotte:true, - trigger:{player:'enterGame'}, - forced:true, - popup:false, + subSkill: { + yozuru: { + sub: true, + charlotte: true, + superCharlotte: true, + trigger: { player: "enterGame" }, + forced: true, + popup: false, //onremove:true, - content:function(){ - var cards=player.cangji_yozuru.slice(0); - for(var i=0;i{ - if(evt.name!=='damage') return false; - return evt.card&&evt.card.name==='sha'; - }).indexOf(event)===0; - }, - forced:true, - silent:true, - popup:true, - charlotte:true, - async content(_,trigger){ - trigger.increase('num'); - }, - }, - wuxianhuoli_liuanhuaming:{ - trigger:{ - player:'loseAfter', - global:['equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'], - }, - filter(event,player){ - if(player===_status.currentPhase) return false; - const evt=event.getl(player); - return evt.cards2&&evt.cards2.length>0; - }, - forced:true, - silent:true, - popup:true, - charlotte:true, - usable:2, - async content(_,__,player){ - player.draw(); - }, - }, - wuxianhuoli_mianmianjudao:{ - trigger:{player:'phaseZhunbeiBegin'}, - forced:true, - silent:true, - popup:true, - charlotte:true, - async content(_,__,player){ - const cards=[]; - for(const type of ['basic','trick']){ - const card=get.cardPile(card=>{ - const typex=get.type2(card,false); - return type===typex; - }); - if(card) cards.add(card); + content: function () { + "step 0"; + player.chooseBool("是否更换手牌?").ai = function () { + var hs = player.getCards("h"); + return get.value(hs, "raw") < 6 * hs; + }; + "step 1"; + if (result.bool) { + var hs = player.getCards("h"); + player.lose(hs, ui.special); + event.hs = hs; + } else event.finish(); + "step 2"; + var hs = event.hs; + player.draw(hs.length, "nodelay"); + for (var i = 0; i < hs.length; i++) { + hs[i].fix(); + ui.cardPile.insertBefore( + hs[i], + ui.cardPile.childNodes[get.rand(ui.cardPile.childElementCount)] + ); } - if(cards.length) player.gain(cards,'gain2'); }, }, - wuxianhuoli_task:{ - trigger:{source:'damageAfter'}, - forced:true, - popup:false, - silent:true, - charlotte:true, - async content(event,trigger,player){ - if(!_status.wuxianhuoliProgress) _status.wuxianhuoliProgress=0; - if(!_status.wuxianhuoliLevel) _status.wuxianhuoliLevel=0; - if(_status.wuxianhuoliLevel>1) return; - _status.wuxianhuoliProgress+=trigger.num; - game.broadcastAll((num,level)=>{ - _status.wuxianhuoliProgress=num; - _status.wuxianhuoliLevel=level; - if(!ui.wuxianhuoliProgress){ - ui.wuxianhuoliProgress=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - } - ui.wuxianhuoliProgress.innerHTML='任务进度('+num+'/'+(level===0?3:5)+')'; - },_status.wuxianhuoliProgress,_status.wuxianhuoliLevel); - if(_status.wuxianhuoliProgress<(_status.wuxianhuoliLevel===0?3:5)) return; - game.broadcastAll(()=>{ - _status.wuxianhuoliProgress=0; + wuxianhuoli_weisuoyuwei: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + silent: true, + popup: true, + charlotte: true, + async content(_, __, player) { + player.draw(); + }, + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") return num + 1; + }, + }, + }, + wuxianhuoli_duoduoyishan: { + trigger: { global: "phaseEnd" }, + forced: true, + silent: true, + popup: true, + charlotte: true, + async content(_, __, player) { + player.draw(); + }, + }, + wuxianhuoli_xushidaifa: { + trigger: { source: "damageBegin1" }, + filter(event, player) { + if (!event.card || event.card.name !== "sha") return false; + return ( + game + .getGlobalHistory("everything", (evt) => { + if (evt.name !== "damage") return false; + return evt.card && evt.card.name === "sha"; + }) + .indexOf(event) === 0 + ); + }, + forced: true, + silent: true, + popup: true, + charlotte: true, + async content(_, trigger) { + trigger.increase("num"); + }, + }, + wuxianhuoli_liuanhuaming: { + trigger: { + player: "loseAfter", + global: [ + "equipAfter", + "addJudgeAfter", + "gainAfter", + "loseAsyncAfter", + "addToExpansionAfter", + ], + }, + filter(event, player) { + if (player === _status.currentPhase) return false; + const evt = event.getl(player); + return evt.cards2 && evt.cards2.length > 0; + }, + forced: true, + silent: true, + popup: true, + charlotte: true, + usable: 2, + async content(_, __, player) { + player.draw(); + }, + }, + wuxianhuoli_mianmianjudao: { + trigger: { player: "phaseZhunbeiBegin" }, + forced: true, + silent: true, + popup: true, + charlotte: true, + async content(_, __, player) { + const cards = []; + for (const type of ["basic", "trick"]) { + const card = get.cardPile((card) => { + const typex = get.type2(card, false); + return type === typex; + }); + if (card) cards.add(card); + } + if (cards.length) player.gain(cards, "gain2"); + }, + }, + wuxianhuoli_task: { + trigger: { source: "damageAfter" }, + forced: true, + popup: false, + silent: true, + charlotte: true, + async content(event, trigger, player) { + if (!_status.wuxianhuoliProgress) _status.wuxianhuoliProgress = 0; + if (!_status.wuxianhuoliLevel) _status.wuxianhuoliLevel = 0; + if (_status.wuxianhuoliLevel > 1) return; + _status.wuxianhuoliProgress += trigger.num; + game.broadcastAll( + (num, level) => { + _status.wuxianhuoliProgress = num; + _status.wuxianhuoliLevel = level; + if (!ui.wuxianhuoliProgress) { + ui.wuxianhuoliProgress = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + } + ui.wuxianhuoliProgress.innerHTML = + "任务进度(" + num + "/" + (level === 0 ? 3 : 5) + ")"; + }, + _status.wuxianhuoliProgress, + _status.wuxianhuoliLevel + ); + if (_status.wuxianhuoliProgress < (_status.wuxianhuoliLevel === 0 ? 3 : 5)) return; + game.broadcastAll(() => { + _status.wuxianhuoliProgress = 0; _status.wuxianhuoliLevel++; }); let next; - const send=(skills,refreshable,stop=false)=>{ - let next=game.createEvent('wuxianhuoli_reward',false); + const send = (skills, refreshable, stop = false) => { + let next = game.createEvent("wuxianhuoli_reward", false); next.setContent(lib.skill.wuxianhuoli_task.contentx); - next.set('skills',skills); - next.set('refreshable',refreshable); - next.set('includeOut',true); - if(!stop) game.resume(); + next.set("skills", skills); + next.set("refreshable", refreshable); + next.set("includeOut", true); + if (!stop) game.resume(); return next; }; - const sendback=(result,player)=>{ - if(!result) result={}; - if(!result.control&&(typeof result.index!=='number'||result.index<0)){ - result.index=0; + const sendback = (result, player) => { + if (!result) result = {}; + if (!result.control && (typeof result.index !== "number" || result.index < 0)) { + result.index = 0; } - results.push([player,result]); + results.push([player, result]); }; - const ai_targets=[],results=[],players=game.players.slice(),skillsMap={}; - let withme=false,withol=false,withai=false; - for(const current of players){ - if(_status.connectMode) current.showTimer(); - const skills=get.info('wuxianhuoli_task').getSkills(); - const refreshable=!current.storage.wuxianhuoli_refreshed; - skillsMap[current.playerid]=skills; - if(current.isOnline()){ - withol=true; - current.send(send,skills,refreshable); + const ai_targets = [], + results = [], + players = game.players.slice(), + skillsMap = {}; + let withme = false, + withol = false, + withai = false; + for (const current of players) { + if (_status.connectMode) current.showTimer(); + const skills = get.info("wuxianhuoli_task").getSkills(); + const refreshable = !current.storage.wuxianhuoli_refreshed; + skillsMap[current.playerid] = skills; + if (current.isOnline()) { + withol = true; + current.send(send, skills, refreshable); current.wait(sendback); - } - else if(current==game.me){ - withme=true; - next=send(skills,refreshable,true); - if(_status.connectMode) game.me.wait(sendback); - } - else{ + } else if (current == game.me) { + withme = true; + next = send(skills, refreshable, true); + if (_status.connectMode) game.me.wait(sendback); + } else { ai_targets.push(current); } } - if(ai_targets.length){ - for(let i=0;i{ - const interval=setInterval(()=>{ - if(results.length===players.length){ + if (withol && !event.resultOL) { + await new Promise((resolve) => { + const interval = setInterval(() => { + if (results.length === players.length) { resolve(); clearInterval(interval); } - },4); + }, 4); }); } - if(ai_targets.length>0){ - withai=true; - await new Promise((resolve)=>{ - const interval=setInterval(()=>{ - if(results.length===players.length){ + if (ai_targets.length > 0) { + withai = true; + await new Promise((resolve) => { + const interval = setInterval(() => { + if (results.length === players.length) { resolve(); clearInterval(interval); } - },4); + }, 4); }); } - if(_status.connectMode){ - for(var i of players) i.hideTimer(); + if (_status.connectMode) { + for (var i of players) i.hideTimer(); } - const entries=[]; - for(const res of results){ - const target=res[0],result=res[1]; - if(!target||!result) continue; - let skill=result.control; - if(!skill) skill=skillsMap[target.playerid][result.index]; - if(result.refreshed) target.storage.wuxianhuoli_refreshed=true; - entries.push([target,skill]); + const entries = []; + for (const res of results) { + const target = res[0], + result = res[1]; + if (!target || !result) continue; + let skill = result.control; + if (!skill) skill = skillsMap[target.playerid][result.index]; + if (result.refreshed) target.storage.wuxianhuoli_refreshed = true; + entries.push([target, skill]); } - entries.sort((a,b)=>lib.sort.seat(a[0],b[0])); - for(const entry of entries){ + entries.sort((a, b) => lib.sort.seat(a[0], b[0])); + for (const entry of entries) { entry[0].popup(entry[1]); await entry[0].addSkills(entry[1]); } - for(const entry of entries){ - await entry[0].draw(2,'nodelay'); + for (const entry of entries) { + await entry[0].draw(2, "nodelay"); } - game.broadcastAll((num,level)=>{ - if(level===2&&ui.wuxianhuoliProgress){ - ui.wuxianhuoliProgress.innerHTML=''; - return; - } - if(!ui.wuxianhuoliProgress){ - ui.wuxianhuoliProgress=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - } - ui.wuxianhuoliProgress.innerHTML='任务进度('+num+'/'+(level===0?3:5)+')'; - },_status.wuxianhuoliProgress,_status.wuxianhuoliLevel); + game.broadcastAll( + (num, level) => { + if (level === 2 && ui.wuxianhuoliProgress) { + ui.wuxianhuoliProgress.innerHTML = ""; + return; + } + if (!ui.wuxianhuoliProgress) { + ui.wuxianhuoliProgress = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + } + ui.wuxianhuoliProgress.innerHTML = + "任务进度(" + num + "/" + (level === 0 ? 3 : 5) + ")"; + }, + _status.wuxianhuoliProgress, + _status.wuxianhuoliLevel + ); await game.asyncDelay(); }, - getSkills(num=6){ - let allList=_status.characterlist.slice(0); - let list=[]; - let skills=[]; - let map=[]; - let entries=[]; + getSkills(num = 6) { + let allList = _status.characterlist.slice(0); + let list = []; + let skills = []; + let map = []; + let entries = []; allList.randomSort(); - for(let i=0;i=num) break; + if (list.length >= num) break; } return skills; }, - async contentx(event){ - _status.noclearcountdown=true; - const controls=[link=>{ - const evt=get.event(); - evt.result={refresh:true}; - event.control.classList.add('disabled'); - event.control.firstChild.innerText='刷新(1/1)'; - game.resume(); - }]; - event.control=ui.create.control(controls.concat(['刷新(0/1)','stayleft'])); - if(!event.refreshable){ - event.control.classList.add('disabled'); - event.control.firstChild.innerText='刷新(1/1)'; + async contentx(event) { + _status.noclearcountdown = true; + const controls = [ + (link) => { + const evt = get.event(); + evt.result = { refresh: true }; + event.control.classList.add("disabled"); + event.control.firstChild.innerText = "刷新(1/1)"; + game.resume(); + }, + ]; + event.control = ui.create.control(controls.concat(["刷新(0/1)", "stayleft"])); + if (!event.refreshable) { + event.control.classList.add("disabled"); + event.control.firstChild.innerText = "刷新(1/1)"; } - let refreshed=false,result; - while(true){ - const skills=event.skills.slice(3*refreshed,3*(refreshed+1)); - const next=game.me.chooseControl(skills).set('choiceList',skills.map(skill=>{ - return '
                        【'+get.translation(lib.translate[skill+'_ab']||get.translation(skill).slice(0,2))+'】
                        '+ - '
                        '+get.skillInfoTranslation(skill,game.me)+'
                        '; - })).set('displayIndex',false).set('prompt','选择获得一个技能'); - result=await next.forResult(); - if(!result.refresh) break; - refreshed=true; + let refreshed = false, + result; + while (true) { + const skills = event.skills.slice(3 * refreshed, 3 * (refreshed + 1)); + const next = game.me + .chooseControl(skills) + .set( + "choiceList", + skills.map((skill) => { + return ( + '
                        【' + + get.translation( + lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2) + ) + + "】
                        " + + "
                        " + + get.skillInfoTranslation(skill, game.me) + + "
                        " + ); + }) + ) + .set("displayIndex", false) + .set("prompt", "选择获得一个技能"); + result = await next.forResult(); + if (!result.refresh) break; + refreshed = true; } - if(event.control) event.control.close(); - delete _status.noclearcountdown;game.stopCountChoose(); - event.result={control:result.control,refreshed}; + if (event.control) event.control.close(); + delete _status.noclearcountdown; + game.stopCountChoose(); + event.result = { control: result.control, refreshed }; }, }, }, - singleTranslate:{ - xiahouyuan:'夏侯渊', - huangzhong:'黄忠', - weiyan:'魏延', - xiaoqiao:'小乔', - xuhuang:'徐晃', - pangde:'庞德', - zhangjiao:'张角', - old_caoren:'曹仁', - old_zhoutai:'周泰', - shuiyanqijunx_info:'出牌阶段,对一名其他角色使用。目标角色选择一项:1、弃置装备区里的所有牌;2、受到你造成的1点伤害。', - guohe_info:'出牌阶段,对有牌的一名其他角色使用。你选择一项:①弃置其装备区里的一张牌。②观看其手牌并弃置其中的一张。', - shunshou_info:'出牌阶段,对距离为1且有牌的一名其他角色使用。你获得其的一张牌。', + singleTranslate: { + xiahouyuan: "夏侯渊", + huangzhong: "黄忠", + weiyan: "魏延", + xiaoqiao: "小乔", + xuhuang: "徐晃", + pangde: "庞德", + zhangjiao: "张角", + old_caoren: "曹仁", + old_zhoutai: "周泰", + shuiyanqijunx_info: + "出牌阶段,对一名其他角色使用。目标角色选择一项:1、弃置装备区里的所有牌;2、受到你造成的1点伤害。", + guohe_info: + "出牌阶段,对有牌的一名其他角色使用。你选择一项:①弃置其装备区里的一张牌。②观看其手牌并弃置其中的一张。", + shunshou_info: "出牌阶段,对距离为1且有牌的一名其他角色使用。你获得其的一张牌。", }, - translate:{ - zhu:"先", - fan:"后", - zhu2:"先手", - fan2:"后手", - normal2:'新1v1', - changban2:'血战长坂坡', - dianjiang2:'点将单挑', - wuxianhuoli2:'无限火力', + translate: { + zhu: "先", + fan: "后", + zhu2: "先手", + fan2: "后手", + normal2: "新1v1", + changban2: "血战长坂坡", + dianjiang2: "点将单挑", + wuxianhuoli2: "无限火力", - wuxianhuoli_weisuoyuwei:'为所欲为', - wuxianhuoli_weisuoyuwei_info:'①准备阶段,你摸一张牌。②你使用【杀】的次数上限+1。', - wuxianhuoli_duoduoyishan:'多多益善', - wuxianhuoli_duoduoyishan_info:'一名角色的回合结束时,你摸一张牌。', - wuxianhuoli_xushidaifa:'蓄势待发', - wuxianhuoli_xushidaifa_info:'当你于一回合首次造成渠道为【杀】的伤害时,此伤害+1。', - wuxianhuoli_liuanhuaming:'柳暗花明', - wuxianhuoli_liuanhuaming_info:'每回合限两次。当你于回合外失去牌后,你摸一张牌。', - wuxianhuoli_mianmianjudao:'面面俱到', - wuxianhuoli_mianmianjudao_info:'准备阶段,你从牌堆或弃牌堆中获得基本牌和锦囊牌各一张。', + wuxianhuoli_weisuoyuwei: "为所欲为", + wuxianhuoli_weisuoyuwei_info: "①准备阶段,你摸一张牌。②你使用【杀】的次数上限+1。", + wuxianhuoli_duoduoyishan: "多多益善", + wuxianhuoli_duoduoyishan_info: "一名角色的回合结束时,你摸一张牌。", + wuxianhuoli_xushidaifa: "蓄势待发", + wuxianhuoli_xushidaifa_info: "当你于一回合首次造成渠道为【杀】的伤害时,此伤害+1。", + wuxianhuoli_liuanhuaming: "柳暗花明", + wuxianhuoli_liuanhuaming_info: "每回合限两次。当你于回合外失去牌后,你摸一张牌。", + wuxianhuoli_mianmianjudao: "面面俱到", + wuxianhuoli_mianmianjudao_info: "准备阶段,你从牌堆或弃牌堆中获得基本牌和锦囊牌各一张。", - wanrong:'婉容', - wanrong_info:'当你成为【杀】的目标后,你可以摸一张牌。', - sgzhiheng:'制衡', - sgzhiheng_info:'出牌阶段限一次,你可以弃置至多两张牌,然后摸等量的牌。', - xiechan:'挟缠', - xiechan_info:'限定技,出牌阶段,你可以和对手拼点。若你赢/没赢,你/其视为对其/你使用一张【决斗】。', - huwei:'虎威', - huwei_info:'当你登场时,你可以视为使用一张【水淹七军】。', - sgkuanggu:'狂骨', - sgkuanggu_info:'当你造成伤害后,若你已受伤,你可以进行判定:若结果为黑色,你回复1点体力。', - suzi:'肃资', - cangji:'藏机', - cangji_info:'当你死亡时,你可以将装备区内的所有牌移动到游戏外。若如此做,你的下一名角色登场时,你将这些牌置入你的装备区。', - sgrenwang:'仁望', - sgrenwang_info:'当你于一名其他角色的出牌阶段内成为该角色使用的【杀】或普通锦囊牌的目标后,若此牌不是其本阶段内对你使用的第一张【杀】或普通锦囊牌,则你可以弃置该角色的一张牌。', - sgduanliang:'断粮', - sgduanliang_info:'出牌阶段,若你本回合内使用牌指定过其他角色为目标,则你可以将一张黑色基本牌或装备牌当做【兵粮寸断】使用。', - sgqingguo:'倾国', - sgqingguo_info:'你可以将一张装备区内的牌当做【闪】使用或打出。', - pianyi:'翩仪', - pianyi_info:'锁定技,当你于对手的回合内登场时,你结束此回合。', - yinli:'姻礼', - yinli_info:'其他角色的装备牌于其回合内进入弃牌堆后,你可以获得之。', - shenju:'慎拒', - shenju_info:'锁定技,你的手牌上限+X(X为你对手的体力值)。', + wanrong: "婉容", + wanrong_info: "当你成为【杀】的目标后,你可以摸一张牌。", + sgzhiheng: "制衡", + sgzhiheng_info: "出牌阶段限一次,你可以弃置至多两张牌,然后摸等量的牌。", + xiechan: "挟缠", + xiechan_info: + "限定技,出牌阶段,你可以和对手拼点。若你赢/没赢,你/其视为对其/你使用一张【决斗】。", + huwei: "虎威", + huwei_info: "当你登场时,你可以视为使用一张【水淹七军】。", + sgkuanggu: "狂骨", + sgkuanggu_info: "当你造成伤害后,若你已受伤,你可以进行判定:若结果为黑色,你回复1点体力。", + suzi: "肃资", + cangji: "藏机", + cangji_info: + "当你死亡时,你可以将装备区内的所有牌移动到游戏外。若如此做,你的下一名角色登场时,你将这些牌置入你的装备区。", + sgrenwang: "仁望", + sgrenwang_info: + "当你于一名其他角色的出牌阶段内成为该角色使用的【杀】或普通锦囊牌的目标后,若此牌不是其本阶段内对你使用的第一张【杀】或普通锦囊牌,则你可以弃置该角色的一张牌。", + sgduanliang: "断粮", + sgduanliang_info: + "出牌阶段,若你本回合内使用牌指定过其他角色为目标,则你可以将一张黑色基本牌或装备牌当做【兵粮寸断】使用。", + sgqingguo: "倾国", + sgqingguo_info: "你可以将一张装备区内的牌当做【闪】使用或打出。", + pianyi: "翩仪", + pianyi_info: "锁定技,当你于对手的回合内登场时,你结束此回合。", + yinli: "姻礼", + yinli_info: "其他角色的装备牌于其回合内进入弃牌堆后,你可以获得之。", + shenju: "慎拒", + shenju_info: "锁定技,你的手牌上限+X(X为你对手的体力值)。", + }, + help: { + 血战长坂: + '
                        游戏规则
                        • 选将阶段
                          双方在游戏开始时由系统随机分配身份。分配到先手身份的玩家优先出牌,分配到后手身份的玩家优先选将。
                          双方各自随机获得3名暗置武将,同时从将池中随机选出6名明置武将,由后手玩家开始,按照一次1张-2张-2张-1张的顺序,轮流选择获得明置武将。之后双方各从自己的6名武将中选择2名分别作为主将和副将进行游戏。
                        • 胜利条件
                          对方死亡。' + + "
                        • 双将规则
                          双将主将决定角色的性别和势力,体力上限为主副将体力上限的平均值,向下取整。体力上限为3的角色可在游戏开始后更换一次起始手牌。
                        • 牌堆
                          牌堆中移除【木牛流马】【闪电】,♣花色的【藤甲】和【无懈可击 ♦️Q】️
                        ", + 无限火力: + '
                        1v1火力全开模式
                          (来自三国杀国际服)
                        • 所有角色的初始体力值和体力上限均为10,护甲均为0
                        • 每局游戏会有一个固定的Buff和一个随机的Buff,对所有角色生效' + + "
                        • 游戏全程会有两个任务,分别为“所有角色造成3点伤害”和“所有角色造成5点伤害”,在任务一完成后才会解锁任务二。
                          每当任务完成时,系统会发放奖励:所有角色观看三个随机的技能并获得其中一个(每名角色每局有一次刷新的机会),然后摸两张牌。", }, - help:{ - '血战长坂':'
                          游戏规则
                          • 选将阶段
                            双方在游戏开始时由系统随机分配身份。分配到先手身份的玩家优先出牌,分配到后手身份的玩家优先选将。
                            双方各自随机获得3名暗置武将,同时从将池中随机选出6名明置武将,由后手玩家开始,按照一次1张-2张-2张-1张的顺序,轮流选择获得明置武将。之后双方各从自己的6名武将中选择2名分别作为主将和副将进行游戏。
                          • 胜利条件
                            对方死亡。'+ - '
                          • 双将规则
                            双将主将决定角色的性别和势力,体力上限为主副将体力上限的平均值,向下取整。体力上限为3的角色可在游戏开始后更换一次起始手牌。
                          • 牌堆
                            牌堆中移除【木牛流马】【闪电】,♣花色的【藤甲】和【无懈可击 ♦️Q】️
                          ', - '无限火力':'
                          1v1火力全开模式
                            (来自三国杀国际服)
                          • 所有角色的初始体力值和体力上限均为10,护甲均为0
                          • 每局游戏会有一个固定的Buff和一个随机的Buff,对所有角色生效'+ - '
                          • 游戏全程会有两个任务,分别为“所有角色造成3点伤害”和“所有角色造成5点伤害”,在任务一完成后才会解锁任务二。
                            每当任务完成时,系统会发放奖励:所有角色观看三个随机的技能并获得其中一个(每名角色每局有一次刷新的机会),然后摸两张牌。', - } }; }); diff --git a/mode/stone.js b/mode/stone.js index 6fc498c71..9d7de1f9a 100644 --- a/mode/stone.js +++ b/mode/stone.js @@ -1,861 +1,878 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'stone', - start:function(){ - "step 0" - lib.init.css(lib.assetURL+'layout/mode/','stone'); - _status.mode='deck'; + name: "stone", + start: function () { + "step 0"; + lib.init.css(lib.assetURL + "layout/mode/", "stone"); + _status.mode = "deck"; game.initStone(); - var playback=localStorage.getItem(lib.configprefix+'playback'); + var playback = localStorage.getItem(lib.configprefix + "playback"); - if(!playback&&_status.mode=='deck'){ - var createCardDialog=function(){ - ui.deckBuilder=ui.create.div('.popup-container#deck-builder',function(){ - if(careerList.classList.contains('shown')){ - careerList.classList.remove('shown'); - newDeck.classList.remove('active'); - } - else if(!cardDialog.classList.contains('shown')){ - this.classList.remove('shown'); - this.timeout=setTimeout(function(){ + if (!playback && _status.mode == "deck") { + var createCardDialog = function () { + ui.deckBuilder = ui.create.div(".popup-container#deck-builder", function () { + if (careerList.classList.contains("shown")) { + careerList.classList.remove("shown"); + newDeck.classList.remove("active"); + } else if (!cardDialog.classList.contains("shown")) { + this.classList.remove("shown"); + this.timeout = setTimeout(function () { ui.deckBuilder.remove(); - },500); - ui.arena.style.top=''; - ui.arena.style.transform=''; - ui.arena.style.opacity=''; - ui.system.style.opacity=''; + }, 500); + ui.arena.style.top = ""; + ui.arena.style.transform = ""; + ui.arena.style.opacity = ""; + ui.system.style.opacity = ""; ui.auto.show(); ui.pause.show(); ui.historybar.show(); } }); - var clickNode=function(){ - cardDialog.classList.add('shown'); - controls.classList.add('shown'); - var name='未命名'; - for(var i=1;;i++){ - if(!lib.storage.deckList[name+i]){ + var clickNode = function () { + cardDialog.classList.add("shown"); + controls.classList.add("shown"); + var name = "未命名"; + for (var i = 1; ; i++) { + if (!lib.storage.deckList[name + i]) { break; } } - cardDialog.editing={ - name:name+i, - content:{ - career:this.firstChild.dataset.career, - deck:[] + cardDialog.editing = { + name: name + i, + content: { + career: this.firstChild.dataset.career, + deck: [], }, - } - rename.innerHTML=name+i; - newDeck.innerHTML='确认编辑'; - newDeck.classList.add('active'); - careerList.classList.remove('shown'); - listContainer.style.transform='translateX(200px)'; - deckContainer.innerHTML=''; - deckContainer.classList.add('shown'); + }; + rename.innerHTML = name + i; + newDeck.innerHTML = "确认编辑"; + newDeck.classList.add("active"); + careerList.classList.remove("shown"); + listContainer.style.transform = "translateX(200px)"; + deckContainer.innerHTML = ""; + deckContainer.classList.add("shown"); updateCardDialog(); + }; + var careerList = ui.create.div(".shadowed.career", ui.deckBuilder); + for (var i = 0; i < lib.careerList.length; i++) { + var node = ui.create.div(careerList, clickNode); + ui.create.div(".menubutton.round", node).dataset.career = lib.careerList[i]; + ui.create.div(".text", lib.translate[lib.careerList[i]], node); } - var careerList=ui.create.div('.shadowed.career',ui.deckBuilder); - for(var i=0;i/g,''); + var removeLine = function () { + rename.innerHTML = rename.innerHTML.replace(/\n|
                            /g, ""); }; var observer = new MutationObserver(removeLine); - observer.observe(rename,{characterData:true,subtree:true}); - rename.addEventListener('keyup',removeLine); + observer.observe(rename, { characterData: true, subtree: true }); + rename.addEventListener("keyup", removeLine); - var cardDialog=ui.create.cardDialog(true,function(name){ - if(lib.card[name].stonehidden) return true; - var type=lib.card[name].type; - return type!='stonecard'&&type!='stonecharacter'; - },{seperate:function(list){ - var nl=[],ns=[]; - var career={}; - var careerspell={}; - for(var i=0;i=30){ - for(var i=0;i= 30) { + for (var i = 0; i < cardDialog.buttons.length; i++) { + cardDialog.buttons[i].classList.add("unselectable"); } - } - else{ - var nummap={}; - for(var i=0;i=2){ + var list = []; + for (var i in nummap) { + if (nummap[i] >= 2) { list.push(i); } } - for(var i=0;ib) return 1; - if(a b) return 1; + if (a < b) return -1; + return 0; + }); + if (editing.origin) { + for (var i = 0; i < listContainer.childElementCount; i++) { + if (listContainer.childNodes[i].name == editing.origin) { + listContainer.childNodes[i].name = editing.name; + listContainer.childNodes[i].firstChild.innerHTML = + editing.name; + break; + } + } + delete lib.storage.deckList[editing.origin]; + } else if (!lib.storage.deckList[editing.name]) { + var deckitem = ui.create.div( + ".deckitem.shadowed", + "" + editing.name + "", + listContainer, + editDeck + ); + ui.create.div(".menubutton.round", deckitem).dataset.career = + editing.content.career; + deckitem.name = editing.name; + } + lib.storage.deckList[editing.name] = editing.content; } - else if(!lib.storage.deckList[editing.name]){ - var deckitem=ui.create.div('.deckitem.shadowed',''+editing.name+'', - listContainer,editDeck); - ui.create.div('.menubutton.round',deckitem).dataset.career=editing.content.career; - deckitem.name=editing.name; - } - lib.storage.deckList[editing.name]=editing.content; + game.save("deckList", lib.storage.deckList); + listContainer.style.transform = ""; + deckContainer.classList.remove("shown"); + updateCardDialog(); } - game.save('deckList',lib.storage.deckList); - listContainer.style.transform=''; - deckContainer.classList.remove('shown'); - updateCardDialog(); + e.stopPropagation(); } - e.stopPropagation(); - }); - var listContainer=ui.create.div('.list-container',deckList); - for(var i in lib.storage.deckList){ - var deckitem=ui.create.div('.deckitem.shadowed',''+i+'', - listContainer,editDeck); - ui.create.div('.menubutton.round',deckitem).dataset.career=lib.storage.deckList[i].career; - deckitem.name=i; + ); + var listContainer = ui.create.div(".list-container", deckList); + for (var i in lib.storage.deckList) { + var deckitem = ui.create.div( + ".deckitem.shadowed", + "" + i + "", + listContainer, + editDeck + ); + ui.create.div(".menubutton.round", deckitem).dataset.career = + lib.storage.deckList[i].career; + deckitem.name = i; } - var deckContainer=ui.create.div('.list-container.deck',deckList); - if(ui.deckcontrol){ + var deckContainer = ui.create.div(".list-container.deck", deckList); + if (ui.deckcontrol) { ui.deckcontrol.show(); - setTimeout(function(){ - if(ui.deckcontrol) ui.deckcontrol.style.transition=''; - },500); + setTimeout(function () { + if (ui.deckcontrol) ui.deckcontrol.style.transition = ""; + }, 500); } }; - ui.deckcontrol=ui.create.system('卡组管理',function(){ - if(this.classList.contains('hidden')) return; - // if(lib.config.low_performance){ - // ui.arena.style.transform='translateY('+ui.window.offsetHeight+'px)'; - // } - // else{ - // ui.arena.style.top='100%'; - // } - // ui.arena.style.transform='scale(0.6)'; - ui.arena.style.opacity=0; - ui.system.style.opacity=0; - ui.window.appendChild(ui.deckBuilder); - if(ui.deckBuilder.timeout){ - clearTimeout(ui.deckBuilder.timeout); - delete ui.deckBuilder.timeout; - } - ui.refresh(ui.deckBuilder); - ui.deckBuilder.classList.add('shown'); - ui.auto.hide(); - ui.pause.hide(); - ui.historybar.hide(); - },true); + ui.deckcontrol = ui.create.system( + "卡组管理", + function () { + if (this.classList.contains("hidden")) return; + // if(lib.config.low_performance){ + // ui.arena.style.transform='translateY('+ui.window.offsetHeight+'px)'; + // } + // else{ + // ui.arena.style.top='100%'; + // } + // ui.arena.style.transform='scale(0.6)'; + ui.arena.style.opacity = 0; + ui.system.style.opacity = 0; + ui.window.appendChild(ui.deckBuilder); + if (ui.deckBuilder.timeout) { + clearTimeout(ui.deckBuilder.timeout); + delete ui.deckBuilder.timeout; + } + ui.refresh(ui.deckBuilder); + ui.deckBuilder.classList.add("shown"); + ui.auto.hide(); + ui.pause.hide(); + ui.historybar.hide(); + }, + true + ); - if(lib.onfree){ - ui.deckcontrol.style.transition='all 0.5s'; + if (lib.onfree) { + ui.deckcontrol.style.transition = "all 0.5s"; ui.deckcontrol.hide(); lib.onfree.push(createCardDialog); - } - else{ + } else { createCardDialog(); } } - if(playback){ + if (playback) { ui.create.me(); - ui.arena.style.display='none'; - ui.system.style.display='none'; - _status.playback=playback; - localStorage.removeItem(lib.configprefix+'playback'); - var store=lib.db.transaction(['video'],'readwrite').objectStore('video'); - store.get(parseInt(playback)).onsuccess=function(e){ - if(e.target.result){ + ui.arena.style.display = "none"; + ui.system.style.display = "none"; + _status.playback = playback; + localStorage.removeItem(lib.configprefix + "playback"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + store.get(parseInt(playback)).onsuccess = function (e) { + if (e.target.result) { game.playVideoContent(e.target.result.video); - } - else{ - alert('播放失败:找不到录像'); + } else { + alert("播放失败:找不到录像"); game.reload(); } - } + }; event.finish(); - } - else{ + } else { game.prepareArena(2); // game.delay(); } - ui.arena.classList.add('stone'); - "step 1" - for(var i=0;i'+game.me.deckCards.length); - uiintro.addSmall([game.me.deckCards,'card']); - return uiintro; - },220); - if(get.config('skill_bar')){ - _status.rageEnabled=true; + "step 2"; + if (_status.mode == "deck") { + _status.deckButton = ui.create.system("卡组", null, true); + lib.setPopped( + _status.deckButton, + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.listen(function (e) { + e.stopPropagation(); + }); + uiintro.add( + '剩余 ' + game.me.deckCards.length + ); + uiintro.addSmall([game.me.deckCards, "card"]); + return uiintro; + }, + 220 + ); + if (get.config("skill_bar")) { + _status.rageEnabled = true; - ui.friendBar=ui.create.div('.skillbar.right.shadowed.playerbg',ui.arena); - ui.enemyBar=ui.create.div('.skillbar.left.shadowed.playerbg',ui.arena); + ui.friendBar = ui.create.div(".skillbar.right.shadowed.playerbg", ui.arena); + ui.enemyBar = ui.create.div(".skillbar.left.shadowed.playerbg", ui.arena); // ui.friendBar.dataset.nature='metal'; // ui.enemyBar.dataset.nature='fire'; - ui.create.div('.skillbarshadow',ui.friendBar); - ui.create.div('.skillbarshadow',ui.enemyBar); - ui.create.div('.skillbarfill',ui.friendBar); - ui.create.div('.skillbarfill',ui.enemyBar); - ui.friendBar.fillnode=ui.create.div(ui.friendBar.lastChild); - ui.enemyBar.fillnode=ui.create.div(ui.enemyBar.lastChild); + ui.create.div(".skillbarshadow", ui.friendBar); + ui.create.div(".skillbarshadow", ui.enemyBar); + ui.create.div(".skillbarfill", ui.friendBar); + ui.create.div(".skillbarfill", ui.enemyBar); + ui.friendBar.fillnode = ui.create.div(ui.friendBar.lastChild); + ui.enemyBar.fillnode = ui.create.div(ui.enemyBar.lastChild); // ui.friendBar.popnode=ui.create.div('.skillbartext',ui.friendBar); // ui.enemyBar.popnode=ui.create.div('.skillbartext',ui.enemyBar); - _status.friendRage=0; - _status.enemyRage=0; + _status.friendRage = 0; + _status.enemyRage = 0; - lib.setIntro(ui.friendBar,null,true); - lib.setIntro(ui.enemyBar,null,true); + lib.setIntro(ui.friendBar, null, true); + lib.setIntro(ui.enemyBar, null, true); } } - _status.friendCount=ui.create.system('',null,true); - _status.enemyCount=ui.create.system('',null,true); + _status.friendCount = ui.create.system("", null, true); + _status.enemyCount = ui.create.system("", null, true); game.updateStatusCount(); - lib.setPopped(_status.friendCount,function(){ - var uiintro=ui.create.dialog('hidden'); + lib.setPopped(_status.friendCount, function () { + var uiintro = ui.create.dialog("hidden"); - if(_status.deadfriend.length){ - uiintro.add('已阵亡'); - uiintro.add([_status.deadfriend,'player']); + if (_status.deadfriend.length) { + uiintro.add("已阵亡"); + uiintro.add([_status.deadfriend, "player"]); } - uiintro.add('未上场'); - if(_status.mylist.length){ - uiintro.add([_status.mylist,'character']); - } - else{ - uiintro.add('(无)') + uiintro.add("未上场"); + if (_status.mylist.length) { + uiintro.add([_status.mylist, "character"]); + } else { + uiintro.add("(无)"); } return uiintro; }); - lib.setPopped(_status.enemyCount,function(){ - if(_status.deadenemy.length){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add('已阵亡'); - uiintro.add([_status.deadenemy,'player']); + lib.setPopped(_status.enemyCount, function () { + if (_status.deadenemy.length) { + var uiintro = ui.create.dialog("hidden"); + uiintro.add("已阵亡"); + uiintro.add([_status.deadenemy, "player"]); return uiintro; } }); - game.me.side=Math.random()<0.5; - game.enemy.side=!game.me.side; + game.me.side = Math.random() < 0.5; + game.enemy.side = !game.me.side; - var players=get.players(lib.sort.position); - var info=[]; - for(var i=0;i=100){ - _status.friendRage=100; - ui.friendBar.fillnode.style.top='-50%'; - ui.friendBar.classList.add('full'); + if (_status.friendRage >= 100) { + _status.friendRage = 100; + ui.friendBar.fillnode.style.top = "-50%"; + ui.friendBar.classList.add("full"); + } else { + ui.friendBar.fillnode.style.top = 100 - _status.friendRage + "%"; + ui.friendBar.classList.remove("full"); } - else{ - ui.friendBar.fillnode.style.top=(100-_status.friendRage)+'%'; - ui.friendBar.classList.remove('full'); + } else { + if (_status.enemyRage < 100) { + popup = ui.enemyBar; + } + _status.enemyRage += num; + if (_status.enemyRage < 0) { + _status.enemyRage = 0; + } + if (_status.enemyRage >= 100) { + _status.enemyRage = 100; + ui.enemyBar.fillnode.style.top = "-50%"; + ui.enemyBar.classList.add("full"); + } else { + ui.enemyBar.fillnode.style.top = 100 - _status.enemyRage + "%"; + ui.enemyBar.classList.remove("full"); } } - else{ - if(_status.enemyRage<100){ - popup=ui.enemyBar; - } - _status.enemyRage+=num; - if(_status.enemyRage<0){ - _status.enemyRage=0; - } - if(_status.enemyRage>=100){ - _status.enemyRage=100; - ui.enemyBar.fillnode.style.top='-50%'; - ui.enemyBar.classList.add('full'); - } - else{ - ui.enemyBar.fillnode.style.top=(100-_status.enemyRage)+'%'; - ui.enemyBar.classList.remove('full'); - } - } - if(num>0&&popup){ - var node=ui.create.div('.skillbartext',num.toString(),popup); + if (num > 0 && popup) { + var node = ui.create.div(".skillbartext", num.toString(), popup); ui.refresh(node); - node.style.opacity=1; - setTimeout(function(){ + node.style.opacity = 1; + setTimeout(function () { node.delete(); - },700); + }, 700); } }, - drawDeck:function(num,log){ - if(!num){ - num=1; + drawDeck: function (num, log) { + if (!num) { + num = 1; } - var cards=this.getDeckCards(num); - if(log==false){ + var cards = this.getDeckCards(num); + if (log == false) { this.directgain(cards); - } - else if(log==true){ + } else if (log == true) { this.directgain(cards); - game.log(this,'从牌库中获得了'+get.cnNumber(num)+'张牌'); - } - else{ - this.gain(cards,'draw'); - game.log(this,'从牌库中获得了'+get.cnNumber(num)+'张牌'); + game.log(this, "从牌库中获得了" + get.cnNumber(num) + "张牌"); + } else { + this.gain(cards, "draw"); + game.log(this, "从牌库中获得了" + get.cnNumber(num) + "张牌"); } return cards; }, - updateActCount:function(used,countx,current){ - if(_status.video){ - this.actcount=countx||2; + updateActCount: function (used, countx, current) { + if (_status.video) { + this.actcount = countx || 2; + } else { + game.addVideo("updateActCount", this, [used, this.actcount, this.getActCount()]); } - else{ - game.addVideo('updateActCount',this,[used,this.actcount,this.getActCount()]); - } - var maxcount,overflow2; - if(game.layout=='default'||used=='outphase'||_status.currentPhase!=this){ - maxcount=this.actcount; - } - else{ - if(_status.video){ - maxcount=this.actcount-(current||0); + var maxcount, overflow2; + if (game.layout == "default" || used == "outphase" || _status.currentPhase != this) { + maxcount = this.actcount; + } else { + if (_status.video) { + maxcount = this.actcount - (current || 0); + } else { + maxcount = this.actcount - this.getActCount(); } - else{ - maxcount=this.actcount-this.getActCount(); + if (this.actcount > maxcount) { + maxcount = this.actcount; } - if(this.actcount>maxcount){ - maxcount=this.actcount; - } - if(maxcount>12){ - maxcount=this.actcount+1; - this.node.actcount.classList.add('overflow2'); - } - else{ - this.node.actcount.classList.remove('overflow2'); + if (maxcount > 12) { + maxcount = this.actcount + 1; + this.node.actcount.classList.add("overflow2"); + } else { + this.node.actcount.classList.remove("overflow2"); } } - for(var i=0;i<12;i++){ - if(maxcount>this.node.actcount.childElementCount){ + for (var i = 0; i < 12; i++) { + if (maxcount > this.node.actcount.childElementCount) { ui.create.div(this.node.actcount); - } - else if(maxcount=this.actcount){ - this.node.actcount.childNodes[i].classList.add('overflow'); + for (var i = 0; i < this.node.actcount.childElementCount; i++) { + if (i < count) { + this.node.actcount.childNodes[i].classList.remove("lost"); + if (i >= this.actcount) { + this.node.actcount.childNodes[i].classList.add("overflow"); + } else { + this.node.actcount.childNodes[i].classList.remove("overflow"); } - else{ - this.node.actcount.childNodes[i].classList.remove('overflow'); - } - } - else{ - this.node.actcount.childNodes[i].classList.add('lost'); - this.node.actcount.childNodes[i].classList.remove('overflow'); + } else { + this.node.actcount.childNodes[i].classList.add("lost"); + this.node.actcount.childNodes[i].classList.remove("overflow"); } } } }, - getAct:function(){ - return this.actcount-this.getActCount(); + getAct: function () { + return this.actcount - this.getActCount(); }, - hasFellowSkill:function(skill,exclude){ - for(var i=0;i=0){ - this.actcharacterlist[index]=null; + removeFellow: function (fellow) { + if (!this.actcharacterlist) return this; + var index = this.actcharacterlist.indexOf(fellow); + if (index >= 0) { + this.actcharacterlist[index] = null; } return this; }, - dieAfter:function(source){ - var dead=this; - if(game.me.isDead()){ - if(!_status.mylist.length){ - _status.friendCount.innerHTML='友军: '+get.cnNumber(0); + dieAfter: function (source) { + var dead = this; + if (game.me.isDead()) { + if (!_status.mylist.length) { + _status.friendCount.innerHTML = "友军: " + get.cnNumber(0); game.over(false); } - } - else if(game.enemy.isDead()){ - if(!_status.enemylist.length){ - _status.enemyCount.innerHTML='敌军: '+get.cnNumber(0); + } else if (game.enemy.isDead()) { + if (!_status.enemylist.length) { + _status.enemyCount.innerHTML = "敌军: " + get.cnNumber(0); game.over(true); } } }, - dieAfter2:function(source){ - var dead=this; - if(game.me.isDead()){ - if(!_status.mylist.length){ - _status.friendCount.innerHTML='友军: '+get.cnNumber(0); + dieAfter2: function (source) { + var dead = this; + if (game.me.isDead()) { + if (!_status.mylist.length) { + _status.friendCount.innerHTML = "友军: " + get.cnNumber(0); game.over(false); - } - else{ + } else { game.pause(); _status.deadfriend.push(this); game.additionaldead.push(this); - setTimeout(function(){ - var player=ui.create.player(); + setTimeout(function () { + var player = ui.create.player(); player.getId(); - player.classList.add('noidentity'); - player.dataset.position=dead.dataset.position; - player.side=dead.side; - player.actcharacterlist=dead.actcharacterlist; - player.addTempClass('replaceme'); - player.actcount=game.enemy.actcount; - player.actcount=dead.actcount; - if(_status.double_character){ - player.init(_status.mylist.shift(),_status.mylist.shift()); - } - else{ + player.classList.add("noidentity"); + player.dataset.position = dead.dataset.position; + player.side = dead.side; + player.actcharacterlist = dead.actcharacterlist; + player.addTempClass("replaceme"); + player.actcount = game.enemy.actcount; + player.actcount = dead.actcount; + if (_status.double_character) { + player.init(_status.mylist.shift(), _status.mylist.shift()); + } else { player.init(_status.mylist.shift()); } player.maxHp++; player.hp++; - if(_status.mode=='deck'){ - get.deck(player,_status.deck.shift()); + if (_status.mode == "deck") { + get.deck(player, _status.deck.shift()); } game.players.push(player); ui.arena.appendChild(player); - game.addVideo('stoneSwap',null,{ - name:player.name1, - name2:player.name2, - position:player.dataset.position, - actcount:player.actcount, - me:true + game.addVideo("stoneSwap", null, { + name: player.name1, + name2: player.name2, + position: player.dataset.position, + actcount: player.actcount, + me: true, }); game.swapControl(player); game.arrangePlayers(); - if(_status.mode=='deck'){ - var nd=game.enemy.countFellow(); - if(nd){ - player.draw(3+nd,{drawDeck:nd},false); + if (_status.mode == "deck") { + var nd = game.enemy.countFellow(); + if (nd) { + player.draw(3 + nd, { drawDeck: nd }, false); + } else { + player.draw(3, false); } - else{ - player.draw(3,false); - } - } - else{ - player.draw(3+game.enemy.countFellow(),false); + } else { + player.draw(3 + game.enemy.countFellow(), false); } game.resume(); game.updateStatusCount(); - },lib.config.duration); + }, lib.config.duration); } - } - else if(game.enemy.isDead()){ - if(!_status.enemylist.length){ - _status.enemyCount.innerHTML='敌军: '+get.cnNumber(0); + } else if (game.enemy.isDead()) { + if (!_status.enemylist.length) { + _status.enemyCount.innerHTML = "敌军: " + get.cnNumber(0); game.over(true); - } - else{ + } else { game.pause(); _status.deadenemy.push(this); game.additionaldead.push(this); - setTimeout(function(){ - var player=ui.create.player(); + setTimeout(function () { + var player = ui.create.player(); player.getId(); - player.classList.add('noidentity'); - player.dataset.position=dead.dataset.position; - player.side=dead.side; - player.actcharacterlist=dead.actcharacterlist; - player.addTempClass('replaceenemy'); - player.actcount=dead.actcount; - if(_status.double_character){ - player.init(_status.enemylist.shift(),_status.enemylist.shift()); - } - else{ + player.classList.add("noidentity"); + player.dataset.position = dead.dataset.position; + player.side = dead.side; + player.actcharacterlist = dead.actcharacterlist; + player.addTempClass("replaceenemy"); + player.actcount = dead.actcount; + if (_status.double_character) { + player.init(_status.enemylist.shift(), _status.enemylist.shift()); + } else { player.init(_status.enemylist.shift()); } player.maxHp++; player.hp++; - if(_status.mode=='deck'){ - get.deck(player,'random'); + if (_status.mode == "deck") { + get.deck(player, "random"); } game.players.push(player); - game.enemy=player; + game.enemy = player; ui.arena.appendChild(player); - game.addVideo('stoneSwap',null,{ - name:player.name1, - name2:player.name2, - position:player.dataset.position, - actcount:player.actcount, + game.addVideo("stoneSwap", null, { + name: player.name1, + name2: player.name2, + position: player.dataset.position, + actcount: player.actcount, }); game.arrangePlayers(); - if(_status.mode=='deck'){ - var nd=game.me.countFellow(); - if(nd){ - player.draw(3+nd,{drawDeck:nd},false); + if (_status.mode == "deck") { + var nd = game.me.countFellow(); + if (nd) { + player.draw(3 + nd, { drawDeck: nd }, false); + } else { + player.draw(3, false); } - else{ - player.draw(3,false); - } - } - else{ - player.draw(3+game.me.countFellow(),false); + } else { + player.draw(3 + game.me.countFellow(), false); } game.resume(); game.updateStatusCount(); - },lib.config.duration); + }, lib.config.duration); } } - if(source&&source.side!=this.side&&!source.isMin()){ - if(_status.mode=='deck'){ + if (source && source.side != this.side && !source.isMin()) { + if (_status.mode == "deck") { source.drawDeck(); - } - else{ + } else { source.draw(); } source.actused--; @@ -1047,621 +1056,1585 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ game.dead.remove(this); game.arrangePlayers(); this.getLeader().removeFellow(this); - setTimeout(function(){ + setTimeout(function () { dead.delete(); - },500); + }, 500); }, - } + }, }, - beastList:['stone_misha','stone_leiouke','stone_huofu','stone_caoyuanshi','stone_jiewangzhu', - 'stone_huangjialeixiang','stone_damoshatuo','stone_tujiu','stone_senlinlang', - 'stone_fennuxiaoji','stone_juxingchanchu','stone_yanjingshe','stone_yuanhou' + beastList: [ + "stone_misha", + "stone_leiouke", + "stone_huofu", + "stone_caoyuanshi", + "stone_jiewangzhu", + "stone_huangjialeixiang", + "stone_damoshatuo", + "stone_tujiu", + "stone_senlinlang", + "stone_fennuxiaoji", + "stone_juxingchanchu", + "stone_yanjingshe", + "stone_yuanhou", ], - cardPack:{ - mode_stone:[ - 'spell_xiaoshi','spell_chenmo','spell_morizaihuo','spell_shengerpingdeng','spell_jingshenkongzhi','spell_anyingkuangluan', - 'spell_binghuan','spell_yanmie','spell_zhiliaozhichu','spell_wangzhezhufu','spell_diyulieyan','spell_zhiliaoshui', - 'spell_hanbingjian','spell_huoqiushu','spell_bianxingshu','spell_aoshuzhihui','spell_baofengxue','spell_lieyanfengbao', - 'spell_shandianfengbao','spell_chazhuangshandian','spell_yaoshu','spell_shixue','spell_lianhuanbaolie','spell_yexinglanghun', - 'spell_fuchouzhinu','spell_liliangzhufu','spell_fennuzhichui','spell_fengxian','spell_zuozhandongyuan','spell_shengliaoshu', - 'spell_cigu','spell_modaoyou','spell_jianrenluanwu','spell_daoshan','spell_cisha','spell_sijidaifa', - 'spell_huotigenxu','spell_wuyashenxiang','spell_ziranzhili','spell_yemanpaoxiao','spell_hengsao','spell_yexingchengzhang', - 'spell_xishengqiyue','spell_zuzhou','spell_xiaoguibaopo','spell_emozhinu','spell_anyinglieyan','spell_liliangdaijia', - 'spell_shenshengxinxing','spell_shengguangzhadan','spell_maizang','spell_xinlingshijie','spell_naluzhiguang','spell_zhiliaozhihuan', - 'spell_nuxi','spell_dunpaimengji','spell_zhansha','spell_nuhuozhongshao','spell_xuanfengzhan','spell_juemingluandou', - 'spell_lierenyinji','spell_kuaisusheji','spell_guanmenfanggou','spell_zhaohuanchongwu','spell_zidanshangtang','spell_duochongsheji', - 'spell_xianzuzhihun','spell_xianzuzhaohuan','spell_fengnu','spell_shihuawuqi','spell_xianzuzhishi','spell_rongyanbaolie', - 'spell_laojiuhuoba','spell_chirehuoba','spell_aoshufeidan','spell_canying','spell_yanbaoshu','spell_hanbingpingzhang','spell_jingxiang', - 'spell_mengun','spell_jipao','spell_beici','spell_weijisifu','spell_zhumo','spell_anzhongpohuai','spell_piaoqie', - 'spell_conglinzhihun','spell_heiandiyu','spell_fugen','spell_xingchenzhuiluo','spell_fennu','spell_ziyang', - 'spell_shalumingling','spell_tianjiangzhuqun','spell_tanxianmao','spell_dubiao','spell_qiangfengsheji','spell_zhuizongshu', - 'spell_zhenyanshu','spell_enzeshu','spell_anyingxingtai','spell_kuaisuzhiliao','spell_kongxinshu','spell_xinlinghanbao', - 'spell_jinyingduijue','spell_zhihuizhufu','spell_shenshengfennu','spell_yongshizhufu','spell_shenpan','spell_zhengqianghaosheng', - 'spell_zhongnian','spell_fuchoudaji','spell_yingyongdaji','spell_zhandounuhuo','spell_chongfeng','spell_kuangbao', - 'spell_linghunhongxi','spell_siwangchanrao','spell_emozhixin','spell_fushishu','spell_ansezhadan','spell_heianqiyue' - ] + cardPack: { + mode_stone: [ + "spell_xiaoshi", + "spell_chenmo", + "spell_morizaihuo", + "spell_shengerpingdeng", + "spell_jingshenkongzhi", + "spell_anyingkuangluan", + "spell_binghuan", + "spell_yanmie", + "spell_zhiliaozhichu", + "spell_wangzhezhufu", + "spell_diyulieyan", + "spell_zhiliaoshui", + "spell_hanbingjian", + "spell_huoqiushu", + "spell_bianxingshu", + "spell_aoshuzhihui", + "spell_baofengxue", + "spell_lieyanfengbao", + "spell_shandianfengbao", + "spell_chazhuangshandian", + "spell_yaoshu", + "spell_shixue", + "spell_lianhuanbaolie", + "spell_yexinglanghun", + "spell_fuchouzhinu", + "spell_liliangzhufu", + "spell_fennuzhichui", + "spell_fengxian", + "spell_zuozhandongyuan", + "spell_shengliaoshu", + "spell_cigu", + "spell_modaoyou", + "spell_jianrenluanwu", + "spell_daoshan", + "spell_cisha", + "spell_sijidaifa", + "spell_huotigenxu", + "spell_wuyashenxiang", + "spell_ziranzhili", + "spell_yemanpaoxiao", + "spell_hengsao", + "spell_yexingchengzhang", + "spell_xishengqiyue", + "spell_zuzhou", + "spell_xiaoguibaopo", + "spell_emozhinu", + "spell_anyinglieyan", + "spell_liliangdaijia", + "spell_shenshengxinxing", + "spell_shengguangzhadan", + "spell_maizang", + "spell_xinlingshijie", + "spell_naluzhiguang", + "spell_zhiliaozhihuan", + "spell_nuxi", + "spell_dunpaimengji", + "spell_zhansha", + "spell_nuhuozhongshao", + "spell_xuanfengzhan", + "spell_juemingluandou", + "spell_lierenyinji", + "spell_kuaisusheji", + "spell_guanmenfanggou", + "spell_zhaohuanchongwu", + "spell_zidanshangtang", + "spell_duochongsheji", + "spell_xianzuzhihun", + "spell_xianzuzhaohuan", + "spell_fengnu", + "spell_shihuawuqi", + "spell_xianzuzhishi", + "spell_rongyanbaolie", + "spell_laojiuhuoba", + "spell_chirehuoba", + "spell_aoshufeidan", + "spell_canying", + "spell_yanbaoshu", + "spell_hanbingpingzhang", + "spell_jingxiang", + "spell_mengun", + "spell_jipao", + "spell_beici", + "spell_weijisifu", + "spell_zhumo", + "spell_anzhongpohuai", + "spell_piaoqie", + "spell_conglinzhihun", + "spell_heiandiyu", + "spell_fugen", + "spell_xingchenzhuiluo", + "spell_fennu", + "spell_ziyang", + "spell_shalumingling", + "spell_tianjiangzhuqun", + "spell_tanxianmao", + "spell_dubiao", + "spell_qiangfengsheji", + "spell_zhuizongshu", + "spell_zhenyanshu", + "spell_enzeshu", + "spell_anyingxingtai", + "spell_kuaisuzhiliao", + "spell_kongxinshu", + "spell_xinlinghanbao", + "spell_jinyingduijue", + "spell_zhihuizhufu", + "spell_shenshengfennu", + "spell_yongshizhufu", + "spell_shenpan", + "spell_zhengqianghaosheng", + "spell_zhongnian", + "spell_fuchoudaji", + "spell_yingyongdaji", + "spell_zhandounuhuo", + "spell_chongfeng", + "spell_kuangbao", + "spell_linghunhongxi", + "spell_siwangchanrao", + "spell_emozhixin", + "spell_fushishu", + "spell_ansezhadan", + "spell_heianqiyue", + ], }, - characterPack:{ - mode_stone:{ - stone_tutengyongshi:['male','wei',4,['shaman_jili'],['minskin','stone'],[4,2,'shaman']], - stone_xuejuren:['male','wei',2,['shaman_xueju'],['minskin','stone'],[1,1,'shaman']], - stone_tuyuansu:['male','qun',5,['lschaofeng'],['minskin','stone'],[5,4,'shaman']], - stone_huoyuansu:['male','shu',3,['shaman_huoxi'],['minskin','stone'],[4,3,'shaman']], - stone_fachao:['male','wei',3,['shaman_tuteng','shaman_fachao'],['minskin','stone'],[3,0,'shaman']], - stone_huoshe:['male','shu',3,['shaman_tuteng','shaman_huoshe'],['minskin','stone'],[3,0,'shaman']], - stone_huoli:['male','wei',3,['shaman_tuteng','shaman_huoli'],['minskin','stone'],[2,0,'shaman']], - stone_huoyanweishi:['male','shu',4,['shaman_zhuhuo'],['minskin','stone'],[4,1,'shaman']], - stone_tutengshi:['female','wei',2,['shaman_peiyu'],['minskin','stone'],[3,3,'shaman']], - stone_shachuisaman:['male','qun',3,['shaman_fengnu'],['minskin','stone'],[4,4,'shaman']], - stone_wanshiyuansu:['male','qun',3,['shaman_zoushi'],['minskin','stone'],[3,1,'shaman']], - stone_shalinxingzhe:['male','qun',4,['shaman_anhun'],['minskin','stone'],[4,2,'shaman']], + characterPack: { + mode_stone: { + stone_tutengyongshi: [ + "male", + "wei", + 4, + ["shaman_jili"], + ["minskin", "stone"], + [4, 2, "shaman"], + ], + stone_xuejuren: ["male", "wei", 2, ["shaman_xueju"], ["minskin", "stone"], [1, 1, "shaman"]], + stone_tuyuansu: ["male", "qun", 5, ["lschaofeng"], ["minskin", "stone"], [5, 4, "shaman"]], + stone_huoyuansu: ["male", "shu", 3, ["shaman_huoxi"], ["minskin", "stone"], [4, 3, "shaman"]], + stone_fachao: [ + "male", + "wei", + 3, + ["shaman_tuteng", "shaman_fachao"], + ["minskin", "stone"], + [3, 0, "shaman"], + ], + stone_huoshe: [ + "male", + "shu", + 3, + ["shaman_tuteng", "shaman_huoshe"], + ["minskin", "stone"], + [3, 0, "shaman"], + ], + stone_huoli: [ + "male", + "wei", + 3, + ["shaman_tuteng", "shaman_huoli"], + ["minskin", "stone"], + [2, 0, "shaman"], + ], + stone_huoyanweishi: [ + "male", + "shu", + 4, + ["shaman_zhuhuo"], + ["minskin", "stone"], + [4, 1, "shaman"], + ], + stone_tutengshi: [ + "female", + "wei", + 2, + ["shaman_peiyu"], + ["minskin", "stone"], + [3, 3, "shaman"], + ], + stone_shachuisaman: [ + "male", + "qun", + 3, + ["shaman_fengnu"], + ["minskin", "stone"], + [4, 4, "shaman"], + ], + stone_wanshiyuansu: [ + "male", + "qun", + 3, + ["shaman_zoushi"], + ["minskin", "stone"], + [3, 1, "shaman"], + ], + stone_shalinxingzhe: [ + "male", + "qun", + 4, + ["shaman_anhun"], + ["minskin", "stone"], + [4, 2, "shaman"], + ], - stone_kuangyedoushi:['male','wu',3,['druid_nuhuo'],['minskin','stone'],[4,2,'druid']], - stone_conglinshouwei:['male','wu',3,['druid_huwei'],['minskin','stone'],[4,2,'druid']], - stone_baohuzhishu:['male','qun',6,['lschaofeng'],['minskin','stone'],[6,4,'druid']], - stone_liebao:['male','wei',3,['stone_chongfeng'],['minskin','stone'],[3,2,'druid']], - stone_zongxiong:['male','shu',4,['lschaofeng'],['minskin','stone'],[4,2,'druid']], - stone_baoqishi:['female','wei',2,['druid_chengzhang'],['minskin','stone'],[2,2,'druid']], - stone_renyaqishi:['female','wei',1,['druid_renya'],['minskin','stone'],[1,1,'druid']], - stone_huangyeqishi:['male','wei',4,['druid_chicheng'],['minskin','stone'],[5,2,'druid']], - stone_huoshanxiemu:['male','wei',3,['druid_juhuo','lschaofeng'],['minskin','stone'],[5,6,'druid']], - stone_conglinxiaoshou:['male','wei',3,['druid_yuehuo'],['minskin','stone'],[4,4,'druid']], - stone_lindishuyao:['female','wei',3,['druid_yeyou'],['minskin','stone'],[3,3,'druid']], - stone_xunmenglong:['male','wei',2,['druid_qicheng'],['minskin','stone'],[3,3,'druid']], + stone_kuangyedoushi: [ + "male", + "wu", + 3, + ["druid_nuhuo"], + ["minskin", "stone"], + [4, 2, "druid"], + ], + stone_conglinshouwei: [ + "male", + "wu", + 3, + ["druid_huwei"], + ["minskin", "stone"], + [4, 2, "druid"], + ], + stone_baohuzhishu: ["male", "qun", 6, ["lschaofeng"], ["minskin", "stone"], [6, 4, "druid"]], + stone_liebao: ["male", "wei", 3, ["stone_chongfeng"], ["minskin", "stone"], [3, 2, "druid"]], + stone_zongxiong: ["male", "shu", 4, ["lschaofeng"], ["minskin", "stone"], [4, 2, "druid"]], + stone_baoqishi: [ + "female", + "wei", + 2, + ["druid_chengzhang"], + ["minskin", "stone"], + [2, 2, "druid"], + ], + stone_renyaqishi: [ + "female", + "wei", + 1, + ["druid_renya"], + ["minskin", "stone"], + [1, 1, "druid"], + ], + stone_huangyeqishi: [ + "male", + "wei", + 4, + ["druid_chicheng"], + ["minskin", "stone"], + [5, 2, "druid"], + ], + stone_huoshanxiemu: [ + "male", + "wei", + 3, + ["druid_juhuo", "lschaofeng"], + ["minskin", "stone"], + [5, 6, "druid"], + ], + stone_conglinxiaoshou: [ + "male", + "wei", + 3, + ["druid_yuehuo"], + ["minskin", "stone"], + [4, 4, "druid"], + ], + stone_lindishuyao: [ + "female", + "wei", + 3, + ["druid_yeyou"], + ["minskin", "stone"], + [3, 3, "druid"], + ], + stone_xunmenglong: [ + "male", + "wei", + 2, + ["druid_qicheng"], + ["minskin", "stone"], + [3, 3, "druid"], + ], - stone_caoyuanshi:['male','qun',5,['hunter_nuhou'],['minskin','stone'],[5,2,'hunter']], - stone_leiouke:['male','shu',2,['hunter_zhanhuo'],['minskin','stone'],[3,1,'hunter']], - stone_huofu:['male','qun',2,['stone_chongfeng'],['minskin','stone'],[3,4,'hunter']], - stone_misha:['male','shu',3,['lschaofeng'],['minskin','stone'],[3,3,'hunter']], - stone_jiewangzhu:['male','wu',1,['hunter_jiewang'],['minskin','stone'],[1,2,'hunter']], - stone_xunshoushi:['male','qun',2,['hunter_xunshou'],['minskin','stone'],[4,3,'hunter']], - stone_senlinlang:['male','qun',1,['hunter_qunxi'],['minskin','stone'],[1,2,'hunter']], - stone_tujiu:['male','qun',3,['hunter_mishi'],['minskin','stone'],[3,2,'hunter']], - stone_muyangren:['male','qun',3,['hunter_muyang'],['minskin','stone'],[4,3,'hunter']], - stone_jujishou:['male','qun',2,['hunter_juji'],['minskin','stone'],[2,2,'hunter']], - stone_damoshatuo:['male','qun',3,['hunter_dusha'],['minskin','stone'],[3,3,'hunter']], - stone_huangjialeixiang:['male','qun',2,['hunter_chuanlin'],['minskin','stone'],[2,3,'hunter']], + stone_caoyuanshi: [ + "male", + "qun", + 5, + ["hunter_nuhou"], + ["minskin", "stone"], + [5, 2, "hunter"], + ], + stone_leiouke: ["male", "shu", 2, ["hunter_zhanhuo"], ["minskin", "stone"], [3, 1, "hunter"]], + stone_huofu: ["male", "qun", 2, ["stone_chongfeng"], ["minskin", "stone"], [3, 4, "hunter"]], + stone_misha: ["male", "shu", 3, ["lschaofeng"], ["minskin", "stone"], [3, 3, "hunter"]], + stone_jiewangzhu: [ + "male", + "wu", + 1, + ["hunter_jiewang"], + ["minskin", "stone"], + [1, 2, "hunter"], + ], + stone_xunshoushi: [ + "male", + "qun", + 2, + ["hunter_xunshou"], + ["minskin", "stone"], + [4, 3, "hunter"], + ], + stone_senlinlang: [ + "male", + "qun", + 1, + ["hunter_qunxi"], + ["minskin", "stone"], + [1, 2, "hunter"], + ], + stone_tujiu: ["male", "qun", 3, ["hunter_mishi"], ["minskin", "stone"], [3, 2, "hunter"]], + stone_muyangren: [ + "male", + "qun", + 3, + ["hunter_muyang"], + ["minskin", "stone"], + [4, 3, "hunter"], + ], + stone_jujishou: ["male", "qun", 2, ["hunter_juji"], ["minskin", "stone"], [2, 2, "hunter"]], + stone_damoshatuo: [ + "male", + "qun", + 3, + ["hunter_dusha"], + ["minskin", "stone"], + [3, 3, "hunter"], + ], + stone_huangjialeixiang: [ + "male", + "qun", + 2, + ["hunter_chuanlin"], + ["minskin", "stone"], + [2, 3, "hunter"], + ], - stone_shuiyuansu:['male','wei',4,['mage_bingdong'],['minskin','stone'],[4,2,'mage']], - stone_wushixuetu:['female','wu',1,['mage_zhufa'],['minskin','stone'],[1,2,'mage']], - stone_huoyao:['male','shu',3,['mage_lieyan'],['minskin','stone'],[3,1,'mage']], - stone_falifulong:['male','shu',2,['mage_tunfa'],['minskin','stone'],[1,1,'mage']], - stone_yingxiongzhihun:['male','wei',1,['mage_minghuo'],['minskin','stone'],[1,2,'mage']], - stone_shifazhe:['male','qun',3,['mage_shifa'],['minskin','stone'],[3,3,'mage']], - stone_aoshushi:['male','qun',3,['mage_aoshu'],['minskin','stone'],[3,2,'mage']], - stone_faqishi:['male','qun',4,['mage_jili'],['minskin','stone'],[4,2,'mage']], - stone_fuhuokaijia:['male','qun',3,['mage_gushou'],['minskin','stone'],[3,3,'mage']], - stone_kaodalalong:['male','qun',4,['mage_yufa'],['minskin','stone'],[5,4,'mage']], - stone_yanshushi:['male','qun',2,['mage_yanshu'],['minskin','stone'],[4,4,'mage']], - stone_xulingwushi:['male','qun',2,['mage_pingxu'],['minskin','stone'],[3,3,'mage']], + stone_shuiyuansu: ["male", "wei", 4, ["mage_bingdong"], ["minskin", "stone"], [4, 2, "mage"]], + stone_wushixuetu: ["female", "wu", 1, ["mage_zhufa"], ["minskin", "stone"], [1, 2, "mage"]], + stone_huoyao: ["male", "shu", 3, ["mage_lieyan"], ["minskin", "stone"], [3, 1, "mage"]], + stone_falifulong: ["male", "shu", 2, ["mage_tunfa"], ["minskin", "stone"], [1, 1, "mage"]], + stone_yingxiongzhihun: [ + "male", + "wei", + 1, + ["mage_minghuo"], + ["minskin", "stone"], + [1, 2, "mage"], + ], + stone_shifazhe: ["male", "qun", 3, ["mage_shifa"], ["minskin", "stone"], [3, 3, "mage"]], + stone_aoshushi: ["male", "qun", 3, ["mage_aoshu"], ["minskin", "stone"], [3, 2, "mage"]], + stone_faqishi: ["male", "qun", 4, ["mage_jili"], ["minskin", "stone"], [4, 2, "mage"]], + stone_fuhuokaijia: ["male", "qun", 3, ["mage_gushou"], ["minskin", "stone"], [3, 3, "mage"]], + stone_kaodalalong: ["male", "qun", 4, ["mage_yufa"], ["minskin", "stone"], [5, 4, "mage"]], + stone_yanshushi: ["male", "qun", 2, ["mage_yanshu"], ["minskin", "stone"], [4, 4, "mage"]], + stone_xulingwushi: ["male", "qun", 2, ["mage_pingxu"], ["minskin", "stone"], [3, 3, "mage"]], - stone_hudunren:['male','qun',2,['paladin_hudun'],['minskin','stone'],[2,2,'paladin']], - stone_junxuguan:['male','qun',3,['paladin_buji'],['minskin','stone'],[4,1,'paladin']], - stone_yurenqishi:['male','qun',2,['paladin_zhaochao'],['minskin','stone'],[4,2,'paladin']], - stone_chidunweishi:['male','qun',3,['paladin_chidun'],['minskin','stone'],[3,2,'paladin']], - stone_liewangshouwei:['male','qun',5,['paladin_shouwei'],['minskin','stone'],[5,2,'paladin']], - stone_longwangpeiou:['female','qun',4,['paladin_zhaohuan'],['minskin','stone'],[5,4,'paladin']], - stone_baoweizhe:['male','qun',2,['paladin_baowei'],['minskin','stone'],[2,1,'paladin']], - stone_guiqishi:['male','qun',5,['paladin_tuxi'],['minskin','stone'],[5,4,'paladin']], - stone_shenmiqishou:['male','qun',4,['paladin_miying'],['minskin','stone'],[5,4,'paladin']], - stone_shixiangweishi:['female','qun',3,['paladin_huashi'],['minskin','stone'],[3,3,'paladin']], - stone_xuefanzhanshi:['male','qun',3,['paladin_jinghua'],['minskin','stone'],[4,4,'paladin']], - stone_xunmashi:['male','qun',3,['paladin_moma'],['minskin','stone'],[3,2,'paladin']], + stone_hudunren: [ + "male", + "qun", + 2, + ["paladin_hudun"], + ["minskin", "stone"], + [2, 2, "paladin"], + ], + stone_junxuguan: [ + "male", + "qun", + 3, + ["paladin_buji"], + ["minskin", "stone"], + [4, 1, "paladin"], + ], + stone_yurenqishi: [ + "male", + "qun", + 2, + ["paladin_zhaochao"], + ["minskin", "stone"], + [4, 2, "paladin"], + ], + stone_chidunweishi: [ + "male", + "qun", + 3, + ["paladin_chidun"], + ["minskin", "stone"], + [3, 2, "paladin"], + ], + stone_liewangshouwei: [ + "male", + "qun", + 5, + ["paladin_shouwei"], + ["minskin", "stone"], + [5, 2, "paladin"], + ], + stone_longwangpeiou: [ + "female", + "qun", + 4, + ["paladin_zhaohuan"], + ["minskin", "stone"], + [5, 4, "paladin"], + ], + stone_baoweizhe: [ + "male", + "qun", + 2, + ["paladin_baowei"], + ["minskin", "stone"], + [2, 1, "paladin"], + ], + stone_guiqishi: ["male", "qun", 5, ["paladin_tuxi"], ["minskin", "stone"], [5, 4, "paladin"]], + stone_shenmiqishou: [ + "male", + "qun", + 4, + ["paladin_miying"], + ["minskin", "stone"], + [5, 4, "paladin"], + ], + stone_shixiangweishi: [ + "female", + "qun", + 3, + ["paladin_huashi"], + ["minskin", "stone"], + [3, 3, "paladin"], + ], + stone_xuefanzhanshi: [ + "male", + "qun", + 3, + ["paladin_jinghua"], + ["minskin", "stone"], + [4, 4, "paladin"], + ], + stone_xunmashi: ["male", "qun", 3, ["paladin_moma"], ["minskin", "stone"], [3, 2, "paladin"]], - stone_lieyanxiaogui:['male','qun',2,['warlock_nonghuo'],['minskin','stone'],[1,4,'warlock']], - stone_xiaoguishouling:['male','qun',3,['warlock_zhaogui'],['minskin','stone'],[3,1,'warlock']], - stone_xiaogui:['male','qun',1,[],['minskin','stone','stonehidden'],[1,1]], - stone_kongjuzhanma:['male','qun',1,['warlock_yongsheng'],['minskin','stone'],[3,1,'warlock']], - stone_morishouwei:['male','qun',4,['stone_chongfeng','warlock_zaihuo'],['minskin','stone'],[4,4,'warlock']], - stone_xukongxingzhe:['male','qun',2,['lschaofeng'],['minskin','stone'],[1,1,'warlock']], - stone_diyuhuo:['male','qun',4,['warlock_yuhuo'],['minskin','stone'],[5,4,'warlock']], - stone_diyuhuox:['male','qun',2,[],['minskin','stone','stonehidden'],[2,2,'warlock']], - stone_heishitanfan:['male','qun',2,['warlock_anyu'],['minskin','stone'],[2,2,'warlock']], - stone_zhaohuanzhe:['male','qun',3,['warlock_zhaohuan'],['minskin','stone'],[4,2,'warlock']], - stone_meimo:['male','qun',3,['warlock_huanmeng'],['minskin','stone'],[2,3,'warlock']], - stone_tongkunvwang:['male','qun',2,['warlock_tongku'],['minskin','stone'],[2,1,'warlock']], - stone_xukongkongmo:['male','qun',3,['warlock_tunshi'],['minskin','stone'],[3,3,'warlock']], - stone_fukongmoyan:['male','qun',4,['warlock_shijie'],['minskin','stone'],[5,4,'warlock']], + stone_lieyanxiaogui: [ + "male", + "qun", + 2, + ["warlock_nonghuo"], + ["minskin", "stone"], + [1, 4, "warlock"], + ], + stone_xiaoguishouling: [ + "male", + "qun", + 3, + ["warlock_zhaogui"], + ["minskin", "stone"], + [3, 1, "warlock"], + ], + stone_xiaogui: ["male", "qun", 1, [], ["minskin", "stone", "stonehidden"], [1, 1]], + stone_kongjuzhanma: [ + "male", + "qun", + 1, + ["warlock_yongsheng"], + ["minskin", "stone"], + [3, 1, "warlock"], + ], + stone_morishouwei: [ + "male", + "qun", + 4, + ["stone_chongfeng", "warlock_zaihuo"], + ["minskin", "stone"], + [4, 4, "warlock"], + ], + stone_xukongxingzhe: [ + "male", + "qun", + 2, + ["lschaofeng"], + ["minskin", "stone"], + [1, 1, "warlock"], + ], + stone_diyuhuo: ["male", "qun", 4, ["warlock_yuhuo"], ["minskin", "stone"], [5, 4, "warlock"]], + stone_diyuhuox: [ + "male", + "qun", + 2, + [], + ["minskin", "stone", "stonehidden"], + [2, 2, "warlock"], + ], + stone_heishitanfan: [ + "male", + "qun", + 2, + ["warlock_anyu"], + ["minskin", "stone"], + [2, 2, "warlock"], + ], + stone_zhaohuanzhe: [ + "male", + "qun", + 3, + ["warlock_zhaohuan"], + ["minskin", "stone"], + [4, 2, "warlock"], + ], + stone_meimo: [ + "male", + "qun", + 3, + ["warlock_huanmeng"], + ["minskin", "stone"], + [2, 3, "warlock"], + ], + stone_tongkunvwang: [ + "male", + "qun", + 2, + ["warlock_tongku"], + ["minskin", "stone"], + [2, 1, "warlock"], + ], + stone_xukongkongmo: [ + "male", + "qun", + 3, + ["warlock_tunshi"], + ["minskin", "stone"], + [3, 3, "warlock"], + ], + stone_fukongmoyan: [ + "male", + "qun", + 4, + ["warlock_shijie"], + ["minskin", "stone"], + [5, 4, "warlock"], + ], - stone_zhihuiguan:['female','qun',2,['warrior_tongling'],['minskin','stone'],[3,2,'warrior']], - stone_kuangzhanshi:['male','qun',2,['warrior_baoluan'],['minskin','stone'],[3,1,'warrior']], - stone_zhujiashi:['male','qun',2,['warrior_zhujia'],['minskin','stone'],[2,1,'warrior']], - stone_jiangong:['male','qun',2,['warrior_jiangong'],['minskin','stone'],[2,2,'warrior']], - stone_chidunshinv:['female','qun',4,['warrior_tidun'],['minskin','stone'],[5,4,'warrior']], - stone_yuanhou:['male','qun',2,['lschaofeng'],['minskin','stone'],[2,3,'warrior']], - stone_heiyaoyaoshou:['male','qun',4,['warrior_heiyao'],['minskin','stone'],[5,4,'warrior']], - stone_honglongyongshi:['male','qun',2,['warrior_fenyong'],['minskin','stone'],[2,3,'warrior']], - stone_peilianshi:['male','qun',2,['lschaofeng','warrior_peilian'],['minskin','stone'],[2,2,'warrior']], - stone_jingyingweishi:['male','qun',3,['stone_chongfeng'],['minskin','stone'],[4,3,'warrior']], - stone_mengmaren:['male','qun',3,['warrior_chuanci'],['minskin','stone'],[4,4,'warrior']], - stone_zhifuzhe:['male','qun',2,['warrior_zhifu'],['minskin','stone'],[3,1,'warrior']], + stone_zhihuiguan: [ + "female", + "qun", + 2, + ["warrior_tongling"], + ["minskin", "stone"], + [3, 2, "warrior"], + ], + stone_kuangzhanshi: [ + "male", + "qun", + 2, + ["warrior_baoluan"], + ["minskin", "stone"], + [3, 1, "warrior"], + ], + stone_zhujiashi: [ + "male", + "qun", + 2, + ["warrior_zhujia"], + ["minskin", "stone"], + [2, 1, "warrior"], + ], + stone_jiangong: [ + "male", + "qun", + 2, + ["warrior_jiangong"], + ["minskin", "stone"], + [2, 2, "warrior"], + ], + stone_chidunshinv: [ + "female", + "qun", + 4, + ["warrior_tidun"], + ["minskin", "stone"], + [5, 4, "warrior"], + ], + stone_yuanhou: ["male", "qun", 2, ["lschaofeng"], ["minskin", "stone"], [2, 3, "warrior"]], + stone_heiyaoyaoshou: [ + "male", + "qun", + 4, + ["warrior_heiyao"], + ["minskin", "stone"], + [5, 4, "warrior"], + ], + stone_honglongyongshi: [ + "male", + "qun", + 2, + ["warrior_fenyong"], + ["minskin", "stone"], + [2, 3, "warrior"], + ], + stone_peilianshi: [ + "male", + "qun", + 2, + ["lschaofeng", "warrior_peilian"], + ["minskin", "stone"], + [2, 2, "warrior"], + ], + stone_jingyingweishi: [ + "male", + "qun", + 3, + ["stone_chongfeng"], + ["minskin", "stone"], + [4, 3, "warrior"], + ], + stone_mengmaren: [ + "male", + "qun", + 3, + ["warrior_chuanci"], + ["minskin", "stone"], + [4, 4, "warrior"], + ], + stone_zhifuzhe: [ + "male", + "qun", + 2, + ["warrior_zhifu"], + ["minskin", "stone"], + [3, 1, "warrior"], + ], - stone_daomufeizei:['male','qun',3,['rogue_xunbao'],['minskin','stone'],[4,3,'rogue']], - stone_qiezei:['male','qun',2,['rogue_touqie'],['minskin','stone'],[2,2,'rogue']], - stone_heitieairen:['male','qun',2,['rogue_qiancang'],['minskin','stone'],[4,3,'rogue']], - stone_tegong:['male','qun',2,['rogue_touxi'],['minskin','stone'],[3,3,'rogue']], - stone_haidaotoumu:['male','qun',2,['rogue_zhaomu'],['minskin','stone'],[2,2,'rogue']], - stone_haidao:['male','qun',1,[],['minskin','stone','stonehidden'],[1,2,'rogue']], - stone_cike:['male','qun',1,['rogue_cisha','stone_qianxing'],['minskin','stone'],[1,1,'rogue']], - stone_duyanhaidao:['male','qun',2,['rogue_duxing'],['minskin','stone'],[3,4,'rogue']], - stone_gangtiewushi:['male','qun',2,['rogue_shoudao'],['minskin','stone'],[3,2,'rogue']], - stone_lifaji:['male','qun',2,['rogue_lifa'],['minskin','stone'],[2,2,'rogue']], - stone_shihualong:['male','qun',1,['rogue_fusheng'],['minskin','stone'],[3,2,'rogue']], - stone_xiushuihaidao:['male','qun',1,['rogue_jielue'],['minskin','stone'],[1,2,'rogue']], - stone_zousishangfan:['male','qun',3,['rogue_jiaoyi'],['minskin','stone'],[4,3,'rogue']], + stone_daomufeizei: [ + "male", + "qun", + 3, + ["rogue_xunbao"], + ["minskin", "stone"], + [4, 3, "rogue"], + ], + stone_qiezei: ["male", "qun", 2, ["rogue_touqie"], ["minskin", "stone"], [2, 2, "rogue"]], + stone_heitieairen: [ + "male", + "qun", + 2, + ["rogue_qiancang"], + ["minskin", "stone"], + [4, 3, "rogue"], + ], + stone_tegong: ["male", "qun", 2, ["rogue_touxi"], ["minskin", "stone"], [3, 3, "rogue"]], + stone_haidaotoumu: [ + "male", + "qun", + 2, + ["rogue_zhaomu"], + ["minskin", "stone"], + [2, 2, "rogue"], + ], + stone_haidao: ["male", "qun", 1, [], ["minskin", "stone", "stonehidden"], [1, 2, "rogue"]], + stone_cike: [ + "male", + "qun", + 1, + ["rogue_cisha", "stone_qianxing"], + ["minskin", "stone"], + [1, 1, "rogue"], + ], + stone_duyanhaidao: [ + "male", + "qun", + 2, + ["rogue_duxing"], + ["minskin", "stone"], + [3, 4, "rogue"], + ], + stone_gangtiewushi: [ + "male", + "qun", + 2, + ["rogue_shoudao"], + ["minskin", "stone"], + [3, 2, "rogue"], + ], + stone_lifaji: ["male", "qun", 2, ["rogue_lifa"], ["minskin", "stone"], [2, 2, "rogue"]], + stone_shihualong: [ + "male", + "qun", + 1, + ["rogue_fusheng"], + ["minskin", "stone"], + [3, 2, "rogue"], + ], + stone_xiushuihaidao: [ + "male", + "qun", + 1, + ["rogue_jielue"], + ["minskin", "stone"], + [1, 2, "rogue"], + ], + stone_zousishangfan: [ + "male", + "qun", + 3, + ["rogue_jiaoyi"], + ["minskin", "stone"], + [4, 3, "rogue"], + ], - stone_beijunmushi:['male','qun',2,['priest_shengliao'],['minskin','stone'],[1,1,'priest']], - stone_guanliyuan:['male','qun',2,['priest_faxian'],['minskin','stone'],[2,1,'priest']], - stone_linghunjisi:['female','qun',4,['priest_hunwu'],['minskin','stone'],[4,2,'priest']], - stone_heianjiaotu:['male','qun',3,['priest_zhufu'],['minskin','stone'],[3,2,'priest']], - stone_guangyaozhizi:['male','qun',3,['priest_guangyao'],['minskin','stone'],[5,3,'priest']], - stone_longmianjiaoguan:['male','qun',2,['priest_xundao'],['minskin','stone'],[2,2,'priest']], - stone_shengdianzhishi:['male','qun',4,['priest_puzhao'],['minskin','stone'],[5,4,'priest']], - stone_suoxiaojishi:['male','qun',2,['priest_suoxiao'],['minskin','stone'],[2,2,'priest']], - stone_anyingzisi:['male','qun',3,['priest_shixin'],['minskin','stone'],[4,4,'priest']], - stone_guangmingquan:['male','qun',3,['priest_shengshui'],['minskin','stone'],[2,0,'priest']], - stone_muguangchulong:['male','qun',2,['priest_muguang'],['minskin','stone'],[1,1,'priest']], - stone_shenshengyongshi:['male','qun',3,['priest_shengguang'],['minskin','stone'],[4,3,'priest']], + stone_beijunmushi: [ + "male", + "qun", + 2, + ["priest_shengliao"], + ["minskin", "stone"], + [1, 1, "priest"], + ], + stone_guanliyuan: [ + "male", + "qun", + 2, + ["priest_faxian"], + ["minskin", "stone"], + [2, 1, "priest"], + ], + stone_linghunjisi: [ + "female", + "qun", + 4, + ["priest_hunwu"], + ["minskin", "stone"], + [4, 2, "priest"], + ], + stone_heianjiaotu: [ + "male", + "qun", + 3, + ["priest_zhufu"], + ["minskin", "stone"], + [3, 2, "priest"], + ], + stone_guangyaozhizi: [ + "male", + "qun", + 3, + ["priest_guangyao"], + ["minskin", "stone"], + [5, 3, "priest"], + ], + stone_longmianjiaoguan: [ + "male", + "qun", + 2, + ["priest_xundao"], + ["minskin", "stone"], + [2, 2, "priest"], + ], + stone_shengdianzhishi: [ + "male", + "qun", + 4, + ["priest_puzhao"], + ["minskin", "stone"], + [5, 4, "priest"], + ], + stone_suoxiaojishi: [ + "male", + "qun", + 2, + ["priest_suoxiao"], + ["minskin", "stone"], + [2, 2, "priest"], + ], + stone_anyingzisi: [ + "male", + "qun", + 3, + ["priest_shixin"], + ["minskin", "stone"], + [4, 4, "priest"], + ], + stone_guangmingquan: [ + "male", + "qun", + 3, + ["priest_shengshui"], + ["minskin", "stone"], + [2, 0, "priest"], + ], + stone_muguangchulong: [ + "male", + "qun", + 2, + ["priest_muguang"], + ["minskin", "stone"], + [1, 1, "priest"], + ], + stone_shenshengyongshi: [ + "male", + "qun", + 3, + ["priest_shengguang"], + ["minskin", "stone"], + [4, 3, "priest"], + ], - stone_zhongshi:['male','wei',1,['stone_zhongshi1'],['minskin','stone'],[1,2]], - stone_zhucangzhe:['male','wei',1,['stone_zhucangzhe1'],['minskin','stone'],[1,2]], - stone_huoqiangshou:['male','wei',3,['stone_huoqiangshou1'],['minskin','stone'],[3,1]], + stone_zhongshi: ["male", "wei", 1, ["stone_zhongshi1"], ["minskin", "stone"], [1, 2]], + stone_zhucangzhe: ["male", "wei", 1, ["stone_zhucangzhe1"], ["minskin", "stone"], [1, 2]], + stone_huoqiangshou: ["male", "wei", 3, ["stone_huoqiangshou1"], ["minskin", "stone"], [3, 1]], - stone_lansaizhanshi:['male','shu',1,['stone_chongfeng'],['minskin','stone'],[1,2]], - stone_kutongsiseng:['male','shu',1,['stone_kutongsiseng1'],['minskin','stone'],[1,2]], - stone_yuanguanying:['male','shu',3,['stone_yuanguanying1'],['minskin','stone'],[3,1]], + stone_lansaizhanshi: ["male", "shu", 1, ["stone_chongfeng"], ["minskin", "stone"], [1, 2]], + stone_kutongsiseng: ["male", "shu", 1, ["stone_kutongsiseng1"], ["minskin", "stone"], [1, 2]], + stone_yuanguanying: ["male", "shu", 3, ["stone_yuanguanying1"], ["minskin", "stone"], [3, 1]], - stone_dijieshicong:['male','wu',2,['stone_dijieshicong1'],['minskin','stone'],[1,1]], - stone_yaosaishouwei:['male','wu',2,['stone_yaosaishouwei1'],['minskin','stone'],[1,1]], - stone_famingjia:['male','wu',3,['stone_famingjia1'],['minskin','stone'],[3,1]], + stone_dijieshicong: ["male", "wu", 2, ["stone_dijieshicong1"], ["minskin", "stone"], [1, 1]], + stone_yaosaishouwei: [ + "male", + "wu", + 2, + ["stone_yaosaishouwei1"], + ["minskin", "stone"], + [1, 1], + ], + stone_famingjia: ["male", "wu", 3, ["stone_famingjia1"], ["minskin", "stone"], [3, 1]], - stone_chilundashi:['male','qun',2,['stone_chilundashi1'],['minskin','stone'],[1,1]], - stone_hanguangzhizhe:['male','qun',2,['stone_hanguangzhizhe1'],['minskin','stone'],[2,2]], - stone_aihaozhihun:['male','qun',3,['stone_aihaozhihun1'],['minskin','stone'],[3,1]], + stone_chilundashi: ["male", "qun", 2, ["stone_chilundashi1"], ["minskin", "stone"], [1, 1]], + stone_hanguangzhizhe: [ + "male", + "qun", + 2, + ["stone_hanguangzhizhe1"], + ["minskin", "stone"], + [2, 2], + ], + stone_aihaozhihun: ["male", "qun", 3, ["stone_aihaozhihun1"], ["minskin", "stone"], [3, 1]], - stone_fennuxiaoji:['male','qun',1,['stone_fennuxiaoji1'],['minskin','stone'],[1,2]], - stone_juxingchanchu:['male','qun',2,['stone_juxingchanchu1'],['minskin','stone'],[2,1]], - stone_wuyi:['male','qun',1,['jijiu'],['minskin','stone','die_audio'],[2,2]], - stone_langren:['male','qun',1,['stone_qianxing'],['minskin','stone'],[1,2]], - stone_shishigui:['male','qun',2,['stone_shishigui1'],['minskin','stone'],[2,1]], + stone_fennuxiaoji: ["male", "qun", 1, ["stone_fennuxiaoji1"], ["minskin", "stone"], [1, 2]], + stone_juxingchanchu: [ + "male", + "qun", + 2, + ["stone_juxingchanchu1"], + ["minskin", "stone"], + [2, 1], + ], + stone_wuyi: ["male", "qun", 1, ["jijiu"], ["minskin", "stone", "die_audio"], [2, 2]], + stone_langren: ["male", "qun", 1, ["stone_qianxing"], ["minskin", "stone"], [1, 2]], + stone_shishigui: ["male", "qun", 2, ["stone_shishigui1"], ["minskin", "stone"], [2, 1]], - stone_fatiaozhuru:['female','qun',1,['stone_fatiaozhuru1'],['minskin','stone'],[1,2]], - stone_mingguangjisi:['female','wu',2,['shushen'],['minskin','stone'],[2,1]], - stone_nianqingjisi:['female','wei',2,['stone_zhufu'],['minskin','stone'],[2,1]], - stone_aomishouwei:['female','qun',1,['biyue'],['minskin','stone'],[2,2]], - stone_yanjingshe:['female','qun',2,['stone_yanjingshe1'],['minskin','stone'],[3,2]], - stone_zhiyuzhe:['female','qun',3,['stone_zhiyu'],['minskin','stone'],[3,1]], - stone_mafengzhuru:['female','qun',1,['stone_mafengzhuru1'],['minskin','stone'],[1,2]], + stone_fatiaozhuru: ["female", "qun", 1, ["stone_fatiaozhuru1"], ["minskin", "stone"], [1, 2]], + stone_mingguangjisi: ["female", "wu", 2, ["shushen"], ["minskin", "stone"], [2, 1]], + stone_nianqingjisi: ["female", "wei", 2, ["stone_zhufu"], ["minskin", "stone"], [2, 1]], + stone_aomishouwei: ["female", "qun", 1, ["biyue"], ["minskin", "stone"], [2, 2]], + stone_yanjingshe: ["female", "qun", 2, ["stone_yanjingshe1"], ["minskin", "stone"], [3, 2]], + stone_zhiyuzhe: ["female", "qun", 3, ["stone_zhiyu"], ["minskin", "stone"], [3, 1]], + stone_mafengzhuru: ["female", "qun", 1, ["stone_mafengzhuru1"], ["minskin", "stone"], [1, 2]], - stone_shumiao:['none','wu',1,[],['minskin','stone','stonehidden'],[1,1]], - stone_shuren:['none','wu',2,['stone_chongfeng','stone_zibao'],['minskin','stone','stonehidden'],[2,2]], - stone_shurenx:['none','wu',2,[],['minskin','stone','stonehidden'],[2,2]], - stone_shurenxx:['none','wu',2,['lschaofeng'],['minskin','stone','stonehidden'],[2,2]], - stone_youlinglang:['none','qun',2,['lschaofeng'],['minskin','stone','stonehidden'],[2,2]], - stone_xiaojingling:['none','qun',1,['xuying'],['minskin','stone','stonehidden'],[1,1]], - stone_zhumo:['none','qun',2,[],['minskin','stone','stonehidden'],[2,2]], - stone_jingxiang:['none','qun',2,['stone_jingxiang','lschaofeng'],['minskin','stone','stonehidden'],[2,0]], - stone_shengguanghuwei:['female','qun',2,['priest_shengguang'],['minskin','stone','stonehidden'],[1,1]], - stone_liegou:['none','qun',1,['stone_chongfeng'],['minskin','stone','stonehidden'],[1,2]], - stone_mianyang:['none','qun',1,['mage_mianyang'],['minskin','stone','stonehidden'],[1,0]], - stone_qingwa:['none','wu',1,['shaman_qingwa'],['minskin','stone','stonehidden'],[1,0]], - stone_shengjiachong:['none','qun',1,['lschaofeng'],['minskin','stone','stonehidden'],[1,1]], + stone_shumiao: ["none", "wu", 1, [], ["minskin", "stone", "stonehidden"], [1, 1]], + stone_shuren: [ + "none", + "wu", + 2, + ["stone_chongfeng", "stone_zibao"], + ["minskin", "stone", "stonehidden"], + [2, 2], + ], + stone_shurenx: ["none", "wu", 2, [], ["minskin", "stone", "stonehidden"], [2, 2]], + stone_shurenxx: [ + "none", + "wu", + 2, + ["lschaofeng"], + ["minskin", "stone", "stonehidden"], + [2, 2], + ], + stone_youlinglang: [ + "none", + "qun", + 2, + ["lschaofeng"], + ["minskin", "stone", "stonehidden"], + [2, 2], + ], + stone_xiaojingling: [ + "none", + "qun", + 1, + ["xuying"], + ["minskin", "stone", "stonehidden"], + [1, 1], + ], + stone_zhumo: ["none", "qun", 2, [], ["minskin", "stone", "stonehidden"], [2, 2]], + stone_jingxiang: [ + "none", + "qun", + 2, + ["stone_jingxiang", "lschaofeng"], + ["minskin", "stone", "stonehidden"], + [2, 0], + ], + stone_shengguanghuwei: [ + "female", + "qun", + 2, + ["priest_shengguang"], + ["minskin", "stone", "stonehidden"], + [1, 1], + ], + stone_liegou: [ + "none", + "qun", + 1, + ["stone_chongfeng"], + ["minskin", "stone", "stonehidden"], + [1, 2], + ], + stone_mianyang: [ + "none", + "qun", + 1, + ["mage_mianyang"], + ["minskin", "stone", "stonehidden"], + [1, 0], + ], + stone_qingwa: [ + "none", + "wu", + 1, + ["shaman_qingwa"], + ["minskin", "stone", "stonehidden"], + [1, 0], + ], + stone_shengjiachong: [ + "none", + "qun", + 1, + ["lschaofeng"], + ["minskin", "stone", "stonehidden"], + [1, 1], + ], - stone_tuteng1:['none','qun',2,['shaman_tuteng','lschaofeng'],['minskin','stone','stonehidden'],[2,0]], - stone_tuteng2:['none','qun',2,['shaman_tuteng','shaman_zhuore'],['minskin','stone','stonehidden'],[2,0]], - stone_tuteng3:['none','qun',2,['shaman_tuteng','shaman_fali'],['minskin','stone','stonehidden'],[2,0]], - stone_tuteng4:['none','qun',2,['shaman_tuteng','shaman_zhiliao'],['minskin','stone','stonehidden'],[2,0]], - stone_xinbing:['none','qun',2,[],['minskin','stone','stonehidden'],[2,0]], + stone_tuteng1: [ + "none", + "qun", + 2, + ["shaman_tuteng", "lschaofeng"], + ["minskin", "stone", "stonehidden"], + [2, 0], + ], + stone_tuteng2: [ + "none", + "qun", + 2, + ["shaman_tuteng", "shaman_zhuore"], + ["minskin", "stone", "stonehidden"], + [2, 0], + ], + stone_tuteng3: [ + "none", + "qun", + 2, + ["shaman_tuteng", "shaman_fali"], + ["minskin", "stone", "stonehidden"], + [2, 0], + ], + stone_tuteng4: [ + "none", + "qun", + 2, + ["shaman_tuteng", "shaman_zhiliao"], + ["minskin", "stone", "stonehidden"], + [2, 0], + ], + stone_xinbing: ["none", "qun", 2, [], ["minskin", "stone", "stonehidden"], [2, 0]], - stone_siwangzhiyi:['male','qun',4,['stone_mieshi'],['minskin','stone','stonehidden','stonelegend'],[6,4]], - stone_alaikesita:['female','qun',4,['stone_fushi'],['minskin','stone','stonehidden','stonelegend'],[6,4]], - stone_yisela:['female','qun',4,['stone_chenshui'],['minskin','stone','stonehidden','stonelegend'],[6,2]], - stone_nuoziduomu:['male','qun',4,['stone_shixu'],['minskin','stone','stonehidden','stonelegend'],[6,4]], - stone_maligousi:['male','qun',4,['stone_mowang'],['minskin','stone','stonehidden','stonelegend'],[6,2]], + stone_siwangzhiyi: [ + "male", + "qun", + 4, + ["stone_mieshi"], + ["minskin", "stone", "stonehidden", "stonelegend"], + [6, 4], + ], + stone_alaikesita: [ + "female", + "qun", + 4, + ["stone_fushi"], + ["minskin", "stone", "stonehidden", "stonelegend"], + [6, 4], + ], + stone_yisela: [ + "female", + "qun", + 4, + ["stone_chenshui"], + ["minskin", "stone", "stonehidden", "stonelegend"], + [6, 2], + ], + stone_nuoziduomu: [ + "male", + "qun", + 4, + ["stone_shixu"], + ["minskin", "stone", "stonehidden", "stonelegend"], + [6, 4], + ], + stone_maligousi: [ + "male", + "qun", + 4, + ["stone_mowang"], + ["minskin", "stone", "stonehidden", "stonelegend"], + [6, 2], + ], - stone_aolajier:['male','qun',4,['stone_chongfeng','shaman_fengnu','paladin_hudun','lschaofeng'],['minskin','stone','stonehidden','stonelegend_shaman'],[6,4]], - stone_andongni:['male','qun',4,['stone_zhiyin'],['minskin','stone','stonehidden','stonelegend_mage'],[6,4]], - stone_jialakesi:['male','qun',6,['stone_bianshen'],['minskin','stone','stonehidden','stonelegend_warlock'],[6,0]], - stone_jialakesix:['male','qun',6,['stone_lianyu'],['modeimage','stonehidden','stonespecial']], - stone_kelushi:['male','qun',5,['stone_chongfeng'],['minskin','stone','stonehidden','stonelegend_hunter'],[6,5]], - stone_geluomashi:['male','qun',4,['stone_chongfeng','stone_jinu'],['minskin','stone','stonehidden','stonelegend_warrior'],[6,4]], - stone_aidewen:['male','qun',3,['stone_lianji'],['minskin','stone','stonehidden','stonelegend_rogue'],[6,3]], - stone_sainaliusi:['male','qun',3,['stone_shenyu'],['minskin','stone','stonehidden','stonelegend_druid'],[6,3]], - stone_fuding:['male','qun',3,['paladin_hudun','lschaofeng','stone_fuchou'],['minskin','stone','stonehidden','stonelegend_paladin'],[6,3]], - stone_weilun:['male','qun',4,['stone_shenyou'],['minskin','stone','stonehidden','stonelegend_priest'],[6,6]], - } + stone_aolajier: [ + "male", + "qun", + 4, + ["stone_chongfeng", "shaman_fengnu", "paladin_hudun", "lschaofeng"], + ["minskin", "stone", "stonehidden", "stonelegend_shaman"], + [6, 4], + ], + stone_andongni: [ + "male", + "qun", + 4, + ["stone_zhiyin"], + ["minskin", "stone", "stonehidden", "stonelegend_mage"], + [6, 4], + ], + stone_jialakesi: [ + "male", + "qun", + 6, + ["stone_bianshen"], + ["minskin", "stone", "stonehidden", "stonelegend_warlock"], + [6, 0], + ], + stone_jialakesix: [ + "male", + "qun", + 6, + ["stone_lianyu"], + ["modeimage", "stonehidden", "stonespecial"], + ], + stone_kelushi: [ + "male", + "qun", + 5, + ["stone_chongfeng"], + ["minskin", "stone", "stonehidden", "stonelegend_hunter"], + [6, 5], + ], + stone_geluomashi: [ + "male", + "qun", + 4, + ["stone_chongfeng", "stone_jinu"], + ["minskin", "stone", "stonehidden", "stonelegend_warrior"], + [6, 4], + ], + stone_aidewen: [ + "male", + "qun", + 3, + ["stone_lianji"], + ["minskin", "stone", "stonehidden", "stonelegend_rogue"], + [6, 3], + ], + stone_sainaliusi: [ + "male", + "qun", + 3, + ["stone_shenyu"], + ["minskin", "stone", "stonehidden", "stonelegend_druid"], + [6, 3], + ], + stone_fuding: [ + "male", + "qun", + 3, + ["paladin_hudun", "lschaofeng", "stone_fuchou"], + ["minskin", "stone", "stonehidden", "stonelegend_paladin"], + [6, 3], + ], + stone_weilun: [ + "male", + "qun", + 4, + ["stone_shenyou"], + ["minskin", "stone", "stonehidden", "stonelegend_priest"], + [6, 6], + ], + }, }, - careerList:['mage','shaman','druid','paladin','rogue','priest','hunter','warrior','warlock'], - game:{ - reserveDead:true, - bannedcards:['lebu','guiyoujie','xietianzi','lingjiandai','jiguanshu','sifeizhenmian','fengxueren','chuansongmen'], - onwash:function(){ - if(_status.mode!='deck') return; - var list=[]; - for(var i=0;i'+i+'',buttons,clickButton); - ui.create.div('.menubutton.round',deckitem).dataset.career=lib.storage.deckList[i].career; - deckitem.name=i; + for (var i in lib.storage.deckList) { + if (lib.storage.deckList[i].deck.length == 30) { + var deckitem = ui.create.div( + ".deckitem.shadowed", + "" + i + "", + buttons, + clickButton + ); + ui.create.div(".menubutton.round", deckitem).dataset.career = + lib.storage.deckList[i].career; + deckitem.name = i; } } - for(var i=0;i随机',buttons,clickButton); - ui.create.div('.menubutton.round',deckitem).dataset.career=lib.careerList[i]; - deckitem.name='random:'+lib.careerList[i]; + for (var i = 0; i < lib.careerList.length; i++) { + var deckitem = ui.create.div( + ".deckitem.shadowed", + "随机", + buttons, + clickButton + ); + ui.create.div(".menubutton.round", deckitem).dataset.career = + lib.careerList[i]; + deckitem.name = "random:" + lib.careerList[i]; } event.dialog.open(); - } - else{ - var bn=parseInt(get.config('battle_number')); - for(var i=0;ib) return 1; - if(a==b) return 0; + deck.sort(function (a, b) { + if (a > b) return 1; + if (a == b) return 0; return -1; }); - player.deck=name; - player.career=career; - if(!player.node.career){ - player.node.career=ui.create.div('.menubutton.round.identity',player); - player.node.career.dataset.career=career; - lib.setIntro(player.node.career,null,true); + player.deck = name; + player.career = career; + if (!player.node.career) { + player.node.career = ui.create.div(".menubutton.round.identity", player); + player.node.career.dataset.career = career; + lib.setIntro(player.node.career, null, true); } - if(!player.deckCards) player.deckCards=[]; - for(var i=0;i=2) return 1; + ai: { + order: 7, + value: 5, + useful: 5, + result: { + player: function (player) { + if (player.getEnemy().countFellow() >= 2) return 1; return 0; - } - } - } + }, + }, + }, }, - spell_linghunhongxi:{ - type:'stonecard', - stoneact:4, - career:'warlock', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ + spell_linghunhongxi: { + type: "stonecard", + stoneact: 4, + career: "warlock", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.die(); - 'step 1' + "step 1"; player.recover(); }, - ai:{ - order:7.5, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -target.hp-target.countCards('h')/2; - } - } - } + ai: { + order: 7.5, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -target.hp - target.countCards("h") / 2; + }, + }, + }, }, - spell_fushishu:{ - type:'stonecard', - stoneact:2, - career:'warlock', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&!target.hasSkill('warlock_fushishu'); + spell_fushishu: { + type: "stonecard", + stoneact: 2, + career: "warlock", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && !target.hasSkill("warlock_fushishu"); }, - content:function(){ - target.addSkill('warlock_fushishu'); + content: function () { + target.addSkill("warlock_fushishu"); + }, + ai: { + order: 7.5, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -target.hp - target.countCards("h") / 2; + }, + }, }, - ai:{ - order:7.5, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -target.hp-target.countCards('h')/2; - } - } - } }, - spell_fuchoudaji:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:3, - career:'warrior', - filterTarget:function(card,player,target){ + spell_fuchoudaji: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 3, + career: "warrior", + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - content:function(){ - if(player.hp<=2){ + selectTarget: -1, + content: function () { + if (player.hp <= 2) { target.damage(3); - } - else{ + } else { target.damage(); } }, - ai:{ - order:8.9, - value:5, - useful:5, - result:{ - target:-1.5 + ai: { + order: 8.9, + value: 5, + useful: 5, + result: { + target: -1.5, + }, + tag: { + damage: 1, + multitarget: 1, + multineg: 1, }, - tag:{ - damage:1, - multitarget:1, - multineg:1, - } - } - }, - spell_yingyongdaji:{ - type:'stonecard', - stoneact:2, - career:'warrior', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.side!=player.side; }, - content:function(){ - 'step 0' - player.damage(2,target); - 'step 1' + }, + spell_yingyongdaji: { + type: "stonecard", + stoneact: 2, + career: "warrior", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.side != player.side; + }, + content: function () { + "step 0"; + player.damage(2, target); + "step 1"; target.damage(2); }, - ai:{ - order:8, - value:5, - useful:5, - result:{ - target:function(player,target){ - if(player.hujia>=2) return -1.5; - if(player.hujia==1){ - if(player.hp>3) return -1.5; + ai: { + order: 8, + value: 5, + useful: 5, + result: { + target: function (player, target) { + if (player.hujia >= 2) return -1.5; + if (player.hujia == 1) { + if (player.hp > 3) return -1.5; return 0; } return 0; - } + }, }, - tag:{ - damage:1, - } - } + tag: { + damage: 1, + }, + }, }, - spell_zhandounuhuo:{ - type:'stonecard', - fullimage:true, - enable:function(event,player){ - for(var i=0;i=2) return -1.5; + if (num >= 2) return -1.5; } } return 0; }, - tag:{ - damage:1 - } - } - } + tag: { + damage: 1, + }, + }, + }, }, - spell_jinyingduijue:{ - type:'stonecard', - stoneact:4, - career:'paladin', - enable:function(card,player){ - var n1=player.countFellow(); - var n2=player.getEnemy().countFellow(); - return n1>0&&n2>0&&n1+n2>2; + spell_jinyingduijue: { + type: "stonecard", + stoneact: 4, + career: "paladin", + enable: function (card, player) { + var n1 = player.countFellow(); + var n2 = player.getEnemy().countFellow(); + return n1 > 0 && n2 > 0 && n1 + n2 > 2; }, - fullimage:true, - filterTarget:function(card,player,target){ + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - if(!targets.length){ + selectTarget: -1, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + if (!targets.length) { event.finish(); return; } - var maxf=[],maxe=[]; - for(var i=0;i maxf[0].hp) { + maxf.length = 0; maxf.push(targets[i]); } - else if(targets[i].hp>maxf[0].hp){ - maxf.length=0; - maxf.push(targets[i]); - } - } - else{ - if(!maxe.length||targets[i].hp==maxe[0].hp){ + } else { + if (!maxe.length || targets[i].hp == maxe[0].hp) { maxe.push(targets[i]); - } - else if(targets[i].hp>maxe[0].hp){ - maxe.length=0; + } else if (targets[i].hp > maxe[0].hp) { + maxe.length = 0; maxe.push(targets[i]); } } } - if(maxf.length){ + if (maxf.length) { targets.remove(maxf.randomGet()); } - if(maxe.length){ + if (maxe.length) { targets.remove(maxe.randomGet()); } targets.sort(lib.sort.seat); - event.targets=targets; - 'step 1' - if(event.targets.length){ + event.targets = targets; + "step 1"; + if (event.targets.length) { event.targets.shift().die(); event.redo(); } }, - ai:{ - order:9, - value:2, - useful:2, - result:{ - player:function(player,target){ - return player.getEnemy().countFellow()-player.countFellow(); - } - } - } + ai: { + order: 9, + value: 2, + useful: 2, + result: { + player: function (player, target) { + return player.getEnemy().countFellow() - player.countFellow(); + }, + }, + }, }, - spell_zhihuizhufu:{ - type:'stonecard', - stoneact:1, - career:'paladin', - enable:function(card,player){ + spell_zhihuizhufu: { + type: "stonecard", + stoneact: 1, + career: "paladin", + enable: function (card, player) { return !player.isMin(); }, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&!target.hasSkill('paladin_zhihuizhufu'); + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && !target.hasSkill("paladin_zhihuizhufu"); }, - content:function(){ - target.addSkill('paladin_zhihuizhufu'); - target.storage.paladin_zhihuizhufu=player; + content: function () { + target.addSkill("paladin_zhihuizhufu"); + target.storage.paladin_zhihuizhufu = player; }, - ai:{ - order:2, - value:5, - useful:5, - result:{ - player:function(player,target){ + ai: { + order: 2, + value: 5, + useful: 5, + result: { + player: function (player, target) { return target.hp; - } - } - } + }, + }, + }, }, - spell_shenshengfennu:{ - type:'stonecard', - stoneact:5, - career:'paladin', - enable:true, - fullimage:true, - filterTarget:true, - content:function(){ - 'step 0' - event.card=player.getDeckCards()[0]; - player.gain(event.card,'gain2','log'); - 'step 1' - var num=lib.card[event.card.name].stoneact; - if(num&&typeof num=='number'){ + spell_shenshengfennu: { + type: "stonecard", + stoneact: 5, + career: "paladin", + enable: true, + fullimage: true, + filterTarget: true, + content: function () { + "step 0"; + event.card = player.getDeckCards()[0]; + player.gain(event.card, "gain2", "log"); + "step 1"; + var num = lib.card[event.card.name].stoneact; + if (num && typeof num == "number") { target.damage(num); } }, - ai:{ - order:6, - value:2, - useful:2, - result:{ - target:-2 + ai: { + order: 6, + value: 2, + useful: 2, + result: { + target: -2, }, - tag:{ - damage:2 - } - } + tag: { + damage: 2, + }, + }, }, - spell_yongshizhufu:{ - type:'stonecard', - stoneact:2, - career:'paladin', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.countCards('h')>0; + spell_yongshizhufu: { + type: "stonecard", + stoneact: 2, + career: "paladin", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.countCards("h") > 0; }, - content:function(){ - target.draw(target.countCards('h')); + content: function () { + target.draw(target.countCards("h")); + }, + ai: { + order: 4, + value: 2, + useful: 2, + result: { + target: function (player, target) { + return Math.max(0, target.countCards("h") - 1); + }, + }, }, - ai:{ - order:4, - value:2, - useful:2, - result:{ - target:function(player,target){ - return Math.max(0,target.countCards('h')-1); - } - } - } }, - spell_shenpan:{ - type:'stonecard', - stoneact:2, - career:'paladin', - enable:function(card,player){ - var num=player.getEnemy().countFellow(); - return num>0&&num>=player.countFellow(); + spell_shenpan: { + type: "stonecard", + stoneact: 2, + career: "paladin", + enable: function (card, player) { + var num = player.getEnemy().countFellow(); + return num > 0 && num >= player.countFellow(); }, - fullimage:true, - notarget:true, - content:function(){ - var target=player.getEnemy().getFellow().randomGet(); + fullimage: true, + notarget: true, + content: function () { + var target = player.getEnemy().getFellow().randomGet(); player.line(target); target.die(); }, - ai:{ - order:9, - value:4, - useful:4, - result:{ - player:1 - } - } + ai: { + order: 9, + value: 4, + useful: 4, + result: { + player: 1, + }, + }, }, - spell_zhengqianghaosheng:{ - type:'stonecard', - stoneact:2, - career:'paladin', - enable:function(card,player){ - return !player.hasSkill('paladin_zhengqianghaosheng'); + spell_zhengqianghaosheng: { + type: "stonecard", + stoneact: 2, + career: "paladin", + enable: function (card, player) { + return !player.hasSkill("paladin_zhengqianghaosheng"); }, - fullimage:true, - filterTarget:function(card,player,target){ - return player==target; + fullimage: true, + filterTarget: function (card, player, target) { + return player == target; }, - selectTarget:-1, - content:function(){ - player.addSkill('paladin_zhengqianghaosheng'); + selectTarget: -1, + content: function () { + player.addSkill("paladin_zhengqianghaosheng"); }, - ai:{ - order:3, - value:4, - useful:4, - result:{ - player:function(player){ - if(player.countFellow()>=2) return 1; + ai: { + order: 3, + value: 4, + useful: 4, + result: { + player: function (player) { + if (player.countFellow() >= 2) return 1; return 0; - } - } - } + }, + }, + }, }, - spell_zhenyanshu:{ - type:'stonecard', - stoneact:1, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ + spell_zhenyanshu: { + type: "stonecard", + stoneact: 1, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ + content: function () { target.maxHp++; target.hp++; target.update(); player.drawDeck(); }, - ai:{ - order:7, - value:3, - useful:3, - result:{ - target:function(player,target){ - return Math.max(1,10-target.hp); - } - } - } + ai: { + order: 7, + value: 3, + useful: 3, + result: { + target: function (player, target) { + return Math.max(1, 10 - target.hp); + }, + }, + }, }, - spell_enzeshu:{ - type:'stonecard', - stoneact:3, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ + spell_enzeshu: { + type: "stonecard", + stoneact: 3, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ - target.maxHp+=3; - target.hp+=3; + content: function () { + target.maxHp += 3; + target.hp += 3; target.update(); }, - ai:{ - order:5, - value:3, - useful:3, - result:{ - target:function(player,target){ - return Math.max(1,10-target.hp); - } - } - } + ai: { + order: 5, + value: 3, + useful: 3, + result: { + target: function (player, target) { + return Math.max(1, 10 - target.hp); + }, + }, + }, }, - spell_anyingxingtai:{ - type:'stonecard', - stoneact:2, - career:'priest', - recastable:true, - enable:function(event,player){ - if(player.career!='priest') return false; - return !player.storage.anyingxingtai||player.storage.anyingxingtai<2; + spell_anyingxingtai: { + type: "stonecard", + stoneact: 2, + career: "priest", + recastable: true, + enable: function (event, player) { + if (player.career != "priest") return false; + return !player.storage.anyingxingtai || player.storage.anyingxingtai < 2; }, - fullimage:true, - filterTarget:function(card,player,target){ - return player==target; + fullimage: true, + filterTarget: function (card, player, target) { + return player == target; }, - selectTarget:-1, - content:function(){ - if(typeof player.storage.anyingxingtai!='number'){ - player.storage.anyingxingtai=1; + selectTarget: -1, + content: function () { + if (typeof player.storage.anyingxingtai != "number") { + player.storage.anyingxingtai = 1; + } else if (player.storage.anyingxingtai < 2) { + player.storage.anyingxingtai = 2; } - else if(player.storage.anyingxingtai<2){ - player.storage.anyingxingtai=2; - } - player.markSkill('priest_anyingxingtai'); + player.markSkill("priest_anyingxingtai"); + }, + ai: { + order: 6.1, + value: 3, + useful: 3, + result: { + player: 1, + }, }, - ai:{ - order:6.1, - value:3, - useful:3, - result:{ - player:1 - } - } }, - spell_kuaisuzhiliao:{ - type:'stonecard', - stoneact:2, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - if(player.hasFellowSkill('priest_hunwu')){ + spell_kuaisuzhiliao: { + type: "stonecard", + stoneact: 2, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + if (player.hasFellowSkill("priest_hunwu")) { return true; } - return target.hp=2) return 1; + if (num >= 2) return 1; } } return 0; - } - } - } + }, + }, + }, }, - spell_heiandiyu:{ - fullimage:true, - type:'stonecard', - enable:true, - stoneact:4, - career:'druid', - filterTarget:function(card,player,target){ + spell_heiandiyu: { + fullimage: true, + type: "stonecard", + enable: true, + stoneact: 4, + career: "druid", + filterTarget: function (card, player, target) { return target.isMin(); }, - multitarget:true, - targetprompt:['增加体力并摸牌'], - selectTarget:[0,1], - notarget:true, - content:function(){ - 'step 0' - if(targets.length){ + multitarget: true, + targetprompt: ["增加体力并摸牌"], + selectTarget: [0, 1], + notarget: true, + content: function () { + "step 0"; + if (targets.length) { targets[0].maxHp++; targets[0].hp++; target.update(); targets[0].draw(3); event.finish(); + } else { + event.num = 0; } - else{ - event.num=0; - } - 'step 1' - if(player.canAddFellow()&&event.num++<10){ - player.addFellowAuto('stone_xiaojingling'); + "step 1"; + if (player.canAddFellow() && event.num++ < 10) { + player.addFellowAuto("stone_xiaojingling"); event.redo(); } }, - ai:{ - order:5, - result:{ - target:function(player,target){ - return Math.max(1,target.hp-target.countCards('h')); + ai: { + order: 5, + result: { + target: function (player, target) { + return Math.max(1, target.hp - target.countCards("h")); }, - } - } + }, + }, }, - spell_ziyang:{ - type:'stonecard', - stoneact:3, - career:'druid', - enable:function(card,player){ - return player.deckCards&&!player.isMin(); + spell_ziyang: { + type: "stonecard", + stoneact: 3, + career: "druid", + enable: function (card, player) { + return player.deckCards && !player.isMin(); }, - fullimage:true, - filterTarget:function(card,player,target){ - return player==target; + fullimage: true, + filterTarget: function (card, player, target) { + return player == target; }, - selectTarget:-1, - content:function(){ - 'step 0' - if(player.hasSkill('druid_ziyang')){ + selectTarget: -1, + content: function () { + "step 0"; + if (player.hasSkill("druid_ziyang")) { player.drawDeck(3); event.finish(); - } - else{ - player.chooseControl('获得行动值','摸牌').ai=function(){ - if(player.countCards('h')<=1) return '摸牌'; - return '获得行动值'; + } else { + player.chooseControl("获得行动值", "摸牌").ai = function () { + if (player.countCards("h") <= 1) return "摸牌"; + return "获得行动值"; }; } - 'step 1' - if(result.control=='摸牌'){ + "step 1"; + if (result.control == "摸牌") { player.drawDeck(3); - } - else{ - player.addSkill('druid_ziyang'); + } else { + player.addSkill("druid_ziyang"); } }, - ai:{ - order:1, - value:4, - useful:4, - result:{ - player:1 - } - } + ai: { + order: 1, + value: 4, + useful: 4, + result: { + player: 1, + }, + }, }, - spell_xingchenzhuiluo:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:6, - career:'druid', - targetprompt:['造成五点伤害'], - multitarget:true, - filterTarget:function(card,player,target){ - return target.side!=player.side&&target.isMin(); + spell_xingchenzhuiluo: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 6, + career: "druid", + targetprompt: ["造成五点伤害"], + multitarget: true, + filterTarget: function (card, player, target) { + return target.side != player.side && target.isMin(); }, - selectTarget:[0,1], - notarget:true, - content:function(){ - 'step 0' - if(targets.length){ + selectTarget: [0, 1], + notarget: true, + content: function () { + "step 0"; + if (targets.length) { targets[0].damage(4); event.finish(); - } - else{ - var list=player.getFellow(true); - if(list.length){ + } else { + var list = player.getFellow(true); + if (list.length) { list.sort(lib.sort.seat); - event.list=list; + event.list = list; player.line(list); - } - else{ + } else { event.finish(); } } - 'step 1' - if(event.list.length){ + "step 1"; + if (event.list.length) { event.list.shift().damage(2); event.redo(); } }, - ai:{ - order:7, - useful:5, - value:5, - result:{ - target:function(player,target){ - if(target==player.getEnemy()) return -2; + ai: { + order: 7, + useful: 5, + value: 5, + result: { + target: function (player, target) { + if (target == player.getEnemy()) return -2; return -1; - } + }, }, - tag:{ - damage:2 - } - } + tag: { + damage: 2, + }, + }, }, - spell_fennu:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:2, - career:'druid', - filterTarget:function(card,player,target){ + spell_fennu: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 2, + career: "druid", + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ - 'step 0' - player.chooseControl('两点','一点').prompt='造成2点伤害,或造成1点伤害并从牌库中获得一张牌'; - 'step 1' - if(result.control=='一点'){ + content: function () { + "step 0"; + player.chooseControl("两点", "一点").prompt = + "造成2点伤害,或造成1点伤害并从牌库中获得一张牌"; + "step 1"; + if (result.control == "一点") { target.damage(); - } - else{ + } else { target.damage(2); event.finish(); } - 'step 2' + "step 2"; player.drawDeck(); }, - ai:{ - order:8, - value:5, - useful:5, - result:{ - target:-1 + ai: { + order: 8, + value: 5, + useful: 5, + result: { + target: -1, }, - tag:{ - damage:2, - } - } + tag: { + damage: 2, + }, + }, }, - spell_fugen:{ - type:'stonecard', - stoneact:2, - career:'druid', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ + spell_fugen: { + type: "stonecard", + stoneact: 2, + career: "druid", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ - 'step 0' + content: function () { + "step 0"; target.die(); - 'step 1' - var list=[]; - for(var i in lib.card){ - if(lib.card[i].stonehidden) continue; - if(lib.card[i].type=='stonecharacter'){ + "step 1"; + var list = []; + for (var i in lib.card) { + if (lib.card[i].stonehidden) continue; + if (lib.card[i].type == "stonecharacter") { list.push(i); } } - player.getEnemy().gain(game.createCard(list.randomGet()),'draw'); + player.getEnemy().gain(game.createCard(list.randomGet()), "draw"); + }, + ai: { + order: 8.8, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -target.hp - target.countCards("h") / 2; + }, + }, }, - ai:{ - order:8.8, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -target.hp-target.countCards('h')/2; - } - } - } }, - spell_mengun:{ - type:'stonecard', - stoneact:2, - career:'rogue', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.side!=player.side; + spell_mengun: { + type: "stonecard", + stoneact: 2, + career: "rogue", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.side != player.side; }, - content:function(){ - 'step 0' - target.die()._triggered=null; - event.name=target.name; - 'step 1' - player.getEnemy().gain(game.createCard(event.name+'_stonecharacter'),'gain2'); + content: function () { + "step 0"; + target.die()._triggered = null; + event.name = target.name; + "step 1"; + player.getEnemy().gain(game.createCard(event.name + "_stonecharacter"), "gain2"); + }, + ai: { + order: 8.8, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -target.hp - target.countCards("h") / 2; + }, + }, }, - ai:{ - order:8.8, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -target.hp-target.countCards('h')/2; - } - } - } }, - spell_jipao:{ - type:'stonecard', - stoneact:3, - career:'rogue', - enable:function(card,player){ + spell_jipao: { + type: "stonecard", + stoneact: 3, + career: "rogue", + enable: function (card, player) { return !player.isMin(); }, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player; + fullimage: true, + filterTarget: function (card, player, target) { + return target == player; }, - selectTarget:-1, - content:function(){ - if(!player.isMin()){ + selectTarget: -1, + content: function () { + if (!player.isMin()) { player.drawDeck(4); } }, - ai:{ - order:1, - value:3, - useful:3, - result:{ - player:1 - } - } - }, - spell_beici:{ - type:'stonecard', - stoneact:0, - career:'rogue', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.hp==target.maxHp; + ai: { + order: 1, + value: 3, + useful: 3, + result: { + player: 1, + }, }, - content:function(){ + }, + spell_beici: { + type: "stonecard", + stoneact: 0, + career: "rogue", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.hp == target.maxHp; + }, + content: function () { target.loseHp(); }, - ai:{ - order:9, - result:{ - target:-1 + ai: { + order: 9, + result: { + target: -1, }, - value:6, - useful:6, - } - }, - spell_weijisifu:{ - type:'stonecard', - stoneact:2, - career:'rogue', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player.getEnemy(); + value: 6, + useful: 6, }, - selectTarget:-1, - content:function(){ - if(target.deckCards){ - var cards=[]; - for(var i=0;i<3;i++){ - cards.push(game.createCard('spell_zhumo')); + }, + spell_weijisifu: { + type: "stonecard", + stoneact: 2, + career: "rogue", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target == player.getEnemy(); + }, + selectTarget: -1, + content: function () { + if (target.deckCards) { + var cards = []; + for (var i = 0; i < 3; i++) { + cards.push(game.createCard("spell_zhumo")); } - player.$give(cards,target); - for(var i=0;i0; + spell_laojiuhuoba: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 2, + career: "mage", + filterTarget: true, + content: function () { + target.damage("fire"); + if (player.deckCards) { + player.deckCards.push(game.createCard("spell_chirehuoba")); + } }, - stoneact:2, - career:'mage', - filterTarget:function(card,player,target){ - return target.side!=player.side&&target.isMin(); + ai: { + order: 7, + value: 4, + useful: 4, + result: { + target: -1, + }, + tag: { + damage: 1, + natureDamage: 1, + fireDamage: 1, + }, }, - selectTarget:-1, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - if(!targets.length){ + }, + spell_chirehuoba: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 2, + career: "mage", + stonehidden: true, + filterTarget: true, + content: function () { + target.damage(2, "fire"); + }, + ai: { + order: 7, + value: 6, + useful: 6, + result: { + target: -2, + }, + tag: { + damage: 2, + natureDamage: 2, + fireDamage: 2, + }, + }, + }, + spell_hanbingpingzhang: { + type: "stonecard", + stoneact: 1, + career: "mage", + enable: true, + fullimage: true, + filterTarget: true, + content: function () { + if (target.maxHp < 2) { + target.maxHp = 2; + } + if (target.hp < 2) { + target.hp = 2; + target.update(); + } + target.addSkill("mage_hanbingpingzhang"); + }, + ai: { + order: 1, + value: 3, + useful: 3, + result: { + target: function (player, target) { + if (target.hp <= 2) return 3 - target.hp; + return 0; + }, + }, + }, + }, + spell_aoshufeidan: { + type: "stonecard", + fullimage: true, + enable: function (event, player) { + return player.getEnemy().countFellow() > 0; + }, + stoneact: 2, + career: "mage", + filterTarget: function (card, player, target) { + return target.side != player.side && target.isMin(); + }, + selectTarget: -1, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + if (!targets.length) { event.finish(); return; } - var map=[]; - for(var i=0;i1) return target.hp; + ai: { + order: 4, + value: 4, + useful: 4, + result: { + target: function (player, target) { + if (target.hasSkill("shaman_tuteng")) return 0; + if (target.hp > 1) return target.hp; return 0; - } - } - } + }, + }, + }, }, - spell_shihuawuqi:{ - type:'stonecard', - stoneact:1, - career:'shaman', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&!target.hasSkill('shaman_shihuawuqi'); + spell_shihuawuqi: { + type: "stonecard", + stoneact: 1, + career: "shaman", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && !target.hasSkill("shaman_shihuawuqi"); }, - content:function(){ - target.addSkill('shaman_shihuawuqi'); + content: function () { + target.addSkill("shaman_shihuawuqi"); }, - ai:{ - order:4, - value:4, - useful:4, - result:{ - target:function(player,target){ - if(target.isTurnedOver()) return 0; - var num=0; - if(target.hasSkill('shaman_fengnu')){ - num=3; + ai: { + order: 4, + value: 4, + useful: 4, + result: { + target: function (player, target) { + if (target.isTurnedOver()) return 0; + var num = 0; + if (target.hasSkill("shaman_fengnu")) { + num = 3; } - if(target.isMin()) return target.hp+num; + if (target.isMin()) return target.hp + num; return 1.1; - } - } - } + }, + }, + }, }, - spell_xianzuzhaohuan:{ - type:'stonecard', - stoneact:2, - career:'shaman', - fullimage:true, - enable:true, - filterTarget:function(card,player,target){ + spell_xianzuzhaohuan: { + type: "stonecard", + stoneact: 2, + career: "shaman", + fullimage: true, + enable: true, + filterTarget: function (card, player, target) { return !target.isMin(); }, - multitarget:true, - multiline:true, - selectTarget:-1, - content:function(){ - 'step 0' - if(targets[0]){ - var hs=targets[0].getCards('h',function(card){ - return get.type(card)=='stonecharacter'; + multitarget: true, + multiline: true, + selectTarget: -1, + content: function () { + "step 0"; + if (targets[0]) { + var hs = targets[0].getCards("h", function (card) { + return get.type(card) == "stonecharacter"; }); - if(hs.length&&targets[0].canAddFellow()){ - targets[0].useCard(targets[0],hs.randomGet(),false).noActCount=true; + if (hs.length && targets[0].canAddFellow()) { + targets[0].useCard(targets[0], hs.randomGet(), false).noActCount = true; } } - 'step 1' - if(targets[1]){ - var hs=targets[1].getCards('h',function(card){ - return get.type(card)=='stonecharacter'; + "step 1"; + if (targets[1]) { + var hs = targets[1].getCards("h", function (card) { + return get.type(card) == "stonecharacter"; }); - if(hs.length&&targets[1].canAddFellow()){ - targets[1].useCard(targets[1],hs.randomGet(),false).noActCount=true; + if (hs.length && targets[1].canAddFellow()) { + targets[1].useCard(targets[1], hs.randomGet(), false).noActCount = true; } } }, - ai:{ - order:9, - value:5, - useful:5, - result:{ - player:function(player){ - var hs=player.getCards('h',function(card){ - return get.type(card)=='stonecharacter'; + ai: { + order: 9, + value: 5, + useful: 5, + result: { + player: function (player) { + var hs = player.getCards("h", function (card) { + return get.type(card) == "stonecharacter"; }); - if(hs.length==0) return 0; - var enemy=player.getEnemy(); - if(enemy.countCards('h')<=1) return 1; - var num=0; - for(var i=0;i=3) return 1; + if (num / hs.length >= 3) return 1; return 0; - } - } - } + }, + }, + }, }, - spell_xianzuzhihun:{ - type:'stonecard', - stoneact:2, - career:'shaman', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&!target.hasSkill('shaman_xianzuzhihun'); + spell_xianzuzhihun: { + type: "stonecard", + stoneact: 2, + career: "shaman", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && !target.hasSkill("shaman_xianzuzhihun"); }, - content:function(){ - target.addSkill('shaman_xianzuzhihun'); + content: function () { + target.addSkill("shaman_xianzuzhihun"); }, - ai:{ - order:5, - value:4, - useful:4, - result:{ - target:function(player,target){ - if(lib.card[target.name+'_stonecharacter']){ - return lib.card[target.name+'_stonecharacter'].stoneact-1; + ai: { + order: 5, + value: 4, + useful: 4, + result: { + target: function (player, target) { + if (lib.card[target.name + "_stonecharacter"]) { + return lib.card[target.name + "_stonecharacter"].stoneact - 1; } return 0; - } - } - } - }, - spell_xianzuzhishi:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:0, - career:'shaman', - filterTarget:function(card,player,target){ - return target==player; + }, + }, }, - selectTarget:-1, - content:function(){ + }, + spell_xianzuzhishi: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 0, + career: "shaman", + filterTarget: function (card, player, target) { + return target == player; + }, + selectTarget: -1, + content: function () { player.drawDeck(2); - player.addTempSkill('shaman_xianzuzhishi'); + player.addTempSkill("shaman_xianzuzhishi"); + }, + ai: { + order: 10, + result: { + player: 1, + }, }, - ai:{ - order:10, - result:{ - player:1 - } - } }, - spell_rongyanbaolie:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:3, - career:'shaman', - filterTarget:true, - content:function(){ - 'step 0' - target.damage(3,'fire'); - 'step 1' + spell_rongyanbaolie: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 3, + career: "shaman", + filterTarget: true, + content: function () { + "step 0"; + target.damage(3, "fire"); + "step 1"; player.loseHp(); }, - ai:{ - order:8, - value:6, - useful:5, - result:{ - target:-2 + ai: { + order: 8, + value: 6, + useful: 5, + result: { + target: -2, }, - tag:{ - damage:2, - natureDamage:2, - fireDamage:2, - } - } + tag: { + damage: 2, + natureDamage: 2, + fireDamage: 2, + }, + }, }, - spell_shenshengxinxing:{ - type:'stonecard', - stoneact:5, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - if(player.hasFellowSkill('priest_hunwu')||target.side!=player.side) return true; + spell_shenshengxinxing: { + type: "stonecard", + stoneact: 5, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + if (player.hasFellowSkill("priest_hunwu") || target.side != player.side) return true; return target.isDamaged(); }, - selectTarget:-1, - content:function(){ - var num=1; - if(player.hasFellowSkill('stone_shenyou')){ - num=2; + selectTarget: -1, + content: function () { + var num = 1; + if (player.hasFellowSkill("stone_shenyou")) { + num = 2; } - if(player.side==target.side){ - if(player.hasFellowSkill('priest_hunwu')){ + if (player.side == target.side) { + if (player.hasFellowSkill("priest_hunwu")) { target.loseHp(num); - } - else{ + } else { target.recover(num); } - } - else{ + } else { target.damage(); } }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:function(player,target){ - if(player.hasFellowSkill('priest_hunwu')) return -1; - if(player.side==target.side) return 1; + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: function (player, target) { + if (player.hasFellowSkill("priest_hunwu")) return -1; + if (player.side == target.side) return 1; return -1; - } + }, + }, + tag: { + damage: 1, + multitarget: 1, + multineg: 1, }, - tag:{ - damage:1, - multitarget:1, - multineg:1 - } - } - }, - spell_shengguangzhadan:{ - type:'stonecard', - stoneact:2, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.countCards('h')>0; }, - selectTarget:-1, - content:function(){ - var num=1; + }, + spell_shengguangzhadan: { + type: "stonecard", + stoneact: 2, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.countCards("h") > 0; + }, + selectTarget: -1, + content: function () { + var num = 1; // if(player.hasFellowSkill('stone_shenyou')){ // num=2; // } - target.damage(target.countCards('h')*num); + target.damage(target.countCards("h") * num); }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -Math.min(target.countCards('h'),target.hp); - } + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -Math.min(target.countCards("h"), target.hp); + }, }, - tag:{ - damage:1, - multitarget:1, - multineg:1 - } - } + tag: { + damage: 1, + multitarget: 1, + multineg: 1, + }, + }, }, - spell_maizang:{ - type:'stonecard', - stoneact:3, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.side!=player.side; + spell_maizang: { + type: "stonecard", + stoneact: 3, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.side != player.side; }, - content:function(){ - 'step 0' - target.die()._triggered=null; - 'step 1' - if(player.deckCards){ - player.deckCards.push(game.createCard(target.name+'_stonecharacter')); + content: function () { + "step 0"; + target.die()._triggered = null; + "step 1"; + if (player.deckCards) { + player.deckCards.push(game.createCard(target.name + "_stonecharacter")); } }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:function(player,target){ - return -target.hp-target.countCards('h')/2; - } - } - } + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return -target.hp - target.countCards("h") / 2; + }, + }, + }, }, - spell_xinlingshijie:{ - type:'stonecard', - stoneact:0, - career:'priest', - enable:function(event,player){ - return player.getEnemy().countCards('h')>0; + spell_xinlingshijie: { + type: "stonecard", + stoneact: 0, + career: "priest", + enable: function (event, player) { + return player.getEnemy().countCards("h") > 0; }, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player.getEnemy(); + fullimage: true, + filterTarget: function (card, player, target) { + return target == player.getEnemy(); }, - selectTarget:-1, - content:function(){ - var card=target.getCards('h').randomGet(); - if(card){ - player.gain(game.createCard(card.name,card.suit,card.number,card.nature),'draw'); + selectTarget: -1, + content: function () { + var card = target.getCards("h").randomGet(); + if (card) { + player.gain(game.createCard(card.name, card.suit, card.number, card.nature), "draw"); } }, - ai:{ - order:9.5, - value:5, - useful:5, - result:{ - player:1 - } - } + ai: { + order: 9.5, + value: 5, + useful: 5, + result: { + player: 1, + }, + }, }, - spell_naluzhiguang:{ - type:'stonecard', - stoneact:1, - career:'priest', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - if(player.hasFellowSkill('priest_hunwu')){ + spell_naluzhiguang: { + type: "stonecard", + stoneact: 1, + career: "priest", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + if (player.hasFellowSkill("priest_hunwu")) { return true; } - return target.hp0; }, - fullimage:true, - filterTarget:function(card,player,target){ + }, + spell_dunpaimengji: { + type: "stonecard", + stoneact: 2, + career: "warrior", + enable: function (event, player) { + return player.hujia > 0; + }, + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - content:function(){ + content: function () { target.damage(player.hujia); }, - ai:{ - order:7.2, - value:5, - useful:5, - result:{ - target:-1.5, - tag:{ - damage:1 - } - } - } - }, - spell_zhansha:{ - type:'stonecard', - stoneact:1, - career:'warrior', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.hp=4) return 1.5; - if(target.hp>=3&&target.countCards('h')= 4) return 1.5; + if (target.hp >= 3 && target.countCards("h") < target.hp) return 1; return 0; - } - } - } + }, + }, + }, }, - spell_xuanfengzhan:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:2, - career:'warrior', - filterTarget:function(card,player,target){ + spell_xuanfengzhan: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 2, + career: "warrior", + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - content:function(){ + selectTarget: -1, + content: function () { target.damage(); }, - ai:{ - order:9, - value:5, - useful:5, - result:{ - target:-1.5 + ai: { + order: 9, + value: 5, + useful: 5, + result: { + target: -1.5, }, - tag:{ - damage:1, - multitarget:1, - multineg:1, - } - } + tag: { + damage: 1, + multitarget: 1, + multineg: 1, + }, + }, }, - spell_juemingluandou:{ - type:'stonecard', - stoneact:4, - career:'warrior', - enable:function(){ - var num=0; - for(var i=0;i=2) return true; + if (num >= 2) return true; } } return false; }, - fullimage:true, - filterTarget:function(card,player,target){ + fullimage: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - content:function(){ - 'step 0' + selectTarget: -1, + content: function () { + "step 0"; targets.randomRemove(); targets.sort(lib.sort.seat); - event.list=targets; - 'step 1' - if(event.list.length){ + event.list = targets; + "step 1"; + if (event.list.length) { event.list.shift().die(); event.redo(); } }, - ai:{ - order:9, - value:5, - useful:5, - result:{ - target:-2 - } - } + ai: { + order: 9, + value: 5, + useful: 5, + result: { + target: -2, + }, + }, }, - spell_lierenyinji:{ - type:'stonecard', - stoneact:0, - career:'hunter', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target.isMin()&&target.maxHp>1; + spell_lierenyinji: { + type: "stonecard", + stoneact: 0, + career: "hunter", + enable: true, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && target.maxHp > 1; }, - content:function(){ - target.loseMaxHp(target.maxHp-1); + content: function () { + target.loseMaxHp(target.maxHp - 1); + }, + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: function (player, target) { + return 1 - target.hp; + }, + }, }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:function(player,target){ - return 1-target.hp; - } - } - } }, - spell_kuaisusheji:{ - type:'stonecard', - stoneact:2, - career:'hunter', - enable:true, - fullimage:true, - filterTarget:true, - content:function(){ + spell_kuaisusheji: { + type: "stonecard", + stoneact: 2, + career: "hunter", + enable: true, + fullimage: true, + filterTarget: true, + content: function () { target.damage(); player.draw(); }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:-1.5, + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: -1.5, }, - tag:{ - damage:1 - } - } + tag: { + damage: 1, + }, + }, }, - spell_guanmenfanggou:{ - type:'stonecard', - stoneact:2, - career:'hunter', - enable:function(event,player){ - return player.getEnemy().countFellow()>0&&player.canAddFellow(); + spell_guanmenfanggou: { + type: "stonecard", + stoneact: 2, + career: "hunter", + enable: function (event, player) { + return player.getEnemy().countFellow() > 0 && player.canAddFellow(); }, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player; + fullimage: true, + filterTarget: function (card, player, target) { + return target == player; }, - selectTarget:-1, - content:function(){ - 'step 0' - event.num=player.getEnemy().countFellow(); - 'step 1' - if(player.canAddFellow()&&event.num--){ - player.addFellowAuto('stone_liegou'); + selectTarget: -1, + content: function () { + "step 0"; + event.num = player.getEnemy().countFellow(); + "step 1"; + if (player.canAddFellow() && event.num--) { + player.addFellowAuto("stone_liegou"); event.redo(); } }, - ai:{ - order:7, - value:5, - useful:5, - result:{ - target:1 - } - } + ai: { + order: 7, + value: 5, + useful: 5, + result: { + target: 1, + }, + }, }, - spell_zhaohuanchongwu:{ - type:'stonecard', - stoneact:2, - career:'hunter', - enable:function(event,player){ + spell_zhaohuanchongwu: { + type: "stonecard", + stoneact: 2, + career: "hunter", + enable: function (event, player) { return player.canAddFellow(); }, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player; + fullimage: true, + filterTarget: function (card, player, target) { + return target == player; }, - selectTarget:-1, - content:function(){ + selectTarget: -1, + content: function () { player.addFellowAuto(lib.beastList.randomGet()); }, - ai:{ - order:6, - value:5, - useful:5, - result:{ - player:1 - } - } - }, - spell_zidanshangtang:{ - type:'stonecard', - stoneact:1, - career:'hunter', - enable:true, - fullimage:true, - filterTarget:function(card,player,target){ - return target==player; + ai: { + order: 6, + value: 5, + useful: 5, + result: { + player: 1, + }, }, - selectTarget:-1, - content:function(){ - var list=['spell_lierenyinji','spell_guanmenfanggou','spell_duochongsheji','spell_kuaisusheji','spell_zhaohuanchongwu']; - player.gain(game.createCard(list.randomGet()),'draw'); - player.addTempSkill('hunter_zidanshangtang'); - }, - ai:{ - order:7.5, - value:5, - useful:5, - result:{ - player:1 - } - } }, - spell_duochongsheji:{ - type:'stonecard', - fullimage:true, - enable:function(event,player){ - for(var i=0;imaxHp){ - maxHp=game.players[i].hp; + if (game.players[i].hp > maxHp) { + maxHp = game.players[i].hp; } } } - if(list.length<2) return 0; - if(list.length==2&&target.hp>=4) return 0; - if(target.hp>maxHp) return 1; + if (list.length < 2) return 0; + if (list.length == 2 && target.hp >= 4) return 0; + if (target.hp > maxHp) return 1; return target.hp; - } + }, }, - } + }, }, - spell_xishengqiyue:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:0, - career:'warlock', - filterTarget:function(card,player,target){ - if(!target.isMin()) return false; - if(ui.selected.targets.length){ - return target.side!=ui.selected.targets[0].side; + spell_xishengqiyue: { + type: "stonecard", + fullimage: true, + enable: true, + stoneact: 0, + career: "warlock", + filterTarget: function (card, player, target) { + if (!target.isMin()) return false; + if (ui.selected.targets.length) { + return target.side != ui.selected.targets[0].side; } return true; }, - selectTarget:2, - multitarget:true, - multiline:true, - content:function(){ + selectTarget: 2, + multitarget: true, + multiline: true, + content: function () { targets.sort(lib.sort.seat); - for(var i=0;i=2) return 1; + ai: { + order: 1, + value: 5, + useful: 5, + result: { + player: function (player) { + if (player.countFellow() >= 2) return 1; return 0; - } + }, }, - } - }, - spell_hengsao:{ - type:'stonecard', - fullimage:true, - enable:true, - stoneact:4, - career:'druid', - filterTarget:function(card,player,target){ - return target.side!=player.side; }, - content:function(){ - 'step 0' - event.list=[]; - for(var i=0;i0; + spell_fuchouzhinu: { + type: "stonecard", + fullimage: true, + enable: function (event, player) { + return player.getEnemy().countFellow() > 0; }, - stoneact:4, - career:'paladin', - filterTarget:function(card,player,target){ - return target.side!=player.side&&target.isMin(); + stoneact: 4, + career: "paladin", + filterTarget: function (card, player, target) { + return target.side != player.side && target.isMin(); }, - selectTarget:-1, - multitarget:true, - multiline:true, - content:function(){ - 'step 0' - if(!targets.length){ + selectTarget: -1, + multitarget: true, + multiline: true, + content: function () { + "step 0"; + if (!targets.length) { event.finish(); return; } - var map=[]; - for(var i=0;i1||target.countCards('he')>0); + spell_chenmo: { + type: "stonecard", + enable: true, + stoneact: 2, + fullimage: true, + filterTarget: function (card, player, target) { + return target.isMin() && (target.maxHp > 1 || target.countCards("he") > 0); }, - content:function(){ - "step 0" - target.discard(target.getCards('he')); - "step 1" - if(target.maxHp>2){ - target.loseMaxHp(target.maxHp-2); + content: function () { + "step 0"; + target.discard(target.getCards("he")); + "step 1"; + if (target.maxHp > 2) { + target.loseMaxHp(target.maxHp - 2); } }, - ai:{ - result:{ - target:function(player,target){ - return Math.min(0,2-target.hp)-target.countCards('h')/2; - } + ai: { + result: { + target: function (player, target) { + return Math.min(0, 2 - target.hp) - target.countCards("h") / 2; + }, }, - order:7 - } + order: 7, + }, }, - spell_morizaihuo:{ - fullimage:true, - type:'stonecard', - enable:true, - filterTarget:function(card,player,target){ + spell_morizaihuo: { + fullimage: true, + type: "stonecard", + enable: true, + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - multiline:true, - multitarget:true, - content:function(){ - 'step 0' + selectTarget: -1, + multiline: true, + multitarget: true, + content: function () { + "step 0"; targets.sort(lib.sort.seat); - event.list=targets; - 'step 1' - if(event.list.length){ + event.list = targets; + "step 1"; + if (event.list.length) { event.list.shift().die(); event.redo(); } - 'step 2' - player.recover(2) + "step 2"; + player.recover(2); }, - stoneact:5, - ai:{ - order:9, - result:{ - target:-1, - player:function(player){ - if(player.hp1; + spell_shengerpingdeng: { + fullimage: true, + type: "stonecard", + enable: true, + stoneact: 2, + filterTarget: function (card, player, target) { + return target.isMin() && target.maxHp > 1; }, - selectTarget:-1, - content:function(){ - target.loseMaxHp(target.maxHp-1); + selectTarget: -1, + content: function () { + target.loseMaxHp(target.maxHp - 1); }, - ai:{ - order:9.1, - result:{ - target:function(player,target){ - if(target.hp>1) return -1; - if(target.maxHp>1) return -0.1; + ai: { + order: 9.1, + result: { + target: function (player, target) { + if (target.hp > 1) return -1; + if (target.maxHp > 1) return -0.1; return 0; - } - } - } + }, + }, + }, }, - spell_jingshenkongzhi:{ - fullimage:true, - type:'stonecard', - enable:function(event,player){ - if(player.isMin()) return false; + spell_jingshenkongzhi: { + fullimage: true, + type: "stonecard", + enable: function (event, player) { + if (player.isMin()) return false; return player.canAddFellow(); }, - stoneact:6, - filterTarget:function(card,player,target){ - return target.isMin()&&target.side!=player.side; + stoneact: 6, + filterTarget: function (card, player, target) { + return target.isMin() && target.side != player.side; }, - content:function(){ + content: function () { target.getLeader().removeFellow(target); - target.side=player.side; + target.side = player.side; player.addFellow(target); - if(!target.isTurnedOver()){ + if (!target.isTurnedOver()) { target.turnOver(); } }, - ai:{ - order:9.5, - result:{ - target:function(player,target){ + ai: { + order: 9.5, + result: { + target: function (player, target) { return -target.hp; - } - } - } + }, + }, + }, }, - spell_anyingkuangluan:{ - type:'stonecard', - fullimage:true, - enable:function(event,player){ - if(player.isMin()) return false; + spell_anyingkuangluan: { + type: "stonecard", + fullimage: true, + enable: function (event, player) { + if (player.isMin()) return false; return player.canAddFellow(); }, - stoneact:4, - filterTarget:function(card,player,target){ - return target.isMin()&&target.side!=player.side&&target.countCards('h')<=1; + stoneact: 4, + filterTarget: function (card, player, target) { + return target.isMin() && target.side != player.side && target.countCards("h") <= 1; }, - content:function(){ + content: function () { target.getLeader().removeFellow(target); - target.side=player.side; + target.side = player.side; player.addFellow(target); - target.addSkill('spell_anyingkuangluan_die'); + target.addSkill("spell_anyingkuangluan_die"); }, - ai:{ - order:9.5, - result:{ - target:function(player,target){ + ai: { + order: 9.5, + result: { + target: function (player, target) { return -target.hp; - } - } - } + }, + }, + }, }, - spell_binghuan:{ - fullimage:true, - type:'stonecard', - enable:true, - stoneact:1, - filterTarget:function(card,player,target){ + spell_binghuan: { + fullimage: true, + type: "stonecard", + enable: true, + stoneact: 1, + filterTarget: function (card, player, target) { return target.isMin(); }, - selectTarget:-1, - content:function(){ + selectTarget: -1, + content: function () { target.turnOver(); }, - ai:{ - order:7, - result:{ - target:function(player,target){ - if(target.isTurnedOver()) return 1; + ai: { + order: 7, + result: { + target: function (player, target) { + if (target.isTurnedOver()) return 1; return -1; - } - } - } - }, - spell_zhiliaozhichu:{ - fullimage:true, - type:'stonecard', - enable:true, - stoneact:1, - filterTarget:function(card,player,target){ - return target.isMin()&&target.side==player.side&& - (!target.hasSkill('lschaofeng')||target.hp0){ + "step 2"; + var dh = target.countCards("h") - player.countCards("h"); + if (dh > 0) { player.draw(dh); } }, - ai:{ - order:7, - value:1, - useful:1, - result:{ - target:function(player,target){ - var ne1=target.countCards('e'),ne2=player.countCards('e'); - var nh1=target.countCards('h'),nh2=player.countCards('h'); - if(nh10){ - target.discard(target.getCards('h').randomGets(dh)); + content: function () { + "step 0"; + target.gain(target.getCards("e"), "gain2"); + "step 1"; + var dh = target.countCards("h") - player.countCards("h"); + if (dh > 0) { + target.discard(target.getCards("h").randomGets(dh)); } }, - ai:{ - order:1, - value:1, - useful:1, - result:{ - target:function(player,target){ - if(target.countCards('he')>=player.countCards('h')) return -1; + ai: { + order: 1, + value: 1, + useful: 1, + result: { + target: function (player, target) { + if (target.countCards("he") >= player.countCards("h")) return -1; return 0; - } - } - } + }, + }, + }, }, }, - skill:{ - stone_mieshi:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i=player.maxHp-1) return [0,0]; - } - } - } - }, - stone_lianyu:{ - mark:true, - intro:{ - content:function(storage){ - return '地狱火的初始手牌数和体力值为'+(storage+2); - } - }, - ai:{ - threaten:function(player,target){ - return 1+target.storage.stone_lianyu; + if (get.tag(card, "recover") && player.hp >= player.maxHp - 1) return [0, 0]; + }, }, - } - }, - stone_lianji:{ - trigger:{global:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.player.side==player.side&&event.source!=player; }, - content:function(){ + }, + stone_lianyu: { + mark: true, + intro: { + content: function (storage) { + return "地狱火的初始手牌数和体力值为" + (storage + 2); + }, + }, + ai: { + threaten: function (player, target) { + return 1 + target.storage.stone_lianyu; + }, + }, + }, + stone_lianji: { + trigger: { global: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return event.player.side == player.side && event.source != player; + }, + content: function () { player.maxHp++; player.hp++; player.update(); player.draw(); }, - ai:{ - threaten:2 - } + ai: { + threaten: 2, + }, }, - stone_shenyu:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - 'step 0' - var target=player.getLeader(); - var next=target.chooseControl('召唤树人','增强随从'); - next.prompt='召唤两个嘲讽树人,或令所有其他随从增加1点体力和体力上限并摸两张牌'; - next.ai=function(){ - if(target.countFellow()<=2) return '召唤树人'; - return '增强随从'; - } - 'step 1' - if(result.control=='增强随从'){ - var targets=player.getLeader().getFellow(); + stone_shenyu: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + "step 0"; + var target = player.getLeader(); + var next = target.chooseControl("召唤树人", "增强随从"); + next.prompt = "召唤两个嘲讽树人,或令所有其他随从增加1点体力和体力上限并摸两张牌"; + next.ai = function () { + if (target.countFellow() <= 2) return "召唤树人"; + return "增强随从"; + }; + "step 1"; + if (result.control == "增强随从") { + var targets = player.getLeader().getFellow(); targets.remove(player); - for(var i=0;i0; + warrior_fenyong: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getLeader().countCards("h", { type: "stonecharacter" }) > 0; }, - content:function(){ - player.addSkill('stone_chongfeng'); - if(player.isTurnedOver()){ + content: function () { + player.addSkill("stone_chongfeng"); + if (player.isTurnedOver()) { player.turnOver(); } - } + }, }, - warrior_peilian:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i1) return true; + priest_suoxiao: { + trigger: { source: "fellow" }, + unique: true, + forced: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i] != player && game.players[i].isMin() && game.players[i].maxHp > 1) + return true; } return false; }, - content:function(){ - "step 0" - event.chooser=player.getLeader(); - event.chooser.chooseTarget('缩小:令一名随从减少2点体力上限',function(card,playerx,target){ - return player!=target&&target.isMin()&&target.maxHp>1; - }).ai=function(target){ - if(get.attitude(player,target)>=0) return 0; - if(target.hp==1) return 0.01; - if(target.maxHp-target.hp>=2) return 0.01; - if(target.maxHp-target.hp==1){ - if(target.hp==2) return 1; + content: function () { + "step 0"; + event.chooser = player.getLeader(); + event.chooser.chooseTarget( + "缩小:令一名随从减少2点体力上限", + function (card, playerx, target) { + return player != target && target.isMin() && target.maxHp > 1; + } + ).ai = function (target) { + if (get.attitude(player, target) >= 0) return 0; + if (target.hp == 1) return 0.01; + if (target.maxHp - target.hp >= 2) return 0.01; + if (target.maxHp - target.hp == 1) { + if (target.hp == 2) return 1; return 0.1; } - switch(target.hp){ - case 1:return 0.01; - case 2:return 1; - case 3:return 2; - case 4:return 1.5; - case 5:return 1; - default:return 0.8; + switch (target.hp) { + case 1: + return 0.01; + case 2: + return 1; + case 3: + return 2; + case 4: + return 1.5; + case 5: + return 1; + default: + return 0.8; } }; player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.line(result.targets[0]); - result.targets[0].maxHp-=2; - if(result.targets[0].maxHp<1){ - result.targets[0].maxHp=1; + result.targets[0].maxHp -= 2; + if (result.targets[0].maxHp < 1) { + result.targets[0].maxHp = 1; } result.targets[0].update(); } - } - }, - priest_shixin:{ - trigger:{global:'useSkillAfter'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.career&&event.player.side==player.side; }, - content:function(){ - 'step 0' - var target=player.getLeader(); - target.damage(); - player.line(target,'green'); - 'step 1' - var target=player.getEnemy(); - target.damage(); - player.line(target,'green'); - } }, - priest_shengshui:{ - trigger:{player:'phaseBegin'}, - unique:true, - forced:true, - filter:function(event,player){ - for(var i=0;i0; + noPhaseDelay: 1, }, - content:function(){ + }, + priest_muguang: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getLeader().countCards("h", { type: "stonecharacter" }) > 0; + }, + content: function () { player.maxHp++; player.hp++; player.update(); - } + }, }, - hunter_mishi:{ - trigger:{global:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.player.side==player.side&&event.source!=player; + hunter_mishi: { + trigger: { global: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return event.player.side == player.side && event.source != player; }, - content:function(){ + content: function () { player.draw(); - } - }, - hunter_muyang:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return player.getLeader().countFellow()>1&&player.getLeader().canAddFellow(); }, - content:function(){ - var num=player.getLeader().countFellow()-1; - var list=[]; - for(var i in lib.character){ - if(lib.character[i][4].includes('stone')&& - !lib.character[i][4].includes('stonehidden')&& - lib.character[i][5]&&lib.character[i][5][0]==num){ + }, + hunter_muyang: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getLeader().countFellow() > 1 && player.getLeader().canAddFellow(); + }, + content: function () { + var num = player.getLeader().countFellow() - 1; + var list = []; + for (var i in lib.character) { + if ( + lib.character[i][4].includes("stone") && + !lib.character[i][4].includes("stonehidden") && + lib.character[i][5] && + lib.character[i][5][0] == num + ) { list.push(i); } } - var target=player.getLeader(); - if(list.length){ + var target = player.getLeader(); + if (list.length) { target.addFellowAuto(list.randomGet()); } - } - }, - hunter_juji:{ - unique:true - }, - hunter_dusha:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - 'step 0' - var list=[]; - var target=player.getLeader(); - for(var i=0;i0; + rogue_jiaoyi: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + var target = player.getLeader(); + return target.countCards("e") > 0; }, - content:function(){ - "step 0" - event.chooser=player.getLeader(); - event.chooser.chooseToDiscard('是否弃置一张装备牌令'+get.translation(player)+'摸三张牌?', - 'he',function(card){ - return get.type(card)=='equip'; - }).ai=function(card){ - return 7-get.value(card); + content: function () { + "step 0"; + event.chooser = player.getLeader(); + event.chooser.chooseToDiscard( + "是否弃置一张装备牌令" + get.translation(player) + "摸三张牌?", + "he", + function (card) { + return get.type(card) == "equip"; + } + ).ai = function (card) { + return 7 - get.value(card); }; - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { player.draw(3); } - } - }, - rogue_jielue:{ - trigger:{global:'equipEnd'}, - unique:true, - forced:true, - filter:function(event,player){ - return event.player.side==player.side&&get.subtype(event.card)=='equip1'; }, - content:function(){ + }, + rogue_jielue: { + trigger: { global: "equipEnd" }, + unique: true, + forced: true, + filter: function (event, player) { + return event.player.side == player.side && get.subtype(event.card) == "equip1"; + }, + content: function () { player.draw(2); }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - rogue_fusheng:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i1){ + rogue_fusheng: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isMin() && game.players[i].hp > 1) { return true; } } }, - content:function(){ - var num=1; - for(var i=0;inum){ - num=game.players[i].hp; + content: function () { + var num = 1; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isMin() && game.players[i].hp > num) { + num = game.players[i].hp; } } - player.hp=num; - player.maxHp=num; + player.hp = num; + player.maxHp = num; player.update(); - } + }, }, - rogue_lifa:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - 'step 0' - var target=player.getLeader(); - if(target.getEquip(1)){ - target=target.getEnemy(); - player.line(target,'green'); + rogue_lifa: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + "step 0"; + var target = player.getLeader(); + if (target.getEquip(1)) { + target = target.getEnemy(); + player.line(target, "green"); target.damage(); - } - else{ - player.line(target,'green'); - var equip1=get.cardPile(function(card){ - return get.subtype(card)=='equip1'; + } else { + player.line(target, "green"); + var equip1 = get.cardPile(function (card) { + return get.subtype(card) == "equip1"; }); - if(!equip1){ - equip1=game.createCard('qingnang'); + if (!equip1) { + equip1 = game.createCard("qingnang"); } target.equip(equip1); } - } - }, - rogue_shoudao:{ - trigger:{global:'phaseEnd'}, - forced:true, - direct:true, - filter:function(event,player){ - return event.player==player.getLeader()&&event.player.countFellow()>1; }, - content:function(){ - 'step 0' - var players=get.players(); - var targets=[]; - for(var i=0;i 1; + }, + content: function () { + "step 0"; + var players = get.players(); + var targets = []; + for (var i = 0; i < players.length; i++) { + if (players[i].side == player.side && players[i].isMin() && players[i] != player) { targets.push(players[i]); } } - if(targets.length){ - var target=targets.randomGet(); - player.logSkill('rogue_shoudao',target); + if (targets.length) { + var target = targets.randomGet(); + player.logSkill("rogue_shoudao", target); target.maxHp++; target.hp++; target.update(); target.draw(); } }, - ai:{ - threaten:1.8 - } - }, - rogue_duxing:{ - trigger:{global:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.player.side!=player.side&&!player.hasSkill('qianxing'); + ai: { + threaten: 1.8, }, - content:function(){ + }, + rogue_duxing: { + trigger: { global: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return event.player.side != player.side && !player.hasSkill("qianxing"); + }, + content: function () { player.tempHide(); - } + }, }, - paladin_moma:{ - global:'paladin_moma2', - ai:{ - threaten:1.5 - } - }, - paladin_moma2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - filter:function(event,player){ - return player.name=='stone_xinbing'&&player.hasFellowSkill('paladin_moma'); + paladin_moma: { + global: "paladin_moma2", + ai: { + threaten: 1.5, }, - content:function(){ - trigger.num+=player.countFellowSkill('paladin_moma'); - } }, - paladin_jinghua:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i1){ + paladin_moma2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + filter: function (event, player) { + return player.name == "stone_xinbing" && player.hasFellowSkill("paladin_moma"); + }, + content: function () { + trigger.num += player.countFellowSkill("paladin_moma"); + }, + }, + paladin_jinghua: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + for (var i = 0; i < game.players.length; i++) { + if ( + game.players[i].isMin() && + game.players[i] != player && + game.players[i].countCards("h") > 1 + ) { return true; } } return false; }, - content:function(){ - "step 0" - var list=[]; - for(var i=0;i1){ + content: function () { + "step 0"; + var list = []; + for (var i = 0; i < game.players.length; i++) { + if ( + game.players[i].isMin() && + game.players[i] != player && + game.players[i].countCards("h") > 1 + ) { list.push(game.players[i]); } } list.sort(lib.sort.seat); - event.list=list; - "step 1" - if(event.list.length){ - var current=event.list.shift(); + event.list = list; + "step 1"; + if (event.list.length) { + var current = event.list.shift(); current.damage(2); - player.line(current,'green'); + player.line(current, "green"); event.redo(); } - } - }, - paladin_tuxi:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - var leader=player.getLeader(); - return leader.hp2){ - return get.attitude(event.chooser,target)*(2-target.maxHp)/100; + content: function () { + "step 0"; + event.chooser = player.getLeader(); + event.chooser.chooseTarget( + "化石:令一名随从的体力值及体力上限变为2", + function (card, playerx, target) { + return ( + player != target && target.isMin() && (target.hp != 2 || target.maxHp != 2) + ); } - return get.attitude(event.chooser,target)*(2-target.hp); + ).ai = function (target) { + if (target.hp == 2 && target.maxHp > 2) { + return (get.attitude(event.chooser, target) * (2 - target.maxHp)) / 100; + } + return get.attitude(event.chooser, target) * (2 - target.hp); }; player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.line(result.targets[0]); - result.targets[0].hp=2; - result.targets[0].maxHp=2; + result.targets[0].hp = 2; + result.targets[0].maxHp = 2; result.targets[0].update(); } - } + }, }, - paladin_baowei:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i0&&player.getEnemy().hasFellow(); }, - content:function(){ - 'step 0' - var num=player.getLeader().countCards('e'); - var map=[]; - var targets=player.getEnemy().getFellow(); - event.targets=targets; - for(var i=0;i 0 && player.getEnemy().hasFellow(); + }, + content: function () { + "step 0"; + var num = player.getLeader().countCards("e"); + var map = []; + var targets = player.getEnemy().getFellow(); + event.targets = targets; + for (var i = 0; i < targets.length; i++) { map.push(0); } - for(var i=0;i1; + player.line(target, "green"); }, - content:function(){ - var target=player.getLeader(); - var num=target.countFellow(); - if(num>1){ - target.actused-=num-1; + }, + druid_yeyou: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + game.asyncDraw([player.getLeader(), player.getEnemy()], 1, { drawDeck: 1 }); + }, + }, + druid_chicheng: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + var target = player.getLeader(); + return _status.currentPhase == target && target.countFellow() > 1; + }, + content: function () { + var target = player.getLeader(); + var num = target.countFellow(); + if (num > 1) { + target.actused -= num - 1; target.updateActCount(); } - } - }, - druid_qicheng:{ - trigger:{player:'dieBegin'}, - forced:true, - unique:true, - content:function(){ - player.getLeader().addSkill('druid_qicheng2'); }, - ai:{ - threaten:0.8 - } }, - druid_qicheng2:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player.hasSkill('druid_qicheng'); + druid_qicheng: { + trigger: { player: "dieBegin" }, + forced: true, + unique: true, + content: function () { + player.getLeader().addSkill("druid_qicheng2"); }, - content:function(){ + ai: { + threaten: 0.8, + }, + }, + druid_qicheng2: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player.hasSkill("druid_qicheng"); + }, + content: function () { game.delay(); - var list=[]; - for(var i in lib.character){ - if(lib.character[i][4].includes('stone')&& - !lib.character[i][4].includes('stonehidden')&& - lib.character[i][5]&&lib.character[i][5][0]==1){ + var list = []; + for (var i in lib.character) { + if ( + lib.character[i][4].includes("stone") && + !lib.character[i][4].includes("stonehidden") && + lib.character[i][5] && + lib.character[i][5][0] == 1 + ) { list.push(i); } } player.addFellowAuto(list.randomGet()); - player.removeSkill('druid_qicheng2'); - } + player.removeSkill("druid_qicheng2"); + }, }, - druid_renya:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - 'step 0' - player.getLeader().chooseControl('冲锋','潜行').ai=function(){ - if(Math.random()<0.5) return '潜行'; - return '冲锋'; - } - 'step 1' - if(result.control=='潜行'){ + druid_renya: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + "step 0"; + player.getLeader().chooseControl("冲锋", "潜行").ai = function () { + if (Math.random() < 0.5) return "潜行"; + return "冲锋"; + }; + "step 1"; + if (result.control == "潜行") { player.maxHp++; player.hp++; player.update(); player.tempHide(); - } - else{ + } else { player.draw(); - player.addSkill('stone_chongfeng'); - if(player.isTurnedOver()){ + player.addSkill("stone_chongfeng"); + if (player.isTurnedOver()) { player.turnOver(); } } - } - }, - druid_yuehuo:{ - trigger:{global:'damageBegin'}, - forced:true, - unique:true, - filter:function(event){ - return event.card&&get.type(event.card)=='trick'&&event.notLink(); }, - content:function(){ + }, + druid_yuehuo: { + trigger: { global: "damageBegin" }, + forced: true, + unique: true, + filter: function (event) { + return event.card && get.type(event.card) == "trick" && event.notLink(); + }, + content: function () { trigger.num++; }, }, - shaman_anhun:{ - trigger:{global:'dieAfter'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.player.side==player.side; + shaman_anhun: { + trigger: { global: "dieAfter" }, + forced: true, + unique: true, + filter: function (event, player) { + return event.player.side == player.side; }, - content:function(){ - player.line(player.getLeader(),'green'); + content: function () { + player.line(player.getLeader(), "green"); player.getLeader().drawDeck(); - } - }, - shaman_zoushi:{ - trigger:{global:'useCardAfter'}, - direct:true, - unique:true, - filter:function(event,player){ - return get.type(event.card)=='stonecharacter'&&event.player==player.getLeader(); }, - content:function(){ - if(!player.storage.shaman_zoushi){ - player.storage.shaman_zoushi=true; - } - else{ - var list=[]; - for(var i=0;i3) num=3; - player.actused-=num; - player.updateActCount(); - player.removeSkill('spell_sijidaifa'); - } - }, - shaman_qingwa:{ - trigger:{player:'phaseDrawBefore'}, - forced:true, - unique:true, - popup:false, - content:function(){ - trigger.cancel(); - }, - ai:{ - threaten:0.1 - } - }, - stone_jingxiang:{ - trigger:{player:'phaseDrawBefore'}, - forced:true, - unique:true, - popup:false, - content:function(){ - trigger.cancel(); - }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='bingliang') return 0; - } + }, }, - noPhaseDelay:1 - } - }, - mage_mianyang:{ - mod:{ - cardEnabled:function(card){ - if(card.name=='sha') return false; - } }, - ai:{ - threaten:0.1 - } + group: "mage_hanbingpingzhang2", }, - priest_xundao:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return player.getLeader().countCards('h',{type:'stonecharacter'})>0; + mage_hanbingpingzhang2: { + trigger: { global: "phaseBegin" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player == player.getLeader(); }, - content:function(){ + content: function () { + player.removeSkill("mage_hanbingpingzhang"); + }, + }, + spell_modaoyou: { + intro: { + content: function (storage) { + return "下次剑刃乱舞的伤害+" + storage; + }, + }, + }, + hunter_jiewang2: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player.hasSkill("hunter_jiewang"); + }, + content: function () { + player.gain(game.createCard(lib.beastList.randomGet() + "_stonecharacter"), "draw"); + player.removeSkill("hunter_jiewang2"); + }, + }, + hunter_zidanshangtang: { + trigger: { player: "useCard" }, + forced: true, + mark: true, + intro: { + content: "每当你使用一张法术牌,便随机获得一张猎人职业法术牌", + }, + filter: function (event) { + return get.type(event.card) == "stonecard"; + }, + content: function () { + var list = [ + "spell_lierenyinji", + "spell_guanmenfanggou", + "spell_duochongsheji", + "spell_kuaisusheji", + "spell_zhaohuanchongwu", + ]; + player.gain(game.createCard(list.randomGet()), "draw"); + }, + }, + spell_yemanpaoxiao: { + mark: true, + intro: { + content: "友方角色造成的伤害+1", + }, + global: "spell_yemanpaoxiao2", + }, + spell_yemanpaoxiao2: { + trigger: { source: "damageBegin" }, + forced: true, + filter: function (event, player) { + return player.getLeader().hasSkill("spell_yemanpaoxiao") && event.notLink(); + }, + content: function () { + trigger.num++; + }, + }, + stone_zibao: { + trigger: { player: "phaseAfter" }, + forced: true, + content: function () { + player.die(); + }, + }, + spell_sijidaifa: { + trigger: { player: "useCard" }, + forced: true, + filter: function (event, player) { + return get.type(event.card) == "stonecard"; + }, + mark: true, + intro: { + content: "使用下一张法术牌时获得X点行动值,X为该法术的行动值消耗且不超过3", + }, + content: function () { + var num = lib.card[trigger.card.name].stoneact; + if (num > 3) num = 3; + player.actused -= num; + player.updateActCount(); + player.removeSkill("spell_sijidaifa"); + }, + }, + shaman_qingwa: { + trigger: { player: "phaseDrawBefore" }, + forced: true, + unique: true, + popup: false, + content: function () { + trigger.cancel(); + }, + ai: { + threaten: 0.1, + }, + }, + stone_jingxiang: { + trigger: { player: "phaseDrawBefore" }, + forced: true, + unique: true, + popup: false, + content: function () { + trigger.cancel(); + }, + ai: { + effect: { + target: function (card) { + if (card.name == "bingliang") return 0; + }, + }, + noPhaseDelay: 1, + }, + }, + mage_mianyang: { + mod: { + cardEnabled: function (card) { + if (card.name == "sha") return false; + }, + }, + ai: { + threaten: 0.1, + }, + }, + priest_xundao: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getLeader().countCards("h", { type: "stonecharacter" }) > 0; + }, + content: function () { player.draw(); - player.addSkill('lschaofeng'); - } - }, - priest_guangyao:{ - trigger:{player:'changeHp'}, - forced:true, - unique:true, - filter:function(event){ - return event.num!=0; + player.addSkill("lschaofeng"); }, - content:function(){ + }, + priest_guangyao: { + trigger: { player: "changeHp" }, + forced: true, + unique: true, + filter: function (event) { + return event.num != 0; + }, + content: function () { player.draw(Math.abs(trigger.num)); }, }, - priest_zhufu:{ - trigger:{player:'dieBegin'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i0; + rogue_cisha: { + trigger: { source: "damageEnd" }, + forced: true, + unique: true, + filter: function (event, player) { + return event.player.isAlive() && event.player.isMin(); }, - content:function(){ - "step 0" - event.chooser=player.getLeader(); + content: function () { + trigger.player.die({ source: player }); + }, + }, + rogue_touxi: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + var target = player.getLeader(); + return target.countCards("e") > 0; + }, + content: function () { + "step 0"; + event.chooser = player.getLeader(); event.chooser.chooseCardTarget({ - position:'e', - filterTarget:function(card,player,target){ - return player.side!=target.side; + position: "e", + filterTarget: function (card, player, target) { + return player.side != target.side; }, - filterCard:true, - ai1:function(card){ - return 9-get.value(card); + filterCard: true, + ai1: function (card) { + return 9 - get.value(card); }, - ai2:function(target){ - return get.damageEffect(target,player,player); + ai2: function (target) { + return get.damageEffect(target, player, player); }, - prompt:'偷袭:弃置一张装备区内的牌并对一名敌方角色1点伤害' + prompt: "偷袭:弃置一张装备区内的牌并对一名敌方角色1点伤害", }); player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.discard(result.cards); event.chooser.line(result.targets[0]); result.targets[0].damage(event.chooser); } - } + }, }, - rogue_qiancang:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i0; - }).ai=function(target){ - return target.countCards('he'); + content: function () { + "step 0"; + event.chooser = player.getLeader(); + event.chooser.chooseTarget( + "持盾:弃置对方一名随从的所有牌", + function (card, playerx, target) { + return ( + player.side != target.side && target.isMin() && target.countCards("he") > 0 + ); + } + ).ai = function (target) { + return target.countCards("he"); }; player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.line(result.targets[0]); game.delay(); - result.targets[0].discard(result.targets[0].getCards('he')); + result.targets[0].discard(result.targets[0].getCards("he")); } - } - }, - paladin_zhaochao:{ - trigger:{global:'useSkillAfter'}, - forced:true, - unique:true, - filter:function(event,player){ - return event.career&&event.player.side==player.side; }, - content:function(){ - player.draw(2); - } }, - paladin_buji:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i1) return 'discard_card'; - return '造成伤害'; + "step 1"; + if (result.bool) { + event.target = result.targets[0]; + event.chooser.chooseControl("造成伤害", "discard_card").ai = function () { + if (event.target.hp > 1) return "discard_card"; + return "造成伤害"; }; event.chooser.line(event.target); game.delay(); - } - else{ + } else { event.finish(); } - "step 2" - if(result.control=='造成伤害'){ + "step 2"; + if (result.control == "造成伤害") { event.target.damage(event.chooser); - } - else{ - event.target.discard(event.target.getCards('h')); - if(event.target.maxHp>2){ - event.target.loseMaxHp(event.target.maxHp-2); + } else { + event.target.discard(event.target.getCards("h")); + if (event.target.maxHp > 2) { + event.target.loseMaxHp(event.target.maxHp - 2); } } - } - }, - druid_yexingchengzhang:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - mark:true, - intro:{ - content:'下个出牌阶段开始时获得三点额外行动值', }, - content:function(){ - player.actused-=3; - player.updateActCount(); - player.removeSkill('druid_yexingchengzhang'); - } }, - druid_ziyang:{ - trigger:{player:'phaseUseBegin'}, - forced:true, - mark:true, - intro:{ - content:'下个出牌阶段开始时获得四点额外行动值', + druid_yexingchengzhang: { + trigger: { player: "phaseUseBegin" }, + forced: true, + mark: true, + intro: { + content: "下个出牌阶段开始时获得三点额外行动值", }, - content:function(){ - player.actused-=4; + content: function () { + player.actused -= 3; player.updateActCount(); - player.removeSkill('druid_ziyang'); - } + player.removeSkill("druid_yexingchengzhang"); + }, }, - druid_chengzhang:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - var target=player.getLeader(); + druid_ziyang: { + trigger: { player: "phaseUseBegin" }, + forced: true, + mark: true, + intro: { + content: "下个出牌阶段开始时获得四点额外行动值", + }, + content: function () { + player.actused -= 4; + player.updateActCount(); + player.removeSkill("druid_ziyang"); + }, + }, + druid_chengzhang: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + var target = player.getLeader(); target.actused--; target.updateActCount(); }, - group:'druid_chengzhang2' + group: "druid_chengzhang2", }, - druid_chengzhang2:{ - trigger:{player:'dieBegin'}, - forced:true, - unique:true, - content:function(){ - player.getLeader().addSkill('druid_chengzhang3'); - } - }, - druid_chengzhang3:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return event.player.hasSkill('druid_chengzhang'); + druid_chengzhang2: { + trigger: { player: "dieBegin" }, + forced: true, + unique: true, + content: function () { + player.getLeader().addSkill("druid_chengzhang3"); }, - content:function(){ - if(player.countCards('h')){ + }, + druid_chengzhang3: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return event.player.hasSkill("druid_chengzhang"); + }, + content: function () { + if (player.countCards("h")) { game.delay(); - player.chooseToDiscard('h',true); + player.chooseToDiscard("h", true); } - player.removeSkill('druid_chengzhang3'); - } - }, - shaman_xueju:{ - trigger:{global:'useCard'}, - forced:true, - unique:true, - filter:function(event,player){ - return get.type(event.card)=='stonecharacter'&&event.player==player.getLeader(); + player.removeSkill("druid_chengzhang3"); }, - content:function(){ - player.draw(); - } }, - shaman_huoxi:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;iplayer.actcount) return false; - if(player.storage.anyingxingtai) return false; + shaman_huoshe: { + trigger: { global: "damageBegin" }, + forced: true, + filter: function (event, player) { + return ( + event.source && + event.source != player && + event.source.isMin() && + player.side == event.source.side && + event.notLink() + ); + }, + content: function () { + trigger.num++; + }, + ai: { + threaten: 1.8, + }, + }, + _priest_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "priest") return false; + if (player.getActCount() + 2 > player.actcount) return false; + if (player.storage.anyingxingtai) return false; return true; }, - usable:1, - prompt:function(event){ - if(event.player.hasFellowSkill('priest_hunwu')) return '令目标失去1点体力'; - return '回复1点体力'; + usable: 1, + prompt: function (event) { + if (event.player.hasFellowSkill("priest_hunwu")) return "令目标失去1点体力"; + return "回复1点体力"; }, - filterTarget:function(card,player,target){ - if(player.hasFellowSkill('priest_hunwu')) return true; - return target.hpplayer.actcount) return false; - if(!player.storage.anyingxingtai) return false; + _priest_skillx: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "priest") return false; + if (player.getActCount() + 2 > player.actcount) return false; + if (!player.storage.anyingxingtai) return false; return true; }, - usable:1, - prompt:function(event,player){ - return '造成'+get.cnNumber(_status.event.player.storage.anyingxingtai)+'点伤害'; + usable: 1, + prompt: function (event, player) { + return "造成" + get.cnNumber(_status.event.player.storage.anyingxingtai) + "点伤害"; }, - filterTarget:true, - content:function(){ - player.actused+=2; + filterTarget: true, + content: function () { + player.actused += 2; player.updateActCount(); - event.parent.career='priest'; - var num=1; + event.parent.career = "priest"; + var num = 1; // if(player.hasFellowSkill('stone_shenyou')){ // num=2; // } - target.damage(player.storage.anyingxingtai*num); + target.damage(player.storage.anyingxingtai * num); + }, + ai: { + order: 2, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); + }, + }, }, - ai:{ - order:2, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); - } - } - } }, - _mage_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.career!='mage') return false; - if(player.getActCount()+2>player.actcount) return false; + _mage_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "mage") return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - line:'fire', - filterTarget:function(card,player,target){ + usable: 1, + line: "fire", + filterTarget: function (card, player, target) { return !target.career; }, - content:function(){ - player.actused+=2; + content: function () { + player.actused += 2; player.updateActCount(); - target.damage('fire'); - event.parent.career='mage'; + target.damage("fire"); + event.parent.career = "mage"; + }, + ai: { + order: 2, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target, "fire"); + }, + }, }, - ai:{ - order:2, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target,'fire'); - } - } - } }, - _warlock_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.hasSkill('stone_lianyu')) return false; - if(player.career!='warlock') return false; - if(player.getActCount()+2>player.actcount) return false; + _warlock_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.hasSkill("stone_lianyu")) return false; + if (player.career != "warlock") return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - content:function(){ - player.actused+=2; + usable: 1, + content: function () { + player.actused += 2; player.updateActCount(); player.drawDeck(2); - event.parent.career='warlock'; + event.parent.career = "warlock"; + }, + ai: { + order: 0.5, + result: { + player: 1, + }, }, - ai:{ - order:0.5, - result:{ - player:1 - } - } }, - _warlock_skillx:{ - enable:'phaseUse', - filter:function(event,player){ - if(!player.hasSkill('stone_lianyu')) return false; - if(player.career!='warlock') return false; - if(player.getActCount()+2>player.actcount) return false; - if(!player.canAddFellow()) return false; + _warlock_skillx: { + enable: "phaseUse", + filter: function (event, player) { + if (!player.hasSkill("stone_lianyu")) return false; + if (player.career != "warlock") return false; + if (player.getActCount() + 2 > player.actcount) return false; + if (!player.canAddFellow()) return false; return true; }, - usable:1, - content:function(){ - 'step 0' - player.actused+=2; + usable: 1, + content: function () { + "step 0"; + player.actused += 2; player.updateActCount(); - event.parent.career='warlock'; - player.addFellowAuto('stone_diyuhuox'); - 'step 1' - var num=player.storage.stone_lianyu; - if(num&&get.itemtype(result)=='player'){ - result.maxHp+=num; - result.hp+=num; + event.parent.career = "warlock"; + player.addFellowAuto("stone_diyuhuox"); + "step 1"; + var num = player.storage.stone_lianyu; + if (num && get.itemtype(result) == "player") { + result.maxHp += num; + result.hp += num; result.directgain(get.cards(num)); } }, - ai:{ - order:0.5, - result:{ - player:1 - } - } + ai: { + order: 0.5, + result: { + player: 1, + }, + }, }, - _hunter_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.career!='hunter') return false; - if(player.getActCount()+2>player.actcount) return false; + _hunter_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "hunter") return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - prompt:function(event){ - if(event.player.hasFellowSkill('hunter_juji')) return '造成1点伤害'; - return '对敌方主将造成1点伤害'; + usable: 1, + prompt: function (event) { + if (event.player.hasFellowSkill("hunter_juji")) return "造成1点伤害"; + return "对敌方主将造成1点伤害"; }, - selectTarget:function(){ - if(_status.event.player.hasFellowSkill('hunter_juji')) return 1; + selectTarget: function () { + if (_status.event.player.hasFellowSkill("hunter_juji")) return 1; return -1; }, - filterTarget:function(card,player,target){ - if(player.hasFellowSkill('hunter_juji')) return target!=player; - return target.career&&target.side!=player.side; + filterTarget: function (card, player, target) { + if (player.hasFellowSkill("hunter_juji")) return target != player; + return target.career && target.side != player.side; }, - content:function(){ - player.actused+=2; + content: function () { + player.actused += 2; player.updateActCount(); target.damage(); - event.parent.career='hunter'; + event.parent.career = "hunter"; + }, + ai: { + order: 2, + result: { + target: function (player, target) { + return get.damageEffect(target, player, target); + }, + }, }, - ai:{ - order:2, - result:{ - target:function(player,target){ - return get.damageEffect(target,player,target); - } - } - } }, - _warrior_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.hujia>=3) return false; - if(player.career!='warrior') return false; - if(player.getActCount()+2>player.actcount) return false; + _warrior_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.hujia >= 3) return false; + if (player.career != "warrior") return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - content:function(){ - player.actused+=2; + usable: 1, + content: function () { + player.actused += 2; player.updateActCount(); player.changeHujia(1); - event.parent.career='warrior'; + event.parent.career = "warrior"; + }, + ai: { + order: 2, + result: { + player: 1, + }, }, - ai:{ - order:2, - result:{ - player:1 - } - } }, - _rogue_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.career!='rogue') return false; - if(player.getActCount()+2>player.actcount) return false; + _rogue_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "rogue") return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - content:function(){ - 'step 0' - player.actused+=2; + usable: 1, + content: function () { + "step 0"; + player.actused += 2; player.updateActCount(); - var equip1=get.cardPile(function(card){ - return get.subtype(card)=='equip1'; + var equip1 = get.cardPile(function (card) { + return get.subtype(card) == "equip1"; }); - if(!equip1){ - equip1=game.createCard('qingnang'); + if (!equip1) { + equip1 = game.createCard("qingnang"); } - var equip4=get.cardPile(function(card){ - return get.type(card)=='equip'&&get.subtype(card)!='equip1'; + var equip4 = get.cardPile(function (card) { + return get.type(card) == "equip" && get.subtype(card) != "equip1"; }); - if(!equip4){ - equip4=game.createCard('chitu'); + if (!equip4) { + equip4 = game.createCard("chitu"); } player.$gain(equip1); - setTimeout(function(){ + setTimeout(function () { player.$gain(equip4); - },250); + }, 250); game.delay(); - event.equip1=equip1; - event.equip4=equip4; - 'step 1' + event.equip1 = equip1; + event.equip4 = equip4; + "step 1"; player.equip(event.equip1); game.delay(0.5); - 'step 2' + "step 2"; player.equip(event.equip4); - event.parent.career='rogue'; + event.parent.career = "rogue"; }, - ai:{ - order:function(skill,player){ - if(!player.getEquip(1)&&player.countCards('e')<2){ - if(player.countCards('h','sha')&&player.getActCount()+3<=player.actcount){ + ai: { + order: function (skill, player) { + if (!player.getEquip(1) && player.countCards("e") < 2) { + if ( + player.countCards("h", "sha") && + player.getActCount() + 3 <= player.actcount + ) { return 4; } return 0.1; } return 0; }, - result:{ - player:function(player){ - if(player.countCards('e')<=2) return 1; + result: { + player: function (player) { + if (player.countCards("e") <= 2) return 1; return 0; - } - } - } - }, - _druid_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.career!='druid') return false; - if(player.getActCount()+2>player.actcount) return false; - return lib.filter.cardEnabled({name:'sha'},player); - }, - usable:1, - filterTarget:function(card,player,target){ - return player.canUse('sha',target,null,false); - }, - direct:true, - content:function(){ - player.actused+=2; - player.updateActCount(); - player.useCard({name:'sha'},targets,'_druid_skill',false).animate=false; - event.parent.career='druid'; - }, - ai:{ - order:function(){ - return get.order({name:'sha'})-0.1; + }, }, - result:{ - target:function(player,target){ - return get.effect(target,{name:'sha'},player,target); - } - } - } + }, }, - shaman_tuteng:{ - trigger:{player:'phaseDrawBefore'}, - forced:true, - popup:false, - content:function(){ + _druid_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "druid") return false; + if (player.getActCount() + 2 > player.actcount) return false; + return lib.filter.cardEnabled({ name: "sha" }, player); + }, + usable: 1, + filterTarget: function (card, player, target) { + return player.canUse("sha", target, null, false); + }, + direct: true, + content: function () { + player.actused += 2; + player.updateActCount(); + player.useCard({ name: "sha" }, targets, "_druid_skill", false).animate = false; + event.parent.career = "druid"; + }, + ai: { + order: function () { + return get.order({ name: "sha" }) - 0.1; + }, + result: { + target: function (player, target) { + return get.effect(target, { name: "sha" }, player, target); + }, + }, + }, + }, + shaman_tuteng: { + trigger: { player: "phaseDrawBefore" }, + forced: true, + popup: false, + content: function () { trigger.cancel(); }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='bingliang') return 0; - } + ai: { + effect: { + target: function (card) { + if (card.name == "bingliang") return 0; + }, }, - noPhaseDelay:1 - } + noPhaseDelay: 1, + }, }, - shaman_zhiliao:{ - trigger:{player:'phaseEnd'}, - forced:true, - direct:true, - content:function(){ - 'step 0' - var players=get.players(); - var targets=[]; - for(var i=0;iplayer.actcount) return false; + _shaman_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "shaman") return false; + if (!player.canAddFellow()) return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - content:function(){ - player.actused+=2; + usable: 1, + content: function () { + player.actused += 2; player.updateActCount(); - var name='stone_tuteng'+Math.ceil(Math.random()*4); + var name = "stone_tuteng" + Math.ceil(Math.random() * 4); player.addFellowAuto(name); - event.parent.career='shaman'; + event.parent.career = "shaman"; + }, + ai: { + order: 2, + result: { + player: 1, + }, }, - ai:{ - order:2, - result:{ - player:1 - } - } }, - _paladin_skill:{ - enable:'phaseUse', - filter:function(event,player){ - if(player.career!='paladin') return false; - if(!player.canAddFellow()) return false; - if(player.getActCount()+2>player.actcount) return false; + _paladin_skill: { + enable: "phaseUse", + filter: function (event, player) { + if (player.career != "paladin") return false; + if (!player.canAddFellow()) return false; + if (player.getActCount() + 2 > player.actcount) return false; return true; }, - usable:1, - content:function(){ - player.actused+=2; + usable: 1, + content: function () { + player.actused += 2; player.updateActCount(); - player.addFellowAuto('stone_xinbing'); - event.parent.career='paladin'; + player.addFellowAuto("stone_xinbing"); + event.parent.career = "paladin"; + }, + ai: { + order: 2, + result: { + player: 1, + }, }, - ai:{ - order:2, - result:{ - player:1 - } - } }, - lschaofeng:{ - mark:true, - intro:{ - content:'已获得嘲讽' - } + lschaofeng: { + mark: true, + intro: { + content: "已获得嘲讽", + }, }, - _lschaofeng:{ - mod:{ - targetEnabled:function(card,player,target){ - if(target.hasSkill('lschaofeng')) return; - if(card.name=='sha'){ - for(var i=0;i0; - }).ai=function(target){ - return target.countCards('he'); + content: function () { + "step 0"; + event.chooser = player.getLeader(); + event.chooser.chooseTarget( + "叫嚣:弃置对方一名随从的所有牌", + function (card, playerx, target) { + return ( + player.side != target.side && target.isMin() && target.countCards("he") > 0 + ); + } + ).ai = function (target) { + return target.countCards("he"); }; player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.line(result.targets[0]); game.delay(); - result.targets[0].discard(result.targets[0].getCards('he')); + result.targets[0].discard(result.targets[0].getCards("he")); } - } + }, }, - stone_huoqiangshou1:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - for(var i=0;i0; }, - content:function(){ - var enemy=player.getEnemy(); - var es=enemy.getCards('e'); - if(es.length){ + }, + stone_dijieshicong1: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getEnemy().countCards("e") > 0; + }, + content: function () { + var enemy = player.getEnemy(); + var es = enemy.getCards("e"); + if (es.length) { player.getLeader().line(enemy); game.delay(); enemy.discard(es.randomGet()); // game.log(get.translation(event.enemy)+'将'+get.translation(es)+'收入手牌') } - } - }, - stone_yaosaishouwei1:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - player.getLeader().addTempSkill('stone_yaosaishouwei2'); - } - }, - stone_yaosaishouwei2:{ - mod:{ - maxHandcard:function(player,num){ - return num+2; - } }, }, - stone_famingjia1:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ + stone_yaosaishouwei1: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + player.getLeader().addTempSkill("stone_yaosaishouwei2"); + }, + }, + stone_yaosaishouwei2: { + mod: { + maxHandcard: function (player, num) { + return num + 2; + }, + }, + }, + stone_famingjia1: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { player.getLeader().draw(2); - } + }, }, - stone_chilundashi1:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - player.addSkill('stone_chilundashi2'); - } + stone_chilundashi1: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + content: function () { + player.addSkill("stone_chilundashi2"); + }, }, - stone_chilundashi2:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - content:function(){ + stone_chilundashi2: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + content: function () { trigger.num++; - player.removeSkill('stone_chilundashi2'); - } + player.removeSkill("stone_chilundashi2"); + }, }, - stone_hanguangzhizhe1:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - content:function(){ - var targets=[]; - for(var i=0;i0&&num>=player.getLeader().countFellow(); }, - content:function(){ - var list=[]; - for(var i=0;i 0 && num >= player.getLeader().countFellow(); + }, + content: function () { + var list = []; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isMin() && game.players[i].side != player.side) { list.push(game.players[i]); } } - if(list.length){ - var target=list.randomGet(); - player.line(target,'green'); - target.die({source:player}); + if (list.length) { + var target = list.randomGet(); + player.line(target, "green"); + target.die({ source: player }); game.delay(); } - } - }, - stone_yanjingshe_old:{ - trigger:{source:'fellow'}, - forced:true, - unique:true, - filter:function(event,player){ - return player.getEnemy().countFellow()>=player.getLeader().countFellow(); }, - content:function(){ - "step 0" - event.chooser=player.getEnemy(); - event.chooser.chooseTarget('毒噬:选择己方一名随从令其死亡',function(card,playerx,target){ - return target.isMin()&&target.side!=player.side; - },true).ai=function(target){ + }, + stone_yanjingshe_old: { + trigger: { source: "fellow" }, + forced: true, + unique: true, + filter: function (event, player) { + return player.getEnemy().countFellow() >= player.getLeader().countFellow(); + }, + content: function () { + "step 0"; + event.chooser = player.getEnemy(); + event.chooser.chooseTarget( + "毒噬:选择己方一名随从令其死亡", + function (card, playerx, target) { + return target.isMin() && target.side != player.side; + }, + true + ).ai = function (target) { return -target.hp; }; player.line(event.chooser); - "step 1" - if(result.bool){ + "step 1"; + if (result.bool) { event.chooser.line(result.targets[0]); game.delay(); result.targets[0].die(); } - } - }, - stone_mafengzhuru1:{ - trigger:{player:'dieBegin'}, - forced:true, - filter:function(event){ - return event.source&&event.source.isMin(); - }, - content:function(){ - trigger.source.addSkill('stone_mafengzhuru2'); }, }, - stone_mafengzhuru2:{ - trigger:{global:'dieAfter'}, - forced:true, - popup:false, - unique:true, - filter:function(event,player){ - return player.hasSkill('stone_mafengzhuru2'); + stone_mafengzhuru1: { + trigger: { player: "dieBegin" }, + forced: true, + filter: function (event) { + return event.source && event.source.isMin(); }, - content:function(){ + content: function () { + trigger.source.addSkill("stone_mafengzhuru2"); + }, + }, + stone_mafengzhuru2: { + trigger: { global: "dieAfter" }, + forced: true, + popup: false, + unique: true, + filter: function (event, player) { + return player.hasSkill("stone_mafengzhuru2"); + }, + content: function () { player.loseHp(); - player.removeSkill('stone_mafengzhuru2'); - } + player.removeSkill("stone_mafengzhuru2"); + }, }, - stone_zhufu:{ - trigger:{global:'phaseEnd'}, - forced:true, - unique:true, - filter:function(event,player){ - if(event.player!=player.getLeader()) return false; - for(var i=0;iplayer.actcount) return false; - } + if (player.getActCount() + stoneact > player.actcount) return false; + }, }, - trigger:{player:'phaseBegin'}, - forced:true, - popup:false, - priority:15, - filter:function(event,player){ + trigger: { player: "phaseBegin" }, + forced: true, + popup: false, + priority: 15, + filter: function (event, player) { return !player.isMin(); }, - content:function(){ - player.actused=0; - if(player.side){ - player.actcount=player.getEnemy().actcount+1; - } - else{ - player.actcount=player.getEnemy().actcount; - if(!_status.actcoin){ - _status.actcoin=true; + content: function () { + player.actused = 0; + if (player.side) { + player.actcount = player.getEnemy().actcount + 1; + } else { + player.actcount = player.getEnemy().actcount; + if (!_status.actcoin) { + _status.actcoin = true; player.actused--; } } - if(player.actcount>6){ - if(get.config('mana_mode')=='inc'){ - player.actcount=6; - } - else{ - player.actcount-=4; + if (player.actcount > 6) { + if (get.config("mana_mode") == "inc") { + player.actcount = 6; + } else { + player.actcount -= 4; } } player.updateActCount(); - player.getEnemy().updateActCount('outphase'); - } - }, - _actcount2:{ - trigger:{player:'useCard'}, - forced:true, - popup:false, - filter:function(event,player){ - return !player.isMin()&&!event.noActCount&&_status.currentPhase==player; + player.getEnemy().updateActCount("outphase"); }, - content:function(){ - var stoneact=get.info(trigger.card).stoneact; - if(typeof stoneact==='number'){ - player.actused+=stoneact-1; + }, + _actcount2: { + trigger: { player: "useCard" }, + forced: true, + popup: false, + filter: function (event, player) { + return !player.isMin() && !event.noActCount && _status.currentPhase == player; + }, + content: function () { + var stoneact = get.info(trigger.card).stoneact; + if (typeof stoneact === "number") { + player.actused += stoneact - 1; } player.updateActCount(); - } + }, }, - stonesha:{ - unique:true, - mod:{ - cardname:function(card){ - if(lib.card[card.name].type=='equip') return 'sha'; + stonesha: { + unique: true, + mod: { + cardname: function (card) { + if (lib.card[card.name].type == "equip") return "sha"; }, }, }, - stoneshan:{ - unique:true, - mod:{ - cardname:function(card){ - if(lib.card[card.name].type.indexOf('stone')==0) return 'shan'; + stoneshan: { + unique: true, + mod: { + cardname: function (card) { + if (lib.card[card.name].type.indexOf("stone") == 0) return "shan"; }, }, }, - stonedraw:{ - trigger:{player:'phaseDrawBegin'}, - forced:true, - popup:false, - content:function(){ + stonedraw: { + trigger: { player: "phaseDrawBegin" }, + forced: true, + popup: false, + content: function () { trigger.num--; }, - ai:{ - effect:{ - target:function(card){ - if(card.name=='bingliang'){ + ai: { + effect: { + target: function (card) { + if (card.name == "bingliang") { return 0.6; } - } - } - } + }, + }, + }, }, - _stonerage1:{ - trigger:{player:'damageEnd'}, - forced:true, - popup:false, - content:function(){ - if(player.isMin()){ - player.changeRage(3*trigger.num); + _stonerage1: { + trigger: { player: "damageEnd" }, + forced: true, + popup: false, + content: function () { + if (player.isMin()) { + player.changeRage(3 * trigger.num); + } else { + player.changeRage(6 * trigger.num); } - else{ - player.changeRage(6*trigger.num); - } - } + }, }, - _stonerage2:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content:function(){ - if(player.isMin()){ + _stonerage2: { + trigger: { player: "dieBegin" }, + forced: true, + popup: false, + content: function () { + if (player.isMin()) { player.changeRage(10); - } - else{ + } else { player.changeRage(20); } - } - }, - _stonerage3:{ - trigger:{player:'phaseAfter'}, - forced:true, - popup:false, - filter:function(event,player){ - return !player.isMin()&&player.getEnemy().countFellow()>player.countFellow(); }, - content:function(){ - player.changeRage((player.getEnemy().countFellow()-player.countFellow())*10); - } }, - _stonerage_add:{ - trigger:{player:'phaseBegin'}, - direct:true, - priority:10, - filter:function(event,player){ - if(!player.canAddFellow()){ + _stonerage3: { + trigger: { player: "phaseAfter" }, + forced: true, + popup: false, + filter: function (event, player) { + return !player.isMin() && player.getEnemy().countFellow() > player.countFellow(); + }, + content: function () { + player.changeRage((player.getEnemy().countFellow() - player.countFellow()) * 10); + }, + }, + _stonerage_add: { + trigger: { player: "phaseBegin" }, + direct: true, + priority: 10, + filter: function (event, player) { + if (!player.canAddFellow()) { return false; } - if(player==game.me){ - return _status.friendRage>=100; - } - else if(player==game.me.getEnemy()){ - return _status.enemyRage>=100; + if (player == game.me) { + return _status.friendRage >= 100; + } else if (player == game.me.getEnemy()) { + return _status.enemyRage >= 100; } return false; }, - content:function(){ - 'step 0' - var list=[]; - var list2=[]; - for(var i in lib.character){ - if(lib.character[i][4].includes('stonelegend_'+player.career)){ + content: function () { + "step 0"; + var list = []; + var list2 = []; + for (var i in lib.character) { + if (lib.character[i][4].includes("stonelegend_" + player.career)) { list.push(i); - } - else if(lib.character[i][4].includes('stonelegend')){ + } else if (lib.character[i][4].includes("stonelegend")) { list2.push(i); } } - var dialog=ui.create.dialog('hidden','召唤一名传说随从','
                            消耗100怒气值和4点行动值
                            ',[list.concat(list2),'character']); - var heilong=false; - var dc=player.getEnemy().countFellow()-player.countFellow(); - if(dc>2){ - heilong=true; - } - else if(dc==2){ - if(player.getEnemy().countFellow()>=3){ - heilong=Math.random()<0.5; - } - else if(player.actcount-player.getActCount()<=0){ - heilong=true; - } - else{ - dc=0; - for(var i=0;i消耗100怒气值和4点行动值
                        ', + [list.concat(list2), "character"] + ); + var heilong = false; + var dc = player.getEnemy().countFellow() - player.countFellow(); + if (dc > 2) { + heilong = true; + } else if (dc == 2) { + if (player.getEnemy().countFellow() >= 3) { + heilong = Math.random() < 0.5; + } else if (player.actcount - player.getActCount() <= 0) { + heilong = true; + } else { + dc = 0; + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isMin() && game.players[i].side != player.side) { + dc += game.players[i].hp; } } - if(dc>5){ - heilong=true; - } - else{ - heilong=Math.random()<0.3; + if (dc > 5) { + heilong = true; + } else { + heilong = Math.random() < 0.3; } } } - var honglong=false; - if(!heilong){ - var num=0; - for(var i=0;i6){ - honglong=true; - } - else if(player.maxHp-player.hp>=3&&player.hp<=2){ - honglong=true; + if (num > 6) { + honglong = true; + } else if (player.maxHp - player.hp >= 3 && player.hp <= 2) { + honglong = true; } } - player.chooseButton(dialog).ai=function(button){ - if(button.link=='stone_siwangzhiyi'){ - if(heilong) return 3; + player.chooseButton(dialog).ai = function (button) { + if (button.link == "stone_siwangzhiyi") { + if (heilong) return 3; return 0; } - if(button.link=='stone_alaikesita'){ - if(honglong) return 2; + if (button.link == "stone_alaikesita") { + if (honglong) return 2; return 0; } return Math.random(); - } - 'step 1' - if(result.bool){ - player.$skill(get.translation(result.links[0]),'legend','metal'); + }; + "step 1"; + if (result.bool) { + player.$skill(get.translation(result.links[0]), "legend", "metal"); game.delay(2); - event.addname=result.links[0]; + event.addname = result.links[0]; player.changeRage(-100); - player.actused+=4; + player.actused += 4; player.updateActCount(); - } - else{ + } else { event.finish(); } - 'step 2' - if(event.addname){ - if(event.addname=='stone_jialakesi'){ - if(player.name=='stone_jialakesix'){ - player.hp=player.maxHp; + "step 2"; + if (event.addname) { + if (event.addname == "stone_jialakesi") { + if (player.name == "stone_jialakesix") { + player.hp = player.maxHp; player.update(); - player.actused-=4; + player.actused -= 4; player.updateActCount(); player.storage.stone_lianyu++; - } - else{ - if(player.name2){ - player.storage.stone_lianyu=1; + } else { + if (player.name2) { + player.storage.stone_lianyu = 1; + } else { + player.storage.stone_lianyu = 0; } - else{ - player.storage.stone_lianyu=0; - } - player.init('stone_jialakesix'); - game.addVideo('reinit2',player,'stone_jialakesix'); + player.init("stone_jialakesix"); + game.addVideo("reinit2", player, "stone_jialakesix"); } - player.syncStorage('stone_lianyu'); - var card=game.createCard('stone_jialakesi_stonecharacter'); + player.syncStorage("stone_lianyu"); + var card = game.createCard("stone_jialakesi_stonecharacter"); card.node.info.remove(); card.node.addinfo.remove(); - player.$give(card,player); - } - else{ + player.$give(card, player); + } else { player.addFellowAuto(event.addname); } } - } - } + }, + }, }, - translate:{ - shaman:'萨满', - mage:'法师', - priest:'牧师', - warrior:'战士', - warlock:'术士', - knight:'死亡骑士', - rogue:'潜行者', - paladin:'圣骑士', - hunter:'猎人', - druid:'德鲁伊', - - stone_siwangzhiyi:'死亡之翼', - stone_alaikesita:'阿莱克萨', - stone_yisela:'伊瑟拉', - stone_nuoziduomu:'诺兹多姆', - stone_maligousi:'玛里苟斯', - stone_aolajier:'奥拉基尔', - stone_andongni:'安东尼', - stone_jialakesi:'加拉克斯', - stone_jialakesix:'加拉克斯', - stone_kelushi:'克鲁什', - stone_geluomashi:'格罗玛什', - stone_aidewen:'艾德温', - stone_sainaliusi:'塞纳留斯', - stone_fuding:'弗丁', - stone_weilun:'维纶', - - stone_fushi:'缚誓', - stone_fushi_info:'你出场时,为所有友方角色回复所有体力值。', - stone_mieshi:'灭世', - stone_mieshi_info:'你出场时,对所有其他随从造成2点伤害,然后弃置己方主将的所有手牌。', - stone_shixu:'时序', - stone_shixu_info:'你出场的回合内,己方主将获得4点行动值。', - stone_chenshui:'沉睡', - stone_chenshui_info:'在你的结束阶段,令己方主将获得一张梦境牌。', - stone_mowang:'魔网', - stone_mowang_info:'己方法术对主将伤害+2,对随从伤害+4。', - - stone_zhiyin:'指引', - stone_zhiyin_info:'每当己方主将使用一张法术牌,将一张火球术置于其手牌。', - stone_bianshen:'变身', - stone_bianshen_info:'你出场时,若己方主将职业为术士,则代之成为新的主将;若己变身,则改为令你召唤的地狱火的初始手牌数和体力值+1。', - stone_lianyu:'炼狱', - stone_lianyu_info:'你的职业技能改为召唤一个地狱火。', - stone_lianji:'连击', - stone_lianji_info:'每当己方主将召唤一个随从,便增加1点体力和体力上限并摸一张牌。', - stone_shenyu:'神谕', - stone_shenyu_info:'你出场时,己方主将可以选择一项:召唤两个嘲讽树人,或令所有其他随从增加1点体力和体力上限并摸两张牌。', - stone_fuchou:'复仇', - stone_fuchou_info:'你死亡后,视为己方主将使用了一张复仇之怒。', - stone_shenyou:'神佑', - stone_shenyou_info:'己方主将的职业技能和法术的治疗效果翻倍。', - stone_jinu:'激怒', - stone_jinu_info:'摸牌阶段,若你己受伤,则额外摸两张牌。', - - spell_shenshengxinxing:'神圣新星', - spell_shenshengxinxing_info:'对所有敌方角色造成1点伤害,令所有友方角色回复1点体力。', - spell_shengguangzhadan:'圣光炸弹', - spell_shengguangzhadan_info:'对所有随从造成等同于其手牌数的伤害。', - spell_maizang:'埋葬', - spell_maizang_info:'令一名敌方随从死亡(不触发死亡技能),并将一张与该随从同名的随从洗入你的牌库。', - spell_xinlingshijie:'心灵视界', - spell_xinlingshijie_info:'将一张敌方主将手牌的复制置于你的手牌。', - spell_naluzhiguang:'纳鲁之光', - spell_naluzhiguang_info:'恢复1点体力值,若目标仍处于受伤状态,则召唤一名圣光护卫。', - spell_zhiliaozhihuan:'治疗之环', - spell_zhiliaozhihuan_info:'令所有随从回复3点体力。', - - spell_zhenyanshu:'真言术', - spell_zhenyanshu_info:'令一名随从增加1点体力和体力上限;从牌库中获得一张牌。', - spell_enzeshu:'恩泽术', - spell_enzeshu_info:'令一名随从增加3点体力和体力上限。', - spell_anyingxingtai:'暗影形态', - priest_anyingxingtai:'暗影形态', - spell_anyingxingtai_info:'你的职业技能改为造成1点伤害,若已进入暗影形态,则改为造成2点伤害。', - spell_kuaisuzhiliao:'快速治疗', - spell_kuaisuzhiliao_info:'回复2点体力。', - spell_xinlinghanbao:'心灵撼爆', - spell_xinlinghanbao_info:'对敌方主将造成2点伤害。', - spell_kongxinshu:'控心术', - spell_kongxinshu_info:'复制敌方牌库中的一张随从,将其置入战场。', - - stone_shengguanghuwei:'圣光护卫', - priest_shengguang:'圣光', - priest_shengguang_info:'每当一名随从获得治疗,摸一张牌。', - - spell_nuxi:'怒袭', - spell_nuxi_info:'造成1点伤害,获得2点护甲。', - spell_dunpaimengji:'盾牌猛击', - spell_dunpaimengji_info:'对一名随从造成等同于你护甲值的伤害。', - spell_zhansha:'斩杀', - spell_zhansha_info:'令一名已受伤的敌方随从死亡。', - spell_nuhuozhongshao:'怒火中烧', - spell_nuhuozhongshao_info:'对一名随从造成1点伤害,然后令其摸两张牌。', - spell_xuanfengzhan:'旋风斩', - spell_xuanfengzhan_info:'对所有随从造成1点伤害。', - spell_juemingluandou:'绝命乱斗', - spell_juemingluandou_info:'随机保留一名随从,然后令所有其他随从死亡。', - - spell_zhongnian:'重碾', - spell_zhongnian_info:'造成X点伤害,X为已受伤的友方角色数且不超过3。', - spell_zhandounuhuo:'战斗怒火', - spell_zhandounuhuo_info:'从牌库中获得X张牌,X为已受伤的友方角色数。', - spell_chongfeng:'冲锋', - spell_chongfeng_info:'令一名武将牌背面朝上的友方随从摸三张牌,然后将武将牌翻至正面。', - spell_fuchoudaji:'复仇打击', - spell_fuchoudaji_info:'对所有随从造成1点伤害,若你的体力值不大于2,改为造成3点伤害。', - spell_kuangbao:'狂暴', - spell_kuangbao_info:'令一名已受伤的友方随从摸四张牌。', - spell_yingyongdaji:'英勇打击', - spell_yingyongdaji_info:'令一名敌方角色对你造成2点伤害,然后对其造成2点伤害。', - - spell_dubiao:'毒镖', - spell_dubiao_info:'对一名随机敌方角色造成1点伤害。', - spell_qiangfengsheji:'强风射击', - spell_qiangfengsheji_info:'对两名敌方随从各造成1点伤害,并弃置其两张手牌。', - spell_tanxianmao:'探险帽', - hunter_tanxianmao:'探险帽', - hunter_tanxianmao_info:'你死亡时,将一张探险帽置入主将的手牌。', - spell_tanxianmao_info:'令一名友方随从增加1点体力和体力上限并摸一张牌,当该随从死亡时,将一张探险帽置入你的手牌。', - spell_shalumingling:'杀戮命令', - spell_shalumingling_info:'造成1点伤害,如果你控制任何野兽,则改为造成2点伤害。', - spell_zhuizongshu:'追踪术', - spell_zhuizongshu_info:'从牌库中随机选择三张牌,获得其中的一张。', - spell_tianjiangzhuqun:'天降蛛群', - spell_tianjiangzhuqun_info:'召唤三只结网蛛。', - - spell_lierenyinji:'猎人印记', - spell_lierenyinji_info:'将一名随从的体力上限降至1。', - spell_kuaisusheji:'快速射击', - spell_kuaisusheji_info:'造成1点伤害,摸一张牌。', - spell_guanmenfanggou:'关门放狗', - spell_guanmenfanggou_info:'每有一名敌方随从,便召唤一只猎狗。', - spell_zhaohuanchongwu:'动物伙伴', - spell_zhaohuanchongwu_info:'随机召唤一只野兽。', - spell_zidanshangtang:'子弹上膛', - spell_zidanshangtang_info:'随机获得一张猎人职业法术牌,并获得技能〖上膛〗直到回合结束。', - spell_duochongsheji:'多重射击', - spell_duochongsheji_info:'对两名随机敌方随从各造成2点伤害。', - - stone_liegou:'猎狗', - hunter_zidanshangtang:'上膛', - hunter_zidanshangtang_bg:'膛', - hunter_zidanshangtang_info:'每当你使用一张法术牌,便随机获得一张猎人职业法术牌。', - - spell_zuzhou:'诅咒', - spell_zuzhou_info:'将目标随从翻面,摸一张牌。', - spell_xishengqiyue:'牺牲契约', - spell_xishengqiyue_info:'令双方各一名随从立即死亡。', - spell_xiaoguibaopo:'小鬼爆破', - spell_xiaoguibaopo_info:'对一名随从造成1~3点伤害,每造成1点伤害,便召唤一只小鬼。', - spell_anyinglieyan:'暗影裂焰', - spell_anyinglieyan_info:'杀死一名友方随从,并对所有敌方随从造成等于其体力值的伤害。', - spell_liliangdaijia:'力量代价', - spell_liliangdaijia_info:'令一名友方随从摸四张牌,将体力值变为5,并在其下个回合结束后死亡。', - spell_emozhinu:'恶魔之怒', - spell_emozhinu_info:'对所有随从造成2点伤害。', - - spell_emozhixin:'恶魔之心', - spell_emozhixin_info:'对一名敌方随从造成4点伤害,或令一名友方随从摸四张牌。', - spell_ansezhadan:'暗色炸弹', - spell_ansezhadan_info:'造成2点伤害。', - spell_fushishu:'腐蚀术', - warlock_fushishu:'腐蚀', - warlock_fushishu_info:'下个回合结束后死亡。', - spell_fushishu_info:'令一名敌方随从于其下个回合结束后死亡。', - spell_heianqiyue:'黑暗契约', - spell_heianqiyue_info:'随机令两名敌方随从死亡,随机弃置两张手牌。', - spell_linghunhongxi:'灵魂虹吸', - spell_linghunhongxi_info:'令一名随从死亡,回复1点体力。', - spell_siwangchanrao:'死亡缠绕', - spell_siwangchanrao_info:'对一名随从造成1点伤害;若该随从死亡,从牌库中获得一张牌。', - - spell_wuyashenxiang:'乌鸦神像', - spell_wuyashenxiang_info:'从三张法术牌或随从牌中选择一张加入手牌。', - spell_huotigenxu:'活体根须', - spell_huotigenxu_info:'造成1点伤害,或召唤两个树苗。', - spell_hengsao:'横扫', - spell_hengsao_info:'对一名敌方角色造成2点伤害,然后对其他敌方角色造成1点伤害。', - spell_yexingchengzhang:'野性成长', - spell_yexingchengzhang_info:'下个出牌阶段开始时获得三点额外行动值。', - spell_ziranzhili:'自然之力', - spell_ziranzhili_info:'召唤三个自爆树人。', - spell_yemanpaoxiao:'野蛮咆哮', - spell_yemanpaoxiao_bg:'咆', - spell_yemanpaoxiao2:'咆哮', - spell_yemanpaoxiao_info:'所有友方角色造成的伤害+1,直到你的下个回合开始。', - - spell_conglinzhihun:'丛林之魂', - druid_conglinzhihun:'树魂', - druid_conglinzhihun_info:'你死亡后召唤一个树人。', - spell_conglinzhihun_info:'令所有友方随从获得技能树魂(你死亡后召唤一个树人)。', - spell_ziyang:'滋养', - spell_ziyang_info:'下个出牌开始阶段获得4点额外行动值,或从牌库中获得三张牌。', - spell_fugen:'腐根', - spell_fugen_info:'令一名随从死亡,将一张随机随从置入对手的手牌。', - spell_xingchenzhuiluo:'星辰坠落', - spell_xingchenzhuiluo_info:'对一名敌方随从造成5点伤害,或对所有敌方随从造成2点伤害。', - spell_fennu:'愤怒', - spell_fennu_info:'对一名随从造成2点伤害,或造成1点伤害并从牌库中获得一张牌。', - spell_heiandiyu:'黑暗低语', - spell_heiandiyu_info:'召唤若干个小精灵直到你的随从数达到4;或令一名随从增加1点体力和体力上限并摸三张牌。', - - druid_yexingchengzhang:'成长', - druid_yexingchengzhang_bg:'长', - druid_yexingchengzhang_info:'下个出牌阶段开始时获得三点额外行动值。', - druid_ziyang:'滋养', - druid_ziyang_bg:'养', - druid_ziyang_info:'下个出牌阶段开始时获得四点额外行动值。', - - stone_shumiao:'树苗', - stone_shuren:'自爆树人', - stone_shurenx:'树人', - stone_shurenxx:'嘲讽树人', - stone_zibao:'自爆', - stone_zibao_info:'结合结束后立即死亡。', - - spell_cigu:'刺骨', - spell_cigu_info:'造成1点伤害,你可以弃置一张装备区内的牌令伤害+1。', - spell_jianrenluanwu:'剑刃乱舞', - spell_jianrenluanwu_info:'弃置你的武器牌,并对所有敌方角色造成1点伤害。', - spell_daoshan:'刀扇', - spell_daoshan_info:'对所有敌方随从造成1点伤害,从牌库中获得一张牌。', - spell_sijidaifa:'伺机待发', - spell_sijidaifa_info:'你使用下一张法术牌时获得X点行动值,X为该法术的行动值消耗且不超过3。', - spell_cisha:'刺杀', - spell_cisha_info:'杀死一名随从。', - spell_modaoyou:'磨刀油', - spell_modaoyou_info:'令你下一次剑刃乱舞造成的伤害+1,并与一名随机友方随从各摸两张牌。', - - spell_mengun:'闷棍', - spell_mengun_info:'令一名敌方随从死亡(不触发死亡技能),将一张该随从的复制置入对手的手牌。', - spell_anzhongpohuai:'暗中破坏', - spell_anzhongpohuai_info:'随机杀死一名敌方随从,随机弃置敌方的一张装备牌。', - spell_beici:'背刺', - spell_beici_info:'令一名未受伤的随从失去1点体力。', - spell_weijisifu:'危机四伏', - spell_zhumo:'蛛魔', - stone_zhumo:'蛛魔', - spell_zhumo_info:'每当该牌被弃置,为你的对手召唤一只蛛魔。', - spell_weijisifu_info:'将三张蛛魔牌洗入对手的牌库;每当一名角色弃置蛛魔牌,为其对手召唤一只蛛魔。', - spell_piaoqie:'剽窃', - spell_piaoqie_info:'复制两张对手牌库中的牌加入你的手牌。', - spell_jipao:'疾跑', - spell_jipao_info:'从牌库中获得四张牌。', - - spell_fengxian:'奉献', - spell_fengxian_info:'对所有敌方角色造成1点伤害。', - spell_fuchouzhinu:'复仇之怒', - spell_fuchouzhinu_info:'造成5点伤害,随机分配到所有敌方随从上。', - spell_shengliaoshu:'圣疗术', - spell_shengliaoshu_info:'恢复2点体力,摸两张牌。', - spell_fennuzhichui:'愤怒之锤', - spell_fennuzhichui_info:'造成1点伤害,从牌库中获得一张牌。', - spell_zuozhandongyuan:'作战动员', - spell_zuozhandongyuan_info:'召唤两个新兵,随机装备一把武器。', - spell_liliangzhufu:'力量祝福', - spell_liliangzhufu_info:'令一名随从摸两张牌。', - - spell_jinyingduijue:'精英对决', - spell_jinyingduijue_info:'双方各保留体力值最高的一名随从,然后令其他随从死亡。', - spell_shenpan:'审判', - spell_shenpan_info:'若你的对手随从数不少于你,则随机令一名敌方随从死亡。', - spell_shenshengfennu:'神圣愤怒', - spell_shenshengfennu_info:'从牌库中获得一张牌,并造成等同于其行动值消耗的伤害。', - spell_yongshizhufu:'勇士祝福', - spell_yongshizhufu_info:'令一名随从的手牌数翻倍。', - spell_zhengqianghaosheng:'争强好胜', - paladin_zhengqianghaosheng:'争强好胜', - paladin_zhengqianghaosheng_info:'在你的下一准备阶段,令所有友方随从增加1点体力和体力上限并摸一张牌。', - spell_zhengqianghaosheng_info:'在你的下一准备阶段,令所有友方随从增加1点体力和体力上限并摸一张牌。', - spell_zhihuizhufu:'智慧祝福', - paladin_zhihuizhufu:'智慧祝福', - spell_zhihuizhufu_info:'选择一名随从,在其每个准备阶段,你从牌库中获得一张牌。', - - spell_fengnu:'风怒', - shaman_fengnu:'风怒', - shaman_fengnu_info:'回合结束后,你获得一个额外回合。', - spell_fengnu_info:'令一名随从获得技能风怒(回合结束后,你获得一个额外回合)。', - spell_rongyanbaolie:'熔岩爆裂', - spell_rongyanbaolie_info:'造成3点火焰伤害,失去1点体力。', - spell_shihuawuqi:'石化武器', - shaman_shihuawuqi:'充能', - shaman_shihuawuqi_info:'准备阶段,你摸三张牌。', - spell_shihuawuqi_info:'令一名友方随从获得技能充能(准备阶段,你摸三张牌),直到你的下一回合开始。', - spell_xianzuzhaohuan:'先祖召唤', - spell_xianzuzhaohuan_info:'双方各将手牌中的一张随机随从牌置入战场。', - spell_xianzuzhihun:'先祖之魂', - shaman_xianzuzhihun:'转生', - shaman_xianzuzhihun_info:'你死亡后,召唤一个自身的复制。', - spell_xianzuzhihun_info:'令一名随从获得技能转生(你死亡后,召唤一个自身的复制)。', - spell_xianzuzhishi:'先祖知识', - shaman_xianzuzhishi:'先祖知识', - shaman_xianzuzhishi_info:'本回合手牌上限-1。', - spell_xianzuzhishi_info:'从牌库中获得两张牌,本回合手牌上限-1(多次使用不叠加)。', - - spell_lianhuanbaolie:'连环爆裂', - spell_lianhuanbaolie_info:'造成1~2点雷电伤害。', - spell_shandianfengbao:'闪电风暴', - spell_shandianfengbao_info:'对所有敌方随从造成1~2点伤害。', - spell_yaoshu:'妖术', - spell_yaoshu_info:'将一个随从变成一只青蛙。', - spell_yexinglanghun:'野性狼魂', - spell_yexinglanghun_info:'召唤两个幽灵狼。', - spell_shixue:'嗜血', - spell_shixue_info:'所有友方随从摸两张牌。', - spell_chazhuangshandian:'叉状闪电', - spell_chazhuangshandian_info:'对两个随机敌方随从各造成1点雷电伤害。', - - stone_qingwa:'青蛙', - stone_youlinglang:'幽灵狼', - stone_jingxiang:'镜像', - stone_jingxiang_info:'锁定技,你跳过摸牌阶段。', - shaman_qingwa:'青蛙', - shaman_qingwa_info:'锁定技,你跳过摸牌阶段。', - stone_xiaojingling:'小精灵', - - spell_laojiuhuoba:'老旧火把', - spell_laojiuhuoba_info:'造成1点伤害,将一张炽热火把置入你的牌库。', - spell_chirehuoba:'炽热火把', - spell_chirehuoba_info:'造成2点火焰伤害。', - spell_canying:'残影', - spell_canying_info:'复制你的所有随从,并将其置入你的手牌。', - spell_yanbaoshu:'炎爆术', - spell_yanbaoshu_info:'造成4点火焰伤害(若目标为主将,伤害不能超过目标的当前体力值)。', - spell_jingxiang:'镜像', - spell_jingxiang_info:'召唤两个具有嘲讽且摸牌阶段不摸牌的随从。', - spell_aoshufeidan:'奥术飞弹', - spell_aoshufeidan_info:'造成3点伤害,随从分配到所有敌方随从上。', - spell_hanbingpingzhang:'寒冰屏障', - mage_hanbingpingzhang:'寒冰屏障', - mage_hanbingpingzhang_info:'体力值不能降到2以内。', - spell_hanbingpingzhang_info:'令一名角色的体力值不能降到2以内,直到你的下一回合开始。', - - spell_hanbingjian:'寒冰箭', - spell_hanbingjian_info:'对一个随从造成2点伤害,然后将其翻面。', - spell_lieyanfengbao:'烈焰风暴', - spell_lieyanfengbao_info:'对所有敌方随从造成2点伤害。', - spell_baofengxue:'暴风雪', - spell_baofengxue_info:'对所有敌方随从造成1点伤害,然后将其翻面。', - spell_aoshuzhihui:'奥术智慧', - spell_aoshuzhihui_info:'从牌库中获得两张牌。', - spell_bianxingshu:'变形术', - spell_bianxingshu_info:'将一个随从变成一只绵羊。', - spell_huoqiushu:'火球术', - spell_huoqiushu_info:'造成3点火焰伤害(若目标为主将,伤害不能超过目标的当前体力值)。', - - stone_mianyang:'绵羊', - mage_mianyang:'绵羊', - mage_mianyang_info:'锁定技,你不能使用杀。', - - stone_beijunmushi:'北郡牧师', - stone_guangyaozhizi:'光耀之子', - stone_longmianjiaoguan:'龙眠教官', - stone_linghunjisi:'灵魂祭司', - stone_guanliyuan:'管理员', - stone_heianjiaotu:'黑暗教徒', - - stone_shengdianzhishi:'圣殿执事', - stone_suoxiaojishi:'缩小技师', - stone_anyingzisi:'暗影子嗣', - stone_guangmingquan:'光明泉', - stone_muguangchulong:'暮光雏龙', - stone_shenshengyongshi:'神圣勇士', - - priest_puzhao:'普照', - priest_puzhao_info:'你出场时,己方主将可令一名其他友方随从增加2点体力和体力上限。', - priest_suoxiao:'缩小', - priest_suoxiao_info:'你出场时,己方主将可令一名其他随从减少2点体力上限(不能小于1)。', - priest_shengshui:'圣水', - priest_shengshui_info:'你跳过摸牌阶段;在你的准备阶段,令一名随机友方角色回复2点体力。', - priest_muguang:'暮光', - priest_muguang_info:'你出场时,若主将手牌中有随从牌,则增加1点体力和体力上限。', - priest_shixin:'蚀心', - priest_shixin_info:'每当己方主将使用一次职业技能,对双方主将各造成1点伤害。', - - priest_shengliao:'圣疗', - priest_shengliao_info:'每当一名随从回复体力,己方主将从牌库中获得一张牌。', - priest_guangyao:'光耀', - priest_guangyao_info:'每当你的体力值发生改变,摸一张牌。', - priest_xundao:'训导', - priest_xundao_info:'你出场时,若己方主将手牌中有随从牌,则摸一张牌并获得嘲讽。', - priest_hunwu:'魂舞', - priest_hunwu_info:'己方主将的职业技能及法术的治疗效果改为令目标失去等量体力。', - priest_faxian:'发现', - priest_faxian_info:'你出场时,己方主将从三张随机随从牌中选择一张加入手牌。', - priest_zhufu:'献身', - priest_zhufu_info:'你死亡时,令一名随机友方随从增加1点体力和体力上限。', - - stone_daomufeizei:'盗墓匪贼', - stone_haidao:'海盗', - stone_haidaotoumu:'海盗头目', - stone_cike:'刺客', - stone_tegong:'特工', - stone_qiezei:'窃贼', - stone_heitieairen:'黑铁矮人', - - stone_duyanhaidao:'独眼海盗', - stone_gangtiewushi:'刚铁武师', - stone_lifaji:'理发机', - stone_shihualong:'石化龙', - stone_xiushuihaidao:'锈水海盗', - stone_zousishangfan:'走私商贩', - - rogue_duxing:'独行', - rogue_duxing_info:'每当敌方主将召唤一名随从,便获得潜行。', - rogue_shoudao:'授道', - rogue_shoudao_info:'在己方主将的结束阶段,令一名随机友方随从增加1点体力和体力上限并摸一张牌。', - rogue_lifa:'理发', - rogue_lifa_info:'为己方主将装备一把武器,若已有武器,改为对敌方主将造成1点伤害。', - rogue_fusheng:'复生', - rogue_fusheng_info:'你出场时,体力值和体力上限变为X,X为场上体力最高的随从的体力值。', - rogue_jielue:'劫掠', - rogue_jielue_info:'每当己方主将装备一把武器牌,摸两张牌。', - rogue_jiaoyi:'交易', - rogue_jiaoyi_info:'你出场时,己方主将可以弃置一张装备牌令你摸三张牌。', - - rogue_touqie:'偷窃', - rogue_touqie_info:'每当你造成一次伤害,己方主将从牌库中获得一张牌。', - rogue_xunbao:'寻宝', - rogue_xunbao_info:'你死亡时,将一张伺机行发置于己方主将的手牌。', - rogue_cisha:'刺杀', - rogue_cisha_info:'每当你对一名随从造成伤害,受伤害随从立即死亡。', - rogue_touxi:'偷袭', - rogue_touxi_info:'你出场时,己方主将可弃置一张装备区内的牌并对一名敌方角色造成1点伤害。', - rogue_qiancang:'潜藏', - rogue_qiancang_info:'你出场时,对所有未受伤害的敌方随从造成1点伤害。', - rogue_zhaomu:'结伙', - rogue_zhaomu_info:'你出场时,召唤一个海盗。', - - stone_zhihuiguan:'指挥官', - stone_jiangong:'监工', - stone_yuanhou:'猿猴', - stone_chidunshinv:'持盾侍女', - stone_zhujiashi:'铸甲师', - stone_kuangzhanshi:'狂战士', - - stone_heiyaoyaoshou:'黑曜妖兽', - stone_honglongyongshi:'红龙勇士', - stone_peilianshi:'陪练师', - stone_jingyingweishi:'精英卫士', - stone_shengjiachong:'圣甲虫', - stone_mengmaren:'猛犸人', - stone_zhifuzhe:'掷斧者', - - warrior_heiyao:'黑曜', - warrior_heiyao_info:'在己方主将的结束阶段,召唤一只圣甲虫。', - warrior_peilian:'陪练', - warrior_peilian_info:'你出场时,己方主将可令一名其他随从获得嘲讽。', - warrior_fenyong:'奋勇', - warrior_fenyong_info:'你出场时,若己方主将手牌中有随从牌,则获得冲锋。', - warrior_chuanci:'穿刺', - warrior_chuanci_info:'每当你对一名敌方随从造成伤害,对另一名随机敌方随从造成等量的伤害。', - warrior_zhifu:'掷斧', - warrior_zhifu_info:'每当你受到一次伤害,对敌方主将造成1点伤害。', - - warrior_tongling:'统领', - warrior_tongling_info:'每当你召唤一个初始手牌数不大于2的随从,令其获得冲锋。', - warrior_baoluan:'暴乱', - warrior_baoluan_info:'每当一名随从受到一次伤害,摸一张牌。', - warrior_jiangong:'监工', - warrior_jiangong_info:'你出场时,己方主将可对一名随从造成1点伤害,然后令该随从摸两张牌。', - warrior_zhujia:'铸甲', - warrior_zhujia_info:'每当你受到一次伤害,己方主将获得1点护甲。', - warrior_tidun:'提盾', - warrior_tidun_info:'你出场时,己方主将获得2点护甲。', - - stone_lieyanxiaogui:'烈焰小鬼', - stone_xiaoguishouling:'小鬼首领', - stone_kongjuzhanma:'恐惧战马', - stone_morishouwei:'末日守卫', - stone_xukongxingzhe:'虚空行者', - stone_diyuhuo:'地狱火', - stone_diyuhuox:'地狱火', - stone_xiaogui:'小鬼', - - stone_heishitanfan:'黑市摊贩', - stone_zhaohuanzhe:'召唤者', - stone_meimo:'魅魔', - stone_tongkunvwang:'痛苦女王', - stone_xukongkongmo:'虚空恐魔', - stone_fukongmoyan:'浮空魔眼', - - warlock_anyu:'暗语', - warlock_anyu_info:'你出场时,己方主将从三张随机的行动值消耗为1的牌中选择一张加入手牌。', - warlock_zhaohuan:'召唤', - warlock_zhaohuan_info:'你死亡时,将手牌中的一张随机随从牌置入战场。', - warlock_huanmeng:'幻梦', - warlock_huanmeng_info:'你出场时,己方主将随机弃置一张手牌。', - warlock_tongku:'痛苦', - warlock_tongku_info:'每当你造成一次伤害,令己方主将回复1点体力。', - warlock_tunshi:'吞噬', - warlock_tunshi_info:'你出场时,己方主将须令一名其他友方随从死亡,然后你获得其全部的手牌和体力值。', - warlock_shijie:'视界', - warlock_shijie_info:'每当己方主将受到一次伤害,你增加1点体力和体力上限并摸一张牌。', - - warlock_nonghuo:'弄火', - warlock_nonghuo_info:'你出场时,对己方主将造成1点火焰伤害。', - warlock_zhaogui:'召鬼', - warlock_zhaogui_info:'每当你受到一次伤害,召唤一个小鬼。', - warlock_yongsheng:'永生', - warlock_yongsheng_info:'你死亡后,召唤一匹恐惧战马。', - warlock_yuhuo:'狱火', - warlock_yuhuo_info:'你出场时,对所有其他随从造成1点伤害。', - warlock_zaihuo:'灾祸', - warlock_zaihuo_info:'你出场时,随机弃置主将的两张手牌。', - - stone_hudunren:'护盾人', - stone_junxuguan:'军需官', - stone_yurenqishi:'鱼人骑士', - stone_chidunweishi:'持盾卫士', - stone_liewangshouwei:'列王守卫', - stone_longwangpeiou:'龙王配偶', - - stone_baoweizhe:'保卫者', - stone_guiqishi:'龟骑士', - stone_shenmiqishou:'神秘骑手', - stone_shixiangweishi:'石像卫士', - stone_xuefanzhanshi:'血帆战士', - stone_xunmashi:'训马师', - - paladin_baowei:'保卫', - paladin_baowei_info:'你出场时,己方主将可令一名其他随从获得1点护甲。', - paladin_tuxi:'吐息', - paladin_tuxi_info:'你出场时,己方主将进行一次判定,若为红色,则回复1点体力。', - paladin_miying:'秘影', - paladin_miying_info:'你出场时,依次将牌堆中的所有不重名的判定牌置入敌方主将的判定区。', - paladin_huashi:'化石', - paladin_huashi_info:'你出场时,己方主将可将一名其他随从的体力值及体力上限变为2。', - paladin_jinghua:'净化', - paladin_jinghua_info:'你出场时,对所有手牌数大于1的随从造成2点伤害。', - paladin_moma:'秣马', - paladin_moma2:'秣马', - paladin_moma_info:'所有友方新兵摸牌阶段摸牌数+1。', - - paladin_zhaohuan:'召唤', - paladin_zhaohuan2:'召唤', - paladin_zhaohuan_info:'你出场后,你的主将在使用下一张随从牌时获得两点行动值。', - paladin_shouwei:'守卫', - paladin_shouwei_info:'你出场时,你的主将回复2点体力值。', - paladin_chidun:'持盾', - paladin_chidun_info:'你出场时,己方主将可以弃置对方一名随从的所有牌。', - paladin_buji:'补给', - paladin_buji_info:'你出场时,所有友方新兵增加1点体力和体力上限并摸两张牌。', - paladin_hudun:'护盾', - paladin_hudun_info:'你出场时,获得1点护甲值。', - paladin_zhaochao:'招潮', - paladin_zhaochao_info:'每当你的主将使用一次英雄技能,便摸两张牌。', - - stone_shifazhe:'嗜法者', - stone_wushixuetu:'巫师学徒', - stone_shuiyuansu:'水元素', - stone_falifulong:'法力浮龙', - stone_yingxiongzhihun:'英雄之魂', - stone_huoyao:'火妖', - - stone_aoshushi:'奥术师', - stone_faqishi:'法骑士', - stone_fuhuokaijia:'复活铠甲', - stone_kaodalalong:'考达拉龙', - stone_yanshushi:'炎术士', - stone_xulingwushi:'虚灵巫师', - - mage_aoshu:'奥术', - mage_aoshu_info:'你出场时,将一张奥术智慧置入主将的手牌。', - mage_jili:'激励', - mage_jili_info:'每当主将使用一次职业技能,摸一张牌。', - mage_gushou:'固守', - mage_gushou_info:'每当己方主将受到多于1伤害时,防止其余伤害。', - mage_yufa:'驭法', - mage_yufa_info:'每当己方主将使用一次职业技能,令其获得1点行动值。', - mage_yanshu:'炎术', - mage_yanshu_info:'你出场时,造成X点火焰伤害,随机分配到敌方随从上,X为己方主将装备区内装备牌的数量。', - mage_pingxu:'冯虚', - mage_pingxu_info:'你出场时,己方主将从三张随机法术牌中选择一张加入手牌。', - - mage_shifa:'嗜法', - mage_shifa_info:'你出场时,将一张随机法术牌置入双方主将的手牌。', - mage_minghuo:'冥火', - mage_minghuo_info:'你的主将的职业技能造成的伤害+1。', - mage_tunfa:'吞法', - mage_tunfa_info:'每当己方主将使用一张法术牌,摸一张牌。', - mage_lieyan:'烈焰', - mage_lieyan_info:'每当己方主将使用一张法术牌,对一名随机敌方角色造成1点火焰伤害。', - mage_zhufa:'助法', - mage_zhufa_info:'每当己方主将使用一张法术牌,令其获得1点行动值。', - mage_bingdong:'冰冻', - mage_bingdong_info:'每当你对一个随从造成伤害,该随从将武将牌翻至背面。', - - stone_caoyuanshi:'草原狮', - stone_leiouke:'雷欧克', - stone_misha:'米莎', - stone_huofu:'霍弗', - stone_jiewangzhu:'结网蛛', - stone_xunshoushi:'驯兽师', - - stone_senlinlang:'森林狼', - stone_tujiu:'秃鹫', - stone_muyangren:'牧羊人', - stone_jujishou:'狙击手', - stone_damoshatuo:'大漠沙驼', - stone_huangjialeixiang:'皇家雷象', - - hunter_jiewang:'结网', - hunter_jiewang_info:'你死亡时,己方主将获得一张随机野兽牌。', - hunter_xunshou:'驯兽', - hunter_xunshou_info:'你出场时,己方主将可选择一名其他友方随从令其增加1点体力和体力上限,摸两张牌并获得嘲讽。', - hunter_nuhou:'怒吼', - hunter_nuhou_info:'当你死亡时,对所有敌方角色造成1点伤害。', - hunter_zhanhuo:'战火', - hunter_zhanhuo2:'战火', - hunter_zhanhuo_info:'其他友方随从摸牌阶段的摸牌数+1。', - - hunter_qunxi:'群袭', - hunter_qunxi_info:'你出场时,所有友方随从摸一张牌。', - hunter_mishi:'觅食', - hunter_mishi_info:'每当己方主将召唤一个随从,摸一张牌。', - hunter_dusha:'渡沙', - hunter_dusha_info:'你出场时,令双方主将各随机使用一张牌库中的1费随从牌(不计入行动值消耗)。', - hunter_chuanlin:'穿林', - hunter_chuanlin_info:'你出场时,己方主将展示牌库中的一张随机随从牌并获得之。', - hunter_muyang:'牧羊', - hunter_muyang_info:'你出场时,随机召唤一个行动值消耗为X的随从,X为其他友方随从数。', - hunter_juji:'狙击', - hunter_juji_info:'你的职业技能可以指定随从为目标。', - - stone_baoqishi:'豹骑士', - stone_conglinshouwei:'从林守卫', - stone_baohuzhishu:'保护之树', - stone_kuangyedoushi:'狂野斗士', - stone_liebao:'猎豹', - stone_zongxiong:'棕熊', - - stone_renyaqishi:'刃牙骑士', - stone_conglinxiaoshou:'丛林枭兽', - stone_huangyeqishi:'荒野骑士', - stone_xunmenglong:'迅猛龙', - stone_lindishuyao:'林地树妖', - stone_huoshanxiemu:'火山邪木', - - druid_renya:'刃牙', - druid_renya_info:'你出场时,己方主将可以选择一项:令你摸一张牌并将武将牌翻至正面,或令你增加1点体力上限并获得技能潜行。', - druid_yuehuo:'月火', - druid_yuehuo_info:'所有锦囊牌造成的伤害+1。', - druid_qicheng:'骑乘', - druid_qicheng_info:'你死亡时,随机召唤一个行动消耗为1的随从。', - druid_chicheng:'驰骋', - druid_chicheng_info:'你出场时,己方主将获得X点行动值,X为其他友方随从数。', - druid_yeyou:'夜游', - druid_yeyou_info:'双方主将各从牌库中获得一张牌。', - druid_juhuo:'举火', - druid_juhuo_info:'己方主将回合内,每有一名随从死亡,令己方主将获得1点行动值。', - - stone_chongfeng:'冲锋', - stone_chongfeng_info:'你出场时,立即将武将牌翻至正面。', - druid_nuhuo:'怒火', - druid_nuhuo_info:'每当己方主将使用一次职业技能,便对一名随机敌人造成1点伤害。', - druid_chengzhang:'成长', - druid_chengzhang2:'成长', - druid_chengzhang_info:'你出场时,己方主将获得1点行动值;你死亡时,己方主将需弃置一张手牌。', - druid_huwei:'护卫', - druid_huwei_info:'你出场时,己方主将可以选择一项:对一名随从造成1点伤害,或弃置一名随从的所有牌并将其体力上限改为2。', - - stone_fachao:'法潮图腾', - stone_tutengyongshi:'图腾勇士', - stone_huoshe:'火舌图腾', - stone_huoyuansu:'火元素', - stone_tuyuansu:'土元素', - stone_wujiyuansu:'无羁元素', - stone_xuejuren:'穴居人', - stone_huoli:'活力图腾', - stone_tutengshi:'图腾师', - stone_shachuisaman:'砂槌萨满', - stone_huoyanweishi:'火焰卫士', - stone_wanshiyuansu:'顽石元素', - stone_shalinxingzhe:'砂鳞行者', - - shaman_anhun:'暗魂', - shaman_anhun_info:'每当一名友方随从死亡,令主将从牌库中获得一张牌。', - shaman_zoushi:'走石', - shaman_zoushi_info:'每当己方主将使用一张随从牌,对一名随机敌方角色造成1点伤害。', - shaman_zhuhuo:'逐火', - shaman_zhuhuo_info:'你出场时,摸1~3张牌。', - shaman_peiyu:'培育', - shaman_peiyu_info:'你出场时,增加X点体力和体力上限,X为友方图腾数。', - shaman_huoli:'活力', - shaman_huoli_info:'己方主将出牌阶段开始时,你令其获得1点行动值。', - shaman_xueju:'穴居', - shaman_xueju_info:'每当己主将使用一张随从牌,摸一张牌。', - shaman_huoxi:'火袭', - shaman_huoxi_info:'你出场时,己方主将可以对对方一名随从造成2点火焰伤害。', - shaman_fachao:'法潮', - shaman_fachao_info:'己方主将在其每个回合结束阶从牌库中获得一张牌并回复1点体力。', - shaman_huoshe:'火舌', - shaman_huoshe_info:'其他友方随从造成的伤害始终+1。', - - shaman_jili:'激励', - shaman_jili_info:'己方主将的结束阶段,所有友方图腾摸一张牌。', - shaman_tuteng:'图腾', - shaman_tuteng_info:'你跳过摸牌阶段。', - shaman_fali:'空气', - shaman_fali_info:'已方主将使用的法术牌伤害+1。', - shaman_zhiliao:'治疗', - shaman_zhiliao_info:'在你的结束阶段,令所有友方随从回复1点体力。', - shaman_zhuore:'灼热', - shaman_zhuore_info:'已方主将的结束阶段,对一名随机敌方随从造成1点伤害。', - - _shaman_skill:'图腾', - _shaman_skill_info:'召唤一个随机图腾。', - _mage_skill:'火冲', - _mage_skill_info:'对一名随从造成1点火焰伤害。', - _priest_skill:'治疗', - _priest_skill_info:'回复1点体力。', - _priest_skillx:'心刺', - _priest_skillx_info:'造成1点伤害。', - _warrior_skill:'战甲', - _warrior_skill_info:'获得1点护甲(不能超过3点)。', - _warlock_skill:'分流', - _warlock_skill_info:'从牌库中获得两张牌。', - _warlock_skillx:'炼狱', - _warlock_skillx_info:'召唤一个地狱火。', - _rogue_skill:'出鞘', - _rogue_skill_info:'装备一把武器和一个随机非武器装备。', - _paladin_skill:'动员', - _paladin_skill_info:'召唤一名士兵。', - _hunter_skill:'射击', - _hunter_skill_info:'对敌方主将造成1点伤害。', - _druid_skill:'猛击', - _druid_skill_info:'视为使用一张不计入出杀次数的杀。', - - stone_tuteng1:'石爪图腾', - stone_tuteng2:'灼热图腾', - stone_tuteng3:'空气图腾', - stone_tuteng4:'治疗图腾', - - stone_xinbing:'新兵', - - stone_zhongshi:'中士', - stone_zhongshi1:'叫嚣', - stone_zhongshi1_info:'你出场时,己方主将可以弃置对方一名随从的所有牌。', - stone_zhucangzhe:'伫藏者', - stone_zhucangzhe1:'伫藏', - stone_zhucangzhe1_info:'你出场时,己方主将可以令己方一名其他角色摸一张牌。', - stone_huoqiangshou:'火枪手', - stone_huoqiangshou1:'火枪', - stone_huoqiangshou1_info:'你出场时,己方主将可以对对方一名随从造成1点伤害。', - - stone_lansaizhanshi:'蓝腮战士', - stone_kutongsiseng:'苦痛侍僧', - stone_kutongsiseng1:'苦痛', - stone_kutongsiseng2:'苦痛', - stone_kutongsiseng1_info:'你出场时,己方主将于本结束阶段摸一张牌。', - stone_yuanguanying:'远古暗影', - stone_yuanguanying1:'暗影', - stone_yuanguanying1_info:'你出场时,己方主将可视为对一名敌方角色使用一张杀。', - - stone_dijieshicong:'低阶侍从', - stone_dijieshicong1:'持枪', - stone_dijieshicong1_info:'你出场时,敌方主将随机弃置一张装备牌。', - stone_yaosaishouwei:'要塞守卫', - stone_yaosaishouwei1:'守卫', - stone_yaosaishouwei1_info:'你出场时,己方主将本回合手牌上限+2。', - stone_famingjia:'发明家', - stone_famingjia1:'发明', - stone_famingjia1_info:'你出场时,己方主将摸两张牌。', - - stone_chilundashi:'齿轮大师', - stone_chilundashi1:'齿轮', - stone_chilundashi2:'齿轮', - stone_chilundashi1_info:'你出场后的第一个摸牌阶段摸牌数+1。', - stone_hanguangzhizhe:'寒光智者', - stone_hanguangzhizhe1:'寒光', - stone_hanguangzhizhe1_info:'你出场时,所有其他随从各摸一张牌。', - stone_aihaozhihun:'哀嚎之魂', - stone_aihaozhihun1:'哀嚎', - stone_aihaozhihun1_info:'你出场时,敌方随从弃置所有牌。', - - stone_fennuxiaoji:'愤怒小鸡', - stone_fennuxiaoji1:'暴怒', - stone_fennuxiaoji1_info:'准备阶段,若你没有手牌,你摸两张牌。', - stone_juxingchanchu:'巨型蟾蜍', - stone_juxingchanchu1:'毒液', - stone_juxingchanchu1_info:'你死亡时,己方主将可令一名敌方随从失去1点体力。', - stone_shishigui:'食尸鬼', - stone_shishigui1:'食尸', - stone_shishigui1_info:'你死亡后,场上所有其他随从失去1点体力。', - stone_wuyi:'巫医', - stone_langren:'狼人', - stone_qianxing:'潜行', - stone_qianxing_info:'你出场时,获得潜行直到下一回合开始。', - - stone_mingguangjisi:'明光祭司', - stone_nianqingjisi:'年轻祭司', - stone_zhufu:'祝福', - stone_zhufu_info:'己方主将的结束阶段,你令一名随机的受伤友方随从回复1点体力。', - stone_aomishouwei:'奥秘守卫', - stone_yanjingshe:'眼镜蛇', - stone_yanjingshe1:'毒噬', - stone_yanjingshe1_info:'你出场时,若敌方随从数不少于己方,则随机杀死一名随从。', - stone_zhiyuzhe:'治愈者', - stone_zhiyu:'治愈', - stone_zhiyu_info:'你出场时,令所有友方随从回复1点体力。', - stone_mafengzhuru:'麻风侏儒', - stone_mafengzhuru1:'麻风', - stone_mafengzhuru1_info:'杀死你的随从失去1点体力。', - stone_fatiaozhuru:'发条侏儒', - stone_fatiaozhuru1:'发条', - stone_fatiaozhuru1_info:'结束阶段,若你没有手牌,你摸两张牌。', - - stonesha:'进攻', - stonesha_info:'锁定技,你的装备牌均视为杀。', - stoneshan:'格挡', - stoneshan_info:'锁定技,你的随从和法术牌均视为闪。', - - stonecharacter:'随从', - spell_shengerpingdeng:'生而平等', - spell_shengerpingdeng_info:'将所有随从体力上限降为1。', - spell_jingshenkongzhi:'精神控制', - spell_jingshenkongzhi_info:'将一名敌方随从吸收为己方。', - spell_anyingkuangluan:'暗影狂乱', - spell_anyingkuangluan_info:'将一名手牌数不超过1的敌方随从吸收为己方,并令其于下个回合结束后死亡。', - spell_anyingkuangluan_die:'暗影狂乱', - spell_anyingkuangluan_die_info:'下个回合结束后死亡。', - spell_binghuan:'冰环', - spell_binghuan_info:'将场上所有随从翻面。', - spell_morizaihuo:'末日灾祸', - spell_morizaihuo_info:'令场上所有随从立即死亡,回复2点体力。', - spell_zhiliaozhichu:'治疗之触', - spell_zhiliaozhichu_info:'令目标随从恢复所有体力值并获得嘲讽。', - lschaofeng:'嘲讽', - lschaofeng_info:'同阵营的无嘲讽角色不以能成为杀的目标。', - spell_wangzhezhufu:'王者祝福', - spell_wangzhezhufu_info:'令一名随从增加2点体力和体力上限并摸两张牌。', - spell_diyulieyan:'地狱烈焰', - spell_diyulieyan_info:'所有角色失去1点体力。', - spell_chenmo:'沉默', - spell_chenmo_info:'弃置一名随从的所有牌,并令其体力上限减至2。', - spell_zhiliaoshui:'治疗水', - spell_zhiliaoshui_info:'出牌阶段对自己使用,恢复2点体力值;或于濒死阶段对一名角色使用,令目标恢复1点体力。', - spell_yanmie:'极恶之咒', - spell_yanmie_info:'交换你与敌方主将的装备区,并摸若干张牌直到你的手牌数与敌方主将相等。', - spell_xiaoshi:'消失', - spell_xiaoshi_info:'令敌方主将将所有装备区内的牌收入手牌,并弃置其若干张手牌,直到其手牌数与你相等。', - - stonecard:'法术', - mode_stone_card_config:'炉石模式', - mode_stone_character_config:'炉石模式', + translate: { + shaman: "萨满", + mage: "法师", + priest: "牧师", + warrior: "战士", + warlock: "术士", + knight: "死亡骑士", + rogue: "潜行者", + paladin: "圣骑士", + hunter: "猎人", + druid: "德鲁伊", + + stone_siwangzhiyi: "死亡之翼", + stone_alaikesita: "阿莱克萨", + stone_yisela: "伊瑟拉", + stone_nuoziduomu: "诺兹多姆", + stone_maligousi: "玛里苟斯", + stone_aolajier: "奥拉基尔", + stone_andongni: "安东尼", + stone_jialakesi: "加拉克斯", + stone_jialakesix: "加拉克斯", + stone_kelushi: "克鲁什", + stone_geluomashi: "格罗玛什", + stone_aidewen: "艾德温", + stone_sainaliusi: "塞纳留斯", + stone_fuding: "弗丁", + stone_weilun: "维纶", + + stone_fushi: "缚誓", + stone_fushi_info: "你出场时,为所有友方角色回复所有体力值。", + stone_mieshi: "灭世", + stone_mieshi_info: "你出场时,对所有其他随从造成2点伤害,然后弃置己方主将的所有手牌。", + stone_shixu: "时序", + stone_shixu_info: "你出场的回合内,己方主将获得4点行动值。", + stone_chenshui: "沉睡", + stone_chenshui_info: "在你的结束阶段,令己方主将获得一张梦境牌。", + stone_mowang: "魔网", + stone_mowang_info: "己方法术对主将伤害+2,对随从伤害+4。", + + stone_zhiyin: "指引", + stone_zhiyin_info: "每当己方主将使用一张法术牌,将一张火球术置于其手牌。", + stone_bianshen: "变身", + stone_bianshen_info: + "你出场时,若己方主将职业为术士,则代之成为新的主将;若己变身,则改为令你召唤的地狱火的初始手牌数和体力值+1。", + stone_lianyu: "炼狱", + stone_lianyu_info: "你的职业技能改为召唤一个地狱火。", + stone_lianji: "连击", + stone_lianji_info: "每当己方主将召唤一个随从,便增加1点体力和体力上限并摸一张牌。", + stone_shenyu: "神谕", + stone_shenyu_info: + "你出场时,己方主将可以选择一项:召唤两个嘲讽树人,或令所有其他随从增加1点体力和体力上限并摸两张牌。", + stone_fuchou: "复仇", + stone_fuchou_info: "你死亡后,视为己方主将使用了一张复仇之怒。", + stone_shenyou: "神佑", + stone_shenyou_info: "己方主将的职业技能和法术的治疗效果翻倍。", + stone_jinu: "激怒", + stone_jinu_info: "摸牌阶段,若你己受伤,则额外摸两张牌。", + + spell_shenshengxinxing: "神圣新星", + spell_shenshengxinxing_info: "对所有敌方角色造成1点伤害,令所有友方角色回复1点体力。", + spell_shengguangzhadan: "圣光炸弹", + spell_shengguangzhadan_info: "对所有随从造成等同于其手牌数的伤害。", + spell_maizang: "埋葬", + spell_maizang_info: + "令一名敌方随从死亡(不触发死亡技能),并将一张与该随从同名的随从洗入你的牌库。", + spell_xinlingshijie: "心灵视界", + spell_xinlingshijie_info: "将一张敌方主将手牌的复制置于你的手牌。", + spell_naluzhiguang: "纳鲁之光", + spell_naluzhiguang_info: "恢复1点体力值,若目标仍处于受伤状态,则召唤一名圣光护卫。", + spell_zhiliaozhihuan: "治疗之环", + spell_zhiliaozhihuan_info: "令所有随从回复3点体力。", + + spell_zhenyanshu: "真言术", + spell_zhenyanshu_info: "令一名随从增加1点体力和体力上限;从牌库中获得一张牌。", + spell_enzeshu: "恩泽术", + spell_enzeshu_info: "令一名随从增加3点体力和体力上限。", + spell_anyingxingtai: "暗影形态", + priest_anyingxingtai: "暗影形态", + spell_anyingxingtai_info: "你的职业技能改为造成1点伤害,若已进入暗影形态,则改为造成2点伤害。", + spell_kuaisuzhiliao: "快速治疗", + spell_kuaisuzhiliao_info: "回复2点体力。", + spell_xinlinghanbao: "心灵撼爆", + spell_xinlinghanbao_info: "对敌方主将造成2点伤害。", + spell_kongxinshu: "控心术", + spell_kongxinshu_info: "复制敌方牌库中的一张随从,将其置入战场。", + + stone_shengguanghuwei: "圣光护卫", + priest_shengguang: "圣光", + priest_shengguang_info: "每当一名随从获得治疗,摸一张牌。", + + spell_nuxi: "怒袭", + spell_nuxi_info: "造成1点伤害,获得2点护甲。", + spell_dunpaimengji: "盾牌猛击", + spell_dunpaimengji_info: "对一名随从造成等同于你护甲值的伤害。", + spell_zhansha: "斩杀", + spell_zhansha_info: "令一名已受伤的敌方随从死亡。", + spell_nuhuozhongshao: "怒火中烧", + spell_nuhuozhongshao_info: "对一名随从造成1点伤害,然后令其摸两张牌。", + spell_xuanfengzhan: "旋风斩", + spell_xuanfengzhan_info: "对所有随从造成1点伤害。", + spell_juemingluandou: "绝命乱斗", + spell_juemingluandou_info: "随机保留一名随从,然后令所有其他随从死亡。", + + spell_zhongnian: "重碾", + spell_zhongnian_info: "造成X点伤害,X为已受伤的友方角色数且不超过3。", + spell_zhandounuhuo: "战斗怒火", + spell_zhandounuhuo_info: "从牌库中获得X张牌,X为已受伤的友方角色数。", + spell_chongfeng: "冲锋", + spell_chongfeng_info: "令一名武将牌背面朝上的友方随从摸三张牌,然后将武将牌翻至正面。", + spell_fuchoudaji: "复仇打击", + spell_fuchoudaji_info: "对所有随从造成1点伤害,若你的体力值不大于2,改为造成3点伤害。", + spell_kuangbao: "狂暴", + spell_kuangbao_info: "令一名已受伤的友方随从摸四张牌。", + spell_yingyongdaji: "英勇打击", + spell_yingyongdaji_info: "令一名敌方角色对你造成2点伤害,然后对其造成2点伤害。", + + spell_dubiao: "毒镖", + spell_dubiao_info: "对一名随机敌方角色造成1点伤害。", + spell_qiangfengsheji: "强风射击", + spell_qiangfengsheji_info: "对两名敌方随从各造成1点伤害,并弃置其两张手牌。", + spell_tanxianmao: "探险帽", + hunter_tanxianmao: "探险帽", + hunter_tanxianmao_info: "你死亡时,将一张探险帽置入主将的手牌。", + spell_tanxianmao_info: + "令一名友方随从增加1点体力和体力上限并摸一张牌,当该随从死亡时,将一张探险帽置入你的手牌。", + spell_shalumingling: "杀戮命令", + spell_shalumingling_info: "造成1点伤害,如果你控制任何野兽,则改为造成2点伤害。", + spell_zhuizongshu: "追踪术", + spell_zhuizongshu_info: "从牌库中随机选择三张牌,获得其中的一张。", + spell_tianjiangzhuqun: "天降蛛群", + spell_tianjiangzhuqun_info: "召唤三只结网蛛。", + + spell_lierenyinji: "猎人印记", + spell_lierenyinji_info: "将一名随从的体力上限降至1。", + spell_kuaisusheji: "快速射击", + spell_kuaisusheji_info: "造成1点伤害,摸一张牌。", + spell_guanmenfanggou: "关门放狗", + spell_guanmenfanggou_info: "每有一名敌方随从,便召唤一只猎狗。", + spell_zhaohuanchongwu: "动物伙伴", + spell_zhaohuanchongwu_info: "随机召唤一只野兽。", + spell_zidanshangtang: "子弹上膛", + spell_zidanshangtang_info: "随机获得一张猎人职业法术牌,并获得技能〖上膛〗直到回合结束。", + spell_duochongsheji: "多重射击", + spell_duochongsheji_info: "对两名随机敌方随从各造成2点伤害。", + + stone_liegou: "猎狗", + hunter_zidanshangtang: "上膛", + hunter_zidanshangtang_bg: "膛", + hunter_zidanshangtang_info: "每当你使用一张法术牌,便随机获得一张猎人职业法术牌。", + + spell_zuzhou: "诅咒", + spell_zuzhou_info: "将目标随从翻面,摸一张牌。", + spell_xishengqiyue: "牺牲契约", + spell_xishengqiyue_info: "令双方各一名随从立即死亡。", + spell_xiaoguibaopo: "小鬼爆破", + spell_xiaoguibaopo_info: "对一名随从造成1~3点伤害,每造成1点伤害,便召唤一只小鬼。", + spell_anyinglieyan: "暗影裂焰", + spell_anyinglieyan_info: "杀死一名友方随从,并对所有敌方随从造成等于其体力值的伤害。", + spell_liliangdaijia: "力量代价", + spell_liliangdaijia_info: "令一名友方随从摸四张牌,将体力值变为5,并在其下个回合结束后死亡。", + spell_emozhinu: "恶魔之怒", + spell_emozhinu_info: "对所有随从造成2点伤害。", + + spell_emozhixin: "恶魔之心", + spell_emozhixin_info: "对一名敌方随从造成4点伤害,或令一名友方随从摸四张牌。", + spell_ansezhadan: "暗色炸弹", + spell_ansezhadan_info: "造成2点伤害。", + spell_fushishu: "腐蚀术", + warlock_fushishu: "腐蚀", + warlock_fushishu_info: "下个回合结束后死亡。", + spell_fushishu_info: "令一名敌方随从于其下个回合结束后死亡。", + spell_heianqiyue: "黑暗契约", + spell_heianqiyue_info: "随机令两名敌方随从死亡,随机弃置两张手牌。", + spell_linghunhongxi: "灵魂虹吸", + spell_linghunhongxi_info: "令一名随从死亡,回复1点体力。", + spell_siwangchanrao: "死亡缠绕", + spell_siwangchanrao_info: "对一名随从造成1点伤害;若该随从死亡,从牌库中获得一张牌。", + + spell_wuyashenxiang: "乌鸦神像", + spell_wuyashenxiang_info: "从三张法术牌或随从牌中选择一张加入手牌。", + spell_huotigenxu: "活体根须", + spell_huotigenxu_info: "造成1点伤害,或召唤两个树苗。", + spell_hengsao: "横扫", + spell_hengsao_info: "对一名敌方角色造成2点伤害,然后对其他敌方角色造成1点伤害。", + spell_yexingchengzhang: "野性成长", + spell_yexingchengzhang_info: "下个出牌阶段开始时获得三点额外行动值。", + spell_ziranzhili: "自然之力", + spell_ziranzhili_info: "召唤三个自爆树人。", + spell_yemanpaoxiao: "野蛮咆哮", + spell_yemanpaoxiao_bg: "咆", + spell_yemanpaoxiao2: "咆哮", + spell_yemanpaoxiao_info: "所有友方角色造成的伤害+1,直到你的下个回合开始。", + + spell_conglinzhihun: "丛林之魂", + druid_conglinzhihun: "树魂", + druid_conglinzhihun_info: "你死亡后召唤一个树人。", + spell_conglinzhihun_info: "令所有友方随从获得技能树魂(你死亡后召唤一个树人)。", + spell_ziyang: "滋养", + spell_ziyang_info: "下个出牌开始阶段获得4点额外行动值,或从牌库中获得三张牌。", + spell_fugen: "腐根", + spell_fugen_info: "令一名随从死亡,将一张随机随从置入对手的手牌。", + spell_xingchenzhuiluo: "星辰坠落", + spell_xingchenzhuiluo_info: "对一名敌方随从造成5点伤害,或对所有敌方随从造成2点伤害。", + spell_fennu: "愤怒", + spell_fennu_info: "对一名随从造成2点伤害,或造成1点伤害并从牌库中获得一张牌。", + spell_heiandiyu: "黑暗低语", + spell_heiandiyu_info: + "召唤若干个小精灵直到你的随从数达到4;或令一名随从增加1点体力和体力上限并摸三张牌。", + + druid_yexingchengzhang: "成长", + druid_yexingchengzhang_bg: "长", + druid_yexingchengzhang_info: "下个出牌阶段开始时获得三点额外行动值。", + druid_ziyang: "滋养", + druid_ziyang_bg: "养", + druid_ziyang_info: "下个出牌阶段开始时获得四点额外行动值。", + + stone_shumiao: "树苗", + stone_shuren: "自爆树人", + stone_shurenx: "树人", + stone_shurenxx: "嘲讽树人", + stone_zibao: "自爆", + stone_zibao_info: "结合结束后立即死亡。", + + spell_cigu: "刺骨", + spell_cigu_info: "造成1点伤害,你可以弃置一张装备区内的牌令伤害+1。", + spell_jianrenluanwu: "剑刃乱舞", + spell_jianrenluanwu_info: "弃置你的武器牌,并对所有敌方角色造成1点伤害。", + spell_daoshan: "刀扇", + spell_daoshan_info: "对所有敌方随从造成1点伤害,从牌库中获得一张牌。", + spell_sijidaifa: "伺机待发", + spell_sijidaifa_info: "你使用下一张法术牌时获得X点行动值,X为该法术的行动值消耗且不超过3。", + spell_cisha: "刺杀", + spell_cisha_info: "杀死一名随从。", + spell_modaoyou: "磨刀油", + spell_modaoyou_info: "令你下一次剑刃乱舞造成的伤害+1,并与一名随机友方随从各摸两张牌。", + + spell_mengun: "闷棍", + spell_mengun_info: "令一名敌方随从死亡(不触发死亡技能),将一张该随从的复制置入对手的手牌。", + spell_anzhongpohuai: "暗中破坏", + spell_anzhongpohuai_info: "随机杀死一名敌方随从,随机弃置敌方的一张装备牌。", + spell_beici: "背刺", + spell_beici_info: "令一名未受伤的随从失去1点体力。", + spell_weijisifu: "危机四伏", + spell_zhumo: "蛛魔", + stone_zhumo: "蛛魔", + spell_zhumo_info: "每当该牌被弃置,为你的对手召唤一只蛛魔。", + spell_weijisifu_info: + "将三张蛛魔牌洗入对手的牌库;每当一名角色弃置蛛魔牌,为其对手召唤一只蛛魔。", + spell_piaoqie: "剽窃", + spell_piaoqie_info: "复制两张对手牌库中的牌加入你的手牌。", + spell_jipao: "疾跑", + spell_jipao_info: "从牌库中获得四张牌。", + + spell_fengxian: "奉献", + spell_fengxian_info: "对所有敌方角色造成1点伤害。", + spell_fuchouzhinu: "复仇之怒", + spell_fuchouzhinu_info: "造成5点伤害,随机分配到所有敌方随从上。", + spell_shengliaoshu: "圣疗术", + spell_shengliaoshu_info: "恢复2点体力,摸两张牌。", + spell_fennuzhichui: "愤怒之锤", + spell_fennuzhichui_info: "造成1点伤害,从牌库中获得一张牌。", + spell_zuozhandongyuan: "作战动员", + spell_zuozhandongyuan_info: "召唤两个新兵,随机装备一把武器。", + spell_liliangzhufu: "力量祝福", + spell_liliangzhufu_info: "令一名随从摸两张牌。", + + spell_jinyingduijue: "精英对决", + spell_jinyingduijue_info: "双方各保留体力值最高的一名随从,然后令其他随从死亡。", + spell_shenpan: "审判", + spell_shenpan_info: "若你的对手随从数不少于你,则随机令一名敌方随从死亡。", + spell_shenshengfennu: "神圣愤怒", + spell_shenshengfennu_info: "从牌库中获得一张牌,并造成等同于其行动值消耗的伤害。", + spell_yongshizhufu: "勇士祝福", + spell_yongshizhufu_info: "令一名随从的手牌数翻倍。", + spell_zhengqianghaosheng: "争强好胜", + paladin_zhengqianghaosheng: "争强好胜", + paladin_zhengqianghaosheng_info: + "在你的下一准备阶段,令所有友方随从增加1点体力和体力上限并摸一张牌。", + spell_zhengqianghaosheng_info: + "在你的下一准备阶段,令所有友方随从增加1点体力和体力上限并摸一张牌。", + spell_zhihuizhufu: "智慧祝福", + paladin_zhihuizhufu: "智慧祝福", + spell_zhihuizhufu_info: "选择一名随从,在其每个准备阶段,你从牌库中获得一张牌。", + + spell_fengnu: "风怒", + shaman_fengnu: "风怒", + shaman_fengnu_info: "回合结束后,你获得一个额外回合。", + spell_fengnu_info: "令一名随从获得技能风怒(回合结束后,你获得一个额外回合)。", + spell_rongyanbaolie: "熔岩爆裂", + spell_rongyanbaolie_info: "造成3点火焰伤害,失去1点体力。", + spell_shihuawuqi: "石化武器", + shaman_shihuawuqi: "充能", + shaman_shihuawuqi_info: "准备阶段,你摸三张牌。", + spell_shihuawuqi_info: + "令一名友方随从获得技能充能(准备阶段,你摸三张牌),直到你的下一回合开始。", + spell_xianzuzhaohuan: "先祖召唤", + spell_xianzuzhaohuan_info: "双方各将手牌中的一张随机随从牌置入战场。", + spell_xianzuzhihun: "先祖之魂", + shaman_xianzuzhihun: "转生", + shaman_xianzuzhihun_info: "你死亡后,召唤一个自身的复制。", + spell_xianzuzhihun_info: "令一名随从获得技能转生(你死亡后,召唤一个自身的复制)。", + spell_xianzuzhishi: "先祖知识", + shaman_xianzuzhishi: "先祖知识", + shaman_xianzuzhishi_info: "本回合手牌上限-1。", + spell_xianzuzhishi_info: "从牌库中获得两张牌,本回合手牌上限-1(多次使用不叠加)。", + + spell_lianhuanbaolie: "连环爆裂", + spell_lianhuanbaolie_info: "造成1~2点雷电伤害。", + spell_shandianfengbao: "闪电风暴", + spell_shandianfengbao_info: "对所有敌方随从造成1~2点伤害。", + spell_yaoshu: "妖术", + spell_yaoshu_info: "将一个随从变成一只青蛙。", + spell_yexinglanghun: "野性狼魂", + spell_yexinglanghun_info: "召唤两个幽灵狼。", + spell_shixue: "嗜血", + spell_shixue_info: "所有友方随从摸两张牌。", + spell_chazhuangshandian: "叉状闪电", + spell_chazhuangshandian_info: "对两个随机敌方随从各造成1点雷电伤害。", + + stone_qingwa: "青蛙", + stone_youlinglang: "幽灵狼", + stone_jingxiang: "镜像", + stone_jingxiang_info: "锁定技,你跳过摸牌阶段。", + shaman_qingwa: "青蛙", + shaman_qingwa_info: "锁定技,你跳过摸牌阶段。", + stone_xiaojingling: "小精灵", + + spell_laojiuhuoba: "老旧火把", + spell_laojiuhuoba_info: "造成1点伤害,将一张炽热火把置入你的牌库。", + spell_chirehuoba: "炽热火把", + spell_chirehuoba_info: "造成2点火焰伤害。", + spell_canying: "残影", + spell_canying_info: "复制你的所有随从,并将其置入你的手牌。", + spell_yanbaoshu: "炎爆术", + spell_yanbaoshu_info: "造成4点火焰伤害(若目标为主将,伤害不能超过目标的当前体力值)。", + spell_jingxiang: "镜像", + spell_jingxiang_info: "召唤两个具有嘲讽且摸牌阶段不摸牌的随从。", + spell_aoshufeidan: "奥术飞弹", + spell_aoshufeidan_info: "造成3点伤害,随从分配到所有敌方随从上。", + spell_hanbingpingzhang: "寒冰屏障", + mage_hanbingpingzhang: "寒冰屏障", + mage_hanbingpingzhang_info: "体力值不能降到2以内。", + spell_hanbingpingzhang_info: "令一名角色的体力值不能降到2以内,直到你的下一回合开始。", + + spell_hanbingjian: "寒冰箭", + spell_hanbingjian_info: "对一个随从造成2点伤害,然后将其翻面。", + spell_lieyanfengbao: "烈焰风暴", + spell_lieyanfengbao_info: "对所有敌方随从造成2点伤害。", + spell_baofengxue: "暴风雪", + spell_baofengxue_info: "对所有敌方随从造成1点伤害,然后将其翻面。", + spell_aoshuzhihui: "奥术智慧", + spell_aoshuzhihui_info: "从牌库中获得两张牌。", + spell_bianxingshu: "变形术", + spell_bianxingshu_info: "将一个随从变成一只绵羊。", + spell_huoqiushu: "火球术", + spell_huoqiushu_info: "造成3点火焰伤害(若目标为主将,伤害不能超过目标的当前体力值)。", + + stone_mianyang: "绵羊", + mage_mianyang: "绵羊", + mage_mianyang_info: "锁定技,你不能使用杀。", + + stone_beijunmushi: "北郡牧师", + stone_guangyaozhizi: "光耀之子", + stone_longmianjiaoguan: "龙眠教官", + stone_linghunjisi: "灵魂祭司", + stone_guanliyuan: "管理员", + stone_heianjiaotu: "黑暗教徒", + + stone_shengdianzhishi: "圣殿执事", + stone_suoxiaojishi: "缩小技师", + stone_anyingzisi: "暗影子嗣", + stone_guangmingquan: "光明泉", + stone_muguangchulong: "暮光雏龙", + stone_shenshengyongshi: "神圣勇士", + + priest_puzhao: "普照", + priest_puzhao_info: "你出场时,己方主将可令一名其他友方随从增加2点体力和体力上限。", + priest_suoxiao: "缩小", + priest_suoxiao_info: "你出场时,己方主将可令一名其他随从减少2点体力上限(不能小于1)。", + priest_shengshui: "圣水", + priest_shengshui_info: "你跳过摸牌阶段;在你的准备阶段,令一名随机友方角色回复2点体力。", + priest_muguang: "暮光", + priest_muguang_info: "你出场时,若主将手牌中有随从牌,则增加1点体力和体力上限。", + priest_shixin: "蚀心", + priest_shixin_info: "每当己方主将使用一次职业技能,对双方主将各造成1点伤害。", + + priest_shengliao: "圣疗", + priest_shengliao_info: "每当一名随从回复体力,己方主将从牌库中获得一张牌。", + priest_guangyao: "光耀", + priest_guangyao_info: "每当你的体力值发生改变,摸一张牌。", + priest_xundao: "训导", + priest_xundao_info: "你出场时,若己方主将手牌中有随从牌,则摸一张牌并获得嘲讽。", + priest_hunwu: "魂舞", + priest_hunwu_info: "己方主将的职业技能及法术的治疗效果改为令目标失去等量体力。", + priest_faxian: "发现", + priest_faxian_info: "你出场时,己方主将从三张随机随从牌中选择一张加入手牌。", + priest_zhufu: "献身", + priest_zhufu_info: "你死亡时,令一名随机友方随从增加1点体力和体力上限。", + + stone_daomufeizei: "盗墓匪贼", + stone_haidao: "海盗", + stone_haidaotoumu: "海盗头目", + stone_cike: "刺客", + stone_tegong: "特工", + stone_qiezei: "窃贼", + stone_heitieairen: "黑铁矮人", + + stone_duyanhaidao: "独眼海盗", + stone_gangtiewushi: "刚铁武师", + stone_lifaji: "理发机", + stone_shihualong: "石化龙", + stone_xiushuihaidao: "锈水海盗", + stone_zousishangfan: "走私商贩", + + rogue_duxing: "独行", + rogue_duxing_info: "每当敌方主将召唤一名随从,便获得潜行。", + rogue_shoudao: "授道", + rogue_shoudao_info: "在己方主将的结束阶段,令一名随机友方随从增加1点体力和体力上限并摸一张牌。", + rogue_lifa: "理发", + rogue_lifa_info: "为己方主将装备一把武器,若已有武器,改为对敌方主将造成1点伤害。", + rogue_fusheng: "复生", + rogue_fusheng_info: "你出场时,体力值和体力上限变为X,X为场上体力最高的随从的体力值。", + rogue_jielue: "劫掠", + rogue_jielue_info: "每当己方主将装备一把武器牌,摸两张牌。", + rogue_jiaoyi: "交易", + rogue_jiaoyi_info: "你出场时,己方主将可以弃置一张装备牌令你摸三张牌。", + + rogue_touqie: "偷窃", + rogue_touqie_info: "每当你造成一次伤害,己方主将从牌库中获得一张牌。", + rogue_xunbao: "寻宝", + rogue_xunbao_info: "你死亡时,将一张伺机行发置于己方主将的手牌。", + rogue_cisha: "刺杀", + rogue_cisha_info: "每当你对一名随从造成伤害,受伤害随从立即死亡。", + rogue_touxi: "偷袭", + rogue_touxi_info: "你出场时,己方主将可弃置一张装备区内的牌并对一名敌方角色造成1点伤害。", + rogue_qiancang: "潜藏", + rogue_qiancang_info: "你出场时,对所有未受伤害的敌方随从造成1点伤害。", + rogue_zhaomu: "结伙", + rogue_zhaomu_info: "你出场时,召唤一个海盗。", + + stone_zhihuiguan: "指挥官", + stone_jiangong: "监工", + stone_yuanhou: "猿猴", + stone_chidunshinv: "持盾侍女", + stone_zhujiashi: "铸甲师", + stone_kuangzhanshi: "狂战士", + + stone_heiyaoyaoshou: "黑曜妖兽", + stone_honglongyongshi: "红龙勇士", + stone_peilianshi: "陪练师", + stone_jingyingweishi: "精英卫士", + stone_shengjiachong: "圣甲虫", + stone_mengmaren: "猛犸人", + stone_zhifuzhe: "掷斧者", + + warrior_heiyao: "黑曜", + warrior_heiyao_info: "在己方主将的结束阶段,召唤一只圣甲虫。", + warrior_peilian: "陪练", + warrior_peilian_info: "你出场时,己方主将可令一名其他随从获得嘲讽。", + warrior_fenyong: "奋勇", + warrior_fenyong_info: "你出场时,若己方主将手牌中有随从牌,则获得冲锋。", + warrior_chuanci: "穿刺", + warrior_chuanci_info: "每当你对一名敌方随从造成伤害,对另一名随机敌方随从造成等量的伤害。", + warrior_zhifu: "掷斧", + warrior_zhifu_info: "每当你受到一次伤害,对敌方主将造成1点伤害。", + + warrior_tongling: "统领", + warrior_tongling_info: "每当你召唤一个初始手牌数不大于2的随从,令其获得冲锋。", + warrior_baoluan: "暴乱", + warrior_baoluan_info: "每当一名随从受到一次伤害,摸一张牌。", + warrior_jiangong: "监工", + warrior_jiangong_info: "你出场时,己方主将可对一名随从造成1点伤害,然后令该随从摸两张牌。", + warrior_zhujia: "铸甲", + warrior_zhujia_info: "每当你受到一次伤害,己方主将获得1点护甲。", + warrior_tidun: "提盾", + warrior_tidun_info: "你出场时,己方主将获得2点护甲。", + + stone_lieyanxiaogui: "烈焰小鬼", + stone_xiaoguishouling: "小鬼首领", + stone_kongjuzhanma: "恐惧战马", + stone_morishouwei: "末日守卫", + stone_xukongxingzhe: "虚空行者", + stone_diyuhuo: "地狱火", + stone_diyuhuox: "地狱火", + stone_xiaogui: "小鬼", + + stone_heishitanfan: "黑市摊贩", + stone_zhaohuanzhe: "召唤者", + stone_meimo: "魅魔", + stone_tongkunvwang: "痛苦女王", + stone_xukongkongmo: "虚空恐魔", + stone_fukongmoyan: "浮空魔眼", + + warlock_anyu: "暗语", + warlock_anyu_info: "你出场时,己方主将从三张随机的行动值消耗为1的牌中选择一张加入手牌。", + warlock_zhaohuan: "召唤", + warlock_zhaohuan_info: "你死亡时,将手牌中的一张随机随从牌置入战场。", + warlock_huanmeng: "幻梦", + warlock_huanmeng_info: "你出场时,己方主将随机弃置一张手牌。", + warlock_tongku: "痛苦", + warlock_tongku_info: "每当你造成一次伤害,令己方主将回复1点体力。", + warlock_tunshi: "吞噬", + warlock_tunshi_info: + "你出场时,己方主将须令一名其他友方随从死亡,然后你获得其全部的手牌和体力值。", + warlock_shijie: "视界", + warlock_shijie_info: "每当己方主将受到一次伤害,你增加1点体力和体力上限并摸一张牌。", + + warlock_nonghuo: "弄火", + warlock_nonghuo_info: "你出场时,对己方主将造成1点火焰伤害。", + warlock_zhaogui: "召鬼", + warlock_zhaogui_info: "每当你受到一次伤害,召唤一个小鬼。", + warlock_yongsheng: "永生", + warlock_yongsheng_info: "你死亡后,召唤一匹恐惧战马。", + warlock_yuhuo: "狱火", + warlock_yuhuo_info: "你出场时,对所有其他随从造成1点伤害。", + warlock_zaihuo: "灾祸", + warlock_zaihuo_info: "你出场时,随机弃置主将的两张手牌。", + + stone_hudunren: "护盾人", + stone_junxuguan: "军需官", + stone_yurenqishi: "鱼人骑士", + stone_chidunweishi: "持盾卫士", + stone_liewangshouwei: "列王守卫", + stone_longwangpeiou: "龙王配偶", + + stone_baoweizhe: "保卫者", + stone_guiqishi: "龟骑士", + stone_shenmiqishou: "神秘骑手", + stone_shixiangweishi: "石像卫士", + stone_xuefanzhanshi: "血帆战士", + stone_xunmashi: "训马师", + + paladin_baowei: "保卫", + paladin_baowei_info: "你出场时,己方主将可令一名其他随从获得1点护甲。", + paladin_tuxi: "吐息", + paladin_tuxi_info: "你出场时,己方主将进行一次判定,若为红色,则回复1点体力。", + paladin_miying: "秘影", + paladin_miying_info: "你出场时,依次将牌堆中的所有不重名的判定牌置入敌方主将的判定区。", + paladin_huashi: "化石", + paladin_huashi_info: "你出场时,己方主将可将一名其他随从的体力值及体力上限变为2。", + paladin_jinghua: "净化", + paladin_jinghua_info: "你出场时,对所有手牌数大于1的随从造成2点伤害。", + paladin_moma: "秣马", + paladin_moma2: "秣马", + paladin_moma_info: "所有友方新兵摸牌阶段摸牌数+1。", + + paladin_zhaohuan: "召唤", + paladin_zhaohuan2: "召唤", + paladin_zhaohuan_info: "你出场后,你的主将在使用下一张随从牌时获得两点行动值。", + paladin_shouwei: "守卫", + paladin_shouwei_info: "你出场时,你的主将回复2点体力值。", + paladin_chidun: "持盾", + paladin_chidun_info: "你出场时,己方主将可以弃置对方一名随从的所有牌。", + paladin_buji: "补给", + paladin_buji_info: "你出场时,所有友方新兵增加1点体力和体力上限并摸两张牌。", + paladin_hudun: "护盾", + paladin_hudun_info: "你出场时,获得1点护甲值。", + paladin_zhaochao: "招潮", + paladin_zhaochao_info: "每当你的主将使用一次英雄技能,便摸两张牌。", + + stone_shifazhe: "嗜法者", + stone_wushixuetu: "巫师学徒", + stone_shuiyuansu: "水元素", + stone_falifulong: "法力浮龙", + stone_yingxiongzhihun: "英雄之魂", + stone_huoyao: "火妖", + + stone_aoshushi: "奥术师", + stone_faqishi: "法骑士", + stone_fuhuokaijia: "复活铠甲", + stone_kaodalalong: "考达拉龙", + stone_yanshushi: "炎术士", + stone_xulingwushi: "虚灵巫师", + + mage_aoshu: "奥术", + mage_aoshu_info: "你出场时,将一张奥术智慧置入主将的手牌。", + mage_jili: "激励", + mage_jili_info: "每当主将使用一次职业技能,摸一张牌。", + mage_gushou: "固守", + mage_gushou_info: "每当己方主将受到多于1伤害时,防止其余伤害。", + mage_yufa: "驭法", + mage_yufa_info: "每当己方主将使用一次职业技能,令其获得1点行动值。", + mage_yanshu: "炎术", + mage_yanshu_info: + "你出场时,造成X点火焰伤害,随机分配到敌方随从上,X为己方主将装备区内装备牌的数量。", + mage_pingxu: "冯虚", + mage_pingxu_info: "你出场时,己方主将从三张随机法术牌中选择一张加入手牌。", + + mage_shifa: "嗜法", + mage_shifa_info: "你出场时,将一张随机法术牌置入双方主将的手牌。", + mage_minghuo: "冥火", + mage_minghuo_info: "你的主将的职业技能造成的伤害+1。", + mage_tunfa: "吞法", + mage_tunfa_info: "每当己方主将使用一张法术牌,摸一张牌。", + mage_lieyan: "烈焰", + mage_lieyan_info: "每当己方主将使用一张法术牌,对一名随机敌方角色造成1点火焰伤害。", + mage_zhufa: "助法", + mage_zhufa_info: "每当己方主将使用一张法术牌,令其获得1点行动值。", + mage_bingdong: "冰冻", + mage_bingdong_info: "每当你对一个随从造成伤害,该随从将武将牌翻至背面。", + + stone_caoyuanshi: "草原狮", + stone_leiouke: "雷欧克", + stone_misha: "米莎", + stone_huofu: "霍弗", + stone_jiewangzhu: "结网蛛", + stone_xunshoushi: "驯兽师", + + stone_senlinlang: "森林狼", + stone_tujiu: "秃鹫", + stone_muyangren: "牧羊人", + stone_jujishou: "狙击手", + stone_damoshatuo: "大漠沙驼", + stone_huangjialeixiang: "皇家雷象", + + hunter_jiewang: "结网", + hunter_jiewang_info: "你死亡时,己方主将获得一张随机野兽牌。", + hunter_xunshou: "驯兽", + hunter_xunshou_info: + "你出场时,己方主将可选择一名其他友方随从令其增加1点体力和体力上限,摸两张牌并获得嘲讽。", + hunter_nuhou: "怒吼", + hunter_nuhou_info: "当你死亡时,对所有敌方角色造成1点伤害。", + hunter_zhanhuo: "战火", + hunter_zhanhuo2: "战火", + hunter_zhanhuo_info: "其他友方随从摸牌阶段的摸牌数+1。", + + hunter_qunxi: "群袭", + hunter_qunxi_info: "你出场时,所有友方随从摸一张牌。", + hunter_mishi: "觅食", + hunter_mishi_info: "每当己方主将召唤一个随从,摸一张牌。", + hunter_dusha: "渡沙", + hunter_dusha_info: "你出场时,令双方主将各随机使用一张牌库中的1费随从牌(不计入行动值消耗)。", + hunter_chuanlin: "穿林", + hunter_chuanlin_info: "你出场时,己方主将展示牌库中的一张随机随从牌并获得之。", + hunter_muyang: "牧羊", + hunter_muyang_info: "你出场时,随机召唤一个行动值消耗为X的随从,X为其他友方随从数。", + hunter_juji: "狙击", + hunter_juji_info: "你的职业技能可以指定随从为目标。", + + stone_baoqishi: "豹骑士", + stone_conglinshouwei: "从林守卫", + stone_baohuzhishu: "保护之树", + stone_kuangyedoushi: "狂野斗士", + stone_liebao: "猎豹", + stone_zongxiong: "棕熊", + + stone_renyaqishi: "刃牙骑士", + stone_conglinxiaoshou: "丛林枭兽", + stone_huangyeqishi: "荒野骑士", + stone_xunmenglong: "迅猛龙", + stone_lindishuyao: "林地树妖", + stone_huoshanxiemu: "火山邪木", + + druid_renya: "刃牙", + druid_renya_info: + "你出场时,己方主将可以选择一项:令你摸一张牌并将武将牌翻至正面,或令你增加1点体力上限并获得技能潜行。", + druid_yuehuo: "月火", + druid_yuehuo_info: "所有锦囊牌造成的伤害+1。", + druid_qicheng: "骑乘", + druid_qicheng_info: "你死亡时,随机召唤一个行动消耗为1的随从。", + druid_chicheng: "驰骋", + druid_chicheng_info: "你出场时,己方主将获得X点行动值,X为其他友方随从数。", + druid_yeyou: "夜游", + druid_yeyou_info: "双方主将各从牌库中获得一张牌。", + druid_juhuo: "举火", + druid_juhuo_info: "己方主将回合内,每有一名随从死亡,令己方主将获得1点行动值。", + + stone_chongfeng: "冲锋", + stone_chongfeng_info: "你出场时,立即将武将牌翻至正面。", + druid_nuhuo: "怒火", + druid_nuhuo_info: "每当己方主将使用一次职业技能,便对一名随机敌人造成1点伤害。", + druid_chengzhang: "成长", + druid_chengzhang2: "成长", + druid_chengzhang_info: "你出场时,己方主将获得1点行动值;你死亡时,己方主将需弃置一张手牌。", + druid_huwei: "护卫", + druid_huwei_info: + "你出场时,己方主将可以选择一项:对一名随从造成1点伤害,或弃置一名随从的所有牌并将其体力上限改为2。", + + stone_fachao: "法潮图腾", + stone_tutengyongshi: "图腾勇士", + stone_huoshe: "火舌图腾", + stone_huoyuansu: "火元素", + stone_tuyuansu: "土元素", + stone_wujiyuansu: "无羁元素", + stone_xuejuren: "穴居人", + stone_huoli: "活力图腾", + stone_tutengshi: "图腾师", + stone_shachuisaman: "砂槌萨满", + stone_huoyanweishi: "火焰卫士", + stone_wanshiyuansu: "顽石元素", + stone_shalinxingzhe: "砂鳞行者", + + shaman_anhun: "暗魂", + shaman_anhun_info: "每当一名友方随从死亡,令主将从牌库中获得一张牌。", + shaman_zoushi: "走石", + shaman_zoushi_info: "每当己方主将使用一张随从牌,对一名随机敌方角色造成1点伤害。", + shaman_zhuhuo: "逐火", + shaman_zhuhuo_info: "你出场时,摸1~3张牌。", + shaman_peiyu: "培育", + shaman_peiyu_info: "你出场时,增加X点体力和体力上限,X为友方图腾数。", + shaman_huoli: "活力", + shaman_huoli_info: "己方主将出牌阶段开始时,你令其获得1点行动值。", + shaman_xueju: "穴居", + shaman_xueju_info: "每当己主将使用一张随从牌,摸一张牌。", + shaman_huoxi: "火袭", + shaman_huoxi_info: "你出场时,己方主将可以对对方一名随从造成2点火焰伤害。", + shaman_fachao: "法潮", + shaman_fachao_info: "己方主将在其每个回合结束阶从牌库中获得一张牌并回复1点体力。", + shaman_huoshe: "火舌", + shaman_huoshe_info: "其他友方随从造成的伤害始终+1。", + + shaman_jili: "激励", + shaman_jili_info: "己方主将的结束阶段,所有友方图腾摸一张牌。", + shaman_tuteng: "图腾", + shaman_tuteng_info: "你跳过摸牌阶段。", + shaman_fali: "空气", + shaman_fali_info: "已方主将使用的法术牌伤害+1。", + shaman_zhiliao: "治疗", + shaman_zhiliao_info: "在你的结束阶段,令所有友方随从回复1点体力。", + shaman_zhuore: "灼热", + shaman_zhuore_info: "已方主将的结束阶段,对一名随机敌方随从造成1点伤害。", + + _shaman_skill: "图腾", + _shaman_skill_info: "召唤一个随机图腾。", + _mage_skill: "火冲", + _mage_skill_info: "对一名随从造成1点火焰伤害。", + _priest_skill: "治疗", + _priest_skill_info: "回复1点体力。", + _priest_skillx: "心刺", + _priest_skillx_info: "造成1点伤害。", + _warrior_skill: "战甲", + _warrior_skill_info: "获得1点护甲(不能超过3点)。", + _warlock_skill: "分流", + _warlock_skill_info: "从牌库中获得两张牌。", + _warlock_skillx: "炼狱", + _warlock_skillx_info: "召唤一个地狱火。", + _rogue_skill: "出鞘", + _rogue_skill_info: "装备一把武器和一个随机非武器装备。", + _paladin_skill: "动员", + _paladin_skill_info: "召唤一名士兵。", + _hunter_skill: "射击", + _hunter_skill_info: "对敌方主将造成1点伤害。", + _druid_skill: "猛击", + _druid_skill_info: "视为使用一张不计入出杀次数的杀。", + + stone_tuteng1: "石爪图腾", + stone_tuteng2: "灼热图腾", + stone_tuteng3: "空气图腾", + stone_tuteng4: "治疗图腾", + + stone_xinbing: "新兵", + + stone_zhongshi: "中士", + stone_zhongshi1: "叫嚣", + stone_zhongshi1_info: "你出场时,己方主将可以弃置对方一名随从的所有牌。", + stone_zhucangzhe: "伫藏者", + stone_zhucangzhe1: "伫藏", + stone_zhucangzhe1_info: "你出场时,己方主将可以令己方一名其他角色摸一张牌。", + stone_huoqiangshou: "火枪手", + stone_huoqiangshou1: "火枪", + stone_huoqiangshou1_info: "你出场时,己方主将可以对对方一名随从造成1点伤害。", + + stone_lansaizhanshi: "蓝腮战士", + stone_kutongsiseng: "苦痛侍僧", + stone_kutongsiseng1: "苦痛", + stone_kutongsiseng2: "苦痛", + stone_kutongsiseng1_info: "你出场时,己方主将于本结束阶段摸一张牌。", + stone_yuanguanying: "远古暗影", + stone_yuanguanying1: "暗影", + stone_yuanguanying1_info: "你出场时,己方主将可视为对一名敌方角色使用一张杀。", + + stone_dijieshicong: "低阶侍从", + stone_dijieshicong1: "持枪", + stone_dijieshicong1_info: "你出场时,敌方主将随机弃置一张装备牌。", + stone_yaosaishouwei: "要塞守卫", + stone_yaosaishouwei1: "守卫", + stone_yaosaishouwei1_info: "你出场时,己方主将本回合手牌上限+2。", + stone_famingjia: "发明家", + stone_famingjia1: "发明", + stone_famingjia1_info: "你出场时,己方主将摸两张牌。", + + stone_chilundashi: "齿轮大师", + stone_chilundashi1: "齿轮", + stone_chilundashi2: "齿轮", + stone_chilundashi1_info: "你出场后的第一个摸牌阶段摸牌数+1。", + stone_hanguangzhizhe: "寒光智者", + stone_hanguangzhizhe1: "寒光", + stone_hanguangzhizhe1_info: "你出场时,所有其他随从各摸一张牌。", + stone_aihaozhihun: "哀嚎之魂", + stone_aihaozhihun1: "哀嚎", + stone_aihaozhihun1_info: "你出场时,敌方随从弃置所有牌。", + + stone_fennuxiaoji: "愤怒小鸡", + stone_fennuxiaoji1: "暴怒", + stone_fennuxiaoji1_info: "准备阶段,若你没有手牌,你摸两张牌。", + stone_juxingchanchu: "巨型蟾蜍", + stone_juxingchanchu1: "毒液", + stone_juxingchanchu1_info: "你死亡时,己方主将可令一名敌方随从失去1点体力。", + stone_shishigui: "食尸鬼", + stone_shishigui1: "食尸", + stone_shishigui1_info: "你死亡后,场上所有其他随从失去1点体力。", + stone_wuyi: "巫医", + stone_langren: "狼人", + stone_qianxing: "潜行", + stone_qianxing_info: "你出场时,获得潜行直到下一回合开始。", + + stone_mingguangjisi: "明光祭司", + stone_nianqingjisi: "年轻祭司", + stone_zhufu: "祝福", + stone_zhufu_info: "己方主将的结束阶段,你令一名随机的受伤友方随从回复1点体力。", + stone_aomishouwei: "奥秘守卫", + stone_yanjingshe: "眼镜蛇", + stone_yanjingshe1: "毒噬", + stone_yanjingshe1_info: "你出场时,若敌方随从数不少于己方,则随机杀死一名随从。", + stone_zhiyuzhe: "治愈者", + stone_zhiyu: "治愈", + stone_zhiyu_info: "你出场时,令所有友方随从回复1点体力。", + stone_mafengzhuru: "麻风侏儒", + stone_mafengzhuru1: "麻风", + stone_mafengzhuru1_info: "杀死你的随从失去1点体力。", + stone_fatiaozhuru: "发条侏儒", + stone_fatiaozhuru1: "发条", + stone_fatiaozhuru1_info: "结束阶段,若你没有手牌,你摸两张牌。", + + stonesha: "进攻", + stonesha_info: "锁定技,你的装备牌均视为杀。", + stoneshan: "格挡", + stoneshan_info: "锁定技,你的随从和法术牌均视为闪。", + + stonecharacter: "随从", + spell_shengerpingdeng: "生而平等", + spell_shengerpingdeng_info: "将所有随从体力上限降为1。", + spell_jingshenkongzhi: "精神控制", + spell_jingshenkongzhi_info: "将一名敌方随从吸收为己方。", + spell_anyingkuangluan: "暗影狂乱", + spell_anyingkuangluan_info: + "将一名手牌数不超过1的敌方随从吸收为己方,并令其于下个回合结束后死亡。", + spell_anyingkuangluan_die: "暗影狂乱", + spell_anyingkuangluan_die_info: "下个回合结束后死亡。", + spell_binghuan: "冰环", + spell_binghuan_info: "将场上所有随从翻面。", + spell_morizaihuo: "末日灾祸", + spell_morizaihuo_info: "令场上所有随从立即死亡,回复2点体力。", + spell_zhiliaozhichu: "治疗之触", + spell_zhiliaozhichu_info: "令目标随从恢复所有体力值并获得嘲讽。", + lschaofeng: "嘲讽", + lschaofeng_info: "同阵营的无嘲讽角色不以能成为杀的目标。", + spell_wangzhezhufu: "王者祝福", + spell_wangzhezhufu_info: "令一名随从增加2点体力和体力上限并摸两张牌。", + spell_diyulieyan: "地狱烈焰", + spell_diyulieyan_info: "所有角色失去1点体力。", + spell_chenmo: "沉默", + spell_chenmo_info: "弃置一名随从的所有牌,并令其体力上限减至2。", + spell_zhiliaoshui: "治疗水", + spell_zhiliaoshui_info: + "出牌阶段对自己使用,恢复2点体力值;或于濒死阶段对一名角色使用,令目标恢复1点体力。", + spell_yanmie: "极恶之咒", + spell_yanmie_info: "交换你与敌方主将的装备区,并摸若干张牌直到你的手牌数与敌方主将相等。", + spell_xiaoshi: "消失", + spell_xiaoshi_info: + "令敌方主将将所有装备区内的牌收入手牌,并弃置其若干张手牌,直到其手牌数与你相等。", + + stonecard: "法术", + mode_stone_card_config: "炉石模式", + mode_stone_character_config: "炉石模式", + }, + help: { + 炉石模式: + '
                        构筑
                        • 点击右上角的卡组管理构建卡组
                        • 一套卡组共30张牌,由法术和随从牌构成,每个同名卡牌最多带两张' + + "
                        • 卡组管理器中,随从右上角的x/y表示登场状态为x牌y血" + + "
                        • 游戏开始时,双方摸三张牌并从牌库中获得一张牌,并可选择将手牌置换一次" + + "
                        • 每当主将摸X张牌时,若X至少为2,则其中的X-1张牌从牌堆中获得,1张牌从牌库中获得" + + "
                        • 每名角色使用一套卡组,卡组用完后会重新补满" + + "
                        • 卡组与职业绑定,每个职业有一个专属技能,每回合限用一次,消耗两点行动值
                        " + + '
                        职业技能
                        • 祭司:召唤一个随机图腾' + + "
                        • 法师:对一名随从造成1点火焰伤害" + + "
                        • 牧师:回复1点体力" + + "
                        • 战士:获得1点护甲(不能超过3点)" + + "
                        • 术士:牌库中摸两张牌" + + "
                        • 潜行者:装备一把武器和一个随机非武器装备" + + "
                        • 圣骑士:召唤一名士兵" + + "
                        • 猎人:对敌方主将造成1点伤害" + + "
                        • 德鲁伊:视为使用一张不计入出杀次数的杀
                        " + + '
                        怒气值
                        • 每当友方随从受到伤害获得3点怒气值,主将受到伤害获得6点怒气值' + + "
                        • 每有一个友方随从死亡,获得10点怒气值,主将死亡获得20点怒气值" + + "
                        • 结束阶段,若己方随从数少于对方会获得10X点怒气值,X为随从数之差" + + "
                        • 怒气值达到100时不再增加。准备阶段,若怒气值己满,可消耗全部怒气值和4点行动值并召唤一名传说随从
                        " + + '
                        战斗
                        • 场上有两名主将进行对抗,主将的体力上限+1' + + "
                        • 游戏牌堆移除了乐不思蜀等跳过出牌阶段以及包含翻面功能的卡牌" + + "
                        • 主将出牌阶段的出牌数量(行动值)有上限,从1开始递增,后手的首个回合有一点额外行动值,装备牌不计入出牌上限
                        • 游戏每进行一轮,主将的出牌上限+1,直到增加至6" + + "
                        • 使用随从牌可召唤一个随从,随从出场时背面朝上。每一方在场的随从数不能超过4
                        • 随从于摸牌阶段摸牌基数为1,随从的法术和随从牌均视为闪,装备牌均视为杀
                        • " + + "随从与其他所有角色相互距离基数为1
                        • " + + "主将杀死对方随从后获得一个额外的行动值并从牌库中获得一张牌,杀死己方随从无惩罚,随从杀死随从无效果" + + "
                        • 主将在随从满员时可重铸随从牌,但回合内总的重铸次数不能超过3;若重铸的牌为随从牌或法术牌,则摸牌改为获得一张随机法术牌" + + "
                        • 嘲讽:若一方阵营中有嘲讽角色,则同阵营的无嘲讽角色不以能成为杀目标" + + "
                        • 行动顺序为先主将后随从。主将或随从死亡后立即移出游戏,主将死亡后替补登场,替补登场时摸3+X张牌,X为对方存活的随从数,无替补时游戏结束", }, - help:{ - '炉石模式': - '
                          构筑
                          • 点击右上角的卡组管理构建卡组
                          • 一套卡组共30张牌,由法术和随从牌构成,每个同名卡牌最多带两张'+ - '
                          • 卡组管理器中,随从右上角的x/y表示登场状态为x牌y血'+ - '
                          • 游戏开始时,双方摸三张牌并从牌库中获得一张牌,并可选择将手牌置换一次'+ - '
                          • 每当主将摸X张牌时,若X至少为2,则其中的X-1张牌从牌堆中获得,1张牌从牌库中获得'+ - '
                          • 每名角色使用一套卡组,卡组用完后会重新补满'+ - '
                          • 卡组与职业绑定,每个职业有一个专属技能,每回合限用一次,消耗两点行动值
                          '+ - '
                          职业技能
                          • 祭司:召唤一个随机图腾'+ - '
                          • 法师:对一名随从造成1点火焰伤害'+ - '
                          • 牧师:回复1点体力'+ - '
                          • 战士:获得1点护甲(不能超过3点)'+ - '
                          • 术士:牌库中摸两张牌'+ - '
                          • 潜行者:装备一把武器和一个随机非武器装备'+ - '
                          • 圣骑士:召唤一名士兵'+ - '
                          • 猎人:对敌方主将造成1点伤害'+ - '
                          • 德鲁伊:视为使用一张不计入出杀次数的杀
                          '+ - '
                          怒气值
                          • 每当友方随从受到伤害获得3点怒气值,主将受到伤害获得6点怒气值'+ - '
                          • 每有一个友方随从死亡,获得10点怒气值,主将死亡获得20点怒气值'+ - '
                          • 结束阶段,若己方随从数少于对方会获得10X点怒气值,X为随从数之差'+ - '
                          • 怒气值达到100时不再增加。准备阶段,若怒气值己满,可消耗全部怒气值和4点行动值并召唤一名传说随从
                          '+ - '
                          战斗
                          • 场上有两名主将进行对抗,主将的体力上限+1'+ - '
                          • 游戏牌堆移除了乐不思蜀等跳过出牌阶段以及包含翻面功能的卡牌'+ - '
                          • 主将出牌阶段的出牌数量(行动值)有上限,从1开始递增,后手的首个回合有一点额外行动值,装备牌不计入出牌上限
                          • 游戏每进行一轮,主将的出牌上限+1,直到增加至6'+ - '
                          • 使用随从牌可召唤一个随从,随从出场时背面朝上。每一方在场的随从数不能超过4
                          • 随从于摸牌阶段摸牌基数为1,随从的法术和随从牌均视为闪,装备牌均视为杀
                          • '+ - '随从与其他所有角色相互距离基数为1
                          • '+ - '主将杀死对方随从后获得一个额外的行动值并从牌库中获得一张牌,杀死己方随从无惩罚,随从杀死随从无效果'+ - '
                          • 主将在随从满员时可重铸随从牌,但回合内总的重铸次数不能超过3;若重铸的牌为随从牌或法术牌,则摸牌改为获得一张随机法术牌'+ - '
                          • 嘲讽:若一方阵营中有嘲讽角色,则同阵营的无嘲讽角色不以能成为杀目标'+ - '
                          • 行动顺序为先主将后随从。主将或随从死亡后立即移出游戏,主将死亡后替补登场,替补登场时摸3+X张牌,X为对方存活的随从数,无替补时游戏结束' - } }; }); diff --git a/mode/tafang.js b/mode/tafang.js index 695be18ed..94fc96cf3 100644 --- a/mode/tafang.js +++ b/mode/tafang.js @@ -1,485 +1,505 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'tafang', - canvasUpdates2:[], - start:function(){ - "step 0" - _status.gameDrawed=true; - lib.init.css(lib.assetURL+'layout/mode','chess'); - lib.init.css(lib.assetURL+'layout/mode','tafang'); - game.loadMode('chess'); - "step 1" - if(get.is.phoneLayout()&&lib.config.touchscreen&& - !lib.config.show_round_menu&& - !['system','menu'].includes(lib.config.swipe_left)&& - !['system','menu'].includes(lib.config.swipe_right)&& - !['system','menu'].includes(lib.config.swipe_up)){ - ui.roundmenu.style.display=''; + name: "tafang", + canvasUpdates2: [], + start: function () { + "step 0"; + _status.gameDrawed = true; + lib.init.css(lib.assetURL + "layout/mode", "chess"); + lib.init.css(lib.assetURL + "layout/mode", "tafang"); + game.loadMode("chess"); + "step 1"; + if ( + get.is.phoneLayout() && + lib.config.touchscreen && + !lib.config.show_round_menu && + !["system", "menu"].includes(lib.config.swipe_left) && + !["system", "menu"].includes(lib.config.swipe_right) && + !["system", "menu"].includes(lib.config.swipe_up) + ) { + ui.roundmenu.style.display = ""; } - if(lib.config.player_border=='normal'&&(lib.config.layout=='long'||lib.config.layout=='long2')){ - ui.arena.classList.add('lslim_player'); + if ( + lib.config.player_border == "normal" && + (lib.config.layout == "long" || lib.config.layout == "long2") + ) { + ui.arena.classList.add("lslim_player"); } - for(var i in result.element){ - for(var j in result.element[i]){ - if(j!='dieAfter'){ - lib.element[i][j]=result.element[i][j]; + for (var i in result.element) { + for (var j in result.element[i]) { + if (j != "dieAfter") { + lib.element[i][j] = result.element[i][j]; } } } - for(var i in result.ui){ - for(var j in result.ui[i]){ - ui[i][j]=result.ui[i][j]; + for (var i in result.ui) { + for (var j in result.ui[i]) { + ui[i][j] = result.ui[i][j]; } } - get.chessDistance=result.get.chessDistance; - get.rawAttitude=result.get.rawAttitude; - var toLoad=['addChessPlayer','addObstacle','removeObstacle','isChessNeighbour', - 'draw2','updateCanvas2','setChessInfo','modeSwapPlayer','initChess']; - for(var i=0;i=8&&j!=0&&j!=ui.chesswidth-1) continue; - if(tafanglist.includes(j)){ - var cg=i*ui.chesswidth+j; + event.obs = []; + if (!event.video) { + var tafanglist = [0, 2, 3, 5, 6, 8, 9, 11, 12]; + for (var i = 0; i < ui.chessheight - 1; i++) { + for (var j = 0; j < ui.chesswidth; j++) { + if (i >= 8 && j != 0 && j != ui.chesswidth - 1) continue; + if (tafanglist.includes(j)) { + var cg = i * ui.chesswidth + j; grids.remove(cg); - game.addObstacle(cg.toString(),false); + game.addObstacle(cg.toString(), false); event.obs.push(cg.toString()); } } } - for(var i=0;icount){ - map[i][j].classList.add('unselectable'); - map[i][j].classList.remove('pointerdiv'); - } - else if(i=='zhaomu'&&_status.friends.length+selectedZhaomu>=5){ - map[i][j].classList.add('unselectable'); - map[i][j].classList.remove('pointerdiv'); - } - else if(i=='bufang'){ - var numbufang=0; - for(var k=0;k count) { + map[i][j].classList.add("unselectable"); + map[i][j].classList.remove("pointerdiv"); + } else if (i == "zhaomu" && _status.friends.length + selectedZhaomu >= 5) { + map[i][j].classList.add("unselectable"); + map[i][j].classList.remove("pointerdiv"); + } else if (i == "bufang") { + var numbufang = 0; + for (var k = 0; k < game.treasures.length; k++) { + if (game.treasures[k].name == map[i][j].link) { numbufang++; } - if(numbufang>=3){ - map[i][j].classList.add('unselectable'); + if (numbufang >= 3) { + map[i][j].classList.add("unselectable"); break; } } } } } - ui.dialog.content.firstChild.innerHTML='剩余行动点:'+count; - } - var clickOrder=0; - event.custom.replace.button=function(button){ - if(!button.classList.contains('unselectable')|| - button.classList.contains('selected')){ - button.classList.toggle('selected'); - button._clickOrder=clickOrder++; + ui.dialog.content.firstChild.innerHTML = "剩余行动点:" + count; + }; + var clickOrder = 0; + event.custom.replace.button = function (button) { + if ( + !button.classList.contains("unselectable") || + button.classList.contains("selected") + ) { + button.classList.toggle("selected"); + button._clickOrder = clickOrder++; } updateSelected(); - } - event.custom.add.window=function(clicked){ - if(clicked) return; - if(event.step>1) return; - for(var i in map){ - for(var j=0;j 1) return; + for (var i in map) { + for (var j = 0; j < map[i].length; j++) { + map[i][j].classList.remove("selected"); + map[i][j].classList.remove("unselectable"); } } updateSelected(); - } - var update=function(link){ - for(var i in map){ - for(var j=0;j=5){ - event.control.childNodes[1].style.opacity=0.5; - event.control.childNodes[1].disabled=true; - if(_status.lastTafangCommand=='招募'){ - _status.lastTafangCommand='布防'; + if (_status.friends.length >= 5) { + event.control.childNodes[1].style.opacity = 0.5; + event.control.childNodes[1].disabled = true; + if (_status.lastTafangCommand == "招募") { + _status.lastTafangCommand = "布防"; } } - _status.imchoosing=true; + _status.imchoosing = true; ui.auto.hide(); - var eventdong=function(){ - var selected=dialog.querySelectorAll('.button.selected'); - event.bufang=[]; - event.zhaomu=[]; - event.xingdong=_status.friends.slice(0); + var eventdong = function () { + var selected = dialog.querySelectorAll(".button.selected"); + event.bufang = []; + event.zhaomu = []; + event.xingdong = _status.friends.slice(0); // var xingdongs=[]; - _status.remainingCount+=10; - for(var i=0;i0){ + }, 50); + event.switchToAuto = eventdong; + if (!_status.auto && 10 + _status.remainingCount > 0) { game.pause(); - } - else{ + } else { eventdong(); } - 'step 1' + "step 1"; event.dialog.close(); event.control.close(); event.done.close(); delete event.dialog; delete event.control; delete event.done; - 'step 2' - event.chooseObstacle=false; - if(event.bufang.length){ - event.obstacles=game.obstacles.slice(0); - for(var i=0;i=0;k--){ - var pos=i+k*ui.chesswidth; - if(lib.posmap[pos]){ + if (j < ui.chessheight) { + shalldelay = true; + for (var k = j; k >= 0; k--) { + var pos = i + k * ui.chesswidth; + if (lib.posmap[pos]) { lib.posmap[pos].moveDown(); } } } } } - if(shalldelay) game.delay(); - 'step 7' - event.justadded=[]; - if(_status.characterList.length){ - if(_status.enemies.length=_status.turnTotal){ + if (_status.turnCount >= _status.turnTotal) { game.over(true); - } - else{ + } else { event.goto(0); game.delay(); } }); }, - loadMap:function(){ - var next=game.createEvent('loadMap'); - next.setContent(function(){ - if(!lib.storage.map){ - lib.storage.map=['basic_small','basic_medium','basic_large']; + loadMap: function () { + var next = game.createEvent("loadMap"); + next.setContent(function () { + if (!lib.storage.map) { + lib.storage.map = ["basic_small", "basic_medium", "basic_large"]; } - if(!lib.storage.newmap){ - lib.storage.newmap=[]; + if (!lib.storage.newmap) { + lib.storage.newmap = []; } - var sceneview=ui.create.div('.storyscene'); - if(!lib.config.touchscreen&&lib.config.mousewheel){ - sceneview._scrollspeed=30; - sceneview._scrollnum=10; - sceneview.onmousewheel=function(){ - if(!this.classList.contains('lockscroll')){ - ui.click.mousewheel.apply(this,arguments); + var sceneview = ui.create.div(".storyscene"); + if (!lib.config.touchscreen && lib.config.mousewheel) { + sceneview._scrollspeed = 30; + sceneview._scrollnum = 10; + sceneview.onmousewheel = function () { + if (!this.classList.contains("lockscroll")) { + ui.click.mousewheel.apply(this, arguments); } }; } lib.setScroll(sceneview); - var switchScene=function(){ - event.result=this.link; + var switchScene = function () { + event.result = this.link; sceneview.delete(); - setTimeout(game.resume,300); - } - var clickScene=function(e){ - if(this.classList.contains('unselectable')) return; - if(this._clicking) return; - if(e&&e.stopPropagation) e.stopPropagation(); - if(this.classList.contains('flipped')){ + setTimeout(game.resume, 300); + }; + var clickScene = function (e) { + if (this.classList.contains("unselectable")) return; + if (this._clicking) return; + if (e && e.stopPropagation) e.stopPropagation(); + if (this.classList.contains("flipped")) { return; } - if(this.classList.contains('glow3')){ - this.classList.remove('glow3'); + if (this.classList.contains("glow3")) { + this.classList.remove("glow3"); lib.storage.newmap.remove(this.name); - game.save('newmap',lib.storage.newmap); + game.save("newmap", lib.storage.newmap); } - var sceneNode=this.parentNode; - var current=document.querySelector('.flipped.scene'); - if(current){ - restoreScene(current,true); + var sceneNode = this.parentNode; + var current = document.querySelector(".flipped.scene"); + if (current) { + restoreScene(current, true); } - this.content.innerHTML=''; - ui.create.div('.menubutton.large.enter','进入',this.content,switchScene).link=this.name; - sceneNode.classList.add('lockscroll'); - var node=this; - node._clicking=true; - setTimeout(function(){ - node._clicking=false; - },700); - sceneNode.dx=ui.window.offsetWidth/2-(-sceneNode.scrollLeft+this.offsetLeft+this.offsetWidth/2); - if(Math.abs(sceneNode.dx)<20){ - sceneNode.dx=0; + this.content.innerHTML = ""; + ui.create.div(".menubutton.large.enter", "进入", this.content, switchScene).link = + this.name; + sceneNode.classList.add("lockscroll"); + var node = this; + node._clicking = true; + setTimeout(function () { + node._clicking = false; + }, 700); + sceneNode.dx = + ui.window.offsetWidth / 2 - + (-sceneNode.scrollLeft + this.offsetLeft + this.offsetWidth / 2); + if (Math.abs(sceneNode.dx) < 20) { + sceneNode.dx = 0; } - if(!sceneNode.sceneInterval&&sceneNode.dx){ - sceneNode.sceneInterval=setInterval(function(){ - var dx=sceneNode.dx; - if(Math.abs(dx)<=2){ - sceneNode.scrollLeft-=dx; + if (!sceneNode.sceneInterval && sceneNode.dx) { + sceneNode.sceneInterval = setInterval(function () { + var dx = sceneNode.dx; + if (Math.abs(dx) <= 2) { + sceneNode.scrollLeft -= dx; clearInterval(sceneNode.sceneInterval); delete sceneNode.sceneInterval; + } else { + var ddx = (dx / Math.sqrt(Math.abs(dx))) * 1.5; + sceneNode.scrollLeft -= ddx; + sceneNode.dx -= ddx; } - else{ - var ddx=dx/Math.sqrt(Math.abs(dx))*1.5; - sceneNode.scrollLeft-=ddx; - sceneNode.dx-=ddx; - } - },16); + }, 16); } - node.style.transition='all ease-in 0.2s'; - node.style.transform='perspective(1600px) rotateY(90deg) scale(0.75)'; - var onEnd=function(){ - node.removeEventListener('webkitTransitionEnd',onEnd); - node.classList.add('flipped'); - sceneNode.classList.add('lockscroll'); - node.style.transition='all ease-out 0.4s'; - node.style.transform='perspective(1600px) rotateY(180deg) scale(1)' + node.style.transition = "all ease-in 0.2s"; + node.style.transform = "perspective(1600px) rotateY(90deg) scale(0.75)"; + var onEnd = function () { + node.removeEventListener("webkitTransitionEnd", onEnd); + node.classList.add("flipped"); + sceneNode.classList.add("lockscroll"); + node.style.transition = "all ease-out 0.4s"; + node.style.transform = "perspective(1600px) rotateY(180deg) scale(1)"; }; node.listenTransition(onEnd); - } - ui.click.scene=clickScene; - var restoreScene=function(node,forced){ - if(node._clicking&&!forced) return; - if(node.transformInterval){ + }; + ui.click.scene = clickScene; + var restoreScene = function (node, forced) { + if (node._clicking && !forced) return; + if (node.transformInterval) { clearInterval(node.transformInterval); delete node.transformInterval; } - var sceneNode=node.parentNode; - node._clicking=true; - setTimeout(function(){ - node._clicking=false; - },700); - node.style.transition='all ease-in 0.2s'; - node.style.transform='perspective(1600px) rotateY(90deg) scale(0.75)'; - var onEnd=function(){ - node.removeEventListener('webkitTransitionEnd',onEnd); - node.classList.remove('flipped'); - if(!sceneNode.querySelector('.flipped')){ - sceneNode.classList.remove('lockscroll'); + var sceneNode = node.parentNode; + node._clicking = true; + setTimeout(function () { + node._clicking = false; + }, 700); + node.style.transition = "all ease-in 0.2s"; + node.style.transform = "perspective(1600px) rotateY(90deg) scale(0.75)"; + var onEnd = function () { + node.removeEventListener("webkitTransitionEnd", onEnd); + node.classList.remove("flipped"); + if (!sceneNode.querySelector(".flipped")) { + sceneNode.classList.remove("lockscroll"); } - node.style.transition='all ease-out 0.4s'; - node.style.transform='perspective(1600px) rotateY(0deg) scale(0.7)' + node.style.transition = "all ease-out 0.4s"; + node.style.transform = "perspective(1600px) rotateY(0deg) scale(0.7)"; }; node.listenTransition(onEnd); - } - ui.click.scene2=restoreScene; - var createScene=function(name){ - var scene=lib.tafang.map[name]; - var node=ui.create.div('.scene',clickScene); - node.style.transform='perspective(1600px) rotateY(0deg) scale(0.7)'; - node.name=name; - node.bgnode=ui.create.div('.background.player',node); - node.info=scene; - ui.create.div('.avatar.menu',node.bgnode); - node.namenode=ui.create.div('.name',node,(scene.name)); - if(lib.storage.map.includes(name)){ - if(lib.storage.newmap.includes(name)){ - node.classList.add('glow3'); + }; + ui.click.scene2 = restoreScene; + var createScene = function (name) { + var scene = lib.tafang.map[name]; + var node = ui.create.div(".scene", clickScene); + node.style.transform = "perspective(1600px) rotateY(0deg) scale(0.7)"; + node.name = name; + node.bgnode = ui.create.div(".background.player", node); + node.info = scene; + ui.create.div(".avatar.menu", node.bgnode); + node.namenode = ui.create.div(".name", node, scene.name); + if (lib.storage.map.includes(name)) { + if (lib.storage.newmap.includes(name)) { + node.classList.add("glow3"); } - node.namenode.dataset.nature='soilm'; + node.namenode.dataset.nature = "soilm"; + } else { + node.classList.add("unselectable"); + node.namenode.innerHTML = "未开启"; } - else{ - node.classList.add('unselectable'); - node.namenode.innerHTML=('未开启'); - } - var content=ui.create.div('.menu',node); + var content = ui.create.div(".menu", node); lib.setScroll(content); - node.content=content; + node.content = content; sceneview.appendChild(node); return node; - } - event.custom.add.window=function(){ - var current=document.querySelector('.flipped.scene'); - if(current){ + }; + event.custom.add.window = function () { + var current = document.querySelector(".flipped.scene"); + if (current) { restoreScene(current); } - } - for(var i in lib.tafang.map){ + }; + for (var i in lib.tafang.map) { createScene(i); } - ui.window.appendChild(sceneview.addTempClass('start')); + ui.window.appendChild(sceneview.addTempClass("start")); game.pause(); }); }, }, - skill:{ - tafang_mech_weixingxianjing_skill:{ - filter:function(player){ - for(var i=0;i<_status.enemies.length;i++){ - if(!_status.enemies[i].isTurnedOver()&& - get.chessDistance(player,_status.enemies[i])<=2){ + skill: { + tafang_mech_weixingxianjing_skill: { + filter: function (player) { + for (var i = 0; i < _status.enemies.length; i++) { + if ( + !_status.enemies[i].isTurnedOver() && + get.chessDistance(player, _status.enemies[i]) <= 2 + ) { return true; } } return false; }, - content:function(){ - var list=[]; - for(var i=0;i<_status.enemies.length;i++){ - if(!_status.enemies[i].isTurnedOver()&& - get.chessDistance(player,_status.enemies[i])<=2){ + content: function () { + var list = []; + for (var i = 0; i < _status.enemies.length; i++) { + if ( + !_status.enemies[i].isTurnedOver() && + get.chessDistance(player, _status.enemies[i]) <= 2 + ) { list.push(_status.enemies[i]); } } - if(list.length){ - game.log('小型陷阱发动'); - var target=list.randomGet(); + if (list.length) { + game.log("小型陷阱发动"); + var target = list.randomGet(); target.turnOver(); - game.logv(player,'tafang_mech_weixingxianjing_skill',[target]).node.text.style.display='none'; - player.line(target,'green'); + game.logv(player, "tafang_mech_weixingxianjing_skill", [ + target, + ]).node.text.style.display = "none"; + player.line(target, "green"); } - } + }, }, - tafang_mech_nengliangqiu_skill:{ - filter:function(player){ - for(var i=0;i<_status.friends.length;i++){ - if(get.chessDistance(player,_status.friends[i])<=3){ + tafang_mech_nengliangqiu_skill: { + filter: function (player) { + for (var i = 0; i < _status.friends.length; i++) { + if (get.chessDistance(player, _status.friends[i]) <= 3) { return true; } } return false; }, - content:function(){ - var list1=[],list2=[]; - for(var i=0;i<_status.friends.length;i++){ - if(get.chessDistance(player,_status.friends[i])<=1){ + content: function () { + var list1 = [], + list2 = []; + for (var i = 0; i < _status.friends.length; i++) { + if (get.chessDistance(player, _status.friends[i]) <= 1) { list2.push(_status.friends[i]); - } - else if(get.chessDistance(player,_status.friends[i])<=3){ + } else if (get.chessDistance(player, _status.friends[i]) <= 3) { list1.push(_status.friends[i]); } // else if(get.chessDistance(player,_status.friends[i])<=4){ // list2.push(_status.friends[i]); // } } - if(list2.length){ - game.asyncDraw(list2,2); - player.line(list2,'green'); + if (list2.length) { + game.asyncDraw(list2, 2); + player.line(list2, "green"); } - if(list1.length){ + if (list1.length) { game.asyncDraw(list1); - player.line(list1,'green'); + player.line(list1, "green"); } - if(list1.length||list2.length){ - game.log('能量球发动'); - game.logv(player,'tafang_mech_nengliangqiu_skill',list1.concat(list2)).node.text.style.display='none'; + if (list1.length || list2.length) { + game.log("能量球发动"); + game.logv( + player, + "tafang_mech_nengliangqiu_skill", + list1.concat(list2) + ).node.text.style.display = "none"; } - } + }, }, - tafang_mech_mutong_skill:{ - filter:function(player){ - for(var i=0;i<_status.enemies.length;i++){ - if(get.chessDistance(player,_status.enemies[i])<=3){ + tafang_mech_mutong_skill: { + filter: function (player) { + for (var i = 0; i < _status.enemies.length; i++) { + if (get.chessDistance(player, _status.enemies[i]) <= 3) { return true; } } return false; }, - content:function(){ - var list=[]; - for(var i=0;i<_status.enemies.length;i++){ - if(get.chessDistance(player,_status.enemies[i])<=3){ + content: function () { + var list = []; + for (var i = 0; i < _status.enemies.length; i++) { + if (get.chessDistance(player, _status.enemies[i]) <= 3) { list.push(_status.enemies[i]); } } - if(list.length){ - game.log('木桶发动'); - var targets=list.randomGets(1); - game.logv(player,'tafang_mech_mutong_skill',targets).node.text.style.display='none'; - player.line(targets,'green'); - for(var i=0;i
                          • 阻上敌人到达最下方的出口,坚持到给定的回合数即获得胜利
                          • '+ - '每轮可获得10个行动点,用来布置机关、招募武将。场上每有一个友方武将,行动点数-1。游戏难度将影响不同操作消耗的行动点数。未用完的行动点将减半(向下取整)并累积到下一轮
                          • '+ - '每一轮在最上方的一个随机位置增加一名敌人,若最上方已有角色,则将其下移一格
                          • '+ - '战场上最多出现3个相同的机关,每个机关在置入战场3轮后消失。战场上最多招募5名友方角色。
                          • '+ - '敌方角色到达底部出口时游戏失败,已方角色到达底部出口,将被移出游戏', + posmap: {}, + help: { + 塔防模式: + "
                            • 阻上敌人到达最下方的出口,坚持到给定的回合数即获得胜利
                            • " + + "每轮可获得10个行动点,用来布置机关、招募武将。场上每有一个友方武将,行动点数-1。游戏难度将影响不同操作消耗的行动点数。未用完的行动点将减半(向下取整)并累积到下一轮
                            • " + + "每一轮在最上方的一个随机位置增加一名敌人,若最上方已有角色,则将其下移一格
                            • " + + "战场上最多出现3个相同的机关,每个机关在置入战场3轮后消失。战场上最多招募5名友方角色。
                            • " + + "敌方角色到达底部出口时游戏失败,已方角色到达底部出口,将被移出游戏", }, }; }); diff --git a/mode/versus.js b/mode/versus.js index c304121be..8a1967da4 100644 --- a/mode/versus.js +++ b/mode/versus.js @@ -1,447 +1,479 @@ -'use strict'; -game.import('mode',function(lib,game,ui,get,ai,_status){ +"use strict"; +game.import("mode", function (lib, game, ui, get, ai, _status) { return { - name:'versus', - init:function(){ - if(get.config('versus_mode')=='jiange'){ - lib.characterPack.mode_versus=lib.jiangeboss; - } - else if(get.config('versus_mode')=='siguo'){ - lib.characterPack.mode_versus={ - tangzi:['male',['wei','wu'].randomGet(),4,['xingzhao'],[]], - liuqi:['male',['shu','qun'].randomGet(),3,['wenji','tunjiang'],[]], + name: "versus", + init: function () { + if (get.config("versus_mode") == "jiange") { + lib.characterPack.mode_versus = lib.jiangeboss; + } else if (get.config("versus_mode") == "siguo") { + lib.characterPack.mode_versus = { + tangzi: ["male", ["wei", "wu"].randomGet(), 4, ["xingzhao"], []], + liuqi: ["male", ["shu", "qun"].randomGet(), 3, ["wenji", "tunjiang"], []], }; - for(var i in lib.characterPack.mode_versus){ - lib.character[i]=lib.characterPack.mode_versus[i]; + for (var i in lib.characterPack.mode_versus) { + lib.character[i] = lib.characterPack.mode_versus[i]; } delete lib.character.sp_liuqi; delete lib.character.xf_tangzi; - lib.cardPack.mode_versus=['zong','xionghuangjiu','tongzhougongji','lizhengshangyou']; - lib.translate.mode_versus_character_config='四国武将'; + lib.cardPack.mode_versus = ["zong", "xionghuangjiu", "tongzhougongji", "lizhengshangyou"]; + lib.translate.mode_versus_character_config = "四国武将"; } - if(!lib.cardPack.mode_versus){ + if (!lib.cardPack.mode_versus) { delete lib.card.zong; delete lib.card.xionghuangjiu; delete lib.card.tongzhougongji; delete lib.card.lizhengshangyou; } }, - start:function(){ - "step 0" - _status.mode=get.config('versus_mode'); - if(_status.connectMode) _status.mode=lib.configOL.versus_mode; - if(_status.brawl&&_status.brawl.submode){ - _status.mode=_status.brawl.submode; + start: function () { + "step 0"; + _status.mode = get.config("versus_mode"); + if (_status.connectMode) _status.mode = lib.configOL.versus_mode; + if (_status.brawl && _status.brawl.submode) { + _status.mode = _status.brawl.submode; } - if(lib.config.test_game){ - _status.mode='standard'; + if (lib.config.test_game) { + _status.mode = "standard"; } - "step 1" - var playback=localStorage.getItem(lib.configprefix+'playback'); - if(playback){ + "step 1"; + var playback = localStorage.getItem(lib.configprefix + "playback"); + if (playback) { ui.create.me(); - ui.arena.style.display='none'; - ui.system.style.display='none'; - _status.playback=playback; - localStorage.removeItem(lib.configprefix+'playback'); - var store=lib.db.transaction(['video'],'readwrite').objectStore('video'); - store.get(parseInt(playback)).onsuccess=function(e){ - if(e.target.result){ + ui.arena.style.display = "none"; + ui.system.style.display = "none"; + _status.playback = playback; + localStorage.removeItem(lib.configprefix + "playback"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + store.get(parseInt(playback)).onsuccess = function (e) { + if (e.target.result) { game.playVideoContent(e.target.result.video); - } - else{ - alert('播放失败:找不到录像'); + } else { + alert("播放失败:找不到录像"); game.reload(); } - } + }; event.finish(); return; } - if(_status.connectMode){ - game.waitForPlayer(function(){ - switch(lib.configOL.versus_mode){ - case '1v1':lib.configOL.number=2;break; - case '2v2':lib.configOL.number=4;break; - case '3v3':lib.configOL.number=6;break; - case '4v4':case 'guandu':lib.configOL.number=8;break; + if (_status.connectMode) { + game.waitForPlayer(function () { + switch (lib.configOL.versus_mode) { + case "1v1": + lib.configOL.number = 2; + break; + case "2v2": + lib.configOL.number = 4; + break; + case "3v3": + lib.configOL.number = 6; + break; + case "4v4": + case "guandu": + lib.configOL.number = 8; + break; } }); - } - else if(_status.mode=='jiange'||_status.mode=='siguo'||_status.mode=='four'||_status.mode=='guandu'){ - if(_status.mode=='four'&&!get.config('enable_all_cards_four')){ - lib.card.list=lib.cardsFour; - game.fixedPile=true; - } - else if(_status.mode=='siguo'){ - for(var i=0;i=8){ - j-=8; + } else if (_status.mode == "jiange") { + var list = ["shumech", "shu", "shuboss", "shu", "wei", "weiboss", "wei", "weimech"]; + var pos = Math.floor(Math.random() * 8); + for (var i = 0; i < 8; i++) { + var j = pos + i; + if (j >= 8) { + j -= 8; } - if(list[i][0]=='w'){ - game.players[j].side=true; - game.players[j].setIdentity('wei'); - game.players[j].identity='wei'; + if (list[i][0] == "w") { + game.players[j].side = true; + game.players[j].setIdentity("wei"); + game.players[j].identity = "wei"; + } else { + game.players[j].side = false; + game.players[j].setIdentity("shu"); + game.players[j].identity = "shu"; } - else{ - game.players[j].side=false; - game.players[j].setIdentity('shu'); - game.players[j].identity='shu'; - } - if(list[i].indexOf('mech')!=-1){ - game.players[j].type='mech'; - } - else if(list[i].indexOf('boss')!=-1){ - game.players[j].type='boss'; - } - else{ - game.players[j].type='human'; + if (list[i].indexOf("mech") != -1) { + game.players[j].type = "mech"; + } else if (list[i].indexOf("boss") != -1) { + game.players[j].type = "boss"; + } else { + game.players[j].type = "human"; } game.players[i].getId(); } game.chooseCharacterJiange(); - } - else if(_status.mode=='three'){ + } else if (_status.mode == "three") { game.chooseCharacterThree(); - } - else{ + } else { game.chooseCharacter(); } - "step 3" - var players=get.players(lib.sort.position); - var info=[]; - for(var i=0;i= 4); } - else{ - info.push(lib.storage.single_control&&game.players.length>=4); - } - game.addVideo('init',null,info); - event.trigger('gameStart'); - if(_status.connectMode){ - if(_status.mode=='1v1'){ - _status.first_less=true; + game.addVideo("init", null, info); + event.trigger("gameStart"); + if (_status.connectMode) { + if (_status.mode == "1v1") { + _status.first_less = true; game.gameDraw(_status.firstChoose.next); game.phaseLoop(_status.firstChoose.next); - } - else if(_status.mode=='2v2'||_status.mode=='3v3'){ - _status.first_less=true; - var firstChoose=(_status.firstAct||game.players.randomGet()); - if(firstChoose.next.side==firstChoose.side){ - firstChoose=firstChoose.next; + } else if (_status.mode == "2v2" || _status.mode == "3v3") { + _status.first_less = true; + var firstChoose = _status.firstAct || game.players.randomGet(); + if (firstChoose.next.side == firstChoose.side) { + firstChoose = firstChoose.next; } - game.gameDraw(firstChoose,function(player){ - if(lib.configOL.replace_handcard&&player==firstChoose.previousSeat){ + game.gameDraw(firstChoose, function (player) { + if (lib.configOL.replace_handcard && player == firstChoose.previousSeat) { return 5; } return 4; }); game.phaseLoop(firstChoose); - } - else if(_status.mode=='guandu'){ + } else if (_status.mode == "guandu") { game.gameDraw(_status.firstAct); game.phaseLoop(_status.firstAct); - } - else if(_status.mode=='4v4'){ - game.gameDraw(_status.firstAct,function(player){ - if(player==_status.firstAct.previousSeat){ + } else if (_status.mode == "4v4") { + game.gameDraw(_status.firstAct, function (player) { + if (player == _status.firstAct.previousSeat) { return 5; } return 4; }); - game.replaceHandcards(_status.firstAct.previous,_status.firstAct.previous.previous); + game.replaceHandcards(_status.firstAct.previous, _status.firstAct.previous.previous); game.phaseLoop(_status.firstAct); } event.finish(); - } - else{ - if(_status.mode=='guandu'){ - game.gameDraw(_status.firstAct,4); + } else { + if (_status.mode == "guandu") { + game.gameDraw(_status.firstAct, 4); game.phaseLoop(_status.firstAct); - } - else if(_status.mode=='two'){ - _status.first_less=true; - _status.first_less_forced=true; - var firstChoose=_status.firstAct; - game.gameDraw(firstChoose,function(player){ - if(player==_status.firstAct.previousSeat&&get.config('replace_handcard_two')){ + } else if (_status.mode == "two") { + _status.first_less = true; + _status.first_less_forced = true; + var firstChoose = _status.firstAct; + game.gameDraw(firstChoose, function (player) { + if (player == _status.firstAct.previousSeat && get.config("replace_handcard_two")) { return 5; } return 4; }); game.phaseLoop(firstChoose); - } - else if(_status.mode=='endless'){ - _status.first_less=true; - _status.first_less_forced=true; - var firstChoose=_status.firstAct; + } else if (_status.mode == "endless") { + _status.first_less = true; + _status.first_less_forced = true; + var firstChoose = _status.firstAct; game.gameDraw(firstChoose); game.phaseLoop(firstChoose); - } - else if(_status.mode=='four'){ - game.gameDraw(_status.firstAct,function(player){ - if(player==_status.firstAct.previousSeat){ + } else if (_status.mode == "four") { + game.gameDraw(_status.firstAct, function (player) { + if (player == _status.firstAct.previousSeat) { return 5; } return 4; }); - if(game.me==_status.firstAct.previous||game.me==_status.firstAct.previous.previous){ - game.me.chooseBool('是否置换手牌?'); - event.replaceCard=true; + if ( + game.me == _status.firstAct.previous || + game.me == _status.firstAct.previous.previous + ) { + game.me.chooseBool("是否置换手牌?"); + event.replaceCard = true; } - } - else if(_status.mode=='siguo'){ - _status.siguoai=[ - [-7.5,-2,0,-4.5,-6,-7.5], - [-7.5,-2,0,-4.5,-6,-7.5], - [-6,-6,-1,-4.5,-6,-7.5], - [-6,-3,0,-3,-3,-6], - [-6,-3,0,-3,-3,-6], - [-6,-6,-6,-6,-6,-6], + } else if (_status.mode == "siguo") { + _status.siguoai = [ + [-7.5, -2, 0, -4.5, -6, -7.5], + [-7.5, -2, 0, -4.5, -6, -7.5], + [-6, -6, -1, -4.5, -6, -7.5], + [-6, -3, 0, -3, -3, -6], + [-6, -3, 0, -3, -3, -6], + [-6, -6, -6, -6, -6, -6], ].randomGet(); - var firstChoose=_status.firstAct; + var firstChoose = _status.firstAct; game.gameDraw(firstChoose); game.phaseLoop(firstChoose); - } - else if(_status.mode=='jiange'){ + } else if (_status.mode == "jiange") { var firstAct; - for(var i=0;i1){ - for(var i=0;i 1) { + for (var i = 0; i < game.players.length - 1; i++) { + if (game.players[i].side != game.players[i + 1].side) { var actcount; - if(Math.random()<0.5){ - actcount=i; - } - else{ - if(i>=lib.storage.number){ - actcount=i-lib.storage.number; - } - else{ - actcount=i+lib.storage.number; + if (Math.random() < 0.5) { + actcount = i; + } else { + if (i >= lib.storage.number) { + actcount = i - lib.storage.number; + } else { + actcount = i + lib.storage.number; } } - if(actcount>0){ + if (actcount > 0) { actcount--; + } else { + actcount = game.players.length - 1; } - else{ - actcount=game.players.length-1; - } - firstAct=game.players[actcount]; + firstAct = game.players[actcount]; break; } } - } - else{ - firstAct=game.players[Math.floor(Math.random()*game.players.length)]; + } else { + firstAct = game.players[Math.floor(Math.random() * game.players.length)]; } } - game.gameDraw(firstAct,4); - _status.first_less=true; - _status.round=0; - if(lib.storage.single_control){ - game.addGlobalSkill('autoswap'); - if(game.players.length>2&&lib.config.show_handcardbutton){ - ui.versushs=ui.create.system('手牌',null,true); - lib.setPopped(ui.versushs,game.versusHoverHandcards,220); + game.gameDraw(firstAct, 4); + _status.first_less = true; + _status.round = 0; + if (lib.storage.single_control) { + game.addGlobalSkill("autoswap"); + if (game.players.length > 2 && lib.config.show_handcardbutton) { + ui.versushs = ui.create.system("手牌", null, true); + lib.setPopped(ui.versushs, game.versusHoverHandcards, 220); } } - _status.enemyCount=ui.create.system('杀敌: '+get.cnNumber(0,true),null,true); - _status.friendCount=ui.create.system('阵亡: '+get.cnNumber(0,true),null,true); + _status.enemyCount = ui.create.system("杀敌: " + get.cnNumber(0, true), null, true); + _status.friendCount = ui.create.system("阵亡: " + get.cnNumber(0, true), null, true); - lib.setPopped(_status.friendCount,game.versusHoverFriend); - lib.setPopped(_status.enemyCount,game.versusHoverEnemy); + lib.setPopped(_status.friendCount, game.versusHoverFriend); + lib.setPopped(_status.enemyCount, game.versusHoverEnemy); - if(lib.storage.zhu){ + if (lib.storage.zhu) { game.versusPhaseLoop(firstAct); - } - else{ + } else { game.versusPhaseLoop(firstAct); } } - if(_status.mode!='four'){ + if (_status.mode != "four") { event.finish(); } } - "step 4" - if(event.replaceCard&&result.bool){ - var hs=game.me.getCards('h'); - for(var i=0;i侯选人数:'+lib.configOL.choice_num+'人'); - uiintro.add('
                              替补人数:'+lib.configOL.replace_number+'人'); + getRoomInfo: function (uiintro) { + if (lib.configOL.versus_mode == "1v1") { + uiintro.add('
                              侯选人数:' + lib.configOL.choice_num + "人"); + uiintro.add('
                              替补人数:' + lib.configOL.replace_number + "人"); } - if(lib.configOL.versus_mode=='2v2'||lib.configOL.versus_mode=='3v3'){ - uiintro.add('
                              四号位保护:'+(lib.configOL.replace_handcard?'开启':'关闭')); - if(lib.configOL.versus_mode=='2v2') uiintro.add('
                              四号位【飞扬】:'+(lib.configOL.olfeiyang_four?'开启':'关闭')); + if (lib.configOL.versus_mode == "2v2" || lib.configOL.versus_mode == "3v3") { + uiintro.add( + '
                              四号位保护:' + + (lib.configOL.replace_handcard ? "开启" : "关闭") + ); + if (lib.configOL.versus_mode == "2v2") + uiintro.add( + '
                              四号位【飞扬】:' + + (lib.configOL.olfeiyang_four ? "开启" : "关闭") + ); } - var last=uiintro.add('
                              出牌时限:'+lib.configOL.choose_timeout+'秒'); + var last = uiintro.add( + '
                              出牌时限:' + lib.configOL.choose_timeout + "秒" + ); // uiintro.add('
                              屏蔽弱将:'+(lib.configOL.ban_weak?'开启':'关闭')); // var last=uiintro.add('
                              屏蔽强将:'+(lib.configOL.ban_strong?'开启':'关闭')); - if(lib.configOL.banned.length){ - last=uiintro.add('
                              禁用武将:'+get.translation(lib.configOL.banned)); + if (lib.configOL.banned.length) { + last = uiintro.add( + '
                              禁用武将:' + get.translation(lib.configOL.banned) + ); } - if(lib.configOL.bannedcards.length){ - last=uiintro.add('
                              禁用卡牌:'+get.translation(lib.configOL.bannedcards)); + if (lib.configOL.bannedcards.length) { + last = uiintro.add( + '
                              禁用卡牌:' + get.translation(lib.configOL.bannedcards) + ); } - last.style.paddingBottom='8px'; + last.style.paddingBottom = "8px"; }, - getVideoName:function(){ - if(_status.mode=='three'){ - var zhu=game.findPlayer2(function(current){ - return current.side==game.me.side&¤t.identity=='zhu'; + getVideoName: function () { + if (_status.mode == "three") { + var zhu = game.findPlayer2(function (current) { + return current.side == game.me.side && current.identity == "zhu"; }); - var str=(game.me.side?'暖/':'冷/')+get.translation(zhu.previousSeat.name1)+'/'+get.translation(zhu.name1)+'/'+get.translation(zhu.nextSeat.name1); - return ['统率三军',str] + var str = + (game.me.side ? "暖/" : "冷/") + + get.translation(zhu.previousSeat.name1) + + "/" + + get.translation(zhu.name1) + + "/" + + get.translation(zhu.nextSeat.name1); + return ["统率三军", str]; } - var str=get.translation(game.me.name1); - if(game.me.name2){ - str+='/'+get.translation(game.me.name2); + var str = get.translation(game.me.name1); + if (game.me.name2) { + str += "/" + get.translation(game.me.name2); } var str2; - if(game.versusVideoName) str2=game.versusVideoName; - else{ - switch(_status.mode){ - case 'two':str2='欢乐成双';break; - case 'endless':str2='无尽模式';break; - case 'three':str2='统率三军';break; - case 'siguo':str2='同舟共济';break; - case 'jiange':str2='守卫剑阁';break; - case 'four':str2='对决 - 4v4';break; - case 'guandu':str2='官渡之战';break; - default:str2='对决 - '+lib.storage.number+'v'+lib.storage.number + if (game.versusVideoName) str2 = game.versusVideoName; + else { + switch (_status.mode) { + case "two": + str2 = "欢乐成双"; + break; + case "endless": + str2 = "无尽模式"; + break; + case "three": + str2 = "统率三军"; + break; + case "siguo": + str2 = "同舟共济"; + break; + case "jiange": + str2 = "守卫剑阁"; + break; + case "four": + str2 = "对决 - 4v4"; + break; + case "guandu": + str2 = "官渡之战"; + break; + default: + str2 = "对决 - " + lib.storage.number + "v" + lib.storage.number; } } - return [str,str2]; + return [str, str2]; }, - addRecord:function(bool){ - if(typeof bool=='boolean'){ - var data=lib.config.gameRecord.versus.data; - var identity=get.cnNumber(lib.storage.number)+'人'; - if(!data[identity]){ - data[identity]=[0,0]; + addRecord: function (bool) { + if (typeof bool == "boolean") { + var data = lib.config.gameRecord.versus.data; + var identity = get.cnNumber(lib.storage.number) + "人"; + if (!data[identity]) { + data[identity] = [0, 0]; } - if(bool){ + if (bool) { data[identity][0]++; - } - else{ + } else { data[identity][1]++; } - var list=['一人','两人','三人']; - var str=''; - for(var i=0;i'; + var list = ["一人", "两人", "三人"]; + var str = ""; + for (var i = 0; i < list.length; i++) { + if (data[list[i]]) { + str += + list[i] + ":" + data[list[i]][0] + "胜" + " " + data[list[i]][1] + "负
                              "; } } - lib.config.gameRecord.versus.str=str; - game.saveConfig('gameRecord',lib.config.gameRecord); + lib.config.gameRecord.versus.str = str; + game.saveConfig("gameRecord", lib.config.gameRecord); } }, - chooseCharacterJiange:function(){ - var next=game.createEvent('chooseCharacter'); - next.showConfig=true; - next.setContent(function(){ - 'step 0' - ui.arena.classList.add('choose-character'); - for(var i in lib.characterPack.mode_versus){ - lib.character[i]=lib.characterPack.mode_versus[i]; - if(!lib.character[i][4]){ - lib.character[i][4]=[]; + chooseCharacterJiange: function () { + var next = game.createEvent("chooseCharacter"); + next.showConfig = true; + next.setContent(function () { + "step 0"; + ui.arena.classList.add("choose-character"); + for (var i in lib.characterPack.mode_versus) { + lib.character[i] = lib.characterPack.mode_versus[i]; + if (!lib.character[i][4]) { + lib.character[i][4] = []; } } - lib.characterIntro.boss_liedixuande=lib.characterIntro.liubei; - lib.characterIntro.boss_gongshenyueying=lib.characterIntro.huangyueying; - lib.characterIntro.boss_tianhoukongming=lib.characterIntro.shen_zhugeliang; - lib.characterIntro.boss_yuhuoshiyuan=lib.characterIntro.pangtong; - lib.characterIntro.boss_qiaokuijunyi=lib.characterIntro.zhenghe; - lib.characterIntro.boss_jiarenzidan=lib.characterIntro.caozhen; - lib.characterIntro.boss_duanyuzhongda=lib.characterIntro.simayi; - lib.characterIntro.boss_juechenmiaocai=lib.characterIntro.xiahouyuan; - lib.characterIntro.boss_kumuyuanrang=lib.characterIntro.xiahoudun; - lib.characterIntro.boss_baijiwenyuan=lib.characterIntro.zhangliao; - lib.characterIntro.boss_yihanyunchang=lib.characterIntro.guanyu; - lib.characterIntro.boss_fuweizilong=lib.characterIntro.zhaoyun; - 'step 1' - for(var i in lib.skill){ - if(lib.skill[i].changeSeat){ - lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; + lib.characterIntro.boss_liedixuande = lib.characterIntro.liubei; + lib.characterIntro.boss_gongshenyueying = lib.characterIntro.huangyueying; + lib.characterIntro.boss_tianhoukongming = lib.characterIntro.shen_zhugeliang; + lib.characterIntro.boss_yuhuoshiyuan = lib.characterIntro.pangtong; + lib.characterIntro.boss_qiaokuijunyi = lib.characterIntro.zhenghe; + lib.characterIntro.boss_jiarenzidan = lib.characterIntro.caozhen; + lib.characterIntro.boss_duanyuzhongda = lib.characterIntro.simayi; + lib.characterIntro.boss_juechenmiaocai = lib.characterIntro.xiahouyuan; + lib.characterIntro.boss_kumuyuanrang = lib.characterIntro.xiahoudun; + lib.characterIntro.boss_baijiwenyuan = lib.characterIntro.zhangliao; + lib.characterIntro.boss_yihanyunchang = lib.characterIntro.guanyu; + lib.characterIntro.boss_fuweizilong = lib.characterIntro.zhaoyun; + "step 1"; + for (var i in lib.skill) { + if (lib.skill[i].changeSeat) { + lib.skill[i] = {}; + if (lib.translate[i + "_info"]) { + lib.translate[i + "_info"] = "此模式下不可用"; } } } - var list={ - weilist:[],shulist:[], - weimech:[],shumech:[], - weiboss:[],shuboss:[], - } - event.list=list; - if(lib.characterPack.boss){ - for(var i in lib.characterPack.boss){ - if(!lib.character[i]&&lib.characterPack.boss[i][4]){ - if(lib.characterPack.boss[i][4].includes('jiangeboss')|| - lib.characterPack.boss[i][4].includes('jiangemech')){ - lib.character[i]=lib.characterPack.boss[i]; + var list = { + weilist: [], + shulist: [], + weimech: [], + shumech: [], + weiboss: [], + shuboss: [], + }; + event.list = list; + if (lib.characterPack.boss) { + for (var i in lib.characterPack.boss) { + if (!lib.character[i] && lib.characterPack.boss[i][4]) { + if ( + lib.characterPack.boss[i][4].includes("jiangeboss") || + lib.characterPack.boss[i][4].includes("jiangemech") + ) { + lib.character[i] = lib.characterPack.boss[i]; } } } } - for(var i in lib.character){ - if(lib.character[i][4]){ - if(lib.character[i][4].includes('jiangeboss')){ - list[lib.character[i][1]+'boss'].push(i);continue; - } - else if(lib.character[i][4].includes('jiangemech')){ - list[lib.character[i][1]+'mech'].push(i);continue; + for (var i in lib.character) { + if (lib.character[i][4]) { + if (lib.character[i][4].includes("jiangeboss")) { + list[lib.character[i][1] + "boss"].push(i); + continue; + } else if (lib.character[i][4].includes("jiangemech")) { + list[lib.character[i][1] + "mech"].push(i); + continue; } } - if(lib.filter.characterDisabled(i)) continue; - if(get.is.double(i)) continue; - if(lib.character[i][1]=='wei'){ + if (lib.filter.characterDisabled(i)) continue; + if (get.is.double(i)) continue; + if (lib.character[i][1] == "wei") { list.weilist.push(i); - } - else if(lib.character[i][1]=='shu'){ + } else if (lib.character[i][1] == "shu") { list.shulist.push(i); } } var dialog; - switch(game.me.type){ - case 'human': - for(var i=0;i当前分数:
                              '+(lib.storage.ladder.current+(_status.ladder_tmp?40:0))+'
                              '); - uiintro.add('
                              历史最高:
                              '+lib.storage.ladder.top+'
                              '); - uiintro.content.lastChild.style.paddingBottom='8px'; - return uiintro; - },180); - _status.ladder=true; - _status.ladder_mmr=0; + ui.ladder = ui.create.system( + game.getLadderName(lib.storage.ladder.current), + null, + true + ); + lib.setPopped( + ui.ladder, + function (uiintro) { + var uiintro = ui.create.dialog("hidden"); + uiintro.add( + '
                              当前分数:
                              ' + + (lib.storage.ladder.current + (_status.ladder_tmp ? 40 : 0)) + + "
                              " + ); + uiintro.add( + '
                              历史最高:
                              ' + + lib.storage.ladder.top + + "
                              " + ); + uiintro.content.lastChild.style.paddingBottom = "8px"; + return uiintro; + }, + 180 + ); + _status.ladder = true; + _status.ladder_mmr = 0; } - event.addSetting=function(){ - var cs=function(link,node){ + event.addSetting = function () { + var cs = function (link, node) { game.swapPlayer(node._link); - _status.rechoose=true; - for(var i=0;ib?1:-1; - } - if(lib.storage.choice=='∞'){ + return a > b ? 1 : -1; + }; + if (lib.storage.choice == "∞") { list.sort(sortByGroup); - } - else{ + } else { list.randomSort(); } - _status.list=list; - var choice=(lib.storage.choice=='∞')?list.length:lib.storage.choice; - event.dialog=ui.create.dialog('选择角色',[list.slice(0,choice),'character']); - event.dialog.classList.add('fixed'); + _status.list = list; + var choice = lib.storage.choice == "∞" ? list.length : lib.storage.choice; + event.dialog = ui.create.dialog("选择角色", [list.slice(0, choice), "character"]); + event.dialog.classList.add("fixed"); // for(var i=0;i=dialog.versus_number.link+dialog.replace_number.link){ - event.fill.firstChild.innerHTML='开始'; - _status.choosefinished=true; - if(ui.cheat){ + event.custom.add.window = function () { + var dialog = _status.event.dialog; + if ( + _status.friend.length == _status.enemy.length && + _status.friend.length >= dialog.versus_number.link + dialog.replace_number.link + ) { + event.fill.firstChild.innerHTML = "开始"; + _status.choosefinished = true; + if (ui.cheat) { ui.cheat.close(); delete ui.cheat; } } - game.save('zhu',dialog.versus_zhu.link); - if(lib.storage.zhu){ + game.save("zhu", dialog.versus_zhu.link); + if (lib.storage.zhu) { // dialog.versus_only_zhu.parentNode.classList.remove('disabled'); - dialog.versus_main_zhu.parentNode.classList.remove('disabled'); - } - else{ + dialog.versus_main_zhu.parentNode.classList.remove("disabled"); + } else { // dialog.versus_only_zhu.parentNode.classList.add('disabled'); - dialog.versus_main_zhu.parentNode.classList.add('disabled'); + dialog.versus_main_zhu.parentNode.classList.add("disabled"); } // game.save('only_zhu',dialog.versus_only_zhu.link); - game.save('main_zhu',dialog.versus_main_zhu.link); - game.save('assign_enemy',dialog.versus_assign_enemy.link); - game.save('seat_order',dialog.versus_seat_order.link); + game.save("main_zhu", dialog.versus_main_zhu.link); + game.save("assign_enemy", dialog.versus_assign_enemy.link); + game.save("seat_order", dialog.versus_seat_order.link); // game.save('cross_seat',dialog.versus_cross_seat.link); - game.save('noreplace_end',dialog.versus_noreplace_end.link); - game.save('single_control',dialog.versus_single_control.link); - switch(lib.storage.seat_order){ - case '交叉':lib.storage.cross_seat=true;lib.storage.random_seat=false;break; - case '随机':lib.storage.cross_seat=false;lib.storage.random_seat=true;break; - default:lib.storage.cross_seat=false;lib.storage.random_seat=false; + game.save("noreplace_end", dialog.versus_noreplace_end.link); + game.save("single_control", dialog.versus_single_control.link); + switch (lib.storage.seat_order) { + case "交叉": + lib.storage.cross_seat = true; + lib.storage.random_seat = false; + break; + case "随机": + lib.storage.cross_seat = false; + lib.storage.random_seat = true; + break; + default: + lib.storage.cross_seat = false; + lib.storage.random_seat = false; } - game.saveConfig('first_less',dialog.versus_first_less.link,true); - game.save('number',dialog.versus_number.link); - game.save('versus_reward',dialog.versus_reward.link); - game.save('versus_punish',dialog.versus_punish.link); - game.save('replace_number',dialog.replace_number.link); - game.save('choice',dialog.choice.link); - var count,i; - if(dialog.buttons.length>lib.storage.choice){ - count=dialog.buttons.length-lib.storage.choice; - var removed=[]; - for(i=dialog.buttons.length-1;i>=0&&count>0;i--){ - if(dialog.buttons[i].classList.contains('target')==false&& - dialog.buttons[i].classList.contains('glow')==false){ + game.saveConfig("first_less", dialog.versus_first_less.link, true); + game.save("number", dialog.versus_number.link); + game.save("versus_reward", dialog.versus_reward.link); + game.save("versus_punish", dialog.versus_punish.link); + game.save("replace_number", dialog.replace_number.link); + game.save("choice", dialog.choice.link); + var count, i; + if (dialog.buttons.length > lib.storage.choice) { + count = dialog.buttons.length - lib.storage.choice; + var removed = []; + for (i = dialog.buttons.length - 1; i >= 0 && count > 0; i--) { + if ( + dialog.buttons[i].classList.contains("target") == false && + dialog.buttons[i].classList.contains("glow") == false + ) { dialog.buttons[i].remove(); _status.list.remove(dialog.buttons[i].link); - removed.push(dialog.buttons[i].link) - dialog.buttons.splice(i,1); + removed.push(dialog.buttons[i].link); + dialog.buttons.splice(i, 1); count--; } } - for(i=0;i=4){ - ui.arena.setNumber(parseInt(ui.arena.dataset.number)+1); - for(var i=0;i= 4) { + ui.arena.setNumber(parseInt(ui.arena.dataset.number) + 1); + for (var i = 0; i < game.players.length; i++) { + game.players[i].dataset.position = parseInt(game.players[i].dataset.position) + 1; } - game.singleHandcard=true; - ui.arena.classList.add('single-handcard'); - ui.window.classList.add('single-handcard'); - ui.fakeme=ui.create.div('.fakeme.avatar'); + game.singleHandcard = true; + ui.arena.classList.add("single-handcard"); + ui.window.classList.add("single-handcard"); + ui.fakeme = ui.create.div(".fakeme.avatar"); // ui.fakeme.line=lib.element.player.line; // ui.fakemebg=ui.create.div('.avatar',ui.fakeme).hide(); } - _status.prepareArena=true; + _status.prepareArena = true; ui.create.me(); - if(ui.fakeme){ + if (ui.fakeme) { ui.me.appendChild(ui.fakeme); } - var position,i; - if(lib.storage.zhu&&lib.storage.only_zhu) position=Math.ceil(num/2)-1; - else position=Math.floor(Math.random()*num) - game.friend=[]; - game.enemy=[]; - if(lib.storage.random_seat){ - var players=game.players.slice(0); + var position, i; + if (lib.storage.zhu && lib.storage.only_zhu) position = Math.ceil(num / 2) - 1; + else position = Math.floor(Math.random() * num); + game.friend = []; + game.enemy = []; + if (lib.storage.random_seat) { + var players = game.players.slice(0); game.friend.push(game.me); players.remove(game.me); - for(i=0;i=4){ + _status.friend.splice(0, num); + _status.enemy.splice(0, num); + if (lib.storage.single_control && game.players.length >= 4) { // ui.fakemebg.show(); game.onSwapControl(); } }); }, - chooseCharacterOL:function(){ - switch(lib.configOL.versus_mode){ - case '1v1':game.chooseCharacterOL1();break; - case '2v2':game.chooseCharacterOL2();break; - case '3v3':game.chooseCharacterOL3();break; - case '4v4':game.chooseCharacterOL4();break; - case 'guandu':game.chooseCharacterOLGuandu();break; + chooseCharacterOL: function () { + switch (lib.configOL.versus_mode) { + case "1v1": + game.chooseCharacterOL1(); + break; + case "2v2": + game.chooseCharacterOL2(); + break; + case "3v3": + game.chooseCharacterOL3(); + break; + case "4v4": + game.chooseCharacterOL4(); + break; + case "guandu": + game.chooseCharacterOLGuandu(); + break; } }, - chooseCharacterOLGuandu:function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - "step 0" - var list=[ - ['zhu','ezhu','ezhong','zhong','ezhong','zhong','zhong','ezhong'], - ['zhu','ezhong','zhong','ezhu','ezhong','zhong','ezhong','zhong'], - ['zhu','ezhong','zhong','ezhong','zhong','ezhong','zhong','ezhu'], - ['zhu','ezhu','zhong','ezhong','zhong','ezhong','zhong','ezhong'], - ['zhu','ezhong','zhong','ezhong','zhong','ezhu','zhong','ezhong'], + chooseCharacterOLGuandu: function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + var list = [ + ["zhu", "ezhu", "ezhong", "zhong", "ezhong", "zhong", "zhong", "ezhong"], + ["zhu", "ezhong", "zhong", "ezhu", "ezhong", "zhong", "ezhong", "zhong"], + ["zhu", "ezhong", "zhong", "ezhong", "zhong", "ezhong", "zhong", "ezhu"], + ["zhu", "ezhu", "zhong", "ezhong", "zhong", "ezhong", "zhong", "ezhong"], + ["zhu", "ezhong", "zhong", "ezhong", "zhong", "ezhu", "zhong", "ezhong"], ].randomGet(); - var side=true; - var num=Math.floor(Math.random()*8); - list=list.splice(8-num).concat(list); - for(var i=0;i<8;i++){ - if(list[i][0]=='e'){ - game.players[i].side=side; - game.players[i].identity=list[i].slice(1); + var side = true; + var num = Math.floor(Math.random() * 8); + list = list.splice(8 - num).concat(list); + for (var i = 0; i < 8; i++) { + if (list[i][0] == "e") { + game.players[i].side = side; + game.players[i].identity = list[i].slice(1); + } else { + game.players[i].side = !side; + game.players[i].identity = list[i]; } - else{ - game.players[i].side=!side; - game.players[i].identity=list[i]; - } - if(game.players[i].identity=='zhu'){ - game[game.players[i].side+'Zhu']=game.players[i]; - game.players[i].isZhu=true; + if (game.players[i].identity == "zhu") { + game[game.players[i].side + "Zhu"] = game.players[i]; + game.players[i].isZhu = true; } game.players[i].setIdentity(game.players[i].identity); - game.players[i].node.identity.dataset.color=get.translation(game.players[i].side+'Color'); + game.players[i].node.identity.dataset.color = get.translation( + game.players[i].side + "Color" + ); game.players[i].getId(); } - var side=true; - var map={}; - var num=Math.floor(Math.random()*8); - list=list.splice(8-num).concat(list); - for(var i=0;i<8;i++){ - if(list[i][0]=='e'){ - game.players[i].side=side; - game.players[i].identity=list[i].slice(1); + var side = true; + var map = {}; + var num = Math.floor(Math.random() * 8); + list = list.splice(8 - num).concat(list); + for (var i = 0; i < 8; i++) { + if (list[i][0] == "e") { + game.players[i].side = side; + game.players[i].identity = list[i].slice(1); + } else { + game.players[i].side = !side; + game.players[i].identity = list[i]; } - else{ - game.players[i].side=!side; - game.players[i].identity=list[i]; - } - map[game.players[i].playerid]=[game.players[i].side,game.players[i].identity]; + map[game.players[i].playerid] = [game.players[i].side, game.players[i].identity]; } - var evt_list=[['huoshaowuchao','chunyuqiong'],['liangcaokuifa','sp_xuyou'],['zhanyanliangzhuwenchou','jsp_guanyu'],['shishengshibai','re_guojia'],['xutuhuanjin','yj_jushou'],['liangjunxiangchi','yj_jushou'],['jianshoudaiyuan','tianfeng'],['yiruoshengqiang','re_caocao'],['shichongerjiao','sp_xuyou']].randomGet(); - var evt=evt_list[0],character=evt_list[1]; + var evt_list = [ + ["huoshaowuchao", "chunyuqiong"], + ["liangcaokuifa", "sp_xuyou"], + ["zhanyanliangzhuwenchou", "jsp_guanyu"], + ["shishengshibai", "re_guojia"], + ["xutuhuanjin", "yj_jushou"], + ["liangjunxiangchi", "yj_jushou"], + ["jianshoudaiyuan", "tianfeng"], + ["yiruoshengqiang", "re_caocao"], + ["shichongerjiao", "sp_xuyou"], + ].randomGet(); + var evt = evt_list[0], + character = evt_list[1]; game.addGlobalSkill(evt); - var func=function(map,evt,character){ - for(var i in map){ - var player=lib.playerOL[i]; - if(player){ - player.side=map[i][0]; - player.identity=map[i][1]; + var func = function (map, evt, character) { + for (var i in map) { + var player = lib.playerOL[i]; + if (player) { + player.side = map[i][0]; + player.identity = map[i][1]; player.setIdentity(); - player.node.identity.dataset.color=get.translation(player.side+'Color'); - if(player.identity=='zhu'){ - game[player.side+'Zhu']=player; - player.isZhu=true; + player.node.identity.dataset.color = get.translation(player.side + "Color"); + if (player.identity == "zhu") { + game[player.side + "Zhu"] = player; + player.isZhu = true; } } } - ui.arena.classList.add('choose-character'); - if(evt=='shishengshibai'){ - ui.guanduInfo=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - ui.guanduInfo.innerHTML='十胜十败(0)'; + ui.arena.classList.add("choose-character"); + if (evt == "shishengshibai") { + ui.guanduInfo = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + ui.guanduInfo.innerHTML = "十胜十败(0)"; } - const showGuanduEvent=function(evt,character){ - if(ui['GuanduEvent_'+evt]) return; - ui['GuanduEvent_'+evt]=ui.create.system(get.translation(evt),null,true); - lib.setPopped(ui['GuanduEvent_'+evt],function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add(get.translation(evt)); - uiintro.add('
                              '+get.translation(evt+'_info')+'
                              '); - var ul=uiintro.querySelector('ul'); - if(ul) ul.style.width='180px'; - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + const showGuanduEvent = function (evt, character) { + if (ui["GuanduEvent_" + evt]) return; + ui["GuanduEvent_" + evt] = ui.create.system(get.translation(evt), null, true); + lib.setPopped( + ui["GuanduEvent_" + evt], + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.add(get.translation(evt)); + uiintro.add( + '
                              ' + + get.translation(evt + "_info") + + "
                              " + ); + var ul = uiintro.querySelector("ul"); + if (ul) ul.style.width = "180px"; + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); }; - for(const i in lib.playerOL){ - const target=lib.playerOL[i]; - if(target==game.me){ - showGuanduEvent(evt,character); - } - else if(target.isOnline2()){ - target.send(showGuanduEvent,evt,character); + for (const i in lib.playerOL) { + const target = lib.playerOL[i]; + if (target == game.me) { + showGuanduEvent(evt, character); + } else if (target.isOnline2()) { + target.send(showGuanduEvent, evt, character); } } - if(lib.config.background_speak) game.playAudio('skill',evt); - var dialog=ui.create.dialog('本局特殊事件:'+get.translation(evt)); - dialog.addText(get.translation(evt+'_info'),false); - dialog.add([[character],'character']); - setTimeout(function(){ + if (lib.config.background_speak) game.playAudio("skill", evt); + var dialog = ui.create.dialog("本局特殊事件:" + get.translation(evt)); + dialog.addText(get.translation(evt + "_info"), false); + dialog.add([[character], "character"]); + setTimeout(function () { dialog.close(); - },5000) + }, 5000); }; - game.broadcastAll(func,map,evt,character); - _status.firstAct=game.falseZhu; - game.delay(0,5000); - "step 1" - game.falseZhu.chooseButtonOL([ - [game.falseZhu,[ - '请选择武将', - [['caocao'],'characterx'], - ],true], - [game.trueZhu,[ - '请选择武将', - [['re_yuanshao'],'characterx'], - ],true] - ],function(player,result){ - if(game.online||player==game.me){ - player.init(result.links[0]); + game.broadcastAll(func, map, evt, character); + _status.firstAct = game.falseZhu; + game.delay(0, 5000); + "step 1"; + game.falseZhu.chooseButtonOL( + [ + [game.falseZhu, ["请选择武将", [["caocao"], "characterx"]], true], + [game.trueZhu, ["请选择武将", [["re_yuanshao"], "characterx"]], true], + ], + function (player, result) { + if (game.online || player == game.me) { + player.init(result.links[0]); + } } - }) - "step 2" - game.broadcastAll(function(result){ - for(var i in result){ - if(!lib.playerOL[i].name){ + ); + "step 2"; + game.broadcastAll(function (result) { + for (var i in result) { + if (!lib.playerOL[i].name) { lib.playerOL[i].init(result[i].links[0]); } lib.playerOL[i].hp++; lib.playerOL[i].maxHp++; lib.playerOL[i].update(); } - },result); - "step 3" - event.falseList=['xiahouyuan','litong','zangba','manchong','xunyu','guojia','zhangliao','xuhuang','caohong','jsp_guanyu','hanhaoshihuan','caoren','yujin','liuye','chengyu','xunyou','zhangxiu','sp_jiaxu'].filter(function(name){ - if(lib.characterReplace[name]){ + }, result); + "step 3"; + event.falseList = [ + "xiahouyuan", + "litong", + "zangba", + "manchong", + "xunyu", + "guojia", + "zhangliao", + "xuhuang", + "caohong", + "jsp_guanyu", + "hanhaoshihuan", + "caoren", + "yujin", + "liuye", + "chengyu", + "xunyou", + "zhangxiu", + "sp_jiaxu", + ].filter(function (name) { + if (lib.characterReplace[name]) { let goon = false; - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'wei'; + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "wei"; goon = true; } } return goon; - } - else if(lib.character[name]){ - lib.character[name][1] = 'wei'; + } else if (lib.character[name]) { + lib.character[name][1] = "wei"; return true; } return false; }); - event.trueList=['xinping','hanmeng','gaogan','yuantanyuanshang','lvkuanglvxiang','xinpi','xunchen','sp_ol_zhanghe','chenlin','jsp_liubei','yj_jushou','guotufengji','gaolan','xuyou','tianfeng','chunyuqiong','shenpei'].filter(function(name){ - if(lib.characterReplace[name]){ + event.trueList = [ + "xinping", + "hanmeng", + "gaogan", + "yuantanyuanshang", + "lvkuanglvxiang", + "xinpi", + "xunchen", + "sp_ol_zhanghe", + "chenlin", + "jsp_liubei", + "yj_jushou", + "guotufengji", + "gaolan", + "xuyou", + "tianfeng", + "chunyuqiong", + "shenpei", + ].filter(function (name) { + if (lib.characterReplace[name]) { let goon = false; - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'qun'; + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "qun"; goon = true; } } return goon; - } - else if(lib.character[name]){ - lib.character[name][1] = 'qun'; + } else if (lib.character[name]) { + lib.character[name][1] = "qun"; return true; } return false; }); - game.broadcast(function(list1,list2){ - for(let name of list1){ - if(lib.characterReplace[name]){ - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'wei'; + game.broadcast( + function (list1, list2) { + for (let name of list1) { + if (lib.characterReplace[name]) { + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "wei"; + } } + } else if (lib.character[name]) { + lib.character[name][1] = "wei"; } } - else if(lib.character[name]){ - lib.character[name][1] = 'wei'; - } - } - for(let name of list2){ - if(lib.characterReplace[name]){ - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'qun'; + for (let name of list2) { + if (lib.characterReplace[name]) { + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "qun"; + } } + } else if (lib.character[name]) { + lib.character[name][1] = "qun"; } } - else if(lib.character[name]){ - lib.character[name][1] = 'qun'; - } - } - },event.falseList,event.trueList); - event.map={}; - var list=[]; - game.countPlayer(function(current){ - if(current.identity=='zhong'){ - var choice=event[current.side+'List'].randomRemove(2); - event.map[current.playerid]=choice; - list.push([current,['请选择武将',[choice,'characterx']],true]); + }, + event.falseList, + event.trueList + ); + event.map = {}; + var list = []; + game.countPlayer(function (current) { + if (current.identity == "zhong") { + var choice = event[current.side + "List"].randomRemove(2); + event.map[current.playerid] = choice; + list.push([current, ["请选择武将", [choice, "characterx"]], true]); } }); - game.me.chooseButtonOL(list,function(player,result){ - if(game.online||player==game.me){ + game.me.chooseButtonOL(list, function (player, result) { + if (game.online || player == game.me) { player.init(result.links[0]); } }); - "step 4" - for(var i in result){ - if(result[i]=='ai'){ - result[i]=event.map[i].randomRemove(1)[0]; - } - else result[i]=result[i].links[0]; + "step 4"; + for (var i in result) { + if (result[i] == "ai") { + result[i] = event.map[i].randomRemove(1)[0]; + } else result[i] = result[i].links[0]; } - game.broadcastAll(function(result){ - for(var i in result){ - if(!lib.playerOL[i].name) lib.playerOL[i].init(result[i]); + game.broadcastAll(function (result) { + for (var i in result) { + if (!lib.playerOL[i].name) lib.playerOL[i].init(result[i]); } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); - },result); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + }, result); }); }, - chooseCharacterGuandu:function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - 'step 0' + chooseCharacterGuandu: function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; lib.init.onfree(); - ui.arena.classList.add('choose-character'); - const side=game.me.side.toString(); - event.friendSide=side;event.enemySide=(side=='true'?'false':'true'); - event.zhuList=[['caocao'],['re_yuanshao']]; - event.falseList=['xiahouyuan','litong','zangba','manchong','xunyu','guojia','zhangliao','xuhuang','caohong','jsp_guanyu','hanhaoshihuan','caoren','yujin','liuye','chengyu','xunyou','zhangxiu','sp_jiaxu'].filter(function(name){ - if(lib.characterReplace[name]){ + ui.arena.classList.add("choose-character"); + const side = game.me.side.toString(); + event.friendSide = side; + event.enemySide = side == "true" ? "false" : "true"; + event.zhuList = [["caocao"], ["re_yuanshao"]]; + event.falseList = [ + "xiahouyuan", + "litong", + "zangba", + "manchong", + "xunyu", + "guojia", + "zhangliao", + "xuhuang", + "caohong", + "jsp_guanyu", + "hanhaoshihuan", + "caoren", + "yujin", + "liuye", + "chengyu", + "xunyou", + "zhangxiu", + "sp_jiaxu", + ].filter(function (name) { + if (lib.characterReplace[name]) { let goon = false; - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'wei'; + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "wei"; goon = true; } } return goon; - } - else if(lib.character[name]){ - lib.character[name][1] = 'wei'; + } else if (lib.character[name]) { + lib.character[name][1] = "wei"; return true; } return false; }); - event.trueList=['xinping','hanmeng','gaogan','yuantanyuanshang','lvkuanglvxiang','xinpi','xunchen','sp_ol_zhanghe','chenlin','jsp_liubei','yj_jushou','guotufengji','gaolan','xuyou','tianfeng','chunyuqiong','shenpei'].filter(function(name){ - if(lib.characterReplace[name]){ + event.trueList = [ + "xinping", + "hanmeng", + "gaogan", + "yuantanyuanshang", + "lvkuanglvxiang", + "xinpi", + "xunchen", + "sp_ol_zhanghe", + "chenlin", + "jsp_liubei", + "yj_jushou", + "guotufengji", + "gaolan", + "xuyou", + "tianfeng", + "chunyuqiong", + "shenpei", + ].filter(function (name) { + if (lib.characterReplace[name]) { let goon = false; - for(let i of lib.characterReplace[name]){ - if(lib.character[i]){ - lib.character[i][1] = 'qun'; + for (let i of lib.characterReplace[name]) { + if (lib.character[i]) { + lib.character[i][1] = "qun"; goon = true; } } return goon; - } - else if(lib.character[name]){ - lib.character[name][1] = 'qun'; + } else if (lib.character[name]) { + lib.character[name][1] = "qun"; return true; } return false; }); - 'step 1' - game[event.enemySide+'Zhu'].chooseButton(['请选择你的武将牌',[event.zhuList[event.enemySide=='true'?1:0],'characterx']],true); - 'step 2' - game[event.enemySide+'Zhu'].init(result.links[0]); - game[event.enemySide+'Zhu'].maxHp++; - game[event.enemySide+'Zhu'].hp++; - game[event.enemySide+'Zhu'].update(); - 'step 3' - game.countPlayer(current=>{ - if(current.side.toString()==event.enemySide&¤t.identity=='zhong'){ - let choice=event[event.enemySide+'List'].randomRemove(2)[0]; - if(lib.characterReplace[choice]) choice=lib.characterReplace[choice].randomGet(); + "step 1"; + game[event.enemySide + "Zhu"].chooseButton( + [ + "请选择你的武将牌", + [event.zhuList[event.enemySide == "true" ? 1 : 0], "characterx"], + ], + true + ); + "step 2"; + game[event.enemySide + "Zhu"].init(result.links[0]); + game[event.enemySide + "Zhu"].maxHp++; + game[event.enemySide + "Zhu"].hp++; + game[event.enemySide + "Zhu"].update(); + "step 3"; + game.countPlayer((current) => { + if (current.side.toString() == event.enemySide && current.identity == "zhong") { + let choice = event[event.enemySide + "List"].randomRemove(2)[0]; + if (lib.characterReplace[choice]) + choice = lib.characterReplace[choice].randomGet(); current.init(choice); } }); - 'step 4' - var evt_list=[['huoshaowuchao','chunyuqiong'],['liangcaokuifa','sp_xuyou'],['zhanyanliangzhuwenchou','jsp_guanyu'],['shishengshibai','re_guojia'],['xutuhuanjin','yj_jushou'],['liangjunxiangchi','yj_jushou'],['jianshoudaiyuan','tianfeng'],['yiruoshengqiang','re_caocao'],['shichongerjiao','sp_xuyou']].randomGet(); - var evt=evt_list[0],character=evt_list[1]; + "step 4"; + var evt_list = [ + ["huoshaowuchao", "chunyuqiong"], + ["liangcaokuifa", "sp_xuyou"], + ["zhanyanliangzhuwenchou", "jsp_guanyu"], + ["shishengshibai", "re_guojia"], + ["xutuhuanjin", "yj_jushou"], + ["liangjunxiangchi", "yj_jushou"], + ["jianshoudaiyuan", "tianfeng"], + ["yiruoshengqiang", "re_caocao"], + ["shichongerjiao", "sp_xuyou"], + ].randomGet(); + var evt = evt_list[0], + character = evt_list[1]; game.addGlobalSkill(evt); - const showGuanduEvent=function(evt){ - if(ui['GuanduEvent_'+evt]) return; - ui['GuanduEvent_'+evt]=ui.create.system(get.translation(evt),null,true); - lib.setPopped(ui['GuanduEvent_'+evt],function(){ - var uiintro=ui.create.dialog('hidden'); - uiintro.add(get.translation(evt)); - uiintro.add('
                              '+get.translation(evt+'_info')+'
                              '); - var ul=uiintro.querySelector('ul'); - if(ul) ul.style.width='180px'; - uiintro.add(ui.create.div('.placeholder')); - return uiintro; - },250); + const showGuanduEvent = function (evt) { + if (ui["GuanduEvent_" + evt]) return; + ui["GuanduEvent_" + evt] = ui.create.system(get.translation(evt), null, true); + lib.setPopped( + ui["GuanduEvent_" + evt], + function () { + var uiintro = ui.create.dialog("hidden"); + uiintro.add(get.translation(evt)); + uiintro.add( + '
                              ' + get.translation(evt + "_info") + "
                              " + ); + var ul = uiintro.querySelector("ul"); + if (ul) ul.style.width = "180px"; + uiintro.add(ui.create.div(".placeholder")); + return uiintro; + }, + 250 + ); }; showGuanduEvent(evt); - game.broadcastAll(function(evt){ - if(lib.config.background_speak) game.playAudio('skill',evt); - if(evt=='shishengshibai'){ - ui.guanduInfo=get.is.phoneLayout()?ui.create.div('.touchinfo.left',ui.window):ui.create.div(ui.gameinfo); - ui.guanduInfo.innerHTML='十胜十败(0)'; + game.broadcastAll(function (evt) { + if (lib.config.background_speak) game.playAudio("skill", evt); + if (evt == "shishengshibai") { + ui.guanduInfo = get.is.phoneLayout() + ? ui.create.div(".touchinfo.left", ui.window) + : ui.create.div(ui.gameinfo); + ui.guanduInfo.innerHTML = "十胜十败(0)"; } - },evt); - game.me.chooseControl('ok').set('dialog',['###本局特殊事件:'+get.translation(evt)+'###'+get.translation(evt+'_info'),[[character],'character']]); - 'step 5' - game[event.friendSide+'Zhu'].chooseButton(['请选择你的武将牌',[event.zhuList[event.friendSide=='true'?1:0],'characterx']],true); - 'step 6' - if(game[event.friendSide+'Zhu']==game.me){ - game[event.friendSide+'Zhu'].init(result.links[0]); - game[event.friendSide+'Zhu'].maxHp++; - game[event.friendSide+'Zhu'].hp++; - game[event.friendSide+'Zhu'].update(); + }, evt); + game.me + .chooseControl("ok") + .set("dialog", [ + "###本局特殊事件:" + + get.translation(evt) + + "###" + + get.translation(evt + "_info"), + [[character], "character"], + ]); + "step 5"; + game[event.friendSide + "Zhu"].chooseButton( + [ + "请选择你的武将牌", + [event.zhuList[event.friendSide == "true" ? 1 : 0], "characterx"], + ], + true + ); + "step 6"; + if (game[event.friendSide + "Zhu"] == game.me) { + game[event.friendSide + "Zhu"].init(result.links[0]); + game[event.friendSide + "Zhu"].maxHp++; + game[event.friendSide + "Zhu"].hp++; + game[event.friendSide + "Zhu"].update(); + } else event.zhuChoice = result.links[0]; + "step 7"; + if (game.me.identity != "zhu") { + event.choose_me = true; + game.me.chooseButton( + [ + "请选择你的武将牌", + [event[event.friendSide + "List"].randomRemove(2), "characterx"], + ], + true + ); } - else event.zhuChoice=result.links[0]; - 'step 7' - if(game.me.identity!='zhu'){ - event.choose_me=true; - game.me.chooseButton(['请选择你的武将牌',[event[event.friendSide+'List'].randomRemove(2),'characterx']],true); - } - 'step 8' - if(event.choose_me) game.me.init(result.links[0]); - game.countPlayer(function(current){ - if(current!=game.me&¤t.side.toString()==event.friendSide){ - if(current.identity=='zhong'){ - let choice=event[event.friendSide+'List'].randomRemove(2)[0]; - if(lib.characterReplace[choice]) choice = lib.characterReplace[choice].randomGet(); + "step 8"; + if (event.choose_me) game.me.init(result.links[0]); + game.countPlayer(function (current) { + if (current != game.me && current.side.toString() == event.friendSide) { + if (current.identity == "zhong") { + let choice = event[event.friendSide + "List"].randomRemove(2)[0]; + if (lib.characterReplace[choice]) + choice = lib.characterReplace[choice].randomGet(); current.init(choice); - } - else{ + } else { current.init(event.zhuChoice); current.maxHp++; current.hp++; @@ -2903,924 +3308,1041 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } } }); - 'step 9' - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); + "step 9"; + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); }); }, - chooseCharacterOL4:function(){ - var next=game.createEvent('chooseCharacter'); - next.setContent(function(){ - "step 0" - var list=[ - ['zhong','ezhong','ezhong','zhong','zhong','ezhong','ezhong','zhong'], - ['zhong','ezhong','zhong','ezhong','ezhong','zhong','ezhong','zhong'], - ['zhong','ezhong','ezhong','zhong','ezhong','zhong','zhong','ezhong'], - ['zhong','ezhong','zhong','ezhong','zhong','ezhong','zhong','ezhong'], - ['zhong','ezhong','ezhong','zhong','ezhong','zhong','ezhong','zhong'], + chooseCharacterOL4: function () { + var next = game.createEvent("chooseCharacter"); + next.setContent(function () { + "step 0"; + var list = [ + ["zhong", "ezhong", "ezhong", "zhong", "zhong", "ezhong", "ezhong", "zhong"], + ["zhong", "ezhong", "zhong", "ezhong", "ezhong", "zhong", "ezhong", "zhong"], + ["zhong", "ezhong", "ezhong", "zhong", "ezhong", "zhong", "zhong", "ezhong"], + ["zhong", "ezhong", "zhong", "ezhong", "zhong", "ezhong", "zhong", "ezhong"], + ["zhong", "ezhong", "ezhong", "zhong", "ezhong", "zhong", "ezhong", "zhong"], ].randomGet(); - var rand1=Math.floor(Math.random()*4); - var rand2=Math.floor(Math.random()*4); - for(var i=0;i0.4){ - return (rank>=6)?Math.random():-Math.random(); - } - else if(seed>0.1){ - return (rank>=4&&rank<6)?Math.random():-Math.random(); - } - else{ - return (rank<4)?Math.random():-Math.random(); - } - }).set('selected',_status.event.selected).set('dialog',event.videoId).set('seed',Math.random()); - "step 2" + ui.arena.classList.add("choose-character"); + }; + event.map = map; + event.selected = []; + game.broadcastAll(func, filterChoice, event.videoId, event.selected, map, lib.choiceFour); + _status.onreconnect = [ + func, + filterChoice, + event.videoId, + event.selected, + map, + lib.choiceFour, + ]; + "step 1"; + game.broadcastAll(function (player) { + player.classList.add("selectedx"); + }, event.current); + event.current + .chooseButton(true) + .set("filterButton", function (button) { + return !_status.event.selected.includes(button.link); + }) + .set("ai", function (button) { + if (_status.event.player.identity == "zhu") { + if (Math.random() < 0.8) { + var info = lib.character[button.link]; + if (!info[4] || !info[4].includes("zhu")) { + return 0; + } + } + } + var seed = _status.event.seed; + var rank = get.rank(button.link, true); + if (seed > 0.4) { + return rank >= 6 ? Math.random() : -Math.random(); + } else if (seed > 0.1) { + return rank >= 4 && rank < 6 ? Math.random() : -Math.random(); + } else { + return rank < 4 ? Math.random() : -Math.random(); + } + }) + .set("selected", _status.event.selected) + .set("dialog", event.videoId) + .set("seed", Math.random()); + "step 2"; event.selected.push(result.links[0]); - game.broadcastAll(function(player,name,zhu){ - player.classList.remove('selectedx'); - player.init(name); - if(player.node.name_seat){ - player.node.name_seat.remove(); - } - },event.current,result.links[0]); - if(event.current.identity=='zhu'){ - if(!event.current.isInitFilter('noZhuHp')){ + game.broadcastAll( + function (player, name, zhu) { + player.classList.remove("selectedx"); + player.init(name); + if (player.node.name_seat) { + player.node.name_seat.remove(); + } + }, + event.current, + result.links[0] + ); + if (event.current.identity == "zhu") { + if (!event.current.isInitFilter("noZhuHp")) { event.current.maxHp++; event.current.hp++; event.current.update(); } } - event.current.classList.remove('selectedx'); - for(var i=0;i0){ - event.withai=true; + "step 3"; + if (event.ai_targets.length > 0) { + event.withai = true; game.pause(); } - 'step 4' - game.broadcastAll(function(id){ - var dialog=get.idDialog(id); - if(dialog){ + "step 4"; + game.broadcastAll(function (id) { + var dialog = get.idDialog(id); + if (dialog) { dialog.close(); clearInterval(dialog.delay); } - },event.videoId); - var result=event._choiceMap; - for(var i in lib.playerOL){ - if(!lib.character[result[i]]){ - result[i]=game._characterChoice[i].randomGet(); + }, event.videoId); + var result = event._choiceMap; + for (var i in lib.playerOL) { + if (!lib.character[result[i]]) { + result[i] = game._characterChoice[i].randomGet(); } _status.characterlist.remove(result[i]); - if(!lib.playerOL[i].name1){ + if (!lib.playerOL[i].name1) { lib.playerOL[i].init(result[i]); } lib.playerOL[i].update(); } - game.broadcast(function(result){ - for(var i in result){ - if(!lib.playerOL[i].name1){ + game.broadcast(function (result) { + for (var i in result) { + if (!lib.playerOL[i].name1) { lib.playerOL[i].init(result[i]); lib.playerOL[i].update(); } } - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500) - },result); - setTimeout(function(){ - ui.arena.classList.remove('choose-character'); - },500); - if(lib.configOL.olfeiyang_four){ - var target=_status.firstAct.previous; - if(target.isIn()) target.addSkill('olfeiyang'); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + }, result); + setTimeout(function () { + ui.arena.classList.remove("choose-character"); + }, 500); + if (lib.configOL.olfeiyang_four) { + var target = _status.firstAct.previous; + if (target.isIn()) target.addSkill("olfeiyang"); } - game.addGlobalSkill('versus_viewHandcard'); + game.addGlobalSkill("versus_viewHandcard"); }); }, - chooseCharacterOL1:function(){ - var next=game.createEvent('chooseCharacterOL'); - next.setContent(function(){ - 'step 0' - game.removeCard('shengdong'); - game.additionaldead=[]; - var list=get.charactersOL(); - list=list.randomGets(parseInt(lib.configOL.choice_num)); - list.remove('huatuo'); - list.remove('sunquan'); - event.videoId=lib.status.videoId++; - if(Math.random()<0.5){ - event.choosing=game.players[0]; + chooseCharacterOL1: function () { + var next = game.createEvent("chooseCharacterOL"); + next.setContent(function () { + "step 0"; + game.removeCard("shengdong"); + game.additionaldead = []; + var list = get.charactersOL(); + list = list.randomGets(parseInt(lib.configOL.choice_num)); + list.remove("huatuo"); + list.remove("sunquan"); + event.videoId = lib.status.videoId++; + if (Math.random() < 0.5) { + event.choosing = game.players[0]; + } else { + event.choosing = game.players[1]; } - else{ - event.choosing=game.players[1]; - } - var createDialog=function(list,id,list1,list2){ - var dialog=ui.create.dialog('选择角色',[list,'character']); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.classList.add('noslide'); - dialog.classList.add('fixed'); - dialog.videoId=id; - if(list2&&list2){ - ui.arena.classList.add('playerhidden'); - for(var i=0;icurrent.classList.contains('acted'))){ - next._isThreeRound=true; + next.setContent(function () { + "step 0"; + var next = player.phase(); + if (!game.players.some((current) => current.classList.contains("acted"))) { + next._isThreeRound = true; } - player.classList.add('acted'); - 'step 1' - if(player.identity!='zhu'){ - for(var i=0;i=2*Math.max(game.friend.length,game.enemy.length)){ - _status.round=0; - for(var i=0;i= 2 * Math.max(game.friend.length, game.enemy.length)) { + _status.round = 0; + for (var i = 0; i < game.players.length; i++) { + game.players[i].classList.remove("acted"); } delete _status.roundStart; } - var list=(_status.currentSide==game.me.side)?game.friend.slice(0):game.enemy.slice(0); - for(var i=0;ib.countCards('j')) return 1; - return a.hp-b.hp; - }) - event.player=list[0]; + if (list.length == 0) event.redo(); + else if ( + list.length == 1 || + (game.me != game.friendZhu && !lib.storage.single_control) || + _status.currentSide != game.me.side + ) { + list.sort(function (a, b) { + if (a.countCards("j") > b.countCards("j")) return 1; + return a.hp - b.hp; + }); + event.player = list[0]; event.goto(0); + } else { + game.me.chooseTarget("选择要行动的角色", true, function (card, player, target) { + return ( + target.classList.contains("acted") == false && target.side == game.me.side + ); + }).includeOut = true; } - else{ - game.me.chooseTarget('选择要行动的角色',true,function(card,player,target){ - return (target.classList.contains('acted')==false&&target.side==game.me.side); - }).includeOut=true; - } - } - else{ - event.player=event.player.next; + } else { + event.player = event.player.next; event.goto(0); } - "step 2" - event.player=result.targets[0]; + "step 2"; + event.player = result.targets[0]; event.goto(0); }); }, - phaseLoopJiange:function(){ - var next=game.createEvent('phaseLoop'); - next.num=0; - next.setContent(function(){ - if(event.num>=8){ - event.num-=8; + phaseLoopJiange: function () { + var next = game.createEvent("phaseLoop"); + next.num = 0; + next.setContent(function () { + if (event.num >= 8) { + event.num -= 8; } - var player=_status.actlist[event.num]; - if(player.isAlive()){ + var player = _status.actlist[event.num]; + if (player.isAlive()) { player.phase(); } event.num++; event.redo(); }); }, - replacePlayerOL:function(player){ - var next=game.createEvent('replacePlayer',false,_status.event.getParent()); - next.source=player; - next.setContent('replacePlayerOL'); + replacePlayerOL: function (player) { + var next = game.createEvent("replacePlayer", false, _status.event.getParent()); + next.source = player; + next.setContent("replacePlayerOL"); }, - replacePlayer:function(player){ - var next=game.createEvent('replacePlayer',false,_status.event.getParent()); - next.source=player; - next.setContent('replacePlayer'); + replacePlayer: function (player) { + var next = game.createEvent("replacePlayer", false, _status.event.getParent()); + next.source = player; + next.setContent("replacePlayer"); }, - replacePlayerTwo:function(player,character){ - var next=game.createEvent('replacePlayerTwo',false,_status.event.getParent()); - next.source=player; - next.character=character; - next.setContent('replacePlayerTwo'); + replacePlayerTwo: function (player, character) { + var next = game.createEvent("replacePlayerTwo", false, _status.event.getParent()); + next.source = player; + next.character = character; + next.setContent("replacePlayerTwo"); }, - versusClickToSwap:function(e){ - if(_status.dragged) return; - if(this.link==game.me){ - if(!this.classList.contains('buttonclick')){ - this.addTempClass('buttonclick'); + versusClickToSwap: function (e) { + if (_status.dragged) return; + if (this.link == game.me) { + if (!this.classList.contains("buttonclick")) { + this.addTempClass("buttonclick"); } - } - else if(_status.event.player==game.me&&!_status.auto){ - game.me.popup('请稍后再换人'); + } else if (_status.event.player == game.me && !_status.auto) { + game.me.popup("请稍后再换人"); e.stopPropagation(); - } - else{ + } else { game.modeSwapPlayer(this.link); } }, - versusHoverEnemy:function(){ - var uiintro=ui.create.dialog('hidden'); + versusHoverEnemy: function () { + var uiintro = ui.create.dialog("hidden"); - if(_status.enemyDied.length){ - uiintro.add('已阵亡'); - uiintro.add([_status.enemyDied,'character']); + if (_status.enemyDied.length) { + uiintro.add("已阵亡"); + uiintro.add([_status.enemyDied, "character"]); } - uiintro.add('未上场'); - if(_status.enemy.length){ - uiintro.add([_status.enemy,'character']); - } - else{ - uiintro.add('(无)') + uiintro.add("未上场"); + if (_status.enemy.length) { + uiintro.add([_status.enemy, "character"]); + } else { + uiintro.add("(无)"); } return uiintro; }, - versusHoverFriend:function(){ - var uiintro=ui.create.dialog('hidden'); + versusHoverFriend: function () { + var uiintro = ui.create.dialog("hidden"); - if(_status.friendDied.length){ - uiintro.add('已阵亡'); - uiintro.add([_status.friendDied,'character']); + if (_status.friendDied.length) { + uiintro.add("已阵亡"); + uiintro.add([_status.friendDied, "character"]); } - uiintro.add('未上场'); - if(_status.friend.length){ - uiintro.add([_status.friend,'character']); - } - else{ - uiintro.add('(无)') + uiintro.add("未上场"); + if (_status.friend.length) { + uiintro.add([_status.friend, "character"]); + } else { + uiintro.add("(无)"); } return uiintro; }, - versusHoverHandcards:function(){ - var uiintro=ui.create.dialog('hidden'); - var added=false; - for(var i=0;i0; + liangcaokuifa: { + trigger: { player: ["useCardAfter", "phaseDrawBegin"] }, + silent: true, + filter: function (event, player) { + if (event.name == "phaseDraw") return true; + return ( + player.getHistory("sourceDamage", function (evt) { + return evt.card == event.card; + }).length > 0 + ); }, - content:function(){ - if(trigger.name=='phaseDraw') trigger.num--; + content: function () { + if (trigger.name == "phaseDraw") trigger.num--; else player.draw(); }, }, - zhanyanliangzhuwenchou:{ - trigger:{player:'phaseBegin'}, - silent:true, - content:function(){ - 'step 0' - player.chooseUseTarget({ - name:'juedou', - isCard:true, - storage:{nowuxie:true} - }, - '选择一名角色,视为对其使用【决斗】','或点【取消】失去1点体力'); - 'step 1' - if(!result.bool) player.loseHp(); + zhanyanliangzhuwenchou: { + trigger: { player: "phaseBegin" }, + silent: true, + content: function () { + "step 0"; + player.chooseUseTarget( + { + name: "juedou", + isCard: true, + storage: { nowuxie: true }, + }, + "选择一名角色,视为对其使用【决斗】", + "或点【取消】失去1点体力" + ); + "step 1"; + if (!result.bool) player.loseHp(); }, }, - xujiu2:{ - charlotte:true, - onremove:true, - trigger:{player:'damageBegin2'}, - forced:true, - content:function(){ - trigger.num+=player.countMark('xujiu2'); + xujiu2: { + charlotte: true, + onremove: true, + trigger: { player: "damageBegin2" }, + forced: true, + content: function () { + trigger.num += player.countMark("xujiu2"); }, - intro:{content:'本回合受到的伤害+#'}, - ai:{threaten:(player,target)=>1+target.countMark('xujiu2')}, + intro: { content: "本回合受到的伤害+#" }, + ai: { threaten: (player, target) => 1 + target.countMark("xujiu2") }, }, - shishengshibai:{ - mod:{ - aiOrder:function(player,card,num){ - if(_status.shishengshibai&&_status.shishengshibai%10==9){ - if(['sha','tao','guohe','shunshou','tunliang','wuzhong','juedou','yuanjun'].includes(card.name)) return num+15; + shishengshibai: { + mod: { + aiOrder: function (player, card, num) { + if (_status.shishengshibai && _status.shishengshibai % 10 == 9) { + if ( + [ + "sha", + "tao", + "guohe", + "shunshou", + "tunliang", + "wuzhong", + "juedou", + "yuanjun", + ].includes(card.name) + ) + return num + 15; } }, }, - trigger:{ - player:'useCard1', + trigger: { + player: "useCard1", }, - silent:true, - content:function(){ - if(event.triggername=='useCard1'){ - if(!_status.shishengshibai) _status.shishengshibai=0; + silent: true, + content: function () { + if (event.triggername == "useCard1") { + if (!_status.shishengshibai) _status.shishengshibai = 0; _status.shishengshibai++; - game.broadcastAll(function(num){ - if(ui.guanduInfo) ui.guanduInfo.innerHTML='十胜十败('+num+')'; - },_status.shishengshibai); - if(_status.shishengshibai%10==0&&trigger.targets&&trigger.targets.length>0&&!['delay','equip'].includes(get.type(trigger.card))){ + game.broadcastAll(function (num) { + if (ui.guanduInfo) ui.guanduInfo.innerHTML = "十胜十败(" + num + ")"; + }, _status.shishengshibai); + if ( + _status.shishengshibai % 10 == 0 && + trigger.targets && + trigger.targets.length > 0 && + !["delay", "equip"].includes(get.type(trigger.card)) + ) { trigger.effectCount++; } } }, - ai:{ - result:{ - player:function(card,player,target){ - if(_status.shishengshibai&&_status.shishengshibai%10==9&&card.name=='tiesuo') return 'zerotarget'; + ai: { + result: { + player: function (card, player, target) { + if ( + _status.shishengshibai && + _status.shishengshibai % 10 == 9 && + card.name == "tiesuo" + ) + return "zerotarget"; }, }, }, }, liangjunxiangchi: { mod: { - maxHandcard: function(player, num) { + maxHandcard: function (player, num) { if (game.roundNumber <= 4) return num + game.roundNumber; }, }, - trigger: { source: 'damageBegin1' }, - filter: function(event, player) { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { if (game.roundNumber <= 4) return false; - var evt2 = event.getParent('phaseUse'); + var evt2 = event.getParent("phaseUse"); if (evt2.player != player) return false; - return player.getHistory('useCard', function (evt) { - return evt.card.name == 'sha' && evt.getParent('phaseUse') == evt2; - }).indexOf(event.getParent()) == 0; + return ( + player + .getHistory("useCard", function (evt) { + return evt.card.name == "sha" && evt.getParent("phaseUse") == evt2; + }) + .indexOf(event.getParent()) == 0 + ); }, silent: true, forced: true, - content: function() { + content: function () { trigger.num++; }, }, xutuhuanjin: { - trigger: { player: 'phaseUseEnd' }, - filter: function(event, player) { - if (player.getHistory('useCard', function (evt) { - return evt.card && evt.card.name == 'sha' && evt.getParent('phaseUse') == event; - }).length > 0) return false; - if (player.getHistory('respond', function (evt) { - return evt.card && evt.card.name == 'sha' && evt.getParent('phaseUse') == event; - }).length > 0) return false; + trigger: { player: "phaseUseEnd" }, + filter: function (event, player) { + if ( + player.getHistory("useCard", function (evt) { + return evt.card && evt.card.name == "sha" && evt.getParent("phaseUse") == event; + }).length > 0 + ) + return false; + if ( + player.getHistory("respond", function (evt) { + return evt.card && evt.card.name == "sha" && evt.getParent("phaseUse") == event; + }).length > 0 + ) + return false; return true; }, forced: true, - content: function() { - player.addTempSkill('xutuhuanjin_yingzi', { player: 'phaseDrawAfter' }); - player.addMark('xutuhuanjin_yingzi', 1, false); + content: function () { + player.addTempSkill("xutuhuanjin_yingzi", { player: "phaseDrawAfter" }); + player.addMark("xutuhuanjin_yingzi", 1, false); }, subSkill: { yingzi: { charlotte: true, onremove: true, - trigger: { player: 'phaseDrawBegin2' }, - filter: function(event, player) { - return !event.numFixed && player.hasMark('xutuhuanjin_yingzi'); + trigger: { player: "phaseDrawBegin2" }, + filter: function (event, player) { + return !event.numFixed && player.hasMark("xutuhuanjin_yingzi"); }, forced: true, - content: function() { - trigger.num += player.countMark('xutuhuanjin_yingzi'); + content: function () { + trigger.num += player.countMark("xutuhuanjin_yingzi"); }, - marktext: '缓', - intro: { content: '下个摸牌阶段多摸#张牌' }, + marktext: "缓", + intro: { content: "下个摸牌阶段多摸#张牌" }, }, }, }, jianshoudaiyuan: { charlotte: true, mod: { - aiValue: function(player, card, num) { - if (card.name != 'sha' && card.name != 'shan') return; + aiValue: function (player, card, num) { + if (card.name != "sha" && card.name != "shan") return; var geti = function () { - var cards = player.getCards('hs', function (card) { - return card.name == 'sha' || card.name == 'shan'; + var cards = player.getCards("hs", function (card) { + return card.name == "sha" || card.name == "shan"; }); if (cards.contains(card)) { return cards.indexOf(card); @@ -4920,45 +5812,52 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }; return Math.max(num, [7, 5, 5, 3][Math.min(geti(), 3)]); }, - aiUseful: function() { + aiUseful: function () { return lib.skill.jianshoudaiyuan.mod.aiValue.apply(this, arguments); }, }, locked: false, - enable: ['chooseToUse', 'chooseToRespond'], - position: 'hs', - prompt: '将【杀】当作【闪】,或将【闪】当作的【杀】使用或打出,然后你的下个弃牌阶段的手牌上限-1', - viewAs:function(cards,player){ - if(cards.length){ - var name=false; - switch(get.name(cards[0],player)){ - case 'sha':name='shan';break; - case 'shan':name='sha';break; + enable: ["chooseToUse", "chooseToRespond"], + position: "hs", + prompt: "将【杀】当作【闪】,或将【闪】当作的【杀】使用或打出,然后你的下个弃牌阶段的手牌上限-1", + viewAs: function (cards, player) { + if (cards.length) { + var name = false; + switch (get.name(cards[0], player)) { + case "sha": + name = "shan"; + break; + case "shan": + name = "sha"; + break; } - if(name) return {name:name}; + if (name) return { name: name }; } return null; }, - onuse: function(links, player) { - player.addTempSkill('jianshoudaiyuan_less', { player: 'phaseDiscardAfter' }); - player.addMark('jianshoudaiyuan_less', 1, false); - player.markSkill('jianshoudaiyuan_less'); + onuse: function (links, player) { + player.addTempSkill("jianshoudaiyuan_less", { player: "phaseDiscardAfter" }); + player.addMark("jianshoudaiyuan_less", 1, false); + player.markSkill("jianshoudaiyuan_less"); }, - onrespond: function(links, player) { - player.addTempSkill('jianshoudaiyuan_less', { player: 'phaseDiscardAfter' }); - player.addMark('jianshoudaiyuan_less', 1, false); - player.markSkill('jianshoudaiyuan_less'); + onrespond: function (links, player) { + player.addTempSkill("jianshoudaiyuan_less", { player: "phaseDiscardAfter" }); + player.addMark("jianshoudaiyuan_less", 1, false); + player.markSkill("jianshoudaiyuan_less"); }, - check: function(card) { + check: function (card) { var player = _status.event.player; - if (_status.event.type == 'phase') { + if (_status.event.type == "phase") { var max = 0; var name2; - var list = ['sha']; - var map = { sha: 'shan' }; + var list = ["sha"]; + var map = { sha: "shan" }; for (var i = 0; i < list.length; i++) { var name = list[i]; - if (player.countCards('hs', map[name]) && player.getUseValue({ name: name }) > 0) { + if ( + player.countCards("hs", map[name]) && + player.getUseValue({ name: name }) > 0 + ) { var temp = get.order({ name: name }); if (temp > max) { max = temp; @@ -4971,35 +5870,41 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } return 1; }, - filterCard: function(card, player, event) { + filterCard: function (card, player, event) { event = event || _status.event; var filter = event._backup.filterCard; var name = get.name(card, player); - if (name == 'sha' && filter({ name: 'shan', cards: [card] }, player, event)) return true; - if (name == 'shan' && filter({ name: 'sha', cards: [card] }, player, event)) return true; + if (name == "sha" && filter({ name: "shan", cards: [card] }, player, event)) return true; + if (name == "shan" && filter({ name: "sha", cards: [card] }, player, event)) return true; return false; }, - filter: function(event, player) { + filter: function (event, player) { var filter = event.filterCard; - if (filter({ name: 'sha' }, player, event) && player.countCards('hs', 'shan')) return true; - if (filter({ name: 'shan' }, player, event) && player.countCards('hs', 'sha')) return true; + if (filter({ name: "sha" }, player, event) && player.countCards("hs", "shan")) + return true; + if (filter({ name: "shan" }, player, event) && player.countCards("hs", "sha")) + return true; return false; }, ai: { respondSha: true, respondShan: true, - skillTagFilter: function(player, tag) { + skillTagFilter: function (player, tag) { var name; switch (tag) { - case 'respondSha': name = 'shan'; break; - case 'respondShan': name = 'sha'; break; + case "respondSha": + name = "shan"; + break; + case "respondShan": + name = "sha"; + break; } - if (!player.countCards('hs', name)) return false; + if (!player.countCards("hs", name)) return false; }, - order:function(item,player){ - if(player&&_status.event.type=='phase'){ - if(player.countCards('hs','shan')&&player.getUseValue({name:'sha'})>0){ - return get.order({name:'sha'},player)*0.99; + order: function (item, player) { + if (player && _status.event.type == "phase") { + if (player.countCards("hs", "shan") && player.getUseValue({ name: "sha" }) > 0) { + return get.order({ name: "sha" }, player) * 0.99; } return 0; } @@ -5010,221 +5915,234 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ less: { onremove: true, charlotte: true, - market: '守', - intro: { content: '手牌上限-#' }, + market: "守", + intro: { content: "手牌上限-#" }, mod: { - maxHandcard: function(player, num) { - return num - player.countMark('jianshoudaiyuan_less'); + maxHandcard: function (player, num) { + return num - player.countMark("jianshoudaiyuan_less"); }, }, }, }, }, yiruoshengqiang: { - trigger: { source: 'damageBegin2' }, - filter: function(event, player) { + trigger: { source: "damageBegin2" }, + filter: function (event, player) { return event.player.hp > player.hp; }, forced: true, silent: true, - content: function() { + content: function () { trigger.num++; }, }, shichongerjiao: { charlotte: true, - trigger: { player: 'phaseJieshu' }, - filter: function(event, player) { - return lib.skill.shichongerjiao.filterx(event, player) || lib.skill.shichongerjiao.filtery(event, player); + trigger: { player: "phaseJieshu" }, + filter: function (event, player) { + return ( + lib.skill.shichongerjiao.filterx(event, player) || + lib.skill.shichongerjiao.filtery(event, player) + ); }, - filterx: function(event, player) { + filterx: function (event, player) { return player.isMaxHp(); }, - filtery: function(event, player) { + filtery: function (event, player) { return player.isMaxHandcard(); }, forced: true, silent: true, - content: function() { + content: function () { var bool1 = lib.skill.shichongerjiao.filterx(trigger, player); var bool2 = lib.skill.shichongerjiao.filtery(trigger, player); - if (bool1) player.chooseToDiscard('he', true); + if (bool1) player.chooseToDiscard("he", true); if (bool2) player.loseHp(); }, }, - wenji:{ - trigger:{global:'phaseUseBegin'}, - filter:function(event,player){ - return event.player.side==player.side&&event.player!=player&&event.player.countCards('h'); + wenji: { + trigger: { global: "phaseUseBegin" }, + filter: function (event, player) { + return ( + event.player.side == player.side && + event.player != player && + event.player.countCards("h") + ); }, - logTarget:'player', - check:function(event,player){ - return event.player.needsToDiscard(1)||event.player.countCards('h')>player.countCards('h')+1||player.hp==1; + logTarget: "player", + check: function (event, player) { + return ( + event.player.needsToDiscard(1) || + event.player.countCards("h") > player.countCards("h") + 1 || + player.hp == 1 + ); }, - content:function(){ - 'step 0' - trigger.player.chooseCard('将一张手牌交给'+get.translation(player),true).ai=function(card){ - if(get.type(card)=='trick') return 8-get.value(card); - return 6-get.value(card); - } - 'step 1' - if(result.bool&&result.cards.length){ - player.gain(result.cards,trigger.player,'give'); - if(get.type(result.cards[0])=='trick'){ - player.addTempSkill('wenji2',{player:'phaseBegin'}); + content: function () { + "step 0"; + trigger.player.chooseCard("将一张手牌交给" + get.translation(player), true).ai = + function (card) { + if (get.type(card) == "trick") return 8 - get.value(card); + return 6 - get.value(card); + }; + "step 1"; + if (result.bool && result.cards.length) { + player.gain(result.cards, trigger.player, "give"); + if (get.type(result.cards[0]) == "trick") { + player.addTempSkill("wenji2", { player: "phaseBegin" }); } } - } + }, }, - wenji2:{ - mark:true, - intro:{ - content:'非队友角色计算与你的距离+1' + wenji2: { + mark: true, + intro: { + content: "非队友角色计算与你的距离+1", }, - mod:{ - globalTo:function(from,to,distance){ - if(from.side!=to.side){ - return distance+1; + mod: { + globalTo: function (from, to, distance) { + if (from.side != to.side) { + return distance + 1; } - } - } + }, + }, }, - tunjiang:{ - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return !player.getStat('damage')&&player.countUsed()>=2; + tunjiang: { + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return !player.getStat("damage") && player.countUsed() >= 2; }, - content:function(){ - 'step 0' - var target=null; - for(var i=0;i=player.countCards('h')){ - return 1; - } - return 0; - }).set('prompt',get.prompt('xingzhao')).set('choiceList',[ - '摸两张牌','令'+get.translation(target)+'摸两张牌' - ]); + if (target) { + event.target = target; + player + .chooseControl("cancel2", function () { + if (target.countCards("h") >= player.countCards("h")) { + return 1; + } + return 0; + }) + .set("prompt", get.prompt("xingzhao")) + .set("choiceList", ["摸两张牌", "令" + get.translation(target) + "摸两张牌"]); + } else { + player.chooseBool(get.prompt("xingzhao")); } - else{ - player.chooseBool(get.prompt('xingzhao')); - } - 'step 1' - if(event.target){ - if(result.index==0){ - player.logSkill('xingzhao'); + "step 1"; + if (event.target) { + if (result.index == 0) { + player.logSkill("xingzhao"); player.draw(2); - } - else if(result.index==1){ - player.logSkill('xingzhao',event.target); + } else if (result.index == 1) { + player.logSkill("xingzhao", event.target); event.target.draw(2); } - } - else{ - if(result.bool){ - player.logSkill('xingzhao'); + } else { + if (result.bool) { + player.logSkill("xingzhao"); player.draw(2); } } - } + }, }, - xingzhao:{ - inherit:'xunxun', - mark:true, - intro:{ - content:function(storage,player){ - var num=0; - for(var i=0;i=1){ - str='具有技能“恂恂”'; + var str = "无技能"; + if (num >= 1) { + str = "具有技能“恂恂”"; } - if(num>=2){ - str+=';当你或队友使用装备牌时,其摸一张牌'; + if (num >= 2) { + str += ";当你或队友使用装备牌时,其摸一张牌"; } - if(num>=3){ - str+=';你和队友跳过判定阶段'; + if (num >= 3) { + str += ";你和队友跳过判定阶段"; } return str; - } + }, }, - filter:function(event,player){ - var num=0; - for(var i=0;i=2; + return bool && num >= 2; }, - content:function(){ + content: function () { player.draw(); - } + }, }, - xingzhao3:{ - trigger:{player:'phaseJudgeBefore'}, - forced:true, - filter:function(event,player){ - var num=0,bool=false; - for(var i=0;i=3; + return bool && num >= 3; }, - content:function(){ + content: function () { trigger.cancel(); - game.log(player,'跳过了判定阶段'); - } - }, - xionghuangjiu:{ - trigger:{source:'damageBegin1'}, - filter:function(event,player){ - return event.card&&event.card==player.storage.xionghuangjiu&&event.notLink(); + game.log(player, "跳过了判定阶段"); }, - forced:true, - content:function(){ + }, + xionghuangjiu: { + trigger: { source: "damageBegin1" }, + filter: function (event, player) { + return event.card && event.card == player.storage.xionghuangjiu && event.notLink(); + }, + forced: true, + content: function () { trigger.num++; }, - temp:true, - vanish:true, - onremove:function(player){ - game.addVideo('jiuNode',player,false); - if(player.node.jiu){ + temp: true, + vanish: true, + onremove: function (player) { + game.addVideo("jiuNode", player, false); + if (player.node.jiu) { player.node.jiu.delete(); player.node.jiu2.delete(); delete player.node.jiu; @@ -5232,1427 +6150,1505 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } delete player.storage.xionghuangjiu; }, - group:['xionghuangjiu2','xionghuangjiu3'] + group: ["xionghuangjiu2", "xionghuangjiu3"], }, - xionghuangjiu2:{ - trigger:{player:'useCardAfter',global:'phaseAfter'}, - priority:2, - filter:function(event,player){ - if(event.name=='useCard') return (event.card&&event.card==player.storage.xionghuangjiu); + xionghuangjiu2: { + trigger: { player: "useCardAfter", global: "phaseAfter" }, + priority: 2, + filter: function (event, player) { + if (event.name == "useCard") + return event.card && event.card == player.storage.xionghuangjiu; return true; }, - forced:true, - popup:false, - audio:false, - content:function(){ - game.broadcastAll(function(player){ - player.removeSkill('xionghuangjiu'); - },player); + forced: true, + popup: false, + audio: false, + content: function () { + game.broadcastAll(function (player) { + player.removeSkill("xionghuangjiu"); + }, player); }, }, - xionghuangjiu3:{ - trigger:{player:'useCard'}, - silent:true, - filter:function(event,player){ + xionghuangjiu3: { + trigger: { player: "useCard" }, + silent: true, + filter: function (event, player) { return !player.storage.xionghuangjiu; }, - content:function(){ - player.storage.xionghuangjiu=trigger.card; - } - }, - longchuanzhibao:{ - mark:'auto', - nopop:true, - init:function(player){ - player.storage.longchuanzhibao=0; + content: function () { + player.storage.xionghuangjiu = trigger.card; }, - intro:{ - content:function(storage,player){ - var str='已有'+storage+'个龙船至宝,'+get.translation(player.side)+'势力共有'; - var num=storage; - for(var i=0;i0; + trigger: { source: "damageEnd" }, + silent: true, + filter: function (event, player) { + return event.player.storage.longchuanzhibao > 0; }, - content:function(){ - player.gainZhibao(1,trigger.player); + content: function () { + player.gainZhibao(1, trigger.player); game.delay(); }, - group:'longchuanzhibao_over', - subSkill:{ - over:{ - trigger:{player:'roundStart'}, - silent:true, - filter:function(){ - var map={wei:0,shu:0,wu:0,qun:0}; - for(var i=0;i=4){ - _status.winside=current.side; + group: "longchuanzhibao_over", + subSkill: { + over: { + trigger: { player: "roundStart" }, + silent: true, + filter: function () { + var map = { wei: 0, shu: 0, wu: 0, qun: 0 }; + for (var i = 0; i < game.players.length; i++) { + var current = game.players[i]; + map[current.side] += current.storage.longchuanzhibao; + if (map[current.side] >= 4) { + _status.winside = current.side; return true; } } }, - content:function(){ - for(var i=0;i0; + forced: true, + filter: function (event, player) { + if (event.name == "die") return event.player.isEnemyOf(player); + return !event.numFixed && player.countMark("boss_huchen") > 0; }, - content:function(){ - if(trigger.name=='die') player.addMark('boss_huchen',1); - else trigger.num+=player.countMark('boss_huchen'); + content: function () { + if (trigger.name == "die") player.addMark("boss_huchen", 1); + else trigger.num += player.countMark("boss_huchen"); }, - intro:{ - content:'已斩杀过$名敌将', + intro: { + content: "已斩杀过$名敌将", }, }, - boss_fengjian:{ - trigger:{source:'damageSource'}, - forced:true, - filter:function(event,player){ + boss_fengjian: { + trigger: { source: "damageSource" }, + forced: true, + filter: function (event, player) { return event.player.isAlive(); }, - logTarget:'player', - content:function(){ - trigger.player.addTempSkill('boss_fengjian2',{player:'phaseAfter'}); - trigger.player.markAuto('boss_fengjian2',[player]); + logTarget: "player", + content: function () { + trigger.player.addTempSkill("boss_fengjian2", { player: "phaseAfter" }); + trigger.player.markAuto("boss_fengjian2", [player]); }, }, - boss_fengjian2:{ - onremove:true, - intro:{ - content:'不能对$使用牌', + boss_fengjian2: { + onremove: true, + intro: { + content: "不能对$使用牌", }, - mod:{ - playerEnabled:function(card,player,target){ - if(player.getStorage('boss_fengjian2').includes(target)) return false; + mod: { + playerEnabled: function (card, player, target) { + if (player.getStorage("boss_fengjian2").includes(target)) return false; }, }, }, - boss_keding:{ - trigger:{player:'useCard2'}, - direct:true, - filter:function(event,player){ - if(!event.targets||event.targets.length!=1) return false; - var card=event.card; - if(card.name!='sha'&&get.type(card)!='trick')return false; - var info=get.info(card); - if(info.allowMultiple==false) return false; - if(!player.countCards('h')) return false; - if(!info.multitarget){ - if(game.hasPlayer(function(current){ - return !event.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&lib.filter.targetInRange(card,player,current); - })){ + boss_keding: { + trigger: { player: "useCard2" }, + direct: true, + filter: function (event, player) { + if (!event.targets || event.targets.length != 1) return false; + var card = event.card; + if (card.name != "sha" && get.type(card) != "trick") return false; + var info = get.info(card); + if (info.allowMultiple == false) return false; + if (!player.countCards("h")) return false; + if (!info.multitarget) { + if ( + game.hasPlayer(function (current) { + return ( + !event.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + lib.filter.targetInRange(card, player, current) + ); + }) + ) { return true; } } return false; }, - content:function(){ - 'step 0' - var card=trigger.card; - var prompt2='弃置任意张手牌,并为'+get.translation(card)+'增加等量的目标'; - var targets=game.filterPlayer(function(current){ - return !trigger.targets.includes(current)&&lib.filter.targetEnabled2(card,player,current)&&lib.filter.targetInRange(card,player,current); + content: function () { + "step 0"; + var card = trigger.card; + var prompt2 = "弃置任意张手牌,并为" + get.translation(card) + "增加等量的目标"; + var targets = game.filterPlayer(function (current) { + return ( + !trigger.targets.includes(current) && + lib.filter.targetEnabled2(card, player, current) && + lib.filter.targetInRange(card, player, current) + ); }); - var max=0; - if(!trigger.targets[0].hasSkill('heiguangkai_skill')) max=targets.filter(function(target){ - return get.effect(target,card,player,player)>0; - }).length; + var max = 0; + if (!trigger.targets[0].hasSkill("heiguangkai_skill")) + max = targets.filter(function (target) { + return get.effect(target, card, player, player) > 0; + }).length; player.chooseCardTarget({ - prompt:get.prompt('boss_keding'), - prompt2:prompt2, - selectCard:function(){ - var player=_status.event.player; - var targets=_status.event.targets; - return [Math.max(1,ui.selected.targets.length),Math.min(targets.length,player.countCards('h'))]; + prompt: get.prompt("boss_keding"), + prompt2: prompt2, + selectCard: function () { + var player = _status.event.player; + var targets = _status.event.targets; + return [ + Math.max(1, ui.selected.targets.length), + Math.min(targets.length, player.countCards("h")), + ]; }, - selectTarget:function(){ + selectTarget: function () { return ui.selected.cards.length; }, - position:'h', - filterCard:lib.filter.cardDiscardable, - filterTarget:function(card,player,target){ + position: "h", + filterCard: lib.filter.cardDiscardable, + filterTarget: function (card, player, target) { return _status.event.targets.includes(target); }, - targets:targets, - ai1:function(card){ - if(ui.selected.cards.length>=_status.event.max) return 0; - return 5-get.value(card); + targets: targets, + ai1: function (card) { + if (ui.selected.cards.length >= _status.event.max) return 0; + return 5 - get.value(card); }, - ai2:function(target){ - if(target.hasSkill('heiguangkai_skill')) return 0; - var trigger=_status.event.getTrigger(); - var player=_status.event.player; - return get.effect(target,trigger.card,player,player); + ai2: function (target) { + if (target.hasSkill("heiguangkai_skill")) return 0; + var trigger = _status.event.getTrigger(); + var player = _status.event.player; + return get.effect(target, trigger.card, player, player); }, - max:max, + max: max, }); - 'step 1' - if(result.bool){ - player.logSkill('boss_keding',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("boss_keding", result.targets); player.discard(result.cards); trigger.targets.addArray(result.targets); } }, }, - boss_bashi:{ - filter:function(event,player){ - return event.player!=player&&event.card&&(event.card.name=='sha'||get.type(event.card)=='trick')&&!player.isTurnedOver(); + boss_bashi: { + filter: function (event, player) { + return ( + event.player != player && + event.card && + (event.card.name == "sha" || get.type(event.card) == "trick") && + !player.isTurnedOver() + ); }, - logTarget:'player', - check:function(event,player){ - if(event.getParent().excluded.includes(player)) return false; - if(get.attitude(player,event.player)>0){ + logTarget: "player", + check: function (event, player) { + if (event.getParent().excluded.includes(player)) return false; + if (get.attitude(player, event.player) > 0) { return false; } - if(get.tag(event.card,'respondSha')){ - if(player.countCards('h',{name:'sha'})==0){ + if (get.tag(event.card, "respondSha")) { + if (player.countCards("h", { name: "sha" }) == 0) { return true; } - } - else if(get.tag(event.card,'respondShan')){ - if(player.countCards('h',{name:'shan'})==0){ + } else if (get.tag(event.card, "respondShan")) { + if (player.countCards("h", { name: "shan" }) == 0) { return true; } - } - else if(get.tag(event.card,'damage')){ - if(event.card.name=='shuiyanqijunx') return player.countCards('e')<2; + } else if (get.tag(event.card, "damage")) { + if (event.card.name == "shuiyanqijunx") return player.countCards("e") < 2; return true; //if(player.countCards('h')<2) return true; } return false; }, - trigger:{target:'useCardToTargeted'}, - content:function(){ + trigger: { target: "useCardToTargeted" }, + content: function () { player.turnOver(); trigger.getParent().excluded.add(player); }, }, - boss_danjing:{ - trigger:{global:'dying'}, - filter:function(event,player){ - return player.hp>1&&event.player.hp<1&&event.player.isFriendOf(player); + boss_danjing: { + trigger: { global: "dying" }, + filter: function (event, player) { + return player.hp > 1 && event.player.hp < 1 && event.player.isFriendOf(player); }, - check:function(event,player){ - var target=event.player; - return get.attitude(player,target)>0&&lib.filter.cardSavable({name:'tao',isCard:true},player,target); + check: function (event, player) { + var target = event.player; + return ( + get.attitude(player, target) > 0 && + lib.filter.cardSavable({ name: "tao", isCard: true }, player, target) + ); }, - logTarget:'player', - content:function(){ - 'step 0' + logTarget: "player", + content: function () { + "step 0"; player.loseHp(); - 'step 1' - var card={name:'tao',isCard:true}; - if(lib.filter.cardSavable(card,player,trigger.player)) player.useCard(card,trigger.player); + "step 1"; + var card = { name: "tao", isCard: true }; + if (lib.filter.cardSavable(card, player, trigger.player)) + player.useCard(card, trigger.player); }, }, - boss_jiaoxie:{ - enable:'phaseUse', - usable:1, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return lib.skill.boss_jiaoxie.filterTarget(null,player,current); + boss_jiaoxie: { + enable: "phaseUse", + usable: 1, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return lib.skill.boss_jiaoxie.filterTarget(null, player, current); }); }, - filterTarget:function(card,player,target){ - return target.isEnemyOf(player)&&target.type=='mech'&&target.countCards('he')>0; + filterTarget: function (card, player, target) { + return target.isEnemyOf(player) && target.type == "mech" && target.countCards("he") > 0; }, - content:function(){ - 'step 0' - if(!target.countCards('he')) event.finish(); - else target.chooseCard('he',true,'将一张牌交给'+get.translation(player)); - 'step 1' - if(result.bool){ - player.gain(result.cards,target,'give'); + content: function () { + "step 0"; + if (!target.countCards("he")) event.finish(); + else target.chooseCard("he", true, "将一张牌交给" + get.translation(player)); + "step 1"; + if (result.bool) { + player.gain(result.cards, target, "give"); } }, - ai:{ - order:9, - result:{ - target:function(player,target){ - if(target.countCards('e',function(card){ - return get.value(card,target)<=0; - })>0) return 1; + ai: { + order: 9, + result: { + target: function (player, target) { + if ( + target.countCards("e", function (card) { + return get.value(card, target) <= 0; + }) > 0 + ) + return 1; return -1; }, }, }, }, - boss_didongjg:{ - trigger:{player:'phaseEnd'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('boss_didongjg'),function(card,player,target){ + boss_didongjg: { + trigger: { player: "phaseEnd" }, + direct: true, + content: function () { + "step 0"; + player.chooseTarget(get.prompt("boss_didongjg"), function (card, player, target) { return target.isEnemyOf(player); - }).ai=function(target){ - var att=get.attitude(player,target); - if(target.isTurnedOver()){ - if(att>0){ - return att+5; + }).ai = function (target) { + var att = get.attitude(player, target); + if (target.isTurnedOver()) { + if (att > 0) { + return att + 5; } return -1; } - if(player.isTurnedOver()){ - return 5-att; + if (player.isTurnedOver()) { + return 5 - att; } return -att; }; - "step 1" - if(result.bool){ - player.logSkill('boss_didongjg',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("boss_didongjg", result.targets); result.targets[0].turnOver(); } }, - ai:{ - threaten:1.7 - } + ai: { + threaten: 1.7, + }, }, - boss_lianyujg:{ - trigger:{player:'phaseEnd'}, - unique:true, - content:function(){ - "step 0" - event.players=game.filterPlayer(function(current){ + boss_lianyujg: { + trigger: { player: "phaseEnd" }, + unique: true, + content: function () { + "step 0"; + event.players = game.filterPlayer(function (current) { return current.isEnemyOf(player); }); - "step 1" - if(event.players.length){ - var current=event.players.shift(); - player.line(current,'fire'); - current.damage('fire'); + "step 1"; + if (event.players.length) { + var current = event.players.shift(); + player.line(current, "fire"); + current.damage("fire"); event.redo(); } }, - ai:{ - threaten:2 - } + ai: { + threaten: 2, + }, }, - boss_mojianjg:{ - trigger:{player:'phaseUseBegin'}, - content:function(){ - var list=game.filterPlayer(function(current){ - return player.canUse('wanjian',current)&¤t.isEnemyOf(player); + boss_mojianjg: { + trigger: { player: "phaseUseBegin" }, + content: function () { + var list = game.filterPlayer(function (current) { + return player.canUse("wanjian", current) && current.isEnemyOf(player); }); list.sort(lib.sort.seat); - player.useCard({name:'wanjian'},list); + player.useCard({ name: "wanjian" }, list); + }, + ai: { + threaten: 1.8, }, - ai:{ - threaten:1.8 - } }, - boss_qiwu:{ - audio:true, - trigger:{player:'useCard'}, - direct:true, - filter:function(event,player){ - if(get.suit(event.card)=='club'){ - return game.hasPlayer(function(current){ - return current.isFriendOf(player)&¤t.isDamaged(); + boss_qiwu: { + audio: true, + trigger: { player: "useCard" }, + direct: true, + filter: function (event, player) { + if (get.suit(event.card) == "club") { + return game.hasPlayer(function (current) { + return current.isFriendOf(player) && current.isDamaged(); }); } return false; }, - content:function(){ - "step 0" - var noneed=(trigger.card.name=='tao'&&trigger.targets[0]==player&&player.hp==player.maxHp-1); - player.chooseTarget(get.prompt('boss_qiwu'),function(card,player,target){ - return target.hp0){ - if(noneed&&player==target){ - num=0.5; - } - else if(target.hp==1){ - num+=3; - } - else if(target.hp==2){ - num+=1; + content: function () { + "step 0"; + var noneed = + trigger.card.name == "tao" && + trigger.targets[0] == player && + player.hp == player.maxHp - 1; + player.chooseTarget(get.prompt("boss_qiwu"), function (card, player, target) { + return target.hp < target.maxHp && target.isFriendOf(player); + }).ai = function (target) { + var num = get.attitude(player, target); + if (num > 0) { + if (noneed && player == target) { + num = 0.5; + } else if (target.hp == 1) { + num += 3; + } else if (target.hp == 2) { + num += 1; } } return num; - } - "step 1" - if(result.bool){ - player.logSkill('qiwu',result.targets); + }; + "step 1"; + if (result.bool) { + player.logSkill("qiwu", result.targets); result.targets[0].recover(); } }, - ai:{ - expose:0.3, - threaten:1.5 - } + ai: { + expose: 0.3, + threaten: 1.5, + }, }, - boss_tianyujg:{ - audio:true, - trigger:{player:'phaseEnd'}, - forced:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.isEnemyOf(player)&&!current.isLinked(); + boss_tianyujg: { + audio: true, + trigger: { player: "phaseEnd" }, + forced: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.isEnemyOf(player) && !current.isLinked(); }); }, - content:function(){ - "step 0" - event.targets=game.filterPlayer(); + content: function () { + "step 0"; + event.targets = game.filterPlayer(); event.targets.sort(lib.sort.seat); - "step 1" - if(event.targets.length){ - var target=event.targets.shift(); - if(!target.isLinked()&&target.isEnemyOf(player)){ - player.line(target,'green'); + "step 1"; + if (event.targets.length) { + var target = event.targets.shift(); + if (!target.isLinked() && target.isEnemyOf(player)) { + player.line(target, "green"); target.link(); } event.redo(); } - } + }, }, - boss_jueji:{ - audio:2, - trigger:{global:'phaseDrawBegin'}, - filter:function(event,player){ - if(event.player.isFriendOf(player)){ + boss_jueji: { + audio: 2, + trigger: { global: "phaseDrawBegin" }, + filter: function (event, player) { + if (event.player.isFriendOf(player)) { return false; } - return event.num>0&&event.player!=player&&event.player.hp 0 && event.player != player && event.player.hp < event.player.maxHp; }, - logTarget:'player', - content:function(){ - player.line(trigger.player,'green'); + logTarget: "player", + content: function () { + player.line(trigger.player, "green"); trigger.num--; }, - ai:{ - expose:0.2, - threaten:1.4 - } + ai: { + expose: 0.2, + threaten: 1.4, + }, }, - boss_huodi:{ - audio:2, - trigger:{player:'phaseEnd'}, - direct:true, - filter:function(event,player){ - return game.hasPlayer(function(current){ - return current.isFriendOf(player)&¤t.isTurnedOver(); + boss_huodi: { + audio: 2, + trigger: { player: "phaseEnd" }, + direct: true, + filter: function (event, player) { + return game.hasPlayer(function (current) { + return current.isFriendOf(player) && current.isTurnedOver(); }); }, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('boss_huodi'),function(card,player,target){ + content: function () { + "step 0"; + player.chooseTarget(get.prompt("boss_huodi"), function (card, player, target) { return !target.isFriendOf(player); - }).ai=function(target){ - if(target.isTurnedOver()) return 0; - return -get.attitude(player,target); + }).ai = function (target) { + if (target.isTurnedOver()) return 0; + return -get.attitude(player, target); }; - "step 1" - if(result.bool){ - player.logSkill('boss_huodi',result.targets); + "step 1"; + if (result.bool) { + player.logSkill("boss_huodi", result.targets); result.targets[0].turnOver(); } }, - ai:{ - expose:0.2 - } + ai: { + expose: 0.2, + }, }, - boss_chuanyun:{ - audio:true, - trigger:{player:'phaseEnd'}, - direct:true, - content:function(){ - "step 0" - player.chooseTarget(get.prompt('boss_chuanyun'),function(card,player,target){ - return player.hp=0; + return num >= 0; }, - forced:true, - content:function(){ - 'step 0' - var targets=game.filterPlayer(function(current){ + forced: true, + content: function () { + "step 0"; + var targets = game.filterPlayer(function (current) { return current.isEnemyOf(player); }); targets.sort(lib.sort.seat); - event.targets=targets; - player.line(targets,'thunder'); - event.num=targets.length; - 'step 1' - if(event.targets.length){ - event.targets.shift().damage('thunder'); + event.targets = targets; + player.line(targets, "thunder"); + event.num = targets.length; + "step 1"; + if (event.targets.length) { + event.targets.shift().damage("thunder"); event.redo(); } - 'step 2' + "step 2"; player.recover(event.num); }, - ai:{ - threaten:function(player,target){ - if(target.hp==1) return 2; - if(target.hp==2&&game.players.length<8) return 1.5; + ai: { + threaten: function (player, target) { + if (target.hp == 1) return 2; + if (target.hp == 2 && game.players.length < 8) return 1.5; return 0.5; }, - } + }, }, - boss_chiying:{ - audio:2, - trigger:{global:'damageBegin4'}, - forced:true, - filter:function(event,player){ - if(event.num<=1) return false; + boss_chiying: { + audio: 2, + trigger: { global: "damageBegin4" }, + forced: true, + filter: function (event, player) { + if (event.num <= 1) return false; return event.player.isFriendOf(player); }, - content:function(){ - trigger.num=1; - } + content: function () { + trigger.num = 1; + }, }, - boss_jingfan:{ - global:'boss_jingfan2', + boss_jingfan: { + global: "boss_jingfan2", }, - boss_jingfan2:{ - mod:{ - globalFrom:function(from,to,distance){ - if(to.isEnemyOf(from)) return; - var players=game.filterPlayer(); - for(var i=0;i0){ - if(players[i].hp==1){ + boss_lingyu: { + trigger: { player: "phaseEnd" }, + check: function (event, player) { + if (player.isTurnedOver()) return true; + var num = 0, + players = game.filterPlayer(); + for (var i = 0; i < players.length; i++) { + if ( + players[i].hp < players[i].maxHp && + players[i].isFriendOf(player) && + get.recoverEffect(players[i]) > 0 + ) { + if (players[i].hp == 1) { return true; } num++; - if(num>=2) return true; + if (num >= 2) return true; } } return false; }, - content:function(){ - 'step 0' + content: function () { + "step 0"; player.turnOver(); - 'step 1' - var list=game.filterPlayer(function(current){ - return current.isDamaged()&¤t.isFriendOf(player); + "step 1"; + var list = game.filterPlayer(function (current) { + return current.isDamaged() && current.isFriendOf(player); }); - player.line(list,'green'); - event.targets=list; - 'step 2' - if(event.targets.length){ + player.line(list, "green"); + event.targets = list; + "step 2"; + if (event.targets.length) { event.targets.shift().recover(); event.redo(); } }, - ai:{ - threaten:1.5, - effect:{ - target:function(card,player,target){ - if(card.name=='guiyoujie') return [0,1]; - } - } + ai: { + threaten: 1.5, + effect: { + target: function (card, player, target) { + if (card.name == "guiyoujie") return [0, 1]; + }, + }, }, }, - boss_zhenwei:{ - global:'boss_zhenwei2', - ai:{ - threaten:1.5 - } + boss_zhenwei: { + global: "boss_zhenwei2", + ai: { + threaten: 1.5, + }, }, - boss_zhenwei2:{ - mod:{ - globalTo:function(from,to,distance){ - if(to.isFriendOf(from)) return; - var players=game.filterPlayer(); - for(var i=0;i0.4?2:3,'thunder'); + if (target) { + player.line(target, "thunder"); + target.damage(Math.random() > 0.4 ? 2 : 3, "thunder"); } }, - ai:{ - threaten:function(player,target){ - if(_status.mode=='jiange'){ - for(var i=0;i0; + if (_status.mode == "jiange") { + for (var i = 0; i < players.length; i++) { + if (players[i].isFriendOf(player) && players[i].hasSkill("huodi")) { + return num > 0; } } } - return num>=4; + return num >= 4; }, - filter:function(event,player){ - var players=game.filterPlayer(); - for(var i=0;i0; + filter: function (event, player) { + return player.countCards("h") > 0; + }, + content: function () { + player.chooseToDiscard("h", true); }, - content:function(){ - player.chooseToDiscard('h',true); - } }, - boss_tunshi:{ - trigger:{player:'phaseBegin'}, - forced:true, - filter:function(event,player){ - var nh=player.countCards('h'); - return game.hasPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('h')>nh; + boss_tunshi: { + trigger: { player: "phaseBegin" }, + forced: true, + filter: function (event, player) { + var nh = player.countCards("h"); + return game.hasPlayer(function (current) { + return current.isEnemyOf(player) && current.countCards("h") > nh; }); }, - content:function(){ - 'step 0' - var nh=player.countCards('h'); - var targets=game.filterPlayer(function(current){ - return current.isEnemyOf(player)&¤t.countCards('h')>nh; + content: function () { + "step 0"; + var nh = player.countCards("h"); + var targets = game.filterPlayer(function (current) { + return current.isEnemyOf(player) && current.countCards("h") > nh; }); targets.sort(lib.sort.seat); - event.targets=targets; - 'step 1' - if(event.targets.length){ - var current=event.targets.shift(); + event.targets = targets; + "step 1"; + if (event.targets.length) { + var current = event.targets.shift(); current.damage(); - player.line(current,'thunder'); + player.line(current, "thunder"); event.redo(); } - } + }, }, - boss_jiguan:{ - mod:{ - targetEnabled:function(card,player,target){ - if(card.name=='lebu'){ + boss_jiguan: { + mod: { + targetEnabled: function (card, player, target) { + if (card.name == "lebu") { return false; } - } - } + }, + }, }, - boss_gongshenjg:{ - audio:2, - trigger:{player:'phaseEnd'}, - mode:['versus'], - filter:function(event,player){ - if(_status.mode!='jiange') return false; - var players=game.filterPlayer(); - for(var i=0;i0&&target.hasJudge('lebu')){ + next.ai = function (target) { + var att = get.attitude(player, target); + if (att > 0 && target.hasJudge("lebu")) { return 0.1; } - if(player.countCards('h')>player.hp){ - if(target==player) return Math.max(1,att-2); + if (player.countCards("h") > player.hp) { + if (target == player) return Math.max(1, att - 2); } - if(target==player) return att+5; + if (target == player) return att + 5; return att; - } + }; } - "step 2" - if(result&&result.targets&&result.targets.length){ - event.target=result.targets[0]; + "step 2"; + if (result && result.targets && result.targets.length) { + event.target = result.targets[0]; } - if(event.cards2.length){ - player.line(event.target,'green'); - event.target.gain(event.cards2,'gain2','log'); + if (event.cards2.length) { + player.line(event.target, "green"); + event.target.gain(event.cards2, "gain2", "log"); } }, - ai:{ - threaten:1.3 - } + ai: { + threaten: 1.3, + }, }, - boss_biantian4:{ - trigger:{player:'dieBegin'}, - forced:true, - popup:false, - content:function(){ - for(var i=0;i-3) return 0; - var eff=get.damageEffect(target,player,player,'fire'); - if(eff>0){ - return eff+target.countCards('e')/2; + }).ai = function (target) { + if (player.hp <= 1) return 0; + if (get.attitude(player, target) > -3) return 0; + var eff = get.damageEffect(target, player, player, "fire"); + if (eff > 0) { + return eff + target.countCards("e") / 2; } return 0; - } - "step 1" - if(result.bool){ - player.logSkill('boss_tianyun',result.targets,'fire'); + }; + "step 1"; + if (result.bool) { + player.logSkill("boss_tianyun", result.targets, "fire"); player.loseHp(); - event.target=result.targets[0]; - } - else{ + event.target = result.targets[0]; + } else { event.finish(); } - "step 2" - if(event.target){ - event.target.damage(Math.random()>0.4?2:3,'fire'); + "step 2"; + if (event.target) { + event.target.damage(Math.random() > 0.4 ? 2 : 3, "fire"); } - "step 3" - if(event.target){ - var es=event.target.getCards('e'); - if(es.length){ + "step 3"; + if (event.target) { + var es = event.target.getCards("e"); + if (es.length) { event.target.discard(es); } } }, - ai:{ - threaten:2 - } - }, - versus_ladder:{ - trigger:{global:['damageEnd','recoverEnd','dieEnd','gainEnd','phaseDiscardEnd']}, - silent:true, - filter:function(event,player){ - if(!_status.ladder) return false; - if(event._ladder_mmr_counted) return false; - if(!event.source) return false; - return event.source==game.me||event.player==game.me; + ai: { + threaten: 2, }, - content:function(){ - switch(event.triggername){ - case 'damageEnd':{ - if(trigger.source.side!=trigger.player.side){ - if(trigger.source==game.me){ - _status.ladder_mmr+=0.5*Math.max(1,trigger.num); - } - else{ - _status.ladder_mmr+=0.2*Math.max(1,trigger.num); + }, + versus_ladder: { + trigger: { global: ["damageEnd", "recoverEnd", "dieEnd", "gainEnd", "phaseDiscardEnd"] }, + silent: true, + filter: function (event, player) { + if (!_status.ladder) return false; + if (event._ladder_mmr_counted) return false; + if (!event.source) return false; + return event.source == game.me || event.player == game.me; + }, + content: function () { + switch (event.triggername) { + case "damageEnd": { + if (trigger.source.side != trigger.player.side) { + if (trigger.source == game.me) { + _status.ladder_mmr += 0.5 * Math.max(1, trigger.num); + } else { + _status.ladder_mmr += 0.2 * Math.max(1, trigger.num); } } break; } - case 'recoverEnd':{ - if(trigger.source!=trigger.player){ - if(trigger.source==game.me){ - if(trigger.player.side==game.me.side){ - _status.ladder_mmr+=0.5*trigger.num; - } - else{ - _status.ladder_mmr-=0.3*trigger.num; + case "recoverEnd": { + if (trigger.source != trigger.player) { + if (trigger.source == game.me) { + if (trigger.player.side == game.me.side) { + _status.ladder_mmr += 0.5 * trigger.num; + } else { + _status.ladder_mmr -= 0.3 * trigger.num; } } - } - else{ - _status.ladder_mmr+=0.3*trigger.num; + } else { + _status.ladder_mmr += 0.3 * trigger.num; } break; } - case 'dieEnd':{ - if(trigger.source==game.me&&trigger.player.side!=game.me.side){ - _status.ladder_mmr+=2; + case "dieEnd": { + if (trigger.source == game.me && trigger.player.side != game.me.side) { + _status.ladder_mmr += 2; } break; } - case 'gainEnd':{ - if(trigger.cards&&trigger.cards.length){ - if(trigger.source==game.me&&trigger.player!=game.me){ - if(trigger.player.side==game.me.side){ - _status.ladder_mmr+=0.3*trigger.cards.length; + case "gainEnd": { + if (trigger.cards && trigger.cards.length) { + if (trigger.source == game.me && trigger.player != game.me) { + if (trigger.player.side == game.me.side) { + _status.ladder_mmr += 0.3 * trigger.cards.length; + } else { + _status.ladder_mmr -= 0.1 * trigger.cards.length; } - else{ - _status.ladder_mmr-=0.1*trigger.cards.length; - } - } - else{ - if(trigger.source){ - if(trigger.source.side!=game.me.side){ - _status.ladder_mmr+=0.3*trigger.cards.length; + } else { + if (trigger.source) { + if (trigger.source.side != game.me.side) { + _status.ladder_mmr += 0.3 * trigger.cards.length; } - } - else{ - _status.ladder_mmr+=0.1*trigger.cards.length; + } else { + _status.ladder_mmr += 0.1 * trigger.cards.length; } } } break; } - case 'phaseDiscardEnd':{ - if(trigger.player==player){ - if(trigger.cards&&trigger.cards.length){ - _status.ladder_mmr-=0.2*trigger.cards.length; + case "phaseDiscardEnd": { + if (trigger.player == player) { + if (trigger.cards && trigger.cards.length) { + _status.ladder_mmr -= 0.2 * trigger.cards.length; } } break; } } - trigger._ladder_mmr_counted=true; - } - } + trigger._ladder_mmr_counted = true; + }, + }, }, - card:{ - tunliang:{ - audio:true, - fullskin:true, - type:'trick', - enable:true, - selectTarget:[1,3], - filterTarget:true, - content:function(){ + card: { + tunliang: { + audio: true, + fullskin: true, + type: "trick", + enable: true, + selectTarget: [1, 3], + filterTarget: true, + content: function () { target.draw(); }, - ai:{ - basic:{ - order:7.2, - useful:4.5, - value:9.2 + ai: { + basic: { + order: 7.2, + useful: 4.5, + value: 9.2, }, - result:{ - target:1, + result: { + target: 1, + }, + tag: { + draw: 1, }, - tag:{ - draw:1 - } - } - }, - yuanjun:{ - fullskin:true, - type:'trick', - selectTarget:[1,2], - enable:true, - filterTarget:function(card,player,target){ - return target!=player&&target.hp{ - var cards=player.getCards('hs',card=>get.tag(card,'damage')&&player.hasValueTarget(card)); - if(!cards.length) return 0; - var cardx=cards.filter(card=>get.name(card)=='sha'); - cardx.sort((a,b)=>player.getUseValue(b)-player.getUseValue(a)); - cardx=cardx.slice(Math.min(cardx.length,player.getCardUsable('sha')),cardx.length); + ai: { + basic: { + order: (item, player) => { + var cards = player.getCards( + "hs", + (card) => get.tag(card, "damage") && player.hasValueTarget(card) + ); + if (!cards.length) return 0; + var cardx = cards.filter((card) => get.name(card) == "sha"); + cardx.sort((a, b) => player.getUseValue(b) - player.getUseValue(a)); + cardx = cardx.slice( + Math.min(cardx.length, player.getCardUsable("sha")), + cardx.length + ); cards.removeArray(cardx); - return get.order(cards.sort((a,b)=>get.order(b,player)-get.order(a,player))[0])+0.3; + return ( + get.order( + cards.sort((a, b) => get.order(b, player) - get.order(a, player))[0] + ) + 0.3 + ); }, - useful:5, - value:3, + useful: 5, + value: 3, }, - result:{ - target:(player,target)=>{ - if(target.hasSkill('gangzhi')||get.attitude(player,target)>=0) return 0; - var cards=player.getCards('hs',card=>get.tag(card,'damage')&&player.canUse(card,target)&&get.effect(target,card,player,player)>0); - if(!cards.length) return 0; - var cardx=cards.filter(card=>get.name(card)=='sha'); - cardx.sort((a,b)=>get.effect(target,b,player,player)-get.effect(target,a,player,player)); - cardx=cardx.slice(Math.min(cardx.length,player.getCardUsable('sha')),cardx.length); + result: { + target: (player, target) => { + if (target.hasSkill("gangzhi") || get.attitude(player, target) >= 0) return 0; + var cards = player.getCards( + "hs", + (card) => + get.tag(card, "damage") && + player.canUse(card, target) && + get.effect(target, card, player, player) > 0 + ); + if (!cards.length) return 0; + var cardx = cards.filter((card) => get.name(card) == "sha"); + cardx.sort( + (a, b) => + get.effect(target, b, player, player) - + get.effect(target, a, player, player) + ); + cardx = cardx.slice( + Math.min(cardx.length, player.getCardUsable("sha")), + cardx.length + ); cards.removeArray(cardx); - return -cards.reduce((sum,card)=>sum+get.effect(target,card,player,player),0); + return -cards.reduce( + (sum, card) => sum + get.effect(target, card, player, player), + 0 + ); }, }, }, }, - zong:{ - fullskin:true, - type:'basic', - cardcolor:'red', - enable:function(card,player){ - return player.hp= 2 && target.countCards("h", "tao") <= 1) { + keep = true; } - else if(nd==1&&target.hp>=2&&target.countCards('h','tao')<=1){ - keep=true; - } - var mode=get.mode(); - if(target.hp>=2&&keep&&target.hasFriend()){ - if(target.hp>2||nd==0) return 0; - if(target.hp==2){ - if(game.hasPlayer(function(current){ - if(target!=current&&get.attitude(target,current)>=3){ - if(current.hp<=1) return true; - } - })){ + var mode = get.mode(); + if (target.hp >= 2 && keep && target.hasFriend()) { + if (target.hp > 2 || nd == 0) return 0; + if (target.hp == 2) { + if ( + game.hasPlayer(function (current) { + if (target != current && get.attitude(target, current) >= 3) { + if (current.hp <= 1) return true; + } + }) + ) { return 0; } } @@ -6660,246 +7656,263 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ return 2; }, }, - tag:{ - recover:1, - save:1, - } - } + tag: { + recover: 1, + save: 1, + }, + }, }, - xionghuangjiu:{ - fullskin:true, - type:"basic", - enable:function(event,player){ - return !player.hasSkill('jiu')&&!player.hasSkill('xionghuangjiu'); + xionghuangjiu: { + fullskin: true, + type: "basic", + enable: function (event, player) { + return !player.hasSkill("jiu") && !player.hasSkill("xionghuangjiu"); }, - lianheng:true, - logv:false, - savable:function(card,player,dying){ - return dying==player; + lianheng: true, + logv: false, + savable: function (card, player, dying) { + return dying == player; }, - usable:1, - selectTarget:-1, - modTarget:true, - filterTarget:function(card,player,target){ - return target==player; + usable: 1, + selectTarget: -1, + modTarget: true, + filterTarget: function (card, player, target) { + return target == player; }, - content:function(){ - if(target.isDying()){ + content: function () { + if (target.isDying()) { target.recover(); - if(_status.currentPhase==target){ + if (_status.currentPhase == target) { target.getStat().card.jiu--; } - } - else{ - if(cards&&cards.length){ - card=cards[0]; + } else { + if (cards && cards.length) { + card = cards[0]; } - game.broadcastAll(function(target,card,gain2){ - if(get.population(target.side)==1){ - target.addSkill('xionghuangjiu'); - } - else{ - if(!target.storage.jiu) target.storage.jiu=0; - target.storage.jiu++; - target.addSkill('jiu'); - } - game.addVideo('jiuNode',target,true); - if(!target.node.jiu&&lib.config.jiu_effect){ - target.node.jiu=ui.create.div('.playerjiu',target.node.avatar); - target.node.jiu2=ui.create.div('.playerjiu',target.node.avatar2); - } - if(gain2&&card.clone&&(card.clone.parentNode==target.parentNode||card.clone.parentNode==ui.arena)){ - card.clone.moveDelete(target); - } - },target,card,target==targets[0]); - if(target==targets[0]){ - if(card.clone&&(card.clone.parentNode==target.parentNode||card.clone.parentNode==ui.arena)){ - game.addVideo('gain2',target,get.cardsInfo([card])); + game.broadcastAll( + function (target, card, gain2) { + if (get.population(target.side) == 1) { + target.addSkill("xionghuangjiu"); + } else { + if (!target.storage.jiu) target.storage.jiu = 0; + target.storage.jiu++; + target.addSkill("jiu"); + } + game.addVideo("jiuNode", target, true); + if (!target.node.jiu && lib.config.jiu_effect) { + target.node.jiu = ui.create.div(".playerjiu", target.node.avatar); + target.node.jiu2 = ui.create.div(".playerjiu", target.node.avatar2); + } + if ( + gain2 && + card.clone && + (card.clone.parentNode == target.parentNode || + card.clone.parentNode == ui.arena) + ) { + card.clone.moveDelete(target); + } + }, + target, + card, + target == targets[0] + ); + if (target == targets[0]) { + if ( + card.clone && + (card.clone.parentNode == target.parentNode || + card.clone.parentNode == ui.arena) + ) { + game.addVideo("gain2", target, get.cardsInfo([card])); } } } }, - ai:{ - basic:{ - useful:function(card,i){ - if(_status.event.player.hp>1){ - if(i==0) return 5; + ai: { + basic: { + useful: function (card, i) { + if (_status.event.player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 3; }, - value:function(card,player,i){ - if(player.hp>1){ - if(i==0) return 5; + value: function (card, player, i) { + if (player.hp > 1) { + if (i == 0) return 5; return 1; } - if(i==0) return 7.3; + if (i == 0) return 7.3; return 3; }, }, - order:function(){ - return get.order({name:'sha'})+0.2; + order: function () { + return get.order({ name: "sha" }) + 0.2; }, - result:{ - target:function(player,target){ - if(target&&target.isDying()) return 2; - if(lib.config.mode=='stone'&&!player.isMin()){ - if(player.getActCount()+1>=player.actcount) return 0; + result: { + target: function (player, target) { + if (target && target.isDying()) return 2; + if (lib.config.mode == "stone" && !player.isMin()) { + if (player.getActCount() + 1 >= player.actcount) return 0; } - var shas=player.getCards('h','sha'); - if(shas.length>1&&player.getCardUsable('sha')>1){ + var shas = player.getCards("h", "sha"); + if (shas.length > 1 && player.getCardUsable("sha") > 1) { return 0; } var card; - if(shas.length){ - for(var i=0;i0); - })){ + if (card) { + if ( + game.hasPlayer(function (current) { + return ( + get.attitude(target, current) < 0 && + target.canUse(card, current, true, true) && + !current.getEquip("baiyin") && + get.effect(current, card, target) > 0 + ); + }) + ) { return 1; } } return 0; }, }, - tag:{ - save:1 - } - } + tag: { + save: 1, + }, + }, }, - tongzhougongji:{ - fullskin:true, - cardimage:'lulitongxin', - notarget:true, - enable:true, - type:'trick', - content:function(){ - 'step 0' - var num=0; - for(var i=0;i2){ - return 0; - } - if(num==2&&get.population(player.side)==1){ - return 0; - } - return 1; - }).set('choiceList',[ - '摸'+get.cnNumber(num)+'张牌', - '你和队友各摸一张牌' - ]); - event.num=num; - 'step 1' - if(result.index==0){ - if(event.num){ + player + .chooseControl(function () { + if (num > 2) { + return 0; + } + if (num == 2 && get.population(player.side) == 1) { + return 0; + } + return 1; + }) + .set("choiceList", ["摸" + get.cnNumber(num) + "张牌", "你和队友各摸一张牌"]); + event.num = num; + "step 1"; + if (result.index == 0) { + if (event.num) { player.draw(event.num); } - } - else{ - if(event.friend){ + } else { + if (event.friend) { player.line(event.friend); - game.asyncDraw([player,event.friend]); - } - else{ + game.asyncDraw([player, event.friend]); + } else { player.draw(); } } }, - ai:{ - basic:{ - order:7.2, - useful:4, - value:9.2 + ai: { + basic: { + order: 7.2, + useful: 4, + value: 9.2, }, - result:{ - target:2, + result: { + target: 2, }, - tag:{ - draw:1 - } - } + tag: { + draw: 1, + }, + }, }, - lizhengshangyou:{ - fullskin:true, - cardimage:'lianjunshengyan', - type:'trick', - enable:true, - selectTarget:-1, - reverseOrder:true, - filterTarget:function(card,player,target){ - for(var i=0;i1&&(game.me==game.friendZhu||(lib.storage.zhu&&lib.storage.single_control))&& - !_status.auto){ - event.dialog=ui.create.dialog('选择替补角色',[list,'character']); - event.filterButton=function(){return true;}; - event.player=game.me; - event.forced=true; - event.custom.replace.confirm=function(){ - event.character=ui.selected.buttons[0].link; + if ( + source.side == game.me.side && + list.length > 1 && + (game.me == game.friendZhu || (lib.storage.zhu && lib.storage.single_control)) && + !_status.auto + ) { + event.dialog = ui.create.dialog("选择替补角色", [list, "character"]); + event.filterButton = function () { + return true; + }; + event.player = game.me; + event.forced = true; + event.custom.replace.confirm = function () { + event.character = ui.selected.buttons[0].link; event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; game.resume(); - } + }; game.check(); game.pause(); + } else { + event.character = list[Math.floor(Math.random() * list.length)]; } - else{ - event.character=list[Math.floor(Math.random()*list.length)]; - } - "step 2" + "step 2"; game.uncheck(); _status.friend.remove(event.character); _status.enemy.remove(event.character); - source.revive(null,false); + source.revive(null, false); game.additionaldead.push({ - name:source.name, - stat:source.stat + name: source.name, + stat: source.stat, }); - game.addVideo('reinit',source,[event.character,get.translation(source.side+'Color')]); + game.addVideo("reinit", source, [ + event.character, + get.translation(source.side + "Color"), + ]); source.uninit(); source.init(event.character); - game.log(source,'出场'); - source.node.identity.dataset.color=get.translation(source.side+'Color'); + game.log(source, "出场"); + source.node.identity.dataset.color = get.translation(source.side + "Color"); source.draw(4); - var evt=event.getParent('dying'); - if(evt&&evt.parent){ - evt=evt.parent; - evt.untrigger(false,source); - for(var i=0;i<100;i++){ - evt=evt.parent; - if(evt.player==source){ + var evt = event.getParent("dying"); + if (evt && evt.parent) { + evt = evt.parent; + evt.untrigger(false, source); + for (var i = 0; i < 100; i++) { + evt = evt.parent; + if (evt.player == source) { evt.finish(); } - if(evt.name=='phase'){ + if (evt.name == "phase") { break; } } } - if(lib.storage.single_control){ + if (lib.storage.single_control) { game.onSwapControl(); } game.triggerEnter(source); - "step 3" + "step 3"; // if(_status.currentPhase==source){ // source.skip('phase'); // } }, - replacePlayerTwo:function(){ - 'step 0' - var cards=source.getCards('hej'); - if(cards.length){ - source.$throw(cards,1000); + replacePlayerTwo: function () { + "step 0"; + var cards = source.getCards("hej"); + if (cards.length) { + source.$throw(cards, 1000); game.cardsDiscard(cards); } game.delay(); - 'step 1' - source.revive(null,false); + "step 1"; + source.revive(null, false); game.additionaldead.push({ - name:source.name, - stat:source.stat + name: source.name, + stat: source.stat, }); - game.addVideo('reinit',source,[event.character,get.translation(source.side+'Color')]); + game.addVideo("reinit", source, [ + event.character, + get.translation(source.side + "Color"), + ]); source.uninit(); source.init(event.character); - game.log(source,'出场'); + game.log(source, "出场"); // source.node.identity.dataset.color=source.side+'zhu'; source.draw(4); - var evt=event.getParent('dying'); - if(evt&&evt.parent){ - evt=evt.parent; - evt.untrigger(false,source); - for(var i=0;i<100;i++){ - evt=evt.parent; - if(evt.player==source){ + var evt = event.getParent("dying"); + if (evt && evt.parent) { + evt = evt.parent; + evt.untrigger(false, source); + for (var i = 0; i < 100; i++) { + evt = evt.parent; + if (evt.player == source) { evt.finish(); } - if(evt.name=='phase'){ + if (evt.name == "phase") { break; } } } game.triggerEnter(source); }, - replacePlayerOL:function(){ - 'step 0' - var cards=source.getCards('hej'); - if(cards.length){ - source.$throw(cards,1000); + replacePlayerOL: function () { + "step 0"; + var cards = source.getCards("hej"); + if (cards.length) { + source.$throw(cards, 1000); game.cardsDiscard(cards); } game.delay(); - 'step 1' - if(event.source.side==game.me.side){ - if(_status.friend.length==1){ - event.directresult=_status.friend[0]; - } - else if(event.source==game.me){ - if(_status.auto){ - event.directresult=_status.friend.randomGet(); + "step 1"; + if (event.source.side == game.me.side) { + if (_status.friend.length == 1) { + event.directresult = _status.friend[0]; + } else if (event.source == game.me) { + if (_status.auto) { + event.directresult = _status.friend.randomGet(); + } + } else { + if (!event.source.isOnline()) { + event.directresult = _status.friend.randomGet(); } } - else{ - if(!event.source.isOnline()){ - event.directresult=_status.friend.randomGet(); + } else { + if (_status.enemy.length == 1) { + event.directresult = _status.enemy[0]; + } else { + if (!event.source.isOnline()) { + event.directresult = _status.enemy.randomGet(); } } } - else{ - if(_status.enemy.length==1){ - event.directresult=_status.enemy[0]; - } - else{ - if(!event.source.isOnline()){ - event.directresult=_status.enemy.randomGet(); - } - } - } - if(!event.directresult){ - if(event.source==game.me){ - event.dialog=ui.create.dialog('选择替补角色',[_status.friend,'character']); - event.filterButton=function(){return true}; - event.player=game.me; - event.forced=true; - event.custom.replace.confirm=function(){ - event.directresult=ui.selected.buttons[0].link; + if (!event.directresult) { + if (event.source == game.me) { + event.dialog = ui.create.dialog("选择替补角色", [_status.friend, "character"]); + event.filterButton = function () { + return true; + }; + event.player = game.me; + event.forced = true; + event.custom.replace.confirm = function () { + event.directresult = ui.selected.buttons[0].link; event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; game.resume(); - } - event.switchToAuto=function(){ - event.directresult=_status.friend.randomGet(); + }; + event.switchToAuto = function () { + event.directresult = _status.friend.randomGet(); event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; }; game.check(); game.pause(); - } - else{ - event.source.send(function(player){ - if(_status.auto){ - _status.event._result=_status.friend.randomGet(); - } - else{ - var next=game.createEvent('replacePlayer'); - next.source=player; - next.setContent(function(){ - event.dialog=ui.create.dialog('选择替补角色',[_status.friend,'character']); - event.filterButton=function(){return true}; - event.player=event.source; - event.forced=true; - event.custom.replace.confirm=function(){ - event.result=ui.selected.buttons[0].link; + } else { + event.source.send(function (player) { + if (_status.auto) { + _status.event._result = _status.friend.randomGet(); + } else { + var next = game.createEvent("replacePlayer"); + next.source = player; + next.setContent(function () { + event.dialog = ui.create.dialog("选择替补角色", [ + _status.friend, + "character", + ]); + event.filterButton = function () { + return true; + }; + event.player = event.source; + event.forced = true; + event.custom.replace.confirm = function () { + event.result = ui.selected.buttons[0].link; event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; game.resume(); game.uncheck(); - } - event.switchToAuto=function(){ - event.result=_status.friend.randomGet(); + }; + event.switchToAuto = function () { + event.result = _status.friend.randomGet(); event.dialog.close(); - if(ui.confirm) ui.confirm.close(); + if (ui.confirm) ui.confirm.close(); delete event.player; game.uncheck(); }; @@ -7103,509 +8132,499 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ }); } game.resume(); - },event.source); + }, event.source); event.source.wait(); game.pause(); } } - 'step 2' + "step 2"; game.uncheck(); - if(!event.directresult){ - if(event.resultOL){ - event.directresult=event.resultOL[source.playerid]; + if (!event.directresult) { + if (event.resultOL) { + event.directresult = event.resultOL[source.playerid]; } - if(!event.directresult||event.directresult=='ai'){ - if(source.side==game.me.side){ - event.directresult=_status.friend.randomGet(); - } - else{ - event.directresult=_status.enemy.randomGet(); + if (!event.directresult || event.directresult == "ai") { + if (source.side == game.me.side) { + event.directresult = _status.friend.randomGet(); + } else { + event.directresult = _status.enemy.randomGet(); } } } - var name=event.directresult; - var color=source.node.identity.dataset.color; + var name = event.directresult; + var color = source.node.identity.dataset.color; game.additionaldead.push({ - name:source.name, - stat:source.stat + name: source.name, + stat: source.stat, }); - game.broadcastAll(function(source,name,color){ - _status.friend.remove(name); - _status.enemy.remove(name); - source.revive(null,false); - source.uninit(); - source.init(name); - source.node.identity.dataset.color=color; - if(source==game.me){ - ui.arena.classList.remove('selecting'); - } - },source,name,color); - game.log(source,'出场'); + game.broadcastAll( + function (source, name, color) { + _status.friend.remove(name); + _status.enemy.remove(name); + source.revive(null, false); + source.uninit(); + source.init(name); + source.node.identity.dataset.color = color; + if (source == game.me) { + ui.arena.classList.remove("selecting"); + } + }, + source, + name, + color + ); + game.log(source, "出场"); source.draw(4); - var evt=event.getParent('dying'); - if(evt&&evt.parent){ - evt=evt.parent; - evt.untrigger(false,source); - for(var i=0;i<100;i++){ - evt=evt.parent; - if(evt.player==source){ + var evt = event.getParent("dying"); + if (evt && evt.parent) { + evt = evt.parent; + evt.untrigger(false, source); + for (var i = 0; i < 100; i++) { + evt = evt.parent; + if (evt.player == source) { evt.finish(); } - if(evt.name=='phase'){ + if (evt.name == "phase") { break; } } } - game.addVideo('reinit',source,[name,color]); + game.addVideo("reinit", source, [name, color]); game.triggerEnter(source); }, }, - player:{ - gainZhibao:function(num,source){ - if(source){ - if(num===true||num>source.storage.longchuanzhibao){ - num=source.storage.longchuanzhibao; + player: { + gainZhibao: function (num, source) { + if (source) { + if (num === true || num > source.storage.longchuanzhibao) { + num = source.storage.longchuanzhibao; + } + } else { + if (typeof num != "number") { + num = 1; } } - else{ - if(typeof num!='number'){ - num=1; - } - } - if(!num||typeof num!='number') return this; + if (!num || typeof num != "number") return this; - this.storage.longchuanzhibao+=num; - this.updateMark('longchuanzhibao'); + this.storage.longchuanzhibao += num; + this.updateMark("longchuanzhibao"); - if(source){ - source.storage.longchuanzhibao-=num; - source.updateMark('longchuanzhibao'); - game.log(this,'从',source,'处获得了'+get.cnNumber(num)+'个','#y龙船至宝'); - } - else{ - game.log(this,'获得了'+get.cnNumber(num)+'个','#y龙船至宝'); + if (source) { + source.storage.longchuanzhibao -= num; + source.updateMark("longchuanzhibao"); + game.log(this, "从", source, "处获得了" + get.cnNumber(num) + "个", "#y龙船至宝"); + } else { + game.log(this, "获得了" + get.cnNumber(num) + "个", "#y龙船至宝"); } - if(source&&source.side!=this.side){ - this.draw(num,'nodelay'); - var that=this; - var friend=game.findPlayer(function(current){ - return current.side==that.side&¤t!=that; + if (source && source.side != this.side) { + this.draw(num, "nodelay"); + var that = this; + var friend = game.findPlayer(function (current) { + return current.side == that.side && current != that; }); - if(friend){ - friend.draw(num,'nodelay'); + if (friend) { + friend.draw(num, "nodelay"); } } - var map={wei:0,shu:0,wu:0,qun:0}; - for(var i=0;i=4){ - current.classList.add('current_action'); - } - else{ - current.classList.remove('current_action'); + for (var i = 0; i < game.players.length; i++) { + var current = game.players[i]; + if (map[current.side] >= 4) { + current.classList.add("current_action"); + } else { + current.classList.remove("current_action"); } } return this; }, - dieAfter2:function(source){ - if(_status.connectMode&&_status.mode!='guandu'){ - if(_status.mode=='1v1'||_status.mode=='3v3') return; - else if(_status.mode=='2v2'){ + dieAfter2: function (source) { + if (_status.connectMode && _status.mode != "guandu") { + if (_status.mode == "1v1" || _status.mode == "3v3") return; + else if (_status.mode == "2v2") { var friend; - for(var i=0;i2)){ + var list = this.side == game.me.side ? _status.friend : _status.enemy; + if ( + (list.length == 0 && lib.storage.noreplace_end) || + (lib.storage.zhu && + lib.storage.main_zhu && + this.identity == "zhu" && + game.players.length > 2) + ) { return; - } - else if(game.friend.length==1&&this==game.friend[0]&&_status.friend.length==0){ + } else if ( + game.friend.length == 1 && + this == game.friend[0] && + _status.friend.length == 0 + ) { return; - } - else if(game.enemy.length==1&&this==game.enemy[0]&&_status.enemy.length==0){ + } else if ( + game.enemy.length == 1 && + this == game.enemy[0] && + _status.enemy.length == 0 + ) { return; - } - else{ - if(source){ - if(source.side!=this.side){ - if(lib.storage.versus_reward){ + } else { + if (source) { + if (source.side != this.side) { + if (lib.storage.versus_reward) { + source.draw(lib.storage.versus_reward); + } + } else { + if (lib.storage.versus_punish == "弃牌") { + source.discard(source.getCards("he")); + } else if ( + lib.storage.versus_punish == "摸牌" && + lib.storage.versus_reward + ) { source.draw(lib.storage.versus_reward); } } - else{ - if(lib.storage.versus_punish=='弃牌'){ - source.discard(source.getCards('he')); - } - else if(lib.storage.versus_punish=='摸牌'&&lib.storage.versus_reward){ - source.draw(lib.storage.versus_reward); - } - } - } - else{ + } else { game.delay(); } } } }, - dieAfter:function(source){ - if(_status.connectMode){ - if(_status.mode=='1v1'||_status.mode=='3v3'){ - game.broadcastAll(function(dead){ - if(dead.side==game.me.side){ + dieAfter: function (source) { + if (_status.connectMode) { + if (_status.mode == "1v1" || _status.mode == "3v3") { + game.broadcastAll(function (dead) { + if (dead.side == game.me.side) { _status.friendDied.push(dead.name1); - _status.friendCount.innerHTML='阵亡: '+get.cnNumber(_status.friendDied.length,true); - } - else{ + _status.friendCount.innerHTML = + "阵亡: " + get.cnNumber(_status.friendDied.length, true); + } else { _status.enemyDied.push(dead.name1); - _status.enemyCount.innerHTML='杀敌: '+get.cnNumber(_status.enemyDied.length,true); + _status.enemyCount.innerHTML = + "杀敌: " + get.cnNumber(_status.enemyDied.length, true); } - },this); - if(this.side==game.me.side){ - if(_status.friend.length==0){ + }, this); + if (this.side == game.me.side) { + if (_status.friend.length == 0) { game.over(false); return; } - } - else{ - if(_status.enemy.length==0){ + } else { + if (_status.enemy.length == 0) { game.over(true); return; } } game.replacePlayerOL(this); - } - else if(_status.mode=='2v2'){ - if(_status.replacetwo){ + } else if (_status.mode == "2v2") { + if (_status.replacetwo) { // later ? } var friend; - for(var i=0;i=side2.length+2){ + } else { + if (side1.length >= side2.length + 2) { me.showGiveup(); } } } return; - } - else if(_status.mode=='two'){ + } else if (_status.mode == "two") { var friend; - for(var i=0;imax){ - max=list[i].storage.longchuanzhibao; + for (var i = 0; i < list.length; i++) { + if (list[i].storage.longchuanzhibao > max) { + max = list[i].storage.longchuanzhibao; } } - for(var i=0;i2)){ - if(game.friend.includes(this)){ + var list = this.side == me.side ? _status.friend : _status.enemy; + if ( + (list.length == 0 && lib.storage.noreplace_end) || + (lib.storage.zhu && + lib.storage.main_zhu && + this.identity == "zhu" && + game.players.length > 2) + ) { + if (game.friend.includes(this)) { game.over(false); - } - else{ + } else { game.over(true); } - } - else if(game.friend.length==1&&this==game.friend[0]&&_status.friend.length==0){ + } else if ( + game.friend.length == 1 && + this == game.friend[0] && + _status.friend.length == 0 + ) { game.over(false); - } - else if(game.enemy.length==1&&this==game.enemy[0]&&_status.enemy.length==0){ + } else if ( + game.enemy.length == 1 && + this == game.enemy[0] && + _status.enemy.length == 0 + ) { game.over(true); - } - else{ + } else { game.replacePlayer(this); } } - } - } + }, + }, }, - get:{ - rawAttitude:function(from,to){ - if(from.side==to.side){ - if(to.identity=='zhu'){ - if(_status.connectMode){ - if(_status.mode=='4v4'||_status.mode=='guandu') return 7; - } - else{ - if(lib.storage.main_zhu||_status.mode=='four'||_status.mode=='guandu') return 7; + get: { + rawAttitude: function (from, to) { + if (from.side == to.side) { + if (to.identity == "zhu") { + if (_status.connectMode) { + if (_status.mode == "4v4" || _status.mode == "guandu") return 7; + } else { + if (lib.storage.main_zhu || _status.mode == "four" || _status.mode == "guandu") + return 7; } } return 6; - } - else{ - if(_status.mode=='siguo'){ - var list=['wei','shu','wu','qun']; - var map={wei:0,shu:0,wu:0,qun:0}; - var map2={wei:0,shu:0,wu:0,qun:0}; - for(var i=0;i=4){ - allin=i; + if (map2[i] >= 4) { + allin = i; break; - } - else if(map2[i]==3){ - map[i]+=10; - } - else if(map2[i]==2){ + } else if (map2[i] == 3) { + map[i] += 10; + } else if (map2[i] == 2) { map[i]++; } } - if(allin) return to.side==allin?-20:0; - list.sort(function(a,b){ - return map[b]-map[a]; + if (allin) return to.side == allin ? -20 : 0; + list.sort(function (a, b) { + return map[b] - map[a]; }); - var id1=list.indexOf(from.side); - var id2=list.indexOf(to.side); - var att=-1; - switch(id1){ - case 0:att=_status.siguoai[id2+2];break; + var id1 = list.indexOf(from.side); + var id2 = list.indexOf(to.side); + var att = -1; + switch (id1) { + case 0: + att = _status.siguoai[id2 + 2]; + break; case 1: - switch(id2){ - case 0:att=_status.siguoai[0];break; - case 2:att=_status.siguoai[1];break; - case 3:att=_status.siguoai[2];break; + switch (id2) { + case 0: + att = _status.siguoai[0]; + break; + case 2: + att = _status.siguoai[1]; + break; + case 3: + att = _status.siguoai[2]; + break; } break; case 2: - switch(id2){ - case 0:att=_status.siguoai[0];break; - case 1:att=_status.siguoai[1];break; - case 3:att=_status.siguoai[2];break; + switch (id2) { + case 0: + att = _status.siguoai[0]; + break; + case 1: + att = _status.siguoai[1]; + break; + case 3: + att = _status.siguoai[2]; + break; } break; - case 3:{ - if(id2==0){ - att=_status.siguoai[1];break; - } - else{ - att=_status.siguoai[2];break; + case 3: { + if (id2 == 0) { + att = _status.siguoai[1]; + break; + } else { + att = _status.siguoai[2]; + break; } } } - if(map2[to.side]>=4){ - att-=10; + if (map2[to.side] >= 4) { + att -= 10; + } else if (map2[to.side] == 3) { + att -= 3; + } else if (map2[to.side] == 2) { + att -= 0.5; } - else if(map2[to.side]==3){ - att-=3; - } - else if(map2[to.side]==2){ - att-=0.5; - } - if(to.storage.longchuanzhibao){ - return att*1.2; + if (to.storage.longchuanzhibao) { + return att * 1.2; } return att; - } - else{ - if(to.identity=='zhu'){ - if(_status.connectMode){ - if(_status.mode=='4v4'||_status.mode=='guandu') return -10; - } - else{ - if(lib.storage.main_zhu||_status.mode=='four'||_status.mode=='guandu') return -10; + } else { + if (to.identity == "zhu") { + if (_status.connectMode) { + if (_status.mode == "4v4" || _status.mode == "guandu") return -10; + } else { + if ( + lib.storage.main_zhu || + _status.mode == "four" || + _status.mode == "guandu" + ) + return -10; } } return -6; @@ -7744,20 +8786,20 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } }, }, - help:{ - '对决模式': - '
                              同舟共济(四国)
                              • 游戏开始时,每个势力的随机一名角色得到一个龙船至宝,1号位角色所在的势力额外获得一个龙船至宝,场上共5枚龙船至宝。龙船至宝是一个特殊标记。'+ - '
                              • 争夺龙船至宝的方式:当敌人受到了你造成的伤害后,若其有龙船至宝,则你获得其一个龙船至宝。若你杀死了该敌人,则你获得其所有的龙船至宝。'+ - '
                              • 获得龙船至宝时的摸牌:除游戏开始时外,若你从非队友处获得了龙船至宝,则你和队友各摸X张牌。(X为该次获得的龙船至宝数;获得队友的龙船至宝不摸牌)'+ - '
                              • 无来源死亡时:当一名角色死亡时,若没有伤害来源,则其持有的所有龙船至宝交给场上龙船至宝数唯一最多的角色,若没有则随机分配,获得龙船至宝的角色和其队友各摸X张牌。'+ - '
                              • 杀死队友时:当你杀死队友时,则将你和队友持有的所有龙船至宝交给场上龙船至宝数唯一最多的敌人,若没有则随机分配,获得龙船至宝的角色和其队友各摸X张牌。'+ - '
                              • 胜利条件:满足一下任意条件游戏结束:(1)在新的一轮开始时,若你的势力获得的龙船至宝至少为4个,则你和队友获胜;(2)消灭所有敌人。'+ - '
                              '+ - '
                              2v2 替补模式
                              • 选将时额外选择一名替补武将,阵亡时使用自己的替补武将上场,无替补时改为用队友的替补武将,两人均无替补时游戏结束'+ - '
                              • 杀死敌方武将摸三张牌,杀死友方武将弃置所有牌
                              '+ - '
                              4v4
                              • 双方各有一名主公和三名忠臣,杀死对方主公获胜
                              • '+ - '8号位游戏开始时额外摸一张牌,7、8号位可在游戏开始时置换一次手牌
                              • '+ - '杀死对方忠臣摸2+x张牌,x为对方(含刚被杀的忠臣)与己方的存活人数之差;主公杀死己方忠臣须弃置所有牌', - } + help: { + 对决模式: + '
                                同舟共济(四国)
                                • 游戏开始时,每个势力的随机一名角色得到一个龙船至宝,1号位角色所在的势力额外获得一个龙船至宝,场上共5枚龙船至宝。龙船至宝是一个特殊标记。' + + "
                                • 争夺龙船至宝的方式:当敌人受到了你造成的伤害后,若其有龙船至宝,则你获得其一个龙船至宝。若你杀死了该敌人,则你获得其所有的龙船至宝。" + + "
                                • 获得龙船至宝时的摸牌:除游戏开始时外,若你从非队友处获得了龙船至宝,则你和队友各摸X张牌。(X为该次获得的龙船至宝数;获得队友的龙船至宝不摸牌)" + + "
                                • 无来源死亡时:当一名角色死亡时,若没有伤害来源,则其持有的所有龙船至宝交给场上龙船至宝数唯一最多的角色,若没有则随机分配,获得龙船至宝的角色和其队友各摸X张牌。" + + "
                                • 杀死队友时:当你杀死队友时,则将你和队友持有的所有龙船至宝交给场上龙船至宝数唯一最多的敌人,若没有则随机分配,获得龙船至宝的角色和其队友各摸X张牌。" + + "
                                • 胜利条件:满足一下任意条件游戏结束:(1)在新的一轮开始时,若你的势力获得的龙船至宝至少为4个,则你和队友获胜;(2)消灭所有敌人。" + + "
                                " + + '
                                2v2 替补模式
                                • 选将时额外选择一名替补武将,阵亡时使用自己的替补武将上场,无替补时改为用队友的替补武将,两人均无替补时游戏结束' + + "
                                • 杀死敌方武将摸三张牌,杀死友方武将弃置所有牌
                                " + + '
                                4v4
                                • 双方各有一名主公和三名忠臣,杀死对方主公获胜
                                • ' + + "8号位游戏开始时额外摸一张牌,7、8号位可在游戏开始时置换一次手牌
                                • " + + "杀死对方忠臣摸2+x张牌,x为对方(含刚被杀的忠臣)与己方的存活人数之差;主公杀死己方忠臣须弃置所有牌", + }, }; }); diff --git a/node_modules/@types/noname-typings/ArrayEx.d.ts b/node_modules/@types/noname-typings/ArrayEx.d.ts index 414f5d0c6..5c823efac 100644 --- a/node_modules/@types/noname-typings/ArrayEx.d.ts +++ b/node_modules/@types/noname-typings/ArrayEx.d.ts @@ -4,72 +4,64 @@ declare interface Array { * @deprecated 已废弃,请使用includes */ contains(item: T): boolean; - containsSome(...item: T): boolean; - containsAll(...item: T): boolean; + containsSome(...item: T[]): boolean; + containsAll(...item: T[]): boolean; /** - * 添加任意元素进数组中 + * 将任意元素添加进数组中,若元素已经存在则不添加 * @param args * @returns - * 1. 当添加成功时,返回此数组 - * 2. 添加失败(已有此元素)时返回false,若传入多个参数,且添加失败时,后面的元素不再进行添加操作 */ - add(...args: T[]): this | false; + add(...item: T[]): this; /** - * 添加一个数组的所有元素到该数组中(循环执行this.add),此时参数arr中若有一个数组元素可能会出现bug + * 将一个数组的所有元素添加进数组中(循环执行this.add),此时参数arr中若有一个数组元素可能会出现bug * @param arr */ - addArray(arr: T[]): this; + addArray(...arr: T[][]): this; /** - * 移除一个元素出该数组(该元素不能是数组) + * 将任意元素移出数组(该元素不能是数组) * @param item * @returns - * 1. 当移除成功时,返回此数组 - * 2. 移除失败(没有此元素)时返回false - * 3. 传入参数为一个数组时,返回undefined */ - remove(item: T): this | false; - - remove(item: T[]): void; + remove(...item: T[]): this; /** - * 将一个数组的所有元素移除出该数组(循环执行this.remove),此时参数arr中若有一个数组元素可能会出现bug + * 将一个数组的所有元素移出数组(循环执行this.remove),此时参数arr中若有一个数组元素可能会出现bug * @param arr */ - removeArray(...arr: T[]): this; + removeArray(...arr: T[][]): this; /** * 随机获得该数组的一个元素 - * @param args 设置需要排除掉的部分元素; + * @param excludes 需要排除的元素; */ - randomGet(...args: T[]): T; + randomGet(...excludes: T[]): T; /** - * 随机移除数组的一个/多个元素 - * @param num 若num为数字的情况下,则移除num个元素,否则移除一个 + * 随机获取多个数组的元素,返回获取到的元素组成的数组 + * @param num 获取的数量(默认为0) + */ + randomGets(num?: number): T[]; + /** + * 随机移除数组的一个元素,返回被移除的元素 (若数组无元素返回undefined) + */ + randomRemove(): T | undefined; + /** + * 随机移除数组的多个元素,返回被移除元素组成的数组 + * @param num 移除元素的个数 * @returns - * 1. 移除一个元素,只返回被移除的元素 - * 2. 移除多个元素,返回一个被移除元素组成的数组 - * 3. 数组无元素返回undefined */ - randomRemove(num?: number): T | T[]; - randomRemove(num?: T): T | undefined; + randomRemove(num: number): T[]; /** - * 随机重新排序数组(数组乱序) + * 将数组随机排序,改变原数组 */ randomSort(): this; /** - * 随机获取数组的元素 + * 以目标玩家为起点,将数组按座位排序,改变原数组 * - * 返回的是一个重新整合的数组 - * @param num 获取的数量, 不传参视为0 - */ - randomGets(num?: number): this; - /** - * 对所有玩家进行排序 + * *只适用于玩家数组(使用lib.sort.seat方法) * - * 其排序,使用的是lib.sort.seat方法,按座位排序 - * @param target 目标玩家 + * @param target 目标玩家(默认为一号位) */ - sortBySeat(target?: Player): Player[]; + sortBySeat(target?: Player): this; /** - * 将一个Array中所有位于处理区的卡牌过滤出来 + * 将一个Array中所有位于处理区的卡牌过滤出来(只适用于卡牌数组) * * 例:设一list为[c1,c2,c3,c4],其中c1和c3是位于处理区的卡牌 * 那么list.filterInD()得到的结果即为[c1,c3] @@ -77,11 +69,11 @@ declare interface Array { * 在1.9.97.8.1或更高的版本中: * 可通过直接在括号中填写一个区域 来判断处于特定区域的卡牌 * 例:list.filterInD('h') 即判断数组中所有位于手牌区的卡牌 - * @param poiston 指定的区域,默认是 'o' + * @param position 指定的区域,默认是 'o' */ - filterInD(poiston?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): Card[]; - someInD(poiston?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): boolean; - everyInD(poiston?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): boolean; + filterInD(position?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): this; + someInD(position?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): boolean; + everyInD(position?: "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o"): boolean; //关于处理区: /* @@ -105,7 +97,13 @@ declare interface Array { * 获取 item 在数组中出现的次数 */ numOf(item: T): number; + /** + * 将数组去重,改变原数组 + */ unique(): this; + /** + * 返回去重后的数组,不改变原数组 + */ toUniqued(): T[]; maxBy(sortBy?: Function, filter?: typeof Array['prototype']['filter']): T; minBy(sortBy?: Function, filter?: typeof Array['prototype']['filter']): T; diff --git a/node_modules/@types/noname-typings/Skill.d.ts b/node_modules/@types/noname-typings/Skill.d.ts index 17e8884da..cbc602a8a 100644 --- a/node_modules/@types/noname-typings/Skill.d.ts +++ b/node_modules/@types/noname-typings/Skill.d.ts @@ -1011,8 +1011,9 @@ declare interface Skill { * @param event 事件,即event._trigger,相当于trigger时机(此时的event为触发该技能时机时的事件) * @param player * @param name 触发名,为event.triggername,目前只有在lib.filter.filterTrigger中才传该值,即被动触发,主动触发不检测该值,目前暂未完善 + * @param target v1.10.11 触发的目标 */ - filter?(event: GameEventPromise, player: Player, name?: string): boolean | void | null; + filter?(event: GameEventPromise, player: Player, name?: string, target?: Player): boolean | void | null; /** * 选择的目标武将牌上出现什么字。 * @@ -1281,9 +1282,11 @@ declare interface Skill { * 若是方法,则配置一个方法直接返回文本,或者玩家 * * 若没有配置prompt,显示该配置的提示 + * + * @param target v1.10.11 触发的目标 */ - logTarget?: string | TwoParmFun; - /** + logTarget?: string | ((event?: GameEventPromise, player?: Player, triggername?: string, target?: Player) => string | Player | Player[] | null); + /** * 是否通过logTarget显示触发者的目标日志; * * 目的:应该是为了细节化显示日志;在createTrigger,step3中使用,取值false,不使用logTarget,显示logSkill; @@ -1365,7 +1368,9 @@ declare interface Skill { * * 无参,简洁写法; */ - check?: ((card: Card) => number | boolean | void) | ((event: GameEventPromise, player: Player) => number | boolean | void) | (() => number | boolean | void); + check?: ((card: Card) => number | boolean | void) | + ((event: GameEventPromise, player: Player, triggername?: string, target?: Player) => number | boolean | void) | + (() => number | boolean | void); // check?(...any:any):number|boolean; // /** ai用于检测的方法:用于主动使用触发技能 */ // check?(card:Card):number|boolean; @@ -1388,7 +1393,30 @@ declare interface Skill { * 手动设置技能的标签 */ categories?: (skill: string, player: Player) => string[]; - + /** + * v1.10.11 + * + * 将技能的cost选择和content执行分离,从而回避原本的含糊不清的情况。 + * + * 对于原本使用direct:true取消logSkill,然后在技能内部选择消耗,再logSkill的情况而言,虽然有效,但是难以区分“技能选择消耗的过程”和“技能本身的效果”,不是一件好事。 + * + * 因此,我们决定将技能的cost和content分离(旧的写法仍然有效,不受影响)。使用例见张辽【突袭】 + */ + cost?: (event: GameEventPromise, trigger: GameEventPromise, player: Player) => Promise; + /** + * v1.10.11 + * + * “按点卖血”类技能和“同时机多个目标分别结算”的技能。 + * + * 现在,无名杀的“按点卖血”技能可以和OL线上一样,在同时触发多个技能时,自选技能的顺序了。 + * + * 用例见郭嘉【遗计】 + * + * 而对于一些牌移动事件的技能而言,不仅要“多次发动”,每次发动时还都有不同的目标。 + * + * 比如伊籍的【急援】,可能会出现“同时将一些牌交给了多名角色”的情况 + */ + getIndex?: (event, player, triggername) => number | Player[]; //日后还有很多属性要添加的 [key: string]: any; } @@ -1881,7 +1909,7 @@ interface ChooseButtonConfigData { * 既player.chooseButton的ai * @param button */ - check?(button: Button): number; + check?(button: Button): number | void; /** * 选择数目,默认为1 * diff --git a/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts b/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts new file mode 100644 index 000000000..7c8af5f8b --- /dev/null +++ b/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts @@ -0,0 +1,197 @@ +// from npm @types/cordova-plugin-android-permissions + +interface PermissionStatus { + hasPermission: boolean; +} + +interface Permissions { + ACCESS_CHECKIN_PROPERTIES: "android.permission.ACCESS_CHECKIN_PROPERTIES"; + ACCESS_BACKGROUND_LOCATION: "android.permission.ACCESS_BACKGROUND_LOCATION"; + ACCESS_COARSE_LOCATION: "android.permission.ACCESS_COARSE_LOCATION"; + ACCESS_FINE_LOCATION: "android.permission.ACCESS_FINE_LOCATION"; + ACCESS_LOCATION_EXTRA_COMMANDS: "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"; + ACCESS_MOCK_LOCATION: "android.permission.ACCESS_MOCK_LOCATION"; + ACCESS_NETWORK_STATE: "android.permission.ACCESS_NETWORK_STATE"; + ACCESS_SURFACE_FLINGER: "android.permission.ACCESS_SURFACE_FLINGER"; + ACCESS_WIFI_STATE: "android.permission.ACCESS_WIFI_STATE"; + ACCOUNT_MANAGER: "android.permission.ACCOUNT_MANAGER"; + ACTIVITY_RECOGNITION: "android.permission.ACTIVITY_RECOGNITION"; + ADD_VOICEMAIL: "com.android.voicemail.permission.ADD_VOICEMAIL"; + AUTHENTICATE_ACCOUNTS: "android.permission.AUTHENTICATE_ACCOUNTS"; + BATTERY_STATS: "android.permission.BATTERY_STATS"; + BIND_ACCESSIBILITY_SERVICE: "android.permission.BIND_ACCESSIBILITY_SERVICE"; + BIND_APPWIDGET: "android.permission.BIND_APPWIDGET"; + BIND_CARRIER_MESSAGING_SERVICE: "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; + BIND_DEVICE_ADMIN: "android.permission.BIND_DEVICE_ADMIN"; + BIND_DREAM_SERVICE: "android.permission.BIND_DREAM_SERVICE"; + BIND_INPUT_METHOD: "android.permission.BIND_INPUT_METHOD"; + BIND_NFC_SERVICE: "android.permission.BIND_NFC_SERVICE"; + BIND_NOTIFICATION_LISTENER_SERVICE: "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; + BIND_PRINT_SERVICE: "android.permission.BIND_PRINT_SERVICE"; + BIND_REMOTEVIEWS: "android.permission.BIND_REMOTEVIEWS"; + BIND_TEXT_SERVICE: "android.permission.BIND_TEXT_SERVICE"; + BIND_TV_INPUT: "android.permission.BIND_TV_INPUT"; + BIND_VOICE_INTERACTION: "android.permission.BIND_VOICE_INTERACTION"; + BIND_VPN_SERVICE: "android.permission.BIND_VPN_SERVICE"; + BIND_WALLPAPER: "android.permission.BIND_WALLPAPER"; + BLUETOOTH: "android.permission.BLUETOOTH"; + BLUETOOTH_ADMIN: "android.permission.BLUETOOTH_ADMIN"; + BLUETOOTH_ADVERTISE: "android.permission.BLUETOOTH_ADVERTISE"; + BLUETOOTH_CONNECT: "android.permission.BLUETOOTH_CONNECT"; + BLUETOOTH_PRIVILEGED: "android.permission.BLUETOOTH_PRIVILEGED"; + BLUETOOTH_SCAN: "android.permission.BLUETOOTH_SCAN"; + BODY_SENSORS: "android.permission.BODY_SENSORS"; + BRICK: "android.permission.BRICK"; + BROADCAST_PACKAGE_REMOVED: "android.permission.BROADCAST_PACKAGE_REMOVED"; + BROADCAST_SMS: "android.permission.BROADCAST_SMS"; + BROADCAST_STICKY: "android.permission.BROADCAST_STICKY"; + BROADCAST_WAP_PUSH: "android.permission.BROADCAST_WAP_PUSH"; + CALL_PHONE: "android.permission.CALL_PHONE"; + CALL_PRIVILEGED: "android.permission.CALL_PRIVILEGED"; + CAMERA: "android.permission.CAMERA"; + CAPTURE_AUDIO_OUTPUT: "android.permission.CAPTURE_AUDIO_OUTPUT"; + CAPTURE_SECURE_VIDEO_OUTPUT: "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"; + CAPTURE_VIDEO_OUTPUT: "android.permission.CAPTURE_VIDEO_OUTPUT"; + CHANGE_COMPONENT_ENABLED_STATE: "android.permission.CHANGE_COMPONENT_ENABLED_STATE"; + CHANGE_CONFIGURATION: "android.permission.CHANGE_CONFIGURATION"; + CHANGE_NETWORK_STATE: "android.permission.CHANGE_NETWORK_STATE"; + CHANGE_WIFI_MULTICAST_STATE: "android.permission.CHANGE_WIFI_MULTICAST_STATE"; + CHANGE_WIFI_STATE: "android.permission.CHANGE_WIFI_STATE"; + CLEAR_APP_CACHE: "android.permission.CLEAR_APP_CACHE"; + CLEAR_APP_USER_DATA: "android.permission.CLEAR_APP_USER_DATA"; + CONTROL_LOCATION_UPDATES: "android.permission.CONTROL_LOCATION_UPDATES"; + DELETE_CACHE_FILES: "android.permission.DELETE_CACHE_FILES"; + DELETE_PACKAGES: "android.permission.DELETE_PACKAGES"; + DEVICE_POWER: "android.permission.DEVICE_POWER"; + DIAGNOSTIC: "android.permission.DIAGNOSTIC"; + DISABLE_KEYGUARD: "android.permission.DISABLE_KEYGUARD"; + DUMP: "android.permission.DUMP"; + EXPAND_STATUS_BAR: "android.permission.EXPAND_STATUS_BAR"; + FACTORY_TEST: "android.permission.FACTORY_TEST"; + FLASHLIGHT: "android.permission.FLASHLIGHT"; + FORCE_BACK: "android.permission.FORCE_BACK"; + GET_ACCOUNTS: "android.permission.GET_ACCOUNTS"; + GET_PACKAGE_SIZE: "android.permission.GET_PACKAGE_SIZE"; + GET_TASKS: "android.permission.GET_TASKS"; + GET_TOP_ACTIVITY_INFO: "android.permission.GET_TOP_ACTIVITY_INFO"; + GLOBAL_SEARCH: "android.permission.GLOBAL_SEARCH"; + HARDWARE_TEST: "android.permission.HARDWARE_TEST"; + INJECT_EVENTS: "android.permission.INJECT_EVENTS"; + INSTALL_LOCATION_PROVIDER: "android.permission.INSTALL_LOCATION_PROVIDER"; + INSTALL_PACKAGES: "android.permission.INSTALL_PACKAGES"; + INSTALL_SHORTCUT: "com.android.launcher.permission.INSTALL_SHORTCUT"; + INTERNAL_SYSTEM_WINDOW: "android.permission.INTERNAL_SYSTEM_WINDOW"; + INTERNET: "android.permission.INTERNET"; + KILL_BACKGROUND_PROCESSES: "android.permission.KILL_BACKGROUND_PROCESSES"; + LOCATION_HARDWARE: "android.permission.LOCATION_HARDWARE"; + MANAGE_ACCOUNTS: "android.permission.MANAGE_ACCOUNTS"; + MANAGE_APP_TOKENS: "android.permission.MANAGE_APP_TOKENS"; + MANAGE_DOCUMENTS: "android.permission.MANAGE_DOCUMENTS"; + MASTER_CLEAR: "android.permission.MASTER_CLEAR"; + MEDIA_CONTENT_CONTROL: "android.permission.MEDIA_CONTENT_CONTROL"; + MODIFY_AUDIO_SETTINGS: "android.permission.MODIFY_AUDIO_SETTINGS"; + MODIFY_PHONE_STATE: "android.permission.MODIFY_PHONE_STATE"; + MOUNT_FORMAT_FILESYSTEMS: "android.permission.MOUNT_FORMAT_FILESYSTEMS"; + MOUNT_UNMOUNT_FILESYSTEMS: "android.permission.MOUNT_UNMOUNT_FILESYSTEMS"; + NFC: "android.permission.NFC"; + PERSISTENT_ACTIVITY: "android.permission.PERSISTENT_ACTIVITY"; + POST_NOTIFICATIONS: "android.permission.POST_NOTIFICATIONS"; + PROCESS_OUTGOING_CALLS: "android.permission.PROCESS_OUTGOING_CALLS"; + READ_CALENDAR: "android.permission.READ_CALENDAR"; + READ_CALL_LOG: "android.permission.READ_CALL_LOG"; + READ_CONTACTS: "android.permission.READ_CONTACTS"; + READ_EXTERNAL_STORAGE: "android.permission.READ_EXTERNAL_STORAGE"; + READ_FRAME_BUFFER: "android.permission.READ_FRAME_BUFFER"; + READ_HISTORY_BOOKMARKS: "com.android.browser.permission.READ_HISTORY_BOOKMARKS"; + READ_INPUT_STATE: "android.permission.READ_INPUT_STATE"; + READ_LOGS: "android.permission.READ_LOGS"; + READ_MEDIA_AUDIO: "android.permission.READ_MEDIA_AUDIO"; + READ_MEDIA_IMAGES: "android.permission.READ_MEDIA_IMAGES"; + READ_MEDIA_VIDEO: "android.permission.READ_MEDIA_VIDEO"; + READ_PHONE_STATE: "android.permission.READ_PHONE_STATE"; + READ_PROFILE: "android.permission.READ_PROFILE"; + READ_SMS: "android.permission.READ_SMS"; + READ_SOCIAL_STREAM: "android.permission.READ_SOCIAL_STREAM"; + READ_SYNC_SETTINGS: "android.permission.READ_SYNC_SETTINGS"; + READ_SYNC_STATS: "android.permission.READ_SYNC_STATS"; + READ_USER_DICTIONARY: "android.permission.READ_USER_DICTIONARY"; + READ_VOICEMAIL: "com.android.voicemail.permission.READ_VOICEMAIL"; + REBOOT: "android.permission.REBOOT"; + RECEIVE_BOOT_COMPLETED: "android.permission.RECEIVE_BOOT_COMPLETED"; + RECEIVE_MMS: "android.permission.RECEIVE_MMS"; + RECEIVE_SMS: "android.permission.RECEIVE_SMS"; + RECEIVE_WAP_PUSH: "android.permission.RECEIVE_WAP_PUSH"; + RECORD_AUDIO: "android.permission.RECORD_AUDIO"; + REORDER_TASKS: "android.permission.REORDER_TASKS"; + RESTART_PACKAGES: "android.permission.RESTART_PACKAGES"; + SEND_RESPOND_VIA_MESSAGE: "android.permission.SEND_RESPOND_VIA_MESSAGE"; + SEND_SMS: "android.permission.SEND_SMS"; + SET_ACTIVITY_WATCHER: "android.permission.SET_ACTIVITY_WATCHER"; + SET_ALARM: "com.android.alarm.permission.SET_ALARM"; + SET_ALWAYS_FINISH: "android.permission.SET_ALWAYS_FINISH"; + SET_ANIMATION_SCALE: "android.permission.SET_ANIMATION_SCALE"; + SET_DEBUG_APP: "android.permission.SET_DEBUG_APP"; + SET_ORIENTATION: "android.permission.SET_ORIENTATION"; + SET_POINTER_SPEED: "android.permission.SET_POINTER_SPEED"; + SET_PREFERRED_APPLICATIONS: "android.permission.SET_PREFERRED_APPLICATIONS"; + SET_PROCESS_LIMIT: "android.permission.SET_PROCESS_LIMIT"; + SET_TIME: "android.permission.SET_TIME"; + SET_TIME_ZONE: "android.permission.SET_TIME_ZONE"; + SET_WALLPAPER: "android.permission.SET_WALLPAPER"; + SET_WALLPAPER_HINTS: "android.permission.SET_WALLPAPER_HINTS"; + SIGNAL_PERSISTENT_PROCESSES: "android.permission.SIGNAL_PERSISTENT_PROCESSES"; + STATUS_BAR: "android.permission.STATUS_BAR"; + SUBSCRIBED_FEEDS_READ: "android.permission.SUBSCRIBED_FEEDS_READ"; + SUBSCRIBED_FEEDS_WRITE: "android.permission.SUBSCRIBED_FEEDS_WRITE"; + SYSTEM_ALERT_WINDOW: "android.permission.SYSTEM_ALERT_WINDOW"; + TRANSMIT_IR: "android.permission.TRANSMIT_IR"; + UNINSTALL_SHORTCUT: "com.android.launcher.permission.UNINSTALL_SHORTCUT"; + UPDATE_DEVICE_STATS: "android.permission.UPDATE_DEVICE_STATS"; + USE_CREDENTIALS: "android.permission.USE_CREDENTIALS"; + USE_SIP: "android.permission.USE_SIP"; + VIBRATE: "android.permission.VIBRATE"; + WAKE_LOCK: "android.permission.WAKE_LOCK"; + WRITE_APN_SETTINGS: "android.permission.WRITE_APN_SETTINGS"; + WRITE_CALENDAR: "android.permission.WRITE_CALENDAR"; + WRITE_CALL_LOG: "android.permission.WRITE_CALL_LOG"; + WRITE_CONTACTS: "android.permission.WRITE_CONTACTS"; + WRITE_EXTERNAL_STORAGE: "android.permission.WRITE_EXTERNAL_STORAGE"; + WRITE_GSERVICES: "android.permission.WRITE_GSERVICES"; + WRITE_HISTORY_BOOKMARKS: "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"; + WRITE_PROFILE: "android.permission.WRITE_PROFILE"; + WRITE_SECURE_SETTINGS: "android.permission.WRITE_SECURE_SETTINGS"; + WRITE_SETTINGS: "android.permission.WRITE_SETTINGS"; + WRITE_SMS: "android.permission.WRITE_SMS"; + WRITE_SOCIAL_STREAM: "android.permission.WRITE_SOCIAL_STREAM"; + WRITE_SYNC_SETTINGS: "android.permission.WRITE_SYNC_SETTINGS"; + WRITE_USER_DICTIONARY: "android.permission.WRITE_USER_DICTIONARY"; + WRITE_VOICEMAIL: "com.android.voicemail.permission.WRITE_VOICEMAIL"; + + checkPermission: ( + permission: string, + successCallback: (status: PermissionStatus) => void, + errorCallback: () => void + ) => void; + + requestPermission: ( + permission: string, + successCallback: (status: PermissionStatus) => void, + errorCallback: () => void + ) => void; + + requestPermissions: ( + permissions: string[], + successCallback: (status: PermissionStatus) => void, + errorCallback: () => void + ) => void; + + hasPermission: ( + permission: string, + successCallback: (status: PermissionStatus) => void, + errorCallback: () => void + ) => void; +} + +interface CordovaPlugins { + permissions: Permissions; +} \ No newline at end of file diff --git a/node_modules/@types/noname-typings/cordova-plugin-device.d.ts b/node_modules/@types/noname-typings/cordova-plugin-device.d.ts new file mode 100644 index 000000000..7b6a2b5ba --- /dev/null +++ b/node_modules/@types/noname-typings/cordova-plugin-device.d.ts @@ -0,0 +1,35 @@ +// Type definitions for cordova-plugin-device +// Project: https://github.com/apache/cordova-plugin-device +// Definitions by: Microsoft Open Technologies Inc +// Tim Brust +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/** + * This plugin defines a global device object, which describes the device's hardware and software. + * Although the object is in the global scope, it is not available until after the deviceready event. + */ +interface Device { + /** Get the version of Cordova running on the device. */ + cordova: string; + /** Indicates that Cordova initialize successfully. */ + available: boolean; + /** + * The device.model returns the name of the device's model or product. The value is set + * by the device manufacturer and may be different across versions of the same product. + */ + model: string; + /** Get the device's operating system name. */ + platform: string; + /** Get the device's Universally Unique Identifier (UUID). */ + uuid: string; + /** Get the operating system version. */ + version: string; + /** Get the device's manufacturer. */ + manufacturer: string; + /** Whether the device is running on a simulator. */ + isVirtual: boolean; + /** Get the device hardware serial number. */ + serial: string; +} + +declare var device: Device; \ No newline at end of file diff --git a/node_modules/@types/noname-typings/index.d.ts b/node_modules/@types/noname-typings/index.d.ts index 387ebd5ce..c89de0bb4 100644 --- a/node_modules/@types/noname-typings/index.d.ts +++ b/node_modules/@types/noname-typings/index.d.ts @@ -9,6 +9,8 @@ /// /// /// +/// +/// /// /// /// diff --git a/node_modules/@types/noname-typings/nonameModules/game/codemirror.d.ts b/node_modules/@types/noname-typings/nonameModules/game/codemirror.d.ts index 83b5c8a9a..5caf2e315 100644 --- a/node_modules/@types/noname-typings/nonameModules/game/codemirror.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/game/codemirror.d.ts @@ -1,2 +1,5 @@ -import codemirror from 'codemirror/index'; -export = codemirror; +export default CodeMirror; +/** + * @type { typeof import('codemirror/index') } + */ +declare var CodeMirror: typeof import('codemirror/index'); diff --git a/node_modules/@types/noname-typings/nonameModules/game/jszip.d.ts b/node_modules/@types/noname-typings/nonameModules/game/jszip.d.ts deleted file mode 100644 index cd478141f..000000000 --- a/node_modules/@types/noname-typings/nonameModules/game/jszip.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import * as jszip from 'jszip' -export = jszip; \ No newline at end of file diff --git a/node_modules/@types/noname-typings/nonameModules/noname.d.ts b/node_modules/@types/noname-typings/nonameModules/noname.d.ts index b13e2d614..24d68dcae 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname.d.ts @@ -1,8 +1,8 @@ -export { GNC as gnc } from "./noname/gnc/index.js"; -export { AI as ai } from "./noname/ai/index.js"; -export { Game as game } from "./noname/game/index.js"; -export { Get as get } from "./noname/get/index.js"; -export { Library as lib } from "./noname/library/index.js"; -export { status as _status } from "./noname/status/index.js"; -export { UI as ui } from "./noname/ui/index.js"; -export { boot } from "./noname/init/index.js"; +export { GNC, gnc, setGNC } from './noname/gnc/index.js'; +export { AI, ai, setAI } from './noname/ai/index.js'; +export { Game, game, setGame } from './noname/game/index.js'; +export { Get, get, setGet } from './noname/get/index.js'; +export { Library, lib, setLibrary } from './noname/library/index.js'; +export { status, _status, setStatus } from './noname/status/index.js'; +export { UI, ui, setUI } from './noname/ui/index.js'; +export { boot } from './noname/init/index.js'; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ai/basic.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ai/basic.d.ts index 40dc8f424..3195ed436 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ai/basic.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ai/basic.d.ts @@ -1,11 +1,11 @@ -export class Basic extends Uninstantable { +export class Basic { /** * @param { ( * button: Button, * buttons?: Button[] * ) => number } check */ - static chooseButton(check: (button: Button, buttons?: Button[]) => number): boolean; + chooseButton(check: (button: any, buttons?: Button[]) => number): boolean | undefined; /** * @param { ( * card?: Card, @@ -13,13 +13,12 @@ export class Basic extends Uninstantable { * ) => number } check * @returns { boolean | undefined } */ - static chooseCard(check: (card?: Card, cards?: Card[]) => number): boolean | undefined; + chooseCard(check: (card?: any, cards?: Card[]) => number): boolean | undefined; /** * @param { ( * target?: Player, * targets?: Player[] * ) => number } check */ - static chooseTarget(check: (target?: Player, targets?: Player[]) => number): boolean; + chooseTarget(check: (target?: any, targets?: Player[]) => number): boolean | undefined; } -import { Uninstantable } from "../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ai/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ai/index.d.ts index 038a291c6..a5e8109d6 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ai/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ai/index.d.ts @@ -1,9 +1,8 @@ -export class AI extends Uninstantable { - static basic: typeof Basic; - static get: typeof get; +export class AI { + basic: Basic; + get: import("../get/index.js").Get; } -export const ai: typeof AI; +export let ai: AI; +export function setAI(instance?: AI | undefined): void; export { Basic }; -import { Uninstantable } from "../util/index.js"; import { Basic } from './basic.js'; -import { Get as get } from '../get/index.js'; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/game/check.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/game/check.d.ts new file mode 100644 index 000000000..cf0668041 --- /dev/null +++ b/node_modules/@types/noname-typings/nonameModules/noname/game/check.d.ts @@ -0,0 +1,26 @@ +export class Check { + processSelection({ type, items, event, useCache, isSelectable }: { + type: any; + items: any; + event: any; + useCache: any; + isSelectable: any; + }): { + ok: boolean; + auto: boolean | undefined; + }; + button(event: any, useCache: any): { + ok: boolean; + auto: boolean | undefined; + }; + card(event: any, useCache: any): { + ok: boolean; + auto: boolean | undefined; + }; + target(event: any, useCache: any): { + ok: boolean; + auto: boolean | undefined; + }; + skill(event: any): void; + confirm(event: any, confirm: any): void; +} diff --git a/node_modules/@types/noname-typings/nonameModules/noname/game/dynamic-style/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/game/dynamic-style/index.d.ts index 64e1ceb64..46cb93dc8 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/game/dynamic-style/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/game/dynamic-style/index.d.ts @@ -37,7 +37,7 @@ export class DynamicStyle { */ get(name: string): { [x: string]: string | number; - }; + } | null; /** * Callback of `DynamicStyle#find`, getting the rule wanted. * `DynamicStyle#find`的回调函数,用于获取符合要求的规则 diff --git a/node_modules/@types/noname-typings/nonameModules/noname/game/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/game/index.d.ts index f1902d74d..ce8f14d61 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/game/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/game/index.d.ts @@ -1,39 +1,39 @@ -export class Game extends Uninstantable { - static online: boolean; - static onlineID: any; - static onlineKey: any; +export class Game { + online: boolean; + onlineID: null; + onlineKey: null; /** * @type {Player[]} */ - static players: Player[]; + players: Player[]; /** * @type {Player[]} */ - static dead: Player[]; - static imported: any[]; + dead: Player[]; + imported: any[]; /** * @type { { [key: string]: Player } } */ - static playerMap: { - [key: string]: import("../library/element/player.js").Player; + playerMap: { + [key: string]: any; }; - static phaseNumber: number; - static roundNumber: number; - static shuffleNumber: number; - static promises: typeof GamePromises; + phaseNumber: number; + roundNumber: number; + shuffleNumber: number; + promises: GamePromises; /** * @type { string } */ - static layout: string; + layout: string; /** * @type { Player } */ - static me: Player; + me: any; /** * @type { boolean } */ - static chess: boolean; - static globalEventHandlers: { + chess: boolean; + globalEventHandlers: { _handlers: {}; getHandler(name: any, type: any): any; ensureHandlerList(name: any, type: any): any; @@ -42,29 +42,29 @@ export class Game extends Uninstantable { getDefaultHandlerType(name: any): string; addHandlerToEvent(event: any): void; }; - static setStratagemBuffCost(cardName: any, cost: any): void; - static setStratagemBuffEffect(cardName: any, effect: any): void; - static setStratagemBuffPrompt(cardName: any, prompt: any): void; + setStratagemBuffCost(cardName: any, cost: any): void; + setStratagemBuffEffect(cardName: any, effect: any): void; + setStratagemBuffPrompt(cardName: any, prompt: any): void; /** * 添加新的属性杀 */ - static addNature(nature: any, translation: any, config: any): any; + addNature(nature: any, translation: any, config: any): any; /** * 判断卡牌信息/事件是否有某个属性 */ - static hasNature(item: any, nature: any, player: any): boolean; + hasNature(item: any, nature: any, player: any): boolean; /** * 设置卡牌信息/事件的属性 */ - static setNature(item: any, nature: any, addNature: any): any; + setNature(item: any, nature: any, addNature: any): any; /** * 洗牌 */ - static washCard(): false | any[] | import("../library/index.js").GameEventPromise; + washCard(): false | never[] | (import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise); /** * 基于钩子的添加势力方法 */ - static addGroup(id: any, short: any, name: any, config: any): any; + addGroup(id: any, short: any, name: any, config: any): any; /** * @typedef {import("../library/hooks/interface.js").NonameHookType} NonameHookType */ @@ -76,13 +76,13 @@ export class Game extends Uninstantable { * @param {Name} name * @param {Parameters} args */ - static callHook(name: Name, args: Parameters): void; - static yingbianEffect(event: any, content: any, ...args: any[]): import("../library/index.js").GameEventPromise; - static setYingbianConditionColor(yingbianCondition: any, color: any): void; - static setComplexYingbianCondition(yingbianCondition: any, condition: any): void; - static setSimpleYingbianCondition(yingbianCondition: any, condition: any): void; - static setYingbianEffect(yingbianEffect: any, effect: any): void; - static setYingbianPrompt(yingbian: any, prompt: any): void; + callHook(name: Name, args: Parameters): void; + yingbianEffect(event: any, content: any, ...args: any[]): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; + setYingbianConditionColor(yingbianCondition: any, color: any): void; + setComplexYingbianCondition(yingbianCondition: any, condition: any): void; + setSimpleYingbianCondition(yingbianCondition: any, condition: any): void; + setYingbianEffect(yingbianEffect: any, effect: any): void; + setYingbianPrompt(yingbian: any, prompt: any): void; /** * Dynamic Style Manager * 动态CSS管理对象 @@ -127,162 +127,162 @@ export class Game extends Uninstantable { * textAlign: "center" * }); */ - static dynamicStyle: DynamicStyle; + dynamicStyle: DynamicStyle; /** * Add a background music to the config option * * 在设置选项中添加一首背景音乐 */ - static addBackgroundMusic(link: any, musicName: any, aozhan: any): void; + addBackgroundMusic(link: any, musicName: any, aozhan: any): void; /** * Remove a background music from the config option * * 从设置选项中移除一首背景音乐 */ - static removeBackgroundMusic(link: any, aozhan: any): void; - static updateBackground(): void; + removeBackgroundMusic(link: any, aozhan: any): void; + updateBackground(): void; /** * Generate a beatmap using the given BPM, beats, and offset * * 用给定的BPM、节拍和偏移生成谱面 */ - static generateBeatmapTimeleap(bpm: any, beats: any, offset: any): any; - static updateRenku(): void; + generateBeatmapTimeleap(bpm: any, beats: any, offset: any): any; + updateRenku(): void; /** * 为牌添加知情者 * @param { Card[] | Card } cards * @param { Player[] } players */ - static addCardKnower(cards: Card[] | Card, players: Player[]): void; + addCardKnower(cards: Card[] | Card, players: Player[]): void; /** * 移除牌的所有知情者。 * @param { Card[] | Card } cards */ - static clearCardKnowers(cards: Card[] | Card): void; + clearCardKnowers(cards: Card[] | Card): void; /** * @param { { [key: string]: any } } [arg] */ - static loseAsync(arg?: { + loseAsync(arg?: { [key: string]: any; - }): import("../library/index.js").GameEventPromise; - static callFuncUseStepCache(prefix: any, func: any, params: any): any; + } | undefined): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; + callFuncUseStepCache(prefix: any, func: any, params: any): any; /** * @param {string} name */ - static getRarity(name: string): "legend" | "epic" | "rare" | "junk" | "common"; + getRarity(name: string): "legend" | "epic" | "rare" | "junk" | "common"; /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { boolean } */ - static hasGlobalHistory(key: T, filter: (event: GameEventPromise) => boolean, last?: GameEventPromise): boolean; + hasGlobalHistory(key: T, filter: (event: import('../library/index.js').GameEventPromise) => boolean, last?: import("../library/index.js").GameEventPromise | undefined): boolean; /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { void } */ - static checkGlobalHistory(key: T_1, filter: (event: GameEventPromise) => boolean, last?: GameEventPromise): void; + checkGlobalHistory(key: T_1, filter: (event: import('../library/index.js').GameEventPromise) => boolean, last?: import("../library/index.js").GameEventPromise | undefined): void; /** * @overload * @returns { GameHistory } */ - static getGlobalHistory(): GameHistory; + getGlobalHistory(): GameHistory; /** * @template { keyof GameHistory } T * @overload * @param { T } key - * @param { (event: GameEventPromise) => boolean } [filter] - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } [filter] + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { GameHistory[T] } */ - static getGlobalHistory(key: T_2, filter?: (event: GameEventPromise) => boolean, last?: GameEventPromise): GameHistory[T_2]; + getGlobalHistory(key: T_2, filter?: ((event: import('../library/index.js').GameEventPromise) => boolean) | undefined, last?: import("../library/index.js").GameEventPromise | undefined): GameHistory[T_2]; /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { boolean } */ - static hasAllGlobalHistory(key: T_3, filter: (event: GameEventPromise) => boolean, last?: GameEventPromise): boolean; + hasAllGlobalHistory(key: T_3, filter: (event: import('../library/index.js').GameEventPromise) => boolean, last?: import("../library/index.js").GameEventPromise | undefined): boolean; /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { void } */ - static checkAllGlobalHistory(key: T_4, filter: (event: GameEventPromise) => boolean, last?: GameEventPromise): void; + checkAllGlobalHistory(key: T_4, filter: (event: import('../library/index.js').GameEventPromise) => boolean, last?: import("../library/index.js").GameEventPromise | undefined): void; /** * @overload * @returns { GameHistory[] } */ - static getAllGlobalHistory(): GameHistory[]; + getAllGlobalHistory(): GameHistory[]; /** * @template { keyof GameHistory } T * @overload * @param { T } key - * @param { (event: GameEventPromise) => boolean } [filter] - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } [filter] + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { GameHistory[T] } */ - static getAllGlobalHistory(key: T_5, filter?: (event: GameEventPromise) => boolean, last?: GameEventPromise): GameHistory[T_5]; + getAllGlobalHistory(key: T_5, filter?: ((event: import('../library/index.js').GameEventPromise) => boolean) | undefined, last?: import("../library/index.js").GameEventPromise | undefined): GameHistory[T_5]; /** * @overload * @returns { void } */ - static cardsDiscard(): void; + cardsDiscard(): void; /** * @overload * @param { Card } cards - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsDiscard(cards: Card): GameEventPromise; + cardsDiscard(cards: any): import('../library/index.js').GameEventPromise; /** * @overload * @param {Card[]} cards - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsDiscard(cards: Card[]): GameEventPromise; + cardsDiscard(cards: Card[]): import('../library/index.js').GameEventPromise; /** * @overload * @returns { void } */ - static cardsGotoOrdering(): void; + cardsGotoOrdering(): void; /** * @overload * @param { Card } cards - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoOrdering(cards: Card): GameEventPromise; + cardsGotoOrdering(cards: any): import('../library/index.js').GameEventPromise; /** * @overload * @param {Card[]} cards - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoOrdering(cards: Card[]): GameEventPromise; + cardsGotoOrdering(cards: Card[]): import('../library/index.js').GameEventPromise; /** * @overload * @returns { void } */ - static cardsGotoSpecial(): void; + cardsGotoSpecial(): void; /** * @overload * @param { Card } cards * @param { 'toRenku' | false } [bool] 为false时不触发trigger,为'toRenku'时牌放到仁库 - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoSpecial(cards: Card, bool?: 'toRenku' | false): GameEventPromise; + cardsGotoSpecial(cards: any, bool?: false | "toRenku" | undefined): import('../library/index.js').GameEventPromise; /** * @overload * @param {Card[]} cards * @param { 'toRenku' | false } [bool] 为false时不触发trigger,为'toRenku'时牌放到仁库 - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoSpecial(cards: Card[], bool?: 'toRenku' | false): GameEventPromise; + cardsGotoSpecial(cards: Card[], bool?: false | "toRenku" | undefined): import('../library/index.js').GameEventPromise; /** * * @param {...( @@ -294,49 +294,49 @@ export class Game extends Uninstantable { * )} args * @returns */ - static cardsGotoPile(...args: (Card[] | Card | Function | 'insert' | 'washCard' | 'triggeronly' | [ + cardsGotoPile(...args: (Card[] | Card | Function | 'insert' | 'washCard' | 'triggeronly' | [ string, any - ])[]): import("../library/index.js").GameEventPromise; + ])[]): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; /** - * @param { GameEventPromise } event + * @param { import('../library/index.js').GameEventPromise } event */ - static $cardsGotoPile(event: GameEventPromise): void; + $cardsGotoPile(event: import('../library/index.js').GameEventPromise): void; /** * @param { false } [pause] */ - static showHistory(pause?: false): void; + showHistory(pause?: false | undefined): void; /** * @param { string } src * @param { true } [blur] */ - static createBackground(src: string, blur?: true): HTMLDivElement; + createBackground(src: string, blur?: true | undefined): HTMLDivElement; /** * * @param { string } url * @param { Player } [player] */ - static changeLand(url: string, player?: Player): void; + changeLand(url: string, player?: any): void; /** * @param { string[] } updates * @param { Function } proceed */ - static checkFileList(updates: string[], proceed: Function): void; + checkFileList(updates: string[], proceed: Function): void; /** * @param {...(Player[] | Player)} args */ - static replaceHandcards(...args: (Player[] | Player)[]): void; + replaceHandcards(...args: (Player[] | Player)[]): void; /** * @param { string } name */ - static removeCard(name: string): void; + removeCard(name: string): void; /** * @param { 'hidden' } [type] */ - static randomMapOL(type?: 'hidden'): void; - static closeMenu(): void; - static closeConnectMenu(): void; - static closePopped(): void; + randomMapOL(type?: "hidden" | undefined): void; + closeMenu(): void; + closeConnectMenu(): void; + closePopped(): void; /** * @template { keyof typeof lib.message.client } T * @overload @@ -344,7 +344,7 @@ export class Game extends Uninstantable { * @param { ...Parameters } args * @returns { void } */ - static broadcast(func: T_6, ...args: Parameters<{ + broadcast(func: T_6, ...args: Parameters<{ log: (arr: any) => void; opened: () => void; onconnection: (id: any) => void; @@ -368,7 +368,7 @@ export class Game extends Uninstantable { createDialog: (id: any, ...args: any[]) => void; gameStart: () => void; updateWaiting: (map: any) => void; - }[T_6]>): void; + }[T_6]> | undefined): void; /** * @template { any[] } T * @overload @@ -376,7 +376,7 @@ export class Game extends Uninstantable { * @param { ...T } args * @returns { void } */ - static broadcast(func: (...args: T_6) => void, ...args: T_6): void; + broadcast(func: (...args: T_6) => void, ...args: T_6 | undefined): void; /** * @template { keyof typeof lib.message.client } T * @overload @@ -384,7 +384,7 @@ export class Game extends Uninstantable { * @param { ...Parameters } args * @returns { void } */ - static broadcastAll(func: T_7, ...args: Parameters<{ + broadcastAll(func: T_7, ...args: Parameters<{ log: (arr: any) => void; opened: () => void; onconnection: (id: any) => void; @@ -408,7 +408,7 @@ export class Game extends Uninstantable { createDialog: (id: any, ...args: any[]) => void; gameStart: () => void; updateWaiting: (map: any) => void; - }[T_7]>): void; + }[T_7]> | undefined): void; /** * @template { any[] } T * @overload @@ -416,36 +416,36 @@ export class Game extends Uninstantable { * @param { ...T } args * @returns { void } */ - static broadcastAll(func: (...args: T_7) => void, ...args: T_7): void; - static syncState(): void; - static updateWaiting(): void; + broadcastAll(func: (...args: T_7) => void, ...args: T_7 | undefined): void; + syncState(): void; + updateWaiting(): void; /** * @param { Function } func */ - static waitForPlayer(func: Function): void; + waitForPlayer(func: Function): void; /** * @param { number } time * @param { Function } [onEnd] */ - static countDown(time: number, onEnd?: Function): void; - static countChoose(clear: any): void; - static stopCountChoose(): void; + countDown(time: number, onEnd?: Function | undefined): void; + countChoose(clear: any): void; + stopCountChoose(): void; /** * @param { string } ip * @param { (result: boolean) => any } callback */ - static connect(ip: string, callback: (result: boolean) => any): void; - static send(...args: any[]): void; + connect(ip: string, callback: (result: boolean) => any): void; + send(...args: any[]): void; /** * @param { string } id * @param {*} message */ - static sendTo(id: string, message: any): import("../library/element/client.js").Client; - static createServer(): void; + sendTo(id: string, message: any): import("../library/element/client.js").Client; + createServer(): void; /** * @returns { HTMLAudioElement } */ - static playAudio(...args: any[]): HTMLAudioElement; + playAudio(...args: any[]): HTMLAudioElement; /** * 根据skill中的audio,audioname,audioname2和player来获取音频地址列表 * @typedef {[string,number]|string|number|boolean} audioInfo @@ -484,13 +484,13 @@ export class Game extends Uninstantable { * //如果key中包含发动技能的角色名player,则直接改用info.audioname2[player]来播放语音 * ``` */ - static parseSkillAudio(skill: string, player?: Player | string, skillInfo?: { + parseSkillAudio(skill: string, player?: Player | string, skillInfo?: { audio: string | number | boolean | [string, number]; - audioname?: string[]; + audioname?: string[] | undefined; audioname2?: { [playerName: string]: string | number | boolean | [string, number]; - }; - } | (string | number | boolean | [string, number])): string[]; + } | undefined; + } | (string | number | boolean | [string, number]) | undefined): string[]; /** * * @param { string } skill @@ -500,141 +500,163 @@ export class Game extends Uninstantable { * @param { ['lib']['skill'] } [skillInfo] * @returns */ - static trySkillAudio(skill: string, player: Player | string, directaudio?: boolean, nobroadcast?: boolean, skillInfo?: any): HTMLAudioElement; + trySkillAudio(skill: string, player: Player | string, directaudio?: boolean | undefined, nobroadcast?: boolean | undefined, skillInfo?: any): HTMLAudioElement | undefined; /** * @param { string } name * @param { number } [index] * @returns */ - static playSkillAudio(name: string, index?: number, ...args: any[]): void; + playSkillAudio(name: string, index?: number | undefined, ...args: any[]): void; /** * @param { string | Card } card * @param { Player | Sex } sex */ - static playCardAudio(card: string | Card, sex: Player | Sex): void; - static playBackgroundMusic(): void; + playCardAudio(card: string | Card, sex: Player | Sex): void; + playBackgroundMusic(): void; /** * @overload * @param { 'character' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType * ) => importCharacterConfig } content * @param {*} [url] */ - static import(type: 'character', content: (lib: Library, game: typeof Game, ui: UI, get: Get, ai: AI, _status: Status) => importCharacterConfig, url?: any): any; + import(type: 'character', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importCharacterConfig, url?: any): any; /** * @overload * @param { 'card' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType * ) => importCardConfig } content * @param {*} [url] */ - static import(type: 'card', content: (lib: Library, game: typeof Game, ui: UI, get: Get, ai: AI, _status: Status) => importCardConfig, url?: any): any; + import(type: 'card', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importCardConfig, url?: any): any; /** * @overload * @param { 'mode' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType * ) => importModeConfig } content * @param {*} [url] */ - static import(type: 'mode', content: (lib: Library, game: typeof Game, ui: UI, get: Get, ai: AI, _status: Status) => importModeConfig, url?: any): any; + import(type: 'mode', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importModeConfig, url?: any): any; /** * @overload * @param { 'player' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType * ) => importPlayerConfig } content * @param {*} [url] */ - static import(type: 'player', content: (lib: Library, game: typeof Game, ui: UI, get: Get, ai: AI, _status: Status) => importPlayerConfig, url?: any): any; + import(type: 'player', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importPlayerConfig, url?: any): any; /** * @overload * @param { 'extension' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType * ) => importExtensionConfig } content * @param {*} [url] */ - static import(type: 'extension', content: (lib: Library, game: typeof Game, ui: UI, get: Get, ai: AI, _status: Status) => importExtensionConfig, url?: any): any; - static loadExtension(object: any): Promise; + import(type: 'extension', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importExtensionConfig, url?: any): any; + /** + * @overload + * @param { 'play' } type + * @param {( + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importPlayConfig } content + * @param {*} [url] + */ + import(type: 'play', content: (lib: InstanceType, game: InstanceType, ui: InstanceType, get: InstanceType, ai: InstanceType, _status: InstanceType) => importPlayConfig, url?: any): any; + loadExtension(object: any): Promise; /** * 下载文件 - * @type { (url: string, folder: string, onsuccess?: Function, onerror?: (e: Error) => void) => void, dev?: 'nodev', onprogress?: Function) => void } + * @type { undefined | ((url: string, folder: string, onsuccess?: Function, onerror?: (e: Error) => void, dev?: 'nodev', onprogress?: Function) => void) } */ - static download: (url: string, folder: string, onsuccess?: Function, onerror?: (e: Error) => void) => void; + download: ((url: string, folder: string, onsuccess?: Function, onerror?: ((e: Error) => void) | undefined, dev?: 'nodev', onprogress?: Function) => void) | undefined; /** * 读取文件为arraybuffer - * @type { (filename: string, callback?: (data: Buffer | ArrayBuffer) => any, onerror?: (e: Error) => void) => void } + * @type { undefined | ((filename: string, callback?: (data: Buffer | ArrayBuffer) => any, onerror?: (e: Error) => void) => void) } */ - static readFile: (filename: string, callback?: (data: Buffer | ArrayBuffer) => any, onerror?: (e: Error) => void) => void; + readFile: ((filename: string, callback?: ((data: Buffer | ArrayBuffer) => any) | undefined, onerror?: ((e: Error) => void) | undefined) => void) | undefined; /** * 读取文件为文本 - * @type { (filename: string, callback?: (data: string) => any, onerror?: (e: Error) => void) => void } + * @type { undefined | ((filename: string, callback?: (data: string) => any, onerror?: (e: Error) => void) => void) } */ - static readFileAsText: (filename: string, callback?: (data: string) => any, onerror?: (e: Error) => void) => void; + readFileAsText: ((filename: string, callback?: ((data: string) => any) | undefined, onerror?: ((e: Error) => void) | undefined) => void) | undefined; /** * 将数据写入文件 - * @type { (data: File | ArrayBuffer, path: string, name: string, callback?: (e: Error) => void) => void } + * @type { undefined | ((data: File | ArrayBuffer, path: string, name: string, callback?: (e: Error) => void) => void) } */ - static writeFile: (data: File | ArrayBuffer, path: string, name: string, callback?: (e: Error) => void) => void; + writeFile: ((data: File | ArrayBuffer, path: string, name: string, callback?: ((e: Error) => void) | undefined) => void) | undefined; /** * 移除文件 - * @type { (filename: string, callback?: (e: Error) => void) => void } + * @type { undefined | ((filename: string, callback?: (e: Error) => void) => void) } */ - static removeFile: (filename: string, callback?: (e: Error) => void) => void; + removeFile: ((filename: string, callback?: ((e: Error) => void) | undefined) => void) | undefined; /** * 获取文件列表 - * @type { (dir: string, success: (folders: string[], files: string[]) => any, failure: (e: Error) => void) => void } + * @type { undefined | ((dir: string, success: (folders: string[], files: string[]) => any, failure?: (e: Error) => void) => void) } */ - static getFileList: (dir: string, success: (folders: string[], files: string[]) => any, failure: (e: Error) => void) => void; + getFileList: ((dir: string, success: (folders: string[], files: string[]) => any, failure?: ((e: Error) => void) | undefined) => void) | undefined; /** * 按路径依次创建文件夹 - * @type { (list: string | string[], callback: Function, file?: boolean) => void } + * @type { undefined | ((list: string | string[], callback: Function, file?: boolean) => void) } */ - static ensureDirectory: (list: string | string[], callback: Function, file?: boolean) => void; + ensureDirectory: ((list: string | string[], callback: Function, file?: boolean) => void) | undefined; /** * 创建文件夹 - * @type { (directory: string, successCallback?: Function, errorCallback?: Function) => void } + * @type { undefined | ((directory: string, successCallback?: Function, errorCallback?: Function) => void) } */ - static createDir: (directory: string, successCallback?: Function, errorCallback?: Function) => void; + createDir: ((directory: string, successCallback?: Function, errorCallback?: Function) => void) | undefined; /** * 删除文件夹 - * @type { (directory: string, successCallback?: Function, errorCallback?: Function) => void } + * @type { undefined | ((directory: string, successCallback?: Function, errorCallback?: Function) => void) } */ - static removeDir: (directory: string, successCallback?: Function, errorCallback?: Function) => void; - static importExtension(data: any, finishLoad: any, exportExtension: any, extensionPackage: any): Promise; + removeDir: ((directory: string, successCallback?: Function, errorCallback?: Function) => void) | undefined; + /** + * @type { (forcecheck?: boolean | null, dev?: boolean) => Promise } + */ + checkForUpdate: (forcecheck?: boolean | null, dev?: boolean) => Promise; + /** + * @type { () => Promise } + */ + checkForAssetUpdate: () => Promise; + importExtension(data: any, finishLoad: any, exportExtension: any, extensionPackage: any): Promise; /** * @param { string } textToWrite * @param { string } [name] */ - static export(textToWrite: string, name?: string): void; + export(textToWrite: string, name?: string | undefined): void; /** * @param { string[] } list * @param { Function } [onsuccess] @@ -643,7 +665,7 @@ export class Game extends Uninstantable { * @param { Function } [process] * @param {*} [dev] */ - static multiDownload2(list: string[], onsuccess?: Function, onerror?: Function, onfinish?: Function, process?: Function, dev?: any): void; + multiDownload2(list: string[], onsuccess?: Function | undefined, onerror?: Function | undefined, onfinish?: Function | undefined, process?: Function | undefined, dev?: any): void; /** * @param { string[] } list * @param { Function } onsuccess @@ -652,24 +674,24 @@ export class Game extends Uninstantable { * @param { Function } [process] * @param {*} [dev] */ - static multiDownload(list: string[], onsuccess: Function, onerror: Function, onfinish: Function, process?: Function, dev?: any, ...args: any[]): void; + multiDownload(list: string[], onsuccess: Function, onerror: Function, onfinish: Function, process?: Function | undefined, dev?: any, ...args: any[]): void; /** * @param { string } url * @param { Function } onload * @param { Function } [onerror] * @param { Function } [onprogress] */ - static fetch(url: string, onload: Function, onerror?: Function, onprogress?: Function): void; + fetch(url: string, onload: Function, onerror?: Function | undefined, onprogress?: Function | undefined): void; /** * @param { string } time * @param { string } mode */ - static playVideo(time: string, mode: string): void; + playVideo(time: string, mode: string): void; /** * @param { Videos } video */ - static playVideoContent(video: Videos): void; - static videoContent: { + playVideoContent(video: Videos): void; + videoContent: { arrangeLib: (content: any) => void; $syncDisable: (player: any, map: any) => void; $syncExpand: (player: any, map: any) => void; @@ -792,50 +814,50 @@ export class Game extends Uninstantable { swapPlayer: (player: any, hs: any) => void; over: (str: any) => void; }; - static reload(): void; - static reload2(): void; - static exit(): void; + reload(): void; + reload2(): void; + exit(): void; /** * @param { string } url */ - static open(url: string): void; - static reloadCurrent(): void; + open(url: string): void; + reloadCurrent(): void; /** * @param { Function } func */ - static update(func: Function): Function; + update(func: Function): Function; /** * @param { Function } func */ - static unupdate(func: Function): void; - static stop(): void; - static run(): void; + unupdate(func: Function): void; + stop(): void; + run(): void; /** * @param { string } type * @param { Player } player * @param { any } [content] * @returns */ - static addVideo(type: string, player: Player, content?: any): void; + addVideo(type: string, player: any, content?: any): void; /** * @param { Function } func */ - static draw(func: Function): void; + draw(func: Function): void; /** * @param { number } [time] */ - static vibrate(time?: number): void; - static prompt(...args: any[]): void; - static alert(str: any): void; - static print(...args: any[]): void; - static animate: { + vibrate(time?: number | undefined): void; + prompt(...args: any[]): void; + alert(str: any): void; + print(...args: any[]): void; + animate: { window: (num: any) => void; flame: (x: any, y: any, duration: any, type: any) => void; }; /** * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path */ - static linexy(path: [number, string | number | { + linexy(path: [number, string | number | { opacity: any; color: any; dashed: any; @@ -844,7 +866,7 @@ export class Game extends Uninstantable { /** * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path */ - static _linexy(path: [number, string | number | { + _linexy(path: [number, string | number | { opacity: any; color: any; dashed: any; @@ -854,23 +876,23 @@ export class Game extends Uninstantable { * @param { string } name * @param { string } skill * @param { Player } player - * @param { GameEventPromise } event - * @returns { GameEventPromise } + * @param { import('../library/index.js').GameEventPromise } event + * @returns { import('../library/index.js').GameEventPromise } */ - static createTrigger(name: string, skill: string, player: Player, event: GameEventPromise, indexedData: any): GameEventPromise; + createTrigger(name: string, skill: string, player: any, event: import('../library/index.js').GameEventPromise, indexedData: any): import('../library/index.js').GameEventPromise; /** * @legacy Use {@link lib.element.GameEvent.constructor} instead. * * @param { string } name * @param { false } [trigger] - * @param { GameEventPromise } [triggerEvent] + * @param { import('../library/index.js').GameEventPromise } [triggerEvent] */ - static createEvent(name: string, trigger?: false, triggerEvent?: GameEventPromise): import("../library/index.js").GameEventPromise; + createEvent(name: string, trigger?: false | undefined, triggerEvent?: import("../library/index.js").GameEventPromise | undefined): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; /** * @param { string } name * @param { { extension: string, sex: Sex, group: string, hp: string | number, skills?: string[], tags?: any[], translate: string } } information */ - static addCharacter(name: string, information: { + addCharacter(name: string, information: { extension: string; sex: Sex; group: string; @@ -883,9 +905,9 @@ export class Game extends Uninstantable { * @param { { mode?: string, forbid?: any, character: { [key: string]: Character }, skill: { [key: string]: object }, [key: string]: any } } pack * @param { string } [packagename] */ - static addCharacterPack(pack: { + addCharacterPack(pack: { [key: string]: any; - mode?: string; + mode?: string | undefined; forbid?: any; character: { [key: string]: Character; @@ -893,13 +915,13 @@ export class Game extends Uninstantable { skill: { [key: string]: any; }; - }, packagename?: string): void; + }, packagename?: string | undefined): void; /** * @param { string } name * @param { Card } info * @param { { extension: string, translate: string, description: string, number?: number, color?: string } } info2 */ - static addCard(name: string, info: Card, info2: { + addCard(name: string, info: any, info2: { extension: string; translate: string; description: string; @@ -910,18 +932,18 @@ export class Game extends Uninstantable { * @param { { extension: string, mode?: string[], forbid?: string[], list: any[], card: {[key: string]: Card}, skill: { [key: string]: object } } } pack * @param { string } [packagename] */ - static addCardPack(pack: { + addCardPack(pack: { extension: string; - mode?: string[]; - forbid?: string[]; + mode?: string[] | undefined; + forbid?: string[] | undefined; list: any[]; card: { - [key: string]: import("../library/element/card.js").Card; + [key: string]: any; }; skill: { [key: string]: any; }; - }, packagename?: string): void; + }, packagename?: string | undefined): void; /** * @param { string } name * @param { { [key: string]: object } } info @@ -930,15 +952,15 @@ export class Game extends Uninstantable { * @param { string } [appendInfo] * @param { string } [abInfo] */ - static addSkill(name: string, info: { + addSkill(name: string, info: { [key: string]: any; - }, translate?: string, description?: string, appendInfo?: string, abInfo?: string): boolean; + }, translate?: string | undefined, description?: string | undefined, appendInfo?: string | undefined, abInfo?: string | undefined): boolean; /** * @param { string } name * @param {*} info * @param { { translate: string, config: { [key: string]: object } } } info2 */ - static addMode(name: string, info: any, info2: { + addMode(name: string, info: any, info2: { translate: string; config: { [key: string]: any; @@ -948,40 +970,41 @@ export class Game extends Uninstantable { * @param { string } skill * @param { Player } [player] */ - static addGlobalSkill(skill: string, player?: Player): boolean; + addGlobalSkill(skill: string, player?: any): boolean; /** * @param { string } skill + * @param { lib.element.Player } player */ - static removeGlobalSkill(skill: string): void; - static resetSkills(): void; + removeGlobalSkill(skill: string, player: lib.element.Player): void; + resetSkills(): void; /** * @param { string } extensionName */ - static hasExtension(extensionName: string): any; + hasExtension(extensionName: string): any; /** * @param { string } extensionName */ - static hasExtensionInstalled(extensionName: string): any; + hasExtensionInstalled(extensionName: string): any; /** * @param { string } extensionName */ - static hasExtensionLoaded(extensionName: string): any; + hasExtensionLoaded(extensionName: string): any; /** * @param { string } extensionName * @param { Function } runnable */ - static runAfterExtensionLoaded(extensionName: string, runnable: Function): void; + runAfterExtensionLoaded(extensionName: string, runnable: Function): void; /** * @param { string } extensionName * @param { boolean } [keepFile] */ - static removeExtension(extensionName: string, keepFile?: boolean): void; - static addRecentCharacter(...args: any[]): void; + removeExtension(extensionName: string, keepFile?: boolean | undefined): void; + addRecentCharacter(...args: any[]): void; /** * @overload * @returns { Card } */ - static createCard(): Card; + createCard(): any; /** * @overload * @param { Card | string } name @@ -989,12 +1012,12 @@ export class Game extends Uninstantable { * @param { number | string } [number] * @param { string } [nature] */ - static createCard(name: Card | string, suit?: string, number?: number | string, nature?: string): any; + createCard(name: Card | string, suit?: string | undefined, number?: string | number | undefined, nature?: string | undefined): any; /** * @overload * @returns { Card } */ - static createCard2(): Card; + createCard2(): any; /** * @overload * @param { Card | string } name @@ -1002,18 +1025,18 @@ export class Game extends Uninstantable { * @param { number } number * @param { string } nature */ - static createCard2(name: Card | string, suit: string, number: number, nature: string): any; + createCard2(name: Card | string, suit: string, number: number, nature: string): any; /** * @param { boolean } bool * @param { Function } callback */ - static forceOver(bool: boolean, callback: Function): void; + forceOver(bool: boolean, callback: Function): void; /** * @param { boolean | string } [result] * @param { boolean } [bool] * @returns */ - static over(result?: boolean | string, bool?: boolean, ...args: any[]): void; + over(result?: string | boolean | undefined, bool?: boolean | undefined, ...args: any[]): void; /** * @type { Map> } * @@ -1021,35 +1044,35 @@ export class Game extends Uninstantable { * * 但是需要事件结果的除外 */ - static executingAsyncEventMap: Map>; + executingAsyncEventMap: Map>; /** - * @type { GameEventPromise[] } + * @type { import('../library/index.js').GameEventPromise[] } */ - static belongAsyncEventList: GameEventPromise[]; + belongAsyncEventList: import('../library/index.js').GameEventPromise[]; /** - * @param { GameEventPromise } [belongAsyncEvent] + * @param { import('../library/index.js').GameEventPromise } [belongAsyncEvent] */ - static loop(belongAsyncEvent?: GameEventPromise): Promise; + loop(belongAsyncEvent?: import("../library/index.js").GameEventPromise | undefined): Promise; /** - * @param { GameEventPromise } [belongAsyncEvent] + * @param { import('../library/index.js').GameEventPromise } [belongAsyncEvent] */ - static runContent(belongAsyncEvent?: GameEventPromise): Promise; - static pause(): void; - static pause2(): void; - static resume(): void; - static resume2(): void; - static delaye(...args: any[]): import("../library/index.js").GameEventPromise; - static delayex(...args: any[]): import("../library/index.js").GameEventPromise; + runContent(belongAsyncEvent?: import("../library/index.js").GameEventPromise | undefined): Promise; + pause(): void; + pause2(): void; + resume(): void; + resume2(): void; + delaye(...args: any[]): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; + delayex(...args: any[]): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; /** * @param { number } [time] * @param { number } [time2] */ - static delay(time?: number, time2?: number): void; + delay(time?: number | undefined, time2?: number | undefined): void; /** * @param { number } [time] * @param { number } [time2] */ - static delayx(time?: number, time2?: number): void; + delayx(time?: number | undefined, time2?: number | undefined): void; /** * 在async content中对game.delay的代替使用方法 * @@ -1058,7 +1081,7 @@ export class Game extends Uninstantable { * @param { number } [time] * @param { number } [time2] */ - static asyncDelay(time?: number, time2?: number): Promise; + asyncDelay(time?: number | undefined, time2?: number | undefined): Promise; /** * 在async content中对game.delayx的代替使用方法 * @@ -1067,39 +1090,13 @@ export class Game extends Uninstantable { * @param { number } [time] * @param { number } [time2] */ - static asyncDelayx(time?: number, time2?: number): Promise; + asyncDelayx(time?: number | undefined, time2?: number | undefined): Promise; /** - * @param { GameEventPromise } [event] + * @param { import('../library/index.js').GameEventPromise } [event] */ - static check(event?: GameEventPromise): boolean; - static Check: { - new (): {}; - processSelection({ type, items, event, useCache, isSelectable }: { - type: any; - items: any; - event: any; - useCache: any; - isSelectable: any; - }): { - ok: boolean; - auto: boolean; - }; - button(event: any, useCache: any): { - ok: boolean; - auto: boolean; - }; - card(event: any, useCache: any): { - ok: boolean; - auto: boolean; - }; - target(event: any, useCache: any): { - ok: boolean; - auto: boolean; - }; - skill(event: any): void; - confirm(event: any, confirm: any): void; - }; - static uncheck(...args: any[]): void; + check(event?: import("../library/index.js").GameEventPromise | undefined): boolean; + Check: Check; + uncheck(...args: any[]): void; /** * @param { Player } player1 * @param { Player } player2 @@ -1107,88 +1104,88 @@ export class Game extends Uninstantable { * @param { boolean } [behind] * @param { boolean } [noanimate] */ - static swapSeat(player1: Player, player2: Player, prompt?: boolean, behind?: boolean, noanimate?: boolean): void; + swapSeat(player1: any, player2: any, prompt?: boolean | undefined, behind?: boolean | undefined, noanimate?: boolean | undefined): void; /** * @param { Player } player1 * @param { Player } [player2] */ - static swapPlayer(player: any, player2?: Player): void; + swapPlayer(player: any, player2?: any): void; /** * @param { Player } player */ - static swapControl(player: Player): void; - static swapPlayerAuto(player: any): void; + swapControl(player: any): void; + swapPlayerAuto(player: any): void; /** * @param { Player } player */ - static findNext(player: Player): import("../library/element/player.js").Player; + findNext(player: any): any; /** * @param { string } name * @param { Function } callback */ - static loadModeAsync(name: string, callback: Function): void; + loadModeAsync(name: string, callback: Function): void; /** * @param { string } name * @param {*} configx */ - static switchMode(name: string, configx: any): void; + switchMode(name: string, configx: any): void; /** * @param { string } mode */ - static loadMode(mode: string): void; + loadMode(mode: string): void; /** * @param {...string} args */ - static loadPackage(...args: string[]): void; + loadPackage(...args: string[]): void; /** * @param { Player } player */ - static phaseLoop(player: Player): void; + phaseLoop(player: any): void; /** * @param { Player } [player] */ - static gameDraw(player?: Player, num?: number): import("../library/index.js").GameEventPromise; - static chooseCharacterDouble(...args: any[]): void; - static updateRoundNumber(): void; + gameDraw(player?: any, num?: number): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; + chooseCharacterDouble(...args: any[]): void; + updateRoundNumber(): void; /** * @param { Player[] } players * @param { number | number[] | (player: Player) => number } num * @param { { drawDeck: boolean } } [drawDeck] * @param { boolean } [bottom] */ - static asyncDraw(players: Player[], num: number | number[] | ((player: Player) => number), drawDeck?: { + asyncDraw(players: Player[], num: number | number[] | ((player: any) => number), drawDeck?: { drawDeck: boolean; - }, bottom?: boolean): void; + } | undefined, bottom?: boolean | undefined): void; /** * @param { Player[] } players * @param { number | number[] | (player: Player) => number } num * @param { { drawDeck: boolean } } [drawDeck] */ - static asyncDrawAuto(players: Player[], num: number | number[] | ((player: Player) => number), drawDeck?: { + asyncDrawAuto(players: Player[], num: number | number[] | ((player: any) => number), drawDeck?: { drawDeck: boolean; - }, ...args: any[]): void; - static finishSkill(i: any, sub: any): void; - static finishCards(): void; + } | undefined, ...args: any[]): void; + finishSkill(i: any, sub: any): void; + finishCards(): void; /** * 这玩意至少19种重载了吧 */ - static checkMod(...args: any[]): any; + checkMod(...args: any[]): any; /** * @param { number } num */ - static prepareArena(num: number): void; - static clearArena(): void; - static clearConnect(): void; - static log(...args: any[]): void; + prepareArena(num: number): void; + clearArena(): void; + clearConnect(): void; + log(...args: any[]): void; /** * @param { Player } player * @param { string | Card[] } card * @param { Player[] } [targets] - * @param { GameEventPromise } [event] + * @param { import('../library/index.js').GameEventPromise } [event] * @param { boolean } [forced] * @param { string } [logvid] */ - static logv(player: Player, card: string | Card[], targets?: Player[], event?: GameEventPromise, forced?: boolean, logvid?: string): HTMLDivElement; + logv(player: any, card: string | Card[], targets?: any[] | undefined, event?: import("../library/index.js").GameEventPromise | undefined, forced?: boolean | undefined, logvid?: string | undefined): HTMLDivElement | undefined; /** * @param { string } storeName * @param { string } idbValidKey @@ -1196,7 +1193,7 @@ export class Game extends Uninstantable { * @param { Function } [onSuccess] * @param { Function } [onError] */ - static putDB(storeName: string, idbValidKey: string, value: any, onSuccess?: Function, onError?: Function): Promise; + putDB(storeName: string, idbValidKey: string, value: any, onSuccess?: Function | undefined, onError?: Function | undefined): Promise; /** * * @param { string } storeName @@ -1204,129 +1201,129 @@ export class Game extends Uninstantable { * @param { Function } [onSuccess] * @param { Function } [onError] */ - static getDB(storeName: string, query?: string | null, onSuccess?: Function, onError?: Function): Promise; + getDB(storeName: string, query?: string | null | undefined, onSuccess?: Function | undefined, onError?: Function | undefined): Promise; /** * @param { string } storeName * @param { string } [query] * @param { Function } [onSuccess] * @param { Function } [onError] */ - static deleteDB(storeName: string, query?: string, onSuccess?: Function, onError?: Function): Promise; + deleteDB(storeName: string, query?: string | undefined, onSuccess?: Function | undefined, onError?: Function | undefined): Promise; /** * @param { string } key * @param { * } [value] * @param { string } [mode] */ - static save(key: string, value?: any, mode?: string): void; - static showChangeLog(): void; + save(key: string, value?: any, mode?: string | undefined): void; + showChangeLog(): void; /** * @param { string } str * @param { string } [extname] */ - static showExtensionChangeLog(str: string, extname?: string): void; + showExtensionChangeLog(str: string, extname?: string | undefined): void; /** * @param { string } key * @param { * } [value] * @param { string | boolean } [local] * @param { Function } [callback] */ - static saveConfig(key: string, value?: any, local?: string | boolean, callback?: Function): void; + saveConfig(key: string, value?: any, local?: string | boolean | undefined, callback?: Function | undefined): void; /** * @param { string } key */ - static saveConfigValue(key: string): void; + saveConfigValue(key: string): void; /** * @param { string } extension * @param { string } key * @param { * } [value] */ - static saveExtensionConfig(extension: string, key: string, value?: any): void; + saveExtensionConfig(extension: string, key: string, value?: any): void; /** * @param { string } extension * @param { string } key */ - static saveExtensionConfigValue(extension: string, key: string): void; + saveExtensionConfigValue(extension: string, key: string): void; /** * @param { string } extension * @param { string } key */ - static getExtensionConfig(extension: string, key: string): any; + getExtensionConfig(extension: string, key: string): any; /** * @param { string } mode */ - static clearModeConfig(mode: string): void; + clearModeConfig(mode: string): void; /** * @param { number } position * @param { string } [character] * @param { string } [character2] */ - static addPlayer(position: number, character?: string, character2?: string): import("../library/element/player.js").Player; + addPlayer(position: number, character?: string | undefined, character2?: string | undefined): import("../library/element/player.js").Player; /** * @param { number } position * @param { string } [character] * @param { string } [animation] */ - static addFellow(position: number, character?: string, animation?: string): import("../library/element/player.js").Player; + addFellow(position: number, character?: string | undefined, animation?: string | undefined): import("../library/element/player.js").Player; /** * @param { Player } player */ - static triggerEnter(player: Player): import("../library/index.js").GameEventPromise; + triggerEnter(player: any): import("../library/element/gameEvent.js").GameEvent & import("../library/element/gameEventPromise.js").GameEventPromise; /** * @param { Player } player */ - static restorePlayer(player: Player): import("../library/element/player.js").Player; + restorePlayer(player: any): any; /** * @param { Player } player */ - static removePlayer(player: Player): import("../library/element/player.js").Player; + removePlayer(player: any): any; /** * @param { Player } player * @param { string } [character] * @param { string } [character2] */ - static replacePlayer(player: Player, character?: string, character2?: string): import("../library/element/player.js").Player; - static arrangePlayers(): void; + replacePlayer(player: any, character?: string | undefined, character2?: string | undefined): import("../library/element/player.js").Player; + arrangePlayers(): void; /** * @param { string[] } skills * @param { Player } player * @param { string[] } exclude */ - static filterSkills(skills: string[], player: Player, exclude: string[]): string[]; + filterSkills(skills: string[], player: any, exclude: string[]): string[]; /** * @param { string[] } skills */ - static expandSkills(skills: string[]): string[]; + expandSkills(skills: string[]): string[]; /** * @param { { [key:string]: any } } style */ - static css(style: { + css(style: { [key: string]: any; }): void; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static hasPlayer(func: (player: Player) => boolean, includeOut?: boolean): boolean; + hasPlayer(func: (player: any) => boolean, includeOut?: boolean | undefined): boolean; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static hasPlayer2(func: (player: Player) => boolean, includeOut?: boolean): boolean; + hasPlayer2(func: (player: any) => boolean, includeOut?: boolean | undefined): boolean; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static countPlayer(func: (player: Player) => boolean, includeOut?: boolean): number; + countPlayer(func: (player: any) => boolean, includeOut?: boolean | undefined): any; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static countPlayer2(func: (player: Player) => boolean, includeOut?: boolean): number; + countPlayer2(func: (player: any) => boolean, includeOut?: boolean | undefined): any; /** * @overload * @returns { Player[] } */ - static filterPlayer(): Player[]; + filterPlayer(): Player[]; /** * @overload * @param { (player: Player) => boolean } func @@ -1334,12 +1331,12 @@ export class Game extends Uninstantable { * @param { boolean } [includeOut] * @returns { Player[] } */ - static filterPlayer(func: (player: Player) => boolean, list?: Player[], includeOut?: boolean): Player[]; + filterPlayer(func: (player: any) => boolean, list?: any[] | undefined, includeOut?: boolean | undefined): Player[]; /** * @overload * @returns { Player[] } */ - static filterPlayer2(): Player[]; + filterPlayer2(): Player[]; /** * @overload * @param { (player: Player) => boolean } func @@ -1347,29 +1344,29 @@ export class Game extends Uninstantable { * @param { boolean } [includeOut] * @returns { Player[] } */ - static filterPlayer2(func: (player: Player) => boolean, list?: Player[], includeOut?: boolean): Player[]; + filterPlayer2(func: (player: any) => boolean, list?: any[] | undefined, includeOut?: boolean | undefined): Player[]; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static findPlayer(func: (player: Player) => boolean, includeOut?: boolean): import("../library/element/player.js").Player; + findPlayer(func: (player: any) => boolean, includeOut?: boolean | undefined): any; /** * @param { (player: Player) => boolean } func * @param { boolean } [includeOut] */ - static findPlayer2(func: (player: Player) => boolean, includeOut?: boolean): import("../library/element/player.js").Player; + findPlayer2(func: (player: any) => boolean, includeOut?: boolean | undefined): any; /** * @param { (player: Player) => boolean } func * @param { boolean } [all] */ - static findCards(func: (player: Player) => boolean, all?: boolean): string[]; - static countGroup(): number; + findCards(func: (player: any) => boolean, all?: boolean | undefined): string[]; + countGroup(): any; /** * 此函数用于计算函数的时间消耗。 * @param {function} 测试的函数 * @returns {number} 消耗的时间 */ - static testRunCost(func: any): number; + testRunCost(func: any): number; /** * 此方法用于对所有targets按顺序执行一个async函数。 * @@ -1377,9 +1374,10 @@ export class Game extends Uninstantable { * @param { (player: Player, i: number) => Promise } asyncFunc 需要执行的async方法 * @param { (a: Player, b: Player) => number } sort 排序器,默认为lib.sort.seat */ - static doAsyncInOrder(targets: Player[], asyncFunc: (player: Player, i: number) => Promise, sort: (a: Player, b: Player) => number): Promise; + doAsyncInOrder(targets: Player[], asyncFunc: (player: any, i: number) => Promise, sort: (a: any, b: any) => number): Promise; } -export const game: typeof Game; +export let game: Game; +export function setGame(instance?: Game | undefined): void; export type GameHistory = { cardMove: GameEventPromise[]; custom: GameEventPromise[]; @@ -1388,6 +1386,7 @@ export type GameHistory = { everything: GameEventPromise[]; }; export type Video = { + name?: string; type: string; player?: string; content?: string | any[]; @@ -1402,8 +1401,8 @@ export type Videos = { video: Video; win: boolean; }; -import { Uninstantable } from "../util/index.js"; import { GamePromises } from "./promises.js"; import { DynamicStyle } from "./dynamic-style/index.js"; -import { Library as lib } from '../library/index.js'; +import { lib } from '../library/index.js'; +import { Check } from "./check.js"; import { delay } from "../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/game/promises.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/game/promises.d.ts index ea25d45cb..2f4e24fbc 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/game/promises.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/game/promises.d.ts @@ -1,28 +1,18 @@ -export class GamePromises extends Uninstantable { +export class GamePromises { /** - * 模仿h5的prompt,用于显示可提示用户进行输入的对话框 - * - * 注: 由于参数列表是随意的,在这里我准备限制一下这个函数的参数顺序 - * - * @type {{ - * (title: string): Promise; - * (title: string, forced: true): Promise; - * (alertOption: 'alert', title: string): Promise; - * }} - * - * @param { string } [title] 设置prompt标题与input内容 - * @param { boolean } [forced] 为true的话将没有"取消按钮" - * @param { string } alertOption 设置prompt是否模拟alert - * @example - * ```js - * // 只设置标题(但是input的初始值就变成了undefined) - * game.promises.prompt('###prompt标题').then(value => console.log(value)); - * // 设置标题和input初始内容 - * game.promises.prompt('###prompt标题###input初始内容').then(value => console.log(value)); - * ``` - * @returns { Promise } + * @overload + * @param { string } title + * @returns { Promise } */ - static prompt(alertOption: string, title?: string, forced?: boolean): Promise; + prompt(title: string): Promise; + /** + * @overload + * @param { string } title + * @param { boolean } [forced] + * @returns { Promise } + * + */ + prompt(title: string, forced?: boolean | undefined): Promise; /** * 模仿h5的alert,用于显示信息的对话框 * @@ -33,14 +23,13 @@ export class GamePromises extends Uninstantable { * ``` * @returns { Promise } */ - static alert(title: string): Promise; - static download(url: any, folder: any, dev: any, onprogress: any): Promise; - static readFile(filename: any): Promise; - static readFileAsText(filename: any): Promise; - static writeFile(data: any, path: any, name: any): Promise; - static ensureDirectory(list: any, callback: any, file: any): Promise; - static createDir(directory: any): Promise; - static removeFile(filename: any): Promise; - static removeDir(directory: any): Promise; + alert(title: string): Promise; + download(url: any, folder: any, dev: any, onprogress: any): Promise; + readFile(filename: any): Promise; + readFileAsText(filename: any): Promise; + writeFile(data: any, path: any, name: any): Promise; + ensureDirectory(list: any, callback: any, file: any): Promise; + createDir(directory: any): Promise; + removeFile(filename: any): Promise; + removeDir(directory: any): Promise; } -import { Uninstantable } from "../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/get/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/get/index.d.ts index 57e9de1ae..e2aaa5672 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/get/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/get/index.d.ts @@ -1,5 +1,6 @@ -export class Get extends Uninstantable { - static is: typeof Is; +export class Get { + is: Is; + promises: Promises; /** * 获取当前内核版本信息 * @@ -9,59 +10,59 @@ export class Get extends Uninstantable { * * @returns {["firefox" | "chrome" | "safari" | "other", number, number, number]} */ - static coreInfo(): ["firefox" | "chrome" | "safari" | "other", number, number, number]; + coreInfo(): ["firefox" | "chrome" | "safari" | "other", number, number, number]; /** * 返回 VCard[] 形式的所有牌,用于印卡将遍历 * @param {Function} filter * @returns {string[][]} */ - static inpileVCardList(filter: Function): string[][]; + inpileVCardList(filter: Function): string[][]; /** * 根据(Player的)座次数n(从1开始)获取对应的“n号位”翻译 * @param {number | Player} seat */ - static seatTranslation(seat: number | Player): string; + seatTranslation(seat: number | Player): string; /** * @param {number} numberOfPlayers * @returns {string[]} */ - static identityList(numberOfPlayers: number): string[]; + identityList(numberOfPlayers: number): string[]; /** * Generate an object URL from the Base64-encoded octet stream * * 从Base64编码的八位字节流生成对象URL */ - static objectURL(octetStream: any): any; + objectURL(octetStream: any): any; /** * Get the card name length * * 获取此牌的字数 */ - static cardNameLength(card: any, player: any): number; + cardNameLength(card: any, player: any): number; /** * Get the Yingbian conditions (of the card) * * 获取(此牌的)应变条件 */ - static yingbianConditions(card: any): string[]; - static complexYingbianConditions(card: any): string[]; - static simpleYingbianConditions(card: any): string[]; + yingbianConditions(card: any): string[]; + complexYingbianConditions(card: any): string[]; + simpleYingbianConditions(card: any): string[]; /** * Get the Yingbian effects (of the card) * * 获取(此牌的)应变效果 */ - static yingbianEffects(card: any): string[]; + yingbianEffects(card: any): string[]; /** * Get the default Yingbian effect of the card * * 获取此牌的默认应变效果 */ - static defaultYingbianEffect(card: any): any; + defaultYingbianEffect(card: any): any; /** * 优先度判断 */ - static priority(skill: any): any; + priority(skill: any): any; /** * 新装备栏相关 * @@ -73,49 +74,49 @@ export class Get extends Uninstantable { * @param { false | Player } [player] * @returns { string[] } */ - static subtypes(obj: string | Card | VCard | CardBaseUIData, player?: false | Player): string[]; + subtypes(obj: string | Card | VCard | CardBaseUIData, player?: false | Player): string[]; /** * @returns { string[] } */ - static pinyin(chinese: any, withTone: any): string[]; - static yunmu(str: any): any; + pinyin(chinese: any, withTone: any): string[]; + yunmu(str: any): any; /** * 用于将参数转换为字符串,作为缓存的key。 */ - static paramToCacheKey(...args: any[]): string; - static yunjiao(str: any): string; + paramToCacheKey(...args: any[]): string; + yunjiao(str: any): string | null; /** * @param { string } skill * @param { Player } player * @returns { string[] } */ - static skillCategoriesOf(skill: string, player: Player): string[]; - static numOf(obj: any, item: any): any; - static connectNickname(): any; - static zhinangs(filter: any): any; - static sourceCharacter(str: any): any; - static isLuckyStar(player: any): boolean; - static infoHp(hp: any): number; - static infoMaxHp(hp: any): number; - static infoHujia(hp: any): number; - static bottomCards(num: any, putBack: any): any; - static discarded(): any; - static cardOffset(): number; - static colorspan(str: any): any; - static evtprompt(next: any, str: any): void; - static autoViewAs(card: any, cards: any): import("../library/element/vcard.js").VCard; + skillCategoriesOf(skill: string, player: any): string[]; + numOf(obj: any, item: any): any; + connectNickname(): any; + zhinangs(filter: any): any; + sourceCharacter(str: any): any; + isLuckyStar(player: any): any; + infoHp(hp: any): number; + infoMaxHp(hp: any): number; + infoHujia(hp: any): number; + bottomCards(num: any, putBack: any): any; + discarded(): any; + cardOffset(): number; + colorspan(str: any): any; + evtprompt(next: any, str: any): void; + autoViewAs(card: any, cards: any): import("../library/element/vcard.js").VCard; /** * @deprecated */ - static _autoViewAs(card: any, cards: any): any; - static max(list: any, func: any, type: any): any; - static min(list: any, func: any, type: any): any; + _autoViewAs(card: any, cards: any): any; + max(list: any, func: any, type: any): any; + min(list: any, func: any, type: any): any; /** * @overload * @param { string } name * @returns { Character } */ - static character(name: string): Character; + character(name: string): Character; /** * @template { 0 | 1 | 2 | 3 | 4 } T * @overload @@ -123,24 +124,30 @@ export class Get extends Uninstantable { * @param { T } num * @returns { Character[T] } */ - static character(name: string, num: T): Character[T]; - static characterInitFilter(name: any): string[]; - static characterIntro(name: any): any; - static bordergroup(info: any, raw: any): any; - static groupnature(group: any, method: any): any; - static sgn(num: any): 0 | 1 | -1; - static rand(num: any, num2: any): any; - static sort(arr: any, method: any, arg: any): any; - static sortSeat(arr: any, target: any): any; - static zip(callback: any): void; - static delayx(num: any, max: any): number; - static prompt(skill: any, target: any, player: any): string; - static prompt2(skill: any, target: any, player: any, ...args: any[]): any; - static url(master: any): string; - static round(num: any, f: any): number; - static playerNumber(): number; - static benchmark(func1: any, func2: any, iteration: any, arg: any): number; - static stringify(obj: any, level: any): any; + character(name: string, num: T): Character[T]; + characterInitFilter(name: any): string[]; + characterIntro(name: any): any; + bordergroup(info: any, raw: any): any; + groupnature(group: any, method: any): any; + sgn(num: any): 0 | 1 | -1; + rand(num: any, num2: any): any; + sort(arr: any, method: any, arg: any): any; + sortSeat(arr: any, target: any): any; + /** + * @param { (zip: JSZip) => any } callback + */ + zip(callback: (zip: JSZip) => any): void; + delayx(num: any, max: any): number; + prompt(skill: any, target: any, player: any): string; + prompt2(skill: any, target: any, player: any, ...args: any[]): string; + url(master: any): string; + round(num: any, f: any): number; + playerNumber(): number; + benchmark(func1: any, func2: any, iteration: any, arg: any): number | undefined; + /** + * @param {any} obj + */ + stringify(obj: any, level?: number): any; /** * 深拷贝函数(虽然只处理了部分情况) * @@ -152,25 +159,25 @@ export class Get extends Uninstantable { * @param {WeakMap} [map] - 拷贝用的临时存储,用于处理循环引用(请勿自行赋值) * @returns {T} - 深拷贝后的对象,若传入值不是对象则为传入值 */ - static copy(obj: T_1, copyKeyDeep?: boolean, map?: WeakMap): T_1; - static inpilefull(type: any): { + copy(obj: T_1, copyKeyDeep?: boolean | undefined, map?: WeakMap | undefined): T_1; + inpilefull(type: any): { name: any; suit: any; number: any; nature: any; }[]; - static inpile(type: any, filter: any): any[]; - static inpile2(type: any): any[]; - static typeCard(type: any, filter: any): string[]; - static libCard(filter: any): string[]; - static ip(): string; - static modetrans(config: any, server: any): string; - static charactersOL(func: any): number[]; - static trimip(str: any): any; - static mode(): any; - static idDialog(id: any): import("../library/element/dialog.js").Dialog; - static arenaState(): { - number: string; + inpile(type: any, filter: any): any[]; + inpile2(type: any): any[]; + typeCard(type: any, filter: any): string[]; + libCard(filter: any): string[]; + ip(): any; + modetrans(config: any, server: any): string; + charactersOL(func: any): number[]; + trimip(str: any): any; + mode(): any; + idDialog(id: any): any; + arenaState(): { + number: string | undefined; players: {}; mode: any; dying: any[]; @@ -181,312 +188,313 @@ export class Get extends Uninstantable { inpile_nature: any[]; renku: any[]; }; - static skillState(player: any): { + skillState(player: any): { global: string[]; }; - static id(): string; - static zhu(player: any, skill: any, group: any): any; - static config(item: any, mode: any): any; - static coinCoeff(list: any): number; - static rank(name: any, num: any): number | "x" | "s" | "b" | "c" | "d" | "a" | "ap" | "am" | "bp" | "bm" | "sp"; - static skillRank(skill: any, type: any, grouped: any): number; - static targetsInfo(targets: any): any[]; - static infoTargets(infos: any): import("../library/element/player.js").Player[]; - static cardInfo(card: any): any[]; - static cardsInfo(cards?: any[]): any[][]; - static infoCard(info: any): import("../library/element/card.js").Card; - static infoCards(infos: any): import("../library/element/card.js").Card[]; - static cardInfoOL(card: any): string; - static infoCardOL(info: any): any; - static cardsInfoOL(cards: any): string[]; - static infoCardsOL(infos: any): any[]; - static playerInfoOL(player: any): string; - static infoPlayerOL(info: any): any; - static playersInfoOL(players: any): string[]; - static infoPlayersOL(infos: any): any[]; - static funcInfoOL(func: any): any; - static infoFuncOL(info: any): any; - static eventInfoOL(item: any, level: any, noMore: any): string; + id(): string; + zhu(player: any, skill: any, group: any): any; + config(item: any, mode: any): any; + coinCoeff(list: any): number; + rank(name: any, num: any): number | "x" | "s" | "c" | "d" | "b" | "a" | "ap" | "am" | "bp" | "bm" | "sp"; + skillRank(skill: any, type: any, grouped: any): number; + targetsInfo(targets: any): any[]; + infoTargets(infos: any): any[]; + cardInfo(card: any): any[]; + cardsInfo(cards?: any[]): any[][]; + infoCard(info: any): import("../library/element/card.js").Card; + infoCards(infos: any): import("../library/element/card.js").Card[]; + cardInfoOL(card: any): string; + infoCardOL(info: any): any; + cardsInfoOL(cards: any): string[]; + infoCardsOL(infos: any): any[]; + playerInfoOL(player: any): string; + infoPlayerOL(info: any): any; + playersInfoOL(players: any): string[]; + infoPlayersOL(infos: any): any[]; + funcInfoOL(func: any): any; + infoFuncOL(info: any): any; + eventInfoOL(item: any, level: any, noMore: any): string; /** * @param {string} item */ - static infoEventOL(item: string): string | import("../library/element/gameEvent.js").GameEvent; - static stringifiedResult(item: any, level: any, nomore: any): any; - static parsedResult(item: any): any; - static verticalStr(str: any, sp: any): string; - static numStr(num: any, method: any): any; - static rawName(str: any): any; + infoEventOL(item: string): import("../library/element/gameEvent.js").GameEvent; + stringifiedResult(item: any, level: any, nomore: any): any; + parsedResult(item: any): any; + verticalStr(str: any, sp: any): string; + numStr(num: any, method: any): any; + rawName(str: any): any; /** * 作用修改:只读前缀 不读_ab */ - static rawName2(str: any): any; - static slimNameHorizontal(str: any): any; + rawName2(str: any): any; + slimNameHorizontal(str: any): any; /** * @param {string} prefix * @param {string} name * @returns {string} */ - static prefixSpan(prefix: string, name: string): string; - static slimName(str: any): string; - static time(): number; - static utc(): number; - static evtDistance(e1: any, e2: any): number; - static xyDistance(from: any, to: any): number; + prefixSpan(prefix: string, name: string): string; + slimName(str: any): string; + time(): number; + utc(): number; + evtDistance(e1: any, e2: any): number; + xyDistance(from: any, to: any): number; /** * @overload * @returns { void } */ - static itemtype(): void; + itemtype(): void; /** * @overload * @param { string } obj * @returns { 'position' | 'natures' | 'nature' } */ - static itemtype(obj: string): 'position' | 'natures' | 'nature'; + itemtype(obj: string): 'position' | 'natures' | 'nature'; /** * @overload * @param { Player[] } obj * @returns { 'players' } */ - static itemtype(obj: Player[]): 'players'; + itemtype(obj: Player[]): 'players'; /** * @overload * @param { Card[] } obj * @returns { 'cards' } */ - static itemtype(obj: Card[]): 'cards'; + itemtype(obj: Card[]): 'cards'; /** * @overload * @param { [number, number] } obj * @returns { 'select' } */ - static itemtype(obj: [number, number]): 'select'; + itemtype(obj: [number, number]): 'select'; /** * @overload * @param { [number, number, number, number] } obj * @returns { 'divposition' } */ - static itemtype(obj: [number, number, number, number]): 'divposition'; + itemtype(obj: [number, number, number, number]): 'divposition'; /** * @overload * @param { Button } obj * @returns { 'button' } */ - static itemtype(obj: Button): 'button'; + itemtype(obj: any): 'button'; /** * @overload * @param { Card } obj * @returns { 'card' } */ - static itemtype(obj: Card): 'card'; + itemtype(obj: any): 'card'; /** * @overload * @param { Player } obj * @returns { 'player' } */ - static itemtype(obj: Player): 'player'; + itemtype(obj: any): 'player'; /** * @overload * @param { Dialog } obj * @returns { 'dialog' } */ - static itemtype(obj: Dialog): 'dialog'; + itemtype(obj: any): 'dialog'; /** * @overload * @param { GameEvent | GameEventPromise } obj * @returns { 'event' } */ - static itemtype(obj: GameEvent | GameEventPromise): 'event'; - static equipNum(card: any): number; - static objtype(obj: any): "object" | "div" | "array" | "table" | "tr" | "td" | "fragment"; - static type(obj: any, method: any, player: any): any; - static type2(card: any, player: any): any; + itemtype(obj: GameEvent | GameEventPromise): 'event'; + equipNum(card: any): number; + objtype(obj: any): "div" | "object" | "array" | "table" | "tr" | "td" | "fragment" | undefined; + type(obj: any, method: any, player: any): any; + type2(card: any, player: any): any; /** * * @param { string | Card | VCard | CardBaseUIData } obj * @param { false | Player } [player] * @returns { string } */ - static subtype(obj: string | Card | VCard | CardBaseUIData, player?: false | Player): string; - static equiptype(card: any, player: any): number; + subtype(obj: string | Card | VCard | CardBaseUIData, player?: false | Player): string; + equiptype(card: any, player: any): number; /** * * @param { Card | VCard | CardBaseUIData } card * @param { false | Player } [player] * @returns { string } */ - static name(card: Card | VCard | CardBaseUIData, player?: false | Player): string; + name(card: Card | VCard | CardBaseUIData, player?: false | Player): string; /** * @param {Card | VCard | Card[] | VCard[]} card * @param {false | Player} [player] * @returns {string} */ - static suit(card: Card | VCard | Card[] | VCard[], player?: false | Player): string; + suit(card: Card | VCard | Card[] | VCard[], player?: false | Player): string; /** * @param {Card | VCard | Card[] | VCard[]} card * @param {false | Player} [player] * @returns {string} */ - static color(card: Card | VCard | Card[] | VCard[], player?: false | Player): string; + color(card: Card | VCard | Card[] | VCard[], player?: false | Player): string; /** * @param {Card | VCard} card * @param {false | Player} [player] * @returns {number} */ - static number(card: Card | VCard, player?: false | Player): number; + number(card: Card | VCard, player?: false | Player): number; /** * 返回一张杀的属性。如有多种属性则用`lib.natureSeparator`分割开来。例:火雷【杀】的返回值为`fire|thunder` * @param {string | string[] | Card | VCard} card * @param {false | Player} [player] * @returns {string} */ - static nature(card: string | string[] | Card | VCard, player?: false | Player): string; + nature(card: string | string[] | Card | VCard, player?: false | Player): string; /** * 返回包含所有属性的数组 * @param {string[] | string} card * @param {false | Player} [player] * @returns {string[]} */ - static natureList(card: string[] | string, player?: false | Player): string[]; - static cards(num: any, putBack: any): any; - static judge(card: any): any; - static judge2(card: any): any; - static distance(from: any, to: any, method: any): number; + natureList(card: string[] | string, player?: false | Player): string[]; + cards(num: any, putBack: any): any; + judge(card: any): any; + judge2(card: any): any; + distance(from: any, to: any, method: any): number; /** * @overload * @param { string } item * @returns { Skill } */ - static info(item: string): Skill; + info(item: string): Skill; /** * @overload * @param { Card | VCard | CardBaseUIData } item * @param { Player | false } [player] * @returns { any } */ - static info(item: Card | VCard | CardBaseUIData, player?: Player | false): any; + info(item: Card | VCard | CardBaseUIData, player?: Player | false): any; /** * @param { number | Select | (()=>Select) } [select] * @returns { Select } */ - static select(select?: number | Select | (() => Select)): Select; - static card(original: any): any; + select(select?: number | Select | (() => Select) | undefined): Select; + card(original: any): any; /** * @overload * @returns {GameEvent} */ - static event(): GameEvent; + event(): any; /** * @template { keyof GameEvent } T * @overload * @param {T} key * @returns {GameEvent[T]} */ - static event(key: T_2): import("../library/element/gameEvent.js").GameEvent[T_2]; - static player(): import("../library/element/player.js").Player; - static players(sort: any, dead: any, out: any): import("../library/element/player.js").Player[]; - static position(card: any, ordering: any): number | "x" | "s" | "e" | "j" | "h" | "c" | "d" | "o"; - static skillTranslation(str: any, player: any): string; - static skillInfoTranslation(name: any, player: any): any; + event(key: T_2): any; + player(): any; + players(sort: any, dead: any, out: any): any[]; + position(card: any, ordering: any): number | "e" | "j" | "x" | "s" | "h" | "c" | "d" | "o" | null | undefined; + skillTranslation(str: any, player: any): string; + skillInfoTranslation(name: any, player: any): any; /** * @returns {string} */ - static translation(str: any, arg: any): string; - static menuZoom(): any; - static strNumber(num: any): any; - static cnNumber(num: any, ordinal: any): any; + translation(str: any, arg: any): string; + menuZoom(): any; + strNumber(num: any): any; + cnNumber(num: any, ordinal: any): any; /** * 遍历子元素 * @param {HTMLElement} node * @returns {Iterable} 迭代器 */ - static iterableChildNodes(node: HTMLElement, ...args: any[]): Iterable; + iterableChildNodes(node: HTMLElement, ...args: any[]): Iterable; /** * @param {((a: Button, b: Button) => number)} [sort] 排序函数 * @returns { Button[] } */ - static selectableButtons(sort?: (a: Button, b: Button) => number): Button[]; + selectableButtons(sort?: ((a: any, b: any) => number) | undefined): Button[]; /** * @param {((a: Card, b: Card) => number)} [sort] 排序函数 * @returns { Card[] } */ - static selectableCards(sort?: (a: Card, b: Card) => number): Card[]; + selectableCards(sort?: ((a: any, b: any) => number) | undefined): Card[]; /** * @returns { string[] } 技能名数组 */ - static skills(): string[]; - static gainableSkills(func: any, player: any): any[]; - static gainableSkillsName(name: any, func: any): any[]; - static gainableCharacters(func: any): string[]; + skills(): string[]; + gainableSkills(func: any, player: any): any[]; + gainableSkillsName(name: any, func: any): any[]; + gainableCharacters(func: any): string[]; /** * @param {((a: Player, b: Player) => number)} [sort] 排序函数 * @returns { Player[] } */ - static selectableTargets(sort?: (a: Player, b: Player) => number): Player[]; - static filter(filter: any, i: any): any; - static cardCount(card: any, player: any): any; - static skillCount(skill: any, player: any): any; - static owner(card: any, method: any): import("../library/element/player.js").Player; - static noSelected(): boolean; - static population(identity: any): number; - static totalPopulation(identity: any): number; + selectableTargets(sort?: ((a: any, b: any) => number) | undefined): Player[]; + filter(filter: any, i: any): any; + cardCount(card: any, player: any): any; + skillCount(skill: any, player: any): any; + owner(card: any, method: any): any; + noSelected(): boolean; + population(identity: any): number; + totalPopulation(identity: any): number; /** * @param { Card | VCard } item */ - static cardtag(item: Card | VCard, tag: any): any; - static tag(item: any, tag: any, item2: any, bool: any): any; - static sortCard(sort: any): (card: any) => any; - static difficulty(): 2 | 1 | 3; - static cardPile(name: any, create: any): any; - static cardPile2(name: any): any; - static discardPile(name: any): any; - static aiStrategy(): 2 | 1 | 3 | 4 | 5 | 6; - static skillintro(name: any, learn: any, learn2: any): string; - static intro(name: any): string; - static storageintro(type: any, content: any, player: any, dialog: any, skill: any): any; - static nodeintro(node: any, simple: any, evt: any): import("../library/element/dialog.js").Dialog; - static linkintro(dialog: any, content: any, player: any): void; - static groups(): string[]; - static types(): any[]; - static links(buttons: any): any[]; - static threaten(target: any, player: any, hp: any): number; - static condition(player: any): any; - static attitude(from: any, to: any, ...args: any[]): any; - static sgnAttitude(...args: any[]): 0 | 1 | -1; - static useful_raw(card: any, player: any): any; - static useful(card: any, player: any): any; - static unuseful(card: any): number; - static unuseful2(card: any): number; - static unuseful3(card: any): number; - static value(card: any, player: any, method: any): any; - static equipResult(player: any, target: any, name: any): number; - static equipValue(card: any, player: any): number; - static equipValueNumber(card: any): number; - static disvalue(card: any, player: any): number; - static disvalue2(card: any, player: any): number; - static skillthreaten(skill: any, player: any, target: any): number | void; - static cacheOrder(item: any): number; + cardtag(item: Card | VCard, tag: any): any; + tag(item: any, tag: any, item2: any, bool: any): any; + sortCard(sort: any): ((card: any) => any) | undefined; + difficulty(): 2 | 1 | 3; + cardPile(name: any, create: any): any; + cardPile2(name: any): any; + discardPile(name: any): any; + aiStrategy(): 2 | 1 | 3 | 4 | 5 | 6; + skillintro(name: any, learn: any, learn2: any): string; + intro(name: any): string; + storageintro(type: any, content: any, player: any, dialog: any, skill: any): any; + nodeintro(node: any, simple: any, evt: any): import("../library/element/dialog.js").Dialog | undefined; + linkintro(dialog: any, content: any, player: any): void; + groups(): string[]; + types(): any[]; + links(buttons: any): any[]; + threaten(target: any, player: any, hp: any): number; + condition(player: any): any; + attitude(from: any, to: any, ...args: any[]): any; + sgnAttitude(...args: any[]): 0 | 1 | -1; + useful_raw(card: any, player: any): any; + useful(card: any, player: any): any; + unuseful(card: any): number; + unuseful2(card: any): number; + unuseful3(card: any): number; + value(card: any, player: any, method: any): any; + equipResult(player: any, target: any, name: any): number; + equipValue(card: any, player: any): any; + equipValueNumber(card: any): any; + disvalue(card: any, player: any): number; + disvalue2(card: any, player: any): number; + skillthreaten(skill: any, player: any, target: any): number | void; + cacheOrder(item: any): number; /** * @returns { number } */ - static order(item: any, player?: import("../library/element/player.js").Player): number; - static result(item: any, skill: any): any; - static cacheEffectUse(target: any, card: any, player: any, player2: any, isLink: any): number; - static effect_use(target: any, card: any, player: any, player2: any, isLink: any): number; - static cacheEffect(target: any, card: any, player: any, player2: any, isLink: any): number; - static effect(target: any, card: any, player: any, player2: any, isLink: any): number; - static damageEffect(target: any, player: any, viewer: any, nature: any): any; + order(item: any, player?: any): number; + result(item: any, skill: any): any; + cacheEffectUse(target: any, card: any, player: any, player2: any, isLink: any): number; + effect_use(target: any, card: any, player: any, player2: any, isLink: any): number; + cacheEffect(target: any, card: any, player: any, player2: any, isLink: any): number; + effect(target: any, card: any, player: any, player2: any, isLink: any): number; + damageEffect(target: any, player: any, viewer: any, nature: any): any; /** * * @param {any} source 如果参数是function,执行此函数并返回结果,传参为此方法剩余的参数。如果参数不是function,直接返回结果。 * @returns 返回的结果 */ - static dynamicVariable(source: any, ...args: any[]): any; - static recoverEffect(target: any, player: any, viewer: any): number; - static buttonValue(button: any): number; - static attitude2(to: any): any; + dynamicVariable(source: any, ...args: any[]): any; + recoverEffect(target: any, player: any, viewer: any): number; + buttonValue(button: any): number; + attitude2(to: any): any; } -export const get: typeof Get; -export { Is }; -import { Uninstantable } from "../util/index.js"; +export let get: Get; +export function setGet(instance?: Get | undefined): void; import { Is } from "./is.js"; +import { Promises } from "./promises.js"; +export { Is, Promises }; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/get/is.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/get/is.d.ts index 59caba09a..45add36bd 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/get/is.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/get/is.d.ts @@ -1,89 +1,89 @@ -export class Is extends Uninstantable { +export class Is { /** * 判断是否为进攻坐骑 * @param { Card | VCard } card * @param { false | Player } [player] * @returns { boolean } */ - static attackingMount(card: Card | VCard, player?: false | Player): boolean; + attackingMount(card: Card | VCard, player?: false | Player): boolean; /** * 判断是否为防御坐骑 * @param { Card | VCard } card * @param { false | Player } [player] * @returns { boolean } */ - static defendingMount(card: Card | VCard, player?: false | Player): boolean; + defendingMount(card: Card | VCard, player?: false | Player): boolean; /** * 判断坐骑栏是否被合并 * @returns { boolean } */ - static mountCombined(): boolean; + mountCombined(): boolean; /** * 判断传入的参数的属性是否相同(参数可以为卡牌、卡牌信息、属性等) * @param {...} infos 要判断的属性列表 * @param {boolean} every 是否判断每一个传入的属性是否完全相同而不是存在部分相同 */ - static sameNature(...args: any[]): boolean; + sameNature(...args: any[]): boolean; /** * 判断传入的参数的属性是否不同(参数可以为卡牌、卡牌信息、属性等) * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全不同而不是存在部分不同 */ - static differentNature(...args: any[]): boolean; + differentNature(...args: any[]): boolean; /** * 判断一张牌是否为明置手牌 * @param { Card } card */ - static shownCard(card: Card): boolean; + shownCard(card: any): boolean; /** * 是否是虚拟牌 * @param { Card | VCard } card */ - static virtualCard(card: Card | VCard): boolean; + virtualCard(card: Card | VCard): boolean; /** * 是否是转化牌 * @param { Card | VCard } card */ - static convertedCard(card: Card | VCard): boolean; + convertedCard(card: Card | VCard): boolean; /** * 是否是实体牌 * @param { Card | VCard } card */ - static ordinaryCard(card: Card | VCard): boolean; + ordinaryCard(card: Card | VCard): any; /** * 押韵判断 * @param { string } str1 * @param { string } str2 */ - static yayun(str1: string, str2: string): boolean; + yayun(str1: string, str2: string): boolean; /** * @param { string } skill 技能id * @param { Player } player 玩家 * @returns */ - static blocked(skill: string, player: Player): boolean; + blocked(skill: string, player: any): boolean; /** * 是否是双势力武将 * @param { string } name * @param { string[] } array * @returns { boolean | string[] } */ - static double(name: string, array: string[]): boolean | string[]; + double(name: string, array: string[]): boolean | string[]; /** * Check if the card has a Yingbian condition * * 检测此牌是否具有应变条件 * @param { Card | VCard } card */ - static yingbianConditional(card: Card | VCard): boolean; + yingbianConditional(card: Card | VCard): boolean; /** * @param { Card | VCard } card */ - static complexlyYingbianConditional(card: Card | VCard): boolean; + complexlyYingbianConditional(card: Card | VCard): boolean; /** * @param { Card | VCard } card */ - static simplyYingbianConditional(card: Card | VCard): boolean; + simplyYingbianConditional(card: Card | VCard): boolean; /** * Check if the card has a Yingbian effect * @@ -91,104 +91,103 @@ export class Is extends Uninstantable { * * @param { Card | VCard } card */ - static yingbianEffective(card: Card | VCard): boolean; + yingbianEffective(card: Card | VCard): boolean; /** * @param { Card | VCard } card */ - static yingbian(card: Card | VCard): boolean; + yingbian(card: Card | VCard): boolean; /** * @param { string } [substring] */ - static emoji(substring?: string): boolean; + emoji(substring?: string | undefined): boolean; /** * @param { string } str */ - static banWords(str: string): boolean; + banWords(str: string): boolean; /** * @param { GameEventPromise } event */ - static converted(event: GameEventPromise): boolean; - static safari(): boolean; + converted(event: any): boolean; + safari(): boolean; /** * @param { (Card | VCard)[]} cards */ - static freePosition(cards: (Card | VCard)[]): boolean; + freePosition(cards: (Card | VCard)[]): boolean; /** * @param { string } name * @param { boolean } item */ - static nomenu(name: string, item: boolean): boolean; - static altered(skillName: any): boolean; + nomenu(name: string, item: boolean): boolean; + altered(skillName: any): boolean; /** * @param { any } obj * @returns { boolean } */ - static node(obj: any): boolean; + node(obj: any): boolean; /** * @param { any } obj */ - static div(obj: any): boolean; + div(obj: any): boolean; /** * @param { any } obj */ - static map(obj: any): boolean; + map(obj: any): boolean; /** * @param { any } obj */ - static set(obj: any): boolean; + set(obj: any): boolean; /** * @param { any } obj */ - static object(obj: any): boolean; + object(obj: any): boolean; /** * @overload * @param { Function } func * @returns { false } */ - static singleSelect(func: Function): false; + singleSelect(func: Function): false; /** * @overload * @param { number | [number, number] } func * @returns { boolean } */ - static singleSelect(func: number | [number, number]): boolean; + singleSelect(func: number | [number, number]): boolean; /** * @param { string | Player } name */ - static jun(name: string | Player): boolean; - static versus(): boolean; - static changban(): boolean; - static single(): boolean; + jun(name: string | Player): boolean; + versus(): boolean; + changban(): boolean; + single(): boolean; /** * @param { Player } [player] */ - static mobileMe(player?: Player): boolean; - static newLayout(): boolean; - static phoneLayout(): boolean; - static singleHandcard(): any; + mobileMe(player?: any): any; + newLayout(): boolean; + phoneLayout(): boolean; + singleHandcard(): any; /** * @param { Player } player */ - static linked2(player: Player): boolean; + linked2(player: any): boolean; /** * @param { {} } obj */ - static empty(obj: {}): boolean; + empty(obj: {}): boolean; /** * @param { string } str */ - static pos(str: string): boolean; + pos(str: string): boolean; /** * @param { string } skill * @param { Player } player * @returns */ - static locked(skill: string, player: Player): any; + locked(skill: string, player: any): any; /** * @param { string } skill * @param { Player } player * @returns */ - static zhuanhuanji(skill: string, player: Player): boolean; + zhuanhuanji(skill: string, player: any): boolean; } -import { Uninstantable } from "../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/get/promises.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/get/promises.d.ts new file mode 100644 index 000000000..ac2e2754e --- /dev/null +++ b/node_modules/@types/noname-typings/nonameModules/noname/get/promises.d.ts @@ -0,0 +1,6 @@ +export class Promises { + /** + * @returns { Promise } + */ + zip(): Promise; +} diff --git a/node_modules/@types/noname-typings/nonameModules/noname/gnc/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/gnc/index.d.ts index 1a367b43b..b2143da90 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/gnc/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/gnc/index.d.ts @@ -1,12 +1,12 @@ -export class GNC extends Uninstantable { +export class GNC { /** * @param {GeneratorFunction} fn * @returns */ - static of(fn: GeneratorFunction): (...args: any[]) => Promise>; - static is: typeof Is; + of(fn: GeneratorFunction): (...args: any[]) => Promise>; + is: Is; } -export const gnc: typeof GNC; -import { Uninstantable } from "../util/index.js"; +export let gnc: GNC; +export function setGNC(instance?: GNC | undefined): void; import { GeneratorFunction } from "../util/index.js"; import { Is } from "./is.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/gnc/is.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/gnc/is.d.ts index eacd29580..146f217fa 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/gnc/is.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/gnc/is.d.ts @@ -1,18 +1,17 @@ -export class Is extends Uninstantable { +export class Is { /** * @param {*} item * @returns {boolean} */ - static coroutine(item: any): boolean; + coroutine(item: any): boolean; /** * @param {*} item * @returns {boolean} */ - static generatorFunc(item: any): boolean; + generatorFunc(item: any): boolean; /** * @param {*} item * @returns {boolean} */ - static generator(item: any): boolean; + generator(item: any): boolean; } -import { Uninstantable } from "../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/init/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/init/index.d.ts index 51456cf8c..eed360421 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/init/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/init/index.d.ts @@ -1,4 +1,4 @@ -export function canUseHttpProtocol(): boolean; +export function canUseHttpProtocol(): any; /** * 传递升级完成的信息 * @returns { string | void } 返回一个网址 diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/announce/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/announce/index.d.ts index 8e4af684b..34bc22c4b 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/announce/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/announce/index.d.ts @@ -1,53 +1,78 @@ -import { NonameAnnounceType } from "./interface.d.ts" - -export interface IAnnounceSubscriber { - subscribe(name: string): void; - unsubscribe(name: string): void; - - get isEmpty(): boolean -} - -export type AnnounceSubscriberType = new ( - content: (value: T, name: string) => void, - target: EventTarget -) => IAnnounceSubscriber; - +/** + * @template T + * @typedef {import("./index").AnnounceSubscriberType} AnnounceSubscriberType + */ +/** + * @typedef {import("./index").IAnnounceSubscriber} IAnnounceSubscriber + */ +/** + * + */ export class Announce { - constructor(eventTarget: EventTarget, records: WeakMap<((arg0: any) => void), IAnnounceSubscriber>, SubscriberType: AnnounceSubscriberType = AnnounceSubscriber) - - /** - * 推送任意数据给所有监听了指定事件的订阅者,并返回给定的数据 - * - * 若不存在订阅指定事件的订阅者,则推送的数据将无意义 - * - * @param name - 要推送事件的名称 - * @param values - 要推送的数据 - */ - publish(name: Name, values: Parameters[0]): Parameters[0] - - /** - * 订阅给定名字的事件,并返回给定的函数 - * - * 在事件触发时执行给定的函数 - * - * 给定的函数将被存储至当前实例中,用于取消订阅时获取 - * - * @param name - 要订阅事件的名称 - * @param method - 事件触发时执行的函数 - */ - subscribe(name: Name, method: Type[Name]): Type[Name] - - /** - * 取消指定事件某一个函数的订阅,并返回该函数 - * - * 给定的函数将不再于事件触发时执行,其余同事件需触发的函数不受限制 - * - * @param name - 要取消订阅事件的名称 - * @param method - 订阅指定事件的函数 - */ - unsubscribe(name: Name, method: Type[Name]): Type[Name] + /** + * + * @param {EventTarget} eventTarget + * @param {WeakMap} records + * @param {AnnounceSubscriberType} [SubscriberType] + */ + constructor(eventTarget: EventTarget, records: WeakMap<(arg0: any) => void, IAnnounceSubscriber>, SubscriberType?: AnnounceSubscriberType | undefined); + /** + * 推送任意数据给所有监听了指定事件的订阅者,并返回给定的数据 + * + * 若不存在订阅指定事件的订阅者,则推送的数据将无意义 + * + * @template T + * @param {string} name - 要推送事件的名称 + * @param {T} values - 要推送的数据 + * @returns {T} + */ + publish(name: string, values: T): T; + /** + * 订阅给定名字的事件,并返回给定的函数 + * + * 在事件触发时执行给定的函数 + * + * 给定的函数将被存储至当前实例中,用于取消订阅时获取 + * + * @template T + * @param {string} name - 要订阅事件的名称 + * @param {(values: T) => void} method - 事件触发时执行的函数 + * @returns {(values: T) => void} + */ + subscribe(name: string, method: (values: T_1) => void): (values: T_1) => void; + /** + * 取消指定事件某一个函数的订阅,并返回该函数 + * + * 给定的函数将不再于事件触发时执行,其余同事件需触发的函数不受限制 + * + * @template T + * @param {string} name - 要取消订阅事件的名称 + * @param {(values: T) => void} method - 订阅指定事件的函数 + * @returns {(values: T) => void} + */ + unsubscribe(name: string, method: (values: T_2) => void): (values: T_2) => void; + #private; } - -export class AnnounceSubscriber implements IAnnounceSubscriber { - constructor(content: (value: T, name: string) => void, target: EventTarget) +/** + * @template T + */ +export class AnnounceSubscriber { + /** + * + * @param {function(T, string): void} content + * @param {EventTarget} target + */ + constructor(content: (arg0: T, arg1: string) => void, target: EventTarget); + get isEmpty(): boolean; + /** + * @param {string} name + */ + subscribe(name: string): void; + /** + * @param {string} name + */ + unsubscribe(name: string): void; + #private; } +export type AnnounceSubscriberType = import("./index").AnnounceSubscriberType; +export type IAnnounceSubscriber = import("./index").IAnnounceSubscriber; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/announce/interface.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/announce/interface.d.ts deleted file mode 100644 index 329a6be84..000000000 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/announce/interface.d.ts +++ /dev/null @@ -1,54 +0,0 @@ - -export interface NonameAnnounceType { - // Apperaence 外观区域 - // 用于关于无名杀外观方面的通知 - - // Apperaence.Theme 无名杀主题区域 - /** - * 主题正在被切换时通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChanging": AnnounceFunction - - /** - * 主题被切换时通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChanged": AnnounceFunction - - /** - * 主题被切换时,已经显示完毕后通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChangeFinished": AnnounceFunction - - // Game 游戏区域 - // 包含游戏对局下的通知 - - // Game.Event 事件区域 - /** - * 当游戏对局开始时进行通知 - * - * @param values - 空对象 - */ - "Noname.Game.Event.GameStart": AnnounceFunction<{}> - - - // Init 初始化区域 - // 用于关于初始化方面的通知 - - // Init.Extension 扩展初始化区域 - /** - * 当扩展初始化完成时通知 - * - * @param values - 扩展名称 - */ - "Noname.Init.Extension.onLoad": AnnounceFunction - - -} - -export type AnnounceFunction = (values: T) => void diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/cache/cacheContext.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/cache/cacheContext.d.ts index 14c9cd09a..1e90c9af0 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/cache/cacheContext.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/cache/cacheContext.d.ts @@ -33,14 +33,14 @@ export class CacheContext { * @param {Array} methods * @returns */ - static inject(source: any, methods: Array): any; + static inject(source: any, methods: Array): null | undefined; static _getCacheValueFromObject(storage: any, key: any, params: any, source: any, func: any): any; static _ensureMember(obj: any, key: any): any; static _wrapParametersToCacheKey(params: any): string; static _wrapParameterToCacheKey(param: any): any; - lib: typeof Library; - game: typeof Game; - get: typeof Get; + lib: import("../index.js").Library; + game: import("../../game/index.js").Game; + get: import("../../get/index.js").Get; sourceMap: Map; storageMap: Map; /** @@ -59,6 +59,3 @@ export class CacheContext { */ _createCacheProxy(delegateObject: T): T; } -import { Library } from "../index.js"; -import { Game } from "../../game/index.js"; -import { Get } from "../../get/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/channel/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/channel/index.d.ts index a929b8a42..2631e4630 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/channel/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/channel/index.d.ts @@ -9,7 +9,7 @@ export class Channel { /** * @type {PromiseResolve | [T, PromiseResolve] | null} */ - _buffer: ((value?: T | PromiseLike) => void) | [T, (value?: void | PromiseLike) => void]; + _buffer: ((value?: T | PromiseLike | undefined) => void) | [T, (value?: void | PromiseLike | undefined) => void] | null; /** * 向该频道发送消息,在消息未被接受前将等待 * diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/button.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/button.d.ts index 7e360e942..58f5afd4d 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/button.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/button.d.ts @@ -6,8 +6,12 @@ export class Button extends HTMLDivElement { * @param {true} [noClick] * @param { Button } [button] */ - constructor(item: {}, type: "character" | "tdnodes" | "blank" | "card" | "vcard" | "characterx" | "player" | ((item: {}, type: Function, position?: HTMLDivElement | DocumentFragment, noClick?: true, button?: Button) => Button), position?: HTMLDivElement | DocumentFragment, noClick?: true, button?: Button); + constructor(item: {}, type: "character" | "tdnodes" | "blank" | "card" | "vcard" | "characterx" | "player" | ((item: {}, type: Function, position?: HTMLDivElement | DocumentFragment, noClick?: true, button?: Button) => Button), position?: HTMLDivElement | DocumentFragment | undefined, noClick?: true | undefined, button?: Button | undefined); + /** + * @type { string | undefined } + */ + buttonid: string | undefined; exclude(): void; get updateTransform(): (bool: any, delay: any) => void; } -import { UI as ui } from '../../ui/index.js'; +import { ui } from '../../ui/index.js'; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/card.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/card.d.ts index 649da9a72..cce666e53 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/card.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/card.d.ts @@ -2,12 +2,12 @@ export class Card extends HTMLDivElement { /** * @param {HTMLDivElement|DocumentFragment} [position] */ - constructor(position?: HTMLDivElement | DocumentFragment); + constructor(position?: HTMLDivElement | DocumentFragment | undefined); /** * @param {'noclick'} [info] * @param {true} [noclick] */ - build(info?: 'noclick', noclick?: true): this; + build(info?: "noclick" | undefined, noclick?: true | undefined): this; buildEventListener(info: any): void; buildProperty(): void; /** @@ -38,8 +38,8 @@ export class Card extends HTMLDivElement { willBeDestroyed(targetPosition: any, player: any, event: any): any; hasNature(nature: any, player: any): boolean; addNature(nature: any): string; - nature: string; - removeNature(nature: any): string; + nature: string | undefined; + removeNature(nature: any): string | undefined; addGaintag(gaintag: any): void; removeGaintag(tag: any): void; hasGaintag(tag: any): boolean; @@ -57,10 +57,10 @@ export class Card extends HTMLDivElement { name: string; nature: string; }): this; - suit: string; - number: number; + suit: string | undefined; + number: number | undefined; destroyed: any; - cardid: string; + cardid: string | undefined; /** * @param {[string, number, string, string]} card */ @@ -68,17 +68,17 @@ export class Card extends HTMLDivElement { updateTransform(bool: any, delay: any): void; aiexclude(): void; addKnower(player: any): void; - _knowers: any[]; + _knowers: any[] | undefined; removeKnower(player: any): void; clearKnowers(): void; isKnownBy(player: any): boolean; getSource(name: any): any; moveDelete(player: any): void; - fixed: boolean; + fixed: boolean | undefined; _onEndMoveDelete: any; moveTo(player: any): this; copy(...args: any[]): Card; - clone: Card; + clone: Card | undefined; uncheck(skill: any): void; recheck(skill: any): void; /** diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/contents.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/contents.d.ts index 64d9acd0f..3d3de19f4 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/contents.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/contents.d.ts @@ -1,4 +1,4 @@ /** * @type { SMap<((event: GameEventPromise, trigger: GameEventPromise, player: Player) => Promise)[]> } */ -export const Contents: SMap<((event: GameEventPromise, trigger: GameEventPromise, player: Player) => Promise)[]>; +export const Contents: SMap<((event: any, trigger: any, player: any) => Promise)[]>; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/dialog.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/dialog.d.ts index 9f47f32f2..388b39ecc 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/dialog.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/dialog.d.ts @@ -22,16 +22,16 @@ export class Dialog extends HTMLDivElement { * @param {*} [noclick] * @param { boolean } [zoom] */ - add(item: string | HTMLDivElement | Card[] | Player[], noclick?: any, zoom?: boolean): string | HTMLDivElement | import("./player.js").Player[] | import("./card.js").Card[]; - forcebutton: boolean; + add(item: string | HTMLDivElement | Card[] | Player[], noclick?: any, zoom?: boolean | undefined): string | any[] | HTMLDivElement; + forcebutton: boolean | undefined; /** * @param { string } str * @param { boolean } [center] */ - addText(str: string, center?: boolean): this; - addSmall(item: any, noclick: any): string | HTMLDivElement | import("./player.js").Player[] | import("./card.js").Card[]; + addText(str: string, center?: boolean | undefined): this; + addSmall(item: any, noclick: any): string | any[] | HTMLDivElement; addAuto(content: any): void; - open(): this; + open(): this | undefined; _dragtransform: any; close(): this; /** diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEvent.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEvent.d.ts index f075e95cc..efa0b6699 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEvent.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEvent.d.ts @@ -1,10 +1,10 @@ export class GameEvent { - static initialGameEvent(): import("../index.js").GameEventPromise; + static initialGameEvent(): GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param {string | GameEvent} [name] * @param {false} [trigger] */ - constructor(name?: string | GameEvent, trigger?: false); + constructor(name?: string | GameEvent | undefined, trigger?: false | undefined); /** * @type { string } */ @@ -37,21 +37,21 @@ export class GameEvent { /** * @type {null|(event: GameEvent)=>any} 这个异步事件对应Promise的resolve函数 **/ - resolve: (event: GameEvent) => any; - _triggered: number; + resolve: ((event: GameEvent) => any) | null; + _triggered: number | undefined; __args: any; /** * @type { Player } */ - source: Player; + source: any; /** * @type { Player } */ - player: Player; + player: any; /** * @type { Player } */ - target: Player; + target: any; /** * @type { Player[] } */ @@ -59,7 +59,7 @@ export class GameEvent { /** * @type { Card } */ - card: Card; + card: any; /** * @type { Card[] } */ @@ -87,7 +87,7 @@ export class GameEvent { /** * @type { Player } */ - customSource: Player; + customSource: any; /** * @type { number } */ @@ -129,23 +129,23 @@ export class GameEvent { * @param {number} [value] * @param {number} [baseValue] */ - addNumber(key: keyof this, value?: number, baseValue?: number): this; + addNumber(key: keyof this, value?: number | undefined, baseValue?: number | undefined): this; /** * @param {keyof this} key * @param {number} [baseValue] */ - decrease(key: keyof this, baseValue?: number): this; + decrease(key: keyof this, baseValue?: number | undefined): this; /** * @param {keyof this} key * @param {number} [baseValue] */ - increase(key: keyof this, baseValue?: number): this; + increase(key: keyof this, baseValue?: number | undefined): this; /** * @param {keyof this} key * @param {number} [value] * @param {number} [baseValue] */ - subtractNumber(key: keyof this, value?: number, baseValue?: number): this; + subtractNumber(key: keyof this, value?: number | undefined, baseValue?: number | undefined): this; /** * @param {Parameters[0]} type * @param {GameEvent} event @@ -157,7 +157,7 @@ export class GameEvent { callHandler(type: Parameters[0], event: GameEvent, option: { state?: 'begin' | 'end'; }): this; - getDefaultHandlerType(): string; + getDefaultHandlerType(): string | undefined; /** * @param {Parameters[0]} [type] * @returns {((event: GameEvent, option: { @@ -170,7 +170,7 @@ export class GameEvent { /** * @param {`on${Capitalize}`} [type] */ - hasHandler(type?: `on${Capitalize}`): any; + hasHandler(type?: `on${Capitalize}` | undefined): any; /** * @overload * @param {...((event: GameEvent, option: { @@ -180,7 +180,7 @@ export class GameEvent { */ pushHandler(...handlers: ((event: GameEvent, option: { state?: 'begin' | 'end'; - }) => void)[]): number; + }) => void)[] | undefined): number; /** * @overload * @param {Parameters[0]} type @@ -191,24 +191,24 @@ export class GameEvent { */ pushHandler(type: Parameters[0], ...handlers: ((event: GameEvent, option: { state?: 'begin' | 'end'; - }) => void)[]): number; + }) => void)[] | undefined): number; changeToZero(): this; - numFixed: boolean; + numFixed: boolean | undefined; finish(): this; putStepCache(key: any, value: any): this; - _stepCache: {}; + _stepCache: {} | undefined; getStepCache(key: any): any; clearStepCache(key: any): this; callFuncUseStepCache(prefix: any, func: any, params: any): any; putTempCache(key1: any, key2: any, value: any): any; - _tempCache: {}; + _tempCache: {} | undefined; getTempCache(key1: any, key2: any): any; - cancel(arg1: any, arg2: any, notrigger: any): import("../index.js").GameEventPromise; + cancel(arg1: any, arg2: any, notrigger: any): (GameEvent & import("./gameEventPromise.js").GameEventPromise) | null | undefined; neutralize(event: any): this; - _neutralized: boolean; + _neutralized: boolean | undefined; _neutralize_event: any; unneutralize(): this; - directHit: boolean; + directHit: boolean | undefined; goto(step: any): this; redo(): this; setHiddenSkill(skill: any): this; @@ -224,7 +224,7 @@ export class GameEvent { * @returns {GameEvent} */ setContents(contents: Function | keyof typeof lib.element.contents): GameEvent; - contents: (string | number | Function) & any[]; + contents: ((string | number | Function) & any[]) | undefined; getLogv(): any; send(): this; resume(): this; @@ -237,20 +237,20 @@ export class GameEvent { * @param {boolean} [includeSelf] 若level不是数字,指定搜索时是否包含事件本身 * @returns {GameEvent|{}|null} */ - getParent(level?: string | number | ((evt: gameEvent) => boolean), forced?: boolean, includeSelf?: boolean): GameEvent | {} | null; + getParent(level?: string | number | ((evt: gameEvent) => boolean) | undefined, forced?: boolean | undefined, includeSelf?: boolean | undefined): GameEvent | {} | null; getTrigger(): any; getRand(name: any): any; - _rand_map: {}; - _rand: number; - insert(content: any, map: any): import("../index.js").GameEventPromise; - insertAfter(content: any, map: any): import("../index.js").GameEventPromise; + _rand_map: {} | undefined; + _rand: number | undefined; + insert(content: any, map: any): GameEvent & import("./gameEventPromise.js").GameEventPromise; + insertAfter(content: any, map: any): GameEvent & import("./gameEventPromise.js").GameEventPromise; backup(skill: any): this; _backup: any; filterButton: any; selectButton: any; filterTarget: any; selectTarget: any; - ignoreMod: boolean; + ignoreMod: boolean | undefined; filterCard2: any; filterCard: any; filterOk: any; @@ -267,20 +267,18 @@ export class GameEvent { _cardChoice: any; _targetChoice: any; _skillChoice: any; - isMine(): boolean; - isOnline(): boolean; + isMine(): any; + isOnline(): any; notLink(): boolean; isPhaseUsing(player: any): boolean; addTrigger(skills: any, player: any): this; removeTrigger(skills: any, player: any): this; - trigger(name: any): import("../index.js").GameEventPromise; - untrigger(all: boolean, player: any): this; + trigger(name: any): (GameEvent & import("./gameEventPromise.js").GameEventPromise) | null | undefined; + untrigger(all: boolean | undefined, player: any): this; /** * 事件转为Promise化 - * - * @returns { GameEventPromise } */ - toPromise(): GameEventPromise; + toPromise(): this & import("./gameEventPromise.js").GameEventPromise; #private; } -import { Library as lib } from "../index.js"; +import { lib } from "../index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEventPromise.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEventPromise.d.ts index e2d98f1f2..eb2481761 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEventPromise.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/gameEventPromise.d.ts @@ -21,11 +21,11 @@ * game.log('等待', player, '摸牌完成执行log'); * ``` */ -export class GameEventPromise extends Promise { +export class GameEventPromise extends Promise { /** - * @param { GameEvent | GameEventPromise } arg + * @param { import('./gameEvent.js').GameEvent } arg */ - constructor(arg: GameEvent | GameEventPromise); + constructor(arg: import('./gameEvent.js').GameEvent); /** 获取原事件对象 */ toEvent(): import("./gameEvent.js").GameEvent; /** @@ -45,46 +45,117 @@ export class GameEventPromise extends Promise; /** - * - * 直接获得result中的信息。 - * - * + * 获取 Result 对象中的信息。 * @example - * ① - * let chooseCardResult = await player.chooseCard().forResult(); - * 选择的卡牌:chooseCardResult.cards - * ② - * let cards = await player.chooseCard().forResult('cards'); - * 选择的卡牌:cards - * ③ - * let [success,cards,targets] = await player.chooseCardTarget().forResult('bool','cards','targets'); - * success:是否做出选择。 - * cards:选择的牌。 - * targets:选择的目标。 + * ```js + // 示例 1: + const chooseCardResult = await player.chooseCard().forResult(); + // 获取整个结果对象,然后访问如 chooseCardResult.cards 等属性 + + // 示例 2: + const cards = await player.chooseCard().forResult('cards'); + // 获取结果对象中 'cards' 属性的值 + + // 示例 3: + const [success, cards, targets] = await player.chooseCardTarget().forResult('bool', 'cards', 'targets'); + // 获取结果对象中多个属性的值 + // - success 表示是否成功 + // - cards 表示选择的卡片 + // - targets 表示选择的目标 + ``` + * @template {keyof Result} T + * @overload + * @returns {Promise} * - * @returns {Promise} 返回的结果 + * @overload + * @param {T} param0 + * @returns {Promise>} + * + * @overload + * @param { T[] } params + * @returns { Promise[]> } */ - forResult(...args: any[]): Promise; + forResult(): Promise; /** - * 返回result中的bool项。 + * 获取 Result 对象中的信息。 + * @example + * ```js + // 示例 1: + const chooseCardResult = await player.chooseCard().forResult(); + // 获取整个结果对象,然后访问如 chooseCardResult.cards 等属性 + + // 示例 2: + const cards = await player.chooseCard().forResult('cards'); + // 获取结果对象中 'cards' 属性的值 + + // 示例 3: + const [success, cards, targets] = await player.chooseCardTarget().forResult('bool', 'cards', 'targets'); + // 获取结果对象中多个属性的值 + // - success 表示是否成功 + // - cards 表示选择的卡片 + // - targets 表示选择的目标 + ``` + * @template {keyof Result} T + * @overload + * @returns {Promise} * - * @returns {Promise} 返回的bool项 + * @overload + * @param {T} param0 + * @returns {Promise>} + * + * @overload + * @param { T[] } params + * @returns { Promise[]> } + */ + forResult(param0: T): Promise>; + /** + * 获取 Result 对象中的信息。 + * @example + * ```js + // 示例 1: + const chooseCardResult = await player.chooseCard().forResult(); + // 获取整个结果对象,然后访问如 chooseCardResult.cards 等属性 + + // 示例 2: + const cards = await player.chooseCard().forResult('cards'); + // 获取结果对象中 'cards' 属性的值 + + // 示例 3: + const [success, cards, targets] = await player.chooseCardTarget().forResult('bool', 'cards', 'targets'); + // 获取结果对象中多个属性的值 + // - success 表示是否成功 + // - cards 表示选择的卡片 + // - targets 表示选择的目标 + ``` + * @template {keyof Result} T + * @overload + * @returns {Promise} + * + * @overload + * @param {T} param0 + * @returns {Promise>} + * + * @overload + * @param { T[] } params + * @returns { Promise[]> } + */ + forResult(params: T[]): Promise[]>; + /** + * 返回result中的bool项 + */ + forResultTest(): Promise<(boolean | any[])[]>; + /** + * 返回result中的bool项 */ forResultBool(): Promise; /** * 返回result中的targets项。 - * - * @returns {Promise} 返回的targets项。 - * */ - forResultTargets(): Promise; + forResultTargets(): Promise; /** * 返回result中的cards项 - * - * @returns {Promise} 返回的cards项。 - * */ - forResultCards(): Promise; + forResultCards(): Promise; /** * 返回result中的card项 * @@ -94,15 +165,11 @@ export class GameEventPromise extends Promise | Promise; /** * 返回result中的control项。 - * - * @returns {Promise} 返回的control项。 */ forResultControl(): Promise; /** * 返回result中的links项。 - * - * @returns {Promise>} 返回的links项。 */ - forResultLinks(): Promise>; + forResultLinks(): Promise; #private; } diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/nodeWS.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/nodeWS.d.ts index 1e7572241..3a7c6e9ff 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/nodeWS.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/nodeWS.d.ts @@ -3,7 +3,7 @@ export class NodeWS { * @param {string | NodeWS} id */ constructor(id: string | NodeWS); - wsid: string; + wsid: string | undefined; send(message: any): void; on(type: any, func: any): void; close(): void; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/player.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/player.d.ts index 71495b209..34afa35d4 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/player.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/player.d.ts @@ -2,7 +2,7 @@ export class Player extends HTMLDivElement { /** * @param {HTMLDivElement|DocumentFragment} [position] */ - constructor(position?: HTMLDivElement | DocumentFragment); + constructor(position?: HTMLDivElement | DocumentFragment | undefined); build(noclick: any): this; buildNode(): void; /** @type { SMap } */ @@ -143,7 +143,7 @@ export class Player extends HTMLDivElement { */ outCount: number; buildEventListener(noclick: any): void; - noclick: boolean; + noclick: boolean | undefined; /** * @type { number } */ @@ -213,7 +213,7 @@ export class Player extends HTMLDivElement { * @param { number } amount * @param { boolean } [limit] */ - changeFury(amount: number, limit?: boolean): void; + changeFury(amount: number, limit?: boolean | undefined): void; /** * version 1.7 * @@ -290,35 +290,35 @@ export class Player extends HTMLDivElement { /** * 让一名角色明置一些手牌 */ - addShownCards(...args: any[]): import("../index.js").GameEventPromise; - hideShownCards(...args: any[]): import("../index.js").GameEventPromise; + addShownCards(...args: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + hideShownCards(...args: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; /** * 获取角色所有的明置手牌 */ - getShownCards(): import("./card.js").Card[]; + getShownCards(): any[]; /** * 获取该角色被other所知的牌 * @param { Player } [other] * @param { (card: Card) => boolean } [filter] */ - getKnownCards(other?: Player, filter?: (card: Card) => boolean): import("./card.js").Card[]; + getKnownCards(other?: Player | undefined, filter?: ((card: any) => boolean) | undefined): any[]; /** * 判断此角色的手牌是否已经被看光了 * @param { Player } [other] */ - isAllCardsKnown(other?: Player): boolean; + isAllCardsKnown(other?: Player | undefined): boolean; /** * 判断此角色是否有被知的牌。 * @param { Player } [other] * @param { (card: Card) => boolean } [filter] */ - hasKnownCards(other?: Player, filter?: (card: Card) => boolean): boolean; + hasKnownCards(other?: Player | undefined, filter?: ((card: any) => boolean) | undefined): boolean; /** * 数此角色被知道的牌 * @param { Player } [other] * @param { (card: Card) => boolean } [filter] */ - countKnownCards(other?: Player, filter?: (card: Card) => boolean): number; + countKnownCards(other?: Player | undefined, filter?: ((card: any) => boolean) | undefined): number; /** * Execute the delay card effect * @@ -329,14 +329,14 @@ export class Player extends HTMLDivElement { * @param {*} judge2 * @returns */ - executeDelayCardEffect(card: Card | string, target: Player, judge: any, judge2: any, ...args: any[]): import("../index.js").GameEventPromise; + executeDelayCardEffect(card: Card | string, target: Player, judge: any, judge2: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * Check if the card does not count toward hand limit * * 检测此牌是否不计入手牌上限 * @param { Card } card */ - canIgnoreHandcard(card: Card): boolean; + canIgnoreHandcard(card: any): boolean; /** * Gift * @@ -344,7 +344,7 @@ export class Player extends HTMLDivElement { * @param { Card | Card[] } cards * @param { Player } target */ - gift(cards: Card | Card[], target: Player, ...args: any[]): import("../index.js").GameEventPromise; + gift(cards: Card | Card[], target: Player, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * Check if the player can gift the card * @@ -353,7 +353,7 @@ export class Player extends HTMLDivElement { * @param { Player } target * @param { boolean } [strict] */ - canGift(card: Card, target: Player, strict?: boolean): boolean; + canGift(card: any, target: Player, strict?: boolean | undefined): boolean; /** * Check if the player refuses gifts * @@ -361,7 +361,7 @@ export class Player extends HTMLDivElement { * @param { Card } card * @param { Player } player */ - refuseGifts(card: Card, player: Player): boolean; + refuseGifts(card: any, player: Player): boolean; /** * Gift AI related * @@ -369,19 +369,19 @@ export class Player extends HTMLDivElement { * @param { Card } card * @param { Player } target */ - getGiftAIResultTarget(card: Card, target: Player): number; + getGiftAIResultTarget(card: any, target: Player): number; /** * @param { Card } card * @param { Player } target */ - getGiftEffect(card: Card, target: Player): number; + getGiftEffect(card: any, target: Player): number; /** * 重铸 * @param { Card | Card[] } cards * @param { (player: Player, cards: Card[]) => any } [recastingLose] * @param { (player: Player, cards: Card[]) => any } [recastingGain] */ - recast(cards: Card | Card[], recastingLose?: (player: Player, cards: Card[]) => any, recastingGain?: (player: Player, cards: Card[]) => any, ...args: any[]): import("../index.js").GameEventPromise; + recast(cards: Card | Card[], recastingLose?: ((player: Player, cards: Card[]) => any) | undefined, recastingGain?: ((player: Player, cards: Card[]) => any) | undefined, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * Check if the player can recast the card * @@ -390,7 +390,7 @@ export class Player extends HTMLDivElement { * @param { Player } [source] * @param { boolean } [strict] */ - canRecast(card: Card, source?: Player, strict?: boolean): boolean; + canRecast(card: any, source?: Player | undefined, strict?: boolean | undefined): boolean; /** * 判断一名角色的某个区域是否被废除 * @@ -398,39 +398,39 @@ export class Player extends HTMLDivElement { * @param { string | number } [type] * @returns { boolean } */ - hasDisabledSlot(type?: string | number): boolean; + hasDisabledSlot(type?: string | number | undefined): boolean; /** * 判断一名角色的某个区域被废除的数量 * * 用法同 {@link hasDisabledSlot} * @param { string | number } [type] */ - countDisabledSlot(type?: string | number): number; + countDisabledSlot(type?: string | number | undefined): number; /** * 判断一名角色是否有某个装备栏空着 * @param { string | number } [type] * @returns { boolean } */ - hasEmptySlot(type?: string | number): boolean; + hasEmptySlot(type?: string | number | undefined): boolean; /** * 判断一名角色的某个装备栏空位的数量 * @param { string | number } [type] */ - countEmptySlot(type?: string | number): number; + countEmptySlot(type?: string | number | undefined): number; /** * 判断一名角色是否有可以用于装备新装备牌的区域(排除金箍棒和六龙等“不可被替换装备”) * * 用法同 {@link hasEnabledSlot} * @param { string | number } [type] */ - hasEquipableSlot(type?: string | number): boolean; + hasEquipableSlot(type?: string | number | undefined): boolean; /** * 统计一名角色有多少个可以用于装备新的装备牌的区域 * * 用法同 {@link hasEnabledSlot} * @param { string | number } [type] */ - countEquipableSlot(type?: string | number): number; + countEquipableSlot(type?: string | number | undefined): number; /** * 判断一名角色是否拥有未被废除的某个区域 * @@ -438,14 +438,14 @@ export class Player extends HTMLDivElement { * @param { string | number } [type] * @returns { boolean } */ - hasEnabledSlot(type?: string | number): boolean; + hasEnabledSlot(type?: string | number | undefined): boolean; /** * 判断一名角色的某个区域未被废除的数量 * * 用法同 {@link hasEnabledSlot} * @param { string | number } [type] */ - countEnabledSlot(type?: string | number): number; + countEnabledSlot(type?: string | number | undefined): number; /** * 获取一名角色装备区内某种类型的装备牌 * @@ -459,19 +459,19 @@ export class Player extends HTMLDivElement { * * 参数:废除来源角色(不写默认当前事件角色),废除区域(数字/区域字符串/数组,可以写多个,重复废除) */ - disableEquip(...args: any[]): import("../index.js").GameEventPromise; + disableEquip(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * 新的恢复装备区 * * 参数:恢复来源角色(不写默认当前事件角色),恢复区域(数字/区域字符串/数组,可以写多个,重复恢复) */ - enableEquip(...args: any[]): import("../index.js").GameEventPromise; + enableEquip(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * 新的扩展装备区 * * 参数:扩展来源角色(不写默认当前事件角色),扩展区域(数字/区域字符串/数组,可以写多个,重复扩展) */ - expandEquip(...args: any[]): import("../index.js").GameEventPromise; + expandEquip(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * 判断判定区是否被废除 */ @@ -480,18 +480,18 @@ export class Player extends HTMLDivElement { * 同步显示扩展装备区状态 * @param { SMap } [map] */ - $syncExpand(map?: SMap): void; + $syncExpand(map?: SMap | undefined): void; /** * 同步装备区废除牌显示状态 * @param { SMap } [map] */ - $syncDisable(map?: SMap): void; + $syncDisable(map?: SMap | undefined): void; /** * @param { string | Card | VCard | CardBaseUIData } name * @param { boolean } [replace] * @returns */ - canEquip(name: string | Card | VCard | CardBaseUIData, replace?: boolean): boolean; + canEquip(name: string | Card | VCard | CardBaseUIData, replace?: boolean | undefined): boolean; /** * @deprecated */ @@ -512,7 +512,7 @@ export class Player extends HTMLDivElement { * @deprecated */ $enableEquip(): void; - chooseToDebate(...args: any[]): import("../index.js").GameEventPromise; + chooseToDebate(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * 向target发起协力 * @param { Player } target @@ -520,7 +520,7 @@ export class Player extends HTMLDivElement { * @param {*} reason */ cooperationWith(target: Player, type: any, reason: any): void; - chooseCooperationFor(...args: any[]): import("../index.js").GameEventPromise; + chooseCooperationFor(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; checkCooperationStatus(target: any, reason: any): boolean; removeCooperation(info: any): void; /** @@ -564,7 +564,7 @@ export class Player extends HTMLDivElement { * @param { string } skill */ removeSkillBlocker(skill: string): void; - loseToSpecial(cards: any, tag: any, target: any): import("../index.js").GameEventPromise; + loseToSpecial(cards: any, tag: any, target: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { Card | Card[] } cards * @param { string } tag @@ -574,7 +574,7 @@ export class Player extends HTMLDivElement { * @param { string } tag * @param { Card[] } [cards] */ - removeGaintag(tag: string, cards?: Card[]): void; + removeGaintag(tag: string, cards?: any[] | undefined): void; /** * @param { Player } target */ @@ -583,31 +583,31 @@ export class Player extends HTMLDivElement { * @param { Card } card * @param { Player } target */ - canSaveCard(card: Card, target: Player): any; + canSaveCard(card: any, target: Player): any; /** * @param { String } from * @param { String } to * @returns { GameEventPromise } */ - reinitCharacter(from: string, to: string, log?: boolean): GameEventPromise; + reinitCharacter(from: string, to: string, log?: boolean): any; /** * @param { String[] } newPairs * @returns { GameEventPromise } */ - changeCharacter(newPairs: string[], log?: boolean): GameEventPromise; + changeCharacter(newPairs: string[], log?: boolean): any; /** * @param { 0 | 1 | 2 } num * @param { false } [log] */ - showCharacter(num: 0 | 1 | 2, log?: false, ...args: any[]): import("../index.js").GameEventPromise; + showCharacter(num: 0 | 1 | 2, log?: false | undefined, ...args: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; /** * @param { 0 | 1 | 2 } num * @param { false } [log] */ - $showCharacter(num: 0 | 1 | 2, log?: false): void; - chooseToPlayBeatmap(beatmap: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseToMove(...args: any[]): import("../index.js").GameEventPromise; - chooseToGuanxing(num: any): import("../index.js").GameEventPromise; + $showCharacter(num: 0 | 1 | 2, log?: false | undefined): void; + chooseToPlayBeatmap(beatmap: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToMove(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToGuanxing(num: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { Player } target * @param { string } name @@ -630,12 +630,12 @@ export class Player extends HTMLDivElement { * @param { string } [nature] * @param { string } [popname] */ - tryCardAnimate(card: Card, name: string, nature?: string, popname?: string, ...args: any[]): void; + tryCardAnimate(card: any, name: string, nature?: string | undefined, popname?: string | undefined, ...args: any[]): void; /** * @param { string } name * @param { string } type */ - hasUsableCard(name: string, type: string): boolean; + hasUsableCard(name: string, type: string): true | undefined; /** * @param { Player } to * @returns { boolean } @@ -652,7 +652,7 @@ export class Player extends HTMLDivElement { * * @param { boolean } [raw] */ - getHp(raw?: boolean): number; + getHp(raw?: boolean | undefined): number; /** * Set “raw” to true to get the player's raw damaged HP instead. * @@ -660,45 +660,45 @@ export class Player extends HTMLDivElement { * * @param { boolean } [raw] */ - getDamagedHp(raw?: boolean): number; + getDamagedHp(raw?: boolean | undefined): number; /** * @param { string } group */ - changeGroup(group: string, log: any, broadcast: any, ...args: any[]): import("../index.js").GameEventPromise; + changeGroup(group: string, log: any, broadcast: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { Player } target */ - chooseToDuiben(target: Player): import("../index.js").GameEventPromise; + chooseToDuiben(target: Player): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { Player } target */ - chooseToPSS(target: Player): import("../index.js").GameEventPromise; - chooseToEnable(...args: any[]): import("../index.js").GameEventPromise; - chooseToDisable(...args: any[]): import("../index.js").GameEventPromise; + chooseToPSS(target: Player): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToEnable(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToDisable(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { boolean } [notmeisok] */ - isPhaseUsing(notmeisok?: boolean): boolean; + isPhaseUsing(notmeisok?: boolean | undefined): boolean; /** * @param { Player } target */ - swapEquip(target: Player): import("../index.js").GameEventPromise; + swapEquip(target: Player): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @param { Player } target * @param { boolean } [goon] * @param { boolean} [bool] */ - canCompare(target: Player, goon?: boolean, bool?: boolean): boolean; + canCompare(target: Player, goon?: boolean | undefined, bool?: boolean | undefined): boolean; $disableJudge(): void; $enableJudge(): void; - disableJudge(): import("../index.js").GameEventPromise; - enableJudge(): import("../index.js").GameEventPromise; - init(character: any, character2: any, skill: any, update: any): this; + disableJudge(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + enableJudge(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + init(character: any, character2: any, skill: any, update: any): this | undefined; skin: { name: any; name2: any; - }; - singleHp: boolean; + } | undefined; + singleHp: boolean | undefined; $init(character: any, character2: any): this; /** * 换肤换音:想要支持某个武将更换皮肤,必须在lib.character.characterSubstitute中存在该武将的id(以下以name代指武将id,character代指换肤图片名) @@ -717,17 +717,17 @@ export class Player extends HTMLDivElement { avatar: any; uninitOL(): void; initRoom(info: any, info2: any): this; - serving: boolean; - roomempty: boolean; - roomfull: boolean; - roomgaming: boolean; + serving: boolean | undefined; + roomempty: boolean | undefined; + roomfull: boolean | undefined; + roomgaming: boolean | undefined; version: any; key: any; config: any; reinit2(newPairs: any): void; $reinit12(newPairs: any): void; $reinit21(newPairs: any): void; - reinit(from: any, to: any, maxHp: any, online: any): this; + reinit(from: any, to: any, maxHp: any, online: any): this | undefined; $reinit(from: any, to: any, maxHp: any, online: any): void; uninit(): this; $uninit(): void; @@ -737,13 +737,13 @@ export class Player extends HTMLDivElement { changeSeat(position: any, video: any): void; send(...args: any[]): this; getId(): this; - playerid: string; + playerid: string | undefined; throwEmotion(target: any, emotion: any, rotate: any): void; emotion(pack: any, id: any): void; chat(str: any): void; say(str: any): void; showGiveup(): void; - _giveUp: boolean; + _giveUp: boolean | undefined; applySkills(skills: any): void; getState(): { hp: number; @@ -754,22 +754,22 @@ export class Player extends HTMLDivElement { name: string; name1: string; name2: string; - handcards: import("./card.js").Card[]; - gaintag: any[]; - equips: import("./card.js").Card[]; - judges: import("./card.js").Card[]; - specials: import("./card.js").Card[]; - expansions: import("./card.js").Card[]; - expansion_gaintag: any[]; + handcards: any[]; + gaintag: never[]; + equips: any[]; + judges: any[]; + specials: any[]; + expansions: any[]; + expansion_gaintag: never[]; disableJudge: boolean; disabledSlots: SMap; expandedSlots: SMap; - views: any[]; + views: never[]; position: number; hujia: number; side: any; identityShown: any; - identityNode: string[]; + identityNode: (string | undefined)[]; identity: any; dead: boolean; linked: boolean; @@ -801,8 +801,8 @@ export class Player extends HTMLDivElement { num(arg1: any, arg2: any, arg3: any): any; line(target: any, config: any): void; line2(targets: any, config: any): void; - getNext(): this; - getPrevious(): this; + getNext(): this | null; + getPrevious(): this | null; countUsed(card: any, type: any): number; getCacheKey(): string; countSkill(skill: any): any; @@ -812,13 +812,13 @@ export class Player extends HTMLDivElement { * @param { string | Record | ((card: Card) => boolean) } [arg2] * @returns { Iterable } */ - iterableGetCards(arg1?: string, arg2?: string | Record | ((card: Card) => boolean)): Iterable; + iterableGetCards(arg1?: string | undefined, arg2?: string | Record | ((card: any) => boolean) | undefined): Iterable; /** * @param { string } [arg1='h'] * @param { string | Record | ((card: Card) => boolean) } [arg2] * @returns { Card[] } */ - getCards(arg1?: string, arg2?: string | Record | ((card: Card) => boolean)): Card[]; + getCards(arg1?: string | undefined, arg2?: string | Record | ((card: any) => boolean) | undefined): Card[]; iterableGetDiscardableCards(player: any, arg1: any, arg2: any): Generator; getDiscardableCards(player: any, arg1: any, arg2: any): any[]; iterableGetGainableCards(player: any, arg1: any, arg2: any): Generator; @@ -831,100 +831,101 @@ export class Player extends HTMLDivElement { getOriginalSkills(): any[]; getModableSkills(): any[]; getSkills(arg2: any, arg3: any, arg4: any): any[]; - get(arg1: any, arg2: any, arg3: any, arg4: any, ...args: any[]): any[] | ChildNode; + get(arg1: any, arg2: any, arg3: any, arg4: any, ...args: any[]): any[] | ChildNode | undefined; syncStorage(skill: any): void; syncSkills(): void; playerfocus(time: any): this; setIdentity(identity: any, nature: any): this; - insertPhase(skill: any, insert: any): import("../index.js").GameEventPromise; - insertEvent(name: any, content: any, arg: any): import("../index.js").GameEventPromise; - phase(skill: any): import("../index.js").GameEventPromise; - phaseZhunbei(): import("../index.js").GameEventPromise; - phaseJudge(): import("../index.js").GameEventPromise; - phaseDraw(): import("../index.js").GameEventPromise; - phaseUse(): import("../index.js").GameEventPromise; - phaseDiscard(): import("../index.js").GameEventPromise; - phaseJieshu(): import("../index.js").GameEventPromise; - chooseToUse(use: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseToRespond(...args: any[]): import("../index.js").GameEventPromise; - chooseToGive(...args: any[]): import("../index.js").GameEventPromise; - chooseToDiscard(...args: any[]): import("../index.js").GameEventPromise; - chooseToCompare(target: any, check: any, ...args: any[]): import("../index.js").GameEventPromise; + insertPhase(skill: any, insert: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + insertEvent(name: any, content: any, arg: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phase(skill: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseZhunbei(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseJudge(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseDraw(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseUse(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseDiscard(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + phaseJieshu(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToUse(use: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToRespond(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToGive(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToDiscard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseToCompare(target: any, check: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; chooseSkill(target: any, ...args: any[]): void; - discoverCard(list: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseCardButton(...args: any[]): import("../index.js").GameEventPromise; - chooseVCardButton(...args: any[]): import("../index.js").GameEventPromise; - chooseButton(...args: any[]): import("../index.js").GameEventPromise; - chooseButtonOL(list: any, callback: any, ai: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseCardOL(...args: any[]): import("../index.js").GameEventPromise; - chooseCard(choose: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseUseTarget(...args: any[]): import("../index.js").GameEventPromise; - chooseTarget(...args: any[]): import("../index.js").GameEventPromise; - chooseCardTarget(choose: any, ...args: any[]): import("../index.js").GameEventPromise; - chooseControlList(...args: any[]): import("../index.js").GameEventPromise; - chooseControl(...args: any[]): import("../index.js").GameEventPromise; - chooseBool(...args: any[]): import("../index.js").GameEventPromise; - chooseDrawRecover(...args: any[]): import("../index.js").GameEventPromise; - choosePlayerCard(...args: any[]): import("../index.js").GameEventPromise; - discardPlayerCard(...args: any[]): import("../index.js").GameEventPromise; - gainPlayerCard(...args: any[]): import("../index.js").GameEventPromise; - showHandcards(str: any, ...args: any[]): import("../index.js").GameEventPromise; - showCards(cards: any, str: any, ...args: any[]): import("../index.js").GameEventPromise; - viewCards(str: any, cards: any, ...args: any[]): import("../index.js").GameEventPromise; - viewHandcards(target: any): false | import("../index.js").GameEventPromise; + discoverCard(list: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseCardButton(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseVCardButton(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseButton(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseButtonOL(list: any, callback: any, ai: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseCardOL(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseCard(choose: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseUseTarget(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseTarget(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseCardTarget(choose: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseControlList(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseControl(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseBool(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + chooseDrawRecover(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + choosePlayerCard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + discardPlayerCard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + gainPlayerCard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + showHandcards(str: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + showCards(cards: any, str: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + viewCards(str: any, cards: any, ...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + viewHandcards(target: any): false | (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise); canMoveCard(withatt: any, nojudge: any, ...args: any[]): boolean; - moveCard(...args: any[]): import("../index.js").GameEventPromise; - useResult(result: any, event: any): import("../index.js").GameEventPromise; - useCard(...args: any[]): import("../index.js").GameEventPromise; - useSkill(...args: any[]): import("../index.js").GameEventPromise; - drawTo(num: any, args: any): import("../index.js").GameEventPromise; - draw(...args: any[]): import("../index.js").GameEventPromise; - randomDiscard(...args: any[]): import("./card.js").Card[]; + moveCard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + useResult(result: any, event: any): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + useCard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + useSkill(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + drawTo(num: any, args: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + draw(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + randomDiscard(...args: any[]): any[]; randomGain(...args: any[]): any; - discard(...args: any[]): import("../index.js").GameEventPromise; - loseToDiscardpile(...args: any[]): import("../index.js").GameEventPromise; - respond(...args: any[]): import("../index.js").GameEventPromise; - swapHandcards(target: any, cards1: any, cards2: any): import("../index.js").GameEventPromise; + discard(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + loseToDiscardpile(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + respond(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + swapHandcards(target: any, cards1: any, cards2: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; directequip(cards: any): void; $addToExpansion(cards: any, broadcast: any, gaintag: any): this; directgain(cards: any, broadcast: any, gaintag: any): this; directgains(cards: any, broadcast: any, gaintag: any): this; - gainMultiple(targets: any, position: any): import("../index.js").GameEventPromise; - gain(...args: any[]): import("../index.js").GameEventPromise; - addToExpansion(...args: any[]): import("../index.js").GameEventPromise; + gainMultiple(targets: any, position: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + gain(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + addToExpansion(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; give(cards: any, target: any, visible: any): any; - lose(...args: any[]): import("../index.js").GameEventPromise; - damage(...args: any[]): import("../index.js").GameEventPromise; - recover(...args: any[]): import("../index.js").GameEventPromise; - doubleDraw(): import("../index.js").GameEventPromise; - loseHp(num: any): import("../index.js").GameEventPromise; - loseMaxHp(...args: any[]): import("../index.js").GameEventPromise; - gainMaxHp(...args: any[]): import("../index.js").GameEventPromise; - changeHp(num: any, popup: any): import("../index.js").GameEventPromise; - changeHujia(num: any, type: any, limit: any): import("../index.js").GameEventPromise; + lose(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + damage(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + recover(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + recoverTo(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + doubleDraw(): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + loseHp(num: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + loseMaxHp(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + gainMaxHp(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + changeHp(num: any, popup: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + changeHujia(num: any, type: any, limit: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; getBuff(...args: any[]): this; getDebuff(...args: any[]): this; - dying(reason: any): import("../index.js").GameEventPromise; - die(reason: any): import("../index.js").GameEventPromise; + dying(reason: any): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + die(reason: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; revive(hp: any, log: any): void; isMad(): boolean; goMad(end: any): void; unMad(): void; tempHide(): void; addExpose(num: any): this; - equip(card: any, draw: any): import("../index.js").GameEventPromise; - addJudge(card: any, cards: any): import("../index.js").GameEventPromise; + equip(card: any, draw: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + addJudge(card: any, cards: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; /** * @returns { boolean } */ canAddJudge(card: any): boolean; addJudgeNext(card: any, unlimited: any): void; - judge(...args: any[]): import("../index.js").GameEventPromise; - turnOver(bool: any): import("../index.js").GameEventPromise; + judge(...args: any[]): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; + turnOver(bool: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; out(skill: any): void; - outSkills: any[]; + outSkills: any[] | undefined; in(skill: any): void; - link(bool: any): import("../index.js").GameEventPromise; + link(bool: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; skip(name: any): void; wait(callback: any): void; unwait(result: any): void; @@ -940,7 +941,7 @@ export class Player extends HTMLDivElement { hideTimer(): void; markAuto(name: any, info: any): void; unmarkAuto(name: any, info: any): void; - getExpansions(tag: any): import("./card.js").Card[]; + getExpansions(tag: any): any[]; countExpansions(tag: any): number; hasExpansions(tag: any): boolean; setStorage(name: any, value: any, mark: any): any; @@ -955,7 +956,7 @@ export class Player extends HTMLDivElement { markSkill(name: any, info: any, card: any, nobroadcast: any): this; unmarkSkill(name: any, nobroadcast: any): this; markSkillCharacter(id: any, target: any, name: any, content: any, nobroadcast: any): this; - markCharacter(name: any, info: any, learn: any, learn2: any): HTMLDivElement; + markCharacter(name: any, info: any, learn: any, learn2: any): HTMLDivElement | undefined; mark(name: any, info: any, skill: any): any; unmark(name: any, info: any): void; addLink(): void; @@ -966,26 +967,26 @@ export class Player extends HTMLDivElement { getUseValue(card: any, distance: any, includecard: any): number; addSubPlayer(cfg: any): string; removeSubPlayer(name: any): void; - callSubPlayer(...args: any[]): import("../index.js").GameEventPromise; - toggleSubPlayer(...args: any[]): import("../index.js").GameEventPromise; - exitSubPlayer(remove: any): import("../index.js").GameEventPromise; + callSubPlayer(...args: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + toggleSubPlayer(...args: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + exitSubPlayer(remove: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; getSubPlayers(tag: any): any[]; addSkillTrigger(skills: any, hidden: any, triggeronly: any): this; - _hookTrigger: any[]; - addSkillLog(skill: any): this; - removeSkillLog(skill: any, popup: any): this; + _hookTrigger: any[] | undefined; + addSkillLog(skill: any): this | undefined; + removeSkillLog(skill: any, popup: any): this | undefined; addInvisibleSkill(skill: any): void; removeInvisibleSkill(skill: any, ...args: any[]): any; - addSkills(skill: any): import("../index.js").GameEventPromise; - removeSkills(skill: any): import("../index.js").GameEventPromise; - changeSkills(addSkill?: any[], removeSkill?: any[]): import("../index.js").GameEventPromise; + addSkills(skill: any): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + removeSkills(skill: any): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; + changeSkills(addSkill?: any[], removeSkill?: any[]): (import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise) | undefined; addSkill(skill: any, checkConflict: any, nobroadcast: any, addToSkills: any): any; - addAdditionalSkills(skill: any, skillsToAdd: any, keep: any): import("../index.js").GameEventPromise; + addAdditionalSkills(skill: any, skillsToAdd: any, keep: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; addAdditionalSkill(skill: any, skillsToAdd: any, keep: any): this; $removeAdditionalSkills(skill: any, target: any): void; getRemovableAdditionalSkills(skill: any, target: any): string[]; removeAdditionalSkill(skill: any, target: any): this; - removeAdditionalSkills(skill: any, target: any): import("../index.js").GameEventPromise; + removeAdditionalSkills(skill: any, target: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; awakenSkill(skill: any, nounmark: any): this; restoreSkill(skill: any, nomark: any): this; disableSkill(skill: any, skills: any): this; @@ -995,13 +996,29 @@ export class Player extends HTMLDivElement { removeEquipTrigger(card: any): this; removeSkillTrigger(skills: any, triggeronly: any): this; removeSkill(skill: any, ...args: any[]): any; - addTempSkills(skillsToAdd: any, expire: any): import("../index.js").GameEventPromise; + addTempSkills(skillsToAdd: any, expire: any): import("./gameEvent.js").GameEvent & import("./gameEventPromise.js").GameEventPromise; addTempSkill(skill: any, expire: any, checkConflict: any): any; tempBanSkill(skill: any, expire: any, log: any): any; isTempBanned(skill: any): boolean; attitudeTo(target: any): any; clearSkills(all: any, ...args: any[]): string[]; checkConflict(skill: any): void; + /** + * 快速获取一名角色当前轮次/前X轮次的历史 + * + * 第一个参数填写获取的动作 + * + * 第二个参数填写获取历史的筛选条件 + * + * 第三个参数填写数字(不填默认为0),获取上X轮的历史(X为0则为本轮历史),第四个参数若为true,则获取从上X轮开始至现在 + * + * 第四个参数若为true,则获取从上X轮开始至现在所有符合条件的历史 + * + * 第五个参数填写event,获取此event之前所有符合条件的历史 + * + * @param { string | function | number | boolean | object } map + */ + getRoundHistory(key: any, filter: any, num: any, keep: any, last: any): any[]; getHistory(key: any, filter: any, last: any): any; checkHistory(key: any, filter: any, last: any): void; hasHistory(key: any, filter: any, last: any): any; @@ -1013,14 +1030,14 @@ export class Player extends HTMLDivElement { getStat(key: any): any; getLastStat(key: any): any; queue(time: any): void; - queueTimeout: NodeJS.Timeout; + queueTimeout: NodeJS.Timeout | undefined; getCardUsable(card: any, pure: any): number; getAttackRange(raw: any): number; getEquipRange(cards: any): number; getGlobalFrom(): number; getGlobalTo(): number; getHandcardLimit(): number; - getEnemies(func: any): Player[]; + getEnemies(func: any): any[] | undefined; getFriends(func: any): any[]; isEnemyOf(...args: any[]): boolean; isFriendOf(player: any): boolean; @@ -1065,13 +1082,13 @@ export class Player extends HTMLDivElement { hasUnknown(num: any): boolean; isUnknown(player: any): boolean; hasWuxie(info: any): boolean; - hasSha(respond: any, noauto: any): boolean; - hasShan(respond: any): boolean; + hasSha(respond: any, noauto: any): true | undefined; + hasShan(respond: any): true | undefined; mayHaveSha(viewer: any, type: any, ignore: any, rvt: any): number | boolean; mayHaveShan(viewer: any, type: any, ignore: any, rvt: any): number | boolean; hasCard(name: any, position: any): boolean; - getEquip(name: any): import("./card.js").Card; - getJudge(name: any): ChildNode; + getEquip(name: any): any; + getJudge(name: any): ChildNode | null; $drawAuto(cards: any, target: any): void; $draw(num: any, init: any, config: any): void; $compareMultiple(card1: any, targets: any, cards: any): void; @@ -1083,12 +1100,12 @@ export class Player extends HTMLDivElement { $throwxy(card: any, left: any, top: any): any; $throwxy2(card: any, left: any, top: any, trans: any, flipx: any, flipy: any, ...args: any[]): any; throwDice(num: any): void; - $giveAuto(card: any, player: any, ...args: any[]): any; + $giveAuto(card: any, player: any, ...args: any[]): void; $give(card: any, player: any, log: any, init: any): void; $handleEquipChange(): void; $equip(card: any): this; $gain(card: any, log: any, init: any): void; - $gain2(cards: any, log: any): boolean; + $gain2(cards: any, log: any): true | undefined; $skill(name: any, type: any, color: any, avatar: any): void; $fire(): void; $thunder(): void; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/element/vcard.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/element/vcard.d.ts index fb220de8c..d4dd547d9 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/element/vcard.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/element/vcard.d.ts @@ -5,7 +5,7 @@ export class VCard { * @param { string } [name] * @param { string } [nature] */ - constructor(suitOrCard?: any, numberOrCards?: number | Card[], name?: string, nature?: string); + constructor(suitOrCard?: any, numberOrCards?: number | any[] | undefined, name?: string | undefined, nature?: string | undefined); /** * @type {string} */ @@ -22,7 +22,7 @@ export class VCard { * @type {string} */ nature: string; - color: string; + color: string | undefined; /** * @type { boolean } */ @@ -43,7 +43,7 @@ export class VCard { /** * @param { Player } player */ - hasNature(nature: any, player: Player): boolean; + hasNature(nature: any, player: any): boolean; getCacheKey(): string; hasGaintag(tag: any): any; } diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/index.d.ts index 225927a56..9f5125615 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/index.d.ts @@ -1,51 +1,51 @@ /// -export class Library extends Uninstantable { - static configprefix: string; - static versionOL: number; - static updateURLS: { +export class Library { + configprefix: string; + versionOL: number; + updateURLS: { coding: string; github: string; }; - static updateURL: string; - static mirrorURL: string; - static hallURL: string; - static assetURL: string; - static userAgent: string; - static characterDefaultPicturePath: string; - static compatibleEdition: boolean; - static changeLog: any[]; - static updates: any[]; - static canvasUpdates: any[]; + updateURL: string; + mirrorURL: string; + hallURL: string; + assetURL: string; + userAgent: string; + characterDefaultPicturePath: string; + compatibleEdition: boolean; + changeLog: any[]; + updates: any[]; + canvasUpdates: any[]; /** * @type { Video[] } */ - static video: Video[]; - static skilllist: any[]; - static connectBanned: any[]; - static characterIntro: {}; - static characterTitle: {}; - static characterPack: {}; - static characterFilter: {}; - static characterSort: {}; - static characterReplace: {}; - static characterSubstitute: {}; - static characterInitFilter: {}; - static characterGuozhanFilter: string[]; - static dynamicTranslate: {}; - static cardPack: {}; - static cardPackInfo: {}; + video: Video[]; + skilllist: any[]; + connectBanned: any[]; + characterIntro: {}; + characterTitle: {}; + characterPack: {}; + characterFilter: {}; + characterSort: {}; + characterReplace: {}; + characterSubstitute: {}; + characterInitFilter: {}; + characterGuozhanFilter: string[]; + dynamicTranslate: {}; + cardPack: {}; + cardPackInfo: {}; /** * @type { SMap } */ - static skin: SMap; - static onresize: any[]; - static onphase: any[]; - static onwash: any[]; - static onover: any[]; - static ondb: any[]; - static ondb2: any[]; - static chatHistory: any[]; - static emotionList: { + skin: SMap; + onresize: any[]; + onphase: any[]; + onwash: any[]; + onover: any[]; + ondb: any[]; + ondb2: any[]; + chatHistory: any[]; + emotionList: { xiaowu_emotion: number; xiaokuo_emotion: number; shibing_emotion: number; @@ -55,37 +55,77 @@ export class Library extends Uninstantable { xiaotao_emotion: number; xiaojiu_emotion: number; }; - static animate: { + animate: { skill: {}; card: {}; }; - static onload: any[]; - static onload2: any[]; - static onprepare: any[]; - static arenaReady: any[]; - static onfree: any[]; - static inpile: any[]; - static inpile_nature: any[]; - static extensions: any[]; - static extensionPack: {}; - static cardType: {}; - static hook: { + onload: any[]; + onload2: any[]; + onprepare: any[]; + arenaReady: any[]; + onfree: any[]; + inpile: any[]; + inpile_nature: any[]; + extensions: any[]; + extensionPack: {}; + cardType: {}; + hook: { globalskill: {}; }; /** * @type { Player | undefined } */ - static tempSortSeat: Player | undefined; + tempSortSeat: Player | undefined; /** - * @returns { never } - */ - static typeAnnotation(): never; + * @type { 'android' | 'ios' | undefined } + */ + device: 'android' | 'ios' | undefined; + /** + * @type { string } + */ + version: string; + /** + * @type { Videos[] } + */ + videos: Videos[]; + /** + * @type { { + * fs: typeof import("fs"), + * path: typeof import("path"), + * debug: () => void, + * clients: Element.Client[], + * banned:[], + * observing:[], + * torespond:{}, + * torespondtimeout:{}, + * } } + */ + node: { + fs: typeof import("fs"); + path: typeof import("path"); + debug: () => void; + clients: Element.Client[]; + banned: []; + observing: []; + torespond: {}; + torespondtimeout: {}; + }; + /** + * @type { { [key: string]: string } } + */ + playerOL: { + [key: string]: string; + }; + /** + * @type { IDBRequest } + */ + db: IDBRequest; /** * 你可以往这里加入{钩子名:函数数组},并在数组里增加你的自定义函数 * 这样当某个地方调用game.callHook(钩子名,[...函数参数])时,就会按顺序将对应数组中的每个函数运行一遍(传参为callHook的第二个参数)。 * 你可以将hook机制类比为event.trigger(),但是这里只能放同步代码 */ - static hooks: Readonly<{ + hooks: Readonly<{ checkBegin: import("./assembly/index.js").NonameAssembly; checkCard: import("./assembly/index.js").NonameAssembly; checkTarget: import("./assembly/index.js").NonameAssembly; @@ -120,7 +160,7 @@ export class Library extends Uninstantable { * // 从某个角落向channel发消息,若无消息接收则等待 * await channel.send(item); */ - static channel: typeof Channel; + channel: typeof Channel; /** * **无名杀消息推送库** * @@ -146,12 +186,12 @@ export class Library extends Uninstantable { * // 若此时乙扩展不想继续订阅`skinChange`事件,可以通过`unsubscribe`解除订阅 * lib.announce.unsubscribe("skinChange", method); */ - static announce: Announce; - static objectURL: Map; - static hookmap: {}; - static imported: {}; - static layoutfixed: string[]; - static pinyins: { + announce: Announce; + objectURL: Map; + hookmap: {}; + imported: {}; + layoutfixed: string[]; + pinyins: { _metadata: { shengmu: string[]; special_shengmu: string[]; @@ -184,10 +224,10 @@ export class Library extends Uninstantable { * * 应变 */ - static yingbian: { + yingbian: { condition: { color: Map; - complex: Map GameEventPromise>; + complex: Map Element.GameEvent & Element.GameEventPromise>; simple: Map any>; }; effect: Map void>; @@ -198,7 +238,7 @@ export class Library extends Uninstantable { * * 谋攻强化 */ - static stratagemBuff: { + stratagemBuff: { cost: Map; effect: Map void>; prompt: Map string>; @@ -208,13 +248,13 @@ export class Library extends Uninstantable { * * 实际的卡牌名称 */ - static actualCardName: Map; - static characterDialogGroup: { + actualCardName: Map; + characterDialogGroup: { 收藏: (name: any, capt: any) => any; 最近: (name: any, capt: any) => any; }; - static listenEnd(node: any): void; - static configMenu: { + listenEnd(node: any): void; + configMenu: { general: { name: string; config: { @@ -303,7 +343,7 @@ export class Library extends Uninstantable { restart: boolean; unfrequent: boolean; intro: string; - onclick(bool: any): boolean; + onclick(bool: any): false | undefined; }; swipe: { name: string; @@ -324,7 +364,7 @@ export class Library extends Uninstantable { chat: string; off: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; swipe_up: { name: string; @@ -339,7 +379,7 @@ export class Library extends Uninstantable { chat: string; off: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; swipe_left: { name: string; @@ -354,7 +394,7 @@ export class Library extends Uninstantable { chat: string; off: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; swipe_right: { name: string; @@ -369,7 +409,7 @@ export class Library extends Uninstantable { chat: string; off: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; round_menu_func: { name: string; @@ -382,7 +422,7 @@ export class Library extends Uninstantable { pause: string; auto: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; show_splash: { name: string; @@ -428,7 +468,7 @@ export class Library extends Uninstantable { config: string; auto: string; }; - onclick(item: any): boolean; + onclick(item: any): false | undefined; }; longpress_info: { name: string; @@ -667,7 +707,7 @@ export class Library extends Uninstantable { phonelayout: { name: string; init: boolean; - onclick(bool: any): boolean; + onclick(bool: any): false | undefined; }; change_skin: { name: string; @@ -1295,7 +1335,7 @@ export class Library extends Uninstantable { name: string; init: boolean; unfrequent: boolean; - onclick(bool: any): boolean; + onclick(bool: any): false | undefined; }; remember_round_button: { name: string; @@ -1666,7 +1706,7 @@ export class Library extends Uninstantable { }; }; }; - static extensionMenu: { + extensionMenu: { cardpile: { enable: { name: string; @@ -1874,7 +1914,7 @@ export class Library extends Uninstantable { }; }; }; - static mode: { + mode: { identity: { name: string; connect: { @@ -3259,7 +3299,7 @@ export class Library extends Uninstantable { }; }; }; - static status: { + status: { running: boolean; canvas: boolean; time: number; @@ -3269,7 +3309,7 @@ export class Library extends Uninstantable { videoId: number; globalId: number; }; - static help: { + help: { 关于游戏: string; 游戏操作: string; 游戏命令: string; @@ -3278,23 +3318,23 @@ export class Library extends Uninstantable { /** * @type {import('path')} */ - static path: import("path").PlatformPath; - static getErrorTip(msg: any): any; - static codeMirrorReady(node: any, editor: any): void; - static setIntro(node: any, func: any, left: any): void; - static setPopped(node: any, func: any, width: any, height: any, forceclick: any, paused2: any): void; - static placePoppedDialog(dialog: any, e: any): void; - static setHover(node: any, func: any, hoveration: any, width: any): any; - static setScroll(node: any): any; - static setMousewheel(node: any): void; - static setLongPress(node: any, func: any): any; - static updateCanvas(time: any): boolean; - static run(time: any): void; - static getUTC(date: any): any; - static saveVideo(): void; - static genAsync(fn: any): (...args: any[]) => Promise>; - static genAwait(item: any): Promise; - static gnc: { + path: import("path").PlatformPath; + getErrorTip(msg: any): any; + codeMirrorReady(node: any, editor: any): void; + setIntro(node: any, func: any, left: any): void; + setPopped(node: any, func: any, width: any, height: any, forceclick: any, paused2: any): void; + placePoppedDialog(dialog: any, e: any): void; + setHover(node: any, func: any, hoveration: any, width: any): any; + setScroll(node: any): any; + setMousewheel(node: any): void; + setLongPress(node: any, func: any): any; + updateCanvas(time: any): false | undefined; + run(time: any): void; + getUTC(date: any): any; + saveVideo(): void; + genAsync(fn: any): (...args: any[]) => Promise>; + genAwait(item: any): Promise; + gnc: { of: (fn: any) => (...args: any[]) => Promise>; is: { coroutine: (item: any) => boolean; @@ -3302,20 +3342,20 @@ export class Library extends Uninstantable { generator: (item: any) => boolean; }; }; - static comparator: { + comparator: { equals: (...args: any[]) => boolean; equalAny: (...args: any[]) => boolean; notEquals: (...args: any[]) => boolean; notEqualAny: (...args: any[]) => boolean; typeEquals: (...args: any[]) => boolean; }; - static creation: { - readonly array: any[]; + creation: { + readonly array: never[]; readonly object: {}; readonly nullObject: any; readonly string: string; }; - static linq: { + linq: { cselector: { hasAttr: (name: any) => string; isAttr: (name: any, item: any) => string; @@ -3348,8 +3388,8 @@ export class Library extends Uninstantable { div(...args: any[]): any; }; }; - static init: typeof LibInit; - static cheat: { + init: LibInit; + cheat: { /** * 将游戏内部的对象暴露到全局中 * @@ -3395,7 +3435,7 @@ export class Library extends Uninstantable { * @param { number | true } [i] 指定game.players的第几个元素,不填指定为自己的下家。为true时切换玩家布局 * @param { string } [skin] 皮肤id */ - p(name: string, i?: number | true, skin?: string): void; + p(name: string, i?: number | true | undefined, skin?: string | undefined): void; /** * @overload * @description 不传参数默认装备麒麟弓,八卦阵,的卢,赤兔,木牛 @@ -3452,24 +3492,24 @@ export class Library extends Uninstantable { * 炉石模式可用,使用'spell_yexinglanghun'卡牌 * @param { boolean } [me] 决定是自己还是对手使用'spell_yexinglanghun'卡牌 */ - uy(me?: boolean): void; + uy(me?: boolean | undefined): void; /** * 炉石模式可用,使用`spell_${name}`卡牌 * @param { string } [name] * @param { boolean } [act] */ - gs(name?: string, act?: boolean): void; + gs(name?: string | undefined, act?: boolean | undefined): void; /** * 炉石模式可用,获得`stone_${name}_stonecharacter`卡牌 * @param { string } [name] * @param { boolean } [act] */ - gc(name?: string, act?: boolean): void; + gc(name?: string | undefined, act?: boolean | undefined): void; /** * 进入/关闭快速自动测试模式(游戏速度最快),只有游戏记录界面 * @param { boolean | string } [bool] */ - a(bool?: boolean | string): void; + a(bool?: string | boolean | undefined): void; /** * 临时去掉“自动测试模式”带来的css效果, * @@ -3498,7 +3538,7 @@ export class Library extends Uninstantable { * 输出每个强度的武将数量、每个武将包的每个强度的武将数量、每个武将对应的id和翻译 * @param { boolean } [bool] 为false不输出无名杀自带的武将id和翻译 */ - r(bool?: boolean): void; + r(bool?: boolean | undefined): void; /** * 打印目标玩家的手牌 * @param { Player } player @@ -3565,7 +3605,7 @@ export class Library extends Uninstantable { * 指定的玩家或自己立即获得诸葛连弩,青龙刀,八卦阵,的卢,赤兔,木牛 * @param { Player } [target] */ - ge(target?: Player): void; + ge(target?: Element.Player | undefined): void; /** * 自己立即获得闪电,火山,洪水,乐不思蜀,鬼幽结 */ @@ -3579,7 +3619,7 @@ export class Library extends Uninstantable { * @param { number } [num] * @param { Player } [target] */ - d(num?: number, target?: Player): void; + d(num?: number | undefined, target?: Element.Player | undefined): void; /** * 给自己立刻添加一个或多个技能 * @param {...string} args 技能名 @@ -3592,7 +3632,7 @@ export class Library extends Uninstantable { * * @param { number | Player } [num] */ - t(num?: number | Player): void; + t(num?: number | Element.Player | undefined): void; /** * 自己以外的其他玩家弃置所有牌 */ @@ -3612,7 +3652,7 @@ export class Library extends Uninstantable { */ z(name: string): void; }; - static translate: { + translate: { flower: string; egg: string; wine: string; @@ -3832,8 +3872,8 @@ export class Library extends Uninstantable { phaseDiscard: string; phaseJieshu: string; }; - static experimental: typeof Experimental; - static element: { + experimental: typeof Experimental; + element: { content: { emptyEvent: () => void; changeCharacter(event: any, trigger: any, player: any): Promise; @@ -3952,7 +3992,7 @@ export class Library extends Uninstantable { link: () => void; chooseToGuanxing: () => void; }; - contents: SMap<((event: GameEventPromise, trigger: GameEventPromise, player: Element.Player) => Promise)[]>; + contents: SMap<((event: any, trigger: any, player: any) => Promise)[]>; Player: typeof Element.Player; Card: typeof Element.Card; VCard: typeof Element.VCard; @@ -4002,8 +4042,11 @@ export class Library extends Uninstantable { */ readonly nodews: Element.NodeWS; }; - static card: { - list: any[]; + card: { + /** + * @type { [CardBaseUIData['suit'], CardBaseUIData['number'], string][] } + */ + list: [CardBaseUIData['suit'], CardBaseUIData['number'], string][]; cooperation_damage: { fullskin: boolean; }; @@ -4118,7 +4161,7 @@ export class Library extends Uninstantable { fullimage: boolean; }; }; - static filter: { + filter: { all: () => boolean; none: () => boolean; /** @@ -4139,7 +4182,7 @@ export class Library extends Uninstantable { * @param { Player } target * @param { boolean } [strict] */ - cardGiftable: (card: Card, player: Player, target: Player, strict?: boolean) => boolean; + cardGiftable: (card: Card, player: Player, target: Player, strict?: boolean | undefined) => boolean; /** * Check if the card is recastable * @@ -4149,7 +4192,7 @@ export class Library extends Uninstantable { * @param { Player } [source] * @param { boolean } [strict] */ - cardRecastable: (card: Card, player?: Player, source?: Player, strict?: boolean) => boolean; + cardRecastable: (card: Card, player?: Player, source?: Element.Player | undefined, strict?: boolean | undefined) => boolean; /** * @param { Card } card * @param { Player } player @@ -4176,7 +4219,7 @@ export class Library extends Uninstantable { * @returns {boolean} */ filterEnable: (event: GameEvent, player: Player, skill: string) => boolean; - characterDisabled: (i: any, libCharacter: any) => boolean; + characterDisabled: (i: any, libCharacter: any) => true | undefined; characterDisabled2: (i: any) => boolean; skillDisabled: (skill: any) => boolean; cardEnabled: (card: any, player: any, event: any) => any; @@ -4200,13 +4243,13 @@ export class Library extends Uninstantable { attackFrom: (card: any, player: any, target: any) => boolean; globalFrom: (card: any, player: any, target: any) => boolean; selectCard: () => number[]; - selectTarget: (card: any, player: any) => number | number[] | (() => number | Select); + selectTarget: (card: any, player: any) => any; judge: (card: any, player: any, target: any) => any; autoRespondSha: () => boolean; autoRespondShan: () => boolean; - wuxieSwap: (event: any) => boolean; + wuxieSwap: (event: any) => true | undefined; }; - static sort: { + sort: { nature: (a: any, b: any) => number; group: (a: any, b: any) => number; character: (a: any, b: any) => number; @@ -4233,7 +4276,7 @@ export class Library extends Uninstantable { * [key: string]: Skill; * }} */ - static skill: { + skill: { [key: string]: Skill; global: string[]; globalmap: SMap; @@ -4244,10 +4287,10 @@ export class Library extends Uninstantable { zhuSkill: SMap; land_used: SMap; }; - static character: {}; - static perfectPair: {}; - static cardPile: {}; - static message: { + character: {}; + perfectPair: {}; + cardPile: {}; + message: { server: { /** @this { any } */ init(this: any, version: any, config: any, banned_info: any): void; @@ -4295,16 +4338,16 @@ export class Library extends Uninstantable { updateWaiting: (map: any) => void; }; }; - static suit: string[]; - static suits: string[]; - static color: { + suit: string[]; + suits: string[]; + color: { black: string[]; red: string[]; none: string[]; }; - static group: string[]; - static nature: Map; - static natureAudio: { + group: string[]; + nature: Map; + natureAudio: { damage: { fire: string; thunder: string; @@ -4325,10 +4368,10 @@ export class Library extends Uninstantable { kami: string; }; }; - static linked: string[]; - static natureBg: Map; - static natureSeparator: string; - static namePrefix: Map; + natureSeparator: string; + namePrefix: Map; - static groupnature: { + groupnature: { shen: string; wei: string; shu: string; @@ -4377,48 +4420,32 @@ export class Library extends Uninstantable { jin: string; ye: string; }; - static lineColor: Map; - static phaseName: string[]; - static quickVoice: string[]; - static other: { - ignore: () => any; + lineColor: Map; + phaseName: string[]; + quickVoice: string[]; + other: { + ignore: () => undefined; }; - static InitFilter: { + InitFilter: { noZhuHp: string; noZhuSkill: string; }; + config: any; + configOL: any; } -export namespace Library { - let videos: Videos[]; - let node: { - fs: typeof import("fs"); - path: typeof import("path"); - debug: () => void; - clients: Element.Client[]; - banned: []; - observing: []; - torespond: {}; - torespondtimeout: {}; - }; - let playerOL: { - [key: string]: string; - }; - let config: any; - let configOL: any; -} -export const lib: typeof Library; +export let lib: Library; +export function setLibrary(instance?: Library | undefined): void; export type Player = InstanceType; export type Card = InstanceType; export type VCard = InstanceType; export type Button = InstanceType; export type Dialog = InstanceType; export type GameEvent = InstanceType; -export type GameEventPromise = InstanceType & InstanceType; +export type GameEventPromise = GameEvent & InstanceType; export type NodeWS = InstanceType; export type Control = InstanceType; -import { Uninstantable } from "../util/index.js"; +import * as Element from "./element/index.js"; import { Channel } from "./channel/index.js"; import { Announce } from "./announce/index.js"; import { LibInit } from "./init/index.js"; import { Experimental } from "./experimental/index.js"; -import * as Element from "./element/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/init/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/init/index.d.ts index 50b48f53b..8b04c7075 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/init/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/init/index.d.ts @@ -1,53 +1,52 @@ -export class LibInit extends Uninstantable { +export class LibInit { /** * 部分函数的Promise版本 */ - static promises: typeof LibInitPromises; - static init(): void; - static reset(): void; - static onload(): Promise; - static startOnline(): void; - static onfree(): void; - static connection(ws: any): void; - static sheet(...args: any[]): HTMLStyleElement; - static css(path: any, file: any, before: any): HTMLLinkElement; - static jsForExtension(path: any, file: any, onLoad: any, onError: any): void; - static js(path: any, file: any, onLoad: any, onError: any): HTMLScriptElement; + promises: LibInitPromises; + init(): void; + reset(): void; + onload(): Promise; + startOnline(): void; + onfree(): void; + connection(ws: any): void; + sheet(...args: any[]): HTMLStyleElement; + css(path: any, file: any, before: any): HTMLLinkElement; + jsForExtension(path: any, file: any, onLoad: any, onError: any): void; + js(path: any, file: any, onLoad: any, onError: any): HTMLScriptElement | undefined; /** * 同步lib.init.js * @returns { void } */ - static jsSync(path: any, file: any, onLoad: any, onError: any): void; - static req(str: any, onload: any, onerror: any, master: any): void; + jsSync(path: any, file: any, onLoad: any, onError: any): void; + req(str: any, onload: any, onerror: any, master: any): void; /** * 同步lib.init.req */ - static reqSync(str: any, onload: any, onerror: any, master: any): string; - static json(url: any, onload: any, onerror: any): void; + reqSync(str: any, onload: any, onerror: any, master: any): string | undefined; + json(url: any, onload: any, onerror: any): void; /** * 同步lib.init.json */ - static jsonSync(url: any, onload: any, onerror: any): void; - static cssstyles(): void; - static layout(layout: any, nosave: any): void; - static background(): void; + jsonSync(url: any, onload: any, onerror: any): void; + cssstyles(): void; + layout(layout: any, nosave: any): void; + background(): void; /** * * @param {*} item * @param {Function} [scope] 作用域 * @returns */ - static parsex(item: any, scope?: Function): any; - static eval(func: any): any; - static encode(strUni: any): string; - static decode(str: any): string; - static stringify(obj: any): string; - static stringifySkill(obj: any): string; + parsex(item: any, scope?: Function | undefined): any; + eval(func: any): any; + encode(strUni: any): string; + decode(str: any): string; + stringify(obj: any): string; + stringifySkill(obj: any): string; /** * 在返回当前加载的esm模块相对位置。 * @param {*} url 传入import.meta.url */ - static getCurrentFileLocation(url: any): string; + getCurrentFileLocation(url: any): string; } -import { Uninstantable } from "../../util/index.js"; import { LibInitPromises } from "./promises.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/init/promises.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/init/promises.d.ts index 67f155fdd..385fdfb28 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/init/promises.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/init/promises.d.ts @@ -1,4 +1,4 @@ -export class LibInitPromises extends Uninstantable { +export class LibInitPromises { /** * Promise版的`lib.init.js` * @@ -6,7 +6,7 @@ export class LibInitPromises extends Uninstantable { * @param {string | string[]} [file] - 文件名或文件名组,忽略则直接读取`path`的内容 * @returns {Promise} */ - static js(path: string, file?: string | string[]): Promise; + js(path: string, file?: string | string[] | undefined): Promise; /** * Promise版的`lib.init.css` * @@ -16,7 +16,7 @@ export class LibInitPromises extends Uninstantable { * @param {boolean} [noerror = false] - 是否忽略报错 * @returns {Promise} */ - static css(path: string, file?: string | string[], before?: Element, noerror?: boolean): Promise; + css(path: string, file?: string | string[] | undefined, before?: Element | undefined, noerror?: boolean | undefined): Promise; /** * Promise版的`lib.init.req` * @@ -24,19 +24,18 @@ export class LibInitPromises extends Uninstantable { * @param {string} [master] * @returns {Promise} */ - static req(str: string, master?: string): Promise; + req(str: string, master?: string | undefined): Promise; /** * Promise版的`lib.init.json` * * @param {string} url - 要读取的地址 * @returns {Promise} */ - static json(url: string): Promise; + json(url: string): Promise; /** * Promise版的`lib.init.sheet` * * @returns {Promise} */ - static sheet(): Promise; + sheet(): Promise; } -import { Uninstantable } from "../../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/library/update.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/library/update.d.ts index b39ff334c..f52662f1a 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/library/update.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/library/update.d.ts @@ -1,3 +1,4 @@ +export function gainAuthorization(): Promise; /** * 字节转换 * @param { number } limit @@ -30,9 +31,9 @@ export function checkVersion(ver1: string, ver2: string): -1 | 0 | 1; * ``` */ export function getRepoTags(options?: { - username?: string; - repository?: string; - accessToken?: string; + username?: string | undefined; + repository?: string | undefined; + accessToken?: string | undefined; }): Promise<{ commit: { sha: string; @@ -58,9 +59,9 @@ export function getRepoTags(options?: { * ``` */ export function getRepoTagDescription(tagName: string, options?: { - username?: string; - repository?: string; - accessToken?: string; + username?: string | undefined; + repository?: string | undefined; + accessToken?: string | undefined; }): Promise<{ /** @type { { browser_download_url: string, content_type: string, name: string, size: number }[] } tag额外上传的素材包 */ assets: { @@ -97,7 +98,7 @@ export function getRepoTagDescription(tagName: string, options?: { * @param { string } [options.username = 'libccy'] 仓库拥有者 * @param { string } [options.repository = 'noname'] 仓库名称 * @param { string } [options.accessToken] 身份令牌 - * @returns { Promise<{ download_url: string, name: string, path: string, sha: string, size: number, type: 'file' } | { download_url: null, name: string, path: string, sha: string, size: 0, type: 'dir' }> } + * @returns { Promise<({ download_url: string, name: string, path: string, sha: string, size: number, type: 'file' } | { download_url: null, name: string, path: string, sha: string, size: 0, type: 'dir' })[]> } * @example * ```js * getRepoFilesList() @@ -105,11 +106,11 @@ export function getRepoTagDescription(tagName: string, options?: { * .catch(error => console.error('Failed to fetch files:', error)); * ``` */ -export function getRepoFilesList(path?: string, branch?: string, options?: { - username?: string; - repository?: string; - accessToken?: string; -}): Promise<{ +export function getRepoFilesList(path?: string | undefined, branch?: string | undefined, options?: { + username?: string | undefined; + repository?: string | undefined; + accessToken?: string | undefined; +}): Promise<({ download_url: string; name: string; path: string; @@ -123,17 +124,47 @@ export function getRepoFilesList(path?: string, branch?: string, options?: { sha: string; size: 0; type: 'dir'; -}>; +})[]>; +/** + * + * 获取仓库指定分支和指定目录内的所有文件(包含子目录的文件) + * @param { string } [path = ''] 路径名称(可放参数) + * @param { string } [branch = ''] 仓库分支名称 + * @param { Object } options + * @param { string } [options.username = 'libccy'] 仓库拥有者 + * @param { string } [options.repository = 'noname'] 仓库名称 + * @param { string } [options.accessToken] 身份令牌 + * @returns { Promise<{ download_url: string, name: string, path: string, sha: string, size: number, type: 'file' }[]> } + * @example + * ```js + * flattenRepositoryFiles() + * .then(files => console.log(files)) + * .catch(error => console.error('Failed to fetch files:', error)); + * ``` + */ +export function flattenRepositoryFiles(path?: string | undefined, branch?: string | undefined, options?: { + username?: string | undefined; + repository?: string | undefined; + accessToken?: string | undefined; +}): Promise<{ + download_url: string; + name: string; + path: string; + sha: string; + size: number; + type: 'file'; +}[]>; /** * 请求一个文件而不是直接储存为文件 * @param { string } url * @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress] + * @param { RequestInit } [options={}] * @example * ```js * await getRepoTagDescription('v1.10.10').then(({ zipball_url }) => request(zipball_url)); * ``` */ -export function request(url: string, onProgress?: (receivedBytes: number, total?: number, filename?: string) => void): Promise; +export function request(url: string, onProgress?: ((receivedBytes: number, total?: number, filename?: string) => void) | undefined, options?: RequestInit | undefined): Promise; /** * * @param { string } [title] @@ -142,4 +173,4 @@ export function request(url: string, onProgress?: (receivedBytes: number, total? * @param { string | number } [value] * @returns { progress } */ -export function createProgress(title?: string, max?: string | number, fileName?: string, value?: string | number): progress; +export function createProgress(title?: string | undefined, max?: string | number | undefined, fileName?: string | undefined, value?: string | number | undefined): progress; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/status/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/status/index.d.ts index 59d72745e..74198ffa9 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/status/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/status/index.d.ts @@ -1,30 +1,68 @@ -export namespace status { - let paused: boolean; - let paused2: boolean; - let paused3: boolean; - let over: boolean; - let clicked: boolean; - let auto: boolean; - let event: GameEventPromise; - let ai: {}; - let lastdragchange: any[]; - let skillaudio: any[]; - let dieClose: any[]; - let dragline: any[]; - let dying: any[]; - let globalHistory: GameHistory[]; - namespace cardtag { - let yingbian_zhuzhan: any[]; - let yingbian_kongchao: any[]; - let yingbian_fujia: any[]; - let yingbian_canqu: any[]; - let yingbian_force: any[]; - } - let renku: any[]; - let prehidden_skills: any[]; - let postReconnect: {}; - let extension: string | void; - let dragged: boolean | void; - let touchconfirmed: boolean | void; +export class status { + paused: boolean; + paused2: boolean; + paused3: boolean; + over: boolean; + clicked: boolean; + auto: boolean; + /** + * @type { GameEventPromise } + */ + event: any; + ai: {}; + lastdragchange: any[]; + skillaudio: any[]; + dieClose: any[]; + dragline: any[]; + dying: any[]; + /** + * @type { GameHistory[] } + */ + globalHistory: GameHistory[]; + cardtag: { + yingbian_zhuzhan: never[]; + yingbian_kongchao: never[]; + yingbian_fujia: never[]; + yingbian_canqu: never[]; + yingbian_force: never[]; + }; + renku: any[]; + prehidden_skills: any[]; + postReconnect: {}; + /** + * @type { string | void } + */ + extension: string | void; + /** + * @type { boolean | void } + */ + dragged: boolean | void; + /** + * @type { boolean | void } + */ + touchconfirmed: boolean | void; + /** + * @type { boolean | void } + */ + connectMode: boolean | void; + /** + * @type { boolean | void } + */ + importingExtension: boolean | void; + /** + * @type { Promise[] | void } + */ + extensionLoaded: Promise[] | void; + /** + * @type { Promise[] | void } + */ + extensionLoading: Promise[] | void; + /** + * @type { { [key: string]: Promise[] } | void } + */ + importing: void | { + [key: string]: Promise[]; + }; } -export namespace _status { } +export let _status: status; +export function setStatus(instance?: status | undefined): void; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ui/click/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ui/click/index.d.ts index 5f767cc2f..35b3b467c 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ui/click/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ui/click/index.d.ts @@ -1,93 +1,122 @@ -export class Click extends Uninstantable { - static identitycircle(): void; - static connectEvents(): void; - static connectClients(): void; - static autoskin(): void; - static skin(avatar: any, name: any, callback: any): void; - static touchpop(forced: any): void; - static exit(): void; - static shortcut(show: any): void; - static favouriteCharacter(e: any): void; - static buttonnameenter(): void; - static buttonnameleave(): void; - static dragtouchdialog(e: any): void; - static identity(e: any): void; - static identity2(): void; - static roundmenu(): void; - static pausehistory(): import("../../library/element/dialog.js").Dialog; - static pauseconfig(): import("../../library/element/dialog.js").Dialog; - static cardPileButton(): import("../../library/element/dialog.js").Dialog; - static chat(): import("../../library/element/dialog.js").Dialog; - static volumn(): import("../../library/element/dialog.js").Dialog; - static volumn_background(e: any): void; - static volumn_audio(e: any): void; - static hoverpopped(): void; - static hoverpopped_leave(): void; - static leavehoverpopped(): void; - static dierevive(): void; - static dieswap(): void; - static dieswap2(): void; - static touchconfirm(): void; - static windowtouchstart(e: any): void; - static windowtouchmove(e: any): void; - static windowtouchend(e: any): void; - static checkroundtranslate(translate: any): void; - static checkdialogtranslate(translate: any, dialog: any): void; - static windowmousewheel(e: any): void; - static windowmousemove(e: any): void; - static windowmousedown(e: any): void; - static cardtouchstart(e: any): void; - static cardtouchmove(e: any): void; - static windowmouseup(e: any): void; - static mousemove(): void; - static mouseenter(): void; - static mouseleave(): void; - static mousedown(): void; - static mouseentercancel(): void; - static hoverplayer(e: any): import("../../library/element/dialog.js").Dialog; - static longpressdown(e: any): void; - static longpresscallback(): void; - static longpresscancel(): void; - static window(): void; - static toggle(): void; - static editor(): void; - static switcher(): void; - static choice(): void; - static button(): void; - static touchintro(): void; - static card(...args: any[]): void; - static avatar(): void; - static avatar2(): void; - static connectroom(e: any): void; - static player(...args: any[]): any; - static target(e: any): void; - static control2(): void; - static control(): void; - static dialogcontrol(): void; - static skill(skill: any): void; - static ok(node: any): void; - static cancel(node: any): void; - static logv(e: any): void; - static logvleave(): void; - static charactercard(name: any, sourcenode: any, noedit: any, resume: any, avatar: any): void; - static intro(e: any): import("../../library/element/dialog.js").Dialog; - static intro2(): void; - static auto(...args: any[]): void; - static wuxie(): void; - static tempnowuxie(): void; - static pause(): void; - static resume(e: any): boolean; - static config(): void; - static swap(): void; - static mousewheel(evt: any): void; - static touchStart(e: any): void; - static dialogtouchStart(e: any): void; - static touchScroll(e: any): void; - static autoskill(bool: any, node: any): void; - static skillbutton(): void; - static autoskill2(e: any): void; - static hiddenskill(e: any): void; - static rightplayer(e: any): boolean; - static right(e: any): boolean; +export class Click { + /** + * @type {() => void} + */ + consoleMenu: () => void; + /** + * @type {(arg0: string) => void} + */ + menuTab: (arg0: string) => void; + identitycircle(): void; + connectEvents(): void; + connectClients(): void; + autoskin(): void; + skin(avatar: any, name: any, callback: any): void; + touchpop(forced: any): void; + exit(): void; + shortcut(show: any): void; + favouriteCharacter(e: any): void; + innerHTML: string | undefined; + buttonnameenter(): void; + buttonnameleave(): void; + dragtouchdialog(e: any): void; + _dragorigin: { + clientX: any; + clientY: any; + } | undefined; + _dragtransform: number[] | undefined; + _dragorigintransform: number[] | undefined; + identity(e: any): void; + _customintro: ((uiintro: any) => void) | undefined; + identity2(): void; + roundmenu(): void; + pausehistory(): import("../../library/element/dialog.js").Dialog | undefined; + pauseconfig(): import("../../library/element/dialog.js").Dialog | undefined; + cardPileButton(): import("../../library/element/dialog.js").Dialog; + chat(): import("../../library/element/dialog.js").Dialog; + volumn(): import("../../library/element/dialog.js").Dialog; + volumn_background(e: any): void; + volumn_audio(e: any): void; + hoverpopped(): void; + _uiintro: any; + hoverpopped_leave(): void; + _poppedalready: boolean | undefined; + leavehoverpopped(): void; + dierevive(): void; + dieswap(): void; + dieswap2(): void; + touchconfirm(): void; + windowtouchstart(e: any): void; + windowtouchmove(e: any): void; + windowtouchend(e: any): void; + checkroundtranslate(translate: any): void; + checkdialogtranslate(translate: any, dialog: any): void; + windowmousewheel(e: any): void; + windowmousemove(e: any): void; + windowmousedown(e: any): void; + cardtouchstart(e: any): void; + _waitingfordrag: { + clientX: any; + clientY: any; + } | undefined; + cardtouchmove(e: any): void; + windowmouseup(e: any): void; + mousemove(): void; + mouseenter(): void; + mouseleave(): void; + _mouseentercreated: boolean | undefined; + mousedown(): void; + mouseentercancel(): void; + hoverplayer(e: any): import("../../library/element/dialog.js").Dialog | undefined; + longpressdown(e: any): void; + _longpresstimeout: NodeJS.Timeout | undefined; + _longpressevent: any; + longpresscallback(): void; + longpresscancel(): void; + window(): void; + toggle(): void; + link: boolean | undefined; + editor(): void; + switcher(): void; + choice(): void; + button(): void; + touchintro(): void; + card(...args: any[]): void; + avatar(): void; + _doubleClicking: boolean | undefined; + avatar2(): void; + connectroom(e: any): void; + player(...args: any[]): void; + target(e: any): void; + control2(): void; + control(): void; + dialogcontrol(): void; + skill(skill: any): void; + ok(node: any): void; + cancel(node: any): void; + logv(e: any): void; + logvtimeout: any; + logvleave(): void; + charactercard(name: any, sourcenode: any, noedit: any, resume: any, avatar: any): void; + intro(e: any): import("../../library/element/dialog.js").Dialog | undefined; + intro2(): void; + auto(...args: any[]): void; + wuxie(): void; + tempnowuxie(): void; + pause(): void; + resume(e: any): false | undefined; + config(): void; + swap(): void; + mousewheel(evt: any): void; + touchStart(e: any): void; + startX: number | undefined; + startY: number | undefined; + dialogtouchStart(e: any): void; + touchScroll(e: any): void; + autoskill(bool: any, node: any): void; + skillbutton(): void; + autoskill2(e: any): void; + hiddenskill(e: any): void; + rightplayer(e: any): boolean; + right(e: any): false | undefined; } -import { Uninstantable } from "../../util/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/index.d.ts index a4ee18e8d..ad87669c0 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/index.d.ts @@ -1,71 +1,75 @@ -export class Create extends Uninstantable { +export class Create { + /** + * @type {(video: Videos, before: boolean) => void} + */ + videoNode: (video: any, before: boolean) => void; /** * 创建身份牌实例 */ - static identityCard(identity: any, position: any, noclick: any): import("../../library/element/card.js").Card; + identityCard(identity: any, position: any, noclick: any): import("../../library/element/card.js").Card; /** * 让卡牌旋转 */ - static cardSpinning(card: any): void; + cardSpinning(card: any): void; /** * 旋转的身份牌! */ - static spinningIdentityCard(identity: any, dialog: any): void; + spinningIdentityCard(identity: any, dialog: any): void; /** * 创建codemirror编辑器 * @param {HTMLDivElement} container * @param {Function} saveInput */ - static editor(container: HTMLDivElement, saveInput: Function): HTMLDivElement; - static cardTempName(card: any, applyNode: any): any; - static connectRooms(list: any): void; - static rarity(button: any): void; - static div(...args: any[]): HTMLDivElement; - static filediv(...args: any[]): any; - static node(...args: any[]): any; - static iframe(src: any): void; - static identitycircle(list: any, target: any): void; - static chat(): void; - static exit(): void; - static connecting(bool: any): void; - static roomInfo(): void; - static templayer(time: any): void; - static selectlist(list: any, init: any, position: any, onchange: any): HTMLSelectElement; + editor(container: HTMLDivElement, saveInput: Function): HTMLDivElement; + cardTempName(card: any, applyNode: any): any; + connectRooms(list: any): void; + rarity(button: any): void; + div(...args: any[]): HTMLDivElement; + filediv(...args: any[]): HTMLDivElement; + node(...args: any[]): any; + iframe(src: any): void; + identitycircle(list: any, target: any): void; + chat(): void; + exit(): void; + connecting(bool: any): void; + roomInfo(): void; + templayer(time: any): void; + selectlist(list: any, init: any, position: any, onchange: any): HTMLSelectElement; /** 创建菜单 */ - static menu: typeof menu; + menu: typeof menu; /** 创建“开始”菜单 */ - static startMenu: (connectMenu: any) => HTMLDivElement; + startMenu: (connectMenu: any) => HTMLDivElement; /** 创建“选项”菜单 */ - static optionsMenu: (connectMenu: any) => void; + optionsMenu: (connectMenu: any) => void; /** 创建“武将”菜单 */ - static characterPackMenu: (connectMenu: any) => (packName: string) => void; + characterPackMenu: (connectMenu: any) => (packName: string) => void; /** 创建“卡牌”菜单 */ - static cardPackMenu: (connectMenu: any) => (packName: string) => void; + cardPackMenu: (connectMenu: any) => (packName: string) => void; /** 创建“扩展”菜单 */ - static extensionMenu: (connectMenu: any) => void; + extensionMenu: (connectMenu: any) => void; /** 创建“其他”菜单 */ - static otherMenu: (connectMenu: any) => void; - static statictable(...args: any[]): HTMLTableElement; - static giveup(): void; - static groupControl(dialog: any): import("../../library/element/control.js").Control; - static cardDialog(...args: any[]): any; - static characterDialog2(filter: any): import("../../library/element/dialog.js").Dialog; - static characterDialog(...args: any[]): import("../../library/element/dialog.js").Dialog; - static dialog(...args: any[]): import("../../library/element/dialog.js").Dialog; - static line2(...args: any[]): any; - static line(...args: any[]): HTMLDivElement; - static switcher(name: any, current: any, current2: any, ...args: any[]): HTMLDivElement; - static caption(str: any, position: any): HTMLDivElement; - static control(...args: any[]): import("../../library/element/control.js").Control; - static confirm(str: any, func: any): void; - static skills(skills: any): import("../../library/element/control.js").Control; - static skills2(skills: any): import("../../library/element/control.js").Control; - static skills3(skills: any): import("../../library/element/control.js").Control; - static arena(): void; - static system(str: any, func: any, right: any, before: any): HTMLDivElement; - static pause(): HTMLDivElement; - static prebutton(item: any, type: any, position: any, noclick: any): HTMLDivElement; - static buttonPresets: { + otherMenu: (connectMenu: boolean | undefined) => void; + statictable(...args: any[]): HTMLTableElement; + giveup(): void; + groupControl(dialog: any): import("../../library/element/control.js").Control; + cardDialog(...args: any[]): import("../../library/element/dialog.js").Dialog; + characterDialog2(filter: any): import("../../library/element/dialog.js").Dialog; + characterDialog(...args: any[]): import("../../library/element/dialog.js").Dialog; + dialog(...args: any[]): import("../../library/element/dialog.js").Dialog; + line2(...args: any[]): HTMLDivElement; + line(...args: any[]): HTMLDivElement; + switcher(name: any, current: any, current2: any, ...args: any[]): HTMLDivElement; + caption(str: any, position: any): HTMLDivElement; + control(...args: any[]): import("../../library/element/control.js").Control; + confirm(str: any, func: any): void; + skills(skills: any): any; + skills2(skills: any): any; + skills3(skills: any): any; + arena(): void; + system(str: any, func: any, right: any, before: any): HTMLDivElement; + pause(): HTMLDivElement | undefined; + prebutton(item: any, type: any, position: any, noclick: any): HTMLDivElement; + buttonPresets: { /** * @returns { import("../library/index.js").Button } */ @@ -95,16 +99,15 @@ export class Create extends Uninstantable { */ player: (item: any, type: any, position: any, noclick: any, node: any) => any; }; - static button(item: any, type: any, position: any, noClick: any, button: any): import("../../library/element/button.js").Button; - static buttons(list: any, type: any, position: any, noclick: any, zoom: any): HTMLDivElement[]; - static textbuttons(list: any, dialog: any, noclick: any): void; - static player(position: any, noclick: any): import("../../library/element/player.js").Player; - static connectPlayers(ip: any): void; - static players(numberOfPlayers: any): import("../../library/element/player.js").Player[]; - static me(hasme: any): void; - static card(position: any, info: any, noclick: any): import("../../library/element/card.js").Card; - static cardsAsync(...args: any[]): void; - static cards(ordered: any): void; + button(item: any, type: any, position: any, noClick: any, button: any): import("../../library/element/button.js").Button; + buttons(list: any, type: any, position: any, noclick: any, zoom: any): HTMLDivElement[]; + textbuttons(list: any, dialog: any, noclick: any): void; + player(position: any, noclick: any): import("../../library/element/player.js").Player; + connectPlayers(ip: any): void; + players(numberOfPlayers: any): any[] | undefined; + me(hasme: any): void; + card(position: any, info: any, noclick: any): import("../../library/element/card.js").Card; + cardsAsync(...args: any[]): void; + cards(ordered: any): void; } -import { Uninstantable } from "../../util/index.js"; import { menu } from "./menu/index.js"; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/index.d.ts index 685a8393e..a4ca5efb3 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/index.d.ts @@ -22,7 +22,7 @@ export function setUpdateActiveCard(fun: Function): void; /** * @param { boolean } [connectMenu] */ -export function menu(connectMenu?: boolean): void; +export function menu(connectMenu?: boolean | undefined): void; /** * @type { HTMLDivElement } * diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/pages/otherMenu.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/pages/otherMenu.d.ts index 2b80a6971..4e260cd23 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/pages/otherMenu.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ui/create/menu/pages/otherMenu.d.ts @@ -1 +1 @@ -export function otherMenu(connectMenu: any): void; +export function otherMenu(connectMenu: boolean | undefined): void; diff --git a/node_modules/@types/noname-typings/nonameModules/noname/ui/index.d.ts b/node_modules/@types/noname-typings/nonameModules/noname/ui/index.d.ts index 8d57192bc..b99c9fecf 100644 --- a/node_modules/@types/noname-typings/nonameModules/noname/ui/index.d.ts +++ b/node_modules/@types/noname-typings/nonameModules/noname/ui/index.d.ts @@ -1,15 +1,15 @@ -export class UI extends Uninstantable { - static updates: any[]; - static thrown: any[]; - static touchlines: any[]; - static todiscard: {}; +export class UI { + updates: any[]; + thrown: any[]; + touchlines: any[]; + todiscard: {}; /** * @type { HTMLStyleElement[] } */ - static playerPositions: HTMLStyleElement[]; - static create: typeof Create; - static click: typeof Click; - static selected: { + playerPositions: HTMLStyleElement[]; + create: Create; + click: Click; + selected: { /** * @type { Button[] } */ @@ -26,111 +26,139 @@ export class UI extends Uninstantable { /** * @type { Dialog[] } */ - static dialogs: Dialog[]; + dialogs: Dialog[]; /** * @type { Dialog } */ - static dialog: Dialog; + dialog: any; /** * @type { HTMLDivElement } */ - static arena: HTMLDivElement; + arena: HTMLDivElement; /** * @type { Control[] } */ - static controls: Control[]; + controls: Control[]; /** * @type { Control } */ - static control: Control; + control: any; /** * @type { Control | undefined } */ - static confirm: Control | undefined; + confirm: Control | undefined; /** * @type { Control | undefined } */ - static skills: Control | undefined; + skills: Control | undefined; /** * @type { Control | undefined } */ - static skills1: Control | undefined; + skills1: Control | undefined; /** * @type { Control | undefined } */ - static skills2: Control | undefined; + skills2: Control | undefined; /** * @type { Control | undefined } */ - static skills3: Control | undefined; + skills3: Control | undefined; /** * @type { HTMLDivElement } */ - static window: HTMLDivElement; + window: HTMLDivElement; /** * @type { HTMLDivElement } */ - static pause: HTMLDivElement; + pause: HTMLDivElement; /** * @type { HTMLAudioElement } */ - static backgroundMusic: HTMLAudioElement; + backgroundMusic: HTMLAudioElement; /** * @type { HTMLDivElement } */ - static special: HTMLDivElement; + special: HTMLDivElement; /** * @type { HTMLDivElement } */ - static fakeme: HTMLDivElement; + fakeme: HTMLDivElement; /** * @type { HTMLDivElement } */ - static chess: HTMLDivElement; + chess: HTMLDivElement; /** * 手动在菜单栏中添加一个武将包的ui * @type { ((packName: string) => void)[] } */ - static updateCharacterPackMenu: ((packName: string) => void)[]; + updateCharacterPackMenu: ((packName: string) => void)[]; /** * 手动在菜单栏中添加一个卡牌包的ui * @type { ((packName: string) => void)[] } */ - static updateCardPackMenu: ((packName: string) => void)[]; + updateCardPackMenu: ((packName: string) => void)[]; /** * @type { HTMLDivElement } 挑战模式下正在操作的角色 */ - static mebg: HTMLDivElement; - static refresh(node: any): void; - static clear(): void; - static updatec(): void; - static updatex(...args: any[]): void; - static updatexr(): void; - static updatejm(player: any, nodes: any, start: any, inv: any): void; - static updatem(player: any): void; - static updatej(player: any): void; - static updatehl(): void; - static updateh(compute: any): void; - static updatehx(node: any): void; - static updated(): void; - static updatez(): void; - static update(): void; - static recycle(node: any, key: any): any; + mebg: HTMLDivElement; + /** + * @type { Function | undefined } + */ + updateUpdate: Function | undefined; + /** + * @type {HTMLDivElement} + */ + commandnode: HTMLDivElement; + /** + * @type {() => void} + */ + updateVideoMenu: () => void; + /** + * @type {HTMLDivElement} + */ + menuContainer: HTMLDivElement; + /** + * @type {HTMLDivElement} + */ + auto: HTMLDivElement; + /** + * @type {HTMLDivElement} + */ + wuxie: HTMLDivElement; + /** + * @type {HTMLDivElement} + */ + tempnowuxie: HTMLDivElement; + refresh(node: any): void; + clear(): void; + updatec(): void; + updatex(...args: any[]): void; + updatexr(): void; + updatejm(player: any, nodes: any, start: any, inv: any): void; + updatem(player: any): void; + updatej(player: any): void; + updatehl(): void; + updateh(compute: any): void; + updatehx(node: any): void; + updated(): void; + updatez(): void; + update(): void; + recycle(node: any, key: any): any; /** * @author curpond * @author Tipx-L * @param {number} [numberOfPlayers] */ - static updateConnectPlayerPositions(numberOfPlayers?: number): void; + updateConnectPlayerPositions(numberOfPlayers?: number | undefined): void; /** * @author curpond * @author Tipx-L * @param {number} [numberOfPlayers] */ - static updatePlayerPositions(numberOfPlayers?: number): void; - static updateRoundNumber(roundNumber: any, cardPileNumber: any): void; + updatePlayerPositions(numberOfPlayers?: number | undefined): void; + updateRoundNumber(roundNumber: any, cardPileNumber: any): void; } -export const ui: typeof UI; -import { Uninstantable } from "../util/index.js"; +export let ui: UI; +export function setUI(instance?: UI | undefined): void; import { Create } from "./create/index.js"; import { Click } from "./click/index.js"; diff --git a/node_modules/@types/noname-typings/package.json b/node_modules/@types/noname-typings/package.json index 80981fd24..5c9f66ff6 100644 --- a/node_modules/@types/noname-typings/package.json +++ b/node_modules/@types/noname-typings/package.json @@ -1,6 +1,6 @@ { "name": "noname-typings", - "version": "2024.04.06", + "version": "2024.04.11", "description": "Noname typings, mainly for showing type hints when creating extensions of the Sanguosha-like game Noname.", "repository": { "type": "git", diff --git a/node_modules/@types/noname-typings/type.d.ts b/node_modules/@types/noname-typings/type.d.ts index 6929b2406..4875a9af2 100644 --- a/node_modules/@types/noname-typings/type.d.ts +++ b/node_modules/@types/noname-typings/type.d.ts @@ -59,12 +59,12 @@ declare type GeneratorContentFuncByAll = (event: GameEventPromise, map: { declare type OldContentFuncByAll = () => void -declare type Game = typeof import('./nonameModules/noname.d.ts').game; -declare type Library = typeof import('./nonameModules/noname.d.ts').lib; -declare type Status = typeof import('./nonameModules/noname.d.ts')._status; -declare type UI = typeof import('./nonameModules/noname.d.ts').ui; -declare type Get = typeof import('./nonameModules/noname.d.ts').get; -declare type AI = typeof import('./nonameModules/noname.d.ts').ai; +declare type Game = typeof import('noname-typings/nonameModules/noname.js').game; +declare type Library = typeof import('noname-typings/nonameModules/noname.js').lib; +declare type Status = typeof import('noname-typings/nonameModules/noname.js')._status; +declare type UI = typeof import('noname-typings/nonameModules/noname.js').ui; +declare type Get = typeof import('noname-typings/nonameModules/noname.js').get; +declare type AI = typeof import('noname-typings/nonameModules/noname.js').ai; declare type Button = import('./nonameModules/noname/library/index.js').Button; declare type Card = import('./nonameModules/noname/library/index.js').Card; @@ -195,7 +195,6 @@ declare interface importCharacterConfig { * 若里面是项目内的同名字段,将覆盖原方法 */ game?: SMap; - /** * 类型:键值对 * @@ -538,6 +537,80 @@ declare interface importExtensionConfig { [key: string]: any; } +/** + * 导入玩法的配置 + */ +declare interface importPlayConfig { + /** 扩展名 */ + name: string; + arenaReady?: Function; + /** + * 设置播放录像 + */ + video?: Function; + /** + * 设置技能 + * */ + skill?: SMap; + /** + * 设置该武将包独有的卡牌(或者是特殊卡牌) + * + * */ + card?: SMap; + translate?: SMap; + /** + * 对应lib.element + * + * 若里面是项目内的同名字段,将覆盖原方法 + */ + element?: SMap; + /** + * 对应ai + * + * 若里面是项目内的同名字段,将覆盖原方法 + */ + ai?: SMap; + /** + * 对应ui + * + * 若里面是项目内的同名字段,将覆盖原方法 + */ + ui?: SMap; + /** + * 对应game + * + * 若里面是项目内的同名字段,将覆盖原方法 + */ + game?: SMap; + /** + * 类型:键值对 + * + * 作用:对应get + * 若里面是项目内的同名字段,将覆盖原方法 + */ + get?: SMap; + /** + * 帮助内容将显示在菜单-选项-帮助中 + * + * 游戏编辑器的帮助代码基本示例结构: + * + * "帮助条目": + * ```jsx + *
                                    + *
                                  • 列表1-条目1 + *
                                  • 列表1-条目2 + *
                                  + *
                                    + *
                                  1. 列表2-条目1 + *
                                  2. 列表2-条目2 + * + * ``` + * (目前可显示帮助信息:mode,extension,card卡包,character武将包) + */ + help?: SMap; + [key: string]: any; +} + /** * 菜单的选项的配置 * diff --git a/node_modules/@types/noname-typings/windowEx.d.ts b/node_modules/@types/noname-typings/windowEx.d.ts index fca9c3721..f089f6478 100644 --- a/node_modules/@types/noname-typings/windowEx.d.ts +++ b/node_modules/@types/noname-typings/windowEx.d.ts @@ -70,4 +70,6 @@ declare interface Window { initReadWriteFunction?(game: Game): Promise; bannedKeyWords: string[]; + + device: Device; } diff --git a/noname.js b/noname.js index 45db36bc4..24d68dcae 100644 --- a/noname.js +++ b/noname.js @@ -1,8 +1,8 @@ -export { GNC as gnc } from './noname/gnc/index.js'; -export { AI as ai } from './noname/ai/index.js'; -export { Game as game } from './noname/game/index.js'; -export { Get as get } from './noname/get/index.js'; -export { Library as lib } from './noname/library/index.js'; -export { status as _status } from './noname/status/index.js'; -export { UI as ui } from './noname/ui/index.js'; +export { GNC, gnc, setGNC } from './noname/gnc/index.js'; +export { AI, ai, setAI } from './noname/ai/index.js'; +export { Game, game, setGame } from './noname/game/index.js'; +export { Get, get, setGet } from './noname/get/index.js'; +export { Library, lib, setLibrary } from './noname/library/index.js'; +export { status, _status, setStatus } from './noname/status/index.js'; +export { UI, ui, setUI } from './noname/ui/index.js'; export { boot } from './noname/init/index.js'; diff --git a/noname/ai/basic.js b/noname/ai/basic.js index 0d03bb8c1..faead5d95 100644 --- a/noname/ai/basic.js +++ b/noname/ai/basic.js @@ -1,23 +1,20 @@ -import { Get as get } from '../get/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { Library as lib } from '../library/index.js'; -import { GNC as gnc } from '../gnc/index.js'; -import { Uninstantable } from "../util/index.js"; -import { CacheContext } from '../library/cache/cacheContext.js'; - -export class Basic extends Uninstantable { +import { get } from "../get/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { CacheContext } from "../library/cache/cacheContext.js"; +export class Basic { /** * @param { ( - * button: Button, + * button: Button, * buttons?: Button[] * ) => number } check */ - static chooseButton(check) { + chooseButton(check) { const event = _status.event; let i, j, range, buttons, buttons2; - let ok = false, forced = event.forced; + let ok = false, + forced = event.forced; let iwhile = 100; while (iwhile--) { range = get.select(event.selectButton); @@ -33,7 +30,7 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - return (j > 0); + return j > 0; } buttons = get.selectableButtons(); if (buttons.length == 0) { @@ -63,7 +60,7 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - buttons[ix].classList.add('selected'); + buttons[ix].classList.add("selected"); ui.selected.buttons.add(buttons[ix]); game.check(); if (ui.selected.buttons.length >= range[0]) { @@ -81,11 +78,12 @@ export class Basic extends Uninstantable { * ) => number } check * @returns { boolean | undefined } */ - static chooseCard(check) { + chooseCard(check) { const event = _status.event; - if (event.filterCard == undefined) return (check() > 0); + if (event.filterCard == undefined) return check() > 0; let i, j, range, cards, cards2, skills, effect; - let ok = false, forced = event.forced; + let ok = false, + forced = event.forced; let iwhile = 100; while (iwhile--) { range = get.select(event.selectCard); @@ -104,7 +102,7 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - return (j > 0); + return j > 0; } cards = get.selectableCards(); // @ts-ignore @@ -139,19 +137,17 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - if (typeof cards[ix] == 'string') { + if (typeof cards[ix] == "string") { ui.click.skill(cards[ix]); var info = get.info(event.skill); if (info.filterCard) { check = info.check || get.unuseful2; - return (Basic.chooseCard(check)); - } - else { + return this.chooseCard(check); + } else { return true; } - } - else { - cards[ix].classList.add('selected'); + } else { + cards[ix].classList.add("selected"); ui.selected.cards.add(cards[ix]); game.check(); if (ui.selected.cards.length >= range[0]) { @@ -167,13 +163,14 @@ export class Basic extends Uninstantable { * @param { ( * target?: Player, * targets?: Player[] - * ) => number } check + * ) => number } check */ - static chooseTarget(check) { + chooseTarget(check) { const event = _status.event; - if (event.filterTarget == undefined) return (check() > 0); + if (event.filterTarget == undefined) return check() > 0; let i, j, range, targets, targets2, effect; - let ok = false, forced = event.forced; + let ok = false, + forced = event.forced; let iwhile = 100; while (iwhile--) { range = get.select(event.selectTarget); @@ -191,10 +188,9 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - return (j > 0); - } - else if (range[1] == 0) { - return check() > 0 + return j > 0; + } else if (range[1] == 0) { + return check() > 0; } targets = get.selectableTargets(); if (targets.length == 0) { @@ -224,7 +220,7 @@ export class Basic extends Uninstantable { } CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); - targets[ix].classList.add('selected'); + targets[ix].classList.add("selected"); ui.selected.targets.add(targets[ix]); game.check(); if (ui.selected.targets.length >= range[0]) { diff --git a/noname/ai/index.js b/noname/ai/index.js index 6452195ef..ec20755c6 100644 --- a/noname/ai/index.js +++ b/noname/ai/index.js @@ -1,20 +1,22 @@ -import { Get as get } from '../get/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { Library as lib } from '../library/index.js'; -import { GNC as gnc } from '../gnc/index.js'; -import { Uninstantable } from "../util/index.js"; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { Basic } from "./basic.js"; -import { Basic } from './basic.js'; +export class AI { + basic = new Basic(); + get = get; +} -export class AI extends Uninstantable { - static basic = Basic; - static get = get; +export let ai = new AI(); + +/** + * @param { InstanceType } [instance] + */ +export let setAI = (instance) => { + ai = instance || new AI(); + if (lib.config.dev) { + window.ai = ai; + } }; -export const ai = AI; - -export { - Basic -} +export { Basic }; diff --git a/noname/game/check.js b/noname/game/check.js new file mode 100644 index 000000000..8efc73174 --- /dev/null +++ b/noname/game/check.js @@ -0,0 +1,151 @@ +import { get } from "../get/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { lib } from "../library/index.js"; + +export class Check { + processSelection({ type, items, event, useCache, isSelectable }) { + let ok = true, + auto; + let selectableItems = false; + const uppercaseType = (type) => type[0].toUpperCase() + type.slice(1); + const uiSelected = ui.selected[`${type}s`]; + const range = get.select(event[`select${uppercaseType(type)}`]); + + if (event.forceAuto && uiSelected.length === range[1]) auto = true; + else if (range[0] !== range[1] || range[0] > 1) auto = false; + + let cache; + let firstCheck = false; + + if (useCache) { + if (!event[`_${type}Choice`]) event[`_${type}Choice`] = {}; + let cacheId = 0; + for (let Type of ["button", "card", "target"]) { + if (type === Type) break; + if (Type === "target") Type = "player"; + ui.selected[`${Type}s`].forEach((i) => (cacheId ^= i[`${Type}id`])); + } + if (!event[`_${type}Choice`][cacheId]) { + event[`_${type}Choice`][cacheId] = []; + firstCheck = true; + } + cache = event[`_${type}Choice`][cacheId]; + } + + items.forEach((item) => { + let selectable; + if (!lib.filter.cardAiIncluded(item)) selectable = false; + else if (useCache && !firstCheck) selectable = cache.includes(item); + else selectable = isSelectable(item, event); + + if (range[1] <= -1) { + if (selectable) { + item.classList.add("selected"); + uiSelected.add(item); + } else { + item.classList.remove("selected"); + uiSelected.remove(item); + } + if (item.updateTransform) item.updateTransform(selectable); + } else { + if (selectable && uiSelected.length < range[1]) { + item.classList.add("selectable"); + if (firstCheck) cache.push(item); + } else item.classList.remove("selectable"); + } + + if (item.classList.contains("selectable")) selectableItems = true; + else if (item.classList.contains("selected")) item.classList.add("selectable"); + + game.callHook(`check${uppercaseType(type)}`, [item, event]); + }); + + if (event[`${type}Required`] && uiSelected.length === 0) ok = false; + else if (uiSelected.length < range[0] && (!event.forced || selectableItems || event.complexSelect)) + ok = false; + + if (event.custom && event.custom.add[type]) event.custom.add[type](); + + return { ok, auto }; + } + button(event, useCache) { + const player = event.player; + const buttons = event.dialog.buttons; + const isSelectable = (button, event) => { + if (!lib.filter.buttonIncluded(button)) return false; + if (button.classList.contains("unselectable")) return false; + return event.filterButton(button, player); + }; + return game.Check.processSelection({ type: "button", items: buttons, event, useCache, isSelectable }); + } + card(event, useCache) { + const player = event.player; + const cards = player.getCards(event.position); + const isSelectable = (card, event) => { + if (card.classList.contains("uncheck")) return false; + if (player.isOut()) return false; + if (!lib.filter.cardRespondable(card, player)) return false; + return event.filterCard(card, player); + }; + return game.Check.processSelection({ type: "card", items: cards, event, useCache, isSelectable }); + } + target(event, useCache) { + const player = event.player; + const card = get.card(); + const targets = game.players.slice(); + if (event.deadTarget) targets.addArray(game.dead); + const isSelectable = (target, event) => { + if (game.chess && !event.chessForceAll && player && get.distance(player, target, "pure") > 7) + return false; + if (target.isOut()) return false; + return event.filterTarget(card, player, target); + }; + return game.Check.processSelection({ type: "target", items: targets, event, useCache, isSelectable }); + } + skill(event) { + if (ui.skills) ui.skills.close(); + if (ui.skills2) ui.skills2.close(); + if (ui.skills3) ui.skills3.close(); + if (event.skill || !get.noSelected() || _status.noconfirm) return; + + const player = event.player; + if (!event._skillChoice) + event._skillChoice = game + .expandSkills(player.getSkills("invisible").concat(lib.skill.global)) + .filter((skill) => lib.filter.filterEnable(event, player, skill)); + + const skills = event._skillChoice.filter((i) => event.isMine() || !event._aiexclude.includes(i)); + const globallist = game.expandSkills(lib.skill.global.slice()); + const ownedlist = game.expandSkills(player.getSkills("invisible", false)); + + const ownedSkills = [], + globalSkills = [], + equipSkills = []; + skills.forEach((skill) => { + if (globallist.includes(skill)) globalSkills.push(skill); + else if (!ownedlist.includes(skill)) equipSkills.push(skill); + else ownedSkills.push(skill); + }); + + if (ownedSkills.length) ui.create.skills(ownedSkills); + if (globalSkills.length) ui.create.skills2(globalSkills); + if (equipSkills.length) ui.create.skills3(equipSkills); + } + confirm(event, confirm) { + ui.arena.classList.add("selecting"); + if ( + event.filterTarget && + (!event.filterCard || + !event.position || + (typeof event.position == "string" && !event.position.includes("e"))) + ) { + ui.arena.classList.add("tempnoe"); + } + game.countChoose(); + if (!_status.noconfirm && !_status.event.noconfirm && (_status.mouseleft || !_status.mousedown)) { + ui.create.confirm(confirm); + } + } +} diff --git a/noname/game/dynamic-style/index.js b/noname/game/dynamic-style/index.js index 62ec36f04..19d0399de 100644 --- a/noname/game/dynamic-style/index.js +++ b/noname/game/dynamic-style/index.js @@ -1,4 +1,3 @@ - export class DynamicStyle { /** * Object of style @@ -56,9 +55,11 @@ export class DynamicStyle { * @returns {string} 样式的字符串形式 */ translate(style) { - return Object.entries(style).map(item => - `${item[0].replace(/([A-Z])/g, match => - `-${match.toLowerCase()}`)}: ${item[1]};`).join(" "); + return Object.entries(style) + .map( + (item) => `${item[0].replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`)}: ${item[1]};` + ) + .join(" "); } /** @@ -81,7 +82,7 @@ export class DynamicStyle { * @returns {boolean} */ has(name) { - return this.#cache.rules.some(item => item[0] === name); + return this.#cache.rules.some((item) => item[0] === name); } /** @@ -92,7 +93,7 @@ export class DynamicStyle { * @returns {?StyleObject} */ get(name) { - const result = this.find(item => item[0] === name); + const result = this.find((item) => item[0] === name); return result ? result[1] : null; } @@ -157,7 +158,7 @@ export class DynamicStyle { * @returns {boolean[]} 添加的结果,为`true`则添加成功,为`false`则添加失败 */ addObject(object) { - return Object.entries(object).map(item => this.add(item[0], item[1])); + return Object.entries(object).map((item) => this.add(item[0], item[1])); } /** @@ -171,8 +172,7 @@ export class DynamicStyle { this.#cache.rules.splice(index, 1); this.#cache.sheet.deleteRule(index); return true; - } - catch (e) { + } catch (e) { console.log(e); return false; } @@ -186,7 +186,7 @@ export class DynamicStyle { removeStyles(name, styles) { if (!this.has(name)) return false; const style = this.get(name); - styles.forEach(styleName => { + styles.forEach((styleName) => { delete style[styleName]; }); return this.update(name, style); @@ -212,8 +212,7 @@ export class DynamicStyle { this.#cache.sheet.insertRule(this.generate(name, style), index); } return true; - } - catch (e) { + } catch (e) { console.log(e); return false; } diff --git a/noname/game/index.js b/noname/game/index.js index e971b0536..002c12b42 100644 --- a/noname/game/index.js +++ b/noname/game/index.js @@ -1,81 +1,86 @@ /** * @typedef {{ - * cardMove:GameEventPromise[], - * custom: GameEventPromise[], - * useCard: GameEventPromise[], + * cardMove: GameEventPromise[], + * custom: GameEventPromise[], + * useCard: GameEventPromise[], * changeHp: GameEventPromise[], - * everything: GameEventPromise[] + * everything: GameEventPromise[] * }} GameHistory - * @typedef { { type: string, player?: string, content?: string | any[], delay: number } } Video + * @typedef { { name?: string, type: string, player?: string, content?: string | any[], delay: number } } Video * @typedef { { mode: string, name: string[], name1: string, name2?: string, time: number, video: Video, win: boolean } } Videos -*/ + */ -import { AI as ai } from '../ai/index.js'; -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { GNC as gnc } from '../gnc/index.js'; -import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction, delay, nonameInitialized } from "../util/index.js"; +import { ai } from "../ai/index.js"; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { gnc } from "../gnc/index.js"; +import { + userAgent, + Uninstantable, + GeneratorFunction, + AsyncFunction, + delay, + nonameInitialized, +} from "../util/index.js"; import { DynamicStyle } from "./dynamic-style/index.js"; import { GamePromises } from "./promises.js"; +import { Check } from "./check.js"; -export class Game extends Uninstantable { - static online = false; - static onlineID = null; - static onlineKey = null; +export class Game { + online = false; + onlineID = null; + onlineKey = null; /** * @type {Player[]} */ - static players = []; + players = []; /** * @type {Player[]} */ - static dead = []; - static imported = []; + dead = []; + imported = []; /** * @type { { [key: string]: Player } } */ - static playerMap = {}; - static phaseNumber = 0; - static roundNumber = 0; - static shuffleNumber = 0; - static promises = GamePromises; + playerMap = {}; + phaseNumber = 0; + roundNumber = 0; + shuffleNumber = 0; + promises = new GamePromises(); /** * @type { string } */ - static layout; + // @ts-ignore + layout; /** * @type { Player } */ - static me; + // @ts-ignore + me; /** * @type { boolean } */ - static chess; - static globalEventHandlers = new class { + // @ts-ignore + chess; + globalEventHandlers = new (class { constructor() { this._handlers = {}; } getHandler(name, type) { - if (!type) - type = this.getDefaultHandlerType(name); - if (!this._handlers[name]) - return null; - if (!this._handlers[name][type]) - return null; + if (!type) type = this.getDefaultHandlerType(name); + if (!this._handlers[name]) return null; + if (!this._handlers[name][type]) return null; return this._handlers[name][type]; } ensureHandlerList(name, type) { - if (!type) - type = this.getDefaultHandlerType(name); - if (!this._handlers[name]) - this._handlers[name] = {}; - if (!this._handlers[name][type]) - this._handlers[name][type] = []; + if (!type) type = this.getDefaultHandlerType(name); + if (!this._handlers[name]) this._handlers[name] = {}; + if (!this._handlers[name][type]) this._handlers[name][type] = []; return this._handlers[name][type]; } @@ -92,8 +97,8 @@ export class Game extends Uninstantable { pushHandler(name, type) { const args = Array.from(arguments); - const functions = (typeof type == 'string' ? args.slice(2) : args.slice(1)); - type = (typeof type == 'string' ? type : this.getDefaultHandlerType(name)); + const functions = typeof type == "string" ? args.slice(2) : args.slice(1); + type = typeof type == "string" ? type : this.getDefaultHandlerType(name); this.ensureHandlerList(name, type).addArray(functions); } @@ -113,40 +118,57 @@ export class Game extends Uninstantable { }); }); } - } + })(); //Stratagem //谋攻 - static setStratagemBuffCost(cardName, cost) { return game.broadcastAll((clientCardName, clientCost) => lib.stratagemBuff.cost.set(clientCardName, clientCost), cardName, cost) } - static setStratagemBuffEffect(cardName, effect) { return game.broadcastAll((clientCardName, clientEffect) => lib.stratagemBuff.cost.set(clientCardName, clientEffect), cardName, effect) } - static setStratagemBuffPrompt(cardName, prompt) { return game.broadcastAll((clientCardName, clientPrompt) => lib.stratagemBuff.cost.set(clientCardName, clientPrompt), cardName, prompt) } + setStratagemBuffCost(cardName, cost) { + return game.broadcastAll( + (clientCardName, clientCost) => lib.stratagemBuff.cost.set(clientCardName, clientCost), + cardName, + cost + ); + } + setStratagemBuffEffect(cardName, effect) { + return game.broadcastAll( + (clientCardName, clientEffect) => lib.stratagemBuff.cost.set(clientCardName, clientEffect), + cardName, + effect + ); + } + setStratagemBuffPrompt(cardName, prompt) { + return game.broadcastAll( + (clientCardName, clientPrompt) => lib.stratagemBuff.cost.set(clientCardName, clientPrompt), + cardName, + prompt + ); + } /** * 添加新的属性杀 */ - static addNature(nature, translation, config) { + addNature(nature, translation, config) { if (!nature) throw new TypeError(); - if (translation && translation.length) lib.translate['nature_' + nature] = translation; + if (translation && translation.length) lib.translate["nature_" + nature] = translation; game.callHook("addNature", [nature, translation, config]); return nature; } /** * 判断卡牌信息/事件是否有某个属性 */ - static hasNature(item, nature, player) { + hasNature(item, nature, player) { var natures = get.natureList(item, player); if (!nature) return natures.length > 0; - if (nature == 'linked') return natures.some(n => lib.linked.includes(n)); + if (nature == "linked") return natures.some((n) => lib.linked.includes(n)); return get.is.sameNature(natures, nature); } /** * 设置卡牌信息/事件的属性 */ - static setNature(item, nature, addNature) { + setNature(item, nature, addNature) { if (!nature) nature = []; if (!addNature) { item.nature = get.nature(nature); if (!item.nature.length) delete item.nature; - } - else { + } else { let natures = Array.isArray(nature) ? nature : nature.split(lib.natureSeparator); let _nature = get.natureList(item, false); _nature.addArray(natures); @@ -157,15 +179,14 @@ export class Game extends Uninstantable { /** * 洗牌 */ - static washCard() { + washCard() { if (!ui.cardPile.hasChildNodes() && !ui.discardPile.hasChildNodes()) return false; if (_status.maxShuffle != undefined) { if (_status.maxShuffle == 0) { if (_status.maxShuffleCheck) { game.over(_status.maxShuffleCheck()); - } - else { - game.over('平局'); + } else { + game.over("平局"); } return []; } @@ -187,12 +208,12 @@ export class Game extends Uninstantable { cards.push(currentcard); } cards.randomSort(); - return game.cardsGotoPile(cards, 'triggeronly', 'washCard', ['shuffleNumber', game.shuffleNumber]) + return game.cardsGotoPile(cards, "triggeronly", "washCard", ["shuffleNumber", game.shuffleNumber]); } /** * 基于钩子的添加势力方法 */ - static addGroup(id, short, name, config) { + addGroup(id, short, name, config) { if (!id) throw new TypeError(); if (lib.comparator.typeEquals(short, "object")) { config = short; @@ -216,27 +237,27 @@ export class Game extends Uninstantable { */ /** * 通用的调用钩子函数 - * + * * @template {NonameHookType} HookType * @template {keyof HookType} Name * @param {Name} name - * @param {Parameters} args + * @param {Parameters} args */ - static callHook(name, args) { + callHook(name, args) { const callHook = () => { for (const hook of lib.hooks[name]) { if (hook != null && typeof hook == "function") { hook(...args); } } - } + }; if ("onload" in lib) lib.onload.add(callHook); else callHook(); } //Yingbian //应变 - static yingbianEffect(event, content) { - const yingbianEffect = game.createEvent('yingbianEffect'); + yingbianEffect(event, content) { + const yingbianEffect = game.createEvent("yingbianEffect"); yingbianEffect.player = event.player; yingbianEffect.card = event.card; yingbianEffect._trigger = event; @@ -244,29 +265,60 @@ export class Game extends Uninstantable { yingbianEffect._args = Array.from(arguments); return yingbianEffect; } - static setYingbianConditionColor(yingbianCondition, color) { return game.broadcastAll((yingbianCondition, color) => lib.yingbian.condition.color.set(yingbianCondition, color), yingbianCondition, color) } - static setComplexYingbianCondition(yingbianCondition, condition) { return game.broadcastAll((yingbianCondition, condition) => lib.yingbian.condition.complex.set(yingbianCondition, condition), yingbianCondition, condition) } - static setSimpleYingbianCondition(yingbianCondition, condition) { return game.broadcastAll((yingbianCondition, condition) => lib.yingbian.condition.simple.set(yingbianCondition, condition), yingbianCondition, condition) } - static setYingbianEffect(yingbianEffect, effect) { return game.broadcastAll((yingbianEffect, effect) => lib.yingbian.effect.set(yingbianEffect, effect), yingbianEffect, effect) } - static setYingbianPrompt(yingbian, prompt) { return game.broadcastAll((yingbian, prompt) => lib.yingbian.prompt.set(yingbian, prompt), yingbian, prompt) } + setYingbianConditionColor(yingbianCondition, color) { + return game.broadcastAll( + (yingbianCondition, color) => lib.yingbian.condition.color.set(yingbianCondition, color), + yingbianCondition, + color + ); + } + setComplexYingbianCondition(yingbianCondition, condition) { + return game.broadcastAll( + (yingbianCondition, condition) => + lib.yingbian.condition.complex.set(yingbianCondition, condition), + yingbianCondition, + condition + ); + } + setSimpleYingbianCondition(yingbianCondition, condition) { + return game.broadcastAll( + (yingbianCondition, condition) => lib.yingbian.condition.simple.set(yingbianCondition, condition), + yingbianCondition, + condition + ); + } + setYingbianEffect(yingbianEffect, effect) { + return game.broadcastAll( + (yingbianEffect, effect) => lib.yingbian.effect.set(yingbianEffect, effect), + yingbianEffect, + effect + ); + } + setYingbianPrompt(yingbian, prompt) { + return game.broadcastAll( + (yingbian, prompt) => lib.yingbian.prompt.set(yingbian, prompt), + yingbian, + prompt + ); + } /** * Dynamic Style Manager * 动态CSS管理对象 - * + * * > No idea to write, it's just a tool to handle css. * > 暂时不知道写啥,反正就是个管CSS的工具 - * + * * @example * // 为符合".content"的元素增加"text-align: center"的样式 * game.dynamicStyle.add(".content", { * textAlign: "center" * }); - * + * * // 在上一条的基础上,再为".content"增加"color: #FFFFFF"的样式 * game.dynamicStyle.add(".content", { * color: "#FFFFFF" * }); - * + * * @example * // 批量添加符合对应选择器元素的样式 * game.dynamicStyle.addObject({ @@ -277,15 +329,15 @@ export class Game extends Uninstantable { * fontSize: "16px" * } * }); - * + * * @example * // 移除".content"元素的样式 * game.dynamicStyle.remove(".content"); - * + * * @example * // 移除".content"元素的"textAlign"样式 * game.dynamicStyle.removeStyles(".content", ["textAligh"]); - * + * * @example * // 如果".content"元素的样式存在,则将".content"的样式修改为给定的样式 * // 反之效果同`game.dynamicStyle.add` @@ -293,129 +345,143 @@ export class Game extends Uninstantable { * textAlign: "center" * }); */ - static dynamicStyle = new DynamicStyle() + dynamicStyle = new DynamicStyle(); /** * Add a background music to the config option - * + * * 在设置选项中添加一首背景音乐 */ - static addBackgroundMusic(link, musicName, aozhan) { - const backgroundMusicSetting = ui[aozhan ? 'aozhan_bgm' : 'background_music_setting'], menu = backgroundMusicSetting._link.menu, config = backgroundMusicSetting._link.config; - if (typeof musicName != 'string') musicName = link; + addBackgroundMusic(link, musicName, aozhan) { + const backgroundMusicSetting = ui[aozhan ? "aozhan_bgm" : "background_music_setting"], + menu = backgroundMusicSetting._link.menu, + config = backgroundMusicSetting._link.config; + if (typeof musicName != "string") musicName = link; if (aozhan) lib.mode.guozhan.config.aozhan_bgm.item[link] = musicName; else lib.config.all.background_music.add(link); config.item[link] = musicName; - const textMenu = ui.create.div('', musicName, menu, function () { - const node = this.parentNode._link, config = node._link.config; - node._link.current = this.link; - const tmpName = node.lastChild.innerHTML; - node.lastChild.innerHTML = config.item[this._link]; - if (config.onclick && config.onclick.call(node, this._link, this) === false) node.lastChild.innerHTML = tmpName; - if (config.update) config.update(); - }, menu.childElementCount - 2); + const textMenu = ui.create.div( + "", + musicName, + menu, + function () { + const node = this.parentNode._link, + config = node._link.config; + node._link.current = this.link; + const tmpName = node.lastChild.innerHTML; + node.lastChild.innerHTML = config.item[this._link]; + if (config.onclick && config.onclick.call(node, this._link, this) === false) + node.lastChild.innerHTML = tmpName; + if (config.update) config.update(); + }, + menu.childElementCount - 2 + ); textMenu._link = link; config.updatex.call(backgroundMusicSetting, []); } /** * Remove a background music from the config option - * + * * 从设置选项中移除一首背景音乐 */ - static removeBackgroundMusic(link, aozhan) { + removeBackgroundMusic(link, aozhan) { if (aozhan) { - if (['disabled', 'random'].includes(link)) return; + if (["disabled", "random"].includes(link)) return; delete lib.mode.guozhan.config.aozhan_bgm.item[link]; if (!Array.isArray(_status.aozhanBGMToRemove)) _status.aozhanBGMToRemove = []; _status.aozhanBGMToRemove.add(link); - } - else { - if (['music_off', 'music_custom', 'music_random'].includes(link)) return; + } else { + if (["music_off", "music_custom", "music_random"].includes(link)) return; lib.config.all.background_music.remove(link); } - const backgroundMusicSetting = ui[aozhan ? 'aozhan_bgm' : 'background_music_setting'], config = backgroundMusicSetting._link.config; + const backgroundMusicSetting = ui[aozhan ? "aozhan_bgm" : "background_music_setting"], + config = backgroundMusicSetting._link.config; config.updatex.call(backgroundMusicSetting, []); } - static updateBackground() { + updateBackground() { const background = _status.tempBackground || lib.config.image_background; ui.background.delete(); - const uiBackground = ui.background = ui.create.div('.background'), style = uiBackground.style; + const uiBackground = (ui.background = ui.create.div(".background")), + style = uiBackground.style; if (lib.config.image_background_blur) { - style.filter = 'blur(8px)'; - style.webkitFilter = 'blur(8px)'; - style.transform = 'scale(1.05)'; + style.filter = "blur(8px)"; + style.webkitFilter = "blur(8px)"; + style.transform = "scale(1.05)"; } document.body.insertBefore(uiBackground, document.body.firstChild); - if (background.startsWith('db:')) uiBackground.setBackgroundDB(background.slice(3)); - else if (background.startsWith('ext:')) uiBackground.setBackgroundImage(`extension/${background.slice(4)}`); - else if (background == 'default') { - uiBackground.addTempClass('start'); - style.backgroundImage = 'none'; - } - else if (background.startsWith('custom_')) { - style.backgroundImage = 'none'; - game.getDB('image', background).then(fileToLoad => { + if (background.startsWith("db:")) uiBackground.setBackgroundDB(background.slice(3)); + else if (background.startsWith("ext:")) + uiBackground.setBackgroundImage(`extension/${background.slice(4)}`); + else if (background == "default") { + uiBackground.addTempClass("start"); + style.backgroundImage = "none"; + } else if (background.startsWith("custom_")) { + style.backgroundImage = "none"; + game.getDB("image", background).then((fileToLoad) => { if (!fileToLoad) return; const fileReader = new FileReader(); - fileReader.onload = fileLoadedEvent => style.backgroundImage = `url(${fileLoadedEvent.target.result})`; + fileReader.onload = (fileLoadedEvent) => + (style.backgroundImage = `url(${fileLoadedEvent.target.result})`); fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else uiBackground.setBackgroundImage(`image/background/${background}.jpg`); - style.backgroundSize = 'cover'; - style.backgroundPosition = '50% 50%'; + } else uiBackground.setBackgroundImage(`image/background/${background}.jpg`); + style.backgroundSize = "cover"; + style.backgroundPosition = "50% 50%"; } /** * Generate a beatmap using the given BPM, beats, and offset - * + * * 用给定的BPM、节拍和偏移生成谱面 */ - static generateBeatmapTimeleap(bpm, beats, offset) { return beats.map(value => Math.round(value * 60000 / bpm + (offset || 0))) } - static updateRenku() { + generateBeatmapTimeleap(bpm, beats, offset) { + return beats.map((value) => Math.round((value * 60000) / bpm + (offset || 0))); + } + updateRenku() { game.broadcast(function (renku) { _status.renku = renku; }, _status.renku); for (var i of game.players) { - if (i.storage.renku) i.markSkill('renku'); + if (i.storage.renku) i.markSkill("renku"); } } /** * 为牌添加知情者 - * @param { Card[] | Card } cards - * @param { Player[] } players + * @param { Card[] | Card } cards + * @param { Player[] } players */ - static addCardKnower(cards, players) { - if (get.itemtype(cards) == 'card') { + addCardKnower(cards, players) { + if (get.itemtype(cards) == "card") { // @ts-ignore cards = [cards]; } // @ts-ignore - cards.forEach(card => card.addKnower(players)); + cards.forEach((card) => card.addKnower(players)); } /** * 移除牌的所有知情者。 * @param { Card[] | Card } cards */ - static clearCardKnowers(cards) { + clearCardKnowers(cards) { // @ts-ignore - if (get.itemtype(cards) == 'card') { + if (get.itemtype(cards) == "card") { // @ts-ignore cards = [cards]; } // @ts-ignore - cards.forEach(card => card.clearKnowers()); + cards.forEach((card) => card.clearKnowers()); } /** * @param { { [key: string]: any } } [arg] */ - static loseAsync(arg) { - var next = game.createEvent('loseAsync'); + loseAsync(arg) { + var next = game.createEvent("loseAsync"); next.forceDie = true; next.getd = function (player, key, position) { if (!position) position = ui.discardPile; - if (!key) key = 'cards'; - var cards = [], event = this; - game.checkGlobalHistory('cardMove', function (evt) { - if (evt.name != 'lose' || evt.position != position || evt.getParent() != event) return; + if (!key) key = "cards"; + var cards = [], + event = this; + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.position != position || evt.getParent() != event) return; if (player && player != evt.player) return; cards.addArray(evt[key]); }); @@ -434,7 +500,7 @@ export class Game extends Uninstantable { cards2: [], gaintag_map: {}, }; - player.checkHistory('lose', function (evt) { + player.checkHistory("lose", function (evt) { if (evt.parent == that) { map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -454,7 +520,7 @@ export class Game extends Uninstantable { next.getg = function (player) { var that = this; var cards = []; - player.checkHistory('gain', function (evt) { + player.checkHistory("gain", function (evt) { if (evt.parent == that) { cards.addArray(evt.cards); } @@ -466,8 +532,8 @@ export class Game extends Uninstantable { } return next; } - static callFuncUseStepCache(prefix, func, params) { - if (typeof func != 'function') return; + callFuncUseStepCache(prefix, func, params) { + if (typeof func != "function") return; if (_status.closeStepCache || !_status.event) return func.apply(null, params); var cacheKey = "[" + prefix + "]" + get.paramToCacheKey.apply(null, params); var ret = _status.event.getStepCache(cacheKey); @@ -478,24 +544,24 @@ export class Game extends Uninstantable { return ret; } /** - * @param {string} name + * @param {string} name */ - static getRarity(name) { + getRarity(name) { var rank = lib.rank.rarity; - if (rank.legend.includes(name)) return 'legend'; - if (rank.epic.includes(name)) return 'epic'; - if (rank.rare.includes(name)) return 'rare'; - if (get.mode() != 'chess' && rank.junk.includes(name)) return 'junk'; - return 'common'; + if (rank.legend.includes(name)) return "legend"; + if (rank.epic.includes(name)) return "epic"; + if (rank.rare.includes(name)) return "rare"; + if (get.mode() != "chess" && rank.junk.includes(name)) return "junk"; + return "common"; } /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { boolean } */ - static hasGlobalHistory(key, filter, last) { + hasGlobalHistory(key, filter, last) { // md谁写的和getGlobalHistory一样?害人! if (!key || !filter) return false; else { @@ -506,8 +572,7 @@ export class Game extends Uninstantable { if (index > lastIndex) return false; return filter(event); }); - } - else { + } else { return history.some(filter); } } @@ -515,11 +580,11 @@ export class Game extends Uninstantable { /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { void } */ - static checkGlobalHistory(key, filter, last) { + checkGlobalHistory(key, filter, last) { // md谁写的和getGlobalHistory一样?害人! if (!key || !filter) return; else { @@ -530,8 +595,7 @@ export class Game extends Uninstantable { if (index > lastIndex) return false; return filter(event); }); - } - else { + } else { history.forEach(filter); } } @@ -544,11 +608,11 @@ export class Game extends Uninstantable { * @template { keyof GameHistory } T * @overload * @param { T } key - * @param { (event: GameEventPromise) => boolean } [filter] - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } [filter] + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { GameHistory[T] } */ - static getGlobalHistory(key, filter, last) { + getGlobalHistory(key, filter, last) { if (!key) return _status.globalHistory[_status.globalHistory.length - 1]; if (!filter) return _status.globalHistory[_status.globalHistory.length - 1][key]; else { @@ -558,7 +622,7 @@ export class Game extends Uninstantable { return history.filter((event, index) => { if (index > lastIndex) return false; return filter(event); - }) + }); } return history.filter(filter); } @@ -566,38 +630,40 @@ export class Game extends Uninstantable { /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { boolean } */ - static hasAllGlobalHistory(key, filter, last) { + hasAllGlobalHistory(key, filter, last) { if (!key || !filter) return false; - return _status.globalHistory.some(value => { + return _status.globalHistory.some((value) => { if (value[key]) { if (last && value[key].includes(last)) { const lastIndex = value[key].indexOf(last); - if (value[key].some((event, index) => { - if (index > lastIndex) return false; - return filter(event); - })) return true; - } - else { + if ( + value[key].some((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }) + ) + return true; + } else { if (value[key].some(filter)) return true; } } - }) + }); } /** * @template { keyof GameHistory } T * @param { T } key - * @param { (event: GameEventPromise) => boolean } filter - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } filter + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { void } */ - static checkAllGlobalHistory(key, filter, last) { + checkAllGlobalHistory(key, filter, last) { if (!key || !filter) return; let stopped = false; - _status.globalHistory.forEach(value => { + _status.globalHistory.forEach((value) => { if (value[key]) { if (last && value[key].includes(last) && !stopped) { stopped = true; @@ -606,12 +672,11 @@ export class Game extends Uninstantable { if (index > lastIndex) return false; return filter(event); }); - } - else { + } else { value[key].forEach(filter); } } - }) + }); } /** * @overload @@ -621,20 +686,19 @@ export class Game extends Uninstantable { * @template { keyof GameHistory } T * @overload * @param { T } key - * @param { (event: GameEventPromise) => boolean } [filter] - * @param { GameEventPromise } [last] + * @param { (event: import('../library/index.js').GameEventPromise) => boolean } [filter] + * @param { import('../library/index.js').GameEventPromise } [last] * @returns { GameHistory[T] } */ - static getAllGlobalHistory(key, filter, last) { + getAllGlobalHistory(key, filter, last) { const history = []; - _status.globalHistory.forEach(value => { + _status.globalHistory.forEach((value) => { if (!key || !value[key]) { history.push(value); - } - else { + } else { history.push(...value[key]); } - }) + }); if (filter) { if (last) { const lastIndex = history.indexOf(last); @@ -653,23 +717,23 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { Card } cards - * @returns { GameEventPromise } + * @param { Card } cards + * @returns { import('../library/index.js').GameEventPromise } */ /** * @overload - * @param {Card[]} cards - * @returns { GameEventPromise } + * @param {Card[]} cards + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsDiscard(cards) { + cardsDiscard(cards) { /** @type { 'cards' | 'card' | void } */ // @ts-ignore var type = get.itemtype(cards); - if (type != 'cards' && type != 'card') return; - var next = game.createEvent('cardsDiscard'); + if (type != "cards" && type != "card") return; + var next = game.createEvent("cardsDiscard"); // @ts-ignore - next.cards = type == 'cards' ? cards.slice(0) : [cards]; - next.setContent('cardsDiscard'); + next.cards = type == "cards" ? cards.slice(0) : [cards]; + next.setContent("cardsDiscard"); next.getd = function (player, key, position) { return this.cards.slice(0); }; @@ -681,22 +745,22 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { Card } cards - * @returns { GameEventPromise } + * @param { Card } cards + * @returns { import('../library/index.js').GameEventPromise } */ /** * @overload - * @param {Card[]} cards - * @returns { GameEventPromise } + * @param {Card[]} cards + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoOrdering(cards) { + cardsGotoOrdering(cards) { /** @type { 'cards' | 'card' | void } */ // @ts-ignore var type = get.itemtype(cards); - if (type != 'cards' && type != 'card') return; - var next = game.createEvent('cardsGotoOrdering'); - next.cards = type == 'cards' ? cards.slice(0) : [cards]; - next.setContent('cardsGotoOrdering'); + if (type != "cards" && type != "card") return; + var next = game.createEvent("cardsGotoOrdering"); + next.cards = type == "cards" ? cards.slice(0) : [cards]; + next.setContent("cardsGotoOrdering"); return next; } /** @@ -705,96 +769,90 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { Card } cards + * @param { Card } cards * @param { 'toRenku' | false } [bool] 为false时不触发trigger,为'toRenku'时牌放到仁库 - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ /** * @overload - * @param {Card[]} cards + * @param {Card[]} cards * @param { 'toRenku' | false } [bool] 为false时不触发trigger,为'toRenku'时牌放到仁库 - * @returns { GameEventPromise } + * @returns { import('../library/index.js').GameEventPromise } */ - static cardsGotoSpecial(cards, bool) { + cardsGotoSpecial(cards, bool) { /** @type { 'cards' | 'card' | void } */ // @ts-ignore var type = get.itemtype(cards); - if (type != 'cards' && type != 'card') return; - var next = game.createEvent('cardsGotoSpecial'); - next.cards = type == 'cards' ? cards.slice(0) : [cards]; - if (bool == 'toRenku') next.toRenku = true; + if (type != "cards" && type != "card") return; + var next = game.createEvent("cardsGotoSpecial"); + next.cards = type == "cards" ? cards.slice(0) : [cards]; + if (bool == "toRenku") next.toRenku = true; else if (bool === false) next.notrigger = true; - next.setContent('cardsGotoSpecial'); + next.setContent("cardsGotoSpecial"); return next; } /** - * + * * @param {...( - * Card[] | - * Card | + * Card[] | + * Card | * Function | * 'insert' | 'washCard' | 'triggeronly' | * [string, any] - * )} args - * @returns + * )} args + * @returns */ - static cardsGotoPile(...args) { + cardsGotoPile(...args) { /** * @type { Card[] } */ const cards = []; - const next = game.createEvent('cardsGotoPile'); + const next = game.createEvent("cardsGotoPile"); next.cards = cards; for (let i = 0; i < args.length; i++) { // @ts-ignore - let arg = args[i], itemtype = get.itemtype(arg); - if (itemtype == 'cards') { + let arg = args[i], + itemtype = get.itemtype(arg); + if (itemtype == "cards") { cards.addArray(arg); - } - else if (itemtype == 'card') { + } else if (itemtype == "card") { cards.add(arg); - } - else if (typeof arg == 'function') { + } else if (typeof arg == "function") { next.insert_index = arg; - } - else if (typeof arg == 'string') { - if (arg == 'insert') next.insert_card = true; - else if (arg == 'washCard') next.washCard = true; - else if (arg == 'triggeronly') next._triggeronly = true; - } - else if (Array.isArray(arg) && arg.length == 2 && typeof arg[0] == 'string') { + } else if (typeof arg == "string") { + if (arg == "insert") next.insert_card = true; + else if (arg == "washCard") next.washCard = true; + else if (arg == "triggeronly") next._triggeronly = true; + } else if (Array.isArray(arg) && arg.length == 2 && typeof arg[0] == "string") { next.set(arg[0], arg[1]); } } if (!cards.length) { _status.event.next.remove(next); - } - else { - next.setContent('cardsGotoPile'); + } else { + next.setContent("cardsGotoPile"); if (next._triggeronly) game.$cardsGotoPile(next); } return next; } /** - * @param { GameEventPromise } event + * @param { import('../library/index.js').GameEventPromise } event */ - static $cardsGotoPile(event) { + $cardsGotoPile(event) { const cards = event.cards; const pile = ui.cardPile; for (let i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('cardPile', null, event)) { + if (cards[i].willBeDestroyed("cardPile", null, event)) { cards[i].selfDestroy(event); continue; } if (event.insert_index) { cards[i].fix(); pile.insertBefore(cards[i], event.insert_index(event, cards[i])); - } - else if (event.insert_card) { + } else if (event.insert_card) { cards[i].fix(); pile.insertBefore(cards[i], pile.firstChild); - } - else { + } else { cards[i].fix(); pile.appendChild(cards[i]); } @@ -802,166 +860,162 @@ export class Game extends Uninstantable { game.updateRoundNumber(); } /** - * @param { false } [pause] + * @param { false } [pause] */ - static showHistory(pause) { - if (lib.config.show_history == 'left') { - ui.window.classList.add('leftbar'); - } - else if (lib.config.show_history == 'right') { - ui.window.classList.add('rightbar'); + showHistory(pause) { + if (lib.config.show_history == "left") { + ui.window.classList.add("leftbar"); + } else if (lib.config.show_history == "right") { + ui.window.classList.add("rightbar"); } if (pause != false && ui.pause) { ui.pause.show(); } } /** - * @param { string } src - * @param { true } [blur] + * @param { string } src + * @param { true } [blur] */ - static createBackground(src, blur) { - const current = document.body.querySelector('.background.upper'); + createBackground(src, blur) { + const current = document.body.querySelector(".background.upper"); if (current) current.delete(); - const node = ui.create.div('.background.blurbg', document.body); + const node = ui.create.div(".background.blurbg", document.body); node.setBackgroundImage(src); - node.style.backgroundSize = 'cover'; - if (blur) node.classList.add('paused'); + node.style.backgroundSize = "cover"; + if (blur) node.classList.add("paused"); return node; } /** - * - * @param { string } url - * @param { Player } [player] + * + * @param { string } url + * @param { Player } [player] */ - static changeLand(url, player) { - game.addVideo('changeLand', player, url); + changeLand(url, player) { + game.addVideo("changeLand", player, url); const parsedPath = lib.path.parse(url); // @ts-ignore delete parsedPath.base; - if (!parsedPath.dir) parsedPath.dir = 'image/card/'; - if (!parsedPath.ext) parsedPath.ext = '.jpg'; + if (!parsedPath.dir) parsedPath.dir = "image/card/"; + if (!parsedPath.ext) parsedPath.ext = ".jpg"; const fileName = parsedPath.name; - game.broadcastAll((formattedPath, name, skill, player) => { - const node = ui.create.div('.background.upper.land'); - node.setBackgroundImage(formattedPath); - node.destroy = () => { - if (node.skill) { - game.removeGlobalSkill(node.skill); - if (node.system) node.system.remove(); + game.broadcastAll( + (formattedPath, name, skill, player) => { + const node = ui.create.div(".background.upper.land"); + node.setBackgroundImage(formattedPath); + node.destroy = () => { + if (node.skill) { + game.removeGlobalSkill(node.skill); + if (node.system) node.system.remove(); + } + node.classList.add("hidden"); + setTimeout(() => node.remove(), 3000); + if (ui.land == node) ui.land = null; + }; + if (ui.land) { + document.body.insertBefore(node, ui.land); + ui.land.destroy(); + } else { + node.classList.add("hidden"); + document.body.insertBefore(node, ui.window); + ui.refresh(node); + node.classList.remove("hidden"); } - node.classList.add('hidden'); - setTimeout(() => node.remove(), 3000); - if (ui.land == node) ui.land = null; - } - if (ui.land) { - document.body.insertBefore(node, ui.land); - ui.land.destroy(); - } - else { - node.classList.add('hidden'); - document.body.insertBefore(node, ui.window); - ui.refresh(node); - node.classList.remove('hidden'); - } - ui.land = node; - if (!name) return; - node.name = name; - node.skill = skill; - if (player) { - node.player = player; - player.addTempSkill('land_used'); - } - lib.setPopped(node.system = ui.create.system(lib.translate[skill], null, true, true), () => { - const uiIntro = ui.create.dialog('hidden'); - uiIntro.addText(player ? `来源:${get.translation(player)}` : '地图').style.margin = '0'; - uiIntro._place_text = uiIntro.add(ui.create.div('.text', lib.translate[`${skill}_info`])); - uiIntro.add(ui.create.div('.placeholder.slim')); - return uiIntro; - }, 200); - game.addGlobalSkill(skill); - }, lib.path.format(parsedPath), fileName, `${fileName}_skill`, player); + ui.land = node; + if (!name) return; + node.name = name; + node.skill = skill; + if (player) { + node.player = player; + player.addTempSkill("land_used"); + } + lib.setPopped( + (node.system = ui.create.system(lib.translate[skill], null, true, true)), + () => { + const uiIntro = ui.create.dialog("hidden"); + uiIntro.addText(player ? `来源:${get.translation(player)}` : "地图").style.margin = + "0"; + uiIntro._place_text = uiIntro.add( + ui.create.div(".text", lib.translate[`${skill}_info`]) + ); + uiIntro.add(ui.create.div(".placeholder.slim")); + return uiIntro; + }, + 200 + ); + game.addGlobalSkill(skill); + }, + lib.path.format(parsedPath), + fileName, + `${fileName}_skill`, + player + ); } /** - * @param { string[] } updates - * @param { Function } proceed + * @param { string[] } updates + * @param { Function } proceed */ - static checkFileList(updates, proceed) { + checkFileList(updates, proceed) { + if (!Array.isArray(updates) || !updates.length) proceed(); let n = updates.length; - if (!n) { - proceed(n); - } for (let i = 0; i < updates.length; i++) { if (lib.node && lib.node.fs) { - lib.node.fs.access(__dirname + '/' + updates[i], (function (entry) { - return function (err) { - if (!err) { - let stat = lib.node.fs.statSync(__dirname + '/' + entry); - if (stat.size == 0) { - err = true; - } - } - if (err) { - n--; - if (n == 0) { - proceed(); - } - } - else { - n--; - updates.remove(entry); - if (n == 0) { - proceed(); - } - } + lib.node.fs.access(__dirname + "/" + updates[i], (err) => { + if (!err) { + let stat = lib.node.fs.statSync(__dirname + "/" + updates[i]); + // @ts-ignore + if (stat.size == 0) err = true; } - }(updates[i]))); - } - else { - resolveLocalFileSystemURL(lib.assetURL + updates[i], (function (name) { - return function (entry) { - n--; - updates.remove(name); - if (n == 0) { - proceed(); - } - } - }(updates[i])), function () { n--; - if (n == 0) { - proceed(); - } + if (!err) updates.remove(updates[i]); + if (n == 0) proceed(); }); + } else { + window.resolveLocalFileSystemURL( + nonameInitialized + updates[i], + () => { + n--; + updates.remove(updates[i]); + if (n == 0) proceed(); + }, + () => { + n--; + if (n == 0) proceed(); + } + ); } } } /** - * @param {...(Player[] | Player)} args + * @overload + * @param {[Player[]]} args */ - static replaceHandcards(...args) { - var next = game.createEvent('replaceHandcards'); + /** + * @overload + * @param {Player[]} args + */ + replaceHandcards(...args) { + var next = game.createEvent("replaceHandcards"); if (Array.isArray(args[0])) { next.players = args[0]; - } - else { + } else { next.players = []; for (var i = 0; i < args.length; i++) { // @ts-ignore - if (get.itemtype(args[i]) == 'player') { + if (get.itemtype(args[i]) == "player") { next.players.push(args[i]); } } } if (_status.connectMode) { - next.setContent('replaceHandcardsOL'); - } - else { - next.setContent('replaceHandcards'); + next.setContent("replaceHandcardsOL"); + } else { + next.setContent("replaceHandcards"); } } /** - * @param { string } name + * @param { string } name */ - static removeCard(name) { + removeCard(name) { for (var i = 0; i < lib.card.list.length; i++) { if (lib.card.list[i][2] == name) { lib.card.list.splice(i--, 1); @@ -978,11 +1032,11 @@ export class Game extends Uninstantable { } } /** - * @param { 'hidden' } [type] + * @param { 'hidden' } [type] */ - static randomMapOL(type) { - if (type == 'hidden') { - ui.arena.classList.add('playerhidden'); + randomMapOL(type) { + if (type == "hidden") { + ui.arena.classList.add("playerhidden"); } game.prepareArena(); if (window.isNonameServer) { @@ -1015,43 +1069,48 @@ export class Game extends Uninstantable { map.push([game.players[i].playerid, game.players[i].nickname]); lib.playerOL[game.players[i].playerid] = game.players[i]; } - game.broadcast(function (map, config, hidden) { - if (hidden) { - ui.arena.classList.add('playerhidden'); - } - lib.configOL = config; - ui.create.players(); - ui.create.me(); - game.me.playerid = game.onlineID; - game.me.nickname = get.connectNickname(); - for (let i = 0; i < map.length; i++) { - if (map[i][0] == game.me.playerid) { - map = map.concat(map.splice(0, i)); - break; + game.broadcast( + function (map, config, hidden) { + if (hidden) { + ui.arena.classList.add("playerhidden"); } - } - for (let i = 0; i < game.players.length; i++) { - game.players[i].playerid = map[i][0]; - game.players[i].nickname = map[i][1]; - game.players[i].setNickname(); - lib.playerOL[game.players[i].playerid] = game.players[i]; - } - _status.mode = lib.configOL[lib.configOL.mode + '_mode']; - }, map, lib.configOL, type == 'hidden'); - _status.mode = lib.configOL[lib.configOL.mode + '_mode']; + lib.configOL = config; + ui.create.players(); + ui.create.me(); + game.me.playerid = game.onlineID; + game.me.nickname = get.connectNickname(); + for (let i = 0; i < map.length; i++) { + if (map[i][0] == game.me.playerid) { + map = map.concat(map.splice(0, i)); + break; + } + } + for (let i = 0; i < game.players.length; i++) { + game.players[i].playerid = map[i][0]; + game.players[i].nickname = map[i][1]; + game.players[i].setNickname(); + lib.playerOL[game.players[i].playerid] = game.players[i]; + } + _status.mode = lib.configOL[lib.configOL.mode + "_mode"]; + }, + map, + lib.configOL, + type == "hidden" + ); + _status.mode = lib.configOL[lib.configOL.mode + "_mode"]; game.chooseCharacterOL(); } - static closeMenu() { - if (ui.menuContainer && !ui.menuContainer.classList.contains('hidden')) { + closeMenu() { + if (ui.menuContainer && !ui.menuContainer.classList.contains("hidden")) { ui.click.configMenu(); } } - static closeConnectMenu() { - if (ui.connectMenuContainer && !ui.connectMenuContainer.classList.contains('hidden')) { + closeConnectMenu() { + if (ui.connectMenuContainer && !ui.connectMenuContainer.classList.contains("hidden")) { ui.click.connectMenu(); } } - static closePopped() { + closePopped() { if (ui.currentpopped) { if (ui.currentpopped._uiintro) { ui.currentpopped._uiintro.delete(); @@ -1074,7 +1133,7 @@ export class Game extends Uninstantable { * @param { ...T } args * @returns { void } */ - static broadcast(func, ...args) { + broadcast(func, ...args) { if (!lib.node || !lib.node.clients || game.online) return; for (var i = 0; i < lib.node.clients.length; i++) { if (lib.node.clients[i].inited) { @@ -1096,65 +1155,68 @@ export class Game extends Uninstantable { * @param { ...T } args * @returns { void } */ - static broadcastAll(func, ...args) { + broadcastAll(func, ...args) { if (game.online) return; game.broadcast.apply(this, arguments); - if (typeof func == 'string') { + if (typeof func == "string") { func = lib.message.client[func]; } - if (typeof func == 'function') { + if (typeof func == "function") { func.apply(this, args); } } - static syncState() { + syncState() { let state = null; if (game.getState) { state = game.getState(); } - game.broadcast(function (state, current, number) { - if (game.updateState && state) game.updateState(state); - _status.currentPhase = current; - game.phaseNumber = number; - }, state, _status.currentPhase, game.phaseNumber); + game.broadcast( + function (state, current, number) { + if (game.updateState && state) game.updateState(state); + _status.currentPhase = current; + game.phaseNumber = number; + }, + state, + _status.currentPhase, + game.phaseNumber + ); } - static updateWaiting() { + updateWaiting() { const map = []; for (let i = 0; i < game.connectPlayers.length; i++) { const player = game.connectPlayers[i]; if (player.playerid) { if (!game.onlinezhu) { game.onlinezhu = player.playerid; - game.send('server', 'changeAvatar', player.nickname, player.avatar); + game.send("server", "changeAvatar", player.nickname, player.avatar); _status.onlinenickname = player.nickname; _status.onlineavatar = player.avatar; } map[i] = [player.nickname, player.avatar, player.playerid]; if (player.playerid == game.onlinezhu) { - map[i].push('zhu'); + map[i].push("zhu"); } - } - else if (player.classList.contains('unselectable2')) { - map[i] = 'disabled'; - } - else { + } else if (player.classList.contains("unselectable2")) { + map[i] = "disabled"; + } else { map[i] = null; } } - game.broadcast('updateWaiting', map); + game.broadcast("updateWaiting", map); } /** - * @param { Function } func + * @param { Function } func */ - static waitForPlayer(func) { - var next = game.createEvent('waitForPlayer', false); + waitForPlayer(func) { + var next = game.createEvent("waitForPlayer", false); next.func = func; - next.setContent('waitForPlayer'); + next.setContent("waitForPlayer"); } /** - * @param { number } time - * @param { Function } [onEnd] + * @param { number } time + * @param { Function } [onEnd] */ - static countDown(time, onEnd) { + countDown(time, onEnd) { // @ts-ignore time = parseInt(time); if (!time) return; @@ -1164,8 +1226,7 @@ export class Game extends Uninstantable { _status.countDown = setInterval(function () { if (--current) { ui.timer.set(current, current / time); - } - else { + } else { ui.timer.set(0, 0); clearInterval(_status.countDown); delete _status.countDown; @@ -1173,23 +1234,26 @@ export class Game extends Uninstantable { } }, 1000); } - static countChoose(clear) { + countChoose(clear) { if (_status.imchoosing) return; _status.imchoosing = true; if (_status.connectMode && !_status.countDown) { ui.timer.show(); let num; //这么一大行都是为了祢衡 - if (_status.event && _status.event.name == 'chooseToUse' && _status.event.type == 'phase' && - _status.event.player && _status.event.player.forceCountChoose && - typeof _status.event.player.forceCountChoose.phaseUse == 'number') { + if ( + _status.event && + _status.event.name == "chooseToUse" && + _status.event.type == "phase" && + _status.event.player && + _status.event.player.forceCountChoose && + typeof _status.event.player.forceCountChoose.phaseUse == "number" + ) { num = _status.event.player.forceCountChoose.phaseUse; - } - else if (_status.connectMode) { + } else if (_status.connectMode) { num = lib.configOL.choose_timeout; - } - else { - num = get.config('choose_timeout'); + } else { + num = get.config("choose_timeout"); } game.countDown(parseInt(num), () => { ui.click.auto(); @@ -1201,49 +1265,47 @@ export class Game extends Uninstantable { game.players[i].showTimer(); } game.me._hide_all_timer = true; - } - else if (!_status.event._global_waiting) { + } else if (!_status.event._global_waiting) { game.me.showTimer(); } } - } - else if (_status.event.player.forceCountChoose && _status.event.isMine() && !_status.countDown) { + } else if (_status.event.player.forceCountChoose && _status.event.isMine() && !_status.countDown) { let info = _status.event.player.forceCountChoose; let num; - if (_status.event.name == 'chooseToUse' && _status.event.type == 'phase' && typeof info.phaseUse == 'number') { + if ( + _status.event.name == "chooseToUse" && + _status.event.type == "phase" && + typeof info.phaseUse == "number" + ) { num = info.phaseUse; - } - else if (typeof info[_status.event.name] == 'number') { - num = info[_status.event.name] - } - else if (info.default) { + } else if (typeof info[_status.event.name] == "number") { + num = info[_status.event.name]; + } else if (info.default) { num = info.default; - } - else return; + } else return; let finish = function () { if (_status.event.endButton) { if (_status.event.skill) { ui.click.cancel(); } ui.click.cancel(); - } - else { + } else { if (ui.confirm && ui.confirm.str) { - if (ui.confirm.str.includes('c')) { + if (ui.confirm.str.includes("c")) { ui.click.cancel(); - } - else if (ui.confirm.str.includes('o')) { + } else if (ui.confirm.str.includes("o")) { ui.click.ok(); } - } - else if (['chooseControl', 'chooseBool'].includes(_status.event.name) && _status.paused) { - _status.event.result = 'ai'; + } else if ( + ["chooseControl", "chooseBool"].includes(_status.event.name) && + _status.paused + ) { + _status.event.result = "ai"; game.resume(); - } - else { - ui.click.auto('forced'); + } else { + ui.click.auto("forced"); setTimeout(() => { - ui.click.auto('forced'); + ui.click.auto("forced"); }, 200); } } @@ -1253,14 +1315,13 @@ export class Game extends Uninstantable { ui.timer.hide(); game.uncheck(); setTimeout(finish, 200); - } - else { + } else { ui.timer.show(); game.countDown(num, finish); } } } - static stopCountChoose() { + stopCountChoose() { if (_status.countDown) { clearInterval(_status.countDown); delete _status.countDown; @@ -1272,27 +1333,26 @@ export class Game extends Uninstantable { for (let i = 0; i < game.players.length; i++) { game.players[i].hideTimer(); } - } - else if (!_status.event._global_waiting) { + } else if (!_status.event._global_waiting) { game.me.hideTimer(); } } } /** - * @param { string } ip - * @param { (result: boolean) => any } callback + * @param { string } ip + * @param { (result: boolean) => any } callback */ - static connect(ip, callback) { + connect(ip, callback) { if (game.online) return; let withport = false; - let index = ip.lastIndexOf(':'); + let index = ip.lastIndexOf(":"); if (index != -1) { index = parseFloat(ip.slice(index + 1)); if (index && Math.floor(index) == index) { withport = true; } } - if (!withport) ip = ip + ':8080'; + if (!withport) ip = ip + ":8080"; _status.connectCallback = callback; try { if (game.ws) { @@ -1300,13 +1360,13 @@ export class Game extends Uninstantable { game.ws.close(); delete game.ws; } - let str = ''; - if (!ip.startsWith('wss://') && !ip.startsWith('ws://')) str = (get.config('wss_mode', 'connect') ? 'wss://' : 'ws://'); - game.ws = new WebSocket(str + ip + ''); - } - // 今天狂神龙尊来了这里也没有参数 - catch { - alert('错误:无效联机地址'); + let str = ""; + if (!ip.startsWith("wss://") && !ip.startsWith("ws://")) + str = get.config("wss_mode", "connect") ? "wss://" : "ws://"; + game.ws = new WebSocket(str + ip + ""); + } catch { + // 今天狂神龙尊来了这里也没有参数 + alert("错误:无效联机地址"); if (callback) callback(false); return; } @@ -1316,24 +1376,24 @@ export class Game extends Uninstantable { game.ws.onclose = lib.element.ws.onclose; _status.ip = ip; } - static send() { - if (game.observe && arguments[0] != 'reinited') return; + send() { + if (game.observe && arguments[0] != "reinited") return; if (game.ws) { const args = Array.from(arguments); - if (typeof args[0] == 'function') { - args.unshift('exec'); + if (typeof args[0] == "function") { + args.unshift("exec"); } game.ws.send(JSON.stringify(get.stringifiedResult(args))); } } /** - * @param { string } id - * @param {*} message + * @param { string } id + * @param {*} message */ - static sendTo(id, message) { + sendTo(id, message) { return new lib.element.Client(new lib.element.NodeWS(id)).send(message); } - static createServer() { + createServer() { lib.node.clients = []; lib.node.banned = []; lib.node.observing = []; @@ -1346,45 +1406,44 @@ export class Game extends Uninstantable { ui.create.chat(); if (game.onlineroom) { void 0; - } - else { - const WebSocketServer = require('ws').Server; + } else { + const WebSocketServer = require("ws").Server; const wss = new WebSocketServer({ port: 8080 }); game.ip = get.ip(); - wss.on('connection', lib.init.connection); + wss.on("connection", lib.init.connection); } } /** * @returns { HTMLAudioElement } */ - static playAudio() { - let path = '', emptyPath = true, notCheckDBPath = true, onError = null; + playAudio() { + let path = "", + emptyPath = true, + notCheckDBPath = true, + onError = null; if (_status.video) { // 为了能更美观的写代码,默认返回audio而不额外加一个void类型 // @ts-ignore - if (arguments[1] != 'video') return; + if (arguments[1] != "video") return; path = arguments[0]; - } - else { + } else { for (const argument of arguments) { - if (typeof argument === 'string' || typeof argument == 'number') { + if (typeof argument === "string" || typeof argument == "number") { if (emptyPath) emptyPath = false; else if (notCheckDBPath) { notCheckDBPath = false; - if (/^db:extension-[^:]*$/.test(path)) path += ':'; - else path += '/'; - } - else path += '/'; + if (/^db:extension-[^:]*$/.test(path)) path += ":"; + else path += "/"; + } else path += "/"; path += argument; - } - else if (typeof argument == 'function') onError = argument; + } else if (typeof argument == "function") onError = argument; if (_status.video) break; } - if (path.startsWith('ext:')) path = path.replace(/^ext:/, 'extension/'); - else if (!path.startsWith('db:')) path = `audio/${path}`; + if (path.startsWith("ext:")) path = path.replace(/^ext:/, "extension/"); + else if (!path.startsWith("db:")) path = `audio/${path}`; if (!lib.config.repeat_audio && _status.skillaudio.includes(path)) return; } - const audio = document.createElement('audio'); + const audio = document.createElement("audio"); audio.autoplay = true; audio.volume = lib.config.volumn_audio / 8; //Some browsers do not support "autoplay", so "oncanplay" listening has been added @@ -1400,58 +1459,63 @@ export class Game extends Uninstantable { if (onError) onError(event); }; new Promise((resolve, reject) => { - if (path.startsWith('db:')) game.getDB('image', path.slice(3)).then(octetStream => resolve(get.objectURL(octetStream)), reject); + if (path.startsWith("db:")) + game.getDB("image", path.slice(3)).then( + (octetStream) => resolve(get.objectURL(octetStream)), + reject + ); else if (lib.path.extname(path)) resolve(`${lib.assetURL}${path}`); else resolve(`${lib.assetURL}${path}.mp3`); - }).then(resolvedPath => { + }).then((resolvedPath) => { audio.src = resolvedPath; ui.window.appendChild(audio); }); return audio; } /** - * 根据skill中的audio,audioname,audioname2和player来获取音频地址列表 - * @typedef {[string,number]|string|number|boolean} audioInfo - * @typedef {{audio: audioInfo, audioname?:string[], audioname2?:{[playerName: string]: audioInfo}}} skillInfo - * @param { string } skill 技能名 - * @param { Player | string } [player] 角色/角色名 - * @param { skillInfo | audioInfo } [skillInfo] 预设的skillInfo/audioInfo(转为skillInfo),覆盖lib.skill[skill] - * @returns { string[] } 语音地址列表 - * @example - * ```js - * const info=lib.skill['skillname']; - * info.audio=undefined //默认值[true,2] - * info.audio=false // 不播放语音 - * info.audio=true // [skill/skillname.mp3] - * info.audio=3 // [skill/skillname1.mp3,skill/skillname2.mp3,skill/skillname3.mp3](项数为数字大小) - * info.audio="(ext:extName|db:extension-extName)(/anyPath):true|number(:format)" //间接路径 - * // 同上,只是将目录改为(ext:extName|db:extension-extName)(/anyPath),且可以指定格式(默认mp3) - * info.audio="(ext:extName|db:extension-extName/)(anyPath/)filename(.format)" //直接路径 - * //path和format至少有一个,否则会识别为引用技能 - * //起始位置为audio/(若无anyPath则为audio/skill/),若没有format默认mp3 - * info.audio="otherSkillname" //引用技能 - * //引用一个其他技能的语音,若lib.skill["otherSkillname"]不存在则读取"otherSkillname"的audio为默认值[true,2] - * info.audio=["otherSkillname", number] //带fixedNum的引用技能 - * //同样引用一个其他技能的语音,若lib.skill["otherSkillname"]不存在则读取"otherSkillname"的audio为number - * //若"otherSkillname"的语音数超过number,则只取前number个 - * info.audio=[true,2,"otherSkillname1",["otherSkillname2",2]] //任意元素拼接 - * //数组里可以放任何以上的格式,结果为分析完的结果合并 - * - * info.audioname=['player1','player2'] - * //audioname里可以放任意角色名。 - * //如果其中包含发动技能的角色名"player",且info.audio不是直接路径"(anyPath/)filename(.format)"的形式 - * //则在"skill"和number中插入"_player",形如 - * - * info.audioname2={'player1':audioInfo1,'player2':audioInfo2} - * //audioname2是一个对象,其中key为角色名,value的类型和info.audio一样 - * //如果key中包含发动技能的角色名player,则直接改用info.audioname2[player]来播放语音 - * ``` - */ - static parseSkillAudio(skill, player, skillInfo) { - if (typeof player === 'string') player = { name: player }; - else if (typeof player !== 'object' || player === null) player = {}; + * 根据skill中的audio,audioname,audioname2和player来获取音频地址列表 + * @typedef {[string,number]|string|number|boolean} audioInfo + * @typedef {{audio: audioInfo, audioname?:string[], audioname2?:{[playerName: string]: audioInfo}}} skillInfo + * @param { string } skill 技能名 + * @param { Player | string } [player] 角色/角色名 + * @param { skillInfo | audioInfo } [skillInfo] 预设的skillInfo/audioInfo(转为skillInfo),覆盖lib.skill[skill] + * @returns { string[] } 语音地址列表 + * @example + * ```js + * const info=lib.skill['skillname']; + * info.audio=undefined //默认值[true,2] + * info.audio=false // 不播放语音 + * info.audio=true // [skill/skillname.mp3] + * info.audio=3 // [skill/skillname1.mp3,skill/skillname2.mp3,skill/skillname3.mp3](项数为数字大小) + * info.audio="(ext:extName|db:extension-extName)(/anyPath):true|number(:format)" //间接路径 + * // 同上,只是将目录改为(ext:extName|db:extension-extName)(/anyPath),且可以指定格式(默认mp3) + * info.audio="(ext:extName|db:extension-extName/)(anyPath/)filename(.format)" //直接路径 + * //path和format至少有一个,否则会识别为引用技能 + * //起始位置为audio/(若无anyPath则为audio/skill/),若没有format默认mp3 + * info.audio="otherSkillname" //引用技能 + * //引用一个其他技能的语音,若lib.skill["otherSkillname"]不存在则读取"otherSkillname"的audio为默认值[true,2] + * info.audio=["otherSkillname", number] //带fixedNum的引用技能 + * //同样引用一个其他技能的语音,若lib.skill["otherSkillname"]不存在则读取"otherSkillname"的audio为number + * //若"otherSkillname"的语音数超过number,则只取前number个 + * info.audio=[true,2,"otherSkillname1",["otherSkillname2",2]] //任意元素拼接 + * //数组里可以放任何以上的格式,结果为分析完的结果合并 + * + * info.audioname=['player1','player2'] + * //audioname里可以放任意角色名。 + * //如果其中包含发动技能的角色名"player",且info.audio不是直接路径"(anyPath/)filename(.format)"的形式 + * //则在"skill"和number中插入"_player",形如 + * + * info.audioname2={'player1':audioInfo1,'player2':audioInfo2} + * //audioname2是一个对象,其中key为角色名,value的类型和info.audio一样 + * //如果key中包含发动技能的角色名player,则直接改用info.audioname2[player]来播放语音 + * ``` + */ + parseSkillAudio(skill, player, skillInfo) { + if (typeof player === "string") player = { name: player }; + else if (typeof player !== "object" || player === null) player = {}; - if (skillInfo && (typeof skillInfo !== 'object' || Array.isArray(skillInfo))) skillInfo = { audio: skillInfo }; + if (skillInfo && (typeof skillInfo !== "object" || Array.isArray(skillInfo))) + skillInfo = { audio: skillInfo }; const checkSkill = (skill, history) => { if (!lib.skill[skill]) return false; @@ -1459,27 +1523,33 @@ export class Game extends Uninstantable { if (history[0] === skill) return false; //deadlock throw new RangeError(`parseSkillAudio: ${skill} in `, history, ` forms a deadlock`); - } + }; - const getName = filter => { - const name = (player.tempname || []).find(i => filter(i)); - return name || [player.name, player.name1, player.name2].reduce((result, name) => { - if (result) return result; - if (!name) return result; - if (filter(name)) return name; - let tempname = get.character(name, 4).find(tag => tag.startsWith('tempname:')); - if (!tempname) return result; - tempname = tempname.split(':').slice(1).find(i => filter(i)); - return tempname || result; - }, void 0); - } + const getName = (filter) => { + const name = (player.tempname || []).find((i) => filter(i)); + return ( + name || + [player.name, player.name1, player.name2].reduce((result, name) => { + if (result) return result; + if (!name) return result; + if (filter(name)) return name; + let tempname = get.character(name, 4).find((tag) => tag.startsWith("tempname:")); + if (!tempname) return result; + tempname = tempname + .split(":") + .slice(1) + .find((i) => filter(i)); + return tempname || result; + }, void 0) + ); + }; /** - * @param {string} skill - * @param {{audioname:string[],history:string[]}} options - * @param {skillInfo} [skillInfo] - * @returns {string[]} - */ + * @param {string} skill + * @param {{audioname:string[],history:string[]}} options + * @param {skillInfo} [skillInfo] + * @returns {string[]} + */ function getAudioList(skill, options, skillInfo) { const info = skillInfo || lib.skill[skill]; if (!info) { @@ -1491,53 +1561,59 @@ export class Game extends Uninstantable { history.unshift(skill); let audioInfo = info.audio; if (Array.isArray(info.audioname)) audioname.addArray(info.audioname); - if (info.audioname2) audioInfo = info.audioname2[getName(i => info.audioname2[i])] || audioInfo; - if (typeof audioInfo === 'function') audioInfo = audioInfo(player); + if (info.audioname2) audioInfo = info.audioname2[getName((i) => info.audioname2[i])] || audioInfo; + if (typeof audioInfo === "function") audioInfo = audioInfo(player); return parseAudio(skill, options, audioInfo); } /** - * @param {string} skill - * @param {{audioname:string[],history:string[]}} options - * @param {audioInfo} audioInfo info.audio - * @returns {string[]} - */ + * @param {string} skill + * @param {{audioname:string[],history:string[]}} options + * @param {audioInfo} audioInfo info.audio + * @returns {string[]} + */ function parseAudio(skill, options, audioInfo) { const audioname = options.audioname.slice(); const history = options.history.slice(); options = { audioname, history }; if (Array.isArray(audioInfo)) { - if (typeof audioInfo[0] === 'string' && typeof audioInfo[1] === 'number') {// [audioname, number] - if (checkSkill(audioInfo[0], history)) return getAudioList(audioInfo[0], options).slice(0, audioInfo[1]); + if (typeof audioInfo[0] === "string" && typeof audioInfo[1] === "number") { + // [audioname, number] + if (checkSkill(audioInfo[0], history)) + return getAudioList(audioInfo[0], options).slice(0, audioInfo[1]); return parseAudio(audioInfo[0], options, audioInfo[1]); } return audioInfo.reduce((total, i) => total.addArray(parseAudio(skill, options, i)), []); } - if (!['string', 'number', 'boolean'].includes(typeof audioInfo)) return parseAudio(skill, options, [true, 2]); + if (!["string", "number", "boolean"].includes(typeof audioInfo)) + return parseAudio(skill, options, [true, 2]); if (audioInfo === false) return []; - if (typeof audioInfo === 'string' && checkSkill(audioInfo, history)) return getAudioList(audioInfo, options); + if (typeof audioInfo === "string" && checkSkill(audioInfo, history)) + return getAudioList(audioInfo, options); audioInfo = String(audioInfo); let list = audioInfo.match(/(?:(.*):|^)(true|\d+)(?::(.*)|$)/); // [path, number|true, format] if (!list) { - let path = '', format = ''; - if (!/^db:|^ext:|\//.test(audioInfo)) path = 'skill/'; - if (!/\.\w+$/.test(audioInfo)) format = '.mp3'; + let path = "", + format = ""; + if (!/^db:|^ext:|\//.test(audioInfo)) path = "skill/"; + if (!/\.\w+$/.test(audioInfo)) format = ".mp3"; if (path && format) return parseAudio(audioInfo, options, [true, 2]); return [`${path}${audioInfo}${format}`]; } - let _audioname = getName(i => audioname.includes(i)); - _audioname = _audioname ? `_${_audioname}` : ''; + let _audioname = getName((i) => audioname.includes(i)); + _audioname = _audioname ? `_${_audioname}` : ""; - if (list[2] === 'true') return [`${list[1] || 'skill'}/${skill}${_audioname}.${list[3] || 'mp3'}`]; + if (list[2] === "true") + return [`${list[1] || "skill"}/${skill}${_audioname}.${list[3] || "mp3"}`]; const audioList = []; list[2] = parseInt(list[2]); for (let i = 1; i <= list[2]; i++) { - audioList.push(`${list[1] || 'skill'}/${skill}${_audioname}${i}.${list[3] || 'mp3'}`); + audioList.push(`${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`); } return audioList; } @@ -1545,23 +1621,25 @@ export class Game extends Uninstantable { return getAudioList(skill, { audioname: [], history: [] }, skillInfo); } /** - * - * @param { string } skill - * @param { Player | string } player - * @param { boolean } [directaudio] - * @param { boolean } [nobroadcast] - * @param { ['lib']['skill'] } [skillInfo] - * @returns + * + * @param { string } skill + * @param { Player | string } player + * @param { boolean } [directaudio] + * @param { boolean } [nobroadcast] + * @param { ['lib']['skill'] } [skillInfo] + * @returns */ - static trySkillAudio(skill, player, directaudio, nobroadcast, skillInfo) { - if (!nobroadcast) game.broadcast(game.trySkillAudio, skill, player, directaudio, nobroadcast, skillInfo); + trySkillAudio(skill, player, directaudio, nobroadcast, skillInfo) { + if (!nobroadcast) + game.broadcast(game.trySkillAudio, skill, player, directaudio, nobroadcast, skillInfo); const info = skillInfo || lib.skill[skill]; if (!info) return; if (!lib.config.background_speak) return; if (info.direct && !directaudio) return; if (lib.skill.global.includes(skill) && !info.forceaudio) return; - let audio, list = game.parseSkillAudio(skill, player, skillInfo).randomSort(); + let audio, + list = game.parseSkillAudio(skill, player, skillInfo).randomSort(); return (function play() { if (!list.length) return; audio = list.shift(); @@ -1569,47 +1647,47 @@ export class Game extends Uninstantable { })(); } /** - * @param { string } name - * @param { number } [index] - * @returns + * @param { string } name + * @param { number } [index] + * @returns */ - static playSkillAudio(name, index) { - if (_status.video && arguments[1] != 'video') return; + playSkillAudio(name, index) { + if (_status.video && arguments[1] != "video") return; if (!lib.config.repeat_audio && _status.skillaudio.includes(name)) return; - game.addVideo('playSkillAudio', null, name); - if (name.indexOf('|') < name.lastIndexOf('|')) { - name = name.slice(name.lastIndexOf('|') + 1); + game.addVideo("playSkillAudio", null, name); + if (name.indexOf("|") < name.lastIndexOf("|")) { + name = name.slice(name.lastIndexOf("|") + 1); } _status.skillaudio.add(name); setTimeout(function () { _status.skillaudio.remove(name); }, 1000); - var str = 'audio/skill/'; - var audio = document.createElement('audio'); + var str = "audio/skill/"; + var audio = document.createElement("audio"); audio.autoplay = true; audio.volume = lib.config.volumn_audio / 8; - audio.src = lib.assetURL + str + name + '.mp3'; - audio.addEventListener('ended', function () { + audio.src = lib.assetURL + str + name + ".mp3"; + audio.addEventListener("ended", function () { this.remove(); }); - if (typeof index != 'number') { + if (typeof index != "number") { index = Math.ceil(Math.random() * 2); } audio._changed = 1; audio.onerror = function () { switch (this._changed) { case 1: { - audio.src = lib.assetURL + str + name + '.ogg'; + audio.src = lib.assetURL + str + name + ".ogg"; this._changed = 2; break; } case 2: { - audio.src = lib.assetURL + str + name + index + '.mp3'; + audio.src = lib.assetURL + str + name + index + ".mp3"; this._changed = 3; break; } case 3: { - audio.src = lib.assetURL + str + name + index + '.ogg'; + audio.src = lib.assetURL + str + name + index + ".ogg"; this._changed = 4; break; } @@ -1625,141 +1703,179 @@ export class Game extends Uninstantable { ui.window.appendChild(audio); } /** - * @param { string | Card } card - * @param { Player | Sex } sex + * @param { string | Card } card + * @param { Player | Sex } sex */ - static playCardAudio(card, sex) { - if (typeof card === 'string') { + playCardAudio(card, sex) { + if (typeof card === "string") { // @ts-ignore card = { name: card }; } // @ts-ignore - if (get.itemtype(sex) === 'player') { + if (get.itemtype(sex) === "player") { // @ts-ignore - sex = (sex.sex == 'female' ? 'female' : 'male'); - } else if (typeof sex == 'string') { - sex = (sex == 'female' ? 'female' : 'male'); + 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; + if (!lib.config.background_audio || (get.type(card) == "equip" && !lib.config.equip_audio)) return; let 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}`); + if (useAudio === "default") { + game.playAudio("card", sex, `${card.name}_${nature}`); return; } else if (useAudio && useAudio[sex]) { game.playAudio(useAudio[sex]); return; } } - const audio = get.dynamicVariable(lib.card[card.name].audio,card,sex); - 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); + const audio = get.dynamicVariable(lib.card[card.name].audio, card, sex); + 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); } - static playBackgroundMusic() { - if (lib.config.background_music == 'music_off') { - ui.backgroundMusic.src = ''; + playBackgroundMusic() { + if (lib.config.background_music == "music_off") { + ui.backgroundMusic.src = ""; return; } if (_status._aozhan) { const aozhanBGMConfiguration = lib.config.mode_config.guozhan.aozhan_bgm; - if (aozhanBGMConfiguration == 'disabled') return; + if (aozhanBGMConfiguration == "disabled") return; let aozhan = _status.tempAozhan || aozhanBGMConfiguration; - if (Array.isArray(aozhan)) aozhan = aozhan.randomGet('disabled', _status.currentAozhan) || aozhanBGMConfiguration; - if (aozhan == 'random') aozhan = Object.keys(lib.mode.guozhan.config.aozhan_bgm.item).randomGet('disabled', 'random', _status.currentAozhan); + if (Array.isArray(aozhan)) + aozhan = aozhan.randomGet("disabled", _status.currentAozhan) || aozhanBGMConfiguration; + if (aozhan == "random") + aozhan = Object.keys(lib.mode.guozhan.config.aozhan_bgm.item).randomGet( + "disabled", + "random", + _status.currentAozhan + ); _status.currentAozhan = aozhan; - if (aozhan.startsWith('db:')) game.getDB('image', aozhan.slice(3)).then(result => ui.backgroundMusic.src = result); - else if (aozhan.startsWith('ext:')) ui.backgroundMusic.src = `${lib.assetURL}extension/${aozhan.slice(4)}`; + if (aozhan.startsWith("db:")) + game.getDB("image", aozhan.slice(3)).then((result) => (ui.backgroundMusic.src = result)); + else if (aozhan.startsWith("ext:")) + ui.backgroundMusic.src = `${lib.assetURL}extension/${aozhan.slice(4)}`; else ui.backgroundMusic.src = `${lib.assetURL}audio/background/aozhan_${aozhan}.mp3`; return; } let music = _status.tempMusic || lib.config.background_music; - if (Array.isArray(music)) music = music.randomGet('music_off', _status.currentMusic) || lib.config.background_music; - if (music == 'music_random') music = lib.config.all.background_music.randomGet('music_off', 'music_random', _status.currentMusic); + if (Array.isArray(music)) + music = music.randomGet("music_off", _status.currentMusic) || lib.config.background_music; + if (music == "music_random") + music = lib.config.all.background_music.randomGet( + "music_off", + "music_random", + _status.currentMusic + ); _status.currentMusic = music; - if (music == 'music_custom') { + if (music == "music_custom") { const backgroundMusicSourceConfiguration = lib.config.background_music_src; - if (backgroundMusicSourceConfiguration) ui.backgroundMusic.src = backgroundMusicSourceConfiguration; + if (backgroundMusicSourceConfiguration) + ui.backgroundMusic.src = backgroundMusicSourceConfiguration; return; } - if (music.startsWith('db:')) game.getDB('image', music.slice(3)).then(result => ui.backgroundMusic.src = result); - else if (music.startsWith('ext:')) ui.backgroundMusic.src = `${lib.assetURL}extension/${music.slice(4)}`; + if (music.startsWith("db:")) + game.getDB("image", music.slice(3)).then((result) => (ui.backgroundMusic.src = result)); + else if (music.startsWith("ext:")) + ui.backgroundMusic.src = `${lib.assetURL}extension/${music.slice(4)}`; else ui.backgroundMusic.src = `${lib.assetURL}audio/background/${music}.mp3`; } // 某种意义上,改不了,得重写 // 等正式用import导入再说 /** * @overload - * @param { 'character' } type + * @param { 'character' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status - * ) => importCharacterConfig } content - * @param {*} [url] + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importCharacterConfig } content + * @param {*} [url] */ /** * @overload - * @param { 'card' } type + * @param { 'card' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status - * ) => importCardConfig } content - * @param {*} [url] + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importCardConfig } content + * @param {*} [url] */ /** * @overload - * @param { 'mode' } type + * @param { 'mode' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status - * ) => importModeConfig } content - * @param {*} [url] + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importModeConfig } content + * @param {*} [url] */ /** * @overload - * @param { 'player' } type + * @param { 'player' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status - * ) => importPlayerConfig } content - * @param {*} [url] + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importPlayerConfig } content + * @param {*} [url] */ /** * @overload - * @param { 'extension' } type + * @param { 'extension' } type * @param {( - * lib: Library, - * game: typeof Game, - * ui: UI, - * get: Get, - * ai: AI, - * _status: Status - * ) => importExtensionConfig } content - * @param {*} [url] + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importExtensionConfig } content + * @param {*} [url] */ - static import(type, content, url) { - if (type == 'extension') { + /** + * @overload + * @param { 'play' } type + * @param {( + * lib: InstanceType, + * game: InstanceType, + * ui: InstanceType, + * get: InstanceType, + * ai: InstanceType, + * _status: InstanceType + * ) => importPlayConfig } content + * @param {*} [url] + */ + import(type, content, url) { + if (type == "extension") { const promise = game.loadExtension(content).then((name) => { if (typeof _status.extensionLoaded == "undefined") _status.extensionLoaded = []; _status.extensionLoaded.add(name); @@ -1768,10 +1884,11 @@ export class Game extends Uninstantable { if (typeof _status.extensionLoading == "undefined") _status.extensionLoading = []; _status.extensionLoading.add(promise); return promise; - } - else { + } else { if (!lib.imported[type]) lib.imported[type] = {}; - const promise = Promise.resolve((gnc.is.generator(content) ? gnc.of(content) : content)(lib, game, ui, get, ai, _status)).then(content2 => { + const promise = Promise.resolve( + (gnc.is.generator(content) ? gnc.of(content) : content)(lib, game, ui, get, ai, _status) + ).then((content2) => { if (content2.name) { lib.imported[type][content2.name] = content2; delete content2.name; @@ -1783,81 +1900,116 @@ export class Game extends Uninstantable { return promise; } } - static async loadExtension(object) { + async loadExtension(object) { let noEval = false; - if (typeof object == 'function') { - object = await (gnc.is.generatorFunc(object) ? gnc.of(object) : object)(lib, game, ui, get, ai, _status); + if (typeof object == "function") { + object = await (gnc.is.generatorFunc(object) ? gnc.of(object) : object)( + lib, + game, + ui, + get, + ai, + _status + ); noEval = true; } - if(object.closeSyntaxCheck){ + if (object.closeSyntaxCheck) { noEval = true; } - const name = object.name, extensionName = `extension_${name}`, extensionMenu = lib.extensionMenu[extensionName] = { - enable: { - name: '开启', - init: true - } - }, objectPackage = object.package; - if (objectPackage) { - const author = Object.getOwnPropertyDescriptor(objectPackage, 'author'); - if (author) Object.defineProperty(extensionMenu.author = { - get name() { - return `作者:${this.author}`; + const name = object.name, + extensionName = `extension_${name}`, + extensionMenu = (lib.extensionMenu[extensionName] = { + enable: { + name: "开启", + init: true, }, - clear: true, - nopointer: true, - }, 'author', author); - const intro = Object.getOwnPropertyDescriptor(objectPackage, 'intro'); - if (intro) Object.defineProperty(extensionMenu.intro = { - clear: true, - nopointer: true, - }, 'name', intro); + }), + objectPackage = object.package; + if (objectPackage) { + const author = Object.getOwnPropertyDescriptor(objectPackage, "author"); + if (author) + Object.defineProperty( + (extensionMenu.author = { + get name() { + return `作者:${this.author}`; + }, + clear: true, + nopointer: true, + }), + "author", + author + ); + const intro = Object.getOwnPropertyDescriptor(objectPackage, "intro"); + if (intro) + Object.defineProperty( + (extensionMenu.intro = { + clear: true, + nopointer: true, + }), + "name", + intro + ); } const objectConfig = object.config; - if (objectConfig) Object.defineProperties(extensionMenu, Object.keys(objectConfig).reduce((propertyDescriptorMap, key) => { - propertyDescriptorMap[key] = Object.getOwnPropertyDescriptor(objectConfig, key); - return propertyDescriptorMap; - }, {})); + if (objectConfig) + Object.defineProperties( + extensionMenu, + Object.keys(objectConfig).reduce((propertyDescriptorMap, key) => { + propertyDescriptorMap[key] = Object.getOwnPropertyDescriptor(objectConfig, key); + return propertyDescriptorMap; + }, {}) + ); const help = object.help; - if (help) Object.defineProperties(lib.help, Object.keys(help).reduce((propertyDescriptorMap, key) => { - propertyDescriptorMap[key] = Object.getOwnPropertyDescriptor(help, key); - return propertyDescriptorMap; - }, {})); - if (object.editable !== false && lib.config.show_extensionmaker) extensionMenu.edit = { - name: '编辑此扩展', - clear: true, - onclick: () => { - if (game.editExtension && lib.extensionPack && lib.extensionPack[name]) game.editExtension(name); - else alert('无法编辑未启用的扩展,请启用此扩展并重启后重试'); - } - }; + if (help) + Object.defineProperties( + lib.help, + Object.keys(help).reduce((propertyDescriptorMap, key) => { + propertyDescriptorMap[key] = Object.getOwnPropertyDescriptor(help, key); + return propertyDescriptorMap; + }, {}) + ); + if (object.editable !== false && lib.config.show_extensionmaker) + extensionMenu.edit = { + name: "编辑此扩展", + clear: true, + onclick: () => { + if (game.editExtension && lib.extensionPack && lib.extensionPack[name]) + game.editExtension(name); + else alert("无法编辑未启用的扩展,请启用此扩展并重启后重试"); + }, + }; extensionMenu.delete = { - name: '删除此扩展', + name: "删除此扩展", clear: true, onclick: function () { - if (this.innerHTML != '确认删除') { - this.innerHTML = '确认删除'; - new Promise(resolve => setTimeout(resolve, 1000)).then(() => this.innerHTML = '删除此扩展'); + if (this.innerHTML != "确认删除") { + this.innerHTML = "确认删除"; + new Promise((resolve) => setTimeout(resolve, 1000)).then( + () => (this.innerHTML = "删除此扩展") + ); return; } - const page = this.parentNode, start = page.parentNode.previousSibling; + const page = this.parentNode, + start = page.parentNode.previousSibling; page.remove(); if (start) { - const pageInStart = Array.from(start.childNodes).find(childNode => childNode.link == page); + const pageInStart = Array.from(start.childNodes).find( + (childNode) => childNode.link == page + ); if (pageInStart) { let active = false; - if (pageInStart.classList.contains('active')) active = true; + if (pageInStart.classList.contains("active")) active = true; pageInStart.remove(); if (active) { - start.firstChild.classList.add('active'); + start.firstChild.classList.add("active"); start.nextSibling.appendChild(start.firstChild.link); } } } game.removeExtension(name); - if (typeof object.onremove == 'function') object.onremove(); - } - } + if (typeof object.onremove == "function") object.onremove(); + }, + }; if (_status.importingExtension) { game.importedPack = object; @@ -1867,7 +2019,8 @@ export class Game extends Uninstantable { if (!object || !libConfig[`${extensionName}_enable`]) return; if (!noEval) lib.init.eval(object); const config = Object.keys(libConfig).reduce((constructingConfig, key) => { - if (key != extensionName && key.startsWith(extensionName)) constructingConfig[key.slice(11 + name.length)] = libConfig[key]; + if (key != extensionName && key.startsWith(extensionName)) + constructingConfig[key.slice(11 + name.length)] = libConfig[key]; return constructingConfig; }, {}); try { @@ -1879,30 +2032,44 @@ export class Game extends Uninstantable { if (!extensionPackFiles.character) extensionPackFiles.character = []; if (!extensionPackFiles.card) extensionPackFiles.card = []; if (!extensionPackFiles.skill) extensionPackFiles.skill = []; - } - else extensionPack = lib.extensionPack[name] = {}; - const content = object.content, precontent = object.precontent; + } else extensionPack = lib.extensionPack[name] = {}; + const content = object.content, + precontent = object.precontent; extensionPack.code = { content: content, precontent: precontent, help: help, - config: objectConfig - } - try{ + config: objectConfig, + }; + try { if (precontent) { _status.extension = name; - - await (gnc.is.generatorFunc(precontent) ? gnc.of(precontent) : precontent).call(object, config); + + await (gnc.is.generatorFunc(precontent) ? gnc.of(precontent) : precontent).call( + object, + config + ); delete _status.extension; } - }catch(e1){ - console.log(`加载《${name}》扩展的precontent时出现错误。`,e1); - if(!lib.config.extension_alert) alert(`加载《${name}》扩展的precontent时出现错误。\n该错误本身可能并不影响扩展运行。您可以在“设置→通用→无视扩展报错”中关闭此弹窗。\n${decodeURI(e1.stack)}`); + } catch (e1) { + console.log(`加载《${name}》扩展的precontent时出现错误。`, e1); + if (!lib.config.extension_alert) + alert( + `加载《${name}》扩展的precontent时出现错误。\n该错误本身可能并不影响扩展运行。您可以在“设置→通用→无视扩展报错”中关闭此弹窗。\n${decodeURI( + e1.stack + )}` + ); } - - if (content) lib.extensions.push([name, content, config, _status.evaluatingExtension, objectPackage || {}]); - } - catch (e) { + + if (content) + lib.extensions.push([ + name, + content, + config, + _status.evaluatingExtension, + objectPackage || {}, + ]); + } catch (e) { console.log(e); } @@ -1910,140 +2077,247 @@ export class Game extends Uninstantable { } /** * 下载文件 - * @type { undefined | ((url: string, folder: string, onsuccess?: Function, onerror?: (e: Error) => void) => void, dev?: 'nodev', onprogress?: Function) => void) } + * @type { undefined | ((url: string, folder: string, onsuccess?: Function, onerror?: (e: Error) => void, dev?: 'nodev', onprogress?: Function) => void) } */ - static download; + download; /** * 读取文件为arraybuffer * @type { undefined | ((filename: string, callback?: (data: Buffer | ArrayBuffer) => any, onerror?: (e: Error) => void) => void) } */ - static readFile; + readFile; /** * 读取文件为文本 * @type { undefined | ((filename: string, callback?: (data: string) => any, onerror?: (e: Error) => void) => void) } */ - static readFileAsText; + readFileAsText; /** * 将数据写入文件 * @type { undefined | ((data: File | ArrayBuffer, path: string, name: string, callback?: (e: Error) => void) => void) } */ - static writeFile; + writeFile; /** * 移除文件 * @type { undefined | ((filename: string, callback?: (e: Error) => void) => void) } */ - static removeFile; + removeFile; /** * 获取文件列表 - * @type { undefined | ((dir: string, success: (folders: string[], files: string[]) => any, failure: (e: Error) => void) => void) } + * @type { undefined | ((dir: string, success: (folders: string[], files: string[]) => any, failure?: (e: Error) => void) => void) } */ - static getFileList; + getFileList; /** * 按路径依次创建文件夹 * @type { undefined | ((list: string | string[], callback: Function, file?: boolean) => void) } */ - static ensureDirectory; + ensureDirectory; /** * 创建文件夹 * @type { undefined | ((directory: string, successCallback?: Function, errorCallback?: Function) => void) } */ - static createDir; + createDir; /** * 删除文件夹 * @type { undefined | ((directory: string, successCallback?: Function, errorCallback?: Function) => void) } */ - static removeDir; + removeDir; /** - * @type { (forcecheck?: boolean | null, dev?: boolean) => Promise } + * @type { (forcecheck?: boolean | null, dev?: boolean) => Promise } */ - static checkForUpdate; + checkForUpdate; /** - * @type { () => Promise } + * @type { () => Promise } */ - static checkForAssetUpdate; - static async importExtension(data, finishLoad, exportExtension, extensionPackage) { + checkForAssetUpdate; + async importExtension(data, finishLoad, exportExtension, extensionPackage) { //by 来瓶可乐加冰、Rintim、Tipx-L、诗笺 const zip = await get.promises.zip(); - if (get.objtype(data) == 'object') { + if (get.objtype(data) == "object") { //导出 - const _filelist = data._filelist, filelist2 = _filelist || []; + const _filelist = data._filelist, + filelist2 = _filelist || []; if (_filelist) delete data._filelist; const filelist = Object.keys(data); - filelist.forEach(value => zip.file(value, data[value])); + filelist.forEach((value) => zip.file(value, data[value])); game.print(filelist); game.print(filelist2); const generate = zip.generate({ - type: 'arraybuffer' + type: "arraybuffer", }); if (!exportExtension) { game.importExtension.apply(this, [generate, finishLoad]); return; } if (extensionPackage) { - extensionPackage.files = filelist.concat(filelist2).filter(value => value != 'extension.js'); + extensionPackage.files = filelist + .concat(filelist2) + .filter((value) => value != "extension.js"); const size = generate.byteLength; if (size < 1000) extensionPackage.size = `${size}B`; else if (size < 1000000) extensionPackage.size = `${Math.round(size / 1000)}KB`; else extensionPackage.size = `${Math.round(size / 100000) / 10}MB`; - zip.file('package.js', Object.keys(extensionPackage).reduce((constructingData, key, currentIndex, keys) => `${constructingData}\t${key}:${JSON.stringify(extensionPackage[key])}${currentIndex < keys.length - 1 ? ',\n' : '\n};'}`, `extension["${exportExtension}"]={\n`)); + zip.file( + "package.js", + Object.keys(extensionPackage).reduce( + (constructingData, key, currentIndex, keys) => + `${constructingData}\t${key}:${JSON.stringify(extensionPackage[key])}${ + currentIndex < keys.length - 1 ? ",\n" : "\n};" + }`, + `extension["${exportExtension}"]={\n` + ) + ); } const blob = zip.generate({ - type: 'blob' - }), fileNameToSaveAs = `${exportExtension.replace(/\\|\/|:|\?|"|\*|<|>|\|/g, '-')}.zip`; + type: "blob", + }), + fileNameToSaveAs = `${exportExtension.replace(/\\|\/|:|\?|"|\*|<|>|\|/g, "-")}.zip`; if (lib.device) { - const directory = lib.device == 'android' ? cordova.file.externalDataDirectory : cordova.file.documentsDirectory; - new Promise((resolve, reject) => window.resolveLocalFileSystemURL(directory, resolve, reject)).then(directoryEntry => new Promise((resolve, reject) => directoryEntry.getFile(fileNameToSaveAs, { - create: true - }, resolve, reject))).then(fileEntry => new Promise((resolve, reject) => fileEntry.createWriter(resolve, reject))).then(fileWriter => new Promise((resolve, reject) => { - fileWriter.onerror = reject; - fileWriter.onwriteend = resolve; - fileWriter.write(blob); - })).then(() => alert(`文件已导出至${directory}${fileNameToSaveAs}`)); - } - else { - const downloadLink = document.createElement('a'); + const directory = + lib.device == "android" + ? cordova.file.externalDataDirectory + : cordova.file.documentsDirectory; + new Promise((resolve, reject) => window.resolveLocalFileSystemURL(directory, resolve, reject)) + .then( + (directoryEntry) => + new Promise((resolve, reject) => + directoryEntry.getFile( + fileNameToSaveAs, + { + create: true, + }, + resolve, + reject + ) + ) + ) + .then( + (fileEntry) => + new Promise((resolve, reject) => fileEntry.createWriter(resolve, reject)) + ) + .then( + (fileWriter) => + new Promise((resolve, reject) => { + fileWriter.onerror = reject; + fileWriter.onwriteend = resolve; + fileWriter.write(blob); + }) + ) + .then(() => alert(`文件已导出至${directory}${fileNameToSaveAs}`)); + } else { + const downloadLink = document.createElement("a"); downloadLink.download = fileNameToSaveAs; - downloadLink.innerHTML = 'Download File'; + downloadLink.innerHTML = "Download File"; downloadLink.href = window.URL.createObjectURL(blob); downloadLink.click(); } - if (typeof finishLoad == 'function') finishLoad(); + if (typeof finishLoad == "function") finishLoad(); return; } //导入 - const UHP = error => alert(`导入失败:\n${JSON.stringify(error, null, '\t')}`); + const UHP = (error) => { + if (!(error instanceof Error)) error = new Error(error); + for (const [key, value] of Object.entries(Object.getOwnPropertyDescriptors(error))) { + if (value.configurable === true) { + Reflect.defineProperty( + error, + key, + Object.assign(value, { + enumerable: true, + }) + ); + } + } + alert(`导入失败:\n${JSON.stringify(error, null, "\t")}`); + console.error(error); + }; try { zip.load(data); - // alert(zip.file('文件夹/加扩展.js').asText()) - const str = zip.file('extension.js').asText(); - if (str === "" || undefined) throw ('你导入的不是扩展!请选择正确的文件'); + let extensionFile = zip.file("extension.js"); + let isTsFile = false; + // 未找到extension.js + if (!extensionFile) { + extensionFile = zip.file("extension.ts"); + if (!extensionFile) throw new Error("未找到extension.js"); + isTsFile = true; + } + /** @type { string } */ + // @ts-ignore + let str = extensionFile.asText(); + if (str === "" || str === undefined) throw "你导入的不是扩展!请选择正确的文件"; + // 编译ts扩展 + if (isTsFile) { + if (typeof globalThis.ts === 'undefined') { + await lib.init.promises.js('game', 'typescript'); + } + /** + * @type {typeof import('typescript')} + */ + const ts = globalThis.ts; + str = ts.transpile(str, { + module: ts.ModuleKind.ES2015, + //@todo: ES2019 -> ES2020 + target: ts.ScriptTarget.ES2019, + inlineSourceMap: true, + resolveJsonModule: true, + esModuleInterop: true, + }, 'extension.ts'); + } _status.importingExtension = true; - eval(str); - await Promise.allSettled(_status.extensionLoading); - delete _status.extensionLoading; + try { + // 导入普通扩展 + eval(str); + // esm扩展可以不写game.impoprt或许会导致_status.extensionLoading不存在 + if (Array.isArray(_status.extensionLoading)) { + await Promise.allSettled(_status.extensionLoading); + delete _status.extensionLoading; + } + } catch (error) { + // 是模块扩展 + if ( + // @ts-ignore + error.message === 'Cannot use import statement outside a module' || + // @ts-ignore + error.message === 'await is only valid in async functions and the top level bodies of modules' + ) { + // 改为用info.json判断扩展名 + const infoFile = zip.file("info.json"); + if (!infoFile) throw new Error("未找到info.json,导入模块化扩展必须加入info.json!"); + const info = JSON.parse(infoFile.asText()); + if (typeof info.name == 'string') { + await game.import('extension', () => { + return Object.assign(info, { + config: {}, + }); + }); + } + } + } _status.importingExtension = false; - if (!game.importedPack) throw ('err'); + if (!game.importedPack) throw "此压缩包不是一个扩展"; const extensionName = game.importedPack.name; - if (lib.config.all.plays.includes(extensionName)) throw ('禁止安装游戏原生扩展'); + if (lib.config.all.plays.includes(extensionName)) throw "禁止安装游戏原生扩展"; const extensions = lib.config.extensions; if (extensions.includes(extensionName)) game.removeExtension(extensionName, true); extensions.add(extensionName); - game.saveConfigValue('extensions'); + game.saveConfigValue("extensions"); game.saveConfig(`extension_${extensionName}_enable`, true); const config = game.importedPack.config; - Object.keys(config).forEach(value => { + Object.keys(config).forEach((value) => { const configObject = config[value]; - if (configObject && 'init' in configObject) game.saveConfig(`extension_${extensionName}_${value}`, configObject.init); + if (configObject && "init" in configObject) + game.saveConfig(`extension_${extensionName}_${value}`, configObject.init); }); if (game.download) { - const files = zip.files, hiddenFileFlags = ['.', '_'], fileList = Object.keys(files).filter(key => !files[key].dir && !hiddenFileFlags.includes(key[0])).reverse(); - //alert(filelist) + const files = zip.files, + hiddenFileFlags = [".", "_"], + fileList = Object.keys(files) + .filter((key) => !files[key].dir && !hiddenFileFlags.includes(key[0])) + .reverse(); //电脑端 //具备nodeJS环境 if (lib.node && lib.node.fs) { - const writeFile = errnoException => { + const writeFile = (errnoException) => { if (errnoException) { finishLoad(); UHP(errnoException); @@ -2052,44 +2326,105 @@ export class Game extends Uninstantable { if (fileList.length) { //filename 数组 ...dir+/+file //这里需要个创文件夹的函数 - const zipDir = fileList.pop(), fileName = zipDir.split('/'), name = fileName.pop(), letGo = name => new Promise(resolve => lib.node.fs.writeFile(`${__dirname}/extension/${extensionName}/${name}`, zip.file(zipDir).asNodeBuffer(), null, resolve)).then(writeFile); - return (fileName.length ? game.createDir(`extension/${extensionName}/${fileName.join("/")}`).then(() => letGo(`${fileName.join('/')}/${name}`)) : letGo(name)); + const zipDir = fileList.pop(), + fileName = zipDir.split("/"), + name = fileName.pop(), + letGo = (name) => + new Promise((resolve) => + lib.node.fs.writeFile( + `${__dirname}/extension/${extensionName}/${name}`, + zip.file(zipDir).asNodeBuffer(), + null, + resolve + ) + ).then(writeFile); + return fileName.length + ? game.promises + .createDir(`extension/${extensionName}/${fileName.join("/")}`) + .then(() => letGo(`${fileName.join("/")}/${name}`)) + : letGo(name); } finishLoad(); - } - game.ensureDirectory(`extension/${extensionName}`).then(writeFile).catch(UHP); - } - else new Promise((resolve, reject) => window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject)).then(directoryEntry => new Promise((resolve, reject) => directoryEntry.getDirectory(`extension/${extensionName}`, { - create: true - }, resolve, reject))).then(directoryEntry => { - //扩展文件夹 - const writeFile = () => { - if (!fileList.length) { - finishLoad(); - return; - } - //filename 数组 ...dir+/+file - const zipDirectory = fileList.shift(), fileName = zipDirectory.split("/"), name = fileName.pop(), letGo = name => new Promise((resolve, reject) => directoryEntry.getFile(name, { - create: true - }, resolve, reject)).then(fileEntry => new Promise((resolve, reject) => fileEntry.createWriter(resolve, reject))).then(fileWriter => new Promise((resolve, reject) => { - fileWriter.onerror = reject; - fileWriter.onwriteend = resolve; - fileWriter.write(zip.file(zipDirectory).asArrayBuffer()); - })).then(writeFile); - return (fileName.length ? game.createDir(`extension/${extensionName}/${fileName.join('/')}`).then(() => letGo(`${fileName.join('/')}/${name}`)) : letGo(name)); }; - return writeFile(); - }).catch(UHP); - } - else { + game.promises.ensureDirectory(`extension/${extensionName}`).then(writeFile).catch(UHP); + } else + new Promise((resolve, reject) => + window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject) + ) + .then( + (directoryEntry) => + new Promise((resolve, reject) => + directoryEntry.getDirectory( + `extension/${extensionName}`, + { + create: true, + }, + resolve, + reject + ) + ) + ) + .then((directoryEntry) => { + //扩展文件夹 + const writeFile = () => { + if (!fileList.length) { + finishLoad(); + return; + } + //filename 数组 ...dir+/+file + const zipDirectory = fileList.shift(), + fileName = zipDirectory.split("/"), + name = fileName.pop(), + letGo = (name) => + new Promise((resolve, reject) => + directoryEntry.getFile( + name, + { + create: true, + }, + resolve, + reject + ) + ) + .then( + (fileEntry) => + new Promise((resolve, reject) => + fileEntry.createWriter(resolve, reject) + ) + ) + .then( + (fileWriter) => + new Promise((resolve, reject) => { + fileWriter.onerror = reject; + fileWriter.onwriteend = resolve; + fileWriter.write( + zip.file(zipDirectory).asArrayBuffer() + ); + }) + ) + .then(writeFile); + return fileName.length + ? game.promises + .createDir(`extension/${extensionName}/${fileName.join("/")}`) + .then(() => letGo(`${fileName.join("/")}/${name}`)) + : letGo(name); + }; + return writeFile(); + }) + .catch(UHP); + } else { localStorage.setItem(`${lib.configprefix}extension_${extensionName}`, str); - const hiddenFileFlags = ['.', '_'], fileList = Object.keys(zip.files).filter(filePath => !hiddenFileFlags.includes(filePath[0]) && filePath[filePath.length - 1] != '/'); + const hiddenFileFlags = [".", "_"], + fileList = Object.keys(zip.files).filter( + (filePath) => + !hiddenFileFlags.includes(filePath[0]) && filePath[filePath.length - 1] != "/" + ); if (fileList.length && lib.db) { lib.config.extensionInfo[extensionName] = { - file: fileList + file: fileList, }; - game.saveConfigValue('extensionInfo'); - fileList.forEach(filePath => { + game.saveConfigValue("extensionInfo"); + fileList.forEach((filePath) => { const arrayBuffer = zip.file(filePath).asArrayBuffer(); if (!arrayBuffer) return; const blob = new Blob([arrayBuffer]); @@ -2097,48 +2432,51 @@ export class Game extends Uninstantable { const fileReader = new FileReader(); fileReader.onerror = reject; fileReader.onload = resolve; - fileReader.readAsDataURL(blob, 'UTF-8'); - }).then(fileLoadedEvent => game.putDB('image', `extension-${extensionName}:${filePath}`, fileLoadedEvent.target.result)); + fileReader.readAsDataURL(blob, "UTF-8"); + }).then((fileLoadedEvent) => + game.putDB( + "image", + `extension-${extensionName}:${filePath}`, + fileLoadedEvent.target.result + ) + ); }); } finishLoad(); } delete game.importedPack; - } - catch (error) { + } catch (error) { UHP(error); return false; } } /** - * @param { string } textToWrite - * @param { string } [name] + * @param { string } textToWrite + * @param { string } [name] */ - static export(textToWrite, name) { - let textFileAsBlob = new Blob([textToWrite], { type: 'text/plain' }); - let fileNameToSaveAs = name || 'noname'; - fileNameToSaveAs = fileNameToSaveAs.replace(/\\|\/|:|\?|"|\*|<|>|\|/g, '.'); + export(textToWrite, name) { + let textFileAsBlob = new Blob([textToWrite], { type: "text/plain" }); + let fileNameToSaveAs = name || "noname"; + fileNameToSaveAs = fileNameToSaveAs.replace(/\\|\/|:|\?|"|\*|<|>|\|/g, "."); if (lib.device) { let directory; - if (lib.device == 'android') { + if (lib.device == "android") { directory = cordova.file.externalDataDirectory; - } - else { + } else { directory = cordova.file.documentsDirectory; } window.resolveLocalFileSystemURL(directory, function (entry) { entry.getFile(fileNameToSaveAs, { create: true }, function (fileEntry) { fileEntry.createWriter(function (fileWriter) { fileWriter.onwriteend = function () { - alert('文件已导出至' + directory + fileNameToSaveAs); - } - fileWriter.write(textFileAsBlob) + alert("文件已导出至" + directory + fileNameToSaveAs); + }; + fileWriter.write(textFileAsBlob); }); }); }); - } - else { + } else { let downloadLink = document.createElement("a"); downloadLink.download = fileNameToSaveAs; downloadLink.innerHTML = "Download File"; @@ -2147,63 +2485,64 @@ export class Game extends Uninstantable { } } /** - * @param { string[] } list - * @param { Function } [onsuccess] - * @param { Function } [onerror] - * @param { Function } [onfinish] - * @param { Function } [process] - * @param {*} [dev] + * @param { string[] } list + * @param { Function } [onsuccess] + * @param { Function } [onerror] + * @param { Function } [onfinish] + * @param { Function } [process] + * @param {*} [dev] */ - static multiDownload2(list, onsuccess, onerror, onfinish, process, dev) { + multiDownload2(list, onsuccess, onerror, onfinish, process, dev) { list = list.slice(0); let download = function () { if (list.length) { let current = list.shift(); let current2; - if (typeof process == 'function') { + if (typeof process == "function") { current2 = process(current); - } - else { + } else { current2 = current; } - if (current.startsWith('theme')) { + if (current.startsWith("theme")) { game.print(current.slice(6)); - } - else if (current.startsWith('image/skin')) { + } else if (current.startsWith("image/skin")) { game.print(current.slice(11)); + } else { + game.print(current.slice(current.lastIndexOf("/") + 1)); } - else { - game.print(current.slice(current.lastIndexOf('/') + 1)); - } - game.download(current, current2, function () { - if (onsuccess) onsuccess(list.length); - download(); - }, function () { - if (onerror) onerror(list.length); - download(); - }, dev); - } - else { + game.download( + current, + current2, + function () { + if (onsuccess) onsuccess(list.length); + download(); + }, + function () { + if (onerror) onerror(list.length); + download(); + }, + dev + ); + } else { if (onfinish) onfinish(); } - } + }; download(); } /** - * @param { string[] } list - * @param { Function } onsuccess - * @param { Function } onerror + * @param { string[] } list + * @param { Function } onsuccess + * @param { Function } onerror * @param { Function } onfinish - * @param { Function } [process] - * @param {*} [dev] + * @param { Function } [process] + * @param {*} [dev] */ - static multiDownload(list, onsuccess, onerror, onfinish, process, dev) { + multiDownload(list, onsuccess, onerror, onfinish, process, dev) { if (lib.config.dev) game.print(get.url()); const args = Array.from(arguments); if (list.length <= 3) { game.multiDownload2.apply(this, args); - } - else { + } else { let num = Math.round(list.length / 3); let left = 3; args[3] = function () { @@ -2213,56 +2552,70 @@ export class Game extends Uninstantable { } }; setTimeout(function () { - args[0] = list.slice(0, num); game.multiDownload2.apply(game, args); + args[0] = list.slice(0, num); + game.multiDownload2.apply(game, args); }); setTimeout(function () { - args[0] = list.slice(num, 2 * num); game.multiDownload2.apply(this, args); + args[0] = list.slice(num, 2 * num); + game.multiDownload2.apply(this, args); }, 200); setTimeout(function () { - args[0] = list.slice(2 * num); game.multiDownload2.apply(this, args); + args[0] = list.slice(2 * num); + game.multiDownload2.apply(this, args); }, 400); } } /** - * @param { string } url - * @param { Function } onload - * @param { Function } [onerror] - * @param { Function } [onprogress] + * @param { string } url + * @param { Function } onload + * @param { Function } [onerror] + * @param { Function } [onprogress] */ - static fetch(url, onload, onerror, onprogress) { - var tmpName = '~tmp' + get.id(); - game.download(encodeURI(url), tmpName, function () { - game.readFile(tmpName, function (data) { - onload(data); - game.removeFile(tmpName); - }, onerror); - }, onerror, null, onprogress); + fetch(url, onload, onerror, onprogress) { + var tmpName = "~tmp" + get.id(); + game.download( + encodeURI(url), + tmpName, + function () { + game.readFile( + tmpName, + function (data) { + onload(data); + game.removeFile(tmpName); + }, + onerror + ); + }, + onerror, + null, + onprogress + ); } /** - * @param { string } time - * @param { string } mode + * @param { string } time + * @param { string } mode */ - static playVideo(time, mode) { + playVideo(time, mode) { if (!_status.replayvideo) { - localStorage.setItem(lib.configprefix + 'playbackmode', lib.config.mode); + localStorage.setItem(lib.configprefix + "playbackmode", lib.config.mode); } - game.saveConfig('mode', mode); - localStorage.setItem(lib.configprefix + 'playback', time); + game.saveConfig("mode", mode); + localStorage.setItem(lib.configprefix + "playback", time); game.reload(); } /** - * @param { Videos } video + * @param { Videos } video */ - static playVideoContent(video) { - const next = game.createEvent('video', false); + playVideoContent(video) { + const next = game.createEvent("video", false); next.video = video; - ui.system.style.display = 'none'; + ui.system.style.display = "none"; ui.system.hide(); - ui.arena.style.display = 'none'; + ui.arena.style.display = "none"; ui.arena.hide(); - ui.window.classList.remove('leftbar'); - ui.window.classList.remove('rightbar'); - ui.historybar.style.display = 'none'; + ui.window.classList.remove("leftbar"); + ui.window.classList.remove("rightbar"); + ui.historybar.style.display = "none"; _status.event = next; _status.paused = false; _status.paused2 = false; @@ -2274,10 +2627,10 @@ export class Game extends Uninstantable { lib.character[j] = lib.character[j] || lib.characterPack[i][j]; } } - next.setContent('playVideoContent'); + next.setContent("playVideoContent"); game.loop(); } - static videoContent = { + videoContent = { arrangeLib: function (content) { for (var i in content) { for (var j in content[i]) { @@ -2287,27 +2640,26 @@ export class Game extends Uninstantable { }, $syncDisable: function (player, map) { player.disabledSlots = map; - player.$syncDisable(map) + player.$syncDisable(map); }, $syncExpand: function (player, map) { player.expandedSlots = map; - player.$syncExpand(map) + player.$syncExpand(map); }, $disableJudge: function (player, map) { - player.$disableJudge() + player.$disableJudge(); }, $enableJudge: function (player, map) { - player.$enableJudge() + player.$enableJudge(); }, jiuNode: function (player, bool) { //Powered by 升麻 if (bool) { if (!player.node.jiu && lib.config.jiu_effect) { - player.node.jiu = ui.create.div('.playerjiu', player.node.avatar); - player.node.jiu2 = ui.create.div('.playerjiu', player.node.avatar2); + player.node.jiu = ui.create.div(".playerjiu", player.node.avatar); + player.node.jiu2 = ui.create.div(".playerjiu", player.node.avatar2); } - } - else { + } else { if (player.node.jiu) { player.node.jiu.delete(); player.node.jiu2.delete(); @@ -2318,11 +2670,11 @@ export class Game extends Uninstantable { }, init: function (players) { if (game.chess) return; - if (lib.config.mode == 'versus') { + if (lib.config.mode == "versus") { players.bool = players.pop(); } ui.arena.setNumber(players.length); - ui.arena.classList.add('video'); + ui.arena.classList.add("video"); game.players.length = 0; game.dead.length = 0; ui.create.players(players.length); @@ -2331,84 +2683,81 @@ export class Game extends Uninstantable { ui.handcards2 = game.me.node.handcards2; ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); - if (lib.config.mode == 'versus') { + if (lib.config.mode == "versus") { if (players.bool) { ui.arena.setNumber(parseInt(ui.arena.dataset.number) + 1); for (var i = 0; i < game.players.length; i++) { game.players[i].dataset.position = parseInt(game.players[i].dataset.position) + 1; } game.singleHandcard = true; - ui.arena.classList.add('single-handcard'); - ui.window.classList.add('single-handcard'); - ui.fakeme = ui.create.div('.fakeme.avatar', ui.me); + ui.arena.classList.add("single-handcard"); + ui.window.classList.add("single-handcard"); + ui.fakeme = ui.create.div(".fakeme.avatar", ui.me); } - ui.arena.style.display = ''; + ui.arena.style.display = ""; ui.refresh(ui.arena); ui.arena.show(); - } - else if (lib.config.mode == 'boss') { + } else if (lib.config.mode == "boss") { if (!players.boss) { game.singleHandcard = true; - ui.arena.classList.add('single-handcard'); - ui.window.classList.add('single-handcard'); - ui.fakeme = ui.create.div('.fakeme.avatar', ui.me); + ui.arena.classList.add("single-handcard"); + ui.window.classList.add("single-handcard"); + ui.fakeme = ui.create.div(".fakeme.avatar", ui.me); } ui.arena.setNumber(8); } ui.updatehl(); for (var i = 0; i < players.length; i++) { - if (lib.config.mode == 'identity') { - if (_status.mode == 'stratagem') { + if (lib.config.mode == "identity") { + if (_status.mode == "stratagem") { game.players[i].init(players[i].name, players[i].name2); game.players[i].identity = players[i].identity; - if (game.players[i].identity == 'fan' && game.players[i].isCamouflaged && game.me.identity == 'nei' || game.players[i] == game.me) { + if ( + (game.players[i].identity == "fan" && + game.players[i].isCamouflaged && + game.me.identity == "nei") || + game.players[i] == game.me + ) { game.players[i].setIdentity(players[i].identity); } - } - else { + } else { game.players[i].init(players[i].name, players[i].name2); game.players[i].setIdentity(players[i].identity); } - } - else if (lib.config.mode == 'doudizhu' || lib.config.mode == 'single') { + } else if (lib.config.mode == "doudizhu" || lib.config.mode == "single") { game.players[i].init(players[i].name, players[i].name2); game.players[i].setIdentity(players[i].identity); - } - else if (lib.config.mode == 'stone') { + } else if (lib.config.mode == "stone") { game.players[i].init(players[i].name, players[i].name2); - game.players[i].classList.add('noidentity'); + game.players[i].classList.add("noidentity"); game.players[i].updateActCount(null, players[i].count, 0); - } - else if (lib.config.mode == 'boss') { + } else if (lib.config.mode == "boss") { game.players[i].init(players[i].name, players[i].name2); game.players[i].setIdentity(players[i].identity); game.players[i].dataset.position = players[i].position; - game.players[i].node.action.innerHTML = '行动'; - } - else if (lib.config.mode == 'versus') { + game.players[i].node.action.innerHTML = "行动"; + } else if (lib.config.mode == "versus") { game.players[i].init(players[i].name, players[i].name2); game.players[i].node.identity.firstChild.innerHTML = players[i].identity; game.players[i].node.identity.dataset.color = players[i].color; - game.players[i].node.action.innerHTML = '行动'; - } - else if (lib.config.mode == 'guozhan') { + game.players[i].node.action.innerHTML = "行动"; + } else if (lib.config.mode == "guozhan") { game.players[i].name = players[i].name; game.players[i].name1 = players[i].name1; game.players[i].name2 = players[i].name2; - game.players[i].sex = 'unknown'; - game.players[i].identity = 'unknown'; + game.players[i].sex = "unknown"; + game.players[i].identity = "unknown"; lib.translate[game.players[i].name] = players[i].translate; game.players[i].init(players[i].name1, players[i].name2); - game.players[i].classList.add('unseen_v'); - game.players[i].classList.add('unseen2_v'); + game.players[i].classList.add("unseen_v"); + game.players[i].classList.add("unseen2_v"); if (game.players[i] != game.me) { - game.players[i].node.identity.firstChild.innerHTML = '猜'; - game.players[i].node.identity.dataset.color = 'unknown'; - } - else { + game.players[i].node.identity.firstChild.innerHTML = "猜"; + game.players[i].node.identity.dataset.color = "unknown"; + } else { game.players[i].setIdentity(game.players[i].group); } } @@ -2417,16 +2766,15 @@ export class Game extends Uninstantable { game.playerMap[game.players[i].dataset.position] = game.players[i]; } - if (lib.config.mode == 'versus') { + if (lib.config.mode == "versus") { if (players.bool) { game.onSwapControl(); } - } - else if (lib.config.mode == 'boss') { + } else if (lib.config.mode == "boss") { if (!players.boss) { game.onSwapControl(); } - ui.arena.style.display = ''; + ui.arena.style.display = ""; ui.refresh(ui.arena); ui.arena.show(); ui.updatehl(); @@ -2435,19 +2783,17 @@ export class Game extends Uninstantable { newcard: function (content) { if (content) { lib.translate[content.name] = content.translate; - lib.translate[content.name + '_info'] = content.info; + lib.translate[content.name + "_info"] = content.info; lib.card[content.name] = {}; - lib.card[content.name].cardimage = content.card + lib.card[content.name].cardimage = content.card; for (var i in lib.card[content.card]) { lib.card[content.name][i] = lib.card[content.card][i]; } if (content.legend) { lib.card[content.name].legend = true; - } - else if (content.epic) { + } else if (content.epic) { lib.card[content.name].epic = true; - } - else if (content.unique) { + } else if (content.unique) { lib.card[content.name].unique = true; } } @@ -2461,53 +2807,49 @@ export class Game extends Uninstantable { } }, playAudio: function (str) { - game.playAudio(str, 'video'); + game.playAudio(str, "video"); }, playSkillAudio: function (name) { - game.playSkillAudio(name, 'video'); + game.playSkillAudio(name, "video"); }, phaseChange: function (player) { if (player) { - var glowing = document.querySelector('.glow_phase'); + var glowing = document.querySelector(".glow_phase"); if (glowing) { - glowing.classList.remove('glow_phase'); + glowing.classList.remove("glow_phase"); } if (lib.config.glow_phase) { - player.classList.add('glow_phase'); + player.classList.add("glow_phase"); // player.dataset.glow_phase=lib.config.glow_phase; } - } - else { + } else { console.log(player); } }, playerfocus: function (player, time) { if (player && player.playerfocus) { player.playerfocus(time); - } - else { + } else { console.log(player); } }, playerfocus2: function () { - ui.arena.classList.add('playerfocus'); + ui.arena.classList.add("playerfocus"); setTimeout(function () { - ui.arena.classList.remove('playerfocus'); - }, 1500) + ui.arena.classList.remove("playerfocus"); + }, 1500); }, identityText: function (player, str) { if (player && str) { player.node.identity.firstChild.innerHTML = str; - } - else { + } else { console.log(player); } }, identityColor: function (player, str) { if (player && str) { player.node.identity.dataset.color = str; - } - else { + } else { console.log(player); } }, @@ -2515,10 +2857,10 @@ export class Game extends Uninstantable { var me = game.playerMap[content[0]]; var player = game.playerMap[content[1]]; if (me) { - me.classList.remove('current_action'); + me.classList.remove("current_action"); } if (player) { - player.classList.add('current_action'); + player.classList.add("current_action"); } }, chessgainmod: function (player, num) { @@ -2527,17 +2869,15 @@ export class Game extends Uninstantable { } if (player && player.$gainmod) { player.$gainmod(num); - } - else { + } else { console.log(player); } }, moveTo: function (player, pos) { if (player && player.moveTo && pos) { player.moveTo(pos[0], pos[1]); - } - else { - console.log(player) + } else { + console.log(player); } }, addObstacle: function (pos) { @@ -2559,25 +2899,23 @@ export class Game extends Uninstantable { } }, thrownhighlight1: function () { - ui.arena.classList.add('thrownhighlight'); + ui.arena.classList.add("thrownhighlight"); }, thrownhighlight2: function () { - ui.arena.classList.remove('thrownhighlight'); + ui.arena.classList.remove("thrownhighlight"); }, chessFocus: function (player) { if (player) { player.chessFocus(); - } - else { - console.log('chessFocus'); + } else { + console.log("chessFocus"); } }, removeTreasure: function (pos) { if (game.playerMap[pos]) { game.playerMap[pos].delete(); delete game.playerMap[pos]; - } - else { + } else { console.log(pos); } }, @@ -2586,8 +2924,7 @@ export class Game extends Uninstantable { for (var i = 0; i < obs.length; i++) { game.addObstacle(obs[i]); } - } - else { + } else { console.log(obs); } }, @@ -2597,8 +2934,7 @@ export class Game extends Uninstantable { delete game.playerMap[content[0]]; player.dataset.position = content[1]; game.playerMap[content[1]] = player; - } - else { + } else { console.log(content); } }, @@ -2606,7 +2942,7 @@ export class Game extends Uninstantable { if (player && name) { player.delete(); var noboss = false; - if (name[0] == '_') { + if (name[0] == "_") { name = name.slice(1); noboss = true; } @@ -2620,21 +2956,20 @@ export class Game extends Uninstantable { game.arrangePlayers(); if (!noboss) { game.boss = boss; - boss.setIdentity('zhu'); - boss.identity = 'zhu'; + boss.setIdentity("zhu"); + boss.identity = "zhu"; + } else { + boss.setIdentity("zhong"); + boss.identity = "zhong"; } - else { - boss.setIdentity('zhong'); - boss.identity = 'zhong'; - } - ui.arena.appendChild(boss.addTempClass('zoominanim')); + ui.arena.appendChild(boss.addTempClass("zoominanim")); } }, stoneSwap: function (info) { var player = ui.create.player(); - player.classList.add('noidentity'); + player.classList.add("noidentity"); player.dataset.position = info.position; - player.addTempClass(info.me ? 'replaceme' : 'replaceenemy'); + player.addTempClass(info.me ? "replaceme" : "replaceenemy"); player.actcount = info.actcount; player.init(info.name, info.name2); game.players.push(player); @@ -2646,8 +2981,7 @@ export class Game extends Uninstantable { chess_tongshuai: function (player, content) { if (player && player.storage) { player.storage.tongshuai.owned = content; - } - else { + } else { console.log(player); } }, @@ -2656,10 +2990,9 @@ export class Game extends Uninstantable { if (player.marks.tongshuai.firstChild) { player.marks.tongshuai.firstChild.remove(); } - player.marks.tongshuai.setBackground(content[0], 'character'); + player.marks.tongshuai.setBackground(content[0], "character"); player.additionalSkills.tongshuai = content[1]; - } - else { + } else { console.log(player); } }, @@ -2669,8 +3002,7 @@ export class Game extends Uninstantable { if (player.node.avatar2) { player.smoothAvatar(vice); } - } - else { + } else { if (player.node.avatar) { player.smoothAvatar(vice); } @@ -2679,17 +3011,16 @@ export class Game extends Uninstantable { }, setAvatar: function (player, content) { if (player && content && content.length == 2) { - player.setAvatar(content[0], content[1]) + player.setAvatar(content[0], content[1]); } }, setAvatarQueue: function (player, content) { if (player && content && content.length == 2) { - player.setAvatarQueue(content[0], content[1]) + player.setAvatarQueue(content[0], content[1]); } }, addSubPlayer: function (player, content) { - if (player && content && content[0] && content[1] && - content[2] && content[3] && content[4]) { + if (player && content && content[0] && content[1] && content[2] && content[3] && content[4]) { var skill = content[0]; lib.skill[skill] = content[1]; lib.character[skill] = content[2]; @@ -2705,16 +3036,14 @@ export class Game extends Uninstantable { source.uninit(); source.init(content[0]); source.node.identity.dataset.color = content[1]; - } - else { + } else { console.log(source); } }, reinit2: function (source, name) { if (source && name) { source.init(name); - } - else { + } else { console.log(source); } }, @@ -2727,13 +3056,12 @@ export class Game extends Uninstantable { if (source.isUnseen(0)) { source.sex = info2[0]; } - source.node.avatar2.setBackground(content.to, 'character'); + source.node.avatar2.setBackground(content.to, "character"); source.node.name2.innerHTML = get.slimName(content.to); - } - else { + } else { source.name = content.to; source.sex = info2[0]; - source.node.avatar.setBackground(content.to, 'character'); + source.node.avatar.setBackground(content.to, "character"); source.node.name.innerHTML = get.slimName(content.to); } source.maxHp = content.hp; @@ -2751,22 +3079,27 @@ export class Game extends Uninstantable { player.tempname.remove(map.from); player.tempname.add(map.to); player.skin[name] = map.to; - const goon = (!lib.character[map.to]); - if (goon) lib.character[map.to] = ['', '', 0, [], (map.list.find(i => i[0] == map.to) || [map.to, []])[1]]; + const goon = !lib.character[map.to]; + if (goon) + lib.character[map.to] = [ + "", + "", + 0, + [], + (map.list.find((i) => i[0] == map.to) || [map.to, []])[1], + ]; player.smoothAvatar(map.avatar2); - player.node['avatar' + map.name.slice(4)].setBackground(map.to, 'character'); - player.node['avatar' + map.name.slice(4)].show(); + player.node["avatar" + map.name.slice(4)].setBackground(map.to, "character"); + player.node["avatar" + map.name.slice(4)].show(); if (goon) delete lib.character[map.to]; }, skill: function (player, content) { - if (typeof content == 'string') { + if (typeof content == "string") { if (lib.skill[content]) lib.skill[content].video(player); - } - else if (Array.isArray(content)) { + } else if (Array.isArray(content)) { if (lib.skill[content[0]]) lib.skill[content[0]].video(player, content[1]); - } - else { - console.log(player, content) + } else { + console.log(player, content); } }, addFellow: function (content) { @@ -2774,32 +3107,31 @@ export class Game extends Uninstantable { game.playerMap[player.dataset.position] = player; }, windowzoom1: function () { - ui.window.style.transition = 'all 0.5s'; - ui.window.classList.add('zoomout3'); + ui.window.style.transition = "all 0.5s"; + ui.window.classList.add("zoomout3"); ui.window.hide(); }, windowzoom2: function () { - ui.window.style.transition = 'all 0s'; + ui.window.style.transition = "all 0s"; ui.refresh(ui.window); }, windowzoom3: function () { - ui.window.classList.remove('zoomout3'); - ui.window.classList.add('zoomin3'); + ui.window.classList.remove("zoomout3"); + ui.window.classList.add("zoomin3"); }, windowzoom4: function () { - ui.window.style.transition = 'all 0.5s'; + ui.window.style.transition = "all 0.5s"; ui.refresh(ui.window); ui.window.show(); - ui.window.classList.remove('zoomin3'); + ui.window.classList.remove("zoomin3"); }, windowzoom5: function () { - ui.window.style.transition = ''; + ui.window.style.transition = ""; }, updateActCount: function (player, content) { if (player && content) { player.updateActCount(content[0], content[1], content[2]); - } - else { + } else { console.log(player); } }, @@ -2807,16 +3139,14 @@ export class Game extends Uninstantable { identity = identity || (player ? player.identity : null); if (player && player.identity) { player.showIdentity(identity); - } - else { + } else { console.log(player); } }, setIdentity: function (player, identity) { if (player && identity) { player.setIdentity(identity); - } - else { + } else { console.log(num); } }, @@ -2824,23 +3154,26 @@ export class Game extends Uninstantable { if (player && player.classList) { switch (num) { case 0: - player.classList.remove('unseen_v'); + player.classList.remove("unseen_v"); break; case 1: - player.classList.remove('unseen2_v'); + player.classList.remove("unseen2_v"); break; case 2: - player.classList.remove('unseen_v'); - player.classList.remove('unseen2_v'); + player.classList.remove("unseen_v"); + player.classList.remove("unseen2_v"); break; } - if (!player.classList.contains('unseen_v') && (!player.name2 || !player.classList.contains('unseen2_v')) && player.storage.nohp) { + if ( + !player.classList.contains("unseen_v") && + (!player.name2 || !player.classList.contains("unseen2_v")) && + player.storage.nohp + ) { delete player.storage.nohp; player.node.hp.show(); player.update(); } - } - else { + } else { console.log(num); } }, @@ -2859,26 +3192,24 @@ export class Game extends Uninstantable { if (player && player.classList) { switch (num) { case 0: - player.classList.add('unseen_v'); + player.classList.add("unseen_v"); break; case 1: - player.classList.add('unseen2_v'); + player.classList.add("unseen2_v"); break; case 2: - player.classList.add('unseen_v'); - player.classList.add('unseen2_v'); + player.classList.add("unseen_v"); + player.classList.add("unseen2_v"); break; } - } - else { + } else { console.log(num); } }, popup: function (player, info) { if (player && info) { player.popup(info[0], info[1]); - } - else { + } else { console.log(player); } }, @@ -2888,85 +3219,84 @@ export class Game extends Uninstantable { draw: function (player, info) { if (player && player.$draw) { player.$draw(info); - } - else { + } else { console.log(player); } }, drawCard: function (player, info) { if (player && info) { player.$draw(get.infoCards(info)); - } - else { + } else { console.log(player); } }, throw: function (player, info) { if (player && info) { player.$throw(get.infoCards(info[0]), info[1], null, info[2]); - } - else { + } else { console.log(player); } }, compare: function (player, info) { if (player && info) { player.$compare(get.infoCard(info[0]), game.playerMap[info[1]], get.infoCard(info[2])); - } - else { + } else { console.log(player); } }, compareMultiple: function (player, info) { if (player && info) { - player.$compareMultiple(get.infoCard(info[0]), get.infoTargets(info[1]), get.infoCards(info[2])); - } - else { + player.$compareMultiple( + get.infoCard(info[0]), + get.infoTargets(info[1]), + get.infoCards(info[2]) + ); + } else { console.log(player); } }, give: function (player, info) { if (player && info) { player.$give(info[0], game.playerMap[info[1]]); - } - else { + } else { console.log(player); } }, giveCard: function (player, info) { if (player && info) { player.$give(get.infoCards(info[0]), game.playerMap[info[1]]); - } - else { + } else { console.log(player); } }, gain: function (player, info) { if (player && player.$gain) { player.$gain(info); - } - else { + } else { console.log(player); } }, gainCard: function (player, info) { if (player && info) { player.$gain(get.infoCards(info)); - } - else { + } else { console.log(player); } }, gain2: function (player, cards) { if (player && player.$draw) { - var nodeList = document.querySelectorAll('#arena>.card,#chess>.card'); + var nodeList = document.querySelectorAll("#arena>.card,#chess>.card"); var nodes = []; for (var i = 0; i < nodeList.length; i++) { nodes.push(nodeList[i]); } for (var i = 0; i < cards.length; i++) { for (var j = 0; j < nodes.length; j++) { - if (cards[i][2] == nodes[j].name && cards[i][0] == nodes[j].suit && cards[i][1] == nodes[j].number) { + if ( + cards[i][2] == nodes[j].name && + cards[i][0] == nodes[j].suit && + cards[i][1] == nodes[j].number + ) { nodes[j].moveDelete(player); cards.splice(i--, 1); nodes.splice(j--, 1); @@ -2977,24 +3307,27 @@ export class Game extends Uninstantable { if (cards.length) { player.$draw(get.infoCards(cards)); } - } - else { + } else { console.log(player); } }, deletenode: function (player, cards, method) { if (cards) { - var nodeList = document.querySelectorAll('#arena>.card,#chess>.card'); + var nodeList = document.querySelectorAll("#arena>.card,#chess>.card"); var nodes = []; for (var i = 0; i < nodeList.length; i++) { nodes.push(nodeList[i]); } for (var i = 0; i < cards.length; i++) { for (var j = 0; j < nodes.length; j++) { - if (cards[i][2] == nodes[j].name && cards[i][0] == nodes[j].suit && cards[i][1] == nodes[j].number) { + if ( + cards[i][2] == nodes[j].name && + cards[i][0] == nodes[j].suit && + cards[i][1] == nodes[j].number + ) { nodes[j].delete(); - if (method == 'zoom') { - nodes[j].style.transform = 'scale(0)'; + if (method == "zoom") { + nodes[j].style.transform = "scale(0)"; } cards.splice(i--, 1); nodes.splice(j--, 1); @@ -3002,26 +3335,24 @@ export class Game extends Uninstantable { } } } - } - else { + } else { console.log(player, cards); } }, highlightnode: function (player, card) { if (card) { - var nodeList = document.querySelectorAll('#arena>.card,#chess>.card'); + var nodeList = document.querySelectorAll("#arena>.card,#chess>.card"); var nodes = []; for (var i = 0; i < nodeList.length; i++) { nodes.push(nodeList[i]); } for (var j = nodes.length - 1; j >= 0; j--) { if (card[2] == nodes[j].name && card[0] == nodes[j].suit && card[1] == nodes[j].number) { - nodes[j].classList.add('thrownhighlight'); + nodes[j].classList.add("thrownhighlight"); break; } } - } - else { + } else { console.log(player, cards); } }, @@ -3032,21 +3363,19 @@ export class Game extends Uninstantable { if (player && content) { var judging = get.infoCard(content[0]); if (game.chess) { - judging.copy('thrown', 'center', 'thrownhighlight', ui.arena).addTempClass('start'); - } - else { - player.$throwordered(judging.copy('thrownhighlight'), true); + judging.copy("thrown", "center", "thrownhighlight", ui.arena).addTempClass("start"); + } else { + player.$throwordered(judging.copy("thrownhighlight"), true); } ui.create.dialog(content[1]).videoId = content[2]; - ui.arena.classList.add('thrownhighlight'); - } - else { + ui.arena.classList.add("thrownhighlight"); + } else { console.log(player); } }, centernode: function (content) { - get.infoCard(content).copy('thrown', 'center', 'thrownhighlight', ui.arena).addTempClass('start'); + get.infoCard(content).copy("thrown", "center", "thrownhighlight", ui.arena).addTempClass("start"); }, judge2: function (videoId) { for (var i = 0; i < ui.dialogs.length; i++) { @@ -3054,37 +3383,34 @@ export class Game extends Uninstantable { ui.dialogs[i].close(); } } - ui.arena.classList.remove('thrownhighlight'); + ui.arena.classList.remove("thrownhighlight"); }, unmarkname: function (player, name) { if (player && player.unmark) { player.unmark(name); - } - else { + } else { console.log(player); } }, unmark: function (player, name) { if (player && player.marks && player.marks[name]) { player.marks[name].delete(); - player.marks[name].style.transform += ' scale(0.2)'; + player.marks[name].style.transform += " scale(0.2)"; delete player.marks[name]; ui.updatem(this); } }, flame: function (player, type) { if (player && type) { - player['$' + type](); - } - else { + player["$" + type](); + } else { console.log(player); } }, throwEmotion: function (player, content) { if (player && content) { player.$throwEmotion(game.playerMap[content[0]], content[1]); - } - else { + } else { console.log(player); } }, @@ -3093,77 +3419,75 @@ export class Game extends Uninstantable { var checkMatch = function (l1, l2) { for (var i = 0; i < l1.length; i++) { for (var j = 0; j < l2.length; j++) { - if (l2[j].suit == l1[i][0] && l2[j].number == l1[i][1] && l2[j].name == l1[i][2]) { + if ( + l2[j].suit == l1[i][0] && + l2[j].number == l1[i][1] && + l2[j].name == l1[i][2] + ) { l2[j].addGaintag(content[1]); l2.splice(j--, 1); break; } } } - } - checkMatch(content[0], player.getCards('h')); - } - else { + }; + checkMatch(content[0], player.getCards("h")); + } else { console.log(player); } }, removeGaintag: function (player, content) { if (player && content) { - if (Array.isArray(content)) player.removeGaintag.apply(player, content) + if (Array.isArray(content)) player.removeGaintag.apply(player, content); else player.removeGaintag(content); - } - else { + } else { console.log(player); } }, line: function (player, content) { if (player && content) { player.line(game.playerMap[content[0]], content[1]); - } - else { + } else { console.log(player); } }, fullscreenpop: function (player, content) { if (player && content) { player.$fullscreenpop(content[0], content[1], content[2]); - } - else { + } else { console.log(player); } }, damagepop: function (player, content) { if (player && content) { player.$damagepop(content[0], content[1], content[2]); - } - else { + } else { console.log(player); } }, damage: function (player, source) { if (player && player.$damage) { player.$damage(game.playerMap[source]); - } - else { + } else { console.log(player); } }, diex: function (player) { if (!player) { - console.log('diex'); + console.log("diex"); return; } - var cards = player.getCards('hej'); + var cards = player.getCards("hej"); for (var i = 0; i < cards.length; i++) { cards[i].discard(); } while (player.node.marks.childNodes.length > 1) { player.node.marks.lastChild.remove(); } - player.classList.add('dead'); - player.classList.remove('turnedover'); - player.classList.remove('out'); - player.node.count.innerHTML = '0'; + player.classList.add("dead"); + player.classList.remove("turnedover"); + player.classList.remove("out"); + player.node.count.innerHTML = "0"; player.node.hp.hide(); player.node.equips.hide(); player.node.count.hide(); @@ -3171,7 +3495,7 @@ export class Game extends Uninstantable { player.next.previous = player.previous; game.players.remove(player); game.dead.push(player); - if (lib.config.mode == 'stone') { + if (lib.config.mode == "stone") { setTimeout(function () { player.delete(); }, 500); @@ -3182,8 +3506,8 @@ export class Game extends Uninstantable { game.me = player; ui.me.lastChild.show(); ui.create.fakeme(); - ui.handcards1 = player.node.handcards1.addTempClass('start').fix(); - ui.handcards2 = player.node.handcards2.addTempClass('start').fix(); + ui.handcards1 = player.node.handcards1.addTempClass("start").fix(); + ui.handcards2 = player.node.handcards2.addTempClass("start").fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); ui.updatehl(); @@ -3209,7 +3533,7 @@ export class Game extends Uninstantable { }, die: function (player) { if (!player) { - console.log('die'); + console.log("die"); return; } player.$die(); @@ -3229,16 +3553,16 @@ export class Game extends Uninstantable { }, revive: function (player) { if (!player) { - console.log('revive'); + console.log("revive"); return; } - player.classList.remove('dead'); + player.classList.remove("dead"); player.node.hp.show(); player.node.equips.show(); player.node.count.show(); - player.node.avatar.style.transform = ''; - player.node.avatar2.style.transform = ''; - player.removeAttribute('style'); + player.node.avatar.style.transform = ""; + player.node.avatar2.style.transform = ""; + player.removeAttribute("style"); }, update: function (player, info) { if (player && info) { @@ -3246,40 +3570,35 @@ export class Game extends Uninstantable { player.maxHp = info[2]; player.hujia = info[3]; player.update(info[0]); - } - else { + } else { console.log(player); } }, phaseJudge: function (player, card) { if (player && card) { // player.$phaseJudge(get.infoCard(card)); - } - else { + } else { console.log(player); } }, directgain: function (player, cards) { if (player && cards) { player.directgain(get.infoCards(cards)); - } - else { + } else { console.log(player); } }, directgains: function (player, cards) { if (player && cards) { player.directgains(get.infoCards(cards)); - } - else { + } else { console.log(player); } }, directequip: function (player, cards) { if (player && cards) { player.directequip(get.infoCards(cards)); - } - else { + } else { console.log(player); } }, @@ -3288,26 +3607,24 @@ export class Game extends Uninstantable { var cards1 = get.infoCards(cards12[0]); var cards2 = get.infoCards(cards12[1]); for (var i = 0; i < cards1.length; i++) { - cards1[i].classList.add('drawinghidden'); + cards1[i].classList.add("drawinghidden"); cards1[i].addGaintag(cards12[2]); player.node.handcards1.insertBefore(cards1[i], player.node.handcards1.firstChild); } for (var i = 0; i < cards2.length; i++) { - cards2[i].classList.add('drawinghidden'); + cards2[i].classList.add("drawinghidden"); cards2[i].addGaintag(cards12[2]); player.node.handcards2.insertBefore(cards2[i], player.node.handcards2.firstChild); } ui.updatehl(); - } - else { + } else { console.log(player); } }, equip: function (player, card) { if (player && card) { player.$equip(get.infoCard(card)); - } - else { + } else { console.log(player); } }, @@ -3315,15 +3632,19 @@ export class Game extends Uninstantable { if (player && content) { var card = get.infoCard(content[0]); card.viewAs = content[1]; - if (card.viewAs && card.viewAs != card.name && (card.classList.contains('fullskin') || card.classList.contains('fullborder'))) { - card.classList.add('fakejudge'); - card.node.background.innerHTML = lib.translate[card.viewAs + '_bg'] || get.translation(card.viewAs)[0] + if ( + card.viewAs && + card.viewAs != card.name && + (card.classList.contains("fullskin") || card.classList.contains("fullborder")) + ) { + card.classList.add("fakejudge"); + card.node.background.innerHTML = + lib.translate[card.viewAs + "_bg"] || get.translation(card.viewAs)[0]; } - card.classList.add('drawinghidden'); + card.classList.add("drawinghidden"); player.node.judges.insertBefore(card, player.node.judges.firstChild); ui.updatej(player); - } - else { + } else { console.log(player); } }, @@ -3336,8 +3657,7 @@ export class Game extends Uninstantable { if (content.id) { player.marks[content.id] = mark; } - } - else { + } else { console.log(player); } }, @@ -3345,16 +3665,15 @@ export class Game extends Uninstantable { if (player && content && player.marks[content.id]) { player.marks[content.id].info = { name: content.name, - content: content.content + content: content.content, }; - player.marks[content.id].setBackground(content.target, 'character'); + player.marks[content.id].setBackground(content.target, "character"); } }, mark: function (player, content) { if (player && content) { var mark = player.mark(content.id, content); - } - else { + } else { console.log(player); } }, @@ -3362,20 +3681,17 @@ export class Game extends Uninstantable { if (player && content) { if (content[1]) { player.markSkill(content[0], null, get.infoCard(content[1])); - } - else { + } else { player.markSkill(content[0]); } - } - else { + } else { console.log(player); } }, unmarkSkill: function (player, name) { if (player && player.unmarkSkill) { player.unmarkSkill(name); - } - else { + } else { console.log(player); } }, @@ -3383,60 +3699,70 @@ export class Game extends Uninstantable { if (player && content) { if (content[2]) { switch (content[2]) { - case 'cards': content[1] = get.infoCards(content[1]); break; - case 'card': content[1] = get.infoCard(content[1]); break; + case "cards": + content[1] = get.infoCards(content[1]); + break; + case "card": + content[1] = get.infoCard(content[1]); + break; } } player.storage[content[0]] = content[1]; - } - else { + } else { console.log(player); } }, markId: function (player, content) { if (player && content) { player.mark(get.infoCard(content[0]), content[1]); - } - else { + } else { console.log(player); } }, unmarkId: function (player, content) { if (player && content) { player.unmark(get.infoCard(content[0]), content[1]); - } - else { + } else { console.log(player); } }, lose: function (player, info) { if (player && info) { - var hs = info[0] || [], es = info[1] || [], js = info[2] || [], ss = info[3] || []; - var phs = player.getCards('h'), pes = player.getCards('e'), pjs = player.getCards('j'), pss = player.getCards('s'); + var hs = info[0] || [], + es = info[1] || [], + js = info[2] || [], + ss = info[3] || []; + var phs = player.getCards("h"), + pes = player.getCards("e"), + pjs = player.getCards("j"), + pss = player.getCards("s"); var checkMatch = function (l1, l2) { for (var i = 0; i < l1.length; i++) { for (var j = 0; j < l2.length; j++) { - if (l2[j].suit == l1[i][0] && l2[j].number == l1[i][1] && l2[j].name == l1[i][2]) { + if ( + l2[j].suit == l1[i][0] && + l2[j].number == l1[i][1] && + l2[j].name == l1[i][2] + ) { l2[j].remove(); l2.splice(j--, 1); break; } } } - } + }; checkMatch(hs, phs); checkMatch(es, pes); checkMatch(js, pjs); checkMatch(ss, pss); ui.updatehl(); - } - else { + } else { console.log(player); } }, loseAfter: function (player) { if (!player) { - console.log('loseAfter'); + console.log("loseAfter"); return; } }, @@ -3444,25 +3770,21 @@ export class Game extends Uninstantable { if (player && player.classList) { if (bool) { player.addLink(); - } - else { + } else { player.removeLink(); } - } - else { + } else { console.log(player); } }, turnOver: function (player, bool) { if (player && player.classList) { if (bool) { - player.classList.add('turnedover'); + player.classList.add("turnedover"); + } else { + player.classList.remove("turnedover"); } - else { - player.classList.remove('turnedover'); - } - } - else { + } else { console.log(player); } }, @@ -3472,16 +3794,14 @@ export class Game extends Uninstantable { setTimeout(function () { dialog.close(); }, 1000); - } - else { + } else { console.log(player); } }, cardDialog: function (content) { if (Array.isArray(content)) { ui.create.dialog(content[0], get.infoCards(content[1])).videoId = content[2]; - } - else if (typeof content == 'number') { + } else if (typeof content == "number") { for (var i = 0; i < ui.dialogs.length; i++) { if (ui.dialogs[i].videoId == content) { ui.dialogs[i].close(); @@ -3520,7 +3840,7 @@ export class Game extends Uninstantable { player1.dataset.position = player2.dataset.position; player2.dataset.position = temp1; game.arrangePlayers(); - if (player1.dataset.position == '0' || player2.dataset.position == '0') { + if (player1.dataset.position == "0" || player2.dataset.position == "0") { pos = parseInt(player1.dataset.position); if (pos == 0) pos = parseInt(player2.dataset.position); num = game.players.length + game.dead.length; @@ -3543,22 +3863,22 @@ export class Game extends Uninstantable { }, removeTafangPlayer: function () { ui.fakeme.hide(); - ui.handcards1Container.innerHTML = ''; - ui.handcards2Container.innerHTML = ''; + ui.handcards1Container.innerHTML = ""; + ui.handcards2Container.innerHTML = ""; game.me = ui.create.player(); }, swapControl: function (player, hs) { if (player && player.node) { var cards = get.infoCards(hs); - player.node.handcards1.innerHTML = ''; - player.node.handcards2.innerHTML = ''; + player.node.handcards1.innerHTML = ""; + player.node.handcards2.innerHTML = ""; player.directgain(cards, false); game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); - ui.handcards1 = player.node.handcards1.addTempClass('start').fix(); - ui.handcards2 = player.node.handcards2.addTempClass('start').fix(); + ui.handcards1 = player.node.handcards1.addTempClass("start").fix(); + ui.handcards2 = player.node.handcards2.addTempClass("start").fix(); ui.handcards1Container.insertBefore(ui.handcards1, ui.handcards1Container.firstChild); ui.handcards2Container.insertBefore(ui.handcards2, ui.handcards2Container.firstChild); @@ -3567,8 +3887,7 @@ export class Game extends Uninstantable { if (game.chess) { ui.create.fakeme(); } - } - else { + } else { console.log(player); } }, @@ -3578,8 +3897,8 @@ export class Game extends Uninstantable { swapPlayer: function (player, hs) { if (player && player.node) { var cards = get.infoCards(hs); - player.node.handcards1.innerHTML = ''; - player.node.handcards2.innerHTML = ''; + player.node.handcards1.innerHTML = ""; + player.node.handcards2.innerHTML = ""; player.directgain(cards, false); var pos = parseInt(player.dataset.position); @@ -3594,8 +3913,8 @@ export class Game extends Uninstantable { game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); game.me = player; - ui.handcards1 = player.node.handcards1.addTempClass('start').fix(); - ui.handcards2 = player.node.handcards2.addTempClass('start').fix(); + ui.handcards1 = player.node.handcards1.addTempClass("start").fix(); + ui.handcards2 = player.node.handcards2.addTempClass("start").fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); @@ -3606,48 +3925,46 @@ export class Game extends Uninstantable { for (var i = 0; i < players.length; i++) { game.playerMap[players[i].dataset.position] = players[i]; } - } - else { + } else { console.log(player); } }, over: function (str) { - var dialog = ui.create.dialog('hidden'); + var dialog = ui.create.dialog("hidden"); dialog.noforcebutton = true; dialog.content.innerHTML = str; dialog.forcebutton = true; dialog.open(); if (game.chess) { - dialog.classList.add('center'); + dialog.classList.add("center"); } - if ((game.layout == 'long2' || game.layout == 'nova') && !game.chess) { - ui.arena.classList.add('choose-character'); + if ((game.layout == "long2" || game.layout == "nova") && !game.chess) { + ui.arena.classList.add("choose-character"); if (ui.me) ui.me.hide(); - if (ui.mebg) ui.mebg.hide() + if (ui.mebg) ui.mebg.hide(); if (ui.autonode) ui.autonode.hide(); - if (lib.config.radius_size != 'off') { - if (ui.historybar) ui.historybar.style.borderRadius = '0 0 0 4px'; + if (lib.config.radius_size != "off") { + if (ui.historybar) ui.historybar.style.borderRadius = "0 0 0 4px"; } } - } - } - static reload() { + }, + }; + reload() { if (_status) { if (_status.reloading) return; _status.reloading = true; } if (_status.video && !_status.replayvideo) { - localStorage.removeItem(lib.configprefix + 'playbackmode'); + localStorage.removeItem(lib.configprefix + "playbackmode"); } - localStorage.setItem('show_splash_off', true); + localStorage.setItem("show_splash_off", true); if (lib.status.reload) { _status.waitingToReload = true; - } - else { + } else { window.location.reload(); } } - static reload2() { + reload2() { lib.status.reload--; if (lib.status.reload == 0 && lib.ondb2.length) { const command = lib.ondb2.shift(); @@ -3661,38 +3978,38 @@ export class Game extends Uninstantable { window.location.reload(); delete _status.waitingToReload; } - static exit() { + exit() { var ua = userAgent; - var ios = ua.includes('iphone') || ua.includes('ipad') || ua.includes('macintosh'); + var ios = ua.includes("iphone") || ua.includes("ipad") || ua.includes("macintosh"); //electron - if (typeof window.process == 'object' && typeof window.require == 'function') { + if (typeof window.process == "object" && typeof window.require == "function") { var versions = window.process.versions; var electronVersion = parseFloat(versions.electron); var remote; if (electronVersion >= 14) { - remote = require('@electron/remote'); + remote = require("@electron/remote"); } else { - remote = require('electron').remote; + remote = require("electron").remote; } var thisWindow = remote.getCurrentWindow(); thisWindow.destroy(); window.process.exit(); } // android-cordova环境 - else if (lib.device === 'android') { + else if (lib.device === "android") { if (navigator.app && navigator.app.exitApp) { navigator.app.exitApp(); } } //ios-cordova环境或ios浏览器环境 - else if (lib.device === 'ios' || !lib.device && ios) { - game.saveConfig('mode'); + else if (lib.device === "ios" || (!lib.device && ios)) { + game.saveConfig("mode"); if (_status) { if (_status.reloading) return; _status.reloading = true; } if (_status.video && !_status.replayvideo) { - localStorage.removeItem(lib.configprefix + 'playbackmode'); + localStorage.removeItem(lib.configprefix + "playbackmode"); } window.location.reload(); } @@ -3703,31 +4020,29 @@ export class Game extends Uninstantable { } } /** - * @param { string } url + * @param { string } url */ - static open(url) { + open(url) { if (lib.device) { if (cordova.InAppBrowser) { - cordova.InAppBrowser.open(url, '_system'); - } - else { + cordova.InAppBrowser.open(url, "_system"); + } else { ui.create.iframe(url); } - } - else { + } else { window.open(url); } } - static reloadCurrent() { - game.saveConfig('continue_name', [game.me.name1 || game.me.name, game.me.name2]); - game.saveConfig('mode', lib.config.mode); - localStorage.setItem(lib.configprefix + 'directstart', true); + reloadCurrent() { + game.saveConfig("continue_name", [game.me.name1 || game.me.name, game.me.name2]); + game.saveConfig("mode", lib.config.mode); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); } /** - * @param { Function } func + * @param { Function } func */ - static update(func) { + update(func) { lib.updates.push(func); if (lib.updates.length === 1) { game.run(); @@ -3735,15 +4050,15 @@ export class Game extends Uninstantable { return func; } /** - * @param { Function } func + * @param { Function } func */ - static unupdate(func) { + unupdate(func) { lib.updates.remove(func); } - static stop() { + stop() { cancelAnimationFrame(lib.status.frameId); } - static run() { + run() { if (lib.updates.length) { cancelAnimationFrame(lib.status.frameId); lib.status.frameId = requestAnimationFrame(function (time) { @@ -3755,25 +4070,25 @@ export class Game extends Uninstantable { } } /** - * @param { string } type - * @param { Player } player - * @param { any } [content] - * @returns + * @param { string } type + * @param { Player } player + * @param { any } [content] + * @returns */ - static addVideo(type, player, content) { + addVideo(type, player, content) { if (_status.video || game.online) return; if (!_status.videoInited) { - if (type == 'arrangeLib') { + if (type == "arrangeLib") { lib.video.push({ type: type, player: player, content: content, - delay: 0 + delay: 0, }); } return; } - if (type == 'storage' && player && player.updateMarks) { + if (type == "storage" && player && player.updateMarks) { player.updateMarks(); } if (game.getVideoName) { @@ -3781,22 +4096,22 @@ export class Game extends Uninstantable { if (!_status.lastVideoLog) { _status.lastVideoLog = time; } - if (get.itemtype(player) == 'player') { + if (get.itemtype(player) == "player") { player = player.dataset.position; } lib.video.push({ type: type, player: player, content: content, - delay: time - _status.lastVideoLog + delay: time - _status.lastVideoLog, }); _status.lastVideoLog = time; } } /** - * @param { Function } func + * @param { Function } func */ - static draw(func) { + draw(func) { lib.canvasUpdates.push(func); if (!lib.status.canvas) { lib.status.canvas = true; @@ -3804,37 +4119,37 @@ export class Game extends Uninstantable { } } /** - * @param { number } [time] + * @param { number } [time] */ - static vibrate(time) { - if ('vibrate' in navigator) { + vibrate(time) { + if ("vibrate" in navigator) { navigator.vibrate(time || 500); } } - static prompt() { - let str, forced, callback, noinput = false, str2 = ''; + prompt() { + let str, + forced, + callback, + noinput = false, + str2 = ""; for (let i = 0; i < arguments.length; i++) { - if (arguments[i] == 'alert') { + if (arguments[i] == "alert") { forced = true; noinput = true; - } - else if (typeof arguments[i] == 'string') { - if (arguments[i].startsWith('###')) { - var list = arguments[i].slice(3).split('###'); + } else if (typeof arguments[i] == "string") { + if (arguments[i].startsWith("###")) { + var list = arguments[i].slice(3).split("###"); str = list[0]; str2 = list[1]; - } - else str = arguments[i]; - } - else if (typeof arguments[i] == 'boolean') { + } else str = arguments[i]; + } else if (typeof arguments[i] == "boolean") { forced = arguments[i]; - } - else if (typeof arguments[i] == 'function') { + } else if (typeof arguments[i] == "function") { callback = arguments[i]; } } if (!callback) { - callback = function () { }; + callback = function () {}; } //try{ // if(noinput){ @@ -3844,23 +4159,22 @@ export class Game extends Uninstantable { // callback(result); //} //catch(e){ - let promptContainer = ui.create.div('.popup-container', ui.window, function () { + let promptContainer = ui.create.div(".popup-container", ui.window, function () { if (this.clicked) { this.clicked = false; - } - else { + } else { clickCancel(); } }); - let dialogContainer = ui.create.div('.prompt-container', promptContainer); - let dialog = ui.create.div('.menubg', ui.create.div(dialogContainer), function () { + let dialogContainer = ui.create.div(".prompt-container", promptContainer); + let dialog = ui.create.div(".menubg", ui.create.div(dialogContainer), function () { promptContainer.clicked = true; }); - let strnode = ui.create.div('', str || '', dialog); - let input = ui.create.node('input', ui.create.div(dialog)); + let strnode = ui.create.div("", str || "", dialog); + let input = ui.create.node("input", ui.create.div(dialog)); input.value = str2; if (noinput) { - input.style.display = 'none'; + input.style.display = "none"; } let controls = ui.create.div(dialog); let clickConfirm = function () { @@ -3868,86 +4182,82 @@ export class Game extends Uninstantable { //给一个返回值使promise化正常使用 callback(true); promptContainer.remove(); - } - else { + } else { callback(input.value); promptContainer.remove(); } - } + }; let clickCancel = function () { callback(false); if (!forced) { promptContainer.remove(); } - } - let confirmNode = ui.create.div('.menubutton.large.disabled', '确定', controls, clickConfirm); + }; + let confirmNode = ui.create.div(".menubutton.large.disabled", "确定", controls, clickConfirm); if (!forced) { - ui.create.div('.menubutton.large', '取消', controls, clickCancel); + ui.create.div(".menubutton.large", "取消", controls, clickCancel); } if (noinput || (str2 && str2.length > 0)) { - confirmNode.classList.remove('disabled'); - } - else { + confirmNode.classList.remove("disabled"); + } else { input.onkeydown = function (e) { if (e.keyCode == 13) { clickConfirm(); - } - else if (e.keyCode == 27) { + } else if (e.keyCode == 27) { clickCancel(); } e.stopPropagation(); - } + }; input.onkeyup = function (e) { if (input.value) { - confirmNode.classList.remove('disabled'); - } - else { - confirmNode.classList.remove('disabled'); + confirmNode.classList.remove("disabled"); + } else { + confirmNode.classList.remove("disabled"); } e.stopPropagation(); - } + }; input.focus(); } //} } - static alert(str) { - game.prompt(str, 'alert'); + alert(str) { + game.prompt(str, "alert"); } - static print() { + print() { if (!_status.toprint) { _status.toprint = []; } _status.toprint.push(Array.from(arguments)); } - static animate = { + animate = { window: function (num) { switch (num) { case 1: { - ui.window.style.transition = 'all 0.5s'; - ui.window.classList.add('zoomout3'); + ui.window.style.transition = "all 0.5s"; + ui.window.classList.add("zoomout3"); ui.window.hide(); - game.addVideo('windowzoom1'); + game.addVideo("windowzoom1"); game.delay(0, 500); break; } case 2: { - ui.window.style.transition = 'all 0s'; + ui.window.style.transition = "all 0s"; ui.refresh(ui.window); - game.addVideo('windowzoom2'); + game.addVideo("windowzoom2"); game.pause(); setTimeout(function () { - ui.window.classList.remove('zoomout3'); - ui.window.classList.add('zoomin3'); - game.addVideo('windowzoom3'); + ui.window.classList.remove("zoomout3"); + ui.window.classList.add("zoomin3"); + game.addVideo("windowzoom3"); setTimeout(function () { - ui.window.style.transition = 'all 0.5s'; + ui.window.style.transition = "all 0.5s"; ui.refresh(ui.window); ui.window.show(); - ui.window.classList.remove('zoomin3'); - game.addVideo('windowzoom4'); + ui.window.classList.remove("zoomin3"); + game.addVideo("windowzoom4"); setTimeout(function () { - ui.window.style.transition = ''; - game.addVideo('windowzoom5'); + ui.window.style.transition = ""; + game.addVideo("windowzoom5"); game.resume(); }, 500); }, 100); @@ -3959,19 +4269,15 @@ export class Game extends Uninstantable { flame: function (x, y, duration, type) { var particles = []; var particle_count = 50; - if (type == 'thunder' || type == 'recover') { + if (type == "thunder" || type == "recover") { particle_count = 30; - } - else if (type == 'coin' || type == 'dust') { + } else if (type == "coin" || type == "dust") { particle_count = 50; - } - else if (type == 'legend') { + } else if (type == "legend") { particle_count = 120; - } - else if (type == 'epic') { + } else if (type == "epic") { particle_count = 80; - } - else if (type == 'rare') { + } else if (type == "rare") { particle_count = 50; } for (var i = 0; i < particle_count; i++) { @@ -3979,11 +4285,11 @@ export class Game extends Uninstantable { } function particle() { this.speed = { x: -1 + Math.random() * 2, y: -5 + Math.random() * 5 }; - if (type == 'thunder' || type == 'coin' || type == 'dust') { + if (type == "thunder" || type == "coin" || type == "dust") { this.speed.y = -3 + Math.random() * 5; this.speed.x = -2 + Math.random() * 4; } - if (type == 'legend' || type == 'rare' || type == 'epic') { + if (type == "legend" || type == "rare" || type == "epic") { this.speed.x *= 3; this.speed.y *= 1.5; } @@ -3995,7 +4301,7 @@ export class Game extends Uninstantable { this.death = this.life; switch (type) { - case 'thunder': { + case "thunder": { this.b = 255; this.r = Math.round(Math.random() * 255); this.g = Math.round(Math.random() * 255); @@ -4004,13 +4310,13 @@ export class Game extends Uninstantable { break; } - case 'fire': { + case "fire": { this.r = 255; this.g = Math.round(Math.random() * 155); this.b = 0; break; } - case 'coin': { + case "coin": { this.r = 255; this.g = Math.round(Math.random() * 25 + 230); this.b = Math.round(Math.random() * 100 + 50); @@ -4018,15 +4324,14 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.life *= 1.3; this.death *= 1.3; break; } - case 'dust': { + case "dust": { this.r = Math.round(Math.random() * 55) + 105; this.g = Math.round(Math.random() * 55) + 150; this.b = 255; @@ -4034,15 +4339,14 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.life *= 1.3; this.death *= 1.3; break; } - case 'legend': { + case "legend": { this.r = 255; this.g = Math.round(Math.random() * 100 + 155); this.b = Math.round(Math.random() * 100 + 50); @@ -4050,8 +4354,7 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.speed.x /= 2; @@ -4060,7 +4363,7 @@ export class Game extends Uninstantable { this.death *= 2; break; } - case 'epic': { + case "epic": { this.r = Math.round(Math.random() * 55) + 200; this.g = Math.round(Math.random() * 100) + 55; this.b = 255; @@ -4068,8 +4371,7 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.speed.x /= 2; @@ -4078,7 +4380,7 @@ export class Game extends Uninstantable { this.death *= 2; break; } - case 'rare': { + case "rare": { this.r = Math.round(Math.random() * 55) + 105; this.g = Math.round(Math.random() * 55) + 150; this.b = 255; @@ -4086,8 +4388,7 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.speed.x /= 2; @@ -4096,7 +4397,7 @@ export class Game extends Uninstantable { this.death *= 2; break; } - case 'recover': { + case "recover": { this.g = 255; this.r = Math.round(Math.random() * 200 + 55); this.b = Math.round(Math.random() * 155 + 55); @@ -4104,8 +4405,7 @@ export class Game extends Uninstantable { this.location.y += Math.round(Math.random() * 40) - 20; if (this.location.x < x) { this.speed.x = -Math.abs(this.speed.x); - } - else if (this.location.x > x) { + } else if (this.location.x > x) { this.speed.x = Math.abs(this.speed.x); } this.speed.x /= 2; @@ -4132,41 +4432,56 @@ export class Game extends Uninstantable { surface.beginPath(); var middle = 0.5; var radius = p.radius; - if (type == 'recover' || type == 'legend' || type == 'rare' || - type == 'epic' || type == 'coin' || type == 'dust') { + if ( + type == "recover" || + type == "legend" || + type == "rare" || + type == "epic" || + type == "coin" || + type == "dust" + ) { middle = 0.7; radius /= 3; } - p.opacity = Math.round(p.death / p.life * 100) / 100 - var gradient = surface.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius); - gradient.addColorStop(0, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")"); - gradient.addColorStop(middle, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")"); + p.opacity = Math.round((p.death / p.life) * 100) / 100; + var gradient = surface.createRadialGradient( + p.location.x, + p.location.y, + 0, + p.location.x, + p.location.y, + p.radius + ); + gradient.addColorStop( + 0, + "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")" + ); + gradient.addColorStop( + middle, + "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")" + ); gradient.addColorStop(1, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", 0)"); surface.fillStyle = gradient; surface.arc(p.location.x, p.location.y, radius, Math.PI * 2, false); surface.fill(); p.death--; - if (type == 'recover') { + if (type == "recover") { p.radius += 0.5; - } - else if (type == 'coin' || type == 'dust') { + } else if (type == "coin" || type == "dust") { p.radius += 0.7; - } - else if (type == 'legend' || type == 'rare' || type == 'epic') { + } else if (type == "legend" || type == "rare" || type == "epic") { p.radius += 0.5; - } - else { + } else { p.radius++; } - p.location.x += (p.speed.x); - p.location.y += (p.speed.y); + p.location.x += p.speed.x; + p.location.y += p.speed.y; if (p.death < 0 || p.radius < 0) { - if (typeof duration == 'number' && time + 500 >= duration) { + if (typeof duration == "number" && time + 500 >= duration) { particles.splice(i--, 1); - } - else { + } else { particles[i] = new particle(); } } @@ -4175,139 +4490,152 @@ export class Game extends Uninstantable { return false; } }); - } - } + }, + }; /** - * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path + * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path */ - static linexy(path) { - const from = [path[0], path[1]], to = [path[2], path[3]]; - let total = typeof arguments[1] === 'number' ? arguments[1] : lib.config.duration * 2, + linexy(path) { + const from = [path[0], path[1]], + to = [path[2], path[3]]; + let total = typeof arguments[1] === "number" ? arguments[1] : lib.config.duration * 2, opacity = 1, color = [255, 255, 255], dashed = false, drag = false; - if (arguments[1] && typeof arguments[1] == 'object') Object.keys(arguments[1]).forEach(value => { - switch (value) { - case 'opacity': - opacity = arguments[1][value]; - break; - case 'color': - color = arguments[1][value]; - break; - case 'dashed': - dashed = arguments[1][value]; - break; - case 'duration': total = arguments[1][value]; - break; - } - }); - else if (typeof arguments[1] == 'string') color = arguments[1]; - if (typeof color == 'string') color = lib.lineColor.get(color) || [255, 255, 255]; + if (arguments[1] && typeof arguments[1] == "object") + Object.keys(arguments[1]).forEach((value) => { + switch (value) { + case "opacity": + opacity = arguments[1][value]; + break; + case "color": + color = arguments[1][value]; + break; + case "dashed": + dashed = arguments[1][value]; + break; + case "duration": + total = arguments[1][value]; + break; + } + }); + else if (typeof arguments[1] == "string") color = arguments[1]; + if (typeof color == "string") color = lib.lineColor.get(color) || [255, 255, 255]; let node; - if (arguments[1] == 'drag') { + if (arguments[1] == "drag") { color = [236, 201, 71]; drag = true; if (arguments[2]) node = arguments[2]; else { - node = ui.create.div('.linexy.drag'); + node = ui.create.div(".linexy.drag"); node.style.left = `${from[0]}px`; node.style.top = `${from[1]}px`; node.style.background = `linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; if (game.chess) ui.chess.appendChild(node); else ui.arena.appendChild(node); } - } - else { - node = ui.create.div('.linexy.hidden'); + } else { + node = ui.create.div(".linexy.hidden"); node.style.left = `${from[0]}px`; node.style.top = `${from[1]}px`; node.style.background = `linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; node.style.transitionDuration = `${total / 3000}s`; } - const dy = to[1] - from[1], dx = to[0] - from[0]; - let deg = Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI * 180; - if (dx >= 0) if (dy <= 0) deg += 90; - else deg = 90 - deg; + const dy = to[1] - from[1], + dx = to[0] - from[0]; + let deg = (Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI) * 180; + if (dx >= 0) + if (dy <= 0) deg += 90; + else deg = 90 - deg; else if (dy <= 0) deg = 270 - deg; else deg += 270; if (drag) { - node.style.transform = `rotate(${(-deg)}deg)`; + node.style.transform = `rotate(${-deg}deg)`; node.style.height = `${get.xyDistance(from, to)}px`; - } - else { - node.style.transform = `rotate(${(-deg)}deg) scaleY(0)`; + } else { + node.style.transform = `rotate(${-deg}deg) scaleY(0)`; node.style.height = `${get.xyDistance(from, to)}px`; - if (['div', 'fragment'].includes(get.objtype(arguments[1]))) arguments[1].appendChild(node); + if (["div", "fragment"].includes(get.objtype(arguments[1]))) arguments[1].appendChild(node); else if (game.chess) ui.chess.appendChild(node); else ui.arena.appendChild(node); ui.refresh(node); node.show(); - node.style.transform = `rotate(${(-deg)}deg) scaleY(1)`; - node.listenTransition(() => setTimeout(() => { - if (!node.classList.contains('removing')) node.delete(); - }, total / 3)); + node.style.transform = `rotate(${-deg}deg) scaleY(1)`; + node.listenTransition(() => + setTimeout(() => { + if (!node.classList.contains("removing")) node.delete(); + }, total / 3) + ); } return node; } /** - * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path + * @param { [number, number | {opacity:any, color:any, dashed:any, duration:any} | string, number, number] } path */ - static _linexy(path) { + _linexy(path) { let from = [path[0], path[1]]; let to = [path[2], path[3]]; - let total = typeof arguments[1] === 'number' ? arguments[1] : lib.config.duration * 2; + let total = typeof arguments[1] === "number" ? arguments[1] : lib.config.duration * 2; let opacity = 1; let color = [255, 255, 255]; let dashed = false; - if (typeof arguments[1] == 'object') { + if (typeof arguments[1] == "object") { for (let i in arguments[1]) { switch (i) { - case 'opacity': opacity = arguments[1][i]; break; - case 'color': color = arguments[1][i]; break; - case 'dashed': dashed = arguments[1][i]; break; - case 'duration': total = arguments[1][i]; break; + case "opacity": + opacity = arguments[1][i]; + break; + case "color": + color = arguments[1][i]; + break; + case "dashed": + dashed = arguments[1][i]; + break; + case "duration": + total = arguments[1][i]; + break; } } - } - else if (arguments[1] == 'fire' || arguments[1] == 'thunder' || arguments[1] == 'green') { + } else if (arguments[1] == "fire" || arguments[1] == "thunder" || arguments[1] == "green") { color = arguments[1]; } - if (color == 'fire') { + if (color == "fire") { color = [255, 146, 68]; - } - else if (color == 'thunder') { + } else if (color == "thunder") { color = [141, 216, 255]; - } - else if (color == 'green') { + } else if (color == "green") { color = [141, 255, 216]; } let drawfunc = function (time, ctx) { let current; if (time < total / 3) { - ctx.strokeStyle = 'rgba(' + color.toString() + ',' + opacity * (time / (total / 3)) + ')'; - current = [from[0] + (to[0] - from[0]) * time / (total / 3), - from[1] + (to[1] - from[1]) * time / (total / 3)]; - } - else if (time <= total) { + ctx.strokeStyle = "rgba(" + color.toString() + "," + opacity * (time / (total / 3)) + ")"; + current = [ + from[0] + ((to[0] - from[0]) * time) / (total / 3), + from[1] + ((to[1] - from[1]) * time) / (total / 3), + ]; + } else if (time <= total) { current = to; if (time > total / 1.5) { - ctx.strokeStyle = 'rgba(' + color.toString() + ',' + opacity * (1 - (time - total / 1.5) / (total - total / 1.5)) + ')'; + ctx.strokeStyle = + "rgba(" + + color.toString() + + "," + + opacity * (1 - (time - total / 1.5) / (total - total / 1.5)) + + ")"; + } else { + ctx.strokeStyle = "rgba(" + color.toString() + "," + opacity + ")"; } - else { - ctx.strokeStyle = 'rgba(' + color.toString() + ',' + opacity + ')'; - } - } - else { + } else { return false; } ctx.beginPath(); if (dashed) { - ctx.lineCap = 'butt'; + ctx.lineCap = "butt"; ctx.setLineDash([8, 2]); - } - else { - ctx.lineCap = 'round'; + } else { + ctx.lineCap = "round"; } ctx.moveTo(from[0], from[1]); ctx.lineTo(current[0], current[1]); @@ -4315,24 +4643,23 @@ export class Game extends Uninstantable { }; if (arguments[2] && game.chess) { game.draw2(drawfunc); - } - else { + } else { game.draw(drawfunc); } } /** - * @param { string } name - * @param { string } skill - * @param { Player } player - * @param { GameEventPromise } event - * @returns { GameEventPromise } + * @param { string } name + * @param { string } skill + * @param { Player } player + * @param { import('../library/index.js').GameEventPromise } event + * @returns { import('../library/index.js').GameEventPromise } */ - static createTrigger(name, skill, player, event, indexedData) { + createTrigger(name, skill, player, event, indexedData) { let info = get.info(skill); if (!info) return false; if ((player.isOut() || player.removed) && !info.forceOut) return; if (player.isDead() && !info.forceDie) return; - let next = game.createEvent('trigger', false); + let next = game.createEvent("trigger", false); next.skill = skill; next.player = player; next.triggername = name; @@ -4340,36 +4667,39 @@ export class Game extends Uninstantable { next.includeOut = true; next._trigger = event; next.indexedData = indexedData; - next.setContent('createTrigger'); + next.setContent("createTrigger"); return next; } /** * @legacy Use {@link lib.element.GameEvent.constructor} instead. - * - * @param { string } name + * + * @param { string } name * @param { false } [trigger] - * @param { GameEventPromise } [triggerEvent] + * @param { import('../library/index.js').GameEventPromise } [triggerEvent] */ - static createEvent(name, trigger, triggerEvent) { - const next = (new lib.element.GameEvent(name, trigger)).toPromise(); + createEvent(name, trigger, triggerEvent) { + const next = new lib.element.GameEvent(name, trigger).toPromise(); (triggerEvent || _status.event).next.push(next); return next; } /** - * @param { string } name - * @param { { extension: string, sex: Sex, group: string, hp: string | number, skills?: string[], tags?: any[], translate: string } } information + * @param { string } name + * @param { { extension: string, sex: Sex, group: string, hp: string | number, skills?: string[], tags?: any[], translate: string } } information */ - static addCharacter(name, information) { - const extensionName = _status.extension || information.extension, character = [ - information.sex, - information.group, - information.hp, - information.skills || [], - [ - _status.evaluatingExtension ? `db:extension-${extensionName}:${name}.jpg` : `ext:${extensionName}/${name}.jpg`, - `die:ext:${extensionName}/${name}.mp3` - ] - ]; + addCharacter(name, information) { + const extensionName = _status.extension || information.extension, + character = [ + information.sex, + information.group, + information.hp, + information.skills || [], + [ + _status.evaluatingExtension + ? `db:extension-${extensionName}:${name}.jpg` + : `ext:${extensionName}/${name}.jpg`, + `die:ext:${extensionName}/${name}.mp3`, + ], + ]; if (information.tags) character[4] = character[4].concat(information.tags); lib.character[name] = character; const packName = `mode_extension_${extensionName}`; @@ -4379,36 +4709,40 @@ export class Game extends Uninstantable { lib.translate[`${packName}_character_config`] = extensionName; } /** - * @param { { mode?: string, forbid?: any, character: { [key: string]: Character }, skill: { [key: string]: object }, [key: string]: any } } pack - * @param { string } [packagename] + * @param { { mode?: string, forbid?: any, character: { [key: string]: Character }, skill: { [key: string]: object }, [key: string]: any } } pack + * @param { string } [packagename] */ - static addCharacterPack(pack, packagename) { - let extname = _status.extension || '扩展'; + addCharacterPack(pack, packagename) { + let extname = _status.extension || "扩展"; let gzFlag = false; packagename = packagename || extname; for (let i in pack) { - if (i == 'mode') { + if (i == "mode") { if (pack[i] == "guozhan") gzFlag = true; continue; } - if (i == 'forbid') continue; + if (i == "forbid") continue; for (let j in pack[i]) { - if (i == 'character') { + if (i == "character") { if (!pack[i][j][4]) { pack[i][j][4] = []; } let imgsrc; if (_status.evaluatingExtension) { - imgsrc = 'db:extension-' + extname + ':' + j + '.jpg'; + imgsrc = "db:extension-" + extname + ":" + j + ".jpg"; + } else { + imgsrc = "ext:" + extname + "/" + j + ".jpg"; } - else { - imgsrc = 'ext:' + extname + '/' + j + '.jpg'; - } - const audiosrc = 'die:ext:' + extname + '/' + j + '.mp3'; - if (!pack[i][j][4].some(str => typeof str == "string" && /^(?:db:extension-|ext:):(?:.+)/.test(str))) pack[i][j][4].add(imgsrc); - if (!pack[i][j][4].some(str => typeof str == "string" && /^die:(?:.+)/.test(str))) pack[i][j][4].add(audiosrc); - if (pack[i][j][4].includes('boss') || - pack[i][j][4].includes('hiddenboss')) { + const audiosrc = "die:ext:" + extname + "/" + j + ".mp3"; + if ( + !pack[i][j][4].some( + (str) => typeof str == "string" && /^(?:db:extension-|ext:):(?:.+)/.test(str) + ) + ) + pack[i][j][4].add(imgsrc); + if (!pack[i][j][4].some((str) => typeof str == "string" && /^die:(?:.+)/.test(str))) + pack[i][j][4].add(audiosrc); + if (pack[i][j][4].includes("boss") || pack[i][j][4].includes("hiddenboss")) { lib.config.forbidai.add(j); } if (lib.config.forbidai_user && lib.config.forbidai_user.includes(j)) { @@ -4417,18 +4751,17 @@ export class Game extends Uninstantable { for (var l = 0; l < pack[i][j][3].length; l++) { lib.skilllist.add(pack[i][j][3][l]); } - } - else if (i == 'skill') { - if (typeof pack[i][j].audio == 'number' || typeof pack[i][j].audio == 'boolean') { - pack[i][j].audio = 'ext:' + extname + ':' + pack[i][j].audio; + } else if (i == "skill") { + if (typeof pack[i][j].audio == "number" || typeof pack[i][j].audio == "boolean") { + pack[i][j].audio = "ext:" + extname + ":" + pack[i][j].audio; } } if (lib[i][j] == undefined) { // 判断扩展武将包是否开启 - if (i == 'character') { + if (i == "character") { // if (!game.hasExtension(extname) || !game.hasExtensionLoaded(extname)) continue; if (lib.config[`extension_${extname}_characters_enable`] === undefined) { - game.saveExtensionConfig(extname, 'characters_enable', true); + game.saveExtensionConfig(extname, "characters_enable", true); } if (lib.config[`extension_${extname}_characters_enable`] === true) { lib[i][j] = pack[i][j]; @@ -4437,114 +4770,110 @@ export class Game extends Uninstantable { } } } - let packname = 'mode_extension_' + packagename; + let packname = "mode_extension_" + packagename; lib.characterPack[packname] = pack.character; - lib.translate[packname + '_character_config'] = packagename; + lib.translate[packname + "_character_config"] = packagename; if (gzFlag) lib.characterGuozhanFilter.add(packname); } /** - * @param { string } name - * @param { Card } info - * @param { { extension: string, translate: string, description: string, number?: number, color?: string } } info2 + * @param { string } name + * @param { Card } info + * @param { { extension: string, translate: string, description: string, number?: number, color?: string } } info2 */ - static addCard(name, info, info2) { - var extname = (_status.extension || info2.extension); + addCard(name, info, info2) { + var extname = _status.extension || info2.extension; if (info.audio == true) { - info.audio = 'ext:' + extname; + info.audio = "ext:" + extname; } if (info.fullskin) { if (_status.evaluatingExtension) { - info.image = 'db:extension-' + extname + ':' + name + '.png'; + info.image = "db:extension-" + extname + ":" + name + ".png"; + } else { + info.image = "ext:" + extname + "/" + name + ".png"; } - else { - info.image = 'ext:' + extname + '/' + name + '.png'; - } - } - else if (info.fullimage) { + } else if (info.fullimage) { if (_status.evaluatingExtension) { - info.image = 'db:extension-' + extname + ':' + name + '.jpg'; - } - else { - info.image = 'ext:' + extname + '/' + name + '.jpg'; + info.image = "db:extension-" + extname + ":" + name + ".jpg"; + } else { + info.image = "ext:" + extname + "/" + name + ".jpg"; } } lib.card[name] = info; lib.translate[name] = info2.translate; - lib.translate[name + '_info'] = info2.description; - if (typeof info2.number == 'number') { - let suits = ['heart', 'spade', 'diamond', 'club']; - if (info2.color == 'red') { - suits = ['heart', 'diamond']; - } - else if (info2.color == 'black') { - suits = ['club', 'spade']; + lib.translate[name + "_info"] = info2.description; + if (typeof info2.number == "number") { + let suits = ["heart", "spade", "diamond", "club"]; + if (info2.color == "red") { + suits = ["heart", "diamond"]; + } else if (info2.color == "black") { + suits = ["club", "spade"]; } for (let i = 0; i < info2.number; i++) { - lib.card.list.push([suits[Math.floor(Math.random() * suits.length)], Math.ceil(Math.random() * 13), name]); + lib.card.list.push([ + suits[Math.floor(Math.random() * suits.length)], + Math.ceil(Math.random() * 13), + name, + ]); } } - let packname = 'mode_extension_' + extname; + let packname = "mode_extension_" + extname; if (!lib.cardPack[packname]) { lib.cardPack[packname] = []; - lib.translate[packname + '_card_config'] = extname; + lib.translate[packname + "_card_config"] = extname; } lib.cardPack[packname].push(name); } /** - * @param { { extension: string, mode?: string[], forbid?: string[], list: any[], card: {[key: string]: Card}, skill: { [key: string]: object } } } pack - * @param { string } [packagename] + * @param { { extension: string, mode?: string[], forbid?: string[], list: any[], card: {[key: string]: Card}, skill: { [key: string]: object } } } pack + * @param { string } [packagename] */ - static addCardPack(pack, packagename) { - let extname = _status.extension || '扩展'; + addCardPack(pack, packagename) { + let extname = _status.extension || "扩展"; packagename = packagename || extname; - let packname = 'mode_extension_' + packagename; + let packname = "mode_extension_" + packagename; lib.cardPack[packname] = []; lib.cardPackInfo[packname] = pack; - lib.translate[packname + '_card_config'] = packagename; + lib.translate[packname + "_card_config"] = packagename; for (let i in pack) { - if (i == 'mode' || i == 'forbid') continue; - if (i == 'list') { + if (i == "mode" || i == "forbid") continue; + if (i == "list") { for (let j = 0; j < pack[i].length; j++) { lib.card.list.push(pack[i][j]); } continue; } for (let j in pack[i]) { - if (i == 'card') { + if (i == "card") { if (pack[i][j].audio == true) { - pack[i][j].audio = 'ext:' + extname; + pack[i][j].audio = "ext:" + extname; } - if(!pack[i][j].image){ + if (!pack[i][j].image) { if (pack[i][j].fullskin) { if (_status.evaluatingExtension) { - pack[i][j].image = 'db:extension-' + extname + ':' + j + '.png'; + pack[i][j].image = "db:extension-" + extname + ":" + j + ".png"; + } else { + pack[i][j].image = "ext:" + extname + "/" + j + ".png"; } - else { - pack[i][j].image = 'ext:' + extname + '/' + j + '.png'; - } - } - else if (pack[i][j].fullimage) { + } else if (pack[i][j].fullimage) { if (_status.evaluatingExtension) { - pack[i][j].image = 'db:extension-' + extname + ':' + j + '.jpg'; - } - else { - pack[i][j].image = 'ext:' + extname + '/' + j + '.jpg'; + pack[i][j].image = "db:extension-" + extname + ":" + j + ".jpg"; + } else { + pack[i][j].image = "ext:" + extname + "/" + j + ".jpg"; } } } lib.cardPack[packname].push(j); - } - else if (i == 'skill') { - if (typeof pack[i][j].audio == 'number' || typeof pack[i][j].audio == 'boolean') { - pack[i][j].audio = 'ext:' + extname + ':' + pack[i][j].audio; + } else if (i == "skill") { + if (typeof pack[i][j].audio == "number" || typeof pack[i][j].audio == "boolean") { + pack[i][j].audio = "ext:" + extname + ":" + pack[i][j].audio; } } if (lib[i][j] == undefined) { // 判断扩展卡牌包是否开启 - if (i == 'card') { + if (i == "card") { // if (!game.hasExtension(extname) || !game.hasExtensionLoaded(extname)) continue; if (lib.config[`extension_${extname}_cards_enable`] === undefined) { - game.saveExtensionConfig(extname, 'cards_enable', true); + game.saveExtensionConfig(extname, "cards_enable", true); } if (lib.config[`extension_${extname}_cards_enable`] === true) { lib[i][j] = pack[i][j]; @@ -4555,51 +4884,50 @@ export class Game extends Uninstantable { } } /** - * @param { string } name - * @param { { [key: string]: object } } info - * @param { string } [translate] - * @param { string } [description] - * @param { string } [appendInfo] - * @param { string } [abInfo] + * @param { string } name + * @param { { [key: string]: object } } info + * @param { string } [translate] + * @param { string } [description] + * @param { string } [appendInfo] + * @param { string } [abInfo] */ - static addSkill(name, info, translate, description, appendInfo, abInfo) { + addSkill(name, info, translate, description, appendInfo, abInfo) { if (lib.skill[name]) { return false; } - if (typeof info.audio == 'number' || typeof info.audio == 'boolean') { - info.audio = 'ext:' + _status.extension + ':' + info.audio; + if (typeof info.audio == "number" || typeof info.audio == "boolean") { + info.audio = "ext:" + _status.extension + ":" + info.audio; } lib.skill[name] = info; lib.translate[name] = translate; - lib.translate[name + '_info'] = description; - lib.translate[name + '_append'] = appendInfo; + lib.translate[name + "_info"] = description; + lib.translate[name + "_append"] = appendInfo; lib.translate[`${name}_ab`] = abInfo; return true; } /** - * @param { string } name - * @param {*} info - * @param { { translate: string, config: { [key: string]: object } } } info2 + * @param { string } name + * @param {*} info + * @param { { translate: string, config: { [key: string]: object } } } info2 */ - static addMode(name, info, info2) { + addMode(name, info, info2) { lib.config.all.mode.push(name); lib.translate[name] = info2.translate; let imgsrc; let extname = _status.extension || info2.extension; if (_status.evaluatingExtension) { - imgsrc = 'extension-' + extname + ':' + name + '.jpg'; - } - else { - imgsrc = 'ext:' + extname + '/' + name + '.jpg'; + imgsrc = "extension-" + extname + ":" + name + ".jpg"; + } else { + imgsrc = "ext:" + extname + "/" + name + ".jpg"; } lib.mode[name] = { name: info2.translate, config: info2.config, splash: imgsrc, - fromextension: true - } - lib.init['setMode_' + name] = async () => { - await game.import('mode', (lib, game, ui, get, ai, _status) => { + fromextension: true, + }; + lib.init["setMode_" + name] = async () => { + await game.import("mode", (lib, game, ui, get, ai, _status) => { info.name = name; return info; }); @@ -4613,13 +4941,13 @@ export class Game extends Uninstantable { if (lib.config.extensionInfo[extname].mode.indexOf(name) == -1) { lib.config.extensionInfo[extname].mode.push(name); } - game.saveConfig('extensionMode', lib.config.extensionInfo); + game.saveConfig("extensionMode", lib.config.extensionInfo); } /** - * @param { string } skill - * @param { Player } [player] + * @param { string } skill + * @param { Player } [player] */ - static addGlobalSkill(skill, player) { + addGlobalSkill(skill, player) { let info = lib.skill[skill]; if (!info) return false; lib.skill.global.add(skill); @@ -4631,18 +4959,17 @@ export class Game extends Uninstantable { } if (info.trigger) { let setTrigger = function (i, evt) { - let name = i + '_' + evt; + let name = i + "_" + evt; if (!lib.hook.globalskill[name]) { lib.hook.globalskill[name] = []; } lib.hook.globalskill[name].add(skill); lib.hookmap[evt] = true; - } + }; for (let i in info.trigger) { - if (typeof info.trigger[i] == 'string') { + if (typeof info.trigger[i] == "string") { setTrigger(i, info.trigger[i]); - } - else if (Array.isArray(info.trigger[i])) { + } else if (Array.isArray(info.trigger[i])) { for (let j = 0; j < info.trigger[i].length; j++) { setTrigger(i, info.trigger[i][j]); } @@ -4652,16 +4979,22 @@ export class Game extends Uninstantable { return true; } /** - * @param { string } skill + * @param { string } skill + * @param { lib.element.Player } player */ - static removeGlobalSkill(skill) { + removeGlobalSkill(skill, player) { + const players = lib.skill.globalmap[skill]; + if (player && Array.isArray(players)) { + lib.skill.globalmap[skill].remove(player); + if (players.length) return; + } lib.skill.global.remove(skill); delete lib.skill.globalmap[skill]; for (let i in lib.hook.globalskill) { lib.hook.globalskill[i].remove(skill); } } - static resetSkills() { + resetSkills() { for (let i = 0; i < game.players.length; i++) { for (let j in game.players[i].tempSkills) { game.players[i].removeSkill(j); @@ -4679,29 +5012,32 @@ export class Game extends Uninstantable { /** * @param { string } extensionName */ - static hasExtension(extensionName) { - if (typeof lib.config[`extension_${extensionName}_enable`] != 'boolean') { - game.saveExtensionConfig(extensionName, 'enable', true); + hasExtension(extensionName) { + if (this.hasExtensionInstalled(extensionName)) { + if (typeof lib.config[`extension_${extensionName}_enable`] != "boolean") { + game.saveExtensionConfig(extensionName, "enable", true); + } + return lib.config[`extension_${extensionName}_enable`] === true; } - return this.hasExtensionInstalled(extensionName) && lib.config[`extension_${extensionName}_enable`]; + return false; } /** * @param { string } extensionName */ - static hasExtensionInstalled(extensionName) { + hasExtensionInstalled(extensionName) { return lib.config.extensions.includes(extensionName); } /** * @param { string } extensionName */ - static hasExtensionLoaded(extensionName) { + hasExtensionLoaded(extensionName) { return extensionName !== void 0 && _status.extensionLoaded.includes(extensionName); } /** - * @param { string } extensionName - * @param { Function } runnable + * @param { string } extensionName + * @param { Function } runnable */ - static runAfterExtensionLoaded(extensionName, runnable) { + runAfterExtensionLoaded(extensionName, runnable) { if (game.hasExtensionLoaded(extensionName)) { runnable(); } else { @@ -4714,30 +5050,33 @@ export class Game extends Uninstantable { } } /** - * @param { string } extensionName - * @param { boolean } [keepFile] + * @param { string } extensionName + * @param { boolean } [keepFile] */ - static removeExtension(extensionName, keepFile) { + removeExtension(extensionName, keepFile) { const prefix = `extension_${extensionName}`; - Object.keys(lib.config).forEach(key => { + Object.keys(lib.config).forEach((key) => { if (key.startsWith(prefix)) game.saveConfig(key); }); localStorage.removeItem(`${lib.configprefix}${prefix}`); - game.deleteDB('data', prefix); + game.deleteDB("data", prefix); lib.config.extensions.remove(extensionName); - game.saveConfig('extensions', lib.config.extensions); + game.saveConfig("extensions", lib.config.extensions); const modeList = lib.config.extensionInfo[extensionName]; if (modeList) { - if (modeList.file) Object.values(modeList.file).forEach(filePath => game.deleteDB('image', `extension-${extensionName}:${filePath}`)); + if (modeList.file) + Object.values(modeList.file).forEach((filePath) => + game.deleteDB("image", `extension-${extensionName}:${filePath}`) + ); if (modeList.mode) Object.values(modeList.mode).forEach(game.clearModeConfig); delete lib.config.extensionInfo[extensionName]; - game.saveConfigValue('extensionInfo'); + game.saveConfigValue("extensionInfo"); } if (!game.download || keepFile) return; - game.promises.removeDir(`${nonameInitialized}extension/${extensionName}`).catch(console.error); + game.promises.removeDir(`extension/${extensionName}`).catch(console.error); } - static addRecentCharacter() { - let list = get.config('recentCharacter') || []; + addRecentCharacter() { + let list = get.config("recentCharacter") || []; for (let i = 0; i < arguments.length; i++) { if (lib.character[arguments[i]]) { list.remove(arguments[i]); @@ -4748,7 +5087,7 @@ export class Game extends Uninstantable { if (list.length > num) { list.splice(num); } - game.saveConfig('recentCharacter', list, true); + game.saveConfig("recentCharacter", list, true); } /** * @overload @@ -4756,23 +5095,23 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { Card | string } name - * @param { string } [suit] - * @param { number | string } [number] - * @param { string } [nature] + * @param { Card | string } name + * @param { string } [suit] + * @param { number | string } [number] + * @param { string } [nature] */ - static createCard(name, suit, number, nature) { - if (typeof name == 'object') { + createCard(name, suit, number, nature) { + if (typeof name == "object") { nature = name.nature; number = name.number; suit = name.suit; name = name.name; } - if (typeof name != 'string') { - name = 'sha'; + if (typeof name != "string") { + name = "sha"; } let noclick = false; - if (suit == 'noclick') { + if (suit == "noclick") { noclick = true; suit = null; } @@ -4782,23 +5121,20 @@ export class Game extends Uninstantable { if (!nature && lib.card[name].cardnature) { nature = lib.card[name].cardnature; } - if (typeof suit != 'string') { - suit = ['heart', 'diamond', 'club', 'spade'].randomGet(); + if (typeof suit != "string") { + suit = ["heart", "diamond", "club", "spade"].randomGet(); + } else if (suit == "black") { + suit = Math.random() < 0.5 ? "club" : "spade"; + } else if (suit == "red") { + suit = Math.random() < 0.5 ? "diamond" : "heart"; } - else if (suit == 'black') { - suit = Math.random() < 0.5 ? 'club' : 'spade'; - } - else if (suit == 'red') { - suit = Math.random() < 0.5 ? 'diamond' : 'heart'; - } - if (typeof number != 'number' && typeof number != 'string') { + if (typeof number != "number" && typeof number != "string") { number = Math.ceil(Math.random() * 13); } let card; if (noclick) { - card = ui.create.card(ui.special, 'noclick', true); - } - else { + card = ui.create.card(ui.special, "noclick", true); + } else { card = ui.create.card(ui.special); } card.storage.vanish = true; @@ -4810,37 +5146,37 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { Card | string } name - * @param { string } suit - * @param { number } number - * @param { string } nature + * @param { Card | string } name + * @param { string } suit + * @param { number } number + * @param { string } nature */ - static createCard2() { + createCard2() { let card = game.createCard.apply(this, arguments); delete card.storage.vanish; return card; } /** - * @param { boolean } bool - * @param { Function } callback + * @param { boolean } bool + * @param { Function } callback */ - static forceOver(bool, callback) { + forceOver(bool, callback) { _status.event.next.length = 0; - let next = game.createEvent('finish_game'); + let next = game.createEvent("finish_game"); next.bool = bool; next.callback = callback; - next.setContent('forceOver'); + next.setContent("forceOver"); if (_status.paused) { game.uncheck(); game.resume(); } } /** - * @param { boolean | string } [result] - * @param { boolean } [bool] - * @returns + * @param { boolean | string } [result] + * @param { boolean } [bool] + * @returns */ - static over(result, bool) { + over(result, bool) { if (_status.over) return; if (game.me._trueMe) game.swapPlayer(game.me._trueMe); let i, j, k, num, table, tr, td, dialog; @@ -4851,13 +5187,13 @@ export class Game extends Uninstantable { if (ui.time3) { clearInterval(ui.time3.interval); } - if ((game.layout == 'long2' || game.layout == 'nova') && !game.chess) { - ui.arena.classList.add('choose-character'); + if ((game.layout == "long2" || game.layout == "nova") && !game.chess) { + ui.arena.classList.add("choose-character"); ui.me.hide(); - ui.mebg.hide() + ui.mebg.hide(); ui.autonode.hide(); - if (lib.config.radius_size != 'off') { - ui.historybar.style.borderRadius = '0 0 0 4px'; + if (lib.config.radius_size != "off") { + ui.historybar.style.borderRadius = "0 0 0 4px"; } } if (game.online) { @@ -4867,39 +5203,36 @@ export class Game extends Uninstantable { dialog.forcebutton = true; let result2 = arguments[1]; if (result2 == true) { - dialog.content.firstChild.innerHTML = '战斗胜利'; - } - else if (result2 == false) { - dialog.content.firstChild.innerHTML = '战斗失败'; + dialog.content.firstChild.innerHTML = "战斗胜利"; + } else if (result2 == false) { + dialog.content.firstChild.innerHTML = "战斗失败"; } ui.update(); - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); for (let i = 0; i < game.players.length; i++) { - let hs = game.players[i].getCards('h'); + let hs = game.players[i].getCards("h"); if (hs.length) { - dialog.add('
                                    ' + get.translation(game.players[i]) + '
                                    '); + dialog.add('
                                    ' + get.translation(game.players[i]) + "
                                    "); dialog.addSmall(hs); } } for (let j = 0; j < game.dead.length; j++) { - let hs = game.dead[j].getCards('h'); + let hs = game.dead[j].getCards("h"); if (hs.length) { - dialog.add('
                                    ' + get.translation(game.dead[j]) + '
                                    '); + dialog.add('
                                    ' + get.translation(game.dead[j]) + "
                                    "); dialog.addSmall(hs); } } - dialog.add(ui.create.div('.placeholder.slim')); + dialog.add(ui.create.div(".placeholder.slim")); if (lib.config.background_audio) { if (result2 === true) { - game.playAudio('effect', 'win'); - } - else if (result2 === false) { - game.playAudio('effect', 'lose'); - } - else { - game.playAudio('effect', 'tie'); + game.playAudio("effect", "win"); + } else if (result2 === false) { + game.playAudio("effect", "lose"); + } else { + game.playAudio("effect", "tie"); } } if (!ui.exit) { @@ -4910,12 +5243,12 @@ export class Game extends Uninstantable { delete ui.giveup; } if (game.servermode) { - ui.exit.firstChild.innerHTML = '返回房间'; + ui.exit.firstChild.innerHTML = "返回房间"; setTimeout(function () { - ui.exit.firstChild.innerHTML = '退出房间'; + ui.exit.firstChild.innerHTML = "退出房间"; _status.roomtimeout = true; lib.config.reconnect_info[2] = null; - game.saveConfig('reconnect_info', lib.config.reconnect_info); + game.saveConfig("reconnect_info", lib.config.reconnect_info); }, 10000); } if (ui.tempnowuxie) { @@ -4933,33 +5266,31 @@ export class Game extends Uninstantable { } if (lib.config.background_audio) { if (result === true) { - game.playAudio('effect', 'win'); - } - else if (result === false) { - game.playAudio('effect', 'lose'); - } - else { - game.playAudio('effect', 'tie'); + game.playAudio("effect", "win"); + } else if (result === false) { + game.playAudio("effect", "lose"); + } else { + game.playAudio("effect", "tie"); } } let resultbool = result; - if (typeof resultbool !== 'boolean') { + if (typeof resultbool !== "boolean") { resultbool = null; } - if (result === true) result = '战斗胜利'; - if (result === false) result = '战斗失败'; - if (result == undefined) result = '战斗结束'; + if (result === true) result = "战斗胜利"; + if (result === false) result = "战斗失败"; + if (result == undefined) result = "战斗结束"; dialog = ui.create.dialog(result); dialog.noforcebutton = true; dialog.forcebutton = true; if (game.addOverDialog) { game.addOverDialog(dialog, result); } - if (typeof _status.coin == 'number' && !_status.connectMode) { + if (typeof _status.coin == "number" && !_status.connectMode) { let coeff = Math.random() * 0.4 + 0.8; let added = 0; let betWin = false; - if (result == '战斗胜利') { + if (result == "战斗胜利") { if (_status.betWin) { betWin = true; _status.coin += 10; @@ -4969,41 +5300,40 @@ export class Game extends Uninstantable { _status.coin += _status.additionalReward(); } switch (lib.config.mode) { - case 'identity': { + case "identity": { switch (game.me.identity) { - case 'zhu': case 'zhong': case 'mingzhong': - if (get.config('enhance_zhu')) { + case "zhu": + case "zhong": + case "mingzhong": + if (get.config("enhance_zhu")) { added = 10; - } - else { + } else { added = 20; } break; - case 'fan': - if (get.config('enhance_zhu')) { + case "fan": + if (get.config("enhance_zhu")) { added = 16; - } - else { + } else { added = 8; } break; - case 'nei': + case "nei": added = 40; break; } - added = added * (game.players.length + game.dead.length) / 8; + added = (added * (game.players.length + game.dead.length)) / 8; break; } - case 'guozhan': - if (game.me.identity == 'ye') { + case "guozhan": + if (game.me.identity == "ye") { added = 8; - } - else { + } else { added = 5 / get.totalPopulation(game.me.identity); } added = added * (game.players.length + game.dead.length); break; - case 'versus': + case "versus": if (_status.friend) { added = 5 * (game.players.length + _status.friend.length); } @@ -5011,11 +5341,10 @@ export class Game extends Uninstantable { default: added = 10; } - } - else { + } else { added = 10; } - if (lib.config.mode == 'chess' && _status.mode == 'combat' && get.config('additional_player')) { + if (lib.config.mode == "chess" && _status.mode == "combat" && get.config("additional_player")) { added = 2; } _status.coin += added * coeff; @@ -5023,48 +5352,42 @@ export class Game extends Uninstantable { _status.coin *= _status.coinCoeff; } _status.coin = Math.ceil(_status.coin); - dialog.add(ui.create.div('', '获得' + _status.coin + '金')); + dialog.add(ui.create.div("", "获得" + _status.coin + "金")); if (betWin) { game.changeCoin(20); - dialog.content.appendChild(document.createElement('br')); - dialog.add(ui.create.div('', '(下注赢得10金)')); + dialog.content.appendChild(document.createElement("br")); + dialog.add(ui.create.div("", "(下注赢得10金)")); } game.changeCoin(_status.coin); } - if (get.mode() == 'versus' && _status.ladder) { + if (get.mode() == "versus" && _status.ladder) { let mmr = _status.ladder_mmr; mmr += 10 - get.rank(game.me.name, true) * 2; - if (result == '战斗胜利') { + if (result == "战斗胜利") { mmr = 20 + Math.round(mmr); if (mmr > 40) { mmr = 40; - } - else if (mmr < 10) { + } else if (mmr < 10) { mmr = 10; } - dialog.add(ui.create.div('', '获得 ' + mmr + ' 积分')); - } - else { + dialog.add(ui.create.div("", "获得 " + mmr + " 积分")); + } else { mmr = -30 + Math.round(mmr / 2); if (mmr > -20) { mmr = -20; - } - else if (mmr < -35) { + } else if (mmr < -35) { mmr = -35; } if (lib.storage.ladder.current < 900) { mmr = Math.round(mmr / 4); - } - else if (lib.storage.ladder.current < 1400) { + } else if (lib.storage.ladder.current < 1400) { mmr = Math.round(mmr / 2); - } - else if (lib.storage.ladder.current < 2000) { + } else if (lib.storage.ladder.current < 2000) { mmr = Math.round(mmr / 1.5); - } - else if (lib.storage.ladder.current > 2500) { + } else if (lib.storage.ladder.current > 2500) { mmr = Math.round(mmr * 1.5); } - dialog.add(ui.create.div('', '失去 ' + (-mmr) + ' 积分')); + dialog.add(ui.create.div("", "失去 " + -mmr + " 积分")); } if (_status.ladder_tmp) { lib.storage.ladder.current += 40; @@ -5074,59 +5397,61 @@ export class Game extends Uninstantable { if (lib.storage.ladder.top < lib.storage.ladder.current) { lib.storage.ladder.top = lib.storage.ladder.current; } - game.save('ladder', lib.storage.ladder); + game.save("ladder", lib.storage.ladder); if (ui.ladder && game.getLadderName) { ui.ladder.innerHTML = game.getLadderName(lib.storage.ladder.current); } } // if(true){ if (game.players.length) { - table = document.createElement('table'); - tr = document.createElement('tr'); - tr.appendChild(document.createElement('td')); - td = document.createElement('td'); - td.innerHTML = '伤害'; + table = document.createElement("table"); + tr = document.createElement("tr"); + tr.appendChild(document.createElement("td")); + td = document.createElement("td"); + td.innerHTML = "伤害"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '受伤'; + td = document.createElement("td"); + td.innerHTML = "受伤"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '摸牌'; + td = document.createElement("td"); + td.innerHTML = "摸牌"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '出牌'; + td = document.createElement("td"); + td.innerHTML = "出牌"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '杀敌'; + td = document.createElement("td"); + td.innerHTML = "杀敌"; tr.appendChild(td); table.appendChild(tr); for (i = 0; i < game.players.length; i++) { - tr = document.createElement('tr'); - td = document.createElement('td'); - td.innerHTML = get.translation(game.players[i]) + (game.players[i].ai.stratagem_camouflage ? '(被伪装)' : ''); + tr = document.createElement("tr"); + td = document.createElement("td"); + td.innerHTML = + get.translation(game.players[i]) + + (game.players[i].ai.stratagem_camouflage ? "(被伪装)" : ""); tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.players[i].stat.length; j++) { if (game.players[i].stat[j].damage != undefined) num += game.players[i].stat[j].damage; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.players[i].stat.length; j++) { if (game.players[i].stat[j].damaged != undefined) num += game.players[i].stat[j].damaged; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.players[i].stat.length; j++) { if (game.players[i].stat[j].gain != undefined) num += game.players[i].stat[j].gain; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.players[i].stat.length; j++) { for (k in game.players[i].stat[j].card) { @@ -5135,7 +5460,7 @@ export class Game extends Uninstantable { } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.players[i].stat.length; j++) { if (game.players[i].stat[j].kill != undefined) num += game.players[i].stat[j].kill; @@ -5144,59 +5469,60 @@ export class Game extends Uninstantable { tr.appendChild(td); table.appendChild(tr); } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); dialog.content.appendChild(table); } if (game.dead.length) { - table = document.createElement('table'); - table.style.opacity = '0.5'; + table = document.createElement("table"); + table.style.opacity = "0.5"; if (game.players.length == 0) { - tr = document.createElement('tr'); - tr.appendChild(document.createElement('td')); - td = document.createElement('td'); - td.innerHTML = '伤害'; + tr = document.createElement("tr"); + tr.appendChild(document.createElement("td")); + td = document.createElement("td"); + td.innerHTML = "伤害"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '受伤'; + td = document.createElement("td"); + td.innerHTML = "受伤"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '摸牌'; + td = document.createElement("td"); + td.innerHTML = "摸牌"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '出牌'; + td = document.createElement("td"); + td.innerHTML = "出牌"; tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '杀敌'; + td = document.createElement("td"); + td.innerHTML = "杀敌"; tr.appendChild(td); table.appendChild(tr); } for (i = 0; i < game.dead.length; i++) { - tr = document.createElement('tr'); - td = document.createElement('td'); - td.innerHTML = get.translation(game.dead[i]) + (game.dead[i].ai.stratagem_camouflage ? '(被伪装)' : ''); + tr = document.createElement("tr"); + td = document.createElement("td"); + td.innerHTML = + get.translation(game.dead[i]) + (game.dead[i].ai.stratagem_camouflage ? "(被伪装)" : ""); tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.dead[i].stat.length; j++) { if (game.dead[i].stat[j].damage != undefined) num += game.dead[i].stat[j].damage; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.dead[i].stat.length; j++) { if (game.dead[i].stat[j].damaged != undefined) num += game.dead[i].stat[j].damaged; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.dead[i].stat.length; j++) { if (game.dead[i].stat[j].gain != undefined) num += game.dead[i].stat[j].gain; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.dead[i].stat.length; j++) { for (k in game.dead[i].stat[j].card) { @@ -5205,7 +5531,7 @@ export class Game extends Uninstantable { } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.dead[i].stat.length; j++) { if (game.dead[i].stat[j].kill != undefined) num += game.dead[i].stat[j].kill; @@ -5214,39 +5540,42 @@ export class Game extends Uninstantable { tr.appendChild(td); table.appendChild(tr); } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); dialog.content.appendChild(table); } if (game.additionaldead && game.additionaldead.length) { - table = document.createElement('table'); - table.style.opacity = '0.5'; + table = document.createElement("table"); + table.style.opacity = "0.5"; for (i = 0; i < game.additionaldead.length; i++) { - tr = document.createElement('tr'); - td = document.createElement('td'); + tr = document.createElement("tr"); + td = document.createElement("td"); td.innerHTML = get.translation(game.additionaldead[i]); tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.additionaldead[i].stat.length; j++) { - if (game.additionaldead[i].stat[j].damage != undefined) num += game.additionaldead[i].stat[j].damage; + if (game.additionaldead[i].stat[j].damage != undefined) + num += game.additionaldead[i].stat[j].damage; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.additionaldead[i].stat.length; j++) { - if (game.additionaldead[i].stat[j].damaged != undefined) num += game.additionaldead[i].stat[j].damaged; + if (game.additionaldead[i].stat[j].damaged != undefined) + num += game.additionaldead[i].stat[j].damaged; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.additionaldead[i].stat.length; j++) { - if (game.additionaldead[i].stat[j].gain != undefined) num += game.additionaldead[i].stat[j].gain; + if (game.additionaldead[i].stat[j].gain != undefined) + num += game.additionaldead[i].stat[j].gain; } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.additionaldead[i].stat.length; j++) { for (k in game.additionaldead[i].stat[j].card) { @@ -5255,20 +5584,21 @@ export class Game extends Uninstantable { } td.innerHTML = num; tr.appendChild(td); - td = document.createElement('td'); + td = document.createElement("td"); num = 0; for (j = 0; j < game.additionaldead[i].stat.length; j++) { - if (game.additionaldead[i].stat[j].kill != undefined) num += game.additionaldead[i].stat[j].kill; + if (game.additionaldead[i].stat[j].kill != undefined) + num += game.additionaldead[i].stat[j].kill; } td.innerHTML = num; tr.appendChild(td); table.appendChild(tr); } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); dialog.content.appendChild(table); } // } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); let clients = game.players.concat(game.dead); for (let i = 0; i < clients.length; i++) { @@ -5277,29 +5607,30 @@ export class Game extends Uninstantable { } } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); for (let i = 0; i < game.players.length; i++) { - if (!_status.connectMode && game.players[i].isUnderControl(true) && game.layout != 'long2') continue; - let hs = game.players[i].getCards('h'); + if (!_status.connectMode && game.players[i].isUnderControl(true) && game.layout != "long2") + continue; + let hs = game.players[i].getCards("h"); if (hs.length) { - dialog.add('
                                    ' + get.translation(game.players[i]) + '
                                    '); + dialog.add('
                                    ' + get.translation(game.players[i]) + "
                                    "); dialog.addSmall(hs); } } for (let i = 0; i < game.dead.length; i++) { - if (!_status.connectMode && game.dead[i].isUnderControl(true) && game.layout != 'long2') continue; - let hs = game.dead[i].getCards('h'); + if (!_status.connectMode && game.dead[i].isUnderControl(true) && game.layout != "long2") continue; + let hs = game.dead[i].getCards("h"); if (hs.length) { - dialog.add('
                                    ' + get.translation(game.dead[i]) + '
                                    '); + dialog.add('
                                    ' + get.translation(game.dead[i]) + "
                                    "); dialog.addSmall(hs); } } - dialog.add(ui.create.div('.placeholder.slim')); - game.addVideo('over', null, dialog.content.innerHTML); + dialog.add(ui.create.div(".placeholder.slim")); + game.addVideo("over", null, dialog.content.innerHTML); let vinum = parseInt(lib.config.video); if (!_status.video && vinum && game.getVideoName && window.indexedDB && _status.videoInited) { - let store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + let store = lib.db.transaction(["video"], "readwrite").objectStore("video"); let videos = lib.videos.slice(0); for (let i = 0; i < videos.length; i++) { if (videos[i].starred) { @@ -5311,8 +5642,7 @@ export class Game extends Uninstantable { let toremove = videos.pop(); lib.videos.remove(toremove); store.delete(toremove.time); - } - else { + } else { break; } } @@ -5322,45 +5652,42 @@ export class Game extends Uninstantable { name: game.getVideoName(), mode: lib.config.mode, video: lib.video, - win: result == '战斗胜利', + win: result == "战斗胜利", name1: me.name1 || me.name, name2: me.name2, - time: lib.getUTC(new Date()) + time: lib.getUTC(new Date()), }; - let modecharacters = lib.characterPack['mode_' + get.mode()]; + let modecharacters = lib.characterPack["mode_" + get.mode()]; if (modecharacters) { - if (get.mode() == 'guozhan') { + if (get.mode() == "guozhan") { if (modecharacters[newvid.name1]) { - if (newvid.name1.startsWith('gz_shibing')) { + if (newvid.name1.startsWith("gz_shibing")) { newvid.name1 = newvid.name1.slice(3, 11); - } - else { + } else { newvid.name1 = newvid.name1.slice(3); } } if (modecharacters[newvid.name2]) { - if (newvid.name2.startsWith('gz_shibing')) { + if (newvid.name2.startsWith("gz_shibing")) { newvid.name2 = newvid.name2.slice(3, 11); - } - else { + } else { newvid.name2 = newvid.name2.slice(3); } } - } - else { + } else { if (modecharacters[newvid.name1]) { - newvid.name1 = get.mode() + '::' + newvid.name1; + newvid.name1 = get.mode() + "::" + newvid.name1; } if (modecharacters[newvid.name2]) { - newvid.name2 = get.mode() + '::' + newvid.name2; + newvid.name2 = get.mode() + "::" + newvid.name2; } } } - if (newvid.name1 && newvid.name1.startsWith('subplayer_')) { - newvid.name1 = newvid.name1.slice(10, newvid.name1.lastIndexOf('_')); + if (newvid.name1 && newvid.name1.startsWith("subplayer_")) { + newvid.name1 = newvid.name1.slice(10, newvid.name1.lastIndexOf("_")); } - if (newvid.name2 && newvid.name2.startsWith('subplayer_')) { - newvid.name1 = newvid.name2.slice(10, newvid.name1.lastIndexOf('_')); + if (newvid.name2 && newvid.name2.startsWith("subplayer_")) { + newvid.name1 = newvid.name2.slice(10, newvid.name1.lastIndexOf("_")); } lib.videos.unshift(newvid); store.put(newvid); @@ -5378,24 +5705,37 @@ export class Game extends Uninstantable { } if (lib.config.test_game && !_status.connectMode) { - if (typeof lib.config.test_game !== 'string') { + if (typeof lib.config.test_game !== "string") { switch (lib.config.mode) { - case 'identity': game.saveConfig('mode', 'guozhan'); break; - case 'guozhan': game.saveConfig('mode', 'versus'); break; - case 'versus': game.saveConfig('mode', 'boss'); break; - case 'boss': game.saveConfig('mode', 'chess'); break; - case 'chess': game.saveConfig('mode', 'stone'); break; - case 'stone': game.saveConfig('mode', 'identity'); break; + case "identity": + game.saveConfig("mode", "guozhan"); + break; + case "guozhan": + game.saveConfig("mode", "versus"); + break; + case "versus": + game.saveConfig("mode", "boss"); + break; + case "boss": + game.saveConfig("mode", "chess"); + break; + case "chess": + game.saveConfig("mode", "stone"); + break; + case "stone": + game.saveConfig("mode", "identity"); + break; } } setTimeout(game.reload, 500); } if (game.controlOver) { - game.controlOver(); return; + game.controlOver(); + return; } if (!_status.brawl) { - if (lib.config.mode == 'boss') { - ui.create.control('再战', function () { + if (lib.config.mode == "boss") { + ui.create.control("再战", function () { let pointer = game.boss; let map = { boss: game.me == game.boss, links: [] }; for (let iwhile = 0; iwhile < 10; iwhile++) { @@ -5407,45 +5747,48 @@ export class Game extends Uninstantable { map.links.push(pointer.name); } } - game.saveConfig('continue_name_boss', map); - game.saveConfig('mode', lib.config.mode); - localStorage.setItem(lib.configprefix + 'directstart', true); + game.saveConfig("continue_name_boss", map); + game.saveConfig("mode", lib.config.mode); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); }); - } - else if (lib.config.mode == 'versus') { - if (_status.mode == 'standard' || _status.mode == 'three') { - ui.create.control('再战', function () { - game.saveConfig('continue_name_versus' + (_status.mode == 'three' ? '_three' : ''), { + } else if (lib.config.mode == "versus") { + if (_status.mode == "standard" || _status.mode == "three") { + ui.create.control("再战", function () { + game.saveConfig("continue_name_versus" + (_status.mode == "three" ? "_three" : ""), { friend: _status.friendBackup, enemy: _status.enemyBackup, - color: _status.color + color: _status.color, }); - game.saveConfig('mode', lib.config.mode); - localStorage.setItem(lib.configprefix + 'directstart', true); + game.saveConfig("mode", lib.config.mode); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); }); } - } - else if (!_status.connectMode && get.config('continue_game') && !ui.continue_game && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); + } else if ( + !_status.connectMode && + get.config("continue_game") && + !ui.continue_game && + !_status.brawl && + !game.no_continue_game + ) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); } } if (!ui.restart) { - if (game.onlineroom && typeof game.roomId == 'string') { - ui.restart = ui.create.control('restart', function () { + if (game.onlineroom && typeof game.roomId == "string") { + ui.restart = ui.create.control("restart", function () { game.broadcastAll(function () { if (ui.exit) { ui.exit.stay = true; - ui.exit.firstChild.innerHTML = '返回房间'; + ui.exit.firstChild.innerHTML = "返回房间"; } }); - game.saveConfig('tmp_owner_roomId', game.roomId); + game.saveConfig("tmp_owner_roomId", game.roomId); setTimeout(game.reload, 100); }); - } - else { - ui.restart = ui.create.control('restart', game.reload); + } else { + ui.restart = ui.create.control("restart", game.reload); } } if (ui.tempnowuxie) { @@ -5469,43 +5812,63 @@ export class Game extends Uninstantable { } if (window.isNonameServer) { lib.configOL.gameStarted = false; - game.saveConfig('pagecfg' + window.isNonameServer, [lib.configOL, game.roomId, _status.onlinenickname, _status.onlineavatar]); + game.saveConfig("pagecfg" + window.isNonameServer, [ + lib.configOL, + game.roomId, + _status.onlinenickname, + _status.onlineavatar, + ]); game.reload(); - } - else if (_status.connectMode && !game.online) { - setTimeout(game.reload, 15000) + } else if (_status.connectMode && !game.online) { + setTimeout(game.reload, 15000); } } /** * @type { Map> } - * + * * 以Promise储存异步事件的执行链,使async content调用事件时无需必须使用await - * + * * 但是需要事件结果的除外 */ - static executingAsyncEventMap = new Map(); + executingAsyncEventMap = new Map(); /** - * @type { GameEventPromise[] } + * @type { import('../library/index.js').GameEventPromise[] } */ - static belongAsyncEventList = []; + belongAsyncEventList = []; /** - * @param { GameEventPromise } [belongAsyncEvent] + * @param { import('../library/index.js').GameEventPromise } [belongAsyncEvent] */ - static async loop(belongAsyncEvent) { + async loop(belongAsyncEvent) { if (belongAsyncEvent) { game.belongAsyncEventList.push(belongAsyncEvent); } else if (game.belongAsyncEventList.length) { belongAsyncEvent = game.belongAsyncEventList.at(-1); } while (true) { - let event = (belongAsyncEvent && belongAsyncEvent.parent == _status.event) ? belongAsyncEvent : _status.event; - let { step, source, player, target, targets, card, cards, skill, forced, num, _trigger: trigger, _result: result } = event; + let event = + belongAsyncEvent && belongAsyncEvent.parent == _status.event + ? belongAsyncEvent + : _status.event; + let { + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + _trigger: trigger, + _result: result, + } = event; const _resolve = () => { if (event.async) { - if (typeof event.resolve == 'function') { + if (typeof event.resolve == "function") { event.resolve(event.toEvent()); } else { - throw new TypeError('异步事件的event.resolve未赋值,使用await时将会被永久等待'); + throw new TypeError("异步事件的event.resolve未赋值,使用await时将会被永久等待"); } } }; @@ -5518,7 +5881,7 @@ export class Game extends Uninstantable { return; } if (_status.paused3) { - _status.paused3 = 'paused'; + _status.paused3 = "paused"; return; } if (lib.status.dateDelaying) { @@ -5528,46 +5891,40 @@ export class Game extends Uninstantable { if (event.next.length > 0) { var next = event.next.shift(); if (next.player && next.player.skipList.includes(next.name)) { - event.trigger(next.name + 'Skipped'); + event.trigger(next.name + "Skipped"); next.player.skipList.remove(next.name); - if (lib.phaseName.includes(next.name)) next.player.getHistory('skipped').add(next.name); - } - else { + if (lib.phaseName.includes(next.name)) next.player.getHistory("skipped").add(next.name); + } else { next.parent = event; _status.event = next; - game.getGlobalHistory('everything').push(next); + game.getGlobalHistory("everything").push(next); } - } - else if (event.finished) { + } else if (event.finished) { if (event._triggered == 1) { - if (event.type == 'card') event.trigger('useCardToOmitted'); - event.trigger(event.name + 'Omitted'); + if (event.type == "card") event.trigger("useCardToOmitted"); + event.trigger(event.name + "Omitted"); event._triggered = 4; - } - else if (event._triggered == 2) { - if (event.type == 'card') event.trigger('useCardToEnd'); - event.trigger(event.name + 'End'); + } else if (event._triggered == 2) { + if (event.type == "card") event.trigger("useCardToEnd"); + event.trigger(event.name + "End"); event._triggered = 3; - } - else if (event._triggered == 3) { - if (event.type == 'card') event.trigger('useCardToAfter'); - event.trigger(event.name + 'After'); + } else if (event._triggered == 3) { + if (event.type == "card") event.trigger("useCardToAfter"); + event.trigger(event.name + "After"); event._triggered++; - } - else if (event.after && event.after.length) { + } else if (event.after && event.after.length) { var next = event.after.shift(); if (next.player && next.player.skipList.includes(next.name)) { - event.trigger(next.name + 'Skipped'); + event.trigger(next.name + "Skipped"); next.player.skipList.remove(next.name); - if (lib.phaseName.includes(next.name)) next.player.getHistory('skipped').add(next.name) - } - else { + if (lib.phaseName.includes(next.name)) + next.player.getHistory("skipped").add(next.name); + } else { next.parent = event; _status.event = next; - game.getGlobalHistory('everything').push(next); + game.getGlobalHistory("everything").push(next); } - } - else { + } else { game.executingAsyncEventMap.delete(event.toEvent()); if (event.parent) { if (event.result) { @@ -5582,38 +5939,39 @@ export class Game extends Uninstantable { if (belongAsyncEvent && belongAsyncEvent.parent == _status.event) { return; } - } - else { + } else { if (game.belongAsyncEventList.includes(event)) { game.belongAsyncEventList.remove(event); } return _resolve(); } } - } - else { + } else { if (event._triggered == 0) { - if (event.type == 'card') event.trigger('useCardToBefore'); - event.trigger(event.name + 'Before'); + if (event.type == "card") event.trigger("useCardToBefore"); + event.trigger(event.name + "Before"); event._triggered++; - } - else if (event._triggered == 1) { - if (event.type == 'card') event.trigger('useCardToBegin'); - event.trigger(event.name + 'Begin'); + } else if (event._triggered == 1) { + if (event.type == "card") event.trigger("useCardToBegin"); + event.trigger(event.name + "Begin"); event._triggered++; - } - else { + } else { event.callHandler(event.getDefaultHandlerType(), event, { - state: 'begin' + state: "begin", }); const after = () => { event.clearStepCache(); event.callHandler(event.getDefaultHandlerType(), event, { - state: 'end' + state: "end", }); if (typeof event.step == "number") ++event.step; }; - if (player && player.classList.contains('dead') && !event.forceDie && event.name != 'phaseLoop') { + if ( + player && + player.classList.contains("dead") && + !event.forceDie && + event.name != "phaseLoop" + ) { game.broadcastAll(function () { while (_status.dieClose.length) { _status.dieClose.shift().close(); @@ -5624,43 +5982,64 @@ export class Game extends Uninstantable { } event.finish(); after(); - } - else if (player && player.removed && event.name != 'phaseLoop') { + } else if (player && player.removed && event.name != "phaseLoop") { event.finish(); after(); - } - else if (player && player.isOut() && event.name != 'phaseLoop' && !event.includeOut) { - if (event.name == 'phase' && player == _status.roundStart && !event.skill) { + } else if (player && player.isOut() && event.name != "phaseLoop" && !event.includeOut) { + if (event.name == "phase" && player == _status.roundStart && !event.skill) { _status.roundSkipped = true; } event.finish(); after(); - } - else { - await game.runContent(belongAsyncEvent).catch(e => { - if (_status.withError || lib.config.compatiblemode || (_status.connectMode && !lib.config.debug)) { - game.print('游戏出错:' + event.name); - game.print(e.toString()); - console.log(e); - } - else throw e; - }).then(after).then(() => { - if (event.finished) { - game.executingAsyncEventMap.delete(event.toEvent()); - } - }); + } else { + await game + .runContent(belongAsyncEvent) + .catch((e) => { + if ( + _status.withError || + lib.config.compatiblemode || + (_status.connectMode && !lib.config.debug) + ) { + game.print("游戏出错:" + event.name); + game.print(e.toString()); + console.log(e); + } else throw e; + }) + .then(after) + .then(() => { + if (event.finished) { + game.executingAsyncEventMap.delete(event.toEvent()); + } + }); } } } } } /** - * @param { GameEventPromise } [belongAsyncEvent] + * @param { import('../library/index.js').GameEventPromise } [belongAsyncEvent] */ - static runContent(belongAsyncEvent) { - return new Promise(resolve => { - let event = (belongAsyncEvent && belongAsyncEvent.parent == _status.event) ? belongAsyncEvent : _status.event; - let { step, source, player, target, targets, card, cards, skill, forced, num, _trigger: trigger, _result: result, _storeEvent } = event; + runContent(belongAsyncEvent) { + return new Promise((resolve) => { + let event = + belongAsyncEvent && belongAsyncEvent.parent == _status.event + ? belongAsyncEvent + : _status.event; + let { + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + _trigger: trigger, + _result: result, + _storeEvent, + } = event; // 数组形式 if ("contents" in event && Array.isArray(event.contents)) { /* @@ -5681,7 +6060,12 @@ export class Game extends Uninstantable { const run = async (event) => { if (typeof event.step !== "number") event.step = 0; while (event.step < event.contents.length && !event.finished) { - const evt = await event.contents[event.step](event, event._trigger, event.player, event._tmpStoreEvent); + const evt = await event.contents[event.step]( + event, + event._trigger, + event.player, + event._tmpStoreEvent + ); if (evt) event._tmpStoreEvent = evt; if (game.executingAsyncEventMap.has(event.toEvent())) { @@ -5699,95 +6083,140 @@ export class Game extends Uninstantable { if (game.executingAsyncEventMap.has(event.toEvent())) { if (!game.executingAsyncEventMap.get(_status.event.toEvent())) { console.warn(`game.executingAsyncEventMap中包括了event,但不包括_status.event!`); - console.log('event :>> ', event.toEvent()); - console.log('_status.event :>> ', _status.event.toEvent()); + console.log("event :>> ", event.toEvent()); + console.log("_status.event :>> ", _status.event.toEvent()); // debugger; - game.executingAsyncEventMap.set(event.toEvent(), game.executingAsyncEventMap.get(event.toEvent()).then(() => { - event.finish(); - resolve(); - })); + game.executingAsyncEventMap.set( + event.toEvent(), + game.executingAsyncEventMap.get(event.toEvent()).then(() => { + event.finish(); + resolve(); + }) + ); } else { - game.executingAsyncEventMap.set(_status.event.toEvent(), game.executingAsyncEventMap.get(_status.event.toEvent()).then(() => { - event.finish(); - resolve(); - })); + game.executingAsyncEventMap.set( + _status.event.toEvent(), + game.executingAsyncEventMap.get(_status.event.toEvent()).then(() => { + event.finish(); + resolve(); + }) + ); } } else { event.finish(); resolve(); } }); - } - else if (event.content instanceof GeneratorFunction) { + } else 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); + 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)') { + if (typeof next.value == "function" && next.value.toString() == "code=>eval(code)") { //触发debugger - var inputCallback = inputResult => { + 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); } - } - game.prompt('', 'debugger调试', inputCallback); + }; + game.prompt("", "debugger调试", inputCallback); return game.pause2(); } if (event.finished) event.generatorContent.return(); resolve(); - } - else if (event.content instanceof AsyncFunction) { + } else if (event.content instanceof AsyncFunction) { // _status,lib,game,ui,get,ai六个变量由game.import提供 event.content(event, trigger, player).then(() => { // 其实这个if几乎一定执行了 if (game.executingAsyncEventMap.has(event.toEvent())) { if (!game.executingAsyncEventMap.get(_status.event.toEvent())) { console.warn(`game.executingAsyncEventMap中包括了event,但不包括_status.event!`); - console.log('event :>> ', event.toEvent()); - console.log('_status.event :>> ', _status.event.toEvent()); + console.log("event :>> ", event.toEvent()); + console.log("_status.event :>> ", _status.event.toEvent()); // debugger; - game.executingAsyncEventMap.set(event.toEvent(), game.executingAsyncEventMap.get(event.toEvent()).then(() => { - event.finish(); - resolve(); - })); + game.executingAsyncEventMap.set( + event.toEvent(), + game.executingAsyncEventMap.get(event.toEvent()).then(() => { + event.finish(); + resolve(); + }) + ); } else { - game.executingAsyncEventMap.set(_status.event.toEvent(), game.executingAsyncEventMap.get(_status.event.toEvent()).then(() => { - event.finish(); - resolve(); - })); + game.executingAsyncEventMap.set( + _status.event.toEvent(), + game.executingAsyncEventMap.get(_status.event.toEvent()).then(() => { + event.finish(); + resolve(); + }) + ); } } else { event.finish(); resolve(); } }); - } - else { - event.content(event, step, source, player, target, targets, - card, cards, skill, forced, num, trigger, result, - _status, lib, game, ui, get, ai); + } else { + event.content( + event, + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + trigger, + result, + _status, + lib, + game, + ui, + get, + ai + ); resolve(); } }); } - static pause() { + pause() { clearTimeout(_status.timeout); _status.paused = true; } - static pause2() { + pause2() { if (_status.connectMode) return; _status.paused2 = true; } - static resume() { + resume() { if (_status.paused) { if (!_status.noclearcountdown) { game.stopCountChoose(); @@ -5797,109 +6226,135 @@ export class Game extends Uninstantable { game.loop(); } } - static resume2() { + resume2() { if (_status.connectMode) return; if (_status.paused2) { _status.paused2 = false; game.loop(); } } - static delaye() { - let next = game.createEvent('delay', false); - next.setContent('delay'); + delaye() { + let next = game.createEvent("delay", false); + next.setContent("delay"); next._args = Array.from(arguments); return next; } - static delayex() { - let next = game.createEvent('delayx', false); - next.setContent('delay'); + delayex() { + let next = game.createEvent("delayx", false); + next.setContent("delay"); next._args = Array.from(arguments); return next; } /** - * @param { number } [time] - * @param { number } [time2] + * @param { number } [time] + * @param { number } [time2] */ - static delay(time, time2) { + delay(time, time2) { if (_status.paused) return; game.pause(); - if (typeof time != 'number') time = 1; - if (typeof time2 != 'number') time2 = 0; + if (typeof time != "number") time = 1; + if (typeof time2 != "number") time2 = 0; time = time * lib.config.duration + time2; - if (lib.config.speed == 'vvfast') time /= 3; + if (lib.config.speed == "vvfast") time /= 3; _status.timeout = setTimeout(game.resume, time); } /** - * @param { number } [time] - * @param { number } [time2] + * @param { number } [time] + * @param { number } [time2] */ - static delayx(time, time2) { - if (typeof time != 'number') time = 1; + delayx(time, time2) { + if (typeof time != "number") time = 1; switch (lib.config.game_speed) { - case 'vslow': time *= 2.5; break; - case 'slow': time *= 1.5; break; - case 'fast': time *= 0.7; break; - case 'vfast': time *= 0.4; break; - case 'vvfast': time *= 0.2; break; + case "vslow": + time *= 2.5; + break; + case "slow": + time *= 1.5; + break; + case "fast": + time *= 0.7; + break; + case "vfast": + time *= 0.4; + break; + case "vvfast": + time *= 0.2; + break; } return game.delay(time, time2); } /** * 在async content中对game.delay的代替使用方法 - * + * * 因为async content里不应该使用game.pause和game.resume - * - * @param { number } [time] - * @param { number } [time2] + * + * @param { number } [time] + * @param { number } [time2] */ - static asyncDelay(time, time2) { + asyncDelay(time, time2) { // if(_status.paused) return; // game.pause(); - if (typeof time != 'number') time = 1; - if (typeof time2 != 'number') time2 = 0; + if (typeof time != "number") time = 1; + if (typeof time2 != "number") time2 = 0; time = time * lib.config.duration + time2; - if (lib.config.speed == 'vvfast') time /= 3; + if (lib.config.speed == "vvfast") time /= 3; //_status.timeout=setTimeout(game.resume,time); return delay(time); } /** * 在async content中对game.delayx的代替使用方法 - * + * * 因为async content里不应该使用game.pause和game.resume - * - * @param { number } [time] - * @param { number } [time2] + * + * @param { number } [time] + * @param { number } [time2] */ - static asyncDelayx(time, time2) { - if (typeof time != 'number') time = 1; + asyncDelayx(time, time2) { + if (typeof time != "number") time = 1; switch (lib.config.game_speed) { - case 'vslow': time *= 2.5; break; - case 'slow': time *= 1.5; break; - case 'fast': time *= 0.7; break; - case 'vfast': time *= 0.4; break; - case 'vvfast': time *= 0.2; break; + case "vslow": + time *= 2.5; + break; + case "slow": + time *= 1.5; + break; + case "fast": + time *= 0.7; + break; + case "vfast": + time *= 0.4; + break; + case "vvfast": + time *= 0.2; + break; } return game.asyncDelay(time, time2); } /** - * @param { GameEventPromise } [event] + * @param { import('../library/index.js').GameEventPromise } [event] */ - static check(event = _status.event) { + check(event = _status.event) { game.callHook("checkBegin", [event]); - + event._checked = true; - let ok = true, auto = true, auto_confirm = lib.config.auto_confirm; + let ok = true, + auto = true, + auto_confirm = lib.config.auto_confirm; const player = event.player; const uppercaseType = (type) => type[0].toUpperCase() + type.slice(1); - - if (!event.filterButton && !event.filterCard && !event.filterTarget && (!event.skill || !event._backup)) { + if ( + !event.filterButton && + !event.filterCard && + !event.filterTarget && + (!event.skill || !event._backup) + ) { if (event.choosing) _status.imchoosing = true; return false; } let useCache = !lib.config.compatiblemode && !event.skill && !event.multitarget; - const filterCache = type => { + const filterCache = (type) => { if (get.select(event[`select${uppercaseType(type)}`])[1] < 0) return false; const cardinfo = get.info(get.card() || {}); if (cardinfo && cardinfo.complexTarget) return false; @@ -5907,7 +6362,7 @@ export class Game extends Uninstantable { return !event[`complex${uppercaseType(type)}`]; }; - ['button', 'card', 'target'].forEach(type => { + ["button", "card", "target"].forEach((type) => { if (!event[`filter${uppercaseType(type)}`]) return; if (!filterCache(type)) useCache = false; if (!ok) game.uncheck(type); @@ -5917,11 +6372,11 @@ export class Game extends Uninstantable { game.Check.skill(event); _status.multitarget = false; - const skillinfo = get.info(event.skill)||{}; + const skillinfo = get.info(event.skill) || {}; if (_status.event.multitarget) _status.multitarget = true; - else if (_status.event.name === 'chooseToUse') { + else if (_status.event.name === "chooseToUse") { if (skillinfo.multitarget && !skillinfo.multiline) _status.multitarget = true; - if (skillinfo.viewAs && typeof skillinfo.viewAs !== 'function') { + if (skillinfo.viewAs && typeof skillinfo.viewAs !== "function") { const cardinfo = get.info(get.card()); if (cardinfo && (cardinfo.multitarget || cardinfo.complexSelect) && !cardinfo.multiline) { _status.multitarget = true; @@ -5929,32 +6384,38 @@ export class Game extends Uninstantable { } } - player.node.equips.classList.remove('popequip'); - if (event.filterCard && lib.config.popequip && !_status.nopopequip && get.is.phoneLayout() && - typeof event.position === 'string' && event.position.includes('e') && - player.node.equips.querySelector('.card.selectable')) { - player.node.equips.classList.add('popequip'); + player.node.equips.classList.remove("popequip"); + if ( + event.filterCard && + lib.config.popequip && + !_status.nopopequip && + get.is.phoneLayout() && + typeof event.position === "string" && + event.position.includes("e") && + player.node.equips.querySelector(".card.selectable") + ) { + player.node.equips.classList.add("popequip"); auto_confirm = false; } - if (event.isMine() && game.chess && get.config('show_distance') && game.me) { + if (event.isMine() && game.chess && get.config("show_distance") && game.me) { const players = game.players.slice(); if (event.deadTarget) players.addArray(game.dead); - players.forEach(player => { + players.forEach((player) => { if (player === game.me) return player.node.action.hide(); player.node.action.show(); - let dist = get.distance(game.me, player, 'pure'); + let dist = get.distance(game.me, player, "pure"); let dist2 = get.distance(game.me, player); player.node.action.innerHTML = `距离:${dist2}/${dist}`; - if (dist > 7) player.node.action.classList.add('thunder'); - else player.node.action.classList.remove('thunder'); + if (dist > 7) player.node.action.classList.add("thunder"); + else player.node.action.classList.remove("thunder"); }); } ok = ok && (!event.filterOk || event.filterOk()); - let confirm = ''; - if (ok) confirm += 'o'; - if (!event.forced && !event.fakeforce && get.noSelected()) confirm += 'c'; + let confirm = ""; + if (ok) confirm += "o"; + if (!event.forced && !event.fakeforce && get.noSelected()) confirm += "c"; if (event.isMine()) game.Check.confirm(event, confirm); game.callHook("checkEnd", [event, { ok, auto, auto_confirm, autoConfirm: auto_confirm }]); @@ -5969,141 +6430,9 @@ export class Game extends Uninstantable { // } return ok; } - static Check = class extends Uninstantable { - static processSelection({ type, items, event, useCache, isSelectable }) { - let ok = true, auto; - let selectableItems = false; - const uppercaseType = (type) => type[0].toUpperCase() + type.slice(1); - const uiSelected = ui.selected[`${type}s`]; - const range = get.select(event[`select${uppercaseType(type)}`]); - - if (event.forceAuto && uiSelected.length === range[1]) auto = true; - else if (range[0] !== range[1] || range[0] > 1) auto = false; - - let cache; - let firstCheck = false; - - if (useCache) { - if (!event[`_${type}Choice`]) event[`_${type}Choice`] = {}; - let cacheId = 0; - for (let Type of ['button', 'card', 'target']) { - if (type === Type) break; - if (Type === "target") Type = "player"; - ui.selected[`${Type}s`].forEach(i => cacheId ^= i[`${Type}id`]); - } - if (!event[`_${type}Choice`][cacheId]) { - event[`_${type}Choice`][cacheId] = []; - firstCheck = true; - } - cache = event[`_${type}Choice`][cacheId]; - } - - items.forEach(item => { - let selectable; - if (!lib.filter.cardAiIncluded(item)) selectable = false; - else if (useCache && !firstCheck) selectable = cache.includes(item); - else selectable = isSelectable(item, event); - - if (range[1] <= -1) { - if (selectable) { - item.classList.add('selected'); - uiSelected.add(item); - } else { - item.classList.remove('selected'); - uiSelected.remove(item); - } - if (item.updateTransform) item.updateTransform(selectable); - } else { - if (selectable && uiSelected.length < range[1]) { - item.classList.add('selectable'); - if (firstCheck) cache.push(item); - } - else item.classList.remove('selectable'); - } - - if (item.classList.contains('selectable')) selectableItems = true; - else if (item.classList.contains('selected')) item.classList.add('selectable'); - - game.callHook(`check${uppercaseType(type)}`, [item, event]); - }); - - if (event[`${type}Required`] && uiSelected.length === 0) ok = false; - else if (uiSelected.length < range[0] && (!event.forced || selectableItems || event.complexSelect)) ok = false; - - if (event.custom && event.custom.add[type]) event.custom.add[type](); - - return { ok, auto }; - } - static button(event, useCache) { - const player = event.player; - const buttons = event.dialog.buttons; - const isSelectable = (button, event) => { - if (!lib.filter.buttonIncluded(button)) return false; - if (button.classList.contains('unselectable')) return false; - return event.filterButton(button, player); - } - return game.Check.processSelection({ type: 'button', items: buttons, event, useCache, isSelectable }); - } - static card(event, useCache) { - const player = event.player; - const cards = player.getCards(event.position); - const isSelectable = (card, event) => { - if (card.classList.contains('uncheck')) return false; - if (player.isOut()) return false; - if (!lib.filter.cardRespondable(card, player)) return false; - return event.filterCard(card, player); - } - return game.Check.processSelection({ type: 'card', items: cards, event, useCache, isSelectable }); - } - static target(event, useCache) { - const player = event.player; - const card = get.card(); - const targets = game.players.slice(); - if (event.deadTarget) targets.addArray(game.dead); - const isSelectable = (target, event) => { - if (game.chess && !event.chessForceAll && player && get.distance(player, target, 'pure') > 7) return false; - if (target.isOut()) return false; - return event.filterTarget(card, player, target); - } - return game.Check.processSelection({ type: 'target', items: targets, event, useCache, isSelectable }); - } - static skill(event) { - if (ui.skills) ui.skills.close(); - if (ui.skills2) ui.skills2.close(); - if (ui.skills3) ui.skills3.close(); - if (event.skill || !get.noSelected() || _status.noconfirm) return; - - const player = event.player; - if (!event._skillChoice) event._skillChoice = game.expandSkills(player.getSkills('invisible').concat(lib.skill.global)).filter(skill => lib.filter.filterEnable(event, player, skill)); - - const skills = event._skillChoice.filter(i => event.isMine() || !event._aiexclude.includes(i)); - const globallist = game.expandSkills(lib.skill.global.slice()); - const ownedlist = game.expandSkills(player.getSkills('invisible', false)); - - const ownedSkills = [], globalSkills = [], equipSkills = []; - skills.forEach(skill => { - if (globallist.includes(skill)) globalSkills.push(skill); - else if (!ownedlist.includes(skill)) equipSkills.push(skill); - else ownedSkills.push(skill); - }); - - if (ownedSkills.length) ui.create.skills(ownedSkills); - if (globalSkills.length) ui.create.skills2(globalSkills); - if (equipSkills.length) ui.create.skills3(equipSkills); - } - static confirm(event, confirm) { - ui.arena.classList.add('selecting'); - if (event.filterTarget && (!event.filterCard || !event.position || (typeof event.position == 'string' && !event.position.includes('e')))) { - ui.arena.classList.add('tempnoe'); - } - game.countChoose(); - if (!_status.noconfirm && !_status.event.noconfirm && (_status.mouseleft || !_status.mousedown)) { - ui.create.confirm(confirm); - } - } - } - static uncheck(...args) { - if (args.length === 0) args = ['button', 'card', 'target']; + Check = new Check(); + uncheck(...args) { + if (args.length === 0) args = ["button", "card", "target"]; const event = _status.event; const players = game.players.slice(); if (_status.event.deadTarget) players.addArray(game.dead); @@ -6111,68 +6440,68 @@ export class Game extends Uninstantable { game.callHook("uncheckBegin", [event, args]); if (game.chess) { - const shadows = Array.from(ui.chessContainer.querySelectorAll('.playergrid.temp')); - shadows.forEach(i => i.remove()); + const shadows = Array.from(ui.chessContainer.querySelectorAll(".playergrid.temp")); + shadows.forEach((i) => i.remove()); } - if(event.player) event.player.node.equips.classList.remove('popequip'); + if (event.player) event.player.node.equips.classList.remove("popequip"); - if (args.includes('button') && event.dialog && event.dialog.buttons) { - event.dialog.buttons.forEach(button => { - button.classList.remove('selectable'); - button.classList.remove('selected'); + if (args.includes("button") && event.dialog && event.dialog.buttons) { + event.dialog.buttons.forEach((button) => { + button.classList.remove("selectable"); + button.classList.remove("selected"); game.callHook("uncheckButton", [button, event]); }); ui.selected.buttons.length = 0; } - if (args.includes('card') && event.player) { - const cards = event.player.getCards('hejsx'); - cards.forEach(card => { - card.classList.remove('selected'); - card.classList.remove('selectable'); + if (args.includes("card") && event.player) { + const cards = event.player.getCards("hejsx"); + cards.forEach((card) => { + card.classList.remove("selected"); + card.classList.remove("selectable"); card.updateTransform(false); game.callHook("uncheckCard", [card, event]); }); ui.selected.cards.length = 0; } - if (args.includes('target')) { - players.forEach(target => { - target.classList.remove('selected'); - target.classList.remove('selectable'); + if (args.includes("target")) { + players.forEach((target) => { + target.classList.remove("selected"); + target.classList.remove("selectable"); game.callHook("uncheckTarget", [target, event]); }); ui.selected.targets.length = 0; } if (args.length === 3) { - ui.arena.classList.remove('selecting'); - ui.arena.classList.remove('tempnoe'); + ui.arena.classList.remove("selecting"); + ui.arena.classList.remove("tempnoe"); _status.imchoosing = false; _status.lastdragchange.length = 0; _status.mousedragging = null; _status.mousedragorigin = null; - ui.touchlines.forEach(i => i.delete()); + ui.touchlines.forEach((i) => i.delete()); ui.touchlines.length = 0; } ui.canvas.width = ui.arena.offsetWidth; ui.canvas.height = ui.arena.offsetHeight; - players.forEach(i => i.unprompt()); - _status.dragline.forEach(i => i && i.remove()); + players.forEach((i) => i.unprompt()); + _status.dragline.forEach((i) => i && i.remove()); _status.dragline.length = 0; - ui.arena.classList.remove('dragging'); + ui.arena.classList.remove("dragging"); game.callHook("uncheckEnd", [event, args]); } /** - * @param { Player } player1 - * @param { Player } player2 - * @param { boolean } [prompt] - * @param { boolean } [behind] - * @param { boolean } [noanimate] + * @param { Player } player1 + * @param { Player } player2 + * @param { boolean } [prompt] + * @param { boolean } [behind] + * @param { boolean } [noanimate] */ - static swapSeat(player1, player2, prompt, behind, noanimate) { + swapSeat(player1, player2, prompt, behind, noanimate) { if (noanimate) { - player1.style.transition = 'all 0s'; - player2.style.transition = 'all 0s'; + player1.style.transition = "all 0s"; + player2.style.transition = "all 0s"; ui.refresh(player1); ui.refresh(player2); } @@ -6181,15 +6510,13 @@ export class Game extends Uninstantable { for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { if (player1.next != player2) { game.swapSeat(player1, player1.next, false, false); - } - else break; + } else break; } if (prompt != false) { - game.log(player1, '将座位移至', player2, '后'); + game.log(player1, "将座位移至", player2, "后"); } - } - else { - game.addVideo('swapSeat', null, [player1.dataset.position, player2.dataset.position]); + } else { + game.addVideo("swapSeat", null, [player1.dataset.position, player2.dataset.position]); let seat1 = player1.seatNum; let seat2 = player2.seatNum; player2.seatNum = seat1; @@ -6200,7 +6527,7 @@ export class Game extends Uninstantable { player2.dataset.position = temp1; game.arrangePlayers(); if (!game.chess) { - if (player1.dataset.position == '0' || player2.dataset.position == '0') { + if (player1.dataset.position == "0" || player2.dataset.position == "0") { pos = parseInt(player1.dataset.position); if (pos == 0) pos = parseInt(player2.dataset.position); num = game.players.length + game.dead.length; @@ -6217,32 +6544,31 @@ export class Game extends Uninstantable { } } if (prompt != false) { - game.log(player1, '和', player2, '交换了座位'); + game.log(player1, "和", player2, "交换了座位"); } } if (noanimate) { setTimeout(() => { - player1.style.transition = ''; - player2.style.transition = ''; + player1.style.transition = ""; + player2.style.transition = ""; }, 200); } } /** - * @param { Player } player1 - * @param { Player } [player2] + * @param { Player } player1 + * @param { Player } [player2] */ - static swapPlayer(player, player2) { - let players = game.players.concat(game.dead) + swapPlayer(player, player2) { + let players = game.players.concat(game.dead); if (player2) { if (player == game.me) game.swapPlayer(player2); else if (player2 == game.me) game.swapPlayer(player); - } - else { + } else { if (player == game.me) return; for (let i = 0; i < players.length; i++) { - players[i].style.transition = 'all 0s'; + players[i].style.transition = "all 0s"; } - game.addVideo('swapPlayer', player, get.cardsInfo(player.getCards('h'))); + game.addVideo("swapPlayer", player, get.cardsInfo(player.getCards("h"))); if (!game.chess) { let pos = parseInt(player.dataset.position); let num = game.players.length + game.dead.length; @@ -6261,8 +6587,8 @@ export class Game extends Uninstantable { if (current.isDead()) { current.$die(); } - ui.handcards1 = player.node.handcards1.addTempClass('start').fix(); - ui.handcards2 = player.node.handcards2.addTempClass('start').fix(); + ui.handcards1 = player.node.handcards1.addTempClass("start").fix(); + ui.handcards2 = player.node.handcards2.addTempClass("start").fix(); ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); @@ -6288,31 +6614,35 @@ export class Game extends Uninstantable { delete ui.continue_game; } } - if (lib.config.mode == 'identity') { + if (lib.config.mode == "identity") { game.me.setIdentity(game.me.identity); } - setTimeout((players) => { - for (let i = 0; i < players.length; i++) { - players[i].style.transition = ''; - } - }, 100, players); + setTimeout( + (players) => { + for (let i = 0; i < players.length; i++) { + players[i].style.transition = ""; + } + }, + 100, + players + ); } /** * @param { Player } player */ - static swapControl(player) { + swapControl(player) { if (player == game.me) return; game.me.node.handcards1.remove(); game.me.node.handcards2.remove(); game.me = player; - ui.handcards1 = player.node.handcards1.addTempClass('start').fix(); - ui.handcards2 = player.node.handcards2.addTempClass('start').fix(); + ui.handcards1 = player.node.handcards1.addTempClass("start").fix(); + ui.handcards2 = player.node.handcards2.addTempClass("start").fix(); ui.handcards1Container.insertBefore(ui.handcards1, ui.handcards1Container.firstChild); ui.handcards2Container.insertBefore(ui.handcards2, ui.handcards2Container.firstChild); ui.updatehl(); - game.addVideo('swapControl', player, get.cardsInfo(player.getCards('h'))); + game.addVideo("swapControl", player, get.cardsInfo(player.getCards("h"))); if (game.me.isAlive()) { if (ui.auto) ui.auto.show(); @@ -6335,18 +6665,17 @@ export class Game extends Uninstantable { } } } - static swapPlayerAuto(player) { + swapPlayerAuto(player) { if (game.modeSwapPlayer) { game.modeSwapPlayer(player); - } - else { + } else { game.swapPlayer(player); } } /** * @param { Player } player */ - static findNext(player) { + findNext(player) { let players = get.players(lib.sort.position); let position = parseInt(player.dataset.position); for (let i = 0; i < players.length; i++) { @@ -6357,12 +6686,12 @@ export class Game extends Uninstantable { return players[0]; } /** - * @param { string } name - * @param { Function } callback + * @param { string } name + * @param { Function } callback */ - static loadModeAsync(name, callback) { + loadModeAsync(name, callback) { window.game = game; - let script = lib.init.js(lib.assetURL + 'mode', name, async () => { + let script = lib.init.js(lib.assetURL + "mode", name, async () => { await Promise.allSettled(_status.importing.mode); if (!lib.config.dev) delete window.game; script.remove(); @@ -6375,22 +6704,24 @@ export class Game extends Uninstantable { }); } /** - * @param { string } name - * @param {*} configx + * @param { string } name + * @param {*} configx */ - static switchMode(name, configx) { + switchMode(name, configx) { if (!lib.layoutfixed.includes(name)) { if (lib.config.layout != game.layout) { lib.init.layout(lib.config.layout); - } - else if (lib.config.mode == 'brawl') { - if (lib.config.player_border == 'normal' && (game.layout == 'long' || game.layout == 'long2')) { - ui.arena.classList.add('lslim_player'); + } else if (lib.config.mode == "brawl") { + if ( + lib.config.player_border == "normal" && + (game.layout == "long" || game.layout == "long2") + ) { + ui.arena.classList.add("lslim_player"); } } } window.game = game; - let script = lib.init.js(lib.assetURL + 'mode', name, async () => { + let script = lib.init.js(lib.assetURL + "mode", name, async () => { await Promise.allSettled(_status.importing.mode); if (!lib.config.dev) delete window.game; script.remove(); @@ -6402,34 +6733,31 @@ export class Game extends Uninstantable { for (i in mode[lib.config.mode].element) { if (!lib.element[i]) lib.element[i] = []; for (j in mode[lib.config.mode].element[i]) { - if (j == 'init') { + if (j == "init") { if (!lib.element[i].inits) lib.element[i].inits = []; lib.element[i].inits.push(mode[lib.config.mode].element[i][j]); - } - else { + } else { lib.element[i][j] = mode[lib.config.mode].element[i][j]; } } } for (i in mode[lib.config.mode].ai) { - if (typeof mode[lib.config.mode].ai[i] == 'object') { + if (typeof mode[lib.config.mode].ai[i] == "object") { if (ai[i] == undefined) ai[i] = {}; for (j in mode[lib.config.mode].ai[i]) { ai[i][j] = mode[lib.config.mode].ai[i][j]; } - } - else { + } else { ai[i] = mode[lib.config.mode].ai[i]; } } for (i in mode[lib.config.mode].ui) { - if (typeof mode[lib.config.mode].ui[i] == 'object') { + if (typeof mode[lib.config.mode].ui[i] == "object") { if (ui[i] == undefined) ui[i] = {}; for (j in mode[lib.config.mode].ui[i]) { ui[i][j] = mode[lib.config.mode].ui[i][j]; } - } - else { + } else { ui[i] = mode[lib.config.mode].ui[i]; } } @@ -6447,19 +6775,19 @@ export class Game extends Uninstantable { lib.onover.push(game.onover); delete game.onover; } - lib.config.banned = lib.config[lib.config.mode + '_banned'] || []; - lib.config.bannedcards = lib.config[lib.config.mode + '_bannedcards'] || []; + lib.config.banned = lib.config[lib.config.mode + "_banned"] || []; + lib.config.bannedcards = lib.config[lib.config.mode + "_bannedcards"] || []; for (i in mode[lib.config.mode]) { - if (i == 'element') continue; - if (i == 'game') continue; - if (i == 'ai') continue; - if (i == 'ui') continue; - if (i == 'get') continue; - if (i == 'config') continue; - if (i == 'start') continue; - if (i == 'startBefore') continue; - if (lib[i] == undefined) lib[i] = (Array.isArray(mode[lib.config.mode][i])) ? [] : {}; + if (i == "element") continue; + if (i == "game") continue; + if (i == "ai") continue; + if (i == "ui") continue; + if (i == "get") continue; + if (i == "config") continue; + if (i == "start") continue; + if (i == "startBefore") continue; + if (lib[i] == undefined) lib[i] = Array.isArray(mode[lib.config.mode][i]) ? [] : {}; for (j in mode[lib.config.mode][i]) { lib[i][j] = mode[lib.config.mode][i][j]; } @@ -6475,17 +6803,16 @@ export class Game extends Uninstantable { _status.paused = false; if (_status.connectMode && lib.mode[name].connect) { - game.saveConfig('connect_mode', name); + game.saveConfig("connect_mode", name); game.clearConnect(); lib.configOL.mode = name; if (configx) { for (let i in configx) { lib.configOL[i] = configx[i]; } - } - else { + } else { for (let i in lib.mode[name].connect) { - if (i == 'update') continue; + if (i == "update") continue; lib.configOL[i.slice(8)] = get.config(i); } lib.configOL.zhinang_tricks = lib.config.connect_zhinang_tricks; @@ -6497,8 +6824,8 @@ export class Game extends Uninstantable { for (let i = 0; i < lib.config.connect_cards.length; i++) { lib.configOL.cardPack.remove(lib.config.connect_cards[i]); } - lib.configOL.banned = lib.config['connect_' + name + '_banned']; - lib.configOL.bannedcards = lib.config['connect_' + name + '_bannedcards']; + lib.configOL.banned = lib.config["connect_" + name + "_banned"]; + lib.configOL.bannedcards = lib.config["connect_" + name + "_bannedcards"]; } lib.configOL.version = lib.versionOL; for (let i in lib.cardPackList) { @@ -6507,38 +6834,39 @@ export class Game extends Uninstantable { } } for (i = 0; i < lib.card.list.length; i++) { - if (lib.card.list[i][2] == 'huosha') { + if (lib.card.list[i][2] == "huosha") { lib.card.list[i] = lib.card.list[i].slice(0); - lib.card.list[i][2] = 'sha'; - lib.card.list[i][3] = 'fire'; - } - else if (lib.card.list[i][2] == 'leisha') { + lib.card.list[i][2] = "sha"; + lib.card.list[i][3] = "fire"; + } else if (lib.card.list[i][2] == "leisha") { lib.card.list[i] = lib.card.list[i].slice(0); - lib.card.list[i][2] = 'sha'; - lib.card.list[i][3] = 'thunder'; + lib.card.list[i][2] = "sha"; + lib.card.list[i][3] = "thunder"; } if (!lib.card[lib.card.list[i][2]]) { - lib.card.list.splice(i, 1); i--; - } - else if (lib.card[lib.card.list[i][2]].mode && - lib.card[lib.card.list[i][2]].mode.includes(lib.config.mode) == false) { - lib.card.list.splice(i, 1); i--; + lib.card.list.splice(i, 1); + i--; + } else if ( + lib.card[lib.card.list[i][2]].mode && + lib.card[lib.card.list[i][2]].mode.includes(lib.config.mode) == false + ) { + lib.card.list.splice(i, 1); + i--; } } } if (!lib.config.show_playerids || !game.showIdentity) { - ui.playerids.style.display = 'none'; - } - else { - ui.playerids.style.display = ''; + ui.playerids.style.display = "none"; + } else { + ui.playerids.style.display = ""; } if (mode[lib.config.mode].startBefore) mode[lib.config.mode].startBefore(); - game.createEvent('game', false).setContent(mode[lib.config.mode].start); + game.createEvent("game", false).setContent(mode[lib.config.mode].start); if (lib.mode[lib.config.mode] && lib.mode[lib.config.mode].fromextension) { let startstr = mode[lib.config.mode].start.toString(); - if (startstr.indexOf('onfree') == -1) { + if (startstr.indexOf("onfree") == -1) { setTimeout(lib.init.onfree, 500); } } @@ -6547,17 +6875,15 @@ export class Game extends Uninstantable { if (!lib.db) { try { lib.storage = JSON.parse(localStorage.getItem(lib.configprefix + lib.config.mode)); - if (typeof lib.storage != 'object') throw ('err'); - if (lib.storage == null) throw ('err'); - } - catch (err) { + if (typeof lib.storage != "object") throw "err"; + if (lib.storage == null) throw "err"; + } catch (err) { lib.storage = {}; localStorage.setItem(lib.configprefix + lib.config.mode, "{}"); } game.loop(); - } - else { - game.getDB('data', lib.config.mode, function (obj) { + } else { + game.getDB("data", lib.config.mode, function (obj) { lib.storage = obj || {}; game.loop(); }); @@ -6565,72 +6891,66 @@ export class Game extends Uninstantable { }); } /** - * @param { string } mode + * @param { string } mode */ - static loadMode(mode) { - let next = game.createEvent('loadMode', false); + loadMode(mode) { + let next = game.createEvent("loadMode", false); next.mode = mode; - next.setContent('loadMode'); + next.setContent("loadMode"); } /** - * @param {...string} args + * @param {...string} args */ - static loadPackage(...args) { - let next = game.createEvent('loadPackage'); + loadPackage(...args) { + let next = game.createEvent("loadPackage"); next.packages = []; for (let i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { + if (typeof arguments[i] == "string") { next.packages.push(arguments[i]); } } - next.setContent('loadPackage'); + next.setContent("loadPackage"); } /** - * @param { Player } player + * @param { Player } player */ - static phaseLoop(player) { - let next = game.createEvent('phaseLoop'); + phaseLoop(player) { + let next = game.createEvent("phaseLoop"); next.player = player; next._isStandardLoop = true; - next.setContent('phaseLoop'); + next.setContent("phaseLoop"); } /** - * @param { Player } [player] + * @param { Player } [player] */ - static gameDraw(player, num = 4) { - let next = game.createEvent('gameDraw'); + gameDraw(player, num = 4) { + let next = game.createEvent("gameDraw"); next.player = player || game.me; next.num = num; - next.setContent('gameDraw'); + next.setContent("gameDraw"); return next; } - static chooseCharacterDouble() { - let next = game.createEvent('chooseCharacter'); + chooseCharacterDouble() { + let next = game.createEvent("chooseCharacter"); let config, width, num, ratio, func, update, list, first; for (let i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'number') { + if (typeof arguments[i] == "number") { if (!width) { width = arguments[i]; - } - else if (!num) { + } else if (!num) { num = arguments[i]; - } - else { + } else { ratio = arguments[i]; } - } - else if (typeof arguments[i] == 'function') { + } else if (typeof arguments[i] == "function") { if (!func) { func = arguments[i]; - } - else { + } else { update = arguments[i]; } - } - else if (Array.isArray(arguments[i])) { + } else if (Array.isArray(arguments[i])) { list = arguments[i]; - } - else if (get.objtype(arguments[i]) == 'object') { + } else if (get.objtype(arguments[i]) == "object") { config = arguments[i]; } } @@ -6644,21 +6964,19 @@ export class Game extends Uninstantable { config.num = config.num || num || 3; config.ratio = config.ratio || ratio || 1.2; config.update = config.update || update; - if (!('first' in config)) { - if (typeof first == 'boolean') { + if (!("first" in config)) { + if (typeof first == "boolean") { config.first = first; - } - else { - config.first = 'rand'; + } else { + config.first = "rand"; } } if (!list) { list = []; for (let i in lib.character) { - if (typeof func == 'function') { + if (typeof func == "function") { if (!func(i)) continue; - } - else { + } else { if (lib.filter.characterDisabled(i)) continue; } list.push(i); @@ -6667,20 +6985,20 @@ export class Game extends Uninstantable { next.config = config; next.list = list; next.setContent(function () { - 'step 0' + "step 0"; event.nodes = []; event.avatars = []; event.friend = []; event.enemy = []; event.blank = []; for (let i = 0; i < event.config.size; i++) { - event.nodes.push(ui.create.div('.shadowed.reduce_radius.choosedouble')); + event.nodes.push(ui.create.div(".shadowed.reduce_radius.choosedouble")); } event.moveAvatar = function (node, i) { - if (!node.classList.contains('moved')) { + if (!node.classList.contains("moved")) { event.blank.push(node.index); } - event.nodes[node.index].style.display = ''; + event.nodes[node.index].style.display = ""; event.nodes[node.index].show(); clearTimeout(event.nodes[node.index].choosetimeout); event.moveNode(node, i); @@ -6689,57 +7007,65 @@ export class Game extends Uninstantable { nodex.hide(); nodex.choosetimeout = setTimeout(function () { nodex.show(); - nodex.style.display = 'none'; + nodex.style.display = "none"; }, 300); }, 400); }; event.aiMove = function (friend) { let list = []; for (let i = 0; i < event.avatars.length; i++) { - if (!event.avatars[i].classList.contains('moved')) { + if (!event.avatars[i].classList.contains("moved")) { list.push(event.avatars[i]); } } for (let i = 0; i < list.length; i++) { if (Math.random() < 0.7 || i == list.length - 1) { if (friend) { - event.moveAvatar(list[i], event.friend.length + event.config.width * (event.config.height - 1)); + event.moveAvatar( + list[i], + event.friend.length + event.config.width * (event.config.height - 1) + ); event.friend.push(list[i]); - } - else { + } else { event.moveAvatar(list[i], event.enemy.length); event.enemy.push(list[i]); } - list[i].classList.add('moved'); + list[i].classList.add("moved"); break; } } }; - event.promptbar = ui.create.div('.hidden', ui.window); - event.promptbar.style.width = '100%'; + event.promptbar = ui.create.div(".hidden", ui.window); + event.promptbar.style.width = "100%"; event.promptbar.style.left = 0; if (get.is.phoneLayout()) { - event.promptbar.style.top = '20px'; + event.promptbar.style.top = "20px"; + } else { + event.promptbar.style.top = "58px"; } - else { - event.promptbar.style.top = '58px'; - } - event.promptbar.style.pointerEvents = 'none'; - event.promptbar.style.textAlign = 'center'; - event.promptbar.style.zIndex = '2'; - ui.create.div('.shadowed.reduce_radius', event.promptbar); - event.promptbar.firstChild.style.fontSize = '18px'; - event.promptbar.firstChild.style.padding = '6px 10px'; - event.promptbar.firstChild.style.position = 'relative'; + event.promptbar.style.pointerEvents = "none"; + event.promptbar.style.textAlign = "center"; + event.promptbar.style.zIndex = "2"; + ui.create.div(".shadowed.reduce_radius", event.promptbar); + event.promptbar.firstChild.style.fontSize = "18px"; + event.promptbar.firstChild.style.padding = "6px 10px"; + event.promptbar.firstChild.style.position = "relative"; event.prompt = function (str) { event.promptbar.firstChild.innerHTML = str; event.promptbar.show(); }; event.moveNode = function (node, i) { - let width = event.width, height = event.height, margin = event.margin; - let left = -(width + 10) * event.config.width / 2 + 5 + (i % event.config.width) * (width + 10); - let top = -(height + 10) * event.config.height / 2 + 5 + Math.floor(i / event.config.width) * (height + 10) + margin / 2; - node.style.transform = 'translate(' + left + 'px,' + top + 'px)'; + let width = event.width, + height = event.height, + margin = event.margin; + let left = + (-(width + 10) * event.config.width) / 2 + 5 + (i % event.config.width) * (width + 10); + let top = + (-(height + 10) * event.config.height) / 2 + + 5 + + Math.floor(i / event.config.width) * (height + 10) + + margin / 2; + node.style.transform = "translate(" + left + "px," + top + "px)"; node.index = i; }; event.resize = function () { @@ -6747,12 +7073,12 @@ export class Game extends Uninstantable { if (!get.is.phoneLayout()) { margin = 38; } - let height = (ui.window.offsetHeight - 10 * (event.config.height + 1) - margin) / event.config.height; + let height = + (ui.window.offsetHeight - 10 * (event.config.height + 1) - margin) / event.config.height; let width = (ui.window.offsetWidth - 10 * (event.config.width + 1)) / event.config.width; if (width * event.config.ratio < height) { height = width * event.config.ratio; - } - else { + } else { width = height / event.config.ratio; } event.width = width; @@ -6760,19 +7086,25 @@ export class Game extends Uninstantable { event.margin = margin; for (let i = 0; i < event.config.size; i++) { event.moveNode(event.nodes[i], i); - event.nodes[i].style.width = width + 'px'; - event.nodes[i].style.height = height + 'px'; + event.nodes[i].style.width = width + "px"; + event.nodes[i].style.height = height + "px"; if (event.avatars[i]) { event.moveNode(event.avatars[i], event.avatars[i].index); - event.avatars[i].style.width = width + 'px'; - event.avatars[i].style.height = height + 'px'; - event.avatars[i].nodename.style.fontSize = Math.max(14, Math.round(width / 5.6)) + 'px'; + event.avatars[i].style.width = width + "px"; + event.avatars[i].style.height = height + "px"; + event.avatars[i].nodename.style.fontSize = + Math.max(14, Math.round(width / 5.6)) + "px"; } } if (event.deciding) { - let str = 'px,' + (event.margin / 2 - event.height * 0.5) + 'px)'; + let str = "px," + (event.margin / 2 - event.height * 0.5) + "px)"; for (let i = 0; i < event.friendlist.length; i++) { - event.friendlist[i].style.transform = 'scale(1.2) translate(' + (-(event.width + 14) * event.friendlist.length / 2 + 7 + i * (event.width + 14)) + str; + event.friendlist[i].style.transform = + "scale(1.2) translate(" + + ((-(event.width + 14) * event.friendlist.length) / 2 + + 7 + + i * (event.width + 14)) + + str; } } }; @@ -6784,131 +7116,145 @@ export class Game extends Uninstantable { event.friendlist.remove(this); event.moveNode(this, this.index); this.nodename.innerHTML = get.slimName(this.link); - } - else { + } else { event.friendlist.push(this); } if (event.friendlist.length == event.config.num) { event.deciding = false; - event.prompt('比赛即将开始'); + event.prompt("比赛即将开始"); setTimeout(game.resume, 1000); } if (event.config.update) { for (let i = 0; i < event.friendlist.length; i++) { - event.friendlist[i].nodename.innerHTML = event.config.update(i, event.friendlist.length) || event.friendlist[i].nodename.innerHTML; + event.friendlist[i].nodename.innerHTML = + event.config.update(i, event.friendlist.length) || + event.friendlist[i].nodename.innerHTML; } } - let str = 'px,' + (event.margin / 2 - event.height * 0.5) + 'px)'; + let str = "px," + (event.margin / 2 - event.height * 0.5) + "px)"; for (let i = 0; i < event.friendlist.length; i++) { - event.friendlist[i].style.transform = 'scale(1.2) translate(' + (-(event.width + 14) * event.friendlist.length / 2 + 7 + i * (event.width + 14)) + str; + event.friendlist[i].style.transform = + "scale(1.2) translate(" + + ((-(event.width + 14) * event.friendlist.length) / 2 + + 7 + + i * (event.width + 14)) + + str; } - } - else { + } else { if (!event.imchoosing) return; if (event.replacing) { this.link = event.replacing; - this.setBackground(event.replacing, 'character'); + this.setBackground(event.replacing, "character"); this.nodename.innerHTML = get.slimName(event.replacing); this.nodename.dataset.nature = get.groupnature(lib.character[event.replacing][1]); delete event.replacing; - if (this.classList.contains('moved')) { + if (this.classList.contains("moved")) { event.custom.add.window(); } } - if (this.classList.contains('moved')) return; - event.moveAvatar(this, event.friend.length + event.config.width * (event.config.height - 1)); + if (this.classList.contains("moved")) return; + event.moveAvatar( + this, + event.friend.length + event.config.width * (event.config.height - 1) + ); event.friend.push(this.link); - this.classList.add('moved'); + this.classList.add("moved"); game.resume(); } }; - event.skipnode = ui.create.system('跳过', function () { + event.skipnode = ui.create.system("跳过", function () { this.remove(); event._skiprest = true; if (event.imchoosing) { game.resume(); } }); - if (get.config('change_choice')) { - event.replacenode = ui.create.system('换将', function () { - event.promptbar.hide(); - while (event.avatars.length) { - event.avatars.shift().remove(); - } - for (let i = 0; i < event.config.size; i++) { - event.nodes[i].show(); - event.nodes[i].style.display = ''; - clearTimeout(event.nodes[i].choosetimeout); - } - delete event.list2; - event.friend.length = 0; - event.enemy.length = 0; - event.blank.length = 0; - event.redoing = true; - if (event.imchoosing) { - game.resume(); - } - }, true); - } - if (get.config('change_choice')) { - event.reselectnode = ui.create.system('重选', function () { - event.promptbar.hide(); - event.list2 = event.list2.concat(event.friend).concat(event.enemy); - event.friend.length = 0; - event.enemy.length = 0; - for (let i = 0; i < event.avatars.length; i++) { - if (event.avatars[i].classList.contains('moved')) { - event.moveAvatar(event.avatars[i], event.blank.randomRemove()); - event.avatars[i].classList.remove('moved'); + if (get.config("change_choice")) { + event.replacenode = ui.create.system( + "换将", + function () { + event.promptbar.hide(); + while (event.avatars.length) { + event.avatars.shift().remove(); } - } - event.redoing = true; - if (event.imchoosing) { - game.resume(); - } - }, true); + for (let i = 0; i < event.config.size; i++) { + event.nodes[i].show(); + event.nodes[i].style.display = ""; + clearTimeout(event.nodes[i].choosetimeout); + } + delete event.list2; + event.friend.length = 0; + event.enemy.length = 0; + event.blank.length = 0; + event.redoing = true; + if (event.imchoosing) { + game.resume(); + } + }, + true + ); } - if (get.config('free_choose')) { + if (get.config("change_choice")) { + event.reselectnode = ui.create.system( + "重选", + function () { + event.promptbar.hide(); + event.list2 = event.list2.concat(event.friend).concat(event.enemy); + event.friend.length = 0; + event.enemy.length = 0; + for (let i = 0; i < event.avatars.length; i++) { + if (event.avatars[i].classList.contains("moved")) { + event.moveAvatar(event.avatars[i], event.blank.randomRemove()); + event.avatars[i].classList.remove("moved"); + } + } + event.redoing = true; + if (event.imchoosing) { + game.resume(); + } + }, + true + ); + } + if (get.config("free_choose")) { let createCharacterDialog = function () { event.freechoosedialog = ui.create.characterDialog(); - event.freechoosedialog.style.height = '80%'; - event.freechoosedialog.style.top = '10%'; - event.freechoosedialog.style.transform = 'scale(0.8)'; - event.freechoosedialog.style.transition = 'all 0.3s'; + event.freechoosedialog.style.height = "80%"; + event.freechoosedialog.style.top = "10%"; + event.freechoosedialog.style.transform = "scale(0.8)"; + event.freechoosedialog.style.transition = "all 0.3s"; event.freechoosedialog.listen(function (e) { if (!event.replacing) { event.dialoglayer.clicked = true; } }); - event.freechoosedialog.classList.add('pointerdialog'); - event.dialoglayer = ui.create.div('.popup-container.hidden', function (e) { - if (this.classList.contains('removing')) return; + event.freechoosedialog.classList.add("pointerdialog"); + event.dialoglayer = ui.create.div(".popup-container.hidden", function (e) { + if (this.classList.contains("removing")) return; if (this.clicked) { this.clicked = false; return; } - ui.window.classList.remove('modepaused'); + ui.window.classList.remove("modepaused"); this.delete(); e.stopPropagation(); - event.freechoosedialog.style.transform = 'scale(0.8)'; + event.freechoosedialog.style.transform = "scale(0.8)"; if (event.replacing) { - event.prompt('用' + get.translation(event.replacing) + '替换一名武将'); - } - else { + event.prompt("用" + get.translation(event.replacing) + "替换一名武将"); + } else { if (event.side == 0) { - event.prompt('请选择两名武将'); - } - else { - event.prompt('请选择一名武将'); + event.prompt("请选择两名武将"); + } else { + event.prompt("请选择一名武将"); } } }); - event.dialoglayer.classList.add('modenopause'); + event.dialoglayer.classList.add("modenopause"); event.dialoglayer.appendChild(event.freechoosedialog); - event.freechoosenode.classList.remove('hidden'); - } + event.freechoosenode.classList.remove("hidden"); + }; event.custom.replace.button = function (button) { event.replacing = button.link; @@ -6917,32 +7263,34 @@ export class Game extends Uninstantable { if (event.replacing) { delete event.replacing; if (event.side == 0) { - event.prompt('请选择两名武将'); - } - else { - event.prompt('请选择一名武将'); + event.prompt("请选择两名武将"); + } else { + event.prompt("请选择一名武将"); } } }; - event.freechoosenode = ui.create.system('自由选将', function () { - if (this.classList.contains('hidden')) return; - if (!event.imchoosing) { - event.prompt('请等待敌方选将'); - return; - } - delete event.replacing; - ui.window.classList.add('modepaused'); - ui.window.appendChild(event.dialoglayer); - ui.refresh(event.dialoglayer); - event.dialoglayer.show(); - event.freechoosedialog.style.transform = 'scale(1)'; - event.promptbar.hide(); - }, true); + event.freechoosenode = ui.create.system( + "自由选将", + function () { + if (this.classList.contains("hidden")) return; + if (!event.imchoosing) { + event.prompt("请等待敌方选将"); + return; + } + delete event.replacing; + ui.window.classList.add("modepaused"); + ui.window.appendChild(event.dialoglayer); + ui.refresh(event.dialoglayer); + event.dialoglayer.show(); + event.freechoosedialog.style.transform = "scale(1)"; + event.promptbar.hide(); + }, + true + ); if (lib.onfree) { - event.freechoosenode.classList.add('hidden'); + event.freechoosenode.classList.add("hidden"); lib.onfree.push(createCharacterDialog); - } - else { + } else { createCharacterDialog(); } } @@ -6960,31 +7308,35 @@ export class Game extends Uninstantable { for (let i = 0; i < event.config.size; i++) { ui.window.appendChild(event.nodes[i]); } - 'step 1' + "step 1"; let rand1 = event.config.first; - if (rand1 == 'rand') { - rand1 = (Math.random() < 0.5); + if (rand1 == "rand") { + rand1 = Math.random() < 0.5; } if (rand1) { _status.color = true; event.side = 1; - } - else { + } else { _status.color = false; event.side = 3; } if (!event.list2) { event.list2 = event.list.randomGets(event.config.width * 2); for (let i = 0; i < event.config.width * 2; i++) { - event.avatars.push(ui.create.div('.shadowed.shadowed2.reduce_radius.character.choosedouble', event.clickAvatar)); + event.avatars.push( + ui.create.div( + ".shadowed.shadowed2.reduce_radius.character.choosedouble", + event.clickAvatar + ) + ); let name = event.list2[i]; - event.avatars[i].setBackground(name, 'character'); + event.avatars[i].setBackground(name, "character"); event.avatars[i].link = name; - event.avatars[i].nodename = ui.create.div('.name', event.avatars[i], get.slimName(name)); + event.avatars[i].nodename = ui.create.div(".name", event.avatars[i], get.slimName(name)); event.avatars[i].nodename.style.fontFamily = lib.config.name_font; event.avatars[i].index = i + event.config.width; - event.avatars[i].addTempClass('start'); - event.nodes[event.avatars[i].index].style.display = 'none'; + event.avatars[i].addTempClass("start"); + event.nodes[event.avatars[i].index].style.display = "none"; event.avatars[i].nodename.dataset.nature = get.groupnature(lib.character[name][1]); lib.setIntro(event.avatars[i]); } @@ -6994,33 +7346,30 @@ export class Game extends Uninstantable { } event.avatars.sort(function (a, b) { return get.rank(b.link, true) - get.rank(a.link, true); - }) + }); } game.delay(); lib.init.onfree(); - 'step 2' + "step 2"; if (event.checkredo()) return; if (event._skiprest) return; if (event.side < 2) { event.imchoosing = true; if (event.side == 0) { - event.prompt('请选择两名武将'); - } - else { - event.prompt('请选择一名武将'); + event.prompt("请选择两名武将"); + } else { + event.prompt("请选择一名武将"); event.fast = get.time(); } game.pause(); - } - else { + } else { event.aiMove(); game.delay(); } - 'step 3' - if (typeof event.fast == 'number' && get.time() - event.fast <= 1000) { + "step 3"; + if (typeof event.fast == "number" && get.time() - event.fast <= 1000) { event.fast = true; - } - else { + } else { event.fast = false; } delete event.imchoosing; @@ -7032,8 +7381,7 @@ export class Game extends Uninstantable { while (event.friend.length < event.config.width) { event.aiMove(true); } - } - else if (event.friend.length + event.enemy.length < event.config.width * 2 - 1) { + } else if (event.friend.length + event.enemy.length < event.config.width * 2 - 1) { if (event.side == 1) { game.delay(event.fast ? 1 : 2); event.promptbar.hide(); @@ -7043,43 +7391,44 @@ export class Game extends Uninstantable { event.side = 0; } event.goto(2); - } - else { + } else { event.promptbar.hide(); event.side++; if (event.side > 3) { event.side = 0; } if (event.side >= 2) { - game.delay() + game.delay(); } } - 'step 4' + "step 4"; if (event.checkredo()) return; if (event.skipnode) event.skipnode.delete(); if (event.replacenode) event.replacenode.delete(); if (event.reselectnode) event.reselectnode.delete(); if (event.freechoosenode) event.freechoosenode.delete(); for (let i = 0; i < event.avatars.length; i++) { - if (!event.avatars[i].classList.contains('moved')) { + if (!event.avatars[i].classList.contains("moved")) { if (event.side < 2) { - event.moveAvatar(event.avatars[i], event.friend.length + event.config.width * (event.config.height - 1)); + event.moveAvatar( + event.avatars[i], + event.friend.length + event.config.width * (event.config.height - 1) + ); event.friend.push(event.avatars[i]); - } - else { + } else { event.moveAvatar(event.avatars[i], event.enemy.length); event.enemy.push(event.avatars[i]); } - event.avatars[i].classList.add('moved'); + event.avatars[i].classList.add("moved"); } } game.delay(); - 'step 5' - event.prompt('选择' + get.cnNumber(event.config.num) + '名出场武将'); + "step 5"; + event.prompt("选择" + get.cnNumber(event.config.num) + "名出场武将"); event.enemylist = []; for (let i = 0; i < event.avatars.length; i++) { if (event.avatars[i].index > event.config.width) { - event.avatars[i].classList.add('selecting'); + event.avatars[i].classList.add("selecting"); } } let rand = []; @@ -7104,9 +7453,9 @@ export class Game extends Uninstantable { event.nodes[i].hide(); } game.pause(); - 'step 6' + "step 6"; event.promptbar.delete(); - if (ui.cardPileButton) ui.cardPileButton.style.display = ''; + if (ui.cardPileButton) ui.cardPileButton.style.display = ""; lib.onresize.remove(event.resize); ui.wuxie.show(); ui.auto.show(); @@ -7123,155 +7472,191 @@ export class Game extends Uninstantable { } }); } - static updateRoundNumber() { - game.broadcastAll((roundNumber, pileTop, pileNumber) => { - if (game.roundNumber != roundNumber) game.roundNumber = roundNumber; - if (_status.pileTop != pileTop) _status.pileTop = pileTop; - ui.updateRoundNumber(roundNumber, pileNumber); - }, game.roundNumber, ui.cardPile.firstChild, ui.cardPile.childElementCount); + updateRoundNumber() { + game.broadcastAll( + (roundNumber, pileTop, pileNumber) => { + if (game.roundNumber != roundNumber) game.roundNumber = roundNumber; + if (_status.pileTop != pileTop) _status.pileTop = pileTop; + ui.updateRoundNumber(roundNumber, pileNumber); + }, + game.roundNumber, + ui.cardPile.firstChild, + ui.cardPile.childElementCount + ); } /** - * @param { Player[] } players - * @param { number | number[] | (player: Player) => number } num - * @param { { drawDeck: boolean } } [drawDeck] - * @param { boolean } [bottom] + * @param { Player[] } players + * @param { number | number[] | (player: Player) => number } num + * @param { { drawDeck: boolean } } [drawDeck] + * @param { boolean } [bottom] */ - static asyncDraw(players, num, drawDeck, bottom) { + asyncDraw(players, num, drawDeck, bottom) { return players.forEach((value, index) => { let num2 = 1; - if (typeof num == 'number') num2 = num; + if (typeof num == "number") num2 = num; else if (Array.isArray(num)) num2 = num[index]; - else if (typeof num == 'function') num2 = num(value); + else if (typeof num == "function") num2 = num(value); if (drawDeck && drawDeck.drawDeck) value.draw(num2, false, drawDeck); - else if (bottom) value.draw(num2, 'nodelay', 'bottom'); - else value.draw(num2, 'nodelay'); - }) + else if (bottom) value.draw(num2, "nodelay", "bottom"); + else value.draw(num2, "nodelay"); + }); } /** - * @param { Player[] } players - * @param { number | number[] | (player: Player) => number } num + * @param { Player[] } players + * @param { number | number[] | (player: Player) => number } num * @param { { drawDeck: boolean } } [drawDeck] */ - static asyncDrawAuto(players, num, drawDeck) { + asyncDrawAuto(players, num, drawDeck) { if (players.length > 1) { game.asyncDraw.apply(this, arguments); return; } let num2 = 1; - if (typeof num == 'number') num2 = num; + if (typeof num == "number") num2 = num; else if (Array.isArray(num)) num2 = num[0]; - else if (typeof num == 'function') num2 = num(players[0]); + else if (typeof num == "function") num2 = num(players[0]); if (drawDeck && drawDeck.drawDeck) players[0].draw(num2, drawDeck); else players[0].draw(num2); } - static finishSkill(i, sub) { - const mode = get.mode(), info = lib.skill[i], iInfo = `${i}_info`; + finishSkill(i, sub) { + const mode = get.mode(), + info = lib.skill[i], + iInfo = `${i}_info`; if (info.alter) { lib.translate[`${iInfo}_origin`] = lib.translate[iInfo]; if (!lib.config.vintageSkills.includes(i)) lib.translate[iInfo] = lib.translate[`${iInfo}_alter`]; - } - else if (_status.mode && lib.translate[iInfo + '_' + mode + '_' + _status.mode]) lib.translate[iInfo] = lib.translate[iInfo + '_' + mode + '_' + _status.mode]; + } else if (_status.mode && lib.translate[iInfo + "_" + mode + "_" + _status.mode]) + lib.translate[iInfo] = lib.translate[iInfo + "_" + mode + "_" + _status.mode]; else if (lib.translate[`${iInfo}_${mode}`]) lib.translate[iInfo] = lib.translate[`${iInfo}_${mode}`]; - else if (lib.translate[`${iInfo}_zhu`] && (mode == 'identity' || mode == 'guozhan' && _status.mode == 'four')) lib.translate[iInfo] = lib.translate[`${iInfo}_zhu`]; - else if (lib.translate[`${iInfo}_combat`] && get.is.versus()) lib.translate[iInfo] = lib.translate[`${iInfo}_combat`]; + else if ( + lib.translate[`${iInfo}_zhu`] && + (mode == "identity" || (mode == "guozhan" && _status.mode == "four")) + ) + lib.translate[iInfo] = lib.translate[`${iInfo}_zhu`]; + else if (lib.translate[`${iInfo}_combat`] && get.is.versus()) + lib.translate[iInfo] = lib.translate[`${iInfo}_combat`]; let deleteSkill = function (skill, iInfo) { - let skillx = {}, info = get.info(skill); + let skillx = {}, + info = get.info(skill); if (info) { - ['audio', 'audioname', 'audioname2'].forEach(name => { + ["audio", "audioname", "audioname2"].forEach((name) => { if (info[name]) skillx[name] = info[name]; }); } lib.skill[skill] = skillx; - if (lib.translate[iInfo]) lib.translate[iInfo] = '此模式下不可用'; - if (lib.dynamicTranslate[skill]) lib.dynamicTranslate[skill] = () => '此模式下不可用'; + if (lib.translate[iInfo]) lib.translate[iInfo] = "此模式下不可用"; + if (lib.dynamicTranslate[skill]) lib.dynamicTranslate[skill] = () => "此模式下不可用"; }; - if ((info.forbid && info.forbid.includes(mode)) || (info.mode && info.mode.includes(mode) == false) || (info.available && info.available(mode) == false)) { + if ( + (info.forbid && info.forbid.includes(mode)) || + (info.mode && info.mode.includes(mode) == false) || + (info.available && info.available(mode) == false) + ) { deleteSkill(i, iInfo); return; } - if (info.viewAs && typeof info.viewAs != 'function') { - if (typeof info.viewAs == 'string') info.viewAs = { - name: info.viewAs - }; + if (info.viewAs && typeof info.viewAs != "function") { + if (typeof info.viewAs == "string") + info.viewAs = { + name: info.viewAs, + }; if (!lib.card[info.viewAs.name]) { deleteSkill(i, iInfo); return; } if (info.ai == undefined) info.ai = {}; - const skill = info.ai, card = lib.card[info.viewAs.name].ai; - if (card) Object.keys(card).forEach(value => { - if (skill[value] == undefined) skill[value] = card[value]; - else if (typeof skill[value] == 'object') Object.keys(card[value]).forEach(element => { - if (skill[value][element] == undefined) skill[value][element] = card[value][element]; + const skill = info.ai, + card = lib.card[info.viewAs.name].ai; + if (card) + Object.keys(card).forEach((value) => { + if (skill[value] == undefined) skill[value] = card[value]; + else if (typeof skill[value] == "object") + Object.keys(card[value]).forEach((element) => { + if (skill[value][element] == undefined) + skill[value][element] = card[value][element]; + }); }); - }); } if (info.inherit) { const skill = lib.skill[info.inherit]; - if (skill) Object.keys(skill).forEach(value => { - if (info[value] != undefined) return; - if (value == 'audio' && (typeof info[value] == 'number' || typeof info[value] == 'boolean')) info[value] = info.inherit; - else info[value] = skill[value]; - }); + if (skill) + Object.keys(skill).forEach((value) => { + if (info[value] != undefined) return; + if ( + value == "audio" && + (typeof info[value] == "number" || typeof info[value] == "boolean") + ) + info[value] = info.inherit; + else info[value] = skill[value]; + }); if (lib.translate[i] == undefined) lib.translate[i] = lib.translate[info.inherit]; - if (lib.translate[iInfo] == undefined) lib.translate[iInfo] = lib.translate[`${info.inherit}_info`]; + if (lib.translate[iInfo] == undefined) + lib.translate[iInfo] = lib.translate[`${info.inherit}_info`]; } if (info.limited) { if (info.mark === undefined) info.mark = true; if (!info.intro) info.intro = {}; - if (info.intro.content === undefined) info.intro.content = 'limited'; + if (info.intro.content === undefined) info.intro.content = "limited"; if (info.skillAnimation === undefined) info.skillAnimation = true; - if (info.init === undefined) info.init = (player, skill) => player.storage[skill] = false; + if (info.init === undefined) info.init = (player, skill) => (player.storage[skill] = false); } - if (info.subSkill && !sub) Object.keys(info.subSkill).forEach(value => { - const iValue = `${i}_${value}`; - lib.skill[iValue] = info.subSkill[value]; - lib.skill[iValue].sub = true; - if (info.subSkill[value].name) lib.translate[iValue] = info.subSkill[value].name; - else lib.translate[iValue] = lib.translate[iValue] || lib.translate[i]; - if (info.subSkill[value].description) lib.translate[`${iValue}_info`] = info.subSkill[value].description; - if (info.subSkill[value].marktext) lib.translate[`${iValue}_bg`] = info.subSkill[value].marktext; - game.finishSkill(iValue, true); - }); + if (info.subSkill && !sub) + Object.keys(info.subSkill).forEach((value) => { + const iValue = `${i}_${value}`; + lib.skill[iValue] = info.subSkill[value]; + lib.skill[iValue].sub = true; + if (info.subSkill[value].name) lib.translate[iValue] = info.subSkill[value].name; + else lib.translate[iValue] = lib.translate[iValue] || lib.translate[i]; + if (info.subSkill[value].description) + lib.translate[`${iValue}_info`] = info.subSkill[value].description; + if (info.subSkill[value].marktext) + lib.translate[`${iValue}_bg`] = info.subSkill[value].marktext; + game.finishSkill(iValue, true); + }); if (info.round) { const k = `${i}_roundcount`; - if (typeof info.group == 'string') info.group = [info.group, k]; + if (typeof info.group == "string") info.group = [info.group, k]; else if (Array.isArray(info.group)) info.group.add(k); else info.group = [k]; lib.skill[k] = ((round, name) => ({ - init: player => { - if (typeof player.storage[name] !== 'number') player.storage[name] = 1 - round; + init: (player) => { + if (typeof player.storage[name] !== "number") player.storage[name] = 1 - round; }, intro: { content: (storage, player) => { - let str = ''; - const info = get.info(name.slice(0, name.indexOf('_roundcount'))); + let str = ""; + const info = get.info(name.slice(0, name.indexOf("_roundcount"))); if (info && info.addintro) str += info.addintro(storage, player); const num = round - (game.roundNumber - storage); - if (num > 0) str += `${get.cnNumber(num)}轮后${info.roundtext || '技能重置'}`; - else str += '技能可发动'; + if (num > 0) str += `${get.cnNumber(num)}轮后${info.roundtext || "技能重置"}`; + else str += "技能可发动"; return str; }, - markcount: (storage, player) => Math.max(round - (game.roundNumber - storage), 0) + markcount: (storage, player) => Math.max(round - (game.roundNumber - storage), 0), }, - trigger: { global: 'roundStart' }, + trigger: { global: "roundStart" }, forced: true, popup: false, silent: true, content: () => { - if (lib.skill[event.name.slice(0, event.name.indexOf('_roundcount'))].round - (game.roundNumber - player.storage[event.name]) > 0) player.updateMarks(); + if ( + lib.skill[event.name.slice(0, event.name.indexOf("_roundcount"))].round - + (game.roundNumber - player.storage[event.name]) > + 0 + ) + player.updateMarks(); else player.unmarkSkill(event.name); - } + }, }))(info.round, k); - lib.translate[k] = lib.translate[i] || ''; + lib.translate[k] = lib.translate[i] || ""; lib.translate[`${k}_bg`] = lib.translate[`${i}_bg`] || lib.translate[k][0]; } if (info.marktext) lib.translate[`${i}_bg`] = info.marktext; if (info.silent) { - if (!('forced' in info)) info.forced = true; - if (!('popup' in info)) info.popup = false; + if (!("forced" in info)) info.forced = true; + if (!("popup" in info)) info.popup = false; } - if (!('_priority' in info)) { + if (!("_priority" in info)) { let priority = 0; if (info.priority) { priority = info.priority * 100; @@ -7284,42 +7669,54 @@ export class Game extends Uninstantable { if (info.ruleSkill) priority -= 75; info._priority = priority; } - if (i[0] == '_') game.addGlobalSkill(i); + if (i[0] == "_") game.addGlobalSkill(i); } - static finishCards() { + finishCards() { _status.cardsFinished = true; - const mode = get.mode(), filterTarget = (card, player, target) => player == target && target.canEquip(card, true), aiBasicOrder = (card, player) => { - const equipValue = get.equipValue(card, player) / 20; - return player && player.hasSkillTag('reverseEquip') ? 8.5 - equipValue : 8 + equipValue; - }, aiBasicValue = (card, player, index, method) => { - if (!player.getCards('e').includes(card) && !player.canEquip(card, true)) return 0.01; - const info = get.info(card), current = player.getEquip(info.subtype), value = current && card != current && get.value(current, player); - let equipValue = info.ai.equipValue || info.ai.basic.equipValue; - if (typeof equipValue == 'function') { - if (method == 'raw') return equipValue(card, player); - if (method == 'raw2') return equipValue(card, player) - value; - return Math.max(0.1, equipValue(card, player) - value); - } - if (typeof equipValue != 'number') equipValue = 0; - if (method == 'raw') return equipValue; - if (method == 'raw2') return equipValue - value; - return Math.max(0.1, equipValue - value); - }, aiResultTarget = (player, target, card) => get.equipResult(player, target, card.name); - Object.keys(lib.card).forEach(libCardKey => { + const mode = get.mode(), + filterTarget = (card, player, target) => player == target && target.canEquip(card, true), + aiBasicOrder = (card, player) => { + const equipValue = get.equipValue(card, player) / 20; + return player && player.hasSkillTag("reverseEquip") ? 8.5 - equipValue : 8 + equipValue; + }, + aiBasicValue = (card, player, index, method) => { + if (!player.getCards("e").includes(card) && !player.canEquip(card, true)) return 0.01; + const info = get.info(card), + current = player.getEquip(info.subtype), + value = current && card != current && get.value(current, player); + let equipValue = info.ai.equipValue || info.ai.basic.equipValue; + if (typeof equipValue == "function") { + if (method == "raw") return equipValue(card, player); + if (method == "raw2") return equipValue(card, player) - value; + return Math.max(0.1, equipValue(card, player) - value); + } + if (typeof equipValue != "number") equipValue = 0; + if (method == "raw") return equipValue; + if (method == "raw2") return equipValue - value; + return Math.max(0.1, equipValue - value); + }, + aiResultTarget = (player, target, card) => get.equipResult(player, target, card.name); + Object.keys(lib.card).forEach((libCardKey) => { const info = `${libCardKey}_info`; if (lib.translate[`${info}_${mode}`]) lib.translate[info] = lib.translate[`${info}_${mode}`]; - else if (lib.translate[`${info}_zhu`] && (mode == 'identity' || mode == 'guozhan' && _status.mode == 'four')) lib.translate[info] = lib.translate[`${info}_zhu`]; - else if (lib.translate[`${info}_combat`] && get.is.versus()) lib.translate[info] = lib.translate[`${info}_combat`]; + else if ( + lib.translate[`${info}_zhu`] && + (mode == "identity" || (mode == "guozhan" && _status.mode == "four")) + ) + lib.translate[info] = lib.translate[`${info}_zhu`]; + else if (lib.translate[`${info}_combat`] && get.is.versus()) + lib.translate[info] = lib.translate[`${info}_combat`]; const card = lib.card[libCardKey]; if (card.filterTarget && card.selectTarget == undefined) card.selectTarget = 1; if (card.autoViewAs) { if (!card.ai) card.ai = {}; if (!card.ai.order) { card.ai.order = lib.card[card.autoViewAs].ai.order; - if (!card.ai.order && lib.card[card.autoViewAs].ai.basic) card.ai.order = lib.card[card.autoViewAs].ai.basic.order; + if (!card.ai.order && lib.card[card.autoViewAs].ai.basic) + card.ai.order = lib.card[card.autoViewAs].ai.basic.order; } } - if (card.type == 'equip') { + if (card.type == "equip") { if (card.enable == undefined) card.enable = true; if (card.selectTarget == undefined) card.selectTarget = -1; if (card.filterTarget == undefined) card.filterTarget = filterTarget; @@ -7327,43 +7724,43 @@ export class Game extends Uninstantable { if (card.allowMultiple == undefined) card.allowMultiple = false; if (card.content == undefined) card.content = lib.element.content.equipCard; if (card.toself == undefined) card.toself = true; - if (card.ai == undefined) card.ai = { - basic: {} - }; + if (card.ai == undefined) + card.ai = { + basic: {}, + }; if (card.ai.basic == undefined) card.ai.basic = {}; - if (card.ai.result == undefined) card.ai.result = { - target: 1.5 - }; + if (card.ai.result == undefined) + card.ai.result = { + target: 1.5, + }; if (card.ai.basic.order == undefined) card.ai.basic.order = aiBasicOrder; if (card.ai.basic.useful == undefined) card.ai.basic.useful = 2; - if (card.subtype == 'equip3') { + if (card.subtype == "equip3") { if (card.ai.basic.equipValue == undefined) card.ai.basic.equipValue = 7; - } - else if (card.subtype == 'equip4') { + } else if (card.subtype == "equip4") { if (card.ai.basic.equipValue == undefined) card.ai.basic.equipValue = 4; - } - else if (card.ai.basic.equipValue == undefined) card.ai.basic.equipValue = 1; + } else if (card.ai.basic.equipValue == undefined) card.ai.basic.equipValue = 1; if (card.ai.basic.value == undefined) card.ai.basic.value = aiBasicValue; if (!card.ai.result.keepAI) card.ai.result.target = aiResultTarget; - } - else if (card.type == 'delay' || card.type == 'special_delay') { + } else if (card.type == "delay" || card.type == "special_delay") { if (card.enable == undefined) card.enable = true; if (card.filterTarget == undefined) card.filterTarget = lib.filter.judge; if (card.content == undefined) card.content = lib.element.content.addJudgeCard; if (card.allowMultiple == undefined) card.allowMultiple = false; } }); - Object.keys(lib.skill).forEach(value => game.finishSkill(value)); + Object.keys(lib.skill).forEach((value) => game.finishSkill(value)); } /** * 这玩意至少19种重载了吧 */ - static checkMod() { - const argumentArray = Array.from(arguments), name = argumentArray[argumentArray.length - 2]; + checkMod() { + const argumentArray = Array.from(arguments), + name = argumentArray[argumentArray.length - 2]; let skills = argumentArray[argumentArray.length - 1]; - if (typeof skills.getModableSkills == 'function') { + if (typeof skills.getModableSkills == "function") { skills = skills.getModableSkills(); - } else if (typeof skills.getSkills == 'function') { + } else if (typeof skills.getSkills == "function") { skills = skills.getSkills().concat(lib.skill.global); game.expandSkills(skills); skills = skills.filter(function (skill) { @@ -7373,18 +7770,18 @@ export class Game extends Uninstantable { skills.sort((a, b) => get.priority(a) - get.priority(b)); } const arg = argumentArray.slice(0, -2); - skills.forEach(value => { + skills.forEach((value) => { var mod = get.info(value).mod[name]; if (!mod) return; - const result = mod.call(this,...arg); - if (result != undefined && typeof arg[arg.length - 1] != 'object') arg[arg.length - 1] = result; + const result = mod.call(this, ...arg); + if (result != undefined && typeof arg[arg.length - 1] != "object") arg[arg.length - 1] = result; }); return arg[arg.length - 1]; } /** - * @param { number } num + * @param { number } num */ - static prepareArena(num) { + prepareArena(num) { _status.prepareArena = true; game.showHistory(false); ui.create.players(num); @@ -7392,10 +7789,10 @@ export class Game extends Uninstantable { ui.create.cardsAsync(); game.finishCards(); } - static clearArena() { - ui.control.innerHTML = ''; - ui.arenalog.innerHTML = ''; - Array.from(ui.arena.childNodes).forEach(value => { + clearArena() { + ui.control.innerHTML = ""; + ui.arenalog.innerHTML = ""; + Array.from(ui.arena.childNodes).forEach((value) => { if (value == ui.canvas) return; if (value == ui.control) return; if (value == ui.arenalog) return; @@ -7404,17 +7801,17 @@ export class Game extends Uninstantable { if (value == ui.autonode) return; value.remove(); }); - ui.sidebar.innerHTML = ''; - ui.cardPile.innerHTML = ''; - ui.discardPile.innerHTML = ''; - ui.special.innerHTML = ''; - ui.ordering.innerHTML = ''; + ui.sidebar.innerHTML = ""; + ui.cardPile.innerHTML = ""; + ui.discardPile.innerHTML = ""; + ui.special.innerHTML = ""; + ui.ordering.innerHTML = ""; ui.playerids.remove(); game.players.length = 0; game.dead.length = 0; game.me = null; } - static clearConnect() { + clearConnect() { if (ui.ipnode) { ui.ipnode.remove(); delete ui.ipnode; @@ -7440,7 +7837,7 @@ export class Game extends Uninstantable { delete ui.startServer; } if (ui.rooms) { - ui.rooms.forEach(value => value.remove()); + ui.rooms.forEach((value) => value.remove()); delete ui.rooms; } if (ui.roombase) { @@ -7459,46 +7856,48 @@ export class Game extends Uninstantable { delete ui.connectClientsCount; delete ui.createRoomButton; } - static log() { - let str = '', str2 = '', logvid = null; + log() { + let str = "", + str2 = "", + logvid = null; const color = new Map([ - ['r', 'fire'], - ['y', 'yellow'], - ['g', 'green'], - ['b', 'blue'] + ["r", "fire"], + ["y", "yellow"], + ["g", "green"], + ["b", "blue"], ]); - Array.from(arguments).forEach(value => { + Array.from(arguments).forEach((value) => { const itemtype = get.itemtype(value); - if (itemtype == 'player' || itemtype == 'players') { + if (itemtype == "player" || itemtype == "players") { str += `${get.translation(value)}`; str2 += get.translation(value); - } - else if (itemtype == 'cards' || itemtype == 'card' || (typeof value == 'object' && value && value.name)) { + } else if ( + itemtype == "cards" || + itemtype == "card" || + (typeof value == "object" && value && value.name) + ) { str += `${get.translation(value)}`; str2 += get.translation(value); - } - else if (typeof value == 'object') { + } else if (typeof value == "object") { if (value.parentNode == ui.historybar) logvid = value.logvid; else { str += get.translation(value); str2 += get.translation(value); } - } - else if (typeof value == 'string') { - if (value[0] == '【' && value[value.length - 1] == '】') { + } else if (typeof value == "string") { + if (value[0] == "【" && value[value.length - 1] == "】") { str += `${get.translation(value)}`; str2 += get.translation(value); - } - else if (value[0] == '#') { - str += `${get.translation(value.slice(2))}`; + } else if (value[0] == "#") { + str += `${get.translation( + value.slice(2) + )}`; str2 += get.translation(value.slice(2)); - } - else { + } else { str += get.translation(value); str2 += get.translation(value); } - } - else { + } else { str += value; str2 += value; } @@ -7506,55 +7905,57 @@ export class Game extends Uninstantable { const node = ui.create.div(); node.innerHTML = lib.config.log_highlight ? str : str2; ui.sidebar.insertBefore(node, ui.sidebar.firstChild); - game.addVideo('log', null, lib.config.log_highlight ? str : str2); + game.addVideo("log", null, lib.config.log_highlight ? str : str2); game.broadcast((str, str2) => game.log(lib.config.log_highlight ? str : str2), str, str2); if (!_status.video && !game.online) { - if (logvid) game.logv(logvid, `
                                    ${lib.config.log_highlight ? str : str2}
                                    `); + if (logvid) + game.logv(logvid, `
                                    ${lib.config.log_highlight ? str : str2}
                                    `); else logvid = _status.event.getLogv(); } - if (lib.config.show_log == 'off' || game.chess) return; + if (lib.config.show_log == "off" || game.chess) return; const nodeentry = node.cloneNode(true); ui.arenalog.insertBefore(nodeentry, ui.arenalog.firstChild); - if (!lib.config.clear_log) while (ui.arenalog.childNodes.length && ui.arenalog.scrollHeight > ui.arenalog.offsetHeight) { - ui.arenalog.lastChild.remove(); - } + if (!lib.config.clear_log) + while (ui.arenalog.childNodes.length && ui.arenalog.scrollHeight > ui.arenalog.offsetHeight) { + ui.arenalog.lastChild.remove(); + } if (!lib.config.low_performance) { - nodeentry.style.transition = 'all 0s'; + nodeentry.style.transition = "all 0s"; nodeentry.style.marginBottom = `-${nodeentry.offsetHeight}px`; ui.refresh(nodeentry); - nodeentry.style.transition = ''; - nodeentry.style.marginBottom = ''; + nodeentry.style.transition = ""; + nodeentry.style.marginBottom = ""; } if (!lib.config.clear_log) return; nodeentry.timeout = setTimeout(() => nodeentry.delete(), 1000); - Array.from(ui.arenalog.childNodes).forEach(value => { + Array.from(ui.arenalog.childNodes).forEach((value) => { if (!value.timeout) value.remove(); }); } /** - * @param { Player } player - * @param { string | Card[] } card - * @param { Player[] } [targets] - * @param { GameEventPromise } [event] - * @param { boolean } [forced] - * @param { string } [logvid] + * @param { Player } player + * @param { string | Card[] } card + * @param { Player[] } [targets] + * @param { import('../library/index.js').GameEventPromise } [event] + * @param { boolean } [forced] + * @param { string } [logvid] */ - static logv(player, card, targets, event, forced, logvid) { + logv(player, card, targets, event, forced, logvid) { if (!player) { player = _status.event.getParent().logvid; if (!player) return; } - const node = ui.create.div('.hidden'); + const node = ui.create.div(".hidden"); node.node = {}; logvid = logvid || get.id(); game.broadcast(game.logv, player, card, targets, event, forced, logvid); - if (typeof player == 'string') { - const childNode = Array.from(ui.historybar.childNodes).find(value => value.logvid == player); + if (typeof player == "string") { + const childNode = Array.from(ui.historybar.childNodes).find((value) => value.logvid == player); if (childNode) childNode.added.push(card); return; } - if (typeof card == 'string') { - if (card != 'die') { + if (typeof card == "string") { + if (card != "die") { if (lib.skill[card] && lib.skill[card].logv === false && !forced) return; if (!lib.translate[card]) return; } @@ -7563,99 +7964,102 @@ export class Game extends Uninstantable { else if (!player.isUnseen(1)) avatar = player.node.avatar2.cloneNode(); else return; node.node.avatar = avatar; - avatar.style.transform = ''; - avatar.className = 'avatar'; - if (card == 'die') { + avatar.style.transform = ""; + avatar.className = "avatar"; + if (card == "die") { node.dead = true; node.player = player; const avatar2 = avatar.cloneNode(); - avatar2.className = 'avatarbg grayscale1'; + avatar2.className = "avatarbg grayscale1"; avatar.appendChild(avatar2); avatar.style.opacity = 0.6; - } - else { - node.node.text = ui.create.div('', get.translation(card, 'skill'), avatar); - node.node.text.dataset.nature = 'water'; + } else { + node.node.text = ui.create.div("", get.translation(card, "skill"), avatar); + node.node.text.dataset.nature = "water"; node.skill = card; } node.appendChild(avatar); - if (card == 'die' && targets && targets != player) { + if (card == "die" && targets && targets != player) { node.source = targets; player = targets; if (!player.isUnseen(0)) avatar = player.node.avatar.cloneNode(); else if (!player.isUnseen(1)) avatar = player.node.avatar2.cloneNode(); - else if (get.mode() == 'guozhan' && player.node && player.node.name_seat) { - avatar = ui.create.div('.avatar.cardbg'); + else if (get.mode() == "guozhan" && player.node && player.node.name_seat) { + avatar = ui.create.div(".avatar.cardbg"); avatar.innerHTML = player.node.name_seat.innerHTML[0]; - } - else return; - avatar.style.transform = ''; + } else return; + avatar.style.transform = ""; node.node.avatar2 = avatar; - avatar.classList.add('avatar2'); + avatar.classList.add("avatar2"); node.appendChild(avatar); } - } - else if (Array.isArray(card)) { - node.cards = card[1].slice(0) + } else if (Array.isArray(card)) { + node.cards = card[1].slice(0); card = card[0]; - const info = [card.suit || '', card.number || '', card.name || '', card.nature || '']; - if (!Array.isArray(node.cards) || !node.cards.length) node.cards = [ui.create.card(node, 'noclick', true).init(info)]; - if (card.name == 'wuxie') { - if (ui.historybar.firstChild && ui.historybar.firstChild.type == 'wuxie') { + const info = [card.suit || "", card.number || "", card.name || "", card.nature || ""]; + if (!Array.isArray(node.cards) || !node.cards.length) + node.cards = [ui.create.card(node, "noclick", true).init(info)]; + if (card.name == "wuxie") { + if (ui.historybar.firstChild && ui.historybar.firstChild.type == "wuxie") { ui.historybar.firstChild.players.push(player); ui.historybar.firstChild.cards.addArray(node.cards); return; } - node.type = 'wuxie'; + node.type = "wuxie"; node.players = [player]; } if (card.copy) card.copy(node, false); else { - card = ui.create.card(node, 'noclick', true); + card = ui.create.card(node, "noclick", true); card.init(info); } let avatar; if (!player.isUnseen(0)) avatar = player.node.avatar.cloneNode(); else if (!player.isUnseen(1)) avatar = player.node.avatar2.cloneNode(); - else if (get.mode() == 'guozhan' && player.node && player.node.name_seat) { - avatar = ui.create.div('.avatar.cardbg'); + else if (get.mode() == "guozhan" && player.node && player.node.name_seat) { + avatar = ui.create.div(".avatar.cardbg"); avatar.innerHTML = player.node.name_seat.innerHTML[0]; - } - else return; + } else return; node.node.avatar = avatar; - avatar.style.transform = ''; - avatar.classList.add('avatar2'); + avatar.style.transform = ""; + avatar.classList.add("avatar2"); node.appendChild(avatar); - if (targets && targets.length == 1 && targets[0] != player && get.itemtype(targets[0]) == 'player') (() => { - let avatar2; - const target = targets[0]; - if (!target.isUnseen(0)) avatar2 = target.node.avatar.cloneNode(); - else if (!player.isUnseen(1)) avatar2 = target.node.avatar2.cloneNode(); - else if (get.mode() == 'guozhan' && target.node && target.node.name_seat) { - avatar2 = ui.create.div('.avatar.cardbg'); - avatar2.innerHTML = target.node.name_seat.innerHTML[0]; - } - else return; - node.node.avatar2 = avatar2; - avatar2.style.transform = ''; - avatar2.classList.add('avatar2'); - avatar2.classList.add('avatar3'); - node.insertBefore(avatar2, avatar); - })(); + if ( + targets && + targets.length == 1 && + targets[0] != player && + get.itemtype(targets[0]) == "player" + ) + (() => { + let avatar2; + const target = targets[0]; + if (!target.isUnseen(0)) avatar2 = target.node.avatar.cloneNode(); + else if (!player.isUnseen(1)) avatar2 = target.node.avatar2.cloneNode(); + else if (get.mode() == "guozhan" && target.node && target.node.name_seat) { + avatar2 = ui.create.div(".avatar.cardbg"); + avatar2.innerHTML = target.node.name_seat.innerHTML[0]; + } else return; + node.node.avatar2 = avatar2; + avatar2.style.transform = ""; + avatar2.classList.add("avatar2"); + avatar2.classList.add("avatar3"); + node.insertBefore(avatar2, avatar); + })(); } if (targets && targets.length) { if (targets.length == 1 && targets[0] == player) { node.targets = []; - } - else { + } else { node.targets = targets; } } - const fullheight = ui.historybar.offsetHeight, num = Math.round((fullheight - 8) / 50), margin = (fullheight - 42 * num) / (num + 1); - node.style.transform = 'scale(0.8)'; + const fullheight = ui.historybar.offsetHeight, + num = Math.round((fullheight - 8) / 50), + margin = (fullheight - 42 * num) / (num + 1); + node.style.transform = "scale(0.8)"; ui.historybar.insertBefore(node, ui.historybar.firstChild); ui.refresh(node); - node.classList.remove('hidden'); + node.classList.remove("hidden"); Array.from(ui.historybar.childNodes).forEach((value, index) => { if (index < num) { value.style.transform = `scale(1) translateY(${margin + index * (42 + margin) - 4}px)`; @@ -7664,12 +8068,18 @@ export class Game extends Uninstantable { if (value.removetimeout) return; value.style.opacity = 0; value.style.transform = `scale(1) translateY(${fullheight}px)`; - value.removetimeout = setTimeout((current => () => current.remove())(value), 500); + value.removetimeout = setTimeout( + ( + (current) => () => + current.remove() + )(value), + 500 + ); }); - if (lib.config.touchscreen) node.addEventListener('touchstart', ui.click.intro); + if (lib.config.touchscreen) node.addEventListener("touchstart", ui.click.intro); else { - node.addEventListener(lib.config.pop_logv ? 'mousemove' : 'click', ui.click.logv); - node.addEventListener('mouseleave', ui.click.logvleave); + node.addEventListener(lib.config.pop_logv ? "mousemove" : "click", ui.click.logv); + node.addEventListener("mouseleave", ui.click.logvleave); } node.logvid = logvid; node.added = []; @@ -7680,40 +8090,53 @@ export class Game extends Uninstantable { return node; } /** - * @param { string } storeName - * @param { string } idbValidKey - * @param { any } value - * @param { Function } [onSuccess] - * @param { Function } [onError] + * @param { string } storeName + * @param { string } idbValidKey + * @param { any } value + * @param { Function } [onSuccess] + * @param { Function } [onError] */ - static putDB(storeName, idbValidKey, value, onSuccess, onError) { + putDB(storeName, idbValidKey, value, onSuccess, onError) { if (!lib.db) return Promise.resolve(value); - if (lib.status.reload) return new Promise((resolve, reject) => lib[_status.dburgent ? 'ondb2' : 'ondb'].push(['putDB', [storeName, idbValidKey, value, event => { - if (typeof onSuccess == 'function') onSuccess(event); - resolve(event); - }, event => { - if (typeof onError == 'function') { - onError(event); - resolve(); - } - else reject(event); - }]])); + if (lib.status.reload) + return new Promise((resolve, reject) => + lib[_status.dburgent ? "ondb2" : "ondb"].push([ + "putDB", + [ + storeName, + idbValidKey, + value, + (event) => { + if (typeof onSuccess == "function") onSuccess(event); + resolve(event); + }, + (event) => { + if (typeof onError == "function") { + onError(event); + resolve(); + } else reject(event); + }, + ], + ]) + ); lib.status.reload++; return new Promise((resolve, reject) => { - const record = lib.db.transaction([storeName], 'readwrite').objectStore(storeName).put(value, idbValidKey); - record.onerror = event => { - if (typeof onError == 'function') { + const record = lib.db + .transaction([storeName], "readwrite") + .objectStore(storeName) + .put(value, idbValidKey); + record.onerror = (event) => { + if (typeof onError == "function") { onError(event); game.reload2(); resolve(); - } - else { + } else { game.reload2(); reject(event); } }; - record.onsuccess = event => { - if (typeof onSuccess == 'function') { + record.onsuccess = (event) => { + if (typeof onSuccess == "function") { _status.dburgent = true; onSuccess(event); delete _status.dburgent; @@ -7724,165 +8147,205 @@ export class Game extends Uninstantable { }); } /** - * - * @param { string } storeName - * @param { string | null } [query] - * @param { Function } [onSuccess] - * @param { Function } [onError] + * + * @param { string } storeName + * @param { string | null } [query] + * @param { Function } [onSuccess] + * @param { Function } [onError] */ - static getDB(storeName, query, onSuccess, onError) { - if (!lib.db) return new Promise(resolve => { - if (typeof onSuccess == 'function') onSuccess(null); - resolve(null); - }); - if (lib.status.reload) return new Promise((resolve, reject) => lib[_status.dburgent ? 'ondb2' : 'ondb'].push(['getDB', [storeName, query, result => { - if (typeof onSuccess == 'function') onSuccess(result); - resolve(result); - }, event => { - if (typeof onError == 'function') { - onError(event); - resolve(); - } - else reject(event); - }]])); - return new Promise(query ? (resolve, reject) => { - lib.status.reload++; - const idbRequest = lib.db.transaction([storeName], 'readwrite').objectStore(storeName).get(query); - idbRequest.onerror = event => { - if (typeof onError == 'function') { - onError(event); - game.reload2(); - resolve(); - } - else { - game.reload2(); - reject(event); - } - }; - idbRequest.onsuccess = event => { - const result = event.target.result; - if (typeof onSuccess == 'function') { - _status.dburgent = true; - onSuccess(result); - delete _status.dburgent; - } - game.reload2(); - resolve(result); - }; - } : (resolve, reject) => { - lib.status.reload++; - const idbRequest = lib.db.transaction([storeName], 'readwrite').objectStore(storeName).openCursor(), object = {}; - idbRequest.onerror = event => { - if (typeof onError == 'function') { - onError(event); - game.reload2(); - resolve(); - } - else { - game.reload2(); - reject(event); - } - }; - idbRequest.onsuccess = event => { - const result = event.target.result; - if (result) { - object[result.key] = result.value; - result.continue(); - return; - } - if (typeof onSuccess == 'function') { - _status.dburgent = true; - onSuccess(object); - delete _status.dburgent; - } - game.reload2(); - resolve(object); - }; - }); + getDB(storeName, query, onSuccess, onError) { + if (!lib.db) + return new Promise((resolve) => { + if (typeof onSuccess == "function") onSuccess(null); + resolve(null); + }); + if (lib.status.reload) + return new Promise((resolve, reject) => + lib[_status.dburgent ? "ondb2" : "ondb"].push([ + "getDB", + [ + storeName, + query, + (result) => { + if (typeof onSuccess == "function") onSuccess(result); + resolve(result); + }, + (event) => { + if (typeof onError == "function") { + onError(event); + resolve(); + } else reject(event); + }, + ], + ]) + ); + return new Promise( + query + ? (resolve, reject) => { + lib.status.reload++; + const idbRequest = lib.db + .transaction([storeName], "readwrite") + .objectStore(storeName) + .get(query); + idbRequest.onerror = (event) => { + if (typeof onError == "function") { + onError(event); + game.reload2(); + resolve(); + } else { + game.reload2(); + reject(event); + } + }; + idbRequest.onsuccess = (event) => { + const result = event.target.result; + if (typeof onSuccess == "function") { + _status.dburgent = true; + onSuccess(result); + delete _status.dburgent; + } + game.reload2(); + resolve(result); + }; + } + : (resolve, reject) => { + lib.status.reload++; + const idbRequest = lib.db + .transaction([storeName], "readwrite") + .objectStore(storeName) + .openCursor(), + object = {}; + idbRequest.onerror = (event) => { + if (typeof onError == "function") { + onError(event); + game.reload2(); + resolve(); + } else { + game.reload2(); + reject(event); + } + }; + idbRequest.onsuccess = (event) => { + const result = event.target.result; + if (result) { + object[result.key] = result.value; + result.continue(); + return; + } + if (typeof onSuccess == "function") { + _status.dburgent = true; + onSuccess(object); + delete _status.dburgent; + } + game.reload2(); + resolve(object); + }; + } + ); } /** - * @param { string } storeName - * @param { string } [query] - * @param { Function } [onSuccess] - * @param { Function } [onError] + * @param { string } storeName + * @param { string } [query] + * @param { Function } [onSuccess] + * @param { Function } [onError] */ - static deleteDB(storeName, query, onSuccess, onError) { - if (!lib.db) return new Promise(resolve => { - if (typeof onSuccess == 'function') onSuccess(false); - resolve(false); - }); - if (lib.status.reload) return new Promise((resolve, reject) => lib[_status.dburgent ? 'ondb2' : 'ondb'].push(['deleteDB', [storeName, query, event => { - if (typeof onSuccess == 'function') onSuccess(event); - resolve(event); - }, event => { - if (typeof onError == 'function') { - onError(event); - resolve(); - } - else reject(event); - }]])); - return query ? new Promise((resolve, reject) => { - lib.status.reload++; - const record = lib.db.transaction([storeName], 'readwrite').objectStore(storeName).delete(query); - record.onerror = event => { - if (typeof onError == 'function') { - onError(event); - game.reload2(); - resolve(); - } - else { - game.reload2(); - reject(event); - } - }; - record.onsuccess = event => { - if (typeof onSuccess == 'function') onSuccess(event); - game.reload2(); - resolve(event); - }; - }) : game.getDB(storeName).then(object => { - const keys = Object.keys(object); - lib.status.reload += keys.length; - const store = lib.db.transaction([storeName], 'readwrite').objectStore(storeName); - return Promise.allSettled(keys.map(key => new Promise((resolve, reject) => { - const request = store.delete(key); - request.onerror = event => { - game.reload2(); - reject(event); - }; - request.onsuccess = event => { - game.reload2(); - resolve(event); - }; - }))); - }); + deleteDB(storeName, query, onSuccess, onError) { + if (!lib.db) + return new Promise((resolve) => { + if (typeof onSuccess == "function") onSuccess(false); + resolve(false); + }); + if (lib.status.reload) + return new Promise((resolve, reject) => + lib[_status.dburgent ? "ondb2" : "ondb"].push([ + "deleteDB", + [ + storeName, + query, + (event) => { + if (typeof onSuccess == "function") onSuccess(event); + resolve(event); + }, + (event) => { + if (typeof onError == "function") { + onError(event); + resolve(); + } else reject(event); + }, + ], + ]) + ); + return query + ? new Promise((resolve, reject) => { + lib.status.reload++; + const record = lib.db + .transaction([storeName], "readwrite") + .objectStore(storeName) + .delete(query); + record.onerror = (event) => { + if (typeof onError == "function") { + onError(event); + game.reload2(); + resolve(); + } else { + game.reload2(); + reject(event); + } + }; + record.onsuccess = (event) => { + if (typeof onSuccess == "function") onSuccess(event); + game.reload2(); + resolve(event); + }; + }) + : game.getDB(storeName).then((object) => { + const keys = Object.keys(object); + lib.status.reload += keys.length; + const store = lib.db.transaction([storeName], "readwrite").objectStore(storeName); + return Promise.allSettled( + keys.map( + (key) => + new Promise((resolve, reject) => { + const request = store.delete(key); + request.onerror = (event) => { + game.reload2(); + reject(event); + }; + request.onsuccess = (event) => { + game.reload2(); + resolve(event); + }; + }) + ) + ); + }); } /** - * @param { string } key - * @param { * } [value] - * @param { string } [mode] + * @param { string } key + * @param { * } [value] + * @param { string } [mode] */ - static save(key, value, mode) { + save(key, value, mode) { if (_status.reloading) return; mode = mode || lib.config.mode; if (lib.db) { if (!key) { - game.putDB('data', mode, get.copy(lib.storage)); + game.putDB("data", mode, get.copy(lib.storage)); return; } if (mode == lib.config.mode) { if (value == undefined) delete lib.storage[key]; else lib.storage[key] = value; lib.storage.version = lib.version; - game.putDB('data', mode, lib.storage); - } - else game.getDB('data', mode, config => { - if (!config) config = {}; - if (value == undefined) delete config[key]; - else config[key] = value; - config.version = lib.version; - game.putDB('data', mode, config); - }); + game.putDB("data", mode, lib.storage); + } else + game.getDB("data", mode, (config) => { + if (!config) config = {}; + if (value == undefined) delete config[key]; + else config[key] = value; + config.version = lib.version; + game.putDB("data", mode, config); + }); return; } if (!key) { @@ -7892,76 +8355,78 @@ export class Game extends Uninstantable { let config; try { config = JSON.parse(localStorage.getItem(`${lib.configprefix}${mode}`)); - if (typeof config != 'object') throw 'err'; - } - catch (err) { + if (typeof config != "object") throw "err"; + } catch (err) { config = {}; } if (value == undefined) { delete config[key]; if (mode == lib.config.mode) delete lib.storage[key]; - } - else { + } else { config[key] = value; if (mode == lib.config.mode) lib.storage[key] = value; } config.version = lib.version; localStorage.setItem(`${lib.configprefix}${mode}`, JSON.stringify(config)); } - static showChangeLog() { + showChangeLog() { if (lib.version == lib.config.version && !_status.extensionChangeLog) return; - const ul = document.createElement('ul'); - ul.style.textAlign = 'left'; - const caption = lib.version == lib.config.version ? '扩展更新' : `${lib.version}更新内容`; - let players = null, cards = null; - if (lib.version != lib.config.version) lib.changeLog.forEach(value => { - if (value.startsWith('players://')) try { - players = JSON.parse(value.slice(10)).filter(value => lib.character[value]); - } - catch (e) { - players = null; + const ul = document.createElement("ul"); + ul.style.textAlign = "left"; + const caption = lib.version == lib.config.version ? "扩展更新" : `${lib.version}更新内容`; + let players = null, + cards = null; + if (lib.version != lib.config.version) + lib.changeLog.forEach((value) => { + if (value.startsWith("players://")) + try { + players = JSON.parse(value.slice(10)).filter((value) => lib.character[value]); + } catch (e) { + players = null; + } + else if (value.startsWith("cards://")) + try { + cards = JSON.parse(value.slice(8)).filter((value) => lib.card[value]); + } catch (e) { + cards = null; + } + else { + const li = document.createElement("li"); + li.innerHTML = value; + ul.appendChild(li); } - else if (value.startsWith('cards://')) try { - cards = JSON.parse(value.slice(8)).filter(value => lib.card[value]); - } - catch (e) { - cards = null; - } - else { - const li = document.createElement('li'); - li.innerHTML = value; + }); + game.saveConfig("version", lib.version); + if (_status.extensionChangeLog) + Object.keys(_status.extensionChangeLog).forEach((value) => { + const li = document.createElement("li"); + li.innerHTML = `${value}:${_status.extensionChangeLog[value]}`; ul.appendChild(li); - } - }); - game.saveConfig('version', lib.version); - if (_status.extensionChangeLog) Object.keys(_status.extensionChangeLog).forEach(value => { - const li = document.createElement('li'); - li.innerHTML = `${value}:${_status.extensionChangeLog[value]}`; - ul.appendChild(li); - }); - const dialog = ui.create.dialog(caption, 'hidden'), lic = ui.create.div(dialog.content); - lic.style.display = 'block'; - ul.style.display = 'inline-block'; - ul.style.marginLeft = '-40px'; + }); + const dialog = ui.create.dialog(caption, "hidden"), + lic = ui.create.div(dialog.content); + lic.style.display = "block"; + ul.style.display = "inline-block"; + ul.style.marginLeft = "-40px"; lic.appendChild(ul); if (players && players.length) { - dialog.addSmall([players, 'character']); - dialog.classList.add('forcebutton'); - dialog.classList.add('withbg'); + dialog.addSmall([players, "character"]); + dialog.classList.add("forcebutton"); + dialog.classList.add("withbg"); } if (cards && cards.length) { - dialog.addSmall([cards.map(value => [get.translation(get.type(value)), '', value]), 'vcard']); - dialog.classList.add('forcebutton'); - dialog.classList.add('withbg'); + dialog.addSmall([cards.map((value) => [get.translation(get.type(value)), "", value]), "vcard"]); + dialog.classList.add("forcebutton"); + dialog.classList.add("withbg"); } dialog.open(); let hidden = false; - if (!ui.auto.classList.contains('hidden')) { + if (!ui.auto.classList.contains("hidden")) { ui.auto.hide(); hidden = true; } game.pause(); - const control = ui.create.control('确定', () => { + const control = ui.create.control("确定", () => { dialog.close(); control.close(); if (hidden) ui.auto.show(); @@ -7970,10 +8435,10 @@ export class Game extends Uninstantable { lib.init.onfree(); } /** - * @param { string } str - * @param { string } [extname] + * @param { string } str + * @param { string } [extname] */ - static showExtensionChangeLog(str, extname) { + showExtensionChangeLog(str, extname) { extname = extname || _status.extension; const cfg = `extension_${extname}_changelog`; if (!lib.extensionPack[extname] || lib.extensionPack[extname].version == lib.config[cfg]) return; @@ -7983,33 +8448,31 @@ export class Game extends Uninstantable { _status.extensionChangeLog[extname] = str; } /** - * @param { string } key - * @param { * } [value] - * @param { string | boolean } [local] - * @param { Function } [callback] + * @param { string } key + * @param { * } [value] + * @param { string | boolean } [local] + * @param { Function } [callback] */ - static saveConfig(key, value, local, callback) { + saveConfig(key, value, local, callback) { if (_status.reloading) return; if (local) { - const localmode = typeof local == 'string' ? local : lib.config.mode; + const localmode = typeof local == "string" ? local : lib.config.mode; if (!lib.config.mode_config[localmode]) lib.config.mode_config[localmode] = {}; if (value == undefined) delete lib.config.mode_config[localmode][key]; else lib.config.mode_config[localmode][key] = value; key += `_mode_config_${localmode}`; - } - else if (value == undefined) delete lib.config[key]; + } else if (value == undefined) delete lib.config[key]; else lib.config[key] = value; if (lib.db) { - if (value == undefined) game.deleteDB('config', key, callback); - else game.putDB('config', key, value, callback); + if (value == undefined) game.deleteDB("config", key, callback); + else game.putDB("config", key, value, callback); return; } let config; try { config = JSON.parse(localStorage.getItem(`${lib.configprefix}config`)); - if (!config || typeof config != 'object') throw 'err'; - } - catch (err) { + if (!config || typeof config != "object") throw "err"; + } catch (err) { config = {}; } if (value === undefined) delete config[key]; @@ -8018,63 +8481,74 @@ export class Game extends Uninstantable { if (callback) callback(); } /** - * @param { string } key + * @param { string } key */ - static saveConfigValue(key) { return game.saveConfig(key, lib.config[key]) } + saveConfigValue(key) { + return game.saveConfig(key, lib.config[key]); + } /** - * @param { string } extension - * @param { string } key + * @param { string } extension + * @param { string } key * @param { * } [value] */ - static saveExtensionConfig(extension, key, value) { return game.saveConfig(`extension_${extension}_${key}`, value) } + saveExtensionConfig(extension, key, value) { + return game.saveConfig(`extension_${extension}_${key}`, value); + } /** - * @param { string } extension - * @param { string } key + * @param { string } extension + * @param { string } key */ - static saveExtensionConfigValue(extension, key) { return game.saveExtensionConfig(extension, key, game.getExtensionConfig(extension, key)) } + saveExtensionConfigValue(extension, key) { + return game.saveExtensionConfig(extension, key, game.getExtensionConfig(extension, key)); + } /** - * @param { string } extension - * @param { string } key + * @param { string } extension + * @param { string } key */ - static getExtensionConfig(extension, key) { return lib.config[`extension_${extension}_${key}`] } + getExtensionConfig(extension, key) { + return lib.config[`extension_${extension}_${key}`]; + } /** - * @param { string } mode + * @param { string } mode */ - static clearModeConfig(mode) { + clearModeConfig(mode) { if (_status.reloading) return; if (lib.db) { - game.getDB('config', null, config => Object.keys(config).forEach(value => { - if (value.substr(value.indexOf('_mode_config') + 13) == mode) game.saveConfig(value); - })); + game.getDB("config", null, (config) => + Object.keys(config).forEach((value) => { + if (value.substr(value.indexOf("_mode_config") + 13) == mode) game.saveConfig(value); + }) + ); return; } let config; try { config = JSON.parse(localStorage.getItem(`${lib.configprefix}config`)); - if (!config || typeof config != 'object') throw 'err'; - } - catch (err) { + if (!config || typeof config != "object") throw "err"; + } catch (err) { config = {}; } - Object.keys(config).forEach(value => { - if (value.substr(value.indexOf('_mode_config') + 13) == mode) delete config[value]; + Object.keys(config).forEach((value) => { + if (value.substr(value.indexOf("_mode_config") + 13) == mode) delete config[value]; }); localStorage.setItem(`${lib.configprefix}config`, JSON.stringify(config)); localStorage.removeItem(`${lib.configprefix}${mode}`); } /** - * @param { number } position - * @param { string } [character] - * @param { string } [character2] + * @param { number } position + * @param { string } [character] + * @param { string } [character2] */ - static addPlayer(position, character, character2) { - if (position < 0 || position > game.players.length + game.dead.length || position == undefined) position = Math.ceil(Math.random() * (game.players.length + game.dead.length)); + addPlayer(position, character, character2) { + if (position < 0 || position > game.players.length + game.dead.length || position == undefined) + position = Math.ceil(Math.random() * (game.players.length + game.dead.length)); const players = game.players.concat(game.dead); ui.arena.setNumber(players.length + 1); - players.forEach(value => { - if (parseInt(value.dataset.position) >= position) value.dataset.position = parseInt(value.dataset.position) + 1; + players.forEach((value) => { + if (parseInt(value.dataset.position) >= position) + value.dataset.position = parseInt(value.dataset.position) + 1; }); - const player = ui.create.player(ui.arena).addTempClass('start'); + const player = ui.create.player(ui.arena).addTempClass("start"); if (character) player.init(character, character2); game.players.push(player); player.dataset.position = position; @@ -8082,13 +8556,13 @@ export class Game extends Uninstantable { return player; } /** - * @param { number } position - * @param { string } [character] - * @param { string } [animation] + * @param { number } position + * @param { string } [character] + * @param { string } [animation] */ - static addFellow(position, character, animation) { - game.addVideo('addFellow', null, [position, character, animation]); - const player = ui.create.player(ui.arena).addTempClass(animation || 'start'); + addFellow(position, character, animation) { + game.addVideo("addFellow", null, [position, character, animation]); + const player = ui.create.player(ui.arena).addTempClass(animation || "start"); player.dataset.position = position || game.players.length + game.dead.length; player.getId(); if (character) player.init(character); @@ -8097,48 +8571,52 @@ export class Game extends Uninstantable { return player; } /** - * @param { Player } player + * @param { Player } player */ - static triggerEnter(player) { - const next = game.createEvent('enterGame', false); + triggerEnter(player) { + const next = game.createEvent("enterGame", false); next.player = player; next.setContent(() => { - event.trigger('enterGame'); + event.trigger("enterGame"); }); return next; } /** - * @param { Player } player + * @param { Player } player */ - static restorePlayer(player) { + restorePlayer(player) { if (game.players.includes(player) || game.dead.includes(player)) return; let position = parseInt(player.dataset.position); - if (position < 0 || position > game.players.length + game.dead.length || position == undefined) position = Math.ceil(Math.random() * (game.players.length + game.dead.length)); + if (position < 0 || position > game.players.length + game.dead.length || position == undefined) + position = Math.ceil(Math.random() * (game.players.length + game.dead.length)); const players = game.players.concat(game.dead); ui.arena.setNumber(players.length + 1); - players.forEach(value => { - if (parseInt(value.dataset.position) >= position) value.dataset.position = parseInt(value.dataset.position) + 1; + players.forEach((value) => { + if (parseInt(value.dataset.position) >= position) + value.dataset.position = parseInt(value.dataset.position) + 1; }); game.players.push(player); delete player.removed; - player.removeAttribute('style'); - player.addTempClass('start'); + player.removeAttribute("style"); + player.addTempClass("start"); ui.arena.appendChild(player); game.arrangePlayers(); return player; } /** - * @param { Player } player + * @param { Player } player */ - static removePlayer(player) { - if (_status.roundStart == player) _status.roundStart = player.next || player.getNext() || game.players[0]; + removePlayer(player) { + if (_status.roundStart == player) + _status.roundStart = player.next || player.getNext() || game.players[0]; const players = game.players.concat(game.dead); player.style.left = `${player.getLeft()}px`; player.style.top = `${player.getTop()}px`; if (player == undefined) player = game.dead[0] || game.me.next; const position = parseInt(player.dataset.position); - players.forEach(value => { - if (parseInt(value.dataset.position) > position) value.dataset.position = parseInt(value.dataset.position) - 1; + players.forEach((value) => { + if (parseInt(value.dataset.position) > position) + value.dataset.position = parseInt(value.dataset.position) - 1; }); if (player.isAlive()) { player.next.previous = player.previous; @@ -8156,21 +8634,21 @@ export class Game extends Uninstantable { ui.auto.hide(); ui.wuxie.hide(); } - setTimeout(() => player.removeAttribute('style'), 500); + setTimeout(() => player.removeAttribute("style"), 500); return player; } /** - * @param { Player } player + * @param { Player } player * @param { string } [character] * @param { string } [character2] */ - static replacePlayer(player, character, character2) { + replacePlayer(player, character, character2) { player.removed = true; const position = parseInt(player.dataset.position); game.players.remove(player); game.dead.remove(player); player.delete(); - const player2 = ui.create.player(ui.arena).addTempClass('start'); + const player2 = ui.create.player(ui.arena).addTempClass("start"); if (character) player2.init(character, character2); game.players.push(player2); player2.dataset.position = position; @@ -8193,34 +8671,40 @@ export class Game extends Uninstantable { if (_status.roundStart == player) _status.roundStart = player2; return player2; } - static arrangePlayers() { + arrangePlayers() { if (game.chess && game.me) { - let friendCount = 0, enemyCount = 0; - const rand = Math.random() < 0.5, sortCount = new Map(); - game.players.forEach(value => { + let friendCount = 0, + enemyCount = 0; + const rand = Math.random() < 0.5, + sortCount = new Map(); + game.players.forEach((value) => { if (value.side == game.me.side) { - if (rand) if (value == game.friendZhu) sortCount.set(value, -2); - else sortCount.set(value, 2 * friendCount); + if (rand) + if (value == game.friendZhu) sortCount.set(value, -2); + else sortCount.set(value, 2 * friendCount); else if (value == game.friendZhu) sortCount.set(value, -1); else sortCount.set(value, 2 * friendCount + 1); friendCount++; return; } - if (rand) if (value == game.enemyZhu) sortCount.set(value, -1); - else sortCount.set(value, 2 * enemyCount + 1); + if (rand) + if (value == game.enemyZhu) sortCount.set(value, -1); + else sortCount.set(value, 2 * enemyCount + 1); else if (value == game.enemyZhu) sortCount.set(value, -2); else sortCount.set(value, 2 * enemyCount); enemyCount++; }); game.players.sort((a, b) => sortCount.get(a) - sortCount.get(b)); - } - else game.players.sort(lib.sort.position); - game.players.concat(game.dead).sort(lib.sort.position).forEach((value, index, array) => { - if (index == 0) value.previousSeat = array[array.length - 1]; - else value.previousSeat = array[index - 1]; - if (index == array.length - 1) value.nextSeat = array[0]; - else value.nextSeat = array[index + 1]; - }); + } else game.players.sort(lib.sort.position); + game.players + .concat(game.dead) + .sort(lib.sort.position) + .forEach((value, index, array) => { + if (index == 0) value.previousSeat = array[array.length - 1]; + else value.previousSeat = array[index - 1]; + if (index == array.length - 1) value.nextSeat = array[0]; + else value.nextSeat = array[index + 1]; + }); game.players.forEach((value, index, array) => { if (index == 0) value.previous = array[array.length - 1]; else value.previous = array[index - 1]; @@ -8229,78 +8713,85 @@ export class Game extends Uninstantable { }); } /** - * @param { string[] } skills - * @param { Player } player - * @param { string[] } exclude + * @param { string[] } skills + * @param { Player } player + * @param { string[] } exclude */ - static filterSkills(skills, player, exclude) { + filterSkills(skills, player, exclude) { const out = skills.slice().removeArray(Object.keys(player.disabledSkills)); if (!player.storage.skill_blocker || !player.storage.skill_blocker.length) return out; - return out.filter(value => exclude && exclude.includes(value) || !get.is.blocked(value, player)); + return out.filter((value) => (exclude && exclude.includes(value)) || !get.is.blocked(value, player)); } /** - * @param { string[] } skills + * @param { string[] } skills */ - static expandSkills(skills) { - return skills.addArray(skills.reduce((previousValue, currentValue) => { - const info = get.info(currentValue); - if (info) { - if (info.group) { - const adds = (Array.isArray(info.group) ? info.group : [info.group]).filter(i => lib.skill[i]); - previousValue.push(...adds); - } - } - else console.log(currentValue); - return previousValue; - }, [])) + expandSkills(skills) { + return skills.addArray( + skills.reduce((previousValue, currentValue) => { + const info = get.info(currentValue); + if (info) { + if (info.group) { + const adds = (Array.isArray(info.group) ? info.group : [info.group]).filter( + (i) => lib.skill[i] + ); + previousValue.push(...adds); + } + } else console.log(currentValue); + return previousValue; + }, []) + ); } /** - * @param { { [key:string]: any } } style + * @param { { [key:string]: any } } style */ - static css(style) { - return Object.keys(style).forEach(value => { + css(style) { + return Object.keys(style).forEach((value) => { let uiStyle = ui.style[value]; if (!uiStyle) { - uiStyle = ui.style[value] = document.createElement('style'); + uiStyle = ui.style[value] = document.createElement("style"); document.head.appendChild(uiStyle); } uiStyle.innerHTML = `${value}${JSON.stringify(style[value]).replace(/"/g, "")}`; - }) + }); } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static hasPlayer(func, includeOut) { return game.players.some(value => (includeOut || !value.isOut()) && func(value)) } + hasPlayer(func, includeOut) { + return game.players.some((value) => (includeOut || !value.isOut()) && func(value)); + } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static hasPlayer2(func, includeOut) { return game.players.concat(game.dead).some(value => (includeOut || !value.isOut()) && func(value)) } + hasPlayer2(func, includeOut) { + return game.players.concat(game.dead).some((value) => (includeOut || !value.isOut()) && func(value)); + } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static countPlayer(func, includeOut) { - if (typeof func != 'function') func = lib.filter.all; + countPlayer(func, includeOut) { + if (typeof func != "function") func = lib.filter.all; return game.players.reduce((previousValue, currentValue) => { if (!includeOut && currentValue.isOut()) return previousValue; const result = func(currentValue); - if (typeof result == 'number') previousValue += result; + if (typeof result == "number") previousValue += result; else if (result) previousValue++; return previousValue; }, 0); } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static countPlayer2(func, includeOut) { - if (typeof func != 'function') func = lib.filter.all; + countPlayer2(func, includeOut) { + if (typeof func != "function") func = lib.filter.all; return game.players.concat(game.dead).reduce((previousValue, currentValue) => { if (!includeOut && currentValue.isOut()) return previousValue; const result = func(currentValue); - if (typeof result == 'number') previousValue += result; + if (typeof result == "number") previousValue += result; else if (result) previousValue++; return previousValue; }, 0); @@ -8311,15 +8802,15 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { (player: Player) => boolean } func - * @param { Player[] } [list] - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { Player[] } [list] + * @param { boolean } [includeOut] * @returns { Player[] } */ - static filterPlayer(func, list, includeOut) { + filterPlayer(func, list, includeOut) { if (!Array.isArray(list)) list = []; - if (typeof func != 'function') func = lib.filter.all; - return list.addArray(game.players.filter(value => (includeOut || !value.isOut()) && func(value))); + if (typeof func != "function") func = lib.filter.all; + return list.addArray(game.players.filter((value) => (includeOut || !value.isOut()) && func(value))); } /** * @overload @@ -8327,41 +8818,50 @@ export class Game extends Uninstantable { */ /** * @overload - * @param { (player: Player) => boolean } func - * @param { Player[] } [list] - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { Player[] } [list] + * @param { boolean } [includeOut] * @returns { Player[] } */ - static filterPlayer2(func, list, includeOut) { + filterPlayer2(func, list, includeOut) { if (!Array.isArray(list)) list = []; - if (typeof func != 'function') func = lib.filter.all; - return list.addArray(game.players.concat(game.dead).filter(value => (includeOut || !value.isOut()) && func(value))); + if (typeof func != "function") func = lib.filter.all; + return list.addArray( + game.players.concat(game.dead).filter((value) => (includeOut || !value.isOut()) && func(value)) + ); } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static findPlayer(func, includeOut) { return game.players.find(value => (includeOut || !value.isOut()) && func(value)) || null } + findPlayer(func, includeOut) { + return game.players.find((value) => (includeOut || !value.isOut()) && func(value)) || null; + } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [includeOut] + * @param { (player: Player) => boolean } func + * @param { boolean } [includeOut] */ - static findPlayer2(func, includeOut) { return game.players.concat(game.dead).find(value => (includeOut || !value.isOut()) && func(value)) || null } + findPlayer2(func, includeOut) { + return ( + game.players.concat(game.dead).find((value) => (includeOut || !value.isOut()) && func(value)) || + null + ); + } /** - * @param { (player: Player) => boolean } func - * @param { boolean } [all] + * @param { (player: Player) => boolean } func + * @param { boolean } [all] */ - static findCards(func, all) { - return Object.keys(lib.card).filter(value => { + findCards(func, all) { + return Object.keys(lib.card).filter((value) => { if (!lib.translate[`${value}_info`]) return false; if (lib.card[value].mode && lib.card[value].mode.includes(lib.config.mode) == false) return false; if (!all && !lib.inpile.includes(value)) return false; return func(value, lib.card[value]); - }) + }); } - static countGroup() { + countGroup() { const list = lib.group.slice(0); - return game.countPlayer(current => { + return game.countPlayer((current) => { if (!list.includes(current.group)) return false; list.remove(current.group); return true; @@ -8372,7 +8872,7 @@ export class Game extends Uninstantable { * @param {function} 测试的函数 * @returns {number} 消耗的时间 */ - static testRunCost(func){ + testRunCost(func) { let time = Date.now(); func(); let past = Date.now() - time; @@ -8381,19 +8881,29 @@ export class Game extends Uninstantable { } /** * 此方法用于对所有targets按顺序执行一个async函数。 - * + * * @param { Player[] } targets 需要执行async方法的目标 * @param { (player: Player, i: number) => Promise } asyncFunc 需要执行的async方法 * @param { (a: Player, b: Player) => number } sort 排序器,默认为lib.sort.seat */ - static async doAsyncInOrder(targets,asyncFunc,sort){ - if(!sort) sort = lib.sort.seat; + async doAsyncInOrder(targets, asyncFunc, sort) { + if (!sort) sort = lib.sort.seat; let sortedTargets = targets.sort(sort); - for(let i=0;i } [instance] + */ +export let setGame = (instance) => { + game = instance || new Game(); + if (lib.config.dev) { + window.game = game; + } +}; diff --git a/noname/game/promises.js b/noname/game/promises.js index 0fe76dd33..a79a407d3 100644 --- a/noname/game/promises.js +++ b/noname/game/promises.js @@ -1,7 +1,6 @@ -import { Uninstantable } from "../util/index.js"; -import { game, Game } from "./index.js"; +import { game } from "../../noname.js"; -export class GamePromises extends Uninstantable { +export class GamePromises { /** * 模仿h5的prompt,用于显示可提示用户进行输入的对话框 * @@ -29,12 +28,12 @@ export class GamePromises extends Uninstantable { * @param { string } title * @param { boolean } [forced] * @returns { Promise } - * + * */ // @ts-ignore - static prompt(alertOption, title, forced) { + prompt(alertOption, title, forced) { return new Promise((resolve, reject) => { - if (alertOption !== 'alert') { + if (alertOption !== "alert") { // @ts-ignore forced = title || false; title = alertOption; @@ -54,31 +53,39 @@ export class GamePromises extends Uninstantable { * ``` * @returns { Promise } */ - static alert(title) { + alert(title) { return new Promise((resolve, reject) => { - game.prompt(title, 'alert', resolve); + game.prompt(title, "alert", resolve); }); } // 读写函数promises化(不用考虑其对应函数是否存在) - static download(url, folder, dev, onprogress) { + download(url, folder, dev, onprogress) { return new Promise((resolve, reject) => { + // @ts-ignore game.download(url, folder, resolve, reject, dev, onprogress); }); } - static readFile(filename) { + /** + * @param {string} filename + * @returns {Promise} + */ + readFile(filename) { return new Promise((resolve, reject) => { + // @ts-ignore game.readFile(filename, resolve, reject); }); } - static readFileAsText(filename) { + readFileAsText(filename) { return new Promise((resolve, reject) => { + // @ts-ignore game.readFileAsText(filename, resolve, reject); }); } - static writeFile(data, path, name) { - return (new Promise((resolve, reject) => { + writeFile(data, path, name) { + return new Promise((resolve, reject) => { + // @ts-ignore game.writeFile(data, path, name, resolve); - })).then(result => { + }).then((result) => { return new Promise((resolve, reject) => { if (result instanceof Error) { reject(result); @@ -88,27 +95,35 @@ export class GamePromises extends Uninstantable { }); }); } - static ensureDirectory(list, callback, file) { + ensureDirectory(list, callback, file) { return new Promise((resolve, reject) => { - game.ensureDirectory(list, callback, file).then(resolve).catch(reject); + // @ts-ignore + game.ensureDirectory(list, resolve, file); }); } - static createDir(directory) { + createDir(directory) { return new Promise((resolve, reject) => { + // @ts-ignore game.createDir(directory, resolve, reject); }); } - static removeFile(filename) { - return /** @type {Promise} */(new Promise((resolve, reject) => { - game.removeFile(filename, err => { - if (err) reject(err); - else resolve(); - }); - })); + removeFile(filename) { + return /** @type {Promise} */ ( + new Promise((resolve, reject) => { + // @ts-ignore + game.removeFile(filename, (err) => { + if (err) reject(err); + else resolve(); + }); + }) + ); } - static removeDir(directory) { - return /** @type {Promise} */(new Promise((resolve, reject) => { - game.removeDir(directory, resolve, reject); - })); + removeDir(directory) { + return /** @type {Promise} */ ( + new Promise((resolve, reject) => { + // @ts-ignore + game.removeDir(directory, resolve, reject); + }) + ); } } diff --git a/noname/get/index.js b/noname/get/index.js index cbb0946c6..1cfd07316 100644 --- a/noname/get/index.js +++ b/noname/get/index.js @@ -1,4764 +1,5229 @@ -import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js"; -import { AI as ai } from '../ai/index.js'; -import { Game as game } from '../game/index.js'; -import { Library as lib } from '../library/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { GNC as gnc } from '../gnc/index.js'; -import { CacheContext } from "../library/cache/cacheContext.js"; -import { Is } from "./is.js"; -import { Promises } from "./promises.js"; - -export class Get extends Uninstantable { - static is = Is; - static promises = Promises; - /** - * 获取当前内核版本信息 - * - * 目前仅考虑`chrome`, `firefox`和`safari`三种浏览器的信息,其余均归于其他范畴 - * - * > 其他后续或许会增加,但`IE`永无可能 - * - * @returns {["firefox" | "chrome" | "safari" | "other", number, number, number]} - */ - static coreInfo() { - const regex = /(firefox|chrome|safari)\/(\d+(?:\.\d+)+)/ - let result - if (!(result = userAgent.match(regex))) return ["other", NaN, NaN, NaN] - if (result[1] != "safari") { - const [major, minor, patch] = result[2].split(".") - return [result[1], parseInt(major), parseInt(minor), parseInt(patch)] - } - result = userAgent.match(/version\/(\d+(?:\.\d+)+).*safari/) - const [major, minor, patch] = result[1].split(".") - return ["safari", parseInt(major), parseInt(minor), parseInt(patch)] - } - /** - * 返回 VCard[] 形式的所有牌,用于印卡将遍历 - * @param {Function} filter - * @returns {string[][]} - */ - static inpileVCardList(filter) { - let list = []; - for (const name of lib.inpile) { - const type = get.type(name); - const info = [type, '', name]; - if (!filter || filter(info)) list.push(info); - if (name == 'sha') { - for (const nature of lib.inpile_nature) { - const info = [type, '', name, nature]; - if (!filter || filter(info)) list.push(info); - } - } - } - return list; - } - /** - * 根据(Player的)座次数n(从1开始)获取对应的“n号位”翻译 - * @param {number | Player} seat - */ - static seatTranslation(seat) { - if (get.itemtype(seat) === 'player') seat = seat.getSeatNum() - 1; - return `${get.cnNumber(seat + 1, true)}号位`; - } - /** - * @param {number} numberOfPlayers - * @returns {string[]} - */ - static identityList(numberOfPlayers) { - const modeConfig = lib.config.mode_config; - if (modeConfig) { - const identityConfig = modeConfig.identity; - if (identityConfig) { - const identityLists = identityConfig.identity; - if (identityLists) { - const identityList = identityLists[numberOfPlayers - 2]; - if (Array.isArray(identityList)) return identityList.slice(); - } - } - } - const numberOfPlayersExceptLord = numberOfPlayers - 1, numberOfLoyalists = Math.round(numberOfPlayersExceptLord * 3 / 9), numberOfSpys = Math.round(numberOfPlayersExceptLord * 2 / 9); - return ['zhu'].concat(Array.from({ - length: numberOfLoyalists - }, () => 'zhong'), Array.from({ - length: numberOfSpys - }, () => 'nei'), Array.from({ - length: numberOfPlayersExceptLord - numberOfLoyalists - numberOfSpys - }, () => 'fan')); - } - /** - * Generate an object URL from the Base64-encoded octet stream - * - * 从Base64编码的八位字节流生成对象URL - */ - static objectURL(octetStream) { - const objectURLMap = lib.objectURL; - if (objectURLMap.has(octetStream)) return objectURLMap.get(octetStream); - const objectURL = URL.createObjectURL(new Blob([Uint8Array.from(atob(octetStream.replace(/^data:[\s\S]*\/[\s\S]*;base64,/, '')), character => character.charCodeAt())])); - objectURLMap.set(octetStream, objectURL); - return objectURL; - } - /** - * Get the card name length - * - * 获取此牌的字数 - */ - static cardNameLength(card, player) { - const actualCardName = lib.actualCardName, name = get.translation(typeof card == 'string' ? card : get.name(card, player)); - return (actualCardName.has(name) ? actualCardName.get(name) : name).length; - } - //Yingbian - //应变 - /** - * Get the Yingbian conditions (of the card) - * - * 获取(此牌的)应变条件 - */ - static yingbianConditions(card) { return get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)); } - static complexYingbianConditions(card) { - const complexYingbianConditions = Array.from(lib.yingbian.condition.complex.keys()); - return card ? complexYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : complexYingbianConditions; - } - static simpleYingbianConditions(card) { - const simpleYingbianConditions = Array.from(lib.yingbian.condition.simple.keys()); - return card ? simpleYingbianConditions.filter(value => get.cardtag(card, `yingbian_${value}`)) : simpleYingbianConditions; - } - /** - * Get the Yingbian effects (of the card) - * - * 获取(此牌的)应变效果 - */ - static yingbianEffects(card) { - const yingbianEffects = Array.from(lib.yingbian.effect.keys()); - return card ? yingbianEffects.filter(value => get.cardtag(card, `yingbian_${value}`)) : yingbianEffects; - } - /** - * Get the default Yingbian effect of the card - * - * 获取此牌的默认应变效果 - */ - static defaultYingbianEffect(card) { - const info = get.info(card); - return info && info.defaultYingbianEffect || null; - } - /** - * 优先度判断 - */ - static priority(skill) { - const info = get.info(skill); - if (!info) return 0; - if ('_priority' in info) return info._priority; - let priority = 0; - if (info.priority) { - priority = info.priority * 100; - } - if (info.silent) { - priority++; - } - if (info.equipSkill) priority -= 25; - if (info.cardSkill) priority -= 50; - if (info.ruleSkill) priority -= 75; - info._priority = priority; - return priority; - } - /** - * 新装备栏相关 - * - * 获取一张装备牌实际占用的装备栏(君曹操六龙) - * - * 用法同{@link subtype},返回数组 - * - * @param { string | Card | VCard | CardBaseUIData } obj - * @param { false | Player } [player] - * @returns { string[] } - */ - static subtypes(obj, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - var name = get.name(obj, player); - if (!lib.card[name]) return []; - if (lib.card[name].subtypes) { - const subtypes = get.copy(lib.card[name].subtypes); - return subtypes; - } - else if (lib.card[name].subtype) { - const subtype = lib.card[name].subtype; - return [subtype]; - } - return []; - } - //装备栏 END - /** - * @returns { string[] } - */ - static pinyin(chinese, withTone) { - const pinyinUtilx = window.pinyinUtilx; - if (!pinyinUtilx) return []; - const pinyins = lib.pinyins; - if (pinyins) { - const pinyin = pinyins[chinese]; - if (Array.isArray(pinyin)) return withTone === false ? pinyin.map(pinyinUtilx.removeTone) : pinyin.slice(); - } - return pinyinUtilx.getPinyin(chinese, null, withTone, true); - } - static yunmu(str) { - //部分整体认读音节特化处理 - const util = window.pinyinUtilx; - if (util && lib.pinyins._metadata.zhengtirendu.includes(util.removeTone(str))) { - return '-' + str[str.length - 1]; - } - //排除声母 - for (let i of lib.pinyins._metadata.shengmu) { - if (str.startsWith(i)) { - str = str.slice(i.length); - if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); - break; - } - } - //排除介母 - if (str.length > 0) { - for (let i in lib.pinyins._metadata.feijiemu) { - if (str[0] == i) { - let goon = false; - for (let j of lib.pinyins._metadata.feijiemu[i]) { - if (str.startsWith(j)) goon = true; - } - if (!goon) str = str.slice(1); - break; - } - } - } - return str; - } - /** - * 用于将参数转换为字符串,作为缓存的key。 - */ - static paramToCacheKey() { - var str = ""; - for (var arg of arguments) { - if (arg === null || arg === undefined) { - str += (arg + "-"); - continue; - } - if (arg.playerid) { - str += "p:" + arg.playerid; - } else if (arg.cardid) { - str += "c:" + arg.cardid; - } else if (arg.name) { - str += "n:" + arg.name; - } else { - str += "s:" + arg; - } - str += "-"; - } - return str; - } - static yunjiao(str) { - const util = window.pinyinUtilx; - if (util) str = util.removeTone(str); - if (lib.pinyins._metadata.zhengtirendu.includes(str)) { - str = ('-' + str[str.length - 1]); - } - else { - for (let i of lib.pinyins._metadata.shengmu) { - if (str.startsWith(i)) { - str = str.slice(i.length); - if (str[0] == 'u' && lib.pinyins._metadata.special_shengmu.includes(i)) str = 'ü' + str.slice(1); - break; - } - } - } - for (let i in lib.pinyins._metadata.yunjiao) { - if (lib.pinyins._metadata.yunjiao[i].includes(str)) return i; - } - return null; - } - /** - * @param { string } skill - * @param { Player } player - * @returns { string[] } - */ - static skillCategoriesOf(skill, player) { - const list = [], info = get.info(skill); - if (!info) return list; - if (get.is.locked(skill, player)) list.add('锁定技'); - if (info.zhuSkill) list.add('主公技'); - if (info.limited) list.add('限定技'); - if (info.juexingji) list.add('觉醒技'); - if (get.is.zhuanhuanji(skill, player)) list.add('转换技'); - if (info.hiddenSkill) list.add('隐匿技'); - if (info.clanSkill) list.add('宗族技'); - if (info.groupSkill) list.add('势力技'); - if (info.dutySkill) list.add('使命技'); - if (info.chargeSkill) list.add('蓄力技'); - if (info.zhenfa) list.add('阵法技'); - if (info.mainSkill) list.add('主将技'); - if (info.viceSkill) list.add('副将技'); - if (info.lordSkill) list.add('君主技'); - if (info.chargingSkill) list.add('蓄能技'); - if (info.charlotte) list.add('Charlotte'); - if (info.sunbenSkill) list.add('昂扬技'); - if (info.categories) list.addArray(info.categories(skill, player)); - return list; - } - static numOf(obj, item) { return obj.filter(element => element == item).length; } - static connectNickname() { return typeof lib.config.connect_nickname == 'string' ? (lib.config.connect_nickname.slice(0, 12)) : "无名玩家"; } - static zhinangs(filter) { - var list = (_status.connectMode ? lib.configOL : lib.config).zhinang_tricks; - if (!list || !list.filter || !list.length) return get.inpile('trick', 'trick').randomGets(3); - if (filter === false) return list.slice(0); - list = list.filter(card => lib.inpile.includes(card)); - if (list.length) return list; - return get.inpile('trick', 'trick').randomGets(3); - } - static sourceCharacter(str) { - if (str) { - for (var i in lib.characterReplace) { - if (lib.characterReplace[i].includes(str)) return i; - } - } - return str; - } - static isLuckyStar(player) { - if (player && player.hasSkillTag('luckyStar')) return true; - if (_status.connectMode) return false; - return (!player || player == game.me || player.isUnderControl()) && lib.config.lucky_star == true; - } - static infoHp(hp) { - if (typeof hp == 'number') return hp; - else if (typeof hp == 'string') { - if (hp.includes('/')) { - const num = hp.split('/')[0]; - if (num) { - if (num == 'Infinity' || num == '∞') { - return Infinity; - } else { - return parseInt(num); - } - } - } else if (hp == 'Infinity' || hp == '∞') return Infinity; - } - return 0; - } - static infoMaxHp(hp) { - if (typeof hp == 'number') return hp; - else if (typeof hp == 'string') { - if (hp.includes('/')) { - const num = hp.split('/')[1]; - if (num) { - if (num == 'Infinity' || num == '∞') { - return Infinity; - } else { - return parseInt(num); - } - } - } else if (hp == 'Infinity' || hp == '∞') return Infinity; - } - return 0; - } - static infoHujia(hp) { - if (typeof hp == 'string' && hp.includes('/')) { - const num = hp.split('/')[2]; - if (num) { - if (num == 'Infinity' || num == '∞') { - return Infinity; - } else { - return parseInt(num); - } - } - } - return 0; - } - static bottomCards(num, putBack) { - if (_status.waitingForCards) { - ui.create.cards.apply(ui.create, _status.waitingForCards); - delete _status.waitingForCards; - } - var list = []; - var card = false; - if (typeof num != 'number') num = 1; - if (num == 0) { card = true; num = 1; } - if (num < 0) num = 1; - while (num--) { - if (ui.cardPile.hasChildNodes() == false) { - game.washCard(); - } - if (ui.cardPile.hasChildNodes() == false) { - game.over('平局'); - return []; - } - var cardx = ui.cardPile.removeChild(ui.cardPile.lastChild); - cardx.original = 'c'; - list.push(cardx); - } - if (putBack) { - for (let i = list.length - 1; i >= 0; i--) { - ui.cardPile.appendChild(list[i]); - } - } - game.updateRoundNumber(); - if (card) return list[0]; - return list; - } - static discarded() { return _status.discarded.filter(item => item.parentNode == ui.discardPile); } - static cardOffset() { - var x = ui.arena.getBoundingClientRect(); - var y = ui.window.getBoundingClientRect(); - return -y.width / 2 + (x.left + x.width / 2); - } - static colorspan(str) { - if (str[0] == '#') { - var color; - switch (str[1]) { - case 'r': color = 'fire'; break; - case 'p': color = 'legend'; break; - case 'b': color = 'blue'; break; - case 'g': color = 'green'; break; - default: return str.slice(2); - } - return '' + str.slice(2) + ''; - } - return str; - } - static evtprompt(next, str) { - if (next.prompt) { - next.set('prompt2', str); - } - else { - if (str.startsWith('###')) { - var prompts = str.slice(3).split('###'); - if (prompts[0]) next.set('prompt', prompts[0]); - if (prompts[1]) next.set('prompt2', prompts[1]); - } - else { - next.set('prompt', str); - } - } - } - static autoViewAs(card, cards) { return new lib.element.VCard(card, cards); } - /** - * @deprecated - */ - static _autoViewAs(card, cards) { - var info = get.info(card); - if (info.autoViewAs) { - if (cards === false) { - return { - name: info.autoViewAs, - }; - } - else if (Array.isArray(cards)) { - return { - name: info.autoViewAs, - cards: cards.slice(0), - }; - } - else if (get.itemtype(card) == 'card') { - return { - name: info.autoViewAs, - cards: [card], - }; - } - else { - return { - name: info.autoViewAs, - suit: card.suit, - number: card.number, - nature: card.nature, - }; - } - } - else { - if (card.isCard || get.itemtype(card) == 'card') { - var next = { - name: get.name(card), - suit: get.suit(card), - number: get.number(card), - nature: get.nature(card), - isCard: true, - cardid: card.cardid, - wunature: card.wunature, - storage: get.copy(card.storage), - cards: get.copy(card.cards), - }; - if (get.itemtype(cards) == 'cards' && !card.cards) next.cards = cards.slice(0); - else if (get.itemtype(card) == 'card') next.cards = [card]; - return next; - } - else if (get.is.object(card) && get.itemtype(cards) == 'cards' && !card.cards) { - card = get.copy(card); - card.cards = cards.slice(0); - } - return card; - } - } - static max(list, func, type) { - list = list.slice(0); - if (typeof func == 'string') { - var key = func; - func = function (item) { - return item[key]; - }; - } - list.sort(function (a, b) { - return func(b) - func(a); - }); - if (type == 'list') { - var list2 = []; - for (var i = 0; i < list.length; i++) { - if (func(list[i]) == func(list[0])) { - list2.push(list[i]); - } - } - return list2; - } - else if (type == 'item') { - return list[0]; - } - else { - return func(list[0]); - } - } - static min(list, func, type) { - list = list.slice(0); - if (typeof func == 'string') { - var key = func; - func = function (item) { - return item[key]; - }; - } - list.sort(function (a, b) { - return func(a) - func(b); - }); - if (type == 'list') { - var list2 = []; - for (var i = 0; i < list.length; i++) { - if (func(list[i]) == func(list[0])) { - list2.push(list[i]); - } - } - return list2; - } - else if (type == 'item') { - return list[0]; - } - else { - return func(list[0]); - } - } - /** - * @overload - * @param { string } name - * @returns { Character } - */ - /** - * @template { 0 | 1 | 2 | 3 | 4 } T - * @overload - * @param { string } name - * @param { T } num - * @returns { Character[T] } - */ - static character(name, num) { - let info = lib.character[name]; - if (!info) { - const pack = Object.keys(lib.characterPack).find(pack => name in lib.characterPack[pack]); - if (pack) info = lib.characterPack[pack][name]; - } - if (typeof num === 'number') { - if (!info) info = []; - if (info[num]) return info[num]; - if (num === 3 || num === 4) return []; - return; - } - return info; - } - static characterInitFilter(name) { - const info = get.character(name); - if (!info || !info[4]) return []; - const filter = info[4].find(tag => tag.startsWith('InitFilter')); - if (!filter) return []; - return filter.split(':').slice(1); - } - static characterIntro(name) { - if (lib.characterIntro[name]) return lib.characterIntro[name]; - var tags = get.character(name, 4); - if (tags) { - for (var i = 0; i < tags.length; i++) { - if (tags[i].startsWith('des:')) { - return tags[i].slice(4); - } - } - } - while (name.includes('_') && !lib.characterIntro[name]) { - name = name.slice(name.indexOf('_') + 1); - } - if (lib.characterIntro[name]) return lib.characterIntro[name]; - return '暂无武将介绍'; - } - static bordergroup(info, raw) { - if (!Array.isArray(info)) { - info = lib.character[info]; - if (!info) return ''; - } - if (Array.isArray(info[4])) for (const str of info[4]) { - if (typeof str == 'string' && str.startsWith('border:')) return str.slice(7); - } - return raw ? '' : info[1] || ''; - } - static groupnature(group, method) { - var nature = lib.groupnature[group]; - if (!nature) return ''; - if (method == 'raw') { - return nature; - } - return nature + 'mm'; - } - static sgn(num) { - if (num > 0) return 1; - if (num < 0) return -1; - return 0; - } - static rand(num, num2) { - if (typeof num2 == 'number') { - return num + Math.floor(Math.random() * (num2 - num + 1)); - } - else { - return Math.floor(Math.random() * num); - } - } - static sort(arr, method, arg) { return method == "seat" ? arr.sortBySeat(arg) : void 0; } - static sortSeat(arr, target) { return arr.sortBySeat(target); } - /** - * @param { (zip: JSZip) => any } callback - */ - static zip(callback) { - if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip', function () { - callback(new JSZip()); - }); - } - else { - callback(new JSZip()); - } - } - static delayx(num, max) { - if (typeof num != 'number') num = 1; - if (typeof max != 'number') max = Infinity; - switch (lib.config.game_speed) { - case 'vslow': return Math.min(max, 2.5 * num); - case 'slow': return Math.min(max, 1.5 * num); - case 'fast': return Math.min(max, 0.7 * num); - case 'vfast': return Math.min(max, 0.4 * num); - case 'vvfast': return Math.min(max, 0.2 * num); - default: return Math.min(max, num); - } - } - static prompt(skill, target, player) { - player = player || _status.event.player; - if (target) { - var str = get.translation(target); - if (target == player) { - str += '(你)'; - } - return '是否对' + str + '发动【' + get.skillTranslation(skill, player) + '】?'; - } - else { - return '是否发动【' + get.skillTranslation(skill, player) + '】?'; - } - } - static prompt2(skill, target, player) { - var str = get.prompt.apply(this, arguments); - if (!lib.translate[skill + '_info']) return str; - return '###' + str + '###' + lib.translate[skill + '_info']; - } - static url(master) { - var url = lib.config.updateURL || lib.updateURL; - if (url[url.length - 1] != '/') { - url += '/'; - } - if (master != 'nodev') { - return url + 'master/'; - } - else { - return url + 'v' + lib.version + '/'; - } - } - static round(num, f) { - var round = Math.pow(10, f); - return Math.round(num * round) / round; - } - static playerNumber() { - var num; - if (_status.brawl && _status.brawl.playerNumber) { - num = _status.brawl.playerNumber; - } - else { - num = get.config('player_number'); - } - return parseInt(num) || 2; - } - static benchmark(func1, func2, iteration, arg) { - var tic, toc; - var key1, key2; - if (!arg) arg = []; - if (Array.isArray(func2)) { - key1 = func2[0]; - key2 = func2[1]; - } - else if (typeof func2 == 'string') { - key1 = func2; - func2 = iteration || 100; - } - else if (typeof func2 == 'number') { - arg = iteration || arg; - iteration = func2; - } - tic = get.utc(); - for (var i = 0; i < iteration; i++) { - if (key1) { - func1[key1](arg.randomGet()); - } - else { - func1(arg.randomGet()); - } - } - toc = get.utc(); - if (typeof func2 == 'number') { - return toc - tic; - } - console.log('time1: ' + (toc - tic)); - tic = get.utc(); - for (var i = 0; i < iteration; i++) { - if (key2) { - func1[key2](arg.randomGet()); - } - else { - func2(arg.randomGet()); - } - } - toc = get.utc(); - console.log('time2: ' + (toc - tic)); - } - /** - * @param {any} obj - */ - static stringify(obj, level = 0) { - level = level || 0; - let indent = ''; - let str; - for (let i = 0; i < level; i++) { - indent += ' '; - } - if (get.objtype(obj) == 'object' || obj instanceof lib.element.GameEventPromise) { - str = '{\n'; - for (let i in obj) { - /** - * @type {string} - */ - let insertDefaultString; - let insertFunctionString = indent + ' ' + get.stringify(obj[i], level + 1) + ',\n'; - let parseFunction = (/** @type {string} */ i) => { - // let string = obj[i].toString(); - i = i.replaceAll('$', '\\$'); - let execResult; - if (obj[i] instanceof GeneratorFunction) { - // *content(){} - execResult = new RegExp(`\\*\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:function*(){} - else { - return insertDefaultString; - } - } - else if (obj[i] instanceof AsyncFunction) { - execResult = new RegExp(`async\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); - // async content(){} - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:async function(){} - else { - return insertDefaultString; - } - } else { - execResult = new RegExp(`${i}[\\s\\S]*?\\(`).exec(obj[i]); - // content(){} - if (execResult && execResult.index === 0) { - return insertFunctionString; - } - // content:function(){} - else { - return insertDefaultString; - } - } - }; - if (/[^a-zA-Z]/.test(i)) { - insertDefaultString = indent + ' "' + i + '":' + get.stringify(obj[i], level + 1) + ',\n'; - if (typeof obj[i] !== 'function') { - str += insertDefaultString; - } else { - str += parseFunction(i); - } - } - else { - insertDefaultString = indent + ' ' + i + ':' + get.stringify(obj[i], level + 1) + ',\n'; - if (typeof obj[i] !== 'function') { - str += insertDefaultString; - } else { - str += parseFunction(i); - } - } - } - str += indent + '}'; - return str; - } - else { - if (typeof obj == 'function') { - str = obj.toString(); - str = str.replace(/\t/g, ' '); - let i = str.lastIndexOf('\n'); - let num = 0; - for (let j = i + 1; j < str.length && str[j] == ' '; j++) { - num++; - } - num = Math.floor(num / 4); - for (i = 0; i < num - level; i++) { - str = str.replace(/\n {4}/g, '\n'); - } - } - else { - try { - if (Array.isArray(obj) && obj.includes(Infinity)) { - obj = obj.slice(0); - let rand = get.id(); - for (let i = 0; i < obj.length; i++) { - if (obj[i] === Infinity) { - obj[i] = parseInt(rand); - } - } - str = JSON.stringify(obj).replace(new RegExp(rand, 'g'), 'Infinity'); - } - else { - str = JSON.stringify(obj) || ''; - } - } - catch (e) { - str = ''; - } - } - return str; - } - } - /** - * 深拷贝函数(虽然只处理了部分情况) - * - * 除了普通的Object和NullObject,均不考虑自行赋值的数据,但会原样将Symbol复制过去 - * - * @template T - * @param {T} obj - 要复制的对象,若不是对象则直接返回原值 - * @param {boolean} [copyKeyDeep = false] - 是否深复制`Map`的`key` - * @param {WeakMap} [map] - 拷贝用的临时存储,用于处理循环引用(请勿自行赋值) - * @returns {T} - 深拷贝后的对象,若传入值不是对象则为传入值 - */ - static copy(obj, copyKeyDeep = false, map = new WeakMap()) { - // 参考[这里](https://juejin.cn/post/7315612852890026021)实现深拷贝 - // 不再判断是否能structuredClone是因为structuredClone会把Symbol给毙了 - const getType = (obj) => Object.prototype.toString.call(obj); - - const canTranverse = { - "[object Map]": true, - "[object Set]": true, - "[object Object]": true, - "[object Array]": true, - "[object Arguments]": true, - "[object Date]": true - }; - - if (typeof obj !== "object" || obj === null || !canTranverse[getType(obj)]) - return obj; - - // @ts-ignore - if (map.has(obj)) return map.get(obj); - - const constructor = obj.constructor; - // @ts-ignore - const target = - constructor - ? ( - // 这四类数据处理单独处理 - // (实际上需要处理的只有Map和Set) - // 除此之外的就只能祝愿有拷贝构造函数了 - (Array.isArray(obj) || obj instanceof Map || obj instanceof Set || constructor === Object) - // @ts-ignore - ? new constructor() - : ( - (constructor.name in window && /\[native code\]/.test(constructor.toString())) - // @ts-ignore - ? new constructor(obj) - : obj - ) - ) - : Object.create(null); - if (target === obj) return target; - - map.set(obj, target); - - if (obj instanceof Map) { - obj.forEach((value, key) => { - target.set(copyKeyDeep ? get.copy(key, copyKeyDeep, map) : key, get.copy(value, copyKeyDeep, map)); - }); - } else if (obj instanceof Set) { - obj.forEach((value) => { - target.add(get.copy(value, copyKeyDeep, map)); - }); - } - - const descriptors = Object.getOwnPropertyDescriptors(obj); - if (descriptors) { - for (const [key, descriptor] of Object.entries(descriptors)) { - const { enumerable, configurable } = descriptor; - if (obj.hasOwnProperty(key)) { - const result = { enumerable, configurable }; - if (descriptor.hasOwnProperty('value')) { - result.value = get.copy(descriptor.value, copyKeyDeep, map); - result.writable = descriptor.writable; - } else { - const { get, set } = descriptor; - result.get = get; - result.set = set; - } - Reflect.defineProperty(target, key, result); - } - } - } - - const symbols = Object.getOwnPropertySymbols(obj); - symbols.forEach((symbol) => { - target[symbol] = get.copy(obj[symbol], copyKeyDeep, map); - }); - - return target; - } - static inpilefull(type) { - var list = []; - for (var i in lib.cardPile) { - for (var j = 0; j < lib.cardPile[i].length; j++) { - var info = lib.cardPile[i][j]; - if (lib.inpile.includes(info[2]) && get.type(info[2]) == type) { - list.push({ - name: info[2], - suit: info[0], - number: info[1], - nature: info[3] - }); - } - } - } - return list; - } - static inpile(type, filter) { - var list = []; - if (filter == 'trick') { - for (var i = 0; i < lib.inpile.length; i++) { - if (get.type(lib.inpile[i], 'trick') == type) list.push(lib.inpile[i]); - } - } - else { - for (var i = 0; i < lib.inpile.length; i++) { - if (typeof type == 'function') { - if (type(lib.inpile[i])) { - list.push(lib.inpile[i]); - } - } - else { - if (typeof filter == 'function' && !filter(lib.inpile[i])) continue; - if (type.startsWith('equip') && type.length == 6) { - if (get.subtype(lib.inpile[i]) == type) list.push(lib.inpile[i]); - } - else { - if (get.type(lib.inpile[i]) == type) list.push(lib.inpile[i]); - } - } - } - } - return list; - } - static inpile2(type) { return get.inpile(type, 'trick'); } - static typeCard(type, filter) { - var list = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; - // if(lib.card[i].vanish||lib.card[i].destroy) continue; - if (lib.card[i].destroy) continue; - if (typeof filter == 'function' && !filter(i)) continue; - if (lib.config.bannedcards.includes(i)) continue; - if (!lib.translate[i + '_info']) continue; - if ((type.startsWith('equip') && type.length == 6) || - (type.startsWith('hslingjian') && type.length == 11) || - (type.startsWith('spell_'))) { - if (get.subtype(i) == type) list.push(i); - } - else { - if (get.type(i) == type) list.push(i); - } - } - return list; - } - static libCard(filter) { - var list = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; - // if(lib.card[i].vanish||lib.card[i].destroy) continue; - if (lib.card[i].destroy) continue; - if (lib.config.bannedcards.includes(i)) continue; - if (!lib.translate[i + '_info']) continue; - if (filter(lib.card[i], i)) { - list.push(i); - } - } - return list; - } - static ip() { - if (!require) return ''; - var interfaces = require('os').networkInterfaces(); - for (var devName in interfaces) { - var iface = interfaces[devName]; - for (var i = 0; i < iface.length; i++) { - var alias = iface[i]; - if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { - return alias.address; - } - } - } - } - static modetrans(config, server) { - if (config.mode == 'doudizhu') { - switch (config.doudizhu_mode) { - case 'kaihei': return '开黑斗地主'; - case 'huanle': return '欢乐斗地主'; - case 'binglin': return '兵临城下'; - case 'online': return '智斗三国'; - default: return '休闲' + (config.double_character ? '双将' : '') + '斗地主'; - } - } - if (config.mode == 'versus') { - switch (config.versus_mode) { - case '1v1': return '单人对决'; - case '2v2': return '欢乐成双'; - case '3v3': return '血战到底'; - case '4v4': return '四人对决'; - case 'guandu': return '官渡之战'; - } - } - if (config.mode == 'single') { - switch (config.single_mode) { - case 'normal': return '新1v1'; - case 'changban': return '血战长坂坡'; - case 'dianjiang': return '点将单挑'; - case 'wuxianhuoli': return '无限火力'; - } - } - if (config.mode == 'identity') { - switch (config.identity_mode) { - case 'purple': return '三对三对二'; - case 'zhong': return (config.double_character ? '双将' : '') + '忠胆英杰'; - case 'stratagem': return get.cnNumber(parseInt(config.number)) + '人' + (config.double_character ? '双将' : '') + '谋攻'; - default: return `${get.cnNumber(parseInt(config.number))}人${config.double_nei ? '双内' : ''}${config.enable_commoner ? '带民' : ''}${config.double_character ? '双将' : ''}身份`; - } - } - if (config.mode == 'guozhan') { - if (config.separatism) return '群雄割据'; - if (config.guozhan_mode != 'normal') switch (config.guozhan_mode) { - case 'yingbian': return '应变国战'; - case 'old': return '怀旧国战'; - } - } - if (server) { - return get.translation(config.mode) + '模式'; - } - else { - return get.cnNumber(parseInt(config.number)) + '人' + get.translation(config.mode); - } - } - static charactersOL(func) { - var list = []; - var libCharacter = {}; - for (var i = 0; i < lib.configOL.characterPack.length; i++) { - var pack = lib.characterPack[lib.configOL.characterPack[i]]; - for (var j in pack) { - if (typeof func == 'function' && func(j)) continue; - if (lib.connectBanned.includes(j)) continue; - if (lib.character[j]) libCharacter[j] = pack[j]; - } - } - for (i in libCharacter) { - if (lib.filter.characterDisabled(i, libCharacter)) continue; - list.push(i); - } - return list; - } - static trimip(str) { - var len = str.length - 5; - if (str.lastIndexOf(':8080') == len) { - str = str.slice(0, len); - } - return str; - } - static mode() { return lib[_status.connectMode ? 'configOL' : 'config'].mode; } - static idDialog(id) { return ui.dialogs.find(dialog => dialog.videoId == id) || null; } - static arenaState() { - var state = { - number: ui.arena.dataset.number, - players: {}, - mode: _status.mode, - dying: _status.dying, - servermode: window.isNonameServer, - roomId: game.roomId, - over: _status.over, - inpile: lib.inpile, - inpile_nature: lib.inpile_nature, - renku: _status.renku, - }; - for (var i in lib.playerOL) { - state.players[i] = lib.playerOL[i].getState(); - } - return state; - } - static skillState(player) { - var skills = { - global: lib.skill.global - }; - var skillinfo = {}; - for (var i in lib.playerOL) { - skills[i] = { - skills: lib.playerOL[i].skills, - hiddenSkills: lib.playerOL[i].hiddenSkills, - invisibleSkills: lib.playerOL[i].invisibleSkills, - additionalSkills: lib.playerOL[i].additionalSkills, - disabledSkills: lib.playerOL[i].disabledSkills, - tempSkills: lib.playerOL[i].tempSkills, - storage: lib.playerOL[i].storage, - }; - } - //for(var i in lib.skill){ - // if(lib.skill[i].chooseButton&&lib.skill[i].enable){ - // skillinfo[i]=lib.skill[i].chooseButton; - // } - //} - skills.skillinfo = skillinfo; - if (player) { - skills.stat = player.getStat(); - } - return skills; - } - static id() { return (Math.floor(1000000 + 9000000 * Math.random())).toString() + (10 + lib.status.globalId++); } - static zhu(player, skill, group) { - if (typeof player == 'string') { - skill = player; - player = null; - } - var mode = get.mode(); - if (mode == 'identity') { - if (_status.mode == 'purple') { - if (!player) return null; - var zhu = game[player.identity.slice(0, 1) + 'Zhu']; - if (!zhu) return null; - if (skill && !zhu.hasSkill(skill)) return null; - return zhu; - } - if (!game.zhu) return null; - if (skill && !game.zhu.hasSkill(skill)) return null; - if (game.zhu.isZhu) return game.zhu; - } - else if (mode == 'versus' && (_status.mode == 'four' || _status.mode == 'guandu')) { - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isZhu) { - if (skill && !(game.players[i].hasSkill(skill))) continue; - if (!player) return game.players[i]; - if (player.side == game.players[i].side) { - return game.players[i]; - } - } - } - } - else if (mode == 'guozhan') { - for (var i = 0; i < game.players.length; i++) { - if (get.is.jun(game.players[i]) && !game.players[i].isUnseen()) { - if (skill && !game.players[i].hasSkill(skill)) continue; - if (!player) return game.players[i]; - if (player.identity == game.players[i].identity) { - return game.players[i]; - } - else if (group && group == game.players[i].identity) { - return game.players[i]; - } - } - } - } - return null; - } - static config(item, mode) { - mode = mode || lib.config.mode; - if (!lib.config.mode_config[mode]) return; - return lib.config.mode_config[mode][item]; - } - static coinCoeff(list) { - var num = 0; - for (var i = 0; i < list.length; i++) { - var rank = get.rank(list[i]); - switch (rank) { - case 'sp': return 0.1; - case 's': num += 0.4; break; - case 'ap': num += 0.6; break; - case 'a': num += 0.8; break; - case 'am': num += 0.95; break; - case 'bp': num += 1.05; break; - case 'b': num += 1.2; break; - case 'bm': num += 1.4; break; - case 'c': num += 1.6; break; - case 'd': num += 1.8; break; - } - } - return num / list.length; - } - static rank(name, num) { - if (typeof name == 'object' && name.name) { - name = name.name; - } - if (num == true) num = 9; - if (typeof num != 'number') num = false; - if (name == _status.lord) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; - var rank = lib.rank; - if (lib.characterPack.standard[name] || lib.characterPack.shenhua[name]) { - var skills; - if (lib.character[name]) { - skills = lib.character[name][3]; - } - else { - var tmpinfo = get.character(name); - if (tmpinfo) { - skills = tmpinfo[3]; - } - else { - skills = []; - } - } - for (var i = 0; i < skills.length; i++) { - if (skills[i].alter && !lib.config.vintageSkills.includes(skills[i])) { - name = lib.rank.a[0]; break; - } - } - } - if (rank.s.includes(name)) return num ? Math.round(8 * (num - 1) / 8 + 1) : 's'; - if (rank.ap.includes(name)) return num ? Math.round(7 * (num - 1) / 8 + 1) : 'ap'; - if (rank.a.includes(name)) return num ? Math.round(6 * (num - 1) / 8 + 1) : 'a'; - if (rank.am.includes(name)) return num ? Math.round(5 * (num - 1) / 8 + 1) : 'am'; - if (rank.bp.includes(name)) return num ? Math.round(4 * (num - 1) / 8 + 1) : 'bp'; - if (rank.b.includes(name)) return num ? Math.round(3 * (num - 1) / 8 + 1) : 'b'; - if (rank.bm.includes(name)) return num ? Math.round(2 * (num - 1) / 8 + 1) : 'bm'; - if (rank.c.includes(name)) return num ? Math.round(1 * (num - 1) / 8 + 1) : 'c'; - if (rank.d.includes(name)) return num ? Math.round(0 * (num - 1) / 8 + 1) : 'd'; - if (lib.character[name] && lib.character[name][4]) { - if (lib.character[name][4].includes('boss') || - lib.character[name][4].includes('bossallowed') || - lib.character[name][4].includes('hiddenboss')) { - return num ? Math.round(9 * (num - 1) / 8 + 1) : 'sp'; - } - } - return num ? Math.round(9 * (num - 1) / 8 + 1) : 'x'; - } - static skillRank(skill, type, grouped) { - var info = lib.skill[skill]; - var player = _status.event.skillRankPlayer || _status.event.player; - if (!info) return 0; - if (info.ai) { - if (info.ai.halfneg) return 0; - if (typeof info.ai.combo == 'string' && player && !player.hasSkill(info.ai.combo)) { - return 0; - } - if (info.ai.neg) return -1; - } - var num = 1; - var threaten = 1; - if (info.ai && info.ai.threaten) { - if (typeof info.ai.threaten == 'number') { - threaten = info.ai.threaten; - } - else if (typeof info.ai.threaten == 'function' && player) { - threaten = info.ai.threaten(player, player); - } - } - if (type && type.includes('in')) { - if (info.enable == 'phaseUse') num += 0.5; - if (info.trigger && info.trigger.player) { - var list = Array.isArray(info.trigger.player) ? info.trigger.player : [info.trigger.player]; - var add = false; - for (var i of list) { - if (i.startsWith('phase')) { - num += 0.5; - add = true; - } - else { - for (var j of lib.phaseName) { - if (i.indexOf[j] == 0) { - num += 0.5; - add = true; - break; - } - } - } - if (add) break; - } - } - if (info.trigger && ((typeof info.trigger.player == 'string' && info.trigger.player.startsWith('use')) || info.trigger.source)) { - num += 0.3; - } - if (num > 1 && threaten > 1) { - num += Math.sqrt(threaten) - 1; - } - } - if (type && type.includes('out')) { - if (threaten < 1) { - num *= 1 / Math.sqrt(threaten); - } - if (info.trigger) { - if (info.trigger.global) { - var list = Array.isArray(info.trigger.global) ? info.trigger.global : [info.trigger.global]; - num += Math.min(3, list.length) / 10; - for (var i of list) { - if (i.startsWith('lose') || i.startsWith('use')) num += 0.3; - if (i.startsWith('cardsDiscard')) num += 0.4; - } - } - if (info.trigger.target || (typeof info.trigger.player == 'string' && - (info.trigger.player.startsWith('damage') || info.trigger.player.startsWith('lose')))) num += 0.1; - } - if (info.ai) { - if (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) { - num += 0.5; - } - if (info.ai.nolose || info.ai.noh || info.ai.noe || info.ai.nodiscard) { - num += 0.3; - } - } - } - if (!grouped) { - var groups = game.expandSkills([skill]); - groups.remove(skill); - var ggt = []; - for (var i = 0; i < groups.length; i++) { - var gi = get.skillRank(groups[i], type, true); - if (gi < 0) { - num -= 0.5; - } - else if (gi > 1) { - ggt.push(gi); - } - } - if (ggt.length) { - num += Math.max.apply(this, ggt) - 1 + ggt.length / 20; - } - } - return num; - } - static targetsInfo(targets) { - var info = []; - for (var i = 0; i < targets.length; i++) { - info.push(targets[i].dataset.position); - } - return info; - } - static infoTargets(infos) { return Array.from(infos || []).map(info => game.playerMap[info]); } - static cardInfo(card) { return [card.suit, card.number, card.name, card.nature]; } - static cardsInfo(cards = []) { return Array.from(cards).map(get.cardInfo); } - static infoCard(info) { - var card = ui.create.card(); - if (info[0]) { - card.init(info); - } - return card; - } - static infoCards(infos) { return Array.from(infos || []).map(get.infoCard); } - static cardInfoOL(card) { return '_noname_card:' + JSON.stringify([card.cardid, card.suit, card.number, card.name, card.nature]); } - static infoCardOL(info) { - if (!lib.cardOL) return info; - var card; - try { - var info = JSON.parse(info.slice(13)); - var id = info.shift(); - if (!id) { - card = ui.create.card(); - if (info && info[2]) card.init(info); - } - else if (lib.cardOL[id]) { - if (lib.cardOL[id].name != info[2]) { - if (info && info[2]) lib.cardOL[id].init(info); - } - card = lib.cardOL[id]; - } - else if (game.online) { - card = ui.create.card(); - card.cardid = id; - if (info && info[2]) card.init(info); - lib.cardOL[id] = card; - } - } - catch (e) { - console.log(e); - } - return card || info; - } - static cardsInfoOL(cards) { return Array.from(cards || []).map(get.cardInfoOL); } - static infoCardsOL(infos) { return Array.from(infos || []).map(get.infoCardOL); } - static playerInfoOL(player) { return '_noname_player:' + player.playerid; } - static infoPlayerOL(info) { return lib.playerOL ? (lib.playerOL[info.slice(15)] || info) : info; } - static playersInfoOL(players) { return Array.from(players || []).map(get.playerInfoOL); } - static infoPlayersOL(infos) { return Array.from(infos || []).map(get.infoPlayerOL); } - static funcInfoOL(func) { - if (typeof func == 'function') { - if (func._filter_args) { - return '_noname_func:' + JSON.stringify(get.stringifiedResult(func._filter_args, 3)); - } - const str = func.toString(); - // js内置的函数 - if ((/\{\s*\[native code\]\s*\}/).test(str)) return '_noname_func:function () {}'; - return '_noname_func:' + str; - } - return ''; - } - static infoFuncOL(info) { - let func; - const str = info.slice(13).trim(); - try { - // js内置的函数 - if ((/\{\s*\[native code\]\s*\}/).test(str)) return function () {}; - // 一般fun和数组形式 - if (str.startsWith("function") || str.startsWith("(")) eval(`func=(${str});`); - // 其他奇形怪状的fun - else { - try { - eval(`func = ${str}`); - } catch { - eval(`let obj = {${str}}; func = obj[Object.keys(obj)[0]]`); - } - } - } catch (e) { - console.error(`${e} in \n${str}`); - return function () {}; - } - if (Array.isArray(func)) { - func = get.filter.apply(this, get.parsedResult(func)); - } - return func; - } - static eventInfoOL(item, level, noMore) { - return get.itemtype(item) == 'event' ? `_noname_event:${JSON.stringify(Object.entries(item).reduce((stringifying, entry) => { - const key = entry[0]; - if (key == '_trigger') { - if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false); - } - else if (!lib.element.GameEvent.prototype[key] && key != 'content' && get.itemtype(entry[1]) != 'event') stringifying[key] = get.stringifiedResult(entry[1], null, false); - return stringifying; - }, {}))}` : ''; - } - /** - * @param {string} item - */ - static infoEventOL(item) { - const evt = new lib.element.GameEvent(); - try { - Object.entries(JSON.parse(item.slice(14))).forEach(entry => { - const key = entry[0]; - if (typeof evt[key] != 'function') evt[key] = get.parsedResult(entry[1]); - }); - } - catch (error) { - console.log(error); - } - return evt || item; - } - static stringifiedResult(item, level, nomore) { - if (!item) return item; - if (typeof item == 'function') { - return get.funcInfoOL(item); - } - else if (typeof item == 'object') { - switch (get.itemtype(item)) { - case 'card': return get.cardInfoOL(item); - case 'cards': return get.cardsInfoOL(item); - case 'player': return get.playerInfoOL(item); - case 'players': return get.playersInfoOL(item); - case 'event': - if (nomore === false) return ''; - return get.eventInfoOL(item); - default: - if (typeof level != 'number') { - level = 8; - } - if (Array.isArray(item)) { - if (level == 0) { - return []; - } - var item2 = []; - for (var i = 0; i < item.length; i++) { - item2.push(get.stringifiedResult(item[i], level - 1, nomore)); - } - return item2; - } - else if (Object.prototype.toString.call(item) == '[object Object]') { - if (level == 0) { - return {}; - } - var item2 = {}; - for (var i in item) { - item2[i] = get.stringifiedResult(item[i], level - 1, nomore); - } - return item2; - } - else { - return {}; - } - } - } - else if (item === Infinity) { - return '_noname_infinity'; - } - else { - return item; - } - } - static parsedResult(item) { - if (!item) return item; - if (typeof item == 'string') { - if (item.startsWith('_noname_func:')) { - return get.infoFuncOL(item); - } - else if (item.startsWith('_noname_card:')) { - return get.infoCardOL(item); - } - else if (item.startsWith('_noname_player:')) { - return get.infoPlayerOL(item); - } - else if (item.startsWith('_noname_event:')) { - return get.infoEventOL(item); - } - else if (item == '_noname_infinity') { - return Infinity; - } - else { - return item; - } - } - else if (Array.isArray(item)) { - var item2 = []; - for (var i = 0; i < item.length; i++) { - item2.push(get.parsedResult(item[i])); - } - return item2; - } - else if (typeof item == 'object') { - var item2 = {}; - for (var i in item) { - item2[i] = get.parsedResult(item[i]); - } - return item2; - } - else { - return item; - } - } - static verticalStr(str, sp) { - if (typeof str != 'string') return ''; - return Array.from(str).filter(value => value != '`').join(''); - } - static numStr(num, method) { - if (num == Infinity) { - if (method == 'card') return get.selectableCards().length + ui.selected.cards.length; - if (method == 'target') return get.selectableTargets().length + ui.selected.targets.length; - return '∞'; - } - return num.toString(); - } - static rawName(str) { - let str2 = lib.translate[str]; - if (lib.translate[str + '_ab']) str2 = lib.translate[str + '_ab']; - if (!str2) return ''; - if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { - return str2.slice(lib.translate[str + '_prefix'].length); - } - return str2; - } - /** - * 作用修改:只读前缀 不读_ab - */ - static rawName2(str) { - let str2 = lib.translate[str]; - if (!str2) return ''; - if (lib.translate[str + '_prefix'] && str2.startsWith(lib.translate[str + '_prefix'])) { - return str2.slice(lib.translate[str + '_prefix'].length); - } - return str2; - } - static slimNameHorizontal(str) { - const slimName = lib.translate[`${str}_ab`] || lib.translate[str]; - if (!slimName) return ''; - const prefix = lib.translate[`${str}_prefix`]; - if (prefix && slimName.startsWith(prefix)) { - //兼容版特化处理 - if (lib.compatibleEdition) return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)} `; - return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)}`; - } - return slimName; - } - /** - * @param {string} prefix - * @param {string} name - * @returns {string} - */ - static prefixSpan(prefix, name) { - const config = lib.config.buttoncharacter_prefix; - if (config == 'off') return ''; - if (config == 'simple') { - const span = document.createElement('span'); - span.innerHTML = prefix; - return span.outerHTML; - } - const namePrefix = lib.namePrefix.get(prefix), exists = Boolean(namePrefix); - if (exists && 'getSpan' in namePrefix) return namePrefix.getSpan(prefix, name); - const span = document.createElement('span'); - if (exists) { - if ('color' in namePrefix) span.style.color = namePrefix.color; - if ('nature' in namePrefix) span.dataset.nature = namePrefix.nature; - if ('showName' in namePrefix) prefix = namePrefix.showName; - } - else span.style.color = '#ffffff'; - span.innerHTML = prefix; - return span.outerHTML; - } - static slimName(str) { return get.verticalStr(get.slimNameHorizontal(str), true); } - static time() { - if (lib.status.dateDelaying) { - return lib.getUTC(lib.status.dateDelaying) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; - } - else { - return lib.getUTC(new Date()) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; - } - } - static utc() { return (new Date()).getTime(); } - static evtDistance(e1, e2) { - var dx = (e1.clientX - e2.clientX) / game.documentZoom; - var dy = (e1.clientY - e2.clientY) / game.documentZoom; - return Math.sqrt(dx * dx + dy * dy); - } - static xyDistance(from, to) { return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])); } - /** - * @overload - * @returns { void } - */ - /** - * @overload - * @param { string } obj - * @returns { 'position' | 'natures' | 'nature' } - */ - /** - * @overload - * @param { Player[] } obj - * @returns { 'players' } - */ - /** - * @overload - * @param { Card[] } obj - * @returns { 'cards' } - */ - /** - * @overload - * @param { [number, number] } obj - * @returns { 'select' } - */ - /** - * @overload - * @param { [number, number, number, number] } obj - * @returns { 'divposition' } - */ - /** - * @overload - * @param { Button } obj - * @returns { 'button' } - */ - /** - * @overload - * @param { Card } obj - * @returns { 'card' } - */ - /** - * @overload - * @param { Player } obj - * @returns { 'player' } - */ - /** - * @overload - * @param { Dialog } obj - * @returns { 'dialog' } - */ - /** - * @overload - * @param { GameEvent | GameEventPromise } obj - * @returns { 'event' } - */ - static itemtype(obj) { - if (typeof obj == 'string') { - if (obj.length <= 5) { - let bool = true; - for (let i = 0; i < obj.length; i++) { - if (/h|e|j|s|x/.test(obj[i]) == false) { - bool = false; break; - } - } - if (bool) return 'position'; - } - if (obj.includes(lib.natureSeparator) && obj.split(lib.natureSeparator).every(n => lib.nature.has(n))) return 'natures'; - if (lib.nature.has(obj)) return 'nature'; - } - if (Array.isArray(obj) && obj.length > 0) { - if (obj.every(p => p instanceof lib.element.Player)) return 'players'; - if (obj.every(p => p instanceof lib.element.Card)) return 'cards'; - if (obj.length == 2) { - if (typeof obj[0] == 'number' && typeof obj[1] == 'number') { - if (obj[0] <= obj[1] || obj[1] <= -1) return 'select'; - } - } - if (obj.length == 4) { - if (obj.every(p => typeof p == 'number')) { - return 'divposition'; - } - } - } - if (obj instanceof lib.element.Button || obj instanceof HTMLDivElement && obj.classList.contains('button') ) return 'button'; - if (obj instanceof lib.element.Card) return 'card'; - if (obj instanceof lib.element.Player) return 'player'; - if (obj instanceof lib.element.Dialog) return 'dialog'; - if (obj instanceof lib.element.GameEvent || - obj instanceof lib.element.GameEventPromise) return 'event'; - - if (typeof obj !== 'object' || obj === null) return; - - if (lib.experimental.symbol.itemType in obj) - return obj[lib.experimental.symbol.itemType]; - } - static equipNum(card) { - if (get.type(card) == 'equip') { - return parseInt(get.subtype(card)[5]); - } - return 0; - } - static objtype(obj) { - if (Object.prototype.toString.call(obj) === '[object Array]') return 'array'; - if (Object.prototype.toString.call(obj) === '[object Object]') return 'object'; - if (Object.prototype.toString.call(obj) === '[object HTMLDivElement]') return 'div'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableElement]') return 'table'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableRowElement]') return 'tr'; - if (Object.prototype.toString.call(obj) === '[object HTMLTableCellElement]') return 'td'; - if (Object.prototype.toString.call(obj) === '[object HTMLBodyElement]') return 'td'; - if (Object.prototype.toString.call(obj) === '[object DocumentFragment]') return 'fragment'; - } - static type(obj, method, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - var name = get.name(obj, player); - if (!lib.card[name]) { - if (!name.startsWith('sha_')) return; - if (name.slice(4).split('_').every(n => lib.nature.has(n))) return lib.card['sha'].type; - } - if (method == 'trick' && lib.card[name].type == 'delay') return 'trick'; - return lib.card[name].type; - } - static type2(card, player) { return get.type(card, 'trick', player); } - /** - * - * @param { string | Card | VCard | CardBaseUIData } obj - * @param { false | Player } [player] - * @returns { string } - */ - static subtype(obj, player) { - if (typeof obj == 'string') obj = { name: obj }; - if (typeof obj != 'object') return; - const name = get.name(obj, player); - if (!lib.card[name]) return; - let subtype = lib.card[name].subtype; - return subtype; - } - static equiptype(card, player) { - var subtype = get.subtype(card, player); - if (subtype.startsWith('equip')) return parseInt(subtype[5]); - return 0; - } - /** - * - * @param { Card | VCard | CardBaseUIData } card - * @param { false | Player } [player] - * @returns { string } - */ - static name(card, player) { - if (get.itemtype(player) == 'player' || (player !== false && get.position(card) == 'h')) { - var owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, card.name, 'cardname', owner); - } - } - return card.name; - } - /** - * @param {Card | VCard | Card[] | VCard[]} card - * @param {false | Player} [player] - * @returns {string} - */ - static suit(card, player) { - if (typeof card !== 'object') return; - if (Array.isArray(card)) { - if (card.length == 1) return get.suit(card[0], player); - return 'none'; - } - else if (!('suit' in card) && Array.isArray(card.cards)) { - return get.suit(card.cards, player); - } - else { - if (player !== false) { - const owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, game.checkMod(card, card.suit, 'suit', owner), 'cardsuit', owner); - } - } - if (card.suit === 'unsure' || lib.suits.includes(card.suit)) return card.suit; - return 'none'; - } - } - /** - * @param {Card | VCard | Card[] | VCard[]} card - * @param {false | Player} [player] - * @returns {string} - */ - static color(card, player) { - if (typeof card !== 'object') return; - if (Array.isArray(card)) { - if (!card.length) return 'none'; - const cards = card.slice(), color = get.color(cards.shift(), player); - for (const anotherCard of cards) { - if (get.color(anotherCard, player) != color) return 'none'; - } - return color; - } - else if (card.color === 'unsure' || Object.keys(lib.color).includes(card.color)) { - return card.color; - } - else if (Array.isArray(card.cards) && !lib.suit.includes(card.suit)) { - return get.color(card.cards, player); - } - else { - const suit = get.suit(card, player); - for (const entry of Object.entries(lib.color)) { - if (entry[1].includes(suit)) return entry[0]; - } - return 'none'; - } - } - /** - * @param {Card | VCard} card - * @param {false | Player} [player] - * @returns {number} - */ - static number(card, player) { - if (typeof card !== 'object') return; - //狗卡你是真敢出啊 - var number = null; - if ('number' in card) { - number = card.number; - if (number === 'unsure') return number; - else if (typeof number != 'number') number = null; - } - else { - if (card.cards && card.cards.length == 1) number = get.number(card.cards[0], false); - } - if (player !== false) { - var owner = player || get.owner(card); - if (owner) { - return game.checkMod(card, owner, number, 'cardnumber', owner); - } - } - return number; - } - /** - * 返回一张杀的属性。如有多种属性则用`lib.natureSeparator`分割开来。例:火雷【杀】的返回值为`fire|thunder` - * @param {string | string[] | Card | VCard} card - * @param {false | Player} [player] - * @returns {string} - */ - static nature(card, player) { - if (typeof card == 'string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); - if (Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); - var nature = card.nature; - if (get.itemtype(player) == 'player' || player !== false) { - var owner = get.owner(card); - if (owner) { - return game.checkMod(card, owner, nature, 'cardnature', owner); - } - } - return nature; - } - /** - * 返回包含所有属性的数组 - * @param {string[] | string} card - * @param {false | Player} [player] - * @returns {string[]} - */ - static natureList(card, player) { - if (!card) return []; - if (get.itemtype(card) == 'natures') return card.split(lib.natureSeparator); - if (get.itemtype(card) == 'nature') return [card]; - const natures = get.nature(card, player); - if (typeof natures != 'string') return []; - return natures.split(lib.natureSeparator); - } - static cards(num, putBack) { - if (_status.waitingForCards) { - ui.create.cards.apply(ui.create, _status.waitingForCards); - delete _status.waitingForCards; - } - var list = []; - var card = false; - if (typeof num != 'number') num = 1; - if (num == 0) { card = true; num = 1; } - if (num < 0) num = 1; - while (num--) { - if (ui.cardPile.hasChildNodes() == false) { - game.washCard(); - } - if (ui.cardPile.hasChildNodes() == false) { - game.over('平局'); - return []; - } - var cardx = ui.cardPile.removeChild(ui.cardPile.firstChild); - cardx.original = 'c'; - list.push(cardx); - } - if (putBack) { - for (let i = list.length - 1; i >= 0; i--) { - ui.cardPile.insertBefore(list[i], ui.cardPile.firstChild); - } - } - game.updateRoundNumber(); - if (card) return list[0]; - return list; - } - static judge(card) { - const cardInfo = (card.viewAs ? lib.card[card.viewAs] : get.info(card)); - return (cardInfo && cardInfo.judge) ? cardInfo.judge : ()=>0; - } - static judge2(card) { return card.viewAs ? lib.card[card.viewAs].judge2 : get.info(card).judge2; } - static distance(from, to, method) { - if (from == to) return 0; - if (!game.players.includes(from) && !game.dead.includes(from)) return Infinity; - if (!game.players.includes(to) && !game.dead.includes(to)) return Infinity; - let n = 1; - if (game.chess) { - let fxy = from.getXY(), txy = to.getXY(); - n = Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); - if (method == 'raw' || method == 'pure' || method == 'absolute') return n; - } - else if (to.isMin(true) || from.isMin(true)) { - if (method == 'raw' || method == 'pure' || method == 'absolute') return n; - } - else { - let player = from, length = game.players.length; - const totalPopulation = game.players.length + game.dead.length + 1; - for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { - if (player.nextSeat != to) { - player = player.nextSeat; - if (player.isAlive() && !player.isOut() && !player.hasSkill('undist') && !player.isMin(true)) n++; - } - else { - break; - } - } - for (let i = 0; i < game.players.length; i++) { - if (game.players[i].isOut() || game.players[i].hasSkill('undist') || game.players[i].isMin(true)) length--; - } - if (method == 'absolute') return n; - if (from.isDead()) length++; - if (to.isDead()) length++; - const left = from.hasSkillTag('left_hand'), right = from.hasSkillTag('right_hand'); - if (left === right) n = Math.min(n, length - n); - else if (left == true) n = length - n; - if (method == 'raw' || method == 'pure') return n; - } - n = game.checkMod(from, to, n, 'globalFrom', from); - n = game.checkMod(from, to, n, 'globalTo', to); - const equips1 = from.getCards('e', function (card) { - return !ui.selected.cards || !ui.selected.cards.includes(card); - }), equips2 = to.getCards('e', function (card) { - return !ui.selected.cards || !ui.selected.cards.includes(card); - }); - for (let i = 0; i < equips1.length; i++) { - let info = get.info(equips1[i]).distance; - if (!info) continue; - if (info.globalFrom) { - n += info.globalFrom; - } - } - for (let i = 0; i < equips2.length; i++) { - let info = get.info(equips2[i]).distance; - if (!info) continue; - if (info.globalTo) { - n += info.globalTo; - } - if (info.attaclTo) { - m += info.attaclTo; - } - } - if (method == 'attack') { - let m = n; - m = game.checkMod(from, to, m, 'attackFrom', from); - m = game.checkMod(from, to, m, 'attackTo', to); - return m; - // const attakRange=from.getEquipRange(); - // m+=(1-attakRange); - // for(let i=0;iSelect) } [select] - * @returns { Select } - */ - static select(select) { - if (typeof select == 'function') return get.select(select()); - else if (typeof select == 'number') return [select, select]; - else if (select && get.itemtype(select) == 'select') return select; - return [1, 1]; - } - static card(original) { - if (_status.event.skill) { - var card = get.info(_status.event.skill).viewAs; - if (typeof card == 'function') card = card(ui.selected.cards, _status.event.player); - if (card) { - return get.autoViewAs(card, ui.selected.cards); - } - } - if (_status.event._get_card) { - return _status.event._get_card; - } - var card = ui.selected.cards[0]; - if (original) return card; - if (card) { - card = get.autoViewAs(card, ui.selected.cards); - } - return card; - } - /** - * @overload - * @returns {GameEvent} - */ - /** - * @template { keyof GameEvent } T - * @overload - * @param {T} key - * @returns {GameEvent[T]} - */ - static event(key) { return key ? _status.event[key] : _status.event; } - static player() { return _status.event.player; } - static players(sort, dead, out) { - var players = game.players.slice(0); - if (sort != false) { - if (typeof sort == 'function') players.sort(sort); - else players.sortBySeat(get.itemtype(sort) == "player" ? sort : _status.event.player); - } - if (dead) players = players.concat(game.dead); - if (!out) players = players.filter(current => !current.isOut()); - return players; - } - static position(card, ordering) { - if (get.itemtype(card) == 'player') return parseInt(card.dataset.position); - if (card.timeout && card.destiny && card.destiny.classList) { - if (card.destiny.classList.contains('equips')) return 'e'; - if (card.destiny.classList.contains('judges')) return 'j'; - if (card.destiny.classList.contains('expansions')) return 'x'; - if (card.destiny.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; - if (card.destiny.id == 'cardPile') return 'c'; - if (card.destiny.id == 'discardPile') return 'd'; - if (card.destiny.id == 'special') return 's'; - if (card.destiny.id == 'ordering') return ordering ? 'o' : 'd'; - return null; - } - if (!card.parentNode || !card.parentNode.classList) return; - if (card.parentNode.classList.contains('equips')) return 'e'; - if (card.parentNode.classList.contains('judges')) return 'j'; - if (card.parentNode.classList.contains('expansions')) return 'x'; - if (card.parentNode.classList.contains('handcards')) return card.classList.contains('glows') ? 's' : 'h'; - if (card.parentNode.id == 'cardPile') return 'c'; - if (card.parentNode.id == 'discardPile') return 'd'; - if (card.parentNode.id == 'special') return 's'; - if (card.parentNode.id == 'ordering') return ordering ? 'o' : 'd'; - return null; - } - static skillTranslation(str, player) { - var str2; - if (str.startsWith('re')) { - str2 = str.slice(2); - if (str2) { - if (lib.translate[str] == lib.translate[str2]) { - if (player.hasSkill(str2)) { - return '界' + lib.translate[str]; - } - } - } - } - else if (str.startsWith('xin')) { - str2 = str.slice(3); - if (str2) { - if (lib.translate[str] == lib.translate[str2]) { - if (player.hasSkill(str2)) { - return '新' + lib.translate[str]; - } - } - } - } - return get.translation(str); - } - static skillInfoTranslation(name, player) { - if (player && lib.dynamicTranslate[name]) return lib.dynamicTranslate[name](player, name); - var str = lib.translate[name + '_info']; - if (!str) return ''; - return str; - // return str.replace(/锁定技/g,'锁定技'). - // replace(/限定技/g,'限定技'). - // replace(/觉醒技/g,'觉醒技'). - // replace(/主将技/g,'主将技'). - // replace(/副将技/g,'副将技'). - // replace(/阵法技/g,'阵法技'). - // replace(/主公技/g,'主公技'); - } - /** - * @returns {string} - */ - static translation(str, arg) { - if (str && typeof str == 'object' && (str.name || str._tempTranslate)) { - if (str._tempTranslate) return str._tempTranslate; - var str2; - if (arg == 'viewAs' && str.viewAs) { - str2 = get.translation(str.viewAs); - } - else { - str2 = get.translation(str.name); - } - if (str2 == '杀') { - str2 = ''; - if (typeof str.nature == 'string') { - let natures = str.nature.split(lib.natureSeparator).sort(lib.sort.nature); - for (let nature of natures) { - str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; - } - } - str2 += '杀'; - } - if (get.itemtype(str) == 'card' || str.isCard) { - if (_status.cardtag && str.cardid) { - var tagstr = ''; - for (var i in _status.cardtag) { - if (_status.cardtag[i].includes(str.cardid)) { - tagstr += lib.translate[i + '_tag']; - } - } - if (tagstr) { - str2 += '·' + tagstr; - } - } - if (str.suit && str.number || str.isCard) { - var cardnum = get.number(str, false) || ''; - if ([1, 11, 12, 13].includes(cardnum)) { - cardnum = { '1': 'A', '11': 'J', '12': 'Q', '13': 'K' }[cardnum]; - } - if (arg == 'viewAs' && str.viewAs != str.name && str.viewAs) { - str2 += '(' + get.translation(str) + ')'; - } - else { - str2 += '【' + get.translation(get.suit(str, false)) + cardnum + '】'; - // var len=str2.length-1; - // str2=str2.slice(0,len)+''+str2[len]+'·'+get.translation(str.suit)+str.number; - } - } - } - return str2; - } - if (Array.isArray(str)) { - var str2 = get.translation(str[0], arg); - for (var i = 1; i < str.length; i++) { - str2 += '、' + get.translation(str[i], arg); - } - return str2; - } - if (get.itemtype(str) == 'natures') { - let natures = str.split(lib.natureSeparator).sort(lib.sort.nature); - var str2 = ''; - for (var nature of natures) { - str2 += lib.translate['nature_' + nature] || lib.translate[nature] || ''; - } - return str2; - } - if (arg == 'skill') { - if (lib.translate[str + '_ab']) return lib.translate[str + '_ab']; - if (lib.translate[str]) return lib.translate[str].slice(0, 2); - return str; - } - else if (arg == 'info') { - if (lib.translate[str + '_info']) return lib.translate[str + '_info']; - var str2 = str.slice(0, str.length - 1); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - if (str.lastIndexOf('_') > 0) { - str2 = str.slice(0, str.lastIndexOf('_')); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - } - str2 = str.slice(0, str.length - 2); - if (lib.translate[str2 + '_info']) return lib.translate[str2 + '_info']; - if (lib.skill[str] && lib.skill[str].prompt) return lib.skill[str].prompt; - } - if (lib.translate[str]) { - return lib.translate[str]; - } - if (typeof str == 'string') { - if (lib.translate['nature_' + str]) return lib.translate['nature_' + str]; - return str; - } - if (typeof str == 'number' || typeof str == 'boolean') { - return str.toString(); - } - if (str && str.toString) { - return str.toString(); - } - return ''; - } - static menuZoom(){ - if(game.menuZoom === undefined || game.menuZoom === null){ - return game.documentZoom; - } - return game.menuZoom; - } - static strNumber(num) { - switch (num) { - case 1: return 'A'; - case 11: return 'J'; - case 12: return 'Q'; - case 13: return 'K'; - default: return num.toString(); - } - } - static cnNumber(num, ordinal) { - if (isNaN(num)) return ''; - let numStr = num.toString(); - if (numStr === 'Infinity') return '∞'; - if (numStr === '-Infinity') return '-∞'; - if (!/^\d+$/.test(numStr)) return num; - - const chars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; - const units = ['', '十', '百', '千']; - - if (numStr.length <= 2) {//两位数以下单独处理保证效率 - if (numStr.length === 1) return !ordinal && num === 2 ? '两' : chars[num]; - return `${numStr[0] === '1' ? '' : chars[numStr[0]]}十${numStr[1] === '0' ? '' : chars[numStr[1]]}`; - } - - numStr = numStr.replace(/(?=(\d{4})+$)/g, ',').split(',').filter(Boolean); - const handleZero = str => { - let result = str.replace(/零{2,}/g, '零'); - if (result.length > 1) result = result.replace(/零+$/g, ''); - return result; - }; - const _transform = str => { - if (str === '2' && !ordinal) return '两'; - let result = ''; - for (let i = 0; i < str.length; i++) { - const part = str[str.length - 1 - i]; - let char = chars[+part]; - let unit = units[i]; - if (char === '零') unit = ''; - else if (char === '一' && i === 1 && str.length === 2) char = ''; - else if (char === '二' && i > 1 && !ordinal) char = '两'; - result = char + unit + result; - } - result = handleZero(result); - return result; - }; - let result = ''; - let tempYi = ''; - for (let i = 0; i < numStr.length; i++) { - const part = numStr[numStr.length - 1 - i]; - let char = _transform(part); - let unit = ''; - if (i % 2) { - [unit, tempYi] = ['万' + tempYi, '']; - if (char === '零') unit = ''; - } else { - unit = '亿'.repeat(i / 2); - if (char === '零') [unit, tempYi] = ['', unit]; - } - result = char + unit + result; - } - result = handleZero(result); - return result; - } - /** - * 遍历子元素 - * @param {HTMLElement} node - * @returns {Iterable} 迭代器 - */ - static *iterableChildNodes(node){ - for(let i=0;i number)} [sort] 排序函数 - * @returns { Button[] } - */ - static selectableButtons(sort) { - if (!_status.event.player) return []; - var buttons = _status.event.dialog.buttons; - var selectable = []; - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].classList.contains('selectable') && - buttons[i].classList.contains('selected') == false) { - selectable.push(buttons[i]); - } - } - if (sort) { - selectable.sort(sort); - } - return selectable; - } - /** - * @param {((a: Card, b: Card) => number)} [sort] 排序函数 - * @returns { Card[] } - */ - static selectableCards(sort) { - if (!_status.event.player) return []; - var cards = _status.event.player.getCards('hes'); - var selectable = []; - for (var i = 0; i < cards.length; i++) { - if (cards[i].classList.contains('selectable') && - cards[i].classList.contains('selected') == false) { - selectable.push(cards[i]); - } - } - if (sort) { - selectable.sort(sort); - } - return selectable; - } - /** - * @returns { string[] } 技能名数组 - */ - static skills() { - var skills = []; - if (ui.skills) { - skills = skills.concat(ui.skills.skills); - } - if (ui.skills2) { - skills = skills.concat(ui.skills2.skills); - } - if (ui.skills3) { - skills = skills.concat(ui.skills3.skills); - } - return skills; - } - static gainableSkills(func, player) { - var list = []; - for (var i in lib.character) { - if (lib.filter.characterDisabled(i)) continue; - if (lib.filter.characterDisabled2(i)) continue; - if (lib.character[i][4]) { - if (lib.character[i][4].includes('boss')) continue; - if (lib.character[i][4].includes('hiddenboss')) continue; - if (lib.character[i][4].includes('minskin')) continue; - if (lib.character[i][4].includes('unseen')) continue; - } - for (var j = 0; j < lib.character[i][3].length; j++) { - var skill = lib.character[i][3][j]; - var info = lib.skill[skill]; - if (lib.filter.skillDisabled(skill)) continue; - if (func && !func(info, skill, i)) continue; - if (player && player.hasSkill && info.ai && info.ai.combo && !player.hasSkill(info.ai.combo)) continue; - list.add(skill); - } - } - return list; - } - static gainableSkillsName(name, func) { - var list = []; - if (name && lib.character[name]) { - if (lib.character[name][4]) { - if (lib.character[name][4].includes('boss')) return list; - if (lib.character[name][4].includes('hiddenboss')) return list; - if (lib.character[name][4].includes('minskin')) return list; - if (lib.character[name][4].includes('unseen')) return list; - } - for (var j = 0; j < lib.character[name][3].length; j++) { - var skill = lib.character[name][3][j]; - var info = lib.skill[skill]; - if (lib.filter.skillDisabled(skill)) continue; - if (func && !func(info, skill, name)) continue; - list.add(skill); - } - } - return list; - } - static gainableCharacters(func) { - var list = []; - for (var i in lib.character) { - var info = lib.character[i]; - if (!info) continue; - if (typeof func == 'function' && !func(info, i)) continue; - if (lib.filter.characterDisabled(i)) continue; - if (lib.filter.characterDisabled2(i)) continue; - list.push(i); - } - if (func === true) { - var players = game.players.concat(game.dead); - for (var i = 0; i < players.length; i++) { - list.remove(players[i].name); - list.remove(players[i].name1); - list.remove(players[i].name2); - } - } - return list; - } - /** - * @param {((a: Player, b: Player) => number)} [sort] 排序函数 - * @returns { Player[] } - */ - static selectableTargets(sort) { - var selectable = []; - var players = game.players.slice(0); - if (_status.event.deadTarget) players.addArray(game.dead); - for (var i = 0; i < players.length; i++) { - if (players[i].classList.contains('selectable') && - players[i].classList.contains('selected') == false) { - selectable.push(players[i]); - } - } - selectable.randomSort(); - if (sort) { - selectable.sort(sort); - } - return selectable; - } - static filter(filter, i) { - if (typeof filter == 'function') return filter; - if (i == undefined) i = 0; - var result = function () { - if (filter == arguments[i]) return true; - for (var j in filter) { - if (Object.prototype.hasOwnProperty.call(filter, j)) { - if (get.itemtype(arguments[i]) == 'card') { - if (j == 'name') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.name(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.name(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'type') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.type(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.type(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'subtype') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.subtype(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.subtype(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'color') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.color(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.color(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'suit') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.suit(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.suit(arguments[i]) != filter[j]) return false; - } - } - else if (j == 'number') { - if (Array.isArray(filter[j])) { - if (filter[j].includes(get.number(arguments[i])) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (get.number(arguments[i]) != filter[j]) return false; - } - } - else if (Array.isArray(filter[j])) { - if (filter[j].includes(arguments[i][j]) == false) return false; - } - else if (typeof filter[j] == 'string') { - if (arguments[i][j] != filter[j]) return false; - } - } - else { - if (arguments[i][j] != filter[j]) return false; - } - } - } - return true; - }; - result._filter_args = [filter, i]; - return result; - } - static cardCount(card, player) { - var num; - if (player == undefined) player = _status.event.player; - if (card == true) { - num = 0; - var stat = player.getStat('card'); - for (var i in stat) { - if (typeof stat[i] == 'number') num += stat[i]; - } - return num; - } - if (typeof card == 'object') { - card = card.name; - } - num = player.getStat('card')[card]; - if (num == undefined) return 0; - return num; - } - static skillCount(skill, player) { - if (player == undefined) player = _status.event.player; - var num = player.getStat('skill')[skill]; - if (num == undefined) return 0; - return num; - } - static owner(card, method) { - return game.players.concat(game.dead).find(current=>{ - if(current.judging[0] == card && method != "judge")return true; - let parent = card.parentNode; - if(parent == current.node.handcards1 || parent == current.node.handcards2){ - return !card.classList.contains('removing'); - }else if(parent == current.node.equips){ - return !card.classListContains('removing','feichu','emptyequip'); - }else if(parent == current.node.judges){ - return !card.classListContains('removing','feichu'); - }else if(parent == current.node.expansions){ - return !card.classListContains('removing'); - } - return false; - }); - //return game.players.concat(game.dead).find(current => - // current.getCards("hejsx").includes(card) || (current.judging[0] == card && method != "judge")); - } - static noSelected() { return ui.selected.buttons.length + ui.selected.cards.length + ui.selected.targets.length == 0; } - static population(identity) { - return identity == undefined ? - game.players.length + game.dead.length : - game.players.filter(current => current.identity == identity).length; - } - static totalPopulation(identity) { - return identity == undefined ? - game.players.length + game.dead.length : - game.players.concat(game.dead).filter(current => current.identity == identity).length; - } - /** - * @param { Card | VCard } item - */ - static cardtag(item, tag) { - return (item.cardid && (get.itemtype(item) == 'card' || !item.cards || !item.cards.length || item.name == item.cards[0].name) && _status.cardtag && _status.cardtag[tag] && _status.cardtag[tag].includes(item.cardid)) - || (item.cardtags && item.cardtags.includes(tag)); - } - static tag(item, tag, item2, bool) { - var result; - if (get.info(item, bool) && get.info(item, bool).ai && get.info(item, bool).ai.tag) { - result = get.info(item, bool).ai.tag[tag]; - } - if (typeof result == 'function') return result(item, item2); - return result; - } - static sortCard(sort) { - var func; - if (sort == 'type_sort') { - func = function (card) { - var type = get.type(card, null, false); - var subtype = get.subtype(card, false); - if (lib.cardType[subtype]) { - return lib.cardType[subtype]; - } - if (lib.cardType[type]) { - return lib.cardType[type]; - } - switch (type) { - case 'basic': return 2; - case 'chess': return 1.5; - case 'trick': return -1; - case 'delay': return -2; - case 'equip': return -3; - default: return -4; - } - }; - } - else if (sort == 'suit_sort') { - func = function (card) { - if (get.suit(card) == 'heart') return 2; - if (get.suit(card) == 'diamond') return 1; - if (get.suit(card) == 'spade') return -1; - if (get.suit(card) == 'club') return -2; - }; - } - else if (sort == 'number_sort') { - func = function (card) { - return get.number(card) - 7 + 0.5; - }; - } - return func; - } - static difficulty() { - switch (get.config('difficulty')) { - case 'easy': return 1; - case 'normal': return 2; - case 'hard': return 3; - default: return 1; - } - } - static cardPile(name, create) { - var filter = function (card) { - if (typeof name == 'string') { - if (card.name == name) { - return true; - } - } - else if (typeof name == 'function') { - if (name(card)) { - return true; - } - } - return false; - }; - if (create != 'discardPile') { - var num = get.rand(0, ui.cardPile.childNodes.length - 1); - for (var i = 0; i < ui.cardPile.childNodes.length; i++) { - var j = i; - if (j >= ui.cardPile.childNodes.length) j -= ui.cardPile.childNodes.length; - if (filter(ui.cardPile.childNodes[j])) { - return ui.cardPile.childNodes[j]; - } - } - } - if (create != 'cardPile') { - for (var i = 0; i < ui.discardPile.childNodes.length; i++) { - var j = i; - if (j >= ui.discardPile.childNodes.length) j -= ui.discardPile.childNodes.length; - if (filter(ui.discardPile.childNodes[j])) { - return ui.discardPile.childNodes[j]; - } - } - } - if (create == 'field') { - var found = null; - game.findPlayer(function (current) { - var ej = current.getCards('ej'); - for (var i = 0; i < ej.length; i++) { - if (filter(ej[i])) { - found = ej[i]; - return true; - } - } - }); - return found; - } - if (create && !['cardPile', 'discardPile', 'field'].includes(create)) { - return game.createCard(name); - } - return null; - } - static cardPile2(name) { return get.cardPile(name, 'cardPile'); } - static discardPile(name) { return get.cardPile(name, 'discardPile'); } - static aiStrategy() { - switch (get.config('ai_strategy')) { - case 'ai_strategy_1': return 1; - case 'ai_strategy_2': return 2; - case 'ai_strategy_3': return 3; - case 'ai_strategy_4': return 4; - case 'ai_strategy_5': return 5; - case 'ai_strategy_6': return 6; - default: return 1; - } - } - static skillintro(name, learn, learn2) { - var str = ''; - var infoitem = lib.character[name]; - if (!infoitem) { - for (var itemx in lib.characterPack) { - if (lib.characterPack[itemx][name]) { - infoitem = lib.characterPack[itemx][name]; break; - } - } - } - var skills = infoitem[3]; - var opacity; - for (var i = 0; i < skills.length; i++) { - if (lib.translate[skills[i]] && lib.translate[skills[i] + '_info'] && lib.skill[skills[i]]) { - if (learn && lib.skill[skills[i]].unique && (learn2 || !lib.skill[skills[i]].gainable)) { - opacity = 'opacity:0.5'; - } - else { - opacity = ''; - } - var skilltrans = get.translation(skills[i]).slice(0, 2); - str += '
                                    【' + skilltrans + '】
                                    ' + - get.skillInfoTranslation(skills[i]) + '
                                    '; - } - } - return str; - } - static intro(name) { - var info = lib.character[name]; - var str = '性别:' + get.translation(info[0]) + '
                                    '; - str += '势力:' + get.translation(info[1]) + '
                                    '; - str += '体力:' + get.translation(info[2]) + '
                                    '; - str += '技能:'; - if (info[3].length) { - str += get.translation(info[3][0]); - for (var i = 1; i < info[3].length; i++) { - str += '、' + get.translation(info[3][i]); - } - } - return str; - } - static storageintro(type, content, player, dialog, skill) { - switch (type) { - case 'mark': { - if (content > 0) { - return '共有' + content + '个标记'; - } - return false; - } - case 'turn': { - if (content > 0) { - return '剩余' + content + '个回合'; - } - return false; - } - case 'time': { - if (content > 0) { - return '剩余' + content + '次'; - } - return false; - } - case 'limited': { - if (content) { - return '已发动'; - } - return '未发动'; - } - case 'info': { - return lib.translate[skill + '_info']; - } - case 'cardCount': { - if (Array.isArray(content)) { - return '共有' + get.cnNumber(content.length) + '张牌'; - } - return false; - } - case 'expansion': { - content = player.getCards('x', function (card) { - return card.hasGaintag(skill); - }); - if (dialog && content.length) { - dialog.addAuto(content); - } - else { - return '没有卡牌'; - } - return false; - } - case 'card': case 'cards': { - if (get.itemtype(content) == 'card') { - content = [content]; - } - if (dialog && get.itemtype(content) == 'cards') { - dialog.addAuto(content); - } - else { - if (content && content.length) { - return get.translation(content); - } - } - if (Array.isArray(content) && !content.length) { - return '没有卡牌'; - } - return false; - } - case 'player': case 'players': { - if (get.itemtype(content) == 'player') { - content = [content]; - } - if (dialog && get.itemtype(content) == 'players') { - dialog.addAuto(content); - return false; - } - else { - if (content && content.length) { - return get.translation(content); - } - return false; - } - } - case 'character': case 'characters': { - if (typeof content == 'string') { - content = [content]; - } - if (dialog && Array.isArray(content)) { - dialog.addAuto([content, 'character']); - return false; - } - else { - if (content && content.length) { - return get.translation(content); - } - return false; - } - } - default: { - if (typeof type == 'string') { - type = type.replace(/#/g, content); - type = type.replace(/&/g, get.cnNumber(content)); - type = type.replace(/\$/g, get.translation(content)); - return type; - } - else if (typeof type == 'function') { - return type(content, player, skill); - } - return false; - } - } - } - static nodeintro(node, simple, evt) { - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - if (node.classList.contains('player') && !node.name) { - return uiintro; - } - var i, translation, intro, str; - if (node._nointro) return; - if (typeof node._customintro == 'function') { - if (node._customintro(uiintro, evt) === false) return; - if (evt) lib.placePoppedDialog(uiintro, evt); - } - else if (Array.isArray(node._customintro)) { - var caption = node._customintro[0]; - var content = node._customintro[1]; - if (typeof caption == 'function') { - caption = caption(node); - } - if (typeof content == 'function') { - content = content(node); - } - uiintro.add(caption); - uiintro.add('
                                    ' + content + '
                                    '); - } - else if (node.classList.contains('player') || node.linkplayer) { - if (node.linkplayer) { - node = node.link; - } - let capt = get.translation(node.name); - const characterInfo = get.character(node.name), sex = node.sex || characterInfo[0]; - if (sex && sex != 'unknown' && lib.config.show_sex) capt += `  ${sex == 'none' ? '无' : get.translation(sex)}`; - const group = node.group; - if (group && group != 'unknown' && lib.config.show_group) capt += `  ${get.translation(group)}`; - uiintro.add(capt); - - if (lib.characterTitle[node.name]) { - uiintro.addText(get.colorspan(lib.characterTitle[node.name])); - } - - if (get.characterInitFilter(node.name)) { - const initFilters = get.characterInitFilter(node.name).filter(tag => { - if (!lib.characterInitFilter[node.name]) return true; - return lib.characterInitFilter[node.name](tag) !== false; - }); - if(initFilters.length){ - const str = initFilters.reduce((strx, stry) => strx + lib.InitFilter[stry] + '
                                    ', '').slice(0, -4); - uiintro.addText(str); - } - } - - if (!node.noclick) { - const allShown = (node.isUnderControl() || (!game.observe && game.me && game.me.hasSkillTag('viewHandcard', null, node, true))); - const shownHs = node.getShownCards(); - if (shownHs.length) { - uiintro.add('
                                    明置的手牌
                                    '); - uiintro.addSmall(shownHs); - if (allShown) { - var hs = node.getCards('h'); - hs.removeArray(shownHs); - if (hs.length) { - uiintro.add('
                                    其他手牌
                                    '); - uiintro.addSmall(hs); - } - } - } - else if (allShown) { - var hs = node.getCards('h'); - if (hs.length) { - uiintro.add('
                                    手牌
                                    '); - uiintro.addSmall(hs); - } - } - } - - var skills = node.getSkills(null, false, false).slice(0); - var skills2 = game.filterSkills(skills, node); - if (node == game.me && node.hiddenSkills.length) { - skills.addArray(node.hiddenSkills); - } - for (var i in node.disabledSkills) { - if (node.disabledSkills[i].length == 1 && - node.disabledSkills[i][0] == i + '_awake' && - !node.hiddenSkills.includes(i)) { - skills.add(i); - } - } - for (i = 0; i < skills.length; i++) { - if (lib.skill[skills[i]] && (lib.skill[skills[i]].nopop || lib.skill[skills[i]].equipSkill)) continue; - if (lib.translate[skills[i] + '_info']) { - if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; - else { - translation = get.translation(skills[i]); - if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; - } - - if (node.forbiddenSkills[skills[i]]) { - var forbidstr = '
                                    ' + translation + '
                                    '; - if (node.forbiddenSkills[skills[i]].length) { - forbidstr += '(与' + get.translation(node.forbiddenSkills[skills[i]]) + '冲突)
                                    '; - } - else { - forbidstr += '(双将禁用)
                                    '; - } - forbidstr += get.skillInfoTranslation(skills[i], node) + '
                                    '; - uiintro.add(forbidstr); - } - else if (!skills2.includes(skills[i])) { - if (lib.skill[skills[i]].preHidden && get.mode() == 'guozhan') { - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    预亮技能
                                    '); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (_status.prehidden_skills.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.hiddenskill); - } - else uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    '); - } - else if (lib.skill[skills[i]].temp || !node.skills.includes(skills[i]) || lib.skill[skills[i]].thundertext) { - if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    自动发动
                                    '); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (lib.skill[skills[i]].frequent) { - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - } - if (lib.skill[skills[i]].subfrequent) { - for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { - if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { - underlinenode.classList.remove('on'); - } - } - } - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.autoskill2); - } - else { - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    '); - } - } - else if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    自动发动
                                    '); - var underlinenode = uiintro.content.lastChild.querySelector('.underlinenode'); - if (lib.skill[skills[i]].frequent) { - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - } - if (lib.skill[skills[i]].subfrequent) { - for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { - if (lib.config.autoskilllist.includes(skills[i] + '_' + lib.skill[skills[i]].subfrequent[j])) { - underlinenode.classList.remove('on'); - } - } - } - if (lib.config.autoskilllist.includes(skills[i])) { - underlinenode.classList.remove('on'); - } - underlinenode.link = skills[i]; - underlinenode.listen(ui.click.autoskill2); - } - else if (lib.skill[skills[i]].clickable && node.isIn() && node.isUnderControl(true)) { - var intronode = uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    ').querySelector('.skillbutton'); - if (!_status.gameStarted || (lib.skill[skills[i]].clickableFilter && !lib.skill[skills[i]].clickableFilter(node))) { - intronode.classList.add('disabled'); - intronode.style.opacity = 0.5; - } - else { - intronode.link = node; - intronode.func = lib.skill[skills[i]].clickable; - intronode.classList.add('pointerdiv'); - intronode.listen(ui.click.skillbutton); - } - } - else { - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i], node) + '
                                    '); - } - if (lib.translate[skills[i] + '_append']) { - uiintro._place_text = uiintro.add('
                                    ' + lib.translate[skills[i] + '_append'] + '
                                    '); - } - } - } - // if(get.is.phoneLayout()){ - // var storage=node.storage; - // for(i in storage){ - // if(get.info(i)&&get.info(i).intro){ - // intro=get.info(i).intro; - // if(node.getSkills().concat(lib.skill.global).includes(i)==false&&!intro.show) continue; - // var name=intro.name?intro.name:get.translation(i); - // if(typeof name=='function'){ - // name=name(storage[i],node); - // } - // translation='
                                    『'+name.slice(0,2)+'』
                                    '; - // var stint=get.storageintro(intro.content,storage[i],node,null,i); - // if(stint){ - // translation+=stint+'
                                    '; - // uiintro.add(translation); - // } - // } - // } - // } - - if (lib.config.right_range && _status.gameStarted) { - uiintro.add(ui.create.div('.placeholder')); - var table, tr, td; - table = document.createElement('table'); - tr = document.createElement('tr'); - table.appendChild(tr); - td = document.createElement('td'); - td.innerHTML = '距离'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '手牌'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '行动'; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = '伤害'; - tr.appendChild(td); - - tr = document.createElement('tr'); - table.appendChild(tr); - td = document.createElement('td'); - if (node == game.me || !game.me || !game.me.isIn()) { - td.innerHTML = '-'; - } - else { - var dist1 = get.numStr(Math.max(1, game.me.distanceTo(node))); - var dist2 = get.numStr(Math.max(1, node.distanceTo(game.me))); - if (dist1 == dist2) { - td.innerHTML = dist1; - } - else { - td.innerHTML = dist1 + '/' + dist2; - } - } - tr.appendChild(td); - td = document.createElement('td'); - let handcardLimit = node.getHandcardLimit(); - td.innerHTML = `${node.countCards('h')}/${handcardLimit >= 114514 ? '∞' : handcardLimit}`; - tr.appendChild(td); - td = document.createElement('td'); - td.innerHTML = node.phaseNumber; - tr.appendChild(td); - td = document.createElement('td'); - - (function () { - num = 0; - for (var j = 0; j < node.stat.length; j++) { - if (typeof node.stat[j].damage == 'number') num += node.stat[j].damage; - } - td.innerHTML = num; - }()); - tr.appendChild(td); - table.style.width = 'calc(100% - 20px)'; - table.style.marginLeft = '10px'; - - uiintro.content.appendChild(table); - if (!lib.config.show_favourite) { - table.style.paddingBottom = '5px'; - } - } - if (!simple || get.is.phoneLayout()) { - var es = node.getCards('e'); - for (var i = 0; i < es.length; i++) { - var cardinfo = lib.card[es[i].name]; - if (cardinfo && cardinfo.cardPrompt) uiintro.add('
                                    ' + es[i].outerHTML + '
                                    ' + cardinfo.cardPrompt(es[i]) + '
                                    '); - else uiintro.add('
                                    ' + es[i].outerHTML + '
                                    ' + lib.translate[es[i].name + '_info'] + '
                                    '); - uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; - - if (lib.translate[es[i].name + '_append']) { - uiintro.add('
                                    ' + lib.translate[es[i].name + '_append'] + '
                                    '); - } - } - var js = node.getCards('j'); - for (var i = 0; i < js.length; i++) { - if (js[i].viewAs && js[i].viewAs != js[i].name) { - let html = js[i].outerHTML; - let cardInfo = lib.card[js[i].viewAs], showCardIntro=true; - if (cardInfo.blankCard) { - var cardOwner = get.owner(js[i]); - if (cardOwner && !cardOwner.isUnderControl(true)) showCardIntro = false; - } - if (!showCardIntro) { - html=ui.create.button(js[i],'blank').outerHTML; - } - uiintro.add('
                                    ' + html + '
                                    ' + lib.translate[js[i].viewAs] + ':' + lib.translate[js[i].viewAs + '_info'] + '
                                    '); - } - else { - uiintro.add('
                                    ' + js[i].outerHTML + '
                                    ' + lib.translate[js[i].name + '_info'] + '
                                    '); - } - uiintro.content.lastChild.querySelector('.skill>.card').style.transform = ''; - } - if (get.is.phoneLayout()) { - var markCoutainer = ui.create.div('.mark-container.marks'); - for (var i in node.marks) { - var nodemark = node.marks[i].cloneNode(true); - nodemark.classList.add('pointerdiv'); - nodemark.link = node.marks[i]; - nodemark.style.transform = ''; - markCoutainer.appendChild(nodemark); - nodemark.listen(function () { - uiintro.noresume = true; - var rect = this.link.getBoundingClientRect(); - ui.click.intro.call(this.link, { - clientX: rect.left + rect.width, - clientY: rect.top + rect.height / 2, - }); - if (lib.config.touchscreen) { - uiintro._close(); - } - }); - } - if (markCoutainer.childElementCount) { - uiintro.addText('标记'); - uiintro.add(markCoutainer); - } - } - } - if (!game.observe && _status.gameStarted && game.me && node != game.me) { - ui.throwEmotion = []; - uiintro.addText('发送交互表情'); - var click = function () { - if (_status.dragged) return; - if (_status.justdragged) return; - if (_status.throwEmotionWait) return; - var emotion = this.link; - if (game.online) { - game.send('throwEmotion', node, emotion); - } - else game.me.throwEmotion(node, emotion); - uiintro._close(); - _status.throwEmotionWait = true; - setTimeout(function () { - _status.throwEmotionWait = false; - if (ui.throwEmotion) { - for (var i of ui.throwEmotion) i.classList.remove('exclude'); - } - }, (emotion == 'flower' || emotion == 'egg') ? 500 : 5000); - }; - var td; - var table = document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin = '0'; - table.style.width = '100%'; - table.style.position = 'relative'; - var listi = ['flower', 'egg']; - for (var i = 0; i < listi.length; i++) { - td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); - ui.throwEmotion.add(td); - if (_status.throwEmotionWait) td.classList.add('exclude'); - td.link = listi[i]; - table.appendChild(td); - td.innerHTML = '' + get.translation(listi[i]) + ''; - td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); - } - uiintro.content.appendChild(table); - table = document.createElement('div'); - table.classList.add('add-setting'); - table.style.margin = '0'; - table.style.width = '100%'; - table.style.position = 'relative'; - var listi = ['wine', 'shoe']; - if (game.me.storage.zhuSkill_shanli) listi = ['yuxisx', 'jiasuo']; - for (var i = 0; i < listi.length; i++) { - td = ui.create.div('.menubutton.reduce_radius.pointerdiv.tdnode'); - ui.throwEmotion.add(td); - if (_status.throwEmotionWait) td.classList.add('exclude'); - td.link = listi[i]; - table.appendChild(td); - td.innerHTML = '' + get.translation(listi[i]) + ''; - td.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', click); - } - uiintro.content.appendChild(table); - } - var modepack = lib.characterPack['mode_' + get.mode()]; - if (lib.config.show_favourite && lib.character[node.name] && game.players.includes(node) && - (!modepack || !modepack[node.name]) && (!simple || get.is.phoneLayout())) { - var addFavourite = ui.create.div('.text.center.pointerdiv'); - addFavourite.link = node.name; - if (lib.config.favouriteCharacter.includes(node.name)) { - addFavourite.innerHTML = '移除收藏'; - } - else { - addFavourite.innerHTML = '添加收藏'; - } - addFavourite.listen(ui.click.favouriteCharacter); - uiintro.add(addFavourite); - } - if (!simple || get.is.phoneLayout()) { - if ((lib.config.change_skin || lib.skin) && !node.isUnseen()) { - var num = 1; - var introadded = false; - var createButtons = function (num, avatar2) { - if (!introadded) { - introadded = true; - uiintro.add('
                                    更改皮肤
                                    '); - } - var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); - lib.setMousewheel(buttons); - var nameskin = (avatar2 ? node.name2 : node.name1); - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - for (var i = 0; i <= num; i++) { - var button = ui.create.div('.button.character.pointerdiv', buttons, function () { - if (this._link) { - if (avatar2) { - lib.config.skin[nameskin] = this._link; - node.node.avatar2.style.backgroundImage = this.style.backgroundImage; - } - else { - lib.config.skin[nameskin] = this._link; - node.node.avatar.style.backgroundImage = this.style.backgroundImage; - } - } - else { - delete lib.config.skin[nameskin]; - if (avatar2) { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar2.setBackground(nameskin2, 'character'); - else node.node.avatar2.setBackground(nameskin, 'character'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.node.avatar.setBackground(nameskin2, 'character'); - else node.node.avatar.setBackground(nameskin, 'character'); - } - } - game.saveConfig('skin', lib.config.skin); - }); - button._link = i; - if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); - } - } - uiintro.add(buttons); - }; - var loadImage = function (avatar2) { - var img = new Image(); - img.onload = function () { - num++; - loadImage(avatar2); - }; - img.onerror = function () { - num--; - if (num) { - createButtons(num, avatar2); - } - if (!avatar2) { - if (!node.classList.contains('unseen2') && node.name2) { - num = 1; - loadImage(true); - } - } - }; - var nameskin = (avatar2 ? node.name2 : node.name1); - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; - }; - if (lib.config.change_skin) { - if (!node.isUnseen(0)) { - loadImage(); - } - else if (node.name2) { - loadImage(true); - } - } - else { - setTimeout(function () { - var nameskin1 = node.name1; - var nameskin2 = node.name2; - if (nameskin1 && nameskin1.startsWith('gz_')) { - nameskin1 = nameskin1.slice(3); - } - if (nameskin2 && nameskin2.startsWith('gz_')) { - nameskin2 = nameskin2.slice(3); - } - if (!node.isUnseen(0) && lib.skin[nameskin1]) { - createButtons(lib.skin[nameskin1]); - } - if (!node.isUnseen(1) && lib.skin[nameskin2]) { - createButtons(lib.skin[nameskin2], true); - } - }); - } - } - } - - uiintro.add(ui.create.div('.placeholder.slim')); - } - else if (node.classList.contains('mark') && node.info && - node.parentNode && node.parentNode.parentNode && node.parentNode.parentNode.classList.contains('player')) { - var info = node.info; - var player = node.parentNode.parentNode; - if (info.name) { - if (typeof info.name == 'function') { - var named = info.name(player.storage[node.skill], player); - if (named) { - uiintro.add(named); - } - } - else { - uiintro.add(info.name); - } - } - else if (info.name !== false) { - uiintro.add(get.translation(node.skill)); - } - if (typeof info.id == 'string' && info.id.startsWith('subplayer') && - player.isUnderControl(true) && player.storage[info.id] && !_status.video) { - var storage = player.storage[info.id]; - uiintro.addText('当前体力:' + storage.hp + '/' + storage.maxHp); - if (storage.hs.length) { - uiintro.addText('手牌区'); - uiintro.addSmall(storage.hs); - } - if (storage.es.length) { - uiintro.addText('装备区'); - uiintro.addSmall(storage.es); - } - } - if (typeof info.mark == 'function') { - var stint = info.mark(uiintro, player.storage[node.skill], player); - if (stint) { - var placetext = uiintro.add('
                                    ' + stint + '
                                    '); - if (!stint.startsWith('
                                    '+stint+'
                                    '); - // } - // else{ - // uiintro.add('
                                    '+stint+'
                                    '); - // } - } - } - else { - var stint = get.storageintro(info.content, player.storage[node.skill], player, uiintro, node.skill); - if (stint) { - if (stint[0] == '@') { - uiintro.add('
                                    ' + stint.slice(1) + '
                                    '); - } - else { - var placetext = uiintro.add('
                                    ' + stint + '
                                    '); - if (!stint.startsWith('
                                    '+stint+'
                                    '); - // } - // else{ - // uiintro.add('
                                    '+stint+'
                                    '); - // } - } - } - uiintro.add(ui.create.div('.placeholder.slim')); - } - else if (node.classList.contains('card')) { - //卡牌长按介绍 - if (ui.arena.classList.contains('observe') && node.parentNode.classList.contains('handcards')) { - return; - } - var name = node.name; - if (node.parentNode.cardMod) { - var moded = false; - for (var i in node.parentNode.cardMod) { - var item = node.parentNode.cardMod[i](node); - if (Array.isArray(item)) { - moded = true; - uiintro.add(item[0]); - uiintro._place_text = uiintro.add('
                                    ' + item[1] + '
                                    '); - } - } - if (moded) return uiintro; - } - if (node.link && node.link.name && lib.card[node.link.name]) { - name = node.link.name; - } - if (get.position(node) == 'j' && node.viewAs && node.viewAs != name) { - uiintro.add(get.translation(node.viewAs)); - var cardInfo = lib.card[node.viewAs], showCardIntro=true; - if (cardInfo.blankCard) { - var cardOwner = get.owner(node); - if (cardOwner && !cardOwner.isUnderControl(true)) showCardIntro = false; - } - if (showCardIntro) uiintro.add('
                                    (' + get.translation(get.translation(node)) + ')
                                    '); - // uiintro.add(get.translation(node.viewAs)+'
                                    ('+get.translation(node)+')
                                    '); - uiintro.nosub = true; - name = node.viewAs; - } - else { - uiintro.add(get.translation(node)); - } - if (node._banning) { - var clickBanned = function () { - var banned = lib.config[this.bannedname] || []; - if (banned.includes(name)) { - banned.remove(name); - } - else { - banned.push(name); - } - game.saveConfig(this.bannedname, banned); - this.classList.toggle('on'); - if (node.updateBanned) { - node.updateBanned(); - } - }; - var modeorder = lib.config.modeorder || []; - for (var i in lib.mode) { - modeorder.add(i); - } - var list = []; - uiintro.contentContainer.listen(function (e) { - ui.click.touchpop(); - e.stopPropagation(); - }); - for (var i = 0; i < modeorder.length; i++) { - if (node._banning == 'online') { - if (!lib.mode[modeorder[i]].connect) continue; - } - else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { - continue; - } - if (lib.config.all.mode.includes(modeorder[i])) { - list.push(modeorder[i]); - } - } - if (lib.card[name] && lib.card[name].type == 'trick') list.push('zhinang_tricks'); - var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); - var banall = false; - for (var i = 0; i < list.length; i++) { - var cfg = ui.create.div('.config', list[i] == 'zhinang_tricks' ? '设为智囊' : (lib.translate[list[i]] + '模式'), page); - cfg.classList.add('toggle'); - if (list[i] == 'zhinang_tricks') { - cfg.bannedname = ((node._banning == 'offline') ? '' : 'connect_') + 'zhinang_tricks'; - } - else if (node._banning == 'offline') { - cfg.bannedname = list[i] + '_bannedcards'; - } - else { - cfg.bannedname = 'connect_' + list[i] + '_bannedcards'; - } - cfg.listen(clickBanned); - ui.create.div(ui.create.div(cfg)); - var banned = lib.config[cfg.bannedname] || []; - if (banned.includes(name) == (list[i] == 'zhinang_tricks')) { - cfg.classList.add('on'); - banall = true; - } - } - ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { - if (this.innerHTML == '全部禁用') { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部启用'; - } - else { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname.indexOf('zhinang_tricks') == -1 && page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部禁用'; - } - }).style.marginTop = '-10px'; - ui.create.div('.placeholder.slim', uiintro.content); - } - else { - if (lib.translate[name + '_info']) { - if (!uiintro.nosub) { - if (lib.card[name] && lib.card[name].derivation) { - if (typeof lib.card[name].derivation == 'string') { - uiintro.add('
                                    来源:' + get.translation(lib.card[name].derivation) + '
                                    '); - } - else if (lib.card[name].derivationpack) { - uiintro.add('
                                    来源:' + get.translation(lib.card[name].derivationpack + '_card_config') + '包
                                    '); - } - } - let typeinfo = ''; - if (lib.card[name] && lib.card[name].unique) { - typeinfo += ('特殊' + get.translation(lib.card[name].type) + '牌'); - } - else if (lib.card[name] && lib.card[name].type && lib.translate[lib.card[name].type]) { - typeinfo += (get.translation(lib.card[name].type) + '牌'); - } - if (get.subtype(name, false)) { - typeinfo += ('-' + get.translation(get.subtype(name, false))); - } - if (typeinfo) { - uiintro.add('
                                    ' + typeinfo + '
                                    '); - } - if (lib.card[name].unique && lib.card[name].type == 'equip') { - if (lib.cardPile.guozhan && lib.cardPack.guozhan.includes(name)) { - uiintro.add('
                                    专属装备
                                    ').style.marginTop = '-5px'; - } - else { - uiintro.add('
                                    特殊装备
                                    ').style.marginTop = '-5px'; - } - } - if (lib.card[name] && lib.card[name].addinfomenu) { - uiintro.add('
                                    ' + lib.card[name].addinfomenu + '
                                    '); - } - if (get.subtype(name, false) == 'equip1') { - var added = false; - if (lib.card[node.name] && lib.card[node.name].distance) { - var dist = lib.card[node.name].distance; - if (dist.attackFrom) { - added = true; - uiintro.add('
                                    攻击范围:' + (-dist.attackFrom + 1) + '
                                    '); - } - } - if (!added) { - uiintro.add('
                                    攻击范围:1
                                    '); - } - } - } - if (lib.card[name].cardPrompt) { - var str = lib.card[name].cardPrompt(node.link || node), placetext = uiintro.add('
                                    ' + str + '
                                    '); - if (!str.startsWith('
                                    ' + lib.translate[name + '_info'] + '
                                    '); - if (!lib.translate[name + '_info'].startsWith('
                                    应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(';')}
                                    `); - } - if (lib.translate[name + '_append']) { - uiintro.add('
                                    ' + lib.translate[name + '_append'] + '
                                    '); - } - } - uiintro.add(ui.create.div('.placeholder.slim')); - } - } - else if (node.classList.contains('character')) { - const character = node.link, characterInfo = get.character(node.link); - let capt = get.translation(character); - if (characterInfo) { - const infoSex = characterInfo[0]; - if (infoSex && lib.config.show_sex) capt += `  ${infoSex == 'none' ? '无' : lib.translate[infoSex]}`; - const infoGroup = characterInfo[1]; - if (infoGroup && lib.config.show_group) { - const group = get.is.double(character, true); - if (group) capt += `  ${group.map(value => get.translation(value)).join('/')}`; - else capt += `  ${lib.translate[infoGroup]}`; - } - } - uiintro.add(capt); - - if (lib.characterTitle[node.link]) { - uiintro.addText(get.colorspan(lib.characterTitle[node.link])); - } - - if (get.characterInitFilter(node.link)) { - const initFilters = get.characterInitFilter(node.link).filter(tag => { - if (!lib.characterInitFilter[node.link]) return true; - return lib.characterInitFilter[node.link](tag) !== false; - }); - if(initFilters.length){ - const str = initFilters.reduce((strx, stry) => strx + lib.InitFilter[stry] + '
                                    ', '').slice(0, -4); - uiintro.addText(str); - } - } - - if (node._banning) { - var clickBanned = function () { - var banned = lib.config[this.bannedname] || []; - if (banned.includes(character)) { - banned.remove(character); - } - else { - banned.push(character); - } - game.saveConfig(this.bannedname, banned); - this.classList.toggle('on'); - if (node.updateBanned) { - node.updateBanned(); - } - }; - var modeorder = lib.config.modeorder || []; - for (var i in lib.mode) { - modeorder.add(i); - } - var list = []; - uiintro.contentContainer.listen(function (e) { - ui.click.touchpop(); - e.stopPropagation(); - }); - for (var i = 0; i < modeorder.length; i++) { - if (node._banning == 'online') { - if (!lib.mode[modeorder[i]].connect) continue; - if (!lib.config['connect_' + modeorder[i] + '_banned']) { - lib.config['connect_' + modeorder[i] + '_banned'] = []; - } - } - else if (modeorder[i] == 'connect' || modeorder[i] == 'brawl') { - continue; - } - if (lib.config.all.mode.includes(modeorder[i])) { - list.push(modeorder[i]); - } - } - var page = ui.create.div('.menu-buttons.configpopped', uiintro.content); - var banall = false; - for (var i = 0; i < list.length; i++) { - var cfg = ui.create.div('.config', lib.translate[list[i]] + '模式', page); - cfg.classList.add('toggle'); - if (node._banning == 'offline') { - cfg.bannedname = list[i] + '_banned'; - } - else { - cfg.bannedname = 'connect_' + list[i] + '_banned'; - } - cfg.listen(clickBanned); - ui.create.div(ui.create.div(cfg)); - var banned = lib.config[cfg.bannedname] || []; - if (!banned.includes(character)) { - cfg.classList.add('on'); - banall = true; - } - } - if (node._banning == 'offline') { - var cfg = ui.create.div('.config', '随机选将可用', page); - cfg.classList.add('toggle'); - cfg.listen(function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - lib.config.forbidai_user.remove(character); - } - else { - lib.config.forbidai_user.add(character); - } - game.saveConfig('forbidai_user', lib.config.forbidai_user); - }); - ui.create.div(ui.create.div(cfg)); - if (!lib.config.forbidai_user.includes(character)) { - cfg.classList.add('on'); - } - } - ui.create.div('.menubutton.pointerdiv', banall ? '全部禁用' : '全部启用', uiintro.content, function () { - if (this.innerHTML == '全部禁用') { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname && page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部启用'; - } - else { - for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].bannedname && !page.childNodes[i].classList.contains('on')) { - clickBanned.call(page.childNodes[i]); - } - } - this.innerHTML = '全部禁用'; - } - }).style.marginTop = '-10px'; - ui.create.div('.placeholder.slim', uiintro.content); - } - else { - var infoitem = get.character(character); - var skills = infoitem[3]; - for (i = 0; i < skills.length; i++) { - if (lib.translate[skills[i] + '_info']) { - if (lib.translate[skills[i] + '_ab']) translation = lib.translate[skills[i] + '_ab']; - else { - translation = get.translation(skills[i]); - if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; - } - - uiintro.add('
                                    ' + translation + '
                                    ' + get.skillInfoTranslation(skills[i]) + '
                                    '); - - if (lib.translate[skills[i] + '_append']) { - uiintro._place_text = uiintro.add('
                                    ' + lib.translate[skills[i] + '_append'] + '
                                    '); - } - } - } - var modepack = lib.characterPack['mode_' + get.mode()]; - if (lib.config.show_favourite && - lib.character[node.link] && (!modepack || !modepack[node.link]) && (!simple || get.is.phoneLayout())) { - var addFavourite = ui.create.div('.text.center.pointerdiv'); - addFavourite.link = node.link; - addFavourite.style.marginBottom = '15px'; - if (lib.config.favouriteCharacter.includes(node.link)) { - addFavourite.innerHTML = '移除收藏'; - } - else { - addFavourite.innerHTML = '添加收藏'; - } - addFavourite.listen(ui.click.favouriteCharacter); - uiintro.add(addFavourite); - } - else { - uiintro.add(ui.create.div('.placeholder.slim')); - } - var addskin = false; - if (node.parentNode.classList.contains('menu-buttons')) { - addskin = !lib.config.show_charactercard; - } - else { - addskin = lib.config.change_skin || lib.skin; - } - if (addskin && (!simple || get.is.phoneLayout())) { - var num = 1; - var introadded = false; - var nameskin = node.link; - var nameskin2 = nameskin; - var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { - nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { - nameskin = nameskin.slice(3); - gzbool = true; - } - var createButtons = function (num) { - if (!num) return; - if (!introadded) { - introadded = true; - uiintro.add('
                                    更改皮肤
                                    '); - } - var buttons = ui.create.div('.buttons.smallzoom.scrollbuttons'); - lib.setMousewheel(buttons); - for (var i = 0; i <= num; i++) { - var button = ui.create.div('.button.character.pointerdiv', buttons, function () { - if (this._link) { - lib.config.skin[nameskin] = this._link; - node.style.backgroundImage = this.style.backgroundImage; - game.saveConfig('skin', lib.config.skin); - } - else { - delete lib.config.skin[nameskin]; - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) node.setBackground(nameskin2, 'character'); - else node.setBackground(nameskin, 'character'); - game.saveConfig('skin', lib.config.skin); - } - }); - button._link = i; - if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); - } - } - uiintro.add(buttons); - }; - var loadImage = function () { - var img = new Image(); - img.onload = function () { - num++; - loadImage(); - }; - img.onerror = function () { - num--; - createButtons(num); - }; - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; - }; - if (lib.config.change_skin) { - loadImage(); - } - else { - setTimeout(function () { - createButtons(lib.skin[nameskin]); - }); - } - } - } - } - else if (node.classList.contains('equips') && ui.arena.classList.contains('selecting')) { - (function () { - uiintro.add('选择装备'); - uiintro.addSmall(Array.from(node.childNodes).filter(node => !node.classList.contains('emptyequip') && !node.classList.contains('feichu')), true); - uiintro.clickintro = true; - ui.control.hide(); - uiintro._onclose = function () { - ui.control.show(); - }; - var confirmbutton; - for (var i = 0; i < uiintro.buttons.length; i++) { - var button = uiintro.buttons[i]; - button.classList.add('pointerdiv'); - if (button.link.classList.contains('selected')) { - button.classList.add('selected'); - } - button.listen(function (e) { - ui.click.card.call(this.link, 'popequip'); - ui.click.window.call(ui.window, e); - if (this.link.classList.contains('selected')) { - this.classList.add('selected'); - } - else { - this.classList.remove('selected'); - } - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - confirmbutton.classList.remove('disabled'); - } - else { - confirmbutton.classList.add('disabled'); - } - }); - } - var buttoncontainer = uiintro.add(ui.create.div()); - buttoncontainer.style.display = 'block'; - confirmbutton = ui.create.div('.menubutton.large.pointerdiv', '确定', function () { - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - uiintro._clickintro(); - ui.click.ok(ui.confirm.firstChild); - } - }, buttoncontainer); - confirmbutton.style.position = 'relative'; - setTimeout(function () { - if (ui.confirm && ui.confirm.str && ui.confirm.str.includes('o')) { - confirmbutton.classList.remove('disabled'); - } - else { - confirmbutton.classList.add('disabled'); - } - }, 300); - }()); - } - else if (node.classList.contains('identity') && node.dataset.career) { - var career = node.dataset.career; - uiintro.add(get.translation(career)); - uiintro.add('
                                    ' + lib.translate['_' + career + '_skill_info'] + '
                                    '); - } - else if (node.classList.contains('skillbar')) { - if (node == ui.friendBar) { - uiintro.add('友方怒气值'); - uiintro.add('
                                    ' + _status.friendRage + '/100
                                    '); - } - else if (node == ui.enemyBar) { - uiintro.add('敌方怒气值'); - uiintro.add('
                                    ' + _status.enemyRage + '/100
                                    '); - } - } - else if (node.parentNode == ui.historybar) { - if (node.dead) { - if (!node.source || node.source == node.player) { - uiintro.add('
                                    ' + get.translation(node.player) + '阵亡
                                    '); - uiintro.addSmall([node.player]); - } - else { - uiintro.add('
                                    ' + get.translation(node.player) + '被' + get.translation(node.source) + '杀害
                                    '); - uiintro.addSmall([node.source]); - } - } - if (node.skill) { - uiintro.add('
                                    ' + get.translation(node.skill, 'skill') + '
                                    '); - uiintro._place_text = uiintro.add('
                                    ' + get.translation(node.skill, 'info') + '
                                    '); - } - if (node.targets && get.itemtype(node.targets) == 'players') { - uiintro.add('
                                    目标
                                    '); - uiintro.addSmall(node.targets); - } - if (node.players && node.players.length > 1) { - uiintro.add('
                                    使用者
                                    '); - uiintro.addSmall(node.players); - } - if (node.cards && node.cards.length) { - uiintro.add('
                                    卡牌
                                    '); - uiintro.addSmall(node.cards); - } - for (var i = 0; i < node.added.length; i++) { - uiintro.add(node.added[i]); - } - if (node.added.length) { - uiintro.add(ui.create.div('.placeholder.slim')); - } - if (uiintro.content.firstChild) { - uiintro.content.firstChild.style.paddingTop = '3px'; - } - } - if (lib.config.touchscreen) { - lib.setScroll(uiintro.contentContainer); - } - return uiintro; - } - static linkintro(dialog, content, player) { - dialog.content.firstChild.remove(); - dialog.add('
                                    已横置
                                    '); - var list = []; - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isLinked() && game.players[i].name && !game.players[i].name.startsWith('unknown')) { - list.push(game.players[i]); - } - } - if (list.length) { - dialog.add(list, true, true); - } - } - static groups() { return ['wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key']; } - static types() { - var types = []; - for (var i in lib.card) { - if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) continue; - if (lib.card[i].forbid && lib.card[i].forbid.includes(lib.config.mode)) continue; - if (lib.card[i].type) { - if (lib.card[i].type == 'delay') types.add('trick'); - else types.add(lib.card[i].type); - } - } - return types; - } - static links(buttons) { - var links = []; - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].link != undefined) links.push(buttons[i].link); - } - return links; - } - static threaten(target, player, hp) { - var threaten = 1; - var skills = target.getSkills(); - if (!player && player !== false) { - player = _status.event.player; - } - for (var i = 0; i < skills.length; i++) { - var info = get.info(skills[i]); - if (info && info.ai && info.ai.threaten) { - if (typeof info.ai.threaten == 'function' && player) { - var tmp = info.ai.threaten(player, target); - if (typeof tmp == 'number') { - threaten *= tmp; - } - } - else if (typeof info.ai.threaten == 'number') { - threaten *= info.ai.threaten; - } - } - } - if (hp) { - switch (target.hp) { - case 0: threaten *= 1.5; break; - case 1: threaten *= 1.2; break; - } - switch (target.countCards('h')) { - case 0: threaten *= 1.5; break; - case 1: threaten *= 1.2; break; - } - } - return threaten; - } - static condition(player) { - var num = player.hp; - if (num > 4) { - num = 4 + Math.sqrt(num - 4); - } - else { - if (player.isHealthy()) { - if (player.hp == 3) { - num += 0.5; - } - else if (player.hp < 3) { - num++; - } - } - } - num += player.countCards('h') / 2; - var es = player.getCards('e'); - for (var i = 0; i < es.length; i++) { - var val = get.equipValueNumber(es[i]); - if (val >= 7) num += 0.8; - if (val >= 5) num += 0.5; - if (val >= 3) num += 0.2; - } - return num; - } - static attitude(from, to) { - if (!from || !to) return 0; - from = from._trueMe || from; - arguments[0] = from; - var att = CacheContext.requireCacheContext().get.rawAttitude.apply(this, arguments); - if (from.isMad()) att = -att; - if (to.isMad() && att > 0) { - if (to.identity == 'zhu') { - att = 1; - } - else { - att = 0; - } - } - if (!_status.tempnofake) { - _status.tempnofake = true; - if (from.ai.modAttitudeFrom) { - att = from.ai.modAttitudeFrom(from, to, att); - } - if (to.ai.modAttitudeTo) { - att = to.ai.modAttitudeTo(from, to, att); - } - delete _status.tempnofake; - } - return att; - } - static sgnAttitude() { - return get.sgn(get.attitude.apply(this, arguments)); - } - static useful_raw(card, player) { - if (get.position(card) == 'j') return -1; - if (get.position(card) == 'e') return get.equipValue(card); - if (card._modUseful) { - return card._modUseful(); - } - var i = 0; - if (!player) player = _status.event.player; - if (player) { - if (_status.event.useCache) { - i = game.callFuncUseStepCache("player.getCardsInUseful", function (player, position, cardname) { - return player.getCards(position, cardname); - }, [player, 'h', card.name]).indexOf(card); - } else { - i = player.getCards('h', card.name).indexOf(card); - } - if (i < 0) i = 0; - } - var aii = get.info(card).ai; - var useful; - if (aii && aii.useful) useful = aii.useful; - else if (aii && aii.basic) useful = aii.basic.useful; - var result; - if (useful == undefined) result = -1; - else if (typeof useful == 'function') { - result = useful(card, i); - } - else if (typeof useful == 'number') result = useful; - else if (i < useful.length) { - result = useful[i]; - } - else result = useful[useful.length - 1]; - result = game.checkMod(player, card, result, 'aiUseful', player); - return result; - } - static useful(card, player) { - if (_status.event.useCache) { - return game.callFuncUseStepCache("get.useful_raw", get.useful_raw, [card, player]); - } - return get.useful_raw(card, player); - } - static unuseful(card) { return -get.useful(card); } - static unuseful2(card) { return 10 - get.useful(card); } - static unuseful3(card) { - if (card.name == 'du') return 20; - return 10 - get.useful(card); - } - static value(card, player, method) { - var result = 0; - var value; - if (Array.isArray(card)) { - if (!card.length) return 0; - value = 0; - for (var i = 0; i < card.length; i++) { - value += get.value(card[i], player, method); - } - return value / Math.sqrt(card.length); - } - if (card._modValue) { - return card._modValue(player, method); - } - var aii = get.info(card).ai; - if (aii && aii.value) value = aii.value; - else if (aii && aii.basic) value = aii.basic.value; - if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; - var geti = function () { - return player.getCardIndex('hs',card.name,card,5); - }; - if (typeof value == 'function') { - result = value(card, player, geti(), method); - } - if (typeof value == 'number') result = value; - if (Array.isArray(value)) { - if (method == 'raw') result = value[0]; - var num = geti(); - if (num < value.length) result = value[Math.max(0,num)]; - else result = value[value.length - 1]; - } - result = game.checkMod(player, card, result, 'aiValue', player); - return result; - } - static equipResult(player, target, name) { - var card = get.card(); - if (!card || card.name != name) { - card = { name: name }; - } - var value1 = get.equipValue(card, target); - var value2 = 0; - if (!player.canEquip(card)) { - if (!player.canEquip(card, true)) return 0; - var current = target.getEquip(card); - if (current && current != card) { - value2 = get.equipValue(current, target); - if (value2 > 0 && !target.needsToDiscard() && !get.tag(card, 'valueswap')) { - return 0; - } - } - } - return Math.max(0, value1 - value2) / 5; - } - static equipValue(card, player) { - if (player == undefined || get.itemtype(player) != 'player') player = get.owner(card); - if (player == undefined || get.itemtype(player) != 'player') player = _status.event.player; - var info = get.info(card); - if (!info.ai) return 0; - var value = info.ai.equipValue; - if (value == undefined) { - if (info.ai.basic && info.ai.basic.equipValue != undefined) { - value = info.ai.basic.equipValue; - } - else return 0; - } - if (typeof value == 'number') return value; - if (typeof value == 'function') return value(card, player, null, 'raw2'); - return 0; - } - static equipValueNumber(card) { - var info = get.info(card); - if (info.ai) { - if (typeof info.ai.equipValue == 'number') return info.ai.equipValue; - if (info.ai.basic && typeof info.ai.basic.equipValue == 'number') return info.ai.basic.equipValue; - } - return 0; - } - static disvalue(card, player) { return -get.value(card, player); } - static disvalue2(card, player) { return -get.value(card, player, 'raw'); } - static skillthreaten(skill, player, target) { - if (!lib.skill[skill]) return 1; - if (!lib.skill[skill].ai) return 1; - var threaten = lib.skill[skill].ai.threaten; - if (typeof threaten == 'number') return threaten; - if (typeof threaten == 'function') { - player = player || _status.event.player; - target = target || player; - return threaten(player, target); - } - return 1; - } - static cacheOrder(item){ - let cache = CacheContext.requireCacheContext(); - return cache.get.order(item); - } - /** - * @returns { number } - */ - static order(item, player = get.player() || game.me) { - let cache = CacheContext.requireCacheContext(); - var info = get.info(item); - if (!info) return -1; - var aii = info.ai; - var order; - if (aii && aii.order) order = aii.order; - else if (aii && aii.basic) order = aii.basic.order; - if (order == undefined) return -1; - var num = order; - if (typeof (order) == 'function') { - num = order(item, player); - } - if (typeof item == 'object' && player) { - num = game.checkMod(player, item, num, 'aiOrder', player); - } - return num; - } - static result(item, skill) { - var result; - var info = get.info(item); - if (info.ai) result = get.copy(info.ai.result); - if (typeof (result) == 'function') result = result(item); - if (!result) result = {}; - if (skill) { - var info2 = get.info(skill); - if (info2.ai) { - info2 = info2.ai.result; - for (var i in info2) { - result[i] = info2[i]; - } - } - } - return result; - } - static cacheEffectUse(target, card, player, player2, isLink){ - let cache = CacheContext.requireCacheContext(); - return cache.get.effect_use(target,card,player,player2,isLink); - } - static effect_use(target, card, player, player2, isLink) { - let cache = CacheContext.requireCacheContext(); - var event = _status.event; - var eventskill = null; - if (player == undefined) player = _status.event.player; - if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); - if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { - var skillinfo = get.info(event.skill); - if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; - else { - card = get.card(); - if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { - eventskill = event.skill; - } - } - } - var info = get.info(card); - if (typeof card == 'object' && info && info.changeTarget) { - var targets = [target]; - info.changeTarget(player, targets); - var eff = 0; - for (var i of targets) { - eff += cache.get.effect(i, card, player, player2, isLink); - } - return eff; - } - var result = get.result(card, eventskill); - var result1 = result.player_use || result.player, result2 = result.target_use || result.target; - if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); - if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); - - if (typeof result1 != 'number') result1 = 0; - if (typeof result2 != 'number') result2 = 0; - var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; - var skills1 = player.getSkills().concat(lib.skill.global); - game.expandSkills(skills1); - var zerotarget = false, zeroplayer = false; - for (var i = 0; i < skills1.length; i++) { - temp1 = get.info(skills1[i]).ai; - if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player_use == 'function') { - temp1 = cache.delegate(temp1.effect).player_use(card, player, target, result1, isLink); - } - else if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { - temp1 = cache.delegate(temp1.effect).player(card, player, target, result1, isLink); - } - else temp1 = undefined; - if (typeof temp1 == 'object') { - if (temp1.length == 2 || temp1.length == 4) { - result1 *= temp1[0]; - temp01 += temp1[1]; - } - if (temp1.length == 4) { - result2 *= temp1[2]; - temp02 += temp1[3]; - } - } - else if (typeof temp1 == 'number') { - result1 *= temp1; - } - else if (temp1 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp1 == 'zerotarget') { - zerotarget = true; - } - else if (temp1 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - } - if (target) { - var skills2 = target.getSkills().concat(lib.skill.global); - game.expandSkills(skills2); - for (var i = 0; i < skills2.length; i++) { - temp2 = get.info(skills2[i]).ai; - if (temp2 && temp2.threaten) temp3 = temp2.threaten; - else temp3 = undefined; - if (temp2 && typeof temp2.effect == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target_use == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = cache.delegate(temp2.effect).target_use(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); - else temp2 = undefined; - } - else temp2 = undefined; - if (typeof temp2 == 'object') { - if (temp2.length == 2 || temp2.length == 4) { - result2 *= temp2[0]; - temp02 += temp2[1]; - } - if (temp2.length == 4) { - result1 *= temp2[2]; - temp01 += temp2[3]; - } - } - else if (typeof temp2 == 'number') { - result2 *= temp2; - } - else if (temp2 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp2 == 'zerotarget') { - zerotarget = true; - } - else if (temp2 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - if (typeof temp3 == 'object') { - temp3 = temp3.target; - } - if (typeof temp3 == 'function') { - temp3 = temp3(player, target); - } - if (typeof temp3 == 'number') { - threaten *= temp3; - } - } - result2 += temp02; - result1 += temp01; - if (typeof card == 'object' && !result.ignoreStatus) { - if (cache.get.attitude(player, target) < 0) { - result2 *= Math.sqrt(threaten); - } - else { - result2 *= Math.sqrt(Math.sqrt(threaten)); - } - if (target.hp == 1) result2 *= 2.5; - if (target.hp == 2) result2 *= 1.8; - let countTargetCards = target.countCards('h'); - if (countTargetCards == 0) { - if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { - result2 *= 1.7; - } - else { - result2 *= 1.5; - } - }else if (countTargetCards == 1) result2 *= 1.3; - else if (countTargetCards == 2) result2 *= 1.1; - else if (countTargetCards >= 3) result2 *= 0.5; - - if (target.hp == 4) result2 *= 0.9; - else if (target.hp == 5) result2 *= 0.8; - else if (target.hp > 5) result2 *= 0.6; - } - } - else { - result2 += temp02; - result1 += temp01; - } - if (zeroplayer) result1 = 0; - if (zerotarget) result2 = 0; - var final = 0; - if (player2) { - final = (result1 * cache.get.attitude(player2, player) + (target ? result2 * cache.get.attitude(player2, target) : 0)); - } - else final = (result1 * cache.get.attitude(player, player) + (target ? result2 * cache.get.attitude(player, target) : 0)); - if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { - var info = get.info(card); - if (!info || !info.ai || !info.ai.canLink) { - if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); - }); - } - else if (info.ai.canLink(player, target, card)) { - game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); - }); - } - } - return final; - } - static cacheEffect(target, card, player, player2, isLink){ - let cache = CacheContext.requireCacheContext(); - return cache.get.effect(target,card,player,player2,isLink); - } - static effect(target, card, player, player2, isLink) { - let cache = CacheContext.requireCacheContext(); - var event = _status.event; - var eventskill = null; - if (player == undefined) player = _status.event.player; - if (card && typeof card == 'object' && 'name' in card) card = get.autoViewAs(card); - if (typeof card != 'string' && (typeof card != 'object' || !card.name)) { - var skillinfo = get.info(event.skill); - if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; - else { - card = get.card(); - if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { - eventskill = event.skill; - } - } - } - var result = get.result(card, eventskill); - var result1 = result.player, result2 = result.target; - if (typeof result1 == 'function') result1 = result1(player, target, card, isLink); - if (typeof result2 == 'function') result2 = result2(player, target, card, isLink); - - if (typeof result1 != 'number') result1 = 0; - if (typeof result2 != 'number') result2 = 0; - var temp1, temp2, temp3, temp01 = 0, temp02 = 0, threaten = 1; - var skills1 = player.getSkills().concat(lib.skill.global); - game.expandSkills(skills1); - var zerotarget = false, zeroplayer = false; - for (var i = 0; i < skills1.length; i++) { - temp1 = get.info(skills1[i]).ai; - if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { - temp1 = temp1.effect.player(card, player, target, result1, isLink); - } - else temp1 = undefined; - if (typeof temp1 == 'object') { - if (temp1.length == 2 || temp1.length == 4) { - result1 *= temp1[0]; - temp01 += temp1[1]; - } - if (temp1.length == 4) { - result2 *= temp1[2]; - temp02 += temp1[3]; - } - } - else if (typeof temp1 == 'number') { - result1 *= temp1; - } - else if (temp1 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp1 == 'zerotarget') { - zerotarget = true; - } - else if (temp1 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - } - if (target) { - var skills2 = target.getSkills().concat(lib.skill.global); - game.expandSkills(skills2); - for (var i = 0; i < skills2.length; i++) { - temp2 = get.info(skills2[i]).ai; - if (temp2 && temp2.threaten) temp3 = cache.delegate(temp2).threaten; - else temp3 = undefined; - if (temp2 && typeof temp2.effect == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); - else temp2 = undefined; - } - else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { - if (!player.hasSkillTag('ignoreSkill', true, { - card: card, - target: target, - skill: skills2[i], - isLink: isLink, - })) temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); - else temp2 = undefined; - } - else temp2 = undefined; - if (typeof temp2 == 'object') { - if (temp2.length == 2 || temp2.length == 4) { - result2 *= temp2[0]; - temp02 += temp2[1]; - } - if (temp2.length == 4) { - result1 *= temp2[2]; - temp01 += temp2[3]; - } - } - else if (typeof temp2 == 'number') { - result2 *= temp2; - } - else if (temp2 == 'zeroplayer') { - zeroplayer = true; - } - else if (temp2 == 'zerotarget') { - zerotarget = true; - } - else if (temp2 == 'zeroplayertarget') { - zeroplayer = true; - zerotarget = true; - } - if (typeof temp3 == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - else if (typeof temp3 == 'object') { - if (typeof temp3.target == 'number') { - threaten *= temp3; - } - else if (typeof temp3.target == 'function' && temp3(player, target) != undefined) { - threaten *= temp3(player, target); - } - } - else if (typeof temp3 == 'number') { - threaten *= temp3; - } - } - result2 += temp02; - result1 += temp01; - if (typeof card == 'object' && !result.ignoreStatus) { - if (cache.get.attitude(player, target) < 0) { - result2 *= Math.sqrt(threaten); - } - else { - result2 *= Math.sqrt(Math.sqrt(threaten)); - } - // *** continue here *** - if (target.hp == 1) result2 *= 2.5; - if (target.hp == 2) result2 *= 1.8; - let targetCountCards = target.countCards('h'); - if (targetCountCards == 0) { - if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { - result2 *= 1.7; - } - else { - result2 *= 1.5; - } - } - if (targetCountCards == 1) result2 *= 1.3; - else if (targetCountCards == 2) result2 *= 1.1; - else if (targetCountCards > 3) result2 *= 0.5; - if (target.hp == 4) result2 *= 0.9; - else if (target.hp == 5) result2 *= 0.8; - else if (target.hp > 5) result2 *= 0.6; - } - } - else { - result2 += temp02; - result1 += temp01; - } - if (zeroplayer) result1 = 0; - if (zerotarget) result2 = 0; - var final = 0; - if (player2) { - final = (result1 * cache.get.attitude(player2, player) + (target ? result2 * cache.get.attitude(player2, target) : 0)); - } - else final = (result1 * cache.get.attitude(player, player) + (target ? result2 * cache.get.attitude(player, target) : 0)); - if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { - var info = get.info(card); - if (!info || !info.ai || !info.ai.canLink) { - if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); - }); - } - else if (info.ai.canLink(player, target, card)) { - game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); - }); - } - } - return final; - } - static damageEffect(target, player, viewer, nature) { - if (get.itemtype(nature) == 'natures') { - var natures = get.natureList(nature); - return natures.map(n => get.damageEffect(target, player, viewer, n)).reduce((p, c) => p + c, 0) / (natures.length || 1); - } - if (!player) { - player = target; - } - if (!viewer) { - viewer = target; - } - var name = 'damage'; - if (nature == 'fire') { - name = 'firedamage'; - } - else if (nature == 'thunder') { - name = 'thunderdamage'; - } - else if (nature == 'ice') { - name = 'icedamage'; - } - var eff = get.effect(target, { name: name }, player, viewer); - if (eff > 0 && target.hujia > 0) return eff / 1.3; - return eff; - } - /** - * - * @param {any} source 如果参数是function,执行此函数并返回结果,传参为此方法剩余的参数。如果参数不是function,直接返回结果。 - * @returns 返回的结果 - */ - static dynamicVariable(source){ - if(typeof source == 'function'){ - return source.call(null,...(Array.from(arguments).slice(1))); - } - return source; - } - static recoverEffect(target, player, viewer) { - if (target.hp == target.maxHp) return 0; - if (!player) { - player = target; - } - if (!viewer) { - viewer = target; - } - return get.effect(target, { name: 'recover' }, player, viewer); - } - static buttonValue(button) { - var card = button.link; - var player = get.owner(card); - if (!player) player = _status.event.player; - if (player.getCards('j').includes(card)) { - var efff = get.effect(player, { - name: card.viewAs || card.name, - cards: [card], - }, player, player); - if (efff > 0) return 0.5; - if (efff == 0) return 0; - return -1.5; - } - if (player.getCards('e').includes(card)) { - var evalue = get.value(card, player); - if (player.hasSkillTag('noe')) { - if (evalue >= 7) { - return evalue / 6; - } - return evalue / 10; - } - return evalue / 3; - } - if (player.hasSkillTag('noh')) return 0.1; - var nh = player.countCards('h'); - switch (nh) { - case 1: return 2; - case 2: return 1.6; - case 3: return 1; - case 4: return 0.8; - case 5: return 0.6; - default: return 0.4; - } - } - static attitude2(to) { return get.attitude(_status.event.player, to); } -} - -export const get = Get; - -export { - Is, - Promises -}; +import { userAgent, GeneratorFunction, AsyncFunction } from "../util/index.js"; +import { game } from "../game/index.js"; +import { lib } from "../library/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { CacheContext } from "../library/cache/cacheContext.js"; +import { Is } from "./is.js"; +import { Promises } from "./promises.js"; + +export class Get { + is = new Is(); + promises = new Promises(); + /** + * 获取当前内核版本信息 + * + * 目前仅考虑`chrome`, `firefox`和`safari`三种浏览器的信息,其余均归于其他范畴 + * + * > 其他后续或许会增加,但`IE`永无可能 + * + * @returns {["firefox" | "chrome" | "safari" | "other", number, number, number]} + */ + coreInfo() { + const regex = /(firefox|chrome|safari)\/(\d+(?:\.\d+)+)/; + let result; + if (!(result = userAgent.match(regex))) return ["other", NaN, NaN, NaN]; + if (result[1] != "safari") { + const [major, minor, patch] = result[2].split("."); + return [result[1], parseInt(major), parseInt(minor), parseInt(patch)]; + } + result = userAgent.match(/version\/(\d+(?:\.\d+)+).*safari/); + const [major, minor, patch] = result[1].split("."); + return ["safari", parseInt(major), parseInt(minor), parseInt(patch)]; + } + /** + * 返回 VCard[] 形式的所有牌,用于印卡将遍历 + * @param {Function} filter + * @returns {string[][]} + */ + inpileVCardList(filter) { + let list = []; + for (const name of lib.inpile) { + const type = get.type(name); + const info = [type, "", name]; + if (!filter || filter(info)) list.push(info); + if (name == "sha") { + for (const nature of lib.inpile_nature) { + const info = [type, "", name, nature]; + if (!filter || filter(info)) list.push(info); + } + } + } + return list; + } + /** + * 根据(Player的)座次数n(从1开始)获取对应的“n号位”翻译 + * @param {number | Player} seat + */ + seatTranslation(seat) { + if (get.itemtype(seat) === "player") seat = seat.getSeatNum() - 1; + return `${get.cnNumber(seat + 1, true)}号位`; + } + /** + * @param {number} numberOfPlayers + * @returns {string[]} + */ + identityList(numberOfPlayers) { + const modeConfig = lib.config.mode_config; + if (modeConfig) { + const identityConfig = modeConfig.identity; + if (identityConfig) { + const identityLists = identityConfig.identity; + if (identityLists) { + const identityList = identityLists[numberOfPlayers - 2]; + if (Array.isArray(identityList)) return identityList.slice(); + } + } + } + const numberOfPlayersExceptLord = numberOfPlayers - 1, + numberOfLoyalists = Math.round((numberOfPlayersExceptLord * 3) / 9), + numberOfSpys = Math.round((numberOfPlayersExceptLord * 2) / 9); + return ["zhu"].concat( + Array.from( + { + length: numberOfLoyalists, + }, + () => "zhong" + ), + Array.from( + { + length: numberOfSpys, + }, + () => "nei" + ), + Array.from( + { + length: numberOfPlayersExceptLord - numberOfLoyalists - numberOfSpys, + }, + () => "fan" + ) + ); + } + /** + * Generate an object URL from the Base64-encoded octet stream + * + * 从Base64编码的八位字节流生成对象URL + */ + objectURL(octetStream) { + const objectURLMap = lib.objectURL; + if (objectURLMap.has(octetStream)) return objectURLMap.get(octetStream); + const objectURL = URL.createObjectURL( + new Blob([ + Uint8Array.from( + atob(octetStream.replace(/^data:[\s\S]*\/[\s\S]*;base64,/, "")), + (character) => character.charCodeAt() + ), + ]) + ); + objectURLMap.set(octetStream, objectURL); + return objectURL; + } + /** + * Get the card name length + * + * 获取此牌的字数 + */ + cardNameLength(card, player) { + const actualCardName = lib.actualCardName, + name = get.translation(typeof card == "string" ? card : get.name(card, player)); + return (actualCardName.has(name) ? actualCardName.get(name) : name).length; + } + //Yingbian + //应变 + /** + * Get the Yingbian conditions (of the card) + * + * 获取(此牌的)应变条件 + */ + yingbianConditions(card) { + return get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)); + } + complexYingbianConditions(card) { + const complexYingbianConditions = Array.from(lib.yingbian.condition.complex.keys()); + return card + ? complexYingbianConditions.filter((value) => get.cardtag(card, `yingbian_${value}`)) + : complexYingbianConditions; + } + simpleYingbianConditions(card) { + const simpleYingbianConditions = Array.from(lib.yingbian.condition.simple.keys()); + return card + ? simpleYingbianConditions.filter((value) => get.cardtag(card, `yingbian_${value}`)) + : simpleYingbianConditions; + } + /** + * Get the Yingbian effects (of the card) + * + * 获取(此牌的)应变效果 + */ + yingbianEffects(card) { + const yingbianEffects = Array.from(lib.yingbian.effect.keys()); + return card + ? yingbianEffects.filter((value) => get.cardtag(card, `yingbian_${value}`)) + : yingbianEffects; + } + /** + * Get the default Yingbian effect of the card + * + * 获取此牌的默认应变效果 + */ + defaultYingbianEffect(card) { + const info = get.info(card); + return (info && info.defaultYingbianEffect) || null; + } + /** + * 优先度判断 + */ + priority(skill) { + const info = get.info(skill); + if (!info) return 0; + if ("_priority" in info) return info._priority; + let priority = 0; + if (info.priority) { + priority = info.priority * 100; + } + if (info.silent) { + priority++; + } + if (info.equipSkill) priority -= 25; + if (info.cardSkill) priority -= 50; + if (info.ruleSkill) priority -= 75; + info._priority = priority; + return priority; + } + /** + * 新装备栏相关 + * + * 获取一张装备牌实际占用的装备栏(君曹操六龙) + * + * 用法同{@link subtype},返回数组 + * + * @param { string | Card | VCard | CardBaseUIData } obj + * @param { false | Player } [player] + * @returns { string[] } + */ + subtypes(obj, player) { + if (typeof obj == "string") obj = { name: obj }; + if (typeof obj != "object") return; + var name = get.name(obj, player); + if (!lib.card[name]) return []; + if (lib.card[name].subtypes) { + const subtypes = get.copy(lib.card[name].subtypes); + return subtypes; + } else if (lib.card[name].subtype) { + const subtype = lib.card[name].subtype; + return [subtype]; + } + return []; + } + //装备栏 END + /** + * @returns { string[] } + */ + pinyin(chinese, withTone) { + const pinyinUtilx = window.pinyinUtilx; + if (!pinyinUtilx) return []; + const pinyins = lib.pinyins; + if (pinyins) { + const pinyin = pinyins[chinese]; + if (Array.isArray(pinyin)) + return withTone === false ? pinyin.map(pinyinUtilx.removeTone) : pinyin.slice(); + } + return pinyinUtilx.getPinyin(chinese, null, withTone, true); + } + yunmu(str) { + //部分整体认读音节特化处理 + const util = window.pinyinUtilx; + if (util && lib.pinyins._metadata.zhengtirendu.includes(util.removeTone(str))) { + return "-" + str[str.length - 1]; + } + //排除声母 + for (let i of lib.pinyins._metadata.shengmu) { + if (str.startsWith(i)) { + str = str.slice(i.length); + if (str[0] == "u" && lib.pinyins._metadata.special_shengmu.includes(i)) + str = "ü" + str.slice(1); + break; + } + } + //排除介母 + if (str.length > 0) { + for (let i in lib.pinyins._metadata.feijiemu) { + if (str[0] == i) { + let goon = false; + for (let j of lib.pinyins._metadata.feijiemu[i]) { + if (str.startsWith(j)) goon = true; + } + if (!goon) str = str.slice(1); + break; + } + } + } + return str; + } + /** + * 用于将参数转换为字符串,作为缓存的key。 + */ + paramToCacheKey() { + var str = ""; + for (var arg of arguments) { + if (arg === null || arg === undefined) { + str += arg + "-"; + continue; + } + if (arg.playerid) { + str += "p:" + arg.playerid; + } else if (arg.cardid) { + str += "c:" + arg.cardid; + } else if (arg.name) { + str += "n:" + arg.name; + } else { + str += "s:" + arg; + } + str += "-"; + } + return str; + } + yunjiao(str) { + const util = window.pinyinUtilx; + if (util) str = util.removeTone(str); + if (lib.pinyins._metadata.zhengtirendu.includes(str)) { + str = "-" + str[str.length - 1]; + } else { + for (let i of lib.pinyins._metadata.shengmu) { + if (str.startsWith(i)) { + str = str.slice(i.length); + if (str[0] == "u" && lib.pinyins._metadata.special_shengmu.includes(i)) + str = "ü" + str.slice(1); + break; + } + } + } + for (let i in lib.pinyins._metadata.yunjiao) { + if (lib.pinyins._metadata.yunjiao[i].includes(str)) return i; + } + return null; + } + /** + * @param { string } skill + * @param { Player } player + * @returns { string[] } + */ + skillCategoriesOf(skill, player) { + const list = [], + info = get.info(skill); + if (!info) return list; + if (get.is.locked(skill, player)) list.add("锁定技"); + if (info.zhuSkill) list.add("主公技"); + if (info.limited) list.add("限定技"); + if (info.juexingji) list.add("觉醒技"); + if (get.is.zhuanhuanji(skill, player)) list.add("转换技"); + if (info.hiddenSkill) list.add("隐匿技"); + if (info.clanSkill) list.add("宗族技"); + if (info.groupSkill) list.add("势力技"); + if (info.dutySkill) list.add("使命技"); + if (info.chargeSkill) list.add("蓄力技"); + if (info.zhenfa) list.add("阵法技"); + if (info.mainSkill) list.add("主将技"); + if (info.viceSkill) list.add("副将技"); + if (info.lordSkill) list.add("君主技"); + if (info.chargingSkill) list.add("蓄能技"); + if (info.charlotte) list.add("Charlotte"); + if (info.sunbenSkill) list.add("昂扬技"); + if (info.categories) list.addArray(info.categories(skill, player)); + return list; + } + numOf(obj, item) { + return obj.filter((element) => element == item).length; + } + connectNickname() { + return 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((card) => lib.inpile.includes(card)); + if (list.length) return list; + return get.inpile("trick", "trick").randomGets(3); + } + sourceCharacter(str) { + if (str) { + for (var i in lib.characterReplace) { + if (lib.characterReplace[i].includes(str)) return i; + } + } + return str; + } + 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(hp) { + if (typeof hp == "number") return hp; + else if (typeof hp == "string") { + if (hp.includes("/")) { + const num = hp.split("/")[0]; + if (num) { + if (num == "Infinity" || num == "∞") { + return Infinity; + } else { + return parseInt(num); + } + } + } else if (hp == "Infinity" || hp == "∞") return Infinity; + } + return 0; + } + infoMaxHp(hp) { + if (typeof hp == "number") return hp; + else if (typeof hp == "string") { + if (hp.includes("/")) { + const num = hp.split("/")[1]; + if (num) { + if (num == "Infinity" || num == "∞") { + return Infinity; + } else { + return parseInt(num); + } + } + } else if (hp == "Infinity" || hp == "∞") return Infinity; + } + return 0; + } + infoHujia(hp) { + if (typeof hp == "string" && hp.includes("/")) { + const num = hp.split("/")[2]; + if (num) { + if (num == "Infinity" || num == "∞") { + return Infinity; + } else { + return parseInt(num); + } + } + } + return 0; + } + bottomCards(num, putBack) { + if (_status.waitingForCards) { + ui.create.cards.apply(ui.create, _status.waitingForCards); + delete _status.waitingForCards; + } + var list = []; + var card = false; + if (typeof num != "number") num = 1; + if (num == 0) { + card = true; + num = 1; + } + if (num < 0) num = 1; + while (num--) { + if (ui.cardPile.hasChildNodes() == false) { + game.washCard(); + } + if (ui.cardPile.hasChildNodes() == false) { + game.over("平局"); + return []; + } + var cardx = ui.cardPile.removeChild(ui.cardPile.lastChild); + cardx.original = "c"; + list.push(cardx); + } + if (putBack) { + for (let i = list.length - 1; i >= 0; i--) { + ui.cardPile.appendChild(list[i]); + } + } + game.updateRoundNumber(); + if (card) return list[0]; + return list; + } + discarded() { + return _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(str) { + if (str[0] == "#") { + var color; + switch (str[1]) { + case "r": + color = "fire"; + break; + case "p": + color = "legend"; + break; + case "b": + color = "blue"; + break; + case "g": + color = "green"; + break; + default: + return str.slice(2); + } + return '' + str.slice(2) + ""; + } + return str; + } + evtprompt(next, str) { + if (next.prompt) { + next.set("prompt2", str); + } else { + if (str.startsWith("###")) { + var prompts = str.slice(3).split("###"); + if (prompts[0]) next.set("prompt", prompts[0]); + if (prompts[1]) next.set("prompt2", prompts[1]); + } else { + next.set("prompt", str); + } + } + } + autoViewAs(card, cards) { + return new lib.element.VCard(card, cards); + } + /** + * @deprecated + */ + _autoViewAs(card, cards) { + var info = get.info(card); + if (info.autoViewAs) { + if (cards === false) { + return { + name: info.autoViewAs, + }; + } else if (Array.isArray(cards)) { + return { + name: info.autoViewAs, + cards: cards.slice(0), + }; + } else if (get.itemtype(card) == "card") { + return { + name: info.autoViewAs, + cards: [card], + }; + } else { + return { + name: info.autoViewAs, + suit: card.suit, + number: card.number, + nature: card.nature, + }; + } + } else { + if (card.isCard || get.itemtype(card) == "card") { + var next = { + name: get.name(card), + suit: get.suit(card), + number: get.number(card), + nature: get.nature(card), + isCard: true, + cardid: card.cardid, + wunature: card.wunature, + storage: get.copy(card.storage), + cards: get.copy(card.cards), + }; + if (get.itemtype(cards) == "cards" && !card.cards) next.cards = cards.slice(0); + else if (get.itemtype(card) == "card") next.cards = [card]; + return next; + } else if (get.is.object(card) && get.itemtype(cards) == "cards" && !card.cards) { + card = get.copy(card); + card.cards = cards.slice(0); + } + return card; + } + } + max(list, func, type) { + list = list.slice(0); + if (typeof func == "string") { + var key = func; + func = function (item) { + return item[key]; + }; + } + list.sort(function (a, b) { + return func(b) - func(a); + }); + if (type == "list") { + var list2 = []; + for (var i = 0; i < list.length; i++) { + if (func(list[i]) == func(list[0])) { + list2.push(list[i]); + } + } + return list2; + } else if (type == "item") { + return list[0]; + } else { + return func(list[0]); + } + } + min(list, func, type) { + list = list.slice(0); + if (typeof func == "string") { + var key = func; + func = function (item) { + return item[key]; + }; + } + list.sort(function (a, b) { + return func(a) - func(b); + }); + if (type == "list") { + var list2 = []; + for (var i = 0; i < list.length; i++) { + if (func(list[i]) == func(list[0])) { + list2.push(list[i]); + } + } + return list2; + } else if (type == "item") { + return list[0]; + } else { + return func(list[0]); + } + } + /** + * @overload + * @param { string } name + * @returns { Character } + */ + /** + * @template { 0 | 1 | 2 | 3 | 4 } T + * @overload + * @param { string } name + * @param { T } num + * @returns { Character[T] } + */ + character(name, num) { + let info = lib.character[name]; + if (!info) { + const pack = Object.keys(lib.characterPack).find((pack) => name in lib.characterPack[pack]); + if (pack) info = lib.characterPack[pack][name]; + } + if (typeof num === "number") { + if (!info) info = []; + if (info[num]) return info[num]; + if (num === 3 || num === 4) return []; + return; + } + return info; + } + characterInitFilter(name) { + const info = get.character(name); + if (!info || !info[4]) return []; + const filter = info[4].find((tag) => tag.startsWith("InitFilter")); + if (!filter) return []; + return filter.split(":").slice(1); + } + characterIntro(name) { + if (lib.characterIntro[name]) return lib.characterIntro[name]; + var tags = get.character(name, 4); + if (tags) { + for (var i = 0; i < tags.length; i++) { + if (tags[i].startsWith("des:")) { + return tags[i].slice(4); + } + } + } + while (name.includes("_") && !lib.characterIntro[name]) { + name = name.slice(name.indexOf("_") + 1); + } + if (lib.characterIntro[name]) return lib.characterIntro[name]; + return "暂无武将介绍"; + } + bordergroup(info, raw) { + if (!Array.isArray(info)) { + info = lib.character[info]; + if (!info) return ""; + } + if (Array.isArray(info[4])) + for (const str of info[4]) { + if (typeof str == "string" && str.startsWith("border:")) return str.slice(7); + } + return raw ? "" : info[1] || ""; + } + groupnature(group, method) { + var nature = lib.groupnature[group]; + if (!nature) return ""; + if (method == "raw") { + return nature; + } + return nature + "mm"; + } + sgn(num) { + if (num > 0) return 1; + if (num < 0) return -1; + return 0; + } + rand(num, num2) { + if (typeof num2 == "number") { + return num + Math.floor(Math.random() * (num2 - num + 1)); + } else { + return Math.floor(Math.random() * num); + } + } + sort(arr, method, arg) { + return method == "seat" ? arr.sortBySeat(arg) : void 0; + } + sortSeat(arr, target) { + return arr.sortBySeat(target); + } + /** + * @param { (zip: JSZip) => any } callback + */ + zip(callback) { + if (!window.JSZip) { + lib.init.js(lib.assetURL + "game", "jszip", function () { + callback(new JSZip()); + }); + } else { + callback(new JSZip()); + } + } + delayx(num, max) { + if (typeof num != "number") num = 1; + if (typeof max != "number") max = Infinity; + switch (lib.config.game_speed) { + case "vslow": + return Math.min(max, 2.5 * num); + case "slow": + return Math.min(max, 1.5 * num); + case "fast": + return Math.min(max, 0.7 * num); + case "vfast": + return Math.min(max, 0.4 * num); + case "vvfast": + return Math.min(max, 0.2 * num); + default: + return Math.min(max, num); + } + } + prompt(skill, target, player) { + player = player || _status.event.player; + if (target) { + var str = get.translation(target); + if (target == player) { + str += "(你)"; + } + return "是否对" + str + "发动【" + get.skillTranslation(skill, player) + "】?"; + } else { + return "是否发动【" + get.skillTranslation(skill, player) + "】?"; + } + } + 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(master) { + var url = lib.config.updateURL || lib.updateURL; + if (url[url.length - 1] != "/") { + url += "/"; + } + if (master != "nodev") { + return url + "master/"; + } else { + return url + "v" + lib.version + "/"; + } + } + round(num, f) { + var round = Math.pow(10, f); + return Math.round(num * round) / round; + } + playerNumber() { + var num; + if (_status.brawl && _status.brawl.playerNumber) { + num = _status.brawl.playerNumber; + } else { + num = get.config("player_number"); + } + return parseInt(num) || 2; + } + benchmark(func1, func2, iteration, arg) { + var tic, toc; + var key1, key2; + if (!arg) arg = []; + if (Array.isArray(func2)) { + key1 = func2[0]; + key2 = func2[1]; + } else if (typeof func2 == "string") { + key1 = func2; + func2 = iteration || 100; + } else if (typeof func2 == "number") { + arg = iteration || arg; + iteration = func2; + } + tic = get.utc(); + for (var i = 0; i < iteration; i++) { + if (key1) { + func1[key1](arg.randomGet()); + } else { + func1(arg.randomGet()); + } + } + toc = get.utc(); + if (typeof func2 == "number") { + return toc - tic; + } + console.log("time1: " + (toc - tic)); + tic = get.utc(); + for (var i = 0; i < iteration; i++) { + if (key2) { + func1[key2](arg.randomGet()); + } else { + func2(arg.randomGet()); + } + } + toc = get.utc(); + console.log("time2: " + (toc - tic)); + } + /** + * @param {any} obj + */ + stringify(obj, level = 0) { + level = level || 0; + let indent = ""; + let str; + for (let i = 0; i < level; i++) { + indent += " "; + } + if (get.objtype(obj) == "object" || obj instanceof lib.element.GameEventPromise) { + str = "{\n"; + for (let i in obj) { + /** + * @type {string} + */ + let insertDefaultString; + let insertFunctionString = indent + " " + get.stringify(obj[i], level + 1) + ",\n"; + let parseFunction = (/** @type {string} */ i) => { + // let string = obj[i].toString(); + i = i.replaceAll("$", "\\$"); + let execResult; + if (obj[i] instanceof GeneratorFunction) { + // *content(){} + execResult = new RegExp(`\\*\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:function*(){} + else { + return insertDefaultString; + } + } else if (obj[i] instanceof AsyncFunction) { + execResult = new RegExp(`async\\s*${i}[\\s\\S]*?\\(`).exec(obj[i]); + // async content(){} + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:async function(){} + else { + return insertDefaultString; + } + } else { + execResult = new RegExp(`${i}[\\s\\S]*?\\(`).exec(obj[i]); + // content(){} + if (execResult && execResult.index === 0) { + return insertFunctionString; + } + // content:function(){} + else { + return insertDefaultString; + } + } + }; + if (/[^a-zA-Z]/.test(i)) { + insertDefaultString = + indent + ' "' + i + '":' + get.stringify(obj[i], level + 1) + ",\n"; + if (typeof obj[i] !== "function") { + str += insertDefaultString; + } else { + str += parseFunction(i); + } + } else { + insertDefaultString = + indent + " " + i + ":" + get.stringify(obj[i], level + 1) + ",\n"; + if (typeof obj[i] !== "function") { + str += insertDefaultString; + } else { + str += parseFunction(i); + } + } + } + str += indent + "}"; + return str; + } else { + if (typeof obj == "function") { + str = obj.toString(); + str = str.replace(/\t/g, " "); + let i = str.lastIndexOf("\n"); + let num = 0; + for (let j = i + 1; j < str.length && str[j] == " "; j++) { + num++; + } + num = Math.floor(num / 4); + for (i = 0; i < num - level; i++) { + str = str.replace(/\n {4}/g, "\n"); + } + } else { + try { + if (Array.isArray(obj) && obj.includes(Infinity)) { + obj = obj.slice(0); + let rand = get.id(); + for (let i = 0; i < obj.length; i++) { + if (obj[i] === Infinity) { + obj[i] = parseInt(rand); + } + } + str = JSON.stringify(obj).replace(new RegExp(rand, "g"), "Infinity"); + } else { + str = JSON.stringify(obj) || ""; + } + } catch (e) { + str = ""; + } + } + return str; + } + } + /** + * 深拷贝函数(虽然只处理了部分情况) + * + * 除了普通的Object和NullObject,均不考虑自行赋值的数据,但会原样将Symbol复制过去 + * + * @template T + * @param {T} obj - 要复制的对象,若不是对象则直接返回原值 + * @param {boolean} [copyKeyDeep = false] - 是否深复制`Map`的`key` + * @param {WeakMap} [map] - 拷贝用的临时存储,用于处理循环引用(请勿自行赋值) + * @returns {T} - 深拷贝后的对象,若传入值不是对象则为传入值 + */ + copy(obj, copyKeyDeep = false, map = new WeakMap()) { + // 参考[这里](https://juejin.cn/post/7315612852890026021)实现深拷贝 + // 不再判断是否能structuredClone是因为structuredClone会把Symbol给毙了 + const getType = (obj) => Object.prototype.toString.call(obj); + + const canTranverse = { + "[object Map]": true, + "[object Set]": true, + "[object Object]": true, + "[object Array]": true, + "[object Arguments]": true, + "[object Date]": true, + }; + + if (typeof obj !== "object" || obj === null || !canTranverse[getType(obj)]) return obj; + + // @ts-ignore + if (map.has(obj)) return map.get(obj); + + const constructor = obj.constructor; + // @ts-ignore + const target = constructor + ? // 这四类数据处理单独处理 + // (实际上需要处理的只有Map和Set) + // 除此之外的就只能祝愿有拷贝构造函数了 + Array.isArray(obj) || obj instanceof Map || obj instanceof Set || constructor === Object + ? // @ts-ignore + new constructor() + : constructor.name in window && /\[native code\]/.test(constructor.toString()) + ? // @ts-ignore + new constructor(obj) + : obj + : Object.create(null); + if (target === obj) return target; + + map.set(obj, target); + + if (obj instanceof Map) { + obj.forEach((value, key) => { + target.set( + copyKeyDeep ? get.copy(key, copyKeyDeep, map) : key, + get.copy(value, copyKeyDeep, map) + ); + }); + } else if (obj instanceof Set) { + obj.forEach((value) => { + target.add(get.copy(value, copyKeyDeep, map)); + }); + } + + const descriptors = Object.getOwnPropertyDescriptors(obj); + if (descriptors) { + for (const [key, descriptor] of Object.entries(descriptors)) { + const { enumerable, configurable } = descriptor; + if (obj.hasOwnProperty(key)) { + const result = { enumerable, configurable }; + if (descriptor.hasOwnProperty("value")) { + result.value = get.copy(descriptor.value, copyKeyDeep, map); + result.writable = descriptor.writable; + } else { + const { get, set } = descriptor; + result.get = get; + result.set = set; + } + Reflect.defineProperty(target, key, result); + } + } + } + + const symbols = Object.getOwnPropertySymbols(obj); + symbols.forEach((symbol) => { + target[symbol] = get.copy(obj[symbol], copyKeyDeep, map); + }); + + return target; + } + inpilefull(type) { + var list = []; + for (var i in lib.cardPile) { + for (var j = 0; j < lib.cardPile[i].length; j++) { + var info = lib.cardPile[i][j]; + if (lib.inpile.includes(info[2]) && get.type(info[2]) == type) { + list.push({ + name: info[2], + suit: info[0], + number: info[1], + nature: info[3], + }); + } + } + } + return list; + } + inpile(type, filter) { + var list = []; + if (filter == "trick") { + for (var i = 0; i < lib.inpile.length; i++) { + if (get.type(lib.inpile[i], "trick") == type) list.push(lib.inpile[i]); + } + } else { + for (var i = 0; i < lib.inpile.length; i++) { + if (typeof type == "function") { + if (type(lib.inpile[i])) { + list.push(lib.inpile[i]); + } + } else { + if (typeof filter == "function" && !filter(lib.inpile[i])) continue; + if (type.startsWith("equip") && type.length == 6) { + if (get.subtype(lib.inpile[i]) == type) list.push(lib.inpile[i]); + } else { + if (get.type(lib.inpile[i]) == type) list.push(lib.inpile[i]); + } + } + } + } + return list; + } + inpile2(type) { + return get.inpile(type, "trick"); + } + typeCard(type, filter) { + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; + // if(lib.card[i].vanish||lib.card[i].destroy) continue; + if (lib.card[i].destroy) continue; + if (typeof filter == "function" && !filter(i)) continue; + if (lib.config.bannedcards.includes(i)) continue; + if (!lib.translate[i + "_info"]) continue; + if ( + (type.startsWith("equip") && type.length == 6) || + (type.startsWith("hslingjian") && type.length == 11) || + type.startsWith("spell_") + ) { + if (get.subtype(i) == type) list.push(i); + } else { + if (get.type(i) == type) list.push(i); + } + } + return list; + } + libCard(filter) { + var list = []; + for (var i in lib.card) { + if (lib.card[i].mode && lib.card[i].mode.includes(get.mode()) == false) continue; + // if(lib.card[i].vanish||lib.card[i].destroy) continue; + if (lib.card[i].destroy) continue; + if (lib.config.bannedcards.includes(i)) continue; + if (!lib.translate[i + "_info"]) continue; + if (filter(lib.card[i], i)) { + list.push(i); + } + } + return list; + } + ip() { + if (!require) return ""; + var interfaces = require("os").networkInterfaces(); + for (var devName in interfaces) { + var iface = interfaces[devName]; + for (var i = 0; i < iface.length; i++) { + var alias = iface[i]; + if (alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal) { + return alias.address; + } + } + } + } + modetrans(config, server) { + if (config.mode == "doudizhu") { + switch (config.doudizhu_mode) { + case "kaihei": + return "开黑斗地主"; + case "huanle": + return "欢乐斗地主"; + case "binglin": + return "兵临城下"; + case "online": + return "智斗三国"; + default: + return "休闲" + (config.double_character ? "双将" : "") + "斗地主"; + } + } + if (config.mode == "versus") { + switch (config.versus_mode) { + case "1v1": + return "单人对决"; + case "2v2": + return "欢乐成双"; + case "3v3": + return "血战到底"; + case "4v4": + return "四人对决"; + case "guandu": + return "官渡之战"; + } + } + if (config.mode == "single") { + switch (config.single_mode) { + case "normal": + return "新1v1"; + case "changban": + return "血战长坂坡"; + case "dianjiang": + return "点将单挑"; + case "wuxianhuoli": + return "无限火力"; + } + } + if (config.mode == "identity") { + switch (config.identity_mode) { + case "purple": + return "三对三对二"; + case "zhong": + return (config.double_character ? "双将" : "") + "忠胆英杰"; + case "stratagem": + return ( + get.cnNumber(parseInt(config.number)) + + "人" + + (config.double_character ? "双将" : "") + + "谋攻" + ); + default: + return `${get.cnNumber(parseInt(config.number))}人${config.double_nei ? "双内" : ""}${ + config.enable_commoner ? "带民" : "" + }${config.double_character ? "双将" : ""}身份`; + } + } + if (config.mode == "guozhan") { + if (config.separatism) return "群雄割据"; + if (config.guozhan_mode != "normal") + switch (config.guozhan_mode) { + case "yingbian": + return "应变国战"; + case "old": + return "怀旧国战"; + } + } + if (server) { + return get.translation(config.mode) + "模式"; + } else { + return get.cnNumber(parseInt(config.number)) + "人" + get.translation(config.mode); + } + } + charactersOL(func) { + var list = []; + var libCharacter = {}; + for (var i = 0; i < lib.configOL.characterPack.length; i++) { + var pack = lib.characterPack[lib.configOL.characterPack[i]]; + for (var j in pack) { + if (typeof func == "function" && func(j)) continue; + if (lib.connectBanned.includes(j)) continue; + if (lib.character[j]) libCharacter[j] = pack[j]; + } + } + for (i in libCharacter) { + if (lib.filter.characterDisabled(i, libCharacter)) continue; + list.push(i); + } + return list; + } + trimip(str) { + var len = str.length - 5; + if (str.lastIndexOf(":8080") == len) { + str = str.slice(0, len); + } + return str; + } + mode() { + return lib[_status.connectMode ? "configOL" : "config"].mode; + } + idDialog(id) { + return ui.dialogs.find((dialog) => dialog.videoId == id) || null; + } + arenaState() { + var state = { + number: ui.arena.dataset.number, + players: {}, + mode: _status.mode, + dying: _status.dying, + servermode: window.isNonameServer, + roomId: game.roomId, + over: _status.over, + inpile: lib.inpile, + inpile_nature: lib.inpile_nature, + renku: _status.renku, + }; + for (var i in lib.playerOL) { + state.players[i] = lib.playerOL[i].getState(); + } + return state; + } + skillState(player) { + var skills = { + global: lib.skill.global, + }; + var skillinfo = {}; + for (var i in lib.playerOL) { + skills[i] = { + skills: lib.playerOL[i].skills, + hiddenSkills: lib.playerOL[i].hiddenSkills, + invisibleSkills: lib.playerOL[i].invisibleSkills, + additionalSkills: lib.playerOL[i].additionalSkills, + disabledSkills: lib.playerOL[i].disabledSkills, + tempSkills: lib.playerOL[i].tempSkills, + storage: lib.playerOL[i].storage, + }; + } + //for(var i in lib.skill){ + // if(lib.skill[i].chooseButton&&lib.skill[i].enable){ + // skillinfo[i]=lib.skill[i].chooseButton; + // } + //} + skills.skillinfo = skillinfo; + if (player) { + skills.stat = player.getStat(); + } + return skills; + } + id() { + return Math.floor(1000000 + 9000000 * Math.random()).toString() + (10 + lib.status.globalId++); + } + zhu(player, skill, group) { + if (typeof player == "string") { + skill = player; + player = null; + } + var mode = get.mode(); + if (mode == "identity") { + if (_status.mode == "purple") { + if (!player) return null; + var zhu = game[player.identity.slice(0, 1) + "Zhu"]; + if (!zhu) return null; + if (skill && !zhu.hasSkill(skill)) return null; + return zhu; + } + if (!game.zhu) return null; + if (skill && !game.zhu.hasSkill(skill)) return null; + if (game.zhu.isZhu) return game.zhu; + } else if (mode == "versus" && (_status.mode == "four" || _status.mode == "guandu")) { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isZhu) { + if (skill && !game.players[i].hasSkill(skill)) continue; + if (!player) return game.players[i]; + if (player.side == game.players[i].side) { + return game.players[i]; + } + } + } + } else if (mode == "guozhan") { + for (var i = 0; i < game.players.length; i++) { + if (get.is.jun(game.players[i]) && !game.players[i].isUnseen()) { + if (skill && !game.players[i].hasSkill(skill)) continue; + if (!player) return game.players[i]; + if (player.identity == game.players[i].identity) { + return game.players[i]; + } else if (group && group == game.players[i].identity) { + return game.players[i]; + } + } + } + } + return null; + } + config(item, mode) { + mode = mode || lib.config.mode; + if (!lib.config.mode_config[mode]) return; + return lib.config.mode_config[mode][item]; + } + coinCoeff(list) { + var num = 0; + for (var i = 0; i < list.length; i++) { + var rank = get.rank(list[i]); + switch (rank) { + case "sp": + return 0.1; + case "s": + num += 0.4; + break; + case "ap": + num += 0.6; + break; + case "a": + num += 0.8; + break; + case "am": + num += 0.95; + break; + case "bp": + num += 1.05; + break; + case "b": + num += 1.2; + break; + case "bm": + num += 1.4; + break; + case "c": + num += 1.6; + break; + case "d": + num += 1.8; + break; + } + } + return num / list.length; + } + rank(name, num) { + if (typeof name == "object" && name.name) { + name = name.name; + } + if (num == true) num = 9; + if (typeof num != "number") num = false; + if (name == _status.lord) return num ? Math.round((7 * (num - 1)) / 8 + 1) : "ap"; + var rank = lib.rank; + if (lib.characterPack.standard[name] || lib.characterPack.shenhua[name]) { + var skills; + if (lib.character[name]) { + skills = lib.character[name][3]; + } else { + var tmpinfo = get.character(name); + if (tmpinfo) { + skills = tmpinfo[3]; + } else { + skills = []; + } + } + for (var i = 0; i < skills.length; i++) { + if (skills[i].alter && !lib.config.vintageSkills.includes(skills[i])) { + name = lib.rank.a[0]; + break; + } + } + } + if (rank.s.includes(name)) return num ? Math.round((8 * (num - 1)) / 8 + 1) : "s"; + if (rank.ap.includes(name)) return num ? Math.round((7 * (num - 1)) / 8 + 1) : "ap"; + if (rank.a.includes(name)) return num ? Math.round((6 * (num - 1)) / 8 + 1) : "a"; + if (rank.am.includes(name)) return num ? Math.round((5 * (num - 1)) / 8 + 1) : "am"; + if (rank.bp.includes(name)) return num ? Math.round((4 * (num - 1)) / 8 + 1) : "bp"; + if (rank.b.includes(name)) return num ? Math.round((3 * (num - 1)) / 8 + 1) : "b"; + if (rank.bm.includes(name)) return num ? Math.round((2 * (num - 1)) / 8 + 1) : "bm"; + if (rank.c.includes(name)) return num ? Math.round((1 * (num - 1)) / 8 + 1) : "c"; + if (rank.d.includes(name)) return num ? Math.round((0 * (num - 1)) / 8 + 1) : "d"; + if (lib.character[name] && lib.character[name][4]) { + if ( + lib.character[name][4].includes("boss") || + lib.character[name][4].includes("bossallowed") || + lib.character[name][4].includes("hiddenboss") + ) { + return num ? Math.round((9 * (num - 1)) / 8 + 1) : "sp"; + } + } + return num ? Math.round((9 * (num - 1)) / 8 + 1) : "x"; + } + skillRank(skill, type, grouped) { + var info = lib.skill[skill]; + var player = _status.event.skillRankPlayer || _status.event.player; + if (!info) return 0; + if (info.ai) { + if (info.ai.halfneg) return 0; + if (typeof info.ai.combo == "string" && player && !player.hasSkill(info.ai.combo)) { + return 0; + } + if (info.ai.neg) return -1; + } + var num = 1; + var threaten = 1; + if (info.ai && info.ai.threaten) { + if (typeof info.ai.threaten == "number") { + threaten = info.ai.threaten; + } else if (typeof info.ai.threaten == "function" && player) { + threaten = info.ai.threaten(player, player); + } + } + if (type && type.includes("in")) { + if (info.enable == "phaseUse") num += 0.5; + if (info.trigger && info.trigger.player) { + var list = Array.isArray(info.trigger.player) ? info.trigger.player : [info.trigger.player]; + var add = false; + for (var i of list) { + if (i.startsWith("phase")) { + num += 0.5; + add = true; + } else { + for (var j of lib.phaseName) { + if (i.indexOf[j] == 0) { + num += 0.5; + add = true; + break; + } + } + } + if (add) break; + } + } + if ( + info.trigger && + ((typeof info.trigger.player == "string" && info.trigger.player.startsWith("use")) || + info.trigger.source) + ) { + num += 0.3; + } + if (num > 1 && threaten > 1) { + num += Math.sqrt(threaten) - 1; + } + } + if (type && type.includes("out")) { + if (threaten < 1) { + num *= 1 / Math.sqrt(threaten); + } + if (info.trigger) { + if (info.trigger.global) { + var list = Array.isArray(info.trigger.global) + ? info.trigger.global + : [info.trigger.global]; + num += Math.min(3, list.length) / 10; + for (var i of list) { + if (i.startsWith("lose") || i.startsWith("use")) num += 0.3; + if (i.startsWith("cardsDiscard")) num += 0.4; + } + } + if ( + info.trigger.target || + (typeof info.trigger.player == "string" && + (info.trigger.player.startsWith("damage") || info.trigger.player.startsWith("lose"))) + ) + num += 0.1; + } + if (info.ai) { + if (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend) { + num += 0.5; + } + if (info.ai.nolose || info.ai.noh || info.ai.noe || info.ai.nodiscard) { + num += 0.3; + } + } + } + if (!grouped) { + var groups = game.expandSkills([skill]); + groups.remove(skill); + var ggt = []; + for (var i = 0; i < groups.length; i++) { + var gi = get.skillRank(groups[i], type, true); + if (gi < 0) { + num -= 0.5; + } else if (gi > 1) { + ggt.push(gi); + } + } + if (ggt.length) { + num += Math.max.apply(this, ggt) - 1 + ggt.length / 20; + } + } + return num; + } + targetsInfo(targets) { + var info = []; + for (var i = 0; i < targets.length; i++) { + info.push(targets[i].dataset.position); + } + return info; + } + infoTargets(infos) { + return Array.from(infos || []).map((info) => game.playerMap[info]); + } + cardInfo(card) { + return [card.suit, card.number, card.name, card.nature]; + } + cardsInfo(cards = []) { + return Array.from(cards).map(get.cardInfo); + } + infoCard(info) { + var card = ui.create.card(); + if (info[0]) { + card.init(info); + } + return card; + } + infoCards(infos) { + return Array.from(infos || []).map(get.infoCard); + } + cardInfoOL(card) { + return ( + "_noname_card:" + JSON.stringify([card.cardid, card.suit, card.number, card.name, card.nature]) + ); + } + infoCardOL(info) { + if (!lib.cardOL) return info; + var card; + try { + var info = JSON.parse(info.slice(13)); + var id = info.shift(); + if (!id) { + card = ui.create.card(); + if (info && info[2]) card.init(info); + } else if (lib.cardOL[id]) { + if (lib.cardOL[id].name != info[2]) { + if (info && info[2]) lib.cardOL[id].init(info); + } + card = lib.cardOL[id]; + } else if (game.online) { + card = ui.create.card(); + card.cardid = id; + if (info && info[2]) card.init(info); + lib.cardOL[id] = card; + } + } catch (e) { + console.log(e); + } + return card || info; + } + cardsInfoOL(cards) { + return Array.from(cards || []).map(get.cardInfoOL); + } + infoCardsOL(infos) { + return Array.from(infos || []).map(get.infoCardOL); + } + playerInfoOL(player) { + return "_noname_player:" + player.playerid; + } + infoPlayerOL(info) { + return lib.playerOL ? lib.playerOL[info.slice(15)] || info : info; + } + playersInfoOL(players) { + return Array.from(players || []).map(get.playerInfoOL); + } + infoPlayersOL(infos) { + return 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)); + } + const str = func.toString(); + // js内置的函数 + if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}"; + return "_noname_func:" + str; + } + return ""; + } + infoFuncOL(info) { + let func; + const str = info.slice(13).trim(); + try { + // js内置的函数 + if (/\{\s*\[native code\]\s*\}/.test(str)) return function () {}; + // 一般fun和数组形式 + if (str.startsWith("function") || str.startsWith("(")) eval(`func=(${str});`); + // 其他奇形怪状的fun + else { + try { + eval(`func = ${str}`); + } catch { + eval(`let obj = {${str}}; func = obj[Object.keys(obj)[0]]`); + } + } + } catch (e) { + console.error(`${e} in \n${str}`); + return function () {}; + } + if (Array.isArray(func)) { + func = get.filter.apply(this, get.parsedResult(func)); + } + return func; + } + eventInfoOL(item, level, noMore) { + return get.itemtype(item) == "event" + ? `_noname_event:${JSON.stringify( + Object.entries(item).reduce((stringifying, entry) => { + const key = entry[0]; + if (key == "_trigger") { + if (noMore !== false) stringifying[key] = get.eventInfoOL(entry[1], null, false); + } else if ( + !lib.element.GameEvent.prototype[key] && + key != "content" && + get.itemtype(entry[1]) != "event" + ) + stringifying[key] = get.stringifiedResult(entry[1], null, false); + return stringifying; + }, {}) + )}` + : ""; + } + /** + * @param {string} item + */ + infoEventOL(item) { + const evt = new lib.element.GameEvent(); + try { + Object.entries(JSON.parse(item.slice(14))).forEach((entry) => { + const key = entry[0]; + if (typeof evt[key] != "function") evt[key] = get.parsedResult(entry[1]); + }); + } catch (error) { + console.log(error); + } + return evt || item; + } + stringifiedResult(item, level, nomore) { + if (!item) return item; + if (typeof item == "function") { + return get.funcInfoOL(item); + } else if (typeof item == "object") { + switch (get.itemtype(item)) { + case "card": + return get.cardInfoOL(item); + case "cards": + return get.cardsInfoOL(item); + case "player": + return get.playerInfoOL(item); + case "players": + return get.playersInfoOL(item); + case "event": + if (nomore === false) return ""; + return get.eventInfoOL(item); + default: + if (typeof level != "number") { + level = 8; + } + if (Array.isArray(item)) { + if (level == 0) { + return []; + } + var item2 = []; + for (var i = 0; i < item.length; i++) { + item2.push(get.stringifiedResult(item[i], level - 1, nomore)); + } + return item2; + } else if (Object.prototype.toString.call(item) == "[object Object]") { + if (level == 0) { + return {}; + } + var item2 = {}; + for (var i in item) { + item2[i] = get.stringifiedResult(item[i], level - 1, nomore); + } + return item2; + } else { + return {}; + } + } + } else if (item === Infinity) { + return "_noname_infinity"; + } else { + return item; + } + } + parsedResult(item) { + if (!item) return item; + if (typeof item == "string") { + if (item.startsWith("_noname_func:")) { + return get.infoFuncOL(item); + } else if (item.startsWith("_noname_card:")) { + return get.infoCardOL(item); + } else if (item.startsWith("_noname_player:")) { + return get.infoPlayerOL(item); + } else if (item.startsWith("_noname_event:")) { + return get.infoEventOL(item); + } else if (item == "_noname_infinity") { + return Infinity; + } else { + return item; + } + } else if (Array.isArray(item)) { + var item2 = []; + for (var i = 0; i < item.length; i++) { + item2.push(get.parsedResult(item[i])); + } + return item2; + } else if (typeof item == "object") { + var item2 = {}; + for (var i in item) { + item2[i] = get.parsedResult(item[i]); + } + return item2; + } else { + return item; + } + } + verticalStr(str, sp) { + if (typeof str != "string") return ""; + return Array.from(str) + .filter((value) => value != "`") + .join(""); + } + numStr(num, method) { + if (num == Infinity) { + if (method == "card") return get.selectableCards().length + ui.selected.cards.length; + if (method == "target") return get.selectableTargets().length + ui.selected.targets.length; + return "∞"; + } + return num.toString(); + } + rawName(str) { + let str2 = lib.translate[str]; + if (lib.translate[str + "_ab"]) str2 = lib.translate[str + "_ab"]; + if (!str2) return ""; + if (lib.translate[str + "_prefix"] && str2.startsWith(lib.translate[str + "_prefix"])) { + return str2.slice(lib.translate[str + "_prefix"].length); + } + return str2; + } + /** + * 作用修改:只读前缀 不读_ab + */ + rawName2(str) { + let str2 = lib.translate[str]; + if (!str2) return ""; + if (lib.translate[str + "_prefix"] && str2.startsWith(lib.translate[str + "_prefix"])) { + return str2.slice(lib.translate[str + "_prefix"].length); + } + return str2; + } + slimNameHorizontal(str) { + const slimName = lib.translate[`${str}_ab`] || lib.translate[str]; + if (!slimName) return ""; + const prefix = lib.translate[`${str}_prefix`]; + if (prefix && slimName.startsWith(prefix)) { + //兼容版特化处理 + if (lib.compatibleEdition) + return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)} `; + return `${get.prefixSpan(prefix, str)}${slimName.slice(prefix.length)}`; + } + return slimName; + } + /** + * @param {string} prefix + * @param {string} name + * @returns {string} + */ + prefixSpan(prefix, name) { + const config = lib.config.buttoncharacter_prefix; + if (config == "off") return ""; + if (config == "simple") { + const span = document.createElement("span"); + span.innerHTML = prefix; + return span.outerHTML; + } + const namePrefix = lib.namePrefix.get(prefix), + exists = Boolean(namePrefix); + if (exists && "getSpan" in namePrefix) return namePrefix.getSpan(prefix, name); + const span = document.createElement("span"); + if (exists) { + if ("color" in namePrefix) span.style.color = namePrefix.color; + if ("nature" in namePrefix) span.dataset.nature = namePrefix.nature; + if ("showName" in namePrefix) prefix = namePrefix.showName; + } else span.style.color = "#ffffff"; + span.innerHTML = prefix; + return span.outerHTML; + } + slimName(str) { + return 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; + } else { + return lib.getUTC(new Date()) - lib.getUTC(lib.status.date) - lib.status.dateDelayed; + } + } + utc() { + return 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(from, to) { + return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])); + } + /** + * @overload + * @returns { void } + */ + /** + * @overload + * @param { string } obj + * @returns { 'position' | 'natures' | 'nature' } + */ + /** + * @overload + * @param { Player[] } obj + * @returns { 'players' } + */ + /** + * @overload + * @param { Card[] } obj + * @returns { 'cards' } + */ + /** + * @overload + * @param { [number, number] } obj + * @returns { 'select' } + */ + /** + * @overload + * @param { [number, number, number, number] } obj + * @returns { 'divposition' } + */ + /** + * @overload + * @param { Button } obj + * @returns { 'button' } + */ + /** + * @overload + * @param { Card } obj + * @returns { 'card' } + */ + /** + * @overload + * @param { Player } obj + * @returns { 'player' } + */ + /** + * @overload + * @param { Dialog } obj + * @returns { 'dialog' } + */ + /** + * @overload + * @param { GameEvent | GameEventPromise } obj + * @returns { 'event' } + */ + itemtype(obj) { + if (typeof obj == "string") { + if (obj.length <= 5) { + let bool = true; + for (let i = 0; i < obj.length; i++) { + if (/h|e|j|s|x/.test(obj[i]) == false) { + bool = false; + break; + } + } + if (bool) return "position"; + } + if ( + obj.includes(lib.natureSeparator) && + obj.split(lib.natureSeparator).every((n) => lib.nature.has(n)) + ) + return "natures"; + if (lib.nature.has(obj)) return "nature"; + } + if (Array.isArray(obj) && obj.length > 0) { + if (obj.every((p) => p instanceof lib.element.Player)) return "players"; + if (obj.every((p) => p instanceof lib.element.Card)) return "cards"; + if (obj.length == 2) { + if (typeof obj[0] == "number" && typeof obj[1] == "number") { + if (obj[0] <= obj[1] || obj[1] <= -1) return "select"; + } + } + if (obj.length == 4) { + if (obj.every((p) => typeof p == "number")) { + return "divposition"; + } + } + } + if ( + obj instanceof lib.element.Button || + (obj instanceof HTMLDivElement && obj.classList.contains("button")) + ) + return "button"; + if (obj instanceof lib.element.Card) return "card"; + if (obj instanceof lib.element.Player) return "player"; + if (obj instanceof lib.element.Dialog) return "dialog"; + if (obj instanceof lib.element.GameEvent || obj instanceof lib.element.GameEventPromise) + return "event"; + + if (typeof obj !== "object" || obj === null) return; + + if (lib.experimental.symbol.itemType in obj) return obj[lib.experimental.symbol.itemType]; + } + equipNum(card) { + if (get.type(card) == "equip") { + return parseInt(get.subtype(card)[5]); + } + return 0; + } + objtype(obj) { + if (Object.prototype.toString.call(obj) === "[object Array]") return "array"; + if (Object.prototype.toString.call(obj) === "[object Object]") return "object"; + if (Object.prototype.toString.call(obj) === "[object HTMLDivElement]") return "div"; + if (Object.prototype.toString.call(obj) === "[object HTMLTableElement]") return "table"; + if (Object.prototype.toString.call(obj) === "[object HTMLTableRowElement]") return "tr"; + if (Object.prototype.toString.call(obj) === "[object HTMLTableCellElement]") return "td"; + if (Object.prototype.toString.call(obj) === "[object HTMLBodyElement]") return "td"; + if (Object.prototype.toString.call(obj) === "[object DocumentFragment]") return "fragment"; + } + type(obj, method, player) { + if (typeof obj == "string") obj = { name: obj }; + if (typeof obj != "object") return; + var name = get.name(obj, player); + if (!lib.card[name]) { + if (!name.startsWith("sha_")) return; + if ( + name + .slice(4) + .split("_") + .every((n) => lib.nature.has(n)) + ) + return lib.card["sha"].type; + } + if (method == "trick" && lib.card[name].type == "delay") return "trick"; + return lib.card[name].type; + } + type2(card, player) { + return get.type(card, "trick", player); + } + /** + * + * @param { string | Card | VCard | CardBaseUIData } obj + * @param { false | Player } [player] + * @returns { string } + */ + subtype(obj, player) { + if (typeof obj == "string") obj = { name: obj }; + if (typeof obj != "object") return; + const name = get.name(obj, player); + if (!lib.card[name]) return; + let subtype = lib.card[name].subtype; + return subtype; + } + equiptype(card, player) { + var subtype = get.subtype(card, player); + if (subtype.startsWith("equip")) return parseInt(subtype[5]); + return 0; + } + /** + * + * @param { Card | VCard | CardBaseUIData } card + * @param { false | Player } [player] + * @returns { string } + */ + name(card, player) { + if (get.itemtype(player) == "player" || (player !== false && get.position(card) == "h")) { + var owner = player || get.owner(card); + if (owner) { + return game.checkMod(card, owner, card.name, "cardname", owner); + } + } + return card.name; + } + /** + * @param {Card | VCard | Card[] | VCard[]} card + * @param {false | Player} [player] + * @returns {string} + */ + suit(card, player) { + if (typeof card !== "object") return; + if (Array.isArray(card)) { + if (card.length == 1) return get.suit(card[0], player); + return "none"; + } else if (!("suit" in card) && Array.isArray(card.cards)) { + return get.suit(card.cards, player); + } else { + if (player !== false) { + const owner = player || get.owner(card); + if (owner) { + return game.checkMod( + card, + owner, + game.checkMod(card, card.suit, "suit", owner), + "cardsuit", + owner + ); + } + } + if (card.suit === "unsure" || lib.suits.includes(card.suit)) return card.suit; + return "none"; + } + } + /** + * @param {Card | VCard | Card[] | VCard[]} card + * @param {false | Player} [player] + * @returns {string} + */ + color(card, player) { + if (typeof card !== "object") return; + if (Array.isArray(card)) { + if (!card.length) return "none"; + const cards = card.slice(), + color = get.color(cards.shift(), player); + for (const anotherCard of cards) { + if (get.color(anotherCard, player) != color) return "none"; + } + return color; + } else if (card.color === "unsure" || Object.keys(lib.color).includes(card.color)) { + return card.color; + } else if (Array.isArray(card.cards) && !lib.suit.includes(card.suit)) { + return get.color(card.cards, player); + } else { + const suit = get.suit(card, player); + for (const entry of Object.entries(lib.color)) { + if (entry[1].includes(suit)) return entry[0]; + } + return "none"; + } + } + /** + * @param {Card | VCard} card + * @param {false | Player} [player] + * @returns {number} + */ + number(card, player) { + if (typeof card !== "object") return; + //狗卡你是真敢出啊 + var number = null; + if ("number" in card) { + number = card.number; + if (number === "unsure") return number; + else if (typeof number != "number") number = null; + } else { + if (card.cards && card.cards.length == 1) number = get.number(card.cards[0], false); + } + if (player !== false) { + var owner = player || get.owner(card); + if (owner) { + return game.checkMod(card, owner, number, "cardnumber", owner); + } + } + return number; + } + /** + * 返回一张杀的属性。如有多种属性则用`lib.natureSeparator`分割开来。例:火雷【杀】的返回值为`fire|thunder` + * @param {string | string[] | Card | VCard} card + * @param {false | Player} [player] + * @returns {string} + */ + nature(card, player) { + if (typeof card == "string") + return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); + if (Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); + var nature = card.nature; + if (get.itemtype(player) == "player" || player !== false) { + var owner = get.owner(card); + if (owner) { + return game.checkMod(card, owner, nature, "cardnature", owner); + } + } + return nature; + } + /** + * 返回包含所有属性的数组 + * @param {string[] | string} card + * @param {false | Player} [player] + * @returns {string[]} + */ + natureList(card, player) { + if (!card) return []; + if (get.itemtype(card) == "natures") return card.split(lib.natureSeparator); + if (get.itemtype(card) == "nature") return [card]; + const natures = get.nature(card, player); + if (typeof natures != "string") return []; + return natures.split(lib.natureSeparator); + } + cards(num, putBack) { + if (_status.waitingForCards) { + ui.create.cards.apply(ui.create, _status.waitingForCards); + delete _status.waitingForCards; + } + var list = []; + var card = false; + if (typeof num != "number") num = 1; + if (num == 0) { + card = true; + num = 1; + } + if (num < 0) num = 1; + while (num--) { + if (ui.cardPile.hasChildNodes() == false) { + game.washCard(); + } + if (ui.cardPile.hasChildNodes() == false) { + game.over("平局"); + return []; + } + var cardx = ui.cardPile.removeChild(ui.cardPile.firstChild); + cardx.original = "c"; + list.push(cardx); + } + if (putBack) { + for (let i = list.length - 1; i >= 0; i--) { + ui.cardPile.insertBefore(list[i], ui.cardPile.firstChild); + } + } + game.updateRoundNumber(); + if (card) return list[0]; + return list; + } + judge(card) { + const cardInfo = card.viewAs ? lib.card[card.viewAs] : get.info(card); + return cardInfo && cardInfo.judge ? cardInfo.judge : () => 0; + } + judge2(card) { + return card.viewAs ? lib.card[card.viewAs].judge2 : get.info(card).judge2; + } + distance(from, to, method) { + if (from == to) return 0; + if (!game.players.includes(from) && !game.dead.includes(from)) return Infinity; + if (!game.players.includes(to) && !game.dead.includes(to)) return Infinity; + let n = 1; + if (game.chess) { + let fxy = from.getXY(), + txy = to.getXY(); + n = Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); + if (method == "raw" || method == "pure" || method == "absolute") return n; + } else if (to.isMin(true) || from.isMin(true)) { + if (method == "raw" || method == "pure" || method == "absolute") return n; + } else { + let player = from, + length = game.players.length; + const totalPopulation = game.players.length + game.dead.length + 1; + for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { + if (player.nextSeat != to) { + player = player.nextSeat; + if ( + player.isAlive() && + !player.isOut() && + !player.hasSkill("undist") && + !player.isMin(true) + ) + n++; + } else { + break; + } + } + for (let i = 0; i < game.players.length; i++) { + if ( + game.players[i].isOut() || + game.players[i].hasSkill("undist") || + game.players[i].isMin(true) + ) + length--; + } + if (method == "absolute") return n; + if (from.isDead()) length++; + if (to.isDead()) length++; + const left = from.hasSkillTag("left_hand"), + right = from.hasSkillTag("right_hand"); + if (left === right) n = Math.min(n, length - n); + else if (left == true) n = length - n; + if (method == "raw" || method == "pure") return n; + } + n = game.checkMod(from, to, n, "globalFrom", from); + n = game.checkMod(from, to, n, "globalTo", to); + const equips1 = from.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }), + equips2 = to.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + for (let i = 0; i < equips1.length; i++) { + let info = get.info(equips1[i]).distance; + if (!info) continue; + if (info.globalFrom) { + n += info.globalFrom; + } + } + for (let i = 0; i < equips2.length; i++) { + let info = get.info(equips2[i]).distance; + if (!info) continue; + if (info.globalTo) { + n += info.globalTo; + } + if (info.attackTo) { + m += info.attackTo; + } + } + if (method == "attack") { + let m = n; + m = game.checkMod(from, to, m, "attackFrom", from); + m = game.checkMod(from, to, m, "attackTo", to); + return m; + // const attakRange=from.getEquipRange(); + // m+=(1-attakRange); + // for(let i=0;iSelect) } [select] + * @returns { Select } + */ + select(select) { + if (typeof select == "function") return get.select(select()); + else if (typeof select == "number") return [select, select]; + else if (select && get.itemtype(select) == "select") return select; + return [1, 1]; + } + card(original) { + if (_status.event.skill) { + var card = get.info(_status.event.skill).viewAs; + if (typeof card == "function") card = card(ui.selected.cards, _status.event.player); + if (card) { + return get.autoViewAs(card, ui.selected.cards); + } + } + if (_status.event._get_card) { + return _status.event._get_card; + } + var card = ui.selected.cards[0]; + if (original) return card; + if (card) { + card = get.autoViewAs(card, ui.selected.cards); + } + return card; + } + /** + * @overload + * @returns {GameEvent} + */ + /** + * @template { keyof GameEvent } T + * @overload + * @param {T} key + * @returns {GameEvent[T]} + */ + event(key) { + return key ? _status.event[key] : _status.event; + } + player() { + return _status.event.player; + } + players(sort, dead, out) { + var players = game.players.slice(0); + if (sort != false) { + if (typeof sort == "function") players.sort(sort); + else players.sortBySeat(get.itemtype(sort) == "player" ? sort : _status.event.player); + } + if (dead) players = players.concat(game.dead); + if (!out) players = players.filter((current) => !current.isOut()); + return players; + } + position(card, ordering) { + if (get.itemtype(card) == "player") return parseInt(card.dataset.position); + if (card.timeout && card.destiny && card.destiny.classList) { + if (card.destiny.classList.contains("equips")) return "e"; + if (card.destiny.classList.contains("judges")) return "j"; + if (card.destiny.classList.contains("expansions")) return "x"; + if (card.destiny.classList.contains("handcards")) + return card.classList.contains("glows") ? "s" : "h"; + if (card.destiny.id == "cardPile") return "c"; + if (card.destiny.id == "discardPile") return "d"; + if (card.destiny.id == "special") return "s"; + if (card.destiny.id == "ordering") return ordering ? "o" : "d"; + return null; + } + if (!card.parentNode || !card.parentNode.classList) return; + if (card.parentNode.classList.contains("equips")) return "e"; + if (card.parentNode.classList.contains("judges")) return "j"; + if (card.parentNode.classList.contains("expansions")) return "x"; + if (card.parentNode.classList.contains("handcards")) + return card.classList.contains("glows") ? "s" : "h"; + if (card.parentNode.id == "cardPile") return "c"; + if (card.parentNode.id == "discardPile") return "d"; + if (card.parentNode.id == "special") return "s"; + if (card.parentNode.id == "ordering") return ordering ? "o" : "d"; + return null; + } + skillTranslation(str, player) { + var str2; + if (str.startsWith("re")) { + str2 = str.slice(2); + if (str2) { + if (lib.translate[str] == lib.translate[str2]) { + if (player.hasSkill(str2)) { + return "界" + lib.translate[str]; + } + } + } + } else if (str.startsWith("xin")) { + str2 = str.slice(3); + if (str2) { + if (lib.translate[str] == lib.translate[str2]) { + if (player.hasSkill(str2)) { + return "新" + lib.translate[str]; + } + } + } + } + return get.translation(str); + } + skillInfoTranslation(name, player) { + if (player && lib.dynamicTranslate[name]) return lib.dynamicTranslate[name](player, name); + var str = lib.translate[name + "_info"]; + if (!str) return ""; + return str; + // return str.replace(/锁定技/g,'锁定技'). + // replace(/限定技/g,'限定技'). + // replace(/觉醒技/g,'觉醒技'). + // replace(/主将技/g,'主将技'). + // replace(/副将技/g,'副将技'). + // replace(/阵法技/g,'阵法技'). + // replace(/主公技/g,'主公技'); + } + /** + * @returns {string} + */ + translation(str, arg) { + if (str && typeof str == "object" && (str.name || str._tempTranslate)) { + if (str._tempTranslate) return str._tempTranslate; + var str2; + if (arg == "viewAs" && str.viewAs) { + str2 = get.translation(str.viewAs); + } else { + str2 = get.translation(str.name); + } + if (str2 == "杀") { + str2 = ""; + if (typeof str.nature == "string") { + let natures = str.nature.split(lib.natureSeparator).sort(lib.sort.nature); + for (let nature of natures) { + str2 += lib.translate["nature_" + nature] || lib.translate[nature] || ""; + } + } + str2 += "杀"; + } + if (get.itemtype(str) == "card" || str.isCard) { + if (_status.cardtag && str.cardid) { + var tagstr = ""; + for (var i in _status.cardtag) { + if (_status.cardtag[i].includes(str.cardid)) { + tagstr += lib.translate[i + "_tag"]; + } + } + if (tagstr) { + str2 += "·" + tagstr; + } + } + if ((str.suit && str.number) || str.isCard) { + var cardnum = get.number(str, false) || ""; + if ([1, 11, 12, 13].includes(cardnum)) { + cardnum = { 1: "A", 11: "J", 12: "Q", 13: "K" }[cardnum]; + } + if (arg == "viewAs" && str.viewAs != str.name && str.viewAs) { + str2 += "(" + get.translation(str) + ")"; + } else { + str2 += "【" + get.translation(get.suit(str, false)) + cardnum + "】"; + // var len=str2.length-1; + // str2=str2.slice(0,len)+''+str2[len]+'·'+get.translation(str.suit)+str.number; + } + } + } + return str2; + } + if (Array.isArray(str)) { + var str2 = get.translation(str[0], arg); + for (var i = 1; i < str.length; i++) { + str2 += "、" + get.translation(str[i], arg); + } + return str2; + } + if (get.itemtype(str) == "natures") { + let natures = str.split(lib.natureSeparator).sort(lib.sort.nature); + var str2 = ""; + for (var nature of natures) { + str2 += lib.translate["nature_" + nature] || lib.translate[nature] || ""; + } + return str2; + } + if (arg == "skill") { + if (lib.translate[str + "_ab"]) return lib.translate[str + "_ab"]; + if (lib.translate[str]) return lib.translate[str].slice(0, 2); + return str; + } else if (arg == "info") { + if (lib.translate[str + "_info"]) return lib.translate[str + "_info"]; + var str2 = str.slice(0, str.length - 1); + if (lib.translate[str2 + "_info"]) return lib.translate[str2 + "_info"]; + if (str.lastIndexOf("_") > 0) { + str2 = str.slice(0, str.lastIndexOf("_")); + if (lib.translate[str2 + "_info"]) return lib.translate[str2 + "_info"]; + } + str2 = str.slice(0, str.length - 2); + if (lib.translate[str2 + "_info"]) return lib.translate[str2 + "_info"]; + if (lib.skill[str] && lib.skill[str].prompt) return lib.skill[str].prompt; + } + if (lib.translate[str]) { + return lib.translate[str]; + } + if (typeof str == "string") { + if (lib.translate["nature_" + str]) return lib.translate["nature_" + str]; + return str; + } + if (typeof str == "number" || typeof str == "boolean") { + return str.toString(); + } + if (str && str.toString) { + return str.toString(); + } + return ""; + } + menuZoom() { + if (game.menuZoom === undefined || game.menuZoom === null) { + return game.documentZoom; + } + return game.menuZoom; + } + strNumber(num) { + switch (num) { + case 1: + return "A"; + case 11: + return "J"; + case 12: + return "Q"; + case 13: + return "K"; + default: + return num.toString(); + } + } + cnNumber(num, ordinal) { + if (isNaN(num)) return ""; + let numStr = num.toString(); + if (numStr === "Infinity") return "∞"; + if (numStr === "-Infinity") return "-∞"; + if (!/^\d+$/.test(numStr)) return num; + + const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]; + const units = ["", "十", "百", "千"]; + + if (numStr.length <= 2) { + //两位数以下单独处理保证效率 + if (numStr.length === 1) return !ordinal && num === 2 ? "两" : chars[num]; + return `${numStr[0] === "1" ? "" : chars[numStr[0]]}十${ + numStr[1] === "0" ? "" : chars[numStr[1]] + }`; + } + + numStr = numStr + .replace(/(?=(\d{4})+$)/g, ",") + .split(",") + .filter(Boolean); + const handleZero = (str) => { + let result = str.replace(/零{2,}/g, "零"); + if (result.length > 1) result = result.replace(/零+$/g, ""); + return result; + }; + const _transform = (str) => { + if (str === "2" && !ordinal) return "两"; + let result = ""; + for (let i = 0; i < str.length; i++) { + const part = str[str.length - 1 - i]; + let char = chars[+part]; + let unit = units[i]; + if (char === "零") unit = ""; + else if (char === "一" && i === 1 && str.length === 2) char = ""; + else if (char === "二" && i > 1 && !ordinal) char = "两"; + result = char + unit + result; + } + result = handleZero(result); + return result; + }; + let result = ""; + let tempYi = ""; + for (let i = 0; i < numStr.length; i++) { + const part = numStr[numStr.length - 1 - i]; + let char = _transform(part); + let unit = ""; + if (i % 2) { + [unit, tempYi] = ["万" + tempYi, ""]; + if (char === "零") unit = ""; + } else { + unit = "亿".repeat(i / 2); + if (char === "零") [unit, tempYi] = ["", unit]; + } + result = char + unit + result; + } + result = handleZero(result); + return result; + } + /** + * 遍历子元素 + * @param {HTMLElement} node + * @returns {Iterable} 迭代器 + */ + *iterableChildNodes(node) { + for (let i = 0; i < arguments.length; i++) { + let arg = arguments[i]; + for (let j = 0; j < arg.childElementCount; j++) { + yield arg.childNodes[j]; + } + } + } + /** + * @param {((a: Button, b: Button) => number)} [sort] 排序函数 + * @returns { Button[] } + */ + selectableButtons(sort) { + if (!_status.event.player) return []; + var buttons = _status.event.dialog.buttons; + var selectable = []; + for (var i = 0; i < buttons.length; i++) { + if ( + buttons[i].classList.contains("selectable") && + buttons[i].classList.contains("selected") == false + ) { + selectable.push(buttons[i]); + } + } + if (sort) { + selectable.sort(sort); + } + return selectable; + } + /** + * @param {((a: Card, b: Card) => number)} [sort] 排序函数 + * @returns { Card[] } + */ + selectableCards(sort) { + if (!_status.event.player) return []; + var cards = _status.event.player.getCards("hes"); + var selectable = []; + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].classList.contains("selectable") && + cards[i].classList.contains("selected") == false + ) { + selectable.push(cards[i]); + } + } + if (sort) { + selectable.sort(sort); + } + return selectable; + } + /** + * @returns { string[] } 技能名数组 + */ + skills() { + var skills = []; + if (ui.skills) { + skills = skills.concat(ui.skills.skills); + } + if (ui.skills2) { + skills = skills.concat(ui.skills2.skills); + } + if (ui.skills3) { + skills = skills.concat(ui.skills3.skills); + } + return skills; + } + gainableSkills(func, player) { + var list = []; + for (var i in lib.character) { + if (lib.filter.characterDisabled(i)) continue; + if (lib.filter.characterDisabled2(i)) continue; + if (lib.character[i][4]) { + if (lib.character[i][4].includes("boss")) continue; + if (lib.character[i][4].includes("hiddenboss")) continue; + if (lib.character[i][4].includes("minskin")) continue; + if (lib.character[i][4].includes("unseen")) continue; + } + for (var j = 0; j < lib.character[i][3].length; j++) { + var skill = lib.character[i][3][j]; + var info = lib.skill[skill]; + if (lib.filter.skillDisabled(skill)) continue; + if (func && !func(info, skill, i)) continue; + if (player && player.hasSkill && info.ai && info.ai.combo && !player.hasSkill(info.ai.combo)) + continue; + list.add(skill); + } + } + return list; + } + gainableSkillsName(name, func) { + var list = []; + if (name && lib.character[name]) { + if (lib.character[name][4]) { + if (lib.character[name][4].includes("boss")) return list; + if (lib.character[name][4].includes("hiddenboss")) return list; + if (lib.character[name][4].includes("minskin")) return list; + if (lib.character[name][4].includes("unseen")) return list; + } + for (var j = 0; j < lib.character[name][3].length; j++) { + var skill = lib.character[name][3][j]; + var info = lib.skill[skill]; + if (lib.filter.skillDisabled(skill)) continue; + if (func && !func(info, skill, name)) continue; + list.add(skill); + } + } + return list; + } + gainableCharacters(func) { + var list = []; + for (var i in lib.character) { + var info = lib.character[i]; + if (!info) continue; + if (typeof func == "function" && !func(info, i)) continue; + if (lib.filter.characterDisabled(i)) continue; + if (lib.filter.characterDisabled2(i)) continue; + list.push(i); + } + if (func === true) { + var players = game.players.concat(game.dead); + for (var i = 0; i < players.length; i++) { + list.remove(players[i].name); + list.remove(players[i].name1); + list.remove(players[i].name2); + } + } + return list; + } + /** + * @param {((a: Player, b: Player) => number)} [sort] 排序函数 + * @returns { Player[] } + */ + selectableTargets(sort) { + var selectable = []; + var players = game.players.slice(0); + if (_status.event.deadTarget) players.addArray(game.dead); + for (var i = 0; i < players.length; i++) { + if ( + players[i].classList.contains("selectable") && + players[i].classList.contains("selected") == false + ) { + selectable.push(players[i]); + } + } + selectable.randomSort(); + if (sort) { + selectable.sort(sort); + } + return selectable; + } + filter(filter, i) { + if (typeof filter == "function") return filter; + if (i == undefined) i = 0; + var result = function () { + if (filter == arguments[i]) return true; + for (var j in filter) { + if (Object.prototype.hasOwnProperty.call(filter, j)) { + if (get.itemtype(arguments[i]) == "card") { + if (j == "name") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.name(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.name(arguments[i]) != filter[j]) return false; + } + } else if (j == "type") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.type(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.type(arguments[i]) != filter[j]) return false; + } + } else if (j == "subtype") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.subtype(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.subtype(arguments[i]) != filter[j]) return false; + } + } else if (j == "color") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.color(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.color(arguments[i]) != filter[j]) return false; + } + } else if (j == "suit") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.suit(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.suit(arguments[i]) != filter[j]) return false; + } + } else if (j == "number") { + if (Array.isArray(filter[j])) { + if (filter[j].includes(get.number(arguments[i])) == false) return false; + } else if (typeof filter[j] == "string") { + if (get.number(arguments[i]) != filter[j]) return false; + } + } else if (Array.isArray(filter[j])) { + if (filter[j].includes(arguments[i][j]) == false) return false; + } else if (typeof filter[j] == "string") { + if (arguments[i][j] != filter[j]) return false; + } + } else { + if (arguments[i][j] != filter[j]) return false; + } + } + } + return true; + }; + result._filter_args = [filter, i]; + return result; + } + cardCount(card, player) { + var num; + if (player == undefined) player = _status.event.player; + if (card == true) { + num = 0; + var stat = player.getStat("card"); + for (var i in stat) { + if (typeof stat[i] == "number") num += stat[i]; + } + return num; + } + if (typeof card == "object") { + card = card.name; + } + num = player.getStat("card")[card]; + if (num == undefined) return 0; + return num; + } + skillCount(skill, player) { + if (player == undefined) player = _status.event.player; + var num = player.getStat("skill")[skill]; + if (num == undefined) return 0; + return num; + } + owner(card, method) { + return game.players.concat(game.dead).find((current) => { + if (current.judging[0] == card && method != "judge") return true; + let parent = card.parentNode; + if (parent == current.node.handcards1 || parent == current.node.handcards2) { + return !card.classList.contains("removing"); + } else if (parent == current.node.equips) { + return !card.classListContains("removing", "feichu", "emptyequip"); + } else if (parent == current.node.judges) { + return !card.classListContains("removing", "feichu"); + } else if (parent == current.node.expansions) { + return !card.classListContains("removing"); + } + return false; + }); + //return game.players.concat(game.dead).find(current => + // current.getCards("hejsx").includes(card) || (current.judging[0] == card && method != "judge")); + } + noSelected() { + return ui.selected.buttons.length + ui.selected.cards.length + ui.selected.targets.length == 0; + } + population(identity) { + return identity == undefined + ? game.players.length + game.dead.length + : game.players.filter((current) => current.identity == identity).length; + } + totalPopulation(identity) { + return identity == undefined + ? game.players.length + game.dead.length + : game.players.concat(game.dead).filter((current) => current.identity == identity).length; + } + /** + * @param { Card | VCard } item + */ + cardtag(item, tag) { + return ( + (item.cardid && + (get.itemtype(item) == "card" || + !item.cards || + !item.cards.length || + item.name == item.cards[0].name) && + _status.cardtag && + _status.cardtag[tag] && + _status.cardtag[tag].includes(item.cardid)) || + (item.cardtags && item.cardtags.includes(tag)) + ); + } + tag(item, tag, item2, bool) { + var result; + if (get.info(item, bool) && get.info(item, bool).ai && get.info(item, bool).ai.tag) { + result = get.info(item, bool).ai.tag[tag]; + } + if (typeof result == "function") return result(item, item2); + return result; + } + sortCard(sort) { + var func; + if (sort == "type_sort") { + func = function (card) { + var type = get.type(card, null, false); + var subtype = get.subtype(card, false); + if (lib.cardType[subtype]) { + return lib.cardType[subtype]; + } + if (lib.cardType[type]) { + return lib.cardType[type]; + } + switch (type) { + case "basic": + return 2; + case "chess": + return 1.5; + case "trick": + return -1; + case "delay": + return -2; + case "equip": + return -3; + default: + return -4; + } + }; + } else if (sort == "suit_sort") { + func = function (card) { + if (get.suit(card) == "heart") return 2; + if (get.suit(card) == "diamond") return 1; + if (get.suit(card) == "spade") return -1; + if (get.suit(card) == "club") return -2; + }; + } else if (sort == "number_sort") { + func = function (card) { + return get.number(card) - 7 + 0.5; + }; + } + return func; + } + difficulty() { + switch (get.config("difficulty")) { + case "easy": + return 1; + case "normal": + return 2; + case "hard": + return 3; + default: + return 1; + } + } + cardPile(name, create) { + var filter = function (card) { + if (typeof name == "string") { + if (card.name == name) { + return true; + } + } else if (typeof name == "function") { + if (name(card)) { + return true; + } + } + return false; + }; + if (create != "discardPile") { + var num = get.rand(0, ui.cardPile.childNodes.length - 1); + for (var i = 0; i < ui.cardPile.childNodes.length; i++) { + var j = i; + if (j >= ui.cardPile.childNodes.length) j -= ui.cardPile.childNodes.length; + if (filter(ui.cardPile.childNodes[j])) { + return ui.cardPile.childNodes[j]; + } + } + } + if (create != "cardPile") { + for (var i = 0; i < ui.discardPile.childNodes.length; i++) { + var j = i; + if (j >= ui.discardPile.childNodes.length) j -= ui.discardPile.childNodes.length; + if (filter(ui.discardPile.childNodes[j])) { + return ui.discardPile.childNodes[j]; + } + } + } + if (create == "field") { + var found = null; + game.findPlayer(function (current) { + var ej = current.getCards("ej"); + for (var i = 0; i < ej.length; i++) { + if (filter(ej[i])) { + found = ej[i]; + return true; + } + } + }); + return found; + } + if (create && !["cardPile", "discardPile", "field"].includes(create)) { + return game.createCard(name); + } + return null; + } + cardPile2(name) { + return get.cardPile(name, "cardPile"); + } + discardPile(name) { + return get.cardPile(name, "discardPile"); + } + aiStrategy() { + switch (get.config("ai_strategy")) { + case "ai_strategy_1": + return 1; + case "ai_strategy_2": + return 2; + case "ai_strategy_3": + return 3; + case "ai_strategy_4": + return 4; + case "ai_strategy_5": + return 5; + case "ai_strategy_6": + return 6; + default: + return 1; + } + } + skillintro(name, learn, learn2) { + var str = ""; + var infoitem = lib.character[name]; + if (!infoitem) { + for (var itemx in lib.characterPack) { + if (lib.characterPack[itemx][name]) { + infoitem = lib.characterPack[itemx][name]; + break; + } + } + } + var skills = infoitem[3]; + var opacity; + for (var i = 0; i < skills.length; i++) { + if (lib.translate[skills[i]] && lib.translate[skills[i] + "_info"] && lib.skill[skills[i]]) { + if (learn && lib.skill[skills[i]].unique && (learn2 || !lib.skill[skills[i]].gainable)) { + opacity = "opacity:0.5"; + } else { + opacity = ""; + } + var skilltrans = get.translation(skills[i]).slice(0, 2); + str += + '
                                    【' + + skilltrans + + '】
                                    ' + + get.skillInfoTranslation(skills[i]) + + '
                                    '; + } + } + return str; + } + intro(name) { + var info = lib.character[name]; + var str = "性别:" + get.translation(info[0]) + "
                                    "; + str += "势力:" + get.translation(info[1]) + "
                                    "; + str += "体力:" + get.translation(info[2]) + "
                                    "; + str += "技能:"; + if (info[3].length) { + str += get.translation(info[3][0]); + for (var i = 1; i < info[3].length; i++) { + str += "、" + get.translation(info[3][i]); + } + } + return str; + } + storageintro(type, content, player, dialog, skill) { + switch (type) { + case "mark": { + if (content > 0) { + return "共有" + content + "个标记"; + } + return false; + } + case "turn": { + if (content > 0) { + return "剩余" + content + "个回合"; + } + return false; + } + case "time": { + if (content > 0) { + return "剩余" + content + "次"; + } + return false; + } + case "limited": { + if (content) { + return "已发动"; + } + return "未发动"; + } + case "info": { + return lib.translate[skill + "_info"]; + } + case "cardCount": { + if (Array.isArray(content)) { + return "共有" + get.cnNumber(content.length) + "张牌"; + } + return false; + } + case "expansion": { + content = player.getCards("x", function (card) { + return card.hasGaintag(skill); + }); + if (dialog && content.length) { + dialog.addAuto(content); + } else { + return "没有卡牌"; + } + return false; + } + case "card": + case "cards": { + if (get.itemtype(content) == "card") { + content = [content]; + } + if (dialog && get.itemtype(content) == "cards") { + dialog.addAuto(content); + } else { + if (content && content.length) { + return get.translation(content); + } + } + if (Array.isArray(content) && !content.length) { + return "没有卡牌"; + } + return false; + } + case "player": + case "players": { + if (get.itemtype(content) == "player") { + content = [content]; + } + if (dialog && get.itemtype(content) == "players") { + dialog.addAuto(content); + return false; + } else { + if (content && content.length) { + return get.translation(content); + } + return false; + } + } + case "character": + case "characters": { + if (typeof content == "string") { + content = [content]; + } + if (dialog && Array.isArray(content)) { + dialog.addAuto([content, "character"]); + return false; + } else { + if (content && content.length) { + return get.translation(content); + } + return false; + } + } + default: { + if (typeof type == "string") { + type = type.replace(/#/g, content); + type = type.replace(/&/g, get.cnNumber(content)); + type = type.replace(/\$/g, get.translation(content)); + return type; + } else if (typeof type == "function") { + return type(content, player, skill); + } + return false; + } + } + } + nodeintro(node, simple, evt) { + var uiintro = ui.create.dialog("hidden", "notouchscroll"); + if (node.classList.contains("player") && !node.name) { + return uiintro; + } + var i, translation, intro, str; + if (node._nointro) return; + if (typeof node._customintro == "function") { + if (node._customintro(uiintro, evt) === false) return; + if (evt) lib.placePoppedDialog(uiintro, evt); + } else if (Array.isArray(node._customintro)) { + var caption = node._customintro[0]; + var content = node._customintro[1]; + if (typeof caption == "function") { + caption = caption(node); + } + if (typeof content == "function") { + content = content(node); + } + uiintro.add(caption); + uiintro.add('
                                    ' + content + "
                                    "); + } else if (node.classList.contains("player") || node.linkplayer) { + if (node.linkplayer) { + node = node.link; + } + let capt = get.translation(node.name); + const characterInfo = get.character(node.name), + sex = node.sex || characterInfo[0]; + if (sex && sex != "unknown" && lib.config.show_sex) + capt += `  ${sex == "none" ? "无" : get.translation(sex)}`; + const group = node.group; + if (group && group != "unknown" && lib.config.show_group) + capt += `  ${get.translation(group)}`; + uiintro.add(capt); + + if (lib.characterTitle[node.name]) { + uiintro.addText(get.colorspan(lib.characterTitle[node.name])); + } + + if (get.characterInitFilter(node.name)) { + const initFilters = get.characterInitFilter(node.name).filter((tag) => { + if (!lib.characterInitFilter[node.name]) return true; + return lib.characterInitFilter[node.name](tag) !== false; + }); + if (initFilters.length) { + const str = initFilters + .reduce((strx, stry) => strx + lib.InitFilter[stry] + "
                                    ", "") + .slice(0, -4); + uiintro.addText(str); + } + } + + if (!node.noclick) { + const allShown = + node.isUnderControl() || + (!game.observe && game.me && game.me.hasSkillTag("viewHandcard", null, node, true)); + const shownHs = node.getShownCards(); + if (shownHs.length) { + uiintro.add('
                                    明置的手牌
                                    '); + uiintro.addSmall(shownHs); + if (allShown) { + var hs = node.getCards("h"); + hs.removeArray(shownHs); + if (hs.length) { + uiintro.add('
                                    其他手牌
                                    '); + uiintro.addSmall(hs); + } + } + } else if (allShown) { + var hs = node.getCards("h"); + if (hs.length) { + uiintro.add('
                                    手牌
                                    '); + uiintro.addSmall(hs); + } + } + } + + var skills = node.getSkills(null, false, false).slice(0); + var skills2 = game.filterSkills(skills, node); + if (node == game.me && node.hiddenSkills.length) { + skills.addArray(node.hiddenSkills); + } + for (var i in node.disabledSkills) { + if ( + node.disabledSkills[i].length == 1 && + node.disabledSkills[i][0] == i + "_awake" && + !node.hiddenSkills.includes(i) + ) { + skills.add(i); + } + } + for (i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]] && (lib.skill[skills[i]].nopop || lib.skill[skills[i]].equipSkill)) + continue; + if (lib.translate[skills[i] + "_info"]) { + if (lib.translate[skills[i] + "_ab"]) translation = lib.translate[skills[i] + "_ab"]; + else { + translation = get.translation(skills[i]); + if (!lib.skill[skills[i]].nobracket) translation = `【${translation.slice(0, 2)}】`; + } + + if (node.forbiddenSkills[skills[i]]) { + var forbidstr = + '
                                    ' + translation + "
                                    "; + if (node.forbiddenSkills[skills[i]].length) { + forbidstr += + "(与" + get.translation(node.forbiddenSkills[skills[i]]) + "冲突)
                                    "; + } else { + forbidstr += "(双将禁用)
                                    "; + } + forbidstr += get.skillInfoTranslation(skills[i], node) + "
                                    "; + uiintro.add(forbidstr); + } else if (!skills2.includes(skills[i])) { + if (lib.skill[skills[i]].preHidden && get.mode() == "guozhan") { + uiintro.add( + '
                                    ' + + translation + + '
                                    ' + + get.skillInfoTranslation(skills[i], node) + + '
                                    预亮技能
                                    ' + ); + var underlinenode = uiintro.content.lastChild.querySelector(".underlinenode"); + if (_status.prehidden_skills.includes(skills[i])) { + underlinenode.classList.remove("on"); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.hiddenskill); + } else + uiintro.add( + '
                                    ' + + translation + + "
                                    " + + get.skillInfoTranslation(skills[i], node) + + "
                                    " + ); + } else if ( + lib.skill[skills[i]].temp || + !node.skills.includes(skills[i]) || + lib.skill[skills[i]].thundertext + ) { + if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { + uiintro.add( + '
                                    ' + + translation + + '
                                    ' + + get.skillInfoTranslation(skills[i], node) + + '
                                    自动发动
                                    ' + ); + var underlinenode = uiintro.content.lastChild.querySelector(".underlinenode"); + if (lib.skill[skills[i]].frequent) { + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove("on"); + } + } + if (lib.skill[skills[i]].subfrequent) { + for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { + if ( + lib.config.autoskilllist.includes( + skills[i] + "_" + lib.skill[skills[i]].subfrequent[j] + ) + ) { + underlinenode.classList.remove("on"); + } + } + } + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove("on"); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.autoskill2); + } else { + uiintro.add( + '
                                    ' + + translation + + '
                                    ' + + get.skillInfoTranslation(skills[i], node) + + "
                                    " + ); + } + } else if (lib.skill[skills[i]].frequent || lib.skill[skills[i]].subfrequent) { + uiintro.add( + '
                                    ' + + translation + + "
                                    " + + get.skillInfoTranslation(skills[i], node) + + '
                                    自动发动
                                    ' + ); + var underlinenode = uiintro.content.lastChild.querySelector(".underlinenode"); + if (lib.skill[skills[i]].frequent) { + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove("on"); + } + } + if (lib.skill[skills[i]].subfrequent) { + for (var j = 0; j < lib.skill[skills[i]].subfrequent.length; j++) { + if ( + lib.config.autoskilllist.includes( + skills[i] + "_" + lib.skill[skills[i]].subfrequent[j] + ) + ) { + underlinenode.classList.remove("on"); + } + } + } + if (lib.config.autoskilllist.includes(skills[i])) { + underlinenode.classList.remove("on"); + } + underlinenode.link = skills[i]; + underlinenode.listen(ui.click.autoskill2); + } else if (lib.skill[skills[i]].clickable && node.isIn() && node.isUnderControl(true)) { + var intronode = uiintro + .add( + '
                                    ' + + translation + + "
                                    " + + get.skillInfoTranslation(skills[i], node) + + '
                                    ' + ) + .querySelector(".skillbutton"); + if ( + !_status.gameStarted || + (lib.skill[skills[i]].clickableFilter && + !lib.skill[skills[i]].clickableFilter(node)) + ) { + intronode.classList.add("disabled"); + intronode.style.opacity = 0.5; + } else { + intronode.link = node; + intronode.func = lib.skill[skills[i]].clickable; + intronode.classList.add("pointerdiv"); + intronode.listen(ui.click.skillbutton); + } + } else { + uiintro.add( + '
                                    ' + + translation + + "
                                    " + + get.skillInfoTranslation(skills[i], node) + + "
                                    " + ); + } + if (lib.translate[skills[i] + "_append"]) { + uiintro._place_text = uiintro.add( + '
                                    ' + lib.translate[skills[i] + "_append"] + "
                                    " + ); + } + } + } + // if(get.is.phoneLayout()){ + // var storage=node.storage; + // for(i in storage){ + // if(get.info(i)&&get.info(i).intro){ + // intro=get.info(i).intro; + // if(node.getSkills().concat(lib.skill.global).includes(i)==false&&!intro.show) continue; + // var name=intro.name?intro.name:get.translation(i); + // if(typeof name=='function'){ + // name=name(storage[i],node); + // } + // translation='
                                    『'+name.slice(0,2)+'』
                                    '; + // var stint=get.storageintro(intro.content,storage[i],node,null,i); + // if(stint){ + // translation+=stint+'
                                    '; + // uiintro.add(translation); + // } + // } + // } + // } + + if (lib.config.right_range && _status.gameStarted) { + uiintro.add(ui.create.div(".placeholder")); + var table, tr, td; + table = document.createElement("table"); + tr = document.createElement("tr"); + table.appendChild(tr); + td = document.createElement("td"); + td.innerHTML = "距离"; + tr.appendChild(td); + td = document.createElement("td"); + td.innerHTML = "手牌"; + tr.appendChild(td); + td = document.createElement("td"); + td.innerHTML = "行动"; + tr.appendChild(td); + td = document.createElement("td"); + td.innerHTML = "伤害"; + tr.appendChild(td); + + tr = document.createElement("tr"); + table.appendChild(tr); + td = document.createElement("td"); + if (node == game.me || !game.me || !game.me.isIn()) { + td.innerHTML = "-"; + } else { + var dist1 = get.numStr(Math.max(1, game.me.distanceTo(node))); + var dist2 = get.numStr(Math.max(1, node.distanceTo(game.me))); + if (dist1 == dist2) { + td.innerHTML = dist1; + } else { + td.innerHTML = dist1 + "/" + dist2; + } + } + tr.appendChild(td); + td = document.createElement("td"); + let handcardLimit = node.getHandcardLimit(); + td.innerHTML = `${node.countCards("h")}/${handcardLimit >= 114514 ? "∞" : handcardLimit}`; + tr.appendChild(td); + td = document.createElement("td"); + td.innerHTML = node.phaseNumber; + tr.appendChild(td); + td = document.createElement("td"); + + (function () { + num = 0; + for (var j = 0; j < node.stat.length; j++) { + if (typeof node.stat[j].damage == "number") num += node.stat[j].damage; + } + td.innerHTML = num; + })(); + tr.appendChild(td); + table.style.width = "calc(100% - 20px)"; + table.style.marginLeft = "10px"; + + uiintro.content.appendChild(table); + if (!lib.config.show_favourite) { + table.style.paddingBottom = "5px"; + } + } + if (!simple || get.is.phoneLayout()) { + var es = node.getCards("e"); + for (var i = 0; i < es.length; i++) { + var cardinfo = lib.card[es[i].name]; + if (cardinfo && cardinfo.cardPrompt) + uiintro.add( + '
                                    ' + + es[i].outerHTML + + "
                                    " + + cardinfo.cardPrompt(es[i]) + + "
                                    " + ); + else + uiintro.add( + '
                                    ' + + es[i].outerHTML + + "
                                    " + + lib.translate[es[i].name + "_info"] + + "
                                    " + ); + uiintro.content.lastChild.querySelector(".skill>.card").style.transform = ""; + + if (lib.translate[es[i].name + "_append"]) { + uiintro.add('
                                    ' + lib.translate[es[i].name + "_append"] + "
                                    "); + } + } + var js = node.getCards("j"); + for (var i = 0; i < js.length; i++) { + if (js[i].viewAs && js[i].viewAs != js[i].name) { + let html = js[i].outerHTML; + let cardInfo = lib.card[js[i].viewAs], + showCardIntro = true; + if (cardInfo.blankCard) { + var cardOwner = get.owner(js[i]); + if (cardOwner && !cardOwner.isUnderControl(true)) showCardIntro = false; + } + if (!showCardIntro) { + html = ui.create.button(js[i], "blank").outerHTML; + } + uiintro.add( + '
                                    ' + + html + + "
                                    " + + lib.translate[js[i].viewAs] + + ":" + + lib.translate[js[i].viewAs + "_info"] + + "
                                    " + ); + } else { + uiintro.add( + '
                                    ' + + js[i].outerHTML + + "
                                    " + + lib.translate[js[i].name + "_info"] + + "
                                    " + ); + } + uiintro.content.lastChild.querySelector(".skill>.card").style.transform = ""; + } + if (get.is.phoneLayout()) { + var markCoutainer = ui.create.div(".mark-container.marks"); + for (var i in node.marks) { + var nodemark = node.marks[i].cloneNode(true); + nodemark.classList.add("pointerdiv"); + nodemark.link = node.marks[i]; + nodemark.style.transform = ""; + markCoutainer.appendChild(nodemark); + nodemark.listen(function () { + uiintro.noresume = true; + var rect = this.link.getBoundingClientRect(); + ui.click.intro.call(this.link, { + clientX: rect.left + rect.width, + clientY: rect.top + rect.height / 2, + }); + if (lib.config.touchscreen) { + uiintro._close(); + } + }); + } + if (markCoutainer.childElementCount) { + uiintro.addText("标记"); + uiintro.add(markCoutainer); + } + } + } + if (!game.observe && _status.gameStarted && game.me && node != game.me) { + ui.throwEmotion = []; + uiintro.addText("发送交互表情"); + var click = function () { + if (_status.dragged) return; + if (_status.justdragged) return; + if (_status.throwEmotionWait) return; + var emotion = this.link; + if (game.online) { + game.send("throwEmotion", node, emotion); + } else game.me.throwEmotion(node, emotion); + uiintro._close(); + _status.throwEmotionWait = true; + setTimeout( + function () { + _status.throwEmotionWait = false; + if (ui.throwEmotion) { + for (var i of ui.throwEmotion) i.classList.remove("exclude"); + } + }, + emotion == "flower" || emotion == "egg" ? 500 : 5000 + ); + }; + var td; + var table = document.createElement("div"); + table.classList.add("add-setting"); + table.style.margin = "0"; + table.style.width = "100%"; + table.style.position = "relative"; + var listi = ["flower", "egg"]; + for (var i = 0; i < listi.length; i++) { + td = ui.create.div(".menubutton.reduce_radius.pointerdiv.tdnode"); + ui.throwEmotion.add(td); + if (_status.throwEmotionWait) td.classList.add("exclude"); + td.link = listi[i]; + table.appendChild(td); + td.innerHTML = "" + get.translation(listi[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", click); + } + uiintro.content.appendChild(table); + table = document.createElement("div"); + table.classList.add("add-setting"); + table.style.margin = "0"; + table.style.width = "100%"; + table.style.position = "relative"; + var listi = ["wine", "shoe"]; + if (game.me.storage.zhuSkill_shanli) listi = ["yuxisx", "jiasuo"]; + for (var i = 0; i < listi.length; i++) { + td = ui.create.div(".menubutton.reduce_radius.pointerdiv.tdnode"); + ui.throwEmotion.add(td); + if (_status.throwEmotionWait) td.classList.add("exclude"); + td.link = listi[i]; + table.appendChild(td); + td.innerHTML = "" + get.translation(listi[i]) + ""; + td.addEventListener(lib.config.touchscreen ? "touchend" : "click", click); + } + uiintro.content.appendChild(table); + } + var modepack = lib.characterPack["mode_" + get.mode()]; + if ( + lib.config.show_favourite && + lib.character[node.name] && + game.players.includes(node) && + (!modepack || !modepack[node.name]) && + (!simple || get.is.phoneLayout()) + ) { + var addFavourite = ui.create.div(".text.center.pointerdiv"); + addFavourite.link = node.name; + if (lib.config.favouriteCharacter.includes(node.name)) { + addFavourite.innerHTML = "移除收藏"; + } else { + addFavourite.innerHTML = "添加收藏"; + } + addFavourite.listen(ui.click.favouriteCharacter); + uiintro.add(addFavourite); + } + if (!simple || get.is.phoneLayout()) { + if ((lib.config.change_skin || lib.skin) && !node.isUnseen()) { + var num = 1; + var introadded = false; + var createButtons = function (num, avatar2) { + if (!introadded) { + introadded = true; + uiintro.add('
                                    更改皮肤
                                    '); + } + var buttons = ui.create.div(".buttons.smallzoom.scrollbuttons"); + lib.setMousewheel(buttons); + var nameskin = avatar2 ? node.name2 : node.name1; + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith("gz_shibing")) { + nameskin = nameskin.slice(3, 11); + } else if (nameskin.startsWith("gz_")) { + nameskin = nameskin.slice(3); + gzbool = true; + } + for (var i = 0; i <= num; i++) { + var button = ui.create.div(".button.character.pointerdiv", buttons, function () { + if (this._link) { + if (avatar2) { + lib.config.skin[nameskin] = this._link; + node.node.avatar2.style.backgroundImage = this.style.backgroundImage; + } else { + lib.config.skin[nameskin] = this._link; + node.node.avatar.style.backgroundImage = this.style.backgroundImage; + } + } else { + delete lib.config.skin[nameskin]; + if (avatar2) { + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + node.node.avatar2.setBackground(nameskin2, "character"); + else node.node.avatar2.setBackground(nameskin, "character"); + } else { + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + node.node.avatar.setBackground(nameskin2, "character"); + else node.node.avatar.setBackground(nameskin, "character"); + } + } + game.saveConfig("skin", lib.config.skin); + }); + button._link = i; + if (i) { + button.setBackgroundImage("image/skin/" + nameskin + "/" + i + ".jpg"); + } else { + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + button.setBackground(nameskin2, "character", "noskin"); + else button.setBackground(nameskin, "character", "noskin"); + } + } + uiintro.add(buttons); + }; + var loadImage = function (avatar2) { + var img = new Image(); + img.onload = function () { + num++; + loadImage(avatar2); + }; + img.onerror = function () { + num--; + if (num) { + createButtons(num, avatar2); + } + if (!avatar2) { + if (!node.classList.contains("unseen2") && node.name2) { + num = 1; + loadImage(true); + } + } + }; + var nameskin = avatar2 ? node.name2 : node.name1; + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith("gz_shibing")) { + nameskin = nameskin.slice(3, 11); + } else if (nameskin.startsWith("gz_")) { + nameskin = nameskin.slice(3); + gzbool = true; + } + img.src = lib.assetURL + "image/skin/" + nameskin + "/" + num + ".jpg"; + }; + if (lib.config.change_skin) { + if (!node.isUnseen(0)) { + loadImage(); + } else if (node.name2) { + loadImage(true); + } + } else { + setTimeout(function () { + var nameskin1 = node.name1; + var nameskin2 = node.name2; + if (nameskin1 && nameskin1.startsWith("gz_")) { + nameskin1 = nameskin1.slice(3); + } + if (nameskin2 && nameskin2.startsWith("gz_")) { + nameskin2 = nameskin2.slice(3); + } + if (!node.isUnseen(0) && lib.skin[nameskin1]) { + createButtons(lib.skin[nameskin1]); + } + if (!node.isUnseen(1) && lib.skin[nameskin2]) { + createButtons(lib.skin[nameskin2], true); + } + }); + } + } + } + + uiintro.add(ui.create.div(".placeholder.slim")); + } else if ( + node.classList.contains("mark") && + node.info && + node.parentNode && + node.parentNode.parentNode && + node.parentNode.parentNode.classList.contains("player") + ) { + var info = node.info; + var player = node.parentNode.parentNode; + if (info.name) { + if (typeof info.name == "function") { + var named = info.name(player.storage[node.skill], player); + if (named) { + uiintro.add(named); + } + } else { + uiintro.add(info.name); + } + } else if (info.name !== false) { + uiintro.add(get.translation(node.skill)); + } + if ( + typeof info.id == "string" && + info.id.startsWith("subplayer") && + player.isUnderControl(true) && + player.storage[info.id] && + !_status.video + ) { + var storage = player.storage[info.id]; + uiintro.addText("当前体力:" + storage.hp + "/" + storage.maxHp); + if (storage.hs.length) { + uiintro.addText("手牌区"); + uiintro.addSmall(storage.hs); + } + if (storage.es.length) { + uiintro.addText("装备区"); + uiintro.addSmall(storage.es); + } + } + if (typeof info.mark == "function") { + var stint = info.mark(uiintro, player.storage[node.skill], player); + if (stint) { + var placetext = uiintro.add( + '
                                    ' + stint + "
                                    " + ); + if (!stint.startsWith('
                                    '+stint+'
                                    '); + // } + // else{ + // uiintro.add('
                                    '+stint+'
                                    '); + // } + } + } else { + var stint = get.storageintro( + info.content, + player.storage[node.skill], + player, + uiintro, + node.skill + ); + if (stint) { + if (stint[0] == "@") { + uiintro.add('
                                    ' + stint.slice(1) + "
                                    "); + } else { + var placetext = uiintro.add( + '
                                    ' + stint + "
                                    " + ); + if (!stint.startsWith('
                                    '+stint+'
                                    '); + // } + // else{ + // uiintro.add('
                                    '+stint+'
                                    '); + // } + } + } + uiintro.add(ui.create.div(".placeholder.slim")); + } else if (node.classList.contains("card")) { + //卡牌长按介绍 + if (ui.arena.classList.contains("observe") && node.parentNode.classList.contains("handcards")) { + return; + } + var name = node.name; + if (node.parentNode.cardMod) { + var moded = false; + for (var i in node.parentNode.cardMod) { + var item = node.parentNode.cardMod[i](node); + if (Array.isArray(item)) { + moded = true; + uiintro.add(item[0]); + uiintro._place_text = uiintro.add( + '
                                    ' + item[1] + "
                                    " + ); + } + } + if (moded) return uiintro; + } + if (node.link && node.link.name && lib.card[node.link.name]) { + name = node.link.name; + } + if (get.position(node) == "j" && node.viewAs && node.viewAs != name) { + uiintro.add(get.translation(node.viewAs)); + var cardInfo = lib.card[node.viewAs], + showCardIntro = true; + if (cardInfo.blankCard) { + var cardOwner = get.owner(node); + if (cardOwner && !cardOwner.isUnderControl(true)) showCardIntro = false; + } + if (showCardIntro) + uiintro.add( + '
                                    (' + get.translation(get.translation(node)) + ")
                                    " + ); + // uiintro.add(get.translation(node.viewAs)+'
                                    ('+get.translation(node)+')
                                    '); + uiintro.nosub = true; + name = node.viewAs; + } else { + uiintro.add(get.translation(node)); + } + if (node._banning) { + var clickBanned = function () { + var banned = lib.config[this.bannedname] || []; + if (banned.includes(name)) { + banned.remove(name); + } else { + banned.push(name); + } + game.saveConfig(this.bannedname, banned); + this.classList.toggle("on"); + if (node.updateBanned) { + node.updateBanned(); + } + }; + var modeorder = lib.config.modeorder || []; + for (var i in lib.mode) { + modeorder.add(i); + } + var list = []; + uiintro.contentContainer.listen(function (e) { + ui.click.touchpop(); + e.stopPropagation(); + }); + for (var i = 0; i < modeorder.length; i++) { + if (node._banning == "online") { + if (!lib.mode[modeorder[i]].connect) continue; + } else if (modeorder[i] == "connect" || modeorder[i] == "brawl") { + continue; + } + if (lib.config.all.mode.includes(modeorder[i])) { + list.push(modeorder[i]); + } + } + if (lib.card[name] && lib.card[name].type == "trick") list.push("zhinang_tricks"); + var page = ui.create.div(".menu-buttons.configpopped", uiintro.content); + var banall = false; + for (var i = 0; i < list.length; i++) { + var cfg = ui.create.div( + ".config", + list[i] == "zhinang_tricks" ? "设为智囊" : lib.translate[list[i]] + "模式", + page + ); + cfg.classList.add("toggle"); + if (list[i] == "zhinang_tricks") { + cfg.bannedname = (node._banning == "offline" ? "" : "connect_") + "zhinang_tricks"; + } else if (node._banning == "offline") { + cfg.bannedname = list[i] + "_bannedcards"; + } else { + cfg.bannedname = "connect_" + list[i] + "_bannedcards"; + } + cfg.listen(clickBanned); + ui.create.div(ui.create.div(cfg)); + var banned = lib.config[cfg.bannedname] || []; + if (banned.includes(name) == (list[i] == "zhinang_tricks")) { + cfg.classList.add("on"); + banall = true; + } + } + ui.create.div( + ".menubutton.pointerdiv", + banall ? "全部禁用" : "全部启用", + uiintro.content, + function () { + if (this.innerHTML == "全部禁用") { + for (var i = 0; i < page.childElementCount; i++) { + if ( + page.childNodes[i].bannedname.indexOf("zhinang_tricks") == -1 && + page.childNodes[i].bannedname && + page.childNodes[i].classList.contains("on") + ) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = "全部启用"; + } else { + for (var i = 0; i < page.childElementCount; i++) { + if ( + page.childNodes[i].bannedname.indexOf("zhinang_tricks") == -1 && + page.childNodes[i].bannedname && + !page.childNodes[i].classList.contains("on") + ) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = "全部禁用"; + } + } + ).style.marginTop = "-10px"; + ui.create.div(".placeholder.slim", uiintro.content); + } else { + if (lib.translate[name + "_info"]) { + if (!uiintro.nosub) { + if (lib.card[name] && lib.card[name].derivation) { + if (typeof lib.card[name].derivation == "string") { + uiintro.add( + '
                                    来源:' + + get.translation(lib.card[name].derivation) + + "
                                    " + ); + } else if (lib.card[name].derivationpack) { + uiintro.add( + '
                                    来源:' + + get.translation(lib.card[name].derivationpack + "_card_config") + + "包
                                    " + ); + } + } + let typeinfo = ""; + if (lib.card[name] && lib.card[name].unique) { + typeinfo += "特殊" + get.translation(lib.card[name].type) + "牌"; + } else if ( + lib.card[name] && + lib.card[name].type && + lib.translate[lib.card[name].type] + ) { + typeinfo += get.translation(lib.card[name].type) + "牌"; + } + if (get.subtype(name, false)) { + typeinfo += "-" + get.translation(get.subtype(name, false)); + } + if (typeinfo) { + uiintro.add('
                                    ' + typeinfo + "
                                    "); + } + if (lib.card[name].unique && lib.card[name].type == "equip") { + if (lib.cardPile.guozhan && lib.cardPack.guozhan.includes(name)) { + uiintro.add('
                                    专属装备
                                    ').style.marginTop = + "-5px"; + } else { + uiintro.add('
                                    特殊装备
                                    ').style.marginTop = + "-5px"; + } + } + if (lib.card[name] && lib.card[name].addinfomenu) { + uiintro.add('
                                    ' + lib.card[name].addinfomenu + "
                                    "); + } + if (get.subtype(name, false) == "equip1") { + var added = false; + if (lib.card[node.name] && lib.card[node.name].distance) { + var dist = lib.card[node.name].distance; + if (dist.attackFrom) { + added = true; + uiintro.add( + '
                                    攻击范围:' + + (-dist.attackFrom + 1) + + "
                                    " + ); + } + } + if (!added) { + uiintro.add('
                                    攻击范围:1
                                    '); + } + } + } + if (lib.card[name].cardPrompt) { + var str = lib.card[name].cardPrompt(node.link || node), + placetext = uiintro.add( + '
                                    ' + str + "
                                    " + ); + if (!str.startsWith('
                                    ' + + lib.translate[name + "_info"] + + "
                                    " + ); + if (!lib.translate[name + "_info"].startsWith('
                                    应变:${yingbianEffects + .map((value) => lib.yingbian.prompt.get(value)) + .join(";")}
                                    ` + ); + } + if (lib.translate[name + "_append"]) { + uiintro.add( + '
                                    ' + + lib.translate[name + "_append"] + + "
                                    " + ); + } + } + uiintro.add(ui.create.div(".placeholder.slim")); + } + } else if (node.classList.contains("character")) { + const character = node.link, + characterInfo = get.character(node.link); + let capt = get.translation(character); + if (characterInfo) { + const infoSex = characterInfo[0]; + if (infoSex && lib.config.show_sex) + capt += `  ${infoSex == "none" ? "无" : lib.translate[infoSex]}`; + const infoGroup = characterInfo[1]; + if (infoGroup && lib.config.show_group) { + const group = get.is.double(character, true); + if (group) + capt += `  ${group.map((value) => get.translation(value)).join("/")}`; + else capt += `  ${lib.translate[infoGroup]}`; + } + } + uiintro.add(capt); + + if (lib.characterTitle[node.link]) { + uiintro.addText(get.colorspan(lib.characterTitle[node.link])); + } + + if (get.characterInitFilter(node.link)) { + const initFilters = get.characterInitFilter(node.link).filter((tag) => { + if (!lib.characterInitFilter[node.link]) return true; + return lib.characterInitFilter[node.link](tag) !== false; + }); + if (initFilters.length) { + const str = initFilters + .reduce((strx, stry) => strx + lib.InitFilter[stry] + "
                                    ", "") + .slice(0, -4); + uiintro.addText(str); + } + } + + if (node._banning) { + var clickBanned = function () { + var banned = lib.config[this.bannedname] || []; + if (banned.includes(character)) { + banned.remove(character); + } else { + banned.push(character); + } + game.saveConfig(this.bannedname, banned); + this.classList.toggle("on"); + if (node.updateBanned) { + node.updateBanned(); + } + }; + var modeorder = lib.config.modeorder || []; + for (var i in lib.mode) { + modeorder.add(i); + } + var list = []; + uiintro.contentContainer.listen(function (e) { + ui.click.touchpop(); + e.stopPropagation(); + }); + for (var i = 0; i < modeorder.length; i++) { + if (node._banning == "online") { + if (!lib.mode[modeorder[i]].connect) continue; + if (!lib.config["connect_" + modeorder[i] + "_banned"]) { + lib.config["connect_" + modeorder[i] + "_banned"] = []; + } + } else if (modeorder[i] == "connect" || modeorder[i] == "brawl") { + continue; + } + if (lib.config.all.mode.includes(modeorder[i])) { + list.push(modeorder[i]); + } + } + var page = ui.create.div(".menu-buttons.configpopped", uiintro.content); + var banall = false; + for (var i = 0; i < list.length; i++) { + var cfg = ui.create.div(".config", lib.translate[list[i]] + "模式", page); + cfg.classList.add("toggle"); + if (node._banning == "offline") { + cfg.bannedname = list[i] + "_banned"; + } else { + cfg.bannedname = "connect_" + list[i] + "_banned"; + } + cfg.listen(clickBanned); + ui.create.div(ui.create.div(cfg)); + var banned = lib.config[cfg.bannedname] || []; + if (!banned.includes(character)) { + cfg.classList.add("on"); + banall = true; + } + } + if (node._banning == "offline") { + var cfg = ui.create.div(".config", "随机选将可用", page); + cfg.classList.add("toggle"); + cfg.listen(function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + lib.config.forbidai_user.remove(character); + } else { + lib.config.forbidai_user.add(character); + } + game.saveConfig("forbidai_user", lib.config.forbidai_user); + }); + ui.create.div(ui.create.div(cfg)); + if (!lib.config.forbidai_user.includes(character)) { + cfg.classList.add("on"); + } + } + ui.create.div( + ".menubutton.pointerdiv", + banall ? "全部禁用" : "全部启用", + uiintro.content, + function () { + if (this.innerHTML == "全部禁用") { + for (var i = 0; i < page.childElementCount; i++) { + if ( + page.childNodes[i].bannedname && + page.childNodes[i].classList.contains("on") + ) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = "全部启用"; + } else { + for (var i = 0; i < page.childElementCount; i++) { + if ( + page.childNodes[i].bannedname && + !page.childNodes[i].classList.contains("on") + ) { + clickBanned.call(page.childNodes[i]); + } + } + this.innerHTML = "全部禁用"; + } + } + ).style.marginTop = "-10px"; + ui.create.div(".placeholder.slim", uiintro.content); + } else { + var infoitem = get.character(character); + var skills = infoitem[3]; + for (i = 0; i < skills.length; i++) { + if (lib.translate[skills[i] + "_info"]) { + if (lib.translate[skills[i] + "_ab"]) translation = lib.translate[skills[i] + "_ab"]; + else { + translation = get.translation(skills[i]); + if (!lib.skill[skills[i]].nobracket) + translation = `【${translation.slice(0, 2)}】`; + } + + uiintro.add( + '
                                    ' + + translation + + "
                                    " + + get.skillInfoTranslation(skills[i]) + + "
                                    " + ); + + if (lib.translate[skills[i] + "_append"]) { + uiintro._place_text = uiintro.add( + '
                                    ' + lib.translate[skills[i] + "_append"] + "
                                    " + ); + } + } + } + var modepack = lib.characterPack["mode_" + get.mode()]; + if ( + lib.config.show_favourite && + lib.character[node.link] && + (!modepack || !modepack[node.link]) && + (!simple || get.is.phoneLayout()) + ) { + var addFavourite = ui.create.div(".text.center.pointerdiv"); + addFavourite.link = node.link; + addFavourite.style.marginBottom = "15px"; + if (lib.config.favouriteCharacter.includes(node.link)) { + addFavourite.innerHTML = "移除收藏"; + } else { + addFavourite.innerHTML = "添加收藏"; + } + addFavourite.listen(ui.click.favouriteCharacter); + uiintro.add(addFavourite); + } else { + uiintro.add(ui.create.div(".placeholder.slim")); + } + var addskin = false; + if (node.parentNode.classList.contains("menu-buttons")) { + addskin = !lib.config.show_charactercard; + } else { + addskin = lib.config.change_skin || lib.skin; + } + if (addskin && (!simple || get.is.phoneLayout())) { + var num = 1; + var introadded = false; + var nameskin = node.link; + var nameskin2 = nameskin; + var gzbool = false; + if (nameskin.startsWith("gz_shibing")) { + nameskin = nameskin.slice(3, 11); + } else if (nameskin.startsWith("gz_")) { + nameskin = nameskin.slice(3); + gzbool = true; + } + var createButtons = function (num) { + if (!num) return; + if (!introadded) { + introadded = true; + uiintro.add('
                                    更改皮肤
                                    '); + } + var buttons = ui.create.div(".buttons.smallzoom.scrollbuttons"); + lib.setMousewheel(buttons); + for (var i = 0; i <= num; i++) { + var button = ui.create.div(".button.character.pointerdiv", buttons, function () { + if (this._link) { + lib.config.skin[nameskin] = this._link; + node.style.backgroundImage = this.style.backgroundImage; + game.saveConfig("skin", lib.config.skin); + } else { + delete lib.config.skin[nameskin]; + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + node.setBackground(nameskin2, "character"); + else node.setBackground(nameskin, "character"); + game.saveConfig("skin", lib.config.skin); + } + }); + button._link = i; + if (i) { + button.setBackgroundImage("image/skin/" + nameskin + "/" + i + ".jpg"); + } else { + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + button.setBackground(nameskin2, "character", "noskin"); + else button.setBackground(nameskin, "character", "noskin"); + } + } + uiintro.add(buttons); + }; + var loadImage = function () { + var img = new Image(); + img.onload = function () { + num++; + loadImage(); + }; + img.onerror = function () { + num--; + createButtons(num); + }; + img.src = lib.assetURL + "image/skin/" + nameskin + "/" + num + ".jpg"; + }; + if (lib.config.change_skin) { + loadImage(); + } else { + setTimeout(function () { + createButtons(lib.skin[nameskin]); + }); + } + } + } + } else if (node.classList.contains("equips") && ui.arena.classList.contains("selecting")) { + (function () { + uiintro.add("选择装备"); + uiintro.addSmall( + Array.from(node.childNodes).filter( + (node) => !node.classList.contains("emptyequip") && !node.classList.contains("feichu") + ), + true + ); + uiintro.clickintro = true; + ui.control.hide(); + uiintro._onclose = function () { + ui.control.show(); + }; + var confirmbutton; + for (var i = 0; i < uiintro.buttons.length; i++) { + var button = uiintro.buttons[i]; + button.classList.add("pointerdiv"); + if (button.link.classList.contains("selected")) { + button.classList.add("selected"); + } + button.listen(function (e) { + ui.click.card.call(this.link, "popequip"); + ui.click.window.call(ui.window, e); + if (this.link.classList.contains("selected")) { + this.classList.add("selected"); + } else { + this.classList.remove("selected"); + } + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes("o")) { + confirmbutton.classList.remove("disabled"); + } else { + confirmbutton.classList.add("disabled"); + } + }); + } + var buttoncontainer = uiintro.add(ui.create.div()); + buttoncontainer.style.display = "block"; + confirmbutton = ui.create.div( + ".menubutton.large.pointerdiv", + "确定", + function () { + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes("o")) { + uiintro._clickintro(); + ui.click.ok(ui.confirm.firstChild); + } + }, + buttoncontainer + ); + confirmbutton.style.position = "relative"; + setTimeout(function () { + if (ui.confirm && ui.confirm.str && ui.confirm.str.includes("o")) { + confirmbutton.classList.remove("disabled"); + } else { + confirmbutton.classList.add("disabled"); + } + }, 300); + })(); + } else if (node.classList.contains("identity") && node.dataset.career) { + var career = node.dataset.career; + uiintro.add(get.translation(career)); + uiintro.add( + '
                                    ' + + lib.translate["_" + career + "_skill_info"] + + "
                                    " + ); + } else if (node.classList.contains("skillbar")) { + if (node == ui.friendBar) { + uiintro.add("友方怒气值"); + uiintro.add( + '
                                    ' + _status.friendRage + "/100
                                    " + ); + } else if (node == ui.enemyBar) { + uiintro.add("敌方怒气值"); + uiintro.add( + '
                                    ' + _status.enemyRage + "/100
                                    " + ); + } + } else if (node.parentNode == ui.historybar) { + if (node.dead) { + if (!node.source || node.source == node.player) { + uiintro.add('
                                    ' + get.translation(node.player) + "阵亡
                                    "); + uiintro.addSmall([node.player]); + } else { + uiintro.add( + '
                                    ' + + get.translation(node.player) + + "被" + + get.translation(node.source) + + "杀害
                                    " + ); + uiintro.addSmall([node.source]); + } + } + if (node.skill) { + uiintro.add('
                                    ' + get.translation(node.skill, "skill") + "
                                    "); + uiintro._place_text = uiintro.add( + '
                                    ' + + get.translation(node.skill, "info") + + "
                                    " + ); + } + if (node.targets && get.itemtype(node.targets) == "players") { + uiintro.add('
                                    目标
                                    '); + uiintro.addSmall(node.targets); + } + if (node.players && node.players.length > 1) { + uiintro.add('
                                    使用者
                                    '); + uiintro.addSmall(node.players); + } + if (node.cards && node.cards.length) { + uiintro.add('
                                    卡牌
                                    '); + uiintro.addSmall(node.cards); + } + for (var i = 0; i < node.added.length; i++) { + uiintro.add(node.added[i]); + } + if (node.added.length) { + uiintro.add(ui.create.div(".placeholder.slim")); + } + if (uiintro.content.firstChild) { + uiintro.content.firstChild.style.paddingTop = "3px"; + } + } + if (lib.config.touchscreen) { + lib.setScroll(uiintro.contentContainer); + } + return uiintro; + } + linkintro(dialog, content, player) { + dialog.content.firstChild.remove(); + dialog.add('
                                    已横置
                                    '); + var list = []; + for (var i = 0; i < game.players.length; i++) { + if ( + game.players[i].isLinked() && + game.players[i].name && + !game.players[i].name.startsWith("unknown") + ) { + list.push(game.players[i]); + } + } + if (list.length) { + dialog.add(list, true, true); + } + } + groups() { + return ["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.includes(lib.config.mode) == false) continue; + if (lib.card[i].forbid && lib.card[i].forbid.includes(lib.config.mode)) continue; + if (lib.card[i].type) { + if (lib.card[i].type == "delay") types.add("trick"); + else types.add(lib.card[i].type); + } + } + return types; + } + links(buttons) { + var links = []; + for (var i = 0; i < buttons.length; i++) { + if (buttons[i].link != undefined) links.push(buttons[i].link); + } + return links; + } + threaten(target, player, hp) { + var threaten = 1; + var skills = target.getSkills(); + if (!player && player !== false) { + player = _status.event.player; + } + for (var i = 0; i < skills.length; i++) { + var info = get.info(skills[i]); + if (info && info.ai && info.ai.threaten) { + if (typeof info.ai.threaten == "function" && player) { + var tmp = info.ai.threaten(player, target); + if (typeof tmp == "number") { + threaten *= tmp; + } + } else if (typeof info.ai.threaten == "number") { + threaten *= info.ai.threaten; + } + } + } + if (hp) { + switch (target.hp) { + case 0: + threaten *= 1.5; + break; + case 1: + threaten *= 1.2; + break; + } + switch (target.countCards("h")) { + case 0: + threaten *= 1.5; + break; + case 1: + threaten *= 1.2; + break; + } + } + return threaten; + } + condition(player) { + var num = player.hp; + if (num > 4) { + num = 4 + Math.sqrt(num - 4); + } else { + if (player.isHealthy()) { + if (player.hp == 3) { + num += 0.5; + } else if (player.hp < 3) { + num++; + } + } + } + num += player.countCards("h") / 2; + var es = player.getCards("e"); + for (var i = 0; i < es.length; i++) { + var val = get.equipValueNumber(es[i]); + if (val >= 7) num += 0.8; + if (val >= 5) num += 0.5; + if (val >= 3) num += 0.2; + } + return num; + } + attitude(from, to) { + if (!from || !to) return 0; + from = from._trueMe || from; + arguments[0] = from; + var att = CacheContext.requireCacheContext().get.rawAttitude.apply(this, arguments); + if (from.isMad()) att = -att; + if (to.isMad() && att > 0) { + if (to.identity == "zhu") { + att = 1; + } else { + att = 0; + } + } + if (!_status.tempnofake) { + _status.tempnofake = true; + if (from.ai.modAttitudeFrom) { + att = from.ai.modAttitudeFrom(from, to, att); + } + if (to.ai.modAttitudeTo) { + att = to.ai.modAttitudeTo(from, to, att); + } + delete _status.tempnofake; + } + return att; + } + sgnAttitude() { + return get.sgn(get.attitude.apply(this, arguments)); + } + useful_raw(card, player) { + if (get.position(card) == "j") return -1; + if (get.position(card) == "e") return get.equipValue(card); + if (card._modUseful) { + return card._modUseful(); + } + var i = 0; + if (!player) player = _status.event.player; + if (player) { + if (_status.event.useCache) { + i = game + .callFuncUseStepCache( + "player.getCardsInUseful", + function (player, position, cardname) { + return player.getCards(position, cardname); + }, + [player, "h", card.name] + ) + .indexOf(card); + } else { + i = player.getCards("h", card.name).indexOf(card); + } + if (i < 0) i = 0; + } + var aii = get.info(card).ai; + var useful; + if (aii && aii.useful) useful = aii.useful; + else if (aii && aii.basic) useful = aii.basic.useful; + var result; + if (useful == undefined) result = -1; + else if (typeof useful == "function") { + result = useful(card, i); + } else if (typeof useful == "number") result = useful; + else if (i < useful.length) { + result = useful[i]; + } else result = useful[useful.length - 1]; + result = game.checkMod(player, card, result, "aiUseful", player); + return result; + } + 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(card) { + return -get.useful(card); + } + unuseful2(card) { + return 10 - get.useful(card); + } + unuseful3(card) { + if (card.name == "du") return 20; + return 10 - get.useful(card); + } + value(card, player, method) { + var result = 0; + var value; + if (Array.isArray(card)) { + if (!card.length) return 0; + value = 0; + for (var i = 0; i < card.length; i++) { + value += get.value(card[i], player, method); + } + return value / Math.sqrt(card.length); + } + if (card._modValue) { + return card._modValue(player, method); + } + var aii = get.info(card).ai; + if (aii && aii.value) value = aii.value; + else if (aii && aii.basic) value = aii.basic.value; + if (player == undefined || get.itemtype(player) != "player") player = _status.event.player; + var geti = function () { + return player.getCardIndex("hs", card.name, card, 5); + }; + if (typeof value == "function") { + result = value(card, player, geti(), method); + } + if (typeof value == "number") result = value; + if (Array.isArray(value)) { + if (method == "raw") result = value[0]; + var num = geti(); + if (num < value.length) result = value[Math.max(0, num)]; + else result = value[value.length - 1]; + } + result = game.checkMod(player, card, result, "aiValue", player); + return result; + } + equipResult(player, target, name) { + var card = get.card(); + if (!card || card.name != name) { + card = { name: name }; + } + var value1 = get.equipValue(card, target); + var value2 = 0; + if (!player.canEquip(card)) { + if (!player.canEquip(card, true)) return 0; + var current = target.getEquip(card); + if (current && current != card) { + value2 = get.equipValue(current, target); + if (value2 > 0 && !target.needsToDiscard() && !get.tag(card, "valueswap")) { + return 0; + } + } + } + return Math.max(0, value1 - value2) / 5; + } + equipValue(card, player) { + if (player == undefined || get.itemtype(player) != "player") player = get.owner(card); + if (player == undefined || get.itemtype(player) != "player") player = _status.event.player; + var info = get.info(card); + if (!info.ai) return 0; + var value = info.ai.equipValue; + if (value == undefined) { + if (info.ai.basic && info.ai.basic.equipValue != undefined) { + value = info.ai.basic.equipValue; + } else return 0; + } + if (typeof value == "number") return value; + if (typeof value == "function") return value(card, player, null, "raw2"); + return 0; + } + equipValueNumber(card) { + var info = get.info(card); + if (info.ai) { + if (typeof info.ai.equipValue == "number") return info.ai.equipValue; + if (info.ai.basic && typeof info.ai.basic.equipValue == "number") return info.ai.basic.equipValue; + } + return 0; + } + disvalue(card, player) { + return -get.value(card, player); + } + disvalue2(card, player) { + return -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; + if (typeof threaten == "number") return threaten; + if (typeof threaten == "function") { + player = player || _status.event.player; + target = target || player; + return threaten(player, target); + } + return 1; + } + cacheOrder(item) { + let cache = CacheContext.requireCacheContext(); + return cache.get.order(item); + } + /** + * @returns { number } + */ + order(item, player = get.player() || game.me) { + let cache = CacheContext.requireCacheContext(); + var info = get.info(item); + if (!info) return -1; + var aii = info.ai; + var order; + if (aii && aii.order) order = aii.order; + else if (aii && aii.basic) order = aii.basic.order; + if (order == undefined) return -1; + var num = order; + if (typeof order == "function") { + num = order(item, player); + } + if (typeof item == "object" && player) { + num = game.checkMod(player, item, num, "aiOrder", player); + } + return num; + } + result(item, skill) { + var result; + var info = get.info(item); + if (info.ai) result = get.copy(info.ai.result); + if (typeof result == "function") result = result(item); + if (!result) result = {}; + if (skill) { + var info2 = get.info(skill); + if (info2.ai) { + info2 = info2.ai.result; + for (var i in info2) { + result[i] = info2[i]; + } + } + } + return result; + } + cacheEffectUse(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); + return cache.get.effect_use(target, card, player, player2, isLink); + } + effect_use(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); + var event = _status.event; + var eventskill = null; + if (player == undefined) player = _status.event.player; + if (card && typeof card == "object" && "name" in card) card = get.autoViewAs(card); + if (typeof card != "string" && (typeof card != "object" || !card.name)) { + var skillinfo = get.info(event.skill); + if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; + else { + card = get.card(); + if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { + eventskill = event.skill; + } + } + } + var info = get.info(card); + if (typeof card == "object" && info && info.changeTarget) { + var targets = [target]; + info.changeTarget(player, targets); + var eff = 0; + for (var i of targets) { + eff += cache.get.effect(i, card, player, player2, isLink); + } + return eff; + } + var result = get.result(card, eventskill); + var result1 = result.player_use || result.player, + result2 = result.target_use || result.target; + if (typeof result1 == "function") result1 = result1(player, target, card, isLink); + if (typeof result2 == "function") result2 = result2(player, target, card, isLink); + + if (typeof result1 != "number") result1 = 0; + if (typeof result2 != "number") result2 = 0; + var temp1, + temp2, + temp3, + temp01 = 0, + temp02 = 0, + threaten = 1; + var skills1 = player.getSkills().concat(lib.skill.global); + game.expandSkills(skills1); + var zerotarget = false, + zeroplayer = false; + for (var i = 0; i < skills1.length; i++) { + temp1 = get.info(skills1[i]).ai; + if (temp1 && typeof temp1.effect == "object" && typeof temp1.effect.player_use == "function") { + temp1 = cache.delegate(temp1.effect).player_use(card, player, target, result1, isLink); + } else if (temp1 && typeof temp1.effect == "object" && typeof temp1.effect.player == "function") { + temp1 = cache.delegate(temp1.effect).player(card, player, target, result1, isLink); + } else temp1 = undefined; + if (typeof temp1 == "object") { + if (temp1.length == 2 || temp1.length == 4) { + result1 *= temp1[0]; + temp01 += temp1[1]; + } + if (temp1.length == 4) { + result2 *= temp1[2]; + temp02 += temp1[3]; + } + } else if (typeof temp1 == "number") { + result1 *= temp1; + } else if (temp1 == "zeroplayer") { + zeroplayer = true; + } else if (temp1 == "zerotarget") { + zerotarget = true; + } else if (temp1 == "zeroplayertarget") { + zeroplayer = true; + zerotarget = true; + } + } + if (target) { + var skills2 = target.getSkills().concat(lib.skill.global); + game.expandSkills(skills2); + for (var i = 0; i < skills2.length; i++) { + temp2 = get.info(skills2[i]).ai; + if (temp2 && temp2.threaten) temp3 = temp2.threaten; + else temp3 = undefined; + if (temp2 && typeof temp2.effect == "function") { + if ( + !player.hasSkillTag("ignoreSkill", true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + }) + ) + temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); + else temp2 = undefined; + } else if ( + temp2 && + typeof temp2.effect == "object" && + typeof temp2.effect.target_use == "function" + ) { + if ( + !player.hasSkillTag("ignoreSkill", true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + }) + ) + temp2 = cache + .delegate(temp2.effect) + .target_use(card, player, target, result2, isLink); + else temp2 = undefined; + } else if ( + temp2 && + typeof temp2.effect == "object" && + typeof temp2.effect.target == "function" + ) { + if ( + !player.hasSkillTag("ignoreSkill", true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + }) + ) + temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); + else temp2 = undefined; + } else temp2 = undefined; + if (typeof temp2 == "object") { + if (temp2.length == 2 || temp2.length == 4) { + result2 *= temp2[0]; + temp02 += temp2[1]; + } + if (temp2.length == 4) { + result1 *= temp2[2]; + temp01 += temp2[3]; + } + } else if (typeof temp2 == "number") { + result2 *= temp2; + } else if (temp2 == "zeroplayer") { + zeroplayer = true; + } else if (temp2 == "zerotarget") { + zerotarget = true; + } else if (temp2 == "zeroplayertarget") { + zeroplayer = true; + zerotarget = true; + } + if (typeof temp3 == "object") { + temp3 = temp3.target; + } + if (typeof temp3 == "function") { + temp3 = temp3(player, target); + } + if (typeof temp3 == "number") { + threaten *= temp3; + } + } + result2 += temp02; + result1 += temp01; + if (typeof card == "object" && !result.ignoreStatus) { + if (cache.get.attitude(player, target) < 0) { + result2 *= Math.sqrt(threaten); + } else { + result2 *= Math.sqrt(Math.sqrt(threaten)); + } + if (target.hp == 1) result2 *= 2.5; + if (target.hp == 2) result2 *= 1.8; + let countTargetCards = target.countCards("h"); + if (countTargetCards == 0) { + if (get.tag(card, "respondSha") || get.tag(card, "respondShan")) { + result2 *= 1.7; + } else { + result2 *= 1.5; + } + } else if (countTargetCards == 1) result2 *= 1.3; + else if (countTargetCards == 2) result2 *= 1.1; + else if (countTargetCards >= 3) result2 *= 0.5; + + if (target.hp == 4) result2 *= 0.9; + else if (target.hp == 5) result2 *= 0.8; + else if (target.hp > 5) result2 *= 0.6; + } + } else { + result2 += temp02; + result1 += temp01; + } + if (zeroplayer) result1 = 0; + if (zerotarget) result2 = 0; + var final = 0; + if (player2) { + final = + result1 * cache.get.attitude(player2, player) + + (target ? result2 * cache.get.attitude(player2, target) : 0); + } else + final = + result1 * cache.get.attitude(player, player) + + (target ? result2 * cache.get.attitude(player, target) : 0); + if (!isLink && get.tag(card, "natureDamage") && !zerotarget) { + var info = get.info(card); + if (!info || !info.ai || !info.ai.canLink) { + if (target.isLinked()) + game.players.forEach(function (current) { + if (current != target && current.isLinked()) + final += cache.get.effect(current, card, player, player2, true); + }); + } else if (info.ai.canLink(player, target, card)) { + game.players.forEach(function (current) { + if (current != target && current.isLinked()) + final += cache.get.effect(current, card, player, player2, true); + }); + } + } + return final; + } + cacheEffect(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); + return cache.get.effect(target, card, player, player2, isLink); + } + effect(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); + var event = _status.event; + var eventskill = null; + if (player == undefined) player = _status.event.player; + if (card && typeof card == "object" && "name" in card) card = get.autoViewAs(card); + if (typeof card != "string" && (typeof card != "object" || !card.name)) { + var skillinfo = get.info(event.skill); + if (event.skill && skillinfo.viewAs == undefined) card = _status.event.skill; + else { + card = get.card(); + if (skillinfo && skillinfo.viewAs && card.name === skillinfo.viewAs.name) { + eventskill = event.skill; + } + } + } + var result = get.result(card, eventskill); + var result1 = result.player, + result2 = result.target; + if (typeof result1 == "function") result1 = result1(player, target, card, isLink); + if (typeof result2 == "function") result2 = result2(player, target, card, isLink); + + if (typeof result1 != "number") result1 = 0; + if (typeof result2 != "number") result2 = 0; + var temp1, + temp2, + temp3, + temp01 = 0, + temp02 = 0, + threaten = 1; + var skills1 = player.getSkills().concat(lib.skill.global); + game.expandSkills(skills1); + var zerotarget = false, + zeroplayer = false; + for (var i = 0; i < skills1.length; i++) { + temp1 = get.info(skills1[i]).ai; + if (temp1 && typeof temp1.effect == "object" && typeof temp1.effect.player == "function") { + temp1 = temp1.effect.player(card, player, target, result1, isLink); + } else temp1 = undefined; + if (typeof temp1 == "object") { + if (temp1.length == 2 || temp1.length == 4) { + result1 *= temp1[0]; + temp01 += temp1[1]; + } + if (temp1.length == 4) { + result2 *= temp1[2]; + temp02 += temp1[3]; + } + } else if (typeof temp1 == "number") { + result1 *= temp1; + } else if (temp1 == "zeroplayer") { + zeroplayer = true; + } else if (temp1 == "zerotarget") { + zerotarget = true; + } else if (temp1 == "zeroplayertarget") { + zeroplayer = true; + zerotarget = true; + } + } + if (target) { + var skills2 = target.getSkills().concat(lib.skill.global); + game.expandSkills(skills2); + for (var i = 0; i < skills2.length; i++) { + temp2 = get.info(skills2[i]).ai; + if (temp2 && temp2.threaten) temp3 = cache.delegate(temp2).threaten; + else temp3 = undefined; + if (temp2 && typeof temp2.effect == "function") { + if ( + !player.hasSkillTag("ignoreSkill", true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + }) + ) + temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); + else temp2 = undefined; + } else if ( + temp2 && + typeof temp2.effect == "object" && + typeof temp2.effect.target == "function" + ) { + if ( + !player.hasSkillTag("ignoreSkill", true, { + card: card, + target: target, + skill: skills2[i], + isLink: isLink, + }) + ) + temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); + else temp2 = undefined; + } else temp2 = undefined; + if (typeof temp2 == "object") { + if (temp2.length == 2 || temp2.length == 4) { + result2 *= temp2[0]; + temp02 += temp2[1]; + } + if (temp2.length == 4) { + result1 *= temp2[2]; + temp01 += temp2[3]; + } + } else if (typeof temp2 == "number") { + result2 *= temp2; + } else if (temp2 == "zeroplayer") { + zeroplayer = true; + } else if (temp2 == "zerotarget") { + zerotarget = true; + } else if (temp2 == "zeroplayertarget") { + zeroplayer = true; + zerotarget = true; + } + if (typeof temp3 == "function" && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } else if (typeof temp3 == "object") { + if (typeof temp3.target == "number") { + threaten *= temp3; + } else if (typeof temp3.target == "function" && temp3(player, target) != undefined) { + threaten *= temp3(player, target); + } + } else if (typeof temp3 == "number") { + threaten *= temp3; + } + } + result2 += temp02; + result1 += temp01; + if (typeof card == "object" && !result.ignoreStatus) { + if (cache.get.attitude(player, target) < 0) { + result2 *= Math.sqrt(threaten); + } else { + result2 *= Math.sqrt(Math.sqrt(threaten)); + } + // *** continue here *** + if (target.hp == 1) result2 *= 2.5; + if (target.hp == 2) result2 *= 1.8; + let targetCountCards = target.countCards("h"); + if (targetCountCards == 0) { + if (get.tag(card, "respondSha") || get.tag(card, "respondShan")) { + result2 *= 1.7; + } else { + result2 *= 1.5; + } + } + if (targetCountCards == 1) result2 *= 1.3; + else if (targetCountCards == 2) result2 *= 1.1; + else if (targetCountCards > 3) result2 *= 0.5; + if (target.hp == 4) result2 *= 0.9; + else if (target.hp == 5) result2 *= 0.8; + else if (target.hp > 5) result2 *= 0.6; + } + } else { + result2 += temp02; + result1 += temp01; + } + if (zeroplayer) result1 = 0; + if (zerotarget) result2 = 0; + var final = 0; + if (player2) { + final = + result1 * cache.get.attitude(player2, player) + + (target ? result2 * cache.get.attitude(player2, target) : 0); + } else + final = + result1 * cache.get.attitude(player, player) + + (target ? result2 * cache.get.attitude(player, target) : 0); + if (!isLink && get.tag(card, "natureDamage") && !zerotarget) { + var info = get.info(card); + if (!info || !info.ai || !info.ai.canLink) { + if (target.isLinked()) + game.players.forEach(function (current) { + if (current != target && current.isLinked()) + final += cache.get.effect(current, card, player, player2, true); + }); + } else if (info.ai.canLink(player, target, card)) { + game.players.forEach(function (current) { + if (current != target && current.isLinked()) + final += cache.get.effect(current, card, player, player2, true); + }); + } + } + return final; + } + damageEffect(target, player, viewer, nature) { + if (get.itemtype(nature) == "natures") { + var natures = get.natureList(nature); + return ( + natures.map((n) => get.damageEffect(target, player, viewer, n)).reduce((p, c) => p + c, 0) / + (natures.length || 1) + ); + } + if (!player) { + player = target; + } + if (!viewer) { + viewer = target; + } + var name = "damage"; + if (nature == "fire") { + name = "firedamage"; + } else if (nature == "thunder") { + name = "thunderdamage"; + } else if (nature == "ice") { + name = "icedamage"; + } + var eff = get.effect(target, { name: name }, player, viewer); + if (eff > 0 && target.hujia > 0) return eff / 1.3; + return eff; + } + /** + * + * @param {any} source 如果参数是function,执行此函数并返回结果,传参为此方法剩余的参数。如果参数不是function,直接返回结果。 + * @returns 返回的结果 + */ + dynamicVariable(source) { + if (typeof source == "function") { + return source.call(null, ...Array.from(arguments).slice(1)); + } + return source; + } + recoverEffect(target, player, viewer) { + if (target.hp == target.maxHp) return 0; + if (!player) { + player = target; + } + if (!viewer) { + viewer = target; + } + return get.effect(target, { name: "recover" }, player, viewer); + } + buttonValue(button) { + var card = button.link; + var player = get.owner(card); + if (!player) player = _status.event.player; + if (player.getCards("j").includes(card)) { + var efff = get.effect( + player, + { + name: card.viewAs || card.name, + cards: [card], + }, + player, + player + ); + if (efff > 0) return 0.5; + if (efff == 0) return 0; + return -1.5; + } + if (player.getCards("e").includes(card)) { + var evalue = get.value(card, player); + if (player.hasSkillTag("noe")) { + if (evalue >= 7) { + return evalue / 6; + } + return evalue / 10; + } + return evalue / 3; + } + if (player.hasSkillTag("noh")) return 0.1; + var nh = player.countCards("h"); + switch (nh) { + case 1: + return 2; + case 2: + return 1.6; + case 3: + return 1; + case 4: + return 0.8; + case 5: + return 0.6; + default: + return 0.4; + } + } + attitude2(to) { + return get.attitude(_status.event.player, to); + } +} + +export let get = new Get(); +/** + * @param { InstanceType } [instance] + */ +export let setGet = (instance) => { + get = instance || new Get(); + if (lib.config.dev) { + window.get = get; + } +}; + +export { Is, Promises }; diff --git a/noname/get/is.js b/noname/get/is.js index f94ba5539..c57a61fbe 100644 --- a/noname/get/is.js +++ b/noname/get/is.js @@ -1,24 +1,23 @@ -import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js"; -import { AI as ai } from '../ai/index.js'; -import { Game as game } from '../game/index.js'; -import { Library as lib } from '../library/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { GNC as gnc } from '../gnc/index.js'; -import { Get as get } from "./index.js"; +import { userAgent } from "../util/index.js"; +import { game } from "../game/index.js"; +import { lib } from "../library/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { get } from "./index.js"; -export class Is extends Uninstantable { +export class Is { /** * 判断是否为进攻坐骑 * @param { Card | VCard } card * @param { false | Player } [player] * @returns { boolean } */ - static attackingMount(card, player) { + attackingMount(card, player) { const subtype = get.subtype(card, player); - if (subtype == 'equip4') return true; - else if (subtype == 'equip6') { - const info = get.info(card, player), distance = info.distance; + if (subtype == "equip4") return true; + else if (subtype == "equip6") { + const info = get.info(card, player), + distance = info.distance; if (!distance) return false; if (distance.globalFrom && !info.notMount) return true; } @@ -30,11 +29,12 @@ export class Is extends Uninstantable { * @param { false | Player } [player] * @returns { boolean } */ - static defendingMount(card, player) { + defendingMount(card, player) { const subtype = get.subtype(card, player); - if (subtype == 'equip3') return true; - else if (subtype == 'equip6') { - const info = get.info(card, player), distance = info.distance; + if (subtype == "equip3") return true; + else if (subtype == "equip6") { + const info = get.info(card, player), + distance = info.distance; if (!distance) return false; if (distance.globalTo && !info.notMount) return true; } @@ -44,11 +44,10 @@ export class Is extends Uninstantable { * 判断坐骑栏是否被合并 * @returns { boolean } */ - static mountCombined() { + mountCombined() { if (lib.configOL.mount_combine) { return lib.configOL.mount_combine; - } - else if (typeof _status.mountCombined != 'boolean') { + } else if (typeof _status.mountCombined != "boolean") { _status.mountCombined = lib.config.mount_combine; } return _status.mountCombined; @@ -58,10 +57,11 @@ export class Is extends Uninstantable { * @param {...} infos 要判断的属性列表 * @param {boolean} every 是否判断每一个传入的属性是否完全相同而不是存在部分相同 */ - static sameNature() { - let processedArguments = [], every = false; - Array.from(arguments).forEach(argument => { - if (typeof argument == 'boolean') every = argument; + sameNature() { + let processedArguments = [], + every = false; + Array.from(arguments).forEach((argument) => { + if (typeof argument == "boolean") every = argument; else if (argument) processedArguments.push(argument); }); if (!processedArguments.length) return true; @@ -72,17 +72,29 @@ export class Is extends Uninstantable { if (argument.length == 1) return false; processedArguments = argument; } - const naturesList = processedArguments.map(card => { - if (typeof card == 'string') return card.split(lib.natureSeparator); + const naturesList = processedArguments.map((card) => { + if (typeof card == "string") return card.split(lib.natureSeparator); else if (Array.isArray(card)) return card; return get.natureList(card || {}); }); const testingNaturesList = naturesList.slice(0, naturesList.length - 1); - if (every) return testingNaturesList.every((natures, index) => naturesList.slice(index + 1).every(testingNatures => testingNatures.length == natures.length && testingNatures.every(nature => natures.includes(nature)))); + if (every) + return testingNaturesList.every((natures, index) => + naturesList + .slice(index + 1) + .every( + (testingNatures) => + testingNatures.length == natures.length && + testingNatures.every((nature) => natures.includes(nature)) + ) + ); return testingNaturesList.every((natures, index) => { const comparingNaturesList = naturesList.slice(index + 1); - if (natures.length) return natures.some(nature => comparingNaturesList.every(testingNatures => testingNatures.includes(nature))); - return comparingNaturesList.every(testingNatures => !testingNatures.length); + if (natures.length) + return natures.some((nature) => + comparingNaturesList.every((testingNatures) => testingNatures.includes(nature)) + ); + return comparingNaturesList.every((testingNatures) => !testingNatures.length); }); } /** @@ -90,10 +102,11 @@ export class Is extends Uninstantable { * @param ...infos 要判断的属性列表 * @param every {boolean} 是否判断每一个传入的属性是否完全不同而不是存在部分不同 */ - static differentNature() { - let processedArguments = [], every = false; - Array.from(arguments).forEach(argument => { - if (typeof argument == 'boolean') every = argument; + differentNature() { + let processedArguments = [], + every = false; + Array.from(arguments).forEach((argument) => { + if (typeof argument == "boolean") every = argument; else if (argument) processedArguments.push(argument); }); if (!processedArguments.length) return false; @@ -104,62 +117,76 @@ export class Is extends Uninstantable { if (argument.length == 1) return true; processedArguments = argument; } - const naturesList = processedArguments.map(card => { - if (typeof card == 'string') return card.split(lib.natureSeparator); + const naturesList = processedArguments.map((card) => { + if (typeof card == "string") return card.split(lib.natureSeparator); else if (Array.isArray(card)) return card; return get.natureList(card || {}); }); const testingNaturesList = naturesList.slice(0, naturesList.length - 1); - if (every) return testingNaturesList.every((natures, index) => naturesList.slice(index + 1).every(testingNatures => testingNatures.every(nature => !natures.includes(nature)))); + if (every) + return testingNaturesList.every((natures, index) => + naturesList + .slice(index + 1) + .every((testingNatures) => testingNatures.every((nature) => !natures.includes(nature))) + ); return testingNaturesList.every((natures, index) => { const comparingNaturesList = naturesList.slice(index + 1); - if (natures.length) return natures.some(nature => comparingNaturesList.every(testingNatures => !testingNatures.length || testingNatures.some(testingNature => testingNature != nature))); - return comparingNaturesList.every(testingNatures => testingNatures.length); + if (natures.length) + return natures.some((nature) => + comparingNaturesList.every( + (testingNatures) => + !testingNatures.length || + testingNatures.some((testingNature) => testingNature != nature) + ) + ); + return comparingNaturesList.every((testingNatures) => testingNatures.length); }); } /** * 判断一张牌是否为明置手牌 * @param { Card } card */ - static shownCard(card) { + shownCard(card) { if (!card) return false; const gaintag = card.gaintag; - return Array.isArray(gaintag) && gaintag.some(tag => tag.startsWith('visible_')); + return Array.isArray(gaintag) && gaintag.some((tag) => tag.startsWith("visible_")); } /** * 是否是虚拟牌 * @param { Card | VCard } card */ // @ts-ignore - static virtualCard(card) { - return (!("cards" in card) || !Array.isArray(card.cards) || card.cards.length === 0); + virtualCard(card) { + return !("cards" in card) || !Array.isArray(card.cards) || card.cards.length === 0; } /** * 是否是转化牌 * @param { Card | VCard } card */ // @ts-ignore - static convertedCard(card) { - return !card.isCard && ("cards" in card) && Array.isArray(card.cards) && card.cards.length > 0; + convertedCard(card) { + return !card.isCard && "cards" in card && Array.isArray(card.cards) && card.cards.length > 0; } /** * 是否是实体牌 * @param { Card | VCard } card */ // @ts-ignore - static ordinaryCard(card) { - return card.isCard && ("cards" in card) && Array.isArray(card.cards) && card.cards.length === 1 + ordinaryCard(card) { + return card.isCard && "cards" in card && Array.isArray(card.cards) && card.cards.length === 1; } /** * 押韵判断 * @param { string } str1 * @param { string } str2 */ - static yayun(str1, str2) { + yayun(str1, str2) { if (str1 == str2) return true; - let pinyin1 = get.pinyin(str1, false), pinyin2 = get.pinyin(str2, false); + let pinyin1 = get.pinyin(str1, false), + pinyin2 = get.pinyin(str2, false); if (!pinyin1.length || !pinyin2.length) return false; - let pron1 = pinyin1[pinyin1.length - 1], pron2 = pinyin2[pinyin2.length - 1]; + let pron1 = pinyin1[pinyin1.length - 1], + pron2 = pinyin2[pinyin2.length - 1]; if (pron1 == pron2) return true; return get.yunjiao(pron1) == get.yunjiao(pron2); } @@ -168,10 +195,11 @@ export class Is extends Uninstantable { * @param { Player } player 玩家 * @returns */ - static blocked(skill, player) { + blocked(skill, player) { if (!player.storage.skill_blocker || !player.storage.skill_blocker.length) return false; for (let i of player.storage.skill_blocker) { - if (lib.skill[i] && lib.skill[i].skillBlocker && lib.skill[i].skillBlocker(skill, player)) return true; + if (lib.skill[i] && lib.skill[i].skillBlocker && lib.skill[i].skillBlocker(skill, player)) + return true; } return false; } @@ -181,12 +209,12 @@ export class Is extends Uninstantable { * @param { string[] } array * @returns { boolean | string[] } */ - static double(name, array) { + double(name, array) { const extraInformations = get.character(name, 4); if (!extraInformations) return false; for (const extraInformation of extraInformations) { - if (!extraInformation.startsWith('doublegroup:')) continue; - return array ? extraInformation.split(':').slice(1) : true; + if (!extraInformation.startsWith("doublegroup:")) continue; + return array ? extraInformation.split(":").slice(1) : true; } return false; } @@ -196,11 +224,13 @@ export class Is extends Uninstantable { * 检测此牌是否具有应变条件 * @param { Card | VCard } card */ - static yingbianConditional(card) { return get.is.complexlyYingbianConditional(card) || get.is.simplyYingbianConditional(card) } + yingbianConditional(card) { + return get.is.complexlyYingbianConditional(card) || get.is.simplyYingbianConditional(card); + } /** * @param { Card | VCard } card */ - static complexlyYingbianConditional(card) { + complexlyYingbianConditional(card) { for (const key of lib.yingbian.condition.complex.keys()) { if (get.cardtag(card, `yingbian_${key}`)) return true; } @@ -209,7 +239,7 @@ export class Is extends Uninstantable { /** * @param { Card | VCard } card */ - static simplyYingbianConditional(card) { + simplyYingbianConditional(card) { for (const key of lib.yingbian.condition.simple.keys()) { if (get.cardtag(card, `yingbian_${key}`)) return true; } @@ -222,7 +252,7 @@ export class Is extends Uninstantable { * * @param { Card | VCard } card */ - static yingbianEffective(card) { + yingbianEffective(card) { for (const key of lib.yingbian.effect.keys()) { if (get.cardtag(card, `yingbian_${key}`)) return true; } @@ -231,13 +261,15 @@ export class Is extends Uninstantable { /** * @param { Card | VCard } card */ - static yingbian(card) { return get.is.yingbianConditional(card) || get.is.yingbianEffective(card) } + yingbian(card) { + return get.is.yingbianConditional(card) || get.is.yingbianEffective(card); + } /** * @param { string } [substring] */ - static emoji(substring) { + emoji(substring) { if (substring) { - const reg = new RegExp("[~#^$@%&!?%*]", 'g'); + const reg = new RegExp("[~#^$@%&!?%*]", "g"); if (substring.match(reg)) { return true; } @@ -246,34 +278,35 @@ export class Is extends Uninstantable { if (0xd800 <= hs && hs <= 0xdbff) { if (substring.length > 1) { const ls = substring.charCodeAt(i + 1); - const uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000; + const uc = (hs - 0xd800) * 0x400 + (ls - 0xdc00) + 0x10000; if (0x1d000 <= uc && uc <= 0x1f77f) { return true; } } - } - else if (substring.length > 1) { + } else if (substring.length > 1) { const ls = substring.charCodeAt(i + 1); if (ls == 0x20e3) { return true; } - } - else { + } else { if (0x2100 <= hs && hs <= 0x27ff) { return true; - } - else if (0x2B05 <= hs && hs <= 0x2b07) { + } else if (0x2b05 <= hs && hs <= 0x2b07) { return true; - } - else if (0x2934 <= hs && hs <= 0x2935) { + } else if (0x2934 <= hs && hs <= 0x2935) { return true; - } - else if (0x3297 <= hs && hs <= 0x3299) { + } else if (0x3297 <= hs && hs <= 0x3299) { return true; - } - else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 - || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b - || hs == 0x2b50) { + } else if ( + hs == 0xa9 || + hs == 0xae || + hs == 0x303d || + hs == 0x3030 || + hs == 0x2b55 || + hs == 0x2b1c || + hs == 0x2b1b || + hs == 0x2b50 + ) { return true; } } @@ -284,24 +317,32 @@ export class Is extends Uninstantable { /** * @param { string } str */ - static banWords(str) { return get.is.emoji(str) || window.bannedKeyWords.some(item => str.includes(item)) } + banWords(str) { + return get.is.emoji(str) || window.bannedKeyWords.some((item) => str.includes(item)); + } /** * @param { GameEventPromise } event */ // @ts-ignore - static converted(event) { return !(event.card && event.card.isCard) } - static safari() { return userAgent.indexOf('safari') != -1 && userAgent.indexOf('chrome') == -1 } + converted(event) { + return !(event.card && event.card.isCard); + } + safari() { + return userAgent.indexOf("safari") != -1 && userAgent.indexOf("chrome") == -1; + } /** * @param { (Card | VCard)[]} cards */ // @ts-ignore - static freePosition(cards) { return !cards.some(card => !card.hasPosition || card.hasPosition()) } + freePosition(cards) { + return !cards.some((card) => !card.hasPosition || card.hasPosition()); + } /** * @param { string } name * @param { boolean } item */ - static nomenu(name, item) { - const menus = ['system', 'menu']; + nomenu(name, item) { + const menus = ["system", "menu"]; const configs = { show_round_menu: lib.config.show_round_menu, round_menu_func: lib.config.round_menu_func, @@ -311,7 +352,7 @@ export class Is extends Uninstantable { swipe_left: lib.config.swipe_left, swipe_right: lib.config.swipe_right, right_click: lib.config.right_click, - phonelayout: lib.config.phonelayout + phonelayout: lib.config.phonelayout, }; configs[name] = item; if (!configs.phonelayout) return false; @@ -323,18 +364,19 @@ export class Is extends Uninstantable { if (menus.includes(configs.swipe_down)) return false; if (menus.includes(configs.swipe_left)) return false; if (menus.includes(configs.swipe_right)) return false; - } - else { - if (configs.right_click == 'config') return false; + } else { + if (configs.right_click == "config") return false; } if (name) { setTimeout(function () { - alert('请将至少一个操作绑定为显示按钮或打开菜单,否则将永远无法打开菜单'); + alert("请将至少一个操作绑定为显示按钮或打开菜单,否则将永远无法打开菜单"); }); } return true; } - static altered(skillName) { return false; } + altered(skillName) { + return false; + } /* skill=>{ return false; @@ -346,25 +388,33 @@ export class Is extends Uninstantable { * @param { any } obj * @returns { boolean } */ - static node(obj) { - return Object.prototype.toString.call(obj).startsWith('[object HTML'); + node(obj) { + return Object.prototype.toString.call(obj).startsWith("[object HTML"); } /** * @param { any } obj */ - static div(obj) { return Object.prototype.toString.call(obj) === '[object HTMLDivElement]' } + div(obj) { + return Object.prototype.toString.call(obj) === "[object HTMLDivElement]"; + } /** * @param { any } obj */ - static map(obj) { return Object.prototype.toString.call(obj) === '[object Map]' } + map(obj) { + return Object.prototype.toString.call(obj) === "[object Map]"; + } /** * @param { any } obj */ - static set(obj) { return Object.prototype.toString.call(obj) === '[object Set]' } + set(obj) { + return Object.prototype.toString.call(obj) === "[object Set]"; + } /** * @param { any } obj */ - static object(obj) { return Object.prototype.toString.call(obj) === '[object Object]' } + object(obj) { + return Object.prototype.toString.call(obj) === "[object Object]"; + } /** * @overload * @param { Function } func @@ -375,68 +425,108 @@ export class Is extends Uninstantable { * @param { number | [number, number] } func * @returns { boolean } */ - static singleSelect(func) { - if (typeof func == 'function') return false; + singleSelect(func) { + if (typeof func == "function") return false; const select = get.select(func); return select[0] == 1 && select[1] == 1; } /** * @param { string | Player } name */ - static jun(name) { - if (get.mode() == 'guozhan') { + jun(name) { + if (get.mode() == "guozhan") { if (name instanceof lib.element.Player) { if (name.isUnseen && name.isUnseen(0)) return false; name = name.name1; } - if (typeof name == 'string' && name.startsWith('gz_jun_')) { + if (typeof name == "string" && name.startsWith("gz_jun_")) { return true; } } return false; } - static versus() { return !_status.connectMode && get.mode() == 'versus' && _status.mode == 'three' } - static changban() { return get.mode() == 'single' && _status.mode == 'changban' } - static single() { return get.mode() == 'single' && _status.mode == 'normal' } + versus() { + return !_status.connectMode && get.mode() == "versus" && _status.mode == "three"; + } + changban() { + return get.mode() == "single" && _status.mode == "changban"; + } + single() { + return get.mode() == "single" && _status.mode == "normal"; + } /** * @param { Player } [player] */ - static mobileMe(player) { return (game.layout == 'mobile' || game.layout == 'long') && !game.chess && player && player.dataset.position == '0' } - static newLayout() { return game.layout != 'default' } - static phoneLayout() { - if (!lib.config.phonelayout) return false; - return (game.layout == 'mobile' || game.layout == 'long' || game.layout == 'long2' || game.layout == 'nova'); + mobileMe(player) { + return ( + (game.layout == "mobile" || game.layout == "long") && + !game.chess && + player && + player.dataset.position == "0" + ); + } + newLayout() { + return game.layout != "default"; + } + phoneLayout() { + if (!lib.config.phonelayout) return false; + return ( + game.layout == "mobile" || + game.layout == "long" || + game.layout == "long2" || + game.layout == "nova" + ); + } + singleHandcard() { + return ( + game.singleHandcard || + game.layout == "mobile" || + game.layout == "long" || + game.layout == "long2" || + game.layout == "nova" + ); } - static singleHandcard() { return game.singleHandcard || game.layout == 'mobile' || game.layout == 'long' || game.layout == 'long2' || game.layout == 'nova' } /** * @param { Player } player */ - static linked2(player) { + linked2(player) { if (game.chess) return true; - if (lib.config.link_style2 != 'rotate') return true; + if (lib.config.link_style2 != "rotate") return true; // if(game.chess) return false; - if (game.layout == 'long' || game.layout == 'long2' || game.layout == 'nova') return true; - if (player.dataset.position == '0') { - return ui.arena.classList.contains('oblongcard'); + if (game.layout == "long" || game.layout == "long2" || game.layout == "nova") return true; + if (player.dataset.position == "0") { + return ui.arena.classList.contains("oblongcard"); } return false; } /** * @param { {} } obj */ - static empty(obj) { return Object.keys(obj).length == 0 } + empty(obj) { + return Object.keys(obj).length == 0; + } /** * @param { string } str */ - static pos(str) { return str == 'h' || str == 'e' || str == 'j' || str == 'he' || str == 'hj' || str == 'ej' || str == 'hej' } + pos(str) { + return ( + str == "h" || + str == "e" || + str == "j" || + str == "he" || + str == "hj" || + str == "ej" || + str == "hej" + ); + } /** * @param { string } skill * @param { Player } player * @returns */ - static locked(skill, player) { + locked(skill, player) { const info = lib.skill[skill]; - if (typeof info.locked == 'function') return info.locked(skill, player); + if (typeof info.locked == "function") return info.locked(skill, player); if (info.locked == false) return false; if (info.trigger && info.forced) return true; if (info.mod) return true; @@ -448,11 +538,12 @@ export class Is extends Uninstantable { * @param { Player } player * @returns */ - static zhuanhuanji(skill, player) { - const info = lib.skill[skill], { zhuanhuanji } = info; - if ('zhuanhuanji2' in info) { + zhuanhuanji(skill, player) { + const info = lib.skill[skill], + { zhuanhuanji } = info; + if ("zhuanhuanji2" in info) { const { zhuanhuanji2 } = info; - if (typeof zhuanhuanji2 === 'function') return Boolean(zhuanhuanji2(skill, player)); + if (typeof zhuanhuanji2 === "function") return Boolean(zhuanhuanji2(skill, player)); return Boolean(zhuanhuanji2); } return Boolean(zhuanhuanji); diff --git a/noname/get/promises.js b/noname/get/promises.js index 5c417f95b..779087cca 100644 --- a/noname/get/promises.js +++ b/noname/get/promises.js @@ -1,11 +1,10 @@ import { get } from "./index.js"; -import { Uninstantable } from "../util/index.js"; -export class Promises extends Uninstantable { +export class Promises { /** * @returns { Promise } */ - static zip() { - return new Promise(resolve => get.zip(resolve)); + zip() { + return new Promise((resolve) => get.zip(resolve)); } -} \ No newline at end of file +} diff --git a/noname/gnc/index.js b/noname/gnc/index.js index df5a6d83b..7cbdcebd9 100644 --- a/noname/gnc/index.js +++ b/noname/gnc/index.js @@ -1,51 +1,65 @@ -import { GeneratorFunction, Uninstantable } from "../util/index.js"; +import { GeneratorFunction } from "../util/index.js"; import { Is } from "./is.js"; // gnc: GeNCoroutine -export class GNC extends Uninstantable { +export class GNC { /** - * @param {GeneratorFunction} fn - * @returns + * @param {GeneratorFunction} fn + * @returns */ - static of(fn) { - return Is.generatorFunc(fn) ? + of(fn) { + /** + * @param {Parameters} args + * @returns {Promise>} + */ + function genCoroutine(...args) { /** - * @param {Parameters} args - * @returns {Promise>} + * @type {Generator & { status: "next" | "throw" , state?: any}} */ - function genCoroutine(...args) { - let gen = fn.apply(this, args); - gen.status = "next"; - gen.state = undefined; - const callback = (resolve, reject) => { - let result, - nexts = resolve, - throws = reject; - try { - result = gen[gen.status](gen.state); - } catch (error) { - reject(error); - return; - } - if (!result.done) { - nexts = (item) => { - gen.state = item; - gen.status = "next"; - callback(resolve, reject); - }; - throws = (err) => { - gen.state = err; - gen.status = "throw"; - callback(resolve, reject); - }; - } - result = result.value; - Promise.resolve(result).then(nexts, throws); - }; - return new Promise(callback); - } : (() => { throw new TypeError("gnc.of needs a GeneratorFunction."); })(); - } - static is = Is; -}; + // @ts-expect-error Must Ok + let gen = fn.apply(this, args); + gen.status = "next"; + gen.state = undefined; + const callback = (resolve, reject) => { + let result, + nexts = resolve, + throws = reject; + try { + result = gen[gen.status](gen.state); + } catch (error) { + reject(error); + return; + } + if (!result.done) { + nexts = (item) => { + gen.state = item; + gen.status = "next"; + callback(resolve, reject); + }; + throws = (err) => { + gen.state = err; + gen.status = "throw"; + callback(resolve, reject); + }; + } + result = result.value; + Promise.resolve(result).then(nexts, throws); + }; + return new Promise(callback); + } -export const gnc = GNC; + if (!this.is.generatorFunc(fn)) throw new TypeError("gnc.of needs a GeneratorFunction."); + + return genCoroutine; + } + is = new Is(); +} + +export let gnc = new GNC(); + +/** + * @param { InstanceType } [instance] + */ +export let setGNC = (instance) => { + gnc = instance || new GNC(); +}; diff --git a/noname/gnc/is.js b/noname/gnc/is.js index 7089fa988..d12f554d7 100644 --- a/noname/gnc/is.js +++ b/noname/gnc/is.js @@ -1,27 +1,33 @@ -import { GeneratorFunction, Uninstantable } from "../util/index.js"; +import { GeneratorFunction } from "../util/index.js"; -export class Is extends Uninstantable { +export class Is { /** - * @param {*} item + * @param {*} item * @returns {boolean} */ - static coroutine(item) { + coroutine(item) { return typeof item == "function" && item.name == "genCoroutine"; } /** - * @param {*} item + * @param {*} item * @returns {boolean} */ - static generatorFunc(item) { + generatorFunc(item) { return item instanceof GeneratorFunction; } /** - * @param {*} item + * @param {*} item * @returns {boolean} */ - static generator(item) { - return (typeof item == "object") && ("constructor" in item) && item.constructor && ("constructor" in item.constructor) && item.constructor.constructor === GeneratorFunction; + generator(item) { + return ( + typeof item == "object" && + "constructor" in item && + item.constructor && + "constructor" in item.constructor && + item.constructor.constructor === GeneratorFunction + ); } -}; +} diff --git a/noname/init/cordova.js b/noname/init/cordova.js index a1d00eb59..da48c7f7e 100644 --- a/noname/init/cordova.js +++ b/noname/init/cordova.js @@ -1,15 +1,15 @@ -// @ts-nocheck -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { nonameInitialized } from '../util/index.js'; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { nonameInitialized } from "../util/index.js"; +import { checkVersion } from "../library/update.js"; export async function cordovaReady() { - if (lib.device == 'android') { + if (lib.device == "android") { document.addEventListener("pause", function () { - if (!_status.paused2 && (typeof _status.event.isMine == 'function' && !_status.event.isMine())) { + if (!_status.paused2 && typeof _status.event.isMine == "function" && !_status.event.isMine()) { ui.click.pause(); } if (ui.backgroundMusic) { @@ -20,45 +20,66 @@ export async function cordovaReady() { if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); }); document.addEventListener("backbutton", function () { - if (ui.arena && ui.arena.classList.contains('menupaused')) { + if (ui.arena && ui.arena.classList.contains("menupaused")) { if (window.saveNonameInput) { window.saveNonameInput(); - } - else { + } else { ui.click.configMenu(); } - } - else if (lib.config.confirm_exit) { + } else if (lib.config.confirm_exit) { navigator.notification.confirm( - '是否退出游戏?', + "是否退出游戏?", function (index) { switch (index) { - case 2: game.reload(); break; - case 3: navigator.app.exitApp(); break; + case 2: + game.reload(); + break; + case 3: + navigator.app.exitApp(); + break; } }, - '确认退出', - ['取消', '重新开始', '退出'] + "确认退出", + ["取消", "重新开始", "退出"] ); - } - else { + } else { navigator.app.exitApp(); } }); if ("cordova" in window && "plugins" in window.cordova && "permissions" in window.cordova.plugins) { const permissions = cordova.plugins.permissions; - const requests = ["WRITE_EXTERNAL_STORAGE", "READ_EXTERNAL_STORAGE"] - requests.forEach(request => { - permissions.checkPermission(permissions[request], status => { - if (!status.hasPermission) { - permissions.requestPermission(permissions[request], lib.other.ignore, lib.other.ignore); - } - }, lib.other.ignore); - }); + const requests = ["WRITE_EXTERNAL_STORAGE", "READ_EXTERNAL_STORAGE"]; + if (typeof device == 'object') { + // 安卓13或以上 + if (checkVersion(device.version, "13") >= 0) { + requests.length = 0; + requests.push('READ_MEDIA_IMAGES', 'READ_MEDIA_VIDEO', 'READ_MEDIA_AUDIO'); + } + } + Promise.all(requests.map(request => { + return new Promise((resolve, reject) => { + permissions.checkPermission(permissions[request], status => { + resolve({ + request: request, + hasPermission: status.hasPermission + }); + }, reject); + }); + })).then(shouldRequestPermissions => { + return shouldRequestPermissions + .filter(({ hasPermission }) => !hasPermission) + .map(({ request }) => permissions[request] || `android.permission.${request}`); + }).then(willRequestPermissions => { + permissions.requestPermissions( + willRequestPermissions, + lib.other.ignore, + lib.other.ignore + ); + }).catch(console.log); } } game.download = function (url, folder, onsuccess, onerror, dev, onprogress) { - if (!url.startsWith('http')) { + if (!url.startsWith("http")) { url = get.url(dev) + url; } var fileTransfer = new FileTransfer(); @@ -69,176 +90,259 @@ export async function cordovaReady() { }; } lib.config.brokenFile.add(folder); - game.saveConfigValue('brokenFile'); - fileTransfer.download(encodeURI(url), encodeURI(folder), function () { - lib.config.brokenFile.remove(folder); - game.saveConfigValue('brokenFile'); - if (onsuccess) { - onsuccess(); - } - }, onerror); + game.saveConfigValue("brokenFile"); + fileTransfer.download( + encodeURI(url), + encodeURI(folder), + function () { + lib.config.brokenFile.remove(folder); + game.saveConfigValue("brokenFile"); + if (onsuccess) { + onsuccess(); + } + }, + onerror + ); }; game.readFile = function (filename, callback, onerror) { - window.resolveLocalFileSystemURL(nonameInitialized, function (entry) { - entry.getFile(filename, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - callback(e.target.result); - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }, onerror); - }, onerror); - }, onerror); + window.resolveLocalFileSystemURL( + nonameInitialized, + function (entry) { + entry.getFile( + filename, + {}, + function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + callback(e.target.result); + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }, onerror); + }, + onerror + ); + }, + onerror + ); }; game.readFileAsText = function (filename, callback, onerror) { - window.resolveLocalFileSystemURL(nonameInitialized, function (entry) { - entry.getFile(filename, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - callback(e.target.result); - }; - fileReader.readAsText(fileToLoad, "UTF-8"); - }, onerror); - }, onerror); - }, onerror); + window.resolveLocalFileSystemURL( + nonameInitialized, + function (entry) { + entry.getFile( + filename, + {}, + function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + callback(e.target.result); + }; + fileReader.readAsText(fileToLoad, "UTF-8"); + }, onerror); + }, + onerror + ); + }, + onerror + ); }; game.writeFile = function (data, path, name, callback) { game.ensureDirectory(path, function () { - if (Object.prototype.toString.call(data) == '[object File]') { + if (Object.prototype.toString.call(data) == "[object File]") { var fileReader = new FileReader(); fileReader.onload = function (e) { game.writeFile(e.target.result, path, name, callback); }; fileReader.readAsArrayBuffer(data, "UTF-8"); - } - else { - window.resolveLocalFileSystemURL(nonameInitialized + path, function (entry) { - entry.getFile(name, { create: true }, function (fileEntry) { - fileEntry.createWriter(function (fileWriter) { - fileWriter.onwriteend = callback; - fileWriter.write(data); - }, callback); - }, callback); - }, callback); + } else { + window.resolveLocalFileSystemURL( + nonameInitialized + path, + function (entry) { + entry.getFile( + name, + { create: true }, + function (fileEntry) { + fileEntry.createWriter(function (fileWriter) { + fileWriter.onwriteend = callback; + fileWriter.write(data); + }, callback); + }, + callback + ); + }, + callback + ); } }); }; game.removeFile = function (dir, callback) { - window.resolveLocalFileSystemURL(nonameInitialized, function (entry) { - entry.getFile(dir, {}, function (fileEntry) { - fileEntry.remove(); - if (callback) callback(); - }, callback || function () { }); - }, callback || function () { }); + window.resolveLocalFileSystemURL( + nonameInitialized, + function (entry) { + entry.getFile( + dir, + {}, + function (fileEntry) { + fileEntry.remove(); + if (callback) callback(); + }, + callback || function () {} + ); + }, + callback || function () {} + ); }; game.getFileList = (dir, success, failure) => { - var files = [], folders = []; - window.resolveLocalFileSystemURL(nonameInitialized + dir, entry => { - var dirReader = entry.createReader(); - var entries = []; - var readEntries = () => { - dirReader.readEntries(results => { - if (!results.length) { - entries.sort(); - for (var i = 0; i < entries.length; i++) { - if (entries[i].isDirectory) { - folders.push(entries[i].name); - } - else { - files.push(entries[i].name); + var files = [], + folders = []; + window.resolveLocalFileSystemURL( + nonameInitialized + dir, + (entry) => { + var dirReader = entry.createReader(); + var entries = []; + var readEntries = () => { + dirReader.readEntries((results) => { + if (!results.length) { + entries.sort(); + for (var i = 0; i < entries.length; i++) { + if (entries[i].isDirectory) { + folders.push(entries[i].name); + } else { + files.push(entries[i].name); + } } + success(folders, files); + } else { + entries = entries.concat(Array.from(results)); + readEntries(); } - success(folders, files); - } - else { - entries = entries.concat(Array.from(results)); - readEntries(); - } - }, failure); - }; - readEntries(); - }, failure); + }, failure); + }; + readEntries(); + }, + failure + ); }; game.ensureDirectory = (list, callback, file) => { - const directoryList = typeof list == 'string' ? [list] : list.slice().reverse(), num = file ? 1 : 0, access = (entry, directory, createDirectory) => { - if (directory.length <= num) { - createDirectory(); - return; - } - const str = directory.pop(); - return new Promise((resolve, reject) => entry.getDirectory(str, { - create: false - }, resolve, reject)).catch(() => new Promise(resolve => entry.getDirectory(str, { - create: true - }, resolve))).then(directoryEntry => access(directoryEntry, directory, createDirectory)); - }; - return new Promise((resolve, reject) => window.resolveLocalFileSystemURL(nonameInitialized, rootEntry => { - const createDirectory = () => { - if (directoryList.length) access(rootEntry, directoryList.pop().split('/').reverse(), createDirectory); - if (typeof callback == 'function') callback(); - resolve(); + const directoryList = typeof list == "string" ? [list] : list.slice().reverse(), + num = file ? 1 : 0, + access = (entry, directory, createDirectory) => { + if (directory.length <= num) { + createDirectory(); + return; + } + const str = directory.pop(); + return new Promise((resolve, reject) => + entry.getDirectory( + str, + { + create: false, + }, + resolve, + reject + ) + ) + .catch( + () => + new Promise((resolve) => + entry.getDirectory( + str, + { + create: true, + }, + resolve + ) + ) + ) + .then((directoryEntry) => access(directoryEntry, directory, createDirectory)); }; - createDirectory(); - }, reject)); + return new Promise((resolve, reject) => + window.resolveLocalFileSystemURL( + nonameInitialized, + (rootEntry) => { + const createDirectory = () => { + if (directoryList.length) + access(rootEntry, directoryList.pop().split("/").reverse(), createDirectory); + if (typeof callback == "function") callback(); + resolve(); + }; + createDirectory(); + }, + reject + ) + ); }; game.createDir = (directory, successCallback, errorCallback) => { - const paths = directory.split('/').reverse(); - new Promise((resolve, reject) => window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject)) - .then(directoryEntry => { - const redo = entry => new Promise((resolve, reject) => entry.getDirectory(paths.pop(), { - create: true - }, resolve, reject)).then(resolvedDirectoryEntry => { - if (paths.length) return redo(resolvedDirectoryEntry); - if (typeof successCallback == 'function') successCallback(); - }); + const paths = directory.split("/").reverse(); + new Promise((resolve, reject) => + window.resolveLocalFileSystemURL(nonameInitialized, resolve, reject) + ).then( + (directoryEntry) => { + const redo = (entry) => + new Promise((resolve, reject) => + entry.getDirectory( + paths.pop(), + { + create: true, + }, + resolve, + reject + ) + ).then((resolvedDirectoryEntry) => { + if (paths.length) return redo(resolvedDirectoryEntry); + if (typeof successCallback == "function") successCallback(); + }); return redo(directoryEntry); - }, reason => { - if (typeof errorCallback != 'function') return Promise.reject(reason); - errorCallback(reason); - }); + }, + (reason) => { + if (typeof errorCallback != "function") return Promise.reject(reason); + errorCallback(reason); + } + ); }; game.removeDir = (directory, successCallback, errorCallback) => { - window.resolveLocalFileSystemURL(`${nonameInitialized}${directory}`, directoryEntry => { - directoryEntry.removeRecursively(() => { - if (typeof successCallback == 'function') successCallback(); - }); - }, e => { - if (typeof errorCallback == 'function') errorCallback(e); - else throw e; - }); + window.resolveLocalFileSystemURL( + `${nonameInitialized}${directory}`, + (directoryEntry) => { + directoryEntry.removeRecursively(() => { + if (typeof successCallback == "function") successCallback(); + }); + }, + (e) => { + if (typeof errorCallback == "function") errorCallback(e); + else throw e; + } + ); }; if (ui.updateUpdate) { ui.updateUpdate(); } var showbar = function () { if (window.StatusBar) { - if (lib.device == 'android') { + if (lib.device == "android") { if (lib.config.show_statusbar_android) { window.StatusBar.overlaysWebView(false); - window.StatusBar.backgroundColorByName('black'); + window.StatusBar.backgroundColorByName("black"); window.StatusBar.show(); } - } - else if (lib.device == 'ios') { - if (lib.config.show_statusbar_ios != 'off' && lib.config.show_statusbar_ios != 'auto') { - if (lib.config.show_statusbar_ios == 'default') { + } else if (lib.device == "ios") { + if (lib.config.show_statusbar_ios != "off" && lib.config.show_statusbar_ios != "auto") { + if (lib.config.show_statusbar_ios == "default") { window.StatusBar.overlaysWebView(false); - } - else { + } else { window.StatusBar.overlaysWebView(true); } - window.StatusBar.backgroundColorByName('black'); + window.StatusBar.backgroundColorByName("black"); window.StatusBar.show(); } } } - } + }; if (lib.arenaReady) { lib.arenaReady.push(showbar); - } - else { + } else { showbar(); } } diff --git a/noname/init/import.js b/noname/init/import.js index 2b7f302b5..776ea605c 100644 --- a/noname/init/import.js +++ b/noname/init/import.js @@ -1,150 +1,166 @@ -import { Game as game } from '../game/index.js'; -import { lib } from '../library/index.js'; - -/** - * @param {string} name - 卡牌包名 - * @returns {Promise} - */ -export const importCardPack = generateImportFunction('card', (name) => `../../card/${name}.js`) - -/** - * @param {string} name - 武将包名 - * @returns {Promise} - */ -export const importCharacterPack = generateImportFunction('character', (name) => `../../character/${name}.js`) - -/** - * @param {string} name - 扩展名 - * @returns {Promise} - */ -export const importExtension = generateImportFunction('extension', (name) => `../../extension/${name}/extension.js`) - -/** - * @param {string} name - 模式名 - * @returns {Promise} - */ -export const importMode = generateImportFunction('mode', (name) => `../../mode/${name}.js`) - -/** - * 生成导入 - * - * @param { 'card' | 'character' | 'extension' | 'mode' } type - * @param {(name: string) => string} pathParser - * @returns {(name: string) => Promise} - */ -function generateImportFunction(type, pathParser) { - return async (name) => { - if (type == 'extension' && !game.hasExtension(name) && !lib.config.all.stockextension.includes(name)) { - // @ts-ignore - await game.import(type, await createEmptyExtension(name)); - return; - } - if(type == 'mode' && lib.mode[name] && lib.mode[name].fromextension){ - let loadModeMethod = lib.init['setMode_'+name]; - if(typeof loadModeMethod === 'function'){ - await Promise.resolve(loadModeMethod()); - return; - } - } - let path = pathParser(name); - // 通过浏览器自带的script标签导入可直接获取报错信息,且不会影响JS运行 - // 此时代码内容也将缓存在浏览器中,故再次import后将不会重新执行代码内容(测试下来如此) - const [status, script] = await new Promise(resolve => { - const createScript = () => { - const script = document.createElement('script'); - script.type = 'module'; - script.src = `${lib.assetURL}noname/init/${path}`; - script.onload = () => resolve(['ok', script]); - return script; - }; - let script = createScript(); - script.onerror = (e) => { - if (path.endsWith('.js') && window.isSecureContext) { - path = path.slice(0, -3) + '.ts'; - script.remove(); - let ts = createScript(); - ts.onerror = (e2) => { - if (lib.path.basename(path) === 'extension.js' && lib.path.dirname(path).endsWith('/extension')) { - console.error(`扩展《${name}》加载失败`, e, e2); - let remove = confirm(`扩展《${name}》加载失败,是否移除此扩展?此操作不会移除目录下的文件。`); - if (remove) { - lib.config.extensions.remove(name); - game.saveConfig('extensions', lib.config.extensions); - } - } - resolve(['error', ts]); - } - document.head.appendChild(ts); - } else { - resolve(['error', script]); - } - }; - document.head.appendChild(script); - }); - script.remove(); - if (status === 'error') { - if (type === 'character') { - console.error('如果您在扩展中使用了game.import创建武将包,请将以下代码删除: lib.config.all.characters.push(\'武将包名\');'); - } - return; - } - const modeContent = await import(path); - if (!modeContent.type) return; - if (modeContent.type !== type) throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`); - // @ts-ignore - await game.import(type, modeContent.default); - } -} - -async function createEmptyExtension(name) { - const extensionInfo = await lib.init.promises.json(`${lib.assetURL}extension/${name}/info.json`)//await import(`../../extension/${name}/info.json`,{assert:{type:'json'}}) - .then(info => info, () => { - return { - name: name, - intro: `扩展《${name}》尚未开启,请开启后查看信息。(建议扩展添加info.json以在关闭时查看信息)`, - author: "未知", - diskURL: "", - forumURL: "", - version: "1.0", - }; - }); - return { - name: extensionInfo.name, - content: function (config, pack) { }, - precontent: function () { }, - config: {}, - help: {}, - package: { - character: { - character: { - }, - translate: { - }, - }, - card: { - card: { - }, - translate: { - }, - list: [], - }, - skill: { - skill: { - }, - translate: { - }, - }, - intro: extensionInfo.intro ? extensionInfo.intro.replace("${assetURL}", lib.assetURL) : "", - author: extensionInfo.author ? extensionInfo.author : "未知", - diskURL: extensionInfo.diskURL ? extensionInfo.diskURL : "", - forumURL: extensionInfo.forumURL ? extensionInfo.forumURL : "", - version: extensionInfo.version ? extensionInfo.version : "1.0.0", - }, - files: { - "character": [], - "card": [], - "skill": [], - "audio": [] - } - } -} \ No newline at end of file +import { game } from "../game/index.js"; +import { lib } from "../library/index.js"; + +/** + * @param {string} name - 卡牌包名 + * @returns {Promise} + */ +export const importCardPack = generateImportFunction("card", (name) => `../../card/${name}.js`); + +/** + * @param {string} name - 武将包名 + * @returns {Promise} + */ +export const importCharacterPack = generateImportFunction( + "character", + (name) => `../../character/${name}.js` +); + +/** + * @param {string} name - 扩展名 + * @returns {Promise} + */ +export const importExtension = generateImportFunction( + "extension", + (name) => `../../extension/${name}/extension.js` +); + +/** + * @param {string} name - 模式名 + * @returns {Promise} + */ +export const importMode = generateImportFunction("mode", (name) => `../../mode/${name}.js`); + +/** + * 生成导入 + * + * @param { 'card' | 'character' | 'extension' | 'mode' } type + * @param {(name: string) => string} pathParser + * @returns {(name: string) => Promise} + */ +function generateImportFunction(type, pathParser) { + return async (name) => { + if ( + type == "extension" && + !game.hasExtension(name) && + !lib.config.all.stockextension.includes(name) + ) { + // @ts-ignore + await game.import(type, await createEmptyExtension(name)); + return; + } + if (type == "mode" && lib.mode[name] && lib.mode[name].fromextension) { + let loadModeMethod = lib.init["setMode_" + name]; + if (typeof loadModeMethod === "function") { + await Promise.resolve(loadModeMethod()); + return; + } + } + let path = pathParser(name); + // 通过浏览器自带的script标签导入可直接获取报错信息,且不会影响JS运行 + // 此时代码内容也将缓存在浏览器中,故再次import后将不会重新执行代码内容(测试下来如此) + const [status, script] = await new Promise((resolve) => { + const createScript = () => { + const script = document.createElement("script"); + script.type = "module"; + script.src = `${lib.assetURL}noname/init/${path}`; + script.onload = () => resolve(["ok", script]); + return script; + }; + let script = createScript(); + script.onerror = (e) => { + if (path.endsWith(".js") && window.isSecureContext) { + path = path.slice(0, -3) + ".ts"; + script.remove(); + let ts = createScript(); + ts.onerror = (e2) => { + if ( + lib.path.basename(path) === "extension.js" && + lib.path.dirname(path).endsWith("/extension") + ) { + console.error(`扩展《${name}》加载失败`, e, e2); + let remove = confirm( + `扩展《${name}》加载失败,是否移除此扩展?此操作不会移除目录下的文件。` + ); + if (remove) { + lib.config.extensions.remove(name); + game.saveConfig("extensions", lib.config.extensions); + } + } + resolve(["error", ts]); + }; + document.head.appendChild(ts); + } else { + resolve(["error", script]); + } + }; + document.head.appendChild(script); + }); + script.remove(); + if (status === "error") { + if (type === "character") { + console.error( + "如果您在扩展中使用了game.import创建武将包,请将以下代码删除: lib.config.all.characters.push('武将包名');" + ); + } + return; + } + const modeContent = await import(path); + if (!modeContent.type) return; + if (modeContent.type !== type) + throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`); + // @ts-ignore + await game.import(type, modeContent.default); + }; +} + +async function createEmptyExtension(name) { + const extensionInfo = await lib.init.promises + .json(`${lib.assetURL}extension/${name}/info.json`) //await import(`../../extension/${name}/info.json`,{assert:{type:'json'}}) + .then( + (info) => info, + () => { + return { + name: name, + intro: `扩展《${name}》尚未开启,请开启后查看信息。(建议扩展添加info.json以在关闭时查看信息)`, + author: "未知", + diskURL: "", + forumURL: "", + version: "1.0", + }; + } + ); + return { + name: extensionInfo.name, + content: function (config, pack) {}, + precontent: function () {}, + config: {}, + help: {}, + package: { + character: { + character: {}, + translate: {}, + }, + card: { + card: {}, + translate: {}, + list: [], + }, + skill: { + skill: {}, + translate: {}, + }, + intro: extensionInfo.intro ? extensionInfo.intro.replace("${assetURL}", lib.assetURL) : "", + author: extensionInfo.author ? extensionInfo.author : "未知", + diskURL: extensionInfo.diskURL ? extensionInfo.diskURL : "", + forumURL: extensionInfo.forumURL ? extensionInfo.forumURL : "", + version: extensionInfo.version ? extensionInfo.version : "1.0.0", + }, + files: { + character: [], + card: [], + skill: [], + audio: [], + }, + }; +} diff --git a/noname/init/index.js b/noname/init/index.js index e1af73d4e..0ce2386db 100644 --- a/noname/init/index.js +++ b/noname/init/index.js @@ -1,1091 +1,1205 @@ - -import { AI as ai } from '../ai/index.js'; -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; - -import { userAgent, nonameInitialized } from '../util/index.js'; -import * as config from '../util/config.js'; -import { promiseErrorHandlerMap } from '../util/browser.js'; -import { gnc } from '../gnc/index.js'; - -import { importCardPack, importCharacterPack, importExtension, importMode } from './import.js'; -import { onload } from './onload.js'; - -// 判断是否从file协议切换到http/s协议 -export function canUseHttpProtocol() { - // 如果是http了就不用 - if (location.protocol.startsWith('http')) return false; - // 首次启动不更新(即还没进行过新手教程) - if (!config.get('new_tutorial')) return false; - if (typeof nonameInitialized == 'string') { - // 手机端 - if (window.cordova) { - // 直接确定包名 - if (nonameInitialized.endsWith('com.noname.shijian/')) { - // 每个app自定义能升级的渠道,比如判断版本 - // @ts-ignore - return window.noname_shijianInterfaces.getApkVersion() >= 16000; - } - } - // 电脑端 - else if (typeof window.require == 'function' && typeof window.process == 'object') { - // 从json判断版本号 - const fs = require('fs'); - const path = require('path'); - if (fs.existsSync(path.join(__dirname, 'package.json'))) { - // @ts-ignore - const json = require('./package.json'); - // 诗笺电脑版的判断 - return json && Number(json.installerVersion) >= 1.7; - } - } - // 浏览器端 - else { - return location.protocol.startsWith('http'); - } - } - return false; -} - -/** - * 传递升级完成的信息 - * @returns { string | void } 返回一个网址 - */ -export function sendUpdate() { - // 手机端 - if (window.cordova) { - // 直接确定包名 - if (nonameInitialized && nonameInitialized.includes('com.noname.shijian')) { - // 给诗笺版apk的java层传递升级完成的信息 - // @ts-ignore - return window.noname_shijianInterfaces.sendUpdate() + '?sendUpdate=true'; - } - } - // 电脑端 - else if (typeof window.require == 'function' && typeof window.process == 'object') { - // 从json判断版本号 - const fs = require('fs'); - const path = require('path'); - if (fs.existsSync(path.join(__dirname, 'package.json'))) { - // @ts-ignore - const json = require('./package.json'); - // 诗笺电脑版的判断 - if (json && Number(json.installerVersion) >= 1.7) { - fs.writeFileSync(path.join(__dirname, 'Home', 'saveProtocol.txt'), ''); - // 启动http - const cp = require('child_process'); - cp.exec(`start /min ${__dirname}\\noname-server.exe -platform=electron`, (err, stdout, stderr) => { }); - return `http://localhost:8089/app.html?sendUpdate=true`; - } - } - } - // 浏览器端 - else { - return location.href; - } -} - -// 无名杀,启动! -export async function boot() { - // 不想看,反正别动 - if (typeof __dirname === 'string' && __dirname.length) { - const dirsplit = __dirname.split('/'); - for (let i = 0; i < dirsplit.length; i++) { - if (dirsplit[i]) { - var c = dirsplit[i][0]; - lib.configprefix += /[A-Z]|[a-z]/.test(c) ? c : '_'; - } - } - lib.configprefix += '_'; - } - - // 加载polyfill内容 - await import('./polyfill.js'); - - // 设定游戏加载时间,超过时间未加载就提醒 - const configLoadTime = localStorage.getItem(lib.configprefix + 'loadtime'); - // 现在不暴露到全局变量里了,直接传给onload - const resetGameTimeout = setTimeout(lib.init.reset, configLoadTime ? parseInt(configLoadTime) : 10000); - - if (typeof window.cordovaLoadTimeout != 'undefined') { - clearTimeout(window.cordovaLoadTimeout); - delete window.cordovaLoadTimeout; - } - - for (const link of document.head.querySelectorAll('link')) { - if (link.href.includes('app/color.css')) { - link.remove(); - break; - } - } - - setServerIndex(); - setBackground(); - - Reflect.set(lib, 'get', get); - Reflect.set(lib, 'ui', ui); - Reflect.set(lib, 'ai', ai); - Reflect.set(lib, 'game', game); - _status.event = lib.element.GameEvent.initialGameEvent(); - - setWindowListener(); - const promiseErrorHandler = await setOnError(); - - // 确认手机端平台 - const noname_inited = localStorage.getItem('noname_inited'); - if (noname_inited && noname_inited !== 'nodejs') { - const ua = userAgent; - if (ua.includes('android')) { - Reflect.set(lib, 'device', 'android'); - } - else if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('macintosh')) { - Reflect.set(lib, 'device', 'ios'); - } - } - - // 在dom加载完后执行相应的操作 - const waitDomLoad = new Promise((resolve) => { - if (document.readyState !== 'complete') { - window.onload = resolve; - } else resolve(void 0); - }).then(onWindowReady.bind(window)); - - - // 闭源客户端检测并提醒 - if (lib.assetURL.includes('com.widget.noname.qingyao') || lib.assetURL.includes('online.nonamekill.android')) { - alert('您正在一个不受信任的闭源客户端上运行《无名杀》。建议您更换为其他开源的无名杀客户端,避免给您带来不必要的损失。'); - } - - // Electron平台 - if (typeof window.require === 'function') { - const { nodeReady } = await import('./node.js'); - nodeReady(); - } - else { - Reflect.set(lib, 'path', (await import('../library/path.js')).default) - if (typeof lib.device != 'undefined') { - const script = document.createElement('script') - script.src = 'cordova.js' - document.body.appendChild(script) - await new Promise((resolve) => { - document.addEventListener('deviceready', async () => { - const { cordovaReady } = await import('./cordova.js') - await cordovaReady() - resolve(void 0) - }) - }) - } - else { - //为其他自定义平台提供文件读写函数赋值的一种方式。 - //但这种方式只允许修改game的文件读写函数。 - if (typeof window.initReadWriteFunction == 'function') { - const g = {} - const ReadWriteFunctionName = ['download', 'readFile', 'readFileAsText', 'writeFile', 'removeFile', 'getFileList', 'ensureDirectory', 'createDir', 'removeDir'] - ReadWriteFunctionName.forEach(prop => { - Object.defineProperty(g, prop, { - configurable: true, - get() { return undefined }, - set(newValue) { - if (typeof newValue == 'function') { - delete g[prop] - g[prop] = game[prop] = newValue - } - } - }) - }) - // @ts-ignore - await window.initReadWriteFunction(g).catch(e => { - console.error('文件读写函数初始化失败:', e) - }) - } - window.onbeforeunload = function () { - if (config.get('confirm_exit') && !_status.reloading) { - return '是否离开游戏?' - } - else { - return null - } - } - } - } - - const loadCssPromise = loadCss(); - const loadConfigPromise = loadConfig(); - await loadCssPromise; - const config2 = await loadConfigPromise; - - // 读取模式 - if (config2.mode) config.set('mode', config2.mode); - if (config.get('mode_config')[config.get('mode')] === undefined) - config.get('mode_config')[config.get('mode')] = {}; - - // 复制共有模式设置 - for (const name in config.get('mode_config').global) { - if (config.get('mode_config')[config.get('mode')][name] === undefined) { - config.get('mode_config')[config.get('mode')][name] = config.get('mode_config').global[name]; - } - } - - if (config.get('characters')) - config.set('defaultcharacters', config.get('characters').slice(0)); - if (config.get('cards')) - config.set('defaultcards', config.get('cards').slice(0)); - - for (const name in config2) { - if (name.includes('_mode_config')) { - var thismode = name.substr(name.indexOf('_mode_config') + 13); - if (!config.get('mode_config')[thismode]) - config.get('mode_config')[thismode] = {}; - config.get('mode_config')[thismode][name.substr(0, name.indexOf('_mode_config'))] = config2[name]; - } - else { - config.set(name, config2[name]); - } - } - - for (const name in get.config('translate')) { - lib.translate[name] = get.config('translate')[name]; - } - - config.get('all').characters = []; - config.get('all').cards = []; - config.get('all').plays = []; - config.get('all').mode = []; - - if (config.get('debug')) { - await lib.init.promises.js(`${lib.assetURL}game`, 'asset'); - if (window.noname_skin_list) { - lib.skin = window.noname_skin_list; - delete window.noname_skin_list; - delete window.noname_asset_list; - } - } - - if (Reflect.get(window, 'isNonameServer')) - config.set('mode', 'connect'); - - var pack = Reflect.get(window, 'noname_package'); - Reflect.deleteProperty(window, 'noname_package'); - for (const name in pack.character) { - if (config.get('all').sgscharacters.includes(name) || config.get('hiddenCharacterPack').indexOf(name) == -1) { - config.get('all').characters.push(name); - lib.translate[name + '_character_config'] = pack.character[name]; - } - } - for (const name in pack.card) { - if (config.get('all').sgscards.includes(name) || config.get('hiddenCardPack').indexOf(name) == -1) { - config.get('all').cards.push(name); - lib.translate[name + '_card_config'] = pack.card[name]; - } - } - for (const name in pack.play) { - config.get('all').plays.push(name); - lib.translate[name + '_play_config'] = pack.play[name]; - } - for (const name in pack.submode) { - for (var j in pack.submode[name]) { - lib.translate[name + '|' + j] = pack.submode[name][j]; - } - } - - if (!config.get('gameRecord')) config.set('gameRecord', {}); - for (const name in pack.mode) { - if (config.get('hiddenModePack').indexOf(name) == -1) { - config.get('all').mode.push(name); - lib.translate[name] = pack.mode[name]; - if (!config.get('gameRecord')[name]) - config.get('gameRecord')[name] = { data: {} }; - } - } - if (config.get('all').mode.length == 0) { - config.get('all').mode.push('identity'); - lib.translate.identity = '身份'; - if (!config.get('gameRecord').identity) - config.get('gameRecord').identity = { data: {} }; - } - if (pack.background) { - for (const name in pack.background) { - if (config.get('hiddenBackgroundPack').includes(name)) continue; - lib.configMenu.appearence.config.image_background.item[name] = pack.background[name]; - } - for (let i = 0; i < config.get('customBackgroundPack').length; i++) { - var link = config.get('customBackgroundPack')[i]; - lib.configMenu.appearence.config.image_background.item[link] = link.slice(link.indexOf('_') + 1); - } - lib.configMenu.appearence.config.image_background.item.default = '默认'; - } - if (pack.music) { - if (typeof lib.device != 'undefined' || typeof window.require === 'function') { - lib.configMenu.audio.config.background_music.item.music_custom = '自定义音乐'; - } - config.get('all').background_music = ['music_default']; - for (const name in pack.music) { - config.get('all').background_music.push(name); - lib.configMenu.audio.config.background_music.item[name] = pack.music[name]; - } - if (config.get('customBackgroundMusic')) { - for (const name in config.get('customBackgroundMusic')) { - config.get('all').background_music.push(name); - lib.configMenu.audio.config.background_music.item[name] = config.get('customBackgroundMusic')[name]; - } - } - lib.configMenu.audio.config.background_music.item.music_random = '随机播放'; - lib.configMenu.audio.config.background_music.item.music_off = '关闭'; - } - if (pack.theme) { - for (const name in pack.theme) { - lib.configMenu.appearence.config.theme.item[name] = pack.theme[name]; - } - } - if (config.get('extension_sources')) { - for (const name in config.get('extension_sources')) { - lib.configMenu.general.config.extension_source.item[name] = name; - } - } - - if (pack.font) { - Reflect.get(ui, 'css').fontsheet = lib.init.sheet(); - const appearenceConfig = lib.configMenu.appearence.config, fontSheet = Reflect.get(ui, 'css').fontsheet.sheet, suitsFont = config.get('suits_font'); - Object.keys(pack.font).forEach((value) => { - const font = pack.font[value]; - appearenceConfig.name_font.item[value] = font; - appearenceConfig.identity_font.item[value] = font; - appearenceConfig.cardtext_font.item[value] = font; - appearenceConfig.global_font.item[value] = font; - fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/${value}.woff2');}`, 0); - if (suitsFont) fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/suits.woff2');}`, 0); - }); - if (suitsFont) fontSheet.insertRule(`@font-face {font-family: 'Suits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); - fontSheet.insertRule(`@font-face {font-family: 'NonameSuits'; src: url('${lib.assetURL}font/suits.woff2');}`, 0); - fontSheet.insertRule(`@font-face {font-family: 'MotoyaLMaru'; src: url('${lib.assetURL}font/motoyamaru.woff2');}`, 0); - appearenceConfig.cardtext_font.item.default = '默认'; - appearenceConfig.global_font.item.default = '默认'; - } - - const ua = userAgent; - if ('ontouchstart' in document) { - if (!config.get('totouched')) { - game.saveConfig('totouched', true); - if (typeof lib.device != 'undefined') { - game.saveConfig('low_performance', true); - game.saveConfig('confirm_exit', true); - game.saveConfig('touchscreen', true); - game.saveConfig('fold_mode', false); - if (ua.indexOf('ipad') == -1) { - game.saveConfig('phonelayout', true); - } - else if (Reflect.get(lib, 'device') === 'ios') { - game.saveConfig('show_statusbar_ios', 'overlay'); - } - } - else if (confirm('是否切换到触屏模式?(触屏模式可提高触屏设备的响应速度,但无法使用鼠标)')) { - game.saveConfig('touchscreen', true); - if (ua.includes('iphone') || ua.includes('android')) { - game.saveConfig('phonelayout', true); - } - game.reload(); - } - } - } - else if (config.get('touchscreen')) { - game.saveConfig('touchscreen', false); - } - if (!config.get('toscrolled') && ua.includes('macintosh')) { - game.saveConfig('toscrolled', true); - game.saveConfig('mousewheel', false); - } - - let show_splash = config.get('show_splash'); - if (show_splash == 'off') { - show_splash = false; - } - else if (show_splash == 'init') { - if (localStorage.getItem('show_splash_off')) { - show_splash = false; - } - } - localStorage.removeItem('show_splash_off'); - const extensionlist = []; - if (!localStorage.getItem(lib.configprefix + 'disable_extension')) { - if (config.has('extensions') && config.get('extensions').length) { - Reflect.set(window, 'resetExtension', () => { - for (var i = 0; i < config.get('extensions').length; i++) { - game.saveConfig('extension_' + config.get('extensions')[i] + '_enable', false); - } - // @ts-ignore - localStorage.setItem(lib.configprefix + 'disable_extension', true); - }); - } - for (var name = 0; name < config.get('plays').length; name++) { - if (config.get('all').plays.includes(config.get('plays')[name])) { - extensionlist.push(config.get('plays')[name]); - } - } - for (var name = 0; name < config.get('extensions').length; name++) { - if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { - continue; - } - var extcontent = localStorage.getItem(lib.configprefix + 'extension_' + config.get('extensions')[name]); - if (extcontent) { - //var backup_onload=lib.init.onload; - _status.evaluatingExtension = true; - try { - eval(extcontent); - } - catch (e) { - console.log(e); - } - //lib.init.onload=backup_onload; - _status.evaluatingExtension = false; - } - else { - extensionlist.push(config.get('extensions')[name]); - } - } - } - else { - for (var name = 0; name < config.get('extensions').length; name++) { - if (Reflect.get(window, 'bannedExtensions').includes(config.get('extensions')[name])) { - continue; - } - // @ts-ignore - game.import('extension', { name: config.get('extensions')[name] }); - } - } - - let layout = config.get('layout'); - if (layout == 'default' || lib.layoutfixed.indexOf(config.get('mode')) !== -1) { - layout = 'mobile'; - } - if (layout == 'phone') { - layout = 'mobile'; - game.saveConfig('layout', 'mobile'); - game.saveConfig('phonelayout', true); - } - Reflect.set(game, 'layout', layout); - - if (config.get('image_background_random')) { - if (_status.htmlbg) { - game.saveConfig('image_background', _status.htmlbg); - } - else { - const list = []; - for (const name in lib.configMenu.appearence.config.image_background.item) { - if (name == 'default') continue; - list.push(name); - } - // @ts-ignore - game.saveConfig('image_background', list.randomGet(lib.config.image_background)); - } - lib.init.background(); - } - delete _status.htmlbg; - - // 无名杀更新日志 - if (window.noname_update) { - Reflect.set(lib, 'version', window.noname_update.version); - // 更全面的更新内容 - if (config.get(`version_description_v${window.noname_update.version}`)) { - try { - const description = config.get(`version_description_v${window.noname_update.version}`); - const html = String.raw; - // 匹配[xx](url)的格式 - const regex = /\[([^\]]*)\]\(([^)]+)\)/g; - lib.changeLog.push( - html` -
                                    - ${description.author.login}于${description.published_at}发布 - `.trim(), - description.body.replaceAll('\n', '
                                    ').replace(regex, function (match, p1, p2) { - // p1 是链接文本,p2 是链接地址 - return `${p1}`; - }) - ); - } catch (e) { - console.error(e); - lib.changeLog.push(...window.noname_update.changeLog); - } - } - // 原更新内容 - else { - lib.changeLog.push(...window.noname_update.changeLog); - } - if (window.noname_update.players) { - lib.changeLog.push('players://' + JSON.stringify(window.noname_update.players)); - } - if (window.noname_update.cards) { - lib.changeLog.push('cards://' + JSON.stringify(window.noname_update.cards)); - } - delete window.noname_update; - } - - // 虽然但是,我就暴露个import,应该没啥问题 - Reflect.set(window, 'game', { - import: game.import.bind(null) - }); - - if (config.get('layout') == 'default') { - config.set('layout', 'mobile'); - } - - const stylesName = ['layout', 'theme', 'card_style', 'cardback_style', 'hp_style']; - const stylesLoading = [ - lib.init.promises.css(lib.assetURL + 'layout/' + layout, 'layout', void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/' + config.get('theme'), 'style', void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/card', config.get('card_style'), void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/cardback', config.get('cardback_style'), void 0, true), - lib.init.promises.css(lib.assetURL + 'theme/style/hp', config.get('hp_style'), void 0, true) - ]; - - if (get.is.phoneLayout()) { - stylesName.push('phone'); - stylesLoading.push(lib.init.promises.css(lib.assetURL + 'layout/default', 'phone')); - } - else { - Reflect.get(ui, 'css').phone = lib.init.css(); - } - - initSheet(Reflect.get(lib, 'config')); - - config.set('duration', 500); - - if (!config.get('touchscreen')) { - document.addEventListener('mousewheel', ui.click.windowmousewheel, { passive: true }); - document.addEventListener('mousemove', ui.click.windowmousemove); - document.addEventListener('mousedown', ui.click.windowmousedown); - document.addEventListener('mouseup', ui.click.windowmouseup); - document.addEventListener('contextmenu', ui.click.right); - } - else { - document.addEventListener('touchstart', ui.click.touchconfirm); - document.addEventListener('touchstart', ui.click.windowtouchstart); - document.addEventListener('touchend', ui.click.windowtouchend); - document.addEventListener('touchmove', ui.click.windowtouchmove); - } - - await waitDomLoad; - - const stylesLoaded = await Promise.all(stylesLoading); - const stylesLength = Math.min(stylesName.length, stylesLoaded.length); - for (let i = 0; i < stylesLength; ++i) { - Reflect.get(ui, 'css')[stylesName[i]] = stylesLoaded[i]; - } - - if (extensionlist.length) { - _status.extensionLoading = []; - _status.extensionLoaded = []; - - const bannedExtensions = Reflect.get(window, 'bannedExtensions'); - - const extensionsLoading = []; - for (const name of extensionlist) { - if (bannedExtensions.includes(name)) continue; - extensionsLoading.push(importExtension(name)); - } - - const extErrorList = []; - for (const promise of extensionsLoading) { - await promise.catch(async (error) => { - extErrorList.add(error); - if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return; - // @ts-ignore - await promiseErrorHandler.onHandle({ promise }); - }); - } - for (const promise of _status.extensionLoading) { - await promise.catch(async (error) => { - if (extErrorList.includes(error)) return; - if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return; - // @ts-ignore - await promiseErrorHandler.onHandle({ promise }); - }); - } - // await Promise.allSettled(_status.extensionLoading); - - _status.extensionLoaded.filter(name => game.hasExtension(name)).forEach((name) => { - lib.announce.publish("Noname.Init.Extension.onLoad", name); - lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0); - }); - delete _status.extensionLoading; - } - - const isArray = Array.isArray; - if (isArray(lib.onprepare) && lib.onprepare.length) { - _status.onprepare = Object.freeze(lib.onprepare.map((fn) => { - if (typeof fn !== "function") return; - return (gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn)(); - })); - } - - const toLoad = []; - - if (localStorage.getItem(`${lib.configprefix}playback`)) - toLoad.push(importMode(config.get('mode'))); - else if ((localStorage.getItem(`${lib.configprefix}directstart`) || !show_splash) && config.get('all').mode.includes(config.get('mode'))) - toLoad.push(importMode(config.get('mode'))); - - for (const cardPack of config.get('all').cards) { - toLoad.push(importCardPack(cardPack)); - } - for (const characterPack of config.get('all').characters) { - toLoad.push(importCharacterPack(characterPack)); - } - toLoad.push(lib.init.promises.js(`${lib.assetURL}character`, 'rank')); - - if (_status.javaScriptExtensions) { - const loadJavaScriptExtension = async (javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index) => { - if (!pathArray && !fileArray && !onLoadArray && !onErrorArray) { - try { - await lib.init.promises.js(javaScriptExtension.path, javaScriptExtension.file); - if (typeof javaScriptExtension.onload == 'function') javaScriptExtension.onload(); - } catch { - if (typeof javaScriptExtension.onerror == 'function') javaScriptExtension.onerror(); - } - return; - } - if (typeof index != 'number') index = 0; - if (pathArray && index >= javaScriptExtension.path.length) return; - if (fileArray && index >= javaScriptExtension.file.length) return; - if (onLoadArray && index >= javaScriptExtension.onload.length) return; - if (onErrorArray && index >= javaScriptExtension.onerror.length) return; - const path = pathArray ? javaScriptExtension.path[index] : javaScriptExtension.path; - const file = fileArray ? javaScriptExtension.file[index] : javaScriptExtension.file; - const onLoad = onLoadArray ? javaScriptExtension.onload[index] : javaScriptExtension.onload; - const onError = onErrorArray ? javaScriptExtension.onerror[index] : javaScriptExtension.onerror; - try { - await lib.init.promises.js(path, file); - if (typeof onLoad == 'function') onLoad(); - } catch { - if (typeof onError == 'function') onError(); - } - await loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray, index + 1); - }; - _status.javaScriptExtensions.forEach((javaScriptExtension) => { - const pathArray = isArray(javaScriptExtension.path); - const fileArray = isArray(javaScriptExtension.file); - const onLoadArray = isArray(javaScriptExtension.onLoad); - const onErrorArray = isArray(javaScriptExtension.onError); - toLoad.push(loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray)); - }); - } - - await Promise.allSettled(toLoad); - - if (_status.importing) { - /** - * @type {Promise[]} - */ - let promises = lib.creation.array; - for (const type in _status.importing) { - // @ts-ignore - promises.addArray(_status.importing[type]); - } - await Promise.allSettled(promises); - delete _status.importing; - } - - await onload(resetGameTimeout); -} - -function initSheet(libConfig) { - if (libConfig.player_style && libConfig.player_style != 'default' && libConfig.player_style != 'custom') { - var str = ''; - switch (libConfig.player_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; - } - Reflect.get(ui, 'css').player_stylesheet = lib.init.sheet('#window .player{background-image:' + str + '}'); - } - if (libConfig.border_style && libConfig.border_style != 'default' && libConfig.border_style != 'custom' && libConfig.border_style != 'auto') { - Reflect.get(ui, 'css').border_stylesheet = lib.init.sheet(); - var bstyle = libConfig.border_style; - if (bstyle.startsWith('dragon_')) { - bstyle = bstyle.slice(7); - } - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '1.png")}', 0); - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + lib.assetURL + 'theme/style/player/' + bstyle + '3.png")}', 0); - Reflect.get(ui, 'css').border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); - } - if (libConfig.control_style && libConfig.control_style != 'default' && libConfig.control_style != 'custom') { - var str = ''; - switch (libConfig.control_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; - } - if (libConfig.control_style == 'wood') { - Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:' + str + '}'); - } - else { - Reflect.get(ui, 'css').control_stylesheet = lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:' + str + '}'); - } - } - if (libConfig.menu_style && libConfig.menu_style != 'default' && libConfig.menu_style != 'custom') { - var str = ''; - switch (libConfig.menu_style) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; - } - Reflect.get(ui, 'css').menu_stylesheet = lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:' + str + '}'); - } -} - -async function loadConfig() { - Reflect.set(lib, 'config', Reflect.get(window, 'config')); - Reflect.set(lib, 'configOL', {}); - Reflect.deleteProperty(window, 'config'); - - let result; - if (localStorage.getItem(`${lib.configprefix}nodb`)) - Reflect.set(window, 'nodb', true); - if (window.indexedDB && !Reflect.get(window, 'nodb')) { - const event = await new Promise((resolve, reject) => { - const idbOpenDBRequest = window.indexedDB.open(`${lib.configprefix}data`, 4); - idbOpenDBRequest.onerror = reject; - idbOpenDBRequest.onsuccess = resolve; - idbOpenDBRequest.onupgradeneeded = idbVersionChangeEvent => { - // @ts-expect-error MaybeHave - const idbDatabase = idbVersionChangeEvent.target.result; - if (!idbDatabase.objectStoreNames.contains('video')) idbDatabase.createObjectStore('video', { - keyPath: 'time' - }); - if (!idbDatabase.objectStoreNames.contains('image')) idbDatabase.createObjectStore('image'); - if (!idbDatabase.objectStoreNames.contains('audio')) idbDatabase.createObjectStore('audio'); - if (!idbDatabase.objectStoreNames.contains('config')) idbDatabase.createObjectStore('config'); - if (!idbDatabase.objectStoreNames.contains('data')) idbDatabase.createObjectStore('data'); - }; - }); - Reflect.set(lib, 'db', event.target.result); - - const object = await game.getDB('config'); - - if (!object.storageImported) { - try { - const item = localStorage.getItem(`${lib.configprefix}config`); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object') throw 'err'; - } - catch (err) { - result = {}; - } - Object.keys(result).forEach(key => game.saveConfig(key, result[key])); - Object.keys(lib.mode).forEach(key => { - try { - const item = localStorage.getItem(`${lib.configprefix}${key}`); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object' || get.is.empty(result)) throw 'err'; - } - catch (err) { - result = false; - } - localStorage.removeItem(`${lib.configprefix}${key}`); - if (result) game.putDB('data', key, result); - }); - game.saveConfig('storageImported', true); - lib.init.background(); - localStorage.removeItem(`${lib.configprefix}config`); - } - else result = object; - } else { - try { - const item = localStorage.getItem(lib.configprefix + 'config'); - if (!item) throw 'err'; - result = JSON.parse(item); - if (!result || typeof result != 'object') throw 'err'; - } - catch (err) { - result = {}; - localStorage.setItem(lib.configprefix + 'config', JSON.stringify({})); - } - } - - return result; -} - -async function loadCss() { - Reflect.set(ui, 'css', { - menu: await lib.init.promises.css(lib.assetURL + 'layout/default', 'menu'), - default: await lib.init.promises.css(lib.assetURL + 'layout/default', 'layout') - }); -} - -/** - * `window.onload`触发时执行的函数 - * - * 目前无任何内容,预防以后出现需要的情况 - * - * @deprecated - * @return {Promise} - */ -async function onWindowReady() { -} - -function setBackground() { - let htmlbg = localStorage.getItem(lib.configprefix + 'background'); - if (htmlbg) { - if (htmlbg[0] == '[') { - try { - htmlbg = JSON.parse(htmlbg); - if (!htmlbg) throw new Error(); - htmlbg = htmlbg[get.rand(htmlbg.length)]; - if (htmlbg.startsWith('custom_')) { - throw ('err'); - } - _status.htmlbg = htmlbg; - } - catch (e) { - htmlbg = null; - } - } - if (htmlbg) { - document.documentElement.style.backgroundImage = 'url("' + lib.assetURL + 'image/background/' + htmlbg + '.jpg")'; - document.documentElement.style.backgroundSize = 'cover'; - document.documentElement.style.backgroundPosition = '50% 50%'; - } - } -} - -function setServerIndex() { - const index = window.location.href.indexOf('index.html?server='); - if (index !== -1) { - Reflect.set(window, 'isNonameServer', window.location.href.slice(index + 18)); - Reflect.set(window, 'nodb', true); - } else { - const savedIndex = localStorage.getItem(lib.configprefix + 'asserver'); - if (savedIndex) { - Reflect.set(window, 'isNonameServer', savedIndex); - Reflect.set(window, 'isNonameServerIp', lib.hallURL); - } - } -} - -async function setOnError() { - const [core] = get.coreInfo(); - - const promiseErrorHandler = new ((core in promiseErrorHandlerMap) ? promiseErrorHandlerMap[core] : promiseErrorHandlerMap.other); - - if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad(); - - window.onunhandledrejection = async (event) => { - if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event); - }; - - window.onerror = function (msg, src, line, column, err) { - if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare(); - const winPath = window.__dirname ? ('file:///' + (__dirname.replace(new RegExp('\\\\', 'g'), '/') + '/')) : ''; - let str = `错误文件: ${typeof src == 'string' ? decodeURI(src).replace(lib.assetURL, '').replace(winPath, '') : '未知文件'}`; - str += `\n错误信息: ${msg}`; - const tip = lib.getErrorTip(msg); - if (tip) str += `\n错误提示: ${tip}`; - str += `\n行号: ${line}`; - str += `\n列号: ${column}`; - const version = typeof lib.version != 'undefined' ? lib.version : ''; - const reg = /[^\d.]/; - const match = version.match(reg) != null; - str += '\n' + `${match ? '游戏' : '无名杀'}版本: ${version || '未知版本'}`; - if (match) str += '\n⚠️您使用的游戏代码不是源于libccy/noname无名杀官方仓库,请自行寻找您所使用的游戏版本开发者反馈!'; - if (_status && _status.event) { - let evt = _status.event; - str += `\nevent.name: ${evt.name}\nevent.step: ${evt.step}`; - // @ts-ignore - if (evt.parent) str += `\nevent.parent.name: ${evt.parent.name}\nevent.parent.step: ${evt.parent.step}`; - // @ts-ignore - if (evt.parent && evt.parent.parent) str += `\nevent.parent.parent.name: ${evt.parent.parent.name}\nevent.parent.parent.step: ${evt.parent.parent.step}`; - if (evt.player || evt.target || evt.source || evt.skill || evt.card) { - str += '\n-------------'; - } - if (evt.player) { - if (lib.translate[evt.player.name]) str += `\nplayer: ${lib.translate[evt.player.name]}[${evt.player.name}]`; - else str += '\nplayer: ' + evt.player.name; - let distance = get.distance(_status.roundStart, evt.player, 'absolute'); - if (distance != Infinity) { - str += `\n座位号: ${distance + 1}`; - } - } - if (evt.target) { - if (lib.translate[evt.target.name]) str += `\ntarget: ${lib.translate[evt.target.name]}[${evt.target.name}]`; - else str += '\ntarget: ' + evt.target.name; - } - if (evt.source) { - if (lib.translate[evt.source.name]) str += `\nsource: ${lib.translate[evt.source.name]}[${evt.source.name}]`; - else str += '\nsource: ' + evt.source.name; - } - if (evt.skill) { - if (lib.translate[evt.skill]) str += `\nskill: ${lib.translate[evt.skill]}[${evt.skill}]`; - else str += '\nskill: ' + evt.skill; - } - if (evt.card) { - if (lib.translate[evt.card.name]) str += `\ncard: ${lib.translate[evt.card.name]}[${evt.card.name}]`; - else str += '\ncard: ' + evt.card.name; - } - } - str += '\n-------------'; - if (typeof line == 'number' && (typeof Reflect.get(game, 'readFile') == 'function' || location.origin != 'file://')) { - const createShowCode = function (lines) { - let showCode = ''; - if (lines.length >= 10) { - if (line > 4) { - for (let i = line - 5; i < line + 6 && i < lines.length; i++) { - showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; - } - } else { - for (let i = 0; i < line + 6 && i < lines.length; i++) { - showCode += `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${lines[i]}\n`; - } - } - } else { - showCode = lines.map((_line, i) => `${i + 1}| ${line == i + 1 ? '⚠️' : ''}${_line}\n`).toString(); - } - return showCode; - }; - //协议名须和html一致(网页端防跨域),且文件是js - if (typeof src == 'string' && src.startsWith(location.protocol) && src.endsWith('.js')) { - //获取代码 - const codes = lib.init.reqSync('local:' + decodeURI(src).replace(lib.assetURL, '').replace(winPath, '')); - if (codes) { - const lines = codes.split("\n"); - str += '\n' + createShowCode(lines); - str += '\n-------------'; - } - } - //解析parsex里的content fun内容(通常是技能content) - // @ts-ignore - else if (err && err.stack && ['at Object.eval [as content]', 'at Proxy.content'].some(str => { - let stackSplit1 = err.stack.split('\n')[1]; - if (stackSplit1) { - return stackSplit1.trim().startsWith(str); - } - return false; - })) { - const codes = _status.event.content; - if (typeof codes == 'function') { - const lines = codes.toString().split("\n"); - str += '\n' + createShowCode(lines); - str += '\n-------------'; - } - } - } - if (err && err.stack) str += '\n' + decodeURI(err.stack).replace(new RegExp(lib.assetURL, 'g'), '').replace(new RegExp(winPath, 'g'), ''); - alert(str); - Reflect.set(window, 'ea', Array.from(arguments)); - Reflect.set(window, 'em', msg); - Reflect.set(window, 'el', line); - Reflect.set(window, 'ec', column); - Reflect.set(window, 'eo', err); - game.print(str); - if (promiseErrorHandler.onErrorFinish) promiseErrorHandler.onErrorFinish(); - // @ts-ignore - if (!lib.config.errstop) { - _status.withError = true; - game.loop(); - } - }; - - return promiseErrorHandler; -} - -function setWindowListener() { - window.onkeydown = function (e) { - if (typeof ui.menuContainer == 'undefined' || !ui.menuContainer.classList.contains('hidden')) { - if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { - if (e.shiftKey) { - if (confirm('是否重置游戏?')) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); - game.reload(); - return; - } - } - else { - game.reload(); - } - } - else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { - if (typeof window.saveNonameInput == 'function') { - window.saveNonameInput(); - } - e.preventDefault(); - e.stopPropagation(); - return false; - } - else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && typeof lib.node != 'undefined') { - lib.node.debug(); - } - } - else { - game.closePopped(); - var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); - for (var i = 0; i < dialogs.length; i++) { - // @ts-ignore - dialogs[i].delete(); - } - if (e.keyCode == 32) { - var node = ui.window.querySelector('pausedbg'); - if (node) { - node.click(); - } - else { - ui.click.pause(); - } - } - else if (e.keyCode == 65) { - if (typeof ui.auto != 'undefined') ui.auto.click(); - } - else if (e.keyCode == 87) { - if (typeof ui.wuxie != 'undefined' && ui.wuxie.style.display != 'none') { - ui.wuxie.classList.toggle('glow'); - } - else if (typeof ui.tempnowuxie != 'undefined') { - ui.tempnowuxie.classList.toggle('glow'); - } - } - else if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { - if (e.shiftKey) { - if (confirm('是否重置游戏?')) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); - localStorage.clear(); - if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); - } - if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); - } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); - game.reload(); - return; - } - } - else { - game.reload(); - } - } - else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && typeof lib.node != 'undefined') { - lib.node.debug(); - } - // else if(e.keyCode==27){ - // if(!ui.arena.classList.contains('paused')) ui.click.config(); - // } - } - }; -} +import { ai } from "../ai/index.js"; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { gnc } from "../gnc/index.js"; +import { userAgent, nonameInitialized } from "../util/index.js"; +import * as config from "../util/config.js"; +import { promiseErrorHandlerMap } from "../util/browser.js"; +import { importCardPack, importCharacterPack, importExtension, importMode } from "./import.js"; +import { onload } from "./onload.js"; + +// 判断是否从file协议切换到http/s协议 +export function canUseHttpProtocol() { + // 如果是http了就不用 + if (location.protocol.startsWith("http")) return false; + // 首次启动不更新(即还没进行过新手教程) + if (!config.get("new_tutorial")) return false; + if (typeof nonameInitialized == "string") { + // 手机端 + if (window.cordova) { + // 直接确定包名 + if (nonameInitialized.endsWith("com.noname.shijian/")) { + // 每个app自定义能升级的渠道,比如判断版本 + // @ts-ignore + return window.noname_shijianInterfaces.getApkVersion() >= 16000; + } + } + // 电脑端 + else if (typeof window.require == "function" && typeof window.process == "object") { + // 从json判断版本号 + const fs = require("fs"); + const path = require("path"); + if (fs.existsSync(path.join(__dirname, "package.json"))) { + // @ts-ignore + const json = require("./package.json"); + // 诗笺电脑版的判断 + return json && Number(json.installerVersion) >= 1.7; + } + } + // 浏览器端 + else { + return location.protocol.startsWith("http"); + } + } + return false; +} + +/** + * 传递升级完成的信息 + * @returns { string | void } 返回一个网址 + */ +export function sendUpdate() { + // 手机端 + if (window.cordova) { + // 直接确定包名 + if (nonameInitialized && nonameInitialized.includes("com.noname.shijian")) { + // 给诗笺版apk的java层传递升级完成的信息 + // @ts-ignore + return window.noname_shijianInterfaces.sendUpdate() + "?sendUpdate=true"; + } + } + // 电脑端 + else if (typeof window.require == "function" && typeof window.process == "object") { + // 从json判断版本号 + const fs = require("fs"); + const path = require("path"); + if (fs.existsSync(path.join(__dirname, "package.json"))) { + // @ts-ignore + const json = require("./package.json"); + // 诗笺电脑版的判断 + if (json && Number(json.installerVersion) >= 1.7) { + fs.writeFileSync(path.join(__dirname, "Home", "saveProtocol.txt"), ""); + // 启动http + const cp = require("child_process"); + cp.exec( + `start /min ${__dirname}\\noname-server.exe -platform=electron`, + (err, stdout, stderr) => {} + ); + return `http://localhost:8089/app.html?sendUpdate=true`; + } + } + } + // 浏览器端 + else { + return location.href; + } +} + +// 无名杀,启动! +export async function boot() { + // 不想看,反正别动 + if (typeof __dirname === "string" && __dirname.length) { + const dirsplit = __dirname.split("/"); + for (let i = 0; i < dirsplit.length; i++) { + if (dirsplit[i]) { + var c = dirsplit[i][0]; + lib.configprefix += /[A-Z]|[a-z]/.test(c) ? c : "_"; + } + } + lib.configprefix += "_"; + } + + // 加载polyfill内容 + await import("./polyfill.js"); + + // 设定游戏加载时间,超过时间未加载就提醒 + const configLoadTime = localStorage.getItem(lib.configprefix + "loadtime"); + // 现在不暴露到全局变量里了,直接传给onload + const resetGameTimeout = setTimeout(lib.init.reset, configLoadTime ? parseInt(configLoadTime) : 10000); + + if (typeof window.cordovaLoadTimeout != "undefined") { + clearTimeout(window.cordovaLoadTimeout); + delete window.cordovaLoadTimeout; + } + + for (const link of document.head.querySelectorAll("link")) { + if (link.href.includes("app/color.css")) { + link.remove(); + break; + } + } + + setServerIndex(); + setBackground(); + + Reflect.set(lib, "get", get); + Reflect.set(lib, "ui", ui); + Reflect.set(lib, "ai", ai); + Reflect.set(lib, "game", game); + _status.event = lib.element.GameEvent.initialGameEvent(); + + setWindowListener(); + const promiseErrorHandler = await setOnError(); + + // 确认手机端平台 + const noname_inited = localStorage.getItem("noname_inited"); + if (noname_inited && noname_inited !== "nodejs") { + const ua = userAgent; + if (ua.includes("android")) { + Reflect.set(lib, "device", "android"); + } else if (ua.includes("iphone") || ua.includes("ipad") || ua.includes("macintosh")) { + Reflect.set(lib, "device", "ios"); + } + } + + // 在dom加载完后执行相应的操作 + const waitDomLoad = new Promise((resolve) => { + if (document.readyState !== "complete") { + window.onload = resolve; + } else resolve(void 0); + }).then(onWindowReady.bind(window)); + + // 闭源客户端检测并提醒 + if ( + lib.assetURL.includes("com.widget.noname.qingyao") || + lib.assetURL.includes("online.nonamekill.android") + ) { + alert( + "您正在一个不受信任的闭源客户端上运行《无名杀》。建议您更换为其他开源的无名杀客户端,避免给您带来不必要的损失。" + ); + } + + // Electron平台 + if (typeof window.require === "function") { + const { nodeReady } = await import("./node.js"); + nodeReady(); + } else { + Reflect.set(lib, "path", (await import("../library/path.js")).default); + if (typeof lib.device != "undefined") { + const script = document.createElement("script"); + script.src = "cordova.js"; + document.body.appendChild(script); + await new Promise((resolve) => { + document.addEventListener("deviceready", async () => { + const { cordovaReady } = await import("./cordova.js"); + await cordovaReady(); + resolve(void 0); + }); + }); + } else { + //为其他自定义平台提供文件读写函数赋值的一种方式。 + //但这种方式只允许修改game的文件读写函数。 + if (typeof window.initReadWriteFunction == "function") { + const g = {}; + const ReadWriteFunctionName = [ + "download", + "readFile", + "readFileAsText", + "writeFile", + "removeFile", + "getFileList", + "ensureDirectory", + "createDir", + "removeDir", + ]; + ReadWriteFunctionName.forEach((prop) => { + Object.defineProperty(g, prop, { + configurable: true, + get() { + return undefined; + }, + set(newValue) { + if (typeof newValue == "function") { + delete g[prop]; + g[prop] = game[prop] = newValue; + } + }, + }); + }); + // @ts-ignore + await window.initReadWriteFunction(g).catch((e) => { + console.error("文件读写函数初始化失败:", e); + }); + } + window.onbeforeunload = function () { + if (config.get("confirm_exit") && !_status.reloading) { + return "是否离开游戏?"; + } else { + return null; + } + }; + } + } + + const loadCssPromise = loadCss(); + const loadConfigPromise = loadConfig(); + await loadCssPromise; + const config2 = await loadConfigPromise; + + // 读取模式 + if (config2.mode) config.set("mode", config2.mode); + if (config.get("mode_config")[config.get("mode")] === undefined) + config.get("mode_config")[config.get("mode")] = {}; + + // 复制共有模式设置 + for (const name in config.get("mode_config").global) { + if (config.get("mode_config")[config.get("mode")][name] === undefined) { + config.get("mode_config")[config.get("mode")][name] = config.get("mode_config").global[name]; + } + } + + if (config.get("characters")) config.set("defaultcharacters", config.get("characters").slice(0)); + if (config.get("cards")) config.set("defaultcards", config.get("cards").slice(0)); + + for (const name in config2) { + if (name.includes("_mode_config")) { + var thismode = name.substr(name.indexOf("_mode_config") + 13); + if (!config.get("mode_config")[thismode]) config.get("mode_config")[thismode] = {}; + config.get("mode_config")[thismode][name.substr(0, name.indexOf("_mode_config"))] = config2[name]; + } else { + config.set(name, config2[name]); + } + } + + for (const name in get.config("translate")) { + lib.translate[name] = get.config("translate")[name]; + } + + config.get("all").characters = []; + config.get("all").cards = []; + config.get("all").plays = []; + config.get("all").mode = []; + + if (config.get("debug")) { + await lib.init.promises.js(`${lib.assetURL}game`, "asset"); + if (window.noname_skin_list) { + lib.skin = window.noname_skin_list; + delete window.noname_skin_list; + delete window.noname_asset_list; + } + } + + if (Reflect.get(window, "isNonameServer")) config.set("mode", "connect"); + + var pack = Reflect.get(window, "noname_package"); + Reflect.deleteProperty(window, "noname_package"); + for (const name in pack.character) { + if ( + config.get("all").sgscharacters.includes(name) || + config.get("hiddenCharacterPack").indexOf(name) == -1 + ) { + config.get("all").characters.push(name); + lib.translate[name + "_character_config"] = pack.character[name]; + } + } + for (const name in pack.card) { + if (config.get("all").sgscards.includes(name) || config.get("hiddenCardPack").indexOf(name) == -1) { + config.get("all").cards.push(name); + lib.translate[name + "_card_config"] = pack.card[name]; + } + } + for (const name in pack.play) { + config.get("all").plays.push(name); + lib.translate[name + "_play_config"] = pack.play[name]; + } + for (const name in pack.submode) { + for (var j in pack.submode[name]) { + lib.translate[name + "|" + j] = pack.submode[name][j]; + } + } + + if (!config.get("gameRecord")) config.set("gameRecord", {}); + for (const name in pack.mode) { + if (config.get("hiddenModePack").indexOf(name) == -1) { + config.get("all").mode.push(name); + lib.translate[name] = pack.mode[name]; + if (!config.get("gameRecord")[name]) config.get("gameRecord")[name] = { data: {} }; + } + } + if (config.get("all").mode.length == 0) { + config.get("all").mode.push("identity"); + lib.translate.identity = "身份"; + if (!config.get("gameRecord").identity) config.get("gameRecord").identity = { data: {} }; + } + if (pack.background) { + for (const name in pack.background) { + if (config.get("hiddenBackgroundPack").includes(name)) continue; + lib.configMenu.appearence.config.image_background.item[name] = pack.background[name]; + } + for (let i = 0; i < config.get("customBackgroundPack").length; i++) { + var link = config.get("customBackgroundPack")[i]; + lib.configMenu.appearence.config.image_background.item[link] = link.slice(link.indexOf("_") + 1); + } + lib.configMenu.appearence.config.image_background.item.default = "默认"; + } + if (pack.music) { + if (typeof lib.device != "undefined" || typeof window.require === "function") { + lib.configMenu.audio.config.background_music.item.music_custom = "自定义音乐"; + } + config.get("all").background_music = ["music_default"]; + for (const name in pack.music) { + config.get("all").background_music.push(name); + lib.configMenu.audio.config.background_music.item[name] = pack.music[name]; + } + if (config.get("customBackgroundMusic")) { + for (const name in config.get("customBackgroundMusic")) { + config.get("all").background_music.push(name); + lib.configMenu.audio.config.background_music.item[name] = + config.get("customBackgroundMusic")[name]; + } + } + lib.configMenu.audio.config.background_music.item.music_random = "随机播放"; + lib.configMenu.audio.config.background_music.item.music_off = "关闭"; + } + if (pack.theme) { + for (const name in pack.theme) { + lib.configMenu.appearence.config.theme.item[name] = pack.theme[name]; + } + } + if (config.get("extension_sources")) { + for (const name in config.get("extension_sources")) { + lib.configMenu.general.config.extension_source.item[name] = name; + } + } + + if (pack.font) { + Reflect.get(ui, "css").fontsheet = lib.init.sheet(); + const appearenceConfig = lib.configMenu.appearence.config, + fontSheet = Reflect.get(ui, "css").fontsheet.sheet, + suitsFont = config.get("suits_font"); + Object.keys(pack.font).forEach((value) => { + const font = pack.font[value]; + appearenceConfig.name_font.item[value] = font; + appearenceConfig.identity_font.item[value] = font; + appearenceConfig.cardtext_font.item[value] = font; + appearenceConfig.global_font.item[value] = font; + fontSheet.insertRule( + `@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/${value}.woff2');}`, + 0 + ); + if (suitsFont) + fontSheet.insertRule( + `@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/suits.woff2');}`, + 0 + ); + }); + if (suitsFont) + fontSheet.insertRule( + `@font-face {font-family: 'Suits'; src: url('${lib.assetURL}font/suits.woff2');}`, + 0 + ); + fontSheet.insertRule( + `@font-face {font-family: 'NonameSuits'; src: url('${lib.assetURL}font/suits.woff2');}`, + 0 + ); + fontSheet.insertRule( + `@font-face {font-family: 'MotoyaLMaru'; src: url('${lib.assetURL}font/motoyamaru.woff2');}`, + 0 + ); + appearenceConfig.cardtext_font.item.default = "默认"; + appearenceConfig.global_font.item.default = "默认"; + } + + const ua = userAgent; + if ("ontouchstart" in document) { + if (!config.get("totouched")) { + game.saveConfig("totouched", true); + if (typeof lib.device != "undefined") { + game.saveConfig("low_performance", true); + game.saveConfig("confirm_exit", true); + game.saveConfig("touchscreen", true); + game.saveConfig("fold_mode", false); + if (ua.indexOf("ipad") == -1) { + game.saveConfig("phonelayout", true); + } else if (Reflect.get(lib, "device") === "ios") { + game.saveConfig("show_statusbar_ios", "overlay"); + } + } else if (confirm("是否切换到触屏模式?(触屏模式可提高触屏设备的响应速度,但无法使用鼠标)")) { + game.saveConfig("touchscreen", true); + if (ua.includes("iphone") || ua.includes("android")) { + game.saveConfig("phonelayout", true); + } + game.reload(); + } + } + } else if (config.get("touchscreen")) { + game.saveConfig("touchscreen", false); + } + if (!config.get("toscrolled") && ua.includes("macintosh")) { + game.saveConfig("toscrolled", true); + game.saveConfig("mousewheel", false); + } + + let show_splash = config.get("show_splash"); + if (show_splash == "off") { + show_splash = false; + } else if (show_splash == "init") { + if (localStorage.getItem("show_splash_off")) { + show_splash = false; + } + } + localStorage.removeItem("show_splash_off"); + const extensionlist = []; + if (!localStorage.getItem(lib.configprefix + "disable_extension")) { + if (config.has("extensions") && config.get("extensions").length) { + Reflect.set(window, "resetExtension", () => { + for (var i = 0; i < config.get("extensions").length; i++) { + game.saveConfig("extension_" + config.get("extensions")[i] + "_enable", false); + } + // @ts-ignore + localStorage.setItem(lib.configprefix + "disable_extension", true); + }); + } + for (var name = 0; name < config.get("plays").length; name++) { + if (config.get("all").plays.includes(config.get("plays")[name])) { + extensionlist.push(config.get("plays")[name]); + } + } + for (var name = 0; name < config.get("extensions").length; name++) { + if (Reflect.get(window, "bannedExtensions").includes(config.get("extensions")[name])) { + continue; + } + var extcontent = localStorage.getItem( + lib.configprefix + "extension_" + config.get("extensions")[name] + ); + if (extcontent) { + //var backup_onload=lib.init.onload; + _status.evaluatingExtension = true; + try { + eval(extcontent); + } catch (e) { + console.log(e); + } + //lib.init.onload=backup_onload; + _status.evaluatingExtension = false; + } else { + extensionlist.push(config.get("extensions")[name]); + } + } + } + + let layout = config.get("layout"); + if (layout == "default" || lib.layoutfixed.indexOf(config.get("mode")) !== -1) { + layout = "mobile"; + } + if (layout == "phone") { + layout = "mobile"; + game.saveConfig("layout", "mobile"); + game.saveConfig("phonelayout", true); + } + Reflect.set(game, "layout", layout); + + if (config.get("image_background_random")) { + if (_status.htmlbg) { + game.saveConfig("image_background", _status.htmlbg); + } else { + const list = []; + for (const name in lib.configMenu.appearence.config.image_background.item) { + if (name == "default") continue; + list.push(name); + } + // @ts-ignore + game.saveConfig("image_background", list.randomGet(lib.config.image_background)); + } + lib.init.background(); + } + delete _status.htmlbg; + + // 无名杀更新日志 + if (window.noname_update) { + Reflect.set(lib, "version", window.noname_update.version); + // 更全面的更新内容 + if (config.get(`version_description_v${window.noname_update.version}`)) { + try { + const description = config.get(`version_description_v${window.noname_update.version}`); + const html = String.raw; + // 匹配[xx](url)的格式 + const regex = /\[([^\]]*)\]\(([^)]+)\)/g; + lib.changeLog.push( + html` +
                                    + ${description.author.login}于${description.published_at}发布 + `.trim(), + description.body.replaceAll("\n", "
                                    ").replace(regex, function (match, p1, p2) { + // p1 是链接文本,p2 是链接地址 + return `${p1}`; + }) + ); + } catch (e) { + console.error(e); + lib.changeLog.push(...window.noname_update.changeLog); + } + } + // 原更新内容 + else { + lib.changeLog.push(...window.noname_update.changeLog); + } + if (window.noname_update.players) { + lib.changeLog.push("players://" + JSON.stringify(window.noname_update.players)); + } + if (window.noname_update.cards) { + lib.changeLog.push("cards://" + JSON.stringify(window.noname_update.cards)); + } + delete window.noname_update; + } + + // 虽然但是,我就暴露个import,应该没啥问题 + Reflect.set(window, "game", { + import: game.import.bind(null), + }); + + if (config.get("layout") == "default") { + config.set("layout", "mobile"); + } + + const stylesName = ["layout", "theme", "card_style", "cardback_style", "hp_style"]; + const stylesLoading = [ + lib.init.promises.css(lib.assetURL + "layout/" + layout, "layout", void 0, true), + lib.init.promises.css(lib.assetURL + "theme/" + config.get("theme"), "style", void 0, true), + lib.init.promises.css(lib.assetURL + "theme/style/card", config.get("card_style"), void 0, true), + lib.init.promises.css( + lib.assetURL + "theme/style/cardback", + config.get("cardback_style"), + void 0, + true + ), + lib.init.promises.css(lib.assetURL + "theme/style/hp", config.get("hp_style"), void 0, true), + ]; + + if (get.is.phoneLayout()) { + stylesName.push("phone"); + stylesLoading.push(lib.init.promises.css(lib.assetURL + "layout/default", "phone")); + } else { + Reflect.get(ui, "css").phone = lib.init.css(); + } + + initSheet(Reflect.get(lib, "config")); + + config.set("duration", 500); + + if (!config.get("touchscreen")) { + document.addEventListener("mousewheel", ui.click.windowmousewheel, { passive: true }); + document.addEventListener("mousemove", ui.click.windowmousemove); + document.addEventListener("mousedown", ui.click.windowmousedown); + document.addEventListener("mouseup", ui.click.windowmouseup); + document.addEventListener("contextmenu", ui.click.right); + } else { + document.addEventListener("touchstart", ui.click.touchconfirm); + document.addEventListener("touchstart", ui.click.windowtouchstart); + document.addEventListener("touchend", ui.click.windowtouchend); + document.addEventListener("touchmove", ui.click.windowtouchmove); + } + + await waitDomLoad; + + const stylesLoaded = await Promise.all(stylesLoading); + const stylesLength = Math.min(stylesName.length, stylesLoaded.length); + for (let i = 0; i < stylesLength; ++i) { + Reflect.get(ui, "css")[stylesName[i]] = stylesLoaded[i]; + } + + if (extensionlist.length) { + _status.extensionLoading = []; + _status.extensionLoaded = []; + + const bannedExtensions = Reflect.get(window, "bannedExtensions"); + + const extensionsLoading = []; + for (const name of extensionlist) { + if (bannedExtensions.includes(name)) continue; + extensionsLoading.push(importExtension(name)); + } + + const extErrorList = []; + for (const promise of extensionsLoading) { + await promise.catch(async (error) => { + extErrorList.add(error); + if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return; + // @ts-ignore + await promiseErrorHandler.onHandle({ promise }); + }); + } + for (const promise of _status.extensionLoading) { + await promise.catch(async (error) => { + if (extErrorList.includes(error)) return; + if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return; + // @ts-ignore + await promiseErrorHandler.onHandle({ promise }); + }); + } + // await Promise.allSettled(_status.extensionLoading); + + _status.extensionLoaded + .filter((name) => game.hasExtension(name)) + .forEach((name) => { + lib.announce.publish("Noname.Init.Extension.onLoad", name); + lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0); + }); + delete _status.extensionLoading; + } + + const isArray = Array.isArray; + if (isArray(lib.onprepare) && lib.onprepare.length) { + _status.onprepare = Object.freeze( + lib.onprepare.map((fn) => { + if (typeof fn !== "function") return; + return (gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn)(); + }) + ); + } + + const toLoad = []; + + if (localStorage.getItem(`${lib.configprefix}playback`)) toLoad.push(importMode(config.get("mode"))); + else if ( + (localStorage.getItem(`${lib.configprefix}directstart`) || !show_splash) && + config.get("all").mode.includes(config.get("mode")) + ) + toLoad.push(importMode(config.get("mode"))); + + for (const cardPack of config.get("all").cards) { + toLoad.push(importCardPack(cardPack)); + } + for (const characterPack of config.get("all").characters) { + toLoad.push(importCharacterPack(characterPack)); + } + toLoad.push(lib.init.promises.js(`${lib.assetURL}character`, "rank")); + + if (_status.javaScriptExtensions) { + const loadJavaScriptExtension = async ( + javaScriptExtension, + pathArray, + fileArray, + onLoadArray, + onErrorArray, + index + ) => { + if (!pathArray && !fileArray && !onLoadArray && !onErrorArray) { + try { + await lib.init.promises.js(javaScriptExtension.path, javaScriptExtension.file); + if (typeof javaScriptExtension.onload == "function") javaScriptExtension.onload(); + } catch { + if (typeof javaScriptExtension.onerror == "function") javaScriptExtension.onerror(); + } + return; + } + if (typeof index != "number") index = 0; + if (pathArray && index >= javaScriptExtension.path.length) return; + if (fileArray && index >= javaScriptExtension.file.length) return; + if (onLoadArray && index >= javaScriptExtension.onload.length) return; + if (onErrorArray && index >= javaScriptExtension.onerror.length) return; + const path = pathArray ? javaScriptExtension.path[index] : javaScriptExtension.path; + const file = fileArray ? javaScriptExtension.file[index] : javaScriptExtension.file; + const onLoad = onLoadArray ? javaScriptExtension.onload[index] : javaScriptExtension.onload; + const onError = onErrorArray ? javaScriptExtension.onerror[index] : javaScriptExtension.onerror; + try { + await lib.init.promises.js(path, file); + if (typeof onLoad == "function") onLoad(); + } catch { + if (typeof onError == "function") onError(); + } + await loadJavaScriptExtension( + javaScriptExtension, + pathArray, + fileArray, + onLoadArray, + onErrorArray, + index + 1 + ); + }; + _status.javaScriptExtensions.forEach((javaScriptExtension) => { + const pathArray = isArray(javaScriptExtension.path); + const fileArray = isArray(javaScriptExtension.file); + const onLoadArray = isArray(javaScriptExtension.onLoad); + const onErrorArray = isArray(javaScriptExtension.onError); + toLoad.push( + loadJavaScriptExtension(javaScriptExtension, pathArray, fileArray, onLoadArray, onErrorArray) + ); + }); + } + + await Promise.allSettled(toLoad); + + if (_status.importing) { + /** + * @type {Promise[]} + */ + let promises = lib.creation.array; + for (const type in _status.importing) { + // @ts-ignore + promises.addArray(_status.importing[type]); + } + await Promise.allSettled(promises); + delete _status.importing; + } + + await onload(resetGameTimeout); +} + +function initSheet(libConfig) { + if (libConfig.player_style && libConfig.player_style != "default" && libConfig.player_style != "custom") { + var str = ""; + switch (libConfig.player_style) { + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; + break; + case "music": + str = "linear-gradient(#4b4b4b, #464646)"; + break; + case "simple": + str = "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + break; + } + Reflect.get(ui, "css").player_stylesheet = lib.init.sheet( + "#window .player{background-image:" + str + "}" + ); + } + if ( + libConfig.border_style && + libConfig.border_style != "default" && + libConfig.border_style != "custom" && + libConfig.border_style != "auto" + ) { + Reflect.get(ui, "css").border_stylesheet = lib.init.sheet(); + var bstyle = libConfig.border_style; + if (bstyle.startsWith("dragon_")) { + bstyle = bstyle.slice(7); + } + Reflect.get(ui, "css").border_stylesheet.sheet.insertRule( + '#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + + lib.assetURL + + "theme/style/player/" + + bstyle + + '1.png")}', + 0 + ); + Reflect.get(ui, "css").border_stylesheet.sheet.insertRule( + '#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + + lib.assetURL + + "theme/style/player/" + + bstyle + + '3.png")}', + 0 + ); + Reflect.get(ui, "css").border_stylesheet.sheet.insertRule( + ".player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}", + 0 + ); + } + if ( + libConfig.control_style && + libConfig.control_style != "default" && + libConfig.control_style != "custom" + ) { + var str = ""; + switch (libConfig.control_style) { + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; + break; + case "music": + str = "linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px"; + break; + case "simple": + str = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px"; + break; + } + if (libConfig.control_style == "wood") { + Reflect.get(ui, "css").control_stylesheet = lib.init.sheet( + "#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:" + + str + + "}" + ); + } else { + Reflect.get(ui, "css").control_stylesheet = lib.init.sheet( + "#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:" + + str + + "}" + ); + } + } + if (libConfig.menu_style && libConfig.menu_style != "default" && libConfig.menu_style != "custom") { + var str = ""; + switch (libConfig.menu_style) { + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; + break; + case "music": + str = "linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px"; + break; + case "simple": + str = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px"; + break; + } + Reflect.get(ui, "css").menu_stylesheet = lib.init.sheet( + "html #window>.dialog.popped,html .menu,html .menubg{background-image:" + str + "}" + ); + } +} + +async function loadConfig() { + Reflect.set(lib, "config", Reflect.get(window, "config")); + Reflect.set(lib, "configOL", {}); + Reflect.deleteProperty(window, "config"); + + let result; + if (localStorage.getItem(`${lib.configprefix}nodb`)) Reflect.set(window, "nodb", true); + if (window.indexedDB && !Reflect.get(window, "nodb")) { + const event = await new Promise((resolve, reject) => { + const idbOpenDBRequest = window.indexedDB.open(`${lib.configprefix}data`, 4); + idbOpenDBRequest.onerror = reject; + idbOpenDBRequest.onsuccess = resolve; + idbOpenDBRequest.onupgradeneeded = (idbVersionChangeEvent) => { + // @ts-expect-error MaybeHave + const idbDatabase = idbVersionChangeEvent.target.result; + if (!idbDatabase.objectStoreNames.contains("video")) + idbDatabase.createObjectStore("video", { + keyPath: "time", + }); + if (!idbDatabase.objectStoreNames.contains("image")) idbDatabase.createObjectStore("image"); + if (!idbDatabase.objectStoreNames.contains("audio")) idbDatabase.createObjectStore("audio"); + if (!idbDatabase.objectStoreNames.contains("config")) idbDatabase.createObjectStore("config"); + if (!idbDatabase.objectStoreNames.contains("data")) idbDatabase.createObjectStore("data"); + }; + }); + Reflect.set(lib, "db", event.target.result); + + const object = await game.getDB("config"); + + if (!object.storageImported) { + try { + const item = localStorage.getItem(`${lib.configprefix}config`); + if (!item) throw "err"; + result = JSON.parse(item); + if (!result || typeof result != "object") throw "err"; + } catch (err) { + result = {}; + } + Object.keys(result).forEach((key) => game.saveConfig(key, result[key])); + Object.keys(lib.mode).forEach((key) => { + try { + const item = localStorage.getItem(`${lib.configprefix}${key}`); + if (!item) throw "err"; + result = JSON.parse(item); + if (!result || typeof result != "object" || get.is.empty(result)) throw "err"; + } catch (err) { + result = false; + } + localStorage.removeItem(`${lib.configprefix}${key}`); + if (result) game.putDB("data", key, result); + }); + game.saveConfig("storageImported", true); + lib.init.background(); + localStorage.removeItem(`${lib.configprefix}config`); + } else result = object; + } else { + try { + const item = localStorage.getItem(lib.configprefix + "config"); + if (!item) throw "err"; + result = JSON.parse(item); + if (!result || typeof result != "object") throw "err"; + } catch (err) { + result = {}; + localStorage.setItem(lib.configprefix + "config", JSON.stringify({})); + } + } + + return result; +} + +async function loadCss() { + Reflect.set(ui, "css", { + menu: await lib.init.promises.css(lib.assetURL + "layout/default", "menu"), + default: await lib.init.promises.css(lib.assetURL + "layout/default", "layout"), + }); +} + +/** + * `window.onload`触发时执行的函数 + * + * 目前无任何内容,预防以后出现需要的情况 + * + * @deprecated + * @return {Promise} + */ +async function onWindowReady() {} + +function setBackground() { + let htmlbg = localStorage.getItem(lib.configprefix + "background"); + if (htmlbg) { + if (htmlbg[0] == "[") { + try { + htmlbg = JSON.parse(htmlbg); + if (!htmlbg) throw new Error(); + htmlbg = htmlbg[get.rand(htmlbg.length)]; + if (htmlbg.startsWith("custom_")) { + throw "err"; + } + _status.htmlbg = htmlbg; + } catch (e) { + htmlbg = null; + } + } + if (htmlbg) { + document.documentElement.style.backgroundImage = + 'url("' + lib.assetURL + "image/background/" + htmlbg + '.jpg")'; + document.documentElement.style.backgroundSize = "cover"; + document.documentElement.style.backgroundPosition = "50% 50%"; + } + } +} + +function setServerIndex() { + const index = window.location.href.indexOf("index.html?server="); + if (index !== -1) { + Reflect.set(window, "isNonameServer", window.location.href.slice(index + 18)); + Reflect.set(window, "nodb", true); + } else { + const savedIndex = localStorage.getItem(lib.configprefix + "asserver"); + if (savedIndex) { + Reflect.set(window, "isNonameServer", savedIndex); + Reflect.set(window, "isNonameServerIp", lib.hallURL); + } + } +} + +async function setOnError() { + const [core] = get.coreInfo(); + + const promiseErrorHandler = new ( + core in promiseErrorHandlerMap ? promiseErrorHandlerMap[core] : promiseErrorHandlerMap.other + )(); + + if (promiseErrorHandler.onLoad) await promiseErrorHandler.onLoad(); + + window.onunhandledrejection = async (event) => { + if (promiseErrorHandler.onHandle) await promiseErrorHandler.onHandle(event); + }; + + window.onerror = function (msg, src, line, column, err) { + if (promiseErrorHandler.onErrorPrepare) promiseErrorHandler.onErrorPrepare(); + const winPath = window.__dirname + ? "file:///" + (__dirname.replace(new RegExp("\\\\", "g"), "/") + "/") + : ""; + let str = `错误文件: ${ + typeof src == "string" + ? decodeURI(src).replace(lib.assetURL, "").replace(winPath, "") + : "未知文件" + }`; + str += `\n错误信息: ${msg}`; + const tip = lib.getErrorTip(msg); + if (tip) str += `\n错误提示: ${tip}`; + str += `\n行号: ${line}`; + str += `\n列号: ${column}`; + const version = typeof lib.version != "undefined" ? lib.version : ""; + const reg = /[^\d.]/; + const match = version.match(reg) != null; + str += "\n" + `${match ? "游戏" : "无名杀"}版本: ${version || "未知版本"}`; + if (match) + str += + "\n⚠️您使用的游戏代码不是源于libccy/noname无名杀官方仓库,请自行寻找您所使用的游戏版本开发者反馈!"; + if (_status && _status.event) { + let evt = _status.event; + str += `\nevent.name: ${evt.name}\nevent.step: ${evt.step}`; + // @ts-ignore + if (evt.parent) + str += `\nevent.parent.name: ${evt.parent.name}\nevent.parent.step: ${evt.parent.step}`; + // @ts-ignore + if (evt.parent && evt.parent.parent) + str += `\nevent.parent.parent.name: ${evt.parent.parent.name}\nevent.parent.parent.step: ${evt.parent.parent.step}`; + if (evt.player || evt.target || evt.source || evt.skill || evt.card) { + str += "\n-------------"; + } + if (evt.player) { + if (lib.translate[evt.player.name]) + str += `\nplayer: ${lib.translate[evt.player.name]}[${evt.player.name}]`; + else str += "\nplayer: " + evt.player.name; + let distance = get.distance(_status.roundStart, evt.player, "absolute"); + if (distance != Infinity) { + str += `\n座位号: ${distance + 1}`; + } + } + if (evt.target) { + if (lib.translate[evt.target.name]) + str += `\ntarget: ${lib.translate[evt.target.name]}[${evt.target.name}]`; + else str += "\ntarget: " + evt.target.name; + } + if (evt.source) { + if (lib.translate[evt.source.name]) + str += `\nsource: ${lib.translate[evt.source.name]}[${evt.source.name}]`; + else str += "\nsource: " + evt.source.name; + } + if (evt.skill) { + if (lib.translate[evt.skill]) str += `\nskill: ${lib.translate[evt.skill]}[${evt.skill}]`; + else str += "\nskill: " + evt.skill; + } + if (evt.card) { + if (lib.translate[evt.card.name]) + str += `\ncard: ${lib.translate[evt.card.name]}[${evt.card.name}]`; + else str += "\ncard: " + evt.card.name; + } + } + str += "\n-------------"; + if ( + typeof line == "number" && + (typeof Reflect.get(game, "readFile") == "function" || location.origin != "file://") + ) { + const createShowCode = function (lines) { + let showCode = ""; + if (lines.length >= 10) { + if (line > 4) { + for (let i = line - 5; i < line + 6 && i < lines.length; i++) { + showCode += `${i + 1}| ${line == i + 1 ? "⚠️" : ""}${lines[i]}\n`; + } + } else { + for (let i = 0; i < line + 6 && i < lines.length; i++) { + showCode += `${i + 1}| ${line == i + 1 ? "⚠️" : ""}${lines[i]}\n`; + } + } + } else { + showCode = lines + .map((_line, i) => `${i + 1}| ${line == i + 1 ? "⚠️" : ""}${_line}\n`) + .toString(); + } + return showCode; + }; + //协议名须和html一致(网页端防跨域),且文件是js + if (typeof src == "string" && src.startsWith(location.protocol) && src.endsWith(".js")) { + //获取代码 + const codes = lib.init.reqSync( + "local:" + decodeURI(src).replace(lib.assetURL, "").replace(winPath, "") + ); + if (codes) { + const lines = codes.split("\n"); + str += "\n" + createShowCode(lines); + str += "\n-------------"; + } + } + //解析parsex里的content fun内容(通常是技能content) + // @ts-ignore + else if ( + err && + err.stack && + ["at Object.eval [as content]", "at Proxy.content"].some((str) => { + let stackSplit1 = err.stack.split("\n")[1]; + if (stackSplit1) { + return stackSplit1.trim().startsWith(str); + } + return false; + }) + ) { + const codes = _status.event.content; + if (typeof codes == "function") { + const lines = codes.toString().split("\n"); + str += "\n" + createShowCode(lines); + str += "\n-------------"; + } + } + } + if (err && err.stack) + str += + "\n" + + decodeURI(err.stack) + .replace(new RegExp(lib.assetURL, "g"), "") + .replace(new RegExp(winPath, "g"), ""); + alert(str); + Reflect.set(window, "ea", Array.from(arguments)); + Reflect.set(window, "em", msg); + Reflect.set(window, "el", line); + Reflect.set(window, "ec", column); + Reflect.set(window, "eo", err); + game.print(str); + if (promiseErrorHandler.onErrorFinish) promiseErrorHandler.onErrorFinish(); + // @ts-ignore + if (!lib.config.errstop) { + _status.withError = true; + game.loop(); + } + }; + + return promiseErrorHandler; +} + +function setWindowListener() { + window.onkeydown = function (e) { + if (typeof ui.menuContainer == "undefined" || !ui.menuContainer.classList.contains("hidden")) { + if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { + if (e.shiftKey) { + if (confirm("是否重置游戏?")) { + var noname_inited = localStorage.getItem("noname_inited"); + var onlineKey = localStorage.getItem(lib.configprefix + "key"); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem("noname_inited", noname_inited); + } + if (onlineKey) { + localStorage.setItem(lib.configprefix + "key", onlineKey); + } + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + "data"); + game.reload(); + return; + } + } else { + game.reload(); + } + } else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { + if (typeof window.saveNonameInput == "function") { + window.saveNonameInput(); + } + e.preventDefault(); + e.stopPropagation(); + return false; + } else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && typeof lib.node != "undefined") { + lib.node.debug(); + } + } else { + game.closePopped(); + var dialogs = document.querySelectorAll("#window>.dialog.popped:not(.static)"); + for (var i = 0; i < dialogs.length; i++) { + // @ts-ignore + dialogs[i].delete(); + } + if (e.keyCode == 32) { + var node = ui.window.querySelector("pausedbg"); + if (node) { + node.click(); + } else { + ui.click.pause(); + } + } else if (e.keyCode == 65) { + if (typeof ui.auto != "undefined") ui.auto.click(); + } else if (e.keyCode == 87) { + if (typeof ui.wuxie != "undefined" && ui.wuxie.style.display != "none") { + ui.wuxie.classList.toggle("glow"); + } else if (typeof ui.tempnowuxie != "undefined") { + ui.tempnowuxie.classList.toggle("glow"); + } + } else if (e.keyCode == 116 || ((e.ctrlKey || e.metaKey) && e.keyCode == 82)) { + if (e.shiftKey) { + if (confirm("是否重置游戏?")) { + var noname_inited = localStorage.getItem("noname_inited"); + var onlineKey = localStorage.getItem(lib.configprefix + "key"); + localStorage.clear(); + if (noname_inited) { + localStorage.setItem("noname_inited", noname_inited); + } + if (onlineKey) { + localStorage.setItem(lib.configprefix + "key", onlineKey); + } + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + "data"); + game.reload(); + return; + } + } else { + game.reload(); + } + } else if (e.keyCode == 83 && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + e.stopPropagation(); + return false; + } else if (e.keyCode == 74 && (e.ctrlKey || e.metaKey) && typeof lib.node != "undefined") { + lib.node.debug(); + } + // else if(e.keyCode==27){ + // if(!ui.arena.classList.contains('paused')) ui.click.config(); + // } + } + }; +} diff --git a/noname/init/node.js b/noname/init/node.js index f4be1c7d0..7331b4b2e 100644 --- a/noname/init/node.js +++ b/noname/init/node.js @@ -1,121 +1,125 @@ // @ts-nocheck -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { checkVersion } from '../library/update.js'; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { checkVersion } from "../library/update.js"; export function nodeReady() { const versions = window.process.versions; // @ts-ignore const electronVersion = parseFloat(versions.electron); lib.node = { - fs: require('fs'), + fs: require("fs"), path: require("path"), debug() { let remote; if (electronVersion >= 14) { // @ts-ignore - remote = require('@electron/remote'); + remote = require("@electron/remote"); } else { // @ts-ignore - remote = require('electron').remote; + remote = require("electron").remote; } remote.getCurrentWindow().toggleDevTools(); - } + }, }; lib.path = lib.node.path; game.download = function (url, folder, onsuccess, onerror, dev, onprogress) { - if (!url.startsWith('http')) { + if (!url.startsWith("http")) { url = get.url(dev) + url; } - game.ensureDirectory(folder, function () { - try { - var file = lib.node.fs.createWriteStream(__dirname + '/' + folder); - } - catch (e) { - onerror(); - } - lib.config.brokenFile.add(folder); - game.saveConfigValue('brokenFile'); - if (!lib.node.http) lib.node.http = require('http'); - if (!lib.node.https) lib.node.https = require('https'); - var opts = require('url').parse(encodeURI(url)); - opts.headers = { 'User-Agent': 'AppleWebkit' }; - (url.startsWith('https') ? lib.node.https : lib.node.http).get(opts, function (response) { - var stream = response.pipe(file); - stream.on('finish', function () { - lib.config.brokenFile.remove(folder); - game.saveConfigValue('brokenFile'); - if (onsuccess) { - onsuccess(); + game.ensureDirectory( + folder, + function () { + try { + var file = lib.node.fs.createWriteStream(__dirname + "/" + folder); + } catch (e) { + onerror(); + } + lib.config.brokenFile.add(folder); + game.saveConfigValue("brokenFile"); + if (!lib.node.http) lib.node.http = require("http"); + if (!lib.node.https) lib.node.https = require("https"); + var opts = require("url").parse(encodeURI(url)); + opts.headers = { "User-Agent": "AppleWebkit" }; + (url.startsWith("https") ? lib.node.https : lib.node.http).get(opts, function (response) { + var stream = response.pipe(file); + stream.on("finish", function () { + lib.config.brokenFile.remove(folder); + game.saveConfigValue("brokenFile"); + if (onsuccess) { + onsuccess(); + } + }); + stream.on("error", onerror); + if (onprogress) { + var streamInterval = setInterval(function () { + if (stream.closed) { + clearInterval(streamInterval); + } else { + onprogress(stream.bytesWritten); + } + }, 200); } }); - stream.on('error', onerror); - if (onprogress) { - var streamInterval = setInterval(function () { - if (stream.closed) { - clearInterval(streamInterval); - } - else { - onprogress(stream.bytesWritten); - } - }, 200); - } - }); - }, true); + }, + true + ); }; game.readFile = function (filename, callback, onerror) { - lib.node.fs.readFile(__dirname + '/' + filename, function (err, data) { + lib.node.fs.readFile(__dirname + "/" + filename, function (err, data) { if (err) { onerror(err); - } - else { + } else { callback(data); } }); }; game.readFileAsText = function (filename, callback, onerror) { - lib.node.fs.readFile(__dirname + '/' + filename, 'utf-8', function (err, data) { + lib.node.fs.readFile(__dirname + "/" + filename, "utf-8", function (err, data) { if (err) { onerror(err); - } - else { + } else { callback(data); } }); }; game.writeFile = function (data, path, name, callback) { game.ensureDirectory(path, function () { - if (Object.prototype.toString.call(data) == '[object File]') { + if (Object.prototype.toString.call(data) == "[object File]") { var fileReader = new FileReader(); fileReader.onload = function (e) { game.writeFile(e.target.result, path, name, callback); }; fileReader.readAsArrayBuffer(data, "UTF-8"); - } - else { + } else { get.zip(function (zip) { - zip.file('i', data); - lib.node.fs.writeFile(__dirname + '/' + path + '/' + name, zip.files.i.asNodeBuffer(), null, callback); + zip.file("i", data); + lib.node.fs.writeFile( + __dirname + "/" + path + "/" + name, + zip.files.i.asNodeBuffer(), + null, + callback + ); }); } }); }; game.removeFile = function (filename, callback) { - lib.node.fs.unlink(__dirname + '/' + filename, callback || function () { }); + lib.node.fs.unlink(__dirname + "/" + filename, callback || function () {}); }; game.getFileList = (dir, success, failure) => { - var files = [], folders = []; - dir = __dirname + '/' + dir; + var files = [], + folders = []; + dir = __dirname + "/" + dir; if (typeof failure == "undefined") { - failure = err => { + failure = (err) => { throw err; }; - } - else if (failure == null) { - failure = () => { }; + } else if (failure == null) { + failure = () => {}; } try { lib.node.fs.readdir(dir, (err, filelist) => { @@ -124,43 +128,53 @@ export function nodeReady() { return; } for (var i = 0; i < filelist.length; i++) { - if (filelist[i][0] != '.' && filelist[i][0] != '_') { - if (lib.node.fs.statSync(dir + '/' + filelist[i]).isDirectory()) { + if (filelist[i][0] != "." && filelist[i][0] != "_") { + if (lib.node.fs.statSync(dir + "/" + filelist[i]).isDirectory()) { folders.push(filelist[i]); - } - else { + } else { files.push(filelist[i]); } } } success(folders, files); }); - } - catch (e) { + } catch (e) { failure(e); } }; game.ensureDirectory = (list, callback, file) => { - const directoryList = typeof list == 'string' ? [list] : list.slice().reverse(), number = file ? 1 : 0, access = (path, directory, createDirectory) => { - if (directory.length <= number) { - createDirectory(); - return; - } - path += `/${directory.pop()}`; - const fullPath = `${__dirname}${path}`; - return new Promise((resolve, reject) => lib.node.fs.access(fullPath, errnoException => { - if (errnoException) reject(); - else resolve(); - })).catch(() => new Promise((resolve, reject) => lib.node.fs.mkdir(fullPath, errnoException => { - if (errnoException) reject(errnoException); - else resolve(); - }))).then(() => access(path, directory, createDirectory), console.log); - }; - new Promise(resolve => { + const directoryList = typeof list == "string" ? [list] : list.slice().reverse(), + number = file ? 1 : 0, + access = (path, directory, createDirectory) => { + if (directory.length <= number) { + createDirectory(); + return; + } + path += `/${directory.pop()}`; + const fullPath = `${__dirname}${path}`; + return new Promise((resolve, reject) => + lib.node.fs.access(fullPath, (errnoException) => { + if (errnoException) reject(); + else resolve(); + }) + ) + .catch( + () => + new Promise((resolve, reject) => + lib.node.fs.mkdir(fullPath, (errnoException) => { + if (errnoException) reject(errnoException); + else resolve(); + }) + ) + ) + .then(() => access(path, directory, createDirectory), console.log); + }; + new Promise((resolve) => { const createDirectory = () => { - if (directoryList.length) access('', directoryList.pop().split('/').reverse(), createDirectory); + if (directoryList.length) + access("", directoryList.pop().split("/").reverse(), createDirectory); else { - if (typeof callback == 'function') callback(); + if (typeof callback == "function") callback(); resolve(); } }; @@ -170,32 +184,35 @@ export function nodeReady() { game.createDir = (directory, successCallback, errorCallback) => { const target = lib.node.path.join(__dirname, directory); if (lib.node.fs.existsSync(target)) { - if (typeof errorCallback == 'function') { - errorCallback(new Error(`${target}已存在`)) - } - } else if (checkVersion(process.versions.node, '10.12.0') > -1) { - lib.node.fs.mkdir(target, { recursive: true }, e => { + // 修改逻辑,路径存在且是文件才会报错 + if (!lib.node.fs.lstatSync(target).isDirectory()){ + if (typeof errorCallback == "function") errorCallback(new Error(`${target}文件已存在`)); + else if (typeof successCallback == "function") successCallback(); + } + else if (typeof successCallback == "function") successCallback(); + } else if (checkVersion(process.versions.node, "10.12.0") > -1) { + lib.node.fs.mkdir(target, { recursive: true }, (e) => { if (e) { - if (typeof errorCallback == 'function') errorCallback(e); + if (typeof errorCallback == "function") errorCallback(e); else throw e; } else { - if (typeof successCallback == 'function') successCallback(); + if (typeof successCallback == "function") successCallback(); } }); } else { - const paths = directory.split('/').reverse(); + const paths = directory.split("/").reverse(); let path = __dirname; const redo = () => { path = lib.node.path.join(path, paths.pop()); const exists = lib.node.fs.existsSync(path); - const callback = e => { + const callback = (e) => { if (e) { - if (typeof errorCallback != 'function') throw e; + if (typeof errorCallback != "function") throw e; errorCallback(e); return; } if (paths.length) return redo(); - if (typeof successCallback == 'function') successCallback(); + if (typeof successCallback == "function") successCallback(); }; if (!exists) lib.node.fs.mkdir(path, callback); else callback(); @@ -206,39 +223,39 @@ export function nodeReady() { game.removeDir = (directory, successCallback, errorCallback) => { const target = lib.node.path.join(__dirname, directory); if (!lib.node.fs.existsSync(target)) { - if (typeof errorCallback == 'function') { - errorCallback(new Error(`${target}不存在`)) + if (typeof errorCallback == "function") { + errorCallback(new Error(`${target}不存在`)); } - } else if (!lib.node.fs.lstatSync(target).isDirectory()) { - if (typeof errorCallback == 'function') { - errorCallback(new Error(`${target}不是文件夹`)) + } else if (!lib.node.fs.lstatSync(target).isDirectory()) { + if (typeof errorCallback == "function") { + errorCallback(new Error(`${target}不是文件夹`)); } - } else if (checkVersion(process.versions.node, '12.10.0') > -1) { - lib.node.fs.rmdir(target, { recursive: true }, e => { + } else if (checkVersion(process.versions.node, "12.10.0") > -1) { + lib.node.fs.rmdir(target, { recursive: true }, (e) => { if (e) { - if (typeof errorCallback == 'function') errorCallback(e); + if (typeof errorCallback == "function") errorCallback(e); else throw e; } else { - if (typeof successCallback == 'function') successCallback(); + if (typeof successCallback == "function") successCallback(); } }); } else { - const deleteFolderRecursive = path => { + const deleteFolderRecursive = (path) => { if (!lib.node.fs.existsSync(path)) return; - lib.node.fs.readdirSync(path).forEach(file => { + lib.node.fs.readdirSync(path).forEach((file) => { const currentPath = `${path}/${file}`; if (lib.node.fs.lstatSync(currentPath).isDirectory()) deleteFolderRecursive(currentPath); else lib.node.fs.unlinkSync(currentPath); }); lib.node.fs.rmdirSync(path); - if (path === target && typeof successCallback == 'function') { + if (path === target && typeof successCallback == "function") { successCallback(); } }; try { deleteFolderRecursive(target); } catch (e) { - if (typeof errorCallback == 'function') errorCallback(e); + if (typeof errorCallback == "function") errorCallback(e); else throw e; } } diff --git a/noname/init/onload.js b/noname/init/onload.js index a58a207fa..731dac0b1 100644 --- a/noname/init/onload.js +++ b/noname/init/onload.js @@ -1,846 +1,919 @@ -// @ts-nocheck -import { AI as ai } from '../ai/index.js'; -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; - -import { userAgent } from '../util/index.js'; -import * as config from '../util/config.js'; -import { gnc } from '../gnc/index.js'; -import { Mutex } from '../util/index.js'; - -export async function onload(resetGameTimeout) { - const libOnload = lib.onload; - delete lib.onload; - await runCustomContents(libOnload); - - ui.updated(); - game.documentZoom = game.deviceZoom; - if (game.documentZoom !== 1) ui.updatez(); - - await createBackground(); - - if (lib.config.touchscreen) createTouchDraggedFilter(); - - // 不拆分,太玄学了 - if (lib.config.card_style === 'custom') { - const fileToLoad = await game.getDB('image', 'card_style') - if (fileToLoad) { - const fileLoadedEvent = await new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }) - if (ui.css.card_stylesheet) ui.css.card_stylesheet.remove(); - ui.css.card_stylesheet = lib.init.sheet(`.card:not(*:empty){background-image:url(${fileLoadedEvent.target.result})}`); - } - - } - if (lib.config.cardback_style === 'custom') { - const fileToLoad1 = await game.getDB('image', 'cardback_style'); - if (fileToLoad1) { - const fileLoadedEvent = await new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad1, "UTF-8"); - }) - if (ui.css.cardback_stylesheet) ui.css.cardback_stylesheet.remove(); - ui.css.cardback_stylesheet = lib.init.sheet(`.card:empty,.card.infohidden{background-image:url(${fileLoadedEvent.target.result})}`); - } - - const fileToLoad2 = await game.getDB('image', 'cardback_style2') - if (fileToLoad2) { - const fileLoadedEvent = await new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad2, "UTF-8"); - }) - if (ui.css.cardback_stylesheet2) ui.css.cardback_stylesheet2.remove(); - ui.css.cardback_stylesheet2 = lib.init.sheet(`.card.infohidden:not(.infoflip){background-image:url(${fileLoadedEvent.target.result})}`); - } - } - if (lib.config.hp_style === 'custom') { - const fileToLoad1 = await game.getDB('image', 'hp_style1') - if (fileToLoad1) { - const fileLoadedEvent = await new Promise((resolve, reject) => { - const fileReader = new FileReader(); - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad1, "UTF-8"); - }) - if (ui.css.hp_stylesheet1) ui.css.hp_stylesheet1.remove(); - ui.css.hp_stylesheet1 = lib.init.sheet(`.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}`); - } - - const fileToLoad2 = await game.getDB('image', 'hp_style2'); - if (fileToLoad2) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad2, "UTF-8"); - }); - if (ui.css.hp_stylesheet2) ui.css.hp_stylesheet2.remove(); - ui.css.hp_stylesheet2 = lib.init.sheet(`.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}`); - } - - const fileToLoad3 = await game.getDB('image', 'hp_style3'); - if (fileToLoad3) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad3, "UTF-8"); - }); - if (ui.css.hp_stylesheet3) ui.css.hp_stylesheet3.remove(); - ui.css.hp_stylesheet3 = lib.init.sheet(`.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}`); - } - - const fileToLoad4 = await game.getDB('image', 'hp_style4'); - if (fileToLoad4) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad4, "UTF-8"); - }); - if (ui.css.hp_stylesheet4) ui.css.hp_stylesheet4.remove(); - ui.css.hp_stylesheet4 = lib.init.sheet(`.hp:not(.text):not(.actcount)>.lost{background-image:url(${fileLoadedEvent.target.result})}`); - } - } - - if (lib.config.player_style === 'custom') { - const fileToLoad = await game.getDB('image', 'player_style'); - if (fileToLoad) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }); - if (ui.css.player_stylesheet) ui.css.player_stylesheet.remove(); - ui.css.player_stylesheet = lib.init.sheet(`#window .player{background-image:url("${fileLoadedEvent.target.result}");background-size:100% 100%;}`); - } else { - ui.css.player_stylesheet = lib.init.sheet('#window .player{background-image:none;background-size:100% 100%;}'); - } - } - if (lib.config.border_style === 'custom') { - const fileToLoad = await game.getDB('image', 'border_style'); - if (fileToLoad) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }); - if (ui.css.border_stylesheet) ui.css.border_stylesheet.remove(); - ui.css.border_stylesheet = lib.init.sheet(); - ui.css.border_stylesheet.sheet.insertRule(`#window .player>.framebg{display:block;background-image:url("${fileLoadedEvent.target.result}")}`, 0); - ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); - } - } - if (lib.config.control_style === 'custom') { - const fileToLoad = await game.getDB('image', 'control_style'); - if (fileToLoad) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }); - if (ui.css.control_stylesheet) ui.css.control_stylesheet.remove(); - ui.css.control_stylesheet = lib.init.sheet(`#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("${fileLoadedEvent.target.result}")}`); - } - } - if (lib.config.menu_style === 'custom') { - const fileToLoad = await game.getDB('image', 'menu_style'); - if (fileToLoad) { - const fileReader = new FileReader(); - const fileLoadedEvent = await new Promise((resolve, reject) => { - fileReader.onload = resolve; - fileReader.onerror = reject; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }); - if (ui.css.menu_stylesheet) ui.css.menu_stylesheet.remove(); - ui.css.menu_stylesheet = lib.init.sheet(`html #window>.dialog.popped,html .menu,html .menubg{background-image:url("${fileLoadedEvent.target.result}");background-size:cover}`); - } - } - - // 改不动,暂时不改了 - const proceed2 = async () => { - var mode = lib.imported.mode; - var card = lib.imported.card; - var character = lib.imported.character; - var play = lib.imported.play; - delete window.game; - var i, j, k; - for (i in mode[lib.config.mode].element) { - if (!lib.element[i]) lib.element[i] = []; - for (j in mode[lib.config.mode].element[i]) { - if (j == 'init') { - if (!lib.element[i].inits) lib.element[i].inits = []; - lib.element[i].inits.push(mode[lib.config.mode].element[i][j]); - } - else { - lib.element[i][j] = mode[lib.config.mode].element[i][j]; - } - } - } - for (i in mode[lib.config.mode].ai) { - if (typeof mode[lib.config.mode].ai[i] == 'object') { - if (ai[i] == undefined) ai[i] = {}; - for (j in mode[lib.config.mode].ai[i]) { - ai[i][j] = mode[lib.config.mode].ai[i][j]; - } - } - else { - ai[i] = mode[lib.config.mode].ai[i]; - } - } - for (i in mode[lib.config.mode].ui) { - if (typeof mode[lib.config.mode].ui[i] == 'object') { - if (ui[i] == undefined) ui[i] = {}; - for (j in mode[lib.config.mode].ui[i]) { - ui[i][j] = mode[lib.config.mode].ui[i][j]; - } - } - else { - ui[i] = mode[lib.config.mode].ui[i]; - } - } - for (i in mode[lib.config.mode].game) { - game[i] = mode[lib.config.mode].game[i]; - } - for (i in mode[lib.config.mode].get) { - get[i] = mode[lib.config.mode].get[i]; - } - lib.init.start = mode[lib.config.mode].start; - lib.init.startBefore = mode[lib.config.mode].startBefore; - if (game.onwash) { - lib.onwash.push(game.onwash); - delete game.onwash; - } - if (game.onover) { - lib.onover.push(game.onover); - delete game.onover; - } - lib.config.banned = lib.config[lib.config.mode + '_banned'] || []; - lib.config.bannedcards = lib.config[lib.config.mode + '_bannedcards'] || []; - - lib.rank = window.noname_character_rank; - delete window.noname_character_rank; - for (i in mode[lib.config.mode]) { - if (i == 'element') continue; - if (i == 'game') continue; - if (i == 'ai') continue; - if (i == 'ui') continue; - if (i == 'get') continue; - if (i == 'config') continue; - if (i == 'onreinit') continue; - if (i == 'start') continue; - if (i == 'startBefore') continue; - if (lib[i] == undefined) lib[i] = (Array.isArray(mode[lib.config.mode][i])) ? [] : {}; - for (j in mode[lib.config.mode][i]) { - lib[i][j] = mode[lib.config.mode][i][j]; - } - } - if (typeof mode[lib.config.mode].init == 'function') { - mode[lib.config.mode].init(); - } - - var connectCharacterPack = []; - var connectCardPack = []; - for (i in character) { - if (character[i].character) { - const characterPack = lib.characterPack[i]; - if (characterPack) Object.assign(characterPack, character[i].character); - else lib.characterPack[i] = character[i].character; - } - for (j in character[i]) { - if (j == 'mode' || j == 'forbid') continue; - if (j == 'connect') { - connectCharacterPack.push(i); - continue; - } - if (j == 'character' && !lib.config.characters.includes(i) && lib.config.mode != 'connect') { - if (lib.config.mode == 'chess' && get.config('chess_mode') == 'leader' && get.config('chess_leader_allcharacter')) { - for (k in character[i][j]) { - lib.hiddenCharacters.push(k); - } - } - else if (lib.config.mode != 'boss' || i != 'boss') { - continue; - } - } - if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { - lib[j].addArray(character[i][j]); - continue; - } - for (k in character[i][j]) { - if (j == 'character') { - if (!character[i][j][k][4]) { - character[i][j][k][4] = []; - } - if (character[i][j][k][4].includes('boss') || - character[i][j][k][4].includes('hiddenboss')) { - lib.config.forbidai.add(k); - } - if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { - lib.config.forbidai.add(k); - } - for (var l = 0; l < character[i][j][k][3].length; l++) { - lib.skilllist.add(character[i][j][k][3][l]); - } - } - if (j == 'skill' && k[0] == '_' && (lib.config.mode != 'connect' ? (!lib.config.characters.includes(i)) : (!character[i].connect))) { - continue; - } - if (j == 'translate' && k == i) { - lib[j][k + '_character_config'] = character[i][j][k]; - } - else { - if (lib[j][k] == undefined) { - if (j == 'skill' && !character[i][j][k].forceLoad && lib.config.mode == 'connect' && !character[i].connect) { - lib[j][k] = { - nopop: character[i][j][k].nopop, - derivation: character[i][j][k].derivation - }; - } - else { - Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(character[i][j], k)); - } - if (j == 'card' && lib[j][k].derivation) { - if (!lib.cardPack.mode_derivation) { - lib.cardPack.mode_derivation = [k]; - } - else { - lib.cardPack.mode_derivation.push(k); - } - } - } - else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { - lib[j][k].addArray(character[i][j][k]); - } - else { - console.log( - `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, - lib[j][k], - `\ncharacter.${i}.${j}.${k}`, - character[i][j][k] - ); - } - } - } - } - } - var connect_avatar_list = []; - for (var i in lib.character) { - connect_avatar_list.push(i); - } - connect_avatar_list.sort(lib.sort.capt); - for (var i = 0; i < connect_avatar_list.length; i++) { - var ia = connect_avatar_list[i]; - lib.mode.connect.config.connect_avatar.item[ia] = lib.translate[ia]; - } - if (lib.config.mode != 'connect') { - var pilecfg = lib.config.customcardpile[get.config('cardpilename') || '当前牌堆']; - if (pilecfg) { - lib.config.bannedpile = get.copy(pilecfg[0] || {}); - lib.config.addedpile = get.copy(pilecfg[1] || {}); - } - else { - lib.config.bannedpile = {}; - lib.config.addedpile = {}; - } - } - else { - lib.cardPackList = {}; - } - for (i in card) { - const cardPack = lib.cardPack[i] ? lib.cardPack[i] : lib.cardPack[i] = []; - if (card[i].card) { - for (var j in card[i].card) { - if (!card[i].card[j].hidden && card[i].translate[j + '_info']) { - cardPack.push(j); - } - } - } - for (j in card[i]) { - if (j == 'mode' || j == 'forbid') continue; - if (j == 'connect') { - connectCardPack.push(i); - continue; - } - if (j == 'list') { - if (lib.config.mode == 'connect') { - const cardPackList = lib.cardPackList[i]; - if (cardPackList) cardPackList.addArray(card[i][j]); - else lib.cardPackList[i] = card[i][j]; - } - else { - if (lib.config.cards.includes(i)) { - var pile; - if (typeof card[i][j] == 'function') { - pile = card[i][j](); - } - else { - pile = card[i][j]; - } - const cardPile = lib.cardPile[i]; - if (cardPile) cardPile.addArray(pile); - else lib.cardPile[i] = pile.slice(0); - if (lib.config.bannedpile[i]) { - for (var k = 0; k < lib.config.bannedpile[i].length; k++) { - pile[lib.config.bannedpile[i][k]] = null; - } - } - for (var k = 0; k < pile.length; k++) { - if (!pile[k]) { - pile.splice(k--, 1); - } - } - if (lib.config.addedpile[i]) { - for (var k = 0; k < lib.config.addedpile[i].length; k++) { - pile.push(lib.config.addedpile[i][k]); - } - } - lib.card.list.addArray(pile); - } - } - } - else { - for (k in card[i][j]) { - if (j == 'skill' && k[0] == '_' && !card[i][j][k].forceLoad && (lib.config.mode != 'connect' ? (!lib.config.cards.includes(i)) : (!card[i].connect))) { - continue; - } - if (j == 'translate' && k == i) { - lib[j][k + '_card_config'] = card[i][j][k]; - } - else { - if (lib[j][k] == undefined) { - if (j == 'skill' && !card[i][j][k].forceLoad && lib.config.mode == 'connect' && !card[i].connect) { - lib[j][k] = { - nopop: card[i][j][k].nopop, - derivation: card[i][j][k].derivation - }; - } - else { - Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(card[i][j], k)); - } - } - else { - console.log( - `dublicate ${j} in card ${i}:\n${k}:\nlib.${j}.${k}`, - lib[j][k], - `\ncard.${i}.${j}.${k}`, - card[i][j][k] - ); - } - if (j == 'card' && lib[j][k].derivation) { - if (!lib.cardPack.mode_derivation) { - lib.cardPack.mode_derivation = [k]; - } - else { - lib.cardPack.mode_derivation.push(k); - } - } - } - } - } - } - } - if (lib.cardPack.mode_derivation) { - for (var i = 0; i < lib.cardPack.mode_derivation.length; i++) { - if (typeof lib.card[lib.cardPack.mode_derivation[i]].derivation == 'string' && !lib.character[lib.card[lib.cardPack.mode_derivation[i]].derivation]) { - lib.cardPack.mode_derivation.splice(i--, 1); - } - else if (typeof lib.card[lib.cardPack.mode_derivation[i]].derivationpack == 'string' && !lib.config.cards.includes(lib.card[lib.cardPack.mode_derivation[i]].derivationpack)) { - lib.cardPack.mode_derivation.splice(i--, 1); - } - } - if (lib.cardPack.mode_derivation.length == 0) { - delete lib.cardPack.mode_derivation; - } - } - if (lib.config.mode != 'connect') { - for (i in play) { - if (lib.config.hiddenPlayPack.includes(i)) continue; - if (play[i].forbid && play[i].forbid.includes(lib.config.mode)) continue; - if (play[i].mode && play[i].mode.includes(lib.config.mode) == false) continue; - for (j in play[i].element) { - if (!lib.element[j]) lib.element[j] = []; - for (k in play[i].element[j]) { - if (k == 'init') { - if (!lib.element[j].inits) lib.element[j].inits = []; - lib.element[j].inits.push(play[i].element[j][k]); - } - else { - lib.element[j][k] = play[i].element[j][k]; - } - } - } - for (j in play[i].ui) { - if (typeof play[i].ui[j] == 'object') { - if (ui[j] == undefined) ui[j] = {}; - for (k in play[i].ui[j]) { - ui[j][k] = play[i].ui[j][k]; - } - } - else { - ui[j] = play[i].ui[j]; - } - } - for (j in play[i].game) { - game[j] = play[i].game[j]; - } - for (j in play[i].get) { - get[j] = play[i].get[j]; - } - for (j in play[i]) { - if (j == 'mode' || j == 'forbid' || j == 'init' || j == 'element' || - j == 'game' || j == 'get' || j == 'ui' || j == 'arenaReady') continue; - for (k in play[i][j]) { - if (j == 'translate' && k == i) { - // lib[j][k+'_play_config']=play[i][j][k]; - } - else { - if (lib[j][k] != undefined) { - console.log( - `dublicate ${j} in play ${i}:\n${k}:\nlib.${j}.${k}`, - lib[j][k], - `\nplay.${i}.${j}.${k}`, - play[i][j][k] - ); - } - lib[j][k] = play[i][j][k]; - } - } - } - if (typeof play[i].init == 'function') play[i].init(); - if (typeof play[i].arenaReady == 'function') lib.arenaReady.push(play[i].arenaReady); - } - } - - lib.connectCharacterPack = []; - lib.connectCardPack = []; - for (var i = 0; i < lib.config.all.characters.length; i++) { - var packname = lib.config.all.characters[i]; - if (connectCharacterPack.includes(packname)) { - lib.connectCharacterPack.push(packname) - } - } - for (var i = 0; i < lib.config.all.cards.length; i++) { - var packname = lib.config.all.cards[i]; - if (connectCardPack.includes(packname)) { - lib.connectCardPack.push(packname) - } - } - if (lib.config.mode != 'connect') { - for (i = 0; i < lib.card.list.length; i++) { - if (lib.card.list[i][2] == 'huosha') { - lib.card.list[i] = lib.card.list[i].slice(0); - lib.card.list[i][2] = 'sha'; - lib.card.list[i][3] = 'fire'; - } - else if (lib.card.list[i][2] == 'leisha') { - lib.card.list[i] = lib.card.list[i].slice(0); - lib.card.list[i][2] = 'sha'; - lib.card.list[i][3] = 'thunder'; - } - if (!lib.card[lib.card.list[i][2]]) { - lib.card.list.splice(i, 1); i--; - } - else if (lib.card[lib.card.list[i][2]].mode && - lib.card[lib.card.list[i][2]].mode.includes(lib.config.mode) == false) { - lib.card.list.splice(i, 1); i--; - } - } - } - - if (lib.config.mode == 'connect') { - _status.connectMode = true; - } - if (window.isNonameServer) { - lib.cheat.i(); - } - else if (lib.config.dev && (!_status.connectMode || lib.config.debug)) { - lib.cheat.i(); - } - lib.config.sort_card = get.sortCard(lib.config.sort); - delete lib.imported.character; - delete lib.imported.card; - delete lib.imported.mode; - delete lib.imported.play; - for (var i in lib.init) { - if (i.startsWith('setMode_')) { - delete lib.init[i]; - } - } - if (!_status.connectMode) { - for (var i = 0; i < lib.extensions.length; i++) { - try { - _status.extension = lib.extensions[i][0]; - _status.evaluatingExtension = lib.extensions[i][3]; - if (typeof lib.extensions[i][1] == "function") - try{ - await (gnc.is.coroutine(lib.extensions[i][1]) ? gnc.of(lib.extensions[i][1]) : lib.extensions[i][1]).call(lib.extensions[i], lib.extensions[i][2], lib.extensions[i][4]); - }catch(e){ - console.log(`加载《${lib.extensions[i][0]}》扩展的content时出现错误。`,e); - if(!lib.config.extension_alert) alert(`加载《${lib.extensions[i][0]}》扩展的content时出现错误。\n该错误本身可能并不影响扩展运行。您可以在“设置→通用→无视扩展报错”中关闭此弹窗。\n${decodeURI(e.stack)}`); - } - if (lib.extensions[i][4]) { - if (lib.extensions[i][4].character) { - for (var j in lib.extensions[i][4].character.character) { - game.addCharacterPack(get.copy(lib.extensions[i][4].character)); - break; - } - } - if (lib.extensions[i][4].card) { - for (var j in lib.extensions[i][4].card.card) { - game.addCardPack(get.copy(lib.extensions[i][4].card)); - break; - } - } - if (lib.extensions[i][4].skill) { - for (var j in lib.extensions[i][4].skill.skill) { - game.addSkill(j, lib.extensions[i][4].skill.skill[j], - lib.extensions[i][4].skill.translate[j], - lib.extensions[i][4].skill.translate[j + '_info'], - lib.extensions[i][4].skill.translate[j + '_append'], - lib.extensions[i][4].skill.translate[j + '_ab']); - } - } - } - delete _status.extension; - delete _status.evaluatingExtension; - } - catch (e) { - console.log(e); - } - } - } - delete lib.extensions; - - if (lib.init.startBefore) { - lib.init.startBefore(); - delete lib.init.startBefore; - } - ui.create.arena(); - game.createEvent('game', false).setContent(lib.init.start); - if (lib.mode[lib.config.mode] && lib.mode[lib.config.mode].fromextension) { - var startstr = mode[lib.config.mode].start.toString(); - if (startstr.indexOf('onfree') == -1) { - setTimeout(lib.init.onfree, 500); - } - } - delete lib.init.start; - if (Array.isArray(_status.onprepare) && _status.onprepare.length) { - await Promise.allSettled(_status.onprepare); - delete _status.onprepare; - } - game.loop(); - }; - const proceed = async () => { - if (!lib.db) { - try { - lib.storage = JSON.parse(localStorage.getItem(lib.configprefix + lib.config.mode)); - if (typeof lib.storage !== 'object') throw ('err'); - if (lib.storage === null) throw ('err'); - } catch (err) { - lib.storage = {}; - localStorage.setItem(lib.configprefix + lib.config.mode, "{}"); - } - await proceed2(); - } - else { - await game.getDB('data', lib.config.mode, async (obj) => { - lib.storage = obj || {}; - await proceed2(); - }); - } - }; - - if (!lib.imported.mode || !lib.imported.mode[lib.config.mode]) { - window.inSplash = true; - clearTimeout(resetGameTimeout); - let clickedNode = false; - const clickNode = function () { - if (clickedNode) return; - this.classList.add('clicked'); - clickedNode = true; - lib.config.mode = this.link; - game.saveConfig('mode', this.link); - if (game.layout != 'mobile' && lib.layoutfixed.indexOf(lib.config.mode) !== -1) { - game.layout = 'mobile'; - ui.css.layout.href = lib.assetURL + 'layout/' + game.layout + '/layout.css'; - } - else if (game.layout == 'mobile' && lib.config.layout != 'mobile' && lib.layoutfixed.indexOf(lib.config.mode) === -1) { - game.layout = lib.config.layout; - if (game.layout == 'default') { - ui.css.layout.href = ''; - } - else { - ui.css.layout.href = lib.assetURL + 'layout/' + game.layout + '/layout.css'; - } - } - splash.delete(1000); - delete window.inSplash; - // 这不好删/m/,顺带lib.init.reset也不好删 - window.resetGameTimeout = setTimeout(lib.init.reset, 10000); - - this.listenTransition(function () { - lib.init.js(lib.assetURL + 'mode', lib.config.mode, proceed); - }, 500); - } - var downNode = function () { - this.classList.add('glow'); - } - var upNode = function () { - this.classList.remove('glow'); - } - var splash = ui.create.div('#splash', document.body); - if (lib.config.touchscreen) { - splash.classList.add('touch'); - lib.setScroll(splash); - } - if (lib.config.player_border != 'wide') { - splash.classList.add('slim'); - } - splash.dataset.radius_size = lib.config.radius_size; - for (var i = 0; i < lib.config.all.mode.length; i++) { - var node = ui.create.div('.hidden', splash, clickNode); - node.link = lib.config.all.mode[i]; - ui.create.div(node, '.splashtext', get.verticalStr(get.translation(lib.config.all.mode[i]))); - if (lib.config.all.stockmode.includes(lib.config.all.mode[i])) { - // 初始启动页设置 - if (lib.config.splash_style == undefined) game.saveConfig('splash_style', 'style1'); - splash.dataset.splash_style = lib.config.splash_style; - // 扩展可通过window.splashurl设置素材读取路径 - if (window.splashurl == undefined) window.splashurl = 'image/splash/'; - if (lib.config.splash_style == 'style1' || lib.config.splash_style == 'style2') { - ui.create.div(node, '.avatar').setBackgroundImage('image/splash/' + lib.config.splash_style + '/' + lib.config.all.mode[i] + '.jpg'); - } else { - ui.create.div(node, '.avatar').setBackgroundImage(splashurl + lib.config.splash_style + '/' + lib.config.all.mode[i] + '.jpg'); - } - } - else { - var avatarnode = ui.create.div(node, '.avatar'); - var avatarbg = lib.mode[lib.config.all.mode[i]].splash; - if (avatarbg.startsWith('ext:')) { - avatarnode.setBackgroundImage(avatarbg.replace(/^ext:/, 'extension/')); - } - else { - avatarnode.setBackgroundDB(avatarbg); - } - } - if (!lib.config.touchscreen) { - node.addEventListener('mousedown', downNode); - node.addEventListener('mouseup', upNode); - node.addEventListener('mouseleave', upNode); - } - setTimeout((function (node) { - return function () { - node.show(); - } - }(node)), i * 100); - } - if (lib.config.mousewheel) { - splash.onmousewheel = ui.click.mousewheel; - } - } - else { - Reflect.set(window, 'resetGameTimeout', resetGameTimeout); - proceed().then(lib.other.ignore); - } - localStorage.removeItem(lib.configprefix + 'directstart'); - - const libOnload2 = lib.onload2; - delete lib.onload2; - await runCustomContents(libOnload2) -} - -async function createBackground() { - ui.background = ui.create.div('.background'); - ui.background.style.backgroundSize = "cover"; - ui.background.style.backgroundPosition = '50% 50%'; - - document.documentElement.style.backgroundImage = ''; - document.documentElement.style.backgroundSize = ''; - document.documentElement.style.backgroundPosition = ''; - document.body.insertBefore(ui.background, document.body.firstChild); - document.body.onresize = ui.updatexr; - - if (!lib.config.image_background) return; - if (lib.config.image_background === 'default') return - - let url = `url("${lib.assetURL}image/background/${lib.config.image_background}.jpg")`; - - if (lib.config.image_background.startsWith('custom_')) { - try { - const fileToLoad = await game.getDB('image', lib.config.image_background); - const fileReader = new FileReader(); - const fileLoadedEvent = await Promise((resolve) => { - fileReader.onload = resolve; - fileReader.readAsDataURL(fileToLoad, "UTF-8"); - }) - const data = fileLoadedEvent.target.result; - url = `url("${data}")`; - } catch (e) { - console.error(e); - url = "none"; - } - } - - ui.background.style.backgroundImage = url; - if (lib.config.image_background_blur) { - ui.background.style.filter = 'blur(8px)'; - ui.background.style.webkitFilter = 'blur(8px)'; - ui.background.style.transform = 'scale(1.05)'; - } -} - -function createTouchDraggedFilter() { - document.body.addEventListener('touchstart', function (e) { - this.startX = e.touches[0].clientX / game.documentZoom; - this.startY = e.touches[0].clientY / game.documentZoom; - _status.dragged = false; - }); - document.body.addEventListener('touchmove', function (e) { - if (_status.dragged) return; - if (Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || - Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10) { - _status.dragged = true; - } - }); -} - -/** - * @async - * @param {((function(Mutex): void) | GeneratorFunction)[]} contents - */ -function runCustomContents(contents) { - if (!Array.isArray(contents)) return - - const mutex = new Mutex(); - - const tasks = contents - .filter((fn) => typeof fn === "function") - .map((fn) => gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn) // 将生成器函数转换成genCoroutin - .map((fn) => fn(mutex)) - - - return Promise - .allSettled(tasks) - .then((results) => { - results.forEach((result) => { - if (result.status === "rejected") { - console.error(result.reason) - } - }) - }) -} +// @ts-nocheck +import { ai } from "../ai/index.js"; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { gnc } from "../gnc/index.js"; +import { Mutex } from "../util/index.js"; + +export async function onload(resetGameTimeout) { + const libOnload = lib.onload; + delete lib.onload; + await runCustomContents(libOnload); + + ui.updated(); + game.documentZoom = game.deviceZoom; + if (game.documentZoom !== 1) ui.updatez(); + + await createBackground(); + + if (lib.config.touchscreen) createTouchDraggedFilter(); + + // 不拆分,太玄学了 + if (lib.config.card_style === "custom") { + const fileToLoad = await game.getDB("image", "card_style"); + if (fileToLoad) { + const fileLoadedEvent = await new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + if (ui.css.card_stylesheet) ui.css.card_stylesheet.remove(); + ui.css.card_stylesheet = lib.init.sheet( + `.card:not(*:empty){background-image:url(${fileLoadedEvent.target.result})}` + ); + } + } + if (lib.config.cardback_style === "custom") { + const fileToLoad1 = await game.getDB("image", "cardback_style"); + if (fileToLoad1) { + const fileLoadedEvent = await new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad1, "UTF-8"); + }); + if (ui.css.cardback_stylesheet) ui.css.cardback_stylesheet.remove(); + ui.css.cardback_stylesheet = lib.init.sheet( + `.card:empty,.card.infohidden{background-image:url(${fileLoadedEvent.target.result})}` + ); + } + + const fileToLoad2 = await game.getDB("image", "cardback_style2"); + if (fileToLoad2) { + const fileLoadedEvent = await new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad2, "UTF-8"); + }); + if (ui.css.cardback_stylesheet2) ui.css.cardback_stylesheet2.remove(); + ui.css.cardback_stylesheet2 = lib.init.sheet( + `.card.infohidden:not(.infoflip){background-image:url(${fileLoadedEvent.target.result})}` + ); + } + } + if (lib.config.hp_style === "custom") { + const fileToLoad1 = await game.getDB("image", "hp_style1"); + if (fileToLoad1) { + const fileLoadedEvent = await new Promise((resolve, reject) => { + const fileReader = new FileReader(); + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad1, "UTF-8"); + }); + if (ui.css.hp_stylesheet1) ui.css.hp_stylesheet1.remove(); + ui.css.hp_stylesheet1 = lib.init.sheet( + `.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}` + ); + } + + const fileToLoad2 = await game.getDB("image", "hp_style2"); + if (fileToLoad2) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad2, "UTF-8"); + }); + if (ui.css.hp_stylesheet2) ui.css.hp_stylesheet2.remove(); + ui.css.hp_stylesheet2 = lib.init.sheet( + `.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}` + ); + } + + const fileToLoad3 = await game.getDB("image", "hp_style3"); + if (fileToLoad3) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad3, "UTF-8"); + }); + if (ui.css.hp_stylesheet3) ui.css.hp_stylesheet3.remove(); + ui.css.hp_stylesheet3 = lib.init.sheet( + `.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url(${fileLoadedEvent.target.result})}` + ); + } + + const fileToLoad4 = await game.getDB("image", "hp_style4"); + if (fileToLoad4) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad4, "UTF-8"); + }); + if (ui.css.hp_stylesheet4) ui.css.hp_stylesheet4.remove(); + ui.css.hp_stylesheet4 = lib.init.sheet( + `.hp:not(.text):not(.actcount)>.lost{background-image:url(${fileLoadedEvent.target.result})}` + ); + } + } + + if (lib.config.player_style === "custom") { + const fileToLoad = await game.getDB("image", "player_style"); + if (fileToLoad) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + if (ui.css.player_stylesheet) ui.css.player_stylesheet.remove(); + ui.css.player_stylesheet = lib.init.sheet( + `#window .player{background-image:url("${fileLoadedEvent.target.result}");background-size:100% 100%;}` + ); + } else { + ui.css.player_stylesheet = lib.init.sheet( + "#window .player{background-image:none;background-size:100% 100%;}" + ); + } + } + if (lib.config.border_style === "custom") { + const fileToLoad = await game.getDB("image", "border_style"); + if (fileToLoad) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + if (ui.css.border_stylesheet) ui.css.border_stylesheet.remove(); + ui.css.border_stylesheet = lib.init.sheet(); + ui.css.border_stylesheet.sheet.insertRule( + `#window .player>.framebg{display:block;background-image:url("${fileLoadedEvent.target.result}")}`, + 0 + ); + ui.css.border_stylesheet.sheet.insertRule( + ".player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}", + 0 + ); + } + } + if (lib.config.control_style === "custom") { + const fileToLoad = await game.getDB("image", "control_style"); + if (fileToLoad) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + if (ui.css.control_stylesheet) ui.css.control_stylesheet.remove(); + ui.css.control_stylesheet = lib.init.sheet( + `#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("${fileLoadedEvent.target.result}")}` + ); + } + } + if (lib.config.menu_style === "custom") { + const fileToLoad = await game.getDB("image", "menu_style"); + if (fileToLoad) { + const fileReader = new FileReader(); + const fileLoadedEvent = await new Promise((resolve, reject) => { + fileReader.onload = resolve; + fileReader.onerror = reject; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + if (ui.css.menu_stylesheet) ui.css.menu_stylesheet.remove(); + ui.css.menu_stylesheet = lib.init.sheet( + `html #window>.dialog.popped,html .menu,html .menubg{background-image:url("${fileLoadedEvent.target.result}");background-size:cover}` + ); + } + } + + // 改不动,暂时不改了 + const proceed2 = async () => { + var mode = lib.imported.mode; + var card = lib.imported.card; + var character = lib.imported.character; + var play = lib.imported.play; + delete window.game; + var i, j, k; + for (i in mode[lib.config.mode].element) { + if (!lib.element[i]) lib.element[i] = []; + for (j in mode[lib.config.mode].element[i]) { + if (j == "init") { + if (!lib.element[i].inits) lib.element[i].inits = []; + lib.element[i].inits.push(mode[lib.config.mode].element[i][j]); + } else { + lib.element[i][j] = mode[lib.config.mode].element[i][j]; + } + } + } + for (i in mode[lib.config.mode].ai) { + if (typeof mode[lib.config.mode].ai[i] == "object") { + if (ai[i] == undefined) ai[i] = {}; + for (j in mode[lib.config.mode].ai[i]) { + ai[i][j] = mode[lib.config.mode].ai[i][j]; + } + } else { + ai[i] = mode[lib.config.mode].ai[i]; + } + } + for (i in mode[lib.config.mode].ui) { + if (typeof mode[lib.config.mode].ui[i] == "object") { + if (ui[i] == undefined) ui[i] = {}; + for (j in mode[lib.config.mode].ui[i]) { + ui[i][j] = mode[lib.config.mode].ui[i][j]; + } + } else { + ui[i] = mode[lib.config.mode].ui[i]; + } + } + for (i in mode[lib.config.mode].game) { + game[i] = mode[lib.config.mode].game[i]; + } + for (i in mode[lib.config.mode].get) { + get[i] = mode[lib.config.mode].get[i]; + } + lib.init.start = mode[lib.config.mode].start; + lib.init.startBefore = mode[lib.config.mode].startBefore; + if (game.onwash) { + lib.onwash.push(game.onwash); + delete game.onwash; + } + if (game.onover) { + lib.onover.push(game.onover); + delete game.onover; + } + lib.config.banned = lib.config[lib.config.mode + "_banned"] || []; + lib.config.bannedcards = lib.config[lib.config.mode + "_bannedcards"] || []; + + lib.rank = window.noname_character_rank; + delete window.noname_character_rank; + for (i in mode[lib.config.mode]) { + if (i == "element") continue; + if (i == "game") continue; + if (i == "ai") continue; + if (i == "ui") continue; + if (i == "get") continue; + if (i == "config") continue; + if (i == "onreinit") continue; + if (i == "start") continue; + if (i == "startBefore") continue; + if (lib[i] == undefined) lib[i] = Array.isArray(mode[lib.config.mode][i]) ? [] : {}; + for (j in mode[lib.config.mode][i]) { + lib[i][j] = mode[lib.config.mode][i][j]; + } + } + if (typeof mode[lib.config.mode].init == "function") { + mode[lib.config.mode].init(); + } + + var connectCharacterPack = []; + var connectCardPack = []; + for (i in character) { + if (character[i].character) { + const characterPack = lib.characterPack[i]; + if (characterPack) Object.assign(characterPack, character[i].character); + else lib.characterPack[i] = character[i].character; + } + for (j in character[i]) { + if (j == "mode" || j == "forbid") continue; + if (j == "connect") { + connectCharacterPack.push(i); + continue; + } + if (j == "character" && !lib.config.characters.includes(i) && lib.config.mode != "connect") { + if ( + lib.config.mode == "chess" && + get.config("chess_mode") == "leader" && + get.config("chess_leader_allcharacter") + ) { + for (k in character[i][j]) { + lib.hiddenCharacters.push(k); + } + } else if (lib.config.mode != "boss" || i != "boss") { + continue; + } + } + if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { + lib[j].addArray(character[i][j]); + continue; + } + for (k in character[i][j]) { + if (j == "character") { + if (!character[i][j][k][4]) { + character[i][j][k][4] = []; + } + if ( + character[i][j][k][4].includes("boss") || + character[i][j][k][4].includes("hiddenboss") + ) { + lib.config.forbidai.add(k); + } + if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { + lib.config.forbidai.add(k); + } + for (var l = 0; l < character[i][j][k][3].length; l++) { + lib.skilllist.add(character[i][j][k][3][l]); + } + } + if ( + j == "skill" && + k[0] == "_" && + (lib.config.mode != "connect" + ? !lib.config.characters.includes(i) + : !character[i].connect) + ) { + continue; + } + if (j == "translate" && k == i) { + lib[j][k + "_character_config"] = character[i][j][k]; + } else { + if (lib[j][k] == undefined) { + if ( + j == "skill" && + !character[i][j][k].forceLoad && + lib.config.mode == "connect" && + !character[i].connect + ) { + lib[j][k] = { + nopop: character[i][j][k].nopop, + derivation: character[i][j][k].derivation, + }; + } else { + Object.defineProperty( + lib[j], + k, + Object.getOwnPropertyDescriptor(character[i][j], k) + ); + } + if (j == "card" && lib[j][k].derivation) { + if (!lib.cardPack.mode_derivation) { + lib.cardPack.mode_derivation = [k]; + } else { + lib.cardPack.mode_derivation.push(k); + } + } + } else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { + lib[j][k].addArray(character[i][j][k]); + } else { + console.log( + `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, + lib[j][k], + `\ncharacter.${i}.${j}.${k}`, + character[i][j][k] + ); + } + } + } + } + } + var connect_avatar_list = []; + for (var i in lib.character) { + connect_avatar_list.push(i); + } + connect_avatar_list.sort(lib.sort.capt); + for (var i = 0; i < connect_avatar_list.length; i++) { + var ia = connect_avatar_list[i]; + lib.mode.connect.config.connect_avatar.item[ia] = lib.translate[ia]; + } + if (lib.config.mode != "connect") { + var pilecfg = lib.config.customcardpile[get.config("cardpilename") || "当前牌堆"]; + if (pilecfg) { + lib.config.bannedpile = get.copy(pilecfg[0] || {}); + lib.config.addedpile = get.copy(pilecfg[1] || {}); + } else { + lib.config.bannedpile = {}; + lib.config.addedpile = {}; + } + } else { + lib.cardPackList = {}; + } + for (i in card) { + const cardPack = lib.cardPack[i] ? lib.cardPack[i] : (lib.cardPack[i] = []); + if (card[i].card) { + for (var j in card[i].card) { + if (!card[i].card[j].hidden && card[i].translate[j + "_info"]) { + cardPack.push(j); + } + } + } + for (j in card[i]) { + if (j == "mode" || j == "forbid") continue; + if (j == "connect") { + connectCardPack.push(i); + continue; + } + if (j == "list") { + if (lib.config.mode == "connect") { + const cardPackList = lib.cardPackList[i]; + if (cardPackList) cardPackList.addArray(card[i][j]); + else lib.cardPackList[i] = card[i][j]; + } else { + if (lib.config.cards.includes(i)) { + var pile; + if (typeof card[i][j] == "function") { + pile = card[i][j](); + } else { + pile = card[i][j]; + } + const cardPile = lib.cardPile[i]; + if (cardPile) cardPile.addArray(pile); + else lib.cardPile[i] = pile.slice(0); + if (lib.config.bannedpile[i]) { + for (var k = 0; k < lib.config.bannedpile[i].length; k++) { + pile[lib.config.bannedpile[i][k]] = null; + } + } + for (var k = 0; k < pile.length; k++) { + if (!pile[k]) { + pile.splice(k--, 1); + } + } + if (lib.config.addedpile[i]) { + for (var k = 0; k < lib.config.addedpile[i].length; k++) { + pile.push(lib.config.addedpile[i][k]); + } + } + lib.card.list.addArray(pile); + } + } + } else { + for (k in card[i][j]) { + if ( + j == "skill" && + k[0] == "_" && + !card[i][j][k].forceLoad && + (lib.config.mode != "connect" ? !lib.config.cards.includes(i) : !card[i].connect) + ) { + continue; + } + if (j == "translate" && k == i) { + lib[j][k + "_card_config"] = card[i][j][k]; + } else { + if (lib[j][k] == undefined) { + if ( + j == "skill" && + !card[i][j][k].forceLoad && + lib.config.mode == "connect" && + !card[i].connect + ) { + lib[j][k] = { + nopop: card[i][j][k].nopop, + derivation: card[i][j][k].derivation, + }; + } else { + Object.defineProperty( + lib[j], + k, + Object.getOwnPropertyDescriptor(card[i][j], k) + ); + } + } else { + console.log( + `dublicate ${j} in card ${i}:\n${k}:\nlib.${j}.${k}`, + lib[j][k], + `\ncard.${i}.${j}.${k}`, + card[i][j][k] + ); + } + if (j == "card" && lib[j][k].derivation) { + if (!lib.cardPack.mode_derivation) { + lib.cardPack.mode_derivation = [k]; + } else { + lib.cardPack.mode_derivation.push(k); + } + } + } + } + } + } + } + if (lib.cardPack.mode_derivation) { + for (var i = 0; i < lib.cardPack.mode_derivation.length; i++) { + if ( + typeof lib.card[lib.cardPack.mode_derivation[i]].derivation == "string" && + !lib.character[lib.card[lib.cardPack.mode_derivation[i]].derivation] + ) { + lib.cardPack.mode_derivation.splice(i--, 1); + } else if ( + typeof lib.card[lib.cardPack.mode_derivation[i]].derivationpack == "string" && + !lib.config.cards.includes(lib.card[lib.cardPack.mode_derivation[i]].derivationpack) + ) { + lib.cardPack.mode_derivation.splice(i--, 1); + } + } + if (lib.cardPack.mode_derivation.length == 0) { + delete lib.cardPack.mode_derivation; + } + } + if (lib.config.mode != "connect") { + for (i in play) { + if (lib.config.hiddenPlayPack.includes(i)) continue; + if (play[i].forbid && play[i].forbid.includes(lib.config.mode)) continue; + if (play[i].mode && play[i].mode.includes(lib.config.mode) == false) continue; + for (j in play[i].element) { + if (!lib.element[j]) lib.element[j] = []; + for (k in play[i].element[j]) { + if (k == "init") { + if (!lib.element[j].inits) lib.element[j].inits = []; + lib.element[j].inits.push(play[i].element[j][k]); + } else { + lib.element[j][k] = play[i].element[j][k]; + } + } + } + for (j in play[i].ui) { + if (typeof play[i].ui[j] == "object") { + if (ui[j] == undefined) ui[j] = {}; + for (k in play[i].ui[j]) { + ui[j][k] = play[i].ui[j][k]; + } + } else { + ui[j] = play[i].ui[j]; + } + } + for (j in play[i].game) { + game[j] = play[i].game[j]; + } + for (j in play[i].get) { + get[j] = play[i].get[j]; + } + for (j in play[i]) { + if ( + j == "mode" || + j == "forbid" || + j == "init" || + j == "element" || + j == "game" || + j == "get" || + j == "ui" || + j == "arenaReady" + ) + continue; + for (k in play[i][j]) { + if (j == "translate" && k == i) { + // lib[j][k+'_play_config']=play[i][j][k]; + } else { + if (lib[j][k] != undefined) { + console.log( + `dublicate ${j} in play ${i}:\n${k}:\nlib.${j}.${k}`, + lib[j][k], + `\nplay.${i}.${j}.${k}`, + play[i][j][k] + ); + } + lib[j][k] = play[i][j][k]; + } + } + } + if (typeof play[i].init == "function") play[i].init(); + if (typeof play[i].arenaReady == "function") lib.arenaReady.push(play[i].arenaReady); + } + } + + lib.connectCharacterPack = []; + lib.connectCardPack = []; + for (var i = 0; i < lib.config.all.characters.length; i++) { + var packname = lib.config.all.characters[i]; + if (connectCharacterPack.includes(packname)) { + lib.connectCharacterPack.push(packname); + } + } + for (var i = 0; i < lib.config.all.cards.length; i++) { + var packname = lib.config.all.cards[i]; + if (connectCardPack.includes(packname)) { + lib.connectCardPack.push(packname); + } + } + if (lib.config.mode != "connect") { + for (i = 0; i < lib.card.list.length; i++) { + if (lib.card.list[i][2] == "huosha") { + lib.card.list[i] = lib.card.list[i].slice(0); + lib.card.list[i][2] = "sha"; + lib.card.list[i][3] = "fire"; + } else if (lib.card.list[i][2] == "leisha") { + lib.card.list[i] = lib.card.list[i].slice(0); + lib.card.list[i][2] = "sha"; + lib.card.list[i][3] = "thunder"; + } + if (!lib.card[lib.card.list[i][2]]) { + lib.card.list.splice(i, 1); + i--; + } else if ( + lib.card[lib.card.list[i][2]].mode && + lib.card[lib.card.list[i][2]].mode.includes(lib.config.mode) == false + ) { + lib.card.list.splice(i, 1); + i--; + } + } + } + + if (lib.config.mode == "connect") { + _status.connectMode = true; + } + if (window.isNonameServer) { + lib.cheat.i(); + } else if (lib.config.dev && (!_status.connectMode || lib.config.debug)) { + lib.cheat.i(); + } + lib.config.sort_card = get.sortCard(lib.config.sort); + delete lib.imported.character; + delete lib.imported.card; + delete lib.imported.mode; + delete lib.imported.play; + for (var i in lib.init) { + if (i.startsWith("setMode_")) { + delete lib.init[i]; + } + } + if (!_status.connectMode) { + for (var i = 0; i < lib.extensions.length; i++) { + try { + _status.extension = lib.extensions[i][0]; + _status.evaluatingExtension = lib.extensions[i][3]; + if (typeof lib.extensions[i][1] == "function") + try { + await (gnc.is.coroutine(lib.extensions[i][1]) + ? gnc.of(lib.extensions[i][1]) + : lib.extensions[i][1] + ).call(lib.extensions[i], lib.extensions[i][2], lib.extensions[i][4]); + } catch (e) { + console.log(`加载《${lib.extensions[i][0]}》扩展的content时出现错误。`, e); + if (!lib.config.extension_alert) + alert( + `加载《${ + lib.extensions[i][0] + }》扩展的content时出现错误。\n该错误本身可能并不影响扩展运行。您可以在“设置→通用→无视扩展报错”中关闭此弹窗。\n${decodeURI( + e.stack + )}` + ); + } + if (lib.extensions[i][4]) { + if (lib.extensions[i][4].character) { + for (var j in lib.extensions[i][4].character.character) { + game.addCharacterPack(get.copy(lib.extensions[i][4].character)); + break; + } + } + if (lib.extensions[i][4].card) { + for (var j in lib.extensions[i][4].card.card) { + game.addCardPack(get.copy(lib.extensions[i][4].card)); + break; + } + } + if (lib.extensions[i][4].skill) { + for (var j in lib.extensions[i][4].skill.skill) { + game.addSkill( + j, + lib.extensions[i][4].skill.skill[j], + lib.extensions[i][4].skill.translate[j], + lib.extensions[i][4].skill.translate[j + "_info"], + lib.extensions[i][4].skill.translate[j + "_append"], + lib.extensions[i][4].skill.translate[j + "_ab"] + ); + } + } + } + delete _status.extension; + delete _status.evaluatingExtension; + } catch (e) { + console.log(e); + } + } + } + delete lib.extensions; + + if (lib.init.startBefore) { + lib.init.startBefore(); + delete lib.init.startBefore; + } + ui.create.arena(); + game.createEvent("game", false).setContent(lib.init.start); + if (lib.mode[lib.config.mode] && lib.mode[lib.config.mode].fromextension) { + var startstr = mode[lib.config.mode].start.toString(); + if (startstr.indexOf("onfree") == -1) { + setTimeout(lib.init.onfree, 500); + } + } + delete lib.init.start; + if (Array.isArray(_status.onprepare) && _status.onprepare.length) { + await Promise.allSettled(_status.onprepare); + delete _status.onprepare; + } + game.loop(); + }; + const proceed = async () => { + if (!lib.db) { + try { + lib.storage = JSON.parse(localStorage.getItem(lib.configprefix + lib.config.mode)); + if (typeof lib.storage !== "object") throw "err"; + if (lib.storage === null) throw "err"; + } catch (err) { + lib.storage = {}; + localStorage.setItem(lib.configprefix + lib.config.mode, "{}"); + } + await proceed2(); + } else { + await game.getDB("data", lib.config.mode, async (obj) => { + lib.storage = obj || {}; + await proceed2(); + }); + } + }; + + if (!lib.imported.mode || !lib.imported.mode[lib.config.mode]) { + window.inSplash = true; + clearTimeout(resetGameTimeout); + let clickedNode = false; + const clickNode = function () { + if (clickedNode) return; + this.classList.add("clicked"); + clickedNode = true; + lib.config.mode = this.link; + game.saveConfig("mode", this.link); + if (game.layout != "mobile" && lib.layoutfixed.indexOf(lib.config.mode) !== -1) { + game.layout = "mobile"; + ui.css.layout.href = lib.assetURL + "layout/" + game.layout + "/layout.css"; + } else if ( + game.layout == "mobile" && + lib.config.layout != "mobile" && + lib.layoutfixed.indexOf(lib.config.mode) === -1 + ) { + game.layout = lib.config.layout; + if (game.layout == "default") { + ui.css.layout.href = ""; + } else { + ui.css.layout.href = lib.assetURL + "layout/" + game.layout + "/layout.css"; + } + } + splash.delete(1000); + delete window.inSplash; + // 这不好删/m/,顺带lib.init.reset也不好删 + window.resetGameTimeout = setTimeout(lib.init.reset, 10000); + + this.listenTransition(function () { + lib.init.js(lib.assetURL + "mode", lib.config.mode, proceed); + }, 500); + }; + var downNode = function () { + this.classList.add("glow"); + }; + var upNode = function () { + this.classList.remove("glow"); + }; + var splash = ui.create.div("#splash", document.body); + if (lib.config.touchscreen) { + splash.classList.add("touch"); + lib.setScroll(splash); + } + if (lib.config.player_border != "wide") { + splash.classList.add("slim"); + } + splash.dataset.radius_size = lib.config.radius_size; + for (var i = 0; i < lib.config.all.mode.length; i++) { + var node = ui.create.div(".hidden", splash, clickNode); + node.link = lib.config.all.mode[i]; + ui.create.div(node, ".splashtext", get.verticalStr(get.translation(lib.config.all.mode[i]))); + if (lib.config.all.stockmode.includes(lib.config.all.mode[i])) { + // 初始启动页设置 + if (lib.config.splash_style == undefined) game.saveConfig("splash_style", "style1"); + splash.dataset.splash_style = lib.config.splash_style; + // 扩展可通过window.splashurl设置素材读取路径 + if (window.splashurl == undefined) window.splashurl = "image/splash/"; + if (lib.config.splash_style == "style1" || lib.config.splash_style == "style2") { + ui.create + .div(node, ".avatar") + .setBackgroundImage( + "image/splash/" + lib.config.splash_style + "/" + lib.config.all.mode[i] + ".jpg" + ); + } else { + ui.create + .div(node, ".avatar") + .setBackgroundImage( + splashurl + lib.config.splash_style + "/" + lib.config.all.mode[i] + ".jpg" + ); + } + } else { + var avatarnode = ui.create.div(node, ".avatar"); + var avatarbg = lib.mode[lib.config.all.mode[i]].splash; + if (avatarbg.startsWith("ext:")) { + avatarnode.setBackgroundImage(avatarbg.replace(/^ext:/, "extension/")); + } else { + avatarnode.setBackgroundDB(avatarbg); + } + } + if (!lib.config.touchscreen) { + node.addEventListener("mousedown", downNode); + node.addEventListener("mouseup", upNode); + node.addEventListener("mouseleave", upNode); + } + setTimeout( + (function (node) { + return function () { + node.show(); + }; + })(node), + i * 100 + ); + } + if (lib.config.mousewheel) { + splash.onmousewheel = ui.click.mousewheel; + } + } else { + Reflect.set(window, "resetGameTimeout", resetGameTimeout); + proceed().then(lib.other.ignore); + } + localStorage.removeItem(lib.configprefix + "directstart"); + + const libOnload2 = lib.onload2; + delete lib.onload2; + await runCustomContents(libOnload2); +} + +async function createBackground() { + ui.background = ui.create.div(".background"); + ui.background.style.backgroundSize = "cover"; + ui.background.style.backgroundPosition = "50% 50%"; + + document.documentElement.style.backgroundImage = ""; + document.documentElement.style.backgroundSize = ""; + document.documentElement.style.backgroundPosition = ""; + document.body.insertBefore(ui.background, document.body.firstChild); + document.body.onresize = ui.updatexr; + + if (!lib.config.image_background) return; + if (lib.config.image_background === "default") return; + + let url = `url("${lib.assetURL}image/background/${lib.config.image_background}.jpg")`; + + if (lib.config.image_background.startsWith("custom_")) { + try { + const fileToLoad = await game.getDB("image", lib.config.image_background); + const fileReader = new FileReader(); + const fileLoadedEvent = await Promise((resolve) => { + fileReader.onload = resolve; + fileReader.readAsDataURL(fileToLoad, "UTF-8"); + }); + const data = fileLoadedEvent.target.result; + url = `url("${data}")`; + } catch (e) { + console.error(e); + url = "none"; + } + } + + ui.background.style.backgroundImage = url; + if (lib.config.image_background_blur) { + ui.background.style.filter = "blur(8px)"; + ui.background.style.webkitFilter = "blur(8px)"; + ui.background.style.transform = "scale(1.05)"; + } +} + +function createTouchDraggedFilter() { + document.body.addEventListener("touchstart", function (e) { + this.startX = e.touches[0].clientX / game.documentZoom; + this.startY = e.touches[0].clientY / game.documentZoom; + _status.dragged = false; + }); + document.body.addEventListener("touchmove", function (e) { + if (_status.dragged) return; + if ( + Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || + Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10 + ) { + _status.dragged = true; + } + }); +} + +/** + * @async + * @param {((function(Mutex): void) | GeneratorFunction)[]} contents + */ +function runCustomContents(contents) { + if (!Array.isArray(contents)) return; + + const mutex = new Mutex(); + + const tasks = contents + .filter((fn) => typeof fn === "function") + .map((fn) => (gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn)) // 将生成器函数转换成genCoroutin + .map((fn) => fn(mutex)); + + return Promise.allSettled(tasks).then((results) => { + results.forEach((result) => { + if (result.status === "rejected") { + console.error(result.reason); + } + }); + }); +} diff --git a/noname/init/polyfill.js b/noname/init/polyfill.js index 3dfab6e43..1f25b12d0 100644 --- a/noname/init/polyfill.js +++ b/noname/init/polyfill.js @@ -1,8 +1,8 @@ -import { Get as get } from '../get/index.js'; -import { Library as lib } from '../library/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; +import { get } from "../get/index.js"; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; // 废弃覆盖原型的HTMLDivElement.prototype.animate // 改为HTMLDivElement.prototype.addTempClass @@ -11,12 +11,11 @@ import { UI as ui } from '../ui/index.js'; * @type { typeof HTMLDivElement['prototype']['animate'] } */ HTMLDivElement.prototype.animate = function (keyframes, options) { - if (typeof keyframes == 'string') { - console.trace(this, '无名杀开发者修改的animate方法已废弃,请改为使用addTempClass方法'); + if (typeof keyframes == "string") { + console.trace(this, "无名杀开发者修改的animate方法已废弃,请改为使用addTempClass方法"); // @ts-ignore return HTMLDivElement.prototype.addTempClass.call(this, keyframes, options); - } - else return HTMLElement.prototype.animate.call(this, keyframes, options); + } else return HTMLElement.prototype.animate.call(this, keyframes, options); }; /** @@ -25,7 +24,7 @@ HTMLDivElement.prototype.animate = function (keyframes, options) { */ HTMLDivElement.prototype.addTempClass = function (name, time = 1000) { // @ts-ignore - let that = get.is.mobileMe(this) && name == 'target' ? ui.mebg : this; + let that = get.is.mobileMe(this) && name == "target" ? ui.mebg : this; that.classList.add(name); setTimeout(() => { that.classList.remove(name); @@ -37,7 +36,7 @@ HTMLDivElement.prototype.addTempClass = function (name, time = 1000) { * @type { typeof HTMLDivElement['prototype']['hide'] } */ HTMLDivElement.prototype.hide = function () { - this.classList.add('hidden'); + this.classList.add("hidden"); return this; }; /** @@ -45,7 +44,7 @@ HTMLDivElement.prototype.hide = function () { * @type { typeof HTMLDivElement['prototype']['unfocus'] } */ HTMLDivElement.prototype.unfocus = function () { - if (lib.config.transparent_dialog) this.classList.add('transparent'); + if (lib.config.transparent_dialog) this.classList.add("transparent"); return this; }; /** @@ -53,7 +52,7 @@ HTMLDivElement.prototype.unfocus = function () { * @type { typeof HTMLDivElement['prototype']['refocus'] } */ HTMLDivElement.prototype.refocus = function () { - this.classList.remove('transparent'); + this.classList.remove("transparent"); return this; }; /** @@ -61,7 +60,7 @@ HTMLDivElement.prototype.refocus = function () { * @type { typeof HTMLDivElement['prototype']['show'] } */ HTMLDivElement.prototype.show = function () { - this.classList.remove('hidden'); + this.classList.remove("hidden"); return this; }; /** @@ -74,16 +73,15 @@ HTMLDivElement.prototype.delete = function (time = 500, callback) { delete this.timeout; } if (!this._listeningEnd || this._transitionEnded) { - if (typeof time != 'number') time = 500; - this.classList.add('removing'); + if (typeof time != "number") time = 500; + this.classList.add("removing"); // @ts-ignore this.timeout = setTimeout(() => { this.remove(); - this.classList.remove('removing'); - if (typeof callback == 'function') callback(); + this.classList.remove("removing"); + if (typeof callback == "function") callback(); }, time); - } - else { + } else { this._onEndDelete = true; } return this; @@ -98,14 +96,14 @@ HTMLDivElement.prototype.goto = function (position, time) { delete this.timeout; } - if (typeof time != 'number') time = 500; - this.classList.add('removing'); + if (typeof time != "number") time = 500; + this.classList.add("removing"); // @ts-ignore this.timeout = setTimeout(() => { if (!this._selfDestroyed) { position.appendChild(this); } - this.classList.remove('removing'); + this.classList.remove("removing"); delete this.destiny; }, time); this.destiny = position; @@ -119,10 +117,10 @@ HTMLDivElement.prototype.fix = function () { clearTimeout(this.timeout); delete this.timeout; delete this.destiny; - this.classList.remove('removing'); + this.classList.remove("removing"); return this; }; -Reflect.defineProperty(HTMLDivElement.prototype, 'setBackground', { +Reflect.defineProperty(HTMLDivElement.prototype, "setBackground", { configurable: true, enumerable: false, writable: true, @@ -133,86 +131,85 @@ Reflect.defineProperty(HTMLDivElement.prototype, 'setBackground', { value: function (name, type, ext, subfolder) { if (!name) return this; let src; - if (ext == 'noskin') ext = '.jpg'; - ext = ext || '.jpg'; - subfolder = subfolder || 'default'; + if (ext == "noskin") ext = ".jpg"; + ext = ext || ".jpg"; + subfolder = subfolder || "default"; if (type) { - let dbimage = null, extimage = null, modeimage = null, nameinfo, gzbool = false; + let dbimage = null, + extimage = null, + modeimage = null, + nameinfo, + gzbool = false; const mode = get.mode(); - if (type == 'character') { + if (type == "character") { if (lib.characterPack[`mode_${mode}`] && lib.characterPack[`mode_${mode}`][name]) { - if (mode == 'guozhan') { + if (mode == "guozhan") { nameinfo = lib.character[name]; - if (name.startsWith('gz_shibing')) name = name.slice(3, 11); + if (name.startsWith("gz_shibing")) name = name.slice(3, 11); else { - if (lib.config.mode_config.guozhan.guozhanSkin && lib.character[name] && lib.character[name][4].includes('gzskin')) gzbool = true; + if ( + lib.config.mode_config.guozhan.guozhanSkin && + lib.character[name] && + lib.character[name][4].includes("gzskin") + ) + gzbool = true; name = name.slice(3); } - } - else modeimage = mode; - } - else if (name.includes('::')) { + } else modeimage = mode; + } else if (name.includes("::")) { // @ts-ignore - name = name.split('::'); + name = name.split("::"); modeimage = name[0]; name = name[1]; - } - else { + } else { nameinfo = get.character(name); } } - if (!modeimage && nameinfo && nameinfo[4]) for (const value of nameinfo[4]) { - if (value.startsWith('ext:')) { - extimage = value; - break; + if (!modeimage && nameinfo && nameinfo[4]) + for (const value of nameinfo[4]) { + if (value.startsWith("ext:")) { + extimage = value; + break; + } else if (value.startsWith("db:")) { + dbimage = value; + break; + } else if (value.startsWith("mode:")) { + modeimage = value.slice(5); + break; + } else if (value.startsWith("character:")) { + name = value.slice(10); + break; + } } - else if (value.startsWith('db:')) { - dbimage = value; - break; - } - else if (value.startsWith('mode:')) { - modeimage = value.slice(5); - break; - } - else if (value.startsWith('character:')) { - name = value.slice(10); - break; - } - } - if (extimage) src = extimage.replace(/^ext:/, 'extension/'); + if (extimage) src = extimage.replace(/^ext:/, "extension/"); else if (dbimage) { this.setBackgroundDB(dbimage.slice(3)); return this; - } - else if (modeimage) src = `image/mode/${modeimage}/character/${name}${ext}`; - else if (type == 'character' && lib.config.skin[name] && arguments[2] != 'noskin') src = `image/skin/${name}/${lib.config.skin[name]}${ext}`; - else if (type == 'character') { - src = `image/character/${gzbool ? 'gz_' : ''}${name}${ext}`; - } - else src = `image/${type}/${subfolder}/${name}${ext}`; - } - else src = `image/${name}${ext}`; - this.style.backgroundPositionX = 'center'; - this.style.backgroundSize = 'cover'; - if (type === 'character') { + } else if (modeimage) src = `image/mode/${modeimage}/character/${name}${ext}`; + else if (type == "character" && lib.config.skin[name] && arguments[2] != "noskin") + src = `image/skin/${name}/${lib.config.skin[name]}${ext}`; + else if (type == "character") { + src = `image/character/${gzbool ? "gz_" : ""}${name}${ext}`; + } else src = `image/${type}/${subfolder}/${name}${ext}`; + } else src = `image/${name}${ext}`; + this.style.backgroundPositionX = "center"; + this.style.backgroundSize = "cover"; + if (type === "character") { const nameinfo = get.character(name); - const sex = nameinfo ? nameinfo[0] : 'male'; - this.setBackgroundImage([ - src, - `${lib.characterDefaultPicturePath}${sex}${ext}` - ]); + const sex = nameinfo && ["male", "female", "double"].includes(nameinfo[0]) ? nameinfo[0] : "male"; + this.setBackgroundImage([src, `${lib.characterDefaultPicturePath}${sex}${ext}`]); } else { this.setBackgroundImage(src); } return this; - } + }, }); /** * @this HTMLDivElement * @type { typeof HTMLDivElement['prototype']['setBackgroundDB'] } */ HTMLDivElement.prototype.setBackgroundDB = function (img) { - return game.getDB('image', img).then(src => { + return game.getDB("image", img).then((src) => { this.style.backgroundImage = `url('${src}')`; this.style.backgroundSize = "cover"; return this; @@ -224,9 +221,11 @@ HTMLDivElement.prototype.setBackgroundDB = function (img) { */ HTMLDivElement.prototype.setBackgroundImage = function (img) { if (Array.isArray(img)) { - this.style.backgroundImage = img.unique().map(v => `url("${lib.assetURL}${v}")`).join(","); - } - else { + this.style.backgroundImage = img + .unique() + .map((v) => `url("${lib.assetURL}${v}")`) + .join(","); + } else { this.style.backgroundImage = `url("${lib.assetURL}${img}")`; } return this; @@ -237,25 +236,23 @@ HTMLDivElement.prototype.setBackgroundImage = function (img) { */ HTMLDivElement.prototype.listen = function (func) { if (lib.config.touchscreen) { - this.addEventListener('touchend', function (e) { + this.addEventListener("touchend", function (e) { if (!_status.dragged) func.call(this, e); }); /** * @this HTMLDivElement - * @param { MouseEvent } e + * @param { MouseEvent } e */ const fallback = function (e) { if (!_status.touchconfirmed) { func.call(this, e); + } else { + this.removeEventListener("click", fallback); } - else { - this.removeEventListener('click', fallback); - } - } - this.addEventListener('click', fallback); - } - else { - this.addEventListener('click', func); + }; + this.addEventListener("click", fallback); + } else { + this.addEventListener("click", func); } return this; }; @@ -271,10 +268,10 @@ HTMLDivElement.prototype.listenTransition = function (func, time) { func.call(this); } clearTimeout(timer); - this.removeEventListener('webkitTransitionEnd', callback); + this.removeEventListener("webkitTransitionEnd", callback); }; const timer = setTimeout(callback, time || 1000); - this.addEventListener('webkitTransitionEnd', callback); + this.addEventListener("webkitTransitionEnd", callback); // @ts-ignore return timer; }; @@ -287,19 +284,17 @@ HTMLDivElement.prototype.setPosition = function () { if (arguments.length == 4) { position = []; for (var i = 0; i < arguments.length; i++) position.push(arguments[i]); - } - else if (arguments.length == 1 && Array.isArray(arguments[0]) && arguments[0].length == 4) { + } else if (arguments.length == 1 && Array.isArray(arguments[0]) && arguments[0].length == 4) { position = arguments[0]; - } - else { + } else { return this; } - var top = 'calc(' + position[0] + '% '; - if (position[1] > 0) top += '+ ' + position[1] + 'px)'; - else top += '- ' + Math.abs(position[1]) + 'px)'; - var left = 'calc(' + position[2] + '% '; - if (position[3] > 0) left += '+ ' + position[3] + 'px)'; - else left += '- ' + Math.abs(position[3]) + 'px)'; + var top = "calc(" + position[0] + "% "; + if (position[1] > 0) top += "+ " + position[1] + "px)"; + else top += "- " + Math.abs(position[1]) + "px)"; + var left = "calc(" + position[2] + "% "; + if (position[3] > 0) left += "+ " + position[3] + "px)"; + else left += "- " + Math.abs(position[3]) + "px)"; this.style.top = top; this.style.left = left; return this; @@ -310,10 +305,9 @@ HTMLDivElement.prototype.setPosition = function () { */ HTMLDivElement.prototype.css = function (style) { for (var i in style) { - if (i == 'innerHTML' && typeof style['innerHTML'] == 'string') { - this.innerHTML = style['innerHTML']; - } - else { + if (i == "innerHTML" && typeof style["innerHTML"] == "string") { + this.innerHTML = style["innerHTML"]; + } else { this.style[i] = style[i]; } } @@ -335,41 +329,41 @@ HTMLTableElement.prototype.get = function (row, col) { * @type { typeof Map['prototype']['contains'] } */ const mapHasFunc = function (item) { - console.trace(this, '已经从array改为map,请改为使用has方法'); + console.trace(this, "已经从array改为map,请改为使用has方法"); return this.has(item); -} +}; Object.defineProperty(Map.prototype, "contains", { configurable: true, enumerable: false, writable: true, - value: mapHasFunc + value: mapHasFunc, }); Object.defineProperty(Map.prototype, "includes", { configurable: true, enumerable: false, writable: true, - value: mapHasFunc + value: mapHasFunc, }); /** * @this Map * @type { typeof Map['prototype']['add'] } */ const mapAddFunc = function (item) { - console.trace(this, '已经从array改为map,请改为使用set方法'); + console.trace(this, "已经从array改为map,请改为使用set方法"); this.set(item, 0); return this; -} +}; Object.defineProperty(Map.prototype, "add", { configurable: true, enumerable: false, writable: true, - value: mapAddFunc + value: mapAddFunc, }); Object.defineProperty(Map.prototype, "push", { configurable: true, enumerable: false, writable: true, - value: mapAddFunc + value: mapAddFunc, }); Object.defineProperty(Map.prototype, "addArray", { configurable: true, @@ -384,7 +378,7 @@ Object.defineProperty(Map.prototype, "addArray", { this.add(arr[i]); } return this; - } + }, }); Object.defineProperty(Map.prototype, "remove", { configurable: true, @@ -395,10 +389,10 @@ Object.defineProperty(Map.prototype, "remove", { * @type { typeof Map['prototype']['remove'] } */ value: function (item) { - console.trace(this, '已经从array改为map,请改为使用delete方法'); + console.trace(this, "已经从array改为map,请改为使用delete方法"); this.delete(item); return this; - } + }, }); /*Map prototype end*/ Object.defineProperty(Array.prototype, "filterInD", { @@ -409,11 +403,11 @@ Object.defineProperty(Array.prototype, "filterInD", { * @this any[] * @type { typeof Array['prototype']['filterInD'] } */ - value: function (pos = 'o') { - if (typeof pos != 'string') pos = 'o'; + value: function (pos = "o") { + if (typeof pos != "string") pos = "o"; // @ts-ignore - return this.filter(card => pos.includes(get.position(card, true))); - } + return this.filter((card) => pos.includes(get.position(card, true))); + }, }); Object.defineProperty(Array.prototype, "someInD", { configurable: true, @@ -423,11 +417,11 @@ Object.defineProperty(Array.prototype, "someInD", { * @this any[] * @type { typeof Array['prototype']['someInD'] } */ - value: function (pos = 'o') { - if (typeof pos != 'string') pos = 'o'; + value: function (pos = "o") { + if (typeof pos != "string") pos = "o"; // @ts-ignore - return this.some(card => pos.includes(get.position(card, true))); - } + return this.some((card) => pos.includes(get.position(card, true))); + }, }); Object.defineProperty(Array.prototype, "everyInD", { configurable: true, @@ -437,14 +431,14 @@ Object.defineProperty(Array.prototype, "everyInD", { * @this any[] * @type { typeof Array['prototype']['everyInD'] } */ - value: function (pos = 'o') { - if (typeof pos != 'string') pos = 'o'; + value: function (pos = "o") { + if (typeof pos != "string") pos = "o"; // @ts-ignore - return this.every(card => pos.includes(get.position(card, true))); - } + return this.every((card) => pos.includes(get.position(card, true))); + }, }); /** -*@legacy Use {@link Array#includes} instead. + *@legacy Use {@link Array#includes} instead. */ Object.defineProperty(Array.prototype, "contains", { configurable: true, @@ -455,9 +449,9 @@ Object.defineProperty(Array.prototype, "contains", { * @type { typeof Array['prototype']['contains'] } */ value: function (...args) { - console.warn(this, 'Array的contains方法已废弃,请使用includes方法'); + console.warn(this, "Array的contains方法已废弃,请使用includes方法"); return this.includes(...args); - } + }, }); Object.defineProperty(Array.prototype, "containsSome", { configurable: true, @@ -468,8 +462,8 @@ Object.defineProperty(Array.prototype, "containsSome", { * @type { typeof Array['prototype']['containsSome'] } */ value: function () { - return Array.from(arguments).some(i => this.includes(i)); - } + return Array.from(arguments).some((i) => this.includes(i)); + }, }); Object.defineProperty(Array.prototype, "containsAll", { configurable: true, @@ -480,8 +474,8 @@ Object.defineProperty(Array.prototype, "containsAll", { * @type { typeof Array['prototype']['containsAll'] } */ value: function () { - return Array.from(arguments).every(i => this.includes(i)); - } + return Array.from(arguments).every((i) => this.includes(i)); + }, }); Object.defineProperty(Array.prototype, "add", { @@ -498,7 +492,7 @@ Object.defineProperty(Array.prototype, "add", { this.push(arg); } return this; - } + }, }); Object.defineProperty(Array.prototype, "addArray", { configurable: true, @@ -513,7 +507,7 @@ Object.defineProperty(Array.prototype, "addArray", { for (const item of arr) this.add(item); } return this; - } + }, }); Object.defineProperty(Array.prototype, "remove", { configurable: true, @@ -526,8 +520,8 @@ Object.defineProperty(Array.prototype, "remove", { value: function () { for (const item of arguments) { let pos = -1; - if (typeof item == 'number' && isNaN(item)) { - pos = this.findIndex(v => isNaN(v)) + if (typeof item == "number" && isNaN(item)) { + pos = this.findIndex((v) => isNaN(v)); } else { pos = this.indexOf(item); } @@ -535,7 +529,7 @@ Object.defineProperty(Array.prototype, "remove", { this.splice(pos, 1); } return this; - } + }, }); Object.defineProperty(Array.prototype, "removeArray", { configurable: true, @@ -549,7 +543,7 @@ Object.defineProperty(Array.prototype, "removeArray", { // @ts-ignore for (const i of Array.from(arguments)) this.remove(...i); return this; - } + }, }); Object.defineProperty(Array.prototype, "unique", { configurable: true, @@ -564,7 +558,7 @@ Object.defineProperty(Array.prototype, "unique", { this.length = uniqueArray.length; for (let i = 0; i < uniqueArray.length; i++) this[i] = uniqueArray[i]; return this; - } + }, }); Object.defineProperty(Array.prototype, "toUniqued", { configurable: true, @@ -576,7 +570,7 @@ Object.defineProperty(Array.prototype, "toUniqued", { */ value: function () { return [...new Set(this)]; - } + }, }); Object.defineProperty(Array.prototype, "randomGet", { configurable: true, @@ -590,7 +584,7 @@ Object.defineProperty(Array.prototype, "randomGet", { let arr = this.slice(0); arr.removeArray(Array.from(arguments)); return arr[Math.floor(Math.random() * arr.length)]; - } + }, }); Object.defineProperty(Array.prototype, "randomGets", { configurable: true, @@ -608,7 +602,7 @@ Object.defineProperty(Array.prototype, "randomGets", { list.push(arr.splice(Math.floor(Math.random() * arr.length), 1)[0]); } return list; - } + }, }); Object.defineProperty(Array.prototype, "randomRemove", { configurable: true, @@ -619,7 +613,7 @@ Object.defineProperty(Array.prototype, "randomRemove", { * @type { typeof Array['prototype']['randomRemove'] } */ value: function (num) { - if (typeof num == 'number') { + if (typeof num == "number") { let list = []; for (let i = 0; i < num; i++) { if (!this.length) break; @@ -628,7 +622,7 @@ Object.defineProperty(Array.prototype, "randomRemove", { return list; } return this.splice(Math.floor(Math.random() * this.length), 1)[0]; - } + }, }); Object.defineProperty(Array.prototype, "randomSort", { configurable: true, @@ -647,7 +641,7 @@ Object.defineProperty(Array.prototype, "randomSort", { this.push(list[i]); } return this; - } + }, }); Object.defineProperty(Array.prototype, "sortBySeat", { configurable: true, @@ -662,10 +656,10 @@ Object.defineProperty(Array.prototype, "sortBySeat", { this.sort(lib.sort.seat); delete lib.tempSortSeat; return this; - } + }, }); /** -*@description 从数组中寻找某个特征最大的,且通过筛选的第一个元素 + *@description 从数组中寻找某个特征最大的,且通过筛选的第一个元素 */ Object.defineProperty(Array.prototype, "maxBy", { configurable: true, @@ -677,10 +671,10 @@ Object.defineProperty(Array.prototype, "maxBy", { */ value: function (sortBy, filter) { let list = this.filter(filter || (() => true)); - if (sortBy && typeof sortBy == 'function') list.sort((a, b) => sortBy(a) - sortBy(b)); + 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, @@ -692,8 +686,8 @@ Object.defineProperty(Array.prototype, "minBy", { */ value: function (sortBy, filter) { let list = this.filter(filter || (() => true)); - if (sortBy && typeof sortBy == 'function') list.sort((a, b) => sortBy(a) - sortBy(b)); + if (sortBy && typeof sortBy == "function") list.sort((a, b) => sortBy(a) - sortBy(b)); else list.sort(); return list[0]; - } + }, }); diff --git a/noname/library/announce/index.d.ts b/noname/library/announce/index.d.ts index 8e4af684b..419e96a8a 100644 --- a/noname/library/announce/index.d.ts +++ b/noname/library/announce/index.d.ts @@ -1,10 +1,10 @@ -import { NonameAnnounceType } from "./interface.d.ts" +import { NonameAnnounceType } from "./interface.d.ts"; export interface IAnnounceSubscriber { subscribe(name: string): void; unsubscribe(name: string): void; - get isEmpty(): boolean + get isEmpty(): boolean; } export type AnnounceSubscriberType = new ( @@ -13,7 +13,11 @@ export type AnnounceSubscriberType = new ( ) => IAnnounceSubscriber; export class Announce { - constructor(eventTarget: EventTarget, records: WeakMap<((arg0: any) => void), IAnnounceSubscriber>, SubscriberType: AnnounceSubscriberType = AnnounceSubscriber) + constructor( + eventTarget: EventTarget, + records: WeakMap<(arg0: any) => void, IAnnounceSubscriber>, + SubscriberType: AnnounceSubscriberType = AnnounceSubscriber + ); /** * 推送任意数据给所有监听了指定事件的订阅者,并返回给定的数据 @@ -23,7 +27,10 @@ export class Announce { * @param name - 要推送事件的名称 * @param values - 要推送的数据 */ - publish(name: Name, values: Parameters[0]): Parameters[0] + publish( + name: Name, + values: Parameters[0] + ): Parameters[0]; /** * 订阅给定名字的事件,并返回给定的函数 @@ -35,7 +42,10 @@ export class Announce { * @param name - 要订阅事件的名称 * @param method - 事件触发时执行的函数 */ - subscribe(name: Name, method: Type[Name]): Type[Name] + subscribe( + name: Name, + method: Type[Name] + ): Type[Name]; /** * 取消指定事件某一个函数的订阅,并返回该函数 @@ -45,9 +55,12 @@ export class Announce { * @param name - 要取消订阅事件的名称 * @param method - 订阅指定事件的函数 */ - unsubscribe(name: Name, method: Type[Name]): Type[Name] + unsubscribe( + name: Name, + method: Type[Name] + ): Type[Name]; } export class AnnounceSubscriber implements IAnnounceSubscriber { - constructor(content: (value: T, name: string) => void, target: EventTarget) + constructor(content: (value: T, name: string) => void, target: EventTarget); } diff --git a/noname/library/announce/index.js b/noname/library/announce/index.js index 348f4fa61..34ebd592e 100644 --- a/noname/library/announce/index.js +++ b/noname/library/announce/index.js @@ -55,9 +55,11 @@ export class Announce { * @returns {T} */ publish(name, values) { - this.#eventTarget.dispatchEvent(new CustomEvent(name, { - detail: [values, name] - })); + this.#eventTarget.dispatchEvent( + new CustomEvent(name, { + detail: [values, name], + }) + ); return values; } @@ -75,13 +77,12 @@ export class Announce { */ subscribe(name, method) { let subscriber; - if (this.#records.has(method)) - subscriber = this.#records.get(method); + if (this.#records.has(method)) subscriber = this.#records.get(method); else { subscriber = new this.#SubscriberType(method, this.#eventTarget); this.#records.set(method, subscriber); } - if (!subscriber) throw new Error() + if (!subscriber) throw new Error(); subscriber.subscribe(name); return method; } @@ -99,10 +100,9 @@ export class Announce { unsubscribe(name, method) { if (this.#records.has(method)) { const subscriber = this.#records.get(method); - if (!subscriber) throw new Error() + if (!subscriber) throw new Error(); subscriber.unsubscribe(name); - if (subscriber.isEmpty) - this.#records.delete(method); + if (subscriber.isEmpty) this.#records.delete(method); } return method; } @@ -120,7 +120,7 @@ export class AnnounceSubscriber { /** * @type {string[]} */ - #listening + #listening; /** * @@ -130,7 +130,7 @@ export class AnnounceSubscriber { constructor(content, target) { this.#content = function (event) { content(event.detail[0], event.detail[1]); - } + }; this.#listening = []; vm.set(this, target); diff --git a/noname/library/announce/interface.d.ts b/noname/library/announce/interface.d.ts index 329a6be84..cd5719c05 100644 --- a/noname/library/announce/interface.d.ts +++ b/noname/library/announce/interface.d.ts @@ -1,54 +1,50 @@ - export interface NonameAnnounceType { - // Apperaence 外观区域 - // 用于关于无名杀外观方面的通知 + // Apperaence 外观区域 + // 用于关于无名杀外观方面的通知 - // Apperaence.Theme 无名杀主题区域 - /** - * 主题正在被切换时通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChanging": AnnounceFunction + // Apperaence.Theme 无名杀主题区域 + /** + * 主题正在被切换时通知 + * + * @param values - 主题名称 + */ + "Noname.Apperaence.Theme.onChanging": AnnounceFunction; - /** - * 主题被切换时通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChanged": AnnounceFunction + /** + * 主题被切换时通知 + * + * @param values - 主题名称 + */ + "Noname.Apperaence.Theme.onChanged": AnnounceFunction; - /** - * 主题被切换时,已经显示完毕后通知 - * - * @param values - 主题名称 - */ - "Noname.Apperaence.Theme.onChangeFinished": AnnounceFunction + /** + * 主题被切换时,已经显示完毕后通知 + * + * @param values - 主题名称 + */ + "Noname.Apperaence.Theme.onChangeFinished": AnnounceFunction; - // Game 游戏区域 - // 包含游戏对局下的通知 + // Game 游戏区域 + // 包含游戏对局下的通知 - // Game.Event 事件区域 - /** - * 当游戏对局开始时进行通知 - * - * @param values - 空对象 - */ - "Noname.Game.Event.GameStart": AnnounceFunction<{}> - - - // Init 初始化区域 - // 用于关于初始化方面的通知 - - // Init.Extension 扩展初始化区域 - /** - * 当扩展初始化完成时通知 - * - * @param values - 扩展名称 - */ - "Noname.Init.Extension.onLoad": AnnounceFunction + // Game.Event 事件区域 + /** + * 当游戏对局开始时进行通知 + * + * @param values - 空对象 + */ + "Noname.Game.Event.GameStart": AnnounceFunction<{}>; + // Init 初始化区域 + // 用于关于初始化方面的通知 + // Init.Extension 扩展初始化区域 + /** + * 当扩展初始化完成时通知 + * + * @param values - 扩展名称 + */ + "Noname.Init.Extension.onLoad": AnnounceFunction; } -export type AnnounceFunction = (values: T) => void +export type AnnounceFunction = (values: T) => void; diff --git a/noname/library/assembly/buildin.js b/noname/library/assembly/buildin.js index 4c629547e..a43051359 100644 --- a/noname/library/assembly/buildin.js +++ b/noname/library/assembly/buildin.js @@ -1,24 +1,24 @@ -import { lib } from "../index.js" -import { ui } from "../../ui/index.js" -import { get } from "../../get/index.js" -import { _status } from "../../status/index.js" +import { lib } from "../index.js"; +import { ui } from "../../ui/index.js"; +import { get } from "../../get/index.js"; +import { _status } from "../../status/index.js"; /** * @type {(import("./interface.js").NonameAssemblyType["checkBegin"])} */ -export const checkBegin = {} +export const checkBegin = {}; /** * @type {(import("./interface.js").NonameAssemblyType["checkCard"])} */ export const checkCard = { updateTempname(card, event) { - if (lib.config.cardtempname === 'off') return - if (get.name(card) === card.name && get.is.sameNature(get.nature(card), card.nature, true)) return - const node = ui.create.cardTempName(card) - if (lib.config.cardtempname !== 'default') node.classList.remove('vertical') - } -} + if (lib.config.cardtempname === "off") return; + if (get.name(card) === card.name && get.is.sameNature(get.nature(card), card.nature, true)) return; + const node = ui.create.cardTempName(card); + if (lib.config.cardtempname !== "default") node.classList.remove("vertical"); + }, +}; /** * @type {(import("./interface.js").NonameAssemblyType["checkTarget"])} @@ -27,48 +27,52 @@ export const checkTarget = { updateInstance(target, event) { // @ts-ignore if (!target.instance) return; - ['selected', 'selectable'].forEach(className => { + ["selected", "selectable"].forEach((className) => { if (target.classList.contains(className)) { // @ts-ignore - target.instance.classList.add(className) + target.instance.classList.add(className); } else { // @ts-ignore - target.instance.classList.remove(className) + target.instance.classList.remove(className); } - }) - } -} + }); + }, +}; /** * @type {(import("./interface.js").NonameAssemblyType["checkButton"])} */ -export const checkButton = {} +export const checkButton = {}; /** * @type {(import("./interface.js").NonameAssemblyType["checkEnd"])} */ export const checkEnd = { autoConfirm(event, { ok, auto, autoConfirm }) { - if (!event.isMine()) return - const skillinfo = get.info(event.skill) || {} - if (ok && auto && (autoConfirm || skillinfo.direct) && !_status.touchnocheck - && !_status.mousedown && (!_status.mousedragging || !_status.mouseleft)) { - if (ui.confirm) ui.confirm.close() + if (!event.isMine()) return; + const skillinfo = get.info(event.skill) || {}; + if ( + ok && + auto && + (autoConfirm || skillinfo.direct) && + !_status.touchnocheck && + !_status.mousedown && + (!_status.mousedragging || !_status.mouseleft) + ) { + if (ui.confirm) ui.confirm.close(); // @ts-ignore - if (event.skillDialog === true) event.skillDialog = false - ui.click.ok() - _status.mousedragging = null - if (skillinfo.preservecancel) ui.create.confirm('c') + if (event.skillDialog === true) event.skillDialog = false; + ui.click.ok(); + _status.mousedragging = null; + if (skillinfo.preservecancel) ui.create.confirm("c"); } - } -} - - + }, +}; /** * @type {(import("./interface.js").NonameAssemblyType["uncheckBegin"])} */ -export const uncheckBegin = {} +export const uncheckBegin = {}; /** * @type {(import("./interface.js").NonameAssemblyType["uncheckCard"])} @@ -76,13 +80,13 @@ export const uncheckBegin = {} export const uncheckCard = { removeTempname(card, event) { // @ts-ignore - if (!card._tempName) return + if (!card._tempName) return; // @ts-ignore - card._tempName.delete() + card._tempName.delete(); // @ts-ignore - delete card._tempName - } -} + delete card._tempName; + }, +}; /** * @type {(import("./interface.js").NonameAssemblyType["uncheckTarget"])} @@ -90,21 +94,20 @@ export const uncheckCard = { export const uncheckTarget = { removeInstance(target, event) { // @ts-ignore - if (!target.instance) return + if (!target.instance) return; // @ts-ignore - target.instance.classList.remove('selected') + target.instance.classList.remove("selected"); // @ts-ignore - target.instance.classList.remove('selectable') - } -} + target.instance.classList.remove("selectable"); + }, +}; /** * @type {(import("./interface.js").NonameAssemblyType["uncheckButton"])} */ -export const uncheckButton = {} - +export const uncheckButton = {}; /** * @type {(import("./interface.js").NonameAssemblyType["uncheckEnd"])} */ -export const uncheckEnd = {} +export const uncheckEnd = {}; diff --git a/noname/library/assembly/index.js b/noname/library/assembly/index.js index 391ab4845..3fe0a1783 100644 --- a/noname/library/assembly/index.js +++ b/noname/library/assembly/index.js @@ -1,8 +1,8 @@ -import * as buildin from "./buildin.js" +import * as buildin from "./buildin.js"; /** * > 这玩意因为狂神还得是数组 - * + * * @template {import("./interface.d.ts").NonameAssemblyType} AssemblyType * @template {keyof AssemblyType} Name * @extends {Array} @@ -11,42 +11,42 @@ export class NonameAssembly extends Array { /** * @type {Name} */ - #name + #name; /** * @type {Map} */ - #record + #record; /** - * - * @param {Name} name + * + * @param {Name} name */ constructor(name) { - super() - this.#name = name - this.#record = new Map() + super(); + this.#name = name; + this.#record = new Map(); if (name in buildin) { // @ts-ignore for (const [key, item] of Object.entries(buildin[name])) { // @ts-ignore - this.add(key, item) + this.add(key, item); } } } static get [Symbol.species]() { - return Array + return Array; } get name() { - return this.#name + return this.#name; } /** - * - * @param {keyof AssemblyType[Name]} name + * + * @param {keyof AssemblyType[Name]} name * @param {AssemblyType[Name][keyof AssemblyType[Name]]} content * @override */ @@ -54,71 +54,70 @@ export class NonameAssembly extends Array { add(name, content) { if (!content) { // @ts-expect-error A - content = name + content = name; // @ts-expect-error A - name = content.name + name = content.name; } - if (typeof content !== "function") throw new Error("you can't add a non-function to assembly.") + if (typeof content !== "function") throw new Error("you can't add a non-function to assembly."); // if (typeof name !== "string" || name.length === 0) throw new Error("you can't add a anonymous function to assembly.") if (typeof name !== "string" || name.length === 0) { - if (!this.includes(content)) Array.prototype.push.call(this, content) - } - else if (!this.has(name)) { - this.#record.set(name, this.length) - Array.prototype.push.call(this, content) + if (!this.includes(content)) Array.prototype.push.call(this, content); + } else if (!this.has(name)) { + this.#record.set(name, this.length); + Array.prototype.push.call(this, content); } - return this + return this; } /** - * - * @param {keyof AssemblyType[Name]} name + * + * @param {keyof AssemblyType[Name]} name * @param {AssemblyType[Name][keyof AssemblyType[Name]]} content * @override */ // @ts-ignore push(name, content) { - return this.add(name, content).length + return this.add(name, content).length; } /** - * - * @param {keyof AssemblyType[Name]} name + * + * @param {keyof AssemblyType[Name]} name */ has(name) { - return this.#record.has(name) + return this.#record.has(name); } /** - * - * @param {keyof AssemblyType[Name]} name + * + * @param {keyof AssemblyType[Name]} name * @returns {AssemblyType[Name][keyof AssemblyType[Name]] | undefined} */ get(name) { - if (!this.has(name)) return void 0 + if (!this.has(name)) return void 0; // @ts-ignore - return this[this.#record.get(name)] + return this[this.#record.get(name)]; } /** - * - * @param {keyof AssemblyType[Name]} name + * + * @param {keyof AssemblyType[Name]} name * @param {AssemblyType[Name][keyof AssemblyType[Name]]} content */ update(name, content) { - if (!this.has(name)) return false + if (!this.has(name)) return false; try { // @ts-ignore - this[this.#record.get(name)] = content + this[this.#record.get(name)] = content; } catch (e) { - console.error(e) - return false + console.error(e); + return false; } - return true + return true; } } @@ -133,9 +132,9 @@ export const defaultHookcompatition = { uncheckCard: new NonameAssembly("uncheckCard"), uncheckTarget: new NonameAssembly("uncheckTarget"), uncheckButton: new NonameAssembly("uncheckButton"), - uncheckEnd: new NonameAssembly("uncheckEnd") -} + uncheckEnd: new NonameAssembly("uncheckEnd"), +}; export const defaultAssemblys = { - ...defaultHookcompatition -} + ...defaultHookcompatition, +}; diff --git a/noname/library/assembly/interface.d.ts b/noname/library/assembly/interface.d.ts index 1407a1c28..c9978edfb 100644 --- a/noname/library/assembly/interface.d.ts +++ b/noname/library/assembly/interface.d.ts @@ -1,58 +1,61 @@ -import { Button, Card, GameEvent, GameEventPromise, Player } from "../element" +import { Button, Card, GameEvent, GameEventPromise, Player } from "../element"; export interface NonameAssemblyType { - checkBegin: {} + checkBegin: {}; checkCard: { /** - * + * * @param card - 检查的卡牌 * @param event - 当前检查的事件 */ - updateTempname(card: Card, event: GameEvent & GameEventPromise): void - } + updateTempname(card: Card, event: GameEvent & GameEventPromise): void; + }; checkTarget: { /** - * + * * @param target - 检查的玩家 * @param event - 当前检查的事件 */ - updateInstance(target: Player, event: GameEvent & GameEventPromise): void - } + updateInstance(target: Player, event: GameEvent & GameEventPromise): void; + }; - checkButton: {} + checkButton: {}; checkEnd: { /** - * + * * @param event - 当前检查的事件 * @param config - 一些配置 */ - autoConfirm(event: GameEvent & GameEventPromise, config: { ok: boolean, auto: boolean, autoConfirm: boolean }): void - } + autoConfirm( + event: GameEvent & GameEventPromise, + config: { ok: boolean; auto: boolean; autoConfirm: boolean } + ): void; + }; - uncheckBegin: {} + uncheckBegin: {}; uncheckCard: { /** - * + * * @param card - 取消检查的卡牌 * @param event - 当前检查的事件 */ - removeTempname(card: Card, event: GameEvent & GameEventPromise): void - } + removeTempname(card: Card, event: GameEvent & GameEventPromise): void; + }; uncheckTarget: { /** - * + * * @param target - 取消检查的玩家 * @param event - 当前检查的事件 */ - removeInstance(target: Player, event: GameEvent & GameEventPromise): void - } + removeInstance(target: Player, event: GameEvent & GameEventPromise): void; + }; - uncheckButton: {} + uncheckButton: {}; - uncheckEnd: {} + uncheckEnd: {}; } diff --git a/noname/library/cache/cacheContext.js b/noname/library/cache/cacheContext.js index 18d6b3e81..479d90b7b 100644 --- a/noname/library/cache/cacheContext.js +++ b/noname/library/cache/cacheContext.js @@ -1,202 +1,215 @@ -import { Library } from "../index.js"; -import { Game } from "../../game/index.js"; -import { Get } from "../../get/index.js"; -import { status as _status } from "../../status/index.js"; +import { lib } from "../index.js"; +import { game } from "../../game/index.js"; +import { get } from "../../get/index.js"; +import { _status } from "../../status/index.js"; import { hex_md5 } from "../crypt/md5.js"; /** * 缓存上下文,用于在各种方法中暂时缓存值,以第一次获取的缓存值为准。 */ -export class CacheContext{ - - constructor(){ - this.lib = this._createCacheProxy(Library); - this.game = this._createCacheProxy(Game); - this.get = this._createCacheProxy(Get); - this.sourceMap = new Map(); - this.storageMap = new Map(); - } +export class CacheContext { + constructor() { + this.lib = this._createCacheProxy(lib); + this.game = this._createCacheProxy(game); + this.get = this._createCacheProxy(get); + this.sourceMap = new Map(); + this.storageMap = new Map(); + } - /** - * 设置当前是否处于缓存环境。当使用inject对类进行注入时,只在缓存环境下会返回缓存值。 - * @param {boolean} cache - */ - static setInCacheEnvironment(cache){ - _status.cacheEnvironment = cache; - } + /** + * 设置当前是否处于缓存环境。当使用inject对类进行注入时,只在缓存环境下会返回缓存值。 + * @param {boolean} cache + */ + static setInCacheEnvironment(cache) { + _status.cacheEnvironment = cache; + } - /** - * 设置一个公有的缓存上下文。缓存上下文持有期间,假设所缓存的函数在参数相同时,绝对不会(注意是绝对不会)返回不同的返回值。 - * 使用inject对类进行注入时,将应用公有的缓存上下文。 - * @param {CacheContext} context - */ - static setCacheContext(context){ - _status.cacheContext = context; - } + /** + * 设置一个公有的缓存上下文。缓存上下文持有期间,假设所缓存的函数在参数相同时,绝对不会(注意是绝对不会)返回不同的返回值。 + * 使用inject对类进行注入时,将应用公有的缓存上下文。 + * @param {CacheContext} context + */ + static setCacheContext(context) { + _status.cacheContext = context; + } - /** - * 返回当前公有的缓存上下文。 - * @returns {CacheContext} 缓存上下文 - */ - static getCacheContext(){ - return _status.cacheContext; - } + /** + * 返回当前公有的缓存上下文。 + * @returns {CacheContext} 缓存上下文 + */ + static getCacheContext() { + return _status.cacheContext; + } - /** - * 移除当前公有的缓存上下文。 - */ - static removeCacheContext(){ - delete _status.cacheContext; - } + /** + * 移除当前公有的缓存上下文。 + */ + static removeCacheContext() { + delete _status.cacheContext; + } - /** - * 返回公有的缓存上下文,没有就创建一个新的返回(不会设置为新的公有缓存上下文)。 - * @returns {CacheContext} 缓存上下文 - */ - static requireCacheContext(){ - let cache = CacheContext.getCacheContext(); - if(!cache){ - return new CacheContext(); - } - return cache; - } + /** + * 返回公有的缓存上下文,没有就创建一个新的返回(不会设置为新的公有缓存上下文)。 + * @returns {CacheContext} 缓存上下文 + */ + static requireCacheContext() { + let cache = CacheContext.getCacheContext(); + if (!cache) { + return new CacheContext(); + } + return cache; + } - /** - * 对一个对象进行代理,对象的所有函数都将按条件返回缓存结果。 - * 注意:以cache开头的方法依然保持原来的调用。 - * 如果所代理的对象拥有cacheSupportFunction方法(返回一个方法名数组),只有允许的方法才会返回缓存结果,剩余方法依然保持原来的调用。 - * @param {any} source 需要代理的对象 - * @returns - */ - delegate(source){ - if(source === null || source === undefined)return source; - if(source._cacheDelegateSource)return source; - let proxy = this.sourceMap.get(source); - if(proxy){ - return proxy; - } - proxy = this._createCacheProxy(source); - this.sourceMap.set(source,proxy); - return proxy; - } + /** + * 对一个对象进行代理,对象的所有函数都将按条件返回缓存结果。 + * 注意:以cache开头的方法依然保持原来的调用。 + * 如果所代理的对象拥有cacheSupportFunction方法(返回一个方法名数组),只有允许的方法才会返回缓存结果,剩余方法依然保持原来的调用。 + * @param {any} source 需要代理的对象 + * @returns + */ + delegate(source) { + if (source === null || source === undefined) return source; + if (source._cacheDelegateSource) return source; + let proxy = this.sourceMap.get(source); + if (proxy) { + return proxy; + } + proxy = this._createCacheProxy(source); + this.sourceMap.set(source, proxy); + return proxy; + } - /** - * 对一个类进行注入。methods为可以返回缓存的所有方法。注入后,此类的相关方法会在公有缓存上下文下返回缓存值。 - * @param {any} source - * @param {Array} methods - * @returns - */ - static inject(source,methods){ - if(source == null || source === undefined)return null; - for(let method of methods){ - let func = source[method]; - if(typeof func != 'function')continue; - source[method] = function(){ - try{ - if(!_status.cacheEnvironment){ - return func.call(this,...arguments); - } - return CacheContext - ._getCacheValueFromObject(CacheContext.requireCacheContext()._requireStorage(this),method,arguments,this,func); - }catch(e){ - return func.call(this,...arguments); - } - } - } - } + /** + * 对一个类进行注入。methods为可以返回缓存的所有方法。注入后,此类的相关方法会在公有缓存上下文下返回缓存值。 + * @param {any} source + * @param {Array} methods + * @returns + */ + static inject(source, methods) { + if (source == null || source === undefined) return null; + for (let method of methods) { + let func = source[method]; + if (typeof func != "function") continue; + source[method] = function () { + try { + if (!_status.cacheEnvironment) { + return func.call(this, ...arguments); + } + return CacheContext._getCacheValueFromObject( + CacheContext.requireCacheContext()._requireStorage(this), + method, + arguments, + this, + func + ); + } catch (e) { + return func.call(this, ...arguments); + } + }; + } + } - _requireStorage(obj){ - let storage = this.storageMap.get(obj); - if(!storage){ - storage = {}; - this.storageMap.set(obj,storage); - } - return storage; - } + _requireStorage(obj) { + let storage = this.storageMap.get(obj); + if (!storage) { + storage = {}; + this.storageMap.set(obj, storage); + } + return storage; + } - /** - * @template T - * @param {T} delegateObject - * @returns {T} - */ - _createCacheProxy(delegateObject){ - const cacheFuncObj = {}; - const cacheStorage = {}; - return new Proxy(delegateObject,{ - get:(target,key)=>{ - if(key == '_cacheDelegateSource')return delegateObject; - let value = target[key]; - if(key.indexOf('cache') == 0){ - return value; - } - if(typeof target.cacheSupportFunction == 'function'){ - if(!target.cacheSupportFunction().includes(key)){ - return value; - } - } - if(typeof value == 'function'){ - let wrapFunc = cacheFuncObj[key]; - if(typeof wrapFunc != 'function'){ - wrapFunc = function(){ - try{ - return CacheContext - ._getCacheValueFromObject(cacheStorage,key,arguments,target); - }catch(e){ - return value.call(target,...arguments); - } - }; - cacheFuncObj[key] = wrapFunc; - } - return wrapFunc; - } - return value; - } - }); - } + /** + * @template T + * @param {T} delegateObject + * @returns {T} + */ + _createCacheProxy(delegateObject) { + const cacheFuncObj = {}; + const cacheStorage = {}; + return new Proxy(delegateObject, { + get: (target, key) => { + if (key == "_cacheDelegateSource") return delegateObject; + let value = target[key]; + if (key.indexOf("cache") == 0) { + return value; + } + if (typeof target.cacheSupportFunction == "function") { + if (!target.cacheSupportFunction().includes(key)) { + return value; + } + } + if (typeof value == "function") { + let wrapFunc = cacheFuncObj[key]; + if (typeof wrapFunc != "function") { + wrapFunc = function () { + try { + return CacheContext._getCacheValueFromObject( + cacheStorage, + key, + arguments, + target + ); + } catch (e) { + return value.call(target, ...arguments); + } + }; + cacheFuncObj[key] = wrapFunc; + } + return wrapFunc; + } + return value; + }, + }); + } - static _getCacheValueFromObject(storage,key,params,source,func){ - let cache = storage; - let funcCache = CacheContext._ensureMember(cache,key); - let cacheKey = CacheContext._wrapParametersToCacheKey(params); - let ret = funcCache[cacheKey]; - if(ret === undefined){ - ret = ((typeof func == 'function')?func:source[key]).call(source,...params); - funcCache[cacheKey] = ret; - //console.log('缓存未命中!'+key+":"+cacheKey+":"+params.length+":ret:"+ret); - }else{ - //console.log(key+":"+cacheKey+":"+params.length+":ret:"+ret); - } - return ret; - } + static _getCacheValueFromObject(storage, key, params, source, func) { + let cache = storage; + let funcCache = CacheContext._ensureMember(cache, key); + let cacheKey = CacheContext._wrapParametersToCacheKey(params); + let ret = funcCache[cacheKey]; + if (ret === undefined) { + ret = (typeof func == "function" ? func : source[key]).call(source, ...params); + funcCache[cacheKey] = ret; + //console.log('缓存未命中!'+key+":"+cacheKey+":"+params.length+":ret:"+ret); + } else { + //console.log(key+":"+cacheKey+":"+params.length+":ret:"+ret); + } + return ret; + } - static _ensureMember(obj,key){ - let mem = obj[key]; - if(!mem){ - mem = {}; - obj[key] = mem; - } - return mem; - } + static _ensureMember(obj, key) { + let mem = obj[key]; + if (!mem) { + mem = {}; + obj[key] = mem; + } + return mem; + } - static _wrapParametersToCacheKey(params){ - return Array.from(params) - .filter(p=>!(p instanceof CacheContext)) - .map(param=>CacheContext._wrapParameterToCacheKey(param)) - .join('-'); - } + static _wrapParametersToCacheKey(params) { + return Array.from(params) + .filter((p) => !(p instanceof CacheContext)) + .map((param) => CacheContext._wrapParameterToCacheKey(param)) + .join("-"); + } - static _wrapParameterToCacheKey(param){ - if(param === null)return 'null'; - if(param === undefined)return 'undefined'; - if(typeof param === 'string')return `[str:${param}]`; - if(typeof param === 'number')return `[d:${param}]`; - if(typeof param === 'boolean')return `[bl:${param}]`; - if(typeof param.getCacheKey == 'function')return param.getCacheKey(); - if(Array.isArray(param)){ - return `[arr:[${param.filter(p=>!(p instanceof CacheContext)).map(p=>CacheContext._wrapParameterToCacheKey(p)).join('-')}]]`; - } - if(typeof param === 'function')return `[f:${hex_md5(param.toString())}]`; - let entries = Object.entries(param); - entries.sort((a,b)=>a[0]e[0]+":"+CacheContext._wrapParameterToCacheKey(e[1])).join(',')}}]`; - } -} \ No newline at end of file + static _wrapParameterToCacheKey(param) { + if (param === null) return "null"; + if (param === undefined) return "undefined"; + if (typeof param === "string") return `[str:${param}]`; + if (typeof param === "number") return `[d:${param}]`; + if (typeof param === "boolean") return `[bl:${param}]`; + if (typeof param.getCacheKey == "function") return param.getCacheKey(); + if (Array.isArray(param)) { + return `[arr:[${param + .filter((p) => !(p instanceof CacheContext)) + .map((p) => CacheContext._wrapParameterToCacheKey(p)) + .join("-")}]]`; + } + if (typeof param === "function") return `[f:${hex_md5(param.toString())}]`; + let entries = Object.entries(param); + entries.sort((a, b) => (a[0] < b[0] ? -1 : 1)); + return `[obj:{${entries + .map((e) => e[0] + ":" + CacheContext._wrapParameterToCacheKey(e[1])) + .join(",")}}]`; + } +} diff --git a/noname/library/cache/childNodesWatcher.js b/noname/library/cache/childNodesWatcher.js index 22670e5db..eb82321bb 100644 --- a/noname/library/cache/childNodesWatcher.js +++ b/noname/library/cache/childNodesWatcher.js @@ -1,23 +1,23 @@ /** -* 子节点观察器,对于需要频繁遍历子节点的DOM对象的实时变化进行缓存。 -*/ -export class ChildNodesWatcher{ - constructor(dom){ - this.dom = dom; - this.childNodes = []; - this.observer = new MutationObserver(mutationsList=>{ - for (let mutation of mutationsList) { - if (mutation.type === 'childList') { - this.onChildNodesChanged(mutation.addedNodes,mutation.removedNodes); - } - } - }); - const config = { childList: true }; - this.observer.observe(dom,config); - } + * 子节点观察器,对于需要频繁遍历子节点的DOM对象的实时变化进行缓存。 + */ +export class ChildNodesWatcher { + constructor(dom) { + this.dom = dom; + this.childNodes = []; + this.observer = new MutationObserver((mutationsList) => { + for (let mutation of mutationsList) { + if (mutation.type === "childList") { + this.onChildNodesChanged(mutation.addedNodes, mutation.removedNodes); + } + } + }); + const config = { childList: true }; + this.observer.observe(dom, config); + } - onChildNodesChanged(addedNodes,removedNodes) { - this.childNodes.addArray(Array.from(addedNodes).filter(node=>node.parentNode == this.dom)); - this.childNodes.removeArray(Array.from(removedNodes)); - } -}; \ No newline at end of file + onChildNodesChanged(addedNodes, removedNodes) { + this.childNodes.addArray(Array.from(addedNodes).filter((node) => node.parentNode == this.dom)); + this.childNodes.removeArray(Array.from(removedNodes)); + } +} diff --git a/noname/library/channel/index.js b/noname/library/channel/index.js index 2a76543fc..3000ad80f 100644 --- a/noname/library/channel/index.js +++ b/noname/library/channel/index.js @@ -1,4 +1,3 @@ - /** * @template T */ @@ -21,7 +20,7 @@ export class Channel { /** * 向该频道发送消息,在消息未被接受前将等待 - * + * * @param {T} value - 要发送的消息 * @returns {Promise} */ @@ -54,7 +53,7 @@ export class Channel { /** * 接收频道所发送的消息,若无消息发送则等待 - * + * * @returns {Promise} 接收到的消息 */ receive() { diff --git a/noname/library/crypt/md5.js b/noname/library/crypt/md5.js index 2d1b6e46d..15ccd391b 100644 --- a/noname/library/crypt/md5.js +++ b/noname/library/crypt/md5.js @@ -53,7 +53,7 @@ function md5_vm_test() { */ function core_md5(x, len) { /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); + x[len >> 5] |= 0x80 << len % 32; x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; @@ -141,7 +141,6 @@ function core_md5(x, len) { d = safe_add(d, oldd); } return Array(a, b, c, d); - } /* @@ -151,16 +150,16 @@ function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); } function md5_ff(a, b, c, d, x, s, t) { - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); + return md5_cmn((b & c) | (~b & d), a, b, x, s, t); } function md5_gg(a, b, c, d, x, s, t) { - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); + return md5_cmn((b & d) | (c & ~d), a, b, x, s, t); } function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a, b, c, d, x, s, t) { - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); + return md5_cmn(c ^ (b | ~d), a, b, x, s, t); } /* @@ -171,10 +170,10 @@ function core_hmac_md5(key, data) { if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); var ipad = Array(16), - opad = Array(16); + opad = Array(16); for (var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; + opad[i] = bkey[i] ^ 0x5c5c5c5c; } var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); @@ -186,9 +185,9 @@ function core_hmac_md5(key, data) { * to work around bugs in some JS interpreters. */ function safe_add(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var lsw = (x & 0xffff) + (y & 0xffff); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); + return (msw << 16) | (lsw & 0xffff); } /* @@ -205,7 +204,8 @@ function bit_rol(num, cnt) { function str2binl(str) { var bin = Array(); var mask = (1 << chrsz) - 1; - for (var i = 0; i < str.length * chrsz; i += chrsz) bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32); + for (var i = 0; i < str.length * chrsz; i += chrsz) + bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32; return bin; } @@ -215,7 +215,8 @@ function str2binl(str) { function binl2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; - for (var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask); + for (var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i >> 5] >>> i % 32) & mask); return str; } @@ -223,10 +224,12 @@ function binl2str(bin) { * Convert an array of little-endian words to a hex string. */ function binl2hex(binarray) { - var hex_tab = hexcase ? "0123456789ABCDEF": "0123456789abcdef"; + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for (var i = 0; i < binarray.length * 4; i++) { - str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF); + str += + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) + + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf); } return str; } @@ -238,11 +241,14 @@ function binl2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for (var i = 0; i < binarray.length * 4; i += 3) { - var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF); + var triplet = + (((binarray[i >> 2] >> (8 * (i % 4))) & 0xff) << 16) | + (((binarray[(i + 1) >> 2] >> (8 * ((i + 1) % 4))) & 0xff) << 8) | + ((binarray[(i + 2) >> 2] >> (8 * ((i + 2) % 4))) & 0xff); for (var j = 0; j < 4; j++) { if (i * 8 + j * 6 > binarray.length * 32) str += b64pad; - else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); + else str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); } } return str; -} \ No newline at end of file +} diff --git a/noname/library/element/button.js b/noname/library/element/button.js index 4785b1648..daf50ec3d 100644 --- a/noname/library/element/button.js +++ b/noname/library/element/button.js @@ -1,11 +1,12 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; - +import { get } from "../../get/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; export class Button extends HTMLDivElement { + /** + * @type { string | undefined } + */ + buttonid; /** * @param {{}} item * @param {keyof typeof ui.create.buttonPresets | ((item: {}, type: Function, position?: HTMLDivElement | DocumentFragment, noClick?: true, button?: Button) => Button)} type @@ -20,14 +21,16 @@ export class Button extends HTMLDivElement { // @ts-ignore [item, type, position, noClick, button] = other._args; } - if (typeof type == 'function') button = type(item, type, position, noClick, button); - else if (ui.create.buttonPresets[type]) button = ui.create.buttonPresets[type](item, type, position, noClick, button); + if (typeof type == "function") button = type(item, type, position, noClick, button); + else if (ui.create.buttonPresets[type]) + button = ui.create.buttonPresets[type](item, type, position, noClick, button); if (button) { Object.setPrototypeOf(button, (lib.element.Button || Button).prototype); - if (!noClick) button.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.button); + if (!noClick) + button.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.button); else { - button.classList.add('noclick'); - const intro = button.querySelector('.intro'); + button.classList.add("noclick"); + const intro = button.querySelector(".intro"); if (intro) intro.remove(); } if (!button.buttonid) button.buttonid = get.id(); @@ -36,7 +39,7 @@ export class Button extends HTMLDivElement { return button; } else { console.error([item, type, position, noClick, button]); - throw 'button不合法'; + throw "button不合法"; } } exclude() { diff --git a/noname/library/element/card.js b/noname/library/element/card.js index a53f089d1..f316b57cd 100644 --- a/noname/library/element/card.js +++ b/noname/library/element/card.js @@ -1,9 +1,8 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; export class Card extends HTMLDivElement { /** @@ -20,7 +19,7 @@ export class Card extends HTMLDivElement { * @type {this} */ // @ts-ignore - const card = ui.create.div('.card', position); + const card = ui.create.div(".card", position); Object.setPrototypeOf(card, (lib.element.Card || Card).prototype); // @ts-ignore card._args = [position]; @@ -40,15 +39,16 @@ export class Card extends HTMLDivElement { } buildEventListener(info) { let card = this; - if (info != 'noclick') { - card.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.card); + if (info != "noclick") { + card.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.card); if (lib.config.touchscreen) { - card.addEventListener('touchstart', ui.click.cardtouchstart); - card.addEventListener('touchmove', ui.click.cardtouchmove); + card.addEventListener("touchstart", ui.click.cardtouchstart); + card.addEventListener("touchmove", ui.click.cardtouchmove); } - if (lib.cardSelectObserver) lib.cardSelectObserver.observe(card, { - attributes: true - }); + if (lib.cardSelectObserver) + lib.cardSelectObserver.observe(card, { + attributes: true, + }); } } buildProperty() { @@ -60,14 +60,14 @@ export class Card extends HTMLDivElement { } buildNode() { this.node = { - image: ui.create.div('.image', this), - info: ui.create.div('.info', this), - name: ui.create.div('.name', this), - name2: ui.create.div('.name2', this), - background: ui.create.div('.background', this), - intro: ui.create.div('.intro', this), - range: ui.create.div('.range', this), - gaintag: ui.create.div('.gaintag', this), + image: ui.create.div(".image", this), + info: ui.create.div(".info", this), + name: ui.create.div(".name", this), + name2: ui.create.div(".name2", this), + background: ui.create.div(".background", this), + intro: ui.create.div(".intro", this), + range: ui.create.div(".range", this), + gaintag: ui.create.div(".gaintag", this), }; this.node.intro.innerHTML = lib.config.intro; } @@ -104,16 +104,15 @@ export class Card extends HTMLDivElement { this.delete(); const info = get.info(this, false); if (!info) return; - if (info.destroyLog !== false) game.log(this, '被销毁了'); + if (info.destroyLog !== false) game.log(this, "被销毁了"); if (info.onDestroy) info.onDestroy(this, event); } //判断一张牌进入某个区域后是否会被销毁 willBeDestroyed(targetPosition, player, event) { const destroyed = this.destroyed; - if (typeof destroyed == 'function') { + if (typeof destroyed == "function") { return destroyed(this, targetPosition, player, event); - } - else if (lib.skill[destroyed]) { + } else if (lib.skill[destroyed]) { if (player) { if (player.hasSkill(destroyed)) { delete this.destroyed; @@ -121,9 +120,8 @@ export class Card extends HTMLDivElement { } } return true; - } - else if (typeof destroyed == 'string') { - return (destroyed == targetPosition); + } else if (typeof destroyed == "string") { + return destroyed == targetPosition; } return destroyed; } @@ -133,18 +131,18 @@ export class Card extends HTMLDivElement { //只针对【杀】起效果 addNature(nature) { let natures = []; - if (!this.nature) this.nature = ''; + if (!this.nature) this.nature = ""; else { natures.addArray(get.natureList(this.nature)); } natures.addArray(get.natureList(nature)); this.nature = get.nature(natures); this.classList.add(nature); - let str = get.translation(this.nature) + '杀'; + let str = get.translation(this.nature) + "杀"; this.node.name.innerText = str; let name = get.name(this, false); do { - if (name == 'sha') { + if (name == "sha") { let _bg; for (const n of natures) if (lib.natureBg.has(n)) _bg = n; if (_bg) { @@ -152,9 +150,8 @@ export class Card extends HTMLDivElement { break; } } - this.node.image.setBackgroundImage('image/card/' + name + '.png'); - } - while (0); + this.node.image.setBackgroundImage("image/card/" + name + ".png"); + } while (0); return this.nature; } removeNature(nature) { @@ -164,11 +161,11 @@ export class Card extends HTMLDivElement { if (!natures.length) delete this.nature; else this.nature = get.nature(natures); this.classList.remove(nature); - let str = get.translation(this.nature) + '杀'; + let str = get.translation(this.nature) + "杀"; this.node.name.innerText = str; let name = get.name(this, false); do { - if (name == 'sha') { + if (name == "sha") { let _bg; for (const n of natures) if (lib.natureBg.has(n)) _bg = n; if (_bg) { @@ -176,29 +173,28 @@ export class Card extends HTMLDivElement { break; } } - this.node.image.setBackgroundImage('image/card/' + name + '.png'); - } - while (0); + this.node.image.setBackgroundImage("image/card/" + name + ".png"); + } while (0); return this.nature; } addGaintag(gaintag) { if (Array.isArray(gaintag)) this.gaintag = gaintag.slice(0); else this.gaintag.add(gaintag); - var str = ''; + var str = ""; for (var gi = 0; gi < this.gaintag.length; gi++) { var translate = get.translation(this.gaintag[gi]); - if (translate != 'invisible') { + if (translate != "invisible") { str += translate; - if (gi < this.gaintag.length - 1) str += ' '; + if (gi < this.gaintag.length - 1) str += " "; } } this.node.gaintag.innerHTML = str; } removeGaintag(tag) { if (tag === true) { - if (this.gaintag && this.gaintag.length || this.node.gaintag.innerHTML.length) this.addGaintag([]); - } - else if (this.hasGaintag(tag)) { + if ((this.gaintag && this.gaintag.length) || this.node.gaintag.innerHTML.length) + this.addGaintag([]); + } else if (this.hasGaintag(tag)) { this.gaintag.remove(tag); this.addGaintag(this.gaintag); } @@ -216,51 +212,46 @@ export class Card extends HTMLDivElement { */ init(card) { if (Array.isArray(card)) { - if (card[2] == 'huosha') { - card[2] = 'sha'; - card[3] = 'fire'; - } - else if (card[2] == 'leisha') { - card[2] = 'sha'; - card[3] = 'thunder'; - } - else if (card[2] == 'cisha') { - card[2] = 'sha'; - card[3] = 'stab'; - } - else if (card[2].length > 3) { - let prefix = card[2].slice(0, card[2].lastIndexOf('sha')); + if (card[2] == "huosha") { + card[2] = "sha"; + card[3] = "fire"; + } else if (card[2] == "leisha") { + card[2] = "sha"; + card[3] = "thunder"; + } else if (card[2] == "cisha") { + card[2] = "sha"; + card[3] = "stab"; + } else if (card[2].length > 3) { + let prefix = card[2].slice(0, card[2].lastIndexOf("sha")); if (lib.nature.has(prefix)) { if (prefix.length + 3 == card[2].length) { - card[2] = 'sha'; + card[2] = "sha"; card[3] = prefix; } } - if (card[2].startsWith('sha_')) { + if (card[2].startsWith("sha_")) { let suffix = card[2].slice(4); - let natureList = suffix.split('_'); - card[2] = 'sha'; + let natureList = suffix.split("_"); + card[2] = "sha"; card[3] = get.nature(natureList); } } - } - else if (typeof card == 'object') { + } else if (typeof card == "object") { card = [card.suit, card.number, card.name, card.nature]; } - var cardnum = card[1] || ''; + var cardnum = card[1] || ""; if (parseInt(cardnum) == cardnum) cardnum = parseInt(cardnum); if (!lib.card[card[2]]) { lib.card[card[2]] = {}; } var info = lib.card[card[2]]; - if (info.global && !this.classList.contains('button')) { + if (info.global && !this.classList.contains("button")) { if (Array.isArray(info.global)) { while (info.global.length) { game.addGlobalSkill(info.global.shift()); } - } - else if (typeof info.global == 'string') { + } else if (typeof info.global == "string") { game.addGlobalSkill(info.global); } delete info.global; @@ -269,7 +260,7 @@ export class Card extends HTMLDivElement { this.number = parseInt(card[1]) || 0; this.name = card[2]; - if (info.destroy && (typeof info.destroy != 'boolean' && !lib.skill[info.destroy])) { + if (info.destroy && typeof info.destroy != "boolean" && !lib.skill[info.destroy]) { this.destroyed = info.destroy; } @@ -288,196 +279,179 @@ export class Card extends HTMLDivElement { this.inits[i](this); } } - if (typeof info.init == 'function') info.init(); + if (typeof info.init == "function") info.init(); return this; } /** * @param {[string, number, string, string]} card - */ + */ $init(card) { var info = lib.card[card[2]]; - var cardnum = card[1] || ''; + var cardnum = card[1] || ""; if (parseInt(cardnum) == cardnum) cardnum = parseInt(cardnum); if (cardnum > 0 && cardnum < 14) { - cardnum = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'][cardnum - 1]; + cardnum = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"][cardnum - 1]; } if (this.name) { - this.classList.remove('epic'); - this.classList.remove('legend'); - this.classList.remove('gold'); - this.classList.remove('unique'); - this.style.background = ''; + this.classList.remove("epic"); + this.classList.remove("legend"); + this.classList.remove("gold"); + this.classList.remove("unique"); + this.style.background = ""; var subtype = get.subtype(this, false); if (subtype) { this.classList.remove(subtype); } } if (info.epic) { - this.classList.add('epic'); - } - else if (info.legend) { - this.classList.add('legend'); - } - else if (info.gold) { - this.classList.add('gold'); - } - else if (info.unique) { - this.classList.add('unique'); + this.classList.add("epic"); + } else if (info.legend) { + this.classList.add("legend"); + } else if (info.gold) { + this.classList.add("gold"); + } else if (info.unique) { + this.classList.add("unique"); } var bg = card[2]; if (info.cardimage) { bg = info.cardimage; } - var img = get.dynamicVariable(lib.card[bg].image,this); + var img = get.dynamicVariable(lib.card[bg].image, this); if (img) { - if (img.startsWith('db:')) { + if (img.startsWith("db:")) { img = img.slice(3); - } - else if (!img.startsWith('ext:')) { + } else if (!img.startsWith("ext:")) { img = null; } } - this.classList.remove('fullskin'); - this.classList.remove('fullimage'); - this.classList.remove('fullborder'); + this.classList.remove("fullskin"); + this.classList.remove("fullimage"); + this.classList.remove("fullborder"); this.dataset.cardName = card[2]; - this.dataset.cardType = info.type || ''; - this.dataset.cardSubype = info.subtype || ''; - this.dataset.cardMultitarget = info.multitarget ? '1' : '0'; - this.node.name.dataset.nature = ''; - this.node.info.classList.remove('red'); + this.dataset.cardType = info.type || ""; + this.dataset.cardSubype = info.subtype || ""; + this.dataset.cardMultitarget = info.multitarget ? "1" : "0"; + this.node.name.dataset.nature = ""; + this.node.info.classList.remove("red"); if (!lib.config.hide_card_image && lib.card[bg].fullskin) { - this.classList.add('fullskin'); + this.classList.add("fullskin"); if (img) { - if (img.startsWith('ext:')) { - this.node.image.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - } - else { + if (img.startsWith("ext:")) { + this.node.image.setBackgroundImage(img.replace(/^ext:/, "extension/")); + } else { this.node.image.setBackgroundDB(img); } - } - else { + } else { if (lib.card[bg].modeimage) { - this.node.image.setBackgroundImage('image/mode/' + lib.card[bg].modeimage + '/card/' + bg + '.png'); - } - else { + this.node.image.setBackgroundImage( + "image/mode/" + lib.card[bg].modeimage + "/card/" + bg + ".png" + ); + } else { do { let nature = card[3]; - if (bg == 'sha' && typeof nature == 'string') { - let natures = get.natureList(nature), _bg; + if (bg == "sha" && typeof nature == "string") { + let natures = get.natureList(nature), + _bg; for (const n of natures) if (lib.natureBg.has(n)) _bg = n; if (_bg) { this.node.image.setBackgroundImage(lib.natureBg.get(_bg)); break; } } - this.node.image.setBackgroundImage('image/card/' + bg + '.png'); - } - while (0); + this.node.image.setBackgroundImage("image/card/" + bg + ".png"); + } while (0); } } - } - else if (get.dynamicVariable(lib.card[bg].image,this) == 'background') { - if (card[3]) this.node.background.setBackground(bg + '_' + get.natureList(card[3])[0], 'card'); - else this.node.background.setBackground(bg, 'card'); - } - else if (lib.card[bg].fullimage) { - this.classList.add('fullimage'); + } else if (get.dynamicVariable(lib.card[bg].image, this) == "background") { + if (card[3]) this.node.background.setBackground(bg + "_" + get.natureList(card[3])[0], "card"); + else this.node.background.setBackground(bg, "card"); + } else if (lib.card[bg].fullimage) { + this.classList.add("fullimage"); if (img) { - if (img.startsWith('ext:')) { - this.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - this.style.backgroundSize = 'cover'; - } - else { + if (img.startsWith("ext:")) { + this.setBackgroundImage(img.replace(/^ext:/, "extension/")); + this.style.backgroundSize = "cover"; + } else { this.setBackgroundDB(img); } - } - else if (get.dynamicVariable(lib.card[bg].image,this)) { - if (get.dynamicVariable(lib.card[bg].image,this).startsWith('character:')) { - this.setBackground(get.dynamicVariable(lib.card[bg].image,this).slice(10), 'character'); + } else if (get.dynamicVariable(lib.card[bg].image, this)) { + if (get.dynamicVariable(lib.card[bg].image, this).startsWith("character:")) { + this.setBackground(get.dynamicVariable(lib.card[bg].image, this).slice(10), "character"); + } else { + this.setBackground(get.dynamicVariable(lib.card[bg].image, this)); } - else { - this.setBackground(get.dynamicVariable(lib.card[bg].image,this)); - } - } - else { - var cardPack = lib.cardPack['mode_' + get.mode()]; + } else { + var cardPack = lib.cardPack["mode_" + get.mode()]; if (Array.isArray(cardPack) && cardPack.includes(bg)) { - this.setBackground('mode/' + get.mode() + '/card/' + bg); - } - else { - this.setBackground('card/' + bg); + this.setBackground("mode/" + get.mode() + "/card/" + bg); + } else { + this.setBackground("card/" + bg); } } - } - else if (lib.card[bg].fullborder) { - this.classList.add('fullborder'); - if (lib.card[bg].fullborder == 'gold') { - this.node.name.dataset.nature = 'metalmm'; - } - else if (lib.card[bg].fullborder == 'silver') { - this.node.name.dataset.nature = 'watermm'; + } else if (lib.card[bg].fullborder) { + this.classList.add("fullborder"); + if (lib.card[bg].fullborder == "gold") { + this.node.name.dataset.nature = "metalmm"; + } else if (lib.card[bg].fullborder == "silver") { + this.node.name.dataset.nature = "watermm"; } if (!this.node.avatar) { - this.node.avatar = ui.create.div('.cardavatar'); + this.node.avatar = ui.create.div(".cardavatar"); this.insertBefore(this.node.avatar, this.firstChild); } if (!this.node.framebg) { - this.node.framebg = ui.create.div('.cardframebg'); + this.node.framebg = ui.create.div(".cardframebg"); this.node.framebg.dataset.auto = lib.card[bg].fullborder; this.insertBefore(this.node.framebg, this.firstChild); } if (img) { - if (img.startsWith('ext:')) { - this.node.avatar.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - this.node.avatar.style.backgroundSize = 'cover'; - } - else { + if (img.startsWith("ext:")) { + this.node.avatar.setBackgroundImage(img.replace(/^ext:/, "extension/")); + this.node.avatar.style.backgroundSize = "cover"; + } else { this.node.avatar.setBackgroundDB(img); } - } - else if (get.dynamicVariable(lib.card[bg].image,this)) { - if (get.dynamicVariable(lib.card[bg].image,this).startsWith('character:')) { - this.node.avatar.setBackground(get.dynamicVariable(lib.card[bg].image,this).slice(10), 'character'); + } else if (get.dynamicVariable(lib.card[bg].image, this)) { + if (get.dynamicVariable(lib.card[bg].image, this).startsWith("character:")) { + this.node.avatar.setBackground( + get.dynamicVariable(lib.card[bg].image, this).slice(10), + "character" + ); + } else { + this.node.avatar.setBackground(get.dynamicVariable(lib.card[bg].image, this)); } - else { - this.node.avatar.setBackground(get.dynamicVariable(lib.card[bg].image,this)); - } - } - else { - var cardPack = lib.cardPack['mode_' + get.mode()]; + } else { + var cardPack = lib.cardPack["mode_" + get.mode()]; if (Array.isArray(cardPack) && cardPack.includes(bg)) { - this.node.avatar.setBackground('mode/' + get.mode() + '/card/' + bg); - } - else { - this.node.avatar.setBackground('card/' + bg); + this.node.avatar.setBackground("mode/" + get.mode() + "/card/" + bg); + } else { + this.node.avatar.setBackground("card/" + bg); } } - } - else if (get.dynamicVariable(lib.card[bg].image,this) == 'card') { - if (card[3]) this.setBackground(bg + '_' + get.natureList(card[3])[0], 'card'); - else this.setBackground(bg, 'card'); - } - else if (typeof get.dynamicVariable(lib.card[bg].image,this) == 'string' && !lib.card[bg].fullskin) { + } else if (get.dynamicVariable(lib.card[bg].image, this) == "card") { + if (card[3]) this.setBackground(bg + "_" + get.natureList(card[3])[0], "card"); + else this.setBackground(bg, "card"); + } else if ( + typeof get.dynamicVariable(lib.card[bg].image, this) == "string" && + !lib.card[bg].fullskin + ) { if (img) { - if (img.startsWith('ext:')) { - this.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - this.style.backgroundSize = 'cover'; - } - else { + if (img.startsWith("ext:")) { + this.setBackgroundImage(img.replace(/^ext:/, "extension/")); + this.style.backgroundSize = "cover"; + } else { this.setBackgroundDB(img); } + } else { + this.setBackground(get.dynamicVariable(lib.card[bg].image, this)); } - else { - this.setBackground(get.dynamicVariable(lib.card[bg].image,this)); - } - } - else { - this.node.background.innerHTML = lib.translate[bg + '_cbg'] || lib.translate[bg + '_bg'] || get.translation(bg)[0]; + } else { + this.node.background.innerHTML = + lib.translate[bg + "_cbg"] || lib.translate[bg + "_bg"] || get.translation(bg)[0]; // this.node.background.style.fontFamily=lib.config.card_font; - if (this.node.background.innerHTML.length > 1) this.node.background.classList.add('tight'); - else this.node.background.classList.remove('tight'); + if (this.node.background.innerHTML.length > 1) this.node.background.classList.add("tight"); + else this.node.background.classList.remove("tight"); } if (!lib.card[bg].fullborder && this.node.avatar && this.node.framebg) { this.node.avatar.remove(); @@ -485,8 +459,8 @@ export class Card extends HTMLDivElement { delete this.node.avatar; delete this.node.framebg; } - if (info.noname && !this.classList.contains('button')) { - this.node.name.style.display = 'none'; + if (info.noname && !this.classList.contains("button")) { + this.node.name.style.display = "none"; } if (info.color) { this.style.color = info.color; @@ -500,82 +474,88 @@ export class Card extends HTMLDivElement { } if (info.modinfo) { this.node.info.innerHTML = info.modinfo; - } - else { - this.node.info.innerHTML = get.translation(card[0]) + ' ' + cardnum + ''; + } else { + this.node.info.innerHTML = + get.translation(card[0]) + + ' ' + + cardnum + + ""; } if (info.addinfo) { if (!this.node.addinfo) { - this.node.addinfo = ui.create.div('.range', this); + this.node.addinfo = ui.create.div(".range", this); } this.node.addinfo.innerHTML = info.addinfo; - } - else if (this.node.addinfo) { + } else if (this.node.addinfo) { this.node.addinfo.remove(); delete this.node.addinfo; } - if (card[0] == 'heart' || card[0] == 'diamond') { - this.node.info.classList.add('red'); + if (card[0] == "heart" || card[0] == "diamond") { + this.node.info.classList.add("red"); } - this.node.image.className = 'image'; + this.node.image.className = "image"; var name = get.translation(card[2]); - if (card[2] == 'sha') { - name = ''; + if (card[2] == "sha") { + name = ""; let nature = card[3]; if (nature) { let natures = get.natureList(nature); natures.sort(lib.sort.nature); for (let nature of natures) { - name += lib.translate['nature_' + nature] || lib.translate[nature] || ''; - if (nature != 'stab') this.node.image.classList.add(nature); + name += lib.translate["nature_" + nature] || lib.translate[nature] || ""; + if (nature != "stab") this.node.image.classList.add(nature); } } - name += '杀'; + name += "杀"; } this.node.name.innerHTML = name; if (name.length >= 5) { - this.node.name.classList.add('long'); + this.node.name.classList.add("long"); if (name.length >= 7) { - this.node.name.classList.add('longlong'); + this.node.name.classList.add("longlong"); } } - this.node.name2.innerHTML = get.translation(card[0]) + cardnum + ' ' + name; - this.classList.add('card'); + this.node.name2.innerHTML = get.translation(card[0]) + cardnum + " " + name; + this.classList.add("card"); if (card[3]) { let natures = get.natureList(card[3]); - natures.forEach(n => { if (n) this.classList.add(n); }); - this.nature = natures.filter(n => lib.nature.has(n)).sort(lib.sort.nature).join(lib.natureSeparator); - } - else if (this.nature) { + natures.forEach((n) => { + if (n) this.classList.add(n); + }); + this.nature = natures + .filter((n) => lib.nature.has(n)) + .sort(lib.sort.nature) + .join(lib.natureSeparator); + } else if (this.nature) { this.classList.remove(this.nature); delete this.nature; } if (info.subtype) this.classList.add(info.subtype); - this.node.range.innerHTML = ''; + this.node.range.innerHTML = ""; switch (get.subtype(this, false)) { - case 'equip1': + case "equip1": var added = false; if (lib.card[this.name] && lib.card[this.name].distance) { var dist = lib.card[this.name].distance; if (dist.attackFrom) { added = true; - this.node.range.innerHTML = '范围: ' + (-dist.attackFrom + 1); + this.node.range.innerHTML = "范围: " + (-dist.attackFrom + 1); } } if (!added) { - this.node.range.innerHTML = '范围: 1'; + this.node.range.innerHTML = "范围: 1"; } break; - case 'equip3': + case "equip3": if (info.distance && info.distance.globalTo) { - this.node.range.innerHTML = '防御: ' + info.distance.globalTo; - this.node.name2.innerHTML += '+'; + this.node.range.innerHTML = "防御: " + info.distance.globalTo; + this.node.name2.innerHTML += "+"; } break; - case 'equip4': + case "equip4": if (info.distance && info.distance.globalFrom) { - this.node.range.innerHTML = '进攻: ' + (-info.distance.globalFrom); - this.node.name2.innerHTML += '-'; + this.node.range.innerHTML = "进攻: " + -info.distance.globalFrom; + this.node.name2.innerHTML += "-"; } break; } @@ -600,10 +580,10 @@ export class Card extends HTMLDivElement { _status.cardtag[tag] = []; } _status.cardtag[tag].add(this.cardid); - tagstr += lib.translate[tag + '_tag']; + tagstr += lib.translate[tag + "_tag"]; //if(i this._knowers.add(p.playerid)); + } else if (type == "players") { + player.forEach((p) => this._knowers.add(p.playerid)); } } } @@ -654,14 +638,14 @@ export class Card extends HTMLDivElement { if (!this._knowers) { return; } - if (typeof player == 'string') { + if (typeof player == "string") { this._knowers.remove(player); } else { let type = get.itemtype(player); - if (type == 'player') { + if (type == "player") { this._knowers.remove(player.playerid); - } else if (type == 'players') { - player.forEach(p => this._knowers.remove(p.playerid)); + } else if (type == "players") { + player.forEach((p) => this._knowers.remove(p.playerid)); } } } @@ -671,16 +655,16 @@ export class Card extends HTMLDivElement { } //判断玩家对此牌是否知情。 isKnownBy(player) { - if (['e', 'j'].includes(get.position(this))) return true;//装备区或者判定区的牌,必知情。 + if (["e", "j"].includes(get.position(this))) return true; //装备区或者判定区的牌,必知情。 let owner = get.owner(this); if (owner) { - if (owner == player) return true;//是牌主,必知情。 - if (player.hasSkillTag('viewHandcard', null, owner, true)) return true;//有viewHandcard标签,必知情。 - if (owner.isUnderControl(true, player)) return true;//被操控,必知情。 + if (owner == player) return true; //是牌主,必知情。 + if (player.hasSkillTag("viewHandcard", null, owner, true)) return true; //有viewHandcard标签,必知情。 + if (owner.isUnderControl(true, player)) return true; //被操控,必知情。 } - if (get.is.shownCard(this)) return true;//此牌是明置牌,必知情。 + if (get.is.shownCard(this)) return true; //此牌是明置牌,必知情。 if (this._knowers) { - return this._knowers.includes('everyone') || this._knowers.includes(player.playerid); + return this._knowers.includes("everyone") || this._knowers.includes(player.playerid); } return false; } @@ -700,42 +684,42 @@ export class Card extends HTMLDivElement { setTimeout(function () { that.delete(); }, 200); - } - else { + } else { this._onEndMoveDelete = player; } } moveTo(player) { this.fixed = true; var dx, dy; - if (this.classList.contains('center')) { + if (this.classList.contains("center")) { var nx = [50, -52]; var ny = [50, -52]; - nx = nx[0] * ui.arena.offsetWidth / 100 + nx[1]; - ny = ny[0] * ui.arena.offsetHeight / 100 + ny[1]; + nx = (nx[0] * ui.arena.offsetWidth) / 100 + nx[1]; + ny = (ny[0] * ui.arena.offsetHeight) / 100 + ny[1]; dx = player.getLeft() + player.offsetWidth / 2 - 52 - nx; dy = player.getTop() + player.offsetHeight / 2 - 52 - ny; - } - else { - this.style.left = this.offsetLeft + 'px'; - this.style.top = this.offsetTop + 'px'; + } else { + this.style.left = this.offsetLeft + "px"; + this.style.top = this.offsetTop + "px"; dx = player.getLeft() + player.offsetWidth / 2 - 52 - this.offsetLeft; dy = player.getTop() + player.offsetHeight / 2 - 52 - this.offsetTop; } if (get.is.mobileMe(player)) { dx += get.cardOffset(); - if (ui.arena.classList.contains('oblongcard')) { + if (ui.arena.classList.contains("oblongcard")) { dy -= 16; } } - - if (this.style.transform && this.style.transform != 'none' && this.style.transform.indexOf('translate') == -1) { - this.style.transform += ' translate(' + dx + 'px,' + dy + 'px)'; - } - else { - this.style.transform = 'translate(' + dx + 'px,' + dy + 'px)'; + if ( + this.style.transform && + this.style.transform != "none" && + this.style.transform.indexOf("translate") == -1 + ) { + this.style.transform += " translate(" + dx + "px," + dy + "px)"; + } else { + this.style.transform = "translate(" + dx + "px," + dy + "px)"; } return this; } @@ -744,34 +728,34 @@ export class Card extends HTMLDivElement { * @type {Card} */ var node = this.cloneNode(true); - node.style.transform = ''; + node.style.transform = ""; node.name = this.name; node.suit = this.suit; node.number = this.number; node.nature = this.nature; - node.classList.remove('hidden'); - node.classList.remove('start'); - node.classList.remove('thrown'); - node.classList.remove('selectable'); - node.classList.remove('selected'); - node.classList.remove('removing'); - node.classList.remove('drawinghidden'); - node.classList.remove('glows'); + node.classList.remove("hidden"); + node.classList.remove("start"); + node.classList.remove("thrown"); + node.classList.remove("selectable"); + node.classList.remove("selected"); + node.classList.remove("removing"); + node.classList.remove("drawinghidden"); + node.classList.remove("glows"); node.node = { - name: node.querySelector('.name'), - info: node.querySelector('.info'), - intro: node.querySelector('.intro'), - background: node.querySelector('.background'), - image: node.querySelector('.image'), - gaintag: node.querySelector('.gaintag'), + name: node.querySelector(".name"), + info: node.querySelector(".info"), + intro: node.querySelector(".intro"), + background: node.querySelector(".background"), + image: node.querySelector(".image"), + gaintag: node.querySelector(".gaintag"), }; - node.node.gaintag.innerHTML = ''; + node.node.gaintag.innerHTML = ""; var clone = true; var position; for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') node.classList.add(arguments[i]); - else if (['div', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'boolean') clone = arguments[i]; + if (typeof arguments[i] == "string") node.classList.add(arguments[i]); + else if (["div", "fragment"].includes(get.objtype(arguments[i]))) position = arguments[i]; + else if (typeof arguments[i] == "boolean") clone = arguments[i]; } node.moveTo = lib.element.Card.prototype.moveTo; node.moveDelete = lib.element.Card.prototype.moveDelete; @@ -781,39 +765,39 @@ export class Card extends HTMLDivElement { } uncheck(skill) { if (skill) this._uncheck.add(skill); - this.classList.add('uncheck'); + this.classList.add("uncheck"); } recheck(skill) { if (skill) this._uncheck.remove(skill); else this._uncheck.length = 0; - if (this._uncheck.length == 0) this.classList.remove('uncheck'); + if (this._uncheck.length == 0) this.classList.remove("uncheck"); } /** * 判断此牌是否包含class样式,参数有多个时,只需一个满足。 - * + * * @param {string} className - * + * * @returns {boolean} 是否包含class */ - classListContains(className){ - return Array.from(arguments).some(name=>this.classList.contains(className)); + classListContains(className) { + return Array.from(arguments).some((name) => this.classList.contains(className)); } /** * 判断此牌是否包含class样式,参数有多个时,需全部满足。 - * + * * @param {string} className - * + * * @returns {boolean} 是否包含class */ - classListContainsAll(){ - return Array.from(arguments).every(name=>this.classList.contains(this.className)); + classListContainsAll() { + return Array.from(arguments).every((name) => this.classList.contains(this.className)); } /** * 返回一个键值,用于在缓存中作为键名。 - * + * * @returns {string} cacheKey */ - getCacheKey(){ + getCacheKey() { return `[c:${this.cardid}]`; } discard(bool) { @@ -821,26 +805,33 @@ export class Card extends HTMLDivElement { this.fix(); ui.discardPile.appendChild(this); } - this.classList.remove('glow'); + this.classList.remove("glow"); if (bool === false) { - ui.cardPile.insertBefore(this, ui.cardPile.childNodes[Math.floor(Math.random() * ui.cardPile.childNodes.length)]); - } - else { + ui.cardPile.insertBefore( + this, + ui.cardPile.childNodes[Math.floor(Math.random() * ui.cardPile.childNodes.length)] + ); + } else { if (_status.discarded) { _status.discarded.add(this); } } } hasTag(tag) { - if (this.cardid && _status.cardtag && _status.cardtag[tag] && _status.cardtag[tag].includes(this.cardid)) { + if ( + this.cardid && + _status.cardtag && + _status.cardtag[tag] && + _status.cardtag[tag].includes(this.cardid) + ) { return true; } return false; } hasPosition() { - return ['h', 'e', 'j', 's', 'x'].includes(get.position(this)); + return ["h", "e", "j", "s", "x"].includes(get.position(this)); } isInPile() { - return ['c', 'd'].includes(get.position(this)); + return ["c", "d"].includes(get.position(this)); } } diff --git a/noname/library/element/client.js b/noname/library/element/client.js index fba45ff6c..dadcc611f 100644 --- a/noname/library/element/client.js +++ b/noname/library/element/client.js @@ -1,17 +1,15 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; export class Client { /** * @param {import('../index.js').NodeWS | InstanceType | Client} ws */ constructor(ws) { - if (ws instanceof Client) throw new Error('Client cannot copy.') + if (ws instanceof Client) throw new Error("Client cannot copy."); this.ws = ws; /** * @type { string } @@ -23,16 +21,15 @@ export class Client { send() { if (this.closed) return this; var args = Array.from(arguments); - if (typeof args[0] == 'function') { - args.unshift('exec'); + if (typeof args[0] == "function") { + args.unshift("exec"); } for (var i = 1; i < args.length; i++) { args[i] = get.stringifiedResult(args[i]); } try { this.ws.send(JSON.stringify(args)); - } - catch (e) { + } catch (e) { this.ws.close(); } return this; @@ -56,20 +53,19 @@ export class Client { game.onlinezhu = null; } game.updateWaiting(); - } - else if (lib.playerOL[this.id]) { + } else if (lib.playerOL[this.id]) { var player = lib.playerOL[this.id]; - player.setNickname(player.nickname + ' - 离线'); + player.setNickname(player.nickname + " - 离线"); // @ts-ignore game.broadcast(function (player) { - player.setNickname(player.nickname + ' - 离线'); + player.setNickname(player.nickname + " - 离线"); }, player); - player.unwait('ai'); + player.unwait("ai"); } if (window.isNonameServer) { // @ts-ignore - document.querySelector('#server_count').innerHTML = lib.node.clients.length; + document.querySelector("#server_count").innerHTML = lib.node.clients.length; } return this; } diff --git a/noname/library/element/content.js b/noname/library/element/content.js index f02c00d27..0cd1bda8a 100644 --- a/noname/library/element/content.js +++ b/noname/library/element/content.js @@ -1,8585 +1,9276 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; - -// 未来再改 -export const Content = { - emptyEvent: () => { - event.trigger(event.name); - }, - //变更武将牌 - async changeCharacter(event,trigger,player) { - const rawPairs = [player.name1]; - if (player.name2 && lib.character[player.name2]) rawPairs.push(player.name2); - event.rawPairs = rawPairs; - const newPairs = event.newPairs; - for(let name of newPairs){ - if(!lib.character[name]){ - console.warn(`警告:Player[${player.name}]试图将武将牌变更为不存在的武将:`,name); - return; - } - } - const removeSkills = [], addSkills = []; - //进行Log - if(event.log !== false) { - //变更前后数量相同的情况 - if (rawPairs.length == newPairs.length){ - for (let i = 0; i { - removeSkills.addArray(lib.character[name][3]); - }) - newPairs.forEach(name => { - addSkills.addArray(lib.character[name][3].filter(skill => { - const info = get.info(skill); - if (!info || (info.zhuSkill && !player.isZhu2())) return false; - return true; - })); - }) - //实际变更武将牌 - player.reinit2(newPairs); - //操作武将牌堆 - if (_status.characterlist) { - _status.characterlist.removeArray(newPairs); - _status.characterlist.addArray(rawPairs); - } - //变更一下获得前后的技能 - await player.changeSkills(addSkills, removeSkills); - //变更角色的所属势力。如果新将是双势力,重选一下势力。 - if(event.changeGroup !== false){ - let newGroups = []; - if (!player.isUnseen(1)) { - newGroups = (get.is.double(player.name1, true) || [get.character(player.name1, 1)]); - } - else if (player.name2 && !player.isUnseen(2)) { - newGroups = (get.is.double(player.name2, true) || [get.character(player.name2, 1)]); - } - if (newGroups.length > 1) { - const newGroup = await player.chooseControl(newGroups).set('prompt','请选择一个新的势力').forResult('control'); - if (newGroup != player.group) { - await player.changeGroup(newGroup); - } - } - else if(newGroups.length == 1 && newGroups[0] != player.group){ - await player.changeGroup(newGroups[0]); - } - } - }, - //变更技能 - async changeSkills (event,trigger,player) { - //获取玩家当前已有的技能 - const ownedSkills = player.getSkills(true, false, false); - //去重检查 - event.addSkill.unique(); - event.removeSkill.unique(); - //避免失去还没拥有的技能 - event.removeSkill = event.removeSkill.filter(skill => ownedSkills.includes(skill)); - const duplicatedSkills = event.addSkill.filter(skill => event.removeSkill.includes(skill)); - if (duplicatedSkills.length) { - event.addSkill.removeArray(duplicatedSkills); - event.removeSkill.removeArray(duplicatedSkills); - } - //if (!event.addSkill.length&&!event.removeSkill.length) return; - //手动触发时机 - await event.trigger('changeSkillsBefore'); - await event.trigger('changeSkillsBegin'); - //处理失去和获得的技能 - if (event.$handle) { - event.$handle(player, event.addSkill, event.removeSkill, event); - } - else { - if(event.addSkill.length){ - player.addSkill(event.addSkill); - game.log(player, '获得了技能', ...event.addSkill.map(i => { - return '#g【' + get.translation(i) + '】'; - })); - } - if(event.removeSkill.length){ - player.removeSkill(event.removeSkill); - game.log(player, '失去了技能', ...event.removeSkill.map(i => { - return '#g【' + get.translation(i) + '】'; - })); - } - } - //手动触发时机 - await event.trigger('changeSkillsEnd'); - await event.trigger('changeSkillsAfter'); - }, - //增加明置手牌 - addShownCards: () => { - const hs = player.getCards('h'), showingCards = event._cards.filter(showingCard => hs.includes(showingCard)), shown = player.getShownCards(); - event.gaintag.forEach(tag => player.addGaintag(showingCards, tag)); - if (!(event.cards = showingCards.filter(showingCard => !shown.includes(showingCard))).length) return; - game.log(player, '明置了', event.cards); - //if (event.animate != false) player.$give(event.cards, player, false); - event.trigger('addShownCardsAfter'); - }, - //隐藏明置手牌 - hideShownCards: () => { - var shown = player.getShownCards(), hidingCards = event._cards.filter(hidingCard => shown.includes(hidingCard)); - if (!hidingCards.length) return; - if (event.gaintag.length) event.gaintag.forEach(tag => player.removeGaintag(tag, hidingCards)); - else { - var map = hidingCards.reduce((constructingMap, hidingCard) => { - hidingCard.gaintag.forEach(tag => { - if (!tag.startsWith('visible_')) return; - if (!constructingMap[tag]) constructingMap[tag] = []; - constructingMap[tag].push(hidingCard); - }); - return constructingMap; - }, {}); - Object.keys(map).forEach(key => player.removeGaintag(key, map[key])); - } - hidingCards.removeArray(player.getShownCards()); - if (!hidingCards.length) return; - game.log(player, '取消明置了', event.cards = hidingCards); - //if (event.animate != false) player.$give(hidingCards, player, false); - event.trigger('hideShownCardsAfter'); - }, - //Execute the delay card effect - //执行延时锦囊牌效果 - executeDelayCardEffect: () => { - 'step 0'; - target.$phaseJudge(card); - event.cancelled = false; - event.trigger('executeDelayCardEffect'); - event.cardName = card.viewAs || card.name; - target.popup(event.cardName, 'thunder'); - if (!lib.card[event.cardName].effect) { - game.delay(); - event.finish(); - } - else if (!lib.card[event.cardName].judge) { - game.delay(); - event.nojudge = true; - } - 'step 1'; - if (event.cancelled || event.nojudge) return; - var next = player.judge(card), judge = event.judge; - if (typeof judge == 'function') next.judge = judge; - var judge2 = event.judge2; - if (typeof judge2 == 'function') next.judge2 = judge2; - 'step 2'; - if (event.excluded) delete event.excluded; - else { - var cardName = event.cardName; - if (event.cancelled && !event.direct) { - var cardCancel = lib.card[cardName].cancel; - if (cardCancel) { - var next = game.createEvent(`${cardName}Cancel`); - next.setContent(cardCancel); - next.cards = [card]; - if (!card.viewAs) { - var autoViewAs = next.card = get.autoViewAs(card); - autoViewAs.expired = card.expired; - } - else { - var autoViewAs = next.card = get.autoViewAs({ - name: cardName - }, next.cards); - autoViewAs.expired = card.expired; - } - next.player = player; - } - } - else { - var next = game.createEvent(cardName); - next.setContent(lib.card[cardName].effect); - next._result = result; - next.cards = [card]; - if (!card.viewAs) { - var autoViewAs = next.card = get.autoViewAs(card); - autoViewAs.expired = card.expired; - } - else { - var autoViewAs = next.card = get.autoViewAs({ - name: cardName - }, next.cards); - autoViewAs.expired = card.expired; - } - next.player = player; - } - } - ui.clear(); - card.delete(); - }, - //Gift - //赠予 - gift: () => { - 'step 0'; - event.num = 0; - 'step 1'; - if (num < cards.length) { - event.card = cards[num]; - event.trigger('gift'); - } - else { - game.delayx(); - event.finish(); - } - 'step 2'; - if (event.deniedGifts.includes(card)) { - game.log(target, '拒绝了', player, '赠予的', card); - event.trigger('giftDeny'); - player.loseToDiscardpile(card).log = false; - event.trigger('giftDenied'); - return; - } - game.log(player, '将', card, '赠予了', target); - player.$give(card, target, false); - game.delay(0.5); - event.trigger('giftAccept'); - if (get.type(card, false) == 'equip') target.equip(card).log = false; - else target.gain(card, player).visible = true; - event.trigger('giftAccepted'); - 'step 3'; - event.num++; - event.goto(1); - }, - //Recast - //重铸 - recast: () => { - 'step 0'; - game.log(player, '重铸了', cards); - if (typeof event.recastingLose != 'function') return; - event.trigger('recastingLose'); - event.recastingLose(player, cards); - event.trigger('recastingLost'); - event.recastingLosingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); - 'step 1'; - event.trigger('recast'); - 'step 2'; - if (typeof event.recastingGain != 'function') return; - event.trigger('recastingGain'); - event.recastingGain(player, cards); - event.trigger('recastingGained'); - event.recastingGainingEvents.push(...event.next.filter(value => value.name != 'arrangeTrigger')); - }, - //装备栏相关 - disableEquip: function () { - 'step 0'; - event.cards = []; - event.num = 0; - event.slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); - else event.slotsx.add(type); - }); - } - else { - event.slotsx.addArray(event.slots); - } - event.slotsx.sort(); - if (!event.slots.length) event.finish(); - 'step 1'; - var slot = event.slotsx[event.num]; - var slot_key = slot; - var left = player.countEnabledSlot(slot), lose; - if (slot == 'equip3_4') { - lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); - slot_key = 'equip3'; - } - else lose = Math.min(left, get.numOf(event.slots, slot)); - if (lose <= 0) event.goto(3); - else { - game.log(player, '废除了' + get.cnNumber(lose) + '个', '#g' + get.translation(slot) + '栏'); - if (!player.disabledSlots) player.disabledSlots = {}; - if (!player.disabledSlots[slot_key]) player.disabledSlots[slot_key] = 0; - player.disabledSlots[slot_key] += lose; - var cards = player.getEquips(slot).filter(card => !event.cards.includes(card)); - if (cards.length > 0) { - if (lose >= left) { - event._result = { bool: true, links: cards }; - } - else if (cards.length > (left - lose)) { - var source = event.source, num = (cards.length - (left - lose)); - if (!source || !source.isIn()) source = player; - source.chooseButton([ - '选择' + (player == source ? '你' : get.translation(player)) + '的' + get.cnNumber(num) + '张' + get.translation(slot) + '牌置入弃牌堆', - cards, - ], true, [1, num]).set('filterOk', function () { - var evt = _status.event; - return ui.selected.buttons.reduce(function (num, button) { - if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); - return num + get.numOf(get.subtypes(button.link, false), evt.slot); - }, 0) == evt.required; - }).set('required', num).set('slot', slot); - } - else event.goto(3); - } - else event.goto(3); - } - 'step 2'; - if (result.bool) event.cards.addArray(result.links); - 'step 3'; - event.num++; - if (event.num < event.slotsx.length) event.goto(1); - else { - player.$syncDisable(); - if (cards.length > 0) player.loseToDiscardpile(cards); - } - }, - enableEquip: function () { - if (!event.slots.length) return; - var slotsx = [...new Set(event.slots)].sort(); - for (var slot of slotsx) { - var lost = player.countDisabledSlot(slot), gain = Math.min(lost, get.numOf(event.slots, slot)); - if (lost <= 0) continue; - else { - game.log(player, '恢复了' + get.cnNumber(gain) + '个', '#g' + get.translation(slot) + '栏'); - if (!player.disabledSlots) player.disabledSlots = {}; - if (!player.disabledSlots[slot]) player.disabledSlots[slot] = 0; - player.disabledSlots[slot] -= gain; - } - } - player.$syncDisable(); - }, - expandEquip: function () { - if (!event.slots.length) return; - var slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') slotsx.add('equip3_4'); - else slotsx.add(type); - }); - } - else { - slotsx.addArray(event.slots); - } - slotsx.sort(); - for (var slot of slotsx) { - var expand = get.numOf(event.slots, slot), slot_key = slot; - if (slot == 'equip3_4') { - expand = Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4')); - slot_key = 'equip3'; - } - game.log(player, '获得了' + get.cnNumber(expand) + '个额外的', '#g' + get.translation(slot) + '栏'); - if (!player.expandedSlots) player.expandedSlots = {}; - if (!player.expandedSlots[slot_key]) player.expandedSlots[slot_key] = 0; - player.expandedSlots[slot_key] += expand; - } - player.$syncExpand(); - }, - //选择顶装备要顶的牌 - replaceEquip: function () { - 'step 0'; - event.cards = []; - var types = get.subtypes(card, false); - if (types.length) { - var info = get.info(card, false); - if (info.customSwap) { - event.cards.addArray(player.getCards('e', function (card) { - return info.customSwap(card); - })); - event.goto(4); - } - else { - event.num = 0; - event.slots = types; - event.slotsx = []; - if (get.is.mountCombined()) { - event.slots.forEach(type => { - if (type == 'equip3' || type == 'equip4') event.slotsx.add('equip3_4'); - else event.slotsx.add(type); - }); - } - else { - event.slotsx.addArray(event.slots); - } - event.slotsx.sort(); - } - } - else event.goto(4); - 'step 1'; - var slot = event.slotsx[event.num]; - var left = player.countEquipableSlot(slot), lose; - if (slot == 'equip3_4') lose = Math.min(left, Math.max(get.numOf(event.slots, 'equip3'), get.numOf(event.slots, 'equip4'))); - else lose = Math.min(left, get.numOf(event.slots, slot)); - if (lose <= 0) event.goto(3); - else { - var cards = player.getEquips(slot).filter(card => { - return !event.cards.includes(card) && lib.filter.canBeReplaced(card, player); - }); - if (cards.length > 0) { - if (lose >= left) { - event._result = { bool: true, links: cards }; - } - else if (cards.length > (left - lose)) { - var source = event.source, num = (cards.length - (left - lose)); - if (!source || !source.isIn()) source = player; - source.chooseButton([ - '选择替换掉' + get.cnNumber(num) + '张' + get.translation(slot) + '牌', - cards, - ], true, [1, num]).set('filterOk', function () { - var evt = _status.event; - return ui.selected.buttons.reduce(function (num, button) { - if (evt.slot == 'equip3_4') return num + Math.max(get.numOf(get.subtypes(button.link, false), 'equip3'), get.numOf(get.subtypes(button.link, false), 'equip4')); - return num + get.numOf(get.subtypes(button.link, false), evt.slot); - }, 0) == evt.required; - }).set('required', num).set('slot', slot); - } - else event.goto(3); - } - else event.goto(3); - } - 'step 2'; - if (result.bool) event.cards.addArray(result.links); - 'step 3'; - event.num++; - if (event.num < event.slotsx.length) event.goto(1); - 'step 4'; - event.result = cards; - }, - //装备牌 - equip: function () { - "step 0"; - var owner = get.owner(card); - if (owner) { - event.owner = owner; - owner.lose(card, ui.special, 'visible').set('type', 'equip').set('getlx', false); - } - else if (get.position(card) == 'c') event.updatePile = true; - "step 1"; - if (event.cancelled) { - event.finish(); - return; - } - if (card.willBeDestroyed('equip', player, event)) { - card.selfDestroy(event); - event.finish(); - return; - } - else if (event.owner) { - if (event.owner.getCards('hejsx').includes(card)) { - event.finish(); - return; - } - } - if (event.draw) { - game.delay(0, 300); - player.$draw(card); - } - "step 2"; - if (card.clone) { - game.broadcast(function (card, player) { - if (card.clone) { - card.clone.moveDelete(player); - } - }, card, player); - card.clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo([card.clone])); - } - player.equiping = true; - "step 3"; - var info = get.info(card, false); - var next = game.createEvent('replaceEquip'); - next.player = player; - next.card = card; - next.setContent(info.replaceEquip || 'replaceEquip'); - "step 4"; - var info = get.info(card, false); - if (get.itemtype(result) == 'cards') { - player.lose(result, 'visible').set('type', 'equip').set('getlx', false).swapEquip = true; - if (info.loseThrow) { - player.$throw(result, 1000); - } - event.swapped = true; - } - "step 5"; - if (get.itemtype(result) == 'cards') { - for (let card of result){ - if (card.willBeDestroyed('discardPile', player, event)) { - card.selfDestroy(event); - } - } - } - "step 6"; - //if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){ - if (player.isMin() || !player.canEquip(card)) { - event.finish(); - game.cardsDiscard(card); - delete player.equiping; - return; - } - var subtype = get.subtype(card); - if (subtype == 'equip6') subtype = 'equip3'; - game.broadcastAll(function (type) { - if (lib.config.background_audio) { - game.playAudio('effect', type); - } - }, subtype); - player.$equip(card); - game.addVideo('equip', player, get.cardInfo(card)); - if (event.log != false) game.log(player, '装备了', card); - if (event.updatePile) game.updateRoundNumber(); - "step 7"; - var info = get.info(card, false); - if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) { - if (Array.isArray(info.onEquip)) { - for (var i = 0; i < info.onEquip.length; i++) { - var next = game.createEvent('equip_' + card.name); - next.setContent(info.onEquip[i]); - next.player = player; - next.card = card; - } - } - else { - var next = game.createEvent('equip_' + card.name); - next.setContent(info.onEquip); - next.player = player; - next.card = card; - } - if (info.equipDelay != false) game.delayx(); - } - delete player.equiping; - if (event.delay) { - game.delayx(); - } - }, - //装备栏 END - changeGroup: function () { - 'step 0'; - event.originGroup = player.group; - if (!event.group) event.group = player.group; - var group = event.group; - player.getHistory('custom').push(event); - if (event.broadcast !== false) { - game.broadcast(function (player, group) { - player.group = group; - player.node.name.dataset.nature = get.groupnature(group); - }, player, group); - } - player.group = group; - player.node.name.dataset.nature = get.groupnature(group); - if (event.log !== false) game.log(player, '将势力变为了', '#y' + get.translation(group + 2)); - }, - chooseToDebate: function () { - 'step 0'; - event.targets = event.list.filter(function (i) { - return i.countCards('h') > 0; - }); - if (!event.targets.length) event.result = { bool: false }; - else { - var next = player.chooseCardOL(event.targets, get.translation(player) + '发起了议事,请选择展示的手牌', true).set('type', 'debate').set('source', player).set('ai', event.ai || function (card) { - return Math.random(); - }).set('aiCard', event.aiCard || function (target) { - var hs = target.getCards('h'); - return { bool: true, cards: [hs.randomGet()] }; - }); - next._args.remove('glow_result'); - } - 'step 1'; - var red = [], black = []; - event.videoId = lib.status.videoId++; - for (var i = 0; i < event.targets.length; i++) { - var card = result[i].cards[0], target = event.targets[i]; - if (get.color(card, target) == 'red') red.push([target, card]); - else black.push([target, card]); - } - event.red = red; event.black = black; - event.trigger('debateShowOpinion'); - 'step 2' - var red = event.red, black = event.black; - if (red.length) { - game.log(red.map(function (i) { - return i[0]; - }), '意见为红色,展示了', red.map(function (i) { - return i[1]; - })); - } - else game.log('#b无人', '意见为红色'); - if (black.length) { - game.log(black.map(function (i) { - return i[0]; - }), '意见为', '#g黑色', ',展示了', black.map(function (i) { - return i[1]; - })); - } - else game.log('#b无人', '意见为', '#g黑色'); - game.broadcastAll(function (name, id, redArgs, blackArgs) { - var dialog = ui.create.dialog(name + '发起了议事', 'hidden', 'forcebutton'); - dialog.videoId = id; - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('fullwidth'); - dialog.classList.add('fullheight'); - dialog.buttonss = []; - - var list = ['意见为红色的角色', '意见为黑色的角色']; - for (var i = 0; i < list.length; i++) { - dialog.add('
                                    ' + list[i] + '
                                    '); - var buttons = ui.create.div('.buttons', dialog.content); - dialog.buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - } - var func = function (target) { - if (target._tempTranslate) return target._tempTranslate; - var name = target.name; - if (lib.translate[name + '_ab']) return lib.translate[name + '_ab']; - return get.translation(name); - }; - for (var i = 0; i < redArgs.length; i++) { - var list = redArgs[i]; - var button = ui.create.button(list[1], 'card', dialog.buttonss[0]); - button.querySelector('.info').innerHTML = func(list[0]); - } - for (var i = 0; i < blackArgs.length; i++) { - var list = blackArgs[i]; - var button = ui.create.button(list[1], 'card', dialog.buttonss[1]); - button.querySelector('.info').innerHTML = func(list[0]); - } - dialog.open(); - }, get.translation(player), event.videoId, red, black); - game.delay(4); - 'step 3'; - game.broadcastAll('closeDialog', event.videoId); - var opinion = null; - if (event.red.length > event.black.length) opinion = 'red'; - else if (event.red.length < event.black.length) opinion = 'black'; - if (opinion) game.log(player, '本次发起的议事结果为', opinion == 'red' ? '红色' : '#g黑色'); - else game.log(player, '本次发起的议事无结果'); - event.result = { - bool: true, - opinion: opinion, - red: event.red, - black: event.black, - targets: event.targets - }; - 'step 4'; - if (event.callback) { - var next = game.createEvent('debateCallback', false); - next.player = player; - next.debateResult = get.copy(event.result); - next.setContent(event.callback); - } - }, - delay: function () { - game[event.name].apply(game, event._args); - }, - chooseCooperationFor: function () { - 'step 0'; - var next = player.chooseButton([ - '选择和' + get.translation(target) + '的协力方式', - [event.cardlist, 'vcard'], - ], true); - next.set('ai', event.ai || function () { - return Math.random(); - }); - 'step 1'; - if (result.bool) { - player.cooperationWith(target, result.links[0][2].slice(12), event.reason); - } - }, - chooseToPlayBeatmap: function () { - 'step 0'; - if (game.online) return; - if (_status.connectMode) event.time = lib.configOL.choose_timeout; - event.videoId = lib.status.videoId++; - //给其他角色看的演奏框 - game.broadcastAll(function (player, id, beatmap) { - if (_status.connectMode) lib.configOL.choose_timeout = (Math.ceil((beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + (beatmap.current || 0)) / 1000) + 5).toString(); - if (player == game.me) return; - var str = get.translation(player) + '正在演奏《' + beatmap.name + '》...'; - if (!_status.connectMode) str += '
                                    (点击屏幕可以跳过等待AI操作)'; - ui.create.dialog(str).videoId = id; - if (ui.backgroundMusic) ui.backgroundMusic.pause(); - if (lib.config.background_audio) { - if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); - else game.playAudio('effect', beatmap.filename); - } - }, player, event.videoId, event.beatmap); - 'step 1'; - var beatmap = event.beatmap; - if (event.isMine()) { - var timeleap = beatmap.timeleap.slice(0); - var current = beatmap.current; - //获取两个音符的时间间隔 - var getTimeout = function () { - var time = timeleap.shift(); - var out = time - current; - current = time; - return out; - }; - //初始化一堆变量 - var score = 0; - var added = timeleap.length; - var number_of_tracks = beatmap.number_of_tracks || 6; - var custom_mapping = Array.isArray(beatmap.mapping); - var mapping = custom_mapping ? beatmap.mapping.slice() : beatmap.mapping; - var hitsound = beatmap.hitsound || 'hitsound.wav'; - if (hitsound.startsWith('ext:')) hitsound = lib.assetURL + 'extension/' + hitsound.slice(4); - else hitsound = lib.assetURL + 'audio/effect/' + hitsound; - var hitsound_audio = new Audio(hitsound); - hitsound_audio.volume = 0.25; - var abs = 1; - var node_pos = 0; - if (custom_mapping) { - node_pos = mapping.shift(); - } - else if (mapping == 'random') { - abs = get.rand(number_of_tracks); - node_pos = abs; - } - var combo = 0; - var max_combo = 0; - var nodes = []; - var roundmenu = false; - //隐藏菜单按钮 - if (ui.roundmenu && ui.roundmenu.display != 'none') { - roundmenu = true; - ui.roundmenu.style.display = 'none'; - } - if (ui.backgroundMusic) ui.backgroundMusic.pause(); - var event = _status.event; - event.settleed = false; - //建个框框 - var dialog = ui.create.dialog('forcebutton', 'hidden'); - event.dialog = dialog; - event.dialog.textPrompt = event.dialog.add('
                                    ' + (beatmap.prompt || '在音符滑条和底部判定区重合时点击屏幕!') + '
                                    '); - event.switchToAuto = function () { }; - event.dialog.classList.add('fixed'); - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - event.dialog.classList.add('fullheight'); - event.dialog.classList.add('noupdate'); - event.dialog.style.overflow = 'hidden'; - //结束后操作 - event.settle = function () { - if (event.settleed) return; - event.settleed = true; - //评分 - var acc = Math.floor(score / (added * 5) * 100); - if (!Array.isArray(lib.config.choose_to_play_beatmap_accuracies)) lib.config.choose_to_play_beatmap_accuracies = []; - lib.config.choose_to_play_beatmap_accuracies.push(acc); - if (lib.config.choose_to_play_beatmap_accuracies.length > 5) lib.config.choose_to_play_beatmap_accuracies.shift(); - game.saveConfigValue("choose_to_play_beatmap_accuracies"); - var rank; - if (acc == 100) rank = ['SS', 'metal']; - else if (acc >= 94) rank = ['S', 'orange']; - else if (acc >= 87) rank = ['A', 'wood']; - else if (acc >= 80) rank = ['B', 'water']; - else if (acc >= 65) rank = ['C', 'thunder']; - else rank = ['D', 'fire']; - event.dialog.textPrompt.innerHTML = '
                                    演奏结束!
                                    最大连击数:' + max_combo + ' 精准度:' + acc + '%
                                    '; - game.me.$fullscreenpop('演奏评级:' + rank[0] + '', null, null, false); - //返回结果并继续游戏 - setTimeout(function () { - event._result = { - bool: true, - accuracy: acc, - rank: rank, - }; - event.dialog.close(); - game.resume(); - _status.imchoosing = false; - if (roundmenu) ui.roundmenu.style.display = ''; - if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); - hitsound_audio.remove(); - }, 1000); - }; - event.dialog.open(); - //操作容差 - var height = event.dialog.offsetHeight; - var width = event.dialog.offsetWidth; - var range1 = (beatmap.range1 || [90, 110]); - var range2 = (beatmap.range2 || [93, 107]); - var range3 = (beatmap.range3 || [96, 104]); - var speed = (beatmap.speed || 25); - //初始化底部的条子 - var judger = ui.create.div(''); - judger.style["background-image"] = (beatmap.judgebar_color || 'linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))'); - judger.style["border-radius"] = '3px'; - judger.style.position = 'absolute'; - judger.style.opacity = '0.3'; - var heightj = Math.ceil(height * (beatmap.judgebar_height || 0.1)); - judger.style.height = heightj + 'px'; - judger.style.width = width + 'px'; - judger.style.left = '0px'; - judger.style.top = (height - heightj) + 'px'; - event.dialog.appendChild(judger); - //生成每个音符 - var addNode = function () { - var node = ui.create.div(''); - nodes.push(node); - node.style["background-image"] = (beatmap.node_color || 'linear-gradient(rgba(120, 120, 240, 1), rgba(100, 100, 230, 1))'); - node.style["border-radius"] = '3px'; - node.style.position = 'absolute'; - node.style.height = Math.ceil(height / 10) + 'px'; - node.style.width = Math.ceil(width / number_of_tracks) - 10 + 'px'; - node._position = get.utc(); - event.dialog.appendChild(node); - - node.style.left = Math.ceil(width * node_pos / number_of_tracks + 5) + 'px'; - node.style.top = '-' + (Math.ceil(height / 10)) + 'px'; - ui.refresh(node); - node.style.transition = 'all ' + speed * 110 + 'ms linear'; - node.style.transform = 'translateY(' + Math.ceil(height * 1.1) + 'px)'; - node.timeout = setTimeout(function () { - if (nodes.includes(node)) { - nodes.remove(node); - player.popup('Miss', 'fire', false); - if (player.damagepopups.length) player.$damagepop(); - combo = 0; - } - }, speed * 110); - - if (custom_mapping) { - node_pos = mapping.shift(); - } - else if (mapping == 'random') { - while (node_pos == abs) { - node_pos = get.rand(number_of_tracks); - } - abs = node_pos; - } - else { - node_pos += abs; - if (node_pos > number_of_tracks - 1) { - abs = -1; - node_pos = number_of_tracks - 2; - } - else if (node_pos < 0) { - abs = 1; - node_pos = 1; - } - } - if (timeleap.length) { - setTimeout(function () { - addNode(); - }, getTimeout()); - } - else { - setTimeout(function () { - event.settle(); - }, speed * 110 + 100); - } - }; - //点击时的判断操作 - var click = function () { - if (!nodes.length) return; - for (var node of nodes) { - //用生成到点击的时间差来判断距离 - var time = get.utc(); - var top = (time - node._position) / speed; - if (top > range1[1]) continue; - else if (top < range1[0]) return; - nodes.remove(node); - clearTimeout(node.timeout); - node.style.transform = ''; - node.style.transition = 'all 0s'; - node.style.top = (height * ((top - 10) / 100)) + 'px'; - ui.refresh(node); - node.style.transition = 'all 0.5s'; - node.style.transform = 'scale(1.2)'; - node.delete(); - if (top >= range3[0] && top < range3[1]) { - score += 5; - player.popup('Perfect', 'orange', false); - } - else if (top >= range2[0] && top < range2[1]) { - score += 3; - player.popup('Great', 'wood', false); - } - else { - score += 1; - player.popup('Good', 'soil', false); - } - if (player.damagepopups.length) player.$damagepop(); - combo++; - max_combo = Math.max(combo, max_combo); - hitsound_audio.currentTime = 0; - if (hitsound_audio.paused) Promise.resolve(hitsound_audio.play()).catch(() => void 0); - break; - } - }; - document.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', click); - - game.pause(); - game.countChoose(); - setTimeout(() => { - if (!lib.config.background_audio) return; - if (beatmap.filename.startsWith('ext:')) game.playAudio(beatmap.filename); - else game.playAudio('effect', beatmap.filename); - }, Math.floor(speed * 100 * (0.9 + beatmap.judgebar_height)) + beatmap.current); - setTimeout(function () { - addNode(); - }, getTimeout()); - } - else if (event.isOnline()) { - event.send(); - } - else { - game.pause(); - game.countChoose(); - var settle = function () { - _status.imchoosing = false; - //Algorithm: Generate the random number range using the mean and the half standard deviation of accuracies of the player's last 5 plays - //算法:用玩家的上5次游玩的准确率的平均数和半标准差生成随机数范围 - var choose_to_play_beatmap_accuracies = (lib.config.choose_to_play_beatmap_accuracies || []).concat(Array.from({ - length: 6 - (lib.config.choose_to_play_beatmap_accuracies || []).length - }, () => get.rand(70, 100))); - var mean = Math.round(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + currentValue) / choose_to_play_beatmap_accuracies.length); - var half_standard_deviation = Math.round(Math.sqrt(choose_to_play_beatmap_accuracies.reduce((previousValue, currentValue) => previousValue + Math.pow(currentValue - mean, 2), 0)) / 2); - var acc = Math.min(Math.max(get.rand.apply(get, beatmap.aiAcc || [mean - half_standard_deviation - get.rand(0, half_standard_deviation), mean + half_standard_deviation + get.rand(0, half_standard_deviation)]), 0), 100); - var rank; - if (acc == 100) rank = ['SS', 'metal']; - else if (acc >= 94) rank = ['S', 'orange']; - else if (acc >= 87) rank = ['A', 'green']; - else if (acc >= 80) rank = ['B', 'water']; - else if (acc >= 65) rank = ['C', 'thunder']; - else rank = ['D', 'fire']; - event._result = { - bool: true, - accuracy: acc, - rank: rank, - }; - if (event.dialog) event.dialog.close(); - if (event.control) event.control.close(); - game.resume(); - }; - var song_duration = beatmap.timeleap[beatmap.timeleap.length - 1] + beatmap.speed * 100 + 1000 + (beatmap.current || 0); - var settle_timeout = setTimeout(settle, song_duration); - if (!_status.connectMode) { - var skip_timeout; - var skip = () => { - settle(); - Array.from(ui.window.getElementsByTagName('audio')).forEach(audio => { - if (audio.currentSrc.includes(beatmap.filename.startsWith('ext:') ? beatmap.name : beatmap.filename)) audio.remove(); - }); - document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); - clearTimeout(settle_timeout); - clearTimeout(skip_timeout); - }; - document.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip); - skip_timeout = setTimeout(() => document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', skip), song_duration); - } - } - 'step 2'; - game.broadcastAll(function (id, time) { - if (_status.connectMode) lib.configOL.choose_timeout = time; - var dialog = get.idDialog(id); - if (dialog) { - dialog.close(); - } - if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); - }, event.videoId, event.time); - var result = event.result || result; - event.result = result; - }, - chooseToMove: function () { - 'step 0'; - if (event.chooseTime && _status.connectMode && !game.online) { - event.time = lib.configOL.choose_timeout; - game.broadcastAll(function (time) { - lib.configOL.choose_timeout = time; - }, event.chooseTime); - } - if (event.isMine()) { - delete ui.selected.guanxing_button; - var list = event.list, filterMove = event.filterMove, filterOk = event.filterOk; - _status.imchoosing = true; - var event = _status.event; - event.settleed = false; - event.dialog = ui.create.dialog(event.prompt || '请选择要操作的牌', 'hidden', 'forcebutton'); - event.switchToAuto = function () { - if (!filterOk(event.moved)) { - if (!event.forced) event._result = { bool: false }; - else event._result = 'ai'; - } - else { - event._result = { - bool: true, - moved: event.moved, - }; - } - event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.resume(); - _status.imchoosing = false; - setTimeout(function () { - ui.arena.classList.remove('choose-to-move'); - }, 500); - }; - event.dialog.classList.add('scroll1'); - event.dialog.classList.add('scroll2'); - event.dialog.classList.add('fullwidth'); - if (list.length > 1) { - ui.arena.classList.add('choose-to-move'); - event.dialog.classList.add('fullheight'); - } - - event.moved = []; - var buttonss = []; - event.buttonss = buttonss; - var updateButtons = function () { - for (var i of buttonss) { - event.moved[i._link] = get.links(Array.from(i.childNodes)); - if (i.textPrompt) i.previousSibling.innerHTML = ('
                                    ' + i.textPrompt(event.moved[i._link]) + '
                                    '); - } - if (filterOk(event.moved)) { - ui.create.confirm('o'); - } - else { - if (!event.forced) ui.create.confirm('c'); - else if (ui.confirm) ui.confirm.close(); - } - }; - var clickButtons = function () { - if (!ui.selected.guanxing_button) return; - if (ui.selected.guanxing_button.parentNode == this) return; - if (!filterMove(ui.selected.guanxing_button, this._link, event.moved)) return; - ui.selected.guanxing_button.classList.remove('glow2'); - this.appendChild(ui.selected.guanxing_button); - delete ui.selected.guanxing_button; - updateButtons(); - }; - - for (var i = 0; i < list.length; i++) { - var tex = event.dialog.add('
                                    ' + list[i][0] + '
                                    '); - tex.classList.add('choosetomove'); - var buttons = ui.create.div('.buttons', event.dialog.content, clickButtons); - buttonss.push(buttons); - buttons.classList.add('popup'); - buttons.classList.add('guanxing'); - buttons._link = i; - if (list[i][1]) { - if (get.itemtype(list[i][1]) == 'cards') { - var cardsb = ui.create.buttons(list[i][1], 'card', buttons); - if (list[i][2] && typeof list[i][2] == 'string') { - for (var ij of cardsb) ij.node.gaintag.innerHTML = get.translation(list[i][2]); - } - } - else if (list[i][1].length == 2) { - ui.create.buttons(list[i][1][0], list[i][1][1], buttons); - } - } - if (list[i][2] && typeof list[i][2] == 'function') buttons.textPrompt = list[i][2]; - } - var tex = event.dialog.add('
                                    点击两张牌以交换位置;点击一张牌并点击其他区域以移动卡牌
                                    '); - tex.classList.add('choosetomove'); - - event.dialog.open(); - updateButtons(); - - event.custom.replace.button = function (button) { - var node = button.parentNode; - if (!buttonss.includes(node)) return; - if (!ui.selected.guanxing_button) { - ui.selected.guanxing_button = button; - button.classList.add('glow2'); - return; - } - if (ui.selected.guanxing_button == button) { - button.classList.remove('glow2'); - delete ui.selected.guanxing_button; - return; - } - if (!filterMove(button, ui.selected.guanxing_button, event.moved)) return; - var par1 = ui.selected.guanxing_button.parentNode, ind1 = ui.selected.guanxing_button.nextSibling, par2 = button.parentNode, ind2 = button.nextSibling; - ui.selected.guanxing_button.classList.remove('glow2'); - par1.insertBefore(button, ind1); - par2.insertBefore(ui.selected.guanxing_button, ind2); - delete ui.selected.guanxing_button; - updateButtons(); - }; - event.custom.replace.confirm = function (bool) { - if (bool) event._result = { - bool: true, - moved: event.moved, - }; - else event._result = { bool: false }; - event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.resume(); - _status.imchoosing = false; - setTimeout(function () { - ui.arena.classList.remove('choose-to-move'); - }, 500); - }; - - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.time) game.broadcastAll(function (time) { - lib.configOL.choose_timeout = time; - }, event.time); - var result = event.result || result; - if ((!result || result == 'ai' || (event.forced && !result.bool)) && event.processAI) { - var moved = event.processAI(event.list); - if (moved) result = { - bool: true, - moved: moved, - }; - else result = { bool: false }; - } - event.result = result; - }, - showCharacter: function () { - 'step 0'; - event.trigger('showCharacterEnd'); - 'step 1'; - event.trigger('showCharacterAfter'); - if (get.mode() == 'identity' && player.isZhu) event.trigger('zhuUpdate'); - }, - removeCharacter: function () { - player.$removeCharacter(event.num); - }, - chooseUseTarget: function () { - 'step 0'; - if (get.is.object(card) && event.viewAs === false) card.isCard = true; - if (cards && get.itemtype(card) != 'card') { - card = get.copy(card); - card.cards = cards.slice(0); - event.card = card; - } - let evt = event.getParent('chooseToUse'); - if (get.itemtype(evt) !== 'event') evt = event; - if (!lib.filter.cardEnabled(card, player) || event.addCount !== false && - !lib.filter.cardUsable(card, player, evt)) { - event.result = { bool: false }; - event.finish(); - return; - } - var info = get.info(card); - var range; - if (!info.notarget) { - var select = get.copy(info.selectTarget); - range = get.select(select); - if (event.selectTarget) range = get.select(event.selectTarget); - game.checkMod(card, player, range, 'selectTarget', player); - } - if (info.notarget || range[1] <= -1) { - if (!info.notarget && range[1] <= -1) { - for (var i = 0; i < targets.length; i++) { - if (event.filterTarget) { - if (!event.filterTarget(card, player, targets[i])) { - targets.splice(i--, 1); - } - } - else if (!player.canUse(card, targets[i], event.nodistance ? false : null, event.addCount === false ? null : true)) { - targets.splice(i--, 1); - } - } - if (targets.length) { - event.targets2 = targets; - } - else { - event.finish(); - return; - } - } - else event.targets2 = []; - if (event.forced) { - event._result = { bool: true }; - return; - } - else { - var next = player.chooseBool(); - next.set('prompt', event.prompt || ('是否' + (event.targets2.length ? '对' : '') + get.translation(event.targets2) + '使用' + get.translation(card) + '?')); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - if (event.prompt2) next.set('prompt2', event.prompt2); - next.ai = function () { - var eff = 0; - for (var i = 0; i < event.targets2.length; i++) { - eff += get.effect(event.targets2[i], card, player, player); - } - return eff > 0; - }; - } - } - else { - if (event.filterTarget) { - var targets = game.filterPlayer(function (current) { - return event.filterTarget(card, player, current); - }); - if (targets.length < range[0]) { - event._result = { bool: false }; - return; - } - else if (!info.complexTarget && targets.length == range[0] && range[0] == range[1]) { - event.targets2 = targets; - event._result = { bool: true }; - return; - } - } - var next = player.chooseTarget(); - next.set('_get_card', card); - next.set('filterTarget', event.filterTarget || function (card, player, target) { - if (!_status.event.targets.includes(target)) return false; - if (!_status.event.nodistance && !lib.filter.targetInRange(card, player, target)) return false; - return lib.filter.targetEnabledx(card, player, target); - }); - next.set('ai', event.ai || get.effect_use); - next.set('selectTarget', event.selectTarget || lib.filter.selectTarget); - if (event.nodistance) next.set('nodistance', true); - if (event.forced) next.set('forced', true); - if (event.addCount !== false) next.set('addCount_extra', true); - next.set('targets', targets); - next.set('prompt', event.prompt || ('选择' + get.translation(card) + '的目标')); - if (event.prompt2) next.set('prompt2', event.prompt2); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - } - 'step 1'; - if (result.bool) { - event.result = { - bool: true, - targets: event.targets2 || result.targets, - }; - var args = [card, event.targets2 || result.targets]; - if (cards) args.push(cards.slice()); - var next = player.useCard(...args); - next.oncard = event.oncard; - if (cards) next.cards = cards.slice(0); - if (event.nopopup) next.nopopup = true; - if (event.animate === false) next.animate = false; - if (event.throw === false) next.throw = false; - if (event.addCount === false) next.addCount = false; - if (event.noTargetDelay) next.targetDelay = false; - if (event.nodelayx) next.delayx = false; - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - next.skill = event.logSkill; - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - } - else event.result = { bool: false }; - }, - chooseToDuiben: function () { - 'step 0'; - if (!event.namelist) event.namelist = ['全军出击', '分兵围城', '奇袭粮道', '开城诱敌']; - game.broadcastAll(function (list) { - var list2 = ['db_atk1', 'db_atk2', 'db_def1', 'db_def2']; - for (var i = 0; i < 4; i++) { - lib.card[list2[i]].image = 'card/' + list2[i] + (list[0] == '全军出击' ? '' : '_' + list[i]); - lib.translate[list2[i]] = list[i]; - } - }, event.namelist); - if (!event.title) event.title = '对策'; - game.log(player, '向', target, '发起了', '#y' + event.title); - if (!event.ai) event.ai = function () { return 1 + Math.random(); }; - if (_status.connectMode) { - player.chooseButtonOL([ - [player, [event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true], - [target, [event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true] - ], function () { }, event.ai).set('switchToAuto', function () { - _status.event.result = 'ai'; - }).set('processAI', function () { - var buttons = _status.event.dialog.buttons; - return { - bool: true, - links: [buttons.randomGet().link], - }; - }); - } - 'step 1'; - if (_status.connectMode) { - event.mes = result[player.playerid].links[0][2]; - event.tes = result[target.playerid].links[0][2]; - event.goto(4); - } - else { - player.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_def2'], ['', '', 'db_def1']], 'vcard']], true).ai = event.ai; - } - 'step 2'; - event.mes = result.links[0][2]; - target.chooseButton([event.title + ':请选择一种策略', [[['', '', 'db_atk1'], ['', '', 'db_atk2']], 'vcard']], true).ai = event.ai; - 'step 3'; - event.tes = result.links[0][2]; - 'step 4'; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - target.$compare(game.createCard(event.tes, '', ''), player, game.createCard(event.mes, '', '')); - game.log(target, '选择的策略为', '#g' + get.translation(event.tes)); - game.log(player, '选择的策略为', '#g' + get.translation(event.mes)); - game.delay(0, 1500); - 'step 5'; - var mes = event.mes.slice(6); - var tes = event.tes.slice(6); - var str; - if (mes == tes) { - str = get.translation(player) + event.title + '成功'; - player.popup('胜', 'wood'); - target.popup('负', 'fire'); - game.log(player, '#g胜'); - event.result = { bool: true }; - } - else { - str = get.translation(player) + event.title + '失败'; - target.popup('胜', 'wood'); - player.popup('负', 'fire'); - game.log(target, '#g胜'); - event.result = { bool: false }; - } - event.result.player = event.mes; - event.result.target = event.tes; - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.trySkillAudio(event.getParent().name + '_' + (event.result.bool ? 'true' + mes : 'false'), player); - game.delay(2); - 'step 6'; - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - }, - chooseToPSS: function () { - 'step 0'; - game.log(player, '对', target, '发起了猜拳'); - if (_status.connectMode) { - player.chooseButtonOL([ - [player, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true], - [target, ['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true] - ], function () { }, function () { return 1 + Math.random(); }).set('switchToAuto', function () { - _status.event.result = 'ai'; - }).set('processAI', function () { - var buttons = _status.event.dialog.buttons; - return { - bool: true, - links: [buttons.randomGet().link], - }; - }); - } - 'step 1'; - if (_status.connectMode) { - event.mes = result[player.playerid].links[0][2]; - event.tes = result[target.playerid].links[0][2]; - event.goto(4); - } - else { - player.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; - } - 'step 2'; - event.mes = result.links[0][2]; - target.chooseButton(['猜拳:请选择一种手势', [[['', '', 'pss_stone'], ['', '', 'pss_scissor'], ['', '', 'pss_paper']], 'vcard']], true).ai = function () { return 1 + Math.random(); }; - 'step 3'; - event.tes = result.links[0][2]; - 'step 4'; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(game.createCard(event.mes, '', ''), target, game.createCard(event.tes, '', '')); - game.log(player, '选择的手势为', '#g' + get.translation(event.mes)); - game.log(target, '选择的手势为', '#g' + get.translation(event.tes)); - game.delay(0, 1500); - 'step 5'; - var mes = event.mes.slice(4); - var tes = event.tes.slice(4); - var str; - if (mes == tes) { - str = '二人平局'; - player.popup('平', 'metal'); - target.popup('平', 'metal'); - game.log('猜拳的结果为', '#g平局'); - event.result = { tie: true }; - } - else { - if ({ paper: 'stone', scissor: 'paper', stone: 'scissor' }[mes] == tes) { - str = get.translation(player) + '胜利'; - player.popup('胜', 'wood'); - target.popup('负', 'fire'); - game.log(player, '#g胜'); - event.result = { bool: true }; - } - else { - str = get.translation(target) + '胜利'; - target.popup('胜', 'wood'); - player.popup('负', 'fire'); - game.log(target, '#g胜'); - event.result = { bool: false }; - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - 'step 6'; - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - }, - cardsDiscard: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('discardPile', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].discard(); - } - if (withPile) game.updateRoundNumber(); - }, - orderingDiscard: function () { - var cards = event.relatedEvent.orderingCards.slice(0); - for (var i = 0; i < cards.length; i++) { - if (get.position(cards[i], true) != 'o') cards.splice(i--, 1); - } - if (cards.length) game.cardsDiscard(cards); - }, - cardsGotoOrdering: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('ordering', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].fix(); - ui.ordering.appendChild(cards[i]); - } - if (withPile) game.updateRoundNumber(); - var evt = event.relatedEvent || event.getParent(); - if (!evt.orderingCards) evt.orderingCards = []; - if (!evt.noOrdering && !evt.cardsOrdered) { - evt.cardsOrdered = true; - var next = game.createEvent('orderingDiscard', false); - event.next.remove(next); - evt.after.push(next); - next.relatedEvent = evt; - next.setContent('orderingDiscard'); - } - if (!evt.noOrdering) evt.orderingCards.addArray(cards); - }, - cardsGotoSpecial: function () { - game.getGlobalHistory().cardMove.push(event); - var withPile = false; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('special', null, event)) { - cards[i].selfDestroy(event); - continue; - } - if (get.position(cards[i], true) == 'c') withPile = true; - cards[i].fix(); - ui.special.appendChild(cards[i]); - } - if (withPile) game.updateRoundNumber(); - if (event.toRenku) { - _status.renku.addArray(cards); - if (_status.renku.length > 6) { - var cards = _status.renku.splice(0, _status.renku.length - 6); - game.log(cards, '从仁库进入了弃牌堆'); - game.cardsDiscard(cards).set('outRange', true).fromRenku = true; - } - game.updateRenku(); - } - }, - cardsGotoPile: function () { - if (event.washCard) { - event.trigger('washCard'); - for (var i = 0; i < lib.onwash.length; i++) { - if (lib.onwash[i]() == 'remove') { - lib.onwash.splice(i--, 1); - } - } - } - game.getGlobalHistory().cardMove.push(event); - if (!event._triggeronly) game.$cardsGotoPile(event); - }, - chooseToEnable: function () { - 'step 0'; - var list = []; - for (var i = 1; i <= 5; i++) { - if (player.hasDisabledSlot(i)) list.push('equip' + i); - } - if (!list.length) event.finish(); - else if (list.length == 1) { - event.list = list; - event._result = { control: list[0] }; - } - else { - var next = source.chooseControl(list); - next.set('prompt', '请选择恢复'+get.translation(player.name)+'的一个装备栏'); - if (!event.ai) event.ai = function (event, player, list) { - return list.randomGet(); - }; - event.ai = event.ai(event.getParent(), player, list); - next.ai = function () { - return event.ai; - }; - } - 'step 1'; - event.result = { control: result.control }; - player.enableEquip(result.control); - }, - chooseToDisable: function () { - 'step 0'; - var list = []; - for (var i = 1; i <= 5; i++) { - if (player.hasEnabledSlot(i)) list.push('equip' + i); - } - if (event.horse) { - if (list.includes('equip3') && (get.is.mountCombined() || list.includes('equip4'))) list.push('equip3_4'); - list.remove('equip3'); - list.remove('equip4'); - } - if (!list.length) event.finish(); - else if (list.length == 1) { - event.list = list; - event._result = { control: list[0] }; - } - else { - list.sort(); - event.list = list; - var next = source.chooseControl(list); - next.set('prompt', '请选择废除'+get.translation(player.name)+'的一个装备栏'); - if (!event.ai) event.ai = function (event, player, list) { - return list.randomGet(); - }; - event.ai = event.ai(event.getParent(), player, list); - next.ai = function () { - return event.ai; - }; - } - 'step 1'; - event.result = { control: result.control }; - if (result.control == 'equip3_4') { - player.disableEquip(3, 4); - } - else player.disableEquip(result.control); - }, - swapEquip: function () { - "step 0"; - game.log(player, '和', target, '交换了装备区中的牌'); - event.cards = [player.getCards('e'), target.getCards('e')]; - game.loseAsync({ - player: player, - target: target, - cards1: event.cards[0], - cards2: event.cards[1], - }).setContent('swapHandcardsx'); - "step 1"; - for (var i = 0; i < event.cards[1].length; i++) { - if (get.position(event.cards[1][i], true) == 'o') player.equip(event.cards[1][i]); - } - for (var i = 0; i < event.cards[0].length; i++) { - if (get.position(event.cards[0][i], true) == 'o') target.equip(event.cards[0][i]); - } - }, - disableJudge: function () { - 'step 0'; - game.log(player, '废除了判定区'); - var js = player.getCards('j'); - if (js.length) player.discard(js); - player.storage._disableJudge = true; - //player.markSkill('_disableJudge'); - 'step 1'; - game.broadcastAll(function (player, card) { - player.$disableJudge(); - }, player); - }, - enableJudge: function () { - if (!player.storage._disableJudge) return; - game.log(player, '恢复了判定区'); - game.broadcastAll(function (player) { - player.$enableJudge(); - }, player); - }, - /*----分界线----*/ - phasing: function () { - 'step 0'; - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - game.phaseNumber++; - player.phaseNumber++; - game.broadcastAll(function (player, player2, num, popup) { - if (lib.config.glow_phase) { - if (player2) player2.classList.remove('glow_phase'); - player.classList.add('glow_phase'); - } - player.phaseNumber = num; - if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); - }, player, _status.currentPhase, player.phaseNumber, !player.noPhaseDelay); - _status.currentPhase = player; - _status.discarded = []; - game.syncState(); - game.addVideo('phaseChange', player); - if (game.phaseNumber == 1) { - delete player._start_cards; - if (lib.configOL.observe) { - lib.configOL.observeReady = true; - game.send('server', 'config', lib.configOL); - } - } - game.log(); - game.log(player, '的回合开始'); - player._noVibrate = true; - if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { - var num; - switch (get.config('auto_identity')) { - case 'one': num = 1; break; - case 'two': num = 2; break; - case 'three': num = 3; break; - case 'always': num = -1; break; - default: num = 0; break; - } - if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { - if (!_status.video) player.popup('显示身份'); - _status.identityShown = true; - game.showIdentity(false); - } - } - player.ai.tempIgnore = []; - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - 'step 1'; - event.trigger('phaseBeginStart'); - }, - toggleSubPlayer: function () { - 'step 0'; - var list = event.list || player.storage.subplayer.skills.slice(0); - list.remove(player.storage.subplayer.name2); - event.list = list; - if (!event.directresult) { - if (list.length > 1) { - var dialog = ui.create.dialog('更换一个随从', 'hidden'); - dialog.add([list, 'character']); - player.chooseButton(dialog, true); - } - else if (list.length == 1) { - event.directresult = list[0]; - } - else { - event.finish(); - } - } - else { - if (!list.includes(event.directresult)) { - event.finish(); - } - } - 'step 1'; - if (!event.directresult) { - if (result && result.bool && result.links[0]) { - event.directresult = result.links[0]; - } - else { - event.finish(); - return; - } - } - if (player.storage.subplayer) { - var current = player.storage.subplayer.name2; - if (event.directresult == current) { - event.finish(); - return; - } - player.storage[current].hp = player.hp; - player.storage[current].maxHp = player.maxHp; - player.storage[current].hs = player.getCards('h'); - player.storage[current].es = player.getCards('e'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - - var cfg = player.storage[event.directresult]; - player.storage.subplayer.name2 = event.directresult; - player.reinit(current, event.directresult, [ - cfg.hp, - cfg.maxHp - ]); - if (cfg.hs.length) player.directgain(cfg.hs); - if (cfg.es.length) player.directequip(cfg.es); - } - }, - exitSubPlayer: function () { - 'step 0'; - if (player.storage.subplayer) { - var current = player.storage.subplayer.name2; - if (event.remove) { - player.lose(player.getCards('he'), ui.discardPile)._triggered = null; - } - else { - player.storage[current].hp = player.hp; - player.storage[current].maxHp = player.maxHp; - player.storage[current].hs = player.getCards('h'); - player.storage[current].es = player.getCards('e'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - } - player.reinit(current, player.storage.subplayer.name, [ - player.storage.subplayer.hp, - player.storage.subplayer.maxHp - ]); - player.update(); - if (event.remove) { - if (player.storage[current].onremove) { - player.storage[current].onremove(player); - } - delete player.storage[current]; - player.storage.subplayer.skills.remove(current); - game.log(player, '牺牲了随从', '#g' + current); - } - else { - game.log(player, '收回了随从', '#g' + current); - } - player.addSkill(player.storage.subplayer.skills); - } - 'step 1'; - if (player.storage.subplayer) { - player.directgain(player.storage.subplayer.hs); - player.directequip(player.storage.subplayer.es); - } - player.removeSkill('subplayer'); - 'step 2'; - if (event.remove) { - event.trigger('subPlayerDie'); - } - }, - callSubPlayer: function () { - 'step 0'; - var list = player.getSubPlayers(event.tag); - event.list = list; - if (!event.directresult) { - if (list.length > 1) { - var dialog = ui.create.dialog('调遣一个随从', 'hidden'); - dialog.add([list, 'character']); - player.chooseButton(dialog, true); - } - else if (list.length == 1) { - event.directresult = list[0]; - } - else { - event.finish(); - } - } - else { - if (!list.includes(event.directresult)) { - event.finish(); - } - } - 'step 1'; - if (!event.directresult) { - if (result && result.bool && result.links[0]) { - event.directresult = result.links[0]; - } - else { - event.finish(); - return; - } - } - if (event.directresult) { - var cfg = player.storage[event.directresult]; - var source = cfg.source || player.name; - var name = event.directresult; - game.log(player, '调遣了随从', '#g' + name); - player.storage.subplayer = { - name: source, - name2: event.directresult, - hp: player.hp, - maxHp: player.maxHp, - skills: event.list.slice(0), - hs: player.getCards('h'), - es: player.getCards('e'), - intro2: cfg.intro2 - }; - player.removeSkill(event.list); - player.reinit(source, name, [cfg.hp, cfg.maxHp]); - player.addSkill('subplayer'); - player.lose(player.getCards('he'), ui.special)._triggered = null; - if (cfg.hs.length) player.directgain(cfg.hs); - if (cfg.es.length) player.directequip(cfg.es); - } - 'step 2'; - game.delay(); - }, - addExtraTarget: function () { - "step 0"; - event.num = 0; - "step 1"; - var target = targets[num], info = get.info(card); - if (target == event.target && event.addedTarget) { - event.addedTargets[num] = event.addedTarget; - event._result = { bool: false }; - } - else if (game.hasPlayer(function (current) { - return info.filterAddedTarget(card, player, current, target); - })) { - var next = player.chooseTarget(get.translation(event.card) + ':选择' + get.translation(targets[num]) + '对应的指向目标', function (card, player, target) { - var card = get.card(), info = get.info(card); - return info.filterAddedTarget(card, player, target, _status.event.preTarget); - }, true); - next.set('_get_card', card); - next.set('preTarget', targets[num]); - next.set('ai', target => get.effect(target, get.card(), player, _status.event.player)); - } - else { - event.addedTargets[num] = false; - event._result = { bool: false }; - } - "step 2"; - if (result.bool) { - event.addedTargets[num] = result.targets[0]; - player.line2([targets[num], result.targets[0]]); - } - event.num++; - if (event.num < targets.length) event.goto(1); - }, - reverseOrder: function () { - "step 0"; - game.delay(); - "step 1"; - var choice; - if (get.tag(card, 'multineg')) { - choice = (player.previous.side == player.side) ? '逆时针' : '顺时针'; - } - else { - choice = (player.next.side == player.side) ? '逆时针' : '顺时针'; - } - player.chooseControl('顺时针', '逆时针', function (event, player) { - return _status.event.choice || '逆时针'; - }).set('prompt', '选择' + get.translation(card) + '的结算方向').set('choice', choice).set('forceDie', true); - "step 2"; - if (result && result.control == '顺时针') { - var evt = event.getParent(), sorter = (_status.currentPhase || player); - evt.fixedSeat = true; - evt.targets.sortBySeat(sorter); - evt.targets.reverse(); - if (evt.targets[evt.targets.length - 1] == sorter) { - evt.targets.unshift(evt.targets.pop()); - } - } - }, - addJudgeCard: function () { - if (lib.filter.judge(card, player, target) && cards.length && get.position(cards[0], true) == 'o') target.addJudge(card, cards); - }, - equipCard: function () { - if (cards.length && get.position(cards[0], true) == 'o') target.equip(cards[0]); - }, - gameDraw: function () { - "step 0"; - if (_status.brawl && _status.brawl.noGameDraw) { - event.finish(); - return; - } - var end = player; - var numx = num; - do { - if (typeof num == 'function') { - numx = num(player); - } - if (player.getTopCards) player.directgain(player.getTopCards(numx)); - else player.directgain(get.cards(numx)); - if (player.singleHp === true && get.mode() != 'guozhan' && (lib.config.mode != 'doudizhu' || _status.mode != 'online')) { - player.doubleDraw(); - } - player._start_cards = player.getCards('h'); - player = player.next; - } - while (player != end); - event.changeCard = get.config('change_card'); - if (_status.connectMode || - (lib.config.mode == 'single' && _status.mode != 'wuxianhuoli') || - (lib.config.mode == 'doudizhu' && _status.mode == 'online') || - lib.config.mode != 'identity' && lib.config.mode != 'guozhan' && lib.config.mode != 'doudizhu' && lib.config.mode != 'single') { - event.changeCard = 'disabled'; - } - "step 1"; - if (event.changeCard != 'disabled' && !_status.auto) { - event.dialog = ui.create.dialog('是否使用手气卡?'); - ui.create.confirm('oc'); - event.custom.replace.confirm = function (bool) { - _status.event.bool = bool; - game.resume(); - }; - } - else { - event.finish(); - } - "step 2"; - if (event.changeCard == 'once') { - event.changeCard = 'disabled'; - } - else if (event.changeCard == 'twice') { - event.changeCard = 'once'; - } - else if (event.changeCard == 'disabled') { - event.bool = false; - return; - } - _status.imchoosing = true; - event.switchToAuto = function () { - _status.event.bool = false; - game.resume(); - }; - game.pause(); - "step 3"; - _status.imchoosing = false; - if (event.bool) { - if (game.changeCoin) { - game.changeCoin(-3); - } - var hs = game.me.getCards('h'); - game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - game.me.directgain(get.cards(hs.length)); - event.goto(2); - } - else { - if (event.dialog) event.dialog.close(); - if (ui.confirm) ui.confirm.close(); - game.me._start_cards = game.me.getCards('h'); - event.finish(); - } - }, - phaseLoop: function () { - "step 0"; - var num = 1, current = player; - while (current.getSeatNum() == 0) { - current.setSeatNum(num); - current = current.next; - num++; - } - "step 1"; - for (var i = 0; i < lib.onphase.length; i++) { - lib.onphase[i](); - } - player.phase(); - "step 2"; - if (!game.players.includes(event.player.next)) { - event.player = game.findNext(event.player.next); - } - else { - event.player = event.player.next; - } - event.goto(1); - }, - loadPackage: function () { - 'step 0'; - if (event.packages.length) { - window.game = game; - var pack = event.packages.shift().split('/'); - lib.init.js(lib.assetURL + pack[0], pack[1], game.resume); - game.pause(); - } - else { - event.finish(); - } - 'step 1'; - if (!lib.config.dev) delete window.game; - var character = lib.imported.character; - var card = lib.imported.card; - var i, j, k; - for (i in character) { - if (character[i].character) { - var characterPack = lib.characterPack[i]; - if (characterPack) Object.assign(characterPack, character[i].character); - else lib.characterPack[i] = character[i].character; - } - if (character[i].forbid && character[i].forbid.includes(lib.config.mode)) continue; - if (character[i].mode && character[i].mode.includes(lib.config.mode) == false) continue; - - if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { - lib[j].addArray(character[i][j]); - continue; - } - for (j in character[i]) { - if (j == 'mode' || j == 'forbid' || j == 'characterSort') continue; - for (k in character[i][j]) { - if (j == 'character') { - if (!character[i][j][k][4]) { - character[i][j][k][4] = []; - } - if (character[i][j][k][4].includes('boss') || - character[i][j][k][4].includes('hiddenboss')) { - lib.config.forbidai.add(k); - } - if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { - lib.config.forbidai.add(k); - } - for (var l = 0; l < character[i][j][k][3].length; l++) { - lib.skilllist.add(character[i][j][k][3][l]); - } - } - if (j == 'translate' && k == i) { - lib[j][k + '_character_config'] = character[i][j][k]; - } - else { - if (lib[j][k] == undefined) { - Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(character[i][j], k)); - } - else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { - lib[j][k].addArray(character[i][j][k]); - } - else { - console.log( - `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, - lib[j][k], - `\ncharacter.${i}.${j}.${k}`, - character[i][j][k] - ); - } - } - } - } - } - for (i in card) { - var cardPack = lib.cardPack[i] ? lib.cardPack[i] : lib.cardPack[i] = []; - if (card[i].card) { - for (var j in card[i].card) { - if (!card[i].card[j].hidden && card[i].translate[j + '_info']) { - cardPack.push(j); - } - } - } - for (j in card[i]) { - if (j == 'mode' || j == 'forbid') continue; - if (j == 'list') continue; - for (k in card[i][j]) { - if (j == 'skill' && k[0] == '_' && !lib.config.cards.includes(i)) { - continue; - } - if (j == 'translate' && k == i) { - lib[j][k + '_card_config'] = card[i][j][k]; - } - else { - if (lib[j][k] == undefined) Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(card[i][j], k)); - else { - console.log( - `dublicate ${j} in card ${i}:\n${k}\nlib.${j}.${k}`, - lib[j][k], - `\ncard.${i}.${j}.${k}`, - card[i][j][k] - ); - } - } - } - } - } - event.goto(0); - }, - loadMode: function () { - 'step 0'; - window.game = game; - lib.init.js(lib.assetURL + 'mode', event.mode, game.resume); - game.pause(); - 'step 1'; - if (!lib.config.dev) delete window.game; - event.result = lib.imported.mode[event.mode]; - delete lib.imported.mode[event.mode]; - }, - forceOver: function () { - 'step 0'; - while (ui.controls.length) { - ui.controls[0].close(); - } - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - 'step 1'; - if (event.bool != 'noover') { - game.over(event.bool); - } - if (event.callback) { - event.callback(); - } - }, - arrangeTrigger: async function (event,trigger,player) { - const doingList = event.doingList.slice(0); - - while(doingList.length>0){ - event.doing = doingList.shift(); - while(true){ - if (trigger.filterStop && trigger.filterStop()) return; - const usableSkills = event.doing.todoList.filter(info => { - return lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill, info.indexedData); - }); - if (usableSkills.length == 0){ - break; - } - else { - event.doing.todoList = event.doing.todoList.filter(i => i.priority <= usableSkills[0].priority); - //firstDo时机和lastDo时机不进行技能优先级选择 - if (get.itemtype(event.doing.player) !== 'player'){ - event.current = usableSkills[0]; - } - else { - event.choice = usableSkills.filter(n => n.priority == usableSkills[0].priority); - //现在只要找到一个同优先度技能为silent,或没有技能描述的技能 便优先执行该技能 - const silentSkill = event.choice.find(item => { - const skillInfo = lib.skill[item.skill]; - return (skillInfo && (skillInfo.silent || !lib.translate[item.skill])); - }) - if (silentSkill){ - event.current = silentSkill; - } - else { - const currentChoice = event.choice[0], skillsToChoose = event.choice.map(i => i.skill).unique(); - if (event.choice.length === 1 || skillsToChoose.length === 1) { - event.current = currentChoice; - } - else{ - const currentPlayer = currentChoice.player; - const next = currentPlayer.chooseControl(skillsToChoose); - next.set('prompt', '选择下一个触发的技能'); - next.set('forceDie', true); - next.set('arrangeSkill', true); - next.set('includeOut', true); - const {result} = await next; - event.current = usableSkills.find(info => info.skill == result.control); - } - } - } - event.doing.doneList.push(event.current); - event.doing.todoList.remove(event.current); - const result = await game.createTrigger(event.triggername, event.current.skill, event.current.player, trigger, event.current.indexedData).forResult(); - if (get.itemtype(event.doing.player) === 'player' && result === 'cancelled'){ - for (let i = 0; i < event.doing.todoList.length; i++) { - if (event.current.skill === event.doing.todoList[i].skill) { - event.doing.doneList.push(event.doing.todoList.splice(i--, 1)[0]); - } - } - } - } - } - } - }, - createTrigger: function () { - "step 0"; - // console.log('triggering: ' + player.name+ ' \'s skill: ' + event.skill+' in ' + event.triggername) - if (game.expandSkills(player.getSkills().concat(lib.skill.global)).includes(event.skill)) return; - var info = get.info(event.skill); - let hidden = player.hiddenSkills.slice(0); - let invisible = player.invisibleSkills.slice(0); - game.expandSkills(hidden); - game.expandSkills(invisible); - if (hidden.includes(event.skill)) { - if (!info.silent && player.hasSkillTag('nomingzhi', false, null, true)) event.finish(); - else if (!info.direct && typeof info.cost !== 'function') event.trigger('triggerHidden'); - else event.skillHidden = true; - } - else if (invisible.includes(event.skill)) event.trigger('triggerInvisible'); - else if (Object.keys(player.additionalSkills).every(i => { - if (i.startsWith('hidden:')) return true; - return !game.expandSkills(player.additionalSkills[i]).includes(event.skill); - })) event.finish(); - "step 1"; - if (event.cancelled) return event.finish(); - var info = get.info(event.skill); - if (event.revealed || info.forced) { - event._result = { bool: true }; - return; - } - const checkFrequent = function (info) { - if (player.hasSkillTag('nofrequent', false, event.skill)) return false; - if (typeof info.frequent == 'boolean') return info.frequent; - if (typeof info.frequent == 'function') return info.frequent(trigger, player); - if (info.frequent == 'check' && typeof info.check == 'function') return info.check(trigger, player); - return false; - }; - if (info.direct) { - if (player.isUnderControl()) game.swapPlayerAuto(player); - if (player.isOnline()) void 0; - event._result = { bool: true }; - event._direct = true; - } - else if(typeof info.cost === 'function'){ - if (checkFrequent(info)) event.frequentSkill = true; - if (player.isUnderControl()) game.swapPlayerAuto(player); - //创建cost事件 - var next = game.createEvent(`${event.skill}_cost`); - next.player = player; - if (event.frequentSkill) next.set('frequentSkill', event.skill); - next.set('forceDie', true); - next.set('includeOut', true); - next._trigger = trigger; - next.triggername = event.triggername; - next.skillHidden = event.skillHidden; - next.indexedData = event.indexedData; - if (info.forceDie) next.forceDie = true; - if (info.forceOut) next.includeOut = true; - next.skill = event.skill; - next.setContent(info.cost); - } - else { - if (checkFrequent(info)) event.frequentSkill = true; - var str; - var check = info.check; - if (info.prompt) str = info.prompt; - else if (typeof info.logTarget == 'string') str = get.prompt(event.skill, trigger[info.logTarget], player); - else if (typeof info.logTarget == 'function') { - const logTarget = info.logTarget(trigger, player, event.triggername, event.indexedData); - if (get.itemtype(logTarget).startsWith('player')) str = get.prompt(event.skill, logTarget, player); - } - else str = get.prompt(event.skill, null, player); - if (typeof str == 'function') str = str(trigger, player, event.triggername, event.indexedData); - - var next = player.chooseBool(str); - if (event.frequentSkill) next.set('frequentSkill', event.skill); - next.set('forceDie', true); - next.set('includeOut', true); - next.ai = () => !check || check(trigger, player, event.triggername, event.indexedData); - - if (typeof info.prompt2 == 'function') next.set('prompt2', info.prompt2(trigger, player, event.triggername, event.indexedData)); - else if (typeof info.prompt2 == 'string') next.set('prompt2', info.prompt2); - else if (info.prompt2 != false) { - if (lib.dynamicTranslate[event.skill]) next.set('prompt2', lib.dynamicTranslate[event.skill](player, event.skill)); - else if (lib.translate[event.skill + '_info']) next.set('prompt2', lib.translate[event.skill + '_info']); - } - - if (trigger.skillwarn) { - if (next.prompt2) next.set('prompt2', '' + trigger.skillwarn + '。' + next.prompt2); - else next.set('prompt2', trigger.skillwarn); - } - } - "step 2"; - var info = get.info(event.skill); - if (result && result.control) result.bool = !result.control.includes('cancel'); - if (!result || !result.bool) return; - var autodelay = info.autodelay; - if (typeof autodelay == 'function') autodelay = autodelay(trigger, player); - if (autodelay && (info.forced || !event.isMine())) { - if (typeof autodelay == 'number') game.delayx(autodelay); - else game.delayx(); - } - "step 3"; - var info = get.info(event.skill); - if (!result || !result.bool) { - if (info.oncancel) info.oncancel(trigger, player); - if (event.indexedData === true) { - event.result = 'cancelled'; - } - return event.finish(); - } - let targets = null; - if (result.targets && result.targets.length > 0) { - targets = result.targets.slice(0); - } - else if (info.logTarget) { - if (typeof info.logTarget === 'string') targets = trigger[info.logTarget]; - else if (typeof info.logTarget === 'function') targets = info.logTarget(trigger, player, event.triggername, event.indexedData); - } - if (get.itemtype(targets) === 'player'){ - targets = [targets]; - } - if (info.popup != false && !info.direct) { - let popup_info = event.skill; - if(typeof info.popup === 'string') popup_info = [event.skill, info.popup]; - if (info.logLine === false) player.logSkill(popup_info, false, info.line); - else player.logSkill(popup_info, targets, info.line); - } - var next = game.createEvent(event.skill); - if (typeof info.usable == 'number') { - player.addSkill('counttrigger'); - if (!player.storage.counttrigger) player.storage.counttrigger = {}; - if (!player.storage.counttrigger[event.skill]) player.storage.counttrigger[event.skill] = 1; - else player.storage.counttrigger[event.skill]++; - } - next.player = player; - next._trigger = trigger; - next.triggername = event.triggername; - // if ("contents" in info && Array.isArray(info.contents)) { - // next.setContents(info.contents); - // } else { - next.setContent(info.content); - // } - - next.skillHidden = event.skillHidden; - if (info.forceDie) next.forceDie = true; - if (info.forceOut) next.includeOut = true; - //传入数据 - if (get.itemtype(targets) == 'players') next.targets = targets.slice(0); - if (get.itemtype(result.cards) === 'cards') next.cards = result.cards.slice(0); - //语法糖部分 - if ('cost_data' in result) next.cost_data = result.cost_data; - next.indexedData = event.indexedData; - "step 4"; - if (!player._hookTrigger) return; - if (player._hookTrigger.some(i => { - const info = lib.skill[i].hookTrigger; - return info && info.after && info.after(event, player, event.triggername); - })) event.trigger('triggerAfter'); - }, - playVideoContent: function () { - 'step 0'; - game.delay(0, 500); - 'step 1'; - if (!game.chess) { - ui.control.innerHTML = ''; - var nodes = []; - for (var i = 0; i < ui.arena.childNodes.length; i++) { - nodes.push(ui.arena.childNodes[i]); - } - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] == ui.canvas) continue; - if (nodes[i] == ui.control) continue; - if (nodes[i] == ui.mebg) continue; - if (nodes[i] == ui.me) continue; - if (nodes[i] == ui.roundmenu) continue; - nodes[i].remove(); - } - ui.sidebar.innerHTML = ''; - ui.cardPile.innerHTML = ''; - ui.discardPile.innerHTML = ''; - ui.special.innerHTML = ''; - ui.ordering.innerHTML = ''; - } - ui.system.firstChild.innerHTML = ''; - ui.system.lastChild.innerHTML = ''; - ui.system.firstChild.appendChild(ui.config2); - if (ui.updateVideoMenu) { - ui.updateVideoMenu(); - } - _status.videoDuration = 1; - ui.create.system('返回', function () { - var mode = localStorage.getItem(lib.configprefix + 'playbackmode'); - if (mode) { - game.saveConfig('mode', mode); - } - game.reload(); - }); - ui.create.system('重播', function () { - _status.replayvideo = true; - game.playVideo(_status.playback, lib.config.mode); - }); - ui.create.system('暂停', ui.click.pause, true).id = 'pausebutton'; - var slow = ui.create.system('减速', function () { - _status.videoDuration *= 1.5; - updateDuration(); - }, true); - var fast = ui.create.system('加速', function () { - _status.videoDuration /= 1.5; - updateDuration(); - }, true); - var updateDuration = function () { - if (_status.videoDuration > 1) { - slow.classList.add('glow'); - } - else { - slow.classList.remove('glow'); - } - if (_status.videoDuration < 1) { - fast.classList.add('glow'); - } - else { - fast.classList.remove('glow'); - } - }; - ui.system.style.display = ''; - ui.refresh(ui.system); - ui.system.show(); - ui.window.show(); - if (lib.config.mode != 'versus' && lib.config.mode != 'boss') { - ui.arena.style.display = ''; - ui.refresh(ui.arena); - ui.arena.show(); - } - if (!game.chess) { - game.playerMap = {}; - } - game.finishCards(); - 'step 2'; - if (event.video.length) { - var content = event.video.shift(); - // console.log(content); - if (content.type == 'delay') { - game.delay(content.content); - } - else if (content.type == 'play') { - window.play = {}; - if (!event.playtoload) { - event.playtoload = 1; - } - else { - event.playtoload++; - } - var script = lib.init.js(lib.assetURL + 'play', content.name); - script.addEventListener('load', function () { - var play = window.play[content.name]; - if (play && play.video) { - play.video(content.init); - } - event.playtoload--; - if (event.playtoload == 0) { - delete window.play; - } - }); - } - else if (typeof content.player == 'string' && game.playerMap[content.player] && - game.playerMap[content.player].classList && - !game.playerMap[content.player].classList.contains('obstacle')) { - game.videoContent[content.type](game.playerMap[content.player], content.content); - } - else { - game.videoContent[content.type](content.content); - } - if (event.video.length) { - game.delay(0, _status.videoDuration * Math.min(2000, event.video[0].delay)); - } - event.redo(); - } - else { - _status.over = true; - ui.system.lastChild.hide(); - setTimeout(function () { - ui.system.lastChild.innerHTML = ''; - }, 500); - } - }, - waitForPlayer: function () { - 'step 0'; - ui.auto.hide(); - ui.pause.hide(); - - game.createServer(); - if (!lib.translate.zhu) { - lib.translate.zhu = '主'; - } - if (event.func) { - event.func(); - } - if (!lib.configOL.number) { - lib.configOL.number = parseInt(lib.configOL.player_number); - } - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - - ui.create.connectPlayers(game.ip); - if (!window.isNonameServer) { - var me = game.connectPlayers[0]; - me.setIdentity('zhu'); - me.initOL(get.connectNickname(), lib.config.connect_avatar); - me.playerid = '1'; - game.onlinezhu = '1'; - } - _status.waitingForPlayer = true; - if (window.isNonameServer) { - document.querySelector('#server_status').innerHTML = '等待中'; - } - game.pause(); - 'step 1'; - _status.waitingForPlayer = false; - lib.configOL.gameStarted = true; - if (window.isNonameServer) { - document.querySelector('#server_status').innerHTML = '游戏中'; - } - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - for (var i = 0; i < game.connectPlayers.length; i++) { - game.connectPlayers[i].delete(); - } - delete game.connectPlayers; - if (ui.roomInfo) { - ui.roomInfo.remove(); - delete ui.roomInfo; - } - if (ui.exitroom) { - ui.exitroom.remove(); - delete ui.exitroom; - } - game.broadcast('gameStart'); - game.delay(2); - ui.auto.show(); - ui.pause.show(); - if (lib.config.show_cardpile) { - ui.cardPileButton.style.display = ''; - } - }, - replaceHandcards: function () { - 'step 0'; - if (event.players.includes(game.me)) { - game.me.chooseBool('是否置换手牌?'); - } - else { - event.finish(); - } - 'step 1'; - if (result && result.bool) { - var hs = game.me.getCards('h'); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - var cards = get.cards(hs.length); - game.me._start_cards = cards; - game.me.directgain(cards); - } - }, - replaceHandcardsOL: function () { - 'step 0'; - var send = function () { - game.me.chooseBool('是否置换手牌?'); - game.resume(); - }; - var sendback = function (result, player) { - if (result && result.bool) { - var hs = player.getCards('h'); - game.broadcastAll(function (player, hs) { - game.addVideo('lose', player, [get.cardsInfo(hs), [], [], []]); - for (var i = 0; i < hs.length; i++) { - hs[i].discard(false); - } - }, player, hs); - var cards = get.cards(hs.length); - player.directgain(cards); - player._start_cards = cards; - } - }; - for (var i = 0; i < event.players.length; i++) { - if (event.players[i].isOnline()) { - event.withol = true; - event.players[i].send(send); - event.players[i].wait(sendback); - } - else if (event.players[i] == game.me) { - event.withme = true; - game.me.chooseBool('是否置换手牌?'); - game.me.wait(sendback); - } - } - 'step 1'; - if (event.withme) { - game.me.unwait(result); - } - 'step 2'; - if (event.withol && !event.resultOL) { - game.pause(); - } - }, - /** - * @deprecated - */ - phase: function () { - 'step 0'; - //规则集中的“回合开始后③(处理“游戏开始时”的时机)” - //提前phaseBefore时机解决“游戏开始时”时机和“一轮开始时”先后 - event.trigger('phaseBefore'); - 'step 1'; - //初始化阶段列表 - if (!event.phaseList) { - event.phaseList = ['phaseZhunbei', 'phaseJudge', 'phaseDraw', 'phaseUse', 'phaseDiscard', 'phaseJieshu']; - } - if (typeof event.num != 'number') { - event.num = 0; - } - //规则集中的“回合开始后①”,更新游戏轮数,触发“一轮游戏开始时” - var isRound = false; - if (!event.skill) { - isRound = _status.roundSkipped; - if (_status.isRoundFilter) { - isRound = _status.isRoundFilter(event, player); - } - else if (_status.seatNumSettled) { - var seatNum = player.getSeatNum(); - if (seatNum != 0) { - if (get.itemtype(_status.lastPhasedPlayer) != 'player' || seatNum < _status.lastPhasedPlayer.getSeatNum()) isRound = true; - _status.lastPhasedPlayer = player; - } - } - else if (player == _status.roundStart) isRound = true; - if (isRound) { - delete _status.roundSkipped; - game.roundNumber++; - event._roundStart = true; - game.updateRoundNumber(); - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isOut() && game.players[i].outCount > 0) { - game.players[i].outCount--; - if (game.players[i].outCount == 0 && !game.players[i].outSkills) { - game.players[i].in(); - } - } - } - event.trigger('roundStart'); - } - } - _status.globalHistory.push({ - cardMove: [], - custom: [], - useCard: [], - changeHp: [], - everything: [], - }); - var players = game.players.slice(0).concat(game.dead); - for (var i = 0; i < players.length; i++) { - var current = players[i]; - current.actionHistory.push({ useCard: [], respond: [], skipped: [], lose: [], gain: [], sourceDamage: [], damage: [], custom: [], useSkill: [] }); - current.stat.push({ card: {}, skill: {} }); - if (isRound) { - current.getHistory().isRound = true; - current.getStat().isRound = true; - } - } - if (isRound) { - game.getGlobalHistory().isRound = true; - } - 'step 2'; - //规则集中的“回合开始后②(1v1武将登场专用)” - event.trigger('phaseBeforeStart'); - 'step 3'; - //规则集中的“回合开始后④(卑弥呼〖纵傀〗的时机)” - event.trigger('phaseBeforeEnd'); - 'step 4'; - //规则集中的“回合开始后⑤”,进行翻面检测 - if (player.isTurnedOver() && !event._noTurnOver) { - event.cancel(); - player.turnOver(); - player.phaseSkipped = true; - var players = game.players.slice(0).concat(game.dead); - for (var i = 0; i < players.length; i++) { - var current = players[i]; - current.getHistory().isSkipped = true; - current.getStat().isSkipped = true; - } - } - else { - player.phaseSkipped = false; - player.getHistory().isMe = true; - player.getStat().isMe = true; - } - 'step 5'; - //规则集中的“回合开始后⑥”,更新“当前回合角色” - while (ui.dialogs.length) { - ui.dialogs[0].close(); - } - game.phaseNumber++; - player.phaseNumber++; - game.broadcastAll(function (player, num, popup) { - if (lib.config.glow_phase) { - player.classList.add('glow_phase'); - } - player.phaseNumber = num; - _status.currentPhase = player; - if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); - }, player, player.phaseNumber, !player.noPhaseDelay); - _status.currentPhase = player; - _status.discarded = []; - game.syncState(); - game.addVideo('phaseChange', player); - if (game.phaseNumber == 1) { - delete player._start_cards; - if (lib.configOL.observe) { - lib.configOL.observeReady = true; - game.send('server', 'config', lib.configOL); - } - } - game.log(); - game.log(player, '的回合开始'); - player._noVibrate = true; - if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { - var num; - switch (get.config('auto_identity')) { - case 'one': num = 1; break; - case 'two': num = 2; break; - case 'three': num = 3; break; - case 'always': num = -1; break; - default: num = 0; break; - } - if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { - if (!_status.video) player.popup('显示身份'); - _status.identityShown = true; - game.showIdentity(false); - } - } - player.ai.tempIgnore = []; - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - 'step 6'; - //规则集中的“回合开始后⑦”,国战武将明置武将牌 - event.trigger('phaseBeginStart'); - 'step 7'; - //规则集中的“回合开始后⑨”,进行当先,化身等操作 - //没有⑧ 因为⑧用不到 - event.trigger('phaseBegin'); - //阶段部分 - 'step 8'; - if (num < event.phaseList.length) { - //规则集中没有的新时机 可以用来插入额外阶段啥的 - if (player.isIn()) event.trigger('phaseChange'); - } - else event.goto(11); - 'step 9'; - if (player.isIn() && num < event.phaseList.length) { - var phase = event.phaseList[num].split('|'); - event.currentPhase = phase[0]; - var next = player[event.currentPhase](); - next.phaseIndex = num; - if (phase.length > 1) { - next._extraPhaseReason = phase[1]; - } - if (event.currentPhase == 'phaseDraw' || event.currentPhase == 'phaseDiscard') { - if (!player.noPhaseDelay) { - if (player == game.me) { - game.delay(); - } - else { - game.delayx(); - } - } - } - } - 'step 10'; - if (event.currentPhase == 'phaseUse') { - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - delete player._noSkill; - } - event.num++; - 'step 11'; - if (event.num < event.phaseList.length) { - event.goto(8); - } - else if (!event._phaseEndTriggered) { - event._phaseEndTriggered = true; - event.trigger('phaseEnd'); - event.redo(); - } - 'step 12'; - event.trigger('phaseAfter'); - 'step 13'; - //删除当前回合角色 此时处于“不属于任何角色的回合”的阶段 - game.broadcastAll(function (player) { - player.classList.remove('glow_phase'); - delete _status.currentPhase; - }, player); - }, - /** - * @deprecated - */ - phase_old: function () { - "step 0"; - player.phaseZhunbei(); - "step 1"; - player.phaseJudge(); - "step 2"; - player.phaseDraw(); - if (!player.noPhaseDelay) { - if (player == game.me) { - game.delay(); - } - else { - game.delayx(); - } - } - "step 3"; - player.phaseUse(); - "step 4"; - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - player.phaseDiscard(); - if (!player.noPhaseDelay) game.delayx(); - //delete player.using; - delete player._noSkill; - "step 5"; - player.phaseJieshu(); - }, - phaseZhunbei: function () { - event.trigger(event.name); - game.log(player, '进入了准备阶段'); - }, - phaseJudge: function () { - "step 0"; - game.log(player, '进入了判定阶段'); - event.cards = player.getCards('j'); - if (!event.cards.length) event.finish(); - "step 1"; - if (cards.length) { - event.card = cards.shift(); - var cardName = event.card.viewAs || event.card.name, cardInfo=lib.card[cardName]; - if (event.card.classList.contains('removing')) { - event.card.remove(); - delete event.card; - event.redo(); - } - else if (event.card.classList.contains('feichu')) { - event.finish(); - return; - } - else if (cardInfo.noEffect || !player.getCards('j').includes(event.card)) { - event.redo(); - } - else { - player.lose(event.card, 'visible', ui.ordering); - player.$phaseJudge(event.card); - event.cancelled = false; - event.trigger('phaseJudge'); - player.popup(cardName, 'thunder'); - if (!cardInfo.effect) { - game.delay(); - event.redo(); - } - else if (!cardInfo.judge) { - game.delay(); - event.nojudge = true; - } - else{ - event.nojudge = false; - } - } - } - else event.finish(); - "step 2"; - if (!event.cancelled && !event.nojudge) player.judge(event.card).set('type', 'phase'); - "step 3"; - var name = event.card.viewAs || event.card.name; - if (event.excluded) { - delete event.excluded; - } - else if (event.cancelled && !event.direct) { - if (lib.card[name].cancel) { - var next = game.createEvent(name + 'Cancel'); - next.setContent(lib.card[name].cancel); - next.cards = [event.card]; - if (!event.card.viewAs) next.card = get.autoViewAs(event.card); - else next.card = get.autoViewAs({ name: name }, next.cards); - next.player = player; - } - } - else { - var next = game.createEvent(name); - next.setContent(lib.card[name].effect); - next._result = result; - next.cards = [event.card]; - if (!event.card.viewAs) next.card = get.autoViewAs(event.card); - else next.card = get.autoViewAs({ name: name }, next.cards); - next.player = player; - } - ui.clear(); - event.goto(1); - }, - /** - * @deprecated - */ - phaseDraw: function () { - "step 0"; - game.log(player, '进入了摸牌阶段'); - event.trigger("phaseDrawBegin1"); - "step 1"; - event.trigger("phaseDrawBegin2"); - "step 2"; - if (game.modPhaseDraw) { - game.modPhaseDraw(player, event.num); - } - else { - if (event.num > 0) { - var num = event.num; - if (event.attachDraw) { - for (var i = 0; i < event.attachDraw.length; i++) { - ui.cardPile.insertBefore(event.attachDraw[i], ui.cardPile.firstChild); - } - num += event.attachDraw.length; - } - var next = player.draw(num); - if (event.attachDraw) { - next.minnum = event.attachDraw.length; - } - } - } - "step 3"; - if (Array.isArray(result)) { - event.cards = result; - } - }, - phaseUse: function () { - "step 0"; - const stat = player.getStat(); - for (let i in stat.skill) { - let bool = false; - const info = lib.skill[i]; - if (!info) continue; - if (info.enable != undefined) { - if (typeof info.enable == 'string' && info.enable == 'phaseUse') bool = true; - else if (typeof info.enable == 'object' && info.enable.includes('phaseUse')) bool = true; - } - if (bool) stat.skill[i] = 0; - } - for (let i in stat.card) { - let bool = false; - const info = lib.card[i]; - if (!info) continue; - if (info.updateUsable == 'phaseUse') stat.card[i] = 0; - } - "step 1"; - event.trigger('phaseUseBefore'); - "step 2"; - event.trigger('phaseUseBegin'); - "step 3"; - if (!event.logged) { - game.log(player, '进入了出牌阶段'); - event.logged = true; - } - var next = player.chooseToUse(); - if (!lib.config.show_phaseuse_prompt) { - next.set('prompt', false); - } - next.set('type', 'phase'); - "step 4"; - if (result.bool && !event.skipped) { - event.goto(3); - } - game.broadcastAll(function () { - if (ui.tempnowuxie) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }); - "step 5"; - event.trigger('phaseUseEnd'); - "step 6"; - event.trigger('phaseUseAfter'); - }, - phaseDiscard: function () { - "step 0"; - game.log(player, '进入了弃牌阶段'); - event.num = player.needsToDiscard(); - if (event.num <= 0) event.finish(); - else { - game.broadcastAll(function (player) { - if (lib.config.show_phase_prompt) { - player.popup('弃牌阶段', null, false); - } - }, player); - } - event.trigger('phaseDiscard'); - "step 1"; - player.chooseToDiscard(num, true) - .set('useCache', true); - "step 2"; - event.cards = result.cards; - }, - phaseJieshu: function () { - event.trigger(event.name); - game.log(player, '进入了结束阶段'); - }, - chooseToUse: function () { - "step 0"; - if (event.responded) return; - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl() && !lib.filter.wuxieSwap(event)) { - game.modeSwapPlayer(player); - } - var skills = player.getSkills('invisible').concat(lib.skill.global); - game.expandSkills(skills); - for (var i = 0; i < skills.length; i++) { - var info = lib.skill[skills[i]]; - if (info && info.onChooseToUse) { - info.onChooseToUse(event); - } - } - if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; - if (event.type == 'phase') { - if (event.isMine()) { - event.endButton = ui.create.control('结束回合', 'stayleft', function () { - var evt = _status.event; - if (evt.name != 'chooseToUse' || evt.type != 'phase') return; - if (evt.skill) { - ui.click.cancel(); - } - ui.click.cancel(); - }); - event.fakeforce = true; - } - else { - if (event.endButton) { - event.endButton.close(); - delete event.endButton; - } - event.fakeforce = false; - } - } - if (event.player.isUnderControl() && !_status.auto) { - event.result = { - bool: false - }; - return; - } - else if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - if (event.type == 'wuxie') { - if (ui.tempnowuxie) { - var triggerevent = event.getTrigger(); - if (triggerevent && triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { - ui.tempnowuxie.close(); - } - } - if (lib.filter.wuxieSwap(event)) { - event.result = { - bool: false - }; - return; - } - } - var ok = game.check(); - if (!ok || !lib.config.auto_confirm) { - game.pause(); - if (lib.config.enable_vibrate && player._noVibrate) { - delete player._noVibrate; - game.vibrate(); - } - if (typeof event.prompt == 'string') { - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = event.prompt; - } - else { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - } - } - else if (typeof event.prompt == 'function') { - event.dialog = ui.create.dialog(event.prompt(event)); - } - else if (event.prompt == undefined) { - var str; - if (typeof event.filterCard == 'object') { - var filter = event.filterCard; - str = '请使用' + get.cnNumber(event.selectCard[0]) + '张'; - if (filter.name) { - str += get.translation(filter.name); - } - else { - str += '牌'; - } - } - else { - str = '请选择要使用的牌'; - } - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = str; - } - else if (typeof event.skillDialog != 'string') { - event.dialog = ui.create.dialog(str); - } - else { - event.dialog = str; - } - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - var ok = game.check(); - if (ok) { - ui.click.ok(); - } - else if (ai.basic.chooseCard(event.ai1) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - event._aiexcludeclear = true; - } - else { - if (!event.norestore) { - if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - } - else { - get.card(true).aiexclude(); - game.uncheck(); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - } - else if (event.skill && !event.norestore) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - if (event.aidelay && event.result && event.result.bool) { - game.delayx(); - } - } - "step 2"; - if (event.endButton) { - event.endButton.close(); - delete event.endButton; - } - event.resume(); - if (event.result) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - if (event.result.skill) { - var info = get.info(event.result.skill); - if (info && info.chooseButton) { - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - var dialog = info.chooseButton.dialog(event, player); - if (info.chooseButton.chooseControl) { - var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.dialog = dialog; - next.set('ai', info.chooseButton.check || function () { return 0; }); - if (event.id) next._parent_id = event.id; - next.type = 'chooseToUse_button'; - } - else { - var next = player.chooseButton(dialog); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.set('ai', info.chooseButton.check || function () { return 1; }); - next.set('filterButton', info.chooseButton.filter || function () { return true; }); - next.set('selectButton', info.chooseButton.select || 1); - next.set('complexSelect', info.chooseButton.complexSelect !== false); - next.set('filterOk', info.chooseButton.filterOk || (() => true)); - if (event.id) next._parent_id = event.id; - next.type = 'chooseToUse_button'; - } - event.buttoned = event.result.skill; - } - else if (info && info.precontent && !game.online && !event.nouse) { - var next = game.createEvent('pre_' + event.result.skill); - next.setContent(info.precontent); - next.set('result', event.result); - next.set('player', player); - } - } - } - "step 3"; - if (event.buttoned) { - if (result.bool || result.control && result.control != 'cancel2') { - var info = get.info(event.buttoned).chooseButton; - lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); - lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; - if (game.online) { - event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; - } - else { - game.broadcast((skill, audio) => { - if (!lib.skill[skill]) lib.skill[skill] = {}; - lib.skill[skill].audio = audio; - }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); - } - event.backup(event.buttoned + '_backup'); - if (info.prompt) { - event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); - } - } - else { - ui.control.addTempClass('nozoom', 100); - event._aiexclude.add(event.buttoned); - } - event.goto(0); - delete event.buttoned; - } - "step 4"; - if (event._aiexcludeclear) { - delete event._aiexcludeclear; - event._aiexclude.length = 0; - } - delete _status.noclearcountdown; - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { - event.skillDialog.close(); - } - if (event.result && event.result.bool && !game.online && !event.nouse) { - player.useResult(event.result, event); - } - else if (event._sendskill) { - event.result._sendskill = event._sendskill; - } - if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { - var info = get.info(event.result.skill || (Array.isArray(event.logSkill) ? event.logSkill[0] : event.logSkill)); - if (info.direct && !info.clearTime) { - _status.noclearcountdown = 'direct'; - } - } - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - if (!_status.noclearcountdown) { - game.stopCountChoose(); - } - "step 5"; - if (event._result && event.result) { - event.result.result = event._result; - } - }, - chooseToRespond: function () { - "step 0"; - if (event.responded) { - delete event.dialog; - return; - } - var skills = player.getSkills('invisible').concat(lib.skill.global); - game.expandSkills(skills); - for (var i = 0; i < skills.length; i++) { - var info = lib.skill[skills[i]]; - if (info && info.onChooseToRespond) { - info.onChooseToRespond(event); - } - } - if (_status.noclearcountdown !== 'direct') _status.noclearcountdown = true; - if (!_status.connectMode && lib.config.skip_shan && event.autochoose && event.autochoose()) { - event.result = { bool: false }; - } - else { - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { - game.modeSwapPlayer(player); - } - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - var ok = game.check(); - if (!ok || !lib.config.auto_confirm) { - game.pause(); - if (event.openskilldialog) { - event.skillDialog = ui.create.dialog(event.openskilldialog); - delete event.openskilldialog; - event.dialog = event.prompt; - } - else { - if (event.prompt) event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) event.dialog.addText(event.prompt2); - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - var ok = game.check(); - if (ok) { - ui.click.ok(); - } - else if (ai.basic.chooseCard(event.ai1 || event.ai) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - event._aiexcludeclear = true; - } - else { - if (!event.norestore) { - if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - } - else { - get.card(true).aiexclude(); - game.uncheck(); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - } - else if (event.skill && !event.norestore) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - var info = get.info(skill); - if (info.sourceSkill) { - event._aiexclude.add(info.sourceSkill); - } - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - if (event.aidelay && event.result && event.result.bool) { - game.delayx(); - } - } - "step 2"; - event.resume(); - if (event.result) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - if (event.result.skill) { - var info = get.info(event.result.skill); - if (info && info.chooseButton) { - if (event.dialog && typeof event.dialog == 'object') event.dialog.close(); - var dialog = info.chooseButton.dialog(event, player); - if (info.chooseButton.chooseControl) { - var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.dialog = dialog; - next.set('ai', info.chooseButton.check || function () { return 0; }); - } - else { - var next = player.chooseButton(dialog); - if (dialog.direct) next.direct = true; - if (dialog.forceDirect) next.forceDirect = true; - next.set('ai', info.chooseButton.check || function () { return 1; }); - next.set('filterButton', info.chooseButton.filter || function () { return true; }); - next.set('selectButton', info.chooseButton.select || 1); - next.set('filterOk', info.chooseButton.filterOk || (() => true)); - } - event.buttoned = event.result.skill; - } - else if (info && info.precontent && !game.online) { - var next = game.createEvent('pre_' + event.result.skill); - next.setContent(info.precontent); - next.set('result', event.result); - next.set('player', player); - } - } - } - "step 3"; - if (event.buttoned) { - if (result.bool || result.control && result.control != 'cancel2') { - var info = get.info(event.buttoned).chooseButton; - lib.skill[event.buttoned + '_backup'] = info.backup(info.chooseControl ? result : result.links, player); - lib.skill[event.buttoned + '_backup'].sourceSkill = event.buttoned; - if (game.online) { - event._sendskill = [event.buttoned + '_backup', lib.skill[event.buttoned + '_backup']]; - } - else { - game.broadcast((skill, audio) => { - if (!lib.skill[skill]) lib.skill[skill] = {}; - lib.skill[skill].audio = audio; - }, event.buttoned + '_backup', lib.skill[event.buttoned + '_backup'].audio); - } - event.backup(event.buttoned + '_backup'); - if (info.prompt) { - event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); - } - } - else { - ui.control.addTempClass('nozoom', 100); - event._aiexclude.add(event.buttoned); - } - event.goto(0); - delete event.buttoned; - } - "step 4"; - delete _status.noclearcountdown; - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { - event.skillDialog.close(); - } - if (event.result.bool && !game.online) { - if (event.result._sendskill) { - lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; - } - if (event.onresult) { - event.onresult(event.result); - } - if ((!event.result || !event.result.bool || event.result._noHidingTimer) && (event.result.skill || event.logSkill)) { - var info = get.info(event.result.skill || (Array.isArray(event.logSkill) ? event.logSkill[0] : event.logSkill)); - if (info.direct && !info.clearTime) { - _status.noclearcountdown = 'direct'; - } - } - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (!event.result.card && event.result.skill) { - event.result.used = event.result.skill; - player.useSkill(event.result.skill, event.result.cards, event.result.targets); - } - else { - if (info && info.prerespond) { - info.prerespond(event.result, player); - } - var next = player.respond(event.result.cards, event.result.card, event.animate, event.result.skill, event.source); - if (event.result.noanimate) next.animate = false; - if (event.parent.card && event.parent.type == 'card') { - next.set('respondTo', [event.parent.player, event.parent.card]); - } - if (event.noOrdering) next.noOrdering = true; - } - } - else if (event._sendskill) { - event.result._sendskill = event._sendskill; - } - if (event.dialog && event.dialog.close) event.dialog.close(); - if (!_status.noclearcountdown) { - game.stopCountChoose(); - } - }, - chooseToGive: function () { - "step 0"; - event.result = { - bool: true, - confirm: 'ok', - buttons: [], - links: [], - cards: [], - targets: [], - }; - event.filterCard = (event => { - const filterCard = event.filterCard; - return function (card, player) { - if (!lib.filter.canBeGained(card, this.target, player)) return false; - return filterCard.call(this, card, player); - }; - })(event); - if (event.directresult) { - event.result.cards = event.directresult.slice(0); - event.goto(2); - return; - } - const directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectCard != 'function' && !event.complexCard); - const cards = directFilter ? player.getCards(event.position).filter(card => !card.classList.contains('uncheck') && lib.filter.cardAiIncluded(card) && event.filterCard(card, player)) : []; - const range = get.select(event.selectCard); - if (directFilter && (range[0] >= cards.length || range[1] <= -1)) { - if (player.isOut()) event.result.cards = []; - else event.result.cards = cards; - } - else if (event.isMine()) { - game.check(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.pause(); - if (range[1] > 1 && typeof event.selectCard != 'function') { - event.aiChoose = ui.create.control('AI代选', function () { - ai.basic.chooseCard(event.ai); - if (_status.event.custom && _status.event.custom.add.card) { - _status.event.custom.add.card(); - } - ui.selected.cards.forEach(i => i.updateTransform(true)); - }); - } - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - event.dialog.open(); - event.dialog.classList.add('noselect'); - } - else if (event.prompt != false) { - let prompt; - if (typeof event.prompt == 'string') prompt = event.prompt; - else { - let select; - if (range[0] == range[1]) select = get.cnNumber(range[0]); - else if (range[1] == Infinity) select = '至少' + get.cnNumber(range[0]); - else select = get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - const position = event.position == 'h' ? '手' : event.position == 'e' ? '装备' : ''; - prompt = `请交给${get.translation(target)}${select}张${position}牌`; - } - event.dialog = ui.create.dialog(prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.promptx)) { - event.promptx.forEach(i => event.dialog.add(i)); - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.style.display = ''; - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - ui.click.cancel(); - event._aiexclude.add(event.skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.aiChoose) event.aiChoose.close(); - if (event.glow_result && event.result.cards && !event.directresult) { - event.result.cards.forEach(i => i.classList.add('glow')); - } - if (event.dialog) event.dialog.close(); - "step 3"; - if (event.result.bool && event.result.cards && !game.online) { - event.cards = event.result.cards.slice(0); - if (event.logSkill) { - if (Array.isArray(event.logSkill)) player.logSkill(...event.logSkill); - else player.logSkill(event.logSkill); - } - if (event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') game.delayx(event.autodelay); - else game.delayx(); - } - } - else event.finish(); - "step 4"; - if (event.boolline) player.line(target, 'green'); - event.done = target.gain(event.cards, player); - event.done.giver = player; - if (event.delay !== false) event.done.animate = event.visibleMove ? 'give' : 'giveAuto'; - else { - target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - if (event.visibleMove) event.done.visible = true; - } - }, - chooseToDiscard: function () { - "step 0"; - if (event.autochoose()) { - event.result = { - bool: true, - autochoose: true, - cards: player.getCards(event.position), - rawcards: player.getCards(event.position), - }; - for (var i = 0; i < event.result.cards.length; i++) { - if (!lib.filter.cardDiscardable(event.result.cards[i], player, event)) { - event.result.cards.splice(i--, 1); - } - } - } - else { - // &&!lib.filter.wuxieSwap(trigger) - if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { - game.modeSwapPlayer(player); - } - event.rangecards = player.getCards(event.position); - for (var i = 0; i < event.rangecards.length; i++) { - if (lib.filter.cardDiscardable(event.rangecards[i], player, event)) { - event.rangecards.splice(i--, 1); - } - else { - event.rangecards[i].uncheck('chooseToDiscard'); - } - } - var range = get.select(event.selectCard); - if (event.isMine()) { - game.check(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.pause(); - if (range[1] > 1 && typeof event.selectCard != 'function') { - event.promptdiscard = ui.create.control('AI代选', function () { - ai.basic.chooseCard(event.ai); - if (_status.event.custom && _status.event.custom.add.card) { - _status.event.custom.add.card(); - } - for (var i = 0; i < ui.selected.cards.length; i++) { - ui.selected.cards[i].updateTransform(true); - } - }); - } - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - event.dialog.open(); - event.dialog.classList.add('noselect'); - } - else if (event.prompt != false) { - var str; - if (typeof (event.prompt) == 'string') str = event.prompt; - else { - str = '请弃置'; - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.style.display = ''; - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - if (event.rangecards) { - for (var i = 0; i < event.rangecards.length; i++) { - event.rangecards[i].recheck('chooseToDiscard'); - } - } - "step 2"; - event.resume(); - if (event.promptdiscard) { - event.promptdiscard.close(); - } - "step 3"; - if (event.result.bool && event.result.cards && event.result.cards.length && - !game.online && event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') { - game.delayx(event.autodelay); - } - else { - game.delayx(); - } - } - "step 4"; - if (event.logSkill && event.result.bool && !game.online) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (!game.online && !event.chooseonly) { - if (typeof event.delay == 'boolean') { - event.done = player.discard(event.result.cards).set('delay', event.delay); - } - else { - event.done = player.discard(event.result.cards); - } - event.done.discarder = player; - } - if (event.dialog && event.dialog.close) event.dialog.close(); - }, - gaincardMultiple: function () { - 'step 0'; - event.type = 'gain'; - if (event.animate == 'give' || event.animate == 'gain2') event.visible = true; - if (player && cards) { - event._lose = true; - player.lose(cards, ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); - } - 'step 1'; - switch (event.animate) { - case 'draw': - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$draw(i[1].length); - } - break; - case 'gain': - game.delay(0, get.delayx(700, 700)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$gain(i[1].length); - } - break; - case 'gain2': case 'draw2': - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - if (i[1].length > 0) i[0].$gain2(i[1]); - } - break; - case 'give': case 'giveAuto': - if (!player) break; - var evt = event.getl(player); - game.delay(0, get.delayx(500, 500)); - for (var i of event.gain_list) { - if (get.itemtype(i[1]) == 'card') i[1] = [i[1]]; - if (event._lose) { - i[1] = i[1].filter(card => { - return !cards.includes(card) || !player.getCards('hejsx').includes(card); - }); - } - var shown = i[1].slice(0), hidden = []; - if (event.animate == 'giveAuto') { - for (var card of i[1]) { - if (evt.hs.includes(card)) { - shown.remove(card); - hidden.push(card); - } - } - } - if (shown.length > 0) player.$give(shown, i[0]); - if (hidden.length > 0) player.$giveAuto(hidden, i[0]); - } - break; - default: - event.finish(); - } - for (var i of event.gain_list) { - if (i[1].length > 0) { - var next = i[0].gain(i[1]); - next.getlx = false; - if (event.visible) next.visible = true; - if (event.giver) next.giver = event.giver; - if (event.gaintag) next.gaintag.addArray(event.gaintag); - } - } - 'step 2'; - game.delayx(); - }, - discardMultiple: function () { - 'step 0'; - event.type = 'discard'; - event.visible = true; - if (!event.position) event.position = ui.discardPile; - var cards = []; - event.cards = cards; - for (var i = 0; i < event.lose_list.length; i++) { - var next = event.lose_list[i][0].lose(event.lose_list[i][1], event.position); - game.log(event.lose_list[i][0], '弃置了', event.lose_list[i][1]); - next.type = 'discard'; - next.animate = false; - next.delay = false; - cards.addArray(event.lose_list[i][1]); - next.getlx = false; - } - var evt = event; - if (evt.animate != false) { - evt.discardid = lib.status.videoId++; - game.broadcastAll(function (list, id, cards) { - for (var i of list) { - for (var j of i[1]) { - j.classList.remove('glow'); - j.classList.remove('glows'); - } - i[0].$throw(i[1], null, 'nobroadcast'); - } - var cardnodes = []; - cardnodes._discardtime = get.time(); - for (var ix of list) { - var card = ix[1]; - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cardnodes.push(cards[i].clone); - } - } - } - ui.todiscard[id] = cardnodes; - }, event.lose_list, evt.discardid, cards); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - if (evt.delay != false) { - var waitingForTransition = get.time(); - evt.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.waitingForTransition; - }); - } - else if (evt.getParent().discardTransition) { - delete evt.getParent().discardTransition; - var waitingForTransition = get.time(); - evt.getParent().waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.getParent().waitingForTransition; - }); - } - } - } - 'step 1'; - if (event.delay != false) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - }, - chooseToCompareLose: function () { - for (var i = 0; i < event.lose_list.length; i++) { - var next = event.lose_list[i][0].lose(event.lose_list[i][1], ui.ordering); - next.relatedEvent = event.getParent(); - next.getlx = false; - } - }, - chooseToCompareMeanwhile: function () { - 'step 0'; - if (player.countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - for (var i = 0; i < targets.length; i++) { - if (targets[i].countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - } - if (!event.multitarget) { - targets.sort(lib.sort.seat); - } - game.log(player, '对', targets, '发起了共同拼点'); - event.compareMeanwhile = true; - 'step 1'; - event._result = []; - event.list = targets.filter(function (current) { - return !event.fixedResult || !event.fixedResult[current.playerid]; - }); - if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { - if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); - player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { - var hs = target.getCards('h'); - var event = _status.event; - event.player = target; - hs.sort(function (a, b) { - return event.ai(b) - event.ai(a); - }); - delete event.player; - return { bool: true, cards: [hs[0]] }; - }; - } - 'step 2'; - var cards = []; - var lose_list = []; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.list.unshift(player); - result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); - lose_list.push([player, [event.fixedResult[player.playerid]]]); - } - else { - if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { - player.logSkill(result[0].skill); - result[0].cards = lib.skill[result[0].skill].onCompare(player); - } - else lose_list.push([player, result[0].cards]); - } - for (var j = 0; j < targets.length; j++) { - if (event.list.includes(targets[j])) { - var i = event.list.indexOf(targets[j]); - if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { - event.list[i].logSkill(result[i].skill); - result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); - } - else lose_list.push([targets[j], result[i].cards]); - cards.push(result[i].cards[0]); - } - else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { - cards.push(event.fixedResult[targets[j].playerid]); - lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); - } - } - if (lose_list.length) { - game.loseAsync({ - lose_list: lose_list, - }).setContent('chooseToCompareLose'); - } - event.lose_list = lose_list; - event.getNum = function (card) { - for (var i of event.lose_list) { - if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.cardlist = cards; - event.cards = cards; - event.card1 = result[0].cards[0]; - event.num1 = event.getNum(event.card1); - event.iwhile = 0; - event.winner = null; - event.maxNum = -1; - event.tempplayer = event.player; - event.result = { - winner: null, - player: event.card1, - targets: event.cardlist.slice(0), - num1: [], - num2: [], - }; - 'step 3'; - event.trigger('compareCardShowBefore'); - 'step 4'; - player.$compareMultiple(event.card1, targets, cards); - game.log(player, '的拼点牌为', event.card1); - event.cardlist.forEach((card, index) => { - game.log(targets[index], '的拼点牌为', card); - }); - player.addTempClass('target'); - game.delay(0, 1000); - 'step 5'; - event.target = null; - event.trigger('compare'); - 'step 6'; - if (event.iwhile < targets.length) { - event.target = targets[event.iwhile]; - event.target.addTempClass('target'); - event.card2 = event.cardlist[event.iwhile]; - event.num2 = event.getNum(event.card2); - //event.tempplayer.line(event.target); - delete event.player; - event.trigger('compare'); - } - else { - game.delay(0, 1000); - event.goto(9); - } - 'step 7'; - event.result.num1[event.iwhile] = event.num1; - event.result.num2[event.iwhile] = event.num2; - var list = [[event.tempplayer, event.num1], [event.target, event.num2]]; - for (var i of list) { - if (i[1] > event.maxNum) { - event.maxNum = i[1]; - event.winner = i[0]; - } - else if (event.winner && i[1] == event.maxNum && i[0] != event.winner) { - event.winner = null; - } - } - 'step 8'; - event.iwhile++; - event.goto(6); - 'step 9'; - var player = event.tempplayer; - event.player = player; - delete event.tempplayer; - var str = '无人拼点成功'; - if (event.winner) { - event.result.winner = event.winner; - str = get.translation(event.winner) + '拼点成功'; - game.log(event.winner, '拼点成功'); - event.winner.popup('胜'); - } else game.log('#b无人', '拼点成功'); - var list = [player].addArray(targets); - list.remove(event.winner); - for (var i of list) { - i.popup('负'); - } - if (str) { - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - } - game.delay(3); - 'step 10'; - game.broadcastAll(ui.clear); - 'step 11'; - event.cards.add(event.card1); - }, - chooseToCompareMultiple: function () { - "step 0"; - if (player.countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - for (var i = 0; i < targets.length; i++) { - if (targets[i].countCards('h') == 0) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - } - if (!event.multitarget) { - targets.sort(lib.sort.seat); - } - game.log(player, '对', targets, '发起拼点'); - "step 1"; - event._result = []; - event.list = targets.filter(function (current) { - return !event.fixedResult || !event.fixedResult[current.playerid]; - }); - if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { - if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); - player.chooseCardOL(event.list, '请选择拼点牌', true).set('type', 'compare').set('ai', event.ai).set('source', player).aiCard = function (target) { - var hs = target.getCards('h'); - var event = _status.event; - event.player = target; - hs.sort(function (a, b) { - return event.ai(b) - event.ai(a); - }); - delete event.player; - return { bool: true, cards: [hs[0]] }; - }; - } - "step 2"; - var cards = []; - var lose_list = []; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.list.unshift(player); - result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); - lose_list.push([player, [event.fixedResult[player.playerid]]]); - } - else { - if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { - player.logSkill(result[0].skill); - result[0].cards = lib.skill[result[0].skill].onCompare(player); - } - else lose_list.push([player, result[0].cards]); - } - for (var j = 0; j < targets.length; j++) { - if (event.list.includes(targets[j])) { - var i = event.list.indexOf(targets[j]); - if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { - event.list[i].logSkill(result[i].skill); - result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); - } - else lose_list.push([targets[j], result[i].cards]); - cards.push(result[i].cards[0]); - } - else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { - cards.push(event.fixedResult[targets[j].playerid]); - lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); - } - } - if (lose_list.length) { - game.loseAsync({ - lose_list: lose_list, - }).setContent('chooseToCompareLose'); - } - event.lose_list = lose_list; - event.getNum = function (card) { - for (var i of event.lose_list) { - if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.cardlist = cards; - event.cards = cards; - event.card1 = result[0].cards[0]; - event.num1 = event.getNum(event.card1); - event.iwhile = 0; - event.result = { - player: event.card1, - targets: event.cardlist.slice(0), - num1: [], - num2: [], - }; - "step 3"; - event.trigger('compareCardShowBefore'); - "step 4"; - game.log(player, '的拼点牌为', event.card1); - "step 5"; - if (event.iwhile < targets.length) { - event.target = targets[event.iwhile]; - event.target.addTempClass('target'); - player.addTempClass('target'); - event.card2 = event.cardlist[event.iwhile]; - event.num2 = event.getNum(event.card2); - game.log(event.target, '的拼点牌为', event.card2); - player.line(event.target); - player.$compare(event.card1, event.target, event.card2); - event.trigger('compare'); - game.delay(0, 1500); - } - else { - event.goto(9); - } - "step 6"; - event.result.num1[event.iwhile] = event.num1; - event.result.num2[event.iwhile] = event.num2; - var str; - if (event.num1 > event.num2) { - str = get.translation(player) + '拼点成功'; - player.popup('胜'); - target.popup('负'); - } - else { - str = get.translation(player) + '拼点失败'; - if (event.num1 == event.num2) { - player.popup('平'); - target.popup('平'); - } - else { - player.popup('负'); - target.popup('胜'); - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - "step 7"; - if (event.callback) { - game.broadcastAll(function (card1, card2) { - if (card1.clone) card1.clone.style.opacity = 0.5; - if (card2.clone) card2.clone.style.opacity = 0.5; - }, event.card1, event.card2); - var next = game.createEvent('compareMultiple'); - next.player = player; - next.target = event.target; - next.card1 = event.card1; - next.card2 = event.card2; - next.num1 = event.num1; - next.num2 = event.num2; - next.setContent(event.callback); - event.compareMultiple = true; - } - "step 8"; - game.broadcastAll(ui.clear); - event.iwhile++; - event.goto(5); - "step 9"; - event.cards.add(event.card1); - }, - chooseToCompare: function () { - "step 0"; - if (((!event.fixedResult || !event.fixedResult[player.playerid]) && player.countCards('h') == 0) || ((!event.fixedResult || !event.fixedResult[target.playerid]) && target.countCards('h') == 0)) { - event.result = { cancelled: true, bool: false }; - event.finish(); - return; - } - game.log(player, '对', target, '发起拼点'); - event.lose_list = []; - "step 1"; - var sendback = function () { - if (_status.event != event) { - return function () { - event.resultOL = _status.event.resultOL; - }; - } - }; - if (event.fixedResult && event.fixedResult[player.playerid]) { - event.card1 = event.fixedResult[player.playerid]; - event.lose_list.push([player, event.card1]); - } - else if (player.isOnline()) { - player.wait(sendback); - event.ol = true; - player.send(function (ai) { - game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; - game.resume(); - }, event.ai); - } - else { - event.localPlayer = true; - player.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; - } - if (event.fixedResult && event.fixedResult[target.playerid]) { - event.card2 = event.fixedResult[target.playerid]; - event.lose_list.push([target, event.card2]); - } - else if (target.isOnline()) { - target.wait(sendback); - event.ol = true; - target.send(function (ai) { - game.me.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = ai; - game.resume(); - }, event.ai); - } - else { - event.localTarget = true; - } - "step 2"; - if (event.localPlayer) { - if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { - result.cards = lib.skill[result.skill].onCompare(player); - player.logSkill(result.skill); - } - else event.lose_list.push([player, result.cards[0]]); - event.card1 = result.cards[0]; - } - if (event.localTarget) { - target.chooseCard('请选择拼点牌', true).set('type', 'compare').set('glow_result', true).ai = event.ai; - } - "step 3"; - if (event.localTarget) { - if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { - target.logSkill(result.skill); - result.cards = lib.skill[result.skill].onCompare(target); - } - else event.lose_list.push([target, result.cards[0]]); - event.card2 = result.cards[0]; - } - if (!event.resultOL && event.ol) { - game.pause(); - } - "step 4"; - try { - if (!event.card1) { - if (event.resultOL[player.playerid].skill && lib.skill[event.resultOL[player.playerid].skill] && lib.skill[event.resultOL[player.playerid].skill].onCompare) { - player.logSkill(event.resultOL[player.playerid].skill); - event.resultOL[player.playerid].cards = lib.skill[event.resultOL[player.playerid].skill].onCompare(player); - } - else event.lose_list.push([player, event.resultOL[player.playerid].cards[0]]); - event.card1 = event.resultOL[player.playerid].cards[0]; - } - if (!event.card2) { - if (event.resultOL[target.playerid].skill && lib.skill[event.resultOL[target.playerid].skill] && lib.skill[event.resultOL[target.playerid].skill].onCompare) { - target.logSkill(event.resultOL[target.playerid].skill); - event.resultOL[target.playerid].cards = lib.skill[event.resultOL[target.playerid].skill].onCompare(player); - } - else event.lose_list.push([target, event.resultOL[target.playerid].cards[0]]); - event.card2 = event.resultOL[target.playerid].cards[0]; - } - if (!event.card1 || !event.card2) { - throw ('err'); - } - } - catch (e) { - console.log(e); - game.print(e); - event.finish(); - return; - } - if (event.card2.number >= 10 || event.card2.number <= 4) { - if (target.countCards('h') > 2) { - event.addToAI = true; - } - } - if (event.lose_list.length) { - game.loseAsync({ - lose_list: event.lose_list, - }).setContent('chooseToCompareLose'); - } - "step 5"; - event.trigger('compareCardShowBefore'); - "step 6"; - game.broadcast(function () { - ui.arena.classList.add('thrownhighlight'); - }); - ui.arena.classList.add('thrownhighlight'); - game.addVideo('thrownhighlight1'); - player.$compare(event.card1, target, event.card2); - game.log(player, '的拼点牌为', event.card1); - game.log(target, '的拼点牌为', event.card2); - var getNum = function (card) { - for (var i of event.lose_list) { - if (i[1] == card) return get.number(card, i[0]); - } - return get.number(card, false); - }; - event.num1 = getNum(event.card1); - event.num2 = getNum(event.card2); - event.trigger('compare'); - game.delay(0, 1500); - "step 7"; - event.result = { - player: event.card1, - target: event.card2, - num1: event.num1, - num2: event.num2 - }; - var str; - if (event.num1 > event.num2) { - event.result.bool = true; - event.result.winner = player; - str = get.translation(player) + '拼点成功'; - player.popup('胜'); - target.popup('负'); - } - else { - event.result.bool = false; - str = get.translation(player) + '拼点失败'; - if (event.num1 == event.num2) { - event.result.tie = true; - player.popup('平'); - target.popup('平'); - } - else { - event.result.winner = target; - player.popup('负'); - target.popup('胜'); - } - } - game.broadcastAll(function (str) { - var dialog = ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function () { - dialog.close(); - }, 1000); - }, str); - game.delay(2); - "step 8"; - if (typeof event.target.ai.shown == 'number' && event.target.ai.shown <= 0.85 && event.addToAI) { - event.target.ai.shown += 0.1; - } - game.broadcastAll(function () { - ui.arena.classList.remove('thrownhighlight'); - }); - game.addVideo('thrownhighlight2'); - if (event.clear !== false) { - game.broadcastAll(ui.clear); - } - if (typeof event.preserve == 'function') { - event.preserve = event.preserve(event.result); - } - else if (event.preserve == 'win') { - event.preserve = event.result.bool; - } - else if (event.preserve == 'lose') { - event.preserve = !event.result.bool; - } - }, - chooseSkill: function () { - 'step 0'; - var list; - if (typeof event.target == 'string') { - list = get.gainableSkillsName(event.target, event.func); - } - else { - list = event.target.getGainableSkills(event.func); - } - if (!list.length) { - event.finish(); - event.result = { bool: false }; - return; - } - event.skillai = function (list) { - return get.max(list, get.skillRank, 'item'); - }; - if (event.isMine()) { - var dialog = ui.create.dialog('forcebutton'); - dialog.add(event.prompt || '选择获得一项技能'); - _status.event.list = list; - var clickItem = function () { - _status.event._result = this.link; - game.resume(); - }; - for (i = 0; i < list.length; i++) { - if (lib.translate[list[i] + '_info']) { - var translation = get.translation(list[i]); - if (translation[0] == '新' && translation.length == 3) { - translation = translation.slice(1, 3); - } - else { - translation = translation.slice(0, 2); - } - var item = dialog.add(''); - item.firstChild.addEventListener('click', clickItem); - item.firstChild.link = list[i]; - } - } - dialog.add(ui.create.div('.placeholder')); - event.dialog = dialog; - event.switchToAuto = function () { - event._result = event.skillai(event.list); - game.resume(); - }; - _status.imchoosing = true; - game.pause(); - } - else { - event._result = event.skillai(list); - } - 'step 1'; - _status.imchoosing = false; - if (event.dialog) { - event.dialog.close(); - } - event.result = { bool: true, skill: result }; - }, - discoverCard: function () { - 'step 0'; - var num = event.num || 3; - var choice; - if (typeof event.list == 'string' || typeof event.list == 'function') { - choice = get.inpile(event.list).randomGets(num); - } - else if (Array.isArray(event.list)) { - choice = event.list.randomGets(num); - } - else { - choice = Array.from(event.list).randomGets(num); - } - if (choice.length) { - var prompt = event.prompt; - if (!prompt) { - prompt = '选择一张牌'; - if (event.use) { - prompt += '使用之'; - } - else if (!event.nogain) { - prompt += '获得之'; - } - } - if (typeof choice[0] === 'string') { - var next = player.chooseVCardButton(choice, prompt, event.forced); - if (event.ai) { - next.set('ai', event.ai); - } - } - else if (get.itemtype(choice[0]) == 'card') { - var next = player.chooseCardButton(choice, prompt, event.forced); - if (event.ai) { - next.set('ai', event.ai); - } - } - else { - event.finish(); - } - } - else { - event.finish(); - } - 'step 1'; - event.result = { - bool: result.bool, - card: null, - choice: null - }; - if (result.bool && result.links.length) { - var link = result.links[0]; - var togain = null; - if (get.itemtype(link) == 'card') { - event.result.card = link; - togain = link; - } - else if (Array.isArray(link)) { - event.result.choice = link[2]; - togain = game.createCard(link[2]); - } - if (togain) { - if (event.use) { - player.chooseUseTarget(togain); - } - else if (!event.nogain) { - player.gain(togain, 'draw'); - game.log(player, '获得了一张牌'); - } - } - } - }, - chooseButton: function () { - "step 0"; - if (typeof event.dialog == 'number') { - event.dialog = get.idDialog(event.dialog); - } - if (event.createDialog && !event.dialog) { - if (Array.isArray(event.createDialog)) { - event.createDialog.add('hidden'); - event.dialog = ui.create.dialog.apply(this, event.createDialog); - } - event.closeDialog = true; - } - if (event.dialog == undefined) event.dialog = ui.dialog; - if (event.isMine() || event.dialogdisplay) { - event.dialog.style.display = ''; - event.dialog.open(); - } - // if (['chooseCharacter', 'chooseButtonOL'].includes(event.getParent().name)) event.complexSelect = true; - var filterButton = event.filterButton || function () { return true; }; - var selectButton = get.select(event.selectButton); - var buttons = event.dialog.buttons; - var buttonsx = []; - var num = 0; - for (var i = 0; i < buttons.length; i++) { - var button = buttons[i]; - if (filterButton(button, player)) { - num++; - buttonsx.add(button); - } - } - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - else if (event.direct && num == selectButton[0] || event.forceDirect) { - var buttons = buttonsx.slice(0, num); - event.result = { - bool: true, - button: [buttons], - links: get.links(buttons), - }; - event.dialog.close(); - } - else { - game.check(); - game.pause(); - } - } - else if (event.isOnline()) { - if (event.direct && num == 1 || event.forceDirect) { - var buttons = buttonsx.slice(0, num); - event.result = { - bool: true, - button: [buttons], - links: get.links(buttons), - }; - event.dialog.close(); - } - else { - event.send(); - } - delete event.callback; - } - else { - event.result = 'ai'; - } - if (event.onfree) { - lib.init.onfree(); - } - "step 1"; - if (event.result == 'ai') { - if (event.processAI) { - event.result = event.processAI(); - } - else { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - } - if (event.closeDialog) { - event.dialog.close(); - } - if (event.callback) { - event.callback(event.player, event.result); - } - event.resume(); - }, - chooseCardOL: function () { - 'step 0'; - event.targets = event.list.slice(0); - if (!_status.connectMode) { - event.result = []; - event.goto(7); - } - else { - for (var i = 0; i < event.list.length; i++) { - var target = event.list[i]; - target.wait(); - if (target.isOnline()) { - target.send(function (args, set) { - game.me.chooseCard.apply(game.me, args).set(set); - game.resume(); - }, event._args, event._set); - event.list.splice(i--, 1); - } - else if (target == game.me) { - event.withme = true; - event.list.splice(i--, 1); - } - } - } - 'step 1'; - if (event.list.length) { - event.target = event.list.shift(); - event.target.chooseCard.apply(event.target, event._args).set(event._set); - } - else { - event.goto(3); - } - 'step 2'; - event.target.unwait(result); - event.goto(1); - 'step 3'; - if (event.withme) { - game.me.chooseCard.apply(game.me, event._args).set(event._set); - } - else { - event.goto(5); - } - 'step 4'; - game.me.unwait(result); - 'step 5'; - if (!event.resultOL) { - game.pause(); - } - 'step 6'; - event.result = []; - for (var i = 0; i < event.targets.length; i++) { - event.result[i] = event.resultOL[event.targets[i].playerid] || {}; - if (event.result[i] == 'ai' && event.aiCard) { - event.result[i] = event.aiCard(event.targets[i]); - } - } - event.finish(); - 'step 7'; - if (event.list.length) { - event.target = event.list.shift(); - event.target.chooseCard.apply(event.target, event._args).set(event._set); - } - else { - for (var i = 0; i < event.targets.length; i++) { - if (!event.result[i]) { - event.result[i] = {}; - } - } - event.finish(); - } - 'step 8'; - event.result[event.targets.indexOf(event.target)] = result; - event.goto(7); - }, - chooseButtonOL: function () { - 'step 0'; - //ui.arena.classList.add('markhidden'); - for (var i = 0; i < event.list.length; i++) { - var current = event.list[i]; - current[0].wait(); - if (current[0].isOnline()) { - var target = current.shift(); - target.send(function (args, callback, switchToAuto, processAI) { - //ui.arena.classList.add('markhidden'); - var next = game.me.chooseButton.apply(game.me, args); - next.callback = callback; - next.switchToAuto = switchToAuto; - next.processAI = processAI; - next.complexSelect = true; - game.resume(); - }, current, event.callback, event.switchToAuto, event.processAI); - target._choose_button_ol = current; - event.list.splice(i--, 1); - } - else if (current[0] == game.me) { - event.last = current; - event.last.shift(); - event.list.splice(i--, 1); - } - } - 'step 1'; - if (event.list.length) { - var current = event.list.shift(); - event.target = current.shift(); - var next = event.target.chooseButton.apply(event.target, current); - next.callback = event.callback; - next.switchToAuto = event.switchToAuto; - next.processAI = event.processAI; - } - else { - event.goto(3); - } - 'step 2'; - event.target.unwait(result); - event.goto(1); - 'step 3'; - if (event.last) { - var next = game.me.chooseButton.apply(game.me, event.last); - next.callback = event.callback; - next.switchToAuto = event.switchToAuto; - next.processAI = event.processAI; - } - else { - event.goto(5); - } - 'step 4'; - game.me.unwait(result); - 'step 5'; - if (!event.resultOL) { - game.pause(); - } - 'step 6'; - /*game.broadcastAll(function(){ - ui.arena.classList.remove('markhidden'); - });*/ - event.result = event.resultOL; - }, - chooseCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true, - links: [] - }; - } - else { - if (event.isMine()) { - game.check(); - game.pause(); - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - if (event.prompt != false) { - var str; - if (typeof event.prompt == 'string') str = event.prompt; - else { - str = '请选择'; - var range = get.select(event.selectCard); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (Array.isArray(event.promptx)) { - for (var i = 0; i < event.promptx.length; i++) { - event.dialog.add(event.promptx[i]); - } - } - if (Array.isArray(event.selectCard)) { - event.promptbar = event.dialog.add('0/' + get.numStr(event.selectCard[1], 'card')); - event.custom.add.card = function () { - _status.event.promptbar.innerHTML = - ui.selected.cards.length + '/' + get.numStr(_status.event.selectCard[1], 'card'); - }; - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else if (event.skill) { - var skill = event.skill; - ui.click.cancel(); - event._aiexclude.add(skill); - event.redo(); - game.resume(); - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.glow_result && event.result.cards && !event.directresult) { - for (var i = 0; i < event.result.cards.length; i++) { - event.result.cards[i].classList.add('glow'); - } - } - if (event.dialog) event.dialog.close(); - }, - chooseTarget: function () { - "step 0"; - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.check(); - game.pause(); - if (event.createDialog && !event.dialog && Array.isArray(event.createDialog)) { - event.dialog = ui.create.dialog.apply(this, event.createDialog); - } - else if (event.prompt != false) { - var str; - if (typeof event.prompt == 'string') str = event.prompt; - else { - str = '请选择'; - var range = get.select(event.selectTarget); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '个目标'; - } - event.dialog = ui.create.dialog(str); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - if (event.promptbar != 'none') { - event.promptbar = event.dialog.add('0/' + get.numStr(get.select(event.selectTarget)[1], 'target')); - event.custom.add.target = function () { - _status.event.promptbar.innerHTML = - ui.selected.targets.length + '/' + get.numStr(get.select(event.selectTarget)[1], 'target'); - }; - } - } - else if (get.itemtype(event.dialog) == 'dialog') { - event.dialog.open(); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseTarget(event.ai) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - } - else { - ui.click.cancel(); - } - } - if (event.result.bool && event.animate !== false) { - for (var i = 0; i < event.result.targets.length; i++) { - event.result.targets[i].addTempClass('target'); - } - } - if (event.dialog) event.dialog.close(); - event.resume(); - "step 2"; - if (event.onresult) { - event.onresult(event.result); - } - if (event.result.bool && event.autodelay && !event.isMine()) { - if (typeof event.autodelay == 'number') { - game.delayx(event.autodelay); - } - else { - game.delayx(); - } - } - }, - chooseCardTarget: function () { - "step 0"; - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - game.check(); - game.pause(); - if (event.prompt != false) { - event.dialog = ui.create.dialog(event.prompt || '请选择卡牌和目标'); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if (ai.basic.chooseCard(event.ai1) || forced) { - if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { - ui.click.ok(); - _status.event._aiexclude.length = 0; - } - else { - ui.click.cancel(); - } - } - else { - ui.click.cancel(); - } - } - "step 2"; - event.resume(); - if (event.result.bool && event.animate !== false) { - for (var i = 0; i < event.result.targets.length; i++) { - event.result.targets[i].addTempClass('target'); - } - } - if (event.dialog) event.dialog.close(); - }, - chooseControl: function () { - "step 0"; - if (event.controls.length == 0) { - if (event.sortcard) { - var sortnum = 2; - if (event.sorttop) { - sortnum = 1; - } - for (var i = 0; i < event.sortcard.length + sortnum; i++) { - event.controls.push(get.cnNumber(i, true)); - } - } - else if (event.choiceList) { - for (var i = 0; i < event.choiceList.length; i++) { - event.controls.push('选项' + get.cnNumber(i + 1, true)); - } - } - else { - event.finish(); - return; - } - } - else if (event.choiceList && event.controls.length == 1 && event.controls[0] == 'cancel2') { - event.controls.shift(); - for (var i = 0; i < event.choiceList.length; i++) { - event.controls.push('选项' + get.cnNumber(i + 1, true)); - } - event.controls.push('cancel2'); - } - if (event.isMine()) { - if (event.arrangeSkill) { - var hidden = player.hiddenSkills.slice(0); - game.expandSkills(hidden); - if (hidden.length) { - for (var i of event.controls) { - if (_status.prehidden_skills.includes(i) && hidden.includes(i)) { - event.result = { - bool: true, - control: i, - }; - return; - } - } - } - } - else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill) && event.controls.includes('cancel2')) { - event.result = { - bool: true, - control: 'cancel2', - }; - return; - } - if (event.sortcard) { - var prompt = event.prompt || '选择一个位置'; - if (event.tosort) { - prompt += '放置' + get.translation(event.tosort); - } - event.dialog = ui.create.dialog(prompt, 'hidden'); - if (event.sortcard && event.sortcard.length) { - event.dialog.addSmall(event.sortcard); - } - else { - event.dialog.buttons = []; - event.dialog.add(ui.create.div('.buttons')); - } - var buttons = event.dialog.content.lastChild; - var sortnum = 2; - if (event.sorttop) { - sortnum = 1; - } - for (var i = 0; i < event.dialog.buttons.length + sortnum; i++) { - var item = ui.create.div('.button.card.pointerdiv.mebg'); - item.style.width = '50px'; - buttons.insertBefore(item, event.dialog.buttons[i]); - item.innerHTML = '
                                    第' + get.cnNumber(i + 1, true) + '张
                                    '; - if (i == event.dialog.buttons.length + 1) { - item.firstChild.innerHTML = '牌堆底'; - } - item.link = get.cnNumber(i, true); - item.listen(ui.click.dialogcontrol); - } - - event.dialog.forcebutton = true; - event.dialog.classList.add('forcebutton'); - event.dialog.open(); - } - else if (event.dialogcontrol) { - event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); - for (var i = 0; i < event.controls.length; i++) { - var item = event.dialog.add(''); - item.firstChild.listen(ui.click.dialogcontrol); - item.firstChild.link = event.controls[i]; - } - event.dialog.forcebutton = true; - event.dialog.classList.add('forcebutton'); - if (event.addDialog) { - for (var i = 0; i < event.addDialog.length; i++) { - if (get.itemtype(event.addDialog[i]) == 'cards') { - event.dialog.addSmall(event.addDialog[i]); - } - else { - event.dialog.add(event.addDialog[i]); - } - } - event.dialog.add(ui.create.div('.placeholder.slim')); - } - event.dialog.open(); - } - else { - if (event.seperate || lib.config.seperate_control) { - var controls = event.controls.slice(0); - var num = 0; - controls.remove('cancel2'); - if (event.direct && controls.length == 1 || event.forceDirect) { - event.result = { - control: event.controls[0].link, - links: get.links([event.controls[0]]), - }; - return; - } - else { - event.controlbars = []; - for (var i = 0; i < event.controls.length; i++) { - event.controlbars.push(ui.create.control([event.controls[i]])); - } - } - } - else { - var controls = event.controls.slice(0); - var num = 0; - controls.remove('cancel2'); - if (event.direct && controls.length == 1 || event.forceDirect) { - event.result = { - control: event.controls[0].link, - links: get.links([event.controls[0]]), - }; - return; - } - event.controlbar = ui.create.control(event.controls); - } - if (event.dialog) { - if (Array.isArray(event.dialog)) { - event.dialog = ui.create.dialog.apply(this, event.dialog); - } - event.dialog.open(); - } - else if (event.choiceList) { - event.dialog = ui.create.dialog(event.prompt || '选择一项', 'hidden'); - event.dialog.forcebutton = true; - event.dialog.open(); - for (var i = 0; i < event.choiceList.length; i++) { - event.dialog.add(''); - } - } - else if (event.prompt) { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, Boolean(event.prompt2.length <= 20 || event.centerprompt2)); - } - } - } - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - event.result = {}; - if (event.ai) { - var result = event.ai(event.getParent(), player); - if (typeof result == 'number') event.result.control = event.controls[result]; - else event.result.control = result; - } - else event.result.control = event.controls[event.choice]; - } - event.result.index = event.controls.indexOf(event.result.control); - event.choosing = false; - _status.imchoosing = false; - if (event.dialog && event.dialog.close) event.dialog.close(); - if (event.controlbar) event.controlbar.close(); - if (event.controlbars) { - for (var i = 0; i < event.controlbars.length; i++) { - event.controlbars[i].close(); - } - } - event.resume(); - }, - chooseBool: function () { - "step 0"; - if (event.isMine()) { - if (event.frequentSkill && !lib.config.autoskilllist.includes(event.frequentSkill)) { - ui.click.ok(); - return; - } - else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - ui.create.confirm('oc'); - if (event.createDialog && !event.dialog) { - if (Array.isArray(event.createDialog)) { - event.dialog = ui.create.dialog.apply(this, event.createDialog); - if (event.dialogselectx) { - for (var i = 0; i < event.dialog.buttons.length; i++) { - event.dialog.buttons[i].classList.add('selectedx'); - } - } - } - } - if (event.dialog) { - event.dialog.open(); - } - else if (event.prompt) { - event.dialog = ui.create.dialog(event.prompt); - if (event.prompt2) { - event.dialog.addText(event.prompt2, event.prompt2.length <= 20); - } - } - game.pause(); - game.countChoose(); - event.choosing = true; - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - "step 1"; - if (event.result == 'ai') { - if (event.ai) { - event.choice = event.ai(event.getParent(), player); - } - event.result = { bool: event.choice }; - } - _status.imchoosing = false; - event.choosing = false; - if (event.dialog) event.dialog.close(); - event.resume(); - }, - chooseDrawRecover: function () { - 'step 0'; - if (player.isHealthy() && event.forced) { - player.draw(event.num1); - event.finish(); - return; - } - var controls = ['draw_card']; - if (player.isDamaged()) { - event.num2 = Math.min(event.num2, player.maxHp - player.hp); - controls.push('recover_hp'); - } - if (!event.forced) { - controls.push('cancel2'); - } - var prompt = event.prompt; - if (!prompt) { - if (player.isHealthy()) { - prompt = '是否摸' + get.cnNumber(event.num1) + '张牌?'; - } - else { - prompt = '摸' + get.cnNumber(event.num1) + '张牌或回复' + get.cnNumber(event.num2) + '点体力'; - } - } - var next = player.chooseControl(controls); - next.set('prompt', prompt); - if (event.hsskill) next.setHiddenSkill(event.hsskill); - if (event.ai) { - next.set('ai', event.ai); - } - else { - var choice; - if (player.isDamaged() && get.recoverEffect(player) > 0 && ( - player.hp == 1 || player.needsToDiscard() || - player.hasSkillTag('maixie_hp') || event.num2 > event.num1 || - (event.num2 == event.num1 && player.needsToDiscard(1)) - )) { - choice = 'recover_hp'; - } - else { - choice = 'draw_card'; - } - next.set('ai', function () { - return _status.event.choice; - }); - next.set('choice', choice); - } - 'step 1'; - if (result.control != 'cancel2') { - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - if (result.control == 'draw_card') { - player.draw(event.num1); - } - else { - player.recover(event.num2); - } - } - event.result = result; - }, - choosePlayerCard: function () { - "step 0"; - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - else { - event.dialog.add('选择' + get.translation(target) + '的一张牌'); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var expand_length = 0; - var directh = (!lib.config.unauto_choose && !event.complexSelect); - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getCards('h'); - if (hs.length) { - expand_length += Math.ceil(hs.length / 6); - var title = event.dialog.add('
                                    手牌区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getCards('e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
                                    装备区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getCards('j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
                                    判定区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - var shown = js.filter(card => { - var name = (card.viewAs || card.name), info = lib.card[name]; - if (!info || !info.blankCard) return true; - return false; - }); - if (shown.length < js.length && !target.isUnderControl(true)) { - var hidden = js.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else{ - event.dialog.add(js); - } - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.finish(); - return; - } var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { - ui.click.cancel(); - return; - } - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('choose-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - if (event.result.links) { - event.result.cards = event.result.links.slice(0); - } - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('choose-player-card'); - }, 500); - }, - discardPlayerCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - links: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true - }; - event.cards = event.directresult.slice(0); - event.goto(2); - return; - } - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt == undefined) { - var str = '弃置' + get.translation(target); - var range = get.select(event.selectButton); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - event.prompt = str; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var directh = (!lib.config.unauto_choose && !event.complexSelect); - var expand_length = 0; - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getDiscardableCards(player, 'h'); - expand_length += Math.ceil(hs.length / 6); - if (hs.length) { - var title = event.dialog.add('
                                    手牌区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getDiscardableCards(player, 'e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
                                    装备区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getDiscardableCards(player, 'j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
                                    判定区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - var shown = js.filter(card => { - var name = (card.viewAs || card.name), info = lib.card[name]; - if (!info || !info.blankCard) return true; - return false; - }); - if (shown.length < js.length && !target.isUnderControl(true)) { - var hidden = js.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else{ - event.dialog.add(js); - } - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.finish(); - return; - } - var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('discard-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - "step 2"; - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('discard-player-card'); - }, 500); - if (event.result.bool && event.result.links && !game.online) { - if (event.logSkill) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - var cards = []; - for (var i = 0; i < event.result.links.length; i++) { - cards.push(event.result.links[i]); - } - event.result.cards = event.result.links.slice(0); - event.cards = cards; - event.trigger("rewriteDiscardResult"); - } - "step 3"; - if (event.boolline) { - player.line(target, 'green'); - } - if (!event.chooseonly) { - var next = target.discard(event.cards); - if (player != target) next.notBySelf = true; - next.discarder = player; - event.done = next; - if (event.delay === false) { - next.set('delay', false); - } - } - }, - gainPlayerCard: function () { - "step 0"; - if (event.directresult) { - event.result = { - buttons: [], - cards: event.directresult.slice(0), - links: event.directresult.slice(0), - targets: [], - confirm: 'ok', - bool: true - }; - event.cards = event.directresult.slice(0); - event.goto(2); - return; - } - if (!event.dialog) event.dialog = ui.create.dialog('hidden'); - else if (!event.isMine()) { - event.dialog.style.display = 'none'; - } - if (event.prompt == undefined) { - var str = '获得' + get.translation(target); - var range = get.select(event.selectButton); - if (range[0] == range[1]) str += get.cnNumber(range[0]); - else if (range[1] == Infinity) str += '至少' + get.cnNumber(range[0]); - else str += get.cnNumber(range[0]) + '至' + get.cnNumber(range[1]); - str += '张'; - if (event.position == 'h' || event.position == undefined) str += '手'; - if (event.position == 'e') str += '装备'; - str += '牌'; - event.prompt = str; - } - if (event.prompt) { - event.dialog.add(event.prompt); - } - if (event.prompt2) { - event.dialog.addText(event.prompt2); - } - var expand_length = 0; - var directh = (!lib.config.unauto_choose && !event.complexSelect); - for (var i = 0; i < event.position.length; i++) { - if (event.position[i] == 'h') { - var hs = target.getGainableCards(player, 'h'); - if (hs.length) { - expand_length += Math.ceil(hs.length / 6); - var title = event.dialog.add('
                                    手牌区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - hs.randomSort(); - if (event.visible || target.isUnderControl(true) || player.hasSkillTag('viewHandcard', null, target, true)) { - event.dialog.add(hs); - directh = false; - } - else { - var shown = hs.filter(card => get.is.shownCard(card)); - if (shown.length) { - var hidden = hs.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else { - event.dialog.add([hs, 'blank']); - } - } - } - } - else if (event.position[i] == 'e') { - var es = target.getGainableCards(player, 'e'); - if (es.length) { - expand_length += Math.ceil(es.length / 6); - var title = event.dialog.add('
                                    装备区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - event.dialog.add(es); - directh = false; - } - } - else if (event.position[i] == 'j') { - var js = target.getGainableCards(player, 'j'); - if (js.length) { - expand_length += Math.ceil(js.length / 6); - var title = event.dialog.add('
                                    判定区
                                    '); - title.style.margin = '0px'; - title.style.padding = '0px'; - var shown = js.filter(card => { - var name = (card.viewAs || card.name), info = lib.card[name]; - if (!info || !info.blankCard) return true; - return false; - }); - if (shown.length < js.length && !target.isUnderControl(true)) { - var hidden = js.filter(card => !shown.includes(card)); - var buttons = ui.create.div('.buttons', event.dialog.content); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(shown, 'card', buttons)); - event.dialog.buttons = event.dialog.buttons.concat(ui.create.buttons(hidden, 'blank', buttons)); - if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; - if (event.dialog.buttons.length > 3) { - event.dialog.classList.remove('forcebutton-auto'); - } - else if (!event.dialog.noforcebutton) { - event.dialog.classList.add('forcebutton-auto'); - } - } - else{ - event.dialog.add(js); - } - directh = false; - } - } - } - if (event.dialog.buttons.length == 0) { - event.dialog.close(); - event.finish(); - return; - } - var cs = target.getCards(event.position); - var select = get.select(event.selectButton); - var directFilter = (event.forced && typeof event.filterOk != 'function' && typeof event.selectButton != 'function' && event.filterButton == lib.filter.all); - if (directFilter && select[0] >= cs.length) { - event.result = { - bool: true, - buttons: event.dialog.buttons, - links: cs - }; - } - else if (directFilter && directh && !event.isOnline() && select[0] == select[1]) { - event.result = { - bool: true, - buttons: event.dialog.buttons.randomGets(select[0]), - links: [] - }; - for (var i = 0; i < event.result.buttons.length; i++) { - event.result.links[i] = event.result.buttons[i].link; - } - } - else { - if (event.isMine()) { - event.dialog.open(); - game.check(); - game.pause(); - if (expand_length > 2) { - ui.arena.classList.add('gain-player-card'); - event.dialog.classList.add('fullheight'); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.result = 'ai'; - } - } - "step 1"; - if (event.result == 'ai') { - game.check(); - if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) ui.click.ok(); - else ui.click.cancel(); - } - event.dialog.close(); - "step 2"; - event.resume(); - setTimeout(function () { - ui.arena.classList.remove('gain-player-card'); - }, 500); - if (game.online || !event.result.bool) { - event.finish(); - } - "step 3"; - if (event.logSkill && event.result.bool && !game.online) { - if (typeof event.logSkill == 'string') { - player.logSkill(event.logSkill); - } - else if (Array.isArray(event.logSkill)) { - player.logSkill.apply(player, event.logSkill); - } - } - var cards = []; - for (var i = 0; i < event.result.links.length; i++) { - cards.push(event.result.links[i]); - } - event.result.cards = event.result.links.slice(0); - event.cards = cards; - event.trigger("rewriteGainResult"); - "step 4"; - if (event.boolline) { - player.line(target, 'green'); - } - if (!event.chooseonly) { - if (event.delay !== false) { - var next = player.gain(event.cards, target, event.visibleMove ? 'give' : 'giveAuto', 'bySelf'); - event.done = next; - } - else { - var next = player.gain(event.cards, target, 'bySelf'); - event.done = next; - target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - if (event.visibleMove) next.visible = true; - } - } - else target[event.visibleMove ? '$give' : '$giveAuto'](cards, player); - }, - showHandcards: function () { - "step 0"; - if (player.countCards('h') == 0) { - event.finish(); - return; - } - var cards = player.getCards('h'); - player.showCards(cards).setContent(function () { }); - var str = get.translation(player.name) + '的手牌'; - if (typeof event.prompt == 'string') { - str = event.prompt; - } - event.dialog = ui.create.dialog(str, cards); - event.dialogid = lib.status.videoId++; - event.dialog.videoId = event.dialogid; - game.broadcast(function (str, cards, id) { - ui.create.dialog(str, cards).videoId = id; - }, str, cards, event.dialogid); - game.log(player, '展示了', cards); - game.addVideo('showCards', player, [str, get.cardsInfo(cards)]); - game.delayx(2); - "step 1"; - game.broadcast('closeDialog', event.dialogid); - event.dialog.close(); - }, - showCards: function () { - "step 0"; - if (get.itemtype(cards) != 'cards') { - event.finish(); - return; - } - if (!event.str) { - event.str = get.translation(player.name) + '展示的牌'; - } - event.dialog = ui.create.dialog(event.str, cards); - event.dialogid = lib.status.videoId++; - event.dialog.videoId = event.dialogid; - - if (event.hiddencards) { - for (var i = 0; i < event.dialog.buttons.length; i++) { - if (event.hiddencards.includes(event.dialog.buttons[i].link)) { - event.dialog.buttons[i].className = 'button card'; - event.dialog.buttons[i].innerHTML = ''; - } - } - } - game.broadcast(function (str, cards, cards2, id) { - var dialog = ui.create.dialog(str, cards); - dialog.forcebutton = true; - dialog.videoId = id; - if (cards2) { - for (var i = 0; i < dialog.buttons.length; i++) { - if (cards2.includes(dialog.buttons[i].link)) { - dialog.buttons[i].className = 'button card'; - dialog.buttons[i].innerHTML = ''; - } - } - } - }, event.str, cards, event.hiddencards, event.dialogid); - if (event.hiddencards) { - var cards2 = cards.slice(0); - for (var i = 0; i < event.hiddencards.length; i++) { - cards2.remove(event.hiddencards[i]); - } - game.log(player, '展示了', cards2); - } - else { - game.log(player, '展示了', cards); - } - game.addCardKnower(cards, 'everyone'); - game.delayx(event.delay_time || 2.5); - game.addVideo('showCards', player, [event.str, get.cardsInfo(cards)]); - "step 1"; - game.broadcast('closeDialog', event.dialogid); - event.dialog.close(); - }, - viewCards: function () { - "step 0"; - game.addCardKnower(event.cards, player); - if (player == game.me) { - event.dialog = ui.create.dialog(event.str, event.cards); - if (event.isMine()) { - game.pause(); - ui.create.confirm('o'); - game.countChoose(); - event.choosing = true; - } - else { - event.finish(); - event.result = 'viewed'; - setTimeout(function () { - event.dialog.close(); - }, 2 * lib.config.duration); - game.delayx(2); - } - } - else if (event.isOnline()) { - event.send(); - } - else { - event.finish(); - } - "step 1"; - event.result = 'viewed'; - _status.imchoosing = false; - event.choosing = false; - if (event.dialog) event.dialog.close(); - }, - moveCard: function () { - 'step 0'; - if (!player.canMoveCard(null, event.nojudge, event.sourceTargets, event.aimTargets, event.filter, event.canReplace ? 'canReplace' : 'noReplace')) { - event.finish(); - return; - } - var next = player.chooseTarget(2, function (card, player, target) { - var filterCard = get.event('filter'); - if (ui.selected.targets.length) { - if (!get.event('aimTargets').includes(target)) return false; - var from = ui.selected.targets[0]; - var js = from.getCards('j', filterCard); - for (var i = 0; i < js.length; i++) { - if (_status.event.nojudge) break; - if (target.canAddJudge(js[i])) return true; - } - if (target.isMin()) return false; - var es = from.getCards('e', filterCard); - for (var i = 0; i < es.length; i++) { - if (target.canEquip(es[i], _status.event.canReplace)) return true; - } - return false; - } - else { - if (!get.event('sourceTargets').includes(target)) return false; - var range = 'ej'; - if (_status.event.nojudge) range = 'e'; - return target.countCards(range, filterCard) > 0; - } - }); - next.set('nojudge', event.nojudge || false); - next.set('ai', function (target) { - var player = _status.event.player; - var att = get.attitude(player, target); - var sgnatt = get.sgn(att); - var aimTargets = get.event('aimTargets'), filterCard = get.event('filter'); - if (ui.selected.targets.length == 0) { - if (att > 0) { - if (!_status.event.nojudge && target.countCards('j', function (card) { - if (!filterCard(card)) return false; - return game.hasPlayer(function (current) { - if (!aimTargets.includes(current)) return false; - return current != target && current.canAddJudge(card) && get.attitude(player, current) < 0; - }); - })) return 14; - if (target.countCards('e', function (card) { - if (!filterCard(card)) return false; - return get.value(card, target) < 0 && game.hasPlayer(function (current) { - if (!aimTargets.includes(current)) return false; - return current != target && get.attitude(player, current) < 0 && current.canEquip(card, _status.event.canReplace) && get.effect(target, card, player, player) < 0; - }); - }) > 0) return 9; - } - else if (att < 0) { - if (game.hasPlayer(function (current) { - if (current != target && get.attitude(player, current) > 0) { - var es = target.getCards('e', filterCard); - for (var i = 0; i < es.length; i++) { - if (get.value(es[i], target) > 0 && current.canEquip(es[i], _status.event.canReplace) && get.effect(current, es[i], player, player) > (_status.event.canReplace ? get.effect(target, es[i], player, player) : 0)) return true; - } - } - })) { - return -att; - } - } - return 0; - } - var es = ui.selected.targets[0].getCards('e', filterCard); - var i; - var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); - for (i = 0; i < es.length; i++) { - if (sgnatt != 0 && att2 != 0 && sgnatt != att2 && - get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && - get.sgn(get.effect(target, es[i], player, target)) == sgnatt && - target.canEquip(es[i], _status.event.canReplace)) { - return Math.abs(att); - } - } - if (i == es.length && (_status.event.nojudge || !ui.selected.targets[0].countCards('j', function (card) { - if (!filterCard(card)) return false; - return target.canAddJudge(card); - }) || att2 <= 0)) { - return 0; - } - return -att * att2; - }); - next.set('multitarget', true); - next.set('targetprompt', _status.event.targetprompt || ['被移走', '移动目标']); - next.set('prompt', event.prompt || '移动场上的一张牌'); - next.set('filter', event.filter); - next.set('sourceTargets', event.sourceTargets || game.filterPlayer()); - next.set('aimTargets', event.aimTargets || game.filterPlayer()); - next.set('canReplace', event.canReplace); - next.set('custom', get.copy(event.custom)); - if (event.prompt2) next.set('prompt2', event.prompt2); - if (event.forced) next.set('forced', true); - 'step 1'; - event.result = result; - if (result.bool) { - if (event.logSkill) player.logSkill(event.logSkill, result.targets, false); - player.line2(result.targets, 'green'); - event.targets = result.targets; - } - else { - event.finish(); - } - 'step 2'; - game.delay(); - 'step 3'; - if (targets.length == 2) { - player.choosePlayerCard('ej', true, function (button) { - var player = _status.event.player; - var targets0 = _status.event.targets0; - var targets1 = _status.event.targets1; - if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) { - if (get.position(button.link) == 'j') return 12; - if (get.value(button.link, targets0) < 0 && get.effect(targets1, button.link, player, targets1) > 0) return 10; - return 0; - } - else { - if (get.position(button.link) == 'j') return -10; - return get.value(button.link) * get.effect(targets1, button.link, player, targets1); - } - }, targets[0]).set('nojudge', event.nojudge || false).set('targets0', targets[0]).set('targets1', targets[1]).set('filterButton', function (button) { - var targets1 = _status.event.targets1; - if (!get.event('filter')(button.link)) return false; - if (get.position(button.link) == 'j') { - if (_status.event.nojudge) return false; - return targets1.canAddJudge(button.link); - } - else { - return targets1.canEquip(button.link, _status.event.canReplace); - } - }).set('filter', event.filter).set('canReplace', event.canReplace).set('custom', get.copy(event.custom)); - } - else { - event.finish(); - } - 'step 4'; - if (result.bool && result.links.length) { - var link = result.links[0]; - if (get.position(link) == 'e') { - event.targets[1].equip(link); - } - else if (link.viewAs) { - event.targets[1].addJudge({ name: link.viewAs }, [link]); - } - else { - event.targets[1].addJudge(link); - } - event.targets[0].$give(link, event.targets[1], false); - game.log(event.targets[0], '的', link, '被移动给了', event.targets[1]); - event.result.card = link; - event.result.position = get.position(link); - game.delay(); - } - }, - useCard: function () { - "step 0"; - if (!card) { - console.log('err: no card', get.translation(event.player)); - event.finish(); - return; - } - if (!get.info(card, false).noForceDie) event.forceDie = true; - if (cards.length) { - var owner = (get.owner(cards[0]) || player); - var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); - var directDiscard = []; - for (var i = 0; i < cards.length; i++) { - if (!next.cards.includes(cards[i])) { - directDiscard.push(cards[i]); - } - } - if (directDiscard.length) game.cardsGotoOrdering(directDiscard); - } - //player.using=cards; - var cardaudio = true; - if (event.skill) { - if (lib.skill[event.skill].audio) { - cardaudio = false; - } - if (lib.skill[event.skill].log != false) { - player.logSkill(event.skill); - } - if (get.info(event.skill).popname) { - player.tryCardAnimate(card, event.card.name, 'metal', true); - } - } - else if (!event.nopopup) { - if (lib.translate[event.card.name + '_pop']) { - player.tryCardAnimate(card, lib.translate[event.card.name + '_pop'], 'metal'); - } - else { - player.tryCardAnimate(card, event.card.name, 'metal'); - } - } - if (event.audio === false) { - cardaudio = false; - } - if (cardaudio) game.broadcastAll((player, card) => { - game.playCardAudio(card, player); - }, player, card); - event.id = get.id(); - if (!Array.isArray(event.excluded)) event.excluded = []; - if (!Array.isArray(event.directHit)) event.directHit = []; - if (typeof event.customArgs != 'object' || typeof event.customArgs.default != 'object') event.customArgs = { default: {} }; - if (typeof event.baseDamage != 'number') event.baseDamage = get.info(card, false).baseDamage || 1; - if (typeof event.effectCount != 'number') event.effectCount = get.info(card, false).effectCount || 1; - event.effectedCount = 0; - if (event.oncard) { - event.oncard(event.card, event.player); - } - player.actionHistory[player.actionHistory.length - 1].useCard.push(event); - game.getGlobalHistory().useCard.push(event); - if (event.addCount !== false) { - if (player.stat[player.stat.length - 1].card[card.name] == undefined) { - player.stat[player.stat.length - 1].card[card.name] = 1; - } - else { - player.stat[player.stat.length - 1].card[card.name]++; - } - } - if (event.skill) { - if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { - player.stat[player.stat.length - 1].skill[event.skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[event.skill]++; - } - var sourceSkill = get.info(event.skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - - if (event.animate != false) { - if (event.throw !== false){ - player.$throw(cards); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - var waitingForTransition = get.time(); - event.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete event.waitingForTransition; - }); - } - } - } - event.trigger('useCard0'); - "step 1"; - if (event.animate != false && event.line != false && !event.hideTargets) { - if (card.name == 'wuxie' && event.getParent()._info_map) { - var evtmap = event.getParent()._info_map; - if (evtmap._source) evtmap = evtmap._source; - var lining = (evtmap.multitarget ? evtmap.targets : evtmap.target) || event.player; - if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { - player.line(lining[0], 'green'); - } - else { - player.line(lining, 'green'); - } - } - else if (card.name == 'youdishenru' && event.getParent().source) { - var lining = event.getParent().sourcex || event.getParent().source2 || event.getParent().source; - if (lining == player && event.getParent().sourcex2) { - lining = event.getParent().sourcex2; - } - if (Array.isArray(lining) && event.getTrigger().name == 'jiedao') { - player.line(lining[0], 'green'); - } - else { - player.line(lining, 'green'); - } - } - else { - var config = {}; - var nature = get.natureList(card)[0]; - if (nature || card.classList && card.classList.contains(nature)) config.color = nature; - if (event.addedTarget) { - player.line2(targets.concat(event.addedTargets), config); - } - else if (get.info(card, false).multitarget && targets.length > 1 && !get.info(card, false).multiline) { - player.line2(targets, config); - } - else { - player.line(targets, config); - } - } - } - if (targets.length && !event.hideTargets) { - var str = (targets.length == 1 && targets[0] == player) ? '#b自己' : targets; - if (cards.length && !card.isCard) { - if (event.addedTarget) { - game.log(player, '对', str, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); - } - else { - game.log(player, '对', str, '使用了', card, '(', cards, ')'); - } - } - else { - if (event.addedTarget) { - game.log(player, '对', str, '使用了', card, '(指向', event.addedTargets, ')'); - } - else { - game.log(player, '对', str, '使用了', card); - } - } - } - else { - if (cards.length && !card.isCard) { - if (event.addedTarget) { - game.log(player, '使用了', card, '(', cards, ',指向', event.addedTargets, ')'); - } - else { - game.log(player, '使用了', card, '(', cards, ')'); - } - } - else { - if (event.addedTarget) { - game.log(player, '使用了', card, '(指向', event.addedTargets, ')'); - } - else { - game.log(player, '使用了', card); - } - } - } - if (card.name == 'wuxie') { - game.logv(player, [card, cards], [event.getTrigger().card]); - } - else { - game.logv(player, [card, cards], targets); - } - event.trigger('useCard1'); - "step 2"; - event.trigger('yingbian'); - "step 3"; - event.trigger('useCard2'); - "step 4"; - event.trigger('useCard'); - event._oncancel = function () { - game.broadcastAll(function (id) { - if (ui.tempnowuxie && ui.tempnowuxie._origin == id) { - ui.tempnowuxie.close(); - delete ui.tempnowuxie; - } - }, event.id); - }; - "step 5"; - event.sortTarget = function (animate, sort) { - var info = get.info(card, false); - if (num == 0 && targets.length > 1) { - if (!info.multitarget) { - if (!event.fixedSeat && !sort) { - targets.sortBySeat((_status.currentPhase || player)); - } - if (animate) for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - else if (animate) { - for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - } - }; - event.sortTarget(); - event.getTriggerTarget = function (list1, list2) { - var listx = list1.slice(0).sortBySeat((_status.currentPhase || player)); - for (var i = 0; i < listx.length; i++) { - if (get.numOf(list2, listx[i]) < get.numOf(listx, listx[i])) return listx[i]; - } - return null; - }; - "step 6"; - if (event.all_excluded) return; - if (!event.triggeredTargets1) event.triggeredTargets1 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets1); - if (target) { - event.triggeredTargets1.push(target); - var next = game.createEvent('useCardToPlayer', false); - if (!event.isFirstTarget1) { - event.isFirstTarget1 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 7"; - if (event.all_excluded) return; - if (!event.triggeredTargets2) event.triggeredTargets2 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets2); - if (target) { - event.triggeredTargets2.push(target); - var next = game.createEvent('useCardToTarget', false); - if (!event.isFirstTarget2) { - event.isFirstTarget2 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 8"; - var info = get.info(card, false); - if (!info.nodelay && event.animate != false) { - if (event.delayx !== false) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - } - "step 9"; - if (event.all_excluded) return; - if (!event.triggeredTargets3) event.triggeredTargets3 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets3); - if (target) { - event.triggeredTargets3.push(target); - var next = game.createEvent('useCardToPlayered', false); - if (!event.isFirstTarget3) { - event.isFirstTarget3 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - event.redo(); - } - "step 10"; - if (event.all_excluded) return; - if (!event.triggeredTargets4) event.triggeredTargets4 = []; - var target = event.getTriggerTarget(targets, event.triggeredTargets4); - if (target) { - event.triggeredTargets4.push(target); - var next = game.createEvent('useCardToTargeted', false); - if (!event.isFirstTarget4) { - event.isFirstTarget4 = true; - next.isFirstTarget = true; - } - next.setContent('emptyEvent'); - next.targets = targets; - next.target = target; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.excluded = event.excluded; - next.directHit = event.directHit; - next.customArgs = event.customArgs; - if (event.forceDie) next.forceDie = true; - if (targets.length == event.triggeredTargets4.length) { - event.sortTarget(); - } - event.redo(); - } - "step 11"; - if (event.all_excluded) return; - event.effectedCount++; - event.num = 0; - var info = get.info(card, false); - if (info.contentBefore) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent(info.contentBefore); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - if (event.forceDie) next.forceDie = true; - } - else if (info.reverseOrder && get.is.versus() && targets.length > 1) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent('reverseOrder'); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - if (event.forceDie) next.forceDie = true; - } - else if (info.singleCard && info.filterAddedTarget && event.addedTargets && event.addedTargets.length < targets.length) { - var next = game.createEvent(card.name + 'ContentBefore'); - next.setContent('addExtraTarget'); - next.target = target; - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.type = 'precard'; - next.addedTarget = event.addedTarget; - next.addedTargets = event.addedTargets; - if (event.forceDie) next.forceDie = true; - } - "step 12"; - if (event.all_excluded) return; - var info = get.info(card, false); - if (num == 0 && targets.length > 1) { - event.sortTarget(true, true); - } - if (targets[num] && targets[num].isDead()) return; - if (targets[num] && targets[num].isOut()) return; - if (targets[num] && targets[num].removed) return; - if (targets[num] && info.ignoreTarget && info.ignoreTarget(card, player, targets[num])) return; - if (targets.length == 0 && !info.notarget) return; - if (targets[num] && event.excluded.includes(targets[num])) { - var next = game.createEvent('useCardToExcluded', false); - next.setContent('emptyEvent'); - next.targets = targets; - next.target = targets[num]; - next.num = num; - next.card = card; - next.cards = cards; - next.player = player; - return; - } - var next = game.createEvent(card.name); - next.setContent(info.content); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.num = num; - next.type = 'card'; - next.skill = event.skill; - next.multitarget = info.multitarget; - next.preResult = event.preResult; - next.baseDamage = event.baseDamage; - if (event.forceDie) next.forceDie = true; - if (event.addedTargets) { - next.addedTargets = event.addedTargets; - next.addedTarget = event.addedTargets[num]; - next._targets = event._targets; - } - if (info.targetDelay === false) { - event.targetDelay = false; - } - next.target = targets[num]; - for (var i in event.customArgs.default) next[i] = event.customArgs.default[i]; - if (next.target && event.customArgs[next.target.playerid]) { - var customArgs = event.customArgs[next.target.playerid]; - for (var i in customArgs) next[i] = customArgs[i]; - } - if (next.target && event.directHit.includes(next.target)) next.directHit = true; - if (next.target && !info.multitarget) { - if (num == 0 && targets.length > 1) { - // var ttt=next.target; - // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); - } - else { - next.target.addTempClass('target'); - } - } - if (!info.nodelay && num > 0) { - if (event.targetDelay !== false) { - game.delayx(0.5); - } - } - "step 13"; - if (event.all_excluded) return; - if (!get.info(event.card, false).multitarget && num < targets.length - 1 && !event.cancelled) { - event.num++; - event.goto(12); - } - "step 14"; - if (event.all_excluded) return; - if (get.info(card, false).contentAfter) { - var next = game.createEvent(card.name + 'ContentAfter'); - next.setContent(get.info(card, false).contentAfter); - next.targets = targets; - next.card = card; - next.cards = cards; - next.player = player; - next.skill = event.skill; - next.preResult = event.preResult; - next.type = 'postcard'; - if (event.forceDie) next.forceDie = true; - } - "step 15"; - if (event.all_excluded) return; - if (event.effectedCount < event.effectCount) { - if (document.getElementsByClassName('thrown').length) { - if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); - } - event.goto(11); - } - "step 16"; - if (event.postAi) { - event.player.logAi(event.targets, event.card); - } - if (event._result) { - event.result = event._result; - } - //delete player.using; - if (document.getElementsByClassName('thrown').length) { - if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); - } - else { - event.finish(); - } - "step 17"; - event._oncancel(); - }, - useSkill: function () { - "step 0"; - var info = get.info(event.skill); - if (!info.noForceDie) event.forceDie = true; - if (!info.noForceOut) event.includeOut = true; - event._skill = event.skill; - game.trySkillAudio(event.skill, player); - var checkShow = player.checkShow(event.skill); - if (info.discard != false && info.lose != false && !info.viewAs) { - player.discard(cards).delay = false; - if (lib.config.low_performance) { - event.discardTransition = true; - } - } - else { - if (info.lose != false) { - if (info.losetrigger == false) { - var losecard = player.lose(cards, ui.special)._triggered = null; - } - else { - var losecard = player.lose(cards, ui.special); - if (info.visible) losecard.visible = true; - if (info.loseTo) losecard.position = ui[info.loseTo]; - if (info.insert) losecard.insert_card = true; - if (losecard.position == ui.special && info.toStorage) losecard.toStorage = true; - } - } - if (!info.prepare && info.viewAs) { - player.$throw(cards); - if (losecard) losecard.visible = true; - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - var waitingForTransition = get.time(); - event.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete event.waitingForTransition; - }); - } - } - } - if (info.line != false && targets.length) { - var config = {}; - if (get.is.object(info.line)) config = info.line; - else if (info.line == 'fire') { - config.color = 'fire'; - } - else if (info.line == 'thunder') { - config.color = 'thunder'; - } - else if (info.line === undefined || info.line == 'green') { - config.color = 'green'; - } - if (info.multitarget && !info.multiline && targets.length > 1) { - player.line2(targets, config); - } - else { - player.line(targets, config); - } - } - var str = ''; - if (targets && targets.length && info.log != 'notarget') { - str += '对' + (targets[0] == player ? '自己' : get.translation(targets[0])); - for (var i = 1; i < targets.length; i++) { - str += '、' + (targets[i] == player ? '自己' : get.translation(targets[i])); - } - str += ''; - } - str += '发动了'; - if (!info.direct && info.log !== false) { - game.log(player, str, '【' + get.skillTranslation(skill, player) + '】'); - if (info.logv !== false) game.logv(player, skill, targets); - player.trySkillAnimate(skill, skill, checkShow); - } - if (event.addCount != false) { - if (player.stat[player.stat.length - 1].skill[skill] == undefined) { - player.stat[player.stat.length - 1].skill[skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[skill]++; - } - var sourceSkill = get.info(skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - if (player.stat[player.stat.length - 1].allSkills == undefined) { - player.stat[player.stat.length - 1].allSkills = 1; - } - else { - player.stat[player.stat.length - 1].allSkills++; - } - if (info.prepare) { - switch (info.prepare) { - case 'give': if (losecard) losecard.visible = true; player.$give(cards, targets[0]); break; - case 'give2': player.$give(cards.length, targets[0]); break; - case 'throw': if (losecard) losecard.visible = true; player.$throw(cards); break; - case 'throw2': player.$throw(cards.length); break; - default: info.prepare(cards, player, targets); - } - } - if (info.round) { - var roundname = skill + '_roundcount'; - player.storage[roundname] = game.roundNumber; - player.syncStorage(roundname); - player.markSkill(roundname); - } - var name = event.skill; - var players = player.getSkills(false, false, false); - var equips = player.getSkills('e'); - var global = lib.skill.global.slice(0); - var logInfo = { - skill: name, - targets: targets, - event: _status.event, - }; - if (info.sourceSkill) { - logInfo.sourceSkill = info.sourceSkill; - if (global.includes(info.sourceSkill)) { - logInfo.type = 'global'; - } - else if (players.includes(info.sourceSkill)) { - logInfo.type = 'player'; - } - else if (equips.includes(info.sourceSkill)) { - logInfo.type = 'equip'; - } - } - else { - if (global.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'global'; - } - else if (players.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'player'; - } - else if (equips.includes(name)) { - logInfo.sourceSkill = name; - logInfo.type = 'equip'; - } - else { - var bool = false; - for (var i of players) { - var expand = [i]; - game.expandSkills(expand); - if (expand.includes(name)) { - bool = true; - logInfo.sourceSkill = i; - logInfo.type = 'player'; - break; - } - } - if (!bool) { - for (var i of players) { - var expand = [i]; - game.expandSkills(expand); - if (expand.includes(name)) { - logInfo.sourceSkill = i; - logInfo.type = 'equip'; - break; - } - } - } - } - } - event.sourceSkill = logInfo.sourceSkill; - event.type = logInfo.type; - player.getHistory('useSkill').push(logInfo); - event.trigger('useSkill'); - "step 1"; - var info = get.info(event.skill); - if (info && info.contentBefore) { - var next = game.createEvent(event.skill + 'ContentBefore'); - next.setContent(info.contentBefore); - next.targets = targets; - next.cards = cards; - next.player = player; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - } - "step 2"; - if (!event.skill) { - console.log('error: no skill', get.translation(event.player), event.player.getSkills()); - if (event._skill) { - event.skill = event._skill; - console.log(event._skill); - } - else { - event.finish(); - return; - } - } - var info = get.info(event.skill); - if (targets[num] && targets[num].isDead() || - targets[num] && targets[num].isOut() || - targets[num] && targets[num].removed) { - if (!info.multitarget && num < targets.length - 1) { - event.num++; - event.redo(); - } - return; - } - var next = game.createEvent(event.skill); - next.setContent(info.content); - next.targets = targets; - next.cards = cards; - next.player = player; - next.num = num; - next.multitarget = info.multitarget; - if (num == 0 && next.targets.length > 1) { - if (!info.multitarget) { - lib.tempSortSeat = player; - targets.sort(lib.sort.seat); - delete lib.tempSortSeat; - } - for (var i = 0; i < targets.length; i++) { - targets[i].addTempClass('target'); - } - } - next.target = targets[num]; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - if (next.target && !info.multitarget) { - if (num == 0 && targets.length > 1) { - // var ttt=next.target; - // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); - } - else { - next.target.addTempClass('target'); - } - } - if (num == 0) { - if (typeof info.delay == 'number') game.delay(info.delay); - else if (info.delay !== false && info.delay !== 0) { - if (event.waitingForTransition) { - _status.waitingForTransition = event.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - } - else game.delayx(0.5); - if (!info.multitarget && num < targets.length - 1) { - event.num++; - event.redo(); - } - "step 3"; - var info = get.info(event.skill); - if (info && info.contentAfter) { - var next = game.createEvent(event.skill + 'ContentAfter'); - next.setContent(info.contentAfter); - next.targets = targets; - next.cards = cards; - next.player = player; - if (event.forceDie) next.forceDie = true; - if (event.includeOut) next.includeOut = true; - } - "step 4"; - if (player.getStat().allSkills > 200) { - player._noSkill = true; - console.log(player.name, event.skill); - } - if (document.getElementsByClassName('thrown').length) { - if (event.skill && get.info(event.skill).delay !== false && get.info(event.skill).delay !== 0) game.delayx(); - } - else { - event.finish(); - } - "step 5"; - ui.clear(); - }, - draw: function() { - // if(lib.config.background_audio){ - // game.playAudio('effect','draw'); - // } - // game.broadcast(function(){ - // if(lib.config.background_audio){ - // game.playAudio('effect','draw'); - // } - // }); - if (typeof event.minnum == 'number' && num < event.minnum) { - num = event.minnum; - } - if (event.drawDeck) { - if (event.drawDeck > num) { - event.drawDeck = num; - } - num -= event.drawDeck; - } - if (event.log != false) { - if (num > 0) { - if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌'); - else game.log(player, '摸了' + get.cnNumber(num) + '张牌'); - } - if (event.drawDeck) { - game.log(player, '从牌库中获得了' + get.cnNumber(event.drawDeck) + '张牌'); - } - } - let cards; - if (num > 0) { - if (event.bottom) cards = get.bottomCards(num); - else if (player.getTopCards) cards = player.getTopCards(num); - else cards = get.cards(num); - } - else { - cards = []; - } - if (event.drawDeck) { - cards = cards.concat(player.getDeckCards(event.drawDeck)); - } - let next; - if (event.animate != false) { - if (event.visible) { - next = player.gain(cards, 'gain2'); - if (event.bottom) game.log(player, '从牌堆底摸了' + get.cnNumber(num) + '张牌(', cards, ')'); - else game.log(player, '摸了' + get.cnNumber(num) + '张牌(', cards, ')'); - } - else { - next = player.gain(cards, 'draw'); - } - } - else { - next = player.gain(cards); - if (event.$draw) { - player.$draw(cards.length); - } - } - if (event.gaintag) next.gaintag.addArray(event.gaintag); - event.result = cards; - }, - discard: function () { - "step 0"; - game.log(player, '弃置了', cards); - event.done = player.lose(cards, event.position, 'visible'); - event.done.type = 'discard'; - if (event.discarder) event.done.discarder = event.discarder; - "step 1"; - event.trigger('discard'); - }, - loseToDiscardpile: function () { - "step 0"; - if (event.log != false) game.log(player, '将', cards, '置入了弃牌堆'); - var next = player.lose(cards, event.position); - if (event.insert_index) next.insert_index = event.insert_index; - if (event.insert_card) next.insert_card = true; - if (!event.blank) next.visible = true; - next.type = 'loseToDiscardpile'; - event.done = next; - "step 1"; - event.trigger('loseToDiscardpile'); - }, - respond: function () { - 'step 0'; - var cardaudio = true; - if (event.skill) { - if (lib.skill[event.skill].audio) { - cardaudio = false; - } - player.logSkill(event.skill); - player.checkShow(event.skill, true); - if (lib.skill[event.skill].onrespond && !game.online) { - lib.skill[event.skill].onrespond(event, player); - } - } - else if (!event.nopopup) player.tryCardAnimate(card, card.name, 'wood'); - if (cardaudio && event.getParent(3).name == 'useCard') game.broadcastAll((player, card) => { - game.playCardAudio(card, player); - /* - if(!lib.config.background_audio) return; - const sex=player.sex=='female'?'female':'male',audio=lib.card[card.name].audio; - if(typeof audio=='string'){ - const audioInfo=audio.split(':'); - if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); - else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); - else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); - } - else game.playAudio('card',sex,card.name);*/ - }, player, card); - if (event.skill) { - if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { - player.stat[player.stat.length - 1].skill[event.skill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[event.skill]++; - } - var sourceSkill = get.info(event.skill).sourceSkill; - if (sourceSkill) { - if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { - player.stat[player.stat.length - 1].skill[sourceSkill] = 1; - } - else { - player.stat[player.stat.length - 1].skill[sourceSkill]++; - } - } - } - if (cards.length && (cards.length > 1 || cards[0].name != card.name)) { - game.log(player, '打出了', card, '(', cards, ')'); - } - else { - game.log(player, '打出了', card); - } - player.actionHistory[player.actionHistory.length - 1].respond.push(event); - if (cards.length) { - var owner = (get.owner(cards[0]) || player); - var next = owner.lose(cards, 'visible', ui.ordering).set('type', 'use'); - var directDiscard = []; - for (var i = 0; i < cards.length; i++) { - if (!next.cards.includes(cards[i])) { - directDiscard.push(cards[i]); - } - } - if (directDiscard.length) game.cardsGotoOrdering(directDiscard); - } - if (event.animate != false && event.throw !== false) { - for (var i = 0; i < cards.length; i++) { - player.$throw(cards[i]); - if (event.highlight) { - cards[i].clone.classList.add('thrownhighlight'); - game.addVideo('highlightnode', player, get.cardInfo(cards[i])); - } - } - if (event.highlight) { - game.broadcast(function (cards) { - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cards[i].clone.classList.add('thrownhighlight'); - } - } - }, cards); - } - } - event.trigger('respond'); - 'step 1'; - game.delayx(0.5); - }, - swapHandcards: function () { - 'step 0'; - event.cards1 = event.cards1 || player.getCards('h'); - event.cards2 = event.cards2 || target.getCards('h'); - game.loseAsync({ - player: player, - target: target, - cards1: event.cards1, - cards2: event.cards2, - }).setContent('swapHandcardsx'); - 'step 1'; - game.loseAsync({ - gain_list: [ - [player, event.cards2.filterInD()], - [target, event.cards1.filterInD()] - ], - }).setContent('gaincardMultiple'); - 'step 2'; - game.delayx(); - }, - swapHandcardsx: function () { - 'step 0'; - player.$giveAuto(event.cards1, target); - target.$giveAuto(event.cards2, player); - 'step 1'; - event.cards = event.cards1; - var next = player.lose(event.cards, ui.ordering); - next.getlx = false; - next.relatedEvent = event.getParent(); - if (player == game.me) { - event.delayed = true; - } - else { - next.delay = false; - } - 'step 2'; - event.cards = event.cards2; - var next = target.lose(event.cards, ui.ordering); - next.getlx = false; - next.relatedEvent = event.getParent(); - if (target == game.me) { - event.delayed = true; - } - else { - next.delay = false; - } - 'step 3'; - if (!event.delayed) game.delay(); - }, - gainMultiple: function () { - 'step 0'; - event.delayed = false; - event.num = 0; - event.cards = []; - 'step 1'; - player.gainPlayerCard(targets[num], event.position, true).set('boolline', false).set('delay', num == targets.length - 1); - 'step 2'; - if (result.bool) { - event.cards.addArray(result.cards); - if (num == targets.length - 1) event.delayed = true; - } - event.num++; - if (event.num < targets.length) { - event.goto(1); - } - 'step 3'; - if (!event.delayed) game.delay(); - }, - gain: function () { - "step 0"; - if (event.animate == 'give') event.visible = true; - if (cards) { - var map = {}; - for (var i of cards) { - var owner = get.owner(i, 'judge'); - if (owner && (owner != player || get.position(i) != 'h')) { - var id = owner.playerid; - if (!map[id]) map[id] = [[], [], []]; - map[id][0].push(i); - var position = get.position(i); - if (position == 'h') map[id][1].push(i); - else map[id][2].push(i); - } - else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; - } - event.losing_map = map; - for (var i in map) { - var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - var next = owner.lose(map[i][0], ui.special).set('type', 'gain').set('forceDie', true).set('getlx', false); - if (event.visible == true) { - next.visible = true; - } - event.relatedLose = next; - } - } - else { - event.finish(); - } - "step 1"; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('handcard', player, event)) { - cards[i].selfDestroy(event); - cards.splice(i--, 1); - } - else if (event.losing_map) { - for (var id in event.losing_map) { - if (event.losing_map[id][0].includes(cards[i])) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; - var hs = source.getCards('hejsx'); - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } else { - cards[i].addKnower(event.visible ? 'everyone' : source); - } - } - } - } - } - if (cards.length == 0) { - event.finish(); - return; - } - player.getHistory('gain').push(event); - //if(event.source&&event.delay!==false) game.delayx(); - "step 2"; - if (player.getStat().gain == undefined) { - player.getStat().gain = cards.length; - } - else { - player.getStat().gain += cards.length; - } - "step 3"; - var sort; - var frag1 = document.createDocumentFragment(); - var frag2 = document.createDocumentFragment(); - var hs = player.getCards('hs'); - for (var i = 0; i < cards.length; i++) { - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - for (var num = 0; num < cards.length; num++) { - sort = lib.config.sort_card(cards[num]); - if (lib.config.reverse_sort) sort = -sort; - if (['o', 'd'].includes(get.position(cards[num], true))) { - cards[num].addKnower('everyone'); - } - cards[num].fix(); - cards[num].style.transform = ''; - cards[num].addGaintag(event.gaintag); - if (event.knowers) { - cards[num].addKnower(event.knowers);//添加事件设定的知情者。 - } - if (_status.discarded) { - _status.discarded.remove(cards[num]); - } - // cards[num].vanishtag.length=0; - for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { - if (cards[num].vanishtag[num2][0] != '_') { - cards[num].vanishtag.splice(num2--, 1); - } - } - if (player == game.me) { - cards[num].classList.add('drawinghidden'); - } - if (get.is.singleHandcard() || sort > 1) frag1.appendChild(cards[num]); - else frag2.appendChild(cards[num]); - } - var addv = function () { - if (player == game.me) { - game.addVideo('gain12', player, [get.cardsInfo(frag1.childNodes), get.cardsInfo(frag2.childNodes), event.gaintag]); - } - }; - var broadcast = function () { - game.broadcast(function (player, cards, num, gaintag) { - player.directgain(cards, null, gaintag); - _status.cardPileNum = num; - }, player, cards, ui.cardPile.childNodes.length, event.gaintag); - }; - if (event.animate == 'draw') { - player.$draw(cards.length); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(500, 500)); - } - else if (event.animate == 'gain') { - player.$gain(cards, event.log); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(700, 700)); - } - else if (event.animate == 'gain2' || event.animate == 'draw2') { - var gain2t = 300; - if (player.$gain2(cards, event.log) && player == game.me) { - gain2t = 500; - } - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(gain2t, gain2t)); - } - else if (event.animate == 'give' || event.animate == 'giveAuto') { - var evtmap = event.losing_map; - if (event.animate == 'give') { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - source.$give(evtmap[i][0], player, event.log); - } - } - else { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - if (evtmap[i][1].length) source.$giveAuto(evtmap[i][1], player, event.log); - if (evtmap[i][2].length) source.$give(evtmap[i][2], player, event.log); - } - } - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(500, 500)); - } - else if (typeof event.animate == 'function') { - var time = event.animate(event); - game.pause(); - setTimeout(function () { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - game.resume(); - }, get.delayx(time, time)); - } - else { - addv(); - player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); - player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); - player.update(); - if (player == game.me) ui.updatehl(); - broadcast(); - event.finish(); - } - "step 4"; - game.delayx(); - if (event.updatePile) game.updateRoundNumber(); - }, - addToExpansion: function () { - "step 0"; - if (event.animate == 'give') event.visible = true; - if (cards) { - var map = {}; - for (var i of cards) { - var owner = get.owner(i, 'judge'); - if (owner && (owner != player || get.position(i) != 'x')) { - var id = owner.playerid; - if (!map[id]) map[id] = [[], [], []]; - map[id][0].push(i); - var position = get.position(i); - if (position == 'h') map[id][1].push(i); - else map[id][2].push(i); - } - else if (!event.updatePile && get.position(i) == 'c') event.updatePile = true; - } - event.losing_map = map; - for (var i in map) { - var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - var next = owner.lose(map[i][0], ui.special).set('type', 'loseToExpansion').set('forceDie', true).set('getlx', false); - if (event.visible == true) next.visible = true; - event.relatedLose = next; - } - } - else { - event.finish(); - } - "step 1"; - for (var i = 0; i < cards.length; i++) { - if (cards[i].willBeDestroyed('expansion', player, event)) { - cards[i].selfDestroy(event); - cards.splice(i--, 1); - } - else if (event.losing_map) { - for (var id in event.losing_map) { - if (event.losing_map[id][0].includes(cards[i])) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; - var hs = source.getCards('hejsx'); - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - } - } - } - if (cards.length == 0) { - event.finish(); - return; - } - "step 2"; - var hs = player.getCards('x'); - for (var i = 0; i < cards.length; i++) { - if (hs.includes(cards[i])) { - cards.splice(i--, 1); - } - } - for (var num = 0; num < cards.length; num++) { - if (_status.discarded) { - _status.discarded.remove(cards[num]); - } - for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { - if (cards[num].vanishtag[num2][0] != '_') { - cards[num].vanishtag.splice(num2--, 1); - } - } - } - if (event.animate == 'draw') { - player.$draw(cards.length); - if (event.log) game.log(player, '将', get.cnNumber(cards.length), '张牌置于了武将牌上'); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(500, 500)); - } - else if (event.animate == 'gain') { - player.$gain(cards, false); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(700, 700)); - } - else if (event.animate == 'gain2' || event.animate == 'draw2') { - var gain2t = 300; - if (player.$gain2(cards) && player == game.me) { - gain2t = 500; - } - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(gain2t, gain2t)); - } - else if (event.animate == 'give' || event.animate == 'giveAuto') { - var evtmap = event.losing_map; - if (event.animate == 'give') { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - source.$give(evtmap[i][0], player, false); - if (event.log) game.log(player, '将', evtmap[i][0], '置于了武将牌上'); - } - } - else { - for (var i in evtmap) { - var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; - if (evtmap[i][1].length) { - source.$giveAuto(evtmap[i][1], player, false); - if (event.log) game.log(player, '将', get.cnNumber(evtmap[i][1].length), '张牌置于了武将牌上'); - } - if (evtmap[i][2].length) { - source.$give(evtmap[i][2], player, false); - if (event.log) game.log(player, '将', evtmap[i][2], '置于了武将牌上'); - } - } - } - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(500, 500)); - } - else if (typeof event.animate == 'function') { - var time = event.animate(event); - game.pause(); - setTimeout(function () { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - game.resume(); - }, get.delayx(time, time)); - } - else { - player.$addToExpansion(cards, null, event.gaintag); - for (var i of event.gaintag) player.markSkill(i); - event.finish(); - } - "step 4"; - game.delayx(); - if (event.updatePile) game.updateRoundNumber(); - }, - lose: function () { - "step 0"; - var evt = event.getParent(); - if ((evt.name != 'discard' || event.type != 'discard') && (evt.name != 'loseToDiscardpile' || event.type != 'loseToDiscardpile')) { - event.delay = false; - return; - } - if (evt.delay === false) event.delay = false; - if (evt.animate != false) { - evt.discardid = lib.status.videoId++; - game.broadcastAll(function (player, cards, id, visible) { - player.$throw(cards, null, 'nobroadcast'); - var cardnodes = []; - cardnodes._discardtime = get.time(); - for (var i = 0; i < cards.length; i++) { - if (cards[i].clone) { - cardnodes.push(cards[i].clone); - if (!visible) { - cards[i].clone.classList.add('infohidden'); - cards[i].clone.classList.add('infoflip'); - } - } - } - ui.todiscard[id] = cardnodes; - }, player, cards, evt.discardid, event.visible); - if (lib.config.sync_speed && cards[0] && cards[0].clone) { - if (evt.delay != false) { - var waitingForTransition = get.time(); - evt.waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.waitingForTransition; - }); - } - else if (evt.getParent().discardTransition) { - delete evt.getParent().discardTransition; - var waitingForTransition = get.time(); - evt.getParent().waitingForTransition = waitingForTransition; - cards[0].clone.listenTransition(function () { - if (_status.waitingForTransition == waitingForTransition && _status.paused) { - game.resume(); - } - delete evt.getParent().waitingForTransition; - }); - } - } - } - "step 1"; - event.gaintag_map = {}; - var hs = [], es = [], js = [], ss = [], xs = []; - var unmarks = []; - if (event.insert_card && event.position == ui.cardPile) event.cards.reverse(); - var hej = player.getCards('hejsx'); - event.stockcards = cards.slice(0); - for (var i = 0; i < cards.length; i++) { - if (!hej.includes(cards[i])) { - cards.splice(i--, 1); - continue; - } - else if (cards[i].parentNode) { - if (cards[i].parentNode.classList.contains('equips')) { - cards[i].original = 'e'; - es.push(cards[i]); - } - else if (cards[i].parentNode.classList.contains('judges')) { - cards[i].original = 'j'; - js.push(cards[i]); - } - else if (cards[i].parentNode.classList.contains('expansions')) { - cards[i].original = 'x'; - xs.push(cards[i]); - if (cards[i].gaintag && cards[i].gaintag.length) unmarks.addArray(cards[i].gaintag); - } - else if (cards[i].parentNode.classList.contains('handcards')) { - if (cards[i].classList.contains('glows')) { - cards[i].original = 's'; - ss.push(cards[i]); - } - else { - cards[i].original = 'h'; - hs.push(cards[i]); - } - } - else { - cards[i].original = null; - } - } - if (cards[i].gaintag && cards[i].gaintag.length) { - event.gaintag_map[cards[i].cardid] = cards[i].gaintag.slice(0); - cards[i].removeGaintag(true); - } - - cards[i].style.transform += ' scale(0.2)'; - cards[i].classList.remove('glow'); - cards[i].classList.remove('glows'); - cards[i].recheck(); - - var info = lib.card[cards[i].name]; - if ('_destroy' in cards[i]) { - if (cards[i]._destroy) { - cards[i].delete(); - cards[i].destroyed = cards[i]._destroy; - continue; - } - } - else if ('destroyed' in cards[i]) { - if (event.getlx !== false && event.position && cards[i].willBeDestroyed(event.position.id, null, event)) { - cards[i].selfDestroy(event); - continue; - } - } - else if (info.destroy) { - cards[i].delete(); - cards[i].destroyed = info.destroy; - continue; - } - if (event.position) { - if (_status.discarded) { - if (event.position == ui.discardPile) { - _status.discarded.add(cards[i]); - } - else { - _status.discarded.remove(cards[i]); - } - } - if (event.insert_index) { - cards[i].fix(); - event.position.insertBefore(cards[i], event.insert_index(event, cards[i])); - } - else if (event.insert_card) { - cards[i].fix(); - event.position.insertBefore(cards[i], event.position.firstChild); - } - else if (event.position == ui.cardPile) { - cards[i].fix(); - event.position.appendChild(cards[i]); - } - else cards[i].goto(event.position); - } - else { - cards[i].remove(); - } - //if(ss.includes(cards[i])) cards.splice(i--,1); - } - if (player == game.me) ui.updatehl(); - ui.updatej(player); - game.broadcast(function (player, cards, num) { - for (var i = 0; i < cards.length; i++) { - cards[i].classList.remove('glow'); - cards[i].classList.remove('glows'); - cards[i].fix(); - cards[i].remove(); - } - if (player == game.me) { - ui.updatehl(); - } - ui.updatej(player); - _status.cardPileNum = num; - }, player, cards, ui.cardPile.childNodes.length); - game.addVideo('lose', player, [get.cardsInfo(hs), get.cardsInfo(es), get.cardsInfo(js), get.cardsInfo(ss)]); - event.cards2 = hs.concat(es); - player.getHistory('lose').push(event); - game.getGlobalHistory().cardMove.push(event); - player.update(); - game.addVideo('loseAfter', player); - event.num = 0; - if (event.position == ui.ordering) { - var evt = event.relatedEvent || event.getParent(); - if (!evt.orderingCards) evt.orderingCards = []; - if (!evt.noOrdering && !evt.cardsOrdered) { - evt.cardsOrdered = true; - var next = game.createEvent('orderingDiscard', false); - event.next.remove(next); - evt.after.push(next); - next.relatedEvent = evt; - next.setContent('orderingDiscard'); - } - if (!evt.noOrdering) { - evt.orderingCards.addArray(cards); - } - } - else if (event.position == ui.cardPile) { - game.updateRoundNumber(); - } - if (unmarks.length) { - for (var i of unmarks) { - player[(lib.skill[i] && lib.skill[i].mark || player.hasCard((card) => card.hasGaintag(i), 'x')) ? 'markSkill' : 'unmarkSkill'](i); - } - } - event.hs = hs; - event.es = es; - event.js = js; - event.ss = ss; - event.xs = xs; - game.clearCardKnowers(hs); - if (hs.length && !event.visible) { - player.getCards('h').forEach(hcard => { hcard.clearKnowers(); }); - } - "step 2"; - if (num < cards.length) { - if (event.es.includes(cards[num])) { - event.loseEquip = true; - player.removeEquipTrigger(cards[num]); - var info = get.info(cards[num]); - if (info.onLose && (!info.filterLose || info.filterLose(cards[num], player))) { - event.goto(3); - return; - } - } - event.num++; - event.redo(); - } - else { - if (event.loseEquip) { - player.addEquipTrigger(); - } - event.goto(4); - } - "step 3"; - var info = get.info(cards[num]); - if (info.loseDelay != false && (player.isAlive() || info.forceDie)) { - player.popup(cards[num].name); - game.delayx(); - } - if (Array.isArray(info.onLose)) { - for (var i = 0; i < info.onLose.length; i++) { - var next = game.createEvent('lose_' + cards[num].name); - next.setContent(info.onLose[i]); - if (info.forceDie) next.forceDie = true; - next.player = player; - next.card = cards[num]; - } - } - else { - var next = game.createEvent('lose_' + cards[num].name); - next.setContent(info.onLose); - next.player = player; - if (info.forceDie) next.forceDie = true; - next.card = cards[num]; - } - event.num++; - event.goto(2); - "step 4"; - if (event.toRenku) { - _status.renku.addArray(cards.filter(function (card) { - return !card.willBeDestroyed('renku', null, event); - })); - if (_status.renku.length > 6) { - var cards = _status.renku.splice(0, _status.renku.length - 6); - game.log(cards, '从仁库进入了弃牌堆'); - game.cardsDiscard(cards).set('outRange', true).fromRenku = true; - } - game.updateRenku(); - } - "step 5"; - var evt = event.getParent(); - if ((evt.name != 'discard' && event.type != 'discard') && (evt.name != 'loseToDiscardpile' && event.type != 'loseToDiscardpile')) return; - if (event.animate === false || event.delay === false) return; - if (evt.delay != false) { - if (evt.waitingForTransition) { - _status.waitingForTransition = evt.waitingForTransition; - game.pause(); - } - else { - game.delayx(); - } - } - }, - damage: function () { - "step 0"; - event.forceDie = true; - if (event.unreal) { event.goto(4); return; } - event.trigger('damageBegin1'); - "step 1"; - event.trigger('damageBegin2'); - "step 2"; - event.trigger('damageBegin3'); - "step 3"; - event.trigger('damageBegin4'); - "step 4"; - //moved changeHujia to changeHp - if (player.hujia > 0 && !player.hasSkillTag('nohujia')) { - var damageAudioInfo = lib.natureAudio.hujia_damage[event.nature]; - if (!damageAudioInfo || damageAudioInfo == 'normal') { - damageAudioInfo = 'effect/hujia_damage' + (num > 1 ? '2' : '') + '.mp3'; - } else if (damageAudioInfo == 'default') { - damageAudioInfo = 'effect/hujia_damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; - } else { - damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; - } - game.broadcastAll(function (damageAudioInfo) { - if (lib.config.background_audio) game.playAudio(damageAudioInfo); - }, damageAudioInfo); - } else { - var damageAudioInfo = lib.natureAudio.damage[event.nature]; - if (!damageAudioInfo || damageAudioInfo == 'normal') { - damageAudioInfo = 'effect/damage' + (num > 1 ? '2' : '') + '.mp3'; - } else if (damageAudioInfo == 'default') { - damageAudioInfo = 'effect/damage_' + event.nature + (num > 1 ? '2' : '') + '.mp3'; - } else { - damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; - } - game.broadcastAll(function (damageAudioInfo) { - if (lib.config.background_audio) game.playAudio(damageAudioInfo); - }, damageAudioInfo); - } - var str = event.unreal ? '视为受到了' : '受到了'; - if (source) str += '来自' + (source == player ? '自己' : get.translation(source)) + '的'; - str += get.cnNumber(num) + '点'; - if (event.nature) str += get.translation(event.nature) + '属性'; - str += '伤害'; - game.log(player, str); - if (player.stat[player.stat.length - 1].damaged == undefined) { - player.stat[player.stat.length - 1].damaged = num; - } - else { - player.stat[player.stat.length - 1].damaged += num; - } - if (source) { - source.getHistory('sourceDamage').push(event); - if (source.stat[source.stat.length - 1].damage == undefined) { - source.stat[source.stat.length - 1].damage = num; - } - else { - source.stat[source.stat.length - 1].damage += num; - } - } - player.getHistory('damage').push(event); - if (!event.unreal) { - if (event.notrigger) { - player.changeHp(-num, false)._triggered = null; - } - else { - player.changeHp(-num, false); - } - } - if (event.animate !== false) { - player.$damage(source); - var natures = (event.nature || '').split(lib.natureSeparator); - game.broadcastAll(function (natures, player) { - if (lib.config.animation && !lib.config.low_performance) { - if (natures.includes('fire')) { - player.$fire(); - } - if (natures.includes('thunder')) { - player.$thunder(); - } - } - }, natures, player); - var numx = player.hasSkillTag('nohujia') ? num : Math.max(0, num - player.hujia); - player.$damagepop(-numx, natures[0]); - } - if (event.unreal) event.goto(6); - if (!event.notrigger) { - if (num == 0) { - event.trigger('damageZero'); - event._triggered = null; - } - else { - event.trigger('damage'); - } - } - "step 5"; - if (player.hp <= 0 && player.isAlive() && !event.nodying) { - game.delayx(); - event._dyinged = true; - player.dying(event); - } - if (source && lib.config.border_style == 'auto') { - var dnum = 0; - for (var j = 0; j < source.stat.length; j++) { - if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; - } - if (dnum >= 2) { - if (lib.config.autoborder_start == 'silver') { - dnum += 4; - } - else if (lib.config.autoborder_start == 'gold') { - dnum += 8; - } - } - if (lib.config.autoborder_count == 'damage') { - source.node.framebg.dataset.decoration = ''; - if (dnum >= 10) { - source.node.framebg.dataset.auto = 'gold'; - if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; - } - else if (dnum >= 6) { - source.node.framebg.dataset.auto = 'silver'; - if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; - } - else if (dnum >= 2) { - source.node.framebg.dataset.auto = 'bronze'; - if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; - } - if (dnum >= 2) { - source.classList.add('topcount'); - } - } - else if (lib.config.autoborder_count == 'mix') { - source.node.framebg.dataset.decoration = ''; - switch (source.node.framebg.dataset.auto) { - case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; - case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; - case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; - } - } - } - "step 6"; - if (!event.notrigger) event.trigger('damageSource'); - }, - recover: function () { - if (num > player.maxHp - player.hp) { - num = player.maxHp - player.hp; - event.num = num; - } - if (num > 0) { - delete event.filterStop; - if (lib.config.background_audio) { - game.playAudio('effect', 'recover'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'recover'); - } - }); - game.broadcastAll(function (player) { - if (lib.config.animation && !lib.config.low_performance) { - player.$recover(); - } - }, player); - player.$damagepop(num, 'wood'); - game.log(player, '回复了' + get.cnNumber(num) + '点体力'); - - player.changeHp(num, false); - } - else event._triggered = null; - }, - loseHp: function () { - "step 0"; - if (event.num <= 0){ - event.finish(); - event._triggered = null; - return; - } - if (lib.config.background_audio) { - game.playAudio('effect', 'loseHp'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'loseHp'); - } - }); - game.log(player, '失去了' + get.cnNumber(num) + '点体力'); - player.changeHp(-num); - "step 1"; - if (player.hp <= 0 && !event.nodying) { - game.delayx(); - event._dyinged = true; - player.dying(event); - } - }, - doubleDraw: function () { - "step 0"; - player.chooseBool('你的主副将体力上限之和是奇数,是否摸一张牌?'); - "step 1"; - if (result.bool) { - player.draw(); - } - }, - loseMaxHp: function () { - "step 0"; - game.log(player, '减少了' + get.cnNumber(num) + '点体力上限'); - player.maxHp -= num; - event.loseHp = Math.max(0, player.hp - player.maxHp); - player.update(); - "step 1"; - if (player.maxHp <= 0) { - player.die(event); - } - }, - gainMaxHp: function () { - "step 0"; - game.log(player, '增加了' + get.cnNumber(num) + '点体力上限'); - player.maxHp += num; - player.update(); - }, - changeHp: function () { - //add to GlobalHistory - game.getGlobalHistory().changeHp.push(event); - //changeHujia moved here - if (num < 0 && player.hujia > 0 && event.getParent().name == 'damage' && !player.hasSkillTag('nohujia')) { - event.hujia = Math.min(-num, player.hujia); - event.getParent().hujia = event.hujia; - event.num += event.hujia; - //log moved to changeHujia - //game.log(player,'的护甲抵挡了'+get.cnNumber(event.hujia)+'点伤害'); - player.changeHujia(-event.hujia).type = 'damage'; - } - //old part - num = event.num; - player.hp += num; - if (isNaN(player.hp)) player.hp = 0; - if (player.hp > player.maxHp) player.hp = player.maxHp; - player.update(); - if (event.popup !== false) { - player.$damagepop(num, 'water'); - } - if (_status.dying.includes(player) && player.hp > 0) { - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - var evt = event.getParent('_save'); - if (evt && evt.finish) evt.finish(); - evt = event.getParent('dying'); - if (evt && evt.finish) evt.finish(); - } - event.trigger('changeHp'); - }, - changeHujia: function () { - if (num > 0) { - game.log(player, '获得了' + get.cnNumber(num) + '点护甲'); - } - else if (num < 0) { - if (-num > player.hujia) { - num = -player.hujia; - event.num = num; - } - switch (event.type) { //log moved here - case 'damage': - game.log(player, '的护甲抵挡了' + get.cnNumber(-num) + '点伤害'); - break; - case 'lose': - game.log(player, '失去了' + get.cnNumber(-num) + '点护甲'); - break; - } - } - player.hujia += num; - //if(player.hujia<0){ - // player.hujia=0; - //} - player.update(); - }, - dying: function () { - "step 0"; - event.forceDie = true; - if (player.isDying() || player.hp > 0) { - event.finish(); - return; - } - _status.dying.unshift(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - event.trigger('dying'); - game.log(player, '濒死'); - "step 1"; - delete event.filterStop; - if (player.hp > 0 || event.nodying) { - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - event.finish(); - } - else if (!event.skipTao) { - var next = game.createEvent('_save'); - var start = false; - var starts = [_status.currentPhase, event.source, event.player, game.me, game.players[0]]; - for (var i = 0; i < starts.length; i++) { - if (get.itemtype(starts[i]) == 'player') { - start = starts[i]; break; - } - } - next.player = start; - next._trigger = event; - next.triggername = '_save'; - next.forceDie = true; - next.setContent(lib.skill._save.content); - } - "step 2"; - _status.dying.remove(player); - game.broadcast(function (list) { - _status.dying = list; - }, _status.dying); - if (player.hp <= 0 && !event.nodying && !player.nodying) player.die(event.reason); - }, - die: function () { - "step 0"; - event.forceDie = true; - if (_status.roundStart == player) { - _status.roundStart = player.next || player.getNext() || game.players[0]; - } - if (ui.land && ui.land.player == player) { - game.addVideo('destroyLand'); - ui.land.destroy(); - } - var unseen = false; - if (player.classList.contains('unseen')) { - player.classList.remove('unseen'); - unseen = true; - } - var logvid = game.logv(player, 'die', source); - event.logvid = logvid; - if (unseen) { - player.classList.add('unseen'); - } - if (source) { - game.log(player, '被', source, '杀害'); - if (source.stat[source.stat.length - 1].kill == undefined) { - source.stat[source.stat.length - 1].kill = 1; - } - else { - source.stat[source.stat.length - 1].kill++; - } - } - else { - game.log(player, '阵亡'); - } - - - // player.removeEquipTrigger(); - - // for(var i in lib.skill.globalmap){ - // if(lib.skill.globalmap[i].includes(player)){ - // lib.skill.globalmap[i].remove(player); - // if(lib.skill.globalmap[i].length==0&&!lib.skill[i].globalFixed){ - // game.removeGlobalSkill(i); - // } - // } - // } - game.broadcastAll(function (player) { - player.classList.add('dead'); - player.removeLink(); - player.classList.remove('turnedover'); - player.classList.remove('out'); - player.node.count.innerHTML = '0'; - player.node.hp.hide(); - player.node.equips.hide(); - player.node.count.hide(); - player.previous.next = player.next; - player.next.previous = player.previous; - game.players.remove(player); - game.dead.push(player); - _status.dying.remove(player); - - if (lib.config.background_speak) { - const name = (player.skin.name || player.name); - const goon = (!lib.character[name]); - if (goon) lib.character[name] = ['', '', 0, [], ((lib.characterSubstitute[player.name] || []).find(i => i[0] == name) || [name, []])[1]]; - if (lib.character[name][4].some(tag => /^die:.+$/.test(tag))) { - var tag = lib.character[name][4].find(tag => /^die:.+$/.test(tag)); - var reg = new RegExp("^ext:(.+)?/"); - var match = tag.match(/^die:(.+)$/); - if (match) { - var path = match[1]; - if (reg.test(path)) path = path.replace(reg, (_o, p) => `../extension/${p}/`); - game.playAudio(path); - } - } - else if (lib.character[name][4].some(tag => tag.startsWith('die_audio'))) { - var tag = lib.character[name][4].find(tag => tag.startsWith('die_audio')); - var list = tag.split(':').slice(1); - game.playAudio('die', list.length ? list[0] : name); - } - else { - game.playAudio('die', name, function () { - game.playAudio('die', name.slice(name.indexOf('_') + 1)); - }); - } - if (goon) delete lib.character[name]; - } - }, player); - - game.addVideo('diex', player); - if (event.animate !== false) { - player.$die(source); - } - if (player.hp != 0) { - player.changeHp(0 - player.hp, false).forceDie = true; - } - "step 1"; - if (player.dieAfter) player.dieAfter(source); - "step 2"; - event.trigger('die'); - "step 3"; - if (player.isDead()) { - if (!game.reserveDead) { - for (var mark in player.marks) { - player.unmarkSkill(mark); - } - while (player.node.marks.childNodes.length > 1) { - player.node.marks.lastChild.remove(); - } - game.broadcast(function (player) { - while (player.node.marks.childNodes.length > 1) { - player.node.marks.lastChild.remove(); - } - }, player); - } - for (var i in player.tempSkills) { - player.removeSkill(i); - } - var skills = player.getSkills(); - for (var i = 0; i < skills.length; i++) { - if (lib.skill[skills[i]].temp) { - player.removeSkill(skills[i]); - } - } - if (_status.characterlist) { - if (lib.character[player.name] && !player.name.startsWith('gz_shibing') && !player.name.startsWith('gz_jun_')) _status.characterlist.add(player.name); - if (lib.character[player.name1] && !player.name1.startsWith('gz_shibing') && !player.name1.startsWith('gz_jun_')) _status.characterlist.add(player.name1); - if (lib.character[player.name2] && !player.name2.startsWith('gz_shibing') && !player.name2.startsWith('gz_jun_')) _status.characterlist.add(player.name2); - } - event.cards = player.getCards('hejsx'); - if (event.cards.length) { - player.discard(event.cards).forceDie = true; - //player.$throw(event.cards,1000); - } - } - "step 4"; - if (player.dieAfter2) player.dieAfter2(source); - "step 5"; - game.broadcastAll(function (player) { - if (game.online && player == game.me && !_status.over && !game.controlOver && !ui.exit) { - if (lib.mode[lib.configOL.mode].config.dierestart) { - ui.create.exit(); - } - } - }, player); - if (!_status.connectMode && player == game.me && !_status.over && !game.controlOver) { - ui.control.show(); - if (get.config('revive') && lib.mode[lib.config.mode].config.revive && !ui.revive) { - ui.revive = ui.create.control('revive', ui.click.dierevive); - } - if (get.config('continue_game') && !ui.continue_game && lib.mode[lib.config.mode].config.continue_game && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); - } - if (get.config('dierestart') && lib.mode[lib.config.mode].config.dierestart && !ui.restart) { - ui.restart = ui.create.control('restart', game.reload); - } - } - - if (!_status.connectMode && player == game.me && !game.modeSwapPlayer) { - // _status.auto=false; - if (ui.auto) { - // ui.auto.classList.remove('glow'); - ui.auto.hide(); - } - if (ui.wuxie) ui.wuxie.hide(); - } - - if (typeof _status.coin == 'number' && source && !_status.auto) { - if (source == game.me || source.isUnderControl()) { - _status.coin += 10; - } - } - if (source && lib.config.border_style == 'auto' && (lib.config.autoborder_count == 'kill' || lib.config.autoborder_count == 'mix')) { - switch (source.node.framebg.dataset.auto) { - case 'gold': case 'silver': source.node.framebg.dataset.auto = 'gold'; break; - case 'bronze': source.node.framebg.dataset.auto = 'silver'; break; - default: source.node.framebg.dataset.auto = lib.config.autoborder_start || 'bronze'; - } - if (lib.config.autoborder_count == 'kill') { - source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; - } - else { - var dnum = 0; - for (var j = 0; j < source.stat.length; j++) { - if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; - } - source.node.framebg.dataset.decoration = ''; - switch (source.node.framebg.dataset.auto) { - case 'bronze': if (dnum >= 4) source.node.framebg.dataset.decoration = 'bronze'; break; - case 'silver': if (dnum >= 8) source.node.framebg.dataset.decoration = 'silver'; break; - case 'gold': if (dnum >= 12) source.node.framebg.dataset.decoration = 'gold'; break; - } - } - source.classList.add('topcount'); - } - }, - addJudge: function () { - "step 0"; - const cardName = typeof card == 'string' ? card : card.name , cardInfo = lib.card[cardName]; - if (cards) { - var owner = get.owner(cards[0]); - if (owner) { - event.relatedLose = owner.lose(cards, ui.special).set('getlx', false); - if (cardInfo && !cardInfo.blankCard) { - event.relatedLose.set('visible', true); - event.set('visible', true); - } - } - else if (get.position(cards[0]) == 'c') event.updatePile = true; - } - "step 1"; - if (cards[0].willBeDestroyed('judge', player, event)) { - cards[0].selfDestroy(event); - event.finish(); - return; - } - else if (event.relatedLose) { - var owner = event.relatedLose.player; - if (owner.getCards('hejsx').includes(card)) { - event.finish(); - return; - } - } - cards[0].fix(); - cards[0].style.transform = ''; - cards[0].classList.remove('drawinghidden'); - delete cards[0]._transform; - var viewAs = typeof card == 'string' ? card : card.name; - if (!lib.card[viewAs] || (!lib.card[viewAs].effect && !lib.card[viewAs].noEffect) ) { - game.cardsDiscard(cards[0]); - } - else { - cards[0].style.transform = ''; - cards[0].classList.add('drawinghidden'); - player.node.judges.insertBefore(cards[0], player.node.judges.firstChild); - if (_status.discarded) { - _status.discarded.remove(cards[0]); - } - ui.updatej(player); - game.broadcast(function (player, card, viewAs) { - card.fix(); - card.style.transform = ''; - card.classList.add('drawinghidden'); - card.viewAs = viewAs; - if (viewAs && viewAs != card.name && (card.classList.contains('fullskin') || card.classList.contains('fullborder'))) { - card.classList.add('fakejudge'); - card.node.background.innerHTML = lib.translate[viewAs + '_bg'] || get.translation(viewAs)[0]; - } - else { - card.classList.remove('fakejudge'); - } - player.node.judges.insertBefore(card, player.node.judges.firstChild); - ui.updatej(player); - if (card.clone && (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena)) { - card.clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo([card])); - } - }, player, cards[0], viewAs); - if (cards[0].clone && (cards[0].clone.parentNode == player.parentNode || cards[0].clone.parentNode == ui.arena)) { - cards[0].clone.moveDelete(player); - game.addVideo('gain2', player, get.cardsInfo(cards)); - } - // player.$gain2(cards); - if (get.itemtype(card) != 'card') { - if (typeof card == 'string') cards[0].viewAs = card; - else cards[0].viewAs = card.name; - } - else { - delete cards[0].viewAs; - } - if (cards[0].viewAs && cards[0].viewAs != cards[0].name) { - if (cards[0].classList.contains('fullskin') || cards[0].classList.contains('fullborder')) { - cards[0].classList.add('fakejudge'); - cards[0].node.background.innerHTML = lib.translate[cards[0].viewAs + '_bg'] || get.translation(cards[0].viewAs)[0]; - } - if(lib.card[viewAs].blankCard){ - game.log(player, '被扣置了' + get.translation(cards[0].viewAs) + ''); - } - else { - game.log(player, '被贴上了' + get.translation(cards[0].viewAs) + '(', cards, ')'); - } - } - else { - cards[0].classList.remove('fakejudge'); - game.log(player, '被贴上了', cards); - } - game.addVideo('addJudge', player, [get.cardInfo(cards[0]), cards[0].viewAs]); - } - if (event.updatePile) game.updateRoundNumber(); - }, - judge: function () { - "step 0"; - var judgestr = get.translation(player) + '的' + event.judgestr + '判定'; - event.videoId = lib.status.videoId++; - var cardj = event.directresult; - if (!cardj) { - if (player.getTopCards) cardj = player.getTopCards()[0]; - else cardj = get.cards()[0]; - } - var owner = get.owner(cardj); - if (owner) { - owner.lose(cardj, 'visible', ui.ordering); - } - else { - var nextj = game.cardsGotoOrdering(cardj); - if (event.position != ui.discardPile) nextj.noOrdering = true; - } - player.judging.unshift(cardj); - game.addVideo('judge1', player, [get.cardInfo(player.judging[0]), judgestr, event.videoId]); - game.broadcastAll(function (player, card, str, id, cardid) { - var event; - if (game.online) { - event = {}; - } - else { - event = _status.event; - } - if (game.chess) { - event.node = card.copy('thrown', 'center', ui.arena).addTempClass('start'); - } - else { - event.node = player.$throwordered(card.copy(), true); - } - if (lib.cardOL) lib.cardOL[cardid] = event.node; - event.node.cardid = cardid; - event.node.classList.add('thrownhighlight'); - ui.arena.classList.add('thrownhighlight'); - event.dialog = ui.create.dialog(str); - event.dialog.classList.add('center'); - event.dialog.videoId = id; - }, player, player.judging[0], judgestr, event.videoId, get.id()); - - game.log(player, '进行' + event.judgestr + '判定,亮出的判定牌为', player.judging[0]); - game.delay(2); - if (!event.noJudgeTrigger) event.trigger('judge'); - "step 1"; - event.result = { - card: player.judging[0], - name: player.judging[0].name, - number: get.number(player.judging[0]), - suit: get.suit(player.judging[0]), - color: get.color(player.judging[0]), - node: event.node, - }; - if (event.fixedResult) { - for (var i in event.fixedResult) { - event.result[i] = event.fixedResult[i]; - } - } - event.result.judge = event.judge(event.result); - if (event.result.judge > 0) event.result.bool = true; - else if (event.result.judge < 0) event.result.bool = false; - else event.result.bool = null; - player.judging.shift(); - game.checkMod(player, event.result, 'judge', player); - if (event.judge2) { - var judge2 = event.judge2(event.result); - if (typeof judge2 == 'boolean') player.tryJudgeAnimate(judge2); - } - if (event.clearArena != false) { - game.broadcastAll(ui.clear); - } - game.broadcast(function (id) { - var dialog = get.idDialog(id); - if (dialog) { - dialog.close(); - } - ui.arena.classList.remove('thrownhighlight'); - }, event.videoId); - event.dialog.close(); - game.addVideo('judge2', null, event.videoId); - ui.arena.classList.remove('thrownhighlight'); - game.log(player, '的判定结果为', event.result.card); - event.trigger('judgeFixing'); - if (event.callback) { - var next = game.createEvent('judgeCallback', false); - next.player = player; - next.card = event.result.card; - next.judgeResult = get.copy(event.result); - next.setContent(event.callback); - } - else { - if (!get.owner(event.result.card)) { - if (event.position != ui.discardPile) event.position.appendChild(event.result.card); - } - } - }, - turnOver: function () { - game.log(player, '翻面'); - player.classList.toggle('turnedover'); - game.broadcast(function (player) { - player.classList.toggle('turnedover'); - }, player); - game.addVideo('turnOver', player, player.classList.contains('turnedover')); - }, - link: function () { - if (player.isLinked()) { - game.log(player, '解除连环'); - } - else { - game.log(player, '被连环'); - } - if (lib.config.background_audio) { - game.playAudio('effect', 'link'); - } - game.broadcast(function () { - if (lib.config.background_audio) { - game.playAudio('effect', 'link'); - } - }); - player.classList.remove('target'); - if (get.is.linked2(player)) { - player.classList.toggle('linked2'); - } - else { - player.classList.toggle('linked'); - } - ui.updatej(player); - ui.updatem(player); - game.broadcast(function (player, linked) { - player.classList.remove('target'); - if (get.is.linked2(player)) { - if (linked) { - player.classList.add('linked2'); - } - else { - player.classList.remove('linked2'); - } - } - else { - if (linked) { - player.classList.add('linked'); - } - else { - player.classList.remove('linked'); - } - } - ui.updatej(player); - ui.updatem(player); - }, player, player.isLinked()); - game.addVideo('link', player, player.isLinked()); - }, - /** - * @deprecated - */ - chooseToGuanxing: function () { - "step 0"; - var cards = get.cards(num); - game.cardsGotoOrdering(cards); - var next = player.chooseToMove(); - next.set('list', [ - ['牌堆顶', cards], - ['牌堆底'], - ]); - next.set('prompt', '点击将牌移动到牌堆顶或牌堆底'); - next.processAI = event.processAI || function (list) { - var cards = list[0][1], player = _status.event.player; - var top = []; - var bottom; - cards.sort(function (a, b) { - return get.value(b, player) - get.value(a, player); - }); - while (cards.length) { - if (get.value(cards[0], player) <= 5) break; - top.unshift(cards.shift()); - } - bottom = cards; - return [top, bottom]; - }; - "step 1"; - var top = result.moved[0]; - var bottom = result.moved[1]; - top.reverse(); - for (var i = 0; i < top.length; i++) { - ui.cardPile.insertBefore(top[i], ui.cardPile.firstChild); - } - for (i = 0; i < bottom.length; i++) { - ui.cardPile.appendChild(bottom[i]); - } - game.addCardKnower(top, player); - game.addCardKnower(bottom, player); - player.popup(get.cnNumber(top.length) + '上' + get.cnNumber(bottom.length) + '下'); - game.log(player, '将' + get.cnNumber(top.length) + '张牌置于牌堆顶'); - game.updateRoundNumber(); - game.delayx(); - } -} +import { ai } from "../../ai/index.js"; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; +import { gnc } from "../../gnc/index.js"; + +// 未来再改 +export const Content = { + emptyEvent: () => { + event.trigger(event.name); + }, + //变更武将牌 + async changeCharacter(event, trigger, player) { + const rawPairs = [player.name1]; + if (player.name2 && lib.character[player.name2]) rawPairs.push(player.name2); + event.rawPairs = rawPairs; + const newPairs = event.newPairs; + for (let name of newPairs) { + if (!lib.character[name]) { + console.warn(`警告:Player[${player.name}]试图将武将牌变更为不存在的武将:`, name); + return; + } + } + const removeSkills = [], + addSkills = []; + //进行Log + if (event.log !== false) { + //变更前后数量相同的情况 + if (rawPairs.length == newPairs.length) { + for (let i = 0; i < Math.min(2, rawPairs.length); i++) { + let rawName = rawPairs[i], + newName = newPairs[i]; + if (rawName != newName) { + game.log( + player, + `将${i == 0 ? "主" : "副"}将从`, + `#b${get.translation(rawName)}`, + "变更为了", + `#b${get.translation(newName)}` + ); + } + } + } else if (rawPairs.length == 1 && newPairs.length == 2) { + game.log( + player, + "将单将", + `#b${get.translation(rawPairs[0])}`, + "变更为了双将", + `#b${get.translation(newPairs[0])}+${get.translation(newPairs[1])}` + ); + } else if (rawPairs.length == 2 && newPairs.length == 1) { + game.log( + player, + "将双将", + `#b${get.translation(rawPairs[0])}+${get.translation(rawPairs[1])}`, + "变更为了单将", + `#b${get.translation(newPairs[0])}` + ); + } + } + //确定要失去和获得的技能 + //失去技能时全部失去,但获得技能时,非主公角色不能获得主公技。 + rawPairs.forEach((name) => { + removeSkills.addArray(lib.character[name][3]); + }); + newPairs.forEach((name) => { + addSkills.addArray( + lib.character[name][3].filter((skill) => { + const info = get.info(skill); + if (!info || (info.zhuSkill && !player.isZhu2())) return false; + return true; + }) + ); + }); + //实际变更武将牌 + player.reinit2(newPairs); + //操作武将牌堆 + if (_status.characterlist) { + _status.characterlist.removeArray(newPairs); + _status.characterlist.addArray(rawPairs); + } + //变更一下获得前后的技能 + await player.changeSkills(addSkills, removeSkills); + //变更角色的所属势力。如果新将是双势力,重选一下势力。 + if (event.changeGroup !== false) { + let newGroups = []; + if (!player.isUnseen(1)) { + newGroups = get.is.double(player.name1, true) || [get.character(player.name1, 1)]; + } else if (player.name2 && !player.isUnseen(2)) { + newGroups = get.is.double(player.name2, true) || [get.character(player.name2, 1)]; + } + if (newGroups.length > 1) { + const newGroup = await player + .chooseControl(newGroups) + .set("prompt", "请选择一个新的势力") + .forResult("control"); + if (newGroup != player.group) { + await player.changeGroup(newGroup); + } + } else if (newGroups.length == 1 && newGroups[0] != player.group) { + await player.changeGroup(newGroups[0]); + } + } + }, + //变更技能 + async changeSkills(event, trigger, player) { + //获取玩家当前已有的技能 + const ownedSkills = player.getSkills(true, false, false); + //去重检查 + event.addSkill.unique(); + event.removeSkill.unique(); + //避免失去还没拥有的技能 + event.removeSkill = event.removeSkill.filter((skill) => ownedSkills.includes(skill)); + const duplicatedSkills = event.addSkill.filter((skill) => event.removeSkill.includes(skill)); + if (duplicatedSkills.length) { + event.addSkill.removeArray(duplicatedSkills); + event.removeSkill.removeArray(duplicatedSkills); + } + //if (!event.addSkill.length&&!event.removeSkill.length) return; + //手动触发时机 + await event.trigger("changeSkillsBefore"); + await event.trigger("changeSkillsBegin"); + //处理失去和获得的技能 + if (event.$handle) { + event.$handle(player, event.addSkill, event.removeSkill, event); + } else { + if (event.addSkill.length) { + player.addSkill(event.addSkill); + game.log( + player, + "获得了技能", + ...event.addSkill.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + } + if (event.removeSkill.length) { + player.removeSkill(event.removeSkill); + game.log( + player, + "失去了技能", + ...event.removeSkill.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + } + } + //手动触发时机 + await event.trigger("changeSkillsEnd"); + await event.trigger("changeSkillsAfter"); + }, + //增加明置手牌 + addShownCards: () => { + const hs = player.getCards("h"), + showingCards = event._cards.filter((showingCard) => hs.includes(showingCard)), + shown = player.getShownCards(); + event.gaintag.forEach((tag) => player.addGaintag(showingCards, tag)); + if (!(event.cards = showingCards.filter((showingCard) => !shown.includes(showingCard))).length) + return; + game.log(player, "明置了", event.cards); + //if (event.animate != false) player.$give(event.cards, player, false); + event.trigger("addShownCardsAfter"); + }, + //隐藏明置手牌 + hideShownCards: () => { + var shown = player.getShownCards(), + hidingCards = event._cards.filter((hidingCard) => shown.includes(hidingCard)); + if (!hidingCards.length) return; + if (event.gaintag.length) event.gaintag.forEach((tag) => player.removeGaintag(tag, hidingCards)); + else { + var map = hidingCards.reduce((constructingMap, hidingCard) => { + hidingCard.gaintag.forEach((tag) => { + if (!tag.startsWith("visible_")) return; + if (!constructingMap[tag]) constructingMap[tag] = []; + constructingMap[tag].push(hidingCard); + }); + return constructingMap; + }, {}); + Object.keys(map).forEach((key) => player.removeGaintag(key, map[key])); + } + hidingCards.removeArray(player.getShownCards()); + if (!hidingCards.length) return; + game.log(player, "取消明置了", (event.cards = hidingCards)); + //if (event.animate != false) player.$give(hidingCards, player, false); + event.trigger("hideShownCardsAfter"); + }, + //Execute the delay card effect + //执行延时锦囊牌效果 + executeDelayCardEffect: () => { + "step 0"; + target.$phaseJudge(card); + event.cancelled = false; + event.trigger("executeDelayCardEffect"); + event.cardName = card.viewAs || card.name; + target.popup(event.cardName, "thunder"); + if (!lib.card[event.cardName].effect) { + game.delay(); + event.finish(); + } else if (!lib.card[event.cardName].judge) { + game.delay(); + event.nojudge = true; + } + "step 1"; + if (event.cancelled || event.nojudge) return; + var next = player.judge(card), + judge = event.judge; + if (typeof judge == "function") next.judge = judge; + var judge2 = event.judge2; + if (typeof judge2 == "function") next.judge2 = judge2; + "step 2"; + if (event.excluded) delete event.excluded; + else { + var cardName = event.cardName; + if (event.cancelled && !event.direct) { + var cardCancel = lib.card[cardName].cancel; + if (cardCancel) { + var next = game.createEvent(`${cardName}Cancel`); + next.setContent(cardCancel); + next.cards = [card]; + if (!card.viewAs) { + var autoViewAs = (next.card = get.autoViewAs(card)); + autoViewAs.expired = card.expired; + } else { + var autoViewAs = (next.card = get.autoViewAs( + { + name: cardName, + }, + next.cards + )); + autoViewAs.expired = card.expired; + } + next.player = player; + } + } else { + var next = game.createEvent(cardName); + next.setContent(lib.card[cardName].effect); + next._result = result; + next.cards = [card]; + if (!card.viewAs) { + var autoViewAs = (next.card = get.autoViewAs(card)); + autoViewAs.expired = card.expired; + } else { + var autoViewAs = (next.card = get.autoViewAs( + { + name: cardName, + }, + next.cards + )); + autoViewAs.expired = card.expired; + } + next.player = player; + } + } + ui.clear(); + card.delete(); + }, + //Gift + //赠予 + gift: () => { + "step 0"; + event.num = 0; + "step 1"; + if (num < cards.length) { + event.card = cards[num]; + event.trigger("gift"); + } else { + game.delayx(); + event.finish(); + } + "step 2"; + if (event.deniedGifts.includes(card)) { + game.log(target, "拒绝了", player, "赠予的", card); + event.trigger("giftDeny"); + player.loseToDiscardpile(card).log = false; + event.trigger("giftDenied"); + return; + } + game.log(player, "将", card, "赠予了", target); + player.$give(card, target, false); + game.delay(0.5); + event.trigger("giftAccept"); + if (get.type(card, false) == "equip") target.equip(card).log = false; + else target.gain(card, player).visible = true; + event.trigger("giftAccepted"); + "step 3"; + event.num++; + event.goto(1); + }, + //Recast + //重铸 + recast: () => { + "step 0"; + game.log(player, "重铸了", cards); + if (typeof event.recastingLose != "function") return; + event.trigger("recastingLose"); + event.recastingLose(player, cards); + event.trigger("recastingLost"); + event.recastingLosingEvents.push(...event.next.filter((value) => value.name != "arrangeTrigger")); + "step 1"; + event.trigger("recast"); + "step 2"; + if (typeof event.recastingGain != "function") return; + event.trigger("recastingGain"); + event.recastingGain(player, cards); + event.trigger("recastingGained"); + event.recastingGainingEvents.push(...event.next.filter((value) => value.name != "arrangeTrigger")); + }, + //装备栏相关 + disableEquip: function () { + "step 0"; + event.cards = []; + event.num = 0; + event.slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach((type) => { + if (type == "equip3" || type == "equip4") event.slotsx.add("equip3_4"); + else event.slotsx.add(type); + }); + } else { + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); + if (!event.slots.length) event.finish(); + "step 1"; + var slot = event.slotsx[event.num]; + var slot_key = slot; + var left = player.countEnabledSlot(slot), + lose; + if (slot == "equip3_4") { + lose = Math.min( + left, + Math.max(get.numOf(event.slots, "equip3"), get.numOf(event.slots, "equip4")) + ); + slot_key = "equip3"; + } else lose = Math.min(left, get.numOf(event.slots, slot)); + if (lose <= 0) event.goto(3); + else { + game.log(player, "废除了" + get.cnNumber(lose) + "个", "#g" + get.translation(slot) + "栏"); + if (!player.disabledSlots) player.disabledSlots = {}; + if (!player.disabledSlots[slot_key]) player.disabledSlots[slot_key] = 0; + player.disabledSlots[slot_key] += lose; + var cards = player.getEquips(slot).filter((card) => !event.cards.includes(card)); + if (cards.length > 0) { + if (lose >= left) { + event._result = { bool: true, links: cards }; + } else if (cards.length > left - lose) { + var source = event.source, + num = cards.length - (left - lose); + if (!source || !source.isIn()) source = player; + source + .chooseButton( + [ + "选择" + + (player == source ? "你" : get.translation(player)) + + "的" + + get.cnNumber(num) + + "张" + + get.translation(slot) + + "牌置入弃牌堆", + cards, + ], + true, + [1, num] + ) + .set("filterOk", function () { + var evt = _status.event; + return ( + ui.selected.buttons.reduce(function (num, button) { + if (evt.slot == "equip3_4") + return ( + num + + Math.max( + get.numOf(get.subtypes(button.link, false), "equip3"), + get.numOf(get.subtypes(button.link, false), "equip4") + ) + ); + return num + get.numOf(get.subtypes(button.link, false), evt.slot); + }, 0) == evt.required + ); + }) + .set("required", num) + .set("slot", slot); + } else event.goto(3); + } else event.goto(3); + } + "step 2"; + if (result.bool) event.cards.addArray(result.links); + "step 3"; + event.num++; + if (event.num < event.slotsx.length) event.goto(1); + else { + player.$syncDisable(); + if (cards.length > 0) player.loseToDiscardpile(cards); + } + }, + enableEquip: function () { + if (!event.slots.length) return; + var slotsx = [...new Set(event.slots)].sort(); + for (var slot of slotsx) { + var lost = player.countDisabledSlot(slot), + gain = Math.min(lost, get.numOf(event.slots, slot)); + if (lost <= 0) continue; + else { + game.log(player, "恢复了" + get.cnNumber(gain) + "个", "#g" + get.translation(slot) + "栏"); + if (!player.disabledSlots) player.disabledSlots = {}; + if (!player.disabledSlots[slot]) player.disabledSlots[slot] = 0; + player.disabledSlots[slot] -= gain; + } + } + player.$syncDisable(); + }, + expandEquip: function () { + if (!event.slots.length) return; + var slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach((type) => { + if (type == "equip3" || type == "equip4") slotsx.add("equip3_4"); + else slotsx.add(type); + }); + } else { + slotsx.addArray(event.slots); + } + slotsx.sort(); + for (var slot of slotsx) { + var expand = get.numOf(event.slots, slot), + slot_key = slot; + if (slot == "equip3_4") { + expand = Math.max(get.numOf(event.slots, "equip3"), get.numOf(event.slots, "equip4")); + slot_key = "equip3"; + } + game.log( + player, + "获得了" + get.cnNumber(expand) + "个额外的", + "#g" + get.translation(slot) + "栏" + ); + if (!player.expandedSlots) player.expandedSlots = {}; + if (!player.expandedSlots[slot_key]) player.expandedSlots[slot_key] = 0; + player.expandedSlots[slot_key] += expand; + } + player.$syncExpand(); + }, + //选择顶装备要顶的牌 + replaceEquip: function () { + "step 0"; + event.cards = []; + var types = get.subtypes(card, false); + if (types.length) { + var info = get.info(card, false); + if (info.customSwap) { + event.cards.addArray( + player.getCards("e", function (card) { + return info.customSwap(card); + }) + ); + event.goto(4); + } else { + event.num = 0; + event.slots = types; + event.slotsx = []; + if (get.is.mountCombined()) { + event.slots.forEach((type) => { + if (type == "equip3" || type == "equip4") event.slotsx.add("equip3_4"); + else event.slotsx.add(type); + }); + } else { + event.slotsx.addArray(event.slots); + } + event.slotsx.sort(); + } + } else event.goto(4); + "step 1"; + var slot = event.slotsx[event.num]; + var left = player.countEquipableSlot(slot), + lose; + if (slot == "equip3_4") + lose = Math.min( + left, + Math.max(get.numOf(event.slots, "equip3"), get.numOf(event.slots, "equip4")) + ); + else lose = Math.min(left, get.numOf(event.slots, slot)); + if (lose <= 0) event.goto(3); + else { + var cards = player.getEquips(slot).filter((card) => { + return !event.cards.includes(card) && lib.filter.canBeReplaced(card, player); + }); + if (cards.length > 0) { + if (lose >= left) { + event._result = { bool: true, links: cards }; + } else if (cards.length > left - lose) { + var source = event.source, + num = cards.length - (left - lose); + if (!source || !source.isIn()) source = player; + source + .chooseButton( + ["选择替换掉" + get.cnNumber(num) + "张" + get.translation(slot) + "牌", cards], + true, + [1, num] + ) + .set("filterOk", function () { + var evt = _status.event; + return ( + ui.selected.buttons.reduce(function (num, button) { + if (evt.slot == "equip3_4") + return ( + num + + Math.max( + get.numOf(get.subtypes(button.link, false), "equip3"), + get.numOf(get.subtypes(button.link, false), "equip4") + ) + ); + return num + get.numOf(get.subtypes(button.link, false), evt.slot); + }, 0) == evt.required + ); + }) + .set("required", num) + .set("slot", slot); + } else event.goto(3); + } else event.goto(3); + } + "step 2"; + if (result.bool) event.cards.addArray(result.links); + "step 3"; + event.num++; + if (event.num < event.slotsx.length) event.goto(1); + "step 4"; + event.result = cards; + }, + //装备牌 + equip: function () { + "step 0"; + var owner = get.owner(card); + if (owner) { + event.owner = owner; + owner.lose(card, ui.special, "visible").set("type", "equip").set("getlx", false); + } else if (get.position(card) == "c") event.updatePile = true; + "step 1"; + if (event.cancelled) { + event.finish(); + return; + } + if (card.willBeDestroyed("equip", player, event)) { + card.selfDestroy(event); + event.finish(); + return; + } else if (event.owner) { + if (event.owner.getCards("hejsx").includes(card)) { + event.finish(); + return; + } + } + if (event.draw) { + game.delay(0, 300); + player.$draw(card); + } + "step 2"; + if (card.clone) { + game.broadcast( + function (card, player) { + if (card.clone) { + card.clone.moveDelete(player); + } + }, + card, + player + ); + card.clone.moveDelete(player); + game.addVideo("gain2", player, get.cardsInfo([card.clone])); + } + player.equiping = true; + "step 3"; + var info = get.info(card, false); + var next = game.createEvent("replaceEquip"); + next.player = player; + next.card = card; + next.setContent(info.replaceEquip || "replaceEquip"); + "step 4"; + var info = get.info(card, false); + if (get.itemtype(result) == "cards") { + player.lose(result, "visible").set("type", "equip").set("getlx", false).swapEquip = true; + if (info.loseThrow) { + player.$throw(result, 1000); + } + event.swapped = true; + } + "step 5"; + if (get.itemtype(result) == "cards") { + for (let card of result) { + if (card.willBeDestroyed("discardPile", player, event)) { + card.selfDestroy(event); + } + } + } + "step 6"; + //if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){ + if (player.isMin() || !player.canEquip(card)) { + event.finish(); + game.cardsDiscard(card); + delete player.equiping; + return; + } + var subtype = get.subtype(card); + if (subtype == "equip6") subtype = "equip3"; + game.broadcastAll(function (type) { + if (lib.config.background_audio) { + game.playAudio("effect", type); + } + }, subtype); + player.$equip(card); + game.addVideo("equip", player, get.cardInfo(card)); + if (event.log != false) game.log(player, "装备了", card); + if (event.updatePile) game.updateRoundNumber(); + "step 7"; + var info = get.info(card, false); + if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) { + if (Array.isArray(info.onEquip)) { + for (var i = 0; i < info.onEquip.length; i++) { + var next = game.createEvent("equip_" + card.name); + next.setContent(info.onEquip[i]); + next.player = player; + next.card = card; + } + } else { + var next = game.createEvent("equip_" + card.name); + next.setContent(info.onEquip); + next.player = player; + next.card = card; + } + if (info.equipDelay != false) game.delayx(); + } + delete player.equiping; + if (event.delay) { + game.delayx(); + } + }, + //装备栏 END + changeGroup: function () { + "step 0"; + event.originGroup = player.group; + if (!event.group) event.group = player.group; + var group = event.group; + player.getHistory("custom").push(event); + if (event.broadcast !== false) { + game.broadcast( + function (player, group) { + player.group = group; + player.node.name.dataset.nature = get.groupnature(group); + }, + player, + group + ); + } + player.group = group; + player.node.name.dataset.nature = get.groupnature(group); + if (event.log !== false) game.log(player, "将势力变为了", "#y" + get.translation(group + 2)); + }, + chooseToDebate: function () { + "step 0"; + event.targets = event.list.filter(function (i) { + return i.countCards("h") > 0; + }); + if (!event.targets.length) event.result = { bool: false }; + else { + var next = player + .chooseCardOL(event.targets, get.translation(player) + "发起了议事,请选择展示的手牌", true) + .set("type", "debate") + .set("source", player) + .set( + "ai", + event.ai || + function (card) { + return Math.random(); + } + ) + .set( + "aiCard", + event.aiCard || + function (target) { + var hs = target.getCards("h"); + return { bool: true, cards: [hs.randomGet()] }; + } + ); + next._args.remove("glow_result"); + } + "step 1"; + var red = [], + black = []; + event.videoId = lib.status.videoId++; + for (var i = 0; i < event.targets.length; i++) { + var card = result[i].cards[0], + target = event.targets[i]; + if (get.color(card, target) == "red") red.push([target, card]); + else black.push([target, card]); + } + event.red = red; + event.black = black; + event.trigger("debateShowOpinion"); + "step 2"; + var red = event.red, + black = event.black; + if (red.length) { + game.log( + red.map(function (i) { + return i[0]; + }), + '意见为红色,展示了', + red.map(function (i) { + return i[1]; + }) + ); + } else game.log("#b无人", '意见为红色'); + if (black.length) { + game.log( + black.map(function (i) { + return i[0]; + }), + "意见为", + "#g黑色", + ",展示了", + black.map(function (i) { + return i[1]; + }) + ); + } else game.log("#b无人", "意见为", "#g黑色"); + game.broadcastAll( + function (name, id, redArgs, blackArgs) { + var dialog = ui.create.dialog(name + "发起了议事", "hidden", "forcebutton"); + dialog.videoId = id; + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("fullwidth"); + dialog.classList.add("fullheight"); + dialog.buttonss = []; + + var list = ["意见为红色的角色", "意见为黑色的角色"]; + for (var i = 0; i < list.length; i++) { + dialog.add('
                                    ' + list[i] + "
                                    "); + var buttons = ui.create.div(".buttons", dialog.content); + dialog.buttonss.push(buttons); + buttons.classList.add("popup"); + buttons.classList.add("guanxing"); + } + var func = function (target) { + if (target._tempTranslate) return target._tempTranslate; + var name = target.name; + if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; + return get.translation(name); + }; + for (var i = 0; i < redArgs.length; i++) { + var list = redArgs[i]; + var button = ui.create.button(list[1], "card", dialog.buttonss[0]); + button.querySelector(".info").innerHTML = func(list[0]); + } + for (var i = 0; i < blackArgs.length; i++) { + var list = blackArgs[i]; + var button = ui.create.button(list[1], "card", dialog.buttonss[1]); + button.querySelector(".info").innerHTML = func(list[0]); + } + dialog.open(); + }, + get.translation(player), + event.videoId, + red, + black + ); + game.delay(4); + "step 3"; + game.broadcastAll("closeDialog", event.videoId); + var opinion = null; + if (event.red.length > event.black.length) opinion = "red"; + else if (event.red.length < event.black.length) opinion = "black"; + if (opinion) + game.log( + player, + "本次发起的议事结果为", + opinion == "red" ? '红色' : "#g黑色" + ); + else game.log(player, "本次发起的议事无结果"); + event.result = { + bool: true, + opinion: opinion, + red: event.red, + black: event.black, + targets: event.targets, + }; + "step 4"; + if (event.callback) { + var next = game.createEvent("debateCallback", false); + next.player = player; + next.debateResult = get.copy(event.result); + next.setContent(event.callback); + } + }, + delay: function () { + game[event.name].apply(game, event._args); + }, + chooseCooperationFor: function () { + "step 0"; + var next = player.chooseButton( + ["选择和" + get.translation(target) + "的协力方式", [event.cardlist, "vcard"]], + true + ); + next.set( + "ai", + event.ai || + function () { + return Math.random(); + } + ); + "step 1"; + if (result.bool) { + player.cooperationWith(target, result.links[0][2].slice(12), event.reason); + } + }, + chooseToPlayBeatmap: function () { + "step 0"; + if (game.online) return; + if (_status.connectMode) event.time = lib.configOL.choose_timeout; + event.videoId = lib.status.videoId++; + //给其他角色看的演奏框 + game.broadcastAll( + function (player, id, beatmap) { + if (_status.connectMode) + lib.configOL.choose_timeout = ( + Math.ceil( + (beatmap.timeleap[beatmap.timeleap.length - 1] + + beatmap.speed * 100 + + (beatmap.current || 0)) / + 1000 + ) + 5 + ).toString(); + if (player == game.me) return; + var str = get.translation(player) + "正在演奏《" + beatmap.name + "》..."; + if (!_status.connectMode) str += "
                                    (点击屏幕可以跳过等待AI操作)"; + ui.create.dialog(str).videoId = id; + if (ui.backgroundMusic) ui.backgroundMusic.pause(); + if (lib.config.background_audio) { + if (beatmap.filename.startsWith("ext:")) game.playAudio(beatmap.filename); + else game.playAudio("effect", beatmap.filename); + } + }, + player, + event.videoId, + event.beatmap + ); + "step 1"; + var beatmap = event.beatmap; + if (event.isMine()) { + var timeleap = beatmap.timeleap.slice(0); + var current = beatmap.current; + //获取两个音符的时间间隔 + var getTimeout = function () { + var time = timeleap.shift(); + var out = time - current; + current = time; + return out; + }; + //初始化一堆变量 + var score = 0; + var added = timeleap.length; + var number_of_tracks = beatmap.number_of_tracks || 6; + var custom_mapping = Array.isArray(beatmap.mapping); + var mapping = custom_mapping ? beatmap.mapping.slice() : beatmap.mapping; + var hitsound = beatmap.hitsound || "hitsound.wav"; + if (hitsound.startsWith("ext:")) hitsound = lib.assetURL + "extension/" + hitsound.slice(4); + else hitsound = lib.assetURL + "audio/effect/" + hitsound; + var hitsound_audio = new Audio(hitsound); + hitsound_audio.volume = 0.25; + var abs = 1; + var node_pos = 0; + if (custom_mapping) { + node_pos = mapping.shift(); + } else if (mapping == "random") { + abs = get.rand(number_of_tracks); + node_pos = abs; + } + var combo = 0; + var max_combo = 0; + var nodes = []; + var roundmenu = false; + //隐藏菜单按钮 + if (ui.roundmenu && ui.roundmenu.display != "none") { + roundmenu = true; + ui.roundmenu.style.display = "none"; + } + if (ui.backgroundMusic) ui.backgroundMusic.pause(); + var event = _status.event; + event.settleed = false; + //建个框框 + var dialog = ui.create.dialog("forcebutton", "hidden"); + event.dialog = dialog; + event.dialog.textPrompt = event.dialog.add( + '
                                    ' + + (beatmap.prompt || "在音符滑条和底部判定区重合时点击屏幕!") + + "
                                    " + ); + event.switchToAuto = function () {}; + event.dialog.classList.add("fixed"); + event.dialog.classList.add("scroll1"); + event.dialog.classList.add("scroll2"); + event.dialog.classList.add("fullwidth"); + event.dialog.classList.add("fullheight"); + event.dialog.classList.add("noupdate"); + event.dialog.style.overflow = "hidden"; + //结束后操作 + event.settle = function () { + if (event.settleed) return; + event.settleed = true; + //评分 + var acc = Math.floor((score / (added * 5)) * 100); + if (!Array.isArray(lib.config.choose_to_play_beatmap_accuracies)) + lib.config.choose_to_play_beatmap_accuracies = []; + lib.config.choose_to_play_beatmap_accuracies.push(acc); + if (lib.config.choose_to_play_beatmap_accuracies.length > 5) + lib.config.choose_to_play_beatmap_accuracies.shift(); + game.saveConfigValue("choose_to_play_beatmap_accuracies"); + var rank; + if (acc == 100) rank = ["SS", "metal"]; + else if (acc >= 94) rank = ["S", "orange"]; + else if (acc >= 87) rank = ["A", "wood"]; + else if (acc >= 80) rank = ["B", "water"]; + else if (acc >= 65) rank = ["C", "thunder"]; + else rank = ["D", "fire"]; + event.dialog.textPrompt.innerHTML = + '
                                    演奏结束!
                                    最大连击数:' + + max_combo + + " 精准度:" + + acc + + "%
                                    "; + game.me.$fullscreenpop( + '演奏评级:' + + rank[0] + + "", + null, + null, + false + ); + //返回结果并继续游戏 + setTimeout(function () { + event._result = { + bool: true, + accuracy: acc, + rank: rank, + }; + event.dialog.close(); + game.resume(); + _status.imchoosing = false; + if (roundmenu) ui.roundmenu.style.display = ""; + if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); + hitsound_audio.remove(); + }, 1000); + }; + event.dialog.open(); + //操作容差 + var height = event.dialog.offsetHeight; + var width = event.dialog.offsetWidth; + var range1 = beatmap.range1 || [90, 110]; + var range2 = beatmap.range2 || [93, 107]; + var range3 = beatmap.range3 || [96, 104]; + var speed = beatmap.speed || 25; + //初始化底部的条子 + var judger = ui.create.div(""); + judger.style["background-image"] = + beatmap.judgebar_color || "linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))"; + judger.style["border-radius"] = "3px"; + judger.style.position = "absolute"; + judger.style.opacity = "0.3"; + var heightj = Math.ceil(height * (beatmap.judgebar_height || 0.1)); + judger.style.height = heightj + "px"; + judger.style.width = width + "px"; + judger.style.left = "0px"; + judger.style.top = height - heightj + "px"; + event.dialog.appendChild(judger); + //生成每个音符 + var addNode = function () { + var node = ui.create.div(""); + nodes.push(node); + node.style["background-image"] = + beatmap.node_color || "linear-gradient(rgba(120, 120, 240, 1), rgba(100, 100, 230, 1))"; + node.style["border-radius"] = "3px"; + node.style.position = "absolute"; + node.style.height = Math.ceil(height / 10) + "px"; + node.style.width = Math.ceil(width / number_of_tracks) - 10 + "px"; + node._position = get.utc(); + event.dialog.appendChild(node); + + node.style.left = Math.ceil((width * node_pos) / number_of_tracks + 5) + "px"; + node.style.top = "-" + Math.ceil(height / 10) + "px"; + ui.refresh(node); + node.style.transition = "all " + speed * 110 + "ms linear"; + node.style.transform = "translateY(" + Math.ceil(height * 1.1) + "px)"; + node.timeout = setTimeout(function () { + if (nodes.includes(node)) { + nodes.remove(node); + player.popup("Miss", "fire", false); + if (player.damagepopups.length) player.$damagepop(); + combo = 0; + } + }, speed * 110); + + if (custom_mapping) { + node_pos = mapping.shift(); + } else if (mapping == "random") { + while (node_pos == abs) { + node_pos = get.rand(number_of_tracks); + } + abs = node_pos; + } else { + node_pos += abs; + if (node_pos > number_of_tracks - 1) { + abs = -1; + node_pos = number_of_tracks - 2; + } else if (node_pos < 0) { + abs = 1; + node_pos = 1; + } + } + if (timeleap.length) { + setTimeout(function () { + addNode(); + }, getTimeout()); + } else { + setTimeout(function () { + event.settle(); + }, speed * 110 + 100); + } + }; + //点击时的判断操作 + var click = function () { + if (!nodes.length) return; + for (var node of nodes) { + //用生成到点击的时间差来判断距离 + var time = get.utc(); + var top = (time - node._position) / speed; + if (top > range1[1]) continue; + else if (top < range1[0]) return; + nodes.remove(node); + clearTimeout(node.timeout); + node.style.transform = ""; + node.style.transition = "all 0s"; + node.style.top = height * ((top - 10) / 100) + "px"; + ui.refresh(node); + node.style.transition = "all 0.5s"; + node.style.transform = "scale(1.2)"; + node.delete(); + if (top >= range3[0] && top < range3[1]) { + score += 5; + player.popup("Perfect", "orange", false); + } else if (top >= range2[0] && top < range2[1]) { + score += 3; + player.popup("Great", "wood", false); + } else { + score += 1; + player.popup("Good", "soil", false); + } + if (player.damagepopups.length) player.$damagepop(); + combo++; + max_combo = Math.max(combo, max_combo); + hitsound_audio.currentTime = 0; + if (hitsound_audio.paused) Promise.resolve(hitsound_audio.play()).catch(() => void 0); + break; + } + }; + document.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", click); + + game.pause(); + game.countChoose(); + setTimeout(() => { + if (!lib.config.background_audio) return; + if (beatmap.filename.startsWith("ext:")) game.playAudio(beatmap.filename); + else game.playAudio("effect", beatmap.filename); + }, Math.floor(speed * 100 * (0.9 + beatmap.judgebar_height)) + beatmap.current); + setTimeout(function () { + addNode(); + }, getTimeout()); + } else if (event.isOnline()) { + event.send(); + } else { + game.pause(); + game.countChoose(); + var settle = function () { + _status.imchoosing = false; + //Algorithm: Generate the random number range using the mean and the half standard deviation of accuracies of the player's last 5 plays + //算法:用玩家的上5次游玩的准确率的平均数和半标准差生成随机数范围 + var choose_to_play_beatmap_accuracies = ( + lib.config.choose_to_play_beatmap_accuracies || [] + ).concat( + Array.from( + { + length: 6 - (lib.config.choose_to_play_beatmap_accuracies || []).length, + }, + () => get.rand(70, 100) + ) + ); + var mean = Math.round( + choose_to_play_beatmap_accuracies.reduce( + (previousValue, currentValue) => previousValue + currentValue + ) / choose_to_play_beatmap_accuracies.length + ); + var half_standard_deviation = Math.round( + Math.sqrt( + choose_to_play_beatmap_accuracies.reduce( + (previousValue, currentValue) => previousValue + Math.pow(currentValue - mean, 2), + 0 + ) + ) / 2 + ); + var acc = Math.min( + Math.max( + get.rand.apply( + get, + beatmap.aiAcc || [ + mean - half_standard_deviation - get.rand(0, half_standard_deviation), + mean + half_standard_deviation + get.rand(0, half_standard_deviation), + ] + ), + 0 + ), + 100 + ); + var rank; + if (acc == 100) rank = ["SS", "metal"]; + else if (acc >= 94) rank = ["S", "orange"]; + else if (acc >= 87) rank = ["A", "green"]; + else if (acc >= 80) rank = ["B", "water"]; + else if (acc >= 65) rank = ["C", "thunder"]; + else rank = ["D", "fire"]; + event._result = { + bool: true, + accuracy: acc, + rank: rank, + }; + if (event.dialog) event.dialog.close(); + if (event.control) event.control.close(); + game.resume(); + }; + var song_duration = + beatmap.timeleap[beatmap.timeleap.length - 1] + + beatmap.speed * 100 + + 1000 + + (beatmap.current || 0); + var settle_timeout = setTimeout(settle, song_duration); + if (!_status.connectMode) { + var skip_timeout; + var skip = () => { + settle(); + Array.from(ui.window.getElementsByTagName("audio")).forEach((audio) => { + if ( + audio.currentSrc.includes( + beatmap.filename.startsWith("ext:") ? beatmap.name : beatmap.filename + ) + ) + audio.remove(); + }); + document.removeEventListener(lib.config.touchscreen ? "touchend" : "click", skip); + clearTimeout(settle_timeout); + clearTimeout(skip_timeout); + }; + document.addEventListener(lib.config.touchscreen ? "touchend" : "click", skip); + skip_timeout = setTimeout( + () => document.removeEventListener(lib.config.touchscreen ? "touchend" : "click", skip), + song_duration + ); + } + } + "step 2"; + game.broadcastAll( + function (id, time) { + if (_status.connectMode) lib.configOL.choose_timeout = time; + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); + }, + event.videoId, + event.time + ); + var result = event.result || result; + event.result = result; + }, + chooseToMove: function () { + "step 0"; + if (event.chooseTime && _status.connectMode && !game.online) { + event.time = lib.configOL.choose_timeout; + game.broadcastAll(function (time) { + lib.configOL.choose_timeout = time; + }, event.chooseTime); + } + if (event.isMine()) { + delete ui.selected.guanxing_button; + var list = event.list, + filterMove = event.filterMove, + filterOk = event.filterOk; + _status.imchoosing = true; + var event = _status.event; + event.settleed = false; + event.dialog = ui.create.dialog(event.prompt || "请选择要操作的牌", "hidden", "forcebutton"); + event.switchToAuto = function () { + if (!filterOk(event.moved)) { + if (!event.forced) event._result = { bool: false }; + else event._result = "ai"; + } else { + event._result = { + bool: true, + moved: event.moved, + }; + } + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.resume(); + _status.imchoosing = false; + setTimeout(function () { + ui.arena.classList.remove("choose-to-move"); + }, 500); + }; + event.dialog.classList.add("scroll1"); + event.dialog.classList.add("scroll2"); + event.dialog.classList.add("fullwidth"); + if (list.length > 1) { + ui.arena.classList.add("choose-to-move"); + event.dialog.classList.add("fullheight"); + } + + event.moved = []; + var buttonss = []; + event.buttonss = buttonss; + var updateButtons = function () { + for (var i of buttonss) { + event.moved[i._link] = get.links(Array.from(i.childNodes)); + if (i.textPrompt) + i.previousSibling.innerHTML = + '
                                    ' + i.textPrompt(event.moved[i._link]) + "
                                    "; + } + if (filterOk(event.moved)) { + ui.create.confirm("o"); + } else { + if (!event.forced) ui.create.confirm("c"); + else if (ui.confirm) ui.confirm.close(); + } + }; + var clickButtons = function () { + if (!ui.selected.guanxing_button) return; + if (ui.selected.guanxing_button.parentNode == this) return; + if (!filterMove(ui.selected.guanxing_button, this._link, event.moved)) return; + ui.selected.guanxing_button.classList.remove("glow2"); + this.appendChild(ui.selected.guanxing_button); + delete ui.selected.guanxing_button; + updateButtons(); + }; + + for (var i = 0; i < list.length; i++) { + var tex = event.dialog.add('
                                    ' + list[i][0] + "
                                    "); + tex.classList.add("choosetomove"); + var buttons = ui.create.div(".buttons", event.dialog.content, clickButtons); + buttonss.push(buttons); + buttons.classList.add("popup"); + buttons.classList.add("guanxing"); + buttons._link = i; + if (list[i][1]) { + if (get.itemtype(list[i][1]) == "cards") { + var cardsb = ui.create.buttons(list[i][1], "card", buttons); + if (list[i][2] && typeof list[i][2] == "string") { + for (var ij of cardsb) ij.node.gaintag.innerHTML = get.translation(list[i][2]); + } + } else if (list[i][1].length == 2) { + ui.create.buttons(list[i][1][0], list[i][1][1], buttons); + } + } + if (list[i][2] && typeof list[i][2] == "function") buttons.textPrompt = list[i][2]; + } + var tex = event.dialog.add( + '
                                    点击两张牌以交换位置;点击一张牌并点击其他区域以移动卡牌
                                    ' + ); + tex.classList.add("choosetomove"); + + event.dialog.open(); + updateButtons(); + + event.custom.replace.button = function (button) { + var node = button.parentNode; + if (!buttonss.includes(node)) return; + if (!ui.selected.guanxing_button) { + ui.selected.guanxing_button = button; + button.classList.add("glow2"); + return; + } + if (ui.selected.guanxing_button == button) { + button.classList.remove("glow2"); + delete ui.selected.guanxing_button; + return; + } + if (!filterMove(button, ui.selected.guanxing_button, event.moved)) return; + var par1 = ui.selected.guanxing_button.parentNode, + ind1 = ui.selected.guanxing_button.nextSibling, + par2 = button.parentNode, + ind2 = button.nextSibling; + ui.selected.guanxing_button.classList.remove("glow2"); + par1.insertBefore(button, ind1); + par2.insertBefore(ui.selected.guanxing_button, ind2); + delete ui.selected.guanxing_button; + updateButtons(); + }; + event.custom.replace.confirm = function (bool) { + if (bool) + event._result = { + bool: true, + moved: event.moved, + }; + else event._result = { bool: false }; + event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.resume(); + _status.imchoosing = false; + setTimeout(function () { + ui.arena.classList.remove("choose-to-move"); + }, 500); + }; + + game.pause(); + game.countChoose(); + event.choosing = true; + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.time) + game.broadcastAll(function (time) { + lib.configOL.choose_timeout = time; + }, event.time); + var result = event.result || result; + if ((!result || result == "ai" || (event.forced && !result.bool)) && event.processAI) { + var moved = event.processAI(event.list); + if (moved) + result = { + bool: true, + moved: moved, + }; + else result = { bool: false }; + } + event.result = result; + }, + showCharacter: function () { + "step 0"; + event.trigger("showCharacterEnd"); + "step 1"; + event.trigger("showCharacterAfter"); + if (get.mode() == "identity" && player.isZhu) event.trigger("zhuUpdate"); + }, + removeCharacter: function () { + player.$removeCharacter(event.num); + }, + chooseUseTarget: function () { + "step 0"; + if (get.is.object(card) && event.viewAs === false) card.isCard = true; + if (cards && get.itemtype(card) != "card") { + card = get.copy(card); + card.cards = cards.slice(0); + event.card = card; + } + let evt = event.getParent("chooseToUse"); + if (get.itemtype(evt) !== "event") evt = event; + if ( + !lib.filter.cardEnabled(card, player) || + (event.addCount !== false && !lib.filter.cardUsable(card, player, evt)) + ) { + event.result = { bool: false }; + event.finish(); + return; + } + var info = get.info(card); + var range; + if (!info.notarget) { + var select = get.copy(info.selectTarget); + range = get.select(select); + if (event.selectTarget) range = get.select(event.selectTarget); + game.checkMod(card, player, range, "selectTarget", player); + } + if (info.notarget || range[1] <= -1) { + if (!info.notarget && range[1] <= -1) { + for (var i = 0; i < targets.length; i++) { + if (event.filterTarget) { + if (!event.filterTarget(card, player, targets[i])) { + targets.splice(i--, 1); + } + } else if ( + !player.canUse( + card, + targets[i], + event.nodistance ? false : null, + event.addCount === false ? null : true + ) + ) { + targets.splice(i--, 1); + } + } + if (targets.length) { + event.targets2 = targets; + } else { + event.finish(); + return; + } + } else event.targets2 = []; + if (event.forced) { + event._result = { bool: true }; + return; + } else { + var next = player.chooseBool(); + next.set( + "prompt", + event.prompt || + "是否" + + (event.targets2.length ? "对" : "") + + get.translation(event.targets2) + + "使用" + + get.translation(card) + + "?" + ); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + if (event.prompt2) next.set("prompt2", event.prompt2); + next.ai = function () { + var eff = 0; + for (var i = 0; i < event.targets2.length; i++) { + eff += get.effect(event.targets2[i], card, player, player); + } + return eff > 0; + }; + } + } else { + if (event.filterTarget) { + var targets = game.filterPlayer(function (current) { + return event.filterTarget(card, player, current); + }); + if (targets.length < range[0]) { + event._result = { bool: false }; + return; + } else if (!info.complexTarget && targets.length == range[0] && range[0] == range[1]) { + event.targets2 = targets; + event._result = { bool: true }; + return; + } + } + var next = player.chooseTarget(); + next.set("_get_card", card); + next.set( + "filterTarget", + event.filterTarget || + function (card, player, target) { + if (!_status.event.targets.includes(target)) return false; + if (!_status.event.nodistance && !lib.filter.targetInRange(card, player, target)) + return false; + return lib.filter.targetEnabledx(card, player, target); + } + ); + next.set("ai", event.ai || get.effect_use); + next.set("selectTarget", event.selectTarget || lib.filter.selectTarget); + if (event.nodistance) next.set("nodistance", true); + if (event.forced) next.set("forced", true); + if (event.addCount !== false) next.set("addCount_extra", true); + next.set("targets", targets); + next.set("prompt", event.prompt || "选择" + get.translation(card) + "的目标"); + if (event.prompt2) next.set("prompt2", event.prompt2); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + } + "step 1"; + if (result.bool) { + event.result = { + bool: true, + targets: event.targets2 || result.targets, + }; + var args = [card, event.targets2 || result.targets]; + if (cards) args.push(cards.slice()); + var next = player.useCard(...args); + next.oncard = event.oncard; + if (cards) next.cards = cards.slice(0); + if (event.nopopup) next.nopopup = true; + if (event.animate === false) next.animate = false; + if (event.throw === false) next.throw = false; + if (event.addCount === false) next.addCount = false; + if (event.noTargetDelay) next.targetDelay = false; + if (event.nodelayx) next.delayx = false; + if (event.logSkill) { + if (typeof event.logSkill == "string") { + next.skill = event.logSkill; + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + } else event.result = { bool: false }; + }, + chooseToDuiben: function () { + "step 0"; + if (!event.namelist) event.namelist = ["全军出击", "分兵围城", "奇袭粮道", "开城诱敌"]; + game.broadcastAll(function (list) { + var list2 = ["db_atk1", "db_atk2", "db_def1", "db_def2"]; + for (var i = 0; i < 4; i++) { + lib.card[list2[i]].image = "card/" + list2[i] + (list[0] == "全军出击" ? "" : "_" + list[i]); + lib.translate[list2[i]] = list[i]; + } + }, event.namelist); + if (!event.title) event.title = "对策"; + game.log(player, "向", target, "发起了", "#y" + event.title); + if (!event.ai) + event.ai = function () { + return 1 + Math.random(); + }; + if (_status.connectMode) { + player + .chooseButtonOL( + [ + [ + player, + [ + event.title + ":请选择一种策略", + [ + [ + ["", "", "db_def2"], + ["", "", "db_def1"], + ], + "vcard", + ], + ], + true, + ], + [ + target, + [ + event.title + ":请选择一种策略", + [ + [ + ["", "", "db_atk1"], + ["", "", "db_atk2"], + ], + "vcard", + ], + ], + true, + ], + ], + function () {}, + event.ai + ) + .set("switchToAuto", function () { + _status.event.result = "ai"; + }) + .set("processAI", function () { + var buttons = _status.event.dialog.buttons; + return { + bool: true, + links: [buttons.randomGet().link], + }; + }); + } + "step 1"; + if (_status.connectMode) { + event.mes = result[player.playerid].links[0][2]; + event.tes = result[target.playerid].links[0][2]; + event.goto(4); + } else { + player.chooseButton( + [ + event.title + ":请选择一种策略", + [ + [ + ["", "", "db_def2"], + ["", "", "db_def1"], + ], + "vcard", + ], + ], + true + ).ai = event.ai; + } + "step 2"; + event.mes = result.links[0][2]; + target.chooseButton( + [ + event.title + ":请选择一种策略", + [ + [ + ["", "", "db_atk1"], + ["", "", "db_atk2"], + ], + "vcard", + ], + ], + true + ).ai = event.ai; + "step 3"; + event.tes = result.links[0][2]; + "step 4"; + game.broadcast(function () { + ui.arena.classList.add("thrownhighlight"); + }); + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + target.$compare(game.createCard(event.tes, "", ""), player, game.createCard(event.mes, "", "")); + game.log(target, "选择的策略为", "#g" + get.translation(event.tes)); + game.log(player, "选择的策略为", "#g" + get.translation(event.mes)); + game.delay(0, 1500); + "step 5"; + var mes = event.mes.slice(6); + var tes = event.tes.slice(6); + var str; + if (mes == tes) { + str = get.translation(player) + event.title + "成功"; + player.popup("胜", "wood"); + target.popup("负", "fire"); + game.log(player, "#g胜"); + event.result = { bool: true }; + } else { + str = get.translation(player) + event.title + "失败"; + target.popup("胜", "wood"); + player.popup("负", "fire"); + game.log(target, "#g胜"); + event.result = { bool: false }; + } + event.result.player = event.mes; + event.result.target = event.tes; + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.trySkillAudio( + event.getParent().name + "_" + (event.result.bool ? "true" + mes : "false"), + player + ); + game.delay(2); + "step 6"; + game.broadcastAll(function () { + ui.arena.classList.remove("thrownhighlight"); + }); + game.addVideo("thrownhighlight2"); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + }, + chooseToPSS: function () { + "step 0"; + game.log(player, "对", target, "发起了猜拳"); + if (_status.connectMode) { + player + .chooseButtonOL( + [ + [ + player, + [ + "猜拳:请选择一种手势", + [ + [ + ["", "", "pss_stone"], + ["", "", "pss_scissor"], + ["", "", "pss_paper"], + ], + "vcard", + ], + ], + true, + ], + [ + target, + [ + "猜拳:请选择一种手势", + [ + [ + ["", "", "pss_stone"], + ["", "", "pss_scissor"], + ["", "", "pss_paper"], + ], + "vcard", + ], + ], + true, + ], + ], + function () {}, + function () { + return 1 + Math.random(); + } + ) + .set("switchToAuto", function () { + _status.event.result = "ai"; + }) + .set("processAI", function () { + var buttons = _status.event.dialog.buttons; + return { + bool: true, + links: [buttons.randomGet().link], + }; + }); + } + "step 1"; + if (_status.connectMode) { + event.mes = result[player.playerid].links[0][2]; + event.tes = result[target.playerid].links[0][2]; + event.goto(4); + } else { + player.chooseButton( + [ + "猜拳:请选择一种手势", + [ + [ + ["", "", "pss_stone"], + ["", "", "pss_scissor"], + ["", "", "pss_paper"], + ], + "vcard", + ], + ], + true + ).ai = function () { + return 1 + Math.random(); + }; + } + "step 2"; + event.mes = result.links[0][2]; + target.chooseButton( + [ + "猜拳:请选择一种手势", + [ + [ + ["", "", "pss_stone"], + ["", "", "pss_scissor"], + ["", "", "pss_paper"], + ], + "vcard", + ], + ], + true + ).ai = function () { + return 1 + Math.random(); + }; + "step 3"; + event.tes = result.links[0][2]; + "step 4"; + game.broadcast(function () { + ui.arena.classList.add("thrownhighlight"); + }); + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + player.$compare(game.createCard(event.mes, "", ""), target, game.createCard(event.tes, "", "")); + game.log(player, "选择的手势为", "#g" + get.translation(event.mes)); + game.log(target, "选择的手势为", "#g" + get.translation(event.tes)); + game.delay(0, 1500); + "step 5"; + var mes = event.mes.slice(4); + var tes = event.tes.slice(4); + var str; + if (mes == tes) { + str = "二人平局"; + player.popup("平", "metal"); + target.popup("平", "metal"); + game.log("猜拳的结果为", "#g平局"); + event.result = { tie: true }; + } else { + if ({ paper: "stone", scissor: "paper", stone: "scissor" }[mes] == tes) { + str = get.translation(player) + "胜利"; + player.popup("胜", "wood"); + target.popup("负", "fire"); + game.log(player, "#g胜"); + event.result = { bool: true }; + } else { + str = get.translation(target) + "胜利"; + target.popup("胜", "wood"); + player.popup("负", "fire"); + game.log(target, "#g胜"); + event.result = { bool: false }; + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + "step 6"; + game.broadcastAll(function () { + ui.arena.classList.remove("thrownhighlight"); + }); + game.addVideo("thrownhighlight2"); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + }, + cardsDiscard: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed("discardPile", null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == "c") withPile = true; + cards[i].discard(); + } + if (withPile) game.updateRoundNumber(); + }, + orderingDiscard: function () { + var cards = event.relatedEvent.orderingCards.slice(0); + for (var i = 0; i < cards.length; i++) { + if (get.position(cards[i], true) != "o") cards.splice(i--, 1); + } + if (cards.length) game.cardsDiscard(cards); + }, + cardsGotoOrdering: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed("ordering", null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == "c") withPile = true; + cards[i].fix(); + ui.ordering.appendChild(cards[i]); + } + if (withPile) game.updateRoundNumber(); + var evt = event.relatedEvent || event.getParent(); + if (!evt.orderingCards) evt.orderingCards = []; + if (!evt.noOrdering && !evt.cardsOrdered) { + evt.cardsOrdered = true; + var next = game.createEvent("orderingDiscard", false); + event.next.remove(next); + evt.after.push(next); + next.relatedEvent = evt; + next.setContent("orderingDiscard"); + } + if (!evt.noOrdering) evt.orderingCards.addArray(cards); + }, + cardsGotoSpecial: function () { + game.getGlobalHistory().cardMove.push(event); + var withPile = false; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed("special", null, event)) { + cards[i].selfDestroy(event); + continue; + } + if (get.position(cards[i], true) == "c") withPile = true; + cards[i].fix(); + ui.special.appendChild(cards[i]); + } + if (withPile) game.updateRoundNumber(); + if (event.toRenku) { + _status.renku.addArray(cards); + if (_status.renku.length > 6) { + var cards = _status.renku.splice(0, _status.renku.length - 6); + game.log(cards, "从仁库进入了弃牌堆"); + game.cardsDiscard(cards).set("outRange", true).fromRenku = true; + } + game.updateRenku(); + } + }, + cardsGotoPile: function () { + if (event.washCard) { + event.trigger("washCard"); + for (var i = 0; i < lib.onwash.length; i++) { + if (lib.onwash[i]() == "remove") { + lib.onwash.splice(i--, 1); + } + } + } + game.getGlobalHistory().cardMove.push(event); + if (!event._triggeronly) game.$cardsGotoPile(event); + }, + chooseToEnable: function () { + "step 0"; + var list = []; + for (var i = 1; i <= 5; i++) { + if (player.hasDisabledSlot(i)) list.push("equip" + i); + } + if (!list.length) event.finish(); + else if (list.length == 1) { + event.list = list; + event._result = { control: list[0] }; + } else { + var next = source.chooseControl(list); + next.set("prompt", "请选择恢复" + get.translation(player.name) + "的一个装备栏"); + if (!event.ai) + event.ai = function (event, player, list) { + return list.randomGet(); + }; + event.ai = event.ai(event.getParent(), player, list); + next.ai = function () { + return event.ai; + }; + } + "step 1"; + event.result = { control: result.control }; + player.enableEquip(result.control); + }, + chooseToDisable: function () { + "step 0"; + var list = []; + for (var i = 1; i <= 5; i++) { + if (player.hasEnabledSlot(i)) list.push("equip" + i); + } + if (event.horse) { + if (list.includes("equip3") && (get.is.mountCombined() || list.includes("equip4"))) + list.push("equip3_4"); + list.remove("equip3"); + list.remove("equip4"); + } + if (!list.length) event.finish(); + else if (list.length == 1) { + event.list = list; + event._result = { control: list[0] }; + } else { + list.sort(); + event.list = list; + var next = source.chooseControl(list); + next.set("prompt", "请选择废除" + get.translation(player.name) + "的一个装备栏"); + if (!event.ai) + event.ai = function (event, player, list) { + return list.randomGet(); + }; + event.ai = event.ai(event.getParent(), player, list); + next.ai = function () { + return event.ai; + }; + } + "step 1"; + event.result = { control: result.control }; + if (result.control == "equip3_4") { + player.disableEquip(3, 4); + } else player.disableEquip(result.control); + }, + swapEquip: function () { + "step 0"; + game.log(player, "和", target, "交换了装备区中的牌"); + event.cards = [player.getCards("e"), target.getCards("e")]; + game.loseAsync({ + player: player, + target: target, + cards1: event.cards[0], + cards2: event.cards[1], + }).setContent("swapHandcardsx"); + "step 1"; + for (var i = 0; i < event.cards[1].length; i++) { + if (get.position(event.cards[1][i], true) == "o") player.equip(event.cards[1][i]); + } + for (var i = 0; i < event.cards[0].length; i++) { + if (get.position(event.cards[0][i], true) == "o") target.equip(event.cards[0][i]); + } + }, + disableJudge: function () { + "step 0"; + game.log(player, "废除了判定区"); + var js = player.getCards("j"); + if (js.length) player.discard(js); + player.storage._disableJudge = true; + //player.markSkill('_disableJudge'); + "step 1"; + game.broadcastAll(function (player, card) { + player.$disableJudge(); + }, player); + }, + enableJudge: function () { + if (!player.storage._disableJudge) return; + game.log(player, "恢复了判定区"); + game.broadcastAll(function (player) { + player.$enableJudge(); + }, player); + }, + /*----分界线----*/ + phasing: function () { + "step 0"; + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + game.phaseNumber++; + player.phaseNumber++; + game.broadcastAll( + function (player, player2, num, popup) { + if (lib.config.glow_phase) { + if (player2) player2.classList.remove("glow_phase"); + player.classList.add("glow_phase"); + } + player.phaseNumber = num; + if (popup && lib.config.show_phase_prompt) player.popup("回合开始", null, false); + }, + player, + _status.currentPhase, + player.phaseNumber, + !player.noPhaseDelay + ); + _status.currentPhase = player; + _status.discarded = []; + game.syncState(); + game.addVideo("phaseChange", player); + if (game.phaseNumber == 1) { + delete player._start_cards; + if (lib.configOL.observe) { + lib.configOL.observeReady = true; + game.send("server", "config", lib.configOL); + } + } + game.log(); + game.log(player, "的回合开始"); + player._noVibrate = true; + if ( + get.config("identity_mode") != "zhong" && + get.config("identity_mode") != "purple" && + !_status.connectMode + ) { + var num; + switch (get.config("auto_identity")) { + case "one": + num = 1; + break; + case "two": + num = 2; + break; + case "three": + num = 3; + break; + case "always": + num = -1; + break; + default: + num = 0; + break; + } + if ( + num && + !_status.identityShown && + game.phaseNumber > game.players.length * num && + game.showIdentity + ) { + if (!_status.video) player.popup("显示身份"); + _status.identityShown = true; + game.showIdentity(false); + } + } + player.ai.tempIgnore = []; + if (ui.land && ui.land.player == player) { + game.addVideo("destroyLand"); + ui.land.destroy(); + } + "step 1"; + event.trigger("phaseBeginStart"); + }, + toggleSubPlayer: function () { + "step 0"; + var list = event.list || player.storage.subplayer.skills.slice(0); + list.remove(player.storage.subplayer.name2); + event.list = list; + if (!event.directresult) { + if (list.length > 1) { + var dialog = ui.create.dialog("更换一个随从", "hidden"); + dialog.add([list, "character"]); + player.chooseButton(dialog, true); + } else if (list.length == 1) { + event.directresult = list[0]; + } else { + event.finish(); + } + } else { + if (!list.includes(event.directresult)) { + event.finish(); + } + } + "step 1"; + if (!event.directresult) { + if (result && result.bool && result.links[0]) { + event.directresult = result.links[0]; + } else { + event.finish(); + return; + } + } + if (player.storage.subplayer) { + var current = player.storage.subplayer.name2; + if (event.directresult == current) { + event.finish(); + return; + } + player.storage[current].hp = player.hp; + player.storage[current].maxHp = player.maxHp; + player.storage[current].hs = player.getCards("h"); + player.storage[current].es = player.getCards("e"); + player.lose(player.getCards("he"), ui.special)._triggered = null; + + var cfg = player.storage[event.directresult]; + player.storage.subplayer.name2 = event.directresult; + player.reinit(current, event.directresult, [cfg.hp, cfg.maxHp]); + if (cfg.hs.length) player.directgain(cfg.hs); + if (cfg.es.length) player.directequip(cfg.es); + } + }, + exitSubPlayer: function () { + "step 0"; + if (player.storage.subplayer) { + var current = player.storage.subplayer.name2; + if (event.remove) { + player.lose(player.getCards("he"), ui.discardPile)._triggered = null; + } else { + player.storage[current].hp = player.hp; + player.storage[current].maxHp = player.maxHp; + player.storage[current].hs = player.getCards("h"); + player.storage[current].es = player.getCards("e"); + player.lose(player.getCards("he"), ui.special)._triggered = null; + } + player.reinit(current, player.storage.subplayer.name, [ + player.storage.subplayer.hp, + player.storage.subplayer.maxHp, + ]); + player.update(); + if (event.remove) { + if (player.storage[current].onremove) { + player.storage[current].onremove(player); + } + delete player.storage[current]; + player.storage.subplayer.skills.remove(current); + game.log(player, "牺牲了随从", "#g" + current); + } else { + game.log(player, "收回了随从", "#g" + current); + } + player.addSkill(player.storage.subplayer.skills); + } + "step 1"; + if (player.storage.subplayer) { + player.directgain(player.storage.subplayer.hs); + player.directequip(player.storage.subplayer.es); + } + player.removeSkill("subplayer"); + "step 2"; + if (event.remove) { + event.trigger("subPlayerDie"); + } + }, + callSubPlayer: function () { + "step 0"; + var list = player.getSubPlayers(event.tag); + event.list = list; + if (!event.directresult) { + if (list.length > 1) { + var dialog = ui.create.dialog("调遣一个随从", "hidden"); + dialog.add([list, "character"]); + player.chooseButton(dialog, true); + } else if (list.length == 1) { + event.directresult = list[0]; + } else { + event.finish(); + } + } else { + if (!list.includes(event.directresult)) { + event.finish(); + } + } + "step 1"; + if (!event.directresult) { + if (result && result.bool && result.links[0]) { + event.directresult = result.links[0]; + } else { + event.finish(); + return; + } + } + if (event.directresult) { + var cfg = player.storage[event.directresult]; + var source = cfg.source || player.name; + var name = event.directresult; + game.log(player, "调遣了随从", "#g" + name); + player.storage.subplayer = { + name: source, + name2: event.directresult, + hp: player.hp, + maxHp: player.maxHp, + skills: event.list.slice(0), + hs: player.getCards("h"), + es: player.getCards("e"), + intro2: cfg.intro2, + }; + player.removeSkill(event.list); + player.reinit(source, name, [cfg.hp, cfg.maxHp]); + player.addSkill("subplayer"); + player.lose(player.getCards("he"), ui.special)._triggered = null; + if (cfg.hs.length) player.directgain(cfg.hs); + if (cfg.es.length) player.directequip(cfg.es); + } + "step 2"; + game.delay(); + }, + addExtraTarget: function () { + "step 0"; + event.num = 0; + "step 1"; + var target = targets[num], + info = get.info(card); + if (target == event.target && event.addedTarget) { + event.addedTargets[num] = event.addedTarget; + event._result = { bool: false }; + } else if ( + game.hasPlayer(function (current) { + return info.filterAddedTarget(card, player, current, target); + }) + ) { + var next = player.chooseTarget( + get.translation(event.card) + ":选择" + get.translation(targets[num]) + "对应的指向目标", + function (card, player, target) { + var card = get.card(), + info = get.info(card); + return info.filterAddedTarget(card, player, target, _status.event.preTarget); + }, + true + ); + next.set("_get_card", card); + next.set("preTarget", targets[num]); + next.set("ai", (target) => get.effect(target, get.card(), player, _status.event.player)); + } else { + event.addedTargets[num] = false; + event._result = { bool: false }; + } + "step 2"; + if (result.bool) { + event.addedTargets[num] = result.targets[0]; + player.line2([targets[num], result.targets[0]]); + } + event.num++; + if (event.num < targets.length) event.goto(1); + }, + reverseOrder: function () { + "step 0"; + game.delay(); + "step 1"; + var choice; + if (get.tag(card, "multineg")) { + choice = player.previous.side == player.side ? "逆时针" : "顺时针"; + } else { + choice = player.next.side == player.side ? "逆时针" : "顺时针"; + } + player + .chooseControl("顺时针", "逆时针", function (event, player) { + return _status.event.choice || "逆时针"; + }) + .set("prompt", "选择" + get.translation(card) + "的结算方向") + .set("choice", choice) + .set("forceDie", true); + "step 2"; + if (result && result.control == "顺时针") { + var evt = event.getParent(), + sorter = _status.currentPhase || player; + evt.fixedSeat = true; + evt.targets.sortBySeat(sorter); + evt.targets.reverse(); + if (evt.targets[evt.targets.length - 1] == sorter) { + evt.targets.unshift(evt.targets.pop()); + } + } + }, + addJudgeCard: function () { + if (lib.filter.judge(card, player, target) && cards.length && get.position(cards[0], true) == "o") + target.addJudge(card, cards); + }, + equipCard: function () { + if (cards.length && get.position(cards[0], true) == "o") target.equip(cards[0]); + }, + gameDraw: function () { + "step 0"; + if (_status.brawl && _status.brawl.noGameDraw) { + event.finish(); + return; + } + var end = player; + var numx = num; + do { + if (typeof num == "function") { + numx = num(player); + } + if (player.getTopCards) player.directgain(player.getTopCards(numx)); + else player.directgain(get.cards(numx)); + if ( + player.singleHp === true && + get.mode() != "guozhan" && + (lib.config.mode != "doudizhu" || _status.mode != "online") + ) { + player.doubleDraw(); + } + player._start_cards = player.getCards("h"); + player = player.next; + } while (player != end); + event.changeCard = get.config("change_card"); + if ( + _status.connectMode || + (lib.config.mode == "single" && _status.mode != "wuxianhuoli") || + (lib.config.mode == "doudizhu" && _status.mode == "online") || + (lib.config.mode != "identity" && + lib.config.mode != "guozhan" && + lib.config.mode != "doudizhu" && + lib.config.mode != "single") + ) { + event.changeCard = "disabled"; + } + "step 1"; + if (event.changeCard != "disabled" && !_status.auto) { + event.dialog = ui.create.dialog("是否使用手气卡?"); + ui.create.confirm("oc"); + event.custom.replace.confirm = function (bool) { + _status.event.bool = bool; + game.resume(); + }; + } else { + event.finish(); + } + "step 2"; + if (event.changeCard == "once") { + event.changeCard = "disabled"; + } else if (event.changeCard == "twice") { + event.changeCard = "once"; + } else if (event.changeCard == "disabled") { + event.bool = false; + return; + } + _status.imchoosing = true; + event.switchToAuto = function () { + _status.event.bool = false; + game.resume(); + }; + game.pause(); + "step 3"; + _status.imchoosing = false; + if (event.bool) { + if (game.changeCoin) { + game.changeCoin(-3); + } + var hs = game.me.getCards("h"); + game.addVideo("lose", game.me, [get.cardsInfo(hs), [], [], []]); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + game.me.directgain(get.cards(hs.length)); + event.goto(2); + } else { + if (event.dialog) event.dialog.close(); + if (ui.confirm) ui.confirm.close(); + game.me._start_cards = game.me.getCards("h"); + event.finish(); + } + }, + phaseLoop: function () { + "step 0"; + var num = 1, + current = player; + while (current.getSeatNum() == 0) { + current.setSeatNum(num); + current = current.next; + num++; + } + "step 1"; + for (var i = 0; i < lib.onphase.length; i++) { + lib.onphase[i](); + } + player.phase(); + "step 2"; + if (!game.players.includes(event.player.next)) { + event.player = game.findNext(event.player.next); + } else { + event.player = event.player.next; + } + event.goto(1); + }, + loadPackage: function () { + "step 0"; + if (event.packages.length) { + window.game = game; + var pack = event.packages.shift().split("/"); + lib.init.js(lib.assetURL + pack[0], pack[1], game.resume); + game.pause(); + } else { + event.finish(); + } + "step 1"; + if (!lib.config.dev) delete window.game; + var character = lib.imported.character; + var card = lib.imported.card; + var i, j, k; + for (i in character) { + if (character[i].character) { + var characterPack = lib.characterPack[i]; + if (characterPack) Object.assign(characterPack, character[i].character); + else lib.characterPack[i] = character[i].character; + } + if (character[i].forbid && character[i].forbid.includes(lib.config.mode)) continue; + if (character[i].mode && character[i].mode.includes(lib.config.mode) == false) continue; + + if (Array.isArray(lib[j]) && Array.isArray(character[i][j])) { + lib[j].addArray(character[i][j]); + continue; + } + for (j in character[i]) { + if (j == "mode" || j == "forbid" || j == "characterSort") continue; + for (k in character[i][j]) { + if (j == "character") { + if (!character[i][j][k][4]) { + character[i][j][k][4] = []; + } + if ( + character[i][j][k][4].includes("boss") || + character[i][j][k][4].includes("hiddenboss") + ) { + lib.config.forbidai.add(k); + } + if (lib.config.forbidai_user && lib.config.forbidai_user.includes(k)) { + lib.config.forbidai.add(k); + } + for (var l = 0; l < character[i][j][k][3].length; l++) { + lib.skilllist.add(character[i][j][k][3][l]); + } + } + if (j == "translate" && k == i) { + lib[j][k + "_character_config"] = character[i][j][k]; + } else { + if (lib[j][k] == undefined) { + Object.defineProperty( + lib[j], + k, + Object.getOwnPropertyDescriptor(character[i][j], k) + ); + } else if (Array.isArray(lib[j][k]) && Array.isArray(character[i][j][k])) { + lib[j][k].addArray(character[i][j][k]); + } else { + console.log( + `dublicate ${j} in character ${i}:\n${k}:\nlib.${j}.${k}`, + lib[j][k], + `\ncharacter.${i}.${j}.${k}`, + character[i][j][k] + ); + } + } + } + } + } + for (i in card) { + var cardPack = lib.cardPack[i] ? lib.cardPack[i] : (lib.cardPack[i] = []); + if (card[i].card) { + for (var j in card[i].card) { + if (!card[i].card[j].hidden && card[i].translate[j + "_info"]) { + cardPack.push(j); + } + } + } + for (j in card[i]) { + if (j == "mode" || j == "forbid") continue; + if (j == "list") continue; + for (k in card[i][j]) { + if (j == "skill" && k[0] == "_" && !lib.config.cards.includes(i)) { + continue; + } + if (j == "translate" && k == i) { + lib[j][k + "_card_config"] = card[i][j][k]; + } else { + if (lib[j][k] == undefined) + Object.defineProperty(lib[j], k, Object.getOwnPropertyDescriptor(card[i][j], k)); + else { + console.log( + `dublicate ${j} in card ${i}:\n${k}\nlib.${j}.${k}`, + lib[j][k], + `\ncard.${i}.${j}.${k}`, + card[i][j][k] + ); + } + } + } + } + } + event.goto(0); + }, + loadMode: function () { + "step 0"; + window.game = game; + lib.init.js(lib.assetURL + "mode", event.mode, game.resume); + game.pause(); + "step 1"; + if (!lib.config.dev) delete window.game; + event.result = lib.imported.mode[event.mode]; + delete lib.imported.mode[event.mode]; + }, + forceOver: function () { + "step 0"; + while (ui.controls.length) { + ui.controls[0].close(); + } + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + "step 1"; + if (event.bool != "noover") { + game.over(event.bool); + } + if (event.callback) { + event.callback(); + } + }, + arrangeTrigger: async function (event, trigger, player) { + const doingList = event.doingList.slice(0); + + while (doingList.length > 0) { + event.doing = doingList.shift(); + while (true) { + if (trigger.filterStop && trigger.filterStop()) return; + const usableSkills = event.doing.todoList.filter((info) => { + return lib.filter.filterTrigger( + trigger, + info.player, + event.triggername, + info.skill, + info.indexedData + ); + }); + if (usableSkills.length == 0) { + break; + } else { + event.doing.todoList = event.doing.todoList.filter( + (i) => i.priority <= usableSkills[0].priority + ); + //firstDo时机和lastDo时机不进行技能优先级选择 + if (get.itemtype(event.doing.player) !== "player") { + event.current = usableSkills[0]; + } else { + event.choice = usableSkills.filter((n) => n.priority == usableSkills[0].priority); + //现在只要找到一个同优先度技能为silent,或没有技能描述的技能 便优先执行该技能 + const silentSkill = event.choice.find((item) => { + const skillInfo = lib.skill[item.skill]; + return skillInfo && (skillInfo.silent || !lib.translate[item.skill]); + }); + if (silentSkill) { + event.current = silentSkill; + } else { + const currentChoice = event.choice[0], + skillsToChoose = event.choice.map((i) => i.skill).unique(); + if (event.choice.length === 1 || skillsToChoose.length === 1) { + event.current = currentChoice; + } else { + const currentPlayer = currentChoice.player; + const next = currentPlayer.chooseControl(skillsToChoose); + next.set("prompt", "选择下一个触发的技能"); + next.set("forceDie", true); + next.set("arrangeSkill", true); + next.set("includeOut", true); + const { result } = await next; + event.current = usableSkills.find((info) => info.skill == result.control); + } + } + } + event.doing.doneList.push(event.current); + event.doing.todoList.remove(event.current); + const result = await game + .createTrigger( + event.triggername, + event.current.skill, + event.current.player, + trigger, + event.current.indexedData + ) + .forResult(); + if (get.itemtype(event.doing.player) === "player" && result === "cancelled") { + for (let i = 0; i < event.doing.todoList.length; i++) { + if (event.current.skill === event.doing.todoList[i].skill) { + event.doing.doneList.push(event.doing.todoList.splice(i--, 1)[0]); + } + } + } + } + } + } + }, + createTrigger: function () { + "step 0"; + // console.log('triggering: ' + player.name+ ' \'s skill: ' + event.skill+' in ' + event.triggername) + if (game.expandSkills(player.getSkills().concat(lib.skill.global)).includes(event.skill)) return; + var info = get.info(event.skill); + let hidden = player.hiddenSkills.slice(0); + let invisible = player.invisibleSkills.slice(0); + game.expandSkills(hidden); + game.expandSkills(invisible); + if (hidden.includes(event.skill)) { + if (!info.silent && player.hasSkillTag("nomingzhi", false, null, true)) event.finish(); + else if (!info.direct && typeof info.cost !== "function") event.trigger("triggerHidden"); + else event.skillHidden = true; + } else if (invisible.includes(event.skill)) event.trigger("triggerInvisible"); + else if ( + Object.keys(player.additionalSkills).every((i) => { + if (i.startsWith("hidden:")) return true; + return !game.expandSkills(player.additionalSkills[i]).includes(event.skill); + }) + ) + event.finish(); + "step 1"; + if (event.cancelled) return event.finish(); + var info = get.info(event.skill); + if (event.revealed || info.forced) { + event._result = { bool: true }; + return; + } + const checkFrequent = function (info) { + if (player.hasSkillTag("nofrequent", false, event.skill)) return false; + if (typeof info.frequent == "boolean") return info.frequent; + if (typeof info.frequent == "function") return info.frequent(trigger, player); + if (info.frequent == "check" && typeof info.check == "function") + return info.check(trigger, player); + return false; + }; + if (info.direct) { + if (player.isUnderControl()) game.swapPlayerAuto(player); + if (player.isOnline()) void 0; + event._result = { bool: true }; + event._direct = true; + } else if (typeof info.cost === "function") { + if (checkFrequent(info)) event.frequentSkill = true; + if (player.isUnderControl()) game.swapPlayerAuto(player); + //创建cost事件 + var next = game.createEvent(`${event.skill}_cost`); + next.player = player; + if (event.frequentSkill) next.set("frequentSkill", event.skill); + next.set("forceDie", true); + next.set("includeOut", true); + next._trigger = trigger; + next.triggername = event.triggername; + next.skillHidden = event.skillHidden; + next.indexedData = event.indexedData; + if (info.forceDie) next.forceDie = true; + if (info.forceOut) next.includeOut = true; + next.skill = event.skill; + next.setContent(info.cost); + } else { + if (checkFrequent(info)) event.frequentSkill = true; + var str; + var check = info.check; + if (info.prompt) str = info.prompt; + else if (typeof info.logTarget == "string") + str = get.prompt(event.skill, trigger[info.logTarget], player); + else if (typeof info.logTarget == "function") { + const logTarget = info.logTarget(trigger, player, event.triggername, event.indexedData); + if (get.itemtype(logTarget).startsWith("player")) + str = get.prompt(event.skill, logTarget, player); + } else str = get.prompt(event.skill, null, player); + if (typeof str == "function") str = str(trigger, player, event.triggername, event.indexedData); + + var next = player.chooseBool(str); + if (event.frequentSkill) next.set("frequentSkill", event.skill); + next.set("forceDie", true); + next.set("includeOut", true); + next.ai = () => !check || check(trigger, player, event.triggername, event.indexedData); + + if (typeof info.prompt2 == "function") + next.set("prompt2", info.prompt2(trigger, player, event.triggername, event.indexedData)); + else if (typeof info.prompt2 == "string") next.set("prompt2", info.prompt2); + else if (info.prompt2 != false) { + if (lib.dynamicTranslate[event.skill]) + next.set("prompt2", lib.dynamicTranslate[event.skill](player, event.skill)); + else if (lib.translate[event.skill + "_info"]) + next.set("prompt2", lib.translate[event.skill + "_info"]); + } + + if (trigger.skillwarn) { + if (next.prompt2) + next.set( + "prompt2", + '' + trigger.skillwarn + "。" + next.prompt2 + ); + else next.set("prompt2", trigger.skillwarn); + } + } + "step 2"; + var info = get.info(event.skill); + if (result && result.control) result.bool = !result.control.includes("cancel"); + if (!result || !result.bool) return; + var autodelay = info.autodelay; + if (typeof autodelay == "function") autodelay = autodelay(trigger, player); + if (autodelay && (info.forced || !event.isMine())) { + if (typeof autodelay == "number") game.delayx(autodelay); + else game.delayx(); + } + "step 3"; + var info = get.info(event.skill); + if (!result || !result.bool) { + if (info.oncancel) info.oncancel(trigger, player); + if (event.indexedData === true) { + event.result = "cancelled"; + } + return event.finish(); + } + let targets = null; + if (result.targets && result.targets.length > 0) { + targets = result.targets.slice(0); + } else if (info.logTarget) { + if (typeof info.logTarget === "string") targets = trigger[info.logTarget]; + else if (typeof info.logTarget === "function") + targets = info.logTarget(trigger, player, event.triggername, event.indexedData); + } + if (get.itemtype(targets) === "player") { + targets = [targets]; + } + if (info.popup != false && !info.direct) { + let popup_info = event.skill; + if (typeof info.popup === "string") popup_info = [event.skill, info.popup]; + if (info.logLine === false) player.logSkill(popup_info, false, info.line); + else player.logSkill(popup_info, targets, info.line); + } + var next = game.createEvent(event.skill); + if (typeof info.usable == "number") { + player.addSkill("counttrigger"); + if (!player.storage.counttrigger) player.storage.counttrigger = {}; + if (!player.storage.counttrigger[event.skill]) player.storage.counttrigger[event.skill] = 1; + else player.storage.counttrigger[event.skill]++; + } + next.player = player; + next._trigger = trigger; + next.triggername = event.triggername; + // if ("contents" in info && Array.isArray(info.contents)) { + // next.setContents(info.contents); + // } else { + next.setContent(info.content); + // } + + next.skillHidden = event.skillHidden; + if (info.forceDie) next.forceDie = true; + if (info.forceOut) next.includeOut = true; + //传入数据 + if (get.itemtype(targets) == "players") next.targets = targets.slice(0); + if (get.itemtype(result.cards) === "cards") next.cards = result.cards.slice(0); + //语法糖部分 + if ("cost_data" in result) next.cost_data = result.cost_data; + next.indexedData = event.indexedData; + "step 4"; + if (!player._hookTrigger) return; + if ( + player._hookTrigger.some((i) => { + const info = lib.skill[i].hookTrigger; + return info && info.after && info.after(event, player, event.triggername); + }) + ) + event.trigger("triggerAfter"); + }, + playVideoContent: function () { + "step 0"; + game.delay(0, 500); + "step 1"; + if (!game.chess) { + ui.control.innerHTML = ""; + var nodes = []; + for (var i = 0; i < ui.arena.childNodes.length; i++) { + nodes.push(ui.arena.childNodes[i]); + } + for (var i = 0; i < nodes.length; i++) { + if (nodes[i] == ui.canvas) continue; + if (nodes[i] == ui.control) continue; + if (nodes[i] == ui.mebg) continue; + if (nodes[i] == ui.me) continue; + if (nodes[i] == ui.roundmenu) continue; + nodes[i].remove(); + } + ui.sidebar.innerHTML = ""; + ui.cardPile.innerHTML = ""; + ui.discardPile.innerHTML = ""; + ui.special.innerHTML = ""; + ui.ordering.innerHTML = ""; + } + ui.system.firstChild.innerHTML = ""; + ui.system.lastChild.innerHTML = ""; + ui.system.firstChild.appendChild(ui.config2); + if (ui.updateVideoMenu) { + ui.updateVideoMenu(); + } + _status.videoDuration = 1; + ui.create.system("返回", function () { + var mode = localStorage.getItem(lib.configprefix + "playbackmode"); + if (mode) { + game.saveConfig("mode", mode); + } + game.reload(); + }); + ui.create.system("重播", function () { + _status.replayvideo = true; + game.playVideo(_status.playback, lib.config.mode); + }); + ui.create.system("暂停", ui.click.pause, true).id = "pausebutton"; + var slow = ui.create.system( + "减速", + function () { + _status.videoDuration *= 1.5; + updateDuration(); + }, + true + ); + var fast = ui.create.system( + "加速", + function () { + _status.videoDuration /= 1.5; + updateDuration(); + }, + true + ); + var updateDuration = function () { + if (_status.videoDuration > 1) { + slow.classList.add("glow"); + } else { + slow.classList.remove("glow"); + } + if (_status.videoDuration < 1) { + fast.classList.add("glow"); + } else { + fast.classList.remove("glow"); + } + }; + ui.system.style.display = ""; + ui.refresh(ui.system); + ui.system.show(); + ui.window.show(); + if (lib.config.mode != "versus" && lib.config.mode != "boss") { + ui.arena.style.display = ""; + ui.refresh(ui.arena); + ui.arena.show(); + } + if (!game.chess) { + game.playerMap = {}; + } + game.finishCards(); + "step 2"; + if (event.video.length) { + var content = event.video.shift(); + // console.log(content); + if (content.type == "delay") { + game.delay(content.content); + } else if (content.type == "play") { + window.play = {}; + if (!event.playtoload) { + event.playtoload = 1; + } else { + event.playtoload++; + } + var script = lib.init.js(lib.assetURL + "play", content.name); + script.addEventListener("load", function () { + var play = window.play[content.name]; + if (play && play.video) { + play.video(content.init); + } + event.playtoload--; + if (event.playtoload == 0) { + delete window.play; + } + }); + } else if ( + typeof content.player == "string" && + game.playerMap[content.player] && + game.playerMap[content.player].classList && + !game.playerMap[content.player].classList.contains("obstacle") + ) { + game.videoContent[content.type](game.playerMap[content.player], content.content); + } else { + game.videoContent[content.type](content.content); + } + if (event.video.length) { + game.delay(0, _status.videoDuration * Math.min(2000, event.video[0].delay)); + } + event.redo(); + } else { + _status.over = true; + ui.system.lastChild.hide(); + setTimeout(function () { + ui.system.lastChild.innerHTML = ""; + }, 500); + } + }, + waitForPlayer: function () { + "step 0"; + ui.auto.hide(); + ui.pause.hide(); + + game.createServer(); + if (!lib.translate.zhu) { + lib.translate.zhu = "主"; + } + if (event.func) { + event.func(); + } + if (!lib.configOL.number) { + lib.configOL.number = parseInt(lib.configOL.player_number); + } + if (game.onlineroom) { + game.send("server", "config", lib.configOL); + } + + ui.create.connectPlayers(game.ip); + if (!window.isNonameServer) { + var me = game.connectPlayers[0]; + me.setIdentity("zhu"); + me.initOL(get.connectNickname(), lib.config.connect_avatar); + me.playerid = "1"; + game.onlinezhu = "1"; + } + _status.waitingForPlayer = true; + if (window.isNonameServer) { + document.querySelector("#server_status").innerHTML = "等待中"; + } + game.pause(); + "step 1"; + _status.waitingForPlayer = false; + lib.configOL.gameStarted = true; + if (window.isNonameServer) { + document.querySelector("#server_status").innerHTML = "游戏中"; + } + if (game.onlineroom) { + game.send("server", "config", lib.configOL); + } + for (var i = 0; i < game.connectPlayers.length; i++) { + game.connectPlayers[i].delete(); + } + delete game.connectPlayers; + if (ui.roomInfo) { + ui.roomInfo.remove(); + delete ui.roomInfo; + } + if (ui.exitroom) { + ui.exitroom.remove(); + delete ui.exitroom; + } + game.broadcast("gameStart"); + game.delay(2); + ui.auto.show(); + ui.pause.show(); + if (lib.config.show_cardpile) { + ui.cardPileButton.style.display = ""; + } + }, + replaceHandcards: function () { + "step 0"; + if (event.players.includes(game.me)) { + game.me.chooseBool("是否置换手牌?"); + } else { + event.finish(); + } + "step 1"; + if (result && result.bool) { + var hs = game.me.getCards("h"); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + var cards = get.cards(hs.length); + game.me._start_cards = cards; + game.me.directgain(cards); + } + }, + replaceHandcardsOL: function () { + "step 0"; + var send = function () { + game.me.chooseBool("是否置换手牌?"); + game.resume(); + }; + var sendback = function (result, player) { + if (result && result.bool) { + var hs = player.getCards("h"); + game.broadcastAll( + function (player, hs) { + game.addVideo("lose", player, [get.cardsInfo(hs), [], [], []]); + for (var i = 0; i < hs.length; i++) { + hs[i].discard(false); + } + }, + player, + hs + ); + var cards = get.cards(hs.length); + player.directgain(cards); + player._start_cards = cards; + } + }; + for (var i = 0; i < event.players.length; i++) { + if (event.players[i].isOnline()) { + event.withol = true; + event.players[i].send(send); + event.players[i].wait(sendback); + } else if (event.players[i] == game.me) { + event.withme = true; + game.me.chooseBool("是否置换手牌?"); + game.me.wait(sendback); + } + } + "step 1"; + if (event.withme) { + game.me.unwait(result); + } + "step 2"; + if (event.withol && !event.resultOL) { + game.pause(); + } + }, + /** + * @deprecated + */ + phase: function () { + "step 0"; + //规则集中的“回合开始后③(处理“游戏开始时”的时机)” + //提前phaseBefore时机解决“游戏开始时”时机和“一轮开始时”先后 + event.trigger("phaseBefore"); + "step 1"; + //初始化阶段列表 + if (!event.phaseList) { + event.phaseList = [ + "phaseZhunbei", + "phaseJudge", + "phaseDraw", + "phaseUse", + "phaseDiscard", + "phaseJieshu", + ]; + } + if (typeof event.num != "number") { + event.num = 0; + } + //规则集中的“回合开始后①”,更新游戏轮数,触发“一轮游戏开始时” + var isRound = false; + if (!event.skill) { + isRound = _status.roundSkipped; + if (_status.isRoundFilter) { + isRound = _status.isRoundFilter(event, player); + } else if (_status.seatNumSettled) { + var seatNum = player.getSeatNum(); + if (seatNum != 0) { + if ( + get.itemtype(_status.lastPhasedPlayer) != "player" || + seatNum < _status.lastPhasedPlayer.getSeatNum() + ) + isRound = true; + _status.lastPhasedPlayer = player; + } + } else if (player == _status.roundStart) isRound = true; + if (isRound) { + delete _status.roundSkipped; + game.roundNumber++; + event._roundStart = true; + game.updateRoundNumber(); + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isOut() && game.players[i].outCount > 0) { + game.players[i].outCount--; + if (game.players[i].outCount == 0 && !game.players[i].outSkills) { + game.players[i].in(); + } + } + } + event.trigger("roundStart"); + } + } + _status.globalHistory.push({ + cardMove: [], + custom: [], + useCard: [], + changeHp: [], + everything: [], + }); + var players = game.players.slice(0).concat(game.dead); + for (var i = 0; i < players.length; i++) { + var current = players[i]; + current.actionHistory.push({ + useCard: [], + respond: [], + skipped: [], + lose: [], + gain: [], + sourceDamage: [], + damage: [], + custom: [], + useSkill: [], + }); + current.stat.push({ card: {}, skill: {} }); + if (isRound) { + current.getHistory().isRound = true; + current.getStat().isRound = true; + } + } + if (isRound) { + game.getGlobalHistory().isRound = true; + } + "step 2"; + //规则集中的“回合开始后②(1v1武将登场专用)” + event.trigger("phaseBeforeStart"); + "step 3"; + //规则集中的“回合开始后④(卑弥呼〖纵傀〗的时机)” + event.trigger("phaseBeforeEnd"); + "step 4"; + //规则集中的“回合开始后⑤”,进行翻面检测 + if (player.isTurnedOver() && !event._noTurnOver) { + event.cancel(); + player.turnOver(); + player.phaseSkipped = true; + var players = game.players.slice(0).concat(game.dead); + for (var i = 0; i < players.length; i++) { + var current = players[i]; + current.getHistory().isSkipped = true; + current.getStat().isSkipped = true; + } + } else { + player.phaseSkipped = false; + player.getHistory().isMe = true; + player.getStat().isMe = true; + } + "step 5"; + //规则集中的“回合开始后⑥”,更新“当前回合角色” + while (ui.dialogs.length) { + ui.dialogs[0].close(); + } + game.phaseNumber++; + player.phaseNumber++; + game.broadcastAll( + function (player, num, popup) { + if (lib.config.glow_phase) { + player.classList.add("glow_phase"); + } + player.phaseNumber = num; + _status.currentPhase = player; + if (popup && lib.config.show_phase_prompt) player.popup("回合开始", null, false); + }, + player, + player.phaseNumber, + !player.noPhaseDelay + ); + _status.currentPhase = player; + _status.discarded = []; + game.syncState(); + game.addVideo("phaseChange", player); + if (game.phaseNumber == 1) { + delete player._start_cards; + if (lib.configOL.observe) { + lib.configOL.observeReady = true; + game.send("server", "config", lib.configOL); + } + } + game.log(); + game.log(player, "的回合开始"); + player._noVibrate = true; + if ( + get.config("identity_mode") != "zhong" && + get.config("identity_mode") != "purple" && + !_status.connectMode + ) { + var num; + switch (get.config("auto_identity")) { + case "one": + num = 1; + break; + case "two": + num = 2; + break; + case "three": + num = 3; + break; + case "always": + num = -1; + break; + default: + num = 0; + break; + } + if ( + num && + !_status.identityShown && + game.phaseNumber > game.players.length * num && + game.showIdentity + ) { + if (!_status.video) player.popup("显示身份"); + _status.identityShown = true; + game.showIdentity(false); + } + } + player.ai.tempIgnore = []; + if (ui.land && ui.land.player == player) { + game.addVideo("destroyLand"); + ui.land.destroy(); + } + "step 6"; + //规则集中的“回合开始后⑦”,国战武将明置武将牌 + event.trigger("phaseBeginStart"); + "step 7"; + //规则集中的“回合开始后⑨”,进行当先,化身等操作 + //没有⑧ 因为⑧用不到 + event.trigger("phaseBegin"); + //阶段部分 + "step 8"; + if (num < event.phaseList.length) { + //规则集中没有的新时机 可以用来插入额外阶段啥的 + if (player.isIn()) event.trigger("phaseChange"); + } else event.goto(11); + "step 9"; + if (player.isIn() && num < event.phaseList.length) { + var phase = event.phaseList[num].split("|"); + event.currentPhase = phase[0]; + var next = player[event.currentPhase](); + next.phaseIndex = num; + if (phase.length > 1) { + next._extraPhaseReason = phase[1]; + } + if (event.currentPhase == "phaseDraw" || event.currentPhase == "phaseDiscard") { + if (!player.noPhaseDelay) { + if (player == game.me) { + game.delay(); + } else { + game.delayx(); + } + } + } + } + "step 10"; + if (event.currentPhase == "phaseUse") { + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + delete player._noSkill; + } + event.num++; + "step 11"; + if (event.num < event.phaseList.length) { + event.goto(8); + } else if (!event._phaseEndTriggered) { + event._phaseEndTriggered = true; + event.trigger("phaseEnd"); + event.redo(); + } + "step 12"; + event.trigger("phaseAfter"); + "step 13"; + //删除当前回合角色 此时处于“不属于任何角色的回合”的阶段 + game.broadcastAll(function (player) { + player.classList.remove("glow_phase"); + delete _status.currentPhase; + }, player); + }, + /** + * @deprecated + */ + phase_old: function () { + "step 0"; + player.phaseZhunbei(); + "step 1"; + player.phaseJudge(); + "step 2"; + player.phaseDraw(); + if (!player.noPhaseDelay) { + if (player == game.me) { + game.delay(); + } else { + game.delayx(); + } + } + "step 3"; + player.phaseUse(); + "step 4"; + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + player.phaseDiscard(); + if (!player.noPhaseDelay) game.delayx(); + //delete player.using; + delete player._noSkill; + "step 5"; + player.phaseJieshu(); + }, + phaseZhunbei: function () { + event.trigger(event.name); + game.log(player, "进入了准备阶段"); + }, + phaseJudge: function () { + "step 0"; + game.log(player, "进入了判定阶段"); + event.cards = player.getCards("j"); + if (!event.cards.length) event.finish(); + "step 1"; + if (cards.length) { + event.card = cards.shift(); + var cardName = event.card.viewAs || event.card.name, + cardInfo = lib.card[cardName]; + if (event.card.classList.contains("removing")) { + event.card.remove(); + delete event.card; + event.redo(); + } else if (event.card.classList.contains("feichu")) { + event.finish(); + return; + } else if (cardInfo.noEffect || !player.getCards("j").includes(event.card)) { + event.redo(); + } else { + player.lose(event.card, "visible", ui.ordering); + player.$phaseJudge(event.card); + event.cancelled = false; + event.trigger("phaseJudge"); + player.popup(cardName, "thunder"); + if (!cardInfo.effect) { + game.delay(); + event.redo(); + } else if (!cardInfo.judge) { + game.delay(); + event.nojudge = true; + } else { + event.nojudge = false; + } + } + } else event.finish(); + "step 2"; + if (!event.cancelled && !event.nojudge) player.judge(event.card).set("type", "phase"); + "step 3"; + var name = event.card.viewAs || event.card.name; + if (event.excluded) { + delete event.excluded; + } else if (event.cancelled && !event.direct) { + if (lib.card[name].cancel) { + var next = game.createEvent(name + "Cancel"); + next.setContent(lib.card[name].cancel); + next.cards = [event.card]; + if (!event.card.viewAs) next.card = get.autoViewAs(event.card); + else next.card = get.autoViewAs({ name: name }, next.cards); + next.player = player; + } + } else { + var next = game.createEvent(name); + next.setContent(lib.card[name].effect); + next._result = result; + next.cards = [event.card]; + if (!event.card.viewAs) next.card = get.autoViewAs(event.card); + else next.card = get.autoViewAs({ name: name }, next.cards); + next.player = player; + } + ui.clear(); + event.goto(1); + }, + /** + * @deprecated + */ + phaseDraw: function () { + "step 0"; + game.log(player, "进入了摸牌阶段"); + event.trigger("phaseDrawBegin1"); + "step 1"; + event.trigger("phaseDrawBegin2"); + "step 2"; + if (game.modPhaseDraw) { + game.modPhaseDraw(player, event.num); + } else { + if (event.num > 0) { + var num = event.num; + if (event.attachDraw) { + for (var i = 0; i < event.attachDraw.length; i++) { + ui.cardPile.insertBefore(event.attachDraw[i], ui.cardPile.firstChild); + } + num += event.attachDraw.length; + } + var next = player.draw(num); + if (event.attachDraw) { + next.minnum = event.attachDraw.length; + } + } + } + "step 3"; + if (Array.isArray(result)) { + event.cards = result; + } + }, + phaseUse: function () { + "step 0"; + const stat = player.getStat(); + for (let i in stat.skill) { + let bool = false; + const info = lib.skill[i]; + if (!info) continue; + if (info.enable != undefined) { + if (typeof info.enable == "string" && info.enable == "phaseUse") bool = true; + else if (typeof info.enable == "object" && info.enable.includes("phaseUse")) bool = true; + } + if (bool) stat.skill[i] = 0; + } + for (let i in stat.card) { + let bool = false; + const info = lib.card[i]; + if (!info) continue; + if (info.updateUsable == "phaseUse") stat.card[i] = 0; + } + "step 1"; + event.trigger("phaseUseBefore"); + "step 2"; + event.trigger("phaseUseBegin"); + "step 3"; + if (!event.logged) { + game.log(player, "进入了出牌阶段"); + event.logged = true; + } + var next = player.chooseToUse(); + if (!lib.config.show_phaseuse_prompt) { + next.set("prompt", false); + } + next.set("type", "phase"); + "step 4"; + if (result.bool && !event.skipped) { + event.goto(3); + } + game.broadcastAll(function () { + if (ui.tempnowuxie) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }); + "step 5"; + event.trigger("phaseUseEnd"); + "step 6"; + event.trigger("phaseUseAfter"); + }, + phaseDiscard: function () { + "step 0"; + game.log(player, "进入了弃牌阶段"); + event.num = player.needsToDiscard(); + if (event.num <= 0) event.finish(); + else { + game.broadcastAll(function (player) { + if (lib.config.show_phase_prompt) { + player.popup("弃牌阶段", null, false); + } + }, player); + } + event.trigger("phaseDiscard"); + "step 1"; + player.chooseToDiscard(num, true).set("useCache", true); + "step 2"; + event.cards = result.cards; + }, + phaseJieshu: function () { + event.trigger(event.name); + game.log(player, "进入了结束阶段"); + }, + chooseToUse: function () { + "step 0"; + if (event.responded) return; + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl() && !lib.filter.wuxieSwap(event)) { + game.modeSwapPlayer(player); + } + var skills = player.getSkills("invisible").concat(lib.skill.global); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.onChooseToUse) { + info.onChooseToUse(event); + } + } + if (_status.noclearcountdown !== "direct") _status.noclearcountdown = true; + if (event.type == "phase") { + if (event.isMine()) { + event.endButton = ui.create.control("结束回合", "stayleft", function () { + var evt = _status.event; + if (evt.name != "chooseToUse" || evt.type != "phase") return; + if (evt.skill) { + ui.click.cancel(); + } + ui.click.cancel(); + }); + event.fakeforce = true; + } else { + if (event.endButton) { + event.endButton.close(); + delete event.endButton; + } + event.fakeforce = false; + } + } + if (event.player.isUnderControl() && !_status.auto) { + event.result = { + bool: false, + }; + return; + } else if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + if (event.type == "wuxie") { + if (ui.tempnowuxie) { + var triggerevent = event.getTrigger(); + if ( + triggerevent && + triggerevent.targets && + triggerevent.num == triggerevent.targets.length - 1 + ) { + ui.tempnowuxie.close(); + } + } + if (lib.filter.wuxieSwap(event)) { + event.result = { + bool: false, + }; + return; + } + } + var ok = game.check(); + if (!ok || !lib.config.auto_confirm) { + game.pause(); + if (lib.config.enable_vibrate && player._noVibrate) { + delete player._noVibrate; + game.vibrate(); + } + if (typeof event.prompt == "string") { + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = event.prompt; + } else { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + } + } else if (typeof event.prompt == "function") { + event.dialog = ui.create.dialog(event.prompt(event)); + } else if (event.prompt == undefined) { + var str; + if (typeof event.filterCard == "object") { + var filter = event.filterCard; + str = "请使用" + get.cnNumber(event.selectCard[0]) + "张"; + if (filter.name) { + str += get.translation(filter.name); + } else { + str += "牌"; + } + } else { + str = "请选择要使用的牌"; + } + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = str; + } else if (typeof event.skillDialog != "string") { + event.dialog = ui.create.dialog(str); + } else { + event.dialog = str; + } + } + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + var ok = game.check(); + if (ok) { + ui.click.ok(); + } else if (ai.basic.chooseCard(event.ai1) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + event._aiexcludeclear = true; + } else { + if (!event.norestore) { + if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + } else { + get.card(true).aiexclude(); + game.uncheck(); + } + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + } + } else if (event.skill && !event.norestore) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + if (event.aidelay && event.result && event.result.bool) { + game.delayx(); + } + } + "step 2"; + if (event.endButton) { + event.endButton.close(); + delete event.endButton; + } + event.resume(); + if (event.result) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + if (event.result.skill) { + var info = get.info(event.result.skill); + if (info && info.chooseButton) { + if (event.dialog && typeof event.dialog == "object") event.dialog.close(); + var dialog = info.chooseButton.dialog(event, player); + if (info.chooseButton.chooseControl) { + var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.dialog = dialog; + next.set( + "ai", + info.chooseButton.check || + function () { + return 0; + } + ); + if (event.id) next._parent_id = event.id; + next.type = "chooseToUse_button"; + } else { + var next = player.chooseButton(dialog); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.set( + "ai", + info.chooseButton.check || + function () { + return 1; + } + ); + next.set( + "filterButton", + info.chooseButton.filter || + function () { + return true; + } + ); + next.set("selectButton", info.chooseButton.select || 1); + next.set("complexSelect", info.chooseButton.complexSelect !== false); + next.set("filterOk", info.chooseButton.filterOk || (() => true)); + if (event.id) next._parent_id = event.id; + next.type = "chooseToUse_button"; + } + event.buttoned = event.result.skill; + } else if (info && info.precontent && !game.online && !event.nouse) { + var next = game.createEvent("pre_" + event.result.skill); + next.setContent(info.precontent); + next.set("result", event.result); + next.set("player", player); + } + } + } + "step 3"; + if (event.buttoned) { + if (result.bool || (result.control && result.control != "cancel2")) { + var info = get.info(event.buttoned).chooseButton; + lib.skill[event.buttoned + "_backup"] = info.backup( + info.chooseControl ? result : result.links, + player + ); + lib.skill[event.buttoned + "_backup"].sourceSkill = event.buttoned; + if (game.online) { + event._sendskill = [event.buttoned + "_backup", lib.skill[event.buttoned + "_backup"]]; + } else { + game.broadcast( + (skill, audio) => { + if (!lib.skill[skill]) lib.skill[skill] = {}; + lib.skill[skill].audio = audio; + }, + event.buttoned + "_backup", + lib.skill[event.buttoned + "_backup"].audio + ); + } + event.backup(event.buttoned + "_backup"); + if (info.prompt) { + event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); + } + } else { + ui.control.addTempClass("nozoom", 100); + event._aiexclude.add(event.buttoned); + } + event.goto(0); + delete event.buttoned; + } + "step 4"; + if (event._aiexcludeclear) { + delete event._aiexcludeclear; + event._aiexclude.length = 0; + } + delete _status.noclearcountdown; + if (event.skillDialog && get.objtype(event.skillDialog) == "div") { + event.skillDialog.close(); + } + if (event.result && event.result.bool && !game.online && !event.nouse) { + player.useResult(event.result, event); + } else if (event._sendskill) { + event.result._sendskill = event._sendskill; + } + if ( + (!event.result || !event.result.bool || event.result._noHidingTimer) && + (event.result.skill || event.logSkill) + ) { + var info = get.info( + event.result.skill || (Array.isArray(event.logSkill) ? event.logSkill[0] : event.logSkill) + ); + if (info.direct && !info.clearTime) { + _status.noclearcountdown = "direct"; + } + } + if (event.dialog && typeof event.dialog == "object") event.dialog.close(); + if (!_status.noclearcountdown) { + game.stopCountChoose(); + } + "step 5"; + if (event._result && event.result) { + event.result.result = event._result; + } + }, + chooseToRespond: function () { + "step 0"; + if (event.responded) { + delete event.dialog; + return; + } + var skills = player.getSkills("invisible").concat(lib.skill.global); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.onChooseToRespond) { + info.onChooseToRespond(event); + } + } + if (_status.noclearcountdown !== "direct") _status.noclearcountdown = true; + if (!_status.connectMode && lib.config.skip_shan && event.autochoose && event.autochoose()) { + event.result = { bool: false }; + } else { + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { + game.modeSwapPlayer(player); + } + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + var ok = game.check(); + if (!ok || !lib.config.auto_confirm) { + game.pause(); + if (event.openskilldialog) { + event.skillDialog = ui.create.dialog(event.openskilldialog); + delete event.openskilldialog; + event.dialog = event.prompt; + } else { + if (event.prompt) event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) event.dialog.addText(event.prompt2); + } + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + var ok = game.check(); + if (ok) { + ui.click.ok(); + } else if (ai.basic.chooseCard(event.ai1 || event.ai) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + event._aiexcludeclear = true; + } else { + if (!event.norestore) { + if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + } else { + get.card(true).aiexclude(); + game.uncheck(); + } + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + } + } else if (event.skill && !event.norestore) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + var info = get.info(skill); + if (info.sourceSkill) { + event._aiexclude.add(info.sourceSkill); + } + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + if (event.aidelay && event.result && event.result.bool) { + game.delayx(); + } + } + "step 2"; + event.resume(); + if (event.result) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + if (event.result.skill) { + var info = get.info(event.result.skill); + if (info && info.chooseButton) { + if (event.dialog && typeof event.dialog == "object") event.dialog.close(); + var dialog = info.chooseButton.dialog(event, player); + if (info.chooseButton.chooseControl) { + var next = player.chooseControl(info.chooseButton.chooseControl(event, player)); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.dialog = dialog; + next.set( + "ai", + info.chooseButton.check || + function () { + return 0; + } + ); + } else { + var next = player.chooseButton(dialog); + if (dialog.direct) next.direct = true; + if (dialog.forceDirect) next.forceDirect = true; + next.set( + "ai", + info.chooseButton.check || + function () { + return 1; + } + ); + next.set( + "filterButton", + info.chooseButton.filter || + function () { + return true; + } + ); + next.set("selectButton", info.chooseButton.select || 1); + next.set("filterOk", info.chooseButton.filterOk || (() => true)); + } + event.buttoned = event.result.skill; + } else if (info && info.precontent && !game.online) { + var next = game.createEvent("pre_" + event.result.skill); + next.setContent(info.precontent); + next.set("result", event.result); + next.set("player", player); + } + } + } + "step 3"; + if (event.buttoned) { + if (result.bool || (result.control && result.control != "cancel2")) { + var info = get.info(event.buttoned).chooseButton; + lib.skill[event.buttoned + "_backup"] = info.backup( + info.chooseControl ? result : result.links, + player + ); + lib.skill[event.buttoned + "_backup"].sourceSkill = event.buttoned; + if (game.online) { + event._sendskill = [event.buttoned + "_backup", lib.skill[event.buttoned + "_backup"]]; + } else { + game.broadcast( + (skill, audio) => { + if (!lib.skill[skill]) lib.skill[skill] = {}; + lib.skill[skill].audio = audio; + }, + event.buttoned + "_backup", + lib.skill[event.buttoned + "_backup"].audio + ); + } + event.backup(event.buttoned + "_backup"); + if (info.prompt) { + event.openskilldialog = info.prompt(info.chooseControl ? result : result.links, player); + } + } else { + ui.control.addTempClass("nozoom", 100); + event._aiexclude.add(event.buttoned); + } + event.goto(0); + delete event.buttoned; + } + "step 4"; + delete _status.noclearcountdown; + if (event.skillDialog && get.objtype(event.skillDialog) == "div") { + event.skillDialog.close(); + } + if (event.result.bool && !game.online) { + if (event.result._sendskill) { + lib.skill[event.result._sendskill[0]] = event.result._sendskill[1]; + } + if (event.onresult) { + event.onresult(event.result); + } + if ( + (!event.result || !event.result.bool || event.result._noHidingTimer) && + (event.result.skill || event.logSkill) + ) { + var info = get.info( + event.result.skill || (Array.isArray(event.logSkill) ? event.logSkill[0] : event.logSkill) + ); + if (info.direct && !info.clearTime) { + _status.noclearcountdown = "direct"; + } + } + if (event.logSkill) { + if (typeof event.logSkill == "string") { + player.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (!event.result.card && event.result.skill) { + event.result.used = event.result.skill; + player.useSkill(event.result.skill, event.result.cards, event.result.targets); + } else { + if (info && info.prerespond) { + info.prerespond(event.result, player); + } + var next = player.respond( + event.result.cards, + event.result.card, + event.animate, + event.result.skill, + event.source + ); + if (event.result.noanimate) next.animate = false; + if (event.parent.card && event.parent.type == "card") { + next.set("respondTo", [event.parent.player, event.parent.card]); + } + if (event.noOrdering) next.noOrdering = true; + } + } else if (event._sendskill) { + event.result._sendskill = event._sendskill; + } + if (event.dialog && event.dialog.close) event.dialog.close(); + if (!_status.noclearcountdown) { + game.stopCountChoose(); + } + }, + chooseToGive: function () { + "step 0"; + event.result = { + bool: true, + confirm: "ok", + buttons: [], + links: [], + cards: [], + targets: [], + }; + event.filterCard = ((event) => { + const filterCard = event.filterCard; + return function (card, player) { + if (!lib.filter.canBeGained(card, this.target, player)) return false; + return filterCard.call(this, card, player); + }; + })(event); + if (event.directresult) { + event.result.cards = event.directresult.slice(0); + event.goto(2); + return; + } + const directFilter = + event.forced && + typeof event.filterOk != "function" && + typeof event.selectCard != "function" && + !event.complexCard; + const cards = directFilter + ? player + .getCards(event.position) + .filter( + (card) => + !card.classList.contains("uncheck") && + lib.filter.cardAiIncluded(card) && + event.filterCard(card, player) + ) + : []; + const range = get.select(event.selectCard); + if (directFilter && (range[0] >= cards.length || range[1] <= -1)) { + if (player.isOut()) event.result.cards = []; + else event.result.cards = cards; + } else if (event.isMine()) { + game.check(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.pause(); + if (range[1] > 1 && typeof event.selectCard != "function") { + event.aiChoose = ui.create.control("AI代选", function () { + ai.basic.chooseCard(event.ai); + if (_status.event.custom && _status.event.custom.add.card) { + _status.event.custom.add.card(); + } + ui.selected.cards.forEach((i) => i.updateTransform(true)); + }); + } + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + event.dialog.open(); + event.dialog.classList.add("noselect"); + } else if (event.prompt != false) { + let prompt; + if (typeof event.prompt == "string") prompt = event.prompt; + else { + let select; + if (range[0] == range[1]) select = get.cnNumber(range[0]); + else if (range[1] == Infinity) select = "至少" + get.cnNumber(range[0]); + else select = get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + const position = event.position == "h" ? "手" : event.position == "e" ? "装备" : ""; + prompt = `请交给${get.translation(target)}${select}张${position}牌`; + } + event.dialog = ui.create.dialog(prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.promptx)) { + event.promptx.forEach((i) => event.dialog.add(i)); + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add("0/" + get.numStr(event.selectCard[1], "card")); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + "/" + get.numStr(_status.event.selectCard[1], "card"); + }; + } + } else if (get.itemtype(event.dialog) == "dialog") { + event.dialog.style.display = ""; + event.dialog.open(); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } else if (event.skill) { + ui.click.cancel(); + event._aiexclude.add(event.skill); + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.aiChoose) event.aiChoose.close(); + if (event.glow_result && event.result.cards && !event.directresult) { + event.result.cards.forEach((i) => i.classList.add("glow")); + } + if (event.dialog) event.dialog.close(); + "step 3"; + if (event.result.bool && event.result.cards && !game.online) { + event.cards = event.result.cards.slice(0); + if (event.logSkill) { + if (Array.isArray(event.logSkill)) player.logSkill(...event.logSkill); + else player.logSkill(event.logSkill); + } + if (event.autodelay && !event.isMine()) { + if (typeof event.autodelay == "number") game.delayx(event.autodelay); + else game.delayx(); + } + } else event.finish(); + "step 4"; + if (event.boolline) player.line(target, "green"); + event.done = target.gain(event.cards, player); + event.done.giver = player; + if (event.delay !== false) event.done.animate = event.visibleMove ? "give" : "giveAuto"; + else { + target[event.visibleMove ? "$give" : "$giveAuto"](cards, player); + if (event.visibleMove) event.done.visible = true; + } + }, + chooseToDiscard: function () { + "step 0"; + if (event.autochoose()) { + event.result = { + bool: true, + autochoose: true, + cards: player.getCards(event.position), + rawcards: player.getCards(event.position), + }; + for (var i = 0; i < event.result.cards.length; i++) { + if (!lib.filter.cardDiscardable(event.result.cards[i], player, event)) { + event.result.cards.splice(i--, 1); + } + } + } else { + // &&!lib.filter.wuxieSwap(trigger) + if (game.modeSwapPlayer && !_status.auto && player.isUnderControl()) { + game.modeSwapPlayer(player); + } + event.rangecards = player.getCards(event.position); + for (var i = 0; i < event.rangecards.length; i++) { + if (lib.filter.cardDiscardable(event.rangecards[i], player, event)) { + event.rangecards.splice(i--, 1); + } else { + event.rangecards[i].uncheck("chooseToDiscard"); + } + } + var range = get.select(event.selectCard); + if (event.isMine()) { + game.check(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.pause(); + if (range[1] > 1 && typeof event.selectCard != "function") { + event.promptdiscard = ui.create.control("AI代选", function () { + ai.basic.chooseCard(event.ai); + if (_status.event.custom && _status.event.custom.add.card) { + _status.event.custom.add.card(); + } + for (var i = 0; i < ui.selected.cards.length; i++) { + ui.selected.cards[i].updateTransform(true); + } + }); + } + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + event.dialog.open(); + event.dialog.classList.add("noselect"); + } else if (event.prompt != false) { + var str; + if (typeof event.prompt == "string") str = event.prompt; + else { + str = "请弃置"; + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += "至少" + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + str += "张"; + if (event.position == "h" || event.position == undefined) str += "手"; + if (event.position == "e") str += "装备"; + str += "牌"; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add("0/" + get.numStr(event.selectCard[1], "card")); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + + "/" + + get.numStr(_status.event.selectCard[1], "card"); + }; + } + } else if (get.itemtype(event.dialog) == "dialog") { + event.dialog.style.display = ""; + event.dialog.open(); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } else if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + } + if (event.rangecards) { + for (var i = 0; i < event.rangecards.length; i++) { + event.rangecards[i].recheck("chooseToDiscard"); + } + } + "step 2"; + event.resume(); + if (event.promptdiscard) { + event.promptdiscard.close(); + } + "step 3"; + if ( + event.result.bool && + event.result.cards && + event.result.cards.length && + !game.online && + event.autodelay && + !event.isMine() + ) { + if (typeof event.autodelay == "number") { + game.delayx(event.autodelay); + } else { + game.delayx(); + } + } + "step 4"; + if (event.logSkill && event.result.bool && !game.online) { + if (typeof event.logSkill == "string") { + player.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (!game.online && !event.chooseonly) { + if (typeof event.delay == "boolean") { + event.done = player.discard(event.result.cards).set("delay", event.delay); + } else { + event.done = player.discard(event.result.cards); + } + event.done.discarder = player; + } + if (event.dialog && event.dialog.close) event.dialog.close(); + }, + gaincardMultiple: function () { + "step 0"; + event.type = "gain"; + if (event.animate == "give" || event.animate == "gain2") event.visible = true; + if (player && cards) { + event._lose = true; + player.lose(cards, ui.special).set("type", "gain").set("forceDie", true).set("getlx", false); + } + "step 1"; + switch (event.animate) { + case "draw": + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == "card") i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter((card) => { + return !cards.includes(card) || !player.getCards("hejsx").includes(card); + }); + } + if (i[1].length > 0) i[0].$draw(i[1].length); + } + break; + case "gain": + game.delay(0, get.delayx(700, 700)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == "card") i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter((card) => { + return !cards.includes(card) || !player.getCards("hejsx").includes(card); + }); + } + if (i[1].length > 0) i[0].$gain(i[1].length); + } + break; + case "gain2": + case "draw2": + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == "card") i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter((card) => { + return !cards.includes(card) || !player.getCards("hejsx").includes(card); + }); + } + if (i[1].length > 0) i[0].$gain2(i[1]); + } + break; + case "give": + case "giveAuto": + if (!player) break; + var evt = event.getl(player); + game.delay(0, get.delayx(500, 500)); + for (var i of event.gain_list) { + if (get.itemtype(i[1]) == "card") i[1] = [i[1]]; + if (event._lose) { + i[1] = i[1].filter((card) => { + return !cards.includes(card) || !player.getCards("hejsx").includes(card); + }); + } + var shown = i[1].slice(0), + hidden = []; + if (event.animate == "giveAuto") { + for (var card of i[1]) { + if (evt.hs.includes(card)) { + shown.remove(card); + hidden.push(card); + } + } + } + if (shown.length > 0) player.$give(shown, i[0]); + if (hidden.length > 0) player.$giveAuto(hidden, i[0]); + } + break; + default: + event.finish(); + } + for (var i of event.gain_list) { + if (i[1].length > 0) { + var next = i[0].gain(i[1]); + next.getlx = false; + if (event.visible) next.visible = true; + if (event.giver) next.giver = event.giver; + if (event.gaintag) next.gaintag.addArray(event.gaintag); + } + } + "step 2"; + game.delayx(); + }, + discardMultiple: function () { + "step 0"; + event.type = "discard"; + event.visible = true; + if (!event.position) event.position = ui.discardPile; + var cards = []; + event.cards = cards; + for (var i = 0; i < event.lose_list.length; i++) { + var next = event.lose_list[i][0].lose(event.lose_list[i][1], event.position); + game.log(event.lose_list[i][0], "弃置了", event.lose_list[i][1]); + next.type = "discard"; + next.animate = false; + next.delay = false; + cards.addArray(event.lose_list[i][1]); + next.getlx = false; + } + var evt = event; + if (evt.animate != false) { + evt.discardid = lib.status.videoId++; + game.broadcastAll( + function (list, id, cards) { + for (var i of list) { + for (var j of i[1]) { + j.classList.remove("glow"); + j.classList.remove("glows"); + } + i[0].$throw(i[1], null, "nobroadcast"); + } + var cardnodes = []; + cardnodes._discardtime = get.time(); + for (var ix of list) { + var card = ix[1]; + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cardnodes.push(cards[i].clone); + } + } + } + ui.todiscard[id] = cardnodes; + }, + event.lose_list, + evt.discardid, + cards + ); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + if (evt.delay != false) { + var waitingForTransition = get.time(); + evt.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.waitingForTransition; + }); + } else if (evt.getParent().discardTransition) { + delete evt.getParent().discardTransition; + var waitingForTransition = get.time(); + evt.getParent().waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.getParent().waitingForTransition; + }); + } + } + } + "step 1"; + if (event.delay != false) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } else { + game.delayx(); + } + } + }, + chooseToCompareLose: function () { + for (var i = 0; i < event.lose_list.length; i++) { + var next = event.lose_list[i][0].lose(event.lose_list[i][1], ui.ordering); + next.relatedEvent = event.getParent(); + next.getlx = false; + } + }, + chooseToCompareMeanwhile: function () { + "step 0"; + if (player.countCards("h") == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + for (var i = 0; i < targets.length; i++) { + if (targets[i].countCards("h") == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + } + if (!event.multitarget) { + targets.sort(lib.sort.seat); + } + game.log(player, "对", targets, "发起了共同拼点"); + event.compareMeanwhile = true; + "step 1"; + event._result = []; + event.list = targets.filter(function (current) { + return !event.fixedResult || !event.fixedResult[current.playerid]; + }); + if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { + if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); + player + .chooseCardOL(event.list, "请选择拼点牌", true) + .set("type", "compare") + .set("ai", event.ai) + .set("source", player).aiCard = function (target) { + var hs = target.getCards("h"); + var event = _status.event; + event.player = target; + hs.sort(function (a, b) { + return event.ai(b) - event.ai(a); + }); + delete event.player; + return { bool: true, cards: [hs[0]] }; + }; + } + "step 2"; + var cards = []; + var lose_list = []; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.list.unshift(player); + result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); + lose_list.push([player, [event.fixedResult[player.playerid]]]); + } else { + if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { + player.logSkill(result[0].skill); + result[0].cards = lib.skill[result[0].skill].onCompare(player); + } else lose_list.push([player, result[0].cards]); + } + for (var j = 0; j < targets.length; j++) { + if (event.list.includes(targets[j])) { + var i = event.list.indexOf(targets[j]); + if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { + event.list[i].logSkill(result[i].skill); + result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); + } else lose_list.push([targets[j], result[i].cards]); + cards.push(result[i].cards[0]); + } else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { + cards.push(event.fixedResult[targets[j].playerid]); + lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); + } + } + if (lose_list.length) { + game.loseAsync({ + lose_list: lose_list, + }).setContent("chooseToCompareLose"); + } + event.lose_list = lose_list; + event.getNum = function (card) { + for (var i of event.lose_list) { + if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.cardlist = cards; + event.cards = cards; + event.card1 = result[0].cards[0]; + event.num1 = event.getNum(event.card1); + event.iwhile = 0; + event.winner = null; + event.maxNum = -1; + event.tempplayer = event.player; + event.result = { + winner: null, + player: event.card1, + targets: event.cardlist.slice(0), + num1: [], + num2: [], + }; + "step 3"; + event.trigger("compareCardShowBefore"); + "step 4"; + player.$compareMultiple(event.card1, targets, cards); + game.log(player, "的拼点牌为", event.card1); + event.cardlist.forEach((card, index) => { + game.log(targets[index], "的拼点牌为", card); + }); + player.addTempClass("target"); + game.delay(0, 1000); + "step 5"; + event.target = null; + event.trigger("compare"); + "step 6"; + if (event.iwhile < targets.length) { + event.target = targets[event.iwhile]; + event.target.addTempClass("target"); + event.card2 = event.cardlist[event.iwhile]; + event.num2 = event.getNum(event.card2); + //event.tempplayer.line(event.target); + delete event.player; + event.trigger("compare"); + } else { + game.delay(0, 1000); + event.goto(9); + } + "step 7"; + event.result.num1[event.iwhile] = event.num1; + event.result.num2[event.iwhile] = event.num2; + var list = [ + [event.tempplayer, event.num1], + [event.target, event.num2], + ]; + for (var i of list) { + if (i[1] > event.maxNum) { + event.maxNum = i[1]; + event.winner = i[0]; + } else if (event.winner && i[1] == event.maxNum && i[0] != event.winner) { + event.winner = null; + } + } + "step 8"; + event.iwhile++; + event.goto(6); + "step 9"; + var player = event.tempplayer; + event.player = player; + delete event.tempplayer; + var str = "无人拼点成功"; + if (event.winner) { + event.result.winner = event.winner; + str = get.translation(event.winner) + "拼点成功"; + game.log(event.winner, "拼点成功"); + event.winner.popup("胜"); + } else game.log("#b无人", "拼点成功"); + var list = [player].addArray(targets); + list.remove(event.winner); + for (var i of list) { + i.popup("负"); + } + if (str) { + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + } + game.delay(3); + "step 10"; + game.broadcastAll(ui.clear); + "step 11"; + event.cards.add(event.card1); + }, + chooseToCompareMultiple: function () { + "step 0"; + if (player.countCards("h") == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + for (var i = 0; i < targets.length; i++) { + if (targets[i].countCards("h") == 0) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + } + if (!event.multitarget) { + targets.sort(lib.sort.seat); + } + game.log(player, "对", targets, "发起拼点"); + "step 1"; + event._result = []; + event.list = targets.filter(function (current) { + return !event.fixedResult || !event.fixedResult[current.playerid]; + }); + if (event.list.length || !event.fixedResult || !event.fixedResult[player.playerid]) { + if (!event.fixedResult || !event.fixedResult[player.playerid]) event.list.unshift(player); + player + .chooseCardOL(event.list, "请选择拼点牌", true) + .set("type", "compare") + .set("ai", event.ai) + .set("source", player).aiCard = function (target) { + var hs = target.getCards("h"); + var event = _status.event; + event.player = target; + hs.sort(function (a, b) { + return event.ai(b) - event.ai(a); + }); + delete event.player; + return { bool: true, cards: [hs[0]] }; + }; + } + "step 2"; + var cards = []; + var lose_list = []; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.list.unshift(player); + result.unshift({ bool: true, cards: [event.fixedResult[player.playerid]] }); + lose_list.push([player, [event.fixedResult[player.playerid]]]); + } else { + if (result[0].skill && lib.skill[result[0].skill] && lib.skill[result[0].skill].onCompare) { + player.logSkill(result[0].skill); + result[0].cards = lib.skill[result[0].skill].onCompare(player); + } else lose_list.push([player, result[0].cards]); + } + for (var j = 0; j < targets.length; j++) { + if (event.list.includes(targets[j])) { + var i = event.list.indexOf(targets[j]); + if (result[i].skill && lib.skill[result[i].skill] && lib.skill[result[i].skill].onCompare) { + event.list[i].logSkill(result[i].skill); + result[i].cards = lib.skill[result[i].skill].onCompare(event.list[i]); + } else lose_list.push([targets[j], result[i].cards]); + cards.push(result[i].cards[0]); + } else if (event.fixedResult && event.fixedResult[targets[j].playerid]) { + cards.push(event.fixedResult[targets[j].playerid]); + lose_list.push([targets[j], [event.fixedResult[targets[j].playerid]]]); + } + } + if (lose_list.length) { + game.loseAsync({ + lose_list: lose_list, + }).setContent("chooseToCompareLose"); + } + event.lose_list = lose_list; + event.getNum = function (card) { + for (var i of event.lose_list) { + if (i[1].contains && i[1].includes(card)) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.cardlist = cards; + event.cards = cards; + event.card1 = result[0].cards[0]; + event.num1 = event.getNum(event.card1); + event.iwhile = 0; + event.result = { + player: event.card1, + targets: event.cardlist.slice(0), + num1: [], + num2: [], + }; + "step 3"; + event.trigger("compareCardShowBefore"); + "step 4"; + game.log(player, "的拼点牌为", event.card1); + "step 5"; + if (event.iwhile < targets.length) { + event.target = targets[event.iwhile]; + event.target.addTempClass("target"); + player.addTempClass("target"); + event.card2 = event.cardlist[event.iwhile]; + event.num2 = event.getNum(event.card2); + game.log(event.target, "的拼点牌为", event.card2); + player.line(event.target); + player.$compare(event.card1, event.target, event.card2); + event.trigger("compare"); + game.delay(0, 1500); + } else { + event.goto(9); + } + "step 6"; + event.result.num1[event.iwhile] = event.num1; + event.result.num2[event.iwhile] = event.num2; + var str; + if (event.num1 > event.num2) { + str = get.translation(player) + "拼点成功"; + player.popup("胜"); + target.popup("负"); + } else { + str = get.translation(player) + "拼点失败"; + if (event.num1 == event.num2) { + player.popup("平"); + target.popup("平"); + } else { + player.popup("负"); + target.popup("胜"); + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + "step 7"; + if (event.callback) { + game.broadcastAll( + function (card1, card2) { + if (card1.clone) card1.clone.style.opacity = 0.5; + if (card2.clone) card2.clone.style.opacity = 0.5; + }, + event.card1, + event.card2 + ); + var next = game.createEvent("compareMultiple"); + next.player = player; + next.target = event.target; + next.card1 = event.card1; + next.card2 = event.card2; + next.num1 = event.num1; + next.num2 = event.num2; + next.setContent(event.callback); + event.compareMultiple = true; + } + "step 8"; + game.broadcastAll(ui.clear); + event.iwhile++; + event.goto(5); + "step 9"; + event.cards.add(event.card1); + }, + chooseToCompare: function () { + "step 0"; + if ( + ((!event.fixedResult || !event.fixedResult[player.playerid]) && player.countCards("h") == 0) || + ((!event.fixedResult || !event.fixedResult[target.playerid]) && target.countCards("h") == 0) + ) { + event.result = { cancelled: true, bool: false }; + event.finish(); + return; + } + game.log(player, "对", target, "发起拼点"); + event.lose_list = []; + "step 1"; + var sendback = function () { + if (_status.event != event) { + return function () { + event.resultOL = _status.event.resultOL; + }; + } + }; + if (event.fixedResult && event.fixedResult[player.playerid]) { + event.card1 = event.fixedResult[player.playerid]; + event.lose_list.push([player, event.card1]); + } else if (player.isOnline()) { + player.wait(sendback); + event.ol = true; + player.send(function (ai) { + game.me.chooseCard("请选择拼点牌", true).set("type", "compare").set("glow_result", true).ai = + ai; + game.resume(); + }, event.ai); + } else { + event.localPlayer = true; + player.chooseCard("请选择拼点牌", true).set("type", "compare").set("glow_result", true).ai = + event.ai; + } + if (event.fixedResult && event.fixedResult[target.playerid]) { + event.card2 = event.fixedResult[target.playerid]; + event.lose_list.push([target, event.card2]); + } else if (target.isOnline()) { + target.wait(sendback); + event.ol = true; + target.send(function (ai) { + game.me.chooseCard("请选择拼点牌", true).set("type", "compare").set("glow_result", true).ai = + ai; + game.resume(); + }, event.ai); + } else { + event.localTarget = true; + } + "step 2"; + if (event.localPlayer) { + if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { + result.cards = lib.skill[result.skill].onCompare(player); + player.logSkill(result.skill); + } else event.lose_list.push([player, result.cards[0]]); + event.card1 = result.cards[0]; + } + if (event.localTarget) { + target.chooseCard("请选择拼点牌", true).set("type", "compare").set("glow_result", true).ai = + event.ai; + } + "step 3"; + if (event.localTarget) { + if (result.skill && lib.skill[result.skill] && lib.skill[result.skill].onCompare) { + target.logSkill(result.skill); + result.cards = lib.skill[result.skill].onCompare(target); + } else event.lose_list.push([target, result.cards[0]]); + event.card2 = result.cards[0]; + } + if (!event.resultOL && event.ol) { + game.pause(); + } + "step 4"; + try { + if (!event.card1) { + if ( + event.resultOL[player.playerid].skill && + lib.skill[event.resultOL[player.playerid].skill] && + lib.skill[event.resultOL[player.playerid].skill].onCompare + ) { + player.logSkill(event.resultOL[player.playerid].skill); + event.resultOL[player.playerid].cards = + lib.skill[event.resultOL[player.playerid].skill].onCompare(player); + } else event.lose_list.push([player, event.resultOL[player.playerid].cards[0]]); + event.card1 = event.resultOL[player.playerid].cards[0]; + } + if (!event.card2) { + if ( + event.resultOL[target.playerid].skill && + lib.skill[event.resultOL[target.playerid].skill] && + lib.skill[event.resultOL[target.playerid].skill].onCompare + ) { + target.logSkill(event.resultOL[target.playerid].skill); + event.resultOL[target.playerid].cards = + lib.skill[event.resultOL[target.playerid].skill].onCompare(player); + } else event.lose_list.push([target, event.resultOL[target.playerid].cards[0]]); + event.card2 = event.resultOL[target.playerid].cards[0]; + } + if (!event.card1 || !event.card2) { + throw "err"; + } + } catch (e) { + console.log(e); + game.print(e); + event.finish(); + return; + } + if (event.card2.number >= 10 || event.card2.number <= 4) { + if (target.countCards("h") > 2) { + event.addToAI = true; + } + } + if (event.lose_list.length) { + game.loseAsync({ + lose_list: event.lose_list, + }).setContent("chooseToCompareLose"); + } + "step 5"; + event.trigger("compareCardShowBefore"); + "step 6"; + game.broadcast(function () { + ui.arena.classList.add("thrownhighlight"); + }); + ui.arena.classList.add("thrownhighlight"); + game.addVideo("thrownhighlight1"); + player.$compare(event.card1, target, event.card2); + game.log(player, "的拼点牌为", event.card1); + game.log(target, "的拼点牌为", event.card2); + var getNum = function (card) { + for (var i of event.lose_list) { + if (i[1] == card) return get.number(card, i[0]); + } + return get.number(card, false); + }; + event.num1 = getNum(event.card1); + event.num2 = getNum(event.card2); + event.trigger("compare"); + game.delay(0, 1500); + "step 7"; + event.result = { + player: event.card1, + target: event.card2, + num1: event.num1, + num2: event.num2, + }; + var str; + if (event.num1 > event.num2) { + event.result.bool = true; + event.result.winner = player; + str = get.translation(player) + "拼点成功"; + player.popup("胜"); + target.popup("负"); + } else { + event.result.bool = false; + str = get.translation(player) + "拼点失败"; + if (event.num1 == event.num2) { + event.result.tie = true; + player.popup("平"); + target.popup("平"); + } else { + event.result.winner = target; + player.popup("负"); + target.popup("胜"); + } + } + game.broadcastAll(function (str) { + var dialog = ui.create.dialog(str); + dialog.classList.add("center"); + setTimeout(function () { + dialog.close(); + }, 1000); + }, str); + game.delay(2); + "step 8"; + if (typeof event.target.ai.shown == "number" && event.target.ai.shown <= 0.85 && event.addToAI) { + event.target.ai.shown += 0.1; + } + game.broadcastAll(function () { + ui.arena.classList.remove("thrownhighlight"); + }); + game.addVideo("thrownhighlight2"); + if (event.clear !== false) { + game.broadcastAll(ui.clear); + } + if (typeof event.preserve == "function") { + event.preserve = event.preserve(event.result); + } else if (event.preserve == "win") { + event.preserve = event.result.bool; + } else if (event.preserve == "lose") { + event.preserve = !event.result.bool; + } + }, + chooseSkill: function () { + "step 0"; + var list; + if (typeof event.target == "string") { + list = get.gainableSkillsName(event.target, event.func); + } else { + list = event.target.getGainableSkills(event.func); + } + if (!list.length) { + event.finish(); + event.result = { bool: false }; + return; + } + event.skillai = function (list) { + return get.max(list, get.skillRank, "item"); + }; + if (event.isMine()) { + var dialog = ui.create.dialog("forcebutton"); + dialog.add(event.prompt || "选择获得一项技能"); + _status.event.list = list; + var clickItem = function () { + _status.event._result = this.link; + game.resume(); + }; + for (i = 0; i < list.length; i++) { + if (lib.translate[list[i] + "_info"]) { + var translation = get.translation(list[i]); + if (translation[0] == "新" && translation.length == 3) { + translation = translation.slice(1, 3); + } else { + translation = translation.slice(0, 2); + } + var item = dialog.add( + '" + ); + item.firstChild.addEventListener("click", clickItem); + item.firstChild.link = list[i]; + } + } + dialog.add(ui.create.div(".placeholder")); + event.dialog = dialog; + event.switchToAuto = function () { + event._result = event.skillai(event.list); + game.resume(); + }; + _status.imchoosing = true; + game.pause(); + } else { + event._result = event.skillai(list); + } + "step 1"; + _status.imchoosing = false; + if (event.dialog) { + event.dialog.close(); + } + event.result = { bool: true, skill: result }; + }, + discoverCard: function () { + "step 0"; + var num = event.num || 3; + var choice; + if (typeof event.list == "string" || typeof event.list == "function") { + choice = get.inpile(event.list).randomGets(num); + } else if (Array.isArray(event.list)) { + choice = event.list.randomGets(num); + } else { + choice = Array.from(event.list).randomGets(num); + } + if (choice.length) { + var prompt = event.prompt; + if (!prompt) { + prompt = "选择一张牌"; + if (event.use) { + prompt += "使用之"; + } else if (!event.nogain) { + prompt += "获得之"; + } + } + if (typeof choice[0] === "string") { + var next = player.chooseVCardButton(choice, prompt, event.forced); + if (event.ai) { + next.set("ai", event.ai); + } + } else if (get.itemtype(choice[0]) == "card") { + var next = player.chooseCardButton(choice, prompt, event.forced); + if (event.ai) { + next.set("ai", event.ai); + } + } else { + event.finish(); + } + } else { + event.finish(); + } + "step 1"; + event.result = { + bool: result.bool, + card: null, + choice: null, + }; + if (result.bool && result.links.length) { + var link = result.links[0]; + var togain = null; + if (get.itemtype(link) == "card") { + event.result.card = link; + togain = link; + } else if (Array.isArray(link)) { + event.result.choice = link[2]; + togain = game.createCard(link[2]); + } + if (togain) { + if (event.use) { + player.chooseUseTarget(togain); + } else if (!event.nogain) { + player.gain(togain, "draw"); + game.log(player, "获得了一张牌"); + } + } + } + }, + chooseButton: function () { + "step 0"; + if (typeof event.dialog == "number") { + event.dialog = get.idDialog(event.dialog); + } + if (event.createDialog && !event.dialog) { + if (Array.isArray(event.createDialog)) { + event.createDialog.add("hidden"); + event.dialog = ui.create.dialog.apply(this, event.createDialog); + } + event.closeDialog = true; + } + if (event.dialog == undefined) event.dialog = ui.dialog; + if (event.isMine() || event.dialogdisplay) { + event.dialog.style.display = ""; + event.dialog.open(); + } + // if (['chooseCharacter', 'chooseButtonOL'].includes(event.getParent().name)) event.complexSelect = true; + var filterButton = + event.filterButton || + function () { + return true; + }; + var selectButton = get.select(event.selectButton); + var buttons = event.dialog.buttons; + var buttonsx = []; + var num = 0; + for (var i = 0; i < buttons.length; i++) { + var button = buttons[i]; + if (filterButton(button, player)) { + num++; + buttonsx.add(button); + } + } + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } else if ((event.direct && num == selectButton[0]) || event.forceDirect) { + var buttons = buttonsx.slice(0, num); + event.result = { + bool: true, + button: [buttons], + links: get.links(buttons), + }; + event.dialog.close(); + } else { + game.check(); + game.pause(); + } + } else if (event.isOnline()) { + if ((event.direct && num == 1) || event.forceDirect) { + var buttons = buttonsx.slice(0, num); + event.result = { + bool: true, + button: [buttons], + links: get.links(buttons), + }; + event.dialog.close(); + } else { + event.send(); + } + delete event.callback; + } else { + event.result = "ai"; + } + if (event.onfree) { + lib.init.onfree(); + } + "step 1"; + if (event.result == "ai") { + if (event.processAI) { + event.result = event.processAI(); + } else { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) + ui.click.ok(); + else ui.click.cancel(); + } + } + if (event.closeDialog) { + event.dialog.close(); + } + if (event.callback) { + event.callback(event.player, event.result); + } + event.resume(); + }, + chooseCardOL: function () { + "step 0"; + event.targets = event.list.slice(0); + if (!_status.connectMode) { + event.result = []; + event.goto(7); + } else { + for (var i = 0; i < event.list.length; i++) { + var target = event.list[i]; + target.wait(); + if (target.isOnline()) { + target.send( + function (args, set) { + game.me.chooseCard.apply(game.me, args).set(set); + game.resume(); + }, + event._args, + event._set + ); + event.list.splice(i--, 1); + } else if (target == game.me) { + event.withme = true; + event.list.splice(i--, 1); + } + } + } + "step 1"; + if (event.list.length) { + event.target = event.list.shift(); + event.target.chooseCard.apply(event.target, event._args).set(event._set); + } else { + event.goto(3); + } + "step 2"; + event.target.unwait(result); + event.goto(1); + "step 3"; + if (event.withme) { + game.me.chooseCard.apply(game.me, event._args).set(event._set); + } else { + event.goto(5); + } + "step 4"; + game.me.unwait(result); + "step 5"; + if (!event.resultOL) { + game.pause(); + } + "step 6"; + event.result = []; + for (var i = 0; i < event.targets.length; i++) { + event.result[i] = event.resultOL[event.targets[i].playerid] || {}; + if (event.result[i] == "ai" && event.aiCard) { + event.result[i] = event.aiCard(event.targets[i]); + } + } + event.finish(); + "step 7"; + if (event.list.length) { + event.target = event.list.shift(); + event.target.chooseCard.apply(event.target, event._args).set(event._set); + } else { + for (var i = 0; i < event.targets.length; i++) { + if (!event.result[i]) { + event.result[i] = {}; + } + } + event.finish(); + } + "step 8"; + event.result[event.targets.indexOf(event.target)] = result; + event.goto(7); + }, + chooseButtonOL: function () { + "step 0"; + //ui.arena.classList.add('markhidden'); + for (var i = 0; i < event.list.length; i++) { + var current = event.list[i]; + current[0].wait(); + if (current[0].isOnline()) { + var target = current.shift(); + target.send( + function (args, callback, switchToAuto, processAI) { + //ui.arena.classList.add('markhidden'); + var next = game.me.chooseButton.apply(game.me, args); + next.callback = callback; + next.switchToAuto = switchToAuto; + next.processAI = processAI; + next.complexSelect = true; + game.resume(); + }, + current, + event.callback, + event.switchToAuto, + event.processAI + ); + target._choose_button_ol = current; + event.list.splice(i--, 1); + } else if (current[0] == game.me) { + event.last = current; + event.last.shift(); + event.list.splice(i--, 1); + } + } + "step 1"; + if (event.list.length) { + var current = event.list.shift(); + event.target = current.shift(); + var next = event.target.chooseButton.apply(event.target, current); + next.callback = event.callback; + next.switchToAuto = event.switchToAuto; + next.processAI = event.processAI; + } else { + event.goto(3); + } + "step 2"; + event.target.unwait(result); + event.goto(1); + "step 3"; + if (event.last) { + var next = game.me.chooseButton.apply(game.me, event.last); + next.callback = event.callback; + next.switchToAuto = event.switchToAuto; + next.processAI = event.processAI; + } else { + event.goto(5); + } + "step 4"; + game.me.unwait(result); + "step 5"; + if (!event.resultOL) { + game.pause(); + } + "step 6"; + /*game.broadcastAll(function(){ + ui.arena.classList.remove('markhidden'); + });*/ + event.result = event.resultOL; + }, + chooseCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + targets: [], + confirm: "ok", + bool: true, + links: [], + }; + } else if (event.autochoose()) { + event.result = { + bool: true, + autochoose: true, + cards: player.getCards(event.position), + confirm: "ok", + buttons: [], + targets: [], + links: [], + }; + } else { + if (event.isMine()) { + game.check(); + game.pause(); + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + if (event.prompt != false) { + var str; + if (typeof event.prompt == "string") str = event.prompt; + else { + str = "请选择"; + var range = get.select(event.selectCard); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += "至少" + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + str += "张"; + if (event.position == "h" || event.position == undefined) str += "手"; + if (event.position == "e") str += "装备"; + str += "牌"; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (Array.isArray(event.promptx)) { + for (var i = 0; i < event.promptx.length; i++) { + event.dialog.add(event.promptx[i]); + } + } + if (Array.isArray(event.selectCard)) { + event.promptbar = event.dialog.add("0/" + get.numStr(event.selectCard[1], "card")); + event.custom.add.card = function () { + _status.event.promptbar.innerHTML = + ui.selected.cards.length + + "/" + + get.numStr(_status.event.selectCard[1], "card"); + }; + } + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseCard(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } else if (event.skill) { + var skill = event.skill; + ui.click.cancel(); + event._aiexclude.add(skill); + event.redo(); + game.resume(); + } else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.glow_result && event.result.cards && !event.directresult) { + for (var i = 0; i < event.result.cards.length; i++) { + event.result.cards[i].classList.add("glow"); + } + } + if (event.dialog) event.dialog.close(); + }, + chooseTarget: function () { + "step 0"; + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.check(); + game.pause(); + if (event.createDialog && !event.dialog && Array.isArray(event.createDialog)) { + event.dialog = ui.create.dialog.apply(this, event.createDialog); + } else if (event.prompt != false) { + var str; + if (typeof event.prompt == "string") str = event.prompt; + else { + str = "请选择"; + var range = get.select(event.selectTarget); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += "至少" + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + str += "个目标"; + } + event.dialog = ui.create.dialog(str); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + if (event.promptbar != "none") { + event.promptbar = event.dialog.add( + "0/" + get.numStr(get.select(event.selectTarget)[1], "target") + ); + event.custom.add.target = function () { + _status.event.promptbar.innerHTML = + ui.selected.targets.length + + "/" + + get.numStr(get.select(event.selectTarget)[1], "target"); + }; + } + } else if (get.itemtype(event.dialog) == "dialog") { + event.dialog.open(); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseTarget(event.ai) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + } else { + ui.click.cancel(); + } + } + if (event.result.bool && event.animate !== false) { + for (var i = 0; i < event.result.targets.length; i++) { + event.result.targets[i].addTempClass("target"); + } + } + if (event.dialog) event.dialog.close(); + event.resume(); + "step 2"; + if (event.onresult) { + event.onresult(event.result); + } + if (event.result.bool && event.autodelay && !event.isMine()) { + if (typeof event.autodelay == "number") { + game.delayx(event.autodelay); + } else { + game.delayx(); + } + } + }, + chooseCardTarget: function () { + "step 0"; + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + game.check(); + game.pause(); + if (event.prompt != false) { + event.dialog = ui.create.dialog(event.prompt || "请选择卡牌和目标"); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + game.check(); + if (ai.basic.chooseCard(event.ai1) || forced) { + if ((ai.basic.chooseTarget(event.ai2) || forced) && (!event.filterOk || event.filterOk())) { + ui.click.ok(); + _status.event._aiexclude.length = 0; + } else { + ui.click.cancel(); + } + } else { + ui.click.cancel(); + } + } + "step 2"; + event.resume(); + if (event.result.bool && event.animate !== false) { + for (var i = 0; i < event.result.targets.length; i++) { + event.result.targets[i].addTempClass("target"); + } + } + if (event.dialog) event.dialog.close(); + }, + chooseControl: function () { + "step 0"; + if (event.controls.length == 0) { + if (event.sortcard) { + var sortnum = 2; + if (event.sorttop) { + sortnum = 1; + } + for (var i = 0; i < event.sortcard.length + sortnum; i++) { + event.controls.push(get.cnNumber(i, true)); + } + } else if (event.choiceList) { + for (var i = 0; i < event.choiceList.length; i++) { + event.controls.push("选项" + get.cnNumber(i + 1, true)); + } + } else { + event.finish(); + return; + } + } else if (event.choiceList && event.controls.length == 1 && event.controls[0] == "cancel2") { + event.controls.shift(); + for (var i = 0; i < event.choiceList.length; i++) { + event.controls.push("选项" + get.cnNumber(i + 1, true)); + } + event.controls.push("cancel2"); + } + if (event.isMine()) { + if (event.arrangeSkill) { + var hidden = player.hiddenSkills.slice(0); + game.expandSkills(hidden); + if (hidden.length) { + for (var i of event.controls) { + if (_status.prehidden_skills.includes(i) && hidden.includes(i)) { + event.result = { + bool: true, + control: i, + }; + return; + } + } + } + } else if ( + event.hsskill && + _status.prehidden_skills.includes(event.hsskill) && + event.controls.includes("cancel2") + ) { + event.result = { + bool: true, + control: "cancel2", + }; + return; + } + if (event.sortcard) { + var prompt = event.prompt || "选择一个位置"; + if (event.tosort) { + prompt += "放置" + get.translation(event.tosort); + } + event.dialog = ui.create.dialog(prompt, "hidden"); + if (event.sortcard && event.sortcard.length) { + event.dialog.addSmall(event.sortcard); + } else { + event.dialog.buttons = []; + event.dialog.add(ui.create.div(".buttons")); + } + var buttons = event.dialog.content.lastChild; + var sortnum = 2; + if (event.sorttop) { + sortnum = 1; + } + for (var i = 0; i < event.dialog.buttons.length + sortnum; i++) { + var item = ui.create.div(".button.card.pointerdiv.mebg"); + item.style.width = "50px"; + buttons.insertBefore(item, event.dialog.buttons[i]); + item.innerHTML = + '
                                    第' + + get.cnNumber(i + 1, true) + + "张
                                    "; + if (i == event.dialog.buttons.length + 1) { + item.firstChild.innerHTML = "牌堆底"; + } + item.link = get.cnNumber(i, true); + item.listen(ui.click.dialogcontrol); + } + + event.dialog.forcebutton = true; + event.dialog.classList.add("forcebutton"); + event.dialog.open(); + } else if (event.dialogcontrol) { + event.dialog = ui.create.dialog(event.prompt || "选择一项", "hidden"); + for (var i = 0; i < event.controls.length; i++) { + var item = event.dialog.add( + '" + ); + item.firstChild.listen(ui.click.dialogcontrol); + item.firstChild.link = event.controls[i]; + } + event.dialog.forcebutton = true; + event.dialog.classList.add("forcebutton"); + if (event.addDialog) { + for (var i = 0; i < event.addDialog.length; i++) { + if (get.itemtype(event.addDialog[i]) == "cards") { + event.dialog.addSmall(event.addDialog[i]); + } else { + event.dialog.add(event.addDialog[i]); + } + } + event.dialog.add(ui.create.div(".placeholder.slim")); + } + event.dialog.open(); + } else { + if (event.seperate || lib.config.seperate_control) { + var controls = event.controls.slice(0); + var num = 0; + controls.remove("cancel2"); + if ((event.direct && controls.length == 1) || event.forceDirect) { + event.result = { + control: event.controls[0].link, + links: get.links([event.controls[0]]), + }; + return; + } else { + event.controlbars = []; + for (var i = 0; i < event.controls.length; i++) { + event.controlbars.push(ui.create.control([event.controls[i]])); + } + } + } else { + var controls = event.controls.slice(0); + var num = 0; + controls.remove("cancel2"); + if ((event.direct && controls.length == 1) || event.forceDirect) { + event.result = { + control: event.controls[0].link, + links: get.links([event.controls[0]]), + }; + return; + } + event.controlbar = ui.create.control(event.controls); + } + if (event.dialog) { + if (Array.isArray(event.dialog)) { + event.dialog = ui.create.dialog.apply(this, event.dialog); + } + event.dialog.open(); + } else if (event.choiceList) { + event.dialog = ui.create.dialog(event.prompt || "选择一项", "hidden"); + event.dialog.forcebutton = true; + event.dialog.open(); + for (var i = 0; i < event.choiceList.length; i++) { + event.dialog.add( + '" + ); + } + } else if (event.prompt) { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText( + event.prompt2, + Boolean(event.prompt2.length <= 20 || event.centerprompt2) + ); + } + } + } + game.pause(); + game.countChoose(); + event.choosing = true; + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + event.result = {}; + if (event.ai) { + var result = event.ai(event.getParent(), player); + if (typeof result == "number") event.result.control = event.controls[result]; + else event.result.control = result; + } else event.result.control = event.controls[event.choice]; + } + event.result.index = event.controls.indexOf(event.result.control); + event.choosing = false; + _status.imchoosing = false; + if (event.dialog && event.dialog.close) event.dialog.close(); + if (event.controlbar) event.controlbar.close(); + if (event.controlbars) { + for (var i = 0; i < event.controlbars.length; i++) { + event.controlbars[i].close(); + } + } + event.resume(); + }, + chooseBool: function () { + "step 0"; + if (event.isMine()) { + if (event.frequentSkill && !lib.config.autoskilllist.includes(event.frequentSkill)) { + ui.click.ok(); + return; + } else if (event.hsskill && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + ui.create.confirm("oc"); + if (event.createDialog && !event.dialog) { + if (Array.isArray(event.createDialog)) { + event.dialog = ui.create.dialog.apply(this, event.createDialog); + if (event.dialogselectx) { + for (var i = 0; i < event.dialog.buttons.length; i++) { + event.dialog.buttons[i].classList.add("selectedx"); + } + } + } + } + if (event.dialog) { + event.dialog.open(); + } else if (event.prompt) { + event.dialog = ui.create.dialog(event.prompt); + if (event.prompt2) { + event.dialog.addText(event.prompt2, event.prompt2.length <= 20); + } + } + game.pause(); + game.countChoose(); + event.choosing = true; + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + "step 1"; + if (event.result == "ai") { + if (event.ai) { + event.choice = event.ai(event.getParent(), player); + } + event.result = { bool: event.choice }; + } + _status.imchoosing = false; + event.choosing = false; + if (event.dialog) event.dialog.close(); + event.resume(); + }, + chooseDrawRecover: function () { + "step 0"; + if (player.isHealthy() && event.forced) { + player.draw(event.num1); + event.finish(); + return; + } + var controls = ["draw_card"]; + if (player.isDamaged()) { + event.num2 = Math.min(event.num2, player.maxHp - player.hp); + controls.push("recover_hp"); + } + if (!event.forced) { + controls.push("cancel2"); + } + var prompt = event.prompt; + if (!prompt) { + if (player.isHealthy()) { + prompt = "是否摸" + get.cnNumber(event.num1) + "张牌?"; + } else { + prompt = "摸" + get.cnNumber(event.num1) + "张牌或回复" + get.cnNumber(event.num2) + "点体力"; + } + } + var next = player.chooseControl(controls); + next.set("prompt", prompt); + if (event.hsskill) next.setHiddenSkill(event.hsskill); + if (event.ai) { + next.set("ai", event.ai); + } else { + var choice; + if ( + player.isDamaged() && + get.recoverEffect(player) > 0 && + (player.hp == 1 || + player.needsToDiscard() || + player.hasSkillTag("maixie_hp") || + event.num2 > event.num1 || + (event.num2 == event.num1 && player.needsToDiscard(1))) + ) { + choice = "recover_hp"; + } else { + choice = "draw_card"; + } + next.set("ai", function () { + return _status.event.choice; + }); + next.set("choice", choice); + } + "step 1"; + if (result.control != "cancel2") { + if (event.logSkill) { + if (typeof event.logSkill == "string") { + player.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + if (result.control == "draw_card") { + player.draw(event.num1); + } else { + player.recover(event.num2); + } + } + event.result = result; + }, + choosePlayerCard: function () { + "step 0"; + if (!event.dialog) event.dialog = ui.create.dialog("hidden"); + else if (!event.isMine()) { + event.dialog.style.display = "none"; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } else { + event.dialog.add("选择" + get.translation(target) + "的一张牌"); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + let expand_length = 0; + const cs = target.getCards(event.position); + const select = get.select(event.selectButton); + const directFilter = + event.forced && + typeof event.filterOk != "function" && + typeof event.selectButton != "function" && + event.filterButton == lib.filter.all; + let directh = + !lib.config.unauto_choose && + !event.isOnline() && + select[0] == select[1] && + (!event.complexSelect || select[1] === 1); + + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == "h") { + var hs = target.getCards("h"); + if (hs.length) { + expand_length += Math.ceil(hs.length / 6); + var title = event.dialog.add( + '
                                    手牌区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + hs.randomSort(); + if ( + event.visible || + target.isUnderControl(true) || + player.hasSkillTag("viewHandcard", null, target, true) + ) { + event.dialog.add(hs); + directh = false; + } else { + var shown = hs.filter((card) => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add([hs, "blank"]); + } + } + } + } else if (event.position[i] == "e") { + var es = target.getCards("e"); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add( + '
                                    装备区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + event.dialog.add(es); + directh = false; + } + } else if (event.position[i] == "j") { + var js = target.getCards("j"); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add( + '
                                    判定区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + var shown = js.filter((card) => { + var name = card.viewAs || card.name, + info = lib.card[name]; + if (!info || !info.blankCard) return true; + return false; + }); + if (shown.length < js.length && !target.isUnderControl(true)) { + var hidden = js.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add(js); + } + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.finish(); + return; + } + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs, + }; + } else if (directFilter && directh) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [], + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } else { + if (event.isMine()) { + if (event.hsskill && !event.forced && _status.prehidden_skills.includes(event.hsskill)) { + ui.click.cancel(); + return; + } + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add("choose-player-card"); + event.dialog.classList.add("fullheight"); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) + ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + if (event.result.links) { + event.result.cards = event.result.links.slice(0); + } + event.resume(); + setTimeout(function () { + ui.arena.classList.remove("choose-player-card"); + }, 500); + }, + discardPlayerCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + links: event.directresult.slice(0), + targets: [], + confirm: "ok", + bool: true, + }; + event.cards = event.directresult.slice(0); + event.goto(2); + return; + } + if (!event.dialog) event.dialog = ui.create.dialog("hidden"); + else if (!event.isMine()) { + event.dialog.style.display = "none"; + } + if (event.prompt == undefined) { + var str = "弃置" + get.translation(target); + var range = get.select(event.selectButton); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += "至少" + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + str += "张"; + if (event.position == "h" || event.position == undefined) str += "手"; + if (event.position == "e") str += "装备"; + str += "牌"; + event.prompt = str; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + let expand_length = 0; + const cs = target.getCards(event.position); + const select = get.select(event.selectButton); + const directFilter = + event.forced && + typeof event.filterOk != "function" && + typeof event.selectButton != "function" && + event.filterButton == lib.filter.all; + let directh = + !lib.config.unauto_choose && + !event.isOnline() && + select[0] == select[1] && + (!event.complexSelect || select[1] === 1); + + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == "h") { + var hs = target.getDiscardableCards(player, "h"); + expand_length += Math.ceil(hs.length / 6); + if (hs.length) { + var title = event.dialog.add( + '
                                    手牌区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + hs.randomSort(); + if ( + event.visible || + target.isUnderControl(true) || + player.hasSkillTag("viewHandcard", null, target, true) + ) { + event.dialog.add(hs); + directh = false; + } else { + var shown = hs.filter((card) => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add([hs, "blank"]); + } + } + } + } else if (event.position[i] == "e") { + var es = target.getDiscardableCards(player, "e"); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add( + '
                                    装备区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + event.dialog.add(es); + directh = false; + } + } else if (event.position[i] == "j") { + var js = target.getDiscardableCards(player, "j"); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add( + '
                                    判定区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + var shown = js.filter((card) => { + var name = card.viewAs || card.name, + info = lib.card[name]; + if (!info || !info.blankCard) return true; + return false; + }); + if (shown.length < js.length && !target.isUnderControl(true)) { + var hidden = js.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add(js); + } + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.finish(); + return; + } + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs, + }; + } else if (directFilter && directh) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [], + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } else { + if (event.isMine()) { + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add("discard-player-card"); + event.dialog.classList.add("fullheight"); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) + ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + "step 2"; + event.resume(); + setTimeout(function () { + ui.arena.classList.remove("discard-player-card"); + }, 500); + if (event.result.bool && event.result.links && !game.online) { + if (event.logSkill) { + if (typeof event.logSkill == "string") { + player.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + var cards = []; + for (var i = 0; i < event.result.links.length; i++) { + cards.push(event.result.links[i]); + } + event.result.cards = event.result.links.slice(0); + event.cards = cards; + event.trigger("rewriteDiscardResult"); + } + "step 3"; + if (event.boolline) { + player.line(target, "green"); + } + if (!event.chooseonly) { + var next = target.discard(event.cards); + if (player != target) next.notBySelf = true; + next.discarder = player; + event.done = next; + if (event.delay === false) { + next.set("delay", false); + } + } + }, + gainPlayerCard: function () { + "step 0"; + if (event.directresult) { + event.result = { + buttons: [], + cards: event.directresult.slice(0), + links: event.directresult.slice(0), + targets: [], + confirm: "ok", + bool: true, + }; + event.cards = event.directresult.slice(0); + event.goto(2); + return; + } + if (!event.dialog) event.dialog = ui.create.dialog("hidden"); + else if (!event.isMine()) { + event.dialog.style.display = "none"; + } + if (event.prompt == undefined) { + var str = "获得" + get.translation(target); + var range = get.select(event.selectButton); + if (range[0] == range[1]) str += get.cnNumber(range[0]); + else if (range[1] == Infinity) str += "至少" + get.cnNumber(range[0]); + else str += get.cnNumber(range[0]) + "至" + get.cnNumber(range[1]); + str += "张"; + if (event.position == "h" || event.position == undefined) str += "手"; + if (event.position == "e") str += "装备"; + str += "牌"; + event.prompt = str; + } + if (event.prompt) { + event.dialog.add(event.prompt); + } + if (event.prompt2) { + event.dialog.addText(event.prompt2); + } + let expand_length = 0; + const cs = target.getCards(event.position); + const select = get.select(event.selectButton); + const directFilter = + event.forced && + typeof event.filterOk != "function" && + typeof event.selectButton != "function" && + event.filterButton == lib.filter.all; + let directh = + !lib.config.unauto_choose && + !event.isOnline() && + select[0] == select[1] && + (!event.complexSelect || select[1] === 1); + + for (var i = 0; i < event.position.length; i++) { + if (event.position[i] == "h") { + var hs = target.getGainableCards(player, "h"); + if (hs.length) { + expand_length += Math.ceil(hs.length / 6); + var title = event.dialog.add( + '
                                    手牌区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + hs.randomSort(); + if ( + event.visible || + target.isUnderControl(true) || + player.hasSkillTag("viewHandcard", null, target, true) + ) { + event.dialog.add(hs); + directh = false; + } else { + var shown = hs.filter((card) => get.is.shownCard(card)); + if (shown.length) { + var hidden = hs.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add([hs, "blank"]); + } + } + } + } else if (event.position[i] == "e") { + var es = target.getGainableCards(player, "e"); + if (es.length) { + expand_length += Math.ceil(es.length / 6); + var title = event.dialog.add( + '
                                    装备区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + event.dialog.add(es); + directh = false; + } + } else if (event.position[i] == "j") { + var js = target.getGainableCards(player, "j"); + if (js.length) { + expand_length += Math.ceil(js.length / 6); + var title = event.dialog.add( + '
                                    判定区
                                    ' + ); + title.style.margin = "0px"; + title.style.padding = "0px"; + var shown = js.filter((card) => { + var name = card.viewAs || card.name, + info = lib.card[name]; + if (!info || !info.blankCard) return true; + return false; + }); + if (shown.length < js.length && !target.isUnderControl(true)) { + var hidden = js.filter((card) => !shown.includes(card)); + var buttons = ui.create.div(".buttons", event.dialog.content); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(shown, "card", buttons) + ); + event.dialog.buttons = event.dialog.buttons.concat( + ui.create.buttons(hidden, "blank", buttons) + ); + if (event.dialog.forcebutton !== false) event.dialog.forcebutton = true; + if (event.dialog.buttons.length > 3) { + event.dialog.classList.remove("forcebutton-auto"); + } else if (!event.dialog.noforcebutton) { + event.dialog.classList.add("forcebutton-auto"); + } + } else { + event.dialog.add(js); + } + directh = false; + } + } + } + if (event.dialog.buttons.length == 0) { + event.dialog.close(); + event.finish(); + return; + } + if (directFilter && select[0] >= cs.length) { + event.result = { + bool: true, + buttons: event.dialog.buttons, + links: cs, + }; + } else if (directFilter && directh) { + event.result = { + bool: true, + buttons: event.dialog.buttons.randomGets(select[0]), + links: [], + }; + for (var i = 0; i < event.result.buttons.length; i++) { + event.result.links[i] = event.result.buttons[i].link; + } + } else { + if (event.isMine()) { + event.dialog.open(); + game.check(); + game.pause(); + if (expand_length > 2) { + ui.arena.classList.add("gain-player-card"); + event.dialog.classList.add("fullheight"); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.result = "ai"; + } + } + "step 1"; + if (event.result == "ai") { + game.check(); + if ((ai.basic.chooseButton(event.ai) || forced) && (!event.filterOk || event.filterOk())) + ui.click.ok(); + else ui.click.cancel(); + } + event.dialog.close(); + "step 2"; + event.resume(); + setTimeout(function () { + ui.arena.classList.remove("gain-player-card"); + }, 500); + if (game.online || !event.result.bool) { + event.finish(); + } + "step 3"; + if (event.logSkill && event.result.bool && !game.online) { + if (typeof event.logSkill == "string") { + player.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + player.logSkill.apply(player, event.logSkill); + } + } + var cards = []; + for (var i = 0; i < event.result.links.length; i++) { + cards.push(event.result.links[i]); + } + event.result.cards = event.result.links.slice(0); + event.cards = cards; + event.trigger("rewriteGainResult"); + "step 4"; + if (event.boolline) { + player.line(target, "green"); + } + if (!event.chooseonly) { + if (event.delay !== false) { + var next = player.gain( + event.cards, + target, + event.visibleMove ? "give" : "giveAuto", + "bySelf" + ); + event.done = next; + } else { + var next = player.gain(event.cards, target, "bySelf"); + event.done = next; + target[event.visibleMove ? "$give" : "$giveAuto"](cards, player); + if (event.visibleMove) next.visible = true; + } + } else target[event.visibleMove ? "$give" : "$giveAuto"](cards, player); + }, + showHandcards: function () { + "step 0"; + if (player.countCards("h") == 0) { + event.finish(); + return; + } + var cards = player.getCards("h"); + player.showCards(cards).setContent(function () {}); + var str = get.translation(player.name) + "的手牌"; + if (typeof event.prompt == "string") { + str = event.prompt; + } + event.dialog = ui.create.dialog(str, cards); + event.dialogid = lib.status.videoId++; + event.dialog.videoId = event.dialogid; + game.broadcast( + function (str, cards, id) { + ui.create.dialog(str, cards).videoId = id; + }, + str, + cards, + event.dialogid + ); + game.log(player, "展示了", cards); + game.addVideo("showCards", player, [str, get.cardsInfo(cards)]); + game.delayx(2); + "step 1"; + game.broadcast("closeDialog", event.dialogid); + event.dialog.close(); + }, + showCards: function () { + "step 0"; + if (get.itemtype(cards) != "cards") { + event.finish(); + return; + } + if (!event.str) { + event.str = get.translation(player.name) + "展示的牌"; + } + event.dialog = ui.create.dialog(event.str, cards); + event.dialogid = lib.status.videoId++; + event.dialog.videoId = event.dialogid; + + if (event.hiddencards) { + for (var i = 0; i < event.dialog.buttons.length; i++) { + if (event.hiddencards.includes(event.dialog.buttons[i].link)) { + event.dialog.buttons[i].className = "button card"; + event.dialog.buttons[i].innerHTML = ""; + } + } + } + game.broadcast( + function (str, cards, cards2, id) { + var dialog = ui.create.dialog(str, cards); + dialog.forcebutton = true; + dialog.videoId = id; + if (cards2) { + for (var i = 0; i < dialog.buttons.length; i++) { + if (cards2.includes(dialog.buttons[i].link)) { + dialog.buttons[i].className = "button card"; + dialog.buttons[i].innerHTML = ""; + } + } + } + }, + event.str, + cards, + event.hiddencards, + event.dialogid + ); + if (event.hiddencards) { + var cards2 = cards.slice(0); + for (var i = 0; i < event.hiddencards.length; i++) { + cards2.remove(event.hiddencards[i]); + } + game.log(player, "展示了", cards2); + } else { + game.log(player, "展示了", cards); + } + game.addCardKnower(cards, "everyone"); + game.delayx(event.delay_time || 2.5); + game.addVideo("showCards", player, [event.str, get.cardsInfo(cards)]); + "step 1"; + game.broadcast("closeDialog", event.dialogid); + event.dialog.close(); + }, + viewCards: function () { + "step 0"; + game.addCardKnower(event.cards, player); + if (player == game.me) { + event.dialog = ui.create.dialog(event.str, event.cards); + if (event.isMine()) { + game.pause(); + ui.create.confirm("o"); + game.countChoose(); + event.choosing = true; + } else { + event.finish(); + event.result = "viewed"; + setTimeout(function () { + event.dialog.close(); + }, 2 * lib.config.duration); + game.delayx(2); + } + } else if (event.isOnline()) { + event.send(); + } else { + event.finish(); + } + "step 1"; + event.result = "viewed"; + _status.imchoosing = false; + event.choosing = false; + if (event.dialog) event.dialog.close(); + }, + moveCard: function () { + "step 0"; + if ( + !player.canMoveCard( + null, + event.nojudge, + event.sourceTargets, + event.aimTargets, + event.filter, + event.canReplace ? "canReplace" : "noReplace" + ) + ) { + event.finish(); + return; + } + var next = player.chooseTarget(2, function (card, player, target) { + var filterCard = get.event("filter"); + if (ui.selected.targets.length) { + if (!get.event("aimTargets").includes(target)) return false; + var from = ui.selected.targets[0]; + var js = from.getCards("j", filterCard); + for (var i = 0; i < js.length; i++) { + if (_status.event.nojudge) break; + if (target.canAddJudge(js[i])) return true; + } + if (target.isMin()) return false; + var es = from.getCards("e", filterCard); + for (var i = 0; i < es.length; i++) { + if (target.canEquip(es[i], _status.event.canReplace)) return true; + } + return false; + } else { + if (!get.event("sourceTargets").includes(target)) return false; + var range = "ej"; + if (_status.event.nojudge) range = "e"; + return target.countCards(range, filterCard) > 0; + } + }); + next.set("nojudge", event.nojudge || false); + next.set("ai", function (target) { + var player = _status.event.player; + var att = get.attitude(player, target); + var sgnatt = get.sgn(att); + var aimTargets = get.event("aimTargets"), + filterCard = get.event("filter"); + if (ui.selected.targets.length == 0) { + if (att > 0) { + if ( + !_status.event.nojudge && + target.countCards("j", function (card) { + if (!filterCard(card)) return false; + return game.hasPlayer(function (current) { + if (!aimTargets.includes(current)) return false; + return ( + current != target && + current.canAddJudge(card) && + get.attitude(player, current) < 0 + ); + }); + }) + ) + return 14; + if ( + target.countCards("e", function (card) { + if (!filterCard(card)) return false; + return ( + get.value(card, target) < 0 && + game.hasPlayer(function (current) { + if (!aimTargets.includes(current)) return false; + return ( + current != target && + get.attitude(player, current) < 0 && + current.canEquip(card, _status.event.canReplace) && + get.effect(target, card, player, player) < 0 + ); + }) + ); + }) > 0 + ) + return 9; + } else if (att < 0) { + if ( + game.hasPlayer(function (current) { + if (current != target && get.attitude(player, current) > 0) { + var es = target.getCards("e", filterCard); + for (var i = 0; i < es.length; i++) { + if ( + get.value(es[i], target) > 0 && + current.canEquip(es[i], _status.event.canReplace) && + get.effect(current, es[i], player, player) > + (_status.event.canReplace + ? get.effect(target, es[i], player, player) + : 0) + ) + return true; + } + } + }) + ) { + return -att; + } + } + return 0; + } + var es = ui.selected.targets[0].getCards("e", filterCard); + var i; + var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); + for (i = 0; i < es.length; i++) { + if ( + sgnatt != 0 && + att2 != 0 && + sgnatt != att2 && + get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && + get.sgn(get.effect(target, es[i], player, target)) == sgnatt && + target.canEquip(es[i], _status.event.canReplace) + ) { + return Math.abs(att); + } + } + if ( + i == es.length && + (_status.event.nojudge || + !ui.selected.targets[0].countCards("j", function (card) { + if (!filterCard(card)) return false; + return target.canAddJudge(card); + }) || + att2 <= 0) + ) { + return 0; + } + return -att * att2; + }); + next.set("multitarget", true); + next.set("targetprompt", _status.event.targetprompt || ["被移走", "移动目标"]); + next.set("prompt", event.prompt || "移动场上的一张牌"); + next.set("filter", event.filter); + next.set("sourceTargets", event.sourceTargets || game.filterPlayer()); + next.set("aimTargets", event.aimTargets || game.filterPlayer()); + next.set("canReplace", event.canReplace); + next.set("custom", get.copy(event.custom)); + if (event.prompt2) next.set("prompt2", event.prompt2); + if (event.forced) next.set("forced", true); + "step 1"; + event.result = result; + if (result.bool) { + if (event.logSkill) player.logSkill(event.logSkill, result.targets, false); + player.line2(result.targets, "green"); + event.targets = result.targets; + } else { + event.finish(); + } + "step 2"; + game.delay(); + "step 3"; + if (targets.length == 2) { + player + .choosePlayerCard( + "ej", + true, + function (button) { + var player = _status.event.player; + var targets0 = _status.event.targets0; + var targets1 = _status.event.targets1; + if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) { + if (get.position(button.link) == "j") return 12; + if ( + get.value(button.link, targets0) < 0 && + get.effect(targets1, button.link, player, targets1) > 0 + ) + return 10; + return 0; + } else { + if (get.position(button.link) == "j") return -10; + return ( + get.value(button.link) * get.effect(targets1, button.link, player, targets1) + ); + } + }, + targets[0] + ) + .set("nojudge", event.nojudge || false) + .set("targets0", targets[0]) + .set("targets1", targets[1]) + .set("filterButton", function (button) { + var targets1 = _status.event.targets1; + if (!get.event("filter")(button.link)) return false; + if (get.position(button.link) == "j") { + if (_status.event.nojudge) return false; + return targets1.canAddJudge(button.link); + } else { + return targets1.canEquip(button.link, _status.event.canReplace); + } + }) + .set("filter", event.filter) + .set("canReplace", event.canReplace) + .set("custom", get.copy(event.custom)); + } else { + event.finish(); + } + "step 4"; + if (result.bool && result.links.length) { + var link = result.links[0]; + if (get.position(link) == "e") { + event.targets[1].equip(link); + } else if (link.viewAs) { + event.targets[1].addJudge({ name: link.viewAs }, [link]); + } else { + event.targets[1].addJudge(link); + } + event.targets[0].$give(link, event.targets[1], false); + game.log(event.targets[0], "的", link, "被移动给了", event.targets[1]); + event.result.card = link; + event.result.position = get.position(link); + game.delay(); + } + }, + useCard: function () { + "step 0"; + if (!card) { + console.log("err: no card", get.translation(event.player)); + event.finish(); + return; + } + if (!get.info(card, false).noForceDie) event.forceDie = true; + if (cards.length) { + var owner = get.owner(cards[0]) || player; + var next = owner.lose(cards, "visible", ui.ordering).set("type", "use"); + var directDiscard = []; + for (var i = 0; i < cards.length; i++) { + if (!next.cards.includes(cards[i])) { + directDiscard.push(cards[i]); + } + } + if (directDiscard.length) game.cardsGotoOrdering(directDiscard); + } + //player.using=cards; + var cardaudio = true; + if (event.skill) { + if (lib.skill[event.skill].audio) { + cardaudio = false; + } + if (lib.skill[event.skill].log != false) { + player.logSkill(event.skill); + } + if (get.info(event.skill).popname) { + player.tryCardAnimate(card, event.card.name, "metal", true); + } + } else if (!event.nopopup) { + if (lib.translate[event.card.name + "_pop"]) { + player.tryCardAnimate(card, lib.translate[event.card.name + "_pop"], "metal"); + } else { + player.tryCardAnimate(card, event.card.name, "metal"); + } + } + if (event.audio === false) { + cardaudio = false; + } + if (cardaudio) + game.broadcastAll( + (player, card) => { + game.playCardAudio(card, player); + }, + player, + card + ); + event.id = get.id(); + if (!Array.isArray(event.excluded)) event.excluded = []; + if (!Array.isArray(event.directHit)) event.directHit = []; + if (typeof event.customArgs != "object" || typeof event.customArgs.default != "object") + event.customArgs = { default: {} }; + if (typeof event.baseDamage != "number") event.baseDamage = get.info(card, false).baseDamage || 1; + if (typeof event.effectCount != "number") event.effectCount = get.info(card, false).effectCount || 1; + event.effectedCount = 0; + if (event.oncard) { + event.oncard(event.card, event.player); + } + player.actionHistory[player.actionHistory.length - 1].useCard.push(event); + game.getGlobalHistory().useCard.push(event); + if (event.addCount !== false) { + if (player.stat[player.stat.length - 1].card[card.name] == undefined) { + player.stat[player.stat.length - 1].card[card.name] = 1; + } else { + player.stat[player.stat.length - 1].card[card.name]++; + } + } + if (event.skill) { + if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { + player.stat[player.stat.length - 1].skill[event.skill] = 1; + } else { + player.stat[player.stat.length - 1].skill[event.skill]++; + } + var sourceSkill = get.info(event.skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + + if (event.animate != false) { + if (event.throw !== false) { + player.$throw(cards); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + var waitingForTransition = get.time(); + event.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete event.waitingForTransition; + }); + } + } + } + event.trigger("useCard0"); + "step 1"; + if (event.animate != false && event.line != false && !event.hideTargets) { + if (card.name == "wuxie" && event.getParent()._info_map) { + var evtmap = event.getParent()._info_map; + if (evtmap._source) evtmap = evtmap._source; + var lining = (evtmap.multitarget ? evtmap.targets : evtmap.target) || event.player; + if (Array.isArray(lining) && event.getTrigger().name == "jiedao") { + player.line(lining[0], "green"); + } else { + player.line(lining, "green"); + } + } else if (card.name == "youdishenru" && event.getParent().source) { + var lining = + event.getParent().sourcex || event.getParent().source2 || event.getParent().source; + if (lining == player && event.getParent().sourcex2) { + lining = event.getParent().sourcex2; + } + if (Array.isArray(lining) && event.getTrigger().name == "jiedao") { + player.line(lining[0], "green"); + } else { + player.line(lining, "green"); + } + } else { + var config = {}; + var nature = get.natureList(card)[0]; + if (nature || (card.classList && card.classList.contains(nature))) config.color = nature; + if (event.addedTarget) { + player.line2(targets.concat(event.addedTargets), config); + } else if ( + get.info(card, false).multitarget && + targets.length > 1 && + !get.info(card, false).multiline + ) { + player.line2(targets, config); + } else { + player.line(targets, config); + } + } + } + if (targets.length && !event.hideTargets) { + var str = targets.length == 1 && targets[0] == player ? "#b自己" : targets; + if (cards.length && !card.isCard) { + if (event.addedTarget) { + game.log( + player, + "对", + str, + "使用了", + card, + "(", + cards, + ",指向", + event.addedTargets, + ")" + ); + } else { + game.log(player, "对", str, "使用了", card, "(", cards, ")"); + } + } else { + if (event.addedTarget) { + game.log(player, "对", str, "使用了", card, "(指向", event.addedTargets, ")"); + } else { + game.log(player, "对", str, "使用了", card); + } + } + } else { + if (cards.length && !card.isCard) { + if (event.addedTarget) { + game.log(player, "使用了", card, "(", cards, ",指向", event.addedTargets, ")"); + } else { + game.log(player, "使用了", card, "(", cards, ")"); + } + } else { + if (event.addedTarget) { + game.log(player, "使用了", card, "(指向", event.addedTargets, ")"); + } else { + game.log(player, "使用了", card); + } + } + } + if (card.name == "wuxie") { + game.logv(player, [card, cards], [event.getTrigger().card]); + } else { + game.logv(player, [card, cards], targets); + } + event.trigger("useCard1"); + "step 2"; + event.trigger("yingbian"); + "step 3"; + event.trigger("useCard2"); + "step 4"; + event.trigger("useCard"); + event._oncancel = function () { + game.broadcastAll(function (id) { + if (ui.tempnowuxie && ui.tempnowuxie._origin == id) { + ui.tempnowuxie.close(); + delete ui.tempnowuxie; + } + }, event.id); + }; + "step 5"; + event.sortTarget = function (animate, sort) { + var info = get.info(card, false); + if (num == 0 && targets.length > 1) { + if (!info.multitarget) { + if (!event.fixedSeat && !sort) { + targets.sortBySeat(_status.currentPhase || player); + } + if (animate) + for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass("target"); + } + } else if (animate) { + for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass("target"); + } + } + } + }; + event.sortTarget(); + event.getTriggerTarget = function (list1, list2) { + var listx = list1.slice(0).sortBySeat(_status.currentPhase || player); + for (var i = 0; i < listx.length; i++) { + if (get.numOf(list2, listx[i]) < get.numOf(listx, listx[i])) return listx[i]; + } + return null; + }; + "step 6"; + if (event.all_excluded) return; + if (!event.triggeredTargets1) event.triggeredTargets1 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets1); + if (target) { + event.triggeredTargets1.push(target); + var next = game.createEvent("useCardToPlayer", false); + if (!event.isFirstTarget1) { + event.isFirstTarget1 = true; + next.isFirstTarget = true; + } + next.setContent("emptyEvent"); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 7"; + if (event.all_excluded) return; + if (!event.triggeredTargets2) event.triggeredTargets2 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets2); + if (target) { + event.triggeredTargets2.push(target); + var next = game.createEvent("useCardToTarget", false); + if (!event.isFirstTarget2) { + event.isFirstTarget2 = true; + next.isFirstTarget = true; + } + next.setContent("emptyEvent"); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 8"; + var info = get.info(card, false); + if (!info.nodelay && event.animate != false) { + if (event.delayx !== false) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } else { + game.delayx(); + } + } + } + "step 9"; + if (event.all_excluded) return; + if (!event.triggeredTargets3) event.triggeredTargets3 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets3); + if (target) { + event.triggeredTargets3.push(target); + var next = game.createEvent("useCardToPlayered", false); + if (!event.isFirstTarget3) { + event.isFirstTarget3 = true; + next.isFirstTarget = true; + } + next.setContent("emptyEvent"); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + event.redo(); + } + "step 10"; + if (event.all_excluded) return; + if (!event.triggeredTargets4) event.triggeredTargets4 = []; + var target = event.getTriggerTarget(targets, event.triggeredTargets4); + if (target) { + event.triggeredTargets4.push(target); + var next = game.createEvent("useCardToTargeted", false); + if (!event.isFirstTarget4) { + event.isFirstTarget4 = true; + next.isFirstTarget = true; + } + next.setContent("emptyEvent"); + next.targets = targets; + next.target = target; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.excluded = event.excluded; + next.directHit = event.directHit; + next.customArgs = event.customArgs; + if (event.forceDie) next.forceDie = true; + if (targets.length == event.triggeredTargets4.length) { + event.sortTarget(); + } + event.redo(); + } + "step 11"; + if (event.all_excluded) return; + event.effectedCount++; + event.num = 0; + var info = get.info(card, false); + if (info.contentBefore) { + var next = game.createEvent(card.name + "ContentBefore"); + next.setContent(info.contentBefore); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = "precard"; + if (event.forceDie) next.forceDie = true; + } else if (info.reverseOrder && get.is.versus() && targets.length > 1) { + var next = game.createEvent(card.name + "ContentBefore"); + next.setContent("reverseOrder"); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = "precard"; + if (event.forceDie) next.forceDie = true; + } else if ( + info.singleCard && + info.filterAddedTarget && + event.addedTargets && + event.addedTargets.length < targets.length + ) { + var next = game.createEvent(card.name + "ContentBefore"); + next.setContent("addExtraTarget"); + next.target = target; + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.type = "precard"; + next.addedTarget = event.addedTarget; + next.addedTargets = event.addedTargets; + if (event.forceDie) next.forceDie = true; + } + "step 12"; + if (event.all_excluded) return; + var info = get.info(card, false); + if (num == 0 && targets.length > 1) { + event.sortTarget(true, true); + } + if (targets[num] && targets[num].isDead()) return; + if (targets[num] && targets[num].isOut()) return; + if (targets[num] && targets[num].removed) return; + if (targets[num] && info.ignoreTarget && info.ignoreTarget(card, player, targets[num])) return; + if (targets.length == 0 && !info.notarget) return; + if (targets[num] && event.excluded.includes(targets[num])) { + var next = game.createEvent("useCardToExcluded", false); + next.setContent("emptyEvent"); + next.targets = targets; + next.target = targets[num]; + next.num = num; + next.card = card; + next.cards = cards; + next.player = player; + return; + } + var next = game.createEvent(card.name); + next.setContent(info.content); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.num = num; + next.type = "card"; + next.skill = event.skill; + next.multitarget = info.multitarget; + next.preResult = event.preResult; + next.baseDamage = event.baseDamage; + if (event.forceDie) next.forceDie = true; + if (event.addedTargets) { + next.addedTargets = event.addedTargets; + next.addedTarget = event.addedTargets[num]; + next._targets = event._targets; + } + if (info.targetDelay === false) { + event.targetDelay = false; + } + next.target = targets[num]; + for (var i in event.customArgs.default) next[i] = event.customArgs.default[i]; + if (next.target && event.customArgs[next.target.playerid]) { + var customArgs = event.customArgs[next.target.playerid]; + for (var i in customArgs) next[i] = customArgs[i]; + } + if (next.target && event.directHit.includes(next.target)) next.directHit = true; + if (next.target && !info.multitarget) { + if (num == 0 && targets.length > 1) { + // var ttt=next.target; + // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); + } else { + next.target.addTempClass("target"); + } + } + if (!info.nodelay && num > 0) { + if (event.targetDelay !== false) { + game.delayx(0.5); + } + } + "step 13"; + if (event.all_excluded) return; + if (!get.info(event.card, false).multitarget && num < targets.length - 1 && !event.cancelled) { + event.num++; + event.goto(12); + } + "step 14"; + if (event.all_excluded) return; + if (get.info(card, false).contentAfter) { + var next = game.createEvent(card.name + "ContentAfter"); + next.setContent(get.info(card, false).contentAfter); + next.targets = targets; + next.card = card; + next.cards = cards; + next.player = player; + next.skill = event.skill; + next.preResult = event.preResult; + next.type = "postcard"; + if (event.forceDie) next.forceDie = true; + } + "step 15"; + if (event.all_excluded) return; + if (event.effectedCount < event.effectCount) { + if (document.getElementsByClassName("thrown").length) { + if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); + } + event.goto(11); + } + "step 16"; + if (event.postAi) { + event.player.logAi(event.targets, event.card); + } + if (event._result) { + event.result = event._result; + } + //delete player.using; + if (document.getElementsByClassName("thrown").length) { + if (event.delayx !== false && get.info(event.card, false).finalDelay !== false) game.delayx(); + } else { + event.finish(); + } + "step 17"; + event._oncancel(); + }, + useSkill: function () { + "step 0"; + var info = get.info(event.skill); + if (!info.noForceDie) event.forceDie = true; + if (!info.noForceOut) event.includeOut = true; + event._skill = event.skill; + game.trySkillAudio(event.skill, player); + var checkShow = player.checkShow(event.skill); + if (info.discard != false && info.lose != false && !info.viewAs) { + player.discard(cards).delay = false; + if (lib.config.low_performance) { + event.discardTransition = true; + } + } else { + if (info.lose != false) { + if (info.losetrigger == false) { + var losecard = (player.lose(cards, ui.special)._triggered = null); + } else { + var losecard = player.lose(cards, ui.special); + if (info.visible) losecard.visible = true; + if (info.loseTo) losecard.position = ui[info.loseTo]; + if (info.insert) losecard.insert_card = true; + if (losecard.position == ui.special && info.toStorage) losecard.toStorage = true; + } + } + if (!info.prepare && info.viewAs) { + player.$throw(cards); + if (losecard) losecard.visible = true; + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + var waitingForTransition = get.time(); + event.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete event.waitingForTransition; + }); + } + } + } + if (info.line != false && targets.length) { + var config = {}; + if (get.is.object(info.line)) config = info.line; + else if (info.line == "fire") { + config.color = "fire"; + } else if (info.line == "thunder") { + config.color = "thunder"; + } else if (info.line === undefined || info.line == "green") { + config.color = "green"; + } + if (info.multitarget && !info.multiline && targets.length > 1) { + player.line2(targets, config); + } else { + player.line(targets, config); + } + } + var str = ""; + if (targets && targets.length && info.log != "notarget") { + str += + '对' + (targets[0] == player ? "自己" : get.translation(targets[0])); + for (var i = 1; i < targets.length; i++) { + str += "、" + (targets[i] == player ? "自己" : get.translation(targets[i])); + } + str += ""; + } + str += "发动了"; + if (!info.direct && info.log !== false) { + game.log(player, str, "【" + get.skillTranslation(skill, player) + "】"); + if (info.logv !== false) game.logv(player, skill, targets); + player.trySkillAnimate(skill, skill, checkShow); + } + if (event.addCount != false) { + if (player.stat[player.stat.length - 1].skill[skill] == undefined) { + player.stat[player.stat.length - 1].skill[skill] = 1; + } else { + player.stat[player.stat.length - 1].skill[skill]++; + } + var sourceSkill = get.info(skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + if (player.stat[player.stat.length - 1].allSkills == undefined) { + player.stat[player.stat.length - 1].allSkills = 1; + } else { + player.stat[player.stat.length - 1].allSkills++; + } + if (info.prepare) { + switch (info.prepare) { + case "give": + if (losecard) losecard.visible = true; + player.$give(cards, targets[0]); + break; + case "give2": + player.$give(cards.length, targets[0]); + break; + case "throw": + if (losecard) losecard.visible = true; + player.$throw(cards); + break; + case "throw2": + player.$throw(cards.length); + break; + default: + info.prepare(cards, player, targets); + } + } + if (info.round) { + var roundname = skill + "_roundcount"; + player.storage[roundname] = game.roundNumber; + player.syncStorage(roundname); + player.markSkill(roundname); + } + var name = event.skill; + var players = player.getSkills(false, false, false); + var equips = player.getSkills("e"); + var global = lib.skill.global.slice(0); + var logInfo = { + skill: name, + targets: targets, + event: _status.event, + }; + if (info.sourceSkill) { + logInfo.sourceSkill = info.sourceSkill; + if (global.includes(info.sourceSkill)) { + logInfo.type = "global"; + } else if (players.includes(info.sourceSkill)) { + logInfo.type = "player"; + } else if (equips.includes(info.sourceSkill)) { + logInfo.type = "equip"; + } + } else { + if (global.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "global"; + } else if (players.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "player"; + } else if (equips.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "equip"; + } else { + var bool = false; + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + bool = true; + logInfo.sourceSkill = i; + logInfo.type = "player"; + break; + } + } + if (!bool) { + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + logInfo.sourceSkill = i; + logInfo.type = "equip"; + break; + } + } + } + } + } + event.sourceSkill = logInfo.sourceSkill; + event.type = logInfo.type; + player.getHistory("useSkill").push(logInfo); + event.trigger("useSkill"); + "step 1"; + var info = get.info(event.skill); + if (info && info.contentBefore) { + var next = game.createEvent(event.skill + "ContentBefore"); + next.setContent(info.contentBefore); + next.targets = targets; + next.cards = cards; + next.player = player; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + } + "step 2"; + if (!event.skill) { + console.log("error: no skill", get.translation(event.player), event.player.getSkills()); + if (event._skill) { + event.skill = event._skill; + console.log(event._skill); + } else { + event.finish(); + return; + } + } + var info = get.info(event.skill); + if ( + (targets[num] && targets[num].isDead()) || + (targets[num] && targets[num].isOut()) || + (targets[num] && targets[num].removed) + ) { + if (!info.multitarget && num < targets.length - 1) { + event.num++; + event.redo(); + } + return; + } + var next = game.createEvent(event.skill); + next.setContent(info.content); + next.targets = targets; + next.cards = cards; + next.player = player; + next.num = num; + next.multitarget = info.multitarget; + if (num == 0 && next.targets.length > 1) { + if (!info.multitarget) { + lib.tempSortSeat = player; + targets.sort(lib.sort.seat); + delete lib.tempSortSeat; + } + for (var i = 0; i < targets.length; i++) { + targets[i].addTempClass("target"); + } + } + next.target = targets[num]; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + if (next.target && !info.multitarget) { + if (num == 0 && targets.length > 1) { + // var ttt=next.target; + // setTimeout(function(){ttt.addTempClass('target');},0.5*lib.config.duration); + } else { + next.target.addTempClass("target"); + } + } + if (num == 0) { + if (typeof info.delay == "number") game.delay(info.delay); + else if (info.delay !== false && info.delay !== 0) { + if (event.waitingForTransition) { + _status.waitingForTransition = event.waitingForTransition; + game.pause(); + } else { + game.delayx(); + } + } + } else game.delayx(0.5); + if (!info.multitarget && num < targets.length - 1) { + event.num++; + event.redo(); + } + "step 3"; + var info = get.info(event.skill); + if (info && info.contentAfter) { + var next = game.createEvent(event.skill + "ContentAfter"); + next.setContent(info.contentAfter); + next.targets = targets; + next.cards = cards; + next.player = player; + if (event.forceDie) next.forceDie = true; + if (event.includeOut) next.includeOut = true; + } + "step 4"; + if (player.getStat().allSkills > 200) { + player._noSkill = true; + console.log(player.name, event.skill); + } + if (document.getElementsByClassName("thrown").length) { + if (event.skill && get.info(event.skill).delay !== false && get.info(event.skill).delay !== 0) + game.delayx(); + } else { + event.finish(); + } + "step 5"; + ui.clear(); + }, + draw: function () { + // if(lib.config.background_audio){ + // game.playAudio('effect','draw'); + // } + // game.broadcast(function(){ + // if(lib.config.background_audio){ + // game.playAudio('effect','draw'); + // } + // }); + if (typeof event.minnum == "number" && num < event.minnum) { + num = event.minnum; + } + if (event.drawDeck) { + if (event.drawDeck > num) { + event.drawDeck = num; + } + num -= event.drawDeck; + } + if (event.log != false) { + if (num > 0) { + if (event.bottom) game.log(player, "从牌堆底摸了" + get.cnNumber(num) + "张牌"); + else game.log(player, "摸了" + get.cnNumber(num) + "张牌"); + } + if (event.drawDeck) { + game.log(player, "从牌库中获得了" + get.cnNumber(event.drawDeck) + "张牌"); + } + } + let cards; + if (num > 0) { + if (event.bottom) cards = get.bottomCards(num); + else if (player.getTopCards) cards = player.getTopCards(num); + else cards = get.cards(num); + } else { + cards = []; + } + if (event.drawDeck) { + cards = cards.concat(player.getDeckCards(event.drawDeck)); + } + let next; + if (event.animate != false) { + if (event.visible) { + next = player.gain(cards, "gain2"); + if (event.bottom) + game.log(player, "从牌堆底摸了" + get.cnNumber(num) + "张牌(", cards, ")"); + else game.log(player, "摸了" + get.cnNumber(num) + "张牌(", cards, ")"); + } else { + next = player.gain(cards, "draw"); + } + } else { + next = player.gain(cards); + if (event.$draw) { + player.$draw(cards.length); + } + } + if (event.gaintag) next.gaintag.addArray(event.gaintag); + event.result = cards; + }, + discard: function () { + "step 0"; + game.log(player, "弃置了", cards); + event.done = player.lose(cards, event.position, "visible"); + event.done.type = "discard"; + if (event.discarder) event.done.discarder = event.discarder; + "step 1"; + event.trigger("discard"); + }, + loseToDiscardpile: function () { + "step 0"; + if (event.log != false) game.log(player, "将", cards, "置入了弃牌堆"); + var next = player.lose(cards, event.position); + if (event.insert_index) next.insert_index = event.insert_index; + if (event.insert_card) next.insert_card = true; + if (!event.blank) next.visible = true; + next.type = "loseToDiscardpile"; + event.done = next; + "step 1"; + event.trigger("loseToDiscardpile"); + }, + respond: function () { + "step 0"; + var cardaudio = true; + if (event.skill) { + if (lib.skill[event.skill].audio) { + cardaudio = false; + } + player.logSkill(event.skill); + player.checkShow(event.skill, true); + if (lib.skill[event.skill].onrespond && !game.online) { + lib.skill[event.skill].onrespond(event, player); + } + } else if (!event.nopopup) player.tryCardAnimate(card, card.name, "wood"); + if (cardaudio && event.getParent(3).name == "useCard") + game.broadcastAll( + (player, card) => { + game.playCardAudio(card, player); + /* + if(!lib.config.background_audio) return; + const sex=player.sex=='female'?'female':'male',audio=lib.card[card.name].audio; + if(typeof audio=='string'){ + const audioInfo=audio.split(':'); + if(audio.startsWith('db:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,audioInfo[2],`${card.name}_${sex}.${audioInfo[3]||'mp3'}`); + else if(audio.startsWith('ext:')) game.playAudio(`${audioInfo[0]}:${audioInfo[1]}`,`${card.name}_${sex}.${audioInfo[2]||'mp3'}`); + else game.playAudio('card',sex,`${audioInfo[0]}.${audioInfo[1]||'mp3'}`); + } + else game.playAudio('card',sex,card.name);*/ + }, + player, + card + ); + if (event.skill) { + if (player.stat[player.stat.length - 1].skill[event.skill] == undefined) { + player.stat[player.stat.length - 1].skill[event.skill] = 1; + } else { + player.stat[player.stat.length - 1].skill[event.skill]++; + } + var sourceSkill = get.info(event.skill).sourceSkill; + if (sourceSkill) { + if (player.stat[player.stat.length - 1].skill[sourceSkill] == undefined) { + player.stat[player.stat.length - 1].skill[sourceSkill] = 1; + } else { + player.stat[player.stat.length - 1].skill[sourceSkill]++; + } + } + } + if (cards.length && (cards.length > 1 || cards[0].name != card.name)) { + game.log(player, "打出了", card, "(", cards, ")"); + } else { + game.log(player, "打出了", card); + } + player.actionHistory[player.actionHistory.length - 1].respond.push(event); + if (cards.length) { + var owner = get.owner(cards[0]) || player; + var next = owner.lose(cards, "visible", ui.ordering).set("type", "use"); + var directDiscard = []; + for (var i = 0; i < cards.length; i++) { + if (!next.cards.includes(cards[i])) { + directDiscard.push(cards[i]); + } + } + if (directDiscard.length) game.cardsGotoOrdering(directDiscard); + } + if (event.animate != false && event.throw !== false) { + for (var i = 0; i < cards.length; i++) { + player.$throw(cards[i]); + if (event.highlight) { + cards[i].clone.classList.add("thrownhighlight"); + game.addVideo("highlightnode", player, get.cardInfo(cards[i])); + } + } + if (event.highlight) { + game.broadcast(function (cards) { + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cards[i].clone.classList.add("thrownhighlight"); + } + } + }, cards); + } + } + event.trigger("respond"); + "step 1"; + game.delayx(0.5); + }, + swapHandcards: function () { + "step 0"; + event.cards1 = event.cards1 || player.getCards("h"); + event.cards2 = event.cards2 || target.getCards("h"); + game.loseAsync({ + player: player, + target: target, + cards1: event.cards1, + cards2: event.cards2, + }).setContent("swapHandcardsx"); + "step 1"; + game.loseAsync({ + gain_list: [ + [player, event.cards2.filterInD()], + [target, event.cards1.filterInD()], + ], + }).setContent("gaincardMultiple"); + "step 2"; + game.delayx(); + }, + swapHandcardsx: function () { + "step 0"; + player.$giveAuto(event.cards1, target); + target.$giveAuto(event.cards2, player); + "step 1"; + event.cards = event.cards1; + var next = player.lose(event.cards, ui.ordering); + next.getlx = false; + next.relatedEvent = event.getParent(); + if (player == game.me) { + event.delayed = true; + } else { + next.delay = false; + } + "step 2"; + event.cards = event.cards2; + var next = target.lose(event.cards, ui.ordering); + next.getlx = false; + next.relatedEvent = event.getParent(); + if (target == game.me) { + event.delayed = true; + } else { + next.delay = false; + } + "step 3"; + if (!event.delayed) game.delay(); + }, + gainMultiple: function () { + "step 0"; + event.delayed = false; + event.num = 0; + event.cards = []; + "step 1"; + player + .gainPlayerCard(targets[num], event.position, true) + .set("boolline", false) + .set("delay", num == targets.length - 1); + "step 2"; + if (result.bool) { + event.cards.addArray(result.cards); + if (num == targets.length - 1) event.delayed = true; + } + event.num++; + if (event.num < targets.length) { + event.goto(1); + } + "step 3"; + if (!event.delayed) game.delay(); + }, + gain: function () { + "step 0"; + if (event.animate == "give") event.visible = true; + if (cards) { + var map = {}; + for (var i of cards) { + var owner = get.owner(i, "judge"); + if (owner && (owner != player || get.position(i) != "h")) { + var id = owner.playerid; + if (!map[id]) map[id] = [[], [], []]; + map[id][0].push(i); + var position = get.position(i); + if (position == "h") map[id][1].push(i); + else map[id][2].push(i); + } else if (!event.updatePile && get.position(i) == "c") event.updatePile = true; + } + event.losing_map = map; + for (var i in map) { + var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + var next = owner + .lose(map[i][0], ui.special) + .set("type", "gain") + .set("forceDie", true) + .set("getlx", false); + if (event.visible == true) { + next.visible = true; + } + event.relatedLose = next; + } + } else { + event.finish(); + } + "step 1"; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed("handcard", player, event)) { + cards[i].selfDestroy(event); + cards.splice(i--, 1); + } else if (event.losing_map) { + for (var id in event.losing_map) { + if (event.losing_map[id][0].includes(cards[i])) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; + var hs = source.getCards("hejsx"); + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } else { + cards[i].addKnower(event.visible ? "everyone" : source); + } + } + } + } + } + if (cards.length == 0) { + event.finish(); + return; + } + player.getHistory("gain").push(event); + //if(event.source&&event.delay!==false) game.delayx(); + "step 2"; + if (player.getStat().gain == undefined) { + player.getStat().gain = cards.length; + } else { + player.getStat().gain += cards.length; + } + "step 3"; + var sort; + var frag1 = document.createDocumentFragment(); + var frag2 = document.createDocumentFragment(); + var hs = player.getCards("hs"); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var num = 0; num < cards.length; num++) { + sort = lib.config.sort_card(cards[num]); + if (lib.config.reverse_sort) sort = -sort; + if (["o", "d"].includes(get.position(cards[num], true))) { + cards[num].addKnower("everyone"); + } + cards[num].fix(); + cards[num].style.transform = ""; + cards[num].addGaintag(event.gaintag); + if (event.knowers) { + cards[num].addKnower(event.knowers); //添加事件设定的知情者。 + } + if (_status.discarded) { + _status.discarded.remove(cards[num]); + } + // cards[num].vanishtag.length=0; + for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { + if (cards[num].vanishtag[num2][0] != "_") { + cards[num].vanishtag.splice(num2--, 1); + } + } + if (player == game.me) { + cards[num].classList.add("drawinghidden"); + } + if (get.is.singleHandcard() || sort > 1) frag1.appendChild(cards[num]); + else frag2.appendChild(cards[num]); + } + var addv = function () { + if (player == game.me) { + game.addVideo("gain12", player, [ + get.cardsInfo(frag1.childNodes), + get.cardsInfo(frag2.childNodes), + event.gaintag, + ]); + } + }; + var broadcast = function () { + game.broadcast( + function (player, cards, num, gaintag) { + player.directgain(cards, null, gaintag); + _status.cardPileNum = num; + }, + player, + cards, + ui.cardPile.childNodes.length, + event.gaintag + ); + }; + if (event.animate == "draw") { + player.$draw(cards.length); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(500, 500)); + } else if (event.animate == "gain") { + player.$gain(cards, event.log); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(700, 700)); + } else if (event.animate == "gain2" || event.animate == "draw2") { + var gain2t = 300; + if (player.$gain2(cards, event.log) && player == game.me) { + gain2t = 500; + } + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(gain2t, gain2t)); + } else if (event.animate == "give" || event.animate == "giveAuto") { + var evtmap = event.losing_map; + if (event.animate == "give") { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + source.$give(evtmap[i][0], player, event.log); + } + } else { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (evtmap[i][1].length) source.$giveAuto(evtmap[i][1], player, event.log); + if (evtmap[i][2].length) source.$give(evtmap[i][2], player, event.log); + } + } + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(500, 500)); + } else if (typeof event.animate == "function") { + var time = event.animate(event); + game.pause(); + setTimeout(function () { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + game.resume(); + }, get.delayx(time, time)); + } else { + addv(); + player.node.handcards1.insertBefore(frag1, player.node.handcards1.firstChild); + player.node.handcards2.insertBefore(frag2, player.node.handcards2.firstChild); + player.update(); + if (player == game.me) ui.updatehl(); + broadcast(); + event.finish(); + } + "step 4"; + game.delayx(); + if (event.updatePile) game.updateRoundNumber(); + }, + addToExpansion: function () { + "step 0"; + if (event.animate == "give") event.visible = true; + if (cards) { + var map = {}; + for (var i of cards) { + var owner = get.owner(i, "judge"); + if (owner && (owner != player || get.position(i) != "x")) { + var id = owner.playerid; + if (!map[id]) map[id] = [[], [], []]; + map[id][0].push(i); + var position = get.position(i); + if (position == "h") map[id][1].push(i); + else map[id][2].push(i); + } else if (!event.updatePile && get.position(i) == "c") event.updatePile = true; + } + event.losing_map = map; + for (var i in map) { + var owner = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + var next = owner + .lose(map[i][0], ui.special) + .set("type", "loseToExpansion") + .set("forceDie", true) + .set("getlx", false); + if (event.visible == true) next.visible = true; + event.relatedLose = next; + } + } else { + event.finish(); + } + "step 1"; + for (var i = 0; i < cards.length; i++) { + if (cards[i].willBeDestroyed("expansion", player, event)) { + cards[i].selfDestroy(event); + cards.splice(i--, 1); + } else if (event.losing_map) { + for (var id in event.losing_map) { + if (event.losing_map[id][0].includes(cards[i])) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[id]; + var hs = source.getCards("hejsx"); + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + } + } + } + if (cards.length == 0) { + event.finish(); + return; + } + "step 2"; + var hs = player.getCards("x"); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var num = 0; num < cards.length; num++) { + if (_status.discarded) { + _status.discarded.remove(cards[num]); + } + for (var num2 = 0; num2 < cards[num].vanishtag.length; num2++) { + if (cards[num].vanishtag[num2][0] != "_") { + cards[num].vanishtag.splice(num2--, 1); + } + } + } + if (event.animate == "draw") { + player.$draw(cards.length); + if (event.log) game.log(player, "将", get.cnNumber(cards.length), "张牌置于了武将牌上"); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(500, 500)); + } else if (event.animate == "gain") { + player.$gain(cards, false); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(700, 700)); + } else if (event.animate == "gain2" || event.animate == "draw2") { + var gain2t = 300; + if (player.$gain2(cards) && player == game.me) { + gain2t = 500; + } + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(gain2t, gain2t)); + } else if (event.animate == "give" || event.animate == "giveAuto") { + var evtmap = event.losing_map; + if (event.animate == "give") { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + source.$give(evtmap[i][0], player, false); + if (event.log) game.log(player, "将", evtmap[i][0], "置于了武将牌上"); + } + } else { + for (var i in evtmap) { + var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; + if (evtmap[i][1].length) { + source.$giveAuto(evtmap[i][1], player, false); + if (event.log) + game.log(player, "将", get.cnNumber(evtmap[i][1].length), "张牌置于了武将牌上"); + } + if (evtmap[i][2].length) { + source.$give(evtmap[i][2], player, false); + if (event.log) game.log(player, "将", evtmap[i][2], "置于了武将牌上"); + } + } + } + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(500, 500)); + } else if (typeof event.animate == "function") { + var time = event.animate(event); + game.pause(); + setTimeout(function () { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + game.resume(); + }, get.delayx(time, time)); + } else { + player.$addToExpansion(cards, null, event.gaintag); + for (var i of event.gaintag) player.markSkill(i); + event.finish(); + } + "step 4"; + game.delayx(); + if (event.updatePile) game.updateRoundNumber(); + }, + lose: function () { + "step 0"; + var evt = event.getParent(); + if ( + (evt.name != "discard" || event.type != "discard") && + (evt.name != "loseToDiscardpile" || event.type != "loseToDiscardpile") + ) { + event.delay = false; + return; + } + if (evt.delay === false) event.delay = false; + if (evt.animate != false) { + evt.discardid = lib.status.videoId++; + game.broadcastAll( + function (player, cards, id, visible) { + player.$throw(cards, null, "nobroadcast"); + var cardnodes = []; + cardnodes._discardtime = get.time(); + for (var i = 0; i < cards.length; i++) { + if (cards[i].clone) { + cardnodes.push(cards[i].clone); + if (!visible) { + cards[i].clone.classList.add("infohidden"); + cards[i].clone.classList.add("infoflip"); + } + } + } + ui.todiscard[id] = cardnodes; + }, + player, + cards, + evt.discardid, + event.visible + ); + if (lib.config.sync_speed && cards[0] && cards[0].clone) { + if (evt.delay != false) { + var waitingForTransition = get.time(); + evt.waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.waitingForTransition; + }); + } else if (evt.getParent().discardTransition) { + delete evt.getParent().discardTransition; + var waitingForTransition = get.time(); + evt.getParent().waitingForTransition = waitingForTransition; + cards[0].clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + delete evt.getParent().waitingForTransition; + }); + } + } + } + "step 1"; + event.gaintag_map = {}; + var hs = [], + es = [], + js = [], + ss = [], + xs = []; + var unmarks = []; + if (event.insert_card && event.position == ui.cardPile) event.cards.reverse(); + var hej = player.getCards("hejsx"); + event.stockcards = cards.slice(0); + for (var i = 0; i < cards.length; i++) { + if (!hej.includes(cards[i])) { + cards.splice(i--, 1); + continue; + } else if (cards[i].parentNode) { + if (cards[i].parentNode.classList.contains("equips")) { + cards[i].original = "e"; + es.push(cards[i]); + } else if (cards[i].parentNode.classList.contains("judges")) { + cards[i].original = "j"; + js.push(cards[i]); + } else if (cards[i].parentNode.classList.contains("expansions")) { + cards[i].original = "x"; + xs.push(cards[i]); + if (cards[i].gaintag && cards[i].gaintag.length) unmarks.addArray(cards[i].gaintag); + } else if (cards[i].parentNode.classList.contains("handcards")) { + if (cards[i].classList.contains("glows")) { + cards[i].original = "s"; + ss.push(cards[i]); + } else { + cards[i].original = "h"; + hs.push(cards[i]); + } + } else { + cards[i].original = null; + } + } + if (cards[i].gaintag && cards[i].gaintag.length) { + event.gaintag_map[cards[i].cardid] = cards[i].gaintag.slice(0); + cards[i].removeGaintag(true); + } + + cards[i].style.transform += " scale(0.2)"; + cards[i].classList.remove("glow"); + cards[i].classList.remove("glows"); + cards[i].recheck(); + + var info = lib.card[cards[i].name]; + if ("_destroy" in cards[i]) { + if (cards[i]._destroy) { + cards[i].delete(); + cards[i].destroyed = cards[i]._destroy; + continue; + } + } else if ("destroyed" in cards[i]) { + if ( + event.getlx !== false && + event.position && + cards[i].willBeDestroyed(event.position.id, null, event) + ) { + cards[i].selfDestroy(event); + continue; + } + } else if (info.destroy) { + cards[i].delete(); + cards[i].destroyed = info.destroy; + continue; + } + if (event.position) { + if (_status.discarded) { + if (event.position == ui.discardPile) { + _status.discarded.add(cards[i]); + } else { + _status.discarded.remove(cards[i]); + } + } + if (event.insert_index) { + cards[i].fix(); + event.position.insertBefore(cards[i], event.insert_index(event, cards[i])); + } else if (event.insert_card) { + cards[i].fix(); + event.position.insertBefore(cards[i], event.position.firstChild); + } else if (event.position == ui.cardPile) { + cards[i].fix(); + event.position.appendChild(cards[i]); + } else cards[i].goto(event.position); + } else { + cards[i].remove(); + } + //if(ss.includes(cards[i])) cards.splice(i--,1); + } + if (player == game.me) ui.updatehl(); + ui.updatej(player); + game.broadcast( + function (player, cards, num) { + for (var i = 0; i < cards.length; i++) { + cards[i].classList.remove("glow"); + cards[i].classList.remove("glows"); + cards[i].fix(); + cards[i].remove(); + } + if (player == game.me) { + ui.updatehl(); + } + ui.updatej(player); + _status.cardPileNum = num; + }, + player, + cards, + ui.cardPile.childNodes.length + ); + game.addVideo("lose", player, [ + get.cardsInfo(hs), + get.cardsInfo(es), + get.cardsInfo(js), + get.cardsInfo(ss), + ]); + event.cards2 = hs.concat(es); + player.getHistory("lose").push(event); + game.getGlobalHistory().cardMove.push(event); + player.update(); + game.addVideo("loseAfter", player); + event.num = 0; + if (event.position == ui.ordering) { + var evt = event.relatedEvent || event.getParent(); + if (!evt.orderingCards) evt.orderingCards = []; + if (!evt.noOrdering && !evt.cardsOrdered) { + evt.cardsOrdered = true; + var next = game.createEvent("orderingDiscard", false); + event.next.remove(next); + evt.after.push(next); + next.relatedEvent = evt; + next.setContent("orderingDiscard"); + } + if (!evt.noOrdering) { + evt.orderingCards.addArray(cards); + } + } else if (event.position == ui.cardPile) { + game.updateRoundNumber(); + } + if (unmarks.length) { + for (var i of unmarks) { + player[ + (lib.skill[i] && lib.skill[i].mark) || player.hasCard((card) => card.hasGaintag(i), "x") + ? "markSkill" + : "unmarkSkill" + ](i); + } + } + event.hs = hs; + event.es = es; + event.js = js; + event.ss = ss; + event.xs = xs; + game.clearCardKnowers(hs); + if (hs.length && !event.visible) { + player.getCards("h").forEach((hcard) => { + hcard.clearKnowers(); + }); + } + "step 2"; + if (num < cards.length) { + if (event.es.includes(cards[num])) { + event.loseEquip = true; + player.removeEquipTrigger(cards[num]); + var info = get.info(cards[num]); + if (info.onLose && (!info.filterLose || info.filterLose(cards[num], player))) { + event.goto(3); + return; + } + } + event.num++; + event.redo(); + } else { + if (event.loseEquip) { + player.addEquipTrigger(); + } + event.goto(4); + } + "step 3"; + var info = get.info(cards[num]); + if (info.loseDelay != false && (player.isAlive() || info.forceDie)) { + player.popup(cards[num].name); + game.delayx(); + } + if (Array.isArray(info.onLose)) { + for (var i = 0; i < info.onLose.length; i++) { + var next = game.createEvent("lose_" + cards[num].name); + next.setContent(info.onLose[i]); + if (info.forceDie) next.forceDie = true; + next.player = player; + next.card = cards[num]; + } + } else { + var next = game.createEvent("lose_" + cards[num].name); + next.setContent(info.onLose); + next.player = player; + if (info.forceDie) next.forceDie = true; + next.card = cards[num]; + } + event.num++; + event.goto(2); + "step 4"; + if (event.toRenku) { + _status.renku.addArray( + cards.filter(function (card) { + return !card.willBeDestroyed("renku", null, event); + }) + ); + if (_status.renku.length > 6) { + var cards = _status.renku.splice(0, _status.renku.length - 6); + game.log(cards, "从仁库进入了弃牌堆"); + game.cardsDiscard(cards).set("outRange", true).fromRenku = true; + } + game.updateRenku(); + } + "step 5"; + var evt = event.getParent(); + if ( + evt.name != "discard" && + event.type != "discard" && + evt.name != "loseToDiscardpile" && + event.type != "loseToDiscardpile" + ) + return; + if (event.animate === false || event.delay === false) return; + if (evt.delay != false) { + if (evt.waitingForTransition) { + _status.waitingForTransition = evt.waitingForTransition; + game.pause(); + } else { + game.delayx(); + } + } + }, + damage: function () { + "step 0"; + event.forceDie = true; + if (event.unreal) { + event.goto(4); + return; + } + event.trigger("damageBegin1"); + "step 1"; + event.trigger("damageBegin2"); + "step 2"; + event.trigger("damageBegin3"); + "step 3"; + event.trigger("damageBegin4"); + "step 4"; + //moved changeHujia to changeHp + if (player.hujia > 0 && !player.hasSkillTag("nohujia")) { + var damageAudioInfo = lib.natureAudio.hujia_damage[event.nature]; + if (!damageAudioInfo || damageAudioInfo == "normal") { + damageAudioInfo = "effect/hujia_damage" + (num > 1 ? "2" : "") + ".mp3"; + } else if (damageAudioInfo == "default") { + damageAudioInfo = "effect/hujia_damage_" + event.nature + (num > 1 ? "2" : "") + ".mp3"; + } else { + damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; + } + game.broadcastAll(function (damageAudioInfo) { + if (lib.config.background_audio) game.playAudio(damageAudioInfo); + }, damageAudioInfo); + } else { + var damageAudioInfo = lib.natureAudio.damage[event.nature]; + if (!damageAudioInfo || damageAudioInfo == "normal") { + damageAudioInfo = "effect/damage" + (num > 1 ? "2" : "") + ".mp3"; + } else if (damageAudioInfo == "default") { + damageAudioInfo = "effect/damage_" + event.nature + (num > 1 ? "2" : "") + ".mp3"; + } else { + damageAudioInfo = damageAudioInfo[num > 1 ? 2 : 1]; + } + game.broadcastAll(function (damageAudioInfo) { + if (lib.config.background_audio) game.playAudio(damageAudioInfo); + }, damageAudioInfo); + } + var str = event.unreal ? "视为受到了" : "受到了"; + if (source) + str += + '来自' + + (source == player ? "自己" : get.translation(source)) + + "的"; + str += get.cnNumber(num) + "点"; + if (event.nature) str += get.translation(event.nature) + "属性"; + str += "伤害"; + game.log(player, str); + if (player.stat[player.stat.length - 1].damaged == undefined) { + player.stat[player.stat.length - 1].damaged = num; + } else { + player.stat[player.stat.length - 1].damaged += num; + } + if (source) { + source.getHistory("sourceDamage").push(event); + if (source.stat[source.stat.length - 1].damage == undefined) { + source.stat[source.stat.length - 1].damage = num; + } else { + source.stat[source.stat.length - 1].damage += num; + } + } + player.getHistory("damage").push(event); + if (!event.unreal) { + if (event.notrigger) { + player.changeHp(-num, false)._triggered = null; + } else { + player.changeHp(-num, false); + } + } + if (event.animate !== false) { + player.$damage(source); + var natures = (event.nature || "").split(lib.natureSeparator); + game.broadcastAll( + function (natures, player) { + if (lib.config.animation && !lib.config.low_performance) { + if (natures.includes("fire")) { + player.$fire(); + } + if (natures.includes("thunder")) { + player.$thunder(); + } + } + }, + natures, + player + ); + var numx = player.hasSkillTag("nohujia") ? num : Math.max(0, num - player.hujia); + player.$damagepop(-numx, natures[0]); + } + if (event.unreal) event.goto(6); + if (!event.notrigger) { + if (num == 0) { + event.trigger("damageZero"); + event._triggered = null; + } else { + event.trigger("damage"); + } + } + "step 5"; + if (player.hp <= 0 && player.isAlive() && !event.nodying) { + game.delayx(); + event._dyinged = true; + player.dying(event); + } + if (source && lib.config.border_style == "auto") { + var dnum = 0; + for (var j = 0; j < source.stat.length; j++) { + if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; + } + if (dnum >= 2) { + if (lib.config.autoborder_start == "silver") { + dnum += 4; + } else if (lib.config.autoborder_start == "gold") { + dnum += 8; + } + } + if (lib.config.autoborder_count == "damage") { + source.node.framebg.dataset.decoration = ""; + if (dnum >= 10) { + source.node.framebg.dataset.auto = "gold"; + if (dnum >= 12) source.node.framebg.dataset.decoration = "gold"; + } else if (dnum >= 6) { + source.node.framebg.dataset.auto = "silver"; + if (dnum >= 8) source.node.framebg.dataset.decoration = "silver"; + } else if (dnum >= 2) { + source.node.framebg.dataset.auto = "bronze"; + if (dnum >= 4) source.node.framebg.dataset.decoration = "bronze"; + } + if (dnum >= 2) { + source.classList.add("topcount"); + } + } else if (lib.config.autoborder_count == "mix") { + source.node.framebg.dataset.decoration = ""; + switch (source.node.framebg.dataset.auto) { + case "bronze": + if (dnum >= 4) source.node.framebg.dataset.decoration = "bronze"; + break; + case "silver": + if (dnum >= 8) source.node.framebg.dataset.decoration = "silver"; + break; + case "gold": + if (dnum >= 12) source.node.framebg.dataset.decoration = "gold"; + break; + } + } + } + "step 6"; + if (!event.notrigger) event.trigger("damageSource"); + }, + recover: function () { + if (num > player.maxHp - player.hp) { + num = player.maxHp - player.hp; + event.num = num; + } + if (num > 0) { + delete event.filterStop; + if (lib.config.background_audio) { + game.playAudio("effect", "recover"); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio("effect", "recover"); + } + }); + game.broadcastAll(function (player) { + if (lib.config.animation && !lib.config.low_performance) { + player.$recover(); + } + }, player); + player.$damagepop(num, "wood"); + game.log(player, "回复了" + get.cnNumber(num) + "点体力"); + + player.changeHp(num, false); + } else event._triggered = null; + }, + loseHp: function () { + "step 0"; + if (event.num <= 0) { + event.finish(); + event._triggered = null; + return; + } + if (lib.config.background_audio) { + game.playAudio("effect", "loseHp"); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio("effect", "loseHp"); + } + }); + game.log(player, "失去了" + get.cnNumber(num) + "点体力"); + player.changeHp(-num); + "step 1"; + if (player.hp <= 0 && !event.nodying) { + game.delayx(); + event._dyinged = true; + player.dying(event); + } + }, + doubleDraw: function () { + "step 0"; + player.chooseBool("你的主副将体力上限之和是奇数,是否摸一张牌?"); + "step 1"; + if (result.bool) { + player.draw(); + } + }, + loseMaxHp: function () { + "step 0"; + game.log(player, "减少了" + get.cnNumber(num) + "点体力上限"); + player.maxHp -= num; + event.loseHp = Math.max(0, player.hp - player.maxHp); + player.update(); + "step 1"; + if (player.maxHp <= 0) { + player.die(event); + } + }, + gainMaxHp: function () { + "step 0"; + game.log(player, "增加了" + get.cnNumber(num) + "点体力上限"); + player.maxHp += num; + player.update(); + }, + changeHp: function () { + //add to GlobalHistory + game.getGlobalHistory().changeHp.push(event); + //changeHujia moved here + if ( + num < 0 && + player.hujia > 0 && + event.getParent().name == "damage" && + !player.hasSkillTag("nohujia") + ) { + event.hujia = Math.min(-num, player.hujia); + event.getParent().hujia = event.hujia; + event.num += event.hujia; + //log moved to changeHujia + //game.log(player,'的护甲抵挡了'+get.cnNumber(event.hujia)+'点伤害'); + player.changeHujia(-event.hujia).type = "damage"; + } + //old part + num = event.num; + player.hp += num; + if (isNaN(player.hp)) player.hp = 0; + if (player.hp > player.maxHp) player.hp = player.maxHp; + player.update(); + if (event.popup !== false) { + player.$damagepop(num, "water"); + } + if (_status.dying.includes(player) && player.hp > 0) { + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + var evt = event.getParent("_save"); + if (evt && evt.finish) evt.finish(); + evt = event.getParent("dying"); + if (evt && evt.finish) evt.finish(); + } + event.trigger("changeHp"); + }, + changeHujia: function () { + if (num > 0) { + game.log(player, "获得了" + get.cnNumber(num) + "点护甲"); + } else if (num < 0) { + if (-num > player.hujia) { + num = -player.hujia; + event.num = num; + } + switch ( + event.type //log moved here + ) { + case "damage": + game.log(player, "的护甲抵挡了" + get.cnNumber(-num) + "点伤害"); + break; + case "lose": + game.log(player, "失去了" + get.cnNumber(-num) + "点护甲"); + break; + } + } + player.hujia += num; + //if(player.hujia<0){ + // player.hujia=0; + //} + player.update(); + }, + dying: function () { + "step 0"; + event.forceDie = true; + if (player.isDying() || player.hp > 0) { + event.finish(); + return; + } + _status.dying.unshift(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + event.trigger("dying"); + game.log(player, "濒死"); + "step 1"; + delete event.filterStop; + if (player.hp > 0 || event.nodying) { + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + event.finish(); + } else if (!event.skipTao) { + var next = game.createEvent("_save"); + var start = false; + var starts = [_status.currentPhase, event.source, event.player, game.me, game.players[0]]; + for (var i = 0; i < starts.length; i++) { + if (get.itemtype(starts[i]) == "player") { + start = starts[i]; + break; + } + } + next.player = start; + next._trigger = event; + next.triggername = "_save"; + next.forceDie = true; + next.setContent(lib.skill._save.content); + } + "step 2"; + _status.dying.remove(player); + game.broadcast(function (list) { + _status.dying = list; + }, _status.dying); + if (player.hp <= 0 && !event.nodying && !player.nodying) player.die(event.reason); + }, + die: function () { + "step 0"; + event.forceDie = true; + if (_status.roundStart == player) { + _status.roundStart = player.next || player.getNext() || game.players[0]; + } + if (ui.land && ui.land.player == player) { + game.addVideo("destroyLand"); + ui.land.destroy(); + } + var unseen = false; + if (player.classList.contains("unseen")) { + player.classList.remove("unseen"); + unseen = true; + } + var logvid = game.logv(player, "die", source); + event.logvid = logvid; + if (unseen) { + player.classList.add("unseen"); + } + if (source) { + game.log(player, "被", source, "杀害"); + if (source.stat[source.stat.length - 1].kill == undefined) { + source.stat[source.stat.length - 1].kill = 1; + } else { + source.stat[source.stat.length - 1].kill++; + } + } else { + game.log(player, "阵亡"); + } + + // player.removeEquipTrigger(); + + // for(var i in lib.skill.globalmap){ + // if(lib.skill.globalmap[i].includes(player)){ + // lib.skill.globalmap[i].remove(player); + // if(lib.skill.globalmap[i].length==0&&!lib.skill[i].globalFixed){ + // game.removeGlobalSkill(i); + // } + // } + // } + game.broadcastAll(function (player) { + player.classList.add("dead"); + player.removeLink(); + player.classList.remove("turnedover"); + player.classList.remove("out"); + player.node.count.innerHTML = "0"; + player.node.hp.hide(); + player.node.equips.hide(); + player.node.count.hide(); + player.previous.next = player.next; + player.next.previous = player.previous; + game.players.remove(player); + game.dead.push(player); + _status.dying.remove(player); + + if (lib.config.background_speak) { + const name = player.skin.name || player.name; + const goon = !lib.character[name]; + if (goon) + lib.character[name] = [ + "", + "", + 0, + [], + ((lib.characterSubstitute[player.name] || []).find((i) => i[0] == name) || [ + name, + [], + ])[1], + ]; + if (lib.character[name][4].some((tag) => /^die:.+$/.test(tag))) { + var tag = lib.character[name][4].find((tag) => /^die:.+$/.test(tag)); + var reg = new RegExp("^ext:(.+)?/"); + var match = tag.match(/^die:(.+)$/); + if (match) { + var path = match[1]; + if (reg.test(path)) path = path.replace(reg, (_o, p) => `../extension/${p}/`); + game.playAudio(path); + } + } else if (lib.character[name][4].some((tag) => tag.startsWith("die_audio"))) { + var tag = lib.character[name][4].find((tag) => tag.startsWith("die_audio")); + var list = tag.split(":").slice(1); + game.playAudio("die", list.length ? list[0] : name); + } else { + game.playAudio("die", name, function () { + game.playAudio("die", name.slice(name.indexOf("_") + 1)); + }); + } + if (goon) delete lib.character[name]; + } + }, player); + + game.addVideo("diex", player); + if (event.animate !== false) { + player.$die(source); + } + if (player.hp != 0) { + player.changeHp(0 - player.hp, false).forceDie = true; + } + "step 1"; + if (player.dieAfter) player.dieAfter(source); + "step 2"; + event.trigger("die"); + "step 3"; + if (player.isDead()) { + if (!game.reserveDead) { + for (var mark in player.marks) { + player.unmarkSkill(mark); + } + while (player.node.marks.childNodes.length > 1) { + player.node.marks.lastChild.remove(); + } + game.broadcast(function (player) { + while (player.node.marks.childNodes.length > 1) { + player.node.marks.lastChild.remove(); + } + }, player); + } + for (var i in player.tempSkills) { + player.removeSkill(i); + } + var skills = player.getSkills(); + for (var i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]].temp) { + player.removeSkill(skills[i]); + } + } + if (_status.characterlist) { + if ( + lib.character[player.name] && + !player.name.startsWith("gz_shibing") && + !player.name.startsWith("gz_jun_") + ) + _status.characterlist.add(player.name); + if ( + lib.character[player.name1] && + !player.name1.startsWith("gz_shibing") && + !player.name1.startsWith("gz_jun_") + ) + _status.characterlist.add(player.name1); + if ( + lib.character[player.name2] && + !player.name2.startsWith("gz_shibing") && + !player.name2.startsWith("gz_jun_") + ) + _status.characterlist.add(player.name2); + } + event.cards = player.getCards("hejsx"); + if (event.cards.length) { + player.discard(event.cards).forceDie = true; + //player.$throw(event.cards,1000); + } + } + "step 4"; + if (player.dieAfter2) player.dieAfter2(source); + "step 5"; + game.broadcastAll(function (player) { + if (game.online && player == game.me && !_status.over && !game.controlOver && !ui.exit) { + if (lib.mode[lib.configOL.mode].config.dierestart) { + ui.create.exit(); + } + } + }, player); + if (!_status.connectMode && player == game.me && !_status.over && !game.controlOver) { + ui.control.show(); + if (get.config("revive") && lib.mode[lib.config.mode].config.revive && !ui.revive) { + ui.revive = ui.create.control("revive", ui.click.dierevive); + } + if ( + get.config("continue_game") && + !ui.continue_game && + lib.mode[lib.config.mode].config.continue_game && + !_status.brawl && + !game.no_continue_game + ) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); + } + if (get.config("dierestart") && lib.mode[lib.config.mode].config.dierestart && !ui.restart) { + ui.restart = ui.create.control("restart", game.reload); + } + } + + if (!_status.connectMode && player == game.me && !game.modeSwapPlayer) { + // _status.auto=false; + if (ui.auto) { + // ui.auto.classList.remove('glow'); + ui.auto.hide(); + } + if (ui.wuxie) ui.wuxie.hide(); + } + + if (typeof _status.coin == "number" && source && !_status.auto) { + if (source == game.me || source.isUnderControl()) { + _status.coin += 10; + } + } + if ( + source && + lib.config.border_style == "auto" && + (lib.config.autoborder_count == "kill" || lib.config.autoborder_count == "mix") + ) { + switch (source.node.framebg.dataset.auto) { + case "gold": + case "silver": + source.node.framebg.dataset.auto = "gold"; + break; + case "bronze": + source.node.framebg.dataset.auto = "silver"; + break; + default: + source.node.framebg.dataset.auto = lib.config.autoborder_start || "bronze"; + } + if (lib.config.autoborder_count == "kill") { + source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; + } else { + var dnum = 0; + for (var j = 0; j < source.stat.length; j++) { + if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; + } + source.node.framebg.dataset.decoration = ""; + switch (source.node.framebg.dataset.auto) { + case "bronze": + if (dnum >= 4) source.node.framebg.dataset.decoration = "bronze"; + break; + case "silver": + if (dnum >= 8) source.node.framebg.dataset.decoration = "silver"; + break; + case "gold": + if (dnum >= 12) source.node.framebg.dataset.decoration = "gold"; + break; + } + } + source.classList.add("topcount"); + } + }, + addJudge: function () { + "step 0"; + const cardName = typeof card == "string" ? card : card.name, + cardInfo = lib.card[cardName]; + if (cards) { + var owner = get.owner(cards[0]); + if (owner) { + event.relatedLose = owner.lose(cards, ui.special).set("getlx", false); + if (cardInfo && !cardInfo.blankCard) { + event.relatedLose.set("visible", true); + event.set("visible", true); + } + } else if (get.position(cards[0]) == "c") event.updatePile = true; + } + "step 1"; + if (cards[0].willBeDestroyed("judge", player, event)) { + cards[0].selfDestroy(event); + event.finish(); + return; + } else if (event.relatedLose) { + var owner = event.relatedLose.player; + if (owner.getCards("hejsx").includes(card)) { + event.finish(); + return; + } + } + cards[0].fix(); + cards[0].style.transform = ""; + cards[0].classList.remove("drawinghidden"); + delete cards[0]._transform; + var viewAs = typeof card == "string" ? card : card.name; + if (!lib.card[viewAs] || (!lib.card[viewAs].effect && !lib.card[viewAs].noEffect)) { + game.cardsDiscard(cards[0]); + } else { + cards[0].style.transform = ""; + cards[0].classList.add("drawinghidden"); + player.node.judges.insertBefore(cards[0], player.node.judges.firstChild); + if (_status.discarded) { + _status.discarded.remove(cards[0]); + } + ui.updatej(player); + game.broadcast( + function (player, card, viewAs) { + card.fix(); + card.style.transform = ""; + card.classList.add("drawinghidden"); + card.viewAs = viewAs; + if ( + viewAs && + viewAs != card.name && + (card.classList.contains("fullskin") || card.classList.contains("fullborder")) + ) { + card.classList.add("fakejudge"); + card.node.background.innerHTML = + lib.translate[viewAs + "_bg"] || get.translation(viewAs)[0]; + } else { + card.classList.remove("fakejudge"); + } + player.node.judges.insertBefore(card, player.node.judges.firstChild); + ui.updatej(player); + if ( + card.clone && + (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena) + ) { + card.clone.moveDelete(player); + game.addVideo("gain2", player, get.cardsInfo([card])); + } + }, + player, + cards[0], + viewAs + ); + if ( + cards[0].clone && + (cards[0].clone.parentNode == player.parentNode || cards[0].clone.parentNode == ui.arena) + ) { + cards[0].clone.moveDelete(player); + game.addVideo("gain2", player, get.cardsInfo(cards)); + } + // player.$gain2(cards); + if (get.itemtype(card) != "card") { + if (typeof card == "string") cards[0].viewAs = card; + else cards[0].viewAs = card.name; + } else { + delete cards[0].viewAs; + } + if (cards[0].viewAs && cards[0].viewAs != cards[0].name) { + if (cards[0].classList.contains("fullskin") || cards[0].classList.contains("fullborder")) { + cards[0].classList.add("fakejudge"); + cards[0].node.background.innerHTML = + lib.translate[cards[0].viewAs + "_bg"] || get.translation(cards[0].viewAs)[0]; + } + if (lib.card[viewAs].blankCard) { + game.log( + player, + '被扣置了' + get.translation(cards[0].viewAs) + "" + ); + } else { + game.log( + player, + '被贴上了' + get.translation(cards[0].viewAs) + "(", + cards, + ")" + ); + } + } else { + cards[0].classList.remove("fakejudge"); + game.log(player, "被贴上了", cards); + } + game.addVideo("addJudge", player, [get.cardInfo(cards[0]), cards[0].viewAs]); + } + if (event.updatePile) game.updateRoundNumber(); + }, + judge: function () { + "step 0"; + var judgestr = get.translation(player) + "的" + event.judgestr + "判定"; + event.videoId = lib.status.videoId++; + var cardj = event.directresult; + if (!cardj) { + if (player.getTopCards) cardj = player.getTopCards()[0]; + else cardj = get.cards()[0]; + } + var owner = get.owner(cardj); + if (owner) { + owner.lose(cardj, "visible", ui.ordering); + } else { + var nextj = game.cardsGotoOrdering(cardj); + if (event.position != ui.discardPile) nextj.noOrdering = true; + } + player.judging.unshift(cardj); + game.addVideo("judge1", player, [get.cardInfo(player.judging[0]), judgestr, event.videoId]); + game.broadcastAll( + function (player, card, str, id, cardid) { + var event; + if (game.online) { + event = {}; + } else { + event = _status.event; + } + if (game.chess) { + event.node = card.copy("thrown", "center", ui.arena).addTempClass("start"); + } else { + event.node = player.$throwordered(card.copy(), true); + } + if (lib.cardOL) lib.cardOL[cardid] = event.node; + event.node.cardid = cardid; + event.node.classList.add("thrownhighlight"); + ui.arena.classList.add("thrownhighlight"); + event.dialog = ui.create.dialog(str); + event.dialog.classList.add("center"); + event.dialog.videoId = id; + }, + player, + player.judging[0], + judgestr, + event.videoId, + get.id() + ); + + game.log(player, "进行" + event.judgestr + "判定,亮出的判定牌为", player.judging[0]); + game.delay(2); + if (!event.noJudgeTrigger) event.trigger("judge"); + "step 1"; + event.result = { + card: player.judging[0], + name: player.judging[0].name, + number: get.number(player.judging[0]), + suit: get.suit(player.judging[0]), + color: get.color(player.judging[0]), + node: event.node, + }; + if (event.fixedResult) { + for (var i in event.fixedResult) { + event.result[i] = event.fixedResult[i]; + } + } + event.result.judge = event.judge(event.result); + if (event.result.judge > 0) event.result.bool = true; + else if (event.result.judge < 0) event.result.bool = false; + else event.result.bool = null; + player.judging.shift(); + game.checkMod(player, event.result, "judge", player); + if (event.judge2) { + var judge2 = event.judge2(event.result); + if (typeof judge2 == "boolean") player.tryJudgeAnimate(judge2); + } + if (event.clearArena != false) { + game.broadcastAll(ui.clear); + } + game.broadcast(function (id) { + var dialog = get.idDialog(id); + if (dialog) { + dialog.close(); + } + ui.arena.classList.remove("thrownhighlight"); + }, event.videoId); + event.dialog.close(); + game.addVideo("judge2", null, event.videoId); + ui.arena.classList.remove("thrownhighlight"); + game.log(player, "的判定结果为", event.result.card); + event.trigger("judgeFixing"); + if (event.callback) { + var next = game.createEvent("judgeCallback", false); + next.player = player; + next.card = event.result.card; + next.judgeResult = get.copy(event.result); + next.setContent(event.callback); + } else { + if (!get.owner(event.result.card)) { + if (event.position != ui.discardPile) event.position.appendChild(event.result.card); + } + } + }, + turnOver: function () { + game.log(player, "翻面"); + player.classList.toggle("turnedover"); + game.broadcast(function (player) { + player.classList.toggle("turnedover"); + }, player); + game.addVideo("turnOver", player, player.classList.contains("turnedover")); + }, + link: function () { + if (player.isLinked()) { + game.log(player, "解除连环"); + } else { + game.log(player, "被连环"); + } + if (lib.config.background_audio) { + game.playAudio("effect", "link"); + } + game.broadcast(function () { + if (lib.config.background_audio) { + game.playAudio("effect", "link"); + } + }); + player.classList.remove("target"); + if (get.is.linked2(player)) { + player.classList.toggle("linked2"); + } else { + player.classList.toggle("linked"); + } + ui.updatej(player); + ui.updatem(player); + game.broadcast( + function (player, linked) { + player.classList.remove("target"); + if (get.is.linked2(player)) { + if (linked) { + player.classList.add("linked2"); + } else { + player.classList.remove("linked2"); + } + } else { + if (linked) { + player.classList.add("linked"); + } else { + player.classList.remove("linked"); + } + } + ui.updatej(player); + ui.updatem(player); + }, + player, + player.isLinked() + ); + game.addVideo("link", player, player.isLinked()); + }, + /** + * @deprecated + */ + chooseToGuanxing: function () { + "step 0"; + var cards = get.cards(num); + game.cardsGotoOrdering(cards); + var next = player.chooseToMove(); + next.set("list", [["牌堆顶", cards], ["牌堆底"]]); + next.set("prompt", "点击将牌移动到牌堆顶或牌堆底"); + next.processAI = + event.processAI || + function (list) { + var cards = list[0][1], + player = _status.event.player; + var top = []; + var bottom; + cards.sort(function (a, b) { + return get.value(b, player) - get.value(a, player); + }); + while (cards.length) { + if (get.value(cards[0], player) <= 5) break; + top.unshift(cards.shift()); + } + bottom = cards; + return [top, bottom]; + }; + "step 1"; + var top = result.moved[0]; + var bottom = result.moved[1]; + top.reverse(); + for (var i = 0; i < top.length; i++) { + ui.cardPile.insertBefore(top[i], ui.cardPile.firstChild); + } + for (i = 0; i < bottom.length; i++) { + ui.cardPile.appendChild(bottom[i]); + } + game.addCardKnower(top, player); + game.addCardKnower(bottom, player); + player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下"); + game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶"); + game.updateRoundNumber(); + game.delayx(); + }, +}; diff --git a/noname/library/element/contents.js b/noname/library/element/contents.js index 163a9869b..085fbe7a7 100644 --- a/noname/library/element/contents.js +++ b/noname/library/element/contents.js @@ -1,10 +1,8 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; /** * @type { SMap<((event: GameEventPromise, trigger: GameEventPromise, player: Player) => Promise)[]> } @@ -14,15 +12,22 @@ export const Contents = { async (event) => { //规则集中的“回合开始后③(处理“游戏开始时”的时机)” //提前phaseBefore时机解决“游戏开始时”时机和“一轮开始时”先后 - event.trigger('phaseBefore'); + event.trigger("phaseBefore"); }, async (event, _trigger, player) => { // 初始化阶段列表 if (!event.phaseList) { - event.phaseList = ['phaseZhunbei', 'phaseJudge', 'phaseDraw', 'phaseUse', 'phaseDiscard', 'phaseJieshu']; + event.phaseList = [ + "phaseZhunbei", + "phaseJudge", + "phaseDraw", + "phaseUse", + "phaseDiscard", + "phaseJieshu", + ]; } - if (typeof event.num != 'number') { + if (typeof event.num != "number") { event.num = 0; } @@ -32,16 +37,18 @@ export const Contents = { isRound = _status.roundSkipped; if (_status.isRoundFilter) { isRound = _status.isRoundFilter(event, player); - } - else if (_status.seatNumSettled) { + } else if (_status.seatNumSettled) { var seatNum = player.getSeatNum(); if (seatNum != 0) { // @ts-ignore - if (get.itemtype(_status.lastPhasedPlayer) != 'player' || seatNum < _status.lastPhasedPlayer.getSeatNum()) isRound = true; + if ( + get.itemtype(_status.lastPhasedPlayer) != "player" || + seatNum < _status.lastPhasedPlayer.getSeatNum() + ) + isRound = true; _status.lastPhasedPlayer = player; } - } - else if (player == _status.roundStart) isRound = true; + } else if (player == _status.roundStart) isRound = true; if (isRound) { delete _status.roundSkipped; game.roundNumber++; @@ -57,7 +64,7 @@ export const Contents = { } } } - event.trigger('roundStart'); + event.trigger("roundStart"); } } @@ -72,7 +79,17 @@ export const Contents = { const players = game.players.slice(0).concat(game.dead); for (const current of players) { // @ts-ignore - current.actionHistory.push({ useCard: [], respond: [], skipped: [], lose: [], gain: [], sourceDamage: [], damage: [], custom: [], useSkill: [] }); + current.actionHistory.push({ + useCard: [], + respond: [], + skipped: [], + lose: [], + gain: [], + sourceDamage: [], + damage: [], + custom: [], + useSkill: [], + }); // @ts-ignore current.stat.push({ card: {}, skill: {} }); if (isRound) { @@ -88,11 +105,11 @@ export const Contents = { }, async (event) => { //规则集中的“回合开始后②(1v1武将登场专用)” - event.trigger('phaseBeforeStart'); + event.trigger("phaseBeforeStart"); }, async (event) => { //规则集中的“回合开始后④(卑弥呼〖纵傀〗的时机)” - event.trigger('phaseBeforeEnd'); + event.trigger("phaseBeforeEnd"); }, async (event, _trigger, player) => { //规则集中的“回合开始后⑤”,进行翻面检测 @@ -106,8 +123,7 @@ export const Contents = { current.getHistory().isSkipped = true; current.getStat().isSkipped = true; } - } - else { + } else { player.phaseSkipped = false; player.getHistory().isMe = true; player.getStat().isMe = true; @@ -125,46 +141,70 @@ export const Contents = { ++player.phaseNumber; // @ts-ignore - game.broadcastAll((player, num, popup) => { - if (lib.config.glow_phase) { - player.classList.add('glow_phase'); - } - player.phaseNumber = num; - _status.currentPhase = player; - if (popup && lib.config.show_phase_prompt) player.popup('回合开始', null, false); - }, player, player.phaseNumber, !player.noPhaseDelay); + game.broadcastAll( + (player, num, popup) => { + if (lib.config.glow_phase) { + player.classList.add("glow_phase"); + } + player.phaseNumber = num; + _status.currentPhase = player; + if (popup && lib.config.show_phase_prompt) player.popup("回合开始", null, false); + }, + player, + player.phaseNumber, + !player.noPhaseDelay + ); _status.currentPhase = player; _status.discarded = []; game.syncState(); // @ts-ignore - game.addVideo('phaseChange', player); + game.addVideo("phaseChange", player); if (game.phaseNumber == 1) { delete player._start_cards; if (lib.configOL.observe) { lib.configOL.observeReady = true; - game.send('server', 'config', lib.configOL); + game.send("server", "config", lib.configOL); } } game.log(); - game.log(player, '的回合开始'); + game.log(player, "的回合开始"); player._noVibrate = true; - if (get.config('identity_mode') != 'zhong' && get.config('identity_mode') != 'purple' && !_status.connectMode) { + if ( + get.config("identity_mode") != "zhong" && + get.config("identity_mode") != "purple" && + !_status.connectMode + ) { let num; - switch (get.config('auto_identity')) { - case 'one': num = 1; break; - case 'two': num = 2; break; - case 'three': num = 3; break; - case 'always': num = -1; break; - default: num = 0; break; + switch (get.config("auto_identity")) { + case "one": + num = 1; + break; + case "two": + num = 2; + break; + case "three": + num = 3; + break; + case "always": + num = -1; + break; + default: + num = 0; + break; } // @ts-ignore - if (num && !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { - if (!_status.video) player.popup('显示身份'); + if ( + num && + !_status.identityShown && + game.phaseNumber > game.players.length * num && + game.showIdentity + ) { + if (!_status.video) player.popup("显示身份"); _status.identityShown = true; // @ts-ignore game.showIdentity(false); @@ -174,39 +214,37 @@ export const Contents = { // @ts-ignore if (ui.land && ui.land.player == player) { // @ts-ignore - game.addVideo('destroyLand'); + game.addVideo("destroyLand"); // @ts-ignore ui.land.destroy(); } }, async (event) => { //规则集中的“回合开始后⑦”,国战武将明置武将牌 - event.trigger('phaseBeginStart'); + event.trigger("phaseBeginStart"); }, async (event) => { //规则集中的“回合开始后⑨”,进行当先,化身等操作 //没有⑧ 因为⑧用不到 - event.trigger('phaseBegin'); + event.trigger("phaseBegin"); }, async (event, _trigger, player) => { if (event.num < event.phaseList.length) { //规则集中没有的新时机 可以用来插入额外阶段啥的 - if (player.isIn()) event.trigger('phaseChange'); - } - else event.goto(11); + if (player.isIn()) event.trigger("phaseChange"); + } else event.goto(11); }, async (event, _trigger, player) => { if (player.isIn() && event.num < event.phaseList.length) { - const phase = event.phaseList[event.num].split('|'); + const phase = event.phaseList[event.num].split("|"); event.currentPhase = phase[0]; - if (event.currentPhase == 'phaseDraw' || event.currentPhase == 'phaseDiscard') { + if (event.currentPhase == "phaseDraw" || event.currentPhase == "phaseDiscard") { if (!player.noPhaseDelay) { // @ts-ignore if (player == game.me) { await game.asyncDelay(); // game.delay(); - } - else { + } else { await game.asyncDelayx(); // game.delayx(); } @@ -221,7 +259,7 @@ export const Contents = { } }, async (event, _trigger, player) => { - if (event.currentPhase === 'phaseUse') { + if (event.currentPhase === "phaseUse") { // @ts-ignore game.broadcastAll(() => { // @ts-ignore @@ -239,28 +277,27 @@ export const Contents = { async (event) => { if (event.num < event.phaseList.length) { event.goto(8); - } - else if (!event._phaseEndTriggered) { + } else if (!event._phaseEndTriggered) { event._phaseEndTriggered = true; - event.trigger('phaseEnd'); + event.trigger("phaseEnd"); event.redo(); } }, async (event) => { - event.trigger('phaseAfter'); + event.trigger("phaseAfter"); }, async ({ player }) => { //删除当前回合角色 此时处于“不属于任何角色的回合”的阶段 // @ts-ignore game.broadcastAll((player) => { - player.classList.remove('glow_phase'); + player.classList.remove("glow_phase"); delete _status.currentPhase; }, player); - } + }, ], phaseDraw: [ async (event, _trigger, player) => { - game.log(player, '进入了摸牌阶段'); + game.log(player, "进入了摸牌阶段"); event.trigger("phaseDrawBegin1"); }, async (event) => { @@ -271,8 +308,7 @@ export const Contents = { if (game.modPhaseDraw) { // @ts-ignore return game.modPhaseDraw(player, event.num); - } - else { + } else { if (event.num > 0) { let num = event.num; if (event.attachDraw) { @@ -294,55 +330,62 @@ export const Contents = { if (Array.isArray(result)) { event.cards = result; } - } + }, ], changeSkills: [ - async (event,trigger,player) => { + async (event, trigger, player) => { //获取玩家当前已有的技能 const ownedSkills = player.getSkills(true, false, false); //去重检查 event.addSkill.unique(); event.removeSkill.unique(); //避免失去还没拥有的技能 - event.removeSkill = event.removeSkill.filter(skill => ownedSkills.includes(skill)); - const duplicatedSkills = event.addSkill.filter(skill => event.removeSkill.includes(skill)); + event.removeSkill = event.removeSkill.filter((skill) => ownedSkills.includes(skill)); + const duplicatedSkills = event.addSkill.filter((skill) => event.removeSkill.includes(skill)); if (duplicatedSkills.length) { event.addSkill.removeArray(duplicatedSkills); event.removeSkill.removeArray(duplicatedSkills); } //if (!event.addSkill.length&&!event.removeSkill.length) return; //手动触发时机 - await event.trigger('changeSkillsBefore'); + await event.trigger("changeSkillsBefore"); }, - async (event,trigger,player) => { - await event.trigger('changeSkillsBegin'); + async (event, trigger, player) => { + await event.trigger("changeSkillsBegin"); }, - async (event,trigger,player) => { + async (event, trigger, player) => { //处理失去和获得的技能 if (event.$handle) { event.$handle(player, event.addSkill, event.removeSkill, event); - } - else { - if(event.addSkill.length){ + } else { + if (event.addSkill.length) { player.addSkill(event.addSkill); - game.log(player, '获得了技能', ...event.addSkill.map(i => { - return '#g【' + get.translation(i) + '】'; - })); + game.log( + player, + "获得了技能", + ...event.addSkill.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); } - if(event.removeSkill.length){ + if (event.removeSkill.length) { player.removeSkill(event.removeSkill); - game.log(player, '失去了技能', ...event.removeSkill.map(i => { - return '#g【' + get.translation(i) + '】'; - })); + game.log( + player, + "失去了技能", + ...event.removeSkill.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); } } }, - async (event,trigger,player) => { + async (event, trigger, player) => { //手动触发时机 - await event.trigger('changeSkillsEnd'); + await event.trigger("changeSkillsEnd"); }, - async (event,trigger,player) => { - await event.trigger('changeSkillsAfter'); + async (event, trigger, player) => { + await event.trigger("changeSkillsAfter"); }, ], }; diff --git a/noname/library/element/control.js b/noname/library/element/control.js index 0b9545620..f6e3be408 100644 --- a/noname/library/element/control.js +++ b/noname/library/element/control.js @@ -1,10 +1,8 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; export class Control extends HTMLDivElement { // @ts-ignore @@ -15,47 +13,47 @@ export class Control extends HTMLDivElement { args = other._args; } - const nc = !ui.control.querySelector('div:not(.removing):not(.stayleft)'); + const nc = !ui.control.querySelector("div:not(.removing):not(.stayleft)"); const controls = Array.isArray(args[0]) ? args[0] : args; /** * @type {this} */ // @ts-ignore - const control = ui.create.div('.control'); + const control = ui.create.div(".control"); Object.setPrototypeOf(control, (lib.element.Control || Control).prototype); ui.control.insertBefore(control, _status.createControl || ui.confirm); - controls.forEach(argument => { - if (argument == 'nozoom') return; - if (typeof argument == 'function') control.custom = argument; - else if (argument == 'stayleft') { + controls.forEach((argument) => { + if (argument == "nozoom") return; + if (typeof argument == "function") control.custom = argument; + else if (argument == "stayleft") { control.stayleft = true; - control.classList.add('stayleft'); - } - else control.add(argument); + control.classList.add("stayleft"); + } else control.add(argument); }); ui.controls.unshift(control); - if (nc) ui.control.addTempClass('nozoom', 100); + if (nc) ui.control.addTempClass("nozoom", 100); if (control.childNodes.length) { - control.style.transition = 'opacity 0.5s'; - control.addTempClass('controlpressdownx', 500); + control.style.transition = "opacity 0.5s"; + control.addTempClass("controlpressdownx", 500); ui.refresh(control); if (!control.stayleft) control.style.transform = `translateX(-${control.offsetWidth / 2}px)`; control.style.opacity = 1; ui.refresh(control); - control.style.transition = ''; + control.style.transition = ""; } - control.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.control2); + control.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.control2); if (lib.config.button_press) { - control.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', function () { - if (this.classList.contains('disabled')) return; - this.classList.add('controlpressdown'); - if (typeof this._offset == 'number') this.style.transform = `translateX(${this._offset}px) scale(0.97)`; + control.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", function () { + if (this.classList.contains("disabled")) return; + this.classList.add("controlpressdown"); + if (typeof this._offset == "number") + this.style.transform = `translateX(${this._offset}px) scale(0.97)`; }); - control.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function () { - this.classList.remove('controlpressdown'); - if (typeof this._offset == 'number') this.style.transform = `translateX(${this._offset}px)`; + control.addEventListener(lib.config.touchscreen ? "touchend" : "mouseup", function () { + this.classList.remove("controlpressdown"); + if (typeof this._offset == "number") this.style.transform = `translateX(${this._offset}px)`; }); } @@ -68,35 +66,33 @@ export class Control extends HTMLDivElement { ui.control.insertBefore(this, _status.createControl || ui.confirm); ui.controls.unshift(this); if (this.childNodes.length) { - this.style.transition = 'opacity 0.5s'; + this.style.transition = "opacity 0.5s"; ui.refresh(this); - this.style.transform = 'translateX(-' + (this.offsetWidth / 2) + 'px)'; + this.style.transform = "translateX(-" + this.offsetWidth / 2 + "px)"; this.style.opacity = 1; ui.refresh(this); - this.style.transition = ''; - } - else { - this.addTempClass('controlpressdownx', 500); + this.style.transition = ""; + } else { + this.addTempClass("controlpressdownx", 500); } ui.updatec(); return this; } add(item) { - var node = document.createElement('div'); + var node = document.createElement("div"); this.appendChild(node); node.link = item; node.innerHTML = get.translation(item); - node.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.control); + node.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.control); } close() { - this.addTempClass('controlpressdownx', 500); + this.addTempClass("controlpressdownx", 500); ui.controls.remove(this); this.delete(); setTimeout(ui.updatec, 100); - if (ui.confirm == this) delete ui.confirm; if (ui.skills == this) delete ui.skills; if (ui.skills2 == this) delete ui.skills2; @@ -105,7 +101,7 @@ export class Control extends HTMLDivElement { replace() { // this.addTempClass('controlpressdownx',500); if (this.replaceTransition === false) { - this.style.transitionProperty = 'none'; + this.style.transitionProperty = "none"; ui.refresh(this); } @@ -115,10 +111,9 @@ export class Control extends HTMLDivElement { else controls = arguments; delete this.custom; for (i = 0; i < controls.length; i++) { - if (typeof controls[i] == 'function') { + if (typeof controls[i] == "function") { this.custom = controls[i]; - } - else { + } else { this.add(controls[i]); } } @@ -126,13 +121,13 @@ export class Control extends HTMLDivElement { var width = 0; for (i = 0; i < this.childNodes.length; i++) width += this.childNodes[i].offsetWidth; ui.refresh(this); - this.style.width = width + 'px'; + this.style.width = width + "px"; } ui.updatec(); if (this.replaceTransition === false) { var that = this; setTimeout(function () { - that.style.transitionProperty = ''; + that.style.transitionProperty = ""; }, 200); } return this; diff --git a/noname/library/element/dialog.js b/noname/library/element/dialog.js index 5d8bcc999..7ce4fda5b 100644 --- a/noname/library/element/dialog.js +++ b/noname/library/element/dialog.js @@ -1,9 +1,7 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; +import { get } from "../../get/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; export class Dialog extends HTMLDivElement { /** @type { HTMLDivElement } */ @@ -37,19 +35,19 @@ export class Dialog extends HTMLDivElement { let noForceButton = false; /** @type { this } */ // @ts-ignore - const dialog = ui.create.div('.dialog'); + const dialog = ui.create.div(".dialog"); Object.setPrototypeOf(dialog, (lib.element.Dialog || Dialog).prototype); - dialog.contentContainer = ui.create.div('.content-container', dialog); - dialog.content = ui.create.div('.content', dialog.contentContainer); - dialog.bar1 = ui.create.div('.bar.top', dialog); - dialog.bar2 = ui.create.div('.bar.bottom', dialog); + dialog.contentContainer = ui.create.div(".content-container", dialog); + dialog.content = ui.create.div(".content", dialog.contentContainer); + dialog.bar1 = ui.create.div(".bar.top", dialog); + dialog.bar2 = ui.create.div(".bar.bottom", dialog); dialog.buttons = []; - Array.from(args).forEach(argument => { - if (typeof argument == 'boolean') dialog.static = argument; - else if (argument == 'hidden') hidden = true; - else if (argument == 'notouchscroll') noTouchScroll = true; - else if (argument == 'forcebutton') forceButton = true; - else if (argument == 'noforcebutton') noForceButton = true; + Array.from(args).forEach((argument) => { + if (typeof argument == "boolean") dialog.static = argument; + else if (argument == "hidden") hidden = true; + else if (argument == "notouchscroll") noTouchScroll = true; + else if (argument == "forcebutton") forceButton = true; + else if (argument == "noforcebutton") noForceButton = true; else dialog.add(argument); }); //if (!hidden) dialog.open(); @@ -58,91 +56,85 @@ export class Dialog extends HTMLDivElement { dialog.contentContainer.ontouchstart = ui.click.dialogtouchStart; dialog.contentContainer.ontouchmove = ui.click.touchScroll; // @ts-ignore - dialog.contentContainer.style.webkitOverflowScrolling = 'touch'; + dialog.contentContainer.style.webkitOverflowScrolling = "touch"; dialog.ontouchstart = ui.click.dragtouchdialog; } if (noForceButton) dialog.noforcebutton = true; else if (forceButton) { dialog.forcebutton = true; - dialog.classList.add('forcebutton'); + dialog.classList.add("forcebutton"); } // @ts-ignore dialog._args = args; return dialog; } /** - * - * @param { string | HTMLDivElement | Card[] | Player[] } item - * @param {*} [noclick] - * @param { boolean } [zoom] + * + * @param { string | HTMLDivElement | Card[] | Player[] } item + * @param {*} [noclick] + * @param { boolean } [zoom] */ add(item, noclick, zoom) { - if (typeof item == 'string') { - if (item.startsWith('###')) { - const items = item.slice(3).split('###'); + if (typeof item == "string") { + if (item.startsWith("###")) { + const items = item.slice(3).split("###"); this.add(items[0], noclick, zoom); this.addText(items[1], items[1].length <= 20, zoom); - } - else if (noclick) { + } else if (noclick) { const strstr = item; - item = ui.create.div('', this.content); + item = ui.create.div("", this.content); item.innerHTML = strstr; - } - else { + } else { item = ui.create.caption(item, this.content); } } // @ts-ignore - else if (['div', 'fragment'].includes(get.objtype(item))) { + else if (["div", "fragment"].includes(get.objtype(item))) { // @ts-ignore this.content.appendChild(item); } // @ts-ignore - else if (get.itemtype(item) == 'cards') { - const buttons = ui.create.div('.buttons', this.content); - if (zoom) buttons.classList.add('smallzoom'); + else if (get.itemtype(item) == "cards") { + const buttons = ui.create.div(".buttons", this.content); + if (zoom) buttons.classList.add("smallzoom"); // @ts-ignore - this.buttons = this.buttons.concat(ui.create.buttons(item, 'card', buttons, noclick)); + this.buttons = this.buttons.concat(ui.create.buttons(item, "card", buttons, noclick)); } // @ts-ignore - else if (get.itemtype(item) == 'players') { - var buttons = ui.create.div('.buttons', this.content); - if (zoom) buttons.classList.add('smallzoom'); + else if (get.itemtype(item) == "players") { + var buttons = ui.create.div(".buttons", this.content); + if (zoom) buttons.classList.add("smallzoom"); // @ts-ignore - this.buttons = this.buttons.concat(ui.create.buttons(item, 'player', buttons, noclick)); - } - else if (item[1] == 'textbutton') { + this.buttons = this.buttons.concat(ui.create.buttons(item, "player", buttons, noclick)); + } else if (item[1] == "textbutton") { ui.create.textbuttons(item[0], this, noclick); - } - else { - var buttons = ui.create.div('.buttons', this.content); - if (zoom) buttons.classList.add('smallzoom'); + } else { + var buttons = ui.create.div(".buttons", this.content); + if (zoom) buttons.classList.add("smallzoom"); // @ts-ignore this.buttons = this.buttons.concat(ui.create.buttons(item[0], item[1], buttons, noclick)); } if (this.buttons.length) { if (this.forcebutton !== false) this.forcebutton = true; if (this.buttons.length > 3 || (zoom && this.buttons.length > 5)) { - this.classList.remove('forcebutton-auto'); - } - else if (!this.noforcebutton) { - this.classList.add('forcebutton-auto'); + this.classList.remove("forcebutton-auto"); + } else if (!this.noforcebutton) { + this.classList.add("forcebutton-auto"); } } ui.update(); return item; } /** - * @param { string } str - * @param { boolean } [center] + * @param { string } str + * @param { boolean } [center] */ addText(str, center) { - if (str && str.startsWith('' + str + ''); - } - else { - this.add('
                                    ' + str + '
                                    '); + this.add('
                                    ' + str + "
                                    "); + } else { + this.add('
                                    ' + str + "
                                    "); } return this; } @@ -150,12 +142,11 @@ export class Dialog extends HTMLDivElement { addSmall(item, noclick) { return this.add(item, noclick, true); } - addAuto(content) { + addAuto(content) { // @ts-ignore if (content && content.length > 4 && !this._hovercustomed) { this.addSmall(content); - } - else { + } else { this.add(content); } } @@ -175,29 +166,27 @@ export class Dialog extends HTMLDivElement { } ui.dialog = this; let translate; - if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains('fixed')) { + if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains("fixed")) { translate = lib.config.dialog_transform; this._dragtransform = translate; - this.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px) scale(0.8)'; + this.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px) scale(0.8)"; + } else { + this.style.transform = "scale(0.8)"; } - else { - this.style.transform = 'scale(0.8)'; - } - this.style.transitionProperty = 'opacity,transform'; - this.style.opacity = '0'; + this.style.transitionProperty = "opacity,transform"; + this.style.opacity = "0"; ui.arena.appendChild(this); ui.dialogs.unshift(this); ui.update(); ui.refresh(this); - if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains('fixed')) { - this.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px) scale(1)'; + if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains("fixed")) { + this.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px) scale(1)"; + } else { + this.style.transform = "scale(1)"; } - else { - this.style.transform = 'scale(1)'; - } - this.style.opacity = '1'; + this.style.opacity = "1"; setTimeout(() => { - this.style.transitionProperty = ''; + this.style.transitionProperty = ""; }, 500); return this; } @@ -216,12 +205,11 @@ export class Dialog extends HTMLDivElement { return this; } /** - * @param { string } str + * @param { string } str */ setCaption(str) { - // @ts-ignore - this.querySelector('.caption').innerHTML = str; + this.querySelector(".caption").innerHTML = str; return this; } } diff --git a/noname/library/element/gameEvent.js b/noname/library/element/gameEvent.js index 9fbd5bfa6..736855ee6 100644 --- a/noname/library/element/gameEvent.js +++ b/noname/library/element/gameEvent.js @@ -1,13 +1,12 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { AsyncFunction } from '../../util/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; +import { AsyncFunction } from "../../util/index.js"; export class GameEvent { - /** @type { GameEventPromise } */ + /** @type { this & import('./gameEventPromise.js').GameEventPromise } */ #promise; /** * @param {string | GameEvent} [name] @@ -19,7 +18,7 @@ export class GameEvent { [name, trigger] = other.__args; } - if (typeof name == 'string') { + if (typeof name == "string") { this.name = name; const gameEvent = get.event(); if (gameEvent) { @@ -41,7 +40,7 @@ export class GameEvent { this.after = []; this.custom = { add: {}, - replace: {} + replace: {}, }; this._aiexclude = []; this._notrigger = []; @@ -51,8 +50,8 @@ export class GameEvent { // @ts-ignore this._result = {}; this._set = []; - /** - * @type {boolean} 这个事件是否使用异步函数处理 + /** + * @type {boolean} 这个事件是否使用异步函数处理 **/ this.async = false; /** @@ -75,6 +74,11 @@ export class GameEvent { */ // @ts-ignore player; + /** + * @type { Player[] } + */ + // @ts-ignore + players; /** * @type { Player } */ @@ -180,10 +184,10 @@ export class GameEvent { * @param {number} [baseValue] */ addNumber(key, value, baseValue) { - if (typeof value != 'number') value = 0; - if (typeof this[key] == 'number') this[key] += value; + if (typeof value != "number") value = 0; + if (typeof this[key] == "number") this[key] += value; else { - if (typeof baseValue != 'number') baseValue = 0; + if (typeof baseValue != "number") baseValue = 0; this[key] = baseValue + value; } return this; @@ -193,7 +197,7 @@ export class GameEvent { * @param {number} [baseValue] */ decrease(key, baseValue) { - if (typeof this[key] == 'number') this[key]--; + if (typeof this[key] == "number") this[key]--; else this.subtractNumber(key, 1, baseValue); return this; } @@ -202,7 +206,7 @@ export class GameEvent { * @param {number} [baseValue] */ increase(key, baseValue) { - if (typeof this[key] == 'number') this[key]++; + if (typeof this[key] == "number") this[key]++; else this.addNumber(key, 1, baseValue); return this; } @@ -212,10 +216,10 @@ export class GameEvent { * @param {number} [baseValue] */ subtractNumber(key, value, baseValue) { - if (typeof value != 'number') value = 0; - if (typeof this[key] == 'number') this[key] -= value; + if (typeof value != "number") value = 0; + if (typeof this[key] == "number") this[key] -= value; else { - if (typeof baseValue != 'number') baseValue = 0; + if (typeof baseValue != "number") baseValue = 0; this[key] = baseValue - value; } return this; @@ -229,9 +233,10 @@ export class GameEvent { * @returns {this} */ callHandler(type, event, option) { - if (this.hasHandler(type)) this.getHandler(type).forEach(handler => { - if (typeof handler == 'function') handler(event, option); - }); + if (this.hasHandler(type)) + this.getHandler(type).forEach((handler) => { + if (typeof handler == "function") handler(event, option); + }); return this; } getDefaultHandlerType() { @@ -274,7 +279,9 @@ export class GameEvent { * @returns {number} */ pushHandler(type) { - return typeof type == 'string' ? this.getHandler(type).push(...Array.from(arguments).slice(1)) : this.getHandler().push(...arguments); + return typeof type == "string" + ? this.getHandler(type).push(...Array.from(arguments).slice(1)) + : this.getHandler().push(...arguments); } changeToZero() { this.num = 0; @@ -304,7 +311,7 @@ export class GameEvent { return this; } callFuncUseStepCache(prefix, func, params) { - if (typeof func != 'function') return; + if (typeof func != "function") return; if (_status.closeStepCache) return func.apply(null, params); var cacheKey = "[" + prefix + "]" + get.paramToCacheKey.apply(null, params); var ret = this.getStepCache(cacheKey); @@ -336,9 +343,10 @@ export class GameEvent { cancel(arg1, arg2, notrigger) { this.untrigger(arg1, arg2); this.finish(); - if (notrigger != 'notrigger') { - if (this.player && lib.phaseName.includes(this.name)) this.player.getHistory('skipped').add(this.name); - return this.trigger(this.name + 'Cancelled'); + if (notrigger != "notrigger") { + if (this.player && lib.phaseName.includes(this.name)) + this.player.getHistory("skipped").add(this.name); + return this.trigger(this.name + "Cancelled"); } return null; } @@ -346,7 +354,7 @@ export class GameEvent { this.untrigger(); this.finish(); this._neutralized = true; - this.trigger('eventNeutralized'); + this.trigger("eventNeutralized"); this._neutralize_event = event || _status.event; return this; } @@ -354,7 +362,7 @@ export class GameEvent { this.untrigger(); delete this._neutralized; delete this.finished; - if (this.type == 'card' && this.card && this.name == 'sha') this.directHit = true; + if (this.type == "card" && this.card && this.name == "sha") this.directHit = true; return this; } goto(step) { @@ -369,7 +377,7 @@ export class GameEvent { if (!this.player) return this; var hidden = this.player.hiddenSkills.slice(0); game.expandSkills(hidden); - if (hidden.includes(skill)) this.set('hsskill', skill); + if (hidden.includes(skill)) this.set("hsskill", skill); return this; } set(key, value) { @@ -379,10 +387,9 @@ export class GameEvent { this.set(arguments[0][i][0], arguments[0][i][1]); } } - } - else { - if (typeof key != 'string') { - console.log('warning: using non-string object as event key'); + } else { + if (typeof key != "string") { + console.log("warning: using non-string object as event key"); console.log(key, value); console.log(_status.event); } @@ -400,28 +407,31 @@ export class GameEvent { case "function": if (item instanceof AsyncFunction) { this.content = item; - } - else this.content = lib.init.parsex(item); + } else this.content = lib.init.parsex(item); break; default: try { - if (!(lib.element.content[item] instanceof AsyncFunction) && !lib.element.content[item]._parsed) { + if ( + !(lib.element.content[item] instanceof AsyncFunction) && + !lib.element.content[item]._parsed + ) { lib.element.content[item] = lib.init.parsex(lib.element.content[item]); lib.element.content[item]._parsed = true; } - } - catch { - throw new Error(`Content ${item} may not exist.\nlib.element.content[${item}] = ${lib.element.content[item]}`); + } catch { + throw new Error( + `Content ${item} may not exist.\nlib.element.content[${item}] = ${lib.element.content[item]}` + ); } if (typeof lib.element.content[item] === "undefined") - throw new Error(`Cannot find lib.element.content[${item}]`) + throw new Error(`Cannot find lib.element.content[${item}]`); // Generator的状态重置 else if (lib.element.content[item]._gen) { this.content = lib.element.content[item].bind({ gen: null, - last: undefined - }) + last: undefined, + }); } else { this.content = lib.element.content[item]; } @@ -431,14 +441,14 @@ export class GameEvent { } /** - * + * * @param {Function | keyof typeof lib.element.contents} contents * @returns {GameEvent} */ setContents(contents) { if (Array.isArray(contents)) this.contents = contents; else if (contents in lib.element.contents) return this.setContents(lib.element.contents[contents]); - else throw new Error('not supported value.'); + else throw new Error("not supported value."); return this; } @@ -450,19 +460,25 @@ export class GameEvent { return null; } send() { - this.player.send(function (name, args, set, event, skills) { - game.me.applySkills(skills); - var next = game.me[name].apply(game.me, args); - for (var i = 0; i < set.length; i++) { - next.set(set[i][0], set[i][1]); - } - if (next._backupevent) { - next.backup(next._backupevent); - } - next._modparent = event; - game.resume(); - }, this.name, this._args || [], this._set, - get.stringifiedResult(this.parent), get.skillState(this.player)); + this.player.send( + function (name, args, set, event, skills) { + game.me.applySkills(skills); + var next = game.me[name].apply(game.me, args); + for (var i = 0; i < set.length; i++) { + next.set(set[i][0], set[i][1]); + } + if (next._backupevent) { + next.backup(next._backupevent); + } + next._modparent = event; + game.resume(); + }, + this.name, + this._args || [], + this._set, + get.stringifiedResult(this.parent), + get.skillState(this.player) + ); this.player.wait(); game.pause(); return this; @@ -478,7 +494,7 @@ export class GameEvent { * 获取事件的父节点。 * 获取事件链上的指定事件。 * 默认获取上一个父节点(核心)。 - * @param {number|string|(evt:gameEvent)=>boolean} [level=1] 获取深度(number)/指定名字(string)/指定特征(function) + * @param {number|string|((evt:GameEvent)=>boolean)} [level=1] 获取深度(number)/指定名字(string)/指定特征(function) * @param {boolean} [forced] 若获取不到节点,默认返回{},若forced为true则返回null * @param {boolean} [includeSelf] 若level不是数字,指定搜索时是否包含事件本身 * @returns {GameEvent|{}|null} @@ -489,9 +505,11 @@ export class GameEvent { const toreturn = forced ? null : {}; const historys = []; const filter = - typeof level === 'function' ? level : - typeof level === 'number' ? evt => i === level : - evt => evt.name === level; + typeof level === "function" + ? level + : typeof level === "number" + ? (evt) => i === level + : (evt) => evt.name === level; while (true) { if (!event) return toreturn; historys.push(event); @@ -503,7 +521,7 @@ export class GameEvent { } } getTrigger() { - return this.getParent(e => e._trigger, false, true)._trigger; + return this.getParent((e) => e._trigger, false, true)._trigger; } getRand(name) { if (name) { @@ -515,17 +533,17 @@ export class GameEvent { return this._rand; } insert(content, map) { - const next = (new lib.element.GameEvent(`${this.name}Inserted`, false)).toPromise(); + const next = new lib.element.GameEvent(`${this.name}Inserted`, false).toPromise(); this.next.push(next); next.setContent(content); - Object.entries(map).forEach(entry => next.set(entry[0], entry[1])); + Object.entries(map).forEach((entry) => next.set(entry[0], entry[1])); return next; } insertAfter(content, map) { - const next = (new lib.element.GameEvent(`${this.name}Inserted`, false)).toPromise(); + const next = new lib.element.GameEvent(`${this.name}Inserted`, false).toPromise(); this.after.push(next); next.setContent(content); - Object.entries(map).forEach(entry => next.set(entry[0], entry[1])); + Object.entries(map).forEach((entry) => next.set(entry[0], entry[1])); return next; } backup(skill) { @@ -555,7 +573,7 @@ export class GameEvent { var info = get.info(skill); this.skill = skill; this._aiexclude = []; - if (typeof info.viewAs == 'function') { + if (typeof info.viewAs == "function") { if (info.filterButton != undefined) this.filterButton = get.filter(info.filterButton); if (info.selectButton != undefined) this.selectButton = info.selectButton; if (info.filterTarget != undefined) this.filterTarget = get.filter(info.filterTarget); @@ -566,8 +584,8 @@ export class GameEvent { this.filterCard = function (card, player, event) { var evt = event || _status.event; if (!evt.ignoreMod && player) { - var mod = game.checkMod(card, player, 'unchanged', 'cardEnabled2', player); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod != "unchanged") return mod; } return get.filter(evt.filterCard2).apply(this, arguments); }; @@ -575,14 +593,14 @@ export class GameEvent { if (info.filterOk == undefined) { this.filterOk = function () { var evt = _status.event; - var card = get.card(), player = get.player(); + var card = get.card(), + player = get.player(); var filter = evt._backup.filterCard; if (filter && !filter(card, player, evt)) return false; if (evt._backup.filterOk) return evt._backup.filterOk(); return true; }; - } - else this.filterOk = info.filterOk; + } else this.filterOk = info.filterOk; if (info.selectCard != undefined) this.selectCard = info.selectCard; if (info.position != undefined) this.position = info.position; //if(info.forced!=undefined) this.forced=info.forced; @@ -591,8 +609,7 @@ export class GameEvent { if (info.complexTarget != undefined) this.complexTarget = info.complexTarget; if (info.ai1 != undefined) this.ai1 = info.ai1; if (info.ai2 != undefined) this.ai2 = info.ai2; - } - else if (info.viewAs) { + } else if (info.viewAs) { if (info.filterButton != undefined) this.filterButton = get.filter(info.filterButton); if (info.selectButton != undefined) this.selectButton = info.selectButton; if (info.filterTarget != undefined) this.filterTarget = get.filter(info.filterTarget); @@ -603,8 +620,8 @@ export class GameEvent { this.filterCard = function (card, player, event) { var evt = event || _status.event; if (!evt.ignoreMod && player) { - var mod = game.checkMod(card, player, 'unchanged', 'cardEnabled2', player); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod != "unchanged") return mod; } return get.filter(evt.filterCard2).apply(this, arguments); }; @@ -612,14 +629,14 @@ export class GameEvent { if (info.filterOk == undefined) { this.filterOk = function () { var evt = _status.event; - var card = get.card(), player = get.player(); + var card = get.card(), + player = get.player(); var filter = evt._backup.filterCard; if (filter && !filter(card, player, evt)) return false; if (evt._backup.filterOk) return evt._backup.filterOk(); return true; }; - } - else this.filterOk = info.filterOk; + } else this.filterOk = info.filterOk; if (info.selectCard != undefined) this.selectCard = info.selectCard; if (info.position != undefined) this.position = info.position; //if(info.forced!=undefined) this.forced=info.forced; @@ -628,8 +645,7 @@ export class GameEvent { if (info.complexTarget != undefined) this.complexTarget = info.complexTarget; if (info.ai1 != undefined) this.ai1 = info.ai1; if (info.ai2 != undefined) this.ai2 = info.ai2; - } - else { + } else { this.filterButton = info.filterButton ? get.filter(info.filterButton) : undefined; this.selectButton = info.selectButton; this.filterTarget = info.filterTarget ? get.filter(info.filterTarget) : undefined; @@ -682,38 +698,41 @@ export class GameEvent { return this; } isMine() { - return (this.player && this.player == game.me && !_status.auto && !this.player.isMad() && !game.notMe); + return this.player && this.player == game.me && !_status.auto && !this.player.isMad() && !game.notMe; } isOnline() { - return (this.player && this.player.isOnline()); + return this.player && this.player.isOnline(); } notLink() { - return this.getParent().name != '_lianhuan' && this.getParent().name != '_lianhuan2'; + return this.getParent().name != "_lianhuan" && this.getParent().name != "_lianhuan2"; } isPhaseUsing(player) { - var evt = this.getParent('phaseUse'); - if (!evt || evt.name != 'phaseUse') return false; + var evt = this.getParent("phaseUse"); + if (!evt || evt.name != "phaseUse") return false; return !player || player == evt.player; } addTrigger(skills, player) { if (!player || !skills) return this; let evt = this; - if (typeof skills == 'string') skills = [skills]; + if (typeof skills == "string") skills = [skills]; game.expandSkills(skills); while (true) { - evt = evt.getParent('arrangeTrigger'); - if (!evt || evt.name != 'arrangeTrigger' || !evt.doingList) return this; - const doing = evt.doingList.find(i => i.player === player); - const firstDo = evt.doingList.find(i => i.player === "firstDo"); - const lastDo = evt.doingList.find(i => i.player === "lastDo"); + evt = evt.getParent("arrangeTrigger"); + if (!evt || evt.name != "arrangeTrigger" || !evt.doingList) return this; + const doing = evt.doingList.find((i) => i.player === player); + const firstDo = evt.doingList.find((i) => i.player === "firstDo"); + const lastDo = evt.doingList.find((i) => i.player === "lastDo"); - skills.forEach(skill => { + skills.forEach((skill) => { const info = lib.skill[skill]; if (!info.trigger) return; - if (!Object.keys(info.trigger).some(i => { - if (Array.isArray(info.trigger[i])) return info.trigger[i].includes(evt.triggername); - return info.trigger[i] === evt.triggername; - })) return; + if ( + !Object.keys(info.trigger).some((i) => { + if (Array.isArray(info.trigger[i])) return info.trigger[i].includes(evt.triggername); + return info.trigger[i] === evt.triggername; + }) + ) + return; const toadd = { skill: skill, @@ -722,10 +741,14 @@ export class GameEvent { }; const map = info.firstDo ? firstDo : info.lastDo ? lastDo : doing; if (!map) return; - if (map.doneList.some(i => i.skill === toadd.skill && i.player === toadd.player)) return; - if (map.todoList.some(i => i.skill === toadd.skill && i.player === toadd.player)) return; + if (map.doneList.some((i) => i.skill === toadd.skill && i.player === toadd.player)) return; + if (map.todoList.some((i) => i.skill === toadd.skill && i.player === toadd.player)) return; map.todoList.add(toadd); - if (typeof map.player === 'string') map.todoList.sort((a, b) => (b.priority - a.priority) || (evt.playerMap.indexOf(a) - evt.playerMap.indexOf(b))); + if (typeof map.player === "string") + map.todoList.sort( + (a, b) => + b.priority - a.priority || evt.playerMap.indexOf(a) - evt.playerMap.indexOf(b) + ); else map.todoList.sort((a, b) => b.priority - a.priority); }); } @@ -733,31 +756,33 @@ export class GameEvent { removeTrigger(skills, player) { if (!player || !skills) return this; let evt = this; - if (typeof skills == 'string') skills = [skills]; + if (typeof skills == "string") skills = [skills]; game.expandSkills(skills); while (true) { - evt = evt.getParent('arrangeTrigger'); - if (!evt || evt.name != 'arrangeTrigger' || !evt.doingList) return this; - const doing = evt.doingList.find(i => i.player == player); - const firstDo = evt.doingList.find(i => i.player == "firstDo"); - const lastDo = evt.doingList.find(i => i.player == "lastDo"); + evt = evt.getParent("arrangeTrigger"); + if (!evt || evt.name != "arrangeTrigger" || !evt.doingList) return this; + const doing = evt.doingList.find((i) => i.player == player); + const firstDo = evt.doingList.find((i) => i.player == "firstDo"); + const lastDo = evt.doingList.find((i) => i.player == "lastDo"); - skills.forEach(skill => [doing, firstDo, lastDo].forEach(map => { - if (!map) return; - const toremove = map.todoList.filter(i => i.skill == skill && i.player == player); - if (toremove.length > 0) map.todoList.removeArray(toremove); - })); + skills.forEach((skill) => + [doing, firstDo, lastDo].forEach((map) => { + if (!map) return; + const toremove = map.todoList.filter((i) => i.skill == skill && i.player == player); + if (toremove.length > 0) map.todoList.removeArray(toremove); + }) + ); } } trigger(name) { if (_status.video) return; - if ((this.name === 'gain' || this.name === 'lose') && !_status.gameDrawed) return; - if (name === 'gameDrawEnd') _status.gameDrawed = true; - if (name === 'gameStart') { + if ((this.name === "gain" || this.name === "lose") && !_status.gameDrawed) return; + if (name === "gameDrawEnd") _status.gameDrawed = true; + if (name === "gameStart") { lib.announce.publish("Noname.Game.Event.GameStart", {}); - lib.announce.publish('gameStart', {}); + lib.announce.publish("gameStart", {}); if (_status.brawl && _status.brawl.gameStart) _status.brawl.gameStart(); - if (lib.config.show_cardpile) ui.cardPileButton.style.display = ''; + if (lib.config.show_cardpile) ui.cardPileButton.style.display = ""; _status.gameStarted = true; game.showHistory(); } @@ -765,7 +790,9 @@ export class GameEvent { if (!game.players || !game.players.length) return; const event = this; if (event.filterStop && event.filterStop()) return; - let start = [_status.currentPhase, event.source, event.player, game.me, game.players[0]].find(i => get.itemtype(i) == 'player'); + let start = [_status.currentPhase, event.source, event.player, game.me, game.players[0]].find( + (i) => get.itemtype(i) == "player" + ); if (!start) return; if (!game.players.includes(start) && !game.dead.includes(start)) start = game.findNext(start); const firstDo = { @@ -779,7 +806,7 @@ export class GameEvent { doneList: [], }; const doingList = []; - const roles = ['player', 'source', 'target', 'global']; + const roles = ["player", "source", "target", "global"]; const playerMap = game.players.concat(game.dead).sortBySeat(start); let player = start; let allbool = false; @@ -791,80 +818,93 @@ export class GameEvent { listAdded: {}, addList(skill) { if (!skill) return; - if (Array.isArray(skill)) return skill.forEach(i => this.addList(i)); + if (Array.isArray(skill)) return skill.forEach((i) => this.addList(i)); if (this.listAdded[skill]) return; this.listAdded[skill] = true; const info = lib.skill[skill]; - const list = info.firstDo ? firstDo.todoList : info.lastDo ? lastDo.todoList : this.todoList; - if (typeof info.getIndex === 'function') { + const list = info.firstDo + ? firstDo.todoList + : info.lastDo + ? lastDo.todoList + : this.todoList; + if (typeof info.getIndex === "function") { const indexedResult = info.getIndex(event, player, name); - if(Array.isArray(indexedResult)){ - indexedResult.forEach(indexedData => { + if (Array.isArray(indexedResult)) { + indexedResult.forEach((indexedData) => { list.push({ skill: skill, player: this.player, priority: get.priority(skill), indexedData, - }) + }); }); - } - else if (typeof indexedResult === 'number' && indexedResult>0){ - for(let i = 0; i < indexedResult; i++){ + } else if (typeof indexedResult === "number" && indexedResult > 0) { + for (let i = 0; i < indexedResult; i++) { list.push({ skill: skill, player: this.player, priority: get.priority(skill), indexedData: true, - }) + }); } } - } - else{ + } else { list.push({ skill: skill, player: this.player, priority: get.priority(skill), }); } - if (typeof list.player == 'string') list.sort((a, b) => (b.priority - a.priority) || (playerMap.indexOf(a) - playerMap.indexOf(b))); + if (typeof list.player == "string") + list.sort( + (a, b) => b.priority - a.priority || playerMap.indexOf(a) - playerMap.indexOf(b) + ); else list.sort((a, b) => b.priority - a.priority); allbool = true; - } + }, }; const notemp = player.skills.slice(); for (const j in player.additionalSkills) { - if (!j.startsWith('hidden:')) notemp.addArray(player.additionalSkills[j]); + if (!j.startsWith("hidden:")) notemp.addArray(player.additionalSkills[j]); } - Object.keys(player.tempSkills).filter(skill => { - if (notemp.includes(skill)) return false; - const expire = player.tempSkills[skill]; - if (typeof expire === 'function') return expire(event, player, name); - if (get.objtype(expire) === 'object') return roles.some(role => { - if (role !== 'global' && player !== event[role]) return false; - if (Array.isArray(expire[role])) return expire[role].includes(name); - return expire[role] === name; + Object.keys(player.tempSkills) + .filter((skill) => { + if (notemp.includes(skill)) return false; + const expire = player.tempSkills[skill]; + if (typeof expire === "function") return expire(event, player, name); + if (get.objtype(expire) === "object") + return roles.some((role) => { + if (role !== "global" && player !== event[role]) return false; + if (Array.isArray(expire[role])) return expire[role].includes(name); + return expire[role] === name; + }); + }) + .forEach((skill) => { + delete player.tempSkills[skill]; + player.removeSkill(skill); }); - }).forEach(skill => { - delete player.tempSkills[skill]; - player.removeSkill(skill); - }); if (lib.config.compatiblemode) { - doing.addList(game.expandSkills(player.getSkills('invisible').concat(lib.skill.global)).filter(skill => { - const info = get.info(skill); - if (!info || !info.trigger) return false; - return roles.some(role => { - if (info.trigger[role] === name) return true; - if (Array.isArray(info.trigger[role]) && info.trigger[role].includes(name)) return true; - }); - })); - } - else roles.forEach(role => { - doing.addList(lib.hook.globalskill[role + '_' + name]); - doing.addList(lib.hook[player.playerid + '_' + role + '_' + name]); - }); + doing.addList( + game + .expandSkills(player.getSkills("invisible").concat(lib.skill.global)) + .filter((skill) => { + const info = get.info(skill); + if (!info || !info.trigger) return false; + return roles.some((role) => { + if (info.trigger[role] === name) return true; + if (Array.isArray(info.trigger[role]) && info.trigger[role].includes(name)) + return true; + }); + }) + ); + } else + roles.forEach((role) => { + doing.addList(lib.hook.globalskill[role + "_" + name]); + doing.addList(lib.hook[player.playerid + "_" + role + "_" + name]); + }); delete doing.listAdded; delete doing.addList; doingList.push(doing); @@ -875,8 +915,8 @@ export class GameEvent { // console.log(name,event.player,doingList.map(i=>({player:i.player,todoList:i.todoList.slice(),doneList:i.doneList.slice()}))) if (allbool) { - const next = game.createEvent('arrangeTrigger', false, event); - next.setContent('arrangeTrigger'); + const next = game.createEvent("arrangeTrigger", false, event); + next.setContent("arrangeTrigger"); next.doingList = doingList; next._trigger = event; next.triggername = name; @@ -889,12 +929,11 @@ export class GameEvent { untrigger(all = true, player) { const evt = this._triggering; if (all) { - if(all !== 'currentOnly') this._triggered = 5; + if (all !== "currentOnly") this._triggered = 5; if (evt && evt.doingList) { - evt.doingList.forEach(doing => doing.todoList = []); + evt.doingList.forEach((doing) => (doing.todoList = [])); } - } - else if (player) { + } else if (player) { this._notrigger.add(player); // if(!evt||!evt.doingList) return this; // const doing=evt.doingList.find(doing=>doing.player==player); @@ -904,11 +943,10 @@ export class GameEvent { } /** * 事件转为Promise化 - * - * @returns { GameEventPromise } */ toPromise() { if (!this.#promise) { + // @ts-ignore this.#promise = new lib.element.GameEventPromise(this); } return this.#promise; diff --git a/noname/library/element/gameEventPromise.js b/noname/library/element/gameEventPromise.js index 7aeecc31d..725c4afd6 100644 --- a/noname/library/element/gameEventPromise.js +++ b/noname/library/element/gameEventPromise.js @@ -1,21 +1,21 @@ -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { AsyncFunction } from '../../util/index.js'; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { AsyncFunction } from "../../util/index.js"; /** * 将事件Promise化以使用async异步函数来执行事件。 - * + * * 事件Promise化后,需要既能使用await等待事件完成, * 又需要在执行之前对事件进行配置。 - * + * * 所以这个类的实例集成了事件和Promise二者的所有属性, * 且Promise的原有属性无法被修改,一切对这个类实例的属性修改,删除, * 再配置等操作都会转发到事件对应的属性中。 - * + * * @extends {Promise} - * + * * @example * 使用await xx()等待异步事件执行: * ```js @@ -35,16 +35,12 @@ export class GameEventPromise extends Promise { } #event; /** - * @param { GameEvent | GameEventPromise } arg + * @param { import('./gameEvent.js').GameEvent } arg */ constructor(arg) { - if (arg instanceof GameEventPromise) - throw new Error("GameEventPromise cannot copy.") - /** - * @type {GameEvent} - */ + if (arg instanceof GameEventPromise) throw new Error("GameEventPromise cannot copy."); const event = arg; - super(resolve => { + super((resolve) => { // 设置为异步事件 event.async = true; // 事件结束后触发resolve @@ -52,40 +48,50 @@ export class GameEventPromise extends Promise { if (!_status.event) return; // game.createEvent的时候还没立即push到next里 Promise.resolve().then(() => { - game.executingAsyncEventMap.set(_status.event.toEvent(), (game.executingAsyncEventMap.get(_status.event.toEvent()) || Promise.resolve()).then(() => { - let eventPromise = _status.event.next.find(e => e.toEvent() == event); - // 如果父级事件也是一个异步的话,那应该立即执行这个事件的 - // 如果在AsyncFunction执行过程中在别的位置新建了一个异步事件,那也直接(等会set配置完)执行 - if (eventPromise && (_status.event.content instanceof AsyncFunction || Array.isArray(_status.event.contents))) { - // 异步执行game.loop - // 不直接game.loop(event)是因为需要让别人可以手动set()和setContent() - // 再执行game.loop是因为原有的game.loop被await卡住了, - // 得新执行一个只执行这个异步事件的game.loop + game.executingAsyncEventMap.set( + _status.event.toEvent(), + (game.executingAsyncEventMap.get(_status.event.toEvent()) || Promise.resolve()).then( + () => { + let eventPromise = _status.event.next.find((e) => e.toEvent() == event); + // 如果父级事件也是一个异步的话,那应该立即执行这个事件的 + // 如果在AsyncFunction执行过程中在别的位置新建了一个异步事件,那也直接(等会set配置完)执行 + if ( + eventPromise && + (_status.event.content instanceof AsyncFunction || + Array.isArray(_status.event.contents)) + ) { + // 异步执行game.loop + // 不直接game.loop(event)是因为需要让别人可以手动set()和setContent() + // 再执行game.loop是因为原有的game.loop被await卡住了, + // 得新执行一个只执行这个异步事件的game.loop - // 事件自行处理skip情况 - _status.event.next.remove(eventPromise); - if (event.player && event.player.skipList.includes(event.name)) { - _status.event.trigger(event.name + 'Skipped'); - event.player.skipList.remove(event.name); - if (lib.phaseName.includes(event.name)) event.player.getHistory('skipped').add(event.name); - _status.event.next.remove(eventPromise); - event.finish(); - // @ts-ignore - resolve(); - return eventPromise; - } + // 事件自行处理skip情况 + _status.event.next.remove(eventPromise); + if (event.player && event.player.skipList.includes(event.name)) { + _status.event.trigger(event.name + "Skipped"); + event.player.skipList.remove(event.name); + if (lib.phaseName.includes(event.name)) + event.player.getHistory("skipped").add(event.name); + _status.event.next.remove(eventPromise); + event.finish(); + // @ts-ignore + resolve(); + return eventPromise; + } - if (_status.event != eventPromise) { - eventPromise.parent = _status.event; - _status.event = eventPromise; - game.getGlobalHistory('everything').push(eventPromise); + if (_status.event != eventPromise) { + eventPromise.parent = _status.event; + _status.event = eventPromise; + game.getGlobalHistory("everything").push(eventPromise); + } + return game.loop(eventPromise).then(() => { + // 有时候event.finished还是false + return eventPromise; + }); + } } - return game.loop(eventPromise).then(() => { - // 有时候event.finished还是false - return eventPromise; - }); - } - })); + ) + ); }); }); this.#event = event; @@ -93,7 +99,7 @@ export class GameEventPromise extends Promise { get(target, prop, receiver) { const thisValue = Reflect.get(target, prop); if (thisValue) { - if (typeof thisValue == 'function') { + if (typeof thisValue == "function") { return thisValue.bind(target); } return thisValue; @@ -127,9 +133,9 @@ export class GameEventPromise extends Promise { } /** * 在某个异步事件中调试变量信息 - * + * * 注: 在调试步骤中`定义的变量只在当前输入的语句有效` - * + * * @example * 在技能中调试技能content相关的信息 * ```js @@ -141,7 +147,7 @@ export class GameEventPromise extends Promise { * ``` */ async debugger() { - return new Promise(resolve => { + return new Promise((resolve) => { const runCode = function (event, code) { try { // 为了使玩家调试时使用var player=xxx时不报错,故使用var @@ -151,109 +157,101 @@ export class GameEventPromise extends Promise { return error; } }.bind(window); - const inputCallback = inputResult => { + const inputCallback = (inputResult) => { if (inputResult === false) { resolve(null); } else { const obj = runCode(this.toEvent(), inputResult); - alert((!obj || obj instanceof Error) ? String(obj) : get.stringify(obj)); - game.promises.prompt('debugger调试').then(inputCallback); + alert(!obj || obj instanceof Error ? String(obj) : get.stringify(obj)); + game.promises.prompt("debugger调试").then(inputCallback); } }; - game.promises.prompt('debugger调试').then(inputCallback); + game.promises.prompt("debugger调试").then(inputCallback); }); } /** + * 获取 Result 对象中的信息。 + * @example + * ```js + // 示例 1: + const chooseCardResult = await player.chooseCard().forResult(); + // 获取整个结果对象,然后访问如 chooseCardResult.cards 等属性 + + // 示例 2: + const cards = await player.chooseCard().forResult('cards'); + // 获取结果对象中 'cards' 属性的值 + + // 示例 3: + const [success, cards, targets] = await player.chooseCardTarget().forResult('bool', 'cards', 'targets'); + // 获取结果对象中多个属性的值 + // - success 表示是否成功 + // - cards 表示选择的卡片 + // - targets 表示选择的目标 + ``` + * @template {keyof Result} T + * @overload + * @returns {Promise} * - * 直接获得result中的信息。 + * @overload + * @param {T} param0 + * @returns {Promise>} * - * - * @example - * ① - * let chooseCardResult = await player.chooseCard().forResult(); - * 选择的卡牌:chooseCardResult.cards - * ② - * let cards = await player.chooseCard().forResult('cards'); - * 选择的卡牌:cards - * ③ - * let [success,cards,targets] = await player.chooseCardTarget().forResult('bool','cards','targets'); - * success:是否做出选择。 - * cards:选择的牌。 - * targets:选择的目标。 - * - * @returns {Promise} 返回的结果 + * @overload + * @param { T[] } params + * @returns { Promise[]> } */ - forResult(){ - if(arguments.length == 0){ - return this.then(event=>{ - return Promise.resolve(event.result); - }); - }else if(arguments.length == 1){ - return this.then(event=>{ - return Promise.resolve(event.result[arguments[0]]); - }); - }else{ - return this.then(event=>{ - return Promise.resolve(Array.from(arguments).map(key=>event.result[key])); - }); + forResult(...params) { + if (params.length == 0) { + return this.then(({ result }) => result); + } else if (params.length == 1) { + return this.then((event) => event.result[params[0]]); + } else { + return this.then((event) => Array.from(params).map((key) => event.result[key])); } } - /** - * 返回result中的bool项。 - * - * @returns {Promise} 返回的bool项 + * 返回result中的bool项 */ - forResultBool(){ - return this.forResult('bool'); + forResultBool() { + return this.forResult("bool"); } /** * 返回result中的targets项。 - * - * @returns {Promise} 返回的targets项。 - * */ - forResultTargets(){ - return this.forResult('targets'); + forResultTargets() { + return this.forResult("targets"); } /** * 返回result中的cards项 - * - * @returns {Promise} 返回的cards项。 - * */ - forResultCards(){ - return this.forResult('cards'); + forResultCards() { + return this.forResult("cards"); } /** * 返回result中的card项 - * + * * @returns {Promise|Promise} 返回的card项。 - * + * */ - forResultCard(){ - return this.forResult('card'); + forResultCard() { + return this.forResult("card"); } /** * 返回result中的control项。 - * - * @returns {Promise} 返回的control项。 */ - forResultControl(){ - return this.forResult('control'); + forResultControl() { + return this.forResult("control"); } /** * 返回result中的links项。 - * - * @returns {Promise>} 返回的links项。 */ - forResultLinks(){ - return this.forResult('links'); + forResultLinks() { + return this.forResult("links"); } } diff --git a/noname/library/element/nodeWS.js b/noname/library/element/nodeWS.js index 91e9da267..be5071e5b 100644 --- a/noname/library/element/nodeWS.js +++ b/noname/library/element/nodeWS.js @@ -1,25 +1,20 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; -import { GNC as gnc } from '../../gnc/index.js'; +import { game } from "../../game/index.js"; +import { _status } from "../../status/index.js"; export class NodeWS { /** * @param {string | NodeWS} id */ constructor(id) { - this.wsid = (id instanceof NodeWS) ? id.wsid : id; + this.wsid = id instanceof NodeWS ? id.wsid : id; } send(message) { - game.send('server', 'send', this.wsid, message); + game.send("server", "send", this.wsid, message); } on(type, func) { - this['on' + type] = func; + this["on" + type] = func; } close() { - game.send('server', 'close', this.wsid); + game.send("server", "close", this.wsid); } } diff --git a/noname/library/element/player.js b/noname/library/element/player.js new file mode 100644 index 000000000..0fabfa39b --- /dev/null +++ b/noname/library/element/player.js @@ -0,0 +1,11052 @@ +import { ai } from "../../ai/index.js"; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; +import { CacheContext } from "../cache/cacheContext.js"; +import { ChildNodesWatcher } from "../cache/childNodesWatcher.js"; + +export class Player extends HTMLDivElement { + /** + * @param {HTMLDivElement|DocumentFragment} [position] + */ + // @ts-ignore + + constructor(position) { + if (position instanceof Player) { + const other = position; + [position] = other._args; + } + /** + * @type {this} + */ + // @ts-ignore + const player = ui.create.div(".player", position); + Object.setPrototypeOf(player, (lib.element.Player || Player).prototype); + // @ts-ignore + player._args = [position]; + return player; + } + build(noclick) { + let player = this; + player.buildNode(); + player.buildProperty(); + player.buildExtra(); + player.buildEventListener(noclick); + return this; + } + buildNode() { + let player = this; + /** @type { SMap } */ + const node = (player.node = { + avatar: ui.create.div(".avatar", player, ui.click.avatar).hide(), + avatar2: ui.create.div(".avatar2", player, ui.click.avatar2).hide(), + turnedover: ui.create.div(".turned", "
                                    翻面
                                    ", player), + framebg: ui.create.div(".framebg", player), + intro: ui.create.div(".intro", player), + identity: ui.create.div(".identity", player), + hp: ui.create.div(".hp", player), + name: ui.create.div(".name", player), + name2: ui.create.div(".name.name2", player), + nameol: ui.create.div(".nameol", player), + count: ui.create.div(".count", player).hide(), + equips: ui.create.div(".equips", player).hide(), + judges: ui.create.div(".judges", player), + marks: ui.create.div(".marks", player), + chain: ui.create.div(".chain", "
                                    ", player), + handcards1: ui.create.div(".handcards"), + handcards2: ui.create.div(".handcards"), + expansions: ui.create.div(".expansions"), + }); + player.node.handcards1._childNodesWatcher = new ChildNodesWatcher(player.node.handcards1); + player.node.handcards2._childNodesWatcher = new ChildNodesWatcher(player.node.handcards2); + if (lib.config.equip_span) { + let observer = new MutationObserver((mutationsList) => { + for (let mutation of mutationsList) { + if (mutation.type === "childList") { + const addedNodes = Array.from(mutation.addedNodes); + const removedNodes = Array.from(mutation.removedNodes); + // @ts-ignore + if ( + addedNodes.some((card) => !card.classList.contains("emptyequip")) || + // @ts-ignore + removedNodes.some((card) => !card.classList.contains("emptyequip")) + ) { + player.$handleEquipChange(); + } + } + } + }); + const config = { childList: true }; + observer.observe(node.equips, config); + } + node.expansions.style.display = "none"; + const chainLength = game.layout == "default" ? 64 : 40; + for (let repetition = 0; repetition < chainLength; repetition++) { + ui.create.div(node.chain.firstChild, ".cardbg").style.transform = `translateX(${ + repetition * 5 - 5 + }px)`; + } + node.action = ui.create.div(".action", node.avatar); + } + buildExtra() { + let player = this; + let node = player.node; + node.link = player.mark(" ", { + mark: get.linkintro, + }); + // @ts-ignore + node.link.firstChild.setBackgroundImage("image/card/tiesuo_mark.png"); + // @ts-ignore + node.link.firstChild.style.backgroundSize = "cover"; + ui.create.div(node.identity); + } + buildProperty() { + let player = this; + player.phaseNumber = 0; + player.skipList = []; + player.skills = []; + player.invisibleSkills = []; + player.initedSkills = []; + player.additionalSkills = {}; + player.disabledSkills = {}; + player.hiddenSkills = []; + player.awakenedSkills = []; + player.forbiddenSkills = {}; + player.popups = []; + player.damagepopups = []; + player.judging = []; + player.stat = [ + { + card: {}, + skill: {}, + }, + ]; + player.actionHistory = [ + { + useCard: [], + respond: [], + skipped: [], + lose: [], + gain: [], + sourceDamage: [], + damage: [], + custom: [], + useSkill: [], + }, + ]; + player.tempSkills = {}; + player.storage = {}; + player.marks = {}; + player.expandedSlots = {}; + player.disabledSlots = {}; + player.ai = { + friend: [], + enemy: [], + neutral: [], + handcards: { + global: [], + source: [], + viewed: [], + }, + }; + player.queueCount = 0; + player.outCount = 0; + } + buildEventListener(noclick) { + let player = this; + let node = player.node; + if (noclick) player.noclick = true; + else { + player.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.target); + node.identity.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.identity); + if (lib.config.touchscreen) player.addEventListener("touchstart", ui.click.playertouchstart); + } + } + /** @type { SMap } */ + node; + /** + * @type { number } + */ + phaseNumber; + /** + * @type { string[] } + */ + skipList; + /** + * @type { string[] } + */ + skills; + /** + * @type { string[] } + */ + invisibleSkills; + /** + * @type { string[] } + */ + initedSkills; + /** + * @type { SMap } + */ + additionalSkills; + /** + * @type { SMap } + */ + disabledSkills; + /** + * @type { string[] } + */ + hiddenSkills; + /** + * @type { string[] } + */ + awakenedSkills; + /** + * @type { SMap } + */ + forbiddenSkills; + /** + * @type { any[] } + */ + popups; + /** + * @type { any[] } + */ + damagepopups; + /** + * @type { Card[] } + */ + judging; + /** + * @type { { card:{}, skill: {} }[] } + */ + stat; + /** + * @type { { + * useCard: GameEventPromise[], + * respond: GameEventPromise[], + * skipped: GameEventPromise[], + * lose: GameEventPromise[], + * gain: GameEventPromise[], + * sourceDamage: GameEventPromise[], + * damage: GameEventPromise[], + * custom: GameEventPromise[], + * useSkill: GameEventPromise[], + * }[] } + */ + actionHistory; + /** + * @type { SMap } + */ + tempSkills; + /** + * @type { SMap } + */ + storage; + /** + * @type { SMap } + */ + marks; + /** + * @type { SMap } + */ + expandedSlots; + /** + * @type { SMap } + */ + disabledSlots; + /** + * @type { { + * friend: [], + * enemy: [], + * neutral: [], + * handcards: { + * global: [], + * source: [], + * viewed: [] + * } + * } } + */ + ai; + /** + * @type { number } + */ + queueCount; + /** + * @type { number } + */ + outCount; + /** + * @type { number } + */ + maxHp; + /** + * @type { number } + */ + hp; + /** + * @type { number } + */ + hujia; + /** + * @type { number } + */ + seatNum; + /** + * @type { Player } + */ + nextSeat; + /** + * @type { Player } + */ + next; + /** + * @type { Player } + */ + previousSeat; + /** + * @type { Player } + */ + previous; + /** + * @type { string } + */ + name; + /** + * @type { string } + */ + name1; + /** + * @type { string } + */ + name2; + /** + * @type { any[] } + */ + tempname; + /** + * @type { string } + */ + sex; + /** + * @type { string } + */ + group; + /** + * @type { ((player: this) => any)[] } + */ + inits; + /** + * @type { ((player: this) => any)[] } + */ + _inits; + //新函数 + /** + * 怒气 + * @param { number } amount + * @param { boolean } [limit] + */ + changeFury(amount, limit) { + if (typeof this.storage.stratagem_fury != "number") this.storage.stratagem_fury = 0; + if (!amount) return; + const furyBefore = this.storage.stratagem_fury; + if (limit === true && typeof _status.stratagemFuryMax == "number") + this.storage.stratagem_fury = Math.min( + Math.max(furyBefore + amount, 0), + _status.stratagemFuryMax + ); + else this.storage.stratagem_fury = Math.max(furyBefore + amount, 0); + const difference = this.storage.stratagem_fury - furyBefore; + if (!difference) return; + game.log( + this, + difference > 0 ? "获得了" : "失去了", + get.cnNumber(Math.abs(difference)), + "点", + "#r怒气" + ); + this.markSkill("stratagem_fury"); + } + /** + * version 1.7 + * + * 链式创建一次性技能的api。 + * + * 使用者只需要关注技能的效果,而不是技能的本身。 + * + * v1.7 可传递作用域 + * @example + * ```js + * (function () { + * let _var = 1; + * let me = player; + * player.when('drawAfter') + * .apply(code => eval(code)) + * .then(() => console.log(_var)) + * .then('me.gainMaxHp(5)'); + * })(); + * ``` + */ + when() { + const player = this; + if (!_status.postReconnect.player_when) + _status.postReconnect.player_when = [ + function (map) { + "use strict"; + for (let i in map) { + lib.skill[i] = { + charlotte: true, + forced: true, + popup: false, + }; + if (typeof map[i] == "string") lib.translate[i] = map[i]; + } + }, + {}, + ]; + let triggerNames = Array.from(arguments); + let trigger; + let instantlyAdd = true; + if (triggerNames.length == 0) throw "player.when的参数数量应大于0"; + //从triggerNames中取出instantlyAdd的部分 + if (triggerNames.includes(false)) { + instantlyAdd = false; + triggerNames.remove(false); + } + // add other triggerNames + // arguments.length = 1 + if (triggerNames.length == 1) { + // 以下两种情况: + // triggerNames = [ ['xxAfter', ...args] ] + // triggerNames = [ 'xxAfter' ] + if (Array.isArray(triggerNames[0]) || typeof triggerNames[0] == "string") + trigger = { player: triggerNames[0] }; + // triggerNames = [ {player:'xxx'} ] + else if (get.is.object(triggerNames[0])) trigger = triggerNames[0]; + } + // arguments.length > 1 + else { + // triggerNames = [ 'xxAfter', 'yyBegin' ] + if (triggerNames.every((t) => typeof t == "string")) trigger = { player: triggerNames }; + // triggerNames = [ {player: 'xxAfter'}, {global: 'yyBegin'} ] + // 此处不做特殊的合并处理,由使用者自行把握,同名属性后者覆盖前者 + else if (triggerNames.every((t) => get.is.object(t))) + trigger = triggerNames.reduce((pre, cur) => Object.assign(pre, cur)); + } + if (!trigger) throw "player.when传参数类型错误:" + triggerNames; + let skillName; + do { + skillName = "player_when_" + Math.random().toString(36).slice(-8); + } while (lib.skill[skillName] != null); + const after = `${skillName}After`; + if (!trigger.player) trigger.player = after; + else if (Array.isArray(trigger.player)) trigger.player.add(after); + else if (typeof trigger.player == "string") trigger.player = [trigger.player, after]; + const vars = {}; + /** + * 作用域 + * @type { (code: string) => any } + */ + let scope; + /** @type { Skill } */ + let skill = { + trigger: trigger, + forced: true, + charlotte: true, + popup: false, + // 必要条件 + /** @type { Required['filter'][] } */ + filterFuns: [], + // 充分条件 + /** @type { Required['filter'][] } */ + filter2Funs: [], + /** @type { Required['content'][] } */ + contentFuns: [], + // 外部变量 + get vars() { + return vars; + }, + get filter() { + return (event, player, name) => { + if (name == `${skillName}After`) { + skill.popup = false; + return true; + } + return ( + skill.filterFuns.every((fun) => Boolean(fun(event, player, name))) && + skill.filter2(event, player, name) + ); + }; + }, + get filter2() { + return (event, player, name) => { + return ( + skill.filter2Funs.length == 0 || + skill.filter2Funs.some((fun) => Boolean(fun(event, player, name))) + ); + }; + }, + }; + const warnVars = [ + "event", + "step", + "source", + "player", + "target", + "targets", + "card", + "cards", + "skill", + "forced", + "num", + "trigger", + "result", + ]; + const errVars = ["_status", "lib", "game", "ui", "get", "ai"]; + const createContent = () => { + let varstr = ""; + for (const key in vars) { + if (warnVars.includes(key)) + console.warn(`Variable '${key}' should not be referenced by vars objects`); + if (errVars.includes(key)) + throw new Error(`Variable '${key}' should not be referenced by vars objects`); + varstr += `var ${key}=lib.skill['${skillName}'].vars['${key}'];\n`; + } + let str = ` + function content(){ + ${varstr}if(event.triggername=='${skillName}After'){ + player.removeSkill('${skillName}'); + delete lib.skill['${skillName}']; + delete lib.translate['${skillName}']; + return event.finish(); + } + `; + for (let i = 0; i < skill.contentFuns.length; i++) { + const fun2 = skill.contentFuns[i]; + const a = fun2.toString(); + //防止传入()=>xxx的情况 + const begin = + a.indexOf("{") == a.indexOf("}") && a.indexOf("{") == -1 && a.indexOf("=>") > -1 + ? a.indexOf("=>") + 2 + : a.indexOf("{") + 1; + const str2 = a.slice(begin, a.lastIndexOf("}") != -1 ? a.lastIndexOf("}") : undefined).trim(); + str += `'step ${i}'\n\t${str2}\n\t`; + } + skill.content = lib.init.parsex((scope || eval)(str + `\n};content;`), scope); + // @ts-ignore + skill.content._parsed = true; + }; + Object.defineProperty(lib.skill, skillName, { + configurable: true, + //这类技能不需要被遍历到 + enumerable: false, + writable: true, + value: skill, + }); + game.broadcast(function (skillName) { + Object.defineProperty(lib.skill, skillName, { + configurable: true, + enumerable: false, + writable: true, + value: { + forced: true, + charlotte: true, + popup: false, + vars: {}, + }, + }); + }, skillName); + if (instantlyAdd !== false) this.addSkill(skillName); + _status.postReconnect.player_when[1][skillName] = true; + return { + /** + * @param { Required['filter'] } fun + */ + filter(fun) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + skill.filterFuns.push(fun); + return this; + }, + /** + * @param { Required['filter'] } fun + */ + removeFilter(fun) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + skill.filterFuns.remove(fun); + return this; + }, + /** + * @param { Required['filter'] } fun + */ + filter2(fun) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + skill.filter2Funs.push(fun); + return this; + }, + /** + * @param { Required['filter'] } fun + */ + removeFilter2(fun) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + skill.filter2Funs.remove(fun); + return this; + }, + /** + * @param { Required['content'] } fun + */ + then(fun) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + skill.contentFuns.push(fun); + createContent(); + return this; + }, + /** + * @param { string } str + */ + popup(str) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + if (typeof str == "string") skill.popup = str; + return this; + }, + /** + * @param { string } translation + */ + translation(translation) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + if (typeof translation == "string") { + _status.postReconnect.player_when[1][skillName] = translation; + game.broadcastAll( + (skillName, translation) => (lib.translate[skillName] = translation), + skillName, + translation + ); + } + return this; + }, + /** + * @param { SMap } obj + */ + assign(obj) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + if (typeof obj == "object" && obj !== null) Object.assign(skill, obj); + return this; + }, + /** + * @param { SMap } arg + */ + vars(arg) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + if (!get.is.object(arg)) throw "vars的第一个参数必须为对象"; + Object.assign(vars, arg); + createContent(); + return this; + }, + /** + * 传递外部作用域 + * + * 一般是传递一个 code=>eval(code) 函数 + * + * 传递后可在then中使用外部变量(vars的上位替代) + * + * @param {Function} _scope + */ + apply(_scope) { + if (lib.skill[skillName] != skill) throw `This skill has been destroyed`; + // @ts-ignore + scope = _scope; + if (skill.contentFuns.length > 0) createContent(); + return this; + }, + /** + * 获得技能 + * 如果instantlyAdd为false,则需要以此法获得技能 + **/ + finish() { + player.addSkill(skillName); + return this; + }, + }; + } + /** + * 让一名角色明置一些手牌 + */ + addShownCards() { + const cards = [], + tags = []; + for (const argument of arguments) { + const type = get.itemtype(argument); + if (type == "cards") cards.addArray(argument); + else if (type == "card") cards.add(argument); + else if (typeof argument == "string" && argument.startsWith("visible_")) tags.add(argument); + } + if (!cards.length || !tags.length) return; + const next = game.createEvent("addShownCards", false); + next.player = this; + next._cards = cards; + next.gaintag = tags; + next.setContent("addShownCards"); + return next; + } + hideShownCards() { + const cards = [], + tags = []; + for (const argument of arguments) { + const type = get.itemtype(argument); + if (type == "cards") cards.addArray(argument); + else if (type == "card") cards.add(argument); + else if (typeof argument == "string" && argument.startsWith("visible_")) tags.add(argument); + } + if (!cards.length) return; + const next = game.createEvent("hideShownCards", false); + next.player = this; + next._cards = cards; + next.gaintag = tags; + next.setContent("hideShownCards"); + return next; + } + /** + * 获取角色所有的明置手牌 + */ + getShownCards() { + return this.getCards("h", (card) => { + return get.is.shownCard(card); + }); + } + /** + * 获取该角色被other所知的牌 + * @param { Player } [other] + * @param { (card: Card) => boolean } [filter] + */ + getKnownCards(other = _status.event.player, filter = (card) => true) { + if (!other) { + if (other === null) + console.trace(`getKnownCards的other参数不应传入null,可以用void 0或undefined占位`); + other = _status.event.player || this; + } + if (!filter) { + if (other === null) + console.trace(`getKnownCards的filter参数不应传入null,可以用void 0或undefined占位`); + filter = (card) => true; + } + return this.getCards("h", (card) => { + return card.isKnownBy(other) && filter(card); + }); + } + /** + * 判断此角色的手牌是否已经被看光了 + * @param { Player } [other] + */ + isAllCardsKnown(other = _status.event.player) { + if (!other) { + if (other === null) + console.trace(`isAllCardsKnown的other参数不应传入null,可以用void 0或undefined占位`); + other = _status.event.player || this; + } + if (!other) other = this; + return ( + this.countCards("h", (card) => { + return !card.isKnownBy(other); + }) == 0 + ); + } + /** + * 判断此角色是否有被知的牌。 + * @param { Player } [other] + * @param { (card: Card) => boolean } [filter] + */ + hasKnownCards(other = _status.event.player, filter = (card) => true) { + if (!other) { + if (other === null) + console.trace(`hasKnownCards的other参数不应传入null,可以用void 0或undefined占位`); + other = _status.event.player || this; + } + if (!filter) { + if (other === null) + console.trace(`hasKnownCards的filter参数不应传入null,可以用void 0或undefined占位`); + filter = (card) => true; + } + return ( + this.countCards("h", (card) => { + return card.isKnownBy(other) && filter(card); + }) > 0 + ); + } + /** + * 数此角色被知道的牌 + * @param { Player } [other] + * @param { (card: Card) => boolean } [filter] + */ + countKnownCards(other, filter) { + return this.getKnownCards(other, filter).length; + } + /** + * Execute the delay card effect + * + * 执行延时锦囊牌效果 + * @param { Card | string } card + * @param { Player } target + * @param {*} judge + * @param {*} judge2 + * @returns + */ + executeDelayCardEffect(card, target, judge, judge2) { + const executeDelayCardEffect = game.createEvent("executeDelayCardEffect"); + executeDelayCardEffect.player = this; + executeDelayCardEffect.target = target || this; + if (typeof card == "string") { + const virtualCard = (executeDelayCardEffect.card = ui.create.card()); + virtualCard._destroy = true; + virtualCard.expired = true; + const info = lib.card[card]; + virtualCard.init(["", "", card, info && info.cardnature]); + } else if (get.itemtype(card) == "card") executeDelayCardEffect.card = card; + else { + _status.event.next.remove(executeDelayCardEffect); + executeDelayCardEffect.resolve(); + } + executeDelayCardEffect.judge = judge; + executeDelayCardEffect.judge2 = judge2; + executeDelayCardEffect.setContent("executeDelayCardEffect"); + executeDelayCardEffect._args = Array.from(arguments); + return executeDelayCardEffect; + } + /** + * Check if the card does not count toward hand limit + * + * 检测此牌是否不计入手牌上限 + * @param { Card } card + */ + canIgnoreHandcard(card) { + return lib.filter.ignoredHandcard(card, this); + } + //Gift + /** + * Gift + * + * 赠予 + * @param { Card | Card[] } cards + * @param { Player } target + */ + gift(cards, target) { + const gift = game.createEvent("gift"); + gift.player = this; + gift.target = target; + const isArray = Array.isArray(cards); + if (cards && !isArray) gift.cards = [cards]; + else if (isArray && cards.length) gift.cards = cards; + else { + _status.event.next.remove(gift); + gift.resolve(); + } + gift.deniedGifts = []; + gift.setContent("gift"); + gift._args = Array.from(arguments); + return gift; + } + /** + * Check if the player can gift the card + * + * 检测角色是否能赠予此牌 + * @param { Card } card + * @param { Player } target + * @param { boolean } [strict] + */ + canGift(card, target, strict) { + return lib.filter.cardGiftable(card, this, target, strict); + } + /** + * Check if the player refuses gifts + * + * 检测角色是否拒绝赠予 + * @param { Card } card + * @param { Player } player + */ + refuseGifts(card, player) { + return this.hasSkillTag("refuseGifts", null, { + player: player, + card: card, + }); + } + /** + * Gift AI related + * + * 赠予AI相关 + * @param { Card } card + * @param { Player } target + */ + getGiftAIResultTarget(card, target) { + if (!card || target.refuseGifts(card, this)) return 0; + if (get.type(card, false) == "equip") return get.effect(target, card, target, target); + if (card.name == "du") return this.hp > target.hp ? -1 : 0; + if (target.hasSkillTag("nogain")) return 0; + return Math.max(1, get.value(card, this) - get.value(card, target)); + } + /** + * @param { Card } card + * @param { Player } target + */ + getGiftEffect(card, target) { + return this.getGiftAIResultTarget(card, target) * get.attitude(this, target); + } + //Recast + /** + * 重铸 + * @param { Card | Card[] } cards + * @param { (player: Player, cards: Card[]) => any } [recastingLose] + * @param { (player: Player, cards: Card[]) => any } [recastingGain] + */ + recast( + cards, + recastingLose = (player, cards) => (player.loseToDiscardpile(cards).log = false), + recastingGain = (player, cards) => (player.draw(cards.length).log = false) + ) { + const recast = game.createEvent("recast"); + recast.player = this; + const isArray = Array.isArray(cards); + if (cards && !isArray) recast.cards = [cards]; + else if (isArray && cards.length) recast.cards = cards; + else { + _status.event.next.remove(recast); + recast.resolve(); + } + if (typeof recastingLose != "function") { + if (recastingLose === null) + console.trace(`recast的recastingLose参数不应传入null,可以用void 0或undefined占位`); + recastingLose = (player, cards) => (player.loseToDiscardpile(cards).log = false); + } + recast.recastingLose = recastingLose; + recast.recastingLosingEvents = []; + if (typeof recastingGain != "function") { + if (recastingLose === null) + console.trace(`recast的recastingGain参数不应传入null,可以用void 0或undefined占位`); + recastingGain = (player, cards) => (player.draw(cards.length).log = false); + } + recast.recastingGain = recastingGain; + recast.recastingGainingEvents = []; + recast.setContent("recast"); + recast._args = Array.from(arguments); + return recast; + } + /** + * Check if the player can recast the card + * + * 检测角色是否能重铸此牌 + * @param { Card } card + * @param { Player } [source] + * @param { boolean } [strict] + */ + canRecast(card, source, strict) { + return lib.filter.cardRecastable(card, this, source, strict); + } + //装备栏相关 + /** + * 判断一名角色的某个区域是否被废除 + * + * type为要判断的区域 若为空 则判断玩家是否有任意一个被废除的区域 + * @param { string | number } [type] + * @returns { boolean } + */ + hasDisabledSlot(type) { + if (type == "horse" || type == "equip3_4") { + return this.hasDisabledSlot(3) && (get.is.mountCombined() || this.hasDisabledSlot(4)); + } else if (get.is.mountCombined() && type == "equip4") { + return false; + } + return this.countDisabledSlot(type) > 0; + } + /** + * 判断一名角色的某个区域被废除的数量 + * + * 用法同 {@link hasDisabledSlot} + * @param { string | number } [type] + */ + countDisabledSlot(type) { + const map = this.disabledSlots || {}; + let num; + if (type == undefined) { + num = 0; + for (let i = 1; i <= 5; i++) { + num += this.countDisabledSlot(i); + } + return num; + } else { + if (typeof type == "number") type = "equip" + type; + if (get.is.mountCombined() && type == "equip4") { + return 0; + } + num = map[type]; + if (typeof num == "number" && num > 0) return num; + return 0; + } + } + /** + * 判断一名角色是否有某个装备栏空着 + * @param { string | number } [type] + * @returns { boolean } + */ + hasEmptySlot(type) { + if (type == "horse" || type == "equip3_4") { + return this.hasEmptySlot(3) && (get.is.mountCombined() || this.hasEmptySlot(4)); + } else if (get.is.mountCombined() && type == "equip4") { + return false; + } + return this.countEmptySlot(type) > 0; + } + /** + * 判断一名角色的某个装备栏空位的数量 + * @param { string | number } [type] + */ + countEmptySlot(type) { + if (!type) return 0; + if (typeof type == "number") type = "equip" + type; + else if (type == "equip3_4") { + type = "equip3"; + } + return Math.max( + 0, + this.countEnabledSlot(type) - + this.getEquips(type).reduce((num, card) => { + let types = get.subtypes(card, false); + return num + get.numOf(types, type); + }, 0) + ); + } + /** + * 判断一名角色是否有可以用于装备新装备牌的区域(排除金箍棒和六龙等“不可被替换装备”) + * + * 用法同 {@link hasEnabledSlot} + * @param { string | number } [type] + */ + hasEquipableSlot(type) { + return this.countEquipableSlot(type) > 0; + } + /** + * 统计一名角色有多少个可以用于装备新的装备牌的区域 + * + * 用法同 {@link hasEnabledSlot} + * @param { string | number } [type] + */ + countEquipableSlot(type) { + if (!type) return 0; + 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, + this.countEnabledSlot(type) - + this.getEquips(type).reduce((num, card) => { + let types = get.subtypes(card, false); + if (!lib.filter.canBeReplaced(card, this)) num += get.numOf(types, type); + return num; + }, 0) + ); + } + /** + * 判断一名角色是否拥有未被废除的某个区域 + * + * type为要判断的区域 若为空 则判断玩家是否有任意一个未被废除的区域 + * @param { string | number } [type] + * @returns { boolean } + */ + hasEnabledSlot(type) { + if (type == "horse" || type == "equip3_4") { + return this.hasEnabledSlot(3) && (get.is.mountCombined() || this.hasEnabledSlot(4)); + } + // else if(type=='equip3_4'){ + // type='equip3'; + // } + else if (get.is.mountCombined() && type == "equip4") { + return false; + } + return this.countEnabledSlot(type) > 0; + } + /** + * 判断一名角色的某个区域未被废除的数量 + * + * 用法同 {@link hasEnabledSlot} + * @param { string | number } [type] + */ + countEnabledSlot(type) { + const map = this.expandedSlots || {}; + let num; + if (!type) { + num = 0; + for (let i = 1; i <= 5; i++) { + num += this.countEnabledSlot(i); + } + return num; + } else { + if (typeof type == "number") type = "equip" + type; + if (get.is.mountCombined() && type == "equip4") { + return 0; + } + let slots = 1; + num = map[type]; + if (typeof num == "number" && num > 0) slots += num; + slots -= this.countDisabledSlot(type); + return slots; + } + } + /** + * 获取一名角色装备区内某种类型的装备牌 + * + * 参数可以为数字/区域字符串/实体牌/虚拟牌/牌名 + * @param { number | string | Card | VCard } subtype + * @returns { Card[] } + */ + getEquips(subtype) { + switch (typeof subtype) { + case "string": + 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]) { + return this.getCards("e", (card) => card.name == subtype); + } else return []; + case "number": + subtype = "equip" + subtype; + break; + case "object": + subtype = get.subtype(subtype, false); + break; + default: + return []; + } + if (!subtype) return []; + return this.getCards("e", (card) => { + // @ts-ignore + return get.subtypes(card, false).includes(subtype); + }); + } + /** + * 新的废除装备区 + * + * 参数:废除来源角色(不写默认当前事件角色),废除区域(数字/区域字符串/数组,可以写多个,重复废除) + */ + disableEquip() { + var next = game.createEvent("disableEquip"); + next.player = this; + next.slots = []; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (Array.isArray(arguments[i])) { + for (var arg of arguments[i]) { + if (typeof arg == "string") { + if (arg.startsWith("equip") && parseInt(arg.slice(5)) > 0) next.slots.push(arg); + } else if (typeof arg == "number") { + next.slots.push("equip" + arg); + } + } + } else if (typeof arguments[i] == "string") { + if (arguments[i].startsWith("equip") && parseInt(arguments[i].slice(5)) > 0) + next.slots.push(arguments[i]); + } else if (typeof arguments[i] == "number") { + next.slots.push("equip" + arguments[i]); + } + } + if (!next.source) next.source = _status.event.player; + if (!next.slots.length) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("disableEquip"); + return next; + } + /** + * 新的恢复装备区 + * + * 参数:恢复来源角色(不写默认当前事件角色),恢复区域(数字/区域字符串/数组,可以写多个,重复恢复) + */ + enableEquip() { + var next = game.createEvent("enableEquip"); + next.player = this; + next.slots = []; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (Array.isArray(arguments[i])) { + for (var arg of arguments[i]) { + if (typeof arg == "string") { + if (arg.startsWith("equip") && parseInt(arg.slice(5)) > 0) next.slots.push(arg); + } else if (typeof arg == "number") { + next.slots.push("equip" + arg); + } + } + } else if (typeof arguments[i] == "string") { + if (arguments[i].startsWith("equip") && parseInt(arguments[i].slice(5)) > 0) + next.slots.push(arguments[i]); + } else if (typeof arguments[i] == "number") { + next.slots.push("equip" + arguments[i]); + } + } + if (!next.source) next.source = _status.event.player; + if (!next.slots.length) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("enableEquip"); + return next; + } + /** + * 新的扩展装备区 + * + * 参数:扩展来源角色(不写默认当前事件角色),扩展区域(数字/区域字符串/数组,可以写多个,重复扩展) + */ + expandEquip() { + var next = game.createEvent("expandEquip"); + next.player = this; + next.slots = []; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (Array.isArray(arguments[i])) { + for (var arg of arguments[i]) { + if (typeof arg == "string") { + if (arg.startsWith("equip") && parseInt(arg.slice(5)) > 0) next.slots.push(arg); + } else if (typeof arg == "number") { + next.slots.push("equip" + arg); + } + } + } else if (typeof arguments[i] == "string") { + if (arguments[i].startsWith("equip") && parseInt(arguments[i].slice(5)) > 0) + next.slots.push(arguments[i]); + } else if (typeof arguments[i] == "number") { + next.slots.push("equip" + arguments[i]); + } + } + if (!next.source) next.source = _status.event.player; + if (!next.slots.length) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("expandEquip"); + return next; + } + /** + * 判断判定区是否被废除 + */ + isDisabledJudge() { + return Boolean(this.storage._disableJudge); + } + /** + * 同步显示扩展装备区状态 + * @param { SMap } [map] + */ + $syncExpand(map) { + if (!map) { + map = this.expandedSlots || {}; + } + game.addVideo("$syncExpand", this, get.copy(map)); + game.broadcast( + function (player, map) { + player.expandedSlots = map; + player.$syncExpand(map); + }, + this, + map + ); + this.markSkill("expandedSlots"); + } + /** + * 同步装备区废除牌显示状态 + * @param { SMap } [map] + */ + $syncDisable(map) { + const suits = { equip3: "+1马栏", equip4: "-1马栏", equip6: "特殊栏" }; + if (get.is.mountCombined()) suits.equip3 = "坐骑栏"; + if (!map) { + map = this.disabledSlots || {}; + } + game.addVideo("$syncDisable", this, get.copy(map)); + game.broadcast( + function (player, map) { + player.disabledSlots = map; + player.$syncDisable(map); + }, + this, + map + ); + const map2 = get.copy(map); + /** @type { Card[] } */ + // @ts-ignore + const cards = Array.from(this.node.equips.childNodes); + for (const card of cards) { + if (card.name.startsWith("feichu_")) { + const index = card.name.slice(7); + if (!map2[index]) map2[index] = 0; + map2[index]--; + } + } + for (const index in map2) { + if (!index.startsWith("equip") || !(parseInt(index.slice(5)) > 0)) continue; + const num = map2[index]; + if (num > 0) { + for (let i = 0; i < num; i++) { + const card = game.createCard( + "feichu_" + index, + suits[index] || get.translation(index) + "栏", + "" + ); + card.fix(); + card.style.transform = ""; + card.classList.remove("drawinghidden"); + card.classList.add("feichu"); + delete card._transform; + const equipNum = get.equipNum(card); + let equipped = false; + for (let j = 0; j < this.node.equips.childNodes.length; j++) { + if (get.equipNum(this.node.equips.childNodes[j]) >= equipNum) { + this.node.equips.insertBefore(card, this.node.equips.childNodes[j]); + equipped = true; + break; + } + } + if (!equipped) { + this.node.equips.appendChild(card); + if (_status.discarded) { + _status.discarded.remove(card); + } + } + } + } else if (num < 0) { + for (let i = 0; i > num; i--) { + const card = cards.find((card) => card.name == "feichu_" + index); + if (card) { + this.node.equips.removeChild(card); + cards.remove(card); + } + } + } + } + } + //以下函数涉及到本次更新内容而进行修改 + /** + * @param { string | Card | VCard | CardBaseUIData } name + * @param { boolean } [replace] + * @returns + */ + canEquip(name, replace) { + const ranges = get.subtypes(name), + rangex = [], + 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, this)).length; + if (num < num2) return false; + } + return true; + } + //以下函数将不再进行后续维护 + /** + * @deprecated + */ + countDisabled() { + return this.countDisabledSlot(...arguments); + } + /** + * @deprecated + */ + isDisabled(arg) { + return this.hasDisabledSlot(arg) && !this.hasEnabledSlot(arg); + } + /** + * @deprecated + */ + isEmpty(num) { + return this.countEnabledSlot(num) > this.getEquips(num).length; + } + //以下函数将被废弃 + /** + * @deprecated + */ + $disableEquip() {} + /** + * @deprecated + */ + $enableEquip() {} + //装备区End + chooseToDebate() { + var next = game.createEvent("chooseToDebate"); + next.player = this; + next._args = []; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "players") { + next.list = arguments[i].slice(0); + } else { + next._args.push(arguments[i]); + } + } + next.setContent("chooseToDebate"); + return next; + } + /** + * 向target发起协力 + * @param { Player } target + * @param {*} type + * @param {*} reason + */ + cooperationWith(target, type, reason) { + if (!this.storage.cooperation) this.storage.cooperation = []; + const info = { + target, + type, + reason, + }; + this.storage.cooperation.add(info); + this.addTempSkill("cooperation", { player: "dieAfter" }); + this.addSkill("cooperation_" + type, { player: "dieAfter" }); + game.log( + this, + "向", + target, + "发起了“协力”,合作类型是", + "#g" + get.translation("cooperation_" + type) + ); + } + chooseCooperationFor() { + var next = game.createEvent("chooseCooperationFor"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.target = arguments[i]; + } else if (Array.isArray(arguments[i])) { + next.cardlist = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.reason = arguments[i]; + } + } + if (!next.cardlist) + next.cardlist = [ + "cooperation_damage", + "cooperation_draw", + "cooperation_discard", + "cooperation_use", + ]; + next.setContent("chooseCooperationFor"); + return next; + } + checkCooperationStatus(target, reason) { + var storage = this.getStorage("cooperation"); + for (var info of storage) { + if (info.target == target && info.reason == reason) { + var skill = lib.skill["cooperation_" + info.type]; + if (skill && skill.checkx && skill.checkx(info)) return true; + } + } + return false; + } + removeCooperation(info) { + let storage = this.getStorage("cooperation"); + if (!storage.includes(info)) return; + storage.remove(info); + let unmark = true, + reason = info.type; + if (!storage.length) { + this.removeSkill("cooperation"); + } else { + for (let i of storage) { + if (i.type == reason) { + unmark = false; + break; + } + } + } + if (unmark) this.removeSkill("cooperation_" + reason); + else this.markSkill("cooperation_" + reason); + } + /** + * @param { string } clan 氏族名称 + * @param { boolean } unseen 是否无视暗将的限制 + */ + hasClan(clan, unseen) { + if (unseen || !this.isUnseen(0)) { + let info = lib.character[this.name1]; + if (info && info[4]) { + for (let i of info[4]) { + if (typeof i == "string" && i.startsWith("clan:") && i.slice(5) == clan) return true; + } + } + } + if (this.name2 && (unseen || !this.isUnseen(1))) { + let info = lib.character[this.name2]; + if (info && info[4]) { + for (let i of info[4]) { + if (typeof i == "string" && i.startsWith("clan:") && i.slice(5) == clan) return true; + } + } + } + return false; + } + /** + * @param { string } skill + */ + changeZhuanhuanji(skill) { + let info = get.info(skill), + zhuanhuan = info.zhuanhuanji; + if (typeof zhuanhuan == "function") zhuanhuan(this, skill); + else if (zhuanhuan == "number") this.addMark(skill, 1, false); + else this.storage[skill] = !this.storage[skill]; + game.broadcastAll( + function (player, skill) { + player.$changeZhuanhuanji(skill); + }, + this, + skill + ); + } + /** + * @param { string } skill + */ + $changeZhuanhuanji(skill) { + var mark = this.marks[skill]; + if (mark) { + // @ts-ignore + if (mark.firstChild.reversed) { + // @ts-ignore + mark.firstChild.reversed = false; + // @ts-ignore + mark.firstChild.style.transform = "none"; + } else { + // @ts-ignore + mark.firstChild.reversed = true; + // @ts-ignore + mark.firstChild.style.transform = "rotate(180deg)"; + } + } + } + /** + * @param { number } num + */ + setSeatNum(num) { + _status.seatNumSettled = true; + game.broadcastAll( + function (player, num) { + player.seatNum = num; + }, + this, + num + ); + } + getSeatNum() { + if (typeof this.seatNum == "number") return this.seatNum; + return 0; + } + /** + * 是否拥有某一性别 + * @param { string } sex + */ + hasSex(sex) { + if (this.sex == "unknown") return false; + if (this.sex == "double") return true; + return this.sex == sex; + } + /** + * 是否和target同一性别 + * @param { Player } target + */ + sameSexAs(target) { + const sex1 = this.sex, + sex2 = target.sex; + if (sex1 == "unknown" || sex2 == "unknown") return false; + if (sex1 == "double" || sex2 == "double") return true; + return sex1 == sex2; + } + /** + * 是否和target不同性别 + * @param { Player } target + */ + differentSexFrom(target) { + var sex1 = this.sex, + sex2 = target.sex; + if (sex1 == "unknown" || sex2 == "unknown") return false; + if (sex1 == "double" || sex2 == "double") return true; + return sex1 != sex2; + } + /** + * @param { string } skill + */ + addSkillBlocker(skill) { + if (!this.storage.skill_blocker) this.storage.skill_blocker = []; + this.storage.skill_blocker.push(skill); + } + /** + * @param { string } skill + */ + removeSkillBlocker(skill) { + if (this.storage.skill_blocker) { + this.storage.skill_blocker.remove(skill); + if (!this.storage.skill_blocker.length) delete this.storage.skill_blocker; + } + } + loseToSpecial(cards, tag, target) { + var next = game.loseAsync({ + player: this, + cards: cards, + tag: tag, + toStorage: true, + target: target || this, + }); + next.setContent(function () { + "step 0"; + player.lose(cards, ui.special).set("getlx", false); + "step 1"; + var cards = event.cards.slice(0); + cards.removeArray(player.getCards("hejsx")); + if (cards.length) target.directgains(cards, null, event.tag); + }); + return next; + } + /** + * @param { Card | Card[] } cards + * @param { string } tag + */ + addGaintag(cards, tag) { + if (get.itemtype(cards) == "card") cards = [cards]; + game.addVideo("addGaintag", this, [get.cardsInfo(cards), tag]); + game.broadcastAll( + function (player, cards, tag) { + var hs = player.getCards("hejsx"); + for (var i of cards) { + if (hs.includes(i)) i.addGaintag(tag); + } + }, + this, + cards, + tag + ); + } + /** + * @param { string } tag + * @param { Card[] } [cards] + */ + removeGaintag(tag, cards) { + cards = cards || this.getCards("h"); + game.addVideo("removeGaintag", this, [tag, get.cardsInfo(cards)]); + game.broadcastAll( + function (player, tag, cards) { + for (var i of cards) i.removeGaintag(tag); + }, + this, + tag, + cards + ); + } + /** + * @param { Player } target + */ + canSave(target) { + if (this.hasSkillTag("save", true, target, true)) return true; + let name = {}, + hs = this.iterableGetCards("hs"); + for (let i of hs) name[get.name(i)] = true; + for (let i in lib.card) { + if (lib.card[i].savable && (lib.inpile.includes(i) || name[i])) { + if ( + lib.filter.cardSavable({ name: i }, this, target) && + (_status.connectMode || this.hasUsableCard(i)) + ) + return true; + } + } + return false; + } + /** + * @param { Card } card + * @param { Player } target + */ + canSaveCard(card, target) { + const mod2 = game.checkMod(card, this, "unchanged", "cardEnabled2", this); + if (mod2 != "unchanged") return mod2; + const mod = game.checkMod(card, this, target, "unchanged", "cardSavable", this); + if (mod != "unchanged") return mod; + let savable = get.info(card).savable; + if (typeof savable == "function") savable = savable(card, this, target); + return savable; + } + /** + * @param { String } from + * @param { String } to + * @returns { GameEventPromise } + */ + reinitCharacter(from, to, log = true) { + const rawPairs = [this.name1]; + if (this.name2) rawPairs.push(this.name2); + for (let i = 0; i < rawPairs.length; i++) { + if (rawPairs[i] == from) { + rawPairs[i] = to; + break; + } + } + return this.changeCharacter(rawPairs, log); + } + /** + * @param { String[] } newPairs + * @returns { GameEventPromise } + */ + changeCharacter(newPairs, log = true) { + if (!Array.isArray(newPairs)) { + console.warn(`警告:Player[${this.name}].changeCharacter填写了一个错误的参数:`, newPairs); + return; + } + for (let name of newPairs) { + if (!lib.character[name]) { + console.warn(`警告:Player[${this.name}]试图将武将牌变更为不存在的武将:`, name); + return; + } + } + const next = game.createEvent("changeCharacter"); + next.player = this; + next.newPairs = newPairs; + next.log = log; + next.setContent("changeCharacter"); + return next; + } + /** + * @param { 0 | 1 | 2 } num + * @param { false } [log] + */ + showCharacter(num, log) { + var toShow = []; + if ((num == 0 || num == 2) && this.isUnseen(0)) toShow.add(this.name1); + if ((num == 1 || num == 2) && this.isUnseen(1)) toShow.add(this.name2); + if (!toShow.length) return; + this.$showCharacter(num, log); + var next = game.createEvent("showCharacter", false); + next.player = this; + next.num = num; + next.toShow = toShow; + next._args = Array.from(arguments); + next.setContent("showCharacter"); + var evt = _status.event; + evt.next.remove(next); + if (evt.logSkill) evt = evt.getParent(); + evt.after.push(next); + return next; + } + /** + * @param { 0 | 1 | 2 } num + * @param { false } [log] + */ + $showCharacter(num, log) { + if (num == 0 && !this.isUnseen(0)) { + return; + } + if (num == 1 && (!this.name2 || !this.isUnseen(1))) { + return; + } + if (!this.isUnseen(2)) { + return; + } + game.addVideo("showCharacter", this, num); + var skills; + switch (num) { + case 0: + if (log !== false) game.log(this, "展示了主将", "#b" + this.name1); + this.name = this.name1; + skills = lib.character[this.name][3] || []; + this.sex = lib.character[this.name][0]; + if (this.group == "unknown") this.group = lib.character[this.name][1]; + this.classList.remove("unseen"); + this.classList.remove("unseen_show"); + break; + case 1: + if (log !== false) game.log(this, "展示了副将", "#b" + this.name2); + skills = lib.character[this.name2][3] || []; + if (this.sex == "unknown") this.sex = lib.character[this.name2][0]; + if (this.name.startsWith("unknown")) this.name = this.name2; + this.classList.remove("unseen2"); + this.classList.remove("unseen2_show"); + break; + case 2: + if (log !== false) { + if (this.name2) + game.log(this, "展示了主将", "#b" + this.name1, "、副将", "#b" + this.name2); + else game.log(this, "展示了主将", "#b" + this.name1); + } + this.name = this.name1; + var skills = lib.character[this.name][3] || []; + if (this.name2) skills = skills.concat(lib.character[this.name2][3] || []); + this.sex = lib.character[this.name][0]; + if (this.group == "unknown") this.group = lib.character[this.name][1]; + this.classList.remove("unseen"); + this.classList.remove("unseen2"); + this.classList.remove("unseen_show"); + this.classList.remove("unseen2_show"); + break; + } + if (!this.isUnseen(2)) { + delete this.storage.nohp; + this.hp = this.storage.rawHp + this.maxHp - 1; + this.maxHp = this.storage.rawMaxHp + this.maxHp - 1; + this.node.hp.show(); + this.update(); + } + game.broadcast( + function (player, name, sex, num, group) { + player.group = group; + player.name = name; + player.sex = sex; + switch (num) { + case 0: + player.classList.remove("unseen"); + break; + case 1: + player.classList.remove("unseen2"); + break; + case 2: + player.classList.remove("unseen"); + player.classList.remove("unseen2"); + break; + } + if (!player.isUnseen(2)) { + delete player.storage.nohp; + player.node.hp.show(); + player.update(); + } + }, + this, + this.name, + this.sex, + num, + this.group + ); + skills = skills.filter((skill) => { + var info = get.info(skill); + if (info && info.zhuSkill && !this.isZhu2()) return false; + return true; + }); + for (var i = 0; i < skills.length; i++) { + if (this.hiddenSkills.includes(skills[i])) { + this.hiddenSkills.remove(skills[i]); + this.addSkill(skills[i]); + } + } + this.checkConflict(); + } + chooseToPlayBeatmap(beatmap) { + var next = game.createEvent("chooseToPlayBeatmap"); + next.player = this; + next.beatmap = beatmap; + next._args = Array.from(arguments); + next.setContent("chooseToPlayBeatmap"); + return next; + } + chooseToMove() { + var next = game.createEvent("chooseToMove"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + next.setContent("chooseToMove"); + next.filterOk = function () { + return true; + }; + next.filterMove = function () { + return true; + }; + return next; + } + chooseToGuanxing(num) { + var next = game.createEvent("chooseToGuanxing"); + next.num = num || 1; + next.player = this; + next.setContent("chooseToGuanxing"); + return next; + } + /** + * @param { Player } target + * @param { string } name + * @param {*} rotate + */ + $throwEmotion(target, name, rotate) { + game.addVideo("throwEmotion", this, [target.dataset.position, name]); + var getLeft = function (player) { + if (player == game.me && !ui.fakeme && !ui.chess) + return player.getLeft() + player.node.avatar.offsetWidth / 2; + return player.getLeft() + player.offsetWidth / 2; + }; + var player = this; + var emotion = ui.create.div( + "", + '
                                    ', + game.chess ? ui.chess : ui.window + ); + emotion.style.width = "60px"; + emotion.style.height = "60px"; + var width = emotion.offsetWidth / 2; + var height = emotion.offsetHeight / 2; + if (game.chess) width += 60; + var left = getLeft(player) - width; + var top = player.getTop() + player.offsetHeight / 3 - height; + emotion.style.left = left + "px"; + emotion.style.top = top + "px"; + var left2 = getLeft(target) - width; + var top2 = target.getTop() + target.offsetHeight / 3 - height; + if (["egg", "flower", "shoe"].includes(name) || rotate) { + var num1 = 0.95 + Math.random() * (1.1 - 0.95); + var num2 = 1 + Math.random() * (3 - 1); + var left2 = getLeft(target) / num1 - width; + var top2 = target.getTop() + target.offsetHeight / num2 - height; + } else { + var left2 = getLeft(target) - width; + var top2 = target.getTop() + target.offsetHeight / 3 - height; + } + emotion.style["z-index"] = 10; + emotion.style.transform = "translateY(" + (top2 - top) + "px) translateX(" + (left2 - left) + "px)"; + // @ts-ignore + if (["egg", "flower", "shoe"].includes(name) || rotate) + emotion.firstElementChild.style.transform = "rotate(1440deg)"; + if (lib.config.background_audio) game.playAudio("effect", "throw_" + name + get.rand(1, 2)); + setTimeout(function () { + emotion.innerHTML = + '
                                    '; + setTimeout(function () { + emotion.delete(); + }, 1200); + }, 600); + } + /** + * @param { boolean } bool + */ + tryJudgeAnimate(bool) { + game.broadcast( + function (player, bool) { + player.trySkillAnimate(bool); + }, + this, + bool + ); + if (bool) this.popup("判定生效", "wood", false); + else this.popup("判定失效", "fire", false); + } + /** + * @param { string } name + * @param { string } popname + * @param { 'main' | 'vice' | boolean } checkShow + */ + trySkillAnimate(name, popname, checkShow) { + if ( + !game.online && + lib.config.skill_animation_type != "off" && + lib.skill[name] && + lib.skill[name].skillAnimation + ) { + if (lib.config.skill_animation_type == "default") { + checkShow = checkShow || "main"; + } else { + checkShow = false; + } + if (lib.skill[name].textAnimation) { + checkShow = false; + } + this.$skill( + lib.skill[name].animationStr || lib.translate[name], + lib.skill[name].skillAnimation, + lib.skill[name].animationColor, + checkShow + ); + return; + } + var player = this; + game.broadcast( + function (player, name, popname) { + player.trySkillAnimate(name, popname); + }, + player, + name, + popname + ); + if (lib.animate.skill[name]) lib.animate.skill[name].apply(this, arguments); + else { + if (popname != name) this.popup(popname, "water", false); + else this.popup(get.skillTranslation(name, this), "water", false); + } + } + /** + * @param { Card } card + * @param { string } name + * @param { string } [nature] + * @param { string } [popname] + */ + tryCardAnimate(card, name, nature, popname) { + game.broadcast( + function (player, card, name, nature, popname) { + player.tryCardAnimate(card, name, nature, popname); + }, + this, + card, + name, + nature, + popname + ); + if (lib.animate.card[card.name]) lib.animate.card[card.name].apply(this, arguments); + else { + if (!lib.config.show_card_prompt) return; + if (get.type(card) == "equip" && lib.config.hide_card_prompt_equip) return; + if (get.type(card) == "basic" && lib.config.hide_card_prompt_basic) return; + if (popname) this.popup({ name: card.name, nature: card.nature }, nature, false); + else this.popup(name, nature, false); + } + } + /** + * @param { string } name + * @param { string } type + */ + hasUsableCard(name, type) { + if (typeof type !== "string") type = type ? "limit" : "all"; + if ( + this.hasCard((i) => { + if (get.name(i, this) !== name) return false; + if (type === "all") return true; + let event = _status.event, + evt = event.getParent("chooseToUse"); + if (get.itemtype(evt) !== "event") evt = event; + if (type === "respond") return lib.filter.cardRespondable(i, this, evt); + return lib.filter.cardEnabled(i, this, type === "limit" ? evt : "forceEnable"); + }, "hs") + ) + return true; + const skills = this.getSkills("invisible").concat(lib.skill.global), + str = "respond" + name[0].toUpperCase() + name.slice(1); + game.expandSkills(skills); + for (let i = 0; i < skills.length; i++) { + const ifo = get.info(skills[i]), + hiddenCard = ifo.hiddenCard; + if ( + ifo.viewAs && + typeof ifo.viewAs !== "function" && + typeof ifo.viewAs !== "string" && + ifo.viewAs.name === name + ) { + if (!ifo.viewAsFilter || ifo.viewAsFilter(this) !== false) return true; + } else if (typeof hiddenCard == "function") { + if (hiddenCard(this, name)) return true; + } + /*else if (ifo.ai && ifo.ai[str]) { + if (ifo.ai.skillTagFilter) { + if ((type === 'respond' || type === 'all')&& ifo.ai.skillTagFilter(this, str, 'respond') !== false) return true; + if (type !== 'respond' && ifo.ai.skillTagFilter(this, str, 'use') !== false) return true; + continue; + } + if (type === 'all') return true; + if (typeof ifo.ai[str] === 'string') { + if (ifo.ai[str] === 'use' || type === 'respond' && ifo.ai[str] === type) return true; + } + else return true; + }*/ + } + } + /** + * @param { Player } to + * @returns { boolean } + */ + inRange(to) { + const from = this; + if (from == to || from.hasSkill("undist") || to.hasSkill("undist")) return false; + if (!game.players.includes(from) && !game.dead.includes(from)) return false; + if (!game.players.includes(to) && !game.dead.includes(to)) return false; + const mod1 = game.checkMod(from, to, "unchanged", "inRange", from); + if (mod1 != "unchanged") return mod1; + const mod2 = game.checkMod(from, to, "unchanged", "inRangeOf", to); + if (mod2 != "unchanged") return mod2; + const range = from.getAttackRange(); + if (range < 1) return false; + let player = from, + m, + n = 1; + let fxy, txy; + if (game.chess) { + fxy = from.getXY(); + txy = to.getXY(); + n = Math.abs(fxy[0] - txy[0]) + Math.abs(fxy[1] - txy[1]); + } else if (to.isMin(true) || from.isMin(true)) { + /* empty */ + } else { + let length = game.players.length; + let totalPopulation = game.players.length + game.dead.length + 1; + for (let iwhile = 0; iwhile < totalPopulation; iwhile++) { + if (player.nextSeat != to) { + player = player.nextSeat; + if ( + player.isAlive() && + !player.isOut() && + !player.hasSkill("undist") && + !player.isMin(true) + ) + n++; + } else { + break; + } + } + for (let i = 0; i < game.players.length; i++) { + if ( + game.players[i].isOut() || + game.players[i].hasSkill("undist") || + game.players[i].isMin(true) + ) + length--; + } + if (from.isDead()) length++; + if (to.isDead()) length++; + let left = from.hasSkillTag("left_hand"); + let right = from.hasSkillTag("right_hand"); + if (left === right) n = Math.min(n, length - n); + else if (left == true) n = length - n; + } + n = game.checkMod(from, to, n, "globalFrom", from); + n = game.checkMod(from, to, n, "globalTo", to); + m = n; + m = game.checkMod(from, to, m, "attackFrom", from); + m = game.checkMod(from, to, m, "attackTo", to); + const equips1 = from.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }), + equips2 = to.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + for (let i = 0; i < equips1.length; i++) { + const info = get.info(equips1[i]).distance; + if (!info) continue; + if (info.globalFrom) { + m += info.globalFrom; + n += info.globalFrom; + } + } + for (let i = 0; i < equips2.length; i++) { + const info = get.info(equips2[i]).distance; + if (!info) continue; + if (info.globalTo) { + m += info.globalTo; + n += info.globalTo; + } + if (info.attackTo) { + m += info.attackTo; + } + } + return m <= range; + } + /** + * @param { Player } source + */ + inRangeOf(source) { + return source.inRange(this); + } + /** + * Get the player's HP not less than 0. Set “raw” to true to get the player's raw HP instead. + * + * 获取角色的体力值。设置“raw”为true以获取角色的体力。 + * + * @param { boolean } [raw] + */ + getHp(raw) { + return raw ? this.hp : Math.max(0, this.hp); + } + /** + * Set “raw” to true to get the player's raw damaged HP instead. + * + * 设置“raw”为true以获取角色已损失的体力。 + * + * @param { boolean } [raw] + */ + getDamagedHp(raw) { + return this.maxHp - this.getHp(raw); + } + /** + * @param { string } group + */ + changeGroup(group, log, broadcast) { + var next = game.createEvent("changeGroup"); + next.player = this; + next.log = true; + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + if (lib.group.includes(arg)) { + next.group = arg; + } else if (typeof arg === "boolean") { + next.log = arg; + } else if (arg === "nobroadcast") { + next.broadcast = false; + } + } + next.setContent("changeGroup"); + return next; + } + /** + * @param { Player } target + */ + chooseToDuiben(target) { + var next = game.createEvent("chooseToDuiben"); + next.player = this; + next.target = target; + next.setContent("chooseToDuiben"); + return next; + } + /** + * @param { Player } target + */ + chooseToPSS(target) { + var next = game.createEvent("chooseToPSS"); + next.player = this; + next.target = target; + next.setContent("chooseToPSS"); + return next; + } + chooseToEnable() { + var next = game.createEvent("chooseToEnable"); + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } + } + if (next.source == undefined) next.source = this; + next.player = this; + next.setContent("chooseToEnable"); + return next; + } + chooseToDisable() { + var next = game.createEvent("chooseToDisable"); + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.horse = arguments[i]; + } + } + if (next.horse == undefined) next.horse = false; + if (next.source == undefined) next.source = this; + next.player = this; + next.setContent("chooseToDisable"); + return next; + } + /** + * @param { boolean } [notmeisok] + */ + isPhaseUsing(notmeisok) { + if (!notmeisok && _status.currentPhase != this) return false; + // @ts-ignore + return _status.event.name == "phaseUse" || _status.event.getParent("phaseUse").name == "phaseUse"; + } + /** + * @param { Player } target + */ + swapEquip(target) { + var next = game.createEvent("swapEquip"); + next.player = this; + next.target = target; + next.setContent("swapEquip"); + return next; + } + /** + * @param { Player } target + * @param { boolean } [goon] + * @param { boolean} [bool] + */ + canCompare(target, goon, bool) { + if (this == target) return false; + if ((!this.countCards("h") && goon !== true) || (!target.countCards("h") && bool !== true)) + return false; + if (this.hasSkillTag("noCompareSource") || target.hasSkillTag("noCompareTarget")) return false; + return true; + } + $disableJudge() { + this.storage._disableJudge = true; + for (let i = 0; i < this.node.judges.childNodes.length; i++) { + if (this.node.judges.childNodes[i].classList.contains("feichu")) return; + } + game.addVideo("$disableJudge", this); + var card = game.createCard("disable_judge", "", ""); + card.fix(); + card.classList.add("feichu"); + card.style.transform = ""; + card.classList.add("drawinghidden"); + this.node.judges.insertBefore(card, this.node.judges.firstChild); + ui.updatej(this); + } + $enableJudge() { + game.addVideo("$enableJudge", this); + this.storage._disableJudge = false; + for (let i = 0; i < this.node.judges.childNodes.length; i++) { + // @ts-ignore + if (this.node.judges.childNodes[i].name == "disable_judge") { + this.node.judges.removeChild(this.node.judges.childNodes[i]); + break; + } + } + } + disableJudge() { + var next = game.createEvent("disableJudge"); + next.player = this; + next.source = _status.event.player; + next.setContent("disableJudge"); + return next; + } + enableJudge() { + var next = game.createEvent("enableJudge"); + next.player = this; + next.source = _status.event.player; + next.setContent("enableJudge"); + return next; + } + //原有函数 + init(character, character2, skill, update) { + let hidden = false; + if (typeof character == "string" && !lib.character[character]) { + lib.character[character] = get.character(character); + } + if (typeof character2 == "string" && !lib.character[character2]) { + lib.character[character2] = get.character(character2); + } + if (!lib.character[character]) return; + if (get.is.jun(character2)) { + var tmp = character; + character = character2; + character2 = tmp; + } + if (character2 == false) { + skill = false; + character2 = null; + } + var info = lib.character[character]; + if (!info) { + info = ["", "", 1, [], []]; + } + if (!info[4]) { + info[4] = []; + } + var skills = info[3].slice(0); + this.clearSkills(true); + + var hp1 = get.infoHp(info[2]); + var maxHp1 = get.infoMaxHp(info[2]); + var hujia1 = get.infoHujia(info[2]); + + this.name = character; + this.name1 = character; + this.tempname = []; + this.skin = { + name: character, + name2: character2, + }; + this.sex = info[0]; + this.group = info[1]; + this.hp = hp1; + this.maxHp = maxHp1; + this.hujia = hujia1; + this.node.intro.innerHTML = lib.config.intro; + this.node.name.dataset.nature = get.groupnature(this.group); + lib.setIntro(this); + this.node.name.innerHTML = get.slimName(character); + if (this.classList.contains("minskin") && this.node.name.querySelectorAll("br").length >= 4) { + this.node.name.classList.add("long"); + } + if (info[4].includes("hiddenSkill") && !this.noclick) { + if (!this.hiddenSkills) this.hiddenSkills = []; + this.hiddenSkills.addArray(skills); + skills = []; + this.name = "unknown"; + this.sex = "male"; + hidden = true; + skills.add("g_hidden_ai"); + } + if (character2 && lib.character[character2]) { + var info2 = lib.character[character2]; + if (!info2) { + info2 = ["", "", 1, [], []]; + } + if (!info2[4]) { + info2[4] = []; + } + + this.name2 = character2; + var hp2 = get.infoHp(info2[2]); + var maxHp2 = get.infoMaxHp(info2[2]); + var hujia2 = get.infoHujia(info2[2]); + this.hujia += hujia2; + var double_hp; + if (_status.connectMode || get.mode() == "single") { + double_hp = "pingjun"; + } else { + double_hp = get.config("double_hp"); + } + switch (double_hp) { + case "pingjun": { + this.maxHp = Math.floor((maxHp1 + maxHp2) / 2); + this.hp = Math.floor((hp1 + hp2) / 2); + this.singleHp = (maxHp1 + maxHp2) % 2 === 1; + break; + } + case "zuidazhi": { + this.maxHp = Math.max(maxHp1, maxHp2); + this.hp = Math.max(hp1, hp2); + break; + } + case "zuixiaozhi": { + this.maxHp = Math.min(maxHp1, maxHp2); + this.hp = Math.min(hp1, hp2); + break; + } + case "zonghe": { + this.maxHp = maxHp1 + maxHp2; + this.hp = hp1 + hp2; + break; + } + default: { + this.maxHp = maxHp1 + maxHp2 - 3; + this.hp = hp1 + hp2 - 3; + } + } + if (info2[4].includes("hiddenSkill") && !this.noclick) { + if (!this.hiddenSkills) this.hiddenSkills = []; + this.hiddenSkills.addArray(info2[3]); + hidden = true; + skills.add("g_hidden_ai"); + } else skills = skills.concat(info2[3]); + } + if (this.storage.nohp || hidden) { + this.storage.rawHp = this.hp; + this.storage.rawMaxHp = this.maxHp; + this.hp = 1; + this.maxHp = 1; + if (this.storage.nohp) { + this.node.hp.hide(); + } + } + if (skill != false) { + skills = skills.filter((skill) => { + var info = get.info(skill); + if (info && info.zhuSkill && !this.isZhu2()) return false; + return true; + }); + for (var i = 0; i < skills.length; i++) { + this.addSkill(skills[i], null, true); + } + this.checkConflict(); + } + lib.group.add(this.group); + + this.$init(character, character2); + + if (this.inits) { + for (var i = 0; i < this.inits.length; i++) { + this.inits[i](this); + } + } + if (this._inits) { + for (var i = 0; i < this._inits.length; i++) { + this._inits[i](this); + } + } + if (update !== false) this.$update(); + return this; + } + $init(character, character2) { + this.classList.add("fullskin"); + var info = lib.character[character]; + if (!info) { + info = ["", "", 1, [], []]; + } + if (!info[4]) { + info[4] = []; + } + + if (!game.minskin && get.is.newLayout() && !info[4].includes("minskin")) { + this.classList.remove("minskin"); + this.node.avatar.setBackground(character, "character"); + } else { + this.node.avatar.setBackground(character, "character"); + if (info[4].includes("minskin")) { + this.classList.add("minskin"); + } else if (game.minskin) { + this.classList.add("minskin"); + } else { + this.classList.remove("minskin"); + } + } + + this.node.avatar.show(); + this.node.count.show(); + this.node.equips.show(); + + this.node.intro.innerHTML = lib.config.intro; + this.node.name.dataset.nature = get.groupnature(this.group); + lib.setIntro(this); + this.node.name.innerHTML = get.slimName(character); + if (this.classList.contains("minskin") && this.node.name.querySelectorAll("br").length >= 4) { + this.node.name.classList.add("long"); + } + if (info[4].includes("hiddenSkill") && !this.noclick) { + if (!_status.video && get.mode() != "guozhan") this.classList.add("unseen_show"); + this.classList.add(_status.video ? "unseen_v" : "unseen"); + if (!this.node.name_seat && !_status.video) { + this.node.name_seat = ui.create.div( + ".name.name_seat", + get.verticalStr(get.translation(this.name)), + this + ); + this.node.name_seat.dataset.nature = get.groupnature(this.group); + } + } + if (character2 && lib.character[character2]) { + var info2 = lib.character[character2]; + if (!info2) { + info2 = ["", "", 1, [], []]; + } + if (!info2[4]) { + info2[4] = []; + } + this.classList.add("fullskin2"); + this.node.avatar2.setBackground(character2, "character"); + this.node.avatar2.show(); + this.name2 = character2; + + this.node.count.classList.add("p2"); + if (info2[4].includes("hiddenSkill") && !this.noclick) { + if (!_status.video && get.mode() != "guozhan") this.classList.add("unseen2_show"); + this.classList.add(_status.video ? "unseen2_v" : "unseen2"); + } + this.node.name2.innerHTML = get.slimName(character2); + } + if (this.storage.nohp) { + this.node.hp.hide(); + } + + return this; + } + /** + * 换肤换音:想要支持某个武将更换皮肤,必须在lib.character.characterSubstitute中存在该武将的id(以下以name代指武将id,character代指换肤图片名) + * + * 如果换肤换音引用本体的image/character素材作为更换的皮肤且不需要使用本体audio/die以外的地方的配音,则你无需在characterSubstitute中书写关于此皮肤的信息 + * + * 如果lib.character[character]不存在,且想引用其他路径的图片素材或阵亡素材,请以[character,[]]的形式写入lib.character.characterSubstitute[name]中,第二个数组填入形式同lib.character[4]的书写形式 + * + * @param { string | object | function } map + * @param { string } character + */ + changeSkin(map, character) { + if (!map || !character) { + console.warn("error: no sourceMap or character to changeSkin", get.translation(this)); + return; + } + if (typeof map == "string") { + map = { skill: map }; + } + for (const i of ["name", "name1", "name2"]) { + if (i == "name1" && this.name === this.name1) continue; + const list = lib.characterSubstitute[this[i]]; + if (this[i] && list) { + const name = i == "name2" ? "name2" : "name"; + if ( + (() => { + if (typeof map == "function") { + return map(this, name); + } + if ( + typeof map.skill == "string" && + (get.character(this[i], 3) || []).includes(map.skill) + ) + return true; + if (typeof map.characterName == "string" && this[i] == map.characterName) return true; + if ( + typeof map.characterSkinName == "string" && + this.skin[name] == map.characterSkinName + ) + return true; + if (typeof map.source == "string" && name == map.source) return true; + return false; + })() + ) { + if (this.skin[name] != character) { + const origin = this.skin[name]; + game.broadcastAll( + (player, name, character, list, origin) => { + player.tempname.remove(origin); + player.tempname.add(character); + player.skin[name] = character; + const goon = !lib.character[character]; + if (goon) + lib.character[character] = [ + "", + "", + 0, + [], + (list.find((i) => i[0] == character) || [character, []])[1], + ]; + player.smoothAvatar(name == "name2"); + player.node["avatar" + name.slice(4)].setBackground(character, "character"); + player.node["avatar" + name.slice(4)].show(); + if (goon) delete lib.character[character]; + }, + this, + name, + character, + list, + origin + ); + game.addVideo("changeSkin", this, { + from: origin, + to: character, + name: name, + list: list, + avatar2: name == "name2", + }); + } + } + } + } + } + changeSkinByName(character, index) { + const name = index == 2 ? "name2" : "name"; + const list = lib.characterSubstitute[this[name]]; + if (list && lib.characterSubstitute[this[name]]) { + const origin = this.skin[name]; + game.broadcastAll( + (player, name, character, list, origin) => { + player.tempname.remove(origin); + player.tempname.add(character); + player.skin[name] = character; + const goon = !lib.character[character]; + if (goon) + lib.character[character] = [ + "", + "", + 0, + [], + (list.find((i) => i[0] == character) || [character, []])[1], + ]; + player.smoothAvatar(name == "name2"); + player.node["avatar" + name.slice(4)].setBackground(character, "character"); + player.node["avatar" + name.slice(4)].show(); + if (goon) delete lib.character[character]; + }, + this, + name, + character, + list, + origin + ); + game.addVideo("changeSkin", this, { + from: origin, + to: character, + name: name, + list: list, + avatar2: name == "name2", + }); + } + } + initOL(name, character) { + this.node.avatar.setBackground(character, "character"); + this.node.avatar.show(); + this.node.name.innerHTML = get.verticalStr(name); + this.nickname = name; + this.avatar = character; + this.node.nameol.innerHTML = ""; + if (lib.character[character]) this.sex = lib.character[character][0]; + } + uninitOL() { + this.node.avatar.hide(); + this.node.name.innerHTML = ""; + this.node.identity.firstChild.innerHTML = ""; + delete this.nickname; + delete this.avatar; + delete this.sex; + } + initRoom(info, info2) { + var str = ""; + this.serving = false; + if (!info || info == "server") { + this.roomempty = true; + str = "空房间"; + this.roomfull = false; + this.roomgaming = false; + this.version = null; + if (info == "server") { + this.serving = true; + } + } else { + var config = info[2]; + this.key = info[4]; + this.roomempty = false; + str += get.modetrans(config); + str += " 模式 "; + for (var i = str.length; i < 11; i++) str += " "; + this.version = config.version; + if (config.gameStarted) { + str += '游戏中 '; + if (config.observe && config.observeReady && this.version == lib.versionOL) { + this.classList.remove("exclude"); + } else { + this.classList.add("exclude"); + } + } else { + str += '等待中 '; + if (this.version != lib.versionOL) { + this.classList.add("exclude"); + } else { + this.classList.remove("exclude"); + } + } + this.maxHp = parseInt(config.number); + this.hp = Math.min(this.maxHp, info[3]); + if (this.hp < this.maxHp || config.gameStarted) str += "人数:" + this.hp + "/" + this.maxHp; + else str += '人数:' + this.hp + "/" + this.maxHp + ""; + + str += " (" + info[0].slice(0, 12) + " 的房间)"; + if (config.mode != "guozhan" && (config.mode != "doudizhu" || config.doudizhu_mode != "online")) { + str += "【"; + for (var i = 0; i < config.cardPack.length; i++) { + str += get.translation(config.cardPack[i] + "_card_config").slice(0, 2); + if (i < config.cardPack.length - 1) str += "+"; + } + str += "】"; + } + this.config = config; + if (this.hp == this.maxHp && !config.gameStarted) { + this.roomfull = true; + } else { + this.roomfull = false; + } + if (config.gameStarted && (!config.observe || !config.observeReady)) { + this.roomgaming = true; + } else { + this.roomgaming = false; + } + } + this.firstChild.innerHTML = str; + return this; + } + reinit2(newPairs) { + const player = this; + game.broadcast( + (player, newPairs) => { + player.reinit2(newPairs); + }, + this, + newPairs + ); + const rawPairs = [this.name1]; + if (this.name2 && lib.character[this.name2]) rawPairs.push(this.name2); + //单将变单将 & 双将变双将 + if (rawPairs.length == newPairs.length) { + for (let i = 0; i < Math.min(2, rawPairs.length); i++) { + let rawName = rawPairs[i], + newName = newPairs[i]; + if (rawName != newName && lib.character[rawName] && lib.character[newName]) { + player.reinit(rawName, newName, null, true); + } + } + } + //单将变双将 + else if (rawPairs.length == 1 && newPairs.length == 2) { + player.name1 = newPairs[0]; + player.name2 = newPairs[1]; + player.$reinit12(newPairs); + } + //双将变单将 + else if (rawPairs.length == 2 && newPairs.length == 1) { + player.name1 = newPairs[0]; + delete player.name2; + player.$reinit21(newPairs); + } + //修改性别 + if (!player.isUnseen(1)) { + player.name = player.name1; + player.sex = get.character(player.name1)[0]; + } else if (!player.isUnseen(2)) { + player.name = player.name2; + player.sex = get.character(player.name2)[0]; + } + } + $reinit12(newPairs) { + const player = this; + player.node.avatar.setBackground(newPairs[0], "character"); + player.node.name.innerHTML = get.slimName(newPairs[0]); + player.name2 = newPairs[1]; + player.classList.add("fullskin2"); + player.node.avatar2.classList.remove("hidden"); + player.node.avatar2.setBackground(newPairs[1], "character"); + player.node.name2.innerHTML = get.slimName(newPairs[1]); + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; + } + } + $reinit21(newPairs) { + const player = this, + name = newPairs[0]; + player.smoothAvatar(false); + player.node.avatar.setBackground(name, "character"); + player.node.name.innerHTML = get.slimName(name); + player.classList.remove("fullskin2"); + player.node.avatar2.classList.add("hidden"); + player.node.name2.innerHTML = ""; + if (player == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; + } + } + reinit(from, to, maxHp, online) { + var info1 = lib.character[from]; + var info2 = lib.character[to]; + var smooth = true, + replaced = null; + if (maxHp == "nosmooth") { + smooth = false; + maxHp = null; + } + if (this.name2 == from) { + this.name2 = to; + this.skin.name2 = to; + } else if (this.name == from || this.name1 == from) { + if (this.name1 == from) { + this.name1 = to; + this.skin.name = to; + } + if (!this.isUnseen(1)) { + this.name = to; + if (this.skin.name != to) this.skin.name = to; + this.sex = info2[0]; + } + } else { + return this; + } + if (!online) { + for (var i = 0; i < info1[3].length; i++) { + this.removeSkill(info1[3][i]); + } + for (var i = 0; i < info2[3].length; i++) { + var info = get.info(info2[3][i]); + if (info && info.zhuSkill && !this.isZhu2()) continue; + this.addSkill(info2[3][i]); + } + if (Array.isArray(maxHp)) { + this.maxHp = maxHp[1]; + this.hp = maxHp[0]; + } else { + var num; + if (maxHp === false) { + num = 0; + } else { + if (typeof maxHp != "number") { + maxHp = get.infoMaxHp(info2[2]); + } + num = maxHp - get.infoMaxHp(info1[2]); + } + if (typeof this.singleHp == "boolean") { + if (num % 2 != 0) { + if (this.singleHp) { + this.maxHp += (num + 1) / 2; + this.singleHp = false; + } else { + this.maxHp += (num - 1) / 2; + this.singleHp = true; + if (!game.online) { + this.doubleDraw(); + } + } + } else { + this.maxHp += num / 2; + } + } else { + this.maxHp += num; + } + } + game.broadcast( + function (player, from, to, skills) { + player.reinit(from, to, null, true); + player.applySkills(skills); + }, + this, + from, + to, + get.skillState(this) + ); + } + game.addVideo("reinit3", this, { + from: from, + to: to, + hp: this.maxHp, + avatar2: this.name2 == to, + }); + this.$reinit(from, to, maxHp, online); + this.update(); + } + $reinit(from, to, maxHp, online) { + var smooth = true; + if (maxHp == "nosmooth") { + smooth = false; + maxHp = null; + } + if (this.name2 == to) { + if (smooth) this.smoothAvatar(true); + this.node.avatar2.setBackground(to, "character"); + this.node.name2.innerHTML = get.slimName(to); + } else if (this.name == to || this.name1 == to) { + if (smooth) this.smoothAvatar(false); + this.node.avatar.setBackground(to, "character"); + this.node.name.innerHTML = get.slimName(to); + + if (this == game.me && ui.fakeme) { + ui.fakeme.style.backgroundImage = this.node.avatar.style.backgroundImage; + } + } + } + uninit() { + delete this.name; + delete this.name1; + delete this.tempname; + delete this.skin; + delete this.sex; + delete this.group; + delete this.hp; + delete this.maxHp; + delete this.hujia; + + if (this.name2) { + delete this.singleHp; + delete this.name2; + } + + this.skipList = []; + this.clearSkills(true); + this.initedSkills = []; + this.additionalSkills = {}; + this.disabledSkills = {}; + this.hiddenSkills = []; + this.awakenedSkills = []; + this.forbiddenSkills = {}; + this.phaseNumber = 0; + this.stat = [{ card: {}, skill: {} }]; + this.tempSkills = {}; + this.storage = {}; + this.marks = {}; + this.expandedSlots = {}; + this.disabledSlots = {}; + this.ai = { friend: [], enemy: [], neutral: [] }; + + this.$uninit(); + + return this; + } + $uninit() { + this.$syncExpand(); + this.$syncDisable(); + game.broadcastAll(function (player) { + delete player.storage._disableJudge; + for (var i = 0; i < player.node.judges.childNodes.length; i++) { + if (player.node.judges.childNodes[i].name == "disable_judge") { + player.node.judges.removeChild(player.node.judges.childNodes[i]); + break; + } + } + }, this); + + this.node.avatar.hide(); + this.node.count.hide(); + if (this.node.wuxing) { + this.node.wuxing.hide(); + } + if (this.node.name_seat) { + this.node.name_seat.remove(); + delete this.node.name_seat; + } + this.node.hp.show(); + this.classList.remove("unseen"); + this.classList.remove("unseen2"); + this.classList.remove("unseen_show"); + this.classList.remove("unseen2_show"); + + this.node.identity.style.backgroundColor = ""; + this.node.intro.innerHTML = ""; + this.node.name.innerHTML = ""; + this.node.hp.innerHTML = ""; + this.node.count.innerHTML = "0"; + + this.node.avatar2.hide(); + this.node.name2.innerHTML = ""; + this.classList.remove("fullskin2"); + this.node.count.classList.remove("p2"); + + for (var mark in this.marks) { + this.marks[mark].remove(); + } + ui.updatem(this); + } + getLeft() { + return this.offsetLeft; + } + getTop() { + return this.offsetTop; + } + smoothAvatar(vice, video) { + var div = ui.create.div(".fullsize"); + if (vice) { + div.style.background = getComputedStyle(this.node.avatar2).background; + this.node.avatar2.appendChild(div); + } else { + div.style.background = getComputedStyle(this.node.avatar).background; + this.node.avatar.appendChild(div); + } + ui.refresh(div); + div.style.transition = "all 1s"; + setTimeout(function () { + div.classList.add("removing"); + setTimeout(function () { + div.remove(); + }, 2000); + }, 100); + if (video != false) { + game.addVideo("smoothAvatar", this, vice); + } + } + changeSeat(position, video) { + var player = this; + if (video !== false) game.addVideo("changeSeat", player, position); + var rect1 = player.getBoundingClientRect(); + player.style.transition = "all 0s"; + ui.refresh(player); + player.dataset.position = position; + var rect2 = player.getBoundingClientRect(); + var dx = rect1.left - rect2.left; + var dy = rect1.top - rect2.top; + if ( + (game.chess || (player.dataset.position != 0 && position != 0)) && + player.classList.contains("linked") + ) { + player.style.transform = "rotate(-90deg) translate(" + -dy + "px," + dx + "px)"; + } else { + player.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + setTimeout(function () { + player.style.transition = ""; + ui.refresh(player); + player.style.transform = ""; + }, 100); + } + send() { + if (!this.ws || this.ws.closed) return this; + this.ws.send.apply(this.ws, arguments); + return this; + } + getId() { + if (_status.video || _status.connectMode) return this; + if (this.playerid) { + delete game.playerMap[this.playerid]; + } + this.playerid = get.id(); + game.playerMap[this.playerid] = this; + return this; + } + throwEmotion(target, emotion, rotate) { + game.broadcastAll( + function (player, target, emotion, rotate) { + player.$throwEmotion(target, emotion, rotate); + }, + this, + target, + emotion, + rotate + ); + } + emotion(pack, id) { + var str = ''; + this.say(str); + game.broadcast( + function (id, str) { + if (lib.playerOL[id]) { + lib.playerOL[id].say(str); + } else if (game.connectPlayers) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == id) { + game.connectPlayers[i].say(str); + return; + } + } + } + }, + this.playerid, + str + ); + } + chat(str) { + if (get.is.banWords(str)) return; + this.say(str); + game.broadcast( + function (id, str) { + if (lib.playerOL[id]) { + lib.playerOL[id].say(str); + } else if (game.connectPlayers) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == id) { + game.connectPlayers[i].say(str); + return; + } + } + } + }, + this.playerid, + str + ); + } + say(str) { + str = str.replace(/##assetURL##/g, lib.assetURL); + var dialog = ui.create.dialog("hidden"); + dialog.classList.add("static"); + dialog.add('
                                    ' + str + "
                                    "); + dialog.classList.add("popped"); + ui.window.appendChild(dialog); + var width = dialog.content.firstChild.firstChild.offsetWidth; + if (width < 190) { + dialog._mod_height = -16; + } else { + dialog.content.firstChild.style.textAlign = "left"; + } + dialog.style.width = width + 16 + "px"; + var refnode; + if (this.node && this.node.avatar && this.parentNode == ui.arena) { + refnode = this.node.avatar; + } + if (refnode) { + lib.placePoppedDialog(dialog, { + clientX: + (ui.arena.offsetLeft + this.getLeft() + refnode.offsetLeft + refnode.offsetWidth / 2) * + game.documentZoom, + clientY: + (ui.arena.offsetTop + this.getTop() + refnode.offsetTop + refnode.offsetHeight / 4) * + game.documentZoom, + }); + } else { + lib.placePoppedDialog(dialog, { + clientX: (this.getLeft() + this.offsetWidth / 2) * game.documentZoom, + clientY: (this.getTop() + this.offsetHeight / 4) * game.documentZoom, + }); + } + if (dialog._mod_height) { + dialog.content.firstChild.style.padding = 0; + } + setTimeout( + function () { + dialog.delete(); + }, + lib.quickVoice.includes(str) ? 3800 : 2000 + ); + var name = get.translation(this.name); + var info = [name ? name + "[" + this.nickname + "]" : this.nickname, str]; + lib.chatHistory.push(info); + if (_status.addChatEntry) { + if (_status.addChatEntry._origin.parentNode) { + _status.addChatEntry(info, false); + } else { + delete _status.addChatEntry; + } + } + if (lib.config.background_speak && lib.quickVoice.includes(str)) { + game.playAudio("voice", this.sex == "female" ? "female" : "male", lib.quickVoice.indexOf(str)); + } + } + showGiveup() { + this._giveUp = true; + if (this == game.me) { + ui.create.giveup(); + } else if (this.isOnline2()) { + this.send(ui.create.giveup); + } + } + applySkills(skills) { + for (var i in skills) { + if (i == "global") { + lib.skill.global = skills[i]; + } + //else if(i=='skillinfo'){ + // for(var j in skills[i]){ + // if(!lib.skill[j]){ + // lib.skill[j]={}; + // } + // lib.skill[j].chooseButton=skills[i][j]; + // } + //} + else if (i == "stat") { + this.stat = [skills.stat]; + } else if (lib.playerOL[i]) { + for (var j in skills[i]) { + lib.playerOL[i][j] = skills[i][j]; + } + } + } + } + getState() { + var state = { + hp: this.hp, + maxHp: this.maxHp, + nickname: this.nickname, + sex: this.sex, + group: this.group, + name: this.name, + name1: this.name1, + name2: this.name2, + handcards: this.getCards("hs"), + gaintag: [], + equips: this.getCards("e"), + judges: this.getCards("j"), + specials: this.getCards("s"), + expansions: this.getCards("x"), + expansion_gaintag: [], + disableJudge: this.isDisabledJudge(), + disabledSlots: this.disabledSlots, + expandedSlots: this.expandedSlots, + views: [], + position: parseInt(this.dataset.position), + hujia: this.hujia, + side: this.side, + identityShown: this.identityShown, + identityNode: [this.node.identity.innerHTML, this.node.identity.dataset.color], + identity: this.identity, + dead: this.isDead(), + linked: this.isLinked(), + turnedover: this.isTurnedOver(), + out: this.isOut(), + phaseNumber: this.phaseNumber, + unseen: this.isUnseen(0), + unseen2: this.isUnseen(1), + seatNum: this.seatNum, + }; + for (var i = 0; i < state.judges.length; i++) { + state.views[i] = state.judges[i].viewAs; + } + for (var i = 0; i < state.handcards.length; i++) { + state.gaintag[i] = state.handcards[i].gaintag; + } + for (var i = 0; i < state.expansions.length; i++) { + state.expansion_gaintag[i] = state.expansions[i].gaintag; + } + if (this.getModeState) { + state.mode = this.getModeState(); + } + return state; + } + setNickname(str) { + this.node.nameol.innerHTML = (str || this.nickname || "").slice(0, 12); + return this; + } + setAvatar(name, name2, video, fakeme) { + var node; + if (this.name2 == name) { + node = this.node.avatar2; + this.smoothAvatar(true, video); + } else if (this.name == name) { + node = this.node.avatar; + this.smoothAvatar(false, video); + } + if (node) { + node.setBackground(name2, "character"); + if (this == game.me && ui.fakeme && fakeme !== false) { + ui.fakeme.style.backgroundImage = node.style.backgroundImage; + } + if (video != false) { + game.addVideo("setAvatar", this, [name, name2]); + } + } + game.broadcast( + function (player, name, name2) { + player.setAvatar(name, name2, false); + }, + this, + name, + name2 + ); + } + setAvatarQueue(name, list) { + var node; + var player = this; + if (player.name2 == name) { + node = player.node.avatar2; + } else { + node = player.node.avatar; + } + if (node._avatarqueue) { + for (var i = 0; i < list.length; i++) { + node._avatarqueue.push(list[i]); + } + } else { + var func = function () { + if (node._avatarqueue.length) { + player.setAvatar(name, node._avatarqueue.shift(), false, false); + } else { + clearInterval(node._avatarqueueinterval); + delete node._avatarqueue; + delete node._avatarqueueinterval; + player.setAvatar(name, name, false, false); + } + }; + node._avatarqueue = list.slice(0); + node._avatarqueueinterval = setInterval(func, 1000); + func(); + } + game.addVideo("setAvatarQueue", this, [name, list]); + } + flashAvatar(skill, name) { + if (lib.skill[name] && !lib.character[name]) { + var stop = false; + var list = lib.config.all.characters.slice(0); + for (var i in lib.characterPack) { + list.add(i); + } + for (var i = 0; i < list.length; i++) { + for (var j in lib.characterPack[list[i]]) { + if (lib.characterPack[list[i]][j][3].includes(name)) { + name = j; + stop = true; + break; + } + } + if (stop) { + break; + } + } + } + if (lib.character[this.name2] && lib.character[this.name2][3].includes(skill)) { + this.setAvatarQueue(this.name2, [name]); + } else { + this.setAvatarQueue(this.name, [name]); + } + } + update() { + if (_status.video && arguments.length == 0) return; + if (this.hp >= this.maxHp) this.hp = this.maxHp; + game.broadcast( + function (player, hp, maxHp, hujia) { + player.hp = hp; + player.maxHp = maxHp; + player.hujia = hujia; + player.$update(); + }, + this, + this.hp, + this.maxHp, + this.hujia + ); + this.$update(...arguments); + } + $update() { + if (this.hp >= this.maxHp) this.hp = this.maxHp; + var hp = this.node.hp; + hp.style.transition = "none"; + if (!_status.video) { + if (this.hujia) { + this.markSkill("ghujia"); + } else { + this.unmarkSkill("ghujia"); + } + } + if (!this.storage.nohp) { + const hidden = this.classList.contains("unseen_show") || this.classList.contains("unseen2_show"); + const maxHp = hidden ? 1 : this.maxHp; + if (maxHp == Infinity) { + hp.innerHTML = this.hp == Infinity ? "∞" : this.hp + "
                                    /
                                    " + "∞" + "
                                    "; + } else if (game.layout == "default" && maxHp > 14) { + hp.innerHTML = this.hp + "/" + maxHp; + hp.classList.add("text"); + } else if ( + get.is.newLayout() && + (maxHp > 9 || + (maxHp > 5 && this.classList.contains("minskin")) || + ((game.layout == "mobile" || game.layout == "long") && + this.dataset.position == 0 && + maxHp > 7)) + ) { + hp.innerHTML = this.hp + "
                                    /
                                    " + maxHp + "
                                    "; + if (this.hp == 0) { + hp.lastChild.classList.add("lost"); + } + hp.classList.add("textstyle"); + // hp.classList.remove('long'); + } else { + hp.innerHTML = ""; + hp.classList.remove("text"); + hp.classList.remove("textstyle"); + while (maxHp > hp.childNodes.length) { + ui.create.div(hp); + } + while (Math.max(0, maxHp) < hp.childNodes.length) { + hp.removeChild(hp.lastChild); + } + for (var i = 0; i < maxHp; i++) { + var index = i; + if (get.is.newLayout()) { + index = maxHp - i - 1; + } + if (i < this.hp) { + hp.childNodes[index].classList.remove("lost"); + } else { + hp.childNodes[index].classList.add("lost"); + } + } + // if(maxHp==9){ + // hp.classList.add('long'); + // } + // else{ + // hp.classList.remove('long'); + // } + } + if (hidden) { + hp.dataset.condition = "hidden"; + } else if (hp.classList.contains("room")) { + hp.dataset.condition = "high"; + } else if (this.hp == 0) { + hp.dataset.condition = ""; + } else if (this.hp > Math.round(maxHp / 2) || this.hp === maxHp) { + hp.dataset.condition = "high"; + } else if (this.hp > Math.floor(maxHp / 3)) { + hp.dataset.condition = "mid"; + } else { + hp.dataset.condition = "low"; + } + + setTimeout(function () { + hp.style.transition = ""; + }); + } + var numh = this.countCards("h"); + if (_status.video) { + numh = arguments[0]; + } + if (numh >= 10) { + this.node.count.dataset.condition = "low"; + this.node.count.innerHTML = Array.from(numh.toString()).join("
                                    "); + } else { + if (numh > 5) { + this.node.count.dataset.condition = "higher"; + } else if (numh > 2) { + this.node.count.dataset.condition = "high"; + } else if (numh > 0) { + this.node.count.dataset.condition = "mid"; + } else { + this.node.count.dataset.condition = "none"; + } + this.node.count.innerHTML = numh; + } + if (this.updates) { + for (var i = 0; i < this.updates.length; i++) { + this.updates[i](this); + } + } + if (!_status.video) { + game.addVideo("update", this, [this.countCards("h"), this.hp, this.maxHp, this.hujia]); + } + this.updateMarks(); + return this; + } + clearMark(i, log) { + let num = this.countMark(i); + if (num > 0) this.removeMark(i, num, log); + } + removeMark(i, num, log) { + if (typeof num != "number" || !num) num = 1; + if (typeof this.storage[i] != "number" || !this.storage[i]) return; + if (num > this.storage[i]) num = this.storage[i]; + this.storage[i] -= num; + if (log !== false) { + var str = false; + var info = get.info(i); + if (info && info.intro && (info.intro.name || info.intro.name2)) + str = info.intro.name2 || info.intro.name; + else str = lib.translate[i]; + if (str) game.log(this, "移去了", get.cnNumber(num), "个", "#g【" + str + "】"); + } + this.syncStorage(i); + this[this.storage[i] || (lib.skill[i] && lib.skill[i].mark) ? "markSkill" : "unmarkSkill"](i); + } + addMark(i, num, log) { + if (typeof num != "number" || !num) num = 1; + if (typeof this.storage[i] != "number") this.storage[i] = 0; + this.storage[i] += num; + if (log !== false) { + var str = false; + var info = get.info(i); + if (info && info.intro && (info.intro.name || info.intro.name2)) + str = info.intro.name2 || info.intro.name; + else str = lib.translate[i]; + if (str) game.log(this, "获得了", get.cnNumber(num), "个", "#g【" + str + "】"); + } + this.syncStorage(i); + this.markSkill(i); + } + setMark(name, num, log) { + const count = this.countMark(name); + if (count > num) this.removeMark(name, count - num, log); + else if (count < num) this.addMark(name, num - count, log); + } + /** + * @param {*} i + * @returns { number } + */ + countMark(i) { + if (this.storage[i] == undefined) return 0; + if (typeof this.storage[i] == "number") return this.storage[i]; + if (Array.isArray(this.storage[i])) return this.storage[i].length; + return 0; + } + hasMark(i) { + return this.countMark(i) > 0; + } + updateMark(i, storage) { + if (!this.marks[i]) { + if (lib.skill[i] && lib.skill[i].intro && (this.storage[i] || lib.skill[i].intro.markcount)) { + this.markSkill(i); + if (!this.marks[i]) return this; + } else { + return this; + } + } + if (storage && this.storage[i]) { + this.syncStorage(i); + } + if ( + i == "ghujia" || + ((!this.marks[i].querySelector(".image") || this.storage[i + "_markcount"]) && + lib.skill[i] && + lib.skill[i].intro && + !lib.skill[i].intro.nocount && + (this.storage[i] || this.storage[i + "_markcount"] || lib.skill[i].intro.markcount)) + ) { + this.marks[i].classList.add("overflowmark"); + var num = 0; + if (typeof lib.skill[i].intro.markcount == "function") { + num = lib.skill[i].intro.markcount(this.storage[i], this); + } else if (lib.skill[i].intro.markcount == "expansion") { + num = this.countCards("x", (card) => card.hasGaintag(i)); + } else if (typeof this.storage[i + "_markcount"] == "number") { + num = this.storage[i + "_markcount"]; + } else if (i == "ghujia") { + num = this.hujia; + } else if (typeof this.storage[i] == "number") { + num = this.storage[i]; + } else if (Array.isArray(this.storage[i])) { + num = this.storage[i].length; + } + if (num) { + if (num == Infinity) num = "∞"; + if (!this.marks[i].markcount) { + this.marks[i].markcount = ui.create.div(".markcount.menubutton", this.marks[i]); + } + this.marks[i].markcount.innerHTML = num; + } else if (this.marks[i].markcount) { + this.marks[i].markcount.delete(); + delete this.marks[i].markcount; + } + } else { + if (this.marks[i].markcount) { + this.marks[i].markcount.delete(); + delete this.marks[i].markcount; + } + if (lib.skill[i].mark == "auto") { + this.unmarkSkill(i); + } + } + return this; + } + updateMarks(connect) { + if (typeof connect == "string" && _status.connectMode && !game.online) { + game.broadcast( + function (player, storage, skill) { + player.storage[skill] = storage; + player.updateMarks(); + }, + this, + this.storage[connect], + connect + ); + } + for (var i in this.marks) { + this.updateMark(i); + } + } + num(arg1, arg2, arg3) { + if (get.itemtype(arg1) == "position") { + return this.get(arg1, arg2, arg3).length; + } else if (arg1 == "s") { + if (typeof arg2 == "boolean") { + return game.expandSkills(this.getSkills(arg2).concat(lib.skill.global)).includes(arg3); + } else { + return game.expandSkills(this.getSkills().concat(lib.skill.global)).includes(arg2); + } + } + } + line(target, config) { + if (get.itemtype(target) == "players") { + for (var i = 0; i < target.length; i++) { + this.line(target[i], config); + } + } else if (get.itemtype(target) == "player") { + if (target == this) return; + game.broadcast( + function (player, target, config) { + player.line(target, config); + }, + this, + target, + config + ); + game.addVideo("line", this, [target.dataset.position, config]); + game.linexy( + [ + this.getLeft() + this.offsetWidth / 2, + this.getTop() + this.offsetHeight / 2, + target.getLeft() + target.offsetWidth / 2, + target.getTop() + target.offsetHeight / 2, + ], + config, + true + ); + } + } + line2(targets, config) { + this.line(targets[0], config); + targets = targets.slice(0); + for (var i = 1; i < targets.length; i++) { + (function (j) { + setTimeout(function () { + targets[j - 1].line(targets[j], config); + }, lib.config.duration * i); + })(i); + } + } + getNext() { + if (this.hasSkill("undist")) return null; + var target = this; + for (var i = 0; i < game.players.length - 1; i++) { + target = target.next; + if (!target.hasSkill("undist")) { + return target; + } + } + return null; + } + getPrevious() { + if (this.hasSkill("undist")) return null; + var target = this; + for (var i = 0; i < game.players.length - 1; i++) { + target = target.previous; + if (!target.hasSkill("undist")) { + return target; + } + } + return null; + } + countUsed(card, type) { + if (type === true) { + var num = 0; + var history = this.getHistory("useCard"); + for (var i = 0; i < history.length; i++) { + if (!card) num++; + else if (typeof card == "string" && history[i].card && card == history[i].card.name) num++; + else if (typeof card == "object" && history[i].card && card.name == history[i].card.name) + num++; + } + return num; + } + var num; + var stat = this.getStat("card"); + if (!card) { + num = 0; + for (var i in stat) { + if (typeof stat[i] == "number") num += stat[i]; + } + return num; + } + if (typeof card == "object") { + card = card.name; + } + num = stat[card]; + if (typeof num != "number") return 0; + return num; + } + getCacheKey() { + return `[p:${this.playerid}]`; + } + countSkill(skill) { + var num = this.getStat("skill")[skill]; + if (num == undefined) return 0; + return num; + } + getStockSkills(unowned, unique, hidden) { + var list = []; + if (lib.character[this.name] && (hidden || !this.isUnseen(0))) { + list.addArray(lib.character[this.name][3]); + } + if (lib.character[this.name1] && (hidden || !this.isUnseen(0))) { + list.addArray(lib.character[this.name1][3]); + } + if (lib.character[this.name2] && (hidden || !this.isUnseen(1))) { + list.addArray(lib.character[this.name2][3]); + } + if (!unowned) { + for (var i = 0; i < list.length; i++) { + if (!this.hasSkill(list[i])) { + list.splice(i--, 1); + } + } + } + if (!unique) { + for (var i = 0; i < list.length; i++) { + var info = lib.skill[list[i]]; + if (!info || info.unique || info.temp || info.sub || info.charlotte) { + list.splice(i--, 1); + } + } + } + return list; + } + /** + * @param { string } [arg1='h'] + * @param { string | Record | ((card: Card) => boolean) } [arg2] + * @returns { Iterable } + */ + *iterableGetCards(arg1, arg2) { + if (typeof arg1 != "string") { + arg1 = "h"; + } + const getCardName = (card) => { + if (card.parentNode == this.node.judges) { + if (card.viewAs) return card.viewAs; + } + return get.name(card); + }; + let filter; + if (arg2) { + if (typeof arg2 == "string") { + filter = (card) => getCardName(card) == arg2; + } else if (Array.isArray(arg2)) { + filter = (card) => arg2.includes(getCardName(card)); + } else if (typeof arg2 == "object") { + filter = (card) => { + for (let j in arg2) { + var value; + if (j == "type" || j == "subtype" || j == "color" || j == "suit" || j == "number") { + value = get[j](card); + } else if (j == "name") { + value = getCardName(card); + } else { + value = card[j]; + } + if ( + (typeof arg2[j] == "string" && value != arg2[j]) || + (Array.isArray(arg2[j]) && !arg2[j].includes(value)) + ) { + return false; + } + } + return true; + }; + } else if (typeof arg2 == "function") { + filter = arg2; + } + } else { + filter = (card) => true; + } + for (let i = 0; i < arg1.length; i++) { + if (arg1[i] == "h") { + for (let card of get.iterableChildNodes(this.node.handcards1, this.node.handcards2)) { + if ( + !card.classList.contains("removing") && + !card.classList.contains("glows") && + filter(card) + ) { + yield card; + } + } + } else if (arg1[i] == "s") { + for (let card of get.iterableChildNodes(this.node.handcards1, this.node.handcards2)) { + if ( + !card.classList.contains("removing") && + card.classList.contains("glows") && + filter(card) + ) { + yield card; + } + } + } else if (arg1[i] == "e") { + for (let card of get.iterableChildNodes(this.node.equips)) { + if ( + !card.classList.contains("removing") && + !card.classList.contains("feichu") && + !card.classList.contains("emptyequip") && + filter(card) + ) { + yield card; + } + } + } else if (arg1[i] == "j") { + for (let card of get.iterableChildNodes(this.node.judges)) { + if ( + !card.classList.contains("removing") && + !card.classList.contains("feichu") && + filter(card) + ) { + yield card; + } + } + } else if (arg1[i] == "x") { + for (let card of get.iterableChildNodes(this.node.expansions)) { + if (!card.classList.contains("removing") && filter(card)) { + yield card; + } + } + } + } + } + /** + * @param { string } [arg1='h'] + * @param { string | Record | ((card: Card) => boolean) } [arg2] + * @returns { Card[] } + */ + getCards(arg1, arg2) { + return Array.from(this.iterableGetCards(arg1, arg2)); + } + *iterableGetDiscardableCards(player, arg1, arg2) { + for (let card of this.iterableGetCards(arg1, arg2)) { + if (lib.filter.canBeDiscarded(card, player, this)) { + yield card; + } + } + } + getDiscardableCards(player, arg1, arg2) { + return Array.from(this.iterableGetDiscardableCards(player, arg1, arg2)); + } + *iterableGetGainableCards(player, arg1, arg2) { + for (let card of this.iterableGetCards(arg1, arg2)) { + if (lib.filter.canBeGained(card, player, this)) { + yield card; + } + } + } + getGainableCards(player, arg1, arg2) { + return Array.from(this.iterableGetGainableCards(player, arg1, arg2)); + } + getGainableSkills(func) { + var list = []; + var names = [this.name, this.name1, this.name2]; + for (var i = 0; i < names.length; i++) { + list.addArray(get.gainableSkillsName(names[i], func)); + } + return list; + } + countCards(arg1, arg2) { + let count = 0; + for (let item of this.iterableGetCards(arg1, arg2)) { + count++; + } + return count; + } + getCardIndex(arg1, name, card, max) { + let count = 0; + for (let item of this.iterableGetCards(arg1)) { + if (get.name(item) == name) { + if (card == item) { + return count; + } + count++; + if (count >= max) return count; + } + } + return -1; + } + countDiscardableCards(player, arg1, arg2) { + return this.getDiscardableCards(player, arg1, arg2).length; + } + countGainableCards(player, arg1, arg2) { + return this.getGainableCards(player, arg1, arg2).length; + } + getOriginalSkills() { + var skills = []; + if (lib.character[this.name] && !this.isUnseen(0)) { + skills.addArray(lib.character[this.name][3]); + } + if (this.name2 && lib.character[this.name2] && !this.isUnseen(1)) { + skills.addArray(lib.character[this.name2][3]); + } + return skills; + } + getModableSkills() { + var skills = this.getSkills().concat(lib.skill.global); + game.expandSkills(skills); + skills = skills.filter(function (skill) { + var info = get.info(skill); + return info && info.mod; + }); + skills.sort((a, b) => get.priority(a) - get.priority(b)); + return skills; + } + getSkills(arg2, arg3, arg4) { + var skills = this.skills.slice(0); + var es = []; + var i, j; + if (arg3 !== false) { + for (i = 0; i < this.node.equips.childElementCount; i++) { + if (!this.node.equips.childNodes[i].classList.contains("removing")) { + var equipskills = get.info(this.node.equips.childNodes[i], false).skills; + if (equipskills) { + es.addArray(equipskills); + } + } + } + if (arg2 == "e") { + return es; + } + } + for (var i in this.additionalSkills) { + if (Array.isArray(this.additionalSkills[i]) && (arg2 || i.indexOf("hidden:") !== 0)) { + for (j = 0; j < this.additionalSkills[i].length; j++) { + if (this.additionalSkills[i][j]) { + skills.add(this.additionalSkills[i][j]); + } + } + } else if (this.additionalSkills[i] && typeof this.additionalSkills[i] == "string") { + skills.add(this.additionalSkills[i]); + } + } + for (var i in this.tempSkills) { + skills.add(i); + } + if (arg2) skills.addArray(this.hiddenSkills); + if (arg2 === false || arg2 == "invisible") skills.addArray(this.invisibleSkills); + if (arg3 !== false) skills.addArray(es); + for (var i in this.forbiddenSkills) { + skills.remove(i); + } + if (arg4 !== false) { + skills = game.filterSkills(skills, this, es); + } + return skills; + } + get(arg1, arg2, arg3, arg4) { + var i, j; + if (arg1 == "s") { + var skills = this.skills.slice(0); + var es = []; + if (arg3 !== false) { + for (i = 0; i < this.node.equips.childElementCount; i++) { + if ( + !this.node.equips.childNodes[i].classList.contains("removing") && + !this.node.equips.childNodes[i].classList.contains("feichu") && + !this.node.equips.childNodes[i].classList.contains("emptyequip") + ) { + var equipskills = get.info(this.node.equips.childNodes[i]).skills; + if (equipskills) { + es.addArray(equipskills); + } + } + } + if (arg2 == "e") { + return es; + } + } + for (var i in this.additionalSkills) { + if (Array.isArray(this.additionalSkills[i])) { + for (j = 0; j < this.additionalSkills[i].length; j++) { + if (this.additionalSkills[i][j]) { + skills.add(this.additionalSkills[i][j]); + } + } + } else if (this.additionalSkills[i] && typeof this.additionalSkills[i] == "string") { + skills.add(this.additionalSkills[i]); + } + } + for (var i in this.tempSkills) { + skills.add(i); + } + if (arg2) skills.addArray(this.hiddenSkills); + if (arg3 !== false) skills.addArray(es); + for (var i in this.forbiddenSkills) { + skills.remove(i); + } + if (arg4 !== false) { + skills = game.filterSkills(skills, this, es); + } + return skills; + } else if (get.is.pos(arg1)) { + var cards = [], + cards1 = []; + for (i = 0; i < arg1.length; i++) { + if (arg1[i] == "h") { + for (j = 0; j < this.node.handcards1.childElementCount; j++) { + if ( + !this.node.handcards1.childNodes[j].classList.contains("removing") && + !this.node.handcards1.childNodes[j].classList.contains("feichu") && + !this.node.handcards1.childNodes[j].classList.contains("emptyequip") && + !this.node.handcards1.childNodes[j].classList.contains("glows") + ) { + cards.push(this.node.handcards1.childNodes[j]); + } + } + for (j = 0; j < this.node.handcards2.childElementCount; j++) { + if ( + !this.node.handcards2.childNodes[j].classList.contains("removing") && + !this.node.handcards2.childNodes[j].classList.contains("feichu") && + !this.node.handcards2.childNodes[j].classList.contains("emptyequip") && + !this.node.handcards2.childNodes[j].classList.contains("glows") + ) { + cards.push(this.node.handcards2.childNodes[j]); + } + } + } else if (arg1[i] == "e") { + for (j = 0; j < this.node.equips.childElementCount; j++) { + if ( + !this.node.equips.childNodes[j].classList.contains("removing") && + !this.node.equips.childNodes[j].classList.contains("feichu") && + !this.node.equips.childNodes[j].classList.contains("emptyequip") + ) { + cards.push(this.node.equips.childNodes[j]); + } + } + if (arguments.length == 2 && typeof arg2 == "string" && /1|2|3|4|5/.test(arg2)) { + for (j = 0; j < cards.length; j++) { + if (get.subtype(cards[j]) == "equip" + arg2) return cards[j]; + } + return; + } + } else if (arg1[i] == "j") { + for (j = 0; j < this.node.judges.childElementCount; j++) { + if ( + !this.node.judges.childNodes[j].classList.contains("removing") && + !this.node.judges.childNodes[j].classList.contains("feichu") && + !this.node.judges.childNodes[j].classList.contains("emptyequip") + ) { + cards.push(this.node.judges.childNodes[j]); + if (this.node.judges.childNodes[j].viewAs && arguments.length > 1) { + this.node.judges.childNodes[j].tempJudge = + this.node.judges.childNodes[j].name; + this.node.judges.childNodes[j].name = this.node.judges.childNodes[j].viewAs; + cards1.push(this.node.judges.childNodes[j]); + } + } + } + } + } + if (arguments.length == 1) { + return cards; + } + if (arg2 != undefined) { + if (typeof arg3 == "function") { + var cards2 = cards.slice(0); + cards.sort(function (a, b) { + return arg3(b, cards2) - arg3(a, cards2); + }); + } + if (typeof arg2 == "string") { + for (i = 0; i < cards.length; i++) { + if (cards[i].name != arg2) { + cards.splice(i, 1); + i--; + } + } + } else if (typeof arg2 == "object") { + for (i = 0; i < cards.length; i++) { + for (j in arg2) { + if (j == "type") { + if (typeof arg2[j] == "object") { + if (arg2[j].includes(get.type(cards[i])) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (get.type(cards[i]) != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } else if (j == "subtype") { + if (typeof arg2[j] == "object") { + if (arg2[j].includes(get.subtype(cards[i])) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (get.subtype(cards[i]) != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } else if (j == "color") { + if (typeof arg2[j] == "object") { + if (arg2[j].includes(get.color(cards[i])) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (get.color(cards[i]) != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } else if (j == "suit") { + if (typeof arg2[j] == "object") { + if (arg2[j].includes(get.suit(cards[i])) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (get.suit(cards[i]) != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } else if (j == "number") { + if (typeof arg2[j] == "object") { + if (arg2[j].includes(get.number(cards[i])) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (get.number(cards[i]) != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } else if (typeof arg2[j] == "object") { + if (arg2[j].includes(cards[i][j]) == false) { + cards.splice(i, 1); + i--; + break; + } + } else if (typeof arg2[j] == "string") { + if (cards[i][j] != arg2[j]) { + cards.splice(i, 1); + i--; + break; + } + } + } + } + } else if (typeof arg2 == "number" && arg2 > 0) { + cards.splice(arg2); + } else if (typeof arg2 == "function") { + for (i = 0; i < cards.length; i++) { + if (!arg2(cards[i])) { + cards.splice(i, 1); + i--; + } + } + } + } + for (i = 0; i < cards1.length; i++) { + if (cards1[i].tempJudge) { + cards1[i].name = cards1[i].tempJudge; + delete cards1[i].tempJudge; + } + } + if (arg2 === 0) return cards[0]; + if (typeof arg3 == "number") { + if (arg3 == 0) return cards[0]; + cards.splice(arg3); + } + if (typeof arg4 == "number") { + if (arg4 == 0) return cards[0]; + cards.splice(arg4); + } + return cards; + } + } + syncStorage(skill) { + switch (get.itemtype(this.storage[skill])) { + case "cards": + game.addVideo("storage", this, [skill, get.cardsInfo(this.storage[skill]), "cards"]); + break; + case "card": + game.addVideo("storage", this, [skill, get.cardInfo(this.storage[skill]), "card"]); + break; + default: + try { + game.addVideo("storage", this, [skill, JSON.parse(JSON.stringify(this.storage[skill]))]); + } catch (e) { + console.log(this.storage[skill]); + } + } + } + syncSkills() { + game.broadcast( + function (player, skills) { + player.applySkills(skills); + }, + this, + get.skillState(this) + ); + } + playerfocus(time) { + time = time || 1000; + this.classList.add("playerfocus"); + ui.arena.classList.add("playerfocus"); + var that = this; + setTimeout(function () { + that.classList.remove("playerfocus"); + ui.arena.classList.remove("playerfocus"); + }, time); + game.addVideo("playerfocus", this, time); + game.broadcast( + function (player, time) { + player.playerfocus(time); + }, + this, + time + ); + return this; + } + setIdentity(identity, nature) { + if (!identity) identity = this.identity; + if (get.is.jun(this)) { + this.node.identity.firstChild.innerHTML = "君"; + } else { + this.node.identity.firstChild.innerHTML = get.translation(identity); + } + this.node.identity.dataset.color = nature || identity; + return this; + } + insertPhase(skill, insert) { + var evt = _status.event.getParent("phase"); + var next; + if (evt && evt.parent && evt.parent.next) { + evt = evt.parent; + next = game.createEvent("phase", false, evt); + } else if (_status.event.parent && _status.event.parent.next) { + evt = _status.event.parent; + next = game.createEvent("phase", false, evt); + } else { + evt = null; + next = game.createEvent("phase", false); + } + if (evt && insert && evt.next.includes(next)) { + evt.next.remove(next); + evt.next.unshift(next); + } + next.player = this; + next.forceDie = true; + next.includeOut = true; + next.skill = skill || _status.event.name; + next.setContent("phase"); + return next; + } + insertEvent(name, content, arg) { + var evt = _status.event.getParent("phase"); + var next; + if (evt && evt.parent && evt.parent.next) { + next = game.createEvent(name, null, evt.parent); + } else { + next = game.createEvent(name); + } + for (var i in arg) { + next[i] = arg[i]; + } + next.player = this; + next.setContent(content); + return next; + } + phase(skill) { + var next = game.createEvent("phase", false); + next.player = this; + next.setContent("phase"); + if (!_status.roundStart) { + _status.roundStart = this; + } + if (skill) { + next.skill = skill; + } + next.forceDie = true; + next.includeOut = true; + return next; + } + phaseZhunbei() { + var next = game.createEvent("phaseZhunbei"); + next.player = this; + next.setContent("phaseZhunbei"); + return next; + } + phaseJudge() { + var next = game.createEvent("phaseJudge"); + next.player = this; + next.setContent("phaseJudge"); + return next; + } + phaseDraw() { + var next = game.createEvent("phaseDraw"); + next.player = this; + next.num = 2; + if ( + (get.config("first_less") || _status.connectMode || _status.first_less_forced) && + game.phaseNumber == 1 && + _status.first_less + ) { + next.num--; + } + next.setContent("phaseDraw"); + return next; + } + phaseUse() { + var next = game.createEvent("phaseUse", false); + next.player = this; + next.setContent("phaseUse"); + return next; + } + phaseDiscard() { + var next = game.createEvent("phaseDiscard"); + next.player = this; + next.setContent("phaseDiscard"); + return next; + } + phaseJieshu() { + var next = game.createEvent("phaseJieshu"); + next.player = this; + next.setContent("phaseJieshu"); + return next; + } + chooseToUse(use) { + var next = game.createEvent("chooseToUse"); + next.player = this; + if (arguments.length == 1 && get.objtype(arguments[0]) == "object") { + for (var i in use) { + next[i] = use[i]; + } + } else { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number" || get.itemtype(arguments[i]) == "select") { + next.selectTarget = arguments[i]; + } else if ( + (typeof arguments[i] == "object" && arguments[i]) || + typeof arguments[i] == "function" + ) { + if (get.itemtype(arguments[i]) == "player" || next.filterCard) { + next.filterTarget = arguments[i]; + } else next.filterCard = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + } + if (typeof next.filterCard == "object") { + next.filterCard = get.filter(next.filterCard); + } + if (typeof next.filterTarget == "object") { + next.filterTarget = get.filter(next.filterTarget, 2); + } + if (next.filterCard == undefined) { + next.filterCard = lib.filter.filterCard; + } + if (next.selectCard == undefined) { + next.selectCard = [1, 1]; + } + if (next.filterTarget == undefined) { + next.filterTarget = lib.filter.filterTarget; + } + if (next.selectTarget == undefined) { + next.selectTarget = lib.filter.selectTarget; + } + if (next.position == undefined) { + next.position = "hs"; + } + if (next.ai1 == undefined) next.ai1 = get.cacheOrder; + if (next.ai2 == undefined) next.ai2 = get.cacheEffectUse; + next.setContent("chooseToUse"); + next._args = Array.from(arguments); + return next; + } + chooseToRespond() { + var next = game.createEvent("chooseToRespond"); + next.player = this; + var filter; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + next.selectCard = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectCard = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (typeof arguments[i] == "function") { + if (next.filterCard) next.ai = arguments[i]; + else next.filterCard = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterCard = get.filter(arguments[i]); + filter = arguments[i]; + } else if (arguments[i] == "nosource") { + next.nosource = true; + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + if (next.filterCard == undefined) next.filterCard = lib.filter.all; + if (next.selectCard == undefined) next.selectCard = [1, 1]; + if (next.source == undefined && !next.nosource) next.source = _status.event.player; + if (next.ai == undefined) next.ai = get.unuseful2; + if (next.prompt != false) { + if (typeof next.prompt == "string") { + //next.dialog=next.prompt; + } else { + var str = "请打出" + get.cnNumber(next.selectCard[0]) + "张"; + if (filter) { + if (filter.name) { + str += get.translation(filter.name); + } else { + str += "牌"; + } + } else { + str += "牌"; + } + if (_status.event.getParent().name == "useCard") { + var cardname = _status.event.name; + if (lib.card[cardname] && lib.translate[cardname]) { + str += "响应" + lib.translate[cardname]; + } + } + next.prompt = str; + } + } + next.position = "hs"; + if (next.ai2 == undefined) next.ai2 = () => 1; + next.setContent("chooseToRespond"); + next._args = Array.from(arguments); + return next; + } + chooseToGive(...args) { + const next = game.createEvent("chooseToGive"); + next.player = this; + if (args.length == 1 && get.is.object(args[0])) { + for (const i in args[0]) next[i] = args[0][i]; + } else + for (const arg of args) { + if (get.itemtype(arg) == "player") { + next.target = arg; + } else if (typeof arg == "number") { + next.selectCard = [arg, arg]; + } else if (get.itemtype(arg) == "select") { + next.selectCard = arg; + } else if (get.itemtype(arg) == "dialog") { + next.dialog = arg; + next.prompt = false; + } else if (typeof arg == "boolean") { + next.forced = arg; + } else if (get.itemtype(arg) == "position") { + next.position = arg; + } else if (typeof arg == "function") { + if (next.filterCard) next.ai = arg; + else next.filterCard = arg; + } else if (typeof arg == "object" && arg) { + next.filterCard = get.filter(arg); + } else if (typeof arg == "string") { + get.evtprompt(next, arg); + } + if (arg === null) console.log(args); + } + if (next.isMine() == false && next.dialog) next.dialog.style.display = "none"; + if (next.filterCard == undefined) next.filterCard = lib.filter.all; + if (next.selectCard == undefined) next.selectCard = [1, 1]; + if (next.position == undefined) next.position = "h"; + if (next.ai == undefined) next.ai = get.unuseful; + next.setContent("chooseToGive"); + next._args = args; + return next; + } + chooseToDiscard() { + var next = game.createEvent("chooseToDiscard"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + next.selectCard = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectCard = arguments[i]; + } else if (get.itemtype(arguments[i]) == "dialog") { + next.dialog = arguments[i]; + next.prompt = false; + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (typeof arguments[i] == "function") { + if (next.filterCard) next.ai = arguments[i]; + else next.filterCard = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterCard = get.filter(arguments[i]); + } else if (typeof arguments[i] == "string") { + if (arguments[i] == "chooseonly") next.chooseonly = true; + else get.evtprompt(next, arguments[i]); + } + if (arguments[i] === null) { + for (var i = 0; i < arguments.length; i++) { + console.log(arguments[i]); + } + } + } + if (next.isMine() == false && next.dialog) next.dialog.style.display = "none"; + if (next.filterCard == undefined) next.filterCard = lib.filter.all; + if (next.selectCard == undefined) next.selectCard = [1, 1]; + if (next.ai == undefined) next.ai = get.unuseful; + next.autochoose = function () { + if (!this.forced) return false; + if (typeof this.selectCard == "function") return false; + if (this.complexCard || this.complexSelect || this.filterOk) return false; + var cards = this.player.getCards(this.position); + if (cards.some(card => !this.filterCard(card, this.player, this))) return false; + var num = cards.length; + for (var i = 0; i < cards.length; i++) { + if (!lib.filter.cardDiscardable(cards[i], this.player, this)) num--; + } + return get.select(this.selectCard)[0] >= num; + }; + next.setContent("chooseToDiscard"); + next._args = Array.from(arguments); + return next; + } + chooseToCompare(target, check) { + var next = game.createEvent("chooseToCompare"); + next.player = this; + if (Array.isArray(target)) { + next.targets = target; + if (check) next.ai = check; + else + next.ai = function (card) { + if (typeof card == "string" && lib.skill[card]) { + var ais = + lib.skill[card].check || + function () { + return 0; + }; + return ais(); + } + var addi = get.value(card) >= 8 && get.type(card) != "equip" ? -3 : 0; + if (card.name == "du") addi -= 3; + var source = _status.event.source; + var player = _status.event.player; + var event = _status.event.getParent(); + var getn = function (card) { + if (player.hasSkill("tianbian") && get.suit(card) == "heart") + return 13 * (Boolean(event.small) ? -1 : 1); + return get.number(card) * (Boolean(event.small) ? -1 : 1); + }; + if (source && source != player) { + if (get.attitude(player, source) > 1) { + if (Boolean(event.small)) return getn(card) - get.value(card) / 3 + addi; + return -getn(card) - get.value(card) / 3 + addi; + } + if (Boolean(event.small)) return -getn(card) - get.value(card) / 5 + addi; + return getn(card) - get.value(card) / 5 + addi; + } else { + if (Boolean(event.small)) return -getn(card) - get.value(card) / 5 + addi; + return getn(card) - get.value(card) / 5 + addi; + } + }; + next.setContent("chooseToCompareMultiple"); + } else { + next.target = target; + if (check) next.ai = check; + else + next.ai = function (card) { + if (typeof card == "string" && lib.skill[card]) { + var ais = + lib.skill[card].check || + function () { + return 0; + }; + return ais(); + } + var player = get.owner(card); + var getn = function (card) { + if (player.hasSkill("tianbian") && get.suit(card) == "heart") return 13; + return get.number(card); + }; + var event = _status.event.getParent(); + var to = player == event.player ? event.target : event.player; + var addi = get.value(card) >= 8 && get.type(card) != "equip" ? -6 : 0; + var friend = get.attitude(player, to) > 0; + if (card.name == "du") addi -= 5; + if (player == event.player) { + if (Boolean(event.small)) + return -getn(card) - get.value(card) / (friend ? 4 : 5) + addi; + return getn(card) - get.value(card) / (friend ? 4 : 5) + addi; + } else { + if (friend == Boolean(event.small)) + return getn(card) - get.value(card) / (friend ? 3 : 5) + addi; + return -getn(card) - get.value(card) / (friend ? 3 : 5) + addi; + } + }; + next.setContent("chooseToCompare"); + } + next.forceDie = true; + next._args = Array.from(arguments); + return next; + } + chooseSkill(target) { + var next = game.createEvent("chooseSkill"); + next.player = this; + next.setContent("chooseSkill"); + next.target = target; + for (var i = 1; i < arguments.length; i++) { + if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } else if (typeof arguments[i] == "function") { + next.func = arguments[i]; + } + } + } + discoverCard(list) { + var next = game.createEvent("discoverCard"); + next.player = this; + next.setContent("discoverCard"); + next.list = list || lib.inpile.slice(0); + next.forced = true; + for (var i = 1; i < arguments.length; i++) { + if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (typeof arguments[i] == "string") { + switch (arguments[i]) { + case "use": + next.use = true; + break; + case "nogain": + next.nogain = true; + break; + default: + next.prompt = arguments[i]; + } + } else if (typeof arguments[i] == "number") { + next.num = arguments[i]; + } else if (typeof arguments[i] === "function") { + next.ai = arguments[i]; + } + } + return next; + } + chooseCardButton() { + var cards, prompt, forced, select; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") cards = arguments[i]; + else if (typeof arguments[i] == "boolean") forced = arguments[i]; + else if (typeof arguments[i] == "string") prompt = arguments[i]; + else if (get.itemtype(arguments[i]) == "select" || typeof arguments[i] == "number") + select = arguments[i]; + } + if (prompt == undefined) prompt = "请选择卡牌"; + return this.chooseButton(forced, select, "hidden", [prompt, cards, "hidden"]); + } + chooseVCardButton() { + var list, + prompt, + forced, + select, + notype = false; + for (var i = 0; i < arguments.length; i++) { + if (Array.isArray(arguments[i])) { + list = arguments[i]; + } else if (arguments[i] == "notype") { + notype = true; + } else if (typeof arguments[i] == "boolean") forced = arguments[i]; + else if (typeof arguments[i] == "string") prompt = arguments[i]; + else if (get.itemtype(arguments[i]) == "select" || typeof arguments[i] == "number") + select = arguments[i]; + } + for (var i = 0; i < list.length; i++) { + list[i] = [notype ? "" : get.subtype(list[i], false) || get.type(list[i]), "", list[i]]; + } + if (prompt == undefined) prompt = "请选择卡牌"; + return this.chooseButton(forced, select, "hidden", [prompt, [list, "vcard"], "hidden"]); + } + chooseButton() { + var next = game.createEvent("chooseButton"); + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "boolean") { + if (!next.forced) next.forced = arguments[i]; + else next.complexSelect = arguments[i]; + } else if (get.itemtype(arguments[i]) == "dialog") { + next.dialog = arguments[i]; + next.closeDialog = true; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectButton = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.selectButton = [arguments[i], arguments[i]]; + } else if (typeof arguments[i] == "function") { + if (next.ai) next.filterButton = arguments[i]; + else next.ai = arguments[i]; + } else if (Array.isArray(arguments[i])) { + next.createDialog = arguments[i]; + } + } + next.player = this; + if (typeof next.forced != "boolean") next.forced = false; + if (next.isMine() == false && next.dialog) next.dialog.style.display = "none"; + if (next.filterButton == undefined) next.filterButton = lib.filter.filterButton; + if (next.selectButton == undefined) next.selectButton = [1, 1]; + if (next.ai == undefined) + next.ai = function () { + return 1; + }; + if (next.complexSelect !== false) next.complexSelect = true; + next.setContent("chooseButton"); + next._args = Array.from(arguments); + next.forceDie = true; + return next; + } + chooseButtonOL(list, callback, ai) { + var next = game.createEvent("chooseButtonOL"); + next.list = list; + next.setContent("chooseButtonOL"); + next.ai = ai; + next.callback = callback; + next._args = Array.from(arguments); + return next; + } + chooseCardOL() { + var next = game.createEvent("chooseCardOL"); + next._args = []; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "players") { + next.list = arguments[i].slice(0); + } else { + next._args.push(arguments[i]); + } + } + next.setContent("chooseCardOL"); + next._args.add("glow_result"); + return next; + } + chooseCard(choose) { + var next = game.createEvent("chooseCard"); + next.player = this; + if (arguments.length == 1 && get.is.object(choose)) { + for (var i in choose) { + next[i] = choose[i]; + } + } else { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + next.selectCard = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectCard = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (typeof arguments[i] == "function") { + if (next.filterCard) next.ai = arguments[i]; + else next.filterCard = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterCard = get.filter(arguments[i]); + } else if (arguments[i] == "glow_result") { + next.glow_result = true; + } else if (typeof arguments[i] == "string") { + get.evtprompt(next, arguments[i]); + } + } + } + if (next.filterCard == undefined) next.filterCard = lib.filter.all; + if (next.selectCard == undefined) next.selectCard = [1, 1]; + if (next.ai == undefined) next.ai = get.unuseful3; + next.autochoose = function () { + if (!this.forced) return false; + if (typeof this.selectCard == "function") return false; + if (this.complexCard || this.complexSelect || this.filterOk) return false; + var cards = this.player.getCards(this.position); + if (cards.some(card => !this.filterCard(card, this.player, this))) return false; + return get.select(this.selectCard)[0] >= this.player.countCards(this.position); + }; + next.setContent("chooseCard"); + next._args = Array.from(arguments); + return next; + } + chooseUseTarget() { + var next = game.createEvent("chooseUseTarget"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (get.itemtype(arguments[i]) == "players") { + next.targets = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + next.targets = [arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectTarget = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.selectTarget = [arguments[i], arguments[i]]; + } else if (get.is.object(arguments[i]) && arguments[i].name) { + next.card = arguments[i]; + } else if (typeof arguments[i] == "string") { + if (arguments[i] == "nopopup") { + next.nopopup = true; + } else if (arguments[i] == "noanimate") { + next.animate = false; + } else if (arguments[i] == "nothrow") { + next.throw = false; + } else if (arguments[i] == "nodistance") { + next.nodistance = true; + } else if (arguments[i] == "noTargetDelay") { + next.noTargetDelay = true; + } else if (arguments[i] == "nodelayx") { + next.nodelayx = true; + } else if (lib.card[arguments[i]] && !next.card) { + next.card = { name: arguments[i], isCard: true }; + } else get.evtprompt(next, arguments[i]); + } else if (arguments[i] === true) { + next.forced = true; + } else if (arguments[i] === false) { + next.addCount = false; + } + } + if (!next.targets) next.targets = game.players.slice(0); + if (next.cards == undefined) { + if (get.itemtype(next.card) == "card") { + next.cards = [next.card]; + } else next.cards = []; + } else if (next.card == undefined) { + if (next.cards) { + next.card = next.cards[0]; + } + } + next.setContent("chooseUseTarget"); + next._args = Array.from(arguments); + return next; + // Fully Online-Ready! Enjoy It! + } + chooseTarget() { + var next = game.createEvent("chooseTarget"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + next.selectTarget = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectTarget = arguments[i]; + } else if (get.itemtype(arguments[i]) == "dialog") { + next.dialog = arguments[i]; + next.prompt = false; + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (typeof arguments[i] == "function") { + if (next.filterTarget) next.ai = arguments[i]; + else next.filterTarget = arguments[i]; + } else if (typeof arguments[i] == "string") { + get.evtprompt(next, arguments[i]); + } + } + if (next.filterTarget == undefined) next.filterTarget = lib.filter.all; + if (next.selectTarget == undefined) next.selectTarget = [1, 1]; + if (next.ai == undefined) next.ai = get.attitude2; + next.setContent("chooseTarget"); + next._args = Array.from(arguments); + next.forceDie = true; + return next; + } + chooseCardTarget(choose) { + var next = game.createEvent("chooseCardTarget"); + next.player = this; + if (arguments.length == 1) { + for (var i in choose) { + next[i] = choose[i]; + } + } + if (typeof next.filterCard == "object") { + next.filterCard = get.filter(next.filterCard); + } + if (typeof next.filterTarget == "object") { + next.filterTarget = get.filter(next.filterTarget, 2); + } + if (next.filterCard == undefined || next.filterCard === true) { + next.filterCard = lib.filter.all; + } + if (next.selectCard == undefined) { + next.selectCard = 1; + } + if (next.filterTarget == undefined || next.filterTarget === true) { + next.filterTarget = lib.filter.all; + } + if (next.selectTarget == undefined) { + next.selectTarget = 1; + } + if (next.ai1 == undefined) next.ai1 = get.unuseful2; + if (next.ai2 == undefined) next.ai2 = get.attitude2; + next.setContent("chooseCardTarget"); + next._args = Array.from(arguments); + return next; + } + chooseControlList() { + var list = []; + var prompt = null; + var forced = "cancel2"; + var func = null; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "string") { + if (!prompt) { + prompt = arguments[i]; + } else { + list.push(arguments[i]); + } + } else if (Array.isArray(arguments[i])) { + list = arguments[i]; + } else if (arguments[i] === true) { + forced = null; + } else if (typeof arguments[i] == "function") { + func = arguments[i]; + } + } + return this.chooseControl(forced, func).set("choiceList", list).set("prompt", prompt); + } + chooseControl() { + var next = game.createEvent("chooseControl"); + next.controls = []; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "string") { + if (arguments[i] == "dialogcontrol") { + next.dialogcontrol = true; + } else if (arguments[i] == "seperate") { + next.seperate = true; + } else { + next.controls.push(arguments[i]); + } + } else if (Array.isArray(arguments[i])) { + next.controls = next.controls.concat(arguments[i]); + } else if (typeof arguments[i] == "function") { + next.ai = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.choice = arguments[i]; + } else if (get.itemtype(arguments[i]) == "dialog") { + next.dialog = arguments[i]; + } + } + next.player = this; + if (next.choice == undefined) next.choice = 0; + next.setContent("chooseControl"); + next._args = Array.from(arguments); + next.forceDie = true; + return next; + } + chooseBool() { + var next = game.createEvent("chooseBool"); + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "boolean") { + next.choice = arguments[i]; + } else if (typeof arguments[i] == "function") { + next.ai = arguments[i]; + } else if (typeof arguments[i] == "string") { + get.evtprompt(next, arguments[i]); + } else if (get.itemtype(arguments[i]) == "dialog") { + next.dialog = arguments[i]; + } + if (next.choice == undefined) next.choice = true; + } + next.player = this; + next.setContent("chooseBool"); + next._args = Array.from(arguments); + next.forceDie = true; + return next; + } + chooseDrawRecover() { + var next = game.createEvent("chooseDrawRecover", false); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + if (typeof next.num1 == "number") { + next.num2 = arguments[i]; + } else { + next.num1 = arguments[i]; + } + } else if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } else if (typeof arguments[i] == "function") { + next.ai = arguments[i]; + } + } + if (typeof next.num1 != "number") { + next.num1 = 1; + } + if (typeof next.num2 != "number") { + next.num2 = 1; + } + next.setContent("chooseDrawRecover"); + return next; + } + choosePlayerCard() { + var next = game.createEvent("choosePlayerCard"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.target = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.selectButton = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectButton = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + if (!next.forced) next.forced = arguments[i]; + else next.complexSelect = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (arguments[i] == "visible") { + next.visible = true; + } else if (typeof arguments[i] == "function") { + if (next.ai) next.filterButton = arguments[i]; + else next.ai = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterButton = get.filter(arguments[i]); + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + if (next.filterButton == undefined) next.filterButton = lib.filter.all; + if (next.position == undefined) next.position = "he"; + if (next.selectButton == undefined) next.selectButton = [1, 1]; + if (next.ai == undefined) + next.ai = function (button) { + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, get.owner(button.link)) > 0) return -val; + return val; + }; + if (next.complexSelect !== false) next.complexSelect = true; + next.setContent("choosePlayerCard"); + next._args = Array.from(arguments); + return next; + } + discardPlayerCard() { + var next = game.createEvent("discardPlayerCard"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.target = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.selectButton = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectButton = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + if (!next.forced) next.forced = arguments[i]; + else next.complexSelect = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (arguments[i] == "visible") { + next.visible = true; + } else if (typeof arguments[i] == "function") { + if (next.ai) next.filterButton = arguments[i]; + else next.ai = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterButton = get.filter(arguments[i]); + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + if (next.filterButton == undefined) next.filterButton = lib.filter.all; + if (next.position == undefined) next.position = "he"; + if (next.selectButton == undefined) next.selectButton = [1, 1]; + if (next.ai == undefined) + next.ai = function (button) { + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, get.owner(button.link)) > 0) return -val; + return val; + }; + if (next.complexSelect !== false) next.complexSelect = true; + next.setContent("discardPlayerCard"); + next._args = Array.from(arguments); + return next; + } + gainPlayerCard() { + var next = game.createEvent("gainPlayerCard"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.target = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.selectButton = [arguments[i], arguments[i]]; + } else if (get.itemtype(arguments[i]) == "select") { + next.selectButton = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + if (!next.forced) next.forced = arguments[i]; + else next.complexSelect = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + next.position = arguments[i]; + } else if (arguments[i] == "visible") { + next.visible = true; + } else if (arguments[i] == "visibleMove") { + next.visibleMove = true; + } else if (typeof arguments[i] == "function") { + if (next.ai) next.filterButton = arguments[i]; + else next.ai = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filterButton = get.filter(arguments[i]); + } else if (typeof arguments[i] == "string") { + next.prompt = arguments[i]; + } + } + if (next.filterButton == undefined) next.filterButton = lib.filter.all; + if (next.position == undefined) next.position = "he"; + if (next.selectButton == undefined) next.selectButton = [1, 1]; + if (next.ai == undefined) + next.ai = function (button) { + var val = get.buttonValue(button); + if (get.attitude(_status.event.player, get.owner(button.link)) > 0) return -val; + return val; + }; + if (next.complexSelect !== false) next.complexSelect = true; + next.setContent("gainPlayerCard"); + next._args = Array.from(arguments); + return next; + } + showHandcards(str) { + var next = game.createEvent("showHandcards"); + next.player = this; + if (typeof str == "string") { + next.prompt = str; + } + next.setContent("showHandcards"); + next._args = Array.from(arguments); + return next; + } + showCards(cards, str) { + var next = game.createEvent("showCards"); + next.player = this; + next.str = str; + if (typeof cards == "string") { + str = cards; + cards = next.str; + next.str = str; + } + if (get.itemtype(cards) == "card") next.cards = [cards]; + else if (get.itemtype(cards) == "cards") next.cards = cards.slice(0); + else { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("showCards"); + next._args = Array.from(arguments); + return next; + } + viewCards(str, cards) { + var next = game.createEvent("viewCards"); + next.player = this; + next.str = str; + next.cards = cards.slice(0); + next.setContent("viewCards"); + next._args = Array.from(arguments); + return next; + } + viewHandcards(target) { + var cards = target.getCards("h"); + if (cards.length) { + return this.viewCards(get.translation(target) + "的手牌", cards); + } else { + return false; + } + } + canMoveCard(withatt, nojudge) { + const player = this; + const args = Array.from(arguments).slice(2); + let sourceTargets, aimTargets, filterCard, canReplace; + args.forEach((arg) => { + if (get.itemtype(arg) == "players") { + if (!sourceTargets) sourceTargets = arg; + else if (!aimTargets) aimTargets = arg; + } else if (get.itemtype(arg) == "player") { + if (!sourceTargets) sourceTargets = [arg]; + else if (!aimTargets) aimTargets = [arg]; + } else if (typeof arg == "function") { + filterCard = arg; + } else if (typeof arg == "object" && arg) { + filterCard = get.filter(arg); + } else if (arg == "canReplace") { + canReplace = true; + } + }); + if (!sourceTargets) sourceTargets = game.filterPlayer(); + if (!aimTargets) aimTargets = game.filterPlayer(); + return sourceTargets.some((current) => { + const att = get.sgn(get.attitude(player, current)); + if (!withatt || att != 0) { + var es = current.getCards("e", filterCard); + for (var i = 0; i < es.length; i++) { + if ( + aimTargets.some((current2) => { + if (withatt) { + if (get.sgn(get.value(es[i], current)) != -att) return false; + var att2 = get.sgn(get.attitude(player, current2)); + if ( + !canReplace || + (att < 0 && current2.countEquipableSlot(get.subtype(es[i]))) + ) { + if ( + att == att2 || + att2 != get.sgn(get.effect(current2, es[i], player, current2)) + ) + return false; + } + } + return ( + current != current2 && + !current2.isMin() && + current2.canEquip(es[i], canReplace) + ); + }) + ) { + return true; + } + } + } + if (!nojudge && (!withatt || att > 0)) { + var js = current.getCards("j", filterCard); + for (var i = 0; i < js.length; i++) { + if ( + game.hasPlayer(function (current2) { + if (withatt) { + var att2 = get.attitude(player, current2); + if (att2 >= 0) return false; + } + return current != current2 && current2.canAddJudge(js[i]); + }) + ) { + return true; + } + } + } + }); + } + moveCard() { + var next = game.createEvent("moveCard"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "boolean") { + next.forced = arguments[i]; + } else if (get.itemtype(arguments[i]) == "players") { + if (!next.sourceTargets) next.sourceTargets = arguments[i]; + else if (!next.aimTargets) next.aimTargets = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + if (!next.sourceTargets) next.sourceTargets = [arguments[i]]; + else if (!next.aimTargets) next.aimTargets = [arguments[i]]; + } else if (typeof arguments[i] == "string") { + if (arguments[i] == "canReplace") { + next.canReplace = true; + } else { + get.evtprompt(next, arguments[i]); + } + } else if (Array.isArray(arguments[i])) { + for (var j = 0; j < arguments[i].length; j++) { + if (typeof arguments[i][j] != "string") break; + } + if (j == arguments[i].length) { + next.targetprompt = arguments[i]; + } + } else if (typeof arguments[i] == "function") { + next.filter = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i]) { + next.filter = get.filter(arguments[i]); + } + } + if (!next.sourceTargets) next.sourceTargets = game.filterPlayer(); + if (!next.aimTargets) next.aimTargets = game.filterPlayer(); + if (next.filter == undefined) next.filter = lib.filter.all; + next.setContent("moveCard"); + next._args = Array.from(arguments); + return next; + } + useResult(result, event) { + event = event || _status.event; + if (result._sendskill) { + lib.skill[result._sendskill[0]] = result._sendskill[1]; + } + if (event.onresult) { + event.onresult(result); + } + if (result.skill) { + var info = get.info(result.skill); + if (info.onuse) { + info.onuse(result, this); + } + // if(info.direct&&!info.clearTime){ + // _status.noclearcountdown=true; + // } + } + if (event.logSkill) { + if (typeof event.logSkill == "string") { + this.logSkill(event.logSkill); + } else if (Array.isArray(event.logSkill)) { + this.logSkill.call(this, ...event.logSkill); + } + } + if (result.card || !result.skill) { + result.used = result.card || result.cards[0]; + var next = this.useCard(result.used, result.cards, result.targets, result.skill); + next.oncard = event.oncard; + next.respondTo = event.respondTo; + if (event.addCount === false) { + next.addCount = false; + } + if (result._apply_args) { + for (var i in result._apply_args) { + next[i] = result._apply_args[i]; + } + } + return next; + } else if (result.skill) { + result.used = result.skill; + return this.useSkill(result.skill, result.cards, result.targets); + } + } + useCard() { + var next = game.createEvent("useCard"); + next.player = this; + next.num = 0; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "players") { + next.targets = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + next.targets = [arguments[i]]; + } else if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i] && arguments[i].name) { + next.card = arguments[i]; + } else if (typeof arguments[i] == "string") { + if (arguments[i] == "noai") { + next.noai = true; + } else if (arguments[i] == "nowuxie") { + next.nowuxie = true; + } else { + next.skill = arguments[i]; + } + } else if (typeof arguments[i] == "boolean") { + next.addCount = arguments[i]; + } + } + if (next.cards == undefined) { + if (get.itemtype(next.card) == "card") { + next.cards = [next.card]; + } else next.cards = []; + } else if (next.card == undefined) { + if (next.cards) { + next.card = next.cards[0]; + } + } + if (!next.targets) { + next.targets = []; + } + if (next.card) { + next.card = get.autoViewAs(next.card, next.cards); + var info = get.info(next.card); + if (info.changeTarget) { + info.changeTarget(next.player, next.targets); + } + if (info.singleCard) { + next._targets = next.targets.slice(0); + next.target = next.targets[0]; + next.addedTargets = next.targets.splice(1); + if (next.addedTargets.length) { + next.addedTarget = next.addedTargets[0]; + } + } + } + for (var i = 0; i < next.targets.length; i++) { + if (get.attitude(this, next.targets[i]) >= -1 && get.attitude(this, next.targets[i]) < 0) { + if (!this.ai.tempIgnore) this.ai.tempIgnore = []; + this.ai.tempIgnore.add(next.targets[i]); + } + } + if ( + typeof this.logAi == "function" && + !next.noai && + !get.info(next.card).noai && + !this.hasSkillTag( + this, + true, + { + card: next.card, + targets: next.targets, + }, + true + ) + ) { + var postAi = get.info(next.card).postAi; + if (postAi && postAi(next.targets)) { + next.postAi = true; + } else { + this.logAi(next.targets, next.card); + } + } + next.stocktargets = next.targets.slice(0); + next.setContent("useCard"); + return next; + } + useSkill() { + var next = game.createEvent("useSkill"); + next.player = this; + next.num = 0; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "players") { + next.targets = arguments[i]; + } else if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.skill = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.addCount = arguments[i]; + } + } + if (next.cards == undefined) { + next.cards = []; + } + if (next.skill && get.info(next.skill) && get.info(next.skill).changeTarget) { + get.info(next.skill).changeTarget(next.player, next.targets); + } + if (next.targets) { + for (var i = 0; i < next.targets.length; i++) { + if (get.attitude(this, next.targets[i]) >= -1 && get.attitude(this, next.targets[i]) < 0) { + if (!this.ai.tempIgnore) this.ai.tempIgnore = []; + this.ai.tempIgnore.add(next.targets[i]); + } + } + if (typeof this.logAi == "function") { + this.logAi(next.targets, next.skill); + } + } else { + next.targets = []; + } + next.setContent("useSkill"); + return next; + } + drawTo(num, args) { + var num2 = num - this.countCards("h"); + var next = this.draw(num2); + if (Array.isArray(args)) { + for (var i = 0; i < args.length; i++) { + if (get.itemtype(args[i]) == "player") { + next.source = args[i]; + } else if (typeof args[i] == "boolean") { + next.animate = args[i]; + } else if (args[i] == "nodelay") { + next.animate = false; + next.$draw = true; + } else if (args[i] == "visible") { + next.visible = true; + } else if (args[i] == "bottom") { + next.bottom = true; + } else if (typeof args[i] == "object" && args[i] && args[i].drawDeck != undefined) { + next.drawDeck = args[i].drawDeck; + } + } + } + return next; + } + draw() { + var next = game.createEvent("draw"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.num = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.animate = arguments[i]; + } else if (arguments[i] == "nodelay") { + next.animate = false; + next.$draw = true; + } else if (arguments[i] == "visible") { + next.visible = true; + } else if (arguments[i] == "bottom") { + next.bottom = true; + } else if ( + typeof arguments[i] == "object" && + arguments[i] && + arguments[i].drawDeck != undefined + ) { + next.drawDeck = arguments[i].drawDeck; + } + } + if (next.num == undefined) next.num = 1; + if (next.num <= 0) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("draw"); + if ( + lib.config.mode == "stone" && + _status.mode == "deck" && + next.drawDeck == undefined && + !next.player.isMin() && + next.num > 1 + ) { + next.drawDeck = 1; + } + next.result = []; + return next; + } + randomDiscard() { + var position = "he", + num = 1, + delay = null; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + num = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + position = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + delay = arguments[i]; + } + } + var cards = this.getCards(position).randomGets(num); + if (cards.length) { + var next = this.discard(cards, "notBySelf"); + if (typeof delay == "boolean") { + next.delay = delay; + } + } + return cards; + } + randomGain() { + var position = "he", + num = 1, + target = null, + line = false; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + num = arguments[i]; + } else if (get.itemtype(arguments[i]) == "position") { + position = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + target = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + line = arguments[i]; + } + } + if (target) { + var cards = target.getCards(position).randomGets(num); + if (cards.length) { + if (line) { + this.line(target, "green"); + } + this.gain(cards, target, "log", "bySelf"); + target.$giveAuto(cards, this); + } + return cards; + } + return []; + } + discard() { + var next = game.createEvent("discard"); + next.player = this; + next.num = 0; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.cards = [arguments[i]]; + } else if (typeof arguments[i] == "boolean") { + next.animate = arguments[i]; + } else if (["div", "fragment"].includes(get.objtype(arguments[i]))) { + next.position = arguments[i]; + } else if (arguments[i] == "notBySelf") { + next.notBySelf = true; + } + } + if (next.cards == undefined) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("discard"); + return next; + } + loseToDiscardpile() { + var next = game.createEvent("loseToDiscardpile"); + next.player = this; + next.num = 0; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.cards = [arguments[i]]; + } else if (typeof arguments[i] == "boolean") { + next.animate = arguments[i]; + } else if (["div", "fragment"].includes(get.objtype(arguments[i]))) { + next.position = arguments[i]; + } else if (arguments[i] == "notBySelf") { + next.notBySelf = true; + } else if (arguments[i] == "insert") { + next.insert_card = true; + } else if (arguments[i] == "blank") { + next.blank = true; + } + } + if (next.cards == undefined) { + _status.event.next.remove(next); + next.resolve(); + } + next.setContent("loseToDiscardpile"); + return next; + } + respond() { + var next = game.createEvent("respond"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i] && arguments[i].name) { + next.card = arguments[i]; + } else if (typeof arguments[i] == "boolean") next.animate = arguments[i]; + else if (arguments[i] == "highlight") next.highlight = true; + else if (arguments[i] == "noOrdering") next.noOrdering = true; + else if (typeof arguments[i] == "string") next.skill = arguments[i]; + } + if (next.cards == undefined) { + if (get.itemtype(next.card) == "card") { + next.cards = [next.card]; + } else { + next.cards = []; + } + } else if (next.card == undefined) { + if (next.cards) { + next.card = next.cards[0]; + if (!next.skill) { + next.card = get.autoViewAs(next.card, next.cards); + } + } + } + next.setContent("respond"); + return next; + } + swapHandcards(target, cards1, cards2) { + var next = game.createEvent("swapHandcards", false); + next.player = this; + next.target = target; + if (cards1) next.cards1 = cards1; + if (cards2) next.cards2 = cards2; + next.setContent("swapHandcards"); + return next; + } + directequip(cards) { + for (var i = 0; i < cards.length; i++) { + this.$equip(cards[i]); + } + if (!_status.video) { + game.addVideo("directequip", this, get.cardsInfo(cards)); + } + } + $addToExpansion(cards, broadcast, gaintag) { + var hs = this.getCards("x"); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var i = 0; i < cards.length; i++) { + cards[i].fix(); + if (gaintag) cards[i].addGaintag(gaintag); + var sort = lib.config.sort_card(cards[i]); + this.node.expansions.insertBefore(cards[i], this.node.expansions.firstChild); + } + if (broadcast !== false) + game.broadcast( + function (player, cards, gaintag) { + player.$addToExpansion(cards, null, gaintag); + }, + this, + cards, + gaintag + ); + return this; + } + directgain(cards, broadcast, gaintag) { + var hs = this.getCards("hs"); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + for (var i = 0; i < cards.length; i++) { + cards[i].fix(); + if (gaintag) cards[i].addGaintag(gaintag); + var sort = lib.config.sort_card(cards[i]); + if (this == game.me) { + cards[i].classList.add("drawinghidden"); + } + if (get.is.singleHandcard() || sort > 0) { + this.node.handcards1.insertBefore(cards[i], this.node.handcards1.firstChild); + } else { + this.node.handcards2.insertBefore(cards[i], this.node.handcards2.firstChild); + } + } + if (this == game.me || _status.video) ui.updatehl(); + if (!_status.video) { + game.addVideo("directgain", this, get.cardsInfo(cards)); + this.update(); + } + if (broadcast !== false) + game.broadcast( + function (player, cards) { + player.directgain(cards); + }, + this, + cards + ); + return this; + } + directgains(cards, broadcast, gaintag) { + var hs = this.getCards("hs"); + for (var i = 0; i < cards.length; i++) { + if (hs.includes(cards[i])) { + cards.splice(i--, 1); + } + } + var addLast = function (card, node) { + if (gaintag) { + for (var i = 0; i < node.childNodes.length; i++) { + var add = node.childNodes[node.childNodes.length - i - 1]; + if (!add.classList.contains("glows")) break; + if (add.hasGaintag(gaintag)) { + node.insertBefore(card, add.nextSibling); + return; + } + } + } + node.appendChild(card); + }; + for (var i = 0; i < cards.length; i++) { + cards[i].fix(); + cards[i].remove(); + if (gaintag) cards[i].addGaintag(gaintag); + cards[i].classList.add("glows"); + if (this == game.me) { + cards[i].classList.add("drawinghidden"); + } + if (get.is.singleHandcard()) { + addLast(cards[i], this.node.handcards1); + } else { + addLast(cards[i], this.node.handcards2); + } + } + if (this == game.me || _status.video) ui.updatehl(); + if (!_status.video) { + game.addVideo("directgains", this, get.cardsInfo(cards)); + this.update(); + } + if (broadcast !== false) + game.broadcast( + function (player, cards, gaintag) { + player.directgains(cards, null, gaintag); + }, + this, + cards, + gaintag + ); + return this; + } + gainMultiple(targets, position) { + var next = game.createEvent("gainMultiple", false); + next.setContent("gainMultiple"); + next.player = this; + next.targets = targets; + next.position = position || "h"; + return next; + } + gain() { + var next = game.createEvent("gain"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.cards = [arguments[i]]; + } else if (arguments[i] === "log") { + next.log = true; + } else if (arguments[i] == "fromStorage") { + next.fromStorage = true; + } else if (arguments[i] == "fromRenku") { + next.fromStorage = true; + next.fromRenku = true; + } else if (arguments[i] == "bySelf") { + next.bySelf = true; + } else if (typeof arguments[i] == "string") { + next.animate = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.delay = arguments[i]; + } + } + if (next.animate == "gain2" || next.animate == "draw2") { + if (!("log" in next)) { + next.log = true; + } + } + next.setContent("gain"); + next.getd = function (player, key, position) { + if (!position) position = ui.discardPile; + if (!key) key = "cards"; + var cards = [], + event = this; + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.position != position || evt.getParent() != event) return; + if (player && player != evt.player) return; + cards.addArray(evt[key]); + }); + return cards; + }; + next.getl = function (player) { + const that = this; + const map = { + player: player, + hs: [], + es: [], + js: [], + ss: [], + xs: [], + cards: [], + cards2: [], + gaintag_map: {}, + }; + player.checkHistory("lose", function (evt) { + if (evt.parent == that) { + map.hs.addArray(evt.hs); + map.es.addArray(evt.es); + map.js.addArray(evt.js); + map.ss.addArray(evt.ss); + map.xs.addArray(evt.xs); + map.cards.addArray(evt.cards); + map.cards2.addArray(evt.cards2); + for (let key in evt.gaintag_map) { + if (!map.gaintag_map[key]) map.gaintag_map[key] = []; + map.gaintag_map[key].addArray(evt.gaintag_map[key]); + } + } + }); + return map; + }; + next.getg = function (player) { + if (this.getlx === false || player != this.player || !this.cards) return []; + return this.cards.slice(0); + }; + next.gaintag = []; + return next; + } + addToExpansion() { + var next = game.createEvent("addToExpansion"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.cards = [arguments[i]]; + } else if (arguments[i] === "log") { + next.log = true; + } else if (arguments[i] == "fromStorage") { + next.fromStorage = true; + } else if (arguments[i] == "fromRenku") { + next.fromStorage = true; + next.fromRenku = true; + } else if (arguments[i] == "bySelf") { + next.bySelf = true; + } else if (typeof arguments[i] == "string") { + next.animate = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.delay = arguments[i]; + } + } + if (next.animate == "gain2" || next.animate == "draw2" || next.animate == "give") { + if (!("log" in next)) { + next.log = true; + } + } + next.setContent("addToExpansion"); + next.getd = function (player, key, position) { + if (!position) position = ui.discardPile; + if (!key) key = "cards"; + var cards = [], + event = this; + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.position != position || evt.getParent() != event) return; + if (player && player != evt.player) return; + cards.addArray(evt[key]); + }); + return cards; + }; + next.getl = function (player) { + const that = this; + const map = { + player: player, + hs: [], + es: [], + js: [], + ss: [], + xs: [], + cards: [], + cards2: [], + gaintag_map: {}, + }; + player.checkHistory("lose", function (evt) { + if (evt.parent == that) { + map.hs.addArray(evt.hs); + map.es.addArray(evt.es); + map.js.addArray(evt.js); + map.ss.addArray(evt.ss); + map.xs.addArray(evt.xs); + map.cards.addArray(evt.cards); + map.cards2.addArray(evt.cards2); + for (let key in evt.gaintag_map) { + if (!map.gaintag_map[key]) map.gaintag_map[key] = []; + map.gaintag_map[key].addArray(evt.gaintag_map[key]); + } + } + }); + return map; + }; + next.gaintag = []; + return next; + } + give(cards, target, visible) { + var next = target.gain(cards, this); + next.animate = visible ? "give" : "giveAuto"; + next.giver = this; + return next; + } + lose() { + var next = game.createEvent("lose"); + next.player = this; + next.forceDie = true; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.cards = [arguments[i]]; + } else if (["div", "fragment"].includes(get.objtype(arguments[i]))) { + next.position = arguments[i]; + } else if (arguments[i] == "toStorage") { + next.toStorage = true; + } else if (arguments[i] == "toRenku") { + next.toStorage = true; + next.toRenku = true; + } else if (arguments[i] == "visible") { + next.visible = true; + } else if (arguments[i] == "insert") { + next.insert_card = true; + } + } + if (next.cards) { + var hej = this.getCards("hejsx"); + for (var i = 0; i < next.cards.length; i++) { + if (!hej.includes(next.cards[i])) { + next.cards.splice(i--, 1); + } + } + } + if (!next.cards || !next.cards.length) { + _status.event.next.remove(next); + next.resolve(); + } else { + if (next.position == undefined) next.position = ui.discardPile; + next.cards = next.cards.slice(0); + } + next.setContent("lose"); + next.getd = function (player, key, position) { + if (!position) position = ui.discardPile; + if (!key) key = "cards"; + if ( + this.getlx === false || + this.position != position || + (player && this.player != player) || + !Array.isArray(this[key]) + ) + return []; + return this[key].slice(0); + }; + next.getl = function (player) { + if (this.getlx !== false && this.player == player) return this; + return { + player: player, + hs: [], + es: [], + js: [], + ss: [], + xs: [], + cards: [], + cards2: [], + gaintag_map: {}, + }; + }; + return next; + } + damage() { + const next = game.createEvent("damage"); + //next.forceDie=true; + next.player = this; + let noCard, noSource; + const event = _status.event; + for (const argument of arguments) { + if (get.itemtype(argument) == "cards") next.cards = argument.slice(); + else if (get.itemtype(argument) == "card") next.card = argument; + else if (typeof argument == "number") next.num = argument; + else if (get.itemtype(argument) == "player") next.source = argument; + else if (argument && typeof argument == "object" && argument.name) next.card = argument; + else if (argument == "nocard") noCard = true; + else if (argument == "nosource") noSource = true; + else if (argument == "notrigger") { + next._triggered = null; + next.notrigger = true; + } else if (argument == "unreal") next.unreal = true; + else if (get.itemtype(argument) == "nature" && argument != "stab") next.nature = argument; + else if (get.itemtype(argument) == "natures") { + const natures = argument.split(lib.natureSeparator).remove("stab"); + if (natures.length) next.nature = natures.join(lib.natureSeparator); + } + } + if (!next.card && !noCard) next.card = event.card; + if (!next.cards && !noCard) next.cards = event.cards; + if (!next.source && !noSource) { + const source = event.customSource || event.player; + if (source && !source.isDead()) next.source = source; + } + if (typeof next.num != "number") next.num = (event.baseDamage || 1) + (event.extraDamage || 0); + next.original_num = next.num; + next.change_history = []; + next.hasNature = function (nature) { + if (!nature) return Boolean(this.nature && this.nature.length > 0); + let natures = get.natureList(nature), + naturesx = get.natureList(this.nature); + if (nature == "linked") return naturesx.some((n) => lib.linked.includes(n)); + return get.is.sameNature(natures, naturesx); + }; + if (next.hasNature("poison")) delete next._triggered; + next.setContent("damage"); + next.filterStop = function () { + if (this.source && this.source.isDead()) delete this.source; + var num = this.original_num; + for (var i of this.change_history) num += i; + if (num != this.num) this.change_history.push(this.num - num); + if (this.num <= 0) { + delete this.filterStop; + this.trigger("damageZero"); + this.finish(); + this._triggered = null; + return true; + } + }; + return next; + } + recover() { + var next = game.createEvent("recover"); + next.player = this; + var nocard, nosource; + var event = _status.event; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "cards") { + next.cards = arguments[i].slice(0); + } else if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (get.itemtype(arguments[i]) == "player") { + next.source = arguments[i]; + } else if (typeof arguments[i] == "object" && arguments[i] && arguments[i].name) { + next.card = arguments[i]; + } else if (typeof arguments[i] == "number") { + next.num = arguments[i]; + } else if (arguments[i] == "nocard") { + nocard = true; + } else if (arguments[i] == "nosource") { + nosource = true; + } + } + if (next.card == undefined && !nocard) next.card = event.card; + if (next.cards == undefined && !nocard) next.cards = event.cards; + if (next.source == undefined && !nosource) next.source = event.customSource || event.player; + if (next.num == undefined) next.num = (event.baseDamage || 1) + (event.extraDamage || 0); + next.filterStop = function () { + if (this.num <= 0 || this.player.isHealthy()) { + delete this.filterStop; + this.finish(); + this._triggered = null; + return true; + } + }; + next.setContent("recover"); + return next; + } + recoverTo() { + const newArguments = []; + let num = 1; + for (let i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === "number") { + num = arguments[i] - this.getHp(true); + newArguments.push(num); + } else { + newArguments.push(arguments[i]); + } + } + return this.recover(...newArguments); + } + doubleDraw() { + var next = game.createEvent("doubleDraw"); + if (get.is.changban()) { + _status.event.next.remove(next); + next.resolve(); + } + next.player = this; + next.setContent("doubleDraw"); + return next; + } + loseHp(num) { + var next = game.createEvent("loseHp"); + next.num = num; + next.player = this; + if (next.num == undefined) next.num = 1; + next.setContent("loseHp"); + next.filterStop = function () { + if (this.num <= 0) { + delete this.filterStop; + this.finish(); + this._triggered = null; + return true; + } + }; + return next; + } + loseMaxHp() { + var next = game.createEvent("loseMaxHp"); + next.player = this; + next.num = 1; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === "number") { + next.num = arguments[i]; + } else if (typeof arguments[i] === "boolean") { + next.forced = arguments[i]; + } + } + next.setContent("loseMaxHp"); + return next; + } + gainMaxHp() { + var next = game.createEvent("gainMaxHp"); + next.player = this; + next.num = 1; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === "number") { + next.num = arguments[i]; + } else if (typeof arguments[i] === "boolean") { + next.forced = arguments[i]; + } + } + next.setContent("gainMaxHp"); + return next; + } + changeHp(num, popup) { + var next = game.createEvent("changeHp"); + next.num = num; + if (popup != undefined) next.popup = popup; + next.player = this; + next.setContent("changeHp"); + return next; + } + + changeHujia(num, type, limit) { + var next = game.createEvent("changeHujia"); + if (typeof num != "number") { + num = 1; + } + if (limit === true) limit = 5; + if (typeof limit == "number" && this.hujia + num > parseInt(limit)) { + num = Math.max(0, parseInt(limit) - this.hujia); + } + if (typeof type != "string") { + if (num > 0) type = "gain"; + else if (num < 0) type = "lose"; + else type = "null"; + } + next.num = num; + next.player = this; + next.type = type; + next.setContent("changeHujia"); + return next; + } + getBuff() { + var list = [1, 2, 3, 4, 5, 6]; + var nodelay = false; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + list.remove(arguments[i]); + } else if (arguments[i] === false) { + nodelay = true; + } + } + if (this.isHealthy()) { + list.remove(2); + } + if (!this.countCards("j")) { + list.remove(5); + } + if (!this.isLinked() && !this.isTurnedOver()) { + list.remove(6); + } + if (this.hasSkill("qianxing")) { + list.remove(4); + } + switch (list.randomGet()) { + case 1: + this.draw(nodelay ? "nodelay" : 1); + break; + case 2: + this.recover(); + break; + case 3: + this.changeHujia(); + break; + case 4: + this.tempHide(); + break; + case 5: + this.discard(this.getCards("j")).delay = !nodelay; + break; + case 6: { + if (this.isLinked()) this.link(); + if (this.isTurnedOver()) this.turnOver(); + break; + } + } + return this; + } + getDebuff() { + var list = [1, 2, 3, 4, 5, 6]; + var nodelay = false; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "number") { + list.remove(arguments[i]); + } else if (arguments[i] === false) { + nodelay = true; + } + } + if (this.countCards("he") == 0) { + list.remove(1); + } + if (this.isLinked()) { + list.remove(4); + } + if (this.hasSkill("fengyin")) { + list.remove(5); + } + if (this.hp == 1) { + list.remove(3); + if (list.length > 1) list.remove(2); + } + if (!list.length) return this; + var num = list.randomGet(); + switch (list.randomGet()) { + case 1: + this.randomDiscard(nodelay ? false : "he"); + break; + case 2: + this.loseHp(); + break; + case 3: + this.damage(); + break; + case 4: + if (!this.isLinked()) this.link(); + break; + case 5: + this.addTempSkill("fengyin", { player: "phaseAfter" }); + break; + case 6: { + var list = []; + for (var i = 0; i < lib.inpile.length; i++) { + var info = lib.card[lib.inpile[i]]; + if (info.type == "delay" && !info.cancel && !this.hasJudge(lib.inpile[i])) { + list.push(lib.inpile[i]); + } + } + if (list.length) { + var card = game.createCard(list.randomGet()); + this.addJudge(card); + this.$draw(card); + if (!nodelay) game.delay(); + } else { + this.getDebuff(6); + } + break; + } + } + return this; + } + dying(reason) { + if (this.nodying || this.hp > 0 || this.isDying()) return; + var next = game.createEvent("dying"); + next.player = this; + next.reason = reason; + if (reason && reason.source) next.source = reason.source; + next.setContent("dying"); + next.filterStop = function () { + if (this.player.hp > 0 || this.nodying) { + delete this.filterStop; + return true; + } + }; + return next; + } + die(reason) { + var next = game.createEvent("die"); + next.player = this; + next.reason = reason; + if (reason) next.source = reason.source; + next.setContent("die"); + return next; + } + revive(hp, log) { + if (log !== false) game.log(this, "复活"); + if (this.maxHp < 1) this.maxHp = 1; + if (hp) this.hp = hp; + else { + this.hp = 1; + } + game.addVideo("revive", this); + this.classList.remove("dead"); + this.removeAttribute("style"); + this.node.avatar.style.transform = ""; + this.node.avatar2.style.transform = ""; + this.node.hp.show(); + this.node.equips.show(); + this.node.count.show(); + this.update(); + var player; + player = this.previousSeat; + while (player.isDead()) player = player.previousSeat; + player.next = this; + this.previous = player; + player = this.nextSeat; + while (player.isDead()) player = player.nextSeat; + player.previous = this; + this.next = player; + game.players.add(this); + game.dead.remove(this); + if (this == game.me) { + if (ui.auto) ui.auto.show(); + if (ui.wuxie) ui.wuxie.show(); + if (ui.revive) { + ui.revive.close(); + delete ui.revive; + } + if (ui.exit) { + ui.exit.close(); + delete ui.exit; + } + if (ui.swap) { + ui.swap.close(); + delete ui.swap; + } + if (ui.restart) { + ui.restart.close(); + delete ui.restart; + } + if (ui.continue_game) { + ui.continue_game.close(); + delete ui.continue_game; + } + } + } + isMad() { + return this.hasSkill("mad"); + } + goMad(end) { + if (end) { + this.addTempSkill("mad", end); + } else { + this.addSkill("mad"); + } + game.log(this, "进入混乱状态"); + } + unMad() { + this.removeSkill("mad"); + } + tempHide() { + this.addTempSkill("qianxing", { player: "phaseBeginStart" }); + } + addExpose(num) { + if (typeof this.ai.shown == "number" && !this.identityShown && this.ai.shown < 1) { + this.ai.shown += num; + if (this.ai.shown > 0.95) { + this.ai.shown = 0.95; + } + } + return this; + } + equip(card, draw) { + var next = game.createEvent("equip"); + next.card = card; + next.player = this; + if (draw) { + next.draw = true; + } + next.setContent(lib.element.content.equip); + if (get.is.object(next.card) && next.card.cards) next.card = next.card.cards[0]; + next.cards = [next.card]; + next.getd = function (player, key, position) { + if (!position) position = ui.discardPile; + if (!key) key = "cards"; + var cards = [], + event = this; + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.position != position || evt.getParent() != event) return; + if (player && player != evt.player) return; + cards.addArray(evt[key]); + }); + return cards; + }; + next.getl = function (player) { + const that = this; + const map = { + player: player, + hs: [], + es: [], + js: [], + ss: [], + xs: [], + cards: [], + cards2: [], + gaintag_map: {}, + }; + player.checkHistory("lose", function (evt) { + if (evt.parent == that) { + map.hs.addArray(evt.hs); + map.es.addArray(evt.es); + map.js.addArray(evt.js); + map.ss.addArray(evt.ss); + map.xs.addArray(evt.xs); + map.cards.addArray(evt.cards); + map.cards2.addArray(evt.cards2); + for (let key in evt.gaintag_map) { + if (!map.gaintag_map[key]) map.gaintag_map[key] = []; + map.gaintag_map[key].addArray(evt.gaintag_map[key]); + } + } + }); + return map; + }; + return next; + } + addJudge(card, cards) { + var next = game.createEvent("addJudge"); + if (get.itemtype(card) == "card") { + next.card = card; + next.cards = [card]; + } else { + next.cards = cards; + if (get.itemtype(next.cards) == "card") next.cards = [next.cards]; + if (typeof card == "string") { + card = { name: card }; + } + next.card = get.autoViewAs(card, next.cards); + } + next.player = this; + next.setContent("addJudge"); + next.getd = function (player, key, position) { + if (!position) position = ui.discardPile; + if (!key) key = "cards"; + var cards = [], + event = this; + game.checkGlobalHistory("cardMove", function (evt) { + if (evt.name != "lose" || evt.position != position || evt.getParent() != event) return; + if (player && player != evt.player) return; + cards.addArray(evt[key]); + }); + return cards; + }; + next.getl = function (player) { + const that = this; + const map = { + player: player, + hs: [], + es: [], + js: [], + ss: [], + xs: [], + cards: [], + cards2: [], + gaintag_map: {}, + }; + player.checkHistory("lose", function (evt) { + if (evt.parent == that) { + map.hs.addArray(evt.hs); + map.es.addArray(evt.es); + map.js.addArray(evt.js); + map.ss.addArray(evt.ss); + map.xs.addArray(evt.xs); + map.cards.addArray(evt.cards); + map.cards2.addArray(evt.cards2); + for (let key in evt.gaintag_map) { + if (!map.gaintag_map[key]) map.gaintag_map[key] = []; + map.gaintag_map[key].addArray(evt.gaintag_map[key]); + } + } + }); + return map; + }; + return next; + } + /** + * @returns { boolean } + */ + canAddJudge(card) { + if (this.isDisabledJudge()) return false; + let name; + if (typeof card == "string") { + name = card; + } else { + name = card.viewAs || card.name; + } + if (!name) return false; + const cardInfo = lib.card[name]; + if (!cardInfo) return false; + if (!cardInfo.allowDuplicate && this.hasJudge(name)) return false; + if (this.isOut()) return false; + var mod = game.checkMod(card, this, this, "unchanged", "targetEnabled", this); + if (mod != "unchanged") return mod; + return true; + } + addJudgeNext(card, unlimited) { + if (!card.expired) { + let target = this.next; + const name = card.viewAs || card.name; + const cards = get.itemtype(card) == "card" ? [card] : card.cards; + if (get.itemtype(cards) != "cards") return; + let bool = false; + if ( + !unlimited && + cards.some((card) => { + const position = get.position(card, true); + return position != "j" && position != "o"; + }) + ) { + game.log(card, "已被移出处理区,无法置入判定区"); + return; + } + for (let iwhile = 0; iwhile < 20; iwhile++) { + if (target.canAddJudge(card)) { + bool = true; + break; + } + target = target.next; + } + if (bool) { + if (card.cards && card.cards.length) { + target.addJudge(name, card.cards[0]); + } else if (card.name != name) { + target.addJudge(name, card); + } else { + target.addJudge(card); + } + } + } else { + card.expired = false; + } + } + judge() { + var next = game.createEvent("judge"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (get.itemtype(arguments[i]) == "card") { + next.card = arguments[i]; + } else if (typeof arguments[i] == "string") { + next.skill = arguments[i]; + } else if (typeof arguments[i] == "function") { + next.judge = arguments[i]; + } else if (typeof arguments[i] == "boolean") { + next.clearArena = arguments[i]; + } else if (["div", "fragment"].includes(get.objtype(arguments[i]))) { + next.position = arguments[i]; + } + } + if (next.card && next.judge == undefined) { + next.judge = get.judge(next.card); + next.judge2 = get.judge2(next.card); + } + if (next.judge == undefined) + next.judge = function () { + return 0; + }; + if (next.position == undefined) next.position = ui.discardPile; + if (next.card) next.cardname = next.card.viewAs || next.card.name; + + var str = ""; + if (next.card) str = get.translation(next.card.viewAs || next.card.name); + else if (next.skill) str = get.translation(next.skill); + else str = get.translation(_status.event.name); + next.judgestr = str; + next.setContent("judge"); + return next; + } + turnOver(bool) { + var next = game.createEvent("turnOver"); + next.player = this; + next.includeOut = true; + next.setContent("turnOver"); + if (typeof bool == "boolean") { + if (bool) { + if (this.isTurnedOver()) { + _status.event.next.remove(next); + next.resolve(); + } + } else { + if (!this.isTurnedOver()) { + _status.event.next.remove(next); + next.resolve(); + } + } + } + return next; + } + out(skill) { + if (typeof skill == "number") { + this.outCount += skill; + } else if (typeof skill == "string") { + if (!this.outSkills) { + this.outSkills = []; + } + this.outSkills.add(skill); + } else { + this.outCount++; + } + if (!this.classList.contains("out")) { + this.classList.add("out"); + game.log(this, "离开游戏"); + } + if (!game.countPlayer()) { + game.over(); + } + } + in(skill) { + if (this.isOut()) { + if (typeof skill == "string") { + if (this.outSkills) { + this.outSkills.remove(skill); + if (!this.outSkills.length) { + delete this.outSkills; + } + } + } else if (typeof skill == "number") { + this.outCount -= skill; + } else { + if (skill === true) { + delete this.outSkills; + } + this.outCount = 0; + } + if (this.outCount <= 0 && !this.outSkills) { + this.outCount = 0; + this.classList.remove("out"); + game.log(this, "进入游戏"); + } + } + } + link(bool) { + var next = game.createEvent("link"); + next.player = this; + next.setContent("link"); + if (typeof bool == "boolean") { + if (bool) { + if (this.isLinked()) { + _status.event.next.remove(next); + next.resolve(); + } + } else { + if (!this.isLinked()) { + _status.event.next.remove(next); + next.resolve(); + } + } + } + return next; + } + skip(name) { + this.skipList.add(name); + } + wait(callback) { + if (lib.node) { + if (typeof callback == "function") { + callback._noname_waiting = true; + lib.node.torespond[this.playerid] = callback; + } else { + lib.node.torespond[this.playerid] = "_noname_waiting"; + } + clearTimeout(lib.node.torespondtimeout[this.playerid]); + if (this.ws && !this.ws.closed) { + var player = this; + var time = parseInt(lib.configOL.choose_timeout) * 1000; + if (_status.event._global_timer || _status.event.getParent().skillHidden) { + for (var i = 0; i < game.players.length; i++) { + game.players[i].showTimer(time); + } + player._hide_all_timer = true; + } else if (!_status.event._global_waiting && _status.noclearcountdown !== "direct") { + player.showTimer(time); + } + lib.node.torespondtimeout[this.playerid] = setTimeout(function () { + player.unwait("ai"); + player.ws.ws.close(); + }, time + 5000); + } + } + } + unwait(result) { + if (this._hide_all_timer) { + delete this._hide_all_timer; + for (var i = 0; i < game.players.length; i++) { + game.players[i].hideTimer(); + } + } else if ( + !get.event("_global_waiting") && + (_status.noclearcountdown !== "direct" || (result && result.bool)) && + !(result && result._noHidingTimer) + ) { + this.hideTimer(); + } + clearTimeout(lib.node.torespondtimeout[this.playerid]); + delete lib.node.torespondtimeout[this.playerid]; + if (!(this.playerid in lib.node.torespond)) return; + var noresume = false; + var proceed = null; + if ( + typeof lib.node.torespond[this.playerid] == "function" && + lib.node.torespond[this.playerid]._noname_waiting + ) { + proceed = lib.node.torespond[this.playerid](result, this); + if (proceed === false) { + noresume = true; + } + } + lib.node.torespond[this.playerid] = result; + for (var i in lib.node.torespond) { + if (lib.node.torespond[i] == "_noname_waiting") { + return; + } else if (lib.node.torespond[i] && lib.node.torespond[i]._noname_waiting) { + return; + } + } + _status.event.result = result; + _status.event.resultOL = lib.node.torespond; + lib.node.torespond = {}; + if (typeof proceed == "function") proceed(); + else if (_status.paused && !noresume) game.resume(); + } + tempUnwait(result) { + if (!(this.playerid in lib.node.torespond)) return; + var proceed; + if ( + typeof lib.node.torespond[this.playerid] == "function" && + lib.node.torespond[this.playerid]._noname_waiting + ) { + proceed = lib.node.torespond[this.playerid](result, this); + } + if (typeof proceed == "function") proceed(); + } + logSkill(name, targets, nature, logv) { + if (get.itemtype(targets) == "player") targets = [targets]; + var nopop = false; + var popname = name; + if (Array.isArray(name)) { + popname = name[1]; + name = name[0]; + } + var checkShow = this.checkShow(name); + if (lib.translate[name]) { + this.trySkillAnimate(name, popname, checkShow); + if (Array.isArray(targets) && targets.length) { + var str; + if (targets[0] == this) { + str = "#b自己"; + if (targets.length > 1) { + str += "、"; + str += get.translation(targets.slice(1)); + } + } else str = targets; + game.log(this, "对", str, "发动了", "【" + get.skillTranslation(name, this) + "】"); + } else { + game.log(this, "发动了", "【" + get.skillTranslation(name, this) + "】"); + } + } + if (nature != false) { + if (nature === undefined) { + nature = "green"; + } + this.line(targets, nature); + } + var info = lib.skill[name]; + if ( + info && + info.ai && + info.ai.expose != undefined && + this.logAi && + (!targets || targets.length != 1 || targets[0] != this) + ) { + this.logAi(lib.skill[name].ai.expose); + } + if (info && info.round) { + var roundname = name + "_roundcount"; + this.storage[roundname] = game.roundNumber; + this.syncStorage(roundname); + this.markSkill(roundname); + } + game.trySkillAudio(name, this, true); + if (game.chess) { + this.chessFocus(); + } + if (logv === true) { + game.logv(this, name, targets, null, true); + } else if (info && info.logv !== false) { + game.logv(this, name, targets); + } + if (info) { + var player = this; + var players = player.getSkills(false, false, false); + var equips = player.getSkills("e"); + var global = lib.skill.global.slice(0); + var logInfo = { + skill: name, + targets: targets, + event: _status.event, + }; + if (info.sourceSkill) { + logInfo.sourceSkill = info.sourceSkill; + if (global.includes(info.sourceSkill)) { + logInfo.type = "global"; + } else if (players.includes(info.sourceSkill)) { + logInfo.type = "player"; + } else if (equips.includes(info.sourceSkill)) { + logInfo.type = "equip"; + } + } else { + if (global.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "global"; + } else if (players.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "player"; + } else if (equips.includes(name)) { + logInfo.sourceSkill = name; + logInfo.type = "equip"; + } else { + var bool = false; + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + bool = true; + logInfo.sourceSkill = i; + logInfo.type = "player"; + break; + } + } + if (!bool) { + for (var i of players) { + var expand = [i]; + game.expandSkills(expand); + if (expand.includes(name)) { + logInfo.sourceSkill = i; + logInfo.type = "equip"; + break; + } + } + } + } + } + var next = game.createEvent("logSkill", false), + evt = _status.event; + next.player = player; + next.forceDie = true; + next.includeOut = true; + evt.next.remove(next); + if (evt.logSkill) evt = evt.getParent(); + for (var i in logInfo) { + if (i == "event") next.log_event = logInfo[i]; + else next[i] = logInfo[i]; + } + evt.after.push(next); + next.setContent("emptyEvent"); + player.getHistory("useSkill").push(logInfo); + //尽可能别往这写插入结算 + //不能用来终止技能发动!!! + var next2 = game.createEvent("logSkillBegin", false); + next2.player = player; + next2.forceDie = true; + next2.includeOut = true; + for (var i in logInfo) { + if (i == "event") next2.log_event = logInfo[i]; + else next2[i] = logInfo[i]; + } + next2.setContent("emptyEvent"); + } + if (this._hookTrigger) { + for (var i = 0; i < this._hookTrigger.length; i++) { + var info = lib.skill[this._hookTrigger[i]].hookTrigger; + if (info && info.log) { + info.log(this, name, targets); + } + } + } + } + unprompt() { + if (this.node.prompt) { + this.node.prompt.delete(); + delete this.node.prompt; + } + } + prompt(str, nature) { + var node; + if (this.node.prompt) { + node = this.node.prompt; + node.innerHTML = ""; + node.className = "damage normal-font damageadded"; + } else { + node = ui.create.div(".damage.normal-font", this); + this.node.prompt = node; + ui.refresh(node); + node.classList.add("damageadded"); + } + node.innerHTML = str; + node.dataset.nature = nature || "soil"; + } + prompt_old(name2, className) { + var node; + if (this.node.prompt) { + node = this.node.prompt; + node.innerHTML = ""; + node.className = "popup"; + } else { + node = ui.create.div(".popup", this.parentNode); + this.node.prompt = node; + } + node.dataset.position = this.dataset.position; + if ( + this.dataset.position == 0 || + parseInt(this.dataset.position) == parseInt(ui.arena.dataset.number) / 2 || + typeof name2 == "number" || + this.classList.contains("minskin") + ) { + node.innerHTML = name2; + } else { + for (var i = 0; i < name2.length; i++) { + node.innerHTML += name2[i] + "
                                    "; + } + } + if (className) { + node.classList.add(className); + } + } + popup(name, className, nobroadcast) { + var name2 = get.translation(name); + if (!name2) return; + this.$damagepop(name2, className || "water", true, nobroadcast); + } + popup_old(name, className) { + var name2 = get.translation(name); + var node = ui.create.div(".popup", this.parentNode); + if (!name2) { + node.remove(); + return node; + } + game.addVideo("popup", this, [name, className]); + node.dataset.position = this.dataset.position; + if ( + this.dataset.position == 0 || + parseInt(this.dataset.position) == parseInt(ui.arena.dataset.number) / 2 || + typeof name2 == "number" || + this.classList.contains("minskin") + ) { + node.innerHTML = name2; + } else { + for (var i = 0; i < name2.length; i++) { + node.innerHTML += name2[i] + "
                                    "; + } + } + if (className) { + node.classList.add(className); + } + this.popups.push(node); + if (this.popups.length > 1) { + node.hide(); + } else { + var that = this; + setTimeout(function () { + that._popup(); + }, 1000); + } + return node; + } + _popup() { + if (this.popups.length) { + this.popups.shift().delete(); + if (this.popups.length) { + this.popups[0].show(); + var that = this; + setTimeout(function () { + that._popup(); + }, 1000); + } + } + } + showTimer(time) { + if (!time && lib.configOL) { + time = parseInt(lib.configOL.choose_timeout) * 1000; + } + if (_status.connectMode && !game.online) { + game.broadcast( + function (player, time) { + player.showTimer(time); + }, + this, + time + ); + } + if (this == game.me) { + return; + } + if (this.node.timer) { + this.node.timer.remove(); + } + var timer = ui.create.div(".timerbar", this); + this.node.timer = timer; + ui.create.div(this.node.timer); + var bar = ui.create.div(this.node.timer); + ui.refresh(bar); + bar.style.transitionDuration = time / 1000 + "s"; + bar.style.transform = "scale(0,1)"; + } + hideTimer() { + if (_status.connectMode && !game.online && this.playerid) { + game.broadcast(function (player) { + player.hideTimer(); + }, this); + } + if (this.node.timer) { + this.node.timer.delete(); + delete this.node.timer; + } + } + markAuto(name, info) { + if (typeof info != "undefined") { + if (!Array.isArray(this.storage[name])) this.storage[name] = []; + if (Array.isArray(info)) { + this.storage[name].addArray(info); + } else this.storage[name].add(info); + this.markSkill(name); + } else { + var storage = this.storage[name]; + if (Array.isArray(storage)) { + this[storage.length > 0 ? "markSkill" : "unmarkSkill"](name); + } else if (typeof storage == "number") { + this[storage > 0 ? "markSkill" : "unmarkSkill"](name); + } + } + } + unmarkAuto(name, info) { + var storage = this.storage[name]; + if (Array.isArray(info) && Array.isArray(storage)) { + storage.removeArray(info.slice(0)); + this.markAuto(name); + } + } + getExpansions(tag) { + return this.getCards("x", (card) => card.hasGaintag(tag)); + } + countExpansions(tag) { + return this.getExpansions(tag).length; + } + hasExpansions(tag) { + return this.countExpansions(tag) > 0; + } + setStorage(name, value, mark) { + this.storage[name] = value; + if (mark) this.markAuto(name); + return value; + } + getStorage(name, defaultValue = []) { + return this.storage[name] || defaultValue; + } + hasStorage(name, value) { + if (!(name in this.storage)) return false; + if (typeof value == "undefined") return true; + const storage = this.storage[name]; + if (storage === value) return true; + return Array.isArray(storage) && storage.includes(value); + } + hasStorageAny(name, values) { + const storage = this.storage[name]; + if (!Array.isArray(values)) values = Array.from(arguments).slice(1); + if (!storage) return false; + if (!Array.isArray(storage)) return values.includes(storage); + return values.some((item) => storage.includes(item)); + } + hasStorageAll(name, values) { + const storage = this.storage[name]; + if (!Array.isArray(values)) values = Array.from(arguments).slice(1); + if (!storage) return false; + if (!Array.isArray(storage)) return false; + return values.every((item) => storage.includes(item)); + } + initStorage(name, value, mark) { + return this.hasStorage(name) ? this.getStorage(name) : this.setStorage(name, value, mark); + } + updateStorage(name, operation, mark) { + return this.setStorage(name, operation(this.getStorage(name)), mark); + } + updateStorageAsync(name, operation, mark) { + return Promise.resolve(this.getStorage(name)) + .then((value) => operation(value)) + .then((value) => this.setStorage(name, value, mark)); + } + removeStorage(name, mark) { + if (!this.hasStorage(name)) return false; + delete this.storage[name]; + if (mark) { + this.unmarkSkill(name); + } + return true; + } + markSkill(name, info, card, nobroadcast) { + if (info === true) { + this.syncStorage(name); + info = null; + } + if (get.itemtype(card) == "card") { + game.addVideo("markSkill", this, [name, get.cardInfo(card)]); + } else { + game.addVideo("markSkill", this, [name]); + } + const func = function (storage, player, name, info, card) { + player.storage[name] = storage; + if (!info) { + if (player.marks[name]) { + player.updateMarks(); + return; + } + if (lib.skill[name]) { + info = lib.skill[name].intro; + } + if (!info) { + return; + } + } + if (player.marks[name]) { + player.marks[name].info = info; + } else { + if (card) { + player.marks[name] = player.mark(card, info, name); + } else { + player.marks[name] = player.mark(name, info); + } + } + player.updateMarks(); + }; + func(this.storage[name], this, name, info, card); + if (!nobroadcast) game.broadcast(func, this.storage[name], this, name, info, card); + return this; + } + unmarkSkill(name, nobroadcast) { + game.addVideo("unmarkSkill", this, name); + if (!nobroadcast) + game.broadcast( + function (player, name) { + if (player.marks[name]) { + player.marks[name].delete(); + player.marks[name].style.transform += " scale(0.2)"; + delete player.marks[name]; + ui.updatem(player); + } + }, + this, + name + ); + if (this.marks[name]) { + this.marks[name].delete(); + this.marks[name].style.transform += " scale(0.2)"; + delete this.marks[name]; + ui.updatem(this); + var info = lib.skill[name]; + if (!game.online && info && info.intro && info.intro.onunmark) { + if (info.intro.onunmark == "throw") { + if (get.itemtype(this.storage[name]) == "cards") { + this.$throw(this.storage[name], 1000); + game.cardsDiscard(this.storage[name]); + game.log(this.storage[name], "进入了弃牌堆"); + this.storage[name].length = 0; + } + } else if (typeof info.intro.onunmark == "function") { + info.intro.onunmark(this.storage[name], this); + } else delete this.storage[name]; + } + } + return this; + } + markSkillCharacter(id, target, name, content, nobroadcast) { + if (typeof target == "object") { + target = target.name; + } + const func = function (player, target, name, content, id) { + if (player.marks[id]) { + player.marks[id].name = name + "_charactermark"; + player.marks[id]._name = target; + player.marks[id].info = { + name: name, + content: content, + id: id, + }; + player.marks[id].setBackground(target, "character"); + game.addVideo("changeMarkCharacter", player, { + id: id, + name: name, + content: content, + target: target, + }); + } else { + player.marks[id] = player.markCharacter(target, { + name: name, + content: content, + id: id, + }); + player.marks[id]._name = target; + game.addVideo("markCharacter", player, { + name: name, + content: content, + id: id, + target: target, + }); + } + }; + func(this, target, name, content, id); + if (!nobroadcast) game.broadcast(func, this, target, name, content, id); + return this; + } + markCharacter(name, info, learn, learn2) { + if (typeof name == "object") { + name = name.name; + } + var node; + if (name.startsWith("unknown")) { + node = ui.create.div(".card.mark.drawinghidden"); + ui.create.div(".background.skillmark", node).innerHTML = get.translation(name)[0]; + } else { + if (!lib.character[name]) return; + node = ui.create.div(".card.mark.drawinghidden").setBackground(name, "character"); + } + this.node.marks.insertBefore(node, this.node.marks.childNodes[1]); + node.name = name + "_charactermark"; + if (!info) { + info = {}; + } + if (!info.name) { + info.name = get.translation(name); + } + if (!info.content) { + info.content = get.skillintro(name, learn, learn2); + } + node.info = info; + node.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.card); + if (!lib.config.touchscreen) { + if (lib.config.hover_all) { + lib.setHover(node, ui.click.hoverplayer); + } + if (lib.config.right_info) { + node.oncontextmenu = ui.click.rightplayer; + } + } + ui.updatem(this); + return node; + } + mark(name, info, skill) { + if (get.itemtype(name) == "cards") { + var marks = []; + for (var i = 0; i < name.length; i++) { + marks.push(this.mark(name[i], info)); + } + return marks; + } else { + var node; + if (get.itemtype(name) == "card") { + node = name.copy("mark"); + node.classList.add("drawinghidden"); + this.node.marks.insertBefore(node, this.node.marks.childNodes[1]); + node.suit = name.suit; + node.number = name.number; + // if(name.name&&lib.card[name.name]&&lib.card[name.name].markimage){ + // node.node.image.style.left=lib.card[name.name].markimage; + // } + + if (name.classList.contains("fullborder")) { + node.classList.add("fakejudge"); + node.classList.add("fakemark"); + (node.querySelector(".background") || ui.create.div(".background", node)).innerHTML = + lib.translate[name.name + "_bg"] || get.translation(name.name)[0]; + } + + name = name.name; + } else { + node = ui.create.div(".card.mark.drawinghidden"); + this.node.marks.insertBefore(node, this.node.marks.childNodes[1]); + if (lib.skill[name] && lib.skill[name].markimage) { + node.setBackgroundImage(lib.skill[name].markimage); + node.style["box-shadow"] = "none"; + node.style["background-size"] = "contain"; + } else if (lib.skill[name] && lib.skill[name].markimage2) { + let img = ui.create.div(".background.skillmark", node); + img.setBackgroundImage(lib.skill[name].markimage2); + img.style["background-size"] = "contain"; + } else { + var str = lib.translate[name + "_bg"]; + if (!str || str[0] == "+" || str[0] == "-") { + str = get.translation(name)[0]; + } + ui.create.div(".background.skillmark", node).innerHTML = str; + } + } + node.name = name; + node.skill = skill || name; + if (typeof info == "object") { + node.info = info; + } else if (typeof info == "string") { + node.markidentifer = info; + } + node.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.card); + if (!lib.config.touchscreen) { + if (lib.config.hover_all) { + lib.setHover(node, ui.click.hoverplayer); + } + if (lib.config.right_info) { + node.oncontextmenu = ui.click.rightplayer; + } + } + this.updateMarks(); + ui.updatem(this); + return node; + } + } + unmark(name, info) { + game.addVideo("unmarkname", this, name); + if (get.itemtype(name) == "card") { + this.unmark(name.name, info); + } else if (get.itemtype(name) == "cards") { + for (var i = 0; i < name.length; i++) { + this.unmark(name[i].name, info); + } + } else { + for (var i = 0; i < this.node.marks.childNodes.length; i++) { + if ( + this.node.marks.childNodes[i].name == name && + (!info || this.node.marks.childNodes[i].markidentifer == info) + ) { + this.node.marks.childNodes[i].delete(); + this.node.marks.childNodes[i].style.transform += " scale(0.2)"; + ui.updatem(this); + return; + } + } + } + } + addLink() { + if (get.is.linked2(this)) { + this.classList.add("linked2"); + } else { + this.classList.add("linked"); + } + } + removeLink() { + if (get.is.linked2(this)) { + this.classList.remove("linked2"); + } else { + this.classList.remove("linked"); + } + } + canUse(card, target, distance, includecard) { + if (typeof card == "string") card = { name: card, isCard: true }; + var info = get.info(card); + if (info.multicheck && !info.multicheck(card, this)) return false; + if (!lib.filter.cardEnabled(card, this)) return false; + if (includecard) { + let evt = includecard; + if (typeof evt !== "object") evt = _status.event.getParent("chooseToUse"); + if (get.itemtype(evt) !== "event") evt = undefined; + if (!lib.filter.cardUsable(card, this, evt)) return false; + } + if (distance !== false && !lib.filter.targetInRange(card, this, target)) return false; + return lib.filter[includecard ? "targetEnabledx" : "targetEnabled"](card, this, target); + } + hasUseTarget(card, distance, includecard) { + var player = this; + return game.hasPlayer(function (current) { + return player.canUse(card, current, distance, includecard); + }); + } + hasValueTarget(card, distance, includecard) { + if (typeof card == "string") { + card = { name: card, isCard: true }; + } + var player = this; + var targets = game.filterPlayer(); + var value = []; + var min = 0; + var info = get.info(card); + if (!info || info.notarget) return false; + var range; + var select = get.copy(info.selectTarget); + if (select == undefined) { + if (info.filterTarget == undefined) return true; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); + if (!range) return false; + + let cache = CacheContext.requireCacheContext(); + for (var i = 0; i < targets.length; i++) { + if (player.canUse(card, targets[i], distance, includecard)) { + var eff = cache.get.effect(targets[i], card, player, player); + if (range[1] == 1 && eff > 0) { + return true; + } + value.push(eff); + } + } + value.sort(function (a, b) { + return b - a; + }); + for (var i = 0; i < value.length; i++) { + if (i == range[1] || (range[1] != -1 && value[i] <= 0)) break; + min += value[i]; + } + return min > 0; + } + getUseValue(card, distance, includecard) { + if (typeof card == "string") { + card = { name: card, isCard: true }; + } + var player = this; + var targets = game.filterPlayer(); + var value = []; + var min = 0; + var info = get.info(card); + if (!info || info.notarget) return 0; + var range; + var select = get.copy(info.selectTarget); + if (select == undefined) { + if (info.filterTarget == undefined) return 1; + range = [1, 1]; + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, "selectTarget", player); + if (!range) return 0; + + let cache = CacheContext.requireCacheContext(); + for (var i = 0; i < targets.length; i++) { + if (player.canUse(card, targets[i], distance, includecard)) { + var eff = cache.get.effect(targets[i], card, player, player); + value.push(eff); + } + } + value.sort(function (a, b) { + return b - a; + }); + for (var i = 0; i < value.length; i++) { + if (i == range[1] || (range[1] != -1 && value[i] <= 0)) break; + min += value[i]; + } + return min; + } + addSubPlayer(cfg) { + var skill = "subplayer_" + cfg.name + "_" + get.id(); + game.log(this, "获得了随从", "#g" + get.translation(cfg.name)); + cfg.hs = cfg.hs || []; + cfg.es = cfg.es || []; + cfg.skills = cfg.skills || []; + cfg.hp = cfg.hp || 1; + cfg.maxHp = cfg.maxHp || 1; + cfg.sex = cfg.sex || "male"; + cfg.group = cfg.group || "qun"; + cfg.skill = cfg.skill || _status.event.name; + if (!cfg.source) { + if ( + this.hasSkill(_status.event.name) && + this.name2 && + lib.character[this.name2] && + lib.character[this.name2][3].includes(_status.event.name) + ) { + cfg.source = this.name2; + } else { + cfg.source = this.name; + } + } + game.broadcastAll( + function (player, skill, cfg) { + lib.skill[skill] = { + intro: { + content: cfg.intro || "", + }, + mark: "character", + subplayer: cfg.skill, + ai: { + subplayer: true, + }, + }; + lib.character[skill] = [cfg.sex, cfg.group, cfg.maxHp, cfg.skills, []]; + if (Array.isArray(cfg.image)) { + cfg.image.forEach((image) => lib.character[skill][4].push(image)); + } else if (typeof cfg.image == "string") { + lib.character[skill][4].push(cfg.image); + } else { + lib.character[skill][4].push("character:" + cfg.name); + } + lib.translate[skill] = cfg.caption || get.rawName(cfg.name); + player.storage[skill] = cfg; + }, + this, + skill, + cfg + ); + game.addVideo("addSubPlayer", this, [ + skill, + lib.skill[skill], + lib.character[skill], + lib.translate[skill], + { name: cfg.name }, + ]); + this.addSkill(skill); + return skill; + } + removeSubPlayer(name) { + if (this.hasSkill("subplayer") && this.name == name) { + this.exitSubPlayer(true); + } else { + if (player.storage[name].onremove) { + player.storage[name].onremove(player); + } + this.removeSkill(name); + delete this.storage[name]; + game.log(player, "牺牲了随从", "#g" + name); + _status.event.trigger("removeSubPlayer"); + } + } + callSubPlayer() { + if (this.hasSkill("subplayer")) return; + var next = game.createEvent("callSubPlayer"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "string") { + next.directresult = arguments[i]; + } + } + next.setContent("callSubPlayer"); + return next; + } + toggleSubPlayer() { + if (!this.hasSkill("subplayer")) return; + var next = game.createEvent("toggleSubPlayer"); + next.player = this; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] == "string") { + next.directresult = arguments[i]; + } + } + next.setContent("toggleSubPlayer"); + return next; + } + exitSubPlayer(remove) { + var next = game.createEvent("exitSubPlayer"); + next.player = this; + next.remove = remove; + next.setContent("exitSubPlayer"); + if (!this.hasSkill("subplayer")) { + _status.event.next.remove(next); + next.resolve(); + } + return next; + } + getSubPlayers(tag) { + var skills = this.getSkills(); + var list = []; + for (var i = 0; i < skills.length; i++) { + var name = skills[i]; + var info = lib.skill[name]; + if (tag && info.subplayer != tag) continue; + if (info.ai && info.ai.subplayer && this.storage[name] && this.storage[name].name) { + list.push(name); + } + } + return list; + } + addSkillTrigger(skills, hidden, triggeronly) { + if (typeof skills == "string") skills = [skills]; + game.expandSkills(skills); + for (const skill of skills) { + const info = lib.skill[skill]; + if (!info) { + console.error( + new ReferenceError( + `Cannot find ${skill} in lib.skill, failed to add ${skill}'s trigger to ${this.name}` + ) + ); + continue; + } + if (!triggeronly) { + if (info.global && (!hidden || info.globalSilent)) { + let global = info.global; + if (!Array.isArray(global)) global = [global]; + global.forEach((skill) => game.addGlobalSkill(skill, this)); + } + if (this.initedSkills.includes(skill)) continue; + this.initedSkills.push(skill); + if (info.init && !_status.video) info.init(this, skill); + } + if (info.trigger && this.playerid) { + const setTrigger = (role, evt) => { + const name = this.playerid + "_" + role + "_" + evt; + if (!lib.hook[name]) lib.hook[name] = []; + lib.hook[name].add(skill); + lib.hookmap[evt] = true; + }; + for (const role in info.trigger) { + let evts = info.trigger[role]; + if (!Array.isArray(evts)) evts = [evts]; + evts.forEach((evt) => setTrigger(role, evt)); + } + } + if (info.hookTrigger) { + if (!this._hookTrigger) this._hookTrigger = []; + this._hookTrigger.add(skill); + } + if (_status.event && _status.event.addTrigger) _status.event.addTrigger(skill, this); + _status.event.clearStepCache(); + } + return this; + } + addSkillLog(skill) { + if (!skill) return this; + this.addSkill(skill); + if (!Array.isArray(skill)) skill = [skill]; + game.log( + this, + "获得了技能", + ...skill.map((i) => { + this.popup(i); + return "#g【" + get.translation(i) + "】"; + }) + ); + } + removeSkillLog(skill, popup) { + if (!skill) return this; + this.removeSkill(skill); + if (!Array.isArray(skill)) skill = [skill]; + game.log( + this, + "失去了技能", + ...skill.map((i) => { + if (popup === true) this.popup(i); + return "#g【" + get.translation(i) + "】"; + }) + ); + } + addInvisibleSkill(skill) { + if (Array.isArray(skill)) { + _status.event.clearStepCache(); + for (var i = 0; i < skill.length; i++) { + this.addInvisibleSkill(skill[i]); + } + } else { + if (this.invisibleSkills.includes(skill)) return; + _status.event.clearStepCache(); + var info = lib.skill[skill]; + if (!info) return; + this.invisibleSkills.add(skill); + this.addSkillTrigger(skill); + if (this.awakenedSkills.includes(skill)) { + this.awakenSkill(skill); + return; + } + } + } + removeInvisibleSkill(skill) { + if (!skill) return; + if (Array.isArray(skill)) { + for (var i = 0; i < skill.length; i++) { + this.removeSkill(skill[i]); + } + } else { + var info = lib.skill[skill]; + if (info && info.fixed && arguments[1] !== true) return skill; + game.broadcastAll( + function (player, skill) { + player.invisibleSkills.remove(skill); + }, + this, + skill + ); + if (!player.hasSkill(skill, true)) player.removeSkill(skill); + } + return skill; + } + addSkills(skill) { + if (!skill) return; + return this.changeSkills(Array.isArray(skill) ? skill : [skill], []); + } + removeSkills(skill) { + if (!skill) return; + return this.changeSkills([], Array.isArray(skill) ? skill : [skill]); + } + changeSkills(addSkill = [], removeSkill = []) { + if (!Array.isArray(addSkill) || !Array.isArray(removeSkill)) { + console.warn(`警告:Player[${this.name}].changeSkills的参数错误,应当为数组形式。`); + return; + } + const next = game.createEvent("changeSkills", false); + next.player = this; + next.forceDie = true; + next.addSkill = addSkill.slice(0).unique(); + next.removeSkill = removeSkill.slice(0).unique(); + next.setContents("changeSkills"); + return next; + } + addSkill(skill, checkConflict, nobroadcast, addToSkills) { + if (Array.isArray(skill)) { + _status.event.clearStepCache(); + for (var i = 0; i < skill.length; i++) { + this.addSkill(skill[i]); + } + } else { + if (this.skills.includes(skill)) return; + _status.event.clearStepCache(); + var info = lib.skill[skill]; + if (!info) return; + if (!addToSkills) { + this.skills.add(skill); + if (!nobroadcast) { + game.broadcast( + function (player, skill) { + player.skills.add(skill); + }, + this, + skill + ); + } + } + this.addSkillTrigger(skill); + if (this.awakenedSkills.includes(skill)) { + this.awakenSkill(skill); + return; + } + if (info.init2 && !_status.video) { + info.init2(this, skill); + } + if (info.mark) { + if (info.mark == "card" && get.itemtype(this.storage[skill]) == "card") { + this.markSkill(skill, null, this.storage[skill], nobroadcast); + } else if (info.mark == "card" && get.itemtype(this.storage[skill]) == "cards") { + this.markSkill(skill, null, this.storage[skill][0], nobroadcast); + } else if (info.mark == "image") { + this.markSkill( + skill, + null, + ui.create.card(null, "noclick").init([null, null, skill]), + nobroadcast + ); + } else if (info.mark == "character") { + var intro = info.intro.content; + if (typeof intro == "function") { + intro = intro(this.storage[skill], this); + } else if (typeof intro == "string") { + intro = intro.replace(/#/g, this.storage[skill]); + intro = intro.replace(/&/g, get.cnNumber(this.storage[skill])); + intro = intro.replace(/\$/g, get.translation(this.storage[skill])); + } + var caption; + if (typeof info.intro.name == "function") { + caption = info.intro.name(this.storage[skill], this); + } else if (typeof info.intro.name == "string") { + caption = info.name; + } else { + caption = get.translation(skill); + } + this.markSkillCharacter(skill, this.storage[skill], caption, intro, nobroadcast); + } else { + this.markSkill(skill, null, null, nobroadcast); + } + } + } + if (checkConflict) this.checkConflict(); + return skill; + } + addAdditionalSkills(skill, skillsToAdd, keep) { + if (typeof skillsToAdd == "string") skillsToAdd = [skillsToAdd]; + if (!Array.isArray(skillsToAdd)) { + console.warn( + `警告:Player[${this.name}].addAdditionalSkills的参数错误,应当为技能字符串或数组:`, + skillsToAdd + ); + } + const skillsToRemove = []; + //如果不需要保留原本的additionalSkills,则判断要移除的技能,并移除这些技能 + if (!keep) { + skillsToRemove.addArray(this.getRemovableAdditionalSkills(skill)); + } + //创建对应的addSkills的事件 + return this.changeSkills(skillsToAdd, skillsToRemove).set( + "$handle", + function (player, skillsToAdd, skillsToRemove) { + //先失去先前获得的衍生技能 + if (skillsToRemove.length > 0) { + game.log( + player, + "失去了技能", + ...skillsToRemove.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + player.removeSkill(skillsToRemove); + } + //再获得新的衍生技能 + if (skillsToAdd.length > 0) { + game.log( + player, + "获得了技能", + ...skillsToAdd.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + if (!Array.isArray(player.additionalSkills[skill])) player.additionalSkills[skill] = []; + for (var i = 0; i < skillsToAdd.length; i++) { + player.addSkill(skillsToAdd[i], null, true, true); + player.additionalSkills[skill].push(skillsToAdd[i]); + } + player.checkConflict(); + } + _status.event.clearStepCache(); + } + ); + } + addAdditionalSkill(skill, skillsToAdd, keep) { + if (typeof skillsToAdd == "string") skillsToAdd = [skillsToAdd]; + if (!Array.isArray(skillsToAdd)) { + console.warn( + `警告:Player[${this.name}].addAdditionalSkill的参数错误,应当为技能字符串或数组:`, + skillsToAdd + ); + } + const skillsToRemove = []; + //如果不需要保留原本的additionalSkills,则判断要移除的技能,并移除这些技能 + if (!keep) { + skillsToRemove.addArray(this.getRemovableAdditionalSkills(skill)); + } + this.removeSkill(skillsToRemove); + //然后处理获得技能的操作 + if (!Array.isArray(this.additionalSkills[skill])) this.additionalSkills[skill] = []; + for (var i = 0; i < skillsToAdd.length; i++) { + this.addSkill(skillsToAdd[i], null, true, true); + this.additionalSkills[skill].push(skillsToAdd[i]); + } + + this.checkConflict(); + _status.event.clearStepCache(); + return this; + } + $removeAdditionalSkills(skill, target) { + const additionalSkills = this.additionalSkills[skill]; + if (Array.isArray(additionalSkills)) { + if (typeof target === "string") { + if (additionalSkills.includes(target)) { + additionalSkills.remove(target); + if (!additionalSkills.length) { + delete this.additionalSkills[skill]; + } + } + } else { + delete this.additionalSkills[skill]; + } + } + } + getRemovableAdditionalSkills(skill, target) { + const player = this, + removableSkills = []; + if (this.additionalSkills[skill]) { + const additionalSkills = this.additionalSkills[skill]; + const hasAnotherSKill = function (skillkey, skill) { + return ( + player.skills.includes(skill) || + player.tempSkills[skill] || + Object.keys(player.additionalSkills).some((key) => { + 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.includes(target)) { + removableSkills.push(target); + } + } else { + if (Array.isArray(additionalSkills)) { + removableSkills.addArray( + additionalSkills.filter((target) => !hasAnotherSKill(skill, target)) + ); + } + } + } + return removableSkills; + } + removeAdditionalSkill(skill, target) { + const player = this, + skills = this.getRemovableAdditionalSkills(skill, target); + if (skills.length) { + player.removeSkill(skills); + } + player.$removeAdditionalSkills(skill, target); + _status.event.clearStepCache(); + return this; + } + removeAdditionalSkills(skill, target) { + const player = this, + skills = this.getRemovableAdditionalSkills(skill, target); + return player.changeSkills([], skills).set("$handle", function (player, addSkills, removeSkills) { + if (removeSkills.length > 0) { + game.log( + player, + "失去了技能", + ...removeSkills.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + player.removeSkill(removeSkills); + } + player.$removeAdditionalSkills(skill, target); + }); + } + awakenSkill(skill, nounmark) { + if (!nounmark) this.unmarkSkill(skill); + this.disableSkill(skill + "_awake", skill); + this.awakenedSkills.add(skill); + if (this.storage[skill] === false) this.storage[skill] = true; + _status.event.clearStepCache(); + return this; + } + restoreSkill(skill, nomark) { + if (this.storage[skill] === true) this.storage[skill] = false; + this.awakenedSkills.remove(skill); + this.enableSkill(skill + "_awake", skill); + if (!nomark) this.markSkill(skill); + _status.event.clearStepCache(); + return this; + } + disableSkill(skill, skills) { + if (typeof skills == "string") { + if (!this.disabledSkills[skills]) { + this.disabledSkills[skills] = []; + var info = get.info(skills); + if (info.ondisable && info.onremove) { + if (typeof info.onremove == "function") { + info.onremove(this, skill); + } else if (typeof info.onremove == "string") { + if (info.onremove == "storage") { + delete this.storage[skill]; + } else { + var cards = this.storage[skill]; + if (get.itemtype(cards) == "card") { + cards = [cards]; + } + if (get.itemtype(cards) == "cards") { + if (this.onremove == "discard") { + this.$throw(cards); + } + if (this.onremove == "discard" || this.onremove == "lose") { + game.cardsDiscard(cards); + delete this.storage[skill]; + } + } + } + } else if (Array.isArray(info.onremove)) { + for (var i = 0; i < info.onremove.length; i++) { + delete this.storage[info.onremove[i]]; + } + } else if (info.onremove === true) { + delete this.storage[skill]; + } + } + } + this.disabledSkills[skills].add(skill); + var group = lib.skill[skills].group; + if (typeof group == "string" || Array.isArray(group)) { + this.disableSkill(skill, group); + } + } else if (Array.isArray(skills)) { + for (var i = 0; i < skills.length; i++) { + this.disableSkill(skill, skills[i]); + } + } + _status.event.clearStepCache(); + return this; + } + enableSkill(skill) { + for (var i in this.disabledSkills) { + this.disabledSkills[i].remove(skill); + if (this.disabledSkills[i].length == 0) { + delete this.disabledSkills[i]; + } + } + _status.event.clearStepCache(); + return this; + } + checkMarks() { + var skills = this.getSkills(); + game.expandSkills(skills); + for (var i in this.marks) { + if (!skills.includes(i) && !this.marks[i].info.fixed) { + this.unmarkSkill(i); + } + } + return this; + } + addEquipTrigger(card) { + if (card) { + var info = get.info(card); + if (info.skills) { + for (var j = 0; j < info.skills.length; j++) { + this.addSkillTrigger(info.skills[j]); + } + } + } else { + var es = this.getCards("e"); + for (var i = 0; i < es.length; i++) { + this.addEquipTrigger(es[i]); + } + } + _status.event.clearStepCache(); + return this; + } + removeEquipTrigger(card) { + if (card) { + var info = get.info(card); + var skills = this.getSkills(null, false); + if (info.skills) { + for (var j = 0; j < info.skills.length; j++) { + if (skills.includes(info.skills[j])) continue; + this.removeSkillTrigger(info.skills[j]); + } + } + if (info.clearLose && typeof info.onLose == "function") { + var next = game.createEvent("lose_" + card.name); + next.setContent(info.onLose); + next.player = this; + next.card = card; + } + } else { + var es = this.getCards("e"); + for (var i = 0; i < es.length; i++) { + this.removeEquipTrigger(es[i]); + } + } + _status.event.clearStepCache(); + return this; + } + removeSkillTrigger(skills, triggeronly) { + if (typeof skills == "string") skills = [skills]; + game.expandSkills(skills); + for (const skill of skills) { + const info = lib.skill[skill]; + if (!info) { + console.error( + new ReferenceError( + `Cannot find ${skill} in lib.skill, failed to remove ${skill}'s trigger to ${this.name}` + ) + ); + continue; + } + if (!triggeronly) { + if (info.global) { + let global = info.global; + if (!Array.isArray(global)) global = [global]; + global.forEach((skill) => game.removeGlobalSkill(skill, this)); + } + if (!this.initedSkills.includes(skill)) continue; + this.initedSkills.remove(skill); + // if(info.onremove&&!_status.video) info.onremove(this,skill); + } + if (info.trigger && this.playerid) { + const removeTrigger = (role, evt) => { + const name = this.playerid + "_" + role + "_" + evt; + if (!lib.hook[name]) return; + lib.hook[name].remove(skill); + if (lib.hook[name].length == 0) delete lib.hook[name]; + }; + for (const role in info.trigger) { + let evts = info.trigger[role]; + if (!Array.isArray(evts)) evts = [evts]; + evts.forEach((evt) => removeTrigger(role, evt)); + } + } + if (info.hookTrigger && this._hookTrigger) { + this._hookTrigger.remove(skill); + if (!this._hookTrigger.length) delete this._hookTrigger; + } + if (_status.event && _status.event.removeTrigger) _status.event.removeTrigger(skill, this); + _status.event.clearStepCache(); + } + return this; + } + removeSkill(skill) { + if (!skill) return; + _status.event.clearStepCache(); + if (Array.isArray(skill)) { + for (var i = 0; i < skill.length; i++) { + this.removeSkill(skill[i]); + } + } else { + var info = lib.skill[skill]; + if (info && info.fixed && arguments[1] !== true) return skill; + this.unmarkSkill(skill); + game.broadcastAll( + function (player, skill) { + player.skills.remove(skill); + player.hiddenSkills.remove(skill); + player.invisibleSkills.remove(skill); + delete player.tempSkills[skill]; + for (var i in player.additionalSkills) { + player.additionalSkills[i].remove(skill); + } + }, + this, + skill + ); + this.checkConflict(skill); + if (info) { + if (info.onremove) { + if (typeof info.onremove == "function") { + info.onremove(this, skill); + } else if (typeof info.onremove == "string") { + if (info.onremove == "storage") { + delete this.storage[skill]; + } else { + var cards = this.storage[skill]; + if (get.itemtype(cards) == "card") { + cards = [cards]; + } + if (get.itemtype(cards) == "cards") { + if (this.onremove == "discard") { + this.$throw(cards); + } + if (this.onremove == "discard" || this.onremove == "lose") { + game.cardsDiscard(cards); + delete this.storage[skill]; + } + } + } + } else if (Array.isArray(info.onremove)) { + for (var i = 0; i < info.onremove.length; i++) { + delete this.storage[info.onremove[i]]; + } + } else if (info.onremove === true) { + delete this.storage[skill]; + } + } + this.removeSkillTrigger(skill); + if (!info.keepSkill) { + this.removeAdditionalSkills(skill); + } + } + this.enableSkill(skill + "_awake"); + } + return skill; + } + addTempSkills(skillsToAdd, expire) { + //请注意,该方法的底层实现并非tempSkill,而是additionalSkills和player.when! + if (typeof skillsToAdd == "string") skillsToAdd = [skillsToAdd]; + if (!Array.isArray(skillsToAdd) || !skillsToAdd.length) { + console.warn( + `警告:Player[${this.name}].addAdditionalSkills的参数错误,应当为技能字符串或非空数组:`, + skillsToAdd + ); + } + //确定技能要被移除的时机 + if (!expire) expire = { global: ["phaseAfter", "phaseBeforeStart"] }; + else if (typeof expire == "string" || Array.isArray(expire)) expire = { global: expire }; + return this.changeSkills(skillsToAdd, []).set("$handle", function (player, addSkills, removeSkills) { + if (addSkills.length) { + game.log( + player, + "获得了技能", + ...addSkills.map((i) => { + return "#g【" + get.translation(i) + "】"; + }) + ); + let skillName; + //生成该TempSkills对应的ID + do { + skillName = "player_tempSkills_" + Math.random().toString(36).slice(-8); + } while (player.additionalSkills[skillName] != null); + player.addAdditionalSkill(skillName, skillsToAdd); + player + .when(expire, false) + .assign({ + firstDo: true, + priority: Infinity, + }) + .vars({ + skillName, + }) + .then(() => { + player.removeAdditionalSkills(skillName); + }) + .finish(); + } + }); + } + addTempSkill(skill, expire, checkConflict) { + if (Array.isArray(skill)) { + for (var i = 0; i < skill.length; i++) { + this.addTempSkill(skill[i], expire, checkConflict); + } + } else { + if (this.hasSkill(skill) && this.tempSkills[skill] == undefined) return; + this.addSkill(skill, checkConflict, true, true); + + if (!expire) expire = { global: ["phaseAfter", "phaseBeforeStart"] }; + else if (typeof expire == "string" || Array.isArray(expire)) expire = { global: expire }; + this.tempSkills[skill] = expire; + + if (get.objtype(expire) == "object") { + const roles = ["player", "source", "target", "global"]; + for (const i of roles) { + let triggers = expire[i]; + if (!Array.isArray(triggers)) triggers = [triggers]; + triggers.forEach((trigger) => (lib.hookmap[trigger] = true)); + } + } + } + return skill; + } + tempBanSkill(skill, expire, log) { + if (Array.isArray(skill)) { + for (var i = 0; i < skill.length; i++) { + this.tempBanSkill(skill[i], expire, log); + } + } else { + if (this.isTempBanned(skill)) return; + this.setStorage(`temp_ban_${skill}`, true); + + if (log !== false && this.hasSkill(skill)) + game.log(this, "的技能", `#g【${get.translation(skill)}】`, "暂时失效了"); + + if (!expire) expire = { global: ["phaseAfter", "phaseBeforeStart"] }; + else if (typeof expire == "string" || Array.isArray(expire)) expire = { global: expire }; + this.when(expire, false) + .assign({ + firstDo: true, + }) + .vars({ + bannedSkill: skill, + }) + .then(() => { + delete player.storage[`temp_ban_${bannedSkill}`]; + }) + .finish(); + } + return skill; + } + isTempBanned(skill) { + return this.hasStorage(`temp_ban_${skill}`); + } + attitudeTo(target) { + if (typeof get.attitude == "function") return get.attitude(this, target); + return 0; + } + clearSkills(all) { + var list = []; + var exclude = []; + for (var i = 0; i < arguments.length; i++) { + exclude.push(arguments[i]); + } + for (i = 0; i < this.skills.length; i++) { + if (lib.skill[this.skills[i]].superCharlotte) continue; + if (!all && (lib.skill[this.skills[i]].temp || lib.skill[this.skills[i]].charlotte)) continue; + if (!exclude.includes(this.skills[i])) { + list.push(this.skills[i]); + } + } + if (all) { + for (var i in this.additionalSkills) { + this.removeAdditionalSkill(i); + } + } + this[all ? "removeSkill" : "removeSkills"](list); + this.checkConflict(); + this.checkMarks(); + return list; + } + checkConflict(skill) { + if (skill) { + if (this.forbiddenSkills[skill]) { + delete this.forbiddenSkills[skill]; + } else { + for (var i in this.forbiddenSkills) { + if (this.forbiddenSkills[i].includes(skill)) { + this.forbiddenSkills[i].remove(skill); + if (!this.forbiddenSkills[i].length) { + delete this.forbiddenSkills[i]; + } + } + } + } + } else { + this.forbiddenSkills = {}; + var forbid = []; + var getName = function (arr) { + var str = ""; + for (var i = 0; i < arr.length; i++) { + str += arr[i] + "+"; + } + return str.slice(0, str.length - 1); + }; + var forbidlist = lib.config.forbid.concat(lib.config.customforbid); + var skills = this.getSkills(); + for (var i = 0; i < forbidlist.length; i++) { + if ( + lib.config.customforbid.includes(forbidlist[i]) || + !lib.config.forbidlist.includes(getName(forbidlist[i])) + ) { + for (var j = 0; j < forbidlist[i].length; j++) { + if (!skills.includes(forbidlist[i][j])) break; + } + if (j == forbidlist[i].length) { + forbid.push(forbidlist[i]); + } + } + } + for (var i = 0; i < forbid.length; i++) { + if (forbid[i][1] || this.name2) { + this.forbiddenSkills[forbid[i][0]] = this.forbiddenSkills[forbid[i][0]] || []; + if (forbid[i][1]) { + this.forbiddenSkills[forbid[i][0]].add(forbid[i][1]); + } + } + } + } + } + /** + * 快速获取一名角色当前轮次/前X轮次的历史 + * + * 第一个参数填写获取的动作 + * + * 第二个参数填写获取历史的筛选条件 + * + * 第三个参数填写数字(不填默认为0),获取上X轮的历史(X为0则为本轮历史),第四个参数若为true,则获取从上X轮开始至现在 + * + * 第四个参数若为true,则获取从上X轮开始至现在所有符合条件的历史 + * + * 第五个参数填写event,获取此event之前所有符合条件的历史 + * + * @param { string | function | number | boolean | object } map + */ + getRoundHistory(key, filter, num, keep, last) { + if (!num) num = 0; + const player = this; + let evts = [], + history = player.actionHistory; + for (let i = history.length - 1; i >= 0; i--) { + if (keep === true || num == 0) { + let currentHistory = history[i]; + if (key) currentHistory = currentHistory[key]; + if (filter) currentHistory = currentHistory.filter(filter); + evts.addArray(currentHistory.reverse()); + } + if (history[i].isRound) { + if (num > 0) num--; + else break; + } + } + evts.reverse(); + if (last && evts.includes(last)) { + const lastIndex = evts.indexOf(last); + return evts.filter((evt) => evts.indexOf(evt) <= lastIndex); + } + return evts; + } + getHistory(key, filter, last) { + if (!key) return this.actionHistory[this.actionHistory.length - 1]; + if (!filter) return this.actionHistory[this.actionHistory.length - 1][key]; + else { + const history = this.getHistory(key); + if (last) { + const lastIndex = history.indexOf(last); + return history.filter((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }); + } + return history.filter(filter); + } + } + checkHistory(key, filter, last) { + if (!key || !filter) return; + else { + const history = this.getHistory(key); + if (last) { + const lastIndex = history.indexOf(last); + history.forEach((event, index) => { + if (index > lastIndex) return false; + filter(event); + }); + } else { + history.forEach(filter); + } + } + } + hasHistory(key, filter, last) { + const history = this.getHistory(key); + if (!filter || typeof filter != "function") filter = lib.filter.all; + if (last) { + const lastIndex = history.indexOf(last); + return history.some((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }); + } + return history.some(filter); + } + getLastHistory(key, filter, last) { + let history = false; + for (let i = this.actionHistory.length - 1; i >= 0; i--) { + if (this.actionHistory[i].isMe) { + history = this.actionHistory[i]; + break; + } + } + if (!history) return null; + if (!key) return history; + if (!filter) return history[key]; + else { + if (last) { + const lastIndex = history.indexOf(last); + return history.filter((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }); + } + return history.filter(filter); + } + } + checkAllHistory(key, filter, last) { + if (!key || !filter) return; + this.actionHistory.forEach((value) => { + let history = value[key]; + if (last && history.includes(last)) { + const lastIndex = history.indexOf(last); + history.forEach((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }); + } else { + history.forEach(filter); + } + }); + } + getAllHistory(key, filter, last) { + const history = []; + this.actionHistory.forEach((value) => { + if (!key || !value[key]) { + history.push(value); + } else { + history.push(...value[key]); + } + }); + if (filter) { + if (last) { + const lastIndex = history.indexOf(last); + return history.filter((event, index) => { + if (index > lastIndex) return false; + return filter(event); + }); + } + return history.filter(filter); + } + return history; + } + hasAllHistory(key, filter, last) { + return this.actionHistory.some((value) => { + let history = value[key]; + if (last && history.includes(last)) { + const lastIndex = history.indexOf(last); + if ( + history.some(function (event, index) { + if (index > lastIndex) return false; + return filter(event); + }) + ) + return true; + } else { + if (history.some(filter)) return true; + } + return false; + }); + } + getLastUsed(num) { + if (typeof num != "number") num = 0; + var history = this.getHistory("useCard"); + if (history.length <= num) return null; + return history[history.length - num - 1]; + } + getStat(key) { + if (!key) return this.stat[this.stat.length - 1]; + return this.stat[this.stat.length - 1][key]; + } + getLastStat(key) { + var stat = false; + for (var i = this.stat.length - 1; i >= 0; i--) { + if (this.stat[i].isMe) { + stat = this.stat[i]; + break; + } + } + if (!stat) return null; + if (!key) return stat; + return stat[key]; + } + queue(time) { + if (time == false) { + clearTimeout(this.queueTimeout); + this.queueCount = 0; + return; + } + if (time == undefined) time = 500; + var player = this; + player.queueCount++; + this.queueTimeout = setTimeout(function () { + player.queueCount--; + if (player.queueCount == 0) { + player.style.transform = ""; + player.node.avatar.style.transform = ""; + player.node.avatar2.style.transform = ""; + if (game.chess) { + ui.placeChess(player, player.dataset.position); + } + if (player == game.me) ui.me.removeAttribute("style"); + } + }, time); + } + getCardUsable(card, pure) { + var player = this; + if (typeof card == "string") { + card = { name: card }; + } + card = get.autoViewAs(card); + var num = get.info(card).usable; + if (typeof num == "function") num = num(card, player); + num = game.checkMod(card, player, num, "cardUsable", player); + if (typeof num != "number") return Infinity; + if (!pure && _status.currentPhase == player) { + return num - player.countUsed(card); + } + return num; + } + getAttackRange(raw) { + const player = this; + let range = 0; + if (raw) { + range = game.checkMod(player, player, range, "globalFrom", player); + range = game.checkMod(player, player, range, "attackFrom", player); + const equips = player.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + equips.forEach((card) => { + const info = get.info(card, false).distance; + if (info && info.globalFrom) { + range += info.globalFrom; + } + }); + return player.getEquipRange() - range; + } + let base = game.checkMod(player, "unchanged", "attackRangeBase", player); + if (base != "unchanged") { + range = base; + } else { + range = player.getEquipRange(); + } + range = game.checkMod(player, range, "attackRange", player); + return range; + } + getEquipRange(cards) { + const player = this; + if (!cards) + cards = player.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + const range = cards.reduce((range, card) => { + let newRange = false; + const info = get.info(card, false); + if (info.distance) { + //如果存在attackRange 则通过attackRange动态获取攻击范围 + if (typeof info.distance.attackRange == "function") { + newRange = info.distance.attackRange(card, player); + } + //否则采用祖宗之法 + else if (typeof info.distance.attackFrom == "number") { + newRange = 1 - info.distance.attackFrom; + } + } + let isN1 = typeof range == "number"; + let isN2 = typeof newRange == "number"; + if (isN1 && isN2) return Math.max(range, newRange); + else return isN1 ? range : newRange; + }, false); + return typeof range == "number" ? range : 1; + } + getGlobalFrom() { + var player = this; + var range = 0; + range = game.checkMod(player, player, range, "globalFrom", player); + var equips = player.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + for (var i = 0; i < equips.length; i++) { + var info = get.info(equips[i]).distance; + if (!info) continue; + if (info.globalFrom) { + range += info.globalFrom; + } + } + return -range; + } + getGlobalTo() { + var player = this; + var range = 0; + range = game.checkMod(player, player, range, "globalTo", player); + var equips = player.getCards("e", function (card) { + return !ui.selected.cards || !ui.selected.cards.includes(card); + }); + for (var i = 0; i < equips.length; i++) { + var info = get.info(equips[i]).distance; + if (!info) continue; + if (info.globalTo) { + range += info.globalTo; + } + } + return range; + } + getHandcardLimit() { + var num = Math.max(this.hp, 0); + num = game.checkMod(this, num, "maxHandcardBase", this); + num = game.checkMod(this, num, "maxHandcard", this); + num = game.checkMod(this, num, "maxHandcardFinal", this); + return Math.max(0, num); + } + getEnemies(func) { + var player = this; + var targets; + var mode = get.mode(); + if (mode == "identity") { + if (_status.mode == "purple") { + switch (player.identity) { + case "bZhu": + case "bZhong": + case "rNei": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["rZhu", "rZhong", "bNei"].includes(target.identity); + }); + break; + case "rZhu": + case "rZhong": + case "bNei": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["bZhu", "bZhong", "rNei"].includes(target.identity); + }); + break; + case "rYe": + case "bYe": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return !["rYe", "bYe"].includes(target.identity); + }); + break; + } + } else { + var num = get.population("fan"); + switch (player.identity) { + case "zhu": + case "zhong": + case "mingzhong": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + if (num >= 3) return target.identity == "fan"; + return target.identity == "nei" || target.identity == "fan"; + }); + break; + case "nei": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + if (num >= 3) return target.identity == "fan"; + if (game.players.length == 2) return target != player; + return ( + target.identity == "zhong" || + target.identity == "mingzhong" || + target.identity == "fan" + ); + }); + break; + case "fan": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity != "fan"; + }); + break; + case "commoner": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + if (num >= 3) return target.identity != "fan"; + return target.identity == "fan"; + }); + break; + } + } + } else if (mode == "guozhan") { + if (player.identity == "ye") { + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return true; + }); + } else { + var group = lib.character[player.name1][1]; + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity == "ye" || lib.character[target.name1][1] != group; + }); + } + } else if (mode == "doudizhu") { + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity != player.identity; + }); + } else { + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.side != player.side; + }); + } + targets.remove(player); + return targets; + } + getFriends(func) { + var player = this; + var targets = []; + var mode = get.mode(); + var self = false; + if (func === true) { + func = null; + self = true; + } + if (mode == "identity") { + if (_status.mode == "purple") { + switch (player.identity) { + case "rZhu": + case "rZhong": + case "bNei": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["rZhu", "rZhong", "bNei"].includes(target.identity); + }); + break; + case "bZhu": + case "bZhong": + case "rNei": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["bZhu", "bZhong", "rNei"].includes(target.identity); + }); + break; + case "rYe": + case "bYe": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["rYe", "bYe"].includes(target.identity); + }); + break; + } + } else { + switch (player.identity) { + case "zhu": + case "zhong": + case "mingzhong": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return ["zhu", "zhong", "mingzhong"].includes(target.identity); + }); + break; + case "nei": + targets = []; + break; + case "fan": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity == "fan"; + }); + break; + case "commoner": + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return true; + }); + break; + } + } + } else if (mode == "guozhan") { + if (player.identity == "ye") { + targets = []; + } else { + var group = lib.character[player.name1][1]; + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity != "ye" && lib.character[target.name1][1] == group; + }); + } + } else if (mode == "doudizhu") { + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.identity == player.identity; + }); + } else { + targets = game.filterPlayer(function (target) { + if (func && !func(target)) return false; + return target.side == player.side; + }); + } + if (self) { + targets.add(player); + } else { + targets.remove(player); + } + return targets; + } + isEnemyOf() { + return !this.isFriendOf.call(this, ...arguments); + } + isFriendOf(player) { + if (get.mode() == "guozhan") { + if (this == player) return true; + if ( + this.getStorage("yexinjia_friend").includes(player) || + player.getStorage("yexinjia_friend").includes(this) + ) + return true; + if (this.identity == "unknown" || this.identity == "ye") return false; + if (player.identity == "unknown" || player.identity == "ye") return false; + return this.identity == player.identity; + } + if (get.mode() == "doudizhu") { + return this.identity == player.identity; + } + if (this.side != undefined && typeof player.side == "boolean") { + return this.side == player.side; + } + return this == player; + } + isFriendsOf(player) { + return player.getFriends(true).includes(this); + } + isEnemiesOf(player) { + return player.getEnemies().includes(this); + } + isAlive() { + return this.classList.contains("dead") == false; + } + isDead() { + return this.classList.contains("dead"); + } + isDying() { + return _status.dying.includes(this) && this.hp <= 0 && this.isAlive(); + } + isDamaged() { + return this.hp < this.maxHp && !this.storage.nohp; + } + isHealthy() { + return this.hp >= this.maxHp || this.storage.nohp; + } + isMaxHp(only, raw) { + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only ? value.getHp(raw) < this.getHp(raw) : value.getHp(raw) <= this.getHp(raw); + }); + } + isMinHp(only, raw) { + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only ? value.getHp(raw) > this.getHp(raw) : value.getHp(raw) >= this.getHp(raw); + }); + } + isMaxCard(only) { + const numberOfCards = this.countCards("he"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only ? value.countCards("he") < numberOfCards : value.countCards("he") <= numberOfCards; + }); + } + isMinCard(only) { + const numberOfCards = this.countCards("he"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only ? value.countCards("he") > numberOfCards : value.countCards("he") >= numberOfCards; + }); + } + isMaxHandcard(only) { + const numberOfHandCards = this.countCards("h"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only + ? value.countCards("h") < numberOfHandCards + : value.countCards("h") <= numberOfHandCards; + }); + } + isMinHandcard(only) { + const numberOfHandCards = this.countCards("h"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only + ? value.countCards("h") > numberOfHandCards + : value.countCards("h") >= numberOfHandCards; + }); + } + isMaxEquip(only) { + const numberOfEquipAreaCards = this.countCards("e"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only + ? value.countCards("e") < numberOfEquipAreaCards + : value.countCards("e") <= numberOfEquipAreaCards; + }); + } + isMinEquip(only) { + const numberOfEquipAreaCards = this.countCards("e"); + return game.players.every((value) => { + if (value.isOut() || value == this) return true; + return only + ? value.countCards("e") > numberOfEquipAreaCards + : value.countCards("e") >= numberOfEquipAreaCards; + }); + } + isLinked() { + if (get.is.linked2(this)) { + return this.classList.contains("linked2"); + } + return this.classList.contains("linked"); + } + isTurnedOver() { + return this.classList.contains("turnedover"); + } + isOut() { + return this.classList.contains("out"); + } + isMin(distance) { + if (distance && lib.config.mode != "stone") return false; + if (this.forcemin) return true; + return this.classList.contains("minskin") && !game.chess; + } + isIn() { + return ( + this.classList.contains("dead") == false && + this.classList.contains("out") == false && + !this.removed + ); + } + isUnseen(num) { + switch (num) { + case 0: + return this.classList.contains("unseen"); + case 1: + return this.classList.contains("unseen2"); + case 2: + return this.classList.contains("unseen") || this.classList.contains("unseen2"); + default: + return ( + this.classList.contains("unseen") && (!this.name2 || this.classList.contains("unseen2")) + ); + } + } + isUnderControl(self, me) { + me = me || game.me; + var that = this._trueMe || this; + if (that.isMad() || game.notMe) return false; + if (this === me) { + if (self) return true; + return false; + } + if (that === me || this == me._trueMe) return true; + if (_status.connectMode) return false; + if (lib.config.mode == "versus") { + if (_status.mode == "three") return this.side == me.side; + if (_status.mode == "standard") return lib.storage.single_control && this.side == me.side; + if (_status.mode == "four") return get.config("four_phaseswap") && this.side == me.side; + if (_status.mode == "two") return get.config("two_phaseswap") && this.side == me.side; + return false; + } else if (lib.config.mode == "boss") { + if (me.side) return false; + return this.side == me.side && get.config("single_control"); + } else if (game.chess) { + if (lib.config.mode == "chess") { + if (_status.mode == "combat" && !get.config("single_control")) return false; + } + return this.side == me.side; + } + return false; + } + isOnline() { + if (this.ws && lib.node && !this.ws.closed && this.ws.inited && !this.isAuto) { + return true; + } + return false; + } + isOnline2() { + if (this.ws && lib.node && !this.ws.closed) { + return true; + } + return false; + } + isOffline() { + if (this.ws && lib.node && this.ws.closed) { + return true; + } + return false; + } + checkShow(skill, showonly) { + var sourceSkill = get.info(skill); + var noshow = false; + if (sourceSkill && sourceSkill.sourceSkill) { + skill = sourceSkill.sourceSkill; + } + if (lib.skill.global.includes(skill)) return false; + if (get.mode() != "guozhan" || game.expandSkills(this.getSkills()).includes(skill)) { + if (showonly) { + return false; + } else { + noshow = true; + } + } + var unseen0 = this.isUnseen(0); + var name1 = this.name1 || this.name; + if (lib.character[name1] && (!showonly || unseen0)) { + var skills = game.expandSkills(lib.character[name1][3].slice(0)); + if (skills.includes(skill)) { + if (!noshow && this.isUnseen(0)) this.showCharacter(0); + return "main"; + } + } + var unseen1 = this.isUnseen(1); + var name2 = this.name2; + if (lib.character[name2] && (!showonly || unseen1)) { + var skills = game.expandSkills(lib.character[name2][3].slice(0)); + if (skills.includes(skill)) { + if (!noshow && this.isUnseen(1)) this.showCharacter(1); + return "vice"; + } + } + return false; + } + needsToDiscard(add, filter, pure) { + /** + * add: (逻辑上)同时考虑“获得”的这张/些牌 + * filter(function): 代替默认策略进行筛选 + * pure: 返回值可以为负数 + */ + let cards = this.getCards("h"), + num = 0; + if (typeof add === "number") num = add; + else if (get.itemtype(add) === "cards") + for (let i of add) { + cards.push(add); + } + else if (get.itemtype(add) === "card") cards.push(add); + if (typeof filter !== "function") filter = (card, player) => !player.canIgnoreHandcard(card); + cards = cards.filter((card) => { + return filter(card, this, cards); + }); + num += cards.length - this.getHandcardLimit(); + if (pure) return num; + return Math.max(0, num); + } + distanceTo(target, method) { + return get.distance(this, target, method); + } + distanceFrom(target, method) { + return get.distance(target, this, method); + } + hasSkill(skill, arg2, arg3, arg4) { + return game.expandSkills(this.getSkills(arg2, arg3, arg4)).includes(skill); + } + hasStockSkill(skill, arg1, arg2, arg3) { + return game.expandSkills(this.getStockSkills(arg1, arg2, arg3)).includes(skill); + } + isZhu2() { + var player = this, + mode = get.mode(); + if (!this.isZhu) return false; + if (mode == "identity") { + if (_status.mode == "stratagem" && !this.identityShown) return false; + return true; + } + if (mode == "versus" && (_status.mode == "four" || _status.mode == "guandu")) return true; + return false; + } + isInitFilter(tag) { + const player = this; + for (const name of [player.name, player.name1, player.name2]) { + if (name && lib.character[name]) { + const filter = get.characterInitFilter(name); + if (!filter.includes(tag)) continue; + if (lib.characterInitFilter[name] && lib.characterInitFilter[name](tag) === false) continue; + return true; + } + } + return false; + } + hasZhuSkill(skill, player) { + if (!this.hasSkill(skill)) return false; + if (player) { + var mode = get.mode(); + if (mode == "identity" && _status.mode == "purple") { + if (this.identity.slice(0, 1) != player.identity.slice(0, 1)) return false; + } + if (mode == "versus" && (_status.mode == "four" || _status.mode == "guandu")) { + if (this.side != player.side) return false; + } + } + return true; + } + hasGlobalTag(tag, arg) { + var skills = lib.skill.global.slice(0); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.ai) { + if ( + info.ai.skillTagFilter && + info.ai[tag] && + info.ai.skillTagFilter(this, tag, arg) === false + ) + continue; + if (typeof info.ai[tag] == "string") { + if (info.ai[tag] == arg) return true; + } else if (info.ai[tag]) { + return true; + } + } + } + return false; + } + hasSkillTag(tag, hidden, arg, globalskill) { + var skills = this.getSkills(hidden); + if (globalskill) { + skills.addArray(lib.skill.global); + } + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var info = lib.skill[skills[i]]; + if (info && info.ai) { + if ( + info.ai.skillTagFilter && + info.ai[tag] && + info.ai.skillTagFilter(this, tag, arg) === false + ) + continue; + if (typeof info.ai[tag] == "string") { + if (info.ai[tag] == arg) return true; + } else if (info.ai[tag]) { + return true; + } + } + } + return false; + } + hasJudge(name) { + if (name && typeof name == "object") { + name = name.viewAs || name.name; + } + var judges = this.getCards("j"); + for (var i = 0; i < judges.length; i++) { + if ((judges[i].viewAs || judges[i].name) == name) { + return true; + } + } + return false; + } + hasFriend() { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].isOut()) continue; + if (game.players[i] != this && get.attitude(game.players[i], this) > 0) { + return true; + } + } + return false; + } + hasUnknown(num) { + var mode = get.mode(); + if (typeof num != "number") { + num = 0; + } + if (mode == "identity" || mode == "guozhan") { + for (var i = 0; i < game.players.length; i++) { + if (game.players[i].ai.shown == 0 && game.players[i] != this) { + num--; + if (num <= 0) { + return true; + } + } + } + } + return false; + } + isUnknown(player) { + var mode = get.mode(); + if (mode == "identity" || mode == "guozhan") { + if (this.ai.shown == 0 && this != player) { + return true; + } + } + return false; + } + hasWuxie(info) { + if (this.countCards("hs", "wuxie")) return true; + var skills = this.getSkills("invisible").concat(lib.skill.global); + game.expandSkills(skills); + for (var i = 0; i < skills.length; i++) { + var ifo = get.info(skills[i]); + if (ifo.hiddenWuxie && info) { + if (typeof ifo.hiddenWuxie == "function" && ifo.hiddenWuxie(this, info)) { + return true; + } + } else if (ifo.viewAs && typeof ifo.viewAs != "function" && ifo.viewAs.name == "wuxie") { + if (!ifo.viewAsFilter || ifo.viewAsFilter(this)) { + return true; + } + } else { + var hiddenCard = ifo.hiddenCard; + if (typeof hiddenCard == "function" && hiddenCard(this, "wuxie")) { + return true; + } + } + } + return false; + } + hasSha(respond, noauto) { + if (this.countCards("hs", "sha")) return true; + if (this.countCards("hs", "hufu")) return true; + if (!noauto && this.countCards("hs", "yuchanqian")) return true; + let tag = respond; + if (typeof tag !== "string") tag = respond ? "respond" : "use"; + if (this.hasSkillTag("respondSha", true, tag, true)) return true; + if (typeof respond !== "string") respond = respond ? "respond" : "all"; + return this.hasUsableCard("sha", respond); + } + hasShan(respond) { + if (this.countCards("hs", "shan")) return true; + if (this.countCards("hs", "hufu")) return true; + let tag = respond; + if (typeof tag !== "string") tag = respond ? "respond" : "use"; + if (this.hasSkillTag("respondShan", true, tag, true)) return true; + if (typeof respond !== "string") respond = respond ? "respond" : "all"; + return this.hasUsableCard("shan", respond); + } + mayHaveSha(viewer, type, ignore, rvt) { + /** + * type: skill tag type 'use', 'respond' + * ignore: ignore cards, ui.selected.cards added + * rvt: return value type 'count', 'odds', 'bool'(default) + */ + let count = 0; + if ( + (this.hp > 2 || (!this.isZhu && this.hp > 1)) && + this.hasSkillTag("respondSha", true, type, true) + ) { + if (rvt === "count") count++; + else if (rvt === "odds") return 1; + else return true; + } + if (get.itemtype(viewer) !== "player") viewer = _status.event.player; + let cards, + selected = []; + if (get.itemtype(ignore) === "cards") selected.addArray(ignore); + else if (get.itemtype(ignore) === "card") selected.add(ignore); + if (this === viewer || get.itemtype(viewer) == "player") cards = this.getKnownCards(viewer); + else cards = this.getShownCards(); + count += cards.filter((card) => { + if (selected.includes(card)) return false; + let name = get.name(card, this); + if (name == "sha" || name == "hufu" || name == "yuchanqian") { + if (type === "use") return lib.filter.cardEnabled(card, this); + if (type === "respond") return lib.filter.cardRespondable(card, this); + return true; + } + return false; + }).length; + if (count && rvt !== "count") return rvt === "odds" ? 1 : true; + let hs = this.getCards("hs").filter((i) => !cards.includes(i)).length; + if (!hs) { + if (rvt === "count") return count; + else if (rvt === "odds") return 0; + return false; + } + if (rvt === "count") { + if (this.isPhaseUsing()) return count + hs / 4; + return count + hs / 4.8; + } + if (hs > 9 || this.isPhaseUsing()) count += Math.pow(2 + hs, 2) / 40; + else count += -1.5 * Math.log(1 - hs / 10); + if (rvt === "odds") return Math.min(1, count); + return count > _status.event.getRand("mayHaveSha" + hs + this.playerid); + } + mayHaveShan(viewer, type, ignore, rvt) { + /** + * type: skill tag type 'use', 'respond' or object + * ignore: ignore cards, ui.selected.cards added + * rvt: return value type 'count', 'odds', 'bool'(default) + */ + let count = 0; + if ( + (this.hp > 2 || (!this.isZhu && this.hp > 1)) && + this.hasSkillTag("respondShan", true, type, true) + ) { + if (rvt === "count") count++; + else if (rvt === "odds") return 1; + else return true; + } + if (get.itemtype(viewer) !== "player") viewer = _status.event.player; + let cards, + selected = []; + if (get.itemtype(ignore) === "cards") selected.addArray(ignore); + else if (get.itemtype(ignore) === "card") selected.add(ignore); + if (this === viewer || get.itemtype(viewer) == "player") cards = this.getKnownCards(viewer); + else cards = this.getShownCards(); + count += cards.filter((card) => { + if (selected.includes(card)) return false; + let name = get.name(card, this); + if (name === "shan" || name === "hufu") { + if (type === "use") return lib.filter.cardEnabled(card, this, "forceEnable"); + if (type === "respond") return lib.filter.cardRespondable(card, this); + return true; + } + return false; + }).length; + if (count && rvt !== "count") return rvt === "odds" ? 1 : true; + let hs = this.getCards("hs").filter((i) => !cards.includes(i)).length; + if (!hs) { + if (rvt === "count") return count; + else if (rvt === "odds") return 0; + return false; + } + if (rvt === "count") { + if (this.isPhaseUsing()) return count + hs / 6; + return count + hs / 3.5; + } + if (this.isPhaseUsing()) count += -1.5 * Math.log(1 - hs / 10); + else count += (2 * hs) / (5 + hs); + if (rvt === "odds") return Math.min(1, count); + return count > _status.event.getRand("mayHaveShan" + hs + this.playerid); + } + hasCard(name, position) { + if (typeof name == "function") { + for (let card of this.iterableGetCards(position, name)) { + return true; + } + } else { + if (this.countCards(position, name)) return true; + } + return false; + } + getEquip(name) { + var es = this.getCards("e"); + if (typeof name == "object" && get.info(name)) { + name = get.info(name).subtype; + if (name) { + name = parseInt(name[5]); + } + } else if (typeof name == "string" && name.startsWith("equip") && name.length == 6) { + name = parseInt(name[5]); + } + if (!name) { + return null; + } + for (var i = 0; i < es.length; i++) { + if (typeof name === "number") { + if (get.info(es[i]).subtype === "equip" + name) { + return es[i]; + } + } else { + if (es[i].name === name) return es[i]; + var source = get.info(es[i]).source; + if (Array.isArray(source) && source.includes(name)) { + return es[i]; + } + } + } + return null; + } + getJudge(name) { + var judges = this.node.judges.childNodes; + for (var i = 0; i < judges.length; i++) { + if (judges[i].classList.contains("removing")) continue; + if ((judges[i].viewAs || judges[i].name) == name) { + return judges[i]; + } + } + return null; + } + $drawAuto(cards, target) { + if (this.isUnderControl(true, target)) { + this.$draw(cards); + } else { + this.$draw(cards.length); + } + } + $draw(num, init, config) { + if (init !== false && init !== "nobroadcast") { + game.broadcast( + function (player, num, init, config) { + player.$draw(num, init, config); + }, + this, + num, + init, + config + ); + } + var cards, node; + if (get.itemtype(num) == "cards") { + cards = num; + num = cards.length; + } else if (get.itemtype(num) == "card") { + cards = [num]; + num = 1; + } + if (init !== false) { + if (cards) { + game.addVideo("drawCard", this, get.cardsInfo(cards)); + } else { + game.addVideo("draw", this, num); + } + } + if (cards) { + cards = cards.slice(0); + node = cards.shift().copy("thrown", "drawingcard"); + } else { + node = ui.create.div(".card.thrown.drawingcard"); + } + node.fixed = true; + node.hide(); + + var dx, dy; + if (game.chess) { + var rect = this.getBoundingClientRect(); + + if (rect.left <= 80) { + dx = -10; + if (rect.top <= 80) { + dy = -10; + } else if (rect.top + rect.height + 80 >= ui.chessContainer.offsetHeight) { + dy = 10; + } else { + dy = 0; + } + } else if (rect.left + rect.width + 80 >= ui.chessContainer.offsetWidth) { + dx = 10; + if (rect.top <= 80) { + dy = -10; + } else if (rect.top + rect.height + 80 >= ui.chessContainer.offsetHeight) { + dy = 10; + } else { + dy = 0; + } + } else if (rect.top <= 80) { + dx = 0; + dy = -10; + } else if (rect.top + rect.height + 80 >= ui.chessContainer.offsetHeight) { + dx = 0; + dy = 10; + } else { + dx = rect.left + this.offsetWidth / 2 - ui.arena.offsetWidth / 2; + dy = rect.top + this.offsetHeight / 2 - ui.arena.offsetHeight / 2; + } + + var coeff = 240 / Math.sqrt(dx * dx + dy * dy); + dx *= coeff; + dy *= coeff; + + node.style.left = this.getLeft() + this.offsetWidth / 2 - 52 - dx + "px"; + node.style.top = this.getTop() + this.offsetHeight / 2 - 52 - dy + "px"; + this.parentNode.appendChild(node); + } else { + this.parentNode.appendChild(node); + node.style.left = "calc(50% - 52px)"; + node.style.top = "calc(50% - 52px)"; + + dx = this.getLeft() + this.offsetWidth / 2 - 52 - node.offsetLeft; + dy = this.getTop() + this.offsetHeight / 2 - 52 - node.offsetTop; + + if (get.is.mobileMe(this)) { + dx += get.cardOffset(); + if (ui.arena.classList.contains("oblongcard")) { + dy -= 16; + } + } + } + node.style.transitionDuration = "0.8s"; + ui.refresh(node); + if (typeof num == "number" && init !== false) { + config = { + total: num, + current: 1, + }; + } + if (config && config.total > 1) { + var total = config.total, + current = config.current; + var dxtotal; + if (total <= 5) { + dxtotal = Math.min(80, (total - 1) * 20); + dx += -dxtotal + (2 * dxtotal * (current - 1)) / (total - 1); + } else { + var total2 = Math.floor(total / 2); + if (current <= total2) { + total = total2; + dy -= 20; + } else { + current -= total2; + total -= total2; + dy += 20; + } + dxtotal = Math.min(80, (total - 1) * 20); + dx += -dxtotal + (2 * dxtotal * (current - 1)) / (total - 1); + } + config.current++; + } + if ( + node.style.transform && + node.style.transform != "none" && + node.style.transform.indexOf("translate") == -1 + ) { + node.style.transform += " translate(" + dx + "px," + dy + "px)"; + } else { + node.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + node.show(); + + node.listenTransition(function () { + node.style.transitionDuration = "0.5s"; + ui.refresh(node); + node.delete(); + }); + var that = this; + if (num && num > 1) { + if (config && config.total > 1) { + setTimeout(function () { + if (cards) { + that.$draw(cards, false, config); + } else { + that.$draw(num - 1, false, config); + } + }, 50); + } else { + setTimeout(function () { + if (cards) { + that.$draw(cards, false, config); + } else { + that.$draw(num - 1, false, config); + } + }, 200); + } + } + } + $compareMultiple(card1, targets, cards) { + game.broadcast( + function (player, card1, targets, cards) { + player.$compareMultiple(card1, targets, cards); + }, + this, + card1, + targets, + cards + ); + game.addVideo("compareMultiple", this, [ + get.cardInfo(card1), + get.targetsInfo(targets), + get.cardsInfo(cards), + ]); + var player = this; + var node1 = player.$throwxy2( + card1, + "calc(50% - 52px)", + "calc(50% + 10px)", + "perspective(600px) rotateY(180deg)", + true + ); + if (lib.config.cardback_style != "default") { + node1.style.transitionProperty = "none"; + ui.refresh(node1); + node1.classList.add("infohidden"); + ui.refresh(node1); + node1.style.transitionProperty = ""; + } else { + node1.classList.add("infohidden"); + } + + node1.style.transform = "perspective(600px) rotateY(180deg) translateX(0)"; + var onEnd01 = function () { + //node1.removeEventListener('webkitTransitionEnd',onEnd01); + setTimeout(function () { + node1.style.transition = "all ease-in 0.3s"; + node1.style.transform = "perspective(600px) rotateY(270deg) translateX(52px)"; + var onEnd = function () { + node1.classList.remove("infohidden"); + node1.style.transition = "all 0s"; + ui.refresh(node1); + node1.style.transform = "perspective(600px) rotateY(-90deg) translateX(52px)"; + ui.refresh(node1); + node1.style.transition = ""; + ui.refresh(node1); + node1.style.transform = ""; + //node1.removeEventListener('webkitTransitionEnd',onEnd); + }; + node1.listenTransition(onEnd); + }, 300); + }; + node1.listenTransition(onEnd01); + + setTimeout(function () { + var left0 = -targets.length * 52 - (targets.length - 1) * 8; + for (var i = 0; i < targets.length; i++) { + (function (target, card2, i) { + var left = left0 + i * 120; + var node2; + if (left < 0) { + node2 = target.$throwxy2( + card2, + "calc(50% - " + -left + "px)", + "calc(50% - 114px)", + "perspective(600px) rotateY(180deg)", + true + ); + } else { + node2 = target.$throwxy2( + card2, + "calc(50% + " + left + "px)", + "calc(50% - 114px)", + "perspective(600px) rotateY(180deg)", + true + ); + } + if (lib.config.cardback_style != "default") { + node2.style.transitionProperty = "none"; + ui.refresh(node2); + node2.classList.add("infohidden"); + ui.refresh(node2); + node2.style.transitionProperty = ""; + } else { + node2.classList.add("infohidden"); + } + node2.style.transform = "perspective(600px) rotateY(180deg) translateX(0)"; + var onEnd02 = function () { + //node2.removeEventListener('webkitTransitionEnd',onEnd02); + setTimeout(function () { + node2.style.transition = "all ease-in 0.3s"; + node2.style.transform = "perspective(600px) rotateY(270deg) translateX(52px)"; + var onEnd = function () { + node2.classList.remove("infohidden"); + node2.style.transition = "all 0s"; + ui.refresh(node2); + node2.style.transform = "perspective(600px) rotateY(-90deg) translateX(52px)"; + ui.refresh(node2); + node2.style.transition = ""; + ui.refresh(node2); + node2.style.transform = ""; + //node2.removeEventListener('webkitTransitionEnd',onEnd); + }; + node2.listenTransition(onEnd); + }, 200); + }; + node2.listenTransition(onEnd02); + })(targets[i], cards[i], i); + } + }, 200); + } + $compare(card1, target, card2) { + game.broadcast( + function (player, target, card1, card2) { + player.$compare(card1, target, card2); + }, + this, + target, + card1, + card2 + ); + game.addVideo("compare", this, [get.cardInfo(card1), target.dataset.position, get.cardInfo(card2)]); + var player = this; + var node1 = player.$throwxy2( + card1, + "calc(50% - 114px)", + "calc(50% - 52px)", + "perspective(600px) rotateY(180deg)", + true + ); + if (lib.config.cardback_style != "default") { + node1.style.transitionProperty = "none"; + ui.refresh(node1); + node1.classList.add("infohidden"); + ui.refresh(node1); + node1.style.transitionProperty = ""; + } else { + node1.classList.add("infohidden"); + } + + node1.style.transform = "perspective(600px) rotateY(180deg) translateX(0)"; + var onEnd01 = function () { + //node1.removeEventListener('webkitTransitionEnd',onEnd01); + setTimeout(function () { + node1.style.transition = "all ease-in 0.3s"; + node1.style.transform = "perspective(600px) rotateY(270deg) translateX(52px)"; + var onEnd = function () { + node1.classList.remove("infohidden"); + node1.style.transition = "all 0s"; + ui.refresh(node1); + node1.style.transform = "perspective(600px) rotateY(-90deg) translateX(52px)"; + ui.refresh(node1); + node1.style.transition = ""; + ui.refresh(node1); + node1.style.transform = ""; + //node1.removeEventListener('webkitTransitionEnd',onEnd); + }; + node1.listenTransition(onEnd); + }, 300); + }; + node1.listenTransition(onEnd01); + setTimeout(function () { + var node2 = target.$throwxy2( + card2, + "calc(50% + 10px)", + "calc(50% - 52px)", + "perspective(600px) rotateY(180deg)", + true + ); + if (lib.config.cardback_style != "default") { + node2.style.transitionProperty = "none"; + ui.refresh(node2); + node2.classList.add("infohidden"); + ui.refresh(node2); + node2.style.transitionProperty = ""; + } else { + node2.classList.add("infohidden"); + } + node2.style.transform = "perspective(600px) rotateY(180deg) translateX(0)"; + var onEnd02 = function () { + //node2.removeEventListener('webkitTransitionEnd',onEnd02); + setTimeout(function () { + node2.style.transition = "all ease-in 0.3s"; + node2.style.transform = "perspective(600px) rotateY(270deg) translateX(52px)"; + var onEnd = function () { + node2.classList.remove("infohidden"); + node2.style.transition = "all 0s"; + ui.refresh(node2); + node2.style.transform = "perspective(600px) rotateY(-90deg) translateX(52px)"; + ui.refresh(node2); + node2.style.transition = ""; + ui.refresh(node2); + node2.style.transform = ""; + //node2.removeEventListener('webkitTransitionEnd',onEnd); + }; + node2.listenTransition(onEnd); + }, 200); + }; + node2.listenTransition(onEnd02); + }, 200); + } + $throw(card, time, init, nosource) { + if (typeof card == "number") { + var tmp = card; + card = []; + while (tmp--) { + var cardx = ui.create.card(); + cardx.classList.add("infohidden"); + cardx.classList.add("infoflip"); + card.push(cardx); + } + } + if (init !== false) { + if (init !== "nobroadcast") { + game.broadcast( + function (player, card, time, init, nosource) { + player.$throw(card, time, init, nosource); + }, + this, + card, + time, + init + ); + } + if (get.itemtype(card) != "cards") { + if (get.itemtype(card) == "card") { + card = [card]; + } else { + return; + } + } + game.addVideo("throw", this, [get.cardsInfo(card), time, nosource]); + } + if (game.chess) { + this.chessFocus(); + } + if (get.itemtype(card) == "cards") { + var node; + for (var i = 0; i < card.length; i++) { + node = this.$throw(card[i], time, false, nosource); + } + return node; + } else { + var node; + if (card == undefined || card.length == 0) return; + node = this.$throwordered(card.copy("thrown"), nosource); + if (time != undefined) { + node.fixed = true; + setTimeout(function () { + node.delete(); + }, time); + } + lib.listenEnd(node); + return node; + } + } + $throwordered() { + return this.$throwordered2.apply(this, arguments); + // if(lib.config.low_performance){ + // return this.$throwordered2.apply(this,arguments); + // } + // else{ + // return this.$throwordered1.apply(this,arguments); + // } + } + $throwordered1(node, nosource) { + node.classList.add("thrown"); + node.hide(); + node.style.transitionProperty = "left,top,opacity,transform"; + for (var i = 0; i < ui.thrown.length; i++) { + if (ui.thrown[i].parentNode != ui.arena || ui.thrown[i].classList.contains("removing")) { + ui.thrown.splice(i--, 1); + } + } + ui.thrown.push(node); + var uithrowns = ui.thrown.slice(0); + var tops; + if (game.chess) { + switch (Math.floor((ui.thrown.length - 1) / 4)) { + case 0: + tops = ["calc(50% - 82px)"]; + break; + case 1: + tops = ["calc(50% - 139px)", "calc(50% - 25px)"]; + break; + case 2: + tops = ["calc(50% - 196px)", "calc(50% - 82px)", "calc(50% + 32px)"]; + break; + default: + tops = ["calc(50% - 253px)", "calc(50% - 139px)", "calc(50% - 25px)", "calc(50% + 89px)"]; + } + } else { + switch (Math.floor((ui.thrown.length - 1) / 4)) { + case 0: + tops = ["calc(50% - 52px)"]; + break; + case 1: + tops = ["calc(50% - 109px)", "calc(50% + 5px)"]; + break; + case 2: + tops = ["calc(50% - 166px)", "calc(50% - 52px)", "calc(50% + 62px)"]; + break; + default: + tops = ["calc(50% - 223px)", "calc(50% - 109px)", "calc(50% + 5px)", "calc(50% + 119px)"]; + } + } + while (uithrowns.length) { + var throwns = uithrowns.splice(0, Math.min(uithrowns.length, 4)); + switch (throwns.length) { + case 1: + throwns[0].style.left = "calc(50% - 52px)"; + break; + case 2: + throwns[0].style.left = "calc(50% - 109px)"; + throwns[1].style.left = "calc(50% + 5px)"; + break; + case 3: + throwns[0].style.left = "calc(50% - 166px)"; + throwns[1].style.left = "calc(50% - 52px)"; + throwns[2].style.left = "calc(50% + 62px)"; + break; + case 4: + throwns[0].style.left = "calc(50% - 223px)"; + throwns[1].style.left = "calc(50% - 109px)"; + throwns[2].style.left = "calc(50% + 5px)"; + throwns[3].style.left = "calc(50% + 119px)"; + break; + } + var top; + if (tops.length) { + top = tops.shift(); + } else { + if (game.chess) { + top = "calc(50% - 82px)"; + } else { + top = "calc(50% - 52px)"; + } + } + for (var i = 0; i < throwns.length; i++) { + throwns[i].style.top = top; + } + } + if (nosource) { + node.style.transform = "scale(0)"; + node.classList.add("center"); + } else { + var parseCalc = function (str) { + var per = str.slice(str.indexOf("calc(") + 5, str.indexOf("%")); + var add = str.slice(str.indexOf("%") + 1, str.indexOf("px")).replace(/\s/g, ""); + return [parseInt(per), parseInt(add)]; + }; + var nx = parseCalc(node.style.left); + var ny = parseCalc(node.style.top); + nx = (nx[0] * ui.arena.offsetWidth) / 100 + nx[1]; + ny = (ny[0] * ui.arena.offsetHeight) / 100 + ny[1]; + var dx, dy; + if (game.chess) { + var rect = this.getBoundingClientRect(); + dx = rect.left + this.offsetWidth / 2 - 52 - nx; + dy = rect.top + this.offsetHeight / 2 - 52 - ny; + } else { + dx = this.getLeft() + this.offsetWidth / 2 - 52 - nx; + dy = this.getTop() + this.offsetHeight / 2 - 52 - ny; + if (get.is.mobileMe(this)) { + dx += get.cardOffset(); + if (ui.arena.classList.contains("oblongcard")) { + dy -= 16; + } + } + } + if ( + node.style.transform && + node.style.transform != "none" && + node.style.transform.indexOf("translate") == -1 + ) { + node.style.transform += " translate(" + dx + "px," + dy + "px)"; + } else { + node.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + } + ui.arena.appendChild(node); + ui.refresh(node); + node.style.transform = ""; + node.show(); + lib.listenEnd(node); + return node; + } + $throwordered2(node, nosource) { + node.classList.add("thrown"); + node.classList.add("center"); + node.hide(); + node.style.transitionProperty = "left,top,opacity,transform"; + + if (nosource) { + // node.style.transform='scale(0)'; + } else { + var nx = [50, -52]; + var ny = [50, -52]; + nx = (nx[0] * ui.arena.offsetWidth) / 100 + nx[1]; + ny = (ny[0] * ui.arena.offsetHeight) / 100 + ny[1]; + var dx, dy; + if (game.chess) { + var rect = this.getBoundingClientRect(); + dx = rect.left + this.offsetWidth / 2 - 52 - nx; + dy = rect.top + this.offsetHeight / 2 - 52 - ny; + } else { + dx = this.getLeft() + this.offsetWidth / 2 - 52 - nx; + dy = this.getTop() + this.offsetHeight / 2 - 52 - ny; + if (get.is.mobileMe(this)) { + dx += get.cardOffset(); + if (ui.arena.classList.contains("oblongcard")) { + dy -= 16; + } + } + } + if ( + node.style.transform && + node.style.transform != "none" && + node.style.transform.indexOf("translate") == -1 + ) { + node.style.transform += " translate(" + dx + "px," + dy + "px)"; + } else { + node.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + } + ui.arena.appendChild(node); + ui.refresh(node); + + for (var i = 0; i < ui.thrown.length; i++) { + if (ui.thrown[i].parentNode != ui.arena || ui.thrown[i].classList.contains("removing")) { + ui.thrown.splice(i--, 1); + } + } + ui.thrown.push(node); + var uithrowns = ui.thrown.slice(0); + var tops; + switch (Math.floor((ui.thrown.length - 1) / 4)) { + case 0: + tops = [0]; + break; + case 1: + tops = [-57, 57]; + break; + case 2: + tops = [-114, 0, 114]; + break; + default: + tops = [-171, -57, 57, 171]; + } + while (uithrowns.length) { + var throwns = uithrowns.splice(0, Math.min(uithrowns.length, 4)); + switch (throwns.length) { + case 1: + throwns[0]._transthrown = "translate(0px,"; + break; + case 2: + throwns[0]._transthrown = "translate(-57px,"; + throwns[1]._transthrown = "translate(57px,"; + break; + case 3: + throwns[0]._transthrown = "translate(-114px,"; + throwns[1]._transthrown = "translate(0,"; + throwns[2]._transthrown = "translate(114px,"; + break; + case 4: + throwns[0]._transthrown = "translate(-171px,"; + throwns[1]._transthrown = "translate(-57px,"; + throwns[2]._transthrown = "translate(57px,"; + throwns[3]._transthrown = "translate(171px,"; + break; + } + var top; + if (tops.length) { + top = tops.shift(); + } else { + top = 0; + } + if (game.chess) { + top -= 30; + } + for (var i = 0; i < throwns.length; i++) { + throwns[i].style.transform = throwns[i]._transthrown + top + "px)"; + delete throwns[i]._transthrown; + } + } + + node.show(); + lib.listenEnd(node); + return node; + } + $throwxy(card, left, top) { + var node = card.copy("thrown", "thrownhighlight"); + node.dataset.position = this.dataset.position; + node.hide(); + node.style.transitionProperty = "left,top,opacity"; + + ui.arena.appendChild(node); + ui.refresh(node); + node.show(); + node.style.left = left; + node.style.top = top; + lib.listenEnd(node); + return node; + } + $throwxy2(card, left, top, trans, flipx, flipy) { + if (game.chess) { + return this.$throwxy.apply(this, arguments); + } + var node = card.copy("thrown", "thrownhighlight"); + node.style.left = left; + node.style.top = top; + node.hide(); + // node.style.transitionProperty='left,top,opacity,transform'; + + var parseCalc = function (str) { + var per = str.slice(str.indexOf("calc(") + 5, str.indexOf("%")); + var add = str.slice(str.indexOf("%") + 1, str.indexOf("px")).replace(/\s/g, ""); + return [parseInt(per), parseInt(add)]; + }; + var nx = parseCalc(node.style.left); + var ny = parseCalc(node.style.top); + nx = (nx[0] * ui.arena.offsetWidth) / 100 + nx[1]; + ny = (ny[0] * ui.arena.offsetHeight) / 100 + ny[1]; + var dx = this.getLeft() + this.offsetWidth / 2 - 52 - nx; + var dy = this.getTop() + this.offsetHeight / 2 - 52 - ny; + if (flipx) dx = -dx; + if (flipy) dy = -dy; + if (trans) { + node.style.transform = trans + " translate(" + dx + "px," + dy + "px)"; + } else { + node.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + + ui.arena.appendChild(node); + ui.refresh(node); + node.show(); + // node.style.transform=trans||''; + lib.listenEnd(node); + return node; + } + throwDice(num) { + if (typeof num != "number") { + num = get.rand(6) + 1; + _status.event.num = num; + } + if (!game.online) { + game.pause(); + } + game.broadcastAll(function (num) { + var diceContainer = ui.create.div(".fullsize.dice-container", ui.window); + ui.window.classList.add("dicepaused"); + var dice = ui.create.div(".dice"); + var side; + + side = ui.create.div(".side.front", dice); + ui.create.div(".dot.center", side); + ui.create.div(".side.front.inner", dice); + + side = ui.create.div(".side.top", dice); + ui.create.div(".dot.dtop.dleft", side); + ui.create.div(".dot.dbottom.dright", side); + ui.create.div(".side.top.inner", dice); + + side = ui.create.div(".side.right", dice); + ui.create.div(".dot.dtop.dleft", side); + ui.create.div(".dot.center", side); + ui.create.div(".dot.dbottom.dright", side); + ui.create.div(".side.right.inner", dice); + + side = ui.create.div(".side.left", dice); + ui.create.div(".dot.dtop.dleft", side); + ui.create.div(".dot.dtop.dright", side); + ui.create.div(".dot.dbottom.dleft", side); + ui.create.div(".dot.dbottom.dright", side); + ui.create.div(".side.left.inner", dice); + + side = ui.create.div(".side.bottom", dice); + ui.create.div(".dot.center", side); + ui.create.div(".dot.dtop.dleft", side); + ui.create.div(".dot.dtop.dright", side); + ui.create.div(".dot.dbottom.dleft", side); + ui.create.div(".dot.dbottom.dright", side); + ui.create.div(".side.bottom.inner", dice); + + side = ui.create.div(".side.back", dice); + ui.create.div(".dot.dtop.dleft", side); + ui.create.div(".dot.dtop.dright", side); + ui.create.div(".dot.dbottom.dleft", side); + ui.create.div(".dot.dbottom.dright", side); + ui.create.div(".dot.center dleft", side); + ui.create.div(".dot.center dright", side); + ui.create.div(".side.back.inner", dice); + + ui.create.div(".side.cover.x", dice); + ui.create.div(".side.cover.y", dice); + ui.create.div(".side.cover.z", dice); + + var map = { + 1: [75, 0, 45], + 2: [-15, 45, 0], + 3: [165, -45, 90], + 4: [345, -45, 90], + 5: [345, -45, 180], + 6: [255, 0, 135], + }; + dice.roll = function (deg) { + if (typeof deg == "number") { + dice.current[0] += deg; + deg = dice.current; + } + deg = deg.slice(0); + dice.current = deg; + this.style.transform = + "rotateX(" + deg[0] + "deg) rotateY(" + deg[1] + "deg) rotateZ(" + deg[2] + "deg)"; + }; + dice.roll(map[num]); + diceContainer.appendChild(dice); + ui.refresh(dice); + dice.roll(1025); + + dice.addEventListener("webkitTransitionEnd", function () { + if (!dice.over) { + dice.style.transition = "transform 0.8s ease"; + dice.roll(-20); + dice.over = true; + } else if (!dice.resumed) { + setTimeout(function () { + diceContainer.delete(); + ui.window.classList.remove("dicepaused"); + }, 300); + if (!game.online) { + setTimeout(game.resume, 800); + } + dice.resumed = true; + } + }); + }, num); + } + $giveAuto(card, player) { + if (Array.isArray(card) && card.length == 0) return; + var args = Array.from(arguments); + if (_status.connectMode || (!this.isUnderControl(true) && !player.isUnderControl(true))) { + if (Array.isArray(card)) { + card = card.length; + } else { + card = 1; + } + args[0] = card; + } + return this.$give.apply(this, args); + } + $give(card, player, log, init) { + if (init !== false) { + game.broadcast( + function (source, card, player, init) { + source.$give(card, player, false, init); + }, + this, + card, + player, + init + ); + if (typeof card == "number" && card >= 0) { + game.addVideo("give", this, [card, player.dataset.position]); + } else { + if (get.itemtype(card) == "card") { + card = [card]; + } + if (get.itemtype(card) == "cards") { + game.addVideo("giveCard", this, [get.cardsInfo(card), player.dataset.position]); + } + } + } + if (get.itemtype(card) == "cards") { + if (log != false && !_status.video) { + game.log(player, "从", this, "获得了", card); + } + if (this.$givemod) { + this.$givemod(card, player); + } else { + for (var i = 0; i < card.length; i++) { + this.$give(card[i], player, false, false); + } + } + } else if (typeof card == "number" && card >= 0) { + if (log != false && !_status.video) { + game.log(player, "从", this, "获得了" + get.cnNumber(card) + "张牌"); + } + if (this.$givemod) { + this.$givemod(card, player); + } else { + while (card--) this.$give("", player, false, false); + } + } else { + if (log != false && !_status.video) { + if (get.itemtype(card) == "card" && log != false) { + game.log(player, "从", this, "获得了", card); + } else { + game.log(player, "从", this, "获得了一张牌"); + } + } + if (this.$givemod) { + this.$givemod(card, player); + } else { + var node; + if (get.itemtype(card) == "card") { + node = card.copy("card", "thrown", false); + } else { + node = ui.create.div(".card.thrown"); + } + // node.dataset.position=this.dataset.position; + node.fixed = true; + this.$throwordered(node); + // lib.listenEnd(node); + // node.hide(); + // node.style.transitionProperty='left,top,opacity'; + // + // node.style.transform='rotate('+(Math.random()*16-8)+'deg)'; + // + // ui.arena.appendChild(node); + // ui.refresh(node); + // node.show(); + // node.style.left='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*100+'px)'; + // node.style.top='calc(50% - 52px '+((Math.random()-0.5<0)?'+':'-')+' '+Math.random()*80+'px)'; + + node.listenTransition(function () { + var dx = player.getLeft() + player.offsetWidth / 2 - 52 - node.offsetLeft; + var dy = player.getTop() + player.offsetHeight / 2 - 52 - node.offsetTop; + if ( + node.style.transform && + node.style.transform != "none" && + node.style.transform.indexOf("translate") == -1 + ) { + node.style.transform += " translate(" + dx + "px," + dy + "px)"; + } else { + node.style.transform = "translate(" + dx + "px," + dy + "px)"; + } + + node.delete(); + }); + // setTimeout(function(){ + // // node.removeAttribute('style'); + // // node.dataset.position=player.dataset.position; + // var dx=player.offsetLeft+player.offsetWidth/2-52-node.offsetLeft; + // var dy=player.offsetTop+player.offsetHeight/2-52-node.offsetTop; + // if(node.style.transform&&node.style.transform!='none'&&node.style.transform.indexOf('translate')==-1){ + // node.style.transform+=' translate('+dx+'px,'+dy+'px)'; + // } + // else{ + // node.style.transform='translate('+dx+'px,'+dy+'px)'; + // } + // + // node.delete(); + // },700); + } + } + } + $handleEquipChange() { + let player = this; + const cards = Array.from(this.node.equips.childNodes); + const cardsResume = cards.slice(0); + cards.forEach((card) => { + if (card.name.indexOf("empty_equip") == 0) { + let num = get.equipNum(card); + let remove = false; + if ((num == 4 || num == 3) && get.is.mountCombined()) { + remove = !this.hasEmptySlot("equip3_4") || this.getEquips("equip3_4").length; + } else if (!this.hasEmptySlot(num) || this.getEquips(num).length) { + remove = true; + } + if (remove) { + this.node.equips.removeChild(card); + cardsResume.remove(card); + } + } + }); + for (let i = 1; i <= 4; i++) { + let add = false; + if ((i == 4 || i == 3) && get.is.mountCombined()) { + add = this.hasEmptySlot("equip3_4") && !this.getEquips("equip3_4").length; + } else { + add = this.hasEmptySlot(i) && !this.getEquips(i).length; + } + if ( + add && + !cardsResume.some((card) => { + let num = get.equipNum(card); + if ((i == 4 || i == 3) && get.is.mountCombined()) { + return num == 4 || num == 3; + } else { + return num == i; + } + }) + ) { + const card = game.createCard("empty_equip" + i, "", ""); + card.fix(); + //console.log('add '+card.name); + card.style.transform = ""; + card.classList.remove("drawinghidden"); + card.classList.add("emptyequip"); + card.classList.add("hidden"); + delete card._transform; + const equipNum = get.equipNum(card); + let equipped = false; + for (let j = 0; j < player.node.equips.childNodes.length; j++) { + if (get.equipNum(player.node.equips.childNodes[j]) >= equipNum) { + player.node.equips.insertBefore(card, player.node.equips.childNodes[j]); + equipped = true; + break; + } + } + if (!equipped) { + player.node.equips.appendChild(card); + if (_status.discarded) { + _status.discarded.remove(card); + } + } + } + } + } + $equip(card) { + game.broadcast( + function (player, card) { + player.$equip(card); + }, + this, + card + ); + card.fix(); + card.style.transform = ""; + card.classList.remove("drawinghidden"); + delete card._transform; + var player = this; + var equipNum = get.equipNum(card); + var equipped = false; + for (var i = 0; i < player.node.equips.childNodes.length; i++) { + if (get.equipNum(player.node.equips.childNodes[i]) >= equipNum) { + player.node.equips.insertBefore(card, player.node.equips.childNodes[i]); + equipped = true; + break; + } + } + if (!equipped) { + player.node.equips.appendChild(card); + if (_status.discarded) { + _status.discarded.remove(card); + } + } + var info = get.info(card); + if (info.skills) { + for (var i = 0; i < info.skills.length; i++) { + player.addSkillTrigger(info.skills[i]); + } + } + return player; + } + $gain(card, log, init) { + if (init !== false) { + game.broadcast( + function (player, card, init) { + player.$gain(card, false, init); + }, + this, + card, + init + ); + if (typeof card == "number" && card >= 0) { + game.addVideo("gain", this, card); + } else { + if (get.itemtype(card) == "card") { + card = [card]; + } + if (get.itemtype(card) == "cards") { + game.addVideo("gainCard", this, get.cardsInfo(card)); + } else { + game.addVideo("gain", this, 1); + } + } + } + if (get.itemtype(card) == "cards") { + if (log != false && !_status.video) { + game.log(this, "获得了", card); + } + if (this.$gainmod) { + this.$gainmod(card); + } else { + for (var i = 0; i < card.length; i++) { + this.$gain(card[i], false, false); + } + } + } else if (typeof card == "number" && card > 1) { + if (log != false && !_status.video) { + game.log(this, "获得了" + get.cnNumber(card) + "张牌"); + } + if (this.$gainmod) { + this.$gainmod(card); + } else { + for (var i = 0; i < card; i++) { + this.$gain(1, false, false); + } + } + } else { + if (get.itemtype(card) == "card" && log != false && !_status.video) { + game.log(this, "获得了", card); + } + if (this.$gainmod) { + this.$gainmod(card); + } else { + var node; + if (get.itemtype(card) == "card") { + // node=this.$throwordered(card.copy(),true); + node = card.copy("thrown", false); + } else { + // node=this.$throwordered(ui.create.div('.card.thrown'),true); + node = ui.create.div(".card.thrown"); + node.moveTo = lib.element.Card.prototype.moveTo; + node.moveDelete = lib.element.Card.prototype.moveDelete; + } + node.fixed = true; + node.style.left = + "calc(50% - 52px " + + (Math.random() - 0.5 < 0 ? "+" : "-") + + " " + + Math.random() * 100 + + "px)"; + node.style.top = + "calc(50% - 52px " + + (Math.random() - 0.5 < 0 ? "+" : "-") + + " " + + Math.random() * 100 + + "px)"; + node.style.transform = "scale(0)"; + node.hide(); + ui.arena.appendChild(node); + ui.refresh(node); + node.show(); + node.style.transform = ""; + + lib.listenEnd(node); + var player = this; + setTimeout(function () { + node.moveDelete(player); + }, 700); + } + } + } + $gain2(cards, log) { + if (log === true) { + game.log(this, "获得了", cards); + } + game.broadcast( + function (player, cards) { + player.$gain2(cards); + }, + this, + cards + ); + if (get.itemtype(cards) == "card") cards = [cards]; + else if (get.itemtype(cards) != "cards") return; + var list = [], + list2 = []; + for (var i = 0; i < cards.length; i++) { + if ( + cards[i].clone && + (cards[i].clone.parentNode == this.parentNode || cards[i].clone.parentNode == ui.arena) && + parseFloat(getComputedStyle(cards[i].clone).opacity) > 0.3 + ) { + cards[i].clone.moveDelete(this); + list2.push(cards[i].clone); + } else { + list.push(cards[i]); + } + } + if (list2.length) { + game.addVideo("gain2", this, get.cardsInfo(list2)); + } + if (list.length) { + this.$draw(list, "nobroadcast"); + return true; + } + } + $skill(name, type, color, avatar) { + if (typeof type != "string") type = "legend"; + if (!avatar) { + this.playerfocus(1500); + game.delay(2); + } else { + game.addVideo("playerfocus2"); + game.broadcastAll(function () { + ui.arena.classList.add("playerfocus"); + setTimeout(function () { + ui.arena.classList.remove("playerfocus"); + }, 1800); + }); + game.delay(3); + } + var that = this; + setTimeout( + function () { + game.broadcastAll( + function (that, type, name, color, avatar) { + if (lib.config.animation && !lib.config.low_performance) { + if (game.chess) { + that["$" + type + "2"](1200); + } else { + that["$" + type](1200); + } + } + if (name) { + that.$fullscreenpop(name, color, avatar); + } + }, + that, + type, + name, + color, + avatar + ); + }, + avatar ? 0 : 300 + ); + } + $fire() { + game.addVideo("flame", this, "fire"); + var left, top; + if (game.chess) { + var rect = this.getBoundingClientRect(); + left = rect.left; + top = rect.top; + } else { + left = this.getLeft(); + top = this.getTop(); + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 20, 700, "fire"); + } + $thunder() { + game.addVideo("flame", this, "thunder"); + var left, top; + if (game.chess) { + var rect = this.getBoundingClientRect(); + left = rect.left; + top = rect.top; + } else { + left = this.getLeft(); + top = this.getTop(); + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "thunder"); + } + $rare2() { + game.addVideo("flame", this, "rare2"); + var rect = this.getBoundingClientRect(); + var left = rect.left; + var top = rect.top + 15; + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "rare"); + } + $epic2() { + game.addVideo("flame", this, "epic2"); + var rect = this.getBoundingClientRect(); + var left = rect.left; + var top = rect.top + 15; + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "epic"); + } + $legend2() { + game.addVideo("flame", this, "legend2"); + var rect = this.getBoundingClientRect(); + var left = rect.left; + var top = rect.top + 15; + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "legend"); + } + $rare(time) { + time = time || 700; + game.addVideo("flame", this, "rare"); + var left, top; + if (game.chess) { + left = this.getLeft() - ui.arena.offsetLeft; + top = this.getTop() - ui.arena.offsetTop; + } else { + left = this.getLeft(); + top = this.getTop(); + } + if (this.classList.contains("minskin")) { + top += 15; + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, time, "rare"); + } + $epic(time) { + time = time || 700; + game.addVideo("flame", this, "epic"); + var left, top; + if (game.chess) { + left = this.getLeft() - ui.arena.offsetLeft; + top = this.getTop() - ui.arena.offsetTop; + } else { + left = this.getLeft(); + top = this.getTop(); + } + if (this.classList.contains("minskin")) { + top += 15; + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, time, "epic"); + } + $legend(time) { + time = time || 700; + game.addVideo("flame", this, "legend"); + var left, top; + if (game.chess) { + left = this.getLeft() - ui.arena.offsetLeft; + top = this.getTop() - ui.arena.offsetTop; + } else { + left = this.getLeft(); + top = this.getTop(); + } + if (this.classList.contains("minskin")) { + top += 15; + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, time, "legend"); + } + $coin() { + game.broadcast(function (player) { + if (!lib.config.low_performance) { + player.$coin(); + } + }, this); + game.addVideo("flame", this, "coin"); + var left = this.getLeft() - ui.arena.offsetLeft; + var top = this.getTop() - ui.arena.offsetTop; + if (this.classList.contains("minskin")) { + top += 15; + } + top -= 25; + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "coin"); + } + $dust() { + game.broadcast(function (player) { + if (!lib.config.low_performance) { + player.$dust(); + } + }, this); + game.addVideo("flame", this, "dust"); + var left = this.getLeft() - ui.arena.offsetLeft; + var top = this.getTop() - ui.arena.offsetTop; + if (this.classList.contains("minskin")) { + top += 15; + } + top -= 25; + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "dust"); + } + $recover() { + game.addVideo("flame", this, "recover"); + var left, top; + if (game.chess) { + var rect = this.getBoundingClientRect(); + left = rect.left; + top = rect.top; + } else { + left = this.getLeft(); + top = this.getTop(); + } + game.animate.flame(left + this.offsetWidth / 2, top + this.offsetHeight - 30, 700, "recover"); + } + $fullscreenpop(str, nature, avatar, broadcast) { + if (broadcast !== false) + game.broadcast( + function (player, str, nature, avatar) { + player.$fullscreenpop(str, nature, avatar); + }, + this, + str, + nature, + avatar + ); + game.addVideo("fullscreenpop", this, [str, nature, avatar]); + var node = ui.create.div(".damage"); + if (avatar && this.node) { + if (avatar == "vice") { + if (lib.character[this.name2]) { + avatar = this.node.avatar2; + } + } else { + if (lib.character[this.name]) { + avatar = this.node.avatar; + } + } + if (!get.is.div(avatar)) { + avatar = false; + } + } else { + avatar = false; + } + if (avatar) { + node.classList.add("fullscreenavatar"); + ui.create.div("", ui.create.div(node)); + // ui.create.div('',str.split('').join('
                                    '),ui.create.div('.text.textbg',node)); + ui.create.div( + "", + "
                                    " + str.split("").join("

                                    ") + "
                                    ", + ui.create.div(".text", node) + ); + node.firstChild.firstChild.style.backgroundImage = avatar.style.backgroundImage; + node.dataset.nature = nature || "unknown"; + var num = 0; + var nodes = node.lastChild.firstChild.querySelectorAll("div"); + var interval = setInterval(function () { + if (num < nodes.length) { + nodes[num].classList.add("flashtext"); + num++; + } else { + clearInterval(interval); + } + }, 100); + } else { + avatar = false; + node.innerHTML = str; + node.dataset.nature = nature || "soil"; + } + if (avatar) { + var rect1 = ui.window.getBoundingClientRect(); + var rect2 = this.getBoundingClientRect(); + var dx = Math.round(2 * rect2.left + rect2.width - rect1.width); + var dy = Math.round(2 * rect2.top + rect2.height - rect1.height); + node.style.transform = "scale(0.5) translate(" + dx + "px," + dy + "px)"; + } + ui.window.appendChild(node); + ui.refresh(node); + if (avatar) { + node.style.transform = "scale(1)"; + node.style.opacity = 1; + } else { + node.classList.add("damageadded"); + } + setTimeout( + function () { + node.delete(); + node.style.transform = "scale(1.5)"; + }, + avatar ? 1600 : 1000 + ); + } + $damagepop(num, nature, font, nobroadcast) { + if (typeof num == "number" || typeof num == "string") { + game.addVideo("damagepop", this, [num, nature, font]); + if (nobroadcast !== false) + game.broadcast( + function (player, num, nature, font) { + player.$damagepop(num, nature, font); + }, + this, + num, + nature, + font + ); + var node = ui.create.div(".damage"); + if (font) { + node.classList.add("normal-font"); + } + if (typeof num == "number" && num > 0) { + if (num == Infinity) num = "+∞"; + else num = "+" + num; + } else if (num == -Infinity) num = "-∞"; + node.innerHTML = num; + this.damagepopups.push(node); + node.dataset.nature = nature || "soil"; + if (this.damagepopups.length == 1) { + this.$damagepop(); + } + } else if (this.damagepopups.length) { + var node = this.damagepopups[0]; + this.appendChild(node); + ui.refresh(node); + node.classList.add("damageadded"); + node.listenTransition(function () { + setTimeout(function () { + node.delete(); + }, 200); + }); + // setTimeout(function(){ + // node.delete(); + // },500); + var that = this; + setTimeout(function () { + that.damagepopups.shift(); + that.$damagepop(); + }, 500); + } + } + $damage(source) { + if (get.itemtype(source) == "player") { + game.addVideo("damage", this, source.dataset.position); + } else { + game.addVideo("damage", this); + } + game.broadcast( + function (player, source) { + player.$damage(source); + }, + this, + source + ); + if (source && source != this && lib.config.damage_shake) { + var left, top; + if (source.getTop() == this.getTop()) { + left = 20; + top = 0; + } else { + var ratio = (source.getLeft() - this.getLeft()) / (source.getTop() - this.getTop()); + left = Math.abs((20 * ratio) / Math.sqrt(1 + ratio * ratio)); + top = Math.abs(20 / Math.sqrt(1 + ratio * ratio)); + } + if (source.getLeft() - this.getLeft() > 0) left = -left; + if (source.getTop() - this.getTop() > 0) top = -top; + if (get.is.mobileMe(this)) { + if (this.classList.contains("linked")) { + this.node.avatar.style.transform = + "translate(" + left + "px," + top + "px) rotate(-90deg)"; + this.node.avatar2.style.transform = + "translate(" + left + "px," + top + "px) rotate(-90deg)"; + } else { + this.node.avatar.style.transform = "translate(" + left + "px," + top + "px)"; + this.node.avatar2.style.transform = "translate(" + left + "px," + top + "px)"; + } + } else if (this.classList.contains("linked") && get.is.newLayout()) { + this.style.transform = "translate(" + left + "px," + top + "px) rotate(-90deg)"; + } else if (this._chesstransform) { + this.style.transform = + "translate(" + + (left + this._chesstransform[0]) + + "px," + + (top + this._chesstransform[1]) + + "px)"; + } else { + this.style.transform = "translate(" + left + "px," + top + "px)"; + } + } else { + var zoom1 = 0.9, + zoom2 = 0.95; + if (arguments[1] == "phase") { + zoom1 = 1.05; + zoom2 = 1.05; + } + if (get.is.mobileMe(this)) { + if (this.classList.contains("linked")) { + this.node.avatar.style.transform = "scale(" + zoom1 + ") rotate(-90deg)"; + this.node.avatar2.style.transform = "scale(" + zoom1 + ") rotate(-90deg)"; + } else { + this.node.avatar.style.transform = "scale(" + zoom1 + ")"; + this.node.avatar2.style.transform = "scale(" + zoom1 + ")"; + } + } else if (this.classList.contains("linked") && get.is.newLayout()) { + this.style.transform = "scale(" + zoom2 + ") rotate(-90deg)"; + } else if (game.chess && this._chesstransform) { + this.style.transform = + "translate(" + + this._chesstransform[0] + + "px," + + this._chesstransform[1] + + "px) scale(" + + zoom2 + + ")"; + } else { + this.style.transform = "scale(" + zoom2 + ")"; + } + } + this.queue(); + } + $die() { + game.addVideo("die", this); + game.broadcast(function (player) { + player.$die(); + }, this); + if (lib.config.die_move != "off") { + this.$dieflip(lib.config.die_move); + } + if (this.$dieAfter) { + this.$dieAfter(); + } + } + $dieflip(type) { + var top0 = ui.window.offsetHeight / 2; + var left0 = ui.window.offsetWidth / 2; + var ratio = (left0 - this.getLeft()) / (top0 - this.getTop()); + var left = Math.abs((50 * ratio) / Math.sqrt(1 + ratio * ratio)); + var top = Math.abs(50 / Math.sqrt(1 + ratio * ratio)); + if (left0 - this.getLeft() > 0) left = -left; + if (top0 - this.getTop() > 0) top = -top; + if (get.is.mobileMe(this)) { + left = -Math.random() * 5 - 10; + top = Math.random() * 5 + 10; + } + if (this._chesstransform) { + left += this._chesstransform[0]; + top += this._chesstransform[1]; + } + var transform = + "translate(" + left + "px," + top + "px) " + "rotate(" + (Math.random() * 20 - 10) + "deg) "; + if (type == "flip") { + if (game.layout == "long" || game.layout == "long2") { + transform += "rotateY(180deg)"; + } else { + transform += Math.random() - 0.5 < 0 ? "rotateX(180deg)" : "rotateY(180deg)"; + } + } + if (get.is.mobileMe(this)) { + this.node.avatar.style.transform = transform; + this.node.avatar2.style.transform = transform; + this.style.transform = ""; + } else { + this.node.avatar.style.transform = ""; + this.node.avatar2.style.transform = ""; + this.style.transform = transform; + } + this.queue(false); + } + $phaseJudge(card) { + game.addVideo("phaseJudge", this, get.cardInfo(card)); + var player = this; + var clone = player.$throw(card); + if (lib.config.low_performance && card && card.clone) { + var waitingForTransition = get.time(); + _status.waitingForTransition = waitingForTransition; + card.clone.listenTransition(function () { + if (_status.waitingForTransition == waitingForTransition && _status.paused) { + game.resume(); + } + }); + game.pause(); + } else { + game.delay(); + } + } +} + +CacheContext.inject(Player.prototype, [ + "hasCard", + "hasValueTarget", + "getModableSkills", + "getCardIndex", + "countCards", + "getSkills", + "getUseValue", + "canUse", +]); diff --git a/noname/library/element/vcard.js b/noname/library/element/vcard.js index 4cd565e83..2f2582e78 100644 --- a/noname/library/element/vcard.js +++ b/noname/library/element/vcard.js @@ -1,133 +1,131 @@ -import { AI as ai } from '../../ai/index.js'; -import { Get as get } from '../../get/index.js'; -import { Game as game } from '../../game/index.js'; -import { Library as lib } from "../index.js"; -import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; - -export class VCard { - /** - * @param { any } [suitOrCard] - * @param { number | Card[] } [numberOrCards] - * @param { string } [name] - * @param { string } [nature] - */ - constructor(suitOrCard, numberOrCards, name, nature) { - if (Array.isArray(suitOrCard)) { - /** - * @type {string} - */ - this.suit = suitOrCard[0]; - /** - * @type {number} - */ - this.number = suitOrCard[1]; - /** - * @type {string} - */ - this.name = suitOrCard[2]; - /** - * @type {string} - */ - this.nature = suitOrCard[3]; - } - // @ts-ignore - else if (get.itemtype(suitOrCard) == 'card') { - this.name = get.name(suitOrCard); - this.suit = get.suit(suitOrCard); - this.color = get.color(suitOrCard); - this.number = get.number(suitOrCard); - this.nature = get.nature(suitOrCard); - /** - * @type { boolean } - */ - this.isCard = true; - this.cardid = suitOrCard.cardid; - this.wunature = suitOrCard.wunature; - /** - * @type {Record} - */ - this.storage = get.copy(suitOrCard.storage); - if (Array.isArray(numberOrCards)) this.cards = numberOrCards.slice(); - else this.cards = [suitOrCard]; - const info = get.info(this, false); - if (info) { - const autoViewAs = info.autoViewAs; - if (typeof autoViewAs == 'string') this.name = autoViewAs; - } - } - else if (suitOrCard && typeof suitOrCard != 'string') { - Object.keys(suitOrCard).forEach(key => { - /** - * @type { PropertyDescriptor } - */ - // @ts-ignore - const propertyDescriptor = Object.getOwnPropertyDescriptor(suitOrCard, key), value = propertyDescriptor.value; - if (Array.isArray(value)) this[key] = value.slice(); - else Object.defineProperty(this, key, propertyDescriptor); - }); - if (Array.isArray(numberOrCards)) { - const noCards = !this.cards; - /** - * @type { Card[] } - */ - this.cards = numberOrCards.slice(); - if (noCards) { - if (!lib.suits.includes(this.suit)) this.suit = get.suit(this); - if (!Object.keys(lib.color).includes(this.color)) this.color = get.color(this); - if (typeof this.number != 'number') this.number = get.number(this); - if (!this.nature) this.nature = get.nature(this); - } - } - else if(numberOrCards === 'unsure' && !this.isCard) { - if(!this.suit) this.suit = 'unsure'; - if(!this.color) this.color = 'unsure'; - if(!this.number) this.number = 'unsure'; - } - const info = get.info(this, false); - if (info) { - const autoViewAs = info.autoViewAs; - if (typeof autoViewAs == 'string') this.name = autoViewAs; - } - } - if (typeof suitOrCard == 'string') this.suit = suitOrCard; - if (typeof numberOrCards == 'number') this.number = numberOrCards; - if (typeof name == 'string') this.name = name; - if (typeof nature == 'string') this.nature = nature; - if (!this.storage) this.storage = {}; - if (!this.cards) this.cards = []; - } - sameSuitAs(card) { - return get.suit(this) == get.suit(card); - } - differentSuitFrom(card) { - return get.suit(this) != get.suit(card); - } - sameNumberAs(card) { - return get.number(this) == get.number(card); - } - differentNumberFrom(card) { - return get.number(this) != get.number(card); - } - sameNameAs(card) { - return get.name(this) == get.name(card); - } - differentNameFrom(card) { - return get.name(this) != get.name(card); - } - /** - * @param { Player } player - */ - hasNature(nature, player) { - const natures = get.natureList(this, player); - if (!nature) return natures.length > 0; - if (nature == 'linked') return natures.some(n => lib.linked.includes(n)); - return get.is.sameNature(natures, nature); - } - getCacheKey(){ - return `[vc:${this.name}+${this.suit?this.suit:'none'}+${this.number===undefined?'none':this.number}${this.nature?'+':''}${this.nature?this.nature:''}]`; - } - hasGaintag(tag) { - return this.gaintag && this.gaintag.includes(tag); - } -} +import { get } from "../../get/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; + +export class VCard { + /** + * @param { any } [suitOrCard] + * @param { number | Card[] } [numberOrCards] + * @param { string } [name] + * @param { string } [nature] + */ + constructor(suitOrCard, numberOrCards, name, nature) { + if (Array.isArray(suitOrCard)) { + /** + * @type {string} + */ + this.suit = suitOrCard[0]; + /** + * @type {number} + */ + this.number = suitOrCard[1]; + /** + * @type {string} + */ + this.name = suitOrCard[2]; + /** + * @type {string} + */ + this.nature = suitOrCard[3]; + } + // @ts-ignore + else if (get.itemtype(suitOrCard) == "card") { + this.name = get.name(suitOrCard); + this.suit = get.suit(suitOrCard); + this.color = get.color(suitOrCard); + this.number = get.number(suitOrCard); + this.nature = get.nature(suitOrCard); + /** + * @type { boolean } + */ + this.isCard = true; + this.cardid = suitOrCard.cardid; + this.wunature = suitOrCard.wunature; + /** + * @type {Record} + */ + this.storage = get.copy(suitOrCard.storage); + if (Array.isArray(numberOrCards)) this.cards = numberOrCards.slice(); + else this.cards = [suitOrCard]; + const info = get.info(this, false); + if (info) { + const autoViewAs = info.autoViewAs; + if (typeof autoViewAs == "string") this.name = autoViewAs; + } + } else if (suitOrCard && typeof suitOrCard != "string") { + Object.keys(suitOrCard).forEach((key) => { + /** + * @type { PropertyDescriptor } + */ + // @ts-ignore + const propertyDescriptor = Object.getOwnPropertyDescriptor(suitOrCard, key), + value = propertyDescriptor.value; + if (Array.isArray(value)) this[key] = value.slice(); + else Object.defineProperty(this, key, propertyDescriptor); + }); + if (Array.isArray(numberOrCards)) { + const noCards = !this.cards; + /** + * @type { Card[] } + */ + this.cards = numberOrCards.slice(); + if (noCards) { + if (!lib.suits.includes(this.suit)) this.suit = get.suit(this); + if (!Object.keys(lib.color).includes(this.color)) this.color = get.color(this); + if (typeof this.number != "number") this.number = get.number(this); + if (!this.nature) this.nature = get.nature(this); + } + } else if (numberOrCards === "unsure" && !this.isCard) { + if (!this.suit) this.suit = "unsure"; + if (!this.color) this.color = "unsure"; + if (!this.number) this.number = "unsure"; + } + const info = get.info(this, false); + if (info) { + const autoViewAs = info.autoViewAs; + if (typeof autoViewAs == "string") this.name = autoViewAs; + } + } + if (typeof suitOrCard == "string") this.suit = suitOrCard; + if (typeof numberOrCards == "number") this.number = numberOrCards; + if (typeof name == "string") this.name = name; + if (typeof nature == "string") this.nature = nature; + if (!this.storage) this.storage = {}; + if (!this.cards) this.cards = []; + } + sameSuitAs(card) { + return get.suit(this) == get.suit(card); + } + differentSuitFrom(card) { + return get.suit(this) != get.suit(card); + } + sameNumberAs(card) { + return get.number(this) == get.number(card); + } + differentNumberFrom(card) { + return get.number(this) != get.number(card); + } + sameNameAs(card) { + return get.name(this) == get.name(card); + } + differentNameFrom(card) { + return get.name(this) != get.name(card); + } + /** + * @param { Player } player + */ + hasNature(nature, player) { + const natures = get.natureList(this, player); + if (!nature) return natures.length > 0; + if (nature == "linked") return natures.some((n) => lib.linked.includes(n)); + return get.is.sameNature(natures, nature); + } + getCacheKey() { + return `[vc:${this.name}+${this.suit ? this.suit : "none"}+${ + this.number === undefined ? "none" : this.number + }${this.nature ? "+" : ""}${this.nature ? this.nature : ""}]`; + } + hasGaintag(tag) { + return this.gaintag && this.gaintag.includes(tag); + } +} diff --git a/noname/library/experimental/index.js b/noname/library/experimental/index.js index b68624008..c8cea9d75 100644 --- a/noname/library/experimental/index.js +++ b/noname/library/experimental/index.js @@ -1,8 +1,8 @@ -import { Uninstantable } from "../../util/index.js"; - -import { ExperimentalSymbol } from "./symbol.js"; - -export class Experimental extends Uninstantable { - static symbol = ExperimentalSymbol - static symbols = ExperimentalSymbol -} +import { Uninstantable } from "../../util/index.js"; + +import { ExperimentalSymbol } from "./symbol.js"; + +export class Experimental extends Uninstantable { + static symbol = ExperimentalSymbol; + static symbols = ExperimentalSymbol; +} diff --git a/noname/library/experimental/symbol.js b/noname/library/experimental/symbol.js index d73532822..393976b36 100644 --- a/noname/library/experimental/symbol.js +++ b/noname/library/experimental/symbol.js @@ -1,5 +1,5 @@ -import { Uninstantable } from "../../util/index.js"; - -export class ExperimentalSymbol extends Uninstantable { - static itemType = Symbol('noname.experimental.itemType') -} +import { Uninstantable } from "../../util/index.js"; + +export class ExperimentalSymbol extends Uninstantable { + static itemType = Symbol("noname.experimental.itemType"); +} diff --git a/noname/library/hooks/buildin.js b/noname/library/hooks/buildin.js index f6f105b02..28b9f9e17 100644 --- a/noname/library/hooks/buildin.js +++ b/noname/library/hooks/buildin.js @@ -1,5 +1,5 @@ -import { lib } from "../index.js" -import { game } from "../../game/index.js" +import { lib } from "../index.js"; +import { game } from "../../game/index.js"; /** * @type {(import("./interface.js").NonameHookType["addGroup"])[]} @@ -7,38 +7,27 @@ import { game } from "../../game/index.js" export const addGroup = [ function addColor(id, _short, _name, config) { if (typeof config.color != "undefined" && config.color != null) { - let color1, color2, color3, color4 + let color1, color2, color3, color4; if (typeof config.color == "string" && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(config.color)) { - let c1 = parseInt(`0x${config.color.slice(1, 3)}`) - let c2 = parseInt(`0x${config.color.slice(3, 5)}`) - let c3 = parseInt(`0x${config.color.slice(5, 7)}`) - color1 = color2 = color3 = color4 = [c1, c2, c3, 1] - } - else if (Array.isArray(config.color) && config.color.length == 4) { - if (config.color.every(item => Array.isArray(item))) { - color1 = config.color[0] - color2 = config.color[1] - color3 = config.color[2] - color4 = config.color[3] - } - else color1 = color2 = color3 = color4 = config.color + let c1 = parseInt(`0x${config.color.slice(1, 3)}`); + let c2 = parseInt(`0x${config.color.slice(3, 5)}`); + let c3 = parseInt(`0x${config.color.slice(5, 7)}`); + color1 = color2 = color3 = color4 = [c1, c2, c3, 1]; + } else if (Array.isArray(config.color) && config.color.length == 4) { + if (config.color.every((item) => Array.isArray(item))) { + color1 = config.color[0]; + color2 = config.color[1]; + color3 = config.color[2]; + color4 = config.color[3]; + } else color1 = color2 = color3 = color4 = config.color; } if (color1 && color2 && color3 && color4) { - const cs = lib.linq.cselector + const cs = lib.linq.cselector; game.dynamicStyle.addObject({ [cs.group( - cs.of( - cs.class("player ", "identity"), - cs.isAttr("data-color", `"${id}"`) - ), - cs.of( - "div", - cs.isAttr("data-nature", `"${id}"`) - ), - cs.of( - "span", - cs.isAttr("data-nature", `"${id}"`) - ) + cs.of(cs.class("player ", "identity"), cs.isAttr("data-color", `"${id}"`)), + cs.of("div", cs.isAttr("data-nature", `"${id}"`)), + cs.of("span", cs.isAttr("data-nature", `"${id}"`)) )]: { textShadow: cs.group( "black 0 0 1px", @@ -46,17 +35,11 @@ export const addGroup = [ `rgba(${color2.join()}) 0 0 5px`, `rgba(${color3.join()}) 0 0 10px`, `rgba(${color4.join()}) 0 0 10px` - ) + ), }, [cs.group( - cs.of( - "div", - cs.isAttr("data-nature", `"${id}m"`) - ), - cs.of( - "span", - cs.isAttr("data-nature", `"${id}m"`) - ) + cs.of("div", cs.isAttr("data-nature", `"${id}m"`)), + cs.of("span", cs.isAttr("data-nature", `"${id}m"`)) )]: { textShadow: cs.group( "black 0 0 1px", @@ -65,17 +48,11 @@ export const addGroup = [ `rgba(${color3.join()}) 0 0 5px`, `rgba(${color4.join()}) 0 0 5px`, "black 0 0 1px" - ) + ), }, [cs.group( - cs.of( - "div", - cs.isAttr("data-nature", `"${id}mm"`) - ), - cs.of( - "span", - cs.isAttr("data-nature", `"${id}mm"`) - ) + cs.of("div", cs.isAttr("data-nature", `"${id}mm"`)), + cs.of("span", cs.isAttr("data-nature", `"${id}mm"`)) )]: { textShadow: cs.group( "black 0 0 1px", @@ -84,10 +61,10 @@ export const addGroup = [ `rgba(${color3.join()}) 0 0 2px`, `rgba(${color4.join()}) 0 0 2px`, "black 0 0 1px" - ) - } - }) - lib.groupnature[id] = id + ), + }, + }); + lib.groupnature[id] = id; } } }, @@ -99,114 +76,98 @@ export const addGroup = [ writable: true, value: { fullskin: true, - image: config.image - } - }) + image: config.image, + }, + }); } - } -] + }, +]; /** * @type {(import("./interface.js").NonameHookType["addNature"])[]} */ export const addNature = [ function addColor(nature, _translation, config) { - if (typeof config != 'object') config = {} + if (typeof config != "object") config = {}; /** * @type {boolean} */ // @ts-ignore - let linked = config.linked + let linked = config.linked; /** * @type {number} */ // @ts-ignore - let order = config.order + let order = config.order; /** * @type {string} */ // @ts-ignore - let background = config.background + let background = config.background; /** * @type {number[]} */ // @ts-ignore - let lineColor = config.lineColor - if (typeof linked != 'boolean') linked = true - if (typeof order != 'number') order = 0 - if (typeof background != 'string') background = '' - if (!Array.isArray(lineColor) || lineColor.length != 3) lineColor = [] - else if (background.startsWith('ext:')) { - background = background.replace(/^ext:/, 'extension/') + let lineColor = config.lineColor; + if (typeof linked != "boolean") linked = true; + if (typeof order != "number") order = 0; + if (typeof background != "string") background = ""; + if (!Array.isArray(lineColor) || lineColor.length != 3) lineColor = []; + else if (background.startsWith("ext:")) { + background = background.replace(/^ext:/, "extension/"); } - if (linked) lib.linked.add(nature) - if (lineColor.length) lib.lineColor.set(nature, lineColor) - lib.nature.set(nature, order) - if (background.length > 0) lib.natureBg.set(nature, background) + if (linked) lib.linked.add(nature); + if (lineColor.length) lib.lineColor.set(nature, lineColor); + lib.nature.set(nature, order); + if (background.length > 0) lib.natureBg.set(nature, background); if (config.audio) { for (let key in config.audio) { if (!lib.natureAudio[key]) { - lib.natureAudio[key] = config.audio[key] + lib.natureAudio[key] = config.audio[key]; } else { for (let key2 in config.audio[key]) { - lib.natureAudio[key][key2] = config.audio[key][key2] + lib.natureAudio[key][key2] = config.audio[key][key2]; } } } } - let color1, color2 + let color1, color2; if (typeof config.color == "string" && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(config.color)) { - let c1 = parseInt(`0x${config.color.slice(1, 3)}`) - let c2 = parseInt(`0x${config.color.slice(3, 5)}`) - let c3 = parseInt(`0x${config.color.slice(5, 7)}`) - color1 = color2 = [c1, c2, c3, 1] - } - else if (Array.isArray(config.color) && config.color.length >= 2 && config.color.length <= 4) { - if (config.color.every(item => Array.isArray(item))) { - color1 = config.color[0] - color2 = config.color[1] - } - else { - let color = config.color.slice() - if (color.length == 3) color.push(1) - color1 = color2 = color + let c1 = parseInt(`0x${config.color.slice(1, 3)}`); + let c2 = parseInt(`0x${config.color.slice(3, 5)}`); + let c3 = parseInt(`0x${config.color.slice(5, 7)}`); + color1 = color2 = [c1, c2, c3, 1]; + } else if (Array.isArray(config.color) && config.color.length >= 2 && config.color.length <= 4) { + if (config.color.every((item) => Array.isArray(item))) { + color1 = config.color[0]; + color2 = config.color[1]; + } else { + let color = config.color.slice(); + if (color.length == 3) color.push(1); + color1 = color2 = color; } } if (color1 && color2) { - const cs = lib.linq.cselector - const g1 = cs.group( - cs.of( - cs.class("card", "fullskin", `${nature}`), - '>', - cs.class("name") - ) - ) - let result = {} + const cs = lib.linq.cselector; + const g1 = cs.group(cs.of(cs.class("card", "fullskin", `${nature}`), ">", cs.class("name"))); + let result = {}; result[g1] = { color: `rgba(${color1.join()})`, - border: cs.merge( - '1px', - 'solid', - `rgba(${color2.join()})` - ), - } + border: cs.merge("1px", "solid", `rgba(${color2.join()})`), + }; // @ts-ignore - game.dynamicStyle.addObject(result) + game.dynamicStyle.addObject(result); const g2 = cs.group( - cs.of( - cs.class("tempname", `${nature}`), - ':not([data-nature])>', - cs.class("span") - ) - ) - let result2 = {} + cs.of(cs.class("tempname", `${nature}`), ":not([data-nature])>", cs.class("span")) + ); + let result2 = {}; result2[g2] = { color: `rgba(${color1.join()})`, - } + }; // @ts-ignore - game.dynamicStyle.addObject(result2) + game.dynamicStyle.addObject(result2); } - } -] + }, +]; diff --git a/noname/library/hooks/hook.js b/noname/library/hooks/hook.js index 777915c6d..df3e557f0 100644 --- a/noname/library/hooks/hook.js +++ b/noname/library/hooks/hook.js @@ -1,4 +1,4 @@ -import * as buildin from "./buildin.js" +import * as buildin from "./buildin.js"; /** * @template {import("./interface.js").NonameHookType} HookType @@ -9,29 +9,29 @@ export class NonameHook extends Array { /** * @type {Name} */ - #name + #name; /** - * - * @param {Name} name + * + * @param {Name} name */ constructor(name) { - super() - this.#name = name + super(); + this.#name = name; if (name in buildin) { // @ts-ignore for (const item of buildin[name]) { - this.push(item) + this.push(item); } } } static get [Symbol.species]() { - return Array + return Array; } get name() { - return this.#name + return this.#name; } } diff --git a/noname/library/hooks/index.js b/noname/library/hooks/index.js index 13aa60ba0..0c44aca34 100644 --- a/noname/library/hooks/index.js +++ b/noname/library/hooks/index.js @@ -1,13 +1,11 @@ -import { NonameHook } from "./hook.js" -import { defaultHookcompatition } from "../assembly/index.js" +import { NonameHook } from "./hook.js"; +import { defaultHookcompatition } from "../assembly/index.js"; export const defaultHooks = { addGroup: new NonameHook("addGroup"), addNature: new NonameHook("addNature"), - ...defaultHookcompatition -} + ...defaultHookcompatition, +}; -export { - NonameHook -} +export { NonameHook }; diff --git a/noname/library/hooks/interface.d.ts b/noname/library/hooks/interface.d.ts index 0be0a6533..e08fb673a 100644 --- a/noname/library/hooks/interface.d.ts +++ b/noname/library/hooks/interface.d.ts @@ -1,94 +1,100 @@ -import { Button, Card, GameEvent, GameEventPromise, Player } from "../element" +import { Button, Card, GameEvent, GameEventPromise, Player } from "../element"; export interface NonameHookType { /** - * + * * @param id - 势力的id * @param short - 势力的短名称(单字称呼) * @param name - 势力的完整名称 * @param config - 关于势力的配置情况 */ - addGroup(id: string, short: string, name: string, config: Record): any + addGroup(id: string, short: string, name: string, config: Record): any; /** - * + * * @param nature - 属性的id * @param translation - 属性的名称 * @param config - 关于属性的配置 */ - addNature(nature: string, translation: string, config: Record): any - + addNature(nature: string, translation: string, config: Record): any; // #region Assembly-Compatition /** - * + * * @param event - 当前检查的事件 */ - checkBegin(event: GameEvent & GameEventPromise): any + checkBegin(event: GameEvent & GameEventPromise): any; /** - * + * * @param event - 当前检查的事件 * @param config - 一些配置 */ - checkEnd(event: GameEvent & GameEventPromise, config: { ok: boolean, auto: boolean, autoConfirm: boolean }): any + checkEnd( + event: GameEvent & GameEventPromise, + config: { ok: boolean; auto: boolean; autoConfirm: boolean } + ): any; /** - * + * * @param button - 检查的Button * @param event - 当前检查的事件 */ - checkButton(button: Button, event: GameEvent & GameEventPromise): any + checkButton(button: Button, event: GameEvent & GameEventPromise): any; /** - * + * * @param card - 检查的卡牌 * @param event - 当前检查的事件 */ - checkCard(card: Card, event: GameEvent & GameEventPromise): any + checkCard(card: Card, event: GameEvent & GameEventPromise): any; /** - * + * * @param target - 检查的玩家 * @param event - 当前检查的事件 */ - checkTarget(target: Player, event: GameEvent & GameEventPromise): any - - + checkTarget(target: Player, event: GameEvent & GameEventPromise): any; /** - * + * * @param event - 当前检查的事件 * @param args - 要取消检查的对象 */ - uncheckBegin(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"]): any + uncheckBegin( + event: GameEvent & GameEventPromise, + args: ("button" | "card" | "target")[] = ["button", "card", "target"] + ): any; /** - * + * * @param event - 当前检查的事件 * @param args - 要取消检查的对象 */ - uncheckEnd(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"]): any + uncheckEnd( + event: GameEvent & GameEventPromise, + args: ("button" | "card" | "target")[] = ["button", "card", "target"] + ): any; /** - * + * * @param button - 取消检查的Button * @param event - 当前检查的事件 */ - uncheckButton(button: Button, event: GameEvent & GameEventPromise): any + uncheckButton(button: Button, event: GameEvent & GameEventPromise): any; /** - * + * * @param card - 取消检查的卡牌 * @param event - 当前检查的事件 */ - uncheckCard(card: Card, event: GameEvent & GameEventPromise): any + uncheckCard(card: Card, event: GameEvent & GameEventPromise): any; /** - * + * * @param target - 取消检查的玩家 * @param event - 当前检查的事件 */ - uncheckTarget(target: Player, event: GameEvent & GameEventPromise): any + uncheckTarget(target: Player, event: GameEvent & GameEventPromise): any; // #endregion } diff --git a/noname/library/index.js b/noname/library/index.js index f5aac07b3..7977ceb56 100644 --- a/noname/library/index.js +++ b/noname/library/index.js @@ -5,95 +5,109 @@ * @typedef { InstanceType } Button * @typedef { InstanceType } Dialog * @typedef { InstanceType } GameEvent - * @typedef { InstanceType & InstanceType } GameEventPromise + * @typedef { GameEvent & InstanceType } GameEventPromise * @typedef { InstanceType } NodeWS * @typedef { InstanceType } Control -*/ -import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction, characterDefaultPicturePath } from "../util/index.js"; -import { AI as ai } from '../ai/index.js'; -import { Get as get } from '../get/index.js'; -import { Game as game } from '../game/index.js'; -import { status as _status } from '../status/index.js'; -import { UI as ui } from '../ui/index.js'; -import { GNC as gnc } from '../gnc/index.js'; - + */ +import { + nonameInitialized, + assetURL, + userAgent, + GeneratorFunction, + AsyncFunction, + characterDefaultPicturePath, +} from "../util/index.js"; +import { ai } from "../ai/index.js"; +import { get } from "../get/index.js"; +import { game } from "../game/index.js"; +import { _status } from "../status/index.js"; +import { ui } from "../ui/index.js"; +import { gnc } from "../gnc/index.js"; import { LibInit } from "./init/index.js"; import { Announce } from "./announce/index.js"; import { Channel } from "./channel/index.js"; import { Experimental } from "./experimental/index.js"; import * as Element from "./element/index.js"; import { updateURLs } from "./update-urls.js"; -import { defaultHooks } from "./hooks/index.js" -import { freezeButExtensible } from "../util/index.js" +import { defaultHooks } from "./hooks/index.js"; +import { freezeButExtensible } from "../util/index.js"; - -export class Library extends Uninstantable { - static configprefix = 'noname_0.9_'; - static versionOL = 27; - static updateURLS = updateURLs; - static updateURL = updateURLs.github; - static mirrorURL = updateURLs.coding; - static hallURL = '47.99.105.222'; - static assetURL = assetURL; - static userAgent = userAgent; - static characterDefaultPicturePath = characterDefaultPicturePath; - static compatibleEdition = Boolean(typeof nonameInitialized == 'string' && nonameInitialized.match(/\/(?:com\.widget|yuri\.nakamura)\.noname\//)); - static changeLog = []; - static updates = []; - static canvasUpdates = []; +export class Library { + configprefix = "noname_0.9_"; + versionOL = 27; + updateURLS = updateURLs; + updateURL = updateURLs.github; + mirrorURL = updateURLs.coding; + hallURL = "47.99.105.222"; + assetURL = assetURL; + userAgent = userAgent; + characterDefaultPicturePath = characterDefaultPicturePath; + compatibleEdition = Boolean( + typeof nonameInitialized == "string" && + nonameInitialized.match(/\/(?:com\.widget|yuri\.nakamura)\.noname\//) + ); + changeLog = []; + updates = []; + canvasUpdates = []; /** * @type { Video[] } */ - static video = []; - static skilllist = []; - static connectBanned = []; - static characterIntro = {}; - static characterTitle = {}; - static characterPack = new Proxy({}, { - set(target, prop, newValue) { - if (typeof prop == 'string') { - // 新增武将包,且不是“收藏”和“禁用” - if (!['mode_favourite', 'mode_banned'].includes(prop) && !Reflect.has(target, prop)) { - Promise.resolve().then(() => { - ui.updateCharacterPackMenu.forEach(fun => fun(prop)); - }); + video = []; + skilllist = []; + connectBanned = []; + characterIntro = {}; + characterTitle = {}; + characterPack = new Proxy( + {}, + { + set(target, prop, newValue) { + if (typeof prop == "string") { + // 新增武将包,且不是“收藏”和“禁用” + if (!["mode_favourite", "mode_banned"].includes(prop) && !Reflect.has(target, prop)) { + Promise.resolve().then(() => { + ui.updateCharacterPackMenu.forEach((fun) => fun(prop)); + }); + } } - } - return Reflect.set(target, prop, newValue); + return Reflect.set(target, prop, newValue); + }, } - }); - static characterFilter = {}; - static characterSort = {}; - static characterReplace = {}; - static characterSubstitute = {}; - static characterInitFilter = {}; - static characterGuozhanFilter = ["mode_guozhan"]; - static dynamicTranslate = {}; - static cardPack = new Proxy({}, { - set(target, prop, newValue) { - if (typeof prop == 'string') { - if (!Reflect.has(target, prop)) { - Promise.resolve().then(() => { - ui.updateCardPackMenu.forEach(fun => fun(prop)); - }); + ); + characterFilter = {}; + characterSort = {}; + characterReplace = {}; + characterSubstitute = {}; + characterInitFilter = {}; + characterGuozhanFilter = ["mode_guozhan"]; + dynamicTranslate = {}; + cardPack = new Proxy( + {}, + { + set(target, prop, newValue) { + if (typeof prop == "string") { + if (!Reflect.has(target, prop)) { + Promise.resolve().then(() => { + ui.updateCardPackMenu.forEach((fun) => fun(prop)); + }); + } } - } - return Reflect.set(target, prop, newValue); + return Reflect.set(target, prop, newValue); + }, } - }); - static cardPackInfo = {}; + ); + cardPackInfo = {}; /** * @type { SMap } */ - static skin = {}; - static onresize = []; - static onphase = []; - static onwash = []; - static onover = []; - static ondb = []; - static ondb2 = []; - static chatHistory = []; - static emotionList = { + skin = {}; + onresize = []; + onphase = []; + onwash = []; + onover = []; + ondb = []; + ondb2 = []; + chatHistory = []; + emotionList = { xiaowu_emotion: 14, xiaokuo_emotion: 8, shibing_emotion: 15, @@ -103,37 +117,40 @@ export class Library extends Uninstantable { xiaotao_emotion: 20, xiaojiu_emotion: 20, }; - static animate = { + animate = { skill: {}, card: {}, }; - static onload = []; - static onload2 = []; - static onprepare = []; - static arenaReady = []; - static onfree = []; - static inpile = []; - static inpile_nature = []; - static extensions = []; - static extensionPack = {}; - static cardType = {}; - static hook = { globalskill: {} }; + onload = []; + onload2 = []; + onprepare = []; + /** + * @type { Function[] | undefined } + */ + arenaReady = []; + onfree = []; + inpile = []; + inpile_nature = []; + extensions = []; + extensionPack = {}; + cardType = {}; + hook = { globalskill: {} }; /** * @type { Player | undefined } */ - static tempSortSeat; + tempSortSeat; /** * @type { 'android' | 'ios' | undefined } */ - static device; + device; /** * @type { string } */ - static version; + version; /** * @type { Videos[] } */ - static videos; + videos; /** * @type { { * fs: typeof import("fs"), @@ -146,22 +163,22 @@ export class Library extends Uninstantable { * torespondtimeout:{}, * } } */ - static node; + node; /** * @type { { [key: string]: string } } */ - static playerOL; + playerOL; /** * @type { IDBRequest } */ - static db; + db; //函数钩子 /** * 你可以往这里加入{钩子名:函数数组},并在数组里增加你的自定义函数 * 这样当某个地方调用game.callHook(钩子名,[...函数参数])时,就会按顺序将对应数组中的每个函数运行一遍(传参为callHook的第二个参数)。 * 你可以将hook机制类比为event.trigger(),但是这里只能放同步代码 */ - static hooks = freezeButExtensible({ ...defaultHooks }); + hooks = freezeButExtensible({ ...defaultHooks }); /** * **无名杀频道推送机制** @@ -184,7 +201,7 @@ export class Library extends Uninstantable { * // 从某个角落向channel发消息,若无消息接收则等待 * await channel.send(item); */ - static channel = Channel; + channel = Channel; /** * **无名杀消息推送库** @@ -211,452 +228,606 @@ export class Library extends Uninstantable { * // 若此时乙扩展不想继续订阅`skinChange`事件,可以通过`unsubscribe`解除订阅 * lib.announce.unsubscribe("skinChange", method); */ - static announce = new Announce(new EventTarget(), new WeakMap()); + announce = new Announce(new EventTarget(), new WeakMap()); - static objectURL = new Map(); - static hookmap = {}; - static imported = {}; - static layoutfixed = ['chess', 'tafang', 'stone']; - static pinyins = { + objectURL = new Map(); + hookmap = {}; + imported = {}; + layoutfixed = ["chess", "tafang", "stone"]; + pinyins = { _metadata: { - shengmu: ['zh', 'ch', 'sh', 'b', 'p', 'm', 'f', 'd', 't', 'l', 'n', 'g', 'k', 'h', 'j', 'q', 'x', 'r', 'z', 'c', 's', 'y', 'w'], - special_shengmu: ['j', 'q', 'x', 'y'], + shengmu: [ + "zh", + "ch", + "sh", + "b", + "p", + "m", + "f", + "d", + "t", + "l", + "n", + "g", + "k", + "h", + "j", + "q", + "x", + "r", + "z", + "c", + "s", + "y", + "w", + ], + special_shengmu: ["j", "q", "x", "y"], feijiemu: { - i: ['ing', 'iu', 'ie', 'in'], - u: ['ui', 'un'], - ü: ['üe', 'ün'], + i: ["ing", "iu", "ie", "in"], + u: ["ui", "un"], + ü: ["üe", "ün"], }, - zhengtirendu: ['zhi', 'chi', 'shi', 'ri', 'zi', 'ci', 'si'], + zhengtirendu: ["zhi", "chi", "shi", "ri", "zi", "ci", "si"], yunjiao: { - '一麻': ['a', 'ia', 'ua'], - '二波': ['o', 'e', 'uo'], - '三皆': ['ie', 'üe'], - '四开': ['ai', 'uai'], - '五微': ['ei', 'ui'], - '六豪': ['ao', 'iao'], - '七尤': ['ou', 'iu'], - '八寒': ['an', 'ian', 'uan', 'üan'], - '九文': ['en', 'in', 'un', 'ün'], - '十唐': ['ang', 'iang', 'uang'], - '十一庚': ['eng', 'ing', 'ong', 'ung'], - '十二齐': ['i', 'er', 'ü'], - '十三支': ['-i'], - '十四姑': ['u'], + 一麻: ["a", "ia", "ua"], + 二波: ["o", "e", "uo"], + 三皆: ["ie", "üe"], + 四开: ["ai", "uai"], + 五微: ["ei", "ui"], + 六豪: ["ao", "iao"], + 七尤: ["ou", "iu"], + 八寒: ["an", "ian", "uan", "üan"], + 九文: ["en", "in", "un", "ün"], + 十唐: ["ang", "iang", "uang"], + 十一庚: ["eng", "ing", "ong", "ung"], + 十二齐: ["i", "er", "ü"], + 十三支: ["-i"], + 十四姑: ["u"], }, - } + }, }; /** * Yingbian * * 应变 */ - static yingbian = { + yingbian = { condition: { color: new Map([ - ['zhuzhan', 'wood'], - ['kongchao', 'soil'], - ['fujia', 'orange'], - ['canqu', 'fire'], - ['force', 'metal'] + ["zhuzhan", "wood"], + ["kongchao", "soil"], + ["fujia", "orange"], + ["canqu", "fire"], + ["force", "metal"], ]), complex: new Map([ - ['zhuzhan', function (event) { - const yingbianZhuzhan = game.createEvent('yingbianZhuzhan'); - yingbianZhuzhan.player = event.player; - yingbianZhuzhan.card = event.card; - yingbianZhuzhan._trigger = event; - yingbianZhuzhan.yingbianZhuzhanAI = event.yingbianZhuzhanAI; - yingbianZhuzhan.afterYingbianZhuzhan = event.afterYingbianZhuzhan; - yingbianZhuzhan.setContent(() => { - 'step 0'; - event._global_waiting = true; - event.send = (player, card, source, targets, id, id2, yingbianZhuzhanAI, skillState) => { - if (skillState) player.applySkills(skillState); - var type = get.type2(card), str = get.translation(source); - if (targets && targets.length) str += `对${get.translation(targets)}`; - str += `使用了${get.translation(card)},是否弃置一张${get.translation(type)}为其助战?`; - player.chooseCard({ - filterCard: (card, player) => get.type2(card) == type && lib.filter.cardDiscardable(card, player), - prompt: str, - position: 'h', - _global_waiting: true, - id: id, - id2: id2, - ai: typeof yingbianZhuzhanAI == 'function' ? yingbianZhuzhanAI(player, card, source, targets) : cardx => { - var info = get.info(card); - if (info && info.ai && info.ai.yingbian) { - var ai = info.ai.yingbian(card, source, targets, player); - if (!ai) return 0; - return ai - get.value(cardx); - } - else if (get.attitude(player, source) <= 0) return 0; - return 5 - get.value(cardx); - } - }); - if (!game.online) return; - _status.event._resultid = id; - game.resume(); - }; - 'step 1'; - var type = get.type2(card); - event.list = game.filterPlayer(current => current != player && current.countCards('h') && (_status.connectMode || current.hasCard(cardx => get.type2(cardx) == type, 'h'))).sortBySeat(_status.currentPhase || player); - event.id = get.id(); - 'step 2'; - if (!event.list.length) event.finish(); - else if (_status.connectMode && (event.list[0].isOnline() || event.list[0] == game.me)) event.goto(4); - else event.send(event.current = event.list.shift(), event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI); - 'step 3'; - if (result.bool) { - event.zhuzhanresult = event.current; - event.zhuzhanresult2 = result; - if (event.current != game.me) game.delayx(); - event.goto(8); - } - else event.goto(2); - 'step 4'; - var id = event.id, sendback = (result, player) => { - if (result && result.id == id && !event.zhuzhanresult && result.bool) { - event.zhuzhanresult = player; - event.zhuzhanresult2 = result; - game.broadcast('cancel', id); - if (_status.event.id == id && _status.event.name == 'chooseCard' && _status.paused) return () => { - event.resultOL = _status.event.resultOL; - ui.click.cancel(); - if (ui.confirm) ui.confirm.close(); - }; - } - else if (_status.event.id == id && _status.event.name == 'chooseCard' && _status.paused) return () => event.resultOL = _status.event.resultOL; - }, withme = false, withol = false, list = event.list; - for (var i = 0; i < list.length; i++) { - var current = list[i]; - if (current.isOnline()) { - withol = true; - current.wait(sendback); - current.send(event.send, current, event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI, get.skillState(current)); - list.splice(i--, 1); - } - else if (current == game.me) { - withme = true; - event.send(current, event.card, player, trigger.targets, event.id, trigger.parent.id, trigger.yingbianZhuzhanAI); - list.splice(i--, 1); - } - } - if (!withme) event.goto(6); - if (_status.connectMode && (withme || withol)) game.players.forEach(value => { - if (value != player) value.showTimer(); - }); - event.withol = withol; - 'step 5'; - if (!result || !result.bool || event.zhuzhanresult) return; - game.broadcast('cancel', event.id); - event.zhuzhanresult = game.me; - event.zhuzhanresult2 = result; - 'step 6'; - if (event.withol && !event.resultOL) game.pause(); - 'step 7'; - game.players.forEach(value => value.hideTimer()); - 'step 8'; - if (event.zhuzhanresult) { - var target = event.zhuzhanresult; - target.line(player, 'green'); - target.discard(event.zhuzhanresult2.cards).discarder = target; - if (typeof event.afterYingbianZhuzhan == 'function') event.afterYingbianZhuzhan(event, trigger); - var yingbianCondition = event.name.slice(8).toLowerCase(), yingbianConditionTag = `yingbian_${yingbianCondition}_tag`; - target.popup(yingbianConditionTag, lib.yingbian.condition.color.get(yingbianCondition)); - game.log(target, '响应了', player, '发起的', yingbianConditionTag); - target.addExpose(0.2); - event.result = { - bool: true + [ + "zhuzhan", + function (event) { + const yingbianZhuzhan = game.createEvent("yingbianZhuzhan"); + yingbianZhuzhan.player = event.player; + yingbianZhuzhan.card = event.card; + yingbianZhuzhan._trigger = event; + yingbianZhuzhan.yingbianZhuzhanAI = event.yingbianZhuzhanAI; + yingbianZhuzhan.afterYingbianZhuzhan = event.afterYingbianZhuzhan; + yingbianZhuzhan.setContent(() => { + "step 0"; + event._global_waiting = true; + event.send = ( + player, + card, + source, + targets, + id, + id2, + yingbianZhuzhanAI, + skillState + ) => { + if (skillState) player.applySkills(skillState); + var type = get.type2(card), + str = get.translation(source); + if (targets && targets.length) str += `对${get.translation(targets)}`; + str += `使用了${get.translation(card)},是否弃置一张${get.translation( + type + )}为其助战?`; + player.chooseCard({ + filterCard: (card, player) => + get.type2(card) == type && lib.filter.cardDiscardable(card, player), + prompt: str, + position: "h", + _global_waiting: true, + id: id, + id2: id2, + ai: + typeof yingbianZhuzhanAI == "function" + ? yingbianZhuzhanAI(player, card, source, targets) + : (cardx) => { + var info = get.info(card); + if (info && info.ai && info.ai.yingbian) { + var ai = info.ai.yingbian( + card, + source, + targets, + player + ); + if (!ai) return 0; + return ai - get.value(cardx); + } else if (get.attitude(player, source) <= 0) return 0; + return 5 - get.value(cardx); + }, + }); + if (!game.online) return; + _status.event._resultid = id; + game.resume(); }; - } - else event.result = { - bool: false - }; - }); - yingbianZhuzhan._args = Array.from(arguments); - return yingbianZhuzhan; - }] + "step 1"; + var type = get.type2(card); + event.list = game + .filterPlayer( + (current) => + current != player && + current.countCards("h") && + (_status.connectMode || + current.hasCard((cardx) => get.type2(cardx) == type, "h")) + ) + .sortBySeat(_status.currentPhase || player); + event.id = get.id(); + "step 2"; + if (!event.list.length) event.finish(); + else if ( + _status.connectMode && + (event.list[0].isOnline() || event.list[0] == game.me) + ) + event.goto(4); + else + event.send( + (event.current = event.list.shift()), + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI + ); + "step 3"; + if (result.bool) { + event.zhuzhanresult = event.current; + event.zhuzhanresult2 = result; + if (event.current != game.me) game.delayx(); + event.goto(8); + } else event.goto(2); + "step 4"; + var id = event.id, + sendback = (result, player) => { + if (result && result.id == id && !event.zhuzhanresult && result.bool) { + event.zhuzhanresult = player; + event.zhuzhanresult2 = result; + game.broadcast("cancel", id); + if ( + _status.event.id == id && + _status.event.name == "chooseCard" && + _status.paused + ) + return () => { + event.resultOL = _status.event.resultOL; + ui.click.cancel(); + if (ui.confirm) ui.confirm.close(); + }; + } else if ( + _status.event.id == id && + _status.event.name == "chooseCard" && + _status.paused + ) + return () => (event.resultOL = _status.event.resultOL); + }, + withme = false, + withol = false, + list = event.list; + for (var i = 0; i < list.length; i++) { + var current = list[i]; + if (current.isOnline()) { + withol = true; + current.wait(sendback); + current.send( + event.send, + current, + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI, + get.skillState(current) + ); + list.splice(i--, 1); + } else if (current == game.me) { + withme = true; + event.send( + current, + event.card, + player, + trigger.targets, + event.id, + trigger.parent.id, + trigger.yingbianZhuzhanAI + ); + list.splice(i--, 1); + } + } + if (!withme) event.goto(6); + if (_status.connectMode && (withme || withol)) + game.players.forEach((value) => { + if (value != player) value.showTimer(); + }); + event.withol = withol; + "step 5"; + if (!result || !result.bool || event.zhuzhanresult) return; + game.broadcast("cancel", event.id); + event.zhuzhanresult = game.me; + event.zhuzhanresult2 = result; + "step 6"; + if (event.withol && !event.resultOL) game.pause(); + "step 7"; + game.players.forEach((value) => value.hideTimer()); + "step 8"; + if (event.zhuzhanresult) { + var target = event.zhuzhanresult; + target.line(player, "green"); + target.discard(event.zhuzhanresult2.cards).discarder = target; + if (typeof event.afterYingbianZhuzhan == "function") + event.afterYingbianZhuzhan(event, trigger); + var yingbianCondition = event.name.slice(8).toLowerCase(), + yingbianConditionTag = `yingbian_${yingbianCondition}_tag`; + target.popup( + yingbianConditionTag, + lib.yingbian.condition.color.get(yingbianCondition) + ); + game.log(target, "响应了", player, "发起的", yingbianConditionTag); + target.addExpose(0.2); + event.result = { + bool: true, + }; + } else + event.result = { + bool: false, + }; + }); + yingbianZhuzhan._args = Array.from(arguments); + return yingbianZhuzhan; + }, + ], ]), simple: new Map([ - ['kongchao', event => !event.player.countCards('h')], - ['fujia', event => event.player.isMaxHandcard()], - ['canqu', event => event.player.getHp() == 1] - ]) + ["kongchao", (event) => !event.player.countCards("h")], + ["fujia", (event) => event.player.isMaxHandcard()], + ["canqu", (event) => event.player.getHp() == 1], + ]), }, effect: new Map([ - ['add', () => { - trigger.yingbian_addTarget = true; - }], - ['remove', () => { - trigger.yingbian_removeTarget = true; - }], - ['damage', () => { - if (typeof trigger.baseDamage != 'number') trigger.baseDamage = 1; - trigger.baseDamage++; - game.log(card, '的伤害值基数+1'); - }], - ['draw', () => { - player.draw(); - }], - ['gain', () => { - const cardx = trigger.respondTo; - if (cardx && cardx[1] && cardx[1].cards && cardx[1].cards.filterInD('od').length) player.gain(cardx[1].cards.filterInD('od'), 'gain2'); - }], - ['hit', () => { - trigger.directHit.addArray(game.players).addArray(game.dead); - game.log(card, '不可被响应'); - }], - ['all', () => { - card.yingbian_all = true; - game.log(card, '执行所有选项'); - }] + [ + "add", + () => { + trigger.yingbian_addTarget = true; + }, + ], + [ + "remove", + () => { + trigger.yingbian_removeTarget = true; + }, + ], + [ + "damage", + () => { + if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1; + trigger.baseDamage++; + game.log(card, "的伤害值基数+1"); + }, + ], + [ + "draw", + () => { + player.draw(); + }, + ], + [ + "gain", + () => { + const cardx = trigger.respondTo; + if (cardx && cardx[1] && cardx[1].cards && cardx[1].cards.filterInD("od").length) + player.gain(cardx[1].cards.filterInD("od"), "gain2"); + }, + ], + [ + "hit", + () => { + trigger.directHit.addArray(game.players).addArray(game.dead); + game.log(card, "不可被响应"); + }, + ], + [ + "all", + () => { + card.yingbian_all = true; + game.log(card, "执行所有选项"); + }, + ], ]), prompt: new Map([ - ['add', '目标+1'], - ['remove', '目标-1'], - ['damage', '伤害+1'], - ['draw', '摸一张牌'], - ['gain', '获得响应的牌'], - ['hit', '此牌不可被响应'], - ['all', '无视条件执行所有选项'] - ]) + ["add", "目标+1"], + ["remove", "目标-1"], + ["damage", "伤害+1"], + ["draw", "摸一张牌"], + ["gain", "获得响应的牌"], + ["hit", "此牌不可被响应"], + ["all", "无视条件执行所有选项"], + ]), }; /** * Stratagem buff * * 谋攻强化 */ - static stratagemBuff = { + stratagemBuff = { cost: new Map([ - ['sha', 1], - ['shan', 1], - ['juedou', 2], - ['huogong', 2], - ['tao', 3] + ["sha", 1], + ["shan", 1], + ["juedou", 2], + ["huogong", 2], + ["tao", 3], ]), effect: new Map([ - ['sha', (event, option) => { - if (event.step != 0 || option.state != 'end') return; - game.log(event.player, '触发了强化效果'); - game.log(event.card, '抵消所需要的', new lib.element.VCard({ - name: 'shan' - }), '数+1'); - const map = event.customArgs; - game.players.concat(game.dead).forEach(current => { - const id = current.playerid; - if (!map[id]) map[id] = {}; - if (typeof map[id].shanRequired == 'number') map[id].shanRequired++; - else map[id].shanRequired = 2; - }); - }], - ['shan', (event, option) => { - if (event.step != 0 || option.state != 'end') return; - game.log(event.player, '触发了强化效果'); - game.log('使用', event.card, '时视为两张', new lib.element.VCard({ - name: 'shan' - }), '的效果'); - event.player.when('useCard').filter(evt => evt == event).then(() => { - trigger.getParent(2).decrease('shanRequired', 1); - }); - }], - ['juedou', (event, option) => { - if (event.step != 0 || option.state != 'end') return; - game.log(event.player, '触发了强化效果'); - game.log('对', event.card, '的目标造成伤害时,伤害+1'); - event.player.when({ - source: 'damageBegin1' - }).filter(evt => evt.getParent(2) == event && event.targets.includes(evt.player)).then(() => { - trigger.increase('num'); - }); - }], - ['huogong', (event, option) => { - if (event.step != 0 || option.state != 'end') return; - game.log(event.player, '触发了强化效果'); - game.log(event.card, '造成的伤害+1'); - event.increase('baseDamage', 1); - }], - ['tao', (event, option) => { - if (event.step != 0 || option.state != 'end') return; - game.log(event.player, '触发了强化效果'); - game.log(event.card, '回复的体力+1'); - event.increase('baseDamage', 1); - }] + [ + "sha", + (event, option) => { + if (event.step != 0 || option.state != "end") return; + game.log(event.player, "触发了强化效果"); + game.log( + event.card, + "抵消所需要的", + new lib.element.VCard({ + name: "shan", + }), + "数+1" + ); + const map = event.customArgs; + game.players.concat(game.dead).forEach((current) => { + const id = current.playerid; + if (!map[id]) map[id] = {}; + if (typeof map[id].shanRequired == "number") map[id].shanRequired++; + else map[id].shanRequired = 2; + }); + }, + ], + [ + "shan", + (event, option) => { + if (event.step != 0 || option.state != "end") return; + game.log(event.player, "触发了强化效果"); + game.log( + "使用", + event.card, + "时视为两张", + new lib.element.VCard({ + name: "shan", + }), + "的效果" + ); + event.player + .when("useCard") + .filter((evt) => evt == event) + .then(() => { + trigger.getParent(2).decrease("shanRequired", 1); + }); + }, + ], + [ + "juedou", + (event, option) => { + if (event.step != 0 || option.state != "end") return; + game.log(event.player, "触发了强化效果"); + game.log("对", event.card, "的目标造成伤害时,伤害+1"); + event.player + .when({ + source: "damageBegin1", + }) + .filter((evt) => evt.getParent(2) == event && event.targets.includes(evt.player)) + .then(() => { + trigger.increase("num"); + }); + }, + ], + [ + "huogong", + (event, option) => { + if (event.step != 0 || option.state != "end") return; + game.log(event.player, "触发了强化效果"); + game.log(event.card, "造成的伤害+1"); + event.increase("baseDamage", 1); + }, + ], + [ + "tao", + (event, option) => { + if (event.step != 0 || option.state != "end") return; + game.log(event.player, "触发了强化效果"); + game.log(event.card, "回复的体力+1"); + event.increase("baseDamage", 1); + }, + ], ]), prompt: new Map([ [ - 'sha', + "sha", /** * @type {() => string} */ - () => `抵消所需要的【${get.translation('shan')}】数+1。` + () => `抵消所需要的【${get.translation("shan")}】数+1。`, ], [ - 'shan', + "shan", /** * @type {() => string} */ - () => `使用时视为两张【${get.translation('shan')}】的效果。` + () => `使用时视为两张【${get.translation("shan")}】的效果。`, ], - [ - 'juedou', - () => '对此牌的目标造成伤害时,伤害+1。' - ], - [ - 'huogong', - () => '造成的伤害+1。' - ], - [ - 'tao', - () => '回复的体力+1。' - ] - ]) + ["juedou", () => "对此牌的目标造成伤害时,伤害+1。"], + ["huogong", () => "造成的伤害+1。"], + ["tao", () => "回复的体力+1。"], + ]), }; /** * The actual card name * * 实际的卡牌名称 */ - static actualCardName = new Map([ - ['挟令', '挟天子以令诸侯'], - ['霹雳投石车', '霹雳车'] + actualCardName = new Map([ + ["挟令", "挟天子以令诸侯"], + ["霹雳投石车", "霹雳车"], ]); - static characterDialogGroup = { - '收藏': function (name, capt) { + characterDialogGroup = { + 收藏: function (name, capt) { return lib.config.favouriteCharacter.includes(name) ? capt : null; }, - '最近': function (name, capt) { - var list = get.config('recentCharacter') || []; + 最近: function (name, capt) { + var list = get.config("recentCharacter") || []; return list.includes(name) ? capt : null; - } + }, }; - static listenEnd(node) { + listenEnd(node) { if (!node._listeningEnd) { node._listeningEnd = true; node.listenTransition(function () { delete node._listeningEnd; if (node._onEndMoveDelete) { node.moveDelete(node._onEndMoveDelete); - } - else if (node._onEndDelete) { + } else if (node._onEndDelete) { node.delete(); } node._transitionEnded = true; }); } } - static configMenu = { + configMenu = { general: { - name: '通用', + name: "通用", config: { mount_combine: { - name: '合并坐骑栏', + name: "合并坐骑栏", init: false, - intro: '
                                  3. 将进攻坐骑栏和防御坐骑栏合并为同一个位置(重启后生效)。', + intro: "
                                  4. 将进攻坐骑栏和防御坐骑栏合并为同一个位置(重启后生效)。", restart: true, }, low_performance: { - name: '流畅模式', + name: "流畅模式", init: false, - intro: '减少部分游戏特效,提高游戏速度', + intro: "减少部分游戏特效,提高游戏速度", onclick(bool) { - game.saveConfig('low_performance', bool); + game.saveConfig("low_performance", bool); if (bool) { - ui.window.classList.add('low_performance'); + ui.window.classList.add("low_performance"); + } else { + ui.window.classList.remove("low_performance"); } - else { - ui.window.classList.remove('low_performance'); - } - } + }, }, compatiblemode: { - name: '兼容模式', + name: "兼容模式", init: false, - intro: '开启兼容模式可防止扩展使游戏卡死并提高对旧扩展的兼容性,但对游戏速度有一定影响,若无不稳定或不兼容的扩展建议关闭', + intro: "开启兼容模式可防止扩展使游戏卡死并提高对旧扩展的兼容性,但对游戏速度有一定影响,若无不稳定或不兼容的扩展建议关闭", onclick(bool) { - game.saveConfig('compatiblemode', bool); + game.saveConfig("compatiblemode", bool); if (bool) { - ui.window.classList.add('compatiblemode'); + ui.window.classList.add("compatiblemode"); + } else { + ui.window.classList.remove("compatiblemode"); } - else { - ui.window.classList.remove('compatiblemode'); - } - } + }, }, confirm_exit: { - name: '确认退出', + name: "确认退出", init: false, unfrequent: true, - intro: '离开游戏前弹出确认对话框', + intro: "离开游戏前弹出确认对话框", }, keep_awake: { - name: '屏幕常亮', + name: "屏幕常亮", init: false, unfrequent: true, - intro: '防止屏幕自动关闭
                                    注:旧版本通过NoSleep.js实现的屏幕常亮可能会影响外置音频的音量', + intro: "防止屏幕自动关闭
                                    注:旧版本通过NoSleep.js实现的屏幕常亮可能会影响外置音频的音量", onclick(bool) { - game.saveConfig('keep_awake', bool); + game.saveConfig("keep_awake", bool); if (bool) { - if (window.plugins && window.plugins.insomnia) window.plugins.insomnia.keepAwake(); + if (window.plugins && window.plugins.insomnia) + window.plugins.insomnia.keepAwake(); else if (window.noSleep) { - document.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function enableNoSleepX() { - document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', enableNoSleepX, false); - window.noSleep.enable(); - }, false); + document.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function enableNoSleepX() { + document.removeEventListener( + lib.config.touchscreen ? "touchend" : "click", + enableNoSleepX, + false + ); + window.noSleep.enable(); + }, + false + ); } - } - else { - if (window.plugins && window.plugins.insomnia) window.plugins.insomnia.allowSleepAgain(); + } else { + if (window.plugins && window.plugins.insomnia) + window.plugins.insomnia.allowSleepAgain(); else if (window.noSleep) window.noSleep.disable(); } - } + }, }, auto_confirm: { - name: '自动确认', + name: "自动确认", init: true, unfrequent: true, - intro: '当候选目标只有1个时,点击目标后无需再点击确认', + intro: "当候选目标只有1个时,点击目标后无需再点击确认", }, skip_shan: { - name: '无闪自动取消', + name: "无闪自动取消", init: false, unfrequent: true, - intro: '当自己需要使用或打出【闪】时,若自己没有【闪】,则跳过该步骤', + intro: "当自己需要使用或打出【闪】时,若自己没有【闪】,则跳过该步骤", }, unauto_choose: { - name: '拆顺手牌选择', + name: "拆顺手牌选择", init: false, unfrequent: true, - intro: '拆牌或者顺牌时,就算只能选择对方的手牌依然手动选择', + intro: "拆牌或者顺牌时,就算只能选择对方的手牌依然手动选择", }, wuxie_self: { - name: '不无懈自己', + name: "不无懈自己", init: true, unfrequent: true, - intro: '自己使用的单目标普通锦囊即将生效时,不询问无懈', + intro: "自己使用的单目标普通锦囊即将生效时,不询问无懈", }, tao_enemy: { - name: '不对敌方出桃', + name: "不对敌方出桃", init: false, - intro: '双方阵营明确的模式中(如对决),敌方角色濒死时不询问出桃', + intro: "双方阵营明确的模式中(如对决),敌方角色濒死时不询问出桃", unfrequent: true, }, enable_drag: { - name: '启用拖拽', + name: "启用拖拽", init: true, - intro: '按住卡牌后可将卡牌拖至目标', + intro: "按住卡牌后可将卡牌拖至目标", unfrequent: true, }, enable_dragline: { - name: '拖拽指示线', + name: "拖拽指示线", init: true, unfrequent: true, - intro: '拖拽时显示虚线,可能降低游戏速度', + intro: "拖拽时显示虚线,可能降低游戏速度", }, enable_touchdragline: { - name: '拖拽指示线', + name: "拖拽指示线", init: false, unfrequent: true, - intro: '拖拽时显示虚线,可能降低游戏速度', + intro: "拖拽时显示虚线,可能降低游戏速度", }, // enable_pressure:{ // name:'启用压感', @@ -682,281 +853,278 @@ export class Library extends Uninstantable { // } // }, touchscreen: { - name: '触屏模式', + name: "触屏模式", init: false, restart: true, unfrequent: true, - intro: '开启后可使触屏设备反应更快,但无法使用鼠标操作', + intro: "开启后可使触屏设备反应更快,但无法使用鼠标操作", onclick(bool) { - if (get.is.nomenu('touchscreen', bool)) return false; - game.saveConfig('touchscreen', bool); - } + if (get.is.nomenu("touchscreen", bool)) return false; + game.saveConfig("touchscreen", bool); + }, }, swipe: { - name: '滑动手势', + name: "滑动手势", init: true, unfrequent: true, - intro: '在非滚动区域向四个方向滑动可执行对应操作', + intro: "在非滚动区域向四个方向滑动可执行对应操作", }, swipe_down: { - name: '下划操作', - init: 'menu', + name: "下划操作", + init: "menu", unfrequent: true, - intro: '向下滑动时执行的操作', + intro: "向下滑动时执行的操作", item: { - system: '显示按钮', - menu: '打开菜单', - pause: '切换暂停', - auto: '切换托管', - chat: '显示聊天', - off: '关闭', + system: "显示按钮", + menu: "打开菜单", + pause: "切换暂停", + auto: "切换托管", + chat: "显示聊天", + off: "关闭", }, onclick(item) { - if (get.is.nomenu('swipe_down', item)) return false; - game.saveConfig('swipe_down', item); - } + if (get.is.nomenu("swipe_down", item)) return false; + game.saveConfig("swipe_down", item); + }, }, swipe_up: { - name: '上划操作', - intro: '向上滑动时执行的操作', - init: 'auto', + name: "上划操作", + intro: "向上滑动时执行的操作", + init: "auto", unfrequent: true, item: { - system: '显示按钮', - menu: '打开菜单', - pause: '切换暂停', - auto: '切换托管', - chat: '显示聊天', - off: '关闭', + system: "显示按钮", + menu: "打开菜单", + pause: "切换暂停", + auto: "切换托管", + chat: "显示聊天", + off: "关闭", }, onclick(item) { - if (get.is.nomenu('swipe_up', item)) return false; - game.saveConfig('swipe_up', item); - } + if (get.is.nomenu("swipe_up", item)) return false; + game.saveConfig("swipe_up", item); + }, }, swipe_left: { - name: '左划操作', - intro: '向左滑动时执行的操作', - init: 'system', + name: "左划操作", + intro: "向左滑动时执行的操作", + init: "system", unfrequent: true, item: { - system: '显示按钮', - menu: '打开菜单', - pause: '切换暂停', - auto: '切换托管', - chat: '显示聊天', - off: '关闭', + system: "显示按钮", + menu: "打开菜单", + pause: "切换暂停", + auto: "切换托管", + chat: "显示聊天", + off: "关闭", }, onclick(item) { - if (get.is.nomenu('swipe_left', item)) return false; - game.saveConfig('swipe_left', item); - } + if (get.is.nomenu("swipe_left", item)) return false; + game.saveConfig("swipe_left", item); + }, }, swipe_right: { - name: '右划操作', - intro: '向右滑动时执行的操作', - init: 'system', + name: "右划操作", + intro: "向右滑动时执行的操作", + init: "system", unfrequent: true, item: { - system: '显示按钮', - menu: '打开菜单', - pause: '切换暂停', - auto: '切换托管', - chat: '显示聊天', - off: '关闭', + system: "显示按钮", + menu: "打开菜单", + pause: "切换暂停", + auto: "切换托管", + chat: "显示聊天", + off: "关闭", }, onclick(item) { - if (get.is.nomenu('swipe_right', item)) return false; - game.saveConfig('swipe_right', item); - } + if (get.is.nomenu("swipe_right", item)) return false; + game.saveConfig("swipe_right", item); + }, }, round_menu_func: { - name: '触屏按钮操作', - intro: '点击屏幕中圆形按钮时执行的操作', - init: 'system', + name: "触屏按钮操作", + intro: "点击屏幕中圆形按钮时执行的操作", + init: "system", unfrequent: true, item: { - system: '显示按钮', - menu: '打开菜单', - pause: '切换暂停', - auto: '切换托管' + system: "显示按钮", + menu: "打开菜单", + pause: "切换暂停", + auto: "切换托管", }, onclick(item) { - if (get.is.nomenu('round_menu_func', item)) return false; - game.saveConfig('round_menu_func', item); + if (get.is.nomenu("round_menu_func", item)) return false; + game.saveConfig("round_menu_func", item); }, }, show_splash: { - name: '显示开始界面', - intro: '游戏开始前进入模式选择画面', - init: 'init', + name: "显示开始界面", + intro: "游戏开始前进入模式选择画面", + init: "init", item: { - off: '关闭', - init: '首次启动', - always: '保持开启', - } + off: "关闭", + init: "首次启动", + always: "保持开启", + }, }, game_speed: { - name: '游戏速度', - init: 'mid', + name: "游戏速度", + init: "mid", item: { - vslow: '慢', - slow: '较慢', - mid: '中', - fast: '较快', - vfast: '快', - vvfast: '很快', + vslow: "慢", + slow: "较慢", + mid: "中", + fast: "较快", + vfast: "快", + vvfast: "很快", }, - intro: '设置不同游戏操作间的时间间隔' + intro: "设置不同游戏操作间的时间间隔", }, sync_speed: { - name: '限制结算速度', - intro: '在动画结算完成前不执行下一步操作,开启后游戏操作的间隔更长但画面更浏畅,在游戏较卡时建议开启', - init: true + name: "限制结算速度", + intro: "在动画结算完成前不执行下一步操作,开启后游戏操作的间隔更长但画面更浏畅,在游戏较卡时建议开启", + init: true, }, enable_vibrate: { - name: '开启震动', - intro: '回合开始时使手机震动', - init: false + name: "开启震动", + intro: "回合开始时使手机震动", + init: false, }, right_click: { - name: '右键操作', - init: 'pause', - intro: '在空白区域点击右键时的操作', + name: "右键操作", + init: "pause", + intro: "在空白区域点击右键时的操作", unfrequent: true, item: { - pause: '暂停', - shortcut: '工具', - config: '选项', - auto: '托管', + pause: "暂停", + shortcut: "工具", + config: "选项", + auto: "托管", }, onclick(item) { - if (get.is.nomenu('right_click', item)) return false; - game.saveConfig('right_click', item); - } + if (get.is.nomenu("right_click", item)) return false; + game.saveConfig("right_click", item); + }, }, longpress_info: { - name: '长按显示信息', + name: "长按显示信息", init: true, unfrequent: true, restart: true, - intro: '长按后弹出菜单', + intro: "长按后弹出菜单", }, right_info: { - name: '右键显示信息', + name: "右键显示信息", init: true, unfrequent: true, restart: true, - intro: '右键点击后弹出菜单', + intro: "右键点击后弹出菜单", }, hover_all: { - name: '悬停显示信息', + name: "悬停显示信息", init: true, unfrequent: true, restart: true, - intro: '悬停后弹出菜单', + intro: "悬停后弹出菜单", }, hover_handcard: { - name: '悬停手牌显示信息', + name: "悬停手牌显示信息", init: true, unfrequent: true, - intro: '悬停手牌后弹出菜单', + intro: "悬停手牌后弹出菜单", }, hoveration: { - name: '悬停菜单弹出时间', + name: "悬停菜单弹出时间", unfrequent: true, - intro: '鼠标移至目标到弹出菜单的时间间隔', - init: '1000', + intro: "鼠标移至目标到弹出菜单的时间间隔", + init: "1000", item: { - '500': '0.5秒', - '700': '0.7秒', - '1000': '1秒', - '1500': '1.5秒', - '2500': '2.5秒', - } + 500: "0.5秒", + 700: "0.7秒", + 1000: "1秒", + 1500: "1.5秒", + 2500: "2.5秒", + }, }, doubleclick_intro: { - name: '双击显示武将资料', + name: "双击显示武将资料", init: true, unfrequent: true, - intro: '双击武将头像后显示其资料卡', + intro: "双击武将头像后显示其资料卡", }, video: { - name: '保存录像', - init: '20', - intro: '游戏结束后保存录像在最大条数,超过后将从最早的录像开始删除(已收藏的录像不计入条数)', + name: "保存录像", + init: "20", + intro: "游戏结束后保存录像在最大条数,超过后将从最早的录像开始删除(已收藏的录像不计入条数)", item: { - '0': '关闭', - '5': '五局', - '10': '十局', - '20': '二十局', - '50': '五十局', - '10000': '无限', + 0: "关闭", + 5: "五局", + 10: "十局", + 20: "二十局", + 50: "五十局", + 10000: "无限", }, unfrequent: true, }, max_loadtime: { - name: '最长载入时间', - intro: '设置游戏从启动到完成载入所需的最长时间,超过此时间未完成载入会报错,若设备较慢或安装了较多扩展可适当延长此时间', - init: '5000', + name: "最长载入时间", + intro: "设置游戏从启动到完成载入所需的最长时间,超过此时间未完成载入会报错,若设备较慢或安装了较多扩展可适当延长此时间", + init: "5000", unfrequent: true, item: { - 5000: '5秒', - 10000: '10秒', - 20000: '20秒', - 60000: '60秒' + 5000: "5秒", + 10000: "10秒", + 20000: "20秒", + 60000: "60秒", }, onclick(item) { - game.saveConfig('max_loadtime', item); - if (item == '5000') { - localStorage.removeItem(lib.configprefix + 'loadtime'); + game.saveConfig("max_loadtime", item); + if (item == "5000") { + localStorage.removeItem(lib.configprefix + "loadtime"); + } else { + localStorage.setItem(lib.configprefix + "loadtime", item); } - else { - localStorage.setItem(lib.configprefix + 'loadtime', item); - } - } + }, }, mousewheel: { - name: '滚轮控制手牌', + name: "滚轮控制手牌", init: true, unfrequent: true, - intro: '开启后滚轮可使手牌横向滚动,在mac等可横向滚动的设备上建议关闭', + intro: "开启后滚轮可使手牌横向滚动,在mac等可横向滚动的设备上建议关闭", onclick(bool) { - game.saveConfig('mousewheel', bool); + game.saveConfig("mousewheel", bool); if (lib.config.touchscreen) return; if (lib.config.mousewheel) { ui.handcards1Container.onmousewheel = ui.click.mousewheel; ui.handcards2Container.onmousewheel = ui.click.mousewheel; - } - else { + } else { ui.handcards1Container.onmousewheel = null; ui.handcards2Container.onmousewheel = null; } - } + }, }, auto_check_update: { - name: '自动检查游戏更新', - intro: '进入游戏时检查更新', + name: "自动检查游戏更新", + intro: "进入游戏时检查更新", init: false, - unfrequent: true + unfrequent: true, }, lucky_star: { - name: '幸运星模式', - intro: '在涉及随机数等的技能中,必定得到效果最好的结果。(联机模式无效)', + name: "幸运星模式", + intro: "在涉及随机数等的技能中,必定得到效果最好的结果。(联机模式无效)", init: false, - unfrequent: true + unfrequent: true, }, dev: { - name: '开发者模式', - intro: '开启后可使用浏览器控制台控制游戏,同时可更新到开发版', + name: "开发者模式", + intro: "开启后可使用浏览器控制台控制游戏,同时可更新到开发版", init: false, onclick(bool) { - game.saveConfig('dev', bool); + game.saveConfig("dev", bool); if (_status.connectMode) return; if (bool) { lib.cheat.i(); - } - else { + } else { delete window.cheat; delete window.game; delete window.ui; @@ -969,54 +1137,57 @@ export class Library extends Uninstantable { unfrequent: true, }, extension_alert: { - name: '无视扩展报错', + name: "无视扩展报错", init: false, unfrequent: true, }, fuck_sojson: { - name: '检测加密扩展', + name: "检测加密扩展", init: false, unfrequent: true, }, errstop: { - name: '出错时停止游戏', + name: "出错时停止游戏", init: false, - unfrequent: true + unfrequent: true, }, update_link: { - name: '更新地址', - init: 'coding', + name: "更新地址", + init: "coding", unfrequent: true, item: { - coding: 'URC', - github: 'GitHub', + coding: "URC", + github: "GitHub", }, onclick(item) { - game.saveConfig('update_link', item); + game.saveConfig("update_link", item); lib.updateURL = lib.updateURLS[item] || lib.updateURLS.coding; }, }, extension_source: { - name: '获取扩展地址', - init: 'GitHub Proxy', + name: "获取扩展地址", + init: "GitHub Proxy", unfrequent: true, item: {}, - intro: () => `获取在线扩展时的地址。当前地址:${document.createElement('br').outerHTML}${lib.config.extension_sources[lib.config.extension_source]}` + intro: () => + `获取在线扩展时的地址。当前地址:${document.createElement("br").outerHTML}${ + lib.config.extension_sources[lib.config.extension_source] + }`, }, extension_create: { - name: '添加获取扩展地址', + name: "添加获取扩展地址", clear: true, unfrequent: true, onclick() { - game.prompt('请输入地址名称', function (str) { + game.prompt("请输入地址名称", function (str) { if (str) { var map = lib.config.extension_sources; - game.prompt('请输入' + str + '的地址', function (str2) { + game.prompt("请输入" + str + "的地址", function (str2) { if (str2) { delete map[str]; map[str] = str2; - game.saveConfig('extension_sources', map); - game.saveConfig('extension_source', str); + game.saveConfig("extension_sources", map); + game.saveConfig("extension_source", str); var nodexx = ui.extension_source; nodexx.updateInner(); var nodeyy = nodexx._link.menu; @@ -1027,7 +1198,7 @@ export class Library extends Uninstantable { break; } } - var textMenu = ui.create.div('', str, nodeyy, function () { + var textMenu = ui.create.div("", str, nodeyy, function () { var node = this.parentNode._link; var config = node._link.config; node._link.current = this.link; @@ -1044,7 +1215,7 @@ export class Library extends Uninstantable { }); textMenu._link = str; nodezz.item[name] = str; - alert('已添加扩展地址:' + str); + alert("已添加扩展地址:" + str); } }); } @@ -1052,11 +1223,12 @@ export class Library extends Uninstantable { }, }, extension_delete: { - name: '删除当前扩展地址', + name: "删除当前扩展地址", clear: true, unfrequent: true, onclick() { - var bool = false, map = lib.config.extension_sources; + var bool = false, + map = lib.config.extension_sources; for (var i in map) { if (i != lib.config.extension_source) { bool = true; @@ -1064,13 +1236,13 @@ export class Library extends Uninstantable { } } if (!bool) { - alert('不能删除最后一个扩展地址!'); + alert("不能删除最后一个扩展地址!"); return; } var name = lib.config.extension_source; - game.saveConfig('extension_source', i); + game.saveConfig("extension_source", i); delete map[name]; - game.saveConfig('extension_sources', map); + game.saveConfig("extension_sources", map); var nodexx = ui.extension_source; nodexx.updateInner(); var nodeyy = nodexx._link.menu; @@ -1082,27 +1254,24 @@ export class Library extends Uninstantable { } } delete nodezz.item[name]; - alert('已删除扩展地址:' + name); + alert("已删除扩展地址:" + name); }, }, update: function (config, map) { - if ('ontouchstart' in document) { + if ("ontouchstart" in document) { map.touchscreen.show(); - } - else { + } else { map.touchscreen.hide(); } if (lib.device || lib.node) { map.auto_check_update.show(); - } - else { + } else { map.auto_check_update.hide(); } if (lib.device) { map.enable_vibrate.show(); map.keep_awake.show(); - } - else { + } else { map.enable_vibrate.hide(); map.keep_awake.hide(); } @@ -1133,15 +1302,13 @@ export class Library extends Uninstantable { map.swipe_down.show(); map.swipe_left.show(); map.swipe_right.show(); - } - else { + } else { map.swipe_up.hide(); map.swipe_down.hide(); map.swipe_left.hide(); map.swipe_right.hide(); } - } - else { + } else { map.mousewheel.show(); map.hover_all.show(); map.right_info.show(); @@ -1150,8 +1317,7 @@ export class Library extends Uninstantable { if (!config.hover_all) { map.hover_handcard.hide(); map.hoveration.hide(); - } - else { + } else { map.hover_handcard.show(); map.hoveration.show(); } @@ -1165,255 +1331,244 @@ export class Library extends Uninstantable { if (lib.config.touchscreen) { map.enable_dragline.hide(); map.enable_touchdragline.show(); - } - else { + } else { map.enable_dragline.show(); map.enable_touchdragline.hide(); } - } - else { + } else { map.enable_dragline.hide(); map.enable_touchdragline.hide(); } if (!get.is.phoneLayout()) { map.round_menu_func.hide(); - } - else { + } else { map.round_menu_func.show(); } - if (!lib.node && lib.device != 'ios') { + if (!lib.node && lib.device != "ios") { map.confirm_exit.show(); - } - else { + } else { map.confirm_exit.hide(); } if (config.dev) { map.errstop.show(); - } - else { + } else { map.errstop.hide(); } - } - } + }, + }, }, appearence: { - name: '外观', + name: "外观", config: { theme: { - name: '主题', - init: 'woodden', + name: "主题", + init: "woodden", item: {}, visualMenu: function (node, link) { if (!node.menu) { - node.className = 'button character themebutton ' + link; - node.menu = ui.create.div(node, '', '
                                    '); + node.className = "button character themebutton " + link; + node.menu = ui.create.div( + node, + "", + "
                                    " + ); } }, onclick: async (theme) => { - game.saveConfig('theme', theme); + game.saveConfig("theme", theme); ui.arena.hide(); lib.init.background(); if (lib.config.autostyle) { if (theme === "simple") { lib.configMenu.appearence.config.player_border.onclick("slim"); - } - else { + } else { lib.configMenu.appearence.config.player_border.onclick("normal"); } } lib.announce.publish("Noname.Apperaence.Theme.onChanging", theme); - await new Promise(resolve => setTimeout(resolve, 500)); + await new Promise((resolve) => setTimeout(resolve, 500)); const deletingTheme = ui.css.theme; - ui.css.theme = lib.init.css(lib.assetURL + 'theme/' + lib.config.theme, 'style'); + ui.css.theme = lib.init.css(lib.assetURL + "theme/" + lib.config.theme, "style"); deletingTheme.remove(); lib.announce.publish("Noname.Apperaence.Theme.onChanged", theme); - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise((resolve) => setTimeout(resolve, 100)); ui.arena.show(); lib.announce.publish("Noname.Apperaence.Theme.onChangeFinished", theme); - } + }, }, layout: { - name: '布局', - init: 'mobile', + name: "布局", + init: "mobile", item: { //default:'旧版', - newlayout: '对称', - mobile: '默认', - long: '宽屏', - long2: '手杀', - nova: '新版' + newlayout: "对称", + mobile: "默认", + long: "宽屏", + long2: "手杀", + nova: "新版", }, visualMenu: function (node, link) { - node.className = 'button character themebutton ' + lib.config.theme; + node.className = "button character themebutton " + lib.config.theme; if (!node.created) { node.created = true; - node.style.overflow = 'hidden'; - node.firstChild.style.display = 'none'; + node.style.overflow = "hidden"; + node.firstChild.style.display = "none"; // node.firstChild.classList.add('shadowed'); // node.firstChild.style.width='16px'; // node.firstChild.style.height='auto'; // node.firstChild.style.padding='2px'; // node.firstChild.style.textAlign='center'; var me = ui.create.div(node); - me.style.top = 'auto'; - if (link == 'default' || link == 'newlayout') { - me.style.width = 'calc(100% - 6px)'; - me.style.left = '3px'; - me.style.bottom = '3px'; - me.style.height = '25px'; - if (link == 'newlayout') { - me.style.height = '23px'; - me.style.bottom = '4px'; + me.style.top = "auto"; + if (link == "default" || link == "newlayout") { + me.style.width = "calc(100% - 6px)"; + me.style.left = "3px"; + me.style.bottom = "3px"; + me.style.height = "25px"; + if (link == "newlayout") { + me.style.height = "23px"; + me.style.bottom = "4px"; } + } else if (link == "long2" || link == "nova") { + me.style.display = "none"; + } else { + me.style.width = "120%"; + me.style.left = "-10%"; + me.style.bottom = "0"; + me.style.height = "22px"; } - else if (link == 'long2' || link == 'nova') { - me.style.display = 'none'; - } - else { - me.style.width = '120%'; - me.style.left = '-10%'; - me.style.bottom = '0'; - me.style.height = '22px'; - } - me.style.borderRadius = '2px'; - var list = ['re_caocao', 're_liubei', 'sp_zhangjiao', 'sunquan']; + me.style.borderRadius = "2px"; + var list = ["re_caocao", "re_liubei", "sp_zhangjiao", "sunquan"]; for (var i = 0; i < 4; i++) { - var player = ui.create.div('.fakeplayer', node); - ui.create.div('.avatar', player).setBackground(list.randomRemove(), 'character'); - player.style.borderRadius = '2px'; + var player = ui.create.div(".fakeplayer", node); + ui.create + .div(".avatar", player) + .setBackground(list.randomRemove(), "character"); + player.style.borderRadius = "2px"; if (i != 3) { - player.style.top = 'auto'; + player.style.top = "auto"; } - if (link == 'default') { - player.style.height = '19px'; - player.style.width = '38px'; - player.classList.add('oldlayout'); - } - else if (link == 'mobile' || link == 'newlayout') { - player.style.width = '24px'; - player.style.height = '29px'; - } - else if (link == 'nova') { - player.style.width = '20px'; - player.style.height = '24px'; - } - else { - player.style.width = '20px'; - player.style.height = '34px'; + if (link == "default") { + player.style.height = "19px"; + player.style.width = "38px"; + player.classList.add("oldlayout"); + } else if (link == "mobile" || link == "newlayout") { + player.style.width = "24px"; + player.style.height = "29px"; + } else if (link == "nova") { + player.style.width = "20px"; + player.style.height = "24px"; + } else { + player.style.width = "20px"; + player.style.height = "34px"; } if (i == 1) { - player.style.left = '3px'; + player.style.left = "3px"; } if (i == 2) { - player.style.left = 'auto'; - player.style.right = '3px'; + player.style.left = "auto"; + player.style.right = "3px"; } if (i == 3) { - player.style.top = '3px'; + player.style.top = "3px"; } - if (link == 'default') { + if (link == "default") { if (i == 0) { - player.style.bottom = '6px'; + player.style.bottom = "6px"; } if (i == 0 || i == 3) { - player.style.left = 'calc(50% - 18px)'; + player.style.left = "calc(50% - 18px)"; } if (i == 1 || i == 2) { - player.style.bottom = '36px'; + player.style.bottom = "36px"; } - } - else if (link == 'newlayout') { + } else if (link == "newlayout") { if (i == 0) { - player.style.bottom = '1px'; + player.style.bottom = "1px"; } if (i == 0 || i == 3) { - player.style.left = 'calc(50% - 12px)'; + player.style.left = "calc(50% - 12px)"; } if (i == 1 || i == 2) { - player.style.bottom = '32px'; + player.style.bottom = "32px"; } - } - else if (link == 'mobile') { + } else if (link == "mobile") { if (i == 0 || i == 3) { - player.style.left = 'calc(50% - 12px)'; + player.style.left = "calc(50% - 12px)"; } if (i == 1 || i == 2) { - player.style.bottom = '30px'; + player.style.bottom = "30px"; } - } - else if (link == 'long') { + } else if (link == "long") { if (i == 0 || i == 3) { - player.style.left = 'calc(50% - 10px)'; + player.style.left = "calc(50% - 10px)"; } if (i == 1 || i == 2) { - player.style.bottom = '45px'; + player.style.bottom = "45px"; } - } - else if (link == 'long2') { + } else if (link == "long2") { if (i == 0) { - player.style.bottom = '2px'; - player.style.left = '3px'; + player.style.bottom = "2px"; + player.style.left = "3px"; } if (i == 3) { - player.style.left = 'calc(50% - 10px)'; + player.style.left = "calc(50% - 10px)"; } if (i == 1 || i == 2) { - player.style.bottom = '45px'; + player.style.bottom = "45px"; } - } - else if (link == 'nova') { + } else if (link == "nova") { if (i == 0) { - player.style.bottom = '2px'; - player.style.left = '3px'; + player.style.bottom = "2px"; + player.style.left = "3px"; } if (i == 3) { - player.style.left = 'calc(50% - 10px)'; + player.style.left = "calc(50% - 10px)"; } if (i == 1 || i == 2) { - player.style.left = '3px'; - player.style.bottom = (i * 30) + 'px'; + player.style.left = "3px"; + player.style.bottom = i * 30 + "px"; } } - if (i == 0 && (link == 'mobile' || link == 'long')) { - player.classList.add('me'); - player.style.borderRadius = '0px'; - player.style.width = '25px'; - player.style.height = '25px'; - player.style.bottom = '-3px'; - player.style.left = '-3px'; + if (i == 0 && (link == "mobile" || link == "long")) { + player.classList.add("me"); + player.style.borderRadius = "0px"; + player.style.width = "25px"; + player.style.height = "25px"; + player.style.bottom = "-3px"; + player.style.left = "-3px"; } } } }, onclick(layout) { if (lib.layoutfixed.includes(lib.config.mode)) { - game.saveConfig('layout', layout); - } - else { + game.saveConfig("layout", layout); + } else { lib.init.layout(layout); } - } + }, }, splash_style: { - name: '启动页', - init: 'style1', + name: "启动页", + init: "style1", item: { - style1: '样式一', - style2: '样式二', + style1: "样式一", + style2: "样式二", }, visualMenu: (node, link) => { - node.className = 'button character'; - node.style.width = '200px'; - node.style.height = `${node.offsetWidth * 1080 / 2400}px`; - node.style.display = 'flex'; - node.style.flexDirection = 'column'; - node.style.alignItems = 'center'; - node.style.backgroundSize = '100% 100%'; + node.className = "button character"; + node.style.width = "200px"; + node.style.height = `${(node.offsetWidth * 1080) / 2400}px`; + node.style.display = "flex"; + node.style.flexDirection = "column"; + node.style.alignItems = "center"; + node.style.backgroundSize = "100% 100%"; node.setBackgroundImage(`image/splash/${link}.jpg`); - } + }, }, // fewplayer:{ // name:'启用人数', @@ -1435,30 +1590,30 @@ export class Library extends Uninstantable { // } // }, player_height: { - name: '角色高度', - init: 'long', + name: "角色高度", + init: "long", // unfrequent:true, item: { - short: '矮', - default: '中', - long: '高', + short: "矮", + default: "中", + long: "高", }, onclick(item) { - game.saveConfig('player_height', item); + game.saveConfig("player_height", item); ui.arena.dataset.player_height = item; - } + }, }, player_height_nova: { - name: '角色高度', - init: 'short', + name: "角色高度", + init: "short", item: { // auto:'自动', - short: '矮', - default: '中', - long: '高', + short: "矮", + default: "中", + long: "高", }, onclick(item) { - game.saveConfig('player_height_nova', item); + game.saveConfig("player_height_nova", item); // if(item=='auto'){ // if(parseInt(ui.arena.dataset.number)>=7){ // ui.arena.dataset.player_height_nova='short'; @@ -1470,7 +1625,7 @@ export class Library extends Uninstantable { // else{ ui.arena.dataset.player_height_nova = item; // } - } + }, }, // background_color_music:{ // name:'背景色', @@ -1509,65 +1664,85 @@ export class Library extends Uninstantable { // } // }, ui_zoom: { - name: '界面缩放', + name: "界面缩放", unfrequent: true, - init: 'normal', + init: "normal", item: { - esmall: '80%', - vsmall: '90%', - small: '95%', - normal: '100%', - big: '105%', - vbig: '110%', - ebig: '120%', - eebig: '150%', - eeebig: '180%', - eeeebig: '200%', + esmall: "80%", + vsmall: "90%", + small: "95%", + normal: "100%", + big: "105%", + vbig: "110%", + ebig: "120%", + eebig: "150%", + eeebig: "180%", + eeeebig: "200%", }, onclick(zoom) { - game.saveConfig('ui_zoom', zoom); + game.saveConfig("ui_zoom", zoom); switch (zoom) { - case 'esmall': zoom = 0.8; break; - case 'vsmall': zoom = 0.9; break; - case 'small': zoom = 0.93; break; - case 'big': zoom = 1.05; break; - case 'vbig': zoom = 1.1; break; - case 'ebig': zoom = 1.2; break; - case 'eebig': zoom = 1.5; break; - case 'eeebig': zoom = 1.8; break; - case 'eeeebig': zoom = 2; break; - default: zoom = 1; + case "esmall": + zoom = 0.8; + break; + case "vsmall": + zoom = 0.9; + break; + case "small": + zoom = 0.93; + break; + case "big": + zoom = 1.05; + break; + case "vbig": + zoom = 1.1; + break; + case "ebig": + zoom = 1.2; + break; + case "eebig": + zoom = 1.5; + break; + case "eeebig": + zoom = 1.8; + break; + case "eeeebig": + zoom = 2; + break; + default: + zoom = 1; } game.documentZoom = game.deviceZoom * zoom; ui.updatez(); if (Array.isArray(lib.onresize)) { - lib.onresize.forEach(fun => { - if (typeof fun == 'function') fun(); + lib.onresize.forEach((fun) => { + if (typeof fun == "function") fun(); }); } - } + }, }, image_background: { - name: '游戏背景', - init: 'default', + name: "游戏背景", + init: "default", item: {}, visualBar: function (node, item, create) { if (node.created) { - node.lastChild.classList.remove('active'); + node.lastChild.classList.remove("active"); return; } node.created = true; - ui.create.filediv('.menubutton', '添加背景', node, function (file) { + ui.create.filediv(".menubutton", "添加背景", node, function (file) { if (file) { var name = file.name; - if (name.includes('.')) { - name = name.slice(0, name.indexOf('.')); + if (name.includes(".")) { + name = name.slice(0, name.indexOf(".")); } - var link = (game.writeFile ? 'cdv_' : 'custom_') + name; + var link = (game.writeFile ? "cdv_" : "custom_") + name; if (item[link]) { for (var i = 1; i < 1000; i++) { - if (!item[link + '_' + i]) { - link = link + '_' + i; break; + if (!item[link + "_" + i]) { + link = link + "_" + i; + break; } } } @@ -1576,36 +1751,33 @@ export class Library extends Uninstantable { create(link, node.parentNode.defaultNode); node.parentNode.updateBr(); lib.config.customBackgroundPack.add(link); - game.saveConfig('customBackgroundPack', lib.config.customBackgroundPack); + game.saveConfig("customBackgroundPack", lib.config.customBackgroundPack); }; if (game.writeFile) { - game.writeFile(file, 'image/background', link + '.jpg', callback); + game.writeFile(file, "image/background", link + ".jpg", callback); + } else { + game.putDB("image", link, file, callback); } - else { - game.putDB('image', link, file, callback); - } - if (node.lastChild.classList.contains('active')) { + if (node.lastChild.classList.contains("active")) { editbg.call(node.lastChild); } } - }).inputNode.accept = 'image/*'; + }).inputNode.accept = "image/*"; var editbg = function () { - this.classList.toggle('active'); + this.classList.toggle("active"); var page = this.parentNode.parentNode; for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].classList.contains('button')) { + if (page.childNodes[i].classList.contains("button")) { var link = page.childNodes[i]._link; - if (link && link != 'default') { + if (link && link != "default") { var str; - if (this.classList.contains('active')) { - if (link.startsWith('custom_') || link.startsWith('cdv_')) { - str = '删除'; + if (this.classList.contains("active")) { + if (link.startsWith("custom_") || link.startsWith("cdv_")) { + str = "删除"; + } else { + str = "隐藏"; } - else { - str = '隐藏'; - } - } - else { + } else { str = item[link]; } page.childNodes[i].firstChild.innerHTML = get.verticalStr(str); @@ -1613,170 +1785,168 @@ export class Library extends Uninstantable { } } }; - ui.create.div('.menubutton', '编辑背景', node, editbg); + ui.create.div(".menubutton", "编辑背景", node, editbg); }, visualMenu: function (node, link, name, config) { - node.className = 'button character'; - node.style.backgroundImage = ''; - node.style.backgroundSize = ''; + node.className = "button character"; + node.style.backgroundImage = ""; + node.style.backgroundSize = ""; if (node.firstChild) { node.firstChild.innerHTML = get.verticalStr(name); } - if (link == 'default' || link.startsWith('custom_')) { - node.style.backgroundImage = 'none'; - node.classList.add('dashedmenubutton'); - if (link.startsWith('custom_')) { - game.getDB('image', link, function (fileToLoad) { + if (link == "default" || link.startsWith("custom_")) { + node.style.backgroundImage = "none"; + node.classList.add("dashedmenubutton"); + if (link.startsWith("custom_")) { + game.getDB("image", link, function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.style.backgroundSize = 'cover'; - node.classList.remove('dashedmenubutton'); + node.style.backgroundImage = "url(" + data + ")"; + node.style.backgroundSize = "cover"; + node.classList.remove("dashedmenubutton"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else { + } else { node.parentNode.defaultNode = node; } - } - else { - node.setBackgroundImage('image/background/' + link + '.jpg'); - node.style.backgroundSize = 'cover'; + } else { + node.setBackgroundImage("image/background/" + link + ".jpg"); + node.style.backgroundSize = "cover"; } }, onclick(background, node) { if (node && node.firstChild) { var menu = node.parentNode; - if (node.firstChild.innerHTML == get.verticalStr('隐藏')) { + if (node.firstChild.innerHTML == get.verticalStr("隐藏")) { menu.parentNode.noclose = true; node.remove(); menu.updateBr(); if (!lib.config.prompt_hidebg) { - alert('隐藏的背景可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidebg', true); + alert("隐藏的背景可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidebg", true); } lib.config.hiddenBackgroundPack.add(background); - game.saveConfig('hiddenBackgroundPack', lib.config.hiddenBackgroundPack); + game.saveConfig("hiddenBackgroundPack", lib.config.hiddenBackgroundPack); delete lib.configMenu.appearence.config.image_background.item[background]; if (lib.config.image_background == background) { - background = 'default'; - this.lastChild.innerHTML = '默认'; - } - else { - this.lastChild.innerHTML = lib.configMenu.appearence.config.image_background.item[lib.config.image_background]; + background = "default"; + this.lastChild.innerHTML = "默认"; + } else { + this.lastChild.innerHTML = + lib.configMenu.appearence.config.image_background.item[ + lib.config.image_background + ]; return; } - } - else if (node.firstChild.innerHTML == get.verticalStr('删除')) { + } else if (node.firstChild.innerHTML == get.verticalStr("删除")) { menu.parentNode.noclose = true; - if (confirm('是否删除此背景?(此操作不可撤销)')) { + if (confirm("是否删除此背景?(此操作不可撤销)")) { node.remove(); menu.updateBr(); lib.config.customBackgroundPack.remove(background); - game.saveConfig('customBackgroundPack', lib.config.customBackgroundPack); - if (background.startsWith('cdv_')) { - game.removeFile('image/background/' + background + '.jpg'); - } - else { - game.deleteDB('image', background); + game.saveConfig("customBackgroundPack", lib.config.customBackgroundPack); + if (background.startsWith("cdv_")) { + game.removeFile("image/background/" + background + ".jpg"); + } else { + game.deleteDB("image", background); } delete lib.configMenu.appearence.config.image_background.item[background]; if (lib.config.image_background == background) { - background = 'default'; - this.lastChild.innerHTML = '默认'; - } - else { - this.lastChild.innerHTML = lib.configMenu.appearence.config.image_background.item[lib.config.image_background]; + background = "default"; + this.lastChild.innerHTML = "默认"; + } else { + this.lastChild.innerHTML = + lib.configMenu.appearence.config.image_background.item[ + lib.config.image_background + ]; return; } } } } - game.saveConfig('image_background', background); + game.saveConfig("image_background", background); lib.init.background(); game.updateBackground(); }, }, image_background_random: { - name: '随机背景', + name: "随机背景", init: false, onclick(bool) { - game.saveConfig('image_background_random', bool); + game.saveConfig("image_background_random", bool); lib.init.background(); - } + }, }, image_background_blur: { - name: '背景模糊', + name: "背景模糊", init: false, onclick(bool) { - game.saveConfig('image_background_blur', bool); + game.saveConfig("image_background_blur", bool); if (lib.config.image_background_blur) { - ui.background.style.filter = 'blur(8px)'; - ui.background.style.webkitFilter = 'blur(8px)'; - ui.background.style.transform = 'scale(1.05)'; - } - else { - ui.background.style.filter = ''; - ui.background.style.webkitFilter = ''; - ui.background.style.transform = ''; + ui.background.style.filter = "blur(8px)"; + ui.background.style.webkitFilter = "blur(8px)"; + ui.background.style.transform = "scale(1.05)"; + } else { + ui.background.style.filter = ""; + ui.background.style.webkitFilter = ""; + ui.background.style.transform = ""; } }, }, phonelayout: { - name: '触屏布局', + name: "触屏布局", init: false, onclick(bool) { - if (get.is.nomenu('phonelayout', bool)) return false; - game.saveConfig('phonelayout', bool); + if (get.is.nomenu("phonelayout", bool)) return false; + game.saveConfig("phonelayout", bool); if (get.is.phoneLayout()) { - ui.css.phone.href = lib.assetURL + 'layout/default/phone.css'; - ui.arena.classList.add('phone'); + ui.css.phone.href = lib.assetURL + "layout/default/phone.css"; + ui.arena.classList.add("phone"); + } else { + ui.css.phone.href = ""; + ui.arena.classList.remove("phone"); } - else { - ui.css.phone.href = ''; - ui.arena.classList.remove('phone'); - } - } + }, }, change_skin: { - name: '开启换肤', + name: "开启换肤", init: true, - intro: '在武将的右键菜单中换肤,皮肤可在选项-文件-图片文件-皮肤图片中添加' + intro: "在武将的右键菜单中换肤,皮肤可在选项-文件-图片文件-皮肤图片中添加", }, change_skin_auto: { - name: '自动换肤', - init: 'off', + name: "自动换肤", + init: "off", item: { - 'off': '关闭', - '30000': '半分钟', - '60000': '一分钟', - '120000': '两分钟', - '300000': '五分钟', + off: "关闭", + 30000: "半分钟", + 60000: "一分钟", + 120000: "两分钟", + 300000: "五分钟", }, - intro: '游戏每进行一段时间自动为一个随机角色更换皮肤', + intro: "游戏每进行一段时间自动为一个随机角色更换皮肤", onclick(item) { - game.saveConfig('change_skin_auto', item); + game.saveConfig("change_skin_auto", item); clearTimeout(_status.skintimeout); - if (item != 'off') { + if (item != "off") { _status.skintimeout = setTimeout(ui.click.autoskin, parseInt(item)); } - } + }, }, card_style: { - name: '卡牌样式', - init: 'default', - intro: '设置正面朝上的卡牌的样式', + name: "卡牌样式", + init: "default", + intro: "设置正面朝上的卡牌的样式", item: { - wood: '木纹', - music: '音乐', - simple: '原版', - ol: '手杀', + wood: "木纹", + music: "音乐", + simple: "原版", + ol: "手杀", // new:'新版', - custom: '自定', - default: '默认', + custom: "自定", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -1784,7 +1954,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -1793,91 +1963,110 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'card_style', file, function () { - game.getDB('image', 'card_style', function (fileToLoad) { + game.putDB("image", "card_style", file, function () { + game.getDB("image", "card_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.className = 'button card fullskin'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.className = "button card fullskin"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'card_style'); - button.style.backgroundImage = 'none'; - button.className = 'button character dashedmenubutton'; - node.classList.remove('showdelete'); - if (lib.config.card_style == 'custom') { - lib.configMenu.appearence.config.card_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "card_style"); + button.style.backgroundImage = "none"; + button.className = "button character dashedmenubutton"; + node.classList.remove("showdelete"); + if (lib.config.card_style == "custom") { + lib.configMenu.appearence.config.card_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button card fullskin'; - node.style.backgroundSize = '100% 100%'; + node.className = "button card fullskin"; + node.style.backgroundSize = "100% 100%"; switch (link) { - case 'default': case 'custom': { - if (lib.config.theme == 'simple') { - node.style.backgroundImage = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; - node.className = 'button character'; - } - else { - node.style.backgroundImage = 'none'; - node.className = 'button character dashedmenubutton'; + case "default": + case "custom": { + if (lib.config.theme == "simple") { + node.style.backgroundImage = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + node.className = "button character"; + } else { + node.style.backgroundImage = "none"; + node.className = "button character dashedmenubutton"; } break; } - case 'new': node.setBackgroundImage('theme/style/card/image/new.png'); break; - case 'ol': node.setBackgroundImage('theme/style/card/image/ol.png'); break; - case 'wood': node.setBackgroundImage('theme/woodden/wood.jpg'); node.style.backgroundSize = 'initial'; break; - case 'music': node.setBackgroundImage('theme/music/wood3.png'); break; - case 'simple': node.setBackgroundImage('theme/simple/card.png'); break; + case "new": + node.setBackgroundImage("theme/style/card/image/new.png"); + break; + case "ol": + node.setBackgroundImage("theme/style/card/image/ol.png"); + break; + case "wood": + node.setBackgroundImage("theme/woodden/wood.jpg"); + node.style.backgroundSize = "initial"; + break; + case "music": + node.setBackgroundImage("theme/music/wood3.png"); + break; + case "simple": + node.setBackgroundImage("theme/simple/card.png"); + break; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'card_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "card_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.className = 'button card fullskin'; - node.parentNode.lastChild.classList.add('showdelete'); + node.style.backgroundImage = "url(" + data + ")"; + node.className = "button card fullskin"; + node.parentNode.lastChild.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick(layout) { - game.saveConfig('card_style', layout); + game.saveConfig("card_style", layout); var style = ui.css.card_style; - ui.css.card_style = lib.init.css(lib.assetURL + 'theme/style/card', lib.config.card_style); + ui.css.card_style = lib.init.css( + lib.assetURL + "theme/style/card", + lib.config.card_style + ); style.remove(); if (ui.css.card_stylesheet) { ui.css.card_stylesheet.remove(); delete ui.css.card_stylesheet; } - if (layout == 'custom') { - game.getDB('image', 'card_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "card_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.card_stylesheet) { ui.css.card_stylesheet.remove(); } - ui.css.card_stylesheet = lib.init.sheet('.card:not(*:empty){background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.card_stylesheet = lib.init.sheet( + ".card:not(*:empty){background-image:url(" + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); @@ -1886,19 +2075,19 @@ export class Library extends Uninstantable { unfrequent: true, }, cardback_style: { - name: '卡背样式', - intro: '设置背面朝上的卡牌的样式', - init: 'default', + name: "卡背样式", + intro: "设置背面朝上的卡牌的样式", + init: "default", item: { // wood:'木纹', // music:'音乐', - official: '原版', + official: "原版", // new:'新版', - feicheng: '废城', - liusha: '流沙', - ol: '手杀', - custom: '自定', - default: '默认', + feicheng: "废城", + liusha: "流沙", + ol: "手杀", + custom: "自定", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -1906,7 +2095,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -1915,75 +2104,103 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'cardback_style', file, function () { - game.getDB('image', 'cardback_style', function (fileToLoad) { + game.putDB("image", "cardback_style", file, function () { + game.getDB("image", "cardback_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.className = 'button character'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.className = "button character"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image/*'; - ui.create.filediv('.menubutton.deletebutton.addbutton', '添加翻转图片', node, function (file) { - if (file) { - game.putDB('image', 'cardback_style2', file, function () { - node.classList.add('hideadd'); - }); - } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'cardback_style'); - game.deleteDB('image', 'cardback_style2'); - button.style.backgroundImage = 'none'; - button.className = 'button character dashedmenubutton'; - node.classList.remove('showdelete'); - node.classList.remove('hideadd'); - if (lib.config.cardback_style == 'custom') { - lib.configMenu.appearence.config.cardback_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image/*"; + ui.create.filediv( + ".menubutton.deletebutton.addbutton", + "添加翻转图片", + node, + function (file) { + if (file) { + game.putDB("image", "cardback_style2", file, function () { + node.classList.add("hideadd"); + }); } - button.classList.add('transparent'); + } + ).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "cardback_style"); + game.deleteDB("image", "cardback_style2"); + button.style.backgroundImage = "none"; + button.className = "button character dashedmenubutton"; + node.classList.remove("showdelete"); + node.classList.remove("hideadd"); + if (lib.config.cardback_style == "custom") { + lib.configMenu.appearence.config.cardback_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; + } + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.style.backgroundSize = '100% 100%'; + node.style.backgroundSize = "100% 100%"; switch (link) { - case 'default': case 'custom': { - node.style.backgroundImage = 'none'; - node.className = 'button character dashedmenubutton'; + case "default": + case "custom": { + node.style.backgroundImage = "none"; + node.className = "button character dashedmenubutton"; break; } - case 'new': node.className = 'button character'; node.setBackgroundImage('theme/style/cardback/image/new.png'); break; - case 'feicheng': node.className = 'button character'; node.setBackgroundImage('theme/style/cardback/image/feicheng.png'); break; - case 'official': node.className = 'button character'; node.setBackgroundImage('theme/style/cardback/image/official.png'); break; - case 'liusha': node.className = 'button character'; node.setBackgroundImage('theme/style/cardback/image/liusha.png'); break; - case 'ol': node.className = 'button character'; node.setBackgroundImage('theme/style/cardback/image/ol.png'); break; - case 'wood': node.className = 'button card fullskin'; node.setBackgroundImage('theme/woodden/wood.jpg'); node.style.backgroundSize = 'initial'; break; - case 'music': node.className = 'button card fullskin'; node.setBackgroundImage('theme/music/wood3.png'); break; + case "new": + node.className = "button character"; + node.setBackgroundImage("theme/style/cardback/image/new.png"); + break; + case "feicheng": + node.className = "button character"; + node.setBackgroundImage("theme/style/cardback/image/feicheng.png"); + break; + case "official": + node.className = "button character"; + node.setBackgroundImage("theme/style/cardback/image/official.png"); + break; + case "liusha": + node.className = "button character"; + node.setBackgroundImage("theme/style/cardback/image/liusha.png"); + break; + case "ol": + node.className = "button character"; + node.setBackgroundImage("theme/style/cardback/image/ol.png"); + break; + case "wood": + node.className = "button card fullskin"; + node.setBackgroundImage("theme/woodden/wood.jpg"); + node.style.backgroundSize = "initial"; + break; + case "music": + node.className = "button card fullskin"; + node.setBackgroundImage("theme/music/wood3.png"); + break; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'cardback_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "cardback_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.className = 'button character'; - node.parentNode.lastChild.classList.add('showdelete'); - game.getDB('image', 'cardback_style2', function (file) { + node.style.backgroundImage = "url(" + data + ")"; + node.className = "button character"; + node.parentNode.lastChild.classList.add("showdelete"); + game.getDB("image", "cardback_style2", function (file) { if (file) { - node.parentNode.lastChild.classList.add('hideadd'); + node.parentNode.lastChild.classList.add("hideadd"); } }); }; @@ -1992,9 +2209,12 @@ export class Library extends Uninstantable { } }, onclick(layout) { - game.saveConfig('cardback_style', layout); + game.saveConfig("cardback_style", layout); var style = ui.css.cardback_style; - ui.css.cardback_style = lib.init.css(lib.assetURL + 'theme/style/cardback', lib.config.cardback_style); + ui.css.cardback_style = lib.init.css( + lib.assetURL + "theme/style/cardback", + lib.config.cardback_style + ); style.remove(); if (ui.css.cardback_stylesheet) { ui.css.cardback_stylesheet.remove(); @@ -2004,23 +2224,31 @@ export class Library extends Uninstantable { ui.css.cardback_stylesheet2.remove(); delete ui.css.cardback_stylesheet2; } - if (layout == 'custom') { - game.getDB('image', 'cardback_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "cardback_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.cardback_stylesheet) { ui.css.cardback_stylesheet.remove(); } - ui.css.cardback_stylesheet = lib.init.sheet('.card:empty,.card.infohidden{background-image:url(' + fileLoadedEvent.target.result + ')}'); - game.getDB('image', 'cardback_style2', function (fileToLoad) { + ui.css.cardback_stylesheet = lib.init.sheet( + ".card:empty,.card.infohidden{background-image:url(" + + fileLoadedEvent.target.result + + ")}" + ); + game.getDB("image", "cardback_style2", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.cardback_stylesheet2) { ui.css.cardback_stylesheet2.remove(); } - ui.css.cardback_stylesheet2 = lib.init.sheet('.card.infohidden:not(.infoflip){background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.cardback_stylesheet2 = lib.init.sheet( + ".card.infohidden:not(.infoflip){background-image:url(" + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); @@ -2032,18 +2260,18 @@ export class Library extends Uninstantable { unfrequent: true, }, hp_style: { - name: '体力条样式', - init: 'ol', + name: "体力条样式", + init: "ol", item: { - default: '默认', + default: "默认", // official:'勾玉', - emotion: '表情', - glass: '勾玉', - round: '国战', - ol: '手杀', - xinglass: '双鱼', - xinround: 'OL', - custom: '自定', + emotion: "表情", + glass: "勾玉", + round: "国战", + ol: "手杀", + xinglass: "双鱼", + xinround: "OL", + custom: "自定", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -2051,7 +2279,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -2060,21 +2288,22 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton.addbutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton.addbutton", "添加图片", node, function (file) { if (file && node.currentDB) { - game.putDB('image', 'hp_style' + node.currentDB, file, function () { - game.getDB('image', 'hp_style' + node.currentDB, function (fileToLoad) { + game.putDB("image", "hp_style" + node.currentDB, file, function () { + game.getDB("image", "hp_style" + node.currentDB, function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.childNodes[node.currentDB - 1].style.backgroundImage = 'url(' + data + ')'; - button.classList.add('shown'); - node.classList.add('showdelete'); + button.childNodes[node.currentDB - 1].style.backgroundImage = + "url(" + data + ")"; + button.classList.add("shown"); + node.classList.add("showdelete"); node.currentDB++; if (node.currentDB > 4) { - node.classList.add('hideadd'); - button.classList.remove('transparent'); + node.classList.add("hideadd"); + button.classList.remove("transparent"); delete node.currentDB; } }; @@ -2082,61 +2311,59 @@ export class Library extends Uninstantable { }); }); } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'hp_style1'); - game.deleteDB('image', 'hp_style2'); - game.deleteDB('image', 'hp_style3'); - game.deleteDB('image', 'hp_style4'); + }).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "hp_style1"); + game.deleteDB("image", "hp_style2"); + game.deleteDB("image", "hp_style3"); + game.deleteDB("image", "hp_style4"); for (var i = 0; i < button.childElementCount; i++) { - button.childNodes[i].style.backgroundImage = 'none'; + button.childNodes[i].style.backgroundImage = "none"; } - node.classList.remove('showdelete'); - node.classList.remove('hideadd'); - if (lib.config.hp_style == 'custom') { - lib.configMenu.appearence.config.hp_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + node.classList.remove("showdelete"); + node.classList.remove("hideadd"); + if (lib.config.hp_style == "custom") { + lib.configMenu.appearence.config.hp_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); - button.classList.remove('shown'); + button.classList.add("transparent"); + button.classList.remove("shown"); node.currentDB = 1; } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button hpbutton dashedmenubutton'; - node.innerHTML = ''; + node.className = "button hpbutton dashedmenubutton"; + node.innerHTML = ""; for (var i = 1; i <= 4; i++) { var div = ui.create.div(node); - if (link == 'default') { + if (link == "default") { ui.create.div(div); - } - else if (link != 'custom') { - div.setBackgroundImage('theme/style/hp/image/' + link + i + '.png'); + } else if (link != "custom") { + div.setBackgroundImage("theme/style/hp/image/" + link + i + ".png"); } if (i == 4) { - div.style.webkitFilter = 'grayscale(1)'; + div.style.webkitFilter = "grayscale(1)"; } } - if (link == 'custom') { - node.classList.add('transparent'); + if (link == "custom") { + node.classList.add("transparent"); var getDB = function (num) { node.parentNode.lastChild.currentDB = num; - game.getDB('image', 'hp_style' + num, function (fileToLoad) { + game.getDB("image", "hp_style" + num, function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.childNodes[num - 1].style.backgroundImage = 'url(' + data + ')'; - node.classList.add('shown'); - node.parentNode.lastChild.classList.add('showdelete'); + node.childNodes[num - 1].style.backgroundImage = "url(" + data + ")"; + node.classList.add("shown"); + node.parentNode.lastChild.classList.add("showdelete"); if (num < 4) { getDB(num + 1); - } - else { - node.parentNode.lastChild.classList.add('hideadd'); - node.classList.remove('transparent'); + } else { + node.parentNode.lastChild.classList.add("hideadd"); + node.classList.remove("transparent"); delete node.parentNode.firstChild.currentDB; } }; @@ -2147,9 +2374,9 @@ export class Library extends Uninstantable { } }, onclick(layout) { - game.saveConfig('hp_style', layout); + game.saveConfig("hp_style", layout); var style = ui.css.hp_style; - ui.css.hp_style = lib.init.css(lib.assetURL + 'theme/style/hp', lib.config.hp_style); + ui.css.hp_style = lib.init.css(lib.assetURL + "theme/style/hp", lib.config.hp_style); style.remove(); if (ui.css.hp_stylesheet1) { ui.css.hp_stylesheet1.remove(); @@ -2167,48 +2394,64 @@ export class Library extends Uninstantable { ui.css.hp_stylesheet4.remove(); delete ui.css.hp_stylesheet4; } - if (layout == 'custom') { - game.getDB('image', 'hp_style1', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "hp_style1", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.hp_stylesheet1) { ui.css.hp_stylesheet1.remove(); } - ui.css.hp_stylesheet1 = lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.hp_stylesheet1 = lib.init.sheet( + '.hp:not(.text):not(.actcount)[data-condition="high"]>div:not(.lost){background-image:url(' + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - game.getDB('image', 'hp_style2', function (fileToLoad) { + game.getDB("image", "hp_style2", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.hp_stylesheet2) { ui.css.hp_stylesheet2.remove(); } - ui.css.hp_stylesheet2 = lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.hp_stylesheet2 = lib.init.sheet( + '.hp:not(.text):not(.actcount)[data-condition="mid"]>div:not(.lost){background-image:url(' + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - game.getDB('image', 'hp_style3', function (fileToLoad) { + game.getDB("image", "hp_style3", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.hp_stylesheet3) { ui.css.hp_stylesheet3.remove(); } - ui.css.hp_stylesheet3 = lib.init.sheet('.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.hp_stylesheet3 = lib.init.sheet( + '.hp:not(.text):not(.actcount)[data-condition="low"]>div:not(.lost){background-image:url(' + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - game.getDB('image', 'hp_style4', function (fileToLoad) { + game.getDB("image", "hp_style4", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.hp_stylesheet4) { ui.css.hp_stylesheet4.remove(); } - ui.css.hp_stylesheet4 = lib.init.sheet('.hp:not(.text):not(.actcount)>.lost{background-image:url(' + fileLoadedEvent.target.result + ')}'); + ui.css.hp_stylesheet4 = lib.init.sheet( + ".hp:not(.text):not(.actcount)>.lost{background-image:url(" + + fileLoadedEvent.target.result + + ")}" + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); @@ -2217,15 +2460,15 @@ export class Library extends Uninstantable { unfrequent: true, }, player_style: { - name: '角色背景', - init: 'default', - intro: '设置角色的背景图片', + name: "角色背景", + init: "default", + intro: "设置角色的背景图片", item: { - wood: '木纹', - music: '音乐', - simple: '简约', - custom: '自定', - default: '默认', + wood: "木纹", + music: "音乐", + simple: "简约", + custom: "自定", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -2233,7 +2476,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -2242,113 +2485,132 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'player_style', file, function () { - game.getDB('image', 'player_style', function (fileToLoad) { + game.putDB("image", "player_style", file, function () { + game.getDB("image", "player_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.className = 'button character'; - button.style.backgroundSize = '100% 100%'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.className = "button character"; + button.style.backgroundSize = "100% 100%"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'player_style'); - button.style.backgroundImage = 'none'; - button.className = 'button character dashedmenubutton'; - node.classList.remove('showdelete'); - if (lib.config.player_style == 'custom') { - lib.configMenu.appearence.config.player_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "player_style"); + button.style.backgroundImage = "none"; + button.className = "button character dashedmenubutton"; + node.classList.remove("showdelete"); + if (lib.config.player_style == "custom") { + lib.configMenu.appearence.config.player_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button character'; - node.style.backgroundSize = ''; - node.style.height = '108px'; + node.className = "button character"; + node.style.backgroundSize = ""; + node.style.height = "108px"; switch (link) { - case 'default': case 'custom': { - node.style.backgroundImage = 'none'; - node.className = 'button character dashedmenubutton'; + case "default": + case "custom": { + node.style.backgroundImage = "none"; + node.className = "button character dashedmenubutton"; break; } - case 'wood': node.setBackgroundImage('theme/woodden/wood.jpg'); break; - case 'music': node.style.backgroundImage = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': node.style.backgroundImage = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; + case "wood": + node.setBackgroundImage("theme/woodden/wood.jpg"); + break; + case "music": + node.style.backgroundImage = "linear-gradient(#4b4b4b, #464646)"; + break; + case "simple": + node.style.backgroundImage = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + break; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'player_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "player_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.className = 'button character'; - node.parentNode.lastChild.classList.add('showdelete'); - node.style.backgroundSize = '100% 100%'; + node.style.backgroundImage = "url(" + data + ")"; + node.className = "button character"; + node.parentNode.lastChild.classList.add("showdelete"); + node.style.backgroundSize = "100% 100%"; }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick(layout) { - game.saveConfig('player_style', layout); + game.saveConfig("player_style", layout); if (ui.css.player_stylesheet) { ui.css.player_stylesheet.remove(); delete ui.css.player_stylesheet; } - if (layout == 'custom') { - game.getDB('image', 'player_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "player_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.player_stylesheet) { ui.css.player_stylesheet.remove(); } - ui.css.player_stylesheet = lib.init.sheet('#window .player{background-image:url("' + fileLoadedEvent.target.result + '");background-size:100% 100%;}'); + ui.css.player_stylesheet = lib.init.sheet( + '#window .player{background-image:url("' + + fileLoadedEvent.target.result + + '");background-size:100% 100%;}' + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else if (layout != 'default') { - var str = ''; + } else if (layout != "default") { + var str = ""; switch (layout) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; + break; + case "music": + str = "linear-gradient(#4b4b4b, #464646)"; + break; + case "simple": + str = "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + break; } - ui.css.player_stylesheet = lib.init.sheet('#window .player{background-image:' + str + '}'); + ui.css.player_stylesheet = lib.init.sheet( + "#window .player{background-image:" + str + "}" + ); } }, unfrequent: true, }, border_style: { - name: '角色边框', - init: 'default', - intro: '设置角色边框的样式,当设为自动时,样式将随着一局游戏中伤害或击杀的数量自动改变', + name: "角色边框", + init: "default", + intro: "设置角色边框的样式,当设为自动时,样式将随着一局游戏中伤害或击杀的数量自动改变", item: { - gold: '金框', - silver: '银框', - bronze: '铜框', - dragon_gold: '金龙', - dragon_silver: '银龙', - dragon_bronze: '玉龙', - custom: '自定', - auto: '自动', - default: '默认', + gold: "金框", + silver: "银框", + bronze: "铜框", + dragon_gold: "金龙", + dragon_silver: "银龙", + dragon_bronze: "玉龙", + custom: "自定", + auto: "自动", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -2356,7 +2618,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -2365,79 +2627,78 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'border_style', file, function () { - game.getDB('image', 'border_style', function (fileToLoad) { + game.putDB("image", "border_style", file, function () { + game.getDB("image", "border_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.className = 'button character'; - button.style.backgroundSize = '100% 100%'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.className = "button character"; + button.style.backgroundSize = "100% 100%"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'border_style'); - button.style.backgroundImage = 'none'; - button.className = 'button character dashedmenubutton'; - node.classList.remove('showdelete'); - if (lib.config.border_style == 'custom') { - lib.configMenu.appearence.config.border_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "border_style"); + button.style.backgroundImage = "none"; + button.className = "button character dashedmenubutton"; + node.classList.remove("showdelete"); + if (lib.config.border_style == "custom") { + lib.configMenu.appearence.config.border_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button character'; - node.style.backgroundSize = ''; - node.style.height = '108px'; - node.dataset.decoration = ''; - if (link == 'default' || link == 'custom' || link == 'auto') { - node.style.backgroundImage = 'none'; - node.className = 'button character dashedmenubutton'; - } - else { - if (link.startsWith('dragon_')) { + node.className = "button character"; + node.style.backgroundSize = ""; + node.style.height = "108px"; + node.dataset.decoration = ""; + if (link == "default" || link == "custom" || link == "auto") { + node.style.backgroundImage = "none"; + node.className = "button character dashedmenubutton"; + } else { + if (link.startsWith("dragon_")) { link = link.slice(7); node.dataset.decoration = link; } - node.setBackgroundImage('theme/style/player/' + link + '1.png'); - node.style.backgroundSize = '100% 100%'; + node.setBackgroundImage("theme/style/player/" + link + "1.png"); + node.style.backgroundSize = "100% 100%"; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'border_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "border_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.className = 'button character'; - node.parentNode.lastChild.classList.add('showdelete'); - node.style.backgroundSize = '100% 100%'; + node.style.backgroundImage = "url(" + data + ")"; + node.className = "button character"; + node.parentNode.lastChild.classList.add("showdelete"); + node.style.backgroundSize = "100% 100%"; }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick(layout) { - game.saveConfig('border_style', layout); + game.saveConfig("border_style", layout); if (ui.css.border_stylesheet) { ui.css.border_stylesheet.remove(); delete ui.css.border_stylesheet; } - if (layout == 'custom') { - game.getDB('image', 'border_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "border_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { @@ -2446,98 +2707,121 @@ export class Library extends Uninstantable { } ui.css.border_stylesheet = lib.init.sheet(); ui.css.border_stylesheet.id = "ui.css.border"; - ui.css.border_stylesheet.sheet.insertRule('#window .player>.framebg{display:block;background-image:url("' + fileLoadedEvent.target.result + '")}', 0); - ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); + ui.css.border_stylesheet.sheet.insertRule( + '#window .player>.framebg{display:block;background-image:url("' + + fileLoadedEvent.target.result + + '")}', + 0 + ); + ui.css.border_stylesheet.sheet.insertRule( + ".player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}", + 0 + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else if (layout != 'default' && layout != 'auto') { + } else if (layout != "default" && layout != "auto") { ui.css.border_stylesheet = lib.init.sheet(); - if (layout.startsWith('dragon_')) { + if (layout.startsWith("dragon_")) { layout = layout.slice(7); ui.arena.dataset.framedecoration = layout; + } else { + ui.arena.dataset.framedecoration = ""; } - else { - ui.arena.dataset.framedecoration = ''; - } - ui.css.border_stylesheet.sheet.insertRule('#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + lib.assetURL + 'theme/style/player/' + layout + '1.png")}', 0); - ui.css.border_stylesheet.sheet.insertRule('#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + lib.assetURL + 'theme/style/player/' + layout + '3.png")}', 0); - ui.css.border_stylesheet.sheet.insertRule('.player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}', 0); + ui.css.border_stylesheet.sheet.insertRule( + '#window .player>.framebg,#window #arena.long.mobile:not(.fewplayer) .player[data-position="0"]>.framebg{display:block;background-image:url("' + + lib.assetURL + + "theme/style/player/" + + layout + + '1.png")}', + 0 + ); + ui.css.border_stylesheet.sheet.insertRule( + '#window #arena.long:not(.fewplayer) .player>.framebg, #arena.oldlayout .player>.framebg{background-image:url("' + + lib.assetURL + + "theme/style/player/" + + layout + + '3.png")}', + 0 + ); + ui.css.border_stylesheet.sheet.insertRule( + ".player>.count{z-index: 3 !important;border-radius: 2px !important;text-align: center !important;}", + 0 + ); } }, unfrequent: true, }, autoborder_count: { - name: '边框升级方式', - intro: '击杀 每击杀一人,边框提升两级
                                    伤害 每造成两点伤害,边框提升一级
                                    混合 击杀量决定边框颜色,伤害量决定边框装饰', - init: 'kill', + name: "边框升级方式", + intro: "击杀 每击杀一人,边框提升两级
                                    伤害 每造成两点伤害,边框提升一级
                                    混合 击杀量决定边框颜色,伤害量决定边框装饰", + init: "kill", item: { - kill: '击杀', - damage: '伤害', - mix: '混合', + kill: "击杀", + damage: "伤害", + mix: "混合", }, unfrequent: true, }, autoborder_start: { - name: '基础边框颜色', - init: 'bronze', + name: "基础边框颜色", + init: "bronze", item: { - bronze: '铜', - silver: '银', - gold: '金' + bronze: "铜", + silver: "银", + gold: "金", }, - unfrequent: true + unfrequent: true, }, player_border: { - name: '边框宽度', - init: 'normal', - intro: '设置角色的边框宽度', + name: "边框宽度", + init: "normal", + intro: "设置角色的边框宽度", unfrequent: true, item: { - slim: '细', - narrow: '窄', - normal: '中', - wide: '宽' + slim: "细", + narrow: "窄", + normal: "中", + wide: "宽", }, onclick(item) { - game.saveConfig('player_border', item); - if (item != 'wide' || game.layout == 'long' || game.layout == 'long2') { - ui.arena.classList.add('slim_player'); + game.saveConfig("player_border", item); + if (item != "wide" || game.layout == "long" || game.layout == "long2") { + ui.arena.classList.add("slim_player"); + } else { + ui.arena.classList.remove("slim_player"); } - else { - ui.arena.classList.remove('slim_player'); + if (item == "slim") { + ui.arena.classList.add("uslim_player"); + } else { + ui.arena.classList.remove("uslim_player"); } - if (item == 'slim') { - ui.arena.classList.add('uslim_player'); + if (item == "narrow") { + ui.arena.classList.add("mslim_player"); + } else { + ui.arena.classList.remove("mslim_player"); } - else { - ui.arena.classList.remove('uslim_player'); - } - if (item == 'narrow') { - ui.arena.classList.add('mslim_player'); - } - else { - ui.arena.classList.remove('mslim_player'); - } - if (item == 'normal' && lib.config.mode != 'brawl' && (game.layout == 'long' || game.layout == 'long2')) { - ui.arena.classList.add('lslim_player'); - } - else { - ui.arena.classList.remove('lslim_player'); + if ( + item == "normal" && + lib.config.mode != "brawl" && + (game.layout == "long" || game.layout == "long2") + ) { + ui.arena.classList.add("lslim_player"); + } else { + ui.arena.classList.remove("lslim_player"); } ui.window.dataset.player_border = item; - } + }, }, menu_style: { - name: '菜单背景', - init: 'default', + name: "菜单背景", + init: "default", item: { - wood: '木纹', - music: '音乐', - simple: '简约', - custom: '自定', - default: '默认', + wood: "木纹", + music: "音乐", + simple: "简约", + custom: "自定", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -2545,7 +2829,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -2554,108 +2838,131 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'menu_style', file, function () { - game.getDB('image', 'menu_style', function (fileToLoad) { + game.putDB("image", "menu_style", file, function () { + game.getDB("image", "menu_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.style.backgroundSize = 'cover'; - button.className = 'button character'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.style.backgroundSize = "cover"; + button.className = "button character"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'menu_style'); - button.style.backgroundImage = 'none'; - button.style.backgroundSize = 'auto'; - button.className = 'button character dashedmenubutton'; - node.classList.remove('showdelete'); - if (lib.config.menu_style == 'custom') { - lib.configMenu.appearence.config.menu_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "menu_style"); + button.style.backgroundImage = "none"; + button.style.backgroundSize = "auto"; + button.className = "button character dashedmenubutton"; + node.classList.remove("showdelete"); + if (lib.config.menu_style == "custom") { + lib.configMenu.appearence.config.menu_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button character'; - node.style.backgroundSize = 'auto'; + node.className = "button character"; + node.style.backgroundSize = "auto"; switch (link) { - case 'default': case 'custom': { - node.style.backgroundImage = 'none'; - node.classList.add('dashedmenubutton'); + case "default": + case "custom": { + node.style.backgroundImage = "none"; + node.classList.add("dashedmenubutton"); break; } - case 'wood': node.setBackgroundImage('theme/woodden/wood2.png'); break; - case 'music': node.style.backgroundImage = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': node.style.backgroundImage = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; + case "wood": + node.setBackgroundImage("theme/woodden/wood2.png"); + break; + case "music": + node.style.backgroundImage = "linear-gradient(#4b4b4b, #464646)"; + break; + case "simple": + node.style.backgroundImage = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + break; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'menu_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "menu_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.style.backgroundSize = 'cover'; - node.className = 'button character'; - node.parentNode.lastChild.classList.add('showdelete'); + node.style.backgroundImage = "url(" + data + ")"; + node.style.backgroundSize = "cover"; + node.className = "button character"; + node.parentNode.lastChild.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick(layout) { - game.saveConfig('menu_style', layout); + game.saveConfig("menu_style", layout); if (ui.css.menu_stylesheet) { ui.css.menu_stylesheet.remove(); delete ui.css.menu_stylesheet; } - if (layout == 'custom') { - game.getDB('image', 'menu_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "menu_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.menu_stylesheet) { ui.css.menu_stylesheet.remove(); } - ui.css.menu_stylesheet = lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:url("' + fileLoadedEvent.target.result + '");background-size:cover}'); + ui.css.menu_stylesheet = lib.init.sheet( + 'html #window>.dialog.popped,html .menu,html .menubg{background-image:url("' + + fileLoadedEvent.target.result + + '");background-size:cover}' + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else if (layout != 'default') { - var str = ''; + } else if (layout != "default") { + var str = ""; switch (layout) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood2.png")'; + break; + case "music": + str = + "linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px"; + break; + case "simple": + str = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px"; + break; } - ui.css.menu_stylesheet = lib.init.sheet('html #window>.dialog.popped,html .menu,html .menubg{background-image:' + str + '}'); + ui.css.menu_stylesheet = lib.init.sheet( + "html #window>.dialog.popped,html .menu,html .menubg{background-image:" + + str + + "}" + ); } }, unfrequent: true, }, control_style: { - name: '按钮背景', - init: 'default', + name: "按钮背景", + init: "default", item: { - wood: '木纹', - music: '音乐', - simple: '简约', - custom: '自定', - default: '默认', + wood: "木纹", + music: "音乐", + simple: "简约", + custom: "自定", + default: "默认", }, visualBar: function (node, item, create, switcher) { if (node.created) { @@ -2663,7 +2970,7 @@ export class Library extends Uninstantable { } var button; for (var i = 0; i < node.parentNode.childElementCount; i++) { - if (node.parentNode.childNodes[i]._link == 'custom') { + if (node.parentNode.childNodes[i]._link == "custom") { button = node.parentNode.childNodes[i]; } } @@ -2672,108 +2979,134 @@ export class Library extends Uninstantable { } node.created = true; var deletepic; - ui.create.filediv('.menubutton', '添加图片', node, function (file) { + ui.create.filediv(".menubutton", "添加图片", node, function (file) { if (file) { - game.putDB('image', 'control_style', file, function () { - game.getDB('image', 'control_style', function (fileToLoad) { + game.putDB("image", "control_style", file, function () { + game.getDB("image", "control_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - button.style.backgroundImage = 'url(' + data + ')'; - button.className = 'button character controlbutton'; - node.classList.add('showdelete'); + button.style.backgroundImage = "url(" + data + ")"; + button.className = "button character controlbutton"; + node.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); }); } - }).inputNode.accept = 'image/*'; - deletepic = ui.create.div('.menubutton.deletebutton', '删除图片', node, function () { - if (confirm('确定删除自定义图片?(此操作不可撤销)')) { - game.deleteDB('image', 'control_style'); - button.style.backgroundImage = 'none'; - button.className = 'button character controlbutton dashedmenubutton'; - node.classList.remove('showdelete'); - if (lib.config.control_style == 'custom') { - lib.configMenu.appearence.config.control_style.onclick('default'); - switcher.lastChild.innerHTML = '默认'; + }).inputNode.accept = "image/*"; + deletepic = ui.create.div(".menubutton.deletebutton", "删除图片", node, function () { + if (confirm("确定删除自定义图片?(此操作不可撤销)")) { + game.deleteDB("image", "control_style"); + button.style.backgroundImage = "none"; + button.className = "button character controlbutton dashedmenubutton"; + node.classList.remove("showdelete"); + if (lib.config.control_style == "custom") { + lib.configMenu.appearence.config.control_style.onclick("default"); + switcher.lastChild.innerHTML = "默认"; } - button.classList.add('transparent'); + button.classList.add("transparent"); } }); }, visualMenu: function (node, link, name, config) { - node.className = 'button character controlbutton'; - node.style.backgroundSize = ''; + node.className = "button character controlbutton"; + node.style.backgroundSize = ""; switch (link) { - case 'default': case 'custom': { - node.style.backgroundImage = 'none'; - node.classList.add('dashedmenubutton'); + case "default": + case "custom": { + node.style.backgroundImage = "none"; + node.classList.add("dashedmenubutton"); break; } - case 'wood': node.setBackgroundImage('theme/woodden/wood.jpg'); break; - case 'music': node.style.backgroundImage = 'linear-gradient(#4b4b4b, #464646)'; break; - case 'simple': node.style.backgroundImage = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))'; break; + case "wood": + node.setBackgroundImage("theme/woodden/wood.jpg"); + break; + case "music": + node.style.backgroundImage = "linear-gradient(#4b4b4b, #464646)"; + break; + case "simple": + node.style.backgroundImage = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4))"; + break; } - if (link == 'custom') { - node.classList.add('transparent'); - game.getDB('image', 'control_style', function (fileToLoad) { + if (link == "custom") { + node.classList.add("transparent"); + game.getDB("image", "control_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - node.style.backgroundImage = 'url(' + data + ')'; - node.className = 'button character controlbutton'; - node.parentNode.lastChild.classList.add('showdelete'); + node.style.backgroundImage = "url(" + data + ")"; + node.className = "button character controlbutton"; + node.parentNode.lastChild.classList.add("showdelete"); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); } }, onclick(layout) { - game.saveConfig('control_style', layout); + game.saveConfig("control_style", layout); if (ui.css.control_stylesheet) { ui.css.control_stylesheet.remove(); delete ui.css.control_stylesheet; } - if (layout == 'custom') { - game.getDB('image', 'control_style', function (fileToLoad) { + if (layout == "custom") { + game.getDB("image", "control_style", function (fileToLoad) { if (!fileToLoad) return; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { if (ui.css.control_stylesheet) { ui.css.control_stylesheet.remove(); } - ui.css.control_stylesheet = lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("' + fileLoadedEvent.target.result + '")}'); + ui.css.control_stylesheet = lib.init.sheet( + '#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:url("' + + fileLoadedEvent.target.result + + '")}' + ); }; fileReader.readAsDataURL(fileToLoad, "UTF-8"); }); - } - else if (layout != 'default') { - var str = ''; + } else if (layout != "default") { + var str = ""; switch (layout) { - case 'wood': str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; break; - case 'music': str = 'linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px'; break; - case 'simple': str = 'linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px'; break; + case "wood": + str = 'url("' + lib.assetURL + 'theme/woodden/wood.jpg")'; + break; + case "music": + str = + "linear-gradient(#4b4b4b, #464646);color:white;text-shadow:black 0 0 2px"; + break; + case "simple": + str = + "linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4));color:white;text-shadow:black 0 0 2px"; + break; } - if (layout == 'wood') { - ui.css.control_stylesheet = lib.init.sheet('#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:' + str + '}'); - } - else { - ui.css.control_stylesheet = lib.init.sheet('#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:' + str + '}'); + if (layout == "wood") { + ui.css.control_stylesheet = lib.init.sheet( + "#window .control,#window .menubutton,#window #system>div>div,#window #system>div>.pressdown2{background-image:" + + str + + "}" + ); + } else { + ui.css.control_stylesheet = lib.init.sheet( + "#window .control,.menubutton:not(.active):not(.highlight):not(.red):not(.blue),#window #system>div>div{background-image:" + + str + + "}" + ); } } }, unfrequent: true, }, custom_button: { - name: '自定义按钮高度', + name: "自定义按钮高度", init: false, unfrequent: true, onclick(bool) { - if (bool !== 'skip') { - game.saveConfig('custom_button', bool); + if (bool !== "skip") { + game.saveConfig("custom_button", bool); } if (ui.css.buttonsheet) { ui.css.buttonsheet.remove(); @@ -2794,269 +3127,278 @@ export class Library extends Uninstantable { cbnum4 = 0; } ui.css.buttonsheet = lib.init.sheet( - '#system>div>div, .caption>div>.tdnode{padding-top:' + cbnum1 + 'px !important;padding-bottom:' + cbnum2 + 'px !important}', - '#control>.control>div{padding-top:' + cbnum3 + 'px;padding-bottom:' + cbnum4 + 'px}', - '#control>.control{padding-top:' + cbnum5 + 'px;padding-bottom:' + cbnum6 + 'px}' + "#system>div>div, .caption>div>.tdnode{padding-top:" + + cbnum1 + + "px !important;padding-bottom:" + + cbnum2 + + "px !important}", + "#control>.control>div{padding-top:" + + cbnum3 + + "px;padding-bottom:" + + cbnum4 + + "px}", + "#control>.control{padding-top:" + + cbnum5 + + "px;padding-bottom:" + + cbnum6 + + "px}" ); } - } + }, }, custom_button_system_top: { - name: '菜单上部高度', - init: '0x', + name: "菜单上部高度", + init: "0x", item: { - '-5x': '-5px', - '-4x': '-4px', - '-3x': '-3px', - '-2x': '-2px', - '-1x': '-1px', - '0x': '默认', - '1x': '1px', - '2x': '2px', - '3x': '3px', - '4x': '4px', - '5x': '5px', + "-5x": "-5px", + "-4x": "-4px", + "-3x": "-3px", + "-2x": "-2px", + "-1x": "-1px", + "0x": "默认", + "1x": "1px", + "2x": "2px", + "3x": "3px", + "4x": "4px", + "5x": "5px", }, unfrequent: true, onclick(item) { - game.saveConfig('custom_button_system_top', item); - lib.configMenu.appearence.config.custom_button.onclick('skip'); - } + game.saveConfig("custom_button_system_top", item); + lib.configMenu.appearence.config.custom_button.onclick("skip"); + }, }, custom_button_system_bottom: { - name: '菜单下部高度', - init: '0x', + name: "菜单下部高度", + init: "0x", item: { - '-5x': '-5px', - '-4x': '-4px', - '-3x': '-3px', - '-2x': '-2px', - '-1x': '-1px', - '0x': '默认', - '1x': '1px', - '2x': '2px', - '3x': '3px', - '4x': '4px', - '5x': '5px', + "-5x": "-5px", + "-4x": "-4px", + "-3x": "-3px", + "-2x": "-2px", + "-1x": "-1px", + "0x": "默认", + "1x": "1px", + "2x": "2px", + "3x": "3px", + "4x": "4px", + "5x": "5px", }, unfrequent: true, onclick(item) { - game.saveConfig('custom_button_system_bottom', item); - lib.configMenu.appearence.config.custom_button.onclick('skip'); - } + game.saveConfig("custom_button_system_bottom", item); + lib.configMenu.appearence.config.custom_button.onclick("skip"); + }, }, custom_button_control_top: { - name: '技能上部高度', - init: '0x', + name: "技能上部高度", + init: "0x", item: { - '-5x': '-5px', - '-4x': '-4px', - '-3x': '-3px', - '-2x': '-2px', - '-1x': '-1px', - '0x': '默认', - '1x': '1px', - '2x': '2px', - '3x': '3px', - '4x': '4px', - '5x': '5px', + "-5x": "-5px", + "-4x": "-4px", + "-3x": "-3px", + "-2x": "-2px", + "-1x": "-1px", + "0x": "默认", + "1x": "1px", + "2x": "2px", + "3x": "3px", + "4x": "4px", + "5x": "5px", }, unfrequent: true, onclick(item) { - game.saveConfig('custom_button_control_top', item); - lib.configMenu.appearence.config.custom_button.onclick('skip'); - } + game.saveConfig("custom_button_control_top", item); + lib.configMenu.appearence.config.custom_button.onclick("skip"); + }, }, custom_button_control_bottom: { - name: '技能下部高度', - init: '0x', + name: "技能下部高度", + init: "0x", item: { - '-5x': '-5px', - '-4x': '-4px', - '-3x': '-3px', - '-2x': '-2px', - '-1x': '-1px', - '0x': '默认', - '1x': '1px', - '2x': '2px', - '3x': '3px', - '4x': '4px', - '5x': '5px', + "-5x": "-5px", + "-4x": "-4px", + "-3x": "-3px", + "-2x": "-2px", + "-1x": "-1px", + "0x": "默认", + "1x": "1px", + "2x": "2px", + "3x": "3px", + "4x": "4px", + "5x": "5px", }, unfrequent: true, onclick(item) { - game.saveConfig('custom_button_control_bottom', item); - lib.configMenu.appearence.config.custom_button.onclick('skip'); - } + game.saveConfig("custom_button_control_bottom", item); + lib.configMenu.appearence.config.custom_button.onclick("skip"); + }, }, radius_size: { - name: '圆角大小', - init: 'default', + name: "圆角大小", + init: "default", item: { - off: '关闭', - reduce: '减小', - default: '默认', - increase: '增大', + off: "关闭", + reduce: "减小", + default: "默认", + increase: "增大", }, unfrequent: true, onclick(item) { - game.saveConfig('radius_size', item); + game.saveConfig("radius_size", item); ui.window.dataset.radius_size = item; - } + }, }, glow_phase: { - name: '当前回合角色高亮', + name: "当前回合角色高亮", unfrequent: true, - init: 'yellow', - intro: '设置当前回合角色的边框颜色', + init: "yellow", + intro: "设置当前回合角色的边框颜色", item: { - none: '无', - yellow: '黄色', - green: '绿色', - purple: '紫色', + none: "无", + yellow: "黄色", + green: "绿色", + purple: "紫色", }, onclick(bool) { - game.saveConfig('glow_phase', bool); + game.saveConfig("glow_phase", bool); lib.init.cssstyles(); - } + }, }, equip_span: { - name: '装备牌占位', - intro: '打开后,没有装备的装备区将在装备栏占据空白位置。', + name: "装备牌占位", + intro: "打开后,没有装备的装备区将在装备栏占据空白位置。", init: false, unfrequent: false, }, fold_card: { - name: '折叠手牌', + name: "折叠手牌", init: true, unfrequent: true, }, fold_mode: { - name: '折叠模式菜单', - intro: '关闭后模式菜单中“更多”内的项目将直接展开', + name: "折叠模式菜单", + intro: "关闭后模式菜单中“更多”内的项目将直接展开", init: true, unfrequent: true, }, seperate_control: { - name: '分离选项条', + name: "分离选项条", init: true, unfrequent: true, - intro: '开启后玩家在进行选择时不同的选项将分开,而不是连在一起', + intro: "开启后玩家在进行选择时不同的选项将分开,而不是连在一起", }, blur_ui: { - name: '模糊效果', - intro: '在暂停或打开菜单时开启模糊效果', + name: "模糊效果", + intro: "在暂停或打开菜单时开启模糊效果", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('blur_ui', bool); + game.saveConfig("blur_ui", bool); if (bool) { - ui.window.classList.add('blur_ui'); + ui.window.classList.add("blur_ui"); + } else { + ui.window.classList.remove("blur_ui"); } - else { - ui.window.classList.remove('blur_ui'); - } - } + }, }, glass_ui: { - name: '玻璃主题', - intro: '为游戏主题打开玻璃效果(手机暂不支持)', + name: "玻璃主题", + intro: "为游戏主题打开玻璃效果(手机暂不支持)", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('glass_ui', bool); + game.saveConfig("glass_ui", bool); if (bool) { - ui.window.classList.add('glass_ui'); + ui.window.classList.add("glass_ui"); + } else { + ui.window.classList.remove("glass_ui"); } - else { - ui.window.classList.remove('glass_ui'); - } - } + }, }, damage_shake: { - name: '伤害抖动', - intro: '角色受到伤害时的抖动效果', + name: "伤害抖动", + intro: "角色受到伤害时的抖动效果", init: true, unfrequent: true, }, button_press: { - name: '按钮效果', - intro: '选项条被按下时将有按下效果', + name: "按钮效果", + intro: "选项条被按下时将有按下效果", init: true, unfrequent: true, }, jiu_effect: { - name: '喝酒效果', + name: "喝酒效果", init: true, unfrequent: true, }, animation: { - name: '游戏特效', - intro: '开启后出现属性伤害、回复体力等情况时会显示动画', + name: "游戏特效", + intro: "开启后出现属性伤害、回复体力等情况时会显示动画", init: false, unfrequent: true, }, skill_animation_type: { - name: '技能特效', - intro: '开启后觉醒技、限定技将显示全屏文字', - init: 'default', + name: "技能特效", + intro: "开启后觉醒技、限定技将显示全屏文字", + init: "default", unfrequent: true, item: { - default: '默认', - old: '旧版', - off: '关闭' - } + default: "默认", + old: "旧版", + off: "关闭", + }, }, die_move: { - name: '阵亡效果', - intro: '阵亡后武将的显示效果', - init: 'flip', + name: "阵亡效果", + intro: "阵亡后武将的显示效果", + init: "flip", unfrequent: true, item: { - off: '关闭', - move: '移动', - flip: '翻面', - } + off: "关闭", + move: "移动", + flip: "翻面", + }, }, target_shake: { - name: '目标效果', - intro: '一名玩家成为卡牌或技能的目标时的显示效果', - init: 'off', + name: "目标效果", + intro: "一名玩家成为卡牌或技能的目标时的显示效果", + init: "off", item: { - off: '关闭', - zoom: '缩放', - shake: '抖动', + off: "关闭", + zoom: "缩放", + shake: "抖动", }, unfrequent: true, onclick(bool) { - game.saveConfig('target_shake', bool); + game.saveConfig("target_shake", bool); ui.arena.dataset.target_shake = bool; - } + }, }, turned_style: { - name: '翻面文字', - intro: '角色被翻面时显示“翻面”', + name: "翻面文字", + intro: "角色被翻面时显示“翻面”", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('turned_style', bool); + game.saveConfig("turned_style", bool); if (bool) { - ui.arena.classList.remove('hide_turned'); + ui.arena.classList.remove("hide_turned"); + } else { + ui.arena.classList.add("hide_turned"); } - else { - ui.arena.classList.add('hide_turned'); - } - } + }, }, link_style2: { - name: '横置样式', - intro: '设置角色被横置时的样式', - init: 'chain', + name: "横置样式", + intro: "设置角色被横置时的样式", + init: "chain", unfrequent: true, item: { - chain: '铁索', - rotate: '横置', - mark: '标记' + chain: "铁索", + rotate: "横置", + mark: "标记", }, onclick(style) { var list = []; @@ -3065,82 +3407,84 @@ export class Library extends Uninstantable { list.push(game.players[i]); } } - game.saveConfig('link_style2', style); + game.saveConfig("link_style2", style); for (var i = 0; i < list.length; i++) { if (get.is.linked2(list[i])) { - list[i].classList.add('linked2'); - list[i].classList.remove('linked'); - } - else { - list[i].classList.add('linked'); - list[i].classList.remove('linked2'); + list[i].classList.add("linked2"); + list[i].classList.remove("linked"); + } else { + list[i].classList.add("linked"); + list[i].classList.remove("linked2"); } } - if (style == 'chain') { - ui.arena.classList.remove('nolink'); - } - else { - ui.arena.classList.add('nolink'); + if (style == "chain") { + ui.arena.classList.remove("nolink"); + } else { + ui.arena.classList.add("nolink"); } ui.updatem(); - } + }, }, cardshape: { - name: '手牌显示', - intro: '将手牌设置为正方形或长方形', - init: 'default', + name: "手牌显示", + intro: "将手牌设置为正方形或长方形", + init: "default", unfrequent: true, item: { - default: '默认', - oblong: '长方', + default: "默认", + oblong: "长方", }, onclick(item) { var linked = false; if (game.me && game.me.isLinked()) { linked = true; } - game.saveConfig('cardshape', item); - if (item == 'oblong' && (game.layout == 'long' || game.layout == 'mobile' || game.layout == 'long2' || game.layout == 'nova')) { - ui.arena.classList.add('oblongcard'); - ui.window.classList.add('oblongcard'); - } - else { - ui.arena.classList.remove('oblongcard'); - ui.window.classList.remove('oblongcard'); + game.saveConfig("cardshape", item); + if ( + item == "oblong" && + (game.layout == "long" || + game.layout == "mobile" || + game.layout == "long2" || + game.layout == "nova") + ) { + ui.arena.classList.add("oblongcard"); + ui.window.classList.add("oblongcard"); + } else { + ui.arena.classList.remove("oblongcard"); + ui.window.classList.remove("oblongcard"); } if (linked) { if (get.is.linked2(game.me)) { - game.me.classList.remove('linked'); - game.me.classList.add('linked2'); - } - else { - game.me.classList.add('linked'); - game.me.classList.remove('linked2'); + game.me.classList.remove("linked"); + game.me.classList.add("linked2"); + } else { + game.me.classList.add("linked"); + game.me.classList.remove("linked2"); } } - } + }, }, cardtempname: { - name: '视为卡牌名称显示', - intro: '显示强制视为类卡牌(如武魂),包括拆顺对话框内的判定牌(国色)转换等名称的显示方式', - init: 'image', + name: "视为卡牌名称显示", + intro: "显示强制视为类卡牌(如武魂),包括拆顺对话框内的判定牌(国色)转换等名称的显示方式", + init: "image", unfrequent: true, item: { - default: '纵向', - horizon: '横向', - image: '图片', - off: '禁用', + default: "纵向", + horizon: "横向", + image: "图片", + off: "禁用", }, onclick(item) { - game.saveConfig('cardtempname', item); + game.saveConfig("cardtempname", item); if (!game.me || !game.me.getCards) return; - var hs = game.me.getCards('h'); + var hs = game.me.getCards("h"); for (var i = 0; i < hs.length; i++) { if (hs[i]._tempName) { switch (item) { - case 'default': - case 'horizon': - case 'image': + case "default": + case "horizon": + case "image": ui.create.cardTempName(hs[i]); break; default: @@ -3149,7 +3493,7 @@ export class Library extends Uninstantable { } } } - } + }, }, /*textequip:{ name:'装备显示', @@ -3170,119 +3514,118 @@ export class Library extends Uninstantable { } },*/ buttoncharacter_style: { - name: '选将样式', - init: 'default', + name: "选将样式", + init: "default", item: { - default: '默认', - simple: '精简', - old: '旧版' + default: "默认", + simple: "精简", + old: "旧版", }, unfrequent: true, }, buttoncharacter_prefix: { - name: '武将前缀', - init: 'default', + name: "武将前缀", + init: "default", item: { - default: '默认', - simple: '不显示颜色', - off: '不显示前缀' + default: "默认", + simple: "不显示颜色", + off: "不显示前缀", }, unfrequent: true, }, cursor_style: { - name: '鼠标指针', - init: 'auto', - intro: '设置为固定后鼠标指针将不随移动到的区域而变化', + name: "鼠标指针", + init: "auto", + intro: "设置为固定后鼠标指针将不随移动到的区域而变化", unfrequent: true, item: { - auto: '自动', - pointer: '固定' + auto: "自动", + pointer: "固定", }, onclick(item) { - game.saveConfig('cursor_style', item); - if (item == 'pointer') { - ui.window.classList.add('nopointer'); + game.saveConfig("cursor_style", item); + if (item == "pointer") { + ui.window.classList.add("nopointer"); + } else { + ui.window.classList.remove("nopointer"); } - else { - ui.window.classList.remove('nopointer'); - } - } + }, }, name_font: { - name: '人名字体', - init: 'xingkai', + name: "人名字体", + init: "xingkai", unfrequent: true, item: {}, textMenu: function (node, link) { - if (link != 'default') { + if (link != "default") { node.style.fontFamily = link; } - node.style.fontSize = '20px'; + node.style.fontSize = "20px"; }, onclick(font) { - game.saveConfig('name_font', font); + game.saveConfig("name_font", font); lib.init.cssstyles(); - } + }, }, identity_font: { - name: '身份字体', - init: 'huangcao', + name: "身份字体", + init: "huangcao", unfrequent: true, item: {}, textMenu: function (node, link) { - if (link != 'default') { + if (link != "default") { node.style.fontFamily = link; } - node.style.fontSize = '20px'; + node.style.fontSize = "20px"; }, onclick(font) { - game.saveConfig('identity_font', font); + game.saveConfig("identity_font", font); lib.init.cssstyles(); - } + }, }, cardtext_font: { - name: '卡牌字体', - init: 'default', + name: "卡牌字体", + init: "default", unfrequent: true, item: {}, textMenu: function (node, link) { - if (link != 'default') { + if (link != "default") { node.style.fontFamily = link; } - node.style.fontSize = '20px'; + node.style.fontSize = "20px"; }, onclick(font) { - game.saveConfig('cardtext_font', font); + game.saveConfig("cardtext_font", font); lib.init.cssstyles(); - } + }, }, global_font: { - name: '界面字体', - init: 'default', + name: "界面字体", + init: "default", unfrequent: true, item: {}, textMenu: function (node, link) { - if (link != 'default') { + if (link != "default") { node.style.fontFamily = link; + } else { + node.style.fontFamily = + "'STHeiti','SimHei','Microsoft JhengHei','Microsoft YaHei','WenQuanYi Micro Hei','Suits',Helvetica,Arial,sans-serif"; } - else { - node.style.fontFamily = "'STHeiti','SimHei','Microsoft JhengHei','Microsoft YaHei','WenQuanYi Micro Hei','Suits',Helvetica,Arial,sans-serif"; - } - node.style.fontSize = '20px'; + node.style.fontSize = "20px"; }, onclick(font) { - game.saveConfig('global_font', font); + game.saveConfig("global_font", font); lib.init.cssstyles(); - } + }, }, suits_font: { - name: '替换花色字体', + name: "替换花色字体", init: true, unfrequent: true, - intro: '使用全角字符的花色替代系统自带的花色(重启游戏后生效)', + intro: "使用全角字符的花色替代系统自带的花色(重启游戏后生效)", onclick(bool) { - game.saveConfig('suits_font', bool); - } + game.saveConfig("suits_font", bool); + }, }, update: function (config, map) { if (lib.config.custom_button) { @@ -3290,8 +3633,7 @@ export class Library extends Uninstantable { map.custom_button_system_bottom.show(); map.custom_button_control_top.show(); map.custom_button_control_bottom.show(); - } - else { + } else { map.custom_button_system_top.hide(); map.custom_button_system_bottom.hide(); map.custom_button_control_top.hide(); @@ -3299,21 +3641,18 @@ export class Library extends Uninstantable { } if (lib.config.change_skin) { map.change_skin_auto.show(); - } - else { + } else { map.change_skin_auto.hide(); } if (lib.config.image_background_random) { map.image_background_blur.show(); map.image_background.hide(); // map.import_background.hide(); - } - else { + } else { map.image_background.show(); - if (lib.config.image_background == 'default') { + if (lib.config.image_background == "default") { map.image_background_blur.hide(); - } - else { + } else { map.image_background_blur.show(); } // if(lib.config.image_background=='custom'&&lib.db){ @@ -3323,80 +3662,75 @@ export class Library extends Uninstantable { // map.import_background.hide(); // } } - if (lib.config.layout == 'long' || lib.config.layout == 'mobile') { + if (lib.config.layout == "long" || lib.config.layout == "mobile") { //map.textequip.show(); map.cardshape.show(); map.phonelayout.show(); - } - else { + } else { //map.textequip.hide(); - if (lib.config.layout == 'long2' || lib.config.layout == 'nova') { + if (lib.config.layout == "long2" || lib.config.layout == "nova") { map.phonelayout.show(); map.cardshape.show(); - } - else { + } else { map.phonelayout.hide(); map.cardshape.hide(); } } - if (lib.config.layout == 'long') { + if (lib.config.layout == "long") { // map.fewplayer.show(); map.player_height.show(); - } - else { + } else { // map.fewplayer.hide(); - if (lib.config.layout == 'long2') { + if (lib.config.layout == "long2") { map.player_height.show(); - } - else { + } else { map.player_height.hide(); } } - if (lib.config.layout == 'nova') { + if (lib.config.layout == "nova") { map.player_height_nova.show(); - } - else { + } else { map.player_height_nova.hide(); } if (lib.config.touchscreen) { map.cursor_style.hide(); - } - else { + } else { map.cursor_style.show(); } - if (lib.config.border_style == 'auto') { + if (lib.config.border_style == "auto") { map.autoborder_count.show(); map.autoborder_start.show(); - } - else { + } else { map.autoborder_count.hide(); map.autoborder_start.hide(); } }, - } + }, }, view: { - name: '显示', + name: "显示", config: { update: function (config, map) { - if (lib.config.mode == 'versus' || lib.config.mode == 'chess' || lib.config.mode == 'tafang' || lib.config.mode == 'boss') { + if ( + lib.config.mode == "versus" || + lib.config.mode == "chess" || + lib.config.mode == "tafang" || + lib.config.mode == "boss" + ) { map.show_handcardbutton.show(); - } - else { + } else { map.show_handcardbutton.hide(); } if (lib.config.touchscreen) { map.pop_logv.hide(); - } - else { + } else { map.pop_logv.show(); } if (lib.device) { - if (lib.device == 'android') { + if (lib.device == "android") { map.show_statusbar_android.show(); map.show_statusbar_ios.hide(); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { map.show_statusbar_ios.show(); map.show_statusbar_android.hide(); } @@ -3407,8 +3741,7 @@ export class Library extends Uninstantable { } }, 5000); } - } - else { + } else { map.show_statusbar_ios.hide(); map.show_statusbar_android.hide(); } @@ -3420,8 +3753,7 @@ export class Library extends Uninstantable { map.show_auto.hide(); map.show_replay.hide(); map.show_round_menu.show(); - } - else { + } else { map.show_pause.show(); map.show_auto.show(); map.show_replay.show(); @@ -3433,15 +3765,13 @@ export class Library extends Uninstantable { if (lib.config.show_card_prompt) { map.hide_card_prompt_basic.show(); map.hide_card_prompt_equip.show(); - } - else { + } else { map.hide_card_prompt_basic.hide(); map.hide_card_prompt_equip.hide(); } - if (lib.config.show_log != 'off') { + if (lib.config.show_log != "off") { map.clear_log.show(); - } - else { + } else { map.clear_log.hide(); } if (get.is.phoneLayout()) { @@ -3449,641 +3779,622 @@ export class Library extends Uninstantable { map.show_time.hide(); if (lib.config.show_time2) { map.watchface.show(); - } - else { + } else { map.watchface.hide(); } - } - else { + } else { map.show_time2.hide(); map.show_time.show(); map.watchface.hide(); } if (lib.config.show_extensionmaker) { map.show_extensionshare.show(); - } - else { + } else { map.show_extensionshare.hide(); } }, show_history: { - name: '出牌记录栏', - init: 'off', - intro: '在屏幕左侧或右侧显示出牌记录', + name: "出牌记录栏", + init: "off", + intro: "在屏幕左侧或右侧显示出牌记录", unfrequent: true, item: { - off: '关闭', - left: '靠左', - right: '靠右', + off: "关闭", + left: "靠左", + right: "靠右", }, onclick(bool) { - if (lib.config.show_history == 'right') ui.window.addTempClass('rightbar2'); - game.saveConfig('show_history', bool); + if (lib.config.show_history == "right") ui.window.addTempClass("rightbar2"); + game.saveConfig("show_history", bool); if (_status.video || !_status.prepareArena) return; - if (bool == 'left') { - ui.window.classList.add('leftbar'); - ui.window.classList.remove('rightbar'); + if (bool == "left") { + ui.window.classList.add("leftbar"); + ui.window.classList.remove("rightbar"); + } else if (bool == "right") { + ui.window.classList.remove("leftbar"); + ui.window.classList.add("rightbar"); + } else { + ui.window.classList.remove("leftbar"); + ui.window.classList.remove("rightbar"); } - else if (bool == 'right') { - ui.window.classList.remove('leftbar'); - ui.window.classList.add('rightbar'); - } - else { - ui.window.classList.remove('leftbar'); - ui.window.classList.remove('rightbar'); - } - } + }, }, pop_logv: { - name: '自动弹出记录', + name: "自动弹出记录", init: false, - unfrequent: true + unfrequent: true, }, show_log: { - name: '历史记录栏', - init: 'off', - intro: '在屏幕中部显示出牌文字记录', + name: "历史记录栏", + init: "off", + intro: "在屏幕中部显示出牌文字记录", unfrequent: true, item: { - off: '关闭', - left: '靠左', - center: '居中', - right: '靠右', + off: "关闭", + left: "靠左", + center: "居中", + right: "靠右", }, onclick(bool) { - game.saveConfig('show_log', bool); - if (lib.config.show_log != 'off') { - ui.arenalog.style.display = ''; + game.saveConfig("show_log", bool); + if (lib.config.show_log != "off") { + ui.arenalog.style.display = ""; ui.arenalog.dataset.position = bool; + } else { + ui.arenalog.style.display = "none"; + ui.arenalog.innerHTML = ""; } - else { - ui.arenalog.style.display = 'none'; - ui.arenalog.innerHTML = ''; - } - } + }, }, clear_log: { - name: '自动清除历史记录', + name: "自动清除历史记录", init: false, unfrequent: true, - intro: '开启后将定时清除历史记录栏的条目(而不是等记录栏满后再清除)' + intro: "开启后将定时清除历史记录栏的条目(而不是等记录栏满后再清除)", }, log_highlight: { - name: '历史记录高亮', + name: "历史记录高亮", init: true, unfrequent: true, - intro: '开启后历史记录不同类别的信息将以不同颜色显示', + intro: "开启后历史记录不同类别的信息将以不同颜色显示", }, show_time: { - name: '显示时间', - intro: '在屏幕顶部显示当前时间', + name: "显示时间", + intro: "在屏幕顶部显示当前时间", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_time', bool); + game.saveConfig("show_time", bool); if (bool) { - ui.time.style.display = ''; + ui.time.style.display = ""; + } else { + ui.time.style.display = "none"; } - else { - ui.time.style.display = 'none'; - } - } + }, }, show_time2: { - name: '显示时间', - intro: '在触屏按钮处显示当前时间', + name: "显示时间", + intro: "在触屏按钮处显示当前时间", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_time2', bool); + game.saveConfig("show_time2", bool); if (bool) { - ui.roundmenu.classList.add('clock'); + ui.roundmenu.classList.add("clock"); + } else { + ui.roundmenu.classList.remove("clock"); } - else { - ui.roundmenu.classList.remove('clock'); - } - } + }, }, watchface: { - name: '表盘样式', - init: 'none', + name: "表盘样式", + init: "none", unfrequent: true, item: { - none: '默认', - simple: '简约', + none: "默认", + simple: "简约", }, onclick(item) { - game.saveConfig('watchface', item); + game.saveConfig("watchface", item); ui.roundmenu.dataset.watchface = item; - } + }, }, show_time3: { - name: '显示游戏时间', + name: "显示游戏时间", init: false, - unfrequent: true + unfrequent: true, }, show_statusbar_android: { - name: '显示状态栏', + name: "显示状态栏", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_statusbar', bool); - if (window.StatusBar && lib.device == 'android') { + game.saveConfig("show_statusbar", bool); + if (window.StatusBar && lib.device == "android") { if (bool) { window.StatusBar.overlaysWebView(false); - window.StatusBar.backgroundColorByName('black'); + window.StatusBar.backgroundColorByName("black"); window.StatusBar.show(); - } - else { + } else { window.StatusBar.hide(); } } - } + }, }, show_statusbar_ios: { - name: '显示状态栏', - init: 'off', + name: "显示状态栏", + init: "off", unfrequent: true, item: { - default: '默认', - overlay: '嵌入', - auto: '自动', - off: '关闭' + default: "默认", + overlay: "嵌入", + auto: "自动", + off: "关闭", }, onclick(bool) { - game.saveConfig('show_statusbar_ios', bool); - if (window.StatusBar && lib.device == 'ios') { - if (bool != 'off' && bool != 'auto') { - if (lib.config.show_statusbar_ios == 'default') { + game.saveConfig("show_statusbar_ios", bool); + if (window.StatusBar && lib.device == "ios") { + if (bool != "off" && bool != "auto") { + if (lib.config.show_statusbar_ios == "default") { window.StatusBar.overlaysWebView(false); - document.body.classList.remove('statusbar'); - } - else { + document.body.classList.remove("statusbar"); + } else { window.StatusBar.overlaysWebView(true); - document.body.classList.add('statusbar'); + document.body.classList.add("statusbar"); } - window.StatusBar.backgroundColorByName('black'); + window.StatusBar.backgroundColorByName("black"); window.StatusBar.show(); - } - else { - document.body.classList.remove('statusbar'); + } else { + document.body.classList.remove("statusbar"); window.StatusBar.hide(); } } - } + }, }, show_card_prompt: { - name: '显示出牌信息', - intro: '出牌时在使用者上显示卡牌名称', + name: "显示出牌信息", + intro: "出牌时在使用者上显示卡牌名称", init: true, unfrequent: true, }, hide_card_prompt_basic: { - name: '隐藏基本牌信息', - intro: '不显示基本牌名称', + name: "隐藏基本牌信息", + intro: "不显示基本牌名称", init: false, unfrequent: true, }, hide_card_prompt_equip: { - name: '隐藏装备牌信息', - intro: '不显示装备牌名称', + name: "隐藏装备牌信息", + intro: "不显示装备牌名称", init: false, unfrequent: true, }, show_phase_prompt: { - name: '显示阶段信息', - intro: '在当前回合不同阶段开始时显示阶段名称', + name: "显示阶段信息", + intro: "在当前回合不同阶段开始时显示阶段名称", init: true, unfrequent: true, }, show_phaseuse_prompt: { - name: '出牌阶段提示', - intro: '在你出牌时显示提示文字', + name: "出牌阶段提示", + intro: "在你出牌时显示提示文字", init: true, unfrequent: true, }, auto_popped_config: { - name: '自动弹出选项', - intro: '鼠标移至选项按钮时弹出模式选择菜单', + name: "自动弹出选项", + intro: "鼠标移至选项按钮时弹出模式选择菜单", init: true, unfrequent: true, }, auto_popped_history: { - name: '自动弹出历史', - intro: '鼠标移至暂停按钮时弹出历史记录菜单', + name: "自动弹出历史", + intro: "鼠标移至暂停按钮时弹出历史记录菜单", init: false, unfrequent: true, }, show_round_menu: { - name: '显示触屏按钮', + name: "显示触屏按钮", init: true, unfrequent: true, onclick(bool) { - if (get.is.nomenu('show_round_menu', bool)) return false; - game.saveConfig('show_round_menu', bool); + if (get.is.nomenu("show_round_menu", bool)) return false; + game.saveConfig("show_round_menu", bool); if (bool && ui.roundmenu) { - ui.roundmenu.style.display = ''; + ui.roundmenu.style.display = ""; + } else { + ui.roundmenu.style.display = "none"; + alert("关闭触屏按钮后可通过手势打开菜单(默认为下划)"); } - else { - ui.roundmenu.style.display = 'none'; - alert('关闭触屏按钮后可通过手势打开菜单(默认为下划)'); - } - } + }, }, remember_round_button: { - name: '记住按钮位置', - intro: '重新开始后触屏按钮将保存的上一局的位置', + name: "记住按钮位置", + intro: "重新开始后触屏按钮将保存的上一局的位置", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('remember_round_button', bool); + game.saveConfig("remember_round_button", bool); if (!bool) { ui.click.resetround(); } - } + }, }, remember_dialog: { - name: '记住对话框位置', - intro: '移动对话框后新的对话框也将在移动后的位置显示', + name: "记住对话框位置", + intro: "移动对话框后新的对话框也将在移动后的位置显示", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('remember_dialog', bool); + game.saveConfig("remember_dialog", bool); if (!bool) { if (ui.dialog) { var dialog = ui.dialog; - dialog.style.transform = ''; + dialog.style.transform = ""; dialog._dragtransform = [0, 0]; - dialog.style.transition = 'all 0.3s'; + dialog.style.transition = "all 0.3s"; dialog._dragtouches; dialog._dragorigin; dialog._dragorigintransform; setTimeout(function () { - dialog.style.transition = ''; + dialog.style.transition = ""; }, 500); } - game.saveConfig('dialog_transform', [0, 0]); + game.saveConfig("dialog_transform", [0, 0]); } - } + }, }, transparent_dialog: { - name: '堆叠对话框虚化', + name: "堆叠对话框虚化", init: false, - intro: '当具有static属性的对话框堆叠(如五谷丰登对话框中提示无懈可击)时,将后方的对话框变为半透明', + intro: "当具有static属性的对话框堆叠(如五谷丰登对话框中提示无懈可击)时,将后方的对话框变为半透明", onclick(bool) { - game.saveConfig('transparent_dialog', bool); + game.saveConfig("transparent_dialog", bool); if (bool) { for (var i = 0; i < ui.dialogs.length; i++) { if (ui.dialogs[i] != ui.dialog && ui.dialogs[i].static) { ui.dialogs[i].unfocus(); } } - } - else { + } else { for (var i = 0; i < ui.dialogs.length; i++) { if (ui.dialogs[i] != ui.dialog && ui.dialogs[i].static) { ui.dialogs[i].refocus(); } } } - } + }, }, show_rarity: { - name: '显示武将评级', + name: "显示武将评级", init: false, - intro: '仅供娱乐,重启后生效', + intro: "仅供娱乐,重启后生效", unfrequent: true, onclick(bool) { - game.saveConfig('show_rarity', bool); - } + game.saveConfig("show_rarity", bool); + }, }, mark_identity_style: { - name: '标记身份操作', - intro: '设置单击身份按钮时的操作', + name: "标记身份操作", + intro: "设置单击身份按钮时的操作", unfrequent: true, - init: 'menu', + init: "menu", item: { - menu: '菜单', - click: '单击', + menu: "菜单", + click: "单击", }, }, character_dialog_tool: { - name: '自由选将显示', - intro: '点击自由选将时默认显示的条目', - init: '最近', + name: "自由选将显示", + intro: "点击自由选将时默认显示的条目", + init: "最近", item: { - '收藏': '收藏', - '最近': '最近', - 'all': '全部' + 收藏: "收藏", + 最近: "最近", + all: "全部", }, unfrequent: true, }, recent_character_number: { - name: '最近使用武将', - intro: '自由选将对话框中最近使用武将的数量', - init: '12', + name: "最近使用武将", + intro: "自由选将对话框中最近使用武将的数量", + init: "12", item: { - '6': '6', - '12': '12', - '20': '20', - '30': '30', + 6: "6", + 12: "12", + 20: "20", + 30: "30", }, - unfrequent: true + unfrequent: true, }, popequip: { - name: '触屏装备选择', - intro: '设置触屏布局中选择装备的方式', + name: "触屏装备选择", + intro: "设置触屏布局中选择装备的方式", init: true, unfrequent: true, }, filternode_button: { - name: '触屏筛选按钮', - intro: '设置自由选将对话框中筛选按钮的样式', + name: "触屏筛选按钮", + intro: "设置自由选将对话框中筛选按钮的样式", init: true, unfrequent: true, }, show_charactercard: { - name: '显示武将资料', - intro: '在武将界面单击时弹出武将资料卡', + name: "显示武将资料", + intro: "在武将界面单击时弹出武将资料卡", init: true, - unfrequent: true + unfrequent: true, }, show_favourite: { - name: '显示添加收藏', - intro: '在角色的右键菜单中显示添加收藏', + name: "显示添加收藏", + intro: "在角色的右键菜单中显示添加收藏", init: false, - unfrequent: true + unfrequent: true, }, show_favmode: { - name: '显示模式收藏', - intro: '快捷菜单中显示收藏模式', + name: "显示模式收藏", + intro: "快捷菜单中显示收藏模式", init: true, - unfrequent: true + unfrequent: true, }, show_favourite_menu: { - name: '显示收藏菜单', - intro: '在选项-武将中显示收藏一栏', + name: "显示收藏菜单", + intro: "在选项-武将中显示收藏一栏", init: true, - unfrequent: true + unfrequent: true, }, show_ban_menu: { - name: '显示禁将菜单', - intro: '在选项-武将中显示禁将一栏', + name: "显示禁将菜单", + intro: "在选项-武将中显示禁将一栏", init: true, - unfrequent: true + unfrequent: true, }, right_range: { - name: '显示距离信息', - intro: '在角色的右键菜单中显示距离等信息', + name: "显示距离信息", + intro: "在角色的右键菜单中显示距离等信息", init: true, - unfrequent: true + unfrequent: true, }, hide_card_image: { - name: '隐藏卡牌背景', - intro: '所有卡牌将使用文字作为背景', + name: "隐藏卡牌背景", + intro: "所有卡牌将使用文字作为背景", init: false, unfrequent: true, restart: true, }, show_name: { - name: '显示角色名称', + name: "显示角色名称", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_name', bool); + game.saveConfig("show_name", bool); if (bool) { - ui.arena.classList.remove('hide_name'); + ui.arena.classList.remove("hide_name"); + } else { + ui.arena.classList.add("hide_name"); } - else { - ui.arena.classList.add('hide_name'); - } - } + }, }, show_sex: { - name: '显示角色性别', - intro: '在角色的右键菜单中显示角色性别', + name: "显示角色性别", + intro: "在角色的右键菜单中显示角色性别", init: true, - unfrequent: true + unfrequent: true, }, show_group: { - name: '显示角色势力', - intro: '在角色的右键菜单中显示角色势力', + name: "显示角色势力", + intro: "在角色的右键菜单中显示角色势力", init: true, - unfrequent: true + unfrequent: true, }, show_replay: { - name: '显示重来按钮', + name: "显示重来按钮", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_replay', bool); + game.saveConfig("show_replay", bool); if (lib.config.show_replay) { - ui.replay.style.display = ''; + ui.replay.style.display = ""; + } else { + ui.replay.style.display = "none"; } - else { - ui.replay.style.display = 'none'; - } - } + }, }, show_playerids: { - name: '显示身份按钮', + name: "显示身份按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_playerids', bool); + game.saveConfig("show_playerids", bool); if (lib.config.show_playerids) { - ui.playerids.style.display = ''; + ui.playerids.style.display = ""; + } else { + ui.playerids.style.display = "none"; } - else { - ui.playerids.style.display = 'none'; - } - } + }, }, show_sortcard: { - name: '显示整理手牌按钮', + name: "显示整理手牌按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_sortcard', bool); + game.saveConfig("show_sortcard", bool); if (lib.config.show_sortcard) { - ui.sortCard.style.display = ''; + ui.sortCard.style.display = ""; + } else { + ui.sortCard.style.display = "none"; } - else { - ui.sortCard.style.display = 'none'; - } - } + }, }, show_pause: { - name: '显示暂停按钮', + name: "显示暂停按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_pause', bool); + game.saveConfig("show_pause", bool); if (lib.config.show_pause) { - ui.pause.style.display = ''; + ui.pause.style.display = ""; + } else { + ui.pause.style.display = "none"; } - else { - ui.pause.style.display = 'none'; - } - } + }, }, show_auto: { - name: '显示托管按钮', + name: "显示托管按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_auto', bool); + game.saveConfig("show_auto", bool); if (lib.config.show_auto) { - ui.auto.style.display = ''; + ui.auto.style.display = ""; + } else { + ui.auto.style.display = "none"; } - else { - ui.auto.style.display = 'none'; - } - } + }, }, show_volumn: { - name: '显示音量按钮', + name: "显示音量按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_volumn', bool); + game.saveConfig("show_volumn", bool); if (lib.config.show_volumn) { - ui.volumn.style.display = ''; + ui.volumn.style.display = ""; + } else { + ui.volumn.style.display = "none"; } - else { - ui.volumn.style.display = 'none'; - } - } + }, }, show_cardpile: { - name: '显示牌堆按钮', + name: "显示牌堆按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_cardpile', bool); + game.saveConfig("show_cardpile", bool); if (bool) { - ui.cardPileButton.style.display = ''; + ui.cardPileButton.style.display = ""; + } else { + ui.cardPileButton.style.display = "none"; } - else { - ui.cardPileButton.style.display = 'none'; - } - } + }, }, show_cardpile_number: { - name: '显示剩余牌数', + name: "显示剩余牌数", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_cardpile_number', bool); + game.saveConfig("show_cardpile_number", bool); if (bool) { - ui.cardPileNumber.style.display = ''; + ui.cardPileNumber.style.display = ""; + } else { + ui.cardPileNumber.style.display = "none"; } - else { - ui.cardPileNumber.style.display = 'none'; - } - } + }, }, show_handcardbutton: { - name: '显示手牌按钮', + name: "显示手牌按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_handcardbutton', bool); - } + game.saveConfig("show_handcardbutton", bool); + }, }, show_giveup: { - name: '显示投降按钮', + name: "显示投降按钮", init: true, unfrequent: true, onclick(bool) { - game.saveConfig('show_giveup', bool); - } + game.saveConfig("show_giveup", bool); + }, }, show_wuxie: { - name: '显示无懈按钮', - intro: '在右上角显示不询问无懈', + name: "显示无懈按钮", + intro: "在右上角显示不询问无懈", init: false, unfrequent: true, onclick(bool) { - game.saveConfig('show_wuxie', bool); + game.saveConfig("show_wuxie", bool); if (lib.config.show_wuxie) { - ui.wuxie.style.display = ''; + ui.wuxie.style.display = ""; + } else { + ui.wuxie.style.display = "none"; } - else { - ui.wuxie.style.display = 'none'; - } - } + }, }, wuxie_right: { - name: '无懈按钮靠左', + name: "无懈按钮靠左", init: true, unfrequent: true, }, show_discardpile: { - name: '暂停时显示弃牌堆', + name: "暂停时显示弃牌堆", init: false, unfrequent: true, }, show_extensionmaker: { - name: '显示制作扩展', + name: "显示制作扩展", init: true, unfrequent: true, }, show_extensionshare: { - name: '显示分享扩展', + name: "显示分享扩展", init: true, unfrequent: true, }, show_characternamepinyin: { - name: '显示武将名注解', - intro: '在武将资料卡显示武将名及其注解、性别、势力、体力等信息', - init: 'showPinyin', + name: "显示武将名注解", + intro: "在武将资料卡显示武将名及其注解、性别、势力、体力等信息", + init: "showPinyin", unfrequent: true, item: { - doNotShow: '不显示', - showPinyin: '拼音(样式一)', - showCodeIdentifier: '代码ID(样式一)', - showPinyin2: '拼音(样式二)', - showCodeIdentifier2: '代码ID(样式二)', + doNotShow: "不显示", + showPinyin: "拼音(样式一)", + showCodeIdentifier: "代码ID(样式一)", + showPinyin2: "拼音(样式二)", + showCodeIdentifier2: "代码ID(样式二)", }, visualMenu: (node, link, name) => { - node.classList.add('button', 'character'); + node.classList.add("button", "character"); const style = node.style; - style.alignItems = 'center'; - style.animation = 'background-position-left-center-right-center-left-center 15s ease infinite'; - style.background = 'linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB)'; - style.backgroundSize = '400% 400%'; - style.display = 'flex'; - style.height = '60px'; - style.justifyContent = 'center'; - style.width = '180px'; + style.alignItems = "center"; + style.animation = + "background-position-left-center-right-center-left-center 15s ease infinite"; + style.background = "linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB)"; + style.backgroundSize = "400% 400%"; + style.display = "flex"; + style.height = "60px"; + style.justifyContent = "center"; + style.width = "180px"; const firstChild = node.firstChild; - firstChild.removeAttribute('class'); - firstChild.style.position = 'initial'; - if (link == 'doNotShow') return; - const ruby = document.createElement('ruby'); + firstChild.removeAttribute("class"); + firstChild.style.position = "initial"; + if (link == "doNotShow") return; + const ruby = document.createElement("ruby"); ruby.textContent = name; - const rt = document.createElement('rt'); - rt.style.fontSize = 'smaller'; - if (link == 'showPinyin2' || link == 'showCodeIdentifier2') { - rt.textContent = link == 'showCodeIdentifier2' ? '[' + link + ']' : '[' + get.pinyin(name) + ']'; + const rt = document.createElement("rt"); + rt.style.fontSize = "smaller"; + if (link == "showPinyin2" || link == "showCodeIdentifier2") { + rt.textContent = + link == "showCodeIdentifier2" + ? "[" + link + "]" + : "[" + get.pinyin(name) + "]"; ruby.appendChild(rt); } else { - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; + const leftParenthesisRP = document.createElement("rp"); + leftParenthesisRP.textContent = "("; ruby.appendChild(leftParenthesisRP); - rt.textContent = link == 'showCodeIdentifier' ? link : get.pinyin(name).join(' '); + rt.textContent = link == "showCodeIdentifier" ? link : get.pinyin(name).join(" "); ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; + const rightParenthesisRP = document.createElement("rp"); + rightParenthesisRP.textContent = ")"; ruby.appendChild(rightParenthesisRP); } firstChild.innerHTML = ruby.outerHTML; - } + }, }, show_skillnamepinyin: { - name: '显示技能名注解', - intro: '在武将资料卡显示技能名注解', + name: "显示技能名注解", + intro: "在武将资料卡显示技能名注解", get init() { return lib.configMenu.view.config.show_characternamepinyin.init; }, @@ -4108,20 +4419,21 @@ export class Library extends Uninstantable { set visualMenu(newVal) { lib.configMenu.view.config.show_characternamepinyin.visualMenu = newVal; }, - } - } + }, + }, }, audio: { - name: '音效', + name: "音效", config: { update: function (config, map) { - if (lib.config.background_music == 'music_custom' && (lib.device || lib.node)) { + if (lib.config.background_music == "music_custom" && (lib.device || lib.node)) { map.import_music.show(); - } - else { + } else { map.import_music.hide(); } - map.clear_background_music[get.is.object(lib.config.customBackgroundMusic) ? 'show' : 'hide'](); + map.clear_background_music[ + get.is.object(lib.config.customBackgroundMusic) ? "show" : "hide" + ](); ui.background_music_setting = map.background_music; map.background_music._link.config.updatex.call(map.background_music, []); }, @@ -4130,128 +4442,130 @@ export class Library extends Uninstantable { this.lastChild.innerHTML = this._link.config.item[lib.config.background_music]; var menu = this._link.menu; for (var i = 0; i < menu.childElementCount; i++) { - if (!['music_off', 'music_custom', 'music_random'].concat(lib.config.all.background_music).includes(menu.childNodes[i]._link)) menu.childNodes[i].delete(); + if ( + !["music_off", "music_custom", "music_random"] + .concat(lib.config.all.background_music) + .includes(menu.childNodes[i]._link) + ) + menu.childNodes[i].delete(); } }, - name: '背景音乐', + name: "背景音乐", init: true, item: { - music_default: '默认', + music_default: "默认", }, onclick(item) { - game.saveConfig('background_music', item); + game.saveConfig("background_music", item); game.playBackgroundMusic(); - } + }, }, import_music: { - name: '
                                    ' + + name: + '
                                    ' + '' + '
                                    ', clear: true, }, background_audio: { - name: '游戏音效', + name: "游戏音效", init: true, }, background_speak: { - name: '人物配音', + name: "人物配音", init: true, }, equip_audio: { - name: '装备配音', + name: "装备配音", init: false, }, repeat_audio: { - name: '播放重复语音', + name: "播放重复语音", init: false, }, volumn_audio: { - name: '音效音量', + name: "音效音量", init: 8, item: { - '0': '〇', - '1': '一', - '2': '二', - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '7': '七', - '8': '八', + 0: "〇", + 1: "一", + 2: "二", + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 7: "七", + 8: "八", }, onclick(volume) { - game.saveConfig('volumn_audio', parseInt(volume)); - } + game.saveConfig("volumn_audio", parseInt(volume)); + }, }, volumn_background: { - name: '音乐音量', + name: "音乐音量", init: 8, item: { - '0': '〇', - '1': '一', - '2': '二', - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '7': '七', - '8': '八', + 0: "〇", + 1: "一", + 2: "二", + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 7: "七", + 8: "八", }, onclick(volume) { - game.saveConfig('volumn_background', parseInt(volume)); + game.saveConfig("volumn_background", parseInt(volume)); ui.backgroundMusic.volume = volume / 8; - } + }, }, clear_background_music: { - name: '清除自定义背景音乐', + name: "清除自定义背景音乐", clear: true, onclick() { - if (confirm('是否清除已导入的所有自定义背景音乐?(该操作不可撤销!)')) { + if (confirm("是否清除已导入的所有自定义背景音乐?(该操作不可撤销!)")) { for (var i in lib.config.customBackgroundMusic) { lib.config.all.background_music.remove(i); - if (i.startsWith('cdv_')) { - game.removeFile('audio/background/' + i + '.mp3'); - } - else { - game.deleteDB('audio', i); + if (i.startsWith("cdv_")) { + game.removeFile("audio/background/" + i + ".mp3"); + } else { + game.deleteDB("audio", i); } } lib.config.customBackgroundMusic = null; - game.saveConfig('customBackgroundMusic', null); - game.saveConfig('background_music', 'music_off'); + game.saveConfig("customBackgroundMusic", null); + game.saveConfig("background_music", "music_off"); if (!_status._aozhan) game.playBackgroundMusic(); } }, }, - } + }, }, skill: { - name: '技能', + name: "技能", config: { update: function (config, map) { for (var i in map) { - if (map[i]._link.config.type == 'autoskill') { + if (map[i]._link.config.type == "autoskill") { if (!lib.config.autoskilllist.includes(i)) { - map[i].classList.add('on'); + map[i].classList.add("on"); + } else { + map[i].classList.remove("on"); } - else { - map[i].classList.remove('on'); - } - } - else if (map[i]._link.config.type == 'banskill') { + } else if (map[i]._link.config.type == "banskill") { if (!lib.config.forbidlist.includes(i)) { - map[i].classList.add('on'); - } - else { - map[i].classList.remove('on'); + map[i].classList.add("on"); + } else { + map[i].classList.remove("on"); } } } - } - } + }, + }, }, others: { - name: '其它', + name: "其它", config: { // reset_database:{ // name:'重置游戏', @@ -4278,97 +4592,101 @@ export class Library extends Uninstantable { // clear:true // }, reset_game: { - name: '重置游戏设置', + name: "重置游戏设置", onclick() { var node = this; if (node._clearing) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + var noname_inited = localStorage.getItem("noname_inited"); + var onlineKey = localStorage.getItem(lib.configprefix + "key"); localStorage.clear(); if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); + localStorage.setItem("noname_inited", noname_inited); } if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); + localStorage.setItem(lib.configprefix + "key", onlineKey); } - game.deleteDB('config'); - game.deleteDB('data'); + game.deleteDB("config"); + game.deleteDB("data"); game.reload(); return; } node._clearing = true; - node.firstChild.innerHTML = '单击以确认 (3)'; + node.firstChild.innerHTML = "单击以确认 (3)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (2)'; + node.firstChild.innerHTML = "单击以确认 (2)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (1)'; + node.firstChild.innerHTML = "单击以确认 (1)"; setTimeout(function () { - node.firstChild.innerHTML = '重置游戏设置'; + node.firstChild.innerHTML = "重置游戏设置"; delete node._clearing; }, 1000); }, 1000); }, 1000); }, - clear: true + clear: true, }, reset_hiddenpack: { - name: '重置隐藏内容', + name: "重置隐藏内容", onclick() { - if (this.firstChild.innerHTML != '已重置') { - this.firstChild.innerHTML = '已重置'; - game.saveConfig('hiddenModePack', []); - game.saveConfig('hiddenCharacterPack', []); - game.saveConfig('hiddenCardPack', []); - game.saveConfig('hiddenPlayPack', []); - game.saveConfig('hiddenBackgroundPack', []); + if (this.firstChild.innerHTML != "已重置") { + this.firstChild.innerHTML = "已重置"; + game.saveConfig("hiddenModePack", []); + game.saveConfig("hiddenCharacterPack", []); + game.saveConfig("hiddenCardPack", []); + game.saveConfig("hiddenPlayPack", []); + game.saveConfig("hiddenBackgroundPack", []); var that = this; setTimeout(function () { - that.firstChild.innerHTML = '重置隐藏内容'; + that.firstChild.innerHTML = "重置隐藏内容"; setTimeout(function () { - if (confirm('是否重新启动使改变生效?')) { + if (confirm("是否重新启动使改变生效?")) { game.reload(); } }); }, 500); } }, - clear: true + clear: true, }, reset_tutorial: { - name: '重置新手向导', + name: "重置新手向导", onclick() { - if (this.firstChild.innerHTML != '已重置') { - this.firstChild.innerHTML = '已重置'; - game.saveConfig('new_tutorial', false); - game.saveConfig('prompt_hidebg'); - game.saveConfig('prompt_hidepack'); + if (this.firstChild.innerHTML != "已重置") { + this.firstChild.innerHTML = "已重置"; + game.saveConfig("new_tutorial", false); + game.saveConfig("prompt_hidebg"); + game.saveConfig("prompt_hidepack"); var that = this; setTimeout(function () { - that.firstChild.innerHTML = '重置新手向导'; + that.firstChild.innerHTML = "重置新手向导"; }, 500); } }, - clear: true + clear: true, }, import_data: { - name: '导入游戏设置', + name: "导入游戏设置", onclick() { - ui.import_data_button.classList.toggle('hidden'); + ui.import_data_button.classList.toggle("hidden"); }, - clear: true + clear: true, }, import_data_button: { - name: '
                                    ' + + name: + '
                                    ' + '' + '
                                    ', clear: true, }, export_data: { - name: '导出游戏设置', + name: "导出游戏设置", onclick() { var data; var export_data = function (data) { - game.export(lib.init.encode(JSON.stringify(data)), '无名杀 - 数据 - ' + (new Date()).toLocaleString()); + game.export( + lib.init.encode(JSON.stringify(data)), + "无名杀 - 数据 - " + new Date().toLocaleString() + ); }; if (!lib.db) { data = {}; @@ -4378,53 +4696,50 @@ export class Library extends Uninstantable { } } export_data(data); - } - else { - game.getDB('config', null, function (data1) { - game.getDB('data', null, function (data2) { + } else { + game.getDB("config", null, function (data1) { + game.getDB("data", null, function (data2) { export_data({ config: data1, - data: data2 + data: data2, }); }); }); } - }, - clear: true + clear: true, }, redownload_game: { - name: '重新下载游戏', + name: "重新下载游戏", onclick() { var node = this; if (node._clearing) { - localStorage.removeItem('noname_inited'); + localStorage.removeItem("noname_inited"); game.reload(); return; } node._clearing = true; - node.firstChild.innerHTML = '单击以确认 (3)'; + node.firstChild.innerHTML = "单击以确认 (3)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (2)'; + node.firstChild.innerHTML = "单击以确认 (2)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (1)'; + node.firstChild.innerHTML = "单击以确认 (1)"; setTimeout(function () { - node.firstChild.innerHTML = '重新下载游戏'; + node.firstChild.innerHTML = "重新下载游戏"; delete node._clearing; }, 1000); }, 1000); }, 1000); }, - clear: true + clear: true, }, update: function (config, map) { if (lib.device || lib.node) { map.redownload_game.show(); - } - else { + } else { map.redownload_game.hide(); } - } + }, // trim_game:{ // name:'隐藏非官方扩展包', // onclick(){ @@ -4477,335 +4792,327 @@ export class Library extends Uninstantable { // }, // clear:true // } - } - } + }, + }, }; - static extensionMenu = { + extensionMenu = { cardpile: { enable: { - name: '开启', + name: "开启", init: false, restart: true, }, intro: { - name: '将杀闪等牌在牌堆中的比例维持在与军争牌堆相同,防止开启扩展包后被过多地稀释', + name: "将杀闪等牌在牌堆中的比例维持在与军争牌堆相同,防止开启扩展包后被过多地稀释", clear: true, nopointer: true, }, sha: { - name: '杀', - init: '1', + name: "杀", + init: "1", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, huosha: { - name: '火杀', - init: '1', + name: "火杀", + init: "1", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, leisha: { - name: '雷杀', - init: '1', + name: "雷杀", + init: "1", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, shan: { - name: '闪', - init: '1', + name: "闪", + init: "1", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, tao: { - name: '桃', - init: '0', + name: "桃", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, jiu: { - name: '酒', - init: '0', + name: "酒", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, wuxie: { - name: '无懈可击', - init: '0.5', + name: "无懈可击", + init: "0.5", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, nanman: { - name: '南蛮入侵', - init: '0', + name: "南蛮入侵", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, wanjian: { - name: '万箭齐发', - init: '0', + name: "万箭齐发", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, guohe: { - name: '过河拆桥', - init: '0', + name: "过河拆桥", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, shunshou: { - name: '顺手牵羊', - init: '0', + name: "顺手牵羊", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, tiesuo: { - name: '铁索连环', - init: '0', + name: "铁索连环", + init: "0", item: { - '1': '补充全部', - '0.5': '补充一半', - '0': '不补充' - } + 1: "补充全部", + 0.5: "补充一半", + 0: "不补充", + }, }, hide: { - name: '隐藏此扩展', + name: "隐藏此扩展", clear: true, onclick() { - if (this.firstChild.innerHTML == '隐藏此扩展') { - this.firstChild.innerHTML = '此扩展将在重启后隐藏'; - lib.config.hiddenPlayPack.add('cardpile'); + if (this.firstChild.innerHTML == "隐藏此扩展") { + this.firstChild.innerHTML = "此扩展将在重启后隐藏"; + lib.config.hiddenPlayPack.add("cardpile"); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } + } else { + this.firstChild.innerHTML = "隐藏此扩展"; + lib.config.hiddenPlayPack.remove("cardpile"); } - else { - this.firstChild.innerHTML = '隐藏此扩展'; - lib.config.hiddenPlayPack.remove('cardpile'); - } - game.saveConfig('hiddenPlayPack', lib.config.hiddenPlayPack); - } + game.saveConfig("hiddenPlayPack", lib.config.hiddenPlayPack); + }, }, }, boss: { enable: { - name: '开启', + name: "开启", init: false, restart: true, onswitch: function (bool) { if (bool) { var storage = { boss: {}, versus: {}, translate: {} }; var loadversus = function () { - game.loadModeAsync('versus', function (mode) { + game.loadModeAsync("versus", function (mode) { for (var i in mode.translate) { storage.translate[i] = mode.translate[i]; } for (var i in mode.jiangeboss) { - if (mode.jiangeboss[i][4].includes('bossallowed')) { + if (mode.jiangeboss[i][4].includes("bossallowed")) { storage.versus[i] = mode.jiangeboss[i]; } } - localStorage.setItem('boss_storage_playpackconfig', JSON.stringify(storage)); + localStorage.setItem("boss_storage_playpackconfig", JSON.stringify(storage)); }); }; - game.loadModeAsync('boss', function (mode) { + game.loadModeAsync("boss", function (mode) { for (var i in mode.translate) { storage.translate[i] = mode.translate[i]; } for (var i in mode.characterPack.mode_boss) { - if (mode.characterPack.mode_boss[i][4].includes('bossallowed')) { + if (mode.characterPack.mode_boss[i][4].includes("bossallowed")) { storage.boss[i] = mode.characterPack.mode_boss[i]; } } loadversus(); }); + } else { + localStorage.removeItem("boss_storage_playpackconfig"); } - else { - localStorage.removeItem('boss_storage_playpackconfig'); - } - } + }, }, intro: { - name: '将剑阁和挑战模式的武将添加到其它模式', + name: "将剑阁和挑战模式的武将添加到其它模式", clear: true, nopointer: true, }, enableai: { - name: '随机选将可用', - init: false + name: "随机选将可用", + init: false, }, hide: { - name: '隐藏此扩展', + name: "隐藏此扩展", clear: true, onclick() { - if (this.firstChild.innerHTML == '隐藏此扩展') { - this.firstChild.innerHTML = '此扩展将在重启后隐藏'; - lib.config.hiddenPlayPack.add('boss'); + if (this.firstChild.innerHTML == "隐藏此扩展") { + this.firstChild.innerHTML = "此扩展将在重启后隐藏"; + lib.config.hiddenPlayPack.add("boss"); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } + } else { + this.firstChild.innerHTML = "隐藏此扩展"; + lib.config.hiddenPlayPack.remove("boss"); } - else { - this.firstChild.innerHTML = '隐藏此扩展'; - lib.config.hiddenPlayPack.remove('boss'); - } - game.saveConfig('hiddenPlayPack', lib.config.hiddenPlayPack); - } + game.saveConfig("hiddenPlayPack", lib.config.hiddenPlayPack); + }, }, }, wuxing: { enable: { - name: '开启', + name: "开启", init: false, restart: true, }, intro: { - name: '每名角色和部分卡牌在游戏开始时随机获得一个属性', + name: "每名角色和部分卡牌在游戏开始时随机获得一个属性", clear: true, nopointer: true, }, num: { - name: '带属性卡牌', - init: '0.3', + name: "带属性卡牌", + init: "0.3", item: { - '0.1': '10%', - '0.2': '20%', - '0.3': '30%', - '0.5': '50%', - } + 0.1: "10%", + 0.2: "20%", + 0.3: "30%", + 0.5: "50%", + }, }, hide: { - name: '隐藏此扩展', + name: "隐藏此扩展", clear: true, onclick() { - if (this.firstChild.innerHTML == '隐藏此扩展') { - this.firstChild.innerHTML = '此扩展将在重启后隐藏'; - lib.config.hiddenPlayPack.add('wuxing'); + if (this.firstChild.innerHTML == "隐藏此扩展") { + this.firstChild.innerHTML = "此扩展将在重启后隐藏"; + lib.config.hiddenPlayPack.add("wuxing"); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } + } else { + this.firstChild.innerHTML = "隐藏此扩展"; + lib.config.hiddenPlayPack.remove("wuxing"); } - else { - this.firstChild.innerHTML = '隐藏此扩展'; - lib.config.hiddenPlayPack.remove('wuxing'); - } - game.saveConfig('hiddenPlayPack', lib.config.hiddenPlayPack); - } + game.saveConfig("hiddenPlayPack", lib.config.hiddenPlayPack); + }, }, }, coin: { enable: { - name: '开启', + name: "开启", init: false, restart: true, onclick(bool) { if (bool) { - lib.config.plays.add('coin'); + lib.config.plays.add("coin"); + } else { + lib.config.plays.remove("coin"); } - else { - lib.config.plays.remove('coin'); - } - game.saveConfig('plays', lib.config.plays); - } + game.saveConfig("plays", lib.config.plays); + }, }, intro: { - name: '每完成一次对局,可获得一定数量的金币;金币可用于购买游戏特效', + name: "每完成一次对局,可获得一定数量的金币;金币可用于购买游戏特效", clear: true, nopointer: true, }, display: { - name: '金币显示', - init: 'text', + name: "金币显示", + init: "text", item: { - symbol: '符号', - text: '文字' + symbol: "符号", + text: "文字", }, onclick(item) { - game.saveConfig('coin_display_playpackconfig', item); + game.saveConfig("coin_display_playpackconfig", item); if (game.changeCoin) game.changeCoin(0); - } + }, }, canvas: { - name: '特效置顶', + name: "特效置顶", init: false, onclick(bool) { - game.saveConfig('coin_canvas_playpackconfig', bool); + game.saveConfig("coin_canvas_playpackconfig", bool); if (bool) { - ui.window.classList.add('canvas_top'); + ui.window.classList.add("canvas_top"); + } else { + ui.window.classList.remove("canvas_top"); } - else { - ui.window.classList.remove('canvas_top'); - } - } + }, }, hide: { - name: '隐藏此扩展', + name: "隐藏此扩展", clear: true, onclick() { - if (this.firstChild.innerHTML == '隐藏此扩展') { - this.firstChild.innerHTML = '此扩展将在重启后隐藏'; - lib.config.hiddenPlayPack.add('coin'); + if (this.firstChild.innerHTML == "隐藏此扩展") { + this.firstChild.innerHTML = "此扩展将在重启后隐藏"; + lib.config.hiddenPlayPack.add("coin"); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } + } else { + this.firstChild.innerHTML = "隐藏此扩展"; + lib.config.hiddenPlayPack.remove("coin"); } - else { - this.firstChild.innerHTML = '隐藏此扩展'; - lib.config.hiddenPlayPack.remove('coin'); - } - game.saveConfig('hiddenPlayPack', lib.config.hiddenPlayPack); - } + game.saveConfig("hiddenPlayPack", lib.config.hiddenPlayPack); + }, }, }, }; - static mode = { + mode = { identity: { - name: '身份', + name: "身份", connect: { update: function (config, map) { - if (config.connect_identity_mode == 'stratagem') { + if (config.connect_identity_mode == "stratagem") { map.connect_round_one_use_fury.show(); - } - else { + } else { map.connect_round_one_use_fury.hide(); } - if (config.connect_identity_mode == 'zhong') { + if (config.connect_identity_mode == "zhong") { map.connect_player_number.hide(); map.connect_limit_zhu.hide(); map.connect_enhance_zhu.hide(); @@ -4815,8 +5122,7 @@ export class Library extends Uninstantable { map.connect_zhong_card.show(); map.connect_special_identity.hide(); map.connect_double_character.show(); - } - else if (config.connect_identity_mode == 'stratagem') { + } else if (config.connect_identity_mode == "stratagem") { map.connect_double_character.show(); map.connect_player_number.show(); map.connect_limit_zhu.hide(); @@ -4826,8 +5132,7 @@ export class Library extends Uninstantable { map.connect_enable_year_limit.show(); map.connect_zhong_card.hide(); map.connect_special_identity.hide(); - } - else if (config.connect_identity_mode == 'purple') { + } else if (config.connect_identity_mode == "purple") { map.connect_player_number.hide(); map.connect_limit_zhu.hide(); map.connect_enhance_zhu.hide(); @@ -4837,41 +5142,47 @@ export class Library extends Uninstantable { map.connect_zhong_card.hide(); map.connect_special_identity.hide(); map.connect_double_character.hide(); - } - else { + } else { map.connect_double_character.show(); map.connect_player_number.show(); map.connect_limit_zhu.show(); map.connect_enhance_zhu.show(); - map.connect_double_nei[config.connect_player_number != '2' && !config.connect_enable_commoner ? 'show' : 'hide'](); - map.connect_enable_commoner[config.connect_player_number != '2' && !config.connect_double_nei ? 'show' : 'hide'](); + map.connect_double_nei[ + config.connect_player_number != "2" && !config.connect_enable_commoner + ? "show" + : "hide" + ](); + map.connect_enable_commoner[ + config.connect_player_number != "2" && !config.connect_double_nei + ? "show" + : "hide" + ](); map.connect_enable_year_limit.show(); map.connect_zhong_card.hide(); - if (config.connect_player_number == '8') { + if (config.connect_player_number == "8") { map.connect_special_identity.show(); - } - else { + } else { map.connect_special_identity.hide(); } } }, connect_identity_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '标准', - zhong: '明忠', - stratagem: '谋攻', - purple: '3v3v2', + normal: "标准", + zhong: "明忠", + stratagem: "谋攻", + purple: "3v3v2", }, restart: true, frequent: true, - intro: '明忠模式和3v3v2模式详见帮助' + intro: "明忠模式和3v3v2模式详见帮助", }, connect_player_number: { - name: '游戏人数', - init: '8', + name: "游戏人数", + init: "8", get item() { return lib.mode.identity.config.player_number.item; }, @@ -4879,75 +5190,75 @@ export class Library extends Uninstantable { restart: true, }, connect_limit_zhu: { - name: '常备主候选武将数', - init: 'group', + name: "常备主候选武将数", + init: "group", restart: true, item: { - off: '不限制', - group: '按势力筛选', - '4': '四', - '6': '六', - '8': '八', + off: "不限制", + group: "按势力筛选", + 4: "四", + 6: "六", + 8: "八", }, }, connect_zhong_card: { - name: '明忠卡牌替换', + name: "明忠卡牌替换", init: true, frequent: true, - restart: true + restart: true, }, connect_double_nei: { - name: '双内奸', + name: "双内奸", init: false, restart: true, // frequent:true, get intro() { return lib.mode.identity.config.double_nei.intro; - } + }, }, connect_enable_commoner: { - name: '启用平民', + name: "启用平民", init: false, restart: true, frequent: false, get intro() { return lib.mode.identity.config.enable_commoner.intro; - } + }, }, connect_double_character: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, restart: true, }, connect_change_card: { - name: '启用手气卡', + name: "启用手气卡", init: false, frequent: true, restart: true, }, connect_special_identity: { - name: '特殊身份', + name: "特殊身份", init: false, restart: true, frequent: true, - intro: '开启后游戏中将增加军师、大将、贼首三个身份' + intro: "开启后游戏中将增加军师、大将、贼首三个身份", }, connect_enable_year_limit: { - name: '启用年机制', + name: "启用年机制", init: false, restart: true, frequent: false, get intro() { return lib.mode.identity.config.enable_year_limit.intro; - } + }, }, connect_round_one_use_fury: { - name: '开启首轮强化卡牌', + name: "开启首轮强化卡牌", init: false, frequent: false, restart: true, - intro: '谋攻篇规则为第二轮开始才可使用怒气强化卡牌,开启此选项从游戏开始即可强化卡牌。' + intro: "谋攻篇规则为第二轮开始才可使用怒气强化卡牌,开启此选项从游戏开始即可强化卡牌。", }, // connect_ban_weak:{ // name:'屏蔽弱将', @@ -4960,23 +5271,22 @@ export class Library extends Uninstantable { // restart:true, // }, connect_enhance_zhu: { - name: '加强主公', + name: "加强主公", init: false, restart: true, - intro: '为主公增加一个额外技能' + intro: "为主公增加一个额外技能", }, }, config: { update: function (config, map) { - if (config.identity_mode == 'stratagem') { + if (config.identity_mode == "stratagem") { map.round_one_use_fury.show(); map.nei_auto_mark_camouflage.show(); - } - else { + } else { map.round_one_use_fury.hide(); map.nei_auto_mark_camouflage.hide(); } - if (config.identity_mode == 'zhong') { + if (config.identity_mode == "zhong") { map.player_number.hide(); map.enhance_zhu.hide(); map.double_nei.hide(); @@ -5002,21 +5312,18 @@ export class Library extends Uninstantable { map.change_identity.show(); if (config.double_character) { map.double_hp.show(); - } - else { + } else { map.double_hp.hide(); } map.continue_game.show(); - } - else if (config.identity_mode == 'stratagem') { + } else if (config.identity_mode == "stratagem") { map.continue_game.show(); map.player_number.show(); map.enhance_zhu.hide(); map.auto_identity.hide(); - if (config.player_number != '2') { + if (config.player_number != "2") { map.double_nei.show(); - } - else { + } else { map.double_nei.hide(); } map.choice_zhu.show(); @@ -5028,16 +5335,14 @@ export class Library extends Uninstantable { map.choice_commoner.hide(); map.enable_year_limit.show(); map.ban_identity.show(); - if (config.ban_identity == 'off') { + if (config.ban_identity == "off") { map.ban_identity2.hide(); - } - else { + } else { map.ban_identity2.show(); } - if (config.ban_identity == 'off' || config.ban_identity2 == 'off') { + if (config.ban_identity == "off" || config.ban_identity2 == "off") { map.ban_identity3.hide(); - } - else { + } else { map.ban_identity3.show(); } map.zhong_card.hide(); @@ -5050,12 +5355,10 @@ export class Library extends Uninstantable { map.double_character.show(); if (config.double_character) { map.double_hp.show(); - } - else { + } else { map.double_hp.hide(); } - } - else if (config.identity_mode == 'purple') { + } else if (config.identity_mode == "purple") { map.player_number.hide(); map.enhance_zhu.hide(); map.double_nei.hide(); @@ -5081,32 +5384,33 @@ export class Library extends Uninstantable { map.free_choose.hide(); map.change_identity.hide(); map.continue_game.hide(); - } - else { + } else { map.continue_game.show(); map.player_number.show(); map.enhance_zhu.show(); map.auto_identity.show(); - map.double_nei[config.player_number != '2' && !config.enable_commoner ? 'show' : 'hide'](); + map.double_nei[ + config.player_number != "2" && !config.enable_commoner ? "show" : "hide" + ](); map.choice_zhu.show(); map.limit_zhu.show(); map.choice_zhong.show(); map.choice_nei.show(); map.choice_fan.show(); - map.enable_commoner[config.player_number != '2' && !config.double_nei ? 'show' : 'hide'](); - map.choice_commoner[config.enable_commoner ? 'show' : 'hide'](); + map.enable_commoner[ + config.player_number != "2" && !config.double_nei ? "show" : "hide" + ](); + map.choice_commoner[config.enable_commoner ? "show" : "hide"](); map.enable_year_limit.show(); map.ban_identity.show(); - if (config.ban_identity == 'off') { + if (config.ban_identity == "off") { map.ban_identity2.hide(); - } - else { + } else { map.ban_identity2.show(); } - if (config.ban_identity == 'off' || config.ban_identity2 == 'off') { + if (config.ban_identity == "off" || config.ban_identity2 == "off") { map.ban_identity3.hide(); - } - else { + } else { map.ban_identity3.show(); } map.zhong_card.hide(); @@ -5115,40 +5419,47 @@ export class Library extends Uninstantable { map.change_choice.show(); map.free_choose.show(); map.change_identity.show(); - if (config.player_number == '8') { + if (config.player_number == "8") { map.special_identity.show(); - } - else { + } else { map.special_identity.hide(); } map.double_character.show(); if (config.double_character) { map.double_hp.show(); - } - else { + } else { map.double_hp.hide(); } } }, identity_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '标准', - zhong: '明忠', - stratagem: '谋攻', - purple: '3v3v2', + normal: "标准", + zhong: "明忠", + stratagem: "谋攻", + purple: "3v3v2", }, restart: true, frequent: true, - intro: '明忠模式与谋攻模式详见帮助' + intro: "明忠模式与谋攻模式详见帮助", }, player_number: { - name: '游戏人数', - init: '8', + name: "游戏人数", + init: "8", get item() { - const minimumNumberOfPlayers = 2, maximumNumberOfPlayers = Math.max(_status.maximumNumberOfPlayers || 10, minimumNumberOfPlayers), item = {}; - for (let playerNumber = minimumNumberOfPlayers; playerNumber <= maximumNumberOfPlayers; playerNumber++) { + const minimumNumberOfPlayers = 2, + maximumNumberOfPlayers = Math.max( + _status.maximumNumberOfPlayers || 10, + minimumNumberOfPlayers + ), + item = {}; + for ( + let playerNumber = minimumNumberOfPlayers; + playerNumber <= maximumNumberOfPlayers; + playerNumber++ + ) { item[playerNumber] = `${get.cnNumber(playerNumber)}人`; } return item; @@ -5157,87 +5468,99 @@ export class Library extends Uninstantable { restart: true, }, double_nei: { - name: '双内奸', + name: "双内奸", init: false, restart: true, frequent: true, - intro: '若游戏人数不大于9,则开启后游戏中将有两个内奸(内奸胜利条件仍为主内1v1时击杀主公)' + intro: "若游戏人数不大于9,则开启后游戏中将有两个内奸(内奸胜利条件仍为主内1v1时击杀主公)", }, choose_group: { - name: '神武将选择势力', + name: "神武将选择势力", init: true, restart: true, frequent: true, - intro: '若开启此选项,选择神武将的玩家需在亮出自己的武将牌之前为自己选择一个势力。' + intro: "若开启此选项,选择神武将的玩家需在亮出自己的武将牌之前为自己选择一个势力。", }, nei_fullscreenpop: { - name: '主内单挑特效', - intro: '在进入主内单挑时,弹出全屏文字特效', + name: "主内单挑特效", + intro: "在进入主内单挑时,弹出全屏文字特效", init: true, unfrequent: true, }, double_character: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, restart: true, }, special_identity: { - name: '特殊身份', + name: "特殊身份", init: false, restart: true, frequent: true, - intro: '开启后游戏中将增加军师、大将、贼首三个身份' + intro: "开启后游戏中将增加军师、大将、贼首三个身份", }, zhong_card: { - name: '明忠卡牌替换', + name: "明忠卡牌替换", init: true, frequent: true, - restart: true + restart: true, }, double_hp: { - name: '双将体力上限', - init: 'pingjun', + name: "双将体力上限", + init: "pingjun", item: { - hejiansan: '和减三', - pingjun: '平均值', - zuidazhi: '最大值', - zuixiaozhi: '最小值', - zonghe: '相加', + hejiansan: "和减三", + pingjun: "平均值", + zuidazhi: "最大值", + zuixiaozhi: "最小值", + zonghe: "相加", }, restart: true, }, auto_identity: { - name: '自动显示身份', + name: "自动显示身份", item: { - off: '关闭', - one: '一轮', - two: '两轮', - three: '三轮', - always: '始终' + off: "关闭", + one: "一轮", + two: "两轮", + three: "三轮", + always: "始终", }, - init: 'off', + init: "off", onclick(bool) { - game.saveConfig('auto_identity', bool, this._link.config.mode); - if (get.config('identity_mode') == 'zhong') return; + game.saveConfig("auto_identity", bool, this._link.config.mode); + if (get.config("identity_mode") == "zhong") return; var num; switch (bool) { - case '一轮': num = 1; break; - case '两轮': num = 2; break; - case '三轮': num = 3; break; - default: num = 0; break; + case "一轮": + num = 1; + break; + case "两轮": + num = 2; + break; + case "三轮": + num = 3; + break; + default: + num = 0; + break; } - if (num & !_status.identityShown && game.phaseNumber > game.players.length * num && game.showIdentity) { + if ( + num & !_status.identityShown && + game.phaseNumber > game.players.length * num && + game.showIdentity + ) { _status.identityShown = true; game.showIdentity(false); } }, - intro: '游戏进行若干轮将自动显示所有角色的身份', + intro: "游戏进行若干轮将自动显示所有角色的身份", }, auto_mark_identity: { - name: '自动标记身份', + name: "自动标记身份", init: true, - intro: '根据角色的出牌行为自动标记可能的身份', + intro: "根据角色的出牌行为自动标记可能的身份", }, // ban_weak:{ // name:'屏蔽弱将', @@ -5250,291 +5573,306 @@ export class Library extends Uninstantable { // restart:true, // }, enhance_zhu: { - name: '加强主公', + name: "加强主公", init: false, restart: true, - intro: '为主公增加一个额外技能' + intro: "为主公增加一个额外技能", }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + game.saveConfig("free_choose", bool, this._link.config.mode); + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } - } + }, }, change_identity: { - name: '自由选择身份和座位', + name: "自由选择身份和座位", init: true, onclick(bool) { - game.saveConfig('change_identity', bool, this._link.config.mode); - if (get.mode() != 'identity' || !_status.event.getParent().showConfig && !_status.event.showConfig) return; + game.saveConfig("change_identity", bool, this._link.config.mode); + if ( + get.mode() != "identity" || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; var dialog; if (ui.cheat2 && ui.cheat2.backup) dialog = ui.cheat2.backup; else dialog = _status.event.dialog; if (!_status.brawl || !_status.brawl.noAddSetting) { - if (!dialog.querySelector('table') && get.config('change_identity')) _status.event.getParent().addSetting(dialog); + if (!dialog.querySelector("table") && get.config("change_identity")) + _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); - } + }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); - if (get.mode() != 'identity' || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + game.saveConfig("change_choice", bool, this._link.config.mode); + if ( + get.mode() != "identity" || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } - } + }, }, change_card: { - name: '开启手气卡', - init: 'disabled', + name: "开启手气卡", + init: "disabled", item: { - disabled: '禁用', - once: '一次', - twice: '两次', - unlimited: '无限', + disabled: "禁用", + once: "一次", + twice: "两次", + unlimited: "无限", }, }, round_one_use_fury: { - name: '开启首轮强化卡牌', + name: "开启首轮强化卡牌", init: false, frequent: false, restart: true, - intro: '谋攻篇规则为第二轮开始才可使用怒气强化卡牌,开启此选项从游戏开始即可强化卡牌。' + intro: "谋攻篇规则为第二轮开始才可使用怒气强化卡牌,开启此选项从游戏开始即可强化卡牌。", }, nei_auto_mark_camouflage: { - name: '内奸自动标记伪装反贼', - intro: '玩家内奸在游戏开始洞察结束后,自动将被洞察角色标记为反贼。', + name: "内奸自动标记伪装反贼", + intro: "玩家内奸在游戏开始洞察结束后,自动将被洞察角色标记为反贼。", init: false, unfrequent: true, }, continue_game: { - name: '显示再战', + name: "显示再战", init: false, onclick(bool) { - game.saveConfig('continue_game', bool, this._link.config.mode); - if (get.config('continue_game') && get.mode() == 'identity') { - if (!ui.continue_game && _status.over && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); + game.saveConfig("continue_game", bool, this._link.config.mode); + if (get.config("continue_game") && get.mode() == "identity") { + if ( + !ui.continue_game && + _status.over && + !_status.brawl && + !game.no_continue_game + ) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); } - } - else if (ui.continue_game) { + } else if (ui.continue_game) { ui.continue_game.close(); delete ui.continue_game; } }, - intro: '游戏结束后可选择用相同的武将再进行一局游戏' + intro: "游戏结束后可选择用相同的武将再进行一局游戏", }, dierestart: { - name: '死亡后显示重来', + name: "死亡后显示重来", init: true, onclick(bool) { - game.saveConfig('dierestart', bool, this._link.config.mode); - if (get.config('dierestart') && get.mode() == 'identity') { + game.saveConfig("dierestart", bool, this._link.config.mode); + if (get.config("dierestart") && get.mode() == "identity") { if (!ui.restart && game.me.isDead() && !_status.connectMode) { - ui.restart = ui.create.control('restart', game.reload); + ui.restart = ui.create.control("restart", game.reload); } - } - else if (ui.restart) { + } else if (ui.restart) { ui.restart.close(); delete ui.restart; } - } + }, }, revive: { - name: '死亡后显示复活', + name: "死亡后显示复活", init: false, onclick(bool) { - game.saveConfig('revive', bool, this._link.config.mode); - if (get.config('revive') && get.mode() == 'identity') { + game.saveConfig("revive", bool, this._link.config.mode); + if (get.config("revive") && get.mode() == "identity") { if (!ui.revive && game.me.isDead()) { - ui.revive = ui.create.control('revive', ui.click.dierevive); + ui.revive = ui.create.control("revive", ui.click.dierevive); } - } - else if (ui.revive) { + } else if (ui.revive) { ui.revive.close(); delete ui.revive; } - } + }, }, ban_identity: { - name: '屏蔽身份', - init: 'off', + name: "屏蔽身份", + init: "off", item: { - off: '关闭', - zhu: '主公', - zhong: '忠臣', - nei: '内奸', - fan: '反贼', + off: "关闭", + zhu: "主公", + zhong: "忠臣", + nei: "内奸", + fan: "反贼", }, }, ban_identity2: { - name: '屏蔽身份2', - init: 'off', + name: "屏蔽身份2", + init: "off", item: { - off: '关闭', - zhu: '主公', - zhong: '忠臣', - nei: '内奸', - fan: '反贼', + off: "关闭", + zhu: "主公", + zhong: "忠臣", + nei: "内奸", + fan: "反贼", }, }, ban_identity3: { - name: '屏蔽身份3', - init: 'off', + name: "屏蔽身份3", + init: "off", item: { - off: '关闭', - zhu: '主公', - zhong: '忠臣', - nei: '内奸', - fan: '反贼', + off: "关闭", + zhu: "主公", + zhong: "忠臣", + nei: "内奸", + fan: "反贼", }, }, ai_strategy: { - name: '内奸策略', - init: 'ai_strategy_1', + name: "内奸策略", + init: "ai_strategy_1", item: { - ai_strategy_1: '均衡', - ai_strategy_2: '偏反', - ai_strategy_3: '偏忠', - ai_strategy_4: '酱油', - ai_strategy_5: '天使', - ai_strategy_6: '仇主', + ai_strategy_1: "均衡", + ai_strategy_2: "偏反", + ai_strategy_3: "偏忠", + ai_strategy_4: "酱油", + ai_strategy_5: "天使", + ai_strategy_6: "仇主", }, - intro: '设置内奸对主忠反的态度' + intro: "设置内奸对主忠反的态度", }, difficulty: { - name: 'AI对人类态度', - init: 'normal', + name: "AI对人类态度", + init: "normal", item: { - easy: '友好', - normal: '一般', - hard: '仇视', + easy: "友好", + normal: "一般", + hard: "仇视", }, }, choice_zhu: { - name: '主公候选武将数', - init: '3', + name: "主公候选武将数", + init: "3", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, limit_zhu: { - name: '常备主候选武将数', - init: 'group', + name: "常备主候选武将数", + init: "group", restart: true, item: { - off: '不限制', - group: '按势力筛选', - '4': '四', - '6': '六', - '8': '八', + off: "不限制", + group: "按势力筛选", + 4: "四", + 6: "六", + 8: "八", }, }, choice_zhong: { - name: '忠臣候选武将数', - init: '4', + name: "忠臣候选武将数", + init: "4", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, choice_nei: { - name: '内奸候选武将数', - init: '5', + name: "内奸候选武将数", + init: "5", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, choice_fan: { - name: '反贼候选武将数', - init: '3', + name: "反贼候选武将数", + init: "3", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, enable_commoner: { - name: '启用平民', + name: "启用平民", init: false, restart: true, frequent: false, - intro: '开启后游戏中将有一个平民(身份)加入游戏。
                                    具体规则请查看帮助。', + intro: "开启后游戏中将有一个平民(身份)加入游戏。
                                    具体规则请查看帮助。", }, choice_commoner: { - name: '平民候选武将数', - init: '4', + name: "平民候选武将数", + init: "4", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, enable_year_limit: { - name: '启用年机制', + name: "启用年机制", init: false, restart: true, frequent: false, - intro: '开启后将会加入年机制。
                                    年机制的具体规则请查看帮助。', + intro: "开启后将会加入年机制。
                                    年机制的具体规则请查看帮助。", }, - } + }, }, guozhan: { - name: '国战', + name: "国战", connect: { connect_guozhan_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '势备', - yingbian: '应变', - old: '怀旧', + normal: "势备", + yingbian: "应变", + old: "怀旧", }, frequent: true, restart: true, - intro: '
                                  5. 势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。
                                  6. 应变:使用OL的应变国战牌堆进行游戏。
                                  7. 怀旧:使用传统国战的牌堆进行游戏。', + intro: "
                                  8. 势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。
                                  9. 应变:使用OL的应变国战牌堆进行游戏。
                                  10. 怀旧:使用传统国战的牌堆进行游戏。", }, connect_player_number: { - name: '游戏人数', - init: '8', + name: "游戏人数", + init: "8", get item() { return lib.mode.guozhan.config.player_number.item; }, @@ -5542,9 +5880,9 @@ export class Library extends Uninstantable { restart: true, }, connect_aozhan: { - name: '鏖战模式', + name: "鏖战模式", init: true, - intro: '若开启此选项,则将在游戏中引入“鏖战模式”的规则:
                                    当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。
                                    ◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。
                                    注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。', + intro: "若开启此选项,则将在游戏中引入“鏖战模式”的规则:
                                    当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。
                                    ◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。
                                    注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。", frequent: true, restart: true, }, @@ -5552,36 +5890,36 @@ export class Library extends Uninstantable { return lib.mode.guozhan.config.separatism; }, connect_initshow_draw: { - name: '首亮奖励', + name: "首亮奖励", item: { - 'off': '关闭', - 'draw': '摸牌', - 'mark': '标记', + off: "关闭", + draw: "摸牌", + mark: "标记", }, - init: 'mark', + init: "mark", frequent: true, - intro: '第一个明置武将牌的角色可获得首亮奖励' + intro: "第一个明置武将牌的角色可获得首亮奖励", }, connect_viewnext: { - name: '观看下家副将', + name: "观看下家副将", init: false, - intro: '若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。', + intro: "若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。", }, connect_zhulian: { - name: '珠联璧合', + name: "珠联璧合", init: true, // frequent:true, - intro: '主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记' + intro: "主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记", }, connect_junzhu: { - name: '替换君主', + name: "替换君主", init: true, // frequent:true, restart: true, - intro: '若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。' + intro: "若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。", }, connect_change_card: { - name: '启用手气卡', + name: "启用手气卡", init: false, frequent: true, restart: true, @@ -5601,32 +5939,40 @@ export class Library extends Uninstantable { update: function (config, map) { if (config.onlyguozhan) { map.junzhu.show(); - } - else { + } else { map.junzhu.hide(); } ui.aozhan_bgm = map.aozhan_bgm; map.aozhan_bgm._link.config.updatex.call(map.aozhan_bgm, []); }, guozhan_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '势备', - yingbian: '应变', - old: '怀旧', - free: '自由', + normal: "势备", + yingbian: "应变", + old: "怀旧", + free: "自由", }, frequent: true, restart: true, - intro: '
                                  11. 势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。
                                  12. 应变:使用OL的应变国战牌堆进行游戏。
                                  13. 怀旧:使用传统国战的牌堆进行游戏。
                                  14. 自由:使用玩家的自定义牌堆进行游戏。', + intro: "
                                  15. 势备:默认模式,使用线下《君临天下·势备篇》的牌堆进行游戏。
                                  16. 应变:使用OL的应变国战牌堆进行游戏。
                                  17. 怀旧:使用传统国战的牌堆进行游戏。
                                  18. 自由:使用玩家的自定义牌堆进行游戏。", }, player_number: { - name: '游戏人数', - init: '8', + name: "游戏人数", + init: "8", get item() { - const minimumNumberOfPlayers = 2, maximumNumberOfPlayers = Math.max(_status.maximumNumberOfPlayers || 12, minimumNumberOfPlayers), item = {}; - for (let playerNumber = minimumNumberOfPlayers; playerNumber <= maximumNumberOfPlayers; playerNumber++) { + const minimumNumberOfPlayers = 2, + maximumNumberOfPlayers = Math.max( + _status.maximumNumberOfPlayers || 12, + minimumNumberOfPlayers + ), + item = {}; + for ( + let playerNumber = minimumNumberOfPlayers; + playerNumber <= maximumNumberOfPlayers; + playerNumber++ + ) { item[playerNumber] = `${get.cnNumber(playerNumber)}人`; } return item; @@ -5635,107 +5981,112 @@ export class Library extends Uninstantable { restart: true, }, aozhan: { - name: '鏖战模式', + name: "鏖战模式", init: true, frequent: true, restart: true, - intro: '若开启此选项,则将在游戏中引入“鏖战模式”的规则:
                                    当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。
                                    ◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。
                                    注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。', + intro: "若开启此选项,则将在游戏中引入“鏖战模式”的规则:
                                    当游戏中仅剩四名或更少角色时(七人以下游戏时改为三名或更少),若此时全场没有超过一名势力相同的角色,则从一个新的回合开始,游戏进入鏖战模式直至游戏结束。
                                    ◇在鏖战模式下,【桃】只能当做【杀】或【闪】使用或打出,不能用来回复体力。
                                    注:进入鏖战模式后,即使之后有两名或者更多势力相同的角色出现,仍然不会取消鏖战模式。", }, separatism: { - name: '群雄割据', + name: "群雄割据", init: false, frequent: true, restart: true, - intro: '开放不同势力组合,以优先亮出的武将牌作为自己的势力,双势力武将则使用列表的第一个势力' + intro: "开放不同势力组合,以优先亮出的武将牌作为自己的势力,双势力武将则使用列表的第一个势力", }, initshow_draw: { - name: '首亮奖励', + name: "首亮奖励", item: { - 'off': '关闭', - 'draw': '摸牌', - 'mark': '标记', + off: "关闭", + draw: "摸牌", + mark: "标记", }, - init: 'mark', + init: "mark", frequent: true, - intro: '第一个明置身份牌的角色可获得摸牌奖励' + intro: "第一个明置身份牌的角色可获得摸牌奖励", }, viewnext: { - name: '观看下家副将', + name: "观看下家副将", init: false, - intro: '若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。', + intro: "若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。", }, aozhan_bgm: { updatex: function () { - this.lastChild.innerHTML = this._link.config.item[lib.config.mode_config.guozhan.aozhan_bgm]; + this.lastChild.innerHTML = + this._link.config.item[lib.config.mode_config.guozhan.aozhan_bgm]; if (!Array.isArray(_status.aozhanBGMToRemove)) return; const menu = this._link.menu; for (let i = 0; i < menu.childElementCount; i++) { const link = menu.childNodes[i]._link; - if (['disabled', 'random'].includes(link) || !_status.aozhanBGMToRemove.includes(link)) continue; + if ( + ["disabled", "random"].includes(link) || + !_status.aozhanBGMToRemove.includes(link) + ) + continue; _status.aozhanBGMToRemove.remove(link); menu.childNodes[i].delete(); } }, - name: '鏖战背景音乐', + name: "鏖战背景音乐", item: { - disabled: '不启用', - online: 'Online', - rewrite: 'Rewrite', - chaoming: '潮鸣', - random: '随机播放', + disabled: "不启用", + online: "Online", + rewrite: "Rewrite", + chaoming: "潮鸣", + random: "随机播放", }, - init: 'rewrite', + init: "rewrite", onclick(item) { - game.saveConfig('aozhan_bgm', item, this._link.config.mode); + game.saveConfig("aozhan_bgm", item, this._link.config.mode); if (_status._aozhan == true) game.playBackgroundMusic(); }, }, zhulian: { - name: '珠联璧合', + name: "珠联璧合", init: true, // frequent:true, - intro: '主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记' + intro: "主将和副将都明置后,若为特定组合,可获得【珠联璧合】标记", }, changeViceType: { - name: '副将变更方式', - init: 'default', + name: "副将变更方式", + init: "default", item: { - default: '发现式', - online: '随机式', + default: "发现式", + online: "随机式", }, frequent: true, restart: true, }, onlyguozhan: { - name: '使用国战武将', + name: "使用国战武将", init: true, frequent: true, restart: true, - intro: '开启武将技能将替换为国战版本并禁用非国战武将' + intro: "开启武将技能将替换为国战版本并禁用非国战武将", }, guozhanSkin: { - name: '使用国战皮肤', + name: "使用国战皮肤", init: true, frequent: true, restart: true, - intro: '开启此选项后,将会把有国战专属皮肤的武将替换为国战皮肤' + intro: "开启此选项后,将会把有国战专属皮肤的武将替换为国战皮肤", }, junzhu: { - name: '替换君主', + name: "替换君主", init: true, // frequent:true, restart: true, - intro: '若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。' + intro: "若开启此选项,玩家的第一个回合开始时,若其主武将牌有对应的君主武将牌,则其可以将此武将牌替换为对应的君主武将牌,然后重新调整体力上限。若玩家的体力上限因此增大,则玩家回复等量的体力。", }, double_hp: { - name: '双将体力上限', - init: 'pingjun', + name: "双将体力上限", + init: "pingjun", item: { - hejiansan: '和减三', - pingjun: '平均值', - zuidazhi: '最大值', - zuixiaozhi: '最小值', - zonghe: '相加', + hejiansan: "和减三", + pingjun: "平均值", + zuidazhi: "最大值", + zuixiaozhi: "最小值", + zonghe: "相加", }, restart: true, }, @@ -5750,206 +6101,219 @@ export class Library extends Uninstantable { // restart:true, // }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + game.saveConfig("free_choose", bool, this._link.config.mode); + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } - } + }, }, onlyguozhanexpand: { - name: '默认展开自由选将', + name: "默认展开自由选将", init: false, restart: true, - intro: '开启后自由选将对话框将默认显示全部武将' + intro: "开启后自由选将对话框将默认显示全部武将", }, change_identity: { - name: '自由选择座位', + name: "自由选择座位", init: true, onclick(bool) { - game.saveConfig('change_identity', bool, this._link.config.mode); - if (get.mode() != 'guozhan' || !_status.event.getParent().showConfig && !_status.event.showConfig) return; + game.saveConfig("change_identity", bool, this._link.config.mode); + if ( + get.mode() != "guozhan" || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; var dialog; if (ui.cheat2 && ui.cheat2.backup) dialog = ui.cheat2.backup; else dialog = _status.event.dialog; if (!_status.brawl || !_status.brawl.noAddSetting) { - if (!dialog.querySelector('table') && get.config('change_identity')) _status.event.getParent().addSetting(dialog); + if (!dialog.querySelector("table") && get.config("change_identity")) + _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); - } + }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); - if (get.mode() != 'guozhan' || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + game.saveConfig("change_choice", bool, this._link.config.mode); + if ( + get.mode() != "guozhan" || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } - } + }, }, change_card: { - name: '开启手气卡', - init: 'disabled', + name: "开启手气卡", + init: "disabled", item: { - disabled: '禁用', - once: '一次', - twice: '两次', - unlimited: '无限', - } + disabled: "禁用", + once: "一次", + twice: "两次", + unlimited: "无限", + }, }, continue_game: { - name: '显示再战', + name: "显示再战", init: true, - intro: '游戏结束后可选择用相同的武将再进行一局游戏', + intro: "游戏结束后可选择用相同的武将再进行一局游戏", onclick(bool) { - game.saveConfig('continue_game', bool, this._link.config.mode); - if (get.config('continue_game') && get.mode() == 'guozhan') { - if (!ui.continue_game && _status.over && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); + game.saveConfig("continue_game", bool, this._link.config.mode); + if (get.config("continue_game") && get.mode() == "guozhan") { + if ( + !ui.continue_game && + _status.over && + !_status.brawl && + !game.no_continue_game + ) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); } - } - else if (ui.continue_game) { + } else if (ui.continue_game) { ui.continue_game.close(); delete ui.continue_game; } - } + }, }, dierestart: { - name: '死亡后显示重来', + name: "死亡后显示重来", init: true, onclick(bool) { - game.saveConfig('dierestart', bool, this._link.config.mode); - if (get.config('dierestart') && get.mode() == 'guozhan') { + game.saveConfig("dierestart", bool, this._link.config.mode); + if (get.config("dierestart") && get.mode() == "guozhan") { if (!ui.restart && game.me.isDead() && !_status.connectMode) { - ui.restart = ui.create.control('restart', game.reload); + ui.restart = ui.create.control("restart", game.reload); } - } - else if (ui.restart) { + } else if (ui.restart) { ui.restart.close(); delete ui.restart; } - } + }, }, revive: { - name: '死亡后显示复活', + name: "死亡后显示复活", init: false, onclick(bool) { - game.saveConfig('revive', bool, this._link.config.mode); - if (get.config('revive') && get.mode() == 'guozhan') { + game.saveConfig("revive", bool, this._link.config.mode); + if (get.config("revive") && get.mode() == "guozhan") { if (!ui.revive && game.me.isDead()) { - ui.revive = ui.create.control('revive', ui.click.dierevive); + ui.revive = ui.create.control("revive", ui.click.dierevive); } - } - else if (ui.revive) { + } else if (ui.revive) { ui.revive.close(); delete ui.revive; } - } + }, }, difficulty: { - name: 'AI对人类态度', - init: 'normal', + name: "AI对人类态度", + init: "normal", item: { - easy: '友好', - normal: '一般', - hard: '仇视', - } + easy: "友好", + normal: "一般", + hard: "仇视", + }, }, choice_num: { - name: '候选武将数', - init: '7', + name: "候选武将数", + init: "7", restart: true, item: { - '5': '五', - '6': '六', - '7': '七', - '8': '八', - '9': '九', - '10': '十', - } + 5: "五", + 6: "六", + 7: "七", + 8: "八", + 9: "九", + 10: "十", + }, }, - } + }, }, versus: { - name: '对决', + name: "对决", connect: { update: function (config, map) { - if (config.connect_versus_mode == '1v1') { + if (config.connect_versus_mode == "1v1") { map.connect_choice_num.show(); map.connect_replace_number.show(); - } - else { + } else { map.connect_choice_num.hide(); map.connect_replace_number.hide(); } - if (config.connect_versus_mode == '2v2' || config.connect_versus_mode == '3v3') { + if (config.connect_versus_mode == "2v2" || config.connect_versus_mode == "3v3") { map.connect_replace_handcard.show(); - if(config.connect_versus_mode == '2v2') map.connect_olfeiyang_four.show(); + if (config.connect_versus_mode == "2v2") map.connect_olfeiyang_four.show(); else map.connect_olfeiyang_four.hide(); - } - else { + } else { map.connect_replace_handcard.hide(); map.connect_olfeiyang_four.hide(); } }, connect_versus_mode: { - name: '游戏模式', - init: '1v1', + name: "游戏模式", + init: "1v1", item: { - '1v1': '1v1', - '2v2': '2v2', - '3v3': '3v3', - '4v4': '4v4', - 'guandu': '官渡', + "1v1": "1v1", + "2v2": "2v2", + "3v3": "3v3", + "4v4": "4v4", + guandu: "官渡", }, - frequent: true + frequent: true, }, connect_replace_handcard: { - name: '四号位保护', + name: "四号位保护", init: true, frequent: true, - intro: '最后行动的角色起始手牌数+1' + intro: "最后行动的角色起始手牌数+1", }, connect_olfeiyang_four: { - name: '四号位获得【飞扬】', + name: "四号位获得【飞扬】", init: true, frequent: true, - intro: '最后行动的角色获得技能【飞扬】(准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌)', + intro: "最后行动的角色获得技能【飞扬】(准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌)", }, connect_choice_num: { - name: '侯选武将数', - init: '20', + name: "侯选武将数", + init: "20", frequent: true, item: { - '12': '12人', - '16': '16人', - '20': '20人', - '24': '24人', - '40': '40人', - } + 12: "12人", + 16: "16人", + 20: "20人", + 24: "24人", + 40: "40人", + }, }, connect_replace_number: { - name: '替补人数', - init: '2', + name: "替补人数", + init: "2", frequent: true, item: { - '0': '无', - '1': '1人', - '2': '2人', - '3': '3人', - '4': '4人', - '5': '5人', - } + 0: "无", + 1: "1人", + 2: "2人", + 3: "3人", + 4: "4人", + 5: "5人", + }, }, // connect_ban_weak:{ // name:'屏蔽弱将', @@ -5964,14 +6328,13 @@ export class Library extends Uninstantable { }, config: { update: function (config, map) { - if (config.versus_mode == 'four') { + if (config.versus_mode == "four") { map.change_choice.hide(); map.ladder.show(); if (config.ladder) { map.ladder_monthly.show(); map.ladder_reset.show(); - } - else { + } else { map.ladder_monthly.hide(); map.ladder_reset.hide(); } @@ -5983,8 +6346,7 @@ export class Library extends Uninstantable { map.fouralign.show(); map.edit_character_four.show(); map.reset_character_four.show(); - } - else { + } else { map.change_choice.show(); map.ladder.hide(); map.ladder_monthly.hide(); @@ -5998,78 +6360,80 @@ export class Library extends Uninstantable { map.edit_character_four.hide(); map.reset_character_four.hide(); } - if (config.versus_mode == 'three') { + if (config.versus_mode == "three") { map.edit_character_three.show(); map.reset_character_three.show(); - } - else { + } else { map.edit_character_three.hide(); map.reset_character_three.hide(); } - if (config.versus_mode == 'three' || config.versus_mode == 'one') { + if (config.versus_mode == "three" || config.versus_mode == "one") { map.enable_all_three.show(); map.enable_all_cards.show(); - } - else { + } else { map.enable_all_three.hide(); map.enable_all_cards.hide(); } - if (config.versus_mode == 'jiange' || config.versus_mode == 'two' || config.versus_mode == 'endless' || - config.versus_mode == 'three' || config.versus_mode == 'one' || config.versus_mode == 'siguo') { + if ( + config.versus_mode == "jiange" || + config.versus_mode == "two" || + config.versus_mode == "endless" || + config.versus_mode == "three" || + config.versus_mode == "one" || + config.versus_mode == "siguo" + ) { map.free_choose.show(); - } - else { + } else { map.free_choose.hide(); } - if (config.versus_mode == 'jiange') { + if (config.versus_mode == "jiange") { map.double_character_jiange.show(); - } - else { + } else { map.double_character_jiange.hide(); } - if (config.versus_mode == 'two') { + if (config.versus_mode == "two") { map.replace_handcard_two.show(); map.olfeiyang_four.show(); map.replace_character_two.show(); map.two_assign.show(); map.two_phaseswap.show(); - } - else { + } else { map.replace_handcard_two.hide(); map.olfeiyang_four.hide(); map.replace_character_two.hide(); map.two_assign.hide(); map.two_phaseswap.hide(); } - if (config.versus_mode == 'two' || config.versus_mode == 'siguo' || config.versus_mode == 'four') { - if (config.versus_mode == 'four' && (config.four_assign || config.four_phaseswap)) { + if ( + config.versus_mode == "two" || + config.versus_mode == "siguo" || + config.versus_mode == "four" + ) { + if (config.versus_mode == "four" && (config.four_assign || config.four_phaseswap)) { map.change_identity.hide(); - } - else { + } else { map.change_identity.show(); } - } - else { + } else { map.change_identity.hide(); } - if (config.versus_mode == 'siguo') { + if (config.versus_mode == "siguo") { map.siguo_character.show(); - } - else { + } else { map.siguo_character.hide(); } }, versus_mode: { - name: '游戏模式', - init: 'four', + name: "游戏模式", + init: "four", item: { - four: '对抗', - three: '统率', - two: '欢乐', - guandu: '官渡', - jiange: '剑阁', - siguo: '四国', - standard: '自由' + four: "对抗", + three: "统率", + two: "欢乐", + guandu: "官渡", + jiange: "剑阁", + siguo: "四国", + standard: "自由", // endless:'无尽', // triple:'血战', // one:'1v1', @@ -6078,93 +6442,96 @@ export class Library extends Uninstantable { frequent: true, }, ladder: { - name: '天梯模式', + name: "天梯模式", init: true, frequent: true, - restart: true + restart: true, }, ladder_monthly: { - name: '每月重置天梯', + name: "每月重置天梯", init: true, frequent: true, }, enable_all: { - name: '启用全部武将', + name: "启用全部武将", init: false, frequent: true, restart: true, }, enable_all_cards_four: { - name: '启用全部卡牌', + name: "启用全部卡牌", init: false, frequent: true, restart: true, }, enable_all_three: { - name: '启用全部武将', + name: "启用全部武将", init: false, frequent: true, restart: true, }, enable_all_cards: { - name: '启用全部卡牌', + name: "启用全部卡牌", init: false, frequent: true, restart: true, }, four_assign: { - name: '代替队友选将', + name: "代替队友选将", init: false, restart: true, }, four_phaseswap: { - name: '代替队友行动', + name: "代替队友行动", init: false, restart: true, }, two_assign: { - name: '代替队友选将', + name: "代替队友选将", init: false, restart: true, }, two_phaseswap: { - name: '代替队友行动', + name: "代替队友行动", init: false, restart: true, }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, frequent: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); + game.saveConfig("free_choose", bool, this._link.config.mode); if (!ui.create.cheat2) return; - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } - } + }, }, fouralign: { - name: '自由选择阵型', - init: false + name: "自由选择阵型", + init: false, }, change_identity: { - name: '自由选择座位', + name: "自由选择座位", init: true, onclick(bool) { - game.saveConfig('change_identity', bool, this._link.config.mode); + game.saveConfig("change_identity", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (_status.mode == 'four') { - if (get.config('four_assign') || get.config('four_phaseswap')) return; + if (_status.mode == "four") { + if (get.config("four_assign") || get.config("four_phaseswap")) return; if (bool) { if (_status.event.parent.addSetting) { _status.event.parent.addSetting(); } - } - else { + } else { var seats = _status.event.parent.seatsbutton; if (seats) { while (seats.length) { @@ -6173,27 +6540,27 @@ export class Library extends Uninstantable { delete _status.event.parent.seatsbutton; } } - } - else { + } else { var dialog; if (ui.cheat2 && ui.cheat2.backup) dialog = ui.cheat2.backup; else dialog = _status.event.dialog; if (!_status.brawl || !_status.brawl.noAddSetting) { - if (!dialog.querySelector('table') && get.config('change_identity')) _status.event.getParent().addSetting(dialog); + if (!dialog.querySelector("table") && get.config("change_identity")) + _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); } - } + }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); + game.saveConfig("change_choice", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } @@ -6201,42 +6568,42 @@ export class Library extends Uninstantable { frequent: true, }, double_character_jiange: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, }, replace_handcard_two: { - name: '四号位保护', + name: "四号位保护", init: true, frequent: true, - intro: '最后行动的角色起始手牌+1' + intro: "最后行动的角色起始手牌+1", }, olfeiyang_four: { - name: '四号位获得【飞扬】', + name: "四号位获得【飞扬】", init: true, frequent: true, - intro: '最后行动的角色获得技能【飞扬】(准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌)', + intro: "最后行动的角色获得技能【飞扬】(准备阶段,你可以弃置三张牌,然后弃置判定区的一张牌)", }, replace_character_two: { - name: '替补模式', + name: "替补模式", init: false, frequent: true, - intro: '每个额外选择一名武将,死亡后用该武将代替重新上场,替补武将用完时失败' + intro: "每个额外选择一名武将,死亡后用该武将代替重新上场,替补武将用完时失败", }, expand_dialog: { - name: '默认展开选将框', - intro: '选将框打开时直接显示全部武将(可能使游戏在开始时卡顿)', + name: "默认展开选将框", + intro: "选将框打开时直接显示全部武将(可能使游戏在开始时卡顿)", init: false, }, siguo_character: { - name: '专属武将出场率', - init: 'increase', + name: "专属武将出场率", + init: "increase", item: { - increase: '大概率', - normal: '默认概率', - off: '不出现', + increase: "大概率", + normal: "默认概率", + off: "不出现", }, - frequent: true + frequent: true, }, // ban_weak:{ // name:'屏蔽弱将', @@ -6249,28 +6616,28 @@ export class Library extends Uninstantable { // restart:true // }, ladder_reset: { - name: '重置天梯数据', + name: "重置天梯数据", onclick() { var node = this; if (node._clearing) { - game.save('ladder', { + game.save("ladder", { current: 900, top: 900, - month: (new Date()).getMonth() + month: new Date().getMonth(), }); - ui.ladder.innerHTML = '卫士五'; + ui.ladder.innerHTML = "卫士五"; clearTimeout(node._clearing); - node.firstChild.innerHTML = '重置天梯数据'; + node.firstChild.innerHTML = "重置天梯数据"; delete node._clearing; return; } - node.firstChild.innerHTML = '单击以确认 (3)'; + node.firstChild.innerHTML = "单击以确认 (3)"; node._clearing = setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (2)'; + node.firstChild.innerHTML = "单击以确认 (2)"; node._clearing = setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (1)'; + node.firstChild.innerHTML = "单击以确认 (1)"; node._clearing = setTimeout(function () { - node.firstChild.innerHTML = '重置天梯数据'; + node.firstChild.innerHTML = "重置天梯数据"; delete node._clearing; }, 1000); }, 1000); @@ -6279,55 +6646,52 @@ export class Library extends Uninstantable { clear: true, }, edit_character_three: { - name: '编辑统率将池', + name: "编辑统率将池", clear: true, onclick() { - if (get.mode() != 'versus') { - alert('请进入对决模式,然后再编辑将池'); + if (get.mode() != "versus") { + alert("请进入对决模式,然后再编辑将池"); return; } - var container = ui.create.div('.popup-container.editor'); + var container = ui.create.div(".popup-container.editor"); var node = container; - var map = get.config('character_three') || lib.choiceThree; - var str = 'character=[\n '; + var map = get.config("character_three") || lib.choiceThree; + var str = "character=[\n "; for (var i = 0; i < map.length; i++) { str += '"' + map[i] + '",'; - if (i + 1 < map.length && (i + 1) % 5 == 0) str += '\n '; + if (i + 1 < map.length && (i + 1) % 5 == 0) str += "\n "; } - str += '\n];'; + str += "\n];"; node.code = str; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { var character = null; eval(code); if (!Array.isArray(character)) { - throw ('err'); + throw "err"; } - } - catch (e) { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } catch (e) { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - game.saveConfig('character_three', character, 'versus'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + game.saveConfig("character_three", character, "versus"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; delete window.saveNonameInput; @@ -6337,91 +6701,89 @@ export class Library extends Uninstantable { if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { + import("../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, editor); } } }, }, reset_character_three: { - name: '重置统率将池', - intro: '将统率三军模式下的将池重置为默认将池', + name: "重置统率将池", + intro: "将统率三军模式下的将池重置为默认将池", clear: true, onclick() { - if (confirm('该操作不可撤销!是否清除统率三军模式的自定义将池,并将其重置为默认将池?')) { - game.saveConfig('character_three', null, 'versus'); - alert('将池已重置'); + if ( + confirm( + "该操作不可撤销!是否清除统率三军模式的自定义将池,并将其重置为默认将池?" + ) + ) { + game.saveConfig("character_three", null, "versus"); + alert("将池已重置"); } }, }, edit_character_four: { - name: '编辑4v4将池', + name: "编辑4v4将池", clear: true, onclick() { - if (get.mode() != 'versus') { - alert('请进入对决模式,然后再编辑将池'); + if (get.mode() != "versus") { + alert("请进入对决模式,然后再编辑将池"); return; } - var container = ui.create.div('.popup-container.editor'); + var container = ui.create.div(".popup-container.editor"); var node = container; - var map = get.config('character_four') || lib.choiceFour; - var str = 'character=[\n '; + var map = get.config("character_four") || lib.choiceFour; + var str = "character=[\n "; for (var i = 0; i < map.length; i++) { str += '"' + map[i] + '",'; - if (i + 1 < map.length && (i + 1) % 5 == 0) str += '\n '; + if (i + 1 < map.length && (i + 1) % 5 == 0) str += "\n "; } - str += '\n];'; + str += "\n];"; node.code = str; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { var character = null; eval(code); if (!Array.isArray(character)) { - throw ('err'); + throw "err"; } - } - catch (e) { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } catch (e) { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - game.saveConfig('character_four', character, 'versus'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + game.saveConfig("character_four", character, "versus"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; delete window.saveNonameInput; @@ -6431,121 +6793,121 @@ export class Library extends Uninstantable { if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { + import("../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, editor); } } }, }, reset_character_four: { - name: '重置4v4将池', - intro: '将4v4模式下的将池重置为默认将池', + name: "重置4v4将池", + intro: "将4v4模式下的将池重置为默认将池", clear: true, onclick() { - if (confirm('该操作不可撤销!是否清除4v4模式的自定义将池,并将其重置为默认将池?')) { - game.saveConfig('character_four', null, 'versus'); - alert('将池已重置'); + if (confirm("该操作不可撤销!是否清除4v4模式的自定义将池,并将其重置为默认将池?")) { + game.saveConfig("character_four", null, "versus"); + alert("将池已重置"); } }, }, - } + }, }, connect: { - name: '联机', + name: "联机", config: { connect_nickname: { - name: '联机昵称', + name: "联机昵称", input: true, frequent: true, }, connect_avatar: { - name: '联机头像', - init: 'caocao', + name: "联机头像", + init: "caocao", item: {}, frequent: true, onclick(item) { - game.saveConfig('connect_avatar', item); - game.saveConfig('connect_avatar', item, 'connect'); - } + game.saveConfig("connect_avatar", item); + game.saveConfig("connect_avatar", item, "connect"); + }, }, hall_ip: { - name: '联机大厅', + name: "联机大厅", input: true, frequent: true, }, hall_button: { - name: '联机大厅按钮', + name: "联机大厅按钮", init: true, frequent: true, onclick(bool) { - game.saveConfig('hall_button', bool, 'connect'); + game.saveConfig("hall_button", bool, "connect"); if (ui.hall_button) { if (bool) { - ui.hall_button.style.display = ''; - } - else { - ui.hall_button.style.display = 'none'; + ui.hall_button.style.display = ""; + } else { + ui.hall_button.style.display = "none"; } } - } + }, }, wss_mode: { - name: '使用WSS协议', + name: "使用WSS协议", init: false, frequent: true, - intro: '在用户填写的IP地址没有直接指定使用WS/WSS协议的情况下,默认使用WSS协议,而非WS协议来连接到联机服务器。
                                    请不要轻易勾选此项!', + intro: "在用户填写的IP地址没有直接指定使用WS/WSS协议的情况下,默认使用WSS协议,而非WS协议来连接到联机服务器。
                                    请不要轻易勾选此项!", }, read_clipboard: { - name: '读取邀请链接', + name: "读取邀请链接", init: false, frequent: true, - intro: '读取剪贴板以解析邀请链接自动加入联机房间', - } - } + intro: "读取剪贴板以解析邀请链接自动加入联机房间", + }, + }, }, boss: { - name: '挑战', + name: "挑战", config: { free_choose: { - name: '自由选将', + name: "自由选将", init: true, frequent: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + game.saveConfig("free_choose", bool, this._link.config.mode); + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } - } + }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); + game.saveConfig("change_choice", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } @@ -6553,21 +6915,20 @@ export class Library extends Uninstantable { frequent: true, }, single_control: { - name: '单人控制', + name: "单人控制", init: true, frequent: true, onclick(bool) { - game.saveConfig('single_control', bool, this._link.config.mode); + game.saveConfig("single_control", bool, this._link.config.mode); if (ui.single_swap && game.me != game.boss) { if (bool) { - ui.single_swap.style.display = 'none'; - } - else { - ui.single_swap.style.display = ''; + ui.single_swap.style.display = "none"; + } else { + ui.single_swap.style.display = ""; } } }, - intro: '只控制一名角色,其他角色由AI控制' + intro: "只控制一名角色,其他角色由AI控制", }, // ban_weak:{ // name:'屏蔽弱将', @@ -6579,46 +6940,44 @@ export class Library extends Uninstantable { // init:false, // restart:true, // }, - } + }, }, doudizhu: { - name: '斗地主', + name: "斗地主", connect: { update: function (config, map) { - if (config.connect_doudizhu_mode == 'online') { + if (config.connect_doudizhu_mode == "online") { map.connect_change_card.hide(); - } - else { + } else { map.connect_change_card.show(); } - if (config.connect_doudizhu_mode != 'normal') { + if (config.connect_doudizhu_mode != "normal") { map.connect_double_character.hide(); - } - else { + } else { map.connect_double_character.show(); } }, connect_doudizhu_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '休闲', - kaihei: '开黑', - huanle: '欢乐', - binglin: '兵临', - online: '智斗', + normal: "休闲", + kaihei: "开黑", + huanle: "欢乐", + binglin: "兵临", + online: "智斗", }, restart: true, frequent: true, }, connect_double_character: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, restart: true, }, connect_change_card: { - name: '启用手气卡', + name: "启用手气卡", init: false, frequent: true, restart: true, @@ -6626,17 +6985,16 @@ export class Library extends Uninstantable { }, config: { update: function (config, map) { - if (config.doudizhu_mode == 'online') { + if (config.doudizhu_mode == "online") { map.change_card.hide(); map.edit_character.show(); map.reset_character.show(); - } - else { + } else { map.change_card.show(); map.edit_character.hide(); map.reset_character.hide(); } - if (config.doudizhu_mode != 'normal') { + if (config.doudizhu_mode != "normal") { map.double_character.hide(); map.free_choose.hide(); map.change_identity.hide(); @@ -6646,8 +7004,7 @@ export class Library extends Uninstantable { map.choice_zhu.hide(); map.choice_fan.hide(); map.revive.hide(); - } - else { + } else { map.double_character.show(); map.free_choose.show(); map.change_identity.show(); @@ -6658,232 +7015,235 @@ export class Library extends Uninstantable { map.choice_fan.show(); map.revive.show(); } - if (config.double_character && config.doudizhu_mode == 'normal') { + if (config.double_character && config.doudizhu_mode == "normal") { map.double_hp.show(); - } - else { + } else { map.double_hp.hide(); } }, doudizhu_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '休闲', - kaihei: '开黑', - huanle: '欢乐', - binglin: '兵临', - online: '智斗', + normal: "休闲", + kaihei: "开黑", + huanle: "欢乐", + binglin: "兵临", + online: "智斗", }, restart: true, frequent: true, }, double_character: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, restart: true, }, double_hp: { - name: '双将体力上限', - init: 'pingjun', + name: "双将体力上限", + init: "pingjun", item: { - hejiansan: '和减三', - pingjun: '平均值', - zuidazhi: '最大值', - zuixiaozhi: '最小值', - zonghe: '相加', + hejiansan: "和减三", + pingjun: "平均值", + zuidazhi: "最大值", + zuixiaozhi: "最小值", + zonghe: "相加", }, restart: true, }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + game.saveConfig("free_choose", bool, this._link.config.mode); + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } - } + }, }, change_identity: { - name: '自由选择身份和座位', + name: "自由选择身份和座位", init: true, onclick(bool) { - game.saveConfig('change_identity', bool, this._link.config.mode); + game.saveConfig("change_identity", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; var dialog; if (ui.cheat2 && ui.cheat2.backup) dialog = ui.cheat2.backup; else dialog = _status.event.dialog; if (!_status.brawl || !_status.brawl.noAddSetting) { - if (!dialog.querySelector('table') && get.config('change_identity')) _status.event.getParent().addSetting(dialog); + if (!dialog.querySelector("table") && get.config("change_identity")) + _status.event.getParent().addSetting(dialog); else _status.event.getParent().removeSetting(dialog); } ui.update(); - } + }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); + game.saveConfig("change_choice", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } - } + }, }, change_card: { - name: '开启手气卡', - init: 'disabled', + name: "开启手气卡", + init: "disabled", item: { - disabled: '禁用', - once: '一次', - twice: '两次', - unlimited: '无限', + disabled: "禁用", + once: "一次", + twice: "两次", + unlimited: "无限", }, }, continue_game: { - name: '显示再战', + name: "显示再战", init: false, onclick(bool) { - game.saveConfig('continue_game', bool, this._link.config.mode); - if (get.config('continue_game')) { - if (!ui.continue_game && _status.over && !_status.brawl && !game.no_continue_game) { - ui.continue_game = ui.create.control('再战', game.reloadCurrent); + game.saveConfig("continue_game", bool, this._link.config.mode); + if (get.config("continue_game")) { + if ( + !ui.continue_game && + _status.over && + !_status.brawl && + !game.no_continue_game + ) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); } - } - else if (ui.continue_game) { + } else if (ui.continue_game) { ui.continue_game.close(); delete ui.continue_game; } }, - intro: '游戏结束后可选择用相同的武将再进行一局游戏' + intro: "游戏结束后可选择用相同的武将再进行一局游戏", }, dierestart: { - name: '死亡后显示重来', + name: "死亡后显示重来", init: true, onclick(bool) { - game.saveConfig('dierestart', bool, this._link.config.mode); - if (get.config('dierestart')) { + game.saveConfig("dierestart", bool, this._link.config.mode); + if (get.config("dierestart")) { if (!ui.restart && game.me.isDead() && !_status.connectMode) { - ui.restart = ui.create.control('restart', game.reload); + ui.restart = ui.create.control("restart", game.reload); } - } - else if (ui.restart) { + } else if (ui.restart) { ui.restart.close(); delete ui.restart; } - } + }, }, revive: { - name: '死亡后显示复活', + name: "死亡后显示复活", init: false, onclick(bool) { - game.saveConfig('revive', bool, this._link.config.mode); - if (get.config('revive')) { + game.saveConfig("revive", bool, this._link.config.mode); + if (get.config("revive")) { if (!ui.revive && game.me.isDead()) { - ui.revive = ui.create.control('revive', ui.click.dierevive); + ui.revive = ui.create.control("revive", ui.click.dierevive); } - } - else if (ui.revive) { + } else if (ui.revive) { ui.revive.close(); delete ui.revive; } - } + }, }, choice_zhu: { - name: '地主候选武将数', - init: '3', + name: "地主候选武将数", + init: "3", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, choice_fan: { - name: '农民候选武将数', - init: '3', + name: "农民候选武将数", + init: "3", restart: true, item: { - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '8': '八', - '10': '十', + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 8: "八", + 10: "十", }, }, edit_character: { - name: '编辑将池', + name: "编辑将池", clear: true, onclick() { - if (get.mode() != 'doudizhu') { - alert('请进入斗地主模式,然后再编辑将池'); + if (get.mode() != "doudizhu") { + alert("请进入斗地主模式,然后再编辑将池"); return; } - var container = ui.create.div('.popup-container.editor'); + var container = ui.create.div(".popup-container.editor"); var node = container; - var map = get.config('character_online') || lib.characterOnline; - node.code = 'character=' + get.stringify(map) + '\n/*\n 这里是智斗三国模式的武将将池。\n 您可以在这里编辑对武将将池进行编辑,然后点击“保存”按钮即可保存。\n 将池中的Key势力武将,仅同时在没有被禁用的情况下,才会出现在选将框中。\n 而非Key势力的武将,只要所在的武将包没有被隐藏,即可出现在选将框中。\n 该将池为单机模式/联机模式通用将池。在这里编辑后,即使进入联机模式,也依然会生效。\n 但联机模式本身禁用的武将(如神貂蝉)不会出现在联机模式的选将框中。\n*/'; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + var map = get.config("character_online") || lib.characterOnline; + node.code = + "character=" + + get.stringify(map) + + "\n/*\n 这里是智斗三国模式的武将将池。\n 您可以在这里编辑对武将将池进行编辑,然后点击“保存”按钮即可保存。\n 将池中的Key势力武将,仅同时在没有被禁用的情况下,才会出现在选将框中。\n 而非Key势力的武将,只要所在的武将包没有被隐藏,即可出现在选将框中。\n 该将池为单机模式/联机模式通用将池。在这里编辑后,即使进入联机模式,也依然会生效。\n 但联机模式本身禁用的武将(如神貂蝉)不会出现在联机模式的选将框中。\n*/"; + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { var character = null; eval(code); if (!get.is.object(character)) { - throw ('err'); + throw "err"; } var groups = []; for (var i in character) { - if (!Array.isArray(character[i])) throw ('type'); + if (!Array.isArray(character[i])) throw "type"; if (character[i].length >= 3) groups.push(i); } - if (groups.length < 3) throw ('enough'); - } - catch (e) { - if (e == 'type') { - alert('请严格按照格式填写,不要写入不为数组的数据'); - } - else if (e == 'enough') { - alert('请保证至少写入了3个势力,且每个势力至少有3个武将'); - } - else if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + if (groups.length < 3) throw "enough"; + } catch (e) { + if (e == "type") { + alert("请严格按照格式填写,不要写入不为数组的数据"); + } else if (e == "enough") { + alert("请保证至少写入了3个势力,且每个势力至少有3个武将"); + } else if (e == "err") { + alert("代码格式有错误,请对比示例代码仔细检查"); + } else { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); } window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - game.saveConfig('character_online', character, 'doudizhu'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + game.saveConfig("character_online", character, "doudizhu"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; delete window.saveNonameInput; @@ -6893,166 +7253,161 @@ export class Library extends Uninstantable { if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../game/codemirror.js').then(() => { + import("../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, editor); } } }, }, reset_character: { - name: '重置将池', - intro: '将智斗三国模式下的将池重置为默认将池', + name: "重置将池", + intro: "将智斗三国模式下的将池重置为默认将池", clear: true, onclick() { - if (confirm('该操作不可撤销!是否清除智斗三国模式的自定义将池,并将其重置为默认将池?')) { - game.saveConfig('character_online', null, 'doudizhu'); - alert('将池已重置'); + if ( + confirm( + "该操作不可撤销!是否清除智斗三国模式的自定义将池,并将其重置为默认将池?" + ) + ) { + game.saveConfig("character_online", null, "doudizhu"); + alert("将池已重置"); } }, }, - } + }, }, single: { - name: '单挑', + name: "单挑", connect: { connect_single_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '新1v1', - dianjiang: '点将单挑', - changban: '血战长坂坡', - wuxianhuoli: '无限火力', + normal: "新1v1", + dianjiang: "点将单挑", + changban: "血战长坂坡", + wuxianhuoli: "无限火力", }, restart: true, frequent: true, - intro: '血战长坂坡和无限火力模式详见帮助', + intro: "血战长坂坡和无限火力模式详见帮助", }, connect_enable_jin: { - name: '启用晋势力武将', + name: "启用晋势力武将", init: false, restart: true, frequent: true, }, connect_change_card: { - name: '启用手气卡', + name: "启用手气卡", init: false, frequent: true, restart: true, }, update: function (config, map) { - if (config.connect_single_mode != 'normal') { + if (config.connect_single_mode != "normal") { map.connect_enable_jin.hide(); - } - else { + } else { map.connect_enable_jin.show(); } - if (config.connect_single_mode != 'wuxianhuoli') { + if (config.connect_single_mode != "wuxianhuoli") { map.connect_change_card.hide(); - } - else { + } else { map.connect_change_card.show(); } }, }, config: { single_mode: { - name: '游戏模式', - init: 'normal', + name: "游戏模式", + init: "normal", item: { - normal: '新1v1', - dianjiang: '点将单挑', - changban: '血战长坂坡', - wuxianhuoli: '无限火力', + normal: "新1v1", + dianjiang: "点将单挑", + changban: "血战长坂坡", + wuxianhuoli: "无限火力", }, restart: true, frequent: true, - intro: '血战长坂坡和无限火力模式详见帮助', + intro: "血战长坂坡和无限火力模式详见帮助", }, enable_jin: { - name: '启用晋势力武将', + name: "启用晋势力武将", init: false, restart: true, frequent: true, }, change_card: { - name: '开启手气卡', - init: 'disabled', + name: "开启手气卡", + init: "disabled", item: { - disabled: '禁用', - once: '一次', - twice: '两次', - unlimited: '无限', - } + disabled: "禁用", + once: "一次", + twice: "两次", + unlimited: "无限", + }, }, update: function (config, map) { - if (config.single_mode != 'normal') { + if (config.single_mode != "normal") { map.enable_jin.hide(); - } - else { + } else { map.enable_jin.show(); } - if (config.single_mode != 'wuxianhuoli') { + if (config.single_mode != "wuxianhuoli") { map.change_card.hide(); - } - else { + } else { map.change_card.show(); } }, - } + }, }, chess: { - name: '战棋', + name: "战棋", config: { chess_mode: { - name: '游戏模式', - init: 'combat', + name: "游戏模式", + init: "combat", item: { - combat: '自由', - three: '统率', - leader: '君主', + combat: "自由", + three: "统率", + leader: "君主", }, restart: true, frequent: true, }, update: function (config, map) { - if (config.chess_mode == 'leader') { + if (config.chess_mode == "leader") { map.chess_leader_save.show(); map.chess_leader_clear.show(); map.chess_leader_allcharacter.show(); map.chess_character.hide(); - } - else { + } else { map.chess_leader_save.hide(); map.chess_leader_clear.hide(); map.chess_leader_allcharacter.hide(); map.chess_character.show(); } - if (config.chess_mode == 'combat') { + if (config.chess_mode == "combat") { // map.battle_number.show(); // map.chess_ordered.show(); map.free_choose.show(); map.change_choice.show(); - } - else { + } else { // map.battle_number.hide(); // map.chess_ordered.hide(); map.free_choose.hide(); @@ -7068,48 +7423,47 @@ export class Library extends Uninstantable { // } }, chess_leader_save: { - name: '选择历程', - init: 'save1', + name: "选择历程", + init: "save1", item: { - save1: '一', - save2: '二', - save3: '三', - save4: '四', - save5: '五', + save1: "一", + save2: "二", + save3: "三", + save4: "四", + save5: "五", }, restart: true, frequent: true, }, chess_leader_allcharacter: { - name: '启用全部角色', + name: "启用全部角色", init: true, onclick(bool) { - if (confirm('调整该设置将清除所有进度,是否继续?')) { - for (var i = 1; i < 6; i++) game.save('save' + i, null, 'chess'); - game.saveConfig('chess_leader_allcharacter', bool, 'chess'); - if (get.mode() == 'chess') game.reload(); + if (confirm("调整该设置将清除所有进度,是否继续?")) { + for (var i = 1; i < 6; i++) game.save("save" + i, null, "chess"); + game.saveConfig("chess_leader_allcharacter", bool, "chess"); + if (get.mode() == "chess") game.reload(); return; - } - else this.classList.toggle('on'); + } else this.classList.toggle("on"); }, }, chess_leader_clear: { - name: '清除进度', + name: "清除进度", onclick() { var node = this; if (node._clearing) { - for (var i = 1; i < 6; i++) game.save('save' + i, null, 'chess'); + for (var i = 1; i < 6; i++) game.save("save" + i, null, "chess"); game.reload(); return; } node._clearing = true; - node.firstChild.innerHTML = '单击以确认 (3)'; + node.firstChild.innerHTML = "单击以确认 (3)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (2)'; + node.firstChild.innerHTML = "单击以确认 (2)"; setTimeout(function () { - node.firstChild.innerHTML = '单击以确认 (1)'; + node.firstChild.innerHTML = "单击以确认 (1)"; setTimeout(function () { - node.firstChild.innerHTML = '清除进度'; + node.firstChild.innerHTML = "清除进度"; delete node._clearing; }, 1000); }, 1000); @@ -7131,55 +7485,59 @@ export class Library extends Uninstantable { // } // }, chess_obstacle: { - name: '随机路障', - init: '0.2', + name: "随机路障", + init: "0.2", item: { - '0': '关闭', - '0.2': '少量', - '0.333': '中量', - '0.5': '大量', + 0: "关闭", + 0.2: "少量", + 0.333: "中量", + 0.5: "大量", }, frequent: true, }, show_range: { - name: '显示卡牌范围', + name: "显示卡牌范围", init: true, }, show_distance: { - name: '显示距离', + name: "显示距离", init: true, }, chess_character: { - name: '战棋武将', + name: "战棋武将", init: true, frequent: true, }, chess_card: { - name: '战棋卡牌', + name: "战棋卡牌", init: true, frequent: true, }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + game.saveConfig("free_choose", bool, this._link.config.mode); + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); + game.saveConfig("change_choice", bool, this._link.config.mode); if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } @@ -7196,31 +7554,31 @@ export class Library extends Uninstantable { // restart:true, // }, chessscroll_speed: { - name: '边缘滚动速度', - init: '20', - intro: '鼠标移至屏幕边缘时自动滚屏', + name: "边缘滚动速度", + init: "20", + intro: "鼠标移至屏幕边缘时自动滚屏", item: { - '0': '不滚动', - '10': '10格/秒', - '20': '20格/秒', - '30': '30格/秒', - } + 0: "不滚动", + 10: "10格/秒", + 20: "20格/秒", + 30: "30格/秒", + }, }, - } + }, }, tafang: { - name: '塔防', + name: "塔防", config: { tafang_turn: { - name: '游戏胜利', - init: '10', + name: "游戏胜利", + init: "10", frequent: true, item: { - '10': '十回合', - '20': '二十回合', - '30': '三十回合', - '1000': '无限', - } + 10: "十回合", + 20: "二十回合", + 30: "三十回合", + 1000: "无限", + }, }, // tafang_size:{ // name:'战场大小', @@ -7233,21 +7591,21 @@ export class Library extends Uninstantable { // } // }, tafang_difficulty: { - name: '战斗难度', - init: '2', + name: "战斗难度", + init: "2", frequent: true, item: { - '1': '简单', - '2': '普通', - '3': '困难', - } + 1: "简单", + 2: "普通", + 3: "困难", + }, }, show_range: { - name: '显示卡牌范围', + name: "显示卡牌范围", init: true, }, show_distance: { - name: '显示距离', + name: "显示距离", init: true, }, // ban_weak:{ @@ -7261,85 +7619,85 @@ export class Library extends Uninstantable { // restart:true, // }, chessscroll_speed: { - name: '边缘滚动速度', - intro: '鼠标移至屏幕边缘时自动滚屏', - init: '20', + name: "边缘滚动速度", + intro: "鼠标移至屏幕边缘时自动滚屏", + init: "20", item: { - '0': '不滚动', - '10': '10格/秒', - '20': '20格/秒', - '30': '30格/秒', - } + 0: "不滚动", + 10: "10格/秒", + 20: "20格/秒", + 30: "30格/秒", + }, }, - } + }, }, brawl: { - name: '乱斗', + name: "乱斗", config: { huanhuazhizhan: { - name: '幻化之战', + name: "幻化之战", init: true, - frequent: true + frequent: true, }, duzhansanguo: { - name: '毒战三国', + name: "毒战三国", init: true, - frequent: true + frequent: true, }, daozhiyueying: { - name: '导师月英', + name: "导师月英", init: true, - frequent: true + frequent: true, }, weiwoduzun: { - name: '唯我独尊', + name: "唯我独尊", init: true, - frequent: true + frequent: true, }, tongxingzhizheng: { - name: '同姓之争', + name: "同姓之争", init: true, - frequent: true + frequent: true, }, jiazuzhizheng: { - name: '家族之争', + name: "家族之争", init: true, - frequent: true + frequent: true, }, tongqueduopao: { - name: '铜雀夺袍', + name: "铜雀夺袍", init: true, - frequent: true + frequent: true, }, tongjiangmoshi: { - name: '同将模式', + name: "同将模式", init: true, - frequent: true + frequent: true, }, baiyidujiang: { - name: '白衣渡江', + name: "白衣渡江", init: true, - frequent: true + frequent: true, }, qianlidanji: { - name: '千里单骑', + name: "千里单骑", init: true, - frequent: true + frequent: true, }, liangjunduilei: { - name: '两军对垒', + name: "两军对垒", init: true, - frequent: true + frequent: true, }, scene: { - name: '创建场景', + name: "创建场景", init: true, - frequent: true - } - } + frequent: true, + }, + }, }, stone: { - name: '炉石', + name: "炉石", config: { // update:function(config,map){ // if(config.stone_mode=='deck'){ @@ -7397,20 +7755,20 @@ export class Library extends Uninstantable { // frequent:true, // }, battle_number: { - name: '出场人数', - init: '1', + name: "出场人数", + init: "1", frequent: true, item: { - '1': '一人', - '2': '两人', - '3': '三人', - '4': '四人', - '6': '六人', - '8': '八人', - '10': '十人', + 1: "一人", + 2: "两人", + 3: "三人", + 4: "四人", + 6: "六人", + 8: "八人", + 10: "十人", }, onclick(num) { - game.saveConfig('battle_number', num, this._link.config.mode); + game.saveConfig("battle_number", num, this._link.config.mode); if (_status.connectMode) return; if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; if (_status.event.getParent().changeDialog) { @@ -7419,51 +7777,58 @@ export class Library extends Uninstantable { }, }, mana_mode: { - name: '行动值变化', - init: 'inc', + name: "行动值变化", + init: "inc", item: { - inf: '涨落', - inc: '递增' + inf: "涨落", + inc: "递增", }, - frequent: true + frequent: true, }, skill_bar: { - name: '怒气值', + name: "怒气值", init: true, frequent: true, restart: true, }, double_character: { - name: '双将模式', + name: "双将模式", init: false, frequent: true, restart: function () { - return _status.event.getParent().name != 'chooseCharacter' || _status.event.name != 'chooseButton'; - } + return ( + _status.event.getParent().name != "chooseCharacter" || + _status.event.name != "chooseButton" + ); + }, }, free_choose: { - name: '自由选将', + name: "自由选将", init: true, onclick(bool) { - game.saveConfig('free_choose', bool, this._link.config.mode); + game.saveConfig("free_choose", bool, this._link.config.mode); if (_status.connectMode) return; - if (get.mode() != this._link.config.mode || !_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat2 && get.config('free_choose')) ui.create.cheat2(); - else if (ui.cheat2 && !get.config('free_choose')) { + if ( + get.mode() != this._link.config.mode || + (!_status.event.getParent().showConfig && !_status.event.showConfig) + ) + return; + if (!ui.cheat2 && get.config("free_choose")) ui.create.cheat2(); + else if (ui.cheat2 && !get.config("free_choose")) { ui.cheat2.close(); delete ui.cheat2; } }, }, change_choice: { - name: '开启换将卡', + name: "开启换将卡", init: true, onclick(bool) { - game.saveConfig('change_choice', bool, this._link.config.mode); + game.saveConfig("change_choice", bool, this._link.config.mode); if (_status.connectMode) return; if (!_status.event.getParent().showConfig && !_status.event.showConfig) return; - if (!ui.cheat && get.config('change_choice')) ui.create.cheat(); - else if (ui.cheat && !get.config('change_choice')) { + if (!ui.cheat && get.config("change_choice")) ui.create.cheat(); + else if (ui.cheat && !get.config("change_choice")) { ui.cheat.close(); delete ui.cheat; } @@ -7479,10 +7844,10 @@ export class Library extends Uninstantable { // init:false, // restart:true, // }, - } + }, }, }; - static status = { + status = { running: false, canvas: false, time: 0, @@ -7492,60 +7857,67 @@ export class Library extends Uninstantable { videoId: 0, globalId: 0, }; - static help = { - '关于游戏': '
                                    关于无名杀
                                    • 无名杀官方发布地址仅有GitHub仓库!
                                      点击前往Github仓库
                                    • 无名杀基于GPLv3开源协议。
                                      点击查看GPLv3协议
                                    • 其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!', - '游戏操作': '
                                      • 长按/鼠标悬停/右键单击显示信息。
                                      • 触屏模式中,双指点击切换暂停;下划显示菜单,上划切换托管。
                                      • 键盘快捷键
                                        ' + - '
                                        A切换托管
                                        W切换不询问无懈
                                        空格暂停
                                      • 编辑牌堆
                                        在卡牌包中修改牌堆后,将自动创建一个临时牌堆,在所有模式中共用,当保存当前牌堆后,临时牌堆被清除。每个模式可设置不同的已保存牌堆,设置的牌堆优先级大于临时牌堆。
                                      ', - '游戏命令': '
                                      变量名
                                      • 场上角色
                                        game.players
                                      • 阵亡角色
                                        game.dead' + - '
                                      • 玩家
                                        game.me
                                      • 玩家的上/下家
                                        game.me.previous/next' + - '
                                      • 玩家的上/下家(含阵亡)
                                        game.me.previousSeat/
                                        nextSeat' + - '
                                      • 牌堆
                                        ui.cardPile
                                      • 弃牌堆
                                        ui.discardPile
                                      ' + + help = { + 关于游戏: + '
                                      关于无名杀
                                      • 无名杀官方发布地址仅有GitHub仓库!
                                        点击前往Github仓库
                                      • 无名杀基于GPLv3开源协议。
                                        点击查看GPLv3协议
                                      • 其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!', + 游戏操作: + "
                                        • 长按/鼠标悬停/右键单击显示信息。
                                        • 触屏模式中,双指点击切换暂停;下划显示菜单,上划切换托管。
                                        • 键盘快捷键
                                          " + + "
                                          A切换托管
                                          W切换不询问无懈
                                          空格暂停
                                        • 编辑牌堆
                                          在卡牌包中修改牌堆后,将自动创建一个临时牌堆,在所有模式中共用,当保存当前牌堆后,临时牌堆被清除。每个模式可设置不同的已保存牌堆,设置的牌堆优先级大于临时牌堆。
                                        ", + 游戏命令: + '
                                        变量名
                                        • 场上角色
                                          game.players
                                        • 阵亡角色
                                          game.dead' + + "
                                        • 玩家
                                          game.me
                                        • 玩家的上/下家
                                          game.me.previous/next" + + "
                                        • 玩家的上/下家(含阵亡)
                                          game.me.previousSeat/
                                          nextSeat" + + "
                                        • 牌堆
                                          ui.cardPile
                                        • 弃牌堆
                                          ui.discardPile
                                        " + '
                                        角色属性
                                        • 体力值
                                          player.hp' + '
                                        • 体力上限
                                          player.maxHp
                                        • 身份
                                          player.identity
                                        • 手牌
                                          player.getCards("h")
                                        • 装备牌
                                          player.getCards("e")
                                        • 判定牌
                                          player.getCards("j")' + - '
                                        • 是否存活/横置/翻面
                                          player.isAlive()/
                                          isLinked()/
                                          isTurnedOver()
                                        ' + + "
                                      • 是否存活/横置/翻面
                                        player.isAlive()/
                                        isLinked()/
                                        isTurnedOver()
                                      " + '
                                      角色操作
                                      • 受到伤害
                                        player.damage(source,
                                        num)' + - '
                                      • 回复体力
                                        player.recover(num)
                                      • 摸牌
                                        player.draw(num)
                                      • 获得牌
                                        player.gain(cards)
                                      • 弃牌
                                        player.discard(cards)' + - '
                                      • 使用卡牌
                                        player.useCard(card,
                                        targets)
                                      • 死亡
                                        player.die()
                                      • 复活
                                        player.revive(hp)
                                      ' + + "
                                    • 回复体力
                                      player.recover(num)
                                    • 摸牌
                                      player.draw(num)
                                    • 获得牌
                                      player.gain(cards)
                                    • 弃牌
                                      player.discard(cards)" + + "
                                    • 使用卡牌
                                      player.useCard(card,
                                      targets)
                                    • 死亡
                                      player.die()
                                    • 复活
                                      player.revive(hp)
                                    " + '
                                    游戏操作
                                    • 在命令框中输出结果
                                      game.print(str)
                                    • 清除命令框中的内容
                                      cls
                                    • 上一条/下一条输入的内容
                                      up/down
                                    • 游戏结束
                                      game.over(bool)' + - '
                                    • 角色资料
                                      lib.character
                                    • 卡牌资料
                                      lib.card
                                    ', - '游戏名词': '
                                    • 智囊:无名杀默认为过河拆桥/无懈可击/无中生有/洞烛先机。牌堆中没有的智囊牌会被过滤。可在卡牌设置中自行增减。若没有可用的智囊,则改为随机选取的三种锦囊牌的牌名。' + - '
                                    • 仁库:部分武将使用的游戏外共通区域。至多包含六张牌。当有新牌注入后,若牌数超过上限,则将最早进入仁库的溢出牌置入弃牌堆。' + - '
                                    • 护甲:和体力类似,每点护甲可抵挡1点伤害,但不影响手牌上限。' + - '
                                    • 随从:通过技能获得,拥有独立的技能、手牌区和装备区(共享判定区),出场时替代主武将的位置;随从死亡时自动切换回主武将。' + - '
                                    • 发现:从三张随机亮出的牌中选择一张,若无特殊说明,则获得此牌。' + - '
                                    • 蓄能技:发动时可以增大黄色的数字。若如此做,红色数字于技能的结算过程中改为原来的两倍。' + - '
                                    • 施法:若技能的拥有者未拥有等待执行的同名“施法”效果,则其可以发动“施法”技能。其须选择声明一个数字X(X∈[1, 3]),在此之后的第X个回合结束时,其执行“施法”效果,且效果中的数字X视为与技能发动者声明的X相同。' + - '
                                    • 共同拼点:一种特殊的拼点结算。发起者与被指定的拼点目标同时亮出拼点牌,进行一次决算:其中拼点牌点数唯一最大的角色赢,其他角色均没赢;若没有点数唯一最大的拼点牌,则所有角色拼点均没赢。' + - '
                                    • 强令:若一名角色拥有带有“强令”的技能,则该技能的发动时机为“出牌阶段开始时”。若技能拥有者发动该技能,其须发布“强令”给一名其他角色,并在对应技能的时间节点加以判断目标角色是否成功完成该强令所要求的任务条件。成功或失败则会根据技能效果执行不同结算流程。' + - '
                                    • 摧坚:若一名角色拥有带有“摧坚”的技能,则该技能的发动时机为“当你使用伤害牌指定第一个目标后”。你可以对其中一个目标发动“摧坚”技能,然后执行后续效果。其中,后续效果里的X等于该目标的非charlotte技能的数量。' + - '
                                    • 妄行:一种特殊的选项。若一名角色拥有带有“妄行”的技能,则该技能触发时,你须选择声明一个数字X(X∈{1,2,3,4}),技能后续中的X即为你选择的数字。选择完毕后,你获得如下效果:回合结束时,你选择一项:1.弃置X张牌;2.减1点体力上限。' + - '
                                    • 搏击:若一名角色拥有带有“搏击”的技能,则当该搏击技能触发时,若本次技能的目标角色在你攻击范围内,且你在其攻击范围内,则你执行技能主体效果时,同时额外执行“搏击”后的额外效果。' + - '
                                    • 游击:若一名角色拥有带有“游击”的技能,则当该游击技能执行至“游击”处时,若本次技能的目标角色在你的攻击范围内,且你不在其攻击范围内,则你可以执行“游击”后的额外效果。' + - '
                                    • 激昂:一名角色发动“昂扬技”标签技能后,此技能失效,直至从此刻至满足此技能“激昂”条件后。' + - '
                                    • 历战:一名角色的回合结束时,若本回合发动过拥有历战效果的技能,则对此技能效果的进行等同于发动次数的永久可叠加式升级或修改。' + - '' + "
                                    • 角色资料
                                      lib.character
                                    • 卡牌资料
                                      lib.card
                                    ", + 游戏名词: + "
                                    • 智囊:无名杀默认为过河拆桥/无懈可击/无中生有/洞烛先机。牌堆中没有的智囊牌会被过滤。可在卡牌设置中自行增减。若没有可用的智囊,则改为随机选取的三种锦囊牌的牌名。" + + "
                                    • 仁库:部分武将使用的游戏外共通区域。至多包含六张牌。当有新牌注入后,若牌数超过上限,则将最早进入仁库的溢出牌置入弃牌堆。" + + "
                                    • 护甲:和体力类似,每点护甲可抵挡1点伤害,但不影响手牌上限。" + + "
                                    • 随从:通过技能获得,拥有独立的技能、手牌区和装备区(共享判定区),出场时替代主武将的位置;随从死亡时自动切换回主武将。" + + "
                                    • 发现:从三张随机亮出的牌中选择一张,若无特殊说明,则获得此牌。" + + "
                                    • 蓄能技:发动时可以增大黄色的数字。若如此做,红色数字于技能的结算过程中改为原来的两倍。" + + "
                                    • 施法:若技能的拥有者未拥有等待执行的同名“施法”效果,则其可以发动“施法”技能。其须选择声明一个数字X(X∈[1, 3]),在此之后的第X个回合结束时,其执行“施法”效果,且效果中的数字X视为与技能发动者声明的X相同。" + + "
                                    • 共同拼点:一种特殊的拼点结算。发起者与被指定的拼点目标同时亮出拼点牌,进行一次决算:其中拼点牌点数唯一最大的角色赢,其他角色均没赢;若没有点数唯一最大的拼点牌,则所有角色拼点均没赢。" + + "
                                    • 强令:若一名角色拥有带有“强令”的技能,则该技能的发动时机为“出牌阶段开始时”。若技能拥有者发动该技能,其须发布“强令”给一名其他角色,并在对应技能的时间节点加以判断目标角色是否成功完成该强令所要求的任务条件。成功或失败则会根据技能效果执行不同结算流程。" + + "
                                    • 摧坚:若一名角色拥有带有“摧坚”的技能,则该技能的发动时机为“当你使用伤害牌指定第一个目标后”。你可以对其中一个目标发动“摧坚”技能,然后执行后续效果。其中,后续效果里的X等于该目标的非charlotte技能的数量。" + + "
                                    • 妄行:一种特殊的选项。若一名角色拥有带有“妄行”的技能,则该技能触发时,你须选择声明一个数字X(X∈{1,2,3,4}),技能后续中的X即为你选择的数字。选择完毕后,你获得如下效果:回合结束时,你选择一项:1.弃置X张牌;2.减1点体力上限。" + + "
                                    • 搏击:若一名角色拥有带有“搏击”的技能,则当该搏击技能触发时,若本次技能的目标角色在你攻击范围内,且你在其攻击范围内,则你执行技能主体效果时,同时额外执行“搏击”后的额外效果。" + + "
                                    • 游击:若一名角色拥有带有“游击”的技能,则当该游击技能执行至“游击”处时,若本次技能的目标角色在你的攻击范围内,且你不在其攻击范围内,则你可以执行“游击”后的额外效果。" + + "
                                    • 激昂:一名角色发动“昂扬技”标签技能后,此技能失效,直至从此刻至满足此技能“激昂”条件后。" + + "
                                    • 历战:一名角色的回合结束时,若本回合发动过拥有历战效果的技能,则对此技能效果的进行等同于发动次数的永久可叠加式升级或修改。" + + "", }; /** * @type {import('path')} */ // @ts-ignore - static path = {}; - static getErrorTip(msg) { - if (typeof msg != 'string') { + path = {}; + getErrorTip(msg) { + if (typeof msg != "string") { try { msg = msg.toString(); - if (typeof msg != 'string') throw 'err'; + if (typeof msg != "string") throw "err"; } catch (_) { - throw '传参错误:' + msg; + throw "传参错误:" + msg; } } - if (msg.startsWith('Uncaught ')) msg = msg.slice(9); + if (msg.startsWith("Uncaught ")) msg = msg.slice(9); let newMessage = msg; if (/RangeError/.test(newMessage)) { if (newMessage.includes("Maximum call stack size exceeded")) { newMessage = "堆栈溢出"; } else if (/argument must be between 0 and 20/.test(newMessage)) { - let funName = newMessage.slice(newMessage.indexOf('RangeError: ') + 12, newMessage.indexOf(')') + 1); + let funName = newMessage.slice( + newMessage.indexOf("RangeError: ") + 12, + newMessage.indexOf(")") + 1 + ); newMessage = funName + "参数必须在0和20之间"; } else { newMessage = "传递错误值到数值计算方法"; @@ -7553,13 +7925,17 @@ export class Library extends Uninstantable { } else if (/ReferenceError/.test(newMessage)) { let messageName; if (newMessage.includes("is not defined")) { - messageName = newMessage.replace('ReferenceError: ', '').replace(' is not defined', ''); + messageName = newMessage.replace("ReferenceError: ", "").replace(" is not defined", ""); newMessage = "引用了一个未定义的变量:" + messageName; } else if (newMessage.includes("invalid assignment left-hand side")) { newMessage = "赋值运算符或比较运算符不匹配"; } else if (newMessage.includes("Octal literals are not allowed in strict mode")) { newMessage = "八进制字面量与八进制转义序列语法已经被废弃"; - } else if (newMessage.includes("Illegal 'use strict' directive in function with non-simple parameter list")) { + } else if ( + newMessage.includes( + "Illegal 'use strict' directive in function with non-simple parameter list" + ) + ) { newMessage = "'use strict'指令不能使用在带有‘非简单参数’列表的函数"; } else if (newMessage.includes("Invalid left-hand side in assignment")) { newMessage = "赋值中的左侧无效,即number,string等不可赋值的非变量数据"; @@ -7567,10 +7943,13 @@ export class Library extends Uninstantable { } else if (/SyntaxError/.test(newMessage)) { let messageName; if (newMessage.includes("Unexpected token ")) { - messageName = newMessage.replace('SyntaxError: Unexpected token ', ''); + messageName = newMessage.replace("SyntaxError: Unexpected token ", ""); newMessage = "使用了未定义或错误的语法 : (" + messageName + ")"; - } else if (newMessage.includes( - "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")) { + } else if ( + newMessage.includes( + "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode" + ) + ) { newMessage = "请在严格模式下运行let,const,class"; } else if (newMessage.includes("for-of loop variable declaration may not have an initializer.")) { newMessage = "for...of 循环的头部包含有初始化表达式"; @@ -7595,24 +7974,31 @@ export class Library extends Uninstantable { } else if (newMessage.includes("Unexpected end of input")) { newMessage = "遗漏了符号或符号顺序不对(小括号,花括号等)"; } else if (newMessage.includes("has already been declared")) { - messageName = newMessage.replace('SyntaxError: Identifier ', '').replace(' has already been declared', ''); + messageName = newMessage + .replace("SyntaxError: Identifier ", "") + .replace(" has already been declared", ""); newMessage = messageName + "变量已经被声明过,不能被重新声明"; } else if (newMessage.includes("Duplicate parameter name not allowed in this context")) { newMessage = "参数名不允许重复"; - } else if (newMessage.includes("Unexpected reserved word") || newMessage.includes( - "Unexpected strict mode reserved word")) { + } else if ( + newMessage.includes("Unexpected reserved word") || + newMessage.includes("Unexpected strict mode reserved word") + ) { newMessage = "保留字被用作标记符"; } } else if (/TypeError/.test(newMessage)) { let messageName; if (newMessage.includes(" is not a function")) { - messageName = newMessage.replace('TypeError: ', '').replace(' is not a function', ''); + messageName = newMessage.replace("TypeError: ", "").replace(" is not a function", ""); newMessage = messageName + "不是一个函数"; } else if (newMessage.includes(" is not a constructor")) { - messageName = newMessage.replace('TypeError: ', '').replace(' is not a constructor', ''); + messageName = newMessage.replace("TypeError: ", "").replace(" is not a constructor", ""); newMessage = messageName + "不是一个构造函数"; } else if (newMessage.includes("Cannot read property")) { - messageName = newMessage.replace('TypeError: Cannot read property ', '').replace(' of null', '').replace(' of undefined', ''); + messageName = newMessage + .replace("TypeError: Cannot read property ", "") + .replace(" of null", "") + .replace(" of undefined", ""); let ofName = newMessage.slice(newMessage.indexOf(" of ") + 4); newMessage = "无法读取'" + ofName + "'的属性值" + messageName; } else if (newMessage.includes("Cannot read properties")) { @@ -7620,19 +8006,23 @@ export class Library extends Uninstantable { let ofName = newMessage.slice(newMessage.indexOf(" of ") + 4, newMessage.indexOf("(") - 1); newMessage = "无法读取'" + ofName + "'的属性值" + messageName; } else if (newMessage.includes("Property description must be an object")) { - messageName = newMessage.replace('TypeError: Property description must be an object: ', ''); + messageName = newMessage.replace("TypeError: Property description must be an object: ", ""); newMessage = messageName + "是非对象类型的值"; } else if (newMessage.includes("Cannot assign to read only property ")) { - messageName = newMessage.slice(47, newMessage.lastIndexOf(' of ') + 1); + messageName = newMessage.slice(47, newMessage.lastIndexOf(" of ") + 1); newMessage = messageName + "属性禁止写入"; } else if (newMessage.includes("Object prototype may only be an Object or null")) { newMessage = messageName + "对象原型只能是对象或null"; } else if (newMessage.includes("Cannot create property")) { - messageName = newMessage.slice(newMessage.indexOf('\'') + 1); - messageName = messageName.slice(0, messageName.indexOf('\'')); + messageName = newMessage.slice(newMessage.indexOf("'") + 1); + messageName = messageName.slice(0, messageName.indexOf("'")); let obj = newMessage.slice(newMessage.indexOf(messageName) + 16); - newMessage = obj + "不能添加或修改'" + messageName + "'属性,任何 Primitive 值都不允许有property"; - } else if (newMessage.includes("Can't add property") && newMessage.includes("is not extensible")) { + newMessage = + obj + "不能添加或修改'" + messageName + "'属性,任何 Primitive 值都不允许有property"; + } else if ( + newMessage.includes("Can't add property") && + newMessage.includes("is not extensible") + ) { newMessage = "对象不可添加属性(不可扩展)"; } else if (newMessage.includes("Cannot redefine property")) { messageName = newMessage.slice(37); @@ -7643,7 +8033,8 @@ export class Library extends Uninstantable { } else if (newMessage.includes("Cannot use 'in' operator to search for ")) { newMessage = "in不能用来在字符串、数字或者其他基本类型的数据中进行检索"; } else if (newMessage.includes("Right-hand side of 'instanceof' is not an object")) { - newMessage = "instanceof 操作符 希望右边的操作数为一个构造对象,即一个有 prototype 属性且可以调用的对象"; + newMessage = + "instanceof 操作符 希望右边的操作数为一个构造对象,即一个有 prototype 属性且可以调用的对象"; } else if (newMessage.includes("Assignment to constant variable")) { newMessage = "const定义的变量不可修改"; } else if (newMessage.includes("Cannot delete property")) { @@ -7672,9 +8063,9 @@ export class Library extends Uninstantable { return newMessage; } } - static codeMirrorReady(node, editor) { + codeMirrorReady(node, editor) { ui.window.appendChild(node); - node.style.fontSize = 20 / game.documentZoom + 'px'; + node.style.fontSize = 20 / game.documentZoom + "px"; const mirror = window.CodeMirror(editor, { value: node.code, mode: "javascript", @@ -7684,18 +8075,18 @@ export class Library extends Uninstantable { autoCloseBrackets: true, fixedGutter: false, hintOptions: { completeSingle: false }, - theme: lib.config.codeMirror_theme || 'mdn-like', + theme: lib.config.codeMirror_theme || "mdn-like", extraKeys: { - "Ctrl-Z": "undo",//撤销 - "Ctrl-Y": "redo",//恢复撤销 + "Ctrl-Z": "undo", //撤销 + "Ctrl-Y": "redo", //恢复撤销 //"Ctrl-A":"selectAll",//全选 }, }); - lib.setScroll(editor.querySelector('.CodeMirror-scroll')); + lib.setScroll(editor.querySelector(".CodeMirror-scroll")); node.aced = true; node.editor = mirror; setTimeout(() => mirror.refresh(), 0); - node.editor.on('change', (e, change) => { + node.editor.on("change", (e, change) => { let code; if (node.editor) { code = node.editor.getValue(); @@ -7703,9 +8094,12 @@ export class Library extends Uninstantable { code = node.textarea.value; } //动态绑定文本 - if (code.length && change.origin == "+input" && + if ( + code.length && + change.origin == "+input" && /{|}|\s|=|;|:|,|,|。|?|!|!|\?|&|#|%|@|‘|’|;/.test(change.text[0]) == false && - change.text.length == 1) { + change.text.length == 1 + ) { //输入了代码,并且不包括空格,{},=, ; , : , 逗号等,才可以自动提示 node.editor.showHint(); } @@ -7713,7 +8107,7 @@ export class Library extends Uninstantable { //防止每次输出字符都创建以下元素 const event = _status.event; const trigger = _status.event; - const player = ui.create.player().init('sunce'); + const player = ui.create.player().init("sunce"); const target = player; const targets = [player]; const source = player; @@ -7721,18 +8115,20 @@ export class Library extends Uninstantable { const cards = [card]; const result = { bool: true }; function forEach(arr, f) { - Array.from(arr).forEach(v => f(v)); + Array.from(arr).forEach((v) => f(v)); } function forAllProps(obj, callback) { if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) { for (let name in obj) callback(name); } else { - for (let o = obj; o; o = Object.getPrototypeOf(o)) Object.getOwnPropertyNames(o).forEach(callback); + for (let o = obj; o; o = Object.getPrototypeOf(o)) + Object.getOwnPropertyNames(o).forEach(callback); } } function scriptHint(editor, keywords, getToken, options) { //Find the token at the cursor - let cur = editor.getCursor(), token = editor.getTokenAt(cur); + let cur = editor.getCursor(), + token = editor.getTokenAt(cur); if (/\b(?:string|comment)\b/.test(token.type)) return; const innerMode = CodeMirror.innerMode(editor.getMode(), token.state); if (innerMode.mode.helperType === "json") return; @@ -7744,13 +8140,14 @@ export class Library extends Uninstantable { end: cur.ch, string: "", state: token.state, - type: token.string == "." ? "property" : null + type: token.string == "." ? "property" : null, }; } else if (token.end > cur.ch) { token.end = cur.ch; token.string = token.string.slice(0, cur.ch - token.start); } - let tprop = token, context; + let tprop = token, + context; //If it is a property, find out what it is a property of. while (tprop.type == "property") { tprop = editor.getTokenAt(CodeMirror.Pos(cur.line, tprop.start)); @@ -7763,22 +8160,44 @@ export class Library extends Uninstantable { let obj; if (Array.isArray(context)) { try { - const code = context.length == 1 ? context[0].string : context.reduceRight((pre, cur) => (pre.string || pre) + '.' + cur.string); + const code = + context.length == 1 + ? context[0].string + : context.reduceRight((pre, cur) => (pre.string || pre) + "." + cur.string); obj = eval(code); if (![null, undefined].includes(obj)) { - const keys = Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(obj))).filter(key => key.startsWith(token.string)); + const keys = Object.getOwnPropertyNames(obj) + .concat(Object.getOwnPropertyNames(Object.getPrototypeOf(obj))) + .filter((key) => key.startsWith(token.string)); list.addArray(keys); } - } catch (_) { return; } - } else if (token && typeof token.string == 'string') { + } catch (_) { + return; + } + } else if (token && typeof token.string == "string") { //非开发者模式下,提示这些单词 - list.addArray(['player', 'card', 'cards', 'result', 'trigger', 'source', 'target', 'targets', 'lib', 'game', 'ui', 'get', 'ai', '_status']); + list.addArray([ + "player", + "card", + "cards", + "result", + "trigger", + "source", + "target", + "targets", + "lib", + "game", + "ui", + "get", + "ai", + "_status", + ]); } return { list: [...new Set(getCompletions(token, context, keywords, options).concat(list))] - .filter(key => key.startsWith(token.string)) - .sort((a, b) => (a + '').localeCompare(b + '')) - .map(text => { + .filter((key) => key.startsWith(token.string)) + .sort((a, b) => (a + "").localeCompare(b + "")) + .map((text) => { return { render(elt, data, cur) { var icon = document.createElement("span"); @@ -7791,38 +8210,31 @@ export class Library extends Uninstantable { } catch { void 0; } - if (type == 'function') { - className += 'function'; - } - else if (type == 'string') { - className += 'text'; - } - else if (type == 'boolean') { - className += 'variable'; - } - else { - className += 'namespace'; + if (type == "function") { + className += "function"; + } else if (type == "string") { + className += "text"; + } else if (type == "boolean") { + className += "variable"; + } else { + className += "namespace"; } } else { if (javascriptKeywords.includes(text)) { - className += 'keyword'; - } - else if (window[text]) { + className += "keyword"; + } else if (window[text]) { const type = typeof window[text]; - if (type == 'function') { - className += 'function'; - } - else if (type == 'string') { - className += 'text'; - } - else if (text == 'window' || type == 'boolean') { - className += 'variable'; - } - else { - className += 'namespace'; + if (type == "function") { + className += "function"; + } else if (type == "string") { + className += "text"; + } else if (text == "window" || type == "boolean") { + className += "variable"; + } else { + className += "namespace"; } } else { - className += 'namespace'; + className += "namespace"; } } icon.className = className; @@ -7834,21 +8246,32 @@ export class Library extends Uninstantable { }; }), from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end) + to: CodeMirror.Pos(cur.line, token.end), }; } function javascriptHint(editor, options) { - return scriptHint(editor, javascriptKeywords, function (e, cur) { return e.getTokenAt(cur); }, options); + return scriptHint( + editor, + javascriptKeywords, + function (e, cur) { + return e.getTokenAt(cur); + }, + options + ); } //覆盖原本的javascript提示 CodeMirror.registerHelper("hint", "javascript", javascriptHint); const stringProps = Object.getOwnPropertyNames(String.prototype); const arrayProps = Object.getOwnPropertyNames(Array.prototype); const funcProps = Object.getOwnPropertyNames(Array.prototype); - const javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends from false finally for function " + - "if in import instanceof let new null return super switch this throw true try typeof var void while with yield").split(" "); + const javascriptKeywords = ( + "break case catch class const continue debugger default delete do else export extends from false finally for function " + + "if in import instanceof let new null return super switch this throw true try typeof var void while with yield" + ).split(" "); function getCompletions(token, context, keywords, options) { - let found = [], start = token.string, global = options && options.globalScope || window; + let found = [], + start = token.string, + global = (options && options.globalScope) || window; function maybeAdd(str) { if (str.lastIndexOf(start, 0) == 0 && !found.includes(str)) found.push(str); } @@ -7861,48 +8284,50 @@ export class Library extends Uninstantable { if (context && context.length) { //If this is a property, see if it belongs to some object we can //find in the current environment. - let obj = context.pop(), base; + let obj = context.pop(), + base; if (obj.type && obj.type.indexOf("variable") === 0) { - if (options && options.additionalContext) - base = options.additionalContext[obj.string]; - if (!options || options.useGlobalScope !== false) - base = base || global[obj.string]; + if (options && options.additionalContext) base = options.additionalContext[obj.string]; + if (!options || options.useGlobalScope !== false) base = base || global[obj.string]; } else if (obj.type == "string") { base = ""; } else if (obj.type == "atom") { base = 1; } else if (obj.type == "function") { - if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && (typeof global.jQuery == 'function')) + if ( + global.jQuery != null && + (obj.string == "$" || obj.string == "jQuery") && + typeof global.jQuery == "function" + ) base = global.jQuery(); - else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) + else if (global._ != null && obj.string == "_" && typeof global._ == "function") base = global._(); } - while (base != null && context.length) - base = base[context.pop().string]; + while (base != null && context.length) base = base[context.pop().string]; if (base != null) gatherCompletions(base); } else { //If not, just look in the global object, any local scope, and optional additional-context //(reading into JS mode internals to get at the local and global variables) for (let v = token.state.localVars; v; v = v.next) maybeAdd(v.name); - for (let c = token.state.context; c; c = c.prev) for (let v = c.vars; v; v = v.next) maybeAdd(v.name); + for (let c = token.state.context; c; c = c.prev) + for (let v = c.vars; v; v = v.next) maybeAdd(v.name); for (let v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); - if (options && options.additionalContext != null) for (let key in options.additionalContext) maybeAdd(key); + if (options && options.additionalContext != null) + for (let key in options.additionalContext) maybeAdd(key); if (!options || options.useGlobalScope !== false) gatherCompletions(global); forEach(keywords, maybeAdd); } - return found.sort((a, b) => (a + '').localeCompare(b + '')); + return found.sort((a, b) => (a + "").localeCompare(b + "")); } } - static setIntro(node, func, left) { + setIntro(node, func, left) { if (lib.config.touchscreen) { if (left) { node.listen(ui.click.touchintro); - } - else { + } else { lib.setLongPress(node, ui.click.intro); } - } - else { + } else { if (left) { node.listen(ui.click.intro); } @@ -7920,7 +8345,7 @@ export class Library extends Uninstantable { node._customintro = func; } } - static setPopped(node, func, width, height, forceclick, paused2) { + setPopped(node, func, width, height, forceclick, paused2) { node._poppedfunc = func; node._poppedwidth = width; node._poppedheight = height; @@ -7929,22 +8354,24 @@ export class Library extends Uninstantable { } if (lib.config.touchscreen || forceclick) { node.listen(ui.click.hoverpopped); - } - else { - node.addEventListener('mouseenter', ui.click.hoverpopped); + } else { + node.addEventListener("mouseenter", ui.click.hoverpopped); // node.addEventListener('mouseleave',ui.click.hoverpopped_leave); } if (paused2) { node._paused2 = true; } } - static placePoppedDialog(dialog, e) { + placePoppedDialog(dialog, e) { if (dialog._place_text) { - if (dialog._place_text.firstChild.offsetWidth >= 190 || dialog._place_text.firstChild.offsetHeight >= 30) { - dialog._place_text.style.marginLeft = '14px'; - dialog._place_text.style.marginRight = '14px'; - dialog._place_text.style.textAlign = 'left'; - dialog._place_text.style.width = 'calc(100% - 28px)'; + if ( + dialog._place_text.firstChild.offsetWidth >= 190 || + dialog._place_text.firstChild.offsetHeight >= 30 + ) { + dialog._place_text.style.marginLeft = "14px"; + dialog._place_text.style.marginRight = "14px"; + dialog._place_text.style.textAlign = "left"; + dialog._place_text.style.width = "calc(100% - 28px)"; } } if (e.touches && e.touches[0]) { @@ -7954,52 +8381,50 @@ export class Library extends Uninstantable { if (dialog._mod_height) { height += dialog._mod_height; } - dialog.style.height = height + 'px'; + dialog.style.height = height + "px"; if (e.clientX / game.documentZoom < ui.window.offsetWidth / 2) { - dialog.style.left = (e.clientX / game.documentZoom + 10) + 'px'; - } - else { - dialog.style.left = (e.clientX / game.documentZoom - dialog.offsetWidth - 10) + 'px'; + dialog.style.left = e.clientX / game.documentZoom + 10 + "px"; + } else { + dialog.style.left = e.clientX / game.documentZoom - dialog.offsetWidth - 10 + "px"; } var idealtop = (e.clientY || 0) / game.documentZoom - dialog.offsetHeight / 2; - if (typeof idealtop != 'number' || isNaN(idealtop) || idealtop <= 5) { + if (typeof idealtop != "number" || isNaN(idealtop) || idealtop <= 5) { idealtop = 5; - } - else if (idealtop + dialog.offsetHeight + 10 > ui.window.offsetHeight) { + } else if (idealtop + dialog.offsetHeight + 10 > ui.window.offsetHeight) { idealtop = ui.window.offsetHeight - 10 - dialog.offsetHeight; } - dialog.style.top = idealtop + 'px'; + dialog.style.top = idealtop + "px"; } - static setHover(node, func, hoveration, width) { + setHover(node, func, hoveration, width) { node._hoverfunc = func; - if (typeof hoveration == 'number') { + if (typeof hoveration == "number") { node._hoveration = hoveration; } - if (typeof width == 'number') { + if (typeof width == "number") { node._hoverwidth = width; } - node.addEventListener('mouseenter', ui.click.mouseenter); - node.addEventListener('mouseleave', ui.click.mouseleave); - node.addEventListener('mousedown', ui.click.mousedown); - node.addEventListener('mousemove', ui.click.mousemove); + node.addEventListener("mouseenter", ui.click.mouseenter); + node.addEventListener("mouseleave", ui.click.mouseleave); + node.addEventListener("mousedown", ui.click.mousedown); + node.addEventListener("mousemove", ui.click.mousemove); return node; } - static setScroll(node) { + setScroll(node) { node.ontouchstart = ui.click.touchStart; node.ontouchmove = ui.click.touchScroll; - node.style.webkitOverflowScrolling = 'touch'; + node.style.webkitOverflowScrolling = "touch"; return node; } - static setMousewheel(node) { + setMousewheel(node) { if (lib.config.mousewheel) node.onmousewheel = ui.click.mousewheel; } - static setLongPress(node, func) { - node.addEventListener('touchstart', ui.click.longpressdown); - node.addEventListener('touchend', ui.click.longpresscancel); + setLongPress(node, func) { + node.addEventListener("touchstart", ui.click.longpressdown); + node.addEventListener("touchend", ui.click.longpresscancel); node._longpresscallback = func; return node; } - static updateCanvas(time) { + updateCanvas(time) { if (lib.canvasUpdates.length === 0) { lib.status.canvas = false; return false; @@ -8008,8 +8433,8 @@ export class Library extends Uninstantable { ui.canvas.height = ui.arena.offsetHeight; var ctx = ui.ctx; ctx.shadowBlur = 5; - ctx.shadowColor = 'rgba(0,0,0,0.3)'; - ctx.strokeStyle = 'white'; + ctx.shadowColor = "rgba(0,0,0,0.3)"; + ctx.strokeStyle = "white"; // ctx.lineCap='round'; ctx.lineWidth = 3; ctx.save(); @@ -8025,10 +8450,10 @@ export class Library extends Uninstantable { } } } - static run(time) { + run(time) { lib.status.time = time; for (var i = 0; i < lib.updates.length; i++) { - if (!('_time' in lib.updates[i])) { + if (!("_time" in lib.updates[i])) { lib.updates[i]._time = time; } if (lib.updates[i](time - lib.updates[i]._time - lib.status.delayed) === false) { @@ -8037,32 +8462,43 @@ export class Library extends Uninstantable { } if (lib.updates.length) { lib.status.frameId = requestAnimationFrame(lib.run); - } - else { + } else { lib.status.time = 0; lib.status.delayed = 0; } } - static getUTC(date) { + getUTC(date) { return date.getTime(); } - static saveVideo() { + saveVideo() { if (_status.videoToSave) { - game.export(lib.init.encode(JSON.stringify(_status.videoToSave)), - '无名杀 - 录像 - ' + _status.videoToSave.name[0] + ' - ' + _status.videoToSave.name[1]); + game.export( + lib.init.encode(JSON.stringify(_status.videoToSave)), + "无名杀 - 录像 - " + _status.videoToSave.name[0] + " - " + _status.videoToSave.name[1] + ); } } - static genAsync(fn) { return gnc.of(fn); } - static genAwait(item) { return gnc.is.generator(item) ? gnc.of(function* () { for (const content of item) { yield content; } })() : Promise.resolve(item); } - static gnc = { - of: fn => gnc.of(fn), + genAsync(fn) { + return gnc.of(fn); + } + genAwait(item) { + return gnc.is.generator(item) + ? gnc.of(function* () { + for (const content of item) { + yield content; + } + })() + : Promise.resolve(item); + } + gnc = { + of: (fn) => gnc.of(fn), is: { - coroutine: item => gnc.is.coroutine(item), - generatorFunc: item => gnc.is.generatorFunc(item), - generator: item => gnc.is.generator(item) - } + coroutine: (item) => gnc.is.coroutine(item), + generatorFunc: (item) => gnc.is.generatorFunc(item), + generator: (item) => gnc.is.generator(item), + }, }; - static comparator = { + comparator = { equals: function () { if (arguments.length == 0) return false; if (arguments.length == 1) return true; @@ -8093,9 +8529,9 @@ export class Library extends Uninstantable { const type = typeof arguments[0]; for (let i = 1; i < arguments.length; ++i) if (type !== arguments[i]) return false; return true; - } + }, }; - static creation = { + creation = { get array() { return []; }, @@ -8107,22 +8543,30 @@ export class Library extends Uninstantable { }, get string() { return ""; - } + }, }; - static linq = { + linq = { cselector: { - hasAttr: name => `[${name}]`, + hasAttr: (name) => `[${name}]`, isAttr: (name, item) => `[${name}=${item}]`, inAttr: (name, item) => `[${name}~=${item}]`, conAttr: (name, item) => `[${name}*=${item}]`, onAttr: (name, item) => `[${name}|=${item}]`, bgnAttr: (name, item) => `[${name}^=${item}]`, endAttr: (name, item) => `[${name}^=${item}]`, - merge: function () { return Array.from(arguments).join(" "); }, - of: function () { return Array.from(arguments).join(""); }, - class: function () { return `.${Array.from(arguments).join(".")}`; }, - group: function () { return Array.from(arguments).join(","); }, - media: type => `@media ${type}` + merge: function () { + return Array.from(arguments).join(" "); + }, + of: function () { + return Array.from(arguments).join(""); + }, + class: function () { + return `.${Array.from(arguments).join(".")}`; + }, + group: function () { + return Array.from(arguments).join(","); + }, + media: (type) => `@media ${type}`, }, dom: { attributes: { @@ -8130,9 +8574,9 @@ export class Library extends Uninstantable { return { _type: "style", name: name, - value: value + value: value, }; - } + }, }, inject(element, options) { //处理id和class @@ -8144,7 +8588,8 @@ export class Library extends Uninstantable { } //处理属性 if (options.attributes) { - for (const item in options.attributes) element.setAttribute(item, options.attributes[item]); + for (const item in options.attributes) + element.setAttribute(item, options.attributes[item]); } //处理样式 if (options.style) { @@ -8175,8 +8620,7 @@ export class Library extends Uninstantable { const type = item["_type"]; if (!(type in result)) result[type] = lib.creation.nullObject; result[type][item.name] = item.value; - } - else { + } else { if (!("style" in result)) result.style = lib.creation.nullObject; for (const name in item) { result.style[name] = item[name]; @@ -8194,8 +8638,7 @@ export class Library extends Uninstantable { if (!("identity" in result)) result.identity = lib.creation.array; const identities = item.split(".").filter(Boolean); for (const item of identities) result.identity.add(item); - } - else result.content = item; + } else result.content = item; break; } } @@ -8205,17 +8648,17 @@ export class Library extends Uninstantable { return { _type: "attributes", name: name, - value: value + value: value, }; }, div() { const dom = lib.linq.dom; return dom.inject(document.createElement("div"), dom.generate(...arguments)); - } - } + }, + }, }; - static init = LibInit; - static cheat = { + init = new LibInit(); + cheat = { /** * 将游戏内部的对象暴露到全局中 * @@ -8236,7 +8679,7 @@ export class Library extends Uninstantable { dy() { let next = game.me.next; for (let i = 0; i < 10; i++) { - if (next.identity != 'zhu') { + if (next.identity != "zhu") { break; } next = next.next; @@ -8256,29 +8699,32 @@ export class Library extends Uninstantable { * @param { (folders: string[], files: string[]) => any } callback */ const gl = function (dir, callback) { - const files = [], folders = []; + const files = [], + folders = []; // dir = '/Users/widget/Documents/extension/' + dir; - dir = lib.node.path.join(__dirname, 'extension', dir); - lib.node.fs.promises.readdir(dir).then(filelist => { - for (let i = 0; i < filelist.length; i++) { - if (filelist[i][0] != '.' && filelist[i][0] != '_') { - if (lib.node.fs.statSync(dir + '/' + filelist[i]).isDirectory()) { - folders.push(filelist[i]); - } - else { - files.push(filelist[i]); + dir = lib.node.path.join(__dirname, "extension", dir); + lib.node.fs.promises + .readdir(dir) + .then((filelist) => { + for (let i = 0; i < filelist.length; i++) { + if (filelist[i][0] != "." && filelist[i][0] != "_") { + if (lib.node.fs.statSync(dir + "/" + filelist[i]).isDirectory()) { + folders.push(filelist[i]); + } else { + files.push(filelist[i]); + } } } - } - callback(folders, files); - }).catch(e => { - throw e; - }); + callback(folders, files); + }) + .catch((e) => { + throw e; + }); }; for (let i = 0; i < args.length; i++) { args[i] = args[i][0]; } - gl('', function (list) { + gl("", function (list) { if (args.length) { for (let i = 0; i < list.length; i++) { if (!args.includes(list[i][0])) { @@ -8292,12 +8738,11 @@ export class Library extends Uninstantable { gl(str, function (folders, files) { if (files.length > 1) { for (let j = 0; j < files.length; j++) { - if (typeof files[i] == 'string' && files[i].includes('extension.js')) { + if (typeof files[i] == "string" && files[i].includes("extension.js")) { files.splice(j--, 1); - } - else { + } else { if (j % 5 == 0) { - str += '\n\t\t\t'; + str += "\n\t\t\t"; } str += '"' + files[j] + '",'; } @@ -8315,70 +8760,261 @@ export class Library extends Uninstantable { */ cfg() { const mode = lib.config.all.mode.slice(0); - mode.remove('connect'); - mode.remove('brawl'); - const banned = ['shen_guanyu', 'shen_caocao', 'caopi', 're_daqiao', 'caorui', - 'daqiao', 'lingcao', 'liuzan', 'lusu', 'luxun', 'yanwen', 'zhouyu', 'ns_wangyue', 'gw_yenaifa', - 'old_caozhen', 'swd_jiangziya', 'xuhuang', 'maliang', 'guojia', 'simayi', 'swd_kangnalishi', 'hs_siwangzhiyi', 'hs_nozdormu', 'old_zhuzhi']; - const bannedcards = ['zengbin']; - const favs = ["hs_tuoqi", "hs_siwangxianzhi", "hs_xukongzhiying", "hs_hsjiasha", "gjqt_xieyi", "gjqt_yunwuyue", "gjqt_beiluo", - "gjqt_cenying", "shen_lvmeng", "shen_zhaoyun", "shen_zhugeliang", "ow_ana", "chenlin", "ns_guanlu", "hs_guldan", "swd_guyue", - "pal_jiangyunfan", "mtg_jiesi", "swd_lanyin", "pal_liumengli", "swd_muyun", "pal_nangonghuang", "swd_muyue", "pal_murongziying", - "swd_qiner", "pal_shenqishuang", "hs_taisi", "wangji", "pal_xingxuan", "xunyou", "hs_yelise", "pal_yuejinzhao", "pal_yueqi", - "gjqt_yuewuyi", "swd_yuxiaoxue", "ow_zhaliya", "zhangchunhua", "hs_zhihuanhua", "swd_zhiyin", "old_zhonghui", "gjqt_bailitusu", - "hs_barnes", "ow_dva", "swd_hengai", "pal_jushifang", "hs_kazhakusi", "hs_lafamu", "ow_liekong", "hs_lreno", "pal_mingxiu", - "swd_murongshi", "gw_oudimu", "gjqt_ouyangshaogong", "hs_pyros", "qinmi", "gw_sanhanya", "hs_selajin", "swd_shuwaner", - "swd_situqiang", "hs_xialikeer", "pal_xuejian", "swd_yuchiyanhong", "swd_yuwentuo", "swd_zhaoyun", "zhugeliang", "gw_aigeleisi", - "gw_aimin", "gjqt_aruan", "hs_aya", "swd_cheyun", "swd_chenjingchou", "gw_diandian", "swd_huzhongxian", "hs_jinglinglong", - "hs_kaituozhe", "hs_kalimosi", "gw_linjing", "ow_luxiao", "re_luxun", "hs_morgl", "swd_sikongyu", "hs_sthrall", "sunquan", - "sunshangxiang", "gw_yioufeisisp", "gw_yisilinni", "hs_yogg", "hs_ysera", "pal_yuntianhe", "zhugejin", "zhugeke", "gw_zhuoertan", - "hs_anduin", "swd_anka", "ow_banzang", "ow_chanyata", "diaochan", "swd_duguningke", "sp_diaochan", "hetaihou", "ns_huamulan", - "swd_huanglei", "swd_huanyuanzhi", "re_huatuo", "gw_huoge", "pal_jiangcheng", "yj_jushou", "swd_kendi", "yxs_libai", - "mtg_lilianna", "xin_liru", "liuxie", "pal_lixiaoyao", "pal_longkui", "ns_nanhua", "swd_qi", "swd_septem", "gw_shasixiwusi", - "ow_tianshi", "swd_weida", "gjqt_xiayize", "swd_xiyan", "hs_xsylvanas", "hs_yelinlonghou", "ow_yuanshi", "zuoci"]; - const vintage = ['tianjian', 'shuiyun', 'zhuyue', 'zhimeng', 'poyun', 'qianfang', 'xfenxin', 'danqing', 'ywuhun', 'tianwu', 'xuelu', - 'shahun', 'yuling', 'duhun', 'liaoyuan', 'touxi', 'wangchen', 'poyue', 'kunlunjing', 'huanhun', 'yunchou', 'tuzhen', 'cyqiaoxie', - 'mufeng', 'duanyi', 'guozao', 'yaotong', 'pozhen', 'tanlin', 'susheng', 'jikong', 'shouyin', 'jilve', 'hxunzhi', 'huodan', 'shanxian', - 'ziyu', 'kuoyin', 'feiren', 'zihui', 'jidong', 'baoxue', 'aqianghua', 'maoding', 'bfengshi', 'zhongdun', 'pingzhang', 'maichong', - 'guozai', 'jingxiang', 'yuelu', 'liechao', 'fengnu', 'hanshuang', 'enze', 'malymowang', 'xshixin', 'qingzun']; + mode.remove("connect"); + mode.remove("brawl"); + const banned = [ + "shen_guanyu", + "shen_caocao", + "caopi", + "re_daqiao", + "caorui", + "daqiao", + "lingcao", + "liuzan", + "lusu", + "luxun", + "yanwen", + "zhouyu", + "ns_wangyue", + "gw_yenaifa", + "old_caozhen", + "swd_jiangziya", + "xuhuang", + "maliang", + "guojia", + "simayi", + "swd_kangnalishi", + "hs_siwangzhiyi", + "hs_nozdormu", + "old_zhuzhi", + ]; + const bannedcards = ["zengbin"]; + const favs = [ + "hs_tuoqi", + "hs_siwangxianzhi", + "hs_xukongzhiying", + "hs_hsjiasha", + "gjqt_xieyi", + "gjqt_yunwuyue", + "gjqt_beiluo", + "gjqt_cenying", + "shen_lvmeng", + "shen_zhaoyun", + "shen_zhugeliang", + "ow_ana", + "chenlin", + "ns_guanlu", + "hs_guldan", + "swd_guyue", + "pal_jiangyunfan", + "mtg_jiesi", + "swd_lanyin", + "pal_liumengli", + "swd_muyun", + "pal_nangonghuang", + "swd_muyue", + "pal_murongziying", + "swd_qiner", + "pal_shenqishuang", + "hs_taisi", + "wangji", + "pal_xingxuan", + "xunyou", + "hs_yelise", + "pal_yuejinzhao", + "pal_yueqi", + "gjqt_yuewuyi", + "swd_yuxiaoxue", + "ow_zhaliya", + "zhangchunhua", + "hs_zhihuanhua", + "swd_zhiyin", + "old_zhonghui", + "gjqt_bailitusu", + "hs_barnes", + "ow_dva", + "swd_hengai", + "pal_jushifang", + "hs_kazhakusi", + "hs_lafamu", + "ow_liekong", + "hs_lreno", + "pal_mingxiu", + "swd_murongshi", + "gw_oudimu", + "gjqt_ouyangshaogong", + "hs_pyros", + "qinmi", + "gw_sanhanya", + "hs_selajin", + "swd_shuwaner", + "swd_situqiang", + "hs_xialikeer", + "pal_xuejian", + "swd_yuchiyanhong", + "swd_yuwentuo", + "swd_zhaoyun", + "zhugeliang", + "gw_aigeleisi", + "gw_aimin", + "gjqt_aruan", + "hs_aya", + "swd_cheyun", + "swd_chenjingchou", + "gw_diandian", + "swd_huzhongxian", + "hs_jinglinglong", + "hs_kaituozhe", + "hs_kalimosi", + "gw_linjing", + "ow_luxiao", + "re_luxun", + "hs_morgl", + "swd_sikongyu", + "hs_sthrall", + "sunquan", + "sunshangxiang", + "gw_yioufeisisp", + "gw_yisilinni", + "hs_yogg", + "hs_ysera", + "pal_yuntianhe", + "zhugejin", + "zhugeke", + "gw_zhuoertan", + "hs_anduin", + "swd_anka", + "ow_banzang", + "ow_chanyata", + "diaochan", + "swd_duguningke", + "sp_diaochan", + "hetaihou", + "ns_huamulan", + "swd_huanglei", + "swd_huanyuanzhi", + "re_huatuo", + "gw_huoge", + "pal_jiangcheng", + "yj_jushou", + "swd_kendi", + "yxs_libai", + "mtg_lilianna", + "xin_liru", + "liuxie", + "pal_lixiaoyao", + "pal_longkui", + "ns_nanhua", + "swd_qi", + "swd_septem", + "gw_shasixiwusi", + "ow_tianshi", + "swd_weida", + "gjqt_xiayize", + "swd_xiyan", + "hs_xsylvanas", + "hs_yelinlonghou", + "ow_yuanshi", + "zuoci", + ]; + const vintage = [ + "tianjian", + "shuiyun", + "zhuyue", + "zhimeng", + "poyun", + "qianfang", + "xfenxin", + "danqing", + "ywuhun", + "tianwu", + "xuelu", + "shahun", + "yuling", + "duhun", + "liaoyuan", + "touxi", + "wangchen", + "poyue", + "kunlunjing", + "huanhun", + "yunchou", + "tuzhen", + "cyqiaoxie", + "mufeng", + "duanyi", + "guozao", + "yaotong", + "pozhen", + "tanlin", + "susheng", + "jikong", + "shouyin", + "jilve", + "hxunzhi", + "huodan", + "shanxian", + "ziyu", + "kuoyin", + "feiren", + "zihui", + "jidong", + "baoxue", + "aqianghua", + "maoding", + "bfengshi", + "zhongdun", + "pingzhang", + "maichong", + "guozai", + "jingxiang", + "yuelu", + "liechao", + "fengnu", + "hanshuang", + "enze", + "malymowang", + "xshixin", + "qingzun", + ]; const favmodes = ["versus|three", "versus|four", "versus|two", "chess|combat"]; for (let i = 0; i < mode.length; i++) { - game.saveConfig(mode[i] + '_banned', banned); - game.saveConfig(mode[i] + '_bannedcards', bannedcards); + game.saveConfig(mode[i] + "_banned", banned); + game.saveConfig(mode[i] + "_bannedcards", bannedcards); } const characters = lib.config.all.characters.slice(0); - characters.remove('standard'); - characters.remove('old'); - game.saveConfig('vintageSkills', vintage); - game.saveConfig('favouriteCharacter', favs); - game.saveConfig('favouriteMode', favmodes); - game.saveConfig('theme', 'simple'); - game.saveConfig('player_border', 'slim'); - game.saveConfig('cards', lib.config.all.cards); - game.saveConfig('characters', characters); - game.saveConfig('change_skin', false); - game.saveConfig('show_splash', 'off'); - game.saveConfig('show_favourite', false); - game.saveConfig('animation', false); - game.saveConfig('hover_all', false); - game.saveConfig('asset_version', 'v1.9'); + characters.remove("standard"); + characters.remove("old"); + game.saveConfig("vintageSkills", vintage); + game.saveConfig("favouriteCharacter", favs); + game.saveConfig("favouriteMode", favmodes); + game.saveConfig("theme", "simple"); + game.saveConfig("player_border", "slim"); + game.saveConfig("cards", lib.config.all.cards); + game.saveConfig("characters", characters); + game.saveConfig("change_skin", false); + game.saveConfig("show_splash", "off"); + game.saveConfig("show_favourite", false); + game.saveConfig("animation", false); + game.saveConfig("hover_all", false); + game.saveConfig("asset_version", "v1.9"); // game.saveConfig('characters',lib.config.all.characters); // game.saveConfig('cards',lib.config.all.cards); - game.saveConfig('plays', ['cardpile']); - game.saveConfig('skip_shan', false); - game.saveConfig('tao_enemy', true); - game.saveConfig('layout', 'long2'); - game.saveConfig('hp_style', 'ol'); - game.saveConfig('background_music', 'music_off'); - game.saveConfig('background_audio', false); - game.saveConfig('background_speak', false); - game.saveConfig('show_volumn', false); - game.saveConfig('show_replay', true); - game.saveConfig('autostyle', true); - game.saveConfig('debug', true); - game.saveConfig('dev', true); + game.saveConfig("plays", ["cardpile"]); + game.saveConfig("skip_shan", false); + game.saveConfig("tao_enemy", true); + game.saveConfig("layout", "long2"); + game.saveConfig("hp_style", "ol"); + game.saveConfig("background_music", "music_off"); + game.saveConfig("background_audio", false); + game.saveConfig("background_speak", false); + game.saveConfig("show_volumn", false); + game.saveConfig("show_replay", true); + game.saveConfig("autostyle", true); + game.saveConfig("debug", true); + game.saveConfig("dev", true); if (!lib.device) { - game.saveConfig('sync_speed', false); + game.saveConfig("sync_speed", false); } game.reload(); }, @@ -8386,7 +9022,7 @@ export class Library extends Uninstantable { * 移除旁观时的手牌暗置效果 */ o() { - ui.arena.classList.remove('observe'); + ui.arena.classList.remove("observe"); }, /** * 向牌堆顶添加牌(即创建一些卡牌添加到牌堆里) @@ -8409,22 +9045,20 @@ export class Library extends Uninstantable { // if(lib.config.layout!='mobile') lib.init.layout('mobile'); if (args.length == 0) { if (ui.css.card_style) ui.css.card_style.remove(); - if (lib.config.card_style != 'simple') { - lib.config.card_style = 'simple'; - ui.css.card_style = lib.init.css(lib.assetURL + 'theme/style/card', 'simple'); + if (lib.config.card_style != "simple") { + lib.config.card_style = "simple"; + ui.css.card_style = lib.init.css(lib.assetURL + "theme/style/card", "simple"); + } else { + lib.config.card_style = "default"; + ui.css.card_style = lib.init.css(lib.assetURL + "theme/style/card", "default"); } - else { - lib.config.card_style = 'default'; - ui.css.card_style = lib.init.css(lib.assetURL + 'theme/style/card', 'default'); - } - } - else { + } else { for (let i = 0; i < args.length; i++) { lib.cheat.g(args[i]); } } - ui.arena.classList.remove('selecting'); - ui.arena.classList.remove('tempnoe'); + ui.arena.classList.remove("selecting"); + ui.arena.classList.remove("tempnoe"); }, /** * 替换皮肤 @@ -8433,26 +9067,25 @@ export class Library extends Uninstantable { * @param { string } [skin] 皮肤id */ p(name, i, skin) { - const list = ['swd', 'hs', 'pal', 'gjqt', 'ow', 'gw']; + const list = ["swd", "hs", "pal", "gjqt", "ow", "gw"]; if (!lib.character[name]) { for (let j = 0; j < list.length; j++) { - if (lib.character[list[j] + '_' + name]) { - name = list[j] + '_' + name; break; + if (lib.character[list[j] + "_" + name]) { + name = list[j] + "_" + name; + break; } } } let target; - if (typeof i == 'number') { + if (typeof i == "number") { target = game.players[i]; - } - else { + } else { target = game.me.next; } if (!lib.character[name]) { - target.node.avatar.setBackground(name, 'character'); + target.node.avatar.setBackground(name, "character"); target.node.avatar.show(); - } - else { + } else { target.init(name); } if (skin) { @@ -8461,11 +9094,10 @@ export class Library extends Uninstantable { ui.click.skin(target.node.avatar, name); } if (i === true) { - if (lib.config.layout == 'long2') { - lib.init.layout('mobile'); - } - else { - lib.init.layout('long2'); + if (lib.config.layout == "long2") { + lib.init.layout("mobile"); + } else { + lib.init.layout("long2"); } } }, @@ -8490,19 +9122,18 @@ export class Library extends Uninstantable { */ let target; for (let i = 0; i < arguments.length; i++) { - if (get.itemtype(arguments[i]) == 'player') { + if (get.itemtype(arguments[i]) == "player") { target = arguments[i]; - } - else { + } else { cards.push(game.createCard(arguments[i])); } } if (!cards.length) { - cards.push(game.createCard('qilin')); - cards.push(game.createCard('bagua')); - cards.push(game.createCard('dilu')); - cards.push(game.createCard('chitu')); - cards.push(game.createCard('muniu')); + cards.push(game.createCard("qilin")); + cards.push(game.createCard("bagua")); + cards.push(game.createCard("dilu")); + cards.push(game.createCard("chitu")); + cards.push(game.createCard("muniu")); } target = target || game.me; for (let i = 0; i < cards.length; i++) { @@ -8523,94 +9154,205 @@ export class Library extends Uninstantable { game.print(...args); }; (function () { - let a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0; - let sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0; + let a = 0, + b = 0, + c = 0, + d = 0, + e = 0, + f = 0, + g = 0; + let sa = 0, + sb = 0, + sc = 0, + sd = 0, + se = 0, + sf = 0, + sg = 0; for (let i in lib.character) { switch (lib.character[i][1]) { - case 'wei': a++; if (lib.config.banned.includes(i)) sa++; break; - case 'shu': b++; if (lib.config.banned.includes(i)) sb++; break; - case 'wu': c++; if (lib.config.banned.includes(i)) sc++; break; - case 'qun': d++; if (lib.config.banned.includes(i)) sd++; break; - case 'jin': g++; if (lib.config.banned.includes(i)) sg++; break; - case 'western': e++; if (lib.config.banned.includes(i)) se++; break; - case 'key': f++; if (lib.config.banned.includes(i)) sf++; break; + case "wei": + a++; + if (lib.config.banned.includes(i)) sa++; + break; + case "shu": + b++; + if (lib.config.banned.includes(i)) sb++; + break; + case "wu": + c++; + if (lib.config.banned.includes(i)) sc++; + break; + case "qun": + d++; + if (lib.config.banned.includes(i)) sd++; + break; + case "jin": + g++; + if (lib.config.banned.includes(i)) sg++; + break; + case "western": + e++; + if (lib.config.banned.includes(i)) se++; + break; + case "key": + f++; + if (lib.config.banned.includes(i)) sf++; + break; } } - log('魏:' + (a - sa) + '/' + a); - log('蜀:' + (b - sb) + '/' + b); - log('吴:' + (c - sc) + '/' + c); - log('群:' + (d - sd) + '/' + d); - log('晋:' + (g - sg) + '/' + g); - log('西:' + (e - se) + '/' + e); - log('键:' + (f - sf) + '/' + f); - log('已启用:' + ((a + b + c + d + e + f) - (sa + sb + sc + sd + se + sf)) + '/' + (a + b + c + d + e + f)); - }()); + log("魏:" + (a - sa) + "/" + a); + log("蜀:" + (b - sb) + "/" + b); + log("吴:" + (c - sc) + "/" + c); + log("群:" + (d - sd) + "/" + d); + log("晋:" + (g - sg) + "/" + g); + log("西:" + (e - se) + "/" + e); + log("键:" + (f - sf) + "/" + f); + log( + "已启用:" + + (a + b + c + d + e + f - (sa + sb + sc + sd + se + sf)) + + "/" + + (a + b + c + d + e + f) + ); + })(); (function () { - let a = 0, b = 0, c = 0, d = 0; - let aa = 0, bb = 0, cc = 0, dd = 0; - let sa = 0, sb = 0, sc = 0, sd = 0; - let sha = 0, shan = 0, tao = 0, jiu = 0, wuxie = 0, heisha = 0, hongsha = 0; - let num = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0 }; + let a = 0, + b = 0, + c = 0, + d = 0; + let aa = 0, + bb = 0, + cc = 0, + dd = 0; + let sa = 0, + sb = 0, + sc = 0, + sd = 0; + let sha = 0, + shan = 0, + tao = 0, + jiu = 0, + wuxie = 0, + heisha = 0, + hongsha = 0; + let num = { + 1: 0, + 2: 0, + 3: 0, + 4: 0, + 5: 0, + 6: 0, + 7: 0, + 8: 0, + 9: 0, + 10: 0, + 11: 0, + 12: 0, + 13: 0, + }; for (let i in lib.card) { - if (get.objtype(lib.card[i]) == 'object' && lib.translate[i + '_info']) { + if (get.objtype(lib.card[i]) == "object" && lib.translate[i + "_info"]) { switch (lib.card[i].type) { - case 'basic': a++; break; - case 'trick': b++; break; - case 'equip': c++; break; - default: d++; break; + case "basic": + a++; + break; + case "trick": + b++; + break; + case "equip": + c++; + break; + default: + d++; + break; } } } for (let i = 0; i < lib.card.list.length; i++) { - if (typeof lib.card[lib.card.list[i][2]] == 'object') { + if (typeof lib.card[lib.card.list[i][2]] == "object") { switch (lib.card[lib.card.list[i][2]].type) { - case 'basic': aa++; break; - case 'trick': case 'delay': bb++; break; - case 'equip': cc++; break; - default: dd++; break; + case "basic": + aa++; + break; + case "trick": + case "delay": + bb++; + break; + case "equip": + cc++; + break; + default: + dd++; + break; } switch (lib.card.list[i][0]) { - case 'heart': sa++; break; - case 'diamond': sb++; break; - case 'club': sc++; break; - case 'spade': sd++; break; + case "heart": + sa++; + break; + case "diamond": + sb++; + break; + case "club": + sc++; + break; + case "spade": + sd++; + break; } - if (lib.card.list[i][2] == 'sha') { + if (lib.card.list[i][2] == "sha") { sha++; - if (lib.card.list[i][0] == 'club' || lib.card.list[i][0] == 'spade') { + if (lib.card.list[i][0] == "club" || lib.card.list[i][0] == "spade") { heisha++; - } - else { + } else { hongsha++; } } - if (lib.card.list[i][2] == 'shan') { + if (lib.card.list[i][2] == "shan") { shan++; } - if (lib.card.list[i][2] == 'tao') { + if (lib.card.list[i][2] == "tao") { tao++; } - if (lib.card.list[i][2] == 'jiu') { + if (lib.card.list[i][2] == "jiu") { jiu++; } - if (lib.card.list[i][2] == 'wuxie') { + if (lib.card.list[i][2] == "wuxie") { wuxie++; } num[lib.card.list[i][1]]++; } } - let str = '基本牌' + aa + '; ' + '锦囊牌' + bb + '; ' + '装备牌' + cc + '; ' + '其它牌' + dd; + let str = + "基本牌" + aa + "; " + "锦囊牌" + bb + "; " + "装备牌" + cc + "; " + "其它牌" + dd; log(str); - str = '红桃牌' + sa + '; ' + '方片牌' + sb + '; ' + '梅花牌' + sc + '; ' + '黑桃牌' + sd; + str = "红桃牌" + sa + "; " + "方片牌" + sb + "; " + "梅花牌" + sc + "; " + "黑桃牌" + sd; log(str); - str = '杀' + sha + '; ' + '黑杀' + heisha + '; ' + '红杀' + hongsha + '; ' + '闪' + shan + '; ' + '桃' + tao + '; ' + '酒' + jiu + '; ' + '无懈' + wuxie; + str = + "杀" + + sha + + "; " + + "黑杀" + + heisha + + "; " + + "红杀" + + hongsha + + "; " + + "闪" + + shan + + "; " + + "桃" + + tao + + "; " + + "酒" + + jiu + + "; " + + "无懈" + + wuxie; log(str); if (arguments[1]) { for (let i = 1; i <= 13; i++) { if (i < 10) { - log(i + ' ', num[i]); - } - else { + log(i + " ", num[i]); + } else { log(i, num[i]); } } @@ -8619,8 +9361,8 @@ export class Library extends Uninstantable { for (let i = 1; i <= 13; i++) { arr.push(num[i]); } - log((a + b + c + d) + '/' + (aa + bb + cc + dd), ...arr); - }()); + log(a + b + c + d + "/" + (aa + bb + cc + dd), ...arr); + })(); }, /** * 显示场上所有的角色的身份 @@ -8648,12 +9390,11 @@ export class Library extends Uninstantable { */ uy(me) { if (me) { - game.me.useCard({ name: 'spell_yexinglanghun' }, game.me); - } - else { + game.me.useCard({ name: "spell_yexinglanghun" }, game.me); + } else { // player.getEnemy是炉石模式的函数 const enemy = game.me.getEnemy(); - enemy.useCard({ name: 'spell_yexinglanghun' }, enemy); + enemy.useCard({ name: "spell_yexinglanghun" }, enemy); } }, /** @@ -8661,8 +9402,8 @@ export class Library extends Uninstantable { * @param { string } [name] * @param { boolean } [act] */ - gs(name = 'yexinglanghun', act) { - const card = game.createCard('spell_' + name); + gs(name = "yexinglanghun", act) { + const card = game.createCard("spell_" + name); game.me.node.handcards1.appendChild(card); if (!act) { game.me.actused = -99; @@ -8679,8 +9420,8 @@ export class Library extends Uninstantable { * @param { string } [name] * @param { boolean } [act] */ - gc(name = 'falifulong', act) { - var card = game.createCard('stone_' + name + '_stonecharacter'); + gc(name = "falifulong", act) { + var card = game.createCard("stone_" + name + "_stonecharacter"); game.me.node.handcards1.appendChild(card); if (!act) { game.me.actused = -99; @@ -8698,19 +9439,16 @@ export class Library extends Uninstantable { */ a(bool) { if (lib.config.test_game) { - game.saveConfig('test_game'); - } - else { + game.saveConfig("test_game"); + } else { if (bool) { - if (typeof bool === 'string') { - game.saveConfig('test_game', bool); + if (typeof bool === "string") { + game.saveConfig("test_game", bool); + } else { + game.saveConfig("test_game", "_"); } - else { - game.saveConfig('test_game', '_'); - } - } - else { - game.saveConfig('test_game', true); + } else { + game.saveConfig("test_game", true); } } game.reload(); @@ -8721,8 +9459,8 @@ export class Library extends Uninstantable { * 如果要彻底关闭,需要再执行一次lib.cheat.a */ as() { - ui.window.classList.remove('testing'); - const bg = ui.window.querySelector('.pausedbg'); + ui.window.classList.remove("testing"); + const bg = ui.window.querySelector(".pausedbg"); if (bg) { bg.remove(); } @@ -8731,8 +9469,8 @@ export class Library extends Uninstantable { * 装备麒麟弓,并且下家玩家对你发动借刀杀人,杀你的上家 */ uj() { - lib.cheat.e('qilin'); - game.me.next.useCard({ name: 'jiedao' }, [game.me, game.me.previous]); + lib.cheat.e("qilin"); + game.me.next.useCard({ name: "jiedao" }, [game.me, game.me.previous]); }, /** * 下家对你使用一张牌 @@ -8748,24 +9486,20 @@ export class Library extends Uninstantable { * ``` */ u(...args) { - let card = new lib.element.VCard({ name: 'sha' }), + let card = new lib.element.VCard({ name: "sha" }), source = game.me.next, targets = []; for (let i = 0; i < args.length; i++) { - if (get.itemtype(args[i]) == 'player') { + if (get.itemtype(args[i]) == "player") { source = args[i]; - } - else if (Array.isArray(args[i])) { + } else if (Array.isArray(args[i])) { targets = args[i]; - } - else if (args instanceof lib.element.VCard) { + } else if (args instanceof lib.element.VCard) { card = args[i]; - } - else if (typeof args[i] == 'object' && args[i] != null && args[i].name) { - console.warn('lib.cheat.u: 以普通obj形式传入的类卡牌形式已经废弃'); + } else if (typeof args[i] == "object" && args[i] != null && args[i].name) { + console.warn("lib.cheat.u: 以普通obj形式传入的类卡牌形式已经废弃"); card = new lib.element.VCard(args[i]); - } - else if (typeof args[i] == 'string') { + } else if (typeof args[i] == "string") { card = new lib.element.VCard({ name: args[i] }); } } @@ -8780,42 +9514,54 @@ export class Library extends Uninstantable { const log = function (...args) { console.log(...args); game.print(...args); - } - let list = ['s', 'ap', 'a', 'am', 'bp', 'b', 'bm', 'c', 'd']; - let str = ''; + }; + let list = ["s", "ap", "a", "am", "bp", "b", "bm", "c", "d"]; + let str = ""; for (let i = 0; i < list.length; i++) { - if (str) str += ' 、 '; - str += list[i] + '-' + lib.rank[list[i]].length; + if (str) str += " 、 "; + str += list[i] + "-" + lib.rank[list[i]].length; } log(str); for (let i in lib.characterPack) { if (!bool && lib.config.all.sgscharacters.includes(i)) continue; let map = {}; - let str = ''; + let str = ""; for (let j in lib.characterPack[i]) { let rank = get.rank(j); if (!map[rank]) { map[rank] = 1; - } - else { + } else { map[rank]++; } } for (let j = 0; j < list.length; j++) { if (map[list[j]]) { - if (str) str += ' 、 '; - str += list[j] + '-' + map[list[j]]; + if (str) str += " 、 "; + str += list[j] + "-" + map[list[j]]; } } if (str) { - log(lib.translate[i + '_character_config'] + ':' + str); + log(lib.translate[i + "_character_config"] + ":" + str); } } - let list2 = lib.rank.s.concat(lib.rank.ap).concat(lib.rank.a).concat(lib.rank.am). - concat(lib.rank.bp).concat(lib.rank.b).concat(lib.rank.bm).concat(lib.rank.c).concat(lib.rank.d); - Object.keys(lib.character).forEach(key => { - if (!lib.config.forbidai.includes(key) && !key.startsWith('boss_') && !key.startsWith('tafang_') && !list2.includes(key)) log(get.translation(key), key); + let list2 = lib.rank.s + .concat(lib.rank.ap) + .concat(lib.rank.a) + .concat(lib.rank.am) + .concat(lib.rank.bp) + .concat(lib.rank.b) + .concat(lib.rank.bm) + .concat(lib.rank.c) + .concat(lib.rank.d); + Object.keys(lib.character).forEach((key) => { + if ( + !lib.config.forbidai.includes(key) && + !key.startsWith("boss_") && + !key.startsWith("tafang_") && + !list2.includes(key) + ) + log(get.translation(key), key); }); }, /** @@ -8823,7 +9569,7 @@ export class Library extends Uninstantable { * @param { Player } player */ h(player) { - console.log(get.translation(player.getCards('h'))); + console.log(get.translation(player.getCards("h"))); }, /** * 给自己立刻添加手牌 @@ -8836,12 +9582,11 @@ export class Library extends Uninstantable { */ g(...args) { for (let i = 0; i < args.length; i++) { - if (i > 0 && typeof args[i] == 'number') { + if (i > 0 && typeof args[i] == "number") { for (let j = 0; j < args[i] - 1; j++) { lib.cheat.gx(args[i - 1]); } - } - else { + } else { lib.cheat.gx(args[i]); } } @@ -8870,10 +9615,10 @@ export class Library extends Uninstantable { * ``` */ gg(...args) { - game.players.forEach(player => { - args.forEach(cardName => { + game.players.forEach((player) => { + args.forEach((cardName) => { lib.cheat.gx(cardName, player); - }) + }); }); }, /** @@ -8918,7 +9663,7 @@ export class Library extends Uninstantable { gn(name) { let nature = null; let suit = null; - let suits = ['club', 'spade', 'diamond', 'heart']; + let suits = ["club", "spade", "diamond", "heart"]; for (let i = 0; i < suits.length; i++) { if (name.startsWith(suits[i])) { suit = suits[i]; @@ -8926,22 +9671,21 @@ export class Library extends Uninstantable { break; } } - if (name.startsWith('red')) { + if (name.startsWith("red")) { name = name.slice(3); - suit = ['diamond', 'heart'].randomGet(); + suit = ["diamond", "heart"].randomGet(); } - if (name.startsWith('black')) { + if (name.startsWith("black")) { name = name.slice(5); - suit = ['spade', 'club'].randomGet(); + suit = ["spade", "club"].randomGet(); } - if (name == 'huosha') { - name = 'sha'; - nature = 'fire'; - } - else if (name == 'leisha') { - name = 'sha'; - nature = 'thunder'; + if (name == "huosha") { + name = "sha"; + nature = "fire"; + } else if (name == "leisha") { + name = "sha"; + nature = "thunder"; } if (!lib.card[name]) { return null; @@ -8954,39 +9698,38 @@ export class Library extends Uninstantable { */ ge(target) { if (target) { - lib.cheat.gx('zhuge', target); - lib.cheat.gx('qinglong', target); - lib.cheat.gx('bagua', target); - lib.cheat.gx('dilu', target); - lib.cheat.gx('chitu', target); - lib.cheat.gx('muniu', target); - } - else { - lib.cheat.g('zhuge'); - lib.cheat.g('qinglong'); - lib.cheat.g('bagua'); - lib.cheat.g('dilu'); - lib.cheat.g('chitu'); - lib.cheat.g('muniu'); + lib.cheat.gx("zhuge", target); + lib.cheat.gx("qinglong", target); + lib.cheat.gx("bagua", target); + lib.cheat.gx("dilu", target); + lib.cheat.gx("chitu", target); + lib.cheat.gx("muniu", target); + } else { + lib.cheat.g("zhuge"); + lib.cheat.g("qinglong"); + lib.cheat.g("bagua"); + lib.cheat.g("dilu"); + lib.cheat.g("chitu"); + lib.cheat.g("muniu"); } }, /** * 自己立即获得闪电,火山,洪水,乐不思蜀,鬼幽结 */ gj() { - lib.cheat.g('shandian'); - lib.cheat.g('huoshan'); - lib.cheat.g('hongshui'); - lib.cheat.g('lebu'); - lib.cheat.g('bingliang'); - lib.cheat.g('guiyoujie'); + lib.cheat.g("shandian"); + lib.cheat.g("huoshan"); + lib.cheat.g("hongshui"); + lib.cheat.g("lebu"); + lib.cheat.g("bingliang"); + lib.cheat.g("guiyoujie"); }, /** * 自己立即获得所有食物牌各一张 */ gf() { for (let i in lib.card) { - if (lib.card[i].type == 'food') { + if (lib.card[i].type == "food") { lib.cheat.g(i); } } @@ -9040,7 +9783,7 @@ export class Library extends Uninstantable { return; } const player = game.players[num]; - const cards = player.getCards('hej'); + const cards = player.getCards("hej"); for (let i = 0; i < cards.length; i++) { cards[i].discard(); } @@ -9051,9 +9794,11 @@ export class Library extends Uninstantable { * 自己以外的其他玩家弃置所有牌 */ to() { - game.players.filter(player => player != game.me).forEach((_, i) => { - lib.cheat.t(i); - }); + game.players + .filter((player) => player != game.me) + .forEach((_, i) => { + lib.cheat.t(i); + }); }, /** * 弃置自己所有牌 @@ -9068,7 +9813,7 @@ export class Library extends Uninstantable { k(i = 1) { game.players[i].hp = 1; lib.cheat.t(i); - lib.cheat.g('juedou'); + lib.cheat.g("juedou"); }, /** * 重新设置当前的主公的武将牌,且血量上限+1(不论当局人数是否大于3) @@ -9076,19 +9821,45 @@ export class Library extends Uninstantable { */ z(name) { switch (name) { - case 'cc': name = 're_caocao'; break; - case 'lb': name = 're_liubei'; break; - case 'sq': name = 'sunquan'; break; - case 'dz': name = 'dongzhuo'; break; - case 'ys': name = 're_yuanshao'; break; - case 'zj': name = 'sp_zhangjiao'; break; - case 'ls': name = 'liushan'; break; - case 'sc': name = 'sunce'; break; - case 'cp': name = 'caopi'; break; - case 'cr': name = 'caorui'; break; - case 'sx': name = 'sunxiu'; break; - case 'lc': name = 'liuchen'; break; - case 'sh': name = 'sunhao'; break; + case "cc": + name = "re_caocao"; + break; + case "lb": + name = "re_liubei"; + break; + case "sq": + name = "sunquan"; + break; + case "dz": + name = "dongzhuo"; + break; + case "ys": + name = "re_yuanshao"; + break; + case "zj": + name = "sp_zhangjiao"; + break; + case "ls": + name = "liushan"; + break; + case "sc": + name = "sunce"; + break; + case "cp": + name = "caopi"; + break; + case "cr": + name = "caorui"; + break; + case "sx": + name = "sunxiu"; + break; + case "lc": + name = "liuchen"; + break; + case "sh": + name = "sunhao"; + break; } game.zhu.init(name); game.zhu.maxHp++; @@ -9096,40 +9867,40 @@ export class Library extends Uninstantable { game.zhu.update(); }, }; - static translate = { - flower: '鲜花', - egg: '鸡蛋', - wine: '酒杯', - shoe: '拖鞋', - yuxisx: '玉玺', - jiasuo: '枷锁', - junk: '平凡', - common: '普通', - rare: '精品', - epic: '史诗', - legend: '传说', + translate = { + flower: "鲜花", + egg: "鸡蛋", + wine: "酒杯", + shoe: "拖鞋", + yuxisx: "玉玺", + jiasuo: "枷锁", + junk: "平凡", + common: "普通", + rare: "精品", + epic: "史诗", + legend: "传说", default: "默认", - special: '特殊', - zhenfa: '阵法', + special: "特殊", + zhenfa: "阵法", aozhan: "鏖战", - mode_derivation_card_config: '衍生', - mode_banned_card_config: '禁卡', - mode_favourite_character_config: '收藏', - mode_banned_character_config: '禁将', + mode_derivation_card_config: "衍生", + mode_banned_card_config: "禁卡", + mode_favourite_character_config: "收藏", + mode_banned_character_config: "禁将", heart: "♥︎", diamond: "♦︎", spade: "♠︎", club: "♣︎", - none: '◈', - ghujia: '护甲', - ghujia_bg: '甲', + none: "◈", + ghujia: "护甲", + ghujia_bg: "甲", heart2: "红桃", diamond2: "方片", spade2: "黑桃", club2: "梅花", - none2: '无色', - red: '红色', - black: '黑色', + none2: "无色", + red: "红色", + black: "黑色", ok: "确定", ok2: "确定", cancel: "取消", @@ -9138,44 +9909,44 @@ export class Library extends Uninstantable { setting: "设置", start: "开始", random: "随机", - _out: '无效', - agree: '同意', - refuse: '拒绝', + _out: "无效", + agree: "同意", + refuse: "拒绝", fire: "火", thunder: "雷", poison: "毒", - kami: '神', - ice: '冰', - stab: '刺', - wei: '魏', - shu: '蜀', - wu: '吴', - qun: '群', - shen: '神', - western: '西', - key: '键', - jin: '晋', - double: '双', - wei2: '魏国', - shu2: '蜀国', - wu2: '吴国', - qun2: '群雄', - shen2: '神明', - western2: '西方', - key2: 'KEY', - jin2: '晋朝', - double2: '双势力', - male: '男', - female: '女', - mad: '混乱', - mad_bg: '疯', - draw_card: '摸牌', - discard_card: '弃牌', - take_damage: '受伤害', - reset_character: '复原武将牌', - recover_hp: '回复体力', - lose_hp: '失去体力', - get_damage: '受伤害', + kami: "神", + ice: "冰", + stab: "刺", + wei: "魏", + shu: "蜀", + wu: "吴", + qun: "群", + shen: "神", + western: "西", + key: "键", + jin: "晋", + double: "双", + wei2: "魏国", + shu2: "蜀国", + wu2: "吴国", + qun2: "群雄", + shen2: "神明", + western2: "西方", + key2: "KEY", + jin2: "晋朝", + double2: "双势力", + male: "男", + female: "女", + mad: "混乱", + mad_bg: "疯", + draw_card: "摸牌", + discard_card: "弃牌", + take_damage: "受伤害", + reset_character: "复原武将牌", + recover_hp: "回复体力", + lose_hp: "失去体力", + get_damage: "受伤害", weiColor: "#b0d0e2", shuColor: "#ffddb9", wuColor: "#b2d9a9", @@ -9184,68 +9955,68 @@ export class Library extends Uninstantable { westernColor: "#ffe14c", jinColor: "#ffe14c", keyColor: "#c9b1fd", - basic: '基本', - equip: '装备', - trick: '锦囊', - delay: '延时锦囊', - special_delay: '技能机制', - character: '角色', - revive: '复活', - equip1: '武器', - equip2: '防具', - equip3: '防御马', - 'equip3_4': '坐骑', - equip4: '攻击马', - equip5: '宝物', - equip6: '特殊装备', - zero: '零', - one: '一', - two: '二', - three: '三', - four: '四', - five: '五', - six: '六', - seven: '七', - eight: '八', - nine: '九', - ten: '十', - _recasting: '重铸', - _lianhuan: '连环', - _lianhuan2: '连环', - _kamisha: '神杀', - _icesha: '冰杀', - qianxing: '潜行', - mianyi: '免疫', - fengyin: '封印', - baiban: '白板', + basic: "基本", + equip: "装备", + trick: "锦囊", + delay: "延时锦囊", + special_delay: "技能机制", + character: "角色", + revive: "复活", + equip1: "武器", + equip2: "防具", + equip3: "防御马", + equip3_4: "坐骑", + equip4: "攻击马", + equip5: "宝物", + equip6: "特殊装备", + zero: "零", + one: "一", + two: "二", + three: "三", + four: "四", + five: "五", + six: "六", + seven: "七", + eight: "八", + nine: "九", + ten: "十", + _recasting: "重铸", + _lianhuan: "连环", + _lianhuan2: "连环", + _kamisha: "神杀", + _icesha: "冰杀", + qianxing: "潜行", + mianyi: "免疫", + fengyin: "封印", + baiban: "白板", _disableJudge: "判定区", - xiaowu_emotion: '小无表情', - guojia_emotion: '郭嘉表情', - zhenji_emotion: '甄姬表情', - shibing_emotion: '士兵表情', - xiaosha_emotion: '小杀表情', - xiaotao_emotion: '小桃表情', - xiaojiu_emotion: '小酒表情', - xiaokuo_emotion: '小扩表情', + xiaowu_emotion: "小无表情", + guojia_emotion: "郭嘉表情", + zhenji_emotion: "甄姬表情", + shibing_emotion: "士兵表情", + xiaosha_emotion: "小杀表情", + xiaotao_emotion: "小桃表情", + xiaojiu_emotion: "小酒表情", + xiaokuo_emotion: "小扩表情", - pause: '暂停', - config: '选项', - auto: '托管', + pause: "暂停", + config: "选项", + auto: "托管", - unknown: '未知', - unknown0: '一号位', - unknown1: '二号位', - unknown2: '三号位', - unknown3: '四号位', - unknown4: '五号位', - unknown5: '六号位', - unknown6: '七号位', - unknown7: '八号位', - unknown8: '九号位', - unknown9: '十号位', - unknown10: '十一号位', - unknown11: '十二号位', + unknown: "未知", + unknown0: "一号位", + unknown1: "二号位", + unknown2: "三号位", + unknown3: "四号位", + unknown4: "五号位", + unknown5: "六号位", + unknown6: "七号位", + unknown7: "八号位", + unknown8: "九号位", + unknown9: "十号位", + unknown10: "十一号位", + unknown11: "十二号位", feichu_equip1: "已废除", feichu_equip1_info: "武器栏已废除", @@ -9257,25 +10028,25 @@ export class Library extends Uninstantable { feichu_equip4_info: "攻击坐骑栏已废除", feichu_equip5: "已废除", feichu_equip5_info: "宝物栏已废除", - feichu_equip6: '已废除', - feichu_equip6_info: '特殊装备栏已废除', + feichu_equip6: "已废除", + feichu_equip6_info: "特殊装备栏已废除", feichu_equip1_bg: "废", feichu_equip2_bg: "废", feichu_equip3_bg: "废", feichu_equip4_bg: "废", feichu_equip5_bg: "废", - feichu_equip6_bg: '废', - disable_judge: '已废除', - disable_judge_info: '判定区已废除', - disable_judge_bg: '废', - pss: '手势', - pss_paper: '布', - pss_scissor: '剪刀', - pss_stone: '石头', - pss_paper_info: '石头剪刀布时的一种手势。克制石头,但被剪刀克制。', - pss_scissor_info: '石头剪刀布时的一种手势。克制布,但被石头克制。', - pss_stone_info: '石头剪刀布时的一种手势。克制剪刀,但被布克制。', - renku: '仁库', + feichu_equip6_bg: "废", + disable_judge: "已废除", + disable_judge_info: "判定区已废除", + disable_judge_bg: "废", + pss: "手势", + pss_paper: "布", + pss_scissor: "剪刀", + pss_stone: "石头", + pss_paper_info: "石头剪刀布时的一种手势。克制石头,但被剪刀克制。", + pss_scissor_info: "石头剪刀布时的一种手势。克制布,但被石头克制。", + pss_stone_info: "石头剪刀布时的一种手势。克制剪刀,但被布克制。", + renku: "仁库", group_wei: "魏势力", group_shu: "蜀势力", group_wu: "吴势力", @@ -9288,43 +10059,43 @@ export class Library extends Uninstantable { group_qun_bg: "群", group_key_bg: "键", group_jin_bg: "晋", - zhengsu: '整肃', - zhengsu_leijin: '擂进', - zhengsu_bianzhen: '变阵', - zhengsu_mingzhi: '鸣止', - zhengsu_leijin_info: '回合内所有于出牌阶段使用的牌点数递增且不少于三张。', - zhengsu_bianzhen_info: '回合内所有于出牌阶段使用的牌花色相同且不少于两张。', - zhengsu_mingzhi_info: '回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。', - db_atk: '策略', - db_atk1: '全军出击', - db_atk2: '分兵围城', - db_def: '策略', - db_def1: '奇袭粮道', - db_def2: '开城诱敌', - cooperation_damage: '同仇', - cooperation_damage_info: '双方累计造成至少4点伤害', - cooperation_draw: '并进', - cooperation_draw_info: '双方累计摸至少八张牌', - cooperation_discard: '疏财', - cooperation_discard_info: '双方累计弃置至少4种花色的牌', - cooperation_use: '戮力', - cooperation_use_info: '双方累计使用至少4种花色的牌', - charge: '蓄力值', - expandedSlots: '扩展装备栏', - stratagem_fury: '怒气', - _stratagem_add_buff: '强化', + zhengsu: "整肃", + zhengsu_leijin: "擂进", + zhengsu_bianzhen: "变阵", + zhengsu_mingzhi: "鸣止", + zhengsu_leijin_info: "回合内所有于出牌阶段使用的牌点数递增且不少于三张。", + zhengsu_bianzhen_info: "回合内所有于出牌阶段使用的牌花色相同且不少于两张。", + zhengsu_mingzhi_info: "回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。", + db_atk: "策略", + db_atk1: "全军出击", + db_atk2: "分兵围城", + db_def: "策略", + db_def1: "奇袭粮道", + db_def2: "开城诱敌", + cooperation_damage: "同仇", + cooperation_damage_info: "双方累计造成至少4点伤害", + cooperation_draw: "并进", + cooperation_draw_info: "双方累计摸至少八张牌", + cooperation_discard: "疏财", + cooperation_discard_info: "双方累计弃置至少4种花色的牌", + cooperation_use: "戮力", + cooperation_use_info: "双方累计使用至少4种花色的牌", + charge: "蓄力值", + expandedSlots: "扩展装备栏", + stratagem_fury: "怒气", + _stratagem_add_buff: "强化", - phaseZhunbei: '准备阶段', - phaseJudge: '判定阶段', - phaseDraw: '摸牌阶段', - phaseUse: '出牌阶段', - phaseDiscard: '弃牌阶段', - phaseJieshu: '结束阶段', + phaseZhunbei: "准备阶段", + phaseJudge: "判定阶段", + phaseDraw: "摸牌阶段", + phaseUse: "出牌阶段", + phaseDiscard: "弃牌阶段", + phaseJieshu: "结束阶段", }; - static experimental = Experimental + experimental = Experimental; - static element = { + element = { content: Element.Content, contents: Element.Contents, Player: Element.Player, @@ -9345,24 +10116,22 @@ export class Library extends Uninstantable { } }, onmessage: function (messageevent) { - if (messageevent.data == 'heartbeat') { - this.send('heartbeat'); + if (messageevent.data == "heartbeat") { + this.send("heartbeat"); return; } var message; try { message = JSON.parse(messageevent.data); - if (!Array.isArray(message) || - typeof lib.message.client[message[0]] !== 'function') { - throw ('err'); + if (!Array.isArray(message) || typeof lib.message.client[message[0]] !== "function") { + throw "err"; } for (var i = 1; i < message.length; i++) { message[i] = get.parsedResult(message[i]); } - } - catch (e) { + } catch (e) { console.log(e); - console.log('invalid message: ' + messageevent.data); + console.log("invalid message: " + messageevent.data); return; } lib.message.client[message.shift()].apply(null, message); @@ -9372,9 +10141,8 @@ export class Library extends Uninstantable { if (_status.connectCallback) { _status.connectCallback(false); delete _status.connectCallback; - } - else { - alert('连接失败'); + } else { + alert("连接失败"); } }, onclose: function () { @@ -9386,18 +10154,16 @@ export class Library extends Uninstantable { if (game.online || game.onlineroom) { if ((game.servermode || game.onlinehall) && _status.over) { void 0; - } - else { - localStorage.setItem(lib.configprefix + 'directstart', true); + } else { + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); } - } - else { + } else { // game.saveConfig('reconnect_info'); } game.online = false; game.ws = null; - } + }, }, /** * @legacy Use {@link lib.element.Player.prototype} instead. @@ -9446,35 +10212,38 @@ export class Library extends Uninstantable { */ get nodews() { return this.NodeWS.prototype; - } + }, }; - static card = { + card = { + /** + * @type { [CardBaseUIData['suit'], CardBaseUIData['number'], string][] } + */ list: [], cooperation_damage: { fullskin: true, }, cooperation_draw: { fullskin: true, - cardimage: 'cooperation_damage', + cardimage: "cooperation_damage", }, cooperation_discard: { fullskin: true, - cardimage: 'cooperation_damage', + cardimage: "cooperation_damage", }, cooperation_use: { fullskin: true, - cardimage: 'cooperation_damage', + cardimage: "cooperation_damage", }, pss_paper: { - type: 'pss', + type: "pss", fullskin: true, }, pss_scissor: { - type: 'pss', + type: "pss", fullskin: true, }, pss_stone: { - type: 'pss', + type: "pss", fullskin: true, }, feichu_equip1: { @@ -9537,23 +10306,23 @@ export class Library extends Uninstantable { group_jin: { fullskin: true }, db_atk1: { - type: 'db_atk', + type: "db_atk", fullimage: true, }, db_atk2: { - type: 'db_atk', + type: "db_atk", fullimage: true, }, db_def1: { - type: 'db_def', + type: "db_def", fullimage: true, }, db_def2: { - type: 'db_def', + type: "db_def", fullimage: true, }, }; - static filter = { + filter = { all: () => true, none: () => false, /** @@ -9564,7 +10333,7 @@ export class Library extends Uninstantable { * @param { Player } player * @returns { boolean } */ - ignoredHandcard: (card, player) => game.checkMod(card, player, false, 'ignoredHandcard', player), + ignoredHandcard: (card, player) => game.checkMod(card, player, false, "ignoredHandcard", player), /** * Check if the card is giftable * @@ -9575,9 +10344,15 @@ export class Library extends Uninstantable { * @param { boolean } [strict] */ cardGiftable: (card, player, target, strict) => { - const mod = game.checkMod(card, player, target, 'unchanged', 'cardGiftable', player); - if (!mod || strict && (mod == 'unchanged' && (get.position(card) != 'h' || !get.cardtag(card, 'gifts')) || player == target)) return false; - return get.type(card, false) != 'equip' || target.canEquip(card, true); + const mod = game.checkMod(card, player, target, "unchanged", "cardGiftable", player); + if ( + !mod || + (strict && + ((mod == "unchanged" && (get.position(card) != "h" || !get.cardtag(card, "gifts"))) || + player == target)) + ) + return false; + return get.type(card, false) != "equip" || target.canEquip(card, true); }, /** * Check if the card is recastable @@ -9590,15 +10365,19 @@ export class Library extends Uninstantable { */ cardRecastable: (card, player = get.owner(card), source, strict) => { if (!player) { - if (player === null) console.trace(`cardRecastable的player参数不应传入null,可以用void 0或undefined占位`); + if (player === null) + console.trace(`cardRecastable的player参数不应传入null,可以用void 0或undefined占位`); player = get.owner(card); } - const mod = game.checkMod(card, player, source, 'unchanged', 'cardRecastable', player); + const mod = game.checkMod(card, player, source, "unchanged", "cardRecastable", player); if (!mod) return false; - if (strict && mod == 'unchanged') { - if (get.position(card) != 'h') return false; - const info = get.info(card), recastable = info.recastable || info.chongzhu; - return Boolean(typeof recastable == 'function' ? recastable(_status.event, player) : recastable); + if (strict && mod == "unchanged") { + if (get.position(card) != "h") return false; + const info = get.info(card), + recastable = info.recastable || info.chongzhu; + return Boolean( + typeof recastable == "function" ? recastable(_status.event, player) : recastable + ); } return true; }, @@ -9609,8 +10388,8 @@ export class Library extends Uninstantable { * @returns { boolean } */ canBeReplaced: function (card, player) { - var mod = game.checkMod(card, player, 'unchanged', 'canBeReplaced', player); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, "unchanged", "canBeReplaced", player); + if (mod != "unchanged") return mod; return true; }, //装备栏 END @@ -9621,14 +10400,14 @@ export class Library extends Uninstantable { return true; }, cardSavable: function (card, player, target) { - if (get.itemtype(card) == 'card') { - var mod2 = game.checkMod(card, player, 'unchanged', 'cardEnabled2', player); - if (mod2 != 'unchanged') return mod2; + if (get.itemtype(card) == "card") { + var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; } - var mod = game.checkMod(card, player, target, 'unchanged', 'cardSavable', player); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, target, "unchanged", "cardSavable", player); + if (mod != "unchanged") return mod; var savable = get.info(card).savable; - if (typeof savable == 'function') savable = savable(card, player, target); + if (typeof savable == "function") savable = savable(card, player, target); return savable; }, /** @@ -9640,35 +10419,50 @@ export class Library extends Uninstantable { * @returns {boolean} */ filterTrigger: function (event, player, triggername, skill, indexedData) { - if (player._hookTrigger && player._hookTrigger.some(i => { - const info = lib.skill[i].hookTrigger; - return info && info.block && info.block(event, player, triggername, skill); - })) return false; + if ( + player._hookTrigger && + player._hookTrigger.some((i) => { + const info = lib.skill[i].hookTrigger; + return info && info.block && info.block(event, player, triggername, skill); + }) + ) + return false; const info = get.info(skill); if (!info) { - console.error(new ReferenceError('缺少info的技能:', skill)); + console.error(new ReferenceError("缺少info的技能:", skill)); return false; } - if (!game.expandSkills(player.getSkills('invisible').concat(lib.skill.global)).includes(skill)) return false; - if (!game.expandSkills(player.getSkills(false).concat(lib.skill.global)).includes(skill)) {//hiddenSkills - if (get.mode() != 'guozhan') return false; + if (!game.expandSkills(player.getSkills("invisible").concat(lib.skill.global)).includes(skill)) + return false; + if (!game.expandSkills(player.getSkills(false).concat(lib.skill.global)).includes(skill)) { + //hiddenSkills + if (get.mode() != "guozhan") return false; if (info.noHidden) return false; } if (!info.forceDie && player.isDead()) return false; if (!info.forceOut && (player.isOut() || player.removed)) return false; if (!info.trigger) return false; - if (!Object.keys(info.trigger).some(role => { - if (role != 'global' && player != event[role]) return false; - if (Array.isArray(info.trigger[role])) return info.trigger[role].includes(triggername); - return info.trigger[role] == triggername; - })) return false; + if ( + !Object.keys(info.trigger).some((role) => { + if (role != "global" && player != event[role]) return false; + if (Array.isArray(info.trigger[role])) return info.trigger[role].includes(triggername); + return info.trigger[role] == triggername; + }) + ) + return false; if (info.filter && !info.filter(event, player, triggername, indexedData)) return false; if (event._notrigger.includes(player) && !lib.skill.global.includes(skill)) return false; - if (typeof info.usable == 'number' && player.hasSkill('counttrigger') && - player.storage.counttrigger && player.storage.counttrigger[skill] >= info.usable) return false; - if (info.round && (info.round - (game.roundNumber - player.storage[skill + '_roundcount']) > 0)) return false; + if ( + typeof info.usable == "number" && + player.hasSkill("counttrigger") && + player.storage.counttrigger && + player.storage.counttrigger[skill] >= info.usable + ) + return false; + if (info.round && info.round - (game.roundNumber - player.storage[skill + "_roundcount"]) > 0) + return false; for (const item in player.storage) { - if (item.startsWith('temp_ban_')) { + if (item.startsWith("temp_ban_")) { if (player.storage[item] !== true) continue; const skillName = item.slice(9); if (lib.skill[skillName]) { @@ -9689,33 +10483,39 @@ export class Library extends Uninstantable { filterEnable: function (event, player, skill) { const info = get.info(skill); if (!info) { - console.error(new ReferenceError('缺少info的技能:', skill)); + console.error(new ReferenceError("缺少info的技能:", skill)); return false; } // if (!game.expandSkills(player.getSkills('invisible').concat(lib.skill.global)).includes(skill)) return false; - if (!game.expandSkills(player.getSkills(false).concat(lib.skill.global)).includes(skill)) {//hiddenSkills - if (player.hasSkillTag('nomingzhi', false, null, true)) return false; - if (get.mode() !== 'guozhan') return false; + if (!game.expandSkills(player.getSkills(false).concat(lib.skill.global)).includes(skill)) { + //hiddenSkills + if (player.hasSkillTag("nomingzhi", false, null, true)) return false; + if (get.mode() !== "guozhan") return false; if (info.noHidden) return false; } - const checkEnable = enable => { - if (typeof enable === 'function') return enable(event); - if (Array.isArray(enable)) return enable.some(i => checkEnable(i)); - if (enable === 'phaseUse') return event.type === 'phase'; - if (typeof enable === 'string') return enable === event.name; + const checkEnable = (enable) => { + if (typeof enable === "function") return enable(event); + if (Array.isArray(enable)) return enable.some((i) => checkEnable(i)); + if (enable === "phaseUse") return event.type === "phase"; + if (typeof enable === "string") return enable === event.name; return false; - } + }; if (!checkEnable(info.enable)) return false; if (info.filter && !info.filter(event, player)) return false; - if (info.viewAs && typeof info.viewAs !== 'function') { + if (info.viewAs && typeof info.viewAs !== "function") { if (info.viewAsFilter && info.viewAsFilter(player) === false) return false; - if (event.filterCard && !event.filterCard(get.autoViewAs(info.viewAs, 'unsure'), player, event)) return false; + if ( + event.filterCard && + !event.filterCard(get.autoViewAs(info.viewAs, "unsure"), player, event) + ) + return false; } if (info.usable && get.skillCount(skill) >= info.usable) return false; if (info.chooseButton && _status.event.noButton) return false; - if (info.round && (info.round - (game.roundNumber - player.storage[skill + '_roundcount']) > 0)) return false; + if (info.round && info.round - (game.roundNumber - player.storage[skill + "_roundcount"]) > 0) + return false; for (const item in player.storage) { - if (!item.startsWith('temp_ban_')) continue; + if (!item.startsWith("temp_ban_")) continue; if (player.storage[item] !== true) continue; const skillName = item.slice(9); if (!lib.skill[skillName]) continue; @@ -9725,20 +10525,26 @@ export class Library extends Uninstantable { return true; }, characterDisabled: function (i, libCharacter) { - if (!lib.character[i] || lib.character[i][4] && lib.character[i][4].includes('forbidai')) return true; - if (lib.character[i][4] && lib.character[i][4].includes('unseen')) return true; + if (!lib.character[i] || (lib.character[i][4] && lib.character[i][4].includes("forbidai"))) + return true; + if (lib.character[i][4] && lib.character[i][4].includes("unseen")) return true; if (lib.config.forbidai.includes(i)) return true; if (lib.characterFilter[i] && !lib.characterFilter[i](get.mode())) return true; if (_status.connectMode) { if (lib.configOL.banned.includes(i) || lib.connectBanned.includes(i)) return true; var double_character = false; - if (lib.configOL.mode == 'guozhan') { + if (lib.configOL.mode == "guozhan") { double_character = true; - } - else if (lib.configOL.double_character && (lib.configOL.mode == 'identity' || lib.configOL.mode == 'stone')) { + } else if ( + lib.configOL.double_character && + (lib.configOL.mode == "identity" || lib.configOL.mode == "stone") + ) { double_character = true; - } - else if (lib.configOL.double_character_jiange && (lib.configOL.mode == 'versus' && _status.mode == 'jiange')) { + } else if ( + lib.configOL.double_character_jiange && + lib.configOL.mode == "versus" && + _status.mode == "jiange" + ) { double_character = true; } if (double_character && lib.config.forbiddouble.includes(i)) { @@ -9754,17 +10560,21 @@ export class Library extends Uninstantable { // if(lib.configOL.ban_strong&&get.rank(i,true)>=8){ // return true; // } - } - else { + } else { if (lib.config.banned.includes(i)) return true; var double_character = false; - if (get.mode() == 'guozhan') { + if (get.mode() == "guozhan") { double_character = true; - } - else if (get.config('double_character') && (lib.config.mode == 'identity' || lib.config.mode == 'stone')) { + } else if ( + get.config("double_character") && + (lib.config.mode == "identity" || lib.config.mode == "stone") + ) { double_character = true; - } - else if (get.config('double_character_jiange') && (lib.config.mode == 'versus' && _status.mode == 'jiange')) { + } else if ( + get.config("double_character_jiange") && + lib.config.mode == "versus" && + _status.mode == "jiange" + ) { double_character = true; } if (double_character && lib.config.forbiddouble.includes(i)) { @@ -9786,17 +10596,18 @@ export class Library extends Uninstantable { var info = lib.character[i]; if (!info) return true; if (info[4]) { - if (info[4].includes('boss')) return true; - if (info[4].includes('hiddenboss')) return true; - if (info[4].includes('minskin')) return true; - if (info[4].includes('unseen')) return true; - if (info[4].includes('forbidai') && (!_status.event.isMine || !_status.event.isMine())) return true; + if (info[4].includes("boss")) return true; + if (info[4].includes("hiddenboss")) return true; + if (info[4].includes("minskin")) return true; + if (info[4].includes("unseen")) return true; + if (info[4].includes("forbidai") && (!_status.event.isMine || !_status.event.isMine())) + return true; if (lib.characterFilter[i] && !lib.characterFilter[i](get.mode())) return true; } return false; }, skillDisabled: function (skill) { - if (!lib.translate[skill] || !lib.translate[skill + '_info']) return true; + if (!lib.translate[skill] || !lib.translate[skill + "_info"]) return true; var info = lib.skill[skill]; if (info && !info.unique && !info.temp && !info.sub && !info.fixed && !info.vanish) { return false; @@ -9806,127 +10617,128 @@ export class Library extends Uninstantable { cardEnabled: function (card, player, event) { if (player == undefined) player = _status.event.player; if (!player) return false; - if (get.itemtype(card) == 'card') { - var mod2 = game.checkMod(card, player, event, 'unchanged', 'cardEnabled2', player); - if (mod2 != 'unchanged') return mod2; + if (get.itemtype(card) == "card") { + var mod2 = game.checkMod(card, player, event, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; } card = get.autoViewAs(card); - if (event === 'forceEnable') { - var mod = game.checkMod(card, player, event, 'unchanged', 'cardEnabled', player); - if (mod != 'unchanged') return mod; + if (event === "forceEnable") { + var mod = game.checkMod(card, player, event, "unchanged", "cardEnabled", player); + if (mod != "unchanged") return mod; return true; - } - else { + } else { var filter = get.info(card).enable; if (!filter) return; - var mod = game.checkMod(card, player, event, 'unchanged', 'cardEnabled', player); - if (mod != 'unchanged') return mod; - if (typeof filter == 'boolean') return filter; - if (typeof filter == 'function') return filter(card, player, event); + var mod = game.checkMod(card, player, event, "unchanged", "cardEnabled", player); + if (mod != "unchanged") return mod; + if (typeof filter == "boolean") return filter; + if (typeof filter == "function") return filter(card, player, event); } }, cardRespondable: function (card, player, event) { event = event || _status.event; - if (event.name != 'chooseToRespond') return true; + if (event.name != "chooseToRespond") return true; var source = event.getParent().player; if (source && source != player) { - if (source.hasSkillTag('norespond', false, [card, player, event], true)) { + if (source.hasSkillTag("norespond", false, [card, player, event], true)) { return false; } } if (player == undefined) player = _status.event.player; - if (get.itemtype(card) == 'card') { - var mod2 = game.checkMod(card, player, event, 'unchanged', 'cardEnabled2', player); - if (mod2 != 'unchanged') return mod2; + if (get.itemtype(card) == "card") { + var mod2 = game.checkMod(card, player, event, "unchanged", "cardEnabled2", player); + if (mod2 != "unchanged") return mod2; } - var mod = game.checkMod(card, player, 'unchanged', 'cardRespondable', player); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); + if (mod != "unchanged") return mod; return true; }, cardUsable2: function (card, player, event) { card = get.autoViewAs(card); var info = get.info(card); - if (info.updateUsable == 'phaseUse') { + if (info.updateUsable == "phaseUse") { event = event || _status.event; - if (event.type == 'chooseToUse_button') event = event.getParent(); + if (event.type == "chooseToUse_button") event = event.getParent(); if (player != _status.event.player) return true; - if (event.getParent().name != 'phaseUse') return true; + if (event.getParent().name != "phaseUse") return true; if (event.getParent().player != player) return true; } var num = info.usable; - if (typeof num == 'function') num = num(card, player); - num = game.checkMod(card, player, num, 'cardUsable', player); - if (typeof num != 'number') return true; - else return (player.countUsed(card) < num); + if (typeof num == "function") num = num(card, player); + num = game.checkMod(card, player, num, "cardUsable", player); + if (typeof num != "number") return true; + else return player.countUsed(card) < num; }, cardUsable: function (card, player, event) { card = get.autoViewAs(card); var info = get.info(card); event = event || _status.event; - if (event.type == 'chooseToUse_button') event = event.getParent(); + if (event.type == "chooseToUse_button") event = event.getParent(); if (player != _status.event.player) return true; - if (info.updateUsable == 'phaseUse') { - if (event.getParent().name != 'phaseUse') return true; + if (info.updateUsable == "phaseUse") { + if (event.getParent().name != "phaseUse") return true; if (event.getParent().player != player) return true; } event.addCount_extra = true; var num = info.usable; - if (typeof num == 'function') num = num(card, player); - num = game.checkMod(card, player, num, 'cardUsable', player); - if (typeof num != 'number') { - return (typeof num == 'boolean') ? num : true; + if (typeof num == "function") num = num(card, player); + num = game.checkMod(card, player, num, "cardUsable", player); + if (typeof num != "number") { + return typeof num == "boolean" ? num : true; } if (player.countUsed(card) < num) return true; - if (game.hasPlayer(function (current) { - return game.checkMod(card, player, current, false, 'cardUsableTarget', player); - })) { + if ( + game.hasPlayer(function (current) { + return game.checkMod(card, player, current, false, "cardUsableTarget", player); + }) + ) { return true; } return false; }, cardDiscardable: function (card, player, event) { event = event || _status.event; - if (typeof event != 'string') event = event.getParent().name; - var mod = game.checkMod(card, player, event, 'unchanged', 'cardDiscardable', player); - if (mod != 'unchanged') return mod; + if (typeof event != "string") event = event.getParent().name; + var mod = game.checkMod(card, player, event, "unchanged", "cardDiscardable", player); + if (mod != "unchanged") return mod; return true; }, canBeDiscarded: function (card, player, target, event) { event = event || _status.event; - if (typeof event != 'string') event = event.getParent().name; - var mod = game.checkMod(card, player, target, event, 'unchanged', 'canBeDiscarded', target); - if (mod != 'unchanged') return mod; + if (typeof event != "string") event = event.getParent().name; + var mod = game.checkMod(card, player, target, event, "unchanged", "canBeDiscarded", target); + if (mod != "unchanged") return mod; return true; }, canBeGained: function (card, player, target, event) { event = event || _status.event; - if (typeof event != 'string') event = event.getParent().name; - var mod = game.checkMod(card, player, target, event, 'unchanged', 'canBeGained', target); - if (mod != 'unchanged') return mod; + if (typeof event != "string") event = event.getParent().name; + var mod = game.checkMod(card, player, target, event, "unchanged", "canBeGained", target); + if (mod != "unchanged") return mod; return true; }, cardAiIncluded: function (card) { if (_status.event.isMine()) return true; - return (_status.event._aiexclude.includes(card) == false); + return _status.event._aiexclude.includes(card) == false; }, filterCard: function (card, player, event) { var info = get.info(card); //if(info.toself&&!lib.filter.targetEnabled(card,player,player)) return false; if (player == undefined) player = _status.event.player; - if (!lib.filter.cardEnabled(card, player, event) || !lib.filter.cardUsable(card, player, event)) return false; + if (!lib.filter.cardEnabled(card, player, event) || !lib.filter.cardUsable(card, player, event)) + return false; if (info.notarget) return true; var range; var select = get.copy(info.selectTarget); if (select == undefined) { if (info.filterTarget == undefined) return true; range = [1, 1]; - } - else if (typeof select == 'number') range = [select, select]; - else if (get.itemtype(select) == 'select') range = select; - else if (typeof select == 'function') range = select(card, player); - game.checkMod(card, player, range, 'selectTarget', player); + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); if (!range || range[1] != -1) return true; - var filterTarget = (event && event.filterTarget) ? event.filterTarget : lib.filter.filterTarget; + var filterTarget = event && event.filterTarget ? event.filterTarget : lib.filter.filterTarget; return game.hasPlayer(function (current) { return filterTarget(card, player, current); }); @@ -9934,15 +10746,32 @@ export class Library extends Uninstantable { targetEnabledx: function (card, player, target) { if (!card) return false; if (!target || !target.isIn()) return false; - let event = _status.event, evt = event.getParent('chooseToUse'); - if(get.itemtype(evt) !== 'event') evt = event; - if (event._backup && event._backup.filterCard == lib.filter.filterCard && - (!lib.filter.cardEnabled(card, player, event) || !lib.filter.cardUsable(card, player, evt))) return false; + let event = _status.event, + evt = event.getParent("chooseToUse"); + if (get.itemtype(evt) !== "event") evt = event; + if ( + event._backup && + event._backup.filterCard == lib.filter.filterCard && + (!lib.filter.cardEnabled(card, player, event) || !lib.filter.cardUsable(card, player, evt)) + ) + return false; if (event.addCount_extra) { - if (!lib.filter.cardUsable2(card, player) && !game.checkMod(card, player, target, false, 'cardUsableTarget', player)) return false; + if ( + !lib.filter.cardUsable2(card, player) && + !game.checkMod(card, player, target, false, "cardUsableTarget", player) + ) + return false; } var info = get.info(card); - if (info.singleCard && info.filterAddedTarget && ui.selected.targets.length) return Boolean(info.filterAddedTarget(card, player, target, ui.selected.targets[ui.selected.targets.length - 1])); + if (info.singleCard && info.filterAddedTarget && ui.selected.targets.length) + return Boolean( + info.filterAddedTarget( + card, + player, + target, + ui.selected.targets[ui.selected.targets.length - 1] + ) + ); return lib.filter.targetEnabled.apply(this, arguments); }, targetEnabled: function (card, player, target) { @@ -9951,25 +10780,27 @@ export class Library extends Uninstantable { var info = get.info(card); var filter = info.filterTarget; if (!info.singleCard || ui.selected.targets.length == 0) { - var mod = game.checkMod(card, player, target, 'unchanged', 'playerEnabled', player); - if (mod != 'unchanged') return mod; - var mod = game.checkMod(card, player, target, 'unchanged', 'targetEnabled', target); - if (mod != 'unchanged') return mod; + var mod = game.checkMod(card, player, target, "unchanged", "playerEnabled", player); + if (mod != "unchanged") return mod; + var mod = game.checkMod(card, player, target, "unchanged", "targetEnabled", target); + if (mod != "unchanged") return mod; } - if (typeof filter == 'boolean') return filter; - if (typeof filter == 'function') return Boolean(filter(card, player, target)); + if (typeof filter == "boolean") return filter; + if (typeof filter == "function") return Boolean(filter(card, player, target)); }, targetEnabled2: function (card, player, target) { if (!card) return false; if (!target || !target.isIn()) return false; if (lib.filter.targetEnabled(card, player, target)) return true; - if (game.checkMod(card, player, target, 'unchanged', 'playerEnabled', player) == false) return false; - if (game.checkMod(card, player, target, 'unchanged', 'targetEnabled', target) == false) return false; + if (game.checkMod(card, player, target, "unchanged", "playerEnabled", player) == false) + return false; + if (game.checkMod(card, player, target, "unchanged", "targetEnabled", target) == false) + return false; var filter = get.info(card).modTarget; - if (typeof filter == 'boolean') return filter; - if (typeof filter == 'function') return Boolean(filter(card, player, target)); + if (typeof filter == "boolean") return filter; + if (typeof filter == "function") return Boolean(filter(card, player, target)); return false; }, targetEnabled3: function (card, player, target) { @@ -9978,10 +10809,11 @@ export class Library extends Uninstantable { var info = get.info(card); if (info.filterTarget == true) return true; - if (typeof info.filterTarget == 'function' && info.filterTarget(card, player, target)) return true; + if (typeof info.filterTarget == "function" && info.filterTarget(card, player, target)) + return true; if (info.modTarget == true) return true; - if (typeof info.modTarget == 'function' && info.modTarget(card, player, target)) return true; + if (typeof info.modTarget == "function" && info.modTarget(card, player, target)) return true; return false; }, targetInRange: function (card, player, target) { @@ -9990,35 +10822,33 @@ export class Library extends Uninstantable { var outrange = info.outrange; if (range == undefined && outrange == undefined) return true; - var mod = game.checkMod(card, player, target, 'unchanged', 'targetInRange', player); + var mod = game.checkMod(card, player, target, "unchanged", "targetInRange", player); var extra = 0; - if (mod != 'unchanged') { - if (typeof mod == 'boolean') return mod; - if (typeof mod == 'number') extra = mod; + if (mod != "unchanged") { + if (typeof mod == "boolean") return mod; + if (typeof mod == "number") extra = mod; } - if (typeof info.range == 'function') return info.range(card, player, target); + if (typeof info.range == "function") return info.range(card, player, target); - if (player.hasSkill('undist') || target.hasSkill('undist')) return false; + if (player.hasSkill("undist") || target.hasSkill("undist")) return false; for (var i in range) { - if (i == 'attack') { + if (i == "attack") { var range2 = player.getAttackRange(); if (range2 <= 0) return false; var distance = get.distance(player, target) + extra; if (range[i] <= distance - range2) return false; - } - else { + } else { var distance = get.distance(player, target, i) + extra; if (range[i] < distance) return false; } } for (var i in outrange) { - if (i == 'attack') { + if (i == "attack") { var range2 = player.getAttackRange(); if (range2 <= 0) return false; var distance = get.distance(player, target) + extra; if (outrange[i] > distance - range2 + 1) return false; - } - else { + } else { var distance = get.distance(player, target, i) + extra; if (outrange[i] > distance) return false; } @@ -10026,12 +10856,16 @@ export class Library extends Uninstantable { return true; }, filterTarget: function (card, player, target) { - return (lib.filter.targetEnabledx(card, player, target) && - lib.filter.targetInRange(card, player, target)); + return ( + lib.filter.targetEnabledx(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); }, filterTarget2: function (card, player, target) { - return (lib.filter.targetEnabled2(card, player, target) && - lib.filter.targetInRange(card, player, target)); + return ( + lib.filter.targetEnabled2(card, player, target) && + lib.filter.targetInRange(card, player, target) + ); }, notMe: function (card, player, target) { return player != target; @@ -10040,7 +10874,7 @@ export class Library extends Uninstantable { return player == target; }, attackFrom: function (card, player, target) { - return get.distance(player, target, 'attack') <= 1; + return get.distance(player, target, "attack") <= 1; }, globalFrom: function (card, player, target) { return get.distance(player, target) <= 1; @@ -10052,16 +10886,16 @@ export class Library extends Uninstantable { if (!card) card = get.card(); if (!player) player = get.player(); if (card == undefined) return; - var range, info = get.info(card); + var range, + info = get.info(card); var select = get.copy(info.selectTarget); if (select == undefined) { if (info.filterTarget == undefined) return [0, 0]; range = [1, 1]; - } - else if (typeof select == 'number') range = [select, select]; - else if (get.itemtype(select) == 'select') range = select; - else if (typeof select == 'function') range = select(card, player); - game.checkMod(card, player, range, 'selectTarget', player); + } else if (typeof select == "number") range = [select, select]; + else if (get.itemtype(select) == "select") range = select; + else if (typeof select == "function") range = select(card, player); + game.checkMod(card, player, range, "selectTarget", player); if (info.singleCard && info.filterAddedTarget) return [range[0] * 2, range[1] * 2]; return range; }, @@ -10075,47 +10909,51 @@ export class Library extends Uninstantable { return !this.player.hasShan(); }, wuxieSwap: function (event) { - if (event.type == 'wuxie') { - if (ui.wuxie && ui.wuxie.classList.contains('glow')) { + if (event.type == "wuxie") { + if (ui.wuxie && ui.wuxie.classList.contains("glow")) { return true; } - if (ui.tempnowuxie && ui.tempnowuxie.classList.contains('glow') && event.state > 0) { + if (ui.tempnowuxie && ui.tempnowuxie.classList.contains("glow") && event.state > 0) { var triggerevent = event.getTrigger(); if (triggerevent) { if (ui.tempnowuxie._origin == triggerevent.parent.id) { return true; } - } - else if (ui.tempnowuxie._origin == _status.event.id2) { + } else if (ui.tempnowuxie._origin == _status.event.id2) { return true; } } if (lib.config.wuxie_self) { var tw = event.info_map; - if (tw.player && tw.player.isUnderControl(true) && !tw.player.hasSkillTag('noautowuxie') && - (!tw.targets || tw.targets.length <= 1) && !tw.noai) { + if ( + tw.player && + tw.player.isUnderControl(true) && + !tw.player.hasSkillTag("noautowuxie") && + (!tw.targets || tw.targets.length <= 1) && + !tw.noai + ) { return true; } } } - } + }, }; - static sort = { + sort = { nature: function (a, b) { return (lib.nature.get(b) || 0) - (lib.nature.get(a) || 0); }, group: function (a, b) { const groupSort = function (group) { let base = 0; - if (group == 'wei') return base; - if (group == 'shu') return base + 1; - if (group == 'wu') return base + 2; - if (group == 'qun') return base + 3; - if (group == 'jin') return base + 4; - if (group == 'key') return base + 5; - if (group == 'western') return base + 6; - if (group == 'shen') return base + 7; - if (group == 'double') return base + 7; + if (group == "wei") return base; + if (group == "shu") return base + 1; + if (group == "wu") return base + 2; + if (group == "qun") return base + 3; + if (group == "jin") return base + 4; + if (group == "key") return base + 5; + if (group == "western") return base + 6; + if (group == "shen") return base + 7; + if (group == "double") return base + 7; return base + 9; }; return groupSort(a) - groupSort(b); @@ -10127,36 +10965,39 @@ export class Library extends Uninstantable { let base = 0; if (get.is.double(name, true)) base = 9; const group = info[1]; - if (group == 'shen') return base - 1; - if (group == 'wei') return base; - if (group == 'shu') return base + 1; - if (group == 'wu') return base + 2; - if (group == 'qun') return base + 3; - if (group == 'jin') return base + 4; - if (group == 'key') return base + 5; - if (group == 'western') return base + 6; + if (group == "shen") return base - 1; + if (group == "wei") return base; + if (group == "shu") return base + 1; + if (group == "wu") return base + 2; + if (group == "qun") return base + 3; + if (group == "jin") return base + 4; + if (group == "key") return base + 5; + if (group == "western") return base + 6; return base + 7; }; const del = groupSort(a) - groupSort(b); if (del != 0) return del; - var aa = a, bb = b; - var firstUnderscoreIndexA = a.indexOf('_'); - var firstUnderscoreIndexB = b.indexOf('_'); - var secondUnderscoreIndexA = firstUnderscoreIndexA != -1 ? a.indexOf('_', firstUnderscoreIndexA + 1) : -1; - var secondUnderscoreIndexB = firstUnderscoreIndexB != -1 ? b.indexOf('_', firstUnderscoreIndexB + 1) : -1; - + var aa = a, + bb = b; + var firstUnderscoreIndexA = a.indexOf("_"); + var firstUnderscoreIndexB = b.indexOf("_"); + var secondUnderscoreIndexA = + firstUnderscoreIndexA != -1 ? a.indexOf("_", firstUnderscoreIndexA + 1) : -1; + var secondUnderscoreIndexB = + firstUnderscoreIndexB != -1 ? b.indexOf("_", firstUnderscoreIndexB + 1) : -1; + if (secondUnderscoreIndexA != -1) { a = a.slice(secondUnderscoreIndexA + 1); } else if (firstUnderscoreIndexA != -1) { a = a.slice(firstUnderscoreIndexA + 1); } - + if (secondUnderscoreIndexB != -1) { b = b.slice(secondUnderscoreIndexB + 1); } else if (firstUnderscoreIndexB != -1) { b = b.slice(firstUnderscoreIndexB + 1); } - + if (a != b) { return a > b ? 1 : -1; } @@ -10166,10 +11007,10 @@ export class Library extends Uninstantable { var typeSort = function (name) { var type = get.type(name); if (!type) return 10; - if (type == 'basic') return -1; - if (type == 'trick') return 0; - if (type == 'delay') return 1; - if (type == 'equip') { + if (type == "basic") return -1; + if (type == "trick") return 0; + if (type == "delay") return 1; + if (type == "equip") { var type2 = get.subtype(name, false); if (type2 && type2.slice) return 1 + parseInt(type2.slice(5) || 7); return 8.5; @@ -10178,35 +11019,38 @@ export class Library extends Uninstantable { }; var del = typeSort(a) - typeSort(b); if (del != 0) return del; - var aa = a, bb = b; - var firstUnderscoreIndexA = a.indexOf('_'); - var firstUnderscoreIndexB = b.indexOf('_'); - var secondUnderscoreIndexA = firstUnderscoreIndexA != -1 ? a.indexOf('_', firstUnderscoreIndexA + 1) : -1; - var secondUnderscoreIndexB = firstUnderscoreIndexB != -1 ? b.indexOf('_', firstUnderscoreIndexB + 1) : -1; - + var aa = a, + bb = b; + var firstUnderscoreIndexA = a.indexOf("_"); + var firstUnderscoreIndexB = b.indexOf("_"); + var secondUnderscoreIndexA = + firstUnderscoreIndexA != -1 ? a.indexOf("_", firstUnderscoreIndexA + 1) : -1; + var secondUnderscoreIndexB = + firstUnderscoreIndexB != -1 ? b.indexOf("_", firstUnderscoreIndexB + 1) : -1; + if (secondUnderscoreIndexA != -1) { a = a.slice(secondUnderscoreIndexA + 1); } else if (firstUnderscoreIndexA != -1) { a = a.slice(firstUnderscoreIndexA + 1); } - + if (secondUnderscoreIndexB != -1) { b = b.slice(secondUnderscoreIndexB + 1); } else if (firstUnderscoreIndexB != -1) { b = b.slice(firstUnderscoreIndexB + 1); } - + if (a != b) { return a > b ? 1 : -1; } return aa > bb ? 1 : -1; }, random: function () { - return (Math.random() - 0.5); + return Math.random() - 0.5; }, seat: function (a, b) { var player = lib.tempSortSeat || _status.event.player || game.me || game.players[0]; - var delta = get.distance(player, a, 'absolute') - get.distance(player, b, 'absolute'); + var delta = get.distance(player, a, "absolute") - get.distance(player, b, "absolute"); if (delta) return delta; delta = parseInt(a.dataset.position) - parseInt(b.dataset.position); if (player.side == game.me.side) return delta; @@ -10216,7 +11060,8 @@ export class Library extends Uninstantable { return parseInt(a.dataset.position) - parseInt(b.dataset.position); }, priority: function (a, b) { - var i1 = get.info(a[0]), i2 = get.info(b[0]); + var i1 = get.info(a[0]), + i2 = get.info(b[0]); if (i1.priority == undefined) i1.priority = 0; if (i2.priority == undefined) i2.priority = 0; if (i1.priority == i2.priority) { @@ -10234,24 +11079,27 @@ export class Library extends Uninstantable { return get.number(b) - get.number(a); }, capt: function (a, b) { - var aa = a, bb = b; - var firstUnderscoreIndexAA = aa.indexOf('_'); - var firstUnderscoreIndexBB = bb.indexOf('_'); - var secondUnderscoreIndexAA = firstUnderscoreIndexAA != -1 ? aa.indexOf('_', firstUnderscoreIndexAA + 1) : -1; - var secondUnderscoreIndexBB = firstUnderscoreIndexBB != -1 ? bb.indexOf('_', firstUnderscoreIndexBB + 1) : -1; - + var aa = a, + bb = b; + var firstUnderscoreIndexAA = aa.indexOf("_"); + var firstUnderscoreIndexBB = bb.indexOf("_"); + var secondUnderscoreIndexAA = + firstUnderscoreIndexAA != -1 ? aa.indexOf("_", firstUnderscoreIndexAA + 1) : -1; + var secondUnderscoreIndexBB = + firstUnderscoreIndexBB != -1 ? bb.indexOf("_", firstUnderscoreIndexBB + 1) : -1; + if (secondUnderscoreIndexAA != -1) { aa = aa.slice(secondUnderscoreIndexAA + 1); } else if (firstUnderscoreIndexAA != -1) { aa = aa.slice(firstUnderscoreIndexAA + 1); } - + if (secondUnderscoreIndexBB != -1) { bb = bb.slice(secondUnderscoreIndexBB + 1); } else if (firstUnderscoreIndexBB != -1) { bb = bb.slice(firstUnderscoreIndexBB + 1); } - + if (aa != bb) { return aa > bb ? 1 : -1; } @@ -10261,7 +11109,7 @@ export class Library extends Uninstantable { if (a > b) return 1; if (a < b) return -1; return 0; - } + }, }; /** * @type {{ @@ -10276,160 +11124,244 @@ export class Library extends Uninstantable { * [key: string]: Skill; * }} */ - static skill = { + skill = { stratagem_fury: { - marktext: '🔥', + marktext: "🔥", intro: { - name: '怒气', + name: "怒气", content: (storage, player) => { - const stratagemFuryMax = _status.stratagemFuryMax, fury = storage || 0; - return `当前怒气值:${typeof stratagemFuryMax == 'number' ? `${fury}/${stratagemFuryMax}` : fury}`; - } - } + const stratagemFuryMax = _status.stratagemFuryMax, + fury = storage || 0; + return `当前怒气值:${ + typeof stratagemFuryMax == "number" ? `${fury}/${stratagemFuryMax}` : fury + }`; + }, + }, }, _stratagem_add_buff: { log: false, - enable: 'chooseToUse', + enable: "chooseToUse", filter: (event, player) => { const fury = player.storage.stratagem_fury; if (!fury) return false; const stratagemSettings = event.stratagemSettings; - if (!stratagemSettings || !stratagemSettings.roundOneUseFury && game.roundNumber < 2) return false; - const cards = player.getCards('hs'); + if (!stratagemSettings || (!stratagemSettings.roundOneUseFury && game.roundNumber < 2)) + return false; + const cards = player.getCards("hs"); if (!cards.length) return false; - const cost = lib.stratagemBuff.cost, names = Array.from(cost.keys()); + const cost = lib.stratagemBuff.cost, + names = Array.from(cost.keys()); if (!names.length) return false; - return cards.some(card => game.checkMod(card, player, 'unchanged', 'cardEnabled2', player) && names.some(availableName => availableName == get.name(card, player) && event.filterCard(new lib.element.VCard({ - name: availableName, - nature: get.nature(card, player), - isCard: true, - cards: [card] - }), player, event) && fury >= cost.get(availableName))); + return cards.some( + (card) => + game.checkMod(card, player, "unchanged", "cardEnabled2", player) && + names.some( + (availableName) => + availableName == get.name(card, player) && + event.filterCard( + new lib.element.VCard({ + name: availableName, + nature: get.nature(card, player), + isCard: true, + cards: [card], + }), + player, + event + ) && + fury >= cost.get(availableName) + ) + ); }, - onChooseToUse: event => { - const player = _status.event.player, fury = player.storage.stratagem_fury; + onChooseToUse: (event) => { + const player = _status.event.player, + fury = player.storage.stratagem_fury; if (!fury) return; - if (!event.stratagemSettings && !game.online) event.set('stratagemSettings', { - roundOneUseFury: _status.connectMode ? lib.configOL.round_one_use_fury : get.config('round_one_use_fury') - }); - const cost = lib.stratagemBuff.cost.get('shan'); - if (typeof cost != 'number' || !event.shanRequired) return; - event.addNumber('shanIgnored', Math.min(player.countCards(lib.skill._stratagem_add_buff.position, { - name: 'shan' - }), Math.floor(fury / cost))); + if (!event.stratagemSettings && !game.online) + event.set("stratagemSettings", { + roundOneUseFury: _status.connectMode + ? lib.configOL.round_one_use_fury + : get.config("round_one_use_fury"), + }); + const cost = lib.stratagemBuff.cost.get("shan"); + if (typeof cost != "number" || !event.shanRequired) return; + event.addNumber( + "shanIgnored", + Math.min( + player.countCards(lib.skill._stratagem_add_buff.position, { + name: "shan", + }), + Math.floor(fury / cost) + ) + ); }, - check: card => { + check: (card) => { const player = _status.event.player; - if (_status.event.type == 'phase') { + if (_status.event.type == "phase") { const cardName = get.name(card, player); - if (cardName == 'sha') { - if (game.hasPlayer(current => { - if (!player.canUse(card, current)) return false; - const storage = player.storage, zhibi = storage.zhibi; - return (zhibi && !zhibi.includes(current) || get.effect(current, card, player, player) >= 2 - Math.max(0, (storage.stratagem_fury || 0) - 1)) && current.mayHaveShan(player, 'use', current.getCards('h', i => { - return i.hasGaintag('sha_notshan'); - })) && player.hasSkill('jiu'); - })) return 1; + if (cardName == "sha") { + if ( + game.hasPlayer((current) => { + if (!player.canUse(card, current)) return false; + const storage = player.storage, + zhibi = storage.zhibi; + return ( + ((zhibi && !zhibi.includes(current)) || + get.effect(current, card, player, player) >= + 2 - Math.max(0, (storage.stratagem_fury || 0) - 1)) && + current.mayHaveShan( + player, + "use", + current.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) && + player.hasSkill("jiu") + ); + }) + ) + return 1; return 0; } - if (cardName == 'tao') { + if (cardName == "tao") { if (player.hp <= 2 && player.getDamagedHp() >= 2) return 1; return 0; } return 1; } - if (_status.event.type == 'dying') return get.attitude(player, _status.event.dying) > 3 ? 1 : 0; - return (_status.event.getParent().shanRequired || 1) > 1 && get.damageEffect(player, _status.event.getParent().player || player, player) < 0 ? 1 : 0; + if (_status.event.type == "dying") + return get.attitude(player, _status.event.dying) > 3 ? 1 : 0; + return (_status.event.getParent().shanRequired || 1) > 1 && + get.damageEffect(player, _status.event.getParent().player || player, player) < 0 + ? 1 + : 0; }, - position: 'hs', + position: "hs", filterCard: (card, player, event) => { if (!event) event = _status.event; const filterCard = event._backup.filterCard; const cost = lib.stratagemBuff.cost; - return Array.from(cost.keys()).some(availableName => availableName == get.name(card, player) && filterCard(new lib.element.VCard({ - name: availableName, - nature: get.nature(card, player), - isCard: true, - cards: [card] - }), player, _status.event) && player.storage.stratagem_fury >= cost.get(availableName)); + return Array.from(cost.keys()).some( + (availableName) => + availableName == get.name(card, player) && + filterCard( + new lib.element.VCard({ + name: availableName, + nature: get.nature(card, player), + isCard: true, + cards: [card], + }), + player, + _status.event + ) && + player.storage.stratagem_fury >= cost.get(availableName) + ); }, viewAs: (cards, player) => { - if(cards.length){ + if (cards.length) { const cardName = get.name(cards[0], player); - return cardName ? new lib.element.VCard({ - name: cardName, - nature: get.nature(cards[0], player), - suit: get.suit(cards[0], player), - number: get.number(cards[0], player), - isCard: true, - cards: [cards[0]], - storage: { - stratagem_buffed: 1 - } - }) : new lib.element.VCard(); + return cardName + ? new lib.element.VCard({ + name: cardName, + nature: get.nature(cards[0], player), + suit: get.suit(cards[0], player), + number: get.number(cards[0], player), + isCard: true, + cards: [cards[0]], + storage: { + stratagem_buffed: 1, + }, + }) + : new lib.element.VCard(); } return null; }, prompt: () => { - const span = document.createElement('span'); - span.classList.add('text'); - span.style.fontFamily = 'yuanli'; - const stratagemBuff = lib.stratagemBuff, cost = stratagemBuff.cost; + const span = document.createElement("span"); + span.classList.add("text"); + span.style.fontFamily = "yuanli"; + const stratagemBuff = lib.stratagemBuff, + cost = stratagemBuff.cost; stratagemBuff.prompt.forEach((prompt, cardName) => { - const li = document.createElement('li'); - li.innerHTML = `【${get.translation(cardName)}】:${cost.get(cardName)}点怒气。${prompt()}`; + const li = document.createElement("li"); + li.innerHTML = `【${get.translation(cardName)}】:${cost.get( + cardName + )}点怒气。${prompt()}`; span.appendChild(li); }); - return `当你需要使用位于“强化表”内的非虚拟卡牌时,你可以消耗对应数量的怒气将其强化并使用。${document.createElement('hr').outerHTML}${span.outerHTML}`; + return `当你需要使用位于“强化表”内的非虚拟卡牌时,你可以消耗对应数量的怒气将其强化并使用。${ + document.createElement("hr").outerHTML + }${span.outerHTML}`; }, onuse: (result, player) => { player.logSkill(result.skill); - const stratagemBuff = lib.stratagemBuff, cardName = result.card.name; + const stratagemBuff = lib.stratagemBuff, + cardName = result.card.name; player.changeFury(-stratagemBuff.cost.get(cardName), true); - const gameEvent = get.event(), effect = stratagemBuff.effect.get(cardName); - if (typeof effect == 'function') gameEvent.pushHandler('onNextUseCard', effect); - gameEvent.pushHandler('onNextUseCard', (event, option) => { - if (event.step == 0 && option.state == 'end') game.broadcastAll(cards => cards.forEach(card => card.clone.classList.add('stratagem-fury-glow')), event.cards); + const gameEvent = get.event(), + effect = stratagemBuff.effect.get(cardName); + if (typeof effect == "function") gameEvent.pushHandler("onNextUseCard", effect); + gameEvent.pushHandler("onNextUseCard", (event, option) => { + if (event.step == 0 && option.state == "end") + game.broadcastAll( + (cards) => + cards.forEach((card) => card.clone.classList.add("stratagem-fury-glow")), + event.cards + ); }); }, ai: { order: (item, player) => { if (!player) player = _status.event.player; - if (_status.event.type == 'phase') for (const card of player.getCards('hs')) { - if (!game.checkMod(card, player, 'unchanged', 'cardEnabled2', player)) continue; - const cardName = get.name(card, player); - if (cardName == 'sha') { - if (game.hasPlayer(current => { - if (!player.canUse(card, current)) return false; - const storage = player.storage, zhibi = storage.zhibi; - return (zhibi && !zhibi.includes(current) || (get.effect(current, card, player, player) >= 2 - Math.max(0, (storage.stratagem_fury || 0) - 1))) && current.mayHaveShan(player, 'use', current.getCards('h', i => { - return i.hasGaintag('sha_notshan'); - })); - })) return get.order(card, player) + 0.5; + if (_status.event.type == "phase") + for (const card of player.getCards("hs")) { + if (!game.checkMod(card, player, "unchanged", "cardEnabled2", player)) continue; + const cardName = get.name(card, player); + if (cardName == "sha") { + if ( + game.hasPlayer((current) => { + if (!player.canUse(card, current)) return false; + const storage = player.storage, + zhibi = storage.zhibi; + return ( + ((zhibi && !zhibi.includes(current)) || + get.effect(current, card, player, player) >= + 2 - Math.max(0, (storage.stratagem_fury || 0) - 1)) && + current.mayHaveShan( + player, + "use", + current.getCards("h", (i) => { + return i.hasGaintag("sha_notshan"); + }) + ) + ); + }) + ) + return get.order(card, player) + 0.5; + } else if (cardName == "tao" && player.hp <= 2 && player.getDamagedHp() >= 2) + return get.order(card, player) + 0.5; + return 8; } - else if (cardName == 'tao' && player.hp <= 2 && player.getDamagedHp() >= 2) return get.order(card, player) + 0.5; - return 8; - } return 3.5; }, directHit_ai: true, skillTagFilter: (player, tag, arg) => { const card = get.autoViewAs(arg.card); - if (card.name != 'sha' || !card.storage.stratagem_buffed) return false; + if (card.name != "sha" || !card.storage.stratagem_buffed) return false; const target = arg.target; - if (target.countCards('h', 'shan') >= 1 && !target.storage.stratagem_fury) return false; - } - } + if (target.countCards("h", "shan") >= 1 && !target.storage.stratagem_fury) return false; + }, + }, }, expandedSlots: { - markimage: 'image/card/expandedSlots.png', + markimage: "image/card/expandedSlots.png", intro: { markcount: function (storage, player) { - var all = 0, storage = player.expandedSlots; + var all = 0, + storage = player.expandedSlots; if (!storage) return 0; for (var key in storage) { var num = storage[key]; - if (typeof num == 'number' && num > 0) { + if (typeof num == "number" && num > 0) { all += num; } } @@ -10437,38 +11369,39 @@ export class Library extends Uninstantable { }, content: function (storage, player) { storage = player.expandedSlots; - if (!storage) return '当前没有扩展装备栏'; - const keys = Object.keys(storage).sort(), combined = get.is.mountCombined(); - let str = ''; + if (!storage) return "当前没有扩展装备栏"; + 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) { + if (typeof num == "number" && num > 0) { let trans = get.translation(key); - if (combined && key == 'equip3') trans = '坐骑'; - str += '
                                    • ' + trans + '栏:' + num + '个
                                      '; + if (combined && key == "equip3") trans = "坐骑"; + str += "
                                    • " + trans + "栏:" + num + "个
                                      "; } } if (str.length) return str.slice(0, str.length - 4); - return '当前没有扩展装备栏'; + return "当前没有扩展装备栏"; }, }, }, charge: { - markimage: 'image/card/charge.png', + markimage: "image/card/charge.png", intro: { - content: '当前蓄力点数:#', + content: "当前蓄力点数:#", }, }, cooperation: { charlotte: true, trigger: { - global: ['phaseAfter', 'dieAfter'], + global: ["phaseAfter", "dieAfter"], }, forced: true, lastDo: true, filter: function (event, player) { - if (event.name == 'die' && event.player.isAlive()) return false; - var storage = player.getStorage('cooperation'); + if (event.name == "die" && event.player.isAlive()) return false; + var storage = player.getStorage("cooperation"); for (var info of storage) { if (info.target == event.player) return true; } @@ -10487,57 +11420,65 @@ export class Library extends Uninstantable { var storage = player.getStorage(skill); var reasons = []; for (var i of storage) reasons.add(i.type); - for (var i of reasons) player.removeSkill(skill + '_' + i); + for (var i of reasons) player.removeSkill(skill + "_" + i); delete player.storage[i]; }, subSkill: { damage: { mark: true, - trigger: { global: 'damage' }, + trigger: { global: "damage" }, forced: true, charlotte: true, popup: false, firstDo: true, filter: function (event, player) { if (!event.source) return false; - var storage = player.getStorage('cooperation'); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'damage' && (event.source == player || event.source == info.target)) return true; + if ( + info.type == "damage" && + (event.source == player || event.source == info.target) + ) + return true; } return false; }, - checkx: (info) => (info.damage && info.damage > 3), + checkx: (info) => info.damage && info.damage > 3, content: function () { var source = trigger.source; - var storage = player.getStorage('cooperation'); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'damage' && (source == player || source == info.target)) { + if (info.type == "damage" && (source == player || source == info.target)) { if (!info.damage) info.damage = 0; info.damage += trigger.num; } } - player.markSkill('cooperation_damage'); + player.markSkill("cooperation_damage"); }, - marktext: '仇', + marktext: "仇", intro: { - name: '协力 - 同仇', + name: "协力 - 同仇", markcount: function (storage, player) { - return Math.max.apply(Math, player.getStorage('cooperation').map(function (info) { - return info.damage || 0; - })); + return Math.max.apply( + Math, + player.getStorage("cooperation").map(function (info) { + return info.damage || 0; + }) + ); }, content: function (storage, player) { - var str = '', storage = player.getStorage('cooperation'); + var str = "", + storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'damage') { - str += '
                                    • 协力角色:' + get.translation(info.target); - str += '
                                    • 协力原因:' + get.translation(info.reason); - str += '
                                    • 协力进度:'; - var num = (info.damage || 0); + if (info.type == "damage") { + str += "
                                    • 协力角色:" + get.translation(info.target); + str += "
                                    • 协力原因:" + get.translation(info.reason); + str += "
                                    • 协力进度:"; + var num = info.damage || 0; str += num; - str += '/4'; - str += (num > 3 ? ' (已完成)' : ' (未完成)'); - str += '
                                        '; + str += "/4"; + str += num > 3 ? " (已完成)" : " (未完成)"; + str += "
                                        "; } } return str.slice(4, str.length - 6); @@ -10546,51 +11487,59 @@ export class Library extends Uninstantable { }, draw: { mark: true, - trigger: { global: 'gainAfter' }, + trigger: { global: "gainAfter" }, forced: true, charlotte: true, popup: false, firstDo: true, filter: function (event, player) { - if (event.getParent().name != 'draw') return false; - var storage = player.getStorage('cooperation'); + if (event.getParent().name != "draw") return false; + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'draw' && (event.player == player || event.player == info.target)) return true; + if ( + info.type == "draw" && + (event.player == player || event.player == info.target) + ) + return true; } return false; }, - checkx: (info) => (info.draw && info.draw > 7), + checkx: (info) => info.draw && info.draw > 7, content: function () { var source = trigger.player; - var storage = player.getStorage('cooperation'); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'draw' && (source == player || source == info.target)) { + if (info.type == "draw" && (source == player || source == info.target)) { if (!info.draw) info.draw = 0; info.draw += trigger.cards.length; } } - player.markSkill('cooperation_draw'); + player.markSkill("cooperation_draw"); }, - marktext: '进', + marktext: "进", intro: { - name: '协力 - 并进', + name: "协力 - 并进", markcount: function (storage, player) { - return Math.max.apply(Math, player.getStorage('cooperation').map(function (info) { - return info.draw || 0; - })); + return Math.max.apply( + Math, + player.getStorage("cooperation").map(function (info) { + return info.draw || 0; + }) + ); }, content: function (storage, player) { - var str = '', storage = player.getStorage('cooperation'); + var str = "", + storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'draw') { - str += '
                                    • 协力角色:' + get.translation(info.target); - str += '
                                    • 协力原因:' + get.translation(info.reason); - str += '
                                    • 协力进度:'; - var num = (info.draw || 0); + if (info.type == "draw") { + str += "
                                    • 协力角色:" + get.translation(info.target); + str += "
                                    • 协力原因:" + get.translation(info.reason); + str += "
                                    • 协力进度:"; + var num = info.draw || 0; str += num; - str += '/8'; - str += (num > 7 ? ' (已完成)' : ' (未完成)'); - str += '
                                        '; + str += "/8"; + str += num > 7 ? " (已完成)" : " (未完成)"; + str += "
                                        "; } } return str.slice(4, str.length - 6); @@ -10599,25 +11548,29 @@ export class Library extends Uninstantable { }, discard: { mark: true, - trigger: { global: 'loseAfter' }, + trigger: { global: "loseAfter" }, forced: true, charlotte: true, popup: false, firstDo: true, filter: function (event, player) { - if (event.type != 'discard') return false; - var storage = player.getStorage('cooperation'); + if (event.type != "discard") return false; + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'discard' && (event.player == player || event.player == info.target)) return true; + if ( + info.type == "discard" && + (event.player == player || event.player == info.target) + ) + return true; } return false; }, - checkx: (info) => (info.discard && info.discard.length > 3), + checkx: (info) => info.discard && info.discard.length > 3, content: function () { var source = trigger.player; - var storage = player.getStorage('cooperation'); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'discard' && (source == player || source == info.target)) { + if (info.type == "discard" && (source == player || source == info.target)) { if (!info.discard) info.discard = []; for (var i of trigger.cards2) { var suit = get.suit(i, player); @@ -10625,30 +11578,39 @@ export class Library extends Uninstantable { } } } - player.markSkill('cooperation_discard'); + player.markSkill("cooperation_discard"); }, - marktext: '财', + marktext: "财", intro: { - name: '协力 - 疏财', + name: "协力 - 疏财", markcount: function (storage, player) { - return Math.max.apply(Math, player.getStorage('cooperation').map(function (info) { - return info.discard ? info.discard.length : 0; - })); + return Math.max.apply( + Math, + player.getStorage("cooperation").map(function (info) { + return info.discard ? info.discard.length : 0; + }) + ); }, content: function (storage, player) { - var str = '', storage = player.getStorage('cooperation'); + var str = "", + storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'discard') { - str += '
                                    • 协力角色:' + get.translation(info.target); - str += '
                                    • 协力原因:' + get.translation(info.reason); - str += '
                                    • 进度:'; + if (info.type == "discard") { + str += "
                                    • 协力角色:" + get.translation(info.target); + str += "
                                    • 协力原因:" + get.translation(info.reason); + str += "
                                    • 进度:"; var suits = info.discard || []; - var suits2 = [['spade', '♠', '♤'], ['heart', '♥', '♡'], ['club', '♣', '♧'], ['diamond', '♦', '♢']]; + var suits2 = [ + ["spade", "♠", "♤"], + ["heart", "♥", "♡"], + ["club", "♣", "♧"], + ["diamond", "♦", "♢"], + ]; for (var i of suits2) { - str += (suits.includes(i[0]) ? i[1] : i[2]); + str += suits.includes(i[0]) ? i[1] : i[2]; } - str += (suits.length > 3 ? ' (已完成)' : ' (未完成)'); - str += '
                                        '; + str += suits.length > 3 ? " (已完成)" : " (未完成)"; + str += "
                                        "; } } return str.slice(4, str.length - 6); @@ -10657,7 +11619,7 @@ export class Library extends Uninstantable { }, use: { mark: true, - trigger: { global: 'useCard1' }, + trigger: { global: "useCard1" }, forced: true, charlotte: true, popup: false, @@ -10665,48 +11627,61 @@ export class Library extends Uninstantable { filter: function (event, player) { var suit = get.suit(event.card); if (!lib.suit.includes(suit)) return false; - var storage = player.getStorage('cooperation'); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'use' - && (event.player == player || event.player == info.target) && - (!info.used || !info.used.includes(suit))) return true; + if ( + info.type == "use" && + (event.player == player || event.player == info.target) && + (!info.used || !info.used.includes(suit)) + ) + return true; } return false; }, - checkx: (info) => (info.used && info.used.length > 3), + checkx: (info) => info.used && info.used.length > 3, content: function () { - var source = trigger.player, suit = get.suit(trigger.card); - var storage = player.getStorage('cooperation'); + var source = trigger.player, + suit = get.suit(trigger.card); + var storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'use' && (source == player || source == info.target)) { + if (info.type == "use" && (source == player || source == info.target)) { if (!info.used) info.used = []; info.used.add(suit); } } - player.markSkill('cooperation_use'); + player.markSkill("cooperation_use"); }, - marktext: '戮', + marktext: "戮", intro: { - name: '协力 - 戮力', + name: "协力 - 戮力", markcount: function (storage, player) { - return Math.max.apply(Math, player.getStorage('cooperation').map(function (info) { - return info.used ? info.used.length : 0; - })); + return Math.max.apply( + Math, + player.getStorage("cooperation").map(function (info) { + return info.used ? info.used.length : 0; + }) + ); }, content: function (storage, player) { - var str = '', storage = player.getStorage('cooperation'); + var str = "", + storage = player.getStorage("cooperation"); for (var info of storage) { - if (info.type == 'use') { - str += '
                                    • 协力角色:' + get.translation(info.target); - str += '
                                    • 协力原因:' + get.translation(info.reason); - str += '
                                    • 进度:'; + if (info.type == "use") { + str += "
                                    • 协力角色:" + get.translation(info.target); + str += "
                                    • 协力原因:" + get.translation(info.reason); + str += "
                                    • 进度:"; var suits = info.used || []; - var suits2 = [['spade', '♠', '♤'], ['heart', '♥', '♡'], ['club', '♣', '♧'], ['diamond', '♦', '♢']]; + var suits2 = [ + ["spade", "♠", "♤"], + ["heart", "♥", "♡"], + ["club", "♣", "♧"], + ["diamond", "♦", "♢"], + ]; for (var i of suits2) { - str += (suits.includes(i[0]) ? i[1] : i[2]); + str += suits.includes(i[0]) ? i[1] : i[2]; } - str += (suits.length > 3 ? ' (已完成)' : ' (未完成)'); - str += '
                                        '; + str += suits.length > 3 ? " (已完成)" : " (未完成)"; + str += "
                                        "; } } return str.slice(4, str.length - 6); @@ -10716,21 +11691,25 @@ export class Library extends Uninstantable { }, }, zhengsu: { - trigger: { player: 'phaseDiscardEnd' }, + trigger: { player: "phaseDiscardEnd" }, forced: true, charlotte: true, filter: function (event, player) { - return (player.storage.zhengsu_leijin || player.storage.zhengsu_bianzhen || player.storage.zhengsu_mingzhi); + return ( + player.storage.zhengsu_leijin || + player.storage.zhengsu_bianzhen || + player.storage.zhengsu_mingzhi + ); }, content: function () { - player.chooseDrawRecover(2, '整肃奖励:摸两张牌或回复1点体力'); + player.chooseDrawRecover(2, "整肃奖励:摸两张牌或回复1点体力"); }, subSkill: { leijin: { mod: { aiOrder: function (player, card, num) { - if (typeof card.number != 'number') return; - var history = player.getHistory('useCard', evt => evt.isPhaseUsing()); + if (typeof card.number != "number") return; + var history = player.getHistory("useCard", (evt) => evt.isPhaseUsing()); if (history.length == 0) return num + 10 * (14 - card.number); var num = get.number(history[0].card); if (!num) return; @@ -10743,7 +11722,7 @@ export class Library extends Uninstantable { }, }, mark: true, - trigger: { player: 'useCard1' }, + trigger: { player: "useCard1" }, lastDo: true, charlotte: true, forced: true, @@ -10753,19 +11732,19 @@ export class Library extends Uninstantable { return player.isPhaseUsing() && player.storage.zhengsu_leijin !== false; }, content: function () { - var list = player.getHistory('useCard', function (evt) { + var list = player.getHistory("useCard", function (evt) { return evt.isPhaseUsing(player); }); var goon = true; for (var i = 0; i < list.length; i++) { var num = get.number(list[i].card); - if (typeof num != 'number') { + if (typeof num != "number") { goon = false; break; } if (i > 0) { var num2 = get.number(list[i - 1].card); - if (typeof num2 != 'number' || num2 >= num) { + if (typeof num2 != "number" || num2 >= num) { goon = false; break; } @@ -10774,31 +11753,40 @@ export class Library extends Uninstantable { if (!goon) { game.broadcastAll(function (player) { player.storage.zhengsu_leijin = false; - if (player.marks.zhengsu_leijin) player.marks.zhengsu_leijin.firstChild.innerHTML = '╳'; + if (player.marks.zhengsu_leijin) + player.marks.zhengsu_leijin.firstChild.innerHTML = "╳"; delete player.storage.zhengsu_leijin_markcount; }, player); - } - else { + } else { if (list.length > 2) { - game.broadcastAll(function (player, num) { - if (player.marks.zhengsu_leijin) player.marks.zhengsu_leijin.firstChild.innerHTML = '○'; - player.storage.zhengsu_leijin = true; - player.storage.zhengsu_leijin_markcount = num; - }, player, num); - } - else game.broadcastAll(function (player, num) { - player.storage.zhengsu_leijin_markcount = num; - }, player, num); + game.broadcastAll( + function (player, num) { + if (player.marks.zhengsu_leijin) + player.marks.zhengsu_leijin.firstChild.innerHTML = "○"; + player.storage.zhengsu_leijin = true; + player.storage.zhengsu_leijin_markcount = num; + }, + player, + num + ); + } else + game.broadcastAll( + function (player, num) { + player.storage.zhengsu_leijin_markcount = num; + }, + player, + num + ); } - player.markSkill('zhengsu_leijin'); + player.markSkill("zhengsu_leijin"); }, intro: { - content: '
                                    • 条件:回合内所有于出牌阶段使用的牌点数递增且不少于三张。', + content: "
                                    • 条件:回合内所有于出牌阶段使用的牌点数递增且不少于三张。", }, }, bianzhen: { mark: true, - trigger: { player: 'useCard1' }, + trigger: { player: "useCard1" }, firstDo: true, charlotte: true, forced: true, @@ -10808,14 +11796,14 @@ export class Library extends Uninstantable { return player.isPhaseUsing() && player.storage.zhengsu_bianzhen !== false; }, content: function () { - var list = player.getHistory('useCard', function (evt) { + var list = player.getHistory("useCard", function (evt) { return evt.isPhaseUsing(); }); - var goon = true, suit = get.suit(list[0].card, false); - if (suit == 'none') { + var goon = true, + suit = get.suit(list[0].card, false); + if (suit == "none") { goon = false; - } - else { + } else { for (var i = 1; i < list.length; i++) { if (get.suit(list[i]) != suit) { goon = false; @@ -10826,36 +11814,51 @@ export class Library extends Uninstantable { if (!goon) { game.broadcastAll(function (player) { player.storage.zhengsu_bianzhen = false; - if (player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML = '╳'; + if (player.marks.zhengsu_bianzhen) + player.marks.zhengsu_bianzhen.firstChild.innerHTML = "╳"; }, player); - } - else { + } else { if (list.length > 1) { game.broadcastAll(function (player) { - if (player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML = '○'; + if (player.marks.zhengsu_bianzhen) + player.marks.zhengsu_bianzhen.firstChild.innerHTML = "○"; player.storage.zhengsu_bianzhen = true; }, player); - } - else game.broadcastAll(function (player, suit) { - if (player.marks.zhengsu_bianzhen) player.marks.zhengsu_bianzhen.firstChild.innerHTML = get.translation(suit); - }, player, suit); + } else + game.broadcastAll( + function (player, suit) { + if (player.marks.zhengsu_bianzhen) + player.marks.zhengsu_bianzhen.firstChild.innerHTML = + get.translation(suit); + }, + player, + suit + ); } - player.markSkill('zhengsu_bianzhen'); + player.markSkill("zhengsu_bianzhen"); }, intro: { - content: '
                                    • 条件:回合内所有于出牌阶段使用的牌花色相同且不少于两张。', + content: "
                                    • 条件:回合内所有于出牌阶段使用的牌花色相同且不少于两张。", }, ai: { effect: { player_use: function (card, player, target) { - if (typeof card != 'object' || !player.isPhaseUsing()) return; + if (typeof card != "object" || !player.isPhaseUsing()) return; var suitx = get.suit(card); - var history = player.getHistory('useCard'); + var history = player.getHistory("useCard"); if (!history.length) { var val = 0; - if (player.hasCard(function (cardx) { - return get.suit(cardx) == suitx && card != cardx && (!card.cards || !card.cards.includes(cardx)) && player.hasValueTarget(cardx); - }, 'hs')) val = [2, 0.1]; + if ( + player.hasCard(function (cardx) { + return ( + get.suit(cardx) == suitx && + card != cardx && + (!card.cards || !card.cards.includes(cardx)) && + player.hasValueTarget(cardx) + ); + }, "hs") + ) + val = [2, 0.1]; if (val) return val; return; } @@ -10869,67 +11872,84 @@ export class Library extends Uninstantable { num++; } if (suitx == suit && num == 1) return [1, 0.1]; - if (suitx != suit && (num > 1 || num <= 1 && player.hasCard(function (cardx) { - return get.suit(cardx) == suit && player.hasValueTarget(cardx); - }, 'hs'))) return 'zeroplayertarget'; + if ( + suitx != suit && + (num > 1 || + (num <= 1 && + player.hasCard(function (cardx) { + return ( + get.suit(cardx) == suit && player.hasValueTarget(cardx) + ); + }, "hs"))) + ) + return "zeroplayertarget"; }, }, }, }, mingzhi: { mark: true, - trigger: { player: 'loseAfter' }, + trigger: { player: "loseAfter" }, firstDo: true, charlotte: true, forced: true, popup: false, onremove: true, filter: function (event, player) { - if (player.storage.zhengsu_mingzhi === false || event.type != 'discard') return false; - var evt = event.getParent('phaseDiscard'); + if (player.storage.zhengsu_mingzhi === false || event.type != "discard") return false; + var evt = event.getParent("phaseDiscard"); return evt && evt.player == player; }, content: function () { - var goon = true, list = []; - player.getHistory('lose', function (event) { - if (!goon || event.type != 'discard') return false; - var evt = event.getParent('phaseDiscard'); + var goon = true, + list = []; + player.getHistory("lose", function (event) { + if (!goon || event.type != "discard") return false; + var evt = event.getParent("phaseDiscard"); if (evt && evt.player == player) { for (var i of event.cards2) { var suit = get.suit(i, player); if (list.includes(suit)) { goon = false; break; - } - else list.push(suit); + } else list.push(suit); } } }); if (!goon) { game.broadcastAll(function (player) { player.storage.zhengsu_mingzhi = false; - if (player.marks.zhengsu_mingzhi) player.marks.zhengsu_mingzhi.firstChild.innerHTML = '╳'; + if (player.marks.zhengsu_mingzhi) + player.marks.zhengsu_mingzhi.firstChild.innerHTML = "╳"; delete player.storage.zhengsu_mingzhi_list; }, player); - } - else { + } else { if (list.length > 1) { - game.broadcastAll(function (player, list) { - if (player.marks.zhengsu_mingzhi) player.marks.zhengsu_mingzhi.firstChild.innerHTML = '○'; - player.storage.zhengsu_mingzhi = true; - player.storage.zhengsu_mingzhi_list = list; - player.storage.zhengsu_mingzhi_markcount = list.length; - }, player, list); - } - else game.broadcastAll(function (player, list) { - player.storage.zhengsu_mingzhi_list = list; - player.storage.zhengsu_mingzhi_markcount = list.length; - }, player, list); + game.broadcastAll( + function (player, list) { + if (player.marks.zhengsu_mingzhi) + player.marks.zhengsu_mingzhi.firstChild.innerHTML = "○"; + player.storage.zhengsu_mingzhi = true; + player.storage.zhengsu_mingzhi_list = list; + player.storage.zhengsu_mingzhi_markcount = list.length; + }, + player, + list + ); + } else + game.broadcastAll( + function (player, list) { + player.storage.zhengsu_mingzhi_list = list; + player.storage.zhengsu_mingzhi_markcount = list.length; + }, + player, + list + ); } - player.markSkill('zhengsu_mingzhi'); + player.markSkill("zhengsu_mingzhi"); }, intro: { - content: '
                                    • 条件:回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。', + content: "
                                    • 条件:回合内所有于弃牌阶段弃置的牌花色均不相同且不少于两张。", }, }, }, @@ -10940,45 +11960,54 @@ export class Library extends Uninstantable { return _status.renku.length; }, mark: function (dialog, content, player) { - if (!_status.renku.length) return '仁库中没有牌'; + if (!_status.renku.length) return "仁库中没有牌"; else dialog.addAuto(_status.renku); }, content: function () { - if (!_status.renku.length) return '仁库中没有牌'; + if (!_status.renku.length) return "仁库中没有牌"; return get.translation(_status.renku); }, }, }, _showHiddenCharacter: { - trigger: { player: ['changeHp', 'phaseBeginStart', 'loseMaxHpBegin', 'gainMaxHpBegin'] }, + trigger: { player: ["changeHp", "phaseBeginStart", "loseMaxHpBegin", "gainMaxHpBegin"] }, firstDo: true, forced: true, popup: false, priority: 25, filter: function (event, player, name) { - return player.isUnseen(2) && get.mode() != 'guozhan'; + return player.isUnseen(2) && get.mode() != "guozhan"; }, content: function () { player.showCharacter(2); - player.removeSkill('g_hidden_ai'); + player.removeSkill("g_hidden_ai"); }, }, _kamisha: { - trigger: { source: 'damageBegin2' }, + trigger: { source: "damageBegin2" }, //forced:true, popup: false, prompt: function (event, player) { - return '是否防止即将对' + get.translation(event.player) + '造成的伤害,改为令其减少' + get.cnNumber(event.num) + '点体力上限?'; + return ( + "是否防止即将对" + + get.translation(event.player) + + "造成的伤害,改为令其减少" + + get.cnNumber(event.num) + + "点体力上限?" + ); }, filter: function (event, player) { - return event.hasNature('kami') && event.num > 0; + return event.hasNature("kami") && event.num > 0; }, ruleSkill: true, check: function (event, player) { var att = get.attitude(player, event.player); if (event.player.hp == event.player.maxHp) return att < 0; - if (event.player.hp == event.player.maxHp - 1 && - (event.player.maxHp <= 3 || event.player.hasSkillTag('maixie'))) return att < 0; + if ( + event.player.hp == event.player.maxHp - 1 && + (event.player.maxHp <= 3 || event.player.hasSkillTag("maixie")) + ) + return att < 0; return att > 0; }, content: function () { @@ -10990,10 +12019,12 @@ export class Library extends Uninstantable { charlotte: true, mod: { targetEnabled: function (card) { - if (card.name == 'tao' && (card.isCard && card.cardid || get.itemtype(card) == 'card')) return false; + if (card.name == "tao" && ((card.isCard && card.cardid) || get.itemtype(card) == "card")) + return false; }, cardSavable: function (card) { - if (card.name == 'tao' && (card.isCard && card.cardid || get.itemtype(card) == 'card')) return false; + if (card.name == "tao" && ((card.isCard && card.cardid) || get.itemtype(card) == "card")) + return false; }, }, group: ["aozhan_sha", "aozhan_shan"], @@ -11008,18 +12039,20 @@ export class Library extends Uninstantable { isCard: true, }, viewAsFilter: function (player) { - if (!player.countCards('hs', 'tao')) return false; + if (!player.countCards("hs", "tao")) return false; }, - position: 'hs', + position: "hs", prompt: "将一张桃当杀使用或打出", - check: function () { return 1; }, + check: function () { + return 1; + }, ai: { respondSha: true, skillTagFilter: function (player) { - if (!player.countCards('hs', 'tao')) return false; + if (!player.countCards("hs", "tao")) return false; }, order: function () { - return get.order({ name: 'sha' }) - 0.1; + return get.order({ name: "sha" }) - 0.1; }, }, sub: true, @@ -11034,15 +12067,17 @@ export class Library extends Uninstantable { isCard: true, }, prompt: "将一张桃当闪打出", - check: function () { return 1; }, - viewAsFilter: function (player) { - if (!player.countCards('hs', 'tao')) return false; + check: function () { + return 1; }, - position: 'hs', + viewAsFilter: function (player) { + if (!player.countCards("hs", "tao")) return false; + }, + position: "hs", ai: { respondShan: true, skillTagFilter: function (player) { - if (!player.countCards('hs', 'tao')) return false; + if (!player.countCards("hs", "tao")) return false; }, }, sub: true, @@ -11059,39 +12094,54 @@ export class Library extends Uninstantable { land_used: {}, unequip: { ai: { unequip: true } }, subplayer: { - trigger: { player: 'dieBefore' }, + trigger: { player: "dieBefore" }, forced: true, priority: -9, onremove: true, - mark: 'character', + mark: "character", intro: { content: function (storage, player) { - if (typeof storage.intro2 == 'string') return storage.intro2; - if (typeof storage.intro2 == 'function') return storage.intro2(storage, player); - return '死亡前切换回主武将'; + if (typeof storage.intro2 == "string") return storage.intro2; + if (typeof storage.intro2 == "function") return storage.intro2(storage, player); + return "死亡前切换回主武将"; }, name: function (storage) { return get.rawName(storage.name); - } + }, }, content: function () { trigger.cancel(); - var evt = trigger.getParent('damage'); + var evt = trigger.getParent("damage"); if (evt.player == player) { evt.untrigger(false, player); } player.exitSubPlayer(true); }, ai: { - nosave: true - } + nosave: true, + }, }, autoswap: { firstDo: true, trigger: { - player: ['playercontrol', 'chooseToUseBegin', 'chooseToRespondBegin', 'chooseToDiscardBegin', 'chooseToCompareBegin', - 'chooseButtonBegin', 'chooseCardBegin', 'chooseTargetBegin', 'chooseCardTargetBegin', 'chooseControlBegin', - 'chooseBoolBegin', 'choosePlayerCardBegin', 'discardPlayerCardBegin', 'gainPlayerCardBegin', 'chooseToMoveBegin', 'chooseToPlayBeatmapBegin'] + player: [ + "playercontrol", + "chooseToUseBegin", + "chooseToRespondBegin", + "chooseToDiscardBegin", + "chooseToCompareBegin", + "chooseButtonBegin", + "chooseCardBegin", + "chooseTargetBegin", + "chooseCardTargetBegin", + "chooseControlBegin", + "chooseBoolBegin", + "choosePlayerCardBegin", + "discardPlayerCardBegin", + "gainPlayerCardBegin", + "chooseToMoveBegin", + "chooseToPlayBeatmapBegin", + ], }, forced: true, priority: 100, @@ -11111,7 +12161,7 @@ export class Library extends Uninstantable { charlotte: true, subSkill: { turn: { - trigger: { player: ['turnOverAfter', 'dieBefore'] }, + trigger: { player: ["turnOverAfter", "dieBefore"] }, silent: true, filter: function (event, player) { if (player.storage.dualside_over) return false; @@ -11120,44 +12170,53 @@ export class Library extends Uninstantable { content: function () { var cfg = player.storage.dualside; var bool = player.isTurnedOver(); - if (trigger.name == 'die') { + if (trigger.name == "die") { bool = !bool; } if (bool) { cfg[1] = player.hp; cfg[2] = player.maxHp; player.reinit(cfg[0], cfg[3], [cfg[4], cfg[5]]); - player.unmarkSkill('dualside'); - player.markSkillCharacter('dualside', { name: cfg[0] }, '正面', '当前体力:' + cfg[1] + '/' + cfg[2]); - } - else { + player.unmarkSkill("dualside"); + player.markSkillCharacter( + "dualside", + { name: cfg[0] }, + "正面", + "当前体力:" + cfg[1] + "/" + cfg[2] + ); + } else { cfg[4] = player.hp; cfg[5] = player.maxHp; player.reinit(cfg[3], cfg[0], [cfg[1], cfg[2]]); - player.unmarkSkill('dualside'); - player.markSkillCharacter('dualside', { name: cfg[3] }, '背面', '当前体力:' + cfg[4] + '/' + cfg[5]); + player.unmarkSkill("dualside"); + player.markSkillCharacter( + "dualside", + { name: cfg[3] }, + "背面", + "当前体力:" + cfg[4] + "/" + cfg[5] + ); } - if (trigger.name == 'die') { + if (trigger.name == "die") { trigger.cancel(); delete player.storage.dualside; player.storage.dualside_over = true; - player.unmarkSkill('dualside'); + player.unmarkSkill("dualside"); } - } + }, }, init: { - trigger: { global: 'gameStart', player: 'enterGame' }, + trigger: { global: "gameStart", player: "enterGame" }, silent: true, content: function () { var list = [player.name, player.name1, player.name2]; for (var i = 0; i < list.length; i++) { if (list[i] && lib.character[list[i]]) { var info = lib.character[list[i]]; - if (info[3].includes('dualside') && info[4]) { + if (info[3].includes("dualside") && info[4]) { player.storage.dualside = [list[i], player.hp, player.maxHp]; for (var j = 0; j < info[4].length; j++) { - if (info[4][j].startsWith('dualside:')) { + if (info[4][j].startsWith("dualside:")) { var name2 = info[4][j].slice(9); var info2 = lib.character[name2]; player.storage.dualside.push(name2); @@ -11169,19 +12228,23 @@ export class Library extends Uninstantable { } } var cfg = player.storage.dualside; - if (get.mode() == 'guozhan') { + if (get.mode() == "guozhan") { if (player.name1 == cfg[0]) { player.showCharacter(0); - } - else { + } else { player.showCharacter(1); } } - player.markSkillCharacter('dualside', { name: cfg[3] }, '背面', '当前体力:' + cfg[4] + '/' + cfg[5]); - } - } + player.markSkillCharacter( + "dualside", + { name: cfg[3] }, + "背面", + "当前体力:" + cfg[4] + "/" + cfg[5] + ); + }, + }, }, - group: ['dualside_init', 'dualside_turn'] + group: ["dualside_init", "dualside_turn"], }, fengyin: { init: function (player, skill) { @@ -11200,10 +12263,10 @@ export class Library extends Uninstantable { var list = player.getSkills(null, false, false).filter(function (i) { return lib.skill.fengyin.skillBlocker(i, player); }); - if (list.length) return '失效技能:' + get.translation(list); - return '无失效技能'; - } - } + if (list.length) return "失效技能:" + get.translation(list); + return "无失效技能"; + }, + }, }, baiban: { init: function (player, skill) { @@ -11222,32 +12285,32 @@ export class Library extends Uninstantable { var list = player.getSkills(null, false, false).filter(function (i) { return lib.skill.baiban.skillBlocker(i, player); }); - if (list.length) return '失效技能:' + get.translation(list); - return '无失效技能'; - } - } + if (list.length) return "失效技能:" + get.translation(list); + return "无失效技能"; + }, + }, }, qianxing: { mark: true, nopop: true, init: function (player) { - game.log(player, '获得了', '【潜行】'); + game.log(player, "获得了", "【潜行】"); }, intro: { - content: '锁定技,你不能成为其他角色的卡牌的目标' + content: "锁定技,你不能成为其他角色的卡牌的目标", }, mod: { targetEnabled: function (card, player, target) { if (player != target) return false; - } - } + }, + }, }, mianyi: { - trigger: { player: 'damageBefore' }, + trigger: { player: "damageBefore" }, mark: true, forced: true, init: function (player) { - game.log(player, '获得了', '【免疫】'); + game.log(player, "获得了", "【免疫】"); }, content: function () { trigger.cancel(); @@ -11258,57 +12321,57 @@ export class Library extends Uninstantable { nodamage: true, effect: { target: function (card, player, target, current) { - if (get.tag(card, 'damage')) return [0, 0]; - } + if (get.tag(card, "damage")) return [0, 0]; + }, }, }, intro: { - content: '防止一切伤害' - } + content: "防止一切伤害", + }, }, mad: { mark: true, locked: true, intro: { - content: '已进入混乱状态', - name: '混乱', + content: "已进入混乱状态", + name: "混乱", onunmark: function (storage, player) { - game.log(player, '解除混乱状态'); - } - } + game.log(player, "解除混乱状态"); + }, + }, }, ghujia: { intro: { content: function (content, player) { - return '已有' + get.cnNumber(player.hujia) + '点护甲值'; - } + return "已有" + get.cnNumber(player.hujia) + "点护甲值"; + }, }, - markimage: 'image/card/shield.png', + markimage: "image/card/shield.png", }, counttrigger: { - trigger: { global: 'phaseAfter' }, + trigger: { global: "phaseAfter" }, silent: true, charlotte: true, priority: -100, lastDo: true, content: function () { - player.removeSkill('counttrigger'); + player.removeSkill("counttrigger"); delete player.storage.counttrigger; }, - group: 'counttrigger_2', + group: "counttrigger_2", subSkill: { 2: { - trigger: { global: ['phaseBeforeStart', 'roundStart'] }, + trigger: { global: ["phaseBeforeStart", "roundStart"] }, silent: true, charlotte: true, firstDo: true, priority: 100, content: function () { - player.removeSkill('counttrigger'); + player.removeSkill("counttrigger"); delete player.storage.counttrigger; }, - } - } + }, + }, }, /** * @deprecated @@ -11403,24 +12466,24 @@ export class Library extends Uninstantable { }, },*/ _usecard: { - trigger: { global: 'useCardAfter' }, + trigger: { global: "useCardAfter" }, forced: true, popup: false, priority: -100, lastDo: true, silent: true, filter: function (event) { - return !event._cleared && event.card.name != 'wuxie'; + return !event._cleared && event.card.name != "wuxie"; }, content: function () { game.broadcastAll(function () { ui.clear(); }); event._cleared = true; - } + }, }, _discard: { - trigger: { global: ['discardAfter', 'loseToDiscardpileAfter', 'loseAsyncAfter'] }, + trigger: { global: ["discardAfter", "loseToDiscardpileAfter", "loseAsyncAfter"] }, forced: true, popup: false, priority: -100, @@ -11435,7 +12498,7 @@ export class Library extends Uninstantable { delete ui.todiscard[id]; if (todiscard) { var time = 1000; - if (typeof todiscard._discardtime == 'number') { + if (typeof todiscard._discardtime == "number") { time += todiscard._discardtime - get.time(); } if (time < 0) { @@ -11448,7 +12511,7 @@ export class Library extends Uninstantable { }, time); } }, trigger.discardid); - } + }, }, _save: { //trigger:{source:'dying2',player:'dying2'}, @@ -11472,12 +12535,17 @@ export class Library extends Uninstantable { return; } event.acted.push(player); - var str = get.translation(trigger.player) + '濒死,是否帮助?'; - var str2 = '当前体力:' + trigger.player.hp; - if (lib.config.tao_enemy && event.dying.side != player.side && lib.config.mode != 'identity' && lib.config.mode != 'guozhan' && !event.dying.hasSkillTag('revertsave')) { + var str = get.translation(trigger.player) + "濒死,是否帮助?"; + var str2 = "当前体力:" + trigger.player.hp; + if ( + lib.config.tao_enemy && + event.dying.side != player.side && + lib.config.mode != "identity" && + lib.config.mode != "guozhan" && + !event.dying.hasSkillTag("revertsave") + ) { event._result = { bool: false }; - } - else if (player.canSave(event.dying)) { + } else if (player.canSave(event.dying)) { player.chooseToUse({ filterCard: function (card, player, event) { event = event || _status.event; @@ -11488,23 +12556,36 @@ export class Library extends Uninstantable { if (!card) return false; var info = get.info(card); if (!info.singleCard || ui.selected.targets.length == 0) { - var mod = game.checkMod(card, player, target, 'unchanged', 'playerEnabled', player); + var mod = game.checkMod( + card, + player, + target, + "unchanged", + "playerEnabled", + player + ); if (mod == false) return false; - var mod = game.checkMod(card, player, target, 'unchanged', 'targetEnabled', target); - if (mod != 'unchanged') return mod; + var mod = game.checkMod( + card, + player, + target, + "unchanged", + "targetEnabled", + target + ); + if (mod != "unchanged") return mod; } return true; }, prompt: str, prompt2: str2, ai1: function (card) { - if (typeof card == 'string') { + if (typeof card == "string") { var info = get.info(card); if (info.ai && info.ai.order) { - if (typeof info.ai.order == 'number') { + if (typeof info.ai.order == "number") { return info.ai.order; - } - else if (typeof info.ai.order == 'function') { + } else if (typeof info.ai.order == "function") { return info.ai.order(); } } @@ -11512,26 +12593,31 @@ export class Library extends Uninstantable { return 1; }, ai2: get.effect_use, - type: 'dying', + type: "dying", targetRequired: true, - dying: event.dying + dying: event.dying, }); - } - else { + } else { event._result = { bool: false }; } "step 2"; if (result.bool) { var player = trigger.player; - if (player.hp <= 0 && !trigger.nodying && !player.nodying && player.isAlive() && !player.isOut() && !player.removed) event.goto(0); + if ( + player.hp <= 0 && + !trigger.nodying && + !player.nodying && + player.isAlive() && + !player.isOut() && + !player.removed + ) + event.goto(0); else trigger.untrigger(); - } - else { + } else { for (var i = 0; i < 20; i++) { if (event.acted.includes(event.player.next)) { break; - } - else { + } else { event.player = event.player.next; if (!event.player.isOut()) { event.goto(1); @@ -11540,23 +12626,27 @@ export class Library extends Uninstantable { } } } - } + }, }, _ismin: { mod: { cardEnabled: function (card, player) { if (player.isMin()) { - if (get.type(card) == 'equip') return false; + if (get.type(card) == "equip") return false; } - } - } + }, + }, }, _recasting: { - enable: 'phaseUse', + enable: "phaseUse", logv: false, - prompt: '将要重铸的牌置入弃牌堆并摸一张牌', - filter: (event, player) => player.hasCard(card => lib.skill._recasting.filterCard(card, player), lib.skill._recasting.position), - position: 'he', + prompt: "将要重铸的牌置入弃牌堆并摸一张牌", + filter: (event, player) => + player.hasCard( + (card) => lib.skill._recasting.filterCard(card, player), + lib.skill._recasting.position + ), + position: "he", filterCard: (card, player) => player.canRecast(card, null, true), discard: false, lose: false, @@ -11564,28 +12654,31 @@ export class Library extends Uninstantable { content: () => { player.recast(cards, void 0, (player, cards) => { var numberOfCardsToDraw = cards.length; - cards.forEach(value => { - if (lib.config.mode == 'stone' && _status.mode == 'deck' && !player.isMin() && get.type(value).startsWith('stone')) { + cards.forEach((value) => { + if ( + lib.config.mode == "stone" && + _status.mode == "deck" && + !player.isMin() && + get.type(value).startsWith("stone") + ) { var stonecard = get.stonecard(1, player.career); if (stonecard.length) { numberOfCardsToDraw -= stonecard.length; - player.gain(game.createCard(stonecard.randomGet()), 'draw'); - } - else player.draw({ - drawDeck: 1 - }).log = false; - } - else if (get.subtype(value) == 'spell_gold') { - var libCard = get.libCard(info => info.subtype == 'spell_silver'); + player.gain(game.createCard(stonecard.randomGet()), "draw"); + } else + player.draw({ + drawDeck: 1, + }).log = false; + } else if (get.subtype(value) == "spell_gold") { + var libCard = get.libCard((info) => info.subtype == "spell_silver"); if (!libCard.length) return; numberOfCardsToDraw--; - player.gain(game.createCard(libCard.randomGet()), 'draw'); - } - else if (get.subtype(value) == 'spell_silver') { - var libCard = get.libCard(info => info.subtype == 'spell_bronze'); + player.gain(game.createCard(libCard.randomGet()), "draw"); + } else if (get.subtype(value) == "spell_silver") { + var libCard = get.libCard((info) => info.subtype == "spell_bronze"); if (!libCard.length) return; numberOfCardsToDraw--; - player.gain(game.createCard(libCard.randomGet()), 'draw'); + player.gain(game.createCard(libCard.randomGet()), "draw"); } }); if (numberOfCardsToDraw) player.draw(numberOfCardsToDraw).log = false; @@ -11593,15 +12686,15 @@ export class Library extends Uninstantable { }, ai: { basic: { - order: 6 + order: 6, }, result: { - player: 1 - } - } + player: 1, + }, + }, }, _lianhuan: { - trigger: { player: 'damageAfter' }, + trigger: { player: "damageAfter" }, filter: function (event, player) { return event.lianhuanable == true; }, @@ -11633,7 +12726,7 @@ export class Library extends Uninstantable { }, }, _lianhuan4: { - trigger: { player: 'changeHp' }, + trigger: { player: "changeHp" }, priority: -10, forced: true, popup: false, @@ -11641,12 +12734,12 @@ export class Library extends Uninstantable { silent: true, filter: function (event, player) { var evt = event.getParent(); - return evt && evt.name == 'damage' && evt.hasNature('linked') && player.isLinked(); + return evt && evt.name == "damage" && evt.hasNature("linked") && player.isLinked(); }, content: function () { player.link(); if (trigger.getParent().notLink()) trigger.getParent().lianhuanable = true; - } + }, }, /** * @deprecated @@ -11675,20 +12768,19 @@ export class Library extends Uninstantable { }, set ai(ai) { lib.skill._recasting.ai = ai; - } - } + }, + }, }; - static character = {}; - static perfectPair = {}; - static cardPile = {}; - static message = { + character = {}; + perfectPair = {}; + cardPile = {}; + message = { server: { /** @this { any } */ init(version, config, banned_info) { if (lib.node.banned.includes(banned_info)) { - this.send('denied', 'banned'); - } - else if (config.id && lib.playerOL && lib.playerOL[config.id]) { + this.send("denied", "banned"); + } else if (config.id && lib.playerOL && lib.playerOL[config.id]) { var player = lib.playerOL[config.id]; player.setNickname(); player.ws = this; @@ -11697,49 +12789,71 @@ export class Library extends Uninstantable { game.broadcast(function (player) { player.setNickname(); }, player); - this.send('reinit', lib.configOL, get.arenaState(), game.getState ? game.getState() : {}, game.ip, null, _status.onreconnect, _status.cardtag, _status.postReconnect); - } - else if (version != lib.versionOL) { - this.send('denied', 'version'); + this.send( + "reinit", + lib.configOL, + get.arenaState(), + game.getState ? game.getState() : {}, + game.ip, + null, + _status.onreconnect, + _status.cardtag, + _status.postReconnect + ); + } else if (version != lib.versionOL) { + this.send("denied", "version"); lib.node.clients.remove(this); this.closed = true; - } - else if (!_status.waitingForPlayer) { + } else if (!_status.waitingForPlayer) { if (game.phaseNumber && lib.configOL.observe) { lib.node.observing.push(this); - this.send('reinit', lib.configOL, get.arenaState(), game.getState ? game.getState() : {}, game.ip, game.players[0].playerid, null, _status.cardtag); + this.send( + "reinit", + lib.configOL, + get.arenaState(), + game.getState ? game.getState() : {}, + game.ip, + game.players[0].playerid, + null, + _status.cardtag + ); if (!ui.removeObserve) { - ui.removeObserve = ui.create.system('移除旁观', function () { - lib.configOL.observe = false; - if (game.onlineroom) { - game.send('server', 'config', lib.configOL); - } - while (lib.node.observing.length) { - lib.node.observing.shift().ws.close(); - } - this.remove(); - delete ui.removeObserve; - }, true, true); + ui.removeObserve = ui.create.system( + "移除旁观", + function () { + lib.configOL.observe = false; + if (game.onlineroom) { + game.send("server", "config", lib.configOL); + } + while (lib.node.observing.length) { + lib.node.observing.shift().ws.close(); + } + this.remove(); + delete ui.removeObserve; + }, + true, + true + ); } - } - else { - this.send('denied', 'gaming'); + } else { + this.send("denied", "gaming"); lib.node.clients.remove(this); this.closed = true; } - } - else if (lib.node.clients.length - (window.isNonameServer ? 1 : 0) >= parseInt(lib.configOL.number)) { - this.send('denied', 'number'); + } else if ( + lib.node.clients.length - (window.isNonameServer ? 1 : 0) >= + parseInt(lib.configOL.number) + ) { + this.send("denied", "number"); lib.node.clients.remove(this); this.closed = true; - } - else { + } else { if (config) { this.avatar = config.avatar; this.nickname = config.nickname; } for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].classList.contains('unselectable2')) continue; + if (game.connectPlayers[i].classList.contains("unselectable2")) continue; if (game.connectPlayers[i] != game.me && !game.connectPlayers[i].playerid) { game.connectPlayers[i].playerid = this.id; game.connectPlayers[i].initOL(this.nickname, this.avatar); @@ -11747,7 +12861,7 @@ export class Library extends Uninstantable { break; } } - this.send('init', this.id, lib.configOL, game.ip, window.isNonameServer, game.roomId); + this.send("init", this.id, lib.configOL, game.ip, window.isNonameServer, game.roomId); } }, /** @this { any } */ @@ -11790,19 +12904,23 @@ export class Library extends Uninstantable { ui.connectStartBar.firstChild.innerHTML = get.modetrans(lib.configOL, true); } }, config); - if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong' && game.connectPlayers) { + if ( + lib.configOL.mode == "identity" && + lib.configOL.identity_mode == "zhong" && + game.connectPlayers + ) { for (var i = 0; i < game.connectPlayers.length; i++) { - game.connectPlayers[i].classList.remove('unselectable2'); + game.connectPlayers[i].classList.remove("unselectable2"); } lib.configOL.number = 8; game.updateWaiting(); } if (game.onlineroom) { - game.send('server', 'config', lib.configOL); + game.send("server", "config", lib.configOL); } for (var i = 0; i < game.connectPlayers.length; i++) { if (game.connectPlayers[i].playerid == this.id) { - game.connectPlayers[i].chat('房间设置已更改'); + game.connectPlayers[i].chat("房间设置已更改"); } } } @@ -11810,13 +12928,12 @@ export class Library extends Uninstantable { changeNumConfig: function (num, index, bool) { if (this.id == game.onlinezhu) { lib.configOL.number = num; - game.send('server', 'config', lib.configOL); + game.send("server", "config", lib.configOL); if (game.connectPlayers && game.connectPlayers[index]) { if (bool) { - game.connectPlayers[index].classList.add('unselectable2'); - } - else { - game.connectPlayers[index].classList.remove('unselectable2'); + game.connectPlayers[index].classList.add("unselectable2"); + } else { + game.connectPlayers[index].classList.remove("unselectable2"); } game.updateWaiting(); } @@ -11832,22 +12949,28 @@ export class Library extends Uninstantable { emotion: function (id, pack, emotion) { if (lib.node.observing.includes(this)) return; var that = this; - if (!this.id || (!lib.playerOL[this.id] && (!game.connectPlayers || !function () { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == that.id) { - return true; - } - } - return false; - }()))) return; + if ( + !this.id || + (!lib.playerOL[this.id] && + (!game.connectPlayers || + !(function () { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == that.id) { + return true; + } + } + return false; + })())) + ) + return; var player; if (lib.playerOL[id]) { player = lib.playerOL[id]; - } - else if (game.connectPlayers) { + } else if (game.connectPlayers) { for (var i = 0; i < game.connectPlayers.length; i++) { if (game.connectPlayers[i].playerid == id) { - player = game.connectPlayers[i]; break; + player = game.connectPlayers[i]; + break; } } } @@ -11856,22 +12979,28 @@ export class Library extends Uninstantable { chat: function (id, str) { if (lib.node.observing.includes(this)) return; var that = this; - if (!this.id || (!lib.playerOL[this.id] && (!game.connectPlayers || !function () { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == that.id) { - return true; - } - } - return false; - }()))) return; + if ( + !this.id || + (!lib.playerOL[this.id] && + (!game.connectPlayers || + !(function () { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == that.id) { + return true; + } + } + return false; + })())) + ) + return; var player; if (lib.playerOL[id]) { player = lib.playerOL[id]; - } - else if (game.connectPlayers) { + } else if (game.connectPlayers) { for (var i = 0; i < game.connectPlayers.length; i++) { if (game.connectPlayers[i].playerid == id) { - player = game.connectPlayers[i]; break; + player = game.connectPlayers[i]; + break; } } } @@ -11880,20 +13009,23 @@ export class Library extends Uninstantable { giveup: function (player) { if (lib.node.observing.includes(this) || !player || !player._giveUp) return; _status.event.next.length = 0; - game.createEvent('giveup', false).set('includeOut', true).setContent(function () { - game.log(player, '投降'); - player.popup('投降'); - player.die('nosource').includeOut = true; - }).player = player; + game + .createEvent("giveup", false) + .set("includeOut", true) + .setContent(function () { + game.log(player, "投降"); + player.popup("投降"); + player.die("nosource").includeOut = true; + }).player = player; }, auto: function () { if (lib.node.observing.includes(this)) return; var player = lib.playerOL[this.id]; if (player) { player.isAuto = true; - player.setNickname(player.nickname + ' - 托管'); + player.setNickname(player.nickname + " - 托管"); game.broadcast(function (player) { - player.setNickname(player.nickname + ' - 托管'); + player.setNickname(player.nickname + " - 托管"); }, player); } }, @@ -11919,15 +13051,14 @@ export class Library extends Uninstantable { var items = []; try { for (var i = 0; i < arguments.length; i++) { - eval('items.push(' + arguments[i] + ')'); + eval("items.push(" + arguments[i] + ")"); } - } - catch (e) { - this.send('log', ['err']); + } catch (e) { + this.send("log", ["err"]); return; } - this.send('log', items); - } + this.send("log", items); + }, }, client: { log: function (arr) { @@ -11938,16 +13069,21 @@ export class Library extends Uninstantable { } }, opened: function () { - game.send('init', lib.versionOL, { - id: game.onlineID, - avatar: lib.config.connect_avatar, - nickname: get.connectNickname() - }, lib.config.banned_info); + game.send( + "init", + lib.versionOL, + { + id: game.onlineID, + avatar: lib.config.connect_avatar, + nickname: get.connectNickname(), + }, + lib.config.banned_info + ); if (ui.connecting && !ui.connecting.splashtimeout) { - ui.connecting.firstChild.innerHTML = '重连成功'; + ui.connecting.firstChild.innerHTML = "重连成功"; } }, - onconnection: id => lib.init.connection(lib.wsOL[id] = new lib.element.NodeWS(id)), + onconnection: (id) => lib.init.connection((lib.wsOL[id] = new lib.element.NodeWS(id))), onmessage: function (id, message) { if (lib.wsOL[id]) { lib.wsOL[id].onmessage(message); @@ -11962,9 +13098,8 @@ export class Library extends Uninstantable { if (game.online || game.onlineroom) { if ((game.servermode || game.onlinehall) && _status.over) { // later - } - else { - game.saveConfig('tmp_user_roomId'); + } else { + game.saveConfig("tmp_user_roomId"); } } game.ws.close(); @@ -11980,32 +13115,31 @@ export class Library extends Uninstantable { game.roomId = index; lib.node = {}; if (config && mode && window.isNonameServer) { - if (mode == 'auto') { + if (mode == "auto") { mode = lib.configOL.mode; } game.switchMode(mode, config); - } - else { + } else { game.switchMode(lib.configOL.mode); } ui.create.connecting(true); }, enterroomfailed: function () { - alert('请稍后再试'); + alert("请稍后再试"); _status.enteringroom = false; ui.create.connecting(true); }, roomlist: function (list, events, clients, wsid) { - game.send('server', 'key', [game.onlineKey, lib.version]); + game.send("server", "key", [game.onlineKey, lib.version]); game.online = true; game.onlinehall = true; lib.config.recentIP.remove(_status.ip); lib.config.recentIP.unshift(_status.ip); lib.config.recentIP.splice(5); if (!lib.config.reconnect_info || lib.config.reconnect_info[0] != _status.ip) { - game.saveConfig('reconnect_info', [_status.ip, null]); + game.saveConfig("reconnect_info", [_status.ip, null]); } - game.saveConfig('recentIP', lib.config.recentIP); + game.saveConfig("recentIP", lib.config.recentIP); _status.connectMode = true; game.clearArena(); @@ -12014,22 +13148,45 @@ export class Library extends Uninstantable { ui.auto.hide(); clearTimeout(_status.createNodeTimeout); - game.send('server', 'changeAvatar', get.connectNickname(), lib.config.connect_avatar); + game.send("server", "changeAvatar", get.connectNickname(), lib.config.connect_avatar); var proceed = function () { game.ip = get.trimip(_status.ip); ui.create.connectRooms(list); if (events) { - ui.connectEvents = ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv', '约战', ui.window, ui.click.connectEvents); - ui.connectEventsCount = ui.create.div('.forceopaque.menubutton.icon.connectevents.highlight.hidden', '', ui.window); - ui.connectClients = ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv.left', '在线', ui.window, ui.click.connectClients); - ui.connectClientsCount = ui.create.div('.forceopaque.menubutton.icon.connectevents.highlight.left', '1', ui.window); - ui.createRoomButton = ui.create.div('.forceopaque.menubutton.large.connectevents.pointerdiv.left2', '创建房间', ui.window, function () { - if (!_status.creatingroom) { - _status.creatingroom = true; - ui.click.connectMenu(); + ui.connectEvents = ui.create.div( + ".forceopaque.menubutton.large.connectevents.pointerdiv", + "约战", + ui.window, + ui.click.connectEvents + ); + ui.connectEventsCount = ui.create.div( + ".forceopaque.menubutton.icon.connectevents.highlight.hidden", + "", + ui.window + ); + ui.connectClients = ui.create.div( + ".forceopaque.menubutton.large.connectevents.pointerdiv.left", + "在线", + ui.window, + ui.click.connectClients + ); + ui.connectClientsCount = ui.create.div( + ".forceopaque.menubutton.icon.connectevents.highlight.left", + "1", + ui.window + ); + ui.createRoomButton = ui.create.div( + ".forceopaque.menubutton.large.connectevents.pointerdiv.left2", + "创建房间", + ui.window, + function () { + if (!_status.creatingroom) { + _status.creatingroom = true; + ui.click.connectMenu(); + } } - }); + ); if (events.length) { ui.connectEventsCount.innerHTML = events.filter(function (evt) { return evt.creator == game.onlineKey || !get.is.banWords(evt.content); @@ -12040,20 +13197,23 @@ export class Library extends Uninstantable { game.wsid = wsid; lib.message.client.updaterooms(list, clients); lib.message.client.updateevents(events); - ui.exitroom = ui.create.system('退出房间', function () { - game.saveConfig('tmp_owner_roomId'); - game.saveConfig('tmp_user_roomId'); - if (ui.rooms) { - game.saveConfig('reconnect_info'); - } - else { - if (lib.config.reconnect_info) { - lib.config.reconnect_info.length = 1; - game.saveConfig('reconnect_info', lib.config.reconnect_info); + ui.exitroom = ui.create.system( + "退出房间", + function () { + game.saveConfig("tmp_owner_roomId"); + game.saveConfig("tmp_user_roomId"); + if (ui.rooms) { + game.saveConfig("reconnect_info"); + } else { + if (lib.config.reconnect_info) { + lib.config.reconnect_info.length = 1; + game.saveConfig("reconnect_info", lib.config.reconnect_info); + } } - } - game.reload(); - }, true); + game.reload(); + }, + true + ); var findRoom = function (id) { for (var room of ui.rooms) { @@ -12061,19 +13221,18 @@ export class Library extends Uninstantable { } return false; }; - if (typeof lib.config.tmp_owner_roomId == 'string') { - if (typeof game.roomId != 'string' && !findRoom(lib.config.tmp_owner_roomId)) { + if (typeof lib.config.tmp_owner_roomId == "string") { + if (typeof game.roomId != "string" && !findRoom(lib.config.tmp_owner_roomId)) { lib.configOL.mode = lib.config.connect_mode; game.roomId = lib.config.tmp_owner_roomId; } - game.saveConfig('tmp_owner_roomId'); + game.saveConfig("tmp_owner_roomId"); } - if (typeof lib.config.tmp_user_roomId == 'string') { - if (typeof game.roomId != 'string') { + if (typeof lib.config.tmp_user_roomId == "string") { + if (typeof game.roomId != "string") { if (findRoom(lib.config.tmp_user_roomId)) { game.roomId = lib.config.tmp_user_roomId; - } - else { + } else { ui.create.connecting(); (function () { var n = 10; @@ -12083,25 +13242,30 @@ export class Library extends Uninstantable { n--; if (findRoom(id)) { clearInterval(interval); - game.send('server', 'enter', id, get.connectNickname(), lib.config.connect_avatar); + game.send( + "server", + "enter", + id, + get.connectNickname(), + lib.config.connect_avatar + ); } - } - else { + } else { ui.create.connecting(true); clearInterval(interval); } }, 500); - }()); + })(); } } - game.saveConfig('tmp_user_roomId'); + game.saveConfig("tmp_user_roomId"); } if (window.isNonameServer) { - var cfg = 'pagecfg' + window.isNonameServer; + var cfg = "pagecfg" + window.isNonameServer; if (lib.config[cfg]) { lib.configOL = lib.config[cfg][0]; - game.send('server', 'server', lib.config[cfg].slice(1)); + game.send("server", "server", lib.config[cfg].slice(1)); game.saveConfig(cfg); _status.protectingroom = true; setTimeout(function () { @@ -12110,72 +13274,85 @@ export class Library extends Uninstantable { game.reload(); } }, 15000); + } else { + game.send("server", "server"); } - else { - game.send('server', 'server'); - } - } - else if (typeof game.roomId == 'string') { + } else if (typeof game.roomId == "string") { var room = findRoom(game.roomId); if (game.roomIdServer && room && (room.serving || !room.version)) { console.log(); if (lib.config.reconnect_info) { lib.config.reconnect_info[2] = null; - game.saveConfig('reconnect_info', lib.config.reconnect_info); + game.saveConfig("reconnect_info", lib.config.reconnect_info); } - } - else { + } else { ui.create.connecting(); - game.send('server', (game.roomId == game.onlineKey) ? 'create' : 'enter', game.roomId, get.connectNickname(), lib.config.connect_avatar); + game.send( + "server", + game.roomId == game.onlineKey ? "create" : "enter", + game.roomId, + get.connectNickname(), + lib.config.connect_avatar + ); } } lib.init.onfree(); }; if (_status.event.parent) { - game.forceOver('noover', proceed); - } - else { + game.forceOver("noover", proceed); + } else { proceed(); } }, updaterooms: function (list, clients) { if (ui.rooms) { - var map = {}, map2 = {}; + var map = {}, + map2 = {}; for (var i of ui.rooms) map2[i.key] = true; for (var i of list) { if (!i) continue; map[i[4]] = i; } - ui.window.classList.add('more_room'); + ui.window.classList.add("more_room"); for (var i = 0; i < ui.rooms.length; i++) { if (!map[ui.rooms[i].key]) { ui.rooms[i].remove(); ui.rooms.splice(i--, 1); - } - else ui.rooms[i].initRoom(list[i]); + } else ui.rooms[i].initRoom(list[i]); } for (var i of list) { if (!i) continue; map[i[4]] = i; if (!map2[i[4]]) { - var player = ui.roombase.add(''); + var player = ui.roombase.add( + '' + ); player.roomindex = i; player.initRoom = lib.element.Player.prototype.initRoom; - player.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.connectroom); + player.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + ui.click.connectroom + ); player.initRoom(i); ui.rooms.push(player); } } - if (!_status.requestReadClipboard && get.config('read_clipboard', 'connect')) { - const read = text => { + if (!_status.requestReadClipboard && get.config("read_clipboard", "connect")) { + const read = (text) => { try { - var roomId = text.split('\n')[1].match(/\d+/); - var caption = ui.rooms.find(caption => caption.key == roomId); - if (caption && (_status.read_clipboard_text || confirm(`是否通过复制的内容加入${roomId}房间?`))) { + var roomId = text.split("\n")[1].match(/\d+/); + var caption = ui.rooms.find((caption) => caption.key == roomId); + if ( + caption && + (_status.read_clipboard_text || + confirm(`是否通过复制的内容加入${roomId}房间?`)) + ) { ui.click.connectroom.call(caption); delete _status.read_clipboard_text; } - } catch (e) { console.log(e); } + } catch (e) { + console.log(e); + } }; //每次启动只请求一次 _status.requestReadClipboard = true; @@ -12184,17 +13361,20 @@ export class Library extends Uninstantable { } else { window.focus(); if (navigator.clipboard && lib.node) { - navigator.clipboard.readText().then(read).catch(_ => { }); + navigator.clipboard + .readText() + .then(read) + .catch((_) => {}); } else { - var input = ui.create.node('textarea', ui.window, { opacity: '0' }); + var input = ui.create.node("textarea", ui.window, { opacity: "0" }); input.select(); - var result = document.execCommand('paste'); + var result = document.execCommand("paste"); input.blur(); ui.window.removeChild(input); if (result || input.value.length > 0) read(input.value); - else if (confirm('是否输入邀请链接以加入房间?')) { - var text = prompt('请输入邀请链接'); - if (typeof text == 'string' && text.length > 0) read(text); + else if (confirm("是否输入邀请链接以加入房间?")) { + var text = prompt("请输入邀请链接"); + if (typeof text == "string" && text.length > 0) read(text); } } } @@ -12215,13 +13395,15 @@ export class Library extends Uninstantable { if (events && ui.connectEvents) { ui.connectEvents.info = events; var num = events.filter(function (evt) { - return typeof evt.creator == 'string' && (evt.creator == game.onlineKey || !get.is.banWords(evt.content)); + return ( + typeof evt.creator == "string" && + (evt.creator == game.onlineKey || !get.is.banWords(evt.content)) + ); }).length; if (num) { ui.connectEventsCount.innerHTML = num; ui.connectEventsCount.show(); - } - else { + } else { ui.connectEventsCount.hide(); } if (_status.connectEventsCallback) { @@ -12230,15 +13412,13 @@ export class Library extends Uninstantable { } }, eventsdenied: function (reason) { - var str = '创建约战失败'; - if (reason == 'total') { - str += ',约战总数不能超过20'; - } - else if (reason == 'time') { - str += ',时间已过'; - } - else if (reason == 'ban') { - str += ',请注意文明发言'; + var str = "创建约战失败"; + if (reason == "total") { + str += ",约战总数不能超过20"; + } else if (reason == "time") { + str += ",时间已过"; + } else if (reason == "ban") { + str += ",请注意文明发言"; } alert(str); }, @@ -12249,16 +13429,15 @@ export class Library extends Uninstantable { game.servermode = servermode; game.roomId = roomId; if (game.servermode) { - game.saveConfig('reconnect_info', [_status.ip, id, game.roomId]); - } - else { - game.saveConfig('reconnect_info', [_status.ip, id]); - game.saveConfig('tmp_user_roomId', roomId); + game.saveConfig("reconnect_info", [_status.ip, id, game.roomId]); + } else { + game.saveConfig("reconnect_info", [_status.ip, id]); + game.saveConfig("tmp_user_roomId", roomId); } lib.config.recentIP.remove(_status.ip); lib.config.recentIP.unshift(_status.ip); lib.config.recentIP.splice(5); - game.saveConfig('recentIP', lib.config.recentIP); + game.saveConfig("recentIP", lib.config.recentIP); _status.connectMode = true; lib.configOL = config; lib.playerOL = {}; @@ -12270,8 +13449,7 @@ export class Library extends Uninstantable { ui.create.chat(); if (game.servermode) { ui.create.connectPlayers(get.modetrans(config, true)); - } - else { + } else { ui.create.connectPlayers(ip); } ui.pause.hide(); @@ -12282,24 +13460,22 @@ export class Library extends Uninstantable { var proceed = function () { game.loadModeAsync(config.mode, function (mode) { for (var i in mode.ai) { - if (typeof mode.ai[i] == 'object') { + if (typeof mode.ai[i] == "object") { if (ai[i] == undefined) ai[i] = {}; for (var j in mode.ai[i]) { ai[i][j] = mode.ai[i][j]; } - } - else { + } else { ai[i] = mode.ai[i]; } } for (var i in mode.get) { - if (typeof mode.get[i] == 'object') { + if (typeof mode.get[i] == "object") { if (get[i] == undefined) get[i] = {}; for (var j in mode.get[i]) { get[i][j] = mode.get[i][j]; } - } - else { + } else { get[i] = mode.get[i]; } } @@ -12312,7 +13488,10 @@ export class Library extends Uninstantable { game.getRoomInfo = mode.game.getRoomInfo; } if (mode.element && mode.element.player) { - Object.defineProperties(lib.element.Player.prototype, Object.getOwnPropertyDescriptors(mode.element.player)); + Object.defineProperties( + lib.element.Player.prototype, + Object.getOwnPropertyDescriptors(mode.element.player) + ); } if (mode.skill) { for (var i in mode.skill) { @@ -12332,16 +13511,15 @@ export class Library extends Uninstantable { } _status.event = lib.element.GameEvent.initialGameEvent(); _status.paused = false; - game.createEvent('game', false).setContent(lib.init.startOnline); + game.createEvent("game", false).setContent(lib.init.startOnline); game.loop(); - game.send('inited'); + game.send("inited"); ui.create.connecting(true); }); }; if (_status.event.parent) { - game.forceOver('noover', proceed); - } - else { + game.forceOver("noover", proceed); + } else { proceed(); } for (var i in lib.characterPack) { @@ -12368,12 +13546,11 @@ export class Library extends Uninstantable { game.roomId = null; } if (game.servermode && !observe) { - game.saveConfig('reconnect_info', [_status.ip, game.onlineID, game.roomId]); - } - else { - game.saveConfig('reconnect_info', [_status.ip, game.onlineID]); + game.saveConfig("reconnect_info", [_status.ip, game.onlineID, game.roomId]); + } else { + game.saveConfig("reconnect_info", [_status.ip, game.onlineID]); if (!observe) { - game.saveConfig('tmp_user_roomId', game.roomId); + game.saveConfig("tmp_user_roomId", game.roomId); } } _status.connectMode = true; @@ -12383,24 +13560,22 @@ export class Library extends Uninstantable { game.loadModeAsync(config.mode, function (mode) { for (var i in mode.ai) { - if (typeof mode.ai[i] == 'object') { + if (typeof mode.ai[i] == "object") { if (ai[i] == undefined) ai[i] = {}; for (var j in mode.ai[i]) { ai[i][j] = mode.ai[i][j]; } - } - else { + } else { ai[i] = mode.ai[i]; } } for (var i in mode.get) { - if (typeof mode.get[i] == 'object') { + if (typeof mode.get[i] == "object") { if (get[i] == undefined) get[i] = {}; for (var j in mode.get[i]) { get[i][j] = mode.get[i][j]; } - } - else { + } else { get[i] = mode.get[i]; } } @@ -12414,7 +13589,10 @@ export class Library extends Uninstantable { game.showIdentity = mode.game.showIdentity; } if (mode.element && mode.element.player) { - Object.defineProperties(lib.element.Player.prototype, Object.getOwnPropertyDescriptors(mode.element.player)); + Object.defineProperties( + lib.element.Player.prototype, + Object.getOwnPropertyDescriptors(mode.element.player) + ); } if (mode.skill) { for (var i in mode.skill) { @@ -12451,16 +13629,19 @@ export class Library extends Uninstantable { ui.exitroom.remove(); delete ui.exitroom; } - } - else { + } else { if (!ui.exitroom) { - ui.create.system('退出旁观', function () { - game.saveConfig('reconnect_info'); - game.reload(); - }, true); + ui.create.system( + "退出旁观", + function () { + game.saveConfig("reconnect_info"); + game.reload(); + }, + true + ); } if (!lib.configOL.observe_handcard) { - ui.arena.classList.add('observe'); + ui.arena.classList.add("observe"); } } postReconnect = get.parsedResult(postReconnect); @@ -12478,27 +13659,29 @@ export class Library extends Uninstantable { var pos = state.players[observe || game.onlineID].position; for (var i in state.players) { var info = state.players[i]; - var player = ui.create.player(ui.arena).addTempClass('start'); - player.dataset.position = (info.position < pos) ? info.position - pos + parseInt(state.number) : info.position - pos; + var player = ui.create.player(ui.arena).addTempClass("start"); + player.dataset.position = + info.position < pos + ? info.position - pos + parseInt(state.number) + : info.position - pos; if (i == observe || i == game.onlineID) { game.me = player; } if (player.setModeState) { player.setModeState(info); - } - else { + } else { player.init(info.name1, info.name2); if (info.name && info.name != info.name1) player.name = info.name; } - if (!info.unseen) player.classList.remove('unseen'); - if (!info.unseen2) player.classList.remove('unseen2'); + if (!info.unseen) player.classList.remove("unseen"); + if (!info.unseen2) player.classList.remove("unseen2"); if (!player.isUnseen(2) && player.storage.nohp) { delete player.storage.nohp; player.node.hp.show(); } player.playerid = i; player.nickname = info.nickname; - player.changeGroup(info.group, false, 'nobroadcast'); + player.changeGroup(info.group, false, "nobroadcast"); player.identity = info.identity; player.identityShown = info.identityShown; player.hp = info.hp; @@ -12512,7 +13695,7 @@ export class Library extends Uninstantable { player.expandedSlots = info.expandedSlots; player.setNickname(); if (info.dead) { - player.classList.add('dead'); + player.classList.add("dead"); if (lib.config.die_move) { player.$dieflip(); } @@ -12520,18 +13703,17 @@ export class Library extends Uninstantable { player.$dieAfter(); } game.dead.push(player); - } - else { + } else { game.players.push(player); } if (info.linked) { player.addLink(); } if (info.turnedover) { - player.classList.add('turnedover'); + player.classList.add("turnedover"); } if (info.out) { - player.classList.add('out'); + player.classList.add("out"); } if (info.disableJudge) { player.$disableJudge(); @@ -12547,7 +13729,7 @@ export class Library extends Uninstantable { info.handcards[i].addGaintag(info.gaintag[i]); } for (var i = 0; i < info.specials.length; i++) { - info.specials[i].classList.add('glows'); + info.specials[i].classList.add("glows"); } if (info.expansions.length) { var expansion_gaintag = []; @@ -12560,9 +13742,10 @@ export class Library extends Uninstantable { } for (var i = 0; i < info.judges.length; i++) { if (info.views[i] && info.views[i] != info.judges[i]) { - info.judges[i].classList.add('fakejudge'); + info.judges[i].classList.add("fakejudge"); info.judges[i].viewAs = info.views[i]; - info.judges[i].node.background.innerHTML = lib.translate[info.views[i] + '_bg'] || get.translation(info.views[i])[0]; + info.judges[i].node.background.innerHTML = + lib.translate[info.views[i] + "_bg"] || get.translation(info.views[i])[0]; } player.node.judges.appendChild(info.judges[i]); } @@ -12571,17 +13754,18 @@ export class Library extends Uninstantable { if (!game.getIdentityList && info.identityNode) { player.node.identity.innerHTML = info.identityNode[0]; player.node.identity.dataset.color = info.identityNode[1]; - } - else if (player == game.me || player.identityShown || observe) { + } else if (player == game.me || player.identityShown || observe) { player.setIdentity(); player.forceShown = true; + } else { + player.setIdentity("cai"); } - else { - player.setIdentity('cai'); - } - if (!lib.configOL.observe_handcard && (lib.configOL.mode == 'identity' || lib.configOL.mode == 'guozhan')) { + if ( + !lib.configOL.observe_handcard && + (lib.configOL.mode == "identity" || lib.configOL.mode == "guozhan") + ) { if (observe && !player.identityShown) { - player.setIdentity('cai'); + player.setIdentity("cai"); player.forceShown = false; } } @@ -12598,36 +13782,35 @@ export class Library extends Uninstantable { if (game.updateState) { game.updateState(state2); } - var next = game.createEvent('game', false); + var next = game.createEvent("game", false); next.setContent(lib.init.startOnline); if (observe) { next.custom.replace.target = function (player) { - if (!lib.configOL.observe_handcard && lib.configOL.mode == 'guozhan') { + if (!lib.configOL.observe_handcard && lib.configOL.mode == "guozhan") { return; } if (player.isAlive()) { - if (!game.me.identityShown && lib.configOL.mode == 'guozhan') { - game.me.node.identity.firstChild.innerHTML = '猜'; - game.me.node.identity.dataset.color = 'unknown'; + if (!game.me.identityShown && lib.configOL.mode == "guozhan") { + game.me.node.identity.firstChild.innerHTML = "猜"; + game.me.node.identity.dataset.color = "unknown"; } game.swapPlayer(player); - if (!game.me.identityShown && lib.configOL.mode == 'guozhan') { - game.me.node.identity.firstChild.innerHTML = ''; + if (!game.me.identityShown && lib.configOL.mode == "guozhan") { + game.me.node.identity.firstChild.innerHTML = ""; } } }; - } - else { + } else { if (Array.isArray(onreconnect)) { onreconnect.shift().apply(this, onreconnect); } } game.loop(); - game.send('reinited'); + game.send("reinited"); game.showHistory(); _status.gameStarted = true; if (lib.config.show_cardpile) { - ui.cardPileButton.style.display = ''; + ui.cardPileButton.style.display = ""; } if (!observe && game.me && (game.me.isDead() || _status.over)) { ui.create.exit(); @@ -12638,35 +13821,41 @@ export class Library extends Uninstantable { }, exec: function (func) { var key = game.onlineKey; - if (typeof func == 'function') { + if (typeof func == "function") { var args = Array.from(arguments); args.shift(); func.apply(this, args); } if (key) { game.onlineKey = key; - localStorage.setItem(lib.configprefix + 'key', game.onlineKey); + localStorage.setItem(lib.configprefix + "key", game.onlineKey); } }, denied: function (reason) { switch (reason) { - case 'version': - alert('加入失败:版本不匹配,请将游戏更新至最新版'); - game.saveConfig('tmp_owner_roomId'); - game.saveConfig('tmp_user_roomId'); - game.saveConfig('reconnect_info'); + case "version": + alert("加入失败:版本不匹配,请将游戏更新至最新版"); + game.saveConfig("tmp_owner_roomId"); + game.saveConfig("tmp_user_roomId"); + game.saveConfig("reconnect_info"); break; - case 'gaming': alert('加入失败:游戏已开始'); break; - case 'number': alert('加入失败:房间已满'); break; - case 'banned': alert('加入失败:房间拒绝你加入'); break; - case 'key': - alert('您的游戏版本过低,请升级到最新版'); - game.saveConfig('tmp_owner_roomId'); - game.saveConfig('tmp_user_roomId'); - game.saveConfig('reconnect_info'); + case "gaming": + alert("加入失败:游戏已开始"); break; - case 'offline': - if (_status.paused && _status.event.name == 'game') { + case "number": + alert("加入失败:房间已满"); + break; + case "banned": + alert("加入失败:房间拒绝你加入"); + break; + case "key": + alert("您的游戏版本过低,请升级到最新版"); + game.saveConfig("tmp_owner_roomId"); + game.saveConfig("tmp_user_roomId"); + game.saveConfig("reconnect_info"); + break; + case "offline": + if (_status.paused && _status.event.name == "game") { setTimeout(game.resume, 500); } break; @@ -12730,7 +13919,7 @@ export class Library extends Uninstantable { ui.auto.show(); ui.pause.show(); if (lib.config.show_cardpile) { - ui.cardPileButton.style.display = ''; + ui.cardPileButton.style.display = ""; } _status.gameStarted = true; game.showHistory(); @@ -12738,67 +13927,64 @@ export class Library extends Uninstantable { updateWaiting: function (map) { if (!game.connectPlayers) return; if (!lib.translate.zhu) { - lib.translate.zhu = '主'; + lib.translate.zhu = "主"; } game.onlinezhu = false; _status.waitingForPlayer = true; for (var i = 0; i < map.length; i++) { - if (map[i] == 'disabled') { - game.connectPlayers[i].classList.add('unselectable2'); - } - else { - game.connectPlayers[i].classList.remove('unselectable2'); + if (map[i] == "disabled") { + game.connectPlayers[i].classList.add("unselectable2"); + } else { + game.connectPlayers[i].classList.remove("unselectable2"); if (map[i]) { game.connectPlayers[i].initOL(map[i][0], map[i][1]); game.connectPlayers[i].playerid = map[i][2]; - if (map[i][3] == 'zhu') { - game.connectPlayers[i].setIdentity('zhu'); + if (map[i][3] == "zhu") { + game.connectPlayers[i].setIdentity("zhu"); if (map[i][2] == game.onlineID) { game.onlinezhu = true; if (ui.roomInfo) { - ui.roomInfo.innerHTML = '房间设置'; + ui.roomInfo.innerHTML = "房间设置"; } if (ui.connectStartButton) { - ui.connectStartButton.innerHTML = '开始游戏'; + ui.connectStartButton.innerHTML = "开始游戏"; } } + } else { + game.connectPlayers[i].node.identity.firstChild.innerHTML = ""; } - else { - game.connectPlayers[i].node.identity.firstChild.innerHTML = ''; - } - } - else { + } else { game.connectPlayers[i].uninitOL(); delete game.connectPlayers[i].playerid; } } } - } - } + }, + }, }; - static suit = ['club', 'spade', 'diamond', 'heart']; - static suits = ['club', 'spade', 'diamond', 'heart', 'none']; - static color = { - black: ['club', 'spade'], - red: ['diamond', 'heart'], - none: ['none'], + suit = ["club", "spade", "diamond", "heart"]; + suits = ["club", "spade", "diamond", "heart", "none"]; + color = { + black: ["club", "spade"], + red: ["diamond", "heart"], + none: ["none"], }; - static group = ['wei', 'shu', 'wu', 'qun', 'jin', 'shen']; + group = ["wei", "shu", "wu", "qun", "jin", "shen"]; //数值代表各元素在名称中排列的先后顺序 - static nature = new Map([ - ['fire', 20], - ['thunder', 30], - ['kami', 60], - ['ice', 40], - ['stab', 10], - ['poison', 50] + nature = new Map([ + ["fire", 20], + ["thunder", 30], + ["kami", 60], + ["ice", 40], + ["stab", 10], + ["poison", 50], ]); - static natureAudio = { + natureAudio = { damage: { - 'fire': 'default',//默认,即语音放置在audio/effect下,以damage_fire.mp3 damage_fire2.mp3命名。 - 'thunder': 'default', - 'ice': 'default', - 'stab': 'normal',//正常,即与普通伤害音效相同。 + fire: "default", //默认,即语音放置在audio/effect下,以damage_fire.mp3 damage_fire2.mp3命名。 + thunder: "default", + ice: "default", + stab: "normal", //正常,即与普通伤害音效相同。 /* 'example':{ 1:'../extension/XXX/damage_example.mp3',//1点伤害。 @@ -12807,9 +13993,9 @@ export class Library extends Uninstantable { */ }, hujia_damage: { - 'fire': 'default',//默认,即语音放置在audio/effect下,以hujia_damage_fire.mp3 hujia_damage_fire2.mp3命名。 - 'thunder': 'default', - 'ice': 'normal',//正常,即与普通伤害音效相同。 + fire: "default", //默认,即语音放置在audio/effect下,以hujia_damage_fire.mp3 hujia_damage_fire2.mp3命名。 + thunder: "default", + ice: "normal", //正常,即与普通伤害音效相同。 /* 'example':{ 1:'../extension/XXX/damage_example.mp3',//1点伤害。 @@ -12818,381 +14004,559 @@ export class Library extends Uninstantable { */ }, sha: { - 'fire': 'default',//默认,即语音放置在audio/card/male与audio/card/female下,命名为sha_fire.mp3 - 'thunder': 'default', - 'ice': 'default', - 'stab': 'default', - 'poison': 'normal',//正常,即播放“杀”的音效。 - 'kami': 'normal', + 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' } */ - } + }, }; - static linked = ['fire', 'thunder', 'kami', 'ice']; - static natureBg = new Map([ - ['stab', 'image/card/cisha.png'] - ]); - static natureSeparator = '|'; - static namePrefix = new Map([ - ['界', { - color: '#fdd559', - nature: 'soilmm', - }], - ['谋', { - color: '#def7ca', - nature: 'woodmm', - }], - ['武', { - color: '#fd8359', - nature: 'soilmm', - }], - ['乐', { - color: '#f7f4fc', - nature: 'keymm', - }], - ['神', { - color: '#faecd1', - nature: 'orangemm', - }], - ['族', { - color: '#ee9ac7', - nature: 'firemm', - }], - ['晋', { - color: '#f3c5ff', - nature: 'blackmm', - }], - ['侠', { - color: '#eeeeee', - nature: 'qunmm', - }], - ['起', { - color: '#c3f9ff', - nature: 'thundermm', - }], - ['承', { - color: '#c3f9ff', - nature: 'thundermm', - }], - ['转', { - color: '#c3f9ff', - nature: 'thundermm', - }], - ['合', { - color: '#c3f9ff', - nature: 'thundermm', - }], - ['梦', { - color: '#6affe2', - nature: 'watermm', - }], - ['用间', { - color: '#c3f9ff', - nature: 'thundermm', - }], - ['战役篇', { - color: '#c3f9ff', - nature: 'thundermm', - showName: '战', - }], - ['武将传', { - color: '#c3f9ff', - nature: 'thundermm', - showName: '传', - }], - ['将', { - nature: 'firemm', - }], - ['新杀', { - color: '#fefedc', - nature: 'metalmm', - showName: '新', - }], - ['旧', { - color: '#a4a4a4', - nature: 'black', - }], - ['旧界', { - color: '#a4a4a4', - nature: 'black', - }], - ['节钺', { - color: '#a4a4a4', - nature: 'black', - }], - ['毅重', { - color: '#a4a4a4', - nature: 'black', - }], - ['★SP', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('SP')}` - }], - ['☆SP', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('SP')}` - }], - ['J.SP', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('SP')}` - }], - ['K系列', { - showName: 'K', - }], - ['经典', { - showName: '典', - }], - ['君', { - color: '#fefedc', - nature: 'shenmm', - }], - ['骰子', { - getSpan: () => { - const span = document.createElement('span'); - span.style.fontFamily = 'NonameSuits'; - span.textContent = '🎲'; - return span.outerHTML; - } - }], - ['SP', { - getSpan: () => { - const span = document.createElement('span'), style = span.style; - style.writingMode = style.webkitWritingMode = 'horizontal-tb'; - style.fontFamily = 'MotoyaLMaru'; - style.transform = 'scaleY(0.85)'; - span.textContent = 'SP'; - return span.outerHTML; + linked = ["fire", "thunder", "kami", "ice"]; + natureBg = new Map([["stab", "image/card/cisha.png"]]); + natureSeparator = "|"; + namePrefix = new Map([ + [ + "界", + { + color: "#fdd559", + nature: "soilmm", }, - }], - ['OL', { - getSpan: () => { - const span = document.createElement('span'), style = span.style; - style.writingMode = style.webkitWritingMode = 'horizontal-tb'; - style.fontFamily = 'MotoyaLMaru'; - style.transform = 'scaleY(0.85)'; - span.textContent = 'OL'; - return span.outerHTML; + ], + [ + "谋", + { + color: "#def7ca", + nature: "woodmm", }, - }], - ['RE', { - getSpan: () => { - const span = document.createElement('span'), style = span.style; - style.writingMode = style.webkitWritingMode = 'horizontal-tb'; - style.fontFamily = 'MotoyaLMaru'; - style.transform = 'scaleY(0.85)'; - span.textContent = 'RE'; - return span.outerHTML; + ], + [ + "武", + { + color: "#fd8359", + nature: "soilmm", }, - }], - ['手杀', { - getSpan: (prefix, name) => { - const simple = lib.config.buttoncharacter_prefix == 'simple', span = document.createElement('span'); - if (lib.characterPack.shiji && name in lib.characterPack.shiji) { - for (const entry of Object.entries(lib.characterSort.shiji)) { - if (!entry[1].includes(name)) continue; - prefix = get.translation(entry[0]).slice(-1); - break; + ], + [ + "乐", + { + color: "#f7f4fc", + nature: "keymm", + }, + ], + [ + "神", + { + color: "#faecd1", + nature: "orangemm", + }, + ], + [ + "族", + { + color: "#ee9ac7", + nature: "firemm", + }, + ], + [ + "晋", + { + color: "#f3c5ff", + nature: "blackmm", + }, + ], + [ + "侠", + { + color: "#eeeeee", + nature: "qunmm", + }, + ], + [ + "起", + { + color: "#c3f9ff", + nature: "thundermm", + }, + ], + [ + "承", + { + color: "#c3f9ff", + nature: "thundermm", + }, + ], + [ + "转", + { + color: "#c3f9ff", + nature: "thundermm", + }, + ], + [ + "合", + { + color: "#c3f9ff", + nature: "thundermm", + }, + ], + [ + "梦", + { + color: "#6affe2", + nature: "watermm", + }, + ], + [ + "用间", + { + color: "#c3f9ff", + nature: "thundermm", + }, + ], + [ + "战役篇", + { + color: "#c3f9ff", + nature: "thundermm", + showName: "战", + }, + ], + [ + "武将传", + { + color: "#c3f9ff", + nature: "thundermm", + showName: "传", + }, + ], + [ + "将", + { + nature: "firemm", + }, + ], + [ + "新杀", + { + color: "#fefedc", + nature: "metalmm", + showName: "新", + }, + ], + [ + "旧", + { + color: "#a4a4a4", + nature: "black", + }, + ], + [ + "旧界", + { + color: "#a4a4a4", + nature: "black", + }, + ], + [ + "节钺", + { + color: "#a4a4a4", + nature: "black", + }, + ], + [ + "毅重", + { + color: "#a4a4a4", + nature: "black", + }, + ], + [ + "★SP", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("SP")}`, + }, + ], + [ + "☆SP", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("SP")}`, + }, + ], + [ + "J.SP", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("SP")}`, + }, + ], + [ + "K系列", + { + showName: "K", + }, + ], + [ + "经典", + { + showName: "典", + }, + ], + [ + "君", + { + color: "#fefedc", + nature: "shenmm", + }, + ], + [ + "骰子", + { + getSpan: () => { + const span = document.createElement("span"); + span.style.fontFamily = "NonameSuits"; + span.textContent = "🎲"; + return span.outerHTML; + }, + }, + ], + [ + "SP", + { + getSpan: () => { + const span = document.createElement("span"), + style = span.style; + style.writingMode = style.webkitWritingMode = "horizontal-tb"; + style.fontFamily = "MotoyaLMaru"; + style.transform = "scaleY(0.85)"; + span.textContent = "SP"; + return span.outerHTML; + }, + }, + ], + [ + "OL", + { + getSpan: () => { + const span = document.createElement("span"), + style = span.style; + style.writingMode = style.webkitWritingMode = "horizontal-tb"; + style.fontFamily = "MotoyaLMaru"; + style.transform = "scaleY(0.85)"; + span.textContent = "OL"; + return span.outerHTML; + }, + }, + ], + [ + "RE", + { + getSpan: () => { + const span = document.createElement("span"), + style = span.style; + style.writingMode = style.webkitWritingMode = "horizontal-tb"; + style.fontFamily = "MotoyaLMaru"; + style.transform = "scaleY(0.85)"; + span.textContent = "RE"; + return span.outerHTML; + }, + }, + ], + [ + "手杀", + { + getSpan: (prefix, name) => { + const simple = lib.config.buttoncharacter_prefix == "simple", + span = document.createElement("span"); + if (lib.characterPack.shiji && name in lib.characterPack.shiji) { + for (const entry of Object.entries(lib.characterSort.shiji)) { + if (!entry[1].includes(name)) continue; + prefix = get.translation(entry[0]).slice(-1); + break; + } + if (!simple) { + span.style.color = "#def7ca"; + span.dataset.nature = "watermm"; + } + span.innerHTML = prefix; + } else if (simple) span.textContent = "手杀"; + else { + span.style.fontFamily = "NonameSuits"; + span.textContent = "📱"; } - if (!simple) { - span.style.color = '#def7ca'; - span.dataset.nature = 'watermm'; - } - span.innerHTML = prefix; - } - else if (simple) span.textContent = '手杀'; - else { - span.style.fontFamily = 'NonameSuits'; - span.textContent = '📱'; - } - return span.outerHTML; + return span.outerHTML; + }, }, - }], - ['TW', { - getSpan: () => { - const span = document.createElement('span'), style = span.style; - style.writingMode = style.webkitWritingMode = 'horizontal-tb'; - style.fontFamily = 'MotoyaLMaru'; - style.transform = 'scaleY(0.85)'; - span.textContent = 'TW'; - return span.outerHTML; + ], + [ + "TW", + { + getSpan: () => { + const span = document.createElement("span"), + style = span.style; + style.writingMode = style.webkitWritingMode = "horizontal-tb"; + style.fontFamily = "MotoyaLMaru"; + style.transform = "scaleY(0.85)"; + span.textContent = "TW"; + return span.outerHTML; + }, }, - }], - ['TW神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('TW')}${get.prefixSpan('神')}` - }], - ['TW将', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('TW')}${get.prefixSpan('将')}` - }], - ['OL神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('OL')}${get.prefixSpan('神')}` - }], - ['旧神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('旧')}${get.prefixSpan('神')}` - }], - ['旧晋', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('旧')}${get.prefixSpan('晋')}` - }], - ['新杀SP', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('新杀')}${get.prefixSpan('SP')}` - }], - ['界SP', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('界')}${get.prefixSpan('SP')}` - }], - ['S特神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('★')}${get.prefixSpan('神')}` - }], - ['手杀界', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('手杀')}${get.prefixSpan('界')}` - }], - ['战役篇神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('战役篇')}${get.prefixSpan('神')}` - }], - ['星', { - color: '#ffd700', - nature: 'glodenmm', - }], - ['OL界', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('OL')}${get.prefixSpan('界')}` - }], - ['OL谋', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('OL')}${get.prefixSpan('谋')}` - }], - ['新杀谋', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('新杀')}${get.prefixSpan('谋')}` - }], - ['经典神', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('经典')}${get.prefixSpan('神')}` - }], - ['旧谋', { - /** - * @returns {string} - */ - getSpan: () => `${get.prefixSpan('旧')}${get.prefixSpan('谋')}` - }] + ], + [ + "TW神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("TW")}${get.prefixSpan("神")}`, + }, + ], + [ + "TW将", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("TW")}${get.prefixSpan("将")}`, + }, + ], + [ + "OL神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("OL")}${get.prefixSpan("神")}`, + }, + ], + [ + "旧神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("旧")}${get.prefixSpan("神")}`, + }, + ], + [ + "旧晋", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("旧")}${get.prefixSpan("晋")}`, + }, + ], + [ + "新杀SP", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("新杀")}${get.prefixSpan("SP")}`, + }, + ], + [ + "界SP", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("界")}${get.prefixSpan("SP")}`, + }, + ], + [ + "S特神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("★")}${get.prefixSpan("神")}`, + }, + ], + [ + "手杀界", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("手杀")}${get.prefixSpan("界")}`, + }, + ], + [ + "战役篇神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("战役篇")}${get.prefixSpan("神")}`, + }, + ], + [ + "星", + { + color: "#ffd700", + nature: "glodenmm", + }, + ], + [ + "OL界", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("OL")}${get.prefixSpan("界")}`, + }, + ], + [ + "OL谋", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("OL")}${get.prefixSpan("谋")}`, + }, + ], + [ + "新杀谋", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("新杀")}${get.prefixSpan("谋")}`, + }, + ], + [ + "经典神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("经典")}${get.prefixSpan("神")}`, + }, + ], + [ + "旧谋", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("旧")}${get.prefixSpan("谋")}`, + }, + ], + [ + "手杀神", + { + /** + * @returns {string} + */ + getSpan: () => `${get.prefixSpan("手杀")}${get.prefixSpan("神")}`, + }, + ], + [ + "龙", + { + color: "#ff0000", + nature: "firemm", + }, + ], ]); - static groupnature = { - shen: 'shen', - wei: 'water', - shu: 'soil', - wu: 'wood', - qun: 'qun', - western: 'thunder', - key: 'key', - jin: 'thunder', - ye: 'thunder', + groupnature = { + shen: "shen", + wei: "water", + shu: "soil", + wu: "wood", + qun: "qun", + western: "thunder", + key: "key", + jin: "thunder", + ye: "thunder", }; - static lineColor = new Map([ - ['fire', [255, 146, 68]], - ['yellow', [255, 255, 122]], - ['blue', [150, 202, 255]], - ['green', [141, 255, 216]], - ['ice', [59, 98, 115]], - ['thunder', [141, 216, 255]], - ['kami', [90, 118, 99]], - ['white', [255, 255, 255]], - ['poison', [104, 221, 127]], - ['brown', [195, 161, 223]], - ['legend', [233, 131, 255]] + lineColor = new Map([ + ["fire", [255, 146, 68]], + ["yellow", [255, 255, 122]], + ["blue", [150, 202, 255]], + ["green", [141, 255, 216]], + ["ice", [59, 98, 115]], + ["thunder", [141, 216, 255]], + ["kami", [90, 118, 99]], + ["white", [255, 255, 255]], + ["poison", [104, 221, 127]], + ["brown", [195, 161, 223]], + ["legend", [233, 131, 255]], ]); - static phaseName = ['phaseZhunbei', 'phaseJudge', 'phaseDraw', 'phaseUse', 'phaseDiscard', 'phaseJieshu']; - static quickVoice = [ - '我从未见过如此厚颜无耻之人!', - '这波不亏', - '请收下我的膝盖', - '你咋不上天呢', - '放开我的队友,冲我来', - '你随便杀,闪不了算我输', - '见证奇迹的时刻到了', - '能不能快一点啊,兵贵神速啊', - '主公,别开枪,自己人', - '小内再不跳,后面还怎么玩儿啊', - '你们忍心,就这么让我酱油了?', - '我,我惹你们了吗', - '姑娘,你真是条汉子', - '三十六计,走为上,容我去去便回', - '人心散了,队伍不好带啊', - '昏君,昏君啊!', - '风吹鸡蛋壳,牌去人安乐', - '小内啊,您老悠着点儿', - '不好意思,刚才卡了', - '你可以打得再烂一点吗', - '哥们,给力点儿行嘛', - '哥哥,交个朋友吧', - '妹子,交个朋友吧', + phaseName = ["phaseZhunbei", "phaseJudge", "phaseDraw", "phaseUse", "phaseDiscard", "phaseJieshu"]; + quickVoice = [ + "我从未见过如此厚颜无耻之人!", + "这波不亏", + "请收下我的膝盖", + "你咋不上天呢", + "放开我的队友,冲我来", + "你随便杀,闪不了算我输", + "见证奇迹的时刻到了", + "能不能快一点啊,兵贵神速啊", + "主公,别开枪,自己人", + "小内再不跳,后面还怎么玩儿啊", + "你们忍心,就这么让我酱油了?", + "我,我惹你们了吗", + "姑娘,你真是条汉子", + "三十六计,走为上,容我去去便回", + "人心散了,队伍不好带啊", + "昏君,昏君啊!", + "风吹鸡蛋壳,牌去人安乐", + "小内啊,您老悠着点儿", + "不好意思,刚才卡了", + "你可以打得再烂一点吗", + "哥们,给力点儿行嘛", + "哥哥,交个朋友吧", + "妹子,交个朋友吧", ]; - static other = { - ignore: () => void 0 + other = { + ignore: () => void 0, }; - static InitFilter = { - 'noZhuHp': '不享受主公的额外体力上限', - 'noZhuSkill': '不享受地主的额外技能', + InitFilter = { + noZhuHp: "不享受主公的额外体力上限", + noZhuSkill: "不享受地主的额外技能", }; } -Library.config = undefined; -Library.configOL = undefined; +Library.prototype.config = undefined; +Library.prototype.configOL = undefined; -export const lib = Library; +export let lib = new Library(); + +/** + * @param { InstanceType } [instance] + */ +export let setLibrary = (instance) => { + lib = instance || new Library(); + if (lib.config.dev) { + window.lib = lib; + } +}; /** * @template T * @param {T} object */ -const setAllPropertiesEnumerable = object => { - Object.getOwnPropertyNames(object).forEach(propertyKey => { - if (propertyKey == 'constructor') return; +const setAllPropertiesEnumerable = (object) => { + Object.getOwnPropertyNames(object).forEach((propertyKey) => { + if (propertyKey == "constructor") return; const propertyDescriptor = Object.getOwnPropertyDescriptor(object, propertyKey); if (!propertyDescriptor.enumerable) propertyDescriptor.enumerable = true; Object.defineProperty(object, propertyKey, propertyDescriptor); @@ -13200,8 +14564,9 @@ const setAllPropertiesEnumerable = object => { return object; }; setAllPropertiesEnumerable(lib.element.Player.prototype); -const cardPrototype = setAllPropertiesEnumerable(lib.element.Card.prototype), vCardPrototype = setAllPropertiesEnumerable(lib.element.VCard.prototype); -Object.keys(vCardPrototype).forEach(key => { +const cardPrototype = setAllPropertiesEnumerable(lib.element.Card.prototype), + vCardPrototype = setAllPropertiesEnumerable(lib.element.VCard.prototype); +Object.keys(vCardPrototype).forEach((key) => { Object.defineProperty(cardPrototype, key, Object.getOwnPropertyDescriptor(vCardPrototype, key)); }); setAllPropertiesEnumerable(lib.element.Button.prototype); diff --git a/noname/library/init/index.js b/noname/library/init/index.js index fc597e389..380e5018a 100644 --- a/noname/library/init/index.js +++ b/noname/library/init/index.js @@ -1,79 +1,78 @@ -import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../../util/index.js"; -import { AI as ai } from '../../ai/index.js' -import { Get as get } from '../../get/index.js' -import { Game, Game as game } from '../../game/index.js' -import { Library as lib } from "../index.js" -import { status as _status } from '../../status/index.js' -import { UI as ui } from '../../ui/index.js' -import { GNC as gnc } from '../../gnc/index.js' +import { GeneratorFunction } from "../../util/index.js"; +import { get } from "../../get/index.js"; +import { game } from "../../game/index.js"; +import { lib } from "../index.js"; +import { _status } from "../../status/index.js"; +import { ui } from "../../ui/index.js"; +import { gnc } from "../../gnc/index.js"; -import { LibInitPromises } from "./promises.js" -import { GameEvent } from "../element/gameEvent.js" -import { GameEventPromise } from "../element/gameEventPromise.js" +import { LibInitPromises } from "./promises.js"; +import { GameEvent } from "../element/gameEvent.js"; +import { GameEventPromise } from "../element/gameEventPromise.js"; -export class LibInit extends Uninstantable { +export class LibInit { /** * 部分函数的Promise版本 */ - static promises = LibInitPromises + promises = new LibInitPromises(); - static init() { - throw new Error('lib.init.init is moved to noname/init') + init() { + throw new Error("lib.init.init is moved to noname/init"); } - static reset() { + reset() { if (window.inSplash) return; if (window.resetExtension) { - if (confirm('游戏似乎未正常载入,有可能因为部分扩展未正常载入,或者因为部分扩展未载入完毕。\n是否禁用扩展并重新打开?')) { + if ( + confirm( + "游戏似乎未正常载入,有可能因为部分扩展未正常载入,或者因为部分扩展未载入完毕。\n是否禁用扩展并重新打开?" + ) + ) { window.resetExtension(); window.location.reload(); } - } - else { + } else { if (lib.device) { if (navigator.notification) { navigator.notification.confirm( - '游戏似乎未正常载入,是否重置游戏?', + "游戏似乎未正常载入,是否重置游戏?", function (index) { if (index == 2) { - localStorage.removeItem('noname_inited'); + localStorage.removeItem("noname_inited"); window.location.reload(); - } - else if (index == 3) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + } else if (index == 3) { + var noname_inited = localStorage.getItem("noname_inited"); + var onlineKey = localStorage.getItem(lib.configprefix + "key"); localStorage.clear(); if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); + localStorage.setItem("noname_inited", noname_inited); } if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); + localStorage.setItem(lib.configprefix + "key", onlineKey); } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + "data"); setTimeout(function () { window.location.reload(); }, 200); } }, - '确认退出', - ['取消', '重新下载', '重置设置'] + "确认退出", + ["取消", "重新下载", "重置设置"] ); - } - else { - if (confirm('游戏似乎未正常载入,是否重置游戏?')) { - localStorage.removeItem('noname_inited'); + } else { + if (confirm("游戏似乎未正常载入,是否重置游戏?")) { + localStorage.removeItem("noname_inited"); window.location.reload(); } } - } - else { - if (confirm('游戏似乎未正常载入,是否重置游戏?')) { - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + } else { + if (confirm("游戏似乎未正常载入,是否重置游戏?")) { + var onlineKey = localStorage.getItem(lib.configprefix + "key"); localStorage.clear(); if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); + localStorage.setItem(lib.configprefix + "key", onlineKey); } - if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + 'data'); + if (indexedDB) indexedDB.deleteDatabase(lib.configprefix + "data"); setTimeout(function () { window.location.reload(); }, 200); @@ -83,109 +82,109 @@ export class LibInit extends Uninstantable { } // 现在改lib.init.onload的都给我无报错被创 - static async onload() { - throw new Error('lib.init.onload is moved to noname/init/onload') + async onload() { + throw new Error("lib.init.onload is moved to noname/init/onload"); } - static startOnline() { - 'step 0' + startOnline() { + "step 0"; event._resultid = null; event._result = null; game.pause(); - 'step 1' + "step 1"; if (result) { if (event._resultid) { result.id = event._resultid; } - game.send('result', result); + game.send("result", result); } event.goto(0); } - static onfree() { + onfree() { if (lib.onfree) { clearTimeout(window.resetGameTimeout); delete window.resetGameTimeout; if (!game.syncMenu) { delete window.resetExtension; - localStorage.removeItem(lib.configprefix + 'disable_extension'); + localStorage.removeItem(lib.configprefix + "disable_extension"); } if (game.removeFile && lib.config.brokenFile.length) { while (lib.config.brokenFile.length) { game.removeFile(lib.config.brokenFile.shift()); } - game.saveConfigValue('brokenFile'); + game.saveConfigValue("brokenFile"); } var onfree = lib.onfree; delete lib.onfree; var loop = function () { if (onfree.length) { - (onfree.shift())(); + onfree.shift()(); setTimeout(loop, 100); } }; setTimeout(loop, 500); - if (!_status.new_tutorial) game.saveConfig('menu_loadondemand', true, lib.config.mode); + if (!_status.new_tutorial) game.saveConfig("menu_loadondemand", true, lib.config.mode); } } - static connection(ws) { + connection(ws) { const client = new lib.element.Client(ws); lib.node.clients.push(client); if (window.isNonameServer) { - document.querySelector('#server_count').innerHTML = lib.node.clients.length; + document.querySelector("#server_count").innerHTML = lib.node.clients.length; } - ws.on('message', function (messagestr) { + ws.on("message", function (messagestr) { var message; try { message = JSON.parse(messagestr); - if (!Array.isArray(message) || - typeof lib.message.server[message[0]] !== 'function') { - throw ('err'); + if (!Array.isArray(message) || typeof lib.message.server[message[0]] !== "function") { + throw "err"; } for (var i = 1; i < message.length; i++) { message[i] = get.parsedResult(message[i]); } - } - catch (e) { + } catch (e) { console.log(e); - console.log('invalid message: ' + messagestr); + console.log("invalid message: " + messagestr); return; } lib.message.server[message.shift()].apply(client, message); }); - ws.on('close', function () { + ws.on("close", function () { client.close(); }); - client.send('opened'); + client.send("opened"); } - static sheet() { - var style = document.createElement('style'); + sheet() { + var style = document.createElement("style"); document.head.appendChild(style); for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { + if (typeof arguments[i] == "string") { style.sheet.insertRule(arguments[i], 0); } } return style; } - static css(path, file, before) { + css(path, file, before) { const style = document.createElement("link"); style.rel = "stylesheet"; if (path) { - if (path[path.length - 1] == '/') path = path.slice(0, path.length - 1); - if (file) path = `${path}${/^db:extension-[^:]*$/.test(path) ? ':' : '/'}${file}.css`; - (path.startsWith('db:') ? game.getDB('image', path.slice(3)).then(get.objectURL) : new Promise(resolve => resolve(path))).then(resolvedPath => { + if (path[path.length - 1] == "/") path = path.slice(0, path.length - 1); + if (file) path = `${path}${/^db:extension-[^:]*$/.test(path) ? ":" : "/"}${file}.css`; + (path.startsWith("db:") + ? game.getDB("image", path.slice(3)).then(get.objectURL) + : new Promise((resolve) => resolve(path)) + ).then((resolvedPath) => { style.href = resolvedPath; - if (typeof before == 'function') { - style.addEventListener('load', before); + if (typeof before == "function") { + style.addEventListener("load", before); document.head.appendChild(style); - } - else if (before) document.head.insertBefore(style, before); + } else if (before) document.head.insertBefore(style, before); else document.head.appendChild(style); }); } @@ -195,46 +194,73 @@ export class LibInit extends Uninstantable { //在扩展的precontent中调用,用于加载扩展必需的JS文件。 //If any of the parameters is an Array, corresponding files will be loaded in order //如果任意参数为数组,则按顺序加载加载相应的文件 - static jsForExtension(path, file, onLoad, onError) { + jsForExtension(path, file, onLoad, onError) { if (!_status.javaScriptExtensions) _status.javaScriptExtensions = []; _status.javaScriptExtensions.push({ path: path, file: file, onLoad: onLoad, - onError: onError + onError: onError, }); } - static js(path, file, onLoad, onError) { - if (path[path.length - 1] == '/') path = path.slice(0, path.length - 1); + js(path, file, onLoad, onError) { + if (path[path.length - 1] == "/") path = path.slice(0, path.length - 1); if (path == `${lib.assetURL}mode` && lib.config.all.stockmode.indexOf(file) == -1) { lib.genAwait(lib.init[`setMode_${file}`]()).then(onLoad); return; } if (Array.isArray(file)) { - file.forEach(value => lib.init.js(path, value, onLoad, onError)); + file.forEach((value) => lib.init.js(path, value, onLoad, onError)); return; } - let scriptSource = file ? `${path}${/^db:extension-[^:]*$/.test(path) ? ':' : '/'}${file}.js` : path; - if (path.startsWith('http')) scriptSource += `?rand=${get.id()}`; - else if (lib.config.fuck_sojson && scriptSource.includes('extension') != -1 && scriptSource.startsWith(lib.assetURL)) { + let scriptSource = file ? `${path}${/^db:extension-[^:]*$/.test(path) ? ":" : "/"}${file}.js` : path; + if (path.startsWith("http")) scriptSource += `?rand=${get.id()}`; + else if ( + lib.config.fuck_sojson && + scriptSource.includes("extension") != -1 && + scriptSource.startsWith(lib.assetURL) + ) { const pathToRead = scriptSource.slice(lib.assetURL.length); const alertMessage = `检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`; - if (typeof game.readFileAsText == 'function') game.readFileAsText(pathToRead, result => { - if (result.includes('sojson') || result.includes('jsjiami') || result.includes('var _0x')) alert(alertMessage); - }, () => void 0); - else if (location.origin != 'file://') lib.init.reqSync(pathToRead, function () { - const result = this.responseText; - if (result.includes('sojson') || result.includes('jsjiami') || result.includes('var _0x')) alert(alertMessage); - }, () => void 0); + if (typeof game.readFileAsText == "function") + game.readFileAsText( + pathToRead, + (result) => { + if ( + result.includes("sojson") || + result.includes("jsjiami") || + result.includes("var _0x") + ) + alert(alertMessage); + }, + () => void 0 + ); + else if (location.origin != "file://") + lib.init.reqSync( + pathToRead, + function () { + const result = this.responseText; + if ( + result.includes("sojson") || + result.includes("jsjiami") || + result.includes("var _0x") + ) + alert(alertMessage); + }, + () => void 0 + ); } - const script = document.createElement('script'); - (scriptSource.startsWith('db:') ? game.getDB('image', scriptSource.slice(3)).then(get.objectURL) : new Promise(resolve => resolve(scriptSource))).then(resolvedScriptSource => { + const script = document.createElement("script"); + (scriptSource.startsWith("db:") + ? game.getDB("image", scriptSource.slice(3)).then(get.objectURL) + : new Promise((resolve) => resolve(scriptSource)) + ).then((resolvedScriptSource) => { script.src = resolvedScriptSource; - if (path.startsWith('http')) script.addEventListener('load', () => script.remove()); + if (path.startsWith("http")) script.addEventListener("load", () => script.remove()); document.head.appendChild(script); - if (typeof onLoad == 'function') script.addEventListener('load', onLoad); - if (typeof onError == 'function') script.addEventListener('error', onError); + if (typeof onLoad == "function") script.addEventListener("load", onLoad); + if (typeof onError == "function") script.addEventListener("error", onError); }); return script; } @@ -243,82 +269,92 @@ export class LibInit extends Uninstantable { * 同步lib.init.js * @returns { void } */ - static jsSync(path, file, onLoad, onError) { - if (lib.assetURL.length == 0 && location.origin == 'file://' && typeof game.readFile == 'undefined') { - const e = new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); - if (typeof onError == 'function') onError(e); + jsSync(path, file, onLoad, onError) { + if (lib.assetURL.length == 0 && location.origin == "file://" && typeof game.readFile == "undefined") { + const e = new Error("浏览器file协议下无法使用此api,请在http/https协议下使用此api"); + if (typeof onError == "function") onError(e); else throw e; return; } - if (path[path.length - 1] == '/') path = path.slice(0, path.length - 1); + if (path[path.length - 1] == "/") path = path.slice(0, path.length - 1); if (path == `${lib.assetURL}mode` && lib.config.all.stockmode.indexOf(file) == -1) { lib.genAwait(lib.init[`setMode_${file}`]()).then(onLoad); return; } if (Array.isArray(file)) { - return file.forEach(value => lib.init.jsSync(path, value, onLoad, onError)); + return file.forEach((value) => lib.init.jsSync(path, value, onLoad, onError)); } let scriptSource; if (!file) scriptSource = path; else scriptSource = `${path}/${file}.js`; - if (path.startsWith('http')) scriptSource += `?rand=${get.id()}`; + if (path.startsWith("http")) scriptSource += `?rand=${get.id()}`; const xmlHttpRequest = new XMLHttpRequest(); let data; xmlHttpRequest.addEventListener("load", () => { if (![0, 200].includes(xmlHttpRequest.status)) { // @ts-ignore - if (typeof onError == 'function') onError(new Error(oReq.statusText || oReq.status)); + if (typeof onError == "function") onError(new Error(oReq.statusText || oReq.status)); return; } data = xmlHttpRequest.responseText; if (!data) { - if (typeof onError == 'function') onError(new Error(`${scriptSource}加载失败!`)); + if (typeof onError == "function") onError(new Error(`${scriptSource}加载失败!`)); return; } - if (lib.config.fuck_sojson && scriptSource.includes('extension') != -1 && scriptSource.startsWith(lib.assetURL)) { + if ( + lib.config.fuck_sojson && + scriptSource.includes("extension") != -1 && + scriptSource.startsWith(lib.assetURL) + ) { const pathToRead = scriptSource.slice(lib.assetURL.length); - if (data.includes('sojson') || data.includes('jsjiami') || data.includes('var _0x')) alert(`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}`); + if (data.includes("sojson") || data.includes("jsjiami") || data.includes("var _0x")) + alert( + `检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${pathToRead}` + ); } try { window.eval(data); - if (typeof onLoad == 'function') onLoad(); - } - catch (error) { - if (typeof onError == 'function') onError(error); + if (typeof onLoad == "function") onLoad(); + } catch (error) { + if (typeof onError == "function") onError(error); } }); - if (typeof onError == 'function') xmlHttpRequest.addEventListener("error", onError); + if (typeof onError == "function") xmlHttpRequest.addEventListener("error", onError); xmlHttpRequest.open("GET", scriptSource, false); xmlHttpRequest.send(); } - static req(str, onload, onerror, master) { + req(str, onload, onerror, master) { let sScriptURL; - if (str.startsWith('http')) sScriptURL = str; - else if (str.startsWith('local:')) { - if (lib.assetURL.length == 0 && location.origin == 'file://' && typeof game.readFile == 'undefined') { - const e = new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); - if (typeof onerror == 'function') onerror(e); + if (str.startsWith("http")) sScriptURL = str; + else if (str.startsWith("local:")) { + if ( + lib.assetURL.length == 0 && + location.origin == "file://" && + typeof game.readFile == "undefined" + ) { + const e = new Error("浏览器file协议下无法使用此api,请在http/https协议下使用此api"); + if (typeof onerror == "function") onerror(e); else throw e; return; } sScriptURL = lib.assetURL + str.slice(6); - } - else { + } else { let url = get.url(master); - if (url[url.length - 1] != '/') url += '/'; + if (url[url.length - 1] != "/") url += "/"; sScriptURL = url + str; } const oReq = new XMLHttpRequest(); - if (typeof onload == 'function') oReq.addEventListener("load", result => { - if (![0, 200].includes(oReq.status)) { - // @ts-ignore - if (typeof onerror == 'function') onerror(new Error(oReq.statusText || oReq.status)); - return; - } - onload.call(oReq, result); - }); - if (typeof onerror == 'function') oReq.addEventListener("error", onerror); + if (typeof onload == "function") + oReq.addEventListener("load", (result) => { + if (![0, 200].includes(oReq.status)) { + // @ts-ignore + if (typeof onerror == "function") onerror(new Error(oReq.statusText || oReq.status)); + return; + } + onload.call(oReq, result); + }); + if (typeof onerror == "function") oReq.addEventListener("error", onerror); oReq.open("GET", sScriptURL); oReq.send(); } @@ -326,58 +362,62 @@ export class LibInit extends Uninstantable { /** * 同步lib.init.req */ - static reqSync(str, onload, onerror, master) { + reqSync(str, onload, onerror, master) { let sScriptURL; - if (str.startsWith('http')) sScriptURL = str; - else if (str.startsWith('local:')) { - if (lib.assetURL.length == 0 && location.origin == 'file://' && typeof game.readFile == 'undefined') { - const e = new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); - if (typeof onerror == 'function') onerror(e); + if (str.startsWith("http")) sScriptURL = str; + else if (str.startsWith("local:")) { + if ( + lib.assetURL.length == 0 && + location.origin == "file://" && + typeof game.readFile == "undefined" + ) { + const e = new Error("浏览器file协议下无法使用此api,请在http/https协议下使用此api"); + if (typeof onerror == "function") onerror(e); else throw e; return; } sScriptURL = lib.assetURL + str.slice(6); - } - else { + } else { let url = get.url(master); - if (url[url.length - 1] != '/') url += '/'; + if (url[url.length - 1] != "/") url += "/"; sScriptURL = url + str; } const oReq = new XMLHttpRequest(); - if (typeof onload == 'function') oReq.addEventListener("load", result => { - if (![0, 200].includes(oReq.status)) { - // @ts-ignore - if (typeof onerror == 'function') onerror(new Error(oReq.statusText || oReq.status)); - return; - } - onload(result); - }); - if (typeof onerror == 'function') oReq.addEventListener("error", onerror); + if (typeof onload == "function") + oReq.addEventListener("load", (result) => { + if (![0, 200].includes(oReq.status)) { + // @ts-ignore + if (typeof onerror == "function") onerror(new Error(oReq.statusText || oReq.status)); + return; + } + onload(result); + }); + if (typeof onerror == "function") oReq.addEventListener("error", onerror); oReq.open("GET", sScriptURL, false); oReq.send(); - if (typeof onload !== 'function') return oReq.responseText; + if (typeof onload !== "function") return oReq.responseText; } - static json(url, onload, onerror) { + json(url, onload, onerror) { const oReq = new XMLHttpRequest(); - if (typeof onload == 'function') oReq.addEventListener("load", () => { - if (![0, 200].includes(oReq.status)) { - // @ts-ignore - if (typeof onerror == 'function') onerror(new Error(oReq.statusText || oReq.status)); - return; - } - let result; - try { - result = JSON.parse(oReq.responseText); - if (!result) throw ('err'); - } - catch (e) { - if (typeof onerror == 'function') onerror(e); - return; - } - onload(result); - }); - if (typeof onerror == 'function') oReq.addEventListener("error", onerror); + if (typeof onload == "function") + oReq.addEventListener("load", () => { + if (![0, 200].includes(oReq.status)) { + // @ts-ignore + if (typeof onerror == "function") onerror(new Error(oReq.statusText || oReq.status)); + return; + } + let result; + try { + result = JSON.parse(oReq.responseText); + if (!result) throw "err"; + } catch (e) { + if (typeof onerror == "function") onerror(e); + return; + } + onload(result); + }); + if (typeof onerror == "function") oReq.addEventListener("error", onerror); oReq.open("GET", url); oReq.send(); } @@ -385,217 +425,275 @@ export class LibInit extends Uninstantable { /** * 同步lib.init.json */ - static jsonSync(url, onload, onerror) { - if (lib.assetURL.length == 0 && location.origin == 'file://' && typeof game.readFile == 'undefined') { - const e = new Error('浏览器file协议下无法使用此api,请在http/https协议下使用此api'); - if (typeof onerror == 'function') onerror(e); + jsonSync(url, onload, onerror) { + if (lib.assetURL.length == 0 && location.origin == "file://" && typeof game.readFile == "undefined") { + const e = new Error("浏览器file协议下无法使用此api,请在http/https协议下使用此api"); + if (typeof onerror == "function") onerror(e); else throw e; return; } const oReq = new XMLHttpRequest(); - if (typeof onload == 'function') oReq.addEventListener("load", () => { - if (![0, 200].includes(oReq.status)) { - // @ts-ignore - if (typeof onerror == 'function') onerror(new Error(oReq.statusText || oReq.status)); - return; - } - let result; - try { - result = JSON.parse(oReq.responseText); - if (!result) throw ('err'); - } - catch (e) { - if (typeof onerror == 'function') onerror(e); - return; - } - onload(result); - }); - if (typeof onerror == 'function') oReq.addEventListener("error", onerror); + if (typeof onload == "function") + oReq.addEventListener("load", () => { + if (![0, 200].includes(oReq.status)) { + // @ts-ignore + if (typeof onerror == "function") onerror(new Error(oReq.statusText || oReq.status)); + return; + } + let result; + try { + result = JSON.parse(oReq.responseText); + if (!result) throw "err"; + } catch (e) { + if (typeof onerror == "function") onerror(e); + return; + } + onload(result); + }); + if (typeof onerror == "function") oReq.addEventListener("error", onerror); oReq.open("GET", url, false); oReq.send(); } - static cssstyles() { + cssstyles() { if (ui.css.styles) { ui.css.styles.remove(); } ui.css.styles = lib.init.sheet(); - ui.css.styles.sheet.insertRule('#arena .player>.name,#arena .button.character>.name {font-family: ' + (lib.config.name_font || 'xinwei') + ',xinwei}', 0); - ui.css.styles.sheet.insertRule('#arena .player>.name,.button.character>.name {font-family: ' + (lib.config.name_font || 'xinwei') + ',xinwei}', 0); - ui.css.styles.sheet.insertRule('#arena .player .identity>div {font-family: ' + (lib.config.identity_font || 'huangcao') + ',xinwei}', 0); - ui.css.styles.sheet.insertRule('.button.character.newstyle>.identity {font-family: ' + (lib.config.identity_font || 'huangcao') + ',xinwei}', 0); - if (lib.config.cardtext_font && lib.config.cardtext_font != 'default') { - ui.css.styles.sheet.insertRule('.card div:not(.info):not(.background) {font-family: ' + lib.config.cardtext_font + ';}', 0); + ui.css.styles.sheet.insertRule( + "#arena .player>.name,#arena .button.character>.name {font-family: " + + (lib.config.name_font || "xinwei") + + ",xinwei}", + 0 + ); + ui.css.styles.sheet.insertRule( + "#arena .player>.name,.button.character>.name {font-family: " + + (lib.config.name_font || "xinwei") + + ",xinwei}", + 0 + ); + ui.css.styles.sheet.insertRule( + "#arena .player .identity>div {font-family: " + + (lib.config.identity_font || "huangcao") + + ",xinwei}", + 0 + ); + ui.css.styles.sheet.insertRule( + ".button.character.newstyle>.identity {font-family: " + + (lib.config.identity_font || "huangcao") + + ",xinwei}", + 0 + ); + if (lib.config.cardtext_font && lib.config.cardtext_font != "default") { + ui.css.styles.sheet.insertRule( + ".card div:not(.info):not(.background) {font-family: " + lib.config.cardtext_font + ";}", + 0 + ); } - if (lib.config.global_font && lib.config.global_font != 'default') { - ui.css.styles.sheet.insertRule('#window {font-family: ' + lib.config.global_font + ',xinwei}', 0); - ui.css.styles.sheet.insertRule('#window #control{font-family: STHeiti,SimHei,Microsoft JhengHei,Microsoft YaHei,WenQuanYi Micro Hei,Suits,Helvetica,Arial,sans-serif}', 0); + if (lib.config.global_font && lib.config.global_font != "default") { + ui.css.styles.sheet.insertRule("#window {font-family: " + lib.config.global_font + ",xinwei}", 0); + ui.css.styles.sheet.insertRule( + "#window #control{font-family: STHeiti,SimHei,Microsoft JhengHei,Microsoft YaHei,WenQuanYi Micro Hei,Suits,Helvetica,Arial,sans-serif}", + 0 + ); } switch (lib.config.glow_phase) { - case 'yellow': ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(217, 152, 62) 0 0 15px, rgb(217, 152, 62) 0 0 15px !important;}', 0); break; - case 'green': ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(10, 155, 67, 1) 0 0 15px, rgba(10, 155, 67, 1) 0 0 15px !important;}', 0); break; - case 'purple': ui.css.styles.sheet.insertRule('#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(189, 62, 170) 0 0 15px, rgb(189, 62, 170) 0 0 15px !important;}', 0); break; + case "yellow": + ui.css.styles.sheet.insertRule( + "#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(217, 152, 62) 0 0 15px, rgb(217, 152, 62) 0 0 15px !important;}", + 0 + ); + break; + case "green": + ui.css.styles.sheet.insertRule( + "#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(10, 155, 67, 1) 0 0 15px, rgba(10, 155, 67, 1) 0 0 15px !important;}", + 0 + ); + break; + case "purple": + ui.css.styles.sheet.insertRule( + "#arena .player:not(.selectable):not(.selected).glow_phase {box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgb(189, 62, 170) 0 0 15px, rgb(189, 62, 170) 0 0 15px !important;}", + 0 + ); + break; } } - static layout(layout, nosave) { - const loadingScreen = ui.create.div('.loading-screen', document.body), loadingScreenStyle = loadingScreen.style; - loadingScreenStyle.animationDuration = '1s'; - loadingScreenStyle.animationFillMode = 'forwards'; - loadingScreenStyle.animationName = 'opacity-0-1'; - if (layout == 'default') layout = 'mobile'; - if (!nosave) game.saveConfig('layout', layout); + layout(layout, nosave) { + const loadingScreen = ui.create.div(".loading-screen", document.body), + loadingScreenStyle = loadingScreen.style; + loadingScreenStyle.animationDuration = "1s"; + loadingScreenStyle.animationFillMode = "forwards"; + loadingScreenStyle.animationName = "opacity-0-1"; + if (layout == "default") layout = "mobile"; + if (!nosave) game.saveConfig("layout", layout); game.layout = layout; ui.arena.hide(); - new Promise(resolve => setTimeout(resolve, 500)).then(() => { - if (game.layout == 'default') { - ui.css.layout.href = ''; - } - else { - ui.css.layout.href = lib.assetURL + 'layout/' + game.layout + '/layout.css'; - } - if (game.layout == 'mobile' || game.layout == 'long') { - ui.arena.classList.add('mobile'); - } - else { - ui.arena.classList.remove('mobile'); - } - if (game.layout == 'mobile' || game.layout == 'long' || game.layout == 'long2' || game.layout == 'nova') { - if (game.me && game.me.node.handcards2.childNodes.length) { - while (game.me.node.handcards2.childNodes.length) { - game.me.node.handcards1.appendChild(game.me.node.handcards2.firstChild); + new Promise((resolve) => setTimeout(resolve, 500)) + .then(() => { + if (game.layout == "default") { + ui.css.layout.href = ""; + } else { + ui.css.layout.href = lib.assetURL + "layout/" + game.layout + "/layout.css"; + } + if (game.layout == "mobile" || game.layout == "long") { + ui.arena.classList.add("mobile"); + } else { + ui.arena.classList.remove("mobile"); + } + if ( + game.layout == "mobile" || + game.layout == "long" || + game.layout == "long2" || + game.layout == "nova" + ) { + if (game.me && game.me.node.handcards2.childNodes.length) { + while (game.me.node.handcards2.childNodes.length) { + game.me.node.handcards1.appendChild(game.me.node.handcards2.firstChild); + } } } - } - if (game.layout == 'default') { - ui.arena.classList.add('oldlayout'); - } - else { - ui.arena.classList.remove('oldlayout'); - } - if (lib.config.cardshape == 'oblong' && (game.layout == 'long' || game.layout == 'mobile' || game.layout == 'long2' || game.layout == 'nova')) { - ui.arena.classList.add('oblongcard'); - ui.window.classList.add('oblongcard'); - } - else { - ui.arena.classList.remove('oblongcard'); - ui.window.classList.remove('oblongcard'); - } - //if(lib.config.textequip=='text'&&(game.layout=='long'||game.layout=='mobile')){ - if (game.layout == 'long' || game.layout == 'mobile') { - ui.arena.classList.add('textequip'); - } - else { - ui.arena.classList.remove('textequip'); - } - if (get.is.phoneLayout()) { - ui.css.phone.href = lib.assetURL + 'layout/default/phone.css'; - ui.arena.classList.add('phone'); - } - else { - ui.css.phone.href = ''; - ui.arena.classList.remove('phone'); - } - for (var i = 0; i < game.players.length; i++) { - if (get.is.linked2(game.players[i])) { - if (game.players[i].classList.contains('linked')) { - game.players[i].classList.remove('linked'); - game.players[i].classList.add('linked2'); + if (game.layout == "default") { + ui.arena.classList.add("oldlayout"); + } else { + ui.arena.classList.remove("oldlayout"); + } + if ( + lib.config.cardshape == "oblong" && + (game.layout == "long" || + game.layout == "mobile" || + game.layout == "long2" || + game.layout == "nova") + ) { + ui.arena.classList.add("oblongcard"); + ui.window.classList.add("oblongcard"); + } else { + ui.arena.classList.remove("oblongcard"); + ui.window.classList.remove("oblongcard"); + } + //if(lib.config.textequip=='text'&&(game.layout=='long'||game.layout=='mobile')){ + if (game.layout == "long" || game.layout == "mobile") { + ui.arena.classList.add("textequip"); + } else { + ui.arena.classList.remove("textequip"); + } + if (get.is.phoneLayout()) { + ui.css.phone.href = lib.assetURL + "layout/default/phone.css"; + ui.arena.classList.add("phone"); + } else { + ui.css.phone.href = ""; + ui.arena.classList.remove("phone"); + } + for (var i = 0; i < game.players.length; i++) { + if (get.is.linked2(game.players[i])) { + if (game.players[i].classList.contains("linked")) { + game.players[i].classList.remove("linked"); + game.players[i].classList.add("linked2"); + } + } else { + if (game.players[i].classList.contains("linked2")) { + game.players[i].classList.remove("linked2"); + game.players[i].classList.add("linked"); + } } } - else { - if (game.players[i].classList.contains('linked2')) { - game.players[i].classList.remove('linked2'); - game.players[i].classList.add('linked'); - } + if (game.layout == "long" || game.layout == "long2") { + ui.arena.classList.add("long"); + } else { + ui.arena.classList.remove("long"); } - } - if (game.layout == 'long' || game.layout == 'long2') { - ui.arena.classList.add('long'); - } - else { - ui.arena.classList.remove('long'); - } - if (lib.config.player_border != 'wide' || game.layout == 'long' || game.layout == 'long2') { - ui.arena.classList.add('slim_player'); - } - else { - ui.arena.classList.remove('slim_player'); - } - if (lib.config.player_border == 'normal' && lib.config.mode != 'brawl' && (game.layout == 'long' || game.layout == 'long2')) { - ui.arena.classList.add('lslim_player'); - } - else { - ui.arena.classList.remove('lslim_player'); - } - if (lib.config.player_border == 'slim') { - ui.arena.classList.add('uslim_player'); - } - else { - ui.arena.classList.remove('uslim_player'); - } - if (lib.config.player_border == 'narrow') { - ui.arena.classList.add('mslim_player'); - } - else { - ui.arena.classList.remove('mslim_player'); - } - ui.updatej(); - ui.updatem(); - return new Promise(resolve => setTimeout(resolve, 100)); - }).then(() => { - ui.arena.show(); - if (game.me) game.me.update(); - return new Promise(resolve => setTimeout(resolve, 500)); - }).then(() => { - ui.updatex(); - ui.updatePlayerPositions(); - return new Promise(resolve => setTimeout(resolve, 500)); - }).then(() => { - ui.updatec(); - loadingScreenStyle.animationName = 'opacity-1-0'; - loadingScreen.addEventListener('animationend', animationEvent => animationEvent.target.remove()); - }); + if (lib.config.player_border != "wide" || game.layout == "long" || game.layout == "long2") { + ui.arena.classList.add("slim_player"); + } else { + ui.arena.classList.remove("slim_player"); + } + if ( + lib.config.player_border == "normal" && + lib.config.mode != "brawl" && + (game.layout == "long" || game.layout == "long2") + ) { + ui.arena.classList.add("lslim_player"); + } else { + ui.arena.classList.remove("lslim_player"); + } + if (lib.config.player_border == "slim") { + ui.arena.classList.add("uslim_player"); + } else { + ui.arena.classList.remove("uslim_player"); + } + if (lib.config.player_border == "narrow") { + ui.arena.classList.add("mslim_player"); + } else { + ui.arena.classList.remove("mslim_player"); + } + ui.updatej(); + ui.updatem(); + return new Promise((resolve) => setTimeout(resolve, 100)); + }) + .then(() => { + ui.arena.show(); + if (game.me) game.me.update(); + return new Promise((resolve) => setTimeout(resolve, 500)); + }) + .then(() => { + ui.updatex(); + ui.updatePlayerPositions(); + return new Promise((resolve) => setTimeout(resolve, 500)); + }) + .then(() => { + ui.updatec(); + loadingScreenStyle.animationName = "opacity-1-0"; + loadingScreen.addEventListener("animationend", (animationEvent) => + animationEvent.target.remove() + ); + }); } - static background() { + background() { if (lib.config.image_background_random) { var list = []; for (var i in lib.configMenu.appearence.config.image_background.item) { - if (i == 'default') continue; + if (i == "default") continue; list.push(i); } list.remove(lib.config.image_background); - localStorage.setItem(lib.configprefix + 'background', JSON.stringify(list)); - } - else if (lib.config.image_background && lib.config.image_background != 'default' && !lib.config.image_background.startsWith('custom_')) { - localStorage.setItem(lib.configprefix + 'background', lib.config.image_background); - } - else if (lib.config.image_background == 'default' && lib.config.theme == 'simple') { - localStorage.setItem(lib.configprefix + 'background', 'ol_bg'); - } - else { - localStorage.removeItem(lib.configprefix + 'background'); + localStorage.setItem(lib.configprefix + "background", JSON.stringify(list)); + } else if ( + lib.config.image_background && + lib.config.image_background != "default" && + !lib.config.image_background.startsWith("custom_") + ) { + localStorage.setItem(lib.configprefix + "background", lib.config.image_background); + } else if (lib.config.image_background == "default" && lib.config.theme == "simple") { + localStorage.setItem(lib.configprefix + "background", "ol_bg"); + } else { + localStorage.removeItem(lib.configprefix + "background"); } } /** - * - * @param {*} item + * + * @param {*} item * @param {Function} [scope] 作用域 - * @returns + * @returns */ - static parsex(item, scope) { + parsex(item, scope) { //by 诗笺、Tipx-L /** - * @param {Function} func + * @param {Function} func */ function Legacy(func) { //Remove all comments //移除所有注释 - let 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(); + let 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]*)/gm, + "$2" + ) + .trim(); //获取第一个 { 后的所有字符 - str = str.slice(str.indexOf('{') + 1); + str = str.slice(str.indexOf("{") + 1); //判断代码中是否有debugger let regex = /event\.debugger\(\)/; let hasDebugger = false; @@ -604,11 +702,14 @@ export class LibInit extends Uninstantable { let debuggerResult; while ((debuggerResult = str.slice(debuggerSkip).match(regex)) != null) { let debuggerCopy = str; - debuggerCopy = debuggerCopy.slice(0, debuggerSkip + debuggerResult.index) + insertDebugger + debuggerCopy.slice(debuggerSkip + debuggerResult.index + debuggerResult[0].length, -1); + debuggerCopy = + debuggerCopy.slice(0, debuggerSkip + debuggerResult.index) + + insertDebugger + + debuggerCopy.slice(debuggerSkip + debuggerResult.index + debuggerResult[0].length, -1); //测试是否有错误 try { new GeneratorFunction(debuggerCopy); - str = debuggerCopy + '}'; + str = debuggerCopy + "}"; debuggerSkip += debuggerResult.index + insertDebugger.length; hasDebugger = true; } catch (error) { @@ -616,8 +717,8 @@ export class LibInit extends Uninstantable { } } //func中要写步骤的话,必须要写step 0 - if (str.indexOf('step 0') == -1) { - str = '{if(event.step==1) {event.finish();return;}\n' + str; + if (str.indexOf("step 0") == -1) { + str = "{if(event.step==1) {event.finish();return;}\n" + str; } else { let skip = 0; let k = 0; @@ -631,7 +732,10 @@ export class LibInit extends Uninstantable { insertStr = `break;case ${k}:`; } let copy = str; - copy = copy.slice(0, skip + result.index) + insertStr + copy.slice(skip + result.index + result[0].length); + copy = + copy.slice(0, skip + result.index) + + insertStr + + copy.slice(skip + result.index + result[0].length); //测试是否有错误 try { new (hasDebugger ? GeneratorFunction : Function)(copy); @@ -646,11 +750,32 @@ export class LibInit extends Uninstantable { str = `if(event.step==${k}){event.finish();return;}` + str; } if (!scope) { - 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)); + 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 + ); } else { - return scope(`function${hasDebugger ? '*' : ''} anonymous(event,step,source,player,target,targets, + return scope(`function${ + hasDebugger ? "*" : "" + } anonymous(event,step,source,player,target,targets, card,cards,skill,forced,num,trigger,result, _status,lib,game,ui,get,ai){${str}}; anonymous;`); } @@ -659,31 +784,55 @@ export class LibInit extends Uninstantable { case "object": if (Array.isArray(item)) { let lastEvent = null; - return function* (event, step, source, player, target, targets, card, cards, skill, forced, num, trigger, result, _status, lib, game, ui, get, ai) { + return function* ( + event, + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + trigger, + result, + _status, + lib, + game, + ui, + get, + ai + ) { if (step >= item.length) return event.finish(); var current = item[step]; - if (typeof current != "function") throw new Error(`content ${step} of ${event.name} is not vaild: ${current}`); - var currentResult = current(event, { - event: event, - step: step, - source: source, - player: player, - target: target, - targets: targets, - card: card, - cards: cards, - skill: skill, - forced: forced, - num: num, - trigger: trigger, - result: result - }, (lastEvent && ("result" in lastEvent)) ? lastEvent.result : null); + if (typeof current != "function") + throw new Error(`content ${step} of ${event.name} is not vaild: ${current}`); + var currentResult = current( + event, + { + event: event, + step: step, + source: source, + player: player, + target: target, + targets: targets, + card: card, + cards: cards, + skill: skill, + forced: forced, + num: num, + trigger: trigger, + result: result, + }, + lastEvent && "result" in lastEvent ? lastEvent.result : null + ); // TODO: use `event.debugger` to replace source if (gnc.is.generator(currentResult)) lastEvent = yield* currentResult; else lastEvent = currentResult; - } - } - else { + }; + } else { if (Symbol.iterator in item) return lib.init.parsex(Array.from(item)); if (item.toString !== Object.prototype.toString) return lib.init.parsex(item.toString()); if ("render" in item) { @@ -696,32 +845,53 @@ export class LibInit extends Uninstantable { case "function": if (gnc.is.generatorFunc(item)) { // let gen, lastEvent; - let content = function* (event, step, source, player, target, targets, card, cards, skill, forced, num, trigger, result, _status, lib, game, ui, get, ai) { + let content = function* ( + event, + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + trigger, + result, + _status, + lib, + game, + ui, + get, + ai + ) { event.step = NaN; - if (!this.gen) this.gen = item(event, { - event, - step, - source, - player, - target, - targets, - card, - cards, - skill, - forced, - num, - trigger, - result - }); + if (!this.gen) + this.gen = item(event, { + event, + step, + source, + player, + target, + targets, + card, + cards, + skill, + forced, + num, + trigger, + result, + }); - let res - if (!this.last) res = this.gen.next() - else if (typeof this.last !== "object") res = this.gen.next(this.last) + let res; + if (!this.last) res = this.gen.next(); + else if (typeof this.last !== "object") res = this.gen.next(this.last); else if (this.last instanceof GameEvent || this.last instanceof GameEventPromise) - res = this.gen.next(this.last.result) - else res = this.gen.next(this.last) + res = this.gen.next(this.last.result); + else res = this.gen.next(this.last); - if (res.done){ + if (res.done) { this.gen = null; return event.finish(); } @@ -737,10 +907,10 @@ export class LibInit extends Uninstantable { } }.bind({ gen: null, - last: undefined - }) - content._gen = true - return content + last: undefined, + }); + content._gen = true; + return content; } else if (item._parsed) return item; // falls through default: @@ -748,18 +918,17 @@ export class LibInit extends Uninstantable { } } - static eval(func) { - if (typeof func == 'function') { - return eval('(' + func.toString() + ')'); - } - else if (typeof func == 'object') { + eval(func) { + if (typeof func == "function") { + return eval("(" + func.toString() + ")"); + } else if (typeof func == "object") { for (var i in func) { if (Object.prototype.hasOwnProperty.call(func, i)) { - if(typeof func[i] == 'function'){ + if (typeof func[i] == "function") { let checkObject = {}; checkObject[i] = func[i]; return eval(`(function(){return ${get.stringify(checkObject)};})()`)[i]; - }else{ + } else { func[i] = lib.init.eval(func[i]); } } @@ -768,79 +937,72 @@ export class LibInit extends Uninstantable { return func; } - static encode(strUni) { - var strUtf = strUni.replace( - /[\u0080-\u07ff]/g, function (c) { - var cc = c.charCodeAt(0); - return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f); - }); - strUtf = strUtf.replace( - /[\u0800-\uffff]/g, function (c) { - var cc = c.charCodeAt(0); - return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3F, 0x80 | cc & 0x3f); - }); + encode(strUni) { + var strUtf = strUni.replace(/[\u0080-\u07ff]/g, function (c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xc0 | (cc >> 6), 0x80 | (cc & 0x3f)); + }); + strUtf = strUtf.replace(/[\u0800-\uffff]/g, function (c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xe0 | (cc >> 12), 0x80 | ((cc >> 6) & 0x3f), 0x80 | (cc & 0x3f)); + }); return btoa(strUtf); } - static decode(str) { + decode(str) { var strUtf = atob(str); - var strUni = strUtf.replace( - /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, function (c) { - var cc = ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f); - return String.fromCharCode(cc); - }); - strUni = strUni.replace( - /[\u00c0-\u00df][\u0080-\u00bf]/g, function (c) { - var cc = (c.charCodeAt(0) & 0x1f) << 6 | c.charCodeAt(1) & 0x3f; - return String.fromCharCode(cc); - }); + var strUni = strUtf.replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, function (c) { + var cc = + ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f); + return String.fromCharCode(cc); + }); + strUni = strUni.replace(/[\u00c0-\u00df][\u0080-\u00bf]/g, function (c) { + var cc = ((c.charCodeAt(0) & 0x1f) << 6) | (c.charCodeAt(1) & 0x3f); + return String.fromCharCode(cc); + }); return strUni; } - static stringify(obj) { - var str = '{' + stringify(obj) { + var str = "{"; for (var i in obj) { - str += '"' + i + '":' - if (Object.prototype.toString.call(obj[i]) == '[object Object]') { + str += '"' + i + '":'; + if (Object.prototype.toString.call(obj[i]) == "[object Object]") { str += lib.init.stringify(obj[i]); - } - else if (typeof obj[i] == 'function') { + } else if (typeof obj[i] == "function") { str += obj[i].toString(); - } - else { + } else { str += JSON.stringify(obj[i]); } - str += ',' + str += ","; } - str += '}'; + str += "}"; return str; } - static stringifySkill(obj) { - var str = ''; + stringifySkill(obj) { + var str = ""; for (var i in obj) { - str += i + ':' - if (Object.prototype.toString.call(obj[i]) == '[object Object]') { - str += '{\n' + lib.init.stringifySkill(obj[i]) + '}'; - } - else if (typeof obj[i] == 'function') { - str += obj[i].toString().replace(/\t/g, ''); - } - else { + str += i + ":"; + if (Object.prototype.toString.call(obj[i]) == "[object Object]") { + str += "{\n" + lib.init.stringifySkill(obj[i]) + "}"; + } else if (typeof obj[i] == "function") { + str += obj[i].toString().replace(/\t/g, ""); + } else { str += JSON.stringify(obj[i]); } - str += ',\n' + str += ",\n"; } return str; } /** * 在返回当前加载的esm模块相对位置。 - * @param {*} url 传入import.meta.url + * @param {*} url 传入import.meta.url */ - static getCurrentFileLocation(url){ - let head = window.location.href.slice(0,window.location.href.lastIndexOf('/')+1); - let ret = url.replace(head,''); + getCurrentFileLocation(url) { + let head = window.location.href.slice(0, window.location.href.lastIndexOf("/") + 1); + let ret = url.replace(head, ""); return decodeURIComponent(ret); } } diff --git a/noname/library/init/promises.js b/noname/library/init/promises.js index 170248d1b..844034828 100644 --- a/noname/library/init/promises.js +++ b/noname/library/init/promises.js @@ -1,67 +1,66 @@ -import { Uninstantable } from "../../util/index.js"; -import { Library as lib } from "../index.js"; +import { lib } from "../../../noname.js"; -export class LibInitPromises extends Uninstantable { +export class LibInitPromises { /** * Promise版的`lib.init.js` - * + * * @param {string} path - 文件路径 * @param {string | string[]} [file] - 文件名或文件名组,忽略则直接读取`path`的内容 * @returns {Promise} */ - static js(path, file) { - return new Promise((resolve, reject) => lib.init.js(path, file, resolve, reject)) + js(path, file) { + return new Promise((resolve, reject) => lib.init.js(path, file, resolve, reject)); } /** * Promise版的`lib.init.css` - * + * * @param {string} path - 文件路径 * @param {string | string[]} [file] - 文件名或文件名组,忽略则直接读取`path`的内容 * @param {Element} [before] - 新样式dom的位置 * @param {boolean} [noerror = false] - 是否忽略报错 * @returns {Promise} */ - static css(path, file, before, noerror = false) { + css(path, file, before, noerror = false) { return new Promise((resolve, reject) => { const style = lib.init.css(path, file, before); const success = () => resolve(style); style.addEventListener("load", success); style.addEventListener("error", noerror ? success : reject); - }) + }); } /** * Promise版的`lib.init.req` - * + * * @param {string} str - 要读取的地址 * @param {string} [master] * @returns {Promise} */ - static req(str, master) { - return new Promise((resolve, reject) => lib.init.req(str, resolve, reject, master)) + req(str, master) { + return new Promise((resolve, reject) => lib.init.req(str, resolve, reject, master)); } /** * Promise版的`lib.init.json` - * + * * @param {string} url - 要读取的地址 * @returns {Promise} */ - static json(url) { - return new Promise((resolve, reject) => lib.init.json(url, resolve, reject)) + json(url) { + return new Promise((resolve, reject) => lib.init.json(url, resolve, reject)); } /** * Promise版的`lib.init.sheet` - * + * * @returns {Promise} */ - static sheet() { + sheet() { return new Promise((resolve, reject) => { const style = lib.init.sheet.apply(lib.init, arguments); style.addEventListener("load", () => resolve(style)); style.addEventListener("error", reject); - }) + }); } } diff --git a/noname/library/path.js b/noname/library/path.js index 1320e0210..b55f01fbb 100644 --- a/noname/library/path.js +++ b/noname/library/path.js @@ -23,46 +23,48 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. function assertPath(path) { - if (typeof path !== 'string') { - throw new TypeError('Path must be a string. Received ' + JSON.stringify(path)); + if (typeof path !== "string") { + throw new TypeError("Path must be a string. Received " + JSON.stringify(path)); } } // Resolves . and .. elements in a path with directory names function normalizeStringPosix(path, allowAboveRoot) { - var res = ''; + var res = ""; var lastSegmentLength = 0; var lastSlash = -1; var dots = 0; var code; for (var i = 0; i <= path.length; ++i) { - if (i < path.length) - code = path.charCodeAt(i); - else if (code === 47 /*/*/) - break; - else - code = 47 /*/*/; + if (i < path.length) code = path.charCodeAt(i); + else if (code === 47 /*/*/) break; + else code = 47 /*/*/; if (code === 47 /*/*/) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) { + if ( + res.length < 2 || + lastSegmentLength !== 2 || + res.charCodeAt(res.length - 1) !== 46 /*.*/ || + res.charCodeAt(res.length - 2) !== 46 /*.*/ + ) { if (res.length > 2) { - var lastSlashIndex = res.lastIndexOf('/'); + var lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex !== res.length - 1) { if (lastSlashIndex === -1) { - res = ''; + res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); - lastSegmentLength = res.length - 1 - res.lastIndexOf('/'); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = i; dots = 0; continue; } } else if (res.length === 2 || res.length === 1) { - res = ''; + res = ""; lastSegmentLength = 0; lastSlash = i; dots = 0; @@ -70,17 +72,13 @@ function normalizeStringPosix(path, allowAboveRoot) { } } if (allowAboveRoot) { - if (res.length > 0) - res += '/..'; - else - res = '..'; + if (res.length > 0) res += "/.."; + else res = ".."; lastSegmentLength = 2; } } else { - if (res.length > 0) - res += '/' + path.slice(lastSlash + 1, i); - else - res = path.slice(lastSlash + 1, i); + if (res.length > 0) res += "/" + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; } lastSlash = i; @@ -96,7 +94,7 @@ function normalizeStringPosix(path, allowAboveRoot) { function _format(sep, pathObject) { var dir = pathObject.dir || pathObject.root; - var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || ''); + var base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); if (!dir) { return base; } @@ -109,17 +107,15 @@ function _format(sep, pathObject) { var posix = { // path.resolve([from ...], to) resolve: function resolve() { - var resolvedPath = ''; + var resolvedPath = ""; var resolvedAbsolute = false; var cwd; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path; - if (i >= 0) - path = arguments[i]; + if (i >= 0) path = arguments[i]; else { - if (cwd === undefined) - cwd = process.cwd(); + if (cwd === undefined) cwd = process.cwd(); path = cwd; } @@ -130,7 +126,7 @@ var posix = { continue; } - resolvedPath = path + '/' + resolvedPath; + resolvedPath = path + "/" + resolvedPath; resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/; } @@ -141,32 +137,30 @@ var posix = { resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute) { - if (resolvedPath.length > 0) - return '/' + resolvedPath; - else - return '/'; + if (resolvedPath.length > 0) return "/" + resolvedPath; + else return "/"; } else if (resolvedPath.length > 0) { return resolvedPath; } else { - return '.'; + return "."; } }, normalize: function normalize(path) { assertPath(path); - if (path.length === 0) return '.'; + if (path.length === 0) return "."; - var isAbsolute = path.charCodeAt(0) === 47 /*/*/; - var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/; + var isAbsolute = path.charCodeAt(0) === 47; /*/*/ + var trailingSeparator = path.charCodeAt(path.length - 1) === 47; /*/*/ // Normalize the path path = normalizeStringPosix(path, !isAbsolute); - if (path.length === 0 && !isAbsolute) path = '.'; - if (path.length > 0 && trailingSeparator) path += '/'; + if (path.length === 0 && !isAbsolute) path = "."; + if (path.length > 0 && trailingSeparator) path += "/"; - if (isAbsolute) return '/' + path; + if (isAbsolute) return "/" + path; return path; }, @@ -176,21 +170,17 @@ var posix = { }, join: function join() { - if (arguments.length === 0) - return '.'; + if (arguments.length === 0) return "."; var joined; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; assertPath(arg); if (arg.length > 0) { - if (joined === undefined) - joined = arg; - else - joined += '/' + arg; + if (joined === undefined) joined = arg; + else joined += "/" + arg; } } - if (joined === undefined) - return '.'; + if (joined === undefined) return "."; return posix.normalize(joined); }, @@ -198,18 +188,17 @@ var posix = { assertPath(from); assertPath(to); - if (from === to) return ''; + if (from === to) return ""; from = posix.resolve(from); to = posix.resolve(to); - if (from === to) return ''; + if (from === to) return ""; // Trim any leading backslashes var fromStart = 1; for (; fromStart < from.length; ++fromStart) { - if (from.charCodeAt(fromStart) !== 47 /*/*/) - break; + if (from.charCodeAt(fromStart) !== 47 /*/*/) break; } var fromEnd = from.length; var fromLen = fromEnd - fromStart; @@ -217,8 +206,7 @@ var posix = { // Trim any leading backslashes var toStart = 1; for (; toStart < to.length; ++toStart) { - if (to.charCodeAt(toStart) !== 47 /*/*/) - break; + if (to.charCodeAt(toStart) !== 47 /*/*/) break; } var toEnd = to.length; var toLen = toEnd - toStart; @@ -254,32 +242,26 @@ var posix = { } var fromCode = from.charCodeAt(fromStart + i); var toCode = to.charCodeAt(toStart + i); - if (fromCode !== toCode) - break; - else if (fromCode === 47 /*/*/) - lastCommonSep = i; + if (fromCode !== toCode) break; + else if (fromCode === 47 /*/*/) lastCommonSep = i; } - var out = ''; + var out = ""; // Generate the relative path based on the path difference between `to` // and `from` for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) { - if (out.length === 0) - out += '..'; - else - out += '/..'; + if (out.length === 0) out += ".."; + else out += "/.."; } } // Lastly, append the rest of the destination (`to`) path that comes after // the common path parts - if (out.length > 0) - return out + to.slice(toStart + lastCommonSep); + if (out.length > 0) return out + to.slice(toStart + lastCommonSep); else { toStart += lastCommonSep; - if (to.charCodeAt(toStart) === 47 /*/*/) - ++toStart; + if (to.charCodeAt(toStart) === 47 /*/*/) ++toStart; return to.slice(toStart); } }, @@ -290,9 +272,9 @@ var posix = { dirname: function dirname(path) { assertPath(path); - if (path.length === 0) return '.'; + if (path.length === 0) return "."; var code = path.charCodeAt(0); - var hasRoot = code === 47 /*/*/; + var hasRoot = code === 47; /*/*/ var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { @@ -308,13 +290,14 @@ var posix = { } } - if (end === -1) return hasRoot ? '/' : '.'; - if (hasRoot && end === 1) return '//'; + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; return path.slice(0, end); }, basename: function basename(path, ext) { - if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string'); + if (ext !== undefined && typeof ext !== "string") + throw new TypeError('"ext" argument must be a string'); assertPath(path); var start = 0; @@ -323,7 +306,7 @@ var posix = { var i; if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { - if (ext.length === path.length && ext === path) return ''; + if (ext.length === path.length && ext === path) return ""; var extIdx = ext.length - 1; var firstNonSlashEnd = -1; for (i = path.length - 1; i >= 0; --i) { @@ -360,7 +343,8 @@ var posix = { } } - if (start === end) end = firstNonSlashEnd; else if (end === -1) end = path.length; + if (start === end) end = firstNonSlashEnd; + else if (end === -1) end = path.length; return path.slice(start, end); } else { for (i = path.length - 1; i >= 0; --i) { @@ -379,7 +363,7 @@ var posix = { } } - if (end === -1) return ''; + if (end === -1) return ""; return path.slice(start, end); } }, @@ -412,10 +396,8 @@ var posix = { } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension - if (startDot === -1) - startDot = i; - else if (preDotState !== 1) - preDotState = 1; + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension @@ -423,33 +405,38 @@ var posix = { } } - if (startDot === -1 || end === -1 || + if ( + startDot === -1 || + end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' - preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { - return ''; + (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) + ) { + return ""; } return path.slice(startDot, end); }, format: function format(pathObject) { - if (pathObject === null || typeof pathObject !== 'object') { - throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject); + if (pathObject === null || typeof pathObject !== "object") { + throw new TypeError( + 'The "pathObject" argument must be of type Object. Received type ' + typeof pathObject + ); } - return _format('/', pathObject); + return _format("/", pathObject); }, parse: function parse(path) { assertPath(path); - var ret = { root: '', dir: '', base: '', ext: '', name: '' }; + var ret = { root: "", dir: "", base: "", ext: "", name: "" }; if (path.length === 0) return ret; var code = path.charCodeAt(0); - var isAbsolute = code === 47 /*/*/; + var isAbsolute = code === 47; /*/*/ var start; if (isAbsolute) { - ret.root = '/'; + ret.root = "/"; start = 1; } else { start = 0; @@ -484,7 +471,8 @@ var posix = { } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; + if (startDot === -1) startDot = i; + else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension @@ -492,13 +480,17 @@ var posix = { } } - if (startDot === -1 || end === -1 || + if ( + startDot === -1 || + end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' - preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) + ) { if (end !== -1) { - if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end); else ret.base = ret.name = path.slice(startPart, end); + if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end); + else ret.base = ret.name = path.slice(startPart, end); } } else { if (startPart === 0 && isAbsolute) { @@ -511,15 +503,16 @@ var posix = { ret.ext = path.slice(startDot, end); } - if (startPart > 0) ret.dir = path.slice(0, startPart - 1); else if (isAbsolute) ret.dir = '/'; + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; return ret; }, - sep: '/', - delimiter: ':', + sep: "/", + delimiter: ":", win32: null, - posix: null + posix: null, }; // @ts-ignore diff --git a/noname/library/update-urls.js b/noname/library/update-urls.js index d53fbb73d..82ee46600 100644 --- a/noname/library/update-urls.js +++ b/noname/library/update-urls.js @@ -1,4 +1,4 @@ export const updateURLs = { - coding: 'https://unitedrhythmized.club/libccy/noname', - github: 'https://raw.githubusercontent.com/libccy/noname' + coding: "https://unitedrhythmized.club/libccy/noname", + github: "https://raw.githubusercontent.com/libccy/noname", }; diff --git a/noname/library/update.js b/noname/library/update.js index 9845366ce..bba8b98d3 100644 --- a/noname/library/update.js +++ b/noname/library/update.js @@ -1,4 +1,4 @@ -import { lib, ui, game } from '../../noname.js'; +import { ui, game, lib } from "../../noname.js"; // https://github.com/libccy/noname/archive/refs/tags/v1.10.10.zip @@ -7,28 +7,31 @@ import { lib, ui, game } from '../../noname.js'; * X-RateLimit-Limit: 请求总量限制 * X-RateLimit-Remaining: 剩余请求次数 * X-RateLimit-Reset: 限制重置时间(UTC时间戳) -*/ + */ /** @type { HeadersInit } */ const defaultHeaders = { - 'Accept': 'application/vnd.github.v3+json', + Accept: "application/vnd.github.v3+json", // 根据GitHub API的要求添加适当的认证头信息 // 如果公共仓库则无需认证,私有仓库需提供token // 'Authorization': `token ${YOUR_GITHUB_PERSONAL_ACCESS_TOKEN}` }; -if (localStorage.getItem('noname_authorization')) { - defaultHeaders['Authorization'] = `token ${localStorage.getItem('noname_authorization')}`; +if (localStorage.getItem("noname_authorization")) { + defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`; } +/** + * 获取github授权的token + */ export async function gainAuthorization() { - if (!localStorage.getItem('noname_authorization') && !sessionStorage.getItem('noname_authorization')) { - const result = await game.promises.prompt('请输入您github的token以解除访问每小时60次的限制'); - if (typeof result == 'string') { - localStorage.setItem('noname_authorization', result); - defaultHeaders['Authorization'] = `token ${localStorage.getItem('noname_authorization')}`; + if (!localStorage.getItem("noname_authorization") && !sessionStorage.getItem("noname_authorization")) { + const result = await game.promises.prompt("请输入您github的token以解除访问每小时60次的限制(可不输入)"); + if (typeof result == "string") { + localStorage.setItem("noname_authorization", result); + defaultHeaders["Authorization"] = `token ${localStorage.getItem("noname_authorization")}`; } else { - sessionStorage.setItem('noname_authorization', "false"); + sessionStorage.setItem("noname_authorization", "false"); } } } @@ -40,30 +43,40 @@ const defaultResponse = async (/** @type {Response} */ response) => { console.log(`请求总量限制`, limit); console.log(`剩余请求次数`, remaining); // @ts-ignore - console.log(`限制重置时间`, (new Date(reset * 1000)).toLocaleString()); - if (Number(remaining) === 0 && !sessionStorage.getItem('noname_authorization') && confirm(`您达到了每小时${limit}次的访问限制,是否输入您github的token以获取更高的请求总量限制`)) { - await gainAuthorization(); + console.log(`限制重置时间`, new Date(reset * 1000).toLocaleString()); + if ( + ( + Number(remaining) === 0 && + !sessionStorage.getItem("noname_authorization") && + confirm(`您达到了每小时${limit}次的访问限制,是否输入您github账号的token以获取更高的请求总量限制`) + ) || ( + response.status === 401 && + (localStorage.removeItem("noname_authorization"), true) && + (alert(`身份验证凭证错误,是否重新输入您github账号的token以获取更高的请求总量限制`), true) + ) + ) { + return gainAuthorization(); } }; /** * 字节转换 - * @param { number } limit + * @param { number } limit */ export function parseSize(limit) { let size = ""; if (limit < 1 * 1024) { // 小于1KB,则转化成B - size = limit.toFixed(2) + "B" + size = limit.toFixed(2) + "B"; } else if (limit < 1 * 1024 * 1024) { // 小于1MB,则转化成KB - size = (limit / 1024).toFixed(2) + "KB" + size = (limit / 1024).toFixed(2) + "KB"; } else if (limit < 1 * 1024 * 1024 * 1024) { // 小于1GB,则转化成MB - size = (limit / (1024 * 1024)).toFixed(2) + "MB" + size = (limit / (1024 * 1024)).toFixed(2) + "MB"; } else { // 其他转化成GB - size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB" + size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"; } // 转成字符串 @@ -77,34 +90,35 @@ export function parseSize(limit) { return sizeStr.slice(0, index) + sizeStr.slice(index + 3, 2); } return size; -}; +} /** * 对比版本号 - * @param { string } ver1 - * @param { string } ver2 - * @returns { -1 | 0 | 1 } + * @param { string } ver1 版本号1 + * @param { string } ver2 版本号2 + * @returns { -1 | 0 | 1 } -1为ver1 < ver2, 0为ver1 == ver2, 1为ver1 > ver2 + * @throws {Error} */ export function checkVersion(ver1, ver2) { - if (typeof ver1 !== 'string') ver1 = String(ver1); - if (typeof ver2 !== 'string') ver2 = String(ver2); + if (typeof ver1 !== "string") ver1 = String(ver1); + if (typeof ver2 !== "string") ver2 = String(ver2); // 移除 'v' 开头 - if (ver1.startsWith('v')) ver1 = ver1.slice(1); - if (ver2.startsWith('v')) ver2 = ver2.slice(1); + if (ver1.startsWith("v")) ver1 = ver1.slice(1); + if (ver2.startsWith("v")) ver2 = ver2.slice(1); // 验证版本号格式 if (/[^0-9.-]/i.test(ver1) || /[^0-9.-]/i.test(ver2)) { - throw new Error('Invalid characters found in the version numbers'); + throw new Error("Invalid characters found in the version numbers"); } /** @param { string } str */ function* walk(str) { - let part = ''; + let part = ""; for (const char of str) { - if (char === '.' || char === '-') { + if (char === "." || char === "-") { if (part) yield Number(part); - part = ''; + part = ""; } else { part += char; } @@ -126,7 +140,7 @@ export function checkVersion(ver1, ver2) { item2 = item2 === undefined ? 0 : item2; if (isNaN(item1) || isNaN(item2)) { - throw new Error('Non-numeric part found in the version numbers'); + throw new Error("Non-numeric part found in the version numbers"); } else if (item1 > item2) { return 1; } else if (item1 < item2) { @@ -138,17 +152,17 @@ export function checkVersion(ver1, ver2) { // 若正常遍历结束,说明版本号相等 return 0; -}; +} /** - * + * * 获取指定仓库的tags * @param { Object } options * @param { string } [options.username = 'libccy'] 仓库拥有者 * @param { string } [options.repository = 'noname'] 仓库名称 * @param { string } [options.accessToken] 身份令牌 * @returns { Promise<{ commit: { sha: string, url: string }, name: string, node_id: string, tarball_url: string, zipball_url: string }[]> } - * + * * @example * ```js * getRepoTags().then(tags => { @@ -159,14 +173,14 @@ export function checkVersion(ver1, ver2) { * }); * ``` */ -export async function getRepoTags(options = { username: 'libccy', repository: 'noname' }) { - if (!localStorage.getItem('noname_authorization')) { - await gainAuthorization(); - } - const { username = 'libccy', repository = 'noname', accessToken } = options; +export async function getRepoTags(options = { username: "libccy", repository: "noname" }) { + // if (!localStorage.getItem("noname_authorization")) { + // await gainAuthorization(); + // } + const { username = "libccy", repository = "noname", accessToken } = options; const headers = Object.assign({}, defaultHeaders); if (accessToken) { - headers['Authorization'] = `token ${accessToken}`; + headers["Authorization"] = `token ${accessToken}`; } const url = `https://api.github.com/repos/${username}/${repository}/tags`; const response = await fetch(url, { headers }); @@ -177,7 +191,7 @@ export async function getRepoTags(options = { username: 'libccy', repository: 'n } else { throw new Error(`Error fetching tags: ${response.statusText}`); } -}; +} /** * 获取指定仓库的指定tags的描述 @@ -194,14 +208,14 @@ export async function getRepoTags(options = { username: 'libccy', repository: 'n * ``` */ -export async function getRepoTagDescription(tagName, options = { username: 'libccy', repository: 'noname' }) { - if (!localStorage.getItem('noname_authorization')) { - await gainAuthorization(); - } - const { username = 'libccy', repository = 'noname', accessToken } = options; +export async function getRepoTagDescription(tagName, options = { username: "libccy", repository: "noname" }) { + // if (!localStorage.getItem("noname_authorization")) { + // await gainAuthorization(); + // } + const { username = "libccy", repository = "noname", accessToken } = options; const headers = Object.assign({}, defaultHeaders); if (accessToken) { - headers['Authorization'] = `token ${accessToken}`; + headers["Authorization"] = `token ${accessToken}`; } const apiUrl = `https://api.github.com/repos/${username}/${repository}/releases/tags/${tagName}`; const response = await fetch(apiUrl, { headers }); @@ -231,15 +245,15 @@ export async function getRepoTagDescription(tagName, options = { username: 'libc /** @type { string } tag名称 */ name: releaseData.name, /** 发布日期 */ - published_at: (new Date(releaseData.published_at)).toLocaleString(), + published_at: new Date(releaseData.published_at).toLocaleString(), /** @type { string } 下载地址 */ zipball_url: releaseData.zipball_url, }; -}; +} /** - * - * 获取仓库指定分支和指定目录内的所有文件和目录 + * + * 获取仓库指定分支和指定(单个)目录内的所有文件和目录 * @param { string } [path = ''] 路径名称(可放参数) * @param { string } [branch = ''] 仓库分支名称 * @param { Object } options @@ -254,23 +268,27 @@ export async function getRepoTagDescription(tagName, options = { username: 'libc * .catch(error => console.error('Failed to fetch files:', error)); * ``` */ -export async function getRepoFilesList(path = '', branch, options = { username: 'libccy', repository: 'noname' }) { - if (!localStorage.getItem('noname_authorization')) { - await gainAuthorization(); - } - const { username = 'libccy', repository = 'noname', accessToken } = options; +export async function getRepoFilesList( + path = "", + branch, + options = { username: "libccy", repository: "noname" } +) { + // if (!localStorage.getItem("noname_authorization")) { + // await gainAuthorization(); + // } + const { username = "libccy", repository = "noname", accessToken } = options; const headers = Object.assign({}, defaultHeaders); if (accessToken) { - headers['Authorization'] = `token ${accessToken}`; + headers["Authorization"] = `token ${accessToken}`; } let url = `https://api.github.com/repos/${username}/${repository}/contents/${path}`; - if (typeof branch == 'string' && branch.length > 0) { + if (typeof branch == "string" && branch.length > 0) { const pathURL = new URL(url); const searchParams = new URLSearchParams(pathURL.search.slice(1)); - if (searchParams.has('ref')) { + if (searchParams.has("ref")) { throw new TypeError(`设置了branch参数后,不应在path参数内拼接ref`); } - searchParams.append('ref', branch); + searchParams.append("ref", branch); url = pathURL.origin + pathURL.pathname + "?" + searchParams.toString(); } const response = await fetch(url, { headers }); @@ -286,13 +304,16 @@ export async function getRepoFilesList(path = '', branch, options = { username: path, sha, size, - type + type, })); -}; +} /** - * + * * 获取仓库指定分支和指定目录内的所有文件(包含子目录的文件) + * + * **注意: 此api可能会大幅度消耗请求次数,请谨慎使用** + * * @param { string } [path = ''] 路径名称(可放参数) * @param { string } [branch = ''] 仓库分支名称 * @param { Object } options @@ -307,7 +328,14 @@ export async function getRepoFilesList(path = '', branch, options = { username: * .catch(error => console.error('Failed to fetch files:', error)); * ``` */ -export async function flattenRepositoryFiles(path = '', branch, options = { username: 'libccy', repository: 'noname' }) { +export async function flattenRepositoryFiles( + path = "", + branch, + options = { username: "libccy", repository: "noname" } +) { + if (!localStorage.getItem("noname_authorization")) { + await gainAuthorization(); + } /** * @type { { download_url: string, name: string, path: string, sha: string, size: number, type: 'file' }[] } */ @@ -318,9 +346,9 @@ export async function flattenRepositoryFiles(path = '', branch, options = { user */ async function traverseDirectory(contents) { for (const item of contents) { - if (item.type === 'file') { + if (item.type === "file") { flattenedFiles.push(item); - } else if (item.type === 'dir') { + } else if (item.type === "dir") { // 获取子目录下的文件列表 const subDirFiles = await getRepoFilesList(item.path, branch, options); // 递归处理子目录中的文件和子目录 @@ -335,30 +363,36 @@ export async function flattenRepositoryFiles(path = '', branch, options = { user // 返回不含文件夹的扁平化文件列表 return allFiles; -}; +} /** - * 请求一个文件而不是直接储存为文件 - * @param { string } url - * @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress] - * @param { RequestInit } [options={}] + * 请求一个文件而不是直接储存为文件,这样可以省内存空间 + * @param { string } url + * @param { (receivedBytes: number, total?:number, filename?: string) => void } [onProgress] + * @param { RequestInit } [options={}] * @example * ```js * await getRepoTagDescription('v1.10.10').then(({ zipball_url }) => request(zipball_url)); * ``` */ export async function request(url, onProgress, options = {}) { - const response = await fetch(url, Object.assign({ - // 告诉服务器我们期望得到范围请求的支持 - headers: { 'Range': 'bytes=0-' }, - }, options)); + const response = await fetch( + url, + Object.assign( + { + // 告诉服务器我们期望得到范围请求的支持 + headers: { Range: "bytes=0-" }, + }, + options + ) + ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // @ts-ignore - let total = parseInt(response.headers.get('Content-Length'), 10); + let total = parseInt(response.headers.get("Content-Length"), 10); // 如果服务器未返回Content-Length,则无法准确计算进度 // @ts-ignore if (isNaN(total)) total = null; @@ -367,8 +401,10 @@ export async function request(url, onProgress, options = {}) { let filename; try { // @ts-ignore - filename = response.headers.get('Content-Disposition').split(';')[1].split('=')[1]; - } catch {} + filename = response.headers.get("Content-Disposition").split(";")[1].split("=")[1]; + } catch { + /* empty */ + } let receivedBytes = 0; let chunks = []; @@ -383,7 +419,7 @@ export async function request(url, onProgress, options = {}) { chunks.push(value); receivedBytes += value.length; - if (typeof onProgress == 'function') { + if (typeof onProgress == "function") { if (total) { const progress = (receivedBytes / total) * 100; onProgress(receivedBytes, progress, filename); @@ -397,99 +433,183 @@ export async function request(url, onProgress, options = {}) { const blob = new Blob(chunks); // 仅做演示,打印已合并的Blob大小 - console.log(`Download completed. Total size: ${ parseSize(blob.size) }.`); + console.log(`Download completed. Total size: ${parseSize(blob.size)}.`); return blob; -}; +} /** - * - * @param { string } [title] - * @param { string | number } [max] - * @param { string } [fileName] - * @param { string | number } [value] + * + * @param { string } [title] + * @param { string | number } [max] + * @param { string } [fileName] + * @param { string | number } [value] * @returns { progress } */ export function createProgress(title, max, fileName, value) { /** @type { progress } */ // @ts-ignore const parent = ui.create.div(ui.window, { - textAlign: 'center', - width: '300px', - height: '150px', - left: 'calc(50% - 150px)', - top: 'auto', - bottom: 'calc(50% - 75px)', - zIndex: '10', - boxShadow: 'rgb(0 0 0 / 40 %) 0 0 0 1px, rgb(0 0 0 / 20 %) 0 3px 10px', - backgroundImage: 'linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4))', - borderRadius: '8px', - overflow: 'hidden scroll' + textAlign: "center", + width: "300px", + height: "150px", + left: "calc(50% - 150px)", + top: "auto", + bottom: "calc(50% - 75px)", + zIndex: "10", + boxShadow: "rgb(0 0 0 / 40 %) 0 0 0 1px, rgb(0 0 0 / 20 %) 0 3px 10px", + backgroundImage: "linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4))", + borderRadius: "8px", + overflow: "hidden scroll", }); // 可拖动 - parent.className = 'dialog'; + parent.className = "dialog"; const container = ui.create.div(parent, { - position: 'absolute', - top: '0', - left: '0', - width: '100%', - height: '100%' + position: "absolute", + top: "0", + left: "0", + width: "100%", + height: "100%", }); container.ontouchstart = ui.click.dialogtouchStart; container.ontouchmove = ui.click.touchScroll; // @ts-ignore - container.style.WebkitOverflowScrolling = 'touch'; + container.style.WebkitOverflowScrolling = "touch"; parent.ontouchstart = ui.click.dragtouchdialog; - const caption = ui.create.div(container, '', title, { - position: 'relative', - paddingTop: '8px', - fontSize: '20px' + const caption = ui.create.div(container, "", title, { + position: "relative", + paddingTop: "8px", + fontSize: "20px", }); - ui.create.node('br', container); + ui.create.node("br", container); const tip = ui.create.div(container, { - position: 'relative', - paddingTop: '8px', - fontSize: '20px', - width: '100%' + position: "relative", + paddingTop: "8px", + fontSize: "20px", + width: "100%", }); - const file = ui.create.node('span', tip, '', fileName); - file.style.width = file.style.maxWidth = '100%'; - ui.create.node('br', tip); - const index = ui.create.node('span', tip, '', String(value || '0')); - ui.create.node('span', tip, '', '/'); - const maxSpan = ui.create.node('span', tip, '', String(max || '未知')); + const file = ui.create.node("span", tip, "", fileName); + file.style.width = file.style.maxWidth = "100%"; + ui.create.node("br", tip); + const index = ui.create.node("span", tip, "", String(value || "0")); + ui.create.node("span", tip, "", "/"); + const maxSpan = ui.create.node("span", tip, "", String(max || "未知")); - ui.create.node('br', container); + ui.create.node("br", container); - const progress = ui.create.node('progress.progress', container); - progress.setAttribute('value', value || '0'); - progress.setAttribute('max', max); + const progress = ui.create.node("progress.progress", container); + progress.setAttribute("value", value || "0"); + progress.setAttribute("max", max); parent.getTitle = () => caption.innerText; - parent.setTitle = title => caption.innerHTML = title; + parent.setTitle = (title) => (caption.innerHTML = title); parent.getFileName = () => file.innerText; - parent.setFileName = name => file.innerHTML = name; + parent.setFileName = (name) => (file.innerHTML = name); parent.getProgressValue = () => progress.value; - parent.setProgressValue = value => progress.value = index.innerHTML = value; + parent.setProgressValue = (value) => (progress.value = index.innerHTML = value); parent.getProgressMax = () => progress.max; - parent.setProgressMax = max => progress.max = maxSpan.innerHTML = max; - parent.autoSetFileNameFromArray = fileNameList => { + parent.setProgressMax = (max) => (progress.max = maxSpan.innerHTML = max); + parent.autoSetFileNameFromArray = (fileNameList) => { if (fileNameList.length > 2) { - parent.setFileName(fileNameList.slice(0, 2).concat(`......等${fileNameList.length - 2}个文件`).join('
                                      ')); + parent.setFileName( + fileNameList + .slice(0, 2) + .concat(`......等${fileNameList.length - 2}个文件`) + .join("
                                      ") + ); } else if (fileNameList.length == 2) { - parent.setFileName(fileNameList.join('
                                      ')); + parent.setFileName(fileNameList.join("
                                      ")); } else if (fileNameList.length == 1) { parent.setFileName(fileNameList[0]); } else { - parent.setFileName('当前没有正在下载的文件'); + parent.setFileName("当前没有正在下载的文件"); } }; return parent; -}; \ No newline at end of file +} + +/** + * 从GitHub存储库检索最新版本(tag),不包括特定tag。 + * + * 此函数从GitHub存储库中获取由所有者和存储库名称指定的tags列表,然后返回不是“v1998”的最新tag名称。 + * @param {string} owner GitHub上拥有存储库的用户名或组织名称。 + * @param {string} repo 要从中提取tag的存储库的名称。 + * @returns {Promise} 以最新版本tag的名称解析的promise,或者如果操作失败则以错误拒绝。 + * @throws {Error} 如果获取操作失败或找不到有效tag,将抛出错误。 + */ +export async function getLatestVersionFromGitHub(owner = "libccy", repo = "noname") { + const tags = await getRepoTags({ + username: owner, + repository: repo, + }); + + for (const tag of tags) { + const tagName = tag.name; + if (tagName === "v1998") continue; + try { + checkVersion(tagName, lib.version); + return tagName; + } catch { + // 非标准版本号 + } + } + + throw new Error("No valid tags found in the repository"); +} + +/** + * 从指定目录中的GitHub存储库中获取树 + * @param {string[]} directories 要从中获取树的目录列表 + * @param {string} version 从中获取树的版本或分支。 + * @param {string} [owner = 'libccy'] GitHub上拥有存储库的用户名或组织名称。 + * @param {string} [repo = 'noname'] GitHub存储库的名称 + * @returns {Promise<{ + * path: string; + * mode: string; + * type: "blob" | "tree"; + * sha: string; + * size: number; + * url: string; + * }[][]>} A promise that resolves with trees from the specified directories. + * @throws {Error} Will throw an error if unable to fetch the repository tree from GitHub. + */ +export async function getTreesFromGithub(directories, version, owner = "libccy", repo = "noname") { + // if (!localStorage.getItem("noname_authorization")) await gainAuthorization(); + + const treesResponse = await fetch( + `https://api.github.com/repos/${owner}/${repo}/git/trees/${version}?recursive=1`, + { + headers: defaultHeaders, + } + ); + await defaultResponse(treesResponse); + if (!treesResponse.ok) + throw new Error(`Failed to fetch the GitHub repository tree: HTTP status ${treesResponse.status}`); + /** + * @type {{ + * sha: string; + * url: string; + * tree: { + * path: string; + * mode: string; + * type: "blob" | "tree"; + * sha: string; + * size: number; + * url: string; + * }[]; + * truncated: boolean; + * }} + */ + const trees = await treesResponse.json(); + const tree = trees.tree; + return directories.map((directory) => + tree.filter(({ type, path }) => type === "blob" && path.startsWith(directory)) + ); +} diff --git a/noname/status/index.js b/noname/status/index.js index eba68cd36..4acb7f2f1 100644 --- a/noname/status/index.js +++ b/noname/status/index.js @@ -1,58 +1,91 @@ -export const status = { - paused: false, - paused2: false, - paused3: false, - over: false, - clicked: false, - auto: false, +import { lib } from "../library/index.js"; + +export class status { + paused = false; + paused2 = false; + paused3 = false; + over = false; + clicked = false; + auto = false; /** * @type { GameEventPromise } */ // @ts-ignore - event: null, - ai: {}, - lastdragchange: [], - skillaudio: [], - dieClose: [], - dragline: [], - dying: [], + event = null; + ai = {}; + lastdragchange = []; + skillaudio = []; + dieClose = []; + dragline = []; + dying = []; /** * @type { GameHistory[] } */ - globalHistory: [{ - // @ts-ignore - cardMove: [], - custom: [], - useCard: [], - changeHp: [], - everything: [], - }], - cardtag: { + globalHistory = [ + { + cardMove: [], + custom: [], + useCard: [], + changeHp: [], + everything: [], + }, + ]; + cardtag = { yingbian_zhuzhan: [], yingbian_kongchao: [], yingbian_fujia: [], yingbian_canqu: [], - yingbian_force: [] - }, - renku: [], - prehidden_skills: [], - postReconnect: {}, + yingbian_force: [], + }; + renku = []; + prehidden_skills = []; + postReconnect = {}; /** - * @type { string | void } + * @type { string | undefined } */ - extension: undefined, + extension = undefined; /** - * @type { boolean | void } + * @type { boolean | undefined } */ - dragged: undefined, + dragged = undefined; /** - * @type { boolean | void } + * @type { boolean | undefined } */ - touchconfirmed: undefined, + touchconfirmed = undefined; /** - * @type { boolean | void } + * @type { boolean | undefined } */ - connectMode: undefined, -}; + connectMode = undefined; + /** + * @type { boolean | undefined } + */ + importingExtension = undefined; + /** + * @type { Promise[] | undefined } + */ + extensionLoaded = undefined; + /** + * @type { Promise[] | undefined } + */ + extensionLoading = undefined; + /** + * @type { { [key: string]: Promise[] } | undefined } + */ + importing = undefined; + /** + * @type { Function | boolean | undefined } + */ + new_tutorial = undefined; +} -export const _status = status; \ No newline at end of file +export let _status = new status(); + +/** + * @param { InstanceType } [instance] + */ +export let setStatus = (instance) => { + _status = instance || new status(); + if (lib.config.dev) { + window._status = _status; + } +}; diff --git a/noname/ui/click/index.js b/noname/ui/click/index.js index 6f69b66f6..c87c1d0cd 100644 --- a/noname/ui/click/index.js +++ b/noname/ui/click/index.js @@ -1,46 +1,52 @@ -import { ui, game, get, lib, _status } from "../../../noname.js"; -import { Uninstantable } from "../../util/index.js"; +import { ui } from "../index.js"; +import { lib } from "../../library/index.js"; +import { game } from "../../game/index.js"; +import { get } from "../../get/index.js"; +import { _status } from "../../status/index.js"; -export class Click extends Uninstantable { +export class Click { /** * @type {() => void} */ - static consoleMenu; + consoleMenu; /** * @type {(arg0: string) => void} */ - static menuTab; - static identitycircle() { + menuTab; + /** + * @type {() => void} + */ + configMenu; + identitycircle() { var list = []; - this.classList.toggle('transparent'); + this.classList.toggle("transparent"); for (var i = 0; i < this.parentNode.childNodes.length; i++) { - if (!this.parentNode.childNodes[i].classList.contains('transparent')) { + if (!this.parentNode.childNodes[i].classList.contains("transparent")) { list.add(this.parentNode.childNodes[i].link[2]); } } var info = this.link; if (list.length == 1) { for (var i = 0; i < this.parentNode.childNodes.length; i++) { - if (!this.parentNode.childNodes[i].classList.contains('transparent')) { + if (!this.parentNode.childNodes[i].classList.contains("transparent")) { var info2 = this.parentNode.childNodes[i].link; info[0].firstChild.innerHTML = info2[1]; info[0].dataset.color = info2[2]; } } - } - else { - info[0].firstChild.innerHTML = ''; - info[0].dataset.color = ''; + } else { + info[0].firstChild.innerHTML = ""; + info[0].dataset.color = ""; ui.create.identitycircle(list, info[0].firstChild); } this._source._guozhanguess = list; } - static connectEvents() { + connectEvents() { if (this.info) { var button = this; - var layer = ui.create.div('.poplayer', ui.window); - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - this.classList.add('active'); + var layer = ui.create.div(".poplayer", ui.window); + var uiintro = ui.create.dialog("hidden", "notouchscroll"); + this.classList.add("active"); if (lib.config.touchscreen) { lib.setScroll(uiintro.contentContainer); } @@ -49,7 +55,7 @@ export class Click extends Uninstantable { this.clicked = false; return; } - button.classList.remove('active'); + button.classList.remove("active"); uiintro.delete(); this.delete(); }); @@ -57,22 +63,24 @@ export class Click extends Uninstantable { _status.clicked = true; }); uiintro.style.zIndex = 21; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); - uiintro.classList.add('onlineclient'); - uiintro.style.width = '180px'; - uiintro.style.height = '300px'; - uiintro.style.left = 'auto'; - uiintro.style.right = '20px'; - uiintro.style.top = 'auto'; - uiintro.style.bottom = '75px'; + uiintro.classList.add("popped"); + uiintro.classList.add("static"); + uiintro.classList.add("onlineclient"); + uiintro.style.width = "180px"; + uiintro.style.height = "300px"; + uiintro.style.left = "auto"; + uiintro.style.right = "20px"; + uiintro.style.top = "auto"; + uiintro.style.bottom = "75px"; uiintro.refresh = function () { if (button.focused) return; - uiintro.content.innerHTML = ''; - uiintro.addText('创建约战'); + uiintro.content.innerHTML = ""; + uiintro.addText("创建约战"); button.textnode = uiintro.content.lastChild.lastChild; - uiintro.add(''); + uiintro.add( + '' + ); uiintro.content.lastChild.style.paddingTop = 0; button.input = uiintro.content.lastChild.lastChild; button.input.onfocus = function () { @@ -90,23 +98,20 @@ export class Click extends Uninstantable { } var datenode = ui.create.div(uiintro.content); datenode.style.marginTop = 0; - datenode.style.whiteSpace = 'nowrap'; + datenode.style.whiteSpace = "nowrap"; var date = new Date(); var days = []; var currentDay = date.getDay(); if (currentDay == 0) currentDay = 7; for (var i = 1; i <= 7; i++) { if (i < currentDay) { - days.push([i.toString(), '下周' + get.cnNumber(i, true)]); - } - else if (i == 7) { - days.push([i.toString(), '周日']); - } - else if (i == currentDay) { - days.push([i.toString(), '今天']); - } - else { - days.push([i.toString(), '周' + get.cnNumber(i, true)]); + days.push([i.toString(), "下周" + get.cnNumber(i, true)]); + } else if (i == 7) { + days.push([i.toString(), "周日"]); + } else if (i == currentDay) { + days.push([i.toString(), "今天"]); + } else { + days.push([i.toString(), "周" + get.cnNumber(i, true)]); } } days = days.concat(days.splice(0, currentDay - 1)); @@ -115,19 +120,19 @@ export class Click extends Uninstantable { initday -= 7; } var daysselect = ui.create.selectlist(days, initday.toString(), datenode); - daysselect.style.width = '55px'; + daysselect.style.width = "55px"; var hours = []; for (var i = 0; i < 24; i++) { - hours.push([i.toString(), i.toString() + '点']); + hours.push([i.toString(), i.toString() + "点"]); } var hoursselect = ui.create.selectlist(hours, date.getHours().toString(), datenode); - hoursselect.style.marginLeft = '5px'; - hoursselect.style.width = '55px'; - var timeconfirm = ui.create.node('button', '确定', datenode); - timeconfirm.style.marginLeft = '5px'; + hoursselect.style.marginLeft = "5px"; + hoursselect.style.width = "55px"; + var timeconfirm = ui.create.node("button", "确定", datenode); + timeconfirm.style.marginLeft = "5px"; timeconfirm.onclick = function () { if (!button.input.value) { - alert('请填写约战标题'); + alert("请填写约战标题"); return; } var date2 = new Date(); @@ -140,25 +145,29 @@ export class Click extends Uninstantable { } var utc = date2.getTime() + deltaday * 24 * 3600000; if (utc < date.getTime()) { - alert('创建失败,时间已过'); + alert("创建失败,时间已过"); return; } if (get.is.banWords(button.input.value)) { - var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { - var that = this; - setTimeout(function () { - if (that.classList.contains('active')) { - if (confirm('确定要离开' + that.info.content + '?')) { - that.classList.remove('active'); + var eventnode = ui.create.div( + ".menubutton.videotext.onlineevent.pointerdiv", + function () { + var that = this; + setTimeout(function () { + if (that.classList.contains("active")) { + if (confirm("确定要离开" + that.info.content + "?")) { + that.classList.remove("active"); + } + } else { + if (confirm("确定要加入" + that.info.content + "?")) { + that.classList.add("active"); + } } - } - else { - if (confirm('确定要加入' + that.info.content + '?')) { - that.classList.add('active'); - } - } - }); - }, uiintro.content, 4); + }); + }, + uiintro.content, + 4 + ); var fakeinfo = { utc: utc, day: parseInt(daysselect.value), @@ -170,134 +179,134 @@ export class Click extends Uninstantable { members: [game.onlineKey], }; eventnode.info = fakeinfo; - ui.create.div('.title', fakeinfo.content, eventnode); + ui.create.div(".title", fakeinfo.content, eventnode); var str; if (fakeinfo.day < currentDay) { - str = '下周'; - } - else { - str = '周'; + str = "下周"; + } else { + str = "周"; } if (fakeinfo.day == 7) { - str += '日'; - } - else { + str += "日"; + } else { str += get.cnNumber(fakeinfo.day, true); } - str += ' '; + str += " "; var hour = fakeinfo.hour; if (hour <= 12) { if (hour <= 5) { - str += '凌晨'; + str += "凌晨"; + } else if (hour < 12) { + str += "上午"; + } else { + str += "中午"; } - else if (hour < 12) { - str += '上午'; - } - else { - str += '中午'; - } - str += fakeinfo.hour + '点'; - } - else { + str += fakeinfo.hour + "点"; + } else { if (hour <= 17) { - str += '下午'; + str += "下午"; + } else { + str += "晚上"; } - else { - str += '晚上'; - } - str += (fakeinfo.hour - 12) + '点'; + str += fakeinfo.hour - 12 + "点"; } - ui.create.div('', '已有' + (fakeinfo.members.length) + '人加入', eventnode); - ui.create.div('', '时间:' + str, eventnode); + ui.create.div("", "已有" + fakeinfo.members.length + "人加入", eventnode); + ui.create.div("", "时间:" + str, eventnode); if (fakeinfo.members.includes(game.onlineKey)) { - eventnode.classList.add('active'); + eventnode.classList.add("active"); } - button.input.value = ''; + button.input.value = ""; return; } - game.send('server', 'events', { - utc: utc, - day: parseInt(daysselect.value), - hour: parseInt(hoursselect.value), - nickname: get.connectNickname(), - avatar: lib.config.connect_avatar, - content: button.input.value - }, game.onlineKey); + game.send( + "server", + "events", + { + utc: utc, + day: parseInt(daysselect.value), + hour: parseInt(hoursselect.value), + nickname: get.connectNickname(), + avatar: lib.config.connect_avatar, + content: button.input.value, + }, + game.onlineKey + ); }; var num = 0; for (var i = 0; i < button.info.length; i++) { - if (typeof button.info[i].creator == 'string' && button.info[i].creator != game.onlineKey && get.is.banWords(button.info[i].content)) continue; + if ( + typeof button.info[i].creator == "string" && + button.info[i].creator != game.onlineKey && + get.is.banWords(button.info[i].content) + ) + continue; if (button.info[i].creator == game.onlineKey) { num++; } - var eventnode = ui.create.div('.menubutton.videotext.onlineevent.pointerdiv', function () { - var that = this; - if (typeof that.info.creator != 'string') return; - setTimeout(function () { - if (that.classList.contains('active')) { - if (confirm('确定要离开' + that.info.content + '?')) { - game.send('server', 'events', that.info.id, game.onlineKey, 'leave'); + var eventnode = ui.create.div( + ".menubutton.videotext.onlineevent.pointerdiv", + function () { + var that = this; + if (typeof that.info.creator != "string") return; + setTimeout(function () { + if (that.classList.contains("active")) { + if (confirm("确定要离开" + that.info.content + "?")) { + game.send("server", "events", that.info.id, game.onlineKey, "leave"); + } + } else { + if (confirm("确定要加入" + that.info.content + "?")) { + game.send("server", "events", that.info.id, game.onlineKey, "join"); + } } - } - else { - if (confirm('确定要加入' + that.info.content + '?')) { - game.send('server', 'events', that.info.id, game.onlineKey, 'join'); - } - } - }); - }, uiintro.content); + }); + }, + uiintro.content + ); eventnode.info = button.info[i]; - if (typeof button.info[i].creator == 'string') { - ui.create.div('.title', button.info[i].content, eventnode); + if (typeof button.info[i].creator == "string") { + ui.create.div(".title", button.info[i].content, eventnode); var str; if (button.info[i].day < currentDay) { - str = '下周'; - } - else { - str = '周'; + str = "下周"; + } else { + str = "周"; } if (button.info[i].day == 7) { - str += '日'; - } - else { + str += "日"; + } else { str += get.cnNumber(button.info[i].day, true); } - str += ' '; + str += " "; var hour = button.info[i].hour; if (hour <= 12) { if (hour <= 5) { - str += '凌晨'; + str += "凌晨"; + } else if (hour < 12) { + str += "上午"; + } else { + str += "中午"; } - else if (hour < 12) { - str += '上午'; - } - else { - str += '中午'; - } - str += button.info[i].hour + '点'; - } - else { + str += button.info[i].hour + "点"; + } else { if (hour <= 17) { - str += '下午'; + str += "下午"; + } else { + str += "晚上"; } - else { - str += '晚上'; - } - str += (button.info[i].hour - 12) + '点'; + str += button.info[i].hour - 12 + "点"; } - ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); + ui.create.div("", "创建者:" + button.info[i].nickname, eventnode); //ui.create.div('','创建者:'+(button.info[i].nickname)+'
                                      ID:'+button.info[i].creator,eventnode); - ui.create.div('', '已有' + (button.info[i].members.length) + '人加入', eventnode); - ui.create.div('', '时间:' + str, eventnode); + ui.create.div("", "已有" + button.info[i].members.length + "人加入", eventnode); + ui.create.div("", "时间:" + str, eventnode); if (button.info[i].members.includes(game.onlineKey)) { - eventnode.classList.add('active'); + eventnode.classList.add("active"); } - } - else { - ui.create.div('.title', button.info[i].title, eventnode); - ui.create.div('', button.info[i].content, eventnode); - ui.create.div('', '创建者:' + (button.info[i].nickname), eventnode); + } else { + ui.create.div(".title", button.info[i].title, eventnode); + ui.create.div("", button.info[i].content, eventnode); + ui.create.div("", "创建者:" + button.info[i].nickname, eventnode); } } if (num >= 3) { @@ -317,12 +326,12 @@ export class Click extends Uninstantable { }; } } - static connectClients() { + connectClients() { if (this.info) { var button = this; - var layer = ui.create.div('.poplayer', ui.window); - var uiintro = ui.create.dialog('hidden', 'notouchscroll'); - this.classList.add('active'); + var layer = ui.create.div(".poplayer", ui.window); + var uiintro = ui.create.dialog("hidden", "notouchscroll"); + this.classList.add("active"); if (lib.config.touchscreen) { lib.setScroll(uiintro.contentContainer); } @@ -331,7 +340,7 @@ export class Click extends Uninstantable { this.clicked = false; return; } - button.classList.remove('active'); + button.classList.remove("active"); uiintro.delete(); this.delete(); }); @@ -339,22 +348,24 @@ export class Click extends Uninstantable { _status.clicked = true; }); uiintro.style.zIndex = 21; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); - uiintro.classList.add('onlineclient'); - uiintro.style.width = '180px'; - uiintro.style.height = '300px'; - uiintro.style.left = 'auto'; - uiintro.style.right = '20px'; - uiintro.style.top = 'auto'; - uiintro.style.bottom = '75px'; + uiintro.classList.add("popped"); + uiintro.classList.add("static"); + uiintro.classList.add("onlineclient"); + uiintro.style.width = "180px"; + uiintro.style.height = "300px"; + uiintro.style.left = "auto"; + uiintro.style.right = "20px"; + uiintro.style.top = "auto"; + uiintro.style.bottom = "75px"; uiintro.refresh = function () { if (button.focused) return; - uiintro.content.innerHTML = ''; - uiintro.addText('发状态'); + uiintro.content.innerHTML = ""; + uiintro.addText("发状态"); button.textnode = uiintro.content.lastChild.lastChild; - uiintro.add(''); + uiintro.add( + '' + ); uiintro.content.lastChild.style.paddingTop = 0; button.input = uiintro.content.lastChild.lastChild; button.input.onfocus = function () { @@ -372,27 +383,26 @@ export class Click extends Uninstantable { } button.input.onkeydown = function (e) { if (e.keyCode == 13 && !this.disabled) { - game.send('server', 'status', this.value); + game.send("server", "status", this.value); this.blur(); this.disabled = true; this.style.opacity = 0.6; - button.textnode.innerHTML = '发状态(10)'; + button.textnode.innerHTML = "发状态(10)"; button.intervaltext = button.textnode.innerHTML; var num = 10; var that = this; button.input.disabled = true; button.input.style.opacity = 0.6; - this.value = ''; + this.value = ""; button.interval = setInterval(function () { num--; if (num > 0) { - button.textnode.innerHTML = '发状态(' + num + ')'; + button.textnode.innerHTML = "发状态(" + num + ")"; button.intervaltext = button.textnode.innerHTML; - } - else { - button.textnode.innerHTML = '发状态'; + } else { + button.textnode.innerHTML = "发状态"; button.input.disabled = false; - button.input.style.opacity = ''; + button.input.style.opacity = ""; clearInterval(button.interval); delete button.interval; delete button.intervaltext; @@ -402,23 +412,32 @@ export class Click extends Uninstantable { }; for (var i = 0; i < button.info.length; i++) { - var node = ui.create.div('.menubutton.videonode.pointerdiv', uiintro.content); - ui.create.div('.menubutton.videoavatar', node).setBackground(button.info[i][1] || 'caocao', 'character'); + var node = ui.create.div(".menubutton.videonode.pointerdiv", uiintro.content); + ui.create + .div(".menubutton.videoavatar", node) + .setBackground(button.info[i][1] || "caocao", "character"); if (button.info[i][4] == game.wsid) { - ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); node.isme = true; - } - else if (button.info[i][2]) { - ui.create.div('.name', (button.info[i][0] || '无名玩家'), node); - } - else { - ui.create.div('.name', '' + (button.info[i][0] || '无名玩家'), node); + ui.create.div( + ".name", + '' + (button.info[i][0] || "无名玩家"), + node + ); + node.isme = true; + } else if (button.info[i][2]) { + ui.create.div(".name", button.info[i][0] || "无名玩家", node); + } else { + ui.create.div( + ".name", + '' + (button.info[i][0] || "无名玩家"), + node + ); } //show ID //ui.create.div('.videostatus',node,button.info[i][5]); //node.classList.add('videonodestatus'); if (button.info[i][3]) { - ui.create.div('.videostatus', node, button.info[i][3].slice(0, 80)); - node.classList.add('videonodestatus'); + ui.create.div(".videostatus", node, button.info[i][3].slice(0, 80)); + node.classList.add("videonodestatus"); } } }; @@ -432,19 +451,18 @@ export class Click extends Uninstantable { }; } } - static autoskin() { + autoskin() { if (!lib.config.change_skin) return; var players = game.filterPlayer(); var change = function (player, num, callback) { - if (num == '1') { + if (num == "1") { ui.click.skin(player.node.avatar, player.name, callback); - } - else { + } else { ui.click.skin(player.node.avatar2, player.name2, callback); } }; var finish = function () { - if (lib.config.change_skin_auto != 'off') { + if (lib.config.change_skin_auto != "off") { _status.skintimeout = setTimeout(ui.click.autoskin, parseInt(lib.config.change_skin_auto)); } }; @@ -453,41 +471,37 @@ export class Click extends Uninstantable { var player = players.randomRemove(); var list = []; if (player.name && !player.isUnseen(0)) { - list.push('1'); + list.push("1"); } if (player.name2 && !player.isUnseen(1)) { - list.push('2'); + list.push("2"); } if (list.length) { change(player, list.randomRemove(), function (bool) { if (bool) { finish(); - } - else if (list.length) { + } else if (list.length) { change(player, list[0], function (bool) { if (bool) { finish(); - } - else { + } else { autoskin(); } }); - } - else { + } else { autoskin(); } }); - } - else { + } else { autoskin(); } } }; autoskin(); } - static skin(avatar, name, callback) { + skin(avatar, name, callback) { var num = 1; - if (name.startsWith('gz_')) { + if (name.startsWith("gz_")) { name = name.slice(3); } if (lib.config.skin[name]) { @@ -497,7 +511,7 @@ export class Click extends Uninstantable { var finish = function (bool) { var player = avatar.parentNode; if (bool) { - fakeavatar.style.boxShadow = 'none'; + fakeavatar.style.boxShadow = "none"; player.insertBefore(fakeavatar, avatar.nextSibling); setTimeout(function () { fakeavatar.delete(); @@ -513,24 +527,23 @@ export class Click extends Uninstantable { var img = new Image(); img.onload = function () { lib.config.skin[name] = num; - game.saveConfig('skin', lib.config.skin); + game.saveConfig("skin", lib.config.skin); avatar.style.backgroundImage = 'url("' + img.src + '")'; finish(true); }; img.onerror = function () { if (lib.config.skin[name]) { finish(true); - } - else { + } else { finish(false); } delete lib.config.skin[name]; - game.saveConfig('skin', lib.config.skin); - avatar.setBackground(name, 'character'); + game.saveConfig("skin", lib.config.skin); + avatar.setBackground(name, "character"); }; - img.src = lib.assetURL + 'image/skin/' + name + '/' + num + '.jpg'; + img.src = lib.assetURL + "image/skin/" + name + "/" + num + ".jpg"; } - static touchpop(forced) { + touchpop(forced) { if (lib.config.touchscreen || forced) { _status.touchpopping = true; clearTimeout(_status.touchpoppingtimeout); @@ -539,75 +552,69 @@ export class Click extends Uninstantable { }, 600); } } - static exit() { + exit() { if (game.servermode && lib.config.reconnect_info && _status.over) { if (!_status.roomtimeout) { lib.config.reconnect_info[2] = game.roomId; - game.saveConfig('reconnect_info', lib.config.reconnect_info); + game.saveConfig("reconnect_info", lib.config.reconnect_info); } game.reload(); return; - } - else { - if (typeof game.roomId != 'string') { - game.saveConfig('reconnect_info'); + } else { + if (typeof game.roomId != "string") { + game.saveConfig("reconnect_info"); } } if (!ui.exit || !ui.exit.stay) { if (lib.config.reconnect_info) { lib.config.reconnect_info.length = 1; - game.saveConfig('reconnect_info', lib.config.reconnect_info); + game.saveConfig("reconnect_info", lib.config.reconnect_info); } - game.saveConfig('tmp_user_roomId', undefined, false, function () { + game.saveConfig("tmp_user_roomId", undefined, false, function () { game.reload(); }); - } - else { + } else { game.reload(); } } - static shortcut(show) { + shortcut(show) { if (show === false) { - ui.shortcut.classList.add('hidden'); + ui.shortcut.classList.add("hidden"); + } else { + ui.shortcut.classList.toggle("hidden"); } - else { - ui.shortcut.classList.toggle('hidden'); - } - if (ui.shortcut.classList.contains('hidden')) { - ui.favmode.style.display = 'none'; - if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { - document.body.classList.remove('statusbar'); + if (ui.shortcut.classList.contains("hidden")) { + ui.favmode.style.display = "none"; + if (window.StatusBar && lib.config.show_statusbar_ios == "auto") { + document.body.classList.remove("statusbar"); window.StatusBar.hide(); } - ui.window.classList.remove('shortcutpaused'); - } - else { + ui.window.classList.remove("shortcutpaused"); + } else { if (lib.config.show_favmode) { - ui.favmode.style.display = ''; + ui.favmode.style.display = ""; } - if (window.StatusBar && lib.config.show_statusbar_ios == 'auto') { - document.body.classList.add('statusbar'); + if (window.StatusBar && lib.config.show_statusbar_ios == "auto") { + document.body.classList.add("statusbar"); window.StatusBar.overlaysWebView(true); - window.StatusBar.backgroundColorByName('black'); + window.StatusBar.backgroundColorByName("black"); window.StatusBar.show(); } if (_status.auto) { - ui.shortcut.autobutton.classList.add('active'); + ui.shortcut.autobutton.classList.add("active"); + } else { + ui.shortcut.autobutton.classList.remove("active"); } - else { - ui.shortcut.autobutton.classList.remove('active'); - } - ui.window.classList.add('shortcutpaused'); + ui.window.classList.add("shortcutpaused"); } } - static favouriteCharacter(e) { - if (typeof this.link == 'string') { - if (this.innerHTML == '添加收藏') { - this.innerHTML = '移除收藏'; + favouriteCharacter(e) { + if (typeof this.link == "string") { + if (this.innerHTML == "添加收藏") { + this.innerHTML = "移除收藏"; lib.config.favouriteCharacter.add(this.link); - } - else { - this.innerHTML = '添加收藏'; + } else { + this.innerHTML = "添加收藏"; lib.config.favouriteCharacter.remove(this.link); } if (ui.favouriteCharacter) { @@ -618,16 +625,18 @@ export class Click extends Uninstantable { } } if (i == ui.favouriteCharacter.childElementCount) { - ui.create.button(this.link, 'character', ui.favouriteCharacter).listen(function (e) { - this._banning = 'offline'; - ui.click.touchpop(); - ui.click.intro.call(this, e); - _status.clicked = false; - delete this._banning; - }).classList.add('noclick'); + ui.create + .button(this.link, "character", ui.favouriteCharacter) + .listen(function (e) { + this._banning = "offline"; + ui.click.touchpop(); + ui.click.intro.call(this, e); + _status.clicked = false; + delete this._banning; + }) + .classList.add("noclick"); } - } - else { + } else { for (var i = 0; i < ui.favouriteCharacter.childElementCount; i++) { if (ui.favouriteCharacter.childNodes[i].link == this.link) { ui.favouriteCharacter.childNodes[i].remove(); @@ -639,21 +648,21 @@ export class Click extends Uninstantable { for (var i = 0; i < lib.config.favouriteCharacter.length; i++) { var favname = lib.config.favouriteCharacter[i]; if (lib.character[favname]) { - shownode = true; break; + shownode = true; + break; } } if (shownode) { - ui.favouriteCharacter.node.style.display = ''; - } - else { - ui.favouriteCharacter.node.style.display = 'none'; + ui.favouriteCharacter.node.style.display = ""; + } else { + ui.favouriteCharacter.node.style.display = "none"; } } - game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); + game.saveConfig("favouriteCharacter", lib.config.favouriteCharacter); } e.stopPropagation(); } - static buttonnameenter() { + buttonnameenter() { if (this.buttonscrollinterval) { clearInterval(this.buttonscrollinterval); } @@ -665,19 +674,17 @@ export class Click extends Uninstantable { if (node.scrollTop + node.offsetHeight >= node.scrollHeight) { clearInterval(that.buttonscrollinterval); delete that.buttonscrollinterval; - } - else { + } else { if (num > 0) { num--; - } - else { + } else { node.scrollTop += 2; } } }, 16); } } - static buttonnameleave() { + buttonnameleave() { if (this.buttonscrollinterval) { clearInterval(this.buttonscrollinterval); } @@ -688,17 +695,14 @@ export class Click extends Uninstantable { if (node.scrollTop == 0) { clearInterval(that.buttonscrollinterval); delete that.buttonscrollinterval; - } - else { + } else { node.scrollTop -= 2; } }, 16); } } - static dragtouchdialog(e) { - if (e.touches.length > 1 && - !this.classList.contains('popped') && - !this.classList.contains('fixed')) { + dragtouchdialog(e) { + if (e.touches.length > 1 && !this.classList.contains("popped") && !this.classList.contains("fixed")) { _status.draggingtouchdialog = this; this._dragorigin = { clientX: e.touches[0].clientX, @@ -712,17 +716,23 @@ export class Click extends Uninstantable { e.stopPropagation(); } } - static identity(e) { + identity(e) { if (_status.dragged) return; _status.clicked = true; if (!game.getIdentityList) return; if (_status.video) return; if (this.parentNode.forceShown) return; - if (!_status.connectMode && this.parentNode.ai.stratagem_camouflage && get.config('nei_auto_mark_camouflage') && game.me.identity == 'nei') return; + if ( + !_status.connectMode && + this.parentNode.ai.stratagem_camouflage && + get.config("nei_auto_mark_camouflage") && + game.me.identity == "nei" + ) + return; if (_status.clickingidentity) { for (var i = 0; i < _status.clickingidentity[1].length; i++) { _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform = ''; + _status.clickingidentity[1][i].style.transform = ""; } if (_status.clickingidentity[0] == this.parentNode) { delete _status.clickingidentity; @@ -731,7 +741,7 @@ export class Click extends Uninstantable { } var list = game.getIdentityList(this.parentNode); if (!list) return; - if (lib.config.mark_identity_style == 'click') { + if (lib.config.mark_identity_style == "click") { var list2 = []; for (var i in list) { list2.push(i); @@ -744,11 +754,10 @@ export class Click extends Uninstantable { break; } } - } - else { - if (get.mode() == 'guozhan') { - list = { wei: '魏', shu: '蜀', wu: '吴', qun: '群', jin: '晋' }; - if (_status.forceKey) list.key = '键'; + } else { + if (get.mode() == "guozhan") { + list = { wei: "魏", shu: "蜀", wu: "吴", qun: "群", jin: "晋" }; + if (_status.forceKey) list.key = "键"; } var list2 = get.copy(list); if (game.getIdentityList2) { @@ -756,41 +765,38 @@ export class Click extends Uninstantable { } var rect = this.parentNode.getBoundingClientRect(); this._customintro = function (uiintro) { - if (get.mode() == 'guozhan') { + if (get.mode() == "guozhan") { uiintro.clickintro = true; - } - else { + } else { uiintro.touchclose = true; } // if(lib.config.theme!='woodden'){ - uiintro.classList.add('woodbg'); + uiintro.classList.add("woodbg"); // } if (get.is.phoneLayout()) { - uiintro.style.width = '100px'; - } - else { - uiintro.style.width = '85px'; + uiintro.style.width = "100px"; + } else { + uiintro.style.width = "85px"; } var source = this.parentNode; for (var i in list) { var node = ui.create.div(); - node.classList.add('guessidentity'); - node.classList.add('pointerdiv'); - ui.create.div('.menubutton.large', list2[i], node); + node.classList.add("guessidentity"); + node.classList.add("pointerdiv"); + ui.create.div(".menubutton.large", list2[i], node); if (!get.is.phoneLayout()) { - node.firstChild.style.fontSize = '24px'; - node.firstChild.style.lineHeight = '24px'; + node.firstChild.style.fontSize = "24px"; + node.firstChild.style.lineHeight = "24px"; } - if (get.mode() == 'guozhan') { + if (get.mode() == "guozhan") { if (source._guozhanguess) { if (!source._guozhanguess.includes(i)) { - node.classList.add('transparent'); + node.classList.add("transparent"); } } node._source = source; node.listen(ui.click.identitycircle); - } - else { + } else { node.listen(function () { var info = this.link; info[0].firstChild.innerHTML = info[1]; @@ -805,8 +811,8 @@ export class Click extends Uninstantable { }; ui.click.touchpop(); ui.click.intro.call(this, { - clientX: (rect.left + rect.width), - clientY: (rect.top) + clientX: rect.left + rect.width, + clientY: rect.top, }); // var nodes=[]; // _status.clickingidentity=[this.parentNode,nodes]; @@ -835,7 +841,7 @@ export class Click extends Uninstantable { // } } } - static identity2() { + identity2() { if (_status.clickingidentity) { _status.clicked = true; var player = _status.clickingidentity[0]; @@ -844,57 +850,57 @@ export class Click extends Uninstantable { player.node.identity.firstChild.innerHTML = this.firstChild.innerHTML; for (var i = 0; i < nodes.length; i++) { nodes[i].delete(); - nodes[i].style.transform = ''; + nodes[i].style.transform = ""; } delete _status.clickingidentity; } } - static roundmenu() { + roundmenu() { game.closeConnectMenu(); switch (lib.config.round_menu_func) { - case 'system': + case "system": game.closePopped(); - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); + ui.system1.classList.add("shown"); + ui.system2.classList.add("shown"); game.closeMenu(); ui.click.shortcut(); break; - case 'menu': + case "menu": if (ui.click.configMenu) { game.closePopped(); game.pause2(); ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); + ui.system1.classList.remove("shown"); + ui.system2.classList.remove("shown"); } break; - case 'pause': + case "pause": ui.click.pause(); break; - case 'auto': + case "auto": ui.click.auto(); break; } _status.clicked = true; } - static pausehistory() { + pausehistory() { if (!lib.config.auto_popped_history) return; if (!ui.sidebar.childNodes.length) return; - var uiintro = ui.create.dialog('hidden'); - uiintro.style.maxHeight = '400px'; + var uiintro = ui.create.dialog("hidden"); + uiintro.style.maxHeight = "400px"; uiintro.add(ui.sidebar); return uiintro; } - static pauseconfig() { + pauseconfig() { if (!lib.config.auto_popped_config) return; if (get.is.phoneLayout()) return; - var uiintro = ui.create.dialog('hidden'); + var uiintro = ui.create.dialog("hidden"); uiintro.listen(function (e) { e.stopPropagation(); }); var rows = Math.floor(lib.config.all.mode.length / 3); - uiintro.type = 'config'; + uiintro.type = "config"; var modes = lib.config.modeorder || lib.config.all.mode.slice(0); for (var i = 0; i < modes.length; i++) { if (!lib.config.all.mode.includes(modes[i])) { @@ -902,15 +908,20 @@ export class Click extends Uninstantable { } } for (var k = 0; k < rows; k++) { - var node = ui.create.div('.newgame.pointernode'); + var node = ui.create.div(".newgame.pointernode"); for (var i = 0; i < 3 && i + k * 3 < modes.length; i++) { var thismode = modes[i + k * 3]; - var div = ui.create.div(thismode == (_status.sourcemode || lib.config.mode) ? '.underlinenode.on' : '.underlinenode', node); + var div = ui.create.div( + thismode == (_status.sourcemode || lib.config.mode) + ? ".underlinenode.on" + : ".underlinenode", + node + ); div.innerHTML = lib.translate[thismode]; div.link = thismode; - div.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { - game.saveConfig('mode', this.link); - localStorage.setItem(lib.configprefix + 'directstart', true); + div.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { + game.saveConfig("mode", this.link); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); }); } @@ -919,66 +930,69 @@ export class Click extends Uninstantable { return uiintro; } - static cardPileButton() { - var uiintro = ui.create.dialog('hidden'); + cardPileButton() { + var uiintro = ui.create.dialog("hidden"); uiintro.listen(function (e) { e.stopPropagation(); }); var num; if (game.online) { num = _status.cardPileNum || 0; - } - else { + } else { num = ui.cardPile.childNodes.length; } - uiintro.add('剩余 ' + num); + uiintro.add('剩余 ' + num); if (_status.connectMode) return uiintro; - uiintro.add('
                                      轮数 ' + game.roundNumber + '    洗牌 ' + game.shuffleNumber + '
                                      '); + uiintro.add( + '
                                      轮数 ' + + game.roundNumber + + '    洗牌 ' + + game.shuffleNumber + + "
                                      " + ); uiintro.add('
                                      弃牌堆
                                      '); if (ui.discardPile.childNodes.length) { var list = []; for (var i = 0; i < ui.discardPile.childNodes.length; i++) { list.unshift(ui.discardPile.childNodes[i]); } - uiintro.addSmall([list, 'card']); - } - else { + uiintro.addSmall([list, "card"]); + } else { uiintro.add('
                                      '); } return uiintro; } - static chat() { - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); + chat() { + ui.system1.classList.add("shown"); + ui.system2.classList.add("shown"); - var uiintro = ui.create.dialog('hidden'); + var uiintro = ui.create.dialog("hidden"); uiintro.listen(function (e) { e.stopPropagation(); }); - var list = ui.create.div('.caption'); + var list = ui.create.div(".caption"); if (get.is.phoneLayout()) { - list.style.maxHeight = '110px'; + list.style.maxHeight = "110px"; + } else { + list.style.maxHeight = "220px"; } - else { - list.style.maxHeight = '220px'; - } - list.style.overflow = 'scroll'; + list.style.overflow = "scroll"; lib.setScroll(list); - uiintro.contentContainer.style.overflow = 'hidden'; + uiintro.contentContainer.style.overflow = "hidden"; var input; var addEntry = function (info, clear) { if (list._chatempty) { - list.innerHTML = ''; + list.innerHTML = ""; delete list._chatempty; } - var node = ui.create.div('.text.chat'); - node.innerHTML = info[0] + ': ' + info[1]; + var node = ui.create.div(".text.chat"); + node.innerHTML = info[0] + ": " + info[1]; list.appendChild(node); list.scrollTop = list.scrollHeight; - uiintro.style.height = uiintro.content.scrollHeight + 'px'; + uiintro.style.height = uiintro.content.scrollHeight + "px"; }; _status.addChatEntry = addEntry; _status.addChatEntry._origin = uiintro; @@ -986,21 +1000,20 @@ export class Click extends Uninstantable { for (var i = 0; i < lib.chatHistory.length; i++) { addEntry(lib.chatHistory[i]); } - } - else { + } else { list._chatempty = true; - list.appendChild(ui.create.div('.text.center', '无聊天记录')); + list.appendChild(ui.create.div(".text.center", "无聊天记录")); } uiintro.add(list); - uiintro.style.height = uiintro.content.offsetHeight + 'px'; + uiintro.style.height = uiintro.content.offsetHeight + "px"; list.scrollTop = list.scrollHeight; - if (!_status.chatValue) _status.chatValue = ''; + if (!_status.chatValue) _status.chatValue = ""; var node = uiintro.add(''); node.style.paddingTop = 0; - node.style.marginBottom = '16px'; + node.style.marginBottom = "16px"; input = node.firstChild; - input.style.width = 'calc(100% - 20px)'; + input.style.width = "calc(100% - 20px)"; input.onchange = function () { _status.chatValue = input.value; }; @@ -1013,11 +1026,11 @@ export class Click extends Uninstantable { if (game.online) { for (var i = 0; i < game.connectPlayers.length; i++) { if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; + player = game.connectPlayers[i]; + break; } } - } - else { + } else { player = game.connectPlayers[0]; } } @@ -1025,18 +1038,16 @@ export class Click extends Uninstantable { if (!player) return; if (get.is.banWords(input.value)) { player.say(input.value); - input.value = ''; - _status.chatValue = ''; - } - else { + input.value = ""; + _status.chatValue = ""; + } else { if (game.online) { - game.send('chat', game.onlineID, str); - } - else { + game.send("chat", game.onlineID, str); + } else { player.chat(str); } - input.value = ''; - _status.chatValue = ''; + input.value = ""; + _status.chatValue = ""; } } e.stopPropagation(); @@ -1046,100 +1057,109 @@ export class Click extends Uninstantable { list.scrollTop = list.scrollHeight; }; uiintro._heightfixed = true; - var emotionTitle = ui.create.div('.text.center', '聊天表情', function () { - if (emotionTitle.innerHTML == '快捷语音') { - emotionTitle.innerHTML = '聊天表情'; + var emotionTitle = ui.create.div(".text.center", "聊天表情", function () { + if (emotionTitle.innerHTML == "快捷语音") { + emotionTitle.innerHTML = "聊天表情"; list2.remove(); list3.remove(); uiintro.add(list1); while (list2.childNodes.length) { list2.firstChild.remove(); } - } - else { - emotionTitle.innerHTML = '快捷语音'; + } else { + emotionTitle.innerHTML = "快捷语音"; list1.remove(); list2.remove(); uiintro.add(list3); } }); uiintro.add(emotionTitle); - var list1 = ui.create.div(''); + var list1 = ui.create.div(""); if (get.is.phoneLayout()) { - list1.style.height = '110px'; + list1.style.height = "110px"; + } else { + list1.style.height = "150px"; } - else { - list1.style.height = '150px'; - } - list1.style.overflow = 'scroll'; + list1.style.overflow = "scroll"; lib.setScroll(list1); uiintro.add(list1); - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - var list2 = ui.create.div(''); + uiintro.style.height = uiintro.content.scrollHeight + "px"; + var list2 = ui.create.div(""); if (get.is.phoneLayout()) { - list2.style.height = '110px'; + list2.style.height = "110px"; + } else { + list2.style.height = "150px"; } - else { - list2.style.height = '150px'; - } - list2.style.overflow = 'scroll'; + list2.style.overflow = "scroll"; lib.setScroll(list2); //uiintro.add(list2); for (var i in lib.emotionList) { - var emotionPack = ui.create.div('.card.fullskin', '', function () { - emotionTitle.innerHTML = get.translation(this.pack); - for (var j = 1; j <= lib.emotionList[this.pack]; j++) { - var emotionButton = ui.create.div('.card.fullskin', '', function () { - var player = game.me; - if (!player) { - if (game.connectPlayers) { - if (game.online) { - for (var i = 0; i < game.connectPlayers.length; i++) { - if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; + var emotionPack = ui.create.div( + ".card.fullskin", + '', + function () { + emotionTitle.innerHTML = get.translation(this.pack); + for (var j = 1; j <= lib.emotionList[this.pack]; j++) { + var emotionButton = ui.create.div( + ".card.fullskin", + '', + function () { + var player = game.me; + if (!player) { + if (game.connectPlayers) { + if (game.online) { + for (var i = 0; i < game.connectPlayers.length; i++) { + if (game.connectPlayers[i].playerid == game.onlineID) { + player = game.connectPlayers[i]; + break; + } + } + } else { + player = game.connectPlayers[0]; } } } - else { - player = game.connectPlayers[0]; + if (!player) return; + if (game.online) { + game.send("emotion", game.onlineID, this.pack, this.emotionID); + } else { + player.emotion(this.pack, this.emotionID); } } - } - if (!player) return; - if (game.online) { - game.send('emotion', game.onlineID, this.pack, this.emotionID); - } - else { - player.emotion(this.pack, this.emotionID); - } - }); - emotionButton.emotionID = j; - emotionButton.pack = this.pack; - emotionButton.style.height = '50px'; - emotionButton.style.width = '50px'; - list2.appendChild(emotionButton); + ); + emotionButton.emotionID = j; + emotionButton.pack = this.pack; + emotionButton.style.height = "50px"; + emotionButton.style.width = "50px"; + list2.appendChild(emotionButton); + } + list1.remove(); + uiintro.add(list2); } - list1.remove(); - uiintro.add(list2); - }); + ); emotionPack.pack = i; - emotionPack.style.height = '50px'; - emotionPack.style.width = '50px'; + emotionPack.style.height = "50px"; + emotionPack.style.width = "50px"; list1.appendChild(emotionPack); } list1.scrollTop = list1.scrollHeight; - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - var list3 = ui.create.div('.caption'); + uiintro.style.height = uiintro.content.scrollHeight + "px"; + var list3 = ui.create.div(".caption"); if (get.is.phoneLayout()) { - list3.style.height = '110px'; + list3.style.height = "110px"; + } else { + list3.style.height = "150px"; } - else { - list3.style.height = '150px'; - } - list3.style.overflow = 'scroll'; + list3.style.overflow = "scroll"; lib.setScroll(list3); for (var i = 0; i < lib.quickVoice.length; i++) { - var node = ui.create.div('.text.chat', function () { + var node = ui.create.div(".text.chat", function () { var player = game.me; var str = this.innerHTML; if (!player) { @@ -1147,20 +1167,19 @@ export class Click extends Uninstantable { if (game.online) { for (var i = 0; i < game.connectPlayers.length; i++) { if (game.connectPlayers[i].playerid == game.onlineID) { - player = game.connectPlayers[i]; break; + player = game.connectPlayers[i]; + break; } } - } - else { + } else { player = game.connectPlayers[0]; } } } if (!player) return; if (game.online) { - game.send('chat', game.onlineID, str); - } - else { + game.send("chat", game.onlineID, str); + } else { player.chat(str); } }); @@ -1170,81 +1189,77 @@ export class Click extends Uninstantable { list3.scrollTop = list1.scrollHeight; return uiintro; } - static volumn() { - var uiintro = ui.create.dialog('hidden'); + volumn() { + var uiintro = ui.create.dialog("hidden"); uiintro.listen(function (e) { e.stopPropagation(); }); - uiintro.add('背景音乐'); - var vol1 = ui.create.div('.volumn'); + uiintro.add("背景音乐"); + var vol1 = ui.create.div(".volumn"); uiintro.add(vol1); for (var i = 0; i < 8; i++) { - var span = document.createElement('span'); + var span = document.createElement("span"); span.link = i + 1; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_background); + span.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.volumn_background); if (i < lib.config.volumn_background) { - span.innerHTML = '●'; - } - else { - span.innerHTML = '○'; + span.innerHTML = "●"; + } else { + span.innerHTML = "○"; } vol1.appendChild(span); } - uiintro.add('游戏音效'); + uiintro.add("游戏音效"); - var vol2 = ui.create.div('.volumn'); + var vol2 = ui.create.div(".volumn"); uiintro.add(vol2); for (var i = 0; i < 8; i++) { - var span = document.createElement('span'); + var span = document.createElement("span"); span.link = i + 1; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.volumn_audio); + span.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.volumn_audio); if (i < lib.config.volumn_audio) { - span.innerHTML = '●'; - } - else { - span.innerHTML = '○'; + span.innerHTML = "●"; + } else { + span.innerHTML = "○"; } vol2.appendChild(span); } - uiintro.add(ui.create.div('.placeholder')); + uiintro.add(ui.create.div(".placeholder")); return uiintro; } - static volumn_background(e) { + volumn_background(e) { if (_status.dragged) return; var volume = this.link; if (volume === 1 && lib.config.volumn_background === 1) { volume = 0; } - game.saveConfig('volumn_background', volume); + game.saveConfig("volumn_background", volume); ui.backgroundMusic.volume = volume / 8; for (var i = 0; i < 8; i++) { if (i < lib.config.volumn_background) { - this.parentNode.childNodes[i].innerHTML = '●'; - } - else { - this.parentNode.childNodes[i].innerHTML = '○'; + this.parentNode.childNodes[i].innerHTML = "●"; + } else { + this.parentNode.childNodes[i].innerHTML = "○"; } } e.stopPropagation(); } - static volumn_audio(e) { + volumn_audio(e) { if (_status.dragged) return; var volume = this.link; if (volume === 1 && lib.config.volumn_audio === 1) { volume = 0; } - game.saveConfig('volumn_audio', volume); + game.saveConfig("volumn_audio", volume); for (var i = 0; i < 8; i++) { if (i < lib.config.volumn_audio) { - this.parentNode.childNodes[i].innerHTML = '●'; - } - else { - this.parentNode.childNodes[i].innerHTML = '○'; + this.parentNode.childNodes[i].innerHTML = "●"; + } else { + this.parentNode.childNodes[i].innerHTML = "○"; } } e.stopPropagation(); } - static hoverpopped() { + hoverpopped() { if (this._uiintro) { return; } @@ -1259,46 +1274,43 @@ export class Click extends Uninstantable { delete ui.currentpopped._uiintro; } ui.currentpopped = this; - uiintro.classList.add('popped'); - uiintro.classList.add('hoverdialog'); - uiintro.classList.add('static'); + uiintro.classList.add("popped"); + uiintro.classList.add("hoverdialog"); + uiintro.classList.add("static"); this._uiintro = uiintro; ui.window.appendChild(uiintro); var width = this._poppedwidth || 330; - uiintro.style.width = width + 'px'; + uiintro.style.width = width + "px"; if (get.is.phoneLayout()) { width *= 1.3; } if (uiintro._heightfixed) { - uiintro.style.height = uiintro.content.scrollHeight + 'px'; - } - else { + uiintro.style.height = uiintro.content.scrollHeight + "px"; + } else { var height = this._poppedheight || uiintro.content.scrollHeight; var height2 = ui.window.offsetHeight - 260; if (get.is.phoneLayout()) { height2 = (ui.window.offsetHeight - 80) / 1.3; } - uiintro.style.height = Math.min(height2, height) + 'px'; + uiintro.style.height = Math.min(height2, height) + "px"; } if (get.is.phoneLayout()) { - uiintro.style.top = '70px'; - } - else { - uiintro.style.top = '50px'; + uiintro.style.top = "70px"; + } else { + uiintro.style.top = "50px"; } var left = this.parentNode.offsetLeft + this.offsetLeft + this.offsetWidth / 2 - width / 2; if (left < 10) { left = 10; - } - else if (left + width > ui.window.offsetWidth - 10) { + } else if (left + width > ui.window.offsetWidth - 10) { left = ui.window.offsetWidth - width - 10; } - uiintro.style.left = left + 'px'; + uiintro.style.left = left + "px"; uiintro._poppedorigin = this; if (!lib.config.touchscreen) { - uiintro.addEventListener('mouseleave', ui.click.leavehoverpopped); + uiintro.addEventListener("mouseleave", ui.click.leavehoverpopped); } ui.click.shortcut(false); if (uiintro._onopen) { @@ -1306,8 +1318,8 @@ export class Click extends Uninstantable { } if (this._paused2 && !lib.config.touchscreen) { game.pause2(); - uiintro.classList.add('static'); - var layer = ui.create.div('.poplayer', ui.window); + uiintro.classList.add("static"); + var layer = ui.create.div(".poplayer", ui.window); var clicklayer = function (e) { uiintro.delete(); layer.remove(); @@ -1318,16 +1330,16 @@ export class Click extends Uninstantable { uiintro.style.zIndex = 21; layer.onclick = clicklayer; layer.oncontextmenu = clicklayer; - uiintro.addEventListener('mouseleave', clicklayer); - uiintro.addEventListener('click', clicklayer); + uiintro.addEventListener("mouseleave", clicklayer); + uiintro.addEventListener("click", clicklayer); } } - static hoverpopped_leave() { + hoverpopped_leave() { this._poppedalready = false; } - static leavehoverpopped() { + leavehoverpopped() { if (_status.dragged) return; - if (this.classList.contains('noleave')) return; + if (this.classList.contains("noleave")) return; this.delete(); var button = this._poppedorigin; @@ -1337,27 +1349,25 @@ export class Click extends Uninstantable { delete button._uiintro; } }, 500); - } - static dierevive() { + dierevive() { if (game.me.isDead()) { game.me.revive(Math.max(1, game.me.maxHp)); game.me.draw(2); - } - else { + } else { if (ui.revive) { ui.revive.close(); delete ui.revive; } } } - static dieswap() { + dieswap() { if (game.me.isDead()) { _status.clicked = true; var i, translation, intro, str; if (ui.intro) { ui.intro.close(); - if (ui.intro.source == 'dieswap') { + if (ui.intro.source == "dieswap") { delete ui.intro; ui.control.show(); game.resume2(); @@ -1367,7 +1377,7 @@ export class Click extends Uninstantable { game.pause2(); ui.control.hide(); ui.intro = ui.create.dialog(); - ui.intro.source = 'dieswap'; + ui.intro.source = "dieswap"; var players = []; for (var i = 0; i < game.players.length; i++) { @@ -1376,48 +1386,51 @@ export class Click extends Uninstantable { } } ui.intro.add(players, true); - var buttons = ui.intro.querySelectorAll('.button'); + var buttons = ui.intro.querySelectorAll(".button"); for (var i = 0; i < buttons.length; i++) { - buttons[i].addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.dieswap2); + buttons[i].addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.dieswap2); } - } - else { + } else { if (ui.swap) { ui.swap.close(); delete ui.swap; } } } - static dieswap2() { + dieswap2() { if (_status.dragged) return; game.swapPlayer(this.link); } - static touchconfirm() { + touchconfirm() { _status.touchconfirmed = true; - document.removeEventListener('touchstart', ui.click.touchconfirm); + document.removeEventListener("touchstart", ui.click.touchconfirm); } - static windowtouchstart(e) { + windowtouchstart(e) { if (window.inSplash) return; if (e.touches[0] && lib.config.swipe && e.touches.length < 2) { _status._swipeorigin = { clientX: e.touches[0].clientX, clientY: e.touches[0].clientY, - time: get.utc() + time: get.utc(), }; } // if(window.ForceTouch&&!_status.paused2&&!_status.forcetouchinterval&&lib.config.enable_pressure){ // _status.forcetouchinterval=setInterval(ui.click.forcetouch,30); // } } - static windowtouchmove(e) { + windowtouchmove(e) { e.preventDefault(); if (window.inSplash) return; if (_status.draggingroundmenu) { delete _status._swipeorigin; if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && e.touches.length) { var translate = ui.roundmenu._dragtransform.slice(0); - var dx = e.touches[0].clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - var dy = e.touches[0].clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + var dx = + e.touches[0].clientX / game.documentZoom - + ui.roundmenu._dragorigin.clientX / game.documentZoom; + var dy = + e.touches[0].clientY / game.documentZoom - + ui.roundmenu._dragorigin.clientY / game.documentZoom; translate[0] += dx; translate[1] += dy; if (dx * dx + dy * dy > 100) { @@ -1430,21 +1443,27 @@ export class Click extends Uninstantable { ui.click.checkroundtranslate(translate); } _status.clicked = true; - } - else if (_status.draggingtouchdialog) { + } else if (_status.draggingtouchdialog) { delete _status._swipeorigin; - if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && e.touches.length) { + if ( + _status.draggingtouchdialog._dragorigin && + _status.draggingtouchdialog._dragtransform && + e.touches.length + ) { var translate = _status.draggingtouchdialog._dragtransform.slice(0); - var dx = e.touches[0].clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; - var dy = e.touches[0].clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; + var dx = + e.touches[0].clientX / game.documentZoom - + _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; + var dy = + e.touches[0].clientY / game.documentZoom - + _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; translate[0] += dx; translate[1] += dy; _status.draggingtouchdialog._dragtouches = e.touches[0]; ui.click.checkdialogtranslate(translate, _status.draggingtouchdialog); } _status.clicked = true; - } - else if (_status._swipeorigin && e.touches[0]) { + } else if (_status._swipeorigin && e.touches[0]) { _status._swipeorigin.touches = e.touches[0]; } @@ -1453,11 +1472,12 @@ export class Click extends Uninstantable { var item = document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY); if (game.chess && ui.selected.cards.length) { var itemtype = get.itemtype(item); - if (itemtype != 'card' && itemtype != 'button') { + if (itemtype != "card" && itemtype != "button") { var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; for (var i = 0; i < game.players.length; i++) { - var left = -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); + var left = + -ui.chessContainer.chessLeft + ui.chess.offsetLeft + game.players[i].getLeft(); var top = -ui.chessContainer.chessTop + ui.chess.offsetTop + game.players[i].getTop(); var width = game.players[i].offsetWidth; var height = game.players[i].offsetHeight; @@ -1474,14 +1494,17 @@ export class Click extends Uninstantable { ui.canvas.height = ui.arena.offsetHeight; var ctx = ui.ctx; ctx.shadowBlur = 5; - ctx.shadowColor = 'rgba(0,0,0,0.3)'; - ctx.strokeStyle = 'white'; + ctx.shadowColor = "rgba(0,0,0,0.3)"; + ctx.strokeStyle = "white"; ctx.lineWidth = 3; ctx.setLineDash([8, 2]); ctx.beginPath(); - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + ctx.moveTo( + _status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, + _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop + ); if (_status.multitarget) { for (var i = 0; i < _status.lastdragchange.length; i++) { @@ -1490,12 +1513,18 @@ export class Click extends Uninstantable { } } if (!_status.selectionfull) { - ctx.lineTo(e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft, e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop); + ctx.lineTo( + e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft, + e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop + ); } ctx.stroke(); if (!_status.multitarget) { for (var i = 0; i < _status.lastdragchange.length; i++) { - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + ctx.moveTo( + _status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, + _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop + ); var exy = _status.lastdragchange[i]._lastdragchange; ctx.lineTo(exy[0], exy[1]); ctx.stroke(); @@ -1515,81 +1544,92 @@ export class Click extends Uninstantable { return; } var itemtype = get.itemtype(item); - if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { + if (itemtype == "card" || itemtype == "button" || itemtype == "player") { _status.mouseleft = true; if (ui.selected.cards.length) { ui.selected.cards[0].updateTransform(true, 100); } var ex = e.touches[0].clientX / game.documentZoom - ui.arena.offsetLeft; var ey = e.touches[0].clientY / game.documentZoom - ui.arena.offsetTop; - var exx = ex, eyy = ey; + var exx = ex, + eyy = ey; if (game.chess) { ex -= -ui.chessContainer.chessLeft + ui.chess.offsetLeft; ey -= -ui.chessContainer.chessTop + ui.chess.offsetTop; } - if (itemtype != 'player' || game.chess || (ex > item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && - ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { + if ( + itemtype != "player" || + game.chess || + (ex > item.offsetLeft && + ex < item.offsetLeft + item.offsetWidth && + ey > item.offsetTop && + ey < item.offsetTop + item.offsetHeight) + ) { var targetfixed = false; - if (itemtype == 'player') { + if (itemtype == "player") { if (get.select(_status.event.selectTarget)[1] <= -1) { targetfixed = true; } } - if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { + if ( + !targetfixed && + item.classList.contains("selectable") && + _status.dragstatuschanged != item + ) { _status.mouseleft = true; _status.dragstatuschanged = item; _status.clicked = false; _status.dragged = false; - var notbefore = itemtype == 'player' && !item.classList.contains('selected'); + var notbefore = itemtype == "player" && !item.classList.contains("selected"); ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { + if (item.classList.contains("selected")) { if (notbefore) { _status.lastdragchange.push(item); item._lastdragchange = [exx, eyy]; if (lib.falseitem) { - var from = [_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop]; + var from = [ + _status.mousedragging.clientX / game.documentZoom - + ui.arena.offsetLeft, + _status.mousedragging.clientY / game.documentZoom - + ui.arena.offsetTop, + ]; var to = [exx, eyy]; - var node = ui.create.div('.linexy.hidden'); - node.style.left = from[0] + 'px'; - node.style.top = from[1] + 'px'; - node.style.transitionDuration = '0.3s'; - node.style.backgroundColor = 'white'; + var node = ui.create.div(".linexy.hidden"); + node.style.left = from[0] + "px"; + node.style.top = from[1] + "px"; + node.style.transitionDuration = "0.3s"; + node.style.backgroundColor = "white"; var dy = to[1] - from[1]; var dx = to[0] - from[0]; - var deg = Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI * 180; + var deg = (Math.atan(Math.abs(dy) / Math.abs(dx)) / Math.PI) * 180; if (dx >= 0) { if (dy <= 0) { deg += 90; - } - else { + } else { deg = 90 - deg; } - } - else { + } else { if (dy <= 0) { deg = 270 - deg; - } - else { + } else { deg += 270; } } - node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(0)'; - node.style.height = get.xyDistance(from, to) + 'px'; + node.style.transform = "rotate(" + -deg + "deg) scaleY(0)"; + node.style.height = get.xyDistance(from, to) + "px"; if (game.chess) { ui.chess.appendChild(node); - } - else { + } else { ui.arena.appendChild(node); } ui.refresh(node); node.show(); - node.style.transform = 'rotate(' + (-deg) + 'deg) scaleY(1)'; + node.style.transform = "rotate(" + -deg + "deg) scaleY(1)"; ui.touchlines.push(node); node._origin = item; } } - } - else { + } else { _status.lastdragchange.remove(item); for (var i = 0; i < ui.touchlines.length; i++) { if (ui.touchlines[i]._origin == item) { @@ -1599,13 +1639,20 @@ export class Click extends Uninstantable { } } _status.selectionfull = true; - if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { + if ( + _status.event.filterButton && + ui.selected.buttons.length < get.select(_status.event.selectButton)[1] + ) { _status.selectionfull = false; - } - else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { + } else if ( + _status.event.filterCard && + ui.selected.cards.length < get.select(_status.event.selectCard)[1] + ) { _status.selectionfull = false; - } - else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { + } else if ( + _status.event.filterTarget && + ui.selected.targets.length < get.select(_status.event.selectTarget)[1] + ) { _status.selectionfull = false; } } @@ -1618,7 +1665,7 @@ export class Click extends Uninstantable { _status.dragstatuschanged = null; } } - static windowtouchend(e) { + windowtouchend(e) { delete _status.force; // if(_status.forcetouchinterval){ // clearInterval(_status.forcetouchinterval); @@ -1636,35 +1683,44 @@ export class Click extends Uninstantable { } var translate; if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform && ui.roundmenu._dragtouches) { - var dx = ui.roundmenu._dragtouches.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - var dy = ui.roundmenu._dragtouches.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + var dx = + ui.roundmenu._dragtouches.clientX / game.documentZoom - + ui.roundmenu._dragorigin.clientX / game.documentZoom; + var dy = + ui.roundmenu._dragtouches.clientY / game.documentZoom - + ui.roundmenu._dragorigin.clientY / game.documentZoom; if (dx * dx + dy * dy < 1000) { ui.click.roundmenu(); ui.roundmenu._dragtransform = ui.roundmenu._dragorigintransform; translate = ui.roundmenu._dragtransform; - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; - } - else { + ui.roundmenu.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px)"; + } else { translate = ui.roundmenu._dragtransform; translate[0] += dx; translate[1] += dy; ui.click.checkroundtranslate(); } delete ui.roundmenu._dragorigin; - } - else { + } else { ui.click.roundmenu(); } _status.clicked = false; - game.saveConfig('roundmenu_transform', translate); + game.saveConfig("roundmenu_transform", translate); delete _status.draggingroundmenu; - } - else if (_status.draggingtouchdialog) { + } else if (_status.draggingtouchdialog) { delete _status._swipeorigin; var translate; - if (_status.draggingtouchdialog._dragorigin && _status.draggingtouchdialog._dragtransform && _status.draggingtouchdialog._dragtouches) { - var dx = _status.draggingtouchdialog._dragtouches.clientX / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; - var dy = _status.draggingtouchdialog._dragtouches.clientY / game.documentZoom - _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; + if ( + _status.draggingtouchdialog._dragorigin && + _status.draggingtouchdialog._dragtransform && + _status.draggingtouchdialog._dragtouches + ) { + var dx = + _status.draggingtouchdialog._dragtouches.clientX / game.documentZoom - + _status.draggingtouchdialog._dragorigin.clientX / game.documentZoom; + var dy = + _status.draggingtouchdialog._dragtouches.clientY / game.documentZoom - + _status.draggingtouchdialog._dragorigin.clientY / game.documentZoom; translate = _status.draggingtouchdialog._dragtransform; translate[0] += dx; translate[1] += dy; @@ -1673,43 +1729,52 @@ export class Click extends Uninstantable { delete _status.draggingtouchdialog._dragorigin; } _status.clicked = false; - game.saveConfig('dialog_transform', translate); + game.saveConfig("dialog_transform", translate); delete _status.draggingtouchdialog; _status.justdragged = true; setTimeout(function () { _status.justdragged = false; }, 500); - } - else if (_status._swipeorigin && !_status.paused2 && !_status.mousedragging && _status._swipeorigin.touches && !_status.filterCharacter) { + } else if ( + _status._swipeorigin && + !_status.paused2 && + !_status.mousedragging && + _status._swipeorigin.touches && + !_status.filterCharacter + ) { if (get.utc() - _status._swipeorigin.time < 500) { - var dx = _status._swipeorigin.touches.clientX / game.documentZoom - _status._swipeorigin.clientX / game.documentZoom; - var dy = _status._swipeorigin.touches.clientY / game.documentZoom - _status._swipeorigin.clientY / game.documentZoom; + var dx = + _status._swipeorigin.touches.clientX / game.documentZoom - + _status._swipeorigin.clientX / game.documentZoom; + var dy = + _status._swipeorigin.touches.clientY / game.documentZoom - + _status._swipeorigin.clientY / game.documentZoom; var goswipe = function (action) { game.closeConnectMenu(); switch (action) { - case 'system': + case "system": game.closePopped(); - ui.system1.classList.add('shown'); - ui.system2.classList.add('shown'); + ui.system1.classList.add("shown"); + ui.system2.classList.add("shown"); game.closeMenu(); ui.click.shortcut(); break; - case 'menu': + case "menu": if (ui.click.configMenu) { game.closePopped(); game.pause2(); ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); + ui.system1.classList.remove("shown"); + ui.system2.classList.remove("shown"); } break; - case 'pause': + case "pause": ui.click.pause(); break; - case 'auto': + case "auto": ui.click.auto(); break; - case 'chat': + case "chat": game.closeMenu(); if (ui.chatButton) { ui.click.hoverpopped.call(ui.chatButton); @@ -1720,16 +1785,13 @@ export class Click extends Uninstantable { if (Math.abs(dx) < 100) { if (dy < -200) { goswipe(lib.config.swipe_up); - } - else if (dy > 200) { + } else if (dy > 200) { goswipe(lib.config.swipe_down); } - } - else if (Math.abs(dy) < 100) { + } else if (Math.abs(dy) < 100) { if (dx < -200) { goswipe(lib.config.swipe_left); - } - else if (dx > 200) { + } else if (dx > 200) { goswipe(lib.config.swipe_right); } } @@ -1747,13 +1809,11 @@ export class Click extends Uninstantable { if (!event.filterOk || event.filterOk()) ui.click.ok(); ui.canvas.width = ui.arena.offsetWidth; ui.canvas.height = ui.arena.offsetHeight; - } - else { + } else { game.uncheck(); game.check(); } - } - else if (_status.mousedragging && _status.mousedragorigin) { + } else if (_status.mousedragging && _status.mousedragorigin) { tmpflag = _status.mousedragorigin; } _status.lastdragchange.length = 0; @@ -1770,34 +1830,32 @@ export class Click extends Uninstantable { _status.dragged = false; _status.clicked = false; } - static checkroundtranslate(translate) { + checkroundtranslate(translate) { var translate = translate || ui.roundmenu._dragtransform; if (translate[1] + ui.roundmenu._position[1] + 50 + ui.arena.offsetTop > ui.window.offsetHeight) { translate[1] = ui.window.offsetHeight - (ui.roundmenu._position[1] + 50) - ui.arena.offsetTop; - } - else if (translate[1] + ui.roundmenu._position[1] + ui.arena.offsetTop < 0) { + } else if (translate[1] + ui.roundmenu._position[1] + ui.arena.offsetTop < 0) { translate[1] = -ui.roundmenu._position[1] - ui.arena.offsetTop; } if (translate[0] + ui.roundmenu._position[0] + 50 + ui.arena.offsetLeft > ui.window.offsetWidth) { translate[0] = ui.window.offsetWidth - (ui.roundmenu._position[0] + 50) - ui.arena.offsetLeft; - } - else if (translate[0] + ui.roundmenu._position[0] + ui.arena.offsetLeft < 0) { + } else if (translate[0] + ui.roundmenu._position[0] + ui.arena.offsetLeft < 0) { translate[0] = -ui.roundmenu._position[0] - ui.arena.offsetLeft; } - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + ui.roundmenu.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px)"; } - static checkdialogtranslate(translate, dialog) { + checkdialogtranslate(translate, dialog) { var translate = translate || dialog._dragtransform; if (Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]) < 10) { translate[0] = 0; translate[1] = 0; } - dialog.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + dialog.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px)"; } - static windowmousewheel(e) { + windowmousewheel(e) { _status.tempunpopup = e; } - static windowmousemove(e) { + windowmousemove(e) { if (window.inSplash) return; if (_status.tempunpopup) { if (get.evtDistance(_status.tempunpopup, e) > 5) { @@ -1805,7 +1863,7 @@ export class Click extends Uninstantable { } } if (e.button == 2) return; - var dialogs = document.querySelectorAll('#window>.dialog.popped:not(.static)'); + var dialogs = document.querySelectorAll("#window>.dialog.popped:not(.static)"); for (var i = 0; i < dialogs.length; i++) { dialogs[i].delete(); } @@ -1813,7 +1871,7 @@ export class Click extends Uninstantable { var sourceitem = document.elementFromPoint(e.clientX, e.clientY); if (game.chess && ui.selected.cards.length) { var itemtype = get.itemtype(sourceitem); - if (itemtype != 'card' && itemtype != 'button') { + if (itemtype != "card" && itemtype != "button") { for (var i = 0; i < game.players.length; i++) { var ex = e.clientX / game.documentZoom - ui.arena.offsetLeft; var ey = e.clientY / game.documentZoom - ui.arena.offsetTop; @@ -1866,14 +1924,17 @@ export class Click extends Uninstantable { ui.canvas.height = ui.arena.offsetHeight; var ctx = ui.ctx; ctx.shadowBlur = 5; - ctx.shadowColor = 'rgba(0,0,0,0.3)'; - ctx.strokeStyle = 'white'; + ctx.shadowColor = "rgba(0,0,0,0.3)"; + ctx.strokeStyle = "white"; ctx.lineWidth = 3; ctx.setLineDash([8, 2]); ctx.beginPath(); - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + ctx.moveTo( + _status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, + _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop + ); if (_status.multitarget) { for (var i = 0; i < _status.lastdragchange.length; i++) { var exy = _status.lastdragchange[i]._lastdragchange; @@ -1881,12 +1942,18 @@ export class Click extends Uninstantable { } } if (!_status.selectionfull) { - ctx.lineTo(e.clientX / game.documentZoom - ui.arena.offsetLeft, e.clientY / game.documentZoom - ui.arena.offsetTop); + ctx.lineTo( + e.clientX / game.documentZoom - ui.arena.offsetLeft, + e.clientY / game.documentZoom - ui.arena.offsetTop + ); } ctx.stroke(); if (!_status.multitarget) { for (var i = 0; i < _status.lastdragchange.length; i++) { - ctx.moveTo(_status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop); + ctx.moveTo( + _status.mousedragging.clientX / game.documentZoom - ui.arena.offsetLeft, + _status.mousedragging.clientY / game.documentZoom - ui.arena.offsetTop + ); var exy = _status.lastdragchange[i]._lastdragchange; ctx.lineTo(exy[0], exy[1]); ctx.stroke(); @@ -1900,8 +1967,8 @@ export class Click extends Uninstantable { _status.mousedragging = null; _status.mousedragorigin = null; _status.clicked = false; - if (_status.event.type == 'phase' && !_status.event.skill && ui.confirm) { - ui.confirm.classList.add('removing'); + if (_status.event.type == "phase" && !_status.event.skill && ui.confirm) { + ui.confirm.classList.add("removing"); } game.uncheck(); game.check(); @@ -1910,49 +1977,66 @@ export class Click extends Uninstantable { return; } var itemtype = get.itemtype(item); - if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { + if (itemtype == "card" || itemtype == "button" || itemtype == "player") { _status.mouseleft = true; if (ui.selected.cards.length) { ui.selected.cards[0].updateTransform(true, 100); } var ex = e.clientX / game.documentZoom - ui.arena.offsetLeft; var ey = e.clientY / game.documentZoom - ui.arena.offsetTop; - var exx = ex, eyy = ey; + var exx = ex, + eyy = ey; if (game.chess) { ex -= -ui.chessContainer.chessLeft + ui.chess.offsetLeft; ey -= -ui.chessContainer.chessTop + ui.chess.offsetTop; } - if (itemtype != 'player' || game.chess || (ex > item.offsetLeft && ex < item.offsetLeft + item.offsetWidth && - ey > item.offsetTop && ey < item.offsetTop + item.offsetHeight)) { + if ( + itemtype != "player" || + game.chess || + (ex > item.offsetLeft && + ex < item.offsetLeft + item.offsetWidth && + ey > item.offsetTop && + ey < item.offsetTop + item.offsetHeight) + ) { var targetfixed = false; - if (itemtype == 'player') { + if (itemtype == "player") { if (get.select(_status.event.selectTarget)[1] <= -1) { targetfixed = true; } } - if (!targetfixed && item.classList.contains('selectable') && _status.dragstatuschanged != item) { + if ( + !targetfixed && + item.classList.contains("selectable") && + _status.dragstatuschanged != item + ) { _status.mouseleft = true; _status.dragstatuschanged = item; _status.clicked = false; - var notbefore = itemtype == 'player' && !item.classList.contains('selected'); + var notbefore = itemtype == "player" && !item.classList.contains("selected"); ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { + if (item.classList.contains("selected")) { if (notbefore) { _status.lastdragchange.push(item); item._lastdragchange = [exx, eyy]; } - } - else { + } else { _status.lastdragchange.remove(item); } _status.selectionfull = true; - if (_status.event.filterButton && ui.selected.buttons.length < get.select(_status.event.selectButton)[1]) { + if ( + _status.event.filterButton && + ui.selected.buttons.length < get.select(_status.event.selectButton)[1] + ) { _status.selectionfull = false; - } - else if (_status.event.filterCard && ui.selected.cards.length < get.select(_status.event.selectCard)[1]) { + } else if ( + _status.event.filterCard && + ui.selected.cards.length < get.select(_status.event.selectCard)[1] + ) { _status.selectionfull = false; - } - else if (_status.event.filterTarget && ui.selected.targets.length < get.select(_status.event.selectTarget)[1]) { + } else if ( + _status.event.filterTarget && + ui.selected.targets.length < get.select(_status.event.selectTarget)[1] + ) { _status.selectionfull = false; } } @@ -1969,35 +2053,42 @@ export class Click extends Uninstantable { } } _status.dragstatuschanged = null; - } - else { + } else { while (item) { if (item == node && !node._mouseentercreated) { ui.click.mouseentercancel(); var hoveration; - if (typeof node._hoveration == 'number') { + if (typeof node._hoveration == "number") { hoveration = node._hoveration; - } - else { + } else { hoveration = parseInt(lib.config.hoveration); - if (node.classList.contains('button') || - (node.parentNode && node.parentNode.parentNode) == ui.me) { + if ( + node.classList.contains("button") || + (node.parentNode && node.parentNode.parentNode) == ui.me + ) { hoveration += 500; } } _status._mouseentertimeout = setTimeout(function () { - if (_status.currentmouseenter != node || node._mouseentercreated || _status.tempunpopup || - _status.mousedragging || _status.mousedown || !node.offsetWidth || !node.offsetHeight) { + if ( + _status.currentmouseenter != node || + node._mouseentercreated || + _status.tempunpopup || + _status.mousedragging || + _status.mousedown || + !node.offsetWidth || + !node.offsetHeight + ) { return; } if (node._hoverfunc && !node._nopup) { var dialog = node._hoverfunc.call(node, e); if (dialog) { - dialog.classList.add('popped'); + dialog.classList.add("popped"); ui.window.appendChild(dialog); lib.placePoppedDialog(dialog, e); if (node._hoverwidth) { - dialog.style.width = node._hoverwidth + 'px'; + dialog.style.width = node._hoverwidth + "px"; dialog._hovercustomed = true; } node._mouseenterdialog = dialog; @@ -2013,8 +2104,10 @@ export class Click extends Uninstantable { var ddialog = _status.draggingdialog; if (ddialog._dragorigin && ddialog._dragtransform) { var translate = ddialog._dragtransform.slice(0); - translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; + translate[0] += + e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; + translate[1] += + e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; ui.click.checkdialogtranslate(translate, ddialog); } _status.clicked = true; @@ -2022,20 +2115,22 @@ export class Click extends Uninstantable { if (_status.draggingroundmenu) { if (ui.roundmenu._dragorigin && ui.roundmenu._dragtransform) { var translate = ui.roundmenu._dragtransform.slice(0); - translate[0] += e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; + translate[0] += + e.clientX / game.documentZoom - ui.roundmenu._dragorigin.clientX / game.documentZoom; + translate[1] += + e.clientY / game.documentZoom - ui.roundmenu._dragorigin.clientY / game.documentZoom; ui.click.checkroundtranslate(translate); } _status.clicked = true; } } } - static windowmousedown(e) { + windowmousedown(e) { if (window.inSplash) return; if (!ui.window) return; if (e.button == 2) return; _status.mousedown = true; - var dialogs = ui.window.querySelectorAll('#window>.dialog.popped:not(.static)'); + var dialogs = ui.window.querySelectorAll("#window>.dialog.popped:not(.static)"); for (var i = 0; i < dialogs.length; i++) { dialogs[i].delete(); } @@ -2043,10 +2138,12 @@ export class Click extends Uninstantable { var item = sourceitem; while (item) { var itemtype = get.itemtype(item); - if (itemtype == 'button') break; - if (itemtype == 'dialog' && - !item.classList.contains('popped') && - !item.classList.contains('fixed')) { + if (itemtype == "button") break; + if ( + itemtype == "dialog" && + !item.classList.contains("popped") && + !item.classList.contains("fixed") + ) { var ddialog = item; _status.draggingdialog = ddialog; ddialog._dragorigin = e; @@ -2068,26 +2165,28 @@ export class Click extends Uninstantable { var evt = _status.event; if (!lib.config.enable_drag) return; - if (!ui.arena.classList.contains('selecting')) return; + if (!ui.arena.classList.contains("selecting")) return; if (!evt.isMine()) return; item = sourceitem; while (item) { var itemtype = get.itemtype(item); - if (itemtype == 'card' || itemtype == 'button' || itemtype == 'player') { - if (item.classList.contains('selectable') && - !item.classList.contains('selected') && - !item.classList.contains('noclick')) { + if (itemtype == "card" || itemtype == "button" || itemtype == "player") { + if ( + item.classList.contains("selectable") && + !item.classList.contains("selected") && + !item.classList.contains("noclick") + ) { _status.clicked = false; ui.click[itemtype].call(item); - if (item.classList.contains('selected')) { + if (item.classList.contains("selected")) { _status.mousedragging = e; _status.mousedragorigin = item; _status.mouseleft = false; _status.selectionfull = false; _status.multitarget = false; _status.lastmouseutc = get.utc(); - ui.arena.classList.add('dragging'); + ui.arena.classList.add("dragging"); } } return; @@ -2095,23 +2194,25 @@ export class Click extends Uninstantable { item = item.parentNode; } } - static cardtouchstart(e) { + cardtouchstart(e) { if (e.touches.length != 1) return; if (!lib.config.enable_drag) return; if (!this.parentNode) return; if (!this.parentNode.parentNode) return; if (this.parentNode.parentNode.parentNode != ui.me) return; - if (this.parentNode.parentNode.classList.contains('scrollh')) return; - if (this.classList.contains('selectable') && - !this.classList.contains('selected') && - !this.classList.contains('noclick')) { + if (this.parentNode.parentNode.classList.contains("scrollh")) return; + if ( + this.classList.contains("selectable") && + !this.classList.contains("selected") && + !this.classList.contains("noclick") + ) { this._waitingfordrag = { clientX: e.touches[0].clientX, - clientY: e.touches[0].clientY + clientY: e.touches[0].clientY, }; } } - static cardtouchmove(e) { + cardtouchmove(e) { ui.click.longpresscancel.call(this); if (this._waitingfordrag) { var drag = this._waitingfordrag; @@ -2119,7 +2220,7 @@ export class Click extends Uninstantable { _status.touchnocheck = true; ui.click.card.call(this); _status.touchnocheck = false; - if (this.classList.contains('selected')) { + if (this.classList.contains("selected")) { _status.mousedragging = drag; _status.mousedragorigin = this; _status.mouseleft = false; @@ -2129,7 +2230,7 @@ export class Click extends Uninstantable { delete this._waitingfordrag; } } - static windowmouseup(e) { + windowmouseup(e) { delete _status.force; // if(_status.forcetouchinterval){ // clearInterval(_status.forcetouchinterval); @@ -2141,12 +2242,14 @@ export class Click extends Uninstantable { var translate; if (ddialog._dragorigin && ddialog._dragtransform) { translate = ddialog._dragtransform; - translate[0] += e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; - translate[1] += e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; + translate[0] += + e.clientX / game.documentZoom - ddialog._dragorigin.clientX / game.documentZoom; + translate[1] += + e.clientY / game.documentZoom - ddialog._dragorigin.clientY / game.documentZoom; ui.click.checkdialogtranslate(null, ddialog); delete ddialog._dragorigin; } - game.saveConfig('dialog_transform', translate); + game.saveConfig("dialog_transform", translate); delete _status.draggingdialog; } if (_status.draggingroundmenu) { @@ -2163,7 +2266,7 @@ export class Click extends Uninstantable { ui.click.checkroundtranslate(); delete ui.roundmenu._dragorigin; } - game.saveConfig('roundmenu_transform', translate); + game.saveConfig("roundmenu_transform", translate); delete _status.draggingroundmenu; } if (e.button == 2) { @@ -2176,8 +2279,7 @@ export class Click extends Uninstantable { game.check(); _status.noright = true; } - } - else { + } else { var tmpflag = false; _status.mousedown = false; for (var i = 0; i < ui.selected.cards.length; i++) { @@ -2190,13 +2292,11 @@ export class Click extends Uninstantable { } var event = _status.event; if (!event.filterOk || event.filterOk()) ui.click.ok(); - } - else { + } else { game.uncheck(); game.check(); } - } - else if (_status.mousedragging && _status.mousedragorigin) { + } else if (_status.mousedragging && _status.mousedragorigin) { tmpflag = _status.mousedragorigin; } _status.lastdragchange.length = 0; @@ -2215,10 +2315,10 @@ export class Click extends Uninstantable { // ui.updatehl(); } if (ui.arena) { - ui.arena.classList.remove('dragging'); + ui.arena.classList.remove("dragging"); } } - static mousemove() { + mousemove() { if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { return; } @@ -2226,38 +2326,38 @@ export class Click extends Uninstantable { _status.currentmouseenter = this; } } - static mouseenter() { + mouseenter() { if (!lib.config.hover_handcard && this.parentNode && this.parentNode.parentNode == ui.me) { return; } _status.currentmouseenter = this; } - static mouseleave() { + mouseleave() { ui.click.mouseentercancel(); if (_status.currentmouseenter == this) { _status.currentmouseenter = null; } this._mouseentercreated = false; } - static mousedown() { + mousedown() { ui.click.mouseentercancel(); if (_status.currentmouseenter == this) { _status.currentmouseenter = null; } this._mouseentercreated = true; } - static mouseentercancel() { + mouseentercancel() { if (_status._mouseentertimeout) { clearTimeout(_status._mouseentertimeout); delete _status._mouseentertimeout; } } - static hoverplayer(e) { + hoverplayer(e) { var node = get.nodeintro(this, true); if (node) node.style.zIndex = 21; return node; } - static longpressdown(e) { + longpressdown(e) { if (_status.longpressed) return; if (this._longpresstimeout) { clearTimeout(this._longpresstimeout); @@ -2274,7 +2374,7 @@ export class Click extends Uninstantable { // } _status.longpressing = this; } - static longpresscallback() { + longpresscallback() { if (!_status.longpressing) return; var node = _status.longpressing; var func = node._longpresscallback; @@ -2304,7 +2404,7 @@ export class Click extends Uninstantable { ui.click.touchpop(); } } - static longpresscancel() { + longpresscancel() { if (this._longpresstimeout) { clearTimeout(this._longpresstimeout); delete this._longpresstimeout; @@ -2314,7 +2414,7 @@ export class Click extends Uninstantable { delete _status.longpressing; } } - static window() { + window() { var clicked = _status.clicked; var dialogtouched = false; if (_status.dialogtouched) { @@ -2327,12 +2427,11 @@ export class Click extends Uninstantable { if (_status.clicked || _status.clicked2) { _status.clicked = false; _status.clicked2 = false; - } - else { + } else { if (_status.clickingidentity) { for (var i = 0; i < _status.clickingidentity[1].length; i++) { _status.clickingidentity[1][i].delete(); - _status.clickingidentity[1][i].style.transform = ''; + _status.clickingidentity[1][i].style.transform = ""; } delete _status.clickingidentity; } @@ -2346,48 +2445,43 @@ export class Click extends Uninstantable { } _status.editing.innerHTML = get.translation(_status.editing.link); delete _status.editing; - } - else if (_status.choosing) { + } else if (_status.choosing) { if (!_status.choosing.expand) { - _status.choosing.parentNode.style.height = ''; + _status.choosing.parentNode.style.height = ""; _status.choosing.nextSibling.delete(); _status.choosing.previousSibling.show(); delete _status.choosing; } - } - else if (ui.intro) { + } else if (ui.intro) { ui.intro.close(); delete ui.intro; ui.control.show(); game.resume2(); - } - else if ((_status.event.isMine() || _status.event.forceMine) && !dialogtouched) { + } else if ((_status.event.isMine() || _status.event.forceMine) && !dialogtouched) { if (_status.event.custom && _status.event.custom.replace.window) { _status.event.custom.replace.window(); - } - else { - if (_status.event.skill && _status.event.name == 'chooseToUse') { + } else { + if (_status.event.skill && _status.event.name == "chooseToUse") { ui.click.cancel(); - } - else if (_status.event._checked) { + } else if (_status.event._checked) { game.uncheck(); game.check(); } } } - if (!ui.shortcut.classList.contains('hidden')) { + if (!ui.shortcut.classList.contains("hidden")) { ui.click.shortcut(false); } - if (get.is.phoneLayout() && ui.menuContainer && ui.menuContainer.classList.contains('hidden')) { - if (ui.system2.classList.contains('shown')) { + if (get.is.phoneLayout() && ui.menuContainer && ui.menuContainer.classList.contains("hidden")) { + if (ui.system2.classList.contains("shown")) { _status.removinground = true; setTimeout(function () { _status.removinground = false; }, 200); } - ui.arena.classList.remove('phonetop'); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); + ui.arena.classList.remove("phonetop"); + ui.system1.classList.remove("shown"); + ui.system2.classList.remove("shown"); // if(ui.chessinfo){ // ui.chessinfo.classList.remove('zoomed'); // } @@ -2395,50 +2489,48 @@ export class Click extends Uninstantable { } if (_status.tempunpop) { _status.tempunpop = false; - } - else { + } else { game.closePopped(); } if (_status.event.custom && _status.event.custom.add.window) { _status.event.custom.add.window(clicked); } } - static toggle() { + toggle() { if (_status.dragged) return; - if (this.parentNode.classList.contains('disabled')) return; + if (this.parentNode.classList.contains("disabled")) return; _status.tempunpop = true; if (this.link) { this.link = false; - this.classList.remove('on'); + this.classList.remove("on"); if (this.additionalCommand) this.additionalCommand(false, this.parentNode); - } - else { + } else { this.link = true; - this.classList.add('on'); + this.classList.add("on"); if (this.additionalCommand) this.additionalCommand(true, this.parentNode); } } - static editor() { + editor() { if (_status.dragged) return; if (_status.editing) return; _status.clicked = true; - this.innerHTML = ''; + this.innerHTML = ""; _status.editing = this; if (this.additionalCommand) this.additionalCommand(this); } - static switcher() { + switcher() { if (_status.dragged) return; - if (this.parentNode.classList.contains('disabled')) return; + if (this.parentNode.classList.contains("disabled")) return; if (_status.choosing) return; _status.clicked = true; _status.tempunpop = true; this.previousSibling.hide(); - var node = ui.create.div('.switcher', this.parentNode).addTempClass('start'); + var node = ui.create.div(".switcher", this.parentNode).addTempClass("start"); for (var i = 0; i < this.choice.length; i++) { - var choice = ui.create.div('.pointerdiv', node); + var choice = ui.create.div(".pointerdiv", node); choice.innerHTML = get.translation(this.choice[i]); choice.link = this.choice[i]; - choice.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.choice); + choice.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.choice); } // this.parentNode.style.height=(node.offsetHeight)+'px'; _status.choosing = this; @@ -2449,25 +2541,27 @@ export class Click extends Uninstantable { }, 500); } } - static choice() { + choice() { if (_status.dragged) return; if (!_status.choosing) return; _status.choosing.link = this.link; _status.choosing.innerHTML = get.translation(this.link); - this.parentNode.parentNode.style.height = ''; + this.parentNode.parentNode.style.height = ""; this.parentNode.delete(); _status.choosing.previousSibling.show(); delete _status.choosing; - if (this.parentNode.parentNode.querySelector('.toggle').additionalCommand) { - this.parentNode.parentNode.querySelector('.toggle').additionalCommand(this.link, this.parentNode.parentNode); + if (this.parentNode.parentNode.querySelector(".toggle").additionalCommand) { + this.parentNode.parentNode + .querySelector(".toggle") + .additionalCommand(this.link, this.parentNode.parentNode); } } - static button() { + button() { if (_status.dragged) return; if (_status.clicked) return; if (_status.tempNoButton) return; if (_status.draggingtouchdialog) return; - if (this.classList.contains('noclick')) return; + if (this.classList.contains("noclick")) return; if (_status.justdragged) return; _status.clicked = true; var custom = _status.event.custom; @@ -2476,17 +2570,16 @@ export class Click extends Uninstantable { return; } if (!_status.event.isMine()) return; - if (this.classList.contains('selectable') == false) return; - if (this.classList.contains('selected')) { + if (this.classList.contains("selectable") == false) return; + if (this.classList.contains("selected")) { ui.selected.buttons.remove(this); - this.classList.remove('selected'); + this.classList.remove("selected"); if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); } - } - else { - this.classList.add('selected'); + } else { + this.classList.add("selected"); ui.selected.buttons.add(this); } if (custom && custom.add && custom.add.button) { @@ -2494,27 +2587,30 @@ export class Click extends Uninstantable { } game.check(); } - static touchintro() { + touchintro() { var rect = this.getBoundingClientRect(); ui.click.touchpop(); ui.click.intro.call(this, { clientX: rect.left + 18, - clientY: rect.top + 12 + clientY: rect.top + 12, }); _status.clicked = false; } - static card() { + card() { delete this._waitingfordrag; if (_status.dragged) return; if (_status.clicked) return; if (ui.intro) return; _status.clicked = true; - if (this.parentNode && (this.parentNode.classList.contains('judges') || this.parentNode.classList.contains('marks'))) { + if ( + this.parentNode && + (this.parentNode.classList.contains("judges") || this.parentNode.classList.contains("marks")) + ) { var rect = this.getBoundingClientRect(); ui.click.touchpop(); ui.click.intro.call(this, { clientX: rect.left + 18, - clientY: rect.top + 12 + clientY: rect.top + 12, }); _status.clicked = false; return; @@ -2524,32 +2620,35 @@ export class Click extends Uninstantable { custom.replace.card(this); return; } - if (this.classList.contains('selectable') == false) return; - if (this.classList.contains('selected')) { + if (this.classList.contains("selectable") == false) return; + if (this.classList.contains("selected")) { ui.selected.cards.remove(this); if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); - } - else { - this.classList.remove('selected'); + } else { + this.classList.remove("selected"); this.updateTransform(); } - } - else { + } else { ui.selected.cards.add(this); - this.classList.add('selected'); + this.classList.add("selected"); this.updateTransform(true); } - if (game.chess && get.config('show_range') && !_status.event.skill && this.classList.contains('selected') && - _status.event.isMine() && _status.event.name == 'chooseToUse') { + if ( + game.chess && + get.config("show_range") && + !_status.event.skill && + this.classList.contains("selected") && + _status.event.isMine() && + _status.event.name == "chooseToUse" + ) { var player = _status.event.player; var range = get.info(this).range; if (range) { - if (typeof range.attack === 'number') { + if (typeof range.attack === "number") { player.createRangeShadow(Math.min(8, player.getAttackRange(true) + range.attack - 1)); - } - else if (typeof range.global === 'number') { + } else if (typeof range.global === "number") { player.createRangeShadow(Math.min(8, player.getGlobalFrom() + range.global)); } } @@ -2559,18 +2658,24 @@ export class Click extends Uninstantable { } game.check(); - if (lib.config.popequip && get.is.phoneLayout() && - arguments[0] != 'popequip' && ui.arena && ui.arena.classList.contains('selecting') && - this.parentNode && this.parentNode.classList.contains('popequip')) { + if ( + lib.config.popequip && + get.is.phoneLayout() && + arguments[0] != "popequip" && + ui.arena && + ui.arena.classList.contains("selecting") && + this.parentNode && + this.parentNode.classList.contains("popequip") + ) { var rect = this.getBoundingClientRect(); ui.click.touchpop(); ui.click.intro.call(this.parentNode, { clientX: rect.left + 18, - clientY: rect.top + 12 + clientY: rect.top + 12, }); } } - static avatar() { + avatar() { if (!lib.config.doubleclick_intro) return; if (this.parentNode.isUnseen(0)) return; if (!lib.character[this.parentNode.name]) return; @@ -2589,9 +2694,9 @@ export class Click extends Uninstantable { game.pause2(); ui.click.charactercard(player.name1 || player.name, null, null, true, this); } - static avatar2() { + avatar2() { if (!lib.config.doubleclick_intro) return; - if (this.parentNode.classList.contains('unseen2')) return; + if (this.parentNode.classList.contains("unseen2")) return; if (!lib.character[this.parentNode.name2]) return; if (!ui.menuContainer) return; var avatar = this; @@ -2608,91 +2713,96 @@ export class Click extends Uninstantable { game.pause2(); ui.click.charactercard(player.name2, null, null, true, this); } - static connectroom(e) { + connectroom(e) { if (_status.dragged) return; if (_status.clicked) return; if (ui.intro) return; if (this.roomfull) { - alert('房间已满'); - } - else if (this.roomgaming && !game.onlineID) { + alert("房间已满"); + } else if (this.roomgaming && !game.onlineID) { if (this.config && this.config.observe) { - alert('房间暂时不可旁观'); + alert("房间暂时不可旁观"); + } else { + alert("房间不允许旁观"); } - else { - alert('房间不允许旁观'); - } - } - else if (!this.roomempty && this.version != lib.versionOL) { + } else if (!this.roomempty && this.version != lib.versionOL) { if (this.version > lib.versionOL) { - alert('加入失败:你的游戏版本过低'); + alert("加入失败:你的游戏版本过低"); + } else { + alert("加入失败:房主的游戏版本过低"); } - else { - alert('加入失败:房主的游戏版本过低'); - } - } - else { + } else { if (!_status.enteringroom) { _status.enteringroom = true; _status.enteringroomserver = this.serving; - game.send('server', 'enter', this.key, get.connectNickname(), lib.config.connect_avatar); + game.send("server", "enter", this.key, get.connectNickname(), lib.config.connect_avatar); } } } - static player() { + player() { return ui.click.target.apply(this, arguments); } - static target(e) { + target(e) { if (_status.dragged) return; if (_status.clicked) return; if (ui.intro) return; - if (this.classList.contains('connect')) { + if (this.classList.contains("connect")) { if (game.online) { if (game.onlinezhu) { if (!this.playerid && game.connectPlayers) { - if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu') return; - if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong') return; - if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; - this.classList.toggle('unselectable2'); - if (this.classList.contains('unselectable2')) { + if (lib.configOL.mode == "versus" || lib.configOL.mode == "doudizhu") return; + if (lib.configOL.mode == "identity" && lib.configOL.identity_mode == "zhong") return; + if (!this.classList.contains("unselectable2") && lib.configOL.number <= 2) return; + this.classList.toggle("unselectable2"); + if (this.classList.contains("unselectable2")) { lib.configOL.number--; - } - else { + } else { lib.configOL.number++; } - game.send('changeNumConfig', lib.configOL.number, - game.connectPlayers.indexOf(this), this.classList.contains('unselectable2')); + game.send( + "changeNumConfig", + lib.configOL.number, + game.connectPlayers.indexOf(this), + this.classList.contains("unselectable2") + ); } } return; } if (this.playerid) { if (this.ws) { - if (confirm('是否踢出' + this.nickname + '?')) { + if (confirm("是否踢出" + this.nickname + "?")) { var id = get.id(); this.ws.send(function (id) { if (game.ws) { game.ws.close(); - game.saveConfig('reconnect_info'); - game.saveConfig('banned_info', id); + game.saveConfig("reconnect_info"); + game.saveConfig("banned_info", id); } }, id); lib.node.banned.push(id); } } - } - else { - if (lib.configOL.mode == 'versus' || lib.configOL.mode == 'doudizhu' || lib.configOL.mode == 'single') return; - if (lib.configOL.mode == 'identity' && (lib.configOL.identity_mode == 'zhong' || lib.configOL.identity_mode == 'purple')) return; - if (!this.classList.contains('unselectable2') && lib.configOL.number <= 2) return; - this.classList.toggle('unselectable2'); - if (this.classList.contains('unselectable2')) { + } else { + if ( + lib.configOL.mode == "versus" || + lib.configOL.mode == "doudizhu" || + lib.configOL.mode == "single" + ) + return; + if ( + lib.configOL.mode == "identity" && + (lib.configOL.identity_mode == "zhong" || lib.configOL.identity_mode == "purple") + ) + return; + if (!this.classList.contains("unselectable2") && lib.configOL.number <= 2) return; + this.classList.toggle("unselectable2"); + if (this.classList.contains("unselectable2")) { lib.configOL.number--; - } - else { + } else { lib.configOL.number++; } - game.send('server', 'config', lib.configOL); + game.send("server", "config", lib.configOL); game.updateWaiting(); } return; @@ -2703,29 +2813,29 @@ export class Click extends Uninstantable { custom.replace.target(this, e); return; } - if (this.classList.contains('selectable') == false) return; + if (this.classList.contains("selectable") == false) return; this.unprompt(); - if (this.classList.contains('selected')) { + if (this.classList.contains("selected")) { ui.selected.targets.remove(this); if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); + } else { + this.classList.remove("selected"); } - else { - this.classList.remove('selected'); - } - } - else { + } else { ui.selected.targets.add(this); - if (_status.event.name == 'chooseTarget' || _status.event.name == 'chooseToUse' || _status.event.name == 'chooseCardTarget') { + if ( + _status.event.name == "chooseTarget" || + _status.event.name == "chooseToUse" || + _status.event.name == "chooseCardTarget" + ) { var targetprompt = null; if (_status.event.targetprompt) { targetprompt = _status.event.targetprompt; - } - else if (_status.event.skill && !get.info(_status.event.skill).viewAs) { + } else if (_status.event.skill && !get.info(_status.event.skill).viewAs) { targetprompt = get.info(_status.event.skill).targetprompt; - } - else if (_status.event.name == 'chooseToUse') { + } else if (_status.event.name == "chooseToUse") { var currentcard = get.card(); if (currentcard) { targetprompt = get.info(currentcard).targetprompt; @@ -2733,45 +2843,46 @@ export class Click extends Uninstantable { } if (targetprompt) { if (Array.isArray(targetprompt)) { - targetprompt = targetprompt[Math.min(targetprompt.length - 1, ui.selected.targets.indexOf(this))]; - } - else if (typeof targetprompt == 'function') { + targetprompt = + targetprompt[ + Math.min(targetprompt.length - 1, ui.selected.targets.indexOf(this)) + ]; + } else if (typeof targetprompt == "function") { targetprompt = targetprompt(this); } - if (targetprompt && typeof targetprompt == 'string') { + if (targetprompt && typeof targetprompt == "string") { this.prompt(targetprompt); } } } - this.classList.add('selected'); + this.classList.add("selected"); } if (custom.add.target) { custom.add.target(); } game.check(); } - static control2() { + control2() { if (this.childNodes.length == 1 && !this._doubleclick) { ui.click.control.call(this.firstChild); } } - static control() { + control() { if (_status.dragged) return; - if (ui.control.classList.contains('hidden')) return; + if (ui.control.classList.contains("hidden")) return; var node = this.parentNode; if (node) { if (node._doubleclick) { return; - } - else { + } else { node._doubleclick = true; setTimeout(function () { node._doubleclick = false; }, 500); } - if (node.classList.contains('hidden')) return; - if (node.classList.contains('removing')) return; - if (node.classList.contains('disabled')) return; + if (node.classList.contains("hidden")) return; + if (node.classList.contains("removing")) return; + if (node.classList.contains("disabled")) return; } if (ui.intro) { ui.intro.close(); @@ -2782,19 +2893,17 @@ export class Click extends Uninstantable { this.parentNode.custom(this.link, this); return; } - if (this.link == 'ok') { + if (this.link == "ok") { ui.click.ok(this); - } - else if (this.link == 'cancel') { + } else if (this.link == "cancel") { ui.click.cancel(this); - } - else { + } else { _status.event.result = { buttons: ui.selected.buttons.slice(0), cards: ui.selected.cards.slice(0), targets: ui.selected.targets.slice(0), control: this.link, - links: get.links(ui.selected.buttons) + links: get.links(ui.selected.buttons), }; if (this.parentNode.close != false) { game.uncheck(); @@ -2803,17 +2912,17 @@ export class Click extends Uninstantable { game.resume(); } } - static dialogcontrol() { + dialogcontrol() { _status.event.result = { buttons: ui.selected.buttons.slice(0), cards: ui.selected.cards.slice(0), targets: ui.selected.targets.slice(0), control: this.link, - links: get.links(ui.selected.buttons) + links: get.links(ui.selected.buttons), }; game.resume(); } - static skill(skill) { + skill(skill) { var info = get.info(skill); var event = _status.event; event.backup(skill); @@ -2821,11 +2930,11 @@ export class Click extends Uninstantable { var cards = event.player.getCards(event.position); for (var i = 0; i < cards.length; i++) { if (!lib.filter.cardDiscardable(cards[i], event.player)) { - cards[i].uncheck('useSkill'); + cards[i].uncheck("useSkill"); } } } - if (typeof event.skillDialog == 'object') { + if (typeof event.skillDialog == "object") { event.skillDialog.close(); } if (event.isMine()) { @@ -2837,43 +2946,55 @@ export class Click extends Uninstantable { var str = get.translation(skill); if (info.prompt) { var str2; - if (typeof info.prompt == 'function') { + if (typeof info.prompt == "function") { str2 = info.prompt(event); - } - else { + } else { str2 = info.prompt; } - event.skillDialog = ui.create.dialog(str, '
                                      ' + str2 + '
                                      '); + event.skillDialog = ui.create.dialog( + str, + '
                                      ' + str2 + "
                                      " + ); if (info.longprompt) { event.skillDialog.forcebutton = true; ui.update(); } - } - else if (info.promptfunc) { - event.skillDialog = ui.create.dialog(str, '
                                      ' + info.promptfunc(event, event.player) + '
                                      '); - } - else if (lib.dynamicTranslate[skill]) { - event.skillDialog = ui.create.dialog(str, '
                                      ' + lib.dynamicTranslate[skill](event.player, skill) + '
                                      '); - } - else if (lib.translate[skill + '_info']) { - event.skillDialog = ui.create.dialog(str, '
                                      ' + lib.translate[skill + '_info'] + '
                                      '); + } else if (info.promptfunc) { + event.skillDialog = ui.create.dialog( + str, + '
                                      ' + info.promptfunc(event, event.player) + "
                                      " + ); + } else if (lib.dynamicTranslate[skill]) { + event.skillDialog = ui.create.dialog( + str, + '
                                      ' + + lib.dynamicTranslate[skill](event.player, skill) + + "
                                      " + ); + } else if (lib.translate[skill + "_info"]) { + event.skillDialog = ui.create.dialog( + str, + '
                                      ' + lib.translate[skill + "_info"] + "
                                      " + ); } } } - static ok(node) { - const gameEvent = get.event(), custom = gameEvent.custom, replaceConfirm = custom.replace.confirm; + ok(node) { + const gameEvent = get.event(), + custom = gameEvent.custom, + replaceConfirm = custom.replace.confirm; if (replaceConfirm) { replaceConfirm(true); return; } - const result = gameEvent.result = { + const result = (gameEvent.result = { buttons: ui.selected.buttons.slice(), cards: ui.selected.cards.slice(), targets: ui.selected.targets.slice(), - confirm: 'ok', + confirm: "ok", bool: true, - links: get.links(ui.selected.buttons) - }; + links: get.links(ui.selected.buttons), + }); if (node) node.parentNode.close(); const skill = gameEvent.skill; if (skill) { @@ -2882,12 +3003,12 @@ export class Click extends Uninstantable { if (info && info.direct && !info.clearTime) { result._noHidingTimer = true; } - const skillInformation = get.info(gameEvent.skill), viewAs = skillInformation.viewAs; - if (typeof viewAs == 'function') { + const skillInformation = get.info(gameEvent.skill), + viewAs = skillInformation.viewAs; + if (typeof viewAs == "function") { const viewedAs = viewAs(result.cards, gameEvent.player); if (viewedAs) result.card = get.autoViewAs(viewedAs); - } - else if (viewAs) result.card = get.autoViewAs(viewAs); + } else if (viewAs) result.card = get.autoViewAs(viewAs); const resultCard = result.card; if (resultCard) { const cards = result.cards; @@ -2898,11 +3019,11 @@ export class Click extends Uninstantable { } } const skillDialog = gameEvent.skillDialog; - if (skillDialog && get.objtype(skillDialog) == 'div') skillDialog.close(); - gameEvent.player.getCards('hej').forEach(card => card.recheck('useSkill')); + if (skillDialog && get.objtype(skillDialog) == "div") skillDialog.close(); + gameEvent.player.getCards("hej").forEach((card) => card.recheck("useSkill")); gameEvent.restore(); - } - else if (['chooseToUse', 'chooseToRespond'].includes(gameEvent.name)) result.card = get.autoViewAs(result.cards[0]); + } else if (["chooseToUse", "chooseToRespond"].includes(gameEvent.name)) + result.card = get.autoViewAs(result.cards[0]); if (ui.skills) ui.skills.close(); if (ui.skills2) ui.skills2.close(); if (ui.skills3) ui.skills3.close(); @@ -2911,34 +3032,35 @@ export class Click extends Uninstantable { if (addConfirm) addConfirm(true); game.resume(); } - static cancel(node) { + cancel(node) { var event = _status.event; if (event.custom.replace.confirm) { - event.custom.replace.confirm(false); return; + event.custom.replace.confirm(false); + return; } if (event.skill && !event.norestore) { - if (event.skillDialog && get.objtype(event.skillDialog) == 'div') { + if (event.skillDialog && get.objtype(event.skillDialog) == "div") { event.skillDialog.close(); } - if (typeof event.dialog == 'string' && event.isMine()) { + if (typeof event.dialog == "string" && event.isMine()) { event.dialog = ui.create.dialog(event.dialog); } - if (_status.event.type == 'phase' && ui.confirm) { - ui.confirm.classList.add('removing'); + if (_status.event.type == "phase" && ui.confirm) { + ui.confirm.classList.add("removing"); } // ui.control.addTempClass('nozoom',100); event.restore(); - var cards = event.player.getCards('hej'); + var cards = event.player.getCards("hej"); for (var i = 0; i < cards.length; i++) { - cards[i].recheck('useSkill'); + cards[i].recheck("useSkill"); } game.uncheck(); game.check(); return; } event.result = { - confirm: 'cancel', - bool: false + confirm: "cancel", + bool: false, }; if (node) { node.parentNode.close(); @@ -2952,7 +3074,7 @@ export class Click extends Uninstantable { } game.resume(); } - static logv(e) { + logv(e) { if (_status.currentlogv) { if (_status.currentlogv == this) return; if (_status.logvtimeout) { @@ -2966,13 +3088,12 @@ export class Click extends Uninstantable { } }, 200); this.logvtimeout = _status.logvtimeout; - } - else { + } else { _status.currentlogv = this; ui.click.intro.call(this, e); } } - static logvleave() { + logvleave() { if (_status.currentlogv == this) { setTimeout(function () { delete _status.currentlogv; @@ -2986,60 +3107,60 @@ export class Click extends Uninstantable { delete this.logvtimeout; } } - static charactercard(name, sourcenode, noedit, resume, avatar) { + charactercard(name, sourcenode, noedit, resume, avatar) { if (_status.dragged) return; - if (lib.config.theme != 'simple') { - ui.window.classList.add('shortcutpaused'); - ui.menuContainer.classList.add('forceopaque'); - } - else { - ui.window.classList.add('systempaused'); - ui.menuContainer.classList.add('transparent2'); + if (lib.config.theme != "simple") { + ui.window.classList.add("shortcutpaused"); + ui.menuContainer.classList.add("forceopaque"); + } else { + ui.window.classList.add("systempaused"); + ui.menuContainer.classList.add("transparent2"); } if (lib.config.blur_ui) { - ui.arena.classList.add('blur'); - ui.system.classList.add('blur'); - ui.menuContainer.classList.add('blur'); + ui.arena.classList.add("blur"); + ui.system.classList.add("blur"); + ui.menuContainer.classList.add("blur"); } - var layer = ui.create.div('.popup-container'); + var layer = ui.create.div(".popup-container"); var clicklayer = function (e) { if (_status.touchpopping) return; if (_status.dragged) return; - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); - ui.menuContainer.classList.remove('forceopaque'); - ui.menuContainer.classList.remove('transparent2'); - ui.arena.classList.remove('blur'); - ui.system.classList.remove('blur'); - ui.menuContainer.classList.remove('blur'); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); + ui.menuContainer.classList.remove("forceopaque"); + ui.menuContainer.classList.remove("transparent2"); + ui.arena.classList.remove("blur"); + ui.system.classList.remove("blur"); + ui.menuContainer.classList.remove("blur"); this.delete(); e.stopPropagation(); if (resume) game.resume2(); return false; }; - var uiintro = ui.create.div('.menubg.charactercard', layer); - var playerbg = ui.create.div('.menubutton.large.ava', uiintro); - var bg = ui.create.div('.avatar', playerbg, function () { - if (changeskinfunc) { - changeskinfunc(); - } - }).setBackground(name, 'character'); + var uiintro = ui.create.div(".menubg.charactercard", layer); + var playerbg = ui.create.div(".menubutton.large.ava", uiintro); + var bg = ui.create + .div(".avatar", playerbg, function () { + if (changeskinfunc) { + changeskinfunc(); + } + }) + .setBackground(name, "character"); var changeskinfunc = null; var nameskin = name; var nameskin2 = name; var gzbool = false; - if (nameskin.startsWith('gz_shibing')) { + if (nameskin.startsWith("gz_shibing")) { nameskin = nameskin.slice(3, 11); - } - else if (nameskin.startsWith('gz_')) { + } else if (nameskin.startsWith("gz_")) { nameskin = nameskin.slice(3); gzbool = true; } var changeskin = function () { - var node = ui.create.div('.changeskin', '可换肤', playerbg); - var avatars = ui.create.div('.avatars', playerbg); + var node = ui.create.div(".changeskin", "可换肤", playerbg); + var avatars = ui.create.div(".avatars", playerbg); changeskinfunc = function () { - playerbg.classList.add('scroll'); + playerbg.classList.add("scroll"); if (node._created) { return; } @@ -3047,43 +3168,49 @@ export class Click extends Uninstantable { var createButtons = function (num) { if (!num) return; if (num >= 4) { - avatars.classList.add('scroll'); + avatars.classList.add("scroll"); if (lib.config.touchscreen) { lib.setScroll(avatars); } } for (var i = 0; i <= num; i++) { var button = ui.create.div(avatars, function () { - playerbg.classList.remove('scroll'); + playerbg.classList.remove("scroll"); if (this._link) { lib.config.skin[nameskin] = this._link; bg.style.backgroundImage = this.style.backgroundImage; if (sourcenode) sourcenode.style.backgroundImage = this.style.backgroundImage; if (avatar) avatar.style.backgroundImage = this.style.backgroundImage; - game.saveConfig('skin', lib.config.skin); - } - else { + game.saveConfig("skin", lib.config.skin); + } else { delete lib.config.skin[nameskin]; - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) { - bg.setBackground(nameskin2, 'character'); - if (sourcenode) sourcenode.setBackground(nameskin2, 'character'); - if (avatar) avatar.setBackground(nameskin2, 'character'); + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) { + bg.setBackground(nameskin2, "character"); + if (sourcenode) sourcenode.setBackground(nameskin2, "character"); + if (avatar) avatar.setBackground(nameskin2, "character"); + } else { + bg.setBackground(nameskin, "character"); + if (sourcenode) sourcenode.setBackground(nameskin, "character"); + if (avatar) avatar.setBackground(nameskin, "character"); } - else { - bg.setBackground(nameskin, 'character'); - if (sourcenode) sourcenode.setBackground(nameskin, 'character'); - if (avatar) avatar.setBackground(nameskin, 'character'); - } - game.saveConfig('skin', lib.config.skin); + game.saveConfig("skin", lib.config.skin); } }); button._link = i; if (i) { - button.setBackgroundImage('image/skin/' + nameskin + '/' + i + '.jpg'); - } - else { - if (gzbool && lib.character[nameskin2][4].includes('gzskin') && lib.config.mode_config.guozhan.guozhanSkin) button.setBackground(nameskin2, 'character', 'noskin'); - else button.setBackground(nameskin, 'character', 'noskin'); + button.setBackgroundImage("image/skin/" + nameskin + "/" + i + ".jpg"); + } else { + if ( + gzbool && + lib.character[nameskin2][4].includes("gzskin") && + lib.config.mode_config.guozhan.guozhanSkin + ) + button.setBackground(nameskin2, "character", "noskin"); + else button.setBackground(nameskin, "character", "noskin"); } } }; @@ -3098,12 +3225,11 @@ export class Click extends Uninstantable { num--; createButtons(num); }; - img.src = lib.assetURL + 'image/skin/' + nameskin + '/' + num + '.jpg'; + img.src = lib.assetURL + "image/skin/" + nameskin + "/" + num + ".jpg"; }; if (lib.config.change_skin) { loadImage(); - } - else { + } else { createButtons(lib.skin[nameskin]); } }; @@ -3111,89 +3237,120 @@ export class Click extends Uninstantable { if (lib.config.change_skin) { var img = new Image(); img.onload = changeskin; - img.src = lib.assetURL + 'image/skin/' + nameskin + '/1.jpg'; - } - else if (lib.config.debug && lib.skin[nameskin]) { + img.src = lib.assetURL + "image/skin/" + nameskin + "/1.jpg"; + } else if (lib.config.debug && lib.skin[nameskin]) { changeskin(); } - var ban = ui.create.div('.menubutton.large.ban.character', uiintro, '禁用', function (e) { - if (this.classList.contains('unselectable')) return; - if (typeof noedit == 'string') { - this.classList.toggle('active'); - var bannedname = noedit + '_banned'; + var ban = ui.create.div(".menubutton.large.ban.character", uiintro, "禁用", function (e) { + if (this.classList.contains("unselectable")) return; + if (typeof noedit == "string") { + this.classList.toggle("active"); + var bannedname = noedit + "_banned"; if (!lib.config[bannedname]) { lib.config[bannedname] = []; } - if (this.classList.contains('active')) { + if (this.classList.contains("active")) { lib.config[bannedname].add(name); - } - else { + } else { lib.config[bannedname].remove(name); } game.saveConfig(bannedname, lib.config[bannedname]); ban.updateBanned(); - } - else { + } else { ui.click.touchpop(); ui.click.intro.call(this, e); _status.clicked = true; } }); ban.link = name; - ban._banning = 'offline'; + ban._banning = "offline"; ban.updateBanned = function () { if (noedit === true) return; - if (lib.config[get.mode() + '_banned'] && lib.config[get.mode() + '_banned'].includes(name)) { - ban.classList.add('active'); - } - else { - ban.classList.remove('active'); + if (lib.config[get.mode() + "_banned"] && lib.config[get.mode() + "_banned"].includes(name)) { + ban.classList.add("active"); + } else { + ban.classList.remove("active"); } if (sourcenode && sourcenode.updateBanned) { sourcenode.updateBanned(); } }; ban.updateBanned(); - var fav = ui.create.div('.menubutton.large.fav', uiintro, '收藏', function () { - if (this.classList.contains('unselectable')) return; - this.classList.toggle('active'); - if (this.classList.contains('active')) { + var fav = ui.create.div(".menubutton.large.fav", uiintro, "收藏", function () { + if (this.classList.contains("unselectable")) return; + this.classList.toggle("active"); + if (this.classList.contains("active")) { lib.config.favouriteCharacter.add(name); - } - else { + } else { lib.config.favouriteCharacter.remove(name); } - game.saveConfig('favouriteCharacter', lib.config.favouriteCharacter); + game.saveConfig("favouriteCharacter", lib.config.favouriteCharacter); }); if (noedit === true) { - fav.classList.add('unselectable'); - ban.classList.add('unselectable'); - } - else if (lib.config.favouriteCharacter.includes(name)) { - fav.classList.add('active'); + fav.classList.add("unselectable"); + ban.classList.add("unselectable"); + } else if (lib.config.favouriteCharacter.includes(name)) { + fav.classList.add("active"); } // 样式二 - if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') { - var intro = ui.create.div('.characterintro', get.characterIntro(name), uiintro); - if (lib.config.show_characternamepinyin == 'showPinyin2' || lib.config.show_characternamepinyin == 'showCodeIdentifier2') { + if ( + lib.config.show_characternamepinyin == "showPinyin2" || + lib.config.show_skillnamepinyin == "showPinyin2" || + lib.config.show_characternamepinyin == "showCodeIdentifier2" || + lib.config.show_skillnamepinyin == "showCodeIdentifier2" + ) { + var intro = ui.create.div(".characterintro", get.characterIntro(name), uiintro); + if ( + lib.config.show_characternamepinyin == "showPinyin2" || + lib.config.show_characternamepinyin == "showCodeIdentifier2" + ) { var charactername = get.rawName2(name); - var characterpinyin = lib.config.show_characternamepinyin == 'showCodeIdentifier2' ? name : get.pinyin(charactername); + var characterpinyin = + lib.config.show_characternamepinyin == "showCodeIdentifier2" + ? name + : get.pinyin(charactername); var nameinfo = get.character(name); var charactersex = get.translation(nameinfo[0]); const charactergroups = get.is.double(name, true); let charactergroup; - if (charactergroups) charactergroup = charactergroups.map(i => get.translation(i)).join('/'); + if (charactergroups) + charactergroup = charactergroups.map((i) => get.translation(i)).join("/"); else charactergroup = get.translation(nameinfo[1]); var characterhp = nameinfo[2]; var characterintroinfo = get.characterIntro(name); - var spacemark = ' | '; - if (charactername.length > 3) spacemark = '' + ' ' + '' + '|' + '' + ' ' + ''; - intro.innerHTML = '' + charactername + '' + '' + '[' + characterpinyin + ']' + '' + spacemark + charactersex + spacemark + charactergroup + spacemark + characterhp + '' + '
                                      ' + characterintroinfo; + var spacemark = " | "; + if (charactername.length > 3) + spacemark = + '' + + " " + + "" + + "|" + + '' + + " " + + ""; + intro.innerHTML = + '' + + charactername + + "" + + '' + + "[" + + characterpinyin + + "]" + + "" + + spacemark + + charactersex + + spacemark + + charactergroup + + spacemark + + characterhp + + '' + + "
                                      " + + characterintroinfo; } - var intro2 = ui.create.div('.characterintro.intro2', uiintro); + var intro2 = ui.create.div(".characterintro.intro2", uiintro); var list = get.character(name, 3) || []; - var skills = ui.create.div('.characterskill', uiintro); + var skills = ui.create.div(".characterskill", uiintro); if (lib.config.touchscreen) { lib.setScroll(intro); lib.setScroll(intro2); @@ -3207,18 +3364,39 @@ export class Click extends Uninstantable { while (intro2.firstChild) { intro2.removeChild(intro2.lastChild); } - var current = this.parentNode.querySelector('.active'); + var current = this.parentNode.querySelector(".active"); if (current) { - current.classList.remove('active'); + current.classList.remove("active"); } - this.classList.add('active'); + this.classList.add("active"); var skillname = get.translation(this.link); var skilltranslationinfo = get.skillInfoTranslation(this.link); - if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && skillname != '阵亡') { - var skillpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? this.link : get.pinyin(skillname); - intro2.innerHTML = '' + skillname + '' + '' + '[' + skillpinyin + ']' + '' + ' ' + skilltranslationinfo; + if ( + (lib.config.show_skillnamepinyin == "showPinyin2" || + lib.config.show_skillnamepinyin == "showCodeIdentifier2") && + skillname != "阵亡" + ) { + var skillpinyin = + lib.config.show_skillnamepinyin == "showCodeIdentifier2" + ? this.link + : get.pinyin(skillname); + intro2.innerHTML = + '' + + skillname + + "" + + '' + + "[" + + skillpinyin + + "]" + + "" + + " " + + skilltranslationinfo; } else { - intro2.innerHTML = '' + skillname + '' + skilltranslationinfo; + intro2.innerHTML = + '' + + skillname + + "" + + skilltranslationinfo; } var info = get.info(this.link); var skill = this.link; @@ -3226,51 +3404,76 @@ export class Click extends Uninstantable { var skillnode = this; if (info.derivation) { var derivation = info.derivation; - if (typeof derivation == 'string') { + if (typeof derivation == "string") { derivation = [derivation]; } for (var i = 0; i < derivation.length; i++) { var derivationname = get.translation(derivation[i]); var derivationtranslationinfo = get.skillInfoTranslation(derivation[i]); - if ((lib.config.show_skillnamepinyin == 'showPinyin2' || lib.config.show_skillnamepinyin == 'showCodeIdentifier2') && derivationname.length <= 5 && derivation[i].indexOf('_faq') == -1) { - var derivationpinyin = lib.config.show_skillnamepinyin == 'showCodeIdentifier2' ? derivation[i] : get.pinyin(derivationname); - intro2.innerHTML += '

                                      ' + derivationname + '' + '' + '[' + derivationpinyin + ']' + '' + ' ' + derivationtranslationinfo; + if ( + (lib.config.show_skillnamepinyin == "showPinyin2" || + lib.config.show_skillnamepinyin == "showCodeIdentifier2") && + derivationname.length <= 5 && + derivation[i].indexOf("_faq") == -1 + ) { + var derivationpinyin = + lib.config.show_skillnamepinyin == "showCodeIdentifier2" + ? derivation[i] + : get.pinyin(derivationname); + intro2.innerHTML += + '

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

                                      ' + derivationname + '' + derivationtranslationinfo; + intro2.innerHTML += + '

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

                                      '; - var skillversionnode = intro2.querySelector('.hrefnode.skillversion'); + var skillversionnode = intro2.querySelector(".hrefnode.skillversion"); if (lib.config.vintageSkills.includes(skill)) { - skillversionnode.innerHTML = '切换至新版'; - } - else { - skillversionnode.innerHTML = '切换至旧版'; + skillversionnode.innerHTML = "切换至新版"; + } else { + skillversionnode.innerHTML = "切换至旧版"; } skillversionnode.listen(function () { if (lib.config.vintageSkills.includes(skill)) { lib.config.vintageSkills.remove(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; - } - else { + lib.translate[skill + "_info"] = lib.translate[skill + "_info_alter"]; + } else { lib.config.vintageSkills.push(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; + lib.translate[skill + "_info"] = lib.translate[skill + "_info_origin"]; } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - clickSkill.call(skillnode, 'init'); + game.saveConfig("vintageSkills", lib.config.vintageSkills); + clickSkill.call(skillnode, "init"); }); } // if(e!=='init') game.trySkillAudio(this.link,playername); // 有bug,先用旧版 - if (lib.config.background_speak && e !== 'init') { - let audio, skillnode = this; + if (lib.config.background_speak && e !== "init") { + let audio, + skillnode = this; const playedAudios = []; (function play() { if (!skillnode.audioList || !skillnode.audioList.length) { skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); - if (!skillnode.audioList.length||skillnode.audioList.length==playedAudios.length) return; + if ( + !skillnode.audioList.length || + skillnode.audioList.length == playedAudios.length + ) + return; } audio = skillnode.audioList.shift(); playedAudios.push(audio); @@ -3278,100 +3481,149 @@ export class Click extends Uninstantable { })(); } }; - } - else { + } else { // 样式一 - const introduction = ui.create.div('.characterintro', uiintro), showCharacterNamePinyin = lib.config.show_characternamepinyin; - if (showCharacterNamePinyin != 'doNotShow') { - const characterIntroTable = ui.create.div('.character-intro-table', introduction), span = document.createElement('span'); - span.style.fontWeight = 'bold'; - const nameInfo = get.character(name), exInfo = nameInfo[4], characterName = exInfo && exInfo.includes('ruby') ? lib.translate[name] : get.rawName2(name); + const introduction = ui.create.div(".characterintro", uiintro), + showCharacterNamePinyin = lib.config.show_characternamepinyin; + if (showCharacterNamePinyin != "doNotShow") { + const characterIntroTable = ui.create.div(".character-intro-table", introduction), + span = document.createElement("span"); + span.style.fontWeight = "bold"; + const nameInfo = get.character(name), + exInfo = nameInfo[4], + characterName = + exInfo && exInfo.includes("ruby") ? lib.translate[name] : get.rawName2(name); span.innerHTML = characterName; - const ruby = document.createElement('ruby'); + const ruby = document.createElement("ruby"); ruby.appendChild(span); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; + const leftParenthesisRP = document.createElement("rp"); + leftParenthesisRP.textContent = "("; ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showCharacterNamePinyin == 'showCodeIdentifier' ? name : lib.translate[`${name}_rt`] || get.pinyin(characterName).join(' '); + const rt = document.createElement("rt"); + rt.innerHTML = + showCharacterNamePinyin == "showCodeIdentifier" + ? name + : lib.translate[`${name}_rt`] || get.pinyin(characterName).join(" "); ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; + const rightParenthesisRP = document.createElement("rp"); + rightParenthesisRP.textContent = ")"; ruby.appendChild(rightParenthesisRP); characterIntroTable.appendChild(ruby); - const characterSexDiv = ui.create.div('.character-sex', characterIntroTable), exInfoSex = exInfo && exInfo.find(value => value.startsWith('sex:')), characterSex = exInfoSex ? exInfoSex.split(':').pop() : nameInfo[0]; + const characterSexDiv = ui.create.div(".character-sex", characterIntroTable), + exInfoSex = exInfo && exInfo.find((value) => value.startsWith("sex:")), + characterSex = exInfoSex ? exInfoSex.split(":").pop() : nameInfo[0]; new Promise((resolve, reject) => { - const imageName = `sex_${characterSex}`, information = lib.card[imageName]; + const imageName = `sex_${characterSex}`, + information = lib.card[imageName]; if (!information) { resolve(`${lib.assetURL}image/card/${imageName}.png`); return; } const image = information.image; if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); + else if (image.startsWith("db:")) + game.getDB("image", image.slice(3)).then(resolve, reject); + else if (image.startsWith("ext:")) + resolve(`${lib.assetURL}${image.replace(/^ext:/, "extension/")}`); else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })).then(image => characterSexDiv.appendChild(image)).catch(() => characterSexDiv.innerHTML = get.translation(characterSex)); - const characterGroupDiv = ui.create.div('.character-group', characterIntroTable), characterGroups = get.is.double(name, true); - if (characterGroups) Promise.all(characterGroups.map(characterGroup => new Promise((resolve, reject) => { - const imageName = `group_${characterGroup}`, information = lib.card[imageName]; - if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); - const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); - else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })))).then(images => { - let documentFragment = document.createDocumentFragment(); - images.forEach(documentFragment.appendChild, documentFragment); - characterGroupDiv.appendChild(documentFragment); - }).catch(() => characterGroupDiv.innerHTML = characterGroups.map(characterGroup => get.translation(characterGroup)).join('/')); + }) + .then( + (source) => + new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + }) + ) + .then((image) => characterSexDiv.appendChild(image)) + .catch(() => (characterSexDiv.innerHTML = get.translation(characterSex))); + const characterGroupDiv = ui.create.div(".character-group", characterIntroTable), + characterGroups = get.is.double(name, true); + if (characterGroups) + Promise.all( + characterGroups.map((characterGroup) => + new Promise((resolve, reject) => { + const imageName = `group_${characterGroup}`, + information = lib.card[imageName]; + if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); + const image = information.image; + if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); + else if (image.startsWith("db:")) + game.getDB("image", image.slice(3)).then(resolve, reject); + else if (image.startsWith("ext:")) + resolve(`${lib.assetURL}${image.replace(/^ext:/, "extension/")}`); + else resolve(`${lib.assetURL}${image}`); + }).then( + (source) => + new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + }) + ) + ) + ) + .then((images) => { + let documentFragment = document.createDocumentFragment(); + images.forEach(documentFragment.appendChild, documentFragment); + characterGroupDiv.appendChild(documentFragment); + }) + .catch( + () => + (characterGroupDiv.innerHTML = characterGroups + .map((characterGroup) => get.translation(characterGroup)) + .join("/")) + ); else { const characterGroup = nameInfo[1]; new Promise((resolve, reject) => { - const imageName = `group_${characterGroup}`, information = lib.card[imageName]; + const imageName = `group_${characterGroup}`, + information = lib.card[imageName]; if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); const image = information.image; if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith('db:')) game.getDB('image', image.slice(3)).then(resolve, reject); - else if (image.startsWith('ext:')) resolve(`${lib.assetURL}${image.replace(/^ext:/, 'extension/')}`); + else if (image.startsWith("db:")) + game.getDB("image", image.slice(3)).then(resolve, reject); + else if (image.startsWith("ext:")) + resolve(`${lib.assetURL}${image.replace(/^ext:/, "extension/")}`); else resolve(`${lib.assetURL}${image}`); - }).then(source => new Promise((resolve, reject) => { - const image = new Image(); - image.onload = () => resolve(image); - image.onerror = reject; - image.src = source; - })).then(image => characterGroupDiv.appendChild(image)).catch(() => characterGroupDiv.innerHTML = get.translation(characterGroup)); + }) + .then( + (source) => + new Promise((resolve, reject) => { + const image = new Image(); + image.onload = () => resolve(image); + image.onerror = reject; + image.src = source; + }) + ) + .then((image) => characterGroupDiv.appendChild(image)) + .catch(() => (characterGroupDiv.innerHTML = get.translation(characterGroup))); } - const hpDiv = ui.create.div('.hp', characterIntroTable), nameInfoHP = nameInfo[2], infoHP = get.infoHp(nameInfoHP); - hpDiv.dataset.condition = infoHP < 4 ? 'mid' : 'high'; + const hpDiv = ui.create.div(".hp", characterIntroTable), + nameInfoHP = nameInfo[2], + infoHP = get.infoHp(nameInfoHP); + hpDiv.dataset.condition = infoHP < 4 ? "mid" : "high"; ui.create.div(hpDiv); - const hpTextDiv = ui.create.div('.text', hpDiv), infoMaxHP = get.infoMaxHp(nameInfoHP); + const hpTextDiv = ui.create.div(".text", hpDiv), + infoMaxHP = get.infoMaxHp(nameInfoHP); hpTextDiv.innerHTML = infoHP == infoMaxHP ? `×${infoHP}` : `×${infoHP}/${infoMaxHP}`; const infoShield = get.infoHujia(nameInfoHP); if (infoShield) { - ui.create.div('.shield', hpDiv); - const shieldTextDiv = ui.create.div('.text', hpDiv); + ui.create.div(".shield", hpDiv); + const shieldTextDiv = ui.create.div(".text", hpDiv); shieldTextDiv.innerHTML = `×${infoShield}`; } - introduction.appendChild(document.createElement('hr')); + introduction.appendChild(document.createElement("hr")); } - const htmlParser = document.createElement('body'); + const htmlParser = document.createElement("body"); htmlParser.innerHTML = get.characterIntro(name); - Array.from(htmlParser.childNodes).forEach(value => introduction.appendChild(value)); - const introduction2 = ui.create.div('.characterintro.intro2', uiintro); + Array.from(htmlParser.childNodes).forEach((value) => introduction.appendChild(value)); + const introduction2 = ui.create.div(".characterintro.intro2", uiintro); var list = get.character(name, 3) || []; - var skills = ui.create.div('.characterskill', uiintro); + var skills = ui.create.div(".characterskill", uiintro); if (lib.config.touchscreen) { lib.setScroll(introduction); lib.setScroll(introduction2); @@ -3385,109 +3637,128 @@ export class Click extends Uninstantable { while (introduction2.firstChild) { introduction2.removeChild(introduction2.lastChild); } - var current = this.parentNode.querySelector('.active'); + var current = this.parentNode.querySelector(".active"); if (current) { - current.classList.remove('active'); + current.classList.remove("active"); } - this.classList.add('active'); - const skillNameSpan = document.createElement('span'), skillNameSpanStyle = skillNameSpan.style; - skillNameSpanStyle.fontWeight = 'bold'; - const link = this.link, skillName = get.translation(link); + this.classList.add("active"); + const skillNameSpan = document.createElement("span"), + skillNameSpanStyle = skillNameSpan.style; + skillNameSpanStyle.fontWeight = "bold"; + const link = this.link, + skillName = get.translation(link); skillNameSpan.innerHTML = skillName; const showSkillNamePinyin = lib.config.show_skillnamepinyin; - if (showSkillNamePinyin != 'doNotShow' && skillName != '阵亡') { - const ruby = document.createElement('ruby'); + if (showSkillNamePinyin != "doNotShow" && skillName != "阵亡") { + const ruby = document.createElement("ruby"); ruby.appendChild(skillNameSpan); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; + const leftParenthesisRP = document.createElement("rp"); + leftParenthesisRP.textContent = "("; ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? link : lib.translate[`${link}_rt`] || get.pinyin(skillName).join(' '); + const rt = document.createElement("rt"); + rt.innerHTML = + showSkillNamePinyin == "showCodeIdentifier" + ? link + : lib.translate[`${link}_rt`] || get.pinyin(skillName).join(" "); ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; + const rightParenthesisRP = document.createElement("rp"); + rightParenthesisRP.textContent = ")"; ruby.appendChild(rightParenthesisRP); const div = ui.create.div(introduction2); - div.style.marginRight = '5px'; + div.style.marginRight = "5px"; div.appendChild(ruby); - } - else { - skillNameSpanStyle.marginRight = '5px'; + } else { + skillNameSpanStyle.marginRight = "5px"; introduction2.appendChild(skillNameSpan); } htmlParser.innerHTML = get.skillInfoTranslation(this.link); - Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); + Array.from(htmlParser.childNodes).forEach((childNode) => + introduction2.appendChild(childNode) + ); var info = get.info(this.link); var skill = this.link; var playername = this.linkname; var skillnode = this; let derivations = info.derivation; if (derivations) { - if (typeof derivations == 'string') derivations = [derivations]; - derivations.forEach(derivation => { - introduction2.appendChild(document.createElement('br')); - introduction2.appendChild(document.createElement('br')); - const derivationNameSpan = document.createElement('span'), derivationNameSpanStyle = derivationNameSpan.style; - derivationNameSpanStyle.fontWeight = 'bold'; + if (typeof derivations == "string") derivations = [derivations]; + derivations.forEach((derivation) => { + introduction2.appendChild(document.createElement("br")); + introduction2.appendChild(document.createElement("br")); + const derivationNameSpan = document.createElement("span"), + derivationNameSpanStyle = derivationNameSpan.style; + derivationNameSpanStyle.fontWeight = "bold"; const derivationName = get.translation(derivation); derivationNameSpan.innerHTML = derivationName; - if (showSkillNamePinyin != 'doNotShow' && derivationName.length <= 5 && derivation.indexOf('_faq') == -1) { - const ruby = document.createElement('ruby'); + if ( + showSkillNamePinyin != "doNotShow" && + derivationName.length <= 5 && + derivation.indexOf("_faq") == -1 + ) { + const ruby = document.createElement("ruby"); ruby.appendChild(derivationNameSpan); - const leftParenthesisRP = document.createElement('rp'); - leftParenthesisRP.textContent = '('; + const leftParenthesisRP = document.createElement("rp"); + leftParenthesisRP.textContent = "("; ruby.appendChild(leftParenthesisRP); - const rt = document.createElement('rt'); - rt.innerHTML = showSkillNamePinyin == 'showCodeIdentifier' ? derivation : lib.translate[`${derivation}_rt`] || get.pinyin(derivationName).join(' '); + const rt = document.createElement("rt"); + rt.innerHTML = + showSkillNamePinyin == "showCodeIdentifier" + ? derivation + : lib.translate[`${derivation}_rt`] || + get.pinyin(derivationName).join(" "); ruby.appendChild(rt); - const rightParenthesisRP = document.createElement('rp'); - rightParenthesisRP.textContent = ')'; + const rightParenthesisRP = document.createElement("rp"); + rightParenthesisRP.textContent = ")"; ruby.appendChild(rightParenthesisRP); const div = ui.create.div(introduction2); - div.style.marginRight = '5px'; + div.style.marginRight = "5px"; div.appendChild(ruby); - } - else { - derivationNameSpanStyle.marginRight = '5px'; + } else { + derivationNameSpanStyle.marginRight = "5px"; introduction2.appendChild(derivationNameSpan); } htmlParser.innerHTML = get.skillInfoTranslation(derivation); - Array.from(htmlParser.childNodes).forEach(childNode => introduction2.appendChild(childNode)); + Array.from(htmlParser.childNodes).forEach((childNode) => + introduction2.appendChild(childNode) + ); }); } if (info.alter) { - introduction2.appendChild(document.createElement('br')); - introduction2.appendChild(document.createElement('br')); - ui.create.div('.hrefnode.skillversion', introduction2); - var skillversionnode = introduction2.querySelector('.hrefnode.skillversion'); + introduction2.appendChild(document.createElement("br")); + introduction2.appendChild(document.createElement("br")); + ui.create.div(".hrefnode.skillversion", introduction2); + var skillversionnode = introduction2.querySelector(".hrefnode.skillversion"); if (lib.config.vintageSkills.includes(skill)) { - skillversionnode.innerHTML = '切换至新版'; - } - else { - skillversionnode.innerHTML = '切换至旧版'; + skillversionnode.innerHTML = "切换至新版"; + } else { + skillversionnode.innerHTML = "切换至旧版"; } skillversionnode.listen(function () { if (lib.config.vintageSkills.includes(skill)) { lib.config.vintageSkills.remove(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_alter']; - } - else { + lib.translate[skill + "_info"] = lib.translate[skill + "_info_alter"]; + } else { lib.config.vintageSkills.push(skill); - lib.translate[skill + '_info'] = lib.translate[skill + '_info_origin']; + lib.translate[skill + "_info"] = lib.translate[skill + "_info_origin"]; } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - clickSkill.call(skillnode, 'init'); + game.saveConfig("vintageSkills", lib.config.vintageSkills); + clickSkill.call(skillnode, "init"); }); } // if(e!=='init') game.trySkillAudio(this.link,playername); // 有bug,先用旧版 - if (lib.config.background_speak && e !== 'init') { - let audio, skillnode = this; + if (lib.config.background_speak && e !== "init") { + let audio, + skillnode = this; const playedAudios = []; (function play() { if (!skillnode.audioList || !skillnode.audioList.length) { skillnode.audioList = game.parseSkillAudio(skillnode.link, playername); - if (!skillnode.audioList.length||skillnode.audioList.length==playedAudios.length) return; + if ( + !skillnode.audioList.length || + skillnode.audioList.length == playedAudios.length + ) + return; } audio = skillnode.audioList.shift(); playedAudios.push(audio); @@ -3500,69 +3771,72 @@ export class Click extends Uninstantable { var initskill = false; for (var i = 0; i < list.length; i++) { if (!get.info(list[i]) || get.info(list[i]).nopop) continue; - if (!lib.translate[list[i]] || !lib.translate[list[i] + '_info']) continue; + if (!lib.translate[list[i]] || !lib.translate[list[i] + "_info"]) continue; var skilltrans = get.translation(list[i]); - if (skilltrans.startsWith(' ')) { + if (skilltrans.startsWith(" ")) { skilltrans = skilltrans.slice(6); } - var current = ui.create.div('.menubutton.large', skills, clickSkill, skilltrans); + var current = ui.create.div(".menubutton.large", skills, clickSkill, skilltrans); current.link = list[i]; current.linkname = name; if (!initskill) { initskill = true; - clickSkill.call(current, 'init'); + clickSkill.call(current, "init"); } } - uiintro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.touchpop); - layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); + uiintro.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.touchpop); + layer.addEventListener(lib.config.touchscreen ? "touchend" : "click", clicklayer); ui.window.appendChild(layer); } - static intro(e) { + intro(e) { if (_status.dragged) return; _status.clicked = true; - if (this.classList.contains('player') && !this.name) { + if (this.classList.contains("player") && !this.name) { return; } if (this.parentNode == ui.historybar) { - if (ui.historybar.style.zIndex == '22') { + if (ui.historybar.style.zIndex == "22") { if (_status.removePop) { if (_status.removePop(this) == false) return; - } - else { + } else { return; } } ui.historybar.style.zIndex = 22; } var uiintro; - if (this.classList.contains('card') && this.parentNode && - this.parentNode.classList.contains('equips') && get.is.phoneLayout() && - !get.is.mobileMe(this.parentNode.parentNode)) { + if ( + this.classList.contains("card") && + this.parentNode && + this.parentNode.classList.contains("equips") && + get.is.phoneLayout() && + !get.is.mobileMe(this.parentNode.parentNode) + ) { uiintro = get.nodeintro(this.parentNode.parentNode, false, e); } uiintro = uiintro || get.nodeintro(this, false, e); if (!uiintro) return; - uiintro.classList.add('popped'); - uiintro.classList.add('static'); + uiintro.classList.add("popped"); + uiintro.classList.add("static"); ui.window.appendChild(uiintro); - var layer = ui.create.div('.poplayer', ui.window); + var layer = ui.create.div(".poplayer", ui.window); var clicklayer = function (e) { if (_status.touchpopping) return; delete ui.throwEmotion; delete _status.removePop; uiintro.delete(); this.remove(); - ui.historybar.style.zIndex = ''; + ui.historybar.style.zIndex = ""; delete _status.currentlogv; - if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); + if (!ui.arena.classList.contains("menupaused") && !uiintro.noresume) game.resume2(); if (e && e.stopPropagation) e.stopPropagation(); if (uiintro._onclose) { uiintro._onclose(); } return false; }; - layer.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clicklayer); + layer.addEventListener(lib.config.touchscreen ? "touchend" : "click", clicklayer); if (!lib.config.touchscreen) layer.oncontextmenu = clicklayer; if (this.parentNode == ui.historybar && lib.config.touchscreen) { var rect = this.getBoundingClientRect(); @@ -3570,11 +3844,10 @@ export class Click extends Uninstantable { } lib.placePoppedDialog(uiintro, e); if (this.parentNode == ui.historybar) { - if (lib.config.show_history == 'right') { - uiintro.style.left = (ui.historybar.offsetLeft - 230) + 'px'; - } - else { - uiintro.style.left = (ui.historybar.offsetLeft + 60) + 'px'; + if (lib.config.show_history == "right") { + uiintro.style.left = ui.historybar.offsetLeft - 230 + "px"; + } else { + uiintro.style.left = ui.historybar.offsetLeft + 60 + "px"; } } uiintro.style.zIndex = 21; @@ -3583,9 +3856,9 @@ export class Click extends Uninstantable { delete _status.removePop; layer.remove(); this.delete(); - ui.historybar.style.zIndex = ''; + ui.historybar.style.zIndex = ""; delete _status.currentlogv; - if (!ui.arena.classList.contains('menupaused') && !uiintro.noresume) game.resume2(); + if (!ui.arena.classList.contains("menupaused") && !uiintro.noresume) game.resume2(); if (uiintro._onclose) { uiintro._onclose(); } @@ -3603,12 +3876,10 @@ export class Click extends Uninstantable { _status.clicked = true; }); uiintro._clickintro = clicklayer; - } - else if (!lib.config.touchscreen) { - uiintro.addEventListener('mouseleave', clickintro); - uiintro.addEventListener('click', clickintro); - } - else if (uiintro.touchclose) { + } else if (!lib.config.touchscreen) { + uiintro.addEventListener("mouseleave", clickintro); + uiintro.addEventListener("click", clickintro); + } else if (uiintro.touchclose) { uiintro.listen(clickintro); } uiintro._close = clicklayer; @@ -3616,7 +3887,7 @@ export class Click extends Uninstantable { game.pause2(); return uiintro; } - static intro2() { + intro2() { if (ui.intro) { ui.intro.close(); if (ui.intro.source == this) { @@ -3627,71 +3898,76 @@ export class Click extends Uninstantable { } } } - static auto() { - if (!ui || !ui.auto || ui.auto.classList.contains('hidden') && arguments[0] !== 'forced') return; + auto() { + if (!ui || !ui.auto || (ui.auto.classList.contains("hidden") && arguments[0] !== "forced")) return; if (_status.paused2) return; ui.click.shortcut(false); if (!_status.auto) { _status.auto = true; - ui.auto.classList.add('glow'); - ui.arena.classList.add('auto'); + ui.auto.classList.add("glow"); + ui.arena.classList.add("auto"); if (_status.imchoosing && _status.paused) { if (ui.confirm) ui.confirm.close(); ui.control.hide(); if (_status.event.switchToAuto) { _status.event.switchToAuto(); - } - else { + } else { if (_status.paused && _status.imchoosing) { game.uncheck(); _status.event.redo(); } } game.resume(); - } - else if (_status.event.switchToAuto) { + } else if (_status.event.switchToAuto) { _status.event.switchToAuto(); } if (game.online) { - game.send('auto'); - } - else if (_status.connectMode) { + game.send("auto"); + } else if (_status.connectMode) { game.broadcastAll(function (player) { - player.setNickname(player.nickname + ' - 托管'); + player.setNickname(player.nickname + " - 托管"); }, game.me); } - } - else { + } else { if (game.notMe) return; ui.control.show(); _status.auto = false; - ui.auto.classList.remove('glow'); - ui.arena.classList.remove('auto'); + ui.auto.classList.remove("glow"); + ui.arena.classList.remove("auto"); if (game.online) { - game.send('unauto'); - } - else if (_status.connectMode) { + game.send("unauto"); + } else if (_status.connectMode) { game.broadcastAll(function (player) { player.setNickname(player.nickname); }, game.me); } } } - static wuxie() { - if (this.classList.contains('hidden')) return; - this.classList.toggle('glow'); - if (this.classList.contains('glow') && _status.event.type == 'wuxie' && - _status.event.isMine() && ui.confirm && _status.imchoosing) { + wuxie() { + if (this.classList.contains("hidden")) return; + this.classList.toggle("glow"); + if ( + this.classList.contains("glow") && + _status.event.type == "wuxie" && + _status.event.isMine() && + ui.confirm && + _status.imchoosing + ) { ui.click.cancel(ui.confirm.lastChild); } } - static tempnowuxie() { - if (this.classList.contains('hidden')) return; - this.classList.toggle('glow'); - if (this.classList.contains('glow') && _status.event.type == 'wuxie' && - _status.event.isMine() && ui.confirm && _status.imchoosing) { + tempnowuxie() { + if (this.classList.contains("hidden")) return; + this.classList.toggle("glow"); + if ( + this.classList.contains("glow") && + _status.event.type == "wuxie" && + _status.event.isMine() && + ui.confirm && + _status.imchoosing + ) { var triggerevent = _status.event.getTrigger(); if (triggerevent && this._origin == triggerevent.parent.id) { if (triggerevent.targets && triggerevent.num == triggerevent.targets.length - 1) { @@ -3701,18 +3977,18 @@ export class Click extends Uninstantable { ui.click.cancel(ui.confirm.lastChild); } } - static pause() { + pause() { if (_status.paused2 || _status.pausing || _status.nopause || !ui.pause) return; if (!_status.video) { - if (ui.pause.classList.contains('hidden')) return; + if (ui.pause.classList.contains("hidden")) return; if (!_status.gameStarted) return; } ui.system.hide(); game.pause2(); var node = ui.create.pause(); if (!node) return; - node.addTempClass('start'); - ui.sidebar3.innerHTML = ''; + node.addTempClass("start"); + ui.sidebar3.innerHTML = ""; if (lib.config.show_discardpile) { for (var i = 0; i < ui.discardPile.childNodes.length; i++) { var div = ui.create.div(ui.sidebar3); @@ -3722,24 +3998,24 @@ export class Click extends Uninstantable { } node.appendChild(ui.sidebar); node.appendChild(ui.sidebar3); - ui.historybar.classList.add('paused'); - ui.arena.classList.add('paused'); - ui.window.classList.add('touchinfohidden'); + ui.historybar.classList.add("paused"); + ui.arena.classList.add("paused"); + ui.window.classList.add("touchinfohidden"); ui.time.hide(); if (game.onpause) { game.onpause(); } } - static resume(e) { + resume(e) { if (_status.pausing) return; if (_status.dragged) return; if (_status.clicked) return; this.delete(); ui.system.show(); ui.time.show(); - ui.historybar.classList.remove('paused'); - ui.arena.classList.remove('paused'); - ui.window.classList.remove('touchinfohidden'); + ui.historybar.classList.remove("paused"); + ui.arena.classList.remove("paused"); + ui.window.classList.remove("touchinfohidden"); game.resume2(); e.stopPropagation(); if (game.onresume) { @@ -3747,7 +4023,7 @@ export class Click extends Uninstantable { } return false; } - static config() { + config() { if (!ui.click.configMenu) return; if (_status.paused2) _status.config2 = false; else _status.config2 = true; @@ -3755,20 +4031,24 @@ export class Click extends Uninstantable { _status.clicked = true; game.pause2(); ui.click.configMenu(); - ui.system1.classList.remove('shown'); - ui.system2.classList.remove('shown'); + ui.system1.classList.remove("shown"); + ui.system2.classList.remove("shown"); } - static swap() { + swap() { if (_status.dragged) return; - if (this.classList.contains('dead')) return; + if (this.classList.contains("dead")) return; if (_status.over) return; if (ui.auto) ui.auto.show(); if (ui.wuxie) ui.wuxie.show(); game.swapPlayer(this); } - static mousewheel(evt) { - if (this.firstChild && this.firstChild.classList.contains('handcards') && - !this.classList.contains('scrollh')) return; + mousewheel(evt) { + if ( + this.firstChild && + this.firstChild.classList.contains("handcards") && + !this.classList.contains("scrollh") + ) + return; var node = this; var num = this._scrollnum || 6; var speed = this._scrollspeed || 16; @@ -3777,109 +4057,109 @@ export class Click extends Uninstantable { node.interval = setInterval(function () { if (num-- && Math.abs(node.scrollLeft + node.clientWidth - node.scrollWidth) > 0) { node.scrollLeft += speed; - } - else { + } else { clearInterval(node.interval); } }, 16); - } - else { + } else { node.interval = setInterval(function () { if (num-- && node.scrollLeft > 0) { node.scrollLeft -= speed; - } - else { + } else { clearInterval(node.interval); } }, 16); } } - static touchStart(e) { + touchStart(e) { this.startX = e.touches[0].clientX / game.documentZoom; this.startY = e.touches[0].clientY / game.documentZoom; _status.dragged = false; } - static dialogtouchStart(e) { + dialogtouchStart(e) { ui.click.touchStart.call(this, e); _status.dialogtouched = true; } - static touchScroll(e) { + touchScroll(e) { if (_status.mousedragging) return; if (_status.draggingtouchdialog) return; if (!_status.dragged) { - if (Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || - Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10) { + if ( + Math.abs(e.touches[0].clientX / game.documentZoom - this.startX) > 10 || + Math.abs(e.touches[0].clientY / game.documentZoom - this.startY) > 10 + ) { _status.dragged = true; } } - if ((this == ui.handcards1Container || this == ui.handcards2Container) && !this.classList.contains('scrollh')) { + if ( + (this == ui.handcards1Container || this == ui.handcards2Container) && + !this.classList.contains("scrollh") + ) { e.preventDefault(); - } - else if (lib.device == 'ios' && this.scrollHeight <= this.offsetHeight + 5 && this.scrollWidth <= this.offsetWidth + 5) { + } else if ( + lib.device == "ios" && + this.scrollHeight <= this.offsetHeight + 5 && + this.scrollWidth <= this.offsetWidth + 5 + ) { e.preventDefault(); - } - else { + } else { delete _status._swipeorigin; e.stopPropagation(); } } - static autoskill(bool, node) { + autoskill(bool, node) { var list = lib.config.autoskilllist; if (bool) { list.remove(node.link); - } - else { + } else { list.add(node.link); } - game.saveConfig('autoskilllist', list); + game.saveConfig("autoskilllist", list); } - static skillbutton() { + skillbutton() { this.func(this.link); } - static autoskill2(e) { - this.classList.toggle('on'); + autoskill2(e) { + this.classList.toggle("on"); var list = []; if (lib.skill[this.link].frequent) { list.push(this.link); } if (lib.skill[this.link].subfrequent) { for (var i = 0; i < lib.skill[this.link].subfrequent.length; i++) { - list.push(this.link + '_' + lib.skill[this.link].subfrequent[i]); + list.push(this.link + "_" + lib.skill[this.link].subfrequent[i]); } } for (var i = 0; i < list.length; i++) { - if (this.classList.contains('on')) { + if (this.classList.contains("on")) { lib.config.autoskilllist.remove(list[i]); - } - else { + } else { lib.config.autoskilllist.add(list[i]); } } - game.saveConfig('autoskilllist', lib.config.autoskilllist); + game.saveConfig("autoskilllist", lib.config.autoskilllist); ui.click.touchpop(); e.stopPropagation(); } - static hiddenskill(e) { - this.classList.toggle('on'); + hiddenskill(e) { + this.classList.toggle("on"); var hidden = lib.skill[this.link].preHidden; if (Array.isArray(hidden)) { - if (this.classList.contains('on')) { + if (this.classList.contains("on")) { _status.prehidden_skills.removeArray(hidden); - } - else { + } else { _status.prehidden_skills.addArray(hidden); } } - if (this.classList.contains('on')) { + if (this.classList.contains("on")) { _status.prehidden_skills.remove(this.link); - } - else { + } else { _status.prehidden_skills.add(this.link); } ui.click.touchpop(); e.stopPropagation(); } - static rightplayer(e) { + rightplayer(e) { if (this._nopup) return false; if (_status.clickedplayer) { return false; @@ -3887,8 +4167,7 @@ export class Click extends Uninstantable { if (this._mouseenterdialog && this._mouseenterdialog.parentNode) { this._mouseenterdialog.delete(); - } - else { + } else { ui.click.intro.call(this, e); } _status.clickedplayer = true; @@ -3896,7 +4175,7 @@ export class Click extends Uninstantable { ui.click.longpresscancel.call(this); return false; } - static right(e) { + right(e) { if (window.inSplash) return false; if (lib.config.touchscreen) return; if (_status.noright) { @@ -3909,13 +4188,20 @@ export class Click extends Uninstantable { } game.closePopped(); switch (lib.config.right_click) { - case 'shortcut': ui.click.shortcut(); break; - case 'pause': ui.click.pause(); break; - case 'auto': ui.click.auto(); break; - case 'config': ui.click.config(); break; + case "shortcut": + ui.click.shortcut(); + break; + case "pause": + ui.click.pause(); + break; + case "auto": + ui.click.auto(); + break; + case "config": + ui.click.config(); + break; } e.preventDefault(); return false; } - -} \ No newline at end of file +} diff --git a/noname/ui/create/index.js b/noname/ui/create/index.js index 61d228821..109b031a1 100644 --- a/noname/ui/create/index.js +++ b/noname/ui/create/index.js @@ -1,5 +1,8 @@ -import { ui, game, get, lib, _status } from "../../../noname.js"; -import { Uninstantable } from "../../util/index.js"; +import { ui } from "../index.js"; +import { lib } from "../../library/index.js"; +import { game } from "../../game/index.js"; +import { get } from "../../get/index.js"; +import { _status } from "../../status/index.js"; import { menu } from "./menu/index.js"; import { cardPackMenu } from "./menu/pages/cardPackMenu.js"; import { characterPackMenu } from "./menu/pages/characterPackMenu.js"; @@ -8,60 +11,62 @@ import { optionsMenu } from "./menu/pages/optionsMenu.js"; import { otherMenu } from "./menu/pages/otherMenu.js"; import { startMenu } from "./menu/pages/startMenu.js"; -export class Create extends Uninstantable { +export class Create { /** * @type {(video: Videos, before: boolean) => void} */ - static videoNode; + videoNode; /** * 创建身份牌实例 */ - static identityCard(identity, position, noclick) { - const card = ui.create.card(position, 'noclick', noclick); - card.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.card); - card.classList.add('button'); - card._customintro = uiintro => uiintro.add(`${get.translation(`${identity}${2}`)}的身份牌`); + identityCard(identity, position, noclick) { + const card = ui.create.card(position, "noclick", noclick); + card.removeEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.card); + card.classList.add("button"); + card._customintro = (uiintro) => uiintro.add(`${get.translation(`${identity}${2}`)}的身份牌`); const fileName = `image/card/identity_${identity}.jpg`; new Promise((resolve, reject) => { const image = new Image(); image.onload = resolve; image.onerror = reject; image.src = `${lib.assetURL}${fileName}`; - }).then(() => { - card.classList.add('fullskin'); - card.node.image.setBackgroundImage(fileName); - }, () => card.node.background.innerHTML = get.translation(identity)[0]); + }).then( + () => { + card.classList.add("fullskin"); + card.node.image.setBackgroundImage(fileName); + }, + () => (card.node.background.innerHTML = get.translation(identity)[0]) + ); return card; } /** * 让卡牌旋转 */ - static cardSpinning(card) { - if (lib.config.cardback_style != 'default') { - card.style.transitionProperty = 'none'; + cardSpinning(card) { + if (lib.config.cardback_style != "default") { + card.style.transitionProperty = "none"; ui.refresh(card); - card.classList.add('infohidden'); + card.classList.add("infohidden"); ui.refresh(card); - card.style.transitionProperty = ''; + card.style.transitionProperty = ""; + } else { + card.classList.add("infohidden"); } - else { - card.classList.add('infohidden'); - } - card.style.transition = 'all 0s'; - card.style.transform = 'perspective(600px) rotateY(180deg) translateX(0)'; + card.style.transition = "all 0s"; + card.style.transform = "perspective(600px) rotateY(180deg) translateX(0)"; const onEnd01 = function () { setTimeout(function () { - card.style.transition = 'all ease-in 0.3s'; - card.style.transform = 'perspective(600px) rotateY(270deg) translateX(52px)'; + card.style.transition = "all ease-in 0.3s"; + card.style.transform = "perspective(600px) rotateY(270deg) translateX(52px)"; var onEnd = function () { - card.classList.remove('infohidden'); - card.style.transition = 'all 0s'; + card.classList.remove("infohidden"); + card.style.transition = "all 0s"; ui.refresh(card); - card.style.transform = 'perspective(600px) rotateY(-90deg) translateX(52px)'; + card.style.transform = "perspective(600px) rotateY(-90deg) translateX(52px)"; ui.refresh(card); - card.style.transition = ''; + card.style.transition = ""; ui.refresh(card); - card.style.transform = ''; + card.style.transform = ""; }; card.listenTransition(onEnd); }, 300); @@ -71,9 +76,9 @@ export class Create extends Uninstantable { /** * 旋转的身份牌! */ - static spinningIdentityCard(identity, dialog) { + spinningIdentityCard(identity, dialog) { const card = ui.create.identityCard(identity); - const buttons = ui.create.div('.buttons', dialog.content); + const buttons = ui.create.div(".buttons", dialog.content); setTimeout(() => { buttons.appendChild(card); dialog.open(); @@ -82,10 +87,10 @@ export class Create extends Uninstantable { } /** * 创建codemirror编辑器 - * @param {HTMLDivElement} container - * @param {Function} saveInput + * @param {HTMLDivElement} container + * @param {Function} saveInput */ - static editor(container, saveInput) { + editor(container, saveInput) { const createList = []; const containerDelete = container.delete; const editorpage = ui.create.div(container); @@ -94,7 +99,9 @@ export class Create extends Uninstantable { for (let i = createList.length - 1; i >= 0; i--) { createList[i].parentNode && createList[i].parentNode.removeChild(createList[i]); } - Array.from(editorpage.children).forEach(v => { v.style.background = ''; }); + Array.from(editorpage.children).forEach((v) => { + v.style.background = ""; + }); containerDelete.apply(this, arguments); }; //创建ul列表 @@ -108,24 +115,26 @@ export class Create extends Uninstantable { } } if (self.ul) { - self.style.background = '#08f'; + self.style.background = "#08f"; createList.add(self.ul); ui.window.appendChild(self.ul); return self.ul; } const editor = container.editor; if (!editor) return false; - self.style.background = '#08f'; - const ul = document.createElement('ul'); + self.style.background = "#08f"; + const ul = document.createElement("ul"); container.css.call(ul, { - position: 'absolute', - top: pos.bottom / game.documentZoom + 'px', - left: pos.left / game.documentZoom + 'px', - height: '20em', - width: pos.width * 4 / game.documentZoom + 'px', + position: "absolute", + top: pos.bottom / game.documentZoom + "px", + left: pos.left / game.documentZoom + "px", + height: "20em", + width: (pos.width * 4) / game.documentZoom + "px", //'font-family':'shousha', - 'font-size': (lib.config.codeMirror_fontSize ? lib.config.codeMirror_fontSize.slice(0, -2) : 16) / game.documentZoom + 'px', - + "font-size": + (lib.config.codeMirror_fontSize ? lib.config.codeMirror_fontSize.slice(0, -2) : 16) / + game.documentZoom + + "px", }); const theme = editor.options.theme; lib.setScroll(ul); @@ -134,21 +143,21 @@ export class Create extends Uninstantable { const getActive = () => { let i = 0; while (i < ul.childElementCount) { - if (ul.childNodes[i].classList.contains('CodeMirror-hint-active')) break; + if (ul.childNodes[i].classList.contains("CodeMirror-hint-active")) break; else i++; } return i; }; - const setActive = i => { - ul.childNodes[getActive()].classList.remove('CodeMirror-hint-active'); - ul.childNodes[i].classList.add('CodeMirror-hint-active'); + const setActive = (i) => { + ul.childNodes[getActive()].classList.remove("CodeMirror-hint-active"); + ul.childNodes[i].classList.add("CodeMirror-hint-active"); return i; }; if (List && List.length && click) { for (let i = 0; i < List.length; ++i) { const elt = ul.appendChild(document.createElement("li")); - elt.style.color = 'black'; - elt.style.boxShadow = 'none'; + elt.style.color = "black"; + elt.style.boxShadow = "none"; const cur = List[i]; if (cur instanceof HTMLElement) { elt.appendChild(cur); @@ -178,20 +187,20 @@ export class Create extends Uninstantable { const ul = this.ul; if (!ul) return false; if (ul.parentNode) ul.parentNode.removeChild(ul); - this.style.background = ''; + this.style.background = ""; //创建后不用删除了,除非以后要动态加载。 //delete this.ul; createList.remove(ul); return ul; }; - const discardConfig = ui.create.div('.editbutton', '取消', editorpage, function () { - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + const discardConfig = ui.create.div(".editbutton", "取消", editorpage, function () { + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(null); delete window.saveNonameInput; }); - const saveConfig = ui.create.div('.editbutton', '保存', editorpage, saveInput); - const theme = ui.create.div('.editbutton', '主题', editorpage, function () { + const saveConfig = ui.create.div(".editbutton", "保存", editorpage, saveInput); + const theme = ui.create.div(".editbutton", "主题", editorpage, function () { if (!this || this == window) return; if (this.ul && this.ul.parentNode) { return closeMenu.call(this); @@ -200,7 +209,7 @@ export class Create extends Uninstantable { const self = this; if (!this.ul) { //主题列表 - const list = ['mdn-like', 'mbo']; + const list = ["mdn-like", "mbo"]; //正在使用的主题 const active = container.editor.options.theme; //排个序 @@ -212,7 +221,7 @@ export class Create extends Uninstantable { const theme = this.innerHTML; container.editor.setOption("theme", theme); setTimeout(() => container.editor.refresh(), 0); - game.saveConfig('codeMirror_theme', theme); + game.saveConfig("codeMirror_theme", theme); closeMenu.call(self); }; const ul = createMenu(pos, self, list, click); @@ -221,7 +230,7 @@ export class Create extends Uninstantable { createMenu(null, self); } }); - const edit = ui.create.div('.editbutton', '编辑', editorpage, function () { + const edit = ui.create.div(".editbutton", "编辑", editorpage, function () { if (!this || this == window) return; if (this.ul && this.ul.parentNode) { return closeMenu.call(this); @@ -229,7 +238,7 @@ export class Create extends Uninstantable { const self = this; if (!this.ul) { const pos = this.getBoundingClientRect(); - const list = ['撤销 Ctrl+Z', '恢复撤销 Ctrl+Y']; + const list = ["撤销 Ctrl+Z", "恢复撤销 Ctrl+Y"]; const click = function (e) { const num = this.innerHTML.indexOf("Ctrl"); const inner = this.innerHTML.slice(num).replace("+", "-"); @@ -243,7 +252,7 @@ export class Create extends Uninstantable { createMenu(null, self); } }); - const fontSize = ui.create.div('.editbutton', '字号', editorpage, function () { + const fontSize = ui.create.div(".editbutton", "字号", editorpage, function () { if (!this || this == window) return; if (this.ul && this.ul.parentNode) { return closeMenu.call(this); @@ -251,13 +260,18 @@ export class Create extends Uninstantable { const self = this; if (!this.ul) { const pos = this.getBoundingClientRect(); - const list = ['16px', '18px', '20px', '22px', '24px', '26px']; + const list = ["16px", "18px", "20px", "22px", "24px", "26px"]; const click = function (e) { const size = this.innerHTML; - container.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px'; - Array.from(self.parentElement.children).map(v => v.ul).filter(Boolean).forEach(v => { v.style.fontSize = size.slice(0, -2) / game.documentZoom + 'px'; }); + container.style.fontSize = size.slice(0, -2) / game.documentZoom + "px"; + Array.from(self.parentElement.children) + .map((v) => v.ul) + .filter(Boolean) + .forEach((v) => { + v.style.fontSize = size.slice(0, -2) / game.documentZoom + "px"; + }); setTimeout(() => container.editor.refresh(), 0); - game.saveConfig('codeMirror_fontSize', size); + game.saveConfig("codeMirror_fontSize", size); closeMenu.call(self); }; const ul = createMenu(pos, self, list, click); @@ -269,31 +283,31 @@ export class Create extends Uninstantable { const editor = ui.create.div(editorpage); return editor; } - static cardTempName(card, applyNode) { + cardTempName(card, applyNode) { let getApplyNode = applyNode || card; let cardName = get.name(card); let cardNature = get.nature(card); let tempname = get.translation(cardName); let cardTempNameConfig = lib.config.cardtempname; - let node = getApplyNode._tempName || ui.create.div('.tempname', getApplyNode); - let datasetNature = ''; + let node = getApplyNode._tempName || ui.create.div(".tempname", getApplyNode); + let datasetNature = ""; getApplyNode._tempName = node; - if (cardTempNameConfig != 'image') { + if (cardTempNameConfig != "image") { //清空,避免和下面的image部分有冲突 - node.innerHTML = ''; - datasetNature = 'fire'; - if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { - datasetNature = 'wood'; + node.innerHTML = ""; + datasetNature = "fire"; + if (get.position(card) == "j" && card.viewAs && card.viewAs != card.name) { + datasetNature = "wood"; tempname = get.translation(card.viewAs); } else { - if (cardName == 'sha') { + if (cardName == "sha") { if (cardNature) tempname = get.translation(cardNature) + tempname; - if (cardNature == 'thunder') datasetNature = 'thunder'; - if (cardNature == 'kami') datasetNature = 'kami'; - if (cardNature == 'ice') datasetNature = 'ice'; + if (cardNature == "thunder") datasetNature = "thunder"; + if (cardNature == "kami") datasetNature = "kami"; + if (cardNature == "ice") datasetNature = "ice"; } } - if (cardTempNameConfig == 'default') getApplyNode._tempName.classList.add('vertical'); + if (cardTempNameConfig == "default") getApplyNode._tempName.classList.add("vertical"); if (datasetNature.length > 0) { node.dataset.nature = datasetNature; } else { @@ -301,145 +315,151 @@ export class Create extends Uninstantable { node.classList.add(datasetNature); } } else { - if (get.position(card) == 'j' && card.viewAs && card.viewAs != card.name) { + if (get.position(card) == "j" && card.viewAs && card.viewAs != card.name) { cardName = card.viewAs; tempname = get.translation(card.viewAs); } - if (cardName == 'sha') { + if (cardName == "sha") { if (cardNature) tempname = get.translation(cardNature) + tempname; - if (cardNature == 'fire') datasetNature = 'fire'; - if (cardNature == 'thunder') datasetNature = 'thunder'; - if (cardNature == 'kami') datasetNature = 'kami'; - if (cardNature == 'ice') datasetNature = 'ice'; + if (cardNature == "fire") datasetNature = "fire"; + if (cardNature == "thunder") datasetNature = "thunder"; + if (cardNature == "kami") datasetNature = "kami"; + if (cardNature == "ice") datasetNature = "ice"; } - let bg = node.querySelector('div'); + let bg = node.querySelector("div"); if (bg) { - Array.from(node.childNodes).filter(v => v != bg).forEach(v => node.removeChild(v)); - } - else bg = ui.create.div(node); - node.classList.add('tempimage'); - let img = get.dynamicVariable(lib.card[cardName].image,card); + Array.from(node.childNodes) + .filter((v) => v != bg) + .forEach((v) => node.removeChild(v)); + } else bg = ui.create.div(node); + node.classList.add("tempimage"); + let img = get.dynamicVariable(lib.card[cardName].image, card); if (img) { - if (img.startsWith('db:')) { + if (img.startsWith("db:")) { img = img.slice(3); - } - else if (!img.startsWith('ext:')) { + } else if (!img.startsWith("ext:")) { img = null; } } if (lib.card[cardName].fullskin) { if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - } - else { + if (img.startsWith("ext:")) { + bg.setBackgroundImage(img.replace(/^ext:/, "extension/")); + } else { bg.setBackgroundDB(img); } - } - else { + } else { if (lib.card[cardName].modeimage) { - bg.setBackgroundImage('image/mode/' + lib.card[cardName].modeimage + '/card/' + cardName + '.png'); - } - else { - if (cardName == 'sha' && cardNature == 'stab') bg.setBackgroundImage('image/card/cisha.png'); - else bg.setBackgroundImage('image/card/' + cardName + '.png'); + bg.setBackgroundImage( + "image/mode/" + lib.card[cardName].modeimage + "/card/" + cardName + ".png" + ); + } else { + if (cardName == "sha" && cardNature == "stab") + bg.setBackgroundImage("image/card/cisha.png"); + else bg.setBackgroundImage("image/card/" + cardName + ".png"); } } - } - else if (get.dynamicVariable(lib.card[cardName].image,card) == 'background') { - if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); - else bg.setBackground(cardName, 'card'); - } - else if (lib.card[cardName].fullimage) { + } else if (get.dynamicVariable(lib.card[cardName].image, card) == "background") { + if (cardNature) bg.setBackground(cardName + "_" + cardNature, "card"); + else bg.setBackground(cardName, "card"); + } else if (lib.card[cardName].fullimage) { if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - bg.style.backgroundSize = 'cover'; - } - else { + if (img.startsWith("ext:")) { + bg.setBackgroundImage(img.replace(/^ext:/, "extension/")); + bg.style.backgroundSize = "cover"; + } else { bg.setBackgroundDB(img); } - } - else if (get.dynamicVariable(lib.card[cardName].image,card)) { - if (get.dynamicVariable(lib.card[cardName].image,card).startsWith('character:')) { - bg.setBackground(get.dynamicVariable(lib.card[cardName].image,card).slice(10), 'character'); + } else if (get.dynamicVariable(lib.card[cardName].image, card)) { + if (get.dynamicVariable(lib.card[cardName].image, card).startsWith("character:")) { + bg.setBackground( + get.dynamicVariable(lib.card[cardName].image, card).slice(10), + "character" + ); + } else { + bg.setBackground(get.dynamicVariable(lib.card[cardName].image, card)); } - else { - bg.setBackground(get.dynamicVariable(lib.card[cardName].image,card)); - } - } - else { - let cardPack = lib.cardPack['mode_' + get.mode()]; + } else { + let cardPack = lib.cardPack["mode_" + get.mode()]; if (Array.isArray(cardPack) && cardPack.includes(cardName)) { - bg.setBackground('mode/' + get.mode() + '/card/' + cardName); - } - else { - bg.setBackground('card/' + cardName); + bg.setBackground("mode/" + get.mode() + "/card/" + cardName); + } else { + bg.setBackground("card/" + cardName); } } - } - else if (get.dynamicVariable(lib.card[cardName].image,card) == 'card') { - if (cardNature) bg.setBackground(cardName + '_' + cardNature, 'card'); - else bg.setBackground(cardName, 'card'); - } - else if (typeof get.dynamicVariable(lib.card[cardName].image,card) == 'string' && !lib.card[cardName].fullskin) { + } else if (get.dynamicVariable(lib.card[cardName].image, card) == "card") { + if (cardNature) bg.setBackground(cardName + "_" + cardNature, "card"); + else bg.setBackground(cardName, "card"); + } else if ( + typeof get.dynamicVariable(lib.card[cardName].image, card) == "string" && + !lib.card[cardName].fullskin + ) { if (img) { - if (img.startsWith('ext:')) { - bg.setBackgroundImage(img.replace(/^ext:/, 'extension/')); - bg.style.backgroundSize = 'cover'; - } - else { + if (img.startsWith("ext:")) { + bg.setBackgroundImage(img.replace(/^ext:/, "extension/")); + bg.style.backgroundSize = "cover"; + } else { bg.setBackgroundDB(img); } + } else { + bg.setBackground(get.dynamicVariable(lib.card[cardName].image, card)); } - else { - bg.setBackground(get.dynamicVariable(lib.card[cardName].image,card)); - } - } - else { - console.warn('卡牌图片解析失败'); + } else { + console.warn("卡牌图片解析失败"); } if (datasetNature.length > 0) { node.classList.add(datasetNature); } delete node.dataset.nature; } - node.innerHTML += `${cardTempNameConfig == 'default' ? get.verticalStr(tempname) : tempname}`; + node.innerHTML += `${ + cardTempNameConfig == "default" ? get.verticalStr(tempname) : tempname + }`; node.tempname = tempname; return node; } - static connectRooms(list) { + connectRooms(list) { ui.rooms = []; ui.roombase = ui.create.dialog(); - ui.roombase.classList.add('fullwidth'); - ui.roombase.classList.add('fullheight'); - ui.roombase.classList.add('fixed'); - ui.roombase.classList.add('scroll1'); - ui.roombase.classList.add('scroll2'); - ui.roombase.classList.add('noupdate'); + ui.roombase.classList.add("fullwidth"); + ui.roombase.classList.add("fullheight"); + ui.roombase.classList.add("fixed"); + ui.roombase.classList.add("scroll1"); + ui.roombase.classList.add("scroll2"); + ui.roombase.classList.add("noupdate"); for (var i = 0; i < list.length; i++) { - var player = ui.roombase.add(''); + var player = ui.roombase.add( + '' + ); player.roomindex = i; player.initRoom = lib.element.Player.prototype.initRoom; - player.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.connectroom); + player.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.connectroom); player.initRoom(list[i]); ui.rooms.push(player); } } - static rarity(button) { + rarity(button) { var rarity = game.getRarity(button.link); - if (rarity != 'common' && lib.config.show_rarity) { + if (rarity != "common" && lib.config.show_rarity) { var intro = button.node.intro; - intro.classList.add('showintro'); - intro.style.fontFamily = 'yuanli'; - intro.style.fontSize = '16px'; - intro.style.bottom = '6px'; - intro.style.left = '6px'; + intro.classList.add("showintro"); + intro.style.fontFamily = "yuanli"; + intro.style.fontSize = "16px"; + intro.style.bottom = "6px"; + intro.style.left = "6px"; switch (rarity) { - case 'rare': intro.dataset.nature = 'thunderm'; break; - case 'epic': intro.dataset.nature = 'metalm'; break; - case 'legend': intro.dataset.nature = 'orangem'; break; - case 'junk': intro.dataset.nature = 'woodm'; break; + case "rare": + intro.dataset.nature = "thunderm"; + break; + case "epic": + intro.dataset.nature = "metalm"; + break; + case "legend": + intro.dataset.nature = "orangem"; + break; + case "junk": + intro.dataset.nature = "woodm"; + break; } intro.innerHTML = get.translation(rarity); } @@ -451,47 +471,44 @@ export class Create extends Uninstantable { else button.node.group.style.backgroundColor=get.translation('weiColor'); }*/ } - static div() { + div() { var str, innerHTML, position, position2, style, divposition, listen; for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { - if (typeof str == 'string') { + if (typeof arguments[i] == "string") { + if (typeof str == "string") { innerHTML = arguments[i]; - } - else { + } else { str = arguments[i]; } - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'number') position2 = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; - else if (typeof arguments[i] == 'function') listen = arguments[i]; + } else if (["div", "table", "tr", "td", "body", "fragment"].includes(get.objtype(arguments[i]))) + position = arguments[i]; + else if (typeof arguments[i] == "number") position2 = arguments[i]; + else if (get.itemtype(arguments[i]) == "divposition") divposition = arguments[i]; + else if (typeof arguments[i] == "object") style = arguments[i]; + else if (typeof arguments[i] == "function") listen = arguments[i]; } - if (str == undefined) str = ''; - var node = document.createElement('div'); + if (str == undefined) str = ""; + var node = document.createElement("div"); for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { + if (str[i] == ".") { if (node.className.length != 0) { - node.className += ' '; + node.className += " "; } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.className += str[i + 1]; i++; } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + } else if (str[i] == "#") { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.id += str[i + 1]; i++; } } } if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { + if (typeof position2 == "number" && position.childNodes.length > position2) { position.insertBefore(node, position.childNodes[position2]); - } - else { + } else { position.appendChild(node); } } @@ -501,19 +518,19 @@ export class Create extends Uninstantable { if (listen) node.listen(listen); return node; } - static filediv() { + filediv() { var args = Array.from(arguments); var func = null; for (var i = 0; i < args.length; i++) { - if (typeof args[i] == 'function') { + if (typeof args[i] == "function") { func = args[i]; args.splice(i, 1); break; } } var div = ui.create.div.apply(this, args); - var input = ui.create.node('input.fileinput'); - input.type = 'file'; + var input = ui.create.node("input.fileinput"); + input.type = "file"; input.onchange = function (e) { func.call(this, this.files[0], e); }; @@ -521,29 +538,27 @@ export class Create extends Uninstantable { div.inputNode = input; return div; } - static node() { + node() { var tagName, str, innerHTML, position, position2, style, divposition, listen; for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') { - if (typeof tagName == 'string') { + if (typeof arguments[i] == "string") { + if (typeof tagName == "string") { innerHTML = arguments[i]; - } - else { + } else { tagName = arguments[i]; } - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'number') position2 = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; - else if (typeof arguments[i] == 'function') listen = arguments[i]; + } else if (["div", "table", "tr", "td", "body", "fragment"].includes(get.objtype(arguments[i]))) + position = arguments[i]; + else if (typeof arguments[i] == "number") position2 = arguments[i]; + else if (get.itemtype(arguments[i]) == "divposition") divposition = arguments[i]; + else if (typeof arguments[i] == "object") style = arguments[i]; + else if (typeof arguments[i] == "function") listen = arguments[i]; } if (tagName == undefined) { - tagName = 'div'; - } - else { - var i1 = tagName.indexOf('.'); - var i2 = tagName.indexOf('#'); + tagName = "div"; + } else { + var i1 = tagName.indexOf("."); + var i2 = tagName.indexOf("#"); if (i1 != -1 || i2 != -1) { if (i2 != -1 && i2 < i1) { i1 = i2; @@ -555,17 +570,16 @@ export class Create extends Uninstantable { var node = document.createElement(tagName); if (str) { for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { + if (str[i] == ".") { if (node.className.length != 0) { - node.className += ' '; + node.className += " "; } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.className += str[i + 1]; i++; } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + } else if (str[i] == "#") { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.id += str[i + 1]; i++; } @@ -573,10 +587,9 @@ export class Create extends Uninstantable { } } if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { + if (typeof position2 == "number" && position.childNodes.length > position2) { position.insertBefore(node, position.childNodes[position2]); - } - else { + } else { position.appendChild(node); } } @@ -586,40 +599,40 @@ export class Create extends Uninstantable { if (listen) node.onclick = listen; return node; } - static iframe(src) { - var layer = document.createElement('div'); - layer.classList.add('poplayer'); - layer.style.zIndex = '100'; + iframe(src) { + var layer = document.createElement("div"); + layer.classList.add("poplayer"); + layer.style.zIndex = "100"; layer.listen(function () { this.remove(); }); - layer.style.background = 'white'; + layer.style.background = "white"; - var webview = document.createElement('iframe'); + var webview = document.createElement("iframe"); webview.src = src; - webview.style.width = '100%'; - webview.style.height = '100%'; - webview.style.left = '0px'; - webview.style.top = '0px'; - webview.style.position = 'absolute'; - webview.style.border = 'none'; + webview.style.width = "100%"; + webview.style.height = "100%"; + webview.style.left = "0px"; + webview.style.top = "0px"; + webview.style.position = "absolute"; + webview.style.border = "none"; layer.appendChild(webview); - var backbutton = ui.create.div('.menubutton.round', '返', layer, function () { + var backbutton = ui.create.div(".menubutton.round", "返", layer, function () { layer.remove(); }); - backbutton.style.bottom = '10px'; - backbutton.style.right = '10px'; - backbutton.style.background = 'rgba(0,0,0,0.4)'; - backbutton.style.color = 'white'; - backbutton.style.textShadow = 'rgba(0,0,0,0.5) 0px 0px 2px'; - backbutton.style.boxShadow = 'rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 3px 10px'; - backbutton.style.position = 'fixed'; + backbutton.style.bottom = "10px"; + backbutton.style.right = "10px"; + backbutton.style.background = "rgba(0,0,0,0.4)"; + backbutton.style.color = "white"; + backbutton.style.textShadow = "rgba(0,0,0,0.5) 0px 0px 2px"; + backbutton.style.boxShadow = "rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 3px 10px"; + backbutton.style.position = "fixed"; ui.window.appendChild(layer); } - static identitycircle(list, target) { - var container = ui.create.div('.identitycircle.menubg', target); + identitycircle(list, target) { + var container = ui.create.div(".identitycircle.menubg", target); var circle = ui.create.div(container); container.dataset.num = list.length; for (var i = 0; i < list.length; i++) { @@ -627,41 +640,39 @@ export class Create extends Uninstantable { sec1.dataset.color = list[i]; var sec2 = ui.create.div(circle); sec2.dataset.color = list[i]; - var deg1 = 360 / list.length * i; + var deg1 = (360 / list.length) * i; var deg2 = 0; if (list.length == 2) { deg2 = 90; - } - else if (list.length == 3) { + } else if (list.length == 3) { deg2 = 30; } - sec1.style.transform = 'rotate(' + deg1 + 'deg)'; - sec2.style.transform = 'rotate(' + (deg1 + deg2) + 'deg)'; + sec1.style.transform = "rotate(" + deg1 + "deg)"; + sec2.style.transform = "rotate(" + (deg1 + deg2) + "deg)"; } } - static chat() { - var chat = ui.create.system('聊天', null, true); + chat() { + var chat = ui.create.system("聊天", null, true); ui.chatButton = chat; lib.setPopped(chat, ui.click.chat, 220); } - static exit() { + exit() { if (!ui.exit) { - ui.exit = ui.create.control('退出房间', ui.click.exit); + ui.exit = ui.create.control("退出房间", ui.click.exit); } } - static connecting(bool) { + connecting(bool) { if (bool) { - ui.window.classList.remove('connecting'); + ui.window.classList.remove("connecting"); if (ui.connecting) { ui.connecting.delete(); delete ui.connecting; } - } - else { - ui.window.classList.add('connecting'); - ui.connecting = ui.create.div('.fullsize.connectlayer'); + } else { + ui.window.classList.add("connecting"); + ui.connecting = ui.create.div(".fullsize.connectlayer"); document.body.appendChild(ui.connecting); - ui.create.div('', '正在重连...', ui.connecting); + ui.create.div("", "正在重连...", ui.connecting); ui.connecting.splashtimeout = setTimeout(function () { if (ui.connecting) { delete ui.connecting.splashtimeout; @@ -674,44 +685,51 @@ export class Create extends Uninstantable { // },1000); } } - static roomInfo() { - var chat = ui.create.system(game.online ? '房间信息' : '房间设置', function () { - if (!game.online || game.onlinezhu) { - ui.click.connectMenu(); - } - }, true); + roomInfo() { + var chat = ui.create.system( + game.online ? "房间信息" : "房间设置", + function () { + if (!game.online || game.onlinezhu) { + ui.click.connectMenu(); + } + }, + true + ); ui.roomInfo = chat; - lib.setPopped(chat, function () { - if (game.getRoomInfo) { - var uiintro = ui.create.dialog('hidden'); - game.getRoomInfo(uiintro); - return uiintro; - } - }, 180); + lib.setPopped( + chat, + function () { + if (game.getRoomInfo) { + var uiintro = ui.create.dialog("hidden"); + game.getRoomInfo(uiintro); + return uiintro; + } + }, + 180 + ); } - static templayer(time) { - if (typeof time != 'number' || isNaN(time) || time == Infinity) { + templayer(time) { + if (typeof time != "number" || isNaN(time) || time == Infinity) { time = 500; } - var templayer = ui.create.div('.popup-container', ui.window); + var templayer = ui.create.div(".popup-container", ui.window); setTimeout(function () { templayer.remove(); }, time); } - static selectlist(list, init, position, onchange) { - var select = document.createElement('select'); + selectlist(list, init, position, onchange) { + var select = document.createElement("select"); for (var i = 0; i < list.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); if (Array.isArray(list[i])) { option.value = list[i][0]; option.innerHTML = list[i][1]; - } - else { + } else { option.value = list[i]; option.innerHTML = list[i]; } if (init == option.value) { - option.selected = 'selected'; + option.selected = "selected"; } select.appendChild(option); } @@ -724,49 +742,47 @@ export class Create extends Uninstantable { return select; } /** 创建菜单 */ - static menu = menu; + menu = menu; /** 创建“开始”菜单 */ - static startMenu = startMenu; + startMenu = startMenu; /** 创建“选项”菜单 */ - static optionsMenu = optionsMenu; + optionsMenu = optionsMenu; /** 创建“武将”菜单 */ - static characterPackMenu = characterPackMenu; + characterPackMenu = characterPackMenu; /** 创建“卡牌”菜单 */ - static cardPackMenu = cardPackMenu; + cardPackMenu = cardPackMenu; /** 创建“扩展”菜单 */ - static extensionMenu = extensionMenu; + extensionMenu = extensionMenu; /** 创建“其他”菜单 */ - static otherMenu = otherMenu; - static statictable() { + otherMenu = otherMenu; + statictable() { var str, row, col, position, position2, fixed, style, divposition; for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string') str = arguments[i]; - else if (typeof arguments[i] == 'number') { - if (typeof row == 'number') { - if (typeof col == 'number') position2 = arguments[i]; + if (typeof arguments[i] == "string") str = arguments[i]; + else if (typeof arguments[i] == "number") { + if (typeof row == "number") { + if (typeof col == "number") position2 = arguments[i]; else col = arguments[i]; - } - else row = arguments[i]; - } - else if (['div', 'table', 'tr', 'td', 'body', 'fragment'].includes(get.objtype(arguments[i]))) position = arguments[i]; - else if (typeof arguments[i] == 'boolean') fixed = arguments[i]; - else if (get.itemtype(arguments[i]) == 'divposition') divposition = arguments[i]; - else if (typeof arguments[i] == 'object') style = arguments[i]; + } else row = arguments[i]; + } else if (["div", "table", "tr", "td", "body", "fragment"].includes(get.objtype(arguments[i]))) + position = arguments[i]; + else if (typeof arguments[i] == "boolean") fixed = arguments[i]; + else if (get.itemtype(arguments[i]) == "divposition") divposition = arguments[i]; + else if (typeof arguments[i] == "object") style = arguments[i]; } - if (str == undefined) str = ''; - var node = document.createElement('table'); + if (str == undefined) str = ""; + var node = document.createElement("table"); for (var i = 0; i < str.length; i++) { - if (str[i] == '.') { + if (str[i] == ".") { if (node.className.length != 0) { - node.className += ' '; + node.className += " "; } - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.className += str[i + 1]; i++; } - } - else if (str[i] == '#') { - while (str[i + 1] != '.' && str[i + 1] != '#' && i + 1 < str.length) { + } else if (str[i] == "#") { + while (str[i + 1] != "." && str[i + 1] != "#" && i + 1 < str.length) { node.id += str[i + 1]; i++; } @@ -774,118 +790,128 @@ export class Create extends Uninstantable { } var tr, td; for (var i = 0; i < row; i++) { - tr = document.createElement('tr'); - if (fixed) tr.style.height = (100 / row) + '%'; + tr = document.createElement("tr"); + if (fixed) tr.style.height = 100 / row + "%"; node.appendChild(tr); for (var j = 0; j < col; j++) { - td = document.createElement('td'); + td = document.createElement("td"); tr.appendChild(td); } } if (position) { - if (typeof position2 == 'number' && position.childNodes.length > position2) { + if (typeof position2 == "number" && position.childNodes.length > position2) { position.insertBefore(node, position.childNodes[position2]); - } - else { + } else { position.appendChild(node); } } return node; } - static giveup() { + giveup() { if (ui.giveup) return; if (!lib.config.show_giveup) return; - ui.giveup = ui.create.system('投降', function () { - var player = game.me; - this.remove(); - if (game.online) { - game.send('giveup', player); - } - else { - _status.event.next.length = 0; - game.createEvent('giveup', false).set('includeOut', true).setContent(function () { - game.log(player, '投降'); - player.popup('投降'); - player.die('nosource').includeOut = true; - }).player = player; - } - if (_status.paused && _status.imchoosing && !_status.auto) { - ui.click.auto(); - } - }, true, true); - } - static groupControl(dialog) { - return ui.create.control('wei', 'shu', 'wu', 'qun', 'jin', 'western', 'key', function (link, node) { - if (link == '全部') { - dialog.currentcapt = ''; - dialog.currentgroup = ''; - for (var i = 0; i < dialog.buttons.length; i++) { - dialog.buttons[i].style.display = ''; + ui.giveup = ui.create.system( + "投降", + function () { + var player = game.me; + this.remove(); + if (game.online) { + game.send("giveup", player); + } else { + _status.event.next.length = 0; + game + .createEvent("giveup", false) + .set("includeOut", true) + .setContent(function () { + game.log(player, "投降"); + player.popup("投降"); + player.die("nosource").includeOut = true; + }).player = player; } - } - else { - if (node.classList.contains('thundertext')) { + if (_status.paused && _status.imchoosing && !_status.auto) { + ui.click.auto(); + } + }, + true, + true + ); + } + groupControl(dialog) { + return ui.create.control("wei", "shu", "wu", "qun", "jin", "western", "key", function (link, node) { + if (link == "全部") { + dialog.currentcapt = ""; + dialog.currentgroup = ""; + for (var i = 0; i < dialog.buttons.length; i++) { + dialog.buttons[i].style.display = ""; + } + } else { + if (node.classList.contains("thundertext")) { dialog.currentgroup = null; dialog.currentgroupnode = null; - node.classList.remove('thundertext'); + node.classList.remove("thundertext"); for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); + if ( + dialog.currentcapt && + dialog.buttons[i].capt != + dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt) + ) { + dialog.buttons[i].classList.add("nodisplay"); + } else { + dialog.buttons[i].classList.remove("nodisplay"); } } - } - else { + } else { if (dialog.currentgroupnode) { - dialog.currentgroupnode.classList.remove('thundertext'); + dialog.currentgroupnode.classList.remove("thundertext"); } dialog.currentgroup = link; dialog.currentgroupnode = node; - node.classList.add('thundertext'); + node.classList.add("thundertext"); for (var i = 0; i < dialog.buttons.length; i++) { - if (dialog.buttons[i].group != link || - (dialog.currentcapt && dialog.buttons[i].capt != dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt))) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); + if ( + dialog.buttons[i].group != link || + (dialog.currentcapt && + dialog.buttons[i].capt != + dialog.getCurrentCapt(dialog.buttons[i].link, dialog.buttons[i].capt)) + ) { + dialog.buttons[i].classList.add("nodisplay"); + } else { + dialog.buttons[i].classList.remove("nodisplay"); } } } } }); } - static cardDialog() { - var args = ['thisiscard']; + cardDialog() { + var args = ["thisiscard"]; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } return ui.create.characterDialog.apply(this, args); } - static characterDialog2(filter) { + characterDialog2(filter) { var list = []; for (var i in lib.character) { - if (lib.character[i][4].includes('minskin')) continue; - if (lib.character[i][4].includes('boss') || lib.character[i][4].includes('hiddenboss')) { - if (lib.config.mode == 'boss') continue; - if (!lib.character[i][4].includes('bossallowed')) continue; + if (lib.character[i][4].includes("minskin")) continue; + if (lib.character[i][4].includes("boss") || lib.character[i][4].includes("hiddenboss")) { + if (lib.config.mode == "boss") continue; + if (!lib.character[i][4].includes("bossallowed")) continue; } - if (lib.character[i][4].includes('stonehidden')) continue; + if (lib.character[i][4].includes("stonehidden")) continue; if (lib.config.banned.includes(i)) continue; if (filter && filter(i)) continue; list.push(i); } - var dialog = ui.create.dialog('hidden'); - dialog.classList.add('noupdate'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('scroll3'); + var dialog = ui.create.dialog("hidden"); + dialog.classList.add("noupdate"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("scroll3"); list.sort(lib.sort.character); - dialog.classList.add('character'); - dialog.classList.add('choose-character'); + dialog.classList.add("character"); + dialog.classList.add("choose-character"); var getPack = function (name) { for (var i in lib.characterPack) { if (lib.characterPack[i][name]) return i; @@ -893,56 +919,54 @@ export class Create extends Uninstantable { return null; }; var packs = {}; - var packnode = ui.create.div('.packnode', dialog); + var packnode = ui.create.div(".packnode", dialog); lib.setScroll(packnode); var clickCapt = function () { - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active) { - active.classList.remove('active'); + active.classList.remove("active"); } - this.classList.add('active'); + this.classList.add("active"); for (var i = 0; i < dialog.buttons.length; i++) { if (this.pack && !this.pack.includes(dialog.buttons[i].link)) { - dialog.buttons[i].classList.add('nodisplay'); - } - else { - dialog.buttons[i].classList.remove('nodisplay'); + dialog.buttons[i].classList.add("nodisplay"); + } else { + dialog.buttons[i].classList.remove("nodisplay"); } } }; var createNode = function (packname) { var translate; var pack = null; - if (packname == '最近') { - pack = get.config('recentCharacter') || []; - } - else if (packname == '收藏') { + if (packname == "最近") { + pack = get.config("recentCharacter") || []; + } else if (packname == "收藏") { pack = lib.config.favouriteCharacter; } - var node = ui.create.div('.dialogbutton.menubutton.large', packname, packnode, clickCapt); + var node = ui.create.div(".dialogbutton.menubutton.large", packname, packnode, clickCapt); node.pack = pack; return node; }; - dialog.add([list, 'character']); + dialog.add([list, "character"]); var bool = true; var node; - var recent = get.config('recentCharacter'); + var recent = get.config("recentCharacter"); if (recent && recent.length) { - node = createNode('最近'); - if (lib.config.character_dialog_tool == '最近') { + node = createNode("最近"); + if (lib.config.character_dialog_tool == "最近") { clickCapt.call(node); bool = false; } } if (lib.config.favouriteCharacter.length) { - node = createNode('收藏'); - if (lib.config.character_dialog_tool == '收藏') { + node = createNode("收藏"); + if (lib.config.character_dialog_tool == "收藏") { clickCapt.call(node); bool = false; } } - var node = createNode('全部'); - if (lib.config.character_dialog_tool == 'all') { + var node = createNode("全部"); + if (lib.config.character_dialog_tool == "all") { clickCapt.call(node); bool = false; } @@ -950,10 +974,10 @@ export class Create extends Uninstantable { clickCapt.call(packnode.firstChild); } - var node = ui.create.div('.dialogbutton.menubutton.large', '筛选', packnode); + var node = ui.create.div(".dialogbutton.menubutton.large", "筛选", packnode); return dialog; } - static characterDialog() { + characterDialog() { // if(lib.config.character_dialog_style=='newstyle'){ // for(var i=0;i 0) { - filternode.firstChild.style.top = (dh / 2) + 'px'; + filternode.firstChild.style.top = dh / 2 + "px"; + } else { + filternode.firstChild.style.top = ""; } - else { - filternode.firstChild.style.top = ''; - } - } - else { - if (newlined2.style.display == 'none') { - newlined2.style.display = 'block'; - } - else { - newlined2.style.display = 'none'; + } else { + if (newlined2.style.display == "none") { + newlined2.style.display = "block"; + } else { + newlined2.style.display = "none"; } } }); @@ -1417,29 +1461,35 @@ export class Create extends Uninstantable { if (!lib.config.characters.includes(lib.config.all.characters[i])) continue; packlist.add(lib.config.all.characters[i]); } - Object.keys(lib.characterPack).filter(key=>{ - if(key.indexOf('mode_extension')!=0)return false; - const extName = key.slice(15); - //if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; - return lib.config[`extension_${extName}_characters_enable`] === true; - }).forEach(key=>packlist.add(key)); + Object.keys(lib.characterPack) + .filter((key) => { + if (key.indexOf("mode_extension") != 0) return false; + const extName = key.slice(15); + //if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; + return lib.config[`extension_${extName}_characters_enable`] === true; + }) + .forEach((key) => packlist.add(key)); for (var i = 0; i < packlist.length; i++) { - var span = document.createElement('div'); - span.style.display = 'inline-block'; - span.style.width = 'auto'; - span.style.margin = '5px'; + var span = document.createElement("div"); + span.style.display = "inline-block"; + span.style.width = "auto"; + span.style.margin = "5px"; if (get.is.phoneLayout()) { - span.style.fontSize = '32px'; + span.style.fontSize = "32px"; + } else { + span.style.fontSize = "22px"; } - else { - span.style.fontSize = '22px'; - } - span.innerHTML = lib.translate[packlist[i] + '_character_config']; + span.innerHTML = lib.translate[packlist[i] + "_character_config"]; span.link = packlist[i]; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + span.addEventListener(lib.config.touchscreen ? "touchend" : "click", clickCapt); newlined2.appendChild(span); if (filternode && !onlypack) { - span.touchlink = ui.create.div(filternode.firstChild, clickCaptNode, '.menubutton.large', span.innerHTML); + span.touchlink = ui.create.div( + filternode.firstChild, + clickCaptNode, + ".menubutton.large", + span.innerHTML + ); span.touchlink.link = span; } } @@ -1453,44 +1503,51 @@ export class Create extends Uninstantable { return lib.cardType[type]; } switch (type) { - case 'basic': return 0; - case 'chess': return 1.5; - case 'trick': return 2; - case 'delay': return 3; - case 'equip': return 4; - case 'zhenfa': return 5; - default: return 6; + case "basic": + return 0; + case "chess": + return 1.5; + case "trick": + return 2; + case "delay": + return 3; + case "equip": + return 4; + case "zhenfa": + return 5; + default: + return 6; } }; list.sort(function (a, b) { var del = groupSort(a) - groupSort(b); if (del != 0) return del; - var aa = a, bb = b; - if (a.includes('_')) { - a = a.slice(a.lastIndexOf('_') + 1); + var aa = a, + bb = b; + if (a.includes("_")) { + a = a.slice(a.lastIndexOf("_") + 1); } - if (b.includes('_')) { - b = b.slice(b.lastIndexOf('_') + 1); + if (b.includes("_")) { + b = b.slice(b.lastIndexOf("_") + 1); } if (a != b) { return a > b ? 1 : -1; } return aa > bb ? 1 : -1; }); - } - else { + } else { list.sort(lib.sort.character); } - dialog = ui.create.dialog('hidden'); - dialog.classList.add('noupdate'); - dialog.classList.add('scroll1'); - dialog.classList.add('scroll2'); - dialog.classList.add('scroll3'); - dialog.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function () { + dialog = ui.create.dialog("hidden"); + dialog.classList.add("noupdate"); + dialog.classList.add("scroll1"); + dialog.classList.add("scroll2"); + dialog.classList.add("scroll3"); + dialog.addEventListener(lib.config.touchscreen ? "touchend" : "mouseup", function () { _status.clicked2 = true; }); if (heightset) { - dialog.style.height = ((game.layout == 'long2' || game.layout == 'nova') ? 380 : 350) + 'px'; + dialog.style.height = (game.layout == "long2" || game.layout == "nova" ? 380 : 350) + "px"; dialog._scrollset = true; } dialog.getCurrentCapt = function (link, capt, noalph) { @@ -1520,220 +1577,206 @@ export class Create extends Uninstantable { dialog.seperate = []; dialog.seperatelist = seperate.list; if (dialog.seperatelist) { - newlined = document.createElement('div'); - newlined.style.marginTop = '5px'; - newlined.style.display = 'block'; - newlined.style.fontFamily = 'xinwei'; + newlined = document.createElement("div"); + newlined.style.marginTop = "5px"; + newlined.style.display = "block"; + newlined.style.fontFamily = "xinwei"; if (get.is.phoneLayout()) { - newlined.style.fontSize = '32px'; + newlined.style.fontSize = "32px"; + } else { + newlined.style.fontSize = "22px"; } - else { - newlined.style.fontSize = '22px'; - } - newlined.style.textAlign = 'center'; + newlined.style.textAlign = "center"; node.appendChild(newlined); for (var i in dialog.seperatelist) { - var span = document.createElement('span'); - span.style.margin = '3px'; + var span = document.createElement("span"); + span.style.margin = "3px"; span.innerHTML = i; span.link = i; span.seperate = true; - span.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickCapt); + span.addEventListener(lib.config.touchscreen ? "touchend" : "click", clickCapt); newlined.appendChild(span); } } for (var i in seperate) { - if (i == 'list') continue; - var link = ''; + if (i == "list") continue; + var link = ""; var linkcontent = seperate[i]; - if (i.includes('_link:')) { - link = i.slice(i.indexOf('_link:') + 6); - i = i.slice(0, i.indexOf('_link:')); + if (i.includes("_link:")) { + link = i.slice(i.indexOf("_link:") + 6); + i = i.slice(0, i.indexOf("_link:")); } var nodesep = dialog.add(i); nodesep.link = link; dialog.seperate.push(nodesep); - dialog.add([linkcontent, 'vcard'], noclick); + dialog.add([linkcontent, "vcard"], noclick); } + } else { + dialog.add([list, "vcard"], noclick); } - else { - dialog.add([list, 'vcard'], noclick); - } - } - else { + } else { if (precharacter) { - dialog.add([list, 'precharacter'], noclick); - } - else if (characterx) { - dialog.add([list, 'characterx'], noclick); - } - else { - dialog.add([list, 'character'], noclick); + dialog.add([list, "precharacter"], noclick); + } else if (characterx) { + dialog.add([list, "characterx"], noclick); + } else { + dialog.add([list, "character"], noclick); } } - dialog.add(ui.create.div('.placeholder')); + dialog.add(ui.create.div(".placeholder")); for (i = 0; i < dialog.buttons.length; i++) { if (thisiscard) { dialog.buttons[i].capt = getCapt(dialog.buttons[i].link[2]); - } - else { + } else { dialog.buttons[i].group = lib.character[dialog.buttons[i].link][1]; dialog.buttons[i].capt = getCapt(dialog.buttons[i].link); } } if (!expandall) { - if (!thisiscard && (lib.characterDialogGroup[lib.config.character_dialog_tool] || - lib.config.character_dialog_tool == '自创')) { + if ( + !thisiscard && + (lib.characterDialogGroup[lib.config.character_dialog_tool] || + lib.config.character_dialog_tool == "自创") + ) { clickCapt.call(node[lib.config.character_dialog_tool]); } } //仅仅下面是新加的,by Curpond - let container = dialog.querySelector('.content-container>.content') - let Searcher = ui.create.div('.searcher.caption') - let input = document.createElement('input') - input.style.textAlign = 'center' - input.style.border = 'solid 2px #294510' - input.style.borderRadius = '6px' - input.style.fontWeight = 'bold' - input.style.fontSize = '21px' - let find = ui.create.button(['find', '搜索'], 'tdnodes') - find.style.display = 'inline' + let container = dialog.querySelector(".content-container>.content"); + let Searcher = ui.create.div(".searcher.caption"); + let input = document.createElement("input"); + input.style.textAlign = "center"; + input.style.border = "solid 2px #294510"; + input.style.borderRadius = "6px"; + input.style.fontWeight = "bold"; + input.style.fontSize = "21px"; + let find = ui.create.button(["find", "搜索"], "tdnodes"); + find.style.display = "inline"; let clickfind = function (e) { - e.stopPropagation() - let value = input.value - if (value == '') { - game.alert('搜索不能为空') - input.focus() - return + e.stopPropagation(); + let value = input.value; + if (value == "") { + game.alert("搜索不能为空"); + input.focus(); + return; } - let list = [] + let list = []; for (let btn of dialog.buttons) { - - if ((new RegExp(value, 'g').test(get.translation(btn.link)))) { - btn.classList.remove('nodisplay') + if (new RegExp(value, "g").test(get.translation(btn.link))) { + btn.classList.remove("nodisplay"); } else { - btn.classList.add('nodisplay') + btn.classList.add("nodisplay"); } } - - } - input.addEventListener('keyup', (e) => { - - if (e.key == 'Enter') clickfind(e) - }) - find.listen(clickfind) - Searcher.appendChild(input) - Searcher.appendChild(find) - container.prepend(Searcher) - + }; + input.addEventListener("keyup", (e) => { + if (e.key == "Enter") clickfind(e); + }); + find.listen(clickfind); + Searcher.appendChild(input); + Searcher.appendChild(find); + container.prepend(Searcher); return dialog; } - static dialog() { + dialog() { let dialog = new lib.element.Dialog(...arguments); - if (!Array.from(arguments).includes('hidden')) { + if (!Array.from(arguments).includes("hidden")) { dialog.open(); } return dialog; } - static line2() { + line2() { var node = ui.create.line.apply(this, arguments); - node.classList.add('line2'); + node.classList.add("line2"); return node; } - static line() { - var two = false, func; - var node = ui.create.div('.config'); + line() { + var two = false, + func; + var node = ui.create.div(".config"); for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'string' || typeof arguments[i] == 'number') { - if (two) ui.create.div('.toggle', node).innerHTML = arguments[i]; + if (typeof arguments[i] == "string" || typeof arguments[i] == "number") { + if (two) ui.create.div(".toggle", node).innerHTML = arguments[i]; else { ui.create.div(node).innerHTML = arguments[i]; two = true; } - } - else if (typeof arguments[i] == 'function') func = arguments[i]; + } else if (typeof arguments[i] == "function") func = arguments[i]; } if (func) { for (var i = 0; i < node.childNodes.length; i++) node.childNodes[i].listen(func); } return node; } - static switcher(name, current, current2) { + switcher(name, current, current2) { var func; - var node = ui.create.div('.config'); - ui.create.div(node).innerHTML = get.translation(name + '_config'); - var switcher = ui.create.div('.toggle.pointerdiv', node); + var node = ui.create.div(".config"); + ui.create.div(node).innerHTML = get.translation(name + "_config"); + var switcher = ui.create.div(".toggle.pointerdiv", node); switcher.name = name; for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == 'function') { - func = arguments[i]; break; + if (typeof arguments[i] == "function") { + func = arguments[i]; + break; } } - if (typeof current == 'string') { + if (typeof current == "string") { switcher.link = current; switcher.innerHTML = get.translation(current); switcher.contentEditable = true; - switcher.style.webkitUserSelect = 'text'; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.editor); - } - else if (typeof current == 'object') { + switcher.style.webkitUserSelect = "text"; + switcher.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.editor); + } else if (typeof current == "object") { switcher.link = current2 || current[0]; switcher.innerHTML = get.translation(switcher.link); switcher.choice = current; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.switcher); - } - else { + switcher.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.switcher); + } else { if (current) { - switcher.classList.add('on'); + switcher.classList.add("on"); } - switcher.classList.add('onoff'); + switcher.classList.add("onoff"); ui.create.div(ui.create.div(switcher)); switcher.link = current ? true : false; - switcher.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.toggle); + switcher.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.toggle); } if (func) switcher.additionalCommand = func; return node; } - static caption(str, position) { - var caption = ui.create.div('.caption', position); + caption(str, position) { + var caption = ui.create.div(".caption", position); caption.innerHTML = str; return caption; } - static control() { + control() { return new lib.element.Control(...arguments); } - static confirm(str, func) { + confirm(str, func) { if (ui.confirm && ui.confirm.str == str) { return; } - if (str == 'o') { + if (str == "o") { if (ui.confirm) { - ui.confirm.replace('ok'); + ui.confirm.replace("ok"); + } else { + ui.confirm = ui.create.control("ok"); } - else { - ui.confirm = ui.create.control('ok'); - } - } - else if (str == 'oc' || str == 'co') { + } else if (str == "oc" || str == "co") { if (ui.confirm) { - ui.confirm.replace('ok', 'cancel'); + ui.confirm.replace("ok", "cancel"); + } else { + ui.confirm = ui.create.control("ok", "cancel"); } - else { - ui.confirm = ui.create.control('ok', 'cancel'); - } - } - else if (str == 'c') { + } else if (str == "c") { if (ui.confirm) { - ui.confirm.replace('cancel'); + ui.confirm.replace("cancel"); + } else { + ui.confirm = ui.create.control("cancel"); } - else { - ui.confirm = ui.create.control('cancel'); - } - } - else if (ui.confirm) { + } else if (ui.confirm) { ui.confirm.close(); delete ui.confirm; } @@ -1743,10 +1786,10 @@ export class Create extends Uninstantable { else delete ui.confirm.custom; } } - static skills(skills) { + skills(skills) { var i, same; if (ui.skills) { - if (ui.skills.skills.length == skills.length && ui.skills.style.display != 'none') { + if (ui.skills.skills.length == skills.length && ui.skills.style.display != "none") { same = true; for (i = 0; i < skills.length; i++) { if (ui.skills.skills.includes(skills[i]) == false) { @@ -1765,22 +1808,24 @@ export class Create extends Uninstantable { } ui.skills = ui.create.control(skills.concat([ui.click.skill])); for (var i = 0; i < ui.skills.childNodes.length; i++) { - ui.skills.childNodes[i].innerHTML = get.skillTranslation(ui.skills.childNodes[i].link, _status.event.player); + ui.skills.childNodes[i].innerHTML = get.skillTranslation( + ui.skills.childNodes[i].link, + _status.event.player + ); } if (!_status.event.isMine()) { - ui.skills.style.display = 'none'; - } - else { + ui.skills.style.display = "none"; + } else { ui.updatec(); } _status.noupdatec = false; ui.skills.skills = skills; return ui.skills; } - static skills2(skills) { + skills2(skills) { var i, same; if (ui.skills2) { - if (ui.skills2.skills.length == skills.length && ui.skills2.style.display != 'none') { + if (ui.skills2.skills.length == skills.length && ui.skills2.style.display != "none") { same = true; for (i = 0; i < skills.length; i++) { if (ui.skills2.skills.includes(skills[i]) == false) { @@ -1799,22 +1844,24 @@ export class Create extends Uninstantable { } ui.skills2 = ui.create.control(skills.concat([ui.click.skill])); for (var i = 0; i < ui.skills2.childNodes.length; i++) { - ui.skills2.childNodes[i].innerHTML = get.skillTranslation(ui.skills2.childNodes[i].link, _status.event.player); + ui.skills2.childNodes[i].innerHTML = get.skillTranslation( + ui.skills2.childNodes[i].link, + _status.event.player + ); } if (!_status.event.isMine()) { - ui.skills2.style.display = 'none'; - } - else { + ui.skills2.style.display = "none"; + } else { ui.updatec(); } _status.noupdatec = false; ui.skills2.skills = skills; return ui.skills2; } - static skills3(skills) { + skills3(skills) { var i, same; if (ui.skills3) { - if (ui.skills3.skills.length == skills.length && ui.skills3.style.display != 'none') { + if (ui.skills3.skills.length == skills.length && ui.skills3.style.display != "none") { same = true; for (i = 0; i < skills.length; i++) { if (ui.skills3.skills.includes(skills[i]) == false) { @@ -1833,58 +1880,67 @@ export class Create extends Uninstantable { } ui.skills3 = ui.create.control(skills.concat([ui.click.skill])); for (var i = 0; i < ui.skills3.childNodes.length; i++) { - ui.skills3.childNodes[i].innerHTML = get.skillTranslation(ui.skills3.childNodes[i].link, _status.event.player); + ui.skills3.childNodes[i].innerHTML = get.skillTranslation( + ui.skills3.childNodes[i].link, + _status.event.player + ); } if (!_status.event.isMine()) { - ui.skills3.style.display = 'none'; - } - else { + ui.skills3.style.display = "none"; + } else { ui.updatec(); } _status.noupdatec = false; ui.skills3.skills = skills; return ui.skills3; } - static arena() { + arena() { var i, j; - ui.window = ui.create.div('#window.hidden', document.body); - ui.create.div('#statusbg', document.body); + ui.window = ui.create.div("#window.hidden", document.body); + ui.create.div("#statusbg", document.body); ui.refresh(ui.window); - if (!localStorage.getItem(lib.configprefix + 'playback')) { + if (!localStorage.getItem(lib.configprefix + "playback")) { ui.window.show(); - } - else { + } else { setTimeout(function () { ui.window.show(); }, 1000); } // lib.setPressure(ui.window,ui.click.pressurepause); if (window.isNonameServer) { - ui.window.classList.add('server'); - var serverinfo = ui.create.div('.serverinfo', ui.window); - ui.create.div('', '服务器正在运行', serverinfo); + ui.window.classList.add("server"); + var serverinfo = ui.create.div(".serverinfo", ui.window); + ui.create.div("", "服务器正在运行", serverinfo); var serverinfotable = ui.create.table(2, 2, ui.create.div(serverinfo)); - serverinfotable.style.display = 'inline-block'; - serverinfotable.firstChild.firstChild.innerHTML = '房间人数:'; - serverinfotable.firstChild.lastChild.id = 'server_count'; - serverinfotable.firstChild.lastChild.innerHTML = '0'; - serverinfotable.lastChild.firstChild.innerHTML = '房间状态:'; - serverinfotable.lastChild.lastChild.id = 'server_status'; - serverinfotable.lastChild.lastChild.innerHTML = '空闲'; - ui.create.div('.menubutton.large', '关闭服务器', function () { - if (_status.gameStarted && !confirm('关闭服务器当前进行的游戏将终止且不可恢复,是否确定关闭?')) { - return; - } - localStorage.removeItem(lib.configprefix + 'asserver'); - game.reload(); - }, ui.create.div('', serverinfo)); + serverinfotable.style.display = "inline-block"; + serverinfotable.firstChild.firstChild.innerHTML = "房间人数:"; + serverinfotable.firstChild.lastChild.id = "server_count"; + serverinfotable.firstChild.lastChild.innerHTML = "0"; + serverinfotable.lastChild.firstChild.innerHTML = "房间状态:"; + serverinfotable.lastChild.lastChild.id = "server_status"; + serverinfotable.lastChild.lastChild.innerHTML = "空闲"; + ui.create.div( + ".menubutton.large", + "关闭服务器", + function () { + if ( + _status.gameStarted && + !confirm("关闭服务器当前进行的游戏将终止且不可恢复,是否确定关闭?") + ) { + return; + } + localStorage.removeItem(lib.configprefix + "asserver"); + game.reload(); + }, + ui.create.div("", serverinfo) + ); } - ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.window); + ui.window.addEventListener(lib.config.touchscreen ? "touchend" : "click", ui.click.window); ui.system = ui.create.div("#system.", ui.window); - ui.arena = ui.create.div('#arena.nome', ui.window); - if (lib.device == 'ios' && !get.is.phoneLayout()) { - ui.arena.classList.add('ipad'); + ui.arena = ui.create.div("#arena.nome", ui.window); + if (lib.device == "ios" && !get.is.phoneLayout()) { + ui.arena.classList.add("ipad"); } ui.arena.setNumber = function (num) { this.dataset.number = num; @@ -1904,122 +1960,147 @@ export class Create extends Uninstantable { }; if (lib.config.low_performance) { - ui.window.classList.add('low_performance'); + ui.window.classList.add("low_performance"); } - if (game.layout == 'mobile' || game.layout == 'long') { - ui.arena.classList.add('mobile'); + if (game.layout == "mobile" || game.layout == "long") { + ui.arena.classList.add("mobile"); } - if (game.layout == 'long' || game.layout == 'long2') { - ui.arena.classList.add('long'); + if (game.layout == "long" || game.layout == "long2") { + ui.arena.classList.add("long"); } - if (game.layout == 'default') { - ui.arena.classList.add('oldlayout'); + if (game.layout == "default") { + ui.arena.classList.add("oldlayout"); } - if (lib.config.player_border != 'wide' || game.layout == 'long' || game.layout == 'long2') { - ui.arena.classList.add('slim_player'); + if (lib.config.player_border != "wide" || game.layout == "long" || game.layout == "long2") { + ui.arena.classList.add("slim_player"); } - if (lib.config.player_border == 'slim') { - ui.arena.classList.add('uslim_player'); + if (lib.config.player_border == "slim") { + ui.arena.classList.add("uslim_player"); } - if (lib.config.player_border == 'narrow') { - ui.arena.classList.add('mslim_player'); + if (lib.config.player_border == "narrow") { + ui.arena.classList.add("mslim_player"); } - if (lib.config.player_border == 'normal' && lib.config.mode != 'brawl' && (game.layout == 'long' || game.layout == 'long2')) { - ui.arena.classList.add('lslim_player'); + if ( + lib.config.player_border == "normal" && + lib.config.mode != "brawl" && + (game.layout == "long" || game.layout == "long2") + ) { + ui.arena.classList.add("lslim_player"); } ui.window.dataset.player_border = lib.config.player_border; if (lib.config.compatiblemode) { - ui.window.classList.add('compatiblemode'); + ui.window.classList.add("compatiblemode"); } - ui.window.dataset.radius_size = lib.config.radius_size || 'default'; - if (game.layout == 'long' || game.layout == 'mobile') { + ui.window.dataset.radius_size = lib.config.radius_size || "default"; + if (game.layout == "long" || game.layout == "mobile") { //if(lib.config.textequip=='text') ui.arena.classList.add('textequip'); - ui.arena.classList.add('textequip'); + ui.arena.classList.add("textequip"); } - if (game.layout == 'long' || game.layout == 'long2' || game.layout == 'mobile' || game.layout == 'nova') { - if (lib.config.cardshape == 'oblong') { - ui.window.classList.add('oblongcard'); - ui.arena.classList.add('oblongcard'); + if ( + game.layout == "long" || + game.layout == "long2" || + game.layout == "mobile" || + game.layout == "nova" + ) { + if (lib.config.cardshape == "oblong") { + ui.window.classList.add("oblongcard"); + ui.arena.classList.add("oblongcard"); } } if (lib.config.blur_ui) { - ui.window.classList.add('blur_ui'); + ui.window.classList.add("blur_ui"); } if (lib.config.glass_ui) { - ui.window.classList.add('glass_ui'); + ui.window.classList.add("glass_ui"); } if (lib.config.custom_button) { - lib.configMenu.appearence.config.custom_button.onclick('skip'); + lib.configMenu.appearence.config.custom_button.onclick("skip"); } - if (lib.config.show_statusbar_ios == 'overlay') { - document.body.classList.add('statusbar'); + if (lib.config.show_statusbar_ios == "overlay") { + document.body.classList.add("statusbar"); } if (lib.config.keep_awake) { if (window.plugins && window.plugins.insomnia) window.plugins.insomnia.keepAwake(); else { - lib.init.js(lib.assetURL + 'game', 'NoSleep', function () { + lib.init.js(lib.assetURL + "game", "NoSleep", function () { var noSleep = new NoSleep(); - document.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function enableNoSleep() { - document.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', enableNoSleep, false); - noSleep.enable(); - window.noSleep = noSleep; - }, false); + document.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + function enableNoSleep() { + document.removeEventListener( + lib.config.touchscreen ? "touchend" : "click", + enableNoSleep, + false + ); + noSleep.enable(); + window.noSleep = noSleep; + }, + false + ); }); } } - lib.init.js(lib.assetURL + 'game', 'pinyinjs', function () { }); - lib.init.js(lib.assetURL + 'game', 'keyWords', function () { }); + lib.init.js(lib.assetURL + "game", "pinyinjs", function () {}); + lib.init.js(lib.assetURL + "game", "keyWords", function () {}); lib.updateURL = lib.updateURLS[lib.config.update_link] || lib.updateURLS.coding; lib.init.cssstyles(); - ui.arena.dataset.player_height = lib.config.player_height || 'default'; - ui.arena.dataset.player_height_nova = lib.config.player_height_nova || 'default'; + ui.arena.dataset.player_height = lib.config.player_height || "default"; + ui.arena.dataset.player_height_nova = lib.config.player_height_nova || "default"; // if(lib.config.player_height_nova=='long') ui.arena.classList.add('player_autolong'); - ui.arena.dataset.target_shake = lib.config.target_shake || 'off'; - ui.backgroundMusic = document.createElement('audio'); + ui.arena.dataset.target_shake = lib.config.target_shake || "off"; + ui.backgroundMusic = document.createElement("audio"); ui.backgroundMusic.volume = lib.config.volumn_background / 8; game.playBackgroundMusic(); ui.backgroundMusic.autoplay = true; - ui.backgroundMusic.addEventListener('ended', game.playBackgroundMusic); + ui.backgroundMusic.addEventListener("ended", game.playBackgroundMusic); ui.window.appendChild(ui.backgroundMusic); - ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', () => { - if (!ui.backgroundMusic.played.length && lib.config.background_music != 'music_off' && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play(); - }, { once: true }); - if (lib.config.cursor_style == 'pointer') { - ui.window.classList.add('nopointer'); + ui.window.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + () => { + if ( + !ui.backgroundMusic.played.length && + lib.config.background_music != "music_off" && + !isNaN(ui.backgroundMusic.duration) + ) + ui.backgroundMusic.play(); + }, + { once: true } + ); + if (lib.config.cursor_style == "pointer") { + ui.window.classList.add("nopointer"); } if (lib.config.turned_style == false) { - ui.arena.classList.add('hide_turned'); + ui.arena.classList.add("hide_turned"); } - if (lib.config.link_style2 != 'chain') { - ui.arena.classList.add('nolink'); + if (lib.config.link_style2 != "chain") { + ui.arena.classList.add("nolink"); } if (lib.config.show_name == false) { - ui.arena.classList.add('hide_name'); + ui.arena.classList.add("hide_name"); } - if (lib.config.change_skin_auto != 'off') { + if (lib.config.change_skin_auto != "off") { _status.skintimeout = setTimeout(ui.click.autoskin, parseInt(lib.config.change_skin_auto)); } - if (lib.config.border_style && lib.config.border_style.startsWith('dragon_')) { + if (lib.config.border_style && lib.config.border_style.startsWith("dragon_")) { ui.arena.dataset.framedecoration = lib.config.border_style.slice(7); } - ui.gameinfo = ui.create.div('#time', ui.window); + ui.gameinfo = ui.create.div("#time", ui.window); - ui.arenalog = ui.create.div('#arenalog', ui.arena); - if (lib.config.show_log == 'off') { - ui.arenalog.style.display = 'none'; - } - else { + ui.arenalog = ui.create.div("#arenalog", ui.arena); + if (lib.config.show_log == "off") { + ui.arenalog.style.display = "none"; + } else { ui.arenalog.dataset.position = lib.config.show_log; } - ui.historybar = ui.create.div('#historybar.shadowed', ui.window); + ui.historybar = ui.create.div("#historybar.shadowed", ui.window); lib.setScroll(ui.historybar); - ui.roundmenu = ui.create.div('#roundmenu.roundarenabutton.menubutton.round', ui.arena); + ui.roundmenu = ui.create.div("#roundmenu.roundarenabutton.menubutton.round", ui.arena); ui.roundmenu._position = [180, 210]; ui.create.div(ui.roundmenu); ui.create.div(ui.roundmenu); @@ -2041,23 +2122,22 @@ export class Create extends Uninstantable { ui.create.div(ui.roundmenu); if (lib.config.show_time2) { - ui.roundmenu.classList.add('clock'); + ui.roundmenu.classList.add("clock"); } - ui.roundmenu.dataset.watchface = lib.config.watchface || 'none'; + ui.roundmenu.dataset.watchface = lib.config.watchface || "none"; if (get.is.phoneLayout()) { if (lib.config.show_time3) { - ui.time3 = ui.create.div('.touchinfo.left', ui.window); + ui.time3 = ui.create.div(".touchinfo.left", ui.window); } - ui.cardPileNumber = ui.create.div('.touchinfo.right', ui.window); - } - else { + ui.cardPileNumber = ui.create.div(".touchinfo.right", ui.window); + } else { if (lib.config.show_time3) { ui.time3 = ui.create.div(ui.gameinfo); } ui.cardPileNumber = ui.create.div(ui.gameinfo); } if (!lib.config.show_cardpile_number) { - ui.cardPileNumber.style.display = 'none'; + ui.cardPileNumber.style.display = "none"; } if (ui.time3) { ui.time3.starttime = get.utc(); @@ -2067,51 +2147,49 @@ export class Create extends Uninstantable { var num1 = Math.floor(num / 3600); var num2 = Math.floor((num - num1 * 3600) / 60); if (num2 < 10) { - num2 = '0' + num2.toString(); + num2 = "0" + num2.toString(); } var num3 = num - num1 * 3600 - parseInt(num2) * 60; if (num3 < 10) { - num3 = '0' + num3.toString(); + num3 = "0" + num3.toString(); } - ui.time3.innerHTML = num1 + ':' + num2 + ':' + num3; - } - else { + ui.time3.innerHTML = num1 + ":" + num2 + ":" + num3; + } else { var num1 = Math.floor(num / 60); var num2 = num - num1 * 60; if (num2 < 10) { - num2 = '0' + num2.toString(); + num2 = "0" + num2.toString(); } - ui.time3.innerHTML = num1 + ':' + num2; + ui.time3.innerHTML = num1 + ":" + num2; } }, 1000); } if (get.is.nomenu()) { - if (!['menu', 'system'].includes(lib.config.round_menu_func)) { - lib.config.round_menu_func = 'system'; + if (!["menu", "system"].includes(lib.config.round_menu_func)) { + lib.config.round_menu_func = "system"; } - } - else if (!lib.config.show_round_menu) { - ui.roundmenu.style.display = 'none'; + } else if (!lib.config.show_round_menu) { + ui.roundmenu.style.display = "none"; } var resetround = function (e) { _status.draggingroundmenu = false; - ui.roundmenu.style.transform = ''; + ui.roundmenu.style.transform = ""; ui.roundmenu._dragtransform = [0, 0]; - ui.roundmenu.style.transition = 'all 0.3s'; + ui.roundmenu.style.transition = "all 0.3s"; delete ui.roundmenu._dragtouches; delete ui.roundmenu._dragorigin; delete ui.roundmenu._dragorigintransform; setTimeout(function () { - ui.roundmenu.style.transition = ''; + ui.roundmenu.style.transition = ""; }, 500); - game.saveConfig('roundmenu_transform', [0, 0]); + game.saveConfig("roundmenu_transform", [0, 0]); if (e) e.stopPropagation(); return false; }; ui.click.resetround = resetround; if (lib.config.touchscreen) { - ui.roundmenu.addEventListener('touchstart', function (e) { + ui.roundmenu.addEventListener("touchstart", function (e) { _status.draggingroundmenu = true; ui.roundmenu._dragorigin = { clientX: e.touches[0].clientX, @@ -2126,61 +2204,79 @@ export class Create extends Uninstantable { delete ui.roundmenu._resetTimeout; }, 1000); }); - } - else { + } else { ui.roundmenu.oncontextmenu = resetround; } if (!lib.config.remember_round_button) { - game.saveConfig('roundmenu_transform'); + game.saveConfig("roundmenu_transform"); } if (lib.config.roundmenu_transform) { var translate = lib.config.roundmenu_transform; ui.roundmenu._dragtransform = translate; - ui.roundmenu.style.transform = 'translate(' + translate[0] + 'px,' + translate[1] + 'px)'; + ui.roundmenu.style.transform = "translate(" + translate[0] + "px," + translate[1] + "px)"; ui.click.checkroundtranslate(); } if (get.is.phoneLayout()) { - ui.arena.classList.add('phone'); + ui.arena.classList.add("phone"); } - ui.sidebar = ui.create.div('#sidebar'); - ui.sidebar3 = ui.create.div('#sidebar3'); - ui.canvas = document.createElement('canvas'); + ui.sidebar = ui.create.div("#sidebar"); + ui.sidebar3 = ui.create.div("#sidebar3"); + ui.canvas = document.createElement("canvas"); ui.arena.appendChild(ui.canvas); - ui.canvas.id = 'canvas'; - ui.ctx = ui.canvas.getContext('2d'); + ui.canvas.id = "canvas"; + ui.ctx = ui.canvas.getContext("2d"); ui.sidebar.ontouchstart = ui.click.touchStart; ui.sidebar.ontouchmove = ui.click.touchScroll; - ui.sidebar.style.webkitOverflowScrolling = 'touch'; + ui.sidebar.style.webkitOverflowScrolling = "touch"; var zoom; switch (lib.config.ui_zoom) { - case 'esmall': zoom = 0.8; break; - case 'vsmall': zoom = 0.9; break; - case 'small': zoom = 0.93; break; - case 'big': zoom = 1.05; break; - case 'vbig': zoom = 1.1; break; - case 'ebig': zoom = 1.2; break; - case 'eebig': zoom = 1.5; break; - case 'eeebig': zoom = 1.8; break; - case 'eeeebig': zoom = 2; break; - default: zoom = 1; + case "esmall": + zoom = 0.8; + break; + case "vsmall": + zoom = 0.9; + break; + case "small": + zoom = 0.93; + break; + case "big": + zoom = 1.05; + break; + case "vbig": + zoom = 1.1; + break; + case "ebig": + zoom = 1.2; + break; + case "eebig": + zoom = 1.5; + break; + case "eeebig": + zoom = 1.8; + break; + case "eeeebig": + zoom = 2; + break; + default: + zoom = 1; } game.documentZoom = game.deviceZoom * zoom; if (zoom != 1) { ui.updatez(); } - ui.system1 = ui.create.div('#system1', ui.system); - ui.system2 = ui.create.div('#system2', ui.system); + ui.system1 = ui.create.div("#system1", ui.system); + ui.system2 = ui.create.div("#system2", ui.system); - ui.replay = ui.create.system('重来', game.reload, true); - ui.replay.id = 'restartbutton'; - ui.config2 = ui.create.system('选项', ui.click.config); - ui.pause = ui.create.system('暂停', ui.click.pause); - ui.pause.id = 'pausebutton'; + ui.replay = ui.create.system("重来", game.reload, true); + ui.replay.id = "restartbutton"; + ui.config2 = ui.create.system("选项", ui.click.config); + ui.pause = ui.create.system("暂停", ui.click.pause); + ui.pause.id = "pausebutton"; if (!_status.video) { ui.pause.hide(); } @@ -2188,104 +2284,108 @@ export class Create extends Uninstantable { lib.setPopped(ui.pause, ui.click.pausehistory, 220, 400, null, true); } if (!lib.config.show_pause) { - ui.pause.style.display = 'none'; + ui.pause.style.display = "none"; } - ui.cardPileButton = ui.create.system('牌堆', null, true); - ui.cardPileButton.style.display = 'none'; + ui.cardPileButton = ui.create.system("牌堆", null, true); + ui.cardPileButton.style.display = "none"; lib.setPopped(ui.cardPileButton, ui.click.cardPileButton, 220); - ui.wuxie = ui.create.system('不询问无懈', ui.click.wuxie, true); + ui.wuxie = ui.create.system("不询问无懈", ui.click.wuxie, true); if (!lib.config.touchscreen) { lib.setPopped(ui.config2, ui.click.pauseconfig, 170); } - ui.auto = ui.create.system('托管', ui.click.auto); + ui.auto = ui.create.system("托管", ui.click.auto); if (!game.syncMenu) { - ui.config2.classList.add('hidden'); - ui.config2.style.transition = 'all 0.5s'; - ui.roundmenu.classList.add('transparent2'); + ui.config2.classList.add("hidden"); + ui.config2.style.transition = "all 0.5s"; + ui.roundmenu.classList.add("transparent2"); ui.auto.style.opacity = 0.5; - ui.auto.style.transition = 'all 0.5s'; + ui.auto.style.transition = "all 0.5s"; lib.onfree.push(function () { - ui.auto.style.opacity = ''; + ui.auto.style.opacity = ""; setTimeout(function () { - ui.auto.style.transition = ''; + ui.auto.style.transition = ""; }, 500); }); } - ui.auto.id = 'autobutton'; - ui.autonode = ui.create.div('#autonode', '
                                      托管中...
                                      ', ui.arena); + ui.auto.id = "autobutton"; + ui.autonode = ui.create.div("#autonode", "
                                      托管中...
                                      ", ui.arena); ui.autonode.listen(ui.click.auto); - if (lib.config.mode == 'connect') { + if (lib.config.mode == "connect") { ui.auto.hide(); ui.pause.hide(); } if (lib.forcehide) { - if (lib.forcehide.includes('replay')) ui.replay.classList.add('forcehide'); - if (lib.forcehide.includes('auto')) ui.auto.classList.add('forcehide'); - if (lib.forcehide.includes('pause')) ui.pause.classList.add('forcehide'); - if (lib.forcehide.includes('wuxie')) ui.wuxie.classList.add('forcehide'); - if (lib.forcehide.includes('cardPileButton')) ui.cardPileButton.classList.add('forcehide'); + if (lib.forcehide.includes("replay")) ui.replay.classList.add("forcehide"); + if (lib.forcehide.includes("auto")) ui.auto.classList.add("forcehide"); + if (lib.forcehide.includes("pause")) ui.pause.classList.add("forcehide"); + if (lib.forcehide.includes("wuxie")) ui.wuxie.classList.add("forcehide"); + if (lib.forcehide.includes("cardPileButton")) ui.cardPileButton.classList.add("forcehide"); } - ui.volumn = ui.create.system('♫'); + ui.volumn = ui.create.system("♫"); lib.setPopped(ui.volumn, ui.click.volumn, 200); // if(lib.config.show_pause) ui.auto.style.marginLeft='10px'; if (!lib.config.show_volumn) { - ui.volumn.style.display = 'none'; + ui.volumn.style.display = "none"; } if (!lib.config.show_auto) { - ui.auto.style.display = 'none'; + ui.auto.style.display = "none"; } if (!lib.config.show_wuxie) { - ui.wuxie.style.display = 'none'; + ui.wuxie.style.display = "none"; } // if(!lib.config.show_cardpile||_status.connectMode){ // ui.cardPileButton.style.display='none'; // } - ui.sortCard = ui.create.system('整理手牌', function () { + ui.sortCard = ui.create.system("整理手牌", function () { if (!game.me) return; - var hs = game.me.getCards('h'); + var hs = game.me.getCards("h"); if (!hs.length) return; - game.addVideo('lose', game.me, [get.cardsInfo(hs), [], [], []]); + game.addVideo("lose", game.me, [get.cardsInfo(hs), [], [], []]); for (var i = 0; i < hs.length; i++) { hs[i].goto(ui.special); } - if (game.me.hasSkillTag('sortCardByNum')) { + if (game.me.hasSkillTag("sortCardByNum")) { var getn = function (card) { var num = get.number(card, game.me); if (num < 3) return 13 + num; return num; }; - hs.sort((a, b) => (getn(b) - getn(a))); - } - else hs.sort(function (b, a) { - if (a.name != b.name) return lib.sort.card(a.name, b.name); - else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); - else return a.number - b.number; - }); + hs.sort((a, b) => getn(b) - getn(a)); + } else + hs.sort(function (b, a) { + if (a.name != b.name) return lib.sort.card(a.name, b.name); + else if (a.suit != b.suit) return lib.suit.indexOf(a) - lib.suit.indexOf(b); + else return a.number - b.number; + }); game.me.directgain(hs, false); }); if (!lib.config.show_sortcard) { - ui.sortCard.style.display = 'none'; + ui.sortCard.style.display = "none"; } - ui.playerids = ui.create.system('显示身份', function () { - if (game.showIdentity) { - game.showIdentity(); - _status.identityShown = true; - } - }, true); + ui.playerids = ui.create.system( + "显示身份", + function () { + if (game.showIdentity) { + game.showIdentity(); + _status.identityShown = true; + } + }, + true + ); if (!lib.config.show_playerids || !game.showIdentity) { - ui.playerids.style.display = 'none'; + ui.playerids.style.display = "none"; } if (!lib.config.show_replay) { - ui.replay.style.display = 'none'; + ui.replay.style.display = "none"; } - ui.control = ui.create.div('#control', ui.arena).addTempClass('nozoom'); - ui.cardPile = ui.create.div('#cardPile'); - ui.discardPile = ui.create.div('#discardPile'); - ui.special = ui.create.div('#special'); - ui.ordering = ui.create.div('#ordering'); + ui.control = ui.create.div("#control", ui.arena).addTempClass("nozoom"); + ui.cardPile = ui.create.div("#cardPile"); + ui.discardPile = ui.create.div("#discardPile"); + ui.special = ui.create.div("#special"); + ui.ordering = ui.create.div("#ordering"); ui.dialogs = []; ui.controls = []; ui.style = {}; @@ -2295,130 +2395,149 @@ export class Create extends Uninstantable { var date = new Date(); var hours = date.getHours(); var minutes = date.getMinutes(); - if (lib.config.watchface == 'simple') { - ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + 9) * 30, 2) + 'deg)'; + if (lib.config.watchface == "simple") { + ui.roundmenu.childNodes[13].style.transform = + "rotate(" + get.round((hours + 9) * 30, 2) + "deg)"; + } else { + ui.roundmenu.childNodes[13].style.transform = + "rotate(" + get.round((hours + minutes / 60 + 9) * 30, 2) + "deg)"; } - else { - ui.roundmenu.childNodes[13].style.transform = 'rotate(' + get.round((hours + minutes / 60 + 9) * 30, 2) + 'deg)'; - } - ui.roundmenu.childNodes[12].style.transform = 'rotate(' + (minutes + 45) * 6 + 'deg)'; + ui.roundmenu.childNodes[12].style.transform = "rotate(" + (minutes + 45) * 6 + "deg)"; if (minutes < 10) { - minutes = '0' + minutes.toString(); + minutes = "0" + minutes.toString(); } - ui.time.innerHTML = hours + ':' + minutes; + ui.time.innerHTML = hours + ":" + minutes; }; _status.timeInterval = setInterval(timeInterval, 30000); timeInterval(); if (!lib.config.show_time) { - ui.time.style.display = 'none'; + ui.time.style.display = "none"; } - ui.timer = ui.create.div('.skillbar.shadowed.playerbg.hidden'); - ui.timer.id = 'timer'; - ui.create.div('.skillbarshadow', ui.timer); - ui.create.div('.skillbarfill', ui.timer); + ui.timer = ui.create.div(".skillbar.shadowed.playerbg.hidden"); + ui.timer.id = "timer"; + ui.create.div(".skillbarshadow", ui.timer); + ui.create.div(".skillbarfill", ui.timer); ui.timer.fillnode = ui.create.div(ui.timer.lastChild); - ui.timer.popnode = ui.create.div('.skillbartext', ui.timer); + ui.timer.popnode = ui.create.div(".skillbartext", ui.timer); ui.timer.popnode.style.opacity = 1; ui.timer.position = 4; ui.timer.style.zIndex = 5; ui.timer.set = function (text, percentage) { - if (typeof text == 'string' || typeof text == 'number') { + if (typeof text == "string" || typeof text == "number") { ui.timer.popnode.innerHTML = text; } - ui.timer.fillnode.style.top = ((1 - percentage) * 100) + '%'; + ui.timer.fillnode.style.top = (1 - percentage) * 100 + "%"; }; var setTimerPosition = function (e) { this.position++; if (this.position > 4) { this.position = 1; } - var left1 = '180px'; - var left2 = 'calc(100% - 245px)'; - var top1 = '210px'; - var top2 = 'calc(100% - 245px)'; - if (game.layout == 'default') { - left1 = '265px'; - top1 = '160px'; - left2 = 'calc(100% - 330px)'; - top2 = 'calc(100% - 235px)'; + var left1 = "180px"; + var left2 = "calc(100% - 245px)"; + var top1 = "210px"; + var top2 = "calc(100% - 245px)"; + if (game.layout == "default") { + left1 = "265px"; + top1 = "160px"; + left2 = "calc(100% - 330px)"; + top2 = "calc(100% - 235px)"; } if (this.position == 1 || this.position == 2) { this.style.top = top2; - } - else { + } else { this.style.top = top1; } if (this.position == 1 || this.position == 4) { this.style.left = left2; - } - else { + } else { this.style.left = left1; } }; ui.timer.listen(setTimerPosition); - ui.shortcut = ui.create.div('#shortcut.hidden', ui.window); + ui.shortcut = ui.create.div("#shortcut.hidden", ui.window); ui.shortcut.listen(ui.click.shortcut); - ui.create.div(ui.shortcut, function (e) { e.stopPropagation(); }); - ui.create.div('.menubutton.round', '重来', ui.shortcut, game.reload).dataset.position = 1; - ui.create.div('.menubutton.round', '退出', ui.shortcut, game.exit).dataset.position = 3; - ui.create.div('.menubutton.round', '记录', ui.shortcut, ui.click.pause).dataset.position = 4; - ui.shortcut.autobutton = ui.create.div('.menubutton.round', '托管', ui.shortcut, ui.click.auto); + ui.create.div(ui.shortcut, function (e) { + e.stopPropagation(); + }); + ui.create.div( + ".menubutton.round", + "重来", + ui.shortcut, + game.reload + ).dataset.position = 1; + ui.create.div(".menubutton.round", "退出", ui.shortcut, game.exit).dataset.position = 3; + ui.create.div( + ".menubutton.round", + "记录", + ui.shortcut, + ui.click.pause + ).dataset.position = 4; + ui.shortcut.autobutton = ui.create.div( + ".menubutton.round", + "托管", + ui.shortcut, + ui.click.auto + ); ui.shortcut.autobutton.dataset.position = 2; - ui.favmodelist = ui.create.div('.favmodelist', ui.shortcut); + ui.favmodelist = ui.create.div(".favmodelist", ui.shortcut); ui.favmodelist.update = function () { const favouriteMode = lib.config.favouriteMode; let removed = false; for (let index = 0; index < favouriteMode.length; index++) { - if (typeof favouriteMode[index] == 'string') continue; + if (typeof favouriteMode[index] == "string") continue; favouriteMode.splice(index--, 1); if (!removed) removed = true; } - if (removed) game.saveConfigValue('favouriteMode'); - this.innerHTML = ''; + if (removed) game.saveConfigValue("favouriteMode"); + this.innerHTML = ""; favouriteMode.slice(0, 6).forEach((value, index) => this.add(value, index)); let mode = lib.config.mode; const config = get.config(`${mode}_mode`); - if (typeof config == 'string') mode += `|${config}`; - if (favouriteMode.includes(mode)) ui.favmode.classList.add('glow'); - else ui.favmode.classList.remove('glow'); + if (typeof config == "string") mode += `|${config}`; + if (favouriteMode.includes(mode)) ui.favmode.classList.add("glow"); + else ui.favmode.classList.remove("glow"); }; ui.favmodelist.add = function (name, index) { - const info = name.split('|'), mode = info[0], submode = info[1], node = ui.create.div('.menubutton.large', this), dataset = node.dataset; - dataset.type = Math.min(6, lib.config.favouriteMode.length) % 2 == 0 ? 'even' : 'odd'; + const info = name.split("|"), + mode = info[0], + submode = info[1], + node = ui.create.div(".menubutton.large", this), + dataset = node.dataset; + dataset.type = Math.min(6, lib.config.favouriteMode.length) % 2 == 0 ? "even" : "odd"; dataset.position = index; - let str = lib.translate[name] || lib.translate[mode] || ''; - if (str.length == 2) str += '模式'; + let str = lib.translate[name] || lib.translate[mode] || ""; + if (str.length == 2) str += "模式"; node.innerHTML = str; node.listen(() => { - game.saveConfig('mode', mode); + game.saveConfig("mode", mode); if (submode) game.saveConfig(`${mode}_mode`, submode, mode); game.reload(); }); }; - ui.favmode = ui.create.system('收藏', function () { - const mode = typeof _status.mode == 'string' ? `${lib.config.mode}|${_status.mode}` : lib.config.mode; - if (this.classList.contains('glow')) { - this.classList.remove('glow'); + ui.favmode = ui.create.system("收藏", function () { + const mode = + typeof _status.mode == "string" ? `${lib.config.mode}|${_status.mode}` : lib.config.mode; + if (this.classList.contains("glow")) { + this.classList.remove("glow"); lib.config.favouriteMode.remove(mode); - } - else { - this.classList.add('glow'); + } else { + this.classList.add("glow"); lib.config.favouriteMode.add(mode); } - game.saveConfig('favouriteMode', lib.config.favouriteMode); + game.saveConfig("favouriteMode", lib.config.favouriteMode); ui.favmodelist.update(); _status.clicked = true; }); - ui.favmode.style.display = 'none'; + ui.favmode.style.display = "none"; ui.favmodelist.update(); // ui.create.div('.menubutton.round','菜单',ui.shortcut,ui.click.config).dataset.position=5; - if (_status.connectMode) { ui.playerids.remove(); - ui.pause.innerHTML = '记录'; + ui.pause.innerHTML = "记录"; } setTimerPosition.call(ui.timer); ui.arena.appendChild(ui.timer); @@ -2426,26 +2545,25 @@ export class Create extends Uninstantable { if (!game.syncMenu) { lib.onfree.push(function () { ui.create.menu(); - ui.config2.classList.remove('hidden'); - ui.roundmenu.classList.remove('transparent2'); + ui.config2.classList.remove("hidden"); + ui.roundmenu.classList.remove("transparent2"); setTimeout(function () { - ui.config2.style.transition = ''; + ui.config2.style.transition = ""; }, 500); }); - } - else { + } else { ui.create.menu(); } lib.status.date = new Date(); lib.status.dateDelayed = 0; - while (lib.arenaReady.length) { - (lib.arenaReady.shift())(); - } + // @ts-ignore + while (lib.arenaReady.length) lib.arenaReady.shift()(); delete lib.arenaReady; - if (lib.config.auto_check_update) { - setTimeout(function () { + if (lib.config.auto_check_update && !sessionStorage.getItem("auto_check_update")) { + setTimeout(() => { + sessionStorage.setItem("auto_check_update", '1'); game.checkForUpdate(false); }, 3000); } @@ -2453,57 +2571,53 @@ export class Create extends Uninstantable { lib.onfree.push(function () { setTimeout(function () { if (!game.download) { - game.saveConfig('asset_version', '无'); - } - else { + game.saveConfig("asset_version", "无"); + } else { var func = function () { - if (confirm('是否下载图片和字体素材?(约175MB)')) { - if (!ui.arena.classList.contains('menupaused')) { + if (confirm("是否下载图片和字体素材?(约386.6MB)")) { + if (!ui.arena.classList.contains("menupaused")) { ui.click.configMenu(); - ui.click.menuTab('其它'); + ui.click.menuTab("其它"); } setTimeout(game.checkForAssetUpdate, 500); - } - else { - game.saveConfig('asset_version', '无'); + } else { + game.saveConfig("asset_version", "无"); } }; if (_status.new_tutorial) { _status.new_tutorial = func; - } - else { + } else { func(); } } }, 3000); }); } - if (localStorage.getItem(lib.configprefix + 'playback')) { + if (localStorage.getItem(lib.configprefix + "playback")) { setTimeout(lib.init.onfree); } if (lib.config.test_game) { - ui.window.classList.add('testing'); - lib.config.game_speed = 'vfast'; + ui.window.classList.add("testing"); + lib.config.game_speed = "vfast"; lib.config.low_performance = true; lib.config.animation = false; _status.auto = true; - ui.auto.classList.add('glow'); + ui.auto.classList.add("glow"); setTimeout(function () { - var node = ui.create.pause().addTempClass('start'); + var node = ui.create.pause().addTempClass("start"); node.appendChild(ui.sidebar); - node.firstChild.innerHTML = '正在测试'; - node.removeEventListener('click', ui.click.resume); + node.firstChild.innerHTML = "正在测试"; + node.removeEventListener("click", ui.click.resume); }, 500); } } - static system(str, func, right, before) { + system(str, func, right, before) { var parent = right ? ui.system2 : ui.system1; var node = ui.create.div(); if (before) { parent.insertBefore(node, parent.firstChild); - } - else { + } else { parent.appendChild(node); } node.innerHTML = str; @@ -2511,19 +2625,19 @@ export class Create extends Uninstantable { node.listen(func); } if (lib.config.button_press) { - node.addEventListener(lib.config.touchscreen ? 'touchstart' : 'mousedown', function (e) { - if (!node.classList.contains('hidden')) node.classList.add('pressdown'); + node.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", function (e) { + if (!node.classList.contains("hidden")) node.classList.add("pressdown"); }); - node.addEventListener(lib.config.touchscreen ? 'touchend' : 'mouseup', function (e) { - node.classList.remove('pressdown'); + node.addEventListener(lib.config.touchscreen ? "touchend" : "mouseup", function (e) { + node.classList.remove("pressdown"); }); - node.addEventListener(lib.config.touchscreen ? 'touchmove' : 'mousemove', function (e) { - node.classList.remove('pressdown'); + node.addEventListener(lib.config.touchscreen ? "touchmove" : "mousemove", function (e) { + node.classList.remove("pressdown"); }); } return node; } - static pause() { + pause() { if (_status.pausing) return; ui.click.shortcut(false); var node = ui.create.div(".pausedbg", ui.window); @@ -2533,11 +2647,10 @@ export class Create extends Uninstantable { }, 500); if (lib.config.touchscreen) { setTimeout(function () { - node.addEventListener('touchend', ui.click.resume); + node.addEventListener("touchend", ui.click.resume); }, 500); - } - else { - node.addEventListener('click', ui.click.resume); + } else { + node.addEventListener("click", ui.click.resume); } if (!lib.config.touchscreen) { node.oncontextmenu = ui.click.resume; @@ -2545,10 +2658,9 @@ export class Create extends Uninstantable { var node2 = ui.create.div(node); if (_status.connectMode) { - node2.innerHTML = ''; - } - else { - node2.innerHTML = '已暂停'; + node2.innerHTML = ""; + } else { + node2.innerHTML = "已暂停"; } // node2.listen(function(){ @@ -2564,9 +2676,9 @@ export class Create extends Uninstantable { // }); return node; } - static prebutton(item, type, position, noclick) { + prebutton(item, type, position, noclick) { var node = ui.create.div(position); - node.style.display = 'none'; + node.style.display = "none"; node.link = item; node.activate = function () { ui.create.button(item, type, position, noclick, node); @@ -2575,18 +2687,17 @@ export class Create extends Uninstantable { _status.prebutton.push(node); return node; } - static buttonPresets = { + buttonPresets = { /** * @returns { import("../library/index.js").Button } */ tdnodes: (item, type, position, noclick, node) => { - node = ui.create.div('.shadowed.reduce_radius.pointerdiv.tdnode.tdnodes', position); + node = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode.tdnodes", position); if (Array.isArray(item)) { - node.innerHTML = '' + (item[1]) + ''; + node.innerHTML = "" + item[1] + ""; node.link = item[0]; - } - else { - node.innerHTML = '' + (item) + ''; + } else { + node.innerHTML = "" + item + ""; node.link = item; } return node; @@ -2595,13 +2706,12 @@ export class Create extends Uninstantable { * @returns { import("../library/index.js").Button } */ blank: (item, type, position, noclick, node) => { - node = ui.create.div('.button.card', position); + node = ui.create.div(".button.card", position); node.link = item; - if (get.position(item) == 'j' && item.viewAs && lib.config.cardtempname != 'off') { - node.classList.add('infoflip'); - node.classList.add('infohidden') - ui.create.cardTempName(item, node).style.setProperty('display', 'block', 'important') - + if (get.position(item) == "j" && item.viewAs && lib.config.cardtempname != "off") { + node.classList.add("infoflip"); + node.classList.add("infohidden"); + ui.create.cardTempName(item, node).style.setProperty("display", "block", "important"); } return node; }, @@ -2609,30 +2719,34 @@ export class Create extends Uninstantable { * @returns { import("../library/index.js").Button } */ card: (item, type, position, noclick, node) => { - if (typeof item.copy == 'function') { + if (typeof item.copy == "function") { node = item.copy(false); - } - else { + } else { node = item.cloneNode(true); } - node.classList.add('button'); + node.classList.add("button"); if (position) position.appendChild(node); node.link = item; if (item.style.backgroundImage) { node.style.backgroundImage = item.style.backgroundImage; - node.style.backgroundSize = 'cover'; + node.style.backgroundSize = "cover"; } if (item.style.color) { node.style.color = item.style.color; } if (item.nature) { let natures = get.natureList(item.nature); - natures.forEach(n => node.classList.add(n)); + natures.forEach((n) => node.classList.add(n)); } if (!noclick) { lib.setIntro(node); } - if (get.position(item) == 'j' && item.viewAs && item.viewAs != item.name && lib.config.cardtempname != 'off') { + if ( + get.position(item) == "j" && + item.viewAs && + item.viewAs != item.name && + lib.config.cardtempname != "off" + ) { ui.create.cardTempName(item, node); } return node; @@ -2641,11 +2755,11 @@ export class Create extends Uninstantable { * @returns { import("../library/index.js").Button } */ vcard: (item, type, position, noclick, node) => { - if (typeof item == 'string') { - item = [get.type(item), '', item]; + if (typeof item == "string") { + item = [get.type(item), "", item]; } - node = ui.create.card(position, 'noclick', noclick); - node.classList.add('button'); + node = ui.create.card(position, "noclick", noclick); + node.classList.add("button"); node.init(item); node.link = item; return node; @@ -2655,25 +2769,30 @@ export class Create extends Uninstantable { */ character: (item, type, position, noclick, node) => { if (node) { - node.classList.add('button'); - node.classList.add('character'); - node.style.display = ''; - } - else { - node = ui.create.div('.button.character', position); + node.classList.add("button"); + node.classList.add("character"); + node.style.display = ""; + } else { + node = ui.create.div(".button.character", position); } node._link = item; - if (_status.noReplaceCharacter && type == 'characterx') type = 'character'; - if (type == 'characterx') { - if (lib.characterReplace[item] && lib.characterReplace[item].length) item = lib.characterReplace[item].randomGet(); + if (_status.noReplaceCharacter && type == "characterx") type = "character"; + if (type == "characterx") { + if (lib.characterReplace[item] && lib.characterReplace[item].length) + item = lib.characterReplace[item].randomGet(); } node.link = item; var double = get.is.double(node._link, true); if (double) node._changeGroup = true; - if (type == 'characterx' && lib.characterReplace[node._link] && lib.characterReplace[node._link].length > 1) node._replaceButton = true; + if ( + type == "characterx" && + lib.characterReplace[node._link] && + lib.characterReplace[node._link].length > 1 + ) + node._replaceButton = true; var func = function (node, item) { - node.setBackground(item, 'character'); + node.setBackground(item, "character"); if (node.node) { node.node.name.remove(); node.node.hp.remove(); @@ -2682,76 +2801,78 @@ export class Create extends Uninstantable { if (node.node.replaceButton) node.node.replaceButton.remove(); } node.node = { - name: ui.create.div('.name', node), - hp: ui.create.div('.hp', node), - group: ui.create.div('.identity', node), - intro: ui.create.div('.intro', node), + name: ui.create.div(".name", node), + hp: ui.create.div(".hp", node), + group: ui.create.div(".identity", node), + intro: ui.create.div(".intro", node), }; var infoitem = lib.character[item]; if (!infoitem) { for (var itemx in lib.characterPack) { if (lib.characterPack[itemx][item]) { - infoitem = lib.characterPack[itemx][item]; break; + infoitem = lib.characterPack[itemx][item]; + break; } } } node.node.name.innerHTML = get.slimName(item); - if (lib.config.buttoncharacter_style == 'default' || lib.config.buttoncharacter_style == 'simple') { - if (lib.config.buttoncharacter_style == 'simple') { - node.node.group.style.display = 'none'; + if ( + lib.config.buttoncharacter_style == "default" || + lib.config.buttoncharacter_style == "simple" + ) { + if (lib.config.buttoncharacter_style == "simple") { + node.node.group.style.display = "none"; } - node.classList.add('newstyle'); + node.classList.add("newstyle"); node.node.name.dataset.nature = get.groupnature(get.bordergroup(infoitem)); - node.node.group.dataset.nature = get.groupnature(get.bordergroup(infoitem), 'raw'); + node.node.group.dataset.nature = get.groupnature(get.bordergroup(infoitem), "raw"); ui.create.div(node.node.hp); - var hp = get.infoHp(infoitem[2]), maxHp = get.infoMaxHp(infoitem[2]), hujia = get.infoHujia(infoitem[2]); + var hp = get.infoHp(infoitem[2]), + maxHp = get.infoMaxHp(infoitem[2]), + hujia = get.infoHujia(infoitem[2]); var str = get.numStr(hp); if (hp != maxHp) { - str += '/'; + str += "/"; str += get.numStr(maxHp); } - var textnode = ui.create.div('.text', str, node.node.hp); + var textnode = ui.create.div(".text", str, node.node.hp); if (infoitem[2] == 0) { node.node.hp.hide(); - } - else if (get.infoHp(infoitem[2]) <= 3) { - node.node.hp.dataset.condition = 'mid'; - } - else { - node.node.hp.dataset.condition = 'high'; + } else if (get.infoHp(infoitem[2]) <= 3) { + node.node.hp.dataset.condition = "mid"; + } else { + node.node.hp.dataset.condition = "high"; } if (hujia > 0) { - ui.create.div(node.node.hp, '.shield'); - ui.create.div('.text', get.numStr(hujia), node.node.hp); + ui.create.div(node.node.hp, ".shield"); + ui.create.div(".text", get.numStr(hujia), node.node.hp); } - } - else { + } else { var hp = get.infoHp(infoitem[2]); var maxHp = get.infoMaxHp(infoitem[2]); var shield = get.infoHujia(infoitem[2]); if (maxHp > 14) { - if (typeof infoitem[2] == 'string') node.node.hp.innerHTML = infoitem[2]; + if (typeof infoitem[2] == "string") node.node.hp.innerHTML = infoitem[2]; else node.node.hp.innerHTML = get.numStr(infoitem[2]); - node.node.hp.classList.add('text'); - } - else { + node.node.hp.classList.add("text"); + } else { for (var i = 0; i < maxHp; i++) { - var next = ui.create.div('', node.node.hp); - if (i >= hp) next.classList.add('exclude'); + var next = ui.create.div("", node.node.hp); + if (i >= hp) next.classList.add("exclude"); } for (var i = 0; i < shield; i++) { - ui.create.div(node.node.hp, '.shield'); + ui.create.div(node.node.hp, ".shield"); } } } if (node.node.hp.childNodes.length == 0) { - node.node.name.style.top = '8px'; + node.node.name.style.top = "8px"; } - if (node.node.name.querySelectorAll('br').length >= 4) { - node.node.name.classList.add('long'); - if (lib.config.buttoncharacter_style == 'old') { - node.addEventListener('mouseenter', ui.click.buttonnameenter); - node.addEventListener('mouseleave', ui.click.buttonnameleave); + if (node.node.name.querySelectorAll("br").length >= 4) { + node.node.name.classList.add("long"); + if (lib.config.buttoncharacter_style == "old") { + node.addEventListener("mouseenter", ui.click.buttonnameenter); + node.addEventListener("mouseleave", ui.click.buttonnameleave); } } node.node.intro.innerHTML = lib.config.intro; @@ -2760,23 +2881,30 @@ export class Create extends Uninstantable { } if (infoitem[1]) { if (double) { - node.node.group.innerHTML = double.reduce((previousValue, currentValue) => `${previousValue}
                                      ${get.translation(currentValue)}
                                      `, ''); - if (double.length > 4) if (new Set([5, 6, 9]).has(double.length)) node.node.group.style.height = '48px'; - else node.node.group.style.height = '64px'; - } - else node.node.group.innerHTML = `
                                      ${get.translation(infoitem[1])}
                                      `; - node.node.group.style.backgroundColor = get.translation(`${get.bordergroup(infoitem)}Color`); - } - else { - node.node.group.style.display = 'none'; + node.node.group.innerHTML = double.reduce( + (previousValue, currentValue) => + `${previousValue}
                                      ${get.translation(currentValue)}
                                      `, + "" + ); + if (double.length > 4) + if (new Set([5, 6, 9]).has(double.length)) node.node.group.style.height = "48px"; + else node.node.group.style.height = "64px"; + } else node.node.group.innerHTML = `
                                      ${get.translation(infoitem[1])}
                                      `; + node.node.group.style.backgroundColor = get.translation( + `${get.bordergroup(infoitem)}Color` + ); + } else { + node.node.group.style.display = "none"; } if (node._replaceButton) { - var intro = ui.create.div('.button.replaceButton', node); - intro[lib.experimental.symbol.itemType] = 'button'; + var intro = ui.create.div(".button.replaceButton", node); + intro[lib.experimental.symbol.itemType] = "button"; node.node.replaceButton = intro; - intro.innerHTML = '切换'; + intro.innerHTML = "切换"; intro._node = node; - intro.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function () { + intro.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { _status.tempNoButton = true; var node = this._node; var list = lib.characterReplace[node._link]; @@ -2809,38 +2937,37 @@ export class Create extends Uninstantable { */ player: (item, type, position, noclick, node) => { if (node) { - node.classList.add('button'); - node.classList.add('character'); - node.style.display = ''; - } - else { - node = ui.create.div('.button.character', position); + node.classList.add("button"); + node.classList.add("character"); + node.style.display = ""; + } else { + node = ui.create.div(".button.character", position); } node._link = item; node.link = item; node.node = { - name: ui.create.div('.name', node), - intro: ui.create.div('.intro', node) + name: ui.create.div(".name", node), + intro: ui.create.div(".intro", node), }; - if (item.name && item.name.startsWith('unknown')) { + if (item.name && item.name.startsWith("unknown")) { if (item.node && item.node.name_seat) { - node.classList.add('cardbg'); - ui.create.div('.avatar_name', node, get.translation(item.name)); + node.classList.add("cardbg"); + ui.create.div(".avatar_name", node, get.translation(item.name)); + } else { + node.setBackground(item.name1, "character"); } - else { - node.setBackground(item.name1, 'character'); - } - } - else { - node.setBackground(item.name, 'character'); + } else { + node.setBackground(item.name, "character"); } return node; - } + }, }; - static button(item, type, position, noClick, button) { return new lib.element.Button(item, type, position, noClick, button); } - static buttons(list, type, position, noclick, zoom) { + button(item, type, position, noClick, button) { + return new lib.element.Button(item, type, position, noClick, button); + } + buttons(list, type, position, noclick, zoom) { var buttons = []; - var pre = (typeof type == 'string' && type.slice(0, 3) == 'pre'); + var pre = typeof type == "string" && type.slice(0, 3) == "pre"; if (pre) { if (!_status.prebutton) { _status.prebutton = []; @@ -2858,35 +2985,39 @@ export class Create extends Uninstantable { for (var i = 0; i < list.length; i++) { if (pre) { buttons.push(ui.create.prebutton(list[i], type.slice(3), fragment, noclick)); - } - else { + } else { buttons.push(ui.create.button(list[i], type, fragment, noclick)); } } if (position) position.appendChild(fragment); return buttons; } - static textbuttons(list, dialog, noclick) { + textbuttons(list, dialog, noclick) { for (var item of list) { var str, link; if (Array.isArray(item)) { str = item[1]; link = item[0]; - } - else { + } else { str = item; link = item; } - if (!str.startsWith(''; + if (!str.startsWith(""; var next = dialog.add(str); - if (!noclick) next.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', ui.click.button); + if (!noclick) + next.firstChild.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + ui.click.button + ); next.firstChild.link = link; Object.setPrototypeOf(next, lib.element.Button.prototype); dialog.buttons.add(next.firstChild); } } - static player(position, noclick) { return new lib.element.Player(position).build(noclick); } - static connectPlayers(ip) { + player(position, noclick) { + return new lib.element.Player(position).build(noclick); + } + connectPlayers(ip) { ui.updateConnectPlayerPositions(); game.connectPlayers = []; const configOL = lib.configOL; @@ -2894,91 +3025,108 @@ export class Create extends Uninstantable { for (let position = 0; position < numberOfPlayers; position++) { const player = ui.create.player(ui.window); player.dataset.position = position; - player.classList.add('connect'); + player.classList.add("connect"); game.connectPlayers.push(player); } var bar = ui.create.div(ui.window); - bar.style.height = '20px'; - bar.style.width = '80%'; - bar.style.left = '10%'; - bar.style.top = 'calc(200% / 7 - 120px + 5px)'; - bar.style.textAlign = 'center'; - var ipbar = ui.create.div('.shadowed', ip, bar); - ipbar.style.padding = '4px'; - ipbar.style.borderRadius = '2px'; - ipbar.style.position = 'relative'; + bar.style.height = "20px"; + bar.style.width = "80%"; + bar.style.left = "10%"; + bar.style.top = "calc(200% / 7 - 120px + 5px)"; + bar.style.textAlign = "center"; + var ipbar = ui.create.div(".shadowed", ip, bar); + ipbar.style.padding = "4px"; + ipbar.style.borderRadius = "2px"; + ipbar.style.position = "relative"; - var button = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton1.pointerdiv', game.online ? '退出联机' : '开始游戏', ui.window, function () { - if (button.clicked) return; - if (game.online) { - if (game.onlinezhu) { - game.send('startGame'); - } - else { - game.saveConfig('tmp_owner_roomId'); - game.saveConfig('tmp_user_roomId'); - game.saveConfig('reconnect_info'); - game.reload(); + var button = ui.create.div( + ".menubutton.large.highlight.connectbutton.connectbutton1.pointerdiv", + game.online ? "退出联机" : "开始游戏", + ui.window, + function () { + if (button.clicked) return; + if (game.online) { + if (game.onlinezhu) { + game.send("startGame"); + } else { + game.saveConfig("tmp_owner_roomId"); + game.saveConfig("tmp_user_roomId"); + game.saveConfig("reconnect_info"); + game.reload(); + } + } else { + var num = 0; + for (var i of game.connectPlayers) { + if (!i.nickname && !i.classList.contains("unselectable2")) num++; + } + if (num >= lib.configOL.number - 1) { + alert("至少要有两名玩家才能开始游戏!"); + return; + } + game.resume(); } + button.delete(); + bar.delete(); + shareButton.delete(); + delete ui.connectStartButton; + delete ui.connectStartBar; + delete ui.connectShareButton; + button.clicked = true; } - else { - var num = 0; - for (var i of game.connectPlayers) { - if (!i.nickname && !i.classList.contains('unselectable2')) num++; - } - if (num >= lib.configOL.number - 1) { - alert('至少要有两名玩家才能开始游戏!'); - return; - } - game.resume(); - } - button.delete(); - bar.delete(); - shareButton.delete(); - delete ui.connectStartButton; - delete ui.connectStartBar; - delete ui.connectShareButton; - button.clicked = true; - }); + ); - var shareButton = ui.create.div('.menubutton.large.highlight.connectbutton.connectbutton2.pointerdiv', '分享房间', ui.window, function () { - var text = `无名杀-联机-${lib.translate[get.mode()]}-${game.connectPlayers.filter(p => p.avatar).length}/${game.connectPlayers.filter(p => !p.classList.contains('unselectable2')).length}\n${get.connectNickname()}邀请你加入${game.roomId}房间\n联机地址:${game.ip}\n请先通过游戏内菜单-开始-联机中启用“读取邀请链接”选项`; - window.focus(); - if (navigator.clipboard && lib.node) { - navigator.clipboard.writeText(text).then(() => { - game.alert(`分享内容复制成功`); - }).catch(e => { - game.alert(`分享内容复制失败${e || ''}`); - }); - } else { - var input = ui.create.node('textarea', ui.window, { opacity: '0' }); - input.value = text; - input.focus(); - input.select(); - var result = document.execCommand('copy'); - input.blur(); - ui.window.removeChild(input); - game.alert(`分享内容复制${result ? '成功' : '失败'}`); + var shareButton = ui.create.div( + ".menubutton.large.highlight.connectbutton.connectbutton2.pointerdiv", + "分享房间", + ui.window, + function () { + var text = `无名杀-联机-${lib.translate[get.mode()]}-${ + game.connectPlayers.filter((p) => p.avatar).length + }/${ + game.connectPlayers.filter((p) => !p.classList.contains("unselectable2")).length + }\n${get.connectNickname()}邀请你加入${game.roomId}房间\n联机地址:${ + game.ip + }\n请先通过游戏内菜单-开始-联机中启用“读取邀请链接”选项`; + window.focus(); + if (navigator.clipboard && lib.node) { + navigator.clipboard + .writeText(text) + .then(() => { + game.alert(`分享内容复制成功`); + }) + .catch((e) => { + game.alert(`分享内容复制失败${e || ""}`); + }); + } else { + var input = ui.create.node("textarea", ui.window, { opacity: "0" }); + input.value = text; + input.focus(); + input.select(); + var result = document.execCommand("copy"); + input.blur(); + ui.window.removeChild(input); + game.alert(`分享内容复制${result ? "成功" : "失败"}`); + } } - }); + ); ui.connectStartButton = button; ui.connectStartBar = bar; ui.connectShareButton = shareButton; } - static players(numberOfPlayers) { + players(numberOfPlayers) { if (numberOfPlayers === 0) { return; } if (numberOfPlayers == undefined) numberOfPlayers = lib.configOL.number; if (numberOfPlayers == undefined) numberOfPlayers = get.playerNumber(); - if (typeof numberOfPlayers == 'string') { + if (typeof numberOfPlayers == "string") { numberOfPlayers = parseInt(numberOfPlayers); } if (!numberOfPlayers) numberOfPlayers = 5; for (let ordinal = 0; ordinal < numberOfPlayers; ordinal++) { - const player = ui.create.player().addTempClass('start'); + const player = ui.create.player().addTempClass("start"); game.players.push(player); player.dataset.position = ordinal; } @@ -2998,15 +3146,15 @@ export class Create extends Uninstantable { players[players.length - 1].next = players[0]; players[players.length - 1].nextSeat = players[0]; ui.arena.setNumber(numberOfPlayers); - players.forEach(player => ui.arena.appendChild(player)); + players.forEach((player) => ui.arena.appendChild(player)); return players; } - static me(hasme) { - ui.mebg = ui.create.div('#mebg', ui.arena); - ui.me = ui.create.div('#me', ui.arena).addTempClass('start'); - ui.handcards1Container = ui.create.div('#handcards1', ui.me); - ui.handcards2Container = ui.create.div('#handcards2', ui.me); - ui.arena.classList.remove('nome'); + me(hasme) { + ui.mebg = ui.create.div("#mebg", ui.arena); + ui.me = ui.create.div("#me", ui.arena).addTempClass("start"); + ui.handcards1Container = ui.create.div("#handcards1", ui.me); + ui.handcards2Container = ui.create.div("#handcards2", ui.me); + ui.arena.classList.remove("nome"); if (lib.config.mousewheel && !lib.config.touchscreen) { ui.handcards1Container.onmousewheel = ui.click.mousewheel; ui.handcards2Container.onmousewheel = ui.click.mousewheel; @@ -3015,8 +3163,8 @@ export class Create extends Uninstantable { ui.handcards2Container.ontouchstart = ui.click.touchStart; ui.handcards1Container.ontouchmove = ui.click.touchScroll; ui.handcards2Container.ontouchmove = ui.click.touchScroll; - ui.handcards1Container.style.webkitOverflowScrolling = 'touch'; - ui.handcards2Container.style.webkitOverflowScrolling = 'touch'; + ui.handcards1Container.style.webkitOverflowScrolling = "touch"; + ui.handcards2Container.style.webkitOverflowScrolling = "touch"; if (hasme && game.me) { ui.handcards1 = game.me.node.handcards1; @@ -3024,8 +3172,7 @@ export class Create extends Uninstantable { ui.handcards1Container.appendChild(ui.handcards1); ui.handcards2Container.appendChild(ui.handcards2); // ui.updatehl(); - } - else if (game.players.length) { + } else if (game.players.length) { game.me = game.players[0]; ui.handcards1 = game.me.node.handcards1; ui.handcards2 = game.me.node.handcards2; @@ -3034,8 +3181,10 @@ export class Create extends Uninstantable { // ui.updatehl(); } } - static card(position, info, noclick) { return new lib.element.Card(position).build(info, noclick); } - static cardsAsync() { + card(position, info, noclick) { + return new lib.element.Card(position).build(info, noclick); + } + cardsAsync() { if (lib.onfree) { _status.waitingForCards = Array.from(arguments); lib.onfree.push(function () { @@ -3044,12 +3193,11 @@ export class Create extends Uninstantable { delete _status.waitingForCards; } }); - } - else { + } else { ui.create.cards.apply(ui.create, arguments); } } - static cards(ordered) { + cards(ordered) { if (_status.brawl) { if (_status.brawl.cardPile) { lib.card.list = _status.brawl.cardPile(lib.card.list); @@ -3066,14 +3214,14 @@ export class Create extends Uninstantable { if (!lib.card.list[i]._replaced) { if (!_status.connectMode) { if (lib.config.bannedcards.includes(lib.card.list[i][2])) continue; - } - else { + } else { if (lib.configOL.bannedcards.includes(lib.card.list[i][2])) continue; } if (game.bannedcards && game.bannedcards.includes(lib.card.list[i][2])) continue; } lib.inpile.add(lib.card.list[i][2]); - if (lib.card.list[i][2] == 'sha' && lib.card.list[i][3]) lib.inpile_nature.add(lib.card.list[i][3]); + if (lib.card.list[i][2] == "sha" && lib.card.list[i][3]) + lib.inpile_nature.add(lib.card.list[i][3]); ui.create.card(ui.cardPile).init(lib.card.list[i]); } } @@ -3085,13 +3233,19 @@ export class Create extends Uninstantable { for (var i in _status.cardtag) { if (!_status.cardtag[i].length) delete _status.cardtag[i]; } - game.broadcastAll(function (num, pile, top, cardtag, inpile2) { - if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = '0轮 剩余牌: ' + num; - lib.inpile = pile; - _status.pileTop = top; - _status.cardtag = cardtag; - lib.inpile_nature = inpile2; - }, ui.cardPile.childNodes.length, lib.inpile, ui.cardPile.firstChild, _status.cardtag, lib.inpile_nature); + game.broadcastAll( + function (num, pile, top, cardtag, inpile2) { + if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = "0轮 剩余牌: " + num; + lib.inpile = pile; + _status.pileTop = top; + _status.cardtag = cardtag; + lib.inpile_nature = inpile2; + }, + ui.cardPile.childNodes.length, + lib.inpile, + ui.cardPile.firstChild, + _status.cardtag, + lib.inpile_nature + ); } - -} \ No newline at end of file +} diff --git a/noname/ui/create/menu/index.js b/noname/ui/create/menu/index.js index 4b9b2a79d..7c3cda7cc 100644 --- a/noname/ui/create/menu/index.js +++ b/noname/ui/create/menu/index.js @@ -1,12 +1,12 @@ import { ui, game, get, lib, _status } from "../../../../noname.js"; export function openMenu(node, e, onclose) { - popupContainer.innerHTML = ''; + popupContainer.innerHTML = ""; var left = Math.round(e.clientX / get.menuZoom()); var zoom = get.is.phoneLayout() ? 1.3 : 1; popupContainer.appendChild(node); // var rect=node.getBoundingClientRect(); - if (node.classList.contains('visual')) { + if (node.classList.contains("visual")) { // var num=node.querySelectorAll('.menu.visual>div').length; // node.style.top=(e.y-node.offsetHeight/2+30)+'px'; for (var i = 0; i < node.childElementCount; i++) { @@ -26,69 +26,78 @@ export function openMenu(node, e, onclose) { var idealtop = e.clientY / get.menuZoom(); if (idealtop < 10) { idealtop = 10; - } - else if ((idealtop + height) * zoom + 10 > ui.window.offsetHeight) { + } else if ((idealtop + height) * zoom + 10 > ui.window.offsetHeight) { idealtop = (ui.window.offsetHeight - 10) / zoom - height; } - node.style.top = idealtop + 'px'; - node.style.left = left + 'px'; + node.style.top = idealtop + "px"; + node.style.left = left + "px"; // } - popupContainer.classList.remove('hidden'); + popupContainer.classList.remove("hidden"); popupContainer.onclose = onclose; -}; +} export function clickToggle() { - if (this.classList.contains('disabled')) return; - this.classList.toggle('on'); + if (this.classList.contains("disabled")) return; + this.classList.toggle("on"); var config = this._link.config; if (config.onclick) { - if (config.onclick.call(this, this.classList.contains('on')) === false) { - this.classList.toggle('on'); + if (config.onclick.call(this, this.classList.contains("on")) === false) { + this.classList.toggle("on"); } } if (config.update) { config.update(); } -}; +} export function clickSwitcher() { - if (this.classList.contains('disabled')) return; + if (this.classList.contains("disabled")) return; var node = this; - this.classList.add('on'); + this.classList.add("on"); if (this._link.menu) { var pos1 = this.lastChild.getBoundingClientRect(); var pos2 = ui.window.getBoundingClientRect(); - if (this._link.menu.classList.contains('visual')) { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top - }, function () { - node.classList.remove('on'); - }); - } - else if (this._link.menu.childElementCount > 10) { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: Math.min((ui.window.offsetHeight - 400) / 2, pos1.top - pos2.top) - }, function () { - node.classList.remove('on'); - }); + if (this._link.menu.classList.contains("visual")) { + openMenu( + this._link.menu, + { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: pos1.top - pos2.top, + }, + function () { + node.classList.remove("on"); + } + ); + } else if (this._link.menu.childElementCount > 10) { + openMenu( + this._link.menu, + { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: Math.min((ui.window.offsetHeight - 400) / 2, pos1.top - pos2.top), + }, + function () { + node.classList.remove("on"); + } + ); lib.setScroll(this._link.menu); - } - else { - openMenu(this._link.menu, { - clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top - }, function () { - node.classList.remove('on'); - }); + } else { + openMenu( + this._link.menu, + { + clientX: pos1.left + pos1.width + 5 - pos2.left, + clientY: pos1.top - pos2.top, + }, + function () { + node.classList.remove("on"); + } + ); } } -}; +} /** * @this { HTMLDivElement } menuContainer */ export function clickContainer(connectMenu) { - this.classList.add('hidden'); + this.classList.add("hidden"); if (connectMenu) { if (_status.enteringroom) { _status.enteringroom = false; @@ -96,19 +105,18 @@ export function clickContainer(connectMenu) { if (_status.creatingroom) { _status.creatingroom = false; } - ui.window.classList.remove('shortcutpaused'); - } - else { + ui.window.classList.remove("shortcutpaused"); + } else { game.resume2(); if (game.onresume2) { game.onresume2(); } - ui.arena.classList.remove('menupaused'); - ui.historybar.classList.remove('menupaused'); - ui.window.classList.remove('touchinfohidden'); - ui.config2.classList.remove('pressdown2'); + ui.arena.classList.remove("menupaused"); + ui.historybar.classList.remove("menupaused"); + ui.window.classList.remove("touchinfohidden"); + ui.config2.classList.remove("pressdown2"); } -}; +} export function clickMenuItem() { var node = this.parentNode._link; var config = node._link.config; @@ -123,37 +131,41 @@ export function clickMenuItem() { if (config.update) { config.update(); } -}; +} export function createMenu(connectMenu, tabs, config) { var createPage = function (position) { var node = ui.create.div(position); - lib.setScroll(ui.create.div('.left.pane', node)); - lib.setScroll(ui.create.div('.right.pane', node)); + lib.setScroll(ui.create.div(".left.pane", node)); + lib.setScroll(ui.create.div(".right.pane", node)); return node; }; - var menu = ui.create.div('.main.menu.dialog.popped.static', config.position, function (e) { + var menu = ui.create.div(".main.menu.dialog.popped.static", config.position, function (e) { e.stopPropagation(); }); if (connectMenu) { - menu.classList.add('center'); - menuContainer.classList.add('centermenu'); + menu.classList.add("center"); + menuContainer.classList.add("centermenu"); } - var menuTab = ui.create.div('.menu-tab', menu); - var menuTabBar = ui.create.div('.menu-tab-bar', menu); - menuTabBar.style.left = (config.bar || 0) + 'px'; + var menuTab = ui.create.div(".menu-tab", menu); + var menuTabBar = ui.create.div(".menu-tab-bar", menu); + menuTabBar.style.left = (config.bar || 0) + "px"; if (Math.round(2 * get.menuZoom()) < 2) { - menuTabBar.style.height = '3px'; + menuTabBar.style.height = "3px"; } - var menuContent = ui.create.div('.menu-content', menu); + var menuContent = ui.create.div(".menu-content", menu); var clickTab = function () { - if (this.classList.contains('disabled')) return; - var active = this.parentNode.querySelector('.active'); + if (this.classList.contains("disabled")) return; + var active = this.parentNode.querySelector(".active"); if (active) { - active.classList.remove('active'); + active.classList.remove("active"); active._link.remove(); } - this.classList.add('active'); - menuTabBar.style.transform = 'translateX(' + (this.getBoundingClientRect().left - this.parentNode.firstChild.getBoundingClientRect().left) / get.menuZoom() + 'px)'; + this.classList.add("active"); + menuTabBar.style.transform = + "translateX(" + + (this.getBoundingClientRect().left - this.parentNode.firstChild.getBoundingClientRect().left) / + get.menuZoom() + + "px)"; menuContent.appendChild(this._link); }; ui.click.menuTab = function (tab) { @@ -166,60 +178,58 @@ export function createMenu(connectMenu, tabs, config) { }; var pages = []; for (var i = 0; i < tabs.length; i++) { - var active = (i === (config.init || 0)); + var active = i === (config.init || 0); pages[i] = createPage(active ? menuContent : null); - ui.create.div(active ? '.active' : '', tabs[i], menuTab, clickTab)._link = pages[i]; + ui.create.div(active ? ".active" : "", tabs[i], menuTab, clickTab)._link = pages[i]; } return { menu: menu, - pages: pages + pages: pages, }; -}; +} export function createConfig(config, position) { - var node = ui.create.div('.config', config.name); + var node = ui.create.div(".config", config.name); node._link = { config: config }; if (!config.clear) { - if (config.name != '开启') { - if (config.name == '屏蔽弱将') { - config.intro = '强度过低的武将(孙策除外)不会出现在选将框,也不会被AI选择'; - } - else if (config.name == '屏蔽强将') { - config.intro = '强度过高的武将不会出现在选将框,也不会被AI选择'; - } - else if (!config.intro) { - config.intro = '设置' + config.name; + if (config.name != "开启") { + if (config.name == "屏蔽弱将") { + config.intro = "强度过低的武将(孙策除外)不会出现在选将框,也不会被AI选择"; + } else if (config.name == "屏蔽强将") { + config.intro = "强度过高的武将不会出现在选将框,也不会被AI选择"; + } else if (!config.intro) { + config.intro = "设置" + config.name; } lib.setIntro(node, function (uiintro) { if (lib.config.touchscreen) _status.dragged = true; - uiintro.style.width = '170px'; + uiintro.style.width = "170px"; var str = config.intro; - if (typeof str == 'function') { + if (typeof str == "function") { str = str(); } - uiintro._place_text = uiintro.add('
                                      ' + str + '
                                      '); + uiintro._place_text = uiintro.add( + '
                                      ' + str + "
                                      " + ); }); } - } - else { - node.innerHTML = '' + config.name + ''; + } else { + node.innerHTML = "" + config.name + ""; if (!config.nopointer) { - node.classList.add('pointerspan'); + node.classList.add("pointerspan"); } } if (config.item) { - if (typeof config.item == 'function') { + if (typeof config.item == "function") { config.item = config.item(); } if (Array.isArray(config.init)) { void 0; - } - else { - node.classList.add('switcher'); + } else { + node.classList.add("switcher"); node.listen(clickSwitcher); - node._link.choosing = ui.create.div('', config.item[config.init], node); - node._link.menu = ui.create.div('.menu'); + node._link.choosing = ui.create.div("", config.item[config.init], node); + node._link.menu = ui.create.div(".menu"); if (config.visualMenu) { - node._link.menu.classList.add('visual'); + node._link.menu.classList.add("visual"); var updateVisual = function () { config.visualMenu(this, this._link, config.item[this._link], config); }; @@ -228,15 +238,13 @@ export function createConfig(config, position) { if (config.visualBar) { if (before) { node._link.menu.insertBefore(visualMenu, before); - } - else { + } else { node._link.menu.insertBefore(visualMenu, node._link.menu.lastChild); } - } - else { + } else { node._link.menu.appendChild(visualMenu); } - ui.create.div('.name', get.verticalStr(config.item[i]), visualMenu); + ui.create.div(".name", get.verticalStr(config.item[i]), visualMenu); visualMenu._link = i; if (config.visualMenu(visualMenu, i, config.item[i], config) !== false) { visualMenu.listen(clickMenuItem); @@ -247,7 +255,7 @@ export function createConfig(config, position) { var visualBar = ui.create.div(node._link.menu, function () { this.parentNode.parentNode.noclose = true; }); - node._link.menu.classList.add('withbar'); + node._link.menu.classList.add("withbar"); config.visualBar(visualBar, config.item, createNode, node); visualBar.update = function () { config.visualBar(visualBar, config.item, createNode, node); @@ -258,7 +266,7 @@ export function createConfig(config, position) { } lib.setScroll(node._link.menu); node._link.menu.updateBr = function () { - var br = Array.from(this.querySelectorAll('.menu.visual>br')); + var br = Array.from(this.querySelectorAll(".menu.visual>br")); while (br.length) { br.shift().remove(); } @@ -269,14 +277,13 @@ export function createConfig(config, position) { } } for (var i = 0; i < split.length; i++) { - this.insertBefore(ui.create.node('br'), split[i]); + this.insertBefore(ui.create.node("br"), split[i]); } }; node._link.menu.updateBr(); - } - else { + } else { for (var i in config.item) { - var textMenu = ui.create.div('', config.item[i], node._link.menu, clickMenuItem); + var textMenu = ui.create.div("", config.item[i], node._link.menu, clickMenuItem); textMenu._link = i; if (config.textMenu) { config.textMenu(textMenu, i, config.item[i], config); @@ -287,25 +294,22 @@ export function createConfig(config, position) { node._link.menu._link = node; node._link.current = config.init; } - } - else if (config.range) { + } else if (config.range) { void 0; - } - else if (config.clear) { - if (node.innerHTML.length >= 15) node.style.height = 'auto'; + } else if (config.clear) { + if (node.innerHTML.length >= 15) node.style.height = "auto"; node.listen(clickToggle); - } - else if (config.input) { - node.classList.add('switcher'); + } else if (config.input) { + node.classList.add("switcher"); var input = ui.create.div(node); if (!config.fixed) { input.contentEditable = true; - input.style.webkitUserSelect = 'text'; + input.style.webkitUserSelect = "text"; } - input.style.minWidth = '10px'; - input.style.maxWidth = '60%'; - input.style.overflow = 'hidden'; - input.style.whiteSpace = 'nowrap'; + input.style.minWidth = "10px"; + input.style.maxWidth = "60%"; + input.style.overflow = "hidden"; + input.style.whiteSpace = "nowrap"; input.onkeydown = function (e) { if (e.keyCode == 13) { e.preventDefault(); @@ -313,57 +317,54 @@ export function createConfig(config, position) { input.blur(); } }; - if (config.name == '联机昵称') { - input.innerHTML = config.init || '无名玩家'; + if (config.name == "联机昵称") { + input.innerHTML = config.init || "无名玩家"; input.onblur = function () { - input.innerHTML = input.innerHTML.replace(/
                                      /g, ''); + input.innerHTML = input.innerHTML.replace(/
                                      /g, ""); if (!input.innerHTML || get.is.banWords(input.innerHTML)) { - input.innerHTML = '无名玩家'; + input.innerHTML = "无名玩家"; } input.innerHTML = input.innerHTML.slice(0, 12); - game.saveConfig('connect_nickname', input.innerHTML); - game.saveConfig('connect_nickname', input.innerHTML, 'connect'); + game.saveConfig("connect_nickname", input.innerHTML); + game.saveConfig("connect_nickname", input.innerHTML, "connect"); }; - } - else if (config.name == '联机大厅') { + } else if (config.name == "联机大厅") { input.innerHTML = config.init || lib.hallURL; input.onblur = function () { if (!input.innerHTML) { input.innerHTML = lib.hallURL; } - input.innerHTML = input.innerHTML.replace(/
                                      /g, ''); - game.saveConfig('hall_ip', input.innerHTML, 'connect'); + input.innerHTML = input.innerHTML.replace(/
                                      /g, ""); + game.saveConfig("hall_ip", input.innerHTML, "connect"); }; - } - else { + } else { input.innerHTML = config.init; input.onblur = config.onblur; } - } - else { - node.classList.add('toggle'); + } else { + node.classList.add("toggle"); node.listen(clickToggle); ui.create.div(ui.create.div(node)); if (config.init == true) { - node.classList.add('on'); + node.classList.add("on"); } } if (position) { position.appendChild(node); } return node; -}; +} -/** +/** * @type { HTMLDivElement } - * - * 也是一个全屏div,但它的子元素是菜单栏 + * + * 也是一个全屏div,但它的子元素是菜单栏 */ export let menuContainer; -/** +/** * @type { HTMLDivElement } - * + * * 一个全屏div */ export let popupContainer; @@ -374,7 +375,7 @@ export let popupContainer; export let updateActive; /** - * @param { Function } fun + * @param { Function } fun */ export function setUpdateActive(fun) { updateActive = fun; @@ -386,7 +387,7 @@ export function setUpdateActive(fun) { export let updateActiveCard; /** - * @param { Function } fun + * @param { Function } fun */ export function setUpdateActiveCard(fun) { updateActiveCard = fun; @@ -408,7 +409,7 @@ export let menuxpages; export const menuUpdates = []; /** - * @param { boolean } [connectMenu] + * @param { boolean } [connectMenu] */ export function menu(connectMenu) { /** 提示重启的计时器 */ @@ -422,78 +423,81 @@ export function menu(connectMenu) { /** * 由于联机模式会创建第二个菜单,所以需要缓存一下可变的变量 */ - const cacheMenuContainer = menuContainer = ui.create.div('.menu-container.hidden', ui.window, () => { + const cacheMenuContainer = (menuContainer = ui.create.div(".menu-container.hidden", ui.window, () => { clickContainer.call(cacheMenuContainer, connectMenu); - }) - const cachePopupContainer = popupContainer = ui.create.div('.popup-container.hidden', ui.window, function closeMenu() { - // @ts-ignore - if (cachePopupContainer.noclose) { + })); + const cachePopupContainer = (popupContainer = ui.create.div( + ".popup-container.hidden", + ui.window, + function closeMenu() { // @ts-ignore - cachePopupContainer.noclose = false; - return; + if (cachePopupContainer.noclose) { + // @ts-ignore + cachePopupContainer.noclose = false; + return; + } + cachePopupContainer.classList.add("hidden"); + if (typeof cachePopupContainer.onclose == "function") { + // @ts-ignore + cachePopupContainer.onclose(); + } } - cachePopupContainer.classList.add('hidden'); - if (typeof cachePopupContainer.onclose == 'function') { - // @ts-ignore - cachePopupContainer.onclose(); - } - }); + )); if (!connectMenu) { ui.menuContainer = cacheMenuContainer; ui.click.configMenu = function () { ui.click.shortcut(false); - if (cacheMenuContainer.classList.contains('hidden')) { - ui.config2.classList.add('pressdown2'); - ui.arena.classList.add('menupaused'); - ui.historybar.classList.add('menupaused'); - ui.window.classList.add('touchinfohidden'); - cacheMenuContainer.classList.remove('hidden'); + if (cacheMenuContainer.classList.contains("hidden")) { + ui.config2.classList.add("pressdown2"); + ui.arena.classList.add("menupaused"); + ui.historybar.classList.add("menupaused"); + ui.window.classList.add("touchinfohidden"); + cacheMenuContainer.classList.remove("hidden"); for (var i = 0; i < menuUpdates.length; i++) { menuUpdates[i](); } - } - else { + } else { clickContainer.call(cacheMenuContainer, connectMenu); } }; - menux = createMenu(connectMenu, ['开始', '选项', '武将', '卡牌', '扩展', '其它'], { - position: cacheMenuContainer, bar: 40 + menux = createMenu(connectMenu, ["开始", "选项", "武将", "卡牌", "扩展", "其它"], { + position: cacheMenuContainer, + bar: 40, }); - } - else { + } else { ui.connectMenuContainer = cacheMenuContainer; ui.click.connectMenu = function () { - if (cacheMenuContainer.classList.contains('hidden')) { + if (cacheMenuContainer.classList.contains("hidden")) { if (_status.waitingForPlayer) { - startButton.innerHTML = '设'; + startButton.innerHTML = "设"; var start = cacheMenux.pages[0].firstChild; for (var i = 0; i < start.childNodes.length; i++) { if (start.childNodes[i].mode != lib.configOL.mode) { - start.childNodes[i].classList.add('unselectable'); - start.childNodes[i].classList.remove('active'); + start.childNodes[i].classList.add("unselectable"); + start.childNodes[i].classList.remove("active"); if (start.childNodes[i].link) start.childNodes[i].link.remove(); - } - else { - start.childNodes[i].classList.add('active'); - if (start.childNodes[i].link) start.nextSibling.appendChild(start.childNodes[i].link); + } else { + start.childNodes[i].classList.add("active"); + if (start.childNodes[i].link) + start.nextSibling.appendChild(start.childNodes[i].link); else console.log(start.nextSibling, start.childNodes[i]); } } } - ui.window.classList.add('shortcutpaused'); - cacheMenuContainer.classList.remove('hidden'); + ui.window.classList.add("shortcutpaused"); + cacheMenuContainer.classList.remove("hidden"); for (var i = 0; i < menuUpdates.length; i++) { menuUpdates[i](); } - } - else { + } else { clickContainer.call(cacheMenuContainer, connectMenu); } }; - menux = createMenu(connectMenu, ['模式', '武将', '卡牌'], { - position: cacheMenuContainer, bar: 123 + menux = createMenu(connectMenu, ["模式", "武将", "卡牌"], { + position: cacheMenuContainer, + bar: 123, }); // menu = menux.menu; let cacheMenux = menux; @@ -518,11 +522,11 @@ export function menu(connectMenu) { ui.create.extensionMenu(connectMenu); // 其他 - ui.create.otherMenu(connectMenu); + ui.create.otherMenu(connectMenu); if (menuTimeout) { clearTimeout(menuTimeout); delete window.resetExtension; - localStorage.removeItem(lib.configprefix + 'disable_extension', true); + localStorage.removeItem(lib.configprefix + "disable_extension", true); } -} \ No newline at end of file +} diff --git a/noname/ui/create/menu/pages/cardPackMenu.js b/noname/ui/create/menu/pages/cardPackMenu.js index dc6b3fd7d..f812dca68 100644 --- a/noname/ui/create/menu/pages/cardPackMenu.js +++ b/noname/ui/create/menu/pages/cardPackMenu.js @@ -14,7 +14,7 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig + createConfig, } from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; @@ -32,23 +32,23 @@ export const cardPackMenu = function (connectMenu) { var rightPane = start.lastChild; var pileCreated = false; var recreatePile = function () { - lib.config.customcardpile['当前牌堆'] = [lib.config.bannedpile, lib.config.addedpile]; - game.saveConfig('customcardpile', lib.config.customcardpile); - game.saveConfig('cardpilename', '当前牌堆', true); + lib.config.customcardpile["当前牌堆"] = [lib.config.bannedpile, lib.config.addedpile]; + game.saveConfig("customcardpile", lib.config.customcardpile); + game.saveConfig("cardpilename", "当前牌堆", true); pileCreated = false; }; var clickMode = function () { - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active === this) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); active = this; - this.classList.add('active'); + this.classList.add("active"); updateActiveCard(this); - if (this.mode == 'cardpile') { + if (this.mode == "cardpile") { this.create(); } if (this.link) rightPane.appendChild(this.link); @@ -59,7 +59,7 @@ export const cardPackMenu = function (connectMenu) { }; setUpdateActiveCard(function (node) { if (!node) { - node = start.firstChild.querySelector('.active'); + node = start.firstChild.querySelector(".active"); if (!node) { return; } @@ -75,42 +75,38 @@ export const cardPackMenu = function (connectMenu) { for (var i = 0; i < start.firstChild.childNodes.length; i++) { var node = start.firstChild.childNodes[i]; if (node.mode) { - if (node.mode.startsWith('mode_')) { + if (node.mode.startsWith("mode_")) { // 扩展卡牌包开启逻辑 - if (node.mode.startsWith('mode_extension')) { + if (node.mode.startsWith("mode_extension")) { const extName = node.mode.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) continue; if (lib.config[`extension_${extName}_cards_enable`] == true) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } } continue; } - if (node.mode == 'custom') continue; - if (node.mode == 'cardpile') continue; + if (node.mode == "custom") continue; + if (node.mode == "cardpile") continue; if (connectMenu) { if (!lib.config.connect_cards.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { + } else { if (lib.config.cards.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } } } @@ -119,30 +115,27 @@ export const cardPackMenu = function (connectMenu) { var togglePack = function (bool) { var name = this._link.config._name; // 扩展卡牌包开启逻辑 - if (name.startsWith('mode_extension')) { + if (name.startsWith("mode_extension")) { const extName = name.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; - game.saveExtensionConfig(extName, 'cards_enable', bool); + game.saveExtensionConfig(extName, "cards_enable", bool); } // 原逻辑 else { if (connectMenu) { if (!bool) { lib.config.connect_cards.add(name); - } - else { + } else { lib.config.connect_cards.remove(name); } - game.saveConfig('connect_cards', lib.config.connect_cards); - } - else { + game.saveConfig("connect_cards", lib.config.connect_cards); + } else { if (bool) { lib.config.cards.add(name); - } - else { + } else { lib.config.cards.remove(name); } - game.saveConfig('cards', lib.config.cards); + game.saveConfig("cards", lib.config.cards); } } updateNodes(); @@ -155,8 +148,7 @@ export const cardPackMenu = function (connectMenu) { } if (bool) { lib.config.bannedpile[name].remove(number); - } - else { + } else { lib.config.bannedpile[name].add(number); } recreatePile(); @@ -165,19 +157,26 @@ export const cardPackMenu = function (connectMenu) { var createModeConfig = function (mode, position) { var info = lib.cardPack[mode]; let cardPack = lib.cardPackInfo[mode]; - if (!lib.cardPile[mode] && cardPack && cardPack.list && Array.isArray(cardPack.list)) lib.cardPile[mode]=cardPack.list; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', lib.translate[mode + '_card_config'], position, clickMode); + if (!lib.cardPile[mode] && cardPack && cardPack.list && Array.isArray(cardPack.list)) + lib.cardPile[mode] = cardPack.list; + var page = ui.create.div(""); + var node = ui.create.div( + ".menubutton.large", + lib.translate[mode + "_card_config"], + position, + clickMode + ); if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); + node.classList.add("smallfont"); } node.mode = mode; node._initLink = function () { node.link = page; var list = []; for (var i = 0; i < info.length; i++) { - if (!lib.card[info[i]] || (lib.card[info[i]].derivation && mode != 'mode_derivation')) continue; - list.push([get.translation(get.type(info[i], 'trick')), '', info[i]]); + if (!lib.card[info[i]] || (lib.card[info[i]].derivation && mode != "mode_derivation")) + continue; + list.push([get.translation(get.type(info[i], "trick")), "", info[i]]); } var sortCard = function (card) { var type = lib.card[card[2]].type; @@ -189,72 +188,85 @@ export const cardPackMenu = function (connectMenu) { return lib.cardType[type]; } switch (type) { - case 'basic': return 0; - case 'chess': return 1.5; - case 'trick': return 2; - case 'delay': return 3; - case 'equip': { + case "basic": + return 0; + case "chess": + return 1.5; + case "trick": + return 2; + case "delay": + return 3; + case "equip": { switch (lib.card[card[2]].subtype) { - case 'equip1': return 4.1; - case 'equip2': return 4.2; - case 'equip3': return 4.3; - case 'equip4': return 4.4; - case 'equip5': return 4.5; - default: return 4; + case "equip1": + return 4.1; + case "equip2": + return 4.2; + case "equip3": + return 4.3; + case "equip4": + return 4.4; + case "equip5": + return 4.5; + default: + return 4; } } - case 'zhenfa': return 5; - default: return 6; + case "zhenfa": + return 5; + default: + return 6; } }; list.sort(function (a, b) { var sort1 = sortCard(a); var sort2 = sortCard(b); if (sort1 == sort2) { - return (b[2] < a[2]) ? 1 : -1; - } - else if (sort1 > sort2) { + return b[2] < a[2] ? 1 : -1; + } else if (sort1 > sort2) { return 1; - } - else { + } else { return -1; } }); var cfgnode = createConfig({ - name: '开启', + name: "开启", _name: mode, init: (() => { // 扩展卡牌包开启逻辑 - if (mode.startsWith('mode_extension')) { + if (mode.startsWith("mode_extension")) { const extName = mode.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; // 这块或许应该在加载扩展时候写 if (lib.config[`extension_${extName}_cards_enable`] === undefined) { - game.saveExtensionConfig(extName, 'cards_enable', true); + game.saveExtensionConfig(extName, "cards_enable", true); } return lib.config[`extension_${extName}_cards_enable`] === true; } // 原逻辑 else return lib.config.cards.includes(mode); })(), - onclick: togglePack + onclick: togglePack, }); - if (!mode.startsWith('mode_') || (cardPack && cardPack.closeable)) { + if (!mode.startsWith("mode_") || (cardPack && cardPack.closeable)) { page.appendChild(cfgnode); - } - else { - page.style.paddingTop = '8px'; + } else { + page.style.paddingTop = "8px"; } var banCard = function (e) { if (_status.clicked) { _status.clicked = false; return; } - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && mode != 'mode_banned') { + if ( + mode.startsWith("mode_") && + !mode.startsWith("mode_extension_") && + mode != "mode_banned" + ) { return; } ui.click.touchpop(); - this._banning = connectMenu ? 'online' : 'offline'; + this._banning = connectMenu ? "online" : "offline"; ui.click.intro.call(this, e); _status.clicked = false; delete this._banning; @@ -262,49 +274,46 @@ export const cardPackMenu = function (connectMenu) { var updateBanned = function () { var list; if (connectMenu) { - var mode = cacheMenux.pages[0].firstChild.querySelector('.active'); + var mode = cacheMenux.pages[0].firstChild.querySelector(".active"); if (mode && mode.mode) { - list = lib.config['connect_' + mode.mode + '_bannedcards']; + list = lib.config["connect_" + mode.mode + "_bannedcards"]; } - } - else { - list = lib.config[get.mode() + '_bannedcards']; + } else { + list = lib.config[get.mode() + "_bannedcards"]; } if (list && list.includes(this.link[2])) { - this.classList.add('banned'); - } - else { - this.classList.remove('banned'); + this.classList.add("banned"); + } else { + this.classList.remove("banned"); } }; - var buttons = ui.create.buttons(list, 'vcard', page); + var buttons = ui.create.buttons(list, "vcard", page); for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); + buttons[i].classList.add("noclick"); buttons[i].listen(banCard); - if (mode != 'mode_banned') { + if (mode != "mode_banned") { buttons[i].updateBanned = updateBanned; } } - page.classList.add('menu-buttons'); - page.classList.add('leftbutton'); - if (!connectMenu && !lib.config.all.sgscards.includes(mode) && !mode.startsWith('mode_')) { - ui.create.div('.config.pointerspan', '隐藏卡牌包', page, function () { - if (this.firstChild.innerHTML == '隐藏卡牌包') { - this.firstChild.innerHTML = '卡牌包将在重启后隐藏'; + page.classList.add("menu-buttons"); + page.classList.add("leftbutton"); + if (!connectMenu && !lib.config.all.sgscards.includes(mode) && !mode.startsWith("mode_")) { + ui.create.div(".config.pointerspan", "隐藏卡牌包", page, function () { + if (this.firstChild.innerHTML == "隐藏卡牌包") { + this.firstChild.innerHTML = "卡牌包将在重启后隐藏"; lib.config.hiddenCardPack.add(mode); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } - } - else { - this.firstChild.innerHTML = '隐藏卡牌包'; + } else { + this.firstChild.innerHTML = "隐藏卡牌包"; lib.config.hiddenCardPack.remove(mode); } - game.saveConfig('hiddenCardPack', lib.config.hiddenCardPack); + game.saveConfig("hiddenCardPack", lib.config.hiddenCardPack); }); } - if ((!mode.startsWith('mode_') || (cardPack && cardPack.closeable)) && lib.cardPile[mode]) { + if ((!mode.startsWith("mode_") || (cardPack && cardPack.closeable)) && lib.cardPile[mode]) { var cardpileNodes = []; var cardpileexpanded = false; if (!lib.config.bannedpile[mode]) { @@ -313,127 +322,136 @@ export const cardPackMenu = function (connectMenu) { if (!lib.config.addedpile[mode]) { lib.config.addedpile[mode] = []; } - ui.create.div('.config.more.pile', '编辑牌堆
                                      >
                                      ', page, function () { + ui.create.div(".config.more.pile", "编辑牌堆
                                      >
                                      ", page, function () { if (cardpileexpanded) { - this.classList.remove('on'); + this.classList.remove("on"); for (var k = 0; k < cardpileNodes.length; k++) { - cardpileNodes[k].style.display = 'none'; + cardpileNodes[k].style.display = "none"; } - } - else { - this.classList.add('on'); + } else { + this.classList.add("on"); for (var k = 0; k < cardpileNodes.length; k++) { - cardpileNodes[k].style.display = ''; + cardpileNodes[k].style.display = ""; } } cardpileexpanded = !cardpileexpanded; }); - var cfgnode = ui.create.div(page, '.config.pointerspan.cardpilecfg.toggle'); - var cfgaddcard = ui.create.node('button', '', '添加卡牌', cfgnode, function () { - this.parentNode.nextSibling.classList.toggle('hidden'); + var cfgnode = ui.create.div(page, ".config.pointerspan.cardpilecfg.toggle"); + var cfgaddcard = ui.create.node("button", "", "添加卡牌", cfgnode, function () { + this.parentNode.nextSibling.classList.toggle("hidden"); }); - var cfgbancard = ui.create.node('button', '', '全部关闭', cfgnode, function () { + var cfgbancard = ui.create.node("button", "", "全部关闭", cfgnode, function () { for (var i = 0; i < cardpileNodes.length; i++) { - if (cardpileNodes[i].type == 'defaultcards' && cardpileNodes[i].classList.contains('on')) { + if ( + cardpileNodes[i].type == "defaultcards" && + cardpileNodes[i].classList.contains("on") + ) { clickToggle.call(cardpileNodes[i]); } } }); - var cfgenablecard = ui.create.node('button', '', '全部开启', cfgnode, function () { + var cfgenablecard = ui.create.node("button", "", "全部开启", cfgnode, function () { for (var i = 0; i < cardpileNodes.length; i++) { - if (cardpileNodes[i].type == 'defaultcards' && !cardpileNodes[i].classList.contains('on')) { + if ( + cardpileNodes[i].type == "defaultcards" && + !cardpileNodes[i].classList.contains("on") + ) { clickToggle.call(cardpileNodes[i]); } } }); - cfgbancard.style.marginLeft = '5px'; - cfgenablecard.style.marginLeft = '5px'; + cfgbancard.style.marginLeft = "5px"; + cfgenablecard.style.marginLeft = "5px"; cardpileNodes.push(cfgnode); - cfgnode.style.display = 'none'; - cfgnode.classList.add('cardpilecfg'); - cfgnode.classList.add('toggle'); - cfgnode.style.marginTop = '5px'; + cfgnode.style.display = "none"; + cfgnode.classList.add("cardpilecfg"); + cfgnode.classList.add("toggle"); + cfgnode.style.marginTop = "5px"; page.appendChild(cfgnode); - var cardpileadd = ui.create.div('.config.toggle.hidden.cardpilecfg.cardpilecfgadd', page); + var cardpileadd = ui.create.div(".config.toggle.hidden.cardpilecfg.cardpilecfgadd", page); var pileaddlist = []; for (var i = 0; i < lib.config.cards.length; i++) { if (!lib.cardPack[lib.config.cards[i]]) continue; for (var j = 0; j < lib.cardPack[lib.config.cards[i]].length; j++) { var cname = lib.cardPack[lib.config.cards[i]][j]; pileaddlist.push([cname, get.translation(cname)]); - if (cname == 'sha') { - pileaddlist.push(['huosha', '火杀']); - pileaddlist.push(['leisha', '雷杀']); - pileaddlist.push(['icesha', '冰杀']); - pileaddlist.push(['cisha', '刺杀']); + if (cname == "sha") { + pileaddlist.push(["huosha", "火杀"]); + pileaddlist.push(["leisha", "雷杀"]); + pileaddlist.push(["icesha", "冰杀"]); + pileaddlist.push(["cisha", "刺杀"]); } } } var cardpileaddname = ui.create.selectlist(pileaddlist, null, cardpileadd); - cardpileaddname.style.width = '75px'; - cardpileaddname.style.marginRight = '2px'; - cardpileaddname.style.marginLeft = '-1px'; - var cardpileaddsuit = ui.create.selectlist([ - ['heart', '红桃'], - ['diamond', '方片'], - ['club', '梅花'], - ['spade', '黑桃'], - ], null, cardpileadd); - cardpileaddsuit.style.width = '53px'; - cardpileaddsuit.style.marginRight = '2px'; - var cardpileaddnumber = ui.create.selectlist([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 - ], null, cardpileadd); - cardpileaddnumber.style.width = '43px'; - cardpileaddnumber.style.marginRight = '2px'; - var button = document.createElement('button'); - button.innerHTML = '确定'; - button.style.width = '40px'; + cardpileaddname.style.width = "75px"; + cardpileaddname.style.marginRight = "2px"; + cardpileaddname.style.marginLeft = "-1px"; + var cardpileaddsuit = ui.create.selectlist( + [ + ["heart", "红桃"], + ["diamond", "方片"], + ["club", "梅花"], + ["spade", "黑桃"], + ], + null, + cardpileadd + ); + cardpileaddsuit.style.width = "53px"; + cardpileaddsuit.style.marginRight = "2px"; + var cardpileaddnumber = ui.create.selectlist( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + null, + cardpileadd + ); + cardpileaddnumber.style.width = "43px"; + cardpileaddnumber.style.marginRight = "2px"; + var button = document.createElement("button"); + button.innerHTML = "确定"; + button.style.width = "40px"; var deletecard = function () { this.parentNode.remove(); var info = this.parentNode._info; var list = lib.config.addedpile[mode]; for (var i = 0; i < list.length; i++) { if (list[i][0] == info[0] && list[i][1] == info[1] && list[i][2] == info[2]) { - list.splice(i, 1); break; + list.splice(i, 1); + break; } } recreatePile(); }; button.onclick = function () { - var card = [ - cardpileaddsuit.value, - cardpileaddnumber.value, - cardpileaddname.value, - ]; + var card = [cardpileaddsuit.value, cardpileaddnumber.value, cardpileaddname.value]; lib.config.addedpile[mode].push(card); recreatePile(); - var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); + var cfgnode = ui.create.div(".config.toggle.cardpilecfg"); cfgnode._info = card; - cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]); - var cfgnodedelete = document.createElement('span'); - cfgnodedelete.classList.add('cardpiledelete'); - cfgnodedelete.innerHTML = '删除'; + cfgnode.innerHTML = + get.translation(card[2]) + " " + get.translation(card[0]) + get.strNumber(card[1]); + var cfgnodedelete = document.createElement("span"); + cfgnodedelete.classList.add("cardpiledelete"); + cfgnodedelete.innerHTML = "删除"; cfgnodedelete.onclick = deletecard; cfgnode.appendChild(cfgnodedelete); page.insertBefore(cfgnode, cardpileadd.nextSibling); }; cardpileadd.appendChild(button); - cardpileadd.style.whiteSpace = 'nowrap'; + cardpileadd.style.whiteSpace = "nowrap"; cardpileNodes.push(cardpileadd); for (var i = 0; i < lib.config.addedpile[mode].length; i++) { var card = lib.config.addedpile[mode][i]; - var cfgnode = ui.create.div('.config.toggle.cardpilecfg'); + var cfgnode = ui.create.div(".config.toggle.cardpilecfg"); cfgnode._info = card; - cfgnode.innerHTML = get.translation(card[2]) + ' ' + get.translation(card[0]) + card[1]; - var cfgnodedelete = document.createElement('span'); - cfgnodedelete.classList.add('cardpiledelete'); - cfgnodedelete.innerHTML = '删除'; + cfgnode.innerHTML = get.translation(card[2]) + " " + get.translation(card[0]) + card[1]; + var cfgnodedelete = document.createElement("span"); + cfgnodedelete.classList.add("cardpiledelete"); + cfgnodedelete.innerHTML = "删除"; cfgnodedelete.onclick = deletecard; cfgnode.appendChild(cfgnodedelete); - cfgnode.style.display = 'none'; + cfgnode.style.display = "none"; cardpileNodes.push(cfgnode); page.appendChild(cfgnode); } @@ -441,37 +459,42 @@ export const cardPackMenu = function (connectMenu) { for (var i = 0; i < lib.cardPile[mode].length; i++) { var card = lib.cardPile[mode][i]; var cfgnode = createConfig({ - name: ((card[2] == 'sha' && card[3]) ? (get.translation(card[3])) : '') + get.translation(card[2]) + ' ' + get.translation(card[0]) + get.strNumber(card[1]), + name: + (card[2] == "sha" && card[3] ? get.translation(card[3]) : "") + + get.translation(card[2]) + + " " + + get.translation(card[0]) + + get.strNumber(card[1]), _number: i, _name: mode, init: !lib.config.bannedpile[mode].includes(i), - onclick: toggleCardPile + onclick: toggleCardPile, }); - cfgnode.type = 'defaultcards'; + cfgnode.type = "defaultcards"; cardpileNodes.push(cfgnode); - cfgnode.style.display = 'none'; - cfgnode.classList.add('cardpilecfg'); + cfgnode.style.display = "none"; + cfgnode.classList.add("cardpilecfg"); page.appendChild(cfgnode); } - ui.create.div('.menuplaceholder', page); + ui.create.div(".menuplaceholder", page); } }; - if (!get.config('menu_loadondemand')) node._initLink(); + if (!get.config("menu_loadondemand")) node._initLink(); return node; }; if (!connectMenu && lib.config.show_ban_menu) { lib.cardPack.mode_banned = []; for (var i = 0; i < lib.config.all.mode.length; i++) { - var banned = lib.config[lib.config.all.mode[i] + '_bannedcards']; + var banned = lib.config[lib.config.all.mode[i] + "_bannedcards"]; if (banned) { for (var j = 0; j < banned.length; j++) { lib.cardPack.mode_banned.add(banned[j]); } } } - var bannednode = createModeConfig('mode_banned', start.firstChild); + var bannednode = createModeConfig("mode_banned", start.firstChild); if (lib.cardPack.mode_banned.length == 0) { - bannednode.style.display = 'none'; + bannednode.style.display = "none"; } delete lib.cardPack.mode_banned; } @@ -479,17 +502,18 @@ export const cardPackMenu = function (connectMenu) { if (connectMenu && !lib.connectCardPack.includes(lib.config.all.cards[i])) continue; createModeConfig(lib.config.all.cards[i], start.firstChild); } - if (!connectMenu) Object.keys(lib.cardPack).forEach(key => { - if (!lib.config.all.cards.includes(key)) createModeConfig(key, start.firstChild); - if (connectMenu) lib.connectCardPack.add(key); - }); - var active = start.firstChild.querySelector('.active'); + if (!connectMenu) + Object.keys(lib.cardPack).forEach((key) => { + if (!lib.config.all.cards.includes(key)) createModeConfig(key, start.firstChild); + if (connectMenu) lib.connectCardPack.add(key); + }); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - if (active.style.display == 'none') { + if (active.style.display == "none") { active = active.nextSibling; } - active.classList.add('active'); + active.classList.add("active"); updateActiveCard(active); } if (!active.link) active._initLink(); @@ -497,73 +521,71 @@ export const cardPackMenu = function (connectMenu) { (function () { if (connectMenu) return; - var page = ui.create.div('.menu-buttons'); - var node = ui.create.div('.menubutton.large', '牌堆', clickMode); - start.firstChild.insertBefore(node, start.firstChild.querySelector('.lefttext')); + var page = ui.create.div(".menu-buttons"); + var node = ui.create.div(".menubutton.large", "牌堆", clickMode); + start.firstChild.insertBefore(node, start.firstChild.querySelector(".lefttext")); node.link = page; - node.mode = 'cardpile'; + node.mode = "cardpile"; node.create = function () { if (pileCreated) return; pileCreated = true; - page.innerHTML = ''; + page.innerHTML = ""; var pileList = null; var createList = function () { if (pileList) { pileList.remove(); } - var list = ['默认牌堆']; - if (lib.config.customcardpile['当前牌堆']) { - list.push('当前牌堆'); + var list = ["默认牌堆"]; + if (lib.config.customcardpile["当前牌堆"]) { + list.push("当前牌堆"); } for (var i in lib.config.customcardpile) { list.add(i); } - var currentpile = get.config('cardpilename'); + var currentpile = get.config("cardpilename"); if (!currentpile) { - if (list.includes('当前牌堆')) { - currentpile = '当前牌堆'; - } - else { - currentpile = '默认牌堆'; + if (list.includes("当前牌堆")) { + currentpile = "当前牌堆"; + } else { + currentpile = "默认牌堆"; } } pileList = ui.create.selectlist(list, currentpile, pileChoose, function (e) { - game.saveConfig('cardpilename', this.value, true); - restart.style.display = ''; + game.saveConfig("cardpilename", this.value, true); + restart.style.display = ""; }); - pileList.style.float = 'right'; + pileList.style.float = "right"; }; - var pileChoose = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', '选择牌堆', page); + var pileChoose = ui.create.div(".config.toggle.cardpilecfg.nomarginleft", "选择牌堆", page); createList(); var pileDel = function () { delete lib.config.customcardpile[this.parentNode.link]; this.parentNode.remove(); - game.saveConfig('customcardpile', lib.config.customcardpile); + game.saveConfig("customcardpile", lib.config.customcardpile); for (var i in lib.config.mode_config) { - if (i == 'global') continue; + if (i == "global") continue; if (lib.config.mode_config[i].cardpilename == this.parentNode.link) { - game.saveConfig('cardpilename', null, i); + game.saveConfig("cardpilename", null, i); } } createList(); }; - var restart = ui.create.div('.config.more', '重新启动', game.reload, page); - restart.style.display = 'none'; + var restart = ui.create.div(".config.more", "重新启动", game.reload, page); + restart.style.display = "none"; var createPileNode = function (name) { - var node = ui.create.div('.config.toggle.cardpilecfg.nomarginleft', name); + var node = ui.create.div(".config.toggle.cardpilecfg.nomarginleft", name); node.link = name; - var del = document.createElement('span'); - del.innerHTML = '删除'; - del.classList.add('cardpiledelete'); + var del = document.createElement("span"); + del.innerHTML = "删除"; + del.classList.add("cardpiledelete"); del.onclick = pileDel; node.appendChild(del); - if (name == '当前牌堆') { + if (name == "当前牌堆") { page.insertBefore(node, pileChoose.nextSibling); - } - else { + } else { page.insertBefore(node, restart); } }; @@ -571,84 +593,86 @@ export const cardPackMenu = function (connectMenu) { createPileNode(i); } var exportCardPile; - ui.create.div('.config.more', '保存当前牌堆
                                      >
                                      ', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - exportCardPile.classList.remove('hidden'); - } - else { - exportCardPile.classList.add('hidden'); + ui.create.div(".config.more", "保存当前牌堆
                                      >
                                      ", page, function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + exportCardPile.classList.remove("hidden"); + } else { + exportCardPile.classList.add("hidden"); } }); - exportCardPile = ui.create.div('.config.cardpileadd.indent', page); - exportCardPile.classList.add('hidden'); - ui.create.div('', '名称:', exportCardPile); + exportCardPile = ui.create.div(".config.cardpileadd.indent", page); + exportCardPile.classList.add("hidden"); + ui.create.div("", '名称:', exportCardPile); var input = exportCardPile.firstChild.lastChild.previousSibling; - input.value = '自定义牌堆'; - input.style.marginRight = '3px'; - input.style.width = '120px'; + input.value = "自定义牌堆"; + input.style.marginRight = "3px"; + input.style.width = "120px"; exportCardPile.firstChild.lastChild.onclick = function () { var name = input.value; var ok = true; - if (lib.config.customcardpile[name] || name == '默认牌堆' || name == '当前牌堆') { + if (lib.config.customcardpile[name] || name == "默认牌堆" || name == "当前牌堆") { for (var i = 1; i <= 1000; i++) { - if (!lib.config.customcardpile[name + '(' + i + ')']) { - name = name + '(' + i + ')'; + if (!lib.config.customcardpile[name + "(" + i + ")"]) { + name = name + "(" + i + ")"; break; } } } lib.config.customcardpile[name] = [lib.config.bannedpile, lib.config.addedpile]; - delete lib.config.customcardpile['当前牌堆']; + delete lib.config.customcardpile["当前牌堆"]; for (var i in lib.mode) { - if (lib.config.mode_config[i] && - (lib.config.mode_config[i].cardpilename == '当前牌堆' || !lib.config.mode_config[i].cardpilename)) { - game.saveConfig('cardpilename', name, i); + if ( + lib.config.mode_config[i] && + (lib.config.mode_config[i].cardpilename == "当前牌堆" || + !lib.config.mode_config[i].cardpilename) + ) { + game.saveConfig("cardpilename", name, i); } } for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].link == '当前牌堆') { + if (page.childNodes[i].link == "当前牌堆") { page.childNodes[i].remove(); break; } } - game.saveConfig('customcardpile', lib.config.customcardpile); + game.saveConfig("customcardpile", lib.config.customcardpile); createPileNode(name); createList(); }; }; - }()); + })(); if (!connectMenu) { // 下面使用了var的特性,请不要在这里直接改为let - var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { - game.saveConfig('cards', lib.config.all.cards); + var node1 = ui.create.div(".lefttext", "全部开启", start.firstChild, function () { + game.saveConfig("cards", lib.config.all.cards); updateNodes(); }); - var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { - game.saveConfig('cards', lib.config.defaultcards); + var node2 = ui.create.div(".lefttext", "恢复默认", start.firstChild, function () { + game.saveConfig("cards", lib.config.defaultcards); updateNodes(); }); - node1.style.marginTop = '12px'; - node2.style.marginTop = '7px'; + node1.style.marginTop = "12px"; + node2.style.marginTop = "7px"; } updateNodes(); /** * 在菜单栏初始化完成后,如果又加载了武将包,进行刷新 - * + * * @param { string } packName */ return function (packName) { // 判断菜单栏有没有加载过这个卡牌包 - if ([...start.firstChild.children].map(node => node.mode).includes(packName)) return; + if ([...start.firstChild.children].map((node) => node.mode).includes(packName)) return; // 显示不是无名杀自带的卡牌包 if (!lib.connectCardPack.includes(packName) && !lib.config.all.cards.includes(packName)) { - if (!(connectMenu && ['mode_derivation', 'mode_banned'].includes(packName))) { + if (!(connectMenu && ["mode_derivation", "mode_banned"].includes(packName))) { createModeConfig(packName, start.firstChild, node1); } if (connectMenu) lib.connectCardPack.add(packName); } - } + }; }; diff --git a/noname/ui/create/menu/pages/characterPackMenu.js b/noname/ui/create/menu/pages/characterPackMenu.js index defa64f95..a0e8d0c1a 100644 --- a/noname/ui/create/menu/pages/characterPackMenu.js +++ b/noname/ui/create/menu/pages/characterPackMenu.js @@ -14,7 +14,7 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig + createConfig, } from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; @@ -33,15 +33,15 @@ export const characterPackMenu = function (connectMenu) { var rightPane = start.lastChild; var clickMode = function () { - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active) { if (active === this) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); } - this.classList.add('active'); + this.classList.add("active"); updateActive(this); if (this.link) rightPane.appendChild(this.link); else { @@ -51,7 +51,7 @@ export const characterPackMenu = function (connectMenu) { }; setUpdateActive(function (node) { if (!node) { - node = start.firstChild.querySelector('.active'); + node = start.firstChild.querySelector(".active"); if (!node) { return; } @@ -69,41 +69,37 @@ export const characterPackMenu = function (connectMenu) { for (var i = 0; i < start.firstChild.childNodes.length; i++) { var node = start.firstChild.childNodes[i]; if (node.mode) { - if (node.mode.startsWith('mode_')) { + if (node.mode.startsWith("mode_")) { // 扩展武将包开启逻辑 - if (node.mode.startsWith('mode_extension')) { + if (node.mode.startsWith("mode_extension")) { const extName = node.mode.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) continue; if (lib.config[`extension_${extName}_characters_enable`] == true) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } } continue; } - if (node.mode == 'custom') continue; + if (node.mode == "custom") continue; if (connectMenu) { if (!lib.config.connect_characters.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { + } else { if (lib.config.characters.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } } } @@ -112,30 +108,27 @@ export const characterPackMenu = function (connectMenu) { var togglePack = function (bool) { var name = this._link.config._name; // 扩展武将包开启逻辑 - if (name.startsWith('mode_extension')) { + if (name.startsWith("mode_extension")) { const extName = name.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; - game.saveExtensionConfig(extName, 'characters_enable', bool); + game.saveExtensionConfig(extName, "characters_enable", bool); } // 原逻辑 else { if (connectMenu) { if (!bool) { lib.config.connect_characters.add(name); - } - else { + } else { lib.config.connect_characters.remove(name); } - game.saveConfig('connect_characters', lib.config.connect_characters); - } - else { + game.saveConfig("connect_characters", lib.config.connect_characters); + } else { if (bool) { lib.config.characters.add(name); - } - else { + } else { lib.config.characters.remove(name); } - game.saveConfig('characters', lib.config.characters); + game.saveConfig("characters", lib.config.characters); } } updateNodes(); @@ -143,10 +136,15 @@ export const characterPackMenu = function (connectMenu) { var createModeConfig = function (mode, position, position2) { var _info = lib.characterPack[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', lib.translate[mode + '_character_config'], position, clickMode); + var page = ui.create.div(""); + var node = ui.create.div( + ".menubutton.large", + lib.translate[mode + "_character_config"], + position, + clickMode + ); if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); + node.classList.add("smallfont"); } if (position2) { position.insertBefore(node, position2); @@ -161,7 +159,7 @@ export const characterPackMenu = function (connectMenu) { var alterableCharacters = []; var charactersToAlter = []; for (var i in _info) { - if (_info[i][4] && _info[i][4].includes('unseen')) continue; + if (_info[i][4] && _info[i][4].includes("unseen")) continue; if (connectMenu && lib.connectBanned.includes(i)) continue; list.push(i); if (boolAI && !lib.config.forbidai_user.includes(i)) boolAI = false; @@ -182,106 +180,111 @@ export const characterPackMenu = function (connectMenu) { list.sort(lib.sort.character); var list2 = list.slice(0); var cfgnode = createConfig({ - name: '开启', + name: "开启", _name: mode, init: (() => { // 扩展武将包开启逻辑 - if (mode.startsWith('mode_extension')) { + if (mode.startsWith("mode_extension")) { const extName = mode.slice(15); if (!game.hasExtension(extName) || !game.hasExtensionLoaded(extName)) return false; // 这块或许应该在加载扩展时候写 if (lib.config[`extension_${extName}_characters_enable`] === undefined) { - game.saveExtensionConfig(extName, 'characters_enable', true); + game.saveExtensionConfig(extName, "characters_enable", true); } return lib.config[`extension_${extName}_characters_enable`] === true; } // 原逻辑 else { - return connectMenu ? (!lib.config.connect_characters.includes(mode)) : (lib.config.characters.includes(mode)); + return connectMenu + ? !lib.config.connect_characters.includes(mode) + : lib.config.characters.includes(mode); } - })(), - onclick: togglePack + onclick: togglePack, }); var cfgnodeAI = createConfig({ - name: '仅点将可用', + name: "仅点将可用", _name: mode, init: boolAI, - intro: '将该武将包内的武将全部设置为仅点将可用', + intro: "将该武将包内的武将全部设置为仅点将可用", onclick(bool) { if (bool) { for (var i = 0; i < list.length; i++) { lib.config.forbidai_user.add(list[i]); } - } - else { + } else { for (var i = 0; i < list.length; i++) { lib.config.forbidai_user.remove(list[i]); } } - game.saveConfig('forbidai_user', lib.config.forbidai_user); + game.saveConfig("forbidai_user", lib.config.forbidai_user); }, }); - if (!mode.startsWith('mode_')) { - cfgnodeAI.style.marginTop = '0px'; + if (!mode.startsWith("mode_")) { + cfgnodeAI.style.marginTop = "0px"; page.appendChild(cfgnode); page.appendChild(cfgnodeAI); if (alterableCharacters.length) { var cfgnode2 = createConfig({ - name: '新版替换', + name: "新版替换", _name: mode, init: charactersToAlter.length == 0, - intro: '以下武将将被修改:' + get.translation(alterableCharacters), + intro: "以下武将将被修改:" + get.translation(alterableCharacters), onclick(bool) { if (bool) { for (var i = 0; i < alterableSkills.length; i++) { lib.config.vintageSkills.remove(alterableSkills[i]); - lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_alter']; + lib.translate[alterableSkills[i] + "_info"] = + lib.translate[alterableSkills[i] + "_info_alter"]; } - } - else { + } else { for (var i = 0; i < alterableSkills.length; i++) { lib.config.vintageSkills.add(alterableSkills[i]); - lib.translate[alterableSkills[i] + '_info'] = lib.translate[alterableSkills[i] + '_info_origin']; + lib.translate[alterableSkills[i] + "_info"] = + lib.translate[alterableSkills[i] + "_info_origin"]; } } - game.saveConfig('vintageSkills', lib.config.vintageSkills); - } + game.saveConfig("vintageSkills", lib.config.vintageSkills); + }, }); - cfgnode2.style.marginTop = '0px'; + cfgnode2.style.marginTop = "0px"; page.appendChild(cfgnode2); } - } - else if (mode.startsWith('mode_extension')) { + } else if (mode.startsWith("mode_extension")) { // 排除4个基本扩展 // 再排除那个boss扩展的间隔包 // 给扩展的武将包加一个开启关闭的功能 - if (!lib.config.all.stockextension.includes(mode.slice(15)) && mode != 'mode_extension_jiange') { + if ( + !lib.config.all.stockextension.includes(mode.slice(15)) && + mode != "mode_extension_jiange" + ) { page.appendChild(cfgnode); } page.appendChild(cfgnodeAI); - } - else { - page.style.paddingTop = '8px'; + } else { + page.style.paddingTop = "8px"; } var banCharacter = function (e) { if (_status.clicked) { _status.clicked = false; return; } - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && - mode != 'mode_favourite' && mode != 'mode_banned') { + if ( + mode.startsWith("mode_") && + !mode.startsWith("mode_extension_") && + mode != "mode_favourite" && + mode != "mode_banned" + ) { if (!connectMenu && lib.config.show_charactercard) { - ui.click.charactercard(this.link, this, mode == 'mode_guozhan' ? 'guozhan' : true); + ui.click.charactercard(this.link, this, mode == "mode_guozhan" ? "guozhan" : true); } return; } ui.click.touchpop(); - this._banning = connectMenu ? 'online' : 'offline'; + this._banning = connectMenu ? "online" : "offline"; if (!connectMenu && lib.config.show_charactercard) { ui.click.charactercard(this.link, this); - } - else { + } else { ui.click.intro.call(this, e); } _status.clicked = false; @@ -290,30 +293,27 @@ export const characterPackMenu = function (connectMenu) { var updateBanned = function () { var _list; if (connectMenu) { - var mode = cacheMenux.pages[0].firstChild.querySelector('.active'); + var mode = cacheMenux.pages[0].firstChild.querySelector(".active"); if (mode && mode.mode) { - _list = lib.config['connect_' + mode.mode + '_banned']; + _list = lib.config["connect_" + mode.mode + "_banned"]; } - } - else { - _list = lib.config[get.mode() + '_banned']; + } else { + _list = lib.config[get.mode() + "_banned"]; } if (_list && _list.includes(this.link)) { - this.classList.add('banned'); - } - else { - this.classList.remove('banned'); + this.classList.add("banned"); + } else { + this.classList.remove("banned"); } }; if (lib.characterSort[mode]) { var listb = []; if (!connectMenu) { - listb = lib.config[get.mode() + '_banned'] || []; - } - else { - var modex = cacheMenux.pages[0].firstChild.querySelector('.active'); + listb = lib.config[get.mode() + "_banned"] || []; + } else { + var modex = cacheMenux.pages[0].firstChild.querySelector(".active"); if (modex && modex.mode) { - listb = lib.config['connect_' + modex.mode + '_banned']; + listb = lib.config["connect_" + modex.mode + "_banned"]; } } for (var pak in lib.characterSort[mode]) { @@ -335,42 +335,49 @@ export const characterPackMenu = function (connectMenu) { onclick(bool) { var banned = []; if (connectMenu) { - var modex = cacheMenux.pages[0].firstChild.querySelector('.active'); + var modex = cacheMenux.pages[0].firstChild.querySelector(".active"); if (modex && modex.mode) { - banned = lib.config['connect_' + modex.mode + '_banned']; + banned = lib.config["connect_" + modex.mode + "_banned"]; } - } - else if (_status.connectMode) return; - else banned = lib.config[get.mode() + '_banned'] || []; + } else if (_status.connectMode) return; + else banned = lib.config[get.mode() + "_banned"] || []; var listx = lib.characterSort[mode][this._link.config._name]; if (bool) { for (var i = 0; i < listx.length; i++) { banned.remove(listx[i]); } - } - else { + } else { for (var i = 0; i < listx.length; i++) { banned.add(listx[i]); } } - game.saveConfig(connectMenu ? ('connect_' + modex.mode + '_banned') : (get.mode() + '_banned'), banned); + game.saveConfig( + connectMenu + ? "connect_" + modex.mode + "_banned" + : get.mode() + "_banned", + banned + ); updateActive(); }, }; - if (mode.startsWith('mode_') && !mode.startsWith('mode_extension_') && !mode.startsWith('mode_guozhan')) { + if ( + mode.startsWith("mode_") && + !mode.startsWith("mode_extension_") && + !mode.startsWith("mode_guozhan") + ) { cfgnodeY.clear = true; delete cfgnodeY.onclick; } var cfgnodeX = createConfig(cfgnodeY); page.appendChild(cfgnodeX); - var buttons = ui.create.buttons(listx, 'character', page); + var buttons = ui.create.buttons(listx, "character", page); for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); + buttons[i].classList.add("noclick"); buttons[i].listen(banCharacter); ui.create.rarity(buttons[i]); - buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp.style.transition = "all 0s"; buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { + if (mode != "mode_banned") { buttons[i].updateBanned = updateBanned; } } @@ -378,65 +385,72 @@ export const characterPackMenu = function (connectMenu) { } if (list2.length) { var cfgnodeX = createConfig({ - name: '其他', - _name: 'others', + name: "其他", + _name: "others", clear: true, }); page.appendChild(cfgnodeX); - var buttons = ui.create.buttons(list2, 'character', page); + var buttons = ui.create.buttons(list2, "character", page); for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); + buttons[i].classList.add("noclick"); buttons[i].listen(banCharacter); ui.create.rarity(buttons[i]); - buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp.style.transition = "all 0s"; buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { + if (mode != "mode_banned") { buttons[i].updateBanned = updateBanned; } } } - } - else { - var buttons = ui.create.buttons(list, 'character', page); + } else { + var buttons = ui.create.buttons(list, "character", page); for (var i = 0; i < buttons.length; i++) { - buttons[i].classList.add('noclick'); + buttons[i].classList.add("noclick"); ui.create.rarity(buttons[i]); buttons[i].listen(banCharacter); - buttons[i].node.hp.style.transition = 'all 0s'; + buttons[i].node.hp.style.transition = "all 0s"; buttons[i].node.hp._innerHTML = buttons[i].node.hp.innerHTML; - if (mode != 'mode_banned') { + if (mode != "mode_banned") { buttons[i].updateBanned = updateBanned; } } } - page.classList.add('menu-buttons'); - page.classList.add('leftbutton'); + page.classList.add("menu-buttons"); + page.classList.add("leftbutton"); if (!connectMenu) { if (lib.config.all.sgscharacters.includes(mode)) { - ui.create.div('.config.pointerspan', '该武将包不可被隐藏', page); - } - else if (!mode.startsWith('mode_')) { - ui.create.div('.config.pointerspan', '隐藏武将包', page, function () { - if (this.firstChild.innerHTML == '隐藏武将包') { - if (confirm('真的要隐藏“' + get.translation(mode + '_character_config') + '”武将包吗?\n建议使用“关闭”而不是“隐藏”功能,否则将会影响其他相关武将包的正常运行!')) { - this.firstChild.innerHTML = '武将包将在重启后隐藏'; + ui.create.div( + ".config.pointerspan", + '该武将包不可被隐藏', + page + ); + } else if (!mode.startsWith("mode_")) { + ui.create.div(".config.pointerspan", "隐藏武将包", page, function () { + if (this.firstChild.innerHTML == "隐藏武将包") { + if ( + confirm( + "真的要隐藏“" + + get.translation(mode + "_character_config") + + "”武将包吗?\n建议使用“关闭”而不是“隐藏”功能,否则将会影响其他相关武将包的正常运行!" + ) + ) { + this.firstChild.innerHTML = "武将包将在重启后隐藏"; lib.config.hiddenCharacterPack.add(mode); if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); } } - } - else { - this.firstChild.innerHTML = '隐藏武将包'; + } else { + this.firstChild.innerHTML = "隐藏武将包"; lib.config.hiddenCharacterPack.remove(mode); } - game.saveConfig('hiddenCharacterPack', lib.config.hiddenCharacterPack); + game.saveConfig("hiddenCharacterPack", lib.config.hiddenCharacterPack); }); } } }; - if (!get.config('menu_loadondemand')) node._initLink(); + if (!get.config("menu_loadondemand")) node._initLink(); return node; }; if (lib.config.show_favourite_menu && !connectMenu && Array.isArray(lib.config.favouriteCharacter)) { @@ -447,18 +461,18 @@ export const characterPackMenu = function (connectMenu) { lib.characterPack.mode_favourite[favname] = lib.character[favname]; } } - var favouriteCharacterNode = createModeConfig('mode_favourite', start.firstChild); + var favouriteCharacterNode = createModeConfig("mode_favourite", start.firstChild); if (!favouriteCharacterNode.link) favouriteCharacterNode._initLink(); ui.favouriteCharacter = favouriteCharacterNode.link; if (get.is.empty(lib.characterPack.mode_favourite)) { - ui.favouriteCharacter.node.style.display = 'none'; + ui.favouriteCharacter.node.style.display = "none"; } delete lib.characterPack.mode_favourite; } if (!connectMenu && lib.config.show_ban_menu) { lib.characterPack.mode_banned = {}; for (var i = 0; i < lib.config.all.mode.length; i++) { - var banned = lib.config[lib.config.all.mode[i] + '_banned']; + var banned = lib.config[lib.config.all.mode[i] + "_banned"]; if (banned) { for (var j = 0; j < banned.length; j++) { if (lib.character[banned[j]]) { @@ -467,9 +481,9 @@ export const characterPackMenu = function (connectMenu) { } } } - var bannednode = createModeConfig('mode_banned', start.firstChild); + var bannednode = createModeConfig("mode_banned", start.firstChild); if (get.is.empty(lib.characterPack.mode_banned)) { - bannednode.style.display = 'none'; + bannednode.style.display = "none"; } delete lib.characterPack.mode_banned; } @@ -477,21 +491,22 @@ export const characterPackMenu = function (connectMenu) { for (var i = 0; i < characterlist.length; i++) { createModeConfig(characterlist[i], start.firstChild); } - if (!connectMenu) Object.keys(lib.characterPack).forEach(key => { - // 单机模式下显示不在lib.config.all.characters里的武将包 - if (!characterlist.includes(key)) createModeConfig(key, start.firstChild); - if (connectMenu) lib.connectCharacterPack.add(key); - }); - var active = start.firstChild.querySelector('.active'); + if (!connectMenu) + Object.keys(lib.characterPack).forEach((key) => { + // 单机模式下显示不在lib.config.all.characters里的武将包 + if (!characterlist.includes(key)) createModeConfig(key, start.firstChild); + if (connectMenu) lib.connectCharacterPack.add(key); + }); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - if (active.style.display == 'none') { + if (active.style.display == "none") { active = active.nextSibling; - if (active.style.display == 'none') { + if (active.style.display == "none") { active = active.nextSibling; } } - active.classList.add('active'); + active.classList.add("active"); updateActive(active); } if (!active.link) active._initLink(); @@ -499,32 +514,32 @@ export const characterPackMenu = function (connectMenu) { if (!connectMenu) { // 下面使用了var的特性,请不要在这里直接改为let - var node1 = ui.create.div('.lefttext', '全部开启', start.firstChild, function () { - game.saveConfig('characters', lib.config.all.characters); + var node1 = ui.create.div(".lefttext", "全部开启", start.firstChild, function () { + game.saveConfig("characters", lib.config.all.characters); updateNodes(); }); - var node2 = ui.create.div('.lefttext', '恢复默认', start.firstChild, function () { - game.saveConfig('characters', lib.config.defaultcharacters); + var node2 = ui.create.div(".lefttext", "恢复默认", start.firstChild, function () { + game.saveConfig("characters", lib.config.defaultcharacters); updateNodes(); }); - node1.style.marginTop = '12px'; - node2.style.marginTop = '7px'; + node1.style.marginTop = "12px"; + node2.style.marginTop = "7px"; } updateNodes(); /** * 在菜单栏初始化完成后,如果又加载了武将包,进行刷新 - * + * * @param { string } packName */ return function (packName) { // 判断菜单栏有没有加载过这个武将包 - if ([...start.firstChild.children].map(node => node.mode).includes(packName)) return; + if ([...start.firstChild.children].map((node) => node.mode).includes(packName)) return; // 显示不是无名杀自带的武将包 if (!lib.connectCharacterPack.includes(packName) && !lib.config.all.characters.includes(packName)) { createModeConfig(packName, start.firstChild, node1); if (connectMenu) lib.connectCharacterPack.add(packName); } - } -}; \ No newline at end of file + }; +}; diff --git a/noname/ui/create/menu/pages/exetensionMenu.js b/noname/ui/create/menu/pages/exetensionMenu.js index 83f734c3a..df9bd3cb3 100644 --- a/noname/ui/create/menu/pages/exetensionMenu.js +++ b/noname/ui/create/menu/pages/exetensionMenu.js @@ -14,7 +14,7 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig + createConfig, } from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; import { nonameInitialized } from "../../../../util/index.js"; @@ -34,17 +34,17 @@ export const extensionMenu = function (connectMenu) { var rightPane = start.lastChild; var clickMode = function () { - if (this.mode == 'get') { + if (this.mode == "get") { this.update(); } - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active === this) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); active = this; - this.classList.add('active'); + this.classList.add("active"); if (this.link) rightPane.appendChild(this.link); else { this._initLink(); @@ -53,7 +53,7 @@ export const extensionMenu = function (connectMenu) { updateNodes(); }; ui.click.extensionTab = function (name) { - ui.click.menuTab('扩展'); + ui.click.menuTab("扩展"); for (var i = 0; i < start.firstChild.childElementCount; i++) { if (start.firstChild.childNodes[i].innerHTML == name) { clickMode.call(start.firstChild.childNodes[i]); @@ -64,49 +64,43 @@ export const extensionMenu = function (connectMenu) { var updateNodes = function () { for (var i = 0; i < start.firstChild.childNodes.length; i++) { var node = start.firstChild.childNodes[i]; - if (node.mode == 'get') continue; - if (node.mode == 'create') continue; - if (node.mode && node.mode.startsWith('extension_')) { - if (lib.config[node.mode + '_enable']) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); + if (node.mode == "get") continue; + if (node.mode == "create") continue; + if (node.mode && node.mode.startsWith("extension_")) { + if (lib.config[node.mode + "_enable"]) { + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); - } - } - else { + } else { if (lib.config.plays.includes(node.mode)) { - node.classList.remove('off'); - if (node.link) node.link.firstChild.classList.add('on'); - } - else { - node.classList.add('off'); - if (node.link) node.link.firstChild.classList.remove('on'); + node.classList.remove("off"); + if (node.link) node.link.firstChild.classList.add("on"); + } else { + node.classList.add("off"); + if (node.link) node.link.firstChild.classList.remove("on"); } } } }; var togglePack = function (bool) { var name = this._link.config._name; - if (name.startsWith('extension_')) { + if (name.startsWith("extension_")) { if (bool) { game.saveConfig(name, true); - } - else { + } else { game.saveConfig(name, false); } - } - else { - name = name.slice(0, name.indexOf('_enable_playpackconfig')); + } else { + name = name.slice(0, name.indexOf("_enable_playpackconfig")); if (bool) { lib.config.plays.add(name); - } - else { + } else { lib.config.plays.remove(name); } - game.saveConfig('plays', lib.config.plays); + game.saveConfig("plays", lib.config.plays); } if (this.onswitch) { this.onswitch(bool); @@ -115,43 +109,44 @@ export const extensionMenu = function (connectMenu) { }; var createModeConfig = function (mode, position) { - var page = ui.create.div(''); - page.style.paddingBottom = '10px'; + var page = ui.create.div(""); + page.style.paddingBottom = "10px"; var node; - if (mode.startsWith('extension_')) { - node = ui.create.div('.menubutton.large', mode.slice(10), position, clickMode); - } - else { - node = ui.create.div('.menubutton.large', lib.translate[mode + '_play_config'], position, clickMode); + if (mode.startsWith("extension_")) { + node = ui.create.div(".menubutton.large", mode.slice(10), position, clickMode); + } else { + node = ui.create.div( + ".menubutton.large", + lib.translate[mode + "_play_config"], + position, + clickMode + ); } if (node.innerHTML.length >= 5) { - node.classList.add('smallfont'); + node.classList.add("smallfont"); } node.mode = mode; // node._initLink=function(){ node.link = page; for (var i in lib.extensionMenu[mode]) { - if (i == 'game') continue; + if (i == "game") continue; var cfg = get.copy(lib.extensionMenu[mode][i]); var j; - if (mode.startsWith('extension_')) { - j = mode + '_' + i; - } - else { - j = mode + '_' + i + '_playpackconfig'; + if (mode.startsWith("extension_")) { + j = mode + "_" + i; + } else { + j = mode + "_" + i + "_playpackconfig"; } cfg._name = j; if (j in lib.config) { cfg.init = lib.config[j]; - } - else { + } else { game.saveConfig(j, cfg.init); } - if (i == 'enable') { + if (i == "enable") { cfg.onclick = togglePack; - } - else if (!lib.extensionMenu[mode][i].onclick) { + } else if (!lib.extensionMenu[mode][i].onclick) { cfg.onclick = function (result) { var cfg = this._link.config; game.saveConfig(cfg._name, result); @@ -181,9 +176,9 @@ export const extensionMenu = function (connectMenu) { (function () { if (!lib.device && !lib.db) return; if (lib.config.show_extensionmaker == false) return; - var page = ui.create.div('#create-extension'); - var node = ui.create.div('.menubutton.large', '制作扩展', start.firstChild, clickMode); - node.mode = 'create'; + var page = ui.create.div("#create-extension"); + var node = ui.create.div(".menubutton.large", "制作扩展", start.firstChild, clickMode); + node.mode = "create"; game.editExtension = function (name) { node._initLink(); game.editExtension(name); @@ -192,142 +187,140 @@ export const extensionMenu = function (connectMenu) { node.link = page; var pageboard = ui.create.div(page); var inputExtLine = ui.create.div(pageboard); - inputExtLine.style.transition = 'all 0s'; - inputExtLine.style.padding = '10px'; - inputExtLine.style.height = '22px'; - inputExtLine.style.lineHeight = '22px'; - inputExtLine.style.whiteSpace = 'nowrap'; - inputExtLine.style.overflow = 'visible'; - var inputExtSpan = document.createElement('span'); - inputExtSpan.innerHTML = '扩展名:'; + inputExtLine.style.transition = "all 0s"; + inputExtLine.style.padding = "10px"; + inputExtLine.style.height = "22px"; + inputExtLine.style.lineHeight = "22px"; + inputExtLine.style.whiteSpace = "nowrap"; + inputExtLine.style.overflow = "visible"; + var inputExtSpan = document.createElement("span"); + inputExtSpan.innerHTML = "扩展名:"; inputExtLine.appendChild(inputExtSpan); - var inputExtName = document.createElement('input'); - inputExtName.type = 'text'; - inputExtName.value = '无名扩展'; - inputExtName.style.width = '80px'; - inputExtName.style.textAlign = 'center'; + var inputExtName = document.createElement("input"); + inputExtName.type = "text"; + inputExtName.value = "无名扩展"; + inputExtName.style.width = "80px"; + inputExtName.style.textAlign = "center"; inputExtLine.appendChild(inputExtName); var buttonConfirmOnclick = function () { - buttonConfirm.style.display = 'none'; - inputExtSpan.style.display = 'none'; - inputExtName.style.display = 'none'; - authorExtLine.style.display = 'none'; - introExtLine.style.display = 'none'; - forumExtLine.style.display = 'none'; - diskExtLine.style.display = 'none'; - versionExtLine.style.display = 'none'; - okExtLine.style.display = 'none'; - inputExtLine.style.padding = '10px'; - buttonRename.style.display = ''; - buttonSave.style.display = ''; - buttonReset.style.display = ''; - buttonExport.style.display = ''; - inputExtSpan.innerHTML = '扩展名称:'; - inputExtName.style.width = '100px'; - inputExtName.style.textAlign = ''; + buttonConfirm.style.display = "none"; + inputExtSpan.style.display = "none"; + inputExtName.style.display = "none"; + authorExtLine.style.display = "none"; + introExtLine.style.display = "none"; + forumExtLine.style.display = "none"; + diskExtLine.style.display = "none"; + versionExtLine.style.display = "none"; + okExtLine.style.display = "none"; + inputExtLine.style.padding = "10px"; + buttonRename.style.display = ""; + buttonSave.style.display = ""; + buttonReset.style.display = ""; + buttonExport.style.display = ""; + inputExtSpan.innerHTML = "扩展名称:"; + inputExtName.style.width = "100px"; + inputExtName.style.textAlign = ""; - dashboard.style.display = ''; + dashboard.style.display = ""; }; var createExtLine = function (str, str2) { var infoExtLine = ui.create.div(pageboard); - infoExtLine.style.display = 'none'; - infoExtLine.style.padding = '0 10px 10px 10px'; - infoExtLine.style.height = '22px'; - infoExtLine.style.lineHeight = '22px'; - infoExtLine.style.whiteSpace = 'nowrap'; - infoExtLine.style.overflow = 'visible'; - if (typeof str == 'boolean') { - var inputConfirm = document.createElement('button'); - inputConfirm.innerHTML = '确定'; + infoExtLine.style.display = "none"; + infoExtLine.style.padding = "0 10px 10px 10px"; + infoExtLine.style.height = "22px"; + infoExtLine.style.lineHeight = "22px"; + infoExtLine.style.whiteSpace = "nowrap"; + infoExtLine.style.overflow = "visible"; + if (typeof str == "boolean") { + var inputConfirm = document.createElement("button"); + inputConfirm.innerHTML = "确定"; inputConfirm.onclick = buttonConfirmOnclick; infoExtLine.appendChild(inputConfirm); return infoExtLine; } - var infoExtSpan = document.createElement('span'); - infoExtSpan.innerHTML = str + ':'; + var infoExtSpan = document.createElement("span"); + infoExtSpan.innerHTML = str + ":"; infoExtLine.appendChild(infoExtSpan); - var infoExtName = document.createElement('input'); - infoExtName.type = 'text'; - infoExtName.style.width = '100px'; - infoExtName.value = str2 || ''; + var infoExtName = document.createElement("input"); + infoExtName.type = "text"; + infoExtName.style.width = "100px"; + infoExtName.value = str2 || ""; infoExtLine.appendChild(infoExtName); return infoExtLine; }; - var authorExtLine = createExtLine('扩展作者', get.connectNickname()); - var introExtLine = createExtLine('扩展描述'); - var versionExtLine = createExtLine('扩展版本', '1.0'); - var diskExtLine = createExtLine('网盘地址'); - var forumExtLine = createExtLine('讨论地址'); + var authorExtLine = createExtLine("扩展作者", get.connectNickname()); + var introExtLine = createExtLine("扩展描述"); + var versionExtLine = createExtLine("扩展版本", "1.0"); + var diskExtLine = createExtLine("网盘地址"); + var forumExtLine = createExtLine("讨论地址"); var okExtLine = createExtLine(true); game.editExtension = function (name) { - page.currentExtension = name || '无名扩展'; + page.currentExtension = name || "无名扩展"; inputExtName.value = page.currentExtension; if (name && lib.extensionPack[name]) { - authorExtLine.querySelector('input').value = lib.extensionPack[name].author || ''; - introExtLine.querySelector('input').value = lib.extensionPack[name].intro || ''; - diskExtLine.querySelector('input').value = lib.extensionPack[name].diskURL || ''; - forumExtLine.querySelector('input').value = lib.extensionPack[name].forumURL || ''; - versionExtLine.querySelector('input').value = lib.extensionPack[name].version || ''; - } - else { - authorExtLine.querySelector('input').value = get.connectNickname() || ''; - introExtLine.querySelector('input').value = ''; - diskExtLine.querySelector('input').value = ''; - forumExtLine.querySelector('input').value = ''; - versionExtLine.querySelector('input').value = '1.0'; + authorExtLine.querySelector("input").value = lib.extensionPack[name].author || ""; + introExtLine.querySelector("input").value = lib.extensionPack[name].intro || ""; + diskExtLine.querySelector("input").value = lib.extensionPack[name].diskURL || ""; + forumExtLine.querySelector("input").value = lib.extensionPack[name].forumURL || ""; + versionExtLine.querySelector("input").value = lib.extensionPack[name].version || ""; + } else { + authorExtLine.querySelector("input").value = get.connectNickname() || ""; + introExtLine.querySelector("input").value = ""; + diskExtLine.querySelector("input").value = ""; + forumExtLine.querySelector("input").value = ""; + versionExtLine.querySelector("input").value = "1.0"; } if (name) { inputExtName.disabled = true; - buttonConfirm.style.display = 'none'; - inputExtSpan.style.display = 'none'; - inputExtName.style.display = 'none'; - buttonRename.style.display = ''; - buttonSave.style.display = ''; - buttonReset.style.display = ''; - buttonExport.style.display = ''; - } - else { + buttonConfirm.style.display = "none"; + inputExtSpan.style.display = "none"; + inputExtName.style.display = "none"; + buttonRename.style.display = ""; + buttonSave.style.display = ""; + buttonReset.style.display = ""; + buttonExport.style.display = ""; + } else { inputExtName.disabled = false; - buttonConfirm.style.display = ''; - inputExtSpan.innerHTML = '扩展名:'; - inputExtName.style.width = '80px'; - inputExtName.style.textAlign = 'center'; - inputExtSpan.style.display = ''; - inputExtName.style.display = ''; - buttonRename.style.display = 'none'; - buttonSave.style.display = 'none'; - buttonReset.style.display = 'none'; - buttonExport.style.display = 'none'; + buttonConfirm.style.display = ""; + inputExtSpan.innerHTML = "扩展名:"; + inputExtName.style.width = "80px"; + inputExtName.style.textAlign = "center"; + inputExtSpan.style.display = ""; + inputExtName.style.display = ""; + buttonRename.style.display = "none"; + buttonSave.style.display = "none"; + buttonReset.style.display = "none"; + buttonExport.style.display = "none"; } - dashboard.style.display = ''; + dashboard.style.display = ""; - exportExtLine.style.display = 'none'; - shareExtLine.style.display = 'none'; - authorExtLine.style.display = 'none'; - introExtLine.style.display = 'none'; - forumExtLine.style.display = 'none'; - diskExtLine.style.display = 'none'; - versionExtLine.style.display = 'none'; - okExtLine.style.display = 'none'; - inputExtLine.style.padding = '10px'; + exportExtLine.style.display = "none"; + shareExtLine.style.display = "none"; + authorExtLine.style.display = "none"; + introExtLine.style.display = "none"; + forumExtLine.style.display = "none"; + diskExtLine.style.display = "none"; + versionExtLine.style.display = "none"; + okExtLine.style.display = "none"; + inputExtLine.style.padding = "10px"; dash1.reset(name); dash2.reset(name); dash3.reset(name); dash4.reset(name); - dash1.link.classList.remove('active'); - dash2.link.classList.remove('active'); - dash3.link.classList.remove('active'); - dash4.link.classList.remove('active'); - var active = node.parentNode.querySelector('.active'); + dash1.link.classList.remove("active"); + dash2.link.classList.remove("active"); + dash3.link.classList.remove("active"); + dash4.link.classList.remove("active"); + var active = node.parentNode.querySelector(".active"); if (active === node) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); - node.classList.add('active'); + node.classList.add("active"); rightPane.appendChild(node.link); }; var processExtension = function (exportext) { @@ -339,77 +332,86 @@ export const extensionMenu = function (connectMenu) { inputExtName.disabled = true; setTimeout(function () { var ext = {}; - var config = null, help = null; + var config = null, + help = null; for (var i in dash4.content) { try { - if (i == 'content' || i == 'precontent') { - eval('ext[i]=' + dash4.content[i]); - if (typeof ext[i] != 'function') { - throw ('err'); - } - else { + if (i == "content" || i == "precontent") { + eval("ext[i]=" + dash4.content[i]); + if (typeof ext[i] != "function") { + throw "err"; + } else { ext[i] = ext[i].toString(); } - } - else { + } else { eval(dash4.content[i]); - eval('ext[i]=' + i); - if (ext[i] == null || typeof ext[i] != 'object') { - throw ('err'); - } - else { + eval("ext[i]=" + i); + if (ext[i] == null || typeof ext[i] != "object") { + throw "err"; + } else { ext[i] = JSON.stringify(ext[i]); } } - } - catch (e) { + } catch (e) { console.log(e); delete ext[i]; } } - page.currentExtension = inputExtName.value || '无名扩展'; + page.currentExtension = inputExtName.value || "无名扩展"; var str = '{name:"' + page.currentExtension + '"'; for (var i in ext) { - str += ',' + i + ':' + ext[i]; + str += "," + i + ":" + ext[i]; } dash2.content.pack.list = []; for (var i = 0; i < dash2.pile.childNodes.length; i++) { dash2.content.pack.list.push(dash2.pile.childNodes[i].link); } - str += ',package:' + get.stringify({ - //替换die audio,加上扩展名 - character: (pack => { - var character = pack.character; - for (var key in character) { - var info = character[key]; - if (Array.isArray(info[4])) { - var tag = info[4].find(tag => /^die:.+$/.test(tag)); - if (tag) { - info[4].remove(tag); - if (typeof game.readFile == 'function') { - info[4].push('die:ext:' + page.currentExtension + '/audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); - } else { - info[4].push('die:db:extension-' + page.currentExtension + ':audio/die/' + tag.slice(tag.lastIndexOf('/') + 1)); + str += + ",package:" + + get.stringify({ + //替换die audio,加上扩展名 + character: ((pack) => { + var character = pack.character; + for (var key in character) { + var info = character[key]; + if (Array.isArray(info[4])) { + var tag = info[4].find((tag) => /^die:.+$/.test(tag)); + if (tag) { + info[4].remove(tag); + if (typeof game.readFile == "function") { + info[4].push( + "die:ext:" + + page.currentExtension + + "/audio/die/" + + tag.slice(tag.lastIndexOf("/") + 1) + ); + } else { + info[4].push( + "die:db:extension-" + + page.currentExtension + + ":audio/die/" + + tag.slice(tag.lastIndexOf("/") + 1) + ); + } } } } - } - return pack; - })(dash1.content.pack), - card: dash2.content.pack, - skill: dash3.content.pack, - intro: introExtLine.querySelector('input').value || '', - author: authorExtLine.querySelector('input').value || '', - diskURL: diskExtLine.querySelector('input').value || '', - forumURL: forumExtLine.querySelector('input').value || '', - version: versionExtLine.querySelector('input').value || '', - }); + return pack; + })(dash1.content.pack), + card: dash2.content.pack, + skill: dash3.content.pack, + intro: introExtLine.querySelector("input").value || "", + author: authorExtLine.querySelector("input").value || "", + diskURL: diskExtLine.querySelector("input").value || "", + forumURL: forumExtLine.querySelector("input").value || "", + version: versionExtLine.querySelector("input").value || "", + }); var files = { character: [], card: [], skill: [], audio: [] }; for (var i in dash1.content.image) { files.character.push(i); } for (var i in dash1.content.audio) { - files.audio.push('audio/die/' + i); + files.audio.push("audio/die/" + i); } for (var i in dash2.content.image) { files.card.push(i); @@ -417,14 +419,26 @@ export const extensionMenu = function (connectMenu) { for (var i in dash3.content.audio) { files.skill.push(i); } - str += ',files:' + JSON.stringify(files); - str += '}'; - var extension = { 'extension.js': 'game.import("extension",function(lib,game,ui,get,ai,_status){return ' + str + '})' }; + str += ",files:" + JSON.stringify(files); + str += "}"; + var extension = { + "extension.js": + 'import { lib, game, ui, get, ai, _status } from "../../noname.js";\ngame.import("extension",function(){\n\treturn ' + + str + + "\n});", + "info.json": JSON.stringify({ + name: page.currentExtension, + author: authorExtLine.querySelector("input").value || "", + diskURL: diskExtLine.querySelector("input").value || "", + forumURL: forumExtLine.querySelector("input").value || "", + version: versionExtLine.querySelector("input").value || "" + }), + }; for (var i in dash1.content.image) { extension[i] = dash1.content.image[i]; } for (var i in dash1.content.audio) { - extension['audio/die/' + i] = dash1.content.audio[i]; + extension["audio/die/" + i] = dash1.content.audio[i]; } for (var i in dash2.content.image) { extension[i] = dash2.content.image[i]; @@ -433,172 +447,188 @@ export const extensionMenu = function (connectMenu) { if (exportext) { var proexport = function () { game.importExtension(extension, null, page.currentExtension, { - intro: introExtLine.querySelector('input').value || '', - author: authorExtLine.querySelector('input').value || '', - netdisk: diskExtLine.querySelector('input').value || '', - forum: forumExtLine.querySelector('input').value || '', - version: versionExtLine.querySelector('input').value || '', + intro: introExtLine.querySelector("input").value || "", + author: authorExtLine.querySelector("input").value || "", + netdisk: diskExtLine.querySelector("input").value || "", + forum: forumExtLine.querySelector("input").value || "", + version: versionExtLine.querySelector("input").value || "", }); }; if (game.getFileList) { - game.getFileList('extension/' + page.currentExtension, function (folders, files) { - extension._filelist = files; - proexport(); - }); - } - else { + game.getFileList( + "extension/" + page.currentExtension, + function (folders, files) { + extension._filelist = files; + proexport(); + } + ); + } else { proexport(); } - } - else { + } else { game.importExtension(extension, function () { - exportExtLine.style.display = ''; + exportExtLine.style.display = ""; }); } }; //兼容网页版情况 if (typeof game.readFile == "function") { - game.readFile('LICENSE', function (data) { - extension['LICENSE'] = data; - game.writeFile(data, 'extension/' + page.currentExtension, 'LICENSE', function () { }); - callback(); - }, function () { - alert('许可证文件丢失,无法导出扩展'); - }); + game.readFile( + "LICENSE", + function (data) { + extension["LICENSE"] = data; + game.writeFile( + data, + "extension/" + page.currentExtension, + "LICENSE", + function () {} + ); + callback(); + }, + function () { + alert("许可证文件丢失,无法导出扩展"); + } + ); } else { callback(); } }, 500); }; - var buttonConfirm = document.createElement('button'); - buttonConfirm.innerHTML = '确定'; - buttonConfirm.style.marginLeft = '5px'; + var buttonConfirm = document.createElement("button"); + buttonConfirm.innerHTML = "确定"; + buttonConfirm.style.marginLeft = "5px"; buttonConfirm.onclick = buttonConfirmOnclick; inputExtLine.appendChild(buttonConfirm); - var buttonRename = document.createElement('button'); - buttonRename.innerHTML = '选项'; - buttonRename.style.marginLeft = '2px'; - buttonRename.style.marginRight = '2px'; - buttonRename.style.display = 'none'; + var buttonRename = document.createElement("button"); + buttonRename.innerHTML = "选项"; + buttonRename.style.marginLeft = "2px"; + buttonRename.style.marginRight = "2px"; + buttonRename.style.display = "none"; buttonRename.onclick = function () { - inputExtSpan.style.display = ''; - inputExtName.style.display = ''; - authorExtLine.style.display = ''; - introExtLine.style.display = ''; - forumExtLine.style.display = ''; - diskExtLine.style.display = ''; - versionExtLine.style.display = ''; - okExtLine.style.display = 'block'; - inputExtLine.style.padding = '20px 10px 10px 10px'; + inputExtSpan.style.display = ""; + inputExtName.style.display = ""; + authorExtLine.style.display = ""; + introExtLine.style.display = ""; + forumExtLine.style.display = ""; + diskExtLine.style.display = ""; + versionExtLine.style.display = ""; + okExtLine.style.display = "block"; + inputExtLine.style.padding = "20px 10px 10px 10px"; inputExtName.disabled = false; - buttonRename.style.display = 'none'; - buttonSave.style.display = 'none'; - buttonReset.style.display = 'none'; - buttonExport.style.display = 'none'; - inputExtSpan.innerHTML = '扩展名称:'; - inputExtName.style.width = '100px'; - inputExtName.style.textAlign = ''; + buttonRename.style.display = "none"; + buttonSave.style.display = "none"; + buttonReset.style.display = "none"; + buttonExport.style.display = "none"; + inputExtSpan.innerHTML = "扩展名称:"; + inputExtName.style.width = "100px"; + inputExtName.style.textAlign = ""; - dashboard.style.display = 'none'; + dashboard.style.display = "none"; }; inputExtLine.appendChild(buttonRename); - var buttonReset = document.createElement('button'); - buttonReset.innerHTML = '重置'; - buttonReset.style.marginLeft = '2px'; - buttonReset.style.marginRight = '2px'; - buttonReset.style.display = 'none'; + var buttonReset = document.createElement("button"); + buttonReset.innerHTML = "重置"; + buttonReset.style.marginLeft = "2px"; + buttonReset.style.marginRight = "2px"; + buttonReset.style.display = "none"; buttonReset.onclick = function () { - if (confirm('当前扩展将被清除,是否确定?')) { + if (confirm("当前扩展将被清除,是否确定?")) { game.editExtension(); } }; inputExtLine.appendChild(buttonReset); - var buttonSave = document.createElement('button'); - buttonSave.innerHTML = '保存'; - buttonSave.style.marginLeft = '2px'; - buttonSave.style.marginRight = '2px'; - buttonSave.style.display = 'none'; + var buttonSave = document.createElement("button"); + buttonSave.innerHTML = "保存"; + buttonSave.style.marginLeft = "2px"; + buttonSave.style.marginRight = "2px"; + buttonSave.style.display = "none"; buttonSave.onclick = function () { - dash1.link.classList.remove('active'); - dash2.link.classList.remove('active'); - dash3.link.classList.remove('active'); - dash4.link.classList.remove('active'); + dash1.link.classList.remove("active"); + dash2.link.classList.remove("active"); + dash3.link.classList.remove("active"); + dash4.link.classList.remove("active"); processExtension(); }; inputExtLine.appendChild(buttonSave); - var buttonExport = document.createElement('button'); - buttonExport.innerHTML = '导出'; - buttonExport.style.marginLeft = '2px'; - buttonExport.style.marginRight = '2px'; - buttonExport.style.display = 'none'; + var buttonExport = document.createElement("button"); + buttonExport.innerHTML = "导出"; + buttonExport.style.marginLeft = "2px"; + buttonExport.style.marginRight = "2px"; + buttonExport.style.display = "none"; buttonExport.onclick = function () { function oldExport() { processExtension(true); if (lib.config.show_extensionshare) { - shareExtLine.style.display = ''; + shareExtLine.style.display = ""; } } - if (typeof game.readFile == 'function' && + if ( + typeof game.readFile == "function" && window.noname_shijianInterfaces && - typeof window.noname_shijianInterfaces.shareExtensionWithPassWordAsync == 'function' && - confirm('是否使用诗笺版自带的导出功能来导出扩展?')) { + typeof window.noname_shijianInterfaces.shareExtensionWithPassWordAsync == "function" && + confirm("是否使用诗笺版自带的导出功能来导出扩展?") + ) { const extName = inputExtName.value; if (!extName) { - alert('未检测到扩展名,将使用无名杀自带的导出功能'); + alert("未检测到扩展名,将使用无名杀自带的导出功能"); oldExport(); return; } - game.readFile(`extension/${extName}/extension.js`, () => { - const pwd = prompt("请输入压缩包密码,不设密码直接点确定"); - let result; - if (pwd === '' || pwd === null) { - window.noname_shijianInterfaces.shareExtensionAsync(extName); - } else { - window.noname_shijianInterfaces.shareExtensionWithPassWordAsync(extName, pwd); + game.readFile( + `extension/${extName}/extension.js`, + () => { + const pwd = prompt("请输入压缩包密码,不设密码直接点确定"); + let result; + if (pwd === "" || pwd === null) { + window.noname_shijianInterfaces.shareExtensionAsync(extName); + } else { + window.noname_shijianInterfaces.shareExtensionWithPassWordAsync(extName, pwd); + } + }, + () => { + alert("未检测到扩展文件,将使用无名杀自带的导出功能"); + oldExport(); } - }, () => { - alert('未检测到扩展文件,将使用无名杀自带的导出功能'); - oldExport(); - }); + ); } else { oldExport(); } }; inputExtLine.appendChild(buttonExport); var exportExtLine = ui.create.div(pageboard); - exportExtLine.style.display = 'none'; - exportExtLine.style.width = 'calc(100% - 40px)'; - exportExtLine.style.textAlign = 'left'; - exportExtLine.style.marginBottom = '5px'; - if (lib.device == 'ios') { + exportExtLine.style.display = "none"; + exportExtLine.style.width = "calc(100% - 40px)"; + exportExtLine.style.textAlign = "left"; + exportExtLine.style.marginBottom = "5px"; + if (lib.device == "ios") { exportExtLine.innerHTML = '已保存。退出游戏并重新打开后生效×'; - exportExtLine.querySelectorAll('span')[0].onclick = function () { - exportExtLine.style.display = 'none'; + exportExtLine.querySelectorAll("span")[0].onclick = function () { + exportExtLine.style.display = "none"; + }; + } else { + exportExtLine.innerHTML = + '重启后生效。立即重启×'; + exportExtLine.querySelectorAll("span")[0].onclick = game.reload; + exportExtLine.querySelectorAll("span")[1].onclick = function () { + exportExtLine.style.display = "none"; }; } - else { - exportExtLine.innerHTML = '重启后生效。立即重启×'; - exportExtLine.querySelectorAll('span')[0].onclick = game.reload; - exportExtLine.querySelectorAll('span')[1].onclick = function () { - exportExtLine.style.display = 'none'; - }; - } - var shareExtLine = ui.create.div(pageboard); - shareExtLine.style.display = 'none'; - shareExtLine.style.width = 'calc(100% - 40px)'; - shareExtLine.style.textAlign = 'left'; - shareExtLine.style.marginBottom = '5px'; - shareExtLine.innerHTML = '已导出扩展。分享扩展×'; - shareExtLine.querySelectorAll('span')[0].onclick = function () { + shareExtLine.style.display = "none"; + shareExtLine.style.width = "calc(100% - 40px)"; + shareExtLine.style.textAlign = "left"; + shareExtLine.style.marginBottom = "5px"; + shareExtLine.innerHTML = + '已导出扩展。分享扩展×'; + shareExtLine.querySelectorAll("span")[0].onclick = function () { //这个链接404了 //game.open('https://tieba.baidu.com/p/5439380222'); //无名杀贴吧首页 - game.open('https://tieba.baidu.com/f?ie=utf-8&kw=%E6%97%A0%E5%90%8D%E6%9D%80'); + game.open("https://tieba.baidu.com/f?ie=utf-8&kw=%E6%97%A0%E5%90%8D%E6%9D%80"); }; - shareExtLine.querySelectorAll('span')[1].onclick = function () { - shareExtLine.style.display = 'none'; + shareExtLine.querySelectorAll("span")[1].onclick = function () { + shareExtLine.style.display = "none"; }; var dashboard = ui.create.div(pageboard); @@ -611,54 +641,53 @@ export const extensionMenu = function (connectMenu) { } }; var createDash = function (str1, str2, node) { - var dash = ui.create.div('.menubutton.large.dashboard'); + var dash = ui.create.div(".menubutton.large.dashboard"); dashboard.appendChild(dash); page.appendChild(node); dash.link = node; node.link = dash; dash.listen(clickDash); lib.setScroll(node); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); + ui.create.div("", str1, dash); + ui.create.div("", str2, dash); }; var dash1 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); + var page = ui.create.div(".hidden.menu-buttons"); var currentButton = null; page.init = function () { - if (!page.querySelector('.button.character')) { - toggle.classList.add('on'); - newCharacter.style.display = ''; + if (!page.querySelector(".button.character")) { + toggle.classList.add("on"); + newCharacter.style.display = ""; } }; var updateButton = function () { - var name = page.querySelector('input.new_name').value; + var name = page.querySelector("input.new_name").value; if (!name) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } - name = name.split('|'); + name = name.split("|"); name = name[0]; if (currentButton) { if (currentButton.link != name) { if (lib.character[name] || page.content.pack.character[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } - } - else { + } else { if (lib.character[name] || page.content.pack.character[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } if (!fakeme.image) { - if (!page.content.image[name + '.jpg']) { - editnode.classList.add('disabled'); + if (!page.content.image[name + ".jpg"]) { + editnode.classList.add("disabled"); return; } } - editnode.classList.remove('disabled'); + editnode.classList.remove("disabled"); }; var clickButton = async function () { if (currentButton == this) { @@ -667,55 +696,68 @@ export const extensionMenu = function (connectMenu) { } resetEditor(); currentButton = this; - toggle.classList.add('on'); - newCharacter.style.display = ''; - fakeme.classList.add('inited'); + toggle.classList.add("on"); + newCharacter.style.display = ""; + fakeme.classList.add("inited"); fakeme.style.backgroundImage = this.style.backgroundImage; if (page.content.pack.translate[this.link] != this.link) { - newCharacter.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; - } - else { - newCharacter.querySelector('.new_name').value = this.link; + newCharacter.querySelector(".new_name").value = + this.link + "|" + page.content.pack.translate[this.link]; + } else { + newCharacter.querySelector(".new_name").value = this.link; } var info = page.content.pack.character[this.link]; - newCharacter.querySelector('.new_hp').value = info[2]; + newCharacter.querySelector(".new_hp").value = info[2]; sexes.value = info[0]; groups.value = info[1]; if (info[4]) { for (var i = 0; i < options.childNodes.length - 1; i++) { - if (options.childNodes[i].lastChild && info[4].includes(options.childNodes[i].lastChild.name)) { + if ( + options.childNodes[i].lastChild && + info[4].includes(options.childNodes[i].lastChild.name) + ) { options.childNodes[i].lastChild.checked = true; - } - else if (options.childNodes[i].lastChild) { + } else if (options.childNodes[i].lastChild) { options.childNodes[i].lastChild.checked = false; } } for (var i = 0; i < info[4].length; i++) { - if (info[4][i].startsWith('des:')) { - newCharacter.querySelector('.new_des').value = info[4][i].slice(4); + if (info[4][i].startsWith("des:")) { + newCharacter.querySelector(".new_des").value = info[4][i].slice(4); } - if (info[4][i].startsWith('die:')) { - var dieaudionode = newCharacter.querySelector('.die_audio'); + if (info[4][i].startsWith("die:")) { + var dieaudionode = newCharacter.querySelector(".die_audio"); dieaudionode.file = { - name: info[4][i].slice(info[4][i].lastIndexOf('/') + 1) + name: info[4][i].slice(info[4][i].lastIndexOf("/") + 1), }; await new Promise((resolve) => { - if (typeof game.readFile == 'function') { - game.readFile(info[4][i].slice(4).replace('ext:', 'extension/'), arraybuffer => { - dieaudionode.arrayBuffer = arraybuffer; - resolve(); - }, () => { - console.warn(`未找到${info[4][i].slice(4).replace('ext:', 'extension/')}阵亡配音`); - resolve(); - }); + if (typeof game.readFile == "function") { + game.readFile( + info[4][i].slice(4).replace("ext:", "extension/"), + (arraybuffer) => { + dieaudionode.arrayBuffer = arraybuffer; + resolve(); + }, + () => { + console.warn( + `未找到${info[4][i] + .slice(4) + .replace("ext:", "extension/")}阵亡配音` + ); + resolve(); + } + ); } else { - game.getDB('image', info[4][i].slice(7)).then(octetStream => { - dieaudionode.arrayBuffer = octetStream; - resolve(); - }, () => { - console.warn(`未找到${info[4][i].slice(4)}阵亡配音`); - resolve(); - }); + game.getDB("image", info[4][i].slice(7)).then( + (octetStream) => { + dieaudionode.arrayBuffer = octetStream; + resolve(); + }, + () => { + console.warn(`未找到${info[4][i].slice(4)}阵亡配音`); + resolve(); + } + ); } }); } @@ -724,34 +766,38 @@ export const extensionMenu = function (connectMenu) { var skills = info[3]; for (var i = 0; i < skills.length; i++) { - var node = document.createElement('button'); + var node = document.createElement("button"); node.skill = skills[i]; node.onclick = deletenode; node.innerHTML = lib.translate[skills[i]]; skillList.firstChild.appendChild(node); } - toggle.innerHTML = '编辑武将
                                      >
                                      '; - editnode.innerHTML = '编辑武将'; - editnode.classList.remove('disabled'); - delnode.innerHTML = '删除'; + toggle.innerHTML = "编辑武将
                                      >
                                      "; + editnode.innerHTML = "编辑武将"; + editnode.classList.remove("disabled"); + delnode.innerHTML = "删除"; delnode.button = this; }; var createButton = function (name, image) { - var button = ui.create.div('.button.character'); + var button = ui.create.div(".button.character"); button.link = name; button.image = image; - button.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundSize = 'cover'; + button.style.backgroundImage = "url(" + image + ")"; + button.style.backgroundSize = "cover"; button.listen(clickButton); - button.classList.add('noclick'); - button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); - button.nodename.style.top = '8px'; + button.classList.add("noclick"); + button.nodename = ui.create.div( + button, + ".name", + get.verticalStr(page.content.pack.translate[name]) + ); + button.nodename.style.top = "8px"; page.insertBefore(button, page.childNodes[1]); }; page.reset = function (name) { resetEditor(); - var buttons = page.querySelectorAll('.button.character'); + var buttons = page.querySelectorAll(".button.character"); var list = []; for (var i = 0; i < buttons.length; i++) { list.push(buttons[i]); @@ -762,17 +808,17 @@ export const extensionMenu = function (connectMenu) { if (lib.extensionPack[name]) { page.content.pack = lib.extensionPack[name].character || { character: {}, - translate: {} + translate: {}, }; page.content.image = {}; for (var i in page.content.pack.character) { - var file = i + '.jpg'; + var file = i + ".jpg"; var loadImage = function (file, data) { var img = new Image(); - img.crossOrigin = 'Anonymous'; + img.crossOrigin = "Anonymous"; img.onload = function () { - var canvas = document.createElement('CANVAS'); - var ctx = canvas.getContext('2d'); + var canvas = document.createElement("CANVAS"); + var ctx = canvas.getContext("2d"); var dataURL; canvas.height = this.height; canvas.width = this.width; @@ -788,107 +834,112 @@ export const extensionMenu = function (connectMenu) { img.src = data; }; if (game.download) { - var url = lib.assetURL + 'extension/' + name + '/' + file; + var url = lib.assetURL + "extension/" + name + "/" + file; createButton(i, url); - if (lib.device == 'ios' || lib.device == 'android') { - window.resolveLocalFileSystemURL(nonameInitialized + 'extension/' + name, function (entry) { - entry.getFile(file, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + if (lib.device == "ios" || lib.device == "android") { + window.resolveLocalFileSystemURL( + nonameInitialized + "extension/" + name, + function (entry) { + entry.getFile(file, {}, function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }); }); - }); - }); - } - else { + } + ); + } else { loadImage(file, url); } - } - else game.getDB('image', `extension-${name}:${file}`).then(value => { - createButton(i, value); - loadImage(file, value); - }); + } else + game.getDB("image", `extension-${name}:${file}`).then((value) => { + createButton(i, value); + loadImage(file, value); + }); } - } - else { + } else { page.content = { pack: { character: {}, - translate: {} + translate: {}, }, image: {}, - audio: {} + audio: {}, }; - toggle.classList.add('on'); - newCharacter.style.display = ''; + toggle.classList.add("on"); + newCharacter.style.display = ""; } }; - ui.create.div('.config.more', '
                                      返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); + ui.create.div( + ".config.more", + '
                                      返回', + page, + function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + } + ); page.content = { pack: { character: {}, - translate: {} + translate: {}, }, image: {}, - audio: {} + audio: {}, }; var newCharacter; - var toggle = ui.create.div('.config.more.on', '创建武将
                                      >
                                      ', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newCharacter.style.display = ''; - } - else { - newCharacter.style.display = 'none'; + var toggle = ui.create.div(".config.more.on", "创建武将
                                      >
                                      ", page, function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + newCharacter.style.display = ""; + } else { + newCharacter.style.display = "none"; } }); var resetEditor = function () { currentButton = null; - toggle.classList.remove('on'); - newCharacter.style.display = 'none'; - fakeme.classList.remove('inited'); + toggle.classList.remove("on"); + newCharacter.style.display = "none"; + fakeme.classList.remove("inited"); delete fakeme.image; delete fakeme.image64; - fakeme.style.backgroundImage = ''; - var inputs = newCharacter.querySelectorAll('input'); + fakeme.style.backgroundImage = ""; + var inputs = newCharacter.querySelectorAll("input"); for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; + inputs[i].value = ""; } - inputs = newCharacter.querySelectorAll('textarea'); + inputs = newCharacter.querySelectorAll("textarea"); for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; + inputs[i].value = ""; } - skillList.firstChild.innerHTML = ''; - toggle.innerHTML = '创建武将
                                      >
                                      '; - editnode.innerHTML = '创建武将'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; + skillList.firstChild.innerHTML = ""; + toggle.innerHTML = "创建武将
                                      >
                                      "; + editnode.innerHTML = "创建武将"; + editnode.classList.add("disabled"); + delnode.innerHTML = "取消"; delete delnode.button; }; - newCharacter = ui.create.div('.new_character', page); - var fakeme = ui.create.div('.avatar', newCharacter); + newCharacter = ui.create.div(".new_character", page); + var fakeme = ui.create.div(".avatar", newCharacter); - var input = document.createElement('input'); - input.type = 'file'; - input.accept = 'image/*'; - input.className = 'fileinput'; + var input = document.createElement("input"); + input.type = "file"; + input.accept = "image/*"; + input.className = "fileinput"; input.onchange = function () { var fileToLoad = input.files[0]; if (fileToLoad) { var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; - fakeme.style.backgroundImage = 'url(' + data + ')'; + fakeme.style.backgroundImage = "url(" + data + ")"; fakeme.image64 = data; - fakeme.classList.add('inited'); + fakeme.classList.add("inited"); var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { fakeme.image = fileLoadedEvent.target.result; @@ -901,26 +952,46 @@ export const extensionMenu = function (connectMenu) { }; fakeme.appendChild(input); - ui.create.div('.select_avatar', '选择头像', fakeme); + ui.create.div(".select_avatar", "选择头像", fakeme); - ui.create.div('.indent', '姓名:', newCharacter).style.paddingTop = '8px'; - ui.create.div('.indent', '介绍:', newCharacter).style.paddingTop = '8px'; - ui.create.div('.indent', '体力:', newCharacter).style.paddingTop = '8px'; - newCharacter.querySelector('input.new_name').onblur = updateButton; - var sexes = ui.create.selectlist([ - ['male', '男'], - ['female', '女'], - ['double', '双性'], - ['none', '无'] - ], null, ui.create.div('.indent', '性别:', newCharacter)); + ui.create.div( + ".indent", + '姓名:', + newCharacter + ).style.paddingTop = "8px"; + ui.create.div( + ".indent", + '介绍:', + newCharacter + ).style.paddingTop = "8px"; + ui.create.div( + ".indent", + '体力:', + newCharacter + ).style.paddingTop = "8px"; + newCharacter.querySelector("input.new_name").onblur = updateButton; + var sexes = ui.create.selectlist( + [ + ["male", "男"], + ["female", "女"], + ["double", "双性"], + ["none", "无"], + ], + null, + ui.create.div(".indent", "性别:", newCharacter) + ); var grouplist = lib.group.map((group, i) => [lib.group[i], get.translation(lib.group[i])]); - var groups = ui.create.selectlist(grouplist, null, ui.create.div('.indent', '势力:', newCharacter)); - var dieaudio = ui.create.div('.die_audio', newCharacter, { textAlign: 'left' }); - var dieaudiolabel = ui.create.node('label', '阵亡配音:', dieaudio); - var dieaudioUpload = dieaudio.appendChild(document.createElement('input')); - dieaudioUpload.type = 'file'; - dieaudioUpload.accept = 'audio/*'; - dieaudioUpload.style.width = 'calc(100% - 100px)'; + var groups = ui.create.selectlist( + grouplist, + null, + ui.create.div(".indent", "势力:", newCharacter) + ); + var dieaudio = ui.create.div(".die_audio", newCharacter, { textAlign: "left" }); + var dieaudiolabel = ui.create.node("label", "阵亡配音:", dieaudio); + var dieaudioUpload = dieaudio.appendChild(document.createElement("input")); + dieaudioUpload.type = "file"; + dieaudioUpload.accept = "audio/*"; + dieaudioUpload.style.width = "calc(100% - 100px)"; dieaudioUpload.onchange = function () { var fileToLoad = dieaudioUpload.files[0]; if (fileToLoad) { @@ -932,26 +1003,25 @@ export const extensionMenu = function (connectMenu) { dieaudio.file = fileToLoad; dieaudio.arrayBuffer = data; dieaudio.blob = blob; - var new_name = newCharacter.querySelector('input.new_name'); - dieaudioUpload.style.display = 'none'; - dieaudiopreview.style.display = - dieaudiocancel.style.display = ''; + var new_name = newCharacter.querySelector("input.new_name"); + dieaudioUpload.style.display = "none"; + dieaudiopreview.style.display = dieaudiocancel.style.display = ""; dieaudiotag.src = window.URL.createObjectURL(blob); }; fileReader.readAsArrayBuffer(fileToLoad); } }; - var dieaudiotag = ui.create.node('audio', dieaudio); - var dieaudiopreview = ui.create.node('button', dieaudio, () => { + var dieaudiotag = ui.create.node("audio", dieaudio); + var dieaudiopreview = ui.create.node("button", dieaudio, () => { if (dieaudiotag.error) { - alert('您使用的客户端不支持预览此音频!'); + alert("您使用的客户端不支持预览此音频!"); } else dieaudiotag.play(); }); - dieaudiopreview.innerHTML = '播放'; - dieaudiopreview.style.display = 'none'; - var dieaudiocancel = ui.create.node('button', dieaudio, () => { - dieaudiopreview.style.display = 'none'; - dieaudiocancel.style.display = 'none'; + dieaudiopreview.innerHTML = "播放"; + dieaudiopreview.style.display = "none"; + var dieaudiocancel = ui.create.node("button", dieaudio, () => { + dieaudiopreview.style.display = "none"; + dieaudiocancel.style.display = "none"; if (dieaudio.blob) { window.URL.revokeObjectURL(dieaudio.blob); dieaudiotag.src = null; @@ -959,13 +1029,17 @@ export const extensionMenu = function (connectMenu) { delete dieaudio.arrayBuffer; delete dieaudio.blob; } - dieaudioUpload.value = ''; - dieaudioUpload.style.display = ''; + dieaudioUpload.value = ""; + dieaudioUpload.style.display = ""; }); - dieaudiocancel.innerHTML = '取消'; - dieaudiocancel.style.display = 'none'; - var options = ui.create.div('.add_skill.options', '主公BOSS仅点将可用
                                      隐匿技
                                      ', newCharacter); - var addSkill = ui.create.div('.add_skill', '添加技能
                                      ', newCharacter); + dieaudiocancel.innerHTML = "取消"; + dieaudiocancel.style.display = "none"; + var options = ui.create.div( + ".add_skill.options", + '主公BOSS仅点将可用
                                      隐匿技
                                      ', + newCharacter + ); + var addSkill = ui.create.div(".add_skill", "添加技能
                                      ", newCharacter); var list = []; for (var i in lib.character) { if (lib.character[i][3].length) { @@ -973,13 +1047,15 @@ export const extensionMenu = function (connectMenu) { } } list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); + a = a[0]; + b = b[0]; + var aa = a, + bb = b; + if (aa.includes("_")) { + aa = aa.slice(aa.indexOf("_") + 1); } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); + if (bb.includes("_")) { + bb = bb.slice(bb.indexOf("_") + 1); } if (aa != bb) { return aa > bb ? 1 : -1; @@ -991,36 +1067,35 @@ export const extensionMenu = function (connectMenu) { for (var i = 0; i < skills.length; i++) { list2.push([skills[i], lib.translate[skills[i]]]); } - list.unshift(['current_extension', '此扩展']); + list.unshift(["current_extension", "此扩展"]); var selectname = ui.create.selectlist(list, list[1], addSkill); page.selectname = selectname; selectname.onchange = function () { - skillopt.innerHTML = ''; - if (this.value == 'current_extension') { + skillopt.innerHTML = ""; + if (this.value == "current_extension") { for (var i in dash3.content.pack.skill) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = i; option.innerHTML = dash3.content.pack.translate[i]; skillopt.appendChild(option); } - } - else { + } else { var skills = lib.character[this.value][3]; for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = skills[i]; option.innerHTML = lib.translate[skills[i]]; skillopt.appendChild(option); } } }; - selectname.style.maxWidth = '85px'; + selectname.style.maxWidth = "85px"; var skillopt = ui.create.selectlist(list2, list2[0], addSkill); - skillopt.style.maxWidth = '60px'; + skillopt.style.maxWidth = "60px"; page.skillopt = skillopt; - var addSkillButton = document.createElement('button'); - addSkillButton.innerHTML = '添加'; + var addSkillButton = document.createElement("button"); + addSkillButton.innerHTML = "添加"; addSkill.appendChild(addSkillButton); page.addSkillButton = addSkillButton; var deletenode = function () { @@ -1028,31 +1103,37 @@ export const extensionMenu = function (connectMenu) { }; addSkillButton.onclick = function () { for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { - if (skillList.firstChild.childNodes[i].skill == skillopt.value) return alert(selectname.value == 'current_extension' ? '此扩展还未添加技能' : '此武将没有技能可添加'); + if (skillList.firstChild.childNodes[i].skill == skillopt.value) + return alert( + selectname.value == "current_extension" + ? "此扩展还未添加技能" + : "此武将没有技能可添加" + ); } //无技能时 if (!skillopt.value || skillopt.childElementCount == 0) return; - var node = document.createElement('button'); + var node = document.createElement("button"); node.skill = skillopt.value; node.onclick = deletenode; for (var i = 0; i < skillopt.childElementCount; i++) { if (skillopt.childNodes[i].value == skillopt.value) { - node.innerHTML = skillopt.childNodes[i].innerHTML; break; + node.innerHTML = skillopt.childNodes[i].innerHTML; + break; } } skillList.firstChild.appendChild(node); }; - var createSkillButton = document.createElement('button'); - createSkillButton.innerHTML = '创建'; - createSkillButton.style.marginLeft = '3px'; + var createSkillButton = document.createElement("button"); + createSkillButton.innerHTML = "创建"; + createSkillButton.style.marginLeft = "3px"; addSkill.appendChild(createSkillButton); createSkillButton.onclick = function () { ui.create.templayer(); page.hide(); dash3.show(); - dash3.fromchar = 'add'; - dash3.toggle.classList.add('on'); - dash3.newSkill.style.display = ''; + dash3.fromchar = "add"; + dash3.toggle.classList.add("on"); + dash3.newSkill.style.display = ""; }; page.updateSkill = function () { for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { @@ -1060,149 +1141,158 @@ export const extensionMenu = function (connectMenu) { var skill = skillList.firstChild.childNodes[i].skill; if (dash3.content.pack.skill[skill]) { node.innerHTML = dash3.content.pack.translate[skill]; - } - else if (lib.skill[skill]) { + } else if (lib.skill[skill]) { node.innerHTML = lib.translate[skill]; - } - else { - node.remove(); i--; + } else { + node.remove(); + i--; } } }; - var skillList = ui.create.div('.skill_list', newCharacter); + var skillList = ui.create.div(".skill_list", newCharacter); ui.create.div(skillList); - var editnode = ui.create.div('.menubutton.large.disabled', '创建武将', ui.create.div(skillList), function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写武将名\n提示:武将名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { + var editnode = ui.create.div( + ".menubutton.large.disabled", + "创建武将", + ui.create.div(skillList), + function () { + var name = page.querySelector("input.new_name").value; + if (!name) { + alert("请填写武将名\n提示:武将名格式为id+|+中文名,其中id必须惟一"); + return; + } + name = name.split("|"); + var translate = name[1] || name[0]; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.character[name] || page.content.pack.character[name]) { + alert( + "武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一" + ); + return; + } + page.content.image[name + ".jpg"] = + page.content.image[currentButton.link + ".jpg"]; + delete page.content.image[currentButton.link + ".jpg"]; + delete page.content.pack.character[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + currentButton.link = name; + } + } else { if (lib.character[name] || page.content.pack.character[name]) { - alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); + alert( + "武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一" + ); return; } - page.content.image[name + '.jpg'] = page.content.image[currentButton.link + '.jpg']; - delete page.content.image[currentButton.link + '.jpg']; - delete page.content.pack.character[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - currentButton.link = name; } - } - else { - if (lib.character[name] || page.content.pack.character[name]) { - alert('武将名与现有武将重复,请更改\n提示:武将名格式为id+|+中文名,其中id必须惟一'); - return; + if (fakeme.image) { + page.content.image[name + ".jpg"] = fakeme.image; + } else { + if (!page.content.image[name + ".jpg"]) { + alert("请选择武将头像"); + return; + } } - } - if (fakeme.image) { - page.content.image[name + '.jpg'] = fakeme.image; - } - else { - if (!page.content.image[name + '.jpg']) { - alert('请选择武将头像'); - return; + var hp = page.querySelector("input.new_hp").value; + //体力支持‘Infinity,∞,无限’表示无限 + if (["Infinity", "∞", "无限"].includes(hp)) hp = Infinity; + else if (hp.indexOf("/") == -1) hp = parseInt(hp) || 1; + var skills = []; + for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { + skills.add(skillList.firstChild.childNodes[i].skill); } - } - var hp = page.querySelector('input.new_hp').value; - //体力支持‘Infinity,∞,无限’表示无限 - if (['Infinity', '∞', '无限'].includes(hp)) hp = Infinity; - else if (hp.indexOf('/') == -1) hp = parseInt(hp) || 1; - var skills = []; - for (var i = 0; i < skillList.firstChild.childNodes.length; i++) { - skills.add(skillList.firstChild.childNodes[i].skill); - } - var tags = []; - for (var i = 0; i < options.childNodes.length - 1; i++) { - if (options.childNodes[i].lastChild && options.childNodes[i].lastChild.checked) { - tags.push(options.childNodes[i].lastChild.name); + var tags = []; + for (var i = 0; i < options.childNodes.length - 1; i++) { + if (options.childNodes[i].lastChild && options.childNodes[i].lastChild.checked) { + tags.push(options.childNodes[i].lastChild.name); + } + } + if (tags.includes("boss")) { + tags.add("bossallowed"); + } + var des = page.querySelector("input.new_des").value; + if (des) { + tags.add("des:" + des); + } + //阵亡配音 + if (dieaudio.file && dieaudio.arrayBuffer) { + var audioname = name + dieaudio.file.name.slice(dieaudio.file.name.indexOf(".")); + tags.add( + `die:${ + typeof game.readFile == "function" ? "ext" : "db" + }:audio/die/${audioname}` + ); + page.content.audio[audioname] = dieaudio.arrayBuffer; } - } - if (tags.includes('boss')) { - tags.add('bossallowed'); - } - var des = page.querySelector('input.new_des').value; - if (des) { - tags.add('des:' + des); - } - //阵亡配音 - if (dieaudio.file && dieaudio.arrayBuffer) { - var audioname = name + dieaudio.file.name.slice(dieaudio.file.name.indexOf('.')); - tags.add(`die:${typeof game.readFile == 'function' ? 'ext' : 'db'}:audio/die/${audioname}`); - page.content.audio[audioname] = dieaudio.arrayBuffer; - } - page.content.pack.translate[name] = translate; - page.content.pack.character[name] = [sexes.value, groups.value, hp, skills, tags]; - if (this.innerHTML == '创建武将') { - createButton(name, fakeme.image64); - } - else if (currentButton) { - if (fakeme.image64) { - currentButton.image = fakeme.image64; - currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; + page.content.pack.translate[name] = translate; + page.content.pack.character[name] = [sexes.value, groups.value, hp, skills, tags]; + if (this.innerHTML == "创建武将") { + createButton(name, fakeme.image64); + } else if (currentButton) { + if (fakeme.image64) { + currentButton.image = fakeme.image64; + currentButton.style.backgroundImage = "url(" + fakeme.image64 + ")"; + } + currentButton.nodename.innerHTML = get.verticalStr(translate); } - currentButton.nodename.innerHTML = get.verticalStr(translate); + resetEditor(); + dash1.link.classList.add("active"); } - resetEditor(); - dash1.link.classList.add('active'); - }); - var delnode = ui.create.div('.menubutton.large', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { + ); + var delnode = ui.create.div(".menubutton.large", "取消", editnode.parentNode, function () { + if (this.innerHTML == "删除") { this.button.remove(); var name = this.button.link; delete dash1.content.pack.character[name]; delete dash1.content.pack.translate[name]; delete dash1.content.image[name]; delete dash1.content.audio[name]; - dash1.link.classList.add('active'); + dash1.link.classList.add("active"); } resetEditor(); }); - delnode.style.marginLeft = '13px'; + delnode.style.marginLeft = "13px"; return page; - }()); + })(); var dash2 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); + var page = ui.create.div(".hidden.menu-buttons"); var currentButton = null; page.init = function () { - if (!page.querySelector('.button.card')) { - toggle.classList.add('on'); - newCard.style.display = ''; + if (!page.querySelector(".button.card")) { + toggle.classList.add("on"); + newCard.style.display = ""; } }; var updateButton = function () { - var name = page.querySelector('input.new_name').value; + var name = page.querySelector("input.new_name").value; if (!name) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } - name = name.split('|'); + name = name.split("|"); name = name[0]; if (currentButton) { if (currentButton.link != name) { if (lib.card[name] || page.content.pack.card[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } - } - else { + } else { if (lib.card[name] || page.content.pack.card[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } - if (!fakeme.image && !fakeme.classList.contains('inited')) { - editnode.classList.add('disabled'); + if (!fakeme.image && !fakeme.classList.contains("inited")) { + editnode.classList.add("disabled"); return; } - editnode.classList.remove('disabled'); + editnode.classList.remove("disabled"); }; var clickButton = function () { if (currentButton == this) { @@ -1211,63 +1301,66 @@ export const extensionMenu = function (connectMenu) { } resetEditor(); currentButton = this; - toggle.classList.add('on'); - newCard.style.display = ''; - fakeme.classList.add('inited'); + toggle.classList.add("on"); + newCard.style.display = ""; + fakeme.classList.add("inited"); delete fakeme.image; delete fakeme.image64; - if (this.classList.contains('fullskin')) { + if (this.classList.contains("fullskin")) { fakeme.imagenode.style.backgroundImage = this.imagenode.style.backgroundImage; - fakeme.classList.add('fullskin'); - } - else { + fakeme.classList.add("fullskin"); + } else { fakeme.style.backgroundImage = this.style.backgroundImage; - fakeme.classList.remove('fullskin'); + fakeme.classList.remove("fullskin"); } if (page.content.pack.translate[this.link] != this.link) { - newCard.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; + newCard.querySelector(".new_name").value = + this.link + "|" + page.content.pack.translate[this.link]; + } else { + newCard.querySelector(".new_name").value = this.link; } - else { - newCard.querySelector('.new_name').value = this.link; - } - newCard.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; + newCard.querySelector(".new_description").value = + page.content.pack.translate[this.link + "_info"]; var info = page.content.pack.card[this.link]; - container.code = 'card=' + get.stringify(info); + container.code = "card=" + get.stringify(info); - toggle.innerHTML = '编辑卡牌
                                      >
                                      '; - editnode.innerHTML = '编辑卡牌'; - editnode.classList.remove('disabled'); - delnode.innerHTML = '删除'; + toggle.innerHTML = "编辑卡牌
                                      >
                                      "; + editnode.innerHTML = "编辑卡牌"; + editnode.classList.remove("disabled"); + delnode.innerHTML = "删除"; delnode.button = this; }; var createButton = function (name, image, fullskin) { - var button = ui.create.div('.button.card'); + var button = ui.create.div(".button.card"); button.link = name; button.image = image; - button.imagenode = ui.create.div('.image', button); + button.imagenode = ui.create.div(".image", button); if (image) { if (fullskin) { - button.imagenode.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundImage = ''; - button.style.backgroundSize = ''; - button.classList.add('fullskin'); - } - else { - button.style.color = 'white'; - button.style.textShadow = 'black 0 0 2px'; - button.imagenode.style.backgroundImage = ''; - button.style.backgroundImage = 'url(' + image + ')'; - button.style.backgroundSize = 'cover'; + button.imagenode.style.backgroundImage = "url(" + image + ")"; + button.style.backgroundImage = ""; + button.style.backgroundSize = ""; + button.classList.add("fullskin"); + } else { + button.style.color = "white"; + button.style.textShadow = "black 0 0 2px"; + button.imagenode.style.backgroundImage = ""; + button.style.backgroundImage = "url(" + image + ")"; + button.style.backgroundSize = "cover"; } } button.listen(clickButton); - button.classList.add('noclick'); - button.nodename = ui.create.div(button, '.name', get.verticalStr(page.content.pack.translate[name])); + button.classList.add("noclick"); + button.nodename = ui.create.div( + button, + ".name", + get.verticalStr(page.content.pack.translate[name]) + ); page.insertBefore(button, page.childNodes[1]); }; page.reset = function (name) { resetEditor(); - var buttons = page.querySelectorAll('.button.card'); + var buttons = page.querySelectorAll(".button.card"); var list = []; for (var i = 0; i < buttons.length; i++) { list.push(buttons[i]); @@ -1278,14 +1371,18 @@ export const extensionMenu = function (connectMenu) { if (lib.extensionPack[name]) { page.content.pack = lib.extensionPack[name].card || { card: {}, - translate: {} + translate: {}, }; page.content.image = {}; if (Array.isArray(page.content.pack.list)) { for (var i = 0; i < page.content.pack.list.length; i++) { var card = page.content.pack.list[i]; - var node = document.createElement('button'); - node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; + var node = document.createElement("button"); + node.innerHTML = + page.content.pack.translate[card[2]] + + " " + + lib.translate[card[0]] + + card[1]; node.name = card[2]; node.link = card; pile.appendChild(node); @@ -1298,17 +1395,16 @@ export const extensionMenu = function (connectMenu) { var file; var fullskin = page.content.pack.card[i].fullskin ? true : false; if (fullskin) { - file = i + '.png'; - } - else { - file = i + '.jpg'; + file = i + ".png"; + } else { + file = i + ".jpg"; } var loadImage = function (file, data) { var img = new Image(); - img.crossOrigin = 'Anonymous'; + img.crossOrigin = "Anonymous"; img.onload = function () { - var canvas = document.createElement('CANVAS'); - var ctx = canvas.getContext('2d'); + var canvas = document.createElement("CANVAS"); + var ctx = canvas.getContext("2d"); var dataURL; canvas.height = this.height; canvas.width = this.width; @@ -1324,116 +1420,121 @@ export const extensionMenu = function (connectMenu) { img.src = data; }; if (game.download) { - var url = lib.assetURL + 'extension/' + name + '/' + file; + var url = lib.assetURL + "extension/" + name + "/" + file; createButton(i, url, fullskin); - if (lib.device == 'ios' || lib.device == 'android') { - window.resolveLocalFileSystemURL(nonameInitialized + 'extension/' + name, function (entry) { - entry.getFile(file, {}, function (fileEntry) { - fileEntry.file(function (fileToLoad) { - var fileReader = new FileReader(); - fileReader.onload = function (e) { - page.content.image[file] = e.target.result; - }; - fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + if (lib.device == "ios" || lib.device == "android") { + window.resolveLocalFileSystemURL( + nonameInitialized + "extension/" + name, + function (entry) { + entry.getFile(file, {}, function (fileEntry) { + fileEntry.file(function (fileToLoad) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + page.content.image[file] = e.target.result; + }; + fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); + }); }); - }); - }); - } - else { + } + ); + } else { loadImage(file, url); } - } - else game.getDB('image', `extension-${name}:${file}`).then(value => { - createButton(i, value, fullskin); - loadImage(file, value); - }); + } else + game.getDB("image", `extension-${name}:${file}`).then((value) => { + createButton(i, value, fullskin); + loadImage(file, value); + }); } - } - else { + } else { page.content = { pack: { card: {}, - translate: {} + translate: {}, }, - image: {} + image: {}, }; - toggle.classList.add('on'); - newCard.style.display = ''; + toggle.classList.add("on"); + newCard.style.display = ""; } updatePile(); }; - ui.create.div('.config.more.margin-bottom', '
                                      返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); + ui.create.div( + ".config.more.margin-bottom", + '
                                      返回', + page, + function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + } + ); page.content = { pack: { card: {}, translate: {}, - list: [] + list: [], }, - image: {} + image: {}, }; var newCard; - var toggle = ui.create.div('.config.more.on', '创建卡牌
                                      >
                                      ', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newCard.style.display = ''; - } - else { - newCard.style.display = 'none'; + var toggle = ui.create.div(".config.more.on", "创建卡牌
                                      >
                                      ", page, function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + newCard.style.display = ""; + } else { + newCard.style.display = "none"; } }); var resetEditor = function () { currentButton = null; - toggle.classList.remove('on'); - newCard.style.display = 'none'; - fakeme.classList.remove('inited'); - fakeme.classList.add('fullskin'); + toggle.classList.remove("on"); + newCard.style.display = "none"; + fakeme.classList.remove("inited"); + fakeme.classList.add("fullskin"); delete fakeme.image; delete fakeme.image64; - fakeme.style.backgroundImage = ''; - fakeme.imagenode.style.backgroundImage = ''; - var inputs = newCard.querySelectorAll('input'); + fakeme.style.backgroundImage = ""; + fakeme.imagenode.style.backgroundImage = ""; + var inputs = newCard.querySelectorAll("input"); for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; + inputs[i].value = ""; } - toggle.innerHTML = '创建卡牌
                                      >
                                      '; - editnode.innerHTML = '创建卡牌'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; + toggle.innerHTML = "创建卡牌
                                      >
                                      "; + editnode.innerHTML = "创建卡牌"; + editnode.classList.add("disabled"); + delnode.innerHTML = "取消"; delete delnode.button; - container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + container.code = + 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; }; - newCard = ui.create.div('.new_character', page); - newCard.style.height = '173px'; - var fakeme = ui.create.div('.card.fullskin', newCard); + newCard = ui.create.div(".new_character", page); + newCard.style.height = "173px"; + var fakeme = ui.create.div(".card.fullskin", newCard); - var input = document.createElement('input'); - input.type = 'file'; - input.accept = 'image/*'; - input.className = 'fileinput'; + var input = document.createElement("input"); + input.type = "file"; + input.accept = "image/*"; + input.className = "fileinput"; input.onchange = function () { var fileToLoad = input.files[0]; if (fileToLoad) { var fileReader = new FileReader(); - var fullimage = (fileToLoad.name.includes('.jpg')); + var fullimage = fileToLoad.name.includes(".jpg"); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; if (fullimage) { - fakeme.imagenode.style.backgroundImage = ''; - fakeme.style.backgroundImage = 'url(' + data + ')'; - fakeme.classList.remove('fullskin'); - } - else { - fakeme.style.backgroundImage = ''; - fakeme.imagenode.style.backgroundImage = 'url(' + data + ')'; - fakeme.classList.add('fullskin'); + fakeme.imagenode.style.backgroundImage = ""; + fakeme.style.backgroundImage = "url(" + data + ")"; + fakeme.classList.remove("fullskin"); + } else { + fakeme.style.backgroundImage = ""; + fakeme.imagenode.style.backgroundImage = "url(" + data + ")"; + fakeme.classList.add("fullskin"); } fakeme.image64 = data; - fakeme.classList.add('inited'); + fakeme.classList.add("inited"); var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { fakeme.image = fileLoadedEvent.target.result; @@ -1446,30 +1547,38 @@ export const extensionMenu = function (connectMenu) { }; fakeme.appendChild(input); - fakeme.imagenode = ui.create.div('.image', fakeme); - ui.create.div('.name', '选择背景', fakeme); + fakeme.imagenode = ui.create.div(".image", fakeme); + ui.create.div(".name", "选择背景", fakeme); - ui.create.div('.indent', '名称:', newCard).style.paddingTop = '8px'; - ui.create.div('.indent', '描述:', newCard).style.paddingTop = '6px'; - newCard.querySelector('input.new_name').onblur = updateButton; - var codeButton = document.createElement('button'); + ui.create.div( + ".indent", + '名称:', + newCard + ).style.paddingTop = "8px"; + ui.create.div( + ".indent", + '描述:', + newCard + ).style.paddingTop = "6px"; + newCard.querySelector("input.new_name").onblur = updateButton; + var codeButton = document.createElement("button"); newCard.appendChild(codeButton); - codeButton.innerHTML = '编辑代码'; - codeButton.style.left = '123px'; - codeButton.style.top = '66px'; - codeButton.style.position = 'absolute'; + codeButton.innerHTML = "编辑代码"; + codeButton.style.left = "123px"; + codeButton.style.top = "66px"; + codeButton.style.position = "absolute"; - var citeButton = document.createElement('button'); + var citeButton = document.createElement("button"); newCard.appendChild(citeButton); - citeButton.innerHTML = '引用代码'; - citeButton.style.left = '123px'; - citeButton.style.top = '90px'; - citeButton.style.position = 'absolute'; + citeButton.innerHTML = "引用代码"; + citeButton.style.left = "123px"; + citeButton.style.top = "90px"; + citeButton.style.position = "absolute"; citeButton.onclick = function () { - codeButton.style.display = 'none'; - citeButton.style.display = 'none'; - selectname.style.display = ''; - confirmcontainer.style.display = ''; + codeButton.style.display = "none"; + citeButton.style.display = "none"; + selectname.style.display = ""; + confirmcontainer.style.display = ""; }; var list = []; @@ -1479,13 +1588,15 @@ export const extensionMenu = function (connectMenu) { } } list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); + a = a[0]; + b = b[0]; + var aa = a, + bb = b; + if (aa.includes("_")) { + aa = aa.slice(aa.indexOf("_") + 1); } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); + if (bb.includes("_")) { + bb = bb.slice(bb.indexOf("_") + 1); } if (aa != bb) { return aa > bb ? 1 : -1; @@ -1493,255 +1604,256 @@ export const extensionMenu = function (connectMenu) { return a > b ? 1 : -1; }); var selectname = ui.create.selectlist(list, list[0], newCard); - selectname.style.left = '123px'; - selectname.style.top = '66px'; - selectname.style.position = 'absolute'; - selectname.style.display = 'none'; + selectname.style.left = "123px"; + selectname.style.top = "66px"; + selectname.style.position = "absolute"; + selectname.style.display = "none"; var confirmcontainer = ui.create.div(newCard); - confirmcontainer.style.left = '123px'; - confirmcontainer.style.top = '90px'; - confirmcontainer.style.position = 'absolute'; - confirmcontainer.style.display = 'none'; + confirmcontainer.style.left = "123px"; + confirmcontainer.style.top = "90px"; + confirmcontainer.style.position = "absolute"; + confirmcontainer.style.display = "none"; - var citeconfirm = document.createElement('button'); - citeconfirm.innerHTML = '引用'; + var citeconfirm = document.createElement("button"); + citeconfirm.innerHTML = "引用"; confirmcontainer.appendChild(citeconfirm); citeconfirm.onclick = function () { - codeButton.style.display = ''; - citeButton.style.display = ''; - selectname.style.display = 'none'; - confirmcontainer.style.display = 'none'; - container.code = 'card=' + get.stringify(lib.card[selectname.value]); + codeButton.style.display = ""; + citeButton.style.display = ""; + selectname.style.display = "none"; + confirmcontainer.style.display = "none"; + container.code = "card=" + get.stringify(lib.card[selectname.value]); codeButton.onclick.call(codeButton); - if (lib.translate[selectname.value + '_info']) { - newCard.querySelector('input.new_description').value = lib.translate[selectname.value + '_info']; + if (lib.translate[selectname.value + "_info"]) { + newCard.querySelector("input.new_description").value = + lib.translate[selectname.value + "_info"]; } }; - var citecancel = document.createElement('button'); - citecancel.innerHTML = '取消'; - citecancel.style.marginLeft = '3px'; + var citecancel = document.createElement("button"); + citecancel.innerHTML = "取消"; + citecancel.style.marginLeft = "3px"; confirmcontainer.appendChild(citecancel); citecancel.onclick = function () { - codeButton.style.display = ''; - citeButton.style.display = ''; - selectname.style.display = 'none'; - confirmcontainer.style.display = 'none'; + codeButton.style.display = ""; + citeButton.style.display = ""; + selectname.style.display = "none"; + confirmcontainer.style.display = "none"; }; codeButton.onclick = function () { var node = container; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); window.saveNonameInput = saveInput; if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../../../../game/codemirror.js').then(() => { + import("../../../../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, editor); } } }; - var container = ui.create.div('.popup-container.editor'); + var container = ui.create.div(".popup-container.editor"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { var card = null; eval(code); - if (card == null || typeof card != 'object') { - throw ('err'); + if (card == null || typeof card != "object") { + throw "err"; } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } catch (e) { + if (e == "err") { + alert("代码格式有错误,请对比示例代码仔细检查"); + } else { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); } window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - dash2.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + dash2.link.classList.add("active"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; delete window.saveNonameInput; }; var editor = ui.create.editor(container, saveInput); - container.code = 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + container.code = + 'card={\n \n}\n\n/*\n示例:\ncard={\n type:"basic",\n enable:true,\n filterTarget:true,\n content:function(){\n target.draw()\n },\n ai:{\n order:1,\n result:{\n target:1\n }\n }\n}\n此例的效果为目标摸一张牌\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - var editnode = ui.create.div('.menubutton.large.new_card.disabled', '创建卡牌', newCard, function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写卡牌名\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - var info = page.querySelector('input.new_description').value; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.card[name] || page.content.pack.card[name]) { - alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); - return; - } - var extname; - if (currentButton.classList.contains('fullskin')) { - extname = '.png'; - } - else { - extname = '.jpg'; - } - page.content.image[name + extname] = page.content.image[currentButton.link + extname]; - delete page.content.image[currentButton.link + extname]; - delete page.content.pack.card[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - delete page.content.pack.translate[currentButton.link + '_info']; - currentButton.link = name; - } - } - else { - if (lib.card[name] || page.content.pack.card[name]) { - alert('卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一'); + var editnode = ui.create.div( + ".menubutton.large.new_card.disabled", + "创建卡牌", + newCard, + function () { + var name = page.querySelector("input.new_name").value; + if (!name) { + alert("请填写卡牌名\n提示:卡牌名格式为id+|+中文名,其中id必须惟一"); return; } - } - if (fakeme.image) { - if (fakeme.classList.contains('fullskin')) { - page.content.image[name + '.png'] = fakeme.image; - delete page.content.image[name + '.jpg']; - } - else { - page.content.image[name + '.jpg'] = fakeme.image; - delete page.content.image[name + '.png']; - } - } - else if (!fakeme.classList.contains('inited')) { - alert('请选择一个卡牌背景'); - return; - } - page.content.pack.translate[name] = translate; - page.content.pack.translate[name + '_info'] = info; - try { - var card = null; - eval(container.code); - if (card == null || typeof card != 'object') { - throw ('err'); - } - page.content.pack.card[name] = card; - } - catch (e) { - page.content.pack.card[name] = {}; - } - if (fakeme.classList.contains('inited')) { - if (fakeme.classList.contains('fullskin')) { - page.content.pack.card[name].fullskin = true; - delete page.content.pack.card[name].fullimage; - } - else { - page.content.pack.card[name].fullimage = true; - delete page.content.pack.card[name].fullskin; - } - } - if (this.innerHTML == '创建卡牌') { - createButton(name, fakeme.image64, fakeme.classList.contains('fullskin')); - } - else if (currentButton) { - if (fakeme.image64) { - if (fakeme.classList.contains('fullskin')) { - currentButton.style.color = ''; - currentButton.style.textShadow = ''; - currentButton.imagenode.style.backgroundImage = 'url(' + fakeme.image64 + ')'; - currentButton.style.backgroundImage = ''; - currentButton.style.backgroundSize = ''; - currentButton.classList.add('fullskin'); + name = name.split("|"); + var translate = name[1] || name[0]; + var info = page.querySelector("input.new_description").value; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.card[name] || page.content.pack.card[name]) { + alert( + "卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一" + ); + return; + } + var extname; + if (currentButton.classList.contains("fullskin")) { + extname = ".png"; + } else { + extname = ".jpg"; + } + page.content.image[name + extname] = + page.content.image[currentButton.link + extname]; + delete page.content.image[currentButton.link + extname]; + delete page.content.pack.card[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + delete page.content.pack.translate[currentButton.link + "_info"]; + currentButton.link = name; } - else { - currentButton.style.color = 'white'; - currentButton.style.textShadow = 'black 0 0 2px'; - currentButton.imagenode.style.backgroundImage = ''; - currentButton.style.backgroundImage = 'url(' + fakeme.image64 + ')'; - currentButton.style.backgroundSize = 'cover'; - currentButton.classList.remove('fullskin'); + } else { + if (lib.card[name] || page.content.pack.card[name]) { + alert( + "卡牌名与现有卡牌重复,请更改\n提示:卡牌名格式为id+|+中文名,其中id必须惟一" + ); + return; } } - currentButton.nodename.innerHTML = get.verticalStr(translate); - } - resetEditor(); - updatePile(); - dash2.link.classList.add('active'); - }); - var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { - this.button.remove(); - var name = this.button.link; - delete dash2.content.pack.card[name]; - delete dash2.content.pack.translate[name]; - delete dash2.content.pack.translate[name + '_info']; - delete dash2.content.image[name]; + if (fakeme.image) { + if (fakeme.classList.contains("fullskin")) { + page.content.image[name + ".png"] = fakeme.image; + delete page.content.image[name + ".jpg"]; + } else { + page.content.image[name + ".jpg"] = fakeme.image; + delete page.content.image[name + ".png"]; + } + } else if (!fakeme.classList.contains("inited")) { + alert("请选择一个卡牌背景"); + return; + } + page.content.pack.translate[name] = translate; + page.content.pack.translate[name + "_info"] = info; + try { + var card = null; + eval(container.code); + if (card == null || typeof card != "object") { + throw "err"; + } + page.content.pack.card[name] = card; + } catch (e) { + page.content.pack.card[name] = {}; + } + if (fakeme.classList.contains("inited")) { + if (fakeme.classList.contains("fullskin")) { + page.content.pack.card[name].fullskin = true; + delete page.content.pack.card[name].fullimage; + } else { + page.content.pack.card[name].fullimage = true; + delete page.content.pack.card[name].fullskin; + } + } + if (this.innerHTML == "创建卡牌") { + createButton(name, fakeme.image64, fakeme.classList.contains("fullskin")); + } else if (currentButton) { + if (fakeme.image64) { + if (fakeme.classList.contains("fullskin")) { + currentButton.style.color = ""; + currentButton.style.textShadow = ""; + currentButton.imagenode.style.backgroundImage = + "url(" + fakeme.image64 + ")"; + currentButton.style.backgroundImage = ""; + currentButton.style.backgroundSize = ""; + currentButton.classList.add("fullskin"); + } else { + currentButton.style.color = "white"; + currentButton.style.textShadow = "black 0 0 2px"; + currentButton.imagenode.style.backgroundImage = ""; + currentButton.style.backgroundImage = "url(" + fakeme.image64 + ")"; + currentButton.style.backgroundSize = "cover"; + currentButton.classList.remove("fullskin"); + } + } + currentButton.nodename.innerHTML = get.verticalStr(translate); + } + resetEditor(); updatePile(); - dash2.link.classList.add('active'); + dash2.link.classList.add("active"); } - resetEditor(); - }); + ); + var delnode = ui.create.div( + ".menubutton.large.new_card_delete", + "取消", + editnode.parentNode, + function () { + if (this.innerHTML == "删除") { + this.button.remove(); + var name = this.button.link; + delete dash2.content.pack.card[name]; + delete dash2.content.pack.translate[name]; + delete dash2.content.pack.translate[name + "_info"]; + delete dash2.content.image[name]; + updatePile(); + dash2.link.classList.add("active"); + } + resetEditor(); + } + ); var editPile; - var toggle2 = ui.create.div('.config.more', '编辑牌堆
                                      >
                                      ', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - editPile.style.display = ''; - } - else { - editPile.style.display = 'none'; + var toggle2 = ui.create.div(".config.more", "编辑牌堆
                                      >
                                      ", page, function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + editPile.style.display = ""; + } else { + editPile.style.display = "none"; } }); - editPile = ui.create.div('.edit_pile', page); - editPile.style.display = 'none'; + editPile = ui.create.div(".edit_pile", page); + editPile.style.display = "none"; - - var cardpileadd = ui.create.div('.config.toggle.cardpilecfg.cardpilecfgadd', editPile); + var cardpileadd = ui.create.div(".config.toggle.cardpilecfg.cardpilecfgadd", editPile); var pile = ui.create.div(editPile); page.pile = pile; - var cardpileaddname = document.createElement('select'); + var cardpileaddname = document.createElement("select"); var updatePile = function () { - cardpileaddname.innerHTML = ''; + cardpileaddname.innerHTML = ""; var list = []; var list2 = []; for (var i in page.content.pack.card) { @@ -1749,60 +1861,62 @@ export const extensionMenu = function (connectMenu) { list2.push(i); } if (list.length) { - toggle2.style.display = ''; - if (toggle2.classList.contains('on')) { - editPile.style.display = ''; - } - else { - editPile.style.display = 'none'; + toggle2.style.display = ""; + if (toggle2.classList.contains("on")) { + editPile.style.display = ""; + } else { + editPile.style.display = "none"; } for (var i = 0; i < list.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = list[i][0]; option.innerHTML = list[i][1]; cardpileaddname.appendChild(option); } for (var i = 0; i < pile.childNodes.length; i++) { if (!list2.includes(pile.childNodes[i].name)) { - pile.childNodes[i].remove(); i--; + pile.childNodes[i].remove(); + i--; } } - } - else { - toggle2.style.display = 'none'; - editPile.style.display = 'none'; - pile.innerHTML = ''; + } else { + toggle2.style.display = "none"; + editPile.style.display = "none"; + pile.innerHTML = ""; } }; updatePile(); cardpileadd.appendChild(cardpileaddname); - cardpileaddname.style.width = '75px'; - cardpileaddname.style.marginRight = '2px'; - cardpileaddname.style.marginLeft = '-1px'; - var cardpileaddsuit = ui.create.selectlist([ - ['heart', '红桃'], - ['diamond', '方片'], - ['club', '梅花'], - ['spade', '黑桃'], - ], null, cardpileadd); - cardpileaddsuit.style.width = '53px'; - cardpileaddsuit.style.marginRight = '2px'; - var cardpileaddnumber = ui.create.selectlist([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 - ], null, cardpileadd); - cardpileaddnumber.style.width = '43px'; - cardpileaddnumber.style.marginRight = '2px'; - var button = document.createElement('button'); - button.innerHTML = '确定'; - button.style.width = '40px'; + cardpileaddname.style.width = "75px"; + cardpileaddname.style.marginRight = "2px"; + cardpileaddname.style.marginLeft = "-1px"; + var cardpileaddsuit = ui.create.selectlist( + [ + ["heart", "红桃"], + ["diamond", "方片"], + ["club", "梅花"], + ["spade", "黑桃"], + ], + null, + cardpileadd + ); + cardpileaddsuit.style.width = "53px"; + cardpileaddsuit.style.marginRight = "2px"; + var cardpileaddnumber = ui.create.selectlist( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + null, + cardpileadd + ); + cardpileaddnumber.style.width = "43px"; + cardpileaddnumber.style.marginRight = "2px"; + var button = document.createElement("button"); + button.innerHTML = "确定"; + button.style.width = "40px"; button.onclick = function () { - var card = [ - cardpileaddsuit.value, - cardpileaddnumber.value, - cardpileaddname.value, - ]; - var node = document.createElement('button'); - node.innerHTML = page.content.pack.translate[card[2]] + ' ' + lib.translate[card[0]] + card[1]; + var card = [cardpileaddsuit.value, cardpileaddnumber.value, cardpileaddname.value]; + var node = document.createElement("button"); + node.innerHTML = + page.content.pack.translate[card[2]] + " " + lib.translate[card[0]] + card[1]; node.name = card[2]; node.link = card; pile.appendChild(node); @@ -1811,47 +1925,46 @@ export const extensionMenu = function (connectMenu) { }; }; cardpileadd.appendChild(button); - cardpileadd.style.whiteSpace = 'nowrap'; - cardpileadd.style.position = 'relative'; - cardpileadd.style.right = '-4px'; + cardpileadd.style.whiteSpace = "nowrap"; + cardpileadd.style.position = "relative"; + cardpileadd.style.right = "-4px"; return page; - }()); + })(); var dash3 = (function () { - var page = ui.create.div('.hidden.menu-buttons.new_skill'); + var page = ui.create.div(".hidden.menu-buttons.new_skill"); var updateButton = function () { - var name = page.querySelector('input.new_name').value; + var name = page.querySelector("input.new_name").value; if (!name) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } - name = name.split('|'); + name = name.split("|"); name = name[0]; if (currentButton) { if (currentButton.link != name) { if (lib.skill[name] || page.content.pack.skill[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } - } - else { + } else { if (lib.skill[name] || page.content.pack.skill[name]) { - editnode.classList.add('disabled'); + editnode.classList.add("disabled"); return; } } - editnode.classList.remove('disabled'); + editnode.classList.remove("disabled"); }; page.init = function () { - if (!page.querySelector('.menubutton:not(.large)')) { - toggle.classList.add('on'); - newSkill.style.display = ''; + if (!page.querySelector(".menubutton:not(.large)")) { + toggle.classList.add("on"); + newSkill.style.display = ""; } }; page.reset = function (name) { resetEditor(); - var buttons = page.querySelectorAll('.menubutton:not(.large)'); + var buttons = page.querySelectorAll(".menubutton:not(.large)"); var list = []; for (var i = 0; i < buttons.length; i++) { list.push(buttons[i]); @@ -1862,37 +1975,40 @@ export const extensionMenu = function (connectMenu) { if (lib.extensionPack[name]) { page.content.pack = lib.extensionPack[name].skill || { skill: {}, - translate: {} + translate: {}, }; page.content.audio = {}; for (var i in page.content.pack.skill) { createButton(i); } dash1.updateSkill(); - } - else { + } else { page.content = { pack: { skill: {}, - translate: {} + translate: {}, }, - audio: {} + audio: {}, }; - toggle.classList.add('on'); - newSkill.style.display = ''; + toggle.classList.add("on"); + newSkill.style.display = ""; } }; - ui.create.div('.config.more.margin-bottom', '
                                      返回', page, function () { - ui.create.templayer(); - page.hide(); - if (page.fromchar) { - dash1.show(); - delete page.fromchar; + ui.create.div( + ".config.more.margin-bottom", + '
                                      返回', + page, + function () { + ui.create.templayer(); + page.hide(); + if (page.fromchar) { + dash1.show(); + delete page.fromchar; + } else { + pageboard.show(); + } } - else { - pageboard.show(); - } - }); + ); var currentButton = null; var clickButton = function () { if (currentButton == this) { @@ -1901,158 +2017,169 @@ export const extensionMenu = function (connectMenu) { } resetEditor(); currentButton = this; - toggle.classList.add('on'); - newSkill.style.display = ''; + toggle.classList.add("on"); + newSkill.style.display = ""; if (page.content.pack.translate[this.link] != this.link) { - newSkill.querySelector('.new_name').value = this.link + '|' + page.content.pack.translate[this.link]; + newSkill.querySelector(".new_name").value = + this.link + "|" + page.content.pack.translate[this.link]; + } else { + newSkill.querySelector(".new_name").value = this.link; } - else { - newSkill.querySelector('.new_name').value = this.link; - } - newSkill.querySelector('.new_description').value = page.content.pack.translate[this.link + '_info']; + newSkill.querySelector(".new_description").value = + page.content.pack.translate[this.link + "_info"]; var info = page.content.pack.skill[this.link]; - container.code = 'skill=' + get.stringify(Object.defineProperty({ ...info }, '_priority', { enumerable: false, writable: true, configurable: true })); - toggle.innerHTML = '编辑技能
                                      >
                                      '; - editnode.innerHTML = '编辑技能'; - editnode.classList.remove('disabled'); + container.code = + "skill=" + + get.stringify( + Object.defineProperty({ ...info }, "_priority", { + enumerable: false, + writable: true, + configurable: true, + }) + ); + toggle.innerHTML = "编辑技能
                                      >
                                      "; + editnode.innerHTML = "编辑技能"; + editnode.classList.remove("disabled"); delnode.button = this; - delnode.innerHTML = '删除'; + delnode.innerHTML = "删除"; }; var createButton = function (name) { - var button = ui.create.div('.menubutton'); + var button = ui.create.div(".menubutton"); button.link = name; button.innerHTML = page.content.pack.translate[name]; button.listen(clickButton); page.insertBefore(button, page.childNodes[1]); }; var newSkill; - var toggle = ui.create.div('.config.more.on', '创建技能
                                      >
                                      ', page, function () { - this.classList.toggle('on'); - if (this.classList.contains('on')) { - newSkill.style.display = ''; - } - else { - newSkill.style.display = 'none'; + var toggle = ui.create.div(".config.more.on", "创建技能
                                      >
                                      ", page, function () { + this.classList.toggle("on"); + if (this.classList.contains("on")) { + newSkill.style.display = ""; + } else { + newSkill.style.display = "none"; } }); page.toggle = toggle; var resetEditor = function () { currentButton = null; - toggle.classList.remove('on'); - newSkill.style.display = 'none'; - var inputs = newSkill.querySelectorAll('input'); + toggle.classList.remove("on"); + newSkill.style.display = "none"; + var inputs = newSkill.querySelectorAll("input"); for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; + inputs[i].value = ""; } - var inputs = newSkill.querySelectorAll('textarea'); + var inputs = newSkill.querySelectorAll("textarea"); for (var i = 0; i < inputs.length; i++) { - inputs[i].value = ''; + inputs[i].value = ""; } - toggle.innerHTML = '创建技能
                                      >
                                      '; - editnode.innerHTML = '创建技能'; - editnode.classList.add('disabled'); - delnode.innerHTML = '取消'; + toggle.innerHTML = "创建技能
                                      >
                                      "; + editnode.innerHTML = "创建技能"; + editnode.classList.add("disabled"); + delnode.innerHTML = "取消"; delete delnode.button; - container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - if (page.fromchar == 'add') { + container.code = + 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + if (page.fromchar == "add") { page.fromchar = true; } }; - newSkill = ui.create.div('.new_character.new_skill', page); + newSkill = ui.create.div(".new_character.new_skill", page); page.newSkill = newSkill; - var namenode = ui.create.div('.config', '名称:', newSkill); - var descnode = ui.create.div('.config', '描述:', newSkill); - namenode.querySelector('input.new_name').onblur = updateButton; - var commandline = ui.create.div('.config', newSkill); - var editbutton = document.createElement('button'); - editbutton.innerHTML = '编辑代码'; + var namenode = ui.create.div( + ".config", + '名称:', + newSkill + ); + var descnode = ui.create.div( + ".config", + '描述:', + newSkill + ); + namenode.querySelector("input.new_name").onblur = updateButton; + var commandline = ui.create.div(".config", newSkill); + var editbutton = document.createElement("button"); + editbutton.innerHTML = "编辑代码"; commandline.appendChild(editbutton); editbutton.onclick = function () { var node = container; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); window.saveNonameInput = saveInput; if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../../../../game/codemirror.js').then(() => { + import("../../../../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, editor); } } }; - var container = ui.create.div('.popup-container.editor'); + var container = ui.create.div(".popup-container.editor"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { var skill = null; eval(code); - if (skill == null || typeof skill != 'object') { - throw ('err'); + if (skill == null || typeof skill != "object") { + throw "err"; } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } catch (e) { + if (e == "err") { + alert("代码格式有错误,请对比示例代码仔细检查"); + } else { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); } window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - dash3.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + dash3.link.classList.add("active"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; delete window.saveNonameInput; }; var editor = ui.create.editor(container, saveInput); - container.code = 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + container.code = + 'skill={\n \n}\n\n/*\n示例:\nskill={\n trigger:{player:"phaseJieshuBegin"},\n frequent:true,\n content:function(){\n player.draw()\n }\n}\n此例为闭月代码\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - var citebutton = document.createElement('button'); - citebutton.innerHTML = '引用代码'; + var citebutton = document.createElement("button"); + citebutton.innerHTML = "引用代码"; commandline.appendChild(citebutton); citebutton.onclick = function () { - editbutton.style.display = 'none'; - citebutton.style.display = 'none'; - selectname.style.display = ''; - skillopt.style.display = ''; - addSkillButton.style.display = ''; - cancelSkillButton.style.display = ''; + editbutton.style.display = "none"; + citebutton.style.display = "none"; + selectname.style.display = ""; + skillopt.style.display = ""; + addSkillButton.style.display = ""; + cancelSkillButton.style.display = ""; }; var list = []; @@ -2062,20 +2189,22 @@ export const extensionMenu = function (connectMenu) { } } list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); + a = a[0]; + b = b[0]; + var aa = a, + bb = b; + if (aa.includes("_")) { + aa = aa.slice(aa.indexOf("_") + 1); } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); + if (bb.includes("_")) { + bb = bb.slice(bb.indexOf("_") + 1); } if (aa != bb) { return aa > bb ? 1 : -1; } return a > b ? 1 : -1; }); - list.push(['others', '其它']); + list.push(["others", "其它"]); var list2 = []; var skills = lib.character[list[0][0]][3]; for (var i = 0; i < skills.length; i++) { @@ -2084,7 +2213,7 @@ export const extensionMenu = function (connectMenu) { var selectname = ui.create.selectlist(list, list[0], commandline); var list3 = []; for (var i in lib.skill) { - if (i != 'global' && !get.is.empty(lib.skill[i]) && !lib.skilllist.includes(i)) { + if (i != "global" && !get.is.empty(lib.skill[i]) && !lib.skilllist.includes(i)) { list3.push(i); } } @@ -2093,249 +2222,273 @@ export const extensionMenu = function (connectMenu) { }); selectname.onchange = function () { var skills; - skillopt.innerHTML = ''; - if (this.value == 'others') { + skillopt.innerHTML = ""; + if (this.value == "others") { skills = list3; for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = skills[i]; option.innerHTML = skills[i]; skillopt.appendChild(option); } - } - else { + } else { skills = lib.character[this.value][3]; for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = skills[i]; option.innerHTML = lib.translate[skills[i]]; skillopt.appendChild(option); } } }; - selectname.style.display = 'none'; - selectname.style.maxWidth = '80px'; + selectname.style.display = "none"; + selectname.style.maxWidth = "80px"; var skillopt = ui.create.selectlist(list2, list2[0], commandline); - skillopt.style.display = 'none'; - skillopt.style.maxWidth = '60px'; - var addSkillButton = document.createElement('button'); - addSkillButton.style.display = 'none'; - addSkillButton.innerHTML = '引用'; + skillopt.style.display = "none"; + skillopt.style.maxWidth = "60px"; + var addSkillButton = document.createElement("button"); + addSkillButton.style.display = "none"; + addSkillButton.innerHTML = "引用"; commandline.appendChild(addSkillButton); addSkillButton.onclick = function () { - editbutton.style.display = ''; - citebutton.style.display = ''; - selectname.style.display = 'none'; - skillopt.style.display = 'none'; - addSkillButton.style.display = 'none'; - cancelSkillButton.style.display = 'none'; - container.code = 'skill=' + get.stringify(Object.defineProperty({ ...lib.skill[skillopt.value] }, '_priority', { enumerable: false, writable: true, configurable: true })); + editbutton.style.display = ""; + citebutton.style.display = ""; + selectname.style.display = "none"; + skillopt.style.display = "none"; + addSkillButton.style.display = "none"; + cancelSkillButton.style.display = "none"; + container.code = + "skill=" + + get.stringify( + Object.defineProperty({ ...lib.skill[skillopt.value] }, "_priority", { + enumerable: false, + writable: true, + configurable: true, + }) + ); editbutton.onclick.call(editbutton); - if (lib.translate[skillopt.value + '_info']) { - newSkill.querySelector('input.new_description').value = lib.translate[skillopt.value + '_info']; + if (lib.translate[skillopt.value + "_info"]) { + newSkill.querySelector("input.new_description").value = + lib.translate[skillopt.value + "_info"]; } }; - var cancelSkillButton = document.createElement('button'); - cancelSkillButton.style.display = 'none'; - cancelSkillButton.innerHTML = '取消'; + var cancelSkillButton = document.createElement("button"); + cancelSkillButton.style.display = "none"; + cancelSkillButton.innerHTML = "取消"; commandline.appendChild(cancelSkillButton); cancelSkillButton.onclick = function () { - editbutton.style.display = ''; - citebutton.style.display = ''; - selectname.style.display = 'none'; - skillopt.style.display = 'none'; - addSkillButton.style.display = 'none'; - cancelSkillButton.style.display = 'none'; + editbutton.style.display = ""; + citebutton.style.display = ""; + selectname.style.display = "none"; + skillopt.style.display = "none"; + addSkillButton.style.display = "none"; + cancelSkillButton.style.display = "none"; }; - var editnode = ui.create.div('.menubutton.large.new_skill.disabled', '创建技能', function () { - var name = page.querySelector('input.new_name').value; - if (!name) { - alert('请填写技能名\n提示:技能名格式为id+|+中文名,其中id必须惟一'); - return; - } - name = name.split('|'); - var translate = name[1] || name[0]; - var info = page.querySelector('input.new_description').value; - name = name[0]; - if (currentButton) { - if (currentButton.link != name) { - if (lib.skill[name] || page.content.pack.skill[name]) { - alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); - return; - } - delete page.content.pack.skill[currentButton.link]; - delete page.content.pack.translate[currentButton.link]; - delete page.content.pack.translate[currentButton.link + '_info']; - currentButton.link = name; - } - } - else { - if (lib.skill[name] || page.content.pack.skill[name]) { - alert('技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一'); + var editnode = ui.create.div( + ".menubutton.large.new_skill.disabled", + "创建技能", + function () { + var name = page.querySelector("input.new_name").value; + if (!name) { + alert("请填写技能名\n提示:技能名格式为id+|+中文名,其中id必须惟一"); return; } - } - page.content.pack.translate[name] = translate; - page.content.pack.translate[name + '_info'] = info; - try { - var skill = null; - eval(container.code); - if (skill == null || typeof skill != 'object') { - throw ('err'); + name = name.split("|"); + var translate = name[1] || name[0]; + var info = page.querySelector("input.new_description").value; + name = name[0]; + if (currentButton) { + if (currentButton.link != name) { + if (lib.skill[name] || page.content.pack.skill[name]) { + alert( + "技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一" + ); + return; + } + delete page.content.pack.skill[currentButton.link]; + delete page.content.pack.translate[currentButton.link]; + delete page.content.pack.translate[currentButton.link + "_info"]; + currentButton.link = name; + } + } else { + if (lib.skill[name] || page.content.pack.skill[name]) { + alert( + "技能名与现有技能重复,请更改\n提示:技能名格式为id+|+中文名,其中id必须惟一" + ); + return; + } } - page.content.pack.skill[name] = skill; - } - catch (e) { - page.content.pack.skill[name] = {}; - } - dash1.selectname.value = 'current_extension'; - dash1.selectname.onchange.call(dash1.selectname); - if (this.innerHTML == '创建技能') { - createButton(name); - if (page.fromchar == 'add') { + page.content.pack.translate[name] = translate; + page.content.pack.translate[name + "_info"] = info; + try { + var skill = null; + eval(container.code); + if (skill == null || typeof skill != "object") { + throw "err"; + } + page.content.pack.skill[name] = skill; + } catch (e) { + page.content.pack.skill[name] = {}; + } + dash1.selectname.value = "current_extension"; + dash1.selectname.onchange.call(dash1.selectname); + if (this.innerHTML == "创建技能") { + createButton(name); + if (page.fromchar == "add") { + ui.create.templayer(); + page.hide(); + dash1.show(); + dash1.skillopt.value = name; + dash1.addSkillButton.onclick(); + delete page.fromchar; + } + } else if (currentButton) { + currentButton.innerHTML = translate; + } + resetEditor(); + dash3.link.classList.add("active"); + dash1.updateSkill(); + }, + newSkill + ); + var delnode = ui.create.div( + ".menubutton.large.new_card_delete", + "取消", + editnode.parentNode, + function () { + if (this.innerHTML == "删除") { + this.button.remove(); + var name = this.button.link; + delete dash3.content.pack.skill[name]; + delete dash3.content.pack.translate[name]; + delete dash3.content.pack.translate[name + "_info"]; + dash3.link.classList.add("active"); + if (get.is.empty(dash3.content.pack.skill)) { + dash1.selectname.value = dash1.selectname.childNodes[1].value; + } + dash1.selectname.onchange.call(dash1.selectname); + dash1.updateSkill(); + resetEditor(); + } else if (page.fromchar == "add") { ui.create.templayer(); page.hide(); dash1.show(); - dash1.skillopt.value = name; - dash1.addSkillButton.onclick(); delete page.fromchar; + setTimeout(resetEditor, 600); + } else { + resetEditor(); } } - else if (currentButton) { - currentButton.innerHTML = translate; - } - resetEditor(); - dash3.link.classList.add('active'); - dash1.updateSkill(); - }, newSkill); - var delnode = ui.create.div('.menubutton.large.new_card_delete', '取消', editnode.parentNode, function () { - if (this.innerHTML == '删除') { - this.button.remove(); - var name = this.button.link; - delete dash3.content.pack.skill[name]; - delete dash3.content.pack.translate[name]; - delete dash3.content.pack.translate[name + '_info']; - dash3.link.classList.add('active'); - if (get.is.empty(dash3.content.pack.skill)) { - dash1.selectname.value = dash1.selectname.childNodes[1].value; - } - dash1.selectname.onchange.call(dash1.selectname); - dash1.updateSkill(); - resetEditor(); - } - else if (page.fromchar == 'add') { - ui.create.templayer(); - page.hide(); - dash1.show(); - delete page.fromchar; - setTimeout(resetEditor, 600); - } - else { - resetEditor(); - } - }); + ); page.content = { pack: { skill: {}, - translate: {} + translate: {}, }, - audio: {} + audio: {}, }; return page; - }()); + })(); var dash4 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - ui.create.div('.config.more.margin-bottom', '
                                      返回', page, function () { - ui.create.templayer(); - page.hide(); - pageboard.show(); - }); + var page = ui.create.div(".hidden.menu-buttons"); + ui.create.div( + ".config.more.margin-bottom", + '
                                      返回', + page, + function () { + ui.create.templayer(); + page.hide(); + pageboard.show(); + } + ); page.reset = function (name) { page.content = {}; if (lib.extensionPack[name]) { for (var i in dashes) { - dashes[i].node.code = ''; + dashes[i].node.code = ""; } for (var i in lib.extensionPack[name].code) { switch (typeof lib.extensionPack[name].code[i]) { - case 'function': page.content[i] = lib.extensionPack[name].code[i].toString(); break; - case 'object': page.content[i] = i + '=' + get.stringify(lib.extensionPack[name].code[i]); break; + case "function": + page.content[i] = lib.extensionPack[name].code[i].toString(); + break; + case "object": + page.content[i] = + i + "=" + get.stringify(lib.extensionPack[name].code[i]); + break; } } for (var i in page.content) { - dashes[i].node.code = page.content[i] || ''; + dashes[i].node.code = page.content[i] || ""; } - } - else { - dashes.content.node.code = 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.precontent.node.code = 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.config.node.code = 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; - dashes.help.node.code = 'help={\n \n}\n\ns/*\n示例:\nhelp={\n "帮助条目":"
                                      • 列表1-条目1
                                      • 列表1-条目2
                                      1. 列表2-条目1
                                      2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + } else { + dashes.content.node.code = + "function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/"; + dashes.precontent.node.code = + "function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/"; + dashes.config.node.code = + 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; + dashes.help.node.code = + 'help={\n \n}\n\ns/*\n示例:\nhelp={\n "帮助条目":"
                                        • 列表1-条目1
                                        • 列表1-条目2
                                        1. 列表2-条目1
                                        2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'; } }; var dashes = {}; var createCode = function (str1, str2, sub, func, link, str) { - var dash = ui.create.div('.menubutton.large.dashboard'); + var dash = ui.create.div(".menubutton.large.dashboard"); dashes[link] = dash; sub.appendChild(dash); dash.listen(func); dash.link = link; - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); - var container = ui.create.div('.popup-container.editor'); + ui.create.div("", str1, dash); + ui.create.div("", str2, dash); + var container = ui.create.div(".popup-container.editor"); var saveInput = function () { var code; if (container.editor) { code = container.editor.getValue(); - } - else if (container.textarea) { + } else if (container.textarea) { code = container.textarea.value; } try { - if (link == 'content' || link == 'precontent') { + if (link == "content" || link == "precontent") { var func = null; - eval('func=' + code); - if (typeof func != 'function') { - throw ('err'); + eval("func=" + code); + if (typeof func != "function") { + throw "err"; } - } - else if (link == 'config') { + } else if (link == "config") { var config = null; eval(code); - if (config == null || typeof config != 'object') { - throw ('err'); + if (config == null || typeof config != "object") { + throw "err"; } - } - else if (link == 'help') { + } else if (link == "help") { var help = null; eval(code); - if (help == null || typeof help != 'object') { - throw ('err'); + if (help == null || typeof help != "object") { + throw "err"; } } - } - catch (e) { - if (e == 'err') { - alert('代码格式有错误,请对比示例代码仔细检查'); - } - else { - var tip = lib.getErrorTip(e) || ''; - alert('代码语法有错误,请仔细检查(' + e + ')' + tip); + } catch (e) { + if (e == "err") { + alert("代码格式有错误,请对比示例代码仔细检查"); + } else { + var tip = lib.getErrorTip(e) || ""; + alert("代码语法有错误,请仔细检查(" + e + ")" + tip); } window.focus(); if (container.editor) { container.editor.focus(); - } - else if (container.textarea) { + } else if (container.textarea) { container.textarea.focus(); } return; } - dash4.link.classList.add('active'); - ui.window.classList.remove('shortcutpaused'); - ui.window.classList.remove('systempaused'); + dash4.link.classList.add("active"); + ui.window.classList.remove("shortcutpaused"); + ui.window.classList.remove("systempaused"); container.delete(); container.code = code; page.content[link] = code; @@ -2350,54 +2503,79 @@ export const extensionMenu = function (connectMenu) { }; var clickCode = function () { var node = this.node; - ui.window.classList.add('shortcutpaused'); - ui.window.classList.add('systempaused'); + ui.window.classList.add("shortcutpaused"); + ui.window.classList.add("systempaused"); window.saveNonameInput = this.saveInput; if (node.aced) { ui.window.appendChild(node); node.editor.setValue(node.code, 1); - } - else if (lib.device == 'ios') { + } else if (lib.device == "ios") { ui.window.appendChild(node); if (!node.textarea) { - var textarea = document.createElement('textarea'); + var textarea = document.createElement("textarea"); this.editor.appendChild(textarea); node.textarea = textarea; lib.setScroll(textarea); } node.textarea.value = node.code; - } - else { + } else { if (!window.CodeMirror) { - import('../../../../../game/codemirror.js').then(() => { + import("../../../../../game/codemirror.js").then(() => { lib.codeMirrorReady(node, this.editor); }); - lib.init.css(lib.assetURL + 'layout/default', 'codemirror'); - } - else { + lib.init.css(lib.assetURL + "layout/default", "codemirror"); + } else { lib.codeMirrorReady(node, this.editor); } } }; page.content = {}; - createCode('主', '主代码', page, clickCode, 'content', 'function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('启', '启动代码', page, clickCode, 'precontent', 'function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('选', '选项代码', page, clickCode, 'config', 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); - createCode('帮', '帮助代码', page, clickCode, 'help', 'help={\n \n}\n\n/*\n示例:\nhelp={\n "帮助条目":"
                                          • 列表1-条目1
                                          • 列表1-条目2
                                          1. 列表2-条目1
                                          2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/'); + createCode( + "主", + "主代码", + page, + clickCode, + "content", + "function(config,pack){\n \n}\n\n/*\n函数执行时机为游戏数据加载之后、界面加载之前\n参数1扩展选项(见选项代码);参数2为扩展定义的武将、卡牌和技能等(可在此函数中修改)\n导出时本段代码中的换行、缩进以及注释将被清除\n*/" + ); + createCode( + "启", + "启动代码", + page, + clickCode, + "precontent", + "function(){\n \n}\n\n/*\n函数执行时机为游戏数据加载之前,且不受禁用扩展的限制\n除添加模式外请慎用\n导出时本段代码中的换行、缩进以及注释将被清除\n*/" + ); + createCode( + "选", + "选项代码", + page, + clickCode, + "config", + 'config={\n \n}\n\n/*\n示例:\nconfig={\n switcher_example:{\n name:"示例列表选项",\n init:"3",\n item:{"1":"一","2":"二","3":"三"}\n },\n toggle_example:{\n name:"示例开关选项",\n init:true\n }\n}\n此例中传入的主代码函数的默认参数为{switcher_example:"3",toggle_example:true}\n导出时本段代码中的换行、缩进以及注释将被清除\n*/' + ); + createCode( + "帮", + "帮助代码", + page, + clickCode, + "help", + 'help={\n \n}\n\n/*\n示例:\nhelp={\n "帮助条目":"
                                            • 列表1-条目1
                                            • 列表1-条目2
                                            1. 列表2-条目1
                                            2. 列表2-条目2"\n}\n帮助内容将显示在菜单-选项-帮助中\n导出时本段代码中的换行、缩进以及注释将被清除\n*/' + ); return page; - }()); - createDash('将', '编辑武将', dash1); - createDash('卡', '编辑卡牌', dash2); - createDash('技', '编辑技能', dash3); - createDash('码', '编辑代码', dash4); + })(); + createDash("将", "编辑武将", dash1); + createDash("卡", "编辑卡牌", dash2); + createDash("技", "编辑技能", dash3); + createDash("码", "编辑代码", dash4); }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); + if (!get.config("menu_loadondemand")) node._initLink(); + })(); (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '获取扩展', start.firstChild, clickMode); - node.mode = 'get'; + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "获取扩展", start.firstChild, clickMode); + node.mode = "get"; var _thisUpdate = false; node.update = function () { _thisUpdate = true; @@ -2406,48 +2584,52 @@ export const extensionMenu = function (connectMenu) { node.link = page; page.listen(function () { if (!page.currenttimeout) { - var active = page.querySelector('.videonode.current'); + var active = page.querySelector(".videonode.current"); if (active) { - active.classList.remove('current'); + active.classList.remove("current"); } } }); var importextensionexpanded = false; - page.style.paddingBottom = '10px'; + page.style.paddingBottom = "10px"; var importExtension; - var extensionNode = ui.create.div('.config.more', '导入扩展
                                              >
                                              ', page, function () { + var extensionNode = ui.create.div(".config.more", "导入扩展
                                              >
                                              ", page, function () { if (importextensionexpanded) { - this.classList.remove('on'); - importExtension.style.display = 'none'; - } - else { - this.classList.add('on'); - importExtension.style.display = ''; + this.classList.remove("on"); + importExtension.style.display = "none"; + } else { + this.classList.add("on"); + importExtension.style.display = ""; } importextensionexpanded = !importextensionexpanded; }); - importExtension = ui.create.div('.new_character.export.import', page); - importExtension.style.marginLeft = '5px'; - importExtension.style.marginTop = '5px'; - importExtension.style.marginBottom = '5px'; - importExtension.style.display = 'none'; - importExtension.style.width = '100%'; - importExtension.style.textAlign = 'left'; - ui.create.div('', '', importExtension); - ui.create.div('.config', '修改下载地址', page, function () { - alert('您可以在“设置→通用→获取扩展地址”中,修改下载扩展时所采用的地址。'); + importExtension = ui.create.div(".new_character.export.import", page); + importExtension.style.marginLeft = "5px"; + importExtension.style.marginTop = "5px"; + importExtension.style.marginBottom = "5px"; + importExtension.style.display = "none"; + importExtension.style.width = "100%"; + importExtension.style.textAlign = "left"; + ui.create.div( + "", + '', + importExtension + ); + ui.create.div(".config", "修改下载地址", page, function () { + alert("您可以在“设置→通用→获取扩展地址”中,修改下载扩展时所采用的地址。"); }); var extensionURL; - var source = lib.config.extension_sources, index = lib.config.extension_source; + var source = lib.config.extension_sources, + index = lib.config.extension_source; if (source && source[index]) extensionURL = source[index]; - else extensionURL = lib.updateURL.replace(/noname/g, 'noname-extension') + '/master/'; + else extensionURL = lib.updateURL.replace(/noname/g, "noname-extension") + "/master/"; - var reloadnode = ui.create.div('.config.toggle.pointerdiv', '重新启动', page, game.reload); - reloadnode.style.display = 'none'; - var placeholder = ui.create.div('.config.toggle', page); + var reloadnode = ui.create.div(".config.toggle.pointerdiv", "重新启动", page, game.reload); + reloadnode.style.display = "none"; + var placeholder = ui.create.div(".config.toggle", page); placeholder.style.height = 0; - placeholder.style.marginTop = '5px'; + placeholder.style.marginTop = "5px"; importExtension.firstChild.lastChild.onclick = function () { const fileToLoad = this.previousSibling.files[0]; @@ -2457,34 +2639,40 @@ export const extensionMenu = function (connectMenu) { fileReader.onerror = reject; fileReader.onload = resolve; fileReader.readAsArrayBuffer(fileToLoad, "UTF-8"); - }).then(progressEvent => { - if (game.importExtension(progressEvent.target.result, () => { - extensionNode.innerHTML = '导入成功,3秒后将重启'; - new Promise(resolve => setTimeout(resolve, 1000)).then(() => { - extensionNode.innerHTML = '导入成功,2秒后将重启'; - return new Promise(resolve => setTimeout(resolve, 1000)); - }).then(() => { - extensionNode.innerHTML = '导入成功,1秒后将重启'; - return new Promise(resolve => setTimeout(resolve, 1000)); - }).then(game.reload); - }) !== false) importExtension.style.display = 'none'; + }).then(async (progressEvent) => { + if ( + await game.importExtension(progressEvent.target.result, () => { + extensionNode.innerHTML = "导入成功,3秒后将重启"; + new Promise((resolve) => setTimeout(resolve, 1000)) + .then(() => { + extensionNode.innerHTML = "导入成功,2秒后将重启"; + return new Promise((resolve) => setTimeout(resolve, 1000)); + }) + .then(() => { + extensionNode.innerHTML = "导入成功,1秒后将重启"; + return new Promise((resolve) => setTimeout(resolve, 1000)); + }) + .then(game.reload); + }) !== false + ) + importExtension.style.display = "none"; }); }; var clickExtension = function () { - var active = this.parentNode.querySelector('.videonode.current'); + var active = this.parentNode.querySelector(".videonode.current"); if (active && active != this) { - active.classList.remove('current'); + active.classList.remove("current"); } - this.classList.add('current'); + this.classList.add("current"); clearTimeout(page.currenttimeout); page.currenttimeout = setTimeout(function () { delete page.currenttimeout; }, 200); }; var downloadExtension = function (e) { - if ((this.innerHTML != '下载扩展' && this.innerHTML != '更新扩展') || !window.JSZip) return; - this.classList.remove('update'); + if ((this.innerHTML != "下载扩展" && this.innerHTML != "更新扩展") || !window.JSZip) return; + this.classList.remove("update"); if (e) { e.stopPropagation(); } @@ -2493,20 +2681,19 @@ export const extensionMenu = function (connectMenu) { var list = []; var size = parseFloat(this.info.size) || 0; if (size) { - if (this.info.size.includes('MB')) { + if (this.info.size.includes("MB")) { size *= 1024 * 1024; - } - else if (this.info.size.includes('KB')) { + } else if (this.info.size.includes("KB")) { size *= 1024; } } - this.innerHTML = '正在下载
                                              正在下载
                                              '; - this.classList.add('nopointer'); - this.classList.add('button-downloading'); - var progress = ui.create.div('.button-progress', this); + this.innerHTML = "正在下载
                                              正在下载
                                              "; + this.classList.add("nopointer"); + this.classList.add("button-downloading"); + var progress = ui.create.div(".button-progress", this); ui.create.div(progress); - var url = extensionURL + this.info.name + '.zip'; + var url = extensionURL + this.info.name + ".zip"; var onprogress = function (byte, total) { if (total) { size = total; @@ -2514,74 +2701,101 @@ export const extensionMenu = function (connectMenu) { if (byte == -1) { byte = size; } - progress.firstChild.style.width = Math.round(100 * byte / size) + '%'; + progress.firstChild.style.width = Math.round((100 * byte) / size) + "%"; }; var files = this.info.files || []; for (var i = 0; i < files.length; i++) { - files[i] = 'extension/' + that.info.name + '/' + files[i]; + files[i] = "extension/" + that.info.name + "/" + files[i]; } game.checkFileList(files, function () { - files.unshift('extension/' + that.info.name + '/extension.js'); + files.unshift("extension/" + that.info.name + "/extension.js"); for (var i = 0; i < files.length; i++) { - files[i] = extensionURL + that.info.name + '/' + files[i].slice(10 + that.info.name.length + 1); + files[i] = + extensionURL + + that.info.name + + "/" + + files[i].slice(10 + that.info.name.length + 1); } - var n1 = 0, n2 = files.length; - game.multiDownload(files, function () { - n1++; - onprogress(n1, n2); - }, function (e) { - game.print('下载失败:' + e.source); - }, function () { - onprogress(-1); - _status.importingExtension = true; - window.game = game; - lib.init.js(lib.assetURL + 'extension/' + that.info.name, 'extension', function () { - if (!lib.config.dev) delete window.game; - if (game.importedPack) { - var extname = game.importedPack.name; - if (lib.config.extensions.includes(extname)) { - game.removeExtension(extname, true); - } - lib.config.extensions.add(extname); - game.saveConfig('extensions', lib.config.extensions); - game.saveConfig('extension_' + extname + '_enable', true); - game.saveConfig('extension_' + extname + '_version', that.info.version); - for (var i in game.importedPack.config) { - if (game.importedPack.config[i] && 'init' in game.importedPack.config[i]) { - game.saveConfig('extension_' + extname + '_' + i, game.importedPack.config[i].init); + var n1 = 0, + n2 = files.length; + game.multiDownload( + files, + function () { + n1++; + onprogress(n1, n2); + }, + function (e) { + game.print("下载失败:" + e.source); + }, + function () { + onprogress(-1); + _status.importingExtension = true; + window.game = game; + lib.init.js( + lib.assetURL + "extension/" + that.info.name, + "extension", + function () { + if (!lib.config.dev) delete window.game; + if (game.importedPack) { + var extname = game.importedPack.name; + if (lib.config.extensions.includes(extname)) { + game.removeExtension(extname, true); + } + lib.config.extensions.add(extname); + game.saveConfig("extensions", lib.config.extensions); + game.saveConfig("extension_" + extname + "_enable", true); + game.saveConfig( + "extension_" + extname + "_version", + that.info.version + ); + for (var i in game.importedPack.config) { + if ( + game.importedPack.config[i] && + "init" in game.importedPack.config[i] + ) { + game.saveConfig( + "extension_" + extname + "_" + i, + game.importedPack.config[i].init + ); + } + } + reloadnode.style.display = ""; + that.childNodes[0].innerHTML = "安装成功"; + that.childNodes[1].innerHTML = "安装成功"; + that.classList.remove("active"); + that.classList.remove("highlight"); + delete game.importedPack; + } else { + that.innerHTML = "安装失败"; + that.classList.add("nopointer"); } + _status.importingExtension = false; + }, + function () { + that.innerHTML = "下载失败"; + that.classList.add("nopointer"); + _status.importingExtension = false; } - reloadnode.style.display = ''; - that.childNodes[0].innerHTML = '安装成功'; - that.childNodes[1].innerHTML = '安装成功'; - that.classList.remove('active'); - that.classList.remove('highlight'); - delete game.importedPack; - } - else { - that.innerHTML = '安装失败'; - that.classList.add('nopointer'); - } - _status.importingExtension = false; - }, function () { - that.innerHTML = '下载失败'; - that.classList.add('nopointer'); - _status.importingExtension = false; - }); - }, function (current) { - return 'extension/' + current.slice(extensionURL.length); - }); + ); + }, + function (current) { + return "extension/" + current.slice(extensionURL.length); + } + ); }); }; node.update = function () { if (this.updated) return; if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip'); + lib.init.js(lib.assetURL + "game", "jszip"); } var toremove = []; for (var i = 0; i < page.childElementCount; i++) { - if (page.childNodes[i].classList.contains('menubutton') || page.childNodes[i].classList.contains('loading')) { + if ( + page.childNodes[i].classList.contains("menubutton") || + page.childNodes[i].classList.contains("loading") + ) { toremove.push(page.childNodes[i]); } } @@ -2589,7 +2803,7 @@ export const extensionMenu = function (connectMenu) { toremove[i].remove(); } - var loading = ui.create.div('.loading.config.toggle', '载入中...', page); + var loading = ui.create.div(".loading.config.toggle", "载入中...", page); var loaded = function () { var list = []; var extension = window.extension; @@ -2599,61 +2813,92 @@ export const extensionMenu = function (connectMenu) { } list.randomSort(); delete window.extension; - loading.style.display = 'none'; + loading.style.display = "none"; for (var i = 0; i < list.length; i++) { - var node = ui.create.div('.videonode.menubutton.extension.large', page, clickExtension); - ui.create.div('.caption', list[i].name, node); - ui.create.div('.text.author', '作者:' + list[i].author + '(' + list[i].size + ')', node); - ui.create.div('.text', '更新日期:' + list[i].date, node); - ui.create.div('.text', list[i].intro, node); - var download = ui.create.div('.menubutton.text.active', '下载扩展', node.firstChild, { 'zIndex': '5' }); + var node = ui.create.div( + ".videonode.menubutton.extension.large", + page, + clickExtension + ); + ui.create.div(".caption", list[i].name, node); + ui.create.div( + ".text.author", + "作者:" + list[i].author + "(" + list[i].size + ")", + node + ); + ui.create.div(".text", "更新日期:" + list[i].date, node); + ui.create.div(".text", list[i].intro, node); + var download = ui.create.div(".menubutton.text.active", "下载扩展", node.firstChild, { + zIndex: "5", + }); if (game.download) { if (list[i].netdisk) { - var linknode = ui.create.div('.text', node); - ui.create.node('span.hrefnode', '网盘链接', function () { - game.open(this.link); - }, linknode).link = list[i].netdisk; - if (list[i].forum) { - ui.create.node('span', linknode).style.marginRight = '10px'; - ui.create.node('span.hrefnode', '参与讨论', function () { + var linknode = ui.create.div(".text", node); + ui.create.node( + "span.hrefnode", + "网盘链接", + function () { game.open(this.link); - }, linknode).link = list[i].forum; + }, + linknode + ).link = list[i].netdisk; + if (list[i].forum) { + ui.create.node("span", linknode).style.marginRight = "10px"; + ui.create.node( + "span.hrefnode", + "参与讨论", + function () { + game.open(this.link); + }, + linknode + ).link = list[i].forum; } - } - else if (list[i].forum) { - var linknode = ui.create.div('.text', node); - ui.create.node('span.hrefnode', '参与讨论', function () { - game.open(this.link); - }, linknode).link = list[i].forum; + } else if (list[i].forum) { + var linknode = ui.create.div(".text", node); + ui.create.node( + "span.hrefnode", + "参与讨论", + function () { + game.open(this.link); + }, + linknode + ).link = list[i].forum; } download.listen(downloadExtension); if (lib.config.extensions.includes(list[i].name)) { - download.classList.remove('active'); - if (lib.extensionPack[list[i].name] && lib.extensionPack[list[i].name].version == list[i].version) { - download.classList.add('transparent2'); - download.classList.remove('active'); - download.innerHTML = '已安装'; - } - else if (lib.config['extension_' + list[i].name + '_version'] != list[i].version) { - download.innerHTML = '更新扩展'; - download.classList.add('highlight'); - download.classList.add('update'); - } - else { - download.classList.add('transparent2'); - download.classList.remove('active'); - download.innerHTML = '已安装'; + download.classList.remove("active"); + if ( + lib.extensionPack[list[i].name] && + lib.extensionPack[list[i].name].version == list[i].version + ) { + download.classList.add("transparent2"); + download.classList.remove("active"); + download.innerHTML = "已安装"; + } else if ( + lib.config["extension_" + list[i].name + "_version"] != list[i].version + ) { + download.innerHTML = "更新扩展"; + download.classList.add("highlight"); + download.classList.add("update"); + } else { + download.classList.add("transparent2"); + download.classList.remove("active"); + download.innerHTML = "已安装"; } } download.info = list[i]; - } - else { + } else { if (list[i].forum) { - var linknode = ui.create.div('.text', node); - ui.create.node('span', linknode); - ui.create.node('span.hrefnode', '参与讨论', function () { - game.open(this.link); - }, linknode).link = list[i].forum; + var linknode = ui.create.div(".text", node); + ui.create.node("span", linknode); + ui.create.node( + "span.hrefnode", + "参与讨论", + function () { + game.open(this.link); + }, + linknode + ).link = list[i].forum; } download.listen(function () { game.open(this.link); @@ -2664,23 +2909,28 @@ export const extensionMenu = function (connectMenu) { }; window.extension = {}; fetch(`${extensionURL}catalog.js`, { - referrerPolicy: 'no-referrer' - }).then(response => response.text()).then(eval).then(loaded).catch(reason => { - console.log(reason); - delete window.extension; - loading.innerHTML = '连接失败:' + (reason instanceof Error ? reason.message : String(reason)); - }); + referrerPolicy: "no-referrer", + }) + .then((response) => response.text()) + .then(eval) + .then(loaded) + .catch((reason) => { + console.log(reason); + delete window.extension; + loading.innerHTML = + "连接失败:" + (reason instanceof Error ? reason.message : String(reason)); + }); }; if (_thisUpdate) node.update(); }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - var active = start.firstChild.querySelector('.active'); + if (!get.config("menu_loadondemand")) node._initLink(); + })(); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); } if (!active.link) active._initLink(); rightPane.appendChild(active.link); updateNodes(); -}; \ No newline at end of file +}; diff --git a/noname/ui/create/menu/pages/optionsMenu.js b/noname/ui/create/menu/pages/optionsMenu.js index 01a087f92..79ef29e10 100644 --- a/noname/ui/create/menu/pages/optionsMenu.js +++ b/noname/ui/create/menu/pages/optionsMenu.js @@ -14,7 +14,7 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig + createConfig, } from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; import { nonameInitialized } from "../../../../util/index.js"; @@ -34,14 +34,14 @@ export const optionsMenu = function (connectMenu) { var rightPane = start.lastChild; var clickMode = function () { - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active === this) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); active = this; - active.classList.add('active'); + active.classList.add("active"); if (this.link) rightPane.appendChild(this.link); else { this._initLink(); @@ -54,22 +54,21 @@ export const optionsMenu = function (connectMenu) { var list = lib.config.autoskilllist; if (bool) { list.remove(name); - } - else { + } else { list.add(name); } - game.saveConfig('autoskilllist', list); + game.saveConfig("autoskilllist", list); }; var skilllistexpanded = game.expandSkills(lib.skilllist); for (var i in lib.skill) { if (!skilllistexpanded.includes(i)) continue; if (lib.skill[i].frequent && lib.translate[i]) { lib.configMenu.skill.config[i] = { - name: lib.translate[i + '_noconf'] || lib.translate[i], + name: lib.translate[i + "_noconf"] || lib.translate[i], init: true, - type: 'autoskill', + type: "autoskill", onclick: clickAutoSkill, - intro: lib.translate[i + '_info'] + intro: lib.translate[i + "_info"], }; } } @@ -78,29 +77,28 @@ export const optionsMenu = function (connectMenu) { var list = lib.config.forbidlist; if (bool) { list.remove(name); - } - else { + } else { list.add(name); } - game.saveConfig('forbidlist', list); + game.saveConfig("forbidlist", list); }; var forbid = lib.config.forbid; if (!lib.config.forbidlist) { - game.saveConfig('forbidlist', []); + game.saveConfig("forbidlist", []); } for (var i = 0; i < forbid.length; i++) { var skip = false; - var str = ''; - var str2 = ''; - var str3 = ''; + var str = ""; + var str2 = ""; + var str3 = ""; for (var j = 0; j < forbid[i].length; j++) { if (!lib.skilllist.includes(forbid[i][j])) { skip = true; break; } - str += get.translation(forbid[i][j]) + '+'; - str2 += forbid[i][j] + '+'; - str3 += get.translation(forbid[i][j]) + ':' + lib.translate[forbid[i][j] + '_info']; + str += get.translation(forbid[i][j]) + "+"; + str2 += forbid[i][j] + "+"; + str3 += get.translation(forbid[i][j]) + ":" + lib.translate[forbid[i][j] + "_info"]; if (j < forbid[i].length - 1) { str3 += '
                                              '; } @@ -112,9 +110,9 @@ export const optionsMenu = function (connectMenu) { lib.configMenu.skill.config[str2] = { name: str, init: true, - type: 'banskill', + type: "banskill", onclick: clickBanSkill, - intro: str3 + intro: str3, }; } @@ -122,8 +120,8 @@ export const optionsMenu = function (connectMenu) { var updateAppearence = null; var createModeConfig = function (mode, position) { var info = lib.configMenu[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', info.name, position, clickMode); + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", info.name, position, clickMode); node.mode = mode; // node._initLink=function(){ node.link = page; @@ -135,48 +133,51 @@ export const optionsMenu = function (connectMenu) { var custombanskillNodes = []; var banskill; - if (mode == 'skill') { + if (mode == "skill") { var autoskillexpanded = false; var banskillexpanded = false; - ui.create.div('.config.more', '自动发动
                                              >
                                              ', page, function () { + ui.create.div(".config.more", "自动发动
                                              >
                                              ", page, function () { if (autoskillexpanded) { - this.classList.remove('on'); + this.classList.remove("on"); for (var k = 0; k < autoskillNodes.length; k++) { - autoskillNodes[k].style.display = 'none'; + autoskillNodes[k].style.display = "none"; } - } - else { - this.classList.add('on'); + } else { + this.classList.add("on"); for (var k = 0; k < autoskillNodes.length; k++) { - autoskillNodes[k].style.display = ''; + autoskillNodes[k].style.display = ""; } } autoskillexpanded = !autoskillexpanded; }); - banskill = ui.create.div('.config.more', '双将禁配
                                              >
                                              ', page, function () { + banskill = ui.create.div(".config.more", "双将禁配
                                              >
                                              ", page, function () { if (banskillexpanded) { - this.classList.remove('on'); + this.classList.remove("on"); for (var k = 0; k < banskillNodes.length; k++) { - banskillNodes[k].style.display = 'none'; + banskillNodes[k].style.display = "none"; } - } - else { - this.classList.add('on'); + } else { + this.classList.add("on"); for (var k = 0; k < banskillNodes.length; k++) { - banskillNodes[k].style.display = ''; + banskillNodes[k].style.display = ""; } } banskillexpanded = !banskillexpanded; }); - var banskilladd = ui.create.div('.config.indent', '添加...', page, function () { - this.nextSibling.classList.toggle('hidden'); - }); - banskilladd.style.display = 'none'; + var banskilladd = ui.create.div( + ".config.indent", + '添加...', + page, + function () { + this.nextSibling.classList.toggle("hidden"); + } + ); + banskilladd.style.display = "none"; banskillNodes.push(banskilladd); - var banskilladdNode = ui.create.div('.config.indent.hidden.banskilladd', page); - banskilladdNode.style.display = 'none'; + var banskilladdNode = ui.create.div(".config.indent.hidden.banskilladd", page); + banskilladdNode.style.display = "none"; banskillNodes.push(banskilladdNode); var matchBanSkill = function (skills1, skills2) { @@ -193,23 +194,23 @@ export const optionsMenu = function (connectMenu) { break; } } - game.saveConfig('customforbid', lib.config.customforbid); + game.saveConfig("customforbid", lib.config.customforbid); this.parentNode.remove(); }; var createCustomBanSkill = function (skills) { - var node = ui.create.div('.config.indent.toggle'); - node.style.display = 'none'; + var node = ui.create.div(".config.indent.toggle"); + node.style.display = "none"; node.link = skills; banskillNodes.push(node); custombanskillNodes.push(node); var str = get.translation(skills[0]); for (var i = 1; i < skills.length; i++) { - str += '+' + get.translation(skills[i]); + str += "+" + get.translation(skills[i]); } node.innerHTML = str; - var span = document.createElement('span'); - span.classList.add('cardpiledelete'); - span.innerHTML = '删除'; + var span = document.createElement("span"); + span.classList.add("cardpiledelete"); + span.innerHTML = "删除"; span.onclick = deleteCustomBanSkill; node.appendChild(span); page.insertBefore(node, banskilladdNode.nextSibling); @@ -221,18 +222,19 @@ export const optionsMenu = function (connectMenu) { (function () { var list = []; for (var i in lib.character) { - if (lib.character[i][3].length) - list.push([i, lib.translate[i]]); + if (lib.character[i][3].length) list.push([i, lib.translate[i]]); } list.sort(function (a, b) { - a = a[0]; b = b[0]; - var aa = a, bb = b; - if (aa.includes('_')) { - aa = aa.slice(aa.indexOf('_') + 1); + a = a[0]; + b = b[0]; + var aa = a, + bb = b; + if (aa.includes("_")) { + aa = aa.slice(aa.indexOf("_") + 1); } - if (bb.includes('_')) { - bb = bb.slice(bb.indexOf('_') + 1); + if (bb.includes("_")) { + bb = bb.slice(bb.indexOf("_") + 1); } if (aa != bb) { return aa > bb ? 1 : -1; @@ -249,38 +251,38 @@ export const optionsMenu = function (connectMenu) { var selectname = ui.create.selectlist(list, list[0], banskilladdNode); selectname.onchange = function () { var skills = lib.character[this.value][3]; - skillopt.innerHTML = ''; + skillopt.innerHTML = ""; for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = skills[i]; option.innerHTML = lib.translate[skills[i]]; skillopt.appendChild(option); } }; - selectname.style.maxWidth = '85px'; + selectname.style.maxWidth = "85px"; var skillopt = ui.create.selectlist(list2, list2[0], banskilladdNode); - var span = document.createElement('span'); - span.innerHTML = '+'; + var span = document.createElement("span"); + span.innerHTML = "+"; banskilladdNode.appendChild(span); - var br = document.createElement('br'); + var br = document.createElement("br"); banskilladdNode.appendChild(br); var selectname2 = ui.create.selectlist(list, list[0], banskilladdNode); selectname2.onchange = function () { var skills = lib.character[this.value][3]; - skillopt2.innerHTML = ''; + skillopt2.innerHTML = ""; for (var i = 0; i < skills.length; i++) { - var option = document.createElement('option'); + var option = document.createElement("option"); option.value = skills[i]; option.innerHTML = lib.translate[skills[i]]; skillopt2.appendChild(option); } }; - selectname2.style.maxWidth = '85px'; + selectname2.style.maxWidth = "85px"; var skillopt2 = ui.create.selectlist(list2, list2[0], banskilladdNode); - var confirmbutton = document.createElement('button'); - confirmbutton.innerHTML = '确定'; + var confirmbutton = document.createElement("button"); + confirmbutton.innerHTML = "确定"; banskilladdNode.appendChild(confirmbutton); confirmbutton.onclick = function () { @@ -293,33 +295,31 @@ export const optionsMenu = function (connectMenu) { if (matchBanSkill(lib.config.customforbid[i], skills)) return; } lib.config.customforbid.push(skills); - game.saveConfig('customforbid', lib.config.customforbid); - createCustomBanSkill(skills).style.display = ''; + game.saveConfig("customforbid", lib.config.customforbid); + createCustomBanSkill(skills).style.display = ""; }; - }()); - page.style.paddingBottom = '10px'; + })(); + page.style.paddingBottom = "10px"; } var config = lib.config; - if (mode == 'appearence') { + if (mode == "appearence") { updateAppearence = function () { info.config.update(config, map); }; - } - else if (mode == 'view') { + } else if (mode == "view") { updateView = function () { info.config.update(config, map); }; } for (var j in info.config) { - if (j === 'update') { + if (j === "update") { continue; } var cfg = get.copy(info.config[j]); cfg._name = j; if (j in config) { cfg.init = config[j]; - } - else if (cfg.type != 'autoskill' && cfg.type != 'banskill') { + } else if (cfg.type != "autoskill" && cfg.type != "banskill") { game.saveConfig(j, cfg.init); } if (!cfg.onclick) { @@ -332,7 +332,7 @@ export const optionsMenu = function (connectMenu) { }; } if (info.config.update) { - if (mode == 'appearence' || mode == 'view') { + if (mode == "appearence" || mode == "view") { cfg.update = function () { if (updateAppearence) { updateAppearence(); @@ -341,32 +341,30 @@ export const optionsMenu = function (connectMenu) { updateView(); } }; - } - else { + } else { cfg.update = function () { info.config.update(config, map); }; } } var cfgnode = createConfig(cfg); - if (cfg.type == 'autoskill') { + if (cfg.type == "autoskill") { autoskillNodes.push(cfgnode); // cfgnode.style.transition='all 0s'; - cfgnode.classList.add('indent'); + cfgnode.classList.add("indent"); // cfgnode.hide(); - cfgnode.style.display = 'none'; - } - else if (cfg.type == 'banskill') { + cfgnode.style.display = "none"; + } else if (cfg.type == "banskill") { banskillNodes.push(cfgnode); // cfgnode.style.transition='all 0s'; - cfgnode.classList.add('indent'); + cfgnode.classList.add("indent"); // cfgnode.hide(); - cfgnode.style.display = 'none'; + cfgnode.style.display = "none"; } - if (j == 'import_data_button') { + if (j == "import_data_button") { ui.import_data_button = cfgnode; cfgnode.hide(); - cfgnode.querySelector('button').onclick = function () { + cfgnode.querySelector("button").onclick = function () { var fileToLoad = this.previousSibling.files[0]; if (fileToLoad) { var fileReader = new FileReader(); @@ -375,40 +373,38 @@ export const optionsMenu = function (connectMenu) { if (!data) return; try { data = JSON.parse(lib.init.decode(data)); - if (!data || typeof data != 'object') { - throw ('err'); + if (!data || typeof data != "object") { + throw "err"; } if (lib.db && (!data.config || !data.data)) { - throw ('err'); + throw "err"; } - } - catch (e) { + } catch (e) { console.log(e); - alert('导入失败'); + alert("导入失败"); return; } - alert('导入成功'); + alert("导入成功"); if (!lib.db) { - var noname_inited = localStorage.getItem('noname_inited'); - var onlineKey = localStorage.getItem(lib.configprefix + 'key'); + var noname_inited = localStorage.getItem("noname_inited"); + var onlineKey = localStorage.getItem(lib.configprefix + "key"); localStorage.clear(); if (noname_inited) { - localStorage.setItem('noname_inited', noname_inited); + localStorage.setItem("noname_inited", noname_inited); } if (onlineKey) { - localStorage.setItem(lib.configprefix + 'key', onlineKey); + localStorage.setItem(lib.configprefix + "key", onlineKey); } for (var i in data) { localStorage.setItem(i, data[i]); } - } - else { + } else { for (var i in data.config) { - game.putDB('config', i, data.config[i]); + game.putDB("config", i, data.config[i]); lib.config[i] = data.config[i]; } for (var i in data.data) { - game.putDB('data', i, data.data[i]); + game.putDB("data", i, data.data[i]); } } lib.init.background(); @@ -417,24 +413,27 @@ export const optionsMenu = function (connectMenu) { fileReader.readAsText(fileToLoad, "UTF-8"); } }; - } - else if (j == 'import_music') { - cfgnode.querySelector('button').onclick = function () { + } else if (j == "import_music") { + cfgnode.querySelector("button").onclick = function () { if (_status.music_importing) return; _status.music_importing = true; var fileToLoad = this.previousSibling.files[0]; if (fileToLoad) { if (!lib.config.customBackgroundMusic) lib.config.customBackgroundMusic = {}; var name = fileToLoad.name; - if (name.includes('.')) { - name = name.slice(0, name.indexOf('.')); + if (name.includes(".")) { + name = name.slice(0, name.indexOf(".")); } - var link = (game.writeFile ? 'cdv_' : 'custom_') + name; + var link = (game.writeFile ? "cdv_" : "custom_") + name; if (lib.config.customBackgroundMusic[link]) { - if (!confirm('已经存在文件名称相同的背景音乐,是否仍然要继续导入?')) { _status.music_importing = false; return; } + if (!confirm("已经存在文件名称相同的背景音乐,是否仍然要继续导入?")) { + _status.music_importing = false; + return; + } for (var i = 1; i < 1000; i++) { - if (!lib.config.customBackgroundMusic[link + '_' + i]) { - link = link + '_' + i; break; + if (!lib.config.customBackgroundMusic[link + "_" + i]) { + link = link + "_" + i; + break; } } } @@ -442,16 +441,25 @@ export const optionsMenu = function (connectMenu) { var nodexx = ui.background_music_setting; var nodeyy = nodexx._link.menu; var nodezz = nodexx._link.config; - var musicname = link.slice(link.indexOf('_') + 1); - game.prompt('###请输入音乐的名称###' + musicname, true, function (str) { + var musicname = link.slice(link.indexOf("_") + 1); + game.prompt("###请输入音乐的名称###" + musicname, true, function (str) { if (str) musicname = str; lib.config.customBackgroundMusic[link] = musicname; lib.config.background_music = link; lib.config.all.background_music.add(link); - game.saveConfig('background_music', link); - game.saveConfig('customBackgroundMusic', lib.config.customBackgroundMusic); + game.saveConfig("background_music", link); + game.saveConfig( + "customBackgroundMusic", + lib.config.customBackgroundMusic + ); nodezz.item[link] = lib.config.customBackgroundMusic[link]; - var textMenu = ui.create.div('', lib.config.customBackgroundMusic[link], nodeyy, clickMenuItem, nodeyy.childElementCount - 2); + var textMenu = ui.create.div( + "", + lib.config.customBackgroundMusic[link], + nodeyy, + clickMenuItem, + nodeyy.childElementCount - 2 + ); textMenu._link = link; nodezz.updatex.call(nodexx, []); _status.music_importing = false; @@ -459,15 +467,13 @@ export const optionsMenu = function (connectMenu) { }); }; if (game.writeFile) { - game.writeFile(fileToLoad, 'audio/background', link + '.mp3', callback); - } - else { - game.putDB('audio', link, fileToLoad, callback); + game.writeFile(fileToLoad, "audio/background", link + ".mp3", callback); + } else { + game.putDB("audio", link, fileToLoad, callback); } } }; - } - else if (j == 'extension_source') { + } else if (j == "extension_source") { ui.extension_source = cfgnode; cfgnode.updateInner = function () { this._link.choosing.innerHTML = lib.config.extension_source; @@ -475,14 +481,12 @@ export const optionsMenu = function (connectMenu) { } map[j] = cfgnode; if (!cfg.unfrequent) { - if (cfg.type == 'autoskill') { + if (cfg.type == "autoskill") { page.insertBefore(cfgnode, banskill); - } - else { + } else { page.appendChild(cfgnode); } - } - else { + } else { // cfgnode.classList.add('auto-hide'); hiddenNodes.push(cfgnode); } @@ -500,7 +504,7 @@ export const optionsMenu = function (connectMenu) { // } // expanded=!expanded; // }); - page.classList.add('morenodes'); + page.classList.add("morenodes"); for (var k = 0; k < hiddenNodes.length; k++) { page.appendChild(hiddenNodes[k]); } @@ -515,58 +519,85 @@ export const optionsMenu = function (connectMenu) { }; for (var i in lib.configMenu) { - if (i != 'others') createModeConfig(i, start.firstChild); + if (i != "others") createModeConfig(i, start.firstChild); } (function () { if (!game.download && !lib.device) return; - var page = ui.create.div('#create-extension'); - var node = ui.create.div('.menubutton.large', '文件', start.firstChild, clickMode); - node.mode = 'create'; + var page = ui.create.div("#create-extension"); + var node = ui.create.div(".menubutton.large", "文件", start.firstChild, clickMode); + node.mode = "create"; node._initLink = function () { node.link = page; var pageboard = ui.create.div(page); var importextensionexpanded = false; var importExtension; - var extensionnode = ui.create.div('.config.more', '导入素材包
                                              >
                                              ', pageboard, function () { - if (importextensionexpanded) { - this.classList.remove('on'); - importExtension.style.display = 'none'; + var extensionnode = ui.create.div( + ".config.more", + "导入素材包
                                              >
                                              ", + pageboard, + function () { + if (importextensionexpanded) { + this.classList.remove("on"); + importExtension.style.display = "none"; + } else { + this.classList.add("on"); + importExtension.style.display = ""; + } + importextensionexpanded = !importextensionexpanded; } - else { - this.classList.add('on'); - importExtension.style.display = ''; - } - importextensionexpanded = !importextensionexpanded; - }); - extensionnode.style.padding = '13px 33px 4px'; - extensionnode.style.left = '0px'; - importExtension = ui.create.div('.new_character.export.import', pageboard); - importExtension.style.padding = '0px 33px 10px'; - importExtension.style.display = 'none'; - importExtension.style.width = '100%'; - importExtension.style.textAlign = 'left'; - ui.create.div('', '', importExtension); - var promptnode = ui.create.div('', '
                                              ', importExtension); - promptnode.style.display = 'none'; + ); + extensionnode.style.padding = "13px 33px 4px"; + extensionnode.style.left = "0px"; + importExtension = ui.create.div(".new_character.export.import", pageboard); + importExtension.style.padding = "0px 33px 10px"; + importExtension.style.display = "none"; + importExtension.style.width = "100%"; + importExtension.style.textAlign = "left"; + ui.create.div( + "", + '', + importExtension + ); + var promptnode = ui.create.div( + "", + '
                                              ', + importExtension + ); + promptnode.style.display = "none"; importExtension.firstChild.lastChild.onclick = function () { - if (promptnode.style.display != 'none') return; + if (promptnode.style.display != "none") return; var fileToLoad = this.previousSibling.files[0]; if (fileToLoad) { - promptnode.style.display = ''; - promptnode.firstChild.innerHTML = '正在解压...'; + promptnode.style.display = ""; + promptnode.firstChild.innerHTML = "正在解压..."; var fileReader = new FileReader(); fileReader.onload = function (fileLoadedEvent) { var data = fileLoadedEvent.target.result; var loadData = function () { var zip = new JSZip(); zip.load(data); - var images = [], audios = [], fonts = [], directories = {}, directoryList = []; - Object.keys(zip.files).forEach(file => { - const parsedPath = lib.path.parse(file), directory = parsedPath.dir, fileExtension = parsedPath.ext.toLowerCase(); - if (directory.startsWith('audio') && (fileExtension == '.mp3' || fileExtension == '.ogg')) audios.push(file); - else if (directory.startsWith('font') && fileExtension == '.woff2') fonts.push(file); - else if (directory.startsWith('image') && (fileExtension == '.jpg' || fileExtension == '.png')) images.push(file); + var images = [], + audios = [], + fonts = [], + directories = {}, + directoryList = []; + Object.keys(zip.files).forEach((file) => { + const parsedPath = lib.path.parse(file), + directory = parsedPath.dir, + fileExtension = parsedPath.ext.toLowerCase(); + if ( + directory.startsWith("audio") && + (fileExtension == ".mp3" || fileExtension == ".ogg") + ) + audios.push(file); + else if (directory.startsWith("font") && fileExtension == ".woff2") + fonts.push(file); + else if ( + directory.startsWith("image") && + (fileExtension == ".jpg" || fileExtension == ".png") + ) + images.push(file); else return; if (!directories[directory]) { directories[directory] = []; @@ -575,92 +606,110 @@ export const optionsMenu = function (connectMenu) { directories[directory].push(parsedPath.base); }); if (audios.length || fonts.length || images.length) { - var str = ''; + var str = ""; if (audios.length) { - str += audios.length + '个音频文件'; + str += audios.length + "个音频文件"; } if (fonts.length) { - if (str.length) str += '、'; - str += fonts.length + '个字体文件'; + if (str.length) str += "、"; + str += fonts.length + "个字体文件"; } if (images.length) { - if (str.length) str += '、'; - str += images.length + '个图片文件'; + if (str.length) str += "、"; + str += images.length + "个图片文件"; } var filelist = audios.concat(fonts).concat(images); if (filelist.length > 200) { - str += ',导入时间可能较长'; + str += ",导入时间可能较长"; } var assetLoaded = function () { - promptnode.firstChild.innerHTML = '导入成功。重新启动×'; - promptnode.firstChild.querySelectorAll('span')[0].onclick = game.reload; - promptnode.firstChild.querySelectorAll('span')[1].onclick = function () { - promptnode.style.display = 'none'; + promptnode.firstChild.innerHTML = + '导入成功。重新启动×'; + promptnode.firstChild.querySelectorAll("span")[0].onclick = game.reload; + promptnode.firstChild.querySelectorAll("span")[1].onclick = function () { + promptnode.style.display = "none"; }; }; - if (confirm('本次将导入' + str + ',是否继续?')) { - promptnode.firstChild.innerHTML = '正在导入... 详细信息'; - promptnode.firstChild.querySelector('span.hrefnode').onclick = ui.click.consoleMenu; + if (confirm("本次将导入" + str + ",是否继续?")) { + promptnode.firstChild.innerHTML = + '正在导入... 详细信息'; + promptnode.firstChild.querySelector("span.hrefnode").onclick = + ui.click.consoleMenu; if (lib.node && lib.node.fs) { var writeFile = function () { if (filelist.length) { var str = filelist.shift(); - game.print(str.slice(str.lastIndexOf('/') + 1)); - lib.node.fs.writeFile(__dirname + '/' + str, zip.files[str].asNodeBuffer(), null, writeFile); - } - else { + game.print(str.slice(str.lastIndexOf("/") + 1)); + lib.node.fs.writeFile( + __dirname + "/" + str, + zip.files[str].asNodeBuffer(), + null, + writeFile + ); + } else { assetLoaded(); } }; game.ensureDirectory(directoryList, writeFile); - - } - else { + } else { var getDirectory = function () { if (directoryList.length) { var dir = directoryList.shift(); var filelist = directories[dir]; - window.resolveLocalFileSystemURL(nonameInitialized + dir, function (entry) { - var writeFile = function () { - if (filelist.length) { - var filename = filelist.shift(); - game.print(filename); - entry.getFile(filename, { create: true }, function (fileEntry) { - fileEntry.createWriter(function (fileWriter) { - fileWriter.onwriteend = writeFile; - fileWriter.onerror = function (e) { - game.print('Write failed: ' + e.toString()); - }; - fileWriter.write(zip.files[dir + '/' + filename].asArrayBuffer()); - }); - }); - } - else { - getDirectory(); - } - }; - writeFile(); - }); - } - else { + window.resolveLocalFileSystemURL( + nonameInitialized + dir, + function (entry) { + var writeFile = function () { + if (filelist.length) { + var filename = filelist.shift(); + game.print(filename); + entry.getFile( + filename, + { create: true }, + function (fileEntry) { + fileEntry.createWriter(function ( + fileWriter + ) { + fileWriter.onwriteend = writeFile; + fileWriter.onerror = function ( + e + ) { + game.print( + "Write failed: " + + e.toString() + ); + }; + fileWriter.write( + zip.files[ + dir + "/" + filename + ].asArrayBuffer() + ); + }); + } + ); + } else { + getDirectory(); + } + }; + writeFile(); + } + ); + } else { assetLoaded(); } }; game.ensureDirectory(directoryList, getDirectory); } + } else { + promptnode.style.display = "none"; } - else { - promptnode.style.display = 'none'; - } - } - else { - alert('没有检测到素材'); + } else { + alert("没有检测到素材"); } }; if (!window.JSZip) { - lib.init.js(lib.assetURL + 'game', 'jszip', loadData); - } - else { + lib.init.js(lib.assetURL + "game", "jszip", loadData); + } else { loadData(); } }; @@ -678,47 +727,48 @@ export const optionsMenu = function (connectMenu) { } }; var createDash = function (str1, str2, node) { - var dash = ui.create.div('.menubutton.large.dashboard'); + var dash = ui.create.div(".menubutton.large.dashboard"); dashboard.appendChild(dash); page.appendChild(node); dash.link = node; node.link = dash; dash.listen(clickDash); lib.setScroll(node); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); + ui.create.div("", str1, dash); + ui.create.div("", str2, dash); }; var createDash2 = function (str1, str2, path, page) { - var dash = ui.create.div('.menubutton.large.dashboard.dashboard2'); + var dash = ui.create.div(".menubutton.large.dashboard.dashboard2"); page.appendChild(dash); dash.listen(function () { page.path = path; enterDirectory(page, path); }); - ui.create.div('', str1, dash); - ui.create.div('', str2, dash); + ui.create.div("", str1, dash); + ui.create.div("", str2, dash); }; var removeFile = function (selected, page) { if (lib.node && lib.node.fs) { var unlink = function () { if (selected.length) { - lib.node.fs.unlink(__dirname + '/' + selected.shift().path, unlink); - } - else { + lib.node.fs.unlink(__dirname + "/" + selected.shift().path, unlink); + } else { enterDirectory(page, page.currentpath); } }; unlink(); - } - else { + } else { window.resolveLocalFileSystemURL(nonameInitialized + page.currentpath, function (entry) { var unlink = function () { if (selected.length) { - entry.getFile(selected.shift().filename, { create: false }, function (fileEntry) { - fileEntry.remove(unlink); - }); - } - else { + entry.getFile( + selected.shift().filename, + { create: false }, + function (fileEntry) { + fileEntry.remove(unlink); + } + ); + } else { enterDirectory(page, page.currentpath); } }; @@ -729,12 +779,12 @@ export const optionsMenu = function (connectMenu) { var clickDirectory = function () { if (_status.dragged) return; var page = this.parentNode.parentNode.parentNode; - if (page.deletebutton.classList.contains('active')) { - if (confirm('确认删除' + this.innerHTML + '文件夹?(此操作不可撤销)')) { + if (page.deletebutton.classList.contains("active")) { + if (confirm("确认删除" + this.innerHTML + "文件夹?(此操作不可撤销)")) { if (lib.node && lib.node.fs) { try { var removeDirectory = function (path, callback) { - lib.node.fs.readdir(__dirname + '/' + path, function (err, list) { + lib.node.fs.readdir(__dirname + "/" + path, function (err, list) { if (err) { console.log(err); return; @@ -742,16 +792,14 @@ export const optionsMenu = function (connectMenu) { var removeFile = function () { if (list.length) { var filename = list.shift(); - var url = __dirname + '/' + path + '/' + filename; + var url = __dirname + "/" + path + "/" + filename; if (lib.node.fs.statSync(url).isDirectory()) { - removeDirectory(path + '/' + filename, removeFile); - } - else { + removeDirectory(path + "/" + filename, removeFile); + } else { lib.node.fs.unlink(url, removeFile); } - } - else { - lib.node.fs.rmdir(__dirname + '/' + path, callback); + } else { + lib.node.fs.rmdir(__dirname + "/" + path, callback); } }; removeFile(); @@ -760,12 +808,10 @@ export const optionsMenu = function (connectMenu) { removeDirectory(this.path, function () { enterDirectory(page, page.currentpath); }); - } - catch (e) { + } catch (e) { console.log(e); } - } - else { + } else { window.resolveLocalFileSystemURL(nonameInitialized + this.path, function (entry) { entry.removeRecursively(function () { enterDirectory(page, page.currentpath); @@ -780,38 +826,35 @@ export const optionsMenu = function (connectMenu) { var clickFile = function () { if (_status.dragged) return; var page = this.parentNode.parentNode.parentNode; - if (page.deletebutton.classList.contains('active')) { - if (confirm('确认删除' + this.innerHTML + '?(此操作不可撤销)')) { + if (page.deletebutton.classList.contains("active")) { + if (confirm("确认删除" + this.innerHTML + "?(此操作不可撤销)")) { removeFile([this], page); } return; } - this.classList.toggle('thundertext'); + this.classList.toggle("thundertext"); page.clicked = true; - if (this.ext == 'jpg' || this.ext == 'png') { - if (this.classList.contains('thundertext')) { + if (this.ext == "jpg" || this.ext == "png") { + if (this.classList.contains("thundertext")) { if (!this.previewnode) { - this.previewnode = document.createElement('img'); + this.previewnode = document.createElement("img"); this.previewnode.src = lib.assetURL + this.path; - this.previewnode.width = '60'; - this.previewnode.style.maxHeight = '120px'; + this.previewnode.width = "60"; + this.previewnode.style.maxHeight = "120px"; this.parentNode.appendChild(this.previewnode); } - } - else { + } else { if (this.previewnode) { this.previewnode.remove(); delete this.previewnode; } } - } - else if (this.ext == 'mp3' || this.ext == 'ogg') { - if (this.classList.contains('thundertext')) { + } else if (this.ext == "mp3" || this.ext == "ogg") { + if (this.classList.contains("thundertext")) { if (!this.previewnode) { this.previewnode = game.playAudio(this.path.slice(6)); } - } - else { + } else { if (this.previewnode) { this.previewnode.remove(); delete this.previewnode; @@ -823,11 +866,10 @@ export const optionsMenu = function (connectMenu) { if (!this.parentNode) return; if (this.parentNode.clicked) { this.parentNode.clicked = false; - } - else { - var selected = Array.from(this.querySelectorAll('span.thundertext')); + } else { + var selected = Array.from(this.querySelectorAll("span.thundertext")); for (var i = 0; i < selected.length; i++) { - selected[i].classList.remove('thundertext'); + selected[i].classList.remove("thundertext"); if (selected[i].previewnode) { selected[i].previewnode.remove(); delete selected[i].previewnode; @@ -836,64 +878,60 @@ export const optionsMenu = function (connectMenu) { } }; var enterDirectory = function (page, path) { - page.innerHTML = ''; + page.innerHTML = ""; page.currentpath = path; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + var backbutton = ui.create.div(".menubutton.round", "返", page, function () { page.clicked = false; clickFileList.call(filelist); if (page.path == path) { page.reset(); - } - else { - if (path.indexOf('/') == -1) { - enterDirectory(page, ''); - } - else { - enterDirectory(page, path.slice(0, path.lastIndexOf('/'))); + } else { + if (path.indexOf("/") == -1) { + enterDirectory(page, ""); + } else { + enterDirectory(page, path.slice(0, path.lastIndexOf("/"))); } } }); backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - + backbutton.style.right = "10px"; + backbutton.style.bottom = "15px"; var refresh = function () { enterDirectory(page, path); }; - var addbutton = ui.create.div('.menubutton.round', '添', page, function () { + var addbutton = ui.create.div(".menubutton.round", "添", page, function () { var pos1 = this.getBoundingClientRect(); var pos2 = ui.window.getBoundingClientRect(); openMenu(this.menu, { clientX: pos1.left + pos1.width + 5 - pos2.left, - clientY: pos1.top - pos2.top + clientY: pos1.top - pos2.top, }); }); - addbutton.menu = ui.create.div('.menu'); - ui.create.div('', '添加文件', addbutton.menu, function () { + addbutton.menu = ui.create.div(".menu"); + ui.create.div("", "添加文件", addbutton.menu, function () { cachePopupContainer.noclose = true; }); var createDir = function (str) { if (lib.node && lib.node.fs) { - lib.node.fs.mkdir(__dirname + '/' + path + '/' + str, refresh); - } - else { + lib.node.fs.mkdir(__dirname + "/" + path + "/" + str, refresh); + } else { window.resolveLocalFileSystemURL(nonameInitialized + path, function (entry) { entry.getDirectory(str, { create: true }, refresh); }); } }; - ui.create.div('', '添加目录', addbutton.menu, function () { + ui.create.div("", "添加目录", addbutton.menu, function () { ui.create.templayer(); - game.prompt('输入目录名称', function (str) { + game.prompt("输入目录名称", function (str) { if (str) { createDir(str); } }); }); - var input = document.createElement('input'); - input.className = 'fileinput'; - input.type = 'file'; + var input = document.createElement("input"); + input.className = "fileinput"; + input.type = "file"; input.onchange = function () { var fileToLoad = input.files[0]; game.print(fileToLoad.name); @@ -907,35 +945,35 @@ export const optionsMenu = function (connectMenu) { }; addbutton.menu.firstChild.appendChild(input); addbutton.style.zIndex = 1; - addbutton.style.right = '10px'; - addbutton.style.bottom = '80px'; + addbutton.style.right = "10px"; + addbutton.style.bottom = "80px"; - var deletebutton = ui.create.div('.menubutton.round', '删', page, function () { + var deletebutton = ui.create.div(".menubutton.round", "删", page, function () { if (!this.parentNode) return; - if (!this.classList.contains('active')) { - var selected = Array.from(filelist.querySelectorAll('span.thundertext')); + if (!this.classList.contains("active")) { + var selected = Array.from(filelist.querySelectorAll("span.thundertext")); if (selected.length) { - if (confirm('一共要删除' + selected.length + '个文件,此操作不可撤销,是否确定?')) { + if ( + confirm("一共要删除" + selected.length + "个文件,此操作不可撤销,是否确定?") + ) { removeFile(selected, page); } + } else { + this.classList.add("active"); } - else { - this.classList.add('active'); - } - } - else { - this.classList.remove('active'); + } else { + this.classList.remove("active"); } }); deletebutton.style.zIndex = 1; - deletebutton.style.right = '10px'; - deletebutton.style.bottom = '145px'; + deletebutton.style.right = "10px"; + deletebutton.style.bottom = "145px"; page.backbutton = backbutton; page.addbutton = addbutton; page.deletebutton = deletebutton; var filelist = ui.create.div(page); - filelist.classList.add('file-container'); + filelist.classList.add("file-container"); filelist.listen(clickFileList); lib.setScroll(filelist); game.getFileList(path, function (folders, files) { @@ -948,122 +986,128 @@ export const optionsMenu = function (connectMenu) { files.sort(sort); var parent = path; if (parent) { - parent += '/'; + parent += "/"; } for (var i = 0; i < folders.length; i++) { - if (!page.path && folders[i] == 'app') continue; - var entry = ui.create.div('', '' + folders[i], filelist); - entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickDirectory); + if (!page.path && folders[i] == "app") continue; + var entry = ui.create.div("", "" + folders[i], filelist); + entry.firstChild.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + clickDirectory + ); entry.firstChild.path = parent + folders[i]; } for (var i = 0; i < files.length; i++) { if (!page.path) { - if (files[i] == 'app.html') continue; - if (files[i] == 'main.js') continue; - if (files[i] == 'package.json') continue; + if (files[i] == "app.html") continue; + if (files[i] == "main.js") continue; + if (files[i] == "package.json") continue; } - var entry = ui.create.div('', '' + files[i], filelist); - entry.firstChild.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', clickFile); - entry.firstChild.ext = files[i].slice(files[i].lastIndexOf('.') + 1); + var entry = ui.create.div("", "" + files[i], filelist); + entry.firstChild.addEventListener( + lib.config.touchscreen ? "touchend" : "click", + clickFile + ); + entry.firstChild.ext = files[i].slice(files[i].lastIndexOf(".") + 1); entry.firstChild.path = parent + files[i]; entry.firstChild.filename = files[i]; } }); }; var dash1 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); + var page = ui.create.div(".hidden.menu-buttons"); page.reset = function () { - page.innerHTML = ''; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + page.innerHTML = ""; + var backbutton = ui.create.div(".menubutton.round", "返", page, function () { ui.create.templayer(); page.hide(); pageboard.show(); }); backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - var placeholder = ui.create.div('.placeholder', page); - placeholder.style.position = 'relative'; - placeholder.style.display = 'block'; - placeholder.style.width = '100%'; - placeholder.style.height = '14px'; - createDash2('将', '武将图片', 'image/character', page); - createDash2('肤', '皮肤图片', 'image/skin', page); - createDash2('卡', '卡牌图片', 'image/card', page); - createDash2('模', '模式图片', 'image/mode', page); - createDash2('始', '开始图片', 'image/splash', page); - createDash2('景', '背景图片', 'image/background', page); + backbutton.style.right = "10px"; + backbutton.style.bottom = "15px"; + var placeholder = ui.create.div(".placeholder", page); + placeholder.style.position = "relative"; + placeholder.style.display = "block"; + placeholder.style.width = "100%"; + placeholder.style.height = "14px"; + createDash2("将", "武将图片", "image/character", page); + createDash2("肤", "皮肤图片", "image/skin", page); + createDash2("卡", "卡牌图片", "image/card", page); + createDash2("模", "模式图片", "image/mode", page); + createDash2("始", "开始图片", "image/splash", page); + createDash2("景", "背景图片", "image/background", page); }; page.reset(); return page; - }()); + })(); var dash2 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); + var page = ui.create.div(".hidden.menu-buttons"); page.reset = function () { - page.innerHTML = ''; - var backbutton = ui.create.div('.menubutton.round', '返', page, function () { + page.innerHTML = ""; + var backbutton = ui.create.div(".menubutton.round", "返", page, function () { ui.create.templayer(); page.hide(); pageboard.show(); }); backbutton.style.zIndex = 1; - backbutton.style.right = '10px'; - backbutton.style.bottom = '15px'; - var placeholder = ui.create.div('.placeholder', page); - placeholder.style.position = 'relative'; - placeholder.style.display = 'block'; - placeholder.style.width = '100%'; - placeholder.style.height = '14px'; - createDash2('技', '技能配音', 'audio/skill', page); - createDash2('卡', '男性卡牌', 'audio/card/male', page); - createDash2('牌', '女性卡牌', 'audio/card/female', page); - createDash2('亡', '阵亡配音', 'audio/die', page); - createDash2('效', '游戏音效', 'audio/effect', page); - createDash2('景', '背景音乐', 'audio/background', page); + backbutton.style.right = "10px"; + backbutton.style.bottom = "15px"; + var placeholder = ui.create.div(".placeholder", page); + placeholder.style.position = "relative"; + placeholder.style.display = "block"; + placeholder.style.width = "100%"; + placeholder.style.height = "14px"; + createDash2("技", "技能配音", "audio/skill", page); + createDash2("卡", "男性卡牌", "audio/card/male", page); + createDash2("牌", "女性卡牌", "audio/card/female", page); + createDash2("亡", "阵亡配音", "audio/die", page); + createDash2("效", "游戏音效", "audio/effect", page); + createDash2("景", "背景音乐", "audio/background", page); }; page.reset(); return page; - }()); + })(); var dash3 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.path = 'font'; + var page = ui.create.div(".hidden.menu-buttons"); + page.path = "font"; page.reset = function () { ui.create.templayer(); page.hide(); pageboard.show(); }; page.init = function () { - enterDirectory(page, 'font'); + enterDirectory(page, "font"); }; return page; - }()); + })(); var dash4 = (function () { - var page = ui.create.div('.hidden.menu-buttons'); - page.path = ''; + var page = ui.create.div(".hidden.menu-buttons"); + page.path = ""; page.reset = function () { ui.create.templayer(); page.hide(); pageboard.show(); }; page.init = function () { - enterDirectory(page, ''); + enterDirectory(page, ""); }; return page; - }()); - createDash('图', '图片文件', dash1); - createDash('音', '音频文件', dash2); - createDash('字', '字体文件', dash3); - createDash('全', '全部文件', dash4); + })(); + createDash("图", "图片文件", dash1); + createDash("音", "音频文件", dash2); + createDash("字", "字体文件", dash3); + createDash("全", "全部文件", dash4); }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - createModeConfig('others', start.firstChild); + if (!get.config("menu_loadondemand")) node._initLink(); + })(); + createModeConfig("others", start.firstChild); - var active = start.firstChild.querySelector('.active'); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); } if (!active.link) active._initLink(); rightPane.appendChild(active.link); -}; \ No newline at end of file +}; diff --git a/noname/ui/create/menu/pages/otherMenu.js b/noname/ui/create/menu/pages/otherMenu.js index 02fe7ac36..627c44a8b 100644 --- a/noname/ui/create/menu/pages/otherMenu.js +++ b/noname/ui/create/menu/pages/otherMenu.js @@ -1,11 +1,5 @@ import { menuContainer, - popupContainer, - updateActive, - setUpdateActive, - updateActiveCard, - setUpdateActiveCard, - menux, menuxpages, menuUpdates, openMenu, @@ -14,20 +8,18 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig -} from '../index.js'; + createConfig, +} from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; import { parseSize, checkVersion, - getRepoTags, getRepoTagDescription, - getRepoFilesList, - flattenRepositoryFiles, request, createProgress, - gainAuthorization -} from "../../../../library/update.js" + getLatestVersionFromGitHub, + getTreesFromGithub, +} from "../../../../library/update.js"; export const otherMenu = function (/** @type { boolean | undefined } */ connectMenu) { if (connectMenu) return; @@ -42,83 +34,82 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // @ts-ignore var start = cacheMenuxpages.shift(); var rightPane = start.lastChild; - var cheatButton = ui.create.div('.menubutton.round.highlight', '作', start); - cheatButton.style.display = 'none'; - var runButton = ui.create.div('.menubutton.round.highlight', '执', start); - runButton.style.display = 'none'; - var clearButton = ui.create.div('.menubutton.round.highlight', '清', start); - clearButton.style.display = 'none'; - clearButton.style.left = '275px'; - var playButton = ui.create.div('.menubutton.round.highlight.hidden', '播', start); - playButton.style.display = 'none'; - playButton.style.left = '215px'; - playButton.style.transition = 'opacity 0.3s'; - var deleteButton = ui.create.div('.menubutton.round.highlight.hidden', '删', start); - deleteButton.style.display = 'none'; - deleteButton.style.left = '275px'; - deleteButton.style.transition = 'opacity 0.3s'; - var saveButton = ui.create.div('.menubutton.round.highlight.hidden', '存', start); - saveButton.style.display = 'none'; - saveButton.style.transition = 'opacity 0.3s'; - + var cheatButton = ui.create.div(".menubutton.round.highlight", "作", start); + cheatButton.style.display = "none"; + var runButton = ui.create.div(".menubutton.round.highlight", "执", start); + runButton.style.display = "none"; + var clearButton = ui.create.div(".menubutton.round.highlight", "清", start); + clearButton.style.display = "none"; + clearButton.style.left = "275px"; + var playButton = ui.create.div(".menubutton.round.highlight.hidden", "播", start); + playButton.style.display = "none"; + playButton.style.left = "215px"; + playButton.style.transition = "opacity 0.3s"; + var deleteButton = ui.create.div(".menubutton.round.highlight.hidden", "删", start); + deleteButton.style.display = "none"; + deleteButton.style.left = "275px"; + deleteButton.style.transition = "opacity 0.3s"; + var saveButton = ui.create.div(".menubutton.round.highlight.hidden", "存", start); + saveButton.style.display = "none"; + saveButton.style.transition = "opacity 0.3s"; + /** + * @this { HTMLDivElement } + */ var clickMode = function () { - if (this.classList.contains('off')) return; - var active = this.parentNode.querySelector('.active'); + if (this.classList.contains("off")) return; + var active = this.parentNode.querySelector(".active"); if (active === this) { return; } if (active) { - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); } active = this; - this.classList.add('active'); + this.classList.add("active"); if (this.link) rightPane.appendChild(this.link); else { this._initLink(); rightPane.appendChild(this.link); } - if (this.type == 'cheat') { - cheatButton.style.display = ''; + if (this.type == "cheat") { + cheatButton.style.display = ""; + } else { + cheatButton.style.display = "none"; } - else { - cheatButton.style.display = 'none'; + if (this.type == "cmd") { + runButton.style.display = ""; + clearButton.style.display = ""; + } else { + runButton.style.display = "none"; + clearButton.style.display = "none"; } - if (this.type == 'cmd') { - runButton.style.display = ''; - clearButton.style.display = ''; - } - else { - runButton.style.display = 'none'; - clearButton.style.display = 'none'; - } - if (this.type == 'video') { - playButton.style.display = ''; - saveButton.style.display = ''; - deleteButton.style.display = ''; - } - else { - playButton.style.display = 'none'; - saveButton.style.display = 'none'; - deleteButton.style.display = 'none'; + if (this.type == "video") { + playButton.style.display = ""; + saveButton.style.display = ""; + deleteButton.style.display = ""; + } else { + playButton.style.display = "none"; + saveButton.style.display = "none"; + deleteButton.style.display = "none"; } }; ui.click.consoleMenu = function () { - ui.click.menuTab('其它'); + ui.click.menuTab("其它"); clickMode.call(ui.commandnode); }; //更新菜单有本体函数赋值,就不要懒加载了 (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '更新', start.firstChild, clickMode); + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "更新", start.firstChild, clickMode); node.link = page; - page.classList.add('menu-help'); - var ul = document.createElement('ul'); - var li1 = document.createElement('li'); - var li2 = document.createElement('li'); - var li3 = document.createElement('li'); + page.classList.add("menu-help"); + var ul = document.createElement("ul"); + var li1 = document.createElement("li"); + var li2 = document.createElement("li"); + var li3 = document.createElement("li"); // const trimURL = url => { // const updateURLS = lib.updateURLS; // for (const key in updateURLS) { @@ -141,11 +132,11 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // } // return url; // }; - li1.innerHTML = '游戏版本:' + lib.version + '

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

                                              '; + li1.innerHTML = "游戏版本:" + lib.version + '

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

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

                                              '; - li3.style.whiteSpace = 'nowrap'; - li3.style.display = 'none';// coding + li3.style.whiteSpace = "nowrap"; + li3.style.display = "none"; // coding /** * @type {HTMLButtonElement} @@ -159,58 +150,208 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM * @type {HTMLButtonElement} */ var checkDevVersionButton; - + game.checkForUpdate = async function (forcecheck, dev) { if (!dev && checkVersionButton.disabled) { return; - } - else if (dev && checkDevVersionButton.disabled) { + } else if (dev && checkDevVersionButton.disabled) { return; - } - else { + } else { if (dev) { - checkDevVersionButton.innerHTML = '正在检查更新'; - } - else { - checkVersionButton.innerHTML = '正在检查更新'; + checkDevVersionButton.innerHTML = "正在检查更新"; + } else { + checkVersionButton.innerHTML = "正在检查更新"; } checkDevVersionButton.disabled = true; checkVersionButton.disabled = true; - function refresh() { + const refresh = () => { checkVersionButton.disabled = false; - checkVersionButton.innerHTML = '检查游戏更新'; + checkVersionButton.innerHTML = "检查游戏更新"; checkDevVersionButton.disabled = false; - checkDevVersionButton.innerHTML = '更新到开发版'; + checkDevVersionButton.innerHTML = "更新到开发版"; + } + + /** + * @param {{ assets: any; author?: { login: string; avatar_url: string; html_url: string; }; body?: string; html_url?: string; name: any; published_at?: string; zipball_url: any; }} description + */ + const download = description => { + const progress = createProgress( + "正在更新" + description.name, + 1, + description.name + ".zip" + ); + /** + * @type {progress} + */ + let unZipProgress; + let url = description.zipball_url; + if (Array.isArray(description.assets) && description.assets.length > 0) { + const coreZipData = description.assets.find((v) => v.name == "noname.core.zip"); + if ( + coreZipData && + confirm( + `检测到该版本(${description.name})有离线包资源,是否改为下载离线包资源?否则将下载完整包资源` + ) + ) { + url = "https://ghproxy.cc/" + coreZipData.browser_download_url; + } + } + request(url, (receivedBytes, total, filename) => { + if (typeof filename == "string") { + progress.setFileName(filename); + } + let received = 0, + max = 0; + if (total) { + max = +(total / (1024 * 1024)).toFixed(1); + } else { + max = 1000; + } + received = +(receivedBytes / (1024 * 1024)).toFixed(1); + if (received > max) max = received; + progress.setProgressMax(max); + progress.setProgressValue(received); + }) + .then(async (blob) => { + progress.remove(); + const zip = await get.promises.zip(); + zip.load(await blob.arrayBuffer()); + const entries = Object.entries(zip.files); + let root; + const hiddenFileFlags = [".", "_"]; + unZipProgress = createProgress( + "正在解压" + progress.getFileName(), + entries.length + ); + let i = 0; + for (const [key, value] of entries) { + // 第一个是文件夹的话,就是根文件夹 + if (i == 0 && value.dir && !description.name.includes("noname.core.zip")) { + root = key; + } + unZipProgress.setProgressValue(i++); + const fileName = + typeof root == "string" && key.startsWith(root) + ? key.replace(root, "") + : key; + if (hiddenFileFlags.includes(fileName[0])) continue; + if (value.dir) { + await game.promises.createDir(fileName); + continue; + } + unZipProgress.setFileName(fileName); + const [path, name] = [ + fileName.split("/").slice(0, -1).join("/"), + fileName.split("/").slice(-1).join("/"), + ]; + game.print(`${fileName}(${i}/${entries.length})`); + await game.promises + .writeFile(value.asArrayBuffer(), path, name) + .catch(async (e) => { + // 特殊处理 + if ( + name == "noname-server.exe" && + e.message.includes("resource busy or locked") && + location.protocol.startsWith("http") + ) { + if ( + typeof window.require == "function" && + typeof window.process == "object" && + typeof window.__dirname == "string" + ) { + return new Promise((resolve, reject) => { + const cp = require("child_process"); + cp.exec(`taskkill /IM noname-server.exe /F`, (e) => { + if (e) reject(e); + else + game.promises + .writeFile(value.asArrayBuffer(), path, name) + .then(() => { + cp.exec( + `start /b ${__dirname}\\noname-server.exe -platform=electron`, + () => { } + ); + function loadURL() { + let myAbortController = + new AbortController(); + let signal = myAbortController.signal; + setTimeout( + () => myAbortController.abort(), + 2000 + ); + fetch( + `http://localhost:8089/app.html`, + { signal } + ) + .then(({ ok }) => { + if (ok) resolve(null); + else + throw new Error( + "fetch加载失败" + ); + }) + .catch(() => loadURL()); + } + loadURL(); + }) + .catch(reject); + }); + }); + } + } else throw e; + }); + } + unZipProgress.remove(); + if (url === description.zipball_url) { + await lib.init.promises.js("game", "update.js"); + if (Array.isArray(window.noname_asset_list)) { + game.saveConfig("asset_version", window.noname_asset_list[0]); + delete window.noname_asset_list; + } + } + if (confirm("更新完成,是否重启?")) { + game.reload(); + } + refresh(); + }) + .catch((e) => { + if (progress.parentNode) progress.remove(); + if (unZipProgress && unZipProgress.parentNode) unZipProgress.remove(); + refresh(); + throw e; + }); } if (!dev) { - getRepoTags() - .then(tags => tags.filter(tag => tag.name != 'v1998')[0]) - .then(tag => { - game.saveConfig('check_version', tag.name.slice(1)); - if (typeof lib.config['version_description_' + tag.name] == 'object') { + getLatestVersionFromGitHub() + .then(tagName => { + game.saveConfig("check_version", tagName.slice(1)); + if (typeof lib.config[`version_description_${tagName}`] == "object") { /** @type { ReturnType } */ - const description = lib.config['version_description_' + tag.name]; + const description = lib.config[`version_description_${tagName}`]; return description; } - else return getRepoTagDescription(tag.name); + else return getRepoTagDescription(tagName); }) .then(description => { // 保存版本信息 - if (typeof lib.config['version_description_' + description.name] != 'object') { - game.saveConfig('version_description_' + description.name, description); + if (typeof lib.config["version_description_" + description.name] != "object") { + game.saveConfig("version_description_" + description.name, description); } const versionResult = checkVersion(lib.version, description.name); if (versionResult === 0) { // forcecheck: 为false的时候是自动检测更新的调用 - if (forcecheck === false || !confirm('版本已是最新,是否强制更新?')) { + if (forcecheck === false || !confirm("版本已是最新,是否强制更新?")) { refresh(); return; } } - const str = versionResult > 0 ? (`有新版本${description.name}可用,是否下载?`) : (`本地版本${ lib.version }高于或等于github版本${description.name},是否强制下载?`); + const str = + versionResult < 0 + ? `有新版本${description.name}可用,是否下载?` + : `本地版本${lib.version}高于或等于github版本${description.name},是否强制下载?`; const str2 = description.body; if (navigator.notification && navigator.notification.confirm) { navigator.notification.confirm( @@ -218,274 +359,206 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM function (index) { if (index == 1) { download(description); - } - else refresh(); + } else refresh(); }, str, - ['确定', '取消'] + ["确定", "取消"] ); - } - else { - if (confirm(str + '\n' + str2)) { + } else { + if (confirm(str + "\n" + str2)) { download(description); - } - else refresh(); + } else refresh(); } }) - .catch(e => { - alert('获取更新失败: ' + e); + .catch((e) => { + alert("获取更新失败: " + e); refresh(); }); } else { - if (confirm('将要直接下载dev版本的完整包,是否继续?')) { + if (confirm("将要直接下载dev版本的完整包,是否继续?")) { download({ - name: 'noname-PR-Branch', + name: "noname-PR-Branch", assets: [], - zipball_url: 'https://ghproxy.cc/https://github.com/libccy/noname/archive/PR-Branch.zip' + zipball_url: + "https://ghproxy.cc/https://github.com/libccy/noname/archive/PR-Branch.zip", }); } else { refresh(); } } - /** - * @param {{ assets: any; author?: { login: string; avatar_url: string; html_url: string; }; body?: string; html_url?: string; name: any; published_at?: string; zipball_url: any; }} description - */ - function download(description) { - const progress = createProgress('正在更新' + description.name, 1, description.name + '.zip'); - /** - * @type {progress} - */ - let unZipProgress; - let url = description.zipball_url; - if (Array.isArray(description.assets) && description.assets.length > 0) { - const coreZipData = description.assets.find(v => v.name == 'noname.core.zip'); - if (coreZipData && confirm(`检测到该版本(${description.name})有离线包资源,是否改为下载离线包资源?否则将下载完整包资源`)) { - url = 'https://ghproxy.cc/' + coreZipData.browser_download_url; - } - } - request(url, (receivedBytes, total, filename) => { - if (typeof filename == 'string') { - progress.setFileName(filename); - } - let received = 0, max = 0; - if (total) { - max = +(total / (1024 * 1024)).toFixed(1) - } else { - max = 1000; - } - received = +(receivedBytes / (1024 * 1024)).toFixed(1); - if (received > max) max = received; - progress.setProgressMax(max); - progress.setProgressValue(received); - }).then(async blob => { - progress.remove(); - const zip = await get.promises.zip(); - zip.load(await blob.arrayBuffer()); - const entries = Object.entries(zip.files); - let root; - const hiddenFileFlags = ['.', '_']; - unZipProgress = createProgress('正在解压' + progress.getFileName(), entries.length); - let i = 0; - for (const [key, value] of entries) { - // 第一个是文件夹的话,就是根文件夹 - if (i == 0 && value.dir && !description.name.includes('noname.core.zip')) { - root = key; - } - unZipProgress.setProgressValue(i++); - const fileName = typeof root == 'string' && key.startsWith(root) ? key.replace(root, '') : key; - if (hiddenFileFlags.includes(fileName[0])) continue; - if (value.dir) { - await game.promises.createDir(fileName); - continue; - } - unZipProgress.setFileName(fileName); - const [path, name] = [fileName.split('/').slice(0, -1).join('/'), fileName.split('/').slice(-1).join('/')]; - game.print(`${fileName}(${i}/${entries.length})`); - await game.promises.writeFile(value.asArrayBuffer(), path, name) - .catch(async e => { - // 特殊处理 - if (name == 'noname-server.exe' && e.message.includes('resource busy or locked') && location.protocol.startsWith('http')) { - if (typeof window.require == 'function' && - typeof window.process == 'object' && - typeof window.__dirname == 'string') { - return new Promise((resolve, reject) => { - const cp = require('child_process'); - cp.exec(`taskkill /IM noname-server.exe /F`, e => { - if (e) reject(e); - else game.promises.writeFile(value.asArrayBuffer(), path, name).then(() => { - cp.exec(`start /b ${__dirname}\\noname-server.exe -platform=electron`, () => { }); - function loadURL() { - let myAbortController = new AbortController();; - let signal = myAbortController.signal; - setTimeout(() => myAbortController.abort(), 2000); - fetch(`http://localhost:8089/app.html`, { signal }) - .then(({ ok }) => { - if (ok) resolve(null); - else throw new Error('fetch加载失败'); - }) - .catch(() => loadURL()); - } - loadURL(); - }).catch(reject); - }); - }); - } - } else throw e; - }); - } - unZipProgress.remove(); - if (url === description.zipball_url) { - await lib.init.promises.js('game', 'update.js'); - if (Array.isArray(window.noname_asset_list)) { - game.saveConfig('asset_version', window.noname_asset_list[0]); - delete window.noname_asset_list; - } - } - if (confirm('更新完成,是否重启?')) { - game.reload(); - } - refresh(); - }).catch(e => { - if (progress.parentNode) progress.remove(); - if (unZipProgress && unZipProgress.parentNode) unZipProgress.remove(); - refresh(); - throw e; - }); - } } }; game.checkForAssetUpdate = async function () { if (checkAssetButton.disabled) { return; - } - else if (game.download) { - if (!localStorage.getItem('noname_authorization') && !sessionStorage.getItem('noname_authorization')) { - if (confirm('素材更新或许会直接超过每小时的访问限制,是否输入您github的token以解除访问每小时60次的限制?')) await gainAuthorization(); - } - checkAssetButton.innerHTML = '正在检查更新'; + } else if (game.download) { + // if ( + // !localStorage.getItem("noname_authorization") && + // !sessionStorage.getItem("noname_authorization") + // ) { + // if ( + // confirm( + // "素材更新或许会直接超过每小时的访问限制,是否输入您github的token以解除访问每小时60次的限制?" + // ) + // ) + // await gainAuthorization(); + // } + checkAssetButton.innerHTML = "正在检查更新"; checkAssetButton.disabled = true; - function refresh() { - checkAssetButton.innerHTML = '检查素材更新'; + + const refresh = () => { + checkAssetButton.innerHTML = "检查素材更新"; checkAssetButton.disabled = false; } - const assetDirs = []; - if (lib.config.asset_font) { - assetDirs.push('font'); - } - if (lib.config.asset_audio) { - assetDirs.push('audio'); - } - if (lib.config.asset_image) { - assetDirs.push('image'); - } - const files = await Promise.all(assetDirs.map(dir => flattenRepositoryFiles(dir))); - assetDirs.forEach((value, index) => { + + const assetDirectories = []; + if (lib.config.asset_font) assetDirectories.push("font"); + if (lib.config.asset_audio) assetDirectories.push("audio"); + if (lib.config.asset_image) assetDirectories.push("image"); + const version = await getLatestVersionFromGitHub().catch(e => { + refresh(); + throw e; + }); + const files = await getTreesFromGithub(assetDirectories, version).catch(e => { + refresh(); + throw e; + }); + + assetDirectories.forEach((assetDirectory, index) => { const arr = files[index]; const size = arr.reduce((previous, current) => { return previous + current.size; }, 0); - game.saveConfig(`asset_${value}_size`, parseSize(size)); + game.saveConfig(`asset_${assetDirectory}_size`, parseSize(size)); }); + /** - * @param { any[] } arr - * @param { Function } predicate + * @template T + * @param { T[] } arr + * @param { (value: T) => Promise } predicate */ const asyncFilter = async (arr, predicate) => { - // @ts-ignore - const results = await Promise.all(arr.map(predicate)); - // @ts-ignore + //将arr每10个分为一个数组,分别使用Promise.all + /** @type { boolean[] } */ + const results = []; + for (let i = 0; i < arr.length; i += 10) { + const pushArr = arr.slice(i, i + 10); + results.push( + ...await Promise.all(pushArr.map(predicate)) + ); + } return arr.filter((_v, index) => results[index]); - } - // @ts-ignore + }; + const result = await asyncFilter(files.flat(), async v => { - return v.size != (await game.promises.readFile(v.path)).length; - }).then(arr => arr.map(v => v.path)); - console.log('需要更新的文件有:', result); - game.print('需要更新的文件有:', result); + return game.promises.readFile(v.path).then(data => { + return v.size != data.byteLength; + }).catch(()=>true) + }).then(arr => arr.map((v) => v.path)); + + console.log("需要更新的文件有:", result); + game.print("需要更新的文件有:", result); const finish = async () => { - await lib.init.promises.js('game', 'asset.js'); + await lib.init.promises.js("game", "asset"); if (Array.isArray(window.noname_asset_list)) { - game.saveConfig('asset_version', window.noname_asset_list[0]); + game.saveConfig("asset_version", window.noname_asset_list[0]); delete window.noname_asset_list; } - if (confirm('更新完成,是否重启?')) { + if (confirm("更新完成,是否重启?")) { game.reload(); } refresh(); }; if (result.length > 0) { - const progress = createProgress('正在更新素材包.zip'); + const progress = createProgress("正在更新素材包.zip"); /** * @type {progress} */ let unZipProgress; - request('noname.unitedrhythmized.club/api', (receivedBytes, total, filename) => { - if (typeof filename == 'string') { - progress.setFileName(filename); - } - let received = 0, max = 0; - if (total) { - max = +(total / (1024 * 1024)).toFixed(1) - } else { - max = 1000; - } - received = +(receivedBytes / (1024 * 1024)).toFixed(1); - if (received > max) max = received; - progress.setProgressMax(max); - progress.setProgressValue(received); - }, { - method: 'post', - body: JSON.stringify({ - fileList: result.concat('game/asset.js') - }) - }).then(async blob => { - progress.remove(); - const zip = await get.promises.zip(); - zip.load(await blob.arrayBuffer()); - const entries = Object.entries(zip.files); - let root; - const hiddenFileFlags = ['.', '_']; - unZipProgress = createProgress('正在解压' + progress.getFileName(), entries.length); - let i = 0; - for (const [key, value] of entries) { - unZipProgress.setProgressValue(i++); - const fileName = typeof root == 'string' && key.startsWith(root) ? key.replace(root, '') : key; - if (hiddenFileFlags.includes(fileName[0])) continue; - if (value.dir) { - await game.promises.createDir(fileName); - continue; + request( + "https://api.unitedrhythmized.club/noname", + (receivedBytes, total, filename) => { + if (typeof filename == "string") { + progress.setFileName(filename); } - unZipProgress.setFileName(fileName); - const [path, name] = [fileName.split('/').slice(0, -1).join('/'), fileName.split('/').slice(-1).join('/')]; - game.print(`${fileName}(${i}/${entries.length})`); - await game.promises.writeFile(value.asArrayBuffer(), path, name); + let received = 0, + max = 0; + if (total) { + max = +(total / (1024 * 1024)).toFixed(1); + } else { + max = 1000; + } + received = +(receivedBytes / (1024 * 1024)).toFixed(1); + if (received > max) max = received; + progress.setProgressMax(max); + progress.setProgressValue(received); + }, + { + method: "POST", + body: JSON.stringify({ + action: "downloadAssets", + version, + fileList: result.concat("game/asset.js"), + }), } - unZipProgress.remove(); - await finish(); - }).catch(e => { - if (progress.parentNode) progress.remove(); - if (unZipProgress && unZipProgress.parentNode) unZipProgress.remove(); - refresh(); - throw e; - }); + ) + .then(async (blob) => { + progress.remove(); + const zip = await get.promises.zip(); + zip.load(await blob.arrayBuffer()); + const entries = Object.entries(zip.files); + let root; + const hiddenFileFlags = [".", "_"]; + unZipProgress = createProgress( + "正在解压" + progress.getFileName(), + entries.length + ); + let i = 0; + for (const [key, value] of entries) { + unZipProgress.setProgressValue(i++); + const fileName = + typeof root == "string" && key.startsWith(root) + ? key.replace(root, "") + : key; + if (hiddenFileFlags.includes(fileName[0])) continue; + if (value.dir) { + await game.promises.createDir(fileName); + continue; + } + unZipProgress.setFileName(fileName); + const [path, name] = [ + fileName.split("/").slice(0, -1).join("/"), + fileName.split("/").slice(-1).join("/"), + ]; + game.print(`${fileName}(${i}/${entries.length})`); + await game.promises.writeFile(value.asArrayBuffer(), path, name); + } + unZipProgress.remove(); + await finish(); + }) + .catch((e) => { + if (progress.parentNode) progress.remove(); + if (unZipProgress && unZipProgress.parentNode) unZipProgress.remove(); + refresh(); + throw e; + }); } else { await finish(); } - } - else { - alert('此版本不支持游戏内更新素材,请手动更新'); + } else { + alert("此版本不支持游戏内更新素材,请手动更新"); } }; - checkVersionButton = document.createElement('button'); - checkVersionButton.innerHTML = '检查游戏更新'; + checkVersionButton = document.createElement("button"); + checkVersionButton.innerHTML = "检查游戏更新"; checkVersionButton.onclick = () => game.checkForUpdate(null); li1.lastChild.appendChild(checkVersionButton); - checkDevVersionButton = document.createElement('button'); - checkDevVersionButton.innerHTML = '更新到开发版'; - checkDevVersionButton.style.marginLeft = '5px'; + checkDevVersionButton = document.createElement("button"); + checkDevVersionButton.innerHTML = "更新到开发版"; + checkDevVersionButton.style.marginLeft = "5px"; checkDevVersionButton.onclick = function () { game.checkForUpdate(null, true); }; @@ -496,37 +569,36 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM (function () { /** @type { HTMLParagraphElement } */ // @ts-ignore - var updatep1 = li1.querySelector('p'); + var updatep1 = li1.querySelector("p"); var updatep2 = li2; var updatep3 = li3; var updatep4 = node; - var updatepx = ui.create.node('p'); + var updatepx = ui.create.node("p"); li1.appendChild(updatepx); - updatepx.style.display = 'none'; - updatepx.style.whiteSpace = 'nowrap'; - updatepx.style.marginTop = '8px'; - var buttonx = ui.create.node('button', '访问项目主页', function () { - window.open('https://github.com/libccy/noname'); + updatepx.style.display = "none"; + updatepx.style.whiteSpace = "nowrap"; + updatepx.style.marginTop = "8px"; + var buttonx = ui.create.node("button", "访问项目主页", function () { + window.open("https://github.com/libccy/noname"); }); updatepx.appendChild(buttonx); ui.updateUpdate = function () { if (!game.download) { - updatep1.style.display = 'none'; - updatep2.style.display = 'none'; - updatep3.style.display = 'none'; - updatepx.style.display = ''; - updatep4.innerHTML = '关于'; - } - else { - updatep1.style.display = ''; - updatep2.style.display = ''; - updatep3.style.display = 'none'; // coding - updatepx.style.display = 'none'; - updatep4.innerHTML = '更新'; + updatep1.style.display = "none"; + updatep2.style.display = "none"; + updatep3.style.display = "none"; + updatepx.style.display = ""; + updatep4.innerHTML = "关于"; + } else { + updatep1.style.display = ""; + updatep2.style.display = ""; + updatep3.style.display = "none"; // coding + updatepx.style.display = "none"; + updatep4.innerHTML = "更新"; } }; ui.updateUpdate(); - }()); + })(); // button4 = document.createElement('button'); // button4.innerHTML = '设置更新地址'; @@ -571,38 +643,53 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // button6.style.display = 'none'; // } - checkAssetButton = document.createElement('button'); - checkAssetButton.innerHTML = '检查素材更新'; + checkAssetButton = document.createElement("button"); + checkAssetButton.innerHTML = "检查素材更新"; checkAssetButton.onclick = () => game.checkForAssetUpdate(); li2.lastChild.appendChild(checkAssetButton); - var span1 = ui.create.div('.config.more', '选项
                                              >
                                              '); - span1.style.fontSize = 'small'; - span1.style.display = 'inline'; + var span1 = ui.create.div(".config.more", "选项
                                              >
                                              "); + span1.style.fontSize = "small"; + span1.style.display = "inline"; span1.toggle = function () { - if (!this.classList.toggle('on')) { - game.saveConfig('asset_toggle_off', true); + if (!this.classList.toggle("on")) { + game.saveConfig("asset_toggle_off", true); [ /* span2, span2_br, span2_check,*/ - span3, span3_br, span3_check, - span4, span4_br, span4_check, - span5, span5_br, span5_check, + span3, + span3_br, + span3_check, + span4, + span4_br, + span4_check, + span5, + span5_br, + span5_check, /* span6, span6_br, span6_check,*/ - ].forEach(item => HTMLDivElement.prototype.css.call(item, { - display: 'none' - })); - } - else { - game.saveConfig('asset_toggle_off'); + ].forEach((item) => + HTMLDivElement.prototype.css.call(item, { + display: "none", + }) + ); + } else { + game.saveConfig("asset_toggle_off"); [ /* span2, span2_br, span2_check,*/ - span3, span3_br, span3_check, - span4, span4_br, span4_check, - span5, span5_br, span5_check, + span3, + span3_br, + span3_check, + span4, + span4_br, + span4_check, + span5, + span5_br, + span5_check, /* span6, span6_br, span6_check,*/ - ].forEach(item => HTMLDivElement.prototype.css.call(item, { - display: '' - })); + ].forEach((item) => + HTMLDivElement.prototype.css.call(item, { + display: "", + }) + ); } }; span1.listen(span1.toggle); @@ -612,38 +699,38 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // li2.lastChild.appendChild(span6_br); // var span2_br = ui.create.node('br'); - var span4 = ui.create.div('', `字体素材(${ lib.config.asset_font_size || '23.4MB' })`); - span4.style.fontSize = 'small'; - span4.style.lineHeight = '16px'; + var span4 = ui.create.div("", `字体素材(${lib.config.asset_font_size || "23.4MB"})`); + span4.style.fontSize = "small"; + span4.style.lineHeight = "16px"; li2.lastChild.appendChild(span4); - var span4_check = document.createElement('input'); - span4_check.type = 'checkbox'; - span4_check.style.marginLeft = '5px'; + var span4_check = document.createElement("input"); + span4_check.type = "checkbox"; + span4_check.style.marginLeft = "5px"; if (lib.config.asset_font) { span4_check.checked = true; } span4_check.onchange = function () { - game.saveConfig('asset_font', this.checked); + game.saveConfig("asset_font", this.checked); }; li2.lastChild.appendChild(span4_check); - var span3_br = ui.create.node('br'); + var span3_br = ui.create.node("br"); li2.lastChild.appendChild(span3_br); - var span3 = ui.create.div('', `音效素材(${ lib.config.asset_audio_size || '350MB' })`); - span3.style.fontSize = 'small'; - span3.style.lineHeight = '16px'; + var span3 = ui.create.div("", `音效素材(${lib.config.asset_audio_size || "350MB"})`); + span3.style.fontSize = "small"; + span3.style.lineHeight = "16px"; li2.lastChild.appendChild(span3); - var span3_check = document.createElement('input'); - span3_check.type = 'checkbox'; - span3_check.style.marginLeft = '5px'; + var span3_check = document.createElement("input"); + span3_check.type = "checkbox"; + span3_check.style.marginLeft = "5px"; if (lib.config.asset_audio) { span3_check.checked = true; } span3_check.onchange = function () { - game.saveConfig('asset_audio', this.checked); + game.saveConfig("asset_audio", this.checked); }; li2.lastChild.appendChild(span3_check); - var span4_br = ui.create.node('br'); + var span4_br = ui.create.node("br"); li2.lastChild.appendChild(span4_br); // var span2 = ui.create.div('', '皮肤素材(351MB)'); @@ -660,22 +747,22 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // game.saveConfig('asset_skin', this.checked); // }; // li2.lastChild.appendChild(span2_check); - var span5 = ui.create.div('', `图片素材(${lib.config.asset_image_size || '363MB'})`); - span5.style.fontSize = 'small'; - span5.style.lineHeight = '16px'; + var span5 = ui.create.div("", `图片素材(${lib.config.asset_image_size || "363MB"})`); + span5.style.fontSize = "small"; + span5.style.lineHeight = "16px"; li2.lastChild.appendChild(span5); - var span5_check = document.createElement('input'); - span5_check.type = 'checkbox'; - span5_check.style.marginLeft = '5px'; + var span5_check = document.createElement("input"); + span5_check.type = "checkbox"; + span5_check.style.marginLeft = "5px"; if (lib.config.asset_image) { span5_check.checked = true; } span5_check.onchange = function () { // @ts-ignore - game.saveConfig('asset_image', this.checked); + game.saveConfig("asset_image", this.checked); }; li2.lastChild.appendChild(span5_check); - var span5_br = ui.create.node('br'); + var span5_br = ui.create.node("br"); li2.lastChild.appendChild(span5_br); // li2.lastChild.appendChild(span2_br); @@ -693,80 +780,90 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM // game.saveConfig('asset_full', this.checked); // }; // li2.lastChild.appendChild(span6_check); - + [ /* span2, span2_br, span2_check,*/ - span3, span3_br, span3_check, - span4, span4_br, span4_check, - span5, span5_br, span5_check, + span3, + span3_br, + span3_check, + span4, + span4_br, + span4_check, + span5, + span5_br, + span5_check, /* span6, span6_br, span6_check,*/ - ].forEach(item => HTMLDivElement.prototype.css.call(item, { - display: 'none' - })); + ].forEach((item) => + HTMLDivElement.prototype.css.call(item, { + display: "none", + }) + ); ul.appendChild(li1); ul.appendChild(li2); ul.appendChild(li3); page.appendChild(ul); - if (!lib.config.asset_toggle_off) { span1.toggle(); } - }()); + })(); (function () { var norow2 = function () { var node = currentrow1; if (!node) return false; - return node.innerHTML == '横置' || node.innerHTML == '翻面' || node.innerHTML == '换人' || node.innerHTML == '复活'; + return ( + node.innerHTML == "横置" || + node.innerHTML == "翻面" || + node.innerHTML == "换人" || + node.innerHTML == "复活" + ); }; var checkCheat = function () { if (norow2()) { for (var i = 0; i < row2.childElementCount; i++) { - row2.childNodes[i].classList.remove('selectedx'); - row2.childNodes[i].classList.add('unselectable'); + row2.childNodes[i].classList.remove("selectedx"); + row2.childNodes[i].classList.add("unselectable"); } - } - else { + } else { for (var i = 0; i < row2.childElementCount; i++) { - row2.childNodes[i].classList.remove('unselectable'); + row2.childNodes[i].classList.remove("unselectable"); } } - if (currentrow1 && currentrow1.innerHTML == '复活') { + if (currentrow1 && currentrow1.innerHTML == "复活") { for (var i = 0; i < row3.childNodes.length; i++) { if (row3.childNodes[i].dead) { - row3.childNodes[i].style.display = ''; + row3.childNodes[i].style.display = ""; + } else { + row3.childNodes[i].style.display = "none"; + row3.childNodes[i].classList.remove("glow"); } - else { - row3.childNodes[i].style.display = 'none'; - row3.childNodes[i].classList.remove('glow'); - } - row3.childNodes[i].classList.remove('unselectable'); + row3.childNodes[i].classList.remove("unselectable"); } - } - else { + } else { for (var i = 0; i < row3.childElementCount; i++) { - if (currentrow1 && currentrow1.innerHTML == '换人' && row3.childNodes[i].link == game.me) { - row3.childNodes[i].classList.add('unselectable'); - } - else { - row3.childNodes[i].classList.remove('unselectable'); + if ( + currentrow1 && + currentrow1.innerHTML == "换人" && + row3.childNodes[i].link == game.me + ) { + row3.childNodes[i].classList.add("unselectable"); + } else { + row3.childNodes[i].classList.remove("unselectable"); } if (!row3.childNodes[i].dead) { - row3.childNodes[i].style.display = ''; - } - else { - row3.childNodes[i].style.display = 'none'; - row3.childNodes[i].classList.remove('glow'); + row3.childNodes[i].style.display = ""; + } else { + row3.childNodes[i].style.display = "none"; + row3.childNodes[i].classList.remove("glow"); } } } - if (currentrow1 && (currentrow2 || norow2()) && row3.querySelector('.glow')) { - cheatButton.classList.add('glowing'); + if (currentrow1 && (currentrow2 || norow2()) && row3.querySelector(".glow")) { + cheatButton.classList.add("glowing"); return true; - } - else { - cheatButton.classList.remove('glowing'); + } else { + cheatButton.classList.remove("glowing"); return false; } }; @@ -775,31 +872,55 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM var num; if (currentrow2) { switch (currentrow2.innerHTML) { - case '一': num = 1; break; - case '二': num = 2; break; - case '三': num = 3; break; - case '四': num = 4; break; - case '五': num = 5; break; + case "一": + num = 1; + break; + case "二": + num = 2; + break; + case "三": + num = 3; + break; + case "四": + num = 4; + break; + case "五": + num = 5; + break; } } var targets = []; - var buttons = row3.querySelectorAll('.glow'); + var buttons = row3.querySelectorAll(".glow"); for (var i = 0; i < buttons.length; i++) { targets.push(buttons[i].link); } while (targets.length) { var target = targets.shift(); switch (currentrow1.innerHTML) { - case '伤害': target.damage(num, 'nosource'); break; - case '回复': target.recover(num, 'nosource'); break; - case '摸牌': target.draw(num); break; - case '弃牌': target.discard(target.getCards('he').randomGets(num)); break; - case '横置': target.link(); break; - case '翻面': target.turnOver(); break; - case '复活': target.revive(target.maxHp); break; - case '换人': { + case "伤害": + target.damage(num, "nosource"); + break; + case "回复": + target.recover(num, "nosource"); + break; + case "摸牌": + target.draw(num); + break; + case "弃牌": + target.discard(target.getCards("he").randomGets(num)); + break; + case "横置": + target.link(); + break; + case "翻面": + target.turnOver(); + break; + case "复活": + target.revive(target.maxHp); + break; + case "换人": { if (_status.event.isMine()) { - if (!ui.auto.classList.contains('hidden')) { + if (!ui.auto.classList.contains("hidden")) { setTimeout(function () { ui.click.auto(); setTimeout(function () { @@ -808,8 +929,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM }, 500); }); } - } - else { + } else { game.swapPlayer(target); } break; @@ -823,81 +943,79 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM } }); - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '控制', start.firstChild, clickMode); + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "控制", start.firstChild, clickMode); node.link = page; - node.type = 'cheat'; - page.classList.add('menu-sym'); + node.type = "cheat"; + page.classList.add("menu-sym"); var currentrow1 = null; - var row1 = ui.create.div('.menu-cheat', page); + var row1 = ui.create.div(".menu-cheat", page); var clickrow1 = function () { - if (this.classList.contains('unselectable')) return; + if (this.classList.contains("unselectable")) return; if (currentrow1 == this) { - this.classList.remove('selectedx'); + this.classList.remove("selectedx"); currentrow1 = null; - } - else { - this.classList.add('selectedx'); + } else { + this.classList.add("selectedx"); if (currentrow1) { - currentrow1.classList.remove('selectedx'); + currentrow1.classList.remove("selectedx"); } currentrow1 = this; - if (this.innerHTML == '换人') { + if (this.innerHTML == "换人") { for (var i = 0; i < row3.childNodes.length; i++) { - row3.childNodes[i].classList.remove('glow'); + row3.childNodes[i].classList.remove("glow"); } } } checkCheat(); }; - var nodedamage = ui.create.div('.menubutton', '伤害', row1, clickrow1); - var noderecover = ui.create.div('.menubutton', '回复', row1, clickrow1); - var nodedraw = ui.create.div('.menubutton', '摸牌', row1, clickrow1); - var nodediscard = ui.create.div('.menubutton', '弃牌', row1, clickrow1); - var nodelink = ui.create.div('.menubutton', '横置', row1, clickrow1); - var nodeturnover = ui.create.div('.menubutton', '翻面', row1, clickrow1); - var noderevive = ui.create.div('.menubutton', '复活', row1, clickrow1); - var nodereplace = ui.create.div('.menubutton', '换人', row1, clickrow1); + var nodedamage = ui.create.div(".menubutton", "伤害", row1, clickrow1); + var noderecover = ui.create.div(".menubutton", "回复", row1, clickrow1); + var nodedraw = ui.create.div(".menubutton", "摸牌", row1, clickrow1); + var nodediscard = ui.create.div(".menubutton", "弃牌", row1, clickrow1); + var nodelink = ui.create.div(".menubutton", "横置", row1, clickrow1); + var nodeturnover = ui.create.div(".menubutton", "翻面", row1, clickrow1); + var noderevive = ui.create.div(".menubutton", "复活", row1, clickrow1); + var nodereplace = ui.create.div(".menubutton", "换人", row1, clickrow1); if (!game.canReplaceViewpoint || !game.canReplaceViewpoint()) { - nodereplace.classList.add('unselectable'); + nodereplace.classList.add("unselectable"); } var currentrow2 = null; - var row2 = ui.create.div('.menu-cheat', page); + var row2 = ui.create.div(".menu-cheat", page); var clickrow2 = function () { - if (this.classList.contains('unselectable')) return; + if (this.classList.contains("unselectable")) return; if (currentrow2 == this) { - this.classList.remove('selectedx'); + this.classList.remove("selectedx"); currentrow2 = null; - } - else { - this.classList.add('selectedx'); + } else { + this.classList.add("selectedx"); if (currentrow2) { - currentrow2.classList.remove('selectedx'); + currentrow2.classList.remove("selectedx"); } currentrow2 = this; } checkCheat(); }; - var nodex1 = ui.create.div('.menubutton', '一', row2, clickrow2); - var nodex2 = ui.create.div('.menubutton', '二', row2, clickrow2); - var nodex3 = ui.create.div('.menubutton', '三', row2, clickrow2); - var nodex4 = ui.create.div('.menubutton', '四', row2, clickrow2); - var nodex5 = ui.create.div('.menubutton', '五', row2, clickrow2); + var nodex1 = ui.create.div(".menubutton", "一", row2, clickrow2); + var nodex2 = ui.create.div(".menubutton", "二", row2, clickrow2); + var nodex3 = ui.create.div(".menubutton", "三", row2, clickrow2); + var nodex4 = ui.create.div(".menubutton", "四", row2, clickrow2); + var nodex5 = ui.create.div(".menubutton", "五", row2, clickrow2); - var row3 = ui.create.div('.menu-buttons.leftbutton.commandbutton', page); - row3.style.marginTop = '3px'; + var row3 = ui.create.div(".menu-buttons.leftbutton.commandbutton", page); + row3.style.marginTop = "3px"; var clickrow3 = function () { - if (this.classList.contains('unselectable')) return; - this.classList.toggle('glow'); - if (currentrow1 && currentrow1.innerHTML == '换人' && this.classList.contains('glow')) { + if (this.classList.contains("unselectable")) return; + this.classList.toggle("glow"); + if (currentrow1 && currentrow1.innerHTML == "换人" && this.classList.contains("glow")) { if (this.link == game.me) { - this.classList.remove('glow'); + this.classList.remove("glow"); } for (var i = 0; i < row3.childElementCount; i++) { if (row3.childNodes[i] != this) { - row3.childNodes[i].classList.remove('glow'); + row3.childNodes[i].classList.remove("glow"); } } } @@ -905,12 +1023,12 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM }; menuUpdates.push(function () { if (_status.video || _status.connectMode) { - node.classList.add('off'); - if (node.classList.contains('active')) { - node.classList.remove('active'); + node.classList.add("off"); + if (node.classList.contains("active")) { + node.classList.remove("active"); node.link.remove(); active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); rightPane.appendChild(active.link); } @@ -933,8 +1051,8 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM if (list.length) { row1.show(); row2.show(); - row3.innerHTML = ''; - var buttons = ui.create.buttons(list, 'player', row3, true); + row3.innerHTML = ""; + var buttons = ui.create.buttons(list, "player", row3, true); for (var i = 0; i < buttons.length; i++) { buttons[i].listen(clickrow3); if (game.dead.includes(buttons[i].link)) { @@ -942,93 +1060,100 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM } } checkCheat(); - } - else { + } else { row1.hide(); row2.hide(); } - if (lib.config.mode == 'identity' || lib.config.mode == 'guozhan' || lib.config.mode == 'doudizhu') { - if (game.notMe || (game.me && (game.me._trueMe || game.hasPlayer(function (current) { - return current._trueMe == game.me; - }))) || !game.phaseNumber || _status.qianlidanji) { - nodereplace.classList.add('unselectable'); - } - else if (_status.event.isMine() && ui.auto.classList.contains('hidden')) { - nodereplace.classList.add('unselectable'); - } - else { - nodereplace.classList.remove('unselectable'); + if ( + lib.config.mode == "identity" || + lib.config.mode == "guozhan" || + lib.config.mode == "doudizhu" + ) { + if ( + game.notMe || + (game.me && + (game.me._trueMe || + game.hasPlayer(function (current) { + return current._trueMe == game.me; + }))) || + !game.phaseNumber || + _status.qianlidanji + ) { + nodereplace.classList.add("unselectable"); + } else if (_status.event.isMine() && ui.auto.classList.contains("hidden")) { + nodereplace.classList.add("unselectable"); + } else { + nodereplace.classList.remove("unselectable"); } } if (game.dead.length == 0) { - noderevive.classList.add('unselectable'); - } - else { - noderevive.classList.remove('unselectable'); + noderevive.classList.add("unselectable"); + } else { + noderevive.classList.remove("unselectable"); } checkCheat(); }); - }()); + })(); (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '命令', start.firstChild, clickMode); + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "命令", start.firstChild, clickMode); ui.commandnode = node; - node.type = 'cmd'; + node.type = "cmd"; menuUpdates.push(function () { if (_status.connectMode) { - node.classList.add('off'); - if (node.classList.contains('active')) { - node.classList.remove('active'); + node.classList.add("off"); + if (node.classList.contains("active")) { + node.classList.remove("active"); if (node.link) node.link.remove(); active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); rightPane.appendChild(active.link); } } }); node._initLink = function () { node.link = page; - page.classList.add('menu-sym'); + page.classList.add("menu-sym"); - const text = document.createElement('div'); + const text = document.createElement("div"); text.css({ - 'width': '194px', - 'height': '124px', - 'padding': '3px', - 'borderRadius': '2px', - 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px', - 'textAlign': 'left', - 'webkitUserSelect': 'initial', - 'overflow': 'scroll', - 'position': 'absolute', - 'left': '30px', - 'top': '50px', - 'wordBreak': 'break-all' + width: "194px", + height: "124px", + padding: "3px", + borderRadius: "2px", + boxShadow: "rgba(0, 0, 0, 0.2) 0 0 0 1px", + textAlign: "left", + webkitUserSelect: "initial", + overflow: "scroll", + position: "absolute", + left: "30px", + top: "50px", + wordBreak: "break-all", }); - const pre = ui.create.node('pre.fullsize', text); + const pre = ui.create.node("pre.fullsize", text); text.css.call(pre, { - 'margin': '0', - 'padding': '0', - 'position': 'relative', - 'webkitUserSelect': 'text', - 'userSelect': 'text' + margin: "0", + padding: "0", + position: "relative", + webkitUserSelect: "text", + userSelect: "text", }); lib.setScroll(pre); page.appendChild(text); - const text2 = document.createElement('input'); + const text2 = document.createElement("input"); text.css.call(text2, { - 'width': '200px', - 'height': '20px', - 'padding': '0', - 'position': 'absolute', - 'top': '15px', - 'left': '30px', - 'resize': 'none', - 'border': 'none', - 'borderRadius': '2px', - 'boxShadow': 'rgba(0, 0, 0, 0.2) 0 0 0 1px' + width: "200px", + height: "20px", + padding: "0", + position: "absolute", + top: "15px", + left: "30px", + resize: "none", + border: "none", + borderRadius: "2px", + boxShadow: "rgba(0, 0, 0, 0.2) 0 0 0 1px", }); const g = {}; @@ -1041,58 +1166,60 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM ui: ui, get: get, ai: ai, - cheat: lib.cheat + cheat: lib.cheat, }); Object.defineProperties(proxyWindow, { - '_status': { + _status: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'lib': { + lib: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'game': { + game: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'ui': { + ui: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'get': { + get: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'ai': { + ai: { configurable: false, enumerable: true, - writable: false + writable: false, }, - 'cheat': { + cheat: { configurable: false, enumerable: true, - writable: false - } + writable: false, + }, }); proxyWindow = new Proxy(proxyWindow, { set(target, prop, newValue) { - if (!['_status', 'lib', 'game', 'ui', 'get', 'ai', 'cheat'].includes(prop)) { + if (!["_status", "lib", "game", "ui", "get", "ai", "cheat"].includes(prop)) { Reflect.set(window, prop, newValue); } return Reflect.set(target, prop, newValue); - } + }, }); //使用new Function隔绝作用域,避免在控制台可以直接访问到runCommand等变量 /** * @type { (value:string)=>any } */ - const fun = (new Function('window', ` + const fun = new Function( + "window", + ` const _status=window._status; const lib=window.lib; const game=window.game; @@ -1106,73 +1233,67 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM "use strict"; return eval(reg.test(value)?('('+value+')'):value); } - `))(proxyWindow); + ` + )(proxyWindow); const runCommand = () => { - if (text2.value && !['up', 'down'].includes(text2.value)) { + if (text2.value && !["up", "down"].includes(text2.value)) { logindex = -1; logs.unshift(text2.value); } - if (text2.value == 'cls') { - pre.innerHTML = ''; - text2.value = ''; - } - else if (text2.value == 'up') { + if (text2.value == "cls") { + pre.innerHTML = ""; + text2.value = ""; + } else if (text2.value == "up") { if (logindex + 1 < logs.length) { text2.value = logs[++logindex]; + } else { + text2.value = ""; } - else { - text2.value = ''; - } - } - else if (text2.value == 'down') { + } else if (text2.value == "down") { if (logindex >= 0) { logindex--; if (logindex < 0) { - text2.value = ''; - } - else { + text2.value = ""; + } else { text2.value = logs[logindex]; } + } else { + text2.value = ""; } - else { - text2.value = ''; - } - } - else if (text2.value.includes('无天使') && (text2.value.includes('无神佛') || text2.value.includes('无神') && text2.value.includes('无佛'))) { - game.print('密码正确!欢迎来到死后世界战线!'); + } else if ( + text2.value.includes("无天使") && + (text2.value.includes("无神佛") || + (text2.value.includes("无神") && text2.value.includes("无佛"))) + ) { + game.print("密码正确!欢迎来到死后世界战线!"); _status.keyVerified = true; - text2.value = ''; - } - else { + text2.value = ""; + } else { if (!game.observe && !game.online) { try { let value = text2.value.trim(); if (value.endsWith(";")) value = value.slice(0, -1).trim(); game.print(fun(value)); - } - catch (e) { + } catch (e) { game.print(e); } } - text2.value = ''; + text2.value = ""; } }; - text2.addEventListener('keydown', e => { + text2.addEventListener("keydown", (e) => { if (e.keyCode == 13) { runCommand(); - } - else if (e.keyCode == 38) { + } else if (e.keyCode == 38) { if (logindex + 1 < logs.length) { text2.value = logs[++logindex]; } - } - else if (e.keyCode == 40) { + } else if (e.keyCode == 40) { if (logindex >= 0) { logindex--; if (logindex < 0) { - text2.value = ''; - } - else { + text2.value = ""; + } else { text2.value = logs[logindex]; } } @@ -1181,57 +1302,60 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM page.appendChild(text2); game.print = function () { const args = [...arguments]; - const printResult = args.map(arg => { - if (typeof arg != 'string') { - const parse = (obj) => { - if (Array.isArray(obj)) { - return `[${obj.map(v => parse(v))}]`; - } else if (typeof obj == 'function') { - return `[Function ${obj.name}]`; - } else if (typeof obj != 'string') { - if (obj instanceof Error) { - return `${String(obj)}`; + const printResult = args + .map((arg) => { + if (typeof arg != "string") { + const parse = (obj) => { + if (Array.isArray(obj)) { + return `[${obj.map((v) => parse(v))}]`; + } else if (typeof obj == "function") { + return `[Function ${obj.name}]`; + } else if (typeof obj != "string") { + if (obj instanceof Error) { + return `${String(obj)}`; + } + return String(obj); + } else { + return `'${String(obj)}'`; } - return String(obj); + }; + if (typeof arg == "function") { + let argi; + try { + argi = get.stringify(arg); + if (argi === "") argi = arg.toString(); + } catch (_) { + argi = arg.toString(); + } + return argi + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } else if (typeof arg == "object") { + let msg = ""; + for (const name of Object.getOwnPropertyNames(arg)) { + msg += `${name}: ${parse(arg[name])}
                                              `; + } + return `
                                              ${parse(arg)}${msg}
                                              `; } else { - return `'${String(obj)}'`; + return parse(arg); } - }; - if (typeof arg == 'function') { - let argi; - try { - argi = get.stringify(arg); - if (argi === '') argi = arg.toString(); - } catch (_) { - argi = arg.toString(); - } - return argi.replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - } - else if (typeof arg == 'object') { - let msg = ''; - for (const name of Object.getOwnPropertyNames(arg)) { - msg += `${name}: ${parse(arg[name])}
                                              `; - } - return `
                                              ${parse(arg)}${msg}
                                              `; } else { - return parse(arg); + const str = String(arg); + if (!/<[a-zA-Z]+[^>]*?\/?>.*?(?=<\/[a-zA-Z]+[^>]*?>|$)/.exec(str)) + return str + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + else return str; } - } else { - const str = String(arg); - if (!/<[a-zA-Z]+[^>]*?\/?>.*?(?=<\/[a-zA-Z]+[^>]*?>|$)/.exec(str)) return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - else return str; - } - }).join(' '); - pre.innerHTML += printResult + '
                                              '; + }) + .join(" "); + pre.innerHTML += printResult + "
                                              "; text.scrollTop = text.scrollHeight; }; if (_status.toprint) { @@ -1240,147 +1364,162 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM } runButton.listen(runCommand); clearButton.listen(() => { - pre.innerHTML = ''; + pre.innerHTML = ""; }); }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); + if (!get.config("menu_loadondemand")) node._initLink(); + })(); (function () { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '战绩', start.firstChild, clickMode); - node.type = 'rec'; + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "战绩", start.firstChild, clickMode); + node.type = "rec"; node._initLink = function () { node.link = page; - page.style.paddingBottom = '10px'; + page.style.paddingBottom = "10px"; var reset = function () { - if (this.innerHTML == '重置') { - this.innerHTML = '确定'; + if (this.innerHTML == "重置") { + this.innerHTML = "确定"; var that = this; setTimeout(function () { - that.innerHTML = '重置'; + that.innerHTML = "重置"; }, 1000); - } - else { + } else { this.parentNode.previousSibling.remove(); this.parentNode.remove(); lib.config.gameRecord[this.parentNode.link] = { data: {} }; - game.saveConfig('gameRecord', lib.config.gameRecord); + game.saveConfig("gameRecord", lib.config.gameRecord); } }; for (var i = 0; i < lib.config.all.mode.length; i++) { if (!lib.config.gameRecord[lib.config.all.mode[i]]) continue; if (lib.config.gameRecord[lib.config.all.mode[i]].str) { - ui.create.div('.config.indent', lib.translate[lib.config.all.mode[i]], page).style.marginBottom = '-5px'; - var item = ui.create.div('.config.indent', lib.config.gameRecord[lib.config.all.mode[i]].str + '重置', page); - item.style.height = 'auto'; - item.lastChild.addEventListener('click', reset); - item.lastChild.classList.add('pointerdiv'); + ui.create.div( + ".config.indent", + lib.translate[lib.config.all.mode[i]], + page + ).style.marginBottom = "-5px"; + var item = ui.create.div( + ".config.indent", + lib.config.gameRecord[lib.config.all.mode[i]].str + "重置", + page + ); + item.style.height = "auto"; + item.lastChild.addEventListener("click", reset); + item.lastChild.classList.add("pointerdiv"); item.link = lib.config.all.mode[i]; } } }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); + if (!get.config("menu_loadondemand")) node._initLink(); + })(); (function () { if (!window.indexedDB || window.nodb) return; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', '录像', start.firstChild, clickMode); - node.type = 'video'; + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", "录像", start.firstChild, clickMode); + node.type = "video"; lib.videos = []; ui.create.videoNode = (video, before) => { lib.videos.remove(video); - lib.videos[before === true ? 'unshift' : 'push'](video); + lib.videos[before === true ? "unshift" : "push"](video); }; node._initLink = function () { node.link = page; - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); store.openCursor().onsuccess = function (e) { var cursor = e.target.result; if (cursor) { lib.videos.push(cursor.value); cursor.continue(); - } - else { + } else { lib.videos.sort(function (a, b) { return parseInt(b.time) - parseInt(a.time); }); var clickcapt = function () { - var current = this.parentNode.querySelector('.videonode.active'); + var current = this.parentNode.querySelector(".videonode.active"); if (current && current != this) { - current.classList.remove('active'); + current.classList.remove("active"); } - if (this.classList.toggle('active')) { + if (this.classList.toggle("active")) { playButton.show(); deleteButton.show(); saveButton.show(); - } - else { + } else { playButton.hide(); deleteButton.hide(); saveButton.hide(); } }; var staritem = function () { - this.parentNode.classList.toggle('starred'); - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); - if (this.parentNode.classList.contains('starred')) { + this.parentNode.classList.toggle("starred"); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); + if (this.parentNode.classList.contains("starred")) { this.parentNode.link.starred = true; - } - else { + } else { this.parentNode.link.starred = false; } store.put(this.parentNode.link); }; var createNode = function (video, before) { - var node = ui.create.div('.videonode.menubutton.large', clickcapt); + var node = ui.create.div(".videonode.menubutton.large", clickcapt); node.link = video; - var nodename1 = ui.create.div('.menubutton.videoavatar', node); - nodename1.setBackground(video.name1, 'character'); + var nodename1 = ui.create.div(".menubutton.videoavatar", node); + nodename1.setBackground(video.name1, "character"); if (video.name2) { - var nodename2 = ui.create.div('.menubutton.videoavatar2', node); - nodename2.setBackground(video.name2, 'character'); + var nodename2 = ui.create.div(".menubutton.videoavatar2", node); + nodename2.setBackground(video.name2, "character"); } var date = new Date(video.time); - var str = date.getFullYear() + '.' + (date.getMonth() + 1) + '.' + (date.getDate()) + ' ' + - date.getHours() + ':'; + var str = + date.getFullYear() + + "." + + (date.getMonth() + 1) + + "." + + date.getDate() + + " " + + date.getHours() + + ":"; var minutes = date.getMinutes(); if (minutes < 10) { - str += '0'; + str += "0"; } str += minutes; - ui.create.div('.caption', video.name[0], node); - ui.create.div('.text', str + '
                                              ' + video.name[1], node); + ui.create.div(".caption", video.name[0], node); + ui.create.div(".text", str + "
                                              " + video.name[1], node); if (video.win) { - ui.create.div('.victory', '胜', node); + ui.create.div(".victory", "胜", node); } if (before) { page.insertBefore(node, page.firstChild); - } - else { + } else { page.appendChild(node); } - ui.create.div('.video_star', '★', node, staritem); + ui.create.div(".video_star", "★", node, staritem); if (video.starred) { - node.classList.add('starred'); + node.classList.add("starred"); } }; for (var i = 0; i < lib.videos.length; i++) { createNode(lib.videos[i]); } ui.create.videoNode = createNode; - var importVideoNode = ui.create.div('.config.switcher.pointerspan', - '导入录像...', function () { - this.nextSibling.classList.toggle('hidden'); - }, page); - importVideoNode.style.marginLeft = '12px'; - importVideoNode.style.marginTop = '3px'; - var importVideo = ui.create.div('.config.hidden', page); - importVideo.style.whiteSpace = 'nowrap'; - importVideo.style.marginBottom = '80px'; - importVideo.style.marginLeft = '13px'; - importVideo.style.width = 'calc(100% - 30px)'; - importVideo.innerHTML = '' + + var importVideoNode = ui.create.div( + ".config.switcher.pointerspan", + '导入录像...', + function () { + this.nextSibling.classList.toggle("hidden"); + }, + page + ); + importVideoNode.style.marginLeft = "12px"; + importVideoNode.style.marginTop = "3px"; + var importVideo = ui.create.div(".config.hidden", page); + importVideo.style.whiteSpace = "nowrap"; + importVideo.style.marginBottom = "80px"; + importVideo.style.marginLeft = "13px"; + importVideo.style.width = "calc(100% - 30px)"; + importVideo.innerHTML = + '' + ''; importVideo.lastChild.onclick = function () { var fileToLoad = importVideo.firstChild.files[0]; @@ -1390,13 +1529,12 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM if (!data) return; try { data = JSON.parse(lib.init.decode(data)); - } - catch (e) { + } catch (e) { console.log(e); - alert('导入失败'); + alert("导入失败"); return; } - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); var videos = lib.videos.slice(0); for (var i = 0; i < videos.length; i++) { if (videos[i].starred) { @@ -1414,14 +1552,13 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM break; } } - } - else { + } else { break; } } for (var i = 0; i < lib.videos.length; i++) { if (lib.videos[i].time == data.time) { - alert('录像已存在'); + alert("录像已存在"); return; } } @@ -1433,114 +1570,112 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM }; playButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); + var current = this.parentNode.querySelector(".videonode.active"); if (current) { game.playVideo(current.link.time, current.link.mode); } }); deleteButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); + var current = this.parentNode.querySelector(".videonode.active"); if (current) { lib.videos.remove(current.link); - var store = lib.db.transaction(['video'], 'readwrite').objectStore('video'); + var store = lib.db.transaction(["video"], "readwrite").objectStore("video"); store.delete(current.link.time); current.remove(); } }); saveButton.listen(function () { - var current = this.parentNode.querySelector('.videonode.active'); + var current = this.parentNode.querySelector(".videonode.active"); if (current) { - game.export(lib.init.encode(JSON.stringify(current.link)), - '无名杀 - 录像 - ' + current.link.name[0] + ' - ' + current.link.name[1]); + game.export( + lib.init.encode(JSON.stringify(current.link)), + "无名杀 - 录像 - " + current.link.name[0] + " - " + current.link.name[1] + ); } }); ui.updateVideoMenu = function () { - var active = start.firstChild.querySelector('.active'); + var active = start.firstChild.querySelector(".active"); if (active) { - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); } - node.classList.add('active'); + node.classList.add("active"); rightPane.appendChild(page); - playButton.style.display = ''; - deleteButton.style.display = ''; - saveButton.style.display = ''; + playButton.style.display = ""; + deleteButton.style.display = ""; + saveButton.style.display = ""; }; } }; }; - if (!get.config('menu_loadondemand')) node._initLink(); - }()); - + if (!get.config("menu_loadondemand")) node._initLink(); + })(); for (var i in lib.help) { - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', i, start.firstChild, clickMode); - node.type = 'help'; + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", i, start.firstChild, clickMode); + node.type = "help"; node.link = page; - node.style.display = 'none'; - page.classList.add('menu-help'); + node.style.display = "none"; + page.classList.add("menu-help"); page.innerHTML = lib.help[i]; } if (!connectMenu) { - var node = ui.create.div('.menubutton.large', '帮助', start.firstChild, function () { - var activex = start.firstChild.querySelector('.active'); - if (this.innerHTML == '帮助') { - cheatButton.style.display = 'none'; - runButton.style.display = 'none'; - clearButton.style.display = 'none'; - playButton.style.display = 'none'; - saveButton.style.display = 'none'; - deleteButton.style.display = 'none'; + var node = ui.create.div(".menubutton.large", "帮助", start.firstChild, function () { + var activex = start.firstChild.querySelector(".active"); + if (this.innerHTML == "帮助") { + cheatButton.style.display = "none"; + runButton.style.display = "none"; + clearButton.style.display = "none"; + playButton.style.display = "none"; + saveButton.style.display = "none"; + deleteButton.style.display = "none"; - this.innerHTML = '返回'; + this.innerHTML = "返回"; for (var i = 0; i < start.firstChild.childElementCount; i++) { var nodex = start.firstChild.childNodes[i]; if (nodex == node) continue; - if (nodex.type == 'help') { - nodex.style.display = ''; - if (activex && activex.type != 'help') { - activex.classList.remove('active'); + if (nodex.type == "help") { + nodex.style.display = ""; + if (activex && activex.type != "help") { + activex.classList.remove("active"); activex.link.remove(); activex = null; - nodex.classList.add('active'); + nodex.classList.add("active"); rightPane.appendChild(nodex.link); } - } - else { - nodex.style.display = 'none'; + } else { + nodex.style.display = "none"; } } - } - else { - this.innerHTML = '帮助'; + } else { + this.innerHTML = "帮助"; for (var i = 0; i < start.firstChild.childElementCount; i++) { var nodex = start.firstChild.childNodes[i]; if (nodex == node) continue; - if (nodex.type != 'help') { - nodex.style.display = ''; - if (activex && activex.type == 'help') { - activex.classList.remove('active'); + if (nodex.type != "help") { + nodex.style.display = ""; + if (activex && activex.type == "help") { + activex.classList.remove("active"); activex.link.remove(); activex = null; clickMode.call(nodex); } - } - else { - nodex.style.display = 'none'; + } else { + nodex.style.display = "none"; } } } }); } - var active = start.firstChild.querySelector('.active'); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); } if (!active.link) active._initLink(); rightPane.appendChild(active.link); -}; \ No newline at end of file +}; diff --git a/noname/ui/create/menu/pages/startMenu.js b/noname/ui/create/menu/pages/startMenu.js index 189aac62c..f7acae544 100644 --- a/noname/ui/create/menu/pages/startMenu.js +++ b/noname/ui/create/menu/pages/startMenu.js @@ -14,7 +14,7 @@ import { clickContainer, clickMenuItem, createMenu, - createConfig + createConfig, } from "../index.js"; import { ui, game, get, ai, lib, _status } from "../../../../../noname.js"; @@ -32,52 +32,54 @@ export const startMenu = function (connectMenu) { var rightPane = start.lastChild; /** 启动按钮 */ - let startButton = ui.create.div('.menubutton.round.highlight', '启', start, function () { - if (this.animating || this.classList.contains('dim')) { + let startButton = ui.create.div(".menubutton.round.highlight", "启", start, function () { + if (this.animating || this.classList.contains("dim")) { return; } - var active = this.parentNode.querySelector('.active'); + var active = this.parentNode.querySelector(".active"); if (active) { if (connectMenu) { if (_status.waitingForPlayer) { var config = {}; for (var i in lib.mode[lib.configOL.mode].connect) { - if (i == 'update') continue; + if (i == "update") continue; config[i.slice(8)] = get.config(i, lib.configOL.mode); } config.zhinang_tricks = lib.config.connect_zhinang_tricks; if (game.online) { if (game.onlinezhu) { - game.send('changeRoomConfig', config); + game.send("changeRoomConfig", config); } - } - else { + } else { game.broadcastAll(function (config) { for (var i in config) { lib.configOL[i] = config[i]; } }, config); - if (lib.configOL.mode == 'identity' && lib.configOL.identity_mode == 'zhong' && game.connectPlayers) { + if ( + lib.configOL.mode == "identity" && + lib.configOL.identity_mode == "zhong" && + game.connectPlayers + ) { for (var i = 0; i < game.connectPlayers.length; i++) { - game.connectPlayers[i].classList.remove('unselectable2'); + game.connectPlayers[i].classList.remove("unselectable2"); } lib.configOL.number = 8; game.updateWaiting(); } if (game.onlineroom) { - game.send('server', 'config', lib.configOL); + game.send("server", "config", lib.configOL); } - game.connectPlayers[0].chat('房间设置已更改'); + game.connectPlayers[0].chat("房间设置已更改"); } - } - else if (_status.enteringroom || _status.creatingroom) { + } else if (_status.enteringroom || _status.creatingroom) { lib.configOL.mode = active.mode; if (_status.enteringroomserver) { - game.saveConfig('connect_mode', lib.configOL.mode); + game.saveConfig("connect_mode", lib.configOL.mode); var config = {}; for (var i in lib.mode[lib.configOL.mode].connect) { - if (i == 'update') continue; + if (i == "update") continue; config[i.slice(8)] = get.config(i, lib.configOL.mode); } config.zhinang_tricks = lib.config.connect_zhinang_tricks; @@ -90,44 +92,59 @@ export const startMenu = function (connectMenu) { for (var i = 0; i < lib.config.connect_cards.length; i++) { config.cardPack.remove(lib.config.connect_cards[i]); } - config.banned = lib.config['connect_' + active.mode + '_banned']; - config.bannedcards = lib.config['connect_' + active.mode + '_bannedcards']; - game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar, config, active.mode); + config.banned = lib.config["connect_" + active.mode + "_banned"]; + config.bannedcards = lib.config["connect_" + active.mode + "_bannedcards"]; + game.send( + "server", + "create", + game.onlineKey, + get.connectNickname(), + lib.config.connect_avatar, + config, + active.mode + ); + } else { + game.send( + "server", + "create", + game.onlineKey, + get.connectNickname(), + lib.config.connect_avatar + ); } - else { - game.send('server', 'create', game.onlineKey, get.connectNickname(), lib.config.connect_avatar); - } - } - else { - localStorage.setItem(lib.configprefix + 'directstart', true); - game.saveConfig('directstartmode', active.mode); - game.saveConfig('mode', 'connect'); - ui.exitroom = ui.create.system('退出房间', function () { - game.saveConfig('directstartmode'); - game.reload(); - }, true); + } else { + localStorage.setItem(lib.configprefix + "directstart", true); + game.saveConfig("directstartmode", active.mode); + game.saveConfig("mode", "connect"); + ui.exitroom = ui.create.system( + "退出房间", + function () { + game.saveConfig("directstartmode"); + game.reload(); + }, + true + ); game.switchMode(active.mode); } clickContainer.call(cacheMenuContainer, connectMenu); - } - else { - game.saveConfig('mode', active.mode); - localStorage.setItem(lib.configprefix + 'directstart', true); + } else { + game.saveConfig("mode", active.mode); + localStorage.setItem(lib.configprefix + "directstart", true); game.reload(); } } }); var clickMode = function () { - if (this.classList.contains('unselectable')) return; - var active = this.parentNode.querySelector('.active'); + if (this.classList.contains("unselectable")) return; + var active = this.parentNode.querySelector(".active"); if (active === this) { return; } - active.classList.remove('active'); + active.classList.remove("active"); active.link.remove(); active = this; - this.classList.add('active'); + this.classList.add("active"); if (this.link) rightPane.appendChild(this.link); else { this._initLink(); @@ -141,8 +158,8 @@ export const startMenu = function (connectMenu) { var createModeConfig = function (mode, position) { var info = lib.mode[mode]; - var page = ui.create.div(''); - var node = ui.create.div('.menubutton.large', info.name, position, clickMode); + var page = ui.create.div(""); + var node = ui.create.div(".menubutton.large", info.name, position, clickMode); node.mode = mode; var connectDisplayMap = { connect_player_number: null, @@ -151,22 +168,21 @@ export const startMenu = function (connectMenu) { var updateConnectDisplayMap = function () { if (_status.waitingForPlayer) { if (connectDisplayMap.connect_player_number) { - connectDisplayMap.connect_player_number.style.display = 'none'; + connectDisplayMap.connect_player_number.style.display = "none"; } if (connectDisplayMap.connect_versus_mode) { - connectDisplayMap.connect_versus_mode.style.display = 'none'; + connectDisplayMap.connect_versus_mode.style.display = "none"; } } }; if (connectMenu) { menuUpdates.push(updateConnectDisplayMap); if (mode == lib.config.connect_mode) { - node.classList.add('active'); + node.classList.add("active"); } - } - else { + } else { if (mode == lib.config.mode) { - node.classList.add('active'); + node.classList.add("active"); } } node._initLink = function () { @@ -179,36 +195,36 @@ export const startMenu = function (connectMenu) { var config = lib.config.mode_config[mode] || {}; if (connectMenu) { infoconfig.connect_choose_timeout = { - name: '出牌时限', - init: '30', + name: "出牌时限", + init: "30", item: { - '10': '10秒', - '15': '15秒', - '30': '30秒', - '60': '60秒', - '90': '90秒', + 10: "10秒", + 15: "15秒", + 30: "30秒", + 60: "60秒", + 90: "90秒", }, connect: true, - frequent: true + frequent: true, }; infoconfig.connect_observe = { - name: '允许旁观', + name: "允许旁观", init: true, - connect: true + connect: true, }; infoconfig.connect_observe_handcard = { - name: '允许观看手牌', + name: "允许观看手牌", init: false, - connect: true + connect: true, }; infoconfig.connect_mount_combine = { - name: '合并坐骑栏', + name: "合并坐骑栏", init: false, - connect: true + connect: true, }; } for (var j in infoconfig) { - if (j === 'update') { + if (j === "update") { continue; } var cfg = get.copy(infoconfig[j]); @@ -216,8 +232,7 @@ export const startMenu = function (connectMenu) { cfg.mode = mode; if (j in config) { cfg.init = config[j]; - } - else { + } else { game.saveConfig(j, cfg.init, mode); } if (!cfg.onclick) { @@ -228,13 +243,12 @@ export const startMenu = function (connectMenu) { cfg.onsave.call(this, result); } if (!_status.connectMode || game.online) { - if (typeof cfg.restart == 'function') { + if (typeof cfg.restart == "function") { if (cfg.restart()) { - startButton.classList.add('glowing'); + startButton.classList.add("glowing"); } - } - else if (cfg.restart) { - startButton.classList.add('glowing'); + } else if (cfg.restart) { + startButton.classList.add("glowing"); } } }; @@ -248,14 +262,16 @@ export const startMenu = function (connectMenu) { map[j] = cfgnode; if (cfg.frequent) { page.appendChild(cfgnode); - } - else { - cfgnode.classList.add('auto-hide'); + } else { + cfgnode.classList.add("auto-hide"); hiddenNodes.push(cfgnode); } } if (!connectMenu) { - var move = ui.create.div('.auto-hide.config', '
                                              上移↑
                                              下移↓
                                              '); + var move = ui.create.div( + ".auto-hide.config", + '
                                              上移↑
                                              下移↓
                                              ' + ); move.firstChild.listen(function () { if (node.previousSibling) { node.parentNode.insertBefore(node, node.previousSibling); @@ -263,22 +279,21 @@ export const startMenu = function (connectMenu) { for (var i = 0; i < node.parentNode.childNodes.length; i++) { order.push(node.parentNode.childNodes[i].mode); } - game.saveConfig('modeorder', order); + game.saveConfig("modeorder", order); } }); move.lastChild.listen(function () { if (node.nextSibling) { if (node.nextSibling.nextSibling) { node.parentNode.insertBefore(node, node.nextSibling.nextSibling); - } - else { + } else { node.parentNode.insertBefore(node.nextSibling, node); } var order = []; for (var i = 0; i < node.parentNode.childNodes.length; i++) { order.push(node.parentNode.childNodes[i].mode); } - game.saveConfig('modeorder', order); + game.saveConfig("modeorder", order); } }); hiddenNodes.push(move); @@ -288,54 +303,55 @@ export const startMenu = function (connectMenu) { if (hiddenNodes.length) { if (lib.config.fold_mode) { var clickmore = function (type) { - if (type === 'expand' && expanded) return; - if (type === 'unexpand' && !expanded) return; + if (type === "expand" && expanded) return; + if (type === "unexpand" && !expanded) return; if (expanded) { - this.classList.remove('on'); - this.parentNode.classList.remove('expanded'); - } - else { - this.classList.add('on'); - this.parentNode.classList.add('expanded'); + this.classList.remove("on"); + this.parentNode.classList.remove("expanded"); + } else { + this.classList.add("on"); + this.parentNode.classList.add("expanded"); } expanded = !expanded; }; - var morenodes = ui.create.div('.config.more', '更多
                                              >
                                              ', page); + var morenodes = ui.create.div(".config.more", "更多
                                              >
                                              ", page); morenodes.listen(clickmore); morenodes._onclick = clickmore; page.morenodes = morenodes; - } - else { - page.classList.add('expanded'); + } else { + page.classList.add("expanded"); if (!connectMenu) { - page.classList.add('expanded2'); + page.classList.add("expanded2"); } } for (var k = 0; k < hiddenNodes.length; k++) { page.appendChild(hiddenNodes[k]); } - } - else { + } else { hasexpand = false; } if (!connectMenu) { - var hidemode = ui.create.div('.config.pointerspan', '隐藏此模式', page, function () { - if (this.firstChild.innerHTML == '隐藏此模式') { - this.firstChild.innerHTML = '此模式将在重启后隐藏'; - lib.config.hiddenModePack.add(mode); - if (!lib.config.prompt_hidepack) { - alert('隐藏的扩展包可通过选项-其它-重置隐藏内容恢复'); - game.saveConfig('prompt_hidepack', true); + var hidemode = ui.create.div( + ".config.pointerspan", + "隐藏此模式", + page, + function () { + if (this.firstChild.innerHTML == "隐藏此模式") { + this.firstChild.innerHTML = "此模式将在重启后隐藏"; + lib.config.hiddenModePack.add(mode); + if (!lib.config.prompt_hidepack) { + alert("隐藏的扩展包可通过选项-其它-重置隐藏内容恢复"); + game.saveConfig("prompt_hidepack", true); + } + } else { + this.firstChild.innerHTML = "隐藏此模式"; + lib.config.hiddenModePack.remove(mode); } + game.saveConfig("hiddenModePack", lib.config.hiddenModePack); } - else { - this.firstChild.innerHTML = '隐藏此模式'; - lib.config.hiddenModePack.remove(mode); - } - game.saveConfig('hiddenModePack', lib.config.hiddenModePack); - }); + ); if (hasexpand) { - hidemode.classList.add('auto-hide'); + hidemode.classList.add("auto-hide"); } } if (infoconfig.update) { @@ -351,7 +367,7 @@ export const startMenu = function (connectMenu) { updateConnectDisplayMap(); } }; - if (!get.config('menu_loadondemand')) node._initLink(); + if (!get.config("menu_loadondemand")) node._initLink(); return node; }; var modeorder = lib.config.modeorder || []; @@ -361,37 +377,40 @@ export const startMenu = function (connectMenu) { for (var i = 0; i < modeorder.length; i++) { if (connectMenu) { if (!lib.mode[modeorder[i]].connect) continue; - if (!lib.config['connect_' + modeorder[i] + '_banned']) { - lib.config['connect_' + modeorder[i] + '_banned'] = []; + if (!lib.config["connect_" + modeorder[i] + "_banned"]) { + lib.config["connect_" + modeorder[i] + "_banned"] = []; } - if (!lib.config['connect_' + modeorder[i] + '_bannedcards']) { - lib.config['connect_' + modeorder[i] + '_bannedcards'] = []; + if (!lib.config["connect_" + modeorder[i] + "_bannedcards"]) { + lib.config["connect_" + modeorder[i] + "_bannedcards"] = []; } } if (lib.config.all.mode.includes(modeorder[i])) { createModeConfig(modeorder[i], start.firstChild); } } - var active = start.firstChild.querySelector('.active'); + var active = start.firstChild.querySelector(".active"); if (!active) { active = start.firstChild.firstChild; - active.classList.add('active'); + active.classList.add("active"); } if (!active.link) active._initLink(); rightPane.appendChild(active.link); if (lib.config.fold_mode) { - rightPane.addEventListener('mousewheel', function (e) { - var morenodes = this.firstChild.morenodes; - if (morenodes) { - if (e.wheelDelta < 0) { - morenodes._onclick.call(morenodes, 'expand'); + rightPane.addEventListener( + "mousewheel", + function (e) { + var morenodes = this.firstChild.morenodes; + if (morenodes) { + if (e.wheelDelta < 0) { + morenodes._onclick.call(morenodes, "expand"); + } else if (this.scrollTop == 0) { + morenodes._onclick.call(morenodes, "unexpand"); + } } - else if (this.scrollTop == 0) { - morenodes._onclick.call(morenodes, 'unexpand'); - } - } - }, { passive: true }); + }, + { passive: true } + ); } return startButton; -}; \ No newline at end of file +}; diff --git a/noname/ui/index.js b/noname/ui/index.js index 345da2432..638e0ca9d 100644 --- a/noname/ui/index.js +++ b/noname/ui/index.js @@ -1,709 +1,719 @@ -import { Uninstantable, nonameInitialized } from "../util/index.js"; -import { Library as lib } from '../library/index.js'; -import { Game as game } from "../game/index.js"; -import { Get as get } from "../get/index.js"; -import { _status } from "../status/index.js"; -import { GNC as gnc } from '../gnc/index.js'; -import { AI as ai } from "../ai/index.js"; -import { Click } from "./click/index.js"; -import { Create } from "./create/index.js"; - -export class UI extends Uninstantable { - static updates = []; - static thrown = []; - static touchlines = []; - static todiscard = {}; - /** - * @type { HTMLStyleElement[] } - */ - static playerPositions = []; - static create = Create; - static click = Click; - static selected = { - /** - * @type { Button[] } - */ - buttons: [], - /** - * @type { Card[] } - */ - cards: [], - /** - * @type { Player[] } - */ - targets: [] - }; - /** - * @type { Dialog[] } - */ - static dialogs; - /** - * @type { Dialog } - */ - static dialog; - /** - * @type { HTMLDivElement } - */ - static arena; - /** - * @type { Control[] } - */ - static controls; - /** - * @type { Control } - */ - static control; - /** - * @type { Control | undefined } - */ - static confirm; - /** - * @type { Control | undefined } - */ - static skills; - /** - * @type { Control | undefined } - */ - static skills1; - /** - * @type { Control | undefined } - */ - static skills2; - /** - * @type { Control | undefined } - */ - static skills3; - /** - * @type { HTMLDivElement } - */ - static window; - /** - * @type { HTMLDivElement } - */ - static pause; - /** - * @type { HTMLAudioElement } - */ - static backgroundMusic; - /** - * @type { HTMLDivElement } - */ - static special; - /** - * @type { HTMLDivElement } - */ - static fakeme; - /** - * @type { HTMLDivElement } - */ - static chess; - /** - * 手动在菜单栏中添加一个武将包的ui - * @type { ((packName: string) => void)[] } - */ - static updateCharacterPackMenu = []; - /** - * 手动在菜单栏中添加一个卡牌包的ui - * @type { ((packName: string) => void)[] } - */ - static updateCardPackMenu = []; - /** - * @type { HTMLDivElement } 挑战模式下正在操作的角色 - */ - static mebg; - /** - * @type { Function | undefined } - */ - static updateUpdate; - /** - * @type {HTMLDivElement} - */ - static commandnode; - /** - * @type {() => void} - */ - static updateVideoMenu; - /** - * @type {HTMLDivElement} - */ - static menuContainer; - /** - * @type {HTMLDivElement} - */ - static auto; - /** - * @type {HTMLDivElement} - */ - static wuxie; - /** - * @type {HTMLDivElement} - */ - static tempnowuxie; - static refresh(node) { - void window.getComputedStyle(node, null).getPropertyValue("opacity"); - } - static clear() { - game.addVideo('uiClear'); - var thrown = document.getElementsByClassName('thrown'); - var nodes = []; - var i; - for (i = 0; i < thrown.length; i++) { - nodes.push(thrown[i]); - } - for (i = 0; i < nodes.length; i++) { - if (!nodes[i].fixed) nodes[i].delete(); - } - } - static updatec() { - if (_status.noupdatec) return; - var length = 0, minoffset = -Infinity; - var controls = []; - var widths = []; - var leftwidths = []; - var add = function (node, first) { - var thiswidth = parseInt(node.style.width); - if (thiswidth) { - thiswidth += 8; - length += thiswidth; - if (first) { - leftwidths.push(thiswidth); - } - else { - widths.push(thiswidth); - } - } - else { - length += node.offsetWidth; - if (first) { - leftwidths.push(node.offsetWidth); - } - else { - widths.push(node.offsetWidth); - } - } - if (first) { - controls.unshift(node); - } - else { - controls.push(node); - } - }; - widths = leftwidths.concat(widths); - var staylefts = []; - for (var i = 0; i < ui.control.childNodes.length; i++) { - if (ui.control.childNodes[i].classList.contains('removing')) continue; - if (lib.config.wuxie_right && ui.control.childNodes[i].stayleft) { - staylefts.push(ui.control.childNodes[i]); - } - else { - add(ui.control.childNodes[i]); - } - } - if (staylefts.length) { - var fullwidth = 0; - var fullright = (game.layout == 'long' || game.layout == 'long2' || game.chess || (game.layout != 'nova' && parseInt(ui.arena.dataset.number) <= 5)); - for (var i = 0; i < widths.length; i++) { - fullwidth += widths[i] + 6; - if (get.is.phoneLayout()) fullwidth += 6; - } - fullwidth /= 2; - var currentLeft = 0; - for (var stayleft of staylefts) { - stayleft.currentLeft = currentLeft; - fullwidth += stayleft.offsetWidth; - currentLeft += stayleft.offsetWidth; - if (get.is.phoneLayout()) { - fullwidth += 18; - currentLeft += 18; - } - else { - fullwidth += 12; - currentLeft += 12; - } - } - if (fullright) { - fullwidth += 124; - if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { - fullwidth += game.me.getLeft(); - } - } - else { - fullwidth += 154; - } - for (var stayleft of staylefts) { - if (game.layout != 'default') { - var current_offset = stayleft._offset; - if (fullright) { - stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 135; - if ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.dataset.number == '8' && get.mode() != 'boss') { - stayleft._offset += game.me.getLeft(); - } - } - else { - stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 165; - } - stayleft._offset += stayleft.currentLeft; - - if (current_offset != stayleft._offset) { - stayleft.addTempClass('controlpressdownx', 500); - stayleft.style.transform = 'translateX(' + stayleft._offset + 'px)'; - } - } - else { - add(stayleft, true); - } - } - if (staylefts.length && controls.length) { - var last = staylefts[staylefts.length - 1]; - minoffset = last._offset + last.offsetWidth + (get.is.phoneLayout() ? 18 : 12); - } - } - if (!controls.length) return; - var offset = -length / 2; - if (minoffset > offset) offset = minoffset; - var control = controls.shift(); - if (control._offset != offset) { - control.addTempClass('controlpressdownx', 500); - control.style.transform = 'translateX(' + offset + 'px)'; - control._offset = offset; - } - while (controls.length) { - var control = controls.shift(); - var width = widths.shift(); - offset += width + 6; - if (get.is.phoneLayout()) { - offset += 6; - } - if (control._offset != offset) { - control.addTempClass('controlpressdownx', 500); - control.style.transform = 'translateX(' + offset + 'px)'; - control._offset = offset; - } - } - } - static updatex() { - ui.update.apply(this, arguments); - ui.updatehl(); - for (var i = 0; i < lib.onresize.length; i++) { - lib.onresize[i](); - } - var cfg = game.documentZoom / game.deviceZoom; - ui.updated(); - game.documentZoom = cfg * game.deviceZoom; - ui.updatez(); - delete ui._updatexr; - } - static updatexr() { - if (ui._updatexr) { - clearTimeout(ui._updatexr); - } - ui._updatexr = setTimeout(ui.updatex, 500); - } - static updatejm(player, nodes, start, inv) { - if (typeof start != 'number') { - start = 0; - } - var str; - if (get.is.mobileMe(player) || game.layout == 'default' || player.classList.contains('linked')) { - str = 'translateX('; - if (inv) { - str += '-'; - } - } - else { - str = 'translateY('; - } - var num = 0; - for (var i = 0; i < nodes.childElementCount; i++) { - var node = nodes.childNodes[i]; - if (i < start) { - node.style.transform = ''; - } - else if (node.classList.contains('removing')) { - start++; - } - else { - ui.refresh(node); - node.classList.remove('drawinghidden'); - node._transform = str + ((i - start) * 28) + 'px)'; - node.style.transform = node._transform; - } - } - } - static updatem(player) { - if (player) { - var start = 0; - if (!player.classList.contains('linked2') || !ui.arena.classList.contains('nolink')) { - start = 1; - } - ui.updatejm(player, player.node.marks, start, get.is.mobileMe(player)); - } - else { - for (var i = 0; i < game.players.length; i++) { - ui.updatem(game.players[i]); - } - } - } - static updatej(player) { - if (player) { - ui.updatejm(player, player.node.judges); - } - else { - for (var i = 0; i < game.players.length; i++) { - ui.updatej(game.players[i]); - } - } - } - static updatehl() { - if (!game.me) return; - if (!ui.handcards1Container || !ui.handcards2Container) return; - if (!ui.handcards1Container.childNodes.length) return; - var hs1 = [], hs2 = []; - for (var i = 0; i < ui.handcards1Container.firstChild.childElementCount; i++) { - if (!ui.handcards1Container.firstChild.childNodes[i].classList.contains('removing')) { - hs1.push(ui.handcards1Container.firstChild.childNodes[i]); - } - } - for (var i = 0; i < ui.handcards2Container.firstChild.childElementCount; i++) { - if (!ui.handcards2Container.firstChild.childNodes[i].classList.contains('removing')) { - hs2.push(ui.handcards2Container.firstChild.childNodes[i]); - } - } - var offset1, offset12 = 0; - if (!lib.config.fold_card) { - offset1 = 112; - ui.handcards1Container.classList.add('scrollh'); - } - else { - offset1 = Math.min(112, (ui.handcards1Container.offsetWidth - 128) / (hs1.length - 1)); - if (hs1.length > 1 && offset1 < 32) { - offset1 = 32; - ui.handcards1Container.classList.add('scrollh'); - } - else { - ui.handcards1Container.classList.remove('scrollh'); - } - } - if (offset1 < 100) { - offset12 = 100 - offset1; - } - for (var i = 0; i < hs1.length; i++) { - hs1[i].style.transform = 'translateX(' + (i * offset1) + 'px)'; - hs1[i]._transform = 'translateX(' + (i * offset1) + 'px)'; - ui.refresh(hs1[i]); - hs1[i].classList.remove('drawinghidden'); - if (offset12 > 40) { - offset12 = 90 - hs1[i].node.info.offsetWidth; - hs1[i].node.info.querySelector('span').style.display = 'none'; - if (hs1[i].node.name.classList.contains('long')) { - hs1[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; - hs1[i].node.name.style.transformOrigin = 'top left'; - } - else { - hs1[i].node.name.style.transform = 'translateY(16px)'; - } - hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px) translateY(-3px)'; - } - else { - hs1[i].node.info.querySelector('span').style.display = ''; - hs1[i].node.name.style.transform = ''; - hs1[i].node.name.style.transformOrigin = ''; - hs1[i].node.info.style.transform = 'translateX(-' + offset12 + 'px)'; - } - } - ui.handcards1Container.firstChild.style.width = (offset1 * (hs1.length - 1) + 118) + 'px'; - - var offset2, offset22 = 0; - if (!lib.config.fold_card) { - offset2 = 112; - ui.handcards2Container.classList.add('scrollh'); - } - else { - offset2 = Math.min(112, (ui.handcards2Container.offsetWidth - 128) / (hs2.length - 1)); - if (hs2.length > 1 && offset2 < 32) { - offset2 = 32; - ui.handcards2Container.classList.add('scrollh'); - } - else { - ui.handcards2Container.classList.remove('scrollh'); - } - } - if (offset2 < 100) { - offset22 = 100 - offset2; - } - for (var i = 0; i < hs2.length; i++) { - hs2[i].style.transform = 'translateX(' + (i * offset2) + 'px)'; - hs2[i]._transform = 'translateX(' + (i * offset2) + 'px)'; - ui.refresh(hs2[i]); - hs2[i].classList.remove('drawinghidden'); - if (offset22 > 40) { - offset22 = 90 - hs2[i].node.info.offsetWidth; - hs2[i].node.info.querySelector('span').style.display = 'none'; - if (hs2[i].node.name.classList.contains('long')) { - hs2[i].node.name.style.transform = 'translateY(16px) scale(0.85)'; - hs2[i].node.name.style.transformOrigin = 'top left'; - } - else { - hs2[i].node.name.style.transform = 'translateY(16px)'; - } - hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px) translateY(-3px)'; - } - else { - hs2[i].node.info.querySelector('span').style.display = ''; - hs2[i].node.name.style.transform = ''; - hs2[i].node.name.style.transformOrigin = ''; - hs2[i].node.info.style.transform = 'translateX(-' + offset22 + 'px)'; - } - } - ui.handcards2Container.firstChild.style.width = (offset2 * (hs2.length - 1) + 118) + 'px'; - } - static updateh(compute) { - if (!game.me) return; - if (!ui.handcards1Container) return; - if (lib.config.low_performance) { - if (compute) { - ui.updatehl(); - setTimeout(ui.updatehl, 1000); - } - return; - } - if (compute) { - ui.handcards1Container._handcardsWidth = ui.handcards1Container.offsetWidth; - ui.handcards2Container._handcardsWidth = ui.handcards2Container.offsetWidth; - } - ui.updatehx(game.me.node.handcards1); - ui.updatehx(game.me.node.handcards2); - } - static updatehx(node) { - var width = node.parentNode._handcardsWidth; - var num = node.childElementCount - node.getElementsByClassName('removing').length; - node.classList.remove('fold0'); - node.classList.remove('fold1'); - node.classList.remove('fold2'); - node.classList.remove('fold3'); - if (num * 78 + 40 >= width) { - // node.dataset.fold=3; - node.classList.add('fold3'); - } - else if (num * 93 + 25 >= width) { - // node.dataset.fold=2; - node.classList.add('fold2'); - } - else if (num * 112 + 6 >= width) { - // node.dataset.fold=1; - node.classList.add('fold1'); - } - else { - // node.dataset.fold=0; - node.classList.add('fold0'); - } - } - static updated() { - if (document.documentElement.offsetWidth < 900 || document.documentElement.offsetHeight < 500) { - game.deviceZoom = Math.min( - Math.round(document.documentElement.offsetWidth / 98) / 10, - Math.round(document.documentElement.offsetHeight / 50) / 10 - ); - } - else { - game.deviceZoom = 1; - } - } - static updatez() { - var width = document.documentElement.offsetWidth; - var height = document.documentElement.offsetHeight; - var zoom = game.documentZoom; - if (zoom != 1) { - document.body.style.width = Math.round(width / zoom) + 'px'; - document.body.style.height = Math.round(height / zoom) + 'px'; - document.body.style.transform = 'scale(' + (Math.floor(zoom * 100) / 100) + ')'; - } - else { - document.body.style.width = width + 'px'; - document.body.style.height = height + 'px'; - document.body.style.transform = ''; - } - } - static update() { - for (var i = 0; i < ui.updates.length; i++) { - ui.updates[i](); - } - if (ui.dialog && !ui.dialog.classList.contains('noupdate')) { - if (game.chess) { - if (ui.dialog.content.scrollHeight < 240 && (!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton) { - ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; - ui.dialog.classList.add('slim'); - } - else { - ui.dialog.style.height = ''; - ui.dialog.classList.remove('slim'); - } - } - else { - if ((!ui.dialog.buttons || !ui.dialog.buttons.length) && !ui.dialog.forcebutton && ui.dialog.classList.contains('fullheight') == false && get.mode() != 'stone') { - ui.dialog.classList.add('nobutton'); - if (ui.dialog.content.offsetHeight < 240) { - if (!ui.dialog._heightset) { - ui.dialog._heightset = ui.dialog.style.height || true; - } - ui.dialog.style.height = ui.dialog.content.offsetHeight + 'px'; - if (lib.config.show_log != 'off') { - ui.dialog.classList.add('scroll1'); - ui.dialog.classList.add('scroll2'); - return; - } - } - else { - if (typeof ui.dialog._heightset == 'string') { - ui.dialog.style.height = ui.dialog._heightset; - } - else if (ui.dialog._heightset) { - ui.dialog.style.height = ''; - } - delete ui.dialog._heightset; - } - } - else { - if (typeof ui.dialog._heightset == 'string') { - ui.dialog.style.height = ui.dialog._heightset; - } - else if (ui.dialog._heightset) { - ui.dialog.style.height = ''; - } - delete ui.dialog._heightset; - ui.dialog.classList.remove('nobutton'); - } - } - var height1 = ui.dialog.content.offsetHeight; - var height2 = ui.dialog.contentContainer.offsetHeight; - if (game.chess) { - if (height1 < 240) { - ui.dialog.style.height = height1 + 'px'; - } - } - else { - if (!ui.dialog.forcebutton && !ui.dialog._scrollset && (height1 <= 190 || (height2 >= height1 && height2 >= 210))) { - ui.dialog.classList.remove('scroll1'); - ui.dialog.classList.remove('scroll2'); - } - else { - ui.dialog.classList.add('scroll1'); - ui.dialog.classList.add('scroll2'); - if (game.layout != 'default') { - ui.dialog.style.height = Math.min(height1, ((game.layout == 'long2' || game.layout == 'nova') && ui.arena.classList.contains('choose-character')) ? 380 : 350) + 'px'; - ui.dialog._scrollset = true; - } - } - if (game.layout == 'long2' || game.layout == 'nova') { - if (height1 + 240 >= ui.arena.offsetHeight) { - ui.dialog.classList.add('scroll3'); - } - else { - ui.dialog.classList.remove('scroll3'); - } - } - } - } - } - static recycle(node, key) { - if (!ui._recycle) ui._recycle = {}; - if (typeof node == 'string') { - return ui._recycle[node]; - } - ui._recycle[key] = node; - } - /** - * @author curpond - * @author Tipx-L - * @param {number} [numberOfPlayers] - */ - static updateConnectPlayerPositions(numberOfPlayers) { - if (typeof numberOfPlayers != 'number') { - const configOL = lib.configOL; - numberOfPlayers = parseInt(configOL.player_number) || configOL.number; - } - if (!numberOfPlayers) return; - const playerPositions = ui.playerPositions; - playerPositions.forEach((position) => { - game.dynamicStyle.remove(position); - }); - playerPositions.length = 0; - const temporaryPlayer = ui.create.div('.player.connect', ui.window).hide(); - const computedStyle = getComputedStyle(temporaryPlayer); - const halfWidth = parseFloat(computedStyle.width) / 2; - const halfHeight = parseFloat(computedStyle.height) / 2; - temporaryPlayer.remove(); - const halfNumberOfPlayers = Math.round(numberOfPlayers / 2); - const upperPercentage = 100 / (halfNumberOfPlayers + 1); - const scale = 10 / numberOfPlayers; - for (let ordinal = 0; ordinal < halfNumberOfPlayers; ordinal++) { - const selector = `#window>.player.connect[data-position='${ordinal}']`; - const css = { - left: `calc(${upperPercentage * (ordinal + 1)}% - ${halfWidth}px)`, - top: `calc(${100 / 3}% - ${halfHeight}px)` - }; - if (scale < 1) - css["transform"] = `scale(${scale})`; - - game.dynamicStyle.add(selector, css); - playerPositions.push(selector); - } - const lowerPercentage = 100 / (numberOfPlayers - halfNumberOfPlayers + 1); - for (let ordinal = halfNumberOfPlayers; ordinal < numberOfPlayers; ordinal++) { - const selector = `#window>.player.connect[data-position='${ordinal}']`; - const css = { - left: `calc(${lowerPercentage * (ordinal - halfNumberOfPlayers + 1)}% - ${halfWidth}px)`, - top: `calc(${100 * 2 / 3}% - ${halfHeight}px)` - }; - if (scale < 1) - css["transform"] = `scale(${scale})`; - - game.dynamicStyle.add(selector, css); - playerPositions.push(selector); - } - } - /** - * @author curpond - * @author Tipx-L - * @param {number} [numberOfPlayers] - */ - static updatePlayerPositions(numberOfPlayers) { - if (typeof numberOfPlayers != 'number') numberOfPlayers = ui.arena.dataset.number; - //当人数不超过8人时,还是用以前的布局 - if (!numberOfPlayers || numberOfPlayers <= 8) return; - const playerPositions = ui.playerPositions; - playerPositions.forEach((position) => { - game.dynamicStyle.remove(position); - }); - playerPositions.length = 0; - //单个人物的宽度,这里要设置玩家的实际的宽度 - const temporaryPlayer = ui.create.div('.player', ui.arena).hide(); - const computedStyle = getComputedStyle(temporaryPlayer); - const scale = 6 / numberOfPlayers; - //玩家顶部距离父容器上边缘的距离偏移的单位距离 - const quarterHeight = parseFloat(computedStyle.height) / 4 * scale; - const halfWidth = parseFloat(computedStyle.width) / 2; - temporaryPlayer.remove(); - //列数,即假如8人场,除去自己后,上面7个人占7列 - const columnCount = numberOfPlayers - 1; - const percentage = 90 / (columnCount - 1); - //仅当游戏人数大于8人,且玩家的座位号大于0时,设置玩家的位置;因为0号位是game.me在最下方,无需设置 - for (let ordinal = 1; ordinal < numberOfPlayers; ordinal++) { - const reversedOrdinal = columnCount - ordinal; - //动态计算玩家的top属性,实现拱桥的效果;只让两边的各两个人向下偏移一些 - const top = Math.max(0, Math.round(numberOfPlayers / 5) - Math.min(Math.abs(ordinal - 1), Math.abs(reversedOrdinal))) * quarterHeight; - const selector = `#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']`; - game.dynamicStyle.add(selector, { - left: `calc(${percentage * reversedOrdinal + 5}% - ${halfWidth}px)`, - top: `${top}px`, - transform: `scale(${scale})` - }); - playerPositions.push(selector); - } - } - static updateRoundNumber(roundNumber, cardPileNumber) { - if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = `${roundNumber}轮 剩余牌: ${cardPileNumber}`; - } -} - -export const ui = UI; +import { lib } from "../library/index.js"; +import { game } from "../game/index.js"; +import { get } from "../get/index.js"; +import { _status } from "../status/index.js"; +import { Click } from "./click/index.js"; +import { Create } from "./create/index.js"; + +export class UI { + updates = []; + thrown = []; + touchlines = []; + todiscard = {}; + /** + * @type { HTMLStyleElement[] } + */ + playerPositions = []; + create = new Create(); + click = new Click(); + selected = { + /** + * @type { Button[] } + */ + buttons: [], + /** + * @type { Card[] } + */ + cards: [], + /** + * @type { Player[] } + */ + targets: [], + }; + /** + * @type { Dialog[] } + */ + dialogs; + /** + * @type { Dialog } + */ + dialog; + /** + * @type { HTMLDivElement } + */ + arena; + /** + * @type { Control[] } + */ + controls; + /** + * @type { Control } + */ + control; + /** + * @type { Control | undefined } + */ + confirm; + /** + * @type { Control | undefined } + */ + skills; + /** + * @type { Control | undefined } + */ + skills1; + /** + * @type { Control | undefined } + */ + skills2; + /** + * @type { Control | undefined } + */ + skills3; + /** + * @type { HTMLDivElement } + */ + window; + /** + * @type { HTMLDivElement } + */ + pause; + /** + * @type { HTMLAudioElement } + */ + backgroundMusic; + /** + * @type { HTMLDivElement } + */ + special; + /** + * @type { HTMLDivElement } + */ + fakeme; + /** + * @type { HTMLDivElement } + */ + chess; + /** + * 手动在菜单栏中添加一个武将包的ui + * @type { ((packName: string) => void)[] } + */ + updateCharacterPackMenu = []; + /** + * 手动在菜单栏中添加一个卡牌包的ui + * @type { ((packName: string) => void)[] } + */ + updateCardPackMenu = []; + /** + * @type { HTMLDivElement } 挑战模式下正在操作的角色 + */ + mebg; + /** + * @type { Function | undefined } + */ + updateUpdate; + /** + * @type {HTMLDivElement} + */ + commandnode; + /** + * @type {() => void} + */ + updateVideoMenu; + /** + * @type {HTMLDivElement} + */ + menuContainer; + /** + * @type {HTMLDivElement} + */ + auto; + /** + * @type {HTMLDivElement} + */ + wuxie; + /** + * @type {HTMLDivElement} + */ + tempnowuxie; + refresh(node) { + void window.getComputedStyle(node, null).getPropertyValue("opacity"); + } + clear() { + game.addVideo("uiClear"); + var thrown = document.getElementsByClassName("thrown"); + var nodes = []; + var i; + for (i = 0; i < thrown.length; i++) { + nodes.push(thrown[i]); + } + for (i = 0; i < nodes.length; i++) { + if (!nodes[i].fixed) nodes[i].delete(); + } + } + updatec() { + if (_status.noupdatec) return; + var length = 0, + minoffset = -Infinity; + var controls = []; + var widths = []; + var leftwidths = []; + var add = function (node, first) { + var thiswidth = parseInt(node.style.width); + if (thiswidth) { + thiswidth += 8; + length += thiswidth; + if (first) { + leftwidths.push(thiswidth); + } else { + widths.push(thiswidth); + } + } else { + length += node.offsetWidth; + if (first) { + leftwidths.push(node.offsetWidth); + } else { + widths.push(node.offsetWidth); + } + } + if (first) { + controls.unshift(node); + } else { + controls.push(node); + } + }; + widths = leftwidths.concat(widths); + var staylefts = []; + for (var i = 0; i < ui.control.childNodes.length; i++) { + if (ui.control.childNodes[i].classList.contains("removing")) continue; + if (lib.config.wuxie_right && ui.control.childNodes[i].stayleft) { + staylefts.push(ui.control.childNodes[i]); + } else { + add(ui.control.childNodes[i]); + } + } + if (staylefts.length) { + var fullwidth = 0; + var fullright = + game.layout == "long" || + game.layout == "long2" || + game.chess || + (game.layout != "nova" && parseInt(ui.arena.dataset.number) <= 5); + for (var i = 0; i < widths.length; i++) { + fullwidth += widths[i] + 6; + if (get.is.phoneLayout()) fullwidth += 6; + } + fullwidth /= 2; + var currentLeft = 0; + for (var stayleft of staylefts) { + stayleft.currentLeft = currentLeft; + fullwidth += stayleft.offsetWidth; + currentLeft += stayleft.offsetWidth; + if (get.is.phoneLayout()) { + fullwidth += 18; + currentLeft += 18; + } else { + fullwidth += 12; + currentLeft += 12; + } + } + if (fullright) { + fullwidth += 124; + if ( + (game.layout == "long2" || game.layout == "nova") && + ui.arena.dataset.number == "8" && + get.mode() != "boss" + ) { + fullwidth += game.me.getLeft(); + } + } else { + fullwidth += 154; + } + for (var stayleft of staylefts) { + if (game.layout != "default") { + var current_offset = stayleft._offset; + if (fullright) { + stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 135; + if ( + (game.layout == "long2" || game.layout == "nova") && + ui.arena.dataset.number == "8" && + get.mode() != "boss" + ) { + stayleft._offset += game.me.getLeft(); + } + } else { + stayleft._offset = Math.ceil(-ui.arena.offsetWidth / 2) + 165; + } + stayleft._offset += stayleft.currentLeft; + + if (current_offset != stayleft._offset) { + stayleft.addTempClass("controlpressdownx", 500); + stayleft.style.transform = "translateX(" + stayleft._offset + "px)"; + } + } else { + add(stayleft, true); + } + } + if (staylefts.length && controls.length) { + var last = staylefts[staylefts.length - 1]; + minoffset = last._offset + last.offsetWidth + (get.is.phoneLayout() ? 18 : 12); + } + } + if (!controls.length) return; + var offset = -length / 2; + if (minoffset > offset) offset = minoffset; + var control = controls.shift(); + if (control._offset != offset) { + control.addTempClass("controlpressdownx", 500); + control.style.transform = "translateX(" + offset + "px)"; + control._offset = offset; + } + while (controls.length) { + var control = controls.shift(); + var width = widths.shift(); + offset += width + 6; + if (get.is.phoneLayout()) { + offset += 6; + } + if (control._offset != offset) { + control.addTempClass("controlpressdownx", 500); + control.style.transform = "translateX(" + offset + "px)"; + control._offset = offset; + } + } + } + updatex() { + ui.update.apply(this, arguments); + ui.updatehl(); + for (var i = 0; i < lib.onresize.length; i++) { + lib.onresize[i](); + } + var cfg = game.documentZoom / game.deviceZoom; + ui.updated(); + game.documentZoom = cfg * game.deviceZoom; + ui.updatez(); + delete ui._updatexr; + } + updatexr() { + if (ui._updatexr) { + clearTimeout(ui._updatexr); + } + ui._updatexr = setTimeout(ui.updatex, 500); + } + updatejm(player, nodes, start, inv) { + if (typeof start != "number") { + start = 0; + } + var str; + if (get.is.mobileMe(player) || game.layout == "default" || player.classList.contains("linked")) { + str = "translateX("; + if (inv) { + str += "-"; + } + } else { + str = "translateY("; + } + var num = 0; + for (var i = 0; i < nodes.childElementCount; i++) { + var node = nodes.childNodes[i]; + if (i < start) { + node.style.transform = ""; + } else if (node.classList.contains("removing")) { + start++; + } else { + ui.refresh(node); + node.classList.remove("drawinghidden"); + node._transform = str + (i - start) * 28 + "px)"; + node.style.transform = node._transform; + } + } + } + updatem(player) { + if (player) { + var start = 0; + if (!player.classList.contains("linked2") || !ui.arena.classList.contains("nolink")) { + start = 1; + } + ui.updatejm(player, player.node.marks, start, get.is.mobileMe(player)); + } else { + for (var i = 0; i < game.players.length; i++) { + ui.updatem(game.players[i]); + } + } + } + updatej(player) { + if (player) { + ui.updatejm(player, player.node.judges); + } else { + for (var i = 0; i < game.players.length; i++) { + ui.updatej(game.players[i]); + } + } + } + updatehl() { + if (!game.me) return; + if (!ui.handcards1Container || !ui.handcards2Container) return; + if (!ui.handcards1Container.childNodes.length) return; + var hs1 = [], + hs2 = []; + for (var i = 0; i < ui.handcards1Container.firstChild.childElementCount; i++) { + if (!ui.handcards1Container.firstChild.childNodes[i].classList.contains("removing")) { + hs1.push(ui.handcards1Container.firstChild.childNodes[i]); + } + } + for (var i = 0; i < ui.handcards2Container.firstChild.childElementCount; i++) { + if (!ui.handcards2Container.firstChild.childNodes[i].classList.contains("removing")) { + hs2.push(ui.handcards2Container.firstChild.childNodes[i]); + } + } + var offset1, + offset12 = 0; + if (!lib.config.fold_card) { + offset1 = 112; + ui.handcards1Container.classList.add("scrollh"); + } else { + offset1 = Math.min(112, (ui.handcards1Container.offsetWidth - 128) / (hs1.length - 1)); + if (hs1.length > 1 && offset1 < 32) { + offset1 = 32; + ui.handcards1Container.classList.add("scrollh"); + } else { + ui.handcards1Container.classList.remove("scrollh"); + } + } + if (offset1 < 100) { + offset12 = 100 - offset1; + } + for (var i = 0; i < hs1.length; i++) { + hs1[i].style.transform = "translateX(" + i * offset1 + "px)"; + hs1[i]._transform = "translateX(" + i * offset1 + "px)"; + ui.refresh(hs1[i]); + hs1[i].classList.remove("drawinghidden"); + if (offset12 > 40) { + offset12 = 90 - hs1[i].node.info.offsetWidth; + hs1[i].node.info.querySelector("span").style.display = "none"; + if (hs1[i].node.name.classList.contains("long")) { + hs1[i].node.name.style.transform = "translateY(16px) scale(0.85)"; + hs1[i].node.name.style.transformOrigin = "top left"; + } else { + hs1[i].node.name.style.transform = "translateY(16px)"; + } + hs1[i].node.info.style.transform = "translateX(-" + offset12 + "px) translateY(-3px)"; + } else { + hs1[i].node.info.querySelector("span").style.display = ""; + hs1[i].node.name.style.transform = ""; + hs1[i].node.name.style.transformOrigin = ""; + hs1[i].node.info.style.transform = "translateX(-" + offset12 + "px)"; + } + } + ui.handcards1Container.firstChild.style.width = offset1 * (hs1.length - 1) + 118 + "px"; + + var offset2, + offset22 = 0; + if (!lib.config.fold_card) { + offset2 = 112; + ui.handcards2Container.classList.add("scrollh"); + } else { + offset2 = Math.min(112, (ui.handcards2Container.offsetWidth - 128) / (hs2.length - 1)); + if (hs2.length > 1 && offset2 < 32) { + offset2 = 32; + ui.handcards2Container.classList.add("scrollh"); + } else { + ui.handcards2Container.classList.remove("scrollh"); + } + } + if (offset2 < 100) { + offset22 = 100 - offset2; + } + for (var i = 0; i < hs2.length; i++) { + hs2[i].style.transform = "translateX(" + i * offset2 + "px)"; + hs2[i]._transform = "translateX(" + i * offset2 + "px)"; + ui.refresh(hs2[i]); + hs2[i].classList.remove("drawinghidden"); + if (offset22 > 40) { + offset22 = 90 - hs2[i].node.info.offsetWidth; + hs2[i].node.info.querySelector("span").style.display = "none"; + if (hs2[i].node.name.classList.contains("long")) { + hs2[i].node.name.style.transform = "translateY(16px) scale(0.85)"; + hs2[i].node.name.style.transformOrigin = "top left"; + } else { + hs2[i].node.name.style.transform = "translateY(16px)"; + } + hs2[i].node.info.style.transform = "translateX(-" + offset22 + "px) translateY(-3px)"; + } else { + hs2[i].node.info.querySelector("span").style.display = ""; + hs2[i].node.name.style.transform = ""; + hs2[i].node.name.style.transformOrigin = ""; + hs2[i].node.info.style.transform = "translateX(-" + offset22 + "px)"; + } + } + ui.handcards2Container.firstChild.style.width = offset2 * (hs2.length - 1) + 118 + "px"; + } + updateh(compute) { + if (!game.me) return; + if (!ui.handcards1Container) return; + if (lib.config.low_performance) { + if (compute) { + ui.updatehl(); + setTimeout(ui.updatehl, 1000); + } + return; + } + if (compute) { + ui.handcards1Container._handcardsWidth = ui.handcards1Container.offsetWidth; + ui.handcards2Container._handcardsWidth = ui.handcards2Container.offsetWidth; + } + ui.updatehx(game.me.node.handcards1); + ui.updatehx(game.me.node.handcards2); + } + updatehx(node) { + var width = node.parentNode._handcardsWidth; + var num = node.childElementCount - node.getElementsByClassName("removing").length; + node.classList.remove("fold0"); + node.classList.remove("fold1"); + node.classList.remove("fold2"); + node.classList.remove("fold3"); + if (num * 78 + 40 >= width) { + // node.dataset.fold=3; + node.classList.add("fold3"); + } else if (num * 93 + 25 >= width) { + // node.dataset.fold=2; + node.classList.add("fold2"); + } else if (num * 112 + 6 >= width) { + // node.dataset.fold=1; + node.classList.add("fold1"); + } else { + // node.dataset.fold=0; + node.classList.add("fold0"); + } + } + updated() { + if (document.documentElement.offsetWidth < 900 || document.documentElement.offsetHeight < 500) { + game.deviceZoom = Math.min( + Math.round(document.documentElement.offsetWidth / 98) / 10, + Math.round(document.documentElement.offsetHeight / 50) / 10 + ); + } else { + game.deviceZoom = 1; + } + } + updatez() { + var width = document.documentElement.offsetWidth; + var height = document.documentElement.offsetHeight; + var zoom = game.documentZoom; + if (zoom != 1) { + document.body.style.width = Math.round(width / zoom) + "px"; + document.body.style.height = Math.round(height / zoom) + "px"; + document.body.style.transform = "scale(" + Math.floor(zoom * 100) / 100 + ")"; + } else { + document.body.style.width = width + "px"; + document.body.style.height = height + "px"; + document.body.style.transform = ""; + } + } + update() { + for (var i = 0; i < ui.updates.length; i++) { + ui.updates[i](); + } + if (ui.dialog && !ui.dialog.classList.contains("noupdate")) { + if (game.chess) { + if ( + ui.dialog.content.scrollHeight < 240 && + (!ui.dialog.buttons || !ui.dialog.buttons.length) && + !ui.dialog.forcebutton + ) { + ui.dialog.style.height = ui.dialog.content.offsetHeight + "px"; + ui.dialog.classList.add("slim"); + } else { + ui.dialog.style.height = ""; + ui.dialog.classList.remove("slim"); + } + } else { + if ( + (!ui.dialog.buttons || !ui.dialog.buttons.length) && + !ui.dialog.forcebutton && + ui.dialog.classList.contains("fullheight") == false && + get.mode() != "stone" + ) { + ui.dialog.classList.add("nobutton"); + if (ui.dialog.content.offsetHeight < 240) { + if (!ui.dialog._heightset) { + ui.dialog._heightset = ui.dialog.style.height || true; + } + ui.dialog.style.height = ui.dialog.content.offsetHeight + "px"; + if (lib.config.show_log != "off") { + ui.dialog.classList.add("scroll1"); + ui.dialog.classList.add("scroll2"); + return; + } + } else { + if (typeof ui.dialog._heightset == "string") { + ui.dialog.style.height = ui.dialog._heightset; + } else if (ui.dialog._heightset) { + ui.dialog.style.height = ""; + } + delete ui.dialog._heightset; + } + } else { + if (typeof ui.dialog._heightset == "string") { + ui.dialog.style.height = ui.dialog._heightset; + } else if (ui.dialog._heightset) { + ui.dialog.style.height = ""; + } + delete ui.dialog._heightset; + ui.dialog.classList.remove("nobutton"); + } + } + var height1 = ui.dialog.content.offsetHeight; + var height2 = ui.dialog.contentContainer.offsetHeight; + if (game.chess) { + if (height1 < 240) { + ui.dialog.style.height = height1 + "px"; + } + } else { + if ( + !ui.dialog.forcebutton && + !ui.dialog._scrollset && + (height1 <= 190 || (height2 >= height1 && height2 >= 210)) + ) { + ui.dialog.classList.remove("scroll1"); + ui.dialog.classList.remove("scroll2"); + } else { + ui.dialog.classList.add("scroll1"); + ui.dialog.classList.add("scroll2"); + if (game.layout != "default") { + ui.dialog.style.height = + Math.min( + height1, + (game.layout == "long2" || game.layout == "nova") && + ui.arena.classList.contains("choose-character") + ? 380 + : 350 + ) + "px"; + ui.dialog._scrollset = true; + } + } + if (game.layout == "long2" || game.layout == "nova") { + if (height1 + 240 >= ui.arena.offsetHeight) { + ui.dialog.classList.add("scroll3"); + } else { + ui.dialog.classList.remove("scroll3"); + } + } + } + } + } + recycle(node, key) { + if (!ui._recycle) ui._recycle = {}; + if (typeof node == "string") { + return ui._recycle[node]; + } + ui._recycle[key] = node; + } + /** + * @author curpond + * @author Tipx-L + * @param {number} [numberOfPlayers] + */ + updateConnectPlayerPositions(numberOfPlayers) { + if (typeof numberOfPlayers != "number") { + const configOL = lib.configOL; + numberOfPlayers = parseInt(configOL.player_number) || configOL.number; + } + if (!numberOfPlayers) return; + const playerPositions = ui.playerPositions; + playerPositions.forEach((position) => { + game.dynamicStyle.remove(position); + }); + playerPositions.length = 0; + const temporaryPlayer = ui.create.div(".player.connect", ui.window).hide(); + const computedStyle = getComputedStyle(temporaryPlayer); + const halfWidth = parseFloat(computedStyle.width) / 2; + const halfHeight = parseFloat(computedStyle.height) / 2; + temporaryPlayer.remove(); + const halfNumberOfPlayers = Math.round(numberOfPlayers / 2); + const upperPercentage = 100 / (halfNumberOfPlayers + 1); + const scale = 10 / numberOfPlayers; + for (let ordinal = 0; ordinal < halfNumberOfPlayers; ordinal++) { + const selector = `#window>.player.connect[data-position='${ordinal}']`; + const css = { + left: `calc(${upperPercentage * (ordinal + 1)}% - ${halfWidth}px)`, + top: `calc(${100 / 3}% - ${halfHeight}px)`, + }; + if (scale < 1) css["transform"] = `scale(${scale})`; + + game.dynamicStyle.add(selector, css); + playerPositions.push(selector); + } + const lowerPercentage = 100 / (numberOfPlayers - halfNumberOfPlayers + 1); + for (let ordinal = halfNumberOfPlayers; ordinal < numberOfPlayers; ordinal++) { + const selector = `#window>.player.connect[data-position='${ordinal}']`; + const css = { + left: `calc(${lowerPercentage * (ordinal - halfNumberOfPlayers + 1)}% - ${halfWidth}px)`, + top: `calc(${(100 * 2) / 3}% - ${halfHeight}px)`, + }; + if (scale < 1) css["transform"] = `scale(${scale})`; + + game.dynamicStyle.add(selector, css); + playerPositions.push(selector); + } + } + /** + * @author curpond + * @author Tipx-L + * @param {number} [numberOfPlayers] + */ + updatePlayerPositions(numberOfPlayers) { + if (typeof numberOfPlayers != "number") numberOfPlayers = ui.arena.dataset.number; + //当人数不超过8人时,还是用以前的布局 + if (!numberOfPlayers || numberOfPlayers <= 8) return; + const playerPositions = ui.playerPositions; + playerPositions.forEach((position) => { + game.dynamicStyle.remove(position); + }); + playerPositions.length = 0; + //单个人物的宽度,这里要设置玩家的实际的宽度 + const temporaryPlayer = ui.create.div(".player", ui.arena).hide(); + const computedStyle = getComputedStyle(temporaryPlayer); + const scale = 6 / numberOfPlayers; + //玩家顶部距离父容器上边缘的距离偏移的单位距离 + const quarterHeight = (parseFloat(computedStyle.height) / 4) * scale; + const halfWidth = parseFloat(computedStyle.width) / 2; + temporaryPlayer.remove(); + //列数,即假如8人场,除去自己后,上面7个人占7列 + const columnCount = numberOfPlayers - 1; + const percentage = 90 / (columnCount - 1); + //仅当游戏人数大于8人,且玩家的座位号大于0时,设置玩家的位置;因为0号位是game.me在最下方,无需设置 + for (let ordinal = 1; ordinal < numberOfPlayers; ordinal++) { + const reversedOrdinal = columnCount - ordinal; + //动态计算玩家的top属性,实现拱桥的效果;只让两边的各两个人向下偏移一些 + const top = + Math.max( + 0, + Math.round(numberOfPlayers / 5) - + Math.min(Math.abs(ordinal - 1), Math.abs(reversedOrdinal)) + ) * quarterHeight; + const selector = `#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']`; + game.dynamicStyle.add(selector, { + left: `calc(${percentage * reversedOrdinal + 5}% - ${halfWidth}px)`, + top: `${top}px`, + transform: `scale(${scale})`, + }); + playerPositions.push(selector); + } + } + updateRoundNumber(roundNumber, cardPileNumber) { + if (ui.cardPileNumber) ui.cardPileNumber.innerHTML = `${roundNumber}轮 剩余牌: ${cardPileNumber}`; + } +} + +export let ui = new UI(); + +/** + * @param { InstanceType } [instance] + */ +export let setUI = (instance) => { + ui = instance || new UI(); + if (lib.config.dev) { + window.ui = ui; + } +}; diff --git a/noname/util/browser.js b/noname/util/browser.js index 7e84aa899..8f4c37483 100644 --- a/noname/util/browser.js +++ b/noname/util/browser.js @@ -1,19 +1,19 @@ -import { PromiseErrorHandler } from './struct/index.js'; - -/** - * 从浏览器名到不同浏览器下异步处理方式的映射 - * - * `key`的值同`get.coreInfo`函数返回值的第一个元素 - * - * @type {Record<"firefox" | "chrome" | "safari" | "other", new () => PromiseErrorHandler>} - */ -export const promiseErrorHandlerMap = { - 'chrome': PromiseErrorHandler.ChromePromiseErrorHandler, - 'firefox': PromiseErrorHandler.FirefoxPromiseErrorHandler, - 'safari': PromiseErrorHandler.UnknownPromiseErrorHandler, - 'other': PromiseErrorHandler.UnknownPromiseErrorHandler -}; - -/** - * @typedef {import('./struct/interface/promise-error-handler.js').PromiseErrorHandler} PromiseErrorHandler - */ +import { PromiseErrorHandler } from "./struct/index.js"; + +/** + * 从浏览器名到不同浏览器下异步处理方式的映射 + * + * `key`的值同`get.coreInfo`函数返回值的第一个元素 + * + * @type {Record<"firefox" | "chrome" | "safari" | "other", new () => PromiseErrorHandler>} + */ +export const promiseErrorHandlerMap = { + chrome: PromiseErrorHandler.ChromePromiseErrorHandler, + firefox: PromiseErrorHandler.FirefoxPromiseErrorHandler, + safari: PromiseErrorHandler.UnknownPromiseErrorHandler, + other: PromiseErrorHandler.UnknownPromiseErrorHandler, +}; + +/** + * @typedef {import('./struct/interface/promise-error-handler.js').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/config.js b/noname/util/config.js index 84e2ba7c1..00d3a9d40 100644 --- a/noname/util/config.js +++ b/noname/util/config.js @@ -1,11 +1,11 @@ -import { Library as lib } from "../library/index.js"; +import { lib } from "../library/index.js"; /** - * @param {string} name + * @param {string} name * @returns {any} */ export function get(name) { - const config = Reflect.get(lib, 'config'); + const config = Reflect.get(lib, "config"); if (!config) return null; return Reflect.get(config, name); } @@ -16,17 +16,17 @@ export function get(name) { * @returns {void} */ export function set(name, value) { - const config = Reflect.get(lib, 'config'); + const config = Reflect.get(lib, "config"); if (!config) return; - Reflect.set(config, name, value) + Reflect.set(config, name, value); } /** - * @param {string} name + * @param {string} name * @returns {boolean} */ export function has(name) { - const config = Reflect.get(lib, 'config'); + const config = Reflect.get(lib, "config"); if (!config) return false; return Reflect.has(config, name); } diff --git a/noname/util/index.js b/noname/util/index.js index 7bca77016..8cc922af0 100644 --- a/noname/util/index.js +++ b/noname/util/index.js @@ -1,11 +1,16 @@ /** @type { string } */ // @ts-ignore -export const nonameInitialized = localStorage.getItem('noname_inited'); -export const assetURL = location.protocol.startsWith('http') || typeof nonameInitialized != 'string' || nonameInitialized == 'nodejs' ? '' : nonameInitialized; -export const GeneratorFunction = (function* () {}).constructor; -export const AsyncFunction = (async function () {}).constructor; +export const nonameInitialized = localStorage.getItem("noname_inited"); +export const assetURL = + location.protocol.startsWith("http") || + typeof nonameInitialized != "string" || + nonameInitialized == "nodejs" + ? "" + : nonameInitialized; +export const GeneratorFunction = function* () {}.constructor; +export const AsyncFunction = async function () {}.constructor; export const userAgent = navigator.userAgent.toLowerCase(); -export { Mutex } from './mutex.js'; +export { Mutex } from "./mutex.js"; export const characterDefaultPicturePath = "image/character/default_silhouette_"; /** @@ -19,7 +24,7 @@ export class Uninstantable { /** * 暂停x毫秒 - * @param { number } ms + * @param { number } ms * @returns { Promise } */ export function delay(ms) { @@ -28,20 +33,20 @@ export function delay(ms) { /** * 将当前Record已有的普通项封装起来,但不阻止其继续扩展 - * + * * @template {object} T * @param {T} record - 要封装的Record * @returns {Readonly} */ export function freezeButExtensible(record) { - const descriptors = Object.getOwnPropertyDescriptors(record) + const descriptors = Object.getOwnPropertyDescriptors(record); if (descriptors) { for (const [key, descriptor] of Object.entries(descriptors)) { - if ("value" in descriptor) descriptor.writable = false - descriptor.configurable = false - Reflect.defineProperty(record, key, descriptor) + if ("value" in descriptor) descriptor.writable = false; + descriptor.configurable = false; + Reflect.defineProperty(record, key, descriptor); } } - return record + return record; } diff --git a/noname/util/mutex.js b/noname/util/mutex.js index cce998fc7..bc7ee88c6 100644 --- a/noname/util/mutex.js +++ b/noname/util/mutex.js @@ -1,75 +1,75 @@ -/** - * 一个非常普通的“锁” - */ -export class Mutex { - /** - * 锁目前的状态,只有“unlocked”和“locked”两种情况 - * - * @type {'locked' | 'unlocked'} - */ - #status; - - /** - * 上锁后用于等待的锁Promise - * - * @type {null | Promise} - */ - #promise; - - /** - * 上锁后用于触发锁Promise的resolve函数 - * - * @type {null | function(): void} - */ - #resolve; - - constructor() { - this.#status = 'unlocked'; - this.#promise = null; - this.#resolve = null; - } - - /** - * 上锁 - * - * 请时刻记住使用`await Mutex#lock()`来使锁正常工作 - */ - async lock() { - switch (this.#status) { - case 'locked': - await this.#promise; - - case 'unlocked': - this.#status = 'locked'; - // @ts-ignore - ({ promise: this.#promise, resolve: this.#resolve } = Promise.withResolvers()) - break; - } - } - - /** - * 解锁 - * - * 请不要在未上锁的情况下解锁 - */ - unlock() { - if (this.#status === 'unlocked') throw new Error('This Mutex is not locked.'); - - this.#status = 'unlocked'; - if (this.#resolve) this.#resolve(); - } - - /** - * 启用锁的try-finally封装,用于在函数执行完后自动解放锁的控制权(就算发生错误) - * - * @param {function(): void | Promise} content - */ - async scoped(content) { - try { - await this.lock(); - await content(); - } finally { - this.unlock(); - } - } -} +/** + * 一个非常普通的“锁” + */ +export class Mutex { + /** + * 锁目前的状态,只有“unlocked”和“locked”两种情况 + * + * @type {'locked' | 'unlocked'} + */ + #status; + + /** + * 上锁后用于等待的锁Promise + * + * @type {null | Promise} + */ + #promise; + + /** + * 上锁后用于触发锁Promise的resolve函数 + * + * @type {null | function(): void} + */ + #resolve; + + constructor() { + this.#status = "unlocked"; + this.#promise = null; + this.#resolve = null; + } + + /** + * 上锁 + * + * 请时刻记住使用`await Mutex#lock()`来使锁正常工作 + */ + async lock() { + switch (this.#status) { + case "locked": + await this.#promise; + + case "unlocked": + this.#status = "locked"; + // @ts-ignore + ({ promise: this.#promise, resolve: this.#resolve } = Promise.withResolvers()); + break; + } + } + + /** + * 解锁 + * + * 请不要在未上锁的情况下解锁 + */ + unlock() { + if (this.#status === "unlocked") throw new Error("This Mutex is not locked."); + + this.#status = "unlocked"; + if (this.#resolve) this.#resolve(); + } + + /** + * 启用锁的try-finally封装,用于在函数执行完后自动解放锁的控制权(就算发生错误) + * + * @param {function(): void | Promise} content + */ + async scoped(content) { + try { + await this.lock(); + await content(); + } finally { + this.unlock(); + } + } +} diff --git a/noname/util/struct/index.js b/noname/util/struct/index.js index 3515a4fad..43cf1dda9 100644 --- a/noname/util/struct/index.js +++ b/noname/util/struct/index.js @@ -1,5 +1,5 @@ -/** - * 无名杀内部所需要的数据结构 - */ - -export * as PromiseErrorHandler from './promise-error-handler/index.js'; +/** + * 无名杀内部所需要的数据结构 + */ + +export * as PromiseErrorHandler from "./promise-error-handler/index.js"; diff --git a/noname/util/struct/interface/index.d.ts b/noname/util/struct/interface/index.d.ts index eaed359b5..66fe943d3 100644 --- a/noname/util/struct/interface/index.d.ts +++ b/noname/util/struct/interface/index.d.ts @@ -1,5 +1,5 @@ -/** - * 无名杀内部构建所需要用到的接口 - */ - -export { PromiseErrorHandler } from './promise-error-handler' +/** + * 无名杀内部构建所需要用到的接口 + */ + +export { PromiseErrorHandler } from "./promise-error-handler"; diff --git a/noname/util/struct/interface/promise-error-handler.d.ts b/noname/util/struct/interface/promise-error-handler.d.ts index 6c35dcf55..932894b16 100644 --- a/noname/util/struct/interface/promise-error-handler.d.ts +++ b/noname/util/struct/interface/promise-error-handler.d.ts @@ -1,53 +1,53 @@ -/** - * 不同浏览器下异步报错问题处理方式的接口,用于定义不同浏览器对待异步报错的处理方式 - */ -export interface PromiseErrorHandler { - /** - * 当异步处理对象初始化时执行的操作 - * - * 因为未来或许会涉及到错误处理方式的更改,故所有初始化操作请于此处执行 - * - * 若该函数为异步函数,则将阻塞运行 - */ - onLoad?(): void | Promise - - /** - * 当异步处理对象被释放时执行的操作 - * - * 目前版本无任何用处,请等待未来的更新 - * - * 未来或许会涉及到错误处理方式的更改,此后请使用无名杀提供的方式来进行异步错误处理的更改 - * - * 若该函数为异步函数,则将阻塞运行 - */ - onUnload?(): void | Promise - - /** - * 当全局监听器捕获到`unhandledrejection`事件时会调用的函数 - * - * 该函数用于正式处理异步报错事件 - * - * 该函数为异步函数时不会阻塞运行 - * - * @param event - 被捕获到的异步报错事件 - */ - onHandle?(event: PromiseRejectionEvent): void | Promise - - /** - * 当触发`window.onerror`时会调用的函数 - * - * 用于在执行`window.onerror`前执行一些可能存在的善后操作 - * - * 该函数无法为异步函数 - */ - onErrorPrepare?(): void - - /** - * 当`window.onerror`运行**即将结束**时会调用的函数 - * - * 用于在执行`window.onerror`后执行一些可能存在的善后操作 - * - * 该函数无法为异步函数 - */ - onErrorFinish?(): void -} +/** + * 不同浏览器下异步报错问题处理方式的接口,用于定义不同浏览器对待异步报错的处理方式 + */ +export interface PromiseErrorHandler { + /** + * 当异步处理对象初始化时执行的操作 + * + * 因为未来或许会涉及到错误处理方式的更改,故所有初始化操作请于此处执行 + * + * 若该函数为异步函数,则将阻塞运行 + */ + onLoad?(): void | Promise; + + /** + * 当异步处理对象被释放时执行的操作 + * + * 目前版本无任何用处,请等待未来的更新 + * + * 未来或许会涉及到错误处理方式的更改,此后请使用无名杀提供的方式来进行异步错误处理的更改 + * + * 若该函数为异步函数,则将阻塞运行 + */ + onUnload?(): void | Promise; + + /** + * 当全局监听器捕获到`unhandledrejection`事件时会调用的函数 + * + * 该函数用于正式处理异步报错事件 + * + * 该函数为异步函数时不会阻塞运行 + * + * @param event - 被捕获到的异步报错事件 + */ + onHandle?(event: PromiseRejectionEvent): void | Promise; + + /** + * 当触发`window.onerror`时会调用的函数 + * + * 用于在执行`window.onerror`前执行一些可能存在的善后操作 + * + * 该函数无法为异步函数 + */ + onErrorPrepare?(): void; + + /** + * 当`window.onerror`运行**即将结束**时会调用的函数 + * + * 用于在执行`window.onerror`后执行一些可能存在的善后操作 + * + * 该函数无法为异步函数 + */ + onErrorFinish?(): void; +} diff --git a/noname/util/struct/promise-error-handler/chrome.js b/noname/util/struct/promise-error-handler/chrome.js index e76317535..028ccfe47 100644 --- a/noname/util/struct/promise-error-handler/chrome.js +++ b/noname/util/struct/promise-error-handler/chrome.js @@ -1,195 +1,200 @@ -/** - * 关于`Google Chrome`的异步错误处理 - * - * 由于`v8`提供的`Error.prepareStackTrace(error, structuredStackTrace)`接口存在一些限制,导致不适合无名杀 - * - * 故我们直接解析`Error`的栈堆信息,来获取相关内容 - * - * ~~`Chrome`所用的`v8`引擎为`Error`提供了特有的报错栈堆处理接口,用于用户自定义报错栈堆的内容。~~ - * - * ~~我们用到了`Error.prepareStackTrace(error, structuredStackTrace)`这个接口,这个接口的信息可参考[这里](https://v8.dev/docs/stack-trace-api#customizing-stack-traces)~~ - * - * ~~该接口提供了结构化的栈堆信息,很幸运的是,这个结构化的栈堆能直接告诉我们报错的文件以及位置,故我们使用该接口,让异步报错能直接定位原始位置~~ - * - * @implements {PromiseErrorHandler} - */ -export class ChromePromiseErrorHandler { - /** - * ~~用于临时记录报错信息的列表,通过`Error.prepareStackTrace`更新该列表~~ - * - * 现在用于存储报错过的错误信息 - * - * @type {Error[]} - */ - #errorList; - - /** - * @type {typeof Error.prepareStackTrace} - * - * @deprecated - */ - #_originErrorPrepareStackTrace; - - /** - * 判断是否是v8错误栈堆用到的正则 - */ - #STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m; - - /** - * ~~初始化`Error.prepareStackTrace`,将该值赋值成我们需要的函数~~ - * - * ~~未防止本来Error.prepareStackTrace便存在赋值的行为,我们将原始值存储,并在需要的函数中调用~~ - * - * 初始化存储报错信息的列表 - */ - onLoad() { - /* - this.#errorList = []; - this.#originErrorPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = (error, stackTraces) => { - // 其实这步或许不需要 - // 但真赋值了Error.prepareStackTrace的话,保不齐会出现需要返回值的情况 - const result = this.#originErrorPrepareStackTrace - ? this.#originErrorPrepareStackTrace(error, stackTraces) - : void 0; - this.#errorList.push([error, stackTraces]); - return result; - }; - */ - this.#errorList = []; - } - - /** - * ~~将原来可能的`Error.prepareStackTrace`赋值回去~~ - * - * @deprecated - */ - onUnload() { - /* - Error.prepareStackTrace = this.#originErrorPrepareStackTrace; - */ - } - - /** - * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 - * - * 如果捕获出来的错误存放我们存报错栈堆的列表中,则证明该错误能获取到栈堆,由此来获取报错的地址和行列号 - * - * @param {PromiseRejectionEvent} event - */ - onHandle(event) { - event.promise.catch((error) => { - // 如果`error`是个错误,则继续处理 - if (error instanceof Error) { - // 如果已经处理过该错误,则不再处理 - if (this.#errorList.includes(error)) return; - this.#errorList.push(error); - // 如果`error`拥有字符串形式的报错栈堆,且报错栈堆确实符合v8的stack - if (typeof error.stack === 'string' && this.#STACK_REGEXP.test(error.stack)) { - // 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行 - // 为了处理eval的情况,故必须获取完行数 - let lines = error.stack.split('\n').filter((line) => - this.#STACK_REGEXP.test(line)); - - // 提供类型信息防止vscode报错 - /** - * @type {string | undefined} - */ - let fileName = void 0; - - /** - * @type {number | undefined} - */ - let line = void 0; - - /** - * @type {number | undefined} - */ - let column = void 0; - - // 从第一条开始遍历,一直遍历到不存在eval的位置 - for (let currentLine = 0; currentLine < lines.length; ++currentLine) { - if (/\(eval /.test(lines[currentLine])) continue; - - let formatedLine = lines[currentLine].replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, ''); - - const location = formatedLine.match(/ (\(.+\)$)/); - if (location) formatedLine = formatedLine.replace(location[0], ''); - - const locationParts = extractLocation(location ? location[1] : formatedLine); - - fileName = ['eval', ''].includes(locationParts[0]) ? void 0 : locationParts[0]; - line = Number(locationParts[1]); - column = Number(locationParts[2]); - break; - } - - // @ts-ignore - window.onerror(error.message, fileName, line, column, error); - } - // 反之我们只能不考虑报错文件信息,直接调用onerror - else { - try{ - // @ts-ignore - let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1]) - if (typeof line == 'string') line = Number(line); - if (typeof column == 'string') column = Number(column); - // @ts-ignore - window.onerror(error.message, src, line, column, error); - }catch(e){ - window.onerror(error.message,'',0,0, error); - } - } - } - /* - console.error(error) - const result = this.#errorList.find(savedError => savedError[0] === error); - if (result) { - // @ts-ignore - window.onerror( - result[0].message, - result[1][0].getScriptNameOrSourceURL(), - result[1][0].getLineNumber() || void 0, - result[1][0].getColumnNumber() || void 0, - result[0] - ); - } - */ - }); - } - - /** - * ~~正式报错时便不再需要报错信息了,故直接清空列表,释放内存~~ - * - * @deprecated - */ - onErrorPrepare() { - /* - this.#errorList.length = 0; - */ - } -} - -/** - * 简易的解析报错栈堆位置信息的函数 - * - * @param {string} urlLike - * @returns {string[]} - */ -export function extractLocation(urlLike) { - // 不存在地址信息的字符串 - if (!/:/.test(urlLike)) { - return [urlLike]; - } - - // 捕获位置用到的正则 - const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; - const parts = regExp.exec(urlLike.replace(/[()]/g, '')); - - // @ts-ignore - return [parts[1], parts[2] || void 0, parts[3] || void 0]; -} - -/** - * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler - */ +/** + * 关于`Google Chrome`的异步错误处理 + * + * 由于`v8`提供的`Error.prepareStackTrace(error, structuredStackTrace)`接口存在一些限制,导致不适合无名杀 + * + * 故我们直接解析`Error`的栈堆信息,来获取相关内容 + * + * ~~`Chrome`所用的`v8`引擎为`Error`提供了特有的报错栈堆处理接口,用于用户自定义报错栈堆的内容。~~ + * + * ~~我们用到了`Error.prepareStackTrace(error, structuredStackTrace)`这个接口,这个接口的信息可参考[这里](https://v8.dev/docs/stack-trace-api#customizing-stack-traces)~~ + * + * ~~该接口提供了结构化的栈堆信息,很幸运的是,这个结构化的栈堆能直接告诉我们报错的文件以及位置,故我们使用该接口,让异步报错能直接定位原始位置~~ + * + * @implements {PromiseErrorHandler} + */ +export class ChromePromiseErrorHandler { + /** + * ~~用于临时记录报错信息的列表,通过`Error.prepareStackTrace`更新该列表~~ + * + * 现在用于存储报错过的错误信息 + * + * @type {Error[]} + */ + #errorList; + + /** + * @type {typeof Error.prepareStackTrace} + * + * @deprecated + */ + #_originErrorPrepareStackTrace; + + /** + * 判断是否是v8错误栈堆用到的正则 + */ + #STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m; + + /** + * ~~初始化`Error.prepareStackTrace`,将该值赋值成我们需要的函数~~ + * + * ~~未防止本来Error.prepareStackTrace便存在赋值的行为,我们将原始值存储,并在需要的函数中调用~~ + * + * 初始化存储报错信息的列表 + */ + onLoad() { + /* + this.#errorList = []; + this.#originErrorPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (error, stackTraces) => { + // 其实这步或许不需要 + // 但真赋值了Error.prepareStackTrace的话,保不齐会出现需要返回值的情况 + const result = this.#originErrorPrepareStackTrace + ? this.#originErrorPrepareStackTrace(error, stackTraces) + : void 0; + this.#errorList.push([error, stackTraces]); + return result; + }; + */ + this.#errorList = []; + } + + /** + * ~~将原来可能的`Error.prepareStackTrace`赋值回去~~ + * + * @deprecated + */ + onUnload() { + /* + Error.prepareStackTrace = this.#originErrorPrepareStackTrace; + */ + } + + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获出来的错误存放我们存报错栈堆的列表中,则证明该错误能获取到栈堆,由此来获取报错的地址和行列号 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + // 如果`error`是个错误,则继续处理 + if (error instanceof Error) { + // 如果已经处理过该错误,则不再处理 + if (this.#errorList.includes(error)) return; + this.#errorList.push(error); + // 如果`error`拥有字符串形式的报错栈堆,且报错栈堆确实符合v8的stack + if (typeof error.stack === "string" && this.#STACK_REGEXP.test(error.stack)) { + // 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行 + // 为了处理eval的情况,故必须获取完行数 + let lines = error.stack.split("\n").filter((line) => this.#STACK_REGEXP.test(line)); + + // 提供类型信息防止vscode报错 + /** + * @type {string | undefined} + */ + let fileName = void 0; + + /** + * @type {number | undefined} + */ + let line = void 0; + + /** + * @type {number | undefined} + */ + let column = void 0; + + // 从第一条开始遍历,一直遍历到不存在eval的位置 + for (let currentLine = 0; currentLine < lines.length; ++currentLine) { + if (/\(eval /.test(lines[currentLine])) continue; + + let formatedLine = lines[currentLine] + .replace(/^\s+/, "") + .replace(/\(eval code/g, "(") + .replace(/^.*?\s+/, ""); + + const location = formatedLine.match(/ (\(.+\)$)/); + if (location) formatedLine = formatedLine.replace(location[0], ""); + + const locationParts = extractLocation(location ? location[1] : formatedLine); + + fileName = ["eval", ""].includes(locationParts[0]) + ? void 0 + : locationParts[0]; + line = Number(locationParts[1]); + column = Number(locationParts[2]); + break; + } + + // @ts-ignore + window.onerror(error.message, fileName, line, column, error); + } + // 反之我们只能不考虑报错文件信息,直接调用onerror + else { + try { + // @ts-ignore + let [_, src = void 0, line = void 0, column = void 0] = + /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split("\n")[1]); + if (typeof line == "string") line = Number(line); + if (typeof column == "string") column = Number(column); + // @ts-ignore + window.onerror(error.message, src, line, column, error); + } catch (e) { + window.onerror(error.message, "", 0, 0, error); + } + } + } + /* + console.error(error) + const result = this.#errorList.find(savedError => savedError[0] === error); + if (result) { + // @ts-ignore + window.onerror( + result[0].message, + result[1][0].getScriptNameOrSourceURL(), + result[1][0].getLineNumber() || void 0, + result[1][0].getColumnNumber() || void 0, + result[0] + ); + } + */ + }); + } + + /** + * ~~正式报错时便不再需要报错信息了,故直接清空列表,释放内存~~ + * + * @deprecated + */ + onErrorPrepare() { + /* + this.#errorList.length = 0; + */ + } +} + +/** + * 简易的解析报错栈堆位置信息的函数 + * + * @param {string} urlLike + * @returns {string[]} + */ +export function extractLocation(urlLike) { + // 不存在地址信息的字符串 + if (!/:/.test(urlLike)) { + return [urlLike]; + } + + // 捕获位置用到的正则 + const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/; + const parts = regExp.exec(urlLike.replace(/[()]/g, "")); + + // @ts-ignore + return [parts[1], parts[2] || void 0, parts[3] || void 0]; +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/struct/promise-error-handler/firefox.js b/noname/util/struct/promise-error-handler/firefox.js index c2d37d77a..56b3f9d14 100644 --- a/noname/util/struct/promise-error-handler/firefox.js +++ b/noname/util/struct/promise-error-handler/firefox.js @@ -1,40 +1,40 @@ -/** - * 关于`Mozilla Firefox`的异步错误处理 - * - * 很幸运,Mozilla直接为`Firefox`的报错提供了地址和行列号,故我们能直接获取到要获取的信息,不用像`v8`那样通过栈堆获取 - * - * 虽然但是,我们还是需要判断一下捕获的报错是否是错误 - * - * @implements {PromiseErrorHandler} - */ -export class FirefoxPromiseErrorHandler { - /** - * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 - * - * 如果捕获到的错误是`Error`,则能直接通过`Firefox`的特性来获取地址和行列号 - * - * @param {PromiseRejectionEvent} event - */ - onHandle(event) { - event.promise.catch((error) => { - if (typeof error === 'object' && error instanceof Error) { - // Firefox在大环境下默认情况必须要那么多ts-ignore - // @ts-ignore - window.onerror( - error.message, - // @ts-ignore - error.fileName, - // @ts-ignore - error.lineNumber, - // @ts-ignore - error.columnNumber, - error - ); - } - }); - } -} - -/** - * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler - */ +/** + * 关于`Mozilla Firefox`的异步错误处理 + * + * 很幸运,Mozilla直接为`Firefox`的报错提供了地址和行列号,故我们能直接获取到要获取的信息,不用像`v8`那样通过栈堆获取 + * + * 虽然但是,我们还是需要判断一下捕获的报错是否是错误 + * + * @implements {PromiseErrorHandler} + */ +export class FirefoxPromiseErrorHandler { + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获到的错误是`Error`,则能直接通过`Firefox`的特性来获取地址和行列号 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + if (typeof error === "object" && error instanceof Error) { + // Firefox在大环境下默认情况必须要那么多ts-ignore + // @ts-ignore + window.onerror( + error.message, + // @ts-ignore + error.fileName, + // @ts-ignore + error.lineNumber, + // @ts-ignore + error.columnNumber, + error + ); + } + }); + } +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/noname/util/struct/promise-error-handler/index.js b/noname/util/struct/promise-error-handler/index.js index 747d197a7..182dccf4c 100644 --- a/noname/util/struct/promise-error-handler/index.js +++ b/noname/util/struct/promise-error-handler/index.js @@ -1,13 +1,13 @@ -/** - * 关于不同浏览器下对异步错误的处理方式 - * - * 目前已实现的浏览器如下: - * - * - `Google Chrome`(包括`electron`、`cordova`以及`crosswalk`) - * - `Mozilla Firefox` - * - */ - -export { ChromePromiseErrorHandler } from './chrome.js'; -export { FirefoxPromiseErrorHandler } from './firefox.js'; -export { UnknownPromiseErrorHandler } from './unknown.js'; +/** + * 关于不同浏览器下对异步错误的处理方式 + * + * 目前已实现的浏览器如下: + * + * - `Google Chrome`(包括`electron`、`cordova`以及`crosswalk`) + * - `Mozilla Firefox` + * + */ + +export { ChromePromiseErrorHandler } from "./chrome.js"; +export { FirefoxPromiseErrorHandler } from "./firefox.js"; +export { UnknownPromiseErrorHandler } from "./unknown.js"; diff --git a/noname/util/struct/promise-error-handler/unknown.js b/noname/util/struct/promise-error-handler/unknown.js index 5d8a13f62..74ac2728f 100644 --- a/noname/util/struct/promise-error-handler/unknown.js +++ b/noname/util/struct/promise-error-handler/unknown.js @@ -1,32 +1,32 @@ -/** - * 关于除已实现浏览器外其余浏览器的异步错误处理 - * - * 很遗憾,对于这类浏览器,因为标准未涉及报错栈堆或地址及行列号,故我们只能直接,暴力地throw出我们捕获到的错误, - * - * 尽管我们还是会为了这类浏览器判断是不是捕获到了一个`Error` - * - * 总之,虽然这里跟Safari无关,但我们还是为新时代IE默哀一秒 - * - * @implements {PromiseErrorHandler} - */ -export class UnknownPromiseErrorHandler { - /** - * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 - * - * 如果捕获到的错误是`Error`,则...我们只能暴力的将`Error`再次`throw`出去 - * - * @param {PromiseRejectionEvent} event - */ - onHandle(event) { - event.promise.catch((error) => { - if (typeof error === 'object' && error instanceof Error) { - // 很遗憾,因浏览器问题,你只能看到这一段 - throw error; - } - }); - } -} - -/** - * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler - */ +/** + * 关于除已实现浏览器外其余浏览器的异步错误处理 + * + * 很遗憾,对于这类浏览器,因为标准未涉及报错栈堆或地址及行列号,故我们只能直接,暴力地throw出我们捕获到的错误, + * + * 尽管我们还是会为了这类浏览器判断是不是捕获到了一个`Error` + * + * 总之,虽然这里跟Safari无关,但我们还是为新时代IE默哀一秒 + * + * @implements {PromiseErrorHandler} + */ +export class UnknownPromiseErrorHandler { + /** + * 在获取报错的时候,我们通过发生报错的`Promise`来进行捕获错误的操作 + * + * 如果捕获到的错误是`Error`,则...我们只能暴力的将`Error`再次`throw`出去 + * + * @param {PromiseRejectionEvent} event + */ + onHandle(event) { + event.promise.catch((error) => { + if (typeof error === "object" && error instanceof Error) { + // 很遗憾,因浏览器问题,你只能看到这一段 + throw error; + } + }); + } +} + +/** + * @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler + */ diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 000000000..e8760a4fd --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,13 @@ +/** @type {import("prettier").Config} */ +export default { + arrowParens: "always", + bracketSpacing: true, + endOfLine: "lf", + printWidth: 110, + proseWrap: "preserve", + quoteProps: "as-needed", + semi: true, + tabWidth: 4, + trailingComma: "es5", + useTabs: true, +}; diff --git a/theme/music/style.css b/theme/music/style.css index aa0ee1a32..6c90e91fd 100644 --- a/theme/music/style.css +++ b/theme/music/style.css @@ -1,130 +1,150 @@ -html{ +html { color: white; text-shadow: black 0 0 2px; - background: url('grid.png'),linear-gradient(#333333, #222222) fixed; + background: url("grid.png"), linear-gradient(#333333, #222222) fixed; } -#system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,#window>.dialog.popped, +#system > div > div, +#mebg, +.control, +.player, +.card, +.avatar, +.avatar2, +.button, +#window > .dialog.popped, #arena:not(.long) .player.unseen .equips:not(*:empty), -#arena.long .player.unseen2 .equips:not(*:empty),.menu,#splash>div, -#arena.mobile:not(.chess) .player[data-position='0'] .equips,.playerbg,#window .player.playerbg,.menubg,.mebg{ +#arena.long .player.unseen2 .equips:not(*:empty), +.menu, +#splash > div, +#arena.mobile:not(.chess) .player[data-position="0"] .equips, +.playerbg, +#window .player.playerbg, +.menubg, +.mebg { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; background-image: linear-gradient(#4b4b4b, #464646); border-radius: 8px; } -#arena.observe .handcards>.card{ +#arena.observe .handcards > .card { background: linear-gradient(#4b4b4b, #464646) !important; } -.videonode.menubutton.extension.current{ - box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 133, 255, 0.4) 0 2px 5px, rgba(0, 133, 255, 0.5) 0 0 12px, rgba(0, 133, 255, 0.8) 0 0 15px; +.videonode.menubutton.extension.current { + box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 133, 255, 0.4) 0 2px 5px, + rgba(0, 133, 255, 0.5) 0 0 12px, rgba(0, 133, 255, 0.8) 0 0 15px; } -body[data-background_color_music='blue'] #system>div>div, -body[data-background_color_music='blue'] #mebg, -body[data-background_color_music='blue'] .control, -body[data-background_color_music='blue'] .player, -body[data-background_color_music='blue'] .card, -body[data-background_color_music='blue'] .avatar, -body[data-background_color_music='blue'] .avatar2, -body[data-background_color_music='blue'] .button, -body[data-background_color_music='blue'] #window>.dialog.popped, -body[data-background_color_music='blue'] .player.unseen .equips:not(*:empty), -body[data-background_color_music='blue'] .menu, -body[data-background_color_music='blue'] #splash>div, -body[data-background_color_music='blue'] #arena.mobile:not(.chess) .player[data-position='0'] .equips{ +body[data-background_color_music="blue"] #system > div > div, +body[data-background_color_music="blue"] #mebg, +body[data-background_color_music="blue"] .control, +body[data-background_color_music="blue"] .player, +body[data-background_color_music="blue"] .card, +body[data-background_color_music="blue"] .avatar, +body[data-background_color_music="blue"] .avatar2, +body[data-background_color_music="blue"] .button, +body[data-background_color_music="blue"] #window > .dialog.popped, +body[data-background_color_music="blue"] .player.unseen .equips:not(*:empty), +body[data-background_color_music="blue"] .menu, +body[data-background_color_music="blue"] #splash > div, +body[data-background_color_music="blue"] #arena.mobile:not(.chess) .player[data-position="0"] .equips { background-image: linear-gradient(#6c7989, #434b55); } -.marks>.card.fullskin>.markcount.menubutton{ - background: url('wood3.png'); +.marks > .card.fullskin > .markcount.menubutton { + background: url("wood3.png"); } - /*.player.current_action{ background-image: linear-gradient(rgba(57, 123, 4,1), rgb(48, 103, 3)); }*/ -#window>.dialog.popped{ +#window > .dialog.popped { border-radius: 6px; } -.control,#system>div>div,.judges>div,.marks>div, +.control, +#system > div > div, +.judges > div, +.marks > div, #arena:not(.long) .player.unseen .equips:not(*:empty), -#arena.long .player.unseen2 .equips:not(*:empty){ - border-radius:4px; +#arena.long .player.unseen2 .equips:not(*:empty) { + border-radius: 4px; overflow: hidden; } -#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty)>.card:not(.selected), -#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty)>.card:not(.selected){ +#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty) > .card:not(.selected), +#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty) > .card:not(.selected) { background: none !important; } -.player,#mebg{ +.player, +#mebg { /*background:url('wood.png') left repeat-y,url('wood.png') right repeat-y,linear-gradient(#4b4b4b, #464646);*/ } -.card{ - color:white; +.card { + color: white; } -.cardbg{ +.cardbg { background-size: initial !important; } -.card:not(*:empty),.cardbg{ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('wood3.png'); +.card:not(*:empty), +.cardbg { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("wood3.png"); } -.marks>.card:not(.fullskin){ +.marks > .card:not(.fullskin) { color: white; text-shadow: black 0 0 2px; background: linear-gradient(#4b4b4b, #464646); } -#me>div>div>.card,#arena>.card:not(*:empty){ +#me > div > div > .card, +#arena > .card:not(*:empty) { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; } -#system>div>.glow { - background-image: linear-gradient(rgba(47,101,150,1), rgba(43, 90, 132,1)); +#system > div > .glow { + background-image: linear-gradient(rgba(47, 101, 150, 1), rgba(43, 90, 132, 1)); box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px !important; } -.fire{ - color: rgb(255,119,63); +.fire { + color: rgb(255, 119, 63); } -.thunder{ - color: rgb(117,186,255); +.thunder { + color: rgb(117, 186, 255); } -.poison{ - color: rgb(104,221,127); +.poison { + color: rgb(104, 221, 127); } -.brown{ - color: rgb(195,161,223); +.brown { + color: rgb(195, 161, 223); } -#roundmenu.clock>div:nth-of-type(15){ +#roundmenu.clock > div:nth-of-type(15) { background: linear-gradient(#4b4b4b, #464646); - box-shadow: rgba(0,0,0,0.6) 0 0 5px inset; + box-shadow: rgba(0, 0, 0, 0.6) 0 0 5px inset; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -6px -6px; } -.woodbg{ - color:rgba(77, 60, 51,0.8) !important; - text-shadow:none !important; +.woodbg { + color: rgba(77, 60, 51, 0.8) !important; + text-shadow: none !important; } -.woodbg .menubutton.large{ - background: url('wood3.png') !important; +.woodbg .menubutton.large { + background: url("wood3.png") !important; box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px !important; } -#window .player.minskin.obstacle[data-obscolor='blue']{ - background: repeating-linear-gradient( - 135deg, - rgba(0, 133, 255, 0.5), - rgba(0, 133, 255, 0.5) 10px, - rgba(0, 0, 0, 0) 10px, - rgba(0, 0, 0, 0) 20px - ); - box-shadow: rgba(0, 133, 255, 0.5) 0 0 0 1px; +#window .player.minskin.obstacle[data-obscolor="blue"] { + background: repeating-linear-gradient( + 135deg, + rgba(0, 133, 255, 0.5), + rgba(0, 133, 255, 0.5) 10px, + rgba(0, 0, 0, 0) 10px, + rgba(0, 0, 0, 0) 20px + ); + box-shadow: rgba(0, 133, 255, 0.5) 0 0 0 1px; } diff --git a/theme/simple/style.css b/theme/simple/style.css index 5e6dfc79a..25e92cd55 100644 --- a/theme/simple/style.css +++ b/theme/simple/style.css @@ -1,8 +1,8 @@ -html{ +html { color: white; text-shadow: black 0 0 2px; min-height: 100%; - background-image: url('../../image/background/ol_bg.jpg'); + background-image: url("../../image/background/ol_bg.jpg"); background-size: cover; background-position: 50% 50%; } @@ -19,100 +19,120 @@ html{ -webkit-backdrop-filter: blur(3px); box-shadow: rgba(0, 0, 0, 0.6) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 3px 10px; } -#system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,#window>.dialog.popped, +#system > div > div, +#mebg, +.control, +.player, +.card, +.avatar, +.avatar2, +.button, +#window > .dialog.popped, #arena:not(.long) .player.unseen .equips:not(*:empty), -#arena.long .player.unseen2 .equips:not(*:empty),.menu,.menubutton,#splash>div, -#arena.mobile:not(.chess) .player[data-position='0'] .equips,.playerbg,#window .player.playerbg,.menubg,.mebg{ +#arena.long .player.unseen2 .equips:not(*:empty), +.menu, +.menubutton, +#splash > div, +#arena.mobile:not(.chess) .player[data-position="0"] .equips, +.playerbg, +#window .player.playerbg, +.menubg, +.mebg { box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; - background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)); + background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)); border-radius: 8px; } -#arena.mobile.textequip:not(.chess) .player[data-position='0'] .equips{ +#arena.mobile.textequip:not(.chess) .player[data-position="0"] .equips { background-image: none; box-shadow: rgba(0, 0, 0, 0.2) -1px 0px 0px 0px; overflow-y: scroll; } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card{ - background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)) !important; +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card { + background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)) !important; } -#arena.observe .handcards>.card{ - background: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)) !important; +#arena.observe .handcards > .card { + background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)) !important; } -.videonode.menubutton.extension.current{ - background-image: linear-gradient(rgba(89, 111, 117, 0.4),rgba(89, 111, 117, 0.4)); +.videonode.menubutton.extension.current { + background-image: linear-gradient(rgba(89, 111, 117, 0.4), rgba(89, 111, 117, 0.4)); box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; } /*.player.current_action{ background-image: linear-gradient(rgba(47,101,150,1), rgba(43, 90, 132,1)); }*/ -.menubutton{ +.menubutton { border-radius: 4px; } /*.player{ background-image: url('card.png'); background-size: cover; }*/ -#window>.dialog.popped{ +#window > .dialog.popped { border-radius: 6px; } -.control,#system>div>div,.judges>div,.marks>div, +.control, +#system > div > div, +.judges > div, +.marks > div, #arena:not(.long) .player.unseen .equips:not(*:empty), -#arena.long .player.unseen2 .equips:not(*:empty){ - border-radius:4px; +#arena.long .player.unseen2 .equips:not(*:empty) { + border-radius: 4px; overflow: hidden; } -#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty)>.card:not(.selected), -#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty)>.card:not(.selected){ +#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty) > .card:not(.selected), +#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty) > .card:not(.selected) { background: none !important; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 4px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 4px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { width: 100%; - height: 100%; - left: 0; - top: 0; + height: 100%; + left: 0; + top: 0; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: block; - transform: scale(0.43) !important; - transform-origin: left top; - left: 2px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: block; + transform: scale(0.43) !important; + transform-origin: left top; + left: 2px; + top: 3px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name.long{ - top: 2px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name.long { + top: 2px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: block; - transform: scale(0.43) !important; - transform-origin: right top; - right: 3px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: block; + transform: scale(0.43) !important; + transform-origin: right top; + right: 3px; + top: 3px; } -.cardbg{ +.cardbg { background-size: 100% 100% !important; } -.card{ - color:white; +.card { + color: white; } -.card:not(*:empty),.cardbg{ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('card.png'); - background-size:100% 100%; +.card:not(*:empty), +.cardbg { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("card.png"); + background-size: 100% 100%; } -.card .markcount{ +.card .markcount { box-shadow: rgba(0, 0, 0, 0.8) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; - background: url('card.png'); + background: url("card.png"); background-size: cover; /*color: white;*/ } -#me>div>div>.card,#arena>.card:not(*:empty){ +#me > div > div > .card, +#arena > .card:not(*:empty) { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; } /*.player{ @@ -125,58 +145,58 @@ html{ ); }*/ -.card:empty,.card.infohidden{ - background: url('../style/cardback/image/official.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("../style/cardback/image/official.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('../style/cardback/image/official2.png'); +.card.infohidden:not(.infoflip) { + background: url("../style/cardback/image/official2.png"); background-size: 100% 100%; } -#system>div>.glow { - background-image: linear-gradient(rgba(47,101,150,1), rgba(43, 90, 132,1)); +#system > div > .glow { + background-image: linear-gradient(rgba(47, 101, 150, 1), rgba(43, 90, 132, 1)); box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px !important; } -.menupaused{ +.menupaused { opacity: 0.3 !important; } -.player .marks>div:first-child>div{ +.player .marks > div:first-child > div { filter: invert(0.8) sepia(1); -webkit-filter: invert(0.8) sepia(1); } -.fire{ - color: rgb(255,119,63); +.fire { + color: rgb(255, 119, 63); } -.thunder{ - color: rgb(117,186,255); +.thunder { + color: rgb(117, 186, 255); } -.poison{ - color: rgb(104,221,127); +.poison { + color: rgb(104, 221, 127); } -.brown{ - color: rgb(195,161,223); +.brown { + color: rgb(195, 161, 223); } -#roundmenu.clock>div:nth-of-type(15){ - background: rgba(0,0,0,0.3); - box-shadow: rgba(0,0,0,0.6) 0 0 5px inset; +#roundmenu.clock > div:nth-of-type(15) { + background: rgba(0, 0, 0, 0.3); + box-shadow: rgba(0, 0, 0, 0.6) 0 0 5px inset; } - -.woodbg{ - color:rgba(77, 60, 51,1) !important; - text-shadow:none !important; +.woodbg { + color: rgba(77, 60, 51, 1) !important; + text-shadow: none !important; } -.woodbg .menubutton.large{ - background: url('card2.png') !important; +.woodbg .menubutton.large { + background: url("card2.png") !important; background-size: 100% 100% !important; box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px !important; } -.player>.glassbg{ +.player > .glassbg { left: 0; top: 0; margin: 0; @@ -189,12 +209,12 @@ html{ z-index: 1; pointer-events: none; } -.player>.glassbg>div:last-child{ +.player > .glassbg > div:last-child { width: 100%; height: 100%; - background: rgba(0,0,0,0.4); + background: rgba(0, 0, 0, 0.4); } -.player>.glassbg>div:first-child{ +.player > .glassbg > div:first-child { left: 0; top: 0; margin: 0; @@ -205,22 +225,22 @@ html{ filter: blur(3px); -webkit-filter: blur(3px); } -.popup-container>.prompt-container>div>div{ - background: rgba(0,0,0,0.6); +.popup-container > .prompt-container > div > div { + background: rgba(0, 0, 0, 0.6); } -.popup-container>.menu.visual>.button.dashedmenubutton{ +.popup-container > .menu.visual > .button.dashedmenubutton { box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px !important; border: none; - background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)) !important; + background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)) !important; } -.popup-container>.menu.visual>.button.dashedmenubutton:not(.hpbutton){ +.popup-container > .menu.visual > .button.dashedmenubutton:not(.hpbutton) { width: 90px; height: 90px; } -.popup-container>.menu.visual>.button.dashedmenubutton.controlbutton{ - height: 26px; +.popup-container > .menu.visual > .button.dashedmenubutton.controlbutton { + height: 26px; } -.popup-container>.menu.visual>.button.dashedmenubutton.controlbutton>div{ +.popup-container > .menu.visual > .button.dashedmenubutton.controlbutton > div { line-height: 26px; } diff --git a/theme/style/card/custom.css b/theme/style/card/custom.css index da2a6ea87..c26388df2 100644 --- a/theme/style/card/custom.css +++ b/theme/style/card/custom.css @@ -1,35 +1,35 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background-size:100% 100%; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background-size: 100% 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 4px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 4px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { width: 100%; - height: 100%; - left: 0; - top: 0; + height: 100%; + left: 0; + top: 0; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: block; - transform: scale(0.43) !important; - transform-origin: left top; - left: 2px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: block; + transform: scale(0.43) !important; + transform-origin: left top; + left: 2px; + top: 3px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name.long{ - top: 2px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name.long { + top: 2px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: block; - transform: scale(0.43) !important; - transform-origin: right top; - right: 3px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: block; + transform: scale(0.43) !important; + transform-origin: right top; + right: 3px; + top: 3px; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -4px -4px; } diff --git a/theme/style/card/music.css b/theme/style/card/music.css index 1b618d9c4..ada0dac32 100644 --- a/theme/style/card/music.css +++ b/theme/style/card/music.css @@ -1,20 +1,20 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('../../music/wood3.png'); - background-size:auto; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("../../music/wood3.png"); + background-size: auto; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -6px -6px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 100%; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: none; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: none; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: none; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: none; } diff --git a/theme/style/card/new.css b/theme/style/card/new.css index 2ed8cf53f..775751a96 100644 --- a/theme/style/card/new.css +++ b/theme/style/card/new.css @@ -1,36 +1,36 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('image/new.png'); - background-size:100% 100%; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("image/new.png"); + background-size: 100% 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 4px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 4px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { width: 100%; - height: 100%; - left: 0; - top: 0; + height: 100%; + left: 0; + top: 0; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: block; - transform: scale(0.43) !important; - transform-origin: left top; - left: 2px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: block; + transform: scale(0.43) !important; + transform-origin: left top; + left: 2px; + top: 3px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name.long{ - top: 2px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name.long { + top: 2px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: block; - transform: scale(0.43) !important; - transform-origin: right top; - right: 3px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: block; + transform: scale(0.43) !important; + transform-origin: right top; + right: 3px; + top: 3px; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -4px -4px; } diff --git a/theme/style/card/ol.css b/theme/style/card/ol.css index f7aea61c0..333ea3341 100644 --- a/theme/style/card/ol.css +++ b/theme/style/card/ol.css @@ -1,37 +1,36 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('image/ol.png'); - background-size:100% 100%; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("image/ol.png"); + background-size: 100% 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 4px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 4px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { width: 100%; - height: 100%; - left: 0; - top: 0; + height: 100%; + left: 0; + top: 0; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: block; - transform: scale(0.43) !important; - transform-origin: left top; - left: 2px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: block; + transform: scale(0.43) !important; + transform-origin: left top; + left: 2px; + top: 3px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name.long{ - top: 2px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name.long { + top: 2px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: block; - transform: scale(0.43) !important; - transform-origin: right top; - right: 3px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: block; + transform: scale(0.43) !important; + transform-origin: right top; + right: 3px; + top: 3px; } - -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -4px -4px; } diff --git a/theme/style/card/simple.css b/theme/style/card/simple.css index 2c3f44fe4..97f6e4ac4 100644 --- a/theme/style/card/simple.css +++ b/theme/style/card/simple.css @@ -1,36 +1,36 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('../../simple/card.png'); - background-size:100% 100%; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("../../simple/card.png"); + background-size: 100% 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 4px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 4px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { width: 100%; - height: 100%; - left: 0; - top: 0; + height: 100%; + left: 0; + top: 0; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: block; - transform: scale(0.43) !important; - transform-origin: left top; - left: 2px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: block; + transform: scale(0.43) !important; + transform-origin: left top; + left: 2px; + top: 3px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name.long{ - top: 2px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name.long { + top: 2px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: block; - transform: scale(0.43) !important; - transform-origin: right top; - right: 3px; - top: 3px; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: block; + transform: scale(0.43) !important; + transform-origin: right top; + right: 3px; + top: 3px; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -4px -4px; } diff --git a/theme/style/card/wood.css b/theme/style/card/wood.css index 28f26d3c3..2944bc944 100644 --- a/theme/style/card/wood.css +++ b/theme/style/card/wood.css @@ -1,20 +1,20 @@ -.card:not(*:empty){ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('../../woodden/wood.jpg'); - background-size:auto; +.card:not(*:empty) { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("../../woodden/wood.jpg"); + background-size: auto; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -6px -6px; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5 { - border-radius: 100%; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 { + border-radius: 100%; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.name{ - display: none; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .name { + display: none; } -#arena.mobile:not(.chess) .player[data-position='0']>.equips>.equip5>.info{ - display: none; +#arena.mobile:not(.chess) .player[data-position="0"] > .equips > .equip5 > .info { + display: none; } diff --git a/theme/style/cardback/custom.css b/theme/style/cardback/custom.css index 2c5227441..cea1873a3 100644 --- a/theme/style/cardback/custom.css +++ b/theme/style/cardback/custom.css @@ -1,6 +1,7 @@ -.card:empty,.card.infohidden{ - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background-size: 100% 100%; } diff --git a/theme/style/cardback/feicheng.css b/theme/style/cardback/feicheng.css index 1bc014678..c529b428f 100644 --- a/theme/style/cardback/feicheng.css +++ b/theme/style/cardback/feicheng.css @@ -1,8 +1,9 @@ -.card:empty,.card.infohidden{ - background: url('image/feicheng.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("image/feicheng.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('image/feicheng2.png'); - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background: url("image/feicheng2.png"); + background-size: 100% 100%; } diff --git a/theme/style/cardback/liusha.css b/theme/style/cardback/liusha.css index f0c4001c7..e4007acb1 100644 --- a/theme/style/cardback/liusha.css +++ b/theme/style/cardback/liusha.css @@ -1,8 +1,9 @@ -.card:empty,.card.infohidden{ - background: url('image/liusha.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("image/liusha.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('image/liusha2.png'); - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background: url("image/liusha2.png"); + background-size: 100% 100%; } diff --git a/theme/style/cardback/music.css b/theme/style/cardback/music.css index 04c28ed7b..d0b6c7c9e 100644 --- a/theme/style/cardback/music.css +++ b/theme/style/cardback/music.css @@ -1,6 +1,7 @@ -.card:empty,.card.infohidden{ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('../../music/wood3.png'); - background-size:auto; +.card:empty, +.card.infohidden { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("../../music/wood3.png"); + background-size: auto; } diff --git a/theme/style/cardback/new.css b/theme/style/cardback/new.css index ed76ef759..2497863d1 100644 --- a/theme/style/cardback/new.css +++ b/theme/style/cardback/new.css @@ -1,8 +1,9 @@ -.card:empty,.card.infohidden{ - background: url('image/new.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("image/new.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('image/new2.png'); - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background: url("image/new2.png"); + background-size: 100% 100%; } diff --git a/theme/style/cardback/official.css b/theme/style/cardback/official.css index 9d1883c57..43982188c 100644 --- a/theme/style/cardback/official.css +++ b/theme/style/cardback/official.css @@ -1,8 +1,9 @@ -.card:empty,.card.infohidden{ - background: url('image/official.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("image/official.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('image/official2.png'); - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background: url("image/official2.png"); + background-size: 100% 100%; } diff --git a/theme/style/cardback/ol.css b/theme/style/cardback/ol.css index 9a8925e8c..49c574e07 100644 --- a/theme/style/cardback/ol.css +++ b/theme/style/cardback/ol.css @@ -1,8 +1,9 @@ -.card:empty,.card.infohidden{ - background: url('image/ol.png'); - background-size: 100% 100%; +.card:empty, +.card.infohidden { + background: url("image/ol.png"); + background-size: 100% 100%; } -.card.infohidden:not(.infoflip){ - background: url('image/ol2.png'); - background-size: 100% 100%; +.card.infohidden:not(.infoflip) { + background: url("image/ol2.png"); + background-size: 100% 100%; } diff --git a/theme/style/cardback/wood.css b/theme/style/cardback/wood.css index af180ffc2..9492072df 100644 --- a/theme/style/cardback/wood.css +++ b/theme/style/cardback/wood.css @@ -1,6 +1,7 @@ -.card:empty,.card.infohidden{ - color:rgb(77, 60, 51); - text-shadow:none; - background: url('../../woodden/wood.jpg'); - background-size:auto; +.card:empty, +.card.infohidden { + color: rgb(77, 60, 51); + text-shadow: none; + background: url("../../woodden/wood.jpg"); + background-size: auto; } diff --git a/theme/style/hp/custom.css b/theme/style/hp/custom.css index 4fb3677ff..218a18a2e 100644 --- a/theme/style/hp/custom.css +++ b/theme/style/hp/custom.css @@ -1,59 +1,68 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/emotion.css b/theme/style/hp/emotion.css index a777b0c52..a3a2cfba4 100644 --- a/theme/style/hp/emotion.css +++ b/theme/style/hp/emotion.css @@ -1,63 +1,72 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/emotion1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:brightness(0.8) contrast(1.5); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/emotion1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: brightness(0.8) contrast(1.5); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/emotion2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:brightness(0.8) contrast(1.5); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/emotion2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: brightness(0.8) contrast(1.5); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/emotion3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:brightness(0.8) contrast(1.5); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/emotion3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: brightness(0.8) contrast(1.5); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/emotion4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/emotion4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/glass.css b/theme/style/hp/glass.css index 28b474511..88a8e10aa 100644 --- a/theme/style/hp/glass.css +++ b/theme/style/hp/glass.css @@ -1,63 +1,72 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/glass1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/glass1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/glass2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/glass2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/glass3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/glass3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/glass4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/glass4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/official.css b/theme/style/hp/official.css index 48a3b2249..5d74eed03 100644 --- a/theme/style/hp/official.css +++ b/theme/style/hp/official.css @@ -1,60 +1,69 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/official1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/official1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/official2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/official2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/official3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/official3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/official4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/official4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/ol.css b/theme/style/hp/ol.css index 7e9ba13bf..f5c030ab0 100644 --- a/theme/style/hp/ol.css +++ b/theme/style/hp/ol.css @@ -1,64 +1,73 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/ol1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.6); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/ol1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.6); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/ol2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.6); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/ol2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.6); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/ol3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.6); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/ol3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.6); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/ol4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.6); - border-radius: 0px; - filter:grayscale(1) opacity(0.8); - -webkit-filter:grayscale(1) opacity(0.8); +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/ol4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.6); + border-radius: 0px; + filter: grayscale(1) opacity(0.8); + -webkit-filter: grayscale(1) opacity(0.8); } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.6); - border-radius: 0px; - filter:grayscale(1) opacity(0.8); - -webkit-filter:grayscale(1) opacity(0.8); +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.6); + border-radius: 0px; + filter: grayscale(1) opacity(0.8); + -webkit-filter: grayscale(1) opacity(0.8); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/round.css b/theme/style/hp/round.css index 1131a3138..9a8f1544e 100644 --- a/theme/style/hp/round.css +++ b/theme/style/hp/round.css @@ -1,63 +1,72 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/round1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/round1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/round2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/round2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/round3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/round3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/round4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/round4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/xinglass.css b/theme/style/hp/xinglass.css index 690ef0729..b30389d12 100644 --- a/theme/style/hp/xinglass.css +++ b/theme/style/hp/xinglass.css @@ -1,63 +1,72 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/xinglass1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/xinglass1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/xinglass2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/xinglass2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/xinglass3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/xinglass3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/xinglass4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/xinglass4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/xinglass4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/xinglass4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/style/hp/xinround.css b/theme/style/hp/xinround.css index d937436d9..dfc33624c 100644 --- a/theme/style/hp/xinround.css +++ b/theme/style/hp/xinround.css @@ -1,63 +1,72 @@ -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - background: url('image/xinround1.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] > div:not(.lost):not(.shield) { + background: url("image/xinround1.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - background: url('image/xinround2.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] > div:not(.lost):not(.shield) { + background: url("image/xinround2.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - background: url('image/xinround3.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - -webkit-filter:none; - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] > div:not(.lost):not(.shield) { + background: url("image/xinround3.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + -webkit-filter: none; + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.lost{ - background: url('image/xinround4.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .lost { + background: url("image/xinround4.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -.hp:not(.text):not(.actcount):not(.treasure)>.shield{ - background: url('image/shield.png'); - box-shadow: none; - border: none; - background-size: 100% 100%; - transform: scale(1.4); - border-radius: 0px; +.hp:not(.text):not(.actcount):not(.treasure) > .shield { + background: url("image/shield.png"); + box-shadow: none; + border: none; + background-size: 100% 100%; + transform: scale(1.4); + border-radius: 0px; } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="high"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="mid"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"]>div:not(.lost):not(.shield){ - transform: scale(1.6); +#arena.oldlayout + .player + .hp:not(.text):not(.actcount):not(.treasure)[data-condition="low"] + > div:not(.lost):not(.shield) { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.lost{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .lost { + transform: scale(1.6); } -#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure)>.shield{ - transform: scale(1.6); +#arena.oldlayout .player .hp:not(.text):not(.actcount):not(.treasure) > .shield { + transform: scale(1.6); } -.button.newstyle>.hp>.text{ - margin-left: 5px; +.button.newstyle > .hp > .text { + margin-left: 5px; } diff --git a/theme/woodden/style.css b/theme/woodden/style.css index 1a47c40dc..06e25c3eb 100644 --- a/theme/woodden/style.css +++ b/theme/woodden/style.css @@ -1,248 +1,285 @@ -html{ +html { color: white; text-shadow: black 0 0 2px; - background: url('grid.png'),linear-gradient(#6c7989, #434b55) fixed; + background: url("grid.png"), linear-gradient(#6c7989, #434b55) fixed; } -#system>div>div,#mebg,.control,.player,.card,.avatar,.avatar2,.button,.dialog>.bar,.menu,#splash>div, -#arena.mobile:not(.chess) .player[data-position='0'] .equips,.playerbg,.menubg,.mebg{ +#system > div > div, +#mebg, +.control, +.player, +.card, +.avatar, +.avatar2, +.button, +.dialog > .bar, +.menu, +#splash > div, +#arena.mobile:not(.chess) .player[data-position="0"] .equips, +.playerbg, +.menubg, +.mebg { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; border-radius: 8px; } -.dialog.choose-character>.packnode>div{ +.dialog.choose-character > .packnode > div { box-shadow: rgba(0, 0, 0, 0.4) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; - background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)); + background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)); color: white; text-shadow: black 0 0 2px; } -.dialog.choose-character>.packnode>div.active{ +.dialog.choose-character > .packnode > div.active { box-shadow: rgba(27, 63, 95, 0.8) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px !important; - background-image: linear-gradient(rgba(47,101,150,1), rgba(43, 90, 132,1)); + background-image: linear-gradient(rgba(47, 101, 150, 1), rgba(43, 90, 132, 1)); } -.button-downloading>.button-progress>div{ - background: rgba(77,224,100,0.45); +.button-downloading > .button-progress > div { + background: rgba(77, 224, 100, 0.45); } -.menu.main>.menu-tab>div:not(.active):not(*:hover), -.menu.main>.menu-tab>.disabled{ - color: rgba(77, 60, 51,0.5); +.menu.main > .menu-tab > div:not(.active):not(*:hover), +.menu.main > .menu-tab > .disabled { + color: rgba(77, 60, 51, 0.5); } -#window>.dialog.popped,.menu,.menubg{ - background:url('wood2.png'); - color:rgba(77, 60, 51,0.8); - text-shadow:none; -} -.popup-container>.menu.visual>.dashedmenubutton{ - color:rgba(77, 60, 51,0.8); +#window > .dialog.popped, +.menu, +.menubg { + background: url("wood2.png"); + color: rgba(77, 60, 51, 0.8); text-shadow: none; - border-color:rgba(77, 60, 51,0.8); } -.cardbg{ +.popup-container > .menu.visual > .dashedmenubutton { + color: rgba(77, 60, 51, 0.8); + text-shadow: none; + border-color: rgba(77, 60, 51, 0.8); +} +.cardbg { background-size: initial !important; } -#splash>div{ - background:url('wood2.png'); +#splash > div { + background: url("wood2.png"); } #arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty), #arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty), #arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty), -#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty){ - background: url('wood.png'); - border-radius:4px; +#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty) { + background: url("wood.png"); + border-radius: 4px; overflow: hidden; box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 2px 10px; } -#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty)>.card:not(.selected), -#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty)>.card, -#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty)>.card:not(.selected){ +#arena:not(.long).mobile:not(.oldlayout) .player.unseen:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena:not(.long):not(.mobile):not(.oldlayout) .player.unseen .equips:not(*:empty) > .card:not(.selected), +#arena.long.mobile:not(.oldlayout) .player.unseen2:not([data-position="0"]) .equips:not(*:empty) > .card, +#arena.long:not(.mobile):not(.oldlayout) .player.unseen2 .equips:not(*:empty) > .card:not(.selected) { background: none !important; } -.coin_menu .content>.caption>.coin_buy>.menubutton{ +.coin_menu .content > .caption > .coin_buy > .menubutton { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px !important; } -.popup.fire{ - color: rgb(255,119,63); +.popup.fire { + color: rgb(255, 119, 63); } -.popup.thunder{ - color: rgb(117,186,255); +.popup.thunder { + color: rgb(117, 186, 255); } -.control .thundertext,.thundertext.thunderauto, +.control .thundertext, +.thundertext.thunderauto, .dialog.popped .bluetext, -.menubg .bluetext{ +.menubg .bluetext { color: rgba(29, 63, 137, 1); } -.control .controlthundertext{ +.control .controlthundertext { color: rgb(62, 41, 30); } .dialog.popped .yellowtext, -.menubg .yellowtext{ - color:#631515; +.menubg .yellowtext { + color: #631515; } .dialog.popped .firetext, -.menubg .firetext{ - color:#a20000; +.menubg .firetext { + color: #a20000; } .dialog.popped .greentext, -.menubg .greentext,.control span.greentext,.poisontext.poisonauto{ - color:#00312d; +.menubg .greentext, +.control span.greentext, +.poisontext.poisonauto { + color: #00312d; } -.control span.firetext{ - color:#631515; +.control span.firetext { + color: #631515; } -.legendtext.legendauto{ +.legendtext.legendauto { color: rgba(106, 27, 154, 1); } -.player,.card,.dialog>.bar,.cardbg, -#arena.mobile:not(.chess) .player[data-position='0'] .equips,.playerbg,#window .player.playerbg{ - background: url('wood.jpg'); +.player, +.card, +.dialog > .bar, +.cardbg, +#arena.mobile:not(.chess) .player[data-position="0"] .equips, +.playerbg, +#window .player.playerbg { + background: url("wood.jpg"); } -.cardbg.button{ - background: url('wood.png'); +.cardbg.button { + background: url("wood.png"); } -#arena.observe .handcards>.card{ - background: url('wood.jpg') !important; +#arena.observe .handcards > .card { + background: url("wood.jpg") !important; } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card{ - background: url('wood.jpg') !important; - color:rgb(77, 60, 51) !important; +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card { + background: url("wood.jpg") !important; + color: rgb(77, 60, 51) !important; text-shadow: none !important; - box-shadow: rgba(0,0,0,0.4) 1px 0 0 1px; + box-shadow: rgba(0, 0, 0, 0.4) 1px 0 0 1px; } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card:first-child{ - box-shadow: rgba(0,0,0,0.4) 0 1px 0 0; +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card:first-child { + box-shadow: rgba(0, 0, 0, 0.4) 0 1px 0 0; } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card.selected{ +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card.selected { -webkit-filter: sepia(0.8) !important; - background-image: url('wood.jpg') !important; + background-image: url("wood.jpg") !important; /*background-image: linear-gradient(rgba(47,101,150,1), rgba(43, 90, 132,1)) !important;*/ /*color: white !important; box-shadow: rgba(0,0,0,0.4) 1px 0 0 1px !important;*/ } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card.selected:first-child{ - box-shadow: rgba(0,0,0,0.4) 0 1px 0 0 !important; +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card.selected:first-child { + box-shadow: rgba(0, 0, 0, 0.4) 0 1px 0 0 !important; } -#arena:not(.chess).textequip .player[data-position='0'] .equips>.card>.name2{ +#arena:not(.chess).textequip .player[data-position="0"] .equips > .card > .name2 { transition: opacity 0.5s, color 0s; } -.control,#system>div>div,.menubutton,#system>div>.pressdown2{ - background: url('wood2.jpg'); - color:rgba(77, 60, 51,0.8); - text-shadow:none; - border-radius:4px; +.control, +#system > div > div, +.menubutton, +#system > div > .pressdown2 { + background: url("wood2.jpg"); + color: rgba(77, 60, 51, 0.8); + text-shadow: none; + border-radius: 4px; } -#roundmenu>div:not(.clock){ - background:rgba(77, 60, 51,0.8); - box-shadow:none; +#roundmenu > div:not(.clock) { + background: rgba(77, 60, 51, 0.8); + box-shadow: none; } -#system>div>.pressdown2{ +#system > div > .pressdown2 { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 133, 255, 0.8) 0 0 0 2px, rgba(0, 133, 255, 1) 0 0 5px !important; } -.judges>div,.marks>div{ - border-radius:4px; +.judges > div, +.marks > div { + border-radius: 4px; } -#mebg,.menubutton,.menubutton.highlight,.menubutton.active,.mebg{ - background: url('wood.png'); +#mebg, +.menubutton, +.menubutton.highlight, +.menubutton.active, +.mebg { + background: url("wood.png"); } -.menubutton.large{ +.menubutton.large { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px !important; } .menubutton.large.active, .menubutton.round.active, .menubutton.active, -.menubutton.highlight.update{ +.menubutton.highlight.update { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 133, 255, 0.4) 0 0 0 2px, rgba(0, 133, 255, 1) 0 0 5px !important; } -.connectevents.icon.highlight{ +.connectevents.icon.highlight { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px !important; - background: url('wood.jpg'); + background: url("wood.jpg"); } -.videonode.menubutton.extension>.caption>.menubutton.active{ +.videonode.menubutton.extension > .caption > .menubutton.active { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px !important; } -.videonode.menubutton.extension.current{ +.videonode.menubutton.extension.current { box-shadow: rgba(0, 0, 0, 0.3) 0 0 0 1px, rgba(0, 133, 255, 0.4) 0 0 0 2px, rgba(0, 133, 255, 1) 0 0 5px !important; } -.themebutton{ +.themebutton { box-shadow: rgba(0, 0, 0, 0.45) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px !important; } -.config.toggle>div>div{ - background: url('wood.png'); +.config.toggle > div > div { + background: url("wood.png"); box-shadow: rgba(151, 151, 151, 1) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 3px 10px; } -.config.toggle.on>div{ +.config.toggle.on > div { background-color: transparent; } -.config.toggle.on>div::before{ - content:'开'; +.config.toggle.on > div::before { + content: "开"; position: absolute; left: 13px; opacity: 0.5; font-size: 14px; line-height: 26px; - font-family: 'xinwei' + font-family: "xinwei"; } -.popup-container>.menu:not(.visual)>div:hover{ - color:white; +.popup-container > .menu:not(.visual) > div:hover { + color: white; background-image: linear-gradient(rgb(0, 133, 255), rgb(5, 119, 220)); box-shadow: none; } -.control,#system>div>div,.popup,.dialog>.bar{ +.control, +#system > div > div, +.popup, +.dialog > .bar { box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.2) 0 2px 10px; } -.card{ - text-shadow:rgba(0,0,0,0.1) 0 0 1px; +.card { + text-shadow: rgba(0, 0, 0, 0.1) 0 0 1px; } -.card.equip3>.range, -.card.equip4>.range{ +.card.equip3 > .range, +.card.equip4 > .range { text-shadow: white 0 0 2px; } -.card,.menubg,.cardbg,.button.character.cardbg{ - color:rgb(77, 60, 51); - text-shadow:none; +.card, +.menubg, +.cardbg, +.button.character.cardbg { + color: rgb(77, 60, 51); + text-shadow: none; } -#arena.mobile:not(.chess) .player[data-position='0'] .card.fullskin.epic>.name2{ +#arena.mobile:not(.chess) .player[data-position="0"] .card.fullskin.epic > .name2 { color: rgba(0, 66, 165, 1); } -#arena.mobile:not(.chess) .player[data-position='0'] .card.fullskin.legend>.name2{ +#arena.mobile:not(.chess) .player[data-position="0"] .card.fullskin.legend > .name2 { color: rgba(106, 27, 154, 1); /*color: rgb(117,186,0);*/ } -.bordered{ - border:1px solid rgba(255, 255, 255,0.5); +.bordered { + border: 1px solid rgba(255, 255, 255, 0.5); } -.dialog.popped .config>.toggle.onoff>div{ - border:1px solid rgba(77, 60, 51,0.8); +.dialog.popped .config > .toggle.onoff > div { + border: 1px solid rgba(77, 60, 51, 0.8); box-shadow: none; } -.dialog.popped .config>.toggle.onoff>div>div{ - background:rgba(77, 60, 51,0.8); - border:1px solid rgba(77, 60, 51,0); - box-shadow:none; +.dialog.popped .config > .toggle.onoff > div > div { + background: rgba(77, 60, 51, 0.8); + border: 1px solid rgba(77, 60, 51, 0); + box-shadow: none; } -.player>.turned{ - color: rgba(0,0,0,0.8); +.player > .turned { + color: rgba(0, 0, 0, 0.8); background: white; } -.player .marks>div:first-child>div{ +.player .marks > div:first-child > div { -webkit-filter: invert(0.8) sepia(1); } -#roundmenu.clock>div:nth-of-type(15){ - background: url('wood2.png'); - box-shadow: rgba(0,0,0,0.5) 0 0 5px inset; +#roundmenu.clock > div:nth-of-type(15) { + background: url("wood2.png"); + box-shadow: rgba(0, 0, 0, 0.5) 0 0 5px inset; } -.menubg.charactercard>.ava>.avatar{ - box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px; +.menubg.charactercard > .ava > .avatar { + box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.3) 0 0 5px; } -#arena:not(.chess) .player[data-position='0']>.equips>.equip5>.image{ +#arena:not(.chess) .player[data-position="0"] > .equips > .equip5 > .image { background-position: -6px -6px; } diff --git a/tsconfig.json b/tsconfig.json index 649199216..8ae43aff5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -77,11 +77,11 @@ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + "strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */